diff --git a/src/formatters.nim b/src/formatters.nim
index 69d1a94..f40de94 100644
--- a/src/formatters.nim
+++ b/src/formatters.nim
@@ -6,12 +6,6 @@ import types, utils, query
from unicode import Rune, `$`
const
- urlRegex = re"((https?|ftp)://(-\.)?([^\s/?\.#]+\.?)+([/\?][^\s\)]*)?)"
- emailRegex = re"([a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+)"
- usernameRegex = re"(^|[^A-z0-9_?\/])@([A-z0-9_]+)"
- picRegex = re"pic.twitter.com/[^ ]+"
- ellipsisRegex = re" ?…"
- hashtagRegex = re"([^\S]|^)([#$]\w+)"
ytRegex = re"(www.|m.)?youtu(be.com|.be)"
twRegex = re"(www.|mobile.)?twitter.com"
nbsp = $Rune(0x000A0)
@@ -26,75 +20,14 @@ proc shortLink*(text: string; length=28): string =
if result.len > length:
result = result[0 ..< length] & "…"
-proc toLink*(url, text: string): string =
- a(text, href=url)
-
-proc reUrlToShortLink*(m: RegexMatch; s: string): string =
- let url = s[m.group(0)[0]]
- toLink(url, shortLink(url))
-
-proc reUrlToLink*(m: RegexMatch; s: string): string =
- let url = s[m.group(0)[0]]
- toLink(url, url.replace(re"https?://(www.)?", ""))
-
-proc reEmailToLink*(m: RegexMatch; s: string): string =
- let url = s[m.group(0)[0]]
- toLink("mailto://" & url, url)
-
-proc reHashtagToLink*(m: RegexMatch; s: string): string =
- result = if m.group(0).len > 0: s[m.group(0)[0]] else: ""
- let hash = s[m.group(1)[0]]
- let link = toLink("/search?q=" & encodeUrl(hash), hash)
- if hash.any(isAlphaAscii):
- result &= link
- else:
- result &= hash
-
-proc reUsernameToLink*(m: RegexMatch; s: string): string =
- var username = ""
- var pretext = ""
-
- let pre = m.group(0)
- let match = m.group(1)
-
- username = s[match[0]]
-
- if pre.len > 0:
- pretext = s[pre[0]]
-
- pretext & toLink("/" & username, "@" & username)
-
-proc reUsernameToFullLink*(m: RegexMatch; s: string): string =
- result = reUsernameToLink(m, s)
- result = result.replace("href=\"/", &"href=\"https://{hostname}/")
-
-proc replaceUrl*(url: string; prefs: Prefs): string =
+proc replaceUrl*(url: string; prefs: Prefs; rss=false): string =
result = url
if prefs.replaceYouTube.len > 0:
result = result.replace(ytRegex, prefs.replaceYouTube)
if prefs.replaceTwitter.len > 0:
result = result.replace(twRegex, prefs.replaceTwitter)
-
-proc linkifyText*(text: string; prefs: Prefs; rss=false): string =
- result = xmltree.escape(stripText(text))
- result = result.replace(ellipsisRegex, " ")
- result = result.replace(emailRegex, reEmailToLink)
if rss:
- result = result.replace(urlRegex, reUrlToLink)
- result = result.replace(usernameRegex, reUsernameToFullLink)
- else:
- result = result.replace(urlRegex, reUrlToShortLink)
- result = result.replace(usernameRegex, reUsernameToLink)
- result = result.replace(hashtagRegex, reHashtagToLink)
- result = result.replace(re"([^\s\(\n%])\s+([;.,!\)'%]|')", "$1")
- result = result.replace(re"^\. 0:
- result = result.replace(link, "")
-
- result = stripTwitterUrls(result)
+ parseText(text, if quote != nil: link else: "")
proc getTime(tweet: XmlNode): XmlNode =
tweet.select(".js-short-timestamp")
@@ -87,10 +100,10 @@ proc getUsername*(profile: XmlNode; selector: string): string =
profile.selectText(selector).strip(chars={'@', ' ', '\n'})
proc getBio*(profile: XmlNode; selector: string; fallback=""): string =
- var bio = profile.selectText(selector)
- if bio.len == 0 and fallback.len > 0:
- bio = profile.selectText(fallback)
- stripText(bio)
+ var bio = profile.select(selector)
+ if bio == nil and fallback.len > 0:
+ bio = profile.select(fallback)
+ parseText(bio)
proc getLocation*(profile: XmlNode): string =
let sel = ".ProfileHeaderCard-locationText"
diff --git a/src/views/profile.nim b/src/views/profile.nim
index f50cf66..18b215a 100644
--- a/src/views/profile.nim
+++ b/src/views/profile.nim
@@ -25,7 +25,7 @@ proc renderProfileCard*(profile: Profile; prefs: Prefs): VNode =
tdiv(class="profile-card-extra"):
if profile.bio.len > 0:
tdiv(class="profile-bio"):
- p: verbatim linkifyText(profile.bio, prefs)
+ p: verbatim replaceUrl(profile.bio, prefs)
if profile.location.len > 0:
tdiv(class="profile-location"):
@@ -39,8 +39,9 @@ proc renderProfileCard*(profile: Profile; prefs: Prefs): VNode =
if profile.website.len > 0:
tdiv(class="profile-website"):
span:
+ let url = replaceUrl(profile.website, prefs)
icon "link"
- verbatim linkifyText(profile.website, prefs)
+ a(href=url): text shortLink(url)
tdiv(class="profile-joindate"):
span(title=getJoinDateFull(profile)):
diff --git a/src/views/rss.nimf b/src/views/rss.nimf
index 72ee5f8..15a43e7 100644
--- a/src/views/rss.nimf
+++ b/src/views/rss.nimf
@@ -7,7 +7,7 @@
#if tweet.pinned: result = "Pinned: "
#elif tweet.retweet.isSome: result = "RT: "
#end if
-#result &= xmltree.escape(replaceUrl(tweet.text, prefs))
+#result &= xmltree.escape(replaceUrl(tweet.text, prefs, rss=true))
#if result.len > 0: return
#end if
#if tweet.photos.len > 0:
@@ -20,7 +20,7 @@
#end proc
#
#proc renderRssTweet(tweet: Tweet; prefs: Prefs): string =
-#let text = linkifyText(tweet.text, prefs, rss=true)
+#let text = replaceUrl(tweet.text, prefs, rss=true)
#if tweet.quote.isSome and get(tweet.quote).available:
#let quoteLink = hostname & getLink(get(tweet.quote))
${text}
${quoteLink}
@@ -58,7 +58,7 @@
#end proc
#
#proc renderTimelineRss*(timeline: Timeline; profile: Profile): string =
-#let prefs = Prefs(replaceTwitter: hostname)
+#let prefs = Prefs(replaceTwitter: hostname, replaceYoutube: "invidio.us")
#result = ""
@@ -84,7 +84,7 @@
#end proc
#
#proc renderListRss*(tweets: seq[Tweet]; name, list: string): string =
-#let prefs = Prefs(replaceTwitter: hostname)
+#let prefs = Prefs(replaceTwitter: hostname, replaceYoutube: "invidio.us")
#let link = &"https://{hostname}/{name}/lists/{list}"
#result = ""
@@ -102,7 +102,7 @@
#end proc
#
#proc renderSearchRss*(tweets: seq[Tweet]; name, param: string): string =
-#let prefs = Prefs(replaceTwitter: hostname)
+#let prefs = Prefs(replaceTwitter: hostname, replaceYoutube: "invidio.us")
#let link = &"https://{hostname}/search"
#result = ""
diff --git a/src/views/timeline.nim b/src/views/timeline.nim
index ebbc8bd..ee8897c 100644
--- a/src/views/timeline.nim
+++ b/src/views/timeline.nim
@@ -56,7 +56,7 @@ proc renderUser(user: Profile; prefs: Prefs): VNode =
linkUser(user, class="username")
tdiv(class="tweet-content media-body"):
- verbatim linkifyText(user.bio, prefs)
+ verbatim replaceUrl(user.bio, prefs)
proc renderTimelineUsers*(results: Result[Profile]; prefs: Prefs; path=""): VNode =
buildHtml(tdiv(class="timeline")):
diff --git a/src/views/tweet.nim b/src/views/tweet.nim
index 0539542..ac0c167 100644
--- a/src/views/tweet.nim
+++ b/src/views/tweet.nim
@@ -215,7 +215,7 @@ proc renderQuote(quote: Quote; prefs: Prefs): VNode =
renderReply(quote)
tdiv(class="quote-text"):
- verbatim linkifyText(quote.text, prefs)
+ verbatim replaceUrl(quote.text, prefs)
if quote.hasThread:
a(class="show-thread", href=getLink(quote)):
@@ -248,7 +248,7 @@ proc renderTweet*(tweet: Tweet; prefs: Prefs; path: string; class="";
renderReply(tweet)
tdiv(class="tweet-content media-body"):
- verbatim linkifyText(tweet.text, prefs)
+ verbatim replaceUrl(tweet.text, prefs)
if tweet.quote.isSome:
renderQuote(tweet.quote.get(), prefs)
diff --git a/tests/test_tweet.py b/tests/test_tweet.py
index 5b8ed05..8fe8e71 100644
--- a/tests/test_tweet.py
+++ b/tests/test_tweet.py
@@ -51,7 +51,7 @@ link = [
'old.reddit.com/r/programming…'
]],
['nim_lang/status/1125887775151140864', [
- 'en.wikipedia.org/wiki/Nim_(p…)'
+ 'en.wikipedia.org/wiki/Nim_(p…'
]],
['hiankun_taioan/status/1086916335215341570', [
'(hackernoon.com/interview-wit…)'