summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/l3build/l3build.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'macros/latex/contrib/l3build/l3build.dtx')
-rw-r--r--macros/latex/contrib/l3build/l3build.dtx2369
1 files changed, 2369 insertions, 0 deletions
diff --git a/macros/latex/contrib/l3build/l3build.dtx b/macros/latex/contrib/l3build/l3build.dtx
new file mode 100644
index 0000000000..e4dbf51fb6
--- /dev/null
+++ b/macros/latex/contrib/l3build/l3build.dtx
@@ -0,0 +1,2369 @@
+% \iffalse
+%
+% File l3build.dtx (C) Copyright 2014-2019 The LaTeX3 Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% http://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3build bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/l3build
+%
+% for those people who are interested.
+%
+%<*driver>
+\RequirePackage{expl3}
+\documentclass[full]{l3doc}
+\renewcommand\partname{Part}
+\usepackage{multicol,needspace}
+\makeatletter
+\addtolength\columnsep{1em}
+\renewcommand\columnseprule{0.4pt}
+\def\@starttoc#1{%
+ \begin{multicols}{2}
+ \small
+ \makeatletter
+ \@input{\jobname.#1}%
+ \expandafter\newwrite\csname tf@#1\endcsname
+ \immediate\openout \csname tf@#1\endcsname \jobname.#1\relax
+ \@nobreakfalse
+ \end{multicols}}
+\makeatother
+\newenvironment{buildcmd}[1]{%
+ \bigskip\par\noindent\hspace{-\parindent}%
+ \fbox{\ttfamily \textcolor[gray]{0.5}{\$} l3build #1}%
+ \nopagebreak\smallskip\nopagebreak\par\nopagebreak\noindent\ignorespaces
+ }
+ {}
+\makeatletter
+\newcommand\luavar[1]{\@ifundefined{lua_#1}{\ERROR}{\texttt{\@nameuse{lua_#1}}}}
+\newcommand\luavarset[3]{\@namedef{lua_#1}{#2}}
+\newcommand\luavarseparator{}
+\makeatother
+\def\allluavars{
+\luavarset{module}{""}{The name of the module}
+\luavarset{bundle}{""}{The name of the bundle in which the module belongs (where relevant)}
+\luavarset{ctanpkg}{module/bundle}{Name of the CTAN package matching this module}
+\luavarseparator
+\luavarset{modules}{\{\}}{The list of all modules in a bundle (when not auto-detecting)}
+\luavarset{exclmodules}{\{\}}{Directories to be excluded from automatic module detection}
+\luavarseparator
+\luavarset{maindir} {"."} {Top level directory for the module/bundle}
+\luavarset{docfiledir} {"."} {Directory containing documentation files}
+\luavarset{sourcefiledir}{"."} {Directory containing source files}
+\luavarset{supportdir} {maindir .. "/support"} {Directory containing general support files}
+\luavarset{testfiledir}{"./testfiles"} {Directory containing test files}
+\luavarset{testsuppdir}{testfiledir .. "/support"}{Directory containing test-specific support files}
+\luavarseparator
+\luavarset{builddir} {maindir .. "/build"} {Directory for building and testing}
+\luavarset{distribdir}{builddir .. "/distrib"}{Directory for generating distribution structure}
+\luavarset{localdir} {builddir .. "/local"} {Directory for extracted files in \enquote{sandboxed} \TeX{} runs}
+\luavarset{testdir} {builddir .. "/test"} {Directory for running tests}
+\luavarset{typesetdir}{builddir .. "/doc"} {Directory for building documentation}
+\luavarset{unpackdir} {builddir .. "/unpack"} {Directory for unpacking sources}
+\luavarseparator
+\luavarset{ctandir}{distribdir .. "/ctan"}{Directory for organising files for CTAN}
+\luavarset{tdsdir} {distribdir .. "/tds"} {Directory for organised files into TDS structure}
+\luavarset{tdsroot}{"latex"}{Root directory of the TDS structure for the bundle/module to be installed into}
+\luavarseparator
+\luavarset{auxfiles} {\{"*.aux", "*.lof", "*.lot", "*.toc"\}}{Secondary files to be saved as part of running tests}
+\luavarset{bibfiles} {\{"*.bib"\}}{\BibTeX{} database files}
+\luavarset{binaryfiles} {\{"*.pdf", "*.zip"\}}{Files to be added in binary mode to zip files}
+\luavarset{bstfiles} {\{"*.bst"\}}{\BibTeX{} style files}
+\luavarset{checkfiles} {\{~\}}{Extra files unpacked purely for tests}
+\luavarset{checksuppfiles} { }{Files needed for performing regression tests}
+\luavarset{cleanfiles} {\{"*.log", "*.pdf", "*.zip"\}}{Files to delete when cleaning}
+\luavarset{demofiles} {\{\}}{Files which show how to use a module}
+\luavarset{docfiles} {\{\}}{Files which are part of the documentation but should not be typeset}
+\luavarset{dynamicfiles} {\{ \}}{Secondary files to cleared before each test is run}
+\luavarset{excludefiles} {\{"*\string~"\}}{Files to ignore entirely (default for Emacs backup files)}
+\luavarset{installfiles} {\{"*.sty","*.cls"\}}{Files to install to the \texttt{tex} area of the \texttt{texmf} tree}
+\luavarset{makeindexfiles} {\{"*.ist"\}}{MakeIndex files to be included in a TDS-style zip}
+\luavarset{scriptfiles} {\{ \}}{Files to install to the \texttt{scripts} area of the \texttt{texmf} tree}
+\luavarset{scriptmanfiles} {\{ \}}{Files to install to the \texttt{doc/man} area of the \texttt{texmf} tree}
+\luavarset{sourcefiles} {\{"*.dtx", "*.ins", "*-????-??-??.sty"\}}{Files to copy for unpacking}
+\luavarset{tagfiles} {\{"*.dtx"\}}{Files for automatic tagging}
+\luavarset{textfiles} {\{"*.md", "*.txt"\}}{Plain text files to send to CTAN as-is}
+\luavarset{typesetdemofiles} {\{\}}{Files to typeset before the documentation for inclusion in main documentation files}
+\luavarset{typesetfiles} {\{"*.dtx"\}}{Files to typeset for documentation}
+\luavarset{typesetsuppfiles} {\{\}}{Files needed to support typesetting when \enquote{sandboxed}}
+\luavarset{typesetsourcefiles}{\{\}}{Files to copy to unpacking when typesetting}
+\luavarset{unpackfiles} {\{"*.ins"\}}{Files to run to perform unpacking}
+\luavarset{unpacksuppfiles} {\{\}}{Files needed to support unpacking when \enquote{sandboxed}}
+\luavarseparator
+\luavarset{includetests}{\{"*"\}}{Test names to include when checking}
+\luavarset{excludetests}{\{\}} {Test names to exclude when checking}
+\luavarseparator
+\luavarset{checkdeps} {\{\}}{List of dependencies for running checks}
+\luavarset{typesetdeps}{\{\}}{List of dependencies for typesetting docs}
+\luavarset{unpackdeps} {\{\}}{List of dependencies for unpacking}
+\luavarseparator
+\luavarset{checkengines}{\{"pdftex", "xetex", "luatex"\}}{Engines to check with \texttt{check} by default}
+\luavarset{stdengine} {"pdftex"}{Engine to generate \texttt{.tlg} file from}
+\luavarset{checkformat} {"latex"} {Format to use for tests}
+\luavarset{specialformats}{\meta{table}} {Non-standard engine/format combinations}
+\luavarseparator
+\luavarset{checkconfigs}{\{\}}{Configurations to use for tests}
+\luavarseparator
+\luavarset{typesetexe} {"pdflatex"} {Executable for compiling \texttt{doc(s)}}
+\luavarset{unpackexe} {"tex"} {Executable for running \texttt{unpack}}
+\luavarset{zipexe} {"zip"} {Executable for creating archive with \texttt{ctan}}
+\luavarset{biberexe} {"biber"} {Biber executable}
+\luavarset{bibtexexe} {"bibtex8"} {\BibTeX{} executable}
+\luavarset{makeindexexe} {"makeindex"}{MakeIndex executable}
+\luavarset{curlexe} {"curl"} {Curl executable for \texttt{upload}}
+\luavarseparator
+\luavarset{checkopts} {"-interaction=nonstopmode"}{Options passed to engine when running checks}
+\luavarset{typesetopts}{"-interaction=nonstopmode"}{Options passed to engine when typesetting}
+\luavarset{unpackopts} {""} {Options passed to engine when unpacking}
+\luavarset{zipopts} {"-v -r -X"} {Options passed to zip program}
+\luavarset{biberopts} {""} {Biber options}
+\luavarset{bibtexopts} {"-W"} {\BibTeX{} options}
+\luavarset{makeindexopts}{""} {MakeIndex options}
+\luavarseparator
+\luavarset{checksearch} {true}{Switch to search the system \texttt{texmf} for during checking}
+\luavarset{typesetsearch}{true}{Switch to search the system \texttt{texmf} for during typesetting}
+\luavarset{unpacksearch} {true}{Switch to search the system \texttt{texmf} for during unpacking}
+\luavarseparator
+\luavarset{glossarystyle}{"gglo.ist"}{MakeIndex style file for glossary/changes creation}
+\luavarset{indexstyle} {"gind.ist"}{MakeIndex style for index creation}
+\luavarseparator
+\luavarset{forcecheckepoch}{"true"} {Force epoch when running tests}
+\luavarset{forcedocepoch} {"false"} {Force epoch when typesetting}
+\luavarseparator
+\luavarset{asciiengines}{\{"pdftex"\}}{Engines which should log as pure ASCII}
+\luavarset{checkruns} {1} {Number of runs to complete for a test before comparing the log}
+\luavarset{ctanreadme}{"README.md"} {Name of the file to send to CTAN as \texttt{README.\meta{ext}}}
+\luavarset{ctanzip}{ctanpkg ... "-ctan"}{Name of the zip file (without extension) created for upload to CTAN}
+\luavarset{epoch} {1463734800} {Epoch (Unix date) to set for test runs}
+\luavarset{flatten} {true} {Switch to flatten any source structure when sending to CTAN}
+\luavarset{maxprintline}{79} {Length of line to use in log files}
+\luavarset{packtdszip} {false} {Switch to build a TDS-style zip file for CTAN}
+\luavarset{typesetcmds} {""} {Instructions to be passed to \TeX{} when doing typesetting}
+\luavarset{typesetruns}{3} {Number of cycles of typesetting to carry out}
+\luavarset{recordstatus}{false} {Switch to include error level from test runs in \texttt{.tlg} files}
+\luavarset{manifestfile} {"MANIFEST.md"} {Filename to use for the manifest file}
+\luavarseparator
+\luavarset{tdslocations}{\{ \}}{Map for non-standard file installations}
+\luavarseparator
+\luavarset{uploadconfig} {\meta{table}} {Metadata to describe the package for CTAN (see Table~\ref{tab:upload-setup})}
+\luavarset{uploadconfig.pkg}{ctanpkg}{Name of the CTAN package}
+\luavarseparator
+\luavarset{bakext}{".bak"}{Extension of backup files}
+\luavarset{dviext}{".dvi"}{Extension of DVI files}
+\luavarset{lvtext}{".lvt"}{Extension of log-based test files}
+\luavarset{tlgext}{".tlg"}{Extension of test file output}
+\luavarset{tpfext}{".tpf"}{Extension of PDF-based test output}
+\luavarset{lveext}{".lve"}{Extension of auto-generating test file output}
+\luavarset{logext}{".log"}{Extension of checking output, before processing it into a \texttt{.tlg}}
+\luavarset{pvtext}{".pvt"}{Extension of PDF-based test files}
+\luavarset{pdfext}{".pdf"}{Extension of PDF file for checking and saving}
+\luavarset{psext} {".ps"} {Extension of PostScript files}
+}
+\allluavars
+
+
+\newcommand\luavartypeset{%
+ \begingroup
+ \frenchspacing
+ \renewcommand\luavarset[3]{
+ \texttt{##1} & \texttt{##2} & ##3 \\
+ }
+ \renewcommand\luavarseparator{\midrule}
+ \setlength\LTleft{-0.21\linewidth}
+ \begin{longtable}{@{}%
+ >{\small}
+ p{0.18\linewidth}
+ @{\hspace{0.03\linewidth}}
+ >{\footnotesize\hangindent=1em}
+ p{0.34\linewidth}
+ @{\hspace{0.03\linewidth}}
+ >{\small\raggedright\arraybackslash}
+ p{0.63\linewidth}
+ @{}}
+ \toprule
+ Variable & Default & Description \\
+ \midrule\endhead
+ \allluavars
+ \bottomrule
+ \end{longtable}
+ \endgroup
+}
+\newcommand\code{\texttt}
+\newcommand\var{\texttt}
+\usepackage[procnames]{listings}
+\lstset{
+ basicstyle=\ttfamily\small,
+ numbers=left,
+ numberstyle={\tiny\color[gray]{0.4}},
+}
+\usepackage{shortvrb}
+\usepackage{enumitem}
+\usepackage{longtable}
+\MakeShortVerb\|
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3build} package\\ Checking and building packages^^A
+% }
+%
+% \author{^^A
+% The \LaTeX3 Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2019-08-24}
+%
+% \maketitle
+% \tableofcontents
+%
+% \begin{documentation}
+%
+% \section{The \pkg{l3build} system}
+%
+% \subsection{Introduction}
+%
+% The \pkg{l3build} system is a Lua script for building \TeX{} packages, with particular emphasis on regression testing.
+% It is written in cross-platform Lua code, so can be used by any modern \TeX{} distribution with the |texlua| interpreter.
+% Wrapper functions/binaries are distributed in the standard \TeX{} distributions so that the script can be called using
+% \texttt{l3build} on the command line; run without arguments it prints a brief synopsis of its usage.
+%
+% The \pkg{l3build} system is designed for packages written in any \TeX\ dialect; its defaults are set up for \LaTeX\ packages written in the DocStrip style. (Caveat: minimal testing has yet been performed for non-\LaTeX{} packages.)
+%
+% Test files are written as standalone \TeX{} documents using the |regression-test.tex| setup file; documentation on writing these tests is discussed in Section~\ref{sec:writing-tests}.
+%
+% Each package will define its own |build.lua| configuration file which both sets variables (such as the name of the package) and may also provide custom functions.
+%
+% \pagebreak[2]
+% A standard package layout might look something like the following:
+% \begin{Verbatim}[fontsize=\small]
+% abc/
+% abc.dtx
+% abc.ins
+% build.lua
+% README.md
+% support/
+% testfiles/
+% \end{Verbatim}
+% Most of this should look fairly self-explanatory.
+% The top level |support/| directory (optional) would contain any necessary files for compiling documentation, running regression tests, and so on.
+%
+% The \pkg{l3build} system is also capable of building and checking \emph{bundles} of packages.
+% To avoid confusion, we refer to either a standalone package or a package within a bundle as a \emph{module}.
+%
+% For example, within the \LaTeX3 project we have the \textsf{l3packages} bundle which contains the \textsf{xparse}, \textsf{xtemplate}, etc., modules.
+% These are all built and distributed as one bundle for installation, distribution \emph{via} CTAN and so forth.
+%
+% Each module in a bundle will have its own build script, and a bundle build script brings them all together.
+% A standard bundle layout would contain the following structure.
+% \begin{Verbatim}
+% mybundle/
+% build.lua
+% support/
+% yyy/ zoo/
+% build.lua build.lua
+% README.md README.md
+% testfiles/ testfiles/
+% yyy.dtx zoo.dtx
+% yyy.ins zoo.ins
+% \end{Verbatim}
+% All modules within a bundle must use the same build script name.
+%
+% In a small number of cases, the name used by CTAN for a module or bundle is
+% different from that used in the installation tree. For example, the \LaTeXe{}
+% kernel is called \pkg{latex-base} by CTAN but is located inside
+% \texttt{\meta{texmf}/tex/latex/base}. This can be handled by using
+% \var{ctanpkg} for the name required by CTAN to override the standard
+% value.
+%
+% The |testfiles/| folder is local to each module, and its layout consists of a series of regression tests with their outputs.
+% \begin{Verbatim}
+% testfiles/
+% test1.lvt
+% test1.tlg
+% ...
+% support/
+% my-test.cls
+% \end{Verbatim}
+% Again, the |support/| directory contains any files necessary to run some or all of these tests.
+%
+% When the build system runs, it creates a directory |build/| for various unpacking, compilation, and testing purposes.
+% For a module, this build folder can be in the main directory of the package itself, but for a bundle it should be common for the bundle itself and for all modules within that bundle.
+% A |build/| folder can be safety deleted; all material within is re-generated for each command of the \pkg{l3build} system.
+%
+% \subsection{Main build commands}
+%
+% In the working directory of a bundle or module, \pkg{l3build} is run by executing
+% \begin{center}
+% \texttt{l3build \meta{command} [\meta{option(s)}]}
+% \end{center}
+% where \texttt{\meta{command}} can be one of the following:
+% \begin{itemize}[noitemsep]\ttfamily
+% \item check
+% \item check \meta{name(s)}
+% \item clean
+% \item ctan
+% \item doc
+% \item doc \meta{name(s)}
+% \item install
+% \item manifest
+% \item save \meta{name(s)}
+% \item tag \meta{tag}
+% \item uninstall
+% \item unpack
+% \item upload
+% \item upload \meta{tag}
+% \end{itemize}
+% These commands are described below.
+%
+% As well as these commands, the system recognises the options
+% \begin{itemize}
+% \item |--config| (|-c|) Configuration(s) to use for testing
+% \item |--date| Date to use when tagging data
+% \item |--debug| Runs the target in debug mode (not supported by all targets)
+% \item |--dirty| Skip cleaning up of the test area
+% \item |--dry-run| Runs the \texttt{install} target but does not copy
+% any files: simply lists those that would be installed
+% \item |--email| Sets the email address for CTAN upload
+% \item |--engine| (|-e|) Sets the engine to use for testing
+% \item |--epoch| Sets the epoch for typesetting and testing
+% \item |--file| (|-F|) Take the upload announcement from the given file
+% \item |--first| Name of the first test to run
+% \item |--force| (|-f|) Force checks to run even if sanity
+% checks fail, \emph{e.g.}~when |--engine| is not given in
+% \luavar{checkengines}
+% \item |--full| Instructs the \texttt{install} target to include the
+% \texttt{doc} and \texttt{source} trees
+% \item |--halt-on-error| (|-H|) Specifies that checks
+% should stop as soon as possible, rather than running all requested
+% tests; the difference file is printed in the terminal directly in the case of failure
+% \item |--last| Name of the last test to run
+% \item |--message| (|-m|) Text for upload announcement
+% \item |--quiet| (|-q|) Suppresses output from unpacking
+% \item |--rerun| Run tests without unpacking/set up
+% \item |--show-log-on-error| To be used in addition to \texttt{--halt-on-error} and results
+% in the full \texttt{.log} file of a failed test to be shown on the console
+% \item |--shuffle| Shuffle the order in which tests run
+% \item |--texmfhome| Sets the location of the user tree for installing
+% \end{itemize}
+%
+% \begin{buildcmd}{check}
+% The |check| command runs the entire test suite.
+% This involves iterating through each \texttt{.lvt} file in the test directory (specified by the \var{testfiledir} variable), compiling each test in a \enquote{sandbox} (a directory specified by \var{testdir}), and comparing the output against each matching predefined \texttt{.tlg} file.
+%
+% If changes to the package or the typesetting environment have affected the results, the check for that file fails.
+% A |diff| of the expected to actual output should then be inspected to determine the cause of the error; it is located in the \var{testdir} directory (default \luavar{testdir}).
+%
+% On Windows, the |diff| program is not available and so |fc| is used instead
+% (generating an |.fc| file). Setting the environmental variables |diffexe|
+% and |diffext| can be used to adjust the choice of comparison made: the standard
+% values are
+% \begin{itemize}
+% \item[Windows] |diffext = fc|, |diffexe = fc /n|
+% \item[*nix] |diffext = diff|, |diffexe = diff -c --strip-trailing-cr|
+% \end{itemize}
+%
+% The following files are moved into the \enquote{sandbox} for the |check| process:
+% \begin{itemize}
+% \item all \var{installfiles} after unpacking;
+% \item all \var{checkfiles} after unpacking;
+% \item any files in the directory \var{testsuppdir};
+% \item any files that match \var{checksuppfiles} in the \var{supportdir}.
+% \end{itemize}
+% This range of possibilities allow sensible defaults but significant flexibility for defining your own test setups.
+%
+% Checking can be performed with any or all of the `engines' \texttt{pdftex}, \texttt{xetex}, and \texttt{luatex}.
+% By default, each test is executed with all three, being compared against the \texttt{.tlg} file produced from the \var{pdftex} engine (these defaults are controlled by the |checkengines| and |stdengine| variable respectively).
+% The format used for tests can be altered by setting \var{checkformat}: the default setting \texttt{latex} means that tests are run using \emph{e.g.}~\texttt{pdflatex}, whereas setting to \texttt{plain} will run tests using \emph{e.g.}~\texttt{pdftex}.
+% (Currently, this should be one of \texttt{latex} or \texttt{plain}.)
+% To perform the check, the engine typesets each test up to \var{checkruns} times.
+% More detail on this in the documentation on |save|.
+% Options passed to the binary are defined in the variable \var{checkopts}.
+%
+% By default, |texmf| trees are searched for input files when checking. This can be disabled by setting \var{checksearch} to |false|: isolation provides confidence that the tests cannot accidentally be running with incorrect files installed in the main distribution or |hometexmf|.
+% \end{buildcmd}
+%
+%
+% \begin{buildcmd}{check \meta{name(s)}}
+% Checks only the test \texttt{\meta{name(s)}.lvt}.
+% All engines specified by \var{checkengines} are tested unless the command
+% line option |--engine| (or |-e|) has been given to limit
+% testing to a single engine. Normally testing is preceded by unpacking
+% source files and copying the result plus any additional support to the
+% test directory: this may be skipped using the |-s| option.
+% \end{buildcmd}
+%
+% \begin{buildcmd}{clean}
+% This command removes all temporary files used for package bundling and regression testing.
+% In the standard layout, these are all files within the directories defined by \var{localdir}, \var{testdir}, \var{typesetdir} and \var{unpackdir}, as well as all files defined in the \var{cleanfiles} variable in the same directory as the script.
+% The defaults are |.pdf| files from typesetting (|doc|) and |.zip| files from bundling (|ctan|).
+% \end{buildcmd}
+%
+%
+% \begin{buildcmd}{ctan}
+% Creates an archive of the package and its documentation, suitable for uploading to CTAN.
+% The archive is compiled in \var{distribdir}, and if the results are successful the resultant |.zip| file is moved into the same directory as the build script.
+% If \var{packtdszip} is set true then the building process includes a |.tds.zip| file containing the `\TeX\ Directory Structure' layout of the package or bundle.
+% The archive therefore may contain two `views' of the package:
+% \begin{Verbatim}
+% abc.zip/
+% abc/
+% abc.dtx
+% abc.ins
+% abc.pdf
+% README.md
+% abc.tds.zip/
+% doc/latex/abc/
+% abc.pdf
+% README.md
+% source/latex/abc/
+% abc.dtx
+% abc.ins
+% tex/latex/abc/
+% abc.sty
+% \end{Verbatim}
+% The files copied into the archive are controlled by a number of variables.
+% The `root' of the TDS structure is defined by \var{tdsroot}, which is \luavar{tdsroot} by default. Plain users would redefine this to |"plain"| (or perhaps |"generic"|), for example.
+% The build process for a |.tds.zip| file currently assumes a `standard'
+% structure in which all extracted files should be placed inside the |tex|
+% tree in a single directory, as shown above. If the module includes any
+% \BibTeX{} or MakeIndex styles these will be placed in the appropriate
+% subtrees.
+%
+% \pagebreak[2]
+% The |doc| tree is constructed from:
+% \begin{itemize}
+% \item all files matched by \var{demofiles},
+% \item all files matched by \var{docfiles},
+% \item all files matched by \var{typesetfiles} with their extension replaced with |.pdf|,
+% \item all files matched by \var{textfiles},
+% \item all files matched by \var{bibfiles}.
+% \end{itemize}
+% The |source| tree is constructed from all files matched by \var{typesetfiles} and \var{sourcefiles}.
+% The |tex| tree from all files matched by \var{installfiles}.
+%
+% The special case \var{ctanreadme} is used to allow renaming of a local
+% |foo.xyz| file to |README.xyz|. The local |foo.xyz| should be listed in
+% \var{textfiles}, and will be renamed as part of constructing the CTAN
+% structure. The file extension will be unchanged by this process.
+%
+% Files that should always be excluded from the archive are matched against the \var{excludefiles} variable; by default this is \luavar{excludefiles}, which match Emacs' autosave files.
+%
+% Binary files should be specified with the \var{binaryfiles} variable (default \luavar{binaryfiles}); these are added to the zip archive without normalising line endings (text files are automatically converted to Unix-style line endings).
+%
+% To create the archive, by default the binary \var{zipexe} is used (\luavar{zipexe}) with options \var{zipopts} (|-v -r -X|). The intermediate build directories \var{ctandir} and \var{tdsdir} are used to construct the archive.
+% \end{buildcmd}
+%
+%
+% \begin{buildcmd}{doc}
+% Compiles documentation files in the \var{typesetdir} directory.
+% In the absence of one or more file names, all documentation is typeset;
+% a file list may be given at the command line for selective typesetting.
+% If the compilation is successful the |.pdf| is moved back into the main directory.
+%
+% The documentation compilation is performed with the \var{typesetexe} binary (default \texttt{pdflatex}), with options \var{typesetopts}.
+% Additional \TeX{} material defined in \var{typesetcmds} is passed to the document (e.g., for writing |\\PassOptionsToClass{l3doc}{letterpaper}|, and so on---note that backslashes need to be escaped in Lua strings).
+%
+% Files that match |typesetsuppfiles| in the |support| directory (|supportdir|) are copied into the |build/local| directory (|localdir|) for the typesetting compilation process.
+% Additional dependencies listed in the \var{typesetdeps} variable (empty by default) will also be installed.
+%
+% Source files specified in \var{sourcefiles} and \var{typesetsourcefiles}
+% are unpacked before the typesetting takes place. (In most cases
+% \var{typesetsourcefiles} will be empty, but may be used where there are
+% files to unpack \emph{only} for typesetting.)
+%
+% If \var{typesetsearch} is \code{true} (default), standard \texttt{texmf} search trees are used in the typesetting compilation. If set to false, \emph{all} necessary files for compilation must be included in the |build/local| sandbox.
+%
+% \end{buildcmd}
+%
+% \begin{buildcmd}{doc \meta{name(s)}}
+% Typesets only the files with the \meta{name(s)} given, which should be the
+% basename without any extension.
+% \end{buildcmd}
+%
+% \begin{buildcmd}{install}
+% Copies all package files (defined by \var{installfiles}) into the user's home \texttt{texmf} tree in the form of the \TeX\ Directory Structure.
+% The location of the user tree can be adjusted using the |--texmfhome| swtich:
+% the standard setting is the location set as |TEXMFHOME|.
+% \end{buildcmd}
+%
+% \begin{buildcmd}{save \meta{name(s)}}
+% This command runs through the same execution as |check| for a specific test(s) \texttt{\meta{name(s)}.lvt}.
+% This command saves the output of the test to a |.tlg| file.
+% This file is then used in all subsequent checks against the \texttt{\meta{name}.lvt} test.
+%
+% If the |--engine| (or |-e|) is specified (one of |pdftex|, |xetex|, or |luatex|), the saved output is stored in \texttt{\meta{name}.\meta{engine}.tlg}. This is necessary if running the test through a different engine produces a different output.
+% A normalisation process is performed when checking to avoid common differences such as register allocation; full details are listed in section~\ref{sec:norm}.
+%
+% If the \var{recordstatus} variable is set \var{true}, additional information
+% will be added to the \texttt{.tlg} to record the \enquote{exit status} of the
+% typesetting compilation of the \texttt{.lvt} file. If the typesetting compilation
+% completed without throwing an error (due to \TeX\ programming errors, for example),
+% the \enquote{exit status} is zero, else non-zero.
+% \end{buildcmd}
+%
+% \begin{buildcmd}{manifest}
+% Generates a `manifest' file which lists the files of the package as known to \pkg{l3build}.
+% The filename of this file (by default \luavar{manifestfile}) can be set with the variable \var{manifestfile}.
+%
+% The intended purpose of this manifest file is to include it within a package as metadata.
+% This would allow, say, for the copyright statement for the package to refer to the
+% manifest file rather than requiring the author to manually keep a file list up-to-date
+% in multiple locations. The manifest file can be structured and documented with a degree
+% of flexibility. Additional information is described in Section~\ref{sec:manifest}.
+%
+% In order for \texttt{manifest} to detect derived and typeset files, it should be run
+% \emph{after} running \texttt{unpack} and \texttt{doc}. If \texttt{manifest}
+% is run after also running \texttt{ctan} it will include the files included
+% in the CTAN and TDS directories as well.
+%
+% Presently, this means that if you wish to include an up-to-date manifest file
+% as part of a \texttt{ctan} release, you must run
+% \texttt{ctan} / \texttt{manifest} / \texttt{ctan}.
+% Improvements to this process are planned for the future.
+% \end{buildcmd}
+%
+% \begin{buildcmd}{tag}
+% Modifies the contents of files specified by |tagfiles| using a search pattern
+% to automatically update the `release tag' (or package version) and date.
+% The tag is given as the command line option and the date using
+% |--date| (|-d|). If not given, the date will default to the current date in
+% ISO format (YYYY-MM-DD). If no option is given (i.e., no tag specified) the tag
+% is passed through as |nil| to allow setting the tag programmatically.
+%
+% The standard setup has no search pattern defined for this target and so no action
+% will be taken \emph{unless} tag substitution is set up by defining the Lua function
+% |update_tag()|. See Section~\ref{sec:tagging} for full details on this feature.
+% \end{buildcmd}
+%
+% \begin{buildcmd}{unpack}
+% This is an internal target that is normally not needed on user level.
+% It unpacks all files into the directory defined by \var{unpackdir}. This occurs before other build commands such as |doc|, |check|, etc.
+%
+% The unpacking process is performed by executing the \var{unpackexe} (default \texttt{tex}) with options \var{unpackopts} on all files defined by the \var{unpackfiles} variable; by default, all files that match \luavar{unpackfiles}.
+%
+% If additional support files are required for the unpacking process, these can be enumerated in the \var{unpacksuppfiles} variable.
+% Dependencies for unpacking are defined with \var{unpackdeps}.
+%
+% By default this process allows files to be accessed in all standard |texmf| trees; this can be disabled by setting \var{unpacksearch} to |false|.
+% \end{buildcmd}
+%
+% \begin{buildcmd}{upload}
+% This target uses \texttt{curl} to upload the package zip file (created using \texttt{ctan}) to CTAN.
+% To control the metadata used to upload the package, the \texttt{uploadconfig} table should be populated with a number of fields.
+% These are documented in Table~\ref{tab:upload-setup}.
+% Missing required fields will result in an interactive prompt for manual entry.
+%
+% See Section~\ref{sec:upload} for full details on this feature.
+% \end{buildcmd}
+%
+% \subsection{The \texttt{build.lua} file}
+%
+% The \texttt{build.lua} file used to control \pkg{l3build} is a simple Lua file
+% which is read during execution. In the current release of \pkg{l3build},
+% \texttt{build.lua} is read automatically and can access all of the global
+% functions provided by the script. Thus it may contain a simple list of
+% variable settings \emph{or} additionally custom code to change the build
+% process. A number of example scripts are given in Section~\ref{sec:examples}.
+%
+% \subsection{Example build scripts}
+% \label{sec:examples}
+%
+% An example of a standalone build script for a package that uses self-contained |.dtx| files is shown in Figure~\ref{fig:breqn}.
+% Here, the |module| only is defined, and since it doesn't use |.ins| files so the variable \var{unpackfiles} is redefined to run |tex| on the |.dtx| files instead to generate the necessary |.sty| files.
+% There are some PDFs in the repository that shouldn't be part of a CTAN submission, so they're explicitly excluded, and here unpacking is done `quietly' to minimise console output when building the package.
+%
+% \begin{figure}[!b]
+% \begin{lstlisting}[frame=single,language={[5.2]Lua},gobble = 6]
+% -- Build configuration for breqn
+%
+% module = "breqn"
+%
+% unpackfiles = {"*.dtx"}
+% excludefiles = {"*/breqn-abbr-test.pdf",
+% "*/eqbreaks.pdf"}
+% unpackopts = "-interaction=batchmode"
+% \end{lstlisting}
+% \caption{The build configuration for the \pkg{breqn} package.}
+% \label{fig:breqn}
+% \end{figure}
+%
+% An example of a bundle build script for \pkg{l3packages} is shown in Figure~\ref{fig:bundle}.
+% Note for \LaTeX3 we use a common file to set all build variables in one place, and the path to the |l3build.lua| script is hard-coded so we always use our own most recent version of the script.
+% An example of an accompanying module build script is shown in Figure~\ref{fig:module}.
+%
+% \begin{figure}[p]
+% \begin{lstlisting}[frame=single,language={[5.2]Lua},gobble = 6]
+% -- Build script for LaTeX3 "l3packages" files
+%
+% -- Identify the bundle: there is no module as this is the "driver"
+% bundle = "l3packages"
+%
+% -- Location of main directory: use Unix-style path separators
+% maindir = ".."
+% \end{lstlisting}
+% \caption{The build script for the \pkg{l3packages} bundle.}
+% \label{fig:bundle}
+% \end{figure}
+%
+% \begin{figure}[p]
+% \begin{lstlisting}[frame=single,language={[5.2]Lua},gobble = 6]
+% -- Build script for LaTeX3 "xparse" files
+%
+% -- Identify the bundle and module:
+% bundle = "l3packages"
+% module = "xparse"
+%
+% -- Location of main directory: use Unix-style path separators
+% -- Should match that defined by the bundle.
+% maindir = "../.."
+% \end{lstlisting}
+% \caption{The build script for the \pkg{xparse} module.}
+% \label{fig:module}
+% \end{figure}
+%
+% \subsection{Backwards compatibility}
+%
+% Earlier releases of \pkg{l3build} required that the last line of
+% \texttt{build.lua} ran the main script, \emph{i.e.}~ that \texttt{build.lua}
+% was what the user called rather than \texttt{l3build.lua}. To allow scripts
+% to support both forms \emph{for the transition}, a simple test may be
+% included as showing in Figure~\ref{fig:build-compat}.
+% \begin{figure}
+% \begin{lstlisting}[frame=single,language={[5.2]Lua},gobble = 6]
+% if not release_date then
+% dofile(kpse.lookup("l3build.lua"))
+% end
+% \end{lstlisting}
+% \caption{Final lines for a \texttt{build.lua} script usable with both older
+% and newer releases of \pkg{l3build}.}
+% \label{fig:build-compat}
+% \end{figure}
+%
+% Note that in time support for loading \pkg{l3build} by calling the
+% \texttt{build.lua} script \emph{may} be removed: the recommended approach for
+% new scripts is to run \texttt{l3build}.
+%
+% \subsection{Variables}
+%
+% This section lists all variables defined in the |l3build.lua| script that are available for customisation.
+%
+% \luavartypeset
+%
+% \subsection{Interaction between tests}
+%
+% Tests are run in a single directory, so whilst they are may be isolated from
+% the system \TeX{} tree they do share files. This may be significant if
+% installation-type files are generated during a test, for example by a
+% |filecontents| environment in \LaTeX{}. Typically, you should set up your
+% tests such that they do not use the same names for such files: this may lead
+% to variable outcomes depending on the order in which tests are run.
+%
+% \subsection{Selective running of tests}
+%
+% The variables |includetests| and |excludetests| may be used to select which
+% tests are run: these variables take test \emph{names} not full file names.
+% The list of tests in |excludetests| overrides any matches in |includetests|,
+% meaning that tests can be disabled selectively. It also makes it possible
+% to disable test on for example a platform basis: the Lua core variable
+% |os.type| may be used to set |excludetests| only on some systems.
+%
+% \subsection{Multiple sets of tests}
+%
+% In most cases, a single set of tests will be appropriate for the module, with
+% a common set of configuration settings applying. However, there are
+% situations where you may need entirely independent sets of tests which have
+% different setting values, for example using different formats or where the
+% entire set will be engine-dependent. To support this, \pkg{l3build} offers
+% the possibility of using multiple configurations for tests. This is supported
+% using the \var{checkconfigs} table. This is used to list the names of each
+% configuration (|.lua| file) which will be used to run tests.
+%
+% For example, for the core \LaTeXe{} tests the main test files are contained
+% in a directory |testfiles|. To test font loading for \XeTeX{} and \LuaTeX{}
+% there are a second set of tests in |testfiles-TU| which use the short
+% |build-TU.lua| file shown in Figure~\ref{fig:configs}. To run both sets of
+% tests, the main |build.lua| file contains the setting
+% |checkconfigs = {"build", "config-TU"}|. This will cause \pkg{l3build} to run
+% first using no additional settings (\emph{i.e.}~reading the normal
+% |build.lua| file alone), then running \emph{also} loading the settings from
+% |config-TU.lua|.
+% \begin{figure}
+% \begin{lstlisting}[frame=single,language={[5.2]Lua},gobble = 6]
+% -- Special config for these tests
+% checksearch = true
+% checkengines = {"xetex","luatex"}
+% testfiledir = "testfiles-TU"
+% \end{lstlisting}
+% \caption{Example of using additional (or overriding) settings for configuring tests in a different subdirectory.}
+% \label{fig:configs}
+% \end{figure}
+%
+% To allow selection of a one or more configurations, and to allow saving of
+% |.tlg| files in non-standard configurations, the |--config| (|-c|) option may
+% be used. This works in the same way as |--engine|: it takes a comma list of
+% configurations to apply, overriding \var{checkconfigs}.
+%
+% \subsection{Dependencies}
+%
+% If you have multiple packages that are developed separately but still interact in some way, it's often desirable to integrate them when performing regression tests.
+% For \LaTeX3, for example, when we make changes to \pkg{l3kernel} it's important to check that the tests for \pkg{l3packages} still run correctly, so it's necessary to include the \pkg{l3kernel} files in the build process for \pkg{l3packages}.
+%
+% In other words, \pkg{l3packages} is \emph{dependent} on \pkg{l3kernel}, and this is specified in \pkg{l3build} by setting appropriately the variables \texttt{checkdeps}, \texttt{typesetdeps}, and \texttt{unpackdeps}.
+% The relevant parts of the \LaTeX3 repository is structured as the following.
+% \Needspace{3\baselineskip}
+% \begin{Verbatim}
+% l3/
+% l3kernel/
+% build.lua
+% expl3.dtx
+% expl3.ins
+% ...
+% testfiles/
+% l3packages/
+% build.lua
+% xparse/
+% build.lua
+% testfiles/
+% xparse.dtx
+% xparse.ins
+% support/
+% \end{Verbatim}
+% For \LaTeX3 build files, |maindir| is defined as top level folder |l3|, so all support files are located here, and the build directories will be created there.
+% To set \pkg{l3kernel} as a dependency of \pkg{l3package}, within |l3packages/xparse/build.lua| the equivalent of the following is set:
+% \begin{Verbatim}
+% maindir = "../.."
+% checkdeps = {maindir .. "/l3kernel"}
+% \end{Verbatim}
+% This ensures that the \pkg{l3kernel} code is included in all processes involved in unpacking and checking and so on.
+% The name of the script file in the dependency is set with the |scriptname| variable; by default these are |"build.lua"|.
+%
+% \subsection{Non-standard source layouts}
+%
+% A variety of source layouts are supported. In general, a \enquote{flat}
+% layout with all source files \enquote{here} is most convenient. However,
+% \pkg{l3build} supports placement of both code and documentation source
+% files in other locations using the \var{sourcefiledir} and \var{docfiledir}
+% variables. For pre-built trees, the glob syntax \texttt{**/*.\meta{ext}} may
+% be useful in these cases: this enables recursive searching in the appropriate
+% tree locations. With the standard settings, this structure will be removed
+% when creating a CTAN release: the variable \var{flatten} may be
+% used to control this behavior.
+%
+% A series of example layouts and matching |build.lua| files are available from
+% \url{https://github.com/latex3/l3build/tree/master/examples}.
+%
+% \subsection{Non-standard formats/binaries}
+%
+% The standard approach used by \pkg{l3build} is to use a combination
+% of \var{engine} and \var{checkformat} to generate the \emph{binary} and
+% \emph{format} combination used for tests. For example, when |pdftex| is
+% the \var{engine} and |latex| is the \var{checkformat}, the system call
+% used is
+% \begin{verbatim}
+% pdftex --fmt=pdflatex
+% \end{verbatim}
+% \emph{i.e.}~the binary names is the same as the \var{engine}, and the format
+% is a simple substitution of the \var{checkformat} into \var{engine}, replacing
+% |tex|.
+%
+% For more complex set ups, \var{specialformats} should be used. This is a
+% table with one entry per \var{checkformat}. Each entry is itself a table,
+% and these contain a list of engines and settings for |binary|, |format|
+% and |options|. For example, for Con\TeX{}t and appropriate set up is
+% \begin{verbatim}
+% specialformats.context = {
+% luatex = {binary = "context", format = ""},
+% pdftex = {binary = "texexec", format = ""},
+% xetex = {binary = "texexec", format = "", options = "--xetex"}
+% }
+% \end{verbatim}
+%
+% \subsection{Output normalisation}
+% \label{sec:norm}
+%
+% To allow test files to be used between different systems (\emph{e.g.}~when
+% multiple developers are involved in a project), the log files are normalised
+% before comparison during checking. This removes some system-dependent
+% data but also some variations due to different engines. This normalisation
+% consists of two parts: removing (\enquote{ignoring}) some lines and modifying
+% others to give consistent test. Currently, the following types of line are
+% ignored:
+% \begin{itemize}
+% \item Lines before the \cs{START}, after the \cs{END} and within
+% \cs{OMIT}/\cs{TIMO} blocks
+% \item Entirely blank lines, including those consisting only of spaces.
+% \item Lines related to loading |.fd| files (from \texttt{(\meta{name}.fd}
+% to the matching \texttt{)}).
+% \item Lines starting \cs{openin} or \cs{openout}.
+% \end{itemize}
+% Modifications made in lines are:
+% \begin{itemize}
+% \item Removal spaces at the start of lines.
+% \item Removal of |./| at start of file names.
+% \item Standardisation of the list of units known to \TeX{} (\pdfTeX{}
+% and \LuaTeX{} add a small number of additional units which are not
+% known to \TeX90 or \XeTeX{}, (u)p\TeX{} adds some additional non-standard
+% ones)
+% \item Standardisation of \verb*|\csname\endcsname | to |\csname\endcsname|
+% (the former is formally correct, but the latter was produced for many
+% years due to a \TeX{} bug).
+% \item Conversion of \texttt{on line \meta{number}} to \texttt{on line ...}
+% to allow flexibility in changes to test files.
+% \item Conversion of file dates to \texttt{....-..-..}, and any version
+% numbers on the same lines to \texttt{v...}.
+% \item Conversion of register numbers in assignment lines
+% \texttt{\cs{\meta{register}}=\cs{\meta{type}}\meta{number}} to
+% \texttt{\cs{\meta{type}}\meta{...}}
+% \item Conversion of box numbers in |\show| lines
+% \texttt{>~\cs{box}\meta{number}=} to \texttt{>~\cs{box}...=}
+% \item Removal of some (u)p\TeX{} data where it is equivalent to
+% \pdfTeX{} (|yoko direction|, |\displace 0.0|)
+% \end{itemize}
+%
+% \LuaTeX{} makes several additional changes to the log file. As normalising
+% these may not be desirable in all cases, they are handled separately.
+% When creating \LuaTeX{}-specific test files (either with \LuaTeX{} as
+% the standard engine or saving a \LuaTeX{}-specific |.tlg| file) no further
+% normalisation is undertaken. On the other hand, for cross-engine comparison
+% the following normalisation is applied:
+% \begin{itemize}
+% \item Removal of additional (unused) |\discretionary| points.
+% \item Normalisation of some |\discretionary| data to a \TeX{}90 form.
+% \item Removal of |U+...| notation for missing characters.
+% \item Removal of |display| for display math boxes
+% (included by \TeX90/\pdfTeX{}/\XeTeX).
+% \item Removal of Omega-like |direction TLT| information.
+% \item Removal of additional whatsit containing local paragraph information
+% (|\localinterlinepenalty|, \emph{etc.}).
+% \item Rounding of glue set to four decimal places (glue set may be
+% slightly different in \LuaTeX{} compared to other engines).
+% \item Conversion of low chars ($0$ to $31$) to |^^| notation.
+% \end{itemize}
+%
+% When making comparisons between 8-bit and Unicode engines it is useful to
+% format the top half of the 8-bit range such that it appears in the log as
+% |^^|\texttt{\meta{char}} (the exact nature of the 8-bit output is otherwise
+% dependent on the active code page). This may be controlled using the
+% |asciiengines| option. Any engines named here will use a |.tcx| file to
+% produce only ASCII chars in the log output, whilst for other engines
+% normalisation is carried out from UTF-8 to ASCII. If the option is set to
+% an empty table the latter process is skipped: suitable for cases where only
+% Unicode engines are in use.
+%
+% \section{Writing test files}
+% \label{sec:writing-tests}
+%
+% Test files are written in a \TeX{} dialect using the support file |regression-test.tex|, which should be |\input| at the very beginning of each test.
+% Additional customisations to this driver can be included in a local |regression-test.cfg| file, which will be loaded automatically if found.
+%
+% The macros loaded by |regression-test.tex| set up the test system and provide a number of commands to aid the production of a structured test suite.
+% The basis of the test suite is to output material into the |.log| file, from which a normalised test output (|.tlg|) file is produced by the build command |save|.
+% A number of commands are provided for this; they are all written in uppercase to help avoid possible conflicts with other package commands.
+%
+% \subsection{Metadata and structural commands}
+%
+% Any commands that write content to the |.log| file that should be ignored can be surrounded by |\OMIT| \dots\ |\TIMO|.
+% At the appropriate location in the document where the |.log| comparisons should start (say, after |\begin{document}|), the test suite must contain the |\START| macro.
+% The test should then include \cs{AUTHOR}\marg{authors details} in case a test file fails in the future and needs to be re-analysed.
+%
+% Some additional diagnostic information can then be included as metadata for the conditions of the test.
+% The desired format can be indicated with \cs{FORMAT}\marg{format name}, and any packages or classes loaded can be indicated with
+%
+% \noindent\hspace*{2\parindent} \cs{CLASS}\oarg{options}\marg{class name, version}\par
+% \noindent\hspace*{2\parindent} \cs{PACKAGE}\oarg{options}\marg{package name, version}
+%
+% \noindent These do not provide information that is useful for automated checking; after all, packages change their version numbers frequently.
+% Rather, including this information in a test indicates the conditions under which the test was definitely known to pass at a certain time in the past.
+%
+% The |\END| command signals the end of the test (but read on).
+% Some additional diagnostic information is printed at this time to debug if the test did not complete `properly' in terms of mismatched brace groups or \cs{if}\dots\cs{fi} groups.
+%
+% In a \LaTeX{} document, |\end{document}| will implicitly call |\END| at the very end of the compilation process.
+% If |\END| is used directly (replacing |\end{document}| in the test), the compilation will halt almost immediately, and various tasks that |\end{document}| usually performs will not occur (such as potentially writing to the various |.toc| files, and so on). This can be an advantage if there is additional material printed to the log file in this stage that you wish to ignore, but it is a disadvantage if the test relies on various auxiliary data for a subsequent typesetting run.
+% (See the \var{checkruns} variable for how these tests would be test up.)
+%
+% \subsection{Commands to help write tests}
+%
+% A simple command \cs{CHECKCOMMAND}\cs{\meta{macro}} is provided to check whether a particular \cs{\meta{macro}} is defined, undefined, or equivalent to \cs{relax}.
+% This is useful to flag either that internal macros are remaining local to their definitions, or that defined commands definitely are defined, or even as a reminder that commands you intend to define in a future package need to be tested once they appear.
+%
+% \cs{TYPE} is used to write material to the \texttt{.log} file, like \LaTeX's \cs{typeout}, but it allows `long' input.
+% The following commands are defined to use \cs{TYPE} to output strings to the \texttt{.log} file.
+% \begin{itemize}
+% \item
+% \cs{SEPARATOR} inserts a long line of \texttt{=} symbols to break up the log output.
+% \item
+% \cs{NEWLINE} inserts a linebreak into the log file.
+% \item
+% \cs{TRUE}, \cs{FALSE}, \cs{YES}, \cs{NO} output those strings to the log file.
+% \item
+% \cs{ERROR} is \emph{not} defined but is commonly used to indicate a code path that should never be reached.
+% \item
+% The \cs{TEST}\marg{title}\marg{contents} command surrounds its \meta{contents} with some \cs{SEPARATOR}s and a \meta{title}.
+% \item
+% \cs{TESTEXP} surrounds its contents with \cs{TYPE} and formatting to match \cs{TEST}; this can be used as a shorthand to test expandable commands.
+% \item
+% TODO: would a \cs{TESTFEXP} command (based on \cs{romannumeral} expansion) be useful as well?
+% \item
+% \cs{BEGINTEST}\marg{title} \dots \cs{ENDTEST} is an environment form of
+% \cs{TEST}, allowing verbatim material, \emph{etc.} to appear.
+% \end{itemize}
+% An example of some of these commands is shown following.
+% \begin{Verbatim}
+% \TEST{bool_set,~lazy~evaluation}
+% {
+% \bool_set:Nn \l_tmpa_bool
+% {
+% \int_compare_p:nNn 1=1
+% && \bool_lazy_any_p:n
+% {
+% { \int_compare_p:nNn 2=3 }
+% { \int_compare_p:nNn 4=4 }
+% { \int_compare_p:nNn 1=\ERROR } % is skipped
+% }
+% && \int_compare_p:nNn 2=2
+% }
+% \bool_if:NTF \l_tmpa_bool \TRUE \FALSE
+% }
+% \end{Verbatim}
+% This test will produce the following in the output.
+% \begin{Verbatim}
+% ==========================================
+% TEST 8: bool_set, lazy evaluation
+% ==========================================
+% TRUE
+% ==========================================
+% \end{Verbatim}
+% (Only if it's the eighth test in the file of course, and assuming \pkg{expl3}
+% coding conventions are active.)
+%
+% \subsection{Showing box content}
+%
+% The commands introduced above are only useful for checking algorithmic or logical correctness.
+% Many packages should be tested based on their typeset output instead; \TeX{} provides a mechanism for this by printing the contents of a box to the log file.
+% The |regression-test.tex| driver file sets up the relevant \TeX{} parameters to produce as much output as possible when showing box output.
+%
+% A plain \TeX{} example of showing box content follows.
+% \begin{Verbatim}[frame=single,fontsize=\small]
+% \input regression-test.tex\relax
+% \START
+% \setbox0=\hbox{\rm hello \it world $a=b+c$}
+% \showbox0
+% \END
+% \end{Verbatim}
+% This produces the output shown in Figure~\ref{fig:box-log} (left side).
+% It is clear that if the definitions used to typeset the material in the box changes, the log output will differ and the test will no longer pass.
+%
+% The equivalent test in \LaTeXe{} using \pkg{expl3} is similar.
+% \begin{Verbatim}[frame=single,fontsize=\small]
+% \input{regression-test.tex}
+% \documentclass{article}
+% \usepackage{expl3}
+% \START
+% \ExplSyntaxOn
+% \box_new:N \l_tmp_box
+% \hbox_set:Nn \l_tmp_box {hello~ \emph{world}~ $a=b+c$}
+% \box_show:N \l_tmp_box
+% \ExplSyntaxOff
+% \END
+% \end{Verbatim}
+% The output from this test is shown in Figure~\ref{fig:box-log} (right side).
+% There is marginal difference (mostly related to font selection and different logging settings in \LaTeX) between the plain and \pkg{expl3} versions.
+%
+% When examples are not self-contained enough to be typeset into boxes, it is possible to ask \TeX{} to output the entire contents of a page.
+% Insert \cs{showoutput} for \LaTeX{} or set \cs{tracingoutput} positive for plain \TeX{}; ensure that the test ends with \cs{newpage} or equivalent because \TeX{} waits until the entire page is finished before outputting it.
+%
+% TODO: should we add something like \cs{TRACEPAGES} to be format-agnostic here? Should this perhaps even be active by default?
+%
+% \begin{figure}
+% \hspace*{-3cm}
+% \begin{BVerbatim}[fontsize=\small]
+% > \box0=
+% \hbox(6.94444+0.83333)x90.56589
+% .\tenrm h
+% .\tenrm e
+% .\tenrm l
+% .\tenrm l
+% .\tenrm o
+% .\glue 3.33333 plus 1.66666 minus 1.11111
+% .\tenit w
+% .\tenit o
+% .\tenit r
+% .\tenit l
+% .\tenit d
+%
+% .\glue 3.57774 plus 1.53333 minus 1.0222
+% .\mathon
+% .\teni a
+% .\glue(\thickmuskip) 2.77771 plus 2.77771
+% .\tenrm =
+% .\glue(\thickmuskip) 2.77771 plus 2.77771
+% .\teni b
+% .\glue(\medmuskip) 2.22217 plus 1.11108 minus 2.22217
+% .\tenrm +
+% .\glue(\medmuskip) 2.22217 plus 1.11108 minus 2.22217
+% .\teni c
+% .\mathoff
+%
+% ! OK.
+% l.9 \showbox0
+%
+%
+% \end{BVerbatim}
+% \qquad
+% \begin{BVerbatim}[fontsize=\small]
+% > \box71=
+% \hbox(6.94444+0.83333)x91.35481
+% .\OT1/cmr/m/n/10 h
+% .\OT1/cmr/m/n/10 e
+% .\OT1/cmr/m/n/10 l
+% .\OT1/cmr/m/n/10 l
+% .\OT1/cmr/m/n/10 o
+% .\glue 3.33333 plus 1.66666 minus 1.11111
+% .\OT1/cmr/m/it/10 w
+% .\OT1/cmr/m/it/10 o
+% .\OT1/cmr/m/it/10 r
+% .\OT1/cmr/m/it/10 l
+% .\OT1/cmr/m/it/10 d
+% .\kern 1.03334
+% .\glue 3.33333 plus 1.66666 minus 1.11111
+% .\mathon
+% .\OML/cmm/m/it/10 a
+% .\glue(\thickmuskip) 2.77771 plus 2.77771
+% .\OT1/cmr/m/n/10 =
+% .\glue(\thickmuskip) 2.77771 plus 2.77771
+% .\OML/cmm/m/it/10 b
+% .\glue(\medmuskip) 2.22217 plus 1.11108 minus 2.22217
+% .\OT1/cmr/m/n/10 +
+% .\glue(\medmuskip) 2.22217 plus 1.11108 minus 2.22217
+% .\OML/cmm/m/it/10 c
+% .\mathoff
+%
+% ! OK.
+% <argument> \l_tmp_box
+%
+% l.12 \box_show:N \l_tmp_box
+% \end{BVerbatim}
+% \caption{Output from displaying the contents of a simple box to the log file, using plain \TeX{} (left) and \pkg{expl3} (right). Some blank lines have been added to the plain \TeX{} version to help with the comparison.}
+% \label{fig:box-log}
+% \end{figure}
+%
+% \subsection{Testing entire pages}
+%
+% There may be occasions where creating entire test pages is necessary
+% to observe the test output required. That is best achieved by applying
+% \cs{showoutput} and forcing a complete page to be produced, for example
+% \begin{Verbatim}[frame=single,fontsize=\small]
+% \input{regression-test.tex}
+% \documentclass{article}
+% \usepackage{expl3}
+% \START
+% \showoutput
+% % Test content here
+% \vfil\break
+% \END
+% \end{Verbatim}
+%
+% \subsection{Additional test tasks}
+%
+% A standard test will run the file \texttt{\meta{name}.lvt} using one
+% or more engines, but will not carry out any additional processing. For
+% some tests, for example bibliography generation, it may be desirable to
+% call one or more tools in addition to the engine. This can be arranged
+% by defining |runtest_tasks|, a function taking one argument, the name
+% of the current test (this is equivalent to \TeX{}'s \cs{jobname},
+% \emph{i.e.}~it lacks an extension). The function |runtest_tasks|
+% is is into a call to the system to run the engine. As such, it
+% should take return a string with the appropriate command(s)
+% and option(s). If more than one task is required, these should be separated
+% by use of |os_concat|, a string variable defined by \pkg{l3build} as the
+% correct concatenation marker for the system. An example of |runtest_tasks|
+% suitable for calling Biber is shown in Listing~\ref{fig:test-tasks}.
+% \begin{figure}
+% \begin{lstlisting}[frame=single,language={[5.2]Lua},gobble = 6]
+% function runtest_tasks(name)
+% return "biber " .. name
+% end
+% \end{lstlisting}
+% \caption{Example \texttt{runtest_tasks} function.}
+% \label{fig:test-tasks}
+% \end{figure}
+%
+% \subsection{Epoch setting}
+%
+% To produce predictable output when using dates, the test system offers the
+% ability to set the epoch to a known value. The \luavar{epoch} variable may
+% be given as a raw value (a simple integer) or as a date in ISO format.
+% The two flags \luavar{forcecheckepoch} and \luavar{forcedocepoch} then
+% determine whether this is applied in testing and typesetting, respectively.
+%
+% The epoch may also be given as a command line option, |-E|, which again
+% takes either a date or raw epoch. When given, this will automatically
+% activate forcing of the epoch in both testing and typesetting.
+%
+% \subsection{Settings in \texttt{texmf.cnf}}
+%
+% To allow application of non-standard \TeX{} trees or similar non-standard
+% settings, \pkg{l3build} enables searching for a \texttt{texmf.cnf} file
+% by setting the envirnmental variable \texttt{TEXMFCNF}. This might
+% for example be used with a file containing
+% \begin{verbatim}
+% TEXMFAUXTREES = ../../texmf,
+% \end{verbatim}
+% for adding a local tree within the development repository (assuming the
+% typical \pkg{l3build} layout).
+%
+% \section{Alternative test formats}
+%
+% \subsection{Generating test files with \pkg{DocStrip}}
+%
+% It is possible to pack tests inside source files. Tests generated during the
+% unpacking process will be available to the \texttt{check} and \texttt{save}
+% commands as if they were stored in the \texttt{testfiledir}. Any explicit
+% test files inside \texttt{testfiledir} take priority over generated ones
+% with the same names.
+%
+% \subsection{Specifying expectations}
+%
+% Regression tests check whether changes introduced in the code modify the test
+% output. Especially while developing a complex package there is not yet a
+% baseline to save a test goal with. It might then be easier to formulate the
+% expected effects and outputs of tests directly. To achieve this, you may
+% create an \texttt{.lve} instead of a \texttt{.tlg}
+% file.\footnote{Mnemonic: \texttt{lv\textbf{t}}: \textbf{t}est,
+% \texttt{lv\textbf{e}}: \textbf{e}xpectation} It is processed exactly like
+% the \texttt{.lvt} to generate the expected outcome. The test fails when both
+% differ.
+%
+% Combining both features enables contrasting the test with its expected
+% outcome in a compact format. Listing \ref{fig:expect-dtx} exemplary tests
+% \TeX{}s counters. Listing \ref{fig:expect-ins} shows the relevant part of an
+% \texttt{.ins} file to generate it.
+%
+% \begin{figure}
+% \begin{lstlisting}[frame=single,language={TeX},gobble = 6]
+% \input regression-test.tex\relax
+% \START
+% \TEST{counter-math}{
+% %<*test>
+% \OMIT
+% \newcounter{numbers}
+% \setcounter{numbers}{2}
+% \addtocounter{numbers}{2}
+% \stepcounter{numbers}
+% \TIMO
+% \typeout{\arabic{numbers}}
+% %</test>
+% %<expect> \typeout{5}
+% }
+% \END
+% \end{lstlisting}
+% \caption{Test and expectation can be specified side-by-side in a single
+% \texttt{.dtx} file.}
+% \label{fig:expect-dtx}
+% \end{figure}
+%
+%\begin{figure}
+% \begin{lstlisting}[frame=single,language={TeX},gobble = 6]
+% \generate{\file{\jobname.lvt}{\from{\jobname.dtx}{test}}
+% \file{\jobname.lve}{\from{\jobname.dtx}{expect}}}
+% \end{lstlisting}
+% \caption{Test and expectation are generated from a \texttt{.dtx} file of
+% the same name.}
+% \label{fig:expect-ins}
+% \end{figure}
+%
+% \subsection{PDF-based tests}
+%
+% In most cases, testing is best handled by using the text-based methods
+% outlined above. However, there are cases where the detail of output structure
+% is important. This can only be fully tested by comparing PDF structure.
+% To support this, \pkg{l3build} can be instructed to build and compare
+% PDF files by setting up tests in \texttt{.pvt} files. The following
+% normalization takes place:
+% \begin{itemize}
+% \item Replacement of binary streams by the marker |[BINARY STREAM]|
+% \item Removal of blank lines
+% \end{itemize}
+%
+% After this normalization takes place, the file can not usually be rendered
+% properly. To check if the build system has produced a correct PDF, the
+% pre-normalization PDF can be found in the \texttt{build} folder.
+%
+% To allow platform-independence, PDF-based tests must use only Type~1 or
+% OpenType fonts: Type3 fonts are system-dependent. PDF files are
+% engine-specific, thus one |.tpf| file should be stored per engine to be
+% tested.
+%
+%
+% \section{Release-focussed features}
+%
+% \subsection{Installation structure}
+%
+% With the standard settings, \pkg{l3build} will install files within
+% the \TeX{} directory structure (TDS) as follows
+% \begin{itemize}
+% \item \var{installfiles} within a \texttt{\meta{bundle}/\meta{module}}
+% (or \texttt{\meta{module}}) directory inside \texttt{tex/\meta{format}}
+% \item \var{sourcefiles} within a \texttt{\meta{bundle}/\meta{module}}
+% (or \texttt{\meta{module}}) directory inside \texttt{source/\meta{format}}
+% \item Typeset PDFs within a \texttt{\meta{bundle}/\meta{module}}
+% (or \texttt{\meta{module}}) directory inside \texttt{doc/\meta{format}}
+% \item \var{bstfiles} within a \texttt{\meta{bundle}/\meta{module}}
+% (or \texttt{\meta{module}}) directory inside \texttt{bibtex/bst}
+% \item \var{bibfiles} within a \texttt{\meta{bundle}/\meta{module}}
+% (or \texttt{\meta{module}}) directory inside \texttt{bibtex/bib}
+% \item \var{makeindexfiles} within a \texttt{\meta{bundle}/\meta{module}}
+% (or \texttt{\meta{module}}) directory inside \texttt{makeindex}
+% \end{itemize}
+%
+% For more complex set ups, this can be customised using the
+% \luavar{tdslocations} table. Each entry there should be a glob specifying the
+% TDS position of a file or files. Any files not specified in the table
+% will use the standard locations above. For example, to place some files
+% in the generic tree, some in the plain \TeX{} tree and some in the \LaTeX{}
+% tree, one might use the set up shown in Figure~\ref{fig:tds}.
+% \begin{figure}
+% \begin{lstlisting}[frame=single,language={[5.2]Lua},gobble = 6]
+% tdslocations =
+% {
+% "tex/generic/mypkg/*.generic.tex" ,
+% "tex/plain/mypkg/*.plain.tex" ,
+% "tex/latex/mypkg/*.latex.tex"
+% }
+% \end{lstlisting}
+% \caption{Example \texttt{tdslocations} table.}
+% \label{fig:tds}
+% \end{figure}
+%
+% The table is read in order, and thus specific file names should come before
+% potential wild-card matches.
+%
+% \subsection{Automatic tagging}
+% \label{sec:tagging}
+%
+% The |tag| target can automatically edit
+% source files to modify date and release tag. As standard, no automatic
+% replacement takes place, but setting up a |update_tag()| function
+% will allow this to happen. This function takes four input arguments:
+% \begin{enumerate}[nosep]
+% \item file name
+% \item full content of the file
+% \item tag name
+% \item tag date
+% \end{enumerate}
+% The |update_tag()| function should return the (modified) contents
+% for writing to disk.
+% For example, the function used by |l3build| itself is
+% shown in Figure~\ref{fig:update-tag}.
+%
+% \begin{figure}
+% \begin{lstlisting}[frame=single,language={[5.2]Lua},gobble = 6]
+% -- Detail how to set the version automatically
+% function update_tag(file,content,tagname,tagdate)
+% if string.match(file, "%.dtx$") then
+% return string.gsub(content,
+% "\n%% \\date{Released %d%d%d%d/%d%d/%d%d}\n",
+% "\n%% \\date{Released " .. tagname .. "}\n")
+% elseif string.match(file, "%.md$") then
+% return string.gsub(content,
+% "\nRelease %d%d%d%d/%d%d/%d%d\n",
+% "\nRelease " .. tagname .. "\n")
+% elseif string.match(file, "%.lua$") then
+% return string.gsub(content,
+% '\nrelease_date = "%d%d%d%d/%d%d/%d%d"\n',
+% '\nrelease_date = "' .. tagname .. '"\n')
+% end
+% return contents
+% end
+% \end{lstlisting}
+% \caption{Example \texttt{update_tag} function.}
+% \label{fig:update-tag}
+% \end{figure}
+%
+% To allow more complex tasks to take place, a hook |tag_hook()| is also
+% available. It will receive the tag name and date as arguments, and
+% may be used to carry out arbitrary tasks after the main tagging process.
+% For example, this can be used to set a version control tag for an entire repository.
+%
+%
+% \subsection{Typesetting documentation}
+%
+% As part of the overall build process, \pkg{l3build} will create PDF
+% documentation as described earlier. The standard build process for PDFs
+% will attempt to run Biber, \BibTeX{} and MakeIndex as appropriate
+% (the exact binaries used are defined by \luavar{biberexe}, \luavar{bibtexexe}
+% and \luavar{makeindexexe}). However, there is no attempt to create an entire
+% PDF creation system in the style of \texttt{latexmk} or similar.
+%
+% For package authors who have more complex requirements than those covered
+% by the standard set up, the Lua script offers the possibility for
+% customisation. The Lua function \texttt{typeset} may be defined before
+% reading \texttt{l3build.lua} and should take one argument, the name of
+% the file to be typeset. Within this function, the auxiliary Lua
+% functions \texttt{biber}, \texttt{bibtex}, \texttt{makeindex} and
+% \texttt{tex} can be used, along with custom code, to define a PDF
+% typesetting pathway. The functions \texttt{biber} and \texttt{bibtex}
+% take a single argument: the name of the file to work with \emph{minus}
+% any extension. The \texttt{tex} takes as an argument the full name
+% of the file. The most complex function \texttt{makeindex} requires the
+% name, input extension, output extension, log extension and style name.
+% For example, Figure~\ref{fig:PDF} shows a simple script which might
+% apply to a case where multiple \BibTeX{} runs are needed (perhaps where
+% citations can appear within other references).
+%
+% Where there are complex requirements for pre-compiled demonstration
+% files, the hook |typeset_demo_tasks()| is available: it runs after
+% copying files to the typesetting location but before the main typesetting
+% run. This may be used for example to script a very large number of
+% demonstrations using a single source (see the \pkg{beamer} package
+% for an example of this).
+%
+% \begin{figure}[!b]
+% \begin{lstlisting}[frame=single,language={[5.2]Lua},gobble = 6]
+% #!/usr/bin/env texlua
+%
+% -- Build script with custom PDF route
+%
+% module = "mymodule"
+%
+% function typeset(file)
+% local name = jobname(file)
+% local errorlevel = tex (file)
+% if errorlevel == 0 then
+% -- Return a non-zero errorlevel if anything goes wrong
+% errorlevel =(
+% bibtex(name) +
+% tex(file) +
+% bibtex(name) +
+% tex(file) +
+% tex(file)
+% )
+% end
+% return errorlevel
+% end
+% \end{lstlisting}
+% \caption{A customised PDF creation script.}
+% \label{fig:PDF}
+% \end{figure}
+%
+%
+% \subsection{Automated upload to CTAN}
+% \label{sec:upload}
+%
+% The CTAN upload process is backed by an API, which \pkg{l3build} can use
+% to send zip files for release. Along with the file, a variety of metadata
+% must be specified about the package, including the version, license, and so on.
+% A description of this metadata is outlined in Table~\ref{tab:upload-setup},
+% and a simple example of an extract from a \texttt{build.lua} file using this is shown
+% in Figure~\ref{fig:uploadconfig}.
+%
+% Note that the \texttt{upload} target will \emph{not} execute the
+% \texttt{ctan} target first.
+%
+% This upload facility assumes availablity of |curl| on your
+% system. In the case of Windows, the system curl will not be
+% available if you are using a 32 bit \TeX\ implementation. Curl
+% executables are available for a variety of operating systems from
+% \url{https://curl.haxx.se/download.html}.
+%
+% \paragraph{Announcement text}
+% It can be convenient not to include the announcement text within the |build.lua| file
+% directly. The command line argument |--message| (|-m|) allows the announcement to be
+% included as part of the |l3build| arguments, and |--file| (|-F|) reads the announcement
+% from a specified file. The \texttt{build.lua} file may also specify that this text is to
+% be taken from the file specified by
+% |uploadconfig.announcement_file|, this allows the release-specific announcement to be
+% specified outside the main |build.lua| file. If
+% |uploadconfig.announcement_file| is |nil| or specifies a file that
+% can not be read, and no announcement is provided by the
+% |announcement| field or commandline arguments, |l3build| will
+% interactively prompt for text (which may be empty).
+%
+% Note that if the announcement text is empty a `silent update'
+% is performed; this should usually be performed for minor bug or documentation fixes only.
+%
+% \paragraph{Note text}
+% This optional field is for passing notes to the CTAN maintainers. As
+% for announcements, the text may be set in |uploadconfig.note| or
+% perhaps more usefully, if |uploadconfig.note_file| is the filename of a
+% readable file the file text is used as the note.
+%
+% \paragraph{Uploader details}
+% The CTAN team use the uploader email address as a form of low-security sanity
+% check that the upload is coming from a reputable source. Therefore, it is advisable not
+% to store this information within a public |build.lua| file. It can be set on the command
+% line with the |--email| option to \texttt{l3build}; alternatively, a private
+% configuration file could be used to add this information at upload time.
+%
+% \paragraph{The \texttt{update} field}
+% In most scenarios the |update| field does not need to be explicitly set. By default
+% \pkg{l3build} assumes that the package being uploaded already exists on CTAN
+% (|update=true|). If it does not, this is caught in the validation process before
+% uploading and automatically corrected. If you set |update| explicitly this will be passed
+% directly to CTAN in all circumstances, leading to errors if you attempt to update a
+% non-existing package or if you attempt to upload a new package with the same name as a
+% pre-existing one.
+%
+% \paragraph{The \texttt{curl} options file}
+%
+% The \pkg{l3build} upload options are passed to |curl| by writing the
+% fields to a text file with a default name being
+% \meta{package}|-ctan.curlopt|. This is then passed to curl using its
+% |--config| commandline option. (Using an intermediate file helps
+% keep \pkg{l3build} portable between systems using different
+% commandline quoting conventions.)
+%
+% By default the file is written into the current directory alongside
+% the zip file to be uploaded. You may wish to specify that this file
+% is ignored by any version control in that directory (using
+% |.gitignore| or similar). Or alternatively you can use the
+% |uploadconfig.curl_file| field in the |build.lua| file to specify an
+% alternative name or location for this file.
+%
+% \paragraph{Debugging}
+% If you have have difficulty with the upload process, add the option |--debug| to divert
+% the request from CTAN to a service that redirects the input back
+% again so it can be examined.
+% It can also be useful to check the contents of the |curlopts| file which has a
+% record of the options passed to curl.
+%
+% \begin{table}[p]
+% \def\YES{\textbullet}
+% \caption{Fields used in the \texttt{uploadconfig} setup table. The
+% first section of fields are \emph{required} and if they are
+% omitted the user will be interactively prompted for further
+% input. Most commands take string input, but those that are
+% indicated with `Multi' accept more than one entry using an array
+% of strings. Most of the fields correspond directly to the fields
+% in the CTAN upload API, the last group relate to file use by
+% \pkg{l3build}.}
+% \label{tab:upload-setup}
+% \medskip
+% \begin{minipage}{\linewidth}
+% \begin{tabular}{@{}lccp{8cm}@{}}
+% \toprule
+% Field & Req. & Multi & Description \\
+% \midrule
+% \texttt{announcement} & \YES & & Announcement text \\
+% \texttt{author } & \YES & & Author name (semicolon-separated for multiple) \\
+% \texttt{ctanPath } & \YES & & CTAN path \\
+% \texttt{email } & \YES & & Email address of uploader \\
+% \texttt{license } & \YES & \YES & Package license(s)\footnote{See \url{https://ctan.org/license}} \\
+% \texttt{pkg } & \YES & & Package name \\
+% \texttt{summary } & \YES & & One-line summary \\
+% \texttt{uploader } & \YES & & Name of uploader \\
+% \texttt{version } & \YES & & Package version \\
+% \midrule
+% \texttt{bugtracker } & & \YES & URL(s) of bug tracker \\
+% \texttt{description } & & & Short description/abstract \\
+% \texttt{development } & & \YES & URL(s) of development channels \\
+% \texttt{home } & & \YES & URL(s) of home page \\
+% \texttt{note } & & & Internal note to CTAN \\
+% \texttt{repository } & & \YES & URL(s) of source repositories \\
+% \texttt{support } & & \YES & URL(s) of support channels \\
+% \texttt{topic } & & \YES & Topic(s)\footnote{See \url{https://ctan.org/topics/highscore}} \\
+% \texttt{update } & & & Boolean \texttt{true} for an update, \texttt{false} for a new package \\
+% \midrule
+% \texttt{announcement\_file} & & & Announcement text file \\
+% \texttt{note\_file} & & & Note text file \\
+% \texttt{curlopt\_file} & & & The filename containing the options passed to curl \\
+% \bottomrule
+% \end{tabular}
+% \end{minipage}
+% \end{table}
+%
+%
+% \begin{figure}[p]
+% \begin{lstlisting}[frame=single,language={[5.2]Lua},gobble = 6]
+% uploadconfig = {
+% pkg = "vertbars",
+% version = "v1.0c",
+% author = "Peter R Wilson; Will Robertson",
+% license = "lppl1.3c",
+% summary = "Mark vertical rules in margin of text",
+% ctanPath = "/macros/latex/contrib/vertbars",
+% repository = "https://github.com/wspr/herries-press/",
+% update = true,
+% }
+% \end{lstlisting}
+% \caption{Example of \texttt{uploadconfig} from the \pkg{vertbars} package.}
+% \label{fig:uploadconfig}
+% \end{figure}
+%
+% \section{Lua interfaces}
+%
+% Whilst for the majority of users the simple variable-based control methods
+% outlined above will suffice, for more advanced applications there will be
+% a need to adjust behavior by using interfaces within the Lua code. This
+% section details the global variables and functions provided.
+%
+% \subsection{Global variables}
+%
+% \begin{variable}{options}
+% The |options| table holds the values passed to \pkg{l3build} at the
+% command line. The possible entries in the table are given in the table
+% below.
+% \begin{center}
+% \begin{tabular}{ll}
+% \toprule
+% Entry & Type \\
+% \midrule
+% \var{config} & Table \\
+% \var{date} & String \\
+% \var{dirty} & Boolean \\
+% \var{dry-run} & Boolean \\
+% \var{email} & String \\
+% \var{engine} & Table \\
+% \var{epoch} & String \\
+% \var{file} & string \\
+% \var{first} & Boolean \\
+% \var{force} & Boolean \\
+% \var{full} & Boolean \\
+% \var{halt-on-error} & Boolean \\
+% \var{help} & Boolean \\
+% \var{message} & string \\
+% \var{names} & Table \\
+% \var{quiet} & Boolean \\
+% \var{rerun} & Boolean \\
+% \var{shuffle} & Boolean \\
+% \var{texmfhome} & String \\
+% \bottomrule
+% \end{tabular}
+% \end{center}
+% \end{variable}
+%
+% \subsection{Utility functions}
+%
+% The utility functions are largely focussed on file operations, though a small
+% number of others are provided. File paths should be given in Unix style
+% (using |/| as a path separator). File operations take place relative to the
+% path from which \pkg{l3build} is called. File operation syntax is largely
+% modelled on Unix command line commands but reflect the need to work on
+% Windows in a flexible way.
+%
+% \begin{function}{abspath()}
+% \begin{syntax}
+% |abspath(|\meta{target}|)|
+% \end{syntax}
+% Returns a string which gives the absolute location of the
+% \meta{target} directory.
+% \end{function}
+%
+% \begin{function}{dirname()}
+% \begin{syntax}
+% |dirname(|\meta{file}|)|
+% \end{syntax}
+% Returns a string comprising the path to a \meta{file} with the name removed
+% (\emph{i.e.}~up to the last |/|). Where the \meta{file} has no path data,
+% |"."| is returned.
+% \end{function}
+%
+% \begin{function}{basename()}
+% \begin{syntax}
+% |basename(|\meta{file}|)|
+% \end{syntax}
+% Returns a string comprising the full name of the \meta{file} with the
+% path removed (\emph{i.e.}~from the last |/| onward).
+% \end{function}
+%
+% \begin{function}{cleandir()}
+% \begin{syntax}
+% |cleandir(|\meta{dir}|)|
+% \end{syntax}
+% Removes any content within the \meta{dir}; returns an error level.
+% \end{function}
+%
+% \begin{function}{cp()}
+% \begin{syntax}
+% |cp(|\meta{glob}, \meta{source}, \meta{destination}|)|
+% \end{syntax}
+% Copies files matching the \meta{glob} from the \meta{source} directory
+% to the \meta{destination}; returns an error level.
+% \end{function}
+%
+% \begin{function}{direxists()}
+% \begin{syntax}
+% |direxists(|\meta{dir}|)|
+% \end{syntax}
+% Tests if the \meta{dir} exists; returns a boolean value.
+% \end{function}
+%
+% \begin{function}{fileexists()}
+% \begin{syntax}
+% |fileexists(|\meta{file}|)|
+% \end{syntax}
+% Tests if the \meta{file} exists; returns a boolean value.
+% \end{function}
+%
+% \begin{function}{filelist()}
+% \begin{syntax}
+% |filelist(|\meta{path}, \oarg{glob}|)|
+% \end{syntax}
+% Returns a table containing all of the files with the \meta{path}
+% which match the \meta{glob}; if the latter is absent returns a list of
+% all files in the \meta{path}.
+% \end{function}
+%
+% \begin{function}{glob_to_pattern()}
+% \begin{syntax}
+% |glob_to_pattern(|\meta{glob}|)|
+% \end{syntax}
+% Returns the \meta{glob} converted to a Lua pattern.
+% \end{function}
+%
+% \begin{function}{jobname()}
+% \begin{syntax}
+% |jobname(|\meta{file}|)|
+% \end{syntax}
+% Returns a string comprising the jobname of the file with the
+% path and extension removed (\emph{i.e.}~from the last |/| up to the
+% last |.|).
+% \end{function}
+%
+% \begin{function}{mkdir()}
+% \begin{syntax}
+% |mkdir(|\meta{dir}|)|
+% \end{syntax}
+% Creates the \meta{dir}; returns an error level.
+% \end{function}
+%
+% \begin{function}{ren()}
+% \begin{syntax}
+% |ren(|\meta{dir}, \meta{source}, \meta{destination}|)|
+% \end{syntax}
+% Renames the \meta{source} file to the \meta{destination} name within
+% the \meta{dir}; returns an error level.
+% \end{function}
+%
+% \begin{function}{rm()}
+% \begin{syntax}
+% |rm(|\meta{dir}, \meta{glob}|)|
+% \end{syntax}
+% Removes files in the \meta{dir} matching the \meta{glob}; returns an
+% error level.
+% \end{function}
+%
+% \begin{function}{run()}
+% \begin{syntax}
+% |run(|\meta{dir}, \meta{cmd}|)|
+% \end{syntax}
+% Executes the \meta{cmd}, starting it in the \meta{dir}; returns an
+% error level.
+% \end{function}
+%
+% \begin{function}{splitpath()}
+% \begin{syntax}
+% |splitpath(|\meta{file}|)|
+% \end{syntax}
+% Returns two strings split at the last |/|: the \texttt{dirname()} and
+% the |basename()|.
+% \end{function}
+%
+% \begin{function}{normalize_path()}
+% \begin{syntax}
+% |normalize_path(|\meta{path}|)|
+% \end{syntax}
+% When called on Windows, returns a string comprising the \meta{path} with
+% |/| characters replaced by |\\|. In other cases returns the path unchanged.
+% \end{function}
+%
+% \subsection{System-dependent strings}
+%
+% To support creation of additional functionality, the following low-level
+% strings are exposed by \pkg{l3build}: these all have system-dependent
+% definitions and avoid the need to test |os.type| during the construction
+% of system calls.
+%
+% \begin{variable}{os_concat}
+% The concatenation operation for using multiple commands in one
+% system call, \emph{e.g.}
+% \begin{verbatim}
+% os.execute("tex " .. file .. os_concat .. "tex " .. file)
+% \end{verbatim}
+% \end{variable}
+%
+% \begin{variable}{os_null}
+% The location to redirect commands which should produce no output
+% at the terminal: almost always used preceded by |>|, \emph{e.g.}
+% \begin{verbatim}
+% os.execute("tex " .. file .. " > " .. os_null)
+% \end{verbatim}
+% \end{variable}
+%
+% \begin{variable}{os_pathsep}
+% The separator used when setting an environment variable to multiple
+% paths, \emph{e.g.}
+% \begin{verbatim}
+% os.execute(os_setenv .. " PATH=../a" .. os_pathsep .. "../b")
+% \end{verbatim}
+% \end{variable}
+%
+% \begin{variable}{os_setenv}
+% The command to set an environmental variable, \emph{e.g.}
+% \begin{verbatim}
+% os.execute(os_setenv .. " PATH=../a")
+% \end{verbatim}
+% \end{variable}
+%
+% \begin{variable}{os_yes}
+% A command to generate a series of $200$ lines each containing the
+% character |y|: this is useful as the Unix |yes| command cannot be
+% used inside |os.execute| (it does not terminate).
+% \end{variable}
+%
+% \subsection{Components of \texttt{l3build}}
+%
+% \begin{function}{call()}
+% \begin{syntax}
+% |call(|\meta{dirs}, \meta{target}, \oarg{options}|)|
+% \end{syntax}
+% Runs the \texttt{l3build} \meta{target} (a string) for each directory in the
+% \meta{dirs} (a table). This will pass command line options for the parent
+% script to the child processes. The \meta{options} table should take the
+% same form as the global \meta{options}, described above. If it is
+% absent then the global list is used. Note that any entry for the
+% |target| in this table is ignored.
+% \end{function}
+%
+% \begin{function}{install_files()}
+% \begin{syntax}
+% |install_files(|\meta{target},\meta{full},\meta{dry-run}|)|
+% \end{syntax}
+% Installs the files from the module into the TDS root \meta{target}.
+% If \meta{full} is \texttt{true}, all files are copied: if it is
+% \texttt{false}, the \texttt{doc} and \texttt{source} trees are skipped.
+% If \meta{dry-run} is \texttt{true}, no files are copied, but instead the
+% files which would be copied are reported.
+% \end{function}
+%
+% \subsection{Typesetting functions}
+%
+% All typetting functions return $0$ on a successful completion.
+%
+% \begin{function}{biber()}
+% \begin{syntax}
+% |biber(|\meta{name},\meta{dir}|)|
+% \end{syntax}
+% Runs Biber on the \meta{name} (\emph{i.e.}~a jobname lacking any
+% extension) inside the \meta{dir}. If there is no |.bcf| file then
+% no action is taken with a return value of $0$.
+% \end{function}
+%
+% \begin{function}{bibtex()}
+% \begin{syntax}
+% |bibtex(|\meta{name},\meta{dir}|)|
+% \end{syntax}
+% Runs Bib\TeX{} on the \meta{name} (\emph{i.e.}~a jobname lacking any
+% extension) inside the \meta{dir}. If there are no |\citation| lines in
+% the |.aux| file then no action is taken with a return value of $0$.
+% \end{function}
+%
+% \begin{function}{makeindex()}
+% \begin{syntax}
+% |makeindex(|\meta{name},\meta{dir},\meta{inext},\meta{outext},\meta{logext},\meta{style}|)|
+% \end{syntax}
+% Runs MakeIndex on the \meta{name} (\emph{i.e.}~a jobname lacking any
+% extension) inside the \meta{dir}. The various extensions and the \meta{style}
+% should normally be given as it standard for MakeIndex.
+% \end{function}
+%
+% \begin{function}{tex()}
+% \begin{syntax}
+% |tex(|\meta{file},\meta{dir}|)|
+% \end{syntax}
+% Runs \luavar{typesetexe} on the \meta{name} inside the \meta{dir}.
+% \end{function}
+%
+% \begin{function}{runcmd()}
+% \begin{syntax}
+% |runcmd(|\meta{cmd},\meta{dir},|{|\meta{envvars}|})|
+% \end{syntax}
+% A generic function which runs the \meta{cmd} in the \meta{dir}, first
+% setting up all of the environmental variables specified to
+% point to the |local| and |working| directories. This function is useful
+% when creating non-standard typesetting steps.
+% \end{function}
+%
+% \subsection{Customising the target list}
+%
+% The targets known to \pkg{l3build} are stored in the global table
+% |target_list|. Each entry should have at least a |func|, pointing to the
+% function used to implement the target. This function will receive the
+% list of names given at the command line as a table argument.
+% In most cases, targets will also have a |desc|, used to construct |help()|
+% automatically. In addition, the following may also be used:
+% \begin{itemize}
+% \item |bundle_func| A variant of |func| used when at the top level of
+% a bundle
+% \item |bundle_target| A boolean to specify that when passing the target
+% name in a bundle, it should have |bundle| prepended.
+% \item |pre| A function executed before the main function, and receiving
+% the |names| as an argument; this allows checking of the |name| data
+% without impact on the main |func|.
+% \end{itemize}
+%
+% \subsection{Customising the manifest file}
+% \label{sec:manifest}
+%
+% The default setup for the manifest file creating with the \texttt{manifest}
+% target attempt to reflect the defaults for \pkg{l3build} itself.
+% The groups (and hence the files) displayed can be completely
+% customised by defining a new setup function which creates a Lua table with
+% the appropriate settings (\S\ref{sec:manifest-groups}).
+%
+% The formatting within the manifest file can be customised by redefining a number
+% of Lua functions. This includes
+% how the files are sorted within each group (\S\ref{sec:manifest-sorting}),
+% the inclusion of one-line descriptions for each file (\S\ref{sec:manifest-desc}),
+% and the details of the formatting of each entry (\S\ref{sec:manifest-formatting}).
+%
+% To perform such customisations, either include the re-definitions directly within your
+% package's |build.lua| file, or make a copy of |l3build-manifest-setup.lua|, rename it,
+% and load it within your |build.lua| using |dofile()|.
+%
+%
+% \subsubsection{Custom manifest groups}
+% \label{sec:manifest-groups}
+%
+% The setup code for defining each group of files within the manifest looks something like
+% the following:
+% \begin{verbatim}
+% manifest_setup = function()
+% local groups = {
+% {
+% subheading = "Repository files",
+% description = [[
+% Files located in the package development repository.
+% ]],
+% },
+% {
+% name = "Source files",
+% description = [[
+% These are source files generating the package files.
+% ]],
+% files = {sourcefiles},
+% },
+% {
+% name = "Typeset documentation source files",
+% description = [[
+% These files are typeset using LaTeX to produce the PDF documentation for the package.
+% ]],
+% files = {typesetfiles,typesetsourcefiles,typesetdemofiles},
+% },
+% ...
+% }
+% return groups
+% end
+% \end{verbatim}
+%
+% The |groups| variable is an ordered array of tables which contain the metadata about each
+% `group' in the manifest listing.
+% The keys supported in these tables are outlined in Table~\ref{tab:manifest-setup} and Table~\ref{tab:manifest-subheadings}
+% See the complete setup code in |l3build-manifest-setup.lua| for examples of these in use.
+%
+% \begin{table}
+% \caption{Table entries used in the manifest setup table for a group.}
+% \label{tab:manifest-setup}
+% \centering
+% \begin{tabular}{lp{8cm}}
+% \toprule
+% Entry & Description \\
+% \midrule
+% \var{name} & The heading of the group \\
+% \var{description} & The description printed below the heading \\
+% \var{files} & Files to include in this group \\
+% \var{exclude} & Files to exclude (default |{excludefiles}|) \\
+% \var{dir} & The directory to search (default |maindir|) \\
+% \var{rename} & An array with a |gsub| redefinition for the filename \\
+% \var{skipfiledescription} & Whether to extract file descriptions from these files (default |false|) \\
+% \bottomrule
+% \end{tabular}
+% \end{table}
+%
+% \begin{table}
+% \caption{Table entries used in the manifest setup table for a subheading.}
+% \label{tab:manifest-subheadings}
+% \centering
+% \begin{tabular}{lp{8cm}}
+% \toprule
+% Entry & Description \\
+% \midrule
+% \var{subheading} & The subheading \\
+% \var{description} & The description printed below the subheading \\
+% \bottomrule
+% \end{tabular}
+% \end{table}
+%
+%
+% \subsubsection{Sorting within each manifest group}
+% \label{sec:manifest-sorting}
+%
+% Within a single group in the manifest listing, files can be matched against multiple variables.
+% For example, for |sourcefiles={*.dtx,*.ins}| the following (unsorted) file listing might result:
+% \begin{itemize}[nosep]
+% \item foo.dtx
+% \item bar.dtx
+% \item foo.ins
+% \item bar.ins
+% \end{itemize}
+% This listing can be sorted using two separate functions by the default manifest code.
+% The first, default, is to sort alphabetically within a single variable match.
+% This keeps all files of a single extension contiguous in the listing.
+% To edit how this sort is performed, redefine the |manifest_sort_within_match| function.
+%
+% The second approach to sorting is to apply a sorting function to the entire set of matched files.
+% (This happens \emph{after} any sorting is applied for each match.)
+% By default this is a no-op but can be edited by redefining the |manifest_sort_within_group|
+% function. For example:
+% \begin{verbatim}
+% manifest_sort_within_group = function(files)
+% local f = files
+% table.sort(f)
+% return f
+% end
+% \end{verbatim}
+% This will produce an alphabetical listing of files:
+% \begin{itemize}
+% \item bar.dtx
+% \item bar.ins
+% \item foo.dtx
+% \item foo.ins
+% \end{itemize}
+%
+%
+% \subsubsection{File descriptions}
+% \label{sec:manifest-desc}
+%
+% By default the manifest contains lists of files, and with a small addition these
+% lists can be augmented with a one-line summary of each file.
+% If the Lua function |manifest_extract_filedesc| is defined, it will be used to search
+% the contents of each file to extract a description for that file.
+% For example, perhaps you are using multiple |.dtx| files for a project and the argument
+% to the first |\section| in each can be used as a file description:
+% \begin{verbatim}
+% manifest_extract_filedesc = function(filehandle,filename)
+%
+% local all_file = filehandle:read("*all")
+% local matchstr = "\\section{(.-)}"
+%
+% filedesc = string.match(all_file,matchstr)
+%
+% return filedesc
+% end
+% \end{verbatim}
+% (Note the |matchstr| above is only an example and doesn't handle nested braces.)
+%
+%
+% \subsubsection{Custom formatting}
+% \label{sec:manifest-formatting}
+%
+% After the manifest code has built a complete listing of files to print, a series of
+% file writing operations are performed which create the manifest file.
+% The following functions can be re-defined to change the formatting of the manifest file:
+% \begin{itemize}
+% \item |manifest_write_opening|: Write the heading of the manifest file and its opening paragraph.
+% \item |manifest_write_subheading|: Write a subheading and description
+% \item |manifest_write_group_heading|: Write the section heading of the manifest group and the group description
+% \item |manifest_write_group_file|: Write the filename (when not writing file descriptions)
+% \item |manifest_write_group_file_descr|: Write the filename and the file description
+% \end{itemize}
+% Full descriptions of their usage and arguments can be found within the |l3build-manifest-setup.lua|
+% code itself.
+%
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \clearpage
+% \section{\texttt{regression-test.tex}}
+%
+% This section describes the code for setting up the regression test system.
+% Each test file should start with |\input regression-test.tex\relax|.
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% \subsection{Preliminaries}
+%
+% We require \eTeX{}.
+% \begin{macrocode}
+\begingroup\expandafter\expandafter\expandafter\endgroup
+\expandafter\ifx\csname eTeXversion\endcsname\relax
+ \errmessage{e-TeX is required to use regression-test.tex}%
+ \expandafter\endinput
+\fi
+% \end{macrocode}
+%
+% \begin{macro}{\reset@catcodes}
+% Unlike in the \LaTeXe{} regression test suite, reset catcodes: each test
+% should set these as appropriate. There's also a quick test for Con\TeX{}t:
+% it defines |\unprotect| which should be a reasonable marker (and is
+% needed as some catcodes are otherwise wrong).
+% \begin{macrocode}
+\ifx\unprotect\undefined
+ \expandafter\edef\csname reset\string @catcodes\endcsname{%
+ \catcode`\noexpand\@=\the\catcode`\@\relax
+ }%
+ \catcode`\@=11 %
+\else
+ \unprotect
+ \def\reset@catcodes{\protect}%
+\fi
+% \end{macrocode}
+% \end{macro}
+%
+% Put \TeX{} into scroll mode, and stop it showing the
+% implementation details of macros in error messages.
+% \begin{macrocode}
+\ifnum\interactionmode>1 \scrollmode\fi
+\errorcontextlines=-1 %
+% \end{macrocode}
+%
+% Show all box details: this avoids getting variable results if boxes
+% have different numbers of lines (\LuaTeX{} adds extra information).
+% \begin{macrocode}
+\showboxbreadth=\maxdimen
+\showboxdepth=\maxdimen
+% \end{macrocode}
+%
+% \begin{macro}{\logginoutput}
+% The |\showoutput| command of \LaTeX{} calls |\loggingoutput| which in turn
+% calls |\errorstopmode| but we want to continue running without any stops.
+% \begin{macrocode}
+\def\loggingoutput{%
+ \tracingoutput=1 %
+ \showboxbreadth=\maxdimen
+ \showboxdepth=\maxdimen
+}
+% \end{macrocode}
+% \end{macro}
+%
+% Set the newline character: \LaTeXe{} does this but plain-based formats do
+% not.
+% \begin{macrocode}
+\newlinechar=`\^^J
+% \end{macrocode}
+%
+% \subsection{Commands in test files}
+%
+% \begin{macro}{\LONGTYPEOUT, \TYPE}
+% A long version of |\typeout|, because tests may contain |\par| tokens.
+% Besides, with that |\TYPE|, we can do
+% |\TYPE { ... \TRUE ... \NEWLINE ... }|.
+% \begin{macrocode}
+\long\def\LONGTYPEOUT#1{%
+ \begingroup
+ \long\def\TYPE##1{##1}%
+ \immediate\write128{#1}%
+ \endgroup
+}
+\let\TYPE\LONGTYPEOUT
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\STARTMESSAGE, \START}
+% Start the test, after the optional |\documentclass|
+% |\begin{document}| commands with |\START|. All lines in the |.log| file
+% before this will be ignored.
+% \begin{macrocode}
+\def\STARTMESSAGE{This is a generated file for the l3build validation system.}
+\def\START{%
+ \LONGTYPEOUT{^^JSTART-TEST-LOG^^J}%
+ \LONGTYPEOUT{^^J%
+ \STARTMESSAGE%
+ ^^J^^JDon't change this file in any respect.%
+ ^^J^^J%
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@@end, \END}
+% The test should end with |\END| or |\end{document}|
+% or |\bye| in plain \TeX{}.
+% \begin{macrocode}
+\ifx\@@end\@undefined
+ \let\@@@end\end
+\else
+ \let\@@@end\@@end
+\fi
+\def\END{%
+ \ifnum\currentgrouplevel>0 %
+ \LONGTYPEOUT{Bad grouping: \the\currentgrouplevel!}%
+ \fi
+ \ifnum\currentiflevel>2 %
+ \LONGTYPEOUT{Bad conditionals: \the\numexpr\currentiflevel-2!}%
+ \fi
+ \LONGTYPEOUT{^^JEND-TEST-LOG^^J}%
+ \@@@end
+}
+\ifx\@@end\@undefined
+ \let\end\END
+\else
+ \let\@@end\END
+\fi
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\OMIT, \TIMO}
+% Surround commands which produce irrelevant lines in the |.log| file by
+% |\OMIT|\dots|\TIMO|
+% \begin{macrocode}
+\def\OMIT{\LONGTYPEOUT{OMIT}}
+\def\TIMO{\LONGTYPEOUT{TIMO}}
+% \end{macrocode}
+% \end{macro}
+%
+%
+
+% \begin{macro}{\SHOWFILE}
+% Load a file (e.g.,| \jobname.toc|) into the .log file with the usual special
+% characters rendered harmless. Use as |\SHOWFILE{\jobname.aux}|.
+% \begin{macrocode}
+\begingroup % within the scope of this groups each line needs to end in % !
+\catcode`\^^M\active %
+\gdef\SHOWFILE#1{%
+ \typeout{-------- #1 (start) ---------}%
+\IfFileExists{#1}%
+ {\begingroup %
+ \catcode`\^^M\active %
+ \edef^^M{^\string^M^^J}%
+ \everyeof{\noexpand}%
+ \obeyspaces %
+ \@sanitize %
+ \message{\@@input #1 }%
+ \endgroup }%
+ {\message{Not found}}%
+ \typeout{-------- #1 (end) -----------}%
+}%
+\endgroup
+% \end{macrocode}
+% \end{macro}
+%
+% To allow testing of possible changes, we allow extra code to be read
+% in before the test starts. The necessary code should be placed in a
+% file |regression-test.cfg|.
+% \begin{macrocode}
+\ifx\InputIfFileExists\@undefined
+ \newread\@inputcheck
+ \long\def\InputIfFileExists#1#2#3{%
+ \openin\@inputcheck#1\relax
+ \ifeof\@inputcheck
+ \def\reserved@a{#3}%
+ \else
+ \def\reserved@a{#2\input #1\relax}%
+ \fi
+ \closein\@inputcheck
+ \reserved@a
+ }%
+\fi
+\InputIfFileExists{regression-test.cfg}
+ {\LONGTYPEOUT{^^J***^^Jregression-test.cfg in operation^^J***^^J}}{}
+% \end{macrocode}
+%
+% \subsection{Formatting the \texttt{.log} file}
+%
+% \begin{macro}{\gTESTint}
+% For tracking the total number of tests.
+% \begin{macrocode}
+\newcount\gTESTint
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \SEPARATOR,
+% \BEGINTEST,
+% \ENDTEST,
+% \TEST,
+% \TESTEXP,
+% \TRUE,
+% \FALSE,
+% \YES,
+% \NO,
+% \NEWLINE
+% }
+% We are not starved for space in the log file output, so let's make it as
+% verbose as is useful when reading the |.diff|'s.
+% \begin{macrocode}
+\def\SEPARATOR{%
+ \TYPE{%
+ ============================================================%
+ }%
+}
+\protected\long\def\BEGINTEST#1{%
+ \global\advance\gTESTint by 1 %
+ \SEPARATOR
+ \LONGTYPEOUT{TEST \the\gTESTint: \detokenize{#1}}%
+ \SEPARATOR
+ \begingroup
+ \let\TYPE\LONGTYPEOUT
+}
+\protected\long\def\ENDTEST{%
+ \endgroup
+ \SEPARATOR
+ \LONGTYPEOUT{}%
+}
+\long\def\TEST#1#2{%
+ \BEGINTEST{#1}%
+ #2%
+ \ENDTEST
+}
+\long\def\TESTEXP#1#2{%
+ \BEGINTEST{#1}%
+ \LONGTYPEOUT{#2}%
+ \ENDTEST
+}
+\def \TRUE {\TYPE{TRUE}}
+\def \FALSE {\TYPE{FALSE}}
+\def \YES {\TYPE{YES}}
+\def \NO {\TYPE{NO}}
+\def \NEWLINE {\TYPE{^^J}}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Suppressing variable data in output}
+%
+% Load the map file early so it does not appear in the log.
+% \begin{macrocode}
+\ifx\pdfoutput\@undefined
+ \ifx\outputmode\@undefined
+ \else
+ \ifnum\outputmode>0 %
+ \pdfextension mapfile{pdftex.map}%
+ \fi
+ \fi
+\else
+ \ifnum\pdfoutput>0 %
+ \pdfmapfile{pdftex.map}%
+ \fi
+\fi
+% \end{macrocode}
+%
+% To make any PDF file produced comparable we need to suppress various
+% pieces of data. This works in concert with setting the epoch from the
+% environment side (as not all output can be controlled here). We are
+% somewhat stuck if \texttt{dvips} is being used so just hope for the best!
+% There is a limit to what can be done with the underlying PDF structure so
+% there is no point entirely suppressing \texttt{Producer}: simply avoid
+% any version numbers.
+% \begin{macrocode}
+\ifnum 0%
+ \ifx\pdfoutput\@undefined\else\ifnum\pdfoutput>0 1\fi\fi
+ \ifx\outputmode\@undefined\else\ifnum\outputmode>0 1\fi\fi
+ >0 %
+ \ifx\pdfvariable\@undefined
+ \pdfinfo{/Producer (\ifx\directlua\@undefined pdf\else Lua\fi TeX)}
+ \ifx\pdfinfoomitdate\@undefined\else
+ \pdfinfoomitdate = 1 %
+ \pdfsuppressptexinfo = \numexpr
+ 0
+ + 1 % PTEX.Fullbanner
+ + 2 % PTEX.FileName
+ \relax
+ \pdftrailerid{}
+ \fi
+ \else
+ \pdfextension info{/Producer (LuaTeX)}
+ \pdfvariable suppressoptionalinfo \numexpr
+ 0
+ + 1 % PTEX.Fullbanner
+ + 2 % PTEX.FileName
+ + 32 % CreationDate
+ + 64 % ModDate
+ + 512 % ID
+ \relax
+ \fi
+\else
+ \ifnum 0%
+ \ifx\XeTeXversion\@undefined\else 1\fi
+ \ifx\kanjiskip\@undefined\else 1\fi
+ >0 %
+ \special{%
+ pdf: docinfo
+ <<
+ /Creator (TeX)
+ /CreationDate ()
+ /ModDate ()
+ /Producer (\ifx\XeTeXversion\@undefined\else x\fi dvipdfmx)
+ >>
+ }
+ \fi
+\fi
+% \end{macrocode}
+%
+% Disable compression in PDF output.
+% \begin{macrocode}
+\ifnum 0%
+ \ifx\pdfoutput\@undefined\else\ifnum\pdfoutput>0 1\fi\fi
+ \ifx\outputmode\@undefined\else\ifnum\outputmode>0 1\fi\fi
+ >0 %
+ \ifx\pdfvariable\@undefined
+ \pdfcompresslevel=0 %
+ \pdfobjcompresslevel=0 %
+ \else
+ \pdfvariable compresslevel=0 %
+ \pdfvariable objcompresslevel=0 %
+ \fi
+\else
+ \ifnum 0%
+ \ifx\XeTeXversion\@undefined\else 1\fi
+ \ifx\kanjiskip\@undefined\else 1\fi
+ >0 %
+ \special{dvipdfmx:config z 0}% Compress level
+ \special{dvipdfmx:config C 0x40}% Object compression
+ \fi
+\fi
+% \end{macrocode}
+%
+% Finish up.
+% \begin{macrocode}
+\reset@catcodes
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \newpage
+% \section{\texttt{l3build.lua}}
+%
+% This section consists of the |l3build.lua| code.
+% This code is \emph{not} generated from |l3build.dtx| since it needs to already be extracted to build \pkg{l3build} itself!
+% As Frank says, we don't want to end up with a double M\"unchhausen.
+%
+% \lstinputlisting
+% [
+% basicstyle=\ttfamily\scriptsize,
+% numbers=left,
+% numberstyle={\tiny\color[gray]{0.4}},
+% language={[5.2]Lua},
+% procnamekeys=function,
+% procnamestyle=\color{red},
+% ]
+% {l3build.lua}
+%
+% \end{implementation}
+%
+% \PrintIndex