From a82fa7dc50515c430d515fb5e8f60cbde408b7ed Mon Sep 17 00:00:00 2001 From: Michael Vitz Date: Wed, 14 Oct 2015 18:22:29 +0200 Subject: [PATCH] Use twitter for linking in updates Using a well established standard for linking reduces discussions and removes us from maintaing that logic as well. Relates to #177 --- project.clj | 3 ++- src/statuses/views/common.clj | 29 ++++++++++++----------------- test/linkification.clj | 29 +++++++++++++++++++---------- 3 files changed, 33 insertions(+), 28 deletions(-) diff --git a/project.clj b/project.clj index 5d2d5a6..39b97f8 100644 --- a/project.clj +++ b/project.clj @@ -10,7 +10,8 @@ [compojure "1.4.0"] [clj-time "0.11.0"] [org.clojure/data.json "0.2.6"] - [org.clojure/tools.cli "0.3.3"]] + [org.clojure/tools.cli "0.3.3"] + [com.twitter/twitter-text "1.12.1"]] :pedantic? :abort :plugins [[jonase/eastwood "0.2.2"]] :profiles {:dev {:dependencies [[ring-mock "0.1.5"]]} diff --git a/src/statuses/views/common.clj b/src/statuses/views/common.clj index 83e5e7f..e45e637 100644 --- a/src/statuses/views/common.clj +++ b/src/statuses/views/common.clj @@ -6,22 +6,17 @@ (defn icon [icon-name] [:span {:class (str "fa fa-" icon-name)}]) -(def uri #"\b((?:[a-z][\w-]+:(?:\/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'\".,<>?«»“”‘’]))") - -;; see: http://www.regular-expressions.info/email.html -(def email #"([a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)") +(def linker (doto (com.twitter.Autolink.) + (.setNoFollow false) + (.setLinkAttributeModifier + (reify com.twitter.Autolink$LinkAttributeModifier + (modify [_ entity attributes] + (doto attributes + (.remove "class") + (.remove "title"))))) + (.setHashtagUrlBase "/statuses/updates?query=%23") + (.setUsernameUrlBase "/statuses/updates?author="))) (defn linkify [text] - (letfn [(handle [[_ m]] (html "@" (link-to (url "/statuses/updates" {:author m}) m))) - (hashtag [[_ m]] (html "#" (link-to (url "/statuses/updates" {:query (str "#" m)}) m))) - (anchor [[m _]] (html (link-to m m))) - (mailto [[m _]] (html (mail-to m)))] - (let [escaped-text (escape-html text)] - (try - (-> escaped-text - (clojure.string/replace #"(?:^|(?<=\s))@(\w+)" handle) - (clojure.string/replace uri anchor) - (clojure.string/replace email mailto) - (clojure.string/replace #"(?:^|(?<=\s))#(\S+)" hashtag)) - (catch Exception e escaped-text))))) - + (when text + (.autoLink linker text))) diff --git a/test/linkification.clj b/test/linkification.clj index 6bc63f5..b25f621 100644 --- a/test/linkification.clj +++ b/test/linkification.clj @@ -22,27 +22,36 @@ (deftest linkify-hashtags (is (= (linkify "lorem #hashtag ipsum") - "lorem #hashtag ipsum")) + "lorem #hashtag ipsum")) (is (= (linkify "#hashtag lipsum") - "#hashtag lipsum")) + "#hashtag lipsum")) (is (= (linkify "lipsum #hashtag") - "lipsum #hashtag")) + "lipsum #hashtag")) (is (= (linkify "#WTF^2") - "#WTF^2"))) + "#WTF^2")) + (is (= + (linkify "lorem (ipsum #foo)") + "lorem (ipsum #foo)")) + (is (= + (linkify "got #foo: awesome") + "got #foo: awesome")) + (is (= + (linkify "got #foo:awesome") + "got #foo:awesome"))) (deftest linkify-uris-with-fragment-identifier (is (= - (linkify "lorem http://example.org#anchor ipsum") - "lorem http://example.org#anchor ipsum"))) + (linkify "lorem http://example.org/#anchor ipsum") + "lorem http://example.org/#anchor ipsum")) (is (= - (linkify "#hashtag lipsum http://example.org#anchor-name") - "#hashtag lipsum http://example.org#anchor-name")) + (linkify "#hashtag lipsum http://example.org/#anchor-name") + "#hashtag lipsum http://example.org/#anchor-name")) (is (= - (linkify "lipsum http://example.org#anchor-name #hashtag") - "lipsum http://example.org#anchor-name #hashtag")) + (linkify "lipsum http://example.org/#anchor-name #hashtag") + "lipsum http://example.org/#anchor-name #hashtag"))) (deftest linkify-email-addresses (is (=