Let us now see how this interface could be used. For an example problem, suppose we have a marked-up input document containing a sequence of sections. We need to enrich each section by prepending to its content two links to the previous and the following section.
Here is what the main function would look like:
global integer section-count define markup source function insert-neighbour-links (value markup source sections) as using output as resolve-referents into #current-output do markup-parse sections output "%c" using output as referent ("Section " || "d" % section-count + 1) output "" done
The resolve-referents
function call establishes the referent resolution scope and begins buffering all the referents written into its result sink. These referents will be written and their values set by the rules invoked by the output "%c"
action. The following using output as referent
action sets one referent value that has not been set by the rules.
This filter function could be invoked in the following way:
global dtd target-dtd process do xml-parse document scan #main-input set target-dtd to #current-dtd output xml.written from insert-neighbour-links (#content) done
Since the function insert-neighbour-links
operates on a markup stream, we could just as easily invoke it on an SGML document, simply by replacing xml-parse
by sgml-parse
in the above rule.
The rule that emits all the referents and sets their values would be the following one:
element "section" local markup-element-event link initial { create-element-event (declared-elements of target-dtd){"link"} attributes { attribute "id" with key "link-end" } } increment section-count using output as referent ("Section " || "d" % section-count) do signal throw #markup-start link output "Section %d(section-count): %v(title)" signal throw #markup-end link done signal throw #markup-start #current-markup-event output referent ("Section " || "d" % section-count - 1) when section-count > 1 output referent ("Section " || "d" % section-count + 1) output #content signal throw #markup-end #current-markup-event
The referent-related parts of this rule look the same as they would with the built-in OmniMark referents. The only difference is in the body of the using output as referent
scope: it emits a stream not only of plain strings like "Section"
, but markup events as well. In other words, it produces a markup stream, and this stream becomes the new referent value.