-
Notifications
You must be signed in to change notification settings - Fork 0
/
list.clj
51 lines (45 loc) · 1.47 KB
/
list.clj
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
(ns cljmd.ast.list
(:require [squirrel.node :refer [node add]]
[flatland.useful.fn :as ufn]
[cljmd.ast.predicate :as pred]
[cljmd.ast.list.item :as item]))
(defn delimiter
"Classifies as either \"paren\" or \"period\" if ordered, nil otherwise."
[marker]
(as-> marker v
(re-find #"^\d{1,9}([.)])$" v)
(second v)
(ufn/fix v #{")"} "paren"
#{"."} "period"
nil)))
(defn start
"The number to start from if ordered (as a string), nil otherwise."
[marker]
(->> marker
(re-find #"^(\d{1,9})[.)]$")
second))
(defn tight?
"True if items comprise a tight list, false otherwise."
[items]
(and (->> items butlast (not-any? pred/blank?))
(every? item/tight? items)))
(defn empty-for
"List AST node with no children, configured for marker."
[marker tight?]
(let [list-type (-> marker item/marker-type name)
delimiter (delimiter marker)
start (start marker)]
(node (cond-> {:tag :list
:type list-type
:tight (str tight?)}
delimiter (assoc :delimiter delimiter)
start (assoc :start start)))))
(defn from-items
"AST node which represents a list comprising items."
[items]
(let [marker (-> items first :data :marker)
root (empty-for marker (tight? items))]
(->> items
(remove pred/blank?)
(map #(assoc % :data {:tag :li}))
(reduce add root))))