\newif\ifplastex%
\ifplastex\documentclass{article}\else
\documentclass{pracjourn}\fi
\usepackage[section]{placeins}
\begin{document}
\title{plasTeX: Converting LaTeX Documents to Other Markup Languages}
\author{Tim Arnold}
\ifplastex\else\email{a\_jtim@bellsouth.net}\fi
\abstract{This article introduces plasTeX, a software package for converting
LaTeX documents to other markup languages. It begins with usage details
including examples of how to create HTML and DocBook XML from LaTeX sources.
Then, it describes development details: how plasTeX works and how developers
can use it to create or extend a publishing workflow in a production setting.
Finally, it ends with some examples of customizing the parser and renderer as
well as suggestions of how others can contribute to this open source project.}
\ifplastex\else\TPJrevision{2008}{10}{10}\fi % Update this at revision
\maketitle
\section{Overview}
PlasTeX is an open source software package that converts LaTeX documents to
other document formats such as HTML and XML. It is written in Python and
is available on SourceForge under the MIT license. See section
\ref{sec:ref} for links to more information.
PlasTeX converts a LaTeX document in two stages. First, it tokenizes and parses
the LaTeX source following rules similar to those of the actual TeX tokenizer
and macro processor. At this stage the document exists internally as an
ordered data structure called a document object model (DOM). Second, plasTeX
applies a rendering template to that data structure to create the final
output. This second stage can be repeated several times to create multiple
output formats from a single parsing stage.
Figure \ref{fig:diag1} shows how a document is transformed
from LaTeX to another markup language.
\begin{figure}
\includegraphics[width=\textwidth]{diagram1}
\caption{PlasTeX Converts LaTeX to Multiple Output Formats}\label{fig:diag1}
\end{figure}
The core of plasTeX is the tokenizing/parsing engine. PlasTeX understands the
content of a source document through its access to actual LaTeX packages and
Python classes. All built-in LaTeX macros are defined as Python classes in
plasTeX.
As plasTeX reads the source file, it must understand each macro it encounters.
If a Python class exists that matches the name of the macro, that class
definition is used. If a matching Python class is not found, plasTeX searches
for the actual LaTeX package macro and expands it before continuing with the
source document. PlasTeX also expands macros defined within your
document.
Renderers can be plugged in as back-ends. Several renderers are bundled with
plasTeX; if a custom output format is needed, it is straightforward to write a
custom renderer. Users who create custom renderers can easily share them with
others through the plasTeX SourceForge site. For example, BrlTeX generates
Braille output from LaTeX sources (see section \ref{sec:ref} a link to more
information).
Out of the box, plasTeX cannot convert every LaTeX document. However,
using inheritance techniques described in section \ref{sec:inherit}, the system
can be modified to produce reasonable output from almost any document.
Professional document producers, casual end users, and programmers use
different methods of working with plasTeX. This article first
describes the command-line interface to plasTeX to show how plasTeX can be
used as is. Later it discusses customization methods for documents with ``special
needs''.
\subsection{Command Line Interface}
The user interface for plasTeX is the \texttt{plastex} command. To convert a
LaTeX document to XHTML using all of the defaults, type the following on the
command line, where \texttt{mylatex.tex} is the name of your LaTeX file:
\begin{verbatim}
plastex mylatex.tex
\end{verbatim}
The \texttt{plastex} command has several options\footnote{You can enter the
\texttt{plastex} command with no arguments to get help on its options and
usage.} to help you control the rendered output. Some important optional
capabilities are listed below:
\begin{itemize}
\item selectable output format (HTML, DocBook XML, and so on)
\item generation of multiple or single output files.
The automatic splitting of files can be configured by section
level or controlled programmatically.
\item image generation for portions of the document that cannot be
easily rendered in a particular output format (for example, equations in
HTML)
\item post-processing hooks for simple customization
\item configurable input and output encodings
\item selectable themes
\end{itemize}
One of the most powerful options is the theme selection.
A theme is a set of templates that plasTeX uses
during rendering to give your documents a different ``look and feel.'' The
following example shows how to specify a theme from the command line.
\begin{verbatim}
plastex --theme=plain mylatex.tex
\end{verbatim}
The theme alters the appearance and behavior of your HTML documents (to match a
corporate style for example). Themes are especially powerful when coupled with
CSS style files. PlasTeX provides the following themes which can be used as a
guide to quickly create custom themes:
\begin{description}
\item[default] full-featured theme with navigation bars, style information, and
breadcrumbs.
\item[python] a variant of the default theme which renders the look and feel of
the standard Python documentation.
\item[plain] bare-bones theme, intended for those who prefer to use pure CSS
styles with plain HTML for complete separation of style and content.
\item[minimal] specialty theme, intended for special cases when segments of
HTML are needed for copying and pasting. Contains no navigation.
\end{description}
For more information about themes, see section \ref{sec:theme}.
\subsection{Mathematics}
As plasTeX parses a LaTeX document, it creates document data and keeps track of
the original source. This means that, after parsing, plasTeX has two ways to
access each document element: as part of the document data or as the LaTeX source from
which the element came. This is important when dealing with equations or
picture environments that might not have corresponding markup in the output
format (HTML, for example).
PlasTeX uses an imager (\texttt{dvipng} by default) to create images of
document elements that cannot be produced otherwise. Several imagers are
available in plasTeX; any program that can be used to convert LaTeX math into
an output format can be used.
When plasTeX converts LaTeX to DocBook XML, both the image and the LaTeX
source are used in the final document. See section \ref{sec:dbk} for an
example.
\subsection{Languages and Encoding Support}
PlasTeX comes bundled with translated terms for document elements in the
following languages: Dutch, French, German, Italian, Portugese, and Spanish. It
also includes three variants of English: American, Australian, and British.
You can use your own translated terms by specifying a local translation file.
These custom terms are substituted into the output document during the
rendering stage.
PlasTeX can read and write the same encodings as Python itself. For example, it
is a simple process to read LaTeX encoded as \texttt{Latin-2} and write the
output format as \texttt{UTF-8}. The output encoding is independent of the
format; that is, all output formats support all encodings.
With its encoding support and XML output, plasTeX can play a critical role when
producing documents in multiple languages. Figure \ref{fig:lang} shows a
possible workflow.
\begin{figure}
\includegraphics[width=\textwidth]{diagram2}
\caption{Producing Documentation in Multiple Languages using plasTeX}
\label{fig:lang}
\end{figure}
Suppose a document is authored in English LaTeX using \texttt{Latin-1}
encoding, final documents are needed in both English and Korean, and that
the translators are unfamiliar with LaTeX or possess translation memory in XML
format. In such a situation, you can use plasTeX to convert the LaTeX
\texttt{Latin-1} source document to DocBook XML in \texttt{UTF-8} encoding.
Translators can then work with the XML document and return it in the new
language. Off-the-shelf tools then convert the DocBook document to produce a
final output document in the new language (see section \ref{sec:dbk} for more
information on the DocBook output).
\subsection{Supported LaTeX Packages}
PlasTeX defines all built-in LaTeX macros, as well as some of the more popular
packages. The following shows some of these supported packages.
\begin{center}
\begin{tabular}{llll}
alltt & float & keyval & subfig \\
amsmath & graphicx & lipsum & textcomp \\
changebar & hyperref & longtable & url \\
color & ifthen & natbib & wrapfig \\
\end{tabular}
\end{center}
\section{Usage}\label{sec:usage}
To get started with plasTeX, you need the following:
\begin{itemize}
\item Python distribution 2.4 or later
\item plasTeX distribution
\item Python Imaging Library
\item LaTeX distribution
\end{itemize}
The Python Imaging Library and the LaTeX distribution are used together to
create images for the rendered document (for example, math images in HTML)
\subsection{HTML}
Figure \ref{fig:rawhtml} displays the default HTML output generated by
converting the well-known \texttt{sample2e.tex} file. The command to generate
the output is:
\begin{verbatim}
plastex sample2e.tex
\end{verbatim}
\begin{figure}
\includegraphics[width=\textwidth]{web}
\caption{Default Output with HTML Renderer}\label{fig:rawhtml}
\end{figure}
An added bonus with plasTeX HTML generation is that it generates
supplemental files so you can easily create further processed HTML, such as
Windows compiled help, EclipseHelp, and JavaHelp\textsuperscript{TM}. Any of
these formats can be produced by downloading the free compiler for the corresponding
format and invoking it with the files generated by plasTeX. For links to
downloads, see section \ref{sec:ref}.
Windows compiled help (CHM) is easily generated with
Microsoft\textsuperscript{\textregistered} HTML Help Workshop:
\begin{figure}
\includegraphics[width=\textwidth]{chm}
\caption{Windows Compiled Help View}\label{fig:chmhtml}
\end{figure}
JavaHelp is generated with the \texttt{hsviewer} available from Sun
Microsystems\textsuperscript{\textregistered}. The following command creates
the JavaHelp output, where \texttt{documentname.hs} is a supplemental file created by plasTeX during HTML conversion:
\begin{verbatim}
java -jar path_to_hsviewer.jar -helpset documentname.hs
\end{verbatim}
\begin{figure}
\includegraphics[width=\textwidth]{jh}
\caption{JavaHelp View}\label{fig:jhhtml}
\end{figure}
\subsection{DocBook XML}\label{sec:dbk}
PlasTeX can produce DocBook 4.5 XML from many LaTeX documents. However, not all
the elements available in DocBook have corresponding LaTeX macros. Although
plasTeX handles much of the mapping, some customization might become necessary
for documents with complex formatting or processing needs. Section
\ref{sec:customize} describes this type of customization.
To convert a LaTeX document to DocBook XML, type the
following on the command line, where \texttt{mylatex.tex} is the name of your
LaTeX file.
\begin{verbatim}
plastex --renderer=DocBook --filename=mylatex.xml mylatex.tex
\end{verbatim}
The option \texttt{--filename=mylatex.xml} specifies that the XML
output be generated in a single file called \texttt{mylatex.xml}.
Figure \ref{fig:docbook} displays a view of the \texttt{sample2e} document as
formatted in DocBook XML (and displayed by the XMLMind Editor).
\begin{figure}
\includegraphics[width=\textwidth]{dbk}
\caption{DocBook XML Output}\label{fig:docbook}
\end{figure}
A powerful toolchain exists to create many formats from DocBook, as can be seen
in Figure \ref{fig:lang}. For that reason plasTeX doesn't directly produce
bibliographies, resolve cross references, or produce indexes for DocBook.
However, it does generate the supplemental files the DocBook tools expect for
processing these document elements.
\subsubsection{Bibliography}
If you use BibTeX in your LaTeX workflow, you can generate
an XML version of your BibTeX database. DocBook processing tools can then
combine that database with your DocBook document to create the bibliography on
the fly. One tool that can converts BibTeX to XML (among other things) is
JabRef, see section \ref{sec:ref} for a link.
\subsubsection{Cross References}
Internal references are rendered in the document as \texttt{link}
elements. This behavior can be modified to produce \texttt{olink} elements
for cross-document references.
\subsubsection{Index}
Index terms are rendered directly in the document. DocBook
processing tools automatically create an index for your document on the fly.
\subsubsection{Mathematics} PlasTeX uses both the rendered image and the LaTeX
source when representing mathematics in DocBook. For example, an inline equation such as
$x+y=\frac{1}{z}$ would be converted to the following docbook element:
\begin{verbatim}
x+y=\frac{1}{z}
\end{verbatim}
A document that uses this system validates against the DocBook DTD, and yet
postprocessing extensions have easy access to the original LaTeX mathematics.
\subsection{Other Formats}
In addition to the HTML and DocBook XML renderers, the following renderers
are also available:
\begin{description}
\item[Text] renders LaTeX to plain text in the specified encoding. For
example, the rendered output of the first part of section \ref{sec:usage} from
this document is as follows:
\begin{figure}
\noindent\rule{\textwidth}{1pt}
\begin{verbatim}
2 Usage Details
To get started with plasTeX, you need the following:
* Python distribution 2.4 or later
* plasTeX distribution
* Python Imaging Library
* LaTeX distribution.
\end{verbatim}
\rule{\textwidth}{1pt}
\caption{Text Renderer Output}
\end{figure}
\item[ManPage] renders LaTeX to the UNIX man page format, which can then be
displayed with the commands \texttt{groff} or \texttt{nroff}.
\item[S5] renders your LaTeX document (Beamer class only) to S5 output. S5 is
a standards-based slideshow system.
\item[Braille] renders LaTeX documents to Braille. This format is not bundled
with plasTeX distribution but is available as BrlTex on the web. See the BrlTeX
entry in section \ref{sec:ref} for details.
\item[Direct to XML] not a true renderer, but a representation of your document
in plasTeX's internal XML format. This representation can be useful to review
if you encounter problems in rendering.
Producing this output format requires a slight modification of the
\texttt{plastex} command line script: uncomment the following lines in the
script and run \texttt{plastex} again.
\begin{verbatim}
## Write XML dump
#outfile = '%s.xml' % jobname
#open(outfile,'w').write(document.toXML().encode('utf-8'))
\end{verbatim}
An XML file is created that displays the structure of the document. The
following LaTeX markup used in this document to display Figure
\ref{fig:docbook}
\begin{verbatim}
\begin{figure}
\includegraphics{dbk}
\caption{DocBook XML Output}\label{fig:docbook}
\end{figure}
\end{verbatim}
has the following internal representation:
\begin{verbatim}
\end{verbatim}
\end{description}
\section{Customizing plasTeX}\label{sec:customize}
\subsection{Process Overview}
PlasTeX might need modification to convert documents that contain custom
macros, complex macros, or macros that have no mapping to the output format. The three
tasks in creating the output are parsing, rendering, and imaging. Each task is
described as follows.
To convert a LaTeX document, plasTeX must first tokenize and parse the source.
It understands how to do this for each document element from the corresponding
Python class definitions. PlasTeX finds these definitions in its standard path
and the locations defined in the environment variable \texttt{PYTHONPATH}.
Next, plasTeX hands off the resulting data structure (DOM) to the renderer. The
rendering templates must display (or more correctly, \textit{mark up}) the
document elements for the intended output format. PlasTeX finds these
templates in its standard path and the locations defined in the environment
variables \texttt{XHTMLTEMPLATES} and \texttt{DocBookTEMPLATES}.
Finally, for any elements that must be handled externally (that is, by the
imager), plasTeX hands off an internally produced \texttt{images.tex}
file to the configured imager, which employs LaTeX itself. PlasTeX finds the
necessary files by using the \texttt{kpsewhich} command and the
locations defined in the environment variable \texttt{TEXINPUTS}.
Thus, the sequence of tasks to customize plasTeX is as follows.
\begin{enumerate}
\item write class definitions for your new commands or environments. Set the
environment variable \texttt{PYTHONPATH} to include the location of your class definitions. Also,
see section \ref{sec:cond} which describes a fallback
mechanism that you can use to redefine simple macros in LaTeX itself.
\item Write templates that correspond to your new commands or environments.
Set the environment variable \texttt{XHTMLTEMPLATES} (or
\texttt{DocBookTEMPLATES} for the DocBook renderer) to include the location of
the templates.
\item Confirm that LaTeX can find the packages
necessary to create the images. If the \texttt{kpsewhich} command cannot find the packages
automatically, set the environment variable \texttt{TEXINPUTS} to include the
location. Note that plasTeX typically handles imaging automatically when a
standard LaTeX distribution is installed.
\end{enumerate}
\subsection{Parsing Details}
\enlargethispage{1ex}%
The goal in this stage of customization is to enable plasTeX to recognize and
correctly parse commands and environments that it encounters in the source
\mbox{document}.
The parsing task usually involves Python classes, because when a source
document loads a package, plasTeX first looks in the \texttt{PYTHONPATH}
environment variable for a Python module of the same name. For example, if the
package loaded is \texttt{mylocals}, plasTeX checks for a Python file
\texttt{mylocals.py}. However, if it does not find that file, it falls back to
the LaTeX packages by using the \texttt{kpsewhich} command to find a package
called \texttt{mylocals.sty}.
These two alternatives lead to the two possible methods of parser
customization.
\begin{itemize}
\item Create a simplified version of the original LaTeX macro that plasTeX uses
(LaTeX uses the more complex version).
\item Implement the macro as a Python class.
\end{itemize}
\subsubsection{Conditional LaTeX Macros}\label{sec:cond}
The simplest customization method is to modify the LaTeX
macro with conditional processing. That is, create a simplified version of
the macro by using the \verb+\ifplastex+ command. The command is built into
plasTeX; during the plasTeX processing the command is set to \texttt{true} and
typically invokes simpler instructions than those used when LaTeX processes the
document.
In the following example\footnote{The examples presented in this paper are
simple enough that plasTeX could parse and render them correctly with no
additional effort. They are presented here only as learning
examples.}, suppose you have a local LaTeX package called \texttt{mylocals.sty}
which defines a new command \verb+\foo+ that takes a single argument.
\begin{verbatim}
\newcommand{\foo}[1]{
\ifplastex\else\vspace*{0.25in}\fi
\textbf{\Large{#1}}
\ifplastex\else\vspace*{1in}\fi
}
\end{verbatim}
In the LaTeX version the \verb+\foo+ command
inserts some vertical space before and after the argument, which it typesets in
bold at a \texttt{Large} size. The plasTeX version bypasses the vertical space
commands but retains the typesetting of the argument. With the macro so
defined, plasTeX will recognize and correctly parse the \verb+\foo+ command.
Suppose that \texttt{mylocals.sty} also defines a new environment called
\texttt{mybox}.
\begin{verbatim}
\ifplastex
\newenvironment{mybox}{}{}
\else
\newenvironment{mybox}
{\fbox\bgroup\begin{minipage}{5in}}
{\end{minipage}\egroup}
\fi
\end{verbatim}
In the plasTeX version, the environment is merely defined and
no action is taken; in the LaTeX version a box is set around a minipage. With
this information, plasTeX can now parse the environment correctly. It can then
be displayed by the renderer (perhaps to put a box around the contents).
In this example, the separation of tasks can be clearly seen. The LaTeX code
handles both the parsing knowledge and the appearance; the plasTeX code
separates the tasks into the macro definition seen here (parsing knowledge) and
the rendering template (appearance), which is described in section
\ref{sec:render}.
\subsubsection{Class Definitions}\label{sec:classdef}
The alternative to writing macros with conditional definitions is to write a
Python class that corresponds to the command or environment. This is the
recommended method for defining complex macros.
The plasTeX documentation describes in detail how to write methods or
functions to override plasTeX's normal behavior or to add new behavior.
For example, you can define methods to manipulate the document structure, create
and change counters, and store data for use in postprocessing.
More commonly, however, a new macro requires normal parsing behavior. The
only requirement for parsing the new macro is to define the macro's signature
(that is, specify the options and arguments that the macro takes). The
\texttt{args} variable in the class definition specifies this information.
You can specify any number of optional arguments and mandatory arguments.
To indicate that an argument is optional, surround the optional arguments with
matching square brackets([]), angle brackets (<>), or parentheses (()), just as
it is written in the LaTeX source. The following list describes some examples:
\begin{description}
\item[\texttt{args = 'title'}] specifies a single mandatory argument named
\texttt{title}.
\item[\texttt{args = 'id title'}] specifies two mandatory arguments named
\texttt{id} and \texttt{title}.
\item[\texttt{args = '[toc] title'}] specifies an optional argument named
\texttt{toc} and a single mandatory argument named \texttt{title}.
\item[\texttt{args = '[options:dict] title'}] specifies an optional list of
keyword-value pairs named \texttt{options} and a single mandatory argument
named \texttt{title}.
\end{description}
After the arguments are parsed, they are set in the \texttt{attributes}
dictionary of the document element. These attributes can then be used in the
rendering stage as \texttt{self/attributes/\textit{argumentname}}. plasTeX's
\texttt{arg} string provides a powerful mechanism for quickly defining
complex macros. The plasTeX documentation has complete details with
several examples.
To continue with the example described in the previous section, suppose that the
macro definitions remain as they were originally written (that is, without using
the \verb+\ifplastex+ command) and the plasTeX class definitions are written in
the Python class file (Python module) \texttt{mylocals.py}. The corresponding
Python code might look like this:
\begin{verbatim}
from plasTeX import Command, Environment
class foo(Command):
args = 'footext'
class mybox(Environment):
pass
\end{verbatim}
The first line imports some of the basic plasTeX functionality---the
foundational classes \texttt{Command} and \texttt{Environment}. For many
macros, you need little else to teach plasTeX how to recognize and parse the new
macros it encounters. With the \verb+\foo+ command for example, you can tell
plasTeX that this is a command with a single argument named \texttt{footext}. This
argument name is used by the renderer after the parsing stage. With the
\verb+mybox+ environment, you define the macro as an environment.
These definitions, written in \texttt{mylocals.py}, make up all the information
plasTeX needs in order to recognize and parse the new command and new
environment.
\subsection{Rendering Details}\label{sec:render}
A renderer is a collection of templates\footnote{The default template engine is
SimpleTal which is based on the Python package, \emph{Zope Page Templates}} that
take the data from the parsed document and can display or markup each document element
encountered.
Assuming that you have a CSS stylesheet for presentation, the following is one
possible template for producing HTML from the definitions given in
the previous section:
\begin{verbatim}
name: foo
name: mybox
\end{verbatim}
The argument given in the \verb+\foo+ command is named \texttt{footext} in the
class definition and is available in the renderer as
\texttt{self/attributes/footext}. It is placed inside a \texttt{}
element which will be displayed as bold in the final display. The
\texttt{class="Large"} attribute might correspond to a class defined in an
accompanying CSS file to render the contents at a larger than normal size.
The contents of the \texttt{mybox} environment is placed inside a
\texttt{blockquote} element with the \texttt{class="mybox"} possibly handling
further display formatting via CSS.
\subsection{Inheritance and Aliasing}\label{sec:inherit}
Inheriting from the base plasTeX classes as shown in section
\ref{sec:classdef} is a fast and powerful way to customize your own
documents. The previous example inherited definitions and behavior directly
from the \texttt{Command} and \texttt{Environment} classes. You can also
inherit from other plasTeX classes. Choose the class with the behavior that most
closely resembles your custom macro. For example, suppose that you have an environment in which you display
program code (called \texttt{Code}) and it is to be treated exactly as a
\texttt{verbatim} block. You can quickly customize plasTeX with this class:
\begin{verbatim}
class Code(verbatim):
pass
\end{verbatim}
When the plasTeX parser encounters the \texttt{Code} environment, it
looks up the definition in the Python classes. The environment subclasses the
\texttt{verbatim} environment, thereby inheriting all the properties needed
for plasTeX to parse the contents. No other code is necessary for plasTeX to
recognize and parse your text.
The following lines in your template file exploit the power of template
aliasing:
\begin{verbatim}
name: Code
alias: verbatim
\end{verbatim}
When the plasTeX renderer encounters the \texttt{Code} environment, it
finds the definition in the templates file and renders it as if were a
\texttt{verbatim} environment. No other code is necessary to render the
\texttt{Code} environment. Obviously this is a simple example; the
power of inheritance and aliasing even for complicated macros, however,
significantly speeds the development of new macro packages and renderers.
\subsection{Creating Themes}\label{sec:theme}
Themes provide a powerful method to quickly change the look and feel of your
HTML or XML documents. Any template directory (a directory specified in the
\texttt{XHTMLTEMPLATES} or \texttt{DocBookTEMPLATES} environment variables)
can contain multiple themes. To create a theme, create a subdirectory called
\texttt{Themes} which contains a directory of HTML or XML templates for each
theme you want to provide. For example, themes included in the plasTeX
distribution for the HTML renderer reside in the following directory structure:
\begin{verbatim}
XHTMLTEMPLATES/
Themes/
default/
minimal/
plain/
python/
\end{verbatim}
Each of the theme directories contains at least one file called
\texttt{default-layout.html}. To create your own themes, use the
\texttt{default/default-layout.html} file as a guide.
\section{Getting Involved}
While the core parser and document builder are powerful and stable, there is
ample opportunity for users to contribute by testing and writing Python classes
to further support popular LaTeX packages, and renderers to new output
formats.
The XHTML renderer is intended as the basis of all HTML-based renderers; when
writing a new HTML-based renderer, it can be subclassed to exploit the power of
inheritance. Even for completely different output formats the code in the XHTML
renderer can be used as a guide throughout development.
\section{References}\label{sec:ref}
The following locations of software distributions and reference material can be
useful for finding further information.
\begin{description}
\item[plasTeX] \url{plastex.sourceforge.net}
\item[Python] \url{http://www.python.org/download/}
\item[Python Imaging Library] \url{http://www.pythonware.com/products/pil/}
\item[HTML Help Workshop]
\url{http://msdn.microsoft.com/en-us/library/ms669985.aspx}
\item[JavaHelp]
\url{http://java.sun.com/developer/technicalArticles/J2SE/Desktop/javahelp/}
\item[JabRef]
\url{http://jabref.sourceforge.net/}
\item[DocBook]\url{http://www.docbook.org/}
\item[DocBook XSL Stylesheets]
\url{http://docbook.sourceforge.net/release/xsl/current/doc/index.html}
\item[XMLMind Editor] \url{http://www.xmlmind.com/xmleditor}
\item[S5 Slide Show System] \url{http://meyerweb.com/eric/tools/s5/}
\item[BrlTex] \url{http://brltex.sourceforge.net/}
\item[SimpleTal] \url{http://www.owlfish.com/software/simpleTAL/}
\item[Zope Page Templates]
\url{http://www.zope.org/Documentation/Books/ZopeBook/2_6Edition/AppendixC.stx}
\end{description}
\end{document}