diff options
| author | Asko Nõmm <asko@nmm.ee> | 2025-09-14 14:40:01 +0300 |
|---|---|---|
| committer | Asko Nõmm <asko@nmm.ee> | 2025-09-14 14:40:01 +0300 |
| commit | 37b555f71ea6ebaea9ff183f186abc46cf9b1a67 (patch) | |
| tree | cd2fb542c4654af2bb4446a442fdc3550a813379 /src/dompa/nodes.cljc | |
| parent | c9fb6f1c80a83f9e8ea88f7db3caedae57985fd7 (diff) | |
Restructure and start working on tests
Diffstat (limited to 'src/dompa/nodes.cljc')
| -rw-r--r-- | src/dompa/nodes.cljc | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/src/dompa/nodes.cljc b/src/dompa/nodes.cljc new file mode 100644 index 0000000..d035116 --- /dev/null +++ b/src/dompa/nodes.cljc @@ -0,0 +1,59 @@ +(ns dompa.nodes) + +(def ^:private default-void-nodes + #{:!doctype :area :base :br :col :embed :hr :img :input + :link :meta :source :track :wbr}) + +(defn- node->html-reducer-fn + [void-nodes nodes->html-fn] + (fn [html node] + (cond + (= (-> node :name) :dompa/text) + (str html (-> node :value)) + + (contains? void-nodes (-> node :name)) + (str "<" (-> node :name) ">") + + :else + (let [value (nodes->html-fn (-> node :children))] + (str "<" (-> node :name) ">" value "</" (-> node :name) ">"))))) + +(defn traverse + "Recursively traverses given tree of `nodes` with a `traverser-fn` + that gets a single node passed to it and returns a new updated tree. + If the traverses function returns `nil`, the node will be removed. + In any other case the node will be replaced. If you wish to keep + a node unchanged, just return it as-is." + [nodes traverser-fn] + (-> (fn [updated-nodes node] + (if-let [updated-node (traverser-fn node)] + (let [children (traverse (-> updated-node :children) traverser-fn)] + (conj updated-nodes (assoc updated-node :children children))) + updated-nodes)) + (reduce [] nodes))) + +(defn ->html + "Transform a vector of `nodes` into an HTML string. + + Options: + - `void-nodes` - A set of node names that are self-closing, defaults to: + - `:!doctype` + - `:area` + - `:base` + - `:br` + - `:col` + - `:embed` + - `:hr` + - `:img` + - `:input` + - `:link` + - `:meta` + - `:source` + - `:track` + - `:wbr` + " + ([nodes] + (->html nodes {:void-nodes default-void-nodes})) + ([nodes {:keys [void-nodes]}] + (-> (node->html-reducer-fn void-nodes ->html) + (reduce "" nodes))))
\ No newline at end of file |
