summaryrefslogtreecommitdiff
path: root/desk/lib/post.hoon
diff options
context:
space:
mode:
Diffstat (limited to 'desk/lib/post.hoon')
-rw-r--r--desk/lib/post.hoon236
1 files changed, 236 insertions, 0 deletions
diff --git a/desk/lib/post.hoon b/desk/lib/post.hoon
new file mode 100644
index 0000000..a0816da
--- /dev/null
+++ b/desk/lib/post.hoon
@@ -0,0 +1,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]
+
+--