One limitation of Stavely's approach was that it assembled
all the executable code fragments into a single file for
execution. But the literate exposition of a C program, for
example, might require the discussion of two source files, a
header file named foo.h and a code
file named foo.c. We get around this
problem by using the role attribute
of the programlisting element in a
more flexible way.
The general form of a literate program source is a valid
DocBook-XML file, except that each fragment of executable
code is wrapped in a programlisting
element with this general format:
<programlisting role='outFile:F'>
(source text)
</programlisting>
where
is the name of the output file to which that source text
should be written.
F
We can then handle the above example by using a
role='outFile:foo.h' attribute on
fragments of the header file and a
role='outFile:foo.c' attribute on
fragments of the code file. For example:
<programlisting role='outFile:foo.h'> (stuff to be written to foo.h) </programlisting> ... <programlisting role='outFile:foo.c'> (stuff to be written to foo.c) </programlisting>
Of course, either of those files can be broken into many fragments spread throughout the document. They can even be intermingled.
There are two important refinements to mention:
You can use a CDATA section to enclose the source
fragment. This XML convention uses special delimiters
to tell processing programs not to mess with anything
between
“<![CDATA[” and
“]]>”. This is
especially convenient for enclosing XML fragments,
because you can use
“<” and
“>” characters
without having to escape them.
If your text is not enclosed in a CDATA section, you
can use DocBook tags inside the
programlisting element.
For example, you can enclose a function call inside a
link element that links to the
definition of that function. In both the HTML and PDF
generated from the DocBook file, that function name
will then be clickable.
Another element you might want to use inside a code
fragment is the co element, to
label lines of the code with callouts that are defined
later inside DocBook callout elements.
Here's an example of the use of callouts, as it would be encoded in the DocBook source. This is from the exposition of a schema using Relax NG Compact Format (RNC).
<programlisting role='outFile:trails.rnc'>
park = element park
{ attribute name { text }?, <co id='park.name'>
trail* <co id='park.trail'>
}
</programlisting>
<calloutlist>
<callout arearefs='park.name'>
<para>
This optional attribute contains the name of the park.
</para>
</callout>
<callout arearefs='park.trail'>
<para>
The content of a <userinput>park</userinput> element
consists of one or more <userinput>trail</userinput>
elements.
</para>
</callout>
</calloutlist>