html.arc isn't that long, you could probably rewrite it using strings pretty quickly if you wanted to. And I'm sure that others using arc would be happy to have a string based system if you wrote it. There's no reason we can't have two alternate methods of generating html in arc.
Here's what I cooked up during the past coupla hours.
It doesn't do much, but builds a base for writing composable html elements.
It reuses the 'tag macro from html.arc as a base (no need to rewrite that part) but captures the output in a string (using 'tostring, of course). Thus the 'btag function becomes the base to build and compose html tags.
The few extra functions included serve as example of how to compose tags.
For example, 'hstack stacks its arguments horizontally using table columns.
'prn expressions are interspersed in between code blocks. They serve as examples, and I was using them for debugging.
(def listify (arg)
(if (acons arg) arg (list arg)))
(def btag (tagspec content)
"Low level tag function, takes two arguments: tagspec and content
content can be a list or an atom"
(let content (listify content)
(tostring (eval `(tag ,tagspec (pr ,@content))))))
(def element (tagspec . content)
"Simple element, just a convenience wrapper around btag"
(btag tagspec content))
; alias
(= e element)
(def section content
(btag 'div content))
(def inline content
(btag 'span content))
(prn (element 'div "Hello"))
(prn (element 'div "Hello " "World"))
(prn (element 'div "Hello" (element 'span "World")))
(prn (section "Hello" (inline "World")))
(def vstack args
"Stack things vertically"
(string:map section args))
(def hstack args
"Stack things horizontally"
(btag '(table cellspacing 0 cellpadding 0)
(btag 'tr
(map [btag 'td _] args))))
(prn "Testing vstack and hstack")
(prn (hstack "hstack" (section "hello") (inline "world")))
(prn (vstack "vstack" (section "hello") (inline "world")))
(def kls (classes . content)
"Generates a div with the classes given in 'classes'"
(let classes (string:intersperse " " (listify classes))
(btag `(div class ,classes) content)))
(prn (kls 'big "Hello " "world"))
(prn (kls '(small big) "Hello " "world"))