diff options
Diffstat (limited to 'macros/latex/contrib/l3build/l3build.dtx')
-rw-r--r-- | macros/latex/contrib/l3build/l3build.dtx | 2369 |
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 |