site.fabricate.adorn namespace

Extensible, minimal API for adorn.

node-reserved-fields

clojure.lang.PersistentHashSet

Keywords used by rewrite-clj to designate node fields

reader-cond->span

function

token-types

clojure.lang.PersistentHashMap

node-attributes

function

Get the HTML element attributes for the given form.

Allows passing through arbitrary attributes (apart from the :class attr).

get-node-meta

function

Get the metadata to apply to the node itself from within the form-level metadata.

node-platform-class

function

coll->span

function

get-class

function

form-classes

clojure.lang.PersistentArrayMap

Mapping from form types to HTML classes

Intended for 'higher-level' forms than rewrite-clj supports as node types

->node

function

Normalize the rewrite-clj node for use in Adorn.

platform-classes

clojure.lang.PersistentHashMap

Classes for each platform

comment->span

function

html-class-defaults

clojure.lang.PersistentHashMap

node-html-classes

clojure.lang.PersistentHashMap

Default HTML class lookup for node types

->span

function

Convert the node to a Hiccup :span vector. Dispatches on the node tag.

whitespace->span

function

uneval->span

function

node-meta

function

node-data

function

newline->span

function

data-attributes

clojure.lang.PersistentArrayMap

HTML data attribute names for relevant information about forms

deref->span

function

get-form-meta

function

Get the form-level metadata by removing any keys with the :node namespace

split-node-metadata

function

src-info-keys

clojure.lang.PersistentHashSet

Keys used by rewrite-clj to record location info for a node

coll-delimiters

clojure.lang.PersistentArrayMap

meta->span

function

fn->span

function

syntax-quote->span

function

platform-class-strs

clojure.lang.PersistentHashMap

literal-type

function

Return the literal type for the given token node.

Intended to be consistent across clj+cljs.

node-clojure-type

function

var->span

function

token->span

function

keyword->span

function

Generate a Hiccup :span data structure from the given keyword node.

Separates the namespace from the keyword, if present.

*escapes*

clojure.lang.PersistentArrayMap

Escape character substitutions for HTML.

escape-html

function

symbol->span

function

Generate a Hiccup :span data structure from the given symbol.

Separates the namespace from the symbol, if present.

quote->span

function

unquote->span

function

tokens

clojure.lang.PersistentHashMap

Spans for individual components of Clojure forms.

apply-node-metadata

function

Rewrites the given node based on the type of metadata it has.

Metadata keywords beginning with the :node namespace prefix get applied to the node; all other metadata remains with the node itself. If all the metadata begins with the :node prefix, return the inner node with that metadata applied. Otherwise, return a metadata node with the node-specific metadata lifted to the node and the remaining metadata inside the node itself.

Non-metadata nodes are returned as-is.

Source code

(ns site.fabricate.adorn
"Extensible, minimal API for adorn."
(:require [site.fabricate.adorn.forms :as forms] ; refactor target TBD #_[site.fabricate.adorn.parse :as parse]
[rewrite-clj.node :as node]
[rewrite-clj.parser :as p]
[rewrite-clj.zip :as z])
)


(defn form-type
"Get the type of the node for display, defaulting to the tag returned by `forms/node-type`.

If `{:display-type :custom-type}` data has been added to the form, return the type. `:display-type` passed as an option in the options map takes precedence over existing node data. `:display-type` can also be a map indicating how child nodes should be handled, in which case the `:self*` entry is used for the top-level node."

([node opts]
(let [display-type (or (get opts :display-type)
(get node :display-type)
(get (meta node) :display-type)
(get node :type)
(get (meta node) :type)
(forms/node-clojure-type node))

self-display-type (or (when (map? display-type) (:self* display-type))
display-type)
]

(cond (keyword? self-display-type) self-display-type
(ifn? self-display-type) :display/fn
:default (forms/node-clojure-type node))
)
)

([node] (form-type node {})))



(defmulti form->hiccup
"Extensible display of arbitrary Clojure values and rewrite-clj nodes as Hiccup elements.

Falls back to defaults defined in `site.fabricate.adorn.forms` namespace for unimplemented values."

form-type)



;; TODO: figure out attribute passthrough for subnodes
(defmethod form->hiccup :display/fn
[node opts]
(let [display-fn (get opts :display-type)]
(display-fn (forms/->node node) opts))
)


(defmethod form->hiccup :display/map
([node {:keys [attrs display-type] :or {attrs {}} :as opts}]
#_(let [node (forms/->node node)
;; fall back to default if no self-display type is set self-display-fn (:self* display-type)
converted (if self-display-fn (self-display-fn node opts))]

;; this is tricky; how does conversion work for the child nodes? ;; does the self display type override this or combine them somehow? ;; (if (node/children node) '...))

(throw (ex-info "Display map not implemented" {:status "pre-alpha"})))
)


(defmethod form->hiccup :fn
([node {:keys [attrs] :or {attrs {}} :as opts}]
(forms/fn->span (forms/->node node) attrs form->hiccup))

([node] (forms/fn->span (forms/->node node) {} form->hiccup)))


(defmethod form->hiccup :meta
([node {:keys [attrs] :or {attrs {}} :as opts}]
(forms/meta->span (forms/->node node) attrs form->hiccup))

([node] (forms/meta->span (forms/->node node) {} form->hiccup)))


(defmethod form->hiccup :multi-line
([node {:keys [attrs] :or {attrs {}} :as opts}]
(forms/token->span (forms/->node node) attrs))

([node] (forms/token->span (forms/->node node) {})))


(defmethod form->hiccup :whitespace
([node {:keys [attrs] :or {attrs {}} :as opts}]
(forms/whitespace->span (forms/->node node) attrs))

([node] (forms/whitespace->span (forms/->node node) {})))


(defmethod form->hiccup :comma
([node {:keys [attrs] :or {attrs {}} :as opts}]
(forms/whitespace->span (forms/->node node)
(update attrs :classes conj "comma"))
)

([node] (forms/whitespace->span (forms/->node node) {:classes ["comma"]})))


(defmethod form->hiccup :uneval
([node {:keys [attrs] :or {attrs {}} :as opts}]
(forms/uneval->span (forms/->node node) attrs form->hiccup))

([node] (forms/uneval->span (forms/->node node) {} form->hiccup)))


(defmethod form->hiccup :vector
([node {:keys [attrs] :or {attrs {}} :as opts}]
(forms/coll->span (forms/->node node) attrs form->hiccup))

([node] (forms/coll->span (forms/->node node) {} form->hiccup)))


(defmethod form->hiccup :token
([node {:keys [attrs] :or {attrs {}} :as opts}]
(forms/token->span (forms/->node node) attrs))

([node] (forms/token->span (forms/->node node) {})))


(defmethod form->hiccup :syntax-quote
([node {:keys [attrs] :or {attrs {}} :as opts}]
(forms/syntax-quote->span (forms/->node node) attrs form->hiccup))

([node] (forms/syntax-quote->span (forms/->node node) {} form->hiccup)))


(defmethod form->hiccup :list
([node {:keys [attrs] :or {attrs {}} :as opts}]
(forms/coll->span (forms/->node node) attrs form->hiccup))

([node] (forms/coll->span (forms/->node node) {} form->hiccup)))


(defmethod form->hiccup :var
([node {:keys [attrs] :or {attrs {}} :as opts}]
(forms/var->span (forms/->node node) attrs))

([node] (forms/var->span (forms/->node node) {})))


(defmethod form->hiccup :quote
([node {:keys [attrs] :or {attrs {}} :as opts}]
(forms/quote->span (forms/->node node) attrs form->hiccup))

([node] (forms/quote->span (forms/->node node) {} form->hiccup)))


(defmethod form->hiccup :unquote
([node {:keys [attrs] :or {attrs {}} :as opts}]
(forms/unquote->span (forms/->node node) attrs form->hiccup))

([node] (forms/unquote->span (forms/->node node) {} form->hiccup)))


(defmethod form->hiccup :deref
([node {:keys [attrs] :or {attrs {}} :as opts}]
(forms/deref->span (forms/->node node) attrs form->hiccup))

([node] (forms/deref->span (forms/->node node) {} form->hiccup)))


(defmethod form->hiccup :comment
([node {:keys [attrs] :or {attrs {}} :as opts}]
(forms/comment->span (forms/->node node) attrs))

([node] (forms/comment->span (forms/->node node) {})))


(defmethod form->hiccup :regex
([node {:keys [attrs] :or {attrs {}} :as opts}]
(forms/token->span (forms/->node node) attrs))

([node] (forms/token->span (forms/->node node) {})))


(defmethod form->hiccup :set
([node {:keys [attrs] :or {attrs {}} :as opts}]
(forms/coll->span (forms/->node node) attrs form->hiccup))

([node] (forms/coll->span (forms/->node node) {} form->hiccup)))


(defmethod form->hiccup :newline
([node {:keys [attrs] :or {attrs {}} :as opts}]
(forms/newline->span (forms/->node node) attrs))

([node] (forms/newline->span (forms/->node node) {})))


(defmethod form->hiccup :map
([node {:keys [attrs] :or {attrs {}} :as opts}]
(forms/coll->span (forms/->node node) attrs form->hiccup))

([node] (forms/coll->span (forms/->node node) {} form->hiccup)))


(defmethod form->hiccup :reader-macro
([node {:keys [attrs] :or {attrs {}} :as opts}]
(forms/reader-cond->span (forms/->node node) attrs form->hiccup))

([node] (forms/reader-cond->span (forms/->node node) {} form->hiccup)))


(defmethod form->hiccup :forms
([node {:keys [attrs] :or {attrs {}} :as opts}]
(apply list (map #(form->hiccup (forms/->node %) {}) (node/children node))))

([node]
(apply list (map #(form->hiccup (forms/->node %) {}) (node/children node))))
)


(defmethod form->hiccup :default
([node {:keys [attrs] :or {attrs {}} :as opts}]
(forms/->span (forms/->node node) attrs form->hiccup))

([node] (forms/->span (forms/->node node) {} form->hiccup)))




(defn clj->hiccup
"Convert the given Clojure string, expression, or rewrite-clj node to a Hiccup data structure.

Uses the multimethod `site.fabricate.adorn/form->hiccup` for dispatch."

([src opts]
(form->hiccup (forms/->node src (select-keys opts [:lang :update-subnodes?]))
opts)
)

([src] (clj->hiccup src {})))