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
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
|
/- post=trill-post
|%
++ node-to-full
|= [p=post:post f=feed:post] ^- full-node:post
p(children (convert-children children.p f))
++ convert-children
|= [children=(set id:post) f=feed:post]
^- full-graph:post
%- ~(rep in children)
|= [=id:post acc=full-graph:post]
=/ n (get:orm:post f id)
?~ n acc
=/ full-node (node-to-full u.n f)
(put:form:post acc id full-node)
++ sanitize
|= c=contents:contents-1:post ^- ?
%+ roll c |= [i=block:contents-1:post acc=_&]
?. ?=(%paragraph -.i) acc
%+ roll p.i |= [ii=inline:contents-1:post iacc=_acc]
?. ?=(%link -.ii) iacc
?~ (de-purl:html href.ii) .n .y
++ block-size
|= =block:contents-1:post
?- -.block
%tasklist 0 :: TODO
%paragraph (inline-size p.block)
%blockquote (inline-size p.block)
%heading (lent (trip p.block))
%list (inline-size p.block)
%media (media-size media.block)
%codeblock
?: (gth (lent (trip lang.block)) 400) 10.000
(lent (trip code.block))
%eval (lent (trip hoon.block))
%ref
?: (gth (lent (trip app.block)) 400) 10.000
(roll path.block |=([i=@t a=@] (add a (lent (trip i)))))
%json
?: (gth (lent (trip content.block)) 5.000) 10.000
?: (gth (lent (trip origin.block)) 1.000) 10.000
0
%table
%+ roll rows.block |= [i=(list contents:contents-1:post) a=@]
=/ inner-count=@
%+ roll i |= [ii=contents:contents-1:post ia=@]
(add ia (post-size ii))
(add inner-count a)
==
++ post-size
|= c=contents:contents-1:post
=| count=@
|-
?~ c count
=/ lc=@ (block-size i.c)
$(c t.c, count (add count lc))
++ inline-token-size
|= i=inline:contents-1:post ^- @ud
?+ -.i (lent (trip p.i))
%break 1
%date 1
%note (add (met 3 id.i) 10):: TODO)
%ship (lent (trip (scot %p p.i)))
%ruby (lent (trip p.i))
%link
?: (gth (lent (trip href.i)) 400) 10.000 :: to prevent hacking through a huge href string
(lent (trip show.i))
==
++ reduce-inline
|= [i=inline:contents-1:post chars=@ud] ^+ i
?- -.i
%break i
%date i
%note i :: TODO
%ship [%text (crip (weld (scag chars (trip (scot %ud p.i))) "..."))]
%ruby i(p (crip (scag chars (trip p.i))))
%link i(show (crip (scag chars (trip show.i))))
%bold
[-.i (crip (scag chars (trip +.i)))]
%codespan
[-.i (crip (scag chars (trip +.i)))]
%italic
[-.i (crip (scag chars (trip +.i)))]
%strike
[-.i (crip (scag chars (trip +.i)))]
%sub
[-.i (crip (scag chars (trip +.i)))]
%sup
[-.i (crip (scag chars (trip +.i)))]
%text
[-.i (crip (weld (scag chars (trip +.i)) "..."))]
%underline
[-.i (crip (scag chars (trip +.i)))]
==
++ inline-size
|= l=(list inline:contents-1:post) ^- @
=| count=@ud
|-
?~ l count
=/ lc=@ud (inline-token-size i.l)
$(l t.l, count (add count lc))
++ media-size
|= =media:contents-1:post ^- @
?- -.media
%video (lent (trip p.media))
%audio (lent (trip p.media))
%images %+ roll p.media
|= [[url=@t caption=@t] a=@]
%+ add a (add (met 3 url) (met 3 caption))
==
++ search
|= [q=@t p=post:post] ^- ?
=/ latest=content-list:post val:head:(pop:corm:post contents.p)
=/ in-tags %+ roll ~(tap in tags.p) |= [i=cord a=_|]
?: (contains i q) %& a
=/ in-blocks %+ roll latest |= [i=block:contents-1:post a=_|]
?: ?- -.i
%paragraph (in-inline p.i q)
%blockquote (in-inline p.i q)
%list (in-inline p.i q)
%heading (contains p.i q)
%codeblock (contains code.i q)
%eval (contains hoon.i q)
%json (contains content.i q)
%media (in-media media.i q)
%ref %| :: TODO
%table %| :: TODO
%tasklist .n :: TODO
== %& a
?| in-tags in-blocks ==
++ contains
|= [container=cord query=cord] ^- ?
?~ (find (trip query) (trip container)) %| %&
++ in-media
|= [=media:contents-1:post q=@t] ^- ?
?. ?=(%images -.media) (contains p.media q)
%+ roll p.media |= [[url=cord caption=cord] a=_|]
?: ?| (contains url q) (contains caption q) == .y a
++ in-inline
|= [l=(list inline:contents-1:post) q=@t] ^- ?
%+ roll l |= [i=inline:contents-1:post a=_|]
?: ?+ -.i (contains p.i q)
%break %|
%ship (contains (scot %p p.i) q)
%date .n :: TODO
%note ?|((contains id.i q) (in-inline text.i q))
%link ?|((contains href.i q) (contains show.i q))
%ruby ?|((contains p.i q) (contains q.i q))
== %& a
++ is-my-reply
|= [p=post:post r=post:post our=@p] ^- ?
?~ parent.r .n
?& .=(author.r our) !.=(author.p our) ==
++ is-thread-child
|= [p=post:post r=post:post our=@p] ^- ?
?~ parent.r .n
?& .=(author.r our) .=(author.p our) ==
++ houyi
|= fn=full-node:post ^- @ud
?~ children.fn 0
=/ lst (tap:form:post children.fn)
%+ add (lent lst)
%+ roll lst
|= [[=id:post n=full-node:post] acc=@ud]
(add acc (houyi n))
::
++ abbreviate-post
|= [cm=content-map:post max-chars=@ud] ^- content-list:post
=/ c (latest-contents cm)
:: we reduce the list of blocks. We count how many characters are there in each block.
:: If the block fits in our count, we insert the block in the filtered list.
:: If not, we cut the content of the box until it does.
=/ ret=content-list:post
=< +<
%^ spin c [bl=*content-list:post available=max-chars]
|= [b=block:contents-1:post [bl=_c available=@ud]]
:: We must return the same data type as the input
:: We don't want to map on the individual block so return as is
:- b
:: The state tho is what we're playing with.
:: We pass the current block and the available char count to another function
=/ cut=[(unit block:contents-1:post) @ud] (cut-block b available)
:: That function checks whether the block fits within the available count.
:: It returns a maybe block and the remaining count
:: If null, we return the list as is
?~ -.cut [bl available]
:: If we get a block back, we add that to our block list, and update the available count
[[u.-.cut bl] +.cut]
(flop ret)
++ cut-block
:: now let's go inside the block
|= [b=block:contents-1:post available=@ud]
^- [(unit block:contents-1:post) @ud]
?+ -.b [~ 0]
:: :: This we can cut
%paragraph =/ inlines (cut-inlines p.b available)
?~ -.inlines [~ available] :- `[-.b -.inlines] +.inlines
:: :: these must go whole or nothing
:: :: %blockquote
:: :: %heading
:: :: %list
:: :: %media
:: :: %eval
:: :: %poll
:: :: %ref
:: :: %json
:: :: %table
==
++ cut-inlines
|= [li=(list inline:contents-1:post) available=@ud] ^+ [li available]
?: .=(0 available) [~ 0]
:: We spin again
=/ ret=[_li @ud]
=/ initial-state [*(list inline:contents-1:post) available]
=< +
%^ spin li initial-state
|= [l=inline:contents-1:post [nl=_li available=@ud]]
:: Again we're not mapping over the tokens, just mutating an internal state
:- l
:: If no more chars available we return of course
?: .=(0 available) [nl available]
:: We look at the size of the current token
=/ size (inline-token-size l)
:: If the size is smaller than available, we add to new list, and substract from available
?: (lte size available)
[[l nl] (sub available size)]
:: If size is bigger than available we reduce the token, insert to list, set avaibable as 0
=/ reduced (reduce-inline l available)
[[reduced nl] 0]
[(flop -.ret) +.ret]
--
|