summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/checklistings
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 /macros/latex/contrib/checklistings
Initial commit
Diffstat (limited to 'macros/latex/contrib/checklistings')
-rw-r--r--macros/latex/contrib/checklistings/Makefile42
-rw-r--r--macros/latex/contrib/checklistings/README.md56
-rw-r--r--macros/latex/contrib/checklistings/checklistings.dtx1061
-rw-r--r--macros/latex/contrib/checklistings/checklistings.hva188
-rw-r--r--macros/latex/contrib/checklistings/checklistings.ins57
-rw-r--r--macros/latex/contrib/checklistings/checklistings.pdfbin0 -> 286631 bytes
-rwxr-xr-xmacros/latex/contrib/checklistings/checklistings.sh446
-rw-r--r--macros/latex/contrib/checklistings/example.html74
-rw-r--r--macros/latex/contrib/checklistings/example.pdfbin0 -> 73949 bytes
-rw-r--r--macros/latex/contrib/checklistings/example.tex56
10 files changed, 1980 insertions, 0 deletions
diff --git a/macros/latex/contrib/checklistings/Makefile b/macros/latex/contrib/checklistings/Makefile
new file mode 100644
index 0000000000..15126e2aba
--- /dev/null
+++ b/macros/latex/contrib/checklistings/Makefile
@@ -0,0 +1,42 @@
+
+all: checklistings.sty checklistings.pdf
+
+checklistings.pdf: checklistings.dtx checklistings.ind checklistings.sty \
+ checklistings.chkl
+ ./checklistings.sh checklistings.chkl
+ pdflatex $<
+ pdflatex $<
+
+checklistings.ind: checklistings.idx
+ makeindex -s gind.ist -o $@ $<
+
+checklistings.idx checklistings.chkl: checklistings.dtx
+ pdflatex $<
+
+checklistings.sty: checklistings.dtx
+ latex checklistings.ins
+
+example.pdf: example.tex example.chkl checklistings.sty
+ ./checklistings.sh example.chkl
+ pdflatex $<
+ pdflatex $<
+
+example.html: example.tex example.chkl checklistings.hva
+ ./checklistings.sh example.chkl
+ hevea -fix example
+
+example.chkl: example.tex
+ pdflatex $<
+
+clean:
+ -@rm -rf chklisting0*.tex chklisting0*.ml Withopen*
+ -@rm -rf chklisting0*.msg chklisting0*.err
+ -@rm -rf checklistings.aux checklistings.glo checklistings.idx
+ -@rm -rf checklistings.ilg checklistings.ind checklistings.log
+ -@rm -rf checklistings.chkl checklistings.tmp
+ -@rm -rf checklistings.hd checklistings.out
+ -@rm -rf example0*.tex example0*.ml
+ -@rm -rf example0*.msg example0*.err example0*.html
+ -@rm -rf example.aux example.log
+ -@rm -rf example.chkl example.tmp
+
diff --git a/macros/latex/contrib/checklistings/README.md b/macros/latex/contrib/checklistings/README.md
new file mode 100644
index 0000000000..70f6c7fcab
--- /dev/null
+++ b/macros/latex/contrib/checklistings/README.md
@@ -0,0 +1,56 @@
+checklistings
+=============
+
+By [Timothy Bourke](http://www.tbrk.org)
+and [Marc Pouzet](http://www.di.ens.fr/~pouzet).
+
+User manuals and papers about programming languages usually contain many
+code samples, often with accompanying compiler messages giving the types
+of declarations or error messages explaining why certain declarations are
+invalid.
+
+The `checklistings` package augments the
+[fancyvrb](http://www.ctan.org/pkg/fancyvrb) and
+[listings](http://www.ctan.org/pkg/listings) packages for including source
+code in LaTeX documents with a way to pass the source code through a
+compiler and also include the resulting messages in the document.
+
+The motivation is to check the code samples in a document for syntax and
+typing errors and to facilitate the inclusion of inferred types and compiler
+warnings or errors in a text. This package is intentionally very lightweight
+and unlike packages like [python](http://www.ctan.org/pkg/python) it is not
+intended for interacting with an interpretor or including the execution
+traces of code. While `checklistings` does not focus on a specific
+programming language, it is designed to work well with ML-like languages.
+
+Using the package involves three elements:
+
+1. The declaration `\usepackage{checklistings}`.
+2. The verbatim environment `\begin{chklisting}...\end{chklisting}`.
+3. The shell script `checklistings.sh`.
+
+In a first pass, `latex`/`pdflatex` outputs code samples into files.
+The second pass is performed by `checklistings.sh` which passes each file
+through a compiler to generate corresponding output files.
+In a third pass, `latex`/`pdflatex` reads from the generated files to
+incorporate the results into the document.
+
+A `checklistings.hva` file is provided for interoperability with
+[HeVeA](http://hevea.inria.fr).
+
+The `checklistings` package may be distributed and/or modified under the
+conditions of the
+[LaTeX Project Public License](http://www.latex-project.org/lppl.txt),
+either version 1.2 of this license or (at your option) any later version.
+
+Please send comments, suggestions, and bug reports (with version number and
+the keyword "checklistings" in the subject of the message) to
+<tim@tbrk.org>. Please keep in mind that we prefer to keep `checklistings`
+simple and lightweight rather than to incorporate many different
+configuration and customization options. The source code is hosted on
+[GitHub](https://github.com/tbrk/checklistings).
+
+This package was developed within the
+[PARKAS](http://www.di.ens.fr/ParkasTeam.html) at
+[Inria](http://www.inria.fr) and the [ENS](http://www.di.ens.fr).
+
diff --git a/macros/latex/contrib/checklistings/checklistings.dtx b/macros/latex/contrib/checklistings/checklistings.dtx
new file mode 100644
index 0000000000..7e12e53ab3
--- /dev/null
+++ b/macros/latex/contrib/checklistings/checklistings.dtx
@@ -0,0 +1,1061 @@
+% \iffalse meta-comment
+%
+% Copyright (C) 2015 by Timothy Bourke <tim@tbrk.org>
+% and Marc Pouzet <pouzet@ens.fr>
+% -------------------------------------------------------
+%
+% This file may be distributed and/or modified under the
+% conditions of the LaTeX Project Public License, either version 1.2
+% of this license or (at your option) any later version.
+% The latest version of this license is in:
+%
+% http://www.latex-project.org/lppl.txt
+%
+% and version 1.2 or later is part of all distributions of LaTeX version
+% 1999/12/01 or later.
+%
+% CTAN Topic: callback, listing
+% \fi
+%
+% \iffalse
+%<*driver>
+\ProvidesFile{checklistings.dtx}
+%</driver>
+%<package>\NeedsTeXFormat{LaTeX2e}
+%<package>\ProvidesPackage{checklistings}
+%<package> [2015/09/01 v1.0 compile code samples and insert the results]
+%<package>\RequirePackage{keyval}
+%<package>\RequirePackage{kvoptions}
+%<package>\RequirePackage{fancyvrb}
+%<package>\RequirePackage{color}
+%<package>\RequirePackage{listings}
+%<package>\makeatletter
+%<package>\lst@RequireAspects{writefile}
+%<package>\SetupKeyvalOptions{family=CHKL,prefix=CHKL@}
+%<package>\makeatother
+%
+%<*driver>
+\documentclass{ltxdoc}
+
+\usepackage{checklistings}
+\usepackage{url}
+\usepackage{hypdoc}
+\usepackage{showexpl}
+\usepackage{array}
+\usepackage{longtable}
+
+\lstset{
+ basicstyle=\small\ttfamily,
+ numbers=none,
+ keywordstyle=\color{blue}\bfseries,
+ pos=l,
+}
+
+\checklistings{
+ msgstyle={formatcom=\footnotesize},
+ errstyle={formatcom=\footnotesize}}
+
+\EnableCrossrefs \CodelineIndex
+\RecordChanges
+
+\newcommand{\refsec}[1]{Section~\ref{sec:#1}}
+
+\begin{document}
+ \DocInput{checklistings.dtx}
+ \PrintChanges
+ \PrintIndex
+\end{document}
+%</driver>
+% \fi
+%
+% \CheckSum{444}
+%
+% \CharacterTable
+% {Upper-case \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
+% Lower-case \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
+% Digits \0\1\2\3\4\5\6\7\8\9
+% Exclamation \! Double quote \" Hash (number) \#
+% Dollar \$ Percent \% Ampersand \&
+% Acute accent \' Left paren \( Right paren \)
+% Asterisk \* Plus \+ Comma \,
+% Minus \- Point \. Solidus \/
+% Colon \: Semicolon \; Less than \<
+% Equals \= Greater than \> Question mark \?
+% Commercial at \@ Left bracket \[ Backslash \\
+% Right bracket \] Circumflex \^ Underscore \_
+% Grave accent \` Left brace \{ Vertical bar \|
+% Right brace \} Tilde \~}
+%
+%
+% \changes{v1.0}{2015/09/01}{Initial version}
+%
+% \GetFileInfo{checklistings.sty}
+%
+% \DoNotIndex{\newcommand,\newenvironment}
+% \DoNotIndex{\@file,\@ifundefined,\@tempboxa,\@undefined}
+% \DoNotIndex{\arabic,\bgroup,\color,\dimexpr,\relax,\topsep,\vspace}
+% \DoNotIndex{\CurrentOption,\DeclareBoolOption,\DeclareComplementaryOption}
+% \DoNotIndex{\DeclareDefaultOption,\DeclareStringOption,\DeclareVoidOption}
+% \DoNotIndex{\def,\define@key,\edef,\egroup,\else,\emph,\expandafter}
+% \DoNotIndex{\fi,\global,\hbox,\ifnum,\InputIfFileExists,\langle,\let}
+% \DoNotIndex{\newcounter,\newif,\PackageWarning,\ProcessKeyvalOptions}
+% \DoNotIndex{\rangle,\setbox,\setkeys,\space,\stepcounter}
+% \DoNotIndex{\value,\@currentlabel,\@firstoftwo,\AtEndDocument,\em}
+% \DoNotIndex{\closeout,\csname,\endcsname,\DefineVerbatimEnvironment}
+% \DoNotIndex{\jobname,\kvsetkeys,\label,\newwrite,\noexpand,\openout}
+% \DoNotIndex{\partopsep,\setlength,\thepage,\write,\resetcounteronoverlays}
+% \DoNotIndex{\@tempa,\fvset,\ifx,\inputlineno,\lstset,\the}
+% \DoNotIndex{\DeclareRobustCommand,\empty,\ifdefined,\meta}
+% \expandafter\DoNotIndex\expandafter{\string\$}
+% \expandafter\DoNotIndex\expandafter{\string\#}
+%
+% \title{The \textsf{checklistings} package\thanks{This document
+% corresponds to \textsf{checklistings}~\fileversion, dated \filedate.}}
+% \author{Timothy Bourke and Marc Pouzet}
+%
+% \maketitle
+
+% \section{Introduction}
+%
+% User manuals and papers about programming languages usually contain many
+% code samples, often with accompanying compiler messages giving the types
+% of declarations or error messages explaining why certain declarations are
+% invalid.
+% This package extends
+% |fancyvrb|\footnote{\url{http://www.ctan.org/pkg/fancyvrb}} and
+% |listings|\footnote{\url{http://www.ctan.org/pkg/listings}}, which are
+% ideal for displaying code, with a way to pass code samples through a
+% compiler and include the resulting messages in a \LaTeX{} document.
+% The motivation is to check the code samples in a document for syntax and
+% typing errors and to facilitate the inclusion of inferred types and
+% compiler warnings or errors in a text.
+% This package is intentionally very lightweight and unlike packages like
+% |python|,\footnote{\url{http://www.ctan.org/pkg/python}} it is not
+% intended for interacting with an interpretor or including the execution
+% traces of code.
+% While it does not focus on a specific programming language, it is designed
+% to work well with ML-like languages.
+%
+% As an example, the text at left below is generated by the \LaTeX{} code at
+% right:
+%
+% \iffalse
+%<*example>
+% \fi
+\begin{LTXexample}
+Code samples are included
+verbatim and the results of
+compilation can be included
+automatically:
+\begin{chklisting}[withresult]
+let inc x = x + 1
+let y = inc 3
+\end{chklisting}
+\end{LTXexample}
+% \iffalse
+%</example>
+% \fi
+%
+% A first pass through |latex| generates both a |.chkl| file,
+% with parameters for the compiler, and an |.ml| file containing the source
+% code (i.e., the two lines in the example above).
+% Running the |checklistings.sh| script processes these files to produce a
+% |.tex| file with the results of compilation.
+% A second pass through |latex| updates the compiler message.
+%
+% \noindent
+% It is possible to continue examples and to label them (to be continued at
+% some later point):
+% \iffalse
+%<*example>
+% \fi
+\begin{LTXexample}[pos=b]
+These definitions follow on from the previous ones:
+\begin{chklisting}[continue,withresult,label=early]
+let z = y + inc y
+\end{chklisting}
+\end{LTXexample}
+% \iffalse
+%</example>
+% \fi
+%
+% \bigskip\noindent
+% Examples need not necessarily succeed:
+% \iffalse
+%<*example>
+% \fi
+\begin{LTXexample}[pos=b]
+This code does not compile:
+\begin{chklisting}[continue,fail,withresult,skipone]
+let u = 3
+let w = u + "four"
+\end{chklisting}
+\end{LTXexample}
+% \iffalse
+%</example>
+% \fi
+% Note that the line number in the error message is 1 even though the
+% |continue| option added a line to include the previous definitions and the
+% |skipone| option hid the |let u = 3| line.
+% The |checklistings.sh| script performs this adjustment by looking for the
+% regular expression `|line *[0-9][0-9]*|' and decrementing the number
+% appropriately.
+% This approach is simple and effective but obviously not foolproof.
+% Some manual tuning of the script may be required for correct results.
+%
+% \section{Use}\label{sec:use}
+%
+% Using the package involves three elements:
+% \begin{enumerate}
+%
+% \item
+% The declaration \verb|\usepackage{checklistings}|.\\
+% \refsec{rvpkg} describes the options for configuring package behaviour.
+%
+% \item
+% The environment \verb|chklisting|.\\
+% This environment is used like any other verbatim environment.
+% \refsec{rvenv} describes options that may be given to control its
+% behaviour.
+%
+% \item
+% The script \verb|checklistings.sh|.\\
+% Running this script passes the contents of each \verb|chklisting|
+% environment through a compiler or interpreter and copies the resulting
+% output into a file.
+%
+% \end{enumerate}
+%
+% Additionally, the file \verb|checklistings.hva| can be used to incorporate
+% the output of |checklistings| in HTML documents generated by
+% HeVeA.\footnote{\url{http://hevea.inria.fr}}
+%
+% \subsection{Package options}\label{sec:rvpkg}
+%
+% \DescribeMacro{\checklistings}
+% Package options are either given as optional arguments to
+% \verb|\usepackage| or via one or more calls to \verb|\checklistings|.
+% The advantage of the latter is that macros are not expanded (for a
+% detailed explanation see the documentation for
+% |kvoptions|,\footnote{\url{http://www.ctan.org/pkg/kvoptions}} Section
+% 4.1, \emph{Package kvoptions-patch}).
+% Options are passed as a comma separated list of \meta{key}|=|\meta{value}
+% pairs and single \meta{key}s.
+%
+% There are three classes of options: options controlling the default
+% behaviour of \verb|chklisting|, options for configuring the
+% \verb|checklistings.sh| script, and options controlling the display of
+% code and results.
+%
+% \subsubsection{Behavioural options}
+%
+% These options control the default behaviour of the \verb|chklisting|
+% environment.
+%
+% \begin{longtable}{@{}>{\ttfamily}lp{75mm}>{\ttfamily}l@{}}
+% \parbox{15mm}{option} & description & \parbox{25mm}{default}\\\hline
+% withresult
+% & Automatically show compilation results.
+% & false
+% \\
+% skipone
+% & Do not display the first line of code (see the description under the
+% |chklisting| environment).
+% &
+% false
+% \\
+% skiptwo
+% & Do not display the first two lines of code (see the description under
+% the |chklisting| environment).
+% &
+% false
+% \\
+% hideproblems
+% & Globally disable the display of failure messages (within a red box) when
+% compilation fails or succeeds unexpectedly.
+% &
+% false
+% \\
+% \end{longtable}
+%
+% \subsubsection{Configuring compilation}\label{sec:compileconfig}
+%
+% These options are used for naming and placing the files generated by
+% \verb|chklisting| environments.
+% They are passed to the \verb|checklistings.sh| script and thus control
+% its behaviour.
+%
+% \makeatletter
+% \begin{longtable}{@{}>{\ttfamily}lp{75mm}>{\ttfamily}l@{}}
+% \parbox{15mm}{option} & description & \parbox{25mm}{default}\\\hline
+% prefix
+% & Prefix for naming source files.
+% It must not contain underscores (\verb|_|).
+% & \CHKL@prefix
+% \\
+% ext
+% & Extension of source files.
+% & \CHKL@ext
+% \\
+% subdir
+% & If defined, source files are created in the given subdirectory, which
+% must already exist.
+% A final slash (\verb|/|) should not be given.
+% The name must not contain underscores (\verb|_|).
+% & \CHKL@subdir
+% \\
+% prompt
+% & The prompt displayed by |\chklistingcmd|.
+% & \CHKL@prompt
+% \\
+% compiler
+% & Path of the compiler to execute.
+% & \CHKL@compiler
+% \\
+% compilerflags
+% & Flags passed to the compiler.
+% These are not revealed by |\chklistingcmd|.
+% & \CHKL@compilerflags
+% \\
+% lastflags
+% & Flags passed to the compiler before the main source file, that is, the
+% last one given.
+% & \CHKL@lastflags
+% \\
+% includecmd
+% & The source language command for importing the definitions of another
+% file.
+% & \CHKL@includecmd
+% \\
+% html
+% & The path of a program that renders source code as html.
+% This value can be useful when using HeVeA to produce web pages from
+% \LaTeX{} documents.
+% In any case, it is optional.
+% & \CHKL@html
+% \end{longtable}
+% \makeatother
+%
+% Each \verb|chklisting| environment is assigned a number $n$, from zero,
+% and its contents are written to the file:
+% \meta{subdir}|/|\meta{prefix}\meta{n}|.|\meta{ext},
+% where \meta{n} is zero-padded to four characters.
+% For example, by default, the fourth environment is written to the file
+% \verb|chklisting0003.ml| in the current directory.
+%
+% Source lines are added for each dependency, and those files are compiled
+% using the \meta{compiler}, \meta{compilerflags}, and \meta{lastflags}
+% options.
+% For example, if the fourth environment depends on the first and the
+% second, a line is added:
+% \begin{center}
+% \meta{includecmd} |Withopen0000| \meta{includecmd} |Withopen0001|,
+% \end{center}
+% where \verb|Withopen| is the prefix used for such augmented files, and the
+% compiler is invoked with:\\
+% \begin{center}
+% \begin{tabular}{ll}
+% \meta{compiler}
+% & \meta{compilerflags}\ \ |Withopen0000|\ \ |Withopen0001| \\
+% & \meta{lastflags}\ \ |Withopen0003|
+% \end{tabular}
+% \end{center}
+%
+% \subsubsection{Controlling the display}
+%
+% This package exploits the display options given by the |fancyvrb| package.
+%
+% \begin{longtable}{@{}>{\ttfamily}lp{75mm}>{\ttfamily}l@{}}
+% \parbox{15mm}{option} & description & \parbox{25mm}{default}\\\hline
+% codestyle
+% & |fancyvrb| options for code
+% & \\
+% msgstyle
+% & |fancyvrb| options for compiler messages
+% & formatcom=\string\em
+% \\
+% errstyle
+% & |fancyvrb| options for error messages
+% & formatcom=\string\em
+% \\
+% codelst
+% & |listings| options for source code, passed with |\lstset|. When this
+% option is not empty, |fancyvrb=true| is included automatically.
+% \\
+% msglst
+% & As for |codelst|, but applied to compiler messages.
+% \\
+% errlst
+% & As for |codelst|, but applied to error messages.
+% \\
+% \end{longtable}
+%
+% Other options are passed directly through to the |fancyvrb| package and
+% applied to all |chklisting| code blocks (but not to messages or errors).
+% For example, \verb|frame=single|.
+% These options must typically be set using |\checklistings|, since they
+% will usually contain commands that should not be expanded immediately
+% (like |\em| or |\bf|).
+%
+% \subsection{The \texttt{chklisting} environment}\label{sec:rvenv}
+%
+% \DescribeEnv{chklisting}
+% As an optional argument, this environment takes a comma separated list of
+% \meta{key}|=|\meta{value} and single \meta{key}s.
+%
+% \begin{longtable}{@{}>{\ttfamily}lp{100mm}}
+% \parbox{15mm}{option} & description \\\hline
+% fail
+% & This code is expected to fail; an error is reported if it succeeds.
+% \\
+% continue
+% & This code is continued from the previous |chklisting| environment; all
+% of the definitions available there are imported.
+% \\
+% label
+% & Label this code for later inclusion.
+% \\
+% include
+% & All of the definitions available after the environment with the given
+% label are imported.
+% \\
+% withresult
+% & The result of compiling the code is displayed (see also
+% |\chklistingmsg| and |\chklistingerr|).
+% This is normally either the types of declared values or the results of
+% evaluation.
+% For environments marked |fail|, it will be an error message.
+% \\
+% withoutresult
+% & The result of compiling code is not displayed automatically.
+% This is the default behaviour, but it can be overridden by the package
+% options.
+% \\
+% hide
+% & The code is not displayed, but it is still compiled, compiler messages
+% are still displayed (if |withresult| is active), and definitions are still
+% available for continuation (|continue|), labelling (|label|), and later
+% inclusion (|include|).
+% \\
+% skipone
+% & Do not display the first line of the code.
+% This line is still sent to the compiler and may thus be used to open
+% other modules, or to pass execution options (via comments).
+% \\
+% skiptwo
+% & As pre the previous option, but two lines are skipped.
+% \\
+% skipnone
+% & Do not skip any lines; this option overrides any package-level skip
+% setting.
+% \\
+% hideproblems
+% & Do not display an error message within the document when compilation
+% fails or succeeds unexpectedly.
+% \\
+% showproblems
+% & Display an error message within the document when compilation fails or
+% succeeds unexpectedly.
+% This is the default behaviour unless the |hideproblems| package option was
+% set.
+% \\
+% \end{longtable}
+%
+% The results of compiling the code of a |chklisting| environment are made
+% available in the following macros until the next |chklisting| which will
+% redefine them.
+% \begin{description}
+%
+% \item[\texttt{\string\chklistingcmd}]
+% \DescribeMacro{\chklistingcmd}
+% contains an idealised version of the command line used to compile the code
+% sample.
+% It includes the |prompt|, the basename of |compiler|, and |lastflags|, but
+% not |compilerflags| or the list of included files.
+% Furthermore, the |subdir| and serial number are removed from the filename
+% of the code sample, which becomes simply \meta{prefix}|.|\meta{ext}.
+%
+% \item[\texttt{\string\chklistingmsg\marg{label}}]
+% \DescribeMacro{\chklistingmsg}: inserts the verbatim text emitted by the
+% compiler, provided compilation succeeded, for the |chklisting|
+% environment labelled \meta{label}.
+% When \meta{label} is left empty, the message for the last environment is
+% inserted.
+% It should not be used after environments marked |fail|.
+%
+% \item[\texttt{\string\chklistingerr\marg{label}}]
+% \DescribeMacro{\chklistingerr}: inserts the verbatim text emitted by the
+% compiler, provided compilation failed, for the |chklisting| environment
+% labelled \meta{label}.
+% When \meta{label} is left empty, the message for the last environment is
+% inserted.
+% It should only be used after environments marked |fail|.
+% \end{description}
+%
+% \subsection{The \texttt{checklistings.sh} script}\label{sec:rvsh}
+%
+% Processing a document that uses the |checklistings| package produces a
+% |.chkl| file containing compiler options and a list of source files
+% together with their interdependencies.
+% The |checklistings.sh| script processes |.chkl| files by executing the
+% specified compiler against each listed source file
+% \meta{subdir}|/|\meta{prefix}\meta{n}|.|\meta{ext} and copying the
+% results---the command-line used, whether it succeeded or failed, the
+% messages on |stdout|, and the messages on |stderr|---into a corresponding
+% file, \meta{subdir}|/|\meta{prefix}\meta{n}|.tex|, for inclusion in the
+% original document.
+%
+% The \verb|checklistings.sh| script is written for the Bourne shell
+% (\verb|sh|).
+% It takes a list of |.chkl| files as arguments (with or without the
+% exentions), but if none are given it processes all such files in the
+% current working directory.
+%
+% The compilation options specified within a \LaTeX{} source file, see
+% \refsec{compileconfig}, can be manually overridden by processing a |.chkl|
+% file, before any others, containing a `|lock|' directive, for example:
+% |lock compiler=/usr/local/bin/ocamlc|.
+% This feature is useful when working with others to develop the compiler
+% being documented.
+%
+% \StopEventually{}
+\makeatletter
+%
+% \section{Remarks}
+%
+% \subsection{Known limitations}
+%
+% The package and script have some known limitations.
+% \begin{itemize}
+%
+% \item
+% Line numbers in error messages may not correspond correctly with the line
+% numbers of sample files, due to either the |skip*| options, or because of
+% lines added to import code.
+%
+% \item
+% The system has been designed to work with ML-style compilers.
+% It has not been tested with other compilers and interpreters.
+% Please contact \url{tim@tbrk.org} if you would like to support other
+% systems.
+% Patches are most welcome, but the intent is to keep this package
+% relatively simple rather than to try to do everything.
+%
+% \item
+% Multiple languages in a single document are not supported.
+%
+% \item
+% Care must be taken when using |checklistings| with the overlays of the
+% Beamer package.
+% In particular, |chklisting| environment commands are to be avoided within
+% commands that completely omit material from slides, like |only|, |alt|, or
+% |temporal|, or with `closed' overlay specifications, like |2| or |1-3|.
+% As these commands do not execute the material, the environment sequence
+% numbers do not increase monotonically, and the compilation results may not
+% be properly synchronized with the verbatim text.
+% Commands that only hide material, or that introduce it successively, like
+% |uncover| or |visible|, or `open' overlay specifications, like |2-|,
+% should function as expected.
+%
+% \end{itemize}
+%
+% \section{Implementation}
+%
+% All internal macros have names of the form |\CHKL@|\meta{name}.
+%
+% \begin{macro}{\chklisting}
+% Generate the sequence of source code identifiers used in per-environment
+% filenames and to manage dependencies.
+% If |beamer| is being used, reset the counter on each overlay to avoid
+% generating multiple output files for the same program.
+% \begin{macrocode}
+\newcounter{chklisting}
+\ifdefined\resetcounteronoverlays
+\resetcounteronoverlays{chklisting}
+\fi
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\ifCHKL@fileexists}
+% An internal boolean variable for remembering whether an input |.tex| file,
+% corresponding to the compilation of source code, was found.
+% \begin{macrocode}
+\newif\ifCHKL@fileexists
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Package Options}
+%
+% The package options are processed using the |kvoptions| package.
+%
+% \begin{macro}{\CHKL@pkg@verbopts}
+% This list accumulates package-level options for the |verbatim|
+% environments.
+% \begin{macrocode}
+\def\CHKL@pkg@verbopts{}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\CHKL@pkg@globalskip}
+% Defines the number of lines to be skipped when displaying a code sample as
+% defined by the global options |skipone| and |skiptwo|.
+% \begin{macrocode}
+\def\CHKL@pkg@globalskip{0}
+% \end{macrocode}
+% \end{macro}
+%
+% \noindent
+% Declare the package options and their default values:
+
+% \begin{macrocode}
+\DeclareBoolOption{withresult}
+\DeclareComplementaryOption{withoutresult}{withresult}
+\DeclareBoolOption[true]{showproblems}
+\DeclareComplementaryOption{hideproblems}{showproblems}
+\DeclareVoidOption{skipone}
+ {\edef\CHKL@pkg@globalskip{1}%
+ \edef\CHKL@pkg@verbopts{\CHKL@pkg@verbopts,firstline=2}}
+\DeclareVoidOption{skiptwo}
+ {\edef\CHKL@pkg@globalskip{2}%
+ \edef\CHKL@pkg@verbopts{\CHKL@pkg@verbopts,firstline=3}}
+\DeclareDefaultOption
+ {\edef\CHKL@pkg@verbopts{\CHKL@pkg@verbopts,\CurrentOption}}
+\DeclareStringOption[]{codestyle}
+\DeclareStringOption[formatcom=\em]{msgstyle}
+\DeclareStringOption[formatcom=\em]{errstyle}
+\DeclareStringOption{codelst}
+\DeclareStringOption{msglst}
+\DeclareStringOption{errlst}
+\DeclareStringOption{emptyoption}
+\DeclareStringOption[.]{subdir}
+\DeclareStringOption[chklisting]{prefix}
+\DeclareStringOption[.ml]{ext}
+\DeclareStringOption[\#]{prompt}
+\DeclareStringOption[ocamlc]{compiler}
+\DeclareStringOption{compilerflags}
+\DeclareStringOption[-i]{lastflags}
+\DeclareStringOption[open]{includecmd}
+\DeclareStringOption[]{html}
+\ProcessKeyvalOptions*
+% \end{macrocode}
+%
+% \begin{macro}{\checklistings}
+% This macro offers another way of setting package options with the
+% advantage that values are not expanded.
+% \begin{macrocode}
+\def\checklistings{\kvsetkeys{CHKL}}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Logging Files to be Processed}
+%
+% Several definitions and commands are used to create and write to the
+% |.chkl| file.
+%
+% \begin{macro}{\CHKL@samplefile}
+% The file generated when a \LaTeX{} document that uses the |checklistings|
+% package is processed.
+% \begin{macrocode}
+\newwrite\CHKL@samplefile
+\openout\CHKL@samplefile=\jobname.chkl
+\AtEndDocument{\closeout\CHKL@samplefile}
+% \end{macrocode}
+% \end{macro}
+%
+% Package options are logged to the file.
+% \begin{macrocode}
+\write\CHKL@samplefile{subdir=\CHKL@subdir/}
+\write\CHKL@samplefile{prefix=\CHKL@prefix}
+\write\CHKL@samplefile{ext=\CHKL@ext}
+\write\CHKL@samplefile{compiler=\CHKL@compiler}
+\write\CHKL@samplefile{compilerflags=\CHKL@compilerflags}
+\write\CHKL@samplefile{lastflags=\CHKL@lastflags}
+\write\CHKL@samplefile{includecmd=\CHKL@includecmd}
+\write\CHKL@samplefile{htmlfilter=\CHKL@html}
+% \end{macrocode}
+%
+% \begin{macro}{\CHKL@logsample}
+% An entry is logged for each |chklisting| environment.
+% It contains the sequence number for the example, followed by a colon, an
+% ordered list of other sample files to import, and the page and line
+% numbers (to include in error messages).
+% \begin{macrocode}
+\DeclareRobustCommand{\CHKL@logsample}[2]{%
+ \edef\CHKL@tolog{#1:#2 [page=\noexpand\thepage] [line=\the\inputlineno]}%
+ \expandafter\write\expandafter\CHKL@samplefile\expandafter{\CHKL@tolog}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Insertion of Compilation Results}
+%
+% Several macros are defined for use by the |checklistings.sh| script (and
+% any similar program).
+% These macros are called from within the |.tex| file generated for each
+% |chklisting| environment.
+%
+% \begin{macro}{\ifchklisting}
+% A successful compilation is signalled by |\chklistingtrue|, and a failed
+% compilation by |\chklistingfalse|.
+% \begin{macrocode}
+\newif\ifchklisting
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\setchklistingcmd}
+% The command used to compile a sample is recorded by |\setchklistingcmd|
+% which (re)defines the internal |\CHKL@prompt| value.
+% \begin{macrocode}
+\DeclareRobustCommand{\setchklistingcmd}[1]{%
+ \global\def\chklistingcmd{\emph{\CHKL@prompt{#1}}}}
+% \end{macrocode}
+% \end{macro}
+
+% \begin{environment}{ChkListingMsg}
+% Normal compiler messages (written on |stdout|) should be communicated
+% between |\begin{ChkListingMsg}| and |\end{ChkListingMsg}|.
+% This verbatim text is saved using the |SaveVerbatim| feature of
+% |fancyvrb|.
+% \begin{macrocode}
+\def\ChkListingMsg{\FV@Environment{}{ChkListingMsg}}
+\def\FVB@ChkListingMsg{\FVB@SaveVerbatim{ChkListingMsg}}
+\let\FVE@ChkListingMsg\FVE@SaveVerbatim
+\DefineVerbatimEnvironment{ChkListingMsg}{ChkListingMsg}{}
+% \end{macrocode}
+% \end{environment}
+
+% \begin{environment}{ChkListingErr}
+% Compiler error messages (usually written on |stderr|) should be
+% communicated between |\begin{ChkListingErr}| and |\end{ChkListingErr}|.
+% This verbatim text is saved using the |SaveVerbatim| feature of
+% |fancyvrb|.
+% \begin{macrocode}
+\def\ChkListingErr{\FV@Environment{}{ChkListingErr}}
+\def\FVB@ChkListingErr{\FVB@SaveVerbatim{ChkListingErr}}
+\let\FVE@ChkListingErr\FVE@SaveVerbatim
+\DefineVerbatimEnvironment{ChkListingErr}{ChkListingErr}{}
+% \end{macrocode}
+% \end{environment}
+
+% \begin{macro}{\chklistingfile}
+% This is the filename used by |checklistings.sh| to refer to the file
+% containing sample code when |\setchklistingcmd| is called.
+% \begin{macrocode}
+\DeclareRobustCommand{\chklistingfile}{\CHKL@prefix\CHKL@ext}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Main Environment}
+%
+% Several auxiliary definitions are needed to track per-environment
+% configuration options.
+%
+% \begin{macro}{\ifCHKL@shouldfail}
+% This boolean variable records whether sample code is expected to fail.
+% \begin{macrocode}
+\newif\ifCHKL@shouldfail
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\ifCHKL@showcode}
+% This boolean variable records whether the compilation result should be
+% shown.
+% \begin{macrocode}
+\newif\ifCHKL@showcode
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\CHKL@skip}
+% Defines the number of lines to be skipped when displaying a code sample.
+% It defaults to the value of |\CHKL@pkg@globalskip|, but may be altered by
+% the environment options |skipone| and |skiptwo|.
+% This value is only used to generate the |skip=| field in the |.chkl| file.
+% The actual skipping is done by the |firstline| option of |verbopts|.
+% \begin{macrocode}
+\def\CHKL@skip{0}
+% \end{macrocode}
+% \end{macro}
+%
+% The |keyval| package\footnote{\url{http://www.ctan.org/pkg/keyval}} is
+% used to parse environment options.
+% The following macros setup parameters used by the |chklisting|
+% environment.
+%
+% \begin{macro}{\CHKL@continue}
+% \begin{macro}{\CHKL@precontinue}
+% These two macros hold lists of source code identifiers:
+% |\CHKL@precontinue| tracks the dependencies of the previous |chklisting|
+% environment and |\CHKL@continue| tracks those of the current one.
+% The |continue| option appends the previous dependencies onto the list of
+% current ones.
+% The dependencies used at each labelled environment are remembered in
+% |\RBRB@deps|\meta{label}.
+% The |include| option causes them to be added to the list of current
+% dependencies.
+%
+% \begin{macrocode}
+\edef\CHKL@precontinue{}
+\define@key{CHKL@envkeys}{continue}[]{\edef\CHKL@continue{\CHKL@precontinue}}
+\define@key{CHKL@envkeys}{include}{%
+ \edef\CHKL@continue{\CHKL@continue\space\@ifundefined{CHKL@deps@#1}%
+ {#1}{\csname CHKL@deps@#1\endcsname}}}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macrocode}
+\define@key{CHKL@envkeys}{fail}[]{\CHKL@shouldfailtrue}
+\define@key{CHKL@envkeys}{label}{\edef\CHKL@label{#1}}
+\define@key{CHKL@envkeys}{skipnone}[]{%
+ \edef\CHKL@skip{0}\edef\CHKL@verbopts{\CHKL@verbopts,firstline=1}}
+\define@key{CHKL@envkeys}{skipone}[]{%
+ \edef\CHKL@skip{1}\edef\CHKL@verbopts{\CHKL@verbopts,firstline=2}}
+\define@key{CHKL@envkeys}{skiptwo}[]{%
+ \edef\CHKL@skip{2}\edef\CHKL@verbopts{\CHKL@verbopts,firstline=3}}
+\define@key{CHKL@envkeys}{hide}[]{\CHKL@showcodefalse}
+\define@key{CHKL@envkeys}{withresult}[]{\CHKL@withresulttrue}
+\define@key{CHKL@envkeys}{withoutresult}[]{\CHKL@withresultfalse}
+\define@key{CHKL@envkeys}{showproblems}[]{\CHKL@showproblemstrue}
+\define@key{CHKL@envkeys}{hideproblems}[]{\CHKL@showproblemsfalse}
+% \end{macrocode}
+%
+% \begin{macro}{\chklistingmsg}
+% This macro takes a single argument \meta{label}.
+% It first configures the |listings| and |fancyvrb| packages with the
+% current display options.
+% It then checks the |fancyvrb| saved text namespace
+% (`\texttt{FV@SV@\ldots}') for an entry named `\texttt{\ldots
+% CHKL@MSG@\meta{label}}'.
+% If found, the associated verbatim text is inserted via the |\UseVerbatim|
+% feature of |fancyvrb|, otherwise an error message is inserted.
+% In the latter case, we prefer not to fail outright, because the user may
+% not yet have had the chance to run the compiler on the extracted code, in
+% which case the log will already contain warnings from |chklisting|.
+% By convention, the |chklisting| environment creates an entry for the
+% empty label (`\texttt{FV@SV@CHKL@MSG@}') when compilation succeeds.
+% \begin{macrocode}
+\DeclareRobustCommand{\chklistingmsg}[1]{
+ \bgroup%
+ \ifx\CHKL@msglst\CHKL@emptyoption\else
+ \expandafter\lstset\expandafter{\CHKL@msglst,fancyvrb=true}\fi%
+ \@ifundefined{FV@SV@CHKL@MSG@#1}
+ {\def\@tempa{#1}
+ \ifx\@tempa\empty
+ \CHKL@none
+ \else
+ $\langle$No message found for the label `#1'!$\rangle$
+ \fi}
+ {\expandafter\UseVerbatim\expandafter[\CHKL@msgstyle]{CHKL@MSG@#1}}%
+ \egroup}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\chklistingerr}
+% This macro is essentially the same as the previous one---only that the
+% substring `\texttt{ERR}' is used instead of `\texttt{MSG}'.
+% \begin{macrocode}
+\DeclareRobustCommand{\chklistingerr}[1]{
+ \bgroup%
+ \ifx\CHKL@errlst\CHKL@emptyoption\else
+ \expandafter\lstset\expandafter{\CHKL@errlst,fancyvrb=true}\fi%
+ \@ifundefined{FV@SV@CHKL@ERR@#1}
+ {\def\@tempa{#1}
+ \ifx\@tempa\empty
+ \CHKL@none
+ \else
+ $\langle$No message found for the label `#1'!$\rangle$
+ \fi}
+ {\expandafter\UseVerbatim\expandafter[\CHKL@errstyle]{CHKL@ERR@#1}}%
+ \egroup}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{environment}{chklisting}
+% This is the main environment for including source code.
+% This macro works in two parts:
+% \begin{enumerate}
+% \item
+% It uses the listings package to write the code to a file,
+% \item
+% It either loads the corresponding |.tex| file or logs an error message.
+% \end{enumerate}
+%
+% The |listings| package allows the definition of custom verbatim
+% environments.
+% This one has a single argument (a list of |keyval| options).
+%
+% \begin{macrocode}
+\lstnewenvironment{chklisting}[1][]
+ {%
+% \end{macrocode}
+% Set default parameter values before invoking |\setkeys|:
+% \begin{macrocode}
+ \CHKL@shouldfailfalse%
+ \CHKL@showcodetrue%
+ \let\CHKL@label\@undefined%
+ \edef\CHKL@continue{}%
+ \def\CHKL@skip{\CHKL@pkg@globalskip}%
+ \let\CHKL@verbopts\CHKL@pkg@verbopts%
+ \def\@currentlabel{\thechklisting}%
+ \setkeys{CHKL@envkeys}{#1}%
+% \end{macrocode}
+%
+% Log an entry to the |.chkl| file:
+%
+% \begin{macrocode}
+ \CHKL@logsample{\arabic{chklisting}}{\CHKL@continue%
+ \space\ifnum\CHKL@skip>0[skip=\CHKL@skip]\fi%
+ \ifCHKL@shouldfail\space[fail]\fi}%
+% \end{macrocode}
+%
+% Update |\CHKL@precontinue| for the next source code block, and, if a label
+% was defined, add an |\CHKL@deps@|\meta{label} entry.
+%
+% \begin{macrocode}
+ \global\edef\CHKL@precontinue{\CHKL@continue\space\arabic{chklisting}}%
+ \@ifundefined{CHKL@label}{}{%
+ \global\expandafter\edef\csname CHKL@deps@\CHKL@label\endcsname{\CHKL@precontinue}}%
+% \end{macrocode}
+%
+% A file will be created in the |\CHKL@subdir| subdirectory, with the name
+% |\CHKL@prefix| followed by the value of the |chklisting| counter, padded
+% out with zeroes to four digits, and the extension |\RBRB@ext|.
+%
+% \begin{macrocode}
+ \edef\CHKL@num{%
+ \ifnum\value{chklisting}<1000 0\fi
+ \ifnum\value{chklisting}<100 0\fi
+ \ifnum\value{chklisting}<10 0\fi
+ \arabic{chklisting}}%
+ \stepcounter{chklisting}%
+ \def\CHKL@file{\CHKL@subdir/\CHKL@prefix\CHKL@num}%
+% \end{macrocode}
+%
+% Clear the definitions used to return information about the compilation
+% run, and close the environment by opening a file, using the |listings|
+% package, into which to write the ensuing contents.
+%
+% \begin{macrocode}
+ \global\let\chklistingcmd\@undefined%
+ \global\let\FV@SV@ChkListingMsg\@undefined%
+ \global\let\FV@SV@ChkListingErr\@undefined%
+ \chklistingtrue%
+ \setbox\@tempboxa\hbox\bgroup%
+ \lst@BeginWriteFile{\CHKL@file\CHKL@ext}%
+ }
+% \end{macrocode}
+%
+% Start closing the environment by closing the previously opened file and
+% group.
+%
+% \begin{macrocode}
+ {%
+ \lst@EndWriteFile%
+ \egroup%
+% \end{macrocode}
+%
+% If |hide| is not active, apply |\CHKL@verbopts| and reload the newly
+% created file.
+%
+% \begin{macrocode}
+ \ifCHKL@showcode%
+ \bgroup%
+ \ifx\CHKL@codelst\CHKL@emptyoption\else%
+ \expandafter\lstset\expandafter{\CHKL@codelst,fancyvrb=true}%
+ \fi%
+ \expandafter\fvset\expandafter{\CHKL@verbopts}%
+ \expandafter\VerbatimInput\expandafter[\CHKL@codestyle]{\CHKL@file\CHKL@ext}%
+ \egroup%
+ \fi%
+% \end{macrocode}
+%
+% Check whether a corresponding |.tex| file was created:
+%
+% \begin{macrocode}
+ \global\edef\CHKL@none{$\langle$Cannot load \CHKL@file.tex!$\rangle$}%
+ \InputIfFileExists{\CHKL@file.tex}{\CHKL@fileexiststrue}{\CHKL@fileexistsfalse}%
+% \end{macrocode}
+%
+% If the |.tex| file was loaded successfully, create `unlabelled' saved
+% verbatim environments for the message and error texts.
+% These are exploited, respectively, by the |\chklistingmsg| and
+% |\chklistingerr| macros.
+%
+% \begin{macrocode}
+ \ifCHKL@fileexists%
+ \@ifundefined{FV@SV@ChkListingMsg}%
+ {}{\global\let\FV@SV@CHKL@MSG@=\FV@SV@ChkListingMsg}%
+ \@ifundefined{FV@SV@ChkListingErr}%
+ {}{\global\let\FV@SV@CHKL@ERR@=\FV@SV@ChkListingErr}%
+% \end{macrocode}
+%
+% Then, if compilation failed and the |fail| option was not active, or if
+% compilation succeeded and the |fail| option is active, log a warning
+% message and, if errors are not being ignored, include details in the
+% document.
+% Otherwise, if |withresult| was given, expand either |\chklistingerr| or
+% |\chklistingmsg|.
+%
+% \begin{macrocode}
+ \ifCHKL@shouldfail%
+ \ifchklisting%
+ \PackageWarning{checklistings}%
+ {Compilation of \CHKL@file\CHKL@ext\space should have failed}%
+ \ifCHKL@showproblems%
+ \UseVerbatim[frame=single,
+ label=Unexpected success,
+ rulecolor=\color{red}]{ChkListingMsg}%
+ \fi%
+ \else%
+ \ifCHKL@withresult%
+ {\setlength{\partopsep}{0em}\chklistingerr{}}%
+ \fi%
+ \fi%
+ \else%
+ \ifchklisting%
+ \ifCHKL@withresult%
+ {%\vspace{\dimexpr-2\topsep-2\partopsep+.5em\relax}%
+ \setlength{\partopsep}{0em}\chklistingmsg{}}%
+ \fi%
+ \else%
+ \PackageWarning{checklistings}%
+ {Compilation of \CHKL@file\CHKL@ext\space should not have failed}%
+ \ifCHKL@showproblems%
+ \UseVerbatim[frame=single,
+ label=Unexpected failure,
+ rulecolor=\color{red}]{ChkListingErr}%
+ \fi%
+ \fi%
+ \fi%
+ \else%
+% \end{macrocode}
+%
+% If the |.tex| file was not loaded successfully, clear the
+% |\chklistingcmd| macros, and the `unlabelled' saved verbatim environments
+% for the message and error results.
+%
+% \begin{macrocode}
+ \PackageWarning{checklistings}{Cannot load \CHKL@file.tex}%
+ \global\let\chklistingcmd\CHKL@none%
+ \global\let\FV@SV@CHKL@MSG@\@undefined%
+ \global\let\FV@SV@CHKL@ERR@\@undefined%
+ \fi%
+% If this environment is labelled, create persistent references to the saved
+% verbatim environments for the message and error results.
+% These are exploited, respectively, by the |\chklistingmsg| and
+% |\chklistingerr| macros when their \meta{label} argument is not empty.
+%
+ \@ifundefined{CHKL@label}{}{%
+ \global\expandafter\let%
+ \csname FV@SV@CHKL@MSG@\CHKL@label\endcsname=\FV@SV@CHKL@MSG@%
+ \global\expandafter\let%
+ \csname FV@SV@CHKL@ERR@\CHKL@label\endcsname=\FV@SV@CHKL@ERR@%
+ }%
+ }%
+% \end{macrocode}
+% \end{environment}
+%
+\makeatother
+\clearpage
+% \Finale
+\endinput
diff --git a/macros/latex/contrib/checklistings/checklistings.hva b/macros/latex/contrib/checklistings/checklistings.hva
new file mode 100644
index 0000000000..8e3a95563b
--- /dev/null
+++ b/macros/latex/contrib/checklistings/checklistings.hva
@@ -0,0 +1,188 @@
+%% HeVeA support for checklistings.
+%%
+%% Limitations / caveats
+%%
+%% * checklistings.hva requires all the intermediate generated by latex and
+%% checklistings.sh (*.<ext>, *.tex, *.msg, *.err).
+%%
+%% * The options 'codestyle', 'msgstyle', 'errstyle', 'codelst', 'msglst',
+%% and 'errlst' cannot be set as in LaTeX, e.g.,
+%% \checklistings{codelst={language=caml}}
+%% Since HeVeA eliminates the grouping braces and passes 'language' to
+%% the handler for 'codelst' (rather than 'language=caml').
+%%
+%% One workaround is to \usepackage{hevea} and use \ifhevea to select
+%% the most appropriate of the two forms.
+%%
+%% * fancyvrb and the package options codestyle, msgstyle, and errstyle are
+%% not supported.
+%% Alternative 1: use the codelst, msglst, and errlst options.
+%% Alternative 2: use css for formatting code, messages, and errors.
+%%
+%% * Non-empty labels in the arguments of \chklistingmsg and
+%% \chklistingerr are not supported.
+%%
+\ProvidesPackage{checklistings}
+\RequirePackage{keyval}
+\RequirePackage{listings}
+
+\newcounter{chklisting}
+\setcounter{chklisting}{-1}
+
+\newif\ifCHKL@fileexists
+\newif\ifCHKL@showcode\CHKL@showcodetrue
+\newif\ifCHKL@shouldfail\CHKL@shouldfailfalse
+\newif\ifCHKL@withresult\CHKL@withresultfalse
+\newif\ifCHKL@showerrors\CHKL@showerrorstrue
+\newif\ifCHKL@loadhtml\CHKL@loadhtmlfalse
+\def\CHKL@pkg@skipopts{}
+
+% % % Declare Options % % %
+
+\DeclareOption{withresult}{\CHKL@withresulttrue}
+\DeclareOption{withoutresult}{\CHKL@withresultfalse}
+\DeclareOption{skipone}{\def\CHKL@pkg@skipopts{firstline=2}}
+\DeclareOption{skiptwo}{\def\CHKL@pkg@skipopts{firstline=3}}
+\DeclareOption{showproblems}{\CHKL@showproblemstrue}
+\DeclareOption{hideproblems}{\CHKL@showproblemsfalse}
+
+\def\CHKL@codestyle{}
+\def\CHKL@msgstyle{}
+\def\CHKL@errstyle{}
+\define@key{CHKL@pkgkeys}{codestyle}[]{\def\CHKL@codestyle{#1}}
+\define@key{CHKL@pkgkeys}{msgstyle}[]{\def\CHKL@msgstyle{#1}}
+\define@key{CHKL@pkgkeys}{errstyle}[]{\def\CHKL@errstyle{#1}}
+
+\def\CHKL@codelst{}
+\def\CHKL@msglst{}
+\def\CHKL@errlst{}
+\define@key{CHKL@pkgkeys}{codelst}[]{\def\CHKL@codelst{#1}}
+\define@key{CHKL@pkgkeys}{msglst}[]{\def\CHKL@msglst{#1}}
+\define@key{CHKL@pkgkeys}{errlst}[]{\def\CHKL@errlst{#1}}
+
+\def\CHKL@subdir{.}
+\def\CHKL@prefix{chklisting}
+\def\CHKL@prompt{\#}
+\def\CHKL@ext{.ml}
+\define@key{CHKL@pkgkeys}{prompt}[]{\def\CHKL@prompt{#1}}
+\define@key{CHKL@pkgkeys}{subdir}[]{\def\CHKL@subdir{#1}}
+\define@key{CHKL@pkgkeys}{prefix}[]{\def\CHKL@prefix{#1}}
+\define@key{CHKL@pkgkeys}{ext}[]{\def\CHKL@ext{#1}}
+\define@key{CHKL@pkgkeys}{html}[]{\CHKL@loadhtmltrue}
+
+% Unused options
+\define@key{CHKL@pkgkeys}{compiler}[]{}
+\define@key{CHKL@pkgkeys}{compilerflags}[]{}
+\define@key{CHKL@pkgkeys}{lastflags}[]{}
+\define@key{CHKL@pkgkeys}{includecmd}[]{}
+
+% % % Process Options % % %
+
+% Work around the lack of \DeclareOption* in package.hva
+\renewcommand{\@process@option}[1]%
+ {\def\pkg@opt{{\@nostyle\@callprim{\@eatspaces}{#1,}}}%
+ \ifu\csname\@pkg@opt@name{\pkg@opt}\endcsname
+ \setkeys{CHKL@pkgkeys}{#1}
+ \else
+ \csname\@pkg@opt@name{\pkg@opt}\endcsname\fi}%
+
+\ProcessOptions*
+\newcommand{\checklistings}[1]{\ExecuteOptions{#1}}
+
+% % % Macros used in files generated by checklistings.sh % % %
+
+\newif\ifchklisting
+\newcommand{\setchklistingcmd}[1]{%
+ \global\def\chklistingcmd{\emph{\CHKL@prompt{#1}}}}
+
+\newenvironment{ChkListingMsg}{\verblatex}{\endverblatex}
+\newenvironment{ChkListingErr}{\verblatex}{\endverblatex}
+
+\newcommand{\chklistingfile}{\CHKL@prefix\CHKL@ext}
+
+% % % Checklistings user macros % % %
+
+\define@key{CHKL@envkeys}{continue}[]{}
+\define@key{CHKL@envkeys}{include}[]{}
+\define@key{CHKL@envkeys}{label}[]{}
+\define@key{CHKL@envkeys}{showproblems}[]{\CHKL@showproblemstrue}
+\define@key{CHKL@envkeys}{hideproblems}[]{\CHKL@showproblemsfalse}
+\define@key{CHKL@envkeys}{skipnone}[]{\def\CHKL@pkg@skipopts{firstline=1}}
+\define@key{CHKL@envkeys}{skipone}[]{\def\CHKL@pkg@skipopts{firstline=2}}
+\define@key{CHKL@envkeys}{skiptwo}[]{\def\CHKL@pkg@skipopts{firstline=3}}
+\define@key{CHKL@envkeys}{hide}[]{\CHKL@showcodefalse}
+\define@key{CHKL@envkeys}{withresult}[]{\CHKL@withresulttrue}
+\define@key{CHKL@envkeys}{withoutresult}[]{\CHKL@withresultfalse}
+\define@key{CHKL@envkeys}{fail}[]{\CHKL@shouldfailtrue}
+
+% Work around the lack of \edef and \expandafter
+\def\CHKL@lstset#1{\lstset{#1}}
+\def\elstset#1{\@callprim{\CHKL@lstset}{\{#1\}}}
+
+\newcommand{\chklistingmsg}{\bgroup%
+ \setenvclass{lstlisting}{lstlisting chklistingmsg}%
+ \elstset{\CHKL@msgstyle}%
+ \elstset{\CHKL@msglst}%
+ \lstinputlisting{\CHKL@subdir/\CHKL@prefix\CHKL@num.msg}%
+ \egroup}%
+
+\newcommand{\chklistingerr}{\bgroup%
+ \setenvclass{lstlisting}{lstlisting chklistingerr}%
+ \elstset{\CHKL@errstyle}%
+ \elstset{\CHKL@errlst}%
+ \lstinputlisting{\CHKL@subdir/\CHKL@prefix\CHKL@num.err}%
+ \egroup}%
+
+\newenvironment{chklisting}[1][]
+ {%
+ \setenvclass{lstlisting}{lstlisting chklisting}%
+ \stepcounter{chklisting}%
+ \def\@currentlabel{\thechklisting}%
+ \@setkeys{CHKL@envkeys}{#1}%
+ \global\def\CHKL@num{%
+ \ifthenelse{\value{chklisting}<1000}{0}{}%
+ \ifthenelse{\value{chklisting}<100}{0}{}%
+ \ifthenelse{\value{chklisting}<10}{0}{}%
+ \arabic{chklisting}}%
+ \global\def\CHKL@file{\CHKL@subdir/\CHKL@prefix\CHKL@num}%
+ \global\let\chklistingcmd\relax%
+ \ifCHKL@showcode%
+ \bgroup%
+ \ifCHKL@loadhtml%
+ \@open{div}{class="chklisting"}%
+ \rawinput{\CHKL@file{}.html}%
+ \@close{div}%
+ \else%
+ \elstset{\CHKL@pkg@skipopts}%
+ \elstset{\CHKL@codestyle}%
+ \elstset{\CHKL@codelst}%
+ \lstinputlisting{\CHKL@file\CHKL@ext}%
+ \fi%
+ \egroup%
+ \input{\CHKL@file.tex}%
+ \ifCHKL@shouldfail%
+ \ifchklisting%
+ \ifCHKL@showproblems%
+ \begin{divstyle}{checklistingserror}%
+ Unexpected success: \chklistingmsg{}
+ \end{divstyle}%
+ \fi%
+ \else%
+ \ifCHKL@withresult{\chklistingerr{}}\fi%
+ \fi%
+ \else
+ \ifchklisting%
+ \ifCHKL@withresult{\chklistingmsg{}}\fi%
+ \else%
+ \ifCHKL@showproblems%
+ \begin{divstyle}{checklistingserror}%
+ Unexpected failure: \chklistingerr{}
+ \end{divstyle}%
+ \fi%
+ \fi%
+ \fi
+ \fi%
+ \verblatex%
+ }
+ {\endverblatex}%
+\endinput
diff --git a/macros/latex/contrib/checklistings/checklistings.ins b/macros/latex/contrib/checklistings/checklistings.ins
new file mode 100644
index 0000000000..eaf454782d
--- /dev/null
+++ b/macros/latex/contrib/checklistings/checklistings.ins
@@ -0,0 +1,57 @@
+%%
+%% Copyright (C) 2014 by Timothy Bourke <tim@tbrk.org>
+%% and Marc Pouzet <pouzet@ens.fr>
+%%
+%% This file may be distributed and/or modified under the conditions of
+%% the LaTeX Project Public License, either version 1.2 of this license
+%% or (at your option) any later version. The latest version of this
+%% license is in:
+%%
+%% http://www.latex-project.org/lppl.txt
+%%
+%% and version 1.2 or later is part of all distributions of LaTeX version
+%% 1999/12/01 or later.
+%%
+
+\input docstrip.tex
+\keepsilent
+
+\usedir{tex/latex/checklistings}
+
+\preamble
+
+This is a generated file.
+
+Copyright (C) 2015 by Timothy Bourke <tim@tbrk.org>
+ and Marc Pouzet <pouzet@ens.fr>
+
+This file may be distributed and/or modified under the conditions of
+the LaTeX Project Public License, either version 1.2 of this license
+or (at your option) any later version. The latest version of this
+license is in:
+
+ http://www.latex-project.org/lppl.txt
+
+and version 1.2 or later is part of all distributions of LaTeX version
+1999/12/01 or later.
+
+\endpreamble
+
+\generate{\file{checklistings.sty}{\from{checklistings.dtx}{package}}}
+
+\obeyspaces
+\Msg{*************************************************************}
+\Msg{* *}
+\Msg{* To finish the installation you have to move the following *}
+\Msg{* file into a directory searched by TeX: *}
+\Msg{* *}
+\Msg{* checklistings.sty *}
+\Msg{* *}
+\Msg{* To produce the documentation run the file *}
+\Msg{* checklistings.dtx through LaTeX. *}
+\Msg{* *}
+\Msg{* Happy TeXing! *}
+\Msg{* *}
+\Msg{*************************************************************}
+
+\endbatchfile
diff --git a/macros/latex/contrib/checklistings/checklistings.pdf b/macros/latex/contrib/checklistings/checklistings.pdf
new file mode 100644
index 0000000000..49f1aa917c
--- /dev/null
+++ b/macros/latex/contrib/checklistings/checklistings.pdf
Binary files differ
diff --git a/macros/latex/contrib/checklistings/checklistings.sh b/macros/latex/contrib/checklistings/checklistings.sh
new file mode 100755
index 0000000000..4131d9acbc
--- /dev/null
+++ b/macros/latex/contrib/checklistings/checklistings.sh
@@ -0,0 +1,446 @@
+#!/bin/sh
+#
+# checklistings #
+# version 1.0 #
+# #
+# Timothy Bourke <tim@tbrk.org> #
+# Inria #
+# École normale supérieure #
+# #
+# Marc Pouzet <pouzet@ens.fr> #
+# Université Pierre et Marie Curie #
+# École normale supérieure #
+# Inria #
+#
+
+##
+# Configuration
+SCRIPT=$(basename "$0")
+SUFFIX=.chkl
+
+RED=""
+BLUE=""
+BLACK=""
+
+ADJUSTLINETEXT=line
+
+##
+# Command-line
+
+usage () {
+ printf '%s: check source code exported from LaTeX documents.\n' "$SCRIPT"
+ printf 'usage: %s [options] [file ...]\n' "$SCRIPT"
+ printf '\n'
+ printf ' options:\n'
+ printf ' --no-colors log to terminal without control codes\n'
+ printf ' --no-line-adjust do not try to adjust error line numbers\n'
+ printf '\n'
+}
+
+unset INFILES
+while [ -n "$1" ]; do
+ case "$1" in
+ --no-colors)
+ unset RED BLUE BLACK
+ ;;
+ --no-line-adjust)
+ unset ADJUSTLINETEXT
+ ;;
+ --h)
+ usage
+ exit 0
+ ;;
+ --help)
+ usage
+ exit 0
+ ;;
+ -*)
+ printf "%s: unrecognized option '%s'\n" "$SCRIPT" "$1"
+ usage
+ exit 1
+ ;;
+ *${SUFFIX})
+ INFILES="$INFILES $1"
+ ;;
+ *)
+ INFILES="$INFILES $1${SUFFIX}"
+ ;;
+ esac
+ shift
+done
+
+if [ -z "$INFILES" ]; then
+ INFILES=$(ls ./*${SUFFIX})
+fi
+
+##
+# Allocate temporary files
+
+cleanup() {
+ rm -f "${OUTFILE}" "${ERRFILE}"
+}
+OUTFILE=$(mktemp -t "${SCRIPT}.out.XXXXXX") || exit 1
+ERRFILE=$(mktemp -t "${SCRIPT}.err.XXXXXX") || (cleanup; exit 1)
+trap cleanup 1 2 15
+
+##
+# Code
+
+#
+# Given
+# var a variable to store the result
+# name the filename prefix
+# num an id number
+# generate a filename from name and num and store it in var.
+#
+setfilename() {
+ var="$1"
+ name="$2"
+ num="$3"
+ if [ "$num" -lt 10 ]; then
+ eval "$var='${name}000${num}'"
+ elif [ "$num" -lt 100 ]; then
+ eval "$var='${name}00${num}'"
+ elif [ "$num" -lt 1000 ]; then
+ eval "$var='${name}0${num}'"
+ else
+ eval "$var='${name}${num}'"
+ fi
+}
+
+#
+# If the WITHOPEN option is set, create a modified program text (with a
+# different name) whose first lines import dependencies.
+# Args:
+# filename the id of the program text
+# openfilenums its dependencies (id list)
+#
+addopen() {
+ filename="$1"
+ openfilenums="$2"
+ unset of f
+
+ if [ -n "$WITHOPEN" ]; then
+ setfilename f "$PREFIX" "$filename"
+ if [ -f "$SUBDIR$f$EXT" ]; then
+
+ openfiles=""
+ for n in $openfilenums; do
+ setfilename of "$WITHOPEN" "$n"
+ # shellcheck disable=SC2154
+ openfiles="$openfiles ${INCLUDECMD} $of"
+ done
+
+ setfilename of "$WITHOPEN" "$filename"
+ if [ -n "$openfiles" ]; then
+ addedlines=$((addedlines + 1))
+ printf '%s \n' "$openfiles" > "$SUBDIR$of$EXT"
+ cat "$SUBDIR$f$EXT" >> "$SUBDIR$of$EXT"
+ else
+ cat "$SUBDIR$f$EXT" > "$SUBDIR$of$EXT"
+ fi
+ fi
+ fi
+}
+
+# A filename string for sed that ignores the case (BSD sed has no i flag)
+makeicfilename() {
+ IFILENAME=""
+ for l in $(printf "%s" "$FILENAME" | sed -e 's/\(.\)/\1 /g'); do
+ L="$(printf "%s" "$l" | tr "[:lower:]" "[:upper:]")"
+ IFILENAME="${IFILENAME}[$L$l]"
+ done
+}
+
+#
+# Given
+# $ERRFILE path to the file containing error messages
+# $ADJUSTLINETEXT the text preceding the line number (default: "line")
+# if empty or unset, no adjustments are made.
+# $addedlines the amount by which to decrement line numbers
+#
+adjustlinenumbers() {
+ if [ -n "$ADJUSTLINETEXT" ]; then
+ printf '' > "$ERRFILE-adjusted"
+ while read line
+ do
+ linen=$(expr "$line" : ".*$ADJUSTLINETEXT *\([0-9][0-9]*\).*")
+ if [ -n "$linen" ]; then
+ before=$(expr "$line" : "^\(.*$ADJUSTLINETEXT *\)$linen.*$")
+ after=$(expr "$line" : "^.*$ADJUSTLINETEXT *$linen\(.*\)$")
+ newlinen=$((linen - addedlines))
+ printf "%s%s%s\n" "$before" "$newlinen" "$after" \
+ >> "$ERRFILE-adjusted"
+ else
+ printf "%s\n" "$line" >> "$ERRFILE-adjusted"
+ fi
+ done < "$ERRFILE"
+ mv "$ERRFILE-adjusted" "$ERRFILE"
+ fi
+}
+
+#
+# Given
+# num a program (id)
+# openfilenums its dependencies (id list)
+# (Try to) Compile the program and create a corresponding .tex file that
+# summarizes the results for reading back into the source document.
+#
+compile() {
+ num="$1"
+ openfilenums="$2"
+ unset ifile ofile outf of FILENAME
+
+ # Decide whether to use the original program source or the version
+ # augmented to import dependencies.
+ if [ -n "$WITHOPEN" ]; then
+ FILENAME=${WITHOPEN}
+ else
+ FILENAME=${PREFIX}
+ fi
+ makeicfilename
+
+ # Generate the program (ifile) and output (ofile) filenames
+ setfilename ifile "$FILENAME" "$num"
+ # shellcheck disable=SC2154
+ ipath="$SUBDIR$ifile$EXT"
+ setfilename ofile "$PREFIX" "$num"
+ # shellcheck disable=SC2154
+ opath="$SUBDIR$ofile.tex"
+ opath_msg="$SUBDIR$ofile.msg"
+ opath_err="$SUBDIR$ofile.err"
+ opath_html="$SUBDIR$ofile.html"
+
+ # Check that the input file exists
+ if [ -f "$ipath" ]; then
+ printf '> %s%s...%s\n' "$BLUE" "$ofile$EXT" "$BLACK"
+ else
+ printf '%s> %s%s: program source not found.%s\n' \
+ "$RED" "$ofile" "$EXT" "$BLACK"
+ return 1
+ fi
+
+ # Generate a list of dependency filenames to pass to the compiler
+ openfiles=""
+ for n in $openfilenums; do
+ setfilename of "$FILENAME" "$n"
+ openfiles="$openfiles $SUBDIR$of$EXT"
+ done
+
+ # Invoke the compiler
+ # shellcheck disable=SC2086
+ $COMPILER $COMPILERFLAGS $openfiles $LASTFLAGS "$ipath" \
+ >"$OUTFILE" 2>"$ERRFILE"
+ COMPILERSTATUS=$?
+ adjustlinenumbers
+
+ # Start the output tex file with the compilation command as a comment
+ printf '%% %s\n' "$COMPILER $COMPILERFLAGS $openfiles \
+ $LASTFLAGS $ipath ($COMPILERSTATUS)" > "$opath"
+
+ # Signal compilation success (\chklistingtrue) or not (\chklistingfalse)
+ if [ "$COMPILERSTATUS" -eq 0 ]; then
+ printf '\\chklistingtrue\n' >> "$opath"
+ if [ "$SHOULDFAIL" -eq 1 ]; then
+ printf '%s unexpected success (line %s/ page %s)!%s\n' \
+ "$RED" "$LINENUM" "$PAGENUM" "$BLACK" >&2
+ fi
+ else
+ printf '\\chklistingfalse\n' >> "$opath"
+ if [ "$SHOULDFAIL" -eq 0 ]; then
+ printf "%s unexpected failure (line %s / page %s)!%s\n" \
+ "$RED" "$LINENUM" "$PAGENUM" "$BLACK" >&2
+ while read line
+ do
+ printf " | %s\n" "$line"
+ done < "$ERRFILE" >&2
+ fi
+ fi
+
+ # Include a sanitized compilation command (\setchklistingcmd)
+ printf '\setchklistingcmd{%s %s \\chklistingfile}\n' \
+ "${COMPILERNAME}" "${LASTFLAGS}" >> "$opath"
+
+ # Include the compiler's stdout
+ printf "%s\n" '\begin{ChkListingMsg}' >> "$opath"
+ if [ "$(wc -l < "$OUTFILE")" -eq 0 ]; then
+ printf "Failed.\n" >> "$opath"
+ else
+ sed -e "s#$SUBDIR$ifile#$PREFIX#g" \
+ -e "s#$IFILENAME[0-9][0-9][0-9][0-9]\.##g" \
+ "$OUTFILE" > "$opath_msg"
+ cat "$opath_msg" >> "$opath"
+ fi
+ printf "%s\n" '\end{ChkListingMsg}' >> "$opath"
+
+ # Include the compiler's stderr
+ printf "%s\n" '\begin{ChkListingErr}' >> "$opath"
+ if [ "$(wc -l < "$ERRFILE")" -eq 0 ]; then
+ printf "%s\n" "Success." >> "$opath"
+ else
+ sed -e "s#$SUBDIR$ifile#$PREFIX#g" \
+ -e "s#$IFILENAME[0-9][0-9][0-9][0-9]\.##g" \
+ "$ERRFILE" > "$opath_err"
+ cat "$opath_err" >> "$opath"
+ fi
+ printf "%s\n" '\end{ChkListingErr}' >> "$opath"
+
+ # Filter to html if necessary
+ if [ -n "$HTMLFILTER" ]; then
+ # shellcheck disable=SC2086
+ if [ "$HTMLFILTER" = "cat" ]; then
+ printf '<pre>\n' > "$opath_html"
+ $HTMLFILTER "$ipath" >> "$opath_html"
+ printf '</pre>\n' >> "$opath_html"
+ else
+ $HTMLFILTER "$ipath" > "$opath_html"
+ fi
+ fi
+
+ return 0
+}
+
+locked=
+dooption() {
+ opt_name="$1"
+ opt_value="$2"
+
+ case "$opt_name" in
+ lock\ *)
+ opt_name=${opt_name#lock }
+ locked="$locked $opt_name "
+ ;;
+ *)
+ if [ "$(expr "$locked" : ".* $opt_name .*")" -ne 0 ]; then
+ printf \
+ 'info: %s: ignoring locked option ''%s''\n' \
+ "$infile" "$opt_name" >&2
+ return
+ fi
+ ;;
+ esac
+
+ case "$opt_name" in
+ subdir)
+ SUBDIR="$opt_value" ;;
+ prefix)
+ PREFIX="$opt_value" ;;
+ ext)
+ EXT="$opt_value" ;;
+ compiler)
+ COMPILER="${opt_value}"
+ COMPILERNAME="$(basename "${COMPILER}")"
+ ;;
+ compilerflags)
+ COMPILERFLAGS="${opt_value}" ;;
+ lastflags)
+ LASTFLAGS="${opt_value}" ;;
+ includecmd)
+ INCLUDECMD="${opt_value}"
+ if [ -z "$INCLUDECMD" ]; then
+ WITHOPEN=
+ else
+ WITHOPEN=Withopen
+ fi
+ ;;
+ htmlfilter)
+ HTMLFILTER="${opt_value}" ;;
+ esac
+}
+
+subdirs=
+readchkl() {
+ infile=$1
+ unset l existing openfilenums filenum opennums
+
+ # Process each line of the command file
+ while read l; do
+ addedlines=0
+ case $l in
+ [[:digit:]]*:*)
+ # a snippet to be compiled
+ filenum=$(expr "$l" : '\(.*\):.*')
+ openfilenums=$(expr "$l" : '.*:\(.*\)')
+
+ # build up a list of dependencies in opennums
+ opennums=""
+ for n in $openfilenums; do
+ case $n in
+ \[page=*)
+ PAGENUM=$(expr "$n" : '\[page=\(.*\)\]')
+ if [ "$PAGENUM" = "" ]; then
+ PAGENUM="unknown"
+ fi
+ ;;
+ \])
+ # ignore invalid patterns when checklistings.sty
+ # cannot expand \thepage properly (due to a
+ # conflicting package setting) and instead produces
+ # '[page=\thepage ]' which is read as two tokens:
+ # '[page=\thepage' and ']'.
+ ;;
+ \[line=*\])
+ LINENUM=$(expr "$n" : '\[line=\(.*\)\]')
+ ;;
+ \[fail\])
+ SHOULDFAIL=1
+ ;;
+ \[skip=*\])
+ addedlines=$(expr "$n" : '\[skip=\([0-9][0-9]*\)\]')
+ ;;
+ *)
+ if [ "$n" -eq "$n" ] 2>/dev/null; then
+ opennums="$opennums $n"
+ else
+ printf \
+ "%swarning: %s: ignoring unresolved include '%s'%s\n" \
+ "$RED" "$filenum" "$n" "$BLACK" >&2
+ fi
+ ;;
+ esac
+ done
+
+ addopen "$filenum" "$opennums"
+ compile "$filenum" "$opennums"
+ ;;
+
+ *=*)
+ n="$(expr "$l" : '\([^=]*\)=.*')"
+ v="$(expr "$l" : '.*=\(.*\)')"
+ dooption "$n" "$v"
+ if [ "$n" = "subdir" ]; then
+ existing=$(expr "$subdirs" : ".*::${SUBDIR}:\\([^:]*\\):.*")
+ if [ -n "$existing" ]; then
+ printf "%swarning: %s: subdir=%s already used by %s!%s\n" \
+ "$RED" "$infile" "$SUBDIR" "$existing" "$BLACK" >&2
+ fi
+ fi
+ ;;
+
+ *)
+ if [ -n "$l" ]; then
+ printf "%sbad %s: %s%s\n" "$RED" "$infile" "$l" "$BLACK" >&2
+ fi
+ ;;
+ esac
+ unset PAGENUM
+ unset LINENUM
+ SHOULDFAIL=0
+ done < "$1"
+ subdirs="$subdirs::$SUBDIR:$infile:"
+}
+
+# Loop through each checklistings command file
+for f in ${INFILES}; do
+
+ # Add the suffix if necessary (as latex does)
+ case $f in
+ *${SUFFIX}) ;;
+ *) infile="$f$SUFFIX" ;;
+ esac
+
+ readchkl "$f"
+done
+
+cleanup
+
diff --git a/macros/latex/contrib/checklistings/example.html b/macros/latex/contrib/checklistings/example.html
new file mode 100644
index 0000000000..5a78714da5
--- /dev/null
+++ b/macros/latex/contrib/checklistings/example.html
@@ -0,0 +1,74 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
+<meta name="generator" content="hevea 2.16">
+<style type="text/css">
+.li-itemize{margin:1ex 0ex;}
+.li-enumerate{margin:1ex 0ex;}
+.dd-description{margin:0ex 0ex 1ex 4ex;}
+.dt-description{margin:0ex;}
+.toc{list-style:none;}
+.footnotetext{margin:0ex; padding:0ex;}
+div.footnotetext P{margin:0px; text-indent:1em;}
+.thefootnotes{text-align:left;margin:0ex;}
+.dt-thefootnotes{margin:0em;}
+.dd-thefootnotes{margin:0em 0em 0em 2em;}
+.footnoterule{margin:1em auto 1em 0px;width:50%;}
+.caption{padding-left:2ex; padding-right:2ex; margin-left:auto; margin-right:auto}
+.title{margin:2ex auto;text-align:center}
+.titlemain{margin:1ex 2ex 2ex 1ex;}
+.titlerest{margin:0ex 2ex;}
+.center{text-align:center;margin-left:auto;margin-right:auto;}
+.flushleft{text-align:left;margin-left:0ex;margin-right:auto;}
+.flushright{text-align:right;margin-left:auto;margin-right:0ex;}
+div table{margin-left:inherit;margin-right:inherit;margin-bottom:2px;margin-top:2px}
+td table{margin:auto;}
+table{border-collapse:collapse;}
+td{padding:0;}
+.cellpadding0 tr td{padding:0;}
+.cellpadding1 tr td{padding:1px;}
+pre{text-align:left;margin-left:0ex;margin-right:auto;}
+blockquote{margin-left:4ex;margin-right:4ex;text-align:left;}
+td p{margin:0px;}
+.boxed{border:1px solid black}
+.textboxed{border:1px solid black}
+.vbar{border:none;width:2px;background-color:black;}
+.hbar{border:none;height:2px;width:100%;background-color:black;}
+.hfill{border:none;height:1px;width:200%;background-color:black;}
+.vdisplay{border-collapse:separate;border-spacing:2px;width:auto; empty-cells:show; border:2px solid red;}
+.vdcell{white-space:nowrap;padding:0px; border:2px solid green;}
+.display{border-collapse:separate;border-spacing:2px;width:auto; border:none;}
+.dcell{white-space:nowrap;padding:0px; border:none;}
+.dcenter{margin:0ex auto;}
+.vdcenter{border:solid #FF8000 2px; margin:0ex auto;}
+.minipage{text-align:left; margin-left:0em; margin-right:auto;}
+.marginpar{border:solid thin black; width:20%; text-align:left;}
+.marginparleft{float:left; margin-left:0ex; margin-right:1ex;}
+.marginparright{float:right; margin-left:1ex; margin-right:0ex;}
+.theorem{text-align:left;margin:1ex auto 1ex 0ex;}
+.part{margin:2ex auto;text-align:center}
+.lstlisting{font-family:monospace;white-space:pre;margin-right:auto;margin-left:0pt;text-align:left}
+.chklistingerr{font-style: italic; color: red;}
+.chklistingmsg{font-style: italic;}
+</style>
+<title>example</title>
+</head>
+<body >
+<!--HEVEA command line is: /usr/bin/hevea -fix example -->
+<!--CUT STYLE article--><!--CUT DEF section 1 --><p>Two simple declarations:
+</p><div class="lstlisting chklisting"><span style="font-family:sans-serif"><span style="font-weight:bold">let</span></span><span style="font-family:sans-serif"> </span><span style="font-family:sans-serif">x</span><span style="font-family:sans-serif"> = 3</span><span style="font-family:sans-serif">
+</span><span style="font-family:sans-serif"><span style="font-weight:bold">let</span></span><span style="font-family:sans-serif"> </span><span style="font-family:sans-serif">f</span><span style="font-family:sans-serif"> </span><span style="font-family:sans-serif">x</span><span style="font-family:sans-serif"> = </span><span style="font-family:sans-serif">x</span><span style="font-family:sans-serif"> + 1</span></div><p>and, after compilation with <em>ocamlc -i example.ml</em>, their types:
+</p><div class="lstlisting chklistingmsg">val x : int
+val f : int -&gt; int</div><p>Then, building on these definitions:
+</p><div class="lstlisting chklisting"><span style="font-family:sans-serif"><span style="font-weight:bold">let</span></span><span style="font-family:sans-serif"> </span><span style="font-family:sans-serif">y</span><span style="font-family:sans-serif"> = </span><span style="font-family:sans-serif">f</span><span style="font-family:sans-serif"> 3</span></div><div class="lstlisting chklistingmsg">val y : int</div><p>What about compiler error messages?:
+</p><div class="lstlisting chklisting"><span style="font-family:sans-serif"><span style="font-weight:bold">let</span></span><span style="font-family:sans-serif"> </span><span style="font-family:sans-serif">z</span><span style="font-family:sans-serif"> = 3 + </span><span style="font-family:sans-serif"><span style="font-family:sans-serif">"four"</span></span></div><p>They are also detected:
+</p><div class="lstlisting chklistingerr">File "example.ml", line 1, characters 12-18:
+Error: This expression has type string but an expression was expected of type
+ int</div><p>We can continue on from earlier examples:</p><div class="lstlisting chklisting"><span style="font-family:sans-serif"><span style="font-weight:bold">let</span></span><span style="font-family:sans-serif"> </span><span style="font-family:sans-serif">z</span><span style="font-family:sans-serif"> = </span><span style="font-family:sans-serif">f</span><span style="font-family:sans-serif"> </span><span style="font-family:sans-serif">y</span></div><div class="lstlisting chklistingmsg">val z : int</div><!--CUT END -->
+<!--HTMLFOOT-->
+<!--ENDHTML-->
+<!--FOOTER-->
+<hr style="height:2"><blockquote class="quote"><em>This document was translated from L<sup>A</sup>T<sub>E</sub>X by
+</em><a href="http://hevea.inria.fr/index.html"><em>H</em><em><span style="font-size:small"><sup>E</sup></span></em><em>V</em><em><span style="font-size:small"><sup>E</sup></span></em><em>A</em></a><em>.</em></blockquote></body>
+</html>
diff --git a/macros/latex/contrib/checklistings/example.pdf b/macros/latex/contrib/checklistings/example.pdf
new file mode 100644
index 0000000000..37def76c62
--- /dev/null
+++ b/macros/latex/contrib/checklistings/example.pdf
Binary files differ
diff --git a/macros/latex/contrib/checklistings/example.tex b/macros/latex/contrib/checklistings/example.tex
new file mode 100644
index 0000000000..88980097a9
--- /dev/null
+++ b/macros/latex/contrib/checklistings/example.tex
@@ -0,0 +1,56 @@
+\documentclass[a4paper]{article}
+
+\usepackage[T1]{fontenc}
+\usepackage[prompt=,prefix=example]{checklistings}
+\usepackage{listings}
+
+\lstdefinestyle{camlstyle}{%
+ language=caml,
+ basicstyle=\sffamily,
+ keywordstyle=\bf,
+ literate={"}{\textquotedbl}1,
+}
+%BEGIN LATEX
+\checklistings{codelst={style=camlstyle}}
+%END LATEX
+%HEVEA \newstyle{.chklistingerr}{font-style: italic; color: red;}
+%HEVEA \newstyle{.chklistingmsg}{font-style: italic;}
+%HEVEA \checklistings{codelst=\{style=camlstyle\}}
+
+\begin{document}
+
+\noindent
+Two simple declarations:
+\begin{chklisting}
+let x = 3
+let f x = x + 1
+\end{chklisting}
+
+\noindent
+and, after compilation with \chklistingcmd, their types:
+\chklistingmsg{}
+
+\noindent
+Then, building on these definitions:
+\begin{chklisting}[continue,withresult,label=early]
+let y = f 3
+\end{chklisting}
+
+\noindent
+What about compiler error messages?:
+\begin{chklisting}[fail]
+let z = 3 + "four"
+\end{chklisting}
+
+\noindent
+They are also detected:
+\chklistingerr{}
+
+\noindent
+We can continue on from earlier examples:
+
+\begin{chklisting}[withresult,include=early]
+let z = f y
+\end{chklisting}
+
+\end{document}