Ensure correct text formatting

This commit is contained in:
Zed 2019-06-25 04:52:38 +02:00
parent 0fee70eeba
commit aae0e51154
7 changed files with 33 additions and 22 deletions

View File

@ -145,9 +145,10 @@ a:hover {
line-height: 1.4em; line-height: 1.4em;
} }
.status-el .media-body { .status-content.media-body {
flex: 1; flex: 1;
padding: 0; padding: 0;
white-space: pre-wrap;
} }
.container, .item { .container, .item {

View File

@ -1,4 +1,4 @@
import strutils, strformat, htmlgen, xmltree import strutils, strformat, htmlgen, xmltree, times
import regex import regex
import ./types, ./utils import ./types, ./utils
@ -8,7 +8,7 @@ from unicode import Rune, `$`
const const
urlRegex = re"((https?|ftp)://(-\.)?([^\s/?\.#]+\.?)+(/[^\s]*)?)" urlRegex = re"((https?|ftp)://(-\.)?([^\s/?\.#]+\.?)+(/[^\s]*)?)"
emailRegex = re"([a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+)" emailRegex = re"([a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+)"
usernameRegex = re"(^|[^\S\n]|\.)@([A-z0-9_]+)" usernameRegex = re"(^|[^\S\n]|\.|>)@([A-z0-9_]+)"
picRegex = re"pic.twitter.com/[^ ]+" picRegex = re"pic.twitter.com/[^ ]+"
cardRegex = re"(https?://)?cards.twitter.com/[^ ]+" cardRegex = re"(https?://)?cards.twitter.com/[^ ]+"
ellipsisRegex = re" ?…" ellipsisRegex = re" ?…"
@ -48,14 +48,14 @@ proc reUsernameToLink*(m: RegexMatch; s: string): string =
pretext & toLink("/" & username, "@" & username) pretext & toLink("/" & username, "@" & username)
proc linkifyText*(text: string): string = proc linkifyText*(text: string): string =
result = text.stripText() result = xmltree.escape(stripText(text))
result = result.replace("\n", "<br>")
result = result.replace(ellipsisRegex, "") result = result.replace(ellipsisRegex, "")
result = result.replace(usernameRegex, reUsernameToLink)
result = result.replace(emailRegex, reEmailToLink) result = result.replace(emailRegex, reEmailToLink)
result = result.replace(urlRegex, reUrlToLink) result = result.replace(urlRegex, reUrlToLink)
result = result.replace(re"([A-z0-9\):;.])<a", "$1 <a") result = result.replace("\n", "<br>")
result = result.replace(re"</a>\s+([;.,\)])", "</a>$1") result = result.replace(usernameRegex, reUsernameToLink)
result = result.replace(re"([^\s\(\n])<a", "$1 <a")
result = result.replace(re"</a>\s+([;.,!\)']|&apos;)", "</a>$1")
proc stripTwitterUrls*(text: string): string = proc stripTwitterUrls*(text: string): string =
result = text result = text
@ -92,3 +92,6 @@ proc pageTitle*(profile: Profile): string =
proc pageTitle*(page: string): string = proc pageTitle*(page: string): string =
&"{page} | Nitter" &"{page} | Nitter"
proc getTime*(tweet: Tweet): string =
tweet.time.format("d/M/yyyy', ' HH:mm:ss")

View File

@ -44,7 +44,7 @@ proc parseQuote*(quote: XmlNode): Quote =
result = Quote( result = Quote(
id: quote.getAttr("data-item-id"), id: quote.getAttr("data-item-id"),
link: quote.getAttr("href"), link: quote.getAttr("href"),
text: quote.selectText(".QuoteTweet-text").stripTwitterUrls() text: getQuoteText(quote)
) )
result.profile = Profile( result.profile = Profile(

View File

@ -42,6 +42,17 @@ proc emojify*(node: XmlNode) =
for i in node.querySelectorAll(".Emoji"): for i in node.querySelectorAll(".Emoji"):
i.add newText(i.getAttr("alt")) i.add newText(i.getAttr("alt"))
proc getQuoteText*(tweet: XmlNode): string =
let
text = tweet.querySelector(".QuoteTweet-text")
hasEmojis = not text.querySelector(".Emoji").isNil
if hasEmojis:
emojify(text)
result = stripText(selectText(text, ".tweet-text"))
result = stripTwitterUrls(result)
proc getTweetText*(tweet: XmlNode): string = proc getTweetText*(tweet: XmlNode): string =
let let
selector = ".tweet-text > a.twitter-timeline-link.u-hidden" selector = ".tweet-text > a.twitter-timeline-link.u-hidden"

View File

@ -3,7 +3,7 @@
# #
#proc renderMain*(body: string; title="Nitter"): string = #proc renderMain*(body: string; title="Nitter"): string =
<!DOCTYPE html> <!DOCTYPE html>
<html> <html lang="en">
<head> <head>
<title>${xmltree.escape(title)}</title> <title>${xmltree.escape(title)}</title>
<link rel="stylesheet" type="text/css" href="/style.css"> <link rel="stylesheet" type="text/css" href="/style.css">

View File

@ -21,9 +21,7 @@
${linkUser(tweet.profile, class="username")} ${linkUser(tweet.profile, class="username")}
</div> </div>
<span class="heading-right"> <span class="heading-right">
<a href="${tweet.link}" class="timeago faint-link"> <a href="${tweet.link}" title="${tweet.getTime()}">${tweet.shortTime}</a>
<time title="${tweet.time.format("d/M/yyyy', ' HH:mm:ss")}">${tweet.shortTime}</time>
</a>
</span> </span>
</div> </div>
</div> </div>
@ -32,7 +30,7 @@
#proc renderQuote(quote: Quote): string = #proc renderQuote(quote: Quote): string =
#let hasMedia = quote.thumb.isSome() or quote.sensitive #let hasMedia = quote.thumb.isSome() or quote.sensitive
<div class="quote"> <div class="quote">
<div class="quote-container" href="${quote.link}"> <div class="quote-container">
<a class="quote-link" href="${quote.link}"></a> <a class="quote-link" href="${quote.link}"></a>
#if hasMedia: #if hasMedia:
<div class="quote-media-container"> <div class="quote-media-container">
@ -56,7 +54,7 @@
${linkUser(quote.profile, class="fullname")} ${linkUser(quote.profile, class="fullname")}
${linkUser(quote.profile, class="username")} ${linkUser(quote.profile, class="username")}
</div> </div>
<div class="quote-text">${linkifyText(xmltree.escape(quote.text))}</div> <div class="quote-text">${linkifyText(quote.text)}</div>
</div> </div>
</div> </div>
#end proc #end proc
@ -65,7 +63,7 @@
#let groups = if tweet.photos.len > 2: tweet.photos.distribute(2) else: @[tweet.photos] #let groups = if tweet.photos.len > 2: tweet.photos.distribute(2) else: @[tweet.photos]
#let display = if groups.len == 1 and groups[0].len == 1: "display: table-caption;" else: "" #let display = if groups.len == 1 and groups[0].len == 1: "display: table-caption;" else: ""
#var first = true #var first = true
<div class="attachments media-body" style="${display}"> <div class="attachments" style="${display}">
#for photos in groups: #for photos in groups:
#let margin = if not first: "margin-top: .25em;" else: "" #let margin = if not first: "margin-top: .25em;" else: ""
#let flex = if photos.len > 1 or groups.len > 1: "display: flex;" else: "" #let flex = if photos.len > 1 or groups.len > 1: "display: flex;" else: ""
@ -87,7 +85,7 @@
#end proc #end proc
# #
#proc renderVideo(video: Video): string = #proc renderVideo(video: Video): string =
<div class="attachments media-body"> <div class="attachments">
<div class="gallery-row" style="max-height: unset;"> <div class="gallery-row" style="max-height: unset;">
<div class="attachment image"> <div class="attachment image">
<video poster=${video.thumb.getSigUrl("pic")} autoplay muted loop></video> <video poster=${video.thumb.getSigUrl("pic")} autoplay muted loop></video>
@ -100,7 +98,7 @@
#end proc #end proc
# #
#proc renderGif(gif: Gif): string = #proc renderGif(gif: Gif): string =
<div class="attachments media-body media-gif"> <div class="attachments media-gif">
<div class="gallery-row" style="max-height: unset;"> <div class="gallery-row" style="max-height: unset;">
<div class="attachment image"> <div class="attachment image">
<video class="gif" poster=${gif.thumb.getSigUrl("pic")} autoplay muted loop> <video class="gif" poster=${gif.thumb.getSigUrl("pic")} autoplay muted loop>
@ -127,9 +125,7 @@
<div class="status-body"> <div class="status-body">
${renderHeading(tweet)} ${renderHeading(tweet)}
<div class="status-content-wrapper"> <div class="status-content-wrapper">
<div class="status-content media-body"> <div class="status-content media-body">${linkifyText(tweet.text)}</div>
${linkifyText(xmltree.escape(tweet.text))}
</div>
</div> </div>
#if tweet.photos.len > 0: #if tweet.photos.len > 0:
${renderMediaGroup(tweet)} ${renderMediaGroup(tweet)}

View File

@ -18,7 +18,7 @@
<div class="profile-bio"> <div class="profile-bio">
#if profile.bio.len > 0: #if profile.bio.len > 0:
<div class="profile-bio"> <div class="profile-bio">
<p>${linkifyText(xmltree.escape(profile.bio))}</p> <p>${linkifyText(profile.bio)}</p>
</div> </div>
#end if #end if
</div> </div>