Created
October 2, 2018 14:22
-
-
Save crofty/6d13ed6be38d547a2a355039de828a15 to your computer and use it in GitHub Desktop.
Document serialization
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns doc-serialization.core) | |
(def block-tags | |
{"h2" :h2 | |
"h3" :h3 | |
"h4" :h4 | |
"p" :p}) | |
(defn serialize-leaf [leaf] | |
[:span (:text leaf)]) | |
(def serialization-rules | |
[(fn [{:keys [object] :as node} children] | |
(if (= "document" object) | |
children)) | |
(fn [{:keys [object leaves]} _] | |
(if (= "text" object) | |
(map serialize-leaf leaves))) | |
(fn [{:keys [object]} children] | |
(if (= "inline" object) | |
`([:span ~@children]))) | |
(fn [{:keys [object type data]} children] | |
(let [tag (get block-tags type)] | |
(if (and (= "block" object) tag) | |
`([~tag | |
~@(if-let [c (:count data)] [[:span (str c ". ")]]) | |
~@children])))) | |
(fn [{:keys [object type]} children] | |
(if (= "block" object) | |
`([:div ~@children])))]) | |
(defn serialize-node-to-hiccup [node] | |
(let [flat-children (mapcat identity (:nodes node))] | |
(some #(% node flat-children) serialization-rules))) | |
(defn prewalk-node [f node] | |
(update (f node) :nodes (partial map (partial prewalk-node f)))) | |
(defn postwalk-node [f node] | |
(f (update node :nodes (partial map (partial postwalk-node f))))) | |
(defn increment-counter-at-depth [depth counts] | |
(->> (update counts (dec depth) inc) | |
(map-indexed #(if (> %1 (dec depth)) 0 %2)) | |
vec)) | |
(defn add-count-to-node [node] | |
(let [counts (volatile! [0 0 0])] | |
(prewalk-node | |
(fn [n] | |
(if-let [k (-> n :data :numbered)] | |
(let [depth (count (clojure.string/split k #"-"))] | |
(vreset! counts (increment-counter-at-depth depth @counts)) | |
(let [count-str (clojure.string/join "." (take depth @counts))] | |
(assoc-in n [:data :count] count-str))) | |
n)) | |
node))) | |
(defn serialize-document-to-hiccup [document] | |
(->> document | |
add-count-to-node | |
(postwalk-node serialize-node-to-hiccup))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment