Menu

Example

OmniMark Code

Example

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.


Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.