summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--SwifTools/Linkify.cpp41
-rw-r--r--SwifTools/UnitTest/LinkifyTest.cpp18
2 files changed, 53 insertions, 6 deletions
diff --git a/SwifTools/Linkify.cpp b/SwifTools/Linkify.cpp
index 0ebe832..0dfa7b5 100644
--- a/SwifTools/Linkify.cpp
+++ b/SwifTools/Linkify.cpp
@@ -7,17 +7,46 @@
#include "SwifTools/Linkify.h"
#include <boost/regex.hpp>
+#include <sstream>
+#include <iostream>
namespace Swift {
-static const boost::regex linkifyRegexp("(https?://([@:\\-\\w\\.]+)+(:\\d+)?(/([=%~\\-\\w/_#@\\.\\+]*(\\?\\S+)?)?)?)");
+static boost::regex linkifyRegexp("^https?://.*");
String Linkify::linkify(const String& input) {
- return String(boost::regex_replace(
- input.getUTF8String(),
- linkifyRegexp,
- "<a href=\"\\1\">\\1</a>",
- boost::match_default|boost::format_all));
+ std::ostringstream result;
+ std::vector<char> currentURL;
+ bool inURL = false;
+ for (size_t i = 0; i < input.getUTF8Size(); ++i) {
+ char c = input[i];
+ if (inURL) {
+ if (c >= 33 && c != '\\' && c != '"') {
+ currentURL.push_back(c);
+ }
+ else {
+ String url(&currentURL[0], currentURL.size());
+ result << "<a href=\"" << url << "\">" << url << "</a>";
+ currentURL.clear();
+ inURL = false;
+ result << c;
+ }
+ }
+ else {
+ if (boost::regex_match(input.getSubstring(i, 8).getUTF8String(), linkifyRegexp)) {
+ currentURL.push_back(c);
+ inURL = true;
+ }
+ else {
+ result << c;
+ }
+ }
+ }
+ if (currentURL.size() > 0) {
+ String url(&currentURL[0], currentURL.size());
+ result << "<a href=\"" << url << "\">" << url << "</a>";
+ }
+ return String(result.str());
}
}
diff --git a/SwifTools/UnitTest/LinkifyTest.cpp b/SwifTools/UnitTest/LinkifyTest.cpp
index 1418957..9655b87 100644
--- a/SwifTools/UnitTest/LinkifyTest.cpp
+++ b/SwifTools/UnitTest/LinkifyTest.cpp
@@ -14,6 +14,7 @@ using namespace Swift;
class LinkifyTest : public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(LinkifyTest);
CPPUNIT_TEST(testLinkify_URLWithResource);
+ CPPUNIT_TEST(testLinkify_HTTPSURLWithResource);
CPPUNIT_TEST(testLinkify_URLWithEmptyResource);
CPPUNIT_TEST(testLinkify_BareURL);
CPPUNIT_TEST(testLinkify_URLSurroundedByWhitespace);
@@ -26,6 +27,7 @@ class LinkifyTest : public CppUnit::TestFixture {
CPPUNIT_TEST(testLinkify_Equal);
CPPUNIT_TEST(testLinkify_Authentication);
CPPUNIT_TEST(testLinkify_At);
+ CPPUNIT_TEST(testLinkify_Amps);
CPPUNIT_TEST_SUITE_END();
public:
@@ -37,6 +39,14 @@ class LinkifyTest : public CppUnit::TestFixture {
result);
}
+ void testLinkify_HTTPSURLWithResource() {
+ String result = Linkify::linkify("https://swift.im/blog");
+
+ CPPUNIT_ASSERT_EQUAL(
+ String("<a href=\"https://swift.im/blog\">https://swift.im/blog</a>"),
+ result);
+ }
+
void testLinkify_URLWithEmptyResource() {
String result = Linkify::linkify("http://swift.im/");
@@ -133,6 +143,14 @@ class LinkifyTest : public CppUnit::TestFixture {
String("<a href=\"http://swift.im/foo@bar\">http://swift.im/foo@bar</a>"),
result);
}
+
+ void testLinkify_Amps() {
+ String result = Linkify::linkify("http://swift.im/foo&bar&baz");
+
+ CPPUNIT_ASSERT_EQUAL(
+ String("<a href=\"http://swift.im/foo&bar&baz\">http://swift.im/foo&bar&baz</a>"),
+ result);
+ }
};
CPPUNIT_TEST_SUITE_REGISTRATION(LinkifyTest);