urbit/pkg/base-dev/mar/story.hoon

158 lines
6.4 KiB
Plaintext
Raw Normal View History

/- *story
2022-01-31 00:01:45 +03:00
/+ *story
2022-01-16 07:37:51 +03:00
!:
|_ tale=story
+$ story-additions [entry-additions=story prose-additions=story]
+$ story-deletions [entry-deletions=story prose-deletions=story]
+$ story-diff [additions=story-additions deletions=story-deletions]
::
2022-01-16 07:37:51 +03:00
++ grad
|%
++ form %story-diff
++ diff
:: diff between given story, tale and another story, tory
2022-01-16 07:37:51 +03:00
|= tory=story
^- story-diff
:: Given tory (new story),
:: tale (old story),
::
:: the map of additions is defined as:
:: any entries that are present in the new story but not in the old one,
:: in conjunction with any additions to the set of proses for existing keys
::
:: given shared-keys := keys-new AND keys-old
:: entry-additions = (new-story - old-story) :: entries present in new-story but not in old-story
:: prose-additions = :: for the entries that are present in both, the values only contain proses not found in old-story
:: for key in shared-keys, val-new in new-story, val-old in old-story:
:: [key (val-new - val-old)]
:: additions = entry-additions UNION prose-additions
::
:: deletions is the same thing, but with new and old swapped.
:: (so anything not in the new but still in the old)
::
=/ entry-additions (~(dif by tory) tale) :: tory(new) - tale(old)
=/ entry-deletions (~(dif by tale) tory) :: tale(old) - tory(new)
::
:: a map with only those kv-pairs that are in both tory and tale.
:: used to filter out any entries that were not in one or the other while calculating the set differences
:: we keep it as a map so that it can be used in int by
:: but we discard all of its values because we overwrite them in the next step
::
=/ entries-both (~(int by tale) tory)
::
:: A - all entries in (tory(new) - tale(old)) + all entries in (tale(old) - tory(new)), but,
:: if the key of an entry is present in both, the final value of that entry will be (val:tory(new) - val:tale(tale))
:: B - only those entries in A whose keys are present in both tory(new) and tale(old)
::
=/ prose-additions
%- ~(int by entries-both) :: B
%- (~(uno by tory) tale) :: A
|= [k=tako:clay proses-tory=(set prose) proses-tale=(set prose)]
^- (set prose)
(~(dif in proses-tory) proses-tale)
::
=/ prose-deletions
%- ~(int by entries-both)
%- (~(uno by tale) tory)
|= [k=tako:clay proses-tale=(set prose) proses-tory=(set prose)]
^- (set prose)
(~(dif in proses-tale) proses-tory)
::
:: invariant (~(int by entry-additions) prose-additions) = ~
:: and vice versa for deletions
:: =/ additions=story (~(uni by entry-additions) prose-additions)
:: =/ deletions=story (~(uni by entry-deletions) prose-deletions)
[[entry-additions prose-additions] [entry-deletions prose-deletions]]
2022-01-16 07:37:51 +03:00
++ pact
:: given tale=story, compute the new story after applying the given dif
|= dif=story-diff
^- story
:: XX code clean up: better way to declare vars
=/ [[entry-additions=story prose-additions=story] [entry-deletions=story prose-deletions=story]] dif
=. tale (~(uni by tale) entry-additions) :: add completely new entries
=. tale :: add new proses to existing entries
%- (~(uno by tale) prose-additions)
|= [k=tako:clay proses-tale=(set prose) proses-additions=(set prose)]
^- (set prose)
(~(uni in proses-tale) proses-additions)
2022-01-16 07:37:51 +03:00
::
=. tale (~(dif by tale) entry-deletions) :: remove any entries which should not be present
=. tale :: remove any proses from existing entries
%- ~(urn by tale)
|= [k=tako:clay proses=(set prose)]
^- (set prose)
:: This works because get:ju returns the empty set if the key isn't found
=/ proses-del=(set prose) (~(get ju prose-deletions) k)
(~(dif in proses) proses-del)
2022-01-16 07:37:51 +03:00
::
tale
2022-01-16 07:37:51 +03:00
++ join
|= [ali=story-diff bob=story-diff]
^- (unit story-diff)
=/ joined-entry-adds (~(uni by entry-additions.additions.ali) entry-additions.additions.bob)
=/ joined-proses-adds
%- (~(uno by prose-additions.additions.ali) prose-additions.additions.bob)
|= [k=tako:clay proses-a=(set prose) proses-b=(set prose)]
^- (set prose)
(~(uni in proses-a) proses-b)
::
=/ joined-entry-dels (~(uni by entry-deletions.deletions.ali) entry-deletions.deletions.bob)
=/ joined-deletion-dels
%- (~(uno by prose-deletions.deletions.ali) prose-deletions.deletions.bob)
|= [k=tako:clay proses-a=(set prose) proses-b=(set prose)]
^- (set prose)
(~(uni in proses-a) proses-b)
2022-01-16 07:37:51 +03:00
:: in a true join, we'd do an intersection and see if the vals are not exactly the same
:: which means we have a conflict, then we'd produce null, kick the flow to mash
%- some
[[joined-entry-adds joined-proses-adds] [joined-entry-dels joined-deletion-dels]]
2022-01-16 07:37:51 +03:00
++ mash
:: called by meld, force merge, annotating conflicts
|= $: [als=ship ald=desk ali=story-diff]
[bos=ship bod=desk bob=story-diff]
==
^- story-diff
(need (join ali bob)) :: XX temporary, only because join doesn't fail
--
::
++ grow :: convert to
|% ::
++ mime :: to %mime
[/text/x-urb-story (as-octs:mimes:html (of-wain:format txt))]
++ txt
^- wain
2022-01-26 19:41:08 +03:00
:: XX code clean up: cleaner snoc
%+ snoc :: ensures terminating newline is present
%+ murn ~(tap by tale)
2022-01-30 23:59:58 +03:00
|= [[=tako:clay =proses]]
2022-01-26 19:41:08 +03:00
^- (unit cord)
?~ proses ~
%- some
2022-01-26 19:41:08 +03:00
%- crip
;: welp
2022-01-30 23:59:58 +03:00
(tako-to-text tako)
(proses-to-text proses)
2022-01-26 19:41:08 +03:00
"---"
==
''
--
++ grab
|% :: convert from
++ noun story :: clam from %noun
++ mime :: retrieve form %mime
|= [p=mite q=octs]
=/ story-text `@t`q.q
2022-01-31 00:01:31 +03:00
=/ parsed-story `(list [@uv (list [@t wain])])`(rash story-text parse-story)
^- story
%- ~(gas by *story)
%+ turn parsed-story
2022-01-31 00:01:31 +03:00
|= [tak=tako:clay proses-list=(list [@t wain])]
^- chapter
:- tak
%- silt
2022-01-31 00:01:31 +03:00
%+ turn proses-list
|= [[title=@t body=(list @t)]]
[title (of-wain:format body)]
--
--