(def! reduce (fn* (fn acc l) (if (empty? l) acc (reduce fn (fn acc (first l)) (rest l)))))
(def! join (fn* (l) (reduce str "" l)))
(def! tag (fn* (name content) (join (list "<" name ">" (join content) "</" name ">"))))
(defmacro! mktags (fn* (& names) (map (fn* (name) `(def! ~(symbol name) (fn* (& content) (tag ~name content)))) names)))
(mktags "html" "head" "title" "body" "h1" "p" "ul" "li")
(print
(html
(head (title "Hello world!"))
(body
(h1 "Hello" "world!")
(p "Writing from inside mal (lisp) seems to work, yeah?")
(apply ul (map li '("one" "two" "three")))
)
)
)
Phew, that took a while!
As part of the whole "programmable site" thing, I've been wanting to write html-as-lisp (because it's fairly easy to type brackets and quotes on my phone keyboard, at least compared to other syntax).
I've been able to do the basic version for a while - use a macro to make functions that take their content, convert it to strings and wrap it in tags. The problem has been that when I generate content on the fly (e.g., the li
tags above), the brackets from the list end up embeded in the outcome.
Until now! Because apply
flattens it's arguments, I can use it to convert the list result of map
into the arguments of ul
.
Sweet. That should be a bit of incentive to get more work done on mal-sharp.