| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869 |
- import std/[macros, htmlgen, unicode]
- import ".."/../[formatters, utils]
- type
- ReplaceSliceKind* = enum
- rkRemove, rkUrl, rkHashtag, rkMention
- ReplaceSlice* = object
- slice*: Slice[int]
- kind*: ReplaceSliceKind
- url*, display*: string
- proc cmp*(x, y: ReplaceSlice): int = cmp(x.slice.a, y.slice.b)
- proc dedupSlices*(s: var seq[ReplaceSlice]) =
- var
- len = s.len
- i = 0
- while i < len:
- var j = i + 1
- while j < len:
- if s[i].slice.a == s[j].slice.a:
- s.del j
- dec len
- else:
- inc j
- inc i
- proc extractHashtags*(result: var seq[ReplaceSlice]; slice: Slice[int]) =
- result.add ReplaceSlice(kind: rkHashtag, slice: slice)
- proc extractUrls*[T](result: var seq[ReplaceSlice]; entity: T;
- textLen: int; hideTwitter = false) =
- let
- link = entity.expandedUrl
- slice = entity.indices
- if hideTwitter and slice.b.succ >= textLen and link.isTwitterUrl:
- if slice.a < textLen:
- result.add ReplaceSlice(kind: rkRemove, slice: slice)
- else:
- result.add ReplaceSlice(kind: rkUrl, url: link,
- display: link.shortLink, slice: slice)
- proc replacedWith*(runes: seq[Rune]; repls: openArray[ReplaceSlice];
- textSlice: Slice[int]): string =
- template extractLowerBound(i: int; idx): int =
- if i > 0: repls[idx].slice.b.succ else: textSlice.a
- result = newStringOfCap(runes.len)
- for i, rep in repls:
- result.add $runes[extractLowerBound(i, i - 1) ..< rep.slice.a]
- case rep.kind
- of rkHashtag:
- let
- name = $runes[rep.slice.a.succ .. rep.slice.b]
- symbol = $runes[rep.slice.a]
- result.add a(symbol & name, href = "/search?q=%23" & name)
- of rkMention:
- result.add a($runes[rep.slice], href = rep.url, title = rep.display)
- of rkUrl:
- result.add a(rep.display, href = rep.url)
- of rkRemove:
- discard
- let rest = extractLowerBound(repls.len, ^1) ..< textSlice.b
- if rest.a <= rest.b:
- result.add $runes[rest]
|