weavejester/hiccup — pull request #64 by pauldorman (2012-09-30 05:23:25+00:00)
Title: Added parse function and refactored compiler

Hi, this introduces a new "parse" macro to hiccup.core, as well as substantial changes to the compiler. The new macro accepts the same input as the hiccup.core/html macro but produces a nested map data structure instead of strings of HTML, e.g.

(hiccup.core/parse [:div#foo.bar "baz"])
{:content [{:tag "div", :attrs {:class "bar", :id "foo"}, :content ["baz"]}]}

There is always a root element represented by a map with a single key and a vector containing the content data:

(parse nil)
{:content [nil]

The "html" macro can take the map produced by parse (or your own functions) and return strings in line with existing behaviour:

(html {:content [{:tag "div" :attrs {:class "bar"} :content "baz"} "foo"]})
"

baz

foo"

The "parse" and "html" macros can be composed and nested freely without adding complexity to the result:

(parse [:div.foo "bar"] (html "baz" (parse [:div "qux"])))
{:content [{:tag "div", :attrs {:class "foo"}, :content ["bar"]}
"baz"
{:tag "div", :attrs {}, :content ["qux"]}]}

(html [:div.foo "bar"] (html "baz" (parse [:div "qux"])))
"

bar

baz

qux

"

(parse [:div "foo" (html "bar" (parse [:div "baz"]) "qux")])
{:content [{:content ["foo" ["bar" {:tag "div", :attrs {}, :content ["baz"]} "qux"]], :attrs {}, :tag "div"}]}

(html [:div "foo" (html "bar" (parse [:div "baz"]) "qux")])
"

foobar

baz

qux

"

I hope the consistent data structure produced by the "parse" macro will simplify the task of writing functions that manipulate Hiccup forms before they are rendered as HTML strings, and allow for extending Hiccup's core functionality in your own programs.