This repository has been archived by the owner on Apr 29, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
text.clj
162 lines (149 loc) · 6.47 KB
/
text.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
(ns oc.lib.text
"Functions related to processing text."
(:require [clojure.string :as s]
[cuerdas.core :as str]
[jsoup.soup :as soup]))
(defn attribution
"
Given the number of distinct authors to mention, the number of items, what to call the
item (needs to pluralize with just an 's'), and a sequence of authors of the items
to attribute (sequence needs to be distinct'able, and have a `:name` property per author),
return a text string that attributes the authors to the items.
E.g.
(attribution 3 7 'comment' [{:name 'Joe'} {:name 'Joe'} {:name 'Moe'} {:name 'Flo'} {:name 'Flo'} {:name 'Sue'}])
'7 comments by Joe, Moe, Flo and others'
"
[attribution-count item-count item-name authors]
(let [distinct-authors (distinct authors)
author-names (map :name (take attribution-count distinct-authors))
more-authors? (> (count distinct-authors) (count author-names))
multiple-authors? (> (count author-names) 1)
author-attribution (cond
;; more distinct authors than we are going to mention
more-authors?
(str (clojure.string/join ", " author-names) " and others")
;; more than 1 author so last mention needs an "and", not a comma
multiple-authors?
(str (clojure.string/join ", " (butlast author-names))
" and "
(last author-names))
;; just 1 author
:else
(first author-names))]
(str item-count " " item-name (when (> item-count 1) "s") " by " author-attribution)))
(defn strip-xss-tags
"
Current xss tags are script, style, and input.
"
[data]
(when data (s/replace data #"(?i)<\/?((script|style|input){1})(\s?[^<>]*)>" "")))
(defn- clean-body-text [body]
(-> body
(s/replace #" " " ")
(str/strip-tags)
(str/strip-newlines)))
(def body-words 20)
(defn truncated-body [body]
(let [clean-body (if-not (clojure.string/blank? body)
(clean-body-text (.text (soup/parse body)))
"")
splitted-body (clojure.string/split clean-body #" ")
truncated-body (filter not-empty
(take body-words ;; 20 words is the average sentence
splitted-body))
reduced-body (str (clojure.string/join " " truncated-body)
(when (= (count truncated-body) body-words)
"..."))]
reduced-body))
(defn replies-summary-text
"Given a replies summary map, creates a phrase like:
- Sean Johnson left replies on updates you care about.
- Sean Johnson and Stuart Levinson left replies on updates you care about.
- Sean Johnson, Stuart Levinson and 1 other left 6 replies on updates you care about.
- Sean Johnson, Stuart Levinson and 2 others left 6 replies on updates you care about."
[{:keys [comment-count comment-authors entry-count]
:or {comment-count 0 comment-authors 0 entry-count 0}}]
(when (pos? comment-count)
(let [space-join (fn [& parts] (s/join " " parts))
author-name (fn [n & [suffix]] (-> comment-authors (nth n) :name (str suffix)))
authors-string (case (count comment-authors)
1 (author-name 0)
2 (space-join (author-name 0) "and" (author-name 1))
3 (space-join (author-name 0 ",") (author-name 1) "and 1 other")
(space-join (author-name 0 ",") (author-name 1 ",") "and" (- (count comment-authors) 2) "others"))
replies-string (case comment-count
1 "left a"
"left")
replies-word (case comment-count
1 "reply"
"replies")
updates-string (case entry-count
1 "on an update"
"on updates")
care-string "you care about."]
[:p.digest-replies-section
authors-string
" "
replies-string
" "
[:span.underline
replies-word]
" "
updates-string
" "
care-string])))
(defn new-boards-summary-node
"Give the newly created boards list, creates a phrase like:
- Since your last digest, 1 topic was created: New topic.
- Since your last digest, 2 topics were created: First topic and Second topic.
- Since your last digest, 3 topics were created: First topic, Second topic and Third topic.
- Since your last digest, 4 topics were created: First topic, Second topic, Third topic and Fourth topic."
[new-boards-list board-url-fn]
(let [board-count (count new-boards-list)]
(when-not (zero? board-count)
(case board-count
1 [:p.digest-new-boards-section
"Since your last digest, "
[:a
{:href (board-url-fn "topics")}
"1 topic "]
"was created: "
[:a
{:href (board-url-fn (-> new-boards-list first :slug))}
(-> new-boards-list first :name)]
"."]
2 [:p.digest-new-boards-section
"Since your last digest, "
[:a
{:href (board-url-fn "topics")}
board-count " topics "]
"were created: "
[:a
{:href (board-url-fn (-> new-boards-list first :slug))}
(-> new-boards-list first :name)]
" and "
[:a
{:href (board-url-fn (-> new-boards-list second :slug))}
(-> new-boards-list second :name)]
"."]
[:p.digest-new-boards-section
"Since your last digest, "
[:a
{:href (board-url-fn "topics")}
board-count " topics "]
"were created: "
(for [b (subvec new-boards-list 0 (- board-count 2))]
[:span
" "
[:a
{:href (board-url-fn (:slug b))}
(:name b)]
","])
[:a
{:href (board-url-fn (-> new-boards-list butlast last :slug))}
(-> new-boards-list butlast last :name)]
" and "
[:a
{:href (board-url-fn (-> new-boards-list last :slug))}
(-> new-boards-list last :name)]
"."]))))