As an exercise both in learning nim and for a project of mine, I am making a simple HTML DSL, similar to the htmlgen module, but something that works better as a language.
Here are three uses: htmlgen standard, what I'm using, and what I'd like. Is there a way I can achieve the third one, or at least improve on the second?
## The htmlgen version:
html(
head(
title(
"Page Title"
)
),
body(
`div`(
class="textarea",
"div content here"
)
)
)
# I find the commas and parens annoying, but I like typing raw: class="textarea"
## My current version
template tag*(output:expr, tag_call:expr, tag_name:string) {.immediate.} =
template tag_call*(body:stmt):stmt {.immediate.} = # this version of the tag takes only stmt block
output("<"&tag_name&">")
body
output("</"&tag_name&">")
template `tag_call 0b`*(body:stmt):stmt {.immediate.} = # same as previous, but user asked explicitly "tag0b"
output("<"&tag_name&">")
body
output("</"&tag_name&">")
template `tag_call 0a`*(attr:expr):stmt {.immediate.} = # no stmt block, but string of tag attributes
output("<"&tag_name&attr&">")
template `tag_call 0ab`*(attr:expr, body:stmt):stmt {.immediate.} = # both stmt block and tag attributes
output("<"&tag_name&attr&">")
body
output("</"&tag_name&">")
proc attrs*(attributes:varargs[string]):string = # converts list of attribute strings ("key","value")->(key="value")
result = ""
for i in 0..high(attributes):
if (i and 1) == 0: result.add( " "&attributes[i]&"=" )
else: result.add( "\""&attributes[i]&"\"" )
#used like this
tag(echo, html_html, "html")
tag(echo, html_head, "head")
tag(echo, html_title, "title")
tag(echo, html_div, "div")
tag(echo, html_body, "body)
html_html():
html_head():
html_title():
echo "Page Title"
html_body():
html_div0ab(attrs("class","textarea")):
echo "div content here"
# yay! no weird commas or parens, but traded them for attrs()
# and diversity of tag calls (div,div0a,div0b,div0ab)
## Version I would like:
var textArea:string = "textarea" # show need for var support, otherwise template of template does work
html:
head:
title:
echo "Page Title"
link(style="style.css") #note no : at the end
body:
`div`(class=textArea, otherAttribute="#FFFFFF"):
echo "div content here"
How can I improve my version, or what are some pointers to approaching the desired version? Thank you!