XLP Release 2
A.J.Hurst
Version 2.4.0
20080822:162322
Table of Contents
1. Introduction
1.1 Background
Literate Programming is a technique developed by Donald
Knuth, and described in his seminal paper in the Computer
Journal, 1984. It is both a software process and a suite of
tools for supporting that process. Programs written as
literate programs go through two (conceptually) independent
processes known as tangling and weaving.
Tangling creates the actual source code for input to a
compiler; weaving creates a documentation file suitable for
processing by a document system such as TeX.
More modern versions of literate program tools have attempted
to decouple the N x M combinatorial explosion created by the
choice of N programming languages and M documentation systems,
by restricting the markup and presentational mechanisms. The
tool currently in use in the work described here is such a
tool: the markup of source documents is done in XML, and the
documentation device is handled by XML translators. This
reduces the problem from an N x M to an N + M one, where N =
1.
XLP started life as a literate programming tool developed
from nuweb, and modified to develop XML code rather than LaTeX
or HTML. It was extensively rewritten during 2003 to use an
XSLT script rather than a C program to do the tangle and weave
processes, so the code is completely platform independent. To
run the code, only an XSLT translator (any flavour) is needed. The
price for this conversion (apart from time) has been the loss
of a number of "syntactic sugar" features, but I don't
miss them much. They are gradually being reintroduced,
generally in an improved form.
This new version is currently used to define and maintain a
range of software that I use on a regular basis.
1.2 Synopsis
This program, or rather, suite of programs, performs literate
program analysis and construction over a literate program
file. Programs in any language can be constructed, as can
documentation in any form. There are two phases to the use of
the suite, each of which is handled by an XSLT file. The
first of these phases uses a common XSLT file, while the
second phase uses an XSLT file that is specific to the form of
documentation being generated. For naming purposes, the first
phase is known as the warp phase, while the second
phase is called the weft phase.
The first phase (warp phase) comprises two passes,
corresponding to the tangling and weaving operations of all
literate program systems. It is important to make the
distinction between phase and pass in this
context. This phase is performed by the litprog.xsl
file. Each of the passes within this phase is handled by a
mode (in the XSL technical sense). The first pass, or
mode=tangle, generates the tangled program files, and
the second pass mode=weave generates an intermediate
file of the woven documentation file.
This documentation file is then processed in phase two of the
suite (the weft phase) by a second XSLT file, which is
documentation language specific. There is only one pass in
the weft phase. Currently, there are two such XSLT files,
lit2html.xsl for HTML documentation, and
lit2tex.xsl for TeX documentation. The output of
this phase is an HTML or TeX document, suitable for processing
by a browser (HTML) or by the TeX system itself (TeX). There
are a standard set of macros (based upon plain TeX) that are
assumed by the TeX translator, and which are available
separately.
All three XSLT files (litprog.xsl for the warp phase,
and lit2html.xsl and lit2tex.xsl for the weft
phase) are described in this document, which is itself a
literate program document.
1.3 The source file structure (XLP files)
The warp (first) phase of XLP reads the input XLP file, a
document type definition for which is given in section 5, The litprog Document
Type Definition (see also the file <litprog.dtd 6.1>). In BNF, the grammar of this file is as
follows (terminals are represented in CAPITALS, although the
corresponding element names are lower case, except for
TableOfContents):
litxmlfile = TITLE AUTHOR VERSION DATE
( section | misc ) *
DocumentHistory?
.
section = TITLE (p | o | d | subsection | misc)* .
subsection = TITLE (p | o | d | subsubsection | misc)* .
subsubsection = TITLE (p | o | d | subsubsubsection | misc)* .
subsubsubsection = TITLE (p | o | d)* .
misc = TABLEOFCONTENTS | FILELIST | MACROLIST | IDENTIFIERLIST
.
o = (CODE | u | v)* .
d = (CODE | u | v)* .
u = USE-REFERENCE .
v = VARIABLE-REFERENCE .
p = (TEXT | u | v)* .
DocumentHistory = Modified* .
Modified = DATE AUTHOR VERSION COMMENT .
See the User Manual
(following) for explanations of these elements.
1.4 Some base definitions
Here we define some important system parameters.
The first one is the location for the
library of XSL translations for various base templates. Update
this to point at the directory used to store templates such as
basic2html.xsl, basic2tex.xsl, and so on (see
for example, <lit2html.xsl 4.1> and
<lit2tex.xsl 4.33>).
<LIBXSL 1.1> = file:///home/ajh/lib/xsl
The following list defines all documentation template names.
All the names of documentation templates that are passed
straight through phase one (the warp phase) should be
added to this list, in order to avoid any "No warp-tangle
template" or "No warp-weave template" errors.
<litprog: define documentation template name list 1.2> =<xsl:variable name="docos">
<xsl:text>|author|b|c|col|comment|date|description|dq|</xsl:text>
<xsl:text>DocumentHistory|em|i|itemize|item|</xsl:text>
<xsl:text>le|Modified|narrower|</xsl:text>
<xsl:text>section|smiley|subsection|subsubsection|</xsl:text>
<xsl:text>subsubsubsection|paragraph|parm|table|TableOfContents|TeX|</xsl:text>
<xsl:text>term|td|th|title|tr|tt|uri|verb|verbatim|version|</xsl:text>
<xsl:text></xsl:text>
</xsl:variable>
2. User Manual
2.1 Overview of an XLP Document
An XLP document is a well-formed XML document. For readers
unfamiliar with XML, an XML document consists of a set of
elements, each flagged with a starting and ending tag, and
containing other elements, text, or both. Tags are defined by
writing the element name within angle brackets
<>, and the ending or closing tag has a leading
/ before the name. The term "well-formed XML
document" means that all elements are strictly nested, and
there is one outer level or root element.
<p>An example of a <b>paragraph</b> element, with nested <b>bold</b> elements</p>
The structure of the XLP document is formally defined
elsewhere, but an informal description will suffice here. The
basic outline of an XLP literate program looks like this:
<?xml version="1.0"?>
<!DOCTYPE litprog SYSTEM "/home/ajh/lib/dtd/litprog.dtd">
<litprog>
... literate program content goes in here ...
</litprog>
The first line of this program is a declaration that the
document is an XML document, constructed according to the
rules of XML version 1.0. This line is optional. The
second line is mandatory, and specifies that the rules of this
particular XML document, an XLP (or XML Literate Program)
document, are defined in the
separate file /home/ajh/lib/dtd/litprog.dtd.
The top-level or root element is a litprog element. This
element contains all the literate programming content. Such
content comes in two basic forms: documentation and code.
Each of these two forms have their own set of elements. There
is limited mixing of these elements, but generally an element
is either pure code or pure documentation. These forms are
described in the next section.
The basic model is that the document has the structure of a
typical descriptive article: opening components are followed
by substantive components, which are then followed by closing
components. Opening material are things like title, author,
date, which are required (if present) to be in a particular
order. The substantive content is encapsulated within
sections, each contain possible subsections, subsubsections,
and even subsubsubsections. Closing material includes things
like tables of content and indices.
Interspersed within the document are the code chunks, which
are file and code definitions. These may generally appear at
any point in the document, but it is their document order that
defines how they are assembled into the overall code
files. Readers familiar with other literate programming
systems may view this arrangement as a conventional
alternation of code and documentation fragments, with a
superimposed document structure.
2.2 Documentation in an XLP Document
Documentation in an XLP document is built from the set of
elements:
author b c col comment date description dq DocumentHistory
em filelist i identlist item le macrolist Modified p section
subsection subsubsection subsubsubsection table
TableOfContents term TeX td th title tr uri verb verbatim
version
Generally, these are constrained as to where
they can appear, but some can be used in arbitrary order.
Their usage is described in the following list, where the
annotation "*" is used to mark those that are
constrained.
- author*
- The author of this literate program. Can appear in two
places: at the top level, after the title element,
or within a Modified element, after a date
element.
- b
- markup text in bold face
- c
- markup text in code (typewriter) face
- col
- The column specification element, used in tables. It is
an empty element, with one attribute, width, defining
the width of a column as a fraction (<=1.0) of the total
page width.
- comment*
- The last element within a Modified element,
describing the nature of this particular
modification.
- d
- define a code chunk (see code)
- date*
- Can appear after version in the document
header, or as the first element in a Modified
element. It defines the date of the document, or
modification, respectively.
- DocumentHistory*
- A sequence of Modified elements, each of which
contains a date, author, version,
comment sequence of nested elements, each of which
documents the appropriate data about the various
modifications to this literate program. If it is
present, it must be the last element in a litprog
element.
- dq
- place double quotes around text
- filelist*
- A place marker to indicate where the list of files
generated should be inserted. It can appear at the top
level, or within a (sub)section.
- i
- markup text in italic face
- identifierlist*
- A place marker to indicate where the table of identifier
cross references should be inserted. It can appear at the
top level, or within a (sub)section.
- item*
- Can only appear within a description,
enumerate or itemize element, where it defines
one of the list items.
- le
- The less than or equal to symbol, <=.
- macrolist*
- A place marker to indicate where the list of macro names
should be inserted. It can appear at the top level, or
within a (sub)section.
- Modified*
- contains date, author, version,
comment elements, defining attributes of each
modification of the literate program.
- o
- define an output file (see code)
- p
- markup a paragraph
- section*
- Can only appear as a top-level element within the
litprog element.
- subsection*
- Can only appear within a section element.
- subsubsection*
- Can only appear within a subsection element.
- subsubsubsection*
- Can only appear within a subsubsection element.
- TableOfContents*
- Defines the place in the literate program where the
table of contents should be inserted. Can only appear at the
top level of the document, or within a section or
sub(sub...)section.
- term*
- Can only appear within a description element,
where it defines the (documentation) term being
defined.
- TeX
- The TeX token.
- td*
- As for HTML, within a table row element (tr),
defines a table data cell.
- th*
- As for HTML, within a table row element (tr),
defines a table header cell.
- title*
- When this element appears immediately after the
opening litprog tag, it is the title of this
literate program. Within a section or sub..section, it is
the title of the corresponding (sub..)section.
- tr*
- As for HTML, defines a table row.
- u
- A use reference to a code fragment. In documentation,
during the weaving pass, the reference becomes a link to
the code fragment, unless an optional attribute
expand is present and non-empty, when the reference
is expanded to its value. In code fragments, during the
tangling pass, the reference is replaced by the expanded
code fragment, as a (recursive) macro expansion.
- uri
- markup a Universal Resource Indicator
- v
- markup a variable (see code)
- verb
- markup verbatim text in-line
- verbatim
- markup verbatim text as a display (paragraph) item.
- version*
- Can appear in either the literate program header
or a Modified element. In both cases, it follows
an author element.
2.3 Code in an XLP Document
Code elements in an XLP literate program take two forms: file
definitions, and code chunks. Code chunks are fragments of
code used to build other code chunks or file definitions. For
this reason, the distinction between code chunks and file
definitions is often blurred, and they are referred to
collectively as code chunks. It should be obvious from the
context when it is important for the distinction to be made.
The code fragments are assembled through a process of
expansion (in technical terms, a "macro expansion")
that replaces references to other chunks by the code defined
in that chunk.
Code within a chunk can be quite arbitrary: there is no
interpretation or parsing of the code, except for XML
elements. Remember that the document is one large XML file,
and text within a code chunk is interpreted according to the
rules of XML. In practice, this means that the characters
"less than" (<) and "ampersand"
(&) have special meanings, and must be
escaped if they are used within code text. The escape
sequences are < and &
respectively.
Alternatively, the block quoting mechanism of XML can be
used. This entails surrounding the entire text that needs to
be quoted with the special sequences <![CDATA[
and ]]>. All text within these
quote sequences will appear verbatim. It follows that if the
sequence ]]> is to appear within the
quoted text, it too must be escaped, for example with
]]>]<![CDATA[]]>]<![CDATA[>]]>><![CDATA[
(the three separate characters, each surrounded by close then
open escape sequences). Strictly speaking, breaking the
sequence once would suffice, but this is a more
sesquipedalian approach !
There are three code elements that may appear within
documentation (and already mentioned above):
- o
- An output element. This element defines a file
built by the literate program. The name of the file is
given by the value of a required attribute, the file
attribute. Note that more than one file element may have
the same name, when the file is considered to be the
concatenation of all similarly named chunks, arranged document
in order. All file definitions are collected into a
list accessed by the element filelist.
- d
- A code chunk defining element. The name of the
code chunk (by which it may be referenced) is given by the
value of a required attribute name. Note that more
than one code chunk may have the same name, when the code
chunk is considered to be the concatenation of all similarly
named chunks, arranged in document order. It is an error to
have names that are common to both code and file chunks.
All code definitions and uses are collected into a list
accessed by the element macrolist.
- v
- A variable element. This may be either a
defining occurrence, or a using occurrence, although within
documentation it is unlikely to be the former. Within
documentation, is usually used to highlight discussion
about a particular variable within the code. See below for
use within a code chunk. All variable definitions and uses
are collected into a list accessed by the element
identifierlist.
There are three elements that may appear within code chunks (i.e.,
within o or d elements). These are:
- u
-
A code chunk using element. This element is normally
empty, and defines the point at which a code chunk is
expanded into the current code chunk or output file. It has
a mandatory attribute name, which cross-references
the corresponding code chunk(s).
It may also have the optional attribute include,
which, when it has the value no, negates the
inclusion of the reference code chunk. This may be used
to "comment out" code, while still retaining the
documentation surrounding the excluded code. The
documentation is annotated accordingly.
A second optional attribute is expand, which
normally has the default value no. When explicitly
set to yes however, it forces the expansion of the
chunk into the document at that point. When called within
code chunks, this is the default behaviour, but when
called within documentation chunks, this changes the
representation of the macro from a link to the expanded
text of the macro. This is useful for defining macros
used within the documentation, rather than code generation
(for example, the date at the head of this document was
generated in this way). Warning: multiple chunks
are not handled correctly, as of version 2.2.0.
- v
- A variable element. See also use within
documentation, above. This may be a defining occurrence, or
a using occurrence, depending upon the optional attribute
var. If var has the (default) value
use (var="use"), then the occurrence is
marked up as a use of the variable. If the attribute has
the value def (var="def"), then the
occurrence is marked up as a defining occurrence. Note that
there is no analysis of the content of the variable
element, which allows arbitrary lexical forms of variable
names to be used. (But be wary of languages such as perl,
or bash shell scripts, which use \$ and other signs to
flag usage of the variable. These annotations should be
excluded from the variable name.)
- com
- A comment element. This element may be used to
markup in-line comments within the code. How the comment is
rendered depends upon the subsequent weft phase, but it will
presumably capitalize upon the contextual position. (Aside:
the tangling of the output file could conceivable include
the comment as an in-line comment - the difficulty here is
that the literate programming system has no knowledge of the
syntactic form of such in-line comments.)
2.4 Running XLP
To use the XLP literate programming system, you need an XSLT
translator. I use xsltproc (see LibXML),
but other XSLT translators will work just as well with the
files described herein. In what follows, we assume the
xsltproc translator.
There are two phases to running the system, called the warp
and weft phases. The warp phase performs tangling and
weaving, and generates an intermediate file for the weft
phase. To run the warp phase, use the call:
xsltproc litprog.xsl yourXLPfile.xlp >yourXLPfile.xml
For the weft phase (document generation), use the call
xsltproc lit2html.xsl yourXLPfile.xml >yourXLPfile.html
This is for HTML generation. For TeX documentation, replace
the two occurrences of html in the above line
with tex.
Note that if documentation is not required, the weft phase
may be omitted.
3. The warp, or literate program phase
This phase is responsible for reading and translating the
source xlp file. There are two passes to this phase, known as
the tangle and weave passes. Each pass performs a
sweep over the input file, applying templates to the elements as
they are seen. In the first pass, the XSLT mode of
mode="tangle" is used; in the second pass,
mode="weave" is used.
In the tangle pass, all documentation chunks are effectively
ignored, while file chunks cause a new document to be written,
containing the code within the file chunk, with all code chunk
references expanded out through a process of macro
expansion. Each file chunk creates a new text document named
with the given file name, which can then be used for further
processing by compilers, etc..
In the weave pass, a new translation of the source XLP document
is made. This new document is given a .xml extension,
and its contents consist of much the same contents as are in
the original XLP file, but with some elements renamed, and
additional housekeeping information issued to assist the final
weft phase.
3.1 Templates defined in litprog.xsl
name |
attributes |
mode |
purpose |
/ |
(none) |
(none) |
The root node |
litprog |
(none) |
tangle |
tangle all output files |
d |
name |
tangle |
define a code chunk named "@name" |
o |
name |
tangle |
build a new output file, called "@name" |
d/v | o/v |
var |
tangle |
define (var="def") or reference
(var="use") a variable (default is reference). |
p |
|
tangle |
paragraph documentation, ignored |
d/com|o/com |
|
tangle |
comment with a code/file chunk: ignored |
u |
|
tangle |
chunk use, expand the referenced code chunk in-line |
* |
|
tangle |
undefined element, issue a warning message |
litprog |
|
weave |
Perform the weave pass |
d | o |
|
weave |
document a code chunk (d) or output file (o) |
d/v | o/v |
|
weave |
document a variable markup (either use or definition,
defined by element attribute var="use" (default) or
var="def") in code (d/v) or file
(o/v) |
d/com | o/com |
|
weave |
document a comment markup in code (d/com)
or file (o/com) |
v |
|
weave |
document a value reference to a code or file chunk |
u |
expand |
weave |
document a use reference to a code or file chunk. If
the attribute expand is present and non-empty, replace
this element by the expanded code definition. |
p |
|
weave |
document a paragraph of literate program text |
section |
|
weave |
document a section of the literate program text |
* |
|
weave |
undefined element, issue a warning message |
3.2 litprog.xsl: the warp translator
"litprog.xsl" 3.1 =
This is the XSLT transformer script for phase one, the
warp phase of the literate programming suite. It is
responsible for tangling the output documents, and
weaving the XML document for input to the weft
phase.
3.2.1 litprog: root template
<litprog: root template 3.2> =<xsl:template match="/">
<xsl:message><xsl:text>Tangling ...</xsl:text></xsl:message>
<xsl:apply-templates mode="tangle"/>
<xsl:message><xsl:text>Weaving ...</xsl:text></xsl:message>
<xsl:element name="LitprogXML">
<xsl:apply-templates mode="weave"/>
</xsl:element>
</xsl:template>
The root template is responsible for the two passes of
tangling and weaving. Note that the tangle phase generates
its own documents (in the XML technical sense), while all
the documentation for the weft phase is generated as the
"default" output of this phase by the tangle pass.
3.2.2 litprog: define variables
<litprog: define variables 3.3> =<xsl:variable name="
crossrefs">
<xsl:for-each select="//d|//o">
<xsl:value-of select="concat(@name,@file)"/>
<xsl:text>@</xsl:text>
<xsl:number format="1" level="multiple" count="section"/>
<xsl:text>.</xsl:text>
<xsl:number from="section" level="any" count="d|o"/>
<xsl:text>
</xsl:text>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="
premacro">
<xsl:text>[[</xsl:text>
<xsl:text>[[</xsl:text>
</xsl:variable>
<xsl:variable name="
postmacro">
<xsl:text>]]</xsl:text>
<xsl:text>]]</xsl:text>
</xsl:variable>
<litprog: define documentation template name list 1.2>
The variable crossrefs is set to a value built from
a newline separated list of code and file chunks, with each
entry (or line) in the form name@location, where
name is the name of the chunk or file, and
location is the chunk number defining that file or
chunk.
The value stored as the value of a chunk number is
multi-valued, in the form s.p, where s is the
section number and p is the part number within the
section.
The two variables premacro and postmacro
define the escape sequences used respectively to start and
end a macro text.
3.2.3 litprog: define script parameters
The script parameters give some control over the behaviour
of the literate programming system. Currently two are
defined: Verbose and machine.
Verbose can be set to a non-negative integer. When
0 (the default), no tracing information is given.
Progressively higher values give more information about the
progress of tangling and weaving.
machine is used to define the target of
compilation. Not currently interpreted.
<litprog: define script parameters 3.4> =<xsl:param name="
Verbose">1</xsl:param>
<xsl:param name="
machine">ararat</xsl:param>
3.2.4 litprog: define procedure templates
Define all the callable templates for the warp phase.
<litprog: define procedure templates 3.5> =
3.2.5 litprog: do-replace template
<litprog: do-replace template 3.6> =<xsl:template name="
do-replace">
<xsl:param name="
text"/>
<xsl:param name="
replace"/>
<xsl:param name="
by"/>
<xsl:choose>
<xsl:when test="contains($text,$replace)">
<xsl:value-of select="substring-before($text,$replace)"/>
<xsl:value-of select="$
by"/>
<xsl:call-template name="
do-replace">
<xsl:with-param name="
text"
select="substring-after($
text,$
replace)"/>
<xsl:with-param name="
replace"
select="$
replace"/>
<xsl:with-param name="
by"
select="$
by"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$
text"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
do-replace is a procedure with three parameters,
text, replace, and by. Multiple
occurrences of replace in the string text are
recursively replaced by the value of by, and this
rebuilt value is returned as the value of the template
call.
3.2.6 litprog: count-trailing-blanks template
<litprog: count-trailing-blanks template 3.7> =<xsl:template name="
count-trailing-blanks">
<xsl:param name="
string"></xsl:param>
<xsl:param name="
count"></xsl:param>
<xsl:choose>
<xsl:when test="substring($string,string-length($string))=' '">
<xsl:call-template name="count-trailing-blanks">
<xsl:with-param name="string"
select="substring($string,1,
string-length($string)-1)"/>
<xsl:with-param name="count" select="$count+1"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$count"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
count-trailing-blanks, as its name suggests,
(recursively) counts the trailing blanks in the string
parameter string and returns this value. The initial
value of the parameter count should be set as 0. The
actual value returned by the procedure is this initial value
plus the number of trailing blanks, hence the need to
initialize it correctly.
3.2.7 litprog: lookupchunkno template
<litprog: lookupchunkno template 3.8> =<xsl:template name="
lookupchunkno">
<xsl:param name="chunkname"></xsl:param>
<xsl:call-template name="lookupchunknoR">
<xsl:with-param name="chunkname" select="$chunkname"/>
<xsl:with-param name="table" select="$
crossrefs"/>
<xsl:with-param name="sep"></xsl:with-param>
</xsl:call-template>
</xsl:template>
Chunk referenced in 3.5Chunk defined in 3.8,
3.9
lookupchunkno returns a list of the chunk numbers of
a named chunk. The name of the required chunk is passed as
the parameter chunkname, and the procedure calls an
auxiliary recursive template lookupchunknoR to find
the actual chunk numbers.
<litprog: lookupchunkno template 3.9> =<xsl:template name="lookupchunknoR">
<xsl:param name="chunkname"></xsl:param>
<xsl:param name="table"></xsl:param>
<xsl:param name="sep"></xsl:param>
<xsl:variable name="find">
<xsl:value-of select="substring-after($table,concat($chunkname,'@'))"/>
</xsl:variable>
{Note 3.9.1}
<litprog: lookupchunknoR debug message 1 3.10> **** Chunk omitted!
<xsl:if test="$find!=''">
{Note 3.9.2}
<xsl:value-of select="$sep"/>
<xsl:value-of select="substring-before($find,'
')"/>
<xsl:call-template name="lookupchunknoR">
<xsl:with-param name="chunkname" select="$chunkname"/>
<xsl:with-param name="table" select="$find"/>
<xsl:with-param name="sep"><xsl:text>,</xsl:text></xsl:with-param>
</xsl:call-template>
</xsl:if>
</xsl:template>
Chunk referenced in 3.5Chunk defined in 3.8,
3.9
- {Note 3.9.1}
- The first key part of the lookup algorithm.
Jump straight to the match in the table of the required
chunk name. If it is there, the find variable is set to
the remainder of the table starting with the match. If it
is not there, the find variable will be empty.
- {Note 3.9.2}
- The second key part of the lookup
algorithm. Return the first part of the find string (it is
the desired chunk number, and use the (remainder of the)
find string as the lookup table for the next
recursion. The algorithm is order n, where n is the number
of matches in the cross reference table for chunkname.
lookupchunknoR takes as parameters the required
chunkname, a partially searched table of cross references,
and the separator string used to separate matches for the
chunk name. It returns a sep separated list of values that
match the second half of all (chunkname, chunkno) pairs in
the cross reference list.
The sep separator is passed as a parameter, since on the
first call, it must be empty. Otherwise we would return
lists of the form ,4,10,15 rather than
4,10,15.
<litprog: lookupchunknoR debug message 1 3.10> =<xsl:message>
<xsl:text>lookupchunknoR(</xsl:text>
<xsl:value-of select="$chunkname"/>
<xsl:text>,</xsl:text>
<xsl:value-of select="$table"/>
<xsl:text>,'</xsl:text>
<xsl:value-of select="$sep"/>
<xsl:text>')</xsl:text>
</xsl:message>
This chunk is conditionally included to provide debugging
information about the progress of the chunk number lookup
procedure.
3.2.8 litprog: lookup template
<litprog: lookup template 3.11> =<xsl:template name="lookup">
<xsl:param name="key"></xsl:param>
<xsl:param name="table"></xsl:param>
<xsl:variable name="pkey">
<xsl:value-of select="$premacro"/>
<xsl:value-of select="$key"/>
<xsl:value-of select="$postmacro"/>
<xsl:value-of select="$premacro"/>
</xsl:variable>
<xsl:variable name="tail" select="substring-after($table,$pkey)"/>
<xsl:variable name="retval">
<xsl:value-of select="substring-before($tail,$postmacro)"/>
</xsl:variable>
<xsl:if test="$Verbose>=2">
<xsl:message>
<xsl:text>lookup:</xsl:text>
<xsl:text>
 key=</xsl:text>
<xsl:value-of select="$key"/>
<xsl:text>
 table=</xsl:text>
<xsl:value-of select="$table"/>
<xsl:text>
 pkey=</xsl:text>
<xsl:value-of select="$pkey"/>
<xsl:text>
 tail=</xsl:text>
<xsl:value-of select="$tail"/>
<xsl:text>
 retval=</xsl:text>
<xsl:value-of select="$retval"/>
<xsl:text>
</xsl:text>
</xsl:message>
</xsl:if>
<xsl:if test="$tail!=''">
<xsl:value-of select="$retval"/>
</xsl:if>
</xsl:template>
3.2.9 litprog: substparms template
This callable template takes a text string representing a
chunk definition, and substitutes for any formal parameters
used within the chunk. Formal parameters are found by
virtue of them being enclosed within 4 sets of square
brackets, as defined by the global variables
premacro and postmacro.
Note that there is a further complication in that formal
parameters nested inside actual parameters have been
escaped, by using 4 sets of curly brackets. These escapings
must be restored before parameter expansion can begin. This
is done by substituting square brackets for the curly ones.
<litprog: substparms template 3.12> =<xsl:template name="substparms">
<xsl:param name="text"></xsl:param>
<xsl:param name="parmtable"></xsl:param>
<substparms: unescape the escaped formal parameters 3.13>
<xsl:variable name="head">
<xsl:value-of select="substring-before($etext,$premacro)"
disable-output-escaping="no"/>
</xsl:variable>
<xsl:variable name="tail">
<xsl:value-of select="substring-after($etext,$postmacro)"
disable-output-escaping="no"/>
</xsl:variable>
<xsl:variable name="parmname">
<xsl:value-of select="substring-before(
substring-after($etext,$premacro),
$postmacro)"
disable-output-escaping="no"/>
</xsl:variable>
<xsl:if test="$Verbose>=2">
<xsl:message>
<xsl:text>substparms: text=</xsl:text>
<xsl:value-of select="$etext"/>
<xsl:text>
substparms: parmtable=</xsl:text>
<xsl:value-of select="$parmtable"/>
<xsl:text>
substparms: parmname=</xsl:text>
<xsl:value-of select="$parmname"/>
</xsl:message>
</xsl:if>
<xsl:variable name="value">
<xsl:call-template name="lookup">
<xsl:with-param name="key" select="$parmname"/>
<xsl:with-param name="table" select="$parmtable"/>
</xsl:call-template>
</xsl:variable>
<xsl:if test="$Verbose>=2">
<xsl:message>
<xsl:text>substparms: </xsl:text>
<xsl:value-of select="$parmname"/>
<xsl:text>=</xsl:text>
<xsl:value-of select="$value"/>
</xsl:message>
</xsl:if>
<substparms: build result string recursively 3.14>
<xsl:if test="$Verbose>=2">
<xsl:message>
<xsl:text>substparms: result=</xsl:text>
<xsl:value-of select="$result"/>
</xsl:message>
</xsl:if>
<xsl:value-of select="$result"/>
</xsl:template>
This is a challenging routine, as evidenced by the number
of debug components built in! Basically, we split the
incoming text string into a pre-formal parameter part (the
head), and a post-formal parameter part (the
tail), as indicated by the premacro and
postmacro strings of square brackets. The formal parameter
itself is looked up in the parameter table, and a result
string is built by concatenating the pre-string, the
parameter value, and a recursively expanded post-string.
<substparms: unescape the escaped formal parameters 3.13> =<xsl:variable name="etext">
<xsl:call-template name="do-replace">
<xsl:with-param name="text">
<xsl:call-template name="do-replace">
<xsl:with-param name="text">
<xsl:value-of select="$text"/>
</xsl:with-param>
<xsl:with-param name="replace">
<xsl:text>{{</xsl:text><xsl:text>{{</xsl:text>
</xsl:with-param>
<xsl:with-param name="by">
<xsl:value-of select="$premacro"/>
</xsl:with-param>
</xsl:call-template>
</xsl:with-param>
<xsl:with-param name="replace">
<xsl:text>}}</xsl:text><xsl:text>}}</xsl:text>
</xsl:with-param>
<xsl:with-param name="by">
<xsl:value-of select="$postmacro"/>
</xsl:with-param>
</xsl:call-template>
</xsl:variable>
We build a new version of the text string parameter in the
variable etext. Two nested calls on the
do-replace template are made, one to replace the
premacro escape, and one to replace the postmacro
escape.
<substparms: build result string recursively 3.14> =<xsl:variable name="result">
<xsl:choose>
<xsl:when test="$head=''">
<xsl:value-of select="$etext"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$head"/>
<xsl:value-of select="$value"/>
<xsl:if test="$tail!=''">
<xsl:call-template name="substparms">
<xsl:with-param name="text">
<xsl:value-of select="$tail"/>
</xsl:with-param>
<xsl:with-param name="parmtable" select="$parmtable"/>
</xsl:call-template>
</xsl:if>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
Build the result of macro expansion recursively. The (first) macro parameter is chopped out, leaving a head and tail string. The parameter is looked up to find its replacement value, and the result returned is the head string, the replacement text value, and the recursive expansion of the tail string.
3.3 litprog: the tangle pass
<litprog: the tangle pass 3.15> =
3.3.1 litprog: tangle all litprog files
<litprog: tangle all litprog files 3.16> =<xsl:template match="litprog" mode="tangle">
<xsl:for-each select="/litprog//o">
{Note 3.16.1}
<xsl:variable name="thisfile" select="@file"/>
<xsl:if test="not(preceding::o[@file=$thisfile])">
{Note 3.16.2}
<xsl:message>
{Note 3.16.3}
<xsl:text>Writing file "</xsl:text>
<xsl:value-of select="@file"/>
<xsl:text>"</xsl:text>
</xsl:message>
<xsl:document href="{$thisfile}" omit-xml-declaration="yes"
indent="yes" method="text">
{Note 3.16.4}
<xsl:apply-templates select="." mode="tangle"/>
{Note 3.16.5}
<xsl:for-each
select="following::o[@file=$thisfile]">
{Note 3.16.6}
<xsl:apply-templates select="." mode="tangle"/>
</xsl:for-each>
</xsl:document>
</xsl:if>
</xsl:for-each>
</xsl:template>
- {Note 3.16.1}
- see point 1
- {Note 3.16.2}
- see
point 2
- {Note 3.16.3}
- see point 3
- {Note 3.16.4}
- see point 4
- {Note 3.16.5}
- see
point 5
- {Note 3.16.6}
- see point 6
To tangle a complete litprog, we scan through all file
chunk definitions, expanding them into an appropriately
named file. Issue a message as each one is processed.
(version 2.4.0) There was a bug here: multiple chunks of
"o" elements did not get appended, since each one
started a new document, thus overwriting the previous chunk.
Here the new logic is this:
- Do all tangling by searching for "o" elements.
- For each one found, check if it is the first one
with this particular file name. If it isn't, ignore it.
- If it is, issue a message that we are tangling the
file, then ....
- ... start a new document with this file name ...
- ... tangle this chunk and ...
- ... tangle all following "o" chunks with the same filename.
3.3.2 litprog: tangle a single file definition chunk
<litprog: tangle a single file definition chunk 3.17> =<xsl:template match="o" mode="tangle">
<xsl:variable name="chunk">
<xsl:apply-templates mode="tangle"/>
</xsl:variable>
<xsl:variable name="chunks">
<xsl:choose>
<xsl:when test='starts-with($chunk,"
")'>
<xsl:value-of select="substring($chunk,2)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$chunk"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:value-of select="$chunks"/>
</xsl:template>
This is done in a manner similar to code chunk tangling.
Here, only the leading new line character is removed. Why?
Good question. When I have an answer, I'll add it to this
documentation.
3.3.3 litprog: tangle a code definition
<litprog: tangle a code definition 3.18> =
A code chunk is tangled in three stages.
Firstly, the chunk has any nested elements resolved and
expanded, as appropriate. This expansion is saved in the
local variable chunki (initial chunk).
<tangle code, initial chunk 3.19> =<xsl:variable name="chunki">
<xsl:apply-templates mode="tangle"/>
</xsl:variable>
Secondly, if the chunk ends in a newline character and the
trim attribute is set to yes, the trailing newline is
removed. The result of this operation is saved in the
variable chunke (end trimmed chunk).
<tangle code, end trimmed chunk 3.20> =<xsl:variable name="chunke">
<xsl:choose>
<xsl:when test='substring($chunki,string-length($chunki)) = "
"
and @trim="yes"'>
<xsl:value-of select="substring($chunki,1,string-length($chunki)-1)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$chunki"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
Thirdly, a leading newline character is removed, if
present. The result of this operation is saved in the
variable chunkes (start and end trimmed chunk).
<tangle code, start and end trimmed chunk 3.21> =<xsl:variable name="chunkes">
<xsl:choose>
<xsl:when test='starts-with($chunke,"
")'>
<xsl:value-of select="substring($chunke,2)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$chunke"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
The resultant value is returned as the result of tangling
this code fragment or chunk.
<tangle code, debugging 3.22> =<xsl:message>
<xsl:text>Depth of 'd' node = </xsl:text>
<xsl:value-of select="count(ancestor::*)"/>
<xsl:text></xsl:text>
</xsl:message>
<xsl:variable name="chunk">
<xsl:for-each select="*/text()">
<xsl:message><xsl:value-of select="name()"/></xsl:message>
<xsl:apply-templates select="." mode="tangle"/>
</xsl:for-each>
</xsl:variable>
<xsl:message><xsl:value-of select="$chunk"/></xsl:message>
<xsl:variable name="chunki">
<xsl:value-of select="$chunk"/>
<xsl:call-template name="do-replace">
<xsl:with-param name="text" select="$chunk"/>
<xsl:with-param name="replace">=</xsl:with-param>
<xsl:with-param name="by">:=</xsl:with-param>
</xsl:call-template>
</xsl:variable>
3.3.4 litprog: tangle variable declarations
<litprog: tangle variable declarations 3.23> =<xsl:template match="d/v | o/v" mode="tangle">
<xsl:apply-templates mode="tangle"/>
</xsl:template>
In tangle mode, variable definitions and uses are basically
passed straight through to the weft phase.
3.3.5 litprog: discard documentation in tangle mode
<litprog: discard documentation in tangle mode 3.24> =<xsl:template match="p" mode="tangle">
</xsl:template>
<xsl:template match="d/com|o/com" mode="tangle">
</xsl:template>
All documentation fragments are ignored in tangle mode.
3.3.6 litprog: tangle all chunks into a single use
<litprog: tangle all chunks into a single use 3.25> =
A use call on a chunk name has been made, which must be
expanded into the document-order concatenation of all code
chunk definitions with the same name.
3.3.6.1 litprog: replace the machine parameter in chunk name
<litprog: replace the machine parameter in chunk name 3.26> =<xsl:variable name="chunkname">
<xsl:call-template name="do-replace">
<xsl:with-param name="text" select="@name"/>
<xsl:with-param name="replace">{$machine}</xsl:with-param>
<xsl:with-param name="by" select="$machine"/>
</xsl:call-template>
</xsl:variable>
This bit is a hack. I really want a method to replace key
strings with parameters, but there isn't anything I can
think of other than using this "do-replace" with a
hard-coded substitution string. Incidentally, do-replace
is copied from Michael Kay's excellent book "XSLT
Programmer's Reference".
3.3.6.2 litprog: check whether to include a use chunk
<litprog: check whether to include a use chunk 3.27> =<xsl:variable name="include">
<xsl:choose>
<xsl:when test="@include">
<xsl:value-of select="@include"/>
</xsl:when>
<xsl:otherwise>yes</xsl:otherwise>
</xsl:choose>
</xsl:variable>
"include" is an attribute that allows the user to comment
out chunks of code, simply by putting an 'include="no"'
attribute into the chunk call. It defaults to "yes", so
set up that default.
3.3.6.3 litprog: save use parameters
<litprog: save use parameters 3.28> =<xsl:variable name="actuals" select="*"/>
3.3.6.4 litprog: compute indentations for use expansion
<litprog: compute indentations for use expansion 3.29> =<xsl:variable name="text-string">
<xsl:value-of select="string(preceding-sibling::text()[1])"/>
</xsl:variable>
<xsl:variable name="count-blanks">
<xsl:call-template name="count-trailing-blanks">
<xsl:with-param name="string" select="$text-string"/>
<xsl:with-param name="count">0</xsl:with-param>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="blanks">
<xsl:value-of select="substring($text-string,
string-length($text-string)-$count-blanks+1,
$count-blanks)"/>
</xsl:variable>
<xsl:variable name="indent" select="$blanks"/>
Now some stuff to determine indentation. This is heavy
XML. We first pull in the most recent text node in the
tree. This will have the indentation blanks before this
call on 'u', and so we count and extract those blanks.
Following that processing, the value of variable
$blanks will be inserted after all new
lines in the text generated by this call on 'u'. That,
together with the indentation that appeared before the
call itself, will mean that all lines of the replacement
text will have the same indentation, assuming that they
are themselves aligned - any additional indentation is
preserved.
3.3.6.5 litprog: check definitions for non-use
<litprog: check definitions for non-use 3.30> =<xsl:if test="count(/litprog//d[@name=$chunkname])=0">
<xsl:message>
<xsl:text>No definition of <</xsl:text>
<xsl:value-of select="$chunkname" disable-output-escaping="no"/>
<xsl:text>></xsl:text>
</xsl:message>
</xsl:if>
Now check that we have some definitions of this chunk.
Count them and issue a warning if the count is zero.
3.3.6.6 litprog: include raw text and expand indentation
<litprog: include raw text and expand indentation 3.31> =
Firstly, cross reference this call on the chunk.
Then the real code expansion takes place. We collect up
all matching chunk definitions, and add them in document
order.
If the chunk is to be included, build the raw text of it,
and then expand all newlines with indentation as computed
above.
<litprog: include text and expand: start message 3.32> =<xsl:if test="$Verbose>1">
<xsl:message terminate="no">
<xsl:text>Using chunk named "</xsl:text>
<xsl:value-of select="$chunkname"/>
<xsl:text>" </xsl:text>
<xsl:for-each select="$actuals">
<xsl:value-of select="string(.)"/>
</xsl:for-each>
</xsl:message>
</xsl:if>
debug this call on expanding a chunk
<litprog: include text and expand: loop message 3.33> =<xsl:if test="$Verbose>1">
<xsl:message terminate="no">
<xsl:text>Matches are "</xsl:text>
<xsl:value-of select="@name" disable-output-escaping="no"/>
<xsl:text>"</xsl:text>
</xsl:message>
</xsl:if>
Show all the chunks that match this use instance.
<litprog: include text and expand: define parmtable 3.34> =<xsl:variable name="parmtable">
<xsl:if test="$Verbose>=2">
<xsl:message>
<xsl:text>building parmtable,parms=</xsl:text>
<xsl:value-of select="$actuals"/>
</xsl:message>
</xsl:if>
<xsl:for-each select="$actuals">
<xsl:value-of select="$premacro"/>
<xsl:value-of select="./@name"/>
<xsl:value-of select="$postmacro"/>
<xsl:value-of select="$premacro"/>
<xsl:call-template name="do-replace">
<xsl:with-param name="text">
<xsl:call-template name="do-replace">
<xsl:with-param name="text">
<xsl:apply-templates mode="tangle"/>
</xsl:with-param>
<xsl:with-param name="replace">
<xsl:value-of select="$premacro"/>
</xsl:with-param>
<xsl:with-param name="by">
<xsl:text>{{</xsl:text><xsl:text>{{</xsl:text>
</xsl:with-param>
</xsl:call-template>
</xsl:with-param>
<xsl:with-param name="replace">
<xsl:value-of select="$postmacro"/>
</xsl:with-param>
<xsl:with-param name="by">
<xsl:text>}}</xsl:text><xsl:text>}}</xsl:text>
</xsl:with-param>
</xsl:call-template>
<xsl:value-of select="$postmacro"/>
</xsl:for-each>
</xsl:variable>
<xsl:if test="$Verbose>=2">
<xsl:message>parmtable=<xsl:value-of select="$parmtable"/></xsl:message>
</xsl:if>
Build the parameter table. This is a string where each
actual parameter is surrounded by the pre- and post- macro
strings (as defined by the variables premacro and
postmacro respectively), then concatenated together
in parameter document order.
<litprog: include text and expand: define rawchunk 3.35> =<xsl:variable name="rawchunk">
<xsl:apply-templates select="." mode="tangle"/>
</xsl:variable>
Build the raw chunk corresponding to this use instance match.
<litprog: include text and expand: define raw2 3.36> =<xsl:variable name="raw2">
<xsl:call-template name="substparms">
<xsl:with-param name="text">
<xsl:value-of select="$rawchunk"/>
</xsl:with-param>
<xsl:with-param name="parmtable" select="$parmtable"/>
</xsl:call-template>
</xsl:variable>
Now expand the actual parameters into the raw chunk,
replacing all formal parameters.
<litprog: include text and expand: replace text 3.37> =<xsl:call-template name="do-replace">
<xsl:with-param name="text">
<xsl:value-of select="$raw2"/>
</xsl:with-param>
<xsl:with-param name="replace">
<xsl:text>
</xsl:text>
</xsl:with-param>
<xsl:with-param name="by">
<xsl:text>
</xsl:text>
<xsl:value-of select="$indent"/>
</xsl:with-param>
</xsl:call-template>
Now rebuild the replacement text by expanding all
newlines with their appropriate indentation. This is to
preserve the indentation established in the actual call on
this chunk.
3.3.7 litprog: default tangle template
<litprog: default tangle template 3.38> =<xsl:template match="*" mode="tangle">
<xsl:variable name="check">
<xsl:text>|</xsl:text>
<xsl:value-of select="name()"/>
<xsl:text>|</xsl:text>
</xsl:variable>
<xsl:if test="$Verbose and not(contains($docos,$check))">
<xsl:message terminate="no">
<xsl:text>No warp-tangle template for </xsl:text>
<xsl:value-of select="name()"/>
</xsl:message>
</xsl:if>
<xsl:element name="{name()}">
<xsl:apply-templates mode="tangle"/>
</xsl:element>
</xsl:template>
This is the default tangle template, invoked if there is no
other template defined to handled this element. Provide an
error message in the event of no tangle template.
3.4 litprog: the weave pass
<litprog: the weave pass 3.39> =
3.4.1 litprog: weave a litprog
<litprog: weave a litprog 3.40> =<xsl:template match="litprog" mode="weave">
<xsl:apply-templates mode="weave"/>
</xsl:template>
Not really much to this, since the whole litprog file is
scanned in document order, generating the intermediate
documentation file as we go.
3.4.2 litprog: weave a code or file definition
<litprog: weave a code or file definition 3.41> =<xsl:template match="d | o" mode="weave">
<xsl:variable name="chunkname">
<xsl:choose>
<xsl:when test="name()='d'">
<xsl:value-of select="@name"/>
</xsl:when>
<xsl:when test="name()='o'">
<xsl:value-of select="@file"/>
</xsl:when>
</xsl:choose>
</xsl:variable>
<xsl:element name="CODE">
<xsl:attribute name="type">
<xsl:choose>
<xsl:when test="name()='d'">define</xsl:when>
<xsl:when test="name()='o'">file</xsl:when>
</xsl:choose>
</xsl:attribute>
<xsl:attribute name="name">
<xsl:value-of select="$chunkname"/>
</xsl:attribute>
<xsl:attribute name="number">
<xsl:number format="1" level="multiple" count="section|DocumentHistory"/>
<xsl:text>.</xsl:text>
<xsl:number from="section" level="any" count="d|o"/>
</xsl:attribute>
<xsl:attribute name="defines">
<xsl:call-template name="lookupchunkno">
<xsl:with-param name="chunkname">
<xsl:value-of select="$chunkname"/>
</xsl:with-param>
</xsl:call-template>
</xsl:attribute>
<xsl:attribute name="uses">
{Note 3.41.1}
<xsl:variable name="defnode" select="."/>
<xsl:for-each select="child::u">
<xsl:if test="position()>1">
<xsl:text>, </xsl:text>
</xsl:if>
<litprog: d-weave debug message-1 3.42> **** Chunk omitted!
<xsl:call-template name="lookupchunkno">
<xsl:with-param name="chunkname" select="@name"/>
</xsl:call-template>
</xsl:for-each>
</xsl:attribute>
<xsl:apply-templates mode="weave"/>
</xsl:element>
<litprog: weave a code comment 3.43>
</xsl:template>
- {Note 3.41.1}
-
Build the uses attribute list, by scanning all child
u elements, and looking up their chunk numbers.
The d | o template, in the weave mode, builds a CODE
element in the woven .xml file, CODE elements define code
fragments. Such elements can have the following attributes:
- type
- for a d fragment, the type is define,
indicating a chunk definition. For an o fragment, the
type is file.
- name
- The name of the code chunk or fragment. For example,
the name of the following code chunk is litprog:
d | o-weave template. For a file fragment, the name
attribute gives the name of the file.
- number
- code chunks are numbered in sequence from the
beginning, for cross referencing purposes.
<litprog: d-weave debug message-1 3.42> =<xsl:message>
<xsl:text>Macro "</xsl:text>
<xsl:value-of select="$defnode/@name"/>
<xsl:text>" references "</xsl:text>
<xsl:value-of select="./@name"/>
<xsl:text>", </xsl:text>
<xsl:call-template name="lookupchunkno">
<xsl:with-param name="chunkname" select="@name"></xsl:with-param>
</xsl:call-template>
</xsl:message>
Generate a helpful debug message to show what other
fragments this code chunk uses.
<litprog: weave a code comment 3.43> =<xsl:if test='./com'>
<xsl:element name='NOTES'>
<xsl:for-each select="./com">
{Note 3.43.1}
<xsl:element name="NOTE">
<xsl:attribute name="HREF">
<xsl:value-of select="position()"/>
</xsl:attribute>
<xsl:apply-templates mode="weave"/>
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:if>
- {Note 3.43.1}
-
Scan through all in-line comments (such as this one), and
for each one, generate a NOTE element, cross
referenced by the ordinal number of this comment within
the chunk.
<litprog: d/com|o/com-weave template 3.44> =<xsl:template match="d/com | o/com" mode="weave">
<xsl:variable name="mypos">
<xsl:value-of select="count(preceding-sibling::com)+1"/>
</xsl:variable>
<xsl:element name="COMMENT">
<xsl:attribute name="HREF">
<xsl:value-of select="$mypos"/>
</xsl:attribute>
</xsl:element>
</xsl:template>
This template, d/com|o/com, handles
comments with code fragments in the weave pass. The comment
itself is handled later, but for the moment, we just insert
a forward reference to it as a link in the current code
fragment. The reference is identified by the ordinal
position of the comment within this code fragment.
3.4.3 litprog: weave a variable markup
The elements 'u' (use) and 'v' (value) both refer to 'd'
(define) elements elsewhere in the document. The difference
is that in weave mode 'u' inserts a hot link to the actual
definition, whereas 'v' inserts the actual value defined in
the 'd' element. This is equivalent to macro expansion, and
is what happens to 'u' elements in tangle mode. In tangle
mode, 'v' elements are ignored. In other words, 'v'
elements are only relevant to document fragments.
<litprog: weave a variable markup 3.45> =<xsl:template match="v" mode="weave">
<xsl:choose>
<xsl:when test="@var='use' or not(@var)">
<xsl:element name="VAR">
<xsl:attribute name="VAR">use</xsl:attribute>
<xsl:value-of select="."/>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:element name="NAME">
<xsl:value-of select="@name"/>
</xsl:element>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<litprog: weave a variable markup 3.46> =<!-- handle variable markup -->
<xsl:template match="d/v | o/v" mode="weave">
<xsl:element name="VAR">
<xsl:attribute name="VAR">
<xsl:choose>
<xsl:when test="@var">
<xsl:value-of select="@var"/>
</xsl:when>
<xsl:otherwise>
<xsl:text>use</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<xsl:if test="@name">
<xsl:attribute name="NAME">
<xsl:value-of select="@name"/>
</xsl:attribute>
</xsl:if>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
3.4.4 litprog: u-weave template
The u-weave template is responsible for inserting a
link to the definition of the referenced code fragment,
in-line in the documentation. Note that at this stage, the
include parameter is simply passed on: it is not
interpreted as to whether the code fragment is actally
included until the documentation construction phase.
<litprog: u-weave template 3.47> =<xsl:template match="u" mode="weave">
<xsl:element name="USE">
<xsl:attribute name="NAME">
<xsl:value-of select="@name"/>
</xsl:attribute>
<xsl:if test="@expand">
<xsl:attribute name="EXPAND">
<xsl:value-of select="@expand"/>
</xsl:attribute>
</xsl:if>
<xsl:if test="@include">
<xsl:attribute name="INCLUDE">
<xsl:value-of select="@include"/>
</xsl:attribute>
</xsl:if>
<xsl:for-each select="*">
<xsl:choose>
<xsl:when test="name()='name' or name()='expand'">
</xsl:when>
<xsl:when test="name()='formal'">
<xsl:element name="formal">
<xsl:attribute name="name">
<xsl:value-of select="@name"/>
</xsl:attribute>
<xsl:value-of select="."/>
</xsl:element>
</xsl:when>
<xsl:when test="name()='actual'">
<xsl:element name="actual">
<xsl:attribute name="name">
<xsl:value-of select="@name"/>
</xsl:attribute>
<xsl:apply-templates mode="weave"/>
</xsl:element>
</xsl:when>
<xsl:otherwise>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:element>
<xsl:if test="$Verbose>1">
<xsl:message>
<xsl:text>Macro "</xsl:text>
<xsl:value-of select="normalize-space(@name)"/>
<xsl:text>" referenced in weave mode in "</xsl:text>
<xsl:value-of select="ancestor::d/@name"/>
<xsl:text>"</xsl:text>
</xsl:message>
</xsl:if>
</xsl:template>
<litprog: u-weave template 3.48> =<xsl:template match="formal" mode="weave">
<xsl:element name="formal">
<xsl:attribute name="name">
<xsl:value-of select="@name"/>
</xsl:attribute>
<xsl:apply-templates mode="weave"/>
</xsl:element>
</xsl:template>
3.4.5 litprog: p-weave template
<litprog: p-weave template 3.49> =<xsl:template match="p" mode="weave">
<P><xsl:apply-templates mode="weave"/></P>
</xsl:template>
3.4.6 litprog: section-weave template
<litprog: section-weave template 3.50> =<xsl:template match="section" mode="weave">
<xsl:element name="section">
<xsl:choose>
<xsl:when test="@numbers">
<xsl:attribute name="numbers">
<xsl:value-of select="@numbers"/>
</xsl:attribute>
</xsl:when>
<xsl:otherwise>
<xsl:attribute name="numbers">yes</xsl:attribute>
</xsl:otherwise>
</xsl:choose>
<xsl:choose>
<xsl:when test="@newpage">
<xsl:attribute name="newpage">
<xsl:value-of select="@newpage"/>
</xsl:attribute>
</xsl:when>
<xsl:otherwise>
<xsl:attribute name="newpage">yes</xsl:attribute>
</xsl:otherwise>
</xsl:choose>
<xsl:attribute name="xref">
<xsl:value-of select="translate(./title,' ?():.,-','')"
disable-output-escaping="no"/>
</xsl:attribute>
<xsl:apply-templates mode="weave"/>
</xsl:element>
</xsl:template>
<xsl:template match="subsection" mode="weave">
<xsl:element name="subsection">
<xsl:choose>
<xsl:when test="@numbers">
<xsl:attribute name="numbers">
<xsl:value-of select="@numbers"/>
</xsl:attribute>
</xsl:when>
<xsl:otherwise>
<xsl:attribute name="numbers">no</xsl:attribute>
</xsl:otherwise>
</xsl:choose>
<xsl:choose>
<xsl:when test="@newpage">
<xsl:attribute name="newpage">
<xsl:value-of select="@newpage"/>
</xsl:attribute>
</xsl:when>
<xsl:otherwise>
<xsl:attribute name="newpage">no</xsl:attribute>
</xsl:otherwise>
</xsl:choose>
<xsl:attribute name="xref">
<xsl:value-of select="translate(./title,' ?():.,-','')"
disable-output-escaping="no"/>
</xsl:attribute>
<xsl:apply-templates mode="weave"/>
</xsl:element>
</xsl:template>
<xsl:template match="subsubsection" mode="weave">
<xsl:element name="subsubsection">
<xsl:attribute name="xref">
<xsl:value-of select="translate(./title,' ?():.,-','')"
disable-output-escaping="no"/>
</xsl:attribute>
<xsl:apply-templates mode="weave"/>
</xsl:element>
</xsl:template>
3.4.7 litprog: listing templates
<litprog: listing templates 3.51> =<xsl:template match="
filelist" mode="weave">
<xsl:text>
</xsl:text>
<xsl:element name="filelist">
</xsl:element>
</xsl:template>
<xsl:template match="
macrolist" mode="weave">
<xsl:text>
</xsl:text>
<xsl:element name="macrolist">
<xsl:if test="@namewidth">
<xsl:attribute name="namewidth">
<xsl:value-of select="@namewidth"/>
</xsl:attribute>
</xsl:if>
<xsl:if test="@definewidth">
<xsl:attribute name="definewidth">
<xsl:value-of select="@definewidth"/>
</xsl:attribute>
</xsl:if>
<xsl:if test="@usewidth">
<xsl:attribute name="usewidth">
<xsl:value-of select="@usewidth"/>
</xsl:attribute>
</xsl:if>
</xsl:element>
</xsl:template>
<xsl:template match="
identifierlist" mode="weave">
<xsl:text>
</xsl:text>
<xsl:element name="IdentifierDefinitions">
<xsl:if test="@namewidth">
<xsl:attribute name="namewidth">
<xsl:value-of select="@namewidth"/>
</xsl:attribute>
</xsl:if>
<xsl:if test="@definewidth">
<xsl:attribute name="definewidth">
<xsl:value-of select="@definewidth"/>
</xsl:attribute>
</xsl:if>
<xsl:if test="@usewidth">
<xsl:attribute name="usewidth">
<xsl:value-of select="@usewidth"/>
</xsl:attribute>
</xsl:if>
</xsl:element>
</xsl:template>
3.4.8 litprog: default weave template
<litprog: default weave template 3.52> =<xsl:template match="*" mode="weave">
<xsl:variable name="check">
<xsl:text>|</xsl:text>
<xsl:value-of select="name()"/>
<xsl:text>|</xsl:text>
</xsl:variable>
<xsl:if test="$Verbose>0 and not(contains($docos,$check))">
<xsl:message terminate="no">
<xsl:text>No warp-weave template for </xsl:text>
<xsl:value-of select="name()"/>
</xsl:message>
</xsl:if>
<xsl:element name="{name()}">
<xsl:for-each select="@*">
<xsl:attribute name="{name()}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:for-each>
<xsl:apply-templates mode="weave"/>
</xsl:element>
</xsl:template>
This template handles all elements not elsewhere handled in
the weave pass. Note that a table of documentation related
elements is kept, and if an element name is matched in this
table, no warning message is issued. All elements, whether
flagged or not, are passed straight through. Note that all
the attributes must be copied as well.
In performing the table lookup, note that the separator
must be present at both ends. This is to ensure that names
that are substrings are not matched implicitly.
4. The weft, or documentation phase
This phase retranslates the output file from phase 1, the XML
file. There is a translation script for each class of
documentation processors. Two are defined here,
lit2html.xsl, for translation to HTML, and
lit2tex.xsl, for translation to TeX.
4.1 lit2html.xsl
"lit2html.xsl" 4.1 =
4.1.1 lit2html: handle the root element
<lit2html: handle the root element 4.2> =
4.1.2 lit2html: handle the literate program translation
<lit2html: handle the literate program translation 4.3> =<xsl:template match="LitprogXML">
<xsl:apply-templates/>
</xsl:template>
4.1.3 lit2html: handle documentation fragments
<lit2html: handle documentation fragments 4.4> =<xsl:template match="abstract">
<H2 ALIGN="center">Abstract</H2>
<DIV STYLE="margin-left:20pt">
<xsl:apply-templates/>
</DIV>
</xsl:template>
The abstract gets a title, and indentation
<lit2html: handle documentation fragments 4.5> =<xsl:template match="author">
<H2 ALIGN="center"><xsl:apply-templates/></H2>
</xsl:template>
Centre the author in heading font
<lit2html: handle documentation fragments 4.6> =<xsl:template match="date">
<H2 ALIGN="center"><xsl:apply-templates/></H2>
</xsl:template>
Ditto the date
<lit2html: handle documentation fragments 4.7> =<xsl:template match='title'>
<H1 ALIGN="center"><xsl:apply-templates/></H1>
</xsl:template>
The title is a bit more important
<lit2html: handle documentation fragments 4.8> =<xsl:template match='subtitle'>
<H2 ALIGN="center"><xsl:apply-templates/></H2>
</xsl:template>
The subtitle is less important
<lit2html: handle documentation fragments 4.9> =<xsl:template match="version">
<H3 ALIGN="center">
<xsl:text>Version </xsl:text>
<xsl:apply-templates/>
</H3>
</xsl:template>
Label the version
<lit2html: handle documentation fragments 4.10> =<xsl:template match="P">
<P><xsl:apply-templates/></P>
</xsl:template>
Build documentation paragraphs
4.1.4 lit2html: handle code fragment references
<lit2html: handle code fragment references 4.11> =<xsl:template match="VALUE">
<xsl:variable name="myname" select="."/>
<xsl:value-of select="//CODE[@name=$myname]"/>
</xsl:template>
I think this one is out-of-date. Check if VALUE elements
are ever created by < >
<lit2html: handle code fragment references 4.12> =<xsl:template match="NAME">
<xsl:variable name="myname" select="."/>
<xsl:element name="A">
<xsl:attribute name="HREF">
<xsl:text>#</xsl:text>
<xsl:value-of select="$myname"/>
</xsl:attribute>
<xsl:value-of select="$myname"/>
</xsl:element>
</xsl:template>
Not sure about this one either.
4.1.5 lit2html: handle a code fragment use
<lit2html: handle a code fragment use 4.13> =<xsl:template match="USE">
<!--<xsl:text disable-output-escaping="yes"><I></xsl:text>-->
{Note 4.13.1}
<xsl:variable name="myname" select="@NAME"/>
<xsl:choose>
<xsl:when test="@EXPAND">
<xsl:value-of select="//CODE[@name=$myname]"/>
</xsl:when>
<xsl:otherwise>
<xsl:element name="I">
<xsl:element name="A">
<xsl:attribute name="HREF">#<xsl:value-of select="@NAME"/>
</xsl:attribute>
<xsl:text disable-outputescaping="yes"><</xsl:text>
<xsl:value-of select="@NAME"/>
<xsl:text disable-outputescaping="yes"> </xsl:text>
<xsl:for-each select="//CODE[@name=$myname]">
<xsl:if test="position()>1"><xsl:text>,</xsl:text></xsl:if>
<xsl:value-of select="@number"/>
</xsl:for-each>
<xsl:text disable-outputescaping="yes">></xsl:text>
</xsl:element>
</xsl:element>
<xsl:if test="actual">
<xsl:element name="span">
<xsl:attribute name="style">color:brown</xsl:attribute>
<xsl:text>(</xsl:text>
<xsl:for-each select="actual">
<xsl:if test="position()>1">
<xsl:text>, </xsl:text>
</xsl:if>
<xsl:value-of select="@name"/>
<xsl:text>='</xsl:text>
<xsl:element name="span">
<xsl:attribute name="style">color:green</xsl:attribute>
<xsl:apply-templates/>
</xsl:element>
<xsl:text>'</xsl:text>
</xsl:for-each>
<xsl:text>)</xsl:text>
</xsl:element>
</xsl:if>
<xsl:if test="formal">
<xsl:text>formal, name=</xsl:text>
<xsl:value-of select="@name"/>
</xsl:if>
<xsl:if test="@INCLUDE='no'">
<xsl:element name="SPAN">
<xsl:attribute name="STYLE">color:red</xsl:attribute>
<xsl:text> **** Chunk omitted!</xsl:text>
</xsl:element>
</xsl:if>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
- {Note 4.13.1}
-
I generate the I tag literally here because the use of
xsl:element generates an I element with a leading newline -
NOT what is wanted here!
4.1.6 lit2html: handle code chunk definitions
<lit2html: handle code chunk definitions 4.14> =<xsl:template match="CODE">
<!-- Issue anchor to bind by name of chunk -->
<xsl:element name="A">
<xsl:attribute name="NAME">
<xsl:value-of select="@name"/>
</xsl:attribute>
</xsl:element>
<!-- Issue anchor to bind by number of chunk -->
<xsl:element name="A">
<xsl:attribute name="NAME">
<xsl:text>xlp:</xsl:text>
<xsl:value-of select="@number"/>
</xsl:attribute>
</xsl:element>
<!-- Handle file chunk -->
<xsl:if test="@type='file'">
<xsl:text disable-output-eascaping="yes">"</xsl:text>
<xsl:element name="a">
<xsl:attribute name="href">
<xsl:value-of select="@name"/>
</xsl:attribute>
<xsl:value-of select="@name"/>
</xsl:element>
<xsl:text disable-output-escaping="yes">"</xsl:text>
<xsl:text disable-output-escaping="yes"> </xsl:text>
<xsl:value-of select="@number"/>
<xsl:text disable-output-escaping="yes"> =</xsl:text>
</xsl:if>
<!-- Handle code chunk -->
<xsl:if test="@type='define'">
<xsl:text disable-output-escaping="no"><</xsl:text>
<xsl:element name="SPAN">
<xsl:attribute name="STYLE">
<xsl:text>color:purple</xsl:text>
</xsl:attribute>
<xsl:value-of select="@name"/>
<xsl:text disable-output-escaping="no"> </xsl:text>
<xsl:value-of select="@number"/>
</xsl:element>
<xsl:text disable-output-escaping="no">> =</xsl:text>
</xsl:if>
<!-- Format the code body, including cross references -->
<lit2html: format the code body 4.15>
<lit2html: build code chunk reference list 4.18>
<DIV STYLE="margin-left:30pt">
<lit2html: display code chunk reference list 4.19>
<lit2html: build code chunk definition list 4.20>
</DIV>
</xsl:template>
<lit2html: format the code body 4.15> =<xsl:choose>
<xsl:when test="
<lit2html: body contains new line characters 4.17>">
<xsl:element name="DIV">
<xsl:attribute name="STYLE" >
margin-left:30pt;white-space:pre;font-family:monospace;
border:thin solid;background:pink
</xsl:attribute>
<xsl:apply-templates mode="stripleadingnl"/>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:text> </xsl:text>
<xsl:element name="SPAN">
<xsl:attribute name="STYLE" >
white-space:pre;font-family:monospace;
border:thin solid;background:pink
</xsl:attribute>
<xsl:apply-templates/>
</xsl:element>
</xsl:otherwise>
</xsl:choose>
There are two basic choices for the code body. Short text
only fragments containing no new lines are formatted
directly onto the definition line, to emphasize the fact
that no new lines are part of the code fragment. Code
bodies containing more than one element <lit2html: body contains several children > (as when a macro call is
expanded within the body), or containing at least one new
line <lit2html: body contains new line characters >, are formatted into a separate paragraph.
<lit2html: body contains several children 4.16> = count(child::*)>0
<lit2html: body contains new line characters 4.17> = contains(.,'
')
Two examples for the last paragraph! Note that the second
half of the condition can be explained the same way, even
though it contains a new line character, since the new line
is escaped.
<lit2html: build code chunk reference list 4.18> =<xsl:variable name="thisname" select="@name"/>
<xsl:variable name="
reflist">
<xsl:for-each select="//CODE">
<xsl:variable name="refnumber" select="@number"/>
<xsl:for-each select="descendant::USE[@NAME=$thisname]">
<xsl:text> </xsl:text>
<xsl:element name="A">
<xsl:attribute name="HREF">
<xsl:text>#xlp:</xsl:text>
<xsl:value-of select="$refnumber"/>
</xsl:attribute>
<xsl:value-of select="$refnumber"/>
</xsl:element>
</xsl:for-each>
</xsl:for-each>
</xsl:variable>
Build a list of chunks in which this code chunk is
referenced, and store it in the variable reflist.
<lit2html: display code chunk reference list 4.19> =<xsl:if test="$
reflist!=''">
<xsl:element name="i">Chunk referenced in </xsl:element>
<xsl:for-each select="//CODE">
<xsl:variable name="refnumber" select="@number"/>
<xsl:if test="descendant::USE[@NAME=$thisname]">
<xsl:text> </xsl:text>
<xsl:element name="A">
<xsl:attribute name="HREF">
<xsl:text>#xlp:</xsl:text>
<xsl:value-of select="$refnumber"/>
</xsl:attribute>
<xsl:value-of select="$refnumber"/>
</xsl:element>
</xsl:if>
</xsl:for-each>
<xsl:element name="br"></xsl:element>
</xsl:if>
If the variable reflist is not empty, display the
list of chunk numbers for each of the chunk names in the
list. Only unique numbers need be displayed, hence the
nested if statement within the //CODE for-each,
rather than another for-each which would itemize repeated
uses.
<lit2html: build code chunk definition list 4.20> =<xsl:if test="count(//CODE[@name=$thisname])>1">
<xsl:element name="i">Chunk defined in </xsl:element>
<xsl:for-each select="//CODE[@name=$thisname]">
<xsl:if test="position()>1"><xsl:text>,</xsl:text></xsl:if>
<xsl:element name="A">
<xsl:attribute name="HREF">
<xsl:text>#xlp:</xsl:text>
<xsl:value-of select="@number"/>
</xsl:attribute>
<xsl:value-of select="@number"/>
</xsl:element>
</xsl:for-each>
<xsl:element name="br"></xsl:element>
</xsl:if>
Build a list of all the chunk numbers that also define this
chunk (that is, they have the same name). All of these
chunks are concatenated in document order to build the
resultant code chunk.
4.1.7 lit2html: handle notes and comments in code fragments
<lit2html: handle notes and comments in code fragments 4.21> =<xsl:template match="COMMENT">
<xsl:variable name="notenum">
<xsl:value-of select="ancestor::CODE/@number"/>
<xsl:text>.</xsl:text>
<xsl:value-of select="@HREF"/>
</xsl:variable>
<xsl:element name="A">
<xsl:attribute name="HREF">
<xsl:text>#xlp-note:</xsl:text>
<xsl:value-of select="$notenum"/>
</xsl:attribute>
<xsl:element name="SPAN">
<xsl:attribute name="STYLE">
<xsl:text>color:green</xsl:text>
</xsl:attribute>
<xsl:text>{Note </xsl:text>
<xsl:value-of select="$notenum"/>
<xsl:text>}</xsl:text>
</xsl:element>
</xsl:element>
</xsl:template>
<xsl:template match="NOTES">
<xsl:element name="DL">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template match="NOTE">
<xsl:variable name="notenum">
<xsl:value-of select="../preceding-sibling::CODE[1]/@number"/>
<xsl:text>.</xsl:text>
<xsl:value-of select="@HREF"/>
</xsl:variable>
<xsl:element name="DT">
<xsl:element name="A">
<xsl:attribute name="NAME">
<xsl:text>xlp-note:</xsl:text>
<xsl:value-of select="$notenum"/>
</xsl:attribute>
<xsl:element name="SPAN">
<xsl:attribute name="STYLE">
<xsl:text>color:green</xsl:text>
</xsl:attribute>
<xsl:text>{Note </xsl:text>
<xsl:value-of select="$notenum"/>
<xsl:text>}</xsl:text>
</xsl:element>
</xsl:element>
</xsl:element>
<xsl:element name="DD">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
4.1.8 lit2html: handle variable definitions and uses
<lit2html: handle variable definitions and uses 4.22> =<xsl:template match="VAR">
<xsl:choose>
<xsl:when test="@VAR='def'">
<xsl:element name="A">
<xsl:attribute name="NAME">
<xsl:text>VAR-</xsl:text>
<xsl:choose>
<xsl:when test="@NAME">
<xsl:value-of select="@NAME"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<xsl:attribute name="STYLE">color:red</xsl:attribute>
<xsl:apply-templates/>
</xsl:element>
</xsl:when>
<xsl:when test="@VAR='use'">
<xsl:element name="A">
<xsl:attribute name="HREF">
<xsl:text>#</xsl:text>
<xsl:text>VAR-</xsl:text>
<xsl:value-of select="."/>
</xsl:attribute>
<xsl:attribute name="STYLE">color:red</xsl:attribute>
<xsl:apply-templates/>
</xsl:element>
</xsl:when>
</xsl:choose>
</xsl:template>
Variable cross referencing generates links between the
variable use and definition points. A definition generates
an anchor of the form "VAR-variable
name", and a use generates a link to the anchor
similarly formed. These links and anchors are highlighted
in red.
4.1.9 lit2html: handle maintaintable
<lit2html: handle maintaintable 4.23> =<xsl:template match="maintaintable">
<TABLE BORDER="1" ALIGN="center">
<xsl:apply-templates select="./*"/>
</TABLE>
<P>
<xsl:text disable-output-escaping="yes">&nbsp;</xsl:text>
</P>
</xsl:template>
<xsl:template match="maintaintable/date">
<xsl:text disable-output-escaping="yes"><TR></xsl:text>
<TD>
<xsl:apply-templates/>
</TD>
</xsl:template>
<xsl:template match="maintaintable/author">
<TD>
<xsl:apply-templates/>
</TD>
</xsl:template>
<xsl:template match="maintaintable/version">
<TD>
<xsl:apply-templates/>
</TD>
</xsl:template>
<xsl:template match="maintaintable/comment">
<TD>
<xsl:apply-templates/>
</TD>
<xsl:text disable-output-escaping="yes"></TR></xsl:text>
</xsl:template>
4.1.10 lit2html: TableOfContents
TableOfContents builds a table of contents by scanning
all sections, subsections and subsubsections, using their
ordinal positions to construct a stepped list of section
numbers and titles
<lit2html: TableOfContents 4.24> =<xsl:template match="TableOfContents">
<xsl:element name="H2">
<xsl:attribute name="ALIGN">left</xsl:attribute>
<xsl:text>Table of Contents</xsl:text>
</xsl:element>
<xsl:element name="TABLE">
<xsl:attribute name="ALIGN">left</xsl:attribute>
<xsl:for-each select="/LitprogXML/section">
<xsl:variable name="titlestring">
<xsl:value-of select="translate(./title,' ?','')"
disable-output-escaping="no"/>
</xsl:variable>
<xsl:element name="TR">
<xsl:element name="TD">
<xsl:attribute name="ALIGN">right</xsl:attribute>
<xsl:number select="position(.)"/>
</xsl:element>
<xsl:element name="TD">
<xsl:attribute name="COLSPAN">3</xsl:attribute>
<xsl:element name="A">
<xsl:attribute name="HREF">
<xsl:text>#</xsl:text>
<xsl:value-of select="$titlestring"/>
</xsl:attribute>
<xsl:value-of select="title"/>
</xsl:element>
</xsl:element>
</xsl:element>
<xsl:for-each select="subsection">
<xsl:element name="TR">
<xsl:element name="TD"></xsl:element>
<xsl:element name="TD">
<xsl:value-of select="count(../preceding-sibling::section)+1"/>
<xsl:text>.</xsl:text>
<xsl:value-of select="position()"/>
</xsl:element>
<xsl:element name="TD">
<xsl:attribute name="COLSPAN">2</xsl:attribute>
<xsl:element name="A">
<xsl:attribute name="HREF">
<xsl:text>#</xsl:text>
<xsl:value-of select="./title"/>
</xsl:attribute>
<xsl:value-of select="title"/>
</xsl:element>
</xsl:element>
</xsl:element>
<xsl:for-each select="subsubsection">
<xsl:element name="TR">
<xsl:element name="TD"></xsl:element>
<xsl:element name="TD"></xsl:element>
<xsl:element name="TD">
<xsl:value-of select="count(../../preceding-sibling::section)+1"/>
<xsl:text>.</xsl:text>
<xsl:value-of select="count(../preceding-sibling::subsection)+1"/>
<xsl:text>.</xsl:text>
<xsl:value-of select="position()"/>
</xsl:element>
<xsl:element name="TD">
<xsl:element name="A">
<xsl:attribute name="HREF">
<xsl:text>#</xsl:text>
<xsl:value-of select="./title"/>
</xsl:attribute>
<xsl:value-of select="title"/>
</xsl:element>
</xsl:element>
</xsl:element>
</xsl:for-each>
</xsl:for-each>
</xsl:for-each>
</xsl:element>
<xsl:element name="BR">
<xsl:attribute name="CLEAR">all</xsl:attribute>
</xsl:element>
<xsl:element name="HR"></xsl:element>
</xsl:template>
4.1.11 lit2html: handle a code text element
<lit2html: handle a code text element 4.25> =<xsl:template match="c">
<xsl:element name="tt">
<xsl:attribute name="style">color:red</xsl:attribute>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
4.1.12 lit2html: construct file definition list
<lit2html: construct file definition list 4.26> =<xsl:template match="filelist">
<xsl:element name="TABLE">
<xsl:element name="TR">
<xsl:element name="TH">File Name</xsl:element>
<xsl:element name="TH">Defined in</xsl:element>
</xsl:element>
<xsl:for-each select="//CODE">
<xsl:sort select="./@name"/>
<xsl:variable name="thispos" select="position()"/>
<xsl:variable name="thisname" select="./@name"/>
<xsl:variable name="prevname" select="preceding::CODE[1]/@name"/>
<xsl:if test="(not($prevname) or $thisname!=$prevname) and @type='file'">
<xsl:element name="TR">
<xsl:element name="TD">
<xsl:value-of select="./@name"/>
</xsl:element>
<xsl:element name="TD">
<xsl:attribute name="ALIGN">left</xsl:attribute>
<xsl:for-each select="//CODE[@name=$thisname]">
<xsl:if test="position()>1">
<xsl:text>, </xsl:text>
</xsl:if>
<xsl:element name="A">
<xsl:attribute name="HREF">
<xsl:text>#xlp:</xsl:text>
<xsl:value-of select="./@number"/>
</xsl:attribute>
<xsl:value-of select="./@number"/>
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:element>
</xsl:if>
</xsl:for-each>
</xsl:element>
</xsl:template>
4.1.13 lit2html: construct chunk definition list
<lit2html: construct chunk definition list 4.27> =<xsl:template match="macrolist">
<xsl:element name="TABLE">
<xsl:element name="TR">
<xsl:element name="TH">Chunk Name</xsl:element>
<xsl:element name="TH">Defined in</xsl:element>
<xsl:element name="TH">Used in</xsl:element>
</xsl:element>
<xsl:for-each select="//CODE">
<xsl:sort select="./@name"/>
<xsl:variable name="thispos" select="position()"/>
<xsl:variable name="thisname" select="./@name"/>
<xsl:variable name="prevname" select="preceding::CODE[1]/@name"/>
<xsl:if test="$thisname!=$prevname and @type='define'">
<xsl:element name="TR">
<xsl:element name="TD">
<xsl:value-of select="./@name"/>
</xsl:element>
<xsl:element name="TD">
<xsl:attribute name="ALIGN">left</xsl:attribute>
<xsl:for-each select="//CODE[@name=$thisname]">
<xsl:if test="position()>1">
<xsl:text>, </xsl:text>
</xsl:if>
<xsl:element name="A">
<xsl:attribute name="HREF">
<xsl:text>#xlp:</xsl:text>
<xsl:value-of select="./@number"/>
</xsl:attribute>
<xsl:value-of select="./@number"/>
</xsl:element>
</xsl:for-each>
</xsl:element>
<xsl:element name="TD">
<xsl:attribute name="ALIGN">left</xsl:attribute>
<xsl:for-each select="//CODE/USE[@NAME=$thisname]">
<xsl:if test="position()>1">
<xsl:text>, </xsl:text>
</xsl:if>
<xsl:element name="A">
<xsl:attribute name="HREF">
<xsl:text>#xlp:</xsl:text>
<xsl:value-of select="ancestor::CODE/@number"/>
</xsl:attribute>
<xsl:value-of select="ancestor::CODE/@number"/>
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:element>
</xsl:if>
</xsl:for-each>
</xsl:element>
</xsl:template>
4.1.14 lit2html: construct identifier definition list
<lit2html: construct identifier definition list 4.28> =<xsl:template match="IdentifierDefinitions">
<xsl:element name="TABLE">
<xsl:element name="TR">
<xsl:element name="TH">Identifier</xsl:element>
<xsl:element name="TH">Defined in</xsl:element>
<xsl:element name="TH">Used in</xsl:element>
</xsl:element>
<xsl:for-each select="//VAR[@VAR='def']">
<xsl:sort select="."/>
<xsl:variable name="name" select="."/>
<xsl:element name="TR">
<xsl:element name="TD">
<xsl:value-of select="."/>
</xsl:element>
<xsl:element name="TD">
<xsl:attribute name="ALIGN">left</xsl:attribute>
<xsl:element name="A">
<xsl:attribute name="HREF">
<xsl:text>#xlp:</xsl:text>
<xsl:value-of select="ancestor::CODE/@number"/>
</xsl:attribute>
<xsl:value-of select="ancestor::CODE/@number"/>
</xsl:element>
</xsl:element>
<xsl:element name="TD">
<xsl:attribute name="ALIGN">left</xsl:attribute>
<xsl:for-each select="//CODE/VAR[@VAR='use' and string()=$name]">
<xsl:if test="position()>1">
<xsl:text>, </xsl:text>
</xsl:if>
<xsl:element name="A">
<xsl:attribute name="HREF">
<xsl:text>#xlp:</xsl:text>
<xsl:value-of select="ancestor::CODE/@number"/>
</xsl:attribute>
<xsl:value-of select="ancestor::CODE/@number"/>
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:template>
4.1.15 lit2html: handle macro parameters
<lit2html: handle macro parameters 4.29> =<xsl:template match="formal">
<xsl:element name="B">
<xsl:attribute name="style">color:brown</xsl:attribute>
<xsl:value-of select="@name"/>
</xsl:element>
</xsl:template>
4.1.16 lit2html: handle document history
<lit2html: handle document history 4.30> =<xsl:template match="DocumentHistory">
<HR SIZE="4" NOSHADE="yes"/><TABLE BORDER="0">
<H1>Document History</H1>
<xsl:apply-templates select="Modified"/>
</TABLE>
<xsl:apply-templates select="*[name()!='Modified']"/>
</xsl:template>
<xsl:template match="DocumentHistory/Modified">
<TR>
<xsl:apply-templates/>
</TR>
</xsl:template>
<xsl:template match="Modified/date">
<TD VALIGN="top">
<xsl:apply-templates/>
</TD>
</xsl:template>
<xsl:template match="Modified/version">
<TD VALIGN="top">
<xsl:apply-templates/>
</TD>
</xsl:template>
<xsl:template match="Modified/author">
<TD VALIGN="top">
<xsl:apply-templates/>
</TD>
</xsl:template>
<xsl:template match="Modified/comment">
<TD VALIGN="top">
<xsl:apply-templates/>
</TD>
</xsl:template>
4.1.17 lit2html: special character templates
Define here all the special characters that cannot be
represented exactly (either because there is no
corresponding glyph, or because they require escaping in
TeX
<lit2html: special character templates 4.31> =<xsl:template match="le">
<xsl:text><=</xsl:text>
</xsl:template>
<xsl:template match="dollar">
<xsl:text>$</xsl:text>
</xsl:template>
<xsl:template match="TeX">
<xsl:text>TeX</xsl:text>
</xsl:template>
4.1.18 lit2html: default template
<lit2html: default template 4.32> =<xsl:template match="text()" mode="stripleadingnl">
<xsl:choose>
<xsl:when test="position()=1 and substring(.,1,1)='
'">
<xsl:value-of select="substring(.,2)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="*" mode="stripleadingnl">
<xsl:apply-templates select="."/>
</xsl:template>
<xsl:template match="*">
<xsl:if test="$Verbose">
<xsl:message terminate="no">
<xsl:text>No weft-html template for </xsl:text>
<xsl:value-of select="name()"/>
</xsl:message>
</xsl:if>
<xsl:element name="{name()}">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
Three templates, which a) strip leading newlines from text
nodes, b) handle non-text nodes in stripping leading
new-lines, and c) a catch-all default template for all other
cases, that prints a warning message as appropriate. The
element and its attributes are passed through unchanged.
4.2 lit2tex.xsl
"lit2tex.xsl" 4.33 =
This file was originally constructed on 20030529:215331
The purpose of this file is to convert the XML output of the
literate programming XML tangle and weave translator <litprog.xsl 3.1> to a tex document, suitable for
processing by plain TeX.
It is assumed that the original litprog document
doc.xlp has been processed by <litprog.xsl 3.1>
to doc.xml. This script converts it to
doc.tex
4.2.1 lit2tex: handle the root node
<lit2tex: handle the root node 4.34> =<!-- the root node: do all the TeX setup and sign off -->
<weft: handle the root element 5.1>(weft root pre text='
<xsl:text disable-output-escaping="no">
\input mytexMacros
\input litprogverb
\input crossref
\def\nl{\hfil\break}
\def\url{\tt}
\parskip 4pt plus 10pt minus 2pt
\def\parameters{\enumerate\itemskip=2pt
\def\itemformat##1{\hss\$
\enumerateflag{\enumeratelevel}{##1}\enspace}}%
\let\endparameters=\endenumerate
\advance\vsize by 10pt
\advance\hsize by -20pt
\tolerance=1600
</xsl:text>
', weft root post text='
<xsl:text disable-output-escaping="no">\bye</xsl:text>
')
4.2.2 lit2tex: handle various documentation elements
<lit2tex: handle various documentation elements 4.35> =<!-- to be rewritten -->
<xsl:template match="abstract">
<H2 ALIGN="center">Abstract</H2>
<DIV STYLE="margin-left:20pt">
<xsl:apply-templates/>
</DIV>
</xsl:template>
<xsl:template match="author">
<xsl:text>\begin{centre}\large\bf </xsl:text>
<xsl:apply-templates/>
<xsl:text>\strut\end{centre}</xsl:text>
</xsl:template>
<xsl:template match="date">
<xsl:text>\begin{centre}\large </xsl:text>
<xsl:apply-templates/>
<xsl:text>\strut\end{centre}</xsl:text>
</xsl:template>
<xsl:template match='title|subtitle'>
<xsl:text>\begin{centre}\Large\bf </xsl:text>
<xsl:apply-templates/>
<xsl:text>\strut\end{centre}</xsl:text>
</xsl:template>
<xsl:template match="version">
<xsl:text>\begin{centre}\large\rm Version </xsl:text>
<xsl:apply-templates/>
<xsl:text>\strut\end{centre}</xsl:text>
</xsl:template>
<xsl:template match="VALUE">
<xsl:variable name="myname" select="."/>
<xsl:value-of select="//CODE[@name=$myname]"/>
</xsl:template>
<!-- to be rewritten -->
<xsl:template match="br"><BR/></xsl:template>
4.2.3 lit2tex: handle a literate program translation
<lit2tex: handle a literate program translation 4.36> =<xsl:template match="LitprogXML">
<xsl:apply-templates/>
</xsl:template>
4.2.4 lit2tex: handle paragraphs
<lit2tex: handle paragraphs 4.37> =<xsl:template match="P">
<xsl:apply-templates/>
<xsl:text>\par </xsl:text>
</xsl:template>
4.2.5 lit2tex: handle reference calls
<lit2tex: handle reference calls 4.38> =<xsl:template match="REF">
<xsl:variable name="myname" select="."/>
<xsl:text disable-outputescaping="yes">@<</xsl:text>
<xsl:apply-templates/>
<xsl:text disable-outputescaping="yes">@=</xsl:text>
<xsl:for-each select="//CODE[@name=$myname]">
<xsl:if test="position()>1"><xsl:text>, </xsl:text></xsl:if>
<xsl:value-of select="@number"/>
</xsl:for-each>
<xsl:text disable-outputescaping="yes">@></xsl:text>
</xsl:template>
4.2.6 lit2tex: handle code fragment definitions
This template formats a code fragment. There is special
work to be done on the name, because of escaping TeX
characters. Underlines are replaced with their escaped
versions and the result saved in the variable
escname. Note that the distinction between the escaped
string $escname and the unescaped string @name
must be preserved, depending upon whether we are using the
string for TeX purposes, or for XML purposes.
<lit2tex: handle code fragment definitions 4.39> =<xsl:template match="CODE">
<xsl:variable name="escname">
<xsl:call-template name="replacesubstring">
<xsl:with-param name="string" select="@name"/>
<xsl:with-param name="pattern">
<xsl:value-of select="'_'"/>
</xsl:with-param>
<xsl:with-param name="replacement">
<xsl:value-of select="'\_'"/>
</xsl:with-param>
</xsl:call-template>
</xsl:variable>
<xsl:if test="@type='file'">
<xsl:text>\vskip\parskip</xsl:text>
<xsl:text>\begingroup\vskip\parskip</xsl:text>
<xsl:text>\leavevmode\advance\leftskip by \codemargin</xsl:text>
<xsl:text>\kern-\codemargin{\it``</xsl:text>
<xsl:value-of select="$escname"/>
<xsl:text>"} </xsl:text>
<xsl:value-of select="@number"/>
<xsl:text> =</xsl:text>
</xsl:if>
<xsl:if test="@type='define'">
<xsl:text>\leavevmode\begingroup\advance\leftskip by \codemargin</xsl:text>
<xsl:text>\kern-\codemargin$<${\it </xsl:text>
<xsl:value-of select="$escname"/>
<xsl:text> </xsl:text>
<xsl:value-of select="@number"/>
<xsl:text>\/}$>$ =</xsl:text>
</xsl:if>
<xsl:text>\begin{codeverbatim}</xsl:text>
<xsl:apply-templates/>
<xsl:text>\end</xsl:text>
<!-- vitally important that these two text fragments be separate! -->
<xsl:text>{codeverbatim}\kern6pt$\diamond$\par
</xsl:text>
<xsl:text>\par
</xsl:text>
<xsl:variable name="thisname" select="$escname"/>
<xsl:variable name="reflist">
<xsl:for-each select="//CODE">
<xsl:variable name="refnumber" select="@number"/>
<xsl:if test="descendant::USE[@NAME=$thisname]">
<xsl:text> </xsl:text>
<xsl:value-of select="$refnumber"/>
</xsl:if>
</xsl:for-each>
</xsl:variable>
<lit2tex: display code chunk definition list 4.40>
<lit2tex: display code chunk reference list 4.41>
<xsl:text>\par\endgroup
</xsl:text>
</xsl:template>
<xsl:template match="actual">
<xsl:text>\end</xsl:text>
<!-- vitally important that these two text fragments be separate! -->
<xsl:text>{codeverbatim}\kern4pt</xsl:text>
<xsl:text>{\it </xsl:text>
<xsl:value-of select="@name"/>
<xsl:text>}</xsl:text>
<xsl:text>\begin</xsl:text>
<!-- vitally important that these two text fragments be separate! -->
<xsl:text>{codeverbatim}</xsl:text>
</xsl:template>
<lit2tex: display code chunk definition list 4.40> =<xsl:if test="count(//CODE[@name=$thisname])>1">
<xsl:text>{\it Macro defined in chunk </xsl:text>
<xsl:for-each select="//CODE[@name=$thisname]">
<xsl:variable name="refnumber" select="@number"/>
<xsl:if test="position()>1">
<xsl:text>\discretionary{,}{}{,}\hskip0pt plus 0.2pt</xsl:text>
</xsl:if>
<xsl:value-of select="$refnumber"/>
</xsl:for-each>
<xsl:text>}
</xsl:text>
<xsl:if test="$
reflist!=''">
<xsl:text>\hfil\break
</xsl:text>
</xsl:if>
</xsl:if>
<lit2tex: display code chunk reference list 4.41> =<xsl:if test="$
reflist!=''">
<xsl:text>{\it Macro referenced in chunk </xsl:text>
<xsl:for-each select="//CODE/descendant::USE[@NAME=$thisname]">
<xsl:variable name="refnumber" select="ancestor::CODE/@number"/>
<xsl:if test="position()>1">
<xsl:text>,\hskip 0pt plus 0.2pt </xsl:text>
</xsl:if>
<xsl:value-of select="$refnumber"/>
</xsl:for-each>
<xsl:text>}
</xsl:text>
</xsl:if>
If the variable reflist is not empty, display the
list of chunk numbers for each of the chunk names in the
list. Only unique numbers need be displayed, hence the
nested if statement within the //CODE for-each,
rather than another for-each which would itemize repeated
uses.
4.2.7 lit2tex: handle code use calls
<lit2tex: handle code use calls 4.42> =<xsl:template match="CODE/USE">
<xsl:text>\end</xsl:text>
<!-- vitally important that these two text fragments be separate! -->
<xsl:text>{codeverbatim}$<${\it </xsl:text>
<xsl:variable name="myname" select="@NAME"/>
<xsl:variable name="include" select="@INCLUDE"/>
<xsl:value-of select="@NAME"/>
<xsl:text> </xsl:text>
<xsl:for-each select="//CODE[@name=$myname]">
<xsl:if test="position()>1"><xsl:text>,</xsl:text></xsl:if>
<xsl:value-of select="@number"/>
<xsl:if test="$include='no'">
<xsl:text> {\bf Chunk omitted!}</xsl:text>
</xsl:if>
</xsl:for-each>
<xsl:text>}$>$</xsl:text>
<xsl:if test="actual">
<xsl:for-each select="actual">
<xsl:if test="position()=1">
<xsl:text> </xsl:text>
</xsl:if>
<xsl:value-of select="./@name"/>
<xsl:text>=</xsl:text>
<xsl:text>`\begin{codeverbatim}</xsl:text>
<xsl:apply-templates/>
<xsl:text>\end</xsl:text>
<xsl:text>{codeverbatim}\kern4pt'</xsl:text>
<xsl:if test="position()<last()">
<xsl:text>, </xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:if>
<xsl:text>\begin{codeverbatim}</xsl:text>
</xsl:template>
<xsl:template match="USE">
<xsl:variable name="myname" select="@NAME"/>
<xsl:choose>
<xsl:when test="@EXPAND">
<xsl:value-of select="//CODE[@name=$myname]"/>
</xsl:when>
<xsl:otherwise>
<xsl:element name="I">
<xsl:element name="A">
<xsl:attribute name="HREF">#<xsl:value-of select="@NAME"/>
</xsl:attribute>
<xsl:text disable-outputescaping="yes">$<${\it </xsl:text>
<xsl:value-of select="@NAME"/>
<xsl:text disable-outputescaping="yes"> </xsl:text>
<xsl:for-each select="//CODE[@name=$myname]">
<xsl:if test="position()>1"><xsl:text>,</xsl:text></xsl:if>
<xsl:value-of select="@number"/>
</xsl:for-each>
<xsl:text disable-outputescaping="yes">\/}$>$</xsl:text>
</xsl:element>
</xsl:element>
<xsl:if test="@INCLUDE='no'">
<xsl:element name="SPAN">
<xsl:attribute name="STYLE">color:red</xsl:attribute>
<xsl:text> **** Chunk omitted!</xsl:text>
</xsl:element>
</xsl:if>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
4.2.8 lit2tex: handle macro parameters
<lit2tex: handle macro parameters 4.43> =<xsl:template match="formal">
<xsl:text> \end</xsl:text>
<!-- vitally important that these two text fragments be separate! -->
<xsl:text>{codeverbatim}{\bf </xsl:text>
<xsl:value-of select="@name"/>
<xsl:text>}</xsl:text>
<xsl:text>\begin{codeverbatim}</xsl:text>
</xsl:template>
The space before the end verbatim seems to be required, as
the end verbatim seems to consume the blank immediately
before it. Don't know why.
4.2.9 lit2tex: handle variable definitions and uses
<lit2tex: handle variable definitions and uses 4.44> =<xsl:template match="VAR">
<xsl:choose>
<xsl:when test="@VAR='def'">
<xsl:element name="A">
<xsl:attribute name="NAME">
<xsl:choose>
<xsl:when test="@NAME">
<xsl:value-of select="@NAME"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<xsl:attribute name="STYLE">color:red</xsl:attribute>
<xsl:apply-templates/>
</xsl:element>
</xsl:when>
<xsl:when test="@VAR='use'">
<xsl:element name="A">
<xsl:attribute name="HREF">
<xsl:text>#</xsl:text>
<xsl:value-of select="."/>
</xsl:attribute>
<xsl:apply-templates/>
</xsl:element>
</xsl:when>
</xsl:choose>
</xsl:template>
4.2.10 lit2tex: handle in-line comments in code
<lit2tex: handle in-line comments in code 4.45> = <xsl:template match="COMMENT">
<xsl:text>\end</xsl:text>
<xsl:text>{codeverbatim}\kern4pt$^{</xsl:text>
<xsl:value-of select="@HREF"/>
<xsl:text>}$</xsl:text>
<xsl:text>\begin</xsl:text>
<xsl:text>{codeverbatim}</xsl:text>
</xsl:template>
<xsl:template match="NOTES">
<xsl:text>
</xsl:text>
<xsl:text>Notes:\par\begin</xsl:text>
<xsl:text>{enumerate}
</xsl:text>
<xsl:apply-templates>
</xsl:apply-templates>
<xsl:text>\end</xsl:text>
<xsl:text>{enumerate}</xsl:text>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="NOTE">
<xsl:text>\item </xsl:text>
<xsl:apply-templates/>
<xsl:text>
</xsl:text>
</xsl:template>
4.2.11 lit2tex: handle maintenance table documentation
<lit2tex: handle maintenance table documentation 4.46> =<xsl:template match="maintaintable">
<xsl:text>\halign{\tabskip=1em plus 1em minus 0.5em#</xsl:text>
<xsl:text>\hfil&#\hfil&#\hfil&</xsl:text>
<xsl:text>\vtop{\hsize=100mm#\strut\hfil}\hfil\cr </xsl:text>
<xsl:apply-templates select="./*"/>
<xsl:text>\crcr}</xsl:text>
</xsl:template>
<xsl:template match="maintaintable/date">
<xsl:text disable-output-escaping="yes"></xsl:text>
<xsl:apply-templates/>
<xsl:text>&</xsl:text>
</xsl:template>
<xsl:template match="maintaintable/author">
<xsl:apply-templates/>
<xsl:text>&</xsl:text>
</xsl:template>
<xsl:template match="maintaintable/version">
<xsl:apply-templates/>
<xsl:text>&</xsl:text>
</xsl:template>
<xsl:template match="maintaintable/comment">
<xsl:apply-templates/>
<xsl:text>\cr
</xsl:text>
</xsl:template>
4.2.12 lit2tex: build table of contents
<lit2tex: build table of contents 4.47> =<xsl:template match="TableOfContents">
<xsl:text>\heading{Table of Contents}
</xsl:text>
<xsl:text>\halign to \hsize{\tabskip=1em#\hfil&#\hfil&</xsl:text>
<xsl:text>#\hfil&#\hfil\tabskip=1em plus 1fil&\hfil#</xsl:text>
<xsl:text>\tabskip0pt\cr
</xsl:text>
<xsl:for-each select="//section">
<lit2tex: build toc: section 4.48>
<xsl:for-each select="subsection">
<lit2tex: build toc: subsection 4.49>
<xsl:for-each select="subsubsection">
<lit2tex: build toc: subsubsections 4.50>
</xsl:for-each>
</xsl:for-each>
</xsl:for-each>
<xsl:text>}
</xsl:text>
</xsl:template>
The table of contents is constructed using an halign
macro, set to the page width, and indenting each section
heading according to the depth of the heading. The last
template is right justified, and carries the page number for
the start of the section (actually, the heading of the
section). We define the table template, then enter loops to
process headings at each level with a (nested) loop. Close
the table of contents with a closing brace and a newline.
<lit2tex: build toc: section 4.48> =<xsl:number select="position(.)"/>
<xsl:text>&\multispan{3}</xsl:text>
<xsl:value-of select="normalize-space(title)"/>
<xsl:text>\hfil&\page{</xsl:text>
<xsl:value-of select="@xref"/>
<xsl:text>}\cr
</xsl:text>
Construct a (one-level) section number, no indent, format
with the title text and a page reference using the sanitised
xref title text
<lit2tex: build toc: subsection 4.49> =<xsl:text>&</xsl:text>
<xsl:number level="single" count="section"/>
<xsl:text>.</xsl:text>
<xsl:number from="section" level="single" count="subsection"/>
<xsl:text>&\multispan{2}</xsl:text>
<xsl:value-of select="normalize-space(title)"/>
<xsl:text>\hfil&\page{</xsl:text>
<xsl:value-of select="@xref"/>
<xsl:text>}\cr
</xsl:text>
Construct a two-level section number, indent it once,
format with the title text and a page reference using the
sanitised xref title text
<lit2tex: build toc: subsubsections 4.50> =<xsl:text>&&</xsl:text>
<xsl:number level="single" count="section"/>
<xsl:text>.</xsl:text>
<xsl:number from="section" level="single" count="subsection"/>
<xsl:text>.</xsl:text>
<xsl:number from="subsection" level="single" count="subsubsection"/>
<xsl:text>&</xsl:text>
<xsl:value-of select="normalize-space(title)"/>
<xsl:text>&\page{</xsl:text>
<xsl:value-of select="@xref"/>
<xsl:text>}\cr
</xsl:text>
Construct a three-level section number, indent it twice,
format with the title text and a page reference using the
sanitised xref title text
4.2.13 lit2tex: build file list
The file list macro builds a fairly simple TeX table of
file identifiers, together with a list of the chunk numbers
in which they are defined. Once the table parameters are
setup, scan through all CODE elements looking for file
definitions with unique file names. Escape underline
characters from these names. Then generate a list of all
chunk numbers defining this file. Note the need to keep the
unescaped file name $thisname distinct from the
escaped file name $escname.
<lit2tex: build file list 4.51> =<xsl:template match="filelist">
<xsl:text>\halign{\tabskip=1em#\hfil&#\hfil\cr
</xsl:text>
<xsl:text>\bf File Name</xsl:text>
<xsl:text>&</xsl:text>
<xsl:text>\bf Defined in</xsl:text>
<xsl:text>\cr </xsl:text>
<xsl:for-each select="//CODE">
<xsl:sort select="@name"/>
<xsl:variable name="thisname" select="@name"/>
<xsl:variable name="prevname" select="preceding::CODE[1]/@name"/>
<xsl:if test="(not($prevname) or $thisname!=$prevname) and @type='file'">
<xsl:variable name="escname">
<xsl:call-template name="replacesubstring">
<xsl:with-param name="string" select="$thisname"/>
<xsl:with-param name="pattern">
<xsl:value-of select="'_'"/>
</xsl:with-param>
<xsl:with-param name="replacement">
<xsl:value-of select="'\_'"/>
</xsl:with-param>
</xsl:call-template>
</xsl:variable>
<xsl:value-of select="$escname"/>
<xsl:text> & </xsl:text>
<xsl:for-each select="//CODE[@name=$thisname]">
<xsl:if test="position()>1">
<xsl:text>, </xsl:text>
</xsl:if>
<xsl:value-of select="@number"/>
</xsl:for-each>
<xsl:text>\cr
</xsl:text>
</xsl:if>
</xsl:for-each>
<xsl:text>}</xsl:text>
</xsl:template>
4.2.14 lit2tex: build identifier list
<lit2tex: build identifier list 4.52> =<xsl:template match="IdentifierDefinitions">
<lit2tex: build macrolist width variables 4.54>
<lit2tex: define macrolist table template 4.55>
<xsl:for-each select="//VAR[@VAR='def']">
<xsl:sort select="."/>
<xsl:variable name="name" select="."/>
<xsl:element name="TR">
<xsl:element name="TD">
<xsl:value-of select="."/>
</xsl:element>
<xsl:text> & </xsl:text>
<xsl:element name="TD">
<xsl:attribute name="ALIGN">center</xsl:attribute>
<xsl:element name="A">
<xsl:attribute name="HREF">
<xsl:text>#xlp:</xsl:text>
<xsl:value-of select="ancestor::CODE/@number"/>
</xsl:attribute>
<xsl:value-of select="ancestor::CODE/@number"/>
</xsl:element>
</xsl:element>
<xsl:text> & </xsl:text>
<xsl:element name="TD">
<xsl:attribute name="ALIGN">right</xsl:attribute>
<xsl:for-each select="//CODE/VAR[@VAR='use' and string()=$name]">
<xsl:if test="position()>1">
<xsl:text>, </xsl:text>
</xsl:if>
<xsl:element name="A">
<xsl:attribute name="HREF">
<xsl:text>#xlp:</xsl:text>
<xsl:value-of select="ancestor::CODE/@number"/>
</xsl:attribute>
<xsl:value-of select="ancestor::CODE/@number"/>
</xsl:element>
</xsl:for-each>
</xsl:element>
<xsl:text>\cr </xsl:text>
</xsl:element>
</xsl:for-each>
<xsl:text>}</xsl:text>
</xsl:template>
4.2.15 lit2tex: handle chunk definition list
The challenge in tabulating a list of chunk definitions is
in handling the variable widths of the fields, given that
some of them may require multiple lines to fit within the
page boundaries. This really requires a two pass algorithm,
of greater complexity than we can afford here.
Consequently, we settle for some manually determined widths,
which can be overridden if necessary. The default widths
are 50\% for the chunk name, and 25\% for each
of the definition and use lists.
Scan through all CODE elements to find the
definitions, and build these into a table of identifiers,
showing both the point of definitions, and all uses of the
identifier.
<lit2tex: handle chunk definition list 4.53> =<xsl:template match="macrolist">
<lit2tex: build macrolist width variables 4.54>
<lit2tex: define macrolist table template 4.55>
<xsl:for-each select="//CODE">
<xsl:sort select="./@name"/>
<xsl:variable name="thispos" select="position()"/>
<xsl:variable name="thisname" select="./@name"/>
<xsl:variable name="prevname">
<xsl:choose>
<xsl:when test="preceding::CODE[1]/@name">
<xsl:value-of select="preceding::CODE[1]/@name"/>
</xsl:when>
<xsl:otherwise> </xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:if test="$thisname!=$prevname and @type='define'">
<xsl:value-of select="./@name"/>
<xsl:text> & </xsl:text>
<xsl:for-each select="//CODE[@name=$thisname]">
<xsl:if test="position()>1">
<xsl:text>, </xsl:text>
</xsl:if>
<xsl:value-of select="./@number"/>
</xsl:for-each>
<xsl:text> & </xsl:text>
<xsl:for-each select="//CODE/USE[@NAME=$thisname]">
<xsl:variable name="thisnum" select="ancestor::CODE/@number"/>
<!-- calc of prevnum is wrong ! -->
<xsl:variable name="prevnum" select="preceding::./@number"/>
<xsl:if test="position()>1">
<xsl:text>, </xsl:text>
</xsl:if>
<xsl:value-of select="$thisnum"/>
</xsl:for-each>
<xsl:text>\cr
</xsl:text>
</xsl:if>
</xsl:for-each>
<xsl:text>}</xsl:text>
</xsl:template>
We define three variables to store the widths of the three
chunk name list columns: chunk name, chunk definitions, and
chunk uses. These values are either defined by the user
with attributes to the macrolist element, or are set
by default to the values 0.50, 0.25, 0.25 respectively.
<lit2tex: build macrolist width variables 4.54> =<xsl:variable name="namewidth">
<xsl:choose>
<xsl:when test="@namewidth">
<xsl:value-of select="@namewidth"/>
</xsl:when>
<xsl:otherwise><xsl:text>0.50</xsl:text></xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="definewidth">
<xsl:choose>
<xsl:when test="@definewidth">
<xsl:value-of select="@definewidth"/>
</xsl:when>
<xsl:otherwise><xsl:text>0.25</xsl:text></xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="usewidth">
<xsl:choose>
<xsl:when test="@usewidth">
<xsl:value-of select="@usewidth"/>
</xsl:when>
<xsl:otherwise><xsl:text>0.25</xsl:text></xsl:otherwise>
</xsl:choose>
</xsl:variable>
This next bit is really messy, basically because of the
horrendous TeX code being produced. This is what gets
produced by this bit of code for the macrolist reference in
this program itself (see later).
\halign{\tabskip=0em\advance\hsize by -1em
\vtop{\hsize=0.60\hsize#\hfil}\hskip0.5em&
\vtop{\hsize=0.20\hsize#\hfil}\hskip0.5em&
\vtop{\hsize=0.20\hsize#\hfil}\cr
\bf Identifier&\bf Defined in&\bf Used in\cr
Each of the table columns gets a width that can be set in
the original XML call on macrolist via the optional
attributes namewidth, definewidth and
usewidth. Each of these parameters should be a
fraction of 1.0, defining the fractional width of the page
taken up by that column, and their sum should be <=1.0
<lit2tex: define macrolist table template 4.55> =<xsl:text>\overfullrule=0pt
</xsl:text>
<xsl:text>\halign{\tabskip=0em\advance\hsize by -1em
</xsl:text>
<xsl:text>\vtop{\hsize=</xsl:text>
<xsl:value-of select="$namewidth"/>
<xsl:text>\hsize#\hfil}\hskip0.5em</xsl:text>
<xsl:text disable-output-escaping="yes">&
</xsl:text>
<xsl:text>\vtop{\hsize=</xsl:text>
<xsl:value-of select="$definewidth"/>
<xsl:text>\hsize#\hfil}\hskip0.5em</xsl:text>
<xsl:text disable-output-escaping="yes">&
</xsl:text>
<xsl:text>\vtop{\hsize=</xsl:text>
<xsl:value-of select="$usewidth"/>
<xsl:text>\hsize#\hfil}\cr
</xsl:text>
<xsl:text>\bf Identifier</xsl:text>
<xsl:text>&</xsl:text>
<xsl:text>\bf Defined in</xsl:text>
<xsl:text>&</xsl:text>
<xsl:text>\bf Used in</xsl:text>
<xsl:text>\cr
</xsl:text>
4.2.16 lit2tex: handle document history
Generate a table to capture the document history.
<lit2tex: handle document history 4.56> =<xsl:template match="DocumentHistory">
<lit2tex: define Document History variables 4.57>
<xsl:text>\heading{Document History}</xsl:text>
<xsl:text>\halign{\tabskip=0pt\advance\hsize by -1.5em
</xsl:text>
<xsl:text>\vtop{\hsize=</xsl:text>
<xsl:value-of select="$datewidth"/>
<xsl:text>\hsize#\hfil}\hskip0.5em</xsl:text>
<xsl:text disable-output-escaping="yes">&</xsl:text>
<xsl:text>\vtop{\hsize=</xsl:text>
<xsl:value-of select="$authorwidth"/>
<xsl:text>\hsize#\hfil}\hskip0.5em</xsl:text>
<xsl:text disable-output-escaping="yes">&</xsl:text>
<xsl:text>\vtop{\hsize=</xsl:text>
<xsl:value-of select="$versionwidth"/>
<xsl:text>\hsize#\hfil}\hskip0.5em</xsl:text>
<xsl:text disable-output-escaping="yes">&</xsl:text>
<xsl:text>\vtop{\hsize=</xsl:text>
<xsl:value-of select="$commentwidth"/>
<xsl:text>\hsize#\hfil}\cr
</xsl:text>
<xsl:text>\bf Date</xsl:text>
<xsl:text>&</xsl:text>
<xsl:text>\bf Author</xsl:text>
<xsl:text>&</xsl:text>
<xsl:text>\bf Version</xsl:text>
<xsl:text>&</xsl:text>
<xsl:text>\bf Comment</xsl:text>
<xsl:text>\cr
</xsl:text>
<xsl:apply-templates select="Modified"/>
<xsl:text>}</xsl:text>
<xsl:apply-templates select="*[name()!='Modified']"/>
</xsl:template>
<xsl:template match="DocumentHistory/Modified">
<xsl:apply-templates/>
<xsl:text disable-output-escaping="no">\cr</xsl:text>
</xsl:template>
<xsl:template match="Modified/date">
<xsl:apply-templates/>
<xsl:text>&</xsl:text>
</xsl:template>
<xsl:template match="Modified/version">
<xsl:apply-templates/>
<xsl:text>&</xsl:text>
</xsl:template>
<xsl:template match="Modified/author">
<xsl:apply-templates/>
<xsl:text>&</xsl:text>
</xsl:template>
<xsl:template match="Modified/comment">
<xsl:apply-templates/>
</xsl:template>
Define the various column width parameters for the
Document History table. Each of these is set to a default
value, unless there is an explicit attribute setting, when
they are set instead to the value passed in the attribute.
<lit2tex: define Document History variables 4.57> =<xsl:variable name="datewidth">
<xsl:choose>
<xsl:when test="@datewidth">
<xsl:value-of select="@datewidth"/>
</xsl:when>
<xsl:otherwise><xsl:text>0.17</xsl:text></xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="authorwidth">
<xsl:choose>
<xsl:when test="@authorwidth">
<xsl:value-of select="@authorwidth"/>
</xsl:when>
<xsl:otherwise><xsl:text>0.10</xsl:text></xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="versionwidth">
<xsl:choose>
<xsl:when test="@versionwidth">
<xsl:value-of select="@versionwidth"/>
</xsl:when>
<xsl:otherwise><xsl:text>0.09</xsl:text></xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="commentwidth">
<xsl:choose>
<xsl:when test="@commentwidth">
<xsl:value-of select="@commentwidth"/>
</xsl:when>
<xsl:otherwise><xsl:text>0.64</xsl:text></xsl:otherwise>
</xsl:choose>
</xsl:variable>
4.2.17 lit2tex: text node handling
<lit2tex: text node handling 4.58> =
These templates handle text nodes in the TeX weft
phase. The callable template replacesubstring is
used in a couple of the templates.
4.2.17.1 lit2tex: callable template replacesubstring
<lit2tex: callable template replacesubstring 4.59> =<xsl:template name="
replacesubstring">
<xsl:param name="string"></xsl:param>
<xsl:param name="pattern"></xsl:param>
<xsl:param name="replacement"></xsl:param>
<xsl:choose>
<xsl:when test="contains($string,$pattern)">
<xsl:value-of select="substring-before($string,$pattern)"/>
<xsl:value-of select="$replacement"/>
<xsl:call-template name="replacesubstring">
<xsl:with-param name="string">
<xsl:value-of select="substring-after($string,$pattern)"/>
</xsl:with-param>
<xsl:with-param name="pattern">
<xsl:value-of select="$pattern"/>
</xsl:with-param>
<xsl:with-param name="replacement">
<xsl:value-of select="$replacement"/>
</xsl:with-param>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$string"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
This callable template takes a string, and returns a new
string with substrings replaced consistently.
4.2.17.2 lit2tex: replace dollar signs with escaped dollar signs
<lit2tex: replace dollar signs with escaped dollar signs 4.60> =<xsl:template match="c//text()">
<xsl:call-template name="replacesubstring">
<xsl:with-param name="string" select="."/>
<xsl:with-param name="pattern">
<xsl:value-of select="'$'"/>
</xsl:with-param>
<xsl:with-param name="replacement">
<xsl:value-of select="'\$'"/>
</xsl:with-param>
</xsl:call-template>
</xsl:template>
A straightforward replace of any dollar sign by their
escaped versions in TeX. These otherwise would start
mathematics mode.
4.2.17.3 lit2tex: filter at signs in text nodes
This template sanitises code text to double up any at
signs. This is a hangover from the C version of the
litprog, and will be removed at a future date. The
offending code is the TeX routine \verb"codeverbatim" in file
"almostverb".
<lit2tex: filter at signs in text nodes 4.61> =<xsl:template match="CODE//text()">
<xsl:call-template name="replacesubstring">
<xsl:with-param name="string" select="."/>
<xsl:with-param name="pattern">
<xsl:value-of select="'@'"/>
</xsl:with-param>
<xsl:with-param name="replacement">
<xsl:value-of select="'@@'"/>
</xsl:with-param>
</xsl:call-template>
</xsl:template>
4.2.17.4 lit2tex: filter underlines in non-verbatim text nodes
We need to make sure that text in text nodes gets
appropriate markup from the TeX point of view. Particular
cases are underscores and dollar signs. Munge through all
text nodes to replace these with their sanitised text
equivalents.
The exceptions are where the text occurs in various
verbatim modes. The XPath expression in the match filters
out these exceptions.
<lit2tex: filter underlines in non-verbatim text nodes 4.62> =<xsl:template match="//*[name()!='verb' and name()!='CODE'
and name()!='c']/text()">
<xsl:call-template name="replacesubstring">
<xsl:with-param name="string" select="."/>
<xsl:with-param name="pattern">
<xsl:value-of select="'_'"/>
</xsl:with-param>
<xsl:with-param name="replacement">
<xsl:value-of select="'\_'"/>
</xsl:with-param>
</xsl:call-template>
</xsl:template>
The following template filters text nodes to replace
underlines with their TeX escaped equivalents. Note that
the filtering is NOT applied when the containing node is a
verb or CODE node, as these contexts have their own
verbatim quoting mechanisms.
4.2.18 lit2tex: special character templates
Define here all the special characters that cannot be
represented exactly (either because there is no
corresponding glyph, or because they require escaping in
TeX
<lit2tex: special character templates 4.63> =<xsl:template match="le">
<xsl:text>\ifmmode\le\else$\le$\fi</xsl:text>
</xsl:template>
<xsl:template match="dollar">
<xsl:text>\$</xsl:text>
</xsl:template>
<xsl:template match="TeX">
<xsl:text>{\TeX}</xsl:text>
</xsl:template>
<xsl:template match="htmlonly">
<xsl:text>{\bf HTML only source omitted!}</xsl:text>
</xsl:template>
4.2.19 lit2tex: default template
<lit2tex: default template 4.64> =<xsl:template match="*">
<xsl:if test="$Verbose">
<xsl:message terminate="no">
<xsl:text>No weft-tex template for </xsl:text>
<xsl:value-of select="name()"/>
</xsl:message>
</xsl:if>
<xsl:element name="{name()}">
<xsl:apply-templates mode="tangle"/>
</xsl:element>
</xsl:template>
A catch-all for any undefined templates. Issue a warning
message and pass the element through unchanged.
5. weft: Common weft fragments
<weft: handle the root element 5.1> =<xsl:template match="/">
weft root pre text
<xsl:apply-templates/>
weft root post text
</xsl:template>
6. The litprog Document Type Definition
"litprog.dtd" 6.1 =
- {Note 6.1.1}
- The text parameter entity defines the standard
element choices that go into the various documentation
chunks. Add any extra document element choices in here, and
they will be automatically distributed into all doco fragments.
- {Note 6.1.2}
- The misc parameter entity defines the miscellaneous
element choices that go into the various documentation
chunks. These elements are usually only specified once per
document, but there is no restriction on them being specified
more often.
6.1 litprog.dtd: Literate Programming elements
<litprog.dtd: Literate Programming elements 6.2> =<!ELEMENT o (#PCDATA|u|v|com)*>
<!ATTLIST o file CDATA #REQUIRED>
<!ELEMENT d (#PCDATA|u|v|com|formal)*>
<!ATTLIST d name CDATA #REQUIRED>
<!ELEMENT u (actual*)>
<!ATTLIST u name CDATA #REQUIRED>
<!ATTLIST u expand CDATA #IMPLIED>
<!ELEMENT v (#PCDATA)>
<!ATTLIST v var (def|use) "use">
<!ELEMENT formal (#PCDATA)>
<!ATTLIST formal name CDATA #REQUIRED>
<!ELEMENT actual (#PCDATA|%text;)*>
<!ATTLIST actual name CDATA #REQUIRED>
<!ELEMENT com (#PCDATA|%text;)*>
- o
-
o elements are file definitions. The file
attribute defines the name of the file.
- d
-
d elements are code chunk definitions. The
name attribute defines the name of the code chunk, by
which it can be referenced in u elements
- u
-
u elements are uses of code chunks. They are
normally empty elements, and may appear in either o
or d elements, or in documentation. In tangling, they
are replaced by the expanded form of the reference code
chunk. In weaving, they are replaced by links to the
referenced code definition. If a weave mode u element
is accompanied by the attribute expand, which is
non-empty, it is replaced by its expanded form.
- v
-
v elements are variable instances. The variable
name forms the element content. If accompanied by the
attribute var set to def, the instance is
taken to be a defining instance, otherwise if the var
attribute is set to use, or does not appear, the
instance is regarded as a use of the variable.
- com
-
com elements are comments. They may be used
within code or file chunks to annotate the code. Depending
upon the context, these comments may be marked-up into the
documentation.
6.2 litprog.dtd: Bibliographic elements
<litprog.dtd: Bibliographic elements 6.3> =<!ELEMENT bibliography (bib)*>
<!ELEMENT bib (author,
title,
((journal,year,volume?,number?,pages)|
(publisher,year,ISBN?)|
uri)
)*>
<!ATTLIST bib idref ID #REQUIRED>
<!ELEMENT volume (#PCDATA|%text;)*>
<!ELEMENT number (#PCDATA|%text;)*>
<!ELEMENT pages (#PCDATA|%text;)*>
6.3 litprog.dtd: Heading and Sectioning elements
<litprog.dtd: Heading and Sectioning elements 6.4> =<!ELEMENT title (#PCDATA|nl)*>
<!ELEMENT subtitle (#PCDATA|nl)*>
<!ELEMENT author (#PCDATA|%text;)*>
<!ELEMENT version (#PCDATA|%text;)*>
<!ATTLIST version id NMTOKEN "1.0"
delete (yes|no) "no"
date CDATA #IMPLIED>
<!ELEMENT date (#PCDATA|%text;)*>
<!ELEMENT abstract (#PCDATA|%text;)*>
<!ELEMENT section (title,(%text;|%misc;|subsection)*)>
<!ATTLIST section numbers CDATA #IMPLIED>
<!ELEMENT subsection (title,(%text;|%misc;|subsubsection)*)>
<!ELEMENT subsubsection (title,(%text;|%misc;|subsubsubsection)*)>
<!ELEMENT subsubsubsection (title,(%text;|%misc;)*)>
6.4 litprog.dtd: Miscellaneous elements
<litprog.dtd: Miscellaneous elements 6.5> =<!ELEMENT TableOfContents EMPTY>
<!ELEMENT filelist EMPTY>
<!ELEMENT macrolist EMPTY>
<!ELEMENT identifierlist EMPTY>
6.5 litprog.dtd: table elements
<litprog.dtd: table elements 6.6> =<!ELEMENT table (tr|LabGroup)*>
<!ATTLIST table border CDATA #IMPLIED
align (left|center) #IMPLIED>
<!ELEMENT tr (td|th)*>
<!ELEMENT td (#PCDATA|%text;)*>
<!ATTLIST td width CDATA #IMPLIED
align CDATA #IMPLIED>
<!ELEMENT th (#PCDATA|%text;)*>
6.6 litprog.dtd: uri elements
<litprog.dtd: uri elements 6.7> =<!ELEMENT uri (#PCDATA)>
<!ATTLIST uri href CDATA #IMPLIED
foot CDATA #IMPLIED
alt CDATA #IMPLIED>
6.7 litprog.dtd: DocumentHistory elements
<litprog.dtd: DocumentHistory elements 6.8> =<!ELEMENT DocumentHistory (Modified*)>
<!ELEMENT Modified (date,author,version,comment)>
<!ELEMENT comment (#PCDATA|%text;)*>
6.8 litprog.dtd: Entities
<litprog.dtd: Entities 6.9> =<!ENTITY lt "<">
<!ENTITY ltt "$<$"> <!-- less than, TeX -->
<!ENTITY gt ">">
<!ENTITY gtt ">"> <!-- greater than, TeX -->
<!ENTITY at "@">
<!ENTITY amp "&;">
<!ENTITY ampt "\&"> <!-- ampersand, TeX -->
<!ENTITY dollar "\$"> <!-- dollar, TeX -->
<!ENTITY ldq "'">
<!ENTITY percent "\%"> <!-- percent, TeX -->
<!ENTITY euro "E">
<!ENTITY verbar "|"> <!-- vertical bar -->
7. The LitprogXML Document Type Definition
"LitprogXML.dtd" 7.1 =<!ELEMENT LitprogXML (title,author,version,date,section*,DocumentHistory?)>
8. File Index
File Name |
Defined in |
LitprogXML.dtd |
7.1 |
lit2html.xsl |
4.1 |
lit2tex.xsl |
4.33 |
litprog.dtd |
6.1 |
litprog.xsl |
3.1 |
9. Macro Index
Chunk Name |
Defined in |
Used in |
current date |
11.2 |
|
current version |
11.1 |
|
lit2html: TableOfContents |
4.24 |
4.1 |
lit2html: body contains new line characters |
4.17 |
4.15 |
lit2html: body contains several children |
4.16 |
|
lit2html: build code chunk definition list |
4.20 |
4.14 |
lit2html: build code chunk reference list |
4.18 |
4.14 |
lit2html: construct chunk definition list |
4.27 |
4.1 |
lit2html: construct file definition list |
4.26 |
4.1 |
lit2html: construct identifier definition list |
4.28 |
4.1 |
lit2html: default template |
4.32 |
4.1 |
lit2html: display code chunk reference list |
4.19 |
4.14 |
lit2html: format the code body |
4.15 |
4.14 |
lit2html: handle a code fragment use |
4.13 |
4.1 |
lit2html: handle a code text element |
4.25 |
4.1 |
lit2html: handle code chunk definitions |
4.14 |
4.1 |
lit2html: handle code fragment references |
4.11, 4.12
|
4.1 |
lit2html: handle document history |
4.30 |
4.1 |
lit2html: handle documentation fragments |
4.4, 4.5, 4.6, 4.7, 4.8, 4.9, 4.10
|
4.1 |
lit2html: handle macro parameters |
4.29 |
4.1 |
lit2html: handle maintaintable |
4.23 |
4.1 |
lit2html: handle notes and comments in code fragments |
4.21 |
4.1 |
lit2html: handle the literate program translation |
4.3 |
4.1 |
lit2html: handle the root element |
4.2 |
4.1 |
lit2html: handle variable definitions and uses |
4.22 |
4.1 |
lit2html: special character templates |
4.31 |
4.1 |
lit2tex: build file list |
4.51 |
4.33 |
lit2tex: build identifier list |
4.52 |
4.33 |
lit2tex: build macrolist width variables |
4.54 |
4.52, 4.53
|
lit2tex: build table of contents |
4.47 |
4.33 |
lit2tex: build toc: section |
4.48 |
4.47 |
lit2tex: build toc: subsection |
4.49 |
4.47 |
lit2tex: build toc: subsubsections |
4.50 |
4.47 |
lit2tex: callable template replacesubstring |
4.59 |
4.58 |
lit2tex: default template |
4.64 |
4.33 |
lit2tex: define Document History variables |
4.57 |
4.56 |
lit2tex: define macrolist table template |
4.55 |
4.52, 4.53
|
lit2tex: display code chunk definition list |
4.40 |
4.39 |
lit2tex: display code chunk reference list |
4.41 |
4.39 |
lit2tex: filter at signs in text nodes |
4.61 |
4.58 |
lit2tex: filter underlines in non-verbatim text nodes |
4.62 |
4.58 |
lit2tex: handle a literate program translation |
4.36 |
4.33 |
lit2tex: handle chunk definition list |
4.53 |
4.33 |
lit2tex: handle code fragment definitions |
4.39 |
4.33 |
lit2tex: handle code use calls |
4.42 |
4.33 |
lit2tex: handle document history |
4.56 |
4.33 |
lit2tex: handle in-line comments in code |
4.45 |
4.33 |
lit2tex: handle macro parameters |
4.43 |
4.33 |
lit2tex: handle maintenance table documentation |
4.46 |
4.33 |
lit2tex: handle paragraphs |
4.37 |
4.33 |
lit2tex: handle reference calls |
4.38 |
4.33 |
lit2tex: handle the root node |
4.34 |
4.33 |
lit2tex: handle variable definitions and uses |
4.44 |
4.33 |
lit2tex: handle various documentation elements |
4.35 |
4.33 |
lit2tex: replace dollar signs with escaped dollar signs |
4.60 |
4.58 |
lit2tex: special character templates |
4.63 |
4.33 |
lit2tex: text node handling |
4.58 |
4.33 |
litprog.dtd: Bibliographic elements |
6.3 |
6.1 |
litprog.dtd: DocumentHistory elements |
6.8 |
6.1 |
litprog.dtd: Entities |
6.9 |
6.1 |
litprog.dtd: Heading and Sectioning elements |
6.4 |
6.1 |
litprog.dtd: Literate Programming elements |
6.2 |
6.1 |
litprog.dtd: Miscellaneous elements |
6.5 |
6.1 |
litprog.dtd: table elements |
6.6 |
6.1 |
litprog.dtd: uri elements |
6.7 |
6.1 |
litprog: check definitions for non-use |
3.30 |
3.25 |
litprog: check whether to include a use chunk |
3.27 |
3.25 |
litprog: compute indentations for use expansion |
3.29 |
3.25 |
litprog: count-trailing-blanks template |
3.7 |
3.5 |
litprog: d-weave debug message-1 |
3.42 |
3.41 |
litprog: d/com|o/com-weave template |
3.44 |
3.39 |
litprog: default tangle template |
3.38 |
3.15 |
litprog: default weave template |
3.52 |
3.39 |
litprog: define documentation template name list |
1.2 |
3.3 |
litprog: define procedure templates |
3.5 |
3.1 |
litprog: define script parameters |
3.4 |
3.1 |
litprog: define variables |
3.3 |
3.1 |
litprog: discard documentation in tangle mode |
3.24 |
3.15 |
litprog: do-replace template |
3.6 |
3.5 |
litprog: include raw text and expand indentation |
3.31 |
3.25 |
litprog: include text and expand: define parmtable |
3.34 |
3.31 |
litprog: include text and expand: define raw2 |
3.36 |
3.31 |
litprog: include text and expand: define rawchunk |
3.35 |
3.31 |
litprog: include text and expand: loop message |
3.33 |
3.31 |
litprog: include text and expand: replace text |
3.37 |
3.31 |
litprog: include text and expand: start message |
3.32 |
3.31 |
litprog: listing templates |
3.51 |
3.39 |
litprog: lookup template |
3.11 |
3.5 |
litprog: lookupchunkno template |
3.8, 3.9
|
3.5 |
litprog: lookupchunknoR debug message 1 |
3.10 |
3.9 |
litprog: p-weave template |
3.49 |
3.39 |
litprog: replace the machine parameter in chunk name |
3.26 |
3.25 |
litprog: root template |
3.2 |
3.1 |
litprog: save use parameters |
3.28 |
3.25 |
litprog: section-weave template |
3.50 |
3.39 |
litprog: substparms template |
3.12 |
3.5 |
litprog: tangle a code definition |
3.18 |
3.15 |
litprog: tangle a single file definition chunk |
3.17 |
3.15 |
litprog: tangle all chunks into a single use |
3.25 |
3.15 |
litprog: tangle all litprog files |
3.16 |
3.15 |
litprog: tangle variable declarations |
3.23 |
3.15 |
litprog: the tangle pass |
3.15 |
3.1 |
litprog: the weave pass |
3.39 |
3.1 |
litprog: u-weave template |
3.47, 3.48
|
3.39 |
litprog: weave a code comment |
3.43 |
3.41 |
litprog: weave a code or file definition |
3.41 |
3.39 |
litprog: weave a litprog |
3.40 |
3.39 |
litprog: weave a variable markup |
3.45, 3.46
|
3.39 |
substparms: build result string recursively |
3.14 |
3.12 |
substparms: unescape the escaped formal parameters |
3.13 |
3.12 |
tangle code, debugging |
3.22 |
3.18 |
tangle code, end trimmed chunk |
3.20 |
3.18 |
tangle code, initial chunk |
3.19 |
3.18 |
tangle code, start and end trimmed chunk |
3.21 |
3.18 |
weft: handle the root element |
5.1 |
4.2, 4.34
|
10. Identifier Index
Document History
20050115:172716 |
ajh |
2.0 |
first literate version of release 2 |
20050121:143117 |
ajh |
2.0.1 |
revised grammar of output .xml file to embrace NOTEs
with a NOTES element. This facilitates processing at phase
2 |
20050705:170139 |
ajh |
2.0.2 |
refined lit2html.xsl to better format short code
chunks. Changed v element within documentation to be
n, to avoid clash with variable markup elements, also
named v
|
20050708:155431 |
ajh |
2.0.3 |
fixed macrolist and identifierlist
templates in litprog.xsl. Significant formatting and
re-chunking of file. |
20050711:102903 |
ajh |
2.0.4 |
working over lit2tex.xsl and
codeverbatim
|
20050712:151429 |
ajh |
2.1.0 |
further "literacising", and removed the
n element from XML intermediate file. |
20050715:130910 |
ajh |
2.1.1 |
Recovery from the schemozzle caused by trying to
upgrade to Tiger on ballarat |
20050722:121800 |
ajh |
2.1.2 |
Further work on the user manual |
20050725:164813 |
ajh |
2.1.3 |
Refinement of the dtd |
20050728:141654 |
ajh |
2.1.4 |
Revised and extended User Manual, revised cross
referencing linkages |
20050913:143424 |
ajh |
2.1.5 |
Updated TeX weft: reformat code and file chunks to give
more accurate presentation of starting and ending line breaks.
Also added non-CODE USE handling. |
20050915:165408 |
ajh |
2.1.6 |
Various minor bug fixes; added width control to
macrolist and Document History. |
20051012:153812 |
ajh |
2.2.0 |
Added macro parameters to code chunks. Currently only
litprog and lit2hml handle these. |
20051014:105557 |
ajh |
2.2.1 |
Added macro parameter handling to lit2tex. |
20061014:133445 |
ajh |
2.3.0 |
start on separate parts structure |
20061027:083327 |
ajh |
2.3.1 |
refined macro parameters |
20070509:184652 |
ajh |
2.3.2 |
finally got round to fixing macro parameters, by
separating into formals and actuals. Extended this to the
TeX phase as well |
20070524:145633 |
ajh |
2.3.3 |
fix logic bug in recursive macro expansion |
20080528:095515 |
ajh |
2.3.4 |
moved list of templates that are passed through without
comment to be common to both tangle and weave in
litprog.xsl. Added 'parm' to that list. |
20080822:162322 |
ajh |
2.4.0 |
fixed bug in multiple chunk output files |
<current version 11.1> = 2.4.0
<current date 11.2> = 20080822:162322