Skip to content

Commit

Permalink
Use twitter for linking in updates
Browse files Browse the repository at this point in the history
Using a well established standard for linking reduces discussions and
removes us from maintaing that logic as well.

Relates to innoq#177
  • Loading branch information
mvitz committed Mar 10, 2016
1 parent 5eec25a commit a82fa7d
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 28 deletions.
3 changes: 2 additions & 1 deletion project.clj
Original file line number Diff line number Diff line change
Expand Up @@ -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"]]}
Expand Down
29 changes: 12 additions & 17 deletions src/statuses/views/common.clj
Original file line number Diff line number Diff line change
Expand Up @@ -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)))
29 changes: 19 additions & 10 deletions test/linkification.clj
Original file line number Diff line number Diff line change
Expand Up @@ -22,27 +22,36 @@
(deftest linkify-hashtags
(is (=
(linkify "lorem #hashtag ipsum")
"lorem #<a href=\"/statuses/updates?query=%23hashtag\">hashtag</a> ipsum"))
"lorem <a href=\"/statuses/updates?query=%23hashtag\">#hashtag</a> ipsum"))
(is (=
(linkify "#hashtag lipsum")
"#<a href=\"/statuses/updates?query=%23hashtag\">hashtag</a> lipsum"))
"<a href=\"/statuses/updates?query=%23hashtag\">#hashtag</a> lipsum"))
(is (=
(linkify "lipsum #hashtag")
"lipsum #<a href=\"/statuses/updates?query=%23hashtag\">hashtag</a>"))
"lipsum <a href=\"/statuses/updates?query=%23hashtag\">#hashtag</a>"))
(is (=
(linkify "#WTF^2")
"#<a href=\"/statuses/updates?query=%23WTF%5E2\">WTF^2</a>")))
"<a href=\"/statuses/updates?query=%23WTF\">#WTF</a>^2"))
(is (=
(linkify "lorem (ipsum #foo)")
"lorem (ipsum <a href=\"/statuses/updates?query=%23foo\">#foo</a>)"))
(is (=
(linkify "got #foo: awesome")
"got <a href=\"/statuses/updates?query=%23foo\">#foo</a>: awesome"))
(is (=
(linkify "got #foo:awesome")
"got <a href=\"/statuses/updates?query=%23foo\">#foo</a>:awesome")))

(deftest linkify-uris-with-fragment-identifier
(is (=
(linkify "lorem http://example.org#anchor ipsum")
"lorem <a href=\"http://example.org#anchor\">http://example.org#anchor</a> ipsum")))
(linkify "lorem http://example.org/#anchor ipsum")
"lorem <a href=\"http://example.org/#anchor\">http://example.org/#anchor</a> ipsum"))
(is (=
(linkify "#hashtag lipsum http://example.org#anchor-name")
"#<a href=\"/statuses/updates?query=%23hashtag\">hashtag</a> lipsum <a href=\"http://example.org#anchor-name\">http://example.org#anchor-name</a>"))
(linkify "#hashtag lipsum http://example.org/#anchor-name")
"<a href=\"/statuses/updates?query=%23hashtag\">#hashtag</a> lipsum <a href=\"http://example.org/#anchor-name\">http://example.org/#anchor-name</a>"))
(is (=
(linkify "lipsum http://example.org#anchor-name #hashtag")
"lipsum <a href=\"http://example.org#anchor-name\">http://example.org#anchor-name</a> #<a href=\"/statuses/updates?query=%23hashtag\">hashtag</a>"))
(linkify "lipsum http://example.org/#anchor-name #hashtag")
"lipsum <a href=\"http://example.org/#anchor-name\">http://example.org/#anchor-name</a> <a href=\"/statuses/updates?query=%23hashtag\">#hashtag</a>")))

(deftest linkify-email-addresses
(is (=
Expand Down

0 comments on commit a82fa7d

Please sign in to comment.