summaryrefslogtreecommitdiff
path: root/support/ltx2x/ltx2x.html
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/ltx2x/ltx2x.html
Initial commit
Diffstat (limited to 'support/ltx2x/ltx2x.html')
-rw-r--r--support/ltx2x/ltx2x.html8107
1 files changed, 8107 insertions, 0 deletions
diff --git a/support/ltx2x/ltx2x.html b/support/ltx2x/ltx2x.html
new file mode 100644
index 0000000000..cd87b79c50
--- /dev/null
+++ b/support/ltx2x/ltx2x.html
@@ -0,0 +1,8107 @@
+
+
+
+
+
+
+
+
+
+
+
+
+<html>
+<head>
+<title>LaTeX to X translator</title>
+</head>
+<body>
+(This document was automatically generated from LaTeX source by the ltx2x program.)
+<a name="HtMlSoD"></a><a href="#HtMlEoD">To the end</a>
+
+
+
+
+
+
+<p>
+
+
+<h1 align=center>
+ <i>LTX2X:</i> A LaTeX to X Auto-tagger
+</h1>
+<h3 align=center>
+Peter R. Wilson <br>
+ Catholic University of America<br><font size=-1>(This work was performed
+while a Guest Researcher at the National Institute of Standards and
+Technology)</font><br> <br>
+ Email: <tt>pwilson@cme.nist.gov</tt>
+</h3>
+<h3 align=center>
+January 1997
+</h3>
+
+
+
+<p><h4>Abstract</h4>
+<blockquote>
+
+ LTX2X is a table-driven program that will replace LaTeX commands
+by user defined text. This report describes the beta version of the system.
+LTX2X supports both a declaritive command style and an interpreted
+procedural language tentatively called EXPRESS-A.
+Details are given of the program functionality including examples.
+System installation instructions are provided.
+</blockquote>
+
+
+
+<p>
+
+
+
+<p>
+
+
+
+<p>
+<h2>Introduction</h2>
+ <a name="sec:introduction"></a>
+
+
+<p>LaTeX [<a href="#LAMPORT94">LAMPORT94</a>], which is built on top of TeX [<a href="#KNUTH84a">KNUTH84a</a>],
+is a document tagging system
+that is very popular in the academic and scientific publishing communities
+because of the high quality typeset material that the system outputs
+for normal text and especially for mathematics.
+
+
+<p>In particular, many of the documents forming the
+International Standard ISO 10303, commonly referred to as STEP [<a href="#STEPIS">STEPIS</a>],
+have been written using LaTeX as
+the document tagging language. Lately there have been moves towards converting
+the STEP documents to embody SGML [<a href="#GOLDFARB90">GOLDFARB90</a>]
+rather than LaTeX markup. This has led
+to an interest in the automatic conversion from LaTeX to SGML
+documents.
+The LTX2X system is an initial attempt to provide a generic capability for
+converting LaTeX tags into other kinds of tags.
+
+
+<p>The LTX2X system described below is in a beta release state. That is, there
+is probably some more work to be done on it but experience from use is
+needed to determine desirable additional functionality. However, the code
+has been stable for some time.
+Bug reports or suggested
+enhancements (especially if the suggestions are accompanied by working code)
+are encouraged, as are constructive comments about this document.
+
+
+<p>Essentially, LTX2X reads a file containing LaTeX markup,
+replaces the LaTeX commands by user-defined text, and writes the result
+out to another file. The program operates from a command table that specifies
+the replacement text. In general, no programming knowledge or skills are
+required to write a command table, which LTX2X will then interpret.
+Some knowledge of LaTeX is required, but no more than is necessary
+for authoring a LaTeX document.
+
+
+<p>LTX2X has proved capable of performing such functions as:
+<ul>
+
+
+ <li> Conversion of documents marked up according to a specific LaTeX
+ documentclass to documents tagged according to a specific SGML DTD.
+
+ <li> Removal of LaTeX commands to produce deTeXed source.
+
+ <li> Conversion of simple LaTeX documents to
+ HTML [<a href="#MUSCIANO96">MUSCIANO96</a>] tagged documents for publication on the
+ World Wide Web.
+</ul>
+
+
+
+<p>The remainder of this introduction gives an overview of the LTX2X program.
+The command table is described in more detail in section <a href="#sec:command-table">sec:command-table</a>
+and information on running the LTX2X program is provided in
+section <a href="#sec:program">sec:program</a>. Section <a href="#sec:expressa">sec:expressa</a> gives an
+overview
+of the EXPRESS-A language. (Footnote: The overview is necessarily
+rather brief as I am shortly moving to a new place of employment and
+EXPRESS-A is the latest addition to the system.)
+Although the functionality available through the command table facility is
+suitable for many tasks, especially since an interpreter for the EXPRESS-A
+general programming language is included within LTX2X,
+section <a href="#sec:special">sec:special</a> gives details on how the system can
+be extended for cases where this proves to be inadequate.
+
+
+<p>The report ends with several appendices. An example command table for
+deTeXing a document is reproduced in <a href="#sec:detexing">sec:detexing</a> and some of
+the issues in converting from LaTeX to HTML are discussed
+in <a href="#sec:htmling">sec:htmling</a>. The known limitations
+of LTX2X are listed in <a href="#sec:limitations">sec:limitations</a> and a summary of the command
+table facilities are given in <a href="#sec:summary">sec:summary</a>. Appendix <a href="#sec:install">sec:install</a>
+provides instructions on installing the LTX2X program, together with copyright
+and warranty information. Finally, <a href="#sec:ctabgrammar">sec:ctabgrammar</a> and <a href="#sec:expgrammar">sec:expgrammar</a>provide grammars for the command table and EXPRESS-A, respectively.
+
+
+<p>
+<h3>Overview</h3>
+
+
+
+<p>The intent of Leslie Lamport, the author of LaTeX, was to provide a document
+tagging system that enabled the capture of the logical structure of a document.
+This system uses Donald Knuth's TeX system as its typesetting engine [<a href="#KNUTH84a">KNUTH84a</a>],
+and thus has an inherent capability for high quality typesetting.
+
+
+<p>All LaTeX commands are distinguished by starting with a backslash (<samp>\</samp>).
+Generally speaking, the name of a command is a string of alphabetic characters
+(e.g. <samp>\acommand</samp>). Commands may take arguments. Required arguments are
+enclosed in curly braces (i.e. <samp>{</samp> and <samp>}</samp>). Optional arguments
+are enclosed in square brackets (i.e. <samp>[</samp> and <samp>]</samp>). The general syntax
+for a command is the command name (preceded by a backslash) followed by the
+argument list with a maximum (Footnote: Under very unusual
+circumstances this limit may be exceeded.) of nine arguments.
+
+
+<p>The LTX2X program reads a LaTeX document file and outputs a
+transformation of this file. By default it outputs the normal text
+while for each LaTeX command and argument performs some
+user-specified actions; typically these actions involve the output
+of specific text corresponding to the particular command.
+The actions are specified in a <em>command table</em> file, written by the user,
+which is read into the LTX2X system before document processing is
+begun. A command table consists of a listing of the LaTeX commands of interest
+together with the desired actiond for each of these commands and their
+arguments.
+Different effects may be easily obtained by changing the command table
+file. For example, a simple command table file may be written that will delete
+all the LaTeX commands from a document, resulting in a plain ASCII file
+with no embedded markup. (Footnote: To afficionados,
+this process is known as de-TeX ing.)
+A more complex command table may be written that will replace LaTeX tags
+with appropriate SGML tags.
+
+
+<p>In some circles it is traditional to introduce a programming
+language by providing an example program that prints `Hello world'.
+In contrast, the following command table file called <tt>bye.ct</tt>,
+when used in conjunction
+with a typical vanilla LaTeX file, will transform the LaTeX file
+to a file that consists only of the words `Goodbye document'.
+
+
+<p><pre>
+C= bye.ct "Goodbye document" for ltx2x
+
+TYPE= COMMAND
+NAME= \documentclass
+ START_TAG= "Goodbye document"
+ PC_AT_END= NO_PRINT
+END_TYPE
+
+C= just in case a LaTeX v2.09 document
+TYPE= COMMAND
+NAME= \documentstyle
+ START_TAG= "Goodbye document"
+ PC_AT_END= NO_PRINT
+END_TYPE
+
+C= just in case there is no \documentclass/style command
+TYPE= BEGIN_DOCUMENT
+ START_TAG= "Goodbye document"
+ PC_AT_END= NO_PRINT
+END_TYPE
+
+TYPE= OTHER_COMMAND
+ PRINT_CONTROL= NO_PRINT
+END_TYPE
+
+TYPE= OTHER_BEGIN
+ PRINT_CONTROL= NO_PRINT
+END_TYPE
+
+TYPE= OTHER_END
+ PRINT_CONTROL= NO_PRINT
+END_TYPE
+
+END_CTFILE= end of bye.ct
+</pre>
+
+<p>Essentially the command table instructs LTX2X what to print for each LaTeX
+command. A command table file consists of a series of commands, one per line
+and introduced by a keyword such as <samp>TYPE=</samp>. Keywords are case
+insensitive but by convention are written in upper case. Comments in
+a command table are introduced by the keyword <samp>C=</samp>.
+
+
+<p>The main body of a command table consists of the specification of
+LaTeX commands of interest and the actions to be taken for these.
+Each specification commences with the keyword <samp>TYPE=</samp> and is
+completed by the keyword <samp>END_TYPE</samp>, the relevant actions
+being listed between these two keywords.
+
+
+<p>LTX2X treats some LaTeX commands specially; among these are
+<samp>\begin{document}</samp> and <samp>\end{document}</samp>. In a command table
+these are specified by the types <samp>TYPE= BEGIN_DOCUMENT</samp> and
+<samp>TYPE= END_DOCUMENT</samp>. The actions at
+<samp>\begin{document}</samp> are firstly to print the string `Goodbye document'
+(specified in the line <samp>START_TAG= "Goodbye document"</samp>) and
+secondly to stop printing any output (specified in the line
+<samp>PC_AT_END= NO_PRINT</samp>).
+
+
+<p>By not specifying the <samp>END_DOCUMENT</samp> entry, the default
+action is used for the <samp>\end{document}</samp> command.
+
+
+<p>The command table entries for the commands <samp>\documentclass</samp> and
+<samp>\documentstyle</samp> specify that, if either of these is in the
+source document, then it is to be replaced by the text string
+<samp>"Goodbye document"</samp>, and then all further printing is to
+be switched off.
+
+
+<p>The other three entries in the command table specify the actions for any
+other kind of LaTeX command. The keyword <samp>OTHER_BEGIN</samp>
+signifies a LaTeX command of the form <samp>\begin{name}</samp> and
+<samp>OTHER_END</samp> signifies a command of the form <samp>\end{name}</samp>.
+The keyword <samp>OTHER_COMMAND</samp> signifies any other kind of
+LaTeX command (e.g., <samp>\acommand ... </samp>). The actions declared
+for these are all <samp>PRINT_CONTROL= NO_PRINT</samp> which shuts off
+any printing of the command or its arguments. In the command table <tt>bye.ct</tt>
+these are only included to prevent printing before the
+<samp>\begin{document}</samp>.
+
+
+<p>To run LTX2X with the above command table, type the following (where <samp>></samp>
+is assumed to be the system prompt):
+<pre>
+> ltx2x -f bye.ct input.tex output.tex
+</pre>
+where <tt>bye.ct</tt> is the name of the command table, and
+<tt>input.tex</tt> and <tt>output.tex</tt> are the names of the input LaTeX
+file and the resulting processed file respectively.
+
+
+<p>
+ As an example of a more useful command table file, the following one called
+<tt>decomm.ct</tt> will remove all LaTeX comments from a typical
+LaTeX source file.
+
+
+<p><pre>
+C= decomm.ct Command table file for ltx2x to de-comment LaTeX source
+
+C= ------------------------------------ set newline characters
+ESCAPE_CHAR= ?
+NEWLINE_CHAR= N
+
+C= ----------------------------------- built in commands
+TYPE= BEGIN_DOCUMENT
+ START_TAG= "\begin{document}"
+END_TYPE
+
+TYPE= END_DOCUMENT
+ START_TAG= "\end{document}"
+END_TYPE
+
+TYPE= BEGIN_VERB
+ START_TAG= "\verb|"
+END_TYPE
+
+TYPE= END_VERB
+ START_TAG= "|"
+END_TYPE
+
+TYPE= BEGIN_VERBATIM
+ START_TAG= "\begin{verbatim}"
+END_TYPE
+</pre>
+<samp>TYPE= END_VERBATIM</samp> <br>
+<samp> START_TAG= "\end{verbatim}"</samp> <br>
+<samp>END_TYPE</samp>
+<pre>
+TYPE= LBRACE
+ START_TAG= "{"
+END_TYPE
+
+TYPE= RBRACE
+ START_TAG= "}"
+END_TYPE
+
+TYPE= PARAGRAPH
+ START_TAG= "?N?N "
+END_TYPE
+
+C= ------------------- define '\item' tags within lists
+
+TYPE= BEGIN_LIST_ENV
+NAME= itemize
+ START_TAG= "\begin{itemize}"
+ START_ITEM= "\item "
+END_TYPE
+
+TYPE= BEGIN_LIST_ENV
+NAME= enumerate
+ START_TAG= "\begin{enumerate}"
+ START_ITEM= "\item "
+END_TYPE
+
+TYPE= BEGIN_LIST_ENV
+NAME= description
+ START_TAG= "\begin{description}"
+ START_ITEM= "\item"
+ START_ITEM_PARAM= "["
+ END_ITEM_PARAM= "] "
+END_TYPE
+
+TYPE= END_LIST_ENV
+ NAME= itemize
+END_TYPE
+
+TYPE= END_LIST_ENV
+ NAME= enumerate
+END_TYPE
+
+TYPE= END_LIST_ENV
+ NAME= description
+END_TYPE
+
+C= --------------------- pass through all other LaTeX commands
+
+TYPE= OTHER_COMMAND
+END_TYPE
+
+TYPE= OTHER_BEGIN
+END_TYPE
+
+TYPE= OTHER_END
+END_TYPE
+
+END_CTFILE= end of file decomm.ct
+</pre>
+In the above command table file, the first pair of commands (<samp>ESCAPE_CHAR=</samp>
+and <samp>NEWLINE_CHAR=</samp>) define the character pair that are to be used to
+signify a `newline' within a tag. An example of their use is later in the
+file in the <samp>PARAGRAPH</samp> command type.
+
+
+<p>As indicated above, LTX2X treats some LaTeX commands specially.
+These are listed next in the
+command table. The special LaTeX commands are the begin and end of the
+<samp>document</samp> and <samp>verbatim</samp>
+environments, together with the <samp>\verb</samp> command, left and right braces,
+the <samp>\ </samp> command, and the LTX2X <samp>PARAGRAPH</samp> specification.
+There are default actions for these, but apart from the <samp>\ </samp> command
+the defaults are not appropriate in this case.
+Above, the actions are to replace the
+LaTeX command by the string forming the LaTeX command. The exception
+is that paragraphs (the <samp>PARAGRAPH</samp> specification) should start
+with at least one blank line and be indented some spaces.
+
+
+<p>The LaTeX <samp>\item</samp> command is used within lists. LTX2X has to be
+told how to treat the <samp>\item</samp> command within each kind of list. This
+has been done above for the <samp>itemize</samp>, <samp>enumerate</samp> and
+<samp>description</samp> environments.
+
+
+<p>The final instructions in the command table file tell LTX2X to pass through the
+text of all other commands and their arguments. The end of the command table file
+is either the physical end of the file or the command <samp>END_CTFILE=</samp>,
+whichever comes first. The <samp>END_CTFILE=</samp> command acts like the
+<samp>C=</samp> command in that arbitrary text can be put after the command.
+
+
+<p>To use the <tt>decomm.ct</tt> command table to de-comment a LaTeX file, type
+the following (where <samp>></samp> is assumed to be the system prompt):
+<pre>
+> ltx2x -f decomm.ct input.tex output.tex
+</pre>
+where <tt>input.tex</tt> and <tt>output.tex</tt> are the names of the input LaTeX
+file for de-commenting and the resulting de-commented version respectively.
+
+
+<p>
+<h2>The command table file</h2>
+ <a name="sec:command-table"></a>
+
+
+<p>By default, LTX2X does not output any LaTeX comments.
+Otherwise, whenever it comes
+across a LaTeX command it looks at the data in the command table file to determine
+what actions it should take. The two most typical actions are either
+to print out the command as read in, or to replace the command by some (possibly
+empty) text.
+
+
+<p>Each line in a command table file is either blank or starts with a keyword followed
+by one or more blanks. For
+example, a comment in the file is a line that starts with <samp>C= </samp>;
+the remainder of the line is any comment text. Comments may be placed anywhere
+in the file.
+
+
+<p>
+
+<h3>Special print characters in tags</h3>
+
+
+
+<p>LTX2X is written in C [<a href="#KERNIGHAN88">KERNIGHAN88</a>].
+The C language enables certain non-printing characters
+to be defined. These are typically written in the form <samp>\c</samp> where <samp>\</samp>
+is the C escape character and <samp>c</samp>
+is a particular character. LTX2X understands some of these special printing
+characters and the command table enables these to be given non-default values.
+
+
+<p>The default escape character (<samp>\</samp>) may be redefined via the
+<samp>ESCAPE_CHAR=</samp> command. For example,
+<pre>
+ESCAPE_CHAR= ?
+</pre>
+will make the question mark character the escape character. Typically, the escape
+character is changed in most command table s to avoid clashing with the LaTeX <samp>\</samp>
+character.
+The following commands
+can be used to redefine the C special characters. Each of these commands takes
+a single character as its value. If a relevant command is not given, then the
+default value is used.
+<dl>
+<dt><samp>NEWLINE_CHAR=</samp>
+<dd> a new line (default is <samp>n</samp>) <br>
+<dt><samp>HORIZONTAL_TAB_CHAR=</samp>
+<dd> horizontal tab (default is <samp>t</samp>) <br>
+<dt><samp>VERTICAL_TAB_CHAR=</samp>
+<dd> vertical tab (default is <samp>v</samp>) <br>
+<dt><samp>BACKSPACE_CHAR=</samp>
+<dd> backspace (default is <samp>b</samp>) <br>
+<dt><samp>CARRIAGE_RETURN_CHAR=</samp>
+<dd> carriage return (default is <samp>r</samp>) <br>
+<dt><samp>FORMFEED_CHAR=</samp>
+<dd> formfeed (default is <samp>f</samp>) <br>
+<dt><samp>AUDIBLE_ALLERT_CHAR=</samp>
+<dd> beep the terminal (default is <samp>a</samp>) <br>
+<dt><samp>HEX_CHAR=</samp>
+<dd> following characters form the hexadecimal number of
+ the character
+ to be printed (default is <samp>x</samp>) (e.g. <samp>?xA3</samp>) <br>
+</dl>
+ These command lines are all optional within a command table and their ordering is
+immaterial. However, if any are present then they must be at the beginning of
+the command table.
+
+
+<p>The above special characters are useful when specifying the replacement text
+for LaTeX commands.
+
+
+<p>
+
+<h3>LaTeX command types</h3>
+
+
+
+<p>The commands for controlling the actions performed on LaTeX commands
+are enclosed between the command lines <samp>TYPE= </samp> and <samp>END_TYPE</samp>,
+as below.
+<pre>
+TYPE= CommandType
+ C= a possibly empty set of commands
+END_TYPE
+</pre>
+where <samp>CommandType</samp> is an LTX2X keyword signifying the kind of LaTeX
+command being specified.
+
+
+<p>
+<h4>Built in command types</h4>
+
+
+<p>Some LaTeX commands are pre-defined within LTX2X. Default actions
+are provided for these but it is recommended that type specifications
+for each of these commands be put in the command table anyway. The keywords for
+these commands are:
+<dl>
+<dt><samp>BEGIN_DOCUMENT</samp>
+<dd> Corresponds to the LaTeX command
+ <samp>\begin{document}</samp>.
+<dt><samp>END_DOCUMENT</samp>
+<dd> Corresponds to the LaTeX command
+ <samp>\end{document}</samp>.
+<dt><samp>BEGIN_VERBATIM</samp>
+<dd> Corresponds to the LaTeX commands
+ <samp>\begin{verbatim}</samp> and <br>
+ <samp>\begin{verbatim*}</samp>.
+<dt><samp>END_VERBATIM</samp>
+<dd> Corresponds to the LaTeX commands
+ <samp>\end{verbatim}</samp> and <samp>\end{verbatim*}</samp>.
+<dt><samp>BEGIN_VERB</samp>
+<dd> Corresponds to the LaTeX commands
+ <samp>\verb</samp> and <samp>\verb*</samp>, together with the succeeding character.
+<dt><samp>END_VERB</samp>
+<dd> Corresponds to the appearance of the character
+ that completes the LaTeX commands
+ <samp>\verb</samp> and <samp>\verb*</samp>.
+<dt><samp>LBRACE</samp>
+<dd> Corresponds to the LaTeX left brace character
+ <samp>{</samp>.
+<dt><samp>RBRACE</samp>
+<dd> Corresponds to the LaTeX right brace character
+ <samp>}</samp>.
+<dt><samp>BEGIN_DOLLAR</samp>
+<dd> Corresponds to the LaTeX <samp>$</samp> symbol signalling the
+ start of an in-text math formula.
+<dt><samp>END_DOLLAR</samp>
+<dd> Corresponds to the LaTeX <samp>$</samp> symbol signalling the
+ end of an in-text math formula.
+<dt><samp>PARAGRAPH</samp>
+<dd> Corresponds to the LaTeX protocol of a blank
+ line signalling the start/end of a paragraph.
+<dt><samp>SLASH_SPACE</samp>
+<dd> Corresponds to the LaTeX <samp>\ </samp> command.
+<dt><samp>OTHER_COMMAND</samp>
+<dd> Corresponds to any LaTeX command of the form
+ <samp>\command</samp> not specified elsewhere within the command table.
+<dt><samp>OTHER_BEGIN</samp>
+<dd> Corresponds to any LaTeX command of the form
+ <samp>\begin{environment}</samp> not specified elsewhere within the command table.
+<dt><samp>OTHER_END</samp>
+<dd> Corresponds to any LaTeX command of the form
+ <samp>\end{environment}</samp> not specified elsewhere within the command table.
+</dl>
+
+
+<p>
+ The ordering of these built in type specifications is immaterial. If
+any of the above are not specified within the command table then LTX2X will use
+their default action.
+ With the exception of the <samp>SLASH_SPACE</samp> command type, the
+default action is to do nothing (i.e., produce no output).
+The default action for the <samp>SLASH_SPACE</samp>
+command type is to output a space.
+
+
+<p>
+<h4>Optional command types</h4>
+
+
+<p>For the purposes of LTX2X, LaTeX commands are divided into various classes.
+The keywords for these clases, and the class descriptions, are listed below.
+
+
+<p><dl>
+<dt><samp>TEX_CHAR</samp>
+<dd> Corresponding to LaTeX's special characters (with the exception
+ of the $, { and } characters).
+<dt><samp>CHAR_COMMAND</samp>
+<dd> Corresponding to LaTeX commands of the type
+ <samp>\c</samp> where <samp>c</samp> is a single non-alphabetic character.
+<dt><samp>COMMAND</samp>
+<dd> Corresponding to LaTeX commands of the type
+ <samp>\command</samp>, where <samp>command</samp> is the name of the command (except for
+ <samp>\begin</samp>, <samp>\end</samp> and <samp>\item</samp>).
+<dt><samp>BEGIN_ENV</samp>
+<dd> Corresponding to LaTeX commands of the type
+ <samp>\begin{environment}</samp> where <samp>environment</samp> is the name of the
+ environment, except for those list environments whose bodies
+ consist of <samp>\item</samp> commands.
+<dt><samp>END_ENV</samp>
+<dd> Corresponding to LaTeX commands of the type
+ <samp>\end{environment}</samp>, with the same restrictions as for <samp>BEGIN_ENV</samp>.
+<dt><samp>BEGIN_LIST_ENV</samp>
+<dd> Corresponding to LaTeX commands of the type
+ <samp>\begin{environment}</samp> where <samp>environment</samp> is the name of an
+ environment whose body consists of <samp>\item</samp> commands.
+<dt><samp>END_LIST_ENV</samp>
+<dd> Corresponding to LaTeX commands of the type
+ <samp>\end{environment}</samp> to match <samp>BEGIN_LIST_ENV</samp>.
+<dt><samp>VCOMMAND</samp>
+<dd> Corresponding to a LaTeX <samp>\verb</samp>-like command.
+<dt><samp>BEGIN_VENV</samp>
+<dd> Corresponding to the start of a verbatim-like
+ environment.
+<dt><samp>END_VENV</samp>
+<dd> Corresponding to the end of a verbatim-like
+ environment.
+<dt><samp>SECTIONING</samp>
+<dd> Corresponding to LaTeX commands of the type
+ <samp>\command</samp>, where <samp>command</samp> is a document sectioning command
+ such as <samp>chapter</samp> or <samp>subsection</samp>.
+<dt><samp>SPECIAL</samp>
+<dd> Reserved for possible future use.
+<dt><samp>SPECIAL_COMMAND</samp>
+<dd> Corresponding to the <samp>COMMAND</samp> keyword,
+ except that some special output processing is to be defined.
+<dt><samp>SPECIAL_BEGIN_ENV</samp>
+<dd> Corresponding to the <samp>BEGIN_ENV</samp> keyword,
+ except that some special output processing is to be defined.
+<dt><samp>SPECIAL_END_ENV</samp>
+<dd> Corresponding to the <samp>END_ENV</samp> keyword,
+ except that some special output processing is to be defined.
+<dt><samp>SPECIAL_BEGIN_LIST</samp>
+<dd> Corresponding to the <samp>BEGIN_LIST_ENV</samp>
+ keyword,
+ except that some special output processing is to be defined.
+<dt><samp>SPECIAL_END_LIST</samp>
+<dd> Corresponding to the <samp>END_LIST_ENV</samp> keyword,
+ except that some special output processing is to be defined.
+<dt><samp>SPECIAL_SECTIONING</samp>
+<dd> Corresponding to the <samp>SECTIONING</samp> keyword,
+ except that some special output processing is to be defined.
+<dt><samp>_PICTURE_</samp>
+<dd> Corresponding to some of the LaTeX picture
+ drawing commands.
+<dt><samp>COMMAND_...</samp>
+<dd> Corresponding to some of the LaTeX commands
+ whose arrangements of required and optional arguments are untypical.
+</dl>
+
+
+<p>The ordering of these types within a command table is immaterial.
+
+
+<p>Each of the above type specifications requires a <samp>NAME=</samp> command,
+whose value is the
+name of the relevant command or environment being specified. For example, the
+following is a (partial) specification of the figure environment and the caption
+command.
+
+
+<p><pre>
+TYPE= BEGIN_ENV
+NAME= figure
+END_TYPE
+
+TYPE= END_ENV
+NAME= figure
+END_TYPE
+
+TYPE= COMMAND
+NAME= \caption
+END_TYPE
+</pre>
+
+<p>
+<h3>Command action tags</h3>
+
+
+
+<p>When LTX2X reads a LaTeX command it performs the following actions:
+<ol>
+
+
+ <li> Looks up the name of the command or environment in the command table. If
+ it is not found, then the appropriate default type is used.
+
+ <li> Sets the printing mode according to the <samp>PC_AT_START=</samp>
+ command.
+
+ <li> Performs the actions specified in the command table by the
+ <samp>START_TAG=</samp> command.
+
+ <li> Processes any specified arguments to the command.
+
+ <li> Performs the actions specified in the command table by the <samp>END_TAG=</samp>
+ command.
+
+ <li> Sets the printing mode according to the <samp>PC_AT_END=</samp> command.
+</ol>
+
+
+
+<p><dl>
+<dt>NOTES
+<dd>:
+<ol>
+
+
+ <li> Except for the default processing of <samp>OTHER_</samp> types, it does not
+ output the command itself.
+
+ <li> If a tag action is not specified, then the default action is null (e.g.,
+ nothing will appear in the output).
+</ol>
+
+</dl>
+
+
+<p>Within a command table all text strings for output are enclosed within double
+quotes. For example:
+<pre>
+START_TAG= "Some "text" string\n another line of text."
+</pre>
+
+<p>Assuming that <samp>\n</samp> means a newline, when this string action is performed
+by LTX2X it will appear in the output file as:
+<pre>
+Some "text" string
+another line of text.
+</pre>
+
+<p>A text string starts with the first double quote and ends with the last double
+quote on the command line. A text string has to be written on a single line
+within the command table. C language special print characters can be embedded within the
+text string (e.g. the <samp>\n</samp> for a newline in the above example). Remember
+that the first section of the command table is used for specifying the
+particular command table version of these.
+
+
+<p>If a text string is too long to fit comfortably on a single line in the
+command table, it may be continued via the <samp>STRING:</samp> command. As many of these
+can be used in succession as required (subject to internal limitations within LTX2X).
+
+
+<p>For instance,
+<pre>
+START_TAG= "Some "text" string\n"
+ STRING: "another line of text."
+</pre>
+has the same effect as the previous example.
+
+
+<p>The following specification is designed to write out the contents of the
+<samp>\caption</samp> command (Footnote: Strictly speaking, the specification does not
+do this exactly, but this simplified illustration will be corrected in
+the next sections.) ,
+preceded by the word `CAPTION' and followed by at least one
+blank line (assuming that the escape character has been set to <samp>?</samp>).
+
+
+<p><pre>
+TYPE= COMMAND
+NAME= \caption
+ START_TAG= "?n CAPTION "
+ END_TAG= "?n?n"
+END_TYPE
+</pre>
+Assuming that somewhere in a LaTeX file there is the command
+<pre>
+stuff
+\caption{This is a caption.}
+more stuff
+</pre>
+then the expected effect (see footnote) is
+<pre>
+stuff
+
+ CAPTION This is a caption.
+
+more stuff
+</pre>
+
+<p>
+<h3>Argument actions</h3>
+
+
+
+<p>LaTeX commands can take arguments. The text for a required argument is
+enclosed in curly braces, while the text for an optional argument is enclosed
+in square brackets. LTX2X can be directed to perform actions at the start and end
+of each argument.
+
+
+<p>The number of required arguments is specified by the command line
+<samp>REQPARAMS=</samp>
+where the value of the command is a digit between 1 and 9 inclusive.
+
+
+<p>LTX2X assumes that a command can have only one optional argument, and that this
+is either first or last in the argument list. The potential presence of an
+optional argument is indicated by the command line <samp>OPT_PARAM=</samp>,
+where the
+value is either the keyword <samp>FIRST</samp> (for first in the list) or
+<samp>LAST</samp> (for last in the list).
+
+
+<p>The actions to be performed at the start and end of each required argument
+are specified via the commands <samp>START_TAG_1=</samp> and <samp>END_TAG_1=</samp>
+for the first required argument, through <samp>START_TAG_9=</samp> and
+<samp>END_TAG_9=</samp> for the ninth argument.
+The actions to be performed at the start and end of the optional argument
+are specified by the command lines <samp>START_OPT=</samp> and <samp>END_OPT=</samp>.
+
+
+<p>The argument delimiters (the braces or brackets) are not printed.
+
+
+<p>In the simplest case, the action is to print a specified text string
+(enclosed in double quotes, and continued with <samp>STRING:</samp> commands
+if necessary). Other kinds of actions are also possible.
+An unspecified tag defaults to doing no action.
+
+
+<p>
+<h4>Print options</h4>
+
+
+<p>
+<h5>Argument processing</h5>
+
+
+
+<p>By default, LTX2X processes (i.e. outputs as appropriate)
+the text of a argument.
+Printing of the argument text may be disabled, if required. The command line
+that controls argument printing is of the form <samp>PRINT_P1=</samp> through
+<samp>PRINT_P9=</samp> for required arguments and
+<samp>PRINT_OPT=</samp> for the optional
+argument. The value of these commands is one from several keywords,
+the most common being <samp>NO_PRINT</samp>; this
+switches off printing of the text of the indicated argument.
+Default printing is resumed after the indicated argument.
+
+
+<p>Continuing the caption example from earlier, we can now complete it. The full
+syntax of the LaTeX command is:
+<pre>
+\caption[optional table of contents entry]{Caption in the text}
+</pre>
+That is, it has one required argument, which prints the caption text both in
+the body of the document and in the table of contents, unless the first optional
+argument is present, in which case its value gets printed in the table of
+contents instead.
+
+
+<p>Assume that an instance of the caption command in a document is:
+<pre>
+Some stuff
+\caption[Short caption]{Long caption for the body of the text.}
+More stuff
+</pre>
+Recall the previous command table caption specification. The actual output from
+processing this would be
+<pre>
+Some stuff
+
+ CAPTION [Short caption]{Long caption for the body of the text.}
+
+More stuff
+</pre>
+because, unless LTX2X is told that there are command arguments and how they should
+be treated, it will just print them out together with their surrounding
+delimiters.
+
+
+<p>The following command table entry will give more acceptable results.
+<pre>
+TYPE= COMMAND
+NAME= \caption
+ START_TAG= "?n CAPTION "
+ END_TAG= "?n?n"
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+ REQPARAMS= 1
+END_TYPE
+</pre>
+
+<p>For the above captioning instance, the output will now be:
+<pre>
+Some stuff
+
+ CAPTION Long caption for the body of the text.
+
+More stuff
+</pre>
+
+<p>The default print mode is to print text to the output file.
+
+
+<p>The keywords that can be used to control argument printing are:
+<dl>
+<dt><samp>NO_PRINT</samp>
+<dd> Do not print anything.
+<dt><samp>TO_SYSBUF</samp>
+<dd> Print to the LTX2X system buffer.
+<dt><samp>TO_BUFFER num</samp>
+<dd> Print to the LTX2X buffer
+ number <samp>num</samp>.
+<dt><samp>TO_FILE name</samp>
+<dd> Print to the file called <samp>name</samp>.
+<dt><samp>NO_OP</samp>
+<dd> Skip all processing of the argument.
+</dl>
+Note that even if the print mode is set to <samp>NO_PRINT</samp>, the
+argument text will still be processed. Only the <samp>NO_OP</samp>
+specification temporarly turns off the processing.
+
+
+<p>
+
+<h5>General printing</h5>
+
+
+
+<p>Just as the printing mode can be set for each argument, it can also be
+set at the start and end of processing a LaTeX command or environment.
+
+
+<p>The specifications <samp>PC_AT_START=</samp> and <samp>PC_AT_END=</samp>
+can be used to set the printing mode at the start of processing a command
+and at the end, respectively. The keywords that can be used in these
+specifications are:
+<dl>
+<dt><samp>NO_PRINT</samp>
+<dd> Do not print anything.
+<dt><samp>TO_SYSBUF</samp>
+<dd> Print to the LTX2X system buffer.
+<dt><samp>TO_BUFFER num</samp>
+<dd> Print to the LTX2X buffer
+ number <samp>num</samp>.
+<dt><samp>TO_FILE name</samp>
+<dd> Print to the file called <samp>name</samp>.
+<dt><samp>RESET</samp>
+<dd> Reset the print mode back to what it was.
+</dl>
+
+
+<p>Unlike the argument printing controls, the print mode is not
+automatically reset. This has to be explicitly specified.
+
+
+<p>As an example, assume that it is required to remove all <samp>figure</samp>
+environments from a LaTeX source and put them into a file on their own.
+The following command table code could be used to accomplish this.
+<pre>
+TYPE= BEGIN_ENV
+NAME= figure
+ PC_AT_START= TO_FILE allfigs.tex
+ START_TAG= "?n\begin{figure}"
+END_TYPE
+
+TYPE= END_ENV
+NAME= figure
+ START_TAG= "\end{figure}"
+ PC_AT_END= RESET
+END_TYPE
+</pre>
+When a LaTeX <samp>figure</samp> environment is started, printing is switched
+to go to the file called <tt>allfigs.tex</tt>. At the end of the <samp>figure</samp>
+environment, the print mode is reset back to what it was before the environment
+began. If at the first <samp>figure</samp> environment the <tt>allfigs.tex</tt>
+file did not exist, then LTX2X would create it automatically.
+
+
+<p>
+<h5>Read actions</h5>
+
+
+
+<p>As noted above, one of the actions that can be specified for a
+LaTeX comand's argument is to set the print mode for printing to a buffer
+or a file. Similarly there are actions which will read from a buffer or
+a file and print the contents. Within an argument tag these kinds of actions are
+specified via the keyword <samp>SOURCE:</samp>. This can take one of several
+values:
+<dl>
+<dt><samp>SYSBUF</samp>
+<dd> Print the contents of the LTX2X system buffer.
+<dt><samp>BUFFER num</samp>
+<dd> Print the contents of the LTX2X buffer
+ number <samp>num</samp>.
+<dt><samp>FILE name</samp>
+<dd> Print the contents of the file called
+ <samp>name</samp>.
+</dl>
+
+
+<p>In a previous example, the LaTeX <samp>figure</samp> environments
+were all written to the file <tt>allfig.tex</tt>. This file could be read
+in again just before the end of the document so that all figures will be
+typeset after everything else.
+<pre>
+TYPE= END_DOCUMENT
+ END_TAG= "?n % figures collected here by LTX2X ?n"
+ SOURCE: FILE allfigs.tex
+ STRING: "?n\end{document}?n"
+END_TYPE
+</pre>
+
+<p>As another example of the use of the print actions consider the LaTeX
+<samp>\maketitle</samp> command. This typesets the arguments of the <samp>\title</samp>,
+<samp>\author</samp> and <samp>\date</samp> commands, which must have been previously
+specified but not necessarily in this ordering. Here is one way this can
+be simulated using LTX2X.
+<pre>
+TYPE= COMMAND
+NAME= \title
+ START_TAG=
+ RESET_BUFFER: 1
+ REQPARAMS= 1
+ PRINT_P1= TO_BUFFER 1
+END_TYPE
+
+TYPE= COMMAND
+NAME= \author
+ START_TAG=
+ RESET_BUFFER: 2
+ REQPARAMS= 1
+ PRINT_P1= TO_BUFFER 2
+END_TYPE
+
+TYPE= COMMAND
+NAME= \date
+ START_TAG=
+ RESET_BUFFER: 3
+ REQPARAMS= 1
+ PRINT_P1= TO_BUFFER 3
+END_TYPE
+
+TYPE= COMMAND
+NAME= \maketitle
+ START_TAG= "?n"
+ SOURCE: BUFFER 1
+ STRING: "?n?n"
+ SOURCE: BUFFER 2
+ STRING: "?n?n"
+ SOURCE: BUFFER 3
+ STRING: "?n?n"
+ END_TAG=
+ RESET_BUFFER: 1
+ RESET_BUFFER: 2
+ RESET_BUFFER: 3
+END_TYPE
+</pre>
+For the <samp>\title</samp> command, the print mode for its argument is set
+for printing to the buffer number 1. The single action at the start of
+the command is to make sure that buffer 1 is empty (the line
+<samp>RESET_BUFFER: 1</samp>). The actions for the <samp>\author</samp> and
+<samp>\date</samp> commands are similar, except that they print their argument
+texts to buffers 2 and 3 respectively.
+
+
+<p>The <samp>\maketitle</samp> command takes no arguments, so all actions
+must be placed under <samp>START_TAG=</samp> and/or <samp>END_TAG=</samp>.
+There are a set of actions specified for <samp>START_TAG=</samp>. Firstly
+a newline is printed and this is followed by the contents of buffer 1
+(i.e., the text of the argument of the <samp>\title</samp> command).
+Then two new lines are printed, followed by the contents of buffer 2
+(the author). Finally another two newlines are printed, the contents
+of buffer 3 (the date), and another two newlines. The actions
+for <samp>END_TAG=</samp> are to clear the contents of the three buffers.
+
+
+<p>Just to extend the example, here is a specification for the
+LaTeX <samp>\thanks</samp> command. LTX2X is not designed to do footnoting
+(as it does not do page breaking)
+so instead the thanks text will be placed inside parentheses on a new line.
+<pre>
+TYPE= COMMAND
+NAME= \thanks
+ START_TAG= "?n ("
+ REQPARAMS= 1
+ END_TAG= ") "
+END_TYPE
+</pre>
+
+<p>
+ Given these command table specification and the following portion of a
+LaTeX document
+<pre>
+\date{29 February 2000}
+\title{The Calculation of Leap Days\thanks{Originally published in JIR}}
+\author{A. N. Other}
+...
+\maketitle
+</pre>
+then output from LTX2X will be:
+<pre>
+The Calculation of Leap Days
+ (Originally published in JIR)
+
+A. N. Other
+
+29 February 2000
+</pre>
+Note that as the <samp>\thanks</samp> command appears within the argument of the
+<samp>\title</samp> command, it is written to the same place as the text of
+the argument of <samp>\title</samp>. Thus, it also gets written to the output file
+when <samp>\maketitle</samp> is processed.
+
+
+<p>
+<h4>Print switching</h4>
+
+
+<p>There are individual actions that enable the printing destination
+to be changed at will within the action set for any particular tag.
+<dl>
+<dt><samp>SWITCH_TO_BUFFER: num</samp>
+<dd> Direct any following printing
+ to the LTX2X buffer number <samp>num</samp>.
+<dt><samp>SWITCH_TO_FILE: name</samp>
+<dd> Direct any following printing
+ to the file called <samp>name</samp>.
+<dt><samp>SWITCH_TO_SYSBUF</samp>
+<dd> Direct any following printing
+ to the LTX2X system buffer.
+<dt><samp>SWITCH_BACK:</samp>
+<dd> Undo the effect of the last
+ <samp>SWITCH_TO...</samp> action.
+</dl>
+
+
+<p>As an example of the utility of this type of action, consider
+again the LaTeX <samp>\maketitle</samp> command. When LaTeX processes
+this command, it typesets the date as specified by the <samp>\date</samp>
+command, or if this has not been specified then it prints the current
+date instead. We can arrange for LTX2X to do something similar by
+adding the following to the command table shown earlier for the <samp>\date</samp>
+and <samp>\maketitle</samp> commands.
+<pre>
+TYPE= COMMAND
+NAME= \documentclass
+ OPT_PARAM= FIRST
+ REQPARAMS= 1
+ PRINT_OPT= NO_PRINT
+ PRINT_P1= NO_PRINT
+ START_TAG=
+ c= Initialise buffer 3 to `Today'
+ RESET_BUFFER: 3
+ SWITCH_TO_BUFFER: 3
+ STRING: "Today"
+ SWITCH_BACK:
+END_TYPE
+</pre>
+At the start of the document, the above actions put the string
+<samp>Today</samp> into <samp>BUFFER 3</samp>, having first ensured that it is
+empty. If the LaTeX source includes a <samp>\date</samp> command, then
+the contents of the buffer will be overwritten, otherwise it will be
+as initialised. In any event, when the <samp>\maketitle</samp> command is
+processed, the value output for the date will be either <samp>Today</samp>
+or whatever the argument was of the <samp>\date</samp> command.
+
+
+<p>
+<h4>Notes on the use of buffers and files</h4>
+
+
+<p>Resetting a buffer or a file always has the effect of emptying it
+of an prior contents.
+
+
+<p>When printing from a buffer or a file, the entire contents are
+printed. There is no limit to the number of times that a buffer
+or a file can be used as a printing source.
+
+
+<p>When printing to a buffer, the new strings are appended at
+the end of the current contents of the buffer, at least until it
+overflows. Unlike the behaviour of files,
+this is independant of any intervening prints from the buffer.
+
+
+<p>When printing to a file, the new strings are appended at the
+end of the current contents of the file. However, if a file is printed
+to after it has been printed from, the prior contents of the file
+are lost, and the new string is added at the start of the file.
+In general, it is safest to treat files as either read-only or write-only.
+
+
+<p>
+
+
+<h4>User specified modes</h4>
+
+
+<p>Consider the LaTeX command <samp>\\</samp>. In normal text this signifies
+that a line break must occur. In a <samp>tabular</samp> environment, though,
+it signifies the end of a row in a table. Suppose that in the LTX2X
+procesing of a tabular environment it is required to start and end each
+row with a vertical bar and to seperate each column also with a vertical
+bar. However, in normal text a <samp>\\</samp> command should just translate
+into a newline. Just to complicate matters further, assume that in
+an <samp>eqnarray</samp> environment, the <samp>&</samp> column seperator is to
+be translated to some spaces, and that the string `(X)' is to be
+put at the end of every row.
+
+
+<p>In other words, we need to process some commands differently
+according to where they appear in the LaTeX source. An LTX2X command table
+provides this capability through mode setting and mode-dependent actions.
+Here is an example of using this facility to solve the requirements
+outlined above.
+<pre>
+TYPE= BEGIN_ENV
+NAME= tabular
+ C= starting actions, etc., here
+ END_TAG=
+ SET_MODE: tabular
+END_TYPE
+
+TYPE= END_ENV
+NAME= tabular
+ START_TAG=
+ RESET_MODE:
+END_TYPE
+
+TYPE= BEGIN_ENV
+NAME= eqnarry
+ C= starting actions, etc., here
+ END_TAG=
+ SET_MODE: eqn
+END_TYPE
+
+TYPE= END_ENV
+NAME= eqnarray
+ START_TAG= " (X)?n"
+ RESET_MODE:
+END_TYPE
+
+TYPE= TEX_CHAR
+NAME= &
+ START_TAG= " | "
+IN_MODE= eqn
+ START_TAG= " "
+END_MODE
+END_TYPE
+
+TYPE= CHAR_COMMAND
+NAME= \\
+ START_TAG= "?n"
+IN_MODE= tabular
+ START_TAG= " |?n"
+ STRING: " | "
+END_MODE
+IN_MODE= eqn
+ START_TAG= " (X)?n"
+END_MODE
+END_TYPE
+</pre>
+
+<p>Let us look at the specification for the <samp>\tabular</samp> environment first.
+The <samp>END_TAG=</samp> action is specified by the single command line
+<samp>SET_MODE:</samp> <samp>tabular</samp>, where <samp>tabular</samp> is any convenient
+name for identifying a mode. Thus, this will set the mode to be <samp>tabular</samp>.
+The action at the end of the environment is to reset the mode
+(<samp>RESET_MODE:</samp>)
+to whatever its previous value was. It is assumed that the last row in any
+<samp>tabular</samp> environment is finished by <samp>\\</samp>. Similar actions are
+performed for the <samp>eqnarray</samp> environment, except that the mode is called
+<samp>eqn</samp> instead of <samp>tabular</samp>. The other difference is that it
+is assumed that the last row is not ended by <samp>\\</samp>, so the end of
+the <samp>eqnarray</samp> environment has to also act like the <samp>\\</samp>.
+
+
+<p>Turning now to the specification for the <samp>&</samp> command, the first part
+of the specification identifies the type and name of the LaTeX command.
+This is then followed by the mode-independent set of actions,
+which in this case
+consists of printing a vertical bar with some spaces on either side of it.
+Following these are any mode-dependent actions, bracketed between
+<samp>IN_MODE=</samp> and <samp>END_MODE</samp>. The value for <samp>IN_MODE=</samp>
+is the name of the relevent mode. In this case the only mode-dependent
+action occurs when <samp>MODE eqn</samp> is in effect and it is to print
+some spaces instead of the default spaces and vertical bar.
+
+
+<p>The specification for the <samp>\\</samp> command has its set of
+mode-independent default actions,
+namely just to print a newline, and two sets of mode-dependent actions.
+When the <samp>tabular</samp> mode is in effect, it prints some spaces, a vertical
+bar, a newline, more spaces, a vertical bar, and finally some more spaces.
+On the other hand, when the <samp>eqn</samp> mode is in effect, it prints some
+spaces, the string `(X)' and a newline. If a mode is in effect
+that is not defined within the specification (e.g., mode <samp>anon</samp>)
+it performs the default mode-independent actions.
+
+
+<p>As a perhaps more practical example, the following command table code will
+convert simple LaTeX <samp>tabular</samp>
+ environments to appropriate mark-up for HTML tables. It is assumed that
+the <samp>tabular</samp> environment is always within a <samp>table</samp> environment.
+
+
+<p>To set the perspective a little, here is the code for a simple table
+in LaTeX:
+<pre>
+\begin{table}[tbp]
+\centering
+\caption{A simple table typeset by \LaTeX.} \label{tab:lxtab}
+\begin{tabular}{|l||r|r||r|r|} \hline
+Stock & \multicolumn{2}{c||}{1994} & \multicolumn{2}{c|}{1995} \\ \cline{2-5}
+ & low & high & low & high \\ \hline
+ABC & 27 & 36 & 23 & 45 \\
+DEF & 53 & 72 & 19 & 54 \\
+GHI & 28 & 49 & 17 & 79 \\ \hline
+\end{tabular}
+\end{table}
+</pre>
+This will be typeset as shown in table <a href="#tab:lxtab">tab:lxtab</a>.
+<center><table border>
+
+<caption>A simple table typeset by LaTeX.</caption> <a name="tab:lxtab">(Table tab:lxtab)</a>
+
+<tr><td> Stock </td><td colspan=2> 1994 </td><td colspan=2> 1995 </tr>
+<tr><td > </td><td > low </td><td > high </td><td > low </td><td > high </tr>
+<tr><td > ABC </td><td > 27 </td><td > 36 </td><td > 23 </td><td > 45 </tr>
+<tr><td >
+DEF </td><td > 53 </td><td > 72 </td><td > 19 </td><td > 54 </tr>
+<tr><td >
+GHI </td><td > 28 </td><td > 49 </td><td > 17 </td><td > 79 </tr>
+<tr><td >
+</table></center>
+
+
+<p>The corresponding HTML code for the table after translation is:
+
+
+
+<p>
+<pre>
+&lt;p&gt;&lt;center&gt;&lt;table border&gt;
+&lt;caption&gt;A simple table typeset by LaTeX.&lt;/caption&gt; &lt;a name="tab:lxtab"&gt;&lt;/a&gt;
+
+
+<p>&lt;tr&gt;&lt;td&gt; Stock &lt;/td&gt;&lt;td colspan=2&gt; 1994 &lt;/td&gt;&lt;td colspan=2&gt; 1995 &lt;/tr&gt;
+&lt;tr&gt;&lt;td&gt;
+ &lt;/td&gt;&lt;td&gt; low &lt;/td&gt;&lt;td&gt; high &lt;/td&gt;&lt;td&gt; low &lt;/td&gt;&lt;td&gt; high &lt;/tr&gt;
+&lt;tr&gt;&lt;td&gt; ABC &lt;/td&gt;&lt;td&gt; 27 &lt;/td&gt;&lt;td&gt; 36 &lt;/td&gt;&lt;td&gt; 23 &lt;/td&gt;&lt;td&gt; 45 &lt;/tr&gt;
+&lt;tr&gt;&lt;td&gt;
+DEF &lt;/td&gt;&lt;td&gt; 53 &lt;/td&gt;&lt;td&gt; 72 &lt;/td&gt;&lt;td&gt; 19 &lt;/td&gt;&lt;td&gt; 54 &lt;/tr&gt;
+&lt;tr&gt;&lt;td&gt;
+GHI &lt;/td&gt;&lt;td&gt; 28 &lt;/td&gt;&lt;td&gt; 49 &lt;/td&gt;&lt;td&gt; 17 &lt;/td&gt;&lt;td&gt; 79 &lt;/tr&gt;
+&lt;tr&gt;&lt;td&gt;
+&lt;/table&gt;&lt;/center&gt;
+</pre>
+
+
+<p>In the HTML browser that I use this is displayed
+approximately as shown for table <a href="#tab:httab">tab:httab</a>.
+
+
+<p><center><table border>
+
+<caption>A simple table typeset after translation to HTML.</caption> <a name="tab:httab">(Table tab:httab)</a>
+
+<tr><td> Stock </td><td colspan=2> 1994 </td><td colspan=2> 1995 </tr>
+<tr><td > </td><td > low </td><td > high </td><td > low </td><td > high </tr>
+<tr><td > ABC </td><td > 27 </td><td > 36 </td><td > 23 </td><td > 45 </tr>
+<tr><td >
+DEF </td><td > 53 </td><td > 72 </td><td > 19 </td><td > 54 </tr>
+<tr><td >
+GHI </td><td > 28 </td><td > 49 </td><td > 17 </td><td > 79 </tr>
+<tr><td >
+</table></center>
+
+
+<p>In HTML a table is enclosed between
+<samp>&lt;table&gt;</samp> and <samp>&lt;/table&gt;</samp> tags.
+Each row of the table is enclosed between
+<samp>&lt;tr&gt;</samp> and <samp>&lt;/tr&gt;</samp> tags,
+and each element in a row is enclosed between
+<samp>&lt;td&gt;</samp> and <samp>&lt;/td&gt;</samp> tags.
+Under certain circumstances the closing tags (i.e.,
+those like <samp>&lt;/...&gt;</samp>)
+can be inferred by the HTML procesors and need
+not be explicitly put into the source text. The equivalent HTML tags to a
+LaTeX <samp>\multicolumn{num}{col}{text}</samp> command are<br>
+<samp>&lt;td colspan=num&gt; text &lt;/td&gt;</samp>.
+
+
+<p>The general actions that LTX2X has to perform in doing the LaTeX to
+HTML translation are:
+<ul>
+
+
+ <li> The start and end of a <samp>table</samp> environment has to translate to
+ the HTML start and end table tags <samp>&lt;table&gt;</samp> and
+ <samp>&lt;/table&gt;</samp>.
+ (Actually this also needs to handle the
+ centering of the HTML table and drawing a border round it as well.)
+
+
+<p>
+ <li> The start and end of the <samp>tabular</samp> environment has to translate
+ into a row start
+ <samp>&lt;tr&gt;&lt;td&gt;</samp> and end <samp>&lt;/tr&gt;</samp>
+ in the HTML table (and set the mode for the
+ LaTeX <samp>\\</samp> command).
+
+
+<p>
+ <li> The <samp>\\</samp> command must end one row of the HTML table and start the
+ next row
+ (<samp>&lt;/tr&gt;?n&lt;tr&gt;&lt;td&gt;</samp>).
+ It need not end a data element as
+ this is automatically closed by the end of the row.
+
+
+<p>
+ <li> The <samp>&</samp> column delimeter must end one HTML data element and start
+ another one (i.e., <samp>&lt;/td&gt;&lt;td&gt;</samp>).
+
+
+<p>
+ <li> The difficulty is in handling the <samp>\multicolumn</samp> command. In the easy
+ case the LaTeX to HTML translation is: <br>
+ <samp>... &amp; text &amp; ...</samp> maps to <br>
+ <samp>... &lt;/td&gt;&lt;td&gt; text &lt;/td&gt;&lt;td&gt; ...</samp>. <br>
+ However, when a multicolumn is involved the translation is <br>
+<samp>... & \multicolumn{N}{P}{text} & ...</samp> maps to <br>
+<samp>... &lt;/td&gt;&lt;td colspan=N&gt; text &lt;/td&gt;&lt;td&gt; ...</samp>. <br>
+As there is no look-ahead in LTX2X we have to be careful about starting a
+data element after a <samp>&</samp> because at that point LTX2X cannot know
+whether or not a <samp>\multicolumn</samp> command comes next, or just an ordinary
+data element.
+
+
+<p></ul>
+
+
+
+<p>We solve this last problem partly by using buffers
+(numbers <samp>8</samp> and <samp>9</samp> in the specification below)
+as temporary storage, and partly by a subtle specification for the
+<samp>\multicolumn</samp> command.
+
+
+<p>
+
+
+<p>
+<pre>
+C= start of a table
+TYPE= BEGIN_ENV
+NAME= table
+ START_TAG= "&lt;center&gt;&lt;table border&gt;"
+ OPT_PARAM= FIRST
+ C= ignore the optional positioning argument
+ PRINT_OPT= NO_PRINT
+END_TYPE
+
+
+<p>C= end a table
+TYPE= END_ENV
+NAME= table
+ START_TAG= "&lt;/table&gt;&lt;/center&gt;"
+END_TYPE
+
+
+<p>C= start a tabular
+TYPE= BEGIN_ENV
+NAME= tabular
+ START_TAG= "?n&lt;tr&gt;&lt;td"
+ RESET_BUFFER: 8
+ RESET_BUFFER: 9
+ OPT_PARAM= FIRST
+ C= ignore the optional positioning argument
+ PRINT_OPT= NO_PRINT
+ REQPARAMS= 1
+ C= ignore the column specification
+ PRINT_P1= NO_OP
+ END_TAG=
+ SET_MODE: tabular
+ PC_AT_END= TO_BUFFER 9
+END_TYPE
+
+
+<p>C= end a tabular
+TYPE= END_ENV
+NAME= tabular
+ PC_AT_START= RESET
+ START_TAG= "&gt;"
+ RESET_BUFFER: 8
+ RESET_BUFFER: 9
+ RESET_MODE:
+END_TYPE
+
+
+<p>C= we can do some processing of the <samp>\multicolumn</samp> command
+TYPE= COMMAND
+NAME= <samp>\multicolumn</samp>
+ PC_AT_START= TO_BUFFER 8
+ REQPARAMS= 2
+ START_TAG_1= " colspan="
+ PRINT_P2= NO_PRINT
+ PC_AT_END= RESET
+END_TYPE
+
+
+<p>C= now for the end/start of a row
+TYPE= CHAR_COMMAND
+NAME= <samp>\\</samp>
+ START_TAG= "&lt;br&gt;"
+IN_MODE= tabular
+ PC_AT_START= RESET
+ START_TAG=
+ SOURCE: BUFFER 8
+ STRING: "&gt; "
+ RESET_BUFFER: 8
+ SOURCE: BUFFER 9
+ END_TAG= "&lt;/tr&gt;?n&lt;tr&gt;&lt;td "
+ RESET_BUFFER: 9
+ PC_AT_END= TO_BUFFER 9
+END_MODE
+END_TYPE
+
+
+<p>C= and the column seperator
+TYPE= TEX_CHAR
+NAME= &amp;
+ PC_AT_START= RESET
+ START_TAG=
+ SOURCE: BUFFER 8
+ STRING: "&gt; "
+ RESET_BUFFER: 8
+ SOURCE: BUFFER 9
+ END_TAG= " &lt;/td&gt;&lt;td "
+ RESET_BUFFER: 9
+ PC_AT_END= TO_BUFFER 9
+END_TYPE
+</pre>
+
+
+
+<p>Regarding the <samp>\multicolumn</samp> specification, we state that as far as
+LTX2X is concerned, it only has two required parameters, and that the action
+for the second one is <samp>NO_PRINT</samp>. The first argument is written to
+buffer <samp>8</samp> after `colspan=' has first been put into it. LTX2X will treat
+the actual third argument to the <samp>\multicolumn</samp> as ordinary text, just
+as if there was no <samp>\multicolumn</samp> in the LaTeX source. We use buffer
+<samp>9</samp> for storing the text of a data element. When LTX2X processes
+a <samp>&amp;</samp> column delimeter it first outputs the contents of
+buffer <samp>8</samp> (the number of columns specification) and then appropriate
+HTML characters. It then outputs the contents of buffer <samp>9</samp> (the
+element text), finishes off the element and partially starts the next element.
+Similar actions are performed at the start of the <samp>tabular</samp> environment
+and at the end of each row in the table.
+
+
+<p>
+<h3>Sectioning command types</h3>
+
+
+
+<p>LTX2X does some particular processing for sectioning command types. Although
+LaTeX can determine where any section of a document ends, other tagging systems
+cannot always do this. They require both a `begin section' and an `end section'
+tag. LTX2X can take account of the nesting depth of document sections and,
+given appropriate specifications, can supply both `begin section' and `end section'
+tags appropriately. This requires a little bit more in the way of specifications
+than we have met so far.
+
+
+<p>For a <samp>SECTIONING</samp> command type, the command line
+<samp>SECTIONING_LEVEL=</samp>
+must be included within the specification. The value of this command is a keyword
+from the following list.
+<dl>
+<dt><samp>PART</samp>
+<dd> For a sectioning command equivalent to the
+ LaTeX <samp>\part</samp> command.
+<dt><samp>CHAPTER</samp>
+<dd> For a sectioning command equivalent to the
+ LaTeX <samp>\chapter</samp> command.
+<dt><samp>SECT</samp>
+<dd> For a sectioning command equivalent to the
+ LaTeX <samp>\section</samp> command.
+<dt><samp>SUBSECT</samp>
+<dd> For a sectioning command equivalent to the
+ LaTeX <samp>\subsection</samp> command.
+<dt><samp>SUBSUBSECT</samp>
+<dd> For a sectioning command equivalent to the
+ LaTeX <samp>\subsubsection</samp> command.
+<dt><samp>PARA</samp>
+<dd> For a sectioning command equivalent to the
+ LaTeX <samp>\paragraph</samp> command.
+<dt><samp>SUBPARA</samp>
+<dd> For a sectioning command equivalent to the
+ LaTeX <samp>\subparagraph</samp> command.
+</dl>
+
+
+<p>When a sectioning command is read from the LaTeX source, LTX2X firstly
+performs the <samp>END_TAG=</samp> actions for any `lower level' sections
+that this one is closing off. It then performs the <samp>START_TAG=</samp>
+actions for the current command, and stores its own <samp>END_TAG=</samp> actions for
+later use. It then goes on and process any arguments as usual.
+ The <samp>END_DOCUMENT</samp> command automatically closes off any opened
+sections.
+
+
+<p>As an example, assume that some kind soul has supplied a LaTeX style
+file that makes the commands <samp>\clause</samp> synonymous with <samp>\subsection</samp>,
+and <samp>\sclause</samp> synonymous with <samp>\subsubsection</samp>, etc. Also assume
+that it is required to output start and end tags of the form
+<samp>&lt;div.1&gt;</samp> and <samp>&lt;/div.1&gt;</samp>
+for sections, <samp>&lt;div.2&gt;</samp> for clauses, etc., and surround the
+headings with tags <samp>&lt;heading&gt;</samp> and <samp>&lt;/heading&gt;</samp>.
+Further, the first
+optional argument is of no interest as the output is going to be
+used by a processing system unable to automatically handle tables of contents.
+Part of an appropriate command table for doing this is:
+
+
+<p>
+
+<pre>
+TYPE= SECTIONING
+NAME= <samp>\section</samp>
+ SECTIONING_LEVEL= SECT
+ START_TAG= "?n?n&lt;div.1&gt;?n"
+ END_TAG= "?n&lt;/div.1&gt;"
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+ REQPARAMS= 1
+ START_TAG_1= "&lt;heading&gt;"
+ END_TAG_1= "&lt;/heading&gt;?n"
+END_TYPE
+
+
+<p>TYPE= SECTIONING
+NAME= <samp>\clause</samp>
+ SECTIONING_LEVEL= SUBSECT
+ START_TAG= "?n?n&lt;div.2&gt;?n"
+ END_TAG= "?n&lt;/div.2&gt;"
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+ REQPARAMS= 1
+ START_TAG_1= "&lt;heading&gt;"
+ END_TAG_1= "&lt;/heading&gt;?n"
+END_TYPE
+</pre>
+
+
+
+<p>An example output resulting from this command table (if it had been applied to this
+document) is:
+
+
+<pre>
+...
+&lt;/div.2&gt;
+&lt;/div.1&gt;
+
+
+<p>&lt;div.1&gt;
+&lt;heading&gt;The command table file&lt;/heading&gt;
+
+
+<p>By default, ...
+</pre>
+
+
+
+<p>
+<h3>List environment types</h3>
+
+
+
+<p>In LaTeX the use of the <samp>\item</samp> command is restricted to within a
+list environment. The typeset appearance of an <samp>\item</samp> typically depends
+on the particular environment in which it is used. LTX2X has a limited capability
+of modifying its <samp>\item</samp> tagging output. It can also provide an `end item'
+tag for those tagging systems that require such a thing.
+
+
+<p>For such list environments, identified by the command type keyword
+<samp>BEGIN_LIST_ENV</samp>,
+the following command lines should be included within the type specification.
+<dl>
+<dt><samp>START_ITEM=</samp>
+<dd> Actions to be performed at the start
+ of each <samp>\item</samp> command in the list.
+<dt><samp>END_ITEM=</samp>
+<dd> Actions to be performed after processing all
+ the <samp>\item</samp>'s text.
+<dt><samp>START_ITEM_PARAM=</samp>
+<dd> Actions to be performed at the start of an
+ <samp>\item</samp>'s optional argument text.
+<dt><samp>END_ITEM_PARAM=</samp>
+<dd> Actions to be performed at the end of an
+ <samp>\item</samp>'s optional argument text.
+</dl>
+As usual, an unspecified tag defaults to no actions.
+
+
+<p>For example, assume that we are not interested in tagging the end of an item,
+but we do want to mark each item in an <samp>itemize</samp> environment with the lowercase
+letter `o', each <samp>enumerate</samp> item with `(N)' and put a colon after the
+optional argument in a description environment. Also, each item should have some
+indentation from the left hand margin.
+
+
+<p><pre>
+TYPE= BEGIN_LIST_ENV
+NAME= itemize
+ START_ITEM= "?n o "
+END_TYPE
+
+TYPE= END_LIST_ENV
+NAME= itemize
+END_TYPE
+
+TYPE= BEGIN_LIST_ENV
+NAME= enumerate
+ START_ITEM= "?n (N) "
+END_TYPE
+
+TYPE= END_LIST_ENV
+NAME= enumerate
+END_TYPE
+
+TYPE= BEGIN_LIST_ENV
+NAME= description
+ START_ITEM= "?n "
+ END_ITEM_PARAM= " : "
+END_TYPE
+
+TYPE= END_LIST_ENV
+NAME= description
+END_TYPE
+</pre>
+
+<p>With the above commands, this LaTeX text:
+<pre>
+\begin{description}
+\item[An example]
+ \begin{itemize}
+ \item the first item;
+ \item the second item.
+ \end{itemize}
+\end{description}
+</pre>
+will be transformed into:
+<pre>
+ An example :
+ o the first item;
+ o the second item.
+</pre>
+
+
+<p>
+<h3>Character types</h3>
+
+
+
+<p>LaTeX treats some characters specially. These special characters are:
+<samp>#</samp>,
+<samp>$</samp>,
+<samp>%</samp>,
+<samp>&</samp>,
+<samp>~</samp>,
+<samp>_</samp>,
+<samp>^</samp>,
+<samp>\</samp>,
+<samp>{</samp>,
+<samp>}</samp>,
+and, under some circumstances, also the
+character <samp>@</samp>.
+ LTX2X recognizes these special characters and, if directed, will
+perform specified actions; otherwise it treats them as it treats any alphanumeric
+character, which is just to print it.
+
+
+<p>It has already been stated that commands for the left and right braces
+(i.e. <samp>{</samp> and <samp>}</samp>) must be given
+within the command table as command types
+<samp>LBRACE</samp>, <samp>RBRACE</samp> respectively.
+The dollar symbol ($) must also be specified via the two command types
+<samp>BEGIN_DOLLAR</samp> and <samp>END_DOLLAR</samp>. Here is an
+example of replacing the dollar signs by tags intended to indicate
+the start and end of a mathematical phrase.
+
+
+<pre>
+TYPE= BEGIN_DOLLAR
+ START_TAG= "&lt;math&gt;"
+END_TYPE
+
+
+<p>TYPE= END_DOLLAR
+ START_TAG= "&lt;/math&gt;"
+END_TYPE
+</pre>
+
+
+
+<p>Commands for the other special LaTeX characters are specified with the
+<samp>TEX_CHAR</samp> command type keyword.
+
+
+<p>The characters <samp>_</samp> (underscore) and <samp>^</samp> (caret) are used in
+LaTeX math mode to indicate subscripting and superscripting respectively. The
+following will replace <samp>^</samp> by <samp>&lt;sup&gt;</samp>, print the superscript
+text (which must be enclosed in braces (Footnote: It is good practice to
+always enclose superscript and subscript text in braces, even though
+TeX does not always require this.) ) and at the end close with
+<samp>&lt;/sup&gt;</samp>.
+
+
+
+<p>
+<pre>
+TYPE= TEX_CHAR
+NAME= <samp>^</samp>
+ START_TAG= "&lt;sup&gt;"
+ REQPARAMS= 1
+ END_TAG= "&lt;/sup&gt;"
+END_TYPE
+</pre>
+
+
+
+<p>Given the above specifications, then <samp>$(2^{15} - 1)$</samp> will be transformed
+into <br>
+<samp>&lt;math&gt;(2&lt;sup&gt;15&lt;/sup&gt; - 1)&lt;/math&gt;</samp>.
+
+
+<p>
+<h3>Verbatim like types</h3>
+
+
+
+<p>The command type <samp>VCOMMAND</samp> is for the procesing of LaTeX
+<samp>\verb</samp>-like commands where the argument of the command is to be
+typeset as-is. For example, there might be a command called <samp>\url</samp>
+which takes one argument which is meant to be an Internet URL. If the
+application was the conversion of a LaTeX document to HTML, then the
+following specification could be useful.
+
+
+<pre>
+TYPE= VCOMMAND
+NAME= <samp>\url</samp>
+ REQPARAMS= 1
+ PRINT_P1= TO_BUFFER 7
+ START_TAG=
+ RESET_BUFFER: 7
+ END_TAG= "&lt;a href=""
+ SOURCE: BUFFER 7
+ STRING: ""&gt;"
+ SOURCE: BUFFER 7
+ STRING: "&lt;/a&gt;"
+ RESET_BUFFER: 7
+END_TYPE
+</pre>
+
+
+
+<p>If the LaTeX source included:
+<pre>
+... obtainable from
+\url{http://www.cdrom.com/pub/tex}
+</pre>
+then the resulting LTX2X output would be:
+
+
+<pre>
+... obtainable from
+&lt;a href="http://www.cdrom.com/pub/tex"&gt;http://www.cdrom.com/pub/tex&lt;/a&gt;
+</pre>
+
+which, if this was then read via an appropriate browser, a link to the URL
+
+<a href="http://www.cdrom.com/pub/tex">http://www.cdrom.com/pub/tex</a>
+
+would be automatically established.
+
+
+<p>Similarly <samp>verbatim</samp>-like environments can also be specified with
+the types <samp>BEGIN_VENV</samp> and <samp>END_VENV</samp>.
+For example, the <tt>html.sty</tt> package defines three LaTeX
+environments for documents that might be converted from LaTeX tagging
+to HTML tagging. One of these, <samp>latexonly</samp> is for LaTeX code
+that is not to occur in the HTMLed document and another is <samp>htmlonly</samp>
+which contains HTML code that is required for an HTML version
+of the document but which is not to appear in the LaTeX ed document.
+The third one is <samp>rawhtml</samp> which is for HTML code to be output
+verbatim to the HTML document source.
+These could be simulated by:
+<pre>
+TYPE= BEGIN_VENV
+NAME= latexonly
+ PC_AT_START= NO_PRINT
+END_TYPE
+
+TYPE= END_VENV
+NAME= latexonly
+ PC_AT_END= RESET
+END_TYPE
+
+TYPE= BEGIN_ENV
+NAME= htmlonly
+END_TYPE
+
+TYPE= END_ENV
+NAME= htmlonly
+END_TYPE
+
+TYPE= BEGIN_VENV
+NAME= rawhtml
+END_TYPE
+
+TYPE= END_VENV
+NAME= rawhtml
+END_TYPE
+</pre>
+
+<p>
+
+<h3>Odd command types</h3>
+
+
+
+<p>The majority of commands in LaTeX that take optional arguments
+have only a single optional argument that is either immediately after
+the command or after all the required arguments. There are, however, some
+commands that do not fit this pattern. This set of command types enables
+at least some of these `odd' commands to be handled.
+
+
+<p>The command type keyword is of the form <samp>COMMAND_code</samp>, where
+<samp>code</samp> indicates the type and ordering of the arguments. The
+<samp>code</samp> is composed from combinations of the letters <samp>O</samp>
+(for an optional argument) and <samp>P</samp> (for a required parameter (i.e.,
+argument)). The ordering of these letters in the <samp>code</samp> specifies
+the type and ordering of the command's arguments.
+
+
+<p>The `odd' command types are:
+<dl>
+<dt><samp>COMMAND_OOP</samp>
+<dd> Corresponding to a LaTeX command of the form <br>
+<samp>\com[OptParam][OptParam]{ReqParam}</samp>.
+For example, the <samp>\makebox</samp>
+command falls into this category.
+
+
+<p><dt><samp>COMMAND_OOOPP</samp>
+<dd> Corresponding to a LaTeX command of the form <br>
+<samp>\com[OptParam][OptParam][OptParam]{ReqParam}{ReqParam}</samp>.
+For example, the <samp>\parbox</samp>
+command falls into this category.
+
+
+<p><dt><samp>COMMAND_OPO</samp>
+<dd> Corresponding to a LaTeX command of the form <br>
+<samp>\com[OptParam]{ReqParam}[OptParam]</samp>.
+For example, the <samp>\RequirePackage</samp> and <samp>\LoadClass</samp>
+commands fall into this category.
+
+
+<p><dt><samp>COMMAND_POOOP</samp>
+<dd> Corresponding to a LaTeX command of the form <br>
+<samp>\com{ReqParam}[OptParam][OptParam][OptParam]{ReqParam}</samp>.
+
+
+<p><dt><samp>COMMAND_POOP</samp>
+<dd> Corresponding to a LaTeX command of the form <br>
+<samp>\com{ReqParam}[OptParam][OptParam]{ReqParam}</samp>.
+For example, the <samp>\newcommand</samp> and its companion commands
+fall into this category.
+
+
+<p><dt><samp>COMMAND_POOPP</samp>
+<dd> Corresponding to a LaTeX command of the form <br>
+<samp>\com{ReqParam}[OptParam][OptParam]{ReqParam}{ReqParam}</samp>.
+For example, the <samp>\newenvironment</samp> and its companion command
+fall into this category.
+</dl>
+
+
+<p>As usual, the command name is required, as are any actions. However,
+it is not necessary to specify the number of required arguments (i.e.
+<samp>REQPARAMS=</samp>) nor the position of the optional argument (i.e.
+<samp>OPT_PARAM=</samp>), as LTX2X already has this information. The tag actions
+are according to the argument ordering given in the <samp>code</samp> and are
+specified by the required argument tags (e.g. <samp>START_TAG_n=</samp> and
+<samp>END_TAG_n=</samp>).
+Do not use any of the command lines for optional arguments. Argument
+actions are controlled in the usual manner.
+
+
+<p>A typical example of the use of these commands is to supress any processing
+of the LaTeX <samp>\newcommand</samp> and its ilk. For example:
+<pre>
+TYPE= COMMAND_POOP
+NAME= \providecommand
+ PRINT_P1= NO_OP
+ PRINT_P2= NO_OP
+ PRINT_P3= NO_OP
+ PRINT_P4= NO_OP
+END_TYPE
+
+TYPE= COMMAND_POOPP
+NAME= \renewenvironment
+ PRINT_P1= NO_OP
+ PRINT_P2= NO_OP
+ PRINT_P3= NO_OP
+ PRINT_P4= NO_OP
+ PRINT_P5= NO_OP
+END_TYPE
+</pre>
+
+<p>
+
+<h3>Other command types</h3>
+
+
+
+<p>The <samp>OTHER_</samp> command types (<samp>OTHER_COMMAND</samp>,
+<samp>OTHER_BEGIN</samp>
+and <samp>OTHER_END</samp>)
+are very limited in what can be affected. Basically, these provide for
+default printing actions if the corresponding LaTeX command has not been
+identified elsewhere in the command table.
+
+
+<p>If there are no commands within the specification, the name of the command and
+all its arguments will be printed verbatim.
+
+
+<p>The command lines <samp>START_TAG=</samp> and <samp>END_TAG=</samp>
+cause the corresponding
+actions to be performed before and after the name of the command is printed. Any
+arguments are printed verbatim.
+
+
+<p>The command line <samp>PRINT_CONTROL=</samp> with a value of <samp>NO_PRINT</samp>
+causes the command name not to be printed, nor any arguments that LTX2X may
+find associated with the command.
+
+
+<p>
+<h3>Picture types</h3>
+
+
+
+<p>The <samp>_PICTURE_</samp> command types differ from all the other types in
+LTX2X, just as they do in LaTeX. In LaTeX some of the picture drawing commands
+take arguments of the form <samp>(number, number)</samp>, representing a coordinate
+pair, as well as the usual
+required arguments enclosed in curly braces and possibly an optional
+argument enclosed in square brackets. Within LTX2X, commands that take coordinate
+arguments are treated specially in the command table.
+
+
+<p>Generally speaking, the LTX2X command types are of the form
+<samp>PICTURE_code</samp>,
+where <samp>code</samp> indicates the type and ordering of the arguments. The
+<samp>code</samp> is composed from combinations of the letters <samp>C</samp> (for a
+coordinate argument), <samp>O</samp> (for an optional argument) and <samp>P</samp> (for
+a required argument). For example, <samp>PICTURE_PCOP</samp> indicates a picture
+command that has a required argument, followed by a coordinate argument,
+followed by an optional argument and finally another required argument.
+
+
+<p>The provided picture types are:
+<dl>
+<dt><samp>BEGIN_PICTURE_CC</samp>
+<dd> Corresponding to a LaTeX command of the form <br>
+ <samp>\begin{PictureEnv}(coords)(coords)</samp>, where the final coordinate argument
+ is optional.
+<dt><samp>PICTURE_CCPP</samp>
+<dd> Corresponding to a LaTeX command of the form <br>
+ <samp>\com(coords)(coords){ReqParam}{ReqParam}</samp>.
+ For example, the <samp>\multiput</samp> command falls into this category.
+<dt><samp>PICTURE_CO</samp>
+<dd> Corresponding to a LaTeX command of the form <br>
+ <samp>\com(coords)[OptParam]</samp>.
+ For example, the standard LaTeX <samp>\oval</samp> command falls into
+ this category.
+<dt><samp>PICTURE_COP</samp>
+<dd> Corresponding to a LaTeX command of the form <br>
+ <samp>\com(coords)[OptParam]{ReqParam}</samp>.
+ For example, the <samp>\makebox</samp> and <samp>\framebox</samp> commands fall
+ into this category.
+<dt><samp>PICTURE_CP</samp>
+<dd> Corresponding to a LaTeX command of the form <br>
+ <samp>\com(coords){ReqParam}</samp>.
+ For example, the <samp>\put</samp>, <samp>\line</samp> and <samp>\vector</samp> commands
+ fall into this category.
+<dt><samp>PICTURE_OCC</samp>
+<dd> Corresponding to a LaTeX command of the form <br>
+ <samp>\com[OptParam](coords)(coords)</samp>.
+ For example, the <samp>\graphpaper</samp> command from the <samp>graphpap</samp>
+ package falls into this category.
+<dt><samp>PICTURE_OCCC</samp>
+<dd> Corresponding to a LaTeX command of the form <br>
+ <samp>\com[OptParam](coords)(coords)(coords)</samp>.
+ For example, the <samp>\qbezier</samp> command falls into this category.
+<dt><samp>PICTURE_OCO</samp>
+<dd> Corresponding to a LaTeX command of the form <br>
+ <samp>\com[OptParam](coords)[OptParam]</samp>.
+ For example, the <samp>\oval</samp> command from the <samp>pict2e</samp> package
+ falls into this category.
+<dt><samp>PICTURE_PCOP</samp>
+<dd> Corresponding to a LaTeX command of the form <br>
+ <samp>\com{ReqParam}(coords)[OptParam]{ReqParam}</samp>.
+ For example, the <samp>\dashbox</samp> and <samp>\savebox</samp> commands fall
+ into this category.
+<dt><samp>END_PICTURE</samp>
+<dd> Corresponding to a LaTeX command of the form <br>
+ <samp>\end{PictureEnv}</samp>.
+</dl>
+
+
+<p>As usual, the command name is required, as are any actions. However,
+it is not necessary to specify the number of required arguments (i.e.
+<samp>REQPARAMS=</samp>) nor the position of the optional argument (i.e.
+<samp>OPT_PARAM=</samp>), as LTX2X already has this information. The tag actions
+are according to the argument ordering given in the <samp>code</samp> and are
+specified by the required argument tags (e.g. <samp>START_TAG_n=</samp> and
+<samp>END_TAG_n=</samp>).
+Do not use any of the command lines for optional arguments. Argument
+actions controlled in the usual manner.
+
+
+<p>As an example, the following specifications within a command table should be
+sufficient to ensure that any picture commands in a source file are
+not passed through to the output file.
+
+
+<p><pre>
+TYPE= BEGIN_PICTURE_CC
+NAME= picture
+PRINT_P1= NO_PRINT
+PRINT_P2 = NO_PRINT
+END_TYPE
+
+TYPE= PICTURE_CP
+NAME= \put
+PRINT_P1= NO_PRINT
+PRINT_P2= NO_OP
+END_TYPE
+
+TYPE= PICTURE_CCPP
+NAME= \multiput
+PRINT_P1= NO_PRINT
+PRINT_P2= NO_PRINT
+PRINT_P3= NO_OP
+PRINT_P4= NO_OP
+END_TYPE
+
+TYPE= PICTURE_PCOP
+NAME= \savebox
+PRINT_P1= NO_OP
+PRINT_P2= NO_PRINT
+PRINT_P3= NO_OP
+PRINT_P4= NO_OP
+END_TYPE
+
+TYPE= PICTURE_OCC
+NAME= \graphpaper
+PRINT_P1= NO_OP
+PRINT_P2= NO_PRINT
+PRINT_P3= NO_PRINT
+END_TYPE
+
+TYPE= PICTURE_OCCC
+NAME= \qbezier
+PRINT_P1= NO_OP
+PRINT_P2= NO_PRINT
+PRINT_P3= NO_PRINT
+PRINT_P4= NO_PRINT
+END_TYPE
+
+TYPE= END_PICTURE
+NAME= picture
+END_TYPE
+</pre>
+
+<p><dl>
+<dt>NOTE 1:
+<dd> The action <samp>NO_OP</samp> cannot be applied to an
+ argument that is a coordinate pair.
+
+
+<p><dt>NOTE 2:
+<dd> As LTX2X is essentially limited to printing actions,
+and cannot actually process any
+LaTeX picture drawing commands, the suppression of picture printing is
+probably the most usual use of the picture commands.
+</dl>
+
+
+<p>
+<h3>Special command types</h3>
+
+
+
+<p>The <samp>SPECIAL_</samp> commands, namely <samp>SPECIAL_COMMAND</samp>,
+<samp>SPECIAL_BEGIN_ENV</samp>,
+ <samp>SPECIAL_BEGIN_LIST</samp>,
+<samp>SPECIAL_END_ENV</samp>,
+<samp>SPECIAL_END_LIST</samp> and
+<samp>SPECIAL_SECTIONING</samp>, are provided for cases where some special kind of
+output processing is required that is not built into LTX2X. In order to implement
+any commands of these types, it is necessary to modify the internals of LTX2X
+and recompile the source code. This is not recommended.
+
+
+<p>
+<h3>File inclusion</h3>
+
+
+
+<p>A command table file can include other command table files. In turn an included
+file can recursively include other command table files. The file inclusion command
+line is
+<pre>
+INCLUDE= FileName
+</pre>
+where <samp>FileName</samp> is the name of the command table file to be included. The effect
+is that the above line is replaced by the contents of <samp>FileName</samp>.
+
+
+<p>For example, assume that there are three command table files called respectively
+<tt>detex.ct</tt>, <tt>detex.l2x</tt> and <tt>detex.fl</tt>. The contents of these
+files are:
+<pre>
+C= ----------file detex.ct
+...
+INCLUDE= detex.l2x
+...
+C= ----------end of detex.ct
+END_CTFILE= end of detex.ct
+</pre>
+and for <tt>detex.l2x</tt> as:
+<pre>
+C= ---------- file detex.l2x
+
+TYPE= COMMAND
+NAME= \lx
+ START_TAG= "LTX2X"
+END_TYPE
+
+INCLUDE= detex.fl
+
+TYPE= COMMAND
+NAME= \ctab
+ START_TAG= "command table"
+END_TYPE
+
+C= ---------- end of file detex.l2x
+END_CTFILE= end of file detex.l2x
+</pre>
+and lastly <tt>detex.fl</tt> is:
+<pre>
+C= ---------- file detex.fl
+
+TYPE= COMMAND
+NAME= \fl
+ START_TAG= "FLaTTeN"
+END_TYPE
+
+C= ---------- end file detex.fl
+END_CTFILE= end file detex.fl
+</pre>
+Then, as far as LTX2X is concerned, the original <tt>detex.ct</tt> file is
+treated as though it had been written as:
+<pre>
+C= ----------file detex.ct
+...
+C= ---------- file detex.l2x
+
+TYPE= COMMAND
+NAME= \lx
+ START_TAG= "LTX2X"
+END_TYPE
+
+C= ---------- file detex.fl
+
+TYPE= COMMAND
+NAME= \fl
+ START_TAG= "FLaTTeN"
+END_TYPE
+
+C= ---------- end file detex.fl
+
+TYPE= COMMAND
+NAME= \ctab
+ START_TAG= "command table"
+END_TYPE
+
+C= ---------- end of file detex.l2x
+...
+C= ----------end of detex.ct
+END_CTFILE= end of detex.ct
+</pre>
+
+<p>Note that nasty things will happen if you have a cycle of inclusions. That is,
+you must not have anything similar to file <tt>A</tt> including file <tt>B</tt> which
+includes file <tt>C</tt> which in turn includes either file <tt>A</tt> or <tt>B</tt>.
+
+
+<p>
+<h3>Interpreter commands</h3>
+ <a name="sec:intcom"></a>
+
+
+<p>LTX2X includes an interpreter for a procedural programming language
+that is based on the ISO international standard EXPRESS information
+modeling language [<a href="#EBOOK, EXPRESSIS">EBOOK, EXPRESSIS</a>]. At the moment the
+programming language within LTX2X is anonymous, but for ease
+of reference I will call it EXPRESS-A
+(EXPRESS -Almost? -Approximate? -Anonymous?).
+The EXPRESS-A language is described later in section <a href="#sec:expressa">sec:expressa</a>,
+but for now it is sufficient to know the commands that signify
+the start and end of this code.
+
+
+<p>The command <samp>CODE_SETUP=</samp> indicates the commencement of
+code to be run before any document processing occurs. The
+<samp>END_CODE</samp> command signifies the end of this code block.
+This block should be placed in the command table before any other commands
+except for the <samp>ESCAPE...</samp> commands, if any. This block
+can contain variable declarations, function and procedure declarations,
+and statements.
+
+
+<p>Code consisting purely of statements can be placed anywhere that
+a tagging action may be specified. These statements are enclosed
+between a <samp>CODE:</samp> and <samp>END_CODE</samp> pair of commands.
+
+
+<p>The EXPRESS-A language is described in detail in <a href="#sec:expressa">sec:expressa</a>,
+but to give a flavour of it here
+is a simple possible application. It has been noted that LTX2X will find
+difficulty in processing the contents of the LaTeX <samp>picture</samp>
+environment. The following portions of a command table write the contents
+of a <samp>figure</samp> environment to an external file and uses the programming
+language to keep a count of the number of figures so processed.
+
+
+<p><pre>
+c= declare and initialise a variable
+CODE_SETUP=
+ LOCAL
+ fignum : INTEGER;
+ END_LOCAL;
+ fignum := 0;
+END_CODE
+
+c= write figure contents to an external file
+TYPE= BEGIN_ENV
+NAME= figure
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+ PC_AT_START= TO_FILE figs.tmp
+ START_TAG=
+ CODE:
+ fignum := fignum + 1; -- increment figure counter
+ println; -- print a blank line
+ println('%%% FIGURE ', fignum); -- write counter as a LaTeX comment
+ END_CODE
+ STRING: "\begin{figure}"
+END_TYPE
+
+c= close figure environment, back to normal output, and output
+c= text indicating that a figure should be here
+TYPE= END_ENV
+NAME= figure
+ PC_AT_START= RESET
+ START_TAG=
+ SWITCH_TO_FILE: figs.tmp
+ STRING: "\end{figure}?n?n"
+ SWITCH_BACK:
+ CODE:
+ println;
+ println('PLACE FOR FIGURE ', fignum);
+ println;
+ END_CODE
+END_TYPE
+</pre>
+
+<p>
+<h2>The LTX2X program</h2>
+ <a name="sec:program"></a>
+
+
+<p>LTX2X is written using flex and bison. The resulting C code should
+compile on any system. More details are given later, but for the end-user
+the next section describes how to run the program, assuming that is available
+on your system.
+
+
+<p>
+<h3>Running LTX2X</h3>
+
+
+
+<p>The syntax for running the compiled version of LTX2X is:
+<pre>
+ltx2x [-c] [-f table-file] [-p number] [-w] [-D dir_cat_char]
+ [-P path_seperators] [-S]
+ [-i number] [-l number] [-t] [-y number] [-C] [-E]
+ input-file output-file
+</pre>
+where elements in square brackets are options. The options fall into
+two groups, one for the casual user and the other for those who may be
+interested in the internals of LTX2X. The first group of options includes:
+<dl>
+<dt>-c
+<dd> By default, LTX2X ignores all LaTeX comments in the input
+ file. This option causes LTX2X to write the comments to the output file.
+
+
+<p><dt>-f
+<dd> By default, LTX2X reads the command table from a file called
+ <samp>ltx2x.ct</samp>. If the required command table is in a file with another name this
+ option is used to change from the default file. For example,
+<pre>
+> ltx2x in.tex out.l2x
+</pre>
+reads a command table from <samp>ltx2x.ct</samp>, while
+<pre>
+> ltx2x -f detex.ct in.tex out.l2x
+</pre>
+reads a command table from file <samp>detex.ct</samp>.
+
+
+<p><dt>-p
+<dd> This option causes LTX2X to `pretty print' the output file
+ (as far as it is able to). The <samp>number</samp> is required and it indicates
+ the desired maximum number
+ of characters per output line. If this is considered to be too small,
+ then LTX2X chooses a value. Note that pretty printing is only applied
+ to the source file --- not to any replacement tags. That is, it
+ only tries to format the running text from the source file.
+
+
+<p><dt>-w
+<dd> By default, LTX2X outputs source white space just at it reads it.
+ This option causes LTX2X to collapse any amount of contiguous white space
+ to a single space. The <samp>-p</samp> option includes the <samp>-w</samp> option.
+
+
+<p><dt>-D
+<dd> The value of this option is the character that the operating system
+ uses to catenate directory names to form a path (see <a href="#sec:search">sec:search</a>).
+ The default value is a
+ slash (i.e. <samp>/</samp>). The default could be changed to a backslash, for example,
+ by <samp>-D \</samp>.
+
+
+<p><dt>-P
+<dd> The environment variable (see <a href="#sec:search">sec:search</a>)
+ contains a list of directories (also known
+ as path names). In the operating system that I use, these are separated by
+ the colon (<samp>:</samp>) character which, together with the semi-colon
+ and space characters, form
+ the LTX2X default separators. The path separator characters can be changed
+ with this option.
+ For example, <samp>-P :</samp> will make the separators be a colon
+ or a space (space is automatically included in the separator list).
+
+
+<p><dt>-S
+<dd> This option enables the source level debugger
+ (see <a href="#sec:sld">sec:sld</a>) for any embedded EXPRESS-A code.
+</dl>
+
+
+<p>The second group of options are principally for those who might be
+extending the LTX2X system.
+
+
+<p><dl>
+<dt>-i
+<dd> This produces information that may be useful for debugging
+ the EXPRESS-A interpreter. <samp>number</samp> is an integer
+ between 1 and 9 inclusive.
+ The greater the number, the more diagnostics are generated.
+
+
+<p><dt>-l
+<dd> This produces information that may be useful for debugging
+ the LTX2X program. <samp>number</samp> is an integer between 1 and 9 inclusive.
+ The greater the number, the more diagnostics are generated.
+
+
+<p><dt>-t
+<dd> This generates diagnostics related to the processing of
+ the command table file.
+
+
+<p><dt>-y
+<dd> Like the <samp>l</samp> option, but produces diagnostic information
+ from the parser (this is actually a null option, but may be useful
+ in the future).
+
+
+<p><dt>-C
+<dd> Disable any interpreter debugging information during
+ the code generation pass. This is not necessary unless the -i
+ option is used.
+
+
+<p><dt>-E
+<dd> Disable any interpreter debugging information during
+ the code execution processing.This is not necessary unless the -i
+ option is used.
+
+
+<p></dl>
+
+
+<p>
+
+
+ LTX2X first reads the specified command table file, together with any included files,
+looking first in the current directory, then in the directories specified by
+the environment variable (if it exists).
+ It then reads the <samp>input-file</samp> from the current directory,
+performs the actions specified in the command table and outputs the results to
+the <samp>output-file</samp>.
+
+
+<p>Three other files are also generated.
+<ul>
+
+
+ <li> <samp>ltx2xct.lis</samp> --- This contains a human-readable form of the internal
+ representation of the command table. It may be useful if there are any errors
+ in the original command table.
+
+ <li> <samp>ltx2x.err</samp> --- This contains any error or warning messages generated
+ by LTX2X. It also contains any diagnostic information that may have been
+ requested via a command line option.
+
+ <li> <samp>interp.csg</samp> --- This contains a human readable listing of the
+ internal byte code generated by the EXPRESS-A interpreter.
+</ul>
+
+
+
+<p>When LTX2X is running normally it prints out a counter to the terminal
+indicating how many hundreds of input source file lines it has processed.
+Lack of such output is an indication that the program may be in a loop and
+chewing up CPU cycles to no avail. In this case, stop the program and examine
+the output for indications of where the trouble is occurring.
+
+
+<p>A limited number of errors are allowed when processing the command table
+and the input LaTeX file before LTX2X gives up and quits. In
+particular, if it is reading a command table file that includes another file, say one
+called <tt>zilch</tt>,
+that it cannot read, it prints the following message to the user's terminal.
+<pre>
+Can't open file zilch
+Enter new file name, or I to ignore, or Q to quit
+:
+</pre>
+A Q (or q) response stops LTX2X from any further processing. An
+I (or i) response causes LTX2X to stop looking for the included file
+and continue processing the current file. Any other response is taken to be
+the name of an included file, which LTX2X then tries to read. If it fails, then
+the above message is repeated. The user is given a limited number of opportunities
+to identify a readable file before LTX2X quits altogether with this message:
+<pre>
+Last attempt. Can't open file zilch. I'm giving up.
+</pre>
+
+
+<p>
+ Regarding performance, the time taken by LTX2X to process a document does
+not appear to be significantly different from the time to LaTeX the
+same document.
+
+
+<p>
+<h4>Directory searching</h4> <a name="sec:search"></a>
+
+
+<p>The program employs a search algorithm to find files that are not
+in the current directory. It first looks in the current directory and
+if a file of the given name is found, then that is used. If the file
+is not found, then it searches for it among directories that are
+specified in a system environment variable. This variable specifies
+a list of pathnames, where the directories forming the path are
+combined using a catenation character. For example, <samp>dir1/dir2/dir3</samp>
+could be a pathname, where the slash (<samp>/</samp>) is the catenation character.
+If it is looking for file <samp>afile.txt</samp> it will catenate the file name
+to the path name (e.g. <samp>dir1/dir2/dir3/afile.txt</samp>) and look for
+that. The pathnames in the list are separated by another character
+(in fact it can be one from a list of characters). For example here
+is a list of two pathnames; <samp>dir1/dir2;dir1/dir4</samp>, where the semi-colon
+(<samp>;</samp>) is the pathname separator.
+
+
+<p>By default, the program uses a slash (<samp>/</samp>) as the directory
+catenation character and the pathname separators can be a space, or
+a colon or a semi-colon (i.e., any of <samp> :;</samp>). All these characters
+can be altered via the program command line options, and should be set to
+match the conventions of your operating system.
+
+
+<p>The environment variable used by the program is LTX2XTABLES.
+On the operating system that I use, I set this in my login file like:
+<pre>
+setenv LTX2XTABLES .:/dir1/dir2:/dir3/dir4
+</pre>
+Your system may have different conventions. Note that if the environment
+variable is not set, only files in the current directory are considered.
+
+
+<p>
+
+<h3>System components</h3>
+
+
+
+<p>The system consists of five main components --- a lexer, a parser, a
+library of support functions and command table parsing code, a
+user-defined library of functions, and an interpreter for the EXPRESS-A
+language.
+
+
+<p>
+<h4>The lexer</h4>
+
+
+<p>The lexer is generated by flex [<a href="#LEVINE92">LEVINE92</a>]
+(a more functional version of lex [<a href="#LESK75">LESK75</a>]).
+The source for the lexer is in file <tt>l2x.l</tt>.
+Its principal function is to read a LaTeX
+source file and recognize LaTeX commands. In general, it passes off the
+relevant command tokens to the parser for performing appropriate actions.
+
+
+<p>However, the lexer does do some processing of the source itself.
+<ul>
+
+
+ <li> It recognizes LaTeX comments (i.e. any text starting with a percent
+ sign and ending with a newline). It silently ignores these comments, unless
+ run with the <samp>-c</samp> option.
+
+ <li> It recognizes the `standard' LaTeX verbatims. It will write out the
+ appropriate tags at the start and end of the verbatim text, while writing
+ the verbatim text directly to the output file, bypassing the parser.
+ It does not distinguish between the unstarred and starred
+ versions of the verbatims.
+
+ <li> Newlines and whitespace are directly written to the output file, again
+ bypassing the parser. The <samp>-p</samp> and <samp>-w</samp> options control the
+ final appearance of whitespace, newlines and paragraphing.
+
+ <li> It recognizes the command <samp>\ </samp> i.e. a backslash followed by a
+ space, and writes the tags defined in the <samp>SLASH_SPACE</samp> specification
+ directly to the output file.
+</ul>
+
+
+
+<p>The lexer is designed to recognize four kinds of LaTeX commands.
+<ul>
+
+
+ <li> Commands of the form <samp>\begin{environment}</samp>
+
+ <li> Commands of the form <samp>\end{environment}</samp>
+
+ <li> Any other command of the form <samp>\command</samp>
+
+ <li> As special cases, commands that are 'verbatim-like' or `verb-like'.
+</ul>
+
+When it finds a command, it looks up the command or environment name in the
+command table and sends the appropriate token and its command table location to the
+parser. As a special case the contents of verbatim-like environments and
+the argument of verb-like coommands are processesd within
+the lexer and not sent to the parser.
+
+
+<p>
+
+<h4>The parser</h4>
+
+
+<p>The parser is generated by bison [<a href="#LEVINE92">LEVINE92</a>]
+(a more powerful version of YACC [<a href="#JOHNSON75">JOHNSON75</a>]).
+The source for the parser is in file <tt>l2x.y</tt>.
+Essentially it defines a very simple
+grammar for a LaTeX document. That is, the grammar is limited to
+generic kinds of commands and command arguments. It does not understand
+the `meaning' of any of the commands or arguments.
+
+
+<p>When the parser receives a token from the lexer it tries to match it with
+one of the grammar rules, performing the actions specified by the command table.
+Here is an extract from the parser grammar file, <tt>l2x.y</tt>,
+for a LaTeX command that has
+two required arguments followed by an optional argument.
+
+
+<p><pre>
+l2xComm2Opt: COMMAND_2_OPT
+ {
+ start_with_req($1);
+ }
+ ReqParam
+ {
+ action_p_p1($1,1);
+ }
+ ReqParam
+ {
+ action_p_opt($1,2);
+ }
+ OptParam
+ {
+ action_last_opt($1);
+ }
+ ;
+</pre>
+
+<p>The actions are enclosed in braces, and are interspersed with the elements
+of the grammar.
+
+
+<p>The token <samp>COMMAND_2_OPT</samp> indicates that the lexer has found a command
+that takes two required arguments followed by an optional argument.
+The parser then performs some
+actions. The <samp>start_with_req</samp> function is the standard LTX2X function
+for the first action in a command production where the final argument
+is optional. The <samp>$1</samp> refers to the
+location of the particular command in the command table, and its value is passed to the
+parser by the lexer.
+
+
+<p>The parser then expects a required argument (i.e. <samp>{</samp>, token <samp>LBRACE</samp>)
+as the start of the required argument, followed by the text of the argument and
+finished off by a right brace (i.e. <samp>}</samp>, token <samp>RBRACE</samp>); the grammar
+for all of this is specified in the production called <samp>ReqParam</samp>). If it
+finds these it performs some further actions, otherwise it reports an
+error.
+In this case the action is defined by the function <samp>action_p_p1</samp>,
+which is the standard action performed between two required arguments
+(the second argument in the function call specifies the Pth argument that
+has been recognized). Another required argument is then expected.
+In this case the action is defined by the function <samp>action_p_opt</samp>,
+which is the standard action performed between the end of the Pth required argument
+and the start of an optional argument. It then looks for an optional
+argument, the grammar for which is specified in the production called
+<samp>OptParam</samp>. The final action is specified by the standard function
+<samp>action_last_opt</samp> for finishing off a command that ends with an
+optional argument.
+
+
+<p>The grammar for a command that that has two required arguments,
+and possibly an
+initial optional argument is similar:
+
+
+<p><pre>
+l2xComm2: COMMAND_2
+ {
+ start_with_opt($1);
+ }
+ OptParam
+ {
+ action_opt_first($1);
+ }
+ ReqParam
+ {
+ action_p_p1($1,1);
+ }
+ ReqParam
+ {
+ action_last_p($1,2);
+ }
+ ;
+</pre>
+
+<p>
+<h4>The support libraries</h4>
+
+
+<p>Source code for the C main program and support functions is in file
+<tt>l2xlib.c</tt>.
+ The main program is responsible for reading in the command table and calling the
+lexer and parser to do the appropriate processing.
+ The file also contains a variety of support functions that are, or could
+be, used in the lexer, parser, action library, or user-defined library.
+
+
+<p>The standard actions for the grammar are contained in file <tt>l2xacts.c</tt>.
+
+
+<p>
+<h4>The user-defined library</h4>
+
+
+<p>The intent of this library is that masochistic users can define their
+own functions for use within LTX2X when processing their <samp>SPECIAL_</samp>
+commands, without having to modify the LTX2X support or action libraries.
+
+
+<p>Source code for the user-defined library should be maintained in a file
+called <tt>l2xusrlb.c</tt> and a corresponding header file called <tt>l2xusrlb.h</tt>.
+
+
+<p>
+<h4>The EXPRESS-A interpreter</h4>
+
+
+<p>The EXPRESS-A interpreter is based on algorithms originally developed
+by Ronald Mak [<a href="#MAKR91">MAKR91</a>] for interpreting Pascal. His original
+algorithms have been modified and extended to cater for EXPRESS-A.
+The interpreter module has a minimal interface with the rest of the
+LTX2X system, and could easily be modified to be a stand-alone program
+(in fact it started that way in the first place). The interface
+between LTX2X and the interpreter is confined to the small
+<tt>l2xistup.c</tt> file.
+
+
+<p>
+
+<h2>The EXPRESS-A programming language</h2>
+ <a name="sec:expressa"></a>
+
+
+<p>EXPRESS is a language for information modeling and includes both
+declarative and procedural aspects [<a href="#EBOOK">EBOOK</a>]. There are also two other
+companion languages called respectively EXPRESS-G and EXPRESS-I. The former
+of these is a graphical form of the declaritive aspects of EXPRESS, and the
+later is an instiation and test case specification language. These languages
+are either ISO international standards [<a href="#EXPRESSIS">EXPRESSIS</a>] or on the way
+to becoming so [<a href="#EXPRESSITR">EXPRESSITR</a>].
+
+
+<p>Certain of the procedural aspects of EXPRESS and EXPRESS-I are relevent
+to the LTX2X concepts and so, together with some other reasons,
+it seemed appropriate to provide an interpreter for a similar language for
+use within LTX2X. EXPRESS-A provides a major subset of the EXPRESS procedural
+language, together with some Pascal-like additions for input and output.
+Of particular note, strings are a built-in type in EXPRESS-A. The language
+also supports three-valued logic and the concept of an `indeterminate'
+value of any type.
+
+
+<p>Earlier I gave an example command table to replace the text of a
+LaTeX document with the words `Goodbye document'. Here is
+an EXPRESS-A program that outputs `Goodbye document'.
+<pre>
+println('Goodbye document');
+END_CODE
+</pre>
+
+<p>The following gives a brief overview of EXPRESS-A. For more details
+consult Schenck &amp; Wilson [<a href="#EBOOK">EBOOK</a>].
+
+
+<p>
+<h3>Basic elements</h3>
+
+
+
+<p>EXPRESS-A is a case-insensitive language and uses the ASCII character
+set. Two kinds of comments are supported --- an end of line comment,
+which starts with a <samp>--</samp> pair and continues until the end of the current
+line --- and an extended comment. An extended comment starts with a
+<samp>(*</samp> pair and is ended by a matching <samp>*)</samp> pair; extended comments
+may be nested.
+
+
+<p>The language contains many reserved words, some of which are only
+applicable to the EXPRESS and EXPRESS-I languages.
+
+
+<p>Identifiers are composed of an initial letter, possibly followed by
+any number of letters, digits, and the underscore character.
+
+
+<p>Literals are self defining constant values. An integer literal consists
+of one or more digits, the first of which shall not be zero. Real numbers
+start with one or more digits, followed by a decimal point. Further
+digits may occur after the point, and finaly there may be an exponent
+in the `e' notation format (e.g., <samp>123.456e-78</samp>).
+
+
+<p>A string literal is any sequence of characters enclosed by single
+quote marks. If a single quote mark is meant to form part of the string,
+two quote marks must be used at that point.
+
+
+<p>Logical literals consists of one of these keywords: <samp>FALSE</samp>,
+<samp>UNKNOWN</samp> or <samp>TRUE</samp>.
+
+
+<p>EXPRESS-A also includes some other constants. <samp>PI</samp> stands
+for the value of the mathematical constant (3.1415...),
+and <samp>CONST_E</samp>
+stands for the value of the mathematical constant e (2.7182...),
+the base of natural logarithms. The special token <samp>?</samp> stands for
+an indeterminate value of any type. The three constants
+<samp>THE_DAY</samp>, <samp>THE_MONTH</samp> and <samp>THE_YEAR</samp> are integer
+values for the current date holding the day of the month (1--31), the
+month of the year (1--12) and the year (four digits), respectively.
+
+
+<p>
+
+<h3>Data types</h3>
+
+
+
+<p>EXPRESS-A is a typed language. The simple data types are: <samp>INTEGER</samp>,
+<samp>REAL</samp>, <samp>STRING</samp> and <samp>LOGICAL</samp>.
+
+
+<p>The aggregation data types are <samp>ARRAY</samp>, <samp>BAG</samp>, <samp>LIST</samp>,
+and <samp>SET</samp>. The array data type is of a fixed size and must have
+declared lower and upper bounds (index range), such as <samp>ARRAY [-7:10] OF</samp>.
+The other aggregate data types are dynamic in size, but may have lower and
+upper bounds specified for the number of elements, such as <samp>SET [2:5] OF</samp>,
+meaning a set that should have between two and five members. For the
+dynamic aggregates the upper bound may be given as <samp>?</samp>, which means
+an unlimited upper bound, such as <samp>LIST [2:?] OF</samp>. If a bound
+specification is absent, then the dynamic aggregate can hold from zero
+to any number of elements. (Footnote: The dynamic aggregates may not
+be fully implemented due to lack of time.)
+
+
+<p>Aggregates are one dimensional, but can be chained together for
+multi-dimensional aggregates, like
+<pre>
+ARRAY [1:4] OF LIST OF INTEGER;
+</pre>
+
+<p>The enumeration data type is a parenthesised comma seperated list of
+identifiers. These identifiers represent the values of the enumerated type;
+for instance
+<pre>
+ENUMERATION OF (red, green, blue)
+</pre>
+
+<p>A defined data type is one declared and named by the user using the
+<samp>TYPE</samp> and <samp>END_TYPE</samp> construct. For example
+<pre>
+TYPE length = REAL; END_TYPE;
+TYPE crowd_size = INTEGER; END_TYPE;
+TYPE signal_colour = ENUMERATION OF (red, amber, green); END_TYPE;
+</pre>
+
+<p>An entity data type consists of a list of attributes and their types, enclosed
+in a <samp>ENTITY</samp> and <samp>END_ENTITY</samp> pair. An entity type
+is named.
+<pre>
+ENTITY an_ent;
+ auditorium_width : length;
+ audience : crowd_size;
+ title : STRING;
+ profit : REAL;
+END_ENTITY;
+</pre>
+
+<p>EXPRESS-A provides for algorithms in the form of functions and procedures.
+
+
+<p>A <samp>FUNCTION</samp> is an algorithm that operates on parameters and returns
+a single resultant value of a specified data type. An invocation of a function
+in an expression evaluates to the resultant value at the point of invocation.
+For example:
+<pre>
+FUNCTION func (par1 : INTEGER; par2 : STRING) : STRING;
+ LOCAL
+ str : STRING;
+ -- other variable declarations
+ END_LOCAL;
+ -- the algorithm statements are here
+ RETURN(str);
+END_FUNCTION;
+</pre>
+Note that the parameters are typed.
+
+
+<p>A <samp>PROCEDURE</samp> is an algorithm that receives parameters from the
+point of invocation and operates on them in some manner. Changes to the parameters
+within the procedure are only reflected to the point of invocation
+when the formal parameter is preceded by the keyword <samp>VAR</samp>.
+For example:
+<pre>
+PROCEDURE proc (par1 : INTEGER; VAR par2 : STRING);
+ -- local declarations and the algorithm statements
+END_PROCEDURE;
+</pre>
+Note that the parameters are typed. In this case the value of <samp>par2</samp>
+may be changed.
+
+
+<p>Variables are declared in a local block, enclosed by the keywords
+<samp>LOCAL</samp> and <samp>END_LOCAL</samp>. A variable declaration consists
+of an identifer and its type, such as:
+<pre>
+LOCAL
+ str : STRING;
+ e1, e2 : an_ent; -- e1 and e2 are both of type an_ent
+ e3 : an_ent; -- so is e3
+ num : INTEGER;
+ col : signal_colour;
+ matrix : ARRAY [1:15] OF ARRAY [1:15] OF REAL;
+END_LOCAL;
+</pre>
+
+<p>The above declarations must be in the following order:
+<ol>
+
+
+ <li> <samp>ENTITY</samp> and/or <samp>TYPE</samp> declarations
+
+ <li> <samp>FUNCTION</samp> and/or <samp>PROCEDURE</samp> declarations
+
+ <li> a <samp>LOCAL</samp> declaration block
+</ol>
+
+
+
+<p>After the above can come any number of statements.
+
+
+<p>
+<h3>Statements</h3>
+
+
+
+<p>EXPRESS-A supports the following statements:
+<ul>
+
+
+ <li> Null statement
+
+ <li> Assignment statement
+
+ <li> Call statement
+
+ <li> <samp>BEGIN</samp> ... <samp>END</samp> compound statement
+
+ <li> <samp>CASE</samp> ... <samp>END_CASE</samp> statement
+
+ <li> <samp>IF</samp> ... <samp>THEN</samp> ... <samp>ELSE</samp>
+ ... <samp>END_IF</samp> statement
+
+ <li> <samp>REPEAT</samp> ... <samp>WHILE</samp> ... <samp>UNTIL</samp> ...
+ <samp>END_REPEAT</samp> statement. This also includes the
+ <samp>ESCAPE</samp> and <samp>SKIP</samp> statements
+
+ <li> <samp>RETURN</samp> statement
+</ul>
+
+
+
+<p>All the above statements are completed by a <samp>;</samp> (semicolon).
+The <em>null</em> statement just consists of a semicolon.
+
+
+<p>The <em>assignment</em> statement is used to assign an instance to a local
+variable or parameter. The data types must be compatible.
+<pre>
+LOCAL
+ a, b, c : REAL;
+END_LOCAL;
+...
+ a := 2.3E-6;
+ b := a;
+ a := -27.0;
+ c := 33.3*b;
+</pre>
+
+<p>The <em>call</em> statement invokes a procedure or a function. The actual
+parameters provided with the call must agree in number, order and type
+with the formal parameters specified in the procedure or function
+declaration. The supplied parameter values must be assignment compatible
+with the formal parameters. This is an example of calling the EXPRESS-A
+defined <samp>INSERT</samp> procedure which takes three parameters:
+<pre>
+INSERT(my_list, list_element, 0);
+</pre>
+
+<p>The <em>compound</em> statement consists of one or more statements enclosed
+between a <samp>BEGIN</samp> and <samp>END</samp> pair. The enclosed statements
+are treated as a single statement.
+<pre>
+...
+ BEGIN
+ a := 2.3e-7;
+ b := a;
+ c := b*33.3;
+ END;
+</pre>
+
+<p>The <em>case</em> statement is a means of selectively executing statements
+based on the value of an expresion.
+<pre>
+LOCAL
+ a : INTEGER;
+ x, y : REAL;
+END_LOCAL;
+...
+ a := 2;
+ x := 21.9;
+ CASE 2*a OF
+ 1 : x := SIN{x};
+ 2 : x := SQRT(x);
+ 3 : x := LOG(x);
+ 4 : x := COS(x); -- this is executed
+ 5, 6 : y := y**x;
+ OTHERWISE : x := 0.0;
+ END_CASE;
+</pre>
+The integer expression following the <samp>CASE</samp> keyword is evaluated.
+The result is compared to the values of the case labels and the
+statement following the first matching label is executed. Execution then
+continues at the statement following the <samp>END_CASE;</samp>. If no
+label matches, then no statements within the case block are executed,
+except if an <samp>OTHERWISE</samp> label is included, which will match
+anything. All other labels are examined before looking for the
+<samp>OTHERWISE</samp>.
+
+
+<p>The <em>if ... then ... else</em> statement allows the conditional
+execution of statements depending on the value of a <samp>LOGICAL</samp>
+expression. When the expression evaluates to <samp>TRUE</samp> the statement(s)
+following the <samp>THEN</samp> are executed, after which control passes
+to the statement following the closing <samp>END_IF</samp>. When the logical
+expression evaluates to <samp>FALSE</samp> or <samp>UNKNOWN</samp> the <samp>THEN</samp>
+statements are jumped over and execution starts at the statement(s) following
+the <samp>ELSE</samp> keyword if present, or at the statement following
+the <samp>END_IF</samp> keyword.
+<pre>
+IF a > 20 THEN
+ b := a + 2;
+ c := c - 1;
+ELSE
+ IF a > 10 THEN
+ b := a + 1;
+ ELSE
+ c := c + 1;
+ END_IF;
+END_IF;
+</pre>
+
+<p>The <em>repeat</em> statement is used to control the conditional repetition
+of a series of statements. The control conditions are:
+<ul>
+
+
+ <li> finite iteration until an integer expression reaches a specified
+ value;
+
+ <li> <samp>WHILE</samp> a logical condition is <samp>TRUE</samp>;
+
+ <li> <samp>UNTIL</samp> a logical condition is <samp>TRUE</samp>.
+</ul>
+
+<pre>
+REPEAT i := 100 TO 0 BY -7 WHILE r >= 0.0 UNTIL err < 1.0e-8;
+ ...
+ r := ...;
+ err := ...;
+END_REPEAT;
+</pre>
+At entry to the <samp>REPEAT</samp> statement the iteration variable is
+initialized to the first bound. If the variable less than or equal to the
+<samp>TO</samp> bound and the increment is positive, or the variable is less
+than the <samp>TO</samp> bound and the increment is negative, processing
+jumps to after the <samp>END_REPEAT</samp>, otherwise processing continues.
+The <samp>WHILE</samp> condition is checked and if
+<samp>TRUE</samp> then the statements in the body are executed. After
+these have been executed the <samp>UNTIL</samp> condition is checked. If this
+is not <samp>TRUE</samp> then processing continues by incrementing the iteration
+variable by either unity or by the <samp>BY</samp> value if present. The whole
+process then starts again with the checking of the iteration variable
+against the <samp>TO</samp> bound.
+
+
+<p>All three types of controls are optional. If none are given then the
+<samp>REPEAT</samp> statement will loop for ever. The <em>escape</em> statement
+causes an immediate transfer out of the <samp>REPEAT</samp> statement
+in which it occurs. The <em>skip</em> statement causes a jump to the
+end of the <samp>REPEAT</samp> statement in which it occurs (i.e., to the point
+where the <samp>UNTIL</samp> expression is tested).
+<pre>
+REPEAT UNTIL (a = 1);
+ ...
+ IF a = 0 THEN
+ ESCAPE;
+ END_IF;
+ ...
+ IF a > 10 THEN
+ SKIP;
+ END_IF;
+ ...
+ ...
+-- SKIP transfers control to here
+END_REPEAT;
+ -- ESCAPE transfers control to here
+</pre>
+
+<p>The <em>return</em> statement terminates the execution of a <samp>FUNCTION</samp>
+or <samp>PROCEDURE</samp>. The <samp>RETURN</samp> statement within a function
+must specify an expression, the value of which is the value returned
+by the function. A <samp>RETURN</samp> in a procedure must not specify an
+expression.
+<pre>
+RETURN(a <> b); -- example for within a function
+RETURN; -- example for within a procedure
+</pre>
+
+<p>
+<h3>Expressions</h3>
+
+
+
+<p>Expressions are combinations of operators, operands and function calls
+which are evaluated to produce a value. The simplest expression is
+either a literal value or the name of a variable.
+
+
+<p>
+<h4>Arithmetic operators</h4>
+
+
+<p>The arithmetic operators act on number values and produce a number
+result. If any operand
+is indeterminate (i.e., <samp>?</samp>) then the result is also
+indeterminate. The operators are:
+<dl>
+<dt>Unary
+<dd> The operators <samp>+</samp> and <samp>-</samp>, the latter of which
+negates its following operand.
+<dt>Binary
+<dd> Addition (<samp>+</samp>),
+ subtraction (<samp>-</samp>),
+ multiplication (<samp>*</samp>),
+ real division (<samp>/</samp>),
+ exponentiation (<samp>**</samp>),
+ integer division (<samp>DIV</samp>),
+ and modulo (<samp>MOD</samp>).
+</dl>
+
+
+<p>
+<h4>Relational operators</h4>
+
+
+<p>The result of a relational expression is a <samp>LOGICAL</samp> value.
+If either operand is indeterminate, the expression evaluates to
+<samp>UNKNOWN</samp>.
+
+
+<p><dl>
+<dt>Value comparison
+<dd> Equal (<samp>=</samp>),
+ not equal (<samp><></samp>),
+ greater than (<samp>></samp>),
+ less than (<samp><</samp>),
+ greater than or equal (<samp>>=</samp>), and
+ less than or equal (<samp><=</samp>).
+
+
+<p><dt>Membership
+<dd> The <samp>IN</samp> operator tests an item for membership
+in a dynamic aggregate (e.g., <samp>IF fred IN mylist THEN ...</samp>).
+
+
+<p><dt>Matching
+<dd> The <samp>LIKE</samp> operator compares a string against a pattern,
+evaluating to <samp>TRUE</samp> if they match. The pattern characters are:
+ <ul>
+
+
+ <li> <samp>@</samp> Matches any letter.
+
+ <li> <samp>^</samp> Matches any upper-case letter.
+
+ <li> <samp>?</samp> Matches any character.
+
+ <li> <samp>&</samp> Matches remainder of string.
+
+ <li> <samp>#</samp> Matches any digit.
+
+ <li> <samp>$</samp> Matches a substring terminated by a space character
+ or end-of-string.
+
+ <li> <samp>*</samp> Matches any number of characters.
+
+ <li> <samp>\</samp> Begins a pattern escape sequence.
+
+ <li> <samp>!</samp> Negation character (used with the other characters).
+
+ <li> Any other character matches itself.
+ </ul>
+
+
+
+<p>Some examples:
+ <ul>
+
+
+ <li> <samp>'The quick red fox' LIKE '$$$$'</samp> is <samp>TRUE</samp>.
+
+ <li> <samp>'Page 231' LIKE '$ ###'</samp> is <samp>TRUE</samp>.
+
+ <li> <samp>'Page 27' LIKE 'Page ###'</samp> is <samp>FALSE</samp>.
+
+ <li> <samp>'\aaaa' LIKE '\\aaaa'</samp> is <samp>TRUE</samp>.
+
+ <li> <samp>'\aaaa' LIKE '\aaaa'</samp> is <samp>FALSE</samp>.
+
+ <li> <samp>'aaaa' LIKE 'a@@a'</samp> is <samp>TRUE</samp>.
+ </ul>
+
+
+
+<p></dl>
+
+
+<p>
+<h4>Logical operators</h4>
+
+
+<p>The logical operators produce a logical result. Except for the
+<samp>NOT</samp> operator which takes one logical operand (e.g., <samp>NOT op</samp>),
+they take two logical operands (e.g., <samp>op1 XOR op2</samp>).
+
+
+<p>The evaluation of the <samp>NOT</samp> operator is given in table <a href="#tab:not">tab:not</a>.
+
+
+<p><center><table border>
+<caption>The NOT logical operator</caption> <a name="tab:not">(Table tab:not)</a>
+
+<tr><td> Operand value </td><td > Result value </tr>
+<tr><td > <samp>TRUE</samp> </td><td > <samp>FALSE</samp> </tr>
+<tr><td >
+<samp>UNKNOWN</samp> </td><td > <samp>UNKNOWN</samp> </tr>
+<tr><td >
+<samp>FALSE</samp> </td><td > <samp>TRUE</samp> </tr>
+<tr><td >
+</table></center>
+
+
+<p>The evaluation of the <samp>AND</samp>, <samp>OR</samp> and <samp>XOR</samp> operators
+is given in table <a href="#tab:andorxor">tab:andorxor</a>.
+
+
+<p><center><table border>
+<caption>The AND, OR and XOR logical operators</caption>
+<a name="tab:andorxor">(Table tab:andorxor)</a>
+
+<tr><td> Op1 </td><td > Op2 </td><td > Op1 <samp>AND</samp> Op2 </td><td > Op1 <samp>OR</samp> Op2 </td><td > Op1 <samp>XOR</samp> Op2 </tr>
+<tr><td > <samp>TRUE</samp> </td><td > <samp>TRUE</samp> </td><td > <samp>TRUE</samp> </td><td > <samp>TRUE</samp> </td><td > <samp>FALSE</samp> </tr>
+<tr><td >
+<samp>TRUE</samp> </td><td > <samp>UNKNOWN</samp> </td><td > <samp>UNKNOWN</samp> </td><td > <samp>TRUE</samp> </td><td > <samp>UNKNOWN</samp> </tr>
+<tr><td >
+<samp>TRUE</samp> </td><td > <samp>FALSE</samp> </td><td > <samp>FALSE</samp> </td><td > <samp>TRUE</samp> </td><td > <samp>TRUE</samp> </tr>
+<tr><td >
+<samp>UNKNOWN</samp> </td><td > <samp>TRUE</samp> </td><td > <samp>UNKNOWN</samp> </td><td > <samp>TRUE</samp> </td><td > <samp>UNKNOWN</samp> </tr>
+<tr><td >
+<samp>UNKNOWN</samp> </td><td > <samp>UNKNOWN</samp> </td><td > <samp>UNKNOWN</samp> </td><td > <samp>UNKNOWN</samp> </td><td > <samp>UNKNOWN</samp> </tr>
+<tr><td >
+<samp>UNKNOWN</samp> </td><td > <samp>FALSE</samp> </td><td > <samp>FALSE</samp> </td><td > <samp>UNKNOWN</samp> </td><td > <samp>UNKNOWN</samp> </tr>
+<tr><td >
+<samp>FALSE</samp> </td><td > <samp>TRUE</samp> </td><td > <samp>FALSE</samp> </td><td > <samp>TRUE</samp> </td><td > <samp>TRUE</samp> </tr>
+<tr><td >
+<samp>FALSE</samp> </td><td > <samp>UNKNOWN</samp> </td><td > <samp>FALSE</samp> </td><td > <samp>UNKNOWN</samp> </td><td > <samp>UNKNOWN</samp> </tr>
+<tr><td >
+<samp>FALSE</samp> </td><td > <samp>FALSE</samp> </td><td > <samp>FALSE</samp> </td><td > <samp>FALSE</samp> </td><td > <samp>FALSE</samp> </tr>
+<tr><td >
+</table></center>
+
+
+<p>
+<h4>Miscellaneous</h4>
+
+
+<p><dl>
+
+
+<p><dt>Function call
+<dd> A function may be called without the result necessarily
+being assigned to a variable. If <samp>fun</samp> is a function with two
+arguments (for simplicitly integer arguments) and returning a logical
+value, then
+<pre>
+log := fun(i1, i2);
+fun(i3, 24*i4);
+</pre>
+are both legitimate calls.
+
+
+<p>
+<dt>Dot operator
+<dd> The dot operator is used to access an attribute from an
+entity. If <samp>ent</samp> is an <samp>ENTITY</samp> type with an attribute
+<samp>att</samp>, then <samp>ent.attr</samp> evaluates to the value of the
+<samp>attr</samp> attribute within the <samp>ent</samp>.
+
+
+<p><dt>String operators
+<dd> <br>
+ The <samp>+</samp> operator takes two strings as
+its operands and evaluates to the string that is the concatenation of its
+operands. For example:
+<pre>
+str1 := 'string1';
+str2 := 'string2';
+str1 := str1 + str2;
+-- str1 = 'string1string2' is TRUE
+</pre>
+
+<p>The substring operator <samp>[i1:i2]</samp> is a postfix operator that when
+applied to a string, evalutes to the string whose characters are composed
+of the <samp>i1</samp>'th through the <samp>i2</samp>'th characters, inclusively,
+of its operand. Note that <samp>i2</samp> must be greater than or equal to
+<samp>i1</samp>, and both must be within the limits of the number of characters
+in the string. For example:
+<pre>
+str1 := 'string';
+str2 := str1[2:4];
+str1 := str1 + str2;
+-- str1 = 'tristring' is TRUE
+</pre>
+
+<p><dt>Aggregate operators
+<dd> <br>
+ The index operator <samp>[i]</samp> is a postfix operator that can be applied
+to an aggregate operand; the expression evaluates to the value of the
+aggregate at the index position. For example, if <samp>lagg</samp> is a
+list of integers:
+<pre>
+insert(lagg, 20, 0);
+insert(lagg, 40, 0);
+insert(lagg, 60, 0);
+insert(lagg, 80, 0);
+-- lagg[2] = 60 is TRUE
+</pre>
+
+<p><dt>Interval expression
+<dd> <br>
+ An <em>interval expression</em> is a <samp>LOGICAL</samp> expression
+consisting of three operands and two operators. It has the form:
+<pre>
+{ low op1 test op2 high }
+</pre>
+where <samp>op1</samp> and <samp>op2</samp> are either of the two relational
+operators <samp><</samp> or <samp><=</samp>, and <samp>low</samp>, <samp>test</samp> and
+<samp>high</samp> are expressions of the same type. The interval expression
+is equivalent to:
+<pre>
+((low op1 test) AND (test op2 high))
+</pre>
+The value of the interval expression is given by
+<ol>
+
+
+ <li> If any operand is indeterminate, then it evauates to <samp>UNKNOWN</samp>.
+
+ <li> If either of the logical relationships evaluates to <samp>FALSE</samp>,
+ then it evauates to <samp>FALSE</samp>.
+
+ <li> If both logical relationships evalute to <samp>TRUE</samp>,
+ then it evauates to <samp>TRUE</samp>.
+
+ <li> Otherwise it evaluates to <samp>UNKNOWN</samp>.
+</ol>
+
+For example:
+<pre>
+i := 10;
+{1 <= i < 20} -- is TRUE
+{1 <= i < 10} -- is FALSE
+i := ?;
+{1 <= i < 10} -- is UNKNOWN
+</pre>
+
+<p>
+</dl>
+
+
+<p>
+
+<h3>Built in procedures and functions</h3>
+
+
+
+<p>
+<h4>Procedures</h4>
+
+
+<p>The following procedures are an integral part of EXPRESS-A. They are
+shown as signatures to inidicate the data types of the formal parameters.
+For convenience, <samp>GENERIC</samp> is used to indicate any type.
+
+
+<p><ul>
+
+
+ <li> <samp>INSERT (VAR L:LIST OF GENERIC; E:GENERIC; P:INTEGER)</samp> <br>
+ <samp>INSERT</samp> inserts the element <samp>E</samp> into a list
+<samp>L</samp> at position <samp>P</samp>. The insertion follows the existing
+element at <samp>P</samp>, so that if <samp>P=0</samp>, <samp>E</samp> will
+become the first element.
+
+
+<p>
+ <li> <samp>REMOVE (VAR L:LIST OF GENERIC; P:INTEGER)</samp> <br>
+ <samp>REMOVE</samp> modifies the list <samp>L</samp> by deleting the
+element at position <samp>P</samp>.
+
+
+<p>
+ <li> <samp>SYSTEM (V:STRING)</samp> <br>
+ <samp>SYSTEM</samp> passes the string <samp>V</samp> to the operating system.
+This is typically used to get the operating system to perform some action.
+
+
+<p>
+ <li> <samp> READ(VAR V1, V2,...:GENERIC)</samp>, <samp>READLN(VAR V1, V2,...:GENERIC)</samp> <br>
+ These two procedures are similar to the Pascal procedures of the same
+ name and put data from standard input into the variable(s)
+ <samp>V1</samp>, etc.
+
+
+<p>The argument is a comma-seperated list of variables. The variables may be
+ of different types, but the types are limited to
+ <samp>INTEGER</samp>,
+ <samp>REAL</samp>,
+ <samp>LOGICAL</samp>, and
+ <samp>STRING</samp>.
+ The procedure gets the next value of the variable's type from standard input
+ and assigns it to the variable. An integer is recognised as a set of digits,
+ optinally preceeded by a sign. A real is in either decimal or scientific
+ notation (e.g., <samp>12.34</samp> or <samp>1.234e1</samp>). A logical is <samp>TRUE</samp>,
+ <samp>FALSE</samp> or <samp>UNKNOWN</samp> (case independent, so <samp>TRUE</samp> could also
+ be <samp>tRuE</samp>). A string is
+ any non-empty set of characters ended by white space (e.g., <samp>string </samp>
+ is one string but <samp>ball of str8 string </samp> is four strings). The difference
+ between <samp>READ</samp> and <samp>READLN</samp> is that the former performs the
+ actions described above, while the latter will discard any remaining characters
+ in the input line after processing its arguments.
+
+
+<p>
+
+ <li> <samp> WRITE(format)</samp>, <samp>WRITELN(format)</samp> <br>
+ These two procedures are similar to the Pascal procedures of the same name.
+ They write data to standard output.
+
+
+<p>The <samp>format</samp> consists of a comma-seperated list of variables with
+ optional spacing specifications. The variable types may be
+ <samp>INTEGER</samp>,
+ <samp>REAL</samp>,
+ <samp>LOGICAL</samp>, or
+ <samp>STRING</samp>.
+ The <samp>LOGICAL</samp> and <samp>STRING</samp> types take no spacing declarations.
+ An <samp>INTEGER</samp> variable can take one optional space specification which
+ is an integer number specifying the minimum field width for printing the value
+ (e.g., <samp>int:6</samp> to specify a minimum field width of 6 characters).
+ A <samp>REAL</samp> variable can take two optional space specifications. The
+ first is the field width and the second is the number of digits to be printed
+ (e.g., <samp>r:10:5</samp> for printing with a field width of 10 characters
+ and to a pecision of 5 digits). For example:
+<pre>
+BEGIN_LOCAL
+ int : INTEGER;
+ r : REAL;
+ log : LOGICAL;
+ str : STRING;
+END_LOCAL;
+ int := 23;
+ r := 23.0;
+ log := true;
+ str := 'This is a string.';
+WRITE('Example', int, r:10:5, ' ', log, ' ', str);
+</pre>
+will produce:
+<pre>
+Example 23 23.000 TRUE This is a string.
+</pre>
+
+<p>The difference between <samp>WRITE</samp> and <samp>WRITELN</samp> is that the latter
+ will end the output line after it has output the values of its arguments.
+ (<samp>WRITELN</samp> need take no arguments, in which case it justs ends the current
+ output line).
+
+
+<p>
+ <li> <samp> PRINT(format)</samp>, <samp>PRINTLN(format)</samp> <br>
+ These <samp>PRINT</samp> procedures are the same as the
+ <samp>WRITE</samp> procedures, except that they send the data
+ to the current LTX2X output destination.
+
+
+<p></ul>
+
+
+
+<p>
+<h4>Functions</h4>
+
+
+<p>The following functions are supplied as part of EXPRESS-A. They are
+exhibited as signatures to show the formal parameters. For convenience,
+<samp>NUMBER</samp> is being used to denote either an <samp>INTEGER</samp> or a
+<samp>REAL</samp> number.
+
+
+<p><ul>
+
+
+ <li> <samp>ABS (V:NUMBER) : NUMBER;</samp> <br>
+ <samp>ABS</samp> returns the absolute value of its argument.
+
+ <li> <samp>COS (V:NUMBER) : REAL;</samp> <br>
+ Returns the cosine of an an angle specified in radians.
+
+ <li> <samp>EOF () : LOGICAL;</samp> <br>
+ Returns <samp>TRUE</samp> if the next character from standard input
+ is `end-of-file', otherwise it returns <samp>FALSE</samp>.
+
+ <li> <samp>EOLN () : LOGICAL;</samp> <br>
+ Returns <samp>TRUE</samp> if the next character from standard input
+ is `end-of-line', otherwise it returns <samp>FALSE</samp>.
+
+ <li> <samp>EXISTS (V:GENERIC) : LOGICAL;</samp> <br>
+ The function <samp>EXISTS</samp> returns <samp>FALSE</samp> if its
+ argument is indeterminate or does not exist, otherwise it returns
+ <samp>TRUE</samp>.
+
+ <li> <samp>EXP (V:NUMBER) : REAL;</samp> <br>
+ Returns e (the base of natural logarithms (<samp>CONST_E</samp>))
+ raised to the power of <samp>V</samp>.
+
+ <li> <samp>HIBOUND (V:AGGREGATE OF GENERIC) : INTEGER;</samp> <br>
+ <samp>HIBOUND</samp> returns the declared upper index of an <samp>ARRAY</samp>
+ or the declared upper bound of a
+ <samp>BAG</samp>, <samp>LIST</samp> or <samp>SET</samp>.
+
+ <li> <samp>HIINDEX (V:AGGREGATE OF GENERIC) : INTEGER;</samp> <br>
+ <samp>HIINDEX</samp> returns the declared upper index of an <samp>ARRAY</samp>
+ or the number of elements in a
+ <samp>BAG</samp>, <samp>LIST</samp> or <samp>SET</samp>.
+
+ <li> <samp>LENGTH (V:STRING) : INTEGER;</samp> <br>
+ Returns the number of characters in its argument.
+
+ <li> <samp>LOBOUND (V:AGGREGATE OF GENERIC) : INTEGER;</samp> <br>
+ <samp>LOBOUND</samp> returns the declared lower index of an <samp>ARRAY</samp>
+ or the declared lower bound of a
+ <samp>BAG</samp>, <samp>LIST</samp> or <samp>SET</samp>.
+
+ <li> <samp>LOG (V:NUMBER) : REAL;</samp> <br>
+ Returns the natural logarithm of its argument.
+
+ <li> <samp>LOG2 (V:NUMBER) : REAL;</samp> <br>
+ Returns the base 2 logarithm of its argument.
+
+ <li> <samp>LOG10 (V:NUMBER) : REAL;</samp> <br>
+ Returns the base 10 logarithm of its argument.
+
+ <li> <samp>LOINDEX (V:AGGREGATE OF GENERIC) : INTEGER;</samp> <br>
+ <samp>LOINDEX</samp> returns the declared lower index of an <samp>ARRAY</samp>
+ or the value 1 for a
+ <samp>BAG</samp>, <samp>LIST</samp> or <samp>SET</samp>.
+
+
+<p>The <samp>..INDEX</samp> functions are useful for iterating over
+ aggregates. For example, if <samp>lagg</samp> is a list of integer,
+ then all the elements can be printed out as a comma-seperated
+ list enclosed in parentheses by:
+<pre>
+writeln;
+write('lagg = (');
+REPEAT i := LOINDEX(lagg) TO HIINDEX(lagg);
+ IF (i = HIINDEX(lagg)) THEN write(lagg[i]:1);
+ ELSE write(lagg[i]:1, ', ');
+ END_IF;
+END_REPEAT;
+writeln(')');
+</pre>
+
+ <li> <samp>NVL (V:GENERIC; SUBS:GENERIC) : GENERIC;</samp> <br>
+ If the argument <samp>V</samp> exists then it is returned, otherwise
+ the argument <samp>SUBS</samp> is returned. Both arguments must be
+ of the same type.
+
+ <li> <samp>ODD (V:INTEGER) : LOGICAL;</samp> <br>
+ Returns <samp>TRUE</samp> or <samp>FALSE</samp> depending on whether or not
+ its argument is odd or even.
+
+ <li> <samp>REXPR (V:STRING; E:STRING) : LOGICAL;</samp> <br>
+ This function tests whether the <samp>V</samp> string parameter
+ matches a regular expression <samp>E</samp>. <samp>REXPR</samp>
+ returns <samp>TRUE</samp> if there is a match, <samp>FALSE</samp>
+ if there is not a match, or <samp>UNKNOWN</samp> if the regular
+ expression is ill-formed.
+
+
+<p>In the regular expression, most characters stand for themselves,
+ but <samp>\</samp> can be used to escape any of the meta-characters.
+ <ul>
+
+
+ <li> The meta-characters <samp>(</samp> and <samp>)</samp> are used for
+ grouping sub-expressions.
+
+ <li> <samp>|</samp> between expressions means one or the other.
+
+ <li> <samp>+</samp> following an expression means match one or more times.
+
+ <li> <samp>*</samp> following an expression means match zero or more times.
+
+ <li> <samp>?</samp> following an expression means match zero or one times.
+
+ <li> <samp>[...]</samp> is an expression indicating that any of the enclosed
+ characters are acceptable.
+
+ <li> <samp>[^...]</samp> is an expression indicating that any characters
+ except those enclosed are acceptable.
+
+ <li> Within a bracket expression a range of characters can be
+ specified by providing the first and last with a seperating hyphen.
+ For instance, <samp>[a-zA-Z]</samp> will match any alphabetic character.
+ </ul>
+
+
+
+<p>Some examples:
+ <ul>
+
+
+ <li> <samp>[a-zA-Z]+</samp> match one or more letters.
+
+ <li> <samp>[0-9]+.[0-9]+([eE][\-\+]?[0-9]+)?</samp> match a floating
+ point number <br>
+ (e.g., <samp>1.23e-27</samp> or <samp>0.987</samp>)
+
+ <li> <samp>[a-zA-Z][0-9a-zA-Z_]*</samp> match an EXPRESS-A variable.
+
+ <li> <samp>[^0-9a-zA-Z]</samp> match anything except letters or digits.
+
+ <li> <samp>(I|i)(F|f)</samp> case insensitive match for the word <samp>IF</samp>.
+ </ul>
+
+
+
+<p>
+ <li> <samp>ROUND (V:NUMBER) : INTEGER;</samp> <br>
+ Returns the nearest integer to its argument value.
+
+ <li> <samp>SIN (V:NUMBER) : REAL;</samp> <br>
+ Returns the sine of an an angle specified in radians.
+
+ <li> <samp>SIZEOF (V:AGGREGATE OF GENERIC) : INTEGER;</samp> <br>
+ <samp>SIZEOF</samp> returns the number of elements in its argument.
+ When <samp>V</samp> is an <samp>ARRAY</samp> this is the declared number
+ of elements. When <samp>V</samp> is a
+ <samp>BAG</samp>, <samp>LIST</samp> or <samp>SET</samp> this is the actual
+ number of elements.
+
+ <li> <samp>SQRT (V:NUMBER) : REAL;</samp> <br>
+ Returns the square root of its argument.
+
+ <li> <samp>TAN (V:NUMBER) : REAL;</samp> <br>
+ Returns the tangent of an an angle specified in radians.
+
+ <li> <samp>TRUNC (V:NUMBER) : INTEGER;</samp> <br>
+ Chops off any decimal part of its argument, returning the corresponding
+ integer value.
+
+
+<p></ul>
+
+
+
+<p>
+
+<h3>Source level debugger</h3>
+ <a name="sec:sld"></a>
+
+
+<p>The EXPRESS-A interpreter includes a source level debugger for
+use when your code appears to be misbehaving. When in operation the
+debugger will prompt for a command to be entered. It understands
+the following commands.
+
+
+<p><ul>
+
+
+ <li> <samp>&lt;return&gt;</samp> Continue processing.
+
+ <li> <samp>break</samp> <samp>&lt;number&gt;</samp> Place a breakpoint at the statement
+ on line <samp>&lt;number&gt;</samp>.
+
+ <li> <samp>break</samp> Print the line numbers of all the breakpoints.
+
+ <li> <samp>unbreak</samp> <samp>&lt;number&gt;</samp> Remove the breakpoint from line
+ <samp>&lt;number&gt;</samp>.
+
+ <li> <samp>unbreak</samp> Remove all breakpoints.
+
+ <li> <samp>trace</samp> Turn on statement tracing.
+
+ <li> <samp>untrace</samp> Turn off statement tracing.
+
+ <li> <samp>entry</samp> Turn on tracing of entry to procedures and functions.
+
+ <li> <samp>unentry</samp> Turn off entry tracing.
+
+ <li> <samp>exit</samp> Turn on tracing of exits from procedures and functions.
+
+ <li> <samp>unexit</samp> Turn off exit tracing.
+
+ <li> <samp>traceall</samp> Turn on all tracing.
+
+ <li> <samp>untraceall</samp> Turn off all tracing.
+
+ <li> <samp>stack</samp> Turn on display of the runtime stack accesses.
+
+ <li> <samp>unstack</samp> Turn off stack display.
+
+ <li> <samp>step</samp> Turn on single-stepping.
+
+ <li> <samp>unstep</samp> Turn off single stepping.
+
+ <li> <samp>fetch</samp> <samp>&lt;variable&gt;</samp> Print data fetches for
+ <samp>&lt;variable&gt;</samp>.
+
+ <li> <samp>store</samp> <samp>&lt;variable&gt;</samp> Print data stores for
+ <samp>&lt;variable&gt;</samp>.
+
+ <li> <samp>watch</samp> <samp>&lt;variable&gt;</samp> Print both data fetches and
+ stores for <samp>&lt;variable&gt;</samp>.
+
+ <li> <samp>watch</samp> Print the names of all variables being watched.
+
+ <li> <samp>unwatch</samp> <samp>&lt;variable&gt;</samp> Remove the watch from
+ <samp>&lt;variable&gt;</samp>.
+
+ <li> <samp>unwatch</samp> Remove all watches.
+
+ <li> <samp>show</samp> <samp>&lt;expression&gt;</samp> Print the value of
+ the EXPRESS-A expresion <samp>&lt;expression&gt;</samp>. The variables
+ in the expression must have been declared in the EXPRESS-A code.
+ For example:
+<pre>
+show (23.0 + LOG(num))/(PI*r**2)
+</pre>
+
+ <li> <samp>assign</samp> <samp>&lt;variable := expression&gt;</samp> Assign the value
+ of <samp>&lt;expression&gt;</samp> to the EXPRESS-A variable <samp>&lt;variable&gt;</samp>.
+ For example:
+<pre>
+assign num := SIN(theta/300.0)
+</pre>
+
+ <li> <samp>where</samp> Print the current line number and the text of the
+ next statement to be executed.
+
+ <li> <samp>kill</samp> Terminate the execution of the LTX2X program.
+</ul>
+
+
+
+<p>
+<h3>Example EXPRESS-A code</h3>
+
+
+
+<p>The following demonstrates most of the functionality of EXPRESS-A.
+Most of this is not particularly interesting, except possibly for the
+algorithms for calculating the date of Easter and for generating
+magic squares.
+
+
+<p><pre>
+ c= fun.ct Test of CODE ltx2x
+
+CODE_SETUP=
+ ENTITY ent;
+ attr1, attr3 : INTEGER;
+ attr2 : STRING;
+ END_ENTITY;
+
+ TYPE joe = INTEGER;
+ END_TYPE;
+
+ TYPE colour = ENUMERATION OF (red, blue, green);
+ END_TYPE;
+
+
+PROCEDURE easter;
+(* calculates the date of Easter for the present year
+ The algorithm can be applied to any year between
+ 1900 and 2099 inclusive, but if so, then the year
+ should be checked to ensure that it is within this range. *)
+ LOCAL
+ n, a, b, m, q, w : INTEGER;
+ day : INTEGER;
+ month : STRING;
+ END_LOCAL;
+
+ n := THE_YEAR - 1900;
+ a := n MOD 19;
+ b := (7*a + 1) DIV 19;
+ m := (11*a + 4 - b) MOD 29;
+ q := n DIV 4;
+ w := (n + q + 31 - m) MOD 7;
+ day := 25 - m - w;
+ month := 'April';
+ IF (day < 1) THEN
+ month := 'March';
+ day := day + 31;
+ END_IF;
+ writeln('In ', THE_YEAR:1, ' Easter is on ', month, day:3);
+END_PROCEDURE;
+
+
+FUNCTION magic_square(order:INTEGER): LOGICAL;
+(* calculates magic squares from order 1 through 15.
+ The order must be an odd number. *)
+ LOCAL
+ row, col, num : INTEGER;
+ sqr_order : INTEGER;
+ magic : ARRAY[1:15] OF ARRAY[1:15] OF INTEGER;
+ END_LOCAL;
+
+ IF (order > 15) THEN -- only squares up to order 15
+ RETURN(FALSE);
+ ELSE
+ IF (order < 1) THEN -- squares have at least one entry
+ RETURN(FALSE);
+ ELSE
+ IF (NOT ODD(order)) THEN -- squares are odd
+ RETURN(FALSE);
+ END_IF;
+ END_IF;
+ END_IF;
+
+ sqr_order := order**2;
+ row := 1;
+ col := (order + 1) DIV 2;
+ REPEAT num := 1 TO sqr_order;
+ magic[row][col] := num;
+ IF ((num MOD order) <> 0) THEN
+ IF (row = 1) THEN row := order; ELSE row := row - 1; END_IF;
+ IF (col = order) THEN col := 1; ELSE col := col + 1; END_IF;
+ ELSE
+ IF (num <> sqr_order) THEN row := row + 1; END_IF;
+ END_IF;
+ END_REPEAT;
+
+ writeln(Magic square of order ',order:2);
+ REPEAT row := 1 TO order;
+ REPEAT col := 1 TO order;
+ write(magic[row][col]:4);
+ END_REPEAT;
+ writeln;
+ END_REPEAT;
+ writeln;
+
+ RETURN(TRUE);
+END_FUNCTION;
+
+FUNCTION month(mnum:INTEGER) : STRING;
+(* Given an integer representing the month in a year,
+ returns the name of the month. *)
+LOCAL
+ str : STRING;
+END_LOCAL;
+
+ CASE mnum OF
+ 1 : str := 'January';
+ 2 : str := 'February';
+ 3 : str := 'March';
+ 4 : str := 'April';
+ 5 : str := 'May';
+ 6 : str := 'June';
+ 7 : str := 'July';
+ 8 : str := 'August';
+ 9 : str := 'September';
+ 10 : str := 'October';
+ 11 : str := 'November';
+ 12 : str := 'December';
+ OTHERWISE : str := '';
+ END_CASE;
+RETURN(str);
+END_FUNCTION;
+
+ LOCAL
+ a : array[1:3] of integer;
+ lagg : list [0:5] of integer;
+ a23 : array[1:2] of array[1:3] of integer;
+ i, n : integer;
+ s1, s2 : string;
+ b : logical;
+ r1, r2 : real;
+ nega : array[-3:-1] of integer;
+ posa : array[3:5] of integer;
+ j : joe;
+ ex : ent;
+ END_LOCAL;
+
+ -- start with a massive compound statement
+ BEGIN
+
+ writeln;
+ println;
+
+ (* write today's date *)
+ writeln('Today is ', THE_DAY:1, ' ', month(THE_MONTH), ' ', THE_YEAR:1);
+ writeln;
+
+ (* The user might be interested in Easter *)
+ easter;
+ writeln;
+
+ (* Call some math functions *)
+ r1 := PI/4;
+ writeln('r1 = PI/4 (0.78539...)', r1);
+ writeln('cos(r1) (0.70710...)', cos(r1));
+ writeln('sin(r1) (0.70710...)', sin(r1));
+ writeln('tan(r1) (1.0)', tan(r1));
+
+ r1 := CONST_E;
+ writeln('r1 = CONST_E (2.7182...)', r1);
+ writeln('log(4.5) (1.50407...)', log(4.5));
+ writeln('log2(8) (3.0)', log2(8));
+ writeln('log10(10) (1.0)', log10(10));
+
+ r2 := exp(10);
+ writeln('exp(10) (2.203...e4)', r2);
+
+ r2 := sqrt(121);
+ writeln('sqrt(121) (11.0)', r2);
+
+ (* populate and print some arrays *)
+ writeln;
+ posa[3] := 10;
+ posa[4] := 20;
+ posa[5] := 30;
+ REPEAT i := LOINDEX(posa) TO HIINDEX(posa);
+ writeln('posa[', i:1, '] = ', posa[i]);
+ END_REPEAT;
+
+ writeln;
+ nega[-3] := 1;
+ nega[-2] := 2;
+ nega[-1] := 3;
+ REPEAT i := LOINDEX(nega) TO HIINDEX(nega);
+ writeln('nega[', i:1, '] = ', nega[i]);
+ END_REPEAT;
+
+ (* Do some things with a list *)
+
+ -- check the initial size (should be empty)
+ i := SIZEOF(lagg);
+ writeln('no. of els in lagg = ', i);
+
+ -- insert elements at the front
+ INSERT(lagg, 10, 0);
+ i := SIZEOF(lagg);
+ writeln('no. of els in lagg = ', i);
+ INSERT(lagg, 20, 0);
+ writeln('no. of els in lagg = ', SIZEOF(lagg));
+
+ -- print some of the elements
+ i := lagg[1];
+ writeln('first in lagg = ', i);
+ writeln('lagg[2] = ', lagg[2]);
+
+ -- check if a value in in the list
+ b := 10 IN lagg;
+ writeln(b); -- should be TRUE
+ b := 30 IN lagg;
+ writeln(b); -- should be FALSE
+
+ -- write all the elements
+ REPEAT i := LOINDEX(lagg) TO HIINDEX(lagg);
+ writeln('lagg[', i:1, '] = ', lagg[i]);
+ println('lagg[', i:1, '] = ', lagg[i]);
+ END_REPEAT;
+
+ (* see what happens with an indeterminate value *)
+ b := FALSE;
+ b := ?;
+ writeln(b);
+ println(b);
+ (* Some more attempts with indeterminate *)
+ i := 2;
+ n := 3*i;
+ writeln(i, n); -- should be 2 6
+ n := 3*?;
+ writeln(i, n); -- should be 2 ?
+ i := ?;
+ n := 3*i;
+ writeln(i, n); -- should be ? ?
+
+END; -- end of compound statement
+ -- but we can have individual statements
+
+
+ (* Try to provide some excitement by making a magic square *)
+ writeln;
+ write('Enter an odd number between 1 and 15: ');
+ readln(n);
+ IF NOT magic_square(n) THEN
+ writeln('I did not like your number which was ', n:1);
+ writeln('If you get it right next time, something magic will happen.');
+ write('Enter an odd number between 1 and 15: ');
+ readln(n);
+ magic_square(n);
+ END_IF;
+
+
+ (* Try a couple of REPEAT statements *)
+ writeln('Test REPEAT (should print -2)');
+ i := -2;
+ REPEAT UNTIL i = 0;
+ writeln(i);
+ println(i);
+ ESCAPE;
+ i := i + 1;
+ END_REPEAT;
+
+ writeln('Test REPEAT (should print 3, 2, 1)');
+ REPEAT i := 3 TO 1 BY -1;
+ writeln(i);
+ END_REPEAT;
+
+
+ (* Try the LIKE operator *)
+ writeln('Test LIKE');
+ writeln(('A' LIKE 'A')); -- should be TRUE
+ writeln(('A' LIKE 'b')); -- should be FALSE
+ writeln(('Page 407' LIKE '$###')); -- should be TRUE
+ writeln(('Page 23' LIKE '$###')); -- should be FALSE
+
+
+ (* Try the REXPR function *)
+ writeln('Test rexpr');
+ writeln(rexpr('A', 'A')); -- should be TRUE
+ writeln(rexpr('A', 'b')); -- should be FALSE
+ writeln(rexpr('Page 407', '[a-zA-Z]+\ [0-9]+')); -- should be TRUE
+ writeln(rexpr('Page 23', '[a-zA-Z]+\ [0-9]')); -- should be FALSE
+
+
+ (* Try an ARRAY OF ARRAY *)
+ a23[1][1] := 11;
+ a23[1][2] := 12;
+ a23[1][3] := 13;
+ a23[2][1] := 21;
+ a23[2][2] := 22;
+ a23[2][3] := 23;
+
+ writeln('Test REPEAT (should be 1 1 11, 1 2 12, 1 3 13, 2 1 21, 2 2 22 etc)');
+ REPEAT n := 1 TO 2;
+ REPEAT i := 1 TO 3;
+ writeln(n, i, a23[n][i]);
+ END_REPEAT;
+ END_REPEAT;
+
+
+ (* do some simple string operations *)
+ s1 := 'string';
+ writeln(s1); -- should be string
+ s2 := s1[2:4];
+ writeln(s2); -- should be tri
+ b := s1 <> s2;
+ writeln(b); -- should be TRUE
+ writeln(s2 + s1); -- should be tristring
+
+
+ (* Assign and print to a user-defined type *)
+ j := 33;
+ writeln(j*3); -- should be 99
+
+ (* Do something with a variable of type ENTITY */
+ ex.attr1 := 33;
+ ex.attr2 := 'The attribute named attr2';
+ ex.attr3 := ex.attr1/3;
+ writeln('ex.attr1 should be 33 and is: ', ex.attr1);
+ writeln('ex.attr2 is: ', ex.attr2);
+ writeln('ex.attr3 should be 11 and is: ', ex.attr3);
+
+END_CODE
+</pre>
+
+<p>
+<h2>Specifying a SPECIAL_ command</h2>
+ <a name="sec:special"></a>
+
+
+<p>This section gives some hints on how to specify a LaTeX command that
+requires some special processing. The faint-hearted should skip this. It is
+assumed that the implementor will have knowledge of LaTeX, C programming,
+and lex and
+YACC style lexer and parser generator systems.
+
+
+<p>There are two ways of defining <samp>SPECIAL_</samp> kinds of commands though
+neither is particularly simple. The easiest is by what is termed the
+coding method. This involves modifying the standard actions. The
+more complicated means is by the grammar method, which involves extending
+the production grammar and, typically, also coding new kinds of actions.
+
+
+<p>The process of specifying one of the <samp>SPECIAL_</samp> kinds of command
+actions is:
+<ul>
+
+
+ <li> Seriously question the need for the special command. One is only required if
+ the standard actions cannot be coerced into serving the needs of the command
+ processing and/or the command grammar is not supported by the LTX2X system.
+
+ <li> Design the required entry for the command table.
+
+ <li> Decide whether the coding or the grammar method is to be used for
+ extending LTX2X.
+ <dl>
+ <dt>Coding method
+<dd> Modify the actions in <tt>l2xusrlb.c</tt>,
+ and possibly
+ add new functions in <tt>l2xusrlb.c</tt> and <tt>l2xusrlb.h</tt>.
+
+
+<p><dt>Grammar method
+<dd> Extend the grammar in <tt>l2x.y</tt>. Typically it
+ be necessary to add new functions to the user-defined
+ library <tt>l2xusrlb</tt> as well.
+ </dl>
+
+ <li> Compile the modified LTX2X system. A <samp>make</samp> file for this is given
+ in Appendix <a href="#sec:install">sec:install</a>.
+
+ <li> Test the extensions and debug the program.
+</ul>
+
+
+
+<p>The <samp>l2xlib</samp> has many functions that may be of use in this process.
+ Some of these are indicated below.
+
+
+<p><ul>
+
+
+ <li> <samp>char *strsave(char s[])</samp> saves a string somewhere
+
+ <li> <samp>void myprint(char s[])</samp> writes a string to the output medium. Its
+ particular action is controlled by the <samp>set_print</samp> and
+ <samp>reset_print</samp> functions, as well as the <samp>-p</samp> option.
+
+ <li> <samp>void verbatim_print(char s[])</samp> like <samp>myprint</samp>,
+ writes a string to the output medium. Its actions are controlled
+ by the current print mode, and newlines are obeyed (i.e., it ignores
+ any pretty-printing option).
+
+ <li> <samp>void yyerror(char s[])</samp> used by the lexer and parser to print
+ an error message string.
+
+ <li> <samp>void warning(char s[])</samp> writes a warning message string.
+
+ <li> <samp>void do_newline()</samp> used within the lexer to set internal variables
+ whenever a newline is encountered in the input.
+
+ <li> <samp>void initialise_sysbuf()</samp> initialises the system supplied string
+ buffer.
+
+ <li> <samp>void print_sysbuf()</samp> writes the content of the system string buffer
+ to the output file.
+
+ <li> <samp>void copy_sysbuf(char s[])</samp> copies the contents of the system
+ string buffer to the user-supplied string. It is the user's responsibility
+ to ensure that the string is big enough.
+
+ <li> <samp>void set_print(PSTRWC pswitch)</samp> controls the action of <samp>myprint</samp>,
+ <samp>print_newline</samp> and <samp>verbatim_print</samp>. If the input argument is
+ <samp>p_default_print</samp>
+ then the print functions should write to the output file; this is the
+ default behavior. If the
+ argument is <samp>p_no_print</samp>, then no writing occurs. If the argument
+ is <samp>p_print_to_sysbuf</samp>, then the print functions write to the system
+ string buffer.
+
+ <li> <samp>void reset_print()</samp> resets the behavior of the print functions. This
+ function should always be used after a call to <samp>set_print</samp>.
+
+ <li> <samp>int lookup_entry(char s[], int kind)</samp> returns the location
+ within the command table of the
+ command name given in <samp>s</samp> of the command type given in <samp>kind</samp>.
+ If <samp>kind</samp> is <samp>DONT_CARE</samp> then the position of the first occurrence
+ of <samp>s</samp> is returned.
+
+ <li> <samp>void get_env_name(char s[])</samp> extracts the name of a LaTeX
+ environment from <samp>s</samp>, which is assumed to have the form
+ <samp>\something { environment }</samp>. The name of the environment is put
+ into the global string <samp>env_name</samp>.
+
+ <li> <samp>PSENTRY get_mode_sym(int loc)</samp> returns a pointer to the
+ symbol table entry at position <samp>loc</samp> in the command table
+ for the current mode.
+
+ <li> <samp>int command_type(int loc)</samp> returns the system defined
+ kind of command at location
+ <samp>loc</samp> in the command table.
+
+ <li> <samp>int get_user_type(int loc)</samp> returns the user input (<samp>TYPE=</samp>)
+ kind of command at location
+ <samp>loc</samp> in the command table.
+
+ <li> <samp>PSTRWC get_t(PSENTRY loc)</samp> returns a pointer to the
+ <samp>START_TAG=</samp> specification for symbol entry <samp>loc</samp>.
+ There are similar functions for other tagging specifications.
+
+ <li> <samp>PSTRWC get_tag_t(PSENTRY loc, int n)</samp> returns a pointer
+ to the <samp>START_TAG_n</samp> specification for the <samp>n</samp>'th
+ argument for symbol entry <samp>loc</samp>. There are similar
+ functions for other argument tagging specifications.
+
+ <li> <samp>PSTRWC get_param_print(PSENTRY loc, int n)</samp> returns a
+ pointer to the print control specification for the
+ <samp>n</samp>'th required argument for symbol entry <samp>loc</samp>.
+ There are similar functions for other print controls.
+
+ <li> <samp>int get_level(PSENTRY loc)</samp> returns the <samp>SECTIONING_LEVEL=</samp>
+ value for symbol entry <samp>loc</samp>.
+</ul>
+
+
+
+<p>The process of specifying a <samp>SPECIAL_</samp> is best described via
+an example.
+
+
+<p>
+<h3>Example</h3>
+
+
+
+<p>Assume that there is a `non-standard' LaTeX command
+which has one required argument. When this command is processed by LaTeX its
+effect is to start a new section in a document entitled
+Normative References. Some boilerplate text is then typeset (specified
+within the definition of the command). This boilerplate includes two
+instances of the text from the argument of the command. Finally, a
+description
+list environment is started.
+
+
+<p>In LaTeX terms, this command could have been defined as:
+<pre>
+\newcommand{\XXspecial}[1]{\section{Normative References}
+ Some boilerplate text with #1
+ in the middle. Now there is
+ some more boilerplate with #1
+ in the middle of it.
+ \begin{description} }
+</pre>
+
+<p>For the purposes of the example, it is desired to replace the occurrence
+of the <samp>\XXspecial</samp> command by the `normal' section heading for the
+output tagged style, and also print out the boilerplate text including
+the argument text in the right places. The start of the list environment has
+also to be taken into account. The <samp>\item</samp> optional argument text is
+to be enclosed in parentheses, with a dash before the main text.
+These requirements are not something that can
+be currently accomplished with the standard LTX2X system.
+
+
+<p>To make the requirements more concrete, if the input LaTeX source
+includes:
+<pre>
+....
+\XXspecial{REQ PARAM TEXT}
+
+\item[Ref 1] Text 1.
+\item[Ref 2] Text 2.
+\end{description}
+....
+</pre>
+then the desired output is to look like:
+<pre>
+....
+
+</div.1>
+
+<div.1>
+<heading>Normative References</heading>
+
+Some boilerplate text with REQ PARAM TEXT
+in the middle. Now there is
+some more boilerplate with REQ PARAM TEXT
+in the middle of it.
+
+ (Ref 1) -- Text 1.
+ (Ref 2) -- Text 2.
+....
+</pre>
+
+<p>
+ Now, let's write a specification for the command table, which we will do in pieces,
+starting with the sectioning tags. In this tagging style, end tags for sections
+take the form <samp>&lt;/div.1&gt;</samp>, and start tags the form <samp>&lt;div.1&gt;</samp>.
+The titles of sections are enclosed between <samp>&lt;heading&gt;</samp> and
+<samp>&lt;/heading&gt;</samp> tags. We also
+want some newlines in the output to set things off. If <samp>?</samp> is used as the
+escape character, then we can specify for the sectioning tagging:
+
+
+<pre>
+SECTIONING_LEVEL= SECT
+START_TAG= "?n?n&lt;div.1&gt;?n"
+ STRING: "&lt;heading&gt;Normative References&lt;/heading&gt;?n"
+END_TAG= "?n&lt;/div.1&gt;"
+</pre>
+
+
+
+<p>There is one required argument and no optional arguments, so we need:
+<pre>
+REQPARAMS= 1
+</pre>
+
+<p>The LaTeX command also starts off a <samp>description</samp> environment, so we have
+to set the tags for the <samp>\item</samp> commands that will follow. This is done by:
+<pre>
+START_ITEM= "?n"
+START_ITEM_PARAM= " ("
+END_ITEM_PARAM= ") -- "
+</pre>
+
+<p>Most of the work is now completed though we still have to give the command name,
+decide what sort of <samp>SPECIAL_</samp> it will be and set the <samp>SPECIAL_TOKEN</samp>
+value. None of the provided <samp>SPECIAL_</samp> types exactly fit this entry as it is
+a mixture of sectioning and list environment, so we will just call it a
+<samp>SPECIAL_COMMAND</samp> type.
+To summarize, the effective state of the command table entry is:
+
+
+<pre>
+TYPE= SPECIAL_COMMAND
+C= NAME= to be specified
+C= SPECIAL_TOKEN= to be specified
+ SECTIONING_LEVEL= SECT
+ START_TAG= "?n?n&lt;div.1&gt;?n"
+ STRING: "&lt;heading&gt;Normative References&lt;/heading&gt;?n"
+ END_TAG= "?n&lt;/div.1&gt;"
+ REQPARAMS= 1
+ START_ITEM= "?n"
+ START_ITEM_PARAM= " ("
+ END_ITEM_PARAM= ") -- "
+END_TYPE
+</pre>
+
+
+
+<p>For pedagogical purposes, this special will be implemented using both the
+grammar and code methods, and the command names used will be <samp>\GRAMMspecial</samp>
+and <samp>\CODEspecial</samp> respectively.
+
+
+<p>
+<h4>Grammar method implementation</h4>
+
+
+<p>The command name for this implementation will be <samp>\GRAMMspecial</samp>.
+
+
+<p>The grammar method requires changes to the grammar specified in <tt>l2x.y</tt>.
+
+
+<p><ol>
+
+
+ <li> A new token has to be defined, call it <samp>GRAMMSPECIAL</samp>, in the first
+part of the file. There is a slot for this under the comment <samp>/* specials */</samp>.
+An integer number, greater than or equal to 10,000 (ten thousand) and less than
+32,768 (2<sup>15</sup>), has to be
+associated with this token. (Footnote: The upper limit of (2<sup>15</sup>-1) is
+set by the bison processor.)
+ Further, this number must not be the same as any other
+number associated with any other token. Let us use
+the maximum number 32,767. The relevant portion of <tt>l2x.y</tt> will look like
+
+
+<pre>
+ /* specials */
+%token &lt;pos&gt; /* other specials here */
+%token &lt;pos&gt; GRAMMSPECIAL 32767
+ /* precedences */
+</pre>
+
+This number is used for communication within the LTX2X system, and is the number
+set as the value of the <samp>SPECIAL_TOKEN</samp> in the command table. We can now finalize
+the command table entry as:
+
+
+<pre>
+TYPE= SPECIAL_COMMAND
+NAME= <samp>\GRAMMspecial</samp>
+SPECIAL_TOKEN= 32767
+ SECTIONING_LEVEL= SECT
+ START_TAG= "?n?n&lt;div.1&gt;?n"
+ STRING: "&lt;heading&gt;Normative References&lt;/heading&gt;?n"
+ END_TAG= "?n&lt;/div.1&gt;"
+ REQPARAMS= 1
+ START_ITEM= "?n"
+ START_ITEM_PARAM= " ("
+ END_ITEM_PARAM= ") -- "
+END_TYPE
+</pre>
+
+
+
+<p>
+ <li> A new production, or productions, has to be added to the grammar. There is
+a place for this at the end of the rules section in the file, under the predefined
+production <samp>l2xSpecials</samp>. Let us call our new production <samp>GrammSpecial</samp>,
+and add it as:
+<pre>
+l2xSpecials: ASpecial
+ | AnotherSpecial
+ | GrammSpecial
+ ;
+</pre>
+where the <samp>ASpecial</samp> and <samp>AnotherSpecial</samp> are pre-existing specials.
+
+
+<p>
+ <li> The production now has to be defined, specifying the expected syntax
+and required actions. This looks like:
+<pre>
+GrammSpecial: GRAMMSPECIAL
+ {
+ start_section($1);
+ myprint(get_t($1));
+ myprint(get_tag_t($1,1));
+ initialise_sysbuf();
+ set_print(p_print_to_sysbuf);
+ }
+ ReqParam
+ {
+ initialise_string(grammbuf);
+ copy_sysbuf(grammbuf);
+ reset_print();
+ prwboiler1();
+ print_sysbuf();
+ prwboiler2();
+ myprint(grammbuf);
+ prwboiler3();
+ start_list($1);
+ }
+ ;
+</pre>
+The actions are enclosed in braces and are defined in terms of
+C code.
+
+
+<p>Once the parser has been given the <samp>GRAMMSPECIAL</samp> token from the lexer,
+it will attempt to
+perform the actions within the first set of braces. The first of these,
+<samp>start_section($1)</samp>, is the LTX2X action for starting a sectioning command.
+Basically, this deals with any closing of prior sections of the document and
+remembering the closing tag for this section.
+The next two actions
+print the start tags for the command and its required argument,
+taking the strings from the command table.
+<samp>initialise_sysbuf()</samp> initializes the
+system string buffer ready for new input. Then the print control is set so
+that any output will be directed into the system string buffer rather
+than the output
+file. This finishes the first set of actions.
+
+
+<p>The production grammar for the required argument comes next. If this
+is incorrect, the parser automatically gives an (uninformative) error message.
+Otherwise, the last set of actions are done. At this point, the text
+of the required argument will be contained in the system string buffer.
+This is then copied to a temporary buffer <samp>grammbuf</samp>, that we have yet
+to define, by calling
+<samp>copy_sysbuf(grammbuf)</samp> having first made sure that this buffer has
+been cleared of any previous contents (the <samp>initialise_string(grammbuf)</samp>
+action). The printing control must now be reset (<samp>reset_print()</samp>), or
+things might get corrupted later. A function <samp>prwboiler1()</samp> is called to
+print the first part of the boilerplate text, followed by printing the contents
+of the system buffer by the action <samp>print_sysbuf()</samp> (remember that this should
+contain the text of the required argument). The second part of the boilerplate
+is written by the function <samp>prwboiler2()</samp>. Just for pedagogical purposes,
+the required argument text is written out using the text stored in the temporary
+buffer (<samp>myprint(grammbuf)</samp>) rather than from the system buffer. The penultimate
+action is the printing of the last piece of boilerplate.
+
+
+<p>The final action --- <samp>start_list($1)</samp> --- is the standard LTX2X action
+at the start of a list environment. This remembers the various tags for the list
+items to follow.
+
+
+<p>A character buffer, <samp>grammbuf</samp>, is now defined in the initial
+section of the <tt>l2x.y</tt> file, as:
+<pre>
+char grammbuf[80];
+</pre>
+which is intended to be large enough to hold the text of the required
+argument of the command.
+
+
+<p>This completes the changes to the grammar file.
+
+
+<p>
+ <li> The three functions called out in the above actions for printing
+the boilerplate are coded and placed in the user library file
+<tt>l2xusrlb.c</tt> and are also added to <tt>l2xusrlb.h</tt>. Here is
+the relevant code as it would appear in <tt>l2xusrlb.c</tt>.
+<pre>
+ /* demonstration string definition */
+
+STRING boiler_string_3 = "\nin the middle of it.\n\n";
+
+ /* demonstration functions */
+
+/* PRWBOILER1 print some demonstration boilerplate */
+void prwboiler1()
+{
+ myprint("\nSome boilerplate text with ");
+} /* end PRWBOILER1 */
+
+/* PRWBOILER2 print some demonstration boilerplate */
+void prwboiler2()
+{
+ myprint("\nin the middle. Now there is\n");
+ myprint("some more boilerplate with ");
+} /* end PRWBOILER2 */
+
+/* PRWBOILER3 yet more demonstration boilerplate */
+void prwboiler3()
+{
+ myprint(boiler_string_3);
+} /* end PRWBOILER1 */
+</pre>
+
+<p>
+ <li> The system is recompiled, using <samp>make</samp>, and tested on some example
+LaTeX files.
+
+
+<p></ol>
+
+
+
+<p>
+
+
+<h4>Code method implementation</h4>
+
+
+<p>This method `merely' requires extending the standard actions to
+account for the new requirements. First, however, we must complete
+the definition of the command table entry. We will call the new
+command <samp>\CODEspecial</samp>. Also a unique value has to be assigned
+to the <samp>SPECIAL_TOKEN</samp>. This must have a value greater than or
+equal to 50,000 (fifty thousand). We will use a value 59,999. Later this
+value is used within the action code to identify the special.
+The command table entry is thus:
+
+
+<pre>
+TYPE= SPECIAL_COMMAND
+NAME= <samp>\CODEspecial</samp>
+SPECIAL_TOKEN= 59999
+ SECTIONING_LEVEL= SECT
+ START_TAG= "?n?n&lt;div.1&gt;?n"
+ STRING: "&lt;heading&gt;Normative References&lt;/heading&gt;?n"
+ END_TAG= "?n&lt;/div.1&gt;"
+ REQPARAMS= 1
+ START_ITEM= "?n"
+ START_ITEM_PARAM= " ("
+ END_ITEM_PARAM= ") -- "
+END_TYPE
+</pre>
+
+which only differs from that for the grammar implemented special in the
+<samp>SPECIAL_TOKEN=</samp> and the <samp>NAME=</samp> values.
+
+
+<p>Before proceeding further, some explanation of the internals of
+the LTX2X system is in order.
+
+
+<p><dl>
+<dt>Command table entry
+<dd> Internally, an array of C structs
+is used for storing the data corresponding to the command table. The struct
+is fully
+defined in file <tt>l2xcom.h</tt>, and type PSENTRY is a
+pointer to an instance of the struct. There is an entry in
+the internal command table for each command. Where a command specification
+is mode-dependent, then the entries for this are stored as a list (the
+command table array is actually an array of lists of command specifications,
+one list per command).
+
+
+<p>For the purposes at hand, only a few
+of the elements are of concern; these are <samp>kind</samp>, <samp>parse_kind</samp>
+and <samp>special_token</samp>. The element <samp>kind</samp> contains an identifier
+of the <samp>TYPE=</samp> value; that is, the type of the command as specified
+by the user. The element <samp>special_token</samp> contains the
+<samp>SPECIAL_TOKEN=</samp> value. The <samp>parse_kind</samp> element contains
+an identifier of the type of command as assigned internally by LTX2X.
+This last identifier is generated by the table processing code
+in <samp>l2xlib.c</samp> and corresponds to one of the token values
+acceptable to the parser.
+
+
+<p><dt>The lexer
+<dd> The lexer reads the source LaTeX file, looking for
+LaTeX commands (essentially anything starting with a backslash). Each
+time it finds a command it looks it up in the command table array, and
+sends its parser token value (the <samp>parse_kind</samp> value) and the command
+table array position to the parser.
+
+
+<p><dt>The parser
+<dd> Given a token from the lexer, the parser finds the
+appropriate grammar production and performs the specified actions. It
+is able to access command information through having the command table
+position.
+
+
+<p><dt>The grammar
+<dd> The grammar used for the LaTeX general commands (and
+environments) is actually very simple --- the complexity is reserved for the
+lexer and the actions. At the grammar level, no distinction is made
+between a command and an environment. There are a total of 19 different
+command types (tokens), which fall into a smaller number of groups.
+<ol>
+
+
+ <li> A command with no arguments.
+
+ <li> A command with just a single optional argument.
+
+ <li> Commands with a final optional argument and between 1 and 8 required
+ arguments.
+
+ <li> Commands with between 1 and 8 required arguments. In this case
+ it is always assumed that there might be an initial optional
+ argument.
+
+ <li> A command with 9 required arguments.
+</ol>
+
+Note that this partitioning is based solely on the number of required
+arguments and the position (if any is declared) of an optional
+argument.
+
+
+<p>For example, if a command/environment is specified in the command table as
+having one required argument and no optional arguments, then this will
+be treated as a command with possibly an initial optional argument and
+one required argument. The grammar for this is:
+<pre>
+l2xComm1: COMMAND_1
+ {
+ start_with_opt($1);
+ }
+ OptParam
+ {
+ action_opt_first($1);
+ }
+ ReqParam
+ {
+ action_last_p($1,1);
+ }
+ ;
+</pre>
+where the words in all upper case are grammar tokens, and words in mixed
+case are other grammar productions. The actions are enclosed between braces.
+The <samp>$1</samp> is the position of the command in the command table array.
+
+
+<p><dt>Actions
+<dd> The standard actions are contained in file <tt>l2xacts.c</tt>.
+Within the code for each standard action, provision is made for
+calling
+action code for specials. All the functions have the same
+general structure. Here, for instance, is the code for the standard
+action that is called between the start of a command and a first optional
+argument.
+<pre>
+/* START_WITH_OPT start action for command with optional param */
+void start_with_opt(pos)
+int pos; /* position of command in table */
+{
+ int user_kind; /* user-specified command type */
+
+ user_kind = get_user_type(pos);
+
+ switch(user_kind) {
+ case TEX_CHAR: /* the general, non-specials */
+ case CHAR_COMMAND:
+ case COMMAND:
+ case BEGIN_ENV:
+ case END_ENV:
+ case BEGIN_LIST_ENV:
+ case END_LIST_ENV:
+ case SECTIONING:
+ start_it(pos); /* command start action */
+ default_start_with_opt(pos); /* start optional param */
+ break;
+ case SPECIAL: /* the specials */
+ case SPECIAL_BEGIN_ENV:
+ case SPECIAL_END_ENV:
+ case SPECIAL_BEGIN_LIST:
+ case SPECIAL_END_LIST:
+ case SPECIAL_COMMAND:
+ case SPECIAL_SECTIONING:
+ special_start_with_opt(pos);
+ break;
+ default: /* should not be here! */
+ warning("(start_with_opt) Unrecognized command type");
+ break;
+ } /* end switch on user_kind */
+} /* end START_WITH_OPT */
+</pre>
+
+<p>The special actions code is in file <samp>l2xusrlib.c</samp>. The code
+for these all follow the same general pattern. For example, here is
+the code implementing the special action between the start of a
+command and a first optional argument.
+<pre>
+/* SPECIAL_START_WITH_OPT special start for command with opt param */
+void special_start_with_opt(pos)
+int pos; /* command position in table */
+{
+ int special_kind; /* user-specified special token */
+
+ special_kind = get_special_token(pos);
+
+ switch(special_kind) {
+ /* additional cases for specials added here */
+
+ /* end of cases for specials */
+ default: /* should not be here! */
+ warning("(special_start_with_opt) Unrecognized SPECIAL");
+ tdebug_str_int("SPECIAL_TOKEN =",special_kind);
+ break;
+ } /* end of switch on user_kind */
+} /* end SPECIAL_START_WITH_OPT */
+</pre>
+Note that the code as provided just issues a warning message.
+
+
+<p>
+</dl>
+
+
+<p>
+ With this background, we will now go on with the example.
+
+
+<p><ol>
+
+
+ <li> Decide on how the LTX2X system will translate your command/environment
+description into its internal grammar command type. In this case it
+will translate into a command with possibly an initial optional argument
+and one required argument.
+
+
+<p>
+ <li> Examine the grammar for the command and hence determine which standard
+actions will be called. In this case there are three of these, namely
+<samp>start_with_opt</samp>, <samp>action_opt_first</samp> and <samp>action_last_p</samp>.
+These are the actions that might require modification.
+
+
+<p>
+ <li> Determine what actions are required for your special. Conceptually
+replace the standard actions in the grammar by your actions. Then determine
+how these should be incorporated into the special action code in
+<samp>l2xusrlb</samp>. In plain
+language, the grammar and conceptual actions for the example are:
+<pre>
+l2xComm1: COMMAND_1
+ {
+ start of as a sectioning command
+ ignore the optional argument as there isn't one
+ }
+ OptParam
+ {
+ finish processing the non-existent optional
+ get ready to store the argument text in a buffer
+ }
+ ReqParam
+ {
+ print the boilerplate and argument text
+ start the description list
+ }
+ ;
+</pre>
+Note that this is essentially the same as we did for the grammar
+implementation for <samp>\GRAMMspecial</samp>, except that there is the additional
+optional argument to be dealt with.
+
+
+<p>
+ <li> Modify the requisite special action code.
+
+
+<p>In the example, three standard actions have to be modified. Here is
+the modification to <samp>special_start_with_opt</samp>:
+<pre>
+/* SPECIAL_START_WITH_OPT special start for command with opt param */
+void special_start_with_opt(pos)
+int pos; /* command position in table */
+{
+ int special_kind; /* user-specified special token */
+
+ special_kind = get_special_token(pos);
+
+ switch(special_kind) {
+ /* additional cases for specials added here */
+ case 59999: /* example coded special */
+ codespecial_start(pos);
+ default_start_with_opt(pos);
+ break;
+
+ /* end of cases for specials */
+ default: /* should not be here! */
+ warning("(special_start_with_opt) Unrecognized SPECIAL");
+ tdebug_str_int("SPECIAL_TOKEN =",special_kind);
+ break;
+ } /* end of switch on user_kind */
+} /* end SPECIAL_START_WITH_OPT */
+</pre>
+The addition is done by adding a new <samp>case 59999:</samp> together with
+appropriate code. The number 59999 is that corresponding to the
+value for <samp>SPECIAL_TOKEN=</samp> in the command table specification
+of <samp>\CODEspecial</samp>. The function <samp>codespecial_start</samp> is to
+be written, while <samp>default_start_with_opt</samp> is an LTX2X defined
+function which initiates processing of an initial optional argument.
+
+
+<p>Similarly, here is the modification to <samp>special_action_opt_first</samp>:
+<pre>
+ /* additional cases for specials added here */
+ case 59999: /* example coded special */
+ default_end_start_opt(pos);
+ codespecial_p1(pos);
+ break;
+
+ /* end of cases for specials */
+</pre>
+where <samp>codespecial_p1</samp> is to be written and <samp>default_end_start_opt</samp>
+is the standard LTX2X action at the end of an initial optional argument.
+
+
+<p>Finally, here is the modification to <samp>special_action_last_p</samp>:
+<pre>
+/* SPECIAL_ACTION_LAST_P action after last req argument */
+void special_action_last_p(pos,p)
+int pos; /* position of command in table */
+int p; /* number of last argument */
+{
+ int special_kind; /* user-specified special token */
+
+ special_kind = get_special_token(pos);
+
+ switch(special_kind) {
+ /* additional cases for specials added here */
+ case 59999: /* example coded special */
+ if (p == 1) { /* has only one req param */
+ codespecial_end(pos);
+ }
+ break;
+
+ /* end of cases for specials */
+ /* stuff deleted to save space */
+</pre>
+
+<p>
+ <li> Code the functions for the new actions.
+
+
+<p>Code for these functions should be put into file <samp>l2xusrlb.c</samp>
+and file <samp>l2xusrlb.h</samp> modified accordingly.
+
+
+<p>Here is the code for the three <samp>codespecial_</samp> functions.
+<pre>
+char codebuf[80]; /* a string buffer */
+
+/* CODESPECIAL_START actions for start of CODEspecial command */
+void codespecial_start(pos)
+int pos; /* command table position */
+{
+ start_section(pos); /* do start of sectioning */
+ myprint(get_t(pos)); /* print start tag */
+} /* end CODESPECIAL_START */
+
+/* CODESPECIAL_P1 actions at start of CODEspecial param 1 */
+void codespecial_p1(pos)
+int pos; /* command table position */
+{
+ myprint(get_tag_t(pos,1)); /* print 1st param start tag */
+ initialise_sysbuf(); /* clear system string buffer */
+ set_print(p_print_to_sysbuf); /* put arg text into sys buffer */
+} /* end CODESPECIAL_P1 */
+
+/* CODESPECIAL_END actions at end of CODEspecial command */
+void codespecial_end(pos)
+int pos; /* command table position */
+{
+ initialise_string(codebuf); /* clear this string buffer */
+ copy_sysbuf(codebuf); /* copy sys buffer into codebuf */
+ reset_print(); /* normal printing */
+ prwboiler1(); /* print some boilerplate */
+ print_sysbuf(); /* print system buffer */
+ prwboiler2(); /* print more boilerplate */
+ myprint(codebuf); /* print codebuff */
+ prwboiler3(); /* print yet more boilerplate */
+ start_list(pos); /* start a list environment */
+} /* end CODESPECIAL_END */
+</pre>
+Note that these actions are almost identical to those that were used
+within the grammar when implementing the <samp>\GRAMMspecial</samp> command.
+
+
+<p>
+ <li> Compile the modified system and test it on example LaTeX files.
+
+
+<p></ol>
+
+
+
+<p>
+<h3>Notes</h3>
+
+
+
+<p><ol>
+
+
+ <li> Installation of a <samp>SPECIAL_</samp> can be limited to making changes
+ to the parser (file <samp>l2x.y</samp>) and/or the user library
+ (files <samp>l2xusrlb.c</samp> and <samp>l2xusrlb.h</samp>).
+ It should not be necessary to touch any other part of the system.
+
+
+<p>
+ <li> Changes to <tt>l2x.y</tt> will necessitate executing the parser generator
+ on this file and
+ system compilation. Changes to the other files will only necessitate
+ compilation.
+
+
+<p>
+ <li> Always use the <samp>myprint</samp>, <samp>verbatim_print</samp>
+ or <samp>print_sysbuf</samp> functions for
+ printing because they incorporate the print control
+ capability.
+
+
+<p>
+ <li> The printing in the above example is trivial. However, it is good practice
+ to define printed output separately from the parser. It makes for easier
+ maintenance. If, for example the boilerplate above was several thousand
+ characters, it might have been an idea to store the text in a file, or
+ files, and then have the boilerplate printing functions read from
+ the file(s).
+ If the text is in a state of flux this could be a good design decision
+ in any case, as changing the text would only involve modifying the
+ text file(s) and avoid recompilation of LTX2X.
+</ol>
+
+
+
+<p>
+<h4>An updated method</h4>
+
+
+<p>The above descriptions of installing a <samp>SPECIAL_</samp> command were
+written for the original release of the LTX2X system, which did not
+have the input and output specification facilities currently available
+within a command table. Below is given a possible command table entry using these
+facilities.
+
+
+<pre>
+TYPE= SPECIAL_COMMAND
+NAME= C= SPECIAL_TOKEN= set the appropriate number
+ SECTIONING_LEVEL= SECT
+ START_TAG= "?n?n&lt;div.1&gt;?n"
+ STRING: "&lt;heading&gt;Normative References&lt;/heading&gt;?n"
+ RESET_SYSBUF:
+ END_TAG= "?n&lt;/div.1&gt;"
+ REQPARAMS= 1
+ PRINT_P1= TO_SYSBUF
+ END_TAG_1=
+ STRING: "?nSome boilerplate text with "
+ SOURCE: SYSBUF
+ STRING: "?nin the middle. Now there is?n"
+ STRING: "some more boilerplate with "
+ SOURCE: SYSBUF
+ STRING: "?nin the middle of it.?n"
+ START_ITEM= "?n"
+ START_ITEM_PARAM= " ("
+ END_ITEM_PARAM= ") -- "
+END_TYPE
+</pre>
+
+The actual implementation of this as either a grammar special or a code
+special is left as an exercise for the reader. Basically it involves
+the deletion of the specific print action and buffer code because this is now
+handled automatically via the command table specification.
+
+
+<p>
+
+
+<h2>APPENDICES</h2>
+
+
+<h2>Example command table file for de-TeX ing</h2>
+ <a name="sec:detexing"></a>
+
+
+<p>This appendix provides the skeleton of a command table file that could be used for
+de-TeX ing a LaTeX document.
+
+
+<p><pre>
+C= detex.ct command table file for ltx2x to deTeX source
+
+C= -----------------------------------escape sequences
+
+C= don't use default here as it may clash with command name output
+ESCAPE_CHAR= ?
+C= keep tye default vaues for the rest
+
+C= ----------------------------------- the built in commands
+TYPE= BEGIN_DOCUMENT
+END_TYPE
+
+TYPE= END_DOCUMENT
+END_TYPE
+
+TYPE= BEGIN_VERB
+END_TYPE
+
+TYPE= END_VERB
+END_TYPE
+
+TYPE= BEGIN_VERBATIM
+ START_TAG= "?n"
+END_TYPE
+
+TYPE= END_VERBATIM
+ START_TAG= "?n"
+END_TYPE
+
+TYPE= BEGIN_DOLLAR
+END_TYPE
+
+TYPE= END_DOLLAR
+END_TYPE
+
+TYPE= SLASH_SPACE
+ START_TAG= " "
+END_TYPE
+
+TYPE= OTHER_COMMAND
+ PRINT_CONTROL= NO_PRINT
+END_TYPE
+
+TYPE= OTHER_BEGIN
+ PRINT_CONTROL= NO_PRINT
+END_TYPE
+
+TYPE= OTHER_END
+ PRINT_CONTROL= NO_PRINT
+END_TYPE
+
+C= throw away naked braces
+TYPE= LBRACE
+END_TYPE
+
+TYPE= RBRACE
+END_TYPE
+
+C= Pretty printing will probably be applied. Indent start of paragraphs
+TYPE= PARAGRAPH
+ START_TAG= "?n?n "
+END_TYPE
+
+C= -------------------------------------(La)TeX special characters
+
+C= hash (for use in \def s )
+TYPE= TEX_CHAR
+NAME= #
+END_TYPE
+
+C= ampersand (tabular column delimiter, replace by some spaces)
+TYPE= TEX_CHAR
+NAME= &
+ START_TAG= " "
+END_TYPE
+
+C= twiddle (unbreakable space)
+TYPE= TEX_CHAR
+NAME= ~
+ START_TAG= " "
+END_TYPE
+
+C= underscore (math subscript)
+TYPE= TEX_CHAR
+NAME= _
+ START_TAG= "_"
+END_TYPE
+
+C= caret (math superscript)
+TYPE= TEX_CHAR
+NAME= ^
+ START_TAG= "^"
+END_TYPE
+
+C= at
+TYPE= TEX_CHAR
+NAME= @
+ START_TAG= "@"
+END_TYPE
+
+C= ------------------------- default single character commands
+C= (replace by appropriate character)
+
+C= LaTeX start a new line
+TYPE= CHAR_COMMAND
+NAME= \\
+ START_TAG= "?n"
+END_TYPE
+
+C= small space
+TYPE= CHAR_COMMAND
+ NAME= \,
+START_TAG= " "
+END_TYPE
+
+C= end of sentence space
+TYPE= CHAR_COMMAND
+NAME= \@
+ START_TAG= " "
+END_TYPE
+
+C= hash
+TYPE= CHAR_COMMAND
+NAME= \#
+ START_TAG= "#"
+END_TYPE
+
+C= dollar
+TYPE= CHAR_COMMAND
+NAME= \$
+ START_TAG= "$"
+END_TYPE
+
+C= ampersand
+TYPE= CHAR_COMMAND
+NAME= \&
+ START_TAG= "&"
+END_TYPE
+
+C= underscore
+TYPE= CHAR_COMMAND
+NAME= \_
+ START_TAG= "_"
+END_TYPE
+
+C= percent
+TYPE= CHAR_COMMAND
+NAME= \%
+ START_TAG= "%"
+END_TYPE
+
+C= left brace
+TYPE= CHAR_COMMAND
+NAME= \{
+ START_TAG= "{"
+END_TYPE
+
+C= right brace
+TYPE= CHAR_COMMAND
+NAME= \}
+ START_TAG= "}"
+END_TYPE
+
+C= optional hyphenation
+TYPE= CHAR_COMMAND
+NAME= \-
+ START_TAG= ""
+END_TYPE
+
+C= ----------------------------- General LaTeX
+
+TYPE= COMMAND
+NAME= \caption
+ START_TAG= "?n CAPTION: "
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+ REQPARAMS= 1
+END_TYPE
+
+TYPE= BEGIN_LIST_ENV
+NAME= itemize
+ START_TAG= "?n"
+ START_ITEM= "?n o "
+END_TYPE
+
+TYPE= END_LIST_ENV
+NAME= itemize
+ START_TAG= "?n"
+END_TYPE
+
+TYPE= BEGIN_LIST_ENV
+NAME= enumerate
+ START_TAG= "?n"
+ START_ITEM= "?n -- "
+END_TYPE
+
+TYPE= END_LIST_ENV
+NAME= enumerate
+ START_TAG= "?n"
+END_TYPE
+
+TYPE= BEGIN_LIST_ENV
+NAME= description
+ START_TAG= "?n"
+ START_ITEM= "?n "
+ END_ITEM_PARAM= " : "
+END_TYPE
+
+TYPE= END_LIST_ENV
+ NAME= description
+START_TAG= "?n"
+END_TYPE
+
+C= replace \footnote with parenthesized text
+TYPE= COMMAND
+NAME= \footnote
+ START_TAG= " ("
+ END_TAG= ") "
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+ REQPARAMS= 1
+END_TYPE
+
+C= ----------------------- sectioning (keep headers only)
+
+C= repeat for all the other sectioning commands
+TYPE= SECTIONING
+NAME= \section
+ SECTIONING_LEVEL= SECT
+ START_TAG= "?n?n"
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+ REQPARAMS= 1
+ END_TAG_1= "?n?n"
+END_TYPE
+
+C= repeat for all the other starred sectioning commands
+TYPE= SECTIONING
+NAME= \section*
+ SECTIONING_LEVEL= SECT
+ START_TAG= "?n?n"
+ REQPARAMS= 1
+ END_TAG_1= "?n?n"
+END_TYPE
+
+C= and whatever else is interesting
+END_CTFILE=
+</pre>
+
+<p>
+<h2>LaTeX to HTML translation</h2>
+ <a name="sec:htmling"></a>
+
+
+<p>The command table file <tt>l2h.ct</tt> contains a set of commands that
+enable simple LaTeX documents to be translated into HTML tagged
+documents for display using a World Wide Web browser. At a minumum
+this command table can be used for conversion of the LaTeX source of
+this manual. It can also handle some very simple mathematics but not
+pictures. (Footnote: HTML itself cannot handle pictures directly (i.e.,
+there is no equivalent to the LaTeX <samp>picture</samp> environment),
+and can only handle simple mathematics.) The specification
+for the HTML tags was taken from Musciano and Kennedy [<a href="#MUSCIANO96">MUSCIANO96</a>].
+
+
+<p>Generally speaking and subject to the above limitations,
+a LaTeX document can be translated
+to HTML without the document having been planned for this purpose,
+with one exception.
+The exception is that a new LaTeX command should be used in the
+document preamble.
+I have called this <samp>\mltitle</samp> and its purpose to to define
+the contents of the header for the HTML text. The definition of this command
+is:
+<pre>
+\newcommand{\mltitle}[1]{}
+</pre>
+That is, as far as LaTeX is concerned, the argument to the command is
+thrown away and is a non-event. As far as the <tt>l2h.ct</tt> command table is concerned
+the argument is the header title. As an example, this manual starts with:
+<pre>
+...
+\mltitle{LaTeX to X translator}
+\begin{document}
+\title{\lx: A \LaTeX{} to X Auto-tagger}
+...
+</pre>
+which gets converted into:
+
+
+<pre>
+&lt;html&gt;
+&lt;head&gt;
+&lt;title&gt;LaTeX to X translator&lt;/title&gt;
+&lt;/head&gt;
+&lt;body&gt;
+
+
+<p>&lt;h1 align=center&gt;
+ LTX2X: A LaTeX to X Auto-tagger
+&lt;/h1&gt;
+...
+</pre>
+
+If the <samp>\mltitle</samp> command is not used, then the effect is to have
+an empty &lt;title&gt; in the &lt;head&gt; of the HTML document.
+
+
+<p>
+ Several aspects of the design of <tt>l2h.ct</tt> in the context of
+the conversion of typical LaTeX documents have been discussed
+as examples in the body of the manual. However, there are some aspects
+specific to the translation of this document should be mentioned.
+These stem from the fact that HTML has no tags corresponding to
+to the LaTeX <samp>\verb</samp> command or <samp>verbatim</samp> environment which
+switch off the meanings of special characters.
+
+
+<p>HTML treats the characters &lt;, &gt;, &amp; and &#035; specially.
+Within a &lt;pre&gt;...&lt;/pre&gt; the browser honours the line breaks
+but does not switch off the meanings of the special characters. In LaTeX,
+the <samp>\verb</samp> command switches off all special characters but prohibits
+any line breaking. The <samp>verbatim</samp> environment both honours line breaks
+and switches off all special characters. The difficulty with this particular
+document is that I want to show author-formatted HTML source, and that is not
+easly possible, unlike using the LaTeX <samp>verbatim</samp> environment for
+showing user-formatted LaTeX source.
+
+
+<p>The problem was solved through the use of two LaTeX environments.
+The first of these is <samp>latexonly</samp> which is used for input that is
+to be processed normally by LaTeX but which is to be totally ignored
+by LTX2X. The other environment is <samp>htmlverbatim</samp> which is used
+for input that is to be totally ignored by LaTeX but which is to be
+processed by LTX2X into an HTML &lt;pre&gt; environment.
+
+
+<p>A package file has been written which provides some addtional
+commands and environments.
+
+
+
+<p>
+<pre>
+<samp>\ProvidesPackage{ltx2html}[1996/08/29 ltx2x HTMLing]</samp>
+<samp>\RequirePackage{html} % the package file for the Perl program</samp>
+ % latex2html
+
+
+<p>% The document title for the WWW browser.
+% If used, must be placed in the preamble.
+<samp>\newcommand{\mltitle}[1]{}</samp>
+
+
+<p>% argument is for processing by LaTeX only
+<samp>\providecommand{\latex}[1]</samp>{&#035;1}
+
+
+<p>% argument is for HTML processing only
+<samp>\providecommand{\html}[1]{}</samp>
+
+
+<p>% print argument as an SGML/HTML start tag
+<samp>\newcommand{\ST}</samp>[1]{&lt;&#035;1&gt;}
+
+
+<p>% print argument as an SGML/HTML end tag
+<samp>\newcommand{\ET}</samp>[1]{&lt;/&#035;1&gt;}
+
+
+<p>% print HTML special characters
+<samp>\newcommand{\Amp}</samp>{&amp;}
+<samp>\newcommand{\GT}</samp>{&gt;}
+<samp>\newcommand{\LT}</samp>{&lt;}
+<samp>\newcommand{\HASH}</samp>{&#035;}
+
+
+<p>% treat contents as a LaTeX comment but
+% translate contents into an HTML "verbatim" environment
+<samp>% Use as: \begin{htmlverbatim} ... \end{htmlverbatim}</samp>
+<samp>\excludecomment{htmlverbatim}</samp>
+
+
+<p><samp>\endinput</samp>
+</pre>
+
+
+
+<p>The command table entries for some of these are:
+
+
+<pre>
+TYPE= COMMAND
+NAME= &amp;
+ START_TAG= "&amp;amp;"
+END_TYPE
+
+
+<p>TYPE= COMMAND
+NAME= &gt;
+ START_TAG= "&amp;gt;"
+END_TYPE
+
+
+<p>TYPE= COMMAND
+NAME= &lt;
+ START_TAG= "&amp;lt;"
+END_TYPE
+
+
+<p>TYPE= COMMAND
+NAME= &#035;
+ START_TAG= "&amp;&#035;035;"
+END_TYPE
+
+
+<p>TYPE= COMMAND
+NAME= <samp>\ST</samp>
+ START_TAG= "&amp;lt;"
+ END_TAG= "&amp;gt;"
+ REQPARAMS= 1
+END_TYPE
+
+
+<p>TYPE= COMMAND
+NAME= <samp>\ET</samp>
+ START_TAG= "&amp;lt;/"
+ END_TAG= "&amp;gt;"
+ REQPARAMS= 1
+END_TYPE
+</pre>
+
+
+
+<p>Finally, as an example, this is how some of the prior example text
+could be
+written in the source of this document.
+.
+
+
+
+<p>
+<pre>
+<samp>\begin{latexonly}</samp>
+<samp>\begin{verbatim}</samp>
+&lt;html&gt;
+&lt;head&gt;
+&lt;title&gt;LaTeX to X translator&lt;/title&gt;
+&lt;/head&gt;
+&lt;body&gt;
+
+
+<p>&lt;h1 align=center&gt;
+ LTX2X: A LaTeX to X Auto-tagger
+&lt;/h1&gt;
+...
+<samp>\end{verbatim}</samp>
+<samp>\end{latexonly}</samp>
+
+
+<p><samp>\begin{htmlverbatim}</samp>
+&lt;html&gt;
+&lt;head&gt;
+&lt;title&gt;LaTeX to X translator<samp>\ET{title}</samp>
+<samp>\ET{head}</samp>
+&lt;body&gt;
+
+
+<p>&lt;h1 align=center&gt;
+&lt;title&gt;LaTeX to X translator<samp>\ET{title}</samp>
+<samp>\ET{head}</samp>
+<samp>...</samp>
+<samp>\end{htmlverbatim}</samp>
+</pre>
+
+
+
+<p>Reading the LaTeX source of this document will reveal some
+other details. Admittedly the problem was compounded by the fact
+that this document contains demonstrations of both LaTeX and
+HTML commands which will be processed through both LaTeX and HTML
+browsers, thus a modicum of care is required to appropriately
+process both sets of special characters.
+
+
+<p>
+
+<h2>Known limitations</h2>
+ <a name="sec:limitations"></a>
+
+
+<p>LTX2X does not do everything that it might (and probably never will).
+The following are some of the things that it does not do.
+
+
+<p><ul>
+
+
+ <li> It does not understand the LaTeX <samp>\input</samp> or <samp>\include</samp>
+ commands ---
+ it just reads the source file as given. It may be useful to pre-process the
+ source file through a program that will automatically incorporate included
+ files into a LaTeX root file [<a href="#PRW94b">PRW94b</a>].
+
+
+<p>
+ <li> The <samp>\newcommand</samp> and friends do not readily
+ fit into the command patterns that
+ LTX2X can deal with. In particular, if it comes across a <samp>\newcommand</samp>
+ specification for a command that is specified in the command table, interesting
+ results might occur (for example, all the following output could be thrown
+ away if the command takes any arguments).
+
+
+<p>For instance, if the document and the command table contain:
+<pre>
+\newcommand{\lx}{LTX2X}
+....
+The \lx\ program ...
+
+TYPE= COMMAND
+NAME= \lx
+ START_TAG= "LTX2X"
+END_TYPE
+</pre>
+then there is usually no problem. On the other hand, if the document and
+ the command table contain:
+<pre>
+\newcommand{\fd}[1]{\texttt{#1}}
+....
+where \fd{InputFile} is the name ...
+
+TYPE= COMMAND
+NAME= \fd
+ REQPARAMS= 1
+END_TYPE
+</pre>
+then there may be a problem, which might be as `minor' as LTX2X reporting
+ a parse error when it has reached <samp>\newcommand{\fd}</samp> in the input
+ file and then carrying on, or it may be more serious.
+
+
+<p>
+ <li> There is a slight problem with optional arguments. LTX2X always takes the
+ first close bracket (<samp>]</samp>) after the opening bracket as signalling
+ the end of the argument text. This occurs even if the close bracket
+ is enclosed in braces (i.e. <samp>{]}</samp>). Opening brackets within optional
+ argument text are handled correctly.
+
+
+<p>
+ <li> It cannot sensibly handle LaTeX
+ constructs of the form <samp>{\em emph text}</samp>.
+ That is, except for command arguments, it does not recognize
+ <samp>{...}</samp> as a grouping construct, so cannot successfully
+ tag the end of the <samp>emph text</samp> in the example. On the other
+ hand, if constructs like <samp>\emph{emph text}</samp> or
+ <samp>\begin{em}emph text\end{em}</samp> are used instead, start and end
+ tags can be generated, given appropriate specifications in the
+ command table.
+
+
+<p>
+ <li> It assumes that all commands that take arguments are written so
+ that each argument is enclosed in braces. For example, the
+ superscripting command should be written as <samp>^{2}</samp> and not
+ as <samp>^2</samp>. Similarly, accent commands should be written as
+ <samp>\={o}</samp> rather than <samp>\=o</samp>, and so on.
+
+
+<p>
+ <li> There has not been time to test all aspects of the EXPRESS-A
+ interpreter. It is possible that this may not perform quite
+ as advertised. In particular dynamic aggregates have not been fully
+ implemented. For example:
+<pre>
+LIST OF INTEGER;
+</pre>
+appears to be handled correctly. More complicated constructs involving
+ dynamic aggregates, such as
+<pre>
+ARRAY [1:7] OF LIST OF ARRAY [-21:21] OF INTEGER;
+</pre>
+have not been tested. It is improbable that <samp>BAG</samp> will
+ work; the status of <samp>SET</samp> is similar and additionally
+ the uniqueness test for set membership has not been implemented.
+
+ <li> No doubt other limitations will come to light as LTX2X gets more use.
+ On the other
+ hand, LTX2X has been able to handle a broader range of cases than
+ it was designed to address.
+
+
+<p>
+</ul>
+
+
+
+<p>
+
+<h2>Command table summary</h2>
+ <a name="sec:summary"></a>
+
+
+<p>This section summarizes the commands and specifications available
+for defining a command table.
+
+
+<p>
+<h3>Special print characters</h3>
+
+
+
+<p>The combination of an escape character and another character can be used to
+specify certain non-visible characters within a tag string. The commands are
+given in Table <a href="#tab:spc">tab:spc</a>.
+
+
+<p><center><table border>
+
+<caption>Special print character commands.</caption> <a name="tab:spc">(Table tab:spc)</a>
+
+<tr><td> Command </td><td > Default </tr>
+<tr><td > <samp>AUDIBLE_ALERT_CHAR=</samp> </td><td > <samp>a</samp> </tr>
+<tr><td >
+<samp>BACKSPACE_CHAR=</samp> </td><td > <samp>b</samp> </tr>
+<tr><td >
+<samp>CARRIAGE_RETURN_CHAR=</samp> </td><td > <samp>r</samp> </tr>
+<tr><td >
+<samp>ESCAPE_CHAR=</samp> </td><td > <samp>\</samp> </tr>
+<tr><td >
+<samp>FORMFEED_CHAR=</samp> </td><td > <samp>f</samp> </tr>
+<tr><td >
+<samp>HEX_CHAR=</samp> </td><td > <samp>x</samp> </tr>
+<tr><td >
+<samp>HORIZONTAL_TAB_CHAR=</samp> </td><td > <samp>t</samp> </tr>
+<tr><td >
+<samp>NEWLINE_CHAR=</samp> </td><td > <samp>n</samp> </tr>
+<tr><td >
+<samp>VERTICAL_TAB_CHAR=</samp> </td><td > <samp>v</samp> </tr>
+<tr><td >
+</table></center>
+
+
+<p>These commands take one character as their value. If any commands are not
+specified, then the default value is used. These commands, if used, must be
+at the beginning of the command table before any <samp>TYPE=</samp> commands,
+although their ordering is not significant among themselves.
+
+
+<p>
+<h3>EXPRESS-A code initialization</h3>
+
+
+
+<p>The keyword <samp>CODE_SETUP=</samp> indicates that the following part
+of the command table, up until the <samp>END_CODE</samp> keyword, contains
+EXPRESS-A code declarations and/or statements. If used, this block
+must come before any of the <samp>TYPE=</samp> commands.
+
+
+<p>
+<h3>Comments and file inclusion</h3>
+
+
+
+<p>A comment within a command table file is any line starting with <samp>C= </samp>.
+
+
+<p>A file can be included within another command table file with the command line
+<pre>
+INCLUDE= FileName
+</pre>
+where <samp>FileName</samp> is the name of the file to be included. The
+<samp>INCLUDE=</samp>
+command cannot appear between the command pair <samp>TYPE=</samp> and its following
+<samp>END_TYPE</samp>.
+
+
+<p>The end of a command table file is either the physical end of the file or
+the command <samp>END_CTFILE=</samp>, whichever occurs first.
+
+
+<p>
+<h3>Command types</h3>
+
+
+
+<p>All command type specifications have the general form:
+<pre>
+TYPE= CommandType
+NAME= CommandName
+ C= a possibly empty list of mode-independent commands
+ C= possibly sets of mode-dependent commands
+END_TYPE
+</pre>
+where <samp>CommandType</samp> is a keyword identifying the kind of command being
+specified and <samp>CommandName</samp> is the identifier of a LaTeX command
+or environment. The potential set of commands that can be used between the
+<samp>TYPE=</samp>
+and <samp>END_TYPE</samp> commands depends on the kind of command being specified,
+but the special print character commands, Table <a href="#tab:spc">tab:spc</a>,
+and the <samp>INCLUDE=</samp> command cannot
+appear within a type specification. All command specifications, except
+for the built in command types (see Table <a href="#tab:rct">tab:rct</a>),
+must include at least a <samp>NAME=</samp> command.
+The ordering of commands within a type
+specification is not significant. The ordering of type specifications within
+a command table file is not significant.
+
+
+<p>The <samp>NAME=</samp> command takes as its value the name of a LaTeX command or
+environment. The name must be written exactly as it would appear in a LaTeX
+source file. That is, <samp>\command</samp> for any command except <samp>\begin{}</samp>
+or <samp>\end{}</samp>, and as <samp>env</samp> for an
+environment begun as <samp>\begin{env}</samp> or ended by <samp>\end{env}</samp>.
+
+
+<p>
+<h4>Built in command types</h4>
+
+
+<p>Table <a href="#tab:rct">tab:rct</a> lists the keywords for the built in command types.
+
+
+<p><center><table border>
+
+<caption>Built in command type keywords.</caption> <a name="tab:rct">(Table tab:rct)</a>
+
+<tr><td> Keyword </td><td > LaTeX command </tr>
+<tr><td > <samp>BEGIN_DOCUMENT</samp> </td><td > <samp>\begin{document}</samp> </tr>
+<tr><td >
+<samp>BEGIN_DOLLAR</samp> </td><td > <samp>$</samp> at start of in-text math </tr>
+<tr><td >
+<samp>BEGIN_VERB</samp> </td><td > <samp>\verb</samp> or <samp>\verb*</samp> and its following character </tr>
+<tr><td >
+<samp>BEGIN_VERBATIM</samp> </td><td > <samp>\begin{verbatim}</samp> or <samp>\begin{verbatim*}</samp> </tr>
+<tr><td >
+<samp>END_DOCUMENT</samp> </td><td > <samp>\end{document}</samp> </tr>
+<tr><td >
+<samp>END_DOLLAR</samp> </td><td > <samp>$</samp> at end of in-text math </tr>
+<tr><td >
+<samp>END_VERB</samp> </td><td > the ending character for <samp>\verb</samp> or <samp>\verb*</samp> </tr>
+<tr><td >
+<samp>END_VERBATIM</samp> </td><td > <samp>\end{verbatim}</samp> or <samp>\end{verbatim*}</samp> </tr>
+<tr><td >
+<samp>LBRACE</samp> </td><td > <samp>{</samp> </tr>
+<tr><td >
+<samp>OTHER_BEGIN</samp> </td><td > of the form <samp>\begin{env}</samp> not specified elsewhere </tr>
+<tr><td >
+<samp>OTHER_COMMAND</samp> </td><td > of the form <samp>\comm</samp> not specified elsewhere </tr>
+<tr><td >
+<samp>OTHER_END</samp> </td><td > of the form <samp>\end{env}</samp> not specified elsewhere </tr>
+<tr><td >
+<samp>PARAGRAPH</samp> </td><td > blank source line </tr>
+<tr><td >
+<samp>RBRACE</samp> </td><td > <samp>}</samp> </tr>
+<tr><td >
+<samp>SLASH_SPACE</samp> </td><td > <samp>\ </samp> </tr>
+<tr><td >
+</table></center>
+
+
+<p>The built in command type specifications can only sensibly use two kinds
+of actions ---
+those specified at the start of the command (e.g., <samp>PC_AT_START=</samp>
+and <samp>START_TAG=</samp>) and/or actions at the end of the command
+(e.g., <samp>PC_AT_END</samp> and <samp>END_TAG=</samp>).
+The <samp>NAME=</samp> command must not be used.
+
+
+<p>The <samp>OTHER_</samp> types are an exception to the above, in that they can include
+the command line <samp>PRINT_CONTROL= NO_PRINT</samp>.
+
+
+<p>LTX2X checks the command table for the presence of these required types. If one
+or more have not been specified, then they are automatically added to the command table
+with default values (e.g. empty strings) for the tags, and a warning message is
+printed giving the default value(s).
+
+
+<p>
+<h4>Optional command types</h4>
+
+
+<p>For discussion purposes, the optional command types have been tabulated
+in different categories. The basic distinction between these categories is
+the sets of commands that are permissible within the command specification.
+
+
+<p>At a minimum, all the specifications must include a <samp>NAME=</samp> command
+and must not contain any <samp>PRINT_CONTROL=</samp> or <samp>INCLUDE=</samp> commands
+or the special
+print character commands listed in Table <a href="#tab:spc">tab:spc</a>.
+
+
+<p>
+ The keywords for the general command types are given Table <a href="#tab:gct">tab:gct</a>.
+
+
+<p><center><table border>
+
+<caption>General command type keywords.</caption> <a name="tab:gct">(Table tab:gct)</a>
+
+<tr><td> Keyword </td><td > LaTeX command form </tr>
+<tr><td > <samp>TEX_CHAR</samp> </td><td > LaTeX special characters (except <samp>{ } $</samp>) </tr>
+<tr><td >
+<samp>CHAR_COMMAND</samp> </td><td > <samp>\c</samp>, where <samp>c</samp> is non-alphabetic </tr>
+<tr><td >
+<samp>COMMAND</samp> </td><td > <samp>\command</samp> except for sectioning or picture commands </tr>
+<tr><td >
+<samp>BEGIN_ENV</samp> </td><td > <samp>\begin{env}</samp> except for <samp>\item</samp> lists </tr>
+<tr><td >
+<samp>END_ENV</samp> </td><td > <samp>\end{env}</samp> except for <samp>\item</samp> lists </tr>
+<tr><td >
+<samp>VCOMMAND</samp> </td><td > a <samp>\verb</samp>-like command </tr>
+<tr><td >
+<samp>BEGIN_VENV</samp> </td><td > start of a <samp>verbatim</samp>-like environment </tr>
+<tr><td >
+<samp>END_VENV</samp> </td><td > end of a <samp>verbatim</samp>-like environment </tr>
+<tr><td >
+</table></center>
+
+
+<p>A general command type specification can include any of the tagging and print
+option commands. They cannot contain a <samp>SECTION_LEVEL=</samp> command, nor can
+they contain any of the <samp>_ITEM_</samp> commands.
+
+
+<p>The keywords for the specific command types are given in Table <a href="#tab:sct">tab:sct</a>.
+
+
+<p><center><table border>
+
+<caption>Specific command type keywords.</caption> <a name="tab:sct">(Table tab:sct)</a>
+
+<tr><td> Keyword </td><td > LaTeX command form </tr>
+<tr><td > <samp>BEGIN_LIST_ENV</samp> </td><td > <samp>\begin{env}</samp> for <samp>\item</samp> lists </tr>
+<tr><td >
+<samp>BEGIN_PICTURE_CC</samp> </td><td > <samp>\begin{pic}()()</samp> </tr>
+<tr><td >
+<samp>END_LIST_ENV</samp> </td><td > <samp>\end{env}</samp> for <samp>\item</samp> lists </tr>
+<tr><td >
+<samp>END_PICTURE</samp> </td><td > <samp>\end{pic}</samp> </tr>
+<tr><td >
+<samp>PICTURE_CCPP</samp> </td><td > <samp>\pic()(){}{}</samp> </tr>
+<tr><td >
+<samp>PICTURE_CO</samp> </td><td > <samp>\pic()[]</samp> </tr>
+<tr><td >
+<samp>PICTURE_COP</samp> </td><td > <samp>\pic()[]{}</samp> </tr>
+<tr><td >
+<samp>PICTURE_CP</samp> </td><td > <samp>\pic(){}</samp> </tr>
+<tr><td >
+<samp>PICTURE_OCC</samp> </td><td > <samp>\pic[]()()</samp> </tr>
+<tr><td >
+<samp>PICTURE_OCCC</samp> </td><td > <samp>\pic[]()()()</samp> </tr>
+<tr><td >
+<samp>PICTURE_OCO</samp> </td><td > <samp>\pic[]()[]</samp> </tr>
+<tr><td >
+<samp>PICTURE_PCOP</samp> </td><td > <samp>\pic{}()[]{}</samp> </tr>
+<tr><td >
+<samp>SECTIONING</samp> </td><td > <samp>\command</samp> for a document section </tr>
+<tr><td >
+<samp>COMMAND_OOP</samp> </td><td > <samp>\com[][]{}</samp> </tr>
+<tr><td >
+<samp>COMMAND_OOOPP</samp> </td><td > <samp>\com[][][]{}{}</samp> </tr>
+<tr><td >
+<samp>COMMAND_OPO</samp> </td><td > <samp>\com[]{}[]</samp> </tr>
+<tr><td >
+<samp>COMMAND_POOOP</samp> </td><td > <samp>\com{}[][][]{}</samp> </tr>
+<tr><td >
+<samp>COMMAND_POOP</samp> </td><td > <samp>\com{}[][]{}</samp> </tr>
+<tr><td >
+<samp>COMMAND_POOPP</samp> </td><td > <samp>\com{}[][]{}{}</samp> </tr>
+<tr><td >
+</table></center>
+
+
+<p>A <samp>BEGIN_LIST_ENV</samp> specification should include at least a
+<samp>START_ITEM=</samp> command. The other <samp>_ITEM_</samp> commands
+are optional.
+Other commands follow the rules for the general command types.
+
+
+<p>The potential commands for the <samp>_PICTURE_</samp> commands are the same as
+for the general commands, with the exception that commands related to optional
+argument processing are not available for use.
+
+
+<p>A <samp>SECTIONING</samp> command specification must include a
+<samp>SECTIONING_LEVEL=</samp>
+command. Other commands follow the rules for the general command types.
+
+
+<p>The keywords for the special command types are given in
+Table <a href="#tab:specct">tab:specct</a>.
+
+
+<p><center><table border>
+
+<caption>Special command type keywords.</caption> <a name="tab:specct">(Table tab:specct)</a>
+
+<tr><td> Keyword </td><td > LaTeX command form </tr>
+<tr><td > <samp>SPECIAL</samp> </td><td > reserved for possible future use </tr>
+<tr><td >
+<samp>SPECIAL_BEGIN_ENV</samp> </td><td > <samp>\begin{env}</samp> except for <samp>\item</samp> lists </tr>
+<tr><td >
+<samp>SPECIAL_BEGIN_LIST</samp> </td><td > <samp>\begin{env}</samp> for <samp>\item</samp> lists </tr>
+<tr><td >
+<samp>SPECIAL_COMMAND</samp> </td><td > <samp>\command</samp> </tr>
+<tr><td >
+<samp>SPECIAL_END_ENV</samp> </td><td > <samp>\end{env}</samp> except for <samp>\item</samp> lists </tr>
+<tr><td >
+<samp>SPECIAL_END_LIST</samp> </td><td > <samp>\end{env}</samp> for <samp>\item</samp> lists </tr>
+<tr><td >
+<samp>SPECIAL_SECTIONING</samp> </td><td > <samp>\command</samp> for a document section </tr>
+<tr><td >
+</table></center>
+
+
+<p>Apart from the general restrictions on the allowed commands within
+a specification, there are no restrictions on the commands that can be
+included within the specification of a <samp>SPECIAL_</samp> command. It is up
+to the creator of the special to decide what is appropriate. However,
+each <samp>SPECIAL_</samp> specification must include the command
+<pre>
+SPECIAL_TOKEN= N
+</pre>
+where <samp>N</samp> is an integer number (with 10000 &lt;= N &lt;= 32767 for a
+grammar special, or N &gt; 50000 for a code special) that has been specified
+within LTX2X as being identified with the grammar and actions corresponding to the
+value of the <samp>NAME=</samp> command for the <samp>SPECIAL_</samp>.
+
+
+<p>
+<h3>Tag specification commands</h3>
+
+
+
+<p>
+<h4>Arguments</h4>
+
+
+<p>The commands relating to the specification of LaTeX command arguments
+are given in Table <a href="#tab:param">tab:param</a>.
+
+
+<p><center><table border>
+
+<caption>Argument commands.</caption> <a name="tab:param">(Table tab:param)</a>
+
+<tr><td> Command </td><td > Value </tr>
+<tr><td > <samp>OPT_PARAM=</samp> </td><td > <samp>FIRST</samp> or <samp>LAST</samp> </tr>
+<tr><td >
+<samp>REQPARAMS=</samp> </td><td > Integer. The number of required arguments </tr>
+<tr><td >
+</table></center>
+
+
+<p>The <samp>OPT_PARAM=</samp> command specifies that the LaTeX command takes one
+optional argument and it is the <samp>FIRST</samp> or <samp>LAST</samp> in the argument
+list.
+
+
+<p>The <samp>REQPARAMS=</samp> command specifies that the LaTeX command has
+<samp>Integer</samp> number of required arguments. <samp>Integer</samp> must be between
+one and nine (Footnote: Or eight if <samp>OPT_PARAM=</samp> is specified.) inclusive.
+
+
+<p>Absence of these commands implies that the relevant LaTeX command has
+no arguments of the unspecified kind.
+
+
+<p>
+<h4>Tag actions</h4>
+
+
+<p>The commands for specifying the tag actions are summarized in
+Table <a href="#tab:tag">tab:tag</a>.
+The <samp>_ITEM_</samp> commands can only be used within a
+<samp>BEGIN_LIST_ENV</samp> or a <samp>SPECIAL_</samp> command specification.
+
+
+<p><center><table border>
+
+<caption>Tag commands.</caption> <a name="tab:tag">(Table tab:tag)</a>
+
+<tr><td> Command </td><td > Application </tr>
+<tr><td > <samp>END_ITEM=</samp> </td><td > actions after <samp>\item</samp> text </tr>
+<tr><td >
+<samp>END_ITEM_PARAM=</samp> </td><td > actions after <samp>\item</samp> optional argument </tr>
+<tr><td >
+<samp>END_OPT=</samp> </td><td > actions after optional argument </tr>
+<tr><td >
+<samp>END_TAG=</samp> </td><td > actions after all arguments processed </tr>
+<tr><td >
+<samp>END_TAG_n=</samp> </td><td > actions after n'th required argument </tr>
+<tr><td >
+<samp>START_ITEM=</samp> </td><td > actions before <samp>\item</samp> </tr>
+<tr><td >
+<samp>START_ITEM_PARAM=</samp> </td><td > actions before <samp>\item</samp> optional argument </tr>
+<tr><td >
+<samp>START_OPT=</samp> </td><td > actions before optional argument </tr>
+<tr><td >
+<samp>START_TAG=</samp> </td><td > actions at start of command </tr>
+<tr><td >
+<samp>START_TAG_n=</samp> </td><td > actions before n'th required argument </tr>
+<tr><td >
+</table></center>
+
+
+<p>
+
+ Each of these commands can specify a list of actions to be performed;
+typically this is just to print a text string. A string is any set of
+characters enclosed in double
+quote marks. The string can include any special printing characters. The
+text string starts immediately after the first double quote and ends immediately
+before the last double quote. The string cannot include a physical linebreak
+within the command table file. If the first action is to print a string then the
+string may be placed on the same line as the keyword.
+
+
+<p>The actions are listed one per line and are performed in the order they
+are listed. Table <a href="#tab:tagaction">tab:tagaction</a> lists the action commands.
+
+
+<p><center><table border>
+
+<caption>Tag actions.</caption> <a name="tab:tagaction">(Table tab:tagaction)</a>
+
+<tr><td> Keyword </td><td > Value </td><td > Application </tr>
+<tr><td > <samp>STRING:</samp> </td><td > text string </td><td > Print the string </tr>
+<tr><td >
+<samp>SOURCE:</samp> </td><td > <samp>BUFFER</samp> <samp>num</samp> </td><td > Print the contents of
+ buffer number <samp>num</samp> </tr>
+<tr><td >
+<samp>SOURCE:</samp> </td><td > <samp>FILE</samp> <samp>name</samp> </td><td > Print the contents of file
+<samp>name</samp> </tr>
+<tr><td >
+<samp>SOURCE:</samp> </td><td > <samp>SYSBUF</samp> </td><td > Print the contents of the system buffer </tr>
+<tr><td >
+<samp>RESET_BUFFER:</samp> </td><td > <samp>num</samp> </td><td > Reset the buffer <samp>num</samp> </tr>
+<tr><td >
+<samp>RESET_FILE:</samp> </td><td > <samp>name</samp> </td><td > Reset the file <samp>name</samp> </tr>
+<tr><td >
+<samp>RESET_SYSBUF:</samp> </td><td > </td><td > Reset the system buffer </tr>
+<tr><td >
+<samp>SWITCH_TO_BUFFER:</samp> </td><td > <samp>num</samp> </td><td > Print to buffer number <samp>num</samp> </tr>
+<tr><td >
+<samp>SWITCH_TO_FILE:</samp> </td><td > <samp>name</samp> </td><td > Print to file called <samp>name</samp> </tr>
+<tr><td >
+<samp>SWITCH_TO_SYSBUF:</samp> </td><td > </td><td > Print to the system buffer </tr>
+<tr><td >
+<samp>SWITCH_BACK:</samp> </td><td > </td><td > Reset the print mode </tr>
+<tr><td >
+<samp>SET_MODE:</samp> </td><td > <samp>name</samp> </td><td > Set the mode to <samp>name</samp> </tr>
+<tr><td >
+<samp>RESET_MODE:</samp> </td><td > </td><td > Reset the mode to its prior value </tr>
+<tr><td >
+<samp>CODE:</samp> </td><td > </td><td > Start of a set of EXPRESS-A statements </tr>
+<tr><td >
+</table></center>
+
+
+<p>
+<h4>Print control</h4>
+
+
+<p>The print control commands are summarized in Table <a href="#tab:print">tab:print</a>.
+These are used to set the print mode at the start and end of a command, and for
+each argument. The exception is the <samp>PRINT_CONTROL=</samp> command
+which can only be used within an <samp>OTHER_</samp> command type
+specification, and which is the only print control that can be
+specified for the <samp>OTHER_</samp> commands.
+
+
+<p><center><table border>
+
+<caption>Print control commands.</caption> <a name="tab:print">(Table tab:print)</a>
+
+<tr><td> Command </td><td > Application </tr>
+<tr><td > <samp>PRINT_CONTROL=</samp> </td><td > printing of <samp>OTHER_</samp> commands </tr>
+<tr><td >
+<samp>PC_AT_START=</samp> </td><td > set printing at start of command </tr>
+<tr><td >
+<samp>PC_AT_END=</samp> </td><td > set printing at end of command </tr>
+<tr><td >
+<samp>PRINT_OPT=</samp> </td><td > printing of optional argument </tr>
+<tr><td >
+<samp>PRINT_Pn=</samp> </td><td > printing of n'th required argument </tr>
+<tr><td >
+</table></center>
+
+
+<p>The values that these commands may take are given in Table <a href="#tab:pcvalues">tab:pcvalues</a>.
+These direct where any print output is to be directed. The default is to
+send all output the the file named as the output on the command line when
+starting LTX2X.
+
+
+<p><center><table border>
+
+<caption>Print control values.</caption> <a name="tab:pcvalues">(Table tab:pcvalues)</a>
+
+<tr><td> Value </td><td > Application </tr>
+<tr><td > <samp>NO_PRINT</samp> </td><td > Do not print at all </tr>
+<tr><td >
+<samp>TO_SYSBUF</samp> </td><td > Print to the system buffer </tr>
+<tr><td >
+<samp>TO_BUFFER</samp> <samp>num</samp> </td><td > Print to buffer number <samp>num</samp> </tr>
+<tr><td >
+<samp>TO_FILE</samp> <samp>name</samp> </td><td > Print to file called <samp>name</samp> </tr>
+<tr><td >
+<samp>NO_OP</samp> </td><td > Do not do any processing </tr>
+<tr><td >
+<samp>RESET</samp> </td><td > Reset the print mode </tr>
+<tr><td >
+</table></center>
+
+
+<p><samp>NO_PRINT</samp> and <samp>NO_OP</samp> both produce no printed output.
+However, in the <samp>NO_OP</samp> case the lexer handles all the processing,
+and effectively just ignores the source document text. In the <samp>NO_PRINT</samp>
+case, the source text is processed as normal, but the printing is directed
+to a black hole.
+
+
+<p>
+
+
+<h4>Sectioning</h4>
+
+
+<p>
+ <samp>SECTIONING</samp> command specifications require a
+<samp>SECTIONING_LEVEL=</samp>
+command. The values that this can take are listed in Table <a href="#tab:level">tab:level</a>.
+
+
+<p><center><table border>
+
+<caption>Sectioning level values.</caption> <a name="tab:level">(Table tab:level)</a>
+
+<tr><td> Value </td><td > Application </tr>
+<tr><td > <samp>PART</samp> </td><td > sectioning equivalent to <samp>\part</samp> </tr>
+<tr><td >
+<samp>CHAPTER</samp> </td><td > sectioning equivalent to <samp>\chapter</samp> </tr>
+<tr><td >
+<samp>SECT</samp> </td><td > sectioning equivalent to <samp>\section</samp> </tr>
+<tr><td >
+<samp>SUBSECT</samp> </td><td > sectioning equivalent to <samp>\subsection</samp> </tr>
+<tr><td >
+<samp>SUBSUBSECT</samp> </td><td > sectioning equivalent to <samp>\subsubsection</samp> </tr>
+<tr><td >
+<samp>PARA</samp> </td><td > sectioning equivalent to <samp>\paragraph</samp> </tr>
+<tr><td >
+<samp>SUBPARA</samp> </td><td > sectioning equivalent to <samp>\subprargraph</samp> </tr>
+<tr><td >
+</table></center>
+
+
+<p>A sectioning command specification uses the <samp>END_TAG=</samp> text tag differently
+from its use by any other specification. In this case, the tag is printed at
+the closure of the text forming the body of the section of the document. A
+document section is considered to be closed when it is followed by a higher
+level sectioning command. The values in Table <a href="#tab:level">tab:level</a> are listed
+in decreasing level. That is, a section at level <samp>CHAPTER</samp> is at a higher
+level than a section at level <samp>PARA</samp>.
+
+
+<p><dl>
+<dt>NOTE
+<dd> For the use of writers of <samp>SPECIAL_</samp> command specifications,
+<samp>SECTIONING_LEVEL=</samp> can be given some additional values. These are
+<samp>PARTm2</samp> and <samp>PARTm1</samp> for levels respectively two and one higher
+than <samp>PART</samp>, and <samp>SUBPARAp1</samp> and <samp>SUBPARAp2</samp> for levels respectively
+one and two lower than <samp>SUBPARA</samp>.
+</dl>
+
+
+<p>
+<h2>System installation</h2>
+ <a name="sec:install"></a>
+
+
+<p>This section describes how to install the LTX2X program and some of the
+internal size limits within LTX2X.
+
+
+<p>
+ The basic LTX2X system requires the following source files:
+<dl>
+<dt><tt>l2x.l</tt>
+<dd> the lexer source.
+<dt><tt>l2x.y</tt>
+<dd> the parser source.
+<dt><tt>l2xlib.c</tt>, <tt>l2xlib.h</tt>
+<dd> main program and support functions.
+<dt><tt>l2xlibtc.h</tt>
+<dd> header file containing keywords and their
+ representations as strings.
+<dt><tt>l2xcom.h</tt>
+<dd> header file for all system components
+ (except for getopt, srchenv and the interpreter).
+<dt><tt>l2xacts.c</tt>, <tt>l2xacts.h</tt>
+<dd> standard action functions.
+<dt><tt>l2xusrlb.c</tt>, <tt>l2xusrlb.h</tt>
+<dd> special actions and user-defined functions.
+<dt><tt>strtypes.h</tt>
+<dd> header file with some type definitions.
+<dt><tt>getopt.c</tt>, <tt>getopt.h</tt>
+<dd> functions for handling command line
+ options Chapter 6[<a href="#LIBES93">LIBES93</a>].
+<dt><tt>srchenv.c</tt>, <tt>srchenv.h</tt>
+<dd> functions for searching directories
+ for files page 747[<a href="#HOLUB90">HOLUB90</a>].
+</dl>
+
+
+<p>The EXPRESS-A interpreter also requires the following files:
+<dl>
+<dt><tt>l2xistup.c</tt>
+<dd> the interface between the main part of LTX2X
+ and the interpreter.
+<dt><tt>l2xicmon.h</tt>
+<dd> header file for the interface.
+<dt><tt>l2xirtne.c</tt>, <tt>l2xistd.c</tt>, <tt>l2xidecl.c</tt>,
+ <tt>l2xistmt.c</tt>, <tt>l2xiexpr.c</tt>
+<dd> the files that contain the code for
+ parsing EXPRESS-A. Respectively they deal with functions and procedures,
+ the built-in functions, declarations, statements, and expressions.
+<dt><tt>l2xiprse.h</tt>
+<dd> header file for parsing.
+<dt><tt>l2xixutl.c</tt>, <tt>l2xiexec.h</tt>
+<dd> utility routines
+ supporting the execution module and
+ for managing the interpreter's stack.
+<dt><tt>l2xixstd.c</tt>, <tt>l2xixstm.c</tt>, <tt>l2xixxpr.c</tt>
+<dd> functions for
+ executing the EXPRESS-A built in functions, statements and expressions.
+<dt><tt>l2xirexp.c</tt>, <tt>l2xirexpr.h</tt>
+<dd> general functions for processing
+ and executing regular expressions.
+<dt><tt>listsetc.c</tt>, <tt>listsetc.h</tt>
+<dd> general functions for processing
+ lists.
+<dt><tt>l2xiscan.c</tt>, <tt>l2xiscan.h</tt>
+<dd> lexing routines for the interpreter.
+<dt><tt>l2xisymt.c</tt>, <tt>l2xisymt.h</tt>
+<dd> routines for managing the
+ interpreter's symbol tables.
+<dt><tt>l2xidbug.c</tt>
+<dd> the source level debugger.
+<dt><tt>l2xierr.c</tt>, <tt>l2xierr.h</tt>
+<dd> EXPRESS-A language error handling
+ and diagnostic output for the user.
+<dt><tt>l2xiidbg.c</tt>, <tt>l2xiidbg.h</tt>, <tt>l2xisdcl.c</tt>
+<dd> diagnostics
+ for a developer of the interpreter.
+<dt><tt>licomsym.h</tt>
+<dd> general header file for the interpreter modules.
+<dt><tt>l2xidftc.h</tt>, <tt>l2xiertc.h</tt>, <tt>l2xisctc.h</tt>, <tt>l2xisftc.h</tt>
+<dd>
+header files containing keywords and their representations as strings.
+</dl>
+
+
+<p>The following files may be useful:
+<dl>
+<dt><tt>man</tt>
+<dd> the manpage
+<dt><tt>printct.c</tt>
+<dd> a program to print and update command table files;
+<dt><tt>ltx2html.sty</tt>
+<dd> a LaTeX package file to assist in retagging
+a LaTeX document to an HTML document.
+</dl>
+
+
+<p>Essentially, installing LTX2X consists of processing the file <tt>l2x.l</tt>
+through a lexer generator, processing the file <tt>l2x.y</tt> through a
+parser generator, and then compiling the results together with the other
+supplied source files.
+
+
+<p>The lexer source file <tt>l2x.l</tt> and the parser source file
+<tt>l2x.y</tt> have to be processed by flex (or equivalent) and bison
+(or equivalent) respectively to generate C code. This code, together
+with the code in the other source files must then be compiled
+and linked to form the executable.
+
+
+<p>The executable must then, after suitable testing, be moved to
+its final place in your system and the manpage (file <tt>man</tt>)
+also copied to its final position in your directory structure.
+
+
+<p>Included in the LTX2X distribution are several command table files. One is
+<tt>detex.ct</tt> which provides an example of commands for de-TeX ing
+a document. (Footnote: You may wish to try using <tt>detex.ct</tt> on the
+LaTeX source of this document to see what the effect is. This can
+also serve as a check on the system installation.)
+Another is <tt>remcom.ct</tt>
+which provides an example of commands to remove comments from a
+LaTeX document. The command table file <tt>bye.ct</tt> replaces a LaTeX
+document by "Goodbye document".
+Another is <tt>ltx2x.ct</tt> which does nothing except try and include
+another file named <tt>ZiLcH</tt>, which presumably is not on anyone's
+system. Running LTX2X with this file will prompt for another name of a
+file if it cannot find <tt>ZiLcH</tt>; enter an existing file (like <tt>detex.ct</tt>)
+at the prompt. (Footnote: This is one way of setting up LTX2X for interactive
+specification of the desired command table file(s).)
+
+
+<p>The command table file <tt>l2h.ct</tt> has proven to be adequate for converting
+the LaTeX source of this manual, and other LaTeX documents without
+pictures and only limited mathematics, into an ASCII file with HTML
+tags instead.
+
+
+<p>The file <tt>fun.ct</tt> contains some test code for the EXPRESS-A
+interpreter. The contents are similar to the example shown at the end of
+section <a href="#sec:expressa">sec:expressa</a>.
+
+
+<p>The <tt>l2xusrlb</tt> files are skeletons. The system does include
+the functions and parser constructs for the <samp>\GRAMMspecial</samp> and
+<samp>\CODEspecial</samp> commands used as examples previously. The last two
+entries in <tt>remcom.ct</tt> are the specification of these, and the
+implementation is as described previously.
+
+
+<p>
+<h3>Command table printing</h3>
+
+
+
+<p>The grammar of the command table has been changed slightly since the
+initial release of LTX2X. The utility C program in <tt>printct.c</tt> may be used to:
+<ul>
+
+
+ <li> Pretty-print a command table;
+
+ <li> Convert an original command table to one that conforms to the new grammar.
+</ul>
+
+
+
+<p>The syntax for running <tt>printct</tt> is:
+<pre>
+printct [-D dir_cat_char] [-P path_seperators] [-f table_file] [-t]
+</pre>
+where elements in square brackets are options. These options are identical
+to the corresponding ones for LTX2X and are as follows:
+<dl>
+<dt>-f
+<dd> By default, <tt>printct</tt> reads the command table from a file called
+ <tt>ltx2x.ct</tt>. If the required command table is in a file with another name this
+ option is used to change from the default file. For example,
+<pre>
+> printct
+</pre>
+reads a command table from <samp>ltx2x.ct</samp>, while
+<pre>
+> printct -f detex.ct
+</pre>
+reads a command table from file <samp>detex.ct</samp>.
+
+
+<p><dt>-t
+<dd> This generates some diagnostics related to the processing of
+ the command table file.
+
+
+<p><dt>-D
+<dd> The value of this option is the character that the operating system
+ uses to catenate directory names to form a path (see <a href="#sec:search">sec:search</a>).
+ The default value is a
+ slash (i.e. <samp>/</samp>). The default could be changed to a backslash, for example,
+ by <samp>-D \</samp>.
+
+
+<p><dt>-P
+<dd> The environment variable (see <a href="#sec:search">sec:search</a>)
+ contains a list of directories (also known
+ as path names). In the operating system that I use, these are separated by
+ the colon (<samp>:</samp>) character which, together with the semi-colon
+ and space characters, form
+ the LTX2X default separators. The path separator characters can be changed
+ with this option.
+ For example, <samp>-P :</samp> will make the separators be a colon
+ or a space (space is automatically included in the separator list).
+</dl>
+
+
+<p><tt>printct</tt> only reads a single command table file and outputs the
+pretty-printed and updated version to file <tt>printct.lis</tt>. It performs
+a very limited amount of error checking and writes error messages and
+statistics to the file <tt>printct.err</tt>.
+
+
+<p>
+
+<h3>A make file</h3>
+
+
+
+<p>
+ Here is a UNIX <tt>make</tt> file [<a href="#ORAM91">ORAM91</a>] for the LTX2X system.
+
+
+<p><pre>
+# makefile for program ltx2x --- LaTeX to X autotagger
+#
+##################### Change the following for your setup
+# The compiler
+CC = cc
+
+# We use flex (or equivalent, but not lex) to generate the lexer
+LEX = flex
+# and the options
+LEXFLAGS = -v
+
+# We use bison (or equivalent) to generate the parser
+YACC = bison
+# and the options
+YACCFLAGS = -y -d -v
+
+# Libraries to be used
+LIBS = -ly -ll -lm
+
+# The root directory for the installation (e.g., /usr/local )
+ROOTDIR = /proj/ltx/teTeX033
+
+# Where to place the running code (e.g. /usr/local/bin )
+BINDIR = ${ROOTDIR}/bin
+
+# Where to place the manpage (e.g., /usr/local/man/man1 )
+MANEXT = 1
+MANDIR = ${ROOTDIR}/man/man${MANEXT}
+
+# Just in case you want to change the name of the binary
+# (and then you should also change the man page and documentation).
+# So, do not change this.
+PROG = ltx2x
+
+# Where to place the user documentation (e.g., /usr/local/doc/ltx2x )
+DOCDIR = ${ROOTDIR}/doc/${PROG}
+
+# Where to place the example command tables (e.g., /usr/local/lib/config/ltx2x )
+CTDIR = ${ROOTDIR}/lib/config/${PROG}
+
+# The file copy command (copy but do not delete original)
+COPY = cp
+
+# The file move command (move and delete original)
+MOVE = mv
+
+# The file delete command
+DELETE = rm
+
+# The make directory (hierarchy) command
+MAKEDIR = mkdirhier
+
+# The stream editor command
+SED = sed
+
+# Command to write to the terminal (stdout)
+ECHO = echo
+
+################### You should not have to change anything after this
+
+# The source modules
+L2XSRCS = l2xytab.c l2xlexyy.c l2xlib.c l2xacts.c l2xusrlb.c
+getopt.c srchenv.c
+
+INTSRCS = l2xirtne.c l2xistd.c l2xidecl.c l2xistmt.c l2xiexpr.c
+l2xiscan.c l2xisymt.c l2xierr.c l2xiidbg.c l2xistup.c l2xistm.c
+l2xixxpr.c l2xixstd.c l2xidbug.c l2xisdcl.c l2xirexp.c listsetc.c
+
+# The object modules
+L2XOBJS = l2xytab.o l2xlexyy.o l2xlib.o l2xacts.o l2xusrlb.o
+ getopt.o srchenv.o
+
+INTSRCS = l2xirtne.o l2xistd.o l2xidecl.o l2xistmt.o l2xiexpr.o
+l2xiscan.o l2xisymt.o l2xierr.o l2xiidbg.o l2xistup.o l2xistm.o
+l2xixxpr.o l2xixstd.o l2xidbug.o l2xisdcl.o l2xirexp.o listsetc.o
+
+OBJS = ${L2XOBJS} ${INTOBJS}
+
+# Link object code together into PROG
+ltx2x : ${OBJS}
+ ${CC} -o ${PROG} ${OBJS} ${LIBS}
+
+# Compile C source code into object code
+getopt.o : getopt.c getopt.h
+ ${CC} -c getopt.c
+l2xytab.o : l2xytab.c l2xlib.h l2xusrlb.h l2xacts.h strtypes.h l2xcom.h
+ ${CC} -c l2xytab.c
+l2xlexyy.o : l2xlexyy.c l2xytab.h l2xlib.h l2xusrlb.h l2xcom.h
+ ${CC} -c l2xlexyy.c
+l2xlib.o : l2xlib.c getopt.h l2xytab.h strtypes.h l2xcom.h
+ ${CC} -c l2xlib.c
+l2xusrlb.o : l2xusrlb.c l2xlib.h l2xytab.h strtypes.h l2xcom.h
+ ${CC} -c l2xusrlb.c
+l2xacts.o : l2xacts.c l2xusrlb.h l2xlib.h l2xytab.h strtypes.h l2xcom.h
+ ${CC} -c l2xacts.c
+srchenv.o : srchenv.c srchenv.h
+ ${CC} -c srchenv.c
+
+# Generate C code for parsing
+l2xytab.c l2xytab.h: l2x.y
+ @ ${ECHO} "Expect 10 shift/reduce conflicts to be reported"
+ ${YACC} ${YACCFLAGS} l2x.y
+ ${MOVE} y.tab.c l2xytab.c
+ ${MOVE} y.tab.h l2xytab.h
+
+# Generate C code for lexing
+l2xlexyy.c : l2x.l
+ ${LEX} ${LEXFLAGS} l2x.l
+ ${MOVE} lex.yy.c l2xlexyy.c
+
+# the interpreter modules
+
+# compiler flags for analyze and execute modules
+ANLFLAG = -Danalyze
+RUNFLAG = -Dtrace
+
+# interpreter header files
+SOMEH = l2xicmon.h l2xierr.h l2xiscan.h l2xisymt.h licomsym.h l2xiidbg.h
+MOSTH = ${SOMEH} l2xiprse.h
+ALLH = ${MOSTH} l2xicpr.h l2xiexec.h
+
+# interpreter interface
+
+l2xistup.o : l2xistup.c ${ALLH}
+ ${CC} -c ${ANLFLAG} ${RUNFLAG} l2xistup.c
+
+# the parser module
+
+l2xirtne.o : l2xirtne.c ${ALLH}
+ ${CC} -c ${ANLFLAG} l2xirtne.c
+
+l2xistd.o : l2xistd.c ${MOSTH}
+ ${CC} -c ${ANLFLAG} ${RUNFLAG} l2xistup.c
+
+l2xistup.o : l2xistup.c ${ALLH}
+ ${CC} -c l2xistd.c
+
+l2xidecl.o : l2xidecl.c ${MOSTH} l2xicpr.h
+ ${CC} -c ${ANLFLAG} l2xisdecl.c
+
+l2xistmt.o : l2xistmt.c ${ALLH}
+ ${CC} -c ${ANLFLAG} l2xistmt.c
+
+l2xiexpr.o : l2xiexpr.c ${MOSTH} l2xicpr.h
+ ${CC} -c ${ANLFLAG} l2xiexpr.c
+
+# the scanner module
+
+l2xiscan.o : l2xiscan.c ${SOMEH} l2xicpr.h
+ ${CC} -c ${ANLFLAG} l2xiscan.c
+
+# symbol table module
+
+l2xisymt.o : l2xisymt.c l2xicmon.h l2xierr.h l2xisymt.h licomsym.h l2xiidbg.h
+ ${CC} -c l2xisymt.c
+
+# executor module
+
+l2xixutl.o : l2xixutl.c ${MOSTH} l2xiexec.h listsetc.h
+ ${CC} -c ${RUNFLAG} l2xixutl.c
+
+l2xixstm.o : l2xixstm.c ${MOSTH} l2xiexec.h listsetc.h
+ ${CC} -c ${RUNFLAG} l2xixstm.c
+
+l2xixxpr.o : l2xixxpr.c ${MOSTH} l2xiexec.h listsetc.h
+ ${CC} -c ${RUNFLAG} l2xixxpr.c
+
+l2xixstd.o : l2xixstd.c ${MOSTH} l2xiexec.h listsetc.h
+ ${CC} -c ${RUNFLAG} l2xixstd.c
+
+l2xidbug.o : l2xidbug.c ${SOMEH} l2xiexec.h listsetc.h
+ ${CC} -c ${RUNFLAG} l2xidbug.c
+
+# error and miscellaneous
+
+l2xisdcl.o : l2xisdcl.c ${SOMEH}
+ ${CC} -c ${ANLFLAG} ${RUNFLAG} l2xisdcl.c
+
+l2xiidbg.o : l2xiidbg.c ${SOMEH} l2xiexec.h
+ ${CC} -c l2xiidbg.c
+
+l2xirexp.o : l2xirexp.c l2xirexp.h
+ ${CC} -c l2xirexp.c
+
+listsetc.o : listsetc.c listsetc.h
+ ${CC} -c listsetc.c
+
+# only call make install if BINDIR has been set
+install : ltx2x
+ ${MAKEDIR} ${BINDIR}
+ ${MOVE} ${PROG} ${BINDIR}
+
+# Edit the file man to replace DOCUMENTDIR by the actual directory
+# where the user manual is to be placed, and CTDIR by the location
+# of the example command table files.
+# Then copy the manpage to the proper place
+manpage :
+ ${SED} 's!DOCUMENTDIR!${DOCDIR}!; s!CTDIR!${CTDIR}!' man > tman
+ ${MAKEDIR} ${MANDIR}
+ ${COPY} tman ${MANDIR}/${PROG}.${MANEXT}
+
+# Copy the user manuals to the proper place
+doc :
+ ${MAKEDIR} ${DOCDIR}
+ ${COPY} ltx2x.tex ${DOCDIR}/${PROG}.tex
+ ${COPY} ltx2x.ps ${DOCDIR}/${PROG}.ps
+ ${COPY} ltx2x.txt ${DOCDIR}/${PROG}.txt
+ ${COPY} ltx2x.html ${DOCDIR}/${PROG}.html
+
+# Copy the example command tables to their final location
+ctables :
+ ${MAKEDIR} ${CTDIR}
+ ${COPY} ltx2x.ct ${CTDIR}/ltx2x.ct
+ ${COPY} detex.ct ${CTDIR}/detex.ct
+ ${COPY} remcom.ct ${CTDIR}/remcom.ct
+ ${COPY} l2h.ct ${CTDIR}/l2h.ct
+ ${COPY} bye.ct ${CTDIR}/bye.ct
+ ${COPY} fun.ct ${CTDIR}/fun.ct
+
+# Do almost everything except clean up
+all : ltx2x install manpage doc ctables
+
+# call make clean to remove the object files, info from YACC,
+# and the edited version of the manpage
+clean :
+ ${DELETE} *.o
+ ${DELETE} y.output
+ ${DELETE} tman
+
+# Compile the command table printer
+printct : printct.o getopt.o srchenv.o
+ ${CC} -o printct printct.o getopt.o srchenv.o
+
+printct.o : printct.c getopt.h strtypes.h l2xcom.h
+ ${CC} -c printct.c
+</pre>
+
+<p>If you use the above makefile then the first part should be edited
+to reflect your system's configuration. You could do <samp>make all</samp>
+which should do everything for you, except the cleaning up.
+A more conservative approach is recommended. First
+just do <samp>make</samp> which will generate the executable. This can then be
+tested. When all is well do <samp>make install</samp> and <samp>make manpage</samp>
+which will put the executable and the manpage into their final positions.
+Finally, <samp>make clean</samp> will remove the intermediate files generated
+during the build process.
+
+
+<p>The above <tt>make</tt> file uses flex as the lexer generator. You can use your
+favorite one instead but it must, unlike lex, support exclusive start states.
+Also, bison is used above as the parser generator. Again, you can use your
+favorite one. As far as I am aware, there is nothing remarkable about the
+grammar, except that during early development I exceeded the size limits
+of yacc. The grammar has been simplified since then, so this may no longer
+be a problem. <br>
+NOTE: If bison is used it reports that there are 10 shift/reduce
+conflicts. It appears that these can be safely ignored.
+
+
+<p>One compilation problem has been noted by Uwe
+Sassenberg (Footnote: <tt>&lt;sassen@hal1.physik.uni-dortmund.de&gt;</tt>)
+on AIX 3.2 and
+IRIX 5.3 systems, but I could not reproduce it on a SunOS 4.1.3 system. This
+is when the main procedure of LTX2X is processing the optional command
+line arguments. For some reason it had difficulties with the C
+<samp>EOF</samp>. The symptom was that the program compiled but when it was
+run
+it sat there absorbing CPU cycles and doing nothing as it had got into
+an infinite <samp>while</samp> loop. The cure was to insert
+the following line of code in file <tt>l2xlib.c</tt>:
+<pre>
+main(argc,argv)
+...
+ /* get command line optional parameters */
+ opterr = 1; /* getopt prints errors if opterr is 1 */
+ while (EOF != (optchar =
+ getopt(argc,argv, "l:ty:f:cp:wE:P:D:"))) {
+/* insert this line of code: if (optchar == 255) break; end insert */
+ switch(optchar) {
+...
+</pre>
+This code line which you may need to insert is supplied as a comment in
+the distributed source.
+
+
+<p>
+<h3>Limits and errors</h3>
+
+
+
+<p>The LTX2X system has some built-in limits which are defined in <tt>l2xlib.c</tt>.
+The following is a listing of the relevant sizes.
+
+
+<p><dl>
+<dt><samp>CLAUSE_STACK_SIZE</samp>
+<dd> The maximum nesting depth of
+document sectioning. This is set somewhat larger than the number of
+standard LaTeX sectioning command types.
+(Default 10)
+
+
+<p><dt><samp>EVERY_N_LINES</samp>
+<dd> Controls the frequency of printing
+processed line numbers to the terminal.
+(Default 100)
+
+
+<p><dt><samp>LIST_STACK_SIZE</samp>
+<dd> The maximum nesting depth of list
+environments. This is set somewhat larger than the standard LaTeX nesting depth.
+(Default 10)
+
+
+<p><dt><samp>MAX_BUFFER</samp>
+<dd> The maximum number of characters that can be held
+in the system buffer, and also the maximum number of characters in a
+pretty-printed output line.
+(Default 2000)
+
+
+<p><dt><samp>MAX_CT_STACK</samp>
+<dd> The maximum nesting depth for included
+command table files.
+(Default 20)
+
+
+<p><dt><samp>MAX_ERRORS</samp>
+<dd> The maximum number of non-fatal errors
+discovered in command table processing or in source file processing before
+LTX2X quits.
+(Default 10)
+
+
+<p><dt><samp>MAX_LINE</samp>
+<dd> The maximum number of characters in a line of
+a LaTeX source file.
+(Default 2000)
+
+
+<p><dt><samp>MAX_PRINT_STACK</samp>
+<dd> The maximum nesting depth for print
+control commands.
+(Default 100)
+
+
+<p><dt><samp>MAX_TABLE_ENTRIES</samp>
+<dd> The maximum number of
+<samp>TYPE</samp> specifications in a command table (including the built in
+type specifications).
+(Default 1000)
+
+
+<p><dt><samp>MAX_TABLE_LINE</samp>
+<dd> The maximum number of characters in a line in
+a command table file.
+(Default 254)
+
+
+<p><dt><samp>MAX_USER_BUFFS</samp>
+<dd> The maximum number of user buffers.
+(Default 20)
+
+
+<p><dt><samp>MAX_UBUFF_LEN</samp>
+<dd> The maximum number of characters that can be
+stored in a user buffer.
+(Default 510)
+
+
+<p><dt><samp>MAX_USER_FILES</samp>
+<dd> The maximum number of user files.
+(Default 16)
+</dl>
+
+
+<p>LTX2X prints out a summary of the program statistices at the end of
+the <tt>ltx2x.err</tt> file.
+ If the limits are not suitable for your purposes, then they may be changed and
+the system rebuilt.
+
+
+<p>LTX2X can produce a variety of error and warning messages, for example
+when any of the above limits are exceeded. Some of the messages are related
+to command table processing, while others are related to LaTeX document
+processing. Both these kinds of messages are targeted to the normal
+end user. There is another set of messages that are aimed at the implementor
+of new <samp>SPECIAL_</samp> commands. An implementor may also find some of the
+debugging options useful if things really fall apart.
+
+
+<p>
+
+<h3>Availability</h3>
+
+
+
+<p>Source code and documentation for LTX2X is available from the
+NIST SOLIS (SC4 On-Line Information Service) system [<a href="#RINAUDOT94">RINAUDOT94</a>]
+in directory <br>
+<tt>/subject/sc4/editing/latex/programs/ltx2x</tt>. <br>
+ SOLIS can be accessed by:
+<ul>
+
+
+ <li> Anonymous ftp to <tt>ftp.cme.nist.gov</tt> (<tt>cd</tt> to <tt>/pub/subject/sc4...</tt>)
+
+ <li> URL <a href="http://www.nist.gov/sc4">http://www.nist.gov/sc4</a>
+</ul>
+
+
+
+<p>Any comments should be directed to <tt>apde@cme.nist.gov</tt>.
+
+
+<p>
+<h4>Copyright</h4>
+
+
+<p>Development of this software was funded by the United States Government
+and is not subject to copyright. It was developed by the
+Manufacturing Systems Integration Division (MSID) of the
+Manufacturing Engineering Laboratory (MEL) of the
+National Institute of Standards and Technology (NIST).
+
+
+<p>
+<h4>Disclaimer</h4>
+
+
+<p>There is no warranty for the LTX2X software. If the LTX2X software
+is modified by someone else and passed on, NIST requests that the software's
+recipients be notified that what they have is not what NIST distributed.
+
+
+<p><dl>
+<dt>Policies
+<dd> <ol>
+
+
+ <li> Anyone may copy and distribute verbatim copies of the
+ source code as received in any medium.
+
+ <li> Anyone may modify your copy or copies of the LTX2X source
+ code or any portion of it, and copy and distribute such
+ modifications provided that all modifications are clearly
+ associated with the entity that performs the modifications.
+</ol>
+
+
+
+<p><dt>NO WARRANTY
+<dd>
+<p>NIST PROVIDES ABSOLUTELY NO WARRANTY. THE LTX2X SOFTWARE IS
+PROVIDED `AS IS' WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE
+RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.
+SHOULD ANY PORTION OF THE LTX2X SOFTWARE PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+
+<p>IN NO EVENT WILL NIST BE LIABLE FOR DAMAGES, INCLUDING ANY
+LOST PROFITS, LOST MONIES, OR OTHER SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE
+(INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED
+INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR A FAILURE OF
+THE PROGRAM TO OPERATE WITH PROGRAMS NOT DISTRIBUTED BY NIST)
+THE PROGRAMS, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY
+OF SUCH DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY.
+</dl>
+
+
+<p>
+
+<h2>A grammar for the command table</h2>
+ <a name="sec:ctabgrammar"></a>
+
+
+<p>
+<h3>Notation</h3>
+
+
+
+<p>The syntactical constructs used correspond to a derivative of
+the Wirth Syntax Notation (WSN) [<a href="#WIRTH77">WIRTH77</a>]. The semantics of the
+enclosing braces are:
+<ul>
+
+
+ <li> curly braces `<tt>{ }</tt>' indicate xero or more repetitions;
+
+ <li> square brackets `<tt>[ ]</tt>' indicate an optional element;
+
+ <li> parenthesis `<tt>( )</tt>' indicates a group;
+
+ <li> vertical bar `<tt>|</tt>' indicates that exactly one of the
+ terms in the expression shall be chosen.
+</ul>
+
+
+
+<p>Here is the grammar for WSN defined in itself.
+<pre>
+syntax = { production } .
+production = identifier '=' expression '.' .
+expression = term { '|' term } .
+term = factor { factor } .
+factor = identifier | literal | group | option | repetition .
+identifier = character { character } .
+literal = '''' character { character } '''' .
+group = '(' expression ')' .
+option = '[' expression ']' .
+repetition = '{' expression '}' .
+</pre>
+
+<p>We also use the following shorthand notation for particular characters:
+<ul>
+
+
+ <li> <samp>\c</samp> --- any printable character
+
+ <li> <samp>\n</samp> --- the end of line character(s)
+
+ <li> <samp>eof</samp> --- the end of file character(s)
+</ul>
+
+
+
+<p>
+<h3>Grammar</h3>
+
+
+
+<p>First, the keywords. Note that these are case insensitive.
+<pre>
+AudibleAlertChar = 'AUDIBLE_ALERT_CHAR=' .
+BackspaceChar = 'BACKSPACE_CHAR=' .
+BeginDocument = 'BEGIN_DOCUMENT' .
+BeginDollar = 'BEGIN_DOLAR' .
+BeginEnv = 'BEGIN_ENV' .
+BeginListEnv = 'BEGIN_LIST_ENV' .
+BeginPictureCc = 'BEGIN_PICTURE_CC' .
+BeginVenv = 'BEGIN_VENV' .
+BeginVerb = 'BEGIN_VERB' .
+BeginVerbatim = 'BEGIN_VERBATIM' .
+Buffer = 'BUFFER' .
+CarriageReturnChar = 'CARRIAGE_RETURN_CHAR=' .
+Chapter = 'CHAPTER' .
+CharCommand = 'CHAR_COMMAND' .
+Command = 'COMMAND' .
+CommandOop = 'COMMAND_OOP' .
+CommandOoopp = 'COMMAND_OOOPP' .
+CommandOpo = 'COMMAND_OPO' .
+CommandPooop = 'COMMAND_POOOP' .
+CommandPoop = 'COMMAND_POOP' .
+CommandPoopp = 'COMMAND_POOPP' .
+Comment = 'C=' .
+EndCtfile = 'END_CTFILE=' .
+EndDocument = 'END_DOCUMENT' .
+EndDollar = 'END_DOLAR' .
+EndEnv = 'END_ENV' .
+EndItem = 'END_ITEM=' .
+EndItemParam = 'END_ITEM_PARAM=' .
+EndListEnv = 'END_LIST_ENV' .
+EndMode = 'END_MODE' .
+EndOpt = 'END_OPT=' .
+EndPicture = 'END_PICTURE' .
+EndTag = 'END_TAG=' .
+EndTag1 = 'END_TAG_1=' .
+EndTag2 = 'END_TAG_2=' .
+EndTag3 = 'END_TAG_3=' .
+EndTag4 = 'END_TAG_4=' .
+EndTag5 = 'END_TAG_5=' .
+EndTag6 = 'END_TAG_6=' .
+EndTag7 = 'END_TAG_7=' .
+EndTag8 = 'END_TAG_8=' .
+EndTag9 = 'END_TAG_9=' .
+EndType = 'END_TYPE' .
+EndVenv = 'END_VENV' .
+EndVerb = 'END_VERB' .
+EndVerbatim = 'END_VERBATIM' .
+EscapeChar = 'ESCAPE_CHAR=' .
+File = 'FILE' .
+First = 'FIRST' .
+FormfeedChar = 'FORMFEED_CHAR=' .
+HexChar = 'HEX_CHAR=' .
+HorizontalTabChar = 'HORIZONTAL_TAB_CHAR=' .
+Include = 'INCLUDE=' .
+InMode = 'IN_MODE=' .
+Last = 'LAST' .
+Lbrace = 'LBRACE' .
+Name = 'NAME=' .
+NewlineChar = 'NEWLINE_CHAR=' .
+NoOp = 'NO_OP' .
+NoPrint = 'NO_PRINT' .
+OptParam = 'OPT_PARAM=' .
+OtherBegin = 'OTHER_BEGIN' .
+OtherCommand = 'OTHER_COMMAND' .
+OtherEnd = 'OTHER_END' .
+Para = 'PARA' .
+Paragraph = 'PARAGRAPH' .
+Part = 'PART' .
+Partm1 = 'PARTm1' .
+Partm2 = 'PARTm2' .
+PcAtEnd = 'PC_AT_END=' .
+PcAtStart = 'PC_AT_START=' .
+PictureCcpp = 'PICTURE_CCPP' .
+PictureCo = 'PICTURE_CO' .
+PictureCop = 'PICTURE_COP' .
+PictureCp = 'PICTURE_CP' .
+PictureOcc = 'PICTURE_OCC' .
+PictureOccc = 'PICTURE_OCCC' .
+PictureOco = 'PICTURE_OCO' .
+PicturePcop = 'PICTURE_PCOP' .
+PrintControl = 'PRINT_CONTROL=' .
+PrintP1 = 'PRINT_P1=' .
+PrintP2 = 'PRINT_P2=' .
+PrintP3 = 'PRINT_P3=' .
+PrintP4 = 'PRINT_P4=' .
+PrintP5 = 'PRINT_P5=' .
+PrintP6 = 'PRINT_P6=' .
+PrintP7 = 'PRINT_P7=' .
+PrintP8 = 'PRINT_P8=' .
+PrintP9 = 'PRINT_P9=' .
+PrintOpt = 'PRINT_OPT=' .
+Rbrace = 'RBRACE' .
+Reqparams = 'REQPARAMS=' .
+Reset = 'RESET' .
+ResetBuffer = 'RESET_BUFFER:' .
+ResetMode = 'RESET_MODE:' .
+Sect = 'SECT' .
+Sectioning = 'SECTIONING' .
+SectioningLevel = 'SECTIONING_LEVEL=' .
+SetMode = 'SET_MODE:' .
+SlashSpace = 'SLASH_SPACE' .
+Source = 'SOURCE:' .
+Special = 'SPECIAL' .
+SpecialBeginEnv = 'SPECIAL_BEGIN_ENV' .
+SpecialBeginList = 'SPECIAL_BEGIN_LIST' .
+SpecialCommand = 'SPECIAL_COMMAND' .
+SpecialEndEnv = 'SPECIAL_END_ENV' .
+SpecialEndList = 'SPECIAL_END_LIST' .
+SpecialSectioning = 'SPECIAL_SECTIONING' .
+StartItem = 'START_ITEM=' .
+StartItemParam = 'START_ITEM_PARAM=' .
+StartOpt = 'START_OPT=' .
+StartTag = 'START_TAG=' .
+StartTag1 = 'START_TAG_1=' .
+StartTag2 = 'START_TAG_2=' .
+StartTag3 = 'START_TAG_3=' .
+StartTag4 = 'START_TAG_4=' .
+StartTag5 = 'START_TAG_5=' .
+StartTag6 = 'START_TAG_6=' .
+StartTag7 = 'START_TAG_7=' .
+StartTag8 = 'START_TAG_8=' .
+StartTag9 = 'START_TAG_9=' .
+String = 'STRING:' .
+SubPara = 'SUBPARA' .
+SubParap1 = 'SUBPARAp1' .
+SubParap2 = 'SUBPARAp2' .
+SubSect = 'SUBSECT' .
+SubSubSect = 'SUBSUBSECT' .
+SwitchBack = 'SWITCH_BACL: ' .
+SwitchToBuffer = 'SWITCH_TO_BUFFER: ' .
+SwitchToFile = 'SWITCH_TO_FILE: ' .
+SwitchToSysbuf = 'SWITCH_TO_SYSBUF: ' .
+Sysbuf = 'SYSBUF' .
+TexChar = 'TEX_CHAR' .
+ToBuffer = 'TO_BUFFER' .
+ToFile = 'TO_FILE' .
+ToSysbuf = 'TO_SYSBUF' .
+Type = 'TYPE=' .
+Vcommand = 'VCOMMAND' .
+VerticalTabChar = 'VERTICAL_TAB_CHAR=' .
+</pre>
+
+<p>Some utility productions.
+<pre>
+latex_id = \c { \c } .
+name = \c { \c } .
+text = '"' { \c } '"' .
+Eol = \n .
+digit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' .
+integer = digit { digit } .
+ct_file_name = name .
+file_id = name .
+buffer_id = integer .
+mode_id = name .
+</pre>
+
+<p>The starting production.
+<pre>
+table = [ special_chars ] { specification | inclusion | comment } eof .
+</pre>
+
+<p>Productions for <samp>inclusion</samp> and <samp>comment</samp> and <samp>eof</samp>.
+<pre>
+inclusion = Include ct_file_name Eol .
+comment = Comment { \c } Eol .
+eof = EndCtfile { \c } Eol .
+</pre>
+
+<p>Productions for <samp>special_chars</samp>.
+<pre>
+special_chars = [ escape ] [ alert ] [ backspace ] [ return ] [ feed ]
+ [ hex ] [ htab ] [ newline ] [ vtab ] { comment } .
+escape = EscapeChar \c Eol Eol .
+alert = AudibleAlertChar \c Eol .
+backspace = BackspaceChar \c Eol .
+return = CarriageReturnChar \c Eol .
+feed = FormfeedChar \c Eol .
+hex = HexChar \c Eol .
+htab = HorizontalTabChar \c Eol .
+newline = NewlineChar \c Eol .
+vtab = VerticalTabChar \c Eol .
+</pre>
+
+<p>
+
+Productions for <samp>specification</samp>.
+<pre>
+specification = built_in | normal | list | section | special | picture | odd .
+built_in = (Type built_in_type Eol) [ built_in_body ] end_type .
+end_type = EndType Eol .
+built_in_type = BeginDocument | BeginDollar | BeginVerb | BeginVerbatim |
+ EndDocument | EndDollar | EndVerb | EndVerbatim |
+ Lbrace | OtherBegin | OtherCommand | OtherEnd |
+ Paragraph | Rbrace | SlashSpace .
+normal = (Type normal_type Eol) type_name [ normal_body ] end_type .
+type_name = Name latex_id Eol .
+normal_type = BeginEnv | BeginVenv | CharCommand | Command |
+ EndEnv | EndVenv | TexChar | Vcommand .
+list = (Type list_type Eol) type_name [ list_body ] end_type .
+list_type = BeginListEnv | EndListEnv .
+section = (Type Sectioning Eol) type_name [ section_body ] end_type .
+special = (Type special_type Eol) type_name [ special_body ] end_type .
+special_type = Special | SpecialBeginEnv | SpecialBeginList |
+ SpecialCommand | SpecialEndEnv | SpecialEndList |
+ SpecialSectioning .
+picture = (Type picture_type Eol) type_name [ picture_body ] end_type .
+picture_type = BeginPictureCc | EndPicture | PictureCcpp | PictureCo |
+ PictureCop | PictureCp | PictureOcc |
+ PictureOccc | PictureOco | PicturePcop .
+odd = (Type odd_type Eol) type_name [ odd_body ] end_type .
+odd_type = CommandOop | CommandOoopp | CommandOpo |
+ CommandPooop | CommandPoop | CommandPoopp .
+</pre>
+
+<p>The <samp>X_body</samp> productions.
+<pre>
+built_in_body = [ basic_body ]
+ { start_mode [ basic_body ] end_mode } .
+start_mode = InMode mode_id Eol .
+end_mode = EndMode Eol .
+normal_body = [ basic_norm_body ]
+ { start_mode [ basic_norm_body ] end_mode } .
+sect_body = [ basic_sect_body ]
+ { start_mode [ basic_sect_body ] end_mode } .
+list_body = [ basic_list_body ]
+ { start_mode [ basic_list_body ] end_mode } .
+picture_body = [ basic_defarg_body ]
+ { start_mode [ basic_defarg_body ] end_mode } .
+odd_body = [ basic_defarg_body ]
+ { start_mode [ basic_defarg_body ] end_mode } .
+special_body = [ basic_special_body ]
+ { start_mode [ basic_special_body ] end_mode } .
+</pre>
+
+<p>
+Note: the ordering of the components of the following
+<samp>basic_X_body</samp> productions is immaterial.
+<pre>
+basic_body = [ start_it ] [ end_it ] .
+basic_norm_body = [ basic_body ] [ no_req_arg ] [ opt_arg_pos ]
+ { arg_print } { arg_action } .
+basic_sect_body = sect_level [ basic_norm_body ] .
+sect_level = SectioningLevel div_level Eol .
+div_level = Chapter | Para | Part | Partm1 | Partm2 | Sect | Subpara |
+ Subparap1 | Subparap2 | Subsect | Subsubsect .
+basic_defarg_body = [ basic_body ] { arg_print } { arg_action } .
+basic_list_body = [ basic_norm_body ] { item_action } .
+basic_special_body = [ sect_level ] [ basic_list_body ] .
+no_req_arg = Reqparams integer Eol .
+opt_arg_pos = OptParam ( First | Last ) Eol .
+</pre>
+
+<p>The <samp>start_it</samp> and <samp>end_it</samp> productions.
+<pre>
+start_it = [ start_print ] [start_action ] .
+start_print = PcAtStart ( basic_pc_kind | Reset ) Eol .
+basic_pc_kind = NoPrint | ToSysbuf | print_to_buffer | print_to_file .
+print_to_buffer = ToBuffer buffer_id .
+print_to_file = ToFile file_id .
+start_action = StartTag [ text ] Eol { tag_action } .
+tag_action = ( String text |
+ Source ( Sysbuf | user_buffer | user_file ) |
+ ResetBuffer buffer_id |
+ ResetFile file_id |
+ ResetSysbuf |
+ SwitchToBuffer buffer_id |
+ SwitchToFile file_id |
+ SwitchToSysbuf |
+ SwitchBack |
+ SetMode mode_id |
+ ResetMode )
+ Eol .
+user_buffer = Buffer buffer_id .
+user_file = File file_id .
+end_it = [ end_print ] [ end_action ] .
+end_print = PcAtEnd (basic_pc_kind | Reset) Eol .
+end_action = EndTag [ text ] Eol { tag_action } .
+</pre>
+
+<p>The <samp>arg_print</samp> productions.
+<pre>
+arg_print = print_arg_kind (basic_pc_kind | NoOp ) Eol .
+print_arg_kind = PrintOpt | PrintP1 | PrintP2 | PrintP3 | PrintP4 |
+ PrintP5 | PrintP6 | PrintP7 | PrintP8 | PrintP9 .
+</pre>
+
+<p>The <samp>arg_action</samp> productions.
+<pre>
+arg_action = arg_tag_kind [ text ] Eol { tag_action } .
+arg_tag_kind = EndOpt | EndTag1 | EndTag2 | EndTag3 | EndTag4 |
+ EndTag5 | EndTag6 | EndTag7 | EndTag8 | EndTag9 |
+ StartOpt | StartTag1 | StartTag2 | StartTag3 | StartTag4 |
+ StartTag5 | StartTag6 | StartTag7 | StartTag8 | StartTag9 .
+</pre>
+
+<p>The <samp>item_action</samp> productions.
+<pre>
+item_action = item_tag_kind [ text ] Eol { tag_action } .
+item_tag_kind = EndItem | EndItemParam | StartItem | StartItemParam .
+</pre>
+
+<p>The parser in LTX2X for the command table is very simple. For each <samp>TYPE=</samp>
+in the command table it creates a <samp>struct</samp> to hold the specification
+data. If any type is multiply defined, then which one will be finally used
+is somewhat random because of the sorting and searching algorithms employed
+internally. No checks are made for multiply defined entries.
+
+
+<p>Each command in the command table starts on a seperate line.
+ The parser reads only as much of a table line as is necessary to parse that
+line according to the first token that it finds on the line. The data in
+each line after parsing is added to the current <samp>struct</samp> for the
+LaTeX command.
+If any of the command lines within an entry are multiply defined,
+then the latest one will overwrite any earlier ones.
+
+
+<p>This line-based parsing means that effectively anything between the
+end of the required data on the line is ignored by the parser, and so could
+be treated as a comment. There is no guarantee that this behaviour will
+be maintained in future releases of LTX2X.
+
+
+<p>
+<h2>A grammar for EXPRESS-A</h2>
+ <a name="sec:expgrammar"></a>
+
+
+<p>The same WSN notation is used for the grammar for EXPRESS-A as
+for the command table grammar.
+
+
+<p>First the keywords. Note that these are case insensitive. Also
+not all of the keywords have been used in this implementation
+of EXPRESS-A; those that have not been used are reserved for the
+future.
+
+
+<p><pre>
+ ABS = 'abs' .
+ ABSTRACT = 'abstract' .
+ ACOS = 'acos' .
+ AGGREGATE = 'aggregate' .
+ ALIAS = 'alias' .
+ AND = 'and' .
+ ANDOR = 'andor' .
+ ARRAY = 'array' .
+ AS = 'as' .
+ ASIN = 'asin' .
+</pre>
+
+
+<p><pre>
+ ATAN = 'atan' .
+ BAG = 'bag' .
+ BEGIN = 'begin' .
+ BINARY = 'binary' .
+ BLENGTH = 'blength' .
+ BOOLEAN = 'boolean' .
+ BY = 'by' .
+ CALL = 'call' .
+ CASE = 'case' .
+ CONSTANT = 'constant' .
+</pre>
+
+
+<p><pre>
+ CONST_E = 'const_e' .
+ CONTEXT = 'context' .
+ COS = 'cos' .
+ CRITERIA = 'criteria' .
+ DERIVE = 'derive' .
+ DIV = 'div' .
+ ELSE = 'else' .
+ END = 'end' .
+ END_ALIAS = 'end_alias' .
+ END_CALL = 'end_call' .
+</pre>
+
+
+<p><pre>
+ END_CASE = 'end_case' .
+ END_CODE = 'end_code' .
+ END_CONSTANT = 'end_constant' .
+ END_CONTEXT = 'end_context' .
+ END_CRITERIA = 'end_criteria' .
+ END_ENTITY = 'end_entity' .
+ END_FUNCTION = 'end_function' .
+ END_IF = 'end_if' .
+ END_LOCAL = 'end_local' .
+ END_MODEL = 'end_model' .
+</pre>
+
+
+<p><pre>
+ END_NOTES = 'end_notes' .
+ END_OBJECTIVE = 'end_objective' .
+ END_PARAMETER = 'end_parameter' .
+ END_PROCEDURE = 'end_procedure' .
+ END_PURPOSE = 'end_purpose' .
+ END_REALIZATION = 'end_realization' .
+ END_REFERENCES = 'end_references' .
+ END_REPEAT = 'end_repeat' .
+ END_RULE = 'end_rule' .
+ END_SCHEMA = 'end_schema' .
+</pre>
+
+
+<p><pre>
+ END_SCHEMA_DATA = 'end_schema_data' .
+ END_TEST_CASE = 'end_test_case' .
+ END_TYPE = 'end_type' .
+ ENTITY = 'entity' .
+ ENUMERATION = 'enumeration' .
+ EOF = 'eof' .
+ EOLN = 'eoln' .
+ ESCAPE = 'escape' .
+ EXISTS = 'exists' .
+ EXP = 'exp' .
+ FALSE = 'false' .
+</pre>
+
+
+<p><pre>
+ FIXED = 'fixed' .
+ FOR = 'for' .
+ FORMAT = 'format' .
+ FROM = 'from' .
+ FUNCTION = 'function' .
+ GENERIC = 'generic' .
+ HIBOUND = 'hibound' .
+ HIINDEX = 'hiindex' .
+ IF = 'if' .
+ IMPORT = 'import' .
+</pre>
+
+
+<p><pre>
+ IN = 'in' .
+ INSERT = 'insert' .
+ INTEGER = 'integer' .
+ INVERSE = 'inverse' .
+ LENGTH = 'length' .
+ LIKE = 'like' .
+ LIST = 'list' .
+ LOBOUND = 'lobound' .
+ LOINDEX = 'loindex' .
+ LOCAL = 'local' .
+</pre>
+
+
+<p><pre>
+ LOG = 'log' .
+ LOG10 = 'log10' .
+ LOG2 = 'log2' .
+ LOGICAL = 'logical' .
+ MOD = 'mod' .
+ MODEL = 'model' .
+ NOT = 'not' .
+ NOTES = 'notes' .
+ NUMBER = 'number' .
+ NVL = 'nvl' .
+</pre>
+
+
+<p><pre>
+ OBJECTIVE = 'objective' .
+ ODD = 'odd' .
+ OF = 'of' .
+ ONEOF = 'oneof' .
+ OPTIONAL = 'optional' .
+ OR = 'or' .
+ ORD = 'ord' .
+ OTHERWISE = 'otherwise' .
+ PARAMETERi = 'parameter' .
+ PI = 'pi' .
+</pre>
+
+
+<p><pre>
+ PRED = 'pred' .
+ PROCEDURE = 'procedure' .
+ PURPOSE = 'purpose' .
+ QUERY = 'query' .
+ READ = 'read' .
+ READLN = 'readln' .
+ REAL = 'real' .
+ REALIZATION = 'realization' .
+ REFERENCE = 'reference' .
+ REFERENCES = 'references' .
+</pre>
+
+
+<p><pre>
+ REMOVE = 'remove' .
+ REPEAT = 'repeat' .
+ RETURN = 'return' .
+ REXPR = 'rexpr' .
+ ROLESOF = 'rolesof' .
+ ROUND = 'round' .
+ RULE = 'rule .
+ SCHEMA = 'schema' .
+ SCHEMA_DATA = 'schema_data' .
+ SELECT = 'select' .
+</pre>
+
+
+<p><pre>
+ SELF = 'self' .
+ SET = 'set' .
+ SIN = 'sin' .
+ SIZEOF = 'sizeof' .
+ SKIP = 'skip' .
+ SQRT = 'sqrt' .
+ STRING = 'string' .
+ SUBOF = 'subof' .
+ SUBTYPE = 'subtype' .
+ SUCC = 'succ' .
+</pre>
+
+
+<p><pre>
+ SUPERTYPE = 'supertype' .
+ SUPOF = 'supof' .
+ SYSTEM = 'system' .
+ TAN = 'tan' .
+ TEST_CASE = 'test_case' .
+ THE_DAY = 'the_day' .
+ THE_MONTH = 'the_month' .
+ THE_YEAR = 'the_year' .
+ THEN = 'then' .
+ TO = 'to' .
+</pre>
+
+
+<p><pre>
+ TRUE = 'true' .
+ TRUNC = 'trunc' .
+ TYPE = 'type' .
+ TYPEOF = 'typeof' .
+ UNIQUE = 'unique' .
+ UNKNOWN = 'unknown' .
+ UNTIL = 'until' .
+ USE = 'use' .
+ USEDIN = 'usedin' .
+ USING = 'using' .
+</pre>
+
+
+<p><pre>
+ VALUE = 'value' .
+ VALUE_IN = 'value_in' .
+ VALUE_UNIQUE = 'value_unique' .
+ VAR = 'var' .
+ WHERE = 'where' .
+ WHILE = 'while' .
+ WITH = 'with' .
+ WRITE = 'write' .
+ WRITELN = 'writeln' .
+ XOR = 'xor' .
+</pre>
+
+<p>The following rules define various classes of characters which are used in
+constructing the tokens.
+
+
+<p><pre>
+ digit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' .
+ digits = digit { digit } .
+ letter = 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' |
+ 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' |
+ 'w' | 'x' | 'y' | 'z' .
+ lparen_not_star = '(' not_star .
+ not_lparen_star = not_paren_star | ')' .
+ not_paren_star = letter | digit | not_paren_star_special .
+ not_paren_star_quote_special = '!' | '"' | '#' | '$' | '%' | '&' | '+' |
+ ',' | '-' | '.' | '/' | ':' | ';' | '<' | '=' | '>' | '?' |
+ '@' | '[' | '\' | ']' | '^' | '_' | '`' | '{' | '|' | '}' |
+ '~' .
+ not_paren_star_special = not_paren_star_quote_special | '''' .
+ not_quote = not_paren_star_quote_special | letter | digit | '(' | ')' | '*' .
+ not_rparen = not_paren_star | '*' | '(' .
+</pre>
+
+
+<p><pre>
+ not_star = not_paren_star | '(' | ')' .
+ octet = hex_digit hex_digit .
+ special = not_paren_star_quote_special | '(' | ')' | '*' | '''' .
+ star_not_rparen = '*' not_rparen .
+</pre>
+
+<p>
+ The following rules specify how certain combinations of characters are
+interpreted as lexical elements within the language.
+
+
+<p><pre>
+ integer_literal = digits .
+ real_literal = digits '.' [ digits ] [ 'e' [ sign ] digits ] .
+ simple_id = letter { letter | digit | '_' } .
+ simple_string_literal = \q { ( \q \q ) | not_quote | \s | \o } \q .
+</pre>
+
+<p>The following rules specify the syntax of comments in EXPRESS-A.
+
+
+<p>
+<pre>
+ embedded_remark = '(*' { not_lparen_star | lparen_not_star |
+ star_not_rparen | embedded_remark } '*)' .
+ remark = embedded_remark | tail_remark .
+ tail_remark = '--' { \a | \s | \o } \n .
+</pre>
+
+<p>
+The following rules represent identifiers which are known to have a particular
+meaning (i.e., to be declared elsewhere as types or functions, etc.).
+
+
+<p>
+
+<pre>
+ attribute_ref = attribute_id .
+ constant_ref = constant_id .
+ entity_ref = entity_id .
+ enumeration_ref = enumeration_id .
+ function_ref = function_id .
+ parameter_ref = parameter_id .
+ procedure_ref = procedure_id .
+ type_ref = type_id .
+ variable_ref = variable_id .
+</pre>
+
+<p>
+
+ The following rules specify how the previous lexical elements may be
+combined into constructs of EXPRESS-A. White space and/or remark(s) may appear
+between any two tokens in these rules. The primary syntax rule for EXPRESS-A
+is <samp>express_a</samp>.
+
+
+<p>
+
+<pre>
+ actual_parameter_list = '(' parameter { ',' parameter } ')' .
+ add_like_op = '+' | '-' | OR | XOR .
+ aggregation_types = array_type | bag_type | list_type | set_type .
+ algorithm_head = { declaration } [ local_decl ] .
+ array_type = ARRAY bound_spec OF base_type .
+ assignment_stmt = general_ref { qualifier } ':=' expression ';' .
+ attribute_decl = attribute_id .
+ attribute_id = simple_id .
+ attribute_qualifier = '.' attribute_ref .
+ bag_type = BAG [ bound_spec ] OF base_type .
+</pre>
+
+
+<p><pre>
+ base_type = aggregation_types | simple_types | named_types .
+ boolean_type = BOOLEAN .
+ bound_1 = numeric_expression .
+ bound_2 = numeric_expression .
+ bound_spec = '[' bound_1 ':' bound_2 ']' .
+ built_in_constant = CONST_E | PI | THE_DAY | THE_MONTH | THE_YEAR | '?' .
+ built_in_function = ABS | COS | EOF | EOLN | EXISTS | EXP |
+ HIBOUND | HIINDEX | LENGTH | LOBOUND | LOINDEX |
+ LOG | LOG2 | LOG10 | NVL | ODD | ORD | PRED |
+ REXPR | ROUND | SIN | SIZEOF |
+ SQRT | SUCC | TAN | TRUNC .
+ built_in_procedure = INSERT | PRINT | PRINTLN | READ | READLN | REMOVE |
+ SYSTEM | WRITE | WRITELN .
+ case_action = case_label { ',' case_label } ':' stmt .
+ case_label = expression .
+</pre>
+
+
+<p><pre>
+ case_stmt = CASE selector OF { case_action } [ OTHERWISE ':' stmt ]
+ END_CASE ';' .
+ compound_stmt = BEGIN stmt { stmt } END ';' .
+ constant_factor = built_in_constant .
+ constructed_types = enumeration_type .
+ declaration = entity_decl | function_decl | procedure_decl | type_decl .
+ entity_body = { explicit_attr } .
+ entity_decl = entity_head entity_body END_ENTITY ';' .
+ entity_head = ENTITY entity_id ';' .
+ entity_id = simple_id .
+ enum_id = simple_id .
+</pre>
+
+
+<p><pre>
+ enumeration_reference = enum_id .
+ enumeration_type = ENUMERATION OF '(' enum_id { ',' enum_id } ')' .
+ escape_stmt = ESCAPE ';' .
+ explicit_attr = attribute_decl { ',' attribute_decl } ':' base_type ';' .
+ express_a = { declaration } [ local_decl ] { stmt } END_CODE .
+ expression = simple_expression [ rel_op_extended simple_expression ] .
+ factor = simple_factor [ '**' simple_factor ] .
+ formal_parameter = parameter_id { ',' parameter_id } ':' parameter_type .
+ function_call = ( built_in_function | function_ref )
+ [ actual_parameter_list ] .
+ function_decl = function_head [ algorithm_head ] stmt { stmt }
+ END_FUNCTION ';' .
+</pre>
+
+
+<p><pre>
+ function_head = FUNCTION function_id [ '(' formal_parameter
+ { ';' formal_parameter } ')' ] ':' parameter_type ';' .
+ function_id = simple_id .
+ generalized_types = general_aggregation_types .
+ general_aggregation_types = general_array_type | general_bag_type |
+ general_list_type | general_set_type .
+ general_array_type = ARRAY [ bound_spec ] OF parameter_type .
+ general_bag_type = BAG [ bound_spec ] OF parameter_type .
+ general_list_type = LIST [ bound_spec ] OF parameter_type .
+ general_ref = parameter_ref | variable_ref .
+ general_set_type = SET [ bound_spec ] OF parameter_type .
+ if_stmt = IF logical_expression THEN stmt { stmt } [ ELSE stmt { stmt } ]
+ END_IF ';' .
+</pre>
+
+
+<p><pre>
+ increment = numeric_expression .
+ increment_control = variable_id ':=' bound_1 TO bound_2 [ BY increment ] .
+ index = numeric_expression .
+ index_1 = index .
+ index_2 = index .
+ index_qualifier = '[' index_1 [ ':' index_2 ] ']' .
+ integer_type = INTEGER .
+ interval = '{' interval_low interval_op interval_item interval_op
+ interval_high '}' .
+ interval_high = simple_expression .
+ interval_item = simple_expression .
+</pre>
+
+
+<p><pre>
+ interval_low = simple_expression .
+ interval_op = '<' | '<=' .
+ list_type = LIST [ bound_spec ] OF base_type .
+ literal = integer_literal | logical_literal | real_literal |
+ string_literal .
+ local_decl = LOCAL local_variable { local_variable } END_LOCAL ';' .
+ local_variable = variable_id { ',' variable_id } ':' parameter_type ';' .
+ logical_expression = expression .
+ logical_literal = FALSE | TRUE | UNKNOWN .
+ logical_type = LOGICAL .
+ multiplication_like_op = '*' | '/' | DIV | MOD | AND | '||' .
+</pre>
+
+
+<p><pre>
+ named_types = entity_ref | type_ref .
+ null_stmt = ';' .
+ numeric_expression = simple_expression .
+ parameter = expression .
+ parameter_id = simple_id .
+ parameter_type = generalized_types | named_types | simple_types .
+ population = entity_ref .
+ primary = literal | ( qualifiable_factor { qualifier } ) .
+ procedure_call_stmt = ( built_in_procedure | procedure_ref )
+ [ actual_parameter_list ] ';' .
+ procedure_decl = procedure_head [ algorithm_head ] { stmt } END_PROCEDURE ';' .
+</pre>
+
+
+<p><pre>
+ procedure_head = PROCEDURE procedure_id [ '(' [ VAR ] formal_parameter
+ { ';' [ VAR ] formal_parameter } ')' ] ';' .
+ procedure_id = simple_id .
+ qualifiable_factor = attribute_ref | constant_factor | function_call |
+ general_ref | population .
+ qualifier = attribute_qualifier | index_qualifier .
+ real_type = REAL .
+ referenced_attribute = attribute_ref | qualified_attribute .
+ rel_op = '<' | '>' | '<=' | '>=' | '<>' | '=' | ':<>:' | ':=:' .
+ rel_op_extended = rel_op | IN | LIKE .
+ repeat_control = [ increment_control ] [ while_control ] [ until_control ] .
+ repeat_stmt = REPEAT repeat_control ';' stmt { stmt } END_REPEAT ';' .
+</pre>
+
+
+<p><pre>
+ return_stmt = RETURN [ '(' expression ')' ] ';' .
+ selector = expression .
+ set_type = SET [ bound_spec ] OF base_type .
+ sign = '+' | '-' .
+ simple_expression = term { add_like_op term } .
+ simple_factor = enumeration_reference | interval |
+ ( [ unary_op ] ( '(' expression ')' | primary ) ) .
+ simple_types = integer_type | logical_type | real_type | string_type .
+ skip_stmt = SKIP ';' .
+ stmt = assignment_stmt | case_stmt | compound_stmt | escape_stmt |
+ if_stmt | null_stmt | procedure_call_stmt | repeat_stmt | return_stmt |
+ skip_stmt .
+ string_literal = simple_string_literal .
+</pre>
+
+
+<p><pre>
+ string_type = STRING .
+ term = factor { multiplication_like_op factor } .
+ type_decl = TYPE type_id '=' underlying_type ';' END_TYPE ';' .
+ type_id = simple_id .
+ unary_op = '+' | '-' | NOT .
+ underlying_type = constructed_types | aggregation_types | simple_types |
+ type_ref .
+ until_control = UNTIL logical_expression .
+ variable_id = simple_id .
+ while_control = WHILE logical_expression .
+</pre>
+
+<p>
+
+
+
+<p><h2>REFERENCES</h2>
+<dl>
+
+
+
+<p>
+<dt>[<a name="LAMPORT94">LAMPORT94</a>]<dd>
+Leslie Lamport.
+ LaTeX: A Document Preparation System.
+ Addison-Wesley Publishing Company, second edition, 1994.
+
+
+<p>
+<dt>[<a name="KNUTH84a">KNUTH84a</a>]<dd>
+Donald E. Knuth.
+ The TeXbook.
+ Addison-Wesley Publishing Company, 1984.
+
+
+<p>
+<dt>[<a name="STEPIS">STEPIS</a>]<dd>
+ISO 10303.
+ Industrial automation systems and integration --- Product data
+ representation and exchange, 1994.
+
+
+<p>
+<dt>[<a name="GOLDFARB90">GOLDFARB90</a>]<dd>
+C. A. Goldfarb.
+ The SGML Handbook.
+ Oxford University Press, 1990.
+ (Edited and with a foreword by Yuri Rubinsky).
+
+
+<p>
+<dt>[<a name="MUSCIANO96">MUSCIANO96</a>]<dd>
+Chuck Musciano and Bill Kennedy.
+ .
+ O'Reilly &amp; Associates, Inc., 1996.
+
+
+<p>
+<dt>[<a name="KERNIGHAN88">KERNIGHAN88</a>]<dd>
+Brian W. Kernighan and Dennis M. Ritchie.
+ The C Programming Language.
+ Prentice Hall, second edition, 1988.
+
+
+<p>
+<dt>[<a name="EBOOK">EBOOK</a>]<dd>
+Douglas A. Schenck and Peter R. Wilson.
+ Information Modeling the EXPRESS Way.
+ Oxford University Press (ISBN 0-19-308714-3), 1994.
+
+
+<p>
+<dt>[<a name="EXPRESSIS">EXPRESSIS</a>]<dd>
+ISO 10303-11:1994.
+ Industrial automation systems and integration --- Product data
+ representation and exchange --- Part 11: Description methods: The EXPRESS
+ language reference manual, 1994.
+
+
+<p>
+<dt>[<a name="LEVINE92">LEVINE92</a>]<dd>
+John R. Levine, Tony Mason, and Doug Brown.
+ lex &amp; yacc.
+ O'Reilly &amp; Associates, Inc., second edition, 1992.
+
+
+<p>
+<dt>[<a name="LESK75">LESK75</a>]<dd>
+M. E. Lesk and E. Schmidt.
+ `LEX --- A Lexical Analyser Generator'.
+ In UNIX Programmer's Manual 2. AT&amp;T Bell Laboratories, Murray
+ Hill, NJ, 1975.
+
+
+<p>
+<dt>[<a name="JOHNSON75">JOHNSON75</a>]<dd>
+S. C. Johnson.
+ YACC --- Yet Another Compiler Compiler.
+ C S Technical Report 32, Bell Telephone Laboratories, Murray Hill,
+ NJ, 1975.
+
+
+<p>
+<dt>[<a name="EXPRESSITR">EXPRESSITR</a>]<dd>
+ISO/TR 10303-12:1997.
+ Industrial automation systems and integration --- Product data
+ representation and exchange --- Part 12: Description method: The EXPRESS-I
+ language reference manual, 1997.
+
+
+<p>
+<dt>[<a name="PRW94b">PRW94b</a>]<dd>
+Peter R. Wilson.
+ `FLaTTeN: A Program to Flatten LaTeX Source Files'.
+ NIST, Gaithersburg, MD 20899, December 1994.
+ (In draft).
+
+
+<p>
+<dt>[<a name="LIBES93">LIBES93</a>]<dd>
+Don Libes.
+ Obfuscated C and Other Mysteries.
+ John Wiley &amp; Sons, Inc., 1993.
+
+
+<p>
+<dt>[<a name="HOLUB90">HOLUB90</a>]<dd>
+A. I. Holub.
+ Compiler Design in C.
+ Prentice-Hall, Inc., 1990.
+
+
+<p>
+<dt>[<a name="ORAM91">ORAM91</a>]<dd>
+Andrew Oram and Steve Talbott.
+ Managing Projects with make.
+ O'Reilly &amp; Associates, Inc., second edition, 1991.
+
+
+<p>
+<dt>[<a name="RINAUDOT94">RINAUDOT94</a>]<dd>
+Gaylen R. Rinaudot.
+ .
+ NISTIR 5511, NIST, Gaithersburg, MD 20899, October 1994.
+
+
+<p>
+<dt>[<a name="WIRTH77">WIRTH77</a>]<dd>
+N. Wirth.
+ `What Can We Do About the Unnecessary Diversity of Notation for
+ Syntactic Definitions?'.
+ Communications of the ACM, 20(11):822--823, November 1977.
+
+
+<p>
+<dt>[<a name="MAKR91">MAKR91</a>]<dd>
+Ronald Mak.
+ Writing Compilers &amp; Interpreters --- An Applied Approach.
+ John Wiley &amp; Sons, Inc., 1991.
+
+
+<p></dl>
+
+
+
+<p>
+
+<a name="HtMlEoD"></a><a href="#HtMlSoD">To the start</a>
+</body>
+</html>
+
+
+<a name="HtMlEoD"></a><a href="#HtMlSoD">To the start</a>
+</body>
+</html>