diff options
Diffstat (limited to 'SwifTools')
-rw-r--r-- | SwifTools/Linkify.cpp | 41 | ||||
-rw-r--r-- | SwifTools/UnitTest/LinkifyTest.cpp | 18 |
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(¤tURL[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(¤tURL[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); |