Skip to main content

The PreTeXt Guide

Section 4.40 Literate Programming

We continue (and do not repeat) the introduction at Section 3.31. PreTeXt implements the literate programming paradigm with two primary elements, <fragment> and <fragref>.
A <fragment> is a chunk of code. Almost always it has a @xml:id attribute. It begins with a mandatory <title>. It may have index entries, but see below for advice using the <list-of> element. Then there is a mix of <code> and <fragref> elements. The <code> element holds the actual text in whatever computer language you are using. Line breaks are respected. Use the XML escape characters &lt; and &amp; if your code needs the < or & characters. Do not try to use XML markup inside the <code> element.
A <fragref> is a reference to some other <fragment>. This is accomplished via the @ref attribute which points to the target via an @xml:id. So this is very similar to an <xref> (Section 3.4), but not enough alike to have the same element name. The most important distinction is that the xsl/pretext-litprog.xsl stylesheet will replace the <fragref> with the contents of the target <fragment>. In other conversions, the <fragref> will be a visual expression of the target <fragment>, possibly with some active means to visit or examine the target (hyperlink, knowl), more similar to an <xref>.
So the xsl/pretext-litprog.xsl stylesheet will course through your fragments converting the tree-like structure given by the references in the <fragref> elements into a depth-first traversal that will assemble the <code> elements, and only the <code> elements, linearly into a program. Notice that it is your job as the author of the program to be certain that this rearrangement results in a syntactically correct program. (PreTeXt is good, but not that good.)
If you are with us this far, you are wondering just where the root of this tree is? In other words, just which <fragment> does this traversal begin with? Good question. At least one <fragment> must have a @filename attribute. Then a traversal will begin here and your program will be output to the file with the name you specify. You are not limited to one file/root, so if your program has multiple source files they may be documented/collected into a single PreTeXt source file. (Notice this implies that every <fragment> must have an @xml:id or a @filename.)
You can place a <fragment> most anywhere you might place any other numbered block (such as <example>), though we would tend to place them as children of divisions. The remainder of your document can have all the usual PreTeXt features: a table of contents, a preface, divisions, an index, references, etc. Then a conversion to PDF, HTML, or other formats, will include your code, but in an order that might be more human-readable, and with careful documentation in close proximity.
Automatically migrating each <fragment> to an index is a bad idea. (We already experimented.) Instead you can try putting
<list-of elements="fragment"/>
into an <appendix>. Perhaps a pointer early on to its existence will help your reader. This list can be subdivided with the use of the @divisions attribute. See Section 4.28. Note that you might still want to provide an index, but remember that its construction is a job for an author (Subsection 4.26.2).
Literate programming has been developed to support the authoritative RELAX-NG version of the PreTeXt schema. Since RELAX-NG is a declarative language, the rearrangement of code hunks is not quite as critical. But still, see schema/pretext.xml for a non-trivial example. As of 2020-11-11 there are a few caveats. Start a discussion on the development forum if you have a need.
  • The conversion to a program has no explicit support for languages which interpret indentation meaningfully (e.g. Python). The <code> element makes no changes, so you could succeed if authored carefully. Some sort of relative indentation attribute might be a good solution.
  • We do not syntax-highlight the code. A language attribute might allow us to recycle existing features.
  • Numbering is serial from the start of the document. Raise a feature request if you think hierarchical numbering is indicated.