summaryrefslogtreecommitdiff
path: root/src/clarktown/parsers/list_block.clj
diff options
context:
space:
mode:
authorAsko Nõmm <asko@bien.ee>2022-04-19 17:50:19 +0300
committerAsko Nõmm <asko@bien.ee>2022-04-19 17:50:19 +0300
commit52203a49aa544b2c11c96445d8732893160c436b (patch)
tree84d7b0e9af92770647643bdf7ddbb898663bd7b8 /src/clarktown/parsers/list_block.clj
parent059bfa7bd9bfdde0c75646bf1dfc20d23da8a02c (diff)
WIP #16
Pretty much done. Needs more testing. And new documentation.
Diffstat (limited to 'src/clarktown/parsers/list_block.clj')
-rw-r--r--src/clarktown/parsers/list_block.clj127
1 files changed, 0 insertions, 127 deletions
diff --git a/src/clarktown/parsers/list_block.clj b/src/clarktown/parsers/list_block.clj
deleted file mode 100644
index 52f955f..0000000
--- a/src/clarktown/parsers/list_block.clj
+++ /dev/null
@@ -1,127 +0,0 @@
-(ns clarktown.parsers.list-block
- (:require
- [clojure.string :as string]))
-
-
-(defn is?
- "Determines whether we're dealing with a list block or not."
- [block]
- (->> (string/trim block)
- (re-matches #"(?s)^(\d\.\s|\*{1}\s|\-{1}\s).*$")))
-
-
-(defn string->indent-n
- "Returns the indentation count from left of `str`, which must be
- in spaces and not tabs."
- [str]
- (count (take-while #{\space} str)))
-
-
-(defn compose-items-with-indent-guides
- "Composes a vector of maps from given `block` that adds a unique
- ID to each line as well as its `indent-n` which is used later
- on to determine hierarchies. "
- [block]
- (->> (string/split-lines block)
- (mapv
- (fn [line]
- {:id (random-uuid)
- :indent-n (string->indent-n line)
- :value (-> line
- string/trim)}))))
-
-
-(defn find-parent-id
- "Assuming a 1-level `items`, will attempt to find the parent `id`
- of the item at given `index`. Will return `nil` otherwise."
- [items index]
- (let [indent-n-at-index (:indent-n (nth items index))]
- (-> (->> (split-at index items)
- first
- reverse
- (remove #(or (> (:indent-n %) indent-n-at-index)
- (= (:indent-n %) indent-n-at-index)))
- first
- :id))))
-
-
-(defn compose-items-with-parents
- "Composes a 1-level list of items from `block` and adds parent
- information to each if they belong to another item. The result
- of this is used to build the final data tree."
- [block]
- (let [items (compose-items-with-indent-guides block)]
- (->> items
- (map-indexed
- (fn [index line]
- (merge line {:parent (find-parent-id items index)}))))))
-
-
-(defn add-to-parent
- "Recursively scans `items`, which can be multiple levels deep,
- and tries to find a home for `item` according to its parent ID."
- [items item]
- (->> items
- (mapv
- (fn [i]
- (if (= (:id i) (:parent item))
- (if (:items i)
- (assoc i :items (concat (:items i) [item]))
- (assoc i :items [item]))
- (if (:items i)
- (assoc i :items (add-to-parent (:items i) item))
- i))))))
-
-
-(defn compose-item-tree
- "Given a `block`, composes a data representation of it based on
- the indentation of each line."
- [block]
- (loop [result []
- items (compose-items-with-parents block)]
- (if (empty? items)
- result
- (let [item (first items)
- parent (:parent item)
- new-item {:id (:id item)
- :value (:value item)}]
- (recur (if parent
- (add-to-parent result item)
- (concat result [new-item]))
- (drop 1 items))))))
-
-
-(defn render-items
- "Renders an ordered/un-ordered list hierarchy from given `items`."
- [items]
- (loop [result ""
- inner-items items]
- (if (empty? inner-items)
- (if (or (string/starts-with? (:value (first items)) "*")
- (string/starts-with? (:value (first items)) "-"))
- (str "<ul>" result "</ul>")
- (str "<ol>" result "</ol>"))
- (let [inner-item (first inner-items)
- value (cond
- ; * unordered list
- (string/starts-with? (:value inner-item) "*")
- (-> (string/replace-first (:value inner-item) "*" "")
- string/trim)
- ; - unordered list
- (string/starts-with? (:value inner-item) "-")
- (-> (string/replace-first (:value inner-item) "-" "")
- string/trim)
- :else
- (-> (string/replace-first (:value inner-item) #"\d\." "")
- string/trim))]
- (recur (if (:items inner-item)
- (str result "<li>" value (render-items (:items inner-item)) "</li>")
- (str result "<li>" value "</li>"))
- (drop 1 inner-items))))))
-
-
-(defn render
- "Renders the list block"
- [block _]
- (-> (compose-item-tree block)
- (render-items))) \ No newline at end of file