2 Passing Parameters Between Micros

Several months ago I ran into this problem, when compiling XML Schema into ASN.1 specifications. Given the structure of XML Schema documents, passing context from "outer nodes" to "inner nodes" seems quite necessary. I had originally hand-written various ad hoc traversals to achieve the translation. But later, when trying to re-write the translator using macros and micros-- this inability to propagate context inwards became a stumbling block.

Since then, I have contemplated adding notation to WebIt! to support such context passing. A few weeks ago, I read Oleg's post on the SSAX-SXML mailing list regarding his DAML "parse-unparse" example. In some sense that article triggered another idea about how to solve this problem, since unparsing XML with namespaces also requires propagating context (the namespace prefix bindings) "inwards". The idea of passing parameters between micros had germinated enough: I realized that no new notation is actually needed--the system of micros already supports this!

The key idea lies in the fact that an xml-micro takes as an argument an xml-node, but in fact can return ANY type. Instead of returning a new element, what if the micro returns a function whose arguments are the parameters we want to pass between micros!

We can implement a stylesheet whose micros take an XML node as its argument, but which return a function from a set of "context" parameters to an XML node. In this example of formatting HTML+sections, we now want not only to format the section numbers correctly, but to arrange that each section heading is formatted as an HTML heading element (i.e. using h1, then h2, etc.). To do this, we pass not only a prefix string, but a list of heading element constructors, starting with [h1, h2, h3, h4, h5]. The outer-most section will using the "car" of this list to format the heading; the "cdr" of this list will be passed as context to the micros formatting the contents of the section. The next level of nested sections will use "h2" as their format.

We can write ths micro as:

(xml-micro
  section
  (xml-rules
    ((_ num: n title: t c ...)
     (lambda (prefix hl)
       (h4:div
         (xml-template ((car hl) prefix n ". " t))
         (h4:p)
         (map
          (lambda (i)
            ((xml-expand i)
             (string-append prefix (xml-template n) ".")
             (cdr hl)))
          (xml-template (list c ...))))))))

This will format the XML fragment given above as:

<html>
  <body>
    <div>
      <h1>
1. First Section      </h1>
      <p />
      <p>
This is the intro section.      </p>
    </div>
    <div>
      <h1>
2. Second Section      </h1>
      <p />
      <div>
        <h2>
2.1. A sub-section        </h2>
        <p />
        <p>
This is section 2.1.        </p>
      </div>
      <div>
        <h2>
2.2. Another sub-section        </h2>
        <p />
        <p>
This is section 2.2.        </p>
      </div>
    </div>
    <div>
      <h1>
3. Last major section      </h1>
      <p />
      <p>
This is the third section      </p>
    </div>
  </body>
</html>

Last modified: Sunday, February 27th, 2005 4:37:51pm
HTML generated using WebIt!.