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.

Reply via email to