I made a bit more progress:
import macros, htmlgen, strutils
macro ph(e: varargs[untyped]): untyped =
## Generates the HTML `merror` element. MathML
https://wikipedia.org/wiki/MathML
## https://developer.mozilla.org/en-US/docs/Web/MathML/Element/merror
result = xmlCheckedTag(e, "ph", "mathbackground mathcolor href" &
commonAttr)
macro ntml(body: untyped): untyped =
proc processNode(node: NimNode): NimNode =
case node.kind
of nnkStmtList, nnkStmtListExpr:
var processedChildren = newSeq[NimNode]()
for child in node:
processedChildren.add(processNode(child))
if processedChildren.len == 1:
return processedChildren[0]
else:
return newCall("ph", processedChildren)
of nnkCall:
let callee = node[0]
if $callee in ["h1", "dv", "p", "ul", "li"]:
var tagArgs: seq[NimNode] = @[]
for arg in node[1..^1]:
tagArgs.add(processNode(arg))
var tag = case $callee
of "dv": "div"
else: callee.repr
return newCall(tag, tagArgs)
else:
return node
else:
return node
proc sanitizeHTML(html: string): string =
return html.replace("<ph>", "").replace("</ph>", "")
let processedBody = processNode(body)
result = quote do:
sanitizeHTML(`processedBody`)
let html = ntml:
dv(id = "main-container"):
h1(style = "color: #333; font-size: 24px;"): "Nim HTML Generator"
p: "This is an example of generating HTML with sugary DSL syntax."
dv(style = "border-radius: 20px; padding: 20px; background-color:
#f0f0f0;"):
p: "Nested div with background."
ul(style = "padding: 0;"):
li(style = "margin: 0 0 10px 30px;"): "List Item 1"
li(style = "margin: 0 0 10px 30px;"): "List Item 2"
li(style = "margin: 0 0 10px 30px;"): "List Item 3"
dv(style = "margin-top: 30px"):
p: "Another paragraph in a separate div."
a(href = "https://nim-lang.org", target = "_blank"): "Visit Nim's
official website"
echo html
Run
output:
<div id="main-container">
<h1 style="color: #333; font-size: 24px;">Nim HTML Generator</h1>
<p>This is an example of generating HTML with sugary DSL syntax.</p>
<div style="border-radius: 20px; padding: 20px; background-color:
#f0f0f0;">
<p>Nested div with background.</p>
<ul style="padding: 0;">
<li style="margin: 0 0 10px 30px;">List Item 1</li>
<li style="margin: 0 0 10px 30px;">List Item 2</li>
<li style="margin: 0 0 10px 30px;">List Item 3</li>
</ul>
</div>
<div style="margin-top: 30px">
<p>Another paragraph in a separate div.</p>
<a href="https://nim-lang.org" target="_blank">Visit Nim's official
website</a>
</div>
</div>
Run
I'm very happy with this so far; next I will try to implement for loops for
doing things like generating li elements.