site.fabricate.adorn namespace
Extensible, minimal API for adorn.
node-reserved-fields
clojure.lang.PersistentHashSetKeywords used by rewrite-clj to designate node fields
reader-cond->span
functiontoken-types
clojure.lang.PersistentHashMapnode-attributes
functionGet the HTML element attributes for the given form.
Allows passing through arbitrary attributes (apart from the :class attr).
get-node-meta
functionGet the metadata to apply to the node itself from within the form-level metadata.
node-platform-class
functioncoll->span
functionget-class
functionform-classes
clojure.lang.PersistentArrayMapMapping from form types to HTML classes
Intended for 'higher-level' forms than rewrite-clj supports as node types
->node
functionNormalize the rewrite-clj node for use in Adorn.
platform-classes
clojure.lang.PersistentHashMapClasses for each platform
comment->span
functionhtml-class-defaults
clojure.lang.PersistentHashMapnode-html-classes
clojure.lang.PersistentHashMapDefault HTML class lookup for node types
->span
functionConvert the node to a Hiccup :span vector. Dispatches on the node tag.
whitespace->span
functionuneval->span
functionnode-meta
functionnode-data
functionnewline->span
functiondata-attributes
clojure.lang.PersistentArrayMapHTML data attribute names for relevant information about forms
deref->span
functionget-form-meta
functionGet the form-level metadata by removing any keys with the :node namespace
split-node-metadata
functionsrc-info-keys
clojure.lang.PersistentHashSetKeys used by rewrite-clj to record location info for a node
coll-delimiters
clojure.lang.PersistentArrayMapmeta->span
functionfn->span
functionsyntax-quote->span
functionplatform-class-strs
clojure.lang.PersistentHashMapliteral-type
functionReturn the literal type for the given token node.
Intended to be consistent across clj+cljs.
node-clojure-type
functionvar->span
functiontoken->span
functionkeyword->span
functionGenerate a Hiccup :span data structure from the given keyword node.
Separates the namespace from the keyword, if present.
*escapes*
clojure.lang.PersistentArrayMapEscape character substitutions for HTML.
escape-html
functionsymbol->span
functionGenerate a Hiccup :span data structure from the given symbol.
Separates the namespace from the symbol, if present.
quote->span
functionunquote->span
functiontokens
clojure.lang.PersistentHashMapSpans for individual components of Clojure forms.
apply-node-metadata
functionRewrites 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 {})))