summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Master/texmf-dist/doc/latex/l3kernel/README89
-rw-r--r--Master/texmf-dist/doc/latex/l3kernel/expl3.pdfbin0 -> 616883 bytes
-rw-r--r--Master/texmf-dist/doc/latex/l3kernel/interface3.tex89
-rw-r--r--Master/texmf-dist/doc/latex/l3kernel/source3.pdfbin0 -> 2582748 bytes
-rw-r--r--Master/texmf-dist/doc/latex/l3kernel/source3.tex106
-rw-r--r--Master/texmf-dist/doc/latex/l3kernel/source3body.tex376
-rw-r--r--Master/texmf-dist/makeindex/l3kernel/l3doc.ist72
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/expl3.dtx1099
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3alloc.dtx216
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3basics.dtx3208
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3bootstrap.dtx647
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3box.dtx1237
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3clist.dtx1437
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3doc.dtx2064
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3expan.dtx1416
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3file.dtx418
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3final.dtx112
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3fp.dtx5676
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3int.dtx2197
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3io.dtx1185
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3keys.dtx1365
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3keyval.dtx405
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3luatex.dtx459
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3msg.dtx1609
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3names.dtx629
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3prg.dtx2046
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3prop.dtx1206
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3quark.dtx486
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3seq.dtx1812
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3skip.dtx1675
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3tl.dtx2268
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3token.dtx2495
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3toks.dtx548
-rw-r--r--Master/texmf-dist/tex/latex/l3kernel/expl3.sty179
-rw-r--r--Master/texmf-dist/tex/latex/l3kernel/l3basics.sty784
-rw-r--r--Master/texmf-dist/tex/latex/l3kernel/l3bootstrap.sty256
-rw-r--r--Master/texmf-dist/tex/latex/l3kernel/l3box.sty219
-rw-r--r--Master/texmf-dist/tex/latex/l3kernel/l3clist.sty426
-rw-r--r--Master/texmf-dist/tex/latex/l3kernel/l3doc.cls1001
-rw-r--r--Master/texmf-dist/tex/latex/l3kernel/l3expan.sty394
-rw-r--r--Master/texmf-dist/tex/latex/l3kernel/l3file.sty133
-rw-r--r--Master/texmf-dist/tex/latex/l3kernel/l3fp.sty3403
-rw-r--r--Master/texmf-dist/tex/latex/l3kernel/l3int.sty743
-rw-r--r--Master/texmf-dist/tex/latex/l3kernel/l3io.sty430
-rw-r--r--Master/texmf-dist/tex/latex/l3kernel/l3keys.sty475
-rw-r--r--Master/texmf-dist/tex/latex/l3kernel/l3keyval.sty177
-rw-r--r--Master/texmf-dist/tex/latex/l3kernel/l3luatex.sty160
-rw-r--r--Master/texmf-dist/tex/latex/l3kernel/l3msg.sty574
-rw-r--r--Master/texmf-dist/tex/latex/l3kernel/l3names.sty489
-rw-r--r--Master/texmf-dist/tex/latex/l3kernel/l3prg.sty563
-rw-r--r--Master/texmf-dist/tex/latex/l3kernel/l3prop.sty333
-rw-r--r--Master/texmf-dist/tex/latex/l3kernel/l3quark.sty154
-rw-r--r--Master/texmf-dist/tex/latex/l3kernel/l3seq.sty531
-rw-r--r--Master/texmf-dist/tex/latex/l3kernel/l3skip.sty332
-rw-r--r--Master/texmf-dist/tex/latex/l3kernel/l3tl.sty628
-rw-r--r--Master/texmf-dist/tex/latex/l3kernel/l3token.sty739
-rw-r--r--Master/texmf-dist/tex/latex/l3kernel/l3toks.sty163
-rwxr-xr-xMaster/tlpkg/bin/tlpkg-ctan-check1
-rw-r--r--Master/tlpkg/tlpsrc/collection-latexrecommended.tlpsrc1
-rw-r--r--Master/tlpkg/tlpsrc/l3kernel.tlpsrc0
60 files changed, 51935 insertions, 0 deletions
diff --git a/Master/texmf-dist/doc/latex/l3kernel/README b/Master/texmf-dist/doc/latex/l3kernel/README
new file mode 100644
index 00000000000..9281d08f4c1
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/l3kernel/README
@@ -0,0 +1,89 @@
+
+ An Experimental LaTeX3 Programming Convention
+ =============================================
+
+ 2011/05/10
+
+
+WHERE TO GET IT
+---------------
+
+The files in this distribution represent a snapshot of selected files
+from the Subversion (SVN) repository of the LaTeX3 Project.
+
+To obtain current versions of the files, visit
+<http://www.latex-project.org/code.html> which contains further
+instructions.
+
+OVERVIEW
+--------
+
+The files of the expl3 bundle provide a low-level API for TeX
+programmers with special syntax conventions, completely separating it
+from document level syntax. Hence, the commands provided are not
+intended for use at the document level nor for use in describing
+design layouts in document class files.
+
+This API provides the foundation on which the LaTeX3 kernel and other
+advanced extensions are built. Special care has been taken so that
+they can be used within a LaTeX2e context as regular packages.
+
+While expl3 is still experimental, the bundle is now regarded as
+broadly stable. The syntax conventions and functions provided are now
+ready for wider use. There may still be changes to some functions, but
+these will be minor when compared to the scope of expl3.
+
+REQUIREMENTS
+------------
+
+The expl3 bundle requires the e-TeX extensions and the functionality
+of the \pdfstrcmp primitive. As a result, the bundle will only work
+with the following engines:
+
+ - pdfTeX v1.30 or later
+ - XeTeX v0.9994 or later
+ - LuaTeX v0.40 or later
+
+pdfTeX v1.30 was released in 2005, and so any recent TeX distribution
+will support expl3. Both XeTeX and LuaTeX have developed more
+actively over the past few years, and for this reason only recent
+releases of these engines are supported.
+
+THE GUILTY PERSONS
+------------------
+
+ Frank Mittelbach, Denys Duchier, Johannes Braams, Michael Downes,
+ David Carlisle, Alan Jeffrey, Chris Rowley, Rainer Schoepf
+ Javier Bezos, Morten Hoegholm, Thomas Lotze, Will Robertson,
+ Joseph Wright, Bruno Le Floch
+
+
+DISCUSSION
+----------
+
+Discussion concerning the approach, suggestions for improvements,
+changes, additions, etc. should be addressed to the list LaTeX-L.
+
+You can subscribe to this list by sending mail to
+
+ listserv@urz.uni-heidelberg.de
+
+with the body containing
+
+ subscribe LATEX-L <Your-First-Name> <Your-Second-Name>
+
+
+BUGS
+----
+
+The issue tracker for LaTeX3 bugs is currently located at
+
+ https://github.com/latex3/svn-mirror/issues
+
+Please report specific issues with LaTeX3 code there. More general
+discussion should be directed to the LaTeX-L lists.
+
+=====================================================================
+
+--- Copyright 1998-2011 The LaTeX3 Project. All rights reserved ---
+
diff --git a/Master/texmf-dist/doc/latex/l3kernel/expl3.pdf b/Master/texmf-dist/doc/latex/l3kernel/expl3.pdf
new file mode 100644
index 00000000000..875541e93ba
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/l3kernel/expl3.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/latex/l3kernel/interface3.tex b/Master/texmf-dist/doc/latex/l3kernel/interface3.tex
new file mode 100644
index 00000000000..f4c4fa4e2bf
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/l3kernel/interface3.tex
@@ -0,0 +1,89 @@
+% \iffalse meta-comment
+%
+%% File: interfaces3.tex Copyright (C) 1990-2011 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 "expl3 bundle" (The Work in LPPL)
+%% and all files in that bundle must be distributed together.
+%%
+%% The released version of this bundle is available from CTAN.
+%%
+%% -----------------------------------------------------------------------
+%%
+%% The development version of the bundle can be found at
+%%
+%% http://www.latex-project.org/svnroot/experimental/trunk/
+%%
+%% for those people who are interested.
+%%
+%%%%%%%%%%%
+%% NOTE: %%
+%%%%%%%%%%%
+%%
+%% Snapshots taken from the repository represent work in progress and may
+%% not work or may contain conflicting material! We therefore ask
+%% people _not_ to put them into distributions, archives, etc. without
+%% prior consultation with the LaTeX3 Project.
+%%
+%% -----------------------------------------------------------------------
+%
+% \fi
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% This document will typeset the LaTeX3 interface descriptions a single
+% document. This will produce quite a large file (more than 170 pages
+% currently).
+%
+% There is also a full version of the sources (source3.tex) which additionally
+% also typesets the command implementations.
+%
+% Do not forget to generate the index (as explained on the terminal output
+% near the end of the run)!
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+\documentclass{l3doc}
+\listfiles
+
+\begin{document}
+
+\title{The \LaTeX3 Interfaces}
+\author{%
+ The \LaTeX3 Project\thanks
+ {%
+ E-mail:
+ \href{mailto:latex-team@latex-project.org}
+ {latex-team@latex-project.org}%
+ }%
+}
+
+\pagenumbering{roman}
+\maketitle
+
+%
+% First load all modules and typeset the documentation parts
+%
+
+\input{source3body} % all the individual modules
+
+\clearpage
+
+\begingroup
+ \def\endash{--}
+ \catcode`\-\active
+ \def-{\futurelet\temp\indexdash}
+ \def\indexdash{\ifx\temp-\endash\fi}
+ \DelayPrintIndex
+\endgroup
+
+\end{document}
+
+
diff --git a/Master/texmf-dist/doc/latex/l3kernel/source3.pdf b/Master/texmf-dist/doc/latex/l3kernel/source3.pdf
new file mode 100644
index 00000000000..946105cd5c8
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/l3kernel/source3.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/latex/l3kernel/source3.tex b/Master/texmf-dist/doc/latex/l3kernel/source3.tex
new file mode 100644
index 00000000000..927e483cce9
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/l3kernel/source3.tex
@@ -0,0 +1,106 @@
+% \iffalse meta-comment
+%
+%% File: source3.tex Copyright (C) 1990-2011 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 "expl3 bundle" (The Work in LPPL)
+%% and all files in that bundle must be distributed together.
+%%
+%% The released version of this bundle is available from CTAN.
+%%
+%% -----------------------------------------------------------------------
+%%
+%% The development version of the bundle can be found at
+%%
+%% http://www.latex-project.org/svnroot/experimental/trunk/
+%%
+%% for those people who are interested.
+%%
+%%%%%%%%%%%
+%% NOTE: %%
+%%%%%%%%%%%
+%%
+%% Snapshots taken from the repository represent work in progress and may
+%% not work or may contain conflicting material! We therefore ask
+%% people _not_ to put them into distributions, archives, etc. without
+%% prior consultation with the LaTeX3 Project.
+%%
+%% -----------------------------------------------------------------------
+%
+% \fi
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% This document will typeset the LaTeX3 sources as a single document.
+% This will produce quite a large file (more than 400 pages).
+%
+% There is also a shorter version (interface3.tex) that only typesets the
+% command % interface descriptions.
+%
+% Do not forget to generate the index (as explained on the terminal output
+% near the end of the run)!
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\documentclass{l3doc}
+\listfiles
+
+\begin{document}
+
+\title{The \LaTeX3 Sources}
+\author{%
+ The \LaTeX3 Project\thanks
+ {%
+ E-mail:
+ \href{mailto:latex-team@latex-project.org}
+ {latex-team@latex-project.org}%
+ }%
+}
+
+\pagenumbering{roman}
+\maketitle
+
+%
+% First load all modules and typeset the documentation parts
+%
+
+\input{source3body} % all the individual modules
+
+%
+% Now reload all modules and typeset the implementation parts
+%
+
+\part{Implementation}
+
+\def\maketitle{}
+\EnableImplementation
+\DisableDocumentation
+\DocInputAgain
+
+\clearpage
+\pagestyle{headings}
+
+% Make TeX shut up.
+\hbadness=10000
+\newcount\hbadness
+\hfuzz=\maxdimen
+
+\PrintChanges
+\clearpage
+
+\begingroup
+ \def\endash{--}
+ \catcode`\-\active
+ \def-{\futurelet\temp\indexdash}
+ \def\indexdash{\ifx\temp-\endash\fi}
+
+ \DelayPrintIndex
+\endgroup
+
+\end{document} \ No newline at end of file
diff --git a/Master/texmf-dist/doc/latex/l3kernel/source3body.tex b/Master/texmf-dist/doc/latex/l3kernel/source3body.tex
new file mode 100644
index 00000000000..fbffe013ae8
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/l3kernel/source3body.tex
@@ -0,0 +1,376 @@
+% \iffalse meta-comment
+%
+%% File: source3body.tex Copyright (C) 1990-2011 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 "expl3 bundle" (The Work in LPPL)
+%% and all files in that bundle must be distributed together.
+%%
+%% The released version of this bundle is available from CTAN.
+%%
+%% -----------------------------------------------------------------------
+%%
+%% The development version of the bundle can be found at
+%%
+%% http://www.latex-project.org/svnroot/experimental/trunk/
+%%
+%% for those people who are interested.
+%%
+%%%%%%%%%%%
+%% NOTE: %%
+%%%%%%%%%%%
+%%
+%% Snapshots taken from the repository represent work in progress and may
+%% not work or may contain conflicting material! We therefore ask
+%% people _not_ to put them into distributions, archives, etc. without
+%% prior consultation with the LaTeX3 Project.
+%%
+%% -----------------------------------------------------------------------
+%
+% \fi
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% This file is used by
+%
+% source3.tex % documentation including implementation
+%
+% interface3.tex % only interface documentation
+%
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+\begin{abstract}
+
+\setlength\parindent{0pt}
+\setlength\parskip{\baselineskip}
+
+\noindent
+This is the reference documentation for the \pkg{expl3}
+programming environment. The \pkg{expl3} modules set up an experimental
+naming scheme for \LaTeX{} commands, which allow the \LaTeX{} programmer
+to systematically name functions and variables, and specify the argument
+types of functions.
+
+The \TeX{} and \eTeX{} primitives are all given a new name according to
+these conventions. However, in the main direct use of the primitives is
+not required or encouraged: the \pkg{expl3} modules define an
+independent low-level \LaTeX3 programming language.
+
+At present, the \pkg{expl3} modules are designed to be loaded on top of
+\LaTeXe{}. In time, a \LaTeX3 format will be produced based on this code.
+This allows the code to be used in \LaTeXe{} packages \emph{now} while a
+stand-alone \LaTeX3 is developed.
+
+\begin{bfseries}
+ While \pkg{expl3} is still experimental, the bundle is now regarded as
+ broadly stable. The syntax conventions and functions provided are now
+ ready for wider use. There may still be changes to some functions, but
+ these will be minor when compared to the scope of \pkg{expl3}.
+
+ New modules will be added to the distributed version of \pkg{expl3} as
+ they reach maturity.
+\end{bfseries}
+
+\end{abstract}
+
+\clearpage
+
+{%
+ \def\\{:}% fix "newlines" in the ToC
+ \tableofcontents
+}
+
+\clearpage
+\pagenumbering{arabic}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Each of the following \DocInput lines includes a file with extension
+% .dtx. Each of these files may be typeset separately. For instance
+% pdflatex l3box.dtx
+% will typeset the source of the LaTeX3 box commands. If you use the
+% Makefile, the index will be generated automatically; e.g.,
+% make doc F=l3box
+%
+% If this file is processed, each of these separate dtx files will be
+% contained as a part of a single document.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\makeatletter
+\def\partname{Part}
+\def\maketitle{\part{\@title}}
+\let\thanks\@gobble
+\let\DelayPrintIndex\PrintIndex
+\let\PrintIndex\@empty
+\makeatother
+
+\part{Introduction to \pkg{expl3} and this document}
+
+This document is intended to act as a comprehensive reference manual
+for the \pkg{expl3} language. A general guide to the \LaTeX3
+programming language is found in \href{expl3.pdf}{expl3.pdf}.
+
+\section{Naming functions and variables}
+
+\LaTeX3 does not use \texttt{@} as a \enquote{letter} for defining
+internal macros. Instead, the symbols |_| and \texttt{:}
+are used in internal macro names to provide structure. The name of
+each \emph{function} is divided into logical units using \texttt{_},
+while \texttt{:} separates the \emph{name} of the function from the
+\emph{argument specifier} (\enquote{arg-spec}). This describes the arguments
+expected by the function. In most cases, each argument is represented
+by a single letter. The complete list of arg-spec letters for a function
+is referred to as the \emph{signature} of the function.
+
+Each function name starts with the \emph{module} to which it belongs.
+Thus apart from a small number of very basic functions, all \pkg{expl3}
+function names contain at least one underscore to divide the module
+name from the descriptive name of the function. For example, all
+functions concerned with comma lists are in module \texttt{clist} and
+begin \cs{clist_}.
+
+Every function must include an argument specifier. For functions which
+take no arguments, this will be blank and the function name will end
+\texttt{:}. Most functions take one or more arguments, and use the
+following argument specifiers:
+\begin{description}
+ \item[\texttt{D}] The \texttt{D} specifier means \emph{do not use}.
+ All of the \TeX{} primitives are initially \cs{let} to a \texttt{D}
+ name, and some are then given a second name. Only the kernel
+ team should use anything with a \texttt{D} specifier!
+ \item[\texttt{N} and \texttt{n}] These mean \emph{no manipulation},
+ of a single token for \texttt{N} and of a set of tokens given in
+ braces for \texttt{n}. Both pass the argument though exactly as
+ given. Usually, if you use a single token for an \texttt{n} argument,
+ all will be well.
+ \item[\texttt{c}] This means \emph{csname}, and indicates that the
+ argument will be turned into a csname before being used. So
+ So \cs{foo:c} |{ArgumentOne}| will act in the same way as \cs{foo:N}
+ \cs{ArgumentOne}.
+ \item[\texttt{V} and \texttt{v}] These mean \emph{value
+ of variable}. The \texttt{V} and \texttt{v} specifiers are used to
+ get the content of a variable without needing to worry about the
+ underlying \TeX{} structure containing the data. A \texttt{V}
+ argument will be a single token (similar to \texttt{N}), for example
+ \cs{foo:V} \cs{MyVariable}; on the other hand, using \texttt{v} a
+ csname is constructed first, and then the value is recovered, for
+ example \cs{foo:v} |{MyVariable}|.
+ \item[\texttt{o}] This means \emph{expansion once}. In general, the
+ \texttt{V} and \texttt{v} specifiers are favoured over \texttt{o}
+ for recovering stored information. However, \texttt{o} is useful
+ for correctly processing information with delimited arguments.
+ \item[\texttt{x}] The \texttt{x} specifier stands for \emph{exhaustive
+ expansion}: the plain \TeX{} \cs{edef}.
+ \item[\texttt{f}] The \texttt{f} specifier stands for \emph{full
+ expansion}, and in contrast to \emph{x} stops at the first
+ non-expandable item without trying to execute it.
+ \item[\texttt{T} and \texttt{F}] For logic tests, there are the branch
+ specifiers \texttt{T} (\emph{true}) and \texttt{F} (\emph{false}).
+ Both specifiers treat the input in the same way as \texttt{n} (no
+ change), but make the logic much easier to see.
+ \item[\texttt{p}] The letter \texttt{p} indicates \TeX{}
+ \emph{parameters}. Normally this will be used for delimited
+ functions as \pkg{expl3} provides better methods for creating simple
+ sequential arguments.
+ \item[\texttt{w}] Finally, there is the \texttt{w} specifier for
+ \emph{weird} arguments. This covers everything else, but mainly
+ applies to delimited values (where the argument must be terminated
+ by some arbitrary string).
+\end{description}
+Notice that the argument specifier describes how the argument is
+processed prior to being passed to the underlying function. For example,
+\cs{foo:c} will take its argument, convert it to a control sequence and
+pass it to \cs{foo:N}.
+
+Variables are named in a similar manner to functions, but begin with
+a single letter to define the type of variable:
+\begin{description}
+ \item[\texttt{c}] Constant: global parameters whose value should not
+ be changed.
+ \item[\texttt{g}] Parameters whose value should only be set globally.
+ \item[\texttt{l}] Parameters whose value should only be set locally.
+\end{description}
+Each variable name is then build up in a similar way to that of a
+function, typically starting with the module\footnote{The module names are
+ not used in case of generic scratch registers defined in the data
+ type modules, e.g., the
+ \texttt{int} module contains some scratch variables called \cs{l_tmpa_int},
+ \cs{l_tmpb_int}, and so on. In such a case adding the module name up front
+ to denote the module
+ and in the back to indicate the type, as in
+ \cs{l_int_tmpa_int} would be very unreadable.} name
+and then a descriptive part.
+Variables end with a short identifier to show the variable type:
+\begin{description}
+ \item[\texttt{bool}] Either true or false.
+ \item[\texttt{box}] Box register.
+ \item[\texttt{clist}] Comma separated list.
+ \item[\texttt{dim}] \enquote{Rigid} lengths.
+ \item[\texttt{int}] Integer-valued count register.
+ \item[\texttt{prop}] Property list.
+ \item[\texttt{skip}] \enquote{Rubber} lengths.
+ \item[\texttt{seq}] \enquote{Sequence}: a data-type used to implement lists
+ (with access at both ends) and stacks.
+ \item[\texttt{stream}] An input or output stream (for reading from or
+ writing to, respectively).
+ \item[\texttt{tl}] Token list variables: placeholder for a token list.
+ \item[\texttt{toks}] Token register.
+\end{description}
+
+\subsection{Terminological inexactitude}
+
+A word of warning. In this document, and others referring to the \pkg{expl3}
+programming modules, we often refer to \enquote{variables} and
+\enquote{functions} as if they
+were actual constructs from a real programming language. In truth, \TeX{}
+is a macro processor, and functions are simply macros that may or may not take
+arguments and expand to their replacement text. Many of the common variables
+are \emph{also} macros, and if placed into the input stream will simply expand
+to their definition as well~--- a \enquote{function} with no arguments and a
+\enquote{token list variable} are in truth one and the same. On the other
+hand, some \enquote{variables} are actually registers that must be
+initialised and their values set and retrieved with specific functions.
+
+The conventions of the \pkg{expl3} code are designed to clearly separate the
+ideas of \enquote{macros that contain data} and
+\enquote{macros that contain code}, and a
+consistent wrapper is applied to all forms of \enquote{data} whether they be
+macros or
+actually registers. This means that sometimes we will use phrases like
+\enquote{the function returns a value}, when actually we just mean
+\enquote{the macro expands to something}. Similarly, the term
+\enquote{execute} might be used in place of \enquote{expand}
+or it might refer to the more specific case of
+\enquote{processing in \TeX's stomach}
+(if you are familiar with the \TeX{}book parlance).
+
+If in doubt, please ask; chances are we've been hasty in writing certain
+definitions and need to be told to tighten up our terminology.
+
+\section{Documentation conventions}
+
+This document is typeset with the experimental \pkg{l3doc} class;
+several conventions are used to help describe the features of the code.
+A number of conventions are used here to make the documentation clearer.
+
+Each group of related functions is given in a box. For a function with
+a \enquote{user} name, this might read:
+\begin{function}{\ExplSyntaxOn, \ExplSyntaxOff}
+ \begin{syntax}
+ \cs{ExplSyntaxOn} \dots{} \cs{ExplSyntaxOff}
+ \end{syntax}
+ The textual description of how the function works would appear here. The
+ syntax of the function is shown in mono-spaced text to the right of
+ the box. In this example, the function takes no arguments and so the
+ name of the function is simply reprinted.
+\end{function}
+
+For programming functions, which use \texttt{_} and \texttt{:} in their name
+there are a few additional conventions: If two related functions are given
+with identical names but different argument specifiers, these are termed
+\emph{variants} of each other, and the latter functions are printed in grey to
+show this more clearly. They will carry out the same function but will take
+different types of argument:
+\begin{function}{\seq_new:N, \seq_new:c}
+ \begin{syntax}
+ \cs{seq_new:N} \meta{sequence}
+ \end{syntax}
+ When a number of variants are described, the arguments are usually
+ illustrated only for the base function. Here, \meta{sequence} indicates
+ that \cs{seq_new:N} expects the name of a sequence. From the argument
+ specifier, \cs{seq_new:c} also expects a sequence name, but as a
+ name rather than as a control sequence. Each argument given in the
+ illustration should be described in the following text.
+\end{function}
+
+Some functions are fully expandable, which allows it to be used within
+an \texttt{x}-type argument (in plain \TeX{} terms, inside an \cs{edef}).
+These fully expandable functions are indicated in the documentation by
+a star:
+\begin{function}[EXP]{\cs_to_str:N}
+ \begin{syntax}
+ \cs{cs_to_str:N} \meta{cs}
+ \end{syntax}
+ As with other functions, some text should follow which explains how
+ the function works. Usually, only the star will indicate that the
+ function is expandable. In this case, the function expects a \meta{cs},
+ shorthand for a \meta{control sequence}.
+\end{function}
+
+Conditional (\texttt{if}) functions are normally defined in three variants,
+with
+\texttt{T}, \texttt{F} and \texttt{TF} argument specifiers. This allows
+them to be used for different \enquote{true}/\enquote{false} branches,
+depending on
+which outcome the conditional is being used to test. To indicate this
+without repetition, this information is given in a shortened form:
+\begin{function}[EXP,pTF]{\xetex_if_engine:}
+ \begin{syntax}
+ \cs{xetex_if_engine:TF} \Arg{true code} \Arg{false code}
+ \end{syntax}
+ The underlining and italic of \texttt{TF} indicates that
+ \cs{xetex_if_engine:T}, \cs{xetex_if_engine:F} and
+ \cs{xetex_if_engine:TF} are all available. Usually, the illustration
+ will use the \texttt{TF} variant, and so both \meta{true code}
+ and \meta{false code} will be shown. The two variant forms \texttt{T} and
+ \texttt{F} take only \meta{true code} and \meta{false code}, respectively.
+ Here, the star also shows that this function is expandable.
+ With some minor exceptions, \emph{all} conditional functions in the
+ \pkg{expl3} modules should be defined in this way.
+\end{function}
+
+Variables, constants and so on are described in a similar manner:
+\begin{variable}{\l_tmpa_tl}
+ A short piece of text will describe the variable: there is no
+ syntax illustration in this case.
+\end{variable}
+
+In some cases, the function is similar to one in \LaTeXe{} or plain \TeX{}.
+In these cases, the text will include an extra \enquote{\textbf{\TeX{}hackers
+note}} section:
+\begin{function}[EXP]{\token_to_str:N}
+ \begin{syntax}
+ \cs{token_to_str:N} \meta{token}
+ \end{syntax}
+ The normal description text.
+ \begin{texnote}
+ Detail for the experienced \TeX{} or \LaTeXe\ programmer. In this
+ case, it would point out that this function is the \TeX{} primitive
+ \cs{string}.
+ \end{texnote}
+\end{function}
+
+\DisableImplementation
+
+\DocInput{l3bootstrap.dtx}
+\DocInput{l3names.dtx}
+\DocInput{l3basics.dtx}
+\DocInput{l3expan.dtx}
+\DocInput{l3prg.dtx}
+\DocInput{l3quark.dtx}
+\DocInput{l3token.dtx}
+\DocInput{l3int.dtx}
+\DocInput{l3skip.dtx}
+\DocInput{l3tl.dtx}
+\DocInput{l3seq.dtx}
+\DocInput{l3clist.dtx}
+\DocInput{l3prop.dtx}
+\DocInput{l3box.dtx}
+\DocInput{l3io.dtx}
+\DocInput{l3msg.dtx}
+\DocInput{l3keyval.dtx}
+\DocInput{l3keys.dtx}
+\DocInput{l3file.dtx}
+\DocInput{l3fp.dtx}
+\DocInput{l3luatex.dtx}
+
+\endinput
diff --git a/Master/texmf-dist/makeindex/l3kernel/l3doc.ist b/Master/texmf-dist/makeindex/l3kernel/l3doc.ist
new file mode 100644
index 00000000000..e1496e34d73
--- /dev/null
+++ b/Master/texmf-dist/makeindex/l3kernel/l3doc.ist
@@ -0,0 +1,72 @@
+%%
+%% This is file `l3doc.ist',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% l3doc.dtx (with options: `docist')
+%%
+%%
+%% EXPERIMENTAL CODE
+%%
+%% Do not distribute this file without also distributing the
+%% source files specified above.
+%%
+%% Do not distribute a modified version of this file.
+%%
+%%
+%% File: l3doc.dtx Copyright (C) 1990-2011 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 "expl3 bundle" (The Work in LPPL)
+%% and all files in that bundle must be distributed together.
+%%
+%% The released version of this bundle is available from CTAN.
+%%
+%% -----------------------------------------------------------------------
+%%
+%% The development version of the bundle can be found at
+%%
+%% http://www.latex-project.org/svnroot/experimental/trunk/
+%%
+%% for those people who are interested.
+%%
+%%%%%%%%%%%
+%% NOTE: %%
+%%%%%%%%%%%
+%%
+%% Snapshots taken from the repository represent work in progress and may
+%% not work or may contain conflicting material! We therefore ask
+%% people _not_ to put them into distributions, archives, etc. without
+%% prior consultation with the LaTeX3 Project.
+%%
+%% -----------------------------------------------------------------------
+actual '='
+quote '!'
+level '#'
+preamble
+"\n \\begin{theindex} \n \\makeatletter\\scan@allowedfalse\n"
+postamble
+"\n\n \\end{theindex}\n"
+item_x1 "\\efill \n \\subitem "
+item_x2 "\\efill \n \\subsubitem "
+delim_0 "\\pfill "
+delim_1 "\\pfill "
+delim_2 "\\pfill "
+lethead_prefix "{\\bfseries\\hfil "
+lethead_suffix "\\hfil}\\nopagebreak\n"
+lethead_flag 1
+heading_prefix "{\\bfseries\\hfil "
+heading_suffix "\\hfil}\\nopagebreak\n"
+headings_flag 1
+
+page_precedence "rnaA"
+%%
+%%
+%% End of file `l3doc.ist'.
diff --git a/Master/texmf-dist/source/latex/l3kernel/expl3.dtx b/Master/texmf-dist/source/latex/l3kernel/expl3.dtx
new file mode 100644
index 00000000000..443c87b3916
--- /dev/null
+++ b/Master/texmf-dist/source/latex/l3kernel/expl3.dtx
@@ -0,0 +1,1099 @@
+% \iffalse meta-comment
+%
+%% File: expl3.dtx Copyright (C) 1990-2011 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 "expl3 bundle" (The Work in LPPL)
+%% and all files in that bundle must be distributed together.
+%%
+%% The released version of this bundle is available from CTAN.
+%%
+%% -----------------------------------------------------------------------
+%%
+%% The development version of the bundle can be found at
+%%
+%% http://www.latex-project.org/svnroot/experimental/trunk/
+%%
+%% for those people who are interested.
+%%
+%%%%%%%%%%%
+%% NOTE: %%
+%%%%%%%%%%%
+%%
+%% Snapshots taken from the repository represent work in progress and may
+%% not work or may contain conflicting material! We therefore ask
+%% people _not_ to put them into distributions, archives, etc. without
+%% prior consultation with the LaTeX3 Project.
+%%
+%% -----------------------------------------------------------------------
+%
+%<*driver|package>
+\RequirePackage{l3names}
+\GetIdInfo$Id: expl3.dtx 2478 2011-06-19 21:34:23Z joseph $
+ {L3 Experimental code bundle wrapper}
+%</driver|package>
+%<*driver>
+\documentclass[full]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \providecommand\acro[1]{\textsc{\MakeLowercase{#1}}}
+% \newenvironment{arg-description}{%
+% \begin{itemize}\def\makelabel##1{\hss\llap{\bfseries##1}}}{\end{itemize}}
+%
+% \title{^^A
+% The \textsf{expl3} package and \LaTeX3 programming^^A
+% \thanks{This file describes v\ExplFileVersion,
+% last revised \ExplFileDate.}^^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 \ExplFileDate}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% \begin{abstract}
+%
+% This document gives an introduction to a new set of programming
+% conventions that have been designed to meet the requirements of
+% implementing large scale \TeX{} macro programming projects such as
+% \LaTeX{}. These programming conventions are the base layer of \LaTeX3.
+%
+% The main features of the system described are:
+% \begin{itemize}
+% \item classification of the macros (or, in \LaTeX{} terminology,
+% commands) into \LaTeX{} functions and \LaTeX{} parameters, and also
+% into modules containing related commands;
+% \item a systematic naming scheme based on these classifications;
+% \item a simple mechanism for controlling the expansion of a function's
+% arguments.
+% \end{itemize}
+% This system is being used as the basis for \TeX{} programming within
+% the \LaTeX3 project. Note that the language is not intended for either
+% document mark-up or style specification. Instead, it is intended that
+% such features will be built on top of the conventions described here.
+%
+% This document is an introduction to the ideas behind the \pkg{expl3}
+% programming interface. For the complete documentation of the programming
+% layer provided by the \LaTeX3 Project, see the accompanying \texttt{source3}
+% document.
+%
+% \end{abstract}
+%
+% \section{Introduction}
+%
+% The first step to develop a \LaTeX{} kernel beyond \LaTeXe{} is to
+% address how the underlying system is programmed. Rather than the
+% current mix of \LaTeX{} and \TeX{} macros, the \LaTeX3 system provides
+% its own consistent interface to all of the functions needed to
+% control \TeX{}. A key part of this work is to ensure that everything
+% is documented, so that \LaTeX{} programmers and users can work
+% efficiently without needing to be familiar with the internal nature
+% of the kernel or with plain \TeX{}.
+%
+% The \pkg{expl3} bundle provides this new programming interface for
+% \LaTeX. To make programming systematic, \LaTeX3 uses some very
+% different conventions to \LaTeXe{} or plain TeX{}. As a result,
+% programmers starting with \LaTeX3 will need to become familiar with
+% the syntax of the new language.
+%
+% The next section shows where this language fits into a complete
+% \TeX{}-based document processing system. We then describe the major
+% features of the syntactic structure of command names, including the
+% argument specification syntax used in function names.
+%
+% The practical ideas behind this argument syntax will be explained,
+% together with the expansion control mechanism and the interface
+% used to define variant forms of functions.
+%
+% As we shall demonstrate, the use of a structured naming scheme and of
+% variant forms for functions greatly improves the readability of the
+% code and hence also its reliability. Moreover, experience has shown
+% that the longer command names which result from the new syntax do not
+% make the process of \emph{writing} code significantly harder.
+%
+% \section{Languages and interfaces}
+%
+% It is possible to identify several distinct languages related to the
+% various interfaces that are needed in a \TeX{}-based document processing
+% system. This section looks at those we consider most important for
+% the \LaTeX3 system.
+%
+% \begin{description}
+% \item[Document mark-up] This comprises those commands (often called
+% tags) that are to embedded in the document (the |.tex| file).
+%
+% It is generally accepted that such mark-up should be essentially
+% \emph{declarative}. It may be traditional \TeX{}-based mark-up such
+% as \LaTeXe{}, as described in~\cite{A-W:LLa94} and~\cite{A-W:GMS94},
+% or a mark-up language defined via \acro{HTML} or \acro{XML}.
+%
+% One problem with more traditional \TeX{} coding conventions (as
+% described in~\cite{A-W:K-TB}) is that the names and syntax of \TeX{}'s
+% primitive formatting commands are ingeniously designed to be
+% \enquote{natural} when used directly by the author as document mark-up or in
+% macros. Ironically, the ubiquity (and widely recognised
+% superiority) of logical mark-up has meant that such explicit
+% formatting commands are almost never needed in documents or in
+% author-defined macros. Thus they are used almost exclusively by
+% \TeX{} programmers to define higher-level commands, and their
+% idiosyncratic syntax is not at all popular with this community.
+% Moreover, many of them have names that could be very useful as
+% document mark-up tags were they not pre-empted as primitives
+% (\emph{e.g.}~\cs{box} or \cs{special}).
+%
+% \item[Designer interface] This relates a (human) typographic
+% designer's specification for a document to a program that
+% \enquote{formats
+% the document}. It should ideally use a declarative language that
+% facilitates expression of the relationship and spacing rules
+% specified for the layout of the various document elements.
+%
+% This language is not embedded in document text and it will be very
+% different in form to the document mark-up language. For \LaTeX,
+% this level was almost completely missing from \LaTeX2.09; \LaTeXe{}
+% made some improvements in this area but it is still the case that
+% implementing a design specification in \LaTeX{} requires far more
+% \enquote{low-level} coding than is acceptable.
+%
+% \item[Programmer interface]
+% This language is the implementation language within which the
+% basic typesetting functionality is implemented, building upon the
+% primitives of \TeX{} (or a successor program). It may also be used
+% to implement the previous two languages \enquote{within} \TeX{}, as in
+% the
+% current \LaTeX{} system.
+%
+% \end{description}
+%
+% The last layer is covered by the conventions described in this
+% document, which describes a system aimed at providing a suitable
+% basis for coding \LaTeX3. Its main distinguishing features are
+% summarised here:
+% \begin{itemize}
+% \item A consistent naming scheme for all commands, including \TeX{}
+% primitives.
+% \item The classification of commands as \LaTeX{} functions or \LaTeX{}
+% parameters, and also their division into modules according to their
+% functionality.
+% \item A simple mechanism for controlling argument expansion.
+% \item Provision of a set of core \LaTeX{} functions that is sufficient
+% for handling programming constructs such as queues, sets, stacks,
+% property lists.
+% \item A \TeX{} programming environment in which, for example, all
+% white space is ignored.
+% \end{itemize}
+%
+% \section{The naming scheme}
+%
+% \LaTeX3 does not use |@| as a \enquote{letter} for defining
+% internal macros. Instead, the symbols |_| and |:|
+% are used in internal macro names to provide structure. In
+% contrast to the plain \TeX{} format and the \LaTeXe{} kernel, these
+% extra letters are used only between parts of a macro name (no
+% strange vowel replacement).
+%
+% While \TeX{} is actually a macro processor, by
+% convention for the \pkg{expl3} programming language we distinguish between
+% \emph{functions} and \emph{variables}. Functions can have arguments and they
+% are either expanded or executed. Variables can be assigned values and they
+% are used in arguments to functions; they are not used directly but are
+% manipulated by functions (including getting and setting functions).
+% Functions and variables with a related functionality (for example accessing
+% counters, or manipulating token lists, \emph{etc.})\ are collected together
+% into a
+% \emph{module}.
+%
+% \subsection{Examples}
+%
+% Before giving the details of the naming scheme, here are a few typical
+% examples to indicate the flavour of the scheme; first some variable
+% names.
+% \begin{quote}
+% \cs{l_tmpa_box} is a local variable (hence the~|l_| prefix)
+% corresponding to a box register.\\
+% \cs{g_tmpa_int} is a global variable (hence the~|g_| prefix)
+% corresponding to an integer register (i.e.~a \TeX{} count
+% register).\\
+% \cs{c_empty_tl} is the constant~(|c_|) token list variable
+% that is always empty.
+% \end{quote}
+%
+% Now here is an example of a typical function name.
+%
+% \cs{seq_push:Nn} is the function which puts the token list specified
+% by its second argument onto the stack specified by its first argument.
+% The different natures of the two arguments are indicated by the~|:Nn|
+% suffix. The first argument must be a single token which \enquote{names}
+% the stack parameter: such single-token arguments are denoted~|N|.
+% The second argument is a normal \TeX{} \enquote{undelimited argument},
+% which
+% may either be a single token or a balanced, brace-delimited token
+% list (which we shall here call a \textit{braced token list}): the~|n|
+% denotes such a \enquote{normal} argument form. The name of the function
+% indicates it belongs to the |seq| module.
+%
+% \subsection{Formal naming syntax}
+%
+% We shall now look in more detail at the syntax of these names. A
+% function name in \LaTeX3 will have a name consisting of three parts:
+% \begin{quote}
+% |\|\meta{module}|_|\meta{description}|:|\meta{arg-spec}
+% \end{quote}
+% while a variable will have (up to) four distinct parts to its name:
+% \begin{quote}
+% |\|\meta{scope}|_|\meta{module}|_|\meta{description}|_|\meta{type}
+% \end{quote}
+%
+% The syntax of all names contains
+% \begin{quote}
+% \meta{module} and \meta{description}
+% \end{quote}
+% these both give information about the command.
+%
+% A \emph{module} is a collection of closely related functions and
+% variables. Typical module names include~|int| for integer parameters
+% and related functions,~|seq| for sequences and~|box| for boxes.
+%
+% Packages providing new programming functionality will add new modules
+% as needed; the programmer can choose any unused name, consisting
+% of letters only, for a module. In general, the module name and module
+% prefix should be related: for example, the kernel module containing
+% \texttt{box} functions is called \texttt{l3box}.
+%
+% The \emph{description} gives more detailed information about the
+% function or parameter, and provides a unique name for it. It should
+% consist of letters and, possibly,~|_|~characters. In general, the
+% description should use |_| to divide up \enquote{words} or other easy to
+% follow parts of the name. For example, the \LaTeX3 kernel provides
+% \cs{if_cs_exist:N} which, as might be expected, tests if a command
+% name exists.
+%
+% As a semi-formalized concept the letter |g| is sometimes used to
+% prefix certain parts of the \meta{description}
+% to mark the function as \enquote{globally acting}, \emph{e.g.},
+% \cs{int_set:Nn} is
+% a local operation while \cs{int_gset:Nn} is a global operation. This
+% of course goes hand in hand with when to use |l_| and |g_|
+% variable prefixes.
+%
+ %\subsubsection{Variables: scope and type}
+%
+% The \meta{scope} part of the name describes how the variable can be
+% accessed. Variables are classified as local, global or constant.
+% This \emph{scope} type appears as a code at the beginning of the name;
+% the codes used are:
+% \begin{arg-description}
+% \item[c] constants (global variables whose value should not be
+% changed);
+% \item[g] variables whose value should only be set globally;
+% \item[l] variables whose value should only be set locally.
+% \end{arg-description}
+%
+% Separate functions are provided to assign data to local and global
+% variables; for example, |\tl_set:Nn| and |\tl_gset:Nn| respectively
+% set the value of a local or global \enquote{token list} variable.
+% Note that it is a poor \TeX{} practise to intermix local and global
+% assignments to a variable; otherwise you risk exhausting the save stack.
+% \unskip\footnote{See \emph{The \TeX{}book}, p.\,301, for further
+% information.}
+%
+% The \meta{type} will be in the list of available
+% \emph{data-types};\footnote{Of course, if a totally new data type is
+% needed then this will not be the case. However, it is hoped that only
+% the kernel team will need to create new data types.} these include the
+% primitive \TeX{} data-types, such as the various registers, but to
+% these will be added data-types built within the \LaTeX{} programming
+% system.
+%
+% The data types in \LaTeX3 are:
+% \begin{description}
+% \item[bool] either true or false (the \LaTeX3 implementation does
+% not use \cs{iftrue} or \cs{iffalse});
+% \item[box] box register;
+% \item[clist] comma separated list;
+% \item[coffin] a \enquote{box with handles} --- a higher-level data
+% type for carrying out |box| alignment operations;
+% \item[dim] \enquote{rigid} lengths;
+% \item[fp] floating-point values;
+% \item[int] integer-valued count register;
+% \item[prop] property list;
+% \item[seq] sequence: a data-type used to implement lists (with
+% access at both ends) and stacks;
+% \item[skip] \enquote{rubber} lengths;
+% \item[stream] an input or output stream (for reading from or writing
+% to, respectively);
+% \item[tl] \enquote{token list variables}: placeholders for token lists.
+% \end{description}
+% When the \meta{type} and \meta{module} are identical (as often happens in
+% the more basic modules) the \meta{module} part is often omitted for
+% aesthetic reasons.
+%
+% The name \enquote{token list} may cause confusion, and so some background is
+% useful. \TeX{} works with tokens and lists of tokens, rather than
+% characters. It provides two ways to store these token lists: within
+% macros and as token registers (|toks|). The implementation in \LaTeX3 means
+% that
+% |toks| are not required, and that all operations for storing tokens can us
+% the |tl| variable type.
+%
+% Experienced \TeX{} programmers will notice that some of the variable
+% types listed are native \TeX{} registers whilst others are not. In
+% general, the underlying \TeX{} implementation for a data structure may
+% vary but the \emph{documented interface} will be stable. For example,
+% the |prop| data type was originally implemented as a |toks|, but
+% is currently built on top of the |tl| data structure.
+%
+% \subsubsection{Variables: guidance}
+%
+% Although \TeX{} provides token registers for certain programming
+% tasks, \LaTeX3 is written so that token list variables can be used
+% for all stored lists of tokens. The \cs{toks_\ldots} functions are
+% therefore for internal use within \LaTeX3 and for supporting
+% \LaTeXe, and should not be needed in new \LaTeX3-based code.
+%
+% Both comma lists and sequences both have similar characteristics.
+% They both use special delimiters to mark out one entry from the
+% next, and are both accessible at both ends. In general, it is
+% easier to create comma lists `by hand' as they can be typed
+% in directly. User input often takes the form of a comma separated
+% list and so there are many cases where this is the obvious
+% data type to use. On the other hand, sequences use special internal
+% tokens to separate entries. This means that they can be used to
+% contain material that comma lists cannot (such as items that may
+% themselves contain commas!). In general, comma lists should be
+% preferred for creating fixed lists inside programs and for
+% handling user input where commas will not occur. On the other
+% hand, sequences should be used to store arbitrary lists of
+% data.
+%
+% \pkg{expl3} implements stacks using the sequence data structure.
+% Thus creating stacks involves first creating a sequence, and
+% then using the sequence functions which work in a stack manner
+% (\cs{seq_push:Nn}, \emph{etc}.).
+%
+% Due to the nature of the underlying \TeX{} implementation, it is
+% possible to assign values to token list variables and comma lists
+% without first declaring them. However, this is \emph{not supported
+% behaviour}. The \LaTeX3 coding convention is that all variables must
+% be declared before use.
+%
+% The \pkg{expl3} package can be loaded with the |check-declarations| option
+% to verify that all variables are declared before use. This has a
+% performance implication and is therefore intended for testing during
+% development and not for use in production documents.
+%
+% \subsubsection{Functions: argument specifications}
+%
+% Function names end with an \meta{arg-spec} after a colon. This
+% gives an indication of the types of argument that a function takes,
+% and provides a convenient method of naming similar functions that
+% differ only in their argument forms (see the next section for
+% examples).
+%
+% The \meta{arg-spec} consists of a (possibly empty) list of letters,
+% each denoting one argument of the function. The letter, including
+% its case, conveys information about the type of argument required.
+%
+% All functions have a base form with arguments using one of the
+% following argument specifiers:
+% \begin{arg-description}
+% \item[n] Unexpanded token or braced token list.\\
+% This is a standard \TeX{} undelimited macro argument.
+% \item[N] Single token (unlike~|n|, the argument must \emph{not} be
+% surrounded by braces).\\
+% A typical example of a command taking an~|N|
+% argument is~|\cs_set|, in which the command being defined must be
+% unbraced.
+% \item[p] Primitive \TeX{} parameter specification.\\
+% This can be something simple like~|#1#2#3|, but may use arbitrary
+% delimited argument syntax such as: |#1,#2\q_stop#3|. This is used
+% when defining functions.
+% \item[T,F]
+% These are special cases of~|n| arguments, used for the
+% true and false code in conditional commands.
+% \end{arg-description}
+% There are two other specifiers with more general meanings:
+% \begin{arg-description}
+% \item[D] This means: \textbf{Do not use}. This special case is used
+% for \TeX{} primitives and other commands that are provided for use
+% only while bootstrapping the \LaTeX{} kernel. Programmers outside
+% the kernel team should not use these functions!
+% \item[w] This means that the argument syntax is \enquote{weird} in that it
+% does not follow any standard rule. It is used for functions with
+% arguments that take non standard forms: examples are \TeX-level
+% delimited arguments and the boolean tests needed after certain
+% primitive |\if|\ldots\ commands.
+% \end{arg-description}
+%
+% In case of |n| arguments that consist of a single token the
+% surrounding braces can be omitted in nearly all
+% situations---functions that force the use of braces even for single
+% token arguments are explicitly mentioned. However, programmers are
+% encouraged to always use braces around \texttt{n} arguments, as this
+% makes the relationship between function and argument clearer.
+%
+% Further argument specifiers are available as part of the expansion
+% control system. These are discussed in the next section.
+%
+% \section{Expansion control}
+%
+% Let's take a look at some typical operations one might want to
+% perform. Suppose we maintain a stack of open files and we use the
+% stack |\g_ior_file_name_seq| to keep track of them (|io| is the
+% file reading and writing module: it uses the module prefix
+% \texttt{ior} for reading functions and variables). The basic
+% operation here is to push a name onto this stack which could be
+% done by the operation
+% \begin{quote}
+% |\seq_gpush:Nn \g_ior_file_name_seq {#1}|
+% \end{quote}
+% where |#1| is the filename. In other words, this operation would
+% push the file name as is onto the stack.
+%
+% However, we might face a situation where the filename is stored in
+% a variable of some sort, say |\l_ior_curr_file_tl|. In this case we
+% want to retrieve the value of the variable. If we simply use
+% \begin{quote}
+% |\seq_gpush:Nn \g_io_file_name_seq \l_io_curr_file_tl|
+% \end{quote}
+% we will not get the value of the variable pushed onto the stack,
+% only the variable name itself. Instead a suitable number of
+% |\exp_after:wN| would be necessary (together with extra braces) to
+% change the order of expansion,\footnote{\cs{exp_after:wN} is
+% the \LaTeX3 name for the \TeX{} \cs{expandafter} primitive.}, \emph{i.e.}
+% \begin{quote}
+% |\exp_after:wN| \\
+% | \seq_gpush:Nn| \\
+% |\exp_after:wN| \\
+% | \g_io_file_name_seq| \\
+% |\exp_after:wN| \\
+% | { \l_io_curr_file_tl }|
+% \end{quote}
+%
+% The above example is probably the simplest case but already shows
+% how the code changes to something difficult to understand.
+% Furthermore there is an assumption in this: that the storage bin
+% reveals its contents after exactly one expansion. Relying on this
+% means that you cannot do proper checking plus you have to know
+% exactly how a storage bin acts in order to get the correct number
+% of expansions. Therefore \LaTeX3 provides the programmer with a
+% general scheme that keeps the code compact and easy to understand.
+%
+% To denote that some argument to a function needs special treatment one
+% just uses different letters in the arg-spec part of the function to
+% mark the desired behaviour. In the above example one would write
+% \begin{quote}
+% |\seq_gpush:NV \g_io_file_name_seq \l_io_curr_file_tl|
+% \end{quote}
+% to achieve the desired effect. Here the |V| (the second argument)
+% is for \enquote{retrieve the value of the variable} before passing it to
+% the base function.
+%
+% The following letters can be used to denote special treatment of
+% arguments before passing it to the base function:
+% \begin{description}
+% \item[c] Character string used as a command name.\\ The argument (a
+% token or braced token list) must, when fully expanded, produce a
+% sequence of characters which is then used to construct a command
+% name (\emph{via}~|\csname| \ldots |\endcsname|). This command name is the
+% single token that is passed to the function as the argument. Hence
+% \begin{quote}
+% |\seq_gpush:cV { g_file_name_seq } \l_tmpa_tl|
+% \end{quote}
+% is equivalent to
+% \begin{quote}
+% |\seq_gpush:NV \g_file_name_seq \l_tmpa_tl"|
+% \end{quote}
+% Remember that \texttt{c} arguments are \emph{fully expanded} by
+% \TeX{} when creating csnames. This means that (a) the entire
+% argument must be expandable and (b) any variables will be
+% converted to their content. So the preceding examples are also
+% equivalent to
+% \begin{quote}
+% |\tl_new:N \g_file_seq_name_tl| \\
+% |\tl_gset:Nn \g_file_seq_name_tl { g_file_name_seq }| \\
+% |\seq_gpush:cV { \g_file_seq_name_tl } \l_tmpa_tl|.
+% \end{quote}
+% (Token list variables are expandable and do not require an
+% accessor function. Other variable types require the appropriate
+% \cs{<var>_use:N} functions to be used in this context.)
+% \item[V] Value of a variable.\\
+% This means that the contents of the register in question is used as the
+% argument, be it an integer, a length-type register, a token list variable
+% or similar. The value is passed to the function as a braced token list.
+% \item[v] Value of a register, constructed from a character string
+% used as a command name.\\
+% This is a combination of |c| and |V| which first constructs a
+% control sequence from the argument and then passes the value of the
+% resulting register to the function.
+% \item[x] Fully-expanded token or braced token list.\\
+% This means that the argument is expanded as in the replacement
+% text of an~|\edef|, and the expansion is passed to the function as
+% a braced token list. This means that expansion takes place until
+% only unexpandable tokens are left.
+% \item[o] One-level-expanded token or braced token list.\\
+% This means that the argument is expanded one level, as by
+% \cs{expandafter}, and the expansion is passed to the function as a
+% braced token list. Note that if the original argument is a braced
+% token list then only the first token in that list is expanded.
+% In general, using \texttt{V} should be preferred to using
+% \texttt{o} for simple variable retrieval.
+% \item[f] Almost the same as the |x| type except here the token list
+% is expanded fully until the first unexpandable token is found and
+% the rest is left unchanged. Note that if this function finds a
+% space at the beginning of the argument it will gobble it and not
+% expand the next argument.
+% \end{description}
+%
+% \subsection{Simpler means better}
+%
+% Anyone who programs in \TeX{} is frustratingly familiar with the
+% problem of arranging that arguments to functions are suitably expanded
+% before the function is called. To illustrate how expansion control
+% can bring instant relief to this problem we shall consider two
+% examples copied from \texttt{latex.ltx}.
+%
+% \begin{verbatim}
+% \global\expandafter\let
+% \csname\cf@encoding \string#1\expandafter\endcsname
+% \csname ?\string#1\endcsname
+% \end{verbatim}
+% This first piece of code is in essence simply a global |\let| whose
+% two arguments firstly have to be constructed before |\let| is
+% executed. The |#1| is a control sequence name such as
+% |\textcurrency|. The token to be defined is obtained by
+% concatenating the characters of the current font encoding stored in
+% |\cf@encoding|, which has to be fully expanded, and the name of the
+% symbol. The second token is the same except it uses the default
+% encoding |?|. The result is a mess of interwoven |\expandafter|
+% and |\csname| beloved of all \TeX{} programmers, and the code is
+% essentially unreadable.
+%
+% Using the conventions and functionality outlined here, the task would
+% be achieved with code such as this:
+% \begin{verbatim}
+% \cs_gset_eq:cc
+% { \cf@encoding \token_to_str:N #1 } { ? \token_to_str:N #1 }
+% \end{verbatim}
+% The command |\cs_gset_eq:cc| is a global~|\let| that generates
+% command names out of both of its arguments before making the
+% definition. This produces code that is far more readable and more
+% likely to be correct first time. (\cs{token_to_str:N} is the \LaTeX3
+% name for \cs{string}.)
+%
+% Here is the second example.
+% \begin{verbatim}
+% \expandafter
+% \in@
+% \csname sym#3%
+% \expandafter
+% \endcsname
+% \expandafter
+% {%
+% \group@list}%
+% \end{verbatim}
+% This piece of code is part of the definition of another function. It
+% first produces two things: a token list, by expanding |\group@list| once;
+% and a token whose name comes from~`|sym#3|'. Then the function~|\in@|
+% is called and this tests if its first argument occurs in the token list
+% of its second argument.
+%
+% Again we can improve enormously on the code. First we shall rename
+% the function~|\in@| according to our conventions. A function such as
+% this but taking two normal \enquote{\texttt{n}} arguments might reasonably be
+% named |\seq_test_in:Nn|; thus the variant function we need will be
+% defined with the appropriate argument types and its name will be
+% |\seq_test_in:cV|. Now this code fragment will be simply:
+% \begin{verbatim}
+% \seq_test_in:cV { sym #3 } \l_group_seq
+% \end{verbatim}
+% Note that, in addition to the lack of |\expandafter|, the space after
+% the~|}| will be silently ignored since all white space is ignored in
+% this programming environment.
+%
+% \subsection{New functions from old}
+%
+% For many common functions the \LaTeX3 kernel will provide variants
+% with a range of argument forms, and similarly it is expected that
+% extension packages providing new functions will make them available in
+% the all the commonly needed forms.
+%
+% However, there will be occasions where it is necessary to construct a
+% new such variant form; therefore the expansion module provides a
+% straightforward mechanism for the creation of functions with any
+% required argument type, starting from a function that takes \enquote{normal}
+% \TeX{} undelimited arguments.
+%
+% To illustrate this let us suppose you have a \enquote{base function}
+% |\demo_cmd:Nnn| that takes three normal arguments, and that you need
+% to construct the variant |\demo_cmd:cnx|, for which the first argument
+% is used to construct the \emph{name} of a command, whilst the third
+% argument must be fully expanded before being passed to
+% |\demo_cmd:Nnn|.
+% To produce the variant form from the base form, simply use this:
+% \begin{verbatim}
+% \cs_generate_variant:Nn \demo_cmd:Nnn { cnx }
+% \end{verbatim}
+% This defines the variant form so that you can then write, for example:
+% \begin{verbatim}
+% \demo_cmd:cnx { abc } { pq } { \rst \xyz }
+% \end{verbatim}
+% rather than \ldots\ well, something like this!
+% \begin{verbatim}
+% \def \tempa {{pq}}%
+% \edef \tempb {\rst \xyz}%
+% \expandafter
+% \demo@cmd:nnn
+% \csname abc%
+% \expandafter
+% \expandafter
+% \expandafter
+% \endcsname
+% \expandafter
+% \tempa
+% \expandafter
+% {%
+% \tempb
+% }%
+% \end{verbatim}
+%
+% Another example: you may wish to declare a function
+% |\demo_cmd_b:xcxcx|, a variant of an existing function
+% |\demo_cmd_b:nnnnn|, that fully
+% expands arguments 1,~3 and~5, and produces commands to pass as
+% arguments 2 and~4 using~|\csname|.
+% The definition you need is simply
+% \begin{verbatim}
+% \cs_generate_variant:Nn \demo_cmd_b:nnnnn { xcxcx }
+% \end{verbatim}
+%
+% This extension mechanism is written so that if the same new form of
+% some existing command is implemented by two extension packages then the
+% two definitions will be identical and thus no conflict will occur.
+%
+% \section{The distribution}
+%
+% At present, the \pkg{expl3} modules are designed to be loaded on top
+% of \LaTeXe. In time, a \LaTeX3 format will be produced based on this
+% code. This allows the code to be used in \LaTeXe{} packages \emph{now}
+% while a stand-alone \LaTeX3 is developed.
+%
+% \begin{bfseries}
+% While \pkg{expl3} is still experimental, the bundle is now regarded
+% as broadly stable. The syntax conventions and functions provided
+% are now ready for wider use. There may still be changes to some
+% functions, but these will be minor when compared to the scope of
+% \pkg{expl3}.
+% \end{bfseries}
+%
+% New modules will be added to the distributed version of \pkg{expl3}
+% as they reach maturity. At present, the \pkg{expl3} bundle consists
+% of a number of modules, most of which are loaded by including the
+% line:
+% \begin{verbatim}
+% \RequirePackage{expl3}
+% \end{verbatim}
+% in a \LaTeXe{} package, class or other file. The \pkg{expl3} modules
+% regarded as stable, and therefore suitable for basing real code on,
+% are as follows:
+%
+% \begin{description}
+% \providecommand\explpkg[2]{\item[#1]#2}
+% \explpkg{l3basics}{
+% This contains the basic definition modules used
+% by the other packages.
+% }
+% \explpkg{l3box}{
+% Primitives for dealing with boxes.
+% }
+% \explpkg{l3clist}{
+% Methods for manipulating comma-separated token lists.
+% }
+% \explpkg{l3expan}{
+% This is the argument expansion module discussed earlier in this
+% document.
+% }
+% \explpkg{l3int}{
+% This implements the integer data-type \texttt{int}.
+% }
+% \explpkg{l3io}{
+% A module providing low level input and output functions.
+% }
+% \explpkg{l3keyval}{
+% Low-level implementation for processing lists of the form
+% \texttt{\{ key1=val1 , key2=val2 \}}.
+% }
+% \explpkg{l3keys}{
+% Higher-level implementation of key--value methods: intended to work
+% as a \LaTeX3 version of \pkg{xkeyval}/\pkg{kvoptions}, although
+% with input syntax more like that of \pkg{pgfkeys}.
+% }
+% \explpkg{l3msg}{
+% Communicating with the user: includes low-level hooks to allow
+% messages to be filtered (higher-level interface for filtering
+% to be written!).
+% }
+% \explpkg{l3names}{
+% This sets up the basic naming scheme and renames all
+% the \TeX{} primitives.
+% }
+% \explpkg{l3prg}{
+% Program control structures such as boolean data type |bool|, generic
+% do-while loops, case-switches, sorting routines and stepwise loops.
+% }
+% \explpkg{l3prop}{
+% This implements the data-type for \enquote{property lists} that are used, in
+% particular, for storing key/value pairs.
+% }
+% \explpkg{l3quark}{
+% A \enquote{quark} is a command that is defined to expand to
+% itself! Therefore they must never be expanded as this will generate
+% infinite recursion; they do however have many uses, \emph{e.g.}~as
+% special markers and delimiters within code.
+% }
+% \explpkg{l3seq}{
+% This implements data-types such as queues and stacks.
+% }
+% \explpkg{l3skip}{
+% Implements the \enquote{rubber length} datatype \texttt{skip} and the
+% \enquote{rigid length} datatype |dim|.
+% }
+% \explpkg{l3tl}{
+% This implements a basic data-type, called a \textit{token-list
+% variable} (|tl var.|), used for storing named token lists: these are
+% \TeX{} macros with no arguments.
+% }
+% \explpkg{l3token}{
+% Analysing token lists and token streams, including peeking ahead to
+% see what's coming next and inspecting tokens to detect which kind
+% they are.
+% }
+% \end{description}
+%
+% \section{Moving from \LaTeXe{} to \LaTeX3}
+%
+% To help programmers to use \LaTeX3 code in existing \LaTeXe{} package,
+% some short notes on making the change are probably desirable.
+% Suggestions for inclusion here are welcome! Some of the following
+% is concerned with code, and some with coding style.
+%
+% \begin{itemize}
+% \item \pkg{expl3} is mainly focussed on programming. This means that
+% some areas still require the use of \LaTeXe{} internal macros.
+% For example, you may well need \cs{@ifpackageloaded}, as there
+% is currently no native \LaTeX3 package loading module.
+% \item User level macros should be generated using the mechanism
+% available in the \pkg{xparse} package, which is available from CTAN
+% or the \LaTeX3 SVN repository.
+% \item At an internal level, most functions should be generated
+% \cs{long} (using \cs{cs_new:Npn}) rather than \enquote{short} (using
+% \cs{cs_new_nopar:Npn}). The exceptions are:
+% \begin{itemize}
+% \item Functions which take no arguments;
+% \item Functions which are used with pre-set arguments which
+% therefore cannot be \cs{long}: this is mainly the case with
+% auxiliary functions.
+% \end{itemize}
+% \item Where possible, declare all variables and functions (using
+% \cs{cs_new:Npn}, \cs{tl_new:N}, etc.) before use.
+% \item Prefer \enquote{higher-level} functions over \enquote{lower-level},
+% where
+% possible. So for example use \cs{cs_if_exist:N(TF)} in preference
+% \cs{if_cs_exist:N}.
+% \item Use space to make code readable. In general, we recommend
+% a layout such as:
+% \begin{verbatim}
+% \cs_new:Npn \foo_bar:Nn #1#2
+% {
+% \cs_if_exist:NTF #1
+% { \foo_bar_aux_i:n {#2} }
+% { \foo_bar_aux_ii:nn {#2} { literal } }
+% }
+% \end{verbatim}
+% where spaces are used around |{| and |}| except for isolated
+% |#1|, |#2|, etc.
+% \item Put different code items on separate lines: readability is
+% much more useful than compactness.
+% \item Use long, descriptive names for functions and variables,
+% and for auxiliary functions use the parent function name plus
+% |aux|, |aux_i|, |aux_ii| and so on.
+% \item If in doubt, ask the team via the LaTeX-L list: someone will
+% soon get back to you!
+% \end{itemize}
+%
+% \section{The \LaTeX3 Project}
+%
+% Development of \LaTeX3 is carried out by The \LaTeX3 Project. Over time,
+% the membership of this team has naturally varied. Currently, the members
+% are
+% \begin{itemize}
+% \item Johannes Braams
+% \item David Carlisle
+% \item Robin Fairbairns
+% \item Morten H{\o}gholm
+% \item Bruno Le Floch
+% \item Thomas Lotze
+% \item Frank Mittelbach
+% \item Will Robertson
+% \item Chris Rowley
+% \item Rainer Sch{\"o}pf
+% \item Joseph Wright
+% \end{itemize}
+% while former members are
+% \begin{itemize}
+% \item Michael Downes
+% \item Denys Duchier
+% \item Alan Jeffrey
+% \item Martin Schr{\"o}der
+% \end{itemize}
+%
+% \begin{thebibliography}{1}
+%
+% \bibitem{A-W:K-TB}
+% Donald E Knuth
+% \newblock \emph{The \TeX{}book}.
+% \newblock Addison-Wesley, Reading, Massachusetts, 1984.
+%
+% \bibitem{A-W:GMS94}
+% Goossens, Mittelbach and Samarin.
+% \newblock \emph{ The \LaTeX{} Companion}.
+% \newblock Addison-Wesley, Reading, Massachusetts, 1994.
+%
+% \bibitem{A-W:LLa94}
+% Leslie Lamport.
+% \newblock \emph{\LaTeX{}: A Document Preparation System}.
+% \newblock Addison-Wesley, Reading, Massachusetts, second edition, 1994.
+%
+% \bibitem{tub:MR97-1}
+% Frank Mittelbach and Chris Rowley.
+% \newblock \enquote{The \LaTeX3 Project}.
+% \newblock \emph{TUGboat},
+% Vol.\,18, No.\,3, pp.\,195--198, 1997.
+%
+% \end{thebibliography}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{expl3} implementation}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% Load \pkg{etex} as otherwise we are likely to get into trouble
+% with registers. Some inserts are reserved also as these have to
+% be from the standard pool.
+% \begin{macrocode}
+\RequirePackage{etex}
+\reserveinserts{32}
+% \end{macrocode}
+%
+% We want \pkg{calc} to allow \LaTeXe{} to do \eTeX{}-like setting (which will
+% be native in \LaTeX3).
+% \begin{macrocode}
+\RequirePackage{calc}
+% \end{macrocode}
+%
+% Do the package identification: this will turn on code syntax.
+% \begin{macrocode}
+\ProvidesExplPackage
+ {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
+% \end{macrocode}
+%
+% \begin{macro}{\@l@expl@check@declarations@bool}
+% \begin{macro}{\@l@expl@log@functions@bool}
+% A couple of package options to be provided.
+% These have to be done by hand as there is no \pkg{expl3} yet: the logging
+% option
+% is needed before loading \pkg{l3basics}!
+% \begin{macrocode}
+\newcommand* \@l@expl@check@declarations@bool { 0 }
+\newcommand*\@l@expl@log@functions@bool { 0 }
+\DeclareOption { check-declarations }
+ { \def \@l@expl@check@declarations@bool { 1 } }
+\DeclareOption { log-functions }
+ {\def \@l@expl@log@functions@bool { 1 } }
+\ProcessOptions \relax
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% We already loaded \pkg{l3names} at the beginning of the \texttt{dtx} file.
+% We now load the base of \LaTeX3, stopping once token list variables are
+% defined.
+% \begin{macrocode}
+\RequirePackage{ l3basics, l3expan, l3tl }
+% \end{macrocode}
+%
+% \begin{macro}{\tl_check_exists:N}
+% When used as a package, there is an option to be picky and to
+% check definitions exist. This part of the process is done now, so that
+% variable types based on |tl| (for example |clist|, |seq| and |prop|) will
+% inherit
+% the appropriate definitions.
+% \begin{macrocode}
+\ifodd \@l@expl@check@declarations@bool \relax
+ \cs_new_protected:Npn \tl_check_exists:N #1
+ {
+ \cs_if_exist:NF #1
+ {
+ \msg_kernel_error:nnx { check } { non-declared-variable }
+ { \token_to_str:N #1 }
+ }
+ }
+ \cs_set_protected:Npn \tl_set:Nn #1#2
+ {
+ \tl_check_exists:N #1
+ \cs_set_nopar:Npx #1 { \exp_not:n {#2} }
+ }
+ \cs_set_protected:Npn \tl_set:Nx #1#2
+ {
+ \tl_check_exists:N #1
+ \cs_set_nopar:Npx #1 {#2}
+ }
+ \cs_set_protected:Npn \tl_gset:Nn #1#2
+ {
+ \tl_check_exists:N #1
+ \cs_gset_nopar:Npx #1 { \exp_not:n {#2} }
+ }
+ \cs_set_protected:Npn \tl_gset:Nx #1#2
+ {
+ \tl_check_exists:N #1
+ \cs_gset_nopar:Npx #1 {#2}
+ }
+ \cs_set_protected:Npn \tl_set_eq:NN #1#2
+ {
+ \tl_check_exists:N #1
+ \tl_check_exists:N #2
+ \cs_set_eq:NN #1 #2
+ }
+ \cs_set_protected:Npn \tl_gset_eq:NN #1#2
+ {
+ \tl_check_exists:N #1
+ \tl_check_exists:N #2
+ \cs_gset_eq:NN #1 #2
+ }
+\fi
+% \end{macrocode}
+%\end{macro}
+%
+% The rest of the code can now be loaded.
+% \begin{macrocode}
+\RequirePackage{
+ l3seq,
+ l3int,
+ l3quark,
+ l3prg,
+ l3clist,
+ l3token,
+ l3prop,
+ l3msg,
+ l3io,
+ l3file,
+ l3skip,
+ l3box,
+ l3keyval,
+ l3keys,
+ l3fp,
+ l3luatex
+}
+% \end{macrocode}
+%
+% Depreciated, but loaded for the moment.
+% \begin{macrocode}
+\RequirePackage{l3toks}
+% \end{macrocode}
+%
+% The error message for variables cannot be created before now: this means that
+% \pkg{expl3} itself may cause some odd errors.
+% \begin{macrocode}
+\bool_if:nT { \@l@expl@check@declarations@bool }
+ {
+ \msg_kernel_new:nnnn { check } { non-declared-variable }
+ { The~variable~#1~has~not~been~declared~\msg_line_context:. }
+ {
+ Checking~is~active,~and~you~have~tried~do~so~something~like: \\
+ \ \ \tl_set:Nn #1 ~
+ \iow_char:N \{ ~ ... ~ \iow_char:N \} \\
+ without~first~having: \\
+ \ \ \tl_new:N #1 \\
+ \\
+ LaTeX~will~create~the~variable~and~continue.
+ }
+ }
+% \end{macrocode}
+%
+% \begin{macro}{\ExplSyntaxOff, \ExplSyntaxOn}
+% These are redefined here to reduce unnecessary work when switching.
+% The definition for \cs{ExplSyntaxOff} copies the code from earlier,
+% so that category codes are restored.
+% \begin{macrocode}
+\cs_set_protected_nopar:Npn \ExplSyntaxOn
+ {
+ \bool_if:NF \l_expl_status_bool
+ {
+ \cs_set_protected_nopar:Npx \ExplSyntaxOff
+ {
+ \char_set_catcode:nn { 9 } { \char_value_catcode:n { 9 } }
+ \char_set_catcode:nn { 32 } { \char_value_catcode:n { 32 } }
+ \char_set_catcode:nn { 34 } { \char_value_catcode:n { 34 } }
+ \char_set_catcode:nn { 38 } { \char_value_catcode:n { 38 } }
+ \char_set_catcode:nn { 58 } { \char_value_catcode:n { 58 } }
+ \char_set_catcode:nn { 94 } { \char_value_catcode:n { 94 } }
+ \char_set_catcode:nn { 95 } { \char_value_catcode:n { 95 } }
+ \char_set_catcode:nn { 124 } { \char_value_catcode:n { 124 } }
+ \char_set_catcode:nn { 126 } { \char_value_catcode:n { 126 } }
+ \tex_endlinechar:D = \tex_the:D \tex_endlinechar:D \scan_stop:
+ \bool_set_false:N \l_expl_status_bool
+ \cs_set_protected_nopar:Npn \ExplSyntaxOff { }
+ }
+ }
+ \char_set_catcode_ignore:n { 9 } % tab
+ \char_set_catcode_ignore:n { 32 } % space
+ \char_set_catcode_other:n { 34 } % double quote
+ \char_set_catcode_alignment:n { 38 } % ampersand
+ \char_set_catcode_letter:n { 58 } % colon
+ \char_set_catcode_math_superscript:n { 94 } % circumflex
+ \char_set_catcode_letter:n { 95 } % underscore
+ \char_set_catcode_other:n { 124 } % pipe
+ \char_set_catcode_space:n { 126 } % tilde
+ \tex_endlinechar:D = 32 \scan_stop:
+ \bool_set_true:N \l_expl_status_bool
+ }
+\cs_set_protected_nopar:Npx \ExplSyntaxOff
+ {
+ \exp_not:o \ExplSyntaxOff
+ \cs_set_protected_nopar:Npn \ExplSyntaxOff { }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3alloc.dtx b/Master/texmf-dist/source/latex/l3kernel/l3alloc.dtx
new file mode 100644
index 00000000000..8e175a2e74d
--- /dev/null
+++ b/Master/texmf-dist/source/latex/l3kernel/l3alloc.dtx
@@ -0,0 +1,216 @@
+% \iffalse meta-comment
+%
+%% File: l3alloc.dtx Copyright (C) 1990-2011 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 "expl3 bundle" (The Work in LPPL)
+%% and all files in that bundle must be distributed together.
+%%
+%% The released version of this bundle is available from CTAN.
+%%
+%% -----------------------------------------------------------------------
+%%
+%% The development version of the bundle can be found at
+%%
+%% http://www.latex-project.org/svnroot/experimental/trunk/
+%%
+%% for those people who are interested.
+%%
+%%%%%%%%%%%
+%% NOTE: %%
+%%%%%%%%%%%
+%%
+%% Snapshots taken from the repository represent work in progress and may
+%% not work or may contain conflicting material! We therefore ask
+%% people _not_ to put them into distributions, archives, etc. without
+%% prior consultation with the LaTeX3 Project.
+%%
+%% -----------------------------------------------------------------------
+%
+%<*driver|package>
+\RequirePackage{l3names}
+\GetIdInfo$Id: l3alloc.dtx 2478 2011-06-19 21:34:23Z joseph $
+ {L3 Experimental register allocation}
+%</driver|package>
+%<*driver>
+\documentclass[full]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3alloc} package\\ Register allocation^^A
+% \thanks{This file describes v\ExplFileVersion,
+% last revised \ExplFileDate.}^^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 \ExplFileDate}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% Note that this module is only used for generating an pkg{expl3}-based
+% format. Under \LaTeX{}, the \pkg{etex} package is used for allocation
+% management.
+%
+% This module provides the basic mechanism for allocating \TeX{}s
+% registers. While designing this we have to take into account the
+% following characteristics:
+% \begin{itemize}
+% \item |\box255| is reserved for use in the output routine, so it
+% should not be allocated otherwise.
+% \item \TeX{} can load up 256 hyphenation patterns (registers
+% |\tex_language:D| 0--255),
+% \item \TeX{} can load no more than 16 math families,
+% \item \TeX{} supports no more than 16 I/O streams for reading
+% (|\tex_read:D|) and 16 I/O streams for writing (|\tex_write:D|),
+% \item \TeX{} supports no more than 256 inserts.
+% \item The other registers (|\tex_count:D|, |\tex_dimen:D|,
+% |\tex_skip:D|, |\tex_muskip:D|, |\tex_box:D|, and |\tex_toks:D|
+% range from 0 to 32768, but registers numbered above 255 are
+% accessed somewhat less efficiently.
+% \item Registers could be allocated both globally and locally; the
+% use of registers could also be globally or locally. Here we
+% provide support for globally allocated registers for both
+% global and local use.
+% \end{itemize}
+% We also need to allow for some bookkeeping: we need to know which
+% register was allocated last and which registers can not be
+% allocated by the standard mechanisms.
+%
+% \begin{function}{\alloc_new:nnnN}
+% \begin{syntax}
+% \cs{alloc_new:nnnN} \Arg{type} \Arg{min} \Arg{max} \meta{function}
+% \end{syntax}
+% Shorthand for allocating new registers. Defines \cs{<type>_new:N} as
+% and allocator function of the specified \meta{type}, indexed up from
+% \meta{min} to a \meta{max}, and with assignment carried out by
+% the \meta{function}. This process will create two token lists,
+% \cs{g_\meta{type}_allocation_tl} and \cs{c_\meta{type}_allocation_max_tl},
+% to store the current and maximum allocation numbers, respectively.
+% It will also create \cs{g_\meta{type}_allocation_seq} to store allocation
+% numbers which should not be used.
+% \end{function}
+%
+% \section{Internal functions}
+%
+% \begin{function}{\alloc_setup_type:nnn}
+% \begin{syntax}
+% \cs{alloc_setup_type:nnn} \Arg{type} \Arg{min} \Arg{max}
+% \end{syntax}
+% Sets up the storage needed for the administration of registers of
+% \Arg{type}, which will start allocating at \meta{min} and will issue
+% an error if there is an attempt to allocate past the \meta{max}.
+% \end{function}
+%
+% \begin{function}{\alloc_reg:nNN}
+% \begin{syntax}
+% \cs{alloc_reg:nNN} \Arg{type} \meta{function} \meta{register}
+% \end{syntax}
+% Preforms the allocation for a new \meta{register} of \meta{type},
+% using the allocator \meta{function} (which will be either a
+% primitive \cs{tex_\ldots def:D} or \cs{tex_chardef:D}).
+% \end{function}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3alloc} implementation}
+%
+% \begin{macrocode}
+%<*initex>
+% \end{macrocode}
+%
+% \begin{macro}{\alloc_new:nnnN}
+% Shorthand for defining new register types and their allocators:
+% \begin{macrocode}
+\cs_new:Npn \alloc_new:nnnN #1#2#3#4
+ {
+ \alloc_setup_type:nnn {#1} {#2} {#3}
+ \cs_new_nopar:cpn { #1 _new:N } ##1 { \alloc_reg:nNN {#1} #4 ##1 }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\alloc_setup_type:nnn}
+% For each type of register we need to \enquote{counters} that hold the
+% last allocated global register, plus a constant for the maximum
+% allocation. We also need a sequence to store the \enquote{exceptions}.
+% \begin{macrocode}
+\cs_new_nopar:Npn \alloc_setup_type:nnn #1#2#3
+ {
+ \tl_new:c { g_ #1 _allocation_tl }
+ \tl_gset:cx { g_ #1 _allocation_tl } { \int_eval:n {#2} }
+ \tl_const:cx { c_ #1 _allocation_max_tl } { \int_eval:n {#3} }
+ \seq_new:c { g_ #1 _allocation_seq }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\alloc_reg:nNN}
+% This internal macro performs the actual allocation.
+% \begin{macrocode}
+\cs_new_nopar:Npn \alloc_reg:nNN #1#2#3
+ {
+ \chk_if_free_cs:N #3
+ \pref_global:D #2 #3 \tl_use:c { g_ #1 _allocation_tl } \scan_stop:
+ \iow_log:x
+ {
+ \token_to_str:N #3 ~=~ #1 ~register~
+ \tl_use:c { g_ #1 _allocation_tl }
+ }
+ \alloc_next:n {#1}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[aux]{\alloc_next:n}
+% Finding the next register to use is a question of doing an increment
+% then a check: if we run out of registers then it is a fatal error, so
+% there is no need to unwind the change. (The check could be done
+% first but that needs an additional calculation.) There is a built-in
+% loop to handle reserved allocation positions.
+% \begin{macrocode}
+\cs_new_nopar:Npn \alloc_next:n #1
+ {
+ \tl_gset:cx { g_ #1 _allocation_tl }
+ { \int_eval:n { \tl_use:c { g_ #1 _allocation_tl } + 1 } }
+ \int_compare:nNnTF
+ { \tl_use:c { g_ #1 _allocation_tl } }
+ > { \tl_use:c { c_ #1 _allocation_max_tl } }
+ { \msg_kernel_fatal:nnx { alloc } { out-of-registers } {#1} }
+ {
+ \seq_if_in:cxT { g_ #1 _allocation_seq }
+ { \tl_use:c { g_ #1 _allocation_tl } }
+ { \alloc_next:n {#1} }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</initex>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx b/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx
new file mode 100644
index 00000000000..52cc56c699a
--- /dev/null
+++ b/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx
@@ -0,0 +1,3208 @@
+% \iffalse meta-comment
+%
+%% File: l3basics.dtx Copyright (C) 1990-2011 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 "expl3 bundle" (The Work in LPPL)
+%% and all files in that bundle must be distributed together.
+%%
+%% The released version of this bundle is available from CTAN.
+%%
+%% -----------------------------------------------------------------------
+%%
+%% The development version of the bundle can be found at
+%%
+%% http://www.latex-project.org/svnroot/experimental/trunk/
+%%
+%% for those people who are interested.
+%%
+%%%%%%%%%%%
+%% NOTE: %%
+%%%%%%%%%%%
+%%
+%% Snapshots taken from the repository represent work in progress and may
+%% not work or may contain conflicting material! We therefore ask
+%% people _not_ to put them into distributions, archives, etc. without
+%% prior consultation with the LaTeX3 Project.
+%%
+%% -----------------------------------------------------------------------
+%
+%<*driver|package>
+\RequirePackage{l3names}
+\GetIdInfo$Id: l3basics.dtx 2493 2011-07-04 09:50:22Z bruno $
+ {L3 Experimental basic definitions}
+%</driver|package>
+%<*driver>
+\documentclass[full]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3basics} package\\ Basic definitions^^A
+% \thanks{This file describes v\ExplFileVersion,
+% last revised \ExplFileDate.}^^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 \ExplFileDate}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% As the name suggest this package holds some basic definitions which
+% are needed by most or all other packages in this set.
+%
+% Here we describe those functions that are used all over the place. With
+% that we mean functions dealing with the construction and testing of
+% control sequences. Furthermore the basic parts of conditional
+% processing are covered; conditional processing dealing with specific
+% data types is described in the modules specific for the respective
+% data types.
+%
+% \section{No operation functions}
+%
+% \begin{function}[EXP]{\prg_do_nothing:}
+% \begin{syntax}
+% \cs{prg_do_nothing:}
+% \end{syntax}
+% An expandable function which does nothing at all: leaves nothing
+% in the input stream after a single expansion.
+% \end{function}
+%
+% \begin{function}{\scan_stop:}
+% \begin{syntax}
+% \cs{scan_stop:}
+% \end{syntax}
+% A non-expandable function which does nothing. Does not vanish on
+% expansion but produces no typeset output.
+% \end{function}
+%
+% \section{Grouping material}
+%
+% \begin{function}{\group_begin:, \group_end:}
+% \begin{syntax}
+% \cs{group_begin:}
+% \cs{group_end:}
+% \end{syntax}
+% These functions begin and end a group for definition purposes.
+% Assignments are local to groups unless carried out in a global
+% manner. (A small number of exceptions to this rule will be noted
+% as necessary elsewhere in this document.) Each \cs{group_begin:}
+% must be matched by a \cs{group_end:}, although this does not have
+% to occur within the same function. Indeed, it is often necessary
+% to start a group within one function and finish it within another,
+% for example when seeking to use non-standard category codes.
+% \end{function}
+%
+% \begin{function}{\group_insert_after:N}
+% \begin{syntax}
+% \cs{group_insert_after:N} \meta{token}
+% \end{syntax}
+% Adds \meta{token} to the list of \meta{tokens} to be inserted
+% when the current group level ends. The list of \meta{tokens} to be
+% inserted will be empty at the beginning of a group: multiple
+% applications of \cs{group_insert_after:N} may be used to build
+% the inserted list one \meta{token} at a time. The current group
+% level may be closed by a \cs{group_end:} function or by a token
+% with category code $2$ (close-group). The later will be a ^^A{
+% |}| if standard category codes apply.
+% \end{function}
+%
+% \section{Control sequences and functions}
+%
+% As \TeX{} is a macro language, creating new functions means
+% creating macros. At point of use, a function is replaced by
+% the replacement text (\enquote{code}) in which each parameter
+% in the code (|#1|, |#2|, \emph{etc.}) is replaced the appropriate
+% arguments absorbed by the function. In the following, \meta{code}
+% is therefore used as a shorthand for \enquote{replacement text}.
+%
+% Functions which are not \enquote{protected} will be fully expanded
+% inside an \texttt{x} expansion. In contrast, \enquote{protected}
+% functions are not expanded within \texttt{x} expansions.
+%
+% \subsection{Defining functions}
+%
+% Functions can be created with no requirement that they are declared
+% first (in contrast to variables, which must always be declared).
+% Declaring a function before setting up the code means that the name
+% chosen will be checked and an error raised if it is already in use.
+% The name of a function can be checked at the point of definition using
+% the \cs{cs_new\ldots} functions: this is recommended for all
+% functions which are defined for the first time.
+%
+% \subsection{Defining new functions using primitive parameter text}
+%
+% \begin{function}{\cs_new:Npn, \cs_new:cpn, \cs_new:Npx, \cs_new:cpx}
+% \begin{syntax}
+% \cs{cs_new:Npn} \meta{function} \meta{parameters} \Arg{code}
+% \end{syntax}
+% Creates \meta{function} to expand to \meta{code} as replacement text.
+% Within the \meta{code}, the \meta{parameters} (|#1|, |#2|,
+% \emph{etc.}) will be replaced by those absorbed by the function.
+% The definition is global and an error will result if the
+% \meta{function} is already defined.
+% \end{function}
+%
+% \begin{function}
+% {
+% \cs_new_nopar:Npn, \cs_new_nopar:cpn,
+% \cs_new_nopar:Npx, \cs_new_nopar:cpx
+% }
+% \begin{syntax}
+% \cs{cs_new_nopar:Npn} \meta{function} \meta{parameters} \Arg{code}
+% \end{syntax}
+% Creates \meta{function} to expand to \meta{code} as replacement text.
+% Within the \meta{code}, the \meta{parameters} (|#1|, |#2|,
+% \emph{etc.}) will be replaced by those absorbed by the function.
+% When the \meta{function} is used the \meta{parameters} absorbed
+% cannot contain \cs{par} tokens. The definition is global and
+% an error will result if the \meta{function} is already defined.
+% \end{function}
+%
+% \begin{function}
+% {
+% \cs_new_protected:Npn, \cs_new_protected:cpn,
+% \cs_new_protected:Npx, \cs_new_protected:cpx
+% }
+% \begin{syntax}
+% \cs{cs_new_protected:Npn} \meta{function} \meta{parameters}
+% ~~\Arg{code}
+% \end{syntax}
+% Creates \meta{function} to expand to \meta{code} as replacement text.
+% Within the \meta{code}, the \meta{parameters} (|#1|, |#2|,
+% \emph{etc.}) will be replaced by those absorbed by the function.
+% The \meta{function} will not expand within an \texttt{x}-type
+% argument. The definition is global and an error will result if the
+% \meta{function} is already defined.
+% \end{function}
+%
+% \begin{function}
+% {
+% \cs_new_protected_nopar:Npn, \cs_new_protected_nopar:cpn ,
+% \cs_new_protected_nopar:Npx, \cs_new_protected_nopar:cpx
+% }
+% \begin{syntax}
+% \cs{cs_new_protected_nopar:Npn} \meta{function} \meta{parameters}
+% ~~\Arg{code}
+% \end{syntax}
+% Creates \meta{function} to expand to \meta{code} as replacement text.
+% Within the \meta{code}, the \meta{parameters} (|#1|, |#2|,
+% \emph{etc.}) will be replaced by those absorbed by the function.
+% When the \meta{function} is used the \meta{parameters} absorbed
+% cannot contain \cs{par} tokens. The \meta{function} will not
+% expand within an \texttt{x}-type argument. The definition is global
+% and an error will result if the \meta{function} is already defined.
+% \end{function}
+%
+% \begin{function}{\cs_set:Npn, \cs_set:cpn, \cs_set:Npx, \cs_set:cpx}
+% \begin{syntax}
+% \cs{cs_set:Npn} \meta{function} \meta{parameters} \Arg{code}
+% \end{syntax}
+% Sets \meta{function} to expand to \meta{code} as replacement text.
+% Within the \meta{code}, the \meta{parameters} (|#1|, |#2|,
+% \emph{etc.}) will be replaced by those absorbed by the function.
+% The assignment of a meaning to \meta{function} is restricted to
+% the current \TeX{} group level.
+% \end{function}
+%
+% \begin{function}
+% {
+% \cs_set_nopar:Npn, \cs_set_nopar:cpn,
+% \cs_set_nopar:Npx, \cs_set_nopar:cpx
+% }
+% \begin{syntax}
+% \cs{cs_set_nopar:Npn} \meta{function} \meta{parameters} \Arg{code}
+% \end{syntax}
+% Sets \meta{function} to expand to \meta{code} as replacement text.
+% Within the \meta{code}, the \meta{parameters} (|#1|, |#2|,
+% \emph{etc.}) will be replaced by those absorbed by the function.
+% When the \meta{function} is used the \meta{parameters} absorbed
+% cannot contain \cs{par} tokens. The assignment of a meaning
+% to \meta{function} is restricted to the current \TeX{} group
+% level.
+% \end{function}
+%
+% \begin{function}
+% {
+% \cs_set_protected:Npn, \cs_set_protected:cpn,
+% \cs_set_protected:Npx, \cs_set_protected:cpx
+% }
+% \begin{syntax}
+% \cs{cs_set_protected:Npn} \meta{function} \meta{parameters}
+% ~~\Arg{code}
+% \end{syntax}
+% Sets \meta{function} to expand to \meta{code} as replacement text.
+% Within the \meta{code}, the \meta{parameters} (|#1|, |#2|,
+% \emph{etc.}) will be replaced by those absorbed by the function.
+% The assignment of a meaning to \meta{function} is restricted to
+% the current \TeX{} group level. The \meta{function} will
+% not expand within an \texttt{x}-type argument.
+% \end{function}
+%
+% \begin{function}
+% {
+% \cs_set_protected_nopar:Npn, \cs_set_protected_nopar:cpn ,
+% \cs_set_protected_nopar:Npx, \cs_set_protected_nopar:cpx ,
+% }
+% \begin{syntax}
+% \cs{cs_set_protected_nopar:Npn} \meta{function}
+% ~~\meta{parameters} \Arg{code}
+% \end{syntax}
+% Sets \meta{function} to expand to \meta{code} as replacement text.
+% Within the \meta{code}, the \meta{parameters} (|#1|, |#2|,
+% \emph{etc.}) will be replaced by those absorbed by the function.
+% When the \meta{function} is used the \meta{parameters} absorbed
+% cannot contain \cs{par} tokens. The assignment of a meaning
+% to \meta{function} is restricted to the current \TeX{} group
+% level. The \meta{function} will not expand within an
+% \texttt{x}-type argument.
+% \end{function}
+%
+% \begin{function}{\cs_gset:Npn, \cs_gset:cpn, \cs_gset:Npx, \cs_gset:cpx}
+% \begin{syntax}
+% \cs{cs_gset:Npn} \meta{function} \meta{parameters} \Arg{code}
+% \end{syntax}
+% Globally sets \meta{function} to expand to \meta{code} as replacement
+% text. Within the \meta{code}, the \meta{parameters} (|#1|, |#2|,
+% \emph{etc.}) will be replaced by those absorbed by the function.
+% The assignment of a meaning to \meta{function} is \emph{not}
+% restricted to the current \TeX{} group level: the assignment is
+% global.
+% \end{function}
+%
+% \begin{function}
+% {
+% \cs_gset_nopar:Npn, \cs_gset_nopar:cpn,
+% \cs_gset_nopar:Npx , \cs_gset_nopar:cpx
+% }
+% \begin{syntax}
+% \cs{cs_gset_nopar:Npn} \meta{function} \meta{parameters} \Arg{code}
+% \end{syntax}
+% Globally sets \meta{function} to expand to \meta{code} as replacement
+% text. Within the \meta{code}, the \meta{parameters} (|#1|, |#2|,
+% \emph{etc.}) will be replaced by those absorbed by the function.
+% When the \meta{function} is used the \meta{parameters} absorbed
+% cannot contain \cs{par} tokens. The assignment of a meaning to
+% \meta{function} is \emph{not} restricted to the current \TeX{}
+% group level: the assignment is global.
+% \end{function}
+%
+% \begin{function}
+% {
+% \cs_gset_protected:Npn, \cs_gset_protected:cpn,
+% \cs_gset_protected:Npx, \cs_gset_protected:cpx
+% }
+% \begin{syntax}
+% \cs{cs_gset_protected:Npn} \meta{function} \meta{parameters}
+% ~~\Arg{code}
+% \end{syntax}
+% Globally sets \meta{function} to expand to \meta{code} as replacement
+% text. Within the \meta{code}, the \meta{parameters} (|#1|, |#2|,
+% \emph{etc.}) will be replaced by those absorbed by the function.
+% The assignment of a meaning to \meta{function} is \emph{not}
+% restricted to the current \TeX{} group level: the assignment is
+% global. The \meta{function} will not expand within an
+% \texttt{x}-type argument.
+% \end{function}
+%
+% \begin{function}
+% {
+% \cs_gset_protected_nopar:Npn, \cs_gset_protected_nopar:cpn,
+% \cs_gset_protected_nopar:Npx, \cs_gset_protected_nopar:cpx
+% }
+% \begin{syntax}
+% \cs{cs_gset_protected_nopar:Npn} \meta{function}
+% ~~\meta{parameters} \Arg{code}
+% \end{syntax}
+% Globally sets \meta{function} to expand to \meta{code} as replacement
+% text. Within the \meta{code}, the \meta{parameters} (|#1|, |#2|,
+% \emph{etc.}) will be replaced by those absorbed by the function.
+% When the \meta{function} is used the \meta{parameters} absorbed
+% cannot contain \cs{par} tokens. The assignment of a meaning to
+% \meta{function} is \emph{not} restricted to the current \TeX{}
+% group level: the assignment is global. The \meta{function} will
+% not expand within an \texttt{x}-type argument.
+% \end{function}
+%
+% \subsection{Defining new functions using the signature}
+%
+% \begin{function}
+% {
+% \cs_new:Nn, \cs_new:cn,
+% \cs_new:Nx, \cs_new:cx
+% }
+% \begin{syntax}
+% \cs{cs_new:Nn} \meta{function} \Arg{code}
+% \end{syntax}
+% Creates \meta{function} to expand to \meta{code} as replacement text.
+% Within the \meta{code}, the number of \meta{parameters} is detected
+% automatically from the function signature. These \meta{parameters}
+% (|#1|, |#2|, \emph{etc.}) will be replaced by those absorbed by the
+% function. The definition is global and
+% an error will result if the \meta{function} is already defined.
+% \end{function}
+%
+% \begin{function}
+% {
+% \cs_new_nopar:Nn, \cs_new_nopar:cn,
+% \cs_new_nopar:Nx, \cs_new_nopar:cx
+% }
+% \begin{syntax}
+% \cs{cs_new_nopar:Nn} \meta{function} \Arg{code}
+% \end{syntax}
+% Creates \meta{function} to expand to \meta{code} as replacement text.
+% Within the \meta{code}, the number of \meta{parameters} is detected
+% automatically from the function signature. These \meta{parameters}
+% (|#1|, |#2|, \emph{etc.}) will be replaced by those absorbed by the
+% function. When the \meta{function} is used the \meta{parameters}
+% absorbed cannot contain \cs{par} tokens. The definition is global and
+% an error will result if the \meta{function} is already defined.
+% \end{function}
+%
+% \begin{function}
+% {
+% \cs_new_protected:Nn, \cs_new_protected:cn,
+% \cs_new_protected:Nx, \cs_new_protected:cx
+% }
+% \begin{syntax}
+% \cs{cs_new_protected:Nn} \meta{function} \Arg{code}
+% \end{syntax}
+% Creates \meta{function} to expand to \meta{code} as replacement text.
+% Within the \meta{code}, the number of \meta{parameters} is detected
+% automatically from the function signature. These \meta{parameters}
+% (|#1|, |#2|, \emph{etc.}) will be replaced by those absorbed by the
+% function. The \meta{function} will not expand within an \texttt{x}-type
+% argument. The definition is global and
+% an error will result if the \meta{function} is already defined.
+% \end{function}
+%
+% \begin{function}
+% {
+% \cs_new_protected_nopar:Nn, \cs_new_protected_nopar:cn,
+% \cs_new_protected_nopar:Nx, \cs_new_protected_nopar:cx
+% }
+% \begin{syntax}
+% \cs{cs_new_protected_nopar:Nn} \meta{function} \Arg{code}
+% \end{syntax}
+% Creates \meta{function} to expand to \meta{code} as replacement text.
+% Within the \meta{code}, the number of \meta{parameters} is detected
+% automatically from the function signature. These \meta{parameters}
+% (|#1|, |#2|, \emph{etc.}) will be replaced by those absorbed by the
+% function. When the \meta{function} is used the \meta{parameters}
+% absorbed cannot contain \cs{par} tokens. The \meta{function} will not
+% expand within an \texttt{x}-type argument. The definition is global and
+% an error will result if the \meta{function} is already defined.
+% \end{function}
+%
+% \begin{function}
+% {
+% \cs_set:Nn, \cs_set:cn,
+% \cs_set:Nx, \cs_set:cx
+% }
+% \begin{syntax}
+% \cs{cs_set:Nn} \meta{function} \Arg{code}
+% \end{syntax}
+% Sets \meta{function} to expand to \meta{code} as replacement text.
+% Within the \meta{code}, the number of \meta{parameters} is detected
+% automatically from the function signature. These \meta{parameters}
+% (|#1|, |#2|, \emph{etc.}) will be replaced by those absorbed by the
+% function.
+% The assignment of a meaning to \meta{function} is restricted to
+% the current \TeX{} group level.
+% \end{function}
+%
+% \begin{function}
+% {
+% \cs_set_nopar:Nn, \cs_set_nopar:cn,
+% \cs_set_nopar:Nx, \cs_set_nopar:cx
+% }
+% \begin{syntax}
+% \cs{cs_set_nopar:Nn} \meta{function} \Arg{code}
+% \end{syntax}
+% Sets \meta{function} to expand to \meta{code} as replacement text.
+% Within the \meta{code}, the number of \meta{parameters} is detected
+% automatically from the function signature. These \meta{parameters}
+% (|#1|, |#2|, \emph{etc.}) will be replaced by those absorbed by the
+% function. When the \meta{function} is used the \meta{parameters}
+% absorbed cannot contain \cs{par} tokens.
+% The assignment of a meaning to \meta{function} is restricted to
+% the current \TeX{} group level.
+% \end{function}
+%
+% \begin{function}
+% {
+% \cs_set_protected:Nn, \cs_set_protected:cn,
+% \cs_set_protected:Nx, \cs_set_protected:cx
+% }
+% \begin{syntax}
+% \cs{cs_set_protected:Nn} \meta{function} \Arg{code}
+% \end{syntax}
+% Sets \meta{function} to expand to \meta{code} as replacement text.
+% Within the \meta{code}, the number of \meta{parameters} is detected
+% automatically from the function signature. These \meta{parameters}
+% (|#1|, |#2|, \emph{etc.}) will be replaced by those absorbed by the
+% function. The \meta{function} will not expand within an \texttt{x}-type
+% argument.
+% The assignment of a meaning to \meta{function} is restricted to
+% the current \TeX{} group level.
+% \end{function}
+%
+% \begin{function}
+% {
+% \cs_set_protected_nopar:Nn, \cs_set_protected_nopar:cn,
+% \cs_set_protected_nopar:Nx, \cs_set_protected_nopar:cx
+% }
+% \begin{syntax}
+% \cs{cs_set_protected_nopar:Nn} \meta{function} \Arg{code}
+% \end{syntax}
+% Sets \meta{function} to expand to \meta{code} as replacement text.
+% Within the \meta{code}, the number of \meta{parameters} is detected
+% automatically from the function signature. These \meta{parameters}
+% (|#1|, |#2|, \emph{etc.}) will be replaced by those absorbed by the
+% function. When the \meta{function} is used the \meta{parameters}
+% absorbed cannot contain \cs{par} tokens. The \meta{function} will not
+% expand within an \texttt{x}-type argument.
+% The assignment of a meaning to \meta{function} is restricted to
+% the current \TeX{} group level.
+% \end{function}
+%
+% \begin{function}
+% {
+% \cs_gset:Nn, \cs_gset:cn,
+% \cs_gset:Nx, \cs_gset:cx
+% }
+% \begin{syntax}
+% \cs{cs_gset:Nn} \meta{function} \Arg{code}
+% \end{syntax}
+% Sets \meta{function} to expand to \meta{code} as replacement text.
+% Within the \meta{code}, the number of \meta{parameters} is detected
+% automatically from the function signature. These \meta{parameters}
+% (|#1|, |#2|, \emph{etc.}) will be replaced by those absorbed by the
+% function.
+% The assignment of a meaning to \meta{function} is global.
+% \end{function}
+%
+% \begin{function}
+% {
+% \cs_gset_nopar:Nn, \cs_gset_nopar:cn,
+% \cs_gset_nopar:Nx, \cs_gset_nopar:cx
+% }
+% \begin{syntax}
+% \cs{cs_gset_nopar:Nn} \meta{function} \Arg{code}
+% \end{syntax}
+% Sets \meta{function} to expand to \meta{code} as replacement text.
+% Within the \meta{code}, the number of \meta{parameters} is detected
+% automatically from the function signature. These \meta{parameters}
+% (|#1|, |#2|, \emph{etc.}) will be replaced by those absorbed by the
+% function. When the \meta{function} is used the \meta{parameters}
+% absorbed cannot contain \cs{par} tokens.
+% The assignment of a meaning to \meta{function} is global.
+% \end{function}
+%
+% \begin{function}
+% {
+% \cs_gset_protected:Nn, \cs_gset_protected:cn,
+% \cs_gset_protected:Nx, \cs_gset_protected:cx
+% }
+% \begin{syntax}
+% \cs{cs_gset_protected:Nn} \meta{function} \Arg{code}
+% \end{syntax}
+% Sets \meta{function} to expand to \meta{code} as replacement text.
+% Within the \meta{code}, the number of \meta{parameters} is detected
+% automatically from the function signature. These \meta{parameters}
+% (|#1|, |#2|, \emph{etc.}) will be replaced by those absorbed by the
+% function. The \meta{function} will not expand within an \texttt{x}-type
+% argument.
+% The assignment of a meaning to \meta{function} is global.
+% \end{function}
+%
+% \begin{function}
+% {
+% \cs_gset_protected_nopar:Nn, \cs_gset_protected_nopar:cn,
+% \cs_gset_protected_nopar:Nx, \cs_gset_protected_nopar:cx
+% }
+% \begin{syntax}
+% \cs{cs_gset_protected_nopar:Nn} \meta{function} \Arg{code}
+% \end{syntax}
+% Sets \meta{function} to expand to \meta{code} as replacement text.
+% Within the \meta{code}, the number of \meta{parameters} is detected
+% automatically from the function signature. These \meta{parameters}
+% (|#1|, |#2|, \emph{etc.}) will be replaced by those absorbed by the
+% function. When the \meta{function} is used the \meta{parameters}
+% absorbed cannot contain \cs{par} tokens. The \meta{function} will not
+% expand within an \texttt{x}-type argument.
+% The assignment of a meaning to \meta{function} is global.
+% \end{function}
+%
+% \begin{function}
+% {\cs_generate_from_arg_count:NNnn, \cs_generate_from_arg_count:cNnn}
+% \begin{syntax}
+% \cs{cs_generate_from_arg_count:NNnn} \meta{function}
+% ~~\meta{creator} \meta{number} \meta{code}
+% \end{syntax}
+% Uses the \meta{creator} function (which should have signature
+% |Npn|, for example \cs{cs_new:Npn}) to define a \meta{function}
+% which takes \meta{number} arguments and has \meta{code} as
+% replacement text. The \meta{number} of arguments is an integer expression,
+% evaluated as detailed for \cs{int_eval:n}.
+% \end{function}
+%
+% \subsection{Copying control sequences}
+%
+% Control sequences (not just functions as defined above) can
+% be set to have the same meaning using the functions described
+% here. Making two control sequences equivalent means that the
+% second control sequence is a \emph{copy} of the first (rather than
+% a pointer to it). Thus the old and new control sequence are not
+% tided together: changes to one are not reflected in the other.
+%
+% In the following text \enquote{cs} is used as an abbreviation for
+% \enquote{control sequence}.
+%
+% \begin{function}
+% {\cs_new_eq:NN, \cs_new_eq:Nc, \cs_new_eq:cN, \cs_new_eq:cc}
+% \begin{syntax}
+% \cs{cs_new_eq:NN} \meta{cs 1} \meta{cs 2}
+% \end{syntax}
+% Creates \meta{control sequence 1} and sets it to have the same
+% meaning as \meta{control sequence 2} at the point where
+% \cs{cs_new_eq:NN} is executed. The two control sequences may
+% subsequently be altered without affecting the copy. The assignment
+% of a meaning to \meta{control sequence 1} is global.
+% \end{function}
+%
+% \begin{function}
+% {\cs_set_eq:NN, \cs_set_eq:Nc, \cs_set_eq:cN, \cs_set_eq:cc}
+% \begin{syntax}
+% \cs{cs_set_eq:NN} \meta{cs 1} \meta{cs 2}
+% \end{syntax}
+% Sets \meta{control sequence 1} to have the same meaning as
+% \meta{control sequence 2} at the point where \cs{cs_set_eq:NN}
+% is executed. The two control sequences may subsequently be
+% altered without affecting the copy. The assignment of a meaning
+% to \meta{control sequence 1} is restricted to the current
+% \TeX{} group level.
+% \end{function}
+%
+% \begin{function}
+% {\cs_gset_eq:NN, \cs_gset_eq:Nc, \cs_gset_eq:cN, \cs_gset_eq:cc}
+% \begin{syntax}
+% \cs{cs_gset_eq:NN} \meta{cs 1} \meta{cs 2}
+% \end{syntax}
+% Globally sets \meta{control sequence 1} to have the same meaning as
+% \meta{control sequence 2} at the point where \cs{cs_gset_eq:NN}
+% is executed. The two control sequences may subsequently be
+% altered without affecting the copy. The assignment of a meaning to
+% \meta{control sequence 1} is \emph{not} restricted to the current
+% \TeX{} group level: the assignment is global.
+% \end{function}
+%
+% \subsection{Deleting control sequences}
+%
+% There are occasions where control sequences need to be deleted.
+% This is handled in a very simple manner.
+%
+% \begin{function}{\cs_undefine:N, \cs_undefine:c}
+% \begin{syntax}
+% \cs{cs_undefine:N} \meta{control sequence}
+% \end{syntax}
+% Sets \meta{control sequence} to be globally undefined.
+% \end{function}
+%
+% \subsection{Showing control sequences}
+%
+% \begin{function}[EXP]{\cs_meaning:N, \cs_meaning:c}
+% \begin{syntax}
+% \cs{cs_meaning:N} \meta{control sequence}
+% \end{syntax}
+% This function expands to the \emph{meaning} of the \meta{control sequence}
+% control sequence. This will show the \meta{replacement text} for a
+% macro.
+% \begin{texnote}
+% This is \TeX{}'s \cs{meaning} primitive.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{\cs_show:N, \cs_show:c}
+% \begin{syntax}
+% \cs{cs_show:N} \meta{control sequence}
+% \end{syntax}
+% Displays the definition of the \meta{control sequence} on the
+% terminal.
+% \begin{texnote}
+% This is the \TeX{} primitive \cs{show}.
+% \end{texnote}
+% \end{function}
+%
+
+% \subsection{Converting to and from control sequences}
+%
+% \begin{function}[EXP]{\use:c}
+% \begin{syntax}
+% \cs{use:c} \Arg{control sequence name}
+% \end{syntax}
+% Converts the given \meta{control sequence name} into a single
+% control sequence token. This process requires two expansions.
+% The content for \meta{control sequence name} may be literal
+% material or from other expandable functions. The
+% \meta{control sequence name} must, when fully expanded, consist
+% of character tokens which are not active: typically, they will
+% be of category code $10$ (space), $11$ (letter)
+% or $12$ (other), or a mixture of these. As an example, both
+% \begin{verbatim}
+% \use:c { a b c }
+% \end{verbatim}
+% and
+% \begin{verbatim}
+% \tl_new:N \l_my_tl
+% \tl_set:Nn \l_my_tl { a b c }
+% \use:c { \tl_use:N \l_my_tl }
+% \end{verbatim}
+% would be equivalent to
+% \begin{verbatim}
+% \abc
+% \end{verbatim}
+% after two expansions of \cs{use:c}.
+% \end{function}
+%
+% \begin{function}[EXP]{\cs:w, \cs_end:}
+% \begin{syntax}
+% \cs{cs:w} \meta{control sequence name} \cs{cs_end:}
+% \end{syntax}
+% Converts the given \meta{control sequence name} into a single
+% control sequence token. This process requires one expansion.
+% The content for \meta{control sequence name} may be literal
+% material or from other expandable functions. The
+% \meta{control sequence name} must, when fully expanded, consist
+% of character tokens which are not active: typically, they will
+% be of category code $10$ (space), $11$ (letter)
+% or $12$ (other), or a mixture of these. As an example, both
+% \begin{verbatim}
+% \cs:w a b c \cs_end:
+% \end{verbatim}
+% and
+% \begin{verbatim}
+% \tl_new:N \l_my_tl
+% \tl_set:Nn \l_my_tl { a b c }
+% \cs:w \tl_use:N \l_my_tl \cs_end:
+% \end{verbatim}
+% would be equivalent to
+% \begin{verbatim}
+% \abc
+% \end{verbatim}
+% after one expansion of \cs{cs:w}.
+% \begin{texnote}
+% These are the \TeX{} primitives \cs{csname} and \cs{endcsname}.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[EXP]{\cs_to_str:N}
+% \begin{syntax}
+% \cs{cs_to_str:N} \Arg{control sequence}
+% \end{syntax}
+% Converts the given \meta{control sequence} into a series of
+% characters with category code $12$ (other), except spaces,
+% of category code $10$. The sequence will \emph{not} include
+% the current escape token, \emph{cf.}~\cs{token_to_str:N}.
+% Full expansion of this function requires a variable number
+% of expansion steps (either 3 or 4), and so an
+% \texttt{f}- or \texttt{x}-type expansion will be required to
+% convert the \meta{control sequence} to a sequence of characters
+% in the input stream.
+% \end{function}
+%
+% \section{Using or removing tokens and arguments}
+%
+% Tokens in the input can be read and used or read and discarded.
+% If one or more tokens are wrapped in braces then in absorbing them
+% the outer set will be removed. At the same time, the category code
+% of each token is set when the token is read by a function (if it
+% is read more than once, the category code is determined by the
+% the situation in force when first function absorbs the token).
+%
+% \begin{function}[EXP]{\use:n, \use:nn, \use:nnn, \use:nnnn}
+% \begin{syntax}
+% \cs{use:n} \Arg{group1}
+% \cs{use:nn} \Arg{group1} \Arg{group2}
+% \cs{use:nnn} \Arg{group1} \Arg{group2} \Arg{group3}
+% \cs{use:nnn} \Arg{group1} \Arg{group2} \Arg{group3} \Arg{group4}
+% \end{syntax}
+% As illustrated, these functions will absorb between one and four
+% arguments, as indicated by the argument specifier. The braces
+% surrounding each argument will be removed leaving the remaining
+% tokens in the input stream. The category code of these tokens will
+% also be fixed by this process (if it has not already been by some
+% other absorption). All of these functions require only a single
+% expansion to operate, so that one expansion of
+% \begin{verbatim}
+% \use:nn { abc } { { def } }
+% \end{verbatim}
+% will result in the input stream containing
+% \begin{verbatim}
+% abc { def }
+% \end{verbatim}
+% \emph{i.e.} only the outer braces will be removed.
+% \end{function}
+%
+% \begin{function}[EXP]{\use_i:nn, \use_ii:nn}
+% \begin{syntax}
+% \cs{use_i:nn} \Arg{group1} \Arg{group2}
+% \end{syntax}
+% These functions will absorb two groups and leave only the
+% first or the second in the input stream. The braces surrounding the
+% arguments will be removed as part of this process. The category code
+% of these tokens will also be fixed (if it has not already been by
+% some other absorption). A single expansion is needed for the
+% functions to take effect.
+% \end{function}
+%
+% \begin{function}[EXP]{\use_i:nnn, \use_ii:nnn, \use_iii:nnn}
+% \begin{syntax}
+% \cs{use_i:nnn} \Arg{group1} \Arg{group2} \Arg{group3}
+% \end{syntax}
+% These functions will absorb three groups and leave only of these
+% in the input stream. The braces surrounding the arguments will be
+% removed as part of this process. The category code of these tokens
+% will also be fixed (if it has not already been by some other
+% absorption). A single expansion is needed for the functions to take
+% effect.
+% \end{function}
+%
+% \begin{function}[EXP]
+% {\use_i:nnnn, \use_ii:nnnn, \use_iii:nnnn , \use_iv:nnnn}
+% \begin{syntax}
+% \cs{use_i:nnnn} \Arg{group1} \Arg{group2} \Arg{group3} \Arg{group4}
+% \end{syntax}
+% These functions will absorb four groups and leave only of these
+% in the input stream. The braces surrounding the arguments will be
+% removed as part of this process. The category code of these tokens
+% will also be fixed (if it has not already been by some other
+% absorption). A single expansion is needed for the functions to take
+% effect.
+% \end{function}
+%
+% \begin{function}[EXP]{\use_i_ii:nnn}
+% \begin{syntax}
+% \cs{use_i_ii:nnn} \Arg{group1} \Arg{group2} \Arg{group3}
+% \end{syntax}
+% This functions will absorb three groups and leave the first and
+% second in the input stream. The braces surrounding the arguments
+% will be removed as part of this process. The category code of
+% these tokens will also be fixed (if it has not already been by
+% some other absorption). A single expansion is needed for the
+% functions to take effect. An example:
+% \begin{verbatim}
+% \use_i_ii:nnn { abc } { { def } } { ghi }
+% \end{verbatim}
+% will result in the input stream containing
+% \begin{verbatim}
+% abc { def }
+% \end{verbatim}
+% \emph{i.e.} the outer braces will be removed and the third group
+% will be removed.
+% \end{function}
+%
+% \begin{function}[EXP]
+% {
+% \use_none:n ,
+% \use_none:nn ,
+% \use_none:nnn ,
+% \use_none:nnnn ,
+% \use_none:nnnnn ,
+% \use_none:nnnnnn ,
+% \use_none:nnnnnnn ,
+% \use_none:nnnnnnnn ,
+% \use_none:nnnnnnnnn
+% }
+% \begin{syntax}
+% \cs{use_none:n} \Arg{group1}
+% \end{syntax}
+% These functions absorb between one and nine groups from the
+% input stream, leaving nothing on the resulting input stream.
+% These functions work after a single expansion. One or more of the
+% \texttt{n} arguments may be an unbraced single token
+% (\emph{i.e.}~an \texttt{N} argument).
+% \end{function}
+%
+% \begin{function}{\use:x}
+% \begin{syntax}
+% \cs{use:x} \Arg{expandable tokens}
+% \end{syntax}
+% Fully expands the \meta{expandable tokens} and inserts the
+% result into the input stream at the current location.
+% \end{function}
+%
+% \subsection{Selecting tokens from delimited arguments}
+%
+% A different kind of function for selecting tokens from the token
+% stream are those that use delimited arguments.
+%
+% \begin{function}[EXP]
+% {
+% \use_none_delimit_by_q_nil:w,
+% \use_none_delimit_by_q_stop:w,
+% \use_none_delimit_by_q_recursion_stop:w
+% }
+% \begin{syntax}
+% \cs{use_none_delimit_by_q_nil:w} \meta{balanced text} \cs{q_nil}
+% \end{syntax}
+% Absorb the \meta{balanced} text form the input stream delimited by
+% the marker given in the function name, leaving nothing in the
+% input stream.
+% \end{function}
+%
+% \begin{function}[EXP]
+% {
+% \use_i_delimit_by_q_nil:nw,
+% \use_i_delimit_by_q_stop:nw,
+% \use_i_delimit_by_q_recursion_stop:nw
+% }
+% \begin{syntax}
+% \cs{use_i_delimit_by_q_nil:nw} \Arg{inserted tokens}
+% ~~\meta{balanced text} \cs{q_nil}
+% \end{syntax}
+% Absorb the \meta{balanced} text form the input stream delimited by
+% the marker given in the function name, leaving \meta{inserted tokens}
+% in the input stream for further processing.
+% \end{function}
+%
+%
+% \begin{function}[EXP]
+% {
+% \use_i_after_fi:nw,
+% \use_i_after_else:nw,
+% \use_i_after_or:nw,
+% \use_i_after_orelse:nw
+% }
+% \begin{syntax}
+% \cs{use_i_after_fi:nw} \Arg{inserted tokens} \cs{fi:}
+% \cs{use_i_after_else:nw} \Arg{inserted tokens} \cs{else:}
+% ~~\meta{balanced text} \cs{fi:}
+% \cs{use_i_after_or:nw} \Arg{inserted tokens} \cs{or:}
+% ~~\meta{balanced text} \cs{fi:}
+% \cs{use_i_after_orelse:nw} \Arg{inserted tokens} \cs{or:} or \cs{else:}
+% ~~\meta{balanced text} \cs{fi:}
+% \end{syntax}
+% Absorb the \meta{balanced text}, if appropriate, delimited by
+% the function name given. The \meta{inserted tokens} are then placed
+% in the input stream after the delimiter. Thus for example
+% \begin{verbatim}
+% \use_i_after_fi:nw { some tokens } \fi:
+% \end{verbatim}
+% will leave
+% \begin{verbatim}
+% \fi: some tokens
+% \end{verbatim}
+% in the input stream for further processing. See the discussion of the
+% primitive \TeX{} conditionals for more detail on \cs{else:}, \cs{fi:}
+% and \cs{or:}.
+% \end{function}
+%
+% \subsection{Decomposing control sequences}
+%
+% \begin{function}[EXP]{\cs_get_arg_count_from_signature:N}
+% \begin{syntax}
+% \cs{cs_get_arg_count_from_signature:N} \meta{function}
+% \end{syntax}
+% Splits the \meta{function} into the name (\emph{i.e.}~the part
+% before the colon) and the signature (\emph{i.e.}~after the colon).
+% The \meta{number} of tokens in the \meta{signature} is then left in
+% the input stream. If there was no \meta{signature} then the result is
+% the marker value $-1$.
+% \end{function}
+%
+% \begin{function}[EXP]{\cs_get_function_name:N}
+% \begin{syntax}
+% \cs{cs_get_function_name:NN} \meta{function}
+% \end{syntax}
+% Splits the \meta{function} into the name (\emph{i.e.}~the part
+% before the colon) and the signature (\emph{i.e.}~after the colon).
+% The \meta{name} is then left in the input stream without the escape
+% character present made up of tokens with category code $12$
+% (other).
+% \end{function}
+%
+% \begin{function}{[EXP]\cs_get_function_signature:N}
+% \begin{syntax}
+% \cs{cs_get_function_signature:NN} \meta{function}
+% \end{syntax}
+% Splits the \meta{function} into the name (\emph{i.e.}~the part
+% before the colon) and the signature (\emph{i.e.}~after the colon).
+% The \meta{signature} is then left in the input stream made up of
+% tokens with category code $12$ (other).
+% \end{function}
+%
+% \begin{function}EXP]{\cs_split_function:NN}
+% \begin{syntax}
+% \cs{cs_split_function:NN} \meta{function} \meta{processor}
+% \end{syntax}
+% Splits the \meta{function} into the name (\emph{i.e.}~the part
+% before the colon) and the signature (\emph{i.e.}~after the colon).
+% This information is then placed in the input stream after the
+% \meta{processor} function in three parts: the \meta{name}, the
+% \meta{signature} and a logic token indicating if a colon was found
+% (to differentiate variables from function names). The \meta{name}
+% will not include the escape character, and both the \meta{name} and
+% \meta{signature} are made up of tokens with category code $12$
+% (other). The \meta{processor} should be a function with argument
+% specification \texttt{:nnN} (plus any trailing arguments needed).
+% \end{function}
+%
+% \begin{function}[EXP]{\cs_to_str:N}
+% \begin{syntax}
+% \cs{cs_to_str:N} \Arg{control sequence}
+% \end{syntax}
+% Converts the given \meta{control sequence} into a series of
+% characters with category code $12$ (other), except spaces,
+% of category code $10$. The sequence will \emph{not} include
+% the current escape token, \emph{cf.}~\cs{token_to_str:N}.
+% Full expansion of this function requires a variable number
+% of expansion steps (either 3 or 4), and so an
+% \texttt{f}- or \texttt{x}-type expansion will be required to
+% convert the \meta{control sequence} to a sequence of characters
+% in the input stream.
+% \end{function}
+%
+% \section{Predicates and conditionals}
+% \label{sec:predicates}
+%
+% \LaTeX3 has three concepts for conditional flow processing:
+% \begin{description}
+% \item[Branching conditionals]
+% Functions that carry out a test and then execute, depending on its
+% result, either the code supplied in the \meta{true arg} or the
+% \meta{false arg}.
+% These arguments are denoted with |T| and |F|, respectively. An
+% example would be
+% \begin{quote}
+% |\cs_if_free:cTF{abc}| \Arg{true code} \Arg{false code}
+% \end{quote}
+% a function that will turn the first argument into a control sequence
+% (since it's marked as |c|) then checks whether this control sequence
+% is still free and then depending on the result carry out the code in
+% the second argument (true case) or in the third argument (false
+% case).
+%
+% These type of functions are known as \enquote{conditionals};
+% whenever a |TF| function is defined it will usually be accompanied by
+% |T| and |F| functions as well. These are provided for convenience when
+% the branch only needs to go a single way. Package writers are free to
+% choose which types to define but the kernel definitions will always
+% provide all three versions.
+%
+% Important to note is that these branching conditionals with \meta{true
+% code} and/or \meta{false code} are always defined in a way that the
+% code of the chosen alternative can operate on following tokens in
+% the input stream.
+%
+% These conditional functions may or may not be fully expandable, but if
+% they are expandable they will be accompanied by a \enquote{predicate}
+% for the same test as described below.
+%
+% \item[Predicates]
+% \enquote{Predicates} are functions that return a special type of
+% boolean value which can be tested by the function \cs{if_predicate:w}
+% or in the boolean expression parser. All functions of this type
+% are expandable and have names that end with |_p| in the
+% description part. For example,
+% \begin{quote}
+% |\cs_if_free_p:N|
+% \end{quote}
+% would be a predicate function for the same type of test as the
+% conditional described above. It would return \enquote{true} if its
+% argument (a single token denoted by |N|) is still free for definition.
+% It would be used in constructions like
+% \begin{quote}
+% |\if_predicate:w \cs_if_free_p:N \l_tmpz_tl| \\
+% | |\meta{true code} \\
+% |else:| \\
+% | |\meta{false code}\\
+% |\fi:| \\
+% \end{quote}
+% or in expressions utilizing the boolean logic parser:
+% \begin{quote}
+% |\bool_if:nTF {| \\
+% \verb" \cs_if_free_p:N \l_tmpz_tl || \cs_if_free_p:N \g_tmpz_tl " \\
+% |}|
+% \Arg{true code} \Arg{false code}
+% \end{quote}
+%
+% Like their branching cousins, predicate functions ensure that all
+% underlying primitive |\else:| or |\fi:| have been removed before
+% returning the boolean true or false values.\footnote{If defined
+% using the interface provided.}
+%
+% For each predicate defined, a \enquote{predicate conditional} will
+% also exist that behaves like a conditional described above.
+%
+% \item[Primitive conditionals]
+% There is a third variety of conditional, which is the original
+% concept used in plain \TeX{} and \LaTeXe{}. Their use is discouraged
+% in \pkg{expl3} (although still used in low-level definitions)
+% because they are more fragile and in many cases require more
+% expansion control (hence more code) than the two types of
+% conditionals described above.
+% \end{description}
+%
+% \begin{variable}{\c_true_bool, \c_false_bool}
+% Constants that represent |true| and |false|, respectively. Used to
+% implement predicates.
+% \end{variable}
+%
+% \subsection{Tests on control sequences}
+%
+% \begin{function}[EXP,pTF]{\cs_if_eq:NN}
+% \begin{syntax}
+% \cs{cs_if_eq_p:NN} \Arg{cs1} \Arg{cs2}
+% \cs{cs_if_eq:NNTF} \Arg{cs1} \Arg{cs2} \Arg{true code}
+% ~~\Arg{false code}
+% \end{syntax}
+% Compares the definition of two \meta{control sequences} and
+% is logically \texttt{true} if the two are the same. The branching
+% versions then leave either \meta{true code} or \meta{false code}
+% in the input stream, as appropriate to the truth of the test and the
+% variant of the function chosen. The logical truth of the test is left
+% in the input stream by the predicate version.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\cs_if_exist:N, \cs_if_exist:c}
+% \begin{syntax}
+% \cs{cs_if_exist_p:N} \meta{control sequence}
+% \cs{cs_if_exist:NTF} \meta{control sequence} \meta{true code}
+% ~~\meta{false code}
+% \end{syntax}
+% Tests whether the \meta{control sequence} is currently defined
+% (whether as a function or another control sequence type). Any
+% valid definition of \meta{control sequence} will evaluate as
+% \texttt{true}. The branching versions then leave either
+% \meta{true code} or \meta{false code} in the input stream, as
+% appropriate to the truth of the test and the variant of the function
+% chosen. The logical truth of the test is left in the input stream by
+% the predicate version.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\cs_if_free:N, \cs_if_free:c}
+% \begin{syntax}
+% \cs{cs_if_free_p:N} \meta{control sequence}
+% \cs{cs_if_free:NTF} \meta{control sequence} \meta{true code}
+% ~~\meta{false code}
+% \end{syntax}
+% Tests whether the \meta{control sequence} is currently free to
+% be defined. This test will be \texttt{false} if the
+% \meta{control sequence} currently exists (as defined by
+% \cs{cs_if_exist:N}). The branching versions then leave either
+% \meta{true code} or \meta{false code} in the input stream, as
+% appropriate to the truth of the test and the variant of the function
+% chosen. The logical truth of the test is left in the input stream by
+% the predicate version.
+% \end{function}
+%
+% \subsection{Testing string equality}
+%
+% \begin{function}[EXP,pTF]
+% {
+% \str_if_eq:nn, \str_if_eq:Vn, \str_if_eq:on, \str_if_eq:no,
+% \str_if_eq:nV, \str_if_eq:VV, \str_if_eq:xx
+% }
+% \begin{syntax}
+% \cs{str_if_eq_p:nn} \Arg{tl1} \Arg{tl2}
+% \cs{str_if_eq:nnTF} \Arg{tl1} \Arg{tl2} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Compares the two \meta{token lists} on a character by character
+% basis, and is \texttt{true} if the two lists contain the same
+% characters in the same order. Thus for example
+% \begin{verbatim}
+% \str_if_eq_p:xx { abc } { \tl_to_str:n { abc } }
+% \end{verbatim}
+% is logically \texttt{true}. The branching versions then leave either
+% \meta{true code} or \meta{false code} in the input stream, as
+% appropriate to the truth of the test and the variant of the function
+% chosen. The logical truth of the test is left in the input stream by
+% the predicate version. All versions of these functions are fully
+% expandable (including those involving an \texttt{x}-type
+% expansion).
+% \end{function}
+%
+% \subsection{Engine-specific conditionals}
+%
+% \begin{function}[EXP,TF]{\luatex_if_engine:}
+% \begin{syntax}
+% \cs{luatex_if_luatex:TF} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Detects is the document is being compiled using \LuaTeX{}. The
+% branching versions then leave either \meta{true code} or
+% \meta{false code} in the input stream, as appropriate to the truth
+% of the test and the variant of the function chosen.
+% \end{function}
+%
+% \begin{function}[EXP,TF]{\pdftex_if_engine:}
+% \begin{syntax}
+% \cs{pdftex_if_engine:TF} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Detects is the document is being compiled using \pdfTeX{}. The
+% branching versions then leave either \meta{true code} or
+% \meta{false code} in the input stream, as appropriate to the truth
+% of the test and the variant of the function chosen.
+% \end{function}
+%
+% \begin{function}[EXP,TF]{\xetex_if_engine:}
+% \begin{syntax}
+% \cs{xetex_if_engine:TF} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Detects is the document is being compiled using \XeTeX{}. The
+% branching versions then leave either \meta{true code} or
+% \meta{false code} in the input stream, as appropriate to the truth
+% of the test and the variant of the function chosen.
+% \end{function}
+%
+% \begin{variable}
+% {
+% \c_luatex_is_engine_bool, \c_pdftex_is_engine_bool,
+% \c_xetex_is_engine_bool
+% }
+% Boolean versions of the engine conditionals, for use in predicate
+% tests.
+% \end{variable}
+%
+% \subsection{Primitive conditionals}
+%
+% The \eTeX{} engine itself provides many different conditionals. Some
+% expand whatever comes after them and others don't. Hence the names
+% for these underlying functions will often contain a |:w| part but
+% higher level functions are often available. See for instance
+% |\int_compare_p:nNn| which is a wrapper for |\if_num:w|.
+%
+% Certain conditionals deal with specific data types like boxes and
+% fonts and are described there. The ones described below are either
+% the universal conditionals or deal with control sequences. We will
+% prefix primitive conditionals with |\if_|.
+%
+% \begin{function}[EXP]
+% {\if_true:, \if_false:, \or:, \else:, \fi:, \reverse_if:N}
+% \begin{syntax}
+% "\if_true:" <true code> "\else:" <false code> "\fi:" \\
+% "\if_false:" <true code> "\else:" <false code> "\fi:" \\
+% "\reverse_if:N" <primitive conditional>
+% \end{syntax}
+% "\if_true:" always executes <true code>, while "\if_false:" always
+% executes <false code>. "\reverse_if:N" reverses any two-way primitive
+% conditional. "\else:" and "\fi:" delimit the branches of the
+% conditional. "\or:" is used in case switches, see \pkg{l3intexpr}
+% for more.
+% \begin{texnote}
+% These are equivalent to their corresponding \TeX\ primitive
+% conditionals; |\reverse_if:N| is \eTeX's |\unless|.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[EXP]{\if_meaning:w}
+% \begin{syntax}
+% "\if_meaning:w" <arg1> <arg2> <true code> "\else:" <false code> "\fi:"
+% \end{syntax}
+% "\if_meaning:w" executes <true code> when <arg1> and <arg2> are the same,
+% otherwise it executes <false code>.
+% <arg1> and <arg2> could be functions, variables, tokens; in all cases the
+% \emph{unexpanded} definitions are compared.
+% \begin{texnote}
+% This is \TeX's |\ifx|.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[EXP]{\if:w, \if_charcode:w,\if_catcode:w}
+% \begin{syntax}
+% "\if:w" <token1> <token2> <true code> "\else:" <false code> "\fi:" \\
+% "\if_catcode:w" <token1> <token2> <true code> "\else:" <false
+% code> "\fi:"
+% \end{syntax}
+% These conditionals will expand any following tokens until two
+% unexpandable tokens are left. If you wish to prevent this expansion,
+% prefix the token in question with "\exp_not:N". "\if_catcode:w"
+% tests if the category codes of the two tokens are the same whereas
+% "\if:w" tests if the character codes are
+% identical. "\if_charcode:w" is an alternative name for "\if:w".
+% \end{function}
+%
+% \begin{function}[EXP]{\if_predicate:w}
+% \begin{syntax}
+% "\if_predicate:w" <predicate> <true code> "\else:" <false code> "\fi:"
+% \end{syntax}
+% This function takes a predicate function and
+% branches according to the result. (In practice this function would also
+% accept a single boolean variable in place of the <predicate> but to make the
+% coding clearer this should be done through "\if_bool:N".)
+% \end{function}
+%
+% \begin{function}[EXP]{\if_bool:N}
+% \begin{syntax}
+% "\if_bool:N" <boolean> <true code> "\else:" <false code> "\fi:"
+% \end{syntax}
+% This function takes a boolean variable and
+% branches according to the result.
+% \end{function}
+%
+% \begin{function}[EXP]{\if_cs_exist:N, \if_cs_exist:w}
+% \begin{syntax}
+% "\if_cs_exist:N" <cs> <true code> "\else:" <false code> "\fi:" \\
+% "\if_cs_exist:w" <tokens> "\cs_end:" <true code> "\else:" <false
+% code> "\fi:"
+% \end{syntax}
+% Check if <cs> appears in the hash table or if the control sequence
+% that can be formed from <tokens> appears in the hash table. The
+% latter function does not turn the control sequence in question into
+% "\scan_stop:"! This can be useful when dealing with control
+% sequences which cannot be entered as a single token.
+% \end{function}
+%
+% \begin{function}[EXP]
+% {
+% \if_mode_horizontal:, \if_mode_vertical:,
+% \if_mode_math:, \if_mode_inner:
+% }
+% \begin{syntax}
+% "\if_mode_horizontal:" <true code> "\else:" <false code> "\fi:"
+% \end{syntax}
+% Execute <true code> if currently in horizontal mode, otherwise
+% execute <false code>. Similar for the other functions.
+% \end{function}
+%
+% \section{Internal kernel functions}
+%
+% \begin{function}{\chk_if_exist_cs:N, \chk_if_exist_cs:c}
+% \begin{syntax}
+% \cs{chk_if_exist_cs:N} \meta{cs}
+% \end{syntax}
+% This function checks that \meta{cs} exists according to the
+% criteria for \cs{cs_if_exist_p:N}, and if not raises a kernel-level
+% error.
+% \end{function}
+%
+% \begin{function}{\chk_if_free_cs:N, \chk_if_free_cs:c}
+% \begin{syntax}
+% \cs{chk_if_free_cs:N} \meta{cs}
+% \end{syntax}
+% This function checks that \meta{cs} is free according to the
+% criteria for \cs{cs_if_free_p:N}, and if not raises a kernel-level
+% error.
+% \end{function}
+%
+% \begin{function}{\pref_global:D, \pref_long:D, \pref_protected:D}
+% \begin{syntax}
+% \cs{pref_global:D} \cs{cs_set_nopar:Npn}
+% \end{syntax}
+% Prefix functions that can be used in front of some definition
+% functions (namely \ldots). The result of prefixing a function
+% definition with \cs{pref_global:D} makes the definition global,
+% \cs{pref_long:D} change the argument scanning mechanism so that it
+% allows \cs{par} tokens in the argument of the prefixed function,
+% and \cs{pref_protected:D} makes the definition robust inside
+% \texttt{x}-type expansions.
+%
+% None of these internal functions should be used by a programmer since
+% the necessary combinations are all available as separate function,
+% \emph{e.g.} \cs{cs_set:Npn} is internally implemented as \cs{pref_long:D}
+% \c{cs_set_nopar:Npn}.
+% \begin{texnote}
+% These prefixes are the primitives \tn{global}, \tn{long}, and
+% \cs{protected}.
+% \end{texnote}
+% \end{function}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3basics} implementation}
+%
+% \begin{macrocode}
+%<*initex|package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*package>
+\ProvidesExplPackage
+ {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
+\package_check_loaded_expl:
+%</package>
+% \end{macrocode}
+%
+% \subsection{Renaming some \TeX{} primitives (again)}
+%
+% Having given all the \TeX{} primitives a consistent name, we need to
+% give sensible names to the ones we actually want to use.
+% These will be defined as needed in the appropriate modules, but
+% do a few now, just to get started.\footnote{This renaming gets expensive
+% in terms of csname usage, an alternative scheme would be to just use
+% the \cs{tex\ldots:D} name in the cases where no good alternative exists.}
+%
+% \begin{macro}{\cs_set_eq:NwN}
+% A pretty basic requirement: \cs{let} one control sequence to another.
+% \begin{macrocode}>
+\tex_let:D \cs_set_eq:NwN \tex_let:D
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\if_true:}
+% \begin{macro}{\if_false:}
+% \begin{macro}{\or:}
+% \begin{macro}{\else:}
+% \begin{macro}{\fi:}
+% \begin{macro}{\reverse_if:N}
+% \begin{macro}{\if:w}
+% \begin{macro}{\if_bool:N}
+% \begin{macro}{\if_predicate:w}
+% \begin{macro}{\if_charcode:w}
+% \begin{macro}{\if_catcode:w}
+% Then some conditionals.
+% \begin{macrocode}
+\cs_set_eq:NwN \if_true: \tex_iftrue:D
+\cs_set_eq:NwN \if_false: \tex_iffalse:D
+\cs_set_eq:NwN \or: \tex_or:D
+\cs_set_eq:NwN \else: \tex_else:D
+\cs_set_eq:NwN \fi: \tex_fi:D
+\cs_set_eq:NwN \reverse_if:N \etex_unless:D
+\cs_set_eq:NwN \if:w \tex_if:D
+\cs_set_eq:NwN \if_bool:N \tex_ifodd:D
+\cs_set_eq:NwN \if_predicate:w \tex_ifodd:D
+\cs_set_eq:NwN \if_charcode:w \tex_if:D
+\cs_set_eq:NwN \if_catcode:w \tex_ifcat:D
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\if_meaning:w}
+% \begin{macrocode}
+\cs_set_eq:NwN \if_meaning:w \tex_ifx:D
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\if_mode_math:}
+% \begin{macro}{\if_mode_horizontal:}
+% \begin{macro}{\if_mode_vertical:}
+% \begin{macro}{\if_mode_inner:}
+% \TeX{} lets us detect some if its modes.
+% \begin{macrocode}
+\cs_set_eq:NwN \if_mode_math: \tex_ifmmode:D
+\cs_set_eq:NwN \if_mode_horizontal: \tex_ifhmode:D
+\cs_set_eq:NwN \if_mode_vertical: \tex_ifvmode:D
+\cs_set_eq:NwN \if_mode_inner: \tex_ifinner:D
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\if_cs_exist:N}
+% \begin{macro}{\if_cs_exist:w}
+% \begin{macrocode}
+\cs_set_eq:NwN \if_cs_exist:N \etex_ifdefined:D
+\cs_set_eq:NwN \if_cs_exist:w \etex_ifcsname:D
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\exp_after:wN}
+% \begin{macro}{\exp_not:N}
+% \begin{macro}{\exp_not:n}
+% The three |\exp_| functions are used in the \textsf{l3expan} module
+% where they are described.
+% \begin{macrocode}
+\cs_set_eq:NwN \exp_after:wN \tex_expandafter:D
+\cs_set_eq:NwN \exp_not:N \tex_noexpand:D
+\cs_set_eq:NwN \exp_not:n \etex_unexpanded:D
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\token_to_meaning:N}
+% \begin{macro}{\token_to_str:N}
+% \begin{macro}{\cs:w}
+% \begin{macro}{\cs_end:}
+% \begin{macro}{\cs_meaning:N}
+% \begin{macro}{\cs_show:N}
+% \begin{macrocode}
+\cs_set_eq:NwN \token_to_meaning:N \tex_meaning:D
+\cs_set_eq:NwN \token_to_str:N \tex_string:D
+\cs_set_eq:NwN \cs:w \tex_csname:D
+\cs_set_eq:NwN \cs_end: \tex_endcsname:D
+\cs_set_eq:NwN \cs_meaning:N \tex_meaning:D
+\cs_set_eq:NwN \cs_show:N \tex_show:D
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\scan_stop:}
+% \begin{macro}{\group_begin:}
+% \begin{macro}{\group_end:}
+% The next three are basic functions for which there also exist
+% versions that are safe inside alignments. These safe versions are
+% defined in the \textsf{l3prg} module.
+% \begin{macrocode}
+\cs_set_eq:NwN \scan_stop: \tex_relax:D
+\cs_set_eq:NwN \group_begin: \tex_begingroup:D
+\cs_set_eq:NwN \group_end: \tex_endgroup:D
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\if_int_compare:w}
+% \begin{macro}{\int_to_roman:w}
+% \begin{macrocode}
+\cs_set_eq:NwN \if_int_compare:w \tex_ifnum:D
+\cs_set_eq:NwN \int_to_roman:w \tex_romannumeral:D
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\group_insert_after:N}
+% \begin{macrocode}
+\cs_set_eq:NwN \group_insert_after:N \tex_aftergroup:D
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\pref_global:D}
+% \begin{macro}{\pref_long:D}
+% \begin{macro}{\pref_protected:D}
+% \begin{macrocode}
+\cs_set_eq:NwN \pref_global:D \tex_global:D
+\cs_set_eq:NwN \pref_long:D \tex_long:D
+\cs_set_eq:NwN \pref_protected:D \etex_protected:D
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\exp_args:Nc}
+% Discussed in \pkg{l3expan}, but needed much earlier.
+% \begin{macrocode}
+\tex_long:D \tex_def:D \exp_args:Nc #1#2 { \exp_after:wN #1 \cs:w #2 \cs_end: }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\token_to_str:c}
+% \begin{macro}{\cs_meaning:c}
+% \begin{macro}{\cs_show:c}
+%% A small number of variants by hand.
+% \begin{macrocode}
+\tex_def:D \cs_meaning:c { \exp_args:Nc \cs_meaning:N }
+\tex_def:D \token_to_str:c { \exp_args:Nc \token_to_str:N }
+\tex_def:D \cs_show:c { \exp_args:Nc \cs_show:N }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection {Defining functions}
+%
+% We start by providing functions for the typical definition
+% functions. First the local ones.
+%
+% \begin{macro}{\cs_set_nopar:Npn}
+% \begin{macro}{\cs_set_nopar:Npx}
+% \begin{macro}{\cs_set:Npn}
+% \begin{macro}{\cs_set:Npx}
+% \begin{macro}{\cs_set_protected_nopar:Npn}
+% \begin{macro}{\cs_set_protected_nopar:Npx}
+% \begin{macro}{\cs_set_protected:Npn}
+% \begin{macro}{\cs_set_protected:Npx}
+% All assignment functions in \LaTeX3 should be naturally robust;
+% after all, the \TeX{} primitives for assignments are and it can be
+% a cause of problems if others aren't.
+% \begin{macrocode}
+\cs_set_eq:NwN \cs_set_nopar:Npn \tex_def:D
+\cs_set_eq:NwN \cs_set_nopar:Npx \tex_edef:D
+\pref_protected:D \cs_set_nopar:Npn \cs_set:Npn
+ { \pref_long:D \cs_set_nopar:Npn }
+\pref_protected:D \cs_set_nopar:Npn \cs_set:Npx
+ { \pref_long:D \cs_set_nopar:Npx }
+\pref_protected:D \cs_set_nopar:Npn \cs_set_protected_nopar:Npn
+ { \pref_protected:D \cs_set_nopar:Npn }
+\pref_protected:D \cs_set_nopar:Npn \cs_set_protected_nopar:Npx
+ { \pref_protected:D \cs_set_nopar:Npx }
+\cs_set_protected_nopar:Npn \cs_set_protected:Npn
+ { \pref_protected:D \pref_long:D \cs_set_nopar:Npn }
+\cs_set_protected_nopar:Npn \cs_set_protected:Npx
+ { \pref_protected:D \pref_long:D \cs_set_nopar:Npx }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\cs_gset_nopar:Npn}
+% \begin{macro}{\cs_gset_nopar:Npx}
+% \begin{macro}{\cs_gset:Npn}
+% \begin{macro}{\cs_gset:Npx}
+% \begin{macro}{\cs_gset_protected_nopar:Npn}
+% \begin{macro}{\cs_gset_protected_nopar:Npx}
+% \begin{macro}{\cs_gset_protected:Npn}
+% \begin{macro}{\cs_gset_protected:Npx}
+% Global versions of the above functions.
+% \begin{macrocode}
+\cs_set_eq:NwN \cs_gset_nopar:Npn \tex_gdef:D
+\cs_set_eq:NwN \cs_gset_nopar:Npx \tex_xdef:D
+\cs_set_protected_nopar:Npn \cs_gset:Npn
+ { \pref_long:D \cs_gset_nopar:Npn }
+\cs_set_protected_nopar:Npn \cs_gset:Npx
+ { \pref_long:D \cs_gset_nopar:Npx }
+\cs_set_protected_nopar:Npn \cs_gset_protected_nopar:Npn
+ { \pref_protected:D \cs_gset_nopar:Npn }
+\cs_set_protected_nopar:Npn \cs_gset_protected_nopar:Npx
+ { \pref_protected:D \cs_gset_nopar:Npx }
+\cs_set_protected_nopar:Npn \cs_gset_protected:Npn
+ { \pref_protected:D \pref_long:D \cs_gset_nopar:Npn }
+\cs_set_protected_nopar:Npn \cs_gset_protected:Npx
+ { \pref_protected:D \pref_long:D \cs_gset_nopar:Npx }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Selecting tokens}
+%
+% \begin{macro}{\use:c}
+% This macro grabs its argument and returns a csname from it.
+% \begin{macrocode}
+\cs_set:Npn \use:c #1 { \cs:w #1 \cs_end: }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\use:x}
+% \begin{macro}[aux]{\cs_tmp:w}
+% Fully expands its argument and passes it to the input stream.
+% Uses |\cs_tmp:| as a scratch register but does not affect it.
+% \begin{macrocode}
+\cs_set_protected:Npn \use:x #1
+ {
+ \group_begin:
+ \cs_set:Npx \cs_tmp:w {#1}
+ \exp_after:wN
+ \group_end:
+ \cs_tmp:w
+ }
+\cs_set:Npn \cs_tmp:w { }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\use:n}
+% \begin{macro}{\use:nn}
+% \begin{macro}{\use:nnn}
+% \begin{macro}{\use:nnnn}
+% These macro grabs its arguments and returns it back to the input
+% (with outer braces removed).
+% \begin{macrocode}
+\cs_set:Npn \use:n #1 {#1}
+\cs_set:Npn \use:nn #1#2 {#1#2}
+\cs_set:Npn \use:nnn #1#2#3 {#1#2#3}
+\cs_set:Npn \use:nnnn #1#2#3#4 {#1#2#3#4}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\use_i:nn}
+% \begin{macro}{\use_ii:nn}
+% The equivalent to \LaTeXe{}'s \cs{@firstoftwo} and \cs{@secondoftwo}.
+% \begin{macrocode}
+\cs_set:Npn \use_i:nn #1#2 {#1}
+\cs_set:Npn \use_ii:nn #1#2 {#2}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\use_i:nnn}
+% \begin{macro}{\use_ii:nnn}
+% \begin{macro}{\use_iii:nnn}
+% \begin{macro}{\use_i_ii:nnn}
+% \begin{macro}{\use_i:nnnn}
+% \begin{macro}{\use_ii:nnnn}
+% \begin{macro}{\use_iii:nnnn}
+% \begin{macro}{\use_iv:nnnn}
+% We also need something for picking up arguments from a longer
+% list.
+% \begin{macrocode}
+\cs_set:Npn \use_i:nnn #1#2#3 {#1}
+\cs_set:Npn \use_ii:nnn #1#2#3 {#2}
+\cs_set:Npn \use_iii:nnn #1#2#3 {#3}
+\cs_set:Npn \use_i_ii:nnn #1#2#3 {#1#2}
+\cs_set:Npn \use_i:nnnn #1#2#3#4 {#1}
+\cs_set:Npn \use_ii:nnnn #1#2#3#4 {#2}
+\cs_set:Npn \use_iii:nnnn #1#2#3#4 {#3}
+\cs_set:Npn \use_iv:nnnn #1#2#3#4 {#4}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\use_none_delimit_by_q_nil:w}
+% \begin{macro}{\use_none_delimit_by_q_stop:w}
+% \begin{macro}{\use_none_delimit_by_q_recursion_stop:w}
+% Functions that gobble everything until they see either \cs{q_nil} or
+% \cs{q_stop}, respectively.
+% \begin{macrocode}
+\cs_set:Npn \use_none_delimit_by_q_nil:w #1 \q_nil { }
+\cs_set:Npn \use_none_delimit_by_q_stop:w #1 \q_stop { }
+\cs_set:Npn \use_none_delimit_by_q_recursion_stop:w #1 \q_recursion_stop { }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\use_i_delimit_by_q_nil:nw}
+% \begin{macro}{\use_i_delimit_by_q_stop:nw}
+% \begin{macro}{\use_i_delimit_by_q_recursion_stop:nw}
+% Same as above but execute first argument after gobbling. Very
+% useful when you need to skip the rest of a mapping sequence but
+% want an easy way to control what should be expanded next.
+% \begin{macrocode}
+\cs_set:Npn \use_i_delimit_by_q_nil:nw #1#2 \q_nil {#1}
+\cs_set:Npn \use_i_delimit_by_q_stop:nw #1#2 \q_stop {#1}
+\cs_set:Npn \use_i_delimit_by_q_recursion_stop:nw #1#2 \q_recursion_stop {#1}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\use_i_after_fi:nw}
+% \begin{macro}{\use_i_after_else:nw}
+% \begin{macro}{\use_i_after_or:nw}
+% \begin{macro}{\use_i_after_orelse:nw}
+% Returns the first argument after ending the conditional.
+% \begin{macrocode}
+\cs_set:Npn \use_i_after_fi:nw #1 \fi: { \fi: #1 }
+\cs_set:Npn \use_i_after_else:nw #1 \else: #2 \fi: { \fi: #1 }
+\cs_set:Npn \use_i_after_or:nw #1 \or: #2 \fi: { \fi: #1 }
+\cs_set:Npn \use_i_after_orelse:nw #1#2#3 \fi: { \fi: #1 }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Gobbling tokens from input}
+%
+% \begin{macro}{\use_none:n}
+% \begin{macro}{\use_none:nn}
+% \begin{macro}{\use_none:nnn}
+% \begin{macro}{\use_none:nnnn}
+% \begin{macro}{\use_none:nnnnn}
+% \begin{macro}{\use_none:nnnnnn}
+% \begin{macro}{\use_none:nnnnnnn}
+% \begin{macro}{\use_none:nnnnnnnn}
+% \begin{macro}{\use_none:nnnnnnnnn}
+% To gobble tokens from the input we use a standard naming
+% convention: the number of tokens gobbled is given by the number of
+% |n|'s following the |:| in the name. Although defining
+% |\use_none:nnn| and above as separate calls of |\use_none:n| and
+% |\use_none:nn| is slightly faster, this is very non-intuitive to
+% the programmer who will assume that expanding such a function once
+% will take care of gobbling all the tokens in one go.
+% \begin{macrocode}
+\cs_set:Npn \use_none:n #1 { }
+\cs_set:Npn \use_none:nn #1#2 { }
+\cs_set:Npn \use_none:nnn #1#2#3 { }
+\cs_set:Npn \use_none:nnnn #1#2#3#4 { }
+\cs_set:Npn \use_none:nnnnn #1#2#3#4#5 { }
+\cs_set:Npn \use_none:nnnnnn #1#2#3#4#5#6 { }
+\cs_set:Npn \use_none:nnnnnnn #1#2#3#4#5#6#7 { }
+\cs_set:Npn \use_none:nnnnnnnn #1#2#3#4#5#6#7#8 { }
+\cs_set:Npn \use_none:nnnnnnnnn #1#2#3#4#5#6#7#8#9 { }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Conditional processing and definitions}
+%
+% Underneath any predicate function (|_p|) or other conditional forms
+% (|TF|, etc.) is a built-in logic saying that it after all of the
+% testing and processing must return the \meta{state} this leaves
+% \TeX{} in. Therefore, a simple user interface could be something like
+% \begin{verbatim}
+% \if_meaning:w #1#2 \prg_return_true: \else:
+% \if_meaning:w #1#3 \prg_return_true: \else:
+% \prg_return_false:
+% \fi: \fi:
+% \end{verbatim}
+% Usually, a \TeX{} programmer would have to insert a number of
+% |\exp_after:wN|s to ensure the state value is returned at exactly
+% the point where the last conditional is finished. However, that
+% obscures the code and forces the \TeX{} programmer to prove that
+% he/she knows the $2^{n}-1$ table. We therefore provide the simpler
+% interface.
+%
+% \begin{macro}{\prg_return_true:}
+% \begin{macro}{\prg_return_false:}
+% The idea here is that \cs{int_to_roman:w} will expand fully any
+% \cs{else:} and the \cs{fi:} that are waiting to be discarded,
+% before reaching the \cs{c_zero} which will leave the expansion null.
+% The code can then leave either the first or second argument in the
+% input stream. This means that all of the branching code has to contain
+% at least two tokens: see how the logical tests are actually implemented
+% to see this.
+% \begin{macrocode}
+\cs_set_nopar:Npn \prg_return_true:
+ { \exp_after:wN \use_i:nn \int_to_roman:w }
+\cs_set_nopar:Npn \prg_return_false:
+ { \exp_after:wN \use_ii:nn \int_to_roman:w}
+% \end{macrocode}
+% An extended state space could be implemented by including a more
+% elaborate function in place of \cs{use_i:nn}/\cs{use_ii:nn}. Provided
+% two arguments are absorbed then the code will work.
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\prg_set_conditional:Npnn,\prg_new_conditional:Npnn,
+% \prg_set_protected_conditional:Npnn,\prg_new_protected_conditional:Npnn}
+% The user functions for the types using parameter text from the
+% programmer. Call aux function to grab parameters, split the base
+% function into name and signature and then use, \emph{e.g.}, |\cs_set:Npn|
+% to define it with.
+% \begin{macrocode}
+\cs_set_protected:Npn \prg_set_conditional:Npnn #1
+ {
+ \prg_get_parm_aux:nw
+ {
+ \cs_split_function:NN #1 \prg_generate_conditional_aux:nnNNnnnn
+ \cs_set:Npn { parm }
+ }
+ }
+\cs_set_protected:Npn \prg_new_conditional:Npnn #1
+ {
+ \prg_get_parm_aux:nw
+ {
+ \cs_split_function:NN #1 \prg_generate_conditional_aux:nnNNnnnn
+ \cs_new:Npn { parm }
+ }
+ }
+\cs_set_protected:Npn \prg_set_protected_conditional:Npnn #1
+ {
+ \prg_get_parm_aux:nw{
+ \cs_split_function:NN #1 \prg_generate_conditional_aux:nnNNnnnn
+ \cs_set_protected:Npn { parm }
+ }
+ }
+\cs_set_protected:Npn \prg_new_protected_conditional:Npnn #1
+ {
+ \prg_get_parm_aux:nw
+ {
+ \cs_split_function:NN #1 \prg_generate_conditional_aux:nnNNnnnn
+ \cs_new_protected:Npn { parm }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\prg_set_conditional:Nnn,\prg_new_conditional:Nnn,
+% \prg_set_protected_conditional:Nnn,\prg_new_protected_conditional:Nnn}
+% The user functions for the types automatically inserting the
+% correct parameter text based on the signature. Call aux function
+% after calculating number of arguments, split the base function
+% into name and signature and then use, \emph{e.g.}, |\cs_set:Npn| to
+% define it with.
+% \begin{macrocode}
+\cs_set_protected:Npn \prg_set_conditional:Nnn #1
+ {
+ \exp_args:Nnf \prg_get_count_aux:nn
+ {
+ \cs_split_function:NN #1 \prg_generate_conditional_aux:nnNNnnnn
+ \cs_set:Npn { count }
+ }
+ { \cs_get_arg_count_from_signature:N #1 }
+ }
+\cs_set_protected:Npn \prg_new_conditional:Nnn #1
+ {
+ \exp_args:Nnf \prg_get_count_aux:nn
+ {
+ \cs_split_function:NN #1 \prg_generate_conditional_aux:nnNNnnnn
+ \cs_new:Npn { count}
+ }
+ { \cs_get_arg_count_from_signature:N #1 }
+ }
+
+\cs_set_protected:Npn \prg_set_protected_conditional:Nnn #1{
+ \exp_args:Nnf \prg_get_count_aux:nn{
+ \cs_split_function:NN #1 \prg_generate_conditional_aux:nnNNnnnn
+ \cs_set_protected:Npn {count}
+ }{\cs_get_arg_count_from_signature:N #1}
+}
+
+\cs_set_protected:Npn \prg_new_protected_conditional:Nnn #1
+ {
+ \exp_args:Nnf \prg_get_count_aux:nn
+ {
+ \cs_split_function:NN #1 \prg_generate_conditional_aux:nnNNnnnn
+ \cs_new_protected:Npn {count}
+ }
+ { \cs_get_arg_count_from_signature:N #1 }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\prg_set_eq_conditional:NNn,\prg_new_eq_conditional:NNn}
+% The obvious setting-equal functions.
+% \begin{macrocode}
+\cs_set_protected:Npn \prg_set_eq_conditional:NNn #1#2#3
+ { \prg_set_eq_conditional_aux:NNNn \cs_set_eq:cc #1#2 {#3} }
+\cs_set_protected:Npn \prg_new_eq_conditional:NNn #1#2#3
+ { \prg_set_eq_conditional_aux:NNNn \cs_new_eq:cc #1#2 {#3} }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[aux]{\prg_get_parm_aux:nw,\prg_get_count_aux:nn}
+% For the |Npnn| type we must grab the parameter text before
+% continuing. We make this a very generic function that takes one
+% argument before reading everything up to a left brace. Something
+% similar for the |Nnn| type.
+% \begin{macrocode}
+\cs_set:Npn \prg_get_count_aux:nn #1#2 { #1 {#2} }
+\cs_set:Npn \prg_get_parm_aux:nw #1#2# { #1 {#2} }
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}[aux]{\prg_generate_conditional_parm_aux:nnNNnnnn,
+% \prg_generate_conditional_parm_aux:nw}
+% The workhorse here is going through a list of desired forms, \emph{i.e.},
+% |p|, |TF|, |T| and |F|. The first three arguments come from splitting up
+% the base form of the conditional, which gives the name, signature
+% and a boolean to signal whether or not there was a colon in the
+% name. For the time being, we do not use this piece of information
+% but could well throw an error. The fourth argument is how to
+% define this function, the fifth is the text |parm| or |count| for
+% which version to use to define the functions, the sixth is the
+% parameters to use (possibly empty) or number of arguments, the
+% seventh is the list of forms to define, the eight is the
+% replacement text which we will augment when defining the forms.
+% \begin{macrocode}
+\cs_set_protected:Npn \prg_generate_conditional_aux:nnNNnnnn #1#2#3#4#5#6#7#8
+ {
+ \prg_generate_conditional_aux:nnw {#5}
+ {
+ #4 {#1} {#2} {#6} {#8}
+ }
+ #7 , ? , \q_recursion_stop
+ }
+% \end{macrocode}
+% Looping through the list of desired forms. First is the text |parm|
+% or |count|, second is five arguments packed together and third is
+% the form. Use text and form to call the correct type.
+% \begin{macrocode}
+\cs_set_protected:Npn \prg_generate_conditional_aux:nnw #1#2#3 ,
+ {
+ \if:w ?#3
+ \exp_after:wN \use_none_delimit_by_q_recursion_stop:w
+ \fi:
+ \use:c { prg_generate_#3_form_#1:Nnnnn } #2
+ \prg_generate_conditional_aux:nnw {#1} {#2}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[aux]
+% {
+% \prg_generate_p_form_parm:Nnnnn,
+% \prg_generate_TF_form_parm:Nnnnn,
+% \prg_generate_T_form_parm:Nnnnn,
+% \prg_generate_F_form_parm:Nnnnn
+% }
+% How to generate the various forms. The |parm| types here takes the
+% following arguments: 1: how to define (an N-type), 2: name, 3:
+% signature, 4: parameter text (or empty), 5: replacement. Remember that
+% the logic-returning functions expect two arguments to be present after
+% \cs{c_zero}: notice the construction of the different variants
+% relies on this, and that the |TF| variant will be slightly faster
+% than the |T| version.
+% \begin{macrocode}
+\cs_set_protected:Npn \prg_generate_p_form_parm:Nnnnn #1#2#3#4#5
+ {
+ \exp_args:Nc #1 { #2 _p: #3 } #4
+ {
+ #5 \c_zero
+ \c_true_bool \c_false_bool
+ }
+ }
+\cs_set_protected:Npn \prg_generate_T_form_parm:Nnnnn #1#2#3#4#5
+ {
+ \exp_args:Nc #1 { #2 : #3 T } #4
+ {
+ #5 \c_zero
+ \use:n \use_none:n
+ }
+ }
+\cs_set_protected:Npn \prg_generate_F_form_parm:Nnnnn #1#2#3#4#5
+ {
+ \exp_args:Nc #1 { #2 : #3 F } #4
+ {
+ #5 \c_zero
+ { }
+ }
+ }
+\cs_set_protected:Npn \prg_generate_TF_form_parm:Nnnnn #1#2#3#4#5
+ {
+ \exp_args:Nc #1 { #2 : #3 TF } #4
+ { #5 \c_zero }
+ }
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}[aux]
+% {
+% \prg_generate_p_form_count:Nnnnn,
+% \prg_generate_TF_form_count:Nnnnn,
+% \prg_generate_T_form_count:Nnnnn,
+% \prg_generate_F_form_count:Nnnnn
+% }
+% The |count| form is similar, but of course requires a number rather
+% than a primitive argument specification.
+% \begin{macrocode}
+\cs_set_protected:Npn \prg_generate_p_form_count:Nnnnn #1#2#3#4#5
+ {
+ \cs_generate_from_arg_count:cNnn { #2 _p: #3 } #1 {#4}
+ {
+ #5 \c_zero
+ \c_true_bool \c_false_bool
+ }
+ }
+\cs_set_protected:Npn \prg_generate_T_form_count:Nnnnn #1#2#3#4#5
+ {
+ \cs_generate_from_arg_count:cNnn { #2 : #3 T } #1 {#4}
+ {
+ #5 \c_zero
+ \use:n \use_none:n
+ }
+ }
+\cs_set_protected:Npn \prg_generate_F_form_count:Nnnnn #1#2#3#4#5
+ {
+ \cs_generate_from_arg_count:cNnn { #2 : #3 F } #1 {#4}
+ {
+ #5 \c_zero
+ { }
+ }
+ }
+\cs_set_protected:Npn \prg_generate_TF_form_count:Nnnnn #1#2#3#4#5
+ {
+ \cs_generate_from_arg_count:cNnn { #2 : #3 TF } #1 {#4}
+ { #5 \c_zero }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[aux]{\prg_set_eq_conditional_aux:NNNn,
+% \prg_set_eq_conditional_aux:NNNw}
+% \begin{macrocode}
+\cs_set_protected:Npn \prg_set_eq_conditional_aux:NNNn #1#2#3#4
+ { \prg_set_eq_conditional_aux:NNNw #1#2#3#4 , ? , \q_recursion_stop }
+% \end{macrocode}
+% Manual clist loop over argument |#4|.
+% \begin{macrocode}
+\cs_set_protected:Npn \prg_set_eq_conditional_aux:NNNw #1#2#3#4 ,
+ {
+ \if:w ? #4 \scan_stop:
+ \exp_after:wN \use_none_delimit_by_q_recursion_stop:w
+ \fi:
+ #1
+ { \exp_args:NNc \cs_split_function:NN #2 { prg_conditional_form_#4:nnn } }
+ { \exp_args:NNc \cs_split_function:NN #3 { prg_conditional_form_#4:nnn } }
+ \prg_set_eq_conditional_aux:NNNw #1 {#2} {#3}
+ }
+% \end{macrocode}
+% \begin{macrocode}
+\cs_set:Npn \prg_conditional_form_p:nnn #1#2#3 { #1 _p : #2 }
+\cs_set:Npn \prg_conditional_form_TF:nnn #1#2#3 { #1 : #2 TF }
+\cs_set:Npn \prg_conditional_form_T:nnn #1#2#3 { #1 : #2 T }
+\cs_set:Npn \prg_conditional_form_F:nnn #1#2#3 { #1 : #2 F }
+% \end{macrocode}
+% \end{macro}
+%
+% All that is left is to define the canonical boolean true and false.
+% I think Michael originated the idea of expandable boolean tests. At
+% first these were supposed to expand into either \texttt{TT} or
+% \texttt{TF} to be tested using |\if:w| but this was later changed to
+% |00| and |01|, so they could be used in logical
+% operations. Later again they were changed to being numerical
+% constants with values of $1$ for true and $0$ for false. We need
+% this from the get-go.
+%
+% \begin{macro}{\c_true_bool}
+% \begin{macro}{\c_false_bool}
+% Here are the canonical boolean values.
+% \begin{macrocode}
+\tex_chardef:D \c_true_bool = 1~
+\tex_chardef:D \c_false_bool = 0~
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Dissecting a control sequence}
+%
+% \begin{macro}{\cs_to_str:N}
+% \begin{macro}[aux]{\cs_to_str_aux:w}
+% This converts a control sequence into the character string of its
+% name, removing the leading escape character. This turns out to be
+% a non-trivial matter as there a different cases:
+% \begin{itemize}
+% \item The usual case of a printable escape character;
+% \item the case of a non-printable escape characters, e.g., when
+% the value of |\tex_escapechar:D| is negative;
+% \item when the escape character is a space.
+% \end{itemize}
+% One approach to solve this is to test how many tokens result from
+% |\token_to_str:N \a|. If there are two tokens, then the escape
+% character is printable, while if it is non-printable then only
+% one is present.
+%
+% However, there is an additional complication: the control
+% sequence itself may start with a space. Clearly that should \emph{not} be
+% lost in the process of converting to a string. So the approach adopted is
+% a little more intricate still. When the escape character is printable,
+% \verb*|\token_to_str:N \ | yields the escape character itself and a space.
+% The escape sequence will terminate the expansion started by
+% \cs{int_to_roman:w}, which is a negative number and so will not
+% gobble the escape character even if it's a number. The \cs{tex_if:D}
+% test will then be \texttt{false}, and the na\"ive approach of gobbling
+% the first character of the \cs{token_to_str:N} version of the control
+% sequence will work, even if the first character is a space.
+% The second case is that the escape character is itself a space. In this
+% case, the escape character space is consumed terminating the first
+% \cs{int_to_roman:w}, and \cs{cs_to_str_aux:w} is expanded. This
+% inserts a space, making the \cs{if:w} test \texttt{true}. The
+% second \cs{int_to_roman:w} will then execute the \cs{token_to_str:N},
+% with the escape-character space being consumed by the
+% \cs{int_to_roman:w}, and thus leaving the control sequence name in the
+% input stream. The final case is where the escape character is not
+% printable.
+% The flow here starts with the \verb*|\token_to_str:N \ | giving just a
+% space, which terminates the first \cs{int_to_roman:w} but leaves no
+% token for the \cs{if:w} test. This means that the \cs{int_to_roman:w}
+% is executed before the test is finished. The result is that the
+% \cs{fi:}, expanded before the \cs{tex_if:D} is finished, becomes
+% \cs{scan_stop:} \cs{fi:}, and the \cs{scan_stop:} is then used in
+% the \cs{if:w} test.
+% In this case, \cs{token_to_str:N} is therefore used with no gobbling at
+% all, which is exactly what is needed in this case.
+% \begin{macrocode}
+\cs_set_nopar:Npn \cs_to_str:N
+ {
+ \if:w \int_to_roman:w - `0 \token_to_str:N \ %
+ \cs_to_str_aux:w
+ \fi:
+ \exp_after:wN \use_none:n \token_to_str:N
+ }
+\cs_set_nopar:Npn \cs_to_str_aux:w #1 \use_none:n
+ { ~ \int_to_roman:w - `0 \fi: }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\cs_split_function:NN}
+% \begin{macro}[aux]{\cs_split_function_aux:w}
+% \begin{macro}[aux]{\cs_split_function_auxii:w}
+% This function takes a function name and splits it into name with
+% the escape char removed and argument specification. In addition to
+% this, a third argument, a boolean \meta{true} or \meta{false} is
+% returned with \meta{true} for when there is a colon in the function
+% and \meta{false} if there is not. Lastly, the second argument of
+% |\cs_split_function:NN| is supposed to be a function
+% taking three variables, one for name, one for signature, and one
+% for the boolean. For example,
+% |\cs_split_function:NN\foo_bar:cnx\use_i:nnn| as input
+% becomes |\use_i:nnn {foo_bar}{cnx}\c_true_bool|.
+%
+% Can't use a literal |:| because it has the wrong catcode here, so
+% it's transformed from |@| with |\tex_lowercase:D|.
+% \begin{macrocode}
+\group_begin:
+ \tex_lccode:D `\@ = `\: \scan_stop:
+ \tex_catcode:D `\@ = 12~
+\tex_lowercase:D
+ {
+ \group_end:
+% \end{macrocode}
+% First ensure that we actually get a properly evaluated str as we
+% don't know how many expansions |\cs_to_str:N| requires. Insert
+% extra colon to catch the error cases.
+% \begin{macrocode}
+ \cs_set:Npn \cs_split_function:NN #1#2
+ {
+ \exp_after:wN \cs_split_function_aux:w
+ \int_to_roman:w - `\q \cs_to_str:N #1 @ a \q_stop #2
+ }
+% \end{macrocode}
+% If no colon in the name, |#2| is |a| with catcode 11 and |#3| is
+% empty. If colon in the name, then either |#2| is a colon or the
+% first letter of the signature. The letters here have catcode 12.
+% If a colon was given we need to a) split off the colon and quark at
+% the end and b) ensure we return the name, signature and boolean true
+% We can't use |\quark_if_no_value:NTF| yet but this is very safe
+% anyway as all tokens have catcode~12.
+% \begin{macrocode}
+ \cs_set:Npn \cs_split_function_aux:w #1 @ #2#3 \q_stop #4
+ {
+ \if_meaning:w a #2
+ \exp_after:wN \use_i:nn
+ \else:
+ \exp_after:wN\use_ii:nn
+ \fi:
+ { #4 {#1} { } \c_false_bool }
+ { \cs_split_function_auxii:w #2#3 \q_stop #4 {#1} }
+ }
+ \cs_set:Npn \cs_split_function_auxii:w #1 @a \q_stop #2#3
+ { #2{#3}{#1}\c_true_bool }
+% \end{macrocode}
+% End of lowercase
+% \begin{macrocode}
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\cs_get_function_name:N, \cs_get_function_signature:N}
+% Now returning the name is trivial: just discard the last two
+% arguments. Similar for signature.
+% \begin{macrocode}
+\cs_set:Npn \cs_get_function_name:N #1
+ { \cs_split_function:NN #1 \use_i:nnn }
+\cs_set:Npn \cs_get_function_signature:N #1
+ { \cs_split_function:NN #1 \use_ii:nnn }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Exist or free}
+%
+% A control sequence is said to \emph{exist} (to be used) if has an entry in
+% the hash table and its meaning is different from the primitive
+% |\tex_relax:D| token. A control sequence is said to be \emph{free}
+% (to be defined) if it does not already exist.
+%
+% \begin{macro}[pTF]{\cs_if_exist:N,\cs_if_exist:c}
+% Two versions for checking existence. For the |N| form we firstly
+% check for |\scan_stop:| and then if it is in the hash
+% table. There is no problem when inputting something like |\else:|
+% or |\fi:| as \TeX{} will only ever skip input in case the token
+% tested against is |\scan_stop:|.
+% \begin{macrocode}
+\prg_set_conditional:Npnn \cs_if_exist:N #1 { p , T , F , TF }
+ {
+ \if_meaning:w #1 \scan_stop:
+ \prg_return_false:
+ \else:
+ \if_cs_exist:N #1
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ \fi:
+ }
+% \end{macrocode}
+% For the |c| form we firstly check if it is in the hash table and
+% then for |\scan_stop:| so that we do not add it to the hash table
+% unless it was already there. Here we have to be careful as the text
+% to be skipped if the first test is false may contain tokens that
+% disturb the scanner. Therefore, we ensure that the second test is
+% performed after the first one has concluded completely.
+% \begin{macrocode}
+\prg_set_conditional:Npnn \cs_if_exist:c #1 { p , T , F , TF }
+ {
+ \if_cs_exist:w #1 \cs_end:
+ \exp_after:wN \use_i:nn
+ \else:
+ \exp_after:wN \use_ii:nn
+ \fi:
+ {
+ \exp_after:wN \if_meaning:w \cs:w #1 \cs_end: \scan_stop:
+ \prg_return_false:
+ \else:
+ \prg_return_true:
+ \fi:
+ }
+ \prg_return_false:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\cs_if_free:N,\cs_if_free:c}
+% The logical reversal of the above.
+% \begin{macrocode}
+\prg_set_conditional:Npnn \cs_if_free:N #1 { p , T , F , TF }
+ {
+ \if_meaning:w #1 \scan_stop:
+ \prg_return_true:
+ \else:
+ \if_cs_exist:N #1
+ \prg_return_false:
+ \else:
+ \prg_return_true:
+ \fi:
+ \fi:
+ }
+\prg_set_conditional:Npnn \cs_if_free:c #1 { p , T , F , TF }
+ {
+ \if_cs_exist:w #1 \cs_end:
+ \exp_after:wN \use_i:nn
+ \else:
+ \exp_after:wN \use_ii:nn
+ \fi:
+ {
+ \exp_after:wN \if_meaning:w \cs:w #1 \cs_end: \scan_stop:
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+ { \prg_return_true: }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Defining and checking (new) functions}
+%
+% \begin{macro}{\c_minus_one, \c_zero, \c_sixteen}
+% \begin{macro}{\c_six, \c_seven, \c_twelve}
+% We need the constants |\c_minus_one| and |\c_sixteen| now for
+% writing information to the log and the terminal and |\c_zero|
+% which is used by some functions in the \textsf{l3alloc} module. The
+% rest are defined in the \textsf{l3int} module -- at least for the
+% ones that can be defined with |\tex_chardef:D| or
+% |\tex_mathchardef:D|. For other constants the \textsf{l3int} module is
+% required but it can't be used until the allocation has been set
+% up properly! The actual allocation mechanism is in
+% \textsf{l3alloc} and as \TeX{} wants to reserve count registers
+% 0--9, the first available one is~10 so we use that for
+% |\c_minus_one|.
+% \begin{macrocode}
+%<*package>
+\cs_set_eq:NwN \c_minus_one \m@ne
+%</package>
+%<*initex>
+\tex_countdef:D \c_minus_one = 10 ~
+\c_minus_one = -1 ~
+%</initex>
+\tex_chardef:D \c_sixteen = 16~
+\tex_chardef:D \c_zero = 0~
+\tex_chardef:D \c_six = 6~
+\tex_chardef:D \c_seven = 7~
+\tex_chardef:D \c_twelve = 12~
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\c_max_register_int}
+% This is here as this particular integer is needed both in package
+% mode and to bootstrap \pkg{l3alloc}
+% \begin{macrocode}
+\tex_mathchardef:D \c_max_register_int = 32 767 \scan_stop:
+% \end{macrocode}
+% \end{macro}
+%
+% We provide two kinds of functions that can be used to define
+% control sequences. On the one hand we have functions that check
+% if their argument doesn't already exist, they are called
+% |\..._new|. The second type of defining functions doesn't check
+% if the argument is already defined.
+%
+% Before we can define them, we need some auxiliary macros that
+% allow us to generate error messages. The definitions here are
+% only temporary, they will be redefined later on.
+%
+% \begin{macro}{\iow_log:x}
+% \begin{macro}{\iow_term:x}
+% We define a routine to write only to the log file. And a
+% similar one for writing to both the log file and the terminal.
+% These will be redefined later by \pkg{l3io}.
+% \begin{macrocode}
+\cs_set_protected_nopar:Npn \iow_log:x
+ { \tex_immediate:D \tex_write:D \c_minus_one }
+\cs_set_protected_nopar:Npn \iow_term:x
+ { \tex_immediate:D \tex_write:D \c_sixteen }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\msg_kernel_error:nnxx}
+% \begin{macro}{\msg_kernel_error:nnx}
+% \begin{macro}{\msg_kernel_error:nn}
+% If an internal error occurs before \LaTeX3 has loaded \pkg{l3msg} then
+% the code should issue a usable if terse error message and halt. This
+% can only happen if a coding error is made by the team, so this is
+% a reasonable response.
+% \begin{macrocode}
+\cs_set_protected_nopar:Npn \msg_kernel_error:nnxx #1#2#3#4
+ {
+ \tex_errmessage:D
+ {
+ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!~! ^^J
+ Argh,~internal~LaTeX3~error! ^^J ^^J
+ Module ~ #1 , ~ message~name~"#2": ^^J
+ Arguments~'#3'~and~'#4' ^^J ^^J
+ This~is~one~for~The~LaTeX3~Project:~bailing~out
+ }
+ \tex_end:D
+ }
+\cs_set_protected_nopar:Npn \msg_kernel_error:nnx #1#2#3
+ { \msg_kernel_error:nnxx {#1} {#2} {#3} { } }
+\cs_set_protected_nopar:Npn \msg_kernel_error:nn #1#2
+ { \msg_kernel_error:nnxx {#1} {#2} { } { } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\msg_line_context:}
+% Another one from \pkg{l3msg} which will be altered later.
+% \begin{macrocode}
+\cs_set_nopar:Npn \msg_line_context:
+ { on~line~\tex_the:D \tex_inputlineno:D }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\cs_record_meaning:N}
+% This macro will be used later on for tracing purposes. But we
+% need some more modules to define it, so we just give some dummy
+% definition here.
+% \begin{macrocode}
+\cs_set:Npn \cs_record_meaning:N #1 { }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\chk_if_free_cs:N, \chk_if_free_cs:c}
+% This command is called by |\cs_new_nopar:Npn| and |\cs_new_eq:NN|
+% \emph{etc.}\
+% to make sure that the argument sequence is not already in use. If
+% it is, an error is signalled. It checks if \meta{csname} is
+% undefined or |\scan_stop:|. Otherwise an error message is
+% issued. We have to make sure we don't put the argument into the
+% conditional processing since it may be an |\if...| type function!
+% \begin {macrocode}
+\cs_set_protected_nopar:Npn \chk_if_free_cs:N #1
+ {
+ \cs_if_free:NF #1
+ {
+ \msg_kernel_error:nnxx { kernel } { command-already-defined }
+ { \token_to_str:N #1 } { \token_to_meaning:N #1 }
+ }
+}
+%<*package>
+\tex_ifodd:D \@l@expl@log@functions@bool
+ \cs_set_protected_nopar:Npn \chk_if_free_cs:N #1
+ {
+ \cs_if_free:NF #1
+ {
+ \msg_kernel_error:nnxx { kernel } { command-already-defined }
+ { \token_to_str:N #1 } { \token_to_meaning:N #1 }
+ }
+ \iow_log:x { Defining~\token_to_str:N #1~ \msg_line_context: }
+ }
+\fi:
+%</package>
+\cs_set_protected_nopar:Npn \chk_if_free_cs:c
+ { \exp_args:Nc \chk_if_free_cs:N }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\chk_if_exist_cs:N, \chk_if_exist_cs:c}
+% This function issues a warning message when the control sequence
+% in its argument does not exist.
+% \begin{macrocode}
+\cs_set_protected_nopar:Npn \chk_if_exist_cs:N #1
+ {
+ \cs_if_exist:NF #1
+ {
+ \msg_kernel_error:nnxx { kernel } { command-not-defined }
+ { \token_to_str:N #1 } { \token_to_meaning:N #1 }
+ }
+ }
+\cs_set_protected_nopar:Npn \chk_if_exist_cs:c
+ { \exp_args:Nc \chk_if_exist_cs:N }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{More new definitions}
+%
+% \begin{macro}{\cs_new_nopar:Npn}
+% \begin{macro}{\cs_new_nopar:Npx}
+% \begin{macro}{\cs_new:Npn}
+% \begin{macro}{\cs_new:Npx}
+% \begin{macro}{\cs_new_protected_nopar:Npn}
+% \begin{macro}{\cs_new_protected_nopar:Npx}
+% \begin{macro}{\cs_new_protected:Npn}
+% \begin{macro}{\cs_new_protected:Npx}
+% Global versions of the above functions.
+% \begin {macrocode}
+\cs_set:Npn \cs_tmp:w #1#2
+ {
+ \cs_set_protected_nopar:Npn #1 ##1
+ {
+ \chk_if_free_cs:N ##1
+ #2 ##1
+ }
+ }
+\cs_tmp:w \cs_new_nopar:Npn \cs_gset_nopar:Npn
+\cs_tmp:w \cs_new_nopar:Npx \cs_gset_nopar:Npx
+\cs_tmp:w \cs_new:Npn \cs_gset:Npn
+\cs_tmp:w \cs_new:Npx \cs_gset:Npx
+\cs_tmp:w \cs_new_protected_nopar:Npn \cs_gset_protected_nopar:Npn
+\cs_tmp:w \cs_new_protected_nopar:Npx \cs_gset_protected_nopar:Npx
+\cs_tmp:w \cs_new_protected:Npn \cs_gset_protected:Npn
+\cs_tmp:w \cs_new_protected:Npx \cs_gset_protected:Npx
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\cs_set_nopar:cpn}
+% \begin{macro}{\cs_set_nopar:cpx}
+% \begin{macro}{\cs_gset_nopar:cpn}
+% \begin{macro}{\cs_gset_nopar:cpx}
+% \begin{macro}{\cs_new_nopar:cpn}
+% \begin{macro}{\cs_new_nopar:cpx}
+% Like |\cs_set_nopar:Npn| and |\cs_new_nopar:Npn|, except that the
+% first argument consists of the sequence of characters that should
+% be used to form the name of the desired control sequence (the |c|
+% stands for csname argument, see the expansion module). Global
+% versions are also provided.
+%
+% |\cs_set_nopar:cpn|\meta{string}\meta{rep-text} will turn \meta{string}
+% into a csname and then assign \m {rep-text} to it by using
+% |\cs_set_nopar:Npn|. This means that there might be a parameter
+% string between the two arguments.
+% \begin{macrocode}
+\cs_set:Npn \cs_tmp:w #1#2
+ { \cs_new_protected_nopar:Npn #1 { \exp_args:Nc #2 } }
+\cs_tmp:w \cs_set_nopar:cpn \cs_set_nopar:Npn
+\cs_tmp:w \cs_set_nopar:cpx \cs_set_nopar:Npx
+\cs_tmp:w \cs_gset_nopar:cpn \cs_gset_nopar:Npn
+\cs_tmp:w \cs_gset_nopar:cpx \cs_gset_nopar:Npx
+\cs_tmp:w \cs_new_nopar:cpn \cs_new_nopar:Npn
+\cs_tmp:w \cs_new_nopar:cpx \cs_new_nopar:Npx
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\cs_set:cpn}
+% \begin{macro}{\cs_set:cpx}
+% \begin{macro}{\cs_gset:cpn}
+% \begin{macro}{\cs_gset:cpx}
+% \begin{macro}{\cs_new:cpn}
+% \begin{macro}{\cs_new:cpx}
+% Variants of the |\cs_set:Npn| versions which make a csname out
+% of the first arguments. We may also do this globally.
+% \begin{macrocode}
+\cs_tmp:w \cs_set:cpn \cs_set:Npn
+\cs_tmp:w \cs_set:cpx \cs_set:Npx
+\cs_tmp:w \cs_gset:cpn \cs_gset:Npn
+\cs_tmp:w \cs_gset:cpx \cs_gset:Npx
+\cs_tmp:w \cs_new:cpn \cs_new:Npn
+\cs_tmp:w \cs_new:cpx \cs_new:Npx
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\cs_set_protected_nopar:cpn}
+% \begin{macro}{\cs_set_protected_nopar:cpx}
+% \begin{macro}{\cs_gset_protected_nopar:cpn}
+% \begin{macro}{\cs_gset_protected_nopar:cpx}
+% \begin{macro}{\cs_new_protected_nopar:cpn}
+% \begin{macro}{\cs_new_protected_nopar:cpx}
+% Variants of the |\cs_set_protected_nopar:Npn| versions which make a csname
+% out of the first arguments. We may also do this globally.
+% \begin{macrocode}
+\cs_tmp:w \cs_set_protected_nopar:cpn \cs_set_protected_nopar:Npn
+\cs_tmp:w \cs_set_protected_nopar:cpx \cs_set_protected_nopar:Npx
+\cs_tmp:w \cs_gset_protected_nopar:cpn \cs_gset_protected_nopar:Npn
+\cs_tmp:w \cs_gset_protected_nopar:cpx \cs_gset_protected_nopar:Npx
+\cs_tmp:w \cs_new_protected_nopar:cpn \cs_new_protected_nopar:Npn
+\cs_tmp:w \cs_new_protected_nopar:cpx \cs_new_protected_nopar:Npx
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\cs_set_protected:cpn}
+% \begin{macro}{\cs_set_protected:cpx}
+% \begin{macro}{\cs_gset_protected:cpn}
+% \begin{macro}{\cs_gset_protected:cpx}
+% \begin{macro}{\cs_new_protected:cpn}
+% \begin{macro}{\cs_new_protected:cpx}
+% Variants of the |\cs_set_protected:Npn| versions which make a csname
+% out of the first arguments. We may also do this globally.
+% \begin{macrocode}
+\cs_tmp:w \cs_set_protected:cpn \cs_set_protected:Npn
+\cs_tmp:w \cs_set_protected:cpx \cs_set_protected:Npx
+\cs_tmp:w \cs_gset_protected:cpn \cs_gset_protected:Npn
+\cs_tmp:w \cs_gset_protected:cpx \cs_gset_protected:Npx
+\cs_tmp:w \cs_new_protected:cpn \cs_new_protected:Npn
+\cs_tmp:w \cs_new_protected:cpx \cs_new_protected:Npx
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[aux]{\use_0_parameter:}
+% \begin{macro}[aux]{\use_1_parameter:}
+% \begin{macro}[aux]{\use_2_parameter:}
+% \begin{macro}[aux]{\use_3_parameter:}
+% \begin{macro}[aux]{\use_4_parameter:}
+% \begin{macro}[aux]{\use_5_parameter:}
+% \begin{macro}[aux]{\use_6_parameter:}
+% \begin{macro}[aux]{\use_7_parameter:}
+% \begin{macro}[aux]{\use_8_parameter:}
+% \begin{macro}[aux]{\use_9_parameter:}
+% For using parameters, \emph{i.e.}, when you need to define a function to
+% process three parameters. See \textsf{xparse} for an application.
+% \begin{macrocode}
+\cs_new_nopar:cpn { use_0_parameter: } { }
+\cs_new_nopar:cpn { use_1_parameter: } { {##1} }
+\cs_new_nopar:cpn { use_2_parameter: } { {##1} {##2} }
+\cs_new_nopar:cpn { use_3_parameter: } { {##1} {##2} {##3} }
+\cs_new_nopar:cpn { use_4_parameter: } { {##1} {##2} {##3} {##4} }
+\cs_new_nopar:cpn { use_5_parameter: } { {##1} {##2} {##3} {##4} {##5} }
+\cs_new_nopar:cpn { use_6_parameter: } { {##1} {##2} {##3} {##4} {##5} {##6} }
+\cs_new_nopar:cpn { use_7_parameter: }
+ { {##1} {##2} {##3} {##4} {##5}{##6} {##7} }
+\cs_new_nopar:cpn { use_8_parameter: }
+ { {##1} {##2} {##3} {##4} {##5} {##6} {##7} {##8} }
+\cs_new_nopar:cpn{ use_9_parameter: }
+ { {##1} {##2} {##3} {##4} {##5} {##6} {##7} {##8} {##9} }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Copying definitions}
+%
+% \begin{macro}{\cs_set_eq:NN}
+% \begin{macro}{\cs_set_eq:cN}
+% \begin{macro}{\cs_set_eq:Nc}
+% \begin{macro}{\cs_set_eq:cc}
+% These macros allow us to copy the definition of a control sequence
+% to another control sequence.
+%
+% The |=| sign allows us to define funny char tokens like |=|
+% itself or \verb*| | with this function. For the definition of
+% |\c_space_char{~}| to work we need the |~| after the |=|.
+%
+% |\cs_set_eq:NN| is long to avoid problems with a literal argument
+% of |\par|. While |\cs_new_eq:NN| will probably never be correct
+% with a first argument of |\par|, define it long in order to throw
+% an \enquote{already defined} error rather than
+% \enquote{runaway argument}.
+% \begin{macrocode}
+\cs_new_protected:Npn \cs_set_eq:NN #1 { \cs_set_eq:NwN #1 =~ }
+\cs_new_protected_nopar:Npn \cs_set_eq:cN { \exp_args:Nc \cs_set_eq:NN }
+\cs_new_protected_nopar:Npn \cs_set_eq:Nc { \exp_args:NNc \cs_set_eq:NN }
+\cs_new_protected_nopar:Npn \cs_set_eq:cc { \exp_args:Ncc \cs_set_eq:NN }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\cs_new_eq:NN}
+% \begin{macro}{\cs_new_eq:cN}
+% \begin{macro}{\cs_new_eq:Nc}
+% \begin{macro}{\cs_new_eq:cc}
+% \begin{macrocode}
+\cs_new_protected:Npn \cs_new_eq:NN #1
+ {
+ \chk_if_free_cs:N #1
+ \pref_global:D \cs_set_eq:NN #1
+ }
+\cs_new_protected_nopar:Npn \cs_new_eq:cN { \exp_args:Nc \cs_new_eq:NN }
+\cs_new_protected_nopar:Npn \cs_new_eq:Nc { \exp_args:NNc \cs_new_eq:NN }
+\cs_new_protected_nopar:Npn \cs_new_eq:cc { \exp_args:Ncc \cs_new_eq:NN }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\cs_gset_eq:NN}
+% \begin{macro}{\cs_gset_eq:cN}
+% \begin{macro}{\cs_gset_eq:Nc}
+% \begin{macro}{\cs_gset_eq:cc}
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \cs_gset_eq:NN { \pref_global:D \cs_set_eq:NN }
+\cs_new_protected_nopar:Npn \cs_gset_eq:Nc { \exp_args:NNc \cs_gset_eq:NN }
+\cs_new_protected_nopar:Npn \cs_gset_eq:cN { \exp_args:Nc \cs_gset_eq:NN }
+\cs_new_protected_nopar:Npn \cs_gset_eq:cc { \exp_args:Ncc \cs_gset_eq:NN }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Undefining functions}
+%
+% \begin{macro}{\cs_undefine:N , \cs_undefine:c}
+% The following function is used to free the main memory from the
+% definition of some function that isn't in use any longer.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \cs_undefine:N #1
+ { \cs_gset_eq:NN #1 \c_undefined:D }
+\cs_new_protected_nopar:Npn \cs_undefine:c #1
+ { \cs_gset_eq:cN {#1} \c_undefined:D }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Defining functions from a given number of arguments}
+%
+% \begin{macro}{\cs_get_arg_count_from_signature:N}
+% \begin{macro}[aux]{\cs_get_arg_count_from_signature_aux:nnN}
+% \begin{macro}[aux]{\cs_get_arg_count_from_signature_auxii:w}
+% Counting the number of tokens in the signature, i.e., the number
+% of arguments the function should take. If there is no signature,
+% we return that there is $-1$ arguments to signal an error.
+% Otherwise we insert the string |9876543210| after the signature.
+% If the signature is empty, the number we want is $0$ so we remove
+% the first nine tokens and return the tenth. Similarly, if the
+% signature is |nnn| we want to remove the nine tokens |nnn987654|
+% and return $3$. Therefore, we simply remove the first nine tokens
+% and then return the tenth.
+% \begin{macrocode}
+\cs_new:Npn \cs_get_arg_count_from_signature:N #1
+ { \cs_split_function:NN #1 \cs_get_arg_count_from_signature_aux:nnN }
+\cs_new:Npn \cs_get_arg_count_from_signature_aux:nnN #1#2#3
+ {
+ \if_predicate:w #3
+ \exp_after:wN \use_i:nn
+ \else:
+ \exp_after:wN\use_ii:nn
+ \fi:
+ {
+ \exp_after:wN \cs_get_arg_count_from_signature_auxii:w
+ \use_none:nnnnnnnnn #2 9876543210 \q_stop
+ }
+ { -1 }
+}
+\cs_new:Npn \cs_get_arg_count_from_signature_auxii:w #1#2 \q_stop {#1}
+% \end{macrocode}
+% A variant form we need right away.
+% \begin{macrocode}
+\cs_new_nopar:Npn \cs_get_arg_count_from_signature:c
+ { \exp_args:Nc \cs_get_arg_count_from_signature:N }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[aux]{\cs_generate_from_arg_count:NNnn}
+% \begin{macro}[aux]{\cs_generate_from_arg_count_error_msg:Nn}
+% We provide a constructor function for defining functions with a
+% given number of arguments. For this we need to choose the correct
+% parameter text and then use that when defining. Since \TeX{}
+% supports from zero to nine arguments, we use a simple switch to
+% choose the correct parameter text, ensuring the result is returned
+% after finishing the conditional. If it is not between zero and
+% nine, we throw an error.
+%
+% 1: function to define, 2: with what to define it, 3: the number of
+% args it requires and 4: the replacement text
+% \begin{macrocode}
+\cs_new_protected:Npn \cs_generate_from_arg_count:NNnn #1#2#3#4
+ {
+ \if_case:w \int_eval:w #3 \int_eval_end:
+ \use_i_after_orelse:nw {#2#1}
+ \or:
+ \use_i_after_orelse:nw {#2#1 ##1}
+ \or:
+ \use_i_after_orelse:nw {#2#1 ##1##2}
+ \or:
+ \use_i_after_orelse:nw {#2#1 ##1##2##3}
+ \or:
+ \use_i_after_orelse:nw {#2#1 ##1##2##3##4}
+ \or:
+ \use_i_after_orelse:nw {#2#1 ##1##2##3##4##5}
+ \or:
+ \use_i_after_orelse:nw {#2#1 ##1##2##3##4##5##6}
+ \or:
+ \use_i_after_orelse:nw {#2#1 ##1##2##3##4##5##6##7}
+ \or:
+ \use_i_after_orelse:nw {#2#1 ##1##2##3##4##5##6##7##8}
+ \or:
+ \use_i_after_orelse:nw {#2#1 ##1##2##3##4##5##6##7##8##9}
+ \else:
+ \use_i_after_fi:nw
+ {
+ \cs_generate_from_arg_count_error_msg:Nn #1 {#3}
+ \use_none:n
+ }
+ \fi:
+ {#4}
+ }
+% \end{macrocode}
+% A variant form we need right away.
+% \begin{macrocode}
+\cs_new_nopar:Npn \cs_generate_from_arg_count:cNnn
+ { \exp_args:Nc \cs_generate_from_arg_count:NNnn }
+% \end{macrocode}
+% The error message. Elsewhere we use the value of $-1$ to signal a
+% missing colon in a function, so provide a hint for help on this.
+% \begin{macrocode}
+\cs_new:Npn \cs_generate_from_arg_count_error_msg:Nn #1#2
+ {
+ \msg_kernel_error:nnxx { kernel } { bad-number-of-arguments }
+ { \token_to_str:N #1 } { \int_eval:n {#2} }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Using the signature to define functions}
+%
+% We can now combine some of the tools we have to provide a simple
+% interface for defining functions. We define some simpler functions
+% with user interface |\cs_set:Nn \foo_bar:nn {#1,#2}|, \emph{i.e.}, the
+% number of arguments is read from the signature.
+%
+%
+% \begin{macro}{\cs_set:Nn}
+% \begin{macro}{\cs_set:Nx}
+% \begin{macro}{\cs_set_nopar:Nn}
+% \begin{macro}{\cs_set_nopar:Nx}
+% \begin{macro}{\cs_set_protected:Nn}
+% \begin{macro}{\cs_set_protected:Nx}
+% \begin{macro}{\cs_set_protected_nopar:Nn}
+% \begin{macro}{\cs_set_protected_nopar:Nx}
+% \begin{macro}{\cs_gset:Nn}
+% \begin{macro}{\cs_gset:Nx}
+% \begin{macro}{\cs_gset_nopar:Nn}
+% \begin{macro}{\cs_gset_nopar:Nx}
+% \begin{macro}{\cs_gset_protected:Nn}
+% \begin{macro}{\cs_gset_protected:Nx}
+% \begin{macro}{\cs_gset_protected_nopar:Nn}
+% \begin{macro}{\cs_gset_protected_nopar:Nx}
+% We want to define |\cs_set:Nn| as
+% \begin{verbatim}
+% \cs_set_protected:Npn \cs_set:Nn #1#2
+% {
+% \cs_generate_from_arg_count:NNnn #1 \cs_set:Npn
+% { \cs_get_arg_count_from_signature:N #1 } {#2}
+% }
+% \end{verbatim}
+% In short, to define |\cs_set:Nn| we need just use |\cs_set:Npn|,
+% everything else is the same for each variant. Therefore, we can
+% make it simpler by temporarily defining a function to do this for
+% us.
+% \begin{macrocode}
+\cs_set:Npn \cs_tmp:w #1#2#3
+ {
+ \cs_set_protected:cpx { cs_ #1 : #2 } ##1##2
+ {
+ \exp_not:N \cs_generate_from_arg_count:NNnn ##1
+ \exp_after:wN \exp_not:N \cs:w cs_#1 : #3 \cs_end:
+ { \exp_not:N\cs_get_arg_count_from_signature:N ##1 }{##2}
+ }
+ }
+% \end{macrocode}
+% Then we define the 32 variants beginning with |N|.
+% \begin{macrocode}
+\cs_tmp:w { set } { Nn } { Npn }
+\cs_tmp:w { set } { Nx } { Npx }
+\cs_tmp:w { set_nopar } { Nn } { Npn }
+\cs_tmp:w { set_nopar } { Nx } { Npx }
+\cs_tmp:w { set_protected } { Nn } { Npn }
+\cs_tmp:w { set_protected } { Nx } { Npx }
+\cs_tmp:w { set_protected_nopar } { Nn } { Npn }
+\cs_tmp:w { set_protected_nopar } { Nx } { Npx }
+\cs_tmp:w { gset } { Nn } { Npn }
+\cs_tmp:w { gset } { Nx } { Npx }
+\cs_tmp:w { gset_nopar } { Nn } { Npn }
+\cs_tmp:w { gset_nopar } { Nx } { Npx }
+\cs_tmp:w { gset_protected } { Nn } { Npn }
+\cs_tmp:w { gset_protected } { Nx } { Npx }
+\cs_tmp:w { gset_protected_nopar } { Nn } { Npn }
+\cs_tmp:w { gset_protected_nopar } { Nx } { Npx }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\cs_new:Nn}
+% \begin{macro}{\cs_new:Nx}
+% \begin{macro}{\cs_new_nopar:Nn}
+% \begin{macro}{\cs_new_nopar:Nx}
+% \begin{macro}{\cs_new_protected:Nn}
+% \begin{macro}{\cs_new_protected:Nx}
+% \begin{macro}{\cs_new_protected_nopar:Nn}
+% \begin{macro}{\cs_new_protected_nopar:Nx}
+% \begin{macrocode}
+\cs_tmp:w { new } { Nn } { Npn }
+\cs_tmp:w { new } { Nx } { Npx }
+\cs_tmp:w { new_nopar } { Nn } { Npn }
+\cs_tmp:w { new_nopar } { Nx } { Npx }
+\cs_tmp:w { new_protected } { Nn } { Npn }
+\cs_tmp:w { new_protected } { Nx } { Npx }
+\cs_tmp:w { new_protected_nopar } { Nn } { Npn }
+\cs_tmp:w { new_protected_nopar } { Nx } { Npx }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% Then something similar for the |c| variants.
+% \begin{verbatim}
+% \cs_set_protected:Npn \cs_set:cn #1#2
+% {
+% \cs_generate_from_arg_count:cNnn {#1} \cs_set:Npn
+% { \cs_get_arg_count_from_signature:c {#1} } {#2}
+% }
+% \end{verbatim}
+% \begin{macrocode}
+\cs_set:Npn \cs_tmp:w #1#2#3
+ {
+ \cs_set_protected:cpx {cs_#1:#2}##1##2{
+ \exp_not:N\cs_generate_from_arg_count:cNnn {##1}
+ \exp_after:wN \exp_not:N \cs:w cs_#1:#3 \cs_end:
+ { \exp_not:N \cs_get_arg_count_from_signature:c {##1} } {##2}
+ }
+ }
+% \end{macrocode}
+% \begin{macro}{\cs_set:cn}
+% \begin{macro}{\cs_set:cx}
+% \begin{macro}{\cs_set_nopar:cn}
+% \begin{macro}{\cs_set_nopar:cx}
+% \begin{macro}{\cs_set_protected:cn}
+% \begin{macro}{\cs_set_protected:cx}
+% \begin{macro}{\cs_set_protected_nopar:cn}
+% \begin{macro}{\cs_set_protected_nopar:cx}
+% \begin{macro}{\cs_gset:cn}
+% \begin{macro}{\cs_gset:cx}
+% \begin{macro}{\cs_gset_nopar:cn}
+% \begin{macro}{\cs_gset_nopar:cx}
+% \begin{macro}{\cs_gset_protected:cn}
+% \begin{macro}{\cs_gset_protected:cx}
+% \begin{macro}{\cs_gset_protected_nopar:cn}
+% \begin{macro}{\cs_gset_protected_nopar:cx}
+% The 32 |c| variants.
+% \begin{macrocode}
+\cs_tmp:w { set } { cn } { Npn }
+\cs_tmp:w { set } { cx } { Npx }
+\cs_tmp:w { set_nopar } { cn } { Npn }
+\cs_tmp:w { set_nopar } { cx } { Npx }
+\cs_tmp:w { set_protected } { cn } { Npn }
+\cs_tmp:w { set_protected } { cx } { Npx }
+\cs_tmp:w { set_protected_nopar } { cn } { Npn }
+\cs_tmp:w { set_protected_nopar } { cx } { Npx }
+\cs_tmp:w { gset } { cn } { Npn }
+\cs_tmp:w { gset } { cx } { Npx }
+\cs_tmp:w { gset_nopar } { cn } { Npn }
+\cs_tmp:w { gset_nopar } { cx } { Npx }
+\cs_tmp:w { gset_protected } { cn } { Npn }
+\cs_tmp:w { gset_protected } { cx } { Npx }
+\cs_tmp:w { gset_protected_nopar } { cn } { Npn }
+\cs_tmp:w { gset_protected_nopar } { cx } { Npx }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\cs_new:cn}
+% \begin{macro}{\cs_new:cx}
+% \begin{macro}{\cs_new_nopar:cn}
+% \begin{macro}{\cs_new_nopar:cx}
+% \begin{macro}{\cs_new_protected:cn}
+% \begin{macro}{\cs_new_protected:cx}
+% \begin{macro}{\cs_new_protected_nopar:cn}
+% \begin{macro}{\cs_new_protected_nopar:cx}
+% \begin{macrocode}
+\cs_tmp:w { new } { cn } { Npn }
+\cs_tmp:w { new } { cx } { Npx }
+\cs_tmp:w { new_nopar } { cn } { Npn }
+\cs_tmp:w { new_nopar } { cx } { Npx }
+\cs_tmp:w { new_protected } { cn } { Npn }
+\cs_tmp:w { new_protected } { cx } { Npx }
+\cs_tmp:w { new_protected_nopar } { cn } { Npn }
+\cs_tmp:w { new_protected_nopar } { cx } { Npx }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Checking control sequence equality}
+%
+% \begin{macro}[pTF]{\cs_if_eq:NN,\cs_if_eq:cN,\cs_if_eq:Nc,\cs_if_eq:cc}
+% Check if two control sequences are identical.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \cs_if_eq:NN #1#2 { p , T , F , TF }
+ {
+ \if_meaning:w #1#2
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+\cs_new_nopar:Npn \cs_if_eq_p:cN { \exp_args:Nc \cs_if_eq_p:NN }
+\cs_new_nopar:Npn \cs_if_eq:cNTF { \exp_args:Nc \cs_if_eq:NNTF }
+\cs_new_nopar:Npn \cs_if_eq:cNT { \exp_args:Nc \cs_if_eq:NNT }
+\cs_new_nopar:Npn \cs_if_eq:cNF { \exp_args:Nc \cs_if_eq:NNF }
+\cs_new_nopar:Npn \cs_if_eq_p:Nc { \exp_args:NNc \cs_if_eq_p:NN }
+\cs_new_nopar:Npn \cs_if_eq:NcTF { \exp_args:NNc \cs_if_eq:NNTF }
+\cs_new_nopar:Npn \cs_if_eq:NcT { \exp_args:NNc \cs_if_eq:NNT }
+\cs_new_nopar:Npn \cs_if_eq:NcF { \exp_args:NNc \cs_if_eq:NNF }
+\cs_new_nopar:Npn \cs_if_eq_p:cc { \exp_args:Ncc \cs_if_eq_p:NN }
+\cs_new_nopar:Npn \cs_if_eq:ccTF { \exp_args:Ncc \cs_if_eq:NNTF }
+\cs_new_nopar:Npn \cs_if_eq:ccT { \exp_args:Ncc \cs_if_eq:NNT }
+\cs_new_nopar:Npn \cs_if_eq:ccF { \exp_args:Ncc \cs_if_eq:NNF }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Diagnostic wrapper functions}
+%
+% \begin{macro}{\kernel_register_show:N, \kernel_register_show:c}
+% \begin{macrocode}
+\cs_new_nopar:Npn \kernel_register_show:N #1
+ {
+ \cs_if_exist:NTF #1
+ { \tex_showthe:D #1 }
+ {
+ \msg_kernel_error:nnx { kernel } { variable-not-defined }
+ { \token_to_str:N #1 }
+ }
+ }
+\cs_new_nopar:Npn \kernel_register_show:c { \exp_args:Nc \int_show:N }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Engine specific definitions}
+%
+% \begin{macro}
+% {
+% \c_pdftex_is_engine_bool, \c_luatex_is_engine_bool,
+% \c_xetex_is_engine_bool
+% }
+% \begin{macro}[TF]{\xetex_if_engine:, \luatex_if_engine:, \pdftex_if_engine:}
+% In some cases it will be useful to know which engine we're running.
+% Don't provide a |_p| predicate because the |_bool| is used for the
+% same thing. This can all be hard-coded for speed.
+% \begin{macrocode}
+\cs_new_eq:NN \luatex_if_engine:T \use_none:n
+\cs_new_eq:NN \luatex_if_engine:F \use:n
+\cs_new_eq:NN \luatex_if_engine:TF \use_ii:nn
+\cs_new_eq:NN \pdftex_if_engine:T \use:n
+\cs_new_eq:NN \pdftex_if_engine:F \use_none:n
+\cs_new_eq:NN \pdftex_if_engine:TF \use_i:nn
+\cs_new_eq:NN \xetex_if_engine:T \use_none:n
+\cs_new_eq:NN \xetex_if_engine:F \use:n
+\cs_new_eq:NN \xetex_if_engine:TF \use_ii:nn
+\cs_new_eq:NN \c_luatex_is_engine_bool \c_false_bool
+\cs_new_eq:NN \c_pdftex_is_engine_bool \c_true_bool
+\cs_new_eq:NN \c_xetex_is_engine_bool \c_false_bool
+\cs_if_exist:NT \xetex_XeTeXversion:D
+ {
+ \cs_set_eq:NN \pdftex_if_engine:T \use_none:n
+ \cs_set_eq:NN \pdftex_if_engine:F \use:n
+ \cs_set_eq:NN \pdftex_if_engine:TF \use_ii:nn
+ \cs_set_eq:NN \xetex_if_engine:T \use:n
+ \cs_set_eq:NN \xetex_if_engine:F \use_none:n
+ \cs_set_eq:NN \xetex_if_engine:TF \use_i:nn
+ \cs_set_eq:NN \c_pdftex_is_engine_bool \c_false_bool
+ \cs_set_eq:NN \c_xetex_is_engine_bool \c_true_bool
+ }
+\cs_if_exist:NT \luatex_directlua:D
+ {
+ \cs_set_eq:NN \luatex_if_engine:T \use:n
+ \cs_set_eq:NN \luatex_if_engine:F \use_none:n
+ \cs_set_eq:NN \luatex_if_engine:TF \use_i:nn
+ \cs_set_eq:NN \pdftex_if_engine:T \use_none:n
+ \cs_set_eq:NN \pdftex_if_engine:F \use:n
+ \cs_set_eq:NN \pdftex_if_engine:TF \use_ii:nn
+ \cs_set_eq:NN \c_luatex_is_engine_bool \c_true_bool
+ \cs_set_eq:NN \c_pdftex_is_engine_bool \c_false_bool
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Doing nothing functions}
+%
+% \begin{macro}{\prg_do_nothing:}
+% This does not fit anywhere else!
+% \begin{macrocode}
+\cs_new_nopar:Npn \prg_do_nothing: { }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{String comparisons}
+%
+% \begin{macro}[pTF]{\str_if_eq:nn}
+% \begin{macro}[pTF]{\str_if_eq:xx}
+% Modern engines provide a direct way of comparing two token lists,
+% but returning a number. This set of conditionals therefore make life
+% a bit clearer. The \texttt{nn} and \texttt{xx} versions are created
+% directly as this is most efficient. These should eventually
+% move somewhere else.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \str_if_eq:nn #1#2 { p , T , F , TF }
+ {
+ \if_int_compare:w \pdftex_strcmp:D { \exp_not:n {#1} } { \exp_not:n {#2} }
+ = \c_zero
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+\prg_new_conditional:Npnn \str_if_eq:xx #1#2 { p , T , F , TF }
+ {
+ \if_int_compare:w \pdftex_strcmp:D {#1} {#2} = \c_zero
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Deprecated functions}
+%
+% Deprecated on 2011-05-27, for removal by 2011-08-31.
+%
+% \begin{macrocode}
+\cs_new_eq:NN \cs_gnew_nopar:Npn \cs_new_nopar:Npn
+\cs_new_eq:NN \cs_gnew:Npn \cs_new:Npn
+\cs_new_eq:NN \cs_gnew_protected_nopar:Npn \cs_new_protected_nopar:Npn
+\cs_new_eq:NN \cs_gnew_protected:Npn \cs_new_protected:Npn
+\cs_new_eq:NN \cs_gnew_nopar:Npx \cs_new_nopar:Npx
+\cs_new_eq:NN \cs_gnew:Npx \cs_new:Npx
+\cs_new_eq:NN \cs_gnew_protected_nopar:Npx \cs_new_protected_nopar:Npx
+\cs_new_eq:NN \cs_gnew_protected:Npx \cs_new_protected:Npx
+\cs_new_eq:NN \cs_gnew_nopar:cpn \cs_new_nopar:cpn
+\cs_new_eq:NN \cs_gnew:cpn \cs_new:cpn
+\cs_new_eq:NN \cs_gnew_protected_nopar:cpn \cs_new_protected_nopar:cpn
+\cs_new_eq:NN \cs_gnew_protected:cpn \cs_new_protected:cpn
+\cs_new_eq:NN \cs_gnew_nopar:cpx \cs_new_nopar:cpx
+\cs_new_eq:NN \cs_gnew:cpx \cs_new:cpx
+\cs_new_eq:NN \cs_gnew_protected_nopar:cpx \cs_new_protected_nopar:cpx
+\cs_new_eq:NN \cs_gnew_protected:cpx \cs_new_protected:cpx
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_new_eq:NN \cs_gnew_eq:NN \cs_new_eq:NN
+\cs_new_eq:NN \cs_gnew_eq:cN \cs_new_eq:cN
+\cs_new_eq:NN \cs_gnew_eq:Nc \cs_new_eq:Nc
+\cs_new_eq:NN \cs_gnew_eq:cc \cs_new_eq:cc
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_new_eq:NN \cs_gundefine:N \cs_undefine:N
+\cs_new_eq:NN \cs_gundefine:c \cs_undefine:c
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_new_eq:NN \group_execute_after:N \group_insert_after:N
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</initex|package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3bootstrap.dtx b/Master/texmf-dist/source/latex/l3kernel/l3bootstrap.dtx
new file mode 100644
index 00000000000..69aaf46357b
--- /dev/null
+++ b/Master/texmf-dist/source/latex/l3kernel/l3bootstrap.dtx
@@ -0,0 +1,647 @@
+% \iffalse meta-comment
+%
+%% File: l3bootstrap.dtx Copyright (C) 2011 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 "expl3 bundle" (The Work in LPPL)
+%% and all files in that bundle must be distributed together.
+%%
+%% The released version of this bundle is available from CTAN.
+%%
+%% -----------------------------------------------------------------------
+%%
+%% The development version of the bundle can be found at
+%%
+%% http://www.latex-project.org/svnroot/experimental/trunk/
+%%
+%% for those people who are interested.
+%%
+%%%%%%%%%%%
+%% NOTE: %%
+%%%%%%%%%%%
+%%
+%% Snapshots taken from the repository represent work in progress and may
+%% not work or may contain conflicting material! We therefore ask
+%% people _not_ to put them into distributions, archives, etc. without
+%% prior consultation with the LaTeX3 Project.
+%%
+%% -----------------------------------------------------------------------
+%
+%<*package>
+\def\GetIdInfo$%
+ Id: #1 #2 #3-#4-#5 #6 #7 $#8%
+ {%
+ \def\ExplFileDate{#3/#4/#5}%
+ \def\ExplFileVersion{#2}%
+ }
+\GetIdInfo$Id: l3bootstrap.dtx 2478 2011-06-19 21:34:23Z joseph $
+ {L3 experimental bootstrap code}
+%</package>
+%<*driver>
+\documentclass[full]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3bootstrap} package\\ Bootstrap code^^A
+% \thanks{This file describes v\ExplFileVersion,
+% last revised \ExplFileDate.}^^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 \ExplFileDate}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% \section{Using the \LaTeX3 modules}
+%
+% The modules documented in \file{source3} are designed to be used on top of
+% \LaTeXe{} and are loaded all as one with the usual |\usepackage{expl3}| or
+% |\RequirePackage{expl3}| instructions. These modules will also form the
+% basis of the \LaTeX3 format, but work in this area is incomplete and not
+% included in this documentation at present.
+%
+% As the modules use a coding syntax different from standard
+% \LaTeXe{} it provides a few functions for setting it up.
+%
+% \begin{function}{\ExplSyntaxOn, \ExplSyntaxOff}
+% \begin{syntax}
+% \cs{ExplSyntaxOn} \meta{code} \cs{ExplSyntaxOff}
+% \end{syntax}
+% The \cs{ExplSyntaxOn} function switches to a category code
+% regim{\'e} in which spaces are ignored and in which the colon (|:|)
+% and underscore (|_|) are treated as \enquote{letters}, thus allowing
+% access to the names of code functions and variables. Within this
+% environment, |~| is used to input a space. The \cs{ExplSyntaxOff}
+% reverts to the document category code regim{\'e}.
+% \end{function}
+%
+% \begin{function}{\ExplSyntaxNamesOn, \ExplSyntaxNamesOff}
+% \begin{syntax}
+% \cs{ExplSyntaxNamesOn} \meta{code} \cs{ExplSyntaxNamesOff}
+% \end{syntax}
+% The \cs{ExplSyntaxOn} function switches to a category code
+% regim{\'e} in which the colon (|:|) and underscore (|_|) are treated as
+% \enquote{letters}, thus allowing access to the names of code functions
+% and variables. In contrast to \cs{ExplSyntaxOn}, using
+% \cs{ExplSyntaxNamesOn} does not cause spaces to be ignored.
+% The \cs{ExplSyntaxNamesOff} reverts to the document category code
+% regim{\'e}.
+% \end{function}
+%
+% \begin{function}{\ProvidesExplPackage, \ProvidesExplClass, \ProvidesExplFile}
+% \begin{syntax}
+% |\RequirePackage{expl3}| \\
+% \cs{ProvidesExplPackage} \Arg{package} \Arg{date} \Arg{version}
+% ~~\Arg{description}
+% \end{syntax}
+% These functions act broadly in the same way as the \LaTeXe{} kernel
+% functions \cs{ProvidesPackage}, \cs{ProvidesClass} and
+% \cs{ProvidesFile}. However, they also implicitly switch
+% \cs{ExplSyntaxOn} for the remainder of the code with the file. At the
+% end of the file, \cs{ExplSyntaxOff} will be called to reverse this.
+% (This is the same concept as \LaTeXe{} provides in turning on
+% \cs{makeatletter} within package and class code.)
+% \end{function}
+%
+% \begin{function}{\GetIdInfo}
+% \begin{syntax}
+% |\RequirePackage{l3names}|
+% \cs{GetIdInfo} |$Id:| \meta{SVN info field} |$| \Arg{description}
+% \end{syntax}
+% Extracts all information from a SVN field. Spaces are not
+% ignored in these fields. The information pieces are stored in
+% separate control sequences with \cs{ExplFileName} for the part of the
+% file name leading up to the period, \cs{ExplFileDate} for date,
+% \cs{ExplFileVersion} for version and \cs{ExplFileDescription} for the
+% description.
+% \end{function}
+%
+% To summarize: Every single package using this syntax should identify
+% itself using one of the above methods. Special care is taken so that
+% every package or class file loaded with \cs{RequirePackage} or alike
+% are loaded with usual \LaTeXe{} category codes and the \LaTeX3 category code
+% scheme is reloaded when needed afterwards. See implementation for
+% details. If you use the \cs{GetIdInfo} command you can use the
+% information when loading a package with
+% \begin{verbatim}
+% \ProvidesExplPackage{\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
+% \end{verbatim}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{Bootstrap code}
+%
+% \begin{macrocode}
+%<*initex|package>
+% \end{macrocode}
+%
+% \subsection{Format-specific code}
+%
+% The very first thing to do is to bootstrap the \IniTeX{} system so
+% that everything else will actually work. \TeX{} does not start with
+% some pretty basic character codes set up.
+% \begin{macrocode}
+%<*initex>
+\catcode `\{ = 1 \relax
+\catcode `\} = 2 \relax
+\catcode `\# = 6 \relax
+\catcode `\^ = 7 \relax
+%</initex>
+% \end{macrocode}
+%
+% Tab characters should not show up in the code, but to be on the
+% safe side.
+% \begin{macrocode}
+%<*initex>
+\catcode `\^^I = 10 \relax
+%</initex>
+% \end{macrocode}
+%
+% For \LuaTeX{} the extra primitives need to be enabled before
+% they can be use. No \cs{ifdefined} yet, so do it the old-fashioned
+% way. The primitive \cs{strcmp} is simulated using some \Lua{}
+% code, which currently has to be applied to every job as the \Lua{}
+% code is not part of the format. Thanks to Taco Hoekwater for this
+% code. The odd \cs{csname} business is needed so that the later
+% deletion code will work.
+% \begin{macrocode}
+%<*initex>
+\begingroup\expandafter\expandafter\expandafter\endgroup
+\expandafter\ifx\csname directlua\endcsname\relax
+\else
+ \directlua
+ {
+ tex.enableprimitives('',tex.extraprimitives ())
+ lua.bytecode[1] = function ()
+ function strcmp (A, B)
+ if A == B then
+ tex.write("0")
+ elseif A < B then
+ tex.write("-1")
+ else
+ tex.write("1")
+ end
+ end
+ end
+ lua.bytecode[1]()
+ }
+ \everyjob\expandafter
+ {\csname\detokenize{luatex_directlua:D}\endcsname{lua.bytecode[1]()}}
+ \long\edef\pdfstrcmp#1#2%
+ {%
+ \expandafter\noexpand\csname\detokenize{luatex_directlua:D}\endcsname
+ {%
+ strcmp%
+ (%
+ "\noexpand\luaescapestring{#1}",%
+ "\noexpand\luaescapestring{#2}"%
+ )%
+ }%
+ }
+\fi
+%</initex>
+% \end{macrocode}
+%
+% \subsection{Package-specific code}
+%
+% The package starts by identifying itself: the information itself is
+% taken from the SVN |Id| string at the start of the source file.
+% \begin{macrocode}
+%<*package>
+\ProvidesPackage{l3bootstrap}
+ [%
+ \ExplFileDate\space v\ExplFileVersion\space
+ L3 Experimental bootstrap code%
+ ]
+%</package>
+% \end{macrocode}
+%
+% For \LuaTeX{} the functionality of the \cs{pdfstrcmp} primitive
+% needs to be provided: the \pkg{pdftexmcds} package is used to
+% do this if necessary. At present, there is also a need to deal
+% with some low-level allocation stuff that could usefully be added
+% to \texttt{lualatex.ini}. As it is currently not, load Heiko
+% Oberdiek's \pkg{luatex} package instead.
+% \begin{macrocode}
+%<*package>
+\def\@tempa%
+ {%
+ \def\@tempa{}%
+ \RequirePackage{luatex}%
+ \RequirePackage{pdftexcmds}%
+ \let\pdfstrcmp\pdf@strcmp
+ }
+\begingroup\expandafter\expandafter\expandafter\endgroup
+\expandafter\ifx\csname directlua\endcsname\relax
+\else
+ \expandafter\@tempa
+\fi
+%</package>
+% \end{macrocode}
+%
+% \begin{macro}{\ExplSyntaxOff, \ExplSyntaxOn}
+% Experimental syntax switching is set up here for the package-loading
+% process. These are redefined in \pkg{expl3} for the package and in
+% \pkg{l3final} for the format.
+% \begin{macrocode}
+%<*package>
+\protected\edef\ExplSyntaxOff
+ {%
+ \catcode 9 = \the\catcode 9\relax
+ \catcode 32 = \the\catcode 32\relax
+ \catcode 34 = \the\catcode 34\relax
+ \catcode 38 = \the\catcode 38\relax
+ \catcode 58 = \the\catcode 58\relax
+ \catcode 94 = \the\catcode 94\relax
+ \catcode 95 = \the\catcode 95\relax
+ \catcode 124 = \the\catcode 124\relax
+ \catcode 126 = \the\catcode 126\relax
+ \endlinechar = \the\endlinechar\relax
+ \chardef\csname\detokenize{l_expl_status_bool}\endcsname = 0 \relax
+ }
+\protected\edef\ExplSyntaxOn
+ {
+ \catcode 9 = 9 \relax
+ \catcode 32 = 9 \relax
+ \catcode 34 = 12 \relax
+ \catcode 58 = 11 \relax
+ \catcode 94 = 7 \relax
+ \catcode 95 = 11 \relax
+ \catcode 124 = 12 \relax
+ \catcode 126 = 10 \relax
+ \endlinechar = 32 \relax
+ \chardef\csname\detokenize{l_expl_status_bool}\endcsname = 1 \relax
+ }
+%</package>
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\l_expl_status_bool}
+% The status for experimental code syntax: this is off at present. This
+% code is used by both the package and the format.
+% \begin{macrocode}
+\expandafter\chardef\csname\detokenize{l_expl_status_bool}\endcsname = 0 \relax
+% \end{macrocode}
+%\end{macro}
+%
+% \subsection{Dealing with package-mode meta-data}
+%
+% \begin{macro}{\GetIdInfo}
+% \begin{macro}[aux]
+% {
+% \GetIdInfoFull, \GetIdInfoAuxI, \GetIdInfoAuxII, \GetIdInfoAuxIII,
+% \GetIdInfoAuxCVS, \GetIdInfoAuxSVN
+% }
+% Functions for collecting up meta-data from the SVN information
+% used by the \LaTeX3 Project.
+% \begin{macrocode}
+%<*package>
+\protected\def\GetIdInfo
+ {
+ \begingroup
+ \catcode 32 = 10 \relax
+ \GetIdInfoAuxI
+ }
+\protected\def\GetIdInfoAuxI$#1$#2%
+ {
+ \def\tempa{#1}%
+ \def\tempb{Id}%
+ \ifx\tempa\tempb
+ \def\tempa
+ {%
+ \endgroup
+ \def\ExplFileDate{0000/00/00}%
+ \def\ExplFileDescription{#2}%
+ \def\ExplFileName{[unknown~name]}%
+ \def\ExplFileVersion{000}%
+ }%
+ \else
+ \def\tempa
+ {%
+ \endgroup
+ \GetIdInfoAuxII$#1${#2}%
+ }%
+ \fi
+ \tempa
+ }
+\protected\def\GetIdInfoAuxII$#1 #2.#3 #4 #5 #6 #7 #8$#9%
+ {%
+ \def\ExplFileName{#2}%
+ \def\ExplFileVersion{#4}%
+ \def\ExplFileDescription{#9}%
+ \GetIdInfoAuxIII#5\relax#3\relax#5\relax#6\relax
+ }
+\protected\def\GetIdInfoAuxIII#1#2#3#4#5#6\relax
+ {%
+ \ifx#5/%
+ \expandafter\GetIdInfoAuxCVS
+ \else
+ \expandafter\GetIdInfoAuxSVN
+ \fi
+ }
+\protected\def\GetIdInfoAuxCVS#1,v\relax#2\relax#3\relax
+ {\def\ExplFileDate{#2}}
+\protected\def\GetIdInfoAuxSVN#1\relax#2-#3-#4\relax#5Z\relax
+ {\def\ExplFileDate{#2/#3/#4}}
+%</package>
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\ProvidesExplPackage, \ProvidesExplClass, \ProvidesExplFile}
+% For other packages and classes building on this one it is convenient
+% not to need \cs{ExplSyntaxOn} each time.
+% \begin{macrocode}
+%<*package>
+\protected\def\ProvidesExplPackage#1#2#3#4%
+ {%
+ \ProvidesPackage{#1}[#2 v#3 #4]%
+ \ExplSyntaxOn
+ }
+\protected\def\ProvidesExplClass#1#2#3#4%
+ {%
+ \ProvidesClass{#1}[#2 v#3 #4]%
+ \ExplSyntaxOn
+ }
+\protected\def\ProvidesExplFile#1#2#3#4%
+ {%
+ \ProvidesFile{#1}[#2 v#3 #4]%
+ \ExplSyntaxOn
+ }
+%</package>
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@pushfilename, \@popfilename}
+% The idea here is to use \LaTeXe{}'s \cs{@pushfilename} and
+% \cs{@popfilename} to track the current syntax status. This can be
+% achieved by saving the current status flag at each push to a stack,
+% then recovering it at the pop stage and checking if the code
+% environment should still be active.
+% \begin{macrocode}
+%<*package>
+\edef\@pushfilename
+ {%
+ \edef\expandafter\noexpand
+ \csname\detokenize{l_expl_status_stack_tl}\endcsname
+ {%
+ \noexpand\ifodd\expandafter\noexpand
+ \csname\detokenize{l_expl_status_bool}\endcsname
+ 1%
+ \noexpand\else
+ 0%
+ \noexpand\fi
+ \expandafter\noexpand
+ \csname\detokenize{l_expl_status_stack_tl}\endcsname
+ }%
+ \ExplSyntaxOff
+ \unexpanded\expandafter{\@pushfilename}%
+ }
+\edef\@popfilename
+ {%
+ \unexpanded\expandafter{\@popfilename}%
+ \noexpand\if a\expandafter\noexpand\csname
+ \detokenize{l_expl_status_stack_tl}\endcsname a%
+ \ExplSyntaxOff
+ \noexpand\else
+ \noexpand\expandafter
+ \expandafter\noexpand\csname
+ \detokenize{expl_status_pop:w}\endcsname
+ \expandafter\noexpand\csname
+ \detokenize{l_expl_status_stack_tl}\endcsname
+ \noexpand\@nil
+ \noexpand\fi
+ }
+%</package>
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\l_expl_status_stack_tl}
+% As \pkg{expl3} itself cannot be loaded with the code environment
+% already active, at the end of the package \cs{ExplSyntaxOff} can
+% safely be called.
+% \begin{macrocode}
+%<*package>
+\@namedef{\detokenize{l_expl_status_stack_tl}}{0}
+%</package>
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[aux]{\expl_status_pop:w}
+% The pop auxiliary function removes the first item from the stack,
+% saves the rest of the stack and then does the test. As
+% \cs{ExplSyntaxOff} is already defined as a protected macro, there
+% is no need for \cs{noexpand} here.
+% \begin{macrocode}
+%<*package>
+\expandafter\edef\csname\detokenize{expl_status_pop:w}\endcsname#1#2\@nil
+ {%
+ \def\expandafter\noexpand
+ \csname\detokenize{l_expl_status_stack_tl}\endcsname{#2}%
+ \noexpand\ifodd#1\space
+ \noexpand\expandafter\noexpand\ExplSyntaxOn
+ \noexpand\else
+ \noexpand\expandafter\ExplSyntaxOff
+ \noexpand\fi
+ }
+%</package>
+% \end{macrocode}
+% \end{macro}
+%
+% We want the \pkg{expl3} bundle to be loaded \enquote{as one};
+% this command is
+% used to ensure that one of the |l3| packages isn't loaded on its own.
+% \begin{macrocode}
+%<*package>
+\expandafter\protected\expandafter\def
+ \csname\detokenize{package_check_loaded_expl:}\endcsname
+ {%
+ \@ifpackageloaded{expl3}
+ {}
+ {%
+ \PackageError{expl3}
+ {Cannot load the expl3 modules separately}
+ {%
+ The expl3 modules cannot be loaded separately;\MessageBreak
+ please \string\usepackage\string{expl3\string} instead.
+ }%
+ }%
+ }
+%</package>
+% \end{macrocode}
+%
+% \subsection{The \cs{pdfstrcmp} primitive in \XeTeX{}}
+%
+% Only \pdfTeX{} has a primitive called \cs{pdfstrcmp}. The \XeTeX{}
+% version is just \cs{strcmp}, so there is some shuffling to do.
+% \begin{macrocode}
+\begingroup\expandafter\expandafter\expandafter\endgroup
+ \expandafter\ifx\csname pdfstrcmp\endcsname\relax
+ \let\pdfstrcmp\strcmp
+\fi
+% \end{macrocode}
+%
+% \subsection{Engine requirements}
+%
+% The code currently requires functionality equivalent to \cs{pdfstrcmp}
+% in addition to \eTeX{}. The former is therefore used as a test for
+% a suitable engine.
+% \begin{macrocode}
+\begingroup\expandafter\expandafter\expandafter\endgroup
+\expandafter\ifx\csname pdfstrcmp\endcsname\relax
+%<*package>
+ \PackageError{l3names}{Required primitive not found: \protect\pdfstrcmp}
+ {%
+ LaTeX3 requires the e-TeX primitives and
+ \string\pdfstrcmp.\MessageBreak
+ These are available in engine versions: \MessageBreak
+ - pdfTeX 1.30 \MessageBreak
+ - XeTeX 0.9994 \MessageBreak
+ - LuaTeX 0.60 \MessageBreak
+ or later. \MessageBreak
+ \MessageBreak
+ Loading of expl3 will abort!
+ }
+%</package>
+%<*initex>
+ \newlinechar`\^^J\relax
+ \errhelp{%
+ LaTeX3 requires the e-TeX primitives and
+ \string\pdfstrcmp. ^^J
+ These are available in engine versions: ^^J
+ - pdfTeX 1.30 ^^J
+ - XeTeX 0.9994 ^^J
+ - LuaTeX 0.60 ^^J
+ or later. ^^J
+ For pdfTeX and XeTeX the '-etex' command-line switch is also
+ needed.^^J
+ ^^J
+ Format building will abort!
+ }
+%</initex>
+ \expandafter\endinput
+\fi
+% \end{macrocode}
+%
+% \subsection{The \LaTeX3 code environment}
+%
+% \begin{macro}{\ExplSyntaxNamesOn, \ExplSyntaxNamesOff}
+% These can be set up early, as they are not used anywhere in the
+% package or format itself. Using an \cs{edef} here makes the
+% definitions that bit clearer later.
+% \begin{macrocode}
+\protected\edef\ExplSyntaxNamesOn
+ {%
+ \expandafter\noexpand
+ \csname\detokenize{char_set_catcode_letter:n}\endcsname{58}%
+ \expandafter\noexpand
+ \csname\detokenize{char_set_catcode_letter:n}\endcsname{95}%
+ }
+\protected\edef\ExplSyntaxNamesOff
+ {%
+ \expandafter\noexpand
+ \csname\detokenize{char_set_catcode_math_subscript:n}\endcsname{58}%
+ \expandafter\noexpand
+ \csname\detokenize{char_set_catcode_other:n}\endcsname{95}%
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% The code environment is now set up for the format: the package deals
+% with this using \cs{ProvidesExplPackage}.
+% \begin{macrocode}
+%<*initex>
+\catcode 9 = 9 \relax
+\catcode 32 = 9 \relax
+\catcode 34 = 12 \relax
+\catcode 58 = 11 \relax
+\catcode 94 = 7 \relax
+\catcode 95 = 11 \relax
+\catcode 124 = 12 \relax
+\catcode 126 = 10 \relax
+\endlinechar = 32 \relax
+%</initex>
+% \end{macrocode}
+%
+% \begin{macro}{\ExplSyntaxOn, \ExplSyntaxOff}
+% The idea here is that multiple \cs{ExplSyntaxOn} calls are not
+% going to mess up category codes, and that multiple calls to
+% \cs{ExplSyntaxOff} are also not wasting time.
+% \begin{macrocode}
+%<*initex>
+\protected \def \ExplSyntaxOn
+ {
+ \bool_if:NF \l_expl_status_bool
+ {
+ \cs_set_protected_nopar:Npx \ExplSyntaxOff
+ {
+ \char_set_catcode:nn { 9 } { \char_value_catcode:n { 9 } }
+ \char_set_catcode:nn { 32 } { \char_value_catcode:n { 32 } }
+ \char_set_catcode:nn { 34 } { \char_value_catcode:n { 34 } }
+ \char_set_catcode:nn { 38 } { \char_value_catcode:n { 38 } }
+ \char_set_catcode:nn { 58 } { \char_value_catcode:n { 58 } }
+ \char_set_catcode:nn { 94 } { \char_value_catcode:n { 94 } }
+ \char_set_catcode:nn { 95 } { \char_value_catcode:n { 95 } }
+ \char_set_catcode:nn { 124 } { \char_value_catcode:n { 124 } }
+ \char_set_catcode:nn { 126 } { \char_value_catcode:n { 126 } }
+ \tex_endlinechar:D =
+ \tex_the:D \tex_endlinechar:D \scan_stop:
+ \bool_set_false:N \l_expl_status_bool
+ \cs_set_protected_nopar:Npn \ExplSyntaxOff { }
+ }
+ }
+ \char_set_catcode_ignore:n { 9 } % tab
+ \char_set_catcode_ignore:n { 32 } % space
+ \char_set_catcode_other:n { 34 } % double quote
+ \char_set_catcode_alignment:n { 38 } % ampersand
+ \char_set_catcode_letter:n { 58 } % colon
+ \char_set_catcode_math_superscript:n { 94 } % circumflex
+ \char_set_catcode_letter:n { 95 } % underscore
+ \char_set_catcode_other:n { 124 } % pipe
+ \char_set_catcode_space:n { 126 } % tilde
+ \tex_endlinechar:D = 32 \scan_stop:
+ \bool_set_true:N \l_expl_status_bool
+ }
+\protected \def \ExplSyntaxOff { }
+%</initex>
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}{\l_expl_status_bool}
+% A flag to show the current syntax status.
+% \begin{macrocode}
+%<*initex>
+\chardef \l_expl_status_bool = 0 ~
+%</initex>
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macrocode}
+%</initex|package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex \ No newline at end of file
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3box.dtx b/Master/texmf-dist/source/latex/l3kernel/l3box.dtx
new file mode 100644
index 00000000000..1947f85b356
--- /dev/null
+++ b/Master/texmf-dist/source/latex/l3kernel/l3box.dtx
@@ -0,0 +1,1237 @@
+% \iffalse meta-comment
+%
+%% File: l3box.dtx Copyright (C) 2005-2011 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 "expl3 bundle" (The Work in LPPL)
+%% and all files in that bundle must be distributed together.
+%%
+%% The released version of this bundle is available from CTAN.
+%%
+%% -----------------------------------------------------------------------
+%%
+%% The development version of the bundle can be found at
+%%
+%% http://www.latex-project.org/svnroot/experimental/trunk/
+%%
+%% for those people who are interested.
+%%
+%%%%%%%%%%%
+%% NOTE: %%
+%%%%%%%%%%%
+%%
+%% Snapshots taken from the repository represent work in progress and may
+%% not work or may contain conflicting material! We therefore ask
+%% people _not_ to put them into distributions, archives, etc. without
+%% prior consultation with the LaTeX3 Project.
+%%
+%% -----------------------------------------------------------------------
+%
+%<*driver|package>
+\RequirePackage{l3names}
+\GetIdInfo$Id: l3box.dtx 2478 2011-06-19 21:34:23Z joseph $
+ {L3 Experimental boxes}
+%</driver|package>
+%<*driver>
+\documentclass[full]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3box} package\\ Boxes^^A
+% \thanks{This file describes v\ExplFileVersion,
+% last revised \ExplFileDate.}^^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 \ExplFileDate}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% There are three kinds of box operations: horizontal mode denoted
+% with prefix |\hbox_|, vertical mode with prefix |\vbox_|, and the
+% generic operations working in both modes with prefix |\box_|.
+%
+% \section{Creating and initialising boxes}
+%
+% \begin{function}{\box_new:N, \box_new:c}
+% \begin{syntax}
+% \cs{box_new:N} \meta{box}
+% \end{syntax}
+% Creates a new \meta{box} or raises an error if the name is
+% already taken. The declaration is global. The \meta{box} will
+% initially be void.
+% \end{function}
+%
+% \begin{function}{\box_clear:N, \box_clear:c}
+% \begin{syntax}
+% \cs{box_clear:N} \meta{box}
+% \end{syntax}
+% Clears the content of the \meta{box} by setting the box equal to
+% \cs{c_void_box} within the current \TeX{} group level.
+% \end{function}
+%
+% \begin{function}{\box_gclear:N, \box_gclear:c}
+% \begin{syntax}
+% \cs{box_gclear:N} \meta{box}
+% \end{syntax}
+% Clears the content of the \meta{box} by setting the box equal to
+% \cs{c_void_box} globally.
+% \end{function}
+%
+% \begin{function}{\box_clear_new:N, \box_clear_new:c}
+% \begin{syntax}
+% \cs{box_clear_new:N} \meta{box}
+% \end{syntax}
+% If the \meta{box} is not defined, globally creates it. If the \meta{box}
+% is defined,
+% clears the content of the \meta{box} by setting the box equal to
+% \cs{c_void_box} within the current \TeX{} group level.
+% \end{function}
+%
+% \begin{function}{\box_gclear_new:N, \box_gclear_new:c}
+% \begin{syntax}
+% \cs{box_gclear_new:N} \meta{box}
+% \end{syntax}
+% If the \meta{box} is not defined, globally creates it. If the \meta{box}
+% is defined,
+% clears the content of the \meta{box} by setting the box equal to
+% \cs{c_void_box} globally.
+% \end{function}
+%
+% \begin{function}
+% {\box_set_eq:NN, \box_set_eq:cN, \box_set_eq:Nc, \box_set_eq:cc}
+% \begin{syntax}
+% \cs{box_set_eq:NN} \meta{box1} \meta{box2}
+% \end{syntax}
+% Sets the content of \meta{box1} equal to that of \meta{box2}. This
+% assignment is restricted to the current \TeX{} group level.
+% \end{function}
+%
+% \begin{function}
+% {\box_gset_eq:NN, \box_gset_eq:cN, \box_gset_eq:Nc, \box_gset_eq:cc}
+% \begin{syntax}
+% \cs{box_gset_eq:NN} \meta{box1} \meta{box2}
+% \end{syntax}
+% Sets the content of \meta{box1} equal to that of \meta{box2} globally.
+% \end{function}
+%
+% \begin{function}
+% {
+% \box_set_eq_clear:NN, \box_set_eq_clear:cN,
+% \box_set_eq_clear:Nc, \box_set_eq_clear:cc
+% }
+% \begin{syntax}
+% \cs{box_set_eq_clear:NN} \meta{box1} \meta{box2}
+% \end{syntax}
+% Sets the content of \meta{box1} within the current \TeX{} group
+% equal to that of \meta{box2}, then clears \meta{box2} globally.
+% \end{function}
+%
+% \begin{function}
+% {
+% \box_gset_eq_clear:NN, \box_gset_eq_clear:cN,
+% \box_gset_eq_clear:Nc, \box_gset_eq_clear:cc
+% }
+% \begin{syntax}
+% \cs{box_gset_eq_clear:NN} \meta{box1} \meta{box2}
+% \end{syntax}
+% Sets the content of \meta{box1} equal to that of \meta{box2}, then
+% clears \meta{box2}. These assignments are global.
+% \end{function}
+%
+% \section{Using boxes}
+%
+% \begin{function}{\box_use:N, \box_use:c}
+% \begin{syntax}
+% \cs{box_use:N} \meta{box}
+% \end{syntax}
+% Inserts the current content of the \meta{box} onto the current
+% list for typesetting.
+% \begin{texnote}
+% This is the \TeX{} primitive \cs{copy}.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{\box_use_clear:N, \box_use_clear:c}
+% \begin{syntax}
+% \cs{box_use_clear:N} \meta{box}
+% \end{syntax}
+% Inserts the current content of the \meta{box} onto the current
+% list for typesetting, then globally clears the content of the
+% \meta{box}.
+% \begin{texnote}
+% This is the \TeX{} primitive \cs{box}.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{\box_move_right:nn, \box_move_left:nn}
+% \begin{syntax}
+% \cs{box_move_right:nn} \Arg{dimexpr} \Arg{box function}
+% \end{syntax}
+% This function operates in vertical mode, and inserts the
+% material specified by the \meta{box function}
+% such that its reference point is displaced horizontally by the given
+% \meta{dimexpr} from the reference point for typesetting, to the right
+% or left as appropriate. The \meta{box function} should be
+% a box opeeration such as |\box_use:N \<box>| or a \enquote{raw}
+% box specification such as |\vbox:n { xyz }|.
+% \end{function}
+%
+% \begin{function}{\box_move_up:nn, \box_move_down:nn}
+% \begin{syntax}
+% \cs{box_move_up:nn} \Arg{dimexpr} \Arg{box function}
+% \end{syntax}
+% This function operates in horizontal mode, and inserts the
+% material specified by the \meta{box function}
+% such that its reference point is displaced vertical by the given
+% \meta{dimexpr} from the reference point for typesetting, up
+% or down as appropriate. The \meta{box function} should be
+% a box opeeration such as |\box_use:N \<box>| or a \enquote{raw}
+% box specification such as |\vbox:n { xyz }|.
+% \end{function}
+%
+% \section{Measuring and setting box dimensions}
+%
+% \begin{function}{\box_dp:N, \box_dp:c}
+% \begin{syntax}
+% \cs{box_dp:N} \meta{box}
+% \end{syntax}
+% Calculates the depth (below the baseline) of the \meta{box}
+% and leaves this in the input stream. The output of this function
+% is suitable for use in a \meta{dimension expression} for
+% calculations.
+% \begin{texnote}
+% This is the \TeX{} primitive \cs{dp}.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{\box_ht:N, \box_ht:c}
+% \begin{syntax}
+% \cs{box_ht:N} \meta{box}
+% \end{syntax}
+% Calculates the height (above the baseline) of the \meta{box}
+% and leaves this in the input stream. The output of this function
+% is suitable for use in a \meta{dimension expression} for
+% calculations.
+% \begin{texnote}
+% This is the \TeX{} primitive \cs{ht}.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{\box_wd:N, \box_wd:c}
+% \begin{syntax}
+% \cs{box_wd:N} \meta{box}
+% \end{syntax}
+% Calculates the width of the \meta{box} and leaves this in the
+% input stream. The output of this function is suitable for use in a
+% \meta{dimension expression} for calculations.
+% \begin{texnote}
+% This is the \TeX{} primitive \cs{wd}.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{\box_set_dp:Nn, \box_set_dp:cn}
+% \begin{syntax}
+% \cs{box_set_dp:Nn} \meta{box} \Arg{dimension expression}
+% \end{syntax}
+% Set the depth (below the baseline) of the \meta{box} to the value of
+% the \Arg{dimension expression}. This is a global assignment.
+% \end{function}
+%
+% \begin{function}{\box_set_ht:Nn, \box_set_ht:cn}
+% \begin{syntax}
+% \cs{box_set_ht:Nn} \meta{box} \Arg{dimension expression}
+% \end{syntax}
+% Set the height (above the baseline) of the \meta{box} to the value of
+% the \Arg{dimension expression}. This is a global assignment.
+% \end{function}
+%
+% \begin{function}{\box_set_wd:Nn, \box_set_wd:cn}
+% \begin{syntax}
+% \cs{box_set_wd:Nn} \meta{box} \Arg{dimension expression}
+% \end{syntax}
+% Set the width of the \meta{box} to the value of the
+% \Arg{dimension expression}. This is a global assignment.
+% \end{function}
+%
+% \section{Box conditionals}
+%
+% \begin{function}[EXP,pTF]{\box_if_empty:N, \box_if_empty:c}
+% \begin{syntax}
+% \cs{box_if_empty_p:N} \meta{box}
+% \cs{box_if_empty:NTF} \meta{box} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if \meta{box} is a empty (equal to \cs{c_empty_box}).
+% The branching versions then leave either
+% \meta{true code} or \meta{false code} in the input stream, as
+% appropriate to the truth of the test and the variant of the function
+% chosen. The logical truth of the test is left in the input stream by
+% the predicate version.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\box_if_horizontal:N, \box_if_horizontal:c}
+% \begin{syntax}
+% \cs{box_if_horizontal_p:N} \meta{box}
+% \cs{box_if_horizontal:NTF} \meta{box} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if \meta{box} is a horizontal box. The branching
+% versions then leave either \meta{true code} or \meta{false code}
+% in the input stream, as appropriate to the truth of the test and
+% the variant of the function chosen. The logical truth of the test
+% is left in the input stream by the predicate version.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\box_if_vertical:N, \box_if_vertical:c}
+% \begin{syntax}
+% \cs{box_if_vertical_p:N} \meta{box}
+% \cs{box_if_vertical:NTF} \meta{box} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if \meta{box} is a vertical box. The branching
+% versions then leave either \meta{true code} or \meta{false code}
+% in the input stream, as appropriate to the truth of the test and
+% the variant of the function chosen. The logical truth of the test
+% is left in the input stream by the predicate version.
+% \end{function}
+%
+% \section{The last box inserted}
+%
+% \begin{variable}{\l_last_box}
+% This is a box containing the last item added to the current partial
+% list, except in the case of the main vertical list (main galley), in
+% which case this box is always void. Notice that although this is
+% not a constant, it is \emph{not} settable by the programmer but is
+% instead varied by \TeX{}.
+% \begin{texnote}
+% This is the \TeX{} primitive \cs{lastbox} renamed.
+% \end{texnote}
+% \end{variable}
+%
+% \section{Constant boxes}
+%
+% \begin{variable}{\c_empty_box}
+% This is a permanently empty box, which is neither set as horizontal
+% nor vertical.
+% \end{variable}
+%
+% \section{Scratch boxes}
+%
+% \begin{variable}{\l_tmpa_tl, \l_tmpb_tl}
+% Scratch boxes for local assignment. These are never used by
+% the kernel code, and so are safe for use with any \LaTeX3-defined
+% function. However, they may be overwritten by other non-kernel
+% code and so should only be used for short-term storage.
+% \end{variable}
+%
+% \section{Viewing box contents}
+%
+% \begin{function}{\box_show:N, \box_show:c}
+% \begin{syntax}
+% \cs{box_show:N} \meta{box}
+% \end{syntax}
+% Writes the contents of \meta{box} to the log file.
+% \begin{texnote}
+% This is the \TeX{} primitive \cs{showbox}.
+% \end{texnote}
+% \end{function}
+%
+% \section{Horizontal mode boxes}
+%
+% \begin{function}{\hbox:n}
+% \begin{syntax}
+% \cs{hbox:n} \Arg{contents}
+% \end{syntax}
+% Typesets the \meta{contents} into a horizontal box of natural
+% width and then includes this box in the current list for typesetting.
+% \begin{texnote}
+% This is the \TeX{} primitive \cs{hbox}.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{\hbox_to_wd:nn}
+% \begin{syntax}
+% \cs{hbox_to_wd:nn} \Arg{dimexpr} \Arg{contents}
+% \end{syntax}
+% Typesets the \meta{contents} into a horizontal box of width
+% \meta{dimexpr} and then includes this box in the current list for
+% typesetting.
+% \end{function}
+%
+% \begin{function}{\hbox_to_zero:n}
+% \begin{syntax}
+% \cs{hbox_to_zero:n} \Arg{contents}
+% \end{syntax}
+% Typesets the \meta{contents} into a horizontal box of zero width
+% and then includes this box in the current list for typesetting.
+% \end{function}
+%
+% \begin{function}{\hbox_set:Nn, \hbox_set:cn}
+% \begin{syntax}
+% \cs{hbox_set:Nn} \meta{box} \Arg{contents}
+% \end{syntax}
+% Typesets the \meta{contents} at natural width and then stores the
+% result inside the \meta{box}. The assignment is local.
+% \end{function}
+%
+% \begin{function}{\hbox_gset:Nn, \hbox_gset:cn}
+% \begin{syntax}
+% \cs{hbox_gset:Nn} \meta{box} \Arg{contents}
+% \end{syntax}
+% Typesets the \meta{contents} at natural width and then stores the
+% result inside the \meta{box}. The assignment is global.
+% \end{function}
+%
+% \begin{function}{\hbox_set_to_wd:Nnn, \hbox_set_to_wd:cnn}
+% \begin{syntax}
+% \cs{hbox_set_to_wd:Nnn} \meta{box} \Arg{dimexpr} \Arg{contents}
+% \end{syntax}
+% Typesets the \meta{contents} to the width given by the \meta{dimexpr}
+% and then stores the result inside the \meta{box}. The assignment is
+% local.
+% \end{function}
+%
+% \begin{function}{\hbox_gset_to_wd:Nnn, \hbox_gset_to_wd:cnn}
+% \begin{syntax}
+% \cs{hbox_gset_to_wd:Nnn} \meta{box} \Arg{dimexpr} \Arg{contents}
+% \end{syntax}
+% Typesets the \meta{contents} to the width given by the \meta{dimexpr}
+% and then stores the result inside the \meta{box}. The assignment is
+% global.
+% \end{function}
+%
+% \begin{function}{\hbox_overlap_right:n}
+% \begin{syntax}
+% \cs{hbox_overlap_right:n} \Arg{contents}
+% \end{syntax}
+% Typesets the \meta{contents} into a horizontal box of zero width
+% such that material will protrude to the right of the insertion
+% point.
+% \end{function}
+%
+% \begin{function}{\hbox_overlap_left:n}
+% \begin{syntax}
+% \cs{hbox_overlap_left:n} \Arg{contents}
+% \end{syntax}
+% Typesets the \meta{contents} into a horizontal box of zero width
+% such that material will protrude to the left of the insertion
+% point.
+% \end{function}
+%
+% \begin{function}
+% {
+% \hbox_set_inline_begin:N, \hbox_set_inline_begin:c,
+% \hbox_set_inline_end:
+% }
+% \begin{syntax}
+% \cs{hbox_set_inline_begin:N} \meta{box} \meta{contents}
+% ~~\cs{hbox_set_inline_end:}
+% \end{syntax}
+% Typesets the \meta{contents} at natural width and then stores the
+% result inside the \meta{box}. The assignment is local. In contrast
+% to \cs{hbox_set:Nn} this function does not absorb the argument
+% when finding the \meta{content}, and so can be used in circumstances
+% where the \meta{content} may not be a simple argument.
+% \end{function}
+%
+% \begin{function}
+% {
+% \hbox_gset_inline_begin:N, \hbox_gset_inline_begin:c,
+% \hbox_gset_inline_end:
+% }
+% \begin{syntax}
+% \cs{hbox_gset_inline_begin:N} \meta{box} \meta{contents}
+% ~~\cs{hbox_gset_inline_end:}
+% \end{syntax}
+% Typesets the \meta{contents} at natural width and then stores the
+% result inside the \meta{box}. The assignment is global. In contrast
+% to \cs{hbox_set:Nn} this function does not absorb the argument
+% when finding the \meta{content}, and so can be used in circumstances
+% where the \meta{content} may not be a simple argument.
+% \end{function}
+%
+% \begin{function}{\hbox_unpack:N, \hbox_unpack:c}
+% \begin{syntax}
+% \cs{hbox_unpack:N} \meta{box}
+% \end{syntax}
+% Unpacks the content of the horizontal \meta{box}, retaining any stretching
+% or shrinking applied when the \meta{box} was set.
+% \begin{texnote}
+% This is the \TeX{} primitive \cs{unhcopy}.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{\hbox_unpack_clear:N, \hbox_unpack_clear:c}
+% \begin{syntax}
+% \cs{hbox_unpack_clear:N} \meta{box}
+% \end{syntax}
+% Unpacks the content of the horizontal \meta{box}, retaining any stretching
+% or shrinking applied when the \meta{box} was set. The \meta{box} is
+% then cleared globally.
+% \begin{texnote}
+% This is the \TeX{} primitive \cs{unhbox}.
+% \end{texnote}
+% \end{function}
+%
+% \section{Vertical mode boxes}
+%
+% Vertical boxes inherit their baseline from their contents. The
+% standard case is that the baseline of the box is at the same position
+% as that of the last item added to the box. This means that the box
+% will have no depth unless the last item added to it had depth. As a
+% result most vertical boxes have a large height value and small or
+% zero depth. The exception are |_top| boxes, where the reference point
+% is that of the first item added. These tend to have a large depth and
+% small height, although the later will typically be non-zero.
+%
+% \begin{function}{\vbox:n}
+% \begin{syntax}
+% \cs{vbox:n} \Arg{contents}
+% \end{syntax}
+% Typesets the \meta{contents} into a vertical box of natural height
+% and includes this box in the current list for typesetting.
+% \begin{texnote}
+% This is the \TeX{} primitive \cs{vbox}.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{\vbox_top:n}
+% \begin{syntax}
+% \cs{vbox_top:n} \Arg{contents}
+% \end{syntax}
+% Typesets the \meta{contents} into a vertical box of natural height
+% and includes this box in the current list for typesetting. The
+% baseline of the box will tbe equal to that of the \emph{first}
+% item added to the box.
+% \begin{texnote}
+% This is the \TeX{} primitive \cs{vtop}.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{\vbox_to_ht:nn}
+% \begin{syntax}
+% \cs{vbox_to_ht:n} \Arg{contents} \Arg{dimexpr}
+% \end{syntax}
+% Typesets the \meta{contents} into a vertical box of height
+% \meta{dimexpr} and then includes this box in the current list for
+% typesetting.
+% \end{function}
+%
+% \begin{function}{\vbox_to_zero:n}
+% \begin{syntax}
+% \cs{vbox_to_zero:n} \Arg{contents}
+% \end{syntax}
+% Typesets the \meta{contents} into a vertical box of zero height
+% and then includes this box in the current list for typesetting.
+% \end{function}
+%
+% \begin{function}{\vbox_set:Nn, \vbox_set:cn}
+% \begin{syntax}
+% \cs{vbox_set:Nn} \meta{box} \Arg{contents}
+% \end{syntax}
+% Typesets the \meta{contents} at natural height and then stores the
+% result inside the \meta{box}. The assignment is local.
+% \end{function}
+%
+% \begin{function}{\vbox_gset:Nn, \vbox_gset:cn}
+% \begin{syntax}
+% \cs{vbox_gset:Nn} \meta{box} \Arg{contents}
+% \end{syntax}
+% Typesets the \meta{contents} at natural height and then stores the
+% result inside the \meta{box}. The assignment is global.
+% \end{function}
+%
+% \begin{function}{\vbox_set_top:Nn, \vbox_set_top:cn}
+% \begin{syntax}
+% \cs{vbox_set_top:Nn} \meta{box} \Arg{contents}
+% \end{syntax}
+% Typesets the \meta{contents} at natural height and then stores the
+% result inside the \meta{box}. The baseline of the box will tbe equal
+% to that of the \emph{first} item added to the box. The assignment is
+% local.
+% \end{function}
+%
+% \begin{function}{\vbox_gset_top:Nn, \vbox_gset_top:cn}
+% \begin{syntax}
+% \cs{vbox_gset_top:Nn} \meta{box} \Arg{contents}
+% \end{syntax}
+% Typesets the \meta{contents} at natural height and then stores the
+% result inside the \meta{box}. The baseline of the box will tbe equal
+% to that of the \emph{first} item added to the box. The assignment is
+% global.
+% \end{function}
+%
+% \begin{function}{\vbox_set_to_ht:Nnn, \vbox_set_to_ht:cnn}
+% \begin{syntax}
+% \cs{vbox_set_to_ht:Nnn} \meta{box} \Arg{dimexpr} \Arg{contents}
+% \end{syntax}
+% Typesets the \meta{contents} to the height given by the
+% \meta{dimexpr} and then stores the result inside the \meta{box}.
+% The assignment is local.
+% \end{function}
+%
+% \begin{function}{\vbox_gset_to_ht:Nnn, \vbox_gset_to_ht:cnn}
+% \begin{syntax}
+% \cs{vbox_gset_to_ht:Nnn} \meta{box} \Arg{dimexpr} \Arg{contents}
+% \end{syntax}
+% Typesets the \meta{contents} to the height given by the
+% \meta{dimexpr} and then stores the result inside the \meta{box}.
+% The assignment is global.
+% \end{function}
+%
+% \begin{function}
+% {
+% \vbox_set_inline_begin:N, \vbox_set_inline_begin:c,
+% \vbox_set_inline_end:
+% }
+% \begin{syntax}
+% \cs{vbox_set_inline_begin:N} \meta{box} \meta{contents}
+% ~~\cs{vbox_set_inline_end:}
+% \end{syntax}
+% Typesets the \meta{contents} at natural height and then stores the
+% result inside the \meta{box}. The assignment is local. In contrast
+% to \cs{vbox_set:Nn} this function does not absorb the argument
+% when finding the \meta{content}, and so can be used in circumstances
+% where the \meta{content} may not be a simple argument.
+% \end{function}
+%
+% \begin{function}
+% {
+% \vbox_gset_inline_begin:N, \vbox_gset_inline_begin:c,
+% \vbox_gset_inline_end:
+% }
+% \begin{syntax}
+% \cs{vbox_gset_inline_begin:N} \meta{box} \meta{contents}
+% ~~\cs{vbox_set_inline_end:}
+% \end{syntax}
+% Typesets the \meta{contents} at natural height and then stores the
+% result inside the \meta{box}. The assignment is global. In contrast
+% to \cs{vbox_set:Nn} this function does not absorb the argument
+% when finding the \meta{content}, and so can be used in circumstances
+% where the \meta{content} may not be a simple argument.
+% \end{function}
+%
+% \begin{function}{\vbox_set_split_to_ht:NNn}
+% \begin{syntax}
+% \cs{vbox_set_split_to_ht:NNn} \meta{box1} \meta{box2} \Arg{dimexpr}
+% \end{syntax}
+% Sets \meta{box1} to contain material to the height given by the
+% \meta{dimexpr} by removing content from the top of \meta{box2}
+% (which must be a vertical box).
+% \begin{texnote}
+% This is the \TeX{} primitive \cs{vsplit}.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{\vbox_unpack:N, \vbox_unpack:c}
+% \begin{syntax}
+% \cs{vbox_unpack:N} \meta{box}
+% \end{syntax}
+% Unpacks the content of the vertical \meta{box}, retaining any stretching
+% or shrinking applied when the \meta{box} was set.
+% \begin{texnote}
+% This is the \TeX{} primitive \cs{unvcopy}.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{\vbox_unpack_clear:N, \vbox_unpack_clear:c}
+% \begin{syntax}
+% \cs{vbox_unpack:N} \meta{box}
+% \end{syntax}
+% Unpacks the content of the vertical \meta{box}, retaining any stretching
+% or shrinking applied when the \meta{box} was set. The \meta{box}
+% is then cleared globally.
+% \begin{texnote}
+% This is the \TeX{} primitive \cs{unvbox}.
+% \end{texnote}
+% \end{function}
+%
+% \section{Primitive box conditionals}
+%
+% \begin{function}[EXP]{\if_hbox:N}
+% \begin{syntax}
+% \cs{if_hbox:N} \meta{box}
+% ~~\meta{true code}
+% \cs{else:}
+% ~~\meta{false code}
+% \cs{fi:}
+% \end{syntax}
+% Tests is \meta{box} is a horizontal box.
+% \begin{texnote}
+% This is the \TeX{} primitive \cs{ifhbox}.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[EXP]{\if_vbox:N}
+% \begin{syntax}
+% \cs{if_vbox:N} \meta{box}
+% ~~\meta{true code}
+% \cs{else:}
+% ~~\meta{false code}
+% \cs{fi:}
+% \end{syntax}
+% Tests is \meta{box} is a vertical box.
+% \begin{texnote}
+% This is the \TeX{} primitive \cs{ifvbox}.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[EXP]{\if_box_empty:N}
+% \begin{syntax}
+% \cs{if_box_empty:N} \meta{box}
+% ~~\meta{true code}
+% \cs{else:}
+% ~~\meta{false code}
+% \cs{fi:}
+% \end{syntax}
+% Tests is \meta{box} is an empty (void) box.
+% \begin{texnote}
+% This is the \TeX{} primitive \cs{ifvoid}.
+% \end{texnote}
+% \end{function}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3box} implementation}
+%
+% \begin{macrocode}
+%<*initex|package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*package>
+\ProvidesExplPackage
+ {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
+\package_check_loaded_expl:
+%<*initex|package>
+% \end{macrocode}
+%
+% The code in this module is very straight forward so I'm not going to
+% comment it very extensively.
+%
+% \subsection{Creating and initialising boxes}
+%
+% \TestFiles{m3box001.lvt}
+%
+% \begin{macro}{\box_new:N,\box_new:c}
+% Defining a new \meta{box} register: remember that box $255$ is not
+% generally available.
+% \begin{macrocode}
+%<*initex>
+\alloc_new:nnnN { box } \c_zero \c_max_register_int \tex_mathchardef:D
+\seq_put_right:Nn \g_box_allocation_seq {255}
+%</initex>
+%<*package>
+\cs_new_protected:Npn \box_new:N #1
+ {
+ \chk_if_free_cs:N #1
+ \newbox #1
+ }
+%</package>
+\cs_generate_variant:Nn \box_new:N { c }
+% \end{macrocode}
+%
+% \begin{macro}{\box_clear:N, \box_clear:c}
+% \begin{macro}{\box_gclear:N, \box_gclear:c}
+% \testfile*
+% Clear a \meta{box} register.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \box_clear:N #1
+ { \box_set_eq:NN #1 \c_empty_box }
+\cs_new_protected_nopar:Npn \box_gclear:N #1
+ { \box_gset_eq:NN #1 \c_empty_box }
+\cs_generate_variant:Nn \box_clear:N { c }
+\cs_generate_variant:Nn \box_gclear:N { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\box_clear_new:N, \box_clear_new:c}
+% \begin{macro}{\box_gclear_new:N, \box_gclear_new:c}
+% \testfile*
+% Clear or new.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \box_clear_new:N #1
+ {
+ \cs_if_exist:NTF #1
+ { \box_set_eq:NN #1 \c_empty_box }
+ { \box_new:N #1 }
+ }
+\cs_new_protected_nopar:Npn \box_gclear_new:N #1
+ {
+ \cs_if_exist:NTF #1
+ { \box_gset_eq:NN #1 \c_empty_box }
+ { \box_new:N #1 }
+ }
+\cs_generate_variant:Nn \box_clear_new:N { c }
+\cs_generate_variant:Nn \box_gclear_new:N { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {\box_set_eq:NN, \box_set_eq:cN, \box_set_eq:Nc, \box_set_eq:cc}
+% \testfile*
+% \begin{macro}
+% {\box_gset_eq:NN, \box_gset_eq:cN, \box_gset_eq:Nc, \box_gset_eq:cc}
+% \testfile*
+% Assigning the contents of a box to be another box.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \box_set_eq:NN #1#2
+ { \tex_setbox:D #1 \tex_copy:D #2 }
+\cs_new_protected_nopar:Npn \box_gset_eq:NN
+ { \pref_global:D \box_set_eq:NN }
+\cs_generate_variant:Nn \box_set_eq:NN { cN , Nc , cc }
+\cs_generate_variant:Nn \box_gset_eq:NN { cN , Nc , cc }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \box_set_eq_clear:NN, \box_set_eq_clear:cN,
+% \box_set_eq_clear:Nc, \box_set_eq_clear:cc
+% }
+% \testfile*
+% \begin{macro}
+% {
+% \box_gset_eq_clear:NN, \box_gset_eq_clear:cN,
+% \box_gset_eq_clear:Nc, \box_gset_eq_clear:cc
+% }
+% \testfile*
+% Assigning the contents of a box to be another box.
+% This clears the second box globally (that's how \TeX{} does it).
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \box_set_eq_clear:NN #1#2
+ { \tex_setbox:D #1 \tex_box:D #2 }
+\cs_new_protected_nopar:Npn \box_gset_eq_clear:NN
+ { \pref_global:D \box_set_eq_clear:NN }
+\cs_generate_variant:Nn \box_set_eq_clear:NN { cN , Nc , cc }
+\cs_generate_variant:Nn \box_gset_eq_clear:NN { cN , Nc , cc }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Measuring and setting box dimensions}
+%
+% \begin{macro}{\box_ht:N,\box_ht:c}
+% \begin{macro}{\box_dp:N,\box_dp:c}
+% \begin{macro}{\box_wd:N,\box_wd:c}
+% \testfile*
+% Accessing the height, depth, and width of a \meta{box} register.
+% \begin{macrocode}
+\cs_new_eq:NN \box_ht:N \tex_ht:D
+\cs_new_eq:NN \box_dp:N \tex_dp:D
+\cs_new_eq:NN \box_wd:N \tex_wd:D
+\cs_generate_variant:Nn \box_ht:N { c }
+\cs_generate_variant:Nn \box_dp:N { c }
+\cs_generate_variant:Nn \box_wd:N { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\box_set_ht:Nn, \box_set_ht:cn}
+% \begin{macro}{\box_set_dp:Nn, \box_set_dp:cn}
+% \begin{macro}{\box_set_wd:Nn, \box_set_wd:cn}
+% Measuring is easy: all primitive work. These primitives are not
+% expandable, so the derived functions are not either.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \box_set_dp:Nn #1#2
+ { \box_dp:N #1 \dim_eval:w #2 \dim_eval_end: }
+\cs_new_protected_nopar:Npn \box_set_ht:Nn #1#2
+ { \box_ht:N #1 \dim_eval:w #2 \dim_eval_end: }
+\cs_new_protected_nopar:Npn \box_set_wd:Nn #1#2
+ { \box_wd:N #1 \dim_eval:w #2 \dim_eval_end: }
+\cs_generate_variant:Nn \box_set_ht:Nn { c }
+\cs_generate_variant:Nn \box_set_dp:Nn { c }
+\cs_generate_variant:Nn \box_set_wd:Nn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Using boxes}
+%
+% \begin{macro}{\box_use_clear:N, \box_use_clear:c}
+% \begin{macro}{\box_use:N, \box_use:c}
+% Using a \meta{box}. These are just \TeX{} primitives with meaningful
+% names.
+% \begin{macrocode}
+\cs_new_eq:NN \box_use_clear:N \tex_box:D
+\cs_new_eq:NN \box_use:N \tex_copy:D
+\cs_generate_variant:Nn \box_use_clear:N { c }
+\cs_generate_variant:Nn \box_use:N { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\box_move_left:nn,\box_move_right:nn}
+% \begin{macro}{\box_move_up:nn,\box_move_down:nn}
+% \testfile*
+% Move box material in different directions.
+% \begin{macrocode}
+\cs_new_protected:Npn \box_move_left:nn #1#2
+ { \tex_moveleft:D \dim_eval:w #1 \dim_eval_end: #2 }
+\cs_new_protected:Npn \box_move_right:nn #1#2
+ { \tex_moveright:D \dim_eval:w #1 \dim_eval_end: #2 }
+\cs_new_protected:Npn \box_move_up:nn #1#2
+ { \tex_raise:D \dim_eval:w #1 \dim_eval_end: #2 }
+\cs_new_protected:Npn \box_move_down:nn #1#2
+ { \tex_lower:D \dim_eval:w #1 \dim_eval_end: #2 }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Box conditionals}
+%
+% \begin{macro}{\if_hbox:N}
+% \begin{macro}{\if_vbox:N}
+% \begin{macro}{\if_box_empty:N}
+% \testfile*
+% The primitives for testing if a \meta{box} is empty/void or which
+% type of box it is.
+% \begin{macrocode}
+\cs_new_eq:NN \if_hbox:N \tex_ifhbox:D
+\cs_new_eq:NN \if_vbox:N \tex_ifvbox:D
+\cs_new_eq:NN \if_box_empty:N \tex_ifvoid:D
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\box_if_horizontal:N,\box_if_horizontal:c}
+% \testfile*
+% \begin{macro}[pTF]{\box_if_vertical:N,\box_if_vertical:c}
+% \testfile*
+% \begin{macrocode}
+\prg_new_conditional:Npnn \box_if_horizontal:N #1 { p , T , F , TF }
+ { \if_hbox:N #1 \prg_return_true: \else: \prg_return_false: \fi: }
+\prg_new_conditional:Npnn \box_if_vertical:N #1 { p , T , F , TF }
+ { \if_vbox:N #1 \prg_return_true: \else: \prg_return_false: \fi: }
+\cs_generate_variant:Nn \box_if_horizontal_p:N { c }
+\cs_generate_variant:Nn \box_if_horizontal:NT { c }
+\cs_generate_variant:Nn \box_if_horizontal:NF { c }
+\cs_generate_variant:Nn \box_if_horizontal:NTF { c }
+\cs_generate_variant:Nn \box_if_vertical_p:N { c }
+\cs_generate_variant:Nn \box_if_vertical:NT { c }
+\cs_generate_variant:Nn \box_if_vertical:NF { c }
+\cs_generate_variant:Nn \box_if_vertical:NTF { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\box_if_empty:N, \box_if_empty:c}
+% \testfile*
+% Testing if a \meta{box} is empty/void.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \box_if_empty:N #1 { p , T , F , TF }
+ { \if_box_empty:N #1 \prg_return_true: \else: \prg_return_false: \fi: }
+\cs_generate_variant:Nn \box_if_empty_p:N { c }
+\cs_generate_variant:Nn \box_if_empty:NT { c }
+\cs_generate_variant:Nn \box_if_empty:NF { c }
+\cs_generate_variant:Nn \box_if_empty:NTF { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{The last box inserted}
+%
+% \begin{variable}{\l_last_box}
+% A different name for this read-only primitive.
+% \begin{macrocode}
+\cs_new_eq:NN \l_last_box \tex_lastbox:D
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\box_set_to_last:N, \box_set_to_last:c}
+% \begin{macro}{\box_gset_to_last:N, \box_gset_to_last:c}
+% \testfile*
+% Set a box to the previous box.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \box_set_to_last:N #1
+ { \tex_setbox:D #1 \l_last_box }
+\cs_new_protected_nopar:Npn \box_gset_to_last:N
+ { \pref_global:D \box_set_to_last:N }
+\cs_generate_variant:Nn \box_set_to_last:N { c }
+\cs_generate_variant:Nn \box_gset_to_last:N { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Constant boxes}
+%
+% \begin{variable}{\c_empty_box}
+% \begin{macrocode}
+%<*package>
+\cs_new_eq:NN \c_empty_box \voidb@x
+%</package>
+%<*initex>
+\box_new:N \c_empty_box
+%</initex>
+% \end{macrocode}
+% \end{variable}
+%
+% \subsection{Scratch boxes}
+%
+% \begin{variable}{\l_tmpa_box, \l_tmpb_box}
+% \begin{macrocode}
+%<*package>
+\cs_new_eq:NN \l_tmpa_box \@tempboxa
+%</package>
+%<*initex>
+\box_new:N \l_tmpa_box
+%</initex>
+\box_new:N \l_tmpb_box
+% \end{macrocode}
+% \end{variable}
+%
+% \subsection{Viewing box contents}
+%
+% \begin{macro}{\box_show:N,\box_show:c}
+% \testfile*
+% Show the contents of a box and write it into the log file.
+% \begin{macrocode}
+\cs_new_eq:NN \box_show:N \tex_showbox:D
+\cs_generate_variant:Nn \box_show:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Horizontal mode boxes}
+%
+% \begin{macro}{\hbox:n}
+% \testfile{m3box002.lvt}
+% Put a horizontal box directly into the input stream.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \hbox:n { \tex_hbox:D \scan_stop: }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\hbox_set:Nn,\hbox_set:cn}
+% \begin{macro}{\hbox_gset:Nn,\hbox_gset:cn}
+% \testfile*
+% \begin{macrocode}
+\cs_new_protected:Npn \hbox_set:Nn #1#2 { \tex_setbox:D #1 \tex_hbox:D {#2} }
+\cs_new_protected_nopar:Npn \hbox_gset:Nn { \pref_global:D \hbox_set:Nn }
+\cs_generate_variant:Nn \hbox_set:Nn { c }
+\cs_generate_variant:Nn \hbox_gset:Nn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\hbox_set_to_wd:Nnn,\hbox_set_to_wd:cnn}
+% \begin{macro}{\hbox_gset_to_wd:Nnn,\hbox_gset_to_wd:cnn}
+% \testfile*
+% Storing material in a horizontal box with a specified width.
+% \begin{macrocode}
+\cs_new_protected:Npn \hbox_set_to_wd:Nnn #1#2#3
+ { \tex_setbox:D #1 \tex_hbox:D to \dim_eval:w #2 \dim_eval_end: {#3} }
+\cs_new_protected_nopar:Npn \hbox_gset_to_wd:Nnn
+ { \pref_global:D \hbox_set_to_wd:Nnn }
+\cs_generate_variant:Nn \hbox_set_to_wd:Nnn { c }
+\cs_generate_variant:Nn \hbox_gset_to_wd:Nnn {cnn}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\hbox_set_inline_begin:N, \hbox_set_inline_begin:c}
+% \begin{macro}{\hbox_gset_inline_begin:N, \hbox_gset_inline_begin:c}
+% \begin{macro}{\hbox_set_inline_end:}
+% \begin{macro}{\hbox_gset_inline_end:}
+% \testfile*
+% Storing material in a horizontal box. This type is useful in
+% environment definitions.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \hbox_set_inline_begin:N #1
+ { \tex_setbox:D #1 \tex_hbox:D \c_group_begin_token }
+\cs_new_protected_nopar:Npn \hbox_gset_inline_begin:N
+ { \pref_global:D \hbox_set_inline_begin:N }
+\cs_generate_variant:Nn \hbox_set_inline_begin:N { c }
+\cs_generate_variant:Nn \hbox_gset_inline_begin:N { c }
+\cs_new_eq:NN \hbox_set_inline_end: \c_group_end_token
+\cs_new_eq:NN \hbox_gset_inline_end: \c_group_end_token
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\hbox_to_wd:nn}
+% \begin{macro}{\hbox_to_zero:n}
+% \testfile*
+% Put a horizontal box directly into the input stream.
+% \begin{macrocode}
+\cs_new_protected:Npn \hbox_to_wd:nn #1#2
+ { \tex_hbox:D to \dim_eval:w #1 \dim_eval_end: {#2} }
+\cs_new_protected:Npn \hbox_to_zero:n #1 { \tex_hbox:D to \c_zero_skip {#1} }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\hbox_overlap_left:n,}
+% \begin{macro}{\hbox_overlap_right:n}
+% Put a zero-sized box with the contents pushed against one side (which
+% makes it stick out on the other) directly into the input stream.
+% \begin{macrocode}
+\cs_new_protected:Npn \hbox_overlap_left:n #1
+ { \hbox_to_zero:n { \tex_hss:D #1 } }
+\cs_new_protected:Npn \hbox_overlap_right:n #1
+ { \hbox_to_zero:n { #1 \tex_hss:D } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\hbox_unpack:N, \hbox_unpack:c}
+% \begin{macro}{\hbox_unpack_clear:N, \hbox_unpack_clear:c}
+% \testfile*
+% Unpacking a box and if requested also clear it.
+% \begin{macrocode}
+\cs_new_eq:NN \hbox_unpack:N \tex_unhcopy:D
+\cs_new_eq:NN \hbox_unpack_clear:N \tex_unhbox:D
+\cs_generate_variant:Nn \hbox_unpack:N { c }
+\cs_generate_variant:Nn \hbox_unpack_clear:N { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Vertical mode boxes}
+%
+% \begin{macro}{\vbox:n}
+% \TestFiles{m3box003.lvt}
+% \begin{macro}{\vbox:n\vbox_top:n}
+% \TestFiles{m3box003.lvt}
+% Put a vertical box directly into the input stream.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \vbox:n { \tex_vbox:D \scan_stop: }
+\cs_new_protected_nopar:Npn \vbox_top:n { \tex_vtop:D \scan_stop: }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\vbox_to_ht:nn,\vbox_to_zero:n}
+% \begin{macro}{\vbox_to_ht:nn,\vbox_to_zero:n}
+% \testfile*
+% Put a vertical box directly into the input stream.
+% \begin{macrocode}
+\cs_new_protected:Npn \vbox_to_ht:nn #1#2
+ { \tex_vbox:D to \dim_eval:w #1 \dim_eval_end: {#2} }
+\cs_new_protected:Npn \vbox_to_zero:n #1 { \tex_vbox:D to \c_zero_dim {#1} }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\vbox_set:Nn, \vbox_set:cn}
+% \begin{macro}{\vbox_gset:Nn, \vbox_gset:cn}
+% \testfile*
+% Storing material in a vertical box with a natural height.
+% \begin{macrocode}
+\cs_new_protected:Npn \vbox_set:Nn #1#2 { \tex_setbox:D #1 \tex_vbox:D {#2} }
+\cs_new_protected_nopar:Npn \vbox_gset:Nn { \pref_global:D \vbox_set:Nn }
+\cs_generate_variant:Nn \vbox_set:Nn { c }
+\cs_generate_variant:Nn \vbox_gset:Nn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\vbox_set_top:Nn, \vbox_set_top:cn}
+% \begin{macro}{\vbox_gset_top:Nn, \vbox_gset_top:cn}
+% \testfile*
+% Storing material in a vertical box with a natural height and reference
+% point at the baseline of the first object in the box.
+% \begin{macrocode}
+\cs_new_protected:Npn \vbox_set_top:Nn #1#2
+ { \tex_setbox:D #1 \tex_vtop:D {#2} }
+\cs_new_protected_nopar:Npn \vbox_gset_top:Nn
+ { \pref_global:D \vbox_set_top:Nn }
+\cs_generate_variant:Nn \vbox_set_top:Nn { c }
+\cs_generate_variant:Nn \vbox_gset_top:Nn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\vbox_set_to_ht:Nnn,\vbox_set_to_ht:cnn}
+% \begin{macro}{\vbox_gset_to_ht:Nnn,\vbox_gset_to_ht:cnn}
+% \testfile*
+% Storing material in a vertical box with a specified height.
+% \begin{macrocode}
+\cs_new_protected:Npn \vbox_set_to_ht:Nnn #1#2#3
+ { \tex_setbox:D #1 \tex_vbox:D to \dim_eval:w #2 \dim_eval_end: {#3} }
+\cs_new_protected_nopar:Npn \vbox_gset_to_ht:Nnn
+ { \pref_global:D \vbox_set_to_ht:Nnn }
+\cs_generate_variant:Nn \vbox_set_to_ht:Nnn { c }
+\cs_generate_variant:Nn \vbox_gset_to_ht:Nnn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\vbox_set_inline_begin:N, \vbox_set_inline_begin:c}
+% \begin{macro}{\vbox_gset_inline_begin:N, \vbox_gset_inline_begin:c}
+% \begin{macro}{\vbox_set_inline_end:}
+% \begin{macro}{\vbox_gset_inline_end:}
+% \testfile*
+% Storing material in a vertical box. This type is useful in
+% environment definitions.
+% \begin{macrocode}
+\cs_new_nopar:Npn \vbox_set_inline_begin:N #1
+ { \tex_setbox:D #1 \tex_vbox:D \c_group_begin_token }
+\cs_new_protected_nopar:Npn \vbox_gset_inline_begin:N
+ { \pref_global:D \vbox_set_inline_begin:N }
+\cs_generate_variant:Nn \vbox_set_inline_begin:N { c }
+\cs_generate_variant:Nn \vbox_gset_inline_begin:N { c }
+\cs_new_eq:NN \vbox_set_inline_end: \c_group_end_token
+\cs_new_eq:NN \vbox_gset_inline_end: \c_group_end_token
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\vbox_unpack:N, \vbox_unpack:c}
+% \begin{macro}{\vbox_unpack_clear:N, \vbox_unpack_clear:c}
+% \testfile*
+% Unpacking a box and if requested also clear it.
+% \begin{macrocode}
+\cs_new_eq:NN \vbox_unpack:N \tex_unvcopy:D
+\cs_new_eq:NN \vbox_unpack_clear:N \tex_unvbox:D
+\cs_generate_variant:Nn \vbox_unpack:N { c }
+\cs_generate_variant:Nn \vbox_unpack_clear:N { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\vbox_set_split_to_ht:NNn}
+% \testfile*
+% Splitting a vertical box in two.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \vbox_set_split_to_ht:NNn #1#2#3
+ { \tex_setbox:D #1 \tex_vsplit:D #2 to \dim_eval:w #3 \dim_eval_end: }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</initex|package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx b/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx
new file mode 100644
index 00000000000..d031b15f552
--- /dev/null
+++ b/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx
@@ -0,0 +1,1437 @@
+% \iffalse meta-comment
+%
+%% File: l3clist.dtx Copyright (C) 2004-2011 Frank Mittelbach,
+%% 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 "expl3 bundle" (The Work in LPPL)
+%% and all files in that bundle must be distributed together.
+%%
+%% The released version of this bundle is available from CTAN.
+%%
+%% -----------------------------------------------------------------------
+%%
+%% The development version of the bundle can be found at
+%%
+%% http://www.latex-project.org/svnroot/experimental/trunk/
+%%
+%% for those people who are interested.
+%%
+%%%%%%%%%%%
+%% NOTE: %%
+%%%%%%%%%%%
+%%
+%% Snapshots taken from the repository represent work in progress and may
+%% not work or may contain conflicting material! We therefore ask
+%% people _not_ to put them into distributions, archives, etc. without
+%% prior consultation with the LaTeX3 Project.
+%%
+%% -----------------------------------------------------------------------
+%
+%<*driver|package>
+\RequirePackage{l3names}
+\GetIdInfo$Id: l3clist.dtx 2498 2011-07-09 17:51:47Z joseph $
+ {L3 Experimental comma separated lists}
+%</driver|package>
+%<*driver>
+\documentclass[full]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3clist} package\\ Comma separated lists^^A
+% \thanks{This file describes v\ExplFileVersion,
+% last revised \ExplFileDate.}^^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 \ExplFileDate}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% Comma lists contain ordered data where items can be added to the left
+% or right end of the sequence. This gives an ordered list which can
+% then be utilised with the \cs{clist_map_function:NN} function. Comma
+% Comma lists cannot contain empty items, thus
+% \begin{verbatim}
+% \clist_new:N \l_my_clist
+% \clist_put_right:Nn \l_my_clist { }
+% \clist_if_empty:NTF \l_my_clist { true } { false }
+% \end{verbatim}
+% will leave \texttt{true} in the input stream.
+%
+% \section{Creating and initialising comma lists}
+%
+% \begin{function}{\clist_new:N, \clist_new:c}
+% \begin{syntax}
+% \cs{clist_new:N} \meta{comma list}
+% \end{syntax}
+% Creates a new \meta{comma list} or raises an error if the name is
+% already taken. The declaration is global. The \meta{comma list} will
+% initially contain no items.
+% \end{function}
+%
+% \begin{function}{\clist_clear:N, \clist_clear:c}
+% \begin{syntax}
+% \cs{clist_clear:N} \meta{comma list}
+% \end{syntax}
+% Clears all items from the \meta{comma list} within the scope of
+% the current \TeX{} group.
+% \end{function}
+%
+% \begin{function}{\clist_gclear:N, \clist_gclear:c}
+% \begin{syntax}
+% \cs{clist_gclear:N} \meta{comma list}
+% \end{syntax}
+% Clears all entries from the \meta{comma list} globally.
+% \end{function}
+%
+% \begin{function}{\clist_clear_new:N, \clist_clear_new:c}
+% \begin{syntax}
+% \cs{clist_clear_new:N} \meta{comma list}
+% \end{syntax}
+% If the \meta{comma list} already exists, clears it within the scope
+% of the current \TeX{} group. If the \meta{comma list} is not defined,
+% it will be created (using \cs{clist_new:N}). Thus the comma list is
+% guaranteed to be available and clear within the current \TeX{}
+% group. The \meta{comma list} will exist globally, but the content
+% outside of the current \TeX{} group is not specified.
+% \end{function}
+%
+% \begin{function}{\clist_gclear_new:N, \clist_gclear_new:c}
+% \begin{syntax}
+% \cs{clist_gclear_new:N} \meta{comma list}
+% \end{syntax}
+% If the \meta{comma list} already exists, clears it globally. If the
+% \meta{comma list} is not defined, it will be created (using
+% \cs{clist_new:N}). Thus the comma list is guaranteed to be available
+% and globally clear.
+% \end{function}
+%
+% \begin{function}
+% {\clist_set_eq:NN, \clist_set_eq:cN, \clist_set_eq:Nc, \clist_set_eq:cc}
+% \begin{syntax}
+% \cs{clist_set_eq:NN} \meta{comma list1} \meta{comma list2}
+% \end{syntax}
+% Sets the content of \meta{comma list1} equal to that of
+% \meta{comma list2}. This assignment is restricted to the current
+% \TeX{} group level.
+% \end{function}
+%
+% \begin{function}
+% {
+% \clist_gset_eq:NN, \clist_gset_eq:cN,
+% \clist_gset_eq:Nc, \clist_gset_eq:cc
+% }
+% \begin{syntax}
+% \cs{clist_gset_eq:NN} \meta{comma list1} \meta{comma list2}
+% \end{syntax}
+% Sets the content of \meta{comma list1} equal to that of
+% \meta{comma list2}. This assignment is global and so is not
+% limited by the current \TeX{} group level.
+% \end{function}
+%
+% \begin{function}{\clist_concat:NNN, \clist_concat:ccc}
+% \begin{syntax}
+% \cs{clist_concat:NNN} \meta{comma list1} \meta{comma list2}
+% ~~\meta{comma list3}
+% \end{syntax}
+% Concatenates the content of \meta{comma list2} and \meta{comma list3}
+% together and saves the result in \meta{comma list1}. The items in
+% \meta{comma list2} will be placed at the left side of the new comma list.
+% This operation is local to the current \TeX{} group and will
+% remove any existing content in \meta{comma list1}.
+% \end{function}
+%
+% \begin{function}{\clist_gconcat:NNN, \clist_gconcat:ccc}
+% \begin{syntax}
+% \cs{clist_gconcat:NNN} \meta{comma list1} \meta{comma list2}
+% ~~\meta{comma list3}
+% \end{syntax}
+% Concatenates the content of \meta{comma list2} and \meta{comma list3}
+% together and saves the result in \meta{comma list1}. The items in
+% \meta{comma list2} will be placed at the left side of the new comma list.
+% This operation is global and will remove any existing content in
+% \meta{comma list1}.
+% \end{function}
+%
+% \section{Appending items to comma lists}
+%
+% \begin{function}{
+% \clist_put_left:Nn, \clist_put_left:NV,
+% \clist_put_left:No, \clist_put_left:Nx,
+% \clist_put_left:cn, \clist_put_left:cV,
+% \clist_put_left:co, \clist_put_left:cx
+% }
+% \begin{syntax}
+% \cs{clist_put_left:Nn} \meta{comma list} \Arg{item}
+% \end{syntax}
+% Appends the \meta{item} to the left of the \meta{comma list}.
+% The assignment is restricted to the current \TeX{} group.
+% \end{function}
+%
+% \begin{function}{
+% \clist_gput_left:Nn, \clist_gput_left:NV,
+% \clist_gput_left:No, \clist_gput_left:Nx,
+% \clist_gput_left:cn, \clist_gput_left:cV,
+% \clist_gput_left:co, \clist_gput_left:cx
+% }
+% \begin{syntax}
+% \cs{clist_gput_left:Nn} \meta{comma list} \Arg{item}
+% \end{syntax}
+% Appends the \meta{item} to the left of the \meta{comma list}.
+% The assignment is global.
+% \end{function}
+%
+% \begin{function}{
+% \clist_put_right:Nn, \clist_put_right:NV,
+% \clist_put_right:No, \clist_put_right:Nx,
+% \clist_put_right:cn, \clist_put_right:cV,
+% \clist_put_right:co, \clist_put_right:cx
+% }
+% \begin{syntax}
+% \cs{clist_put_right:Nn} \meta{comma list} \Arg{item}
+% \end{syntax}
+% Appends the \meta{item} to the right of the \meta{comma list}.
+% The assignment is restricted to the current \TeX{} group.
+% \end{function}
+%
+% \begin{function}{
+% \clist_gput_right:Nn, \clist_gput_right:NV,
+% \clist_gput_right:No, \clist_gput_right:Nx,
+% \clist_gput_right:cn, \clist_gput_right:cV,
+% \clist_gput_right:co, \clist_gput_right:cx
+% }
+% \begin{syntax}
+% \cs{clist_gput_right:Nn} \meta{comma list} \Arg{item}
+% \end{syntax}
+% Appends the \meta{item} to the right of the \meta{comma list}.
+% The assignment is global.
+% \end{function}
+%
+% \section{Comma lists as stacks}
+%
+% \begin{function}{\clist_get:NN, \clist_get:cN}
+% \begin{syntax}
+% \cs{clist_get:NN} \meta{comma list} \meta{token list variable}
+% \end{syntax}
+% Stores the left-most item from a \meta{comma list} in the
+% \meta{token list variable} without removing it from the
+% \meta{comma list}. The \meta{token list variable} is assigned locally.
+% \end{function}
+%
+% \begin{function}{\clist_get:NN, \clist_get:cN}
+% \begin{syntax}
+% \cs{clist_get:NN} \meta{comma list} \meta{token list variable}
+% \end{syntax}
+% Stores the right-most item from a \meta{comma list} in the
+% \meta{token list variable} without removing it from the
+% \meta{comma list}. The \meta{token list variable} is assigned locally.
+% \end{function}
+%
+% \begin{function}{\clist_pop:NN, \clist_pop:cN}
+% \begin{syntax}
+% \cs{clist_pop:NN} \meta{comma list} \meta{token list variable}
+% \end{syntax}
+% Pops the left-most item from a \meta{comma list} into the
+% \meta{token list variable}, \emph{i.e.}~removes the item from the
+% comma list and stores it in the \meta{token list variable}.
+% Both of the variables are assigned locally.
+% \end{function}
+%
+% \begin{function}{\clist_gpop:NN, \clist_gpop:cN}
+% \begin{syntax}
+% \cs{clist_gpop:NN} \meta{comma list} \meta{token list variable}
+% \end{syntax}
+% Pops the left-most item from a \meta{comma list} into the
+% \meta{token list variable}, \emph{i.e.}~removes the item from the
+% comma list and stores it in the \meta{token list variable}.
+% The \meta{comma list} is modified globally, while the assignment of
+% the \meta{token list variable} is local.
+% \end{function}
+%
+% \begin{function}
+% {
+% \clist_push:Nn, \clist_push:NV, \clist_push:No, \clist_push:Nx,
+% \clist_push:cn, \clist_push:cV, \clist_push:co, \clist_push:cx
+% }
+% \begin{syntax}
+% \cs{clist_push:Nn} \meta{sequence} \Arg{item}
+% \end{syntax}
+% Adds the \Arg{item} to the top of the \meta{comma list}.
+% The assignment is restricted to the current \TeX{} group.
+% \end{function}
+%
+% \begin{function}
+% {
+% \clist_gpush:Nn, \clist_gpush:NV, \clist_gpush:No, \clist_gpush:Nx,
+% \clist_gpush:cn, \clist_gpush:cV, \clist_gpush:co, \clist_gpush:cx
+% }
+% \begin{syntax}
+% \cs{clist_gpush:Nn} \meta{sequence} \Arg{item}
+% \end{syntax}
+% Pushes the \meta{item} onto the end of the top of the
+% \meta{comma list}. The assignment is global.
+% \end{function}
+%
+% \section{Using comma lists}
+%
+% \begin{function}[EXP]{\clist_use:N, \clist_use:c}
+% \begin{syntax}
+% \cs{clist_use:N} \meta{comma list}
+% \end{syntax}
+% Places the \meta{comma list} directly into the input stream, thus
+% treating it as a \meta{token list}.
+% \end{function}
+%
+% \section{Modifying comma lists}
+%
+% While comma lists are normally used as ordered lists, it may be
+% necessary to modify the content. The functions here may be used
+% to update comma lists, while retaining the order of the unaffected
+% entries.
+%
+% \begin{function}{\clist_remove_duplicates:N, \clist_remove_duplicates:c}
+% \begin{syntax}
+% \cs{clist_remove_duplicates:N} \meta{comma list}
+% \end{syntax}
+% Removes duplicate items from the \meta{comma list}, leaving the
+% left most copy of each item in the \meta{comma list}. The \meta{item}
+% comparison takes place on a token basis, as for \cs{tl_if_eq:nn(TF)}.
+% The removal is local to the current \TeX{} group.
+% \begin{texnote}
+% This function iterates through every item in the \meta{comma list} and
+% does a comparison with the \meta{items} already checked. It is therefore
+% relatively slow with large comma lists.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{\clist_gremove_duplicates:N, \clist_gremove_duplicates:c}
+% \begin{syntax}
+% \cs{clist_gremove_duplicates:N} \meta{comma list}
+% \end{syntax}
+% Removes duplicate items from the \meta{comma list}, leaving the
+% left most copy of each item in the \meta{comma list}. The \meta{item}
+% comparison takes place on a token basis, as for \cs{tl_if_eq:nn(TF)}.
+% The removal is applied globally.
+% \begin{texnote}
+% This function iterates through every item in the \meta{comma list} and
+% does a comparison with the \meta{items} already checked. It is therefore
+% relatively slow with large comma lists.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{\clist_remove_all:Nn, \clist_remove_all:cn}
+% \begin{syntax}
+% \cs{clist_remove_all:Nn} \meta{comma list} \Arg{item}
+% \end{syntax}
+% Removes every occurrence of \meta{item} from the \meta{comma list}.
+% The \meta{item} comparison takes place on a token basis, as for
+% \cs{tl_if_eq:nn(TF)}. The removal is local to the current \TeX{} group.
+% \end{function}
+%
+% \begin{function}{\clist_gremove_all:Nn, \clist_gremove_all:cn}
+% \begin{syntax}
+% \cs{clist_gremove_all:Nn} \meta{comma list} \Arg{item}
+% \end{syntax}
+% Removes each occurrence of \meta{item} from the \meta{comma list}.
+% The \meta{item} comparison takes place on a token basis, as for
+% \cs{tl_if_eq:nn(TF)}. The removal is applied globally.
+% \end{function}
+%
+% \begin{function}{\clist_trim_spaces:N, \clist_trim_spaces:c}
+% \begin{syntax}
+% \cs{clist_trim_spaces:N} \meta{comma list}
+% \end{syntax}
+% Removes leading and trailing spaces from each \meta{item} in the
+% \meta{comma list} within the current \TeX{} group. This space-removal
+% process takes place as described for \cs{tl_trim_spaces:n}.
+% \end{function}
+%
+% \begin{function}{\clist_gtrim_spaces:N, \clist_gtrim_spaces:c}
+% \begin{syntax}
+% \cs{clist_gtrim_spaces:N} \meta{comma list}
+% \end{syntax}
+% Removes leading and trailing spaces from each \meta{item} in the
+% \meta{comma list} globally. This space-removal
+% process takes place as described for \cs{tl_trim_spaces:n}.
+% \end{function}
+%
+% \begin{function}[EXP]{\clist_trim_spaces:n}
+% \begin{syntax}
+% \cs{clist_trim_spaces:N} \meta{comma list}
+% \end{syntax}
+% Removes leading and trailing spaces from each \meta{item} in the
+% \meta{comma list}, leaving the resulting modified list in the
+% input stream.
+% \end{function}
+%
+% \section{Comma list conditionals}
+%
+% \begin{function}[EXP,pTF]{\clist_if_empty:N, \clist_if_empty:c}
+% \begin{syntax}
+% \cs{clist_if_empty_p:N} \meta{comma list}
+% \cs{clist_if_empty:NTF} \meta{comma list}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{comma list} is empty (containing no items). The
+% branching versions then leave either \meta{true code} or
+% \meta{false code} in the input stream, as appropriate to the truth of
+% the test and the variant of the function chosen. The logical truth of
+% the test is left in the input stream by the predicate version.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]
+% {\clist_if_eq:NN, \clist_if_eq:Nc, \clist_if_eq:cN, \clist_if_eq:cc}
+% \begin{syntax}
+% \cs{clist_if_eq_p:NN} \Arg{clist1} \Arg{clist2}
+% \cs{clist_if_eq:NNTF} \Arg{clist1} \Arg{clist2} \Arg{true code}
+% ~~\Arg{false code}
+% \end{syntax}
+% Compares the content of two \meta{comma lists} and
+% is logically \texttt{true} if the two contain the same list of
+% entries in the same order. The branching versions then leave either
+% \meta{true code} or \meta{false code} in the input stream, as
+% appropriate to the truth of the test and the variant of the function
+% chosen. The logical truth of the test is left in the input stream by
+% the predicate version.
+% \end{function}
+%
+% \begin{function}[TF]{
+% \clist_if_in:Nn, \clist_if_in:NV, \clist_if_in:No,
+% \clist_if_in:cn, \clist_if_in:cV, \clist_if_in:co,
+% \clist_if_in:nn, \clist_if_in:nV, \clist_if_in:no
+% }
+% \begin{syntax}
+% \cs{clist_if_in:NnTF} \meta{comma list} \Arg{item}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{item} is present in the \meta{comma list}.
+% Either the \meta{true code} or \meta{false code} is left in the input
+% stream, as appropriate to the truth of the test and the variant of the
+% function
+% chosen.
+% \end{function}
+%
+% \section{Mapping to comma lists}
+%
+% \begin{function}[EXP]
+% {\clist_map_function:NN, \clist_map_function:cN, \clist_map_function:nN}
+% \begin{syntax}
+% \cs{clist_map_function:NN} \meta{comma list} \meta{function}
+% \end{syntax}
+% Applies \meta{function} to every \meta{item} stored in the
+% \meta{comma list}. The \meta{function} will receive one argument for
+% each iteration. The \meta{items} are returned from left to right.
+% The function \cs{clist_map_inline:Nn} is in general more efficient
+% than \cs{clist_map_function:NN}.
+% One mapping may be nested inside another.
+% \end{function}
+%
+% \begin{function}
+% {\clist_map_inline:Nn, \clist_map_inline:cn, \clist_map_inline:nn}
+% \begin{syntax}
+% \cs{clist_map_inline:Nn} \meta{comma list} \Arg{inline function}
+% \end{syntax}
+% Applies \meta{inline function} to every \meta{item} stored
+% within the \meta{comma list}. The \meta{inline function} should
+% consist of code which will receive the \meta{item} as |#1|.
+% One in line mapping can be nested inside another. The \meta{items}
+% are returned from left to right.
+% \end{function}
+%
+% \begin{function}
+% {\clist_map_variable:NNn, \clist_map_variable:cNn, \clist_map_variable:nNn}
+% \begin{syntax}
+% \cs{clist_map_variable:NNn} \meta{comma list}
+% ~~\meta{tl~var.} \Arg{function using tl~var.}
+% \end{syntax}
+% Stores each entry in the \meta{comma list} in turn in the
+% \meta{tl~var.}\ and applies the \meta{function using tl~var.}
+% The \meta{function} will usually consist of code making use of
+% the \meta{tl~var.}, but this is not enforced. One variable
+% mapping can be nested inside another. The \meta{items}
+% are returned from left to right.
+% \end{function}
+%
+% \begin{function}[EXP]{\clist_map_break:}
+% \begin{syntax}
+% \cs{clist_map_break:}
+% \end{syntax}
+% Used to terminate a \cs{clist_map_\ldots} function before all
+% entries in the \meta{comma list} have been processed. This will
+% normally take place within a conditional statement, for example
+% \begin{verbatim}
+% \clist_map_inline:Nn \l_my_clist
+% {
+% \str_if_eq:nnTF { #1 } { bingo }
+% { \clist_map_break: }
+% {
+% % Do something useful
+% }
+% }
+% \end{verbatim}
+% Use outside of a \cs{clist_map_\ldots} scenario will lead to low
+% level \TeX{} errors.
+% \begin{texnote}
+% When the mapping is broken, additional tokens may be inserted by the
+% internal macro \cs{clist_break_point:n} before further items are taken
+% from the input stream. This will depend on the design of the mapping
+% function.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[EXP]{\clist_map_break:n}
+% \begin{syntax}
+% \cs{clist_map_break:n} \Arg{tokens}
+% \end{syntax}
+% Used to terminate a \cs{clist_map_\ldots} function before all
+% entries in the \meta{comma list} have been processed, inserting
+% the \meta{tokens} after the mapping has ended. This will
+% normally take place within a conditional statement, for example
+% \begin{verbatim}
+% \clist_map_inline:Nn \l_my_clist
+% {
+% \str_if_eq:nnTF { #1 } { bingo }
+% { \clist_map_break:n { <tokens> } }
+% {
+% % Do something useful
+% }
+% }
+% \end{verbatim}
+% Use outside of a \cs{clist_map_\ldots} scenario will lead to low
+% level \TeX{} errors.
+% \begin{texnote}
+% When the mapping is broken, additional tokens may be inserted by the
+% internal macro \cs{clist_break_point:n} before the \meta{tokens} are
+% inserted into the input stream.
+% This will depend on the design of the mapping function.
+% \end{texnote}
+% \end{function}
+%
+% \section{Comma lists as stacks}
+%
+% Comma lists can be used as stacks, where data is pushed to and popped
+% from the top of the comma list. (The left of a comma list is the top, for
+% performance reasons.) The stack functions for comma lists are not
+% intended to be mixed with the general ordered data functions detailed
+% in the previous section: a comma list should either be used as an
+% ordered data type or as a stack, but not in both ways.
+%
+% \begin{function}{\clist_get:NN, \clist_get:cN}
+% \begin{syntax}
+% \cs{clist_get:NN} \meta{comma list} \meta{token list variable}
+% \end{syntax}
+% Reads the top item from a \meta{comma list} into the
+% \meta{token list variable} without removing it from the
+% \meta{comma list}. The \meta{token list variable} is assigned locally.
+% If \meta{comma list} is empty an error will be raised.
+% \end{function}
+%
+% \begin{function}{\clist_pop:NN, \clist_pop:cN}
+% \begin{syntax}
+% \cs{clist_pop:NN} \meta{comma list} \meta{token list variable}
+% \end{syntax}
+% Pops the top item from a \meta{comma list} into the
+% \meta{token list variable}. Both of the variables are assigned
+% locally. If \meta{comma list} is empty an error will be raised.
+% \end{function}
+%
+% \begin{function}{\clist_gpop:NN, \clist_gpop:cN}
+% \begin{syntax}
+% \cs{clist_gpop:NN} \meta{comma list} \meta{token list variable}
+% \end{syntax}
+% Pops the top item from a \meta{comma list} into the
+% \meta{token list variable}. The \meta{comma list} is modified globally,
+% while the \meta{token list variable} is assigned locally. If
+% \meta{comma list} is empty an error will be raised.
+% \end{function}
+%
+% \begin{function}{
+% \clist_push:Nn, \clist_push:NV, \clist_push:No, \clist_push:Nx,
+% \clist_push:cn, \clist_push:cV, \clist_push:co, \clist_push:cx
+% }
+% \begin{syntax}
+% \cs{clist_push:Nn} \meta{comma list} \Arg{item}
+% \end{syntax}
+% Adds the \Arg{item} to the top of the \meta{comma list}.
+% The assignment is restricted to the current \TeX{} group.
+% \end{function}
+%
+% \begin{function}{
+% \clist_gpush:Nn, \clist_gpush:NV, \clist_gpush:No, \clist_gpush:Nx,
+% \clist_gpush:cn, \clist_gpush:cV, \clist_gpush:co, \clist_gpush:cx
+% }
+% \begin{syntax}
+% \cs{clist_gpush:Nn} \meta{comma list} \Arg{item}
+% \end{syntax}
+% Pushes the \meta{item} onto the end of the top of the
+% \meta{comma list}. The assignment is global.
+% \end{function}
+%
+% \section{Viewing comma lists}
+%
+% \begin{function}{\clist_show:N, \clist_show:c}
+% \begin{syntax}
+% \cs{clist_show:N} \meta{comma list}
+% \end{syntax}
+% Displays the entries in the \meta{comma list} in the terminal.
+% \end{function}
+%
+% \section{Experimental comma list functions}
+%
+% This section contains functions which may or may not be retained, depending
+% on how useful they are found to be.
+%
+% \begin{function}[EXP]{\clist_length:N, \clist_length:c,\clist_length:n}
+% \begin{syntax}
+% \cs{clist_length:N} \meta{comma list}
+% \end{syntax}
+% Leaves the number of items in the \meta{comma list} in the input
+% stream as an \meta{integer denotation}. The total number of items
+% in a \meta{comma list} will include those which are empty and duplicates,
+% \emph{i.e.}~every item in a \meta{comma list} is unique.
+% \end{function}
+%
+% \begin{function}[EXP]{\clist_item:Nn, \clist_item:cn, \clist_item:nn}
+% \begin{syntax}
+% \cs{clist_item:Nn} \meta{comma list} \Arg{integer expression}
+% \end{syntax}
+% Indexing items in the \meta{comma list} from $0$ at the top (left), this
+% function will evaluate the \meta{integer expression} and leave the
+% appropriate item from the comma list in the input stream. If the
+% \meta{integer expression} is negative, indexing occurs from the
+% bottom (right) of the comma list. When the \meta{integer expression}
+% is larger than the number of items in the \meta{comma list} (as
+% calculated by \cs{clist_length:N}) then the function will expand to
+% nothing.
+% \end{function}
+%
+% \begin{function}
+% {
+% \clist_set_from_seq:NN, \clist_set_from_seq:cN,
+% \clist_set_from_seq:Nc, \clist_set_from_seq:cc
+% }
+% \begin{syntax}
+% \cs{clist_set_from_seq:NN} \meta{comma list} \meta{sequence}
+% \end{syntax}
+% Sets the \meta{comma list} within the current \TeX{} group to be equal
+% to the content of the \meta{sequence}.
+% \end{function}
+%
+% \begin{function}
+% {
+% \clist_gset_from_seq:NN, \clist_gset_from_seq:cN,
+% \clist_gset_from_seq:Nc, \clist_gset_from_seq:cc
+% }
+% \begin{syntax}
+% \cs{clist_gset_from_seq:NN} \meta{comma list} \meta{sequence}
+% \end{syntax}
+% Sets the \meta{comma list} globally to equal to the content of the
+% \meta{sequence}.
+% \end{function}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3clist} implementation}
+%
+% \TestFiles{m3clist002}
+%
+% \begin{macrocode}
+%<*initex|package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*package>
+\ProvidesExplPackage
+ {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
+\package_check_loaded_expl:
+%</package>
+% \end{macrocode}
+%
+% \begin{variable}{\l_clist_tmpa_tl, \l_clist_tmpb_tl}
+% Scratch space for various internal uses.
+% \begin{macrocode}
+\tl_new:N \l_clist_tmpa_tl
+\tl_new:N \l_clist_tmpb_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \subsection{Allocation and initialisation}
+%
+% \begin{macro}{\clist_new:N,\clist_new:c}
+% \UnitTested
+% Internally, comma lists are just token lists.
+% \begin{macrocode}
+\cs_new_eq:NN \clist_new:N \tl_new:N
+\cs_new_eq:NN \clist_new:c \tl_new:c
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\clist_clear:N, \clist_clear:c}
+% \UnitTested
+% \begin{macro}{\clist_gclear:N, \clist_gclear:c}
+% \UnitTested
+% Clearing comma lists is just the same as clearing token lists.
+% \begin{macrocode}
+\cs_new_eq:NN \clist_clear:N \tl_clear:N
+\cs_new_eq:NN \clist_clear:c \tl_clear:c
+\cs_new_eq:NN \clist_gclear:N \tl_gclear:N
+\cs_new_eq:NN \clist_gclear:c \tl_gclear:c
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\clist_clear_new:N, \clist_clear_new:c}
+% \UnitTested
+% \begin{macro}{\clist_gclear_new:N, \clist_gclear_new:c}
+% \UnitTested
+% Once again a copy from the token list functions.
+% \begin{macrocode}
+\cs_new_eq:NN \clist_clear_new:N \tl_clear_new:N
+\cs_new_eq:NN \clist_clear_new:c \tl_clear_new:c
+\cs_new_eq:NN \clist_gclear_new:N \tl_gclear_new:N
+\cs_new_eq:NN \clist_gclear_new:c \tl_gclear_new:c
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {\clist_set_eq:NN, \clist_set_eq:cN, \clist_set_eq:Nc, \clist_set_eq:cc}
+% \UnitTested
+% \begin{macro}
+% {
+% \clist_gset_eq:NN, \clist_gset_eq:cN,
+% \clist_gset_eq:Nc, \clist_gset_eq:cc
+% }
+% \UnitTested
+% Once again, these are simple copies from the token list functions.
+% \begin{macrocode}
+\cs_new_eq:NN \clist_set_eq:NN \tl_set_eq:NN
+\cs_new_eq:NN \clist_set_eq:Nc \tl_set_eq:Nc
+\cs_new_eq:NN \clist_set_eq:cN \tl_set_eq:cN
+\cs_new_eq:NN \clist_set_eq:cc \tl_set_eq:cc
+\cs_new_eq:NN \clist_gset_eq:NN \tl_gset_eq:NN
+\cs_new_eq:NN \clist_gset_eq:Nc \tl_gset_eq:Nc
+\cs_new_eq:NN \clist_gset_eq:cN \tl_gset_eq:cN
+\cs_new_eq:NN \clist_gset_eq:cc \tl_gset_eq:cc
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\clist_concat:NNN, \clist_concat:ccc}
+% \UnitTested
+% \begin{macro}{\clist_gconcat:NNN, \clist_gconcat:ccc}
+% \UnitTested
+% \begin{macro}[aux]{\clist_concat_aux:NNNN}
+% Concatenating sequences is not quite as easy as it seems, as there is
+% the danger that |#1| may be the same as either |#2| or |#3|. Also,
+% there needs to be the correct addition of a comma to the output. So
+% a little work to do.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \clist_concat:NNN
+ { \clist_concat_aux:NNNN \tl_set:Nx }
+\cs_new_protected_nopar:Npn \clist_gconcat:NNN
+ { \clist_concat_aux:NNNN \tl_gset:Nx }
+\cs_new_protected_nopar:Npn \clist_concat_aux:NNNN #1#2#3#4
+ {
+ #1 #2
+ {
+ \clist_if_empty:NTF #3
+ { \exp_not:o #4 }
+ {
+ \exp_not:o #3
+ \clist_if_empty:NF #4
+ {
+ ,
+ \exp_not:o #4
+ }
+ }
+ }
+ }
+\cs_generate_variant:Nn \clist_concat:NNN { ccc }
+\cs_generate_variant:Nn \clist_gconcat:NNN { ccc }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Appending items to comma lists}
+%
+% \begin{macro}
+% {
+% \clist_put_left:Nn, \clist_put_left:NV,
+% \clist_put_left:No, \clist_put_left:Nx,
+% \clist_put_left:cn, \clist_put_left:cV,
+% \clist_put_left:co, \clist_put_left:cx
+% }
+% \UnitTested
+% \begin{macro}
+% {
+% \clist_gput_left:Nn, \clist_gput_left:NV,
+% \clist_gput_left:No, \clist_gput_left:Nx,
+% \clist_gput_left:cn, \clist_gput_left:cV,
+% \clist_gput_left:co, \clist_gput_left:cx
+% }
+% \UnitTested
+% Comma lists cannot hold empty values: there are therefore a couple
+% of sanity checks to avoid accumulating commas.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \clist_put_left:Nn
+ { \clist_put_aux:NNnnNn \tl_set:Nn \tl_put_left:Nn { } , }
+\cs_new_protected_nopar:Npn \clist_gput_left:Nn
+ { \clist_put_aux:NNnnNn \tl_gset:Nn \tl_gput_left:Nn { } , }
+\cs_new_protected:Npn \clist_put_aux:NNnnNn #1#2#3#4#5#6
+ {
+ \clist_if_empty:NTF #5
+ { #1 #5 {#6} }
+ { \tl_if_empty:nF {#6} { #2 #5 { #3 #6 #4 } } }
+ }
+\cs_generate_variant:Nn \clist_put_left:Nn { NV , No , Nx }
+\cs_generate_variant:Nn \clist_put_left:Nn { c , cV , co , cx }
+\cs_generate_variant:Nn \clist_gput_left:Nn { NV , No , Nx }
+\cs_generate_variant:Nn \clist_gput_left:Nn { c , cV , co , cx }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \clist_put_right:Nn, \clist_put_right:NV,
+% \clist_put_right:No, \clist_put_right:Nx,
+% \clist_put_right:cn, \clist_put_right:cV,
+% \clist_put_right:co, \clist_put_right:cx
+% }
+% \begin{macro}
+% {
+% \clist_gput_right:Nn, \clist_gput_right:NV,
+% \clist_gput_right:No, \clist_gput_right:Nx,
+% \clist_gput_right:cn, \clist_gput_right:cV,
+% \clist_gput_right:co, \clist_gput_right:cx
+% }
+% The same for the right side.
+% \begin{macrocode}
+\cs_new_protected:Npn \clist_put_right:Nn
+ { \clist_put_aux:NNnnNn \tl_set:Nn \tl_put_right:Nn , { } }
+\cs_new_protected_nopar:Npn \clist_gput_right:Nn
+ { \clist_put_aux:NNnnNn \tl_gset:Nn \tl_gput_right:Nn , { } }
+\cs_generate_variant:Nn \clist_put_right:Nn { NV , No , Nx }
+\cs_generate_variant:Nn \clist_put_right:Nn { c , cV , co , cx }
+\cs_generate_variant:Nn \clist_gput_right:Nn { NV , No , Nx }
+\cs_generate_variant:Nn \clist_gput_right:Nn { c , cV , co , cx }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Comma lists as stacks}
+%
+% \begin{macro}{\clist_get:NN, \clist_get:cN}
+% \UnitTested
+% \begin{macro}[aux]{\clist_get_aux:wN}
+% Getting an item from the left of a comma list is pretty easy: just
+% trim off the first item using the comma.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \clist_get:NN #1#2
+ { \exp_after:wN \clist_get_aux:wN #1 , \q_stop #2 }
+\cs_new_protected:Npn \clist_get_aux:wN #1 , #2 \q_stop #3
+ { \tl_set:Nn #3 {#1} }
+\cs_generate_variant:Nn \clist_get:NN { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\clist_pop:NN, \clist_pop:cN}
+% \UnitTested
+% \begin{macro}{\clist_gpop:NN, \clist_gpop:cN}
+% \UnitTested
+% \begin{macro}[aux]{\clist_pop_aux:NNN}
+% \begin{macro}[aux]{\clist_pop_aux:wNNN}
+% The aim here is to get the popped item as |#1| in the auxiliary, with
+% |#2| containing either the remainder of the list \emph{or} \cs{q_nil}
+% if there were insufficient items. That keeps the number of auxiliary
+% functions down.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \clist_pop:NN
+ { \clist_pop_aux:NNN \tl_set:Nn }
+\cs_new_protected_nopar:Npn \clist_gpop:NN
+ { \clist_pop_aux:NNN \tl_gset:Nn }
+\cs_new_protected_nopar:Npn \clist_pop_aux:NNN #1#2#3
+ { \exp_after:wN \clist_pop_aux:wNNN #2 , \q_nil , \q_nil , \q_stop #1#2#3 }
+\cs_new_protected:Npn \clist_pop_aux:wNNN #1 , #2 , \q_nil , #3 \q_stop #4#5#6
+ {
+ \quark_if_nil:nTF {#2}
+ { #4 #5 { } }
+ { #4 #5 {#2} }
+ \tl_set:Nn #6 {#1}
+ }
+\cs_generate_variant:Nn \clist_pop:NN { c }
+\cs_generate_variant:Nn \clist_gpop:NN { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{
+% \clist_push:Nn, \clist_push:NV, \clist_push:No, \clist_push:Nx,
+% \clist_push:cn, \clist_push:cV, \clist_push:co, \clist_push:cx
+% }
+% \UnitTested
+% \begin{macro}{
+% \clist_gpush:Nn, \clist_gpush:NV, \clist_gpush:No, \clist_gpush:Nx,
+% \clist_gpush:cn, \clist_gpush:cV, \clist_gpush:co, \clist_gpush:cx
+% }
+% \UnitTested
+% Pushing to a sequence is the same as adding on the left.
+% \begin{macrocode}
+\cs_new_eq:NN \clist_push:Nn \clist_put_left:Nn
+\cs_new_eq:NN \clist_push:NV \clist_put_left:NV
+\cs_new_eq:NN \clist_push:No \clist_put_left:No
+\cs_new_eq:NN \clist_push:Nx \clist_put_left:Nx
+\cs_new_eq:NN \clist_push:cn \clist_put_left:cn
+\cs_new_eq:NN \clist_push:cV \clist_put_left:cV
+\cs_new_eq:NN \clist_push:co \clist_put_left:co
+\cs_new_eq:NN \clist_push:cx \clist_put_left:cx
+\cs_new_eq:NN \clist_gpush:Nn \clist_gput_left:Nn
+\cs_new_eq:NN \clist_gpush:NV \clist_gput_left:NV
+\cs_new_eq:NN \clist_gpush:No \clist_gput_left:No
+\cs_new_eq:NN \clist_gpush:Nx \clist_gput_left:Nx
+\cs_new_eq:NN \clist_gpush:cn \clist_gput_left:cn
+\cs_new_eq:NN \clist_gpush:cV \clist_gput_left:cV
+\cs_new_eq:NN \clist_gpush:co \clist_gput_left:co
+\cs_new_eq:NN \clist_gpush:cx \clist_gput_left:cx
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Using comma lists}
+%
+% \begin{macro}{\clist_use:N, \clist_use:c}
+% \UnitTested
+% The approach is the same as for \cs{tl_use:N}.
+% \begin{macrocode}
+\cs_new_eq:NN \clist_use:N \tl_use:N
+\cs_new_eq:NN \clist_use:c \tl_use:c
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Modifying comma lists}
+%
+% \begin{variable}{\l_clist_remove_clist}
+% An internal comma list for the removal routines.
+% \begin{macrocode}
+\clist_new:N \l_clist_remove_clist
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\clist_remove_duplicates:N, \clist_remove_duplicates:c}
+% \UnitTested
+% \begin{macro}{\clist_gremove_duplicates:N, \clist_gremove_duplicates:c}
+% \UnitTested
+% \begin{macro}[aux]{\clist_remove_duplicates_aux:NN}
+% Removing duplicates means making a new list then copying it.
+% \begin{macrocode}
+\cs_new_protected:Npn \clist_remove_duplicates:N
+ { \clist_remove_duplicates_aux:NN \clist_set_eq:NN }
+\cs_new_protected:Npn \clist_gremove_duplicates:N
+ { \clist_remove_duplicates_aux:NN \clist_gset_eq:NN }
+\cs_new_protected:Npn \clist_remove_duplicates_aux:NN #1#2
+ {
+ \clist_clear:N \l_clist_remove_clist
+ \clist_map_inline:Nn #2
+ {
+ \clist_if_in:NnF \l_clist_remove_clist {##1}
+ { \clist_put_right:Nn \l_clist_remove_clist {##1} }
+ }
+ #1 #2 \l_clist_remove_clist
+ }
+\cs_generate_variant:Nn \clist_remove_duplicates:N { c }
+\cs_generate_variant:Nn \clist_gremove_duplicates:N { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\clist_remove_all:Nn, \clist_remove_all:cn}
+% \UnitTested
+% \begin{macro}{\clist_gremove_all:Nn, \clist_gremove_all:cn}
+% \UnitTested
+% \begin{macro}[aux]{\clist_remove_all_aux:NNn}
+% \begin{macro}[aux]{\clist_remove_all_aux:w}
+% Removing an item from a comma list is done without looping over
+% the entire list, as the performance of that approach is very bad for
+% long lists. Instead, a delimited function is needed. For this to work
+% correctly, there is a need to add an additional comma at the start of
+% the list, and to remove it again once the removal is complete. Of
+% course, the list can end up empty, which is the reason for the test
+% before copying back to the parent.
+% \begin{macrocode}
+\cs_new_protected:Npn \clist_remove_all:Nn
+ { \clist_remove_all_aux:NNn \clist_set_eq:NN }
+\cs_new_protected:Npn \clist_gremove_all:Nn
+ { \clist_remove_all_aux:NNn \clist_gset_eq:NN }
+\cs_new_protected:Npn \clist_remove_all_aux:NNn #1#2#3
+ {
+ \clist_if_empty:NF #2
+ {
+ \clist_clear:N \l_clist_remove_clist
+ \cs_set_protected:Npn \clist_remove_all_aux:w
+ ##1 , #3 , ##2 \q_stop
+ {
+ \tl_put_right:Nn \l_clist_remove_clist {##1}
+ \quark_if_no_value:nF {##2}
+ { \clist_remove_all_aux:w , ##2 \q_stop }
+ }
+ \exp_after:wN \clist_remove_all_aux:w
+ \exp_after:wN , #2 , #3 , \q_no_value \q_stop
+ \tl_if_empty:NF \l_clist_remove_clist
+ {
+ \exp_after:wN \tl_set:No \exp_after:wN
+ \l_clist_remove_clist \exp_after:wN
+ { \exp_after:wN \use_none:n \l_clist_remove_clist }
+ }
+ #1 #2 \l_clist_remove_clist
+ }
+ }
+\cs_new_protected:Npn \clist_remove_all_aux:w { }
+\cs_generate_variant:Nn \clist_remove_all:Nn { c }
+\cs_generate_variant:Nn \clist_gremove_all:Nn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\clist_trim_spaces:n}
+% \begin{macro}
+% {
+% \clist_trim_spaces:N, \clist_trim_spaces:c,
+% \clist_gtrim_spaces:N, \clist_gtrim_spaces:c
+% }
+% \begin{macro}{\clist_trim_spaces_aux_i:n}
+% \begin{macro}{\clist_trim_spaces_aux_ii:n}
+% Here, the basic plan is to use \cs{tl_trim_spaces:n} to do the work:
+% the only issue is to make sure that the number of commas at the end of
+% the process is correct.
+% \begin{macrocode}
+\cs_new:Npn \clist_trim_spaces:n #1
+ {
+ \exp_args:Nf \clist_trim_spaces_aux_i:n
+ { \clist_map_function:nN {#1} \clist_trim_spaces_aux_ii:n }
+ }
+\cs_new:Npn \clist_trim_spaces_aux_i:n #1 { \use_ii:nn #1 }
+\cs_new:Npn \clist_trim_spaces_aux_ii:n #1
+ { , \tl_trim_spaces:n {#1} }
+\cs_new_protected:Npn \clist_trim_spaces:N #1
+ { \tl_set:Nf #1 { \exp_args:No \clist_trim_spaces:n #1 } }
+\cs_new_protected:Npn \clist_gtrim_spaces:N #1
+ { \tl_gset:Nf #1 { \exp_args:No \clist_trim_spaces:n #1 } }
+\cs_generate_variant:Nn \clist_trim_spaces:N { c }
+\cs_generate_variant:Nn \clist_gtrim_spaces:N { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Comma list conditionals}
+%
+% \begin{macro}[aux]{\clist_tmp:w}
+% A temporary function for comparison.
+% \begin{macrocode}
+\cs_new_protected:Npn \clist_tmp:w { }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\clist_if_empty:N, \clist_if_empty:c}
+% \UnitTested
+% Simple copies from the token list variable material.
+% \begin{macrocode}
+\prg_new_eq_conditional:NNn \clist_if_empty:N \tl_if_empty:N { p , T , F , TF }
+\prg_new_eq_conditional:NNn \clist_if_empty:c \tl_if_empty:c { p , T , F , TF }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]
+% {\clist_if_eq:NN, \clist_if_eq:Nc, \clist_if_eq:cN, \clist_if_eq:cc}
+% \UnitTested
+% Simple copies from the token list variable material.
+% \begin{macrocode}
+\prg_new_eq_conditional:NNn \clist_if_eq:NN \tl_if_eq:NN { p , T , F , TF }
+\prg_new_eq_conditional:NNn \clist_if_eq:Nc \tl_if_eq:Nc { p , T , F , TF }
+\prg_new_eq_conditional:NNn \clist_if_eq:cN \tl_if_eq:cN { p , T , F , TF }
+\prg_new_eq_conditional:NNn \clist_if_eq:cc \tl_if_eq:cc { p , T , F , TF }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[TF]
+% {
+% \clist_if_in:Nn, \clist_if_in:NV, \clist_if_in:No,
+% \clist_if_in:cn, \clist_if_in:cV, \clist_if_in:co
+% }
+% \UnitTested
+% \begin{macrocode}
+\prg_new_protected_conditional:Npnn \clist_if_in:Nn #1#2
+ { T , F , TF }
+ {
+ \cs_set_protected:Npn \clist_tmp:w ##1 , #2 , ##2##3 \q_stop
+ {
+ \if_meaning:w \q_no_value ##2
+ \prg_return_false:
+ \else:
+ \prg_return_true:
+ \fi:
+ }
+ \exp_last_unbraced:NNo \clist_tmp:w , #1 , #2 , \q_no_value \q_stop
+ }
+\prg_new_protected_conditional:Npnn \clist_if_in:nn #1#2
+ { T , F , TF }
+ {
+ \cs_set_protected:Npn \clist_tmp:w ##1 , #2 , ##2##3 \q_stop
+ {
+ \if_meaning:w \q_no_value ##2
+ \prg_return_false:
+ \else:
+ \prg_return_true:
+ \fi:
+ }
+ \clist_tmp:w , #1 , #2 , \q_no_value \q_stop
+ }
+\cs_generate_variant:Nn \clist_if_in:NnT { NV , No }
+\cs_generate_variant:Nn \clist_if_in:NnT { c , cV , co }
+\cs_generate_variant:Nn \clist_if_in:NnF { NV , No }
+\cs_generate_variant:Nn \clist_if_in:NnF { c , cV , co }
+\cs_generate_variant:Nn \clist_if_in:NnTF { NV , No }
+\cs_generate_variant:Nn \clist_if_in:NnTF { c , cV , co }
+\cs_generate_variant:Nn \clist_if_in:nnT { nV , no }
+\cs_generate_variant:Nn \clist_if_in:nnF { nV , no }
+\cs_generate_variant:Nn \clist_if_in:nnTF { nV , no }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Mapping to comma lists}
+%
+% \begin{macro}{\clist_map_function:NN, \clist_map_function:cN}
+% \UnitTested
+% \begin{macro}{\clist_map_function:nN}
+% \UnitTested
+% \begin{macro}[aux]{\clist_map_function_aux:Nw}
+% Mapping to comma lists is pretty simple, if not massively efficient.
+% \begin{macrocode}
+\cs_new_nopar:Npn \clist_map_function:NN #1#2
+ {
+ \clist_if_empty:NF #1
+ {
+ \exp_last_unbraced:NNo \clist_map_function_aux:Nw #2 #1
+ , \q_recursion_tail , \q_recursion_stop
+ }
+ }
+\cs_new:Npn \clist_map_function:nN #1#2
+ {
+ \tl_if_empty:nF {#1}
+ {
+ \clist_map_function_aux:Nw #2 #1
+ , \q_recursion_tail , \q_recursion_stop
+ }
+ }
+\cs_new:Npn \clist_map_function_aux:Nw #1#2 ,
+ {
+ \quark_if_recursion_tail_stop:n {#2}
+ #1 {#2}
+ \clist_map_function_aux:Nw #1
+ }
+\cs_generate_variant:Nn \clist_map_function:NN { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{variable}{\g_clist_map_inline_int}
+% For the nesting of mappings.
+% \begin{macrocode}
+\int_new:N \g_clist_map_inline_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\clist_map_inline:Nn, \clist_map_inline:cn}
+% \UnitTested
+% \begin{macro}{\clist_map_inline:nn}
+% \UnitTested
+% Inline mapping is done by creating a suitable function
+% \enquote{on the fly}:
+% this is done globally to avoid any issues with \TeX{}'s groups.
+% \begin{macrocode}
+\cs_new_protected:Npn \clist_map_inline:Nn #1#2
+ {
+ \int_gincr:N \g_clist_map_inline_int
+ \cs_gset:cpn { clist_map_inline_ \int_use:N \g_clist_map_inline_int :n }
+ ##1
+ {#2}
+ \exp_args:NNc \clist_map_function:NN #1
+ { clist_map_inline_ \int_use:N \g_clist_map_inline_int :n }
+ \int_gdecr:N \g_clist_map_inline_int
+ }
+\cs_new_protected:Npn \clist_map_inline:nn #1#2
+ {
+ \int_gincr:N \g_clist_map_inline_int
+ \cs_gset:cpn { clist_map_inline_ \int_use:N \g_clist_map_inline_int :n }
+ ##1
+ {#2}
+ \exp_args:Nnc \clist_map_function:nN {#1}
+ { clist_map_inline_ \int_use:N \g_clist_map_inline_int :n }
+ \int_gdecr:N \g_clist_map_inline_int
+ }
+\cs_generate_variant:Nn \clist_map_inline:Nn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\clist_map_variable:NNn, \clist_map_variable:cNn}
+% \UnitTested
+% This is just a dedicated version of the inline mapping.
+% \begin{macrocode}
+\cs_new_protected:Npn \clist_map_variable:NNn #1#2#3
+ {
+ \clist_map_inline:Nn #1
+ {
+ \tl_set:Nn #2 {##1}
+ #3
+ }
+ }
+\cs_new_protected:Npn \clist_map_variable:nNn #1#2#3
+ {
+ \clist_map_inline:nn {#1}
+ {
+ \tl_set:Nn #2 {##1}
+ #3
+ }
+ }
+\cs_generate_variant:Nn \clist_map_variable:NNn { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\clist_map_break:}
+% \UnitTested
+% \begin{macro}{\clist_map_break:n}
+% Both are simple renaming.
+% \begin{macrocode}
+\cs_new_eq:NN \clist_map_break: \use_none_delimit_by_q_recursion_stop:w
+\cs_new_eq:NN \clist_map_break:n \use_i_delimit_by_q_recursion_stop:nw
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \section{Viewing comma lists}
+%
+% \begin{macro}{\clist_show:N, \clist_show:c}
+% \UnitTested
+% \begin{macro}[aux]{\clist_show_aux:n}
+% \begin{macro}[aux]{\clist_show_aux:w}
+% The aim of the mapping here is to create a token list containing the
+% formatted comma list. The very first item needs the new line and \verb*|> |
+% removing, which is achieved using a \texttt{w}-type auxiliary. To avoid
+% a low-level \TeX{} error if there is an empty comma list, a simple test is
+% used to keep the output \enquote{clean}.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \clist_show:N #1
+ {
+ \clist_if_empty:NTF #1
+ {
+ \iow_term:x { Comma~list~\token_to_str:N #1 \c_space_tl is~empty }
+ \tl_show:n { }
+ }
+ {
+ \iow_term:x
+ {
+ Comma~list~\token_to_str:N #1 \c_space_tl
+ contains~the~items~(without~outer~braces):
+ }
+ \tl_set:Nx \l_clist_show_tl
+ { \clist_map_function:NN #1 \clist_show_aux:n }
+ \etex_showtokens:D \exp_after:wN \exp_after:wN \exp_after:wN
+ { \exp_after:wN \clist_show_aux:w \l_clist_show_tl }
+ }
+ }
+\cs_new:Npn \clist_show_aux:n #1
+ {
+ \iow_newline: > \c_space_tl \c_space_tl
+ \iow_char:N \{ \exp_not:n {#1} \iow_char:N \}
+ }
+\cs_new:Npn \clist_show_aux:w #1 > ~ { }
+\cs_generate_variant:Nn \clist_show:N { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Experimental functions}
+%
+% \begin{macro}{\clist_length:N, \clist_length:c}
+% \begin{macro}{\clist_length:n}
+% \begin{macro}[aux]{\clist_length_aux:n}
+% Counting the items in a comma list is done using the same approach as for
+% other length functions: turn each entry into a \texttt{+1} then use
+% integer evaluation to actually do the mathematics.
+% \begin{macrocode}
+\cs_new:Npn \clist_length:N #1
+ {
+ \int_eval:n
+ {
+ 0
+ \clist_map_function:NN #1 \clist_length_aux:n
+ }
+ }
+\cs_new:Npn \clist_length:n #1
+ {
+ \int_eval:n
+ {
+ 0
+ \clist_map_function:nN {#1} \clist_length_aux:n
+ }
+ }
+\cs_new:Npn \clist_length_aux:n #1 { +1 }
+\cs_generate_variant:Nn \clist_length:N { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\clist_item:Nn, \clist_item:cn}
+% \begin{macro}{\clist_item:nn}
+% \begin{macro}[aux]{\clist_item_aux:nnn}
+% The idea here is to find the offset of the item from the left, then use
+% a loop to grab the correct item. If the resulting offset is too large,
+% then \cs{quark_if_recursion_stop:n} will be true,
+% terminating the loop and returning nothing at all.
+% \begin{macrocode}
+\cs_set_nopar:Npn \clist_item:Nn #1#2
+ { \exp_args:No \clist_item:nn #1 {#2} }
+\cs_set:Npn \clist_item:nn #1#2
+ {
+ \int_compare:nNnTF {#2} < \c_zero
+ {
+ \exp_args:Nf \clist_item_aux:nw
+ { \int_eval:n { \clist_length:n {#1} + #2 } }
+ #1 , \q_recursion_tail \q_recursion_stop
+ }
+ { \clist_item_aux:nw {#2} #1 , \q_recursion_tail \q_recursion_stop }
+ }
+\cs_set:Npn \clist_item_aux:nw #1#2 , #3
+ {
+ \int_compare:nNnTF {#1} = \c_zero
+ { \use_i_delimit_by_q_recursion_stop:nw {#2} }
+ {
+ \quark_if_recursion_tail_stop:n {#3}
+ \exp_args:Nf \clist_item_aux:nw
+ { \int_eval:n { #1 - 1 } }
+ #3
+ }
+ }
+\cs_generate_variant:Nn \clist_item:Nn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \clist_set_from_seq:NN, \clist_set_from_seq:cN,
+% \clist_set_from_seq:Nc, \clist_set_from_seq:cc
+% }
+% \begin{macro}
+% {
+% \clist_gset_from_seq:NN, \clist_gset_from_seq:cN,
+% \clist_gset_from_seq:Nc, \clist_gset_from_seq:cc
+% }
+% Setting a comma list from a comma-separated list is done using a simple
+% mapping. We wrap each item with braces, \cs{exp_not:n}, and a comma. The
+% first comma must be removed, except in the case of an empty comma-list.
+% \begin{macrocode}
+\cs_new_protected:Npn \clist_set_from_seq:NN #1#2
+ {
+ \seq_if_empty:NTF #2
+ { \clist_clear:N #1 }
+ {
+ \seq_push_item_def:n { , \exp_not:n {{##1}} }
+ \tl_set:Nx #1
+ { \exp_after:wN \use_none:n \tex_romannumeral:D -`\0 #2 }
+ \seq_pop_item_def:
+ }
+ }
+\cs_new_protected:Npn \clist_gset_from_seq:NN #1#2
+ {
+ \seq_if_empty:NTF #2
+ { \clist_gclear:N #1 }
+ {
+ \seq_push_item_def:n { , \exp_not:n {##1} }
+ \tl_gset:Nx #1
+ { \exp_after:wN \use_none:n \tex_romannumeral:D -`\0 #2 }
+ \seq_pop_item_def:
+ }
+ }
+\cs_generate_variant:Nn \clist_set_from_seq:NN { Nc }
+\cs_generate_variant:Nn \clist_set_from_seq:NN { c , cc }
+\cs_generate_variant:Nn \clist_gset_from_seq:NN { Nc }
+\cs_generate_variant:Nn \clist_gset_from_seq:NN { c , cc }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Deprecated interfaces}
+%
+% Deprecated on 2011-05-27, for removal by 2011-08-31.
+%
+% \begin{macro}{\clist_top:NN, \clist_top:cN}
+% These are old stack functions.
+% \begin{macrocode}
+\cs_new_eq:NN \clist_top:NN \clist_get:NN
+\cs_new_eq:NN \clist_top:cN \clist_get:cN
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\clist_remove_element:Nn}
+% \begin{macro}{\clist_gremove_element:Nn}
+% An older name for \cs{clist_remove_all:Nn}.
+% \begin{macrocode}
+\cs_new_eq:NN \clist_remove_element:Nn \clist_remove_all:Nn
+\cs_new_eq:NN \clist_gremove_element:Nn \clist_gremove_all:Nn
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\clist_display:N, \clist_display:c}
+% An older name for \cs{clist_show:N}.
+% \begin{macrocode}
+\cs_new_eq:NN \clist_display:N \clist_show:N
+\cs_new_eq:NN \clist_display:c \clist_show:c
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</initex|package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex \ No newline at end of file
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx b/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx
new file mode 100644
index 00000000000..5039b8c0f62
--- /dev/null
+++ b/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx
@@ -0,0 +1,2064 @@
+% \iffalse meta-comment
+%
+%% File: l3doc.dtx Copyright (C) 1990-2011 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 "expl3 bundle" (The Work in LPPL)
+%% and all files in that bundle must be distributed together.
+%%
+%% The released version of this bundle is available from CTAN.
+%%
+%% -----------------------------------------------------------------------
+%%
+%% The development version of the bundle can be found at
+%%
+%% http://www.latex-project.org/svnroot/experimental/trunk/
+%%
+%% for those people who are interested.
+%%
+%%%%%%%%%%%
+%% NOTE: %%
+%%%%%%%%%%%
+%%
+%% Snapshots taken from the repository represent work in progress and may
+%% not work or may contain conflicting material! We therefore ask
+%% people _not_ to put them into distributions, archives, etc. without
+%% prior consultation with the LaTeX3 Project.
+%%
+%% -----------------------------------------------------------------------
+%
+%<*driver>
+\def\nameofplainTeX{plain}
+\ifx\fmtname\nameofplainTeX\else
+ \expandafter\begingroup
+\fi
+\input docstrip.tex
+\askforoverwritefalse
+\preamble
+
+
+EXPERIMENTAL CODE
+
+Do not distribute this file without also distributing the
+source files specified above.
+
+Do not distribute a modified version of this file.
+
+
+\endpreamble
+% stop docstrip adding \endinput
+\postamble
+\endpostamble
+\generate{\file{l3doc.cls}{\from{l3doc.dtx}{class}}}
+\generate{\file{l3doc.ist}{\from{l3doc.dtx}{docist}}}
+\ifx\fmtname\nameofplainTeX
+ \expandafter\endbatchfile
+\else
+ \expandafter\endgroup
+\fi
+%</driver>
+%
+%<*driver|class>
+\RequirePackage{l3names}
+%</driver|class>
+%
+% Need to protect the file metadata for any modules that load l3doc.
+% This is restored after "\ProvideExplClass" below.
+% \begin{macrocode}
+%<class>\let \filenameOld \ExplFileName
+%<class>\let \filedateOld \ExplFileDate
+%<class>\let \fileversionOld \ExplFileVersion
+%<class>\let \filedescriptionOld \ExplFileDescription
+% \end{macrocode}
+%
+%<*driver|class>
+\GetIdInfo$Id: l3doc.dtx 2478 2011-06-19 21:34:23Z joseph $
+ {L3 Experimental documentation class}
+%</driver|class>
+%
+%<*driver>
+\ProvidesFile{\ExplFileName.dtx}
+ [\ExplFileDate\space v\ExplFileVersion\space\ExplFileDescription]
+\documentclass{l3doc}
+\usepackage{framed}
+\begin{document}
+ \DocInput{l3doc.dtx}
+\end{document}
+%</driver>
+%
+% This isn't included in the typeset documentation because it's a bit ugly:
+%<*class>
+\ProvidesExplClass
+ {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
+\RequirePackage{expl3,xparse}
+\let \ExplFileName \filenameOld
+\let \ExplFileDate \filedateOld
+\let \ExplFileVersion \fileversionOld
+\let \ExplFileDescription \filedescriptionOld
+%</class>
+% \fi
+%
+% \title{The \pkg{l3doc} class\thanks{This file
+% has version number v\ExplFileVersion, last
+% revised \ExplFileDate.}}
+% \author{\Team}
+% \date{\ExplFileDate}
+% \maketitle
+% \tableofcontents
+%
+% \begin{documentation}
+%
+% \section{Introduction}
+%
+% This is an ad-hoc class for documenting the \pkg{expl3} bundle,
+% a collection of modules or packages that make up \LaTeX3's programming
+% environment. Eventually it will replace the "ltxdoc" class for \LaTeX3,
+% but not before the good ideas in \pkg{hypdoc}, \cls{xdoc2}, \pkg{docmfp}, and
+% \cls{gmdoc} are incorporated.
+%
+% \textbf{It is even less stable than the main \pkg{expl3} packages. Use at own risk!}
+%
+% It is written as a `self-contained' docstrip file: executing
+% "latex l3doc.dtx"
+% will generate the "l3doc.cls" file and typeset this
+% documentation; execute "tex l3doc.dtx" to only generate the ".cls" file.
+%
+% \section{Features of other packages}
+%
+% This class builds on the \pkg{ltxdoc} class and the \pkg{doc} package, but
+% in the time since they were originally written some
+% improvements and replacements have appeared that we would like to use as
+% inspiration.
+%
+% These packages or classes are \pkg{hypdoc}, \pkg{docmfp}, \pkg{gmdoc},
+% and \pkg{xdoc}. I have summarised them below in order to work out what
+% sort of features we should aim at a minimum for \pkg{l3doc}.
+%
+% \subsection{The \pkg{hypdoc} package}
+%
+% This package provides hyperlink support for the \pkg{doc} package. I have
+% included it in this list to remind me that cross-referencing between
+% documentation and implementation of methods is not very good. (E.g., it
+% would be nice to be able to automatically hyperlink the documentation for
+% a function from its implementation and vice-versa.)
+%
+% \subsection{The \pkg{docmfp} package}
+%
+% \begin{itemize}
+% \item Provides "\DescribeRoutine" and the "routine" environment (etc.)
+% for MetaFont and MetaPost code.
+% \item Provides "\DescribeVariable" and the "variable" environment (etc.)
+% for more general code.
+% \item Provides "\Describe" and the "Code" environment (etc.) as a
+% generalisation of the above two instantiations.
+% \item Small tweaks to the DocStrip system to aid non-\LaTeX\ use.
+% \end{itemize}
+%
+% \subsection{The \pkg{xdoc2} package}
+%
+% \begin{itemize}
+% \item Two-sided printing.
+% \item "\NewMacroEnvironment", "\NewDescribeEnvironment"; similar idea
+% to \pkg{docmfp} but more comprehensive.
+% \item Tons of small improvements.
+% \end{itemize}
+%
+% \subsection{The \pkg{gmdoc} package}
+%
+% Radical re-implementation of \pkg{doc} as a package or class.
+% \begin{itemize}
+% \item Requires no "\begin{macrocode}" blocks!
+% \item Automatically inserts "\begin{macro}" blocks!
+% \item And a whole bunch of other little things.
+% \end{itemize}
+%
+% \section{Problems \& Todo}
+%
+% Problems at the moment: (1)~not flexible in the types of things that can be documented; (2)~very nonstandard markup (e.g., the odd `"/ (...)"' tags; (3)~no obvious link between the "\begin{function}" environment for documenting things to the "\begin{macro}" function that's used analogously in the implementation.
+%
+% The "macro" should probably be renamed to "function" when it is used within
+% an implementation section. But they should have the same syntax before that happens!
+%
+% Furthermore, we need another `layer' of documentation commands to
+% account for `user-macro' as opposed to `code-functions'; the \pkg{expl3}
+% functions should be documented differently, probably, to the \pkg{xparse}
+% user macros (at least in terms of indexing).
+%
+% In no particular order, a list of things to do:
+% \begin{itemize}
+% \item Rename \env{function}/\env{macro} environments to better describe
+% their use.
+% \item Generalise \env{function}/\env{macro} for documenting `other things',
+% such as environment names, package options, even keyval options.
+% \item Use \pkg{xparse}.
+% \item New function like "\part" but for files (remove awkward `File' as "\partname").
+% \item Something better to replace "\StopEventually"; I'm thinking two
+% environments \env{documentation} and \env{implementation} that can
+% conditionally typeset/ignore their material.
+% (This has been implemented but needs further consideration.)
+% \item Hyperlink documentation and implementation of macros (see
+% the \textsc{dtx} file of \pkg{svn-multi} v2 as an example).
+% \end{itemize}
+%
+% \section{Bugs}
+%
+% \begin{itemize}
+% \item Spaces are ignored entirely within \env{function} and \env{macro}
+% arguments. This is just waiting for a convenient space-trimming
+% macro in \pkg{expl3}.
+% \end{itemize}
+%
+% \section{Documentation}
+%
+% \subsection{Configuration}
+%
+% Before class options are processed, \pkg{l3doc} loads a configuration
+% file "l3doc.cfg" if it exists, allowing you to customise the behaviour of
+% the class without having to change the documentation source files.
+%
+% For example, to produce documentation on letter-sized paper instead of the
+% default A4 size, create |l3doc.cfg| and include the line
+% \begin{verbatim}
+% \PassOptionsToClass{letterpaper}{l3doc}
+% \end{verbatim}
+%
+% By default, \pkg{l3doc} selects the |T1| font encoding and loads the
+% Latin Modern fonts.
+% To prevent this, use the class option |cm-default|.
+%
+% \subsection{Partitioning documentation and implementation}
+%
+% \pkg{doc} uses the "\OnlyDocumentation"/"\AlsoImplementation" macros
+% to guide the use of "\StopEventually{}", which is intended to be placed
+% to partition the documentation and implementation within a single DTX file.
+%
+% This isn't very flexible, since it assumes that we \emph{always} want
+% to print the documentation. For the \pkg{expl3} sources, I wanted to be
+% be able to input DTX files in two modes: only displaying the documentation,
+% and only displaying the implementation. For example:
+%
+% \begin{verbatim}
+% \DisableImplementation
+% \DocInput{l3basics,l3prg,...}
+% \EnableImplementation
+% \DisableDocumentation
+% \DocInputAgain
+% \end{verbatim}
+%
+% The idea being that the entire \pkg{expl3} bundle can be documented,
+% with the implementation included at the back. Now, this isn't perfect,
+% but it's a start.
+%
+% Use "\begin{documentation}...\end{documentation}" around the documentation,
+% and "\begin{implementation}...\end{implementation}" around the implementation.
+% The "\EnableDocumentation"/"\EnableImplementation" will cause them to be typeset
+% when the DTX file is "\DocInput"; use "\DisableDocumentation"/"\DisableImplementation"
+% to omit the contents of those environments.
+%
+% Note that \cmd\DocInput\ now takes comma-separated arguments, and \cmd\DocInputAgain\
+% can be used to re-input all DTX files previously input in this way.
+%
+% \subsection{Describing functions in the documentation}
+%
+% \DescribeEnv{function}
+% \DescribeEnv{syntax}
+% Two heavily-used environments are defined to describe the syntax
+% of \textsf{expl3} functions and variables.
+% \begin{framed}
+% \vspace{-\baselineskip}
+% \begin{verbatim}
+% \begin{function}{ list_of , functions }
+% \begin{syntax}
+% "\foo_bar:" \Arg{meta} <test1>
+% \end{syntax}
+% <description>
+% \end{function}
+% \end{verbatim}
+% \vspace{-2\baselineskip}
+% \hrulefill
+% \begin{function}{ list_of , functions }
+% \begin{syntax}
+% "\foo_bar:" \Arg{meta} <test1>
+% \end{syntax}
+% <description>
+% \end{function}
+% \end{framed}
+%
+% Function environments take an optional argument to indicate whether the function(s) it
+% describes are expandable or defined in conditional forms. Use "EXP", "TF", or "pTF"
+% for this; note that "pTF" implies "EXP" since predicates must always be expandable.
+% As an example:
+% \begin{framed}
+% \vspace{-\baselineskip}
+% \begin{verbatim}
+% \begin{function}[pTF]{ \cs_if_exist:N }
+% \begin{syntax}
+% "\cs_if_exist_p:N" <cs>
+% \end{syntax}
+% <description>
+% \end{function}
+% \end{verbatim}
+% \vspace{-2\baselineskip}
+% \hrulefill
+% \begin{function}[pTF]{ \cs_if_exist:N }
+% \begin{syntax}
+% "\cs_if_exist_p:N" <cs>
+% \end{syntax}
+% <description>
+% \end{function}
+% \end{framed}
+%
+% Note that the list of functions used to use "|" as a separator instead,
+% and this syntax is still supported.
+%
+% In the old syntax, individual functions could be suffixed by an optional flag or
+% two to indicate the same information given in the optional argument.
+% This is still supported; use "/" to separate the function name
+% from the flag(s) and then add any of "(EXP)", "(TF)", or "(pTF)".
+%
+% \DescribeEnv{variable}
+% If you are documenting a variable instead of a function, use the "variable" environment instead; it behaves identically to the "function" environment above.
+%
+% \subsection{Describing functions in the implementation}
+%
+% \DescribeEnv{macro}
+% The well-used environment from \LaTeXe\ for marking up the implementation
+% of macros/functions remains the \env{macro} environment.
+% Some changes in \pkg{l3doc}: it now accepts comma-separated lists
+% of functions, to avoid a very large number of consecutive "\end{macro}"
+% statements.
+% \begin{verbatim}
+% % \begin{macro}{\foo:N,\foo:c}
+% % \begin{macrocode}
+% ... code for \foo:N and \foo:c ...
+% % \end{macrocode}
+% % \end{macro}
+% \end{verbatim}
+% If you are documenting an auxiliary macro, it's generally not necessary
+% to highlight it as much and you also don't need to check it for, say,
+% having a test function and having a documentation chunk earlier in a "function"
+% environment. In this case, write "\begin[aux]{macro}" and it will be
+% marked as such; its margin call-out will be printed in grey.
+%
+% Similarly, an internal package function still requires documentation
+% but usually will not be documented for users to see; these can be marked
+% as such with "\begin[internal]{macro}".
+%
+% For documenting \pkg{expl3}-type conditionals, you may also pass this
+% environment a "TF" option (and omit it from the function name) to denote that
+% the function is provided with "T", "F", and "TF" suffixes.
+% A similar "pTF" option will print both "TF" and "_p" predicate forms.
+%
+%
+% \DescribeMacro{\TestFiles}
+% \cs{TestFiles}\marg{list of files} is used to indicate which test files
+% are used for the current code; they will be printed in the documentation.
+%
+% \DescribeMacro{\UnitTested}
+% Within a "macro" environment, it is a good idea to mark whether a unit test has
+% been created for the commands it defines. This is indicated by writing \cs{UnitTested}
+% anywhere within "\begin{macro}" \dots "\end{macro}".
+%
+% If the class option "checktest" is enabled, then it is an \emph{error} to have a
+% "macro" environment without a \cs{testfile} file. This is intended for large packages such
+% as \pkg{expl3} that should have absolutely comprehensive tests suites and whose authors
+% may not always be as sharp at adding new tests with new code as they should be.
+%
+% \DescribeMacro{\TestMissing}
+% If a function is missing a test, this may be flagged by writing (as many times as needed)
+% \cs{TestMissing}\marg{explanation of test required}.
+% These missing tests will be summarised in the listing printed at the end of the
+% compilation run.
+%
+% \DescribeEnv{variable}
+% When documenting variable definitions, use the "variable" environment instead.
+% It will, here, behave identically to the "macro" environment, except that if the class
+% option "checktest" is enabled, variables will not be required to have a test file.
+%
+% \DescribeEnv{arguments}
+% Within a \env{macro} environment, you may use the \env{arguments} environment
+% to describe the arguments taken by the function(s). It behaves
+% like a modified enumerate environment.
+% \begin{verbatim}
+% % \begin{macro}{\foo:nn,\foo:VV}
+% % \begin{arguments}
+% % \item Name of froozle to be frazzled
+% % \item Name of muble to be jubled
+% % \end{arguments}
+% % \begin{macrocode}
+% ... code for \foo:nn and \foo:VV ...
+% % \end{macrocode}
+% % \end{macro}
+% \end{verbatim}
+%
+% \bigskip
+% \textbf{OPTIONS FOR THE FUTURE}\qquad Any improvements to the markup
+% for the \env{function} environment would be good to mirror in \env{macro}.
+%
+% Perhaps this would be a better syntax for describing arguments?
+% \begin{verbatim}
+% \begin{macro}{\foo:nn,foo:VV}
+% \dArg{Name of froozle to be frazzled}
+% \dArg{Name of mumble to be jumbled}
+% ...
+% \end{verbatim}
+% I.e., get rid of the environment and do things like in, say, \pkg{fontspec}.
+%
+% \subsection{Keeping things consistent}
+%
+% Whenever a function is either documented or defined with \env{function}
+% and \env{macro} respectively, its name is stored in a sequence for later
+% processing.
+%
+% At the end of the document (i.e., after the \textsc{dtx} file has finished
+% processing), the list of names is analysed to check whether all defined
+% functions have been documented and vice versa. The results are printed
+% in the console output.
+%
+% If you need to do more serious work with these lists of names, take a
+% look at the implementation for the data structures and methods used to
+% store and access them directly.
+%
+% \subsection{Documenting templates}
+%
+% The following macros are provided for documenting templates; might
+% end up being something completely different but who knows.
+% \begin{quote}\parskip=0pt\obeylines
+% "\begin{TemplateInterfaceDescription}" \Arg{template type name}
+% " \TemplateArgument{none}{---}"
+% \textsc{or one or more of these:}
+% " \TemplateArgument" \Arg{arg no} \Arg{meaning}
+% \textsc{and}
+% "\TemplateSemantics"
+% " " \meta{text describing the template type semantics}
+% "\end{TemplateInterfaceDescription}"
+% \end{quote}
+%
+% \begin{quote}\parskip=0pt\obeylines
+% "\begin{TemplateDescription}" \Arg{template type name} \Arg{name}
+% \textsc{one or more of these:}
+% " \TemplateKey" \marg{key name} \marg{type of key}
+% " "\marg{textual description of meaning}
+% " "\marg{default value if any}
+% \textsc{and}
+% "\TemplateSemantics"
+% " " \meta{text describing special additional semantics of the template}
+% "\end{TemplateDescription}"
+% \end{quote}
+%
+% \begin{quote}\parskip=0pt\obeylines
+% "\begin{InstanceDescription}" \oarg{text to specify key column width (optional)}
+% \hfill\marg{template type name}\marg{instance name}\marg{template name}
+% \textsc{one or more of these:}
+% " \InstanceKey" \marg{key name} \marg{value}
+% \textsc{and}
+% "\InstanceSemantics"
+% " " \meta{text describing the result of this instance}
+% "\end{InstanceDescription}"
+% \end{quote}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3doc} implementation}
+%
+% \begin{macrocode}
+%<*class>
+% \end{macrocode}
+%
+% The Guilty Parties.
+% \begin{macrocode}
+\cs_new_nopar:Npn\Team{%
+ The~\LaTeX3~Project\thanks{%
+ Frank~Mittelbach,~Denys~Duchier,~Chris~Rowley,~
+ Rainer~Sch\"opf,~Johannes~Braams,~Michael~Downes,~
+ David~Carlisle,~Alan~Jeffrey,~Morten~H\o{}gholm,~Thomas~Lotze,~
+ Javier~Bezos,~Will~Robertson,~Joseph~Wright}}
+% \end{macrocode}
+%
+% \subsection{Options and configuration}
+%
+% \begin{macrocode}
+\DeclareOption{a5paper}{\@latexerr{Option not supported}{}}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\bool_new:N \g_doc_full_bool
+\bool_new:N \g_doc_lmodern_bool
+\bool_new:N \g_doc_checkfunc_bool
+\bool_new:N \g_doc_checktest_bool
+% \end{macrocode}
+%
+% \begin{macrocode}
+\DeclareOption{full}{ \bool_set_true:N \g_doc_full_bool }
+\DeclareOption{onlydoc}{ \bool_set_false:N \g_doc_full_bool }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\DeclareOption{check}{ \bool_set_true:N \g_doc_checkfunc_bool }
+\DeclareOption{nocheck}{ \bool_set_false:N \g_doc_checkfunc_bool }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\DeclareOption{checktest}{ \bool_set_true:N \g_doc_checktest_bool }
+\DeclareOption{nochecktest}{ \bool_set_false:N \g_doc_checktest_bool }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\DeclareOption{cm-default}{ \bool_set_false:N \g_doc_lmodern_bool }
+\DeclareOption{lm-default}{ \bool_set_true:N \g_doc_lmodern_bool }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\DeclareOption*{\PassOptionsToClass{\CurrentOption}{article}}
+\ExecuteOptions{full,a4paper,nocheck,nochecktest,lm-default}
+% \end{macrocode}
+%
+% Input a local configuration file, if it exists.
+%
+% \begin{macrocode}
+\InputIfFileExists{l3doc.cfg}
+ {
+ \typeout{*************************************^^J
+ *~Local~config~file~l3doc.cfg~used ^^J
+ *************************************}
+ }
+ { \@input{l3doc.ltx} }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\ProcessOptions
+% \end{macrocode}
+%
+%
+% \subsection{Class and package loading}
+%
+% \begin{macrocode}
+\LoadClass{article}
+\RequirePackage{doc}
+\RequirePackage{array,alphalph,booktabs,color,fixltx2e,enumitem,textcomp,trace,underscore,csquotes}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\bool_if:NT \g_doc_lmodern_bool {
+ \RequirePackage[T1]{fontenc}
+ \RequirePackage{lmodern}
+}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\RequirePackage{hypdoc}
+% \end{macrocode}
+% Just want the "comment" environment from \pkg{verbatim}:
+% \begin{macrocode}
+\let\doc@verbatim\verbatim
+\let\enddoc@verbatim\endverbatim
+\let\doc@@verbatim\@verbatim
+\expandafter\let\csname doc@verbatim*\expandafter\endcsname
+ \csname verbatim*\endcsname
+\expandafter\let\csname enddoc@verbatim*\expandafter\endcsname
+ \csname endverbatim*\endcsname
+\expandafter\let\csname doc@@verbatim*\expandafter\endcsname
+ \csname @verbatim*\endcsname
+\RequirePackage{verbatim}
+\AtBeginDocument{%
+ \let\verbatim\doc@verbatim
+ \let\endverbatim\enddoc@verbatim
+ \let\@verbatim\doc@@verbatim
+ \expandafter\let\csname verbatim*\expandafter\endcsname
+ \csname doc@verbatim*\endcsname
+ \expandafter\let\csname endverbatim*\expandafter\endcsname
+ \csname enddoc@verbatim*\endcsname
+ \expandafter\let\csname @verbatim*\expandafter\endcsname
+ \csname doc@@verbatim*\endcsname
+}
+% \end{macrocode}
+%
+% \subsection{Configuration}
+%
+% \begin{macro}{\MakePrivateLetters}
+% \begin{macrocode}
+\cs_set_nopar:Npn \MakePrivateLetters {
+ \char_set_catcode_letter:N \@
+ \char_set_catcode_letter:N \_
+ \char_set_catcode_letter:N \:
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+\setcounter{StandardModuleDepth}{1}
+\@addtoreset{CodelineNo}{part}
+\cs_set_nopar:Npn \theCodelineNo {
+ \textcolor[gray]{0.5}{ \sffamily\tiny\arabic{CodelineNo} }
+}
+% \end{macrocode}
+%
+%
+%
+% \subsection{Design}
+%
+% Increase the text width slightly so that width the standard fonts
+% 72 columns of code may appear in a |macrocode| environment.
+% Increase the marginpar width slightly, for long command names.
+% And increase the left margin by a similar amount.
+% \begin{macrocode}
+\setlength \textwidth { 385pt }
+\addtolength \marginparwidth { 30pt }
+\addtolength \oddsidemargin { 20pt }
+\addtolength \evensidemargin { 20pt }
+% \end{macrocode}
+% (These were introduced when "article" was the documentclass, but
+% I've left them here for now to remind me to do something about them
+% later; we still have the problem of \emph{very long} command names.)
+%
+% Customise lists:
+% \begin{macrocode}
+\cs_set_eq:NN \@@oldlist\list
+\cs_set_nopar:Npn \list#1#2{\@@oldlist{#1}{#2\listparindent\z@}}
+\setlength \parindent { 0pt }
+\setlength \itemindent { 0pt }
+\setlength \parskip { \medskipamount }
+% \end{macrocode}
+%
+% \subsection{Text markup}
+%
+% Make "|" and |"| be `short verb' characters, but not in
+% the document preamble, where an active character may interfere
+% with packages that are loaded.
+% \begin{macrocode}
+\AtBeginDocument {
+ \MakeShortVerb \"
+ \MakeShortVerb \|
+}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\providecommand*\eTeX{
+ \if b\expandafter\@car\f@series\@nil\boldmath\fi
+ $\m@th\varepsilon$-\TeX
+}
+\providecommand*\IniTeX{Ini\TeX}
+\providecommand*\Lua{Lua}
+\providecommand*\LuaTeX{\Lua\TeX}
+\providecommand*\pdfTeX{pdf\TeX}
+\RequirePackage{graphicx}
+\cs_if_free:NT \XeTeX {
+ \cs_new_protected_nopar:Npn \XeTeX
+ {X\kern-.125em\lower.5ex\hbox{\reflectbox{E}}\kern-.1667em\TeX}
+}
+% \end{macrocode}
+%
+% \begin{macro}{\cmd,\cs}
+% |\cmd{\foo}| Prints |\foo| verbatim. It may be used inside moving
+% arguments. |\cs{foo}| also prints |\foo|, for those who prefer that
+% syntax.
+% \begin{macrocode}
+\cs_set_nopar:Npn \cmd #1 { \cs{\expandafter\cmd@to@cs\string#1} }
+\cs_set_nopar:Npn \cmd@to@cs #1#2 { \char\number`#2\relax }
+\DeclareRobustCommand \cs [1] { \texttt { \char`\\ #1 } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\marg,\oarg,\parg}
+% |\marg{text}| prints \marg{text}, `mandatory argument'.\\
+% |\oarg{text}| prints \oarg{text}, `optional argument'.\\
+% |\parg{te,xt}| prints \parg{te,xt}, `picture mode argument'.
+% \begin{macrocode}
+\providecommand\marg[1]{ \texttt{\char`\{} \meta{#1} \texttt{\char`\}} }
+\providecommand\oarg[1]{ \texttt[ \meta{#1} \texttt] }
+\providecommand\parg[1]{ \texttt( \meta{#1} \texttt) }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\m,\file,\env,\pkg,\cls}
+% This list may change\dots this is just my preference for markup.
+% \begin{macrocode}
+\cs_set_eq:NN \m \meta
+\cs_set_eq:NN \file \nolinkurl
+\DeclareRobustCommand \env {\texttt}
+\DeclareRobustCommand \pkg {\textsf}
+\DeclareRobustCommand \cls {\textsf}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{environment}{texnote}
+% \begin{macrocode}
+\newenvironment{texnote}{
+ \endgraf
+ \vspace{3mm}
+ \small\textbf{\TeX~hackers~note:}
+}{
+ \vspace{3mm}
+}
+% \end{macrocode}
+% \end{environment}
+%
+% \begin{macro}{\tn}
+% As \cs{cs}. Use this to mark up all \TeX\ and \LaTeXe\ commands; they
+% then end up together in the index. TODO: hyperlinks in the index entries.
+% \begin{macrocode}
+\newcommand\tn[1]{
+ \texttt{\bslash #1}
+ \index{TeX~and~LaTeX2e~commands\actualchar
+ \string\TeX{}~and~\string\LaTeXe{}~commands:\levelchar
+ #1\actualchar{\string\ttfamily\string\bslash{}#1}}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{environment}{documentation}
+% \begin{environment}{implementation}
+% \begin{macro}{\EnableDocumentation,\EnableImplementation}
+% \begin{macro}{\DisableDocumentation,\DisableImplementation}
+% \begin{macrocode}
+\cs_new:Npn \doc_implementation: {
+ \cs_set:Npn \variable {\macro[var]}
+}
+\cs_new:Npn \doc_docu: {
+ \cs_set_eq:NN \variable \variabledoc
+}
+\AtEndOfPackage{\doc_docu:}
+\newenvironment{documentation}{\doc_docu:}{}
+\newenvironment{implementation}{\doc_implementation:}{}
+\newcommand\EnableDocumentation{%
+ \renewenvironment{documentation}{\doc_docu:}{}%
+}
+\newcommand\EnableImplementation{%
+ \renewenvironment{implementation}{\doc_implementation:}{}%
+}
+\newcommand\DisableDocumentation{%
+ \cs_set_eq:NN \documentation \comment
+ \cs_set_eq:NN \enddocumentation \endcomment
+}
+\newcommand\DisableImplementation{%
+ \cs_set_eq:NN \implementation \comment
+ \cs_set_eq:NN \endimplementation \endcomment
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{environment}
+% \end{environment}
+%
+% \begin{environment}{arguments}
+% This environment is designed to be used within a \env{macro} environment
+% to describe the arguments of the macro/function.
+% \begin{macrocode}
+\newenvironment{arguments}{
+ \enumerate[
+ nolistsep,
+ label=\texttt{\#\arabic*}~:,
+ labelsep=*,
+ ]
+}{
+ \endenumerate
+}
+% \end{macrocode}
+% \end{environment}
+%
+% \begin{environment}{function}
+% \begin{environment}{variabledoc}
+% Environment for documenting function(s).
+% Stick the function names in a box. Use a "|" as delimiter and
+% allow |<...>| to be used as markup for |\meta{...}|.
+% Ignore spaces and sanitize with catcodes before reading argument.
+% \begin{macrocode}
+\char_set_catcode_active:N \<
+\DeclareDocumentCommand \function { O{} } {
+
+ \phantomsection
+
+ \bool_gset_false:N \l_doc_meta_TF_bool
+ \bool_gset_false:N \l_doc_meta_pTF_bool
+ \bool_gset_false:N \l_doc_meta_EXP_bool
+
+ \cs_set_nopar:Npn \KV_key_no_value_elt:n ##1 { \use:c {doc_meta_opt_##1:} }
+ \keyval_parse:NNn \KV_key_no_value_elt:n \use_none:nn {#1}
+
+ \char_set_catcode_active:N \<
+ \cs_set_eq:NN < \doc_open_meta:n
+
+ \group_begin:
+ \MakePrivateLetters
+ \char_set_catcode_other:N \|
+ \char_set_catcode_other:N \\
+ \char_set_catcode_space:N \~
+ \char_set_catcode_ignore:N \ % space
+ \char_set_catcode_ignore:N \^^M
+ \char_set_catcode_ignore:N \^^I
+ \function_aux:n
+}
+\char_set_catcode_other:N \<
+\cs_set_eq:NN \variabledoc \function
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_set:Nn \doc_meta_opt_TF: {
+ \bool_gset_true:N \l_doc_meta_TF_bool
+}
+\cs_set:Nn \doc_meta_opt_EXP: {
+ \bool_gset_true:N \l_doc_meta_EXP_bool
+}
+\cs_set:Nn \doc_meta_opt_pTF: {
+ \bool_gset_true:N \l_doc_meta_pTF_bool
+ \bool_gset_true:N \l_doc_meta_TF_bool
+ \bool_gset_true:N \l_doc_meta_EXP_bool
+}
+% \end{macrocode}
+%
+% \begin{macro}{\function_aux:n}
+% \begin{arguments}
+% \item Vertical bar--separated list of functions with optional metadata;
+% input has already been sanitised by catcode changes before reading
+% the argument.
+% \end{arguments}
+% Because vertical bars are odd delimiters to choose, we also now iterate over commas!
+% \begin{macrocode}
+\group_begin:
+\char_set_catcode_other:N \|
+\cs_gset_nopar:Npn \function_aux:n #1 {
+ \cs_set_nopar:Npn \nextnewline{\cs_gset_nopar:Npn\nextnewline{\\}}
+ \tl_gset_eq:NN \g_doc_macro_tl \c_empty_tl
+ \bigskip\endgraf\noindent\ttfamily
+ \tabular[b]{ | l @{} c | }
+ \hline
+ \clist_map_inline:nn {#1} {\doc_showmacro:w ##1 | \q_stop} \\
+ \hline
+ \endtabular
+ \group_end:
+}
+\group_end:
+% \end{macrocode}
+% \end{macro}
+% \end{environment}
+% \end{environment}
+%
+% \begin{macro}{\doc_showmacro:w}
+% This function reads in a "|"-separated list, passing each item to
+% the auxiliary function "\doc_showmacro_aux:w".
+% \begin{macrocode}
+\group_begin:
+\char_set_catcode_other:N \|
+\cs_gset_nopar:Npn \doc_showmacro:w #1 | {
+ \tl_if_blank:nTF {#1} {
+ \use_none:n
+ }{
+ \doc_showmacro_aux:w #1 / \q_stop
+ \peek_meaning:NTF \q_stop { \use_none:n } { \doc_showmacro:w }
+ }
+}
+\group_end:
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+\bool_new:N \l_doc_meta_TF_bool
+\bool_new:N \l_doc_meta_pTF_bool
+\bool_new:N \l_doc_meta_EXP_bool
+% \end{macrocode}
+%
+% \begin{macro}{\doc_showmacro_aux:w}
+% This macro is passed one of:
+% \begin{quote}
+% "\abc:cnx / (EXP) / \q_stop" \\
+% "\abc:cnx / \q_stop" \\
+% \end{quote}
+% We also have some code here to print out every documented macro at the end
+% of the document.
+% \begin{arguments}
+% \item Function/macro/variable name \item Metadata tags (if any)
+% \end{arguments}
+% \begin{macrocode}
+\cs_new_nopar:Npn \doc_showmacro_aux:w #1 / #2 \q_stop {
+
+ \tl_if_in:nnT {#2} { (TF) } {
+ \bool_gset_true:N \l_doc_meta_TF_bool
+ }
+
+ \tl_if_in:nnT {#2} { (EXP) } {
+ \bool_gset_true:N \l_doc_meta_EXP_bool
+ }
+
+ \tl_if_in:nnT {#2} { (pTF) } {
+ \bool_gset_true:N \l_doc_meta_TF_bool
+ \bool_gset_true:N \l_doc_meta_pTF_bool
+ \bool_gset_true:N \l_doc_meta_EXP_bool
+ }
+
+ \bool_if:NT \l_doc_meta_pTF_bool {
+ \tl_set:Nx \l_doc_pTF_name_tl { \doc_predicate_from_base:w #1 \q_nil }
+ \doc_special_main_index:o { \l_doc_pTF_name_tl }
+ \seq_gput_right:Nx \g_doc_functions_seq { \tl_to_str:N \l_doc_pTF_name_tl }
+ }
+
+ \bool_if:NTF \l_doc_meta_TF_bool {
+ \doc_special_main_index:o { #1 TF }
+ \seq_gput_right:Nx \g_doc_functions_seq { \tl_to_str:n { #1 TF } }
+ \seq_gput_right:Nx \g_doc_functions_seq { \tl_to_str:n { #1 T } }
+ \seq_gput_right:Nx \g_doc_functions_seq { \tl_to_str:n { #1 F } }
+ }{
+ \doc_special_main_index:o { #1 }
+ \seq_gput_right:Nx \g_doc_functions_seq { \tl_to_str:n { #1 } }
+ }
+
+ \bool_if:NTF \l_doc_meta_pTF_bool {
+ \bool_gset_false:N \l_doc_meta_TF_bool
+ \exp_after:wN \doc_showmacro_aux_ii:w \l_doc_pTF_name_tl ::\q_stop
+ \bool_gset_true:N \l_doc_meta_TF_bool
+ \doc_showmacro_aux_ii:w #1::\q_stop
+ }{
+ \doc_showmacro_aux_ii:w #1::\q_stop
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\doc_showmacro_aux_ii:w}
+% This macro is passed arguments in the following ways:
+% \begin{quote}
+% "\doc_showmacro_aux_ii:w "^^A
+% \makebox[\widthof{\texttt{123456}}]{\meta{name}}^^A
+% " ::\q_stop" \\
+% "\doc_showmacro_aux_ii:w \foo ::\q_stop" \\
+% "\doc_showmacro_aux_ii:w \foo: ::\q_stop" \\
+% "\doc_showmacro_aux_ii:w \foo:Z ::\q_stop" \\
+% \end{quote}
+% Notice that for "\foo", "#2" and "#3" are empty,\\
+% for "\foo:", "#2" is empty, and "#3" is `":"'\\
+% for "\foo:Z", "#2" is `"Z"' and "#3" is `":"' .
+% \begin{arguments}
+% \item Function name \item Possible arg.\ spec. \item Possible colon
+% \end{arguments}
+% \begin{macrocode}
+\cs_set_nopar:Npn \doc_showmacro_aux_ii:w #1:#2:#3 \q_stop {
+ \nextnewline
+ \str_if_eq:xxTF {#1} {\g_doc_macro_tl} {
+ \doc_typeset_aux:n
+ }{
+ \tl_gset:Nn \g_doc_macro_tl {#1}
+ \use:n
+ }
+ { \g_doc_macro_tl }
+ #3
+ #2
+ \bool_if:NT \l_doc_meta_TF_bool { \doc_typeset_TF: }
+ &
+ \bool_if:NT \l_doc_meta_EXP_bool {
+ \hspace{\tabcolsep}
+ $\star$
+ }
+ \tl_set:Nx \g_doc_macro_tl { \tl_to_str:N \g_doc_macro_tl }
+ \exp_args:NNf \tl_replace_all_in:Nnn \g_doc_macro_tl {\token_to_str:N _} {/}
+ \exp_args:NNf \tl_replace_all_in:Nnn \g_doc_macro_tl {\@backslashchar} {}
+ \bool_if:NT \g_doc_full_bool {
+ \exp_args:Nf\label{doc/function/\g_doc_macro_tl#3#2}
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{environment}{syntax}
+% Syntax block placed next to the list of functions to illustrate their use.
+% \begin{macrocode}
+\dim_new:N \g_doc_syntax_dim
+\dim_set:Nn \g_doc_syntax_dim {0.7\textwidth}
+\newenvironment{syntax}{
+ \minipage[b]{\g_doc_syntax_dim}
+ \cs_set_nopar:Npn \meta@font@select{\rmfamily\itshape} % (Will: I HATE italic cmtt!)
+ \small\ttfamily\raggedright
+ \obeyspaces\obeylines
+}{
+ \endminipage
+ \hfil\break
+ \global\@ignoretrue
+}
+% \end{macrocode}
+% \end{environment}
+%
+% Perhaps these belong in \file{l3token}?
+% \begin{macrocode}
+\tl_map_inline:nn {0123456789} { \cs_gset_eq:cN {char_other_#1} #1 }
+% \end{macrocode}
+%
+% \begin{macro}{\doc_open_meta:n,\doc_close_meta:n}
+% This code turns all numbers within "<...>" markup to be set as subscripts.
+% You can use escaped numbers to get the real thing (e.g., "\1" = `1').
+% \begin{macrocode}
+\group_begin:
+ \tl_map_inline:nn {0123456789} { \char_set_catcode_active:N #1 }
+ \cs_new:Npn \doc_open_meta:n {
+ \group_begin:
+ \tl_map_function:nN {0123456789} \doc_assign_num:n
+ \doc_close_meta:w
+ }
+ \cs_new:Npn \Arg {
+ \texttt{ \char`\{ }
+ \group_begin:
+ \tl_map_function:nN {0123456789} \doc_assign_num:n
+ \doc_close_Arg:n
+ }
+\group_end:
+\cs_new_nopar:Npn \doc_close_meta:w #1> { \meta {#1} \group_end: }
+\cs_new_nopar:Npn \doc_close_Arg:n #1 {
+ \meta {#1}
+ \group_end:
+ \texttt{ \char`\} }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\doc_assign_num:n}
+% This function takes a numeral (`0'), defines its escaped self to be equal
+% to itself ("\0" $\to$ `0'), makes it active, and turns itself into a subscript
+% instead (`0' $\to$ `${}_0$').
+% \begin{macrocode}
+\cs_new_nopar:Npn \doc_assign_num:n #1 {
+ \cs_set_eq:cc { \string #1 } { char_other_\string #1 }
+ \char_set_catcode_active:N #1
+ \cs_set_nopar:Npn #1 { \unskip \, $ {} \sb { \use:c { char_other_\string #1 } } $ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{environment}{macro}
+% We want to extend the old definition to allow comma-separated lists of
+% macros, rather than one at a time. keyval processing is very rudimentary;
+% awaiting a more robust solution.
+% \begin{macrocode}
+\renewcommand \macro [1][] {
+
+ \int_compare:nNnTF \currentgrouplevel=2
+ { \int_gzero:N \g_doc_nested_macro_int }
+ { \int_incr:N \g_doc_nested_macro_int }
+
+ \bool_set_false:N \l_doc_macro_aux_bool
+ \bool_set_false:N \l_doc_macro_internal_bool
+ \bool_set_false:N \l_doc_macro_TF_bool
+ \bool_set_false:N \l_doc_macro_pTF_bool
+ \bool_set_false:N \l_doc_macro_var_bool
+ \bool_set_false:N \l_doc_tested_bool
+
+ \cs_set_eq:NN \doc_macroname_prefix:n \use:n
+ \cs_set_eq:NN \doc_macroname_suffix: \c_empty_tl
+
+ \cs_set_nopar:Npn \KV_key_no_value_elt:n ##1 { \use:c {doc_macro_opt_##1:} }
+ \keyval_parse:NNn \KV_key_no_value_elt:n \use_none:nn {#1}
+
+ \cs_set_eq:NN \testfile \doc_print_testfile:n
+
+ \group_begin:
+ \MakePrivateLetters
+ \char_set_catcode_letter:N \\
+ \char_set_catcode_ignore:N \ % space
+ \char_set_catcode_ignore:N \^^M
+ \char_set_catcode_ignore:N \^^I
+ \doc_macro_aux:n
+}
+% \end{macrocode}
+% After changing the catcodes, parse the arguments:
+% \begin{macrocode}
+\cs_new_nopar:Npn \doc_macro_aux:n #1 {
+ \group_end:
+ \cs_set:Npn \l_doc_macro_input_clist {#1}
+ \bool_if:NTF \l_doc_macro_pTF_bool
+ {
+ \clist_map_inline:nn {#1}
+ {
+ \tl_if_blank:nF {##1}
+ {
+ \exp_args:Nf \doc_macro_single
+ { \doc_predicate_from_base:w ##1 \q_nil }
+ }
+ }
+ \bool_set_true:N \l_doc_macro_TF_bool
+ \clist_map_inline:nn {#1}
+ { \tl_if_blank:nF {##1} { \doc_macro_single {##1} } }
+ \bool_set_false:N \l_doc_macro_TF_bool
+ }
+ {
+ \clist_map_inline:nn {#1}
+ { \tl_if_blank:nF {##1} { \doc_macro_single {##1} } }
+ }
+}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\bool_new:N \l_doc_macro_internal_bool
+\bool_new:N \l_doc_macro_aux_bool
+\bool_new:N \l_doc_macro_TF_bool
+\bool_new:N \l_doc_macro_pTF_bool
+\bool_new:N \l_doc_macro_var_bool
+\cs_set_nopar:Npn \doc_macro_opt_aux: { \bool_set_true:N \l_doc_macro_aux_bool }
+\cs_set_nopar:Npn \doc_macro_opt_internal: { \bool_set_true:N \l_doc_macro_internal_bool }
+\cs_set_nopar:Npn \doc_macro_opt_TF: { \bool_set_true:N \l_doc_macro_TF_bool }
+\cs_set_nopar:Npn \doc_macro_opt_pTF: { \bool_set_true:N \l_doc_macro_pTF_bool }
+\cs_set_nopar:Npn \doc_macro_opt_var: { \bool_set_true:N \l_doc_macro_var_bool }
+% \end{macrocode}
+% \end{environment}
+%
+% \begin{macrocode}
+\cs_set:Npn \doc_predicate_from_base:w #1:#2 \q_nil {#1_p:#2}
+% \end{macrocode}
+%
+% \begin{environment}{doc_macro_single}
+% Let's start to mess around with "doc"'s "macro" environment. See \file{doc.dtx}
+% for a full explanation of the original environment. It's
+% rather \emph{enthusiastically} commented.
+% \begin{arguments}
+% \item Macro/function/whatever name; input has already been sanitised.
+% \end{arguments}
+% \begin{macrocode}
+\int_new:N \l_doc_macro_int
+\cs_set_nopar:Npn \doc_macro_single #1 {
+ \int_incr:N \l_doc_macro_int
+ \tl_set:Nx \saved@macroname { \token_to_str:N #1 }
+ \topsep\MacroTopsep
+ \trivlist
+ \cs_set_nopar:Npn \makelabel ##1 { \llap{##1} }
+ \if@inlabel
+ \cs_set_eq:NN \@tempa \@empty
+ \count@ \macro@cnt
+ \loop \ifnum\count@>\z@
+ \cs_set_nopar:Npx \@tempa{\@tempa\hbox{\strut}}
+ \advance\count@\m@ne
+ \repeat
+ \cs_set_nopar:Npx \makelabel ##1 {
+ \llap{\vtop to\baselineskip {\@tempa\hbox{##1}\vss}}
+ }
+ \advance \macro@cnt \@ne
+ \else
+ \macro@cnt \@ne
+ \fi
+
+ \bool_if:NT \l_doc_macro_aux_bool {
+ \cs_set_eq:NN \doc_macroname_prefix:n \doc_typeset_aux:n
+ }
+ \bool_if:NT \l_doc_macro_TF_bool {
+ \cs_set_eq:NN \doc_macroname_suffix: \doc_typeset_TF:
+ }
+
+ \bool_if:NF \l_doc_macro_aux_bool {
+ \tl_gset:Nx \l_doc_macro_tl { \tl_to_str:n {#1} }
+ \exp_args:NNf \tl_greplace_all_in:Nnn \l_doc_macro_tl {\token_to_str:N _} {/}
+ \exp_args:NNf \tl_greplace_all_in:Nnn \l_doc_macro_tl {\@backslashchar} {}
+ }
+
+ \use:x {
+ \exp_not:N \item [ \exp_not:N \doc_print_macroname:n {
+ \tl_to_str:n {#1}
+ }]
+ }
+ \global\advance \c@CodelineNo \@ne
+
+ \bool_if:NF \l_doc_macro_aux_bool {
+ \bool_if:NTF \l_doc_macro_TF_bool {
+ \seq_gput_right:Nx \g_doc_macros_seq { \tl_to_str:n { #1 TF } }
+ \seq_gput_right:Nx \g_doc_macros_seq { \tl_to_str:n { #1 T } }
+ \seq_gput_right:Nx \g_doc_macros_seq { \tl_to_str:n { #1 F } }
+ }{
+ \seq_gput_right:Nx \g_doc_macros_seq { \tl_to_str:n {#1} }
+ }
+ }
+ \bool_if:NTF \l_doc_macro_TF_bool {
+ \SpecialMainIndex{#1 TF}\nobreak
+ \DoNotIndex{#1 TF}
+ }{
+ \SpecialMainIndex{#1}\nobreak
+ \DoNotIndex{#1}
+ }
+
+ \global\advance \c@CodelineNo \m@ne
+ \ignorespaces
+}
+% \end{macrocode}
+%
+% \begin{macro}{\doc_print_macroname:n}
+% \begin{macrocode}
+\tl_clear:N \l_doc_macro_tl
+\cs_set_nopar:Npn \doc_print_macroname:n #1 {
+ \strut
+ \int_compare:nTF { \tl_elt_count:n {#1} <= 28 }
+ { \MacroFont } { \MacroLongFont }
+
+ % INEFFICIENT: (!)
+ \exp_args:NNx \seq_if_in:NnTF \g_doc_functions_seq
+ { #1 \bool_if:NT \l_doc_macro_TF_bool { \tl_to_str:n {TF} } }
+ {
+ \hyperref [doc/function/\l_doc_macro_tl]
+ }
+ { \use:n }
+ {
+ \doc_macroname_prefix:n {#1} \doc_macroname_suffix: \ % space!
+ }
+}
+% \end{macrocode}
+% \end{macro}
+% \end{environment}
+%
+% \begin{macro}{\MacroLongFont}
+% \begin{macrocode}
+\providecommand \MacroLongFont {
+ \fontfamily{lmtt}\fontseries{lc}\small
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\doc_typeset_TF:,\doc_typeset_aux:n}
+% Used by \cs{doc_macro_single} and \cs{doc_showmacro_aux_ii:w} to typeset
+% conditionals and auxiliary functions.
+% \begin{macrocode}
+\cs_set_nopar:Npn \doc_typeset_TF: {
+ \itshape TF%
+ \makebox[0pt][r]{%
+ \color[gray]{0.5}
+ \underline { \phantom{\itshape TF} \kern-0.1em }
+ }
+}
+\cs_set_nopar:Npn \doc_typeset_aux:n #1 {
+ {\color[gray]{0.5} #1}
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\doc_print_testfile:n}
+% Used to show that a macro has a test, somewhere.
+% \begin{macrocode}
+\DeclareDocumentCommand \doc_print_testfile:n {m} {
+ \bool_set_true:N \l_doc_tested_bool
+ \tl_if_eq:nnF {#1} {*} {
+ \seq_if_in:NnF \g_doc_testfiles_seq {#1}
+ {
+ \par{\footnotesize(\textit{
+ The~ test~ suite~ for~ this~ command,~ and~ others~ in~ this~ file,~ is~ \textsf{#1}}.
+ )\par}
+ \seq_gput_right:Nn \g_doc_testfiles_seq {#1}
+ }
+ }
+}
+\seq_new:N \g_doc_testfiles_seq
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\TestFiles}
+% \begin{macrocode}
+\DeclareDocumentCommand \TestFiles {m} {
+ \par
+ {\itshape
+ The~ following~ test~ files~ are~ used~ for~ this~ code:~ \textsf{#1}.
+ }
+ \par\ignorespaces
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\UnitTested}
+% \begin{macrocode}
+\DeclareDocumentCommand \UnitTested {} {
+ \testfile*
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\TestMissing}
+% \begin{macrocode}
+\cs_generate_variant:Nn \prop_gput:Nnn {NVx}
+\prop_new:N \g_doc_missing_tests_prop
+\DeclareDocumentCommand \TestMissing {m} {
+ \prop_if_in:NVTF \g_doc_missing_tests_prop \l_doc_macro_input_clist
+ {
+ \prop_get:NVN \g_doc_missing_tests_prop \l_doc_macro_input_clist \l_tmpa_tl
+ \prop_gput:NVx \g_doc_missing_tests_prop \l_doc_macro_input_clist
+ {
+ *~ \l_tmpa_tl
+ ^^J \exp_not:n {\space\space\space\space\space\space}
+ *~ #1
+ }
+ }
+ { \prop_gput:NVn \g_doc_missing_tests_prop \l_doc_macro_input_clist {#1} }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\endmacro}
+% \begin{macrocode}
+\int_new:N \g_doc_nested_macro_int
+\cs_set:Nn \doc_texttt_comma:n {\,,~\texttt{#1}}
+\cs_set:Npn \endmacro {
+ \int_compare:nT {\g_doc_nested_macro_int<1}
+ {
+ \par\nobreak{\footnotesize(\emph{
+ End~ definition~ for~
+ \prg_case_int:nnn { \clist_length:N \l_doc_macro_input_clist }
+ {
+ {1} { \texttt{ \clist_use:N \l_doc_macro_input_clist }. }
+ {2}
+ {
+ \tl_set:Nx \l_clist_first_tl { \clist_item:Nn \l_doc_macro_input_clist {0} }
+ \tl_set:Nx \l_clist_last_tl { \clist_item:Nn \l_doc_macro_input_clist {1} }
+ \texttt{\l_clist_first_tl}\,~ and~ \texttt{\l_clist_last_tl}\,.
+ }
+ {3}
+ {
+ \tl_set:Nx \l_clist_first_tl { \clist_item:Nn \l_doc_macro_input_clist {0} }
+ \tl_set:Nx \l_clist_mid_tl { \clist_item:Nn \l_doc_macro_input_clist {1} }
+ \tl_set:Nx \l_clist_last_tl { \clist_item:Nn \l_doc_macro_input_clist {2} }
+ \texttt{\l_clist_first_tl}\,,~
+ \texttt{\l_clist_mid_tl}\,,~
+ and~ \texttt{\l_clist_last_tl}\,.
+ }
+ }
+ {
+ \tl_set:Nx \l_clist_first_tl { \clist_item:Nn \l_doc_macro_input_clist {0} }
+ \texttt{\l_clist_first_tl}\,~and~others.
+ }
+ \bool_if:nT {
+ !\l_doc_macro_aux_bool &&
+ !\l_doc_macro_internal_bool &&
+ \int_compare_p:n {\g_doc_nested_macro_int<1}
+ }
+ {
+ \int_compare:nNnTF \l_doc_macro_int=1 {~This~} {~These~}
+ \bool_if:NTF \l_doc_macro_var_bool{variable}{function}
+ \int_compare:nNnTF \l_doc_macro_int=1 {~is~}{s~are~}
+ documented~on~page~
+ \exp_args:Nx\pageref{doc/function/\l_doc_macro_tl}.
+ }
+ })\par}
+ }
+ \bool_if:nT
+ { \g_doc_checktest_bool &&
+ !( \l_doc_macro_aux_bool || \l_doc_macro_var_bool ) &&
+ !\l_doc_tested_bool
+ }
+ {
+ \seq_gput_right:Nx \g_doc_not_tested_seq
+ {
+ \l_doc_macro_input_clist
+ \bool_if:NT \l_doc_macro_pTF_bool {~(pTF)}
+ \bool_if:NT \l_doc_macro_TF_bool {~(TF)}
+ }
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\DescribeOption}
+% For describing package options. Due to Joseph Wright.
+% Name/usage might change soon.
+% \begin{macrocode}
+\newcommand*{\DescribeOption}{
+ \leavevmode
+ \@bsphack
+ \begingroup
+ \MakePrivateLetters
+ \Describe@Option
+}
+\newcommand*{\Describe@Option}[1]{
+ \endgroup
+ \marginpar{
+ \raggedleft
+ \PrintDescribeEnv{#1}
+ }
+ \SpecialOptionIndex{#1}
+ \@esphack
+ \ignorespaces
+}
+\newcommand*{\SpecialOptionIndex}[1]{
+ \@bsphack
+ \begingroup
+ \HD@target
+ \let\HDorg@encapchar\encapchar
+ \edef\encapchar usage{
+ \HDorg@encapchar hdclindex{\the\c@HD@hypercount}{usage}
+ }
+ \index{
+ #1\actualchar{\protect\ttfamily#1}~(option)
+ \encapchar usage
+ }
+ \index{
+ options:\levelchar#1\actualchar{\protect\ttfamily#1}
+ \encapchar usage
+ }
+ \endgroup
+ \@esphack
+}
+% \end{macrocode}
+% \end{macro}
+%
+% Here are some definitions for additional markup that will help to
+% structure your documentation.
+%
+% \begin{environment}{danger}
+% \begin{environment}{ddanger}
+% \begin{syntax}
+% |\begin{[d]danger}|\\
+% dangerous code\\
+% |\end{[d]danger}|
+% \end{syntax}
+%
+% \begin{danger}
+% Provides a danger bend, as known from the \TeX{}book.
+% \end{danger}
+% The actual character from the font |manfnt|:
+% \begin{macrocode}
+\font\manual=manfnt
+\cs_set_nopar:Npn \dbend { {\manual\char127} }
+% \end{macrocode}
+%
+% Defines the single danger bend. Use it whenever there is a feature in your
+% package that might be tricky to use.
+% FIXME: Has to be fixed when in combination with a macro-definition.
+% \begin{macrocode}
+\newenvironment {danger} {
+ \begin{trivlist}\item[]\noindent
+ \begingroup\hangindent=2pc\hangafter=-2
+ \cs_set_nopar:Npn \par{\endgraf\endgroup}
+ \hbox to0pt{\hskip-\hangindent\dbend\hfill}\ignorespaces
+}{
+ \par\end{trivlist}
+}
+% \end{macrocode}
+%
+% \begin{ddanger}
+% Use the double danger bend if there is something which could cause serious
+% problems when used in a wrong way. Better the normal user does not know
+% about such things.
+% \end{ddanger}
+% \begin{macrocode}
+\newenvironment {ddanger} {
+ \begin{trivlist}\item[]\noindent
+ \begingroup\hangindent=3.5pc\hangafter=-2
+ \cs_set_nopar:Npn \par{\endgraf\endgroup}
+ \hbox to0pt{\hskip-\hangindent\dbend\kern2pt\dbend\hfill}\ignorespaces
+}{
+ \par\end{trivlist}
+}
+% \end{macrocode}
+% \end{environment}
+% \end{environment}
+%
+% \subsection{Documenting templates}
+%
+% \begin{macrocode}
+\newenvironment{TemplateInterfaceDescription}[1]
+ {\subsection{The~object~type~`#1'}%
+ \begingroup
+ \@beginparpenalty\@M
+ \description
+ \def\TemplateArgument##1##2{\item[Arg:~##1]##2\par}%
+ \def\TemplateSemantics{\enddescription\endgroup
+ \subsubsection*{Semantics:}}%
+ }
+ {\par\bigskip}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\newenvironment{TemplateDescription}[2]
+ {\subsection{The~template~`#2'~(object~type~#1)}%
+ \subsubsection*{Attributes:}%
+ \begingroup
+ \@beginparpenalty\@M
+ \description
+ \def\TemplateKey##1##2##3##4{\item[##1~(##2)]##3%
+ \ifx\TemplateKey##4\TemplateKey\else
+% \hskip0ptplus3em\penalty-500\hskip 0pt plus 1filll Default:~##4%
+ \hfill\penalty500\hbox{}\hfill Default:~##4%
+ \nobreak\hskip-\parfillskip\hskip0pt\relax
+ \fi
+ \par}%
+ \def\TemplateSemantics{\enddescription\endgroup
+ \subsubsection*{Semantics~\&~Comments:}}%
+ }
+ {\par\bigskip}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\newenvironment{InstanceDescription}[4][xxxxxxxxxxxxxxx]
+ {\subsubsection{The~instance~`#3'~(template~#2/#4)}%
+ \subsubsection*{Attribute~values:}%
+ \begingroup
+ \@beginparpenalty\@M
+ \def\InstanceKey##1##2{\>\textbf{##1}\>##2\\}%
+ \def\InstanceSemantics{\endtabbing\endgroup
+ \vskip-30pt\vskip0pt
+ \subsubsection*{Layout~description~\&~Comments:}}%
+ \tabbing
+ xxxx\=#1\=\kill
+ }
+ {\par\bigskip}
+% \end{macrocode}
+%
+% \subsection{Inheriting doc}
+%
+% Code here is taken from \pkg{doc}, stripped of comments and translated
+% into \pkg{expl3} syntax. New features are added in various places.
+%
+% \begin{macro}{\StopEventually,\Finale,\AlsoImplementation,\OnlyDescription}
+% \begin{macrocode}
+\bool_new:N \g_doc_implementation_bool
+\cs_set_nopar:Npn \AlsoImplementation {
+ \bool_set_true:N \g_doc_implementation_bool
+ \cs_set:Npn \StopEventually ##1 {
+ \@bsphack
+ \cs_gset_nopar:Npn \Finale { ##1 \check@checksum }
+ \init@checksum
+ \@esphack
+ }
+}
+\AlsoImplementation
+\cs_set_nopar:Npn \OnlyDescription {
+ \@bsphack
+ \bool_set_false:N \g_doc_implementation_bool
+ \cs_set:Npn \StopEventually ##1 { ##1 \endinput }
+ \@esphack
+}
+\cs_set_eq:NN \Finale \relax
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+\cs_set_nopar:Npn \partname{File}
+% \end{macrocode}
+%
+% \begin{macro}{\DocInput}
+% From \pkg{doc}. Now accepts comma-list input (who has commas in filenames?).
+% \begin{macrocode}
+\clist_new:N \g_docinput_clist
+\cs_set:Npn \DocInput #1 {
+ \clist_map_inline:nn {#1} {
+ \clist_put_right:Nn \g_docinput_clist {##1}
+ \MakePercentIgnore
+ \input{##1}
+ \MakePercentComment
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\DocInputAgain}
+% Uses "\g_docinput_clist" to re-input whatever's already been "\DocInput"-ed until now.
+% May be used multiple times.
+% \begin{macrocode}
+\cs_set:Npn \DocInputAgain {
+ \clist_map_inline:Nn \g_docinput_clist {
+ \MakePercentIgnore
+ \input{##1}
+ \MakePercentComment
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\DocInclude}
+% More or less exactly the same as |\include|, but uses |\DocInput|
+% on a |dtx| file, not |\input| on a |tex| file.
+% \begin{macrocode}
+\cs_set_nopar:Npn \partname{File}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\newcommand*{\DocInclude}[1]{%
+ \relax\clearpage
+ \docincludeaux
+ \IfFileExists{#1.fdd}{
+ \cs_set_nopar:Npn \currentfile{#1.fdd}
+ }{
+ \cs_set_nopar:Npn \currentfile{#1.dtx}
+ }
+ \ifnum\@auxout=\@partaux
+ \@latexerr{\string\include\space cannot~be~nested}\@eha
+ \else
+ \@docinclude #1
+ \fi
+}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_set_nopar:Npn \@docinclude #1 {
+ \clearpage
+ \immediate\write\@mainaux{\string\@input{#1.aux}}
+ \@tempswatrue
+ \if@partsw
+ \@tempswafalse
+ \cs_set_nopar:Npx \@tempb{#1}
+ \@for\@tempa:=\@partlist\do{
+ \ifx\@tempa\@tempb\@tempswatrue\fi
+ }
+ \fi
+ \if@tempswa
+ \cs_set_eq:NN \@auxout\@partaux
+ \immediate\openout\@partaux #1.aux
+ \immediate\write\@partaux{\relax}
+ \cs_set_eq:NN \@ltxdoc@PrintIndex\PrintIndex
+ \cs_set_eq:NN \PrintIndex\relax
+ \cs_set_eq:NN \@ltxdoc@PrintChanges\PrintChanges
+ \cs_set_eq:NN \PrintChanges\relax
+ \cs_set_eq:NN \@ltxdoc@theglossary\theglossary
+ \cs_set_eq:NN \@ltxdoc@endtheglossary\endtheglossary
+ \part{\currentfile}
+ {
+ \cs_set_eq:NN \ttfamily\relax
+ \cs_gset_nopar:Npx \filekey{\filekey, \thepart={\ttfamily\currentfile}}
+ }
+ \DocInput{\currentfile}
+ \cs_set_eq:NN \PrintIndex\@ltxdoc@PrintIndex
+ \cs_set_eq:NN \PrintChanges\@ltxdoc@PrintChanges
+ \cs_set_eq:NN \theglossary\@ltxdoc@theglossary
+ \cs_set_eq:NN \endtheglossary\@ltxdoc@endtheglossary
+ \clearpage
+ \@writeckpt{#1}
+ \immediate\closeout\@partaux
+ \else
+ \@nameuse{cp@#1}
+ \fi
+ \cs_set_eq:NN \@auxout\@mainaux
+}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_gset_nopar:Npn \codeline@wrindex #1 {
+ \immediate\write\@indexfile {
+ \string\indexentry{#1}
+ {\filesep\number\c@CodelineNo}
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+\cs_set_eq:NN \filesep \@empty
+% \end{macrocode}
+%
+% \begin{macro}{\docincludeaux}
+% \begin{macrocode}
+\cs_set_nopar:Npn \docincludeaux {
+ \cs_set_nopar:Npn \thepart {\alphalph{part}}
+ \cs_set_nopar:Npn \filesep {\thepart-}
+ \cs_set_eq:NN \filekey\@gobble
+ \g@addto@macro\index@prologue{
+ \cs_gset_nopar:Npn\@oddfoot{
+ \parbox{\textwidth}{
+ \strut\footnotesize
+ \raggedright{\bfseries File~Key:}~\filekey
+ }
+ }
+ \cs_set_eq:NN \@evenfoot\@oddfoot
+ }
+ \cs_gset_eq:NN \docincludeaux\relax
+ \cs_gset_nopar:Npn\@oddfoot{
+ \expandafter\ifx\csname ver@\currentfile\endcsname\relax
+ File~\thepart :~{\ttfamily\currentfile}~
+ \else
+ \GetFileInfo{\currentfile}
+ File~\thepart :~{\ttfamily\filename}~
+ Date:~\ExplFileDate\ % space
+ Version~\ExplFileVersion
+ \fi
+ \hfill\thepage
+ }
+ \cs_set_eq:NN \@evenfoot \@oddfoot
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{At end document}
+%
+% Print all defined and documented macros/functions.
+%
+% \begin{macrocode}
+\seq_new:N \g_doc_functions_seq
+\seq_new:N \g_doc_macros_seq
+\seq_new:N \g_doc_not_tested_seq
+% \end{macrocode}
+%
+% \begin{macrocode}
+\iow_open:Nn \g_write_func_stream { \jobname.cmds }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_new_nopar:Npn \doc_show_functions_defined: {
+ \bool_if:nT { \g_doc_implementation_bool && \g_doc_checkfunc_bool } {
+ \typeout{ ======================================== ^^J }
+
+ \tl_clear:N \l_tmpa_tl
+ \seq_map_inline:Nn \g_doc_functions_seq {
+ \seq_if_in:NnT \g_doc_macros_seq {##1} {
+ \tl_put_right:Nn \l_tmpa_tl { ##1 ^^J }
+ \iow_now:Nn \g_write_func_stream { ##1 }
+ }
+ }
+ \iow_close:N \g_write_func_stream
+ \doc_functions_typeout:n {
+ Functions~both~documented~and~defined:^^J (In~order~of~being~documented)
+ }
+
+ \seq_map_inline:Nn \g_doc_functions_seq {
+ \seq_if_in:NnF \g_doc_macros_seq {##1} {
+ \tl_put_right:Nn \l_tmpa_tl { ##1 ^^J }
+ }
+ }
+ \doc_functions_typeout:n { Functions~documented~but~not~defined: }
+
+ \seq_map_inline:Nn \g_doc_macros_seq {
+ \seq_if_in:NnF \g_doc_functions_seq {##1} {
+ \tl_put_right:Nn \l_tmpa_tl { ##1 ^^J }
+ }
+ }
+ \doc_functions_typeout:n { Functions~defined~but~not~documented: }
+
+ \typeout{ ======================================== }
+ }
+}
+\AtEndDocument{ \doc_show_functions_defined: }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_set_nopar:Npn \doc_functions_typeout:n #1 {
+ \tl_if_empty:NF \l_tmpa_tl {
+ \typeout{
+ -------------------------------------- ^^J #1 ^^J
+ -------------------------------------- ^^J \l_tmpa_tl
+ }
+ \tl_clear:N \l_tmpa_tl
+ }
+}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_new:Npn \doc_show_not_tested: {
+ \bool_if:NT \g_doc_checktest_bool
+ {
+ \bool_if:nT { !(\seq_if_empty_p:N \g_doc_not_tested_seq) ||
+ !(\prop_if_empty_p:N \g_doc_missing_tests_prop) }
+ {
+ \tl_clear:N \l_tmpa_tl
+ \prop_if_empty:NF \g_doc_missing_tests_prop
+ {
+ \tl_put_right:Nn \l_tmpa_tl
+ {
+ ^^J^^JThe~ following~ macro(s)~ have~ incomplete~ tests:^^J
+ }
+ \prop_map_inline:Nn \g_doc_missing_tests_prop
+ {
+ \tl_put_right:Nn \l_tmpa_tl
+ {^^J\space\space\space\space ##1
+ ^^J\space\space\space\space\space\space ##2}
+ }
+ }
+ \seq_if_empty:NF \g_doc_not_tested_seq
+ {
+ \tl_put_right:Nn \l_tmpa_tl
+ {
+ ^^J^^J
+ The~ following~ macro(s)~ do~ not~ have~ any~ tests:^^J
+ }
+ \seq_map_inline:Nn \g_doc_not_tested_seq
+ {
+ \clist_map_inline:nn {##1}
+ {
+ \tl_put_right:Nn \l_tmpa_tl {^^J\space\space\space\space ####1}
+ }
+ }
+ \int_set:Nn \l_tmpa_int {\etex_interactionmode:D}
+ \errorstopmode
+ \ClassError{l3doc}{\l_tmpa_tl}{}
+ \int_set:Nn \etex_interactionmode:D {\l_tmpa_int}
+ }
+ }
+ }
+}
+\AtEndDocument{ \doc_show_not_tested: }
+% \end{macrocode}
+%
+% \subsection{Indexing}
+%
+% Fix index (for now):
+% \begin{macrocode}
+\g@addto@macro\theindex{\MakePrivateLetters}
+\cs_set:Npn \verbatimchar {&}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\setcounter{IndexColumns}{2}
+% \end{macrocode}
+%
+% Set up the Index to use "\part"
+% \begin{macrocode}
+\IndexPrologue{
+ \part*{Index}
+ \markboth{Index}{Index}
+ \addcontentsline{toc}{part}{Index}
+ The~italic~numbers~denote~the~pages~where~the~
+ corresponding~entry~is~described,~
+ numbers~underlined~point~to~the~definition,~
+ all~others~indicate~the~places~where~it~is~used.
+}
+% \end{macrocode}
+%
+%
+% \begin{macro}{\doc_special_main_index:n,\doc_special_main_index:o,\hdpgindex}
+% Heiko's replacement to play nicely with |hypdoc|:
+% \begin{macrocode}
+
+\cs_set_nopar:Npn \doc_special_main_index:n #1 {
+ \index{
+ \@gobble#1
+ \actualchar
+ \string\verb\quotechar*\verbatimchar#1\verbatimchar
+ \encapchar
+ hdpgindex{\thepage}{usage}
+ }
+}
+\cs_set_nopar:Npn \doc_special_main_index:o { \exp_args:No \doc_special_main_index:n }
+% \end{macrocode}
+% \begin{macrocode}
+\cs_set_nopar:Npn \hdpgindex #1#2#3 {
+ \csname\ifx\\#2\\relax\else#2\fi\endcsname{
+ \hyperlink{page.#1}{#3}
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+\g@addto@macro \PrintIndex { \AtEndDocument{ \typeout{^^J
+ ========================================^^J
+ Generate~the~index~by~executing^^J
+ \c_space_tl \c_space_tl \c_space_tl \c_space_tl
+ makeindex~-s~l3doc.ist~-o~\jobname.ind~\jobname.idx^^J
+ ========================================^^J
+ }}
+}
+% \end{macrocode}
+%
+% \subsection{Change history}
+%
+% Set the change history to use "\part".
+% Allow control names to be hyphenated in here...
+% \begin{macrocode}
+\GlossaryPrologue{
+ \part*{Change~History}
+ {\GlossaryParms\ttfamily\hyphenchar\font=`\-}
+ \markboth{Change~History}{Change~History}
+ \addcontentsline{toc}{part}{Change~History}
+}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\g@addto@macro \PrintChanges { \AtEndDocument{ \typeout{^^J
+ ========================================^^J
+ Generate~the~change~list~by~executing^^J
+ \c_space_tl \c_space_tl \c_space_tl \c_space_tl
+ makeindex~-s~gglo.ist~~-o~\jobname.gls~\jobname.glo^^J
+ ========================================^^J
+ }}
+}
+% \end{macrocode}
+%
+%^^A The standard \changes command modified slightly to better cope with
+%^^A this multiple file document.
+%^^A\def\changes@#1#2#3{%
+%^^A \let\protect\@unexpandable@protect
+%^^A \edef\@tempa{\noexpand\glossary{#2\space\currentfile\space#1\levelchar
+%^^A \ifx\saved@macroname\@empty
+%^^A \space
+%^^A \actualchar
+%^^A \generalname
+%^^A \else
+%^^A \expandafter\@gobble
+%^^A \saved@macroname
+%^^A \actualchar
+%^^A \string\verb\quotechar*%
+%^^A \verbatimchar\saved@macroname
+%^^A \verbatimchar
+%^^A \fi
+%^^A :\levelchar #3}}%
+%^^A \@tempa\endgroup\@esphack}
+%
+% \subsection{cfg}
+%
+% \begin{macrocode}
+\bool_if:NTF \g_doc_full_bool {
+ \RecordChanges
+ \CodelineIndex
+ \EnableCrossrefs
+ \AlsoImplementation
+}{
+ \CodelineNumbered
+ \DisableCrossrefs
+ \OnlyDescription
+}
+% \end{macrocode}
+%
+%
+% \begin{macrocode}
+%</class>
+% \end{macrocode}
+%
+%
+% \subsection{Makeindex configuration}
+%
+% The makeindex style "l3doc.ist" is used in place of the usual
+% "gind.ist" to ensure that I is used in the sequence I J K
+% not I II II, which would be the default makeindex behaviour.
+%
+% Will: Do we need this?
+%
+% \begin{macrocode}
+%<*docist>
+actual '='
+quote '!'
+level '#'
+preamble
+"\n \\begin{theindex} \n \\makeatletter\\scan@allowedfalse\n"
+postamble
+"\n\n \\end{theindex}\n"
+item_x1 "\\efill \n \\subitem "
+item_x2 "\\efill \n \\subsubitem "
+delim_0 "\\pfill "
+delim_1 "\\pfill "
+delim_2 "\\pfill "
+% The next lines will produce some warnings when
+% running Makeindex as they try to cover two different
+% versions of the program:
+lethead_prefix "{\\bfseries\\hfil "
+lethead_suffix "\\hfil}\\nopagebreak\n"
+lethead_flag 1
+heading_prefix "{\\bfseries\\hfil "
+heading_suffix "\\hfil}\\nopagebreak\n"
+headings_flag 1
+
+% and just for source3:
+% Remove R so I is treated in sequence I J K not I II III
+page_precedence "rnaA"
+%</docist>
+% \end{macrocode}
+%
+% \section{Testing}
+%\ExplSyntaxOn
+%\cs_set_eq:NN\g_saved_doc_functions_seq\g_doc_functions_seq
+%\cs_set_eq:NN\g_saved_doc_macros_seq\g_doc_macros_seq
+%\ExplSyntaxOff
+%
+% \begin{function}{\example_foo:N|\example_foo:c}
+% \begin{syntax}
+% "\example_foo:N" <arg1>
+% \end{syntax}
+% <0123456789> <\0\1\2\3\4\5\6\7\8\9> \Arg{arg1} ":("
+% \end{function}
+%
+% \begin{function}{ \foo | \foo: | \foo:x | \barrz: }
+% \begin{syntax}
+% "\example_foo:N" <arg1>
+% \end{syntax}
+% <0123456789> <\0\1\2\3\4\5\6\7\8\9>
+% \end{function}
+%
+% \begin{function}{\foo:N / (TF) | \foo_if:c / (TF) (EXP)}
+% Test.
+% \end{function}
+%
+% \begin{function}[EXP]{\fffoo:N}
+% Test.
+% \end{function}
+% \begin{function}[TF]{\ffffoo:N}
+% Test.
+% \end{function}
+% \begin{function}[pTF]{\ffoo:N}
+% Test.
+% \end{function}
+%
+% \begin{function}{ \bar / (EXP) | \bar: / (EXP) | \bar:x / (EXP) | }
+% \begin{syntax}
+% "\example_foo:N" <arg1>
+% \end{syntax}
+% <0123456789> <\0\1\2\3\4\5\6\7\8\9>
+% \end{function}
+%
+% \begin{macro}{ \foo , \foo: , \foo:x }
+% Testing.
+% \end{macro}
+%
+% \bigskip\bigskip
+%
+% \begin{macro}[aux]{ \foo_aux: }
+% Testing.
+% \end{macro}
+%
+% \bigskip\bigskip
+%
+% \begin{macro}[TF]{ \foo_if:c }
+% Testing.
+% \end{macro}
+%
+% \begin{macro}[internal]{ \foo_if:d }
+% Testing.
+% \end{macro}
+%
+% \bigskip\bigskip
+%
+% \begin{macro}{\aaaa_bbbb_cccc_dddd_eeee_ffff_gggg_hhhh}
+% Long macro names need to be printed in a shorter font.
+% \begin{macrocode}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\c_minus_one,
+% \c_zero,
+% \c_one,
+% \c_two,
+% \c_three,
+% \c_four,
+% \c_five,
+% \c_six,
+% \c_seven,
+% \c_eight,
+% \c_nine,
+% \c_ten,
+% \c_eleven,
+% \c_sixteen,
+% \c_thirty_two,
+% \c_hundred_one,
+% \c_twohundred_fifty_five,
+% \c_twohundred_fifty_six,
+% \c_thousand,
+% \c_ten_thousand,
+% \c_ten_thousand_one}
+% \begin{arguments}
+% \item name
+% \item parameters
+% \end{arguments}
+% Another test.
+% \end{macro}
+%
+%
+%\ExplSyntaxOn
+%\cs_set_eq:NN\g_doc_functions_seq\g_saved_doc_functions_seq
+%\cs_set_eq:NN\g_doc_macros_seq\g_saved_doc_macros_seq
+%\ExplSyntaxOff
+%
+%
+% \subsection{Macros}
+% \raggedright
+% \ExplSyntaxOn
+% \seq_map_inline:Nn \g_doc_macros_seq { `\texttt{#1}' \quad }
+% \ExplSyntaxOff
+%
+% \subsection{Functions}
+% \ExplSyntaxOn
+% \seq_map_inline:Nn \g_doc_functions_seq { `\texttt{#1}' \quad }
+% \ExplSyntaxOff
+%
+% \end{implementation}
+%
+% \PrintIndex
+%
+% \endinput
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3expan.dtx b/Master/texmf-dist/source/latex/l3kernel/l3expan.dtx
new file mode 100644
index 00000000000..5b37fd49aaf
--- /dev/null
+++ b/Master/texmf-dist/source/latex/l3kernel/l3expan.dtx
@@ -0,0 +1,1416 @@
+% \iffalse meta-comment
+%
+%% File: l3expan.dtx Copyright (C) 1990-2011 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 "expl3 bundle" (The Work in LPPL)
+%% and all files in that bundle must be distributed together.
+%%
+%% The released version of this bundle is available from CTAN.
+%%
+%% -----------------------------------------------------------------------
+%%
+%% The development version of the bundle can be found at
+%%
+%% http://www.latex-project.org/svnroot/experimental/trunk/
+%%
+%% for those people who are interested.
+%%
+%%%%%%%%%%%
+%% NOTE: %%
+%%%%%%%%%%%
+%%
+%% Snapshots taken from the repository represent work in progress and may
+%% not work or may contain conflicting material! We therefore ask
+%% people _not_ to put them into distributions, archives, etc. without
+%% prior consultation with the LaTeX3 Project.
+%%
+%% -----------------------------------------------------------------------
+%
+%<*driver|package>
+\RequirePackage{l3names}
+\GetIdInfo$Id: l3expan.dtx 2480 2011-06-20 17:25:23Z bruno $
+ {L3 Experimental argument expansion}
+%</driver|package>
+%<*driver>
+\documentclass[full]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3expan} package\\ Argument expansion^^A
+% \thanks{This file describes v\ExplFileVersion,
+% last revised \ExplFileDate.}^^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 \ExplFileDate}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% This module provides generic methods for expanding \TeX{} arguments in a
+% systematic manner. The functions in this module all have prefix |exp|.
+%
+% Not all possible variations are implemented for every base
+% function. Instead only those that are used within the \LaTeX3 kernel
+% or otherwise seem to be of general interest are implemented.
+% Consult the module description to find out which functions are
+% actually defined. The next section explains how to define missing
+% variants.
+%
+% \section{Defining new variants}
+%
+% The definition of variant forms for base functions may be necessary
+% when writing new functions or when applying a kernel function in a
+% situation that we haven't thought of before.
+%
+% Internally preprocessing of arguments is done with functions from the
+% |\exp_| module. They all look alike, an example would be
+% |\exp_args:NNo|. This function has three arguments, the first and the
+% second are a single tokens the third argument gets
+% expanded once. If |\seq_gpush:No| was not defined the example
+% above could be coded in the following way:
+% \begin{verbatim}
+% \exp_args:NNo \seq_gpush:Nn
+% \g_file_name_stack
+% \l_tmpa_tl
+% \end{verbatim}
+% In other words, the first argument to |\exp_args:NNo| is the base
+% function and the other arguments are preprocessed and then passed to
+% this base function. In the example the first argument to the base
+% function should be a single token which is left unchanged while the
+% second argument is expanded once. From this example we can also see
+% how the variants are defined. They just expand into the appropriate
+% |\exp_| function followed by the desired base function, \emph{e.g.}
+% \begin{quote}
+% |\cs_new_nopar:Npn\seq_gpush:No{\exp_args:NNo\seq_gpush:Nn}|
+% \end{quote}
+% Providing variants in this way in style files is uncritical as the
+% |\cs_new_nopar:Npn| function will silently accept definitions whenever the
+% new definition is identical to an already given one. Therefore adding
+% such definition to later releases of the kernel will not make such
+% style files obsolete.
+%
+% The steps above may be automated by using the function
+% |\cs_generate_variant:Nn|, described next.
+%
+% \section{Methods for defining variants}
+%
+% \begin{function}{\cs_generate_variant:Nn}
+% \begin{syntax}
+% \cs{cs_generate_variant:Nn} \meta{parent control sequence}
+% ~~\Arg{variant argument specifiers}
+% \end{syntax}
+% This function is used to define argument-specifier variants of the
+% \meta{parent control sequence} for \LaTeX3 code-level macros. The
+% \meta{parent control sequence} is first separated into the
+% \meta{base name} and \meta{original argument specifier}. The
+% comma-separated list of \meta{variant argument specifiers} is
+% then used to define variants of the
+% \meta{original argument specifier} where these are not already
+% defined. For each \meta{variant} given, a function is created
+% which will expand its arguments as detailed and pass them
+% to the \meta{parent control sequence}. So for example
+% \begin{verbatim}
+% \cs_set:Npn \foo:Nn #1#2 { code here }
+% \cs_generate_variant:Nn \foo:Nn { c }
+% \end{verbatim}
+% will create a new function \cs{foo:cn} which will expand its first
+% argument into a control sequence name and pass the result to
+% \cs{foo:Nn}. Similarly
+% \begin{verbatim}
+% \cs_generate_variant:Nn \foo:Nn { NV , cV }
+% \end{verbatim}
+% would generate the functions \cs{foo:NV} and \cs{foo:cV} in the
+% same way. The \cs{cs_generate_variant:Nn} function can only be
+% applied if the \meta{parent control sequence} is already defined. If
+% the \meta{parent control sequence} is protected then the new sequence
+% will also be protected. The \meta{variant} is created globally, as
+% is any \cs{exp_args:N\meta{variant}} function needed to carry out
+% the expansion.
+% \end{function}
+%
+% \section{Introducing the variants}
+%
+% The available internal functions for argument expansion come in two
+% flavours, some of them are faster then others. Therefore it is usually
+% best to follow the following guidelines when defining new functions
+% that are supposed to come with variant forms:
+% \begin{itemize}
+% \item
+% Arguments that might need expansion should come first in the list of
+% arguments to make processing faster.
+% \item
+% Arguments that should consist of single tokens should come first.
+% \item
+% Arguments that need full expansion (\emph{i.e.}, are denoted
+% with |x|) should be avoided if possible as they can not be
+% processed expandably, \emph{i.e.}, functions of this type will
+% not work correctly in arguments that are itself subject to |x|
+% expansion.
+% \item
+% In general, unless in the last position, multi-token arguments
+% |n|, |f|, and |o| will need special processing which is not fast.
+% Therefore it is best to use the optimized functions, namely
+% those that contain only |N|, |c|, |V|, and |v|, and, in the last
+% position, |o|, |f|, with possible trailing |N| or |n|, which are
+% not expanded.
+% \end{itemize}
+%
+% The |V| type returns the value of a register, which can be one of
+% |tl|, |num|, |int|, |skip|, |dim|, |toks|, or built-in \TeX{}
+% registers. The |v| type is the same except it first creates a
+% control sequence out of its argument before returning the
+% value. This recent addition to the argument specifiers may shake
+% things up a bit as most places where |o| is used will be replaced by
+% |V|. The documentation you are currently reading will therefore
+% require a fair bit of re-writing.
+%
+% In general, the programmer should not need to be concerned with
+% expansion control. When simply using the content of a variable,
+% functions with a |V| specifier should be used. For those referred to by
+% (cs)name, the |v| specifier is available for the same purpose. Only when
+% specific expansion steps are needed, such as when using delimited
+% arguments, should the lower-level functions with |o| specifiers be employed.
+%
+% The |f| type is so special that it deserves an example.
+% Let's pretend we want to set |\aaa| equal to the control sequence
+% stemming from turning |b \l_tmpa_tl b| into a control
+% sequence. Furthermore we want to store the execution of it in a
+% \meta{tl~var}. In this example we assume |\l_tmpa_tl| contains
+% the text string |lur|. The straightforward approach is
+% \begin{quote}
+% |\tl_set:No \l_tmpb_tl {\cs_set_eq:Nc \aaa { b \l_tmpa_tl b } }|
+% \end{quote}
+% Unfortunately this only puts
+% |\exp_args:NNc \cs_set_eq:NN \aaa {b \l_tmpa_tl b}| into |\l_tmpb_tl|
+% and not |\cs_set_eq:NwN \aaa = \blurb| as we probably wanted. Using
+% |\tl_set:Nx| is not an option as that will die horribly. Instead
+% we can do a
+% \begin{quote}
+% |\tl_set:Nf \l_tmpb_tl {\cs_set_eq:Nc \aaa { b \l_tmpa_tl b } }|
+% \end{quote}
+% which puts the desired result in |\l_tmpb_tl|. It requires
+% |\toks_set:Nf| to be defined as
+% \begin{quote}
+% |\cs_set_nopar:Npn \tl_set:Nf { \exp_args:NNf \tl_set:Nn }|
+% \end{quote}
+% If you use this type of expansion in conditional processing then
+% you should stick to using |TF| type functions only as it does not
+% try to finish any |\if... \fi:| itself!
+%
+% \section{Manipulating the first argument}
+%
+% These functions are described in detail: expansion of multiple tokens follows
+% the same rules but is described in a shorter fashion.
+%
+% \begin{function}[EXP]{\exp_args:No}
+% \begin{syntax}
+% \cs{exp_args:No} \meta{function} \Arg{tokens} \Arg{tokens2} ...
+% \end{syntax}
+% This function absorbs two arguments (the \meta{function} name and
+% the \meta{tokens}). The \meta{tokens} are expanded once, and the result
+% is inserted in braces into the input stream \emph{after} reinsertion
+% of the \meta{function}. Thus the \meta{function} may take more than
+% one argument: all others will be left unchanged.
+% \end{function}
+%
+% \begin{function}[EXP]{\exp_args:Nc, \exp_args:cc}
+% \begin{syntax}
+% \cs{exp_args:Nc} \meta{function} \Arg{tokens} \Arg{tokens2} ...
+% \end{syntax}
+% This function absorbs two arguments (the \meta{function} name and
+% the \meta{tokens}). The \meta{tokens} are expanded until only characters
+% remain, and are then turned into a control sequence. (An internal error
+% will occur if such a conversion is not possible). The result
+% is inserted into the input stream \emph{after} reinsertion
+% of the \meta{function}. Thus the \meta{function} may take more than
+% one argument: all others will be left unchanged.
+%
+% The |:cc| variant constructs the \meta{function} name in the same
+% manner as described for the \meta{tokens}.
+% \end{function}
+%
+% \begin{function}[EXP]{\exp_args:NV}
+% \begin{syntax}
+% \cs{exp_args:NV} \meta{function} \meta{variable} \Arg{tokens2} ...
+% \end{syntax}
+% This function absorbs two arguments (the names of the \meta{function} and
+% the the \meta{variable}). The content of the \meta{variable} are recovered
+% and placed inside braces into the input stream \emph{after} reinsertion
+% of the \meta{function}. Thus the \meta{function} may take more than
+% one argument: all others will be left unchanged.
+% \end{function}
+%
+% \begin{function}[EXP]{\exp_args:Nv}
+% \begin{syntax}
+% \cs{exp_args:Nv} \meta{function} \Arg{tokens} \Arg{tokens2} ...
+% \end{syntax}
+% This function absorbs two arguments (the \meta{function} name and
+% the \meta{tokens}). The \meta{tokens} are expanded until only characters
+% remain, and are then turned into a control sequence. (An internal error
+% will occur if such a conversion is not possible). This control sequence
+% should
+% be the name of a \meta{variable}. The content of the \meta{variable} are
+% recovered and placed inside braces into the input stream \emph{after}
+% reinsertion of the \meta{function}. Thus the \meta{function} may take more
+% than one argument: all others will be left unchanged.
+% \end{function}
+%
+% \begin{function}[EXP]{\exp_args:Nf}
+% \begin{syntax}
+% \cs{exp_args:Nf} \meta{function} \Arg{tokens} \Arg{tokens2} ...
+% \end{syntax}
+% This function absorbs two arguments (the \meta{function} name and
+% the \meta{tokens}). The \meta{tokens} are fully expanded until the
+% first non-expandable token or space is found, and the result
+% is inserted in braces into the input stream \emph{after} reinsertion
+% of the \meta{function}. Thus the \meta{function} may take more than
+% one argument: all others will be left unchanged.
+% \end{function}
+%
+% \begin{function}{\exp_args:Nx}
+% \begin{syntax}
+% \cs{exp_args:Nx} \meta{function} \Arg{tokens} \Arg{tokens2} ...
+% \end{syntax}
+% This function absorbs two arguments (the \meta{function} name and
+% the \meta{tokens}) and exhaustively expands the \meta{tokens}
+% second. The result is inserted in braces into the input stream
+% \emph{after} reinsertion of the \meta{function}.
+% Thus the \meta{function} may take more
+% than one argument: all others will be left unchanged.
+% \end{function}
+%
+% \section{Manipulating two arguments}
+%
+% \begin{function}[EXP]
+% {
+% \exp_args:NNo,
+% \exp_args:NNc,
+% \exp_args:NNv,
+% \exp_args:NNV,
+% \exp_args:NNf,
+% \exp_args:Nco,
+% \exp_args:Ncf,
+% \exp_args:Ncc,
+% \exp_args:NVV
+% }
+% \begin{syntax}
+% \cs{exp_args:NNc} \meta{token1} \meta{token2} \Arg{tokens}
+% \end{syntax}
+% These optimized functions absorb three arguments and expand the second and
+% third as detailed by their argument specifier. The first argument
+% of the function is then the next item on the input stream, followed
+% by the expansion of the second and third arguments.
+% \end{function}
+%
+% \begin{function}[EXP]
+% {
+% \exp_args:Nno,
+% \exp_args:NnV,
+% \exp_args:Nnf,
+% \exp_args:Noo,
+% \exp_args:Noc,
+% \exp_args:Nff,
+% \exp_args:Nfo,
+% \exp_args:Nnc
+% }
+% \begin{syntax}
+% \cs{exp_args:Noo} \meta{token} \Arg{tokens1} \Arg{tokens2}
+% \end{syntax}
+% These functions absorb three arguments and expand the second and
+% third as detailed by their argument specifier. The first argument
+% of the function is then the next item on the input stream, followed
+% by the expansion of the second and third arguments.
+% These functions need special (slower) processing.
+% \end{function}
+%
+% \begin{function}
+% {
+% \exp_args:NNx,
+% \exp_args:Nnx,
+% \exp_args:Ncx,
+% \exp_args:Nox,
+% \exp_args:Nxo,
+% \exp_args:Nxx
+% }
+% \begin{syntax}
+% \cs{exp_args:NNx} \meta{token1} \meta{token2} \Arg{tokens}
+% \end{syntax}
+% These functions absorb three arguments and expand the second and
+% third as detailed by their argument specifier. The first argument
+% of the function is then the next item on the input stream, followed
+% by the expansion of the second and third arguments. These functions
+% are not expandable.
+% \end{function}
+%
+% \section{Manipulating three arguments}
+%
+% \begin{function}[EXP]
+% {
+% \exp_args:NNNo,
+% \exp_args:NNNV,
+% \exp_args:Nccc,
+% \exp_args:NcNc,
+% \exp_args:NcNo,
+% \exp_args:Ncco
+% }
+% \begin{syntax}
+% \cs{exp_args:NNNo} \meta{token1} \meta{token2} \meta{token3}
+% ~~\Arg{tokens}
+% \end{syntax}
+% These optimized functions absorb four arguments and expand the second, third
+% and fourth as detailed by their argument specifier. The first
+% argument of the function is then the next item on the input stream,
+% followed by the expansion of the second argument, \emph{etc}.
+% \end{function}
+%
+% \begin{function}[EXP]
+% {
+% \exp_args:NNoo,
+% \exp_args:NNno,
+% \exp_args:Nnno,
+% \exp_args:Nnnc,
+% \exp_args:Nooo,
+% }
+% \begin{syntax}
+% \cs{exp_args:NNNo} \meta{token1} \meta{token2} \meta{token3}
+% ~~\Arg{tokens}
+% \end{syntax}
+% These functions absorb four arguments and expand the second, third
+% and fourth as detailed by their argument specifier. The first
+% argument of the function is then the next item on the input stream,
+% followed by the expansion of the second argument, \emph{etc}.
+% These functions need special (slower) processing.
+% \end{function}
+%
+% \begin{function}
+% {
+% \exp_args:NNnx,
+% \exp_args:NNox,
+% \exp_args:Nnnx,
+% \exp_args:Nnox,
+% \exp_args:Noox,
+% \exp_args:Ncnx,
+% \exp_args:Nccx
+% }
+% \begin{syntax}
+% \cs{exp_args:NNnx} \meta{token1} \meta{token2} \meta{tokens1}
+% ~~\Arg{tokens2}
+% \end{syntax}
+% These functions absorb four arguments and expand the second, third
+% and fourth as detailed by their argument specifier. The first
+% argument of the function is then the next item on the input stream,
+% followed by the expansion of the second argument, \emph{etc.}
+% \end{function}
+%
+% \section{Unbraced expansion}
+%
+% \begin{function}
+% {
+% \exp_last_unbraced:Nf,
+% \exp_last_unbraced:NV,
+% \exp_last_unbraced:No,
+% \exp_last_unbraced:Nv,
+% \exp_last_unbraced:NcV,
+% \exp_last_unbraced:NNV,
+% \exp_last_unbraced:NNo,
+% \exp_last_unbraced:Nfo,
+% \exp_last_unbraced:NNNV,
+% \exp_last_unbraced:NNNo
+% }
+% \begin{syntax}
+% \cs{exp_last_unbraced:Nno} \meta{token} \meta{tokens1} \meta{tokens2}
+% \end{syntax}
+% These functions absorb the number of arguments given by their
+% specification, carry out the expansion
+% indicated and leave the the results in the input stream, with the
+% last argument not surrounded by the usual braces.
+% Of these, \cs{exp_last_unbraced:Nfo} needs special (slower) processing.
+% \end{function}
+%
+% \begin{function}[EXP]{\exp_last_two_unbraced:Noo}
+% \begin{syntax}
+% \cs{exp_last_two_unbraced:Noo} \meta{token} \meta{tokens1} \Arg{tokens2}
+% \end{syntax}
+% This function absorbs three arguments and expand the second and third
+% once. The first argument of the function is then the next item on the
+% input stream, followed by the expansion of the second and third arguments,
+% which are not wrapped in braces.
+% This function needs special (slower) processing.
+% \end{function}
+%
+% \begin{function}[EXP]{\exp_after:wN}
+% \begin{syntax}
+% \cs{exp_after:wN} \meta{token1} \meta{token2}
+% \end{syntax}
+% Carries out a single expansion of \meta{token2} prior to expansion
+% of \meta{token1}. If \meta{token2} is a \TeX{} primitive, it will
+% be executed rather than expanded, while if \meta{token2} has not
+% expansion (for example, if it is a character) then it will be left
+% unchanged. It is important to notice that \meta{token1} may be
+% \emph{any} single token, including group-opening and -closing
+% tokens (|{| or |}"| assuming normal \TeX{} category codes). Unless
+% specifically required, expansion should be carried out using an
+% appropriate argument specifier variant or the appropriate
+% \cs{exp_arg:N} function.
+% \begin{texnote}
+% This is the \TeX{} primitive \cs{expandafter} renamed.
+% \end{texnote}
+% \end{function}
+%
+% \section{Preventing expansion}
+%
+% \begin{function}{\exp_not:N}
+% \begin{syntax}
+% \cs{exp_not:N} \meta{token}
+% \end{syntax}
+% Prevents expansion of the \meta{token} in a context where it would otherwise
+% be expanded, for example an |x|-type argument.
+% \begin{texnote}
+% This is the \TeX{} \cs{noexpand} primitive.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{\exp_not:c}
+% \begin{syntax}
+% \cs{exp_not:c} \Arg{tokens}
+% \end{syntax}
+% Expands the \meta{tokens} until only unexpandable content remains, and then
+% converts this into a control sequence. Further expansion of this control
+% sequence is then inhibited.
+% \end{function}
+%
+% \begin{function}{\exp_not:n}
+% \begin{syntax}
+% \cs{exp_not:n} \Arg{tokens}
+% \end{syntax}
+% Prevents expansion of the \meta{tokens} in a context where they would
+% otherwise
+% be expanded, for example an |x|-type argument.
+% \begin{texnote}
+% This is the \eTeX{} \cs{unexpanded} primitive.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{\exp_not:V}
+% \begin{syntax}
+% \cs{exp_not:V} \meta{variable}
+% \end{syntax}
+% Recovers the content of the \meta{variable}, then prevents expansion
+% of the this material in a context where it would otherwise
+% be expanded, for example an |x|-type argument.
+% \end{function}
+%
+% \begin{function}{\exp_not:v}
+% \begin{syntax}
+% \cs{exp_not:v} \Arg{tokens}
+% \end{syntax}
+% Expands the \meta{tokens} until only unexpandable content remains, and then
+% converts this into a control sequence (which should be a \meta{variable}
+% name). The content of the \meta{variable} is recovered, and further
+% expansion is prevented in a context where it would otherwise
+% be expanded, for example an |x|-type argument.
+% \end{function}
+%
+% \begin{function}{\exp_not:o}
+% \begin{syntax}
+% \cs{exp_not:o} \Arg{tokens}
+% \end{syntax}
+% Expands the \meta{tokens} once, then prevents any further expansion in a
+% context where they would otherwise
+% be expanded, for example an |x|-type argument.
+% \end{function}
+%
+% \begin{function}[EXP]{\exp_not:f}
+% \begin{syntax}
+% \cs{exp_not:f} \meta{tokens}
+% \end{syntax}
+% Expands \meta{tokens} fully until the first unexpandable token
+% is found. Expansion then stops, and the result of the expansion
+% (including any tokens which were not expanded) is protected from
+% further expansion.
+% \end{function}
+%
+% \begin{function}[EXP]{\exp_stop_f:}
+% \begin{syntax}
+% \cs{function:f} \meta{tokens} \cs{exp_stop_f:} \meta{more tokens}
+% \end{syntax}
+% This function terminates an \texttt{f}-type expansion. Thus if
+% a function \cs{function:f} starts an \texttt{f}-type expansion
+% and all of \meta{tokens} are expandable \cs{exp_stop:f} will
+% terminate the expansion of tokens even if \meta{more tokens}
+% are also expandable. The function itself is an implicit space
+% token. Inside an \texttt{x}-type expansion, it will retain its
+% form, but when typeset it produces the underlying space (\verb*| |).
+% \end{function}
+%
+% \section{Internal functions and variables}
+%
+% \begin{variable}{\l_exp_tl}
+% The |\exp_| module has its private variables to temporarily store
+% results of the argument expansion. This is done to avoid interference
+% with other functions using temporary variables.
+% \end{variable}
+%
+% \begin{function}[EXP]{\exp_eval_register:N, \exp_eval_register:c}
+% \begin{syntax}
+% \cs{exp_eval_register:N} \meta{variable}
+% \end{syntax}
+% These functions evaluates a \meta{variable} as part of a |V| or |v|
+% expansion (respectively), preceeded by \cs{c_zero} which stops
+% the expansion of a previous \cs{tex_romannumeral:D}.
+% A \meta{variable} might exist as
+% one of two things: a parameter-less non-long, non-protected macro
+% or a built-in \TeX{} register such as |\count|.
+% \end{function}
+%
+% \begin{function}{\::n, \::N, \::c, \::o, \::f, \::x, \::v, \::V, \:::}
+% \begin{syntax}
+% |\cs_set_nopar:Npn \exp_args:Ncof { \::c \::o \::f \::: }|
+% \end{syntax}
+% Internal forms for the base expansion types. These names do \emph{not}
+% conform to the general \LaTeX3 approach as this makes them more readily
+% visible in the log and so forth.
+% \end{function}
+%
+% \begin{function}{\cs_generate_internal_variant:n}
+% \begin{syntax}
+% \cs{cs_generate_internal_variant:n} \meta{arg~spec}
+% \end{syntax}
+% Tests if the function |\exp_args:N|\meta{arg~spec} exists, and defines it
+% if it does not. The \meta{arg~spec} should be a series of one or more
+% of the letters |N|, |c|, |n|, |o|, |V|, |v|, |f| and |x|.
+% \end{function}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3expan} implementation}
+%
+% \begin{macrocode}
+%<*initex|package>
+% \end{macrocode}
+%
+% We start by ensuring that the required packages are loaded.
+% \begin{macrocode}
+%<*package>
+\ProvidesExplPackage
+ {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
+\package_check_loaded_expl:
+%</package>
+% \end{macrocode}
+%
+% \begin{macro}{\exp_after:wN}
+% \begin{macro}{\exp_not:N}
+% \begin{macro}{\exp_not:n}
+% These are defined in \pkg{l3basics}.
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{General expansion}
+%
+% In this section a general mechanism for defining functions to handle
+% argument handling is defined. These general expansion functions are
+% expandable unless |x| is used. (Any version of |x| is going to have
+% to use one of the \LaTeX3 names for |\cs_set_nopar:Npx| at some point, and
+% so is never going to be expandable.\footnote{However, some
+% primitives have certain characteristics that means that their
+% arguments undergo an \texttt{x} type expansion but the primitive
+% is in fact still expandable. We shall make it very clear when such
+% a function is expandable.})
+%
+% The definition of expansion functions with this technique happens
+% in section~\ref{sec:gendef}.
+% In section~\ref{sec:handtune} some common cases are coded by a more direct
+% method for efficiency, typically using calls to |\exp_after:wN|.
+%
+% \begin{variable}{\l_exp_tl}
+% We need a scratch token list variable.
+% We don't use |tl| methods so that \pkg{l3expan} can be loaded earlier.
+% \begin{macrocode}
+\cs_new_nopar:Npn \l_exp_tl { }
+% \end{macrocode}
+% \end{variable}
+%
+% This code uses internal functions with names that start with |\::|
+% to perform the expansions. All macros are |long| as this turned out
+% to be desirable since the tokens undergoing expansion may be
+% arbitrary user input.
+%
+% An argument manipulator |\::|\meta{Z} always has signature |#1\:::#2#3|
+% where |#1| holds the remaining argument manipulations to be performed,
+% |\:::| serves as an end marker for the list of manipulations, |#2|
+% is the carried over result of the previous expansion steps and |#3| is
+% the argument about to be processed.
+%
+% \begin{macro}[aux]{\exp_arg_next:nnn}
+% \begin{macro}[aux]{\exp_arg_next_nobrace:nnn}
+% |#1| is the result of an expansion step, |#2| is the remaining
+% argument manipulations and |#3| is the current result of the
+% expansion chain. This auxiliary function moves |#1| back after
+% |#3| in the input stream and checks if any expansion is left to
+% be done by calling |#2|. In by far the most cases we will require
+% to add a set of braces to the result of an argument manipulation
+% so it is more effective to do it directly here. Actually, so far
+% only the |c| of the final argument manipulation variants does not
+% require a set of braces.
+% \begin{macrocode}
+\cs_new:Npn \exp_arg_next:nnn #1#2#3 { #2 \::: { #3 {#1} } }
+\cs_new:Npn \exp_arg_next_nobrace:nnn #1#2#3 { #2 \::: { #3 #1 } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[int]{\:::}
+% The end marker is just another name for the identity function.
+% \begin{macrocode}
+\cs_new:Npn \::: #1 {#1}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\::n}
+% This function is used to skip an argument that doesn't need to
+% be expanded.
+% \begin{macrocode}
+\cs_new:Npn \::n #1 \::: #2#3 { #1 \::: { #2 {#3} } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\::N}
+% This function is used to skip an argument that consists of a
+% single token and doesn't need to be expanded.
+% \begin{macrocode}
+\cs_new:Npn \::N #1 \::: #2#3 { #1 \::: {#2#3} }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\::c}
+% This function is used to skip an argument that is turned into
+% as control sequence without expansion.
+% \begin{macrocode}
+\cs_new:Npn \::c #1 \::: #2#3
+ { \exp_after:wN \exp_arg_next_nobrace:nnn \cs:w #3 \cs_end: {#1} {#2} }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\::o}
+% This function is used to expand an argument once.
+% \begin{macrocode}
+\cs_new:Npn \::o #1 \::: #2#3
+ { \exp_after:wN \exp_arg_next:nnn \exp_after:wN {#3} {#1} {#2} }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\::f}
+% \begin{macro}{\exp_stop_f:}
+% This function is used to expand a token list until the first
+% unexpandable token is found. The underlying |\tex_romannumeral:D -`0|
+% expands everything in its way to find something terminating the
+% number and thereby expands the function in front of it. This
+% scanning procedure is terminated once the expansion hits
+% something non-expandable or a space. We introduce |\exp_stop_f:|
+% to mark such an end of expansion marker; in case the scanner hits
+% a number, this number also terminates the scanning and is left
+% untouched. In the example shown earlier the scanning was stopped
+% once \TeX{} had fully expanded |\cs_set_eq:Nc \aaa { b \l_tmpa_tl b }|
+% into |\cs_set_eq:NwN \aaa = \blurb| which then turned out to contain
+% the non-expandable token |\cs_set_eq:NwN|. Since the expansion of
+% |\tex_romannumeral:D -`0| is \meta{null}, we wind up with a fully
+% expanded list, only \TeX{} has not tried to execute any of the
+% non-expandable tokens. This is what differentiates this function
+% from the |x| argument type.
+% \begin{macrocode}
+\cs_new:Npn \::f #1 \::: #2#3
+ {
+ \exp_after:wN \exp_arg_next:nnn
+ \exp_after:wN { \tex_romannumeral:D -`0 #3 }
+ {#1} {#2}
+ }
+\use:nn { \cs_new_eq:NN \exp_stop_f: } { ~ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[int]{\::x}
+% This function is used to expand an argument fully.
+% \begin{macrocode}
+\cs_new_protected:Npn \::x #1 \::: #2#3
+ {
+ \cs_set_nopar:Npx \l_exp_tl { {#3} }
+ \exp_after:wN \exp_arg_next:nnn \l_exp_tl {#1} {#2}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\::v}
+% \begin{macro}[int]{\::V}
+% These functions return the value of a register, i.e., one of
+% |tl|, |num|, |int|, |skip|, |dim| and |muskip|. The |V| version
+% expects a single token whereas |v| like |c| creates a csname from
+% its argument given in braces and then evaluates it as if it was a
+% |V|. The primitive \cs{tex_romannumeral:D} sets off an expansion
+% similar to an |f| type expansion, which we will terminate using
+% \cs{c_zero}. The argument is returned in braces.
+% \begin{macrocode}
+\cs_new:Npn \::V #1 \::: #2#3
+ {
+ \exp_after:wN \exp_arg_next:nnn
+ \exp_after:wN { \tex_romannumeral:D \exp_eval_register:N #3 }
+ {#1} {#2}
+}
+\cs_new:Npn \::v # 1\::: #2#3
+ {
+ \exp_after:wN \exp_arg_next:nnn
+ \exp_after:wN { \tex_romannumeral:D \exp_eval_register:c {#3} }
+ {#1} {#2}
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[int]{\exp_eval_register:N, \exp_eval_register:c}
+% \begin{macro}[aux]{\exp_eval_error_msg:w}
+% This function evaluates a register. Now a register might exist as
+% one of two things: A parameter-less macro or a built-in \TeX{}
+% register such as |\count|. For the \TeX{} registers we have to
+% utilize a |\tex_the:D| whereas for the macros we merely have to
+% expand them once. The trick is to find out when to use
+% |\tex_the:D| and when not to. What we do here is try to find out
+% whether the token will expand to something else when hit with
+% |\exp_after:wN|. The technique is to compare the meaning of the
+% register in question when it has been prefixed with |\exp_not:N|
+% and the register itself. If it is a macro, the prefixed
+% |\exp_not:N| will temporarily turn it into the primitive
+% |\scan_stop:|.
+% \begin{macrocode}
+\cs_new_nopar:Npn \exp_eval_register:N #1
+ {
+ \exp_after:wN \if_meaning:w \exp_not:N #1 #1
+% \end{macrocode}
+% If the token was not a macro it may be a malformed variable from a
+% |c| expansion in which case it is equal to the primitive
+% |\scan_stop:|. In that case we throw an error. We could let \TeX{}
+% do it for us but that would result in the rather obscure
+% \begin{quote}
+% |! You can't use `\relax' after \the.|
+% \end{quote}
+% which while quite true doesn't give many hints as to what actually
+% went wrong. We provide something more sensible.
+% \begin{macrocode}
+ \if_meaning:w \scan_stop: #1
+ \exp_eval_error_msg:w
+ \fi:
+% \end{macrocode}
+% The next bit requires some explanation. The function must be
+% initiated by the primitive \cs{tex_romannumeral:D} and we want to
+% terminate this expansion chain by inserting the \cs{c_zero} integer
+% constant. However, we have to expand the register |#1| before we do
+% that. If it is a \TeX{} register, we need to execute the sequence
+% |\exp_after:wN \c_zero \tex_the:D #1| and if it is a macro we
+% need to execute |\exp_after:wN \c_zero #1|. We therefore issue
+% the longer of the two sequences and if the register is a macro, we
+% remove the |\tex_the:D|.
+% \begin{macrocode}
+ \else:
+ \exp_after:wN \use_i_ii:nnn
+ \fi:
+ \exp_after:wN \c_zero \tex_the:D #1
+ }
+\cs_new_nopar:Npn \exp_eval_register:c #1
+ { \exp_after:wN \exp_eval_register:N \cs:w #1 \cs_end: }
+% \end{macrocode}
+% Clean up nicely, then call the undefined control sequence. The
+% result is an error message looking like this:
+% \begin{verbatim}
+% ! Undefined control sequence.
+% \exp_eval_error_msg:w ...erroneous variable used!
+%
+% l.55 \tl_set:Nv \l_tmpa_tl {undefined_tl}
+% \end{verbatim}
+% \begin{macrocode}
+\group_begin:%
+\tex_catcode:D`\!=11\scan_stop:%
+\tex_catcode:D`\ =11\scan_stop:%
+\cs_new:Npn\exp_eval_error_msg:w#1\tex_the:D#2{%
+\fi:\fi:\exp_after:wN\c_zero\erroneous variable used!}%
+\group_end:%
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Hand-tuned definitions}
+% \label{sec:handtune}
+%
+% One of the most important features of these functions is that they
+% are fully expandable and therefore allow to prefix them with
+% |\pref_global:D| for example.
+%
+% \begin{macro}{\exp_args:No}
+% \begin{macro}{\exp_args:NNo}
+% \begin{macro}{\exp_args:NNNo}
+% Those lovely runs of expansion!
+% \begin{macrocode}
+\cs_new:Npn \exp_args:No #1#2 { \exp_after:wN #1 \exp_after:wN {#2} }
+\cs_new:Npn \exp_args:NNo #1#2#3
+ { \exp_after:wN #1 \exp_after:wN #2 \exp_after:wN {#3} }
+\cs_new:Npn \exp_args:NNNo #1#2#3#4
+ { \exp_after:wN #1 \exp_after:wN#2 \exp_after:wN #3 \exp_after:wN {#4} }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\exp_args:Nc}
+% In \pkg{l3basics}
+%\end{macro}
+%
+% \begin{macro}{\exp_args:cc, \exp_args:NNc, \exp_args:Ncc, \exp_args:Nccc}
+% Here are the functions that turn their argument into csnames but
+% are expandable.
+% \begin{macrocode}
+\cs_new:Npn \exp_args:cc #1#2
+ { \cs:w #1 \exp_after:wN \cs_end: \cs:w #2 \cs_end: }
+\cs_new:Npn \exp_args:NNc #1#2#3
+ { \exp_after:wN #1 \exp_after:wN #2 \cs:w # 3\cs_end: }
+\cs_new:Npn \exp_args:Ncc #1#2#3
+ { \exp_after:wN #1 \cs:w #2 \exp_after:wN \cs_end: \cs:w #3 \cs_end: }
+\cs_new:Npn \exp_args:Nccc #1#2#3#4
+ {
+ \exp_after:wN #1
+ \cs:w #2 \exp_after:wN \cs_end:
+ \cs:w #3 \exp_after:wN \cs_end:
+ \cs:w #4 \cs_end:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\exp_args:Nf, \exp_args:NV, \exp_args:Nv, \exp_args:Nx}
+% \begin{macrocode}
+\cs_new:Npn \exp_args:Nf #1#2
+ { \exp_after:wN #1 \exp_after:wN { \tex_romannumeral:D -`0 #2 } }
+\cs_new:Npn \exp_args:Nv #1#2
+ {
+ \exp_after:wN #1 \exp_after:wN
+ { \tex_romannumeral:D \exp_eval_register:c {#2} }
+ }
+\cs_new:Npn \exp_args:NV #1#2
+ {
+ \exp_after:wN #1 \exp_after:wN
+ { \tex_romannumeral:D \exp_eval_register:N #2 }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\exp_args:NNV,\exp_args:NNv,\exp_args:NNf,
+% \exp_args:NVV,
+% \exp_args:Ncf,\exp_args:Nco}
+% Some more hand-tuned function with three arguments.
+% If we force that an |o| argument always has braces,
+% we could implement \cs{exp_args:Nco} with less tokens
+% and only two arguments.
+% \begin{macrocode}
+\cs_new:Npn \exp_args:NNf #1#2#3
+ {
+ \exp_after:wN #1
+ \exp_after:wN #2
+ \exp_after:wN { \tex_romannumeral:D -`0 #3 }
+ }
+\cs_new:Npn \exp_args:NNv #1#2#3
+ {
+ \exp_after:wN #1
+ \exp_after:wN #2
+ \exp_after:wN { \tex_romannumeral:D \exp_eval_register:c {#3} }
+ }
+\cs_new:Npn \exp_args:NNV #1#2#3
+ {
+ \exp_after:wN #1
+ \exp_after:wN #2
+ \exp_after:wN { \tex_romannumeral:D \exp_eval_register:N #3 }
+ }
+\cs_new:Npn \exp_args:Nco #1#2#3
+ {
+ \exp_after:wN #1
+ \cs:w #2 \exp_after:wN \cs_end:
+ \exp_after:wN {#3}
+ }
+\cs_new:Npn \exp_args:Ncf #1#2#3
+ {
+ \exp_after:wN #1
+ \cs:w #2 \exp_after:wN \cs_end:
+ \exp_after:wN { \tex_romannumeral:D -`0 #3 }
+ }
+\cs_new_nopar:Npn \exp_args:NVV #1#2#3
+ {
+ \exp_after:wN #1
+ \exp_after:wN { \tex_romannumeral:D \exp_after:wN
+ \exp_eval_register:N \exp_after:wN #2 \exp_after:wN }
+ \exp_after:wN { \tex_romannumeral:D \exp_eval_register:N #3 }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\exp_args:Ncco,
+% \exp_args:NcNc,
+% \exp_args:NcNo,
+% \exp_args:NNNV}
+% A few more that we can hand-tune.
+% \begin{macrocode}
+\cs_new:Npn \exp_args:NNNV #1#2#3#4
+ {
+ \exp_after:wN #1
+ \exp_after:wN #2
+ \exp_after:wN #3
+ \exp_after:wN { \tex_romannumeral:D \exp_eval_register:N #4 }
+ }
+\cs_new:Npn \exp_args:NcNc #1#2#3#4
+ {
+ \exp_after:wN #1
+ \cs:w #2 \exp_after:wN \cs_end:
+ \exp_after:wN #3
+ \cs:w #4 \cs_end:
+ }
+\cs_new:Npn \exp_args:NcNo #1#2#3#4
+ {
+ \exp_after:wN #1
+ \cs:w #2 \exp_after:wN \cs_end:
+ \exp_after:wN #3
+ \exp_after:wN {#4}
+ }
+\cs_new:Npn \exp_args:Ncco #1#2#3#4
+ {
+ \exp_after:wN #1
+ \cs:w #2 \exp_after:wN \cs_end:
+ \cs:w #3 \exp_after:wN \cs_end:
+ \exp_after:wN {#4}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Definitions with the automated technique}
+% \label{sec:gendef}
+%
+% Some of these could be done more efficiently, but the complexity of
+% coding then becomes an issue. Notice that the auto-generated functions
+% are all not long: they don't actually take any arguments themselves.
+%
+% \begin{macro}{\exp_args:Nx}
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \exp_args:Nx { \::x \::: }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\exp_args:NNx,
+% \exp_args:Nnc,
+% \exp_args:Ncx,
+% \exp_args:Nfo,\exp_args:Nff,
+% \exp_args:Nnf,\exp_args:Nno,\exp_args:NnV,\exp_args:Nnx,
+% \exp_args:Noo,\exp_args:Noc,\exp_args:Nox,
+% \exp_args:Nxo,\exp_args:Nxx}
+% Here are the actual function definitions, using the helper functions
+% above.
+% \begin{macrocode}
+\cs_new_nopar:Npn \exp_args:Nnc { \::n \::c \::: }
+\cs_new_nopar:Npn \exp_args:Nfo { \::f \::o \::: }
+\cs_new_nopar:Npn \exp_args:Nff { \::f \::f \::: }
+\cs_new_nopar:Npn \exp_args:Nnf { \::n \::f \::: }
+\cs_new_nopar:Npn \exp_args:Nno { \::n \::o \::: }
+\cs_new_nopar:Npn \exp_args:NnV { \::n \::V \::: }
+\cs_new_nopar:Npn \exp_args:Noc { \::o \::c \::: }
+\cs_new_nopar:Npn \exp_args:Noo { \::o \::o \::: }
+\cs_new_protected_nopar:Npn \exp_args:NNx { \::N \::x \::: }
+\cs_new_protected_nopar:Npn \exp_args:Ncx { \::c \::x \::: }
+\cs_new_protected_nopar:Npn \exp_args:Nnx { \::n \::x \::: }
+\cs_new_protected_nopar:Npn \exp_args:Nox { \::o \::x \::: }
+\cs_new_protected_nopar:Npn \exp_args:Nxo { \::x \::o \::: }
+\cs_new_protected_nopar:Npn \exp_args:Nxx { \::x \::x \::: }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\exp_args:Nccx,
+% \exp_args:Ncnx,
+% \exp_args:NNno,
+% \exp_args:Nnno,
+% \exp_args:Nnnx,
+% \exp_args:Nnox,
+% \exp_args:Nooo,
+% \exp_args:Noox,
+% \exp_args:Nnnc,
+% \exp_args:NNnx,
+% \exp_args:NNoo,
+% \exp_args:NNox}
+% \begin{macrocode}
+\cs_new_nopar:Npn \exp_args:NNno { \::N \::n \::o \::: }
+\cs_new_nopar:Npn \exp_args:NNoo { \::N \::o \::o \::: }
+\cs_new_nopar:Npn \exp_args:Nnnc { \::n \::n \::c \::: }
+\cs_new_nopar:Npn \exp_args:Nnno { \::n \::n \::o \::: }
+\cs_new_nopar:Npn \exp_args:Nooo { \::o \::o \::o \::: }
+\cs_new_protected_nopar:Npn \exp_args:NNnx { \::N \::n \::x \::: }
+\cs_new_protected_nopar:Npn \exp_args:NNox { \::N \::o \::x \::: }
+\cs_new_protected_nopar:Npn \exp_args:Nnnx { \::n \::n \::x \::: }
+\cs_new_protected_nopar:Npn \exp_args:Nnox { \::n \::o \::x \::: }
+\cs_new_protected_nopar:Npn \exp_args:Nccx { \::c \::c \::x \::: }
+\cs_new_protected_nopar:Npn \exp_args:Ncnx { \::c \::n \::x \::: }
+\cs_new_protected_nopar:Npn \exp_args:Noox { \::o \::o \::x \::: }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Last-unbraced versions}
+%
+% \begin{macro}[aux]{\exp_arg_last_unbraced:nn}
+% \begin{macro}[aux]{\::f_unbraced}
+% \begin{macro}[aux]{\::o_unbraced}
+% \begin{macro}[aux]{\::V_unbraced}
+% \begin{macro}[aux]{\::v_unbraced}
+% There are a few places where the last argument needs to be available
+% unbraced. First some helper macros.
+% \begin{macrocode}
+\cs_new:Npn \exp_arg_last_unbraced:nn #1#2 { #2#1 }
+\cs_new:Npn \::f_unbraced \::: #1#2
+ {
+ \exp_after:wN \exp_arg_last_unbraced:nn
+ \exp_after:wN { \tex_romannumeral:D -`0 #2 } {#1}
+ }
+\cs_new:Npn \::o_unbraced \::: #1#2
+ { \exp_after:wN \exp_arg_last_unbraced:nn \exp_after:wN {#2} {#1} }
+\cs_new:Npn \::V_unbraced \::: #1#2
+ {
+ \exp_after:wN \exp_arg_last_unbraced:nn
+ \exp_after:wN { \tex_romannumeral:D \exp_eval_register:N #2 } {#1}
+ }
+\cs_new:Npn \::v_unbraced \::: #1#2
+ {
+ \exp_after:wN \exp_arg_last_unbraced:nn
+ \exp_after:wN { \tex_romannumeral:D \exp_eval_register:c {#2} } {#1}
+ }
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%
+% \begin{macro}{\exp_last_unbraced:NV}
+% \begin{macro}{\exp_last_unbraced:Nv}
+% \begin{macro}{\exp_last_unbraced:Nf}
+% \begin{macro}{\exp_last_unbraced:No}
+% \begin{macro}{\exp_last_unbraced:NcV}
+% \begin{macro}{\exp_last_unbraced:NNV}
+% \begin{macro}{\exp_last_unbraced:NNo}
+% \begin{macro}{\exp_last_unbraced:Noo}
+% \begin{macro}{\exp_last_unbraced:Nfo}
+% \begin{macro}{\exp_last_unbraced:NNNV}
+% \begin{macro}{\exp_last_unbraced:NNNo}
+% Now the business end: most of these are hand-tuned for speed, but the
+% general system is in place.
+% \begin{macrocode}
+\cs_new:Npn \exp_last_unbraced:NV #1#2
+ { \exp_after:wN #1 \tex_romannumeral:D \exp_eval_register:N #2 }
+\cs_new:Npn \exp_last_unbraced:Nv #1#2
+ { \exp_after:wN #1 \tex_romannumeral:D \exp_eval_register:c {#2} }
+\cs_new:Npn \exp_last_unbraced:No #1#2 { \exp_after:wN #1 #2 }
+\cs_new:Npn \exp_last_unbraced:Nf #1#2
+ { \exp_after:wN #1 \tex_romannumeral:D -`0 #2 }
+\cs_new:Npn \exp_last_unbraced:NcV #1#2#3
+ {
+ \exp_after:wN #1
+ \cs:w #2 \exp_after:wN \cs_end:
+ \tex_romannumeral:D \exp_eval_register:N #3
+ }
+\cs_new:Npn \exp_last_unbraced:NNV #1#2#3
+ {
+ \exp_after:wN #1
+ \exp_after:wN #2
+ \tex_romannumeral:D \exp_eval_register:N #3
+ }
+\cs_new:Npn \exp_last_unbraced:NNo #1#2#3
+ { \exp_after:wN #1 \exp_after:wN #2 #3 }
+\cs_new_nopar:Npn \exp_last_unbraced:Noo { \::o \::o_unbraced \::: }
+\cs_new_nopar:Npn \exp_last_unbraced:Nfo { \::f \::o_unbraced \::: }
+\cs_new:Npn \exp_last_unbraced:NNNV #1#2#3#4
+ {
+ \exp_after:wN #1
+ \exp_after:wN #2
+ \exp_after:wN #3
+ \tex_romannumeral:D \exp_eval_register:N #4
+ }
+\cs_new:Npn \exp_last_unbraced:NNNo #1#2#3#4
+ { \exp_after:wN #1 \exp_after:wN #2 \exp_after:wN #3 #4 }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\exp_last_two_unbraced:Noo}
+% If |#2| is a single token then this can be implemented as
+% \begin{verbatim}
+% \cs_new:Npn \exp_last_two_unbraced:Noo #1 #2 #3
+% { \exp_after:wN \exp_after:wN \exp_after:wN #1 \exp_after:wN #2 #3 }
+% \end{verbatim}
+% However, for robustness this is not suitable. Instead, a bit of a
+% shuffle is used to ensure that |#2| can be multiple tokens.
+% \begin{macrocode}
+\cs_new:Npn \exp_last_two_unbraced:Noo #1#2#3
+ { \exp_after:wN \exp_last_two_unbraced_aux:nnN \exp_after:wN {#3} {#2} #1 }
+\cs_new:Npn \exp_last_two_unbraced_aux:nnN #1#2#3
+ { \exp_after:wN #3 #2 #1 }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Preventing expansion}
+%
+% \begin{macro}{\exp_not:o}
+% \begin{macro}{\exp_not:f}
+% \begin{macro}{\exp_not:V}
+% \begin{macro}{\exp_not:v}
+% \begin{macrocode}
+\cs_new:Npn \exp_not:o #1 { \etex_unexpanded:D \exp_after:wN {#1} }
+\cs_new:Npn \exp_not:f #1
+ { \etex_unexpanded:D \exp_after:wN { \tex_romannumeral:D -`0 #1 } }
+\cs_new:Npn \exp_not:V #1
+ {
+ \etex_unexpanded:D \exp_after:wN
+ { \tex_romannumeral:D \exp_eval_register:N #1 }
+ }
+\cs_new:Npn \exp_not:v #1
+ {
+ \etex_unexpanded:D \exp_after:wN
+ { \tex_romannumeral:D \exp_eval_register:c {#1} }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\exp_not:c}
+% A helper function.
+% \begin{macrocode}
+\cs_new:Npn \exp_not:c #1 { \exp_after:wN \exp_not:N \cs:w #1 \cs_end: }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Defining function variants}
+%
+% \begin{macro}{\cs_generate_variant:Nn}
+% \begin{macro}[aux]{\cs_generate_variant_aux:nnNNn}
+% \begin{macro}[aux]{\cs_generate_variant_aux:Nnnw}
+% \begin{macro}[aux]{\cs_generate_variant_aux:NNn}
+% \begin{macro}[aux]{\cs_generate_variant_aux:N}
+% \begin{arguments}
+% \item Base form of a function; \emph{e.g.},~|\tl_set:Nn|
+% \item One or more variant argument specifiers; e.g., |{Nx,c,cx}|
+% \end{arguments}
+% Split up the original base function to grab its name and signature
+% consisting of $k$ letters. Then we wish to iterate through the list
+% of variant argument specifiers, and for each one construct a new
+% function name using the original base name, the variant signature
+% consisting of $l$ letters and the last $k-l$ letters of the base
+% signature. For example, for a base function |\tl_set:Nn| which
+% needs a |c| variant form, we want the new signature to be |cn|.
+% \begin{macrocode}
+\cs_new_protected:Npn \cs_generate_variant:Nn #1
+ {
+ \chk_if_exist_cs:N #1
+ \cs_split_function:NN #1 \cs_generate_variant_aux:nnNNn
+ #1
+ }
+% \end{macrocode}
+% We discard the boolean |#3| and then set off a loop through the desired
+% variant forms. The original function is retained as |#4| for efficiency.
+% \begin{macrocode}
+\cs_new:Npn \cs_generate_variant_aux:nnNNn #1#2#3#4#5
+ { \cs_generate_variant_aux:Nnnw #4 {#1}{#2} #5 , ? , \q_recursion_stop }
+% \end{macrocode}
+% Next is the real work to be done. We now have 1: original function,
+% 2: base name, 3: base signature, 4: beginning of variant signature.
+% To construct the new
+% csname and the |\exp_args:Ncc| form, we need the variant signature.
+% In our example, we wanted to discard the first two letters of the
+% base signature because the variant form started with |cc|. This is
+% the same as putting first |cc| in the signature and then
+% |\use_none:nn| followed by the base signature |NNn|. We therefore
+% call a small loop that outputs an |n| for each letter in the variant
+% signature and use this to call the correct |\use_none:| variant.
+%
+% Firstly though, we check whether to terminate the loop.
+% Then build the variant function once, to avoid repeating this
+% relatively expensive operation. Then recurse.
+% \begin{macrocode}
+\cs_new:Npn \cs_generate_variant_aux:Nnnw #1#2#3#4 ,
+ {
+ \if:w ? #4
+ \exp_after:wN \use_none_delimit_by_q_recursion_stop:w
+ \fi:
+ \exp_args:NNc \cs_generate_variant_aux:NNn
+ #1
+ { #2 : #4 \use:c { use_none: \cs_generate_variant_aux:N #4 ? } #3 }
+ {#4}
+ \cs_generate_variant_aux:Nnnw #1 {#2} {#3}
+ }
+% \end{macrocode}
+% Check if the variant form has already been defined.
+% If not, then define it and then additionally check if
+% the |\exp_args:N| form needed is defined.
+% Otherwise tell that it was already defined.
+% \begin{macrocode}
+\cs_new:Npn \cs_generate_variant_aux:NNn #1 #2 #3
+ {
+ \cs_if_free:NTF #2
+ {
+ \cs_generate_variant_aux:NNpx #1 #2
+ { \exp_not:c { exp_args:N #3 } \exp_not:N #1 }
+ \cs_generate_internal_variant:n {#3}
+ }
+ {
+ \iow_log:x
+ {
+ Variant~\token_to_str:N #2~%
+ already~defined;~ not~ changing~ it~on~line~%
+ \tex_the:D \tex_inputlineno:D
+ }
+ }
+ }
+% \end{macrocode}
+% The small loop for defining the required number of |n|s. Break when
+% seeing a |?|.
+% \begin{macrocode}
+\cs_new:Npn \cs_generate_variant_aux:N #1
+ {
+ \if:w ? #1
+ \exp_after:wN \use_none:nn
+ \fi:
+ n
+ \cs_generate_variant_aux:N
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[aux]{\cs_generate_variant_aux:NNpx}
+% \begin{macro}[aux]{\cs_generate_variant_aux:w}
+% The idea here is to pick up protected parent functions, using the
+% nature of the meaning string that they generate. The test here is
+% almost the same as \cs{tl_if_empty:nTF}, but has to be hard-coded as
+% that function is not yet available and because it has to match both
+% long and short macros.
+% \begin{macrocode}
+\group_begin:
+ \tex_lccode:D `\Z = `\d \scan_stop:
+ \tex_lccode:D `\? =`\\ \scan_stop:
+ \tex_catcode:D `\P = 12 \scan_stop:
+ \tex_catcode:D `\R = 12 \scan_stop:
+ \tex_catcode:D `\O = 12 \scan_stop:
+ \tex_catcode:D `\T = 12 \scan_stop:
+ \tex_catcode:D `\E = 12 \scan_stop:
+ \tex_catcode:D `\C = 12 \scan_stop:
+ \tex_catcode:D `\Z = 12 \scan_stop:
+\tex_lowercase:D
+ {
+ \group_end:
+ \cs_new_nopar:Npn \cs_generate_variant_aux:NNpx #1
+ {
+ \exp_after:wN \cs_generate_variant_aux:w
+ \token_to_meaning:N #1 ? PROTECTEZ \q_stop
+ }
+ \cs_new:Npn \cs_generate_variant_aux:w #1 ? PROTECTEZ #2 \q_stop
+ {
+ \if_catcode:w a \etex_detokenize:D \exp_after:wN {#1} a
+ \exp_after:wN \cs_new_protected_nopar:Npx
+ \else:
+ \exp_after:wN \cs_new_nopar:Npx
+ \fi:
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[int]{\cs_generate_internal_variant:n}
+% \begin{macro}[aux]{\cs_generate_internal_variant_aux:N}
+% Test if |exp_args:N #1| is already defined
+% and if not define it via the
+% |\::| commands using the chars in |#1|
+% \begin{macrocode}
+\cs_new_protected:Npn \cs_generate_internal_variant:n #1
+ {
+ \cs_if_free:cT { exp_args:N #1 }
+ {
+ \cs_new:cpx { exp_args:N #1 }
+ { \cs_generate_internal_variant_aux:N #1 : }
+ }
+ }
+% \end{macrocode}
+% This command grabs char by char outputting |\::#1| (not expanded
+% further) until we see a |:|. That colon is in fact also turned into
+% |\:::| so that the required structure for |\exp_args...| commands
+% is correctly terminated.
+% \begin{macrocode}
+\cs_new:Npn \cs_generate_internal_variant_aux:N #1
+ {
+ \exp_not:c { :: #1 }
+ \if_meaning:w #1 :
+ \exp_after:wN \use_none:n
+ \fi:
+ \cs_generate_internal_variant_aux:N
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+%\subsection{Variants which cannot be created earlier}
+%
+% \begin{macro}[pTF]
+% {\str_if_eq:Vn, \str_if_eq:on, \str_if_eq:nV, \str_if_eq:no, \str_if_eq:VV}
+% These cannot come earlier as they need \cs{cs_generate_variant:Nn}.
+% \begin{macrocode}
+\cs_generate_variant:Nn \str_if_eq_p:nn { V , o }
+\cs_generate_variant:Nn \str_if_eq_p:nn { nV , no , VV }
+\cs_generate_variant:Nn \str_if_eq:nnT { V , o }
+\cs_generate_variant:Nn \str_if_eq:nnT { nV , no , VV }
+\cs_generate_variant:Nn \str_if_eq:nnF { V , o }
+\cs_generate_variant:Nn \str_if_eq:nnF { nV , no , VV }
+\cs_generate_variant:Nn \str_if_eq:nnTF { V , o }
+\cs_generate_variant:Nn \str_if_eq:nnTF { nV , no , VV }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</initex|package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3file.dtx b/Master/texmf-dist/source/latex/l3kernel/l3file.dtx
new file mode 100644
index 00000000000..7ec9de82c5e
--- /dev/null
+++ b/Master/texmf-dist/source/latex/l3kernel/l3file.dtx
@@ -0,0 +1,418 @@
+% \iffalse meta-comment
+%
+%% File: l3file.dtx Copyright (C) 2009-2011 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 "expl3 bundle" (The Work in LPPL)
+%% and all files in that bundle must be distributed together.
+%%
+%% The released version of this bundle is available from CTAN.
+%%
+%% -----------------------------------------------------------------------
+%%
+%% The development version of the bundle can be found at
+%%
+%% http://www.latex-project.org/svnroot/experimental/trunk/
+%%
+%% for those people who are interested.
+%%
+%%%%%%%%%%%
+%% NOTE: %%
+%%%%%%%%%%%
+%%
+%% Snapshots taken from the repository represent work in progress and may
+%% not work or may contain conflicting material! We therefore ask
+%% people _not_ to put them into distributions, archives, etc. without
+%% prior consultation with the LaTeX3 Project.
+%%
+%% -----------------------------------------------------------------------
+%
+%<*driver|package>
+\RequirePackage{l3names}
+\GetIdInfo$Id: l3file.dtx 2478 2011-06-19 21:34:23Z joseph $
+ {L3 Experimental file operations}
+%</driver|package>
+%<*driver>
+\documentclass[full]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3file} package\\ File operations^^A
+% \thanks{This file describes v\ExplFileVersion,
+% last revised \ExplFileDate.}^^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 \ExplFileDate}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% In contrast to the \pkg{l3io} module, which deals with the lowest
+% level of file management, the \pkg{l3file} module provides a higher
+% level interface for handling file contents. This involves providing
+% convenient wrappers around many of the functions in \pkg{l3io}
+% to make them more generally accessible.
+%
+% It is important to remember that \TeX{} will attempt to locate files using
+% both the operating system path and entries in the \TeX{} file database (most
+% \TeX{} systems use such a database). Thus the \enquote{current path} for
+% \TeX{} is somewhat broader than that for other programs.
+%
+% \section{File operation functions}
+%
+% \begin{variable}{\g_file_current_name_tl}
+% Contains the name of the current \LaTeX{} file. This variable
+% should not be modified: it is intended for information only. It
+% will be equal to \cs{c_job_name_tl} at the start of a \LaTeX{}
+% run and will be modified each time a file is read using
+% \cs{file_input:n}.
+% \end{variable}
+%
+% \begin{function}[TF]{\file_if_exist:n}
+% \begin{syntax}
+% \cs{file_if_exist:nTF} \Arg{file name} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Searches for \meta{file name} using the current \TeX{} search
+% path and the additional paths controlled by
+% \cs{file_path_include:n}). The branching versions then leave
+% either \meta{true code} or \meta{false code} in the input stream,
+% as appropriate to the truth of the test and the variant of the
+% function chosen.
+% \begin{texnote}
+% The \meta{file name} may contain both literal items and expandable
+% content, which should on full expansion be the desired file name.
+% The expansion occurs when \TeX{} searches for the file.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{\file_add_path:nN}
+% \begin{syntax}
+% \cs{file_add_path:nN} \Arg{file name} \meta{tl var}
+% \end{syntax}
+% Searches for \meta{file name} in the path as detailed for
+% \cs{file_if_exist:nTF}, and if found sets the \meta{tl var} the
+% fully-qualified name of the file, \emph{i.e}.~the path and file name.
+% If the file is not found then the \meta{tl var} will be empty.
+% \begin{texnote}
+% The \meta{file name} may contain both literal items and expandable
+% content, which should on full expansion be the desired file name.
+% The expansion occurs when \TeX{} searches for the file.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{\file_input:n}
+% \begin{syntax}
+% \cs{file_input:n} \Arg{file name}
+% \end{syntax}
+% Searches for \meta{file name} in the path as detailed for
+% \cs{file_if_exist:nTF}, and if found reads in the file as
+% additional \LaTeX{} source. All files read are recorded
+% for information and the file name stack is updated by this
+% function.
+% \begin{texnote}
+% The \meta{file name} may contain both literal items and expandable
+% content, which should on full expansion be the desired file name.
+% The expansion occurs when \TeX{} searches for the file.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{\file_path_include:n}
+% \begin{syntax}
+% \cs{file_path_include:n} \Arg{path}
+% \end{syntax}
+% Adds \meta{path} to the list of those used to search for files
+% by the \cs{file_input:n} and \cs{file_if_exist:n} function. The
+% assignment is local.
+% \end{function}
+%
+% \begin{function}{\file_path_remove:n}
+% \begin{syntax}
+% \cs{file_path_remove:n} \Arg{path}
+% \end{syntax}
+% Removes \meta{path} from the list of those used to search for files
+% by the \cs{file_input:n} and \cs{file_if_exist:n} function. The
+% assignment is local.
+% \end{function}
+%
+% \begin{function}{\file_list:}
+% \begin{syntax}
+% \cs{file_list:}
+% \end{syntax}
+% This function will list all files loaded using \cs{file_input:n}
+% in the log file.
+% \end{function}
+%
+% \section{Internal file functions}
+%
+% \begin{variable}{\g_file_stack_seq}
+% Stores the stack of nested files loaded using \cs{file_input:n}. This
+% is needed to restore the appropriate file name to
+% \cs{g_file_current_name_tl} at the end of each file.
+% \end{variable}
+%
+% \begin{variable}{\g_file_record_seq}
+% Stores the name of every file loaded using \cs{file_input:n}. In
+% contrast to \cs{g_file_stack_seq}, no items are ever removed from this
+% sequence.
+% \end{variable}
+%
+% \begin{variable}{\l_file_name_tl}
+% Used to return the full name of a file for internal use.
+% \end{variable}
+%
+% \begin{variable}{\l_file_search_path_seq}
+% The sequence of file paths to search when loading a file.
+% \end{variable}
+%
+% \begin{variable}{\l_file_search_path_saved_seq}
+% When loaded on top of \LaTeXe{}, there is a need to save the search
+% path so that \cs{input@path} can be used as appropriate.
+% \end{variable}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3file} implementation}
+%
+% \TestFiles{m3file001}
+%
+% \begin{macrocode}
+%<*initex|package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*package>
+\ProvidesExplPackage
+ {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
+\package_check_loaded_expl:
+%</package>
+% \end{macrocode}
+%
+% \begin{variable}{\g_file_current_name_tl}
+% The name of the current file should be available at all times.
+% \begin{macrocode}
+\tl_new:N \g_file_current_name_tl
+% \end{macrocode}
+% For the format the file name needs to be picked up at the start of the
+% file. In package mode the current file name is collected from \LaTeXe{}.
+% \begin{macrocode}
+%<*initex>
+\tex_everyjob:D \exp_after:wN
+ {
+ \tex_the:D \tex_everyjob:D
+ \tl_gset:Nx \g_file_current_name_tl { \tex_jobname:D }
+ }
+%</initex>
+%<*package>
+\tl_gset_eq:NN \g_file_current_name_tl \@currname
+%</package>
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\g_file_stack_seq}
+% The input list of files is stored as a sequence stack.
+% \begin{macrocode}
+\seq_new:N \g_file_stack_seq
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\g_file_record_seq}
+% The total list of files used is recorded separately from the current file
+% stack, as nothing is ever popped from this list.
+% \begin{macrocode}
+\seq_new:N \g_file_record_seq
+% \end{macrocode}
+% The current file name should be included in the file list!
+% \begin{macrocode}
+%<*initex>
+\tex_everyjob:D \exp_after:wN
+ {
+ \tex_the:D \tex_everyjob:D
+ \seq_gput_right:NV \g_file_record_seq \g_file_current_name_tl
+ }
+%</initex>
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_file_name_tl}
+% Used to return the fully-qualified name of a file.
+% \begin{macrocode}
+\tl_new:N \l_file_name_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_file_search_path_seq}
+% The current search path.
+% \begin{macrocode}
+\seq_new:N \l_file_search_path_seq
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_file_search_path_saved_seq}
+% The current search path has to be saved for package use.
+% \begin{macrocode}
+%<*package>
+\seq_new:N \l_file_search_path_saved_seq
+%</package>
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\file_add_path:nN}
+% \begin{variable}{\g_file_test_stream}
+% \begin{macro}[aux]{\file_add_path_search:nN}
+% The way to test if a file exists is to try to open it: if it does not
+% exist then \TeX{} will report end-of-file. For files which are in the
+% current directory, this is straight-forward. For other locations, a
+% search has to be made looking at each potential path in turn. The first
+% location is of course treated as the correct one. If nothing is found,
+% |#2| is returned empty.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \file_add_path:nN #1#2
+ {
+ \ior_open:Nn \g_file_test_stream {#1}
+ \ior_if_eof:NTF \g_file_test_stream
+ { \file_add_path_search:nN {#1} #2 }
+ {
+ \ior_close:N \g_file_test_stream
+ \tl_set:Nx #2 {#1}
+ }
+ }
+\cs_new_protected_nopar:Npn \file_add_path_search:nN #1#2
+ {
+ \tl_clear:N #2
+%<*package>
+ \cs_if_exist:NT \input@path
+ {
+ \seq_set_eq:NN \l_file_search_path_saved_seq \l_file_search_path_seq
+ \clist_map_inline:Nn \input@path
+ { \seq_put_right:Nn \l_file_search_path_seq {##1} }
+ }
+%</package>
+ \seq_map_inline:Nn \l_file_search_path_seq
+ {
+ \ior_open:Nn \g_file_test_stream { ##1 #1 }
+ \ior_if_eof:NF \g_file_test_stream
+ {
+ \tl_set:Nx #2 { ##1 #1 }
+ \seq_map_break:
+ }
+ }
+%<*package>
+ \cs_if_exist:NT \input@path
+ { \seq_set_eq:NN \l_file_search_path_seq \l_file_search_path_saved_seq }
+%</package>
+ \ior_close:N \g_file_test_stream
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{variable}
+% \end{macro}
+%
+% \begin{macro}[TF]{\file_if_exist:n}
+% The test for the existence of a file is a wrapper around the function to
+% add a path to a file. If the file was found, the path will contain
+% something, whereas if the file was not located then the return value
+% will be empty.
+% \begin{macrocode}
+\prg_new_protected_conditional:Nnn \file_if_exist:n { T , F , TF }
+ {
+ \file_add_path:nN {#1} \l_file_name_tl
+ \tl_if_empty:NTF \l_file_name_tl
+ { \prg_return_false: }
+ { \prg_return_true: }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\file_input:n}
+% Loading a file is done in a safe way, checking first that the file
+% exists and loading only if it does.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \file_input:n #1
+ {
+ \file_add_path:nN {#1} \l_file_name_tl
+ \tl_if_empty:NF \l_file_name_tl
+ {
+%<*initex>
+ \seq_gput_right:Nx \g_file_record_seq {#1}
+%</initex>
+%<*package>
+ \@addtofilelist {#1}
+%</package>
+ \seq_gpush:NV \g_file_stack_seq \g_file_current_name_tl
+ \tl_gset:Nn \g_file_current_name_tl {#1}
+ \exp_after:wN \tex_input:D \l_file_name_tl ~
+ \seq_gpop:NN \g_file_stack_seq \g_file_current_name_tl
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\file_path_include:n}
+% \begin{macro}{\file_path_remove:n}
+% Wrapper functions to manage the search path.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \file_path_include:n #1
+ {
+ \seq_if_in:NnF \l_file_search_path_seq {#1}
+ { \seq_put_right:Nn \l_file_search_path_seq {#1} }
+ }
+\cs_new_protected_nopar:Npn \file_path_remove:n #1
+ { \seq_remove_all:Nn \l_file_search_path_seq {#1} }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\file_list:}
+% A function to list all files used to the log.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \file_list:
+ {
+ \seq_remove_duplicates:N \g_file_record_seq
+ \iow_log:n { *~File~List~* }
+ \seq_map_inline:Nn \g_file_record_seq { \iow_log:n {##1} }
+ \iow_log:n { ************* }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% When used as a package, there is a need to hold onto the standard
+% file list as well as the new one here.
+% \begin{macrocode}
+%<*package>
+\AtBeginDocument
+ {
+ \clist_map_inline:Nn \@filelist
+ { \seq_put_right:Nn \g_file_record_seq {#1} }
+ }
+%</package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</initex|package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex \ No newline at end of file
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3final.dtx b/Master/texmf-dist/source/latex/l3kernel/l3final.dtx
new file mode 100644
index 00000000000..bc37e2aaee4
--- /dev/null
+++ b/Master/texmf-dist/source/latex/l3kernel/l3final.dtx
@@ -0,0 +1,112 @@
+% \iffalse meta-comment
+%
+%% File: l3final.dtx Copyright (C) 1990-2011 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 "expl3 bundle" (The Work in LPPL)
+%% and all files in that bundle must be distributed together.
+%%
+%% The released version of this bundle is available from CTAN.
+%%
+%% -----------------------------------------------------------------------
+%%
+%% The development version of the bundle can be found at
+%%
+%% http://www.latex-project.org/svnroot/experimental/trunk/
+%%
+%% for those people who are interested.
+%%
+%%%%%%%%%%%
+%% NOTE: %%
+%%%%%%%%%%%
+%%
+%% Snapshots taken from the repository represent work in progress and may
+%% not work or may contain conflicting material! We therefore ask
+%% people _not_ to put them into distributions, archives, etc. without
+%% prior consultation with the LaTeX3 Project.
+%%
+%% -----------------------------------------------------------------------
+%
+%<*driver|package>
+\RequirePackage{l3names}
+\GetIdInfo$Id: l3final.dtx 2478 2011-06-19 21:34:23Z joseph $
+ {L3 Experimental format finalisation}
+%</driver|package>
+%<*driver>
+\documentclass[full]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3final} package\\ Format finalisation^^A
+% \thanks{This file describes v\ExplFileVersion,
+% last revised \ExplFileDate.}^^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 \ExplFileDate}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% This module is the end of the \LaTeX3 format file. Currently, there
+% is not a lot happening here.
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3final} Implementation}
+%
+% \begin{macrocode}
+%<*initex>
+% \end{macrocode}
+%
+% \begin{macro}{\par}
+% \TeX{} has a nasty habit of inserting a command with the name \cs{par}
+% so we had better make sure that that command at least has a definition.
+% \begin{macrocode}
+\cs_set_eq:NN \par \tex_par:D
+% \end{macrocode}
+% \end{macro}
+%
+% The very last job is to dump the format, taking care to first leave
+% the code environment.
+% \begin{macrocode}
+\use:n
+ {
+ \char_set_catcode_space:n { 9 }
+ \char_set_catcode_space:n { 32 }
+ \char_set_catcode_math_subscript:n { 94 }
+ \char_set_catcode_other:n { 58 }
+ \char_set_catcode_active:n { 126 }
+ \tex_endlinechar:D = 13 \scan_stop:
+ \tex_dump:D
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</initex>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+%\PrintIndex
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp.dtx
new file mode 100644
index 00000000000..36ac323debd
--- /dev/null
+++ b/Master/texmf-dist/source/latex/l3kernel/l3fp.dtx
@@ -0,0 +1,5676 @@
+% \iffalse meta-comment
+%
+%% File: l3fp.dtx Copyright (C) 2010,2011 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 "expl3 bundle" (The Work in LPPL)
+%% and all files in that bundle must be distributed together.
+%%
+%% The released version of this bundle is available from CTAN.
+%%
+%% -----------------------------------------------------------------------
+%%
+%% The development version of the bundle can be found at
+%%
+%% http://www.latex-project.org/svnroot/experimental/trunk/
+%%
+%% for those people who are interested.
+%%
+%%%%%%%%%%%
+%% NOTE: %%
+%%%%%%%%%%%
+%%
+%% Snapshots taken from the repository represent work in progress and may
+%% not work or may contain conflicting material! We therefore ask
+%% people _not_ to put them into distributions, archives, etc. without
+%% prior consultation with the LaTeX3 Project.
+%%
+%% -----------------------------------------------------------------------
+%
+%<*driver|package>
+\RequirePackage{l3names}
+\GetIdInfo$Id: l3fp.dtx 2478 2011-06-19 21:34:23Z joseph $
+ {L3 Experimental floating-point operations}
+%</driver|package>
+%<*driver>
+\documentclass[full]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3fp} package\\ Floating-point operations^^A
+% \thanks{This file describes v\ExplFileVersion,
+% last revised \ExplFileDate.}^^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 \ExplFileDate}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% A floating point number is one which is stored as a mantissa and
+% a separate exponent. This module implements arithmetic using radix
+% $10$ floating point numbers. This means that the mantissa should
+% be a real number in the range $1 \le \expandafter\mathopen\string|
+% x \expandafter\mathclose\string| < 10$, with the
+% exponent given as an integer between $-99$ and $99$. In the
+% input, the exponent part is represented starting with an \texttt{e}.
+% As this is a low-level module, error-checking is minimal. Numbers
+% which are too large for the floating point unit to handle will result
+% in errors, either from \TeX{} or from \LaTeX{}. The \LaTeX{} code does not
+% check that the input will not overflow, hence the possibility of a
+% \TeX{} error. On the other hand, numbers which are too small will be
+% dropped, which will mean that extra decimal digits will simply be
+% lost.
+%
+% When parsing numbers, any missing parts will be interpreted as
+% zero. So for example
+%\begin{verbatim}
+% \fp_set:Nn \l_my_fp { }
+% \fp_set:Nn \l_my_fp { . }
+% \fp_set:Nn \l_my_fp { - }
+% \end{verbatim}
+% will all be interpreted as zero values without raising an error.
+%
+% Operations which give an undefined result (such as division by
+% $0$) will not lead to errors. Instead special marker values are
+% returned, which can be tested for using fr example
+% \cs{fp_if_undefined:N(TF)}. In this way it is possible to work with
+% asymptotic functions without first checking the input. If these
+% special values are carried forward in calculations they will be
+% treated as $0$.
+%
+% Floating point numbers are stored in the \texttt{fp} floating point
+% variable type. This has a standard range of functions for
+% variable management.
+%
+% \section{Floating-point variables}
+%
+% \begin{function}{\fp_new:N, \fp_new:c}
+% \begin{syntax}
+% \cs{fp_new:N} \meta{floating point variable}
+% \end{syntax}
+% Creates a new \meta{floating point variable} or raises an error if
+% the name is already taken. The declaration global. The
+% \meta{floating point} will initially be set to |+0.000000000e0|
+% (the zero floating point).
+% \end{function}
+%
+% \begin{function}{\fp_const:Nn, \fp_const:cn}
+% \begin{syntax}
+% \cs{fp_const:Nn} \meta{floating point variable} \Arg{value}
+% \end{syntax}
+% Creates a new constant \meta{floating point variable} or raises an
+% error if the name is already taken. The value of the
+% \meta{floating point variable} will be set globally to the
+% \meta{value}.
+% \end{function}
+%
+% \begin{function}{\fp_set_eq:NN, \fp_set_eq:cN, \fp_set_eq:Nc, \fp_set_eq:cc}
+% \begin{syntax}
+% \cs{fp_set_eq:NN} \meta{fp var1} \meta{fp var2}
+% \end{syntax}
+% Sets the value of \meta{floating point variable1} equal to that of
+% \meta{floating point variable2}. This assignment is restricted to the
+% current \TeX{} group level.
+% \end{function}
+%
+% \begin{function}
+% {\fp_gset_eq:NN, \fp_gset_eq:cN, \fp_gset_eq:Nc, \fp_gset_eq:cc}
+% \begin{syntax}
+% \cs{fp_gset_eq:NN} \meta{fp var1} \meta{fp var2}
+% \end{syntax}
+% Sets the value of \meta{floating point variable1} equal to that of
+% \meta{floating point variable2}. This assignment is global and so is
+% not limited by the current \TeX{} group level.
+% \end{function}
+%
+% \begin{function}{\fp_zero:N, \fp_zero:c}
+% \begin{syntax}
+% \cs{fp_zero:N} \meta{floating point variable}
+% \end{syntax}
+% Sets the \meta{floating point variable} to |+0.000000000e0| within
+% the current scope.
+% \end{function}
+%
+% \begin{function}{\fp_gzero:N, \fp_gzero:c}
+% \begin{syntax}
+% \cs{fp_gzero:N} \meta{floating point variable}
+% \end{syntax}
+% Sets the \meta{floating point variable} to |+0.000000000e0| globally.
+% \end{function}
+%
+% \begin{function}{\fp_set:Nn, \fp_set:cn}
+% \begin{syntax}
+% \cs{fp_set:Nn} \meta{floating point variable} \Arg{value}
+% \end{syntax}
+% Sets the \meta{floating point variable} variable to \meta{value}
+% within the scope of the current \TeX{} group.
+% \end{function}
+%
+% \begin{function}{\fp_gset:Nn, \fp_gset:cn}
+% \begin{syntax}
+% \cs{fp_gset:Nn} \meta{floating point variable} \Arg{value}
+% \end{syntax}
+% Sets the \meta{floating point variable} variable to \meta{value}
+% globally.
+% \end{function}
+%
+% \begin{function}{\fp_set_from_dim:Nn, \fp_set_from_dim:cn}
+% \begin{syntax}
+% \cs{fp_set_from_dim:Nn} \meta{floating point variable} \Arg{dimexpr}
+% \end{syntax}
+% Sets the \meta{floating point variable} to the distance represented
+% by the \meta{dimension expression} in the units points. This means
+% that distances given in other units are first converted to points
+% before being assigned to the \meta{floating point variable}. The
+% assignment is local.
+% \end{function}
+%
+% \begin{function}{\fp_gset_from_dim:Nn, \fp_gset_from_dim:cn}
+% \begin{syntax}
+% \cs{fp_gset_from_dim:Nn} \meta{floating point variable} \Arg{dimexpr}
+% \end{syntax}
+% Sets the \meta{floating point variable} to the distance represented
+% by the \meta{dimension expression} in the units points. This means
+% that distances given in other units are first converted to points
+% before being assigned to the \meta{floating point variable}. The
+% assignment is global.
+% \end{function}
+%
+% \begin{function}[EXP]{\fp_use:N, \fp_use:c}
+% \begin{syntax}
+% \cs{fp_use:N} \meta{floating point variable}
+% \end{syntax}
+% Inserts the value of the \meta{floating point variable} into the
+% input stream. The value will be given as a real number without any
+% exponent part, and will always include a decimal point. For example,
+% \begin{verbatim}
+% \fp_new:Nn \test
+% \fp_set:Nn \test { 1.234 e 5 }
+% \fp_use:N \test
+% \end{verbatim}
+% will insert |12345.00000| into the input stream.
+% As illustrated, a floating point will always be inserted with ten
+% significant digits given. Very large and very small values will
+% include additional zeros for place value.
+% \end{function}
+%
+% \begin{function}{\fp_show:N, \fp_show:c}
+% \begin{syntax}
+% \cs{fp_show:N} \meta{floating point variable}
+% \end{syntax}
+% Displays the content of the \meta{floating point variable} on the
+% terminal.
+% \end{function}
+%
+% \section{Conversion of floating point values to other formats}
+%
+% It is useful to be able to convert floating point variables to
+% other forms. These functions are expandable, so that the material
+% can be used in a variety of contexts. The \cs{fp_use:N} function
+% should also be consulted in this context, as it will insert the
+% value of the floating point variable as a real number.
+%
+% \begin{function}[EXP]{\fp_to_dim:N, \fp_to_dim:c}
+% \begin{syntax}
+% \cs{fp_to_dim:N} \meta{floating point variable}
+% \end{syntax}
+% Inserts the value of the \meta{floating point variable}
+% into the input stream converted into a dimension in points.
+% \end{function}
+%
+% \begin{function}[EXP]{\fp_to_int:N, \fp_to_int:c}
+% \begin{syntax}
+% \cs{fp_to_int:N} \meta{floating point variable}
+% \end{syntax}
+% Inserts the integer value of the \meta{floating point variable}
+% into the input stream. The decimal part of the number will not be
+% included, but will be used to round the integer.
+% \end{function}
+%
+% \begin{function}[EXP]{\fp_to_tl:N, \fp_to_tl:c}
+% \begin{syntax}
+% \cs{fp_to_tl:N} \meta{floating point variable}
+% \end{syntax}
+% Inserts a representation of the \meta{floating point variable} into
+% the input stream as a token list. The representation follows the
+% conventions of a pocket calculator:
+% \begin{center}
+% \ttfamily
+% \begin{tabular}{r@{.}lr@{.}l}
+% \toprule
+% \multicolumn{2}{l}{\rmfamily{Floating point value}} &
+% \multicolumn{2}{l}{\rmfamily{Representation}} \\
+% \midrule
+% 1 & 234000000000e0 & 1 & 234 \\
+% -1 & 234000000000e0 & -1 & 234 \\
+% 1 & 234000000000e3 & \multicolumn{2}{l}{1234} \\
+% 1 & 234000000000e13 & \multicolumn{2}{l}{1234e13} \\
+% 1 & 234000000000e-1 & 0 & 1234 \\
+% 1 & 234000000000e-2 & 0 & 01234 \\
+% 1 & 234000000000e-3 & 1 & 234e-3 \\
+% \bottomrule
+% \end{tabular}
+% \end{center}
+% Notice that trailing zeros are removed in this process, and that
+% numbers which do not require a decimal part do \emph{not} include
+% a decimal marker.
+% \end{function}
+%
+% \section{Rounding floating point values}
+%
+% The module can round floating point values to either decimal places
+% or significant figures using the usual method in which exact halves
+% are rounded up.
+%
+% \begin{function}{\fp_round_figures:Nn, \fp_round_figures:cn}
+% \begin{syntax}
+% \cs{fp_round_figures:Nn} \meta{floating point variable} \Arg{target}
+% \end{syntax}
+% Rounds the \meta{floating point variable} to the \meta{target} number
+% of significant figures (an integer expression). The rounding is
+% carried out locally.
+% \end{function}
+%
+% \begin{function}{\fp_ground_figures:Nn, \fp_ground_figures:cn}
+% \begin{syntax}
+% \cs{fp_ground_figures:Nn} \meta{floating point variable} \Arg{target}
+% \end{syntax}
+% Rounds the \meta{floating point variable} to the \meta{target} number
+% of significant figures (an integer expression). The rounding is
+% carried out globally.
+% \end{function}
+%
+% \begin{function}{\fp_round_places:Nn, \fp_round_places:cn}
+% \begin{syntax}
+% \cs{fp_round_places:Nn} \meta{floating point variable} \Arg{target}
+% \end{syntax}
+% Rounds the \meta{floating point variable} to the \meta{target} number
+% of decimal places (an integer expression). The rounding is
+% carried out locally.
+% \end{function}
+%
+% \begin{function}{\fp_ground_places:Nn, \fp_ground_places:cn}
+% \begin{syntax}
+% \cs{fp_ground_places:Nn} \meta{floating point variable} \Arg{target}
+% \end{syntax}
+% Rounds the \meta{floating point variable} to the \meta{target} number
+% of decimal places (an integer expression). The rounding is
+% carried out globally.
+% \end{function}
+%
+% \section{Floating-point conditionals}
+%
+% \begin{function}[EXP,pTF]{\fp_if_undefined:N}
+% \begin{syntax}
+% \cs{fp_if_undefined_p:N} \meta{fixed-point}
+% \cs{fp_if_undefined:NTF} \meta{fixed-point}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if \meta{floating point} is undefined (\emph{i.e.}~equal to the
+% special \cs{c_undefined_fp} variable). The branching versions then
+% leave either \meta{true code} or \meta{false code} in the input
+% stream, as appropriate to the truth of the test and the variant of
+% the function chosen. The logical truth of the test is left in the
+% input stream by the predicate version.
+% \end{function}
+%
+% \begin{function}[EXP]{\fp_if_zero:N}
+% \begin{syntax}
+% \cs{fp_if_zero_p:N} \meta{fixed-point}
+% \cs{fp_if_zero:NTF} \meta{fixed-point} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if \meta{floating point} is equal to zero (\emph{i.e.}~equal to
+% the special \cs{c_zero_fp} variable). The branching versions then
+% leave either \meta{true code} or \meta{false code} in the input
+% stream, as appropriate to the truth of the test and the variant of
+% the function chosen. The logical truth of the test is left in the
+% input stream by the predicate version.
+% \end{function}
+%
+% \begin{function}[TF]{\fp_compare:nNn}
+% \begin{syntax}
+% \cs{fp_compare:nNnTF}
+% ~~\Arg{floating point1} \meta{relation} \Arg{floating point2}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% This function compared the two \meta{floating point} values, which
+% may be stored as \texttt{fp} variables, using the \meta{relation}:
+% \begin{center}
+% \begin{tabular}{ll}
+% Equal & |=| \\
+% Greater than & |>| \\
+% Less than & |<| \\
+% \end{tabular}
+% \end{center}
+% Either \meta{true code} or \meta{false code} is then left in the
+% input stream, as appropriate to the truth of the test and the variant
+% of the function chosen. The tests treat undefined floating points as
+% zero as the comparison is intended for real numbers only.
+% \end{function}
+%
+% \begin{function}[TF]{\fp_compare:n}
+% \begin{syntax}
+% \cs{fp_compare:nTF}
+% ~~\{ \meta{floating point1} \meta{relation} \meta{floating point2} \}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% This function compared the two \meta{floating point} values, which
+% may be stored as \texttt{fp} variables, using the \meta{relation}:
+% \begin{center}
+% \begin{tabular}{ll}
+% Equal & |=| or |==| \\
+% Greater than & |>| \\
+% Greater than or equal & |>=| \\
+% Less than & |<| \\
+% Less than or equal & |<=| \\
+% Not equal & |!=| \\
+% \end{tabular}
+% \end{center}
+% Either \meta{true code} or \meta{false code} is then left in the
+% input stream, as appropriate to the truth of the test and the variant
+% of the function chosen. The tests treat undefined floating points as
+% zero as the comparison is intended for real numbers only.
+% \end{function}
+%
+% \section{Unary floating-point operations}
+%
+% The unary operations alter the value stored within an \texttt{fp}
+% variable.
+%
+% \begin{function}{\fp_abs:N, \fp_abs:c}
+% \begin{syntax}
+% \cs{fp_abs:N} \meta{floating point variable}
+% \end{syntax}
+% Converts the \meta{floating point variable} to its absolute value,
+% assigning the result within the current \TeX\ group.
+% \end{function}
+%
+% \begin{function}{\fp_gabs:N, \fp_gabs:c}
+% \begin{syntax}
+% \cs{fp_gabs:N} \meta{floating point variable}
+% \end{syntax}
+% Converts the \meta{floating point variable} to its absolute value,
+% assigning the result globally.
+% \end{function}
+%
+% \begin{function}{\fp_neg:N, \fp_neg:c}
+% \begin{syntax}
+% \cs{fp_neg:N} \meta{floating point variable}
+% \end{syntax}
+% Reverse the sign of the \meta{floating point variable}, assigning the
+% result within the current \TeX\ group.
+% \end{function}
+%
+% \begin{function}{\fp_gneg:N, \fp_gneg:c}
+% \begin{syntax}
+% \cs{fp_gneg:N} \meta{floating point variable}
+% \end{syntax}
+% Reverse the sign of the \meta{floating point variable}, assigning the
+% result globally.
+% \end{function}
+%
+% \section{Floating-point arithmetic}
+%
+% Binary arithmetic operations act on the value stored in an
+% \texttt{fp}, so for example
+% \begin{verbatim}
+% \fp_set:Nn \l_my_fp { 1.234 }
+% \fp_sub:Nn \l_my_fp { 5.678 }
+% \end{verbatim}
+% sets \cs{l_my_fp} to the result of $1.234 - 5.678$
+% (\emph{i.e.}~$-4.444$).
+%
+% \begin{function}{\fp_add:Nn, \fp_add:cn}
+% \begin{syntax}
+% \cs{fp_add:Nn} \meta{floating point} \Arg{value}
+% \end{syntax}
+% Adds the \meta{value} to the \meta{floating point}, making the
+% assignment within the current \TeX{} group level.
+% \end{function}
+%
+% \begin{function}{\fp_gadd:Nn, \fp_gadd:cn}
+% \begin{syntax}
+% \cs{fp_gadd:Nn} \meta{floating point} \Arg{value}
+% \end{syntax}
+% Adds the \meta{value} to the \meta{floating point}, making the
+% assignment globally.
+% \end{function}
+%
+% \begin{function}{\fp_sub:Nn, \fp_sub:cn}
+% \begin{syntax}
+% \cs{fp_sub:Nn} \meta{floating point} \Arg{value}
+% \end{syntax}
+% Subtracts the \meta{value} from the \meta{floating point}, making the
+% assignment within the current \TeX{} group level.
+% \end{function}
+%
+% \begin{function}{\fp_gsub:Nn, \fp_gsub:cn}
+% \begin{syntax}
+% \cs{fp_gsub:Nn} \meta{floating point} \Arg{value}
+% \end{syntax}
+% Subtracts the \meta{value} from the \meta{floating point}, making the
+% assignment globally.
+% \end{function}
+%
+% \begin{function}{\fp_mul:Nn, \fp_mul:cn}
+% \begin{syntax}
+% \cs{fp_mul:Nn} \meta{floating point} \Arg{value}
+% \end{syntax}
+% Multiples the \meta{floating point} by the \meta{value}, making the
+% assignment within the current \TeX{} group level.
+% \end{function}
+%
+% \begin{function}{\fp_gmul:Nn, \fp_gmul:cn}
+% \begin{syntax}
+% \cs{fp_gmul:Nn} \meta{floating point} \Arg{value}
+% \end{syntax}
+% Multiples the \meta{floating point} by the \meta{value}, making the
+% assignment globally.
+% \end{function}
+%
+% \begin{function}{\fp_div:Nn, \fp_div:cn}
+% \begin{syntax}
+% \cs{fp_div:Nn} \meta{floating point} \Arg{value}
+% \end{syntax}
+% Divides the \meta{floating point} by the \meta{value}, making the
+% assignment within the current \TeX{} group level. If the \meta{value}
+% is zero, the \meta{floating point} will be set to
+% \cs{c_undefined_fp}. The assignment is local.
+% \end{function}
+%
+% \begin{function}{\fp_gdiv:Nn, \fp_gdiv:cn}
+% \begin{syntax}
+% \cs{fp_gdiv:Nn} \meta{floating point} \Arg{value}
+% \end{syntax}
+% Divides the \meta{floating point} by the \meta{value}, making the
+% assignment globally. If the \meta{value} is zero, the
+% \meta{floating point} will be set to \cs{c_undefined_fp}.
+% The assignment is global.
+% \end{function}
+%
+% \section{Floating-point power operations}
+%
+% \begin{function}{\fp_pow:Nn, \fp_pow:cn}
+% \begin{syntax}
+% \cs{fp_pow:Nn} \meta{floating point} \Arg{value}
+% \end{syntax}
+% Raises the \meta{floating point} to the given \meta{value}. If the
+% \meta{floating point} is negative, then the \meta{value} should be
+% either a positive real number or a negative integer. If the
+% \meta{floating point} is positive, then the \meta{value} may be any
+% real value. Mathematically invalid operations such as $0^{0}$
+% will give set the \meta{floating point} to to \cs{c_undefined_fp}.
+% The assignment is local.
+% \end{function}
+%
+% \begin{function}{\fp_gpow:Nn, \fp_gpow:cn}
+% \begin{syntax}
+% \cs{fp_gpow:Nn} \meta{floating point} \Arg{value}
+% \end{syntax}
+% Raises the \meta{floating point} to the given \meta{value}. If the
+% \meta{floating point} is negative, then the \meta{value} should be
+% either a positive real number or a negative integer. If the
+% \meta{floating point} is positive, then the \meta{value} may be any
+% real value. Mathematically invalid operations such as $0^{0}$
+% will give set the \meta{floating point} to to \cs{c_undefined_fp}.
+% The assignment is global.
+% \end{function}
+%
+% \section{Exponential and logarithm functions}
+%
+% \begin{function}{\fp_exp:Nn, \fp_exp:cn}
+% \begin{syntax}
+% \cs{fp_exp:Nn} \meta{floating point} \Arg{value}
+% \end{syntax}
+% Calculates the exponential of the \meta{value} and assigns this
+% to the \meta{floating point}. The assignment is local.
+% \end{function}
+%
+% \begin{function}{\fp_gexp:Nn, \fp_gexp:cn}
+% \begin{syntax}
+% \cs{fp_gexp:Nn} \meta{floating point} \Arg{value}
+% \end{syntax}
+% Calculates the exponential of the \meta{value} and assigns this
+% to the \meta{floating point}. The assignment is global.
+% \end{function}
+%
+% \begin{function}{\fp_ln:Nn, \fp_ln:cn}
+% \begin{syntax}
+% \cs{fp_ln:Nn} \meta{floating point} \Arg{value}
+% \end{syntax}
+% Calculates the natural logarithm of the \meta{value} and assigns
+% this to the \meta{floating point}. The assignment is local.
+% \end{function}
+%
+% \begin{function}{\fp_gln:Nn, \fp_gln:cn}
+% \begin{syntax}
+% \cs{fp_gln:Nn} \meta{floating point} \Arg{value}
+% \end{syntax}
+% Calculates the natural logarithm of the \meta{value} and assigns
+% this to the \meta{floating point}. The assignment is global.
+% \end{function}
+%
+% \section{Trigonometric functions}
+%
+% The trigonometric functions all work in radians. They accept a maximum
+% input value of $100\,000\,000$, as there are issues with range
+% reduction and very large input values.
+%
+% \begin{function}{\fp_sin:Nn, \fp_sin:cn}
+% \begin{syntax}
+% \cs{fp_sin:Nn} \meta{floating point} \Arg{value}
+% \end{syntax}
+% Assigns the sine of the \meta{value} to the \meta{floating point}.
+% The \meta{value} should be given in radians. The assignment is
+% local.
+% \end{function}
+%
+% \begin{function}{\fp_gsin:Nn, \fp_gsin:cn}
+% \begin{syntax}
+% \cs{fp_gsin:Nn} \meta{floating point} \Arg{value}
+% \end{syntax}
+% Assigns the sine of the \meta{value} to the \meta{floating point}.
+% The \meta{value} should be given in radians. The assignment is
+% global.
+% \end{function}
+%
+% \begin{function}{\fp_cos:Nn, \fp_cos:cn}
+% \begin{syntax}
+% \cs{fp_cos:Nn} \meta{floating point} \Arg{value}
+% \end{syntax}
+% Assigns the cosine of the \meta{value} to the \meta{floating point}.
+% The \meta{value} should be given in radians. The assignment is
+% local.
+% \end{function}
+%
+% \begin{function}{\fp_gcos:Nn, \fp_gcos:cn}
+% \begin{syntax}
+% \cs{fp_gcos:Nn} \meta{floating point} \Arg{value}
+% \end{syntax}
+% Assigns the cosine of the \meta{value} to the \meta{floating point}.
+% The \meta{value} should be given in radians. The assignment is
+% global.
+% \end{function}
+%
+% \begin{function}{\fp_tan:Nn, \fp_tan:cn}
+% \begin{syntax}
+% \cs{fp_tan:Nn} \meta{floating point} \Arg{value}
+% \end{syntax}
+% Assigns the tangent of the \meta{value} to the \meta{floating point}.
+% The \meta{value} should be given in radians. The assignment is
+% local.
+% \end{function}
+%
+% \begin{function}{\fp_gtan:Nn, \fp_gtan:cn}
+% \begin{syntax}
+% \cs{fp_gtan:Nn} \meta{floating point} \Arg{value}
+% \end{syntax}
+% Assigns the tangent of the \meta{value} to the \meta{floating point}.
+% The \meta{value} should be given in radians. The assignment is
+% global.
+% \end{function}
+%
+% \section{Constant floating point values}
+%
+% \begin{variable}{\c_e_fp}
+% The value of the base of natural numbers, $\mathrm{e}$.
+% \end{variable}
+%
+% \begin{variable}{\c_one_fp}
+% A floating point variable with permanent value $1$: used for
+% speeding up some comparisons.
+% \end{variable}
+%
+% \begin{variable}{\c_pi_fp}
+% The value of $\pi$.
+% \end{variable}
+%
+% \begin{variable}{\c_undefined_fp}
+% A special marker floating point variable representing the result of
+% an operation which does not give a defined result (such as division
+% by $0$).
+% \end{variable}
+%
+% \begin{variable}{\c_zero_fp}
+% A permanently zero floating point variable.
+% \end{variable}
+%
+% \section{Notes on the floating point unit}
+%
+% As calculation of the elemental transcendental functions is
+% computationally expensive compared to storage of results, after
+% calculating a trigonometric function, exponent, \emph{etc.}~the module
+% stored the result for reuse. Thus the performance of the module for
+% repeated operations, most probably trigonometric functions, should be
+% much higher than if the values were re-calculated every time they
+% were needed.
+%
+% Anyone with experience of programming floating point calculations will
+% know that this is a complex area. The aim of the unit is to be
+% accurate enough for the likely applications in a typesetting context.
+% The arithmetic operations are therefore intended to provide ten digit
+% accuracy with the last digit accurate to $\pm 1$. The elemental
+% transcendental functions may not provide such high accuracy in every
+% case, although the design aim has been to provide $10$ digit
+% accuracy for cases likely to be relevant in typesetting situations.
+% A good overview of the challenges in this area can be found in
+% J.-M.~Muller, \emph{Elementary functions: algorithms and
+% implementation}, 2nd edition, Birkh{\"a}uer Boston, New York, USA,
+% 2006.
+%
+% The internal representation of numbers is tuned to the needs of the
+% underlying \TeX{} system. This means that the format is somewhat
+% different from that used in, for example, computer floating point
+% units. Programming in \TeX{} makes it most convenient to use a
+% radix $10$ system, using \TeX{} \texttt{count} registers for
+% storage and taking advantage where possible of delimited arguments.
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3fp} Implementation}
+%
+% \TestFiles{m3fp003.lvt}
+%
+% \begin{macrocode}
+%<*initex|package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*package>
+\ProvidesExplPackage
+ {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
+\package_check_loaded_expl:
+%</package>
+% \end{macrocode}
+%
+% \subsection{Constants}
+%
+% \begin{variable}{\c_forty_four}
+% \begin{variable}{\c_one_million}
+% \begin{variable}{\c_one_hundred_million}
+% \begin{variable}{\c_five_hundred_million}
+% \begin{variable}{\c_one_thousand_million}
+% There is some speed to gain by moving numbers into fixed positions.
+% \begin{macrocode}
+\int_const:Nn \c_forty_four { 44 }
+\int_const:Nn \c_one_million { 1 000 000 }
+\int_const:Nn \c_one_hundred_million { 100 000 000 }
+\int_const:Nn \c_five_hundred_million { 500 000 000 }
+\int_const:Nn \c_one_thousand_million { 1 000 000 000 }
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+%
+% \begin{variable}{\c_fp_pi_by_four_decimal_int}
+% \begin{variable}{\c_fp_pi_by_four_extended_int}
+% \begin{variable}{\c_fp_pi_decimal_int}
+% \begin{variable}{\c_fp_pi_extended_int}
+% \begin{variable}{\c_fp_two_pi_decimal_int}
+% \begin{variable}{\c_fp_two_pi_extended_int}
+% Parts of $\pi$ for trigonometric range reduction, implemented
+% as \texttt{int} variables for speed.
+% \begin{macrocode}
+\int_new:N \c_fp_pi_by_four_decimal_int
+\int_set:Nn \c_fp_pi_by_four_decimal_int { 785 398 158 }
+\int_new:N \c_fp_pi_by_four_extended_int
+\int_set:Nn \c_fp_pi_by_four_extended_int { 897 448 310 }
+\int_new:N \c_fp_pi_decimal_int
+\int_set:Nn \c_fp_pi_decimal_int { 141 592 653 }
+\int_new:N \c_fp_pi_extended_int
+\int_set:Nn \c_fp_pi_extended_int { 589 793 238 }
+\int_new:N \c_fp_two_pi_decimal_int
+\int_set:Nn \c_fp_two_pi_decimal_int { 283 185 307 }
+\int_new:N \c_fp_two_pi_extended_int
+\int_set:Nn \c_fp_two_pi_extended_int { 179 586 477 }
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+%
+% \begin{variable}{\c_e_fp}
+% The value $\mathrm{e}$ as a \enquote{machine number}.
+% \begin{macrocode}
+\tl_const:Nn \c_e_fp { + 2.718281828 e 0 }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\c_one_fp}
+% The constant value $1$: used for fast comparisons.
+% \begin{macrocode}
+\tl_const:Nn \c_one_fp { + 1.000000000 e 0 }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\c_pi_fp}
+% The value $\pi$ as a \enquote{machine number}.
+% \begin{macrocode}
+\tl_const:Nn \c_pi_fp { + 3.141592654 e 0 }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\c_undefined_fp}
+% A marker for undefined values.
+% \begin{macrocode}
+\tl_const:Nn \c_undefined_fp { X 0.000000000 e 0 }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\c_zero_fp}
+% The constant zero value.
+% \begin{macrocode}
+\tl_const:Nn \c_zero_fp { + 0.000000000 e 0 }
+% \end{macrocode}
+% \end{variable}
+%
+% \subsection{Variables}
+%
+% \begin{variable}{\l_fp_arg_tl}
+% A token list to store the formalised representation of the input
+% for transcendental functions.
+% \begin{macrocode}
+\tl_new:N \l_fp_arg_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_fp_count_int}
+% A counter for things like the number of divisions possible.
+% \begin{macrocode}
+\int_new:N \l_fp_count_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_fp_div_offset_int}
+% When carrying out division, an offset is used for the results to
+% get the decimal part correct.
+% \begin{macrocode}
+\int_new:N \l_fp_div_offset_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_fp_exp_integer_int}
+% \begin{variable}{\l_fp_exp_decimal_int}
+% \begin{variable}{\l_fp_exp_extended_int}
+% \begin{variable}{\l_fp_exp_exponent_int}
+% Used for the calculation of exponent values.
+% \begin{macrocode}
+\int_new:N \l_fp_exp_integer_int
+\int_new:N \l_fp_exp_decimal_int
+\int_new:N \l_fp_exp_extended_int
+\int_new:N \l_fp_exp_exponent_int
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+%
+% \begin{variable}{\l_fp_input_a_sign_int}
+% \begin{variable}{\l_fp_input_a_integer_int}
+% \begin{variable}{\l_fp_input_a_decimal_int}
+% \begin{variable}{\l_fp_input_a_exponent_int}
+% \begin{variable}{\l_fp_input_b_sign_int}
+% \begin{variable}{\l_fp_input_b_integer_int}
+% \begin{variable}{\l_fp_input_b_decimal_int}
+% \begin{variable}{\l_fp_input_b_exponent_int}
+% Storage for the input: two storage areas as there are at most two
+% inputs.
+% \begin{macrocode}
+\int_new:N \l_fp_input_a_sign_int
+\int_new:N \l_fp_input_a_integer_int
+\int_new:N \l_fp_input_a_decimal_int
+\int_new:N \l_fp_input_a_exponent_int
+\int_new:N \l_fp_input_b_sign_int
+\int_new:N \l_fp_input_b_integer_int
+\int_new:N \l_fp_input_b_decimal_int
+\int_new:N \l_fp_input_b_exponent_int
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+%
+% \begin{variable}{\l_fp_input_a_extended_int}
+% \begin{variable}{\l_fp_input_b_extended_int}
+% For internal use, \enquote{extended} floating point numbers are
+% needed.
+% \begin{macrocode}
+\int_new:N \l_fp_input_a_extended_int
+\int_new:N \l_fp_input_b_extended_int
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+%
+% \begin{variable}{\l_fp_mul_a_i_int}
+% \begin{variable}{\l_fp_mul_a_ii_int}
+% \begin{variable}{\l_fp_mul_a_iii_int}
+% \begin{variable}{\l_fp_mul_a_iv_int}
+% \begin{variable}{\l_fp_mul_a_v_int}
+% \begin{variable}{\l_fp_mul_a_vi_int}
+% \begin{variable}{\l_fp_mul_b_i_int}
+% \begin{variable}{\l_fp_mul_b_ii_int}
+% \begin{variable}{\l_fp_mul_b_iii_int}
+% \begin{variable}{\l_fp_mul_b_iv_int}
+% \begin{variable}{\l_fp_mul_b_v_int}
+% \begin{variable}{\l_fp_mul_b_vi_int}
+% Multiplication requires that the decimal part is split into parts
+% so that there are no overflows.
+% \begin{macrocode}
+\int_new:N \l_fp_mul_a_i_int
+\int_new:N \l_fp_mul_a_ii_int
+\int_new:N \l_fp_mul_a_iii_int
+\int_new:N \l_fp_mul_a_iv_int
+\int_new:N \l_fp_mul_a_v_int
+\int_new:N \l_fp_mul_a_vi_int
+\int_new:N \l_fp_mul_b_i_int
+\int_new:N \l_fp_mul_b_ii_int
+\int_new:N \l_fp_mul_b_iii_int
+\int_new:N \l_fp_mul_b_iv_int
+\int_new:N \l_fp_mul_b_v_int
+\int_new:N \l_fp_mul_b_vi_int
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+%
+% \begin{variable}{\l_fp_mul_output_int}
+% \begin{variable}{\l_fp_mul_output_tl}
+% Space for multiplication results.
+% \begin{macrocode}
+\int_new:N \l_fp_mul_output_int
+\tl_new:N \l_fp_mul_output_tl
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+%
+% \begin{variable}{\l_fp_output_sign_int}
+% \begin{variable}{\l_fp_output_integer_int}
+% \begin{variable}{\l_fp_output_decimal_int}
+% \begin{variable}{\l_fp_output_exponent_int}
+% Output is stored in the same way as input.
+% \begin{macrocode}
+\int_new:N \l_fp_output_sign_int
+\int_new:N \l_fp_output_integer_int
+\int_new:N \l_fp_output_decimal_int
+\int_new:N \l_fp_output_exponent_int
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+%
+% \begin{variable}{\l_fp_output_extended_int}
+% Again, for calculations an extended part.
+% \begin{macrocode}
+\int_new:N \l_fp_output_extended_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_fp_round_carry_bool}
+% To indicate that a digit needs to be carried forward.
+% \begin{macrocode}
+\bool_new:N \l_fp_round_carry_bool
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_fp_round_decimal_tl}
+% A temporary store when rounding, to build up the decimal part without
+% needing to do any maths.
+% \begin{macrocode}
+\tl_new:N \l_fp_round_decimal_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_fp_round_position_int}
+% \begin{variable}{\l_fp_round_target_int}
+% Used to check the position for rounding.
+% \begin{macrocode}
+\int_new:N \l_fp_round_position_int
+\int_new:N \l_fp_round_target_int
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+%
+% \begin{variable}{\l_fp_sign_tl}
+% There are places where the sign needs to be set up \enquote{early},
+% so that the registers can be re-used.
+% \begin{macrocode}
+\tl_new:N \l_fp_sign_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_fp_split_sign_int}
+% When splitting the input it is fastest to use a fixed name for the
+% sign part, and to transfer it after the split is complete.
+% \begin{macrocode}
+\int_new:N \l_fp_split_sign_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_fp_tmp_int}
+% A scratch \texttt{int}: used only where the value is not carried
+% forward.
+% \begin{macrocode}
+\int_new:N \l_fp_tmp_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_fp_tmp_tl}
+% A scratch token list variable for expanding material.
+% \begin{macrocode}
+\tl_new:N \l_fp_tmp_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_fp_trig_octant_int}
+% To track which octant the trigonometric input is in.
+% \begin{macrocode}
+\int_new:N \l_fp_trig_octant_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_fp_trig_sign_int}
+% \begin{variable}{\l_fp_trig_decimal_int}
+% \begin{variable}{\l_fp_trig_extended_int}
+% Used for the calculation of trigonometric values.
+% \begin{macrocode}
+\int_new:N \l_fp_trig_sign_int
+\int_new:N \l_fp_trig_decimal_int
+\int_new:N \l_fp_trig_extended_int
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+%
+% \subsection{Parsing numbers}
+%
+% \begin{macro}{\fp_read:N}
+% \begin{macro}[aux]{\fp_read_aux:w}
+% Reading a stored value is made easier as the format is designed to
+% match the delimited function. This is always used to read the first
+% value (register |a|).
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_read:N #1
+ { \exp_after:wN \fp_read_aux:w #1 \q_stop }
+\cs_new_protected_nopar:Npn \fp_read_aux:w #1#2 . #3 e #4 \q_stop
+ {
+ \if:w #1 -
+ \l_fp_input_a_sign_int \c_minus_one
+ \else:
+ \l_fp_input_a_sign_int \c_one
+ \fi:
+ \l_fp_input_a_integer_int #2 \scan_stop:
+ \l_fp_input_a_decimal_int #3 \scan_stop:
+ \l_fp_input_a_exponent_int #4 \scan_stop:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\fp_split:Nn}
+% \begin{macro}[aux]{\fp_split_sign:}
+% \begin{macro}[aux]{\fp_split_exponent:}
+% \begin{macro}[aux]{\fp_split_aux_i:w}
+% \begin{macro}[aux]{\fp_split_aux_ii:w}
+% \begin{macro}[aux]{\fp_split_aux_iii:w}
+% \begin{macro}[aux]{\fp_split_decimal:w}
+% \begin{macro}[aux]{\fp_split_decimal_aux:w}
+% The aim here is to use as much of \TeX{}'s mechanism as possible to pick
+% up the numerical input without any mistakes. In particular, negative
+% numbers have to be filtered out first in case the integer part is
+% $0$ (in which case \TeX{} would drop the |-| sign). That process
+% has to be done in a loop for cases where the sign is repeated.
+% Finding an exponent is relatively easy, after which the next phase is
+% to find the integer part, which will terminate with a |.|, and trigger
+% the decimal-finding code. The later will allow the decimal to be too
+% long, truncating the result.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_split:Nn #1#2
+ {
+ \tl_set:Nx \l_fp_tmp_tl {#2}
+ \tl_set_rescan:Nno \l_fp_tmp_tl { \char_set_catcode_ignore:n { 32 } }
+ { \l_fp_tmp_tl }
+ \l_fp_split_sign_int \c_one
+ \fp_split_sign:
+ \use:c { l_fp_input_ #1 _sign_int } \l_fp_split_sign_int
+ \exp_after:wN \fp_split_exponent:w \l_fp_tmp_tl e e \q_stop #1
+ }
+\cs_new_protected_nopar:Npn \fp_split_sign:
+ {
+ \if_int_compare:w \pdftex_strcmp:D
+ { \exp_after:wN \tl_head:w \l_fp_tmp_tl ? \q_stop } { - }
+ = \c_zero
+ \tl_set:Nx \l_fp_tmp_tl
+ {
+ \exp_after:wN
+ \tl_tail:w \l_fp_tmp_tl \prg_do_nothing: \q_stop
+ }
+ \l_fp_split_sign_int -\l_fp_split_sign_int
+ \exp_after:wN \fp_split_sign:
+ \else:
+ \if_int_compare:w \pdftex_strcmp:D
+ { \exp_after:wN \tl_head:w \l_fp_tmp_tl ? \q_stop } { + }
+ = \c_zero
+ \tl_set:Nx \l_fp_tmp_tl
+ {
+ \exp_after:wN
+ \tl_tail:w \l_fp_tmp_tl \prg_do_nothing: \q_stop
+ }
+ \exp_after:wN \exp_after:wN \exp_after:wN \fp_split_sign:
+ \fi:
+ \fi:
+ }
+\cs_new_protected_nopar:Npn \fp_split_exponent:w #1 e #2 e #3 \q_stop #4
+ {
+ \use:c { l_fp_input_ #4 _exponent_int }
+ \int_eval:w 0 #2 \scan_stop:
+ \tex_afterassignment:D \fp_split_aux_i:w
+ \use:c { l_fp_input_ #4 _integer_int }
+ \int_eval:w 0 #1 . . \q_stop #4
+ }
+\cs_new_protected_nopar:Npn \fp_split_aux_i:w #1 . #2 . #3 \q_stop
+ { \fp_split_aux_ii:w #2 000000000 \q_stop }
+\cs_new_protected_nopar:Npn \fp_split_aux_ii:w #1#2#3#4#5#6#7#8#9
+ { \fp_split_aux_iii:w {#1#2#3#4#5#6#7#8#9} }
+\cs_new_protected_nopar:Npn \fp_split_aux_iii:w #1#2 \q_stop
+ {
+ \l_fp_tmp_int 1 #1 \scan_stop:
+ \exp_after:wN \fp_split_decimal:w
+ \int_use:N \l_fp_tmp_int 000000000 \q_stop
+ }
+\cs_new_protected_nopar:Npn \fp_split_decimal:w #1#2#3#4#5#6#7#8#9
+ { \fp_split_decimal_aux:w {#2#3#4#5#6#7#8#9} }
+\cs_new_protected_nopar:Npn \fp_split_decimal_aux:w #1#2#3 \q_stop #4
+ {
+ \use:c { l_fp_input_ #4 _decimal_int } #1#2 \scan_stop:
+ \if_int_compare:w
+ \int_eval:w
+ \use:c { l_fp_input_ #4 _integer_int } +
+ \use:c { l_fp_input_ #4 _decimal_int }
+ \scan_stop:
+ = \c_zero
+ \use:c { l_fp_input_ #4 _sign_int } \c_one
+ \fi:
+ \if_int_compare:w
+ \use:c { l_fp_input_ #4 _integer_int } < \c_one_thousand_million
+ \else:
+ \exp_after:wN \fp_overflow_msg:
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\fp_standardise:NNNN}
+% \begin{macro}[aux]{\fp_standardise_aux:NNNN}
+% \begin{macro}[aux]{\fp_standardise_aux:}
+% \begin{macro}[aux]{\fp_standardise_aux:w}
+% The idea here is to shift the input into a known exponent range. This
+% is done using \TeX{} tokens where possible, as this is faster than
+% arithmetic.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_standardise:NNNN #1#2#3#4
+ {
+ \if_int_compare:w
+ \int_eval:w #2 + #3 = \c_zero
+ #1 \c_one
+ #4 \c_zero
+ \exp_after:wN \use_none:nnnn
+ \else:
+ \exp_after:wN \fp_standardise_aux:NNNN
+ \fi:
+ #1#2#3#4
+ }
+\cs_new_protected_nopar:Npn \fp_standardise_aux:NNNN #1#2#3#4
+ {
+ \cs_set_protected_nopar:Npn \fp_standardise_aux:
+ {
+ \if_int_compare:w #2 = \c_zero
+ \tex_advance:D #3 \c_one_thousand_million
+ \exp_after:wN \fp_standardise_aux:w
+ \int_use:N #3 \q_stop
+ \exp_after:wN \fp_standardise_aux:
+ \fi:
+ }
+ \cs_set_protected_nopar:Npn
+ \fp_standardise_aux:w ##1##2##3##4##5##6##7##8##9 \q_stop
+ {
+ #2 ##2 \scan_stop:
+ #3 ##3##4##5##6##7##8##9 0 \scan_stop:
+ \tex_advance:D #4 \c_minus_one
+ }
+ \fp_standardise_aux:
+ \cs_set_protected_nopar:Npn \fp_standardise_aux:
+ {
+ \if_int_compare:w #2 > \c_nine
+ \tex_advance:D #2 \c_one_thousand_million
+ \exp_after:wN \use_i:nn \exp_after:wN
+ \fp_standardise_aux:w \int_use:N #2
+ \exp_after:wN \fp_standardise_aux:
+ \fi:
+ }
+ \cs_set_protected_nopar:Npn
+ \fp_standardise_aux:w ##1##2##3##4##5##6##7##8##9
+ {
+ #2 ##1##2##3##4##5##6##7##8 \scan_stop:
+ \tex_advance:D #3 \c_one_thousand_million
+ \tex_divide:D #3 \c_ten
+ \tl_set:Nx \l_fp_tmp_tl
+ {
+ ##9
+ \exp_after:wN \use_none:n \int_use:N #3
+ }
+ #3 \l_fp_tmp_tl \scan_stop:
+ \tex_advance:D #4 \c_one
+ }
+ \fp_standardise_aux:
+ \if_int_compare:w #4 < \c_one_hundred
+ \if_int_compare:w #4 > -\c_one_hundred
+ \else:
+ #1 \c_one
+ #2 \c_zero
+ #3 \c_zero
+ #4 \c_zero
+ \fi:
+ \else:
+ \exp_after:wN \fp_overflow_msg:
+ \fi:
+ }
+\cs_new_protected_nopar:Npn \fp_standardise_aux: { }
+\cs_new_protected_nopar:Npn \fp_standardise_aux:w { }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Internal utilities}
+%
+% \begin{macro}{\fp_level_input_exponents:}
+% \begin{macro}[aux]{\fp_level_input_exponents_a:}
+% \begin{macro}[aux]{\fp_level_input_exponents_a:NNNNNNNNN}
+% \begin{macro}[aux]{\fp_level_input_exponents_b:}
+% \begin{macro}[aux]{\fp_level_input_exponents_b:NNNNNNNNN}
+% The routines here are similar to those used to standardise the
+% exponent. However, the aim here is different: the two exponents need
+% to end up the same.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_level_input_exponents:
+ {
+ \if_int_compare:w \l_fp_input_a_exponent_int > \l_fp_input_b_exponent_int
+ \exp_after:wN \fp_level_input_exponents_a:
+ \else:
+ \exp_after:wN \fp_level_input_exponents_b:
+ \fi:
+ }
+\cs_new_protected_nopar:Npn \fp_level_input_exponents_a:
+ {
+ \if_int_compare:w \l_fp_input_a_exponent_int > \l_fp_input_b_exponent_int
+ \tex_advance:D \l_fp_input_b_integer_int \c_one_thousand_million
+ \exp_after:wN \use_i:nn \exp_after:wN
+ \fp_level_input_exponents_a:NNNNNNNNN
+ \int_use:N \l_fp_input_b_integer_int
+ \exp_after:wN \fp_level_input_exponents_a:
+ \fi:
+ }
+\cs_new_protected_nopar:Npn \fp_level_input_exponents_a:NNNNNNNNN
+ #1#2#3#4#5#6#7#8#9
+ {
+ \l_fp_input_b_integer_int #1#2#3#4#5#6#7#8 \scan_stop:
+ \tex_advance:D \l_fp_input_b_decimal_int \c_one_thousand_million
+ \tex_divide:D \l_fp_input_b_decimal_int \c_ten
+ \tl_set:Nx \l_fp_tmp_tl
+ {
+ #9
+ \exp_after:wN \use_none:n
+ \int_use:N \l_fp_input_b_decimal_int
+ }
+ \l_fp_input_b_decimal_int \l_fp_tmp_tl \scan_stop:
+ \tex_advance:D \l_fp_input_b_exponent_int \c_one
+ }
+\cs_new_protected_nopar:Npn \fp_level_input_exponents_b:
+ {
+ \if_int_compare:w \l_fp_input_b_exponent_int > \l_fp_input_a_exponent_int
+ \tex_advance:D \l_fp_input_a_integer_int \c_one_thousand_million
+ \exp_after:wN \use_i:nn \exp_after:wN
+ \fp_level_input_exponents_b:NNNNNNNNN
+ \int_use:N \l_fp_input_a_integer_int
+ \exp_after:wN \fp_level_input_exponents_b:
+ \fi:
+ }
+\cs_new_protected_nopar:Npn \fp_level_input_exponents_b:NNNNNNNNN
+ #1#2#3#4#5#6#7#8#9
+ {
+ \l_fp_input_a_integer_int #1#2#3#4#5#6#7#8 \scan_stop:
+ \tex_advance:D \l_fp_input_a_decimal_int \c_one_thousand_million
+ \tex_divide:D \l_fp_input_a_decimal_int \c_ten
+ \tl_set:Nx \l_fp_tmp_tl
+ {
+ #9
+ \exp_after:wN \use_none:n
+ \int_use:N \l_fp_input_a_decimal_int
+ }
+ \l_fp_input_a_decimal_int \l_fp_tmp_tl \scan_stop:
+ \tex_advance:D \l_fp_input_a_exponent_int \c_one
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[aux]{\fp_tmp:w}
+% Used for output of results, cutting down on \cs{exp_after:wN}.
+% This is just a place holder definition.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_tmp:w #1#2 { }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Operations for \texttt{fp} variables}
+%
+% The format of \texttt{fp} variables is tightly defined, so that
+% they can be read quickly by the internal code. The format is a single
+% sign token, a single number, the decimal point, nine decimal numbers,
+% an |e| and finally the exponent. This final part may vary in length.
+% When stored, floating points will always be stored with a value in
+% the integer position unless the number is zero.
+%
+% \begin{macro}{\fp_new:N, \fp_new:c}
+% \UnitTested
+% Fixed-points always have a value, and of course this has to be
+% initialised globally.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_new:N #1
+ {
+ \tl_new:N #1
+ \tl_gset_eq:NN #1 \c_zero_fp
+ }
+\cs_generate_variant:Nn \fp_new:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\fp_const:Nn, \fp_const:cn}
+% A simple wrapper.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_const:Nn #1#2
+ {
+ \fp_new:N #1
+ \fp_gset:Nn #1 {#2}
+ }
+\cs_generate_variant:Nn \fp_const:Nn { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\fp_zero:N, \fp_zero:c}
+% \UnitTested
+% \begin{macro}{\fp_gzero:N, \fp_gzero:c}
+% \UnitTested
+% Zeroing fixed-points is pretty obvious.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_zero:N #1
+ { \tl_set_eq:NN #1 \c_zero_fp }
+\cs_new_protected_nopar:Npn \fp_gzero:N #1
+ { \tl_gset_eq:NN #1 \c_zero_fp }
+\cs_generate_variant:Nn \fp_zero:N { c }
+\cs_generate_variant:Nn \fp_gzero:N { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\fp_set:Nn, \fp_set:cn}
+% \UnitTested
+% \begin{macro}{\fp_gset:Nn, \fp_gset:cn}
+% \UnitTested
+% \begin{macro}[aux]{\fp_set_aux:NNn}
+% To trap any input errors, a very simple version of the parser is run
+% here. This will pick up any invalid characters at this stage, saving
+% issues later. The splitting approach is the same as the more
+% advanced function later.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_set:Nn { \fp_set_aux:NNn \tl_set:Nn }
+\cs_new_protected_nopar:Npn \fp_gset:Nn { \fp_set_aux:NNn \tl_gset:Nn }
+\cs_new_protected_nopar:Npn \fp_set_aux:NNn #1#2#3
+ {
+ \group_begin:
+ \fp_split:Nn a {#3}
+ \fp_standardise:NNNN
+ \l_fp_input_a_sign_int
+ \l_fp_input_a_integer_int
+ \l_fp_input_a_decimal_int
+ \l_fp_input_a_exponent_int
+ \tex_advance:D \l_fp_input_a_decimal_int \c_one_thousand_million
+ \cs_set_protected_nopar:Npx \fp_tmp:w
+ {
+ \group_end:
+ #1 \exp_not:N #2
+ {
+ \if_int_compare:w \l_fp_input_a_sign_int < \c_zero
+ -
+ \else:
+ +
+ \fi:
+ \int_use:N \l_fp_input_a_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \int_use:N \l_fp_input_a_decimal_int
+ e
+ \int_use:N \l_fp_input_a_exponent_int
+ }
+ }
+ \fp_tmp:w
+ }
+\cs_generate_variant:Nn \fp_set:Nn { c }
+\cs_generate_variant:Nn \fp_gset:Nn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+%
+%
+% \begin{macro}{\fp_set_from_dim:Nn, \fp_set_from_dim:cn}
+% \UnitTested
+% \begin{macro}{\fp_gset_from_dim:Nn, \fp_gset_from_dim:cn}
+% \UnitTested
+% \begin{macro}[aux]{\fp_set_from_dim_aux:NNn}
+% \begin{macro}[aux]{\fp_set_from_dim_aux:w}
+% \begin{variable}{\l_fp_tmp_dim}
+% \begin{variable}{\l_fp_tmp_skip}
+% Here, dimensions are converted to fixed-points \emph{via} a
+% temporary variable. This ensures that they always convert as points.
+% The code is then essentially the same as for \cs{fp_set:Nn}, but with
+% the dimension passed so that it will be striped of the |pt| on the
+% way through. The passage through a skip is used to remove any rubber
+% part.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_set_from_dim:Nn
+ { \fp_set_from_dim_aux:NNn \tl_set:Nx }
+\cs_new_protected_nopar:Npn \fp_gset_from_dim:Nn
+ { \fp_set_from_dim_aux:NNn \tl_gset:Nx }
+\cs_new_protected_nopar:Npn \fp_set_from_dim_aux:NNn #1#2#3
+ {
+ \group_begin:
+ \l_fp_tmp_skip \etex_glueexpr:D #3 \scan_stop:
+ \l_fp_tmp_dim \l_fp_tmp_skip
+ \fp_split:Nn a
+ {
+ \exp_after:wN \fp_set_from_dim_aux:w
+ \dim_use:N \l_fp_tmp_dim
+ }
+ \fp_standardise:NNNN
+ \l_fp_input_a_sign_int
+ \l_fp_input_a_integer_int
+ \l_fp_input_a_decimal_int
+ \l_fp_input_a_exponent_int
+ \tex_advance:D \l_fp_input_a_decimal_int \c_one_thousand_million
+ \cs_set_protected_nopar:Npx \fp_tmp:w
+ {
+ \group_end:
+ #1 \exp_not:N #2
+ {
+ \if_int_compare:w \l_fp_input_a_sign_int < \c_zero
+ -
+ \else:
+ +
+ \fi:
+ \int_use:N \l_fp_input_a_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \int_use:N \l_fp_input_a_decimal_int
+ e
+ \int_use:N \l_fp_input_a_exponent_int
+ }
+ }
+ \fp_tmp:w
+ }
+\cs_set_protected_nopar:Npx \fp_set_from_dim_aux:w
+ {
+ \cs_set_nopar:Npn \exp_not:N \fp_set_from_dim_aux:w
+ ##1 \tl_to_str:n { pt } {##1}
+ }
+\fp_set_from_dim_aux:w
+\cs_generate_variant:Nn \fp_set_from_dim:Nn { c }
+\cs_generate_variant:Nn \fp_gset_from_dim:Nn { c }
+\dim_new:N \l_fp_tmp_dim
+\skip_new:N \l_fp_tmp_skip
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\fp_set_eq:NN, \fp_set_eq:cN, \fp_set_eq:Nc, \fp_set_eq:cc}
+% \UnitTested
+% \begin{macro}{\fp_gset_eq:NN, \fp_gset_eq:cN, \fp_gset_eq:Nc, \fp_gset_eq:cc}
+% \UnitTested
+% Pretty simple, really.
+% \begin{macrocode}
+\cs_new_eq:NN \fp_set_eq:NN \tl_set_eq:NN
+\cs_new_eq:NN \fp_set_eq:cN \tl_set_eq:cN
+\cs_new_eq:NN \fp_set_eq:Nc \tl_set_eq:Nc
+\cs_new_eq:NN \fp_set_eq:cc \tl_set_eq:cc
+\cs_new_eq:NN \fp_gset_eq:NN \tl_gset_eq:NN
+\cs_new_eq:NN \fp_gset_eq:cN \tl_gset_eq:cN
+\cs_new_eq:NN \fp_gset_eq:Nc \tl_gset_eq:Nc
+\cs_new_eq:NN \fp_gset_eq:cc \tl_gset_eq:cc
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\fp_show:N, \fp_show:c}
+% \UnitTested
+% Simple showing of the underlying variable.
+% \begin{macrocode}
+\cs_new_eq:NN \fp_show:N \tl_show:N
+\cs_new_eq:NN \fp_show:c \tl_show:c
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\fp_use:N, \fp_use:c}
+% \UnitTested
+% \begin{macro}[aux]{\fp_use_aux:w}
+% \begin{macro}[aux]{\fp_use_none:w}
+% \begin{macro}[aux]{\fp_use_small:w}
+% \begin{macro}[aux]{\fp_use_large:w}
+% \begin{macro}[aux]{\fp_use_large_aux_i:w}
+% \begin{macro}[aux]{\fp_use_large_aux_1:w}
+% \begin{macro}[aux]{\fp_use_large_aux_2:w}
+% \begin{macro}[aux]{\fp_use_large_aux_3:w}
+% \begin{macro}[aux]{\fp_use_large_aux_4:w}
+% \begin{macro}[aux]{\fp_use_large_aux_5:w}
+% \begin{macro}[aux]{\fp_use_large_aux_6:w}
+% \begin{macro}[aux]{\fp_use_large_aux_7:w}
+% \begin{macro}[aux]{\fp_use_large_aux_8:w}
+% \begin{macro}[aux]{\fp_use_large_aux_i:w}
+% \begin{macro}[aux]{\fp_use_large_aux_ii:w}
+% The idea of the \cs{fp_use:N} function to convert the stored
+% value into something suitable for \TeX{} to use as a number in an
+% expandable manner. The first step is to deal with the sign, then
+% work out how big the input is.
+% \begin{macrocode}
+\cs_new_nopar:Npn \fp_use:N #1
+ { \exp_after:wN \fp_use_aux:w #1 \q_stop }
+\cs_generate_variant:Nn \fp_use:N { c }
+\cs_new_nopar:Npn \fp_use_aux:w #1#2 e #3 \q_stop
+ {
+ \if:w #1 -
+ -
+ \fi:
+ \if_int_compare:w #3 > \c_zero
+ \exp_after:wN \fp_use_large:w
+ \else:
+ \if_int_compare:w #3 < \c_zero
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \fp_use_small:w
+ \else:
+ \exp_after:wN \exp_after:wN \exp_after:wN \fp_use_none:w
+ \fi:
+ \fi:
+ #2 e #3 \q_stop
+ }
+% \end{macrocode}
+% When the exponent is zero, the input is simply returned as output.
+% \begin{macrocode}
+\cs_new_nopar:Npn \fp_use_none:w #1 e #2 \q_stop {#1}
+% \end{macrocode}
+% For small numbers (less than $1$) the correct number of zeros
+% have to be inserted, but the decimal point is easy.
+% \begin{macrocode}
+\cs_new_nopar:Npn \fp_use_small:w #1 . #2 e #3 \q_stop
+ {
+ 0 .
+ \prg_replicate:nn { -#3 - 1 } { 0 }
+ #1#2
+ }
+% \end{macrocode}
+% Life is more complex for large numbers. The decimal point needs to
+% be shuffled, with potentially some zero-filling for very large values.
+% \begin{macrocode}
+\cs_new_nopar:Npn \fp_use_large:w #1 . #2 e #3 \q_stop
+ {
+ \if_int_compare:w #3 < \c_ten
+ \exp_after:wN \fp_use_large_aux_i:w
+ \else:
+ \exp_after:wN \fp_use_large_aux_ii:w
+ \fi:
+ #1#2 e #3 \q_stop
+ }
+\cs_new_nopar:Npn \fp_use_large_aux_i:w #1#2 e #3 \q_stop
+ {
+ #1
+ \use:c { fp_use_large_aux_ #3 :w } #2 \q_stop
+ }
+\cs_new_nopar:cpn { fp_use_large_aux_1:w } #1#2 \q_stop { #1 . #2 }
+\cs_new_nopar:cpn { fp_use_large_aux_2:w } #1#2#3 \q_stop
+ { #1#2 . #3 }
+\cs_new_nopar:cpn { fp_use_large_aux_3:w } #1#2#3#4 \q_stop
+ { #1#2#3 . #4 }
+\cs_new_nopar:cpn { fp_use_large_aux_4:w } #1#2#3#4#5 \q_stop
+ { #1#2#3#4 . #5 }
+\cs_new_nopar:cpn { fp_use_large_aux_5:w } #1#2#3#4#5#6 \q_stop
+ { #1#2#3#4#5 . #6 }
+\cs_new_nopar:cpn { fp_use_large_aux_6:w } #1#2#3#4#5#6#7 \q_stop
+ { #1#2#3#4#5#6 . #7 }
+\cs_new_nopar:cpn { fp_use_large_aux_7:w } #1#2#3#4#5#6#7#8 \q_stop
+ { #1#2#3#4#6#7 . #8 }
+\cs_new_nopar:cpn { fp_use_large_aux_8:w } #1#2#3#4#5#6#7#8#9 \q_stop
+ { #1#2#3#4#5#6#7#8 . #9 }
+\cs_new_nopar:cpn { fp_use_large_aux_9:w } #1 \q_stop { #1 . }
+\cs_new_nopar:Npn \fp_use_large_aux_ii:w #1 e #2 \q_stop
+ {
+ #1
+ \prg_replicate:nn { #2 - 9 } { 0 }
+ .
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Transferring to other types}
+%
+% The \cs{fp_use:N} function converts a floating point variable to
+% a form that can be used by \TeX{}. Here, the functions are slightly
+% different, as some information may be discarded.
+%
+% \begin{macro}{\fp_to_dim:N, \fp_to_dim:c}
+% A very simple wrapper.
+% \begin{macrocode}
+\cs_new_nopar:Npn \fp_to_dim:N #1 { \fp_use:N #1 pt }
+\cs_generate_variant:Nn \fp_to_dim:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\fp_to_int:N, \fp_to_int:c}
+% \UnitTested
+% \begin{macro}[aux]{\fp_to_int_aux:w}
+% \begin{macro}[aux]{\fp_to_int_none:w}
+% \begin{macro}[aux]{\fp_to_int_small:w}
+% \begin{macro}[aux]{\fp_to_int_large:w}
+% \begin{macro}[aux]{\fp_to_int_large_aux_i:w}
+% \begin{macro}[aux]{\fp_to_int_large_aux_1:w}
+% \begin{macro}[aux]{\fp_to_int_large_aux_2:w}
+% \begin{macro}[aux]{\fp_to_int_large_aux_3:w}
+% \begin{macro}[aux]{\fp_to_int_large_aux_4:w}
+% \begin{macro}[aux]{\fp_to_int_large_aux_5:w}
+% \begin{macro}[aux]{\fp_to_int_large_aux_6:w}
+% \begin{macro}[aux]{\fp_to_int_large_aux_7:w}
+% \begin{macro}[aux]{\fp_to_int_large_aux_8:w}
+% \begin{macro}[aux]{\fp_to_int_large_aux_i:w}
+% \begin{macro}[aux]{\fp_to_int_large_aux:nnn}
+% \begin{macro}[aux]{\fp_to_int_large_aux_ii:w}
+% Converting to integers in an expandable manner is very similar to
+% simply using floating point variables, particularly in the lead-off.
+% \begin{macrocode}
+\cs_new_nopar:Npn \fp_to_int:N #1
+ { \exp_after:wN \fp_to_int_aux:w #1 \q_stop }
+\cs_generate_variant:Nn \fp_to_int:N { c }
+\cs_new_nopar:Npn \fp_to_int_aux:w #1#2 e #3 \q_stop
+ {
+ \if:w #1 -
+ -
+ \fi:
+ \if_int_compare:w #3 < \c_zero
+ \exp_after:wN \fp_to_int_small:w
+ \else:
+ \exp_after:wN \fp_to_int_large:w
+ \fi:
+ #2 e #3 \q_stop
+ }
+% \end{macrocode}
+% For small numbers, if the decimal part is greater than a half then
+% there is rounding up to do.
+% \begin{macrocode}
+\cs_new_nopar:Npn \fp_to_int_small:w #1 . #2 e #3 \q_stop
+ {
+ \if_int_compare:w #3 > \c_one
+ \else:
+ \if_int_compare:w #1 < \c_five
+ 0
+ \else:
+ 1
+ \fi:
+ \fi:
+ }
+% \end{macrocode}
+% For large numbers, the idea is to split off the part for rounding,
+% do the rounding and fill if needed.
+% \begin{macrocode}
+\cs_new_nopar:Npn \fp_to_int_large:w #1 . #2 e #3 \q_stop
+ {
+ \if_int_compare:w #3 < \c_ten
+ \exp_after:wN \fp_to_int_large_aux_i:w
+ \else:
+ \exp_after:wN \fp_to_int_large_aux_ii:w
+ \fi:
+ #1#2 e #3 \q_stop
+ }
+\cs_new_nopar:Npn \fp_to_int_large_aux_i:w #1#2 e #3 \q_stop
+ { \use:c { fp_to_int_large_aux_ #3 :w } #2 \q_stop {#1} }
+\cs_new_nopar:cpn { fp_to_int_large_aux_1:w } #1#2 \q_stop
+ { \fp_to_int_large_aux:nnn { #2 0 } {#1} }
+\cs_new_nopar:cpn { fp_to_int_large_aux_2:w } #1#2#3 \q_stop
+ { \fp_to_int_large_aux:nnn { #3 00 } {#1#2} }
+\cs_new_nopar:cpn { fp_to_int_large_aux_3:w } #1#2#3#4 \q_stop
+ { \fp_to_int_large_aux:nnn { #4 000 } {#1#2#3} }
+\cs_new_nopar:cpn { fp_to_int_large_aux_4:w } #1#2#3#4#5 \q_stop
+ { \fp_to_int_large_aux:nnn { #5 0000 } {#1#2#3#4} }
+\cs_new_nopar:cpn { fp_to_int_large_aux_5:w } #1#2#3#4#5#6 \q_stop
+ { \fp_to_int_large_aux:nnn { #6 00000 } {#1#2#3#4#5} }
+\cs_new_nopar:cpn { fp_to_int_large_aux_6:w } #1#2#3#4#5#6#7 \q_stop
+ { \fp_to_int_large_aux:nnn { #7 000000 } {#1#2#3#4#5#6} }
+\cs_new_nopar:cpn { fp_to_int_large_aux_7:w } #1#2#3#4#5#6#7#8 \q_stop
+ { \fp_to_int_large_aux:nnn { #8 0000000 } {#1#2#3#4#5#6#7} }
+\cs_new_nopar:cpn { fp_to_int_large_aux_8:w } #1#2#3#4#5#6#7#8#9 \q_stop
+ { \fp_to_int_large_aux:nnn { #9 00000000 } {#1#2#3#4#5#6#7#8} }
+\cs_new_nopar:cpn { fp_to_int_large_aux_9:w } #1 \q_stop {#1}
+\cs_new_nopar:Npn \fp_to_int_large_aux:nnn #1#2#3
+ {
+ \if_int_compare:w #1 < \c_five_hundred_million
+ #3#2
+ \else:
+ \int_value:w \int_eval:w #3#2 + 1 \int_eval_end:
+ \fi:
+ }
+\cs_new_nopar:Npn \fp_to_int_large_aux_ii:w #1 e #2 \q_stop
+ {
+ #1
+ \prg_replicate:nn { #2 - 9 } { 0 }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\fp_to_tl:N, \fp_to_tl:c}
+% \UnitTested
+% \begin{macro}[aux]{\fp_to_tl_aux:w}
+% \begin{macro}[aux]{\fp_to_tl_large:w}
+% \begin{macro}[aux]{\fp_to_tl_large_aux_i:w}
+% \begin{macro}[aux]{\fp_to_tl_large_aux_ii:w}
+% \begin{macro}[aux]{\fp_to_tl_large_0:w}
+% \begin{macro}[aux]{\fp_to_tl_large_1:w}
+% \begin{macro}[aux]{\fp_to_tl_large_2:w}
+% \begin{macro}[aux]{\fp_to_tl_large_3:w}
+% \begin{macro}[aux]{\fp_to_tl_large_4:w}
+% \begin{macro}[aux]{\fp_to_tl_large_5:w}
+% \begin{macro}[aux]{\fp_to_tl_large_6:w}
+% \begin{macro}[aux]{\fp_to_tl_large_7:w}
+% \begin{macro}[aux]{\fp_to_tl_large_8:w}
+% \begin{macro}[aux]{\fp_to_tl_large_8_aux:w}
+% \begin{macro}[aux]{\fp_to_tl_large_9:w}
+% \begin{macro}[aux]{\fp_to_tl_small:w}
+% \begin{macro}[aux]{\fp_to_tl_small_one:w}
+% \begin{macro}[aux]{\fp_to_tl_small_two:w}
+% \begin{macro}[aux]{\fp_to_tl_small_aux:w}
+% \begin{macro}[aux]{\fp_to_tl_large_zeros:NNNNNNNNN}
+% \begin{macro}[aux]{\fp_to_tl_small_zeros:NNNNNNNNN}
+% \begin{macro}[aux]{\fp_use_iix_ix:NNNNNNNNN}
+% \begin{macro}[aux]{\fp_use_ix:NNNNNNNNN}
+% \begin{macro}[aux]{\fp_use_i_to_vii:NNNNNNNNN}
+% \begin{macro}[aux]{\fp_use_i_to_iix:NNNNNNNNN}
+% Converting to integers in an expandable manner is very similar to
+% simply using floating point variables, particularly in the lead-off.
+% \begin{macrocode}
+\cs_new_nopar:Npn \fp_to_tl:N #1
+ { \exp_after:wN \fp_to_tl_aux:w #1 \q_stop }
+\cs_generate_variant:Nn \fp_to_tl:N { c }
+\cs_new_nopar:Npn \fp_to_tl_aux:w #1#2 e #3 \q_stop
+ {
+ \if:w #1 -
+ -
+ \fi:
+ \if_int_compare:w #3 < \c_zero
+ \exp_after:wN \fp_to_tl_small:w
+ \else:
+ \exp_after:wN \fp_to_tl_large:w
+ \fi:
+ #2 e #3 \q_stop
+ }
+% \end{macrocode}
+% For \enquote{large} numbers (exponent $\ge 0$) there are two
+% cases. For very large exponents ($ \ge 10 $) life is easy: apart
+% from dropping extra zeros there is no work to do. On the other hand,
+% for intermediate exponent values the decimal needs to be moved, then
+% zeros can be dropped.
+% \begin{macrocode}
+\cs_new_nopar:Npn \fp_to_tl_large:w #1 e #2 \q_stop
+ {
+ \if_int_compare:w #2 < \c_ten
+ \exp_after:wN \fp_to_tl_large_aux_i:w
+ \else:
+ \exp_after:wN \fp_to_tl_large_aux_ii:w
+ \fi:
+ #1 e #2 \q_stop
+ }
+\cs_new_nopar:Npn \fp_to_tl_large_aux_i:w #1 e #2 \q_stop
+ { \use:c { fp_to_tl_large_ #2 :w } #1 \q_stop }
+\cs_new_nopar:Npn \fp_to_tl_large_aux_ii:w #1 . #2 e #3 \q_stop
+ {
+ #1
+ \fp_to_tl_large_zeros:NNNNNNNNN #2
+ e #3
+ }
+\cs_new_nopar:cpn { fp_to_tl_large_0:w } #1 . #2 \q_stop
+ {
+ #1
+ \fp_to_tl_large_zeros:NNNNNNNNN #2
+ }
+\cs_new_nopar:cpn { fp_to_tl_large_1:w } #1 . #2#3 \q_stop
+ {
+ #1#2
+ \fp_to_tl_large_zeros:NNNNNNNNN #3 0
+ }
+\cs_new_nopar:cpn { fp_to_tl_large_2:w } #1 . #2#3#4 \q_stop
+ {
+ #1#2#3
+ \fp_to_tl_large_zeros:NNNNNNNNN #4 00
+ }
+\cs_new_nopar:cpn { fp_to_tl_large_3:w } #1 . #2#3#4#5 \q_stop
+ {
+ #1#2#3#4
+ \fp_to_tl_large_zeros:NNNNNNNNN #5 000
+ }
+\cs_new_nopar:cpn { fp_to_tl_large_4:w } #1 . #2#3#4#5#6 \q_stop
+ {
+ #1#2#3#4#5
+ \fp_to_tl_large_zeros:NNNNNNNNN #6 0000
+ }
+\cs_new_nopar:cpn { fp_to_tl_large_5:w } #1 . #2#3#4#5#6#7 \q_stop
+ {
+ #1#2#3#4#5#6
+ \fp_to_tl_large_zeros:NNNNNNNNN #7 00000
+ }
+\cs_new_nopar:cpn { fp_to_tl_large_6:w } #1 . #2#3#4#5#6#7#8 \q_stop
+ {
+ #1#2#3#4#5#6#7
+ \fp_to_tl_large_zeros:NNNNNNNNN #8 000000
+ }
+\cs_new_nopar:cpn { fp_to_tl_large_7:w } #1 . #2#3#4#5#6#7#8#9 \q_stop
+ {
+ #1#2#3#4#5#6#7#8
+ \fp_to_tl_large_zeros:NNNNNNNNN #9 0000000
+ }
+\cs_new_nopar:cpn { fp_to_tl_large_8:w } #1 .
+ {
+ #1
+ \use:c { fp_to_tl_large_8_aux:w }
+ }
+\cs_new_nopar:cpn { fp_to_tl_large_8_aux:w } #1#2#3#4#5#6#7#8#9 \q_stop
+ {
+ #1#2#3#4#5#6#7#8
+ \fp_to_tl_large_zeros:NNNNNNNNN #9 00000000
+ }
+\cs_new_nopar:cpn { fp_to_tl_large_9:w } #1 . #2 \q_stop {#1#2}
+% \end{macrocode}
+% Dealing with small numbers is a bit more complex as there has to be
+% rounding. This makes life rather awkward, as there need to be a series
+% of tests and calculations, as things cannot be stored in an
+% expandable system.
+% \begin{macrocode}
+\cs_new_nopar:Npn \fp_to_tl_small:w #1 e #2 \q_stop
+ {
+ \if_int_compare:w #2 = \c_minus_one
+ \exp_after:wN \fp_to_tl_small_one:w
+ \else:
+ \if_int_compare:w #2 = -\c_two
+ \exp_after:wN \exp_after:wN \exp_after:wN \fp_to_tl_small_two:w
+ \else:
+ \exp_after:wN \exp_after:wN \exp_after:wN \fp_to_tl_small_aux:w
+ \fi:
+ \fi:
+ #1 e #2 \q_stop
+ }
+\cs_new_nopar:Npn \fp_to_tl_small_one:w #1 . #2 e #3 \q_stop
+ {
+ \if_int_compare:w \fp_use_ix:NNNNNNNNN #2 > \c_four
+ \if_int_compare:w
+ \int_eval:w #1 \fp_use_i_to_iix:NNNNNNNNN #2 + 1
+ < \c_one_thousand_million
+ 0.
+ \exp_after:wN \fp_to_tl_small_zeros:NNNNNNNNN
+ \int_value:w \int_eval:w
+ #1 \fp_use_i_to_iix:NNNNNNNNN #2 + 1
+ \int_eval_end:
+ \else:
+ 1
+ \fi:
+ \else:
+ 0. #1
+ \fp_to_tl_small_zeros:NNNNNNNNN #2
+ \fi:
+ }
+\cs_new_nopar:Npn \fp_to_tl_small_two:w #1 . #2 e #3 \q_stop
+ {
+ \if_int_compare:w \fp_use_iix_ix:NNNNNNNNN #2 > \c_forty_four
+ \if_int_compare:w
+ \int_eval:w #1 \fp_use_i_to_vii:NNNNNNNNN #2 0 + \c_ten
+ < \c_one_thousand_million
+ 0.0
+ \exp_after:wN \fp_to_tl_small_zeros:NNNNNNNNN
+ \int_value:w \int_eval:w
+ #1 \fp_use_i_to_vii:NNNNNNNNN #2 0 + \c_ten
+ \int_eval_end:
+ \else:
+ 0.1
+ \fi:
+ \else:
+ 0.0
+ #1
+ \fp_to_tl_small_zeros:NNNNNNNNN #2
+ \fi:
+ }
+\cs_new_nopar:Npn \fp_to_tl_small_aux:w #1 . #2 e #3 \q_stop
+ {
+ #1
+ \fp_to_tl_large_zeros:NNNNNNNNN #2
+ e #3
+ }
+% \end{macrocode}
+% Rather than a complex recursion, the tests for finding trailing zeros
+% are written out long-hand. The difference between the two is only the
+% need for a decimal marker.
+% \begin{macrocode}
+\cs_new_nopar:Npn \fp_to_tl_large_zeros:NNNNNNNNN #1#2#3#4#5#6#7#8#9
+ {
+ \if_int_compare:w #9 = \c_zero
+ \if_int_compare:w #8 = \c_zero
+ \if_int_compare:w #7 = \c_zero
+ \if_int_compare:w #6 = \c_zero
+ \if_int_compare:w #5 = \c_zero
+ \if_int_compare:w #4 = \c_zero
+ \if_int_compare:w #3 = \c_zero
+ \if_int_compare:w #2 = \c_zero
+ \if_int_compare:w #1 = \c_zero
+ \else:
+ . #1
+ \fi:
+ \else:
+ . #1#2
+ \fi:
+ \else:
+ . #1#2#3
+ \fi:
+ \else:
+ . #1#2#3#4
+ \fi:
+ \else:
+ . #1#2#3#4#5
+ \fi:
+ \else:
+ . #1#2#3#4#5#6
+ \fi:
+ \else:
+ . #1#2#3#4#5#6#7
+ \fi:
+ \else:
+ . #1#2#3#4#5#6#7#8
+ \fi:
+ \else:
+ . #1#2#3#4#5#6#7#8#9
+ \fi:
+ }
+\cs_new_nopar:Npn \fp_to_tl_small_zeros:NNNNNNNNN #1#2#3#4#5#6#7#8#9
+ {
+ \if_int_compare:w #9 = \c_zero
+ \if_int_compare:w #8 = \c_zero
+ \if_int_compare:w #7 = \c_zero
+ \if_int_compare:w #6 = \c_zero
+ \if_int_compare:w #5 = \c_zero
+ \if_int_compare:w #4 = \c_zero
+ \if_int_compare:w #3 = \c_zero
+ \if_int_compare:w #2 = \c_zero
+ \if_int_compare:w #1 = \c_zero
+ \else:
+ #1
+ \fi:
+ \else:
+ #1#2
+ \fi:
+ \else:
+ #1#2#3
+ \fi:
+ \else:
+ #1#2#3#4
+ \fi:
+ \else:
+ #1#2#3#4#5
+ \fi:
+ \else:
+ #1#2#3#4#5#6
+ \fi:
+ \else:
+ #1#2#3#4#5#6#7
+ \fi:
+ \else:
+ #1#2#3#4#5#6#7#8
+ \fi:
+ \else:
+ #1#2#3#4#5#6#7#8#9
+ \fi:
+ }
+% \end{macrocode}
+% Some quick \enquote{return a few} functions.
+% \begin{macrocode}
+\cs_new_nopar:Npn \fp_use_iix_ix:NNNNNNNNN #1#2#3#4#5#6#7#8#9 {#8#9}
+\cs_new_nopar:Npn \fp_use_ix:NNNNNNNNN #1#2#3#4#5#6#7#8#9 {#9}
+\cs_new_nopar:Npn \fp_use_i_to_vii:NNNNNNNNN #1#2#3#4#5#6#7#8#9
+ {#1#2#3#4#5#6#7}
+\cs_new_nopar:Npn \fp_use_i_to_iix:NNNNNNNNN #1#2#3#4#5#6#7#8#9
+ {#1#2#3#4#5#6#7#8}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Rounding numbers}
+%
+% The results may well need to be rounded. A couple of related functions
+% to do this for a stored value.
+%
+% \begin{macro}{\fp_round_figures:Nn, \fp_round_figures:cn}
+% \UnitTested
+% \begin{macro}{\fp_ground_figures:Nn, \fp_ground_figures:cn}
+% \UnitTested
+% \begin{macro}[aux]{\fp_round_figures_aux:NNn}
+% Rounding to figures needs only an adjustment to the target by one
+% (as the target is in decimal places).
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_round_figures:Nn
+ { \fp_round_figures_aux:NNn \tl_set:Nn }
+\cs_generate_variant:Nn \fp_round_figures:Nn { c }
+\cs_new_protected_nopar:Npn \fp_ground_figures:Nn
+ { \fp_round_figures_aux:NNn \tl_gset:Nn }
+\cs_generate_variant:Nn \fp_ground_figures:Nn { c }
+\cs_new_protected_nopar:Npn \fp_round_figures_aux:NNn #1#2#3
+ {
+ \group_begin:
+ \fp_read:N #2
+ \int_set:Nn \l_fp_round_target_int { #3 - 1 }
+ \if_int_compare:w \l_fp_round_target_int < \c_ten
+ \exp_after:wN \fp_round:
+ \fi:
+ \tex_advance:D \l_fp_input_a_decimal_int \c_one_thousand_million
+ \cs_set_protected_nopar:Npx \fp_tmp:w
+ {
+ \group_end:
+ #1 \exp_not:N #2
+ {
+ \if_int_compare:w \l_fp_input_a_sign_int < \c_zero
+ -
+ \else:
+ +
+ \fi:
+ \int_use:N \l_fp_input_a_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \int_use:N \l_fp_input_a_decimal_int
+ e
+ \int_use:N \l_fp_input_a_exponent_int
+ }
+ }
+ \fp_tmp:w
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\fp_round_places:Nn, \fp_round_places:cn}
+% \UnitTested
+% \begin{macro}{\fp_ground_places:Nn, \fp_ground_places:cn}
+% \UnitTested
+% \begin{macro}[aux]{\fp_round_places_aux:NNn}
+% Rounding to places needs an adjustment for the exponent value, which
+% will mean that everything should be correct.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_round_places:Nn
+ { \fp_round_places_aux:NNn \tl_set:Nn }
+\cs_generate_variant:Nn \fp_round_places:Nn { c }
+\cs_new_protected_nopar:Npn \fp_ground_places:Nn
+ { \fp_round_places_aux:NNn \tl_gset:Nn }
+\cs_generate_variant:Nn \fp_ground_places:Nn { c }
+\cs_new_protected_nopar:Npn \fp_round_places_aux:NNn #1#2#3
+ {
+ \group_begin:
+ \fp_read:N #2
+ \int_set:Nn \l_fp_round_target_int
+ { #3 + \l_fp_input_a_exponent_int }
+ \if_int_compare:w \l_fp_round_target_int < \c_ten
+ \exp_after:wN \fp_round:
+ \fi:
+ \tex_advance:D \l_fp_input_a_decimal_int \c_one_thousand_million
+ \cs_set_protected_nopar:Npx \fp_tmp:w
+ {
+ \group_end:
+ #1 \exp_not:N #2
+ {
+ \if_int_compare:w \l_fp_input_a_sign_int < \c_zero
+ -
+ \else:
+ +
+ \fi:
+ \int_use:N \l_fp_input_a_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \int_use:N \l_fp_input_a_decimal_int
+ e
+ \int_use:N \l_fp_input_a_exponent_int
+ }
+ }
+ \fp_tmp:w
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\fp_round:}
+% \begin{macro}[aux]{\fp_round_aux:NNNNNNNNN}
+% \begin{macro}{\fp_round_loop:N}
+% The rounding approach is the same for decimal places and significant
+% figures. There are always nine decimal digits to round, so the code
+% can be written to account for this. The basic logic is simply to
+% find the rounding, track any carry digit and move along. At the end
+% of the loop there is a possible shuffle if the integer part has
+% become $10$.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_round:
+ {
+ \bool_set_false:N \l_fp_round_carry_bool
+ \l_fp_round_position_int \c_eight
+ \tl_clear:N \l_fp_round_decimal_tl
+ \tex_advance:D \l_fp_input_a_decimal_int \c_one_thousand_million
+ \exp_after:wN \use_i:nn \exp_after:wN
+ \fp_round_aux:NNNNNNNNN \int_use:N \l_fp_input_a_decimal_int
+ }
+\cs_new_protected_nopar:Npn \fp_round_aux:NNNNNNNNN #1#2#3#4#5#6#7#8#9
+ {
+ \fp_round_loop:N #9#8#7#6#5#4#3#2#1
+ \bool_if:NT \l_fp_round_carry_bool
+ { \tex_advance:D \l_fp_input_a_integer_int \c_one }
+ \l_fp_input_a_decimal_int \l_fp_round_decimal_tl \scan_stop:
+ \if_int_compare:w \l_fp_input_a_integer_int < \c_ten
+ \else:
+ \l_fp_input_a_integer_int \c_one
+ \tex_divide:D \l_fp_input_a_decimal_int \c_ten
+ \tex_advance:D \l_fp_input_a_exponent_int \c_one
+ \fi:
+ }
+\cs_new_protected_nopar:Npn \fp_round_loop:N #1
+ {
+ \if_int_compare:w \l_fp_round_position_int < \l_fp_round_target_int
+ \bool_if:NTF \l_fp_round_carry_bool
+ { \l_fp_tmp_int \int_eval:w #1 + \c_one \scan_stop: }
+ { \l_fp_tmp_int \int_eval:w #1 \scan_stop: }
+ \if_int_compare:w \l_fp_tmp_int = \c_ten
+ \l_fp_tmp_int \c_zero
+ \else:
+ \bool_set_false:N \l_fp_round_carry_bool
+ \fi:
+ \tl_set:Nx \l_fp_round_decimal_tl
+ { \int_use:N \l_fp_tmp_int \l_fp_round_decimal_tl }
+ \else:
+ \tl_set:Nx \l_fp_round_decimal_tl { 0 \l_fp_round_decimal_tl }
+ \if_int_compare:w \l_fp_round_position_int = \l_fp_round_target_int
+ \if_int_compare:w #1 > \c_four
+ \bool_set_true:N \l_fp_round_carry_bool
+ \fi:
+ \fi:
+ \fi:
+ \tex_advance:D \l_fp_round_position_int \c_minus_one
+ \if_int_compare:w \l_fp_round_position_int > \c_minus_one
+ \exp_after:wN \fp_round_loop:N
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Unary functions}
+%
+% \begin{macro}{\fp_abs:N, \fp_abs:c}
+% \UnitTested
+% \begin{macro}{\fp_gabs:N, \fp_gabs:c}
+% \UnitTested
+% \begin{macro}[aux]{\fp_abs_aux:NN}
+% Setting the absolute value is easy: read the value, ignore the sign,
+% return the result.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_abs:N { \fp_abs_aux:NN \tl_set:Nn }
+\cs_new_protected_nopar:Npn \fp_gabs:N { \fp_abs_aux:NN \tl_gset:Nn }
+\cs_generate_variant:Nn \fp_abs:N { c }
+\cs_generate_variant:Nn \fp_gabs:N { c }
+\cs_new_protected_nopar:Npn \fp_abs_aux:NN #1#2
+ {
+ \group_begin:
+ \fp_read:N #2
+ \tex_advance:D \l_fp_input_a_decimal_int \c_one_thousand_million
+ \cs_set_protected_nopar:Npx \fp_tmp:w
+ {
+ \group_end:
+ #1 \exp_not:N #2
+ {
+ +
+ \int_use:N \l_fp_input_a_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \int_use:N \l_fp_input_a_decimal_int
+ e
+ \int_use:N \l_fp_input_a_exponent_int
+ }
+ }
+ \fp_tmp:w
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\fp_neg:N, \fp_neg:c}
+% \UnitTested
+% \begin{macro}{\fp_gneg:N, \fp_gneg:c}
+% \UnitTested
+% \begin{macro}[aux]{\fp_neg:NN}
+% Just a bit more complex: read the input, reverse the sign and
+% output the result.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_neg:N { \fp_neg_aux:NN \tl_set:Nn }
+\cs_new_protected_nopar:Npn \fp_gneg:N { \fp_neg_aux:NN \tl_gset:Nn }
+\cs_generate_variant:Nn \fp_neg:N { c }
+\cs_generate_variant:Nn \fp_gneg:N { c }
+\cs_new_protected_nopar:Npn \fp_neg_aux:NN #1#2
+ {
+ \group_begin:
+ \fp_read:N #2
+ \tex_advance:D \l_fp_input_a_decimal_int \c_one_thousand_million
+ \tl_set:Nx \l_fp_tmp_tl
+ {
+ \if_int_compare:w \l_fp_input_a_sign_int < \c_zero
+ +
+ \else:
+ -
+ \fi:
+ \int_use:N \l_fp_input_a_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \int_use:N \l_fp_input_a_decimal_int
+ e
+ \int_use:N \l_fp_input_a_exponent_int
+ }
+ \exp_after:wN \group_end: \exp_after:wN
+ #1 \exp_after:wN #2 \exp_after:wN { \l_fp_tmp_tl }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Basic arithmetic}
+%
+% \begin{macro}{\fp_add:Nn, \fp_add:cn}
+% \UnitTested
+% \begin{macro}{\fp_gadd:Nn,\fp_gadd:cn}
+% \UnitTested
+% \begin{macro}[aux]{\fp_add_aux:NNn}
+% \begin{macro}[aux]{\fp_add_core:}
+% \begin{macro}[aux]{\fp_add_sum:}
+% \begin{macro}[aux]{\fp_add_difference:}
+% The various addition functions are simply different ways to call the
+% single master function below. This pattern is repeated for the
+% other arithmetic functions.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_add:Nn { \fp_add_aux:NNn \tl_set:Nn }
+\cs_new_protected_nopar:Npn \fp_gadd:Nn { \fp_add_aux:NNn \tl_gset:Nn }
+\cs_generate_variant:Nn \fp_add:Nn { c }
+\cs_generate_variant:Nn \fp_gadd:Nn { c }
+% \end{macrocode}
+% Addition takes place using one of two paths. If the signs of the
+% two parts are the same, they are simply combined. On the other
+% hand, if the signs are different the calculation finds this
+% difference.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_add_aux:NNn #1#2#3
+ {
+ \group_begin:
+ \fp_read:N #2
+ \fp_split:Nn b {#3}
+ \fp_standardise:NNNN
+ \l_fp_input_b_sign_int
+ \l_fp_input_b_integer_int
+ \l_fp_input_b_decimal_int
+ \l_fp_input_b_exponent_int
+ \fp_add_core:
+ \fp_tmp:w #1#2
+ }
+\cs_new_protected_nopar:Npn \fp_add_core:
+ {
+ \fp_level_input_exponents:
+ \if_int_compare:w
+ \int_eval:w
+ \l_fp_input_a_sign_int * \l_fp_input_b_sign_int
+ > \c_zero
+ \exp_after:wN \fp_add_sum:
+ \else:
+ \exp_after:wN \fp_add_difference:
+ \fi:
+ \l_fp_output_exponent_int \l_fp_input_a_exponent_int
+ \fp_standardise:NNNN
+ \l_fp_output_sign_int
+ \l_fp_output_integer_int
+ \l_fp_output_decimal_int
+ \l_fp_output_exponent_int
+ \cs_set_protected_nopar:Npx \fp_tmp:w ##1##2
+ {
+ \group_end:
+ ##1 ##2
+ {
+ \if_int_compare:w \l_fp_output_sign_int < \c_zero
+ -
+ \else:
+ +
+ \fi:
+ \int_use:N \l_fp_output_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \int_value:w \int_eval:w
+ \l_fp_output_decimal_int + \c_one_thousand_million
+ e
+ \int_use:N \l_fp_output_exponent_int
+ }
+ }
+ }
+% \end{macrocode}
+% Finding the sum of two numbers is trivially easy.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_add_sum:
+ {
+ \l_fp_output_sign_int \l_fp_input_a_sign_int
+ \l_fp_output_integer_int
+ \int_eval:w
+ \l_fp_input_a_integer_int + \l_fp_input_b_integer_int
+ \scan_stop:
+ \l_fp_output_decimal_int
+ \int_eval:w
+ \l_fp_input_a_decimal_int + \l_fp_input_b_decimal_int
+ \scan_stop:
+ \if_int_compare:w \l_fp_output_decimal_int < \c_one_thousand_million
+ \else:
+ \tex_advance:D \l_fp_output_integer_int \c_one
+ \tex_advance:D \l_fp_output_decimal_int -\c_one_thousand_million
+ \fi:
+ }
+% \end{macrocode}
+% When the signs of the two parts of the input are different, the
+% absolute difference is worked out first. There is then a calculation
+% to see which way around everything has worked out, so that the final
+% sign is correct. The difference might also give a zero result with
+% a negative sign, which is reversed as zero is regarded as positive.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_add_difference:
+ {
+ \l_fp_output_integer_int
+ \int_eval:w
+ \l_fp_input_a_integer_int - \l_fp_input_b_integer_int
+ \scan_stop:
+ \l_fp_output_decimal_int
+ \int_eval:w
+ \l_fp_input_a_decimal_int - \l_fp_input_b_decimal_int
+ \scan_stop:
+ \if_int_compare:w \l_fp_output_decimal_int < \c_zero
+ \tex_advance:D \l_fp_output_integer_int \c_minus_one
+ \tex_advance:D \l_fp_output_decimal_int \c_one_thousand_million
+ \fi:
+ \if_int_compare:w \l_fp_output_integer_int < \c_zero
+ \l_fp_output_sign_int \l_fp_input_b_sign_int
+ \if_int_compare:w \l_fp_output_decimal_int = \c_zero
+ \l_fp_output_integer_int -\l_fp_output_integer_int
+ \else:
+ \l_fp_output_decimal_int
+ \int_eval:w
+ \c_one_thousand_million - \l_fp_output_decimal_int
+ \scan_stop:
+ \l_fp_output_integer_int
+ \int_eval:w
+ - \l_fp_output_integer_int - \c_one
+ \scan_stop:
+ \fi:
+ \else:
+ \l_fp_output_sign_int \l_fp_input_a_sign_int
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\fp_sub:Nn, \fp_sub:cn}
+% \UnitTested
+% \begin{macro}{\fp_gsub:Nn,\fp_gsub:cn}
+% \UnitTested
+% \begin{macro}[aux]{\fp_sub_aux:NNn}
+% Subtraction is essentially the same as addition, but with the sign
+% of the second component reversed. Thus the core of the two function
+% groups is the same, with just a little set up here.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_sub:Nn { \fp_sub_aux:NNn \tl_set:Nn }
+\cs_new_protected_nopar:Npn \fp_gsub:Nn { \fp_sub_aux:NNn \tl_gset:Nn }
+\cs_generate_variant:Nn \fp_sub:Nn { c }
+\cs_generate_variant:Nn \fp_gsub:Nn { c }
+\cs_new_protected_nopar:Npn \fp_sub_aux:NNn #1#2#3
+ {
+ \group_begin:
+ \fp_read:N #2
+ \fp_split:Nn b {#3}
+ \fp_standardise:NNNN
+ \l_fp_input_b_sign_int
+ \l_fp_input_b_integer_int
+ \l_fp_input_b_decimal_int
+ \l_fp_input_b_exponent_int
+ \tex_multiply:D \l_fp_input_b_sign_int \c_minus_one
+ \fp_add_core:
+ \fp_tmp:w #1#2
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\fp_mul:Nn, \fp_mul:cn}
+% \UnitTested
+% \begin{macro}{\fp_gmul:Nn,\fp_gmul:cn}
+% \UnitTested
+% \begin{macro}[aux]{\fp_mul_aux:NNn}
+% \begin{macro}[aux]{\fp_mul_internal:}
+% \begin{macro}[aux]{\fp_mul_split:NNNN}
+% \begin{macro}[aux]{\fp_mul_split:w}
+% \begin{macro}[aux]{\fp_mul_end_level:}
+% \begin{macro}[aux]{\fp_mul_end_level:NNNNNNNNN}
+% The pattern is much the same for multiplication.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_mul:Nn { \fp_mul_aux:NNn \tl_set:Nn }
+\cs_new_protected_nopar:Npn \fp_gmul:Nn { \fp_mul_aux:NNn \tl_gset:Nn }
+\cs_generate_variant:Nn \fp_mul:Nn { c }
+\cs_generate_variant:Nn \fp_gmul:Nn { c }
+% \end{macrocode}
+% The approach to multiplication is as follows. First, the two numbers
+% are split into blocks of three digits. These are then multiplied
+% together to find products for each group of three output digits. This
+% is al written out in full for speed reasons. Between each block of
+% three digits in the output, there is a carry step. The very lowest
+% digits are not calculated, while
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_mul_aux:NNn #1#2#3
+ {
+ \group_begin:
+ \fp_read:N #2
+ \fp_split:Nn b {#3}
+ \fp_standardise:NNNN
+ \l_fp_input_b_sign_int
+ \l_fp_input_b_integer_int
+ \l_fp_input_b_decimal_int
+ \l_fp_input_b_exponent_int
+ \fp_mul_internal:
+ \l_fp_output_exponent_int
+ \int_eval:w
+ \l_fp_input_a_exponent_int + \l_fp_input_b_exponent_int
+ \scan_stop:
+ \fp_standardise:NNNN
+ \l_fp_output_sign_int
+ \l_fp_output_integer_int
+ \l_fp_output_decimal_int
+ \l_fp_output_exponent_int
+ \cs_set_protected_nopar:Npx \fp_tmp:w
+ {
+ \group_end:
+ #1 \exp_not:N #2
+ {
+ \if_int_compare:w
+ \int_eval:w
+ \l_fp_input_a_sign_int * \l_fp_input_b_sign_int
+ < \c_zero
+ \if_int_compare:w
+ \int_eval:w
+ \l_fp_output_integer_int + \l_fp_output_decimal_int
+ = \c_zero
+ +
+ \else:
+ -
+ \fi:
+ \else:
+ +
+ \fi:
+ \int_use:N \l_fp_output_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \int_value:w \int_eval:w
+ \l_fp_output_decimal_int + \c_one_thousand_million
+ e
+ \int_use:N \l_fp_output_exponent_int
+ }
+ }
+ \fp_tmp:w
+ }
+% \end{macrocode}
+% Done separately so that the internal use is a bit easier.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_mul_internal:
+ {
+ \fp_mul_split:NNNN \l_fp_input_a_decimal_int
+ \l_fp_mul_a_i_int \l_fp_mul_a_ii_int \l_fp_mul_a_iii_int
+ \fp_mul_split:NNNN \l_fp_input_b_decimal_int
+ \l_fp_mul_b_i_int \l_fp_mul_b_ii_int \l_fp_mul_b_iii_int
+ \l_fp_mul_output_int \c_zero
+ \tl_clear:N \l_fp_mul_output_tl
+ \fp_mul_product:NN \l_fp_mul_a_i_int \l_fp_mul_b_iii_int
+ \fp_mul_product:NN \l_fp_mul_a_ii_int \l_fp_mul_b_ii_int
+ \fp_mul_product:NN \l_fp_mul_a_iii_int \l_fp_mul_b_i_int
+ \tex_divide:D \l_fp_mul_output_int \c_one_thousand
+ \fp_mul_product:NN \l_fp_input_a_integer_int \l_fp_mul_b_iii_int
+ \fp_mul_product:NN \l_fp_mul_a_i_int \l_fp_mul_b_ii_int
+ \fp_mul_product:NN \l_fp_mul_a_ii_int \l_fp_mul_b_i_int
+ \fp_mul_product:NN \l_fp_mul_a_iii_int \l_fp_input_b_integer_int
+ \fp_mul_end_level:
+ \fp_mul_product:NN \l_fp_input_a_integer_int \l_fp_mul_b_ii_int
+ \fp_mul_product:NN \l_fp_mul_a_i_int \l_fp_mul_b_i_int
+ \fp_mul_product:NN \l_fp_mul_a_ii_int \l_fp_input_b_integer_int
+ \fp_mul_end_level:
+ \fp_mul_product:NN \l_fp_input_a_integer_int \l_fp_mul_b_i_int
+ \fp_mul_product:NN \l_fp_mul_a_i_int \l_fp_input_b_integer_int
+ \fp_mul_end_level:
+ \l_fp_output_decimal_int 0 \l_fp_mul_output_tl \scan_stop:
+ \tl_clear:N \l_fp_mul_output_tl
+ \fp_mul_product:NN \l_fp_input_a_integer_int \l_fp_input_b_integer_int
+ \fp_mul_end_level:
+ \l_fp_output_integer_int 0 \l_fp_mul_output_tl \scan_stop:
+ }
+% \end{macrocode}
+% The split works by making a $10$ digit number, from which
+% the first digit can then be dropped using a delimited argument. The
+% groups of three digits are then assigned to the various parts of
+% the input: notice that |##9| contains the last two digits of the
+% smallest part of the input.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_mul_split:NNNN #1#2#3#4
+ {
+ \tex_advance:D #1 \c_one_thousand_million
+ \cs_set_protected_nopar:Npn \fp_mul_split_aux:w
+ ##1##2##3##4##5##6##7##8##9 \q_stop {
+ #2 ##2##3##4 \scan_stop:
+ #3 ##5##6##7 \scan_stop:
+ #4 ##8##9 \scan_stop:
+ }
+ \exp_after:wN \fp_mul_split_aux:w \int_use:N #1 \q_stop
+ \tex_advance:D #1 -\c_one_thousand_million
+ }
+\cs_new_protected_nopar:Npn \fp_mul_product:NN #1#2
+ {
+ \l_fp_mul_output_int
+ \int_eval:w \l_fp_mul_output_int + #1 * #2 \scan_stop:
+ }
+% \end{macrocode}
+% At the end of each output group of three, there is a transfer of
+% information so that there is no danger of an overflow. This is done by
+% expansion to keep the number of calculations down.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_mul_end_level:
+ {
+ \tex_advance:D \l_fp_mul_output_int \c_one_thousand_million
+ \exp_after:wN \use_i:nn \exp_after:wN
+ \fp_mul_end_level:NNNNNNNNN \int_use:N \l_fp_mul_output_int
+ }
+\cs_new_protected_nopar:Npn \fp_mul_end_level:NNNNNNNNN #1#2#3#4#5#6#7#8#9
+ {
+ \tl_set:Nx \l_fp_mul_output_tl { #7#8#9 \l_fp_mul_output_tl }
+ \l_fp_mul_output_int #1#2#3#4#5#6 \scan_stop:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\fp_div:Nn, \fp_div:cn}
+% \UnitTested
+% \begin{macro}{\fp_gdiv:Nn,\fp_gdiv:cn}
+% \UnitTested
+% \begin{macro}[aux]{\fp_div_aux:NNn}
+% \begin{macro}{\fp_div_internal:}
+% \begin{macro}[aux]{\fp_div_loop:}
+% \begin{macro}[aux]{\fp_div_divide:}
+% \begin{macro}[aux]{\fp_div_divide_aux:}
+% \begin{macro}[aux]{\fp_div_store:}
+% \begin{macro}[aux]{\fp_div_store_integer:}
+% \begin{macro}[aux]{\fp_div_store_decimal:}
+% The pattern is much the same for multiplication.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_div:Nn { \fp_div_aux:NNn \tl_set:Nn }
+\cs_new_protected_nopar:Npn \fp_gdiv:Nn { \fp_div_aux:NNn \tl_gset:Nn }
+\cs_generate_variant:Nn \fp_div:Nn { c }
+\cs_generate_variant:Nn \fp_gdiv:Nn { c }
+% \end{macrocode}
+% Division proper starts with a couple of tests. If the denominator is
+% zero then a error is issued. On the other hand, if the numerator is
+% zero then the result must be $0.0$ and can be given with no
+% further work.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_div_aux:NNn #1#2#3
+ {
+ \group_begin:
+ \fp_read:N #2
+ \fp_split:Nn b {#3}
+ \fp_standardise:NNNN
+ \l_fp_input_b_sign_int
+ \l_fp_input_b_integer_int
+ \l_fp_input_b_decimal_int
+ \l_fp_input_b_exponent_int
+ \if_int_compare:w
+ \int_eval:w
+ \l_fp_input_b_integer_int + \l_fp_input_b_decimal_int
+ = \c_zero
+ \cs_set_protected_nopar:Npx \fp_tmp:w ##1##2
+ {
+ \group_end:
+ #1 \exp_not:N #2 { \c_undefined_fp }
+ }
+ \else:
+ \if_int_compare:w
+ \int_eval:w
+ \l_fp_input_a_integer_int + \l_fp_input_a_decimal_int
+ = \c_zero
+ \cs_set_protected_nopar:Npx \fp_tmp:w ##1##2
+ {
+ \group_end:
+ #1 \exp_not:N #2 { \c_zero_fp }
+ }
+ \else:
+ \exp_after:wN \exp_after:wN \exp_after:wN \fp_div_internal:
+ \fi:
+ \fi:
+ \fp_tmp:w #1#2
+ }
+% \end{macrocode}
+% The main division algorithm works by finding how many times |b| can
+% be removed from |a|, storing the result and doing the subtraction.
+% Input |a| is then multiplied by $10$, and the process is repeated.
+% The looping ends either when there is nothing left of |a|
+% (\emph{i.e.}~an exact result) or when the code reaches the ninth
+% decimal place. Most of the process takes place in the loop function
+% below.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_div_internal: {
+ \l_fp_output_integer_int \c_zero
+ \l_fp_output_decimal_int \c_zero
+ \cs_set_eq:NN \fp_div_store: \fp_div_store_integer:
+ \l_fp_div_offset_int \c_one_hundred_million
+ \fp_div_loop:
+ \l_fp_output_exponent_int
+ \int_eval:w
+ \l_fp_input_a_exponent_int - \l_fp_input_b_exponent_int
+ \scan_stop:
+ \fp_standardise:NNNN
+ \l_fp_output_sign_int
+ \l_fp_output_integer_int
+ \l_fp_output_decimal_int
+ \l_fp_output_exponent_int
+ \cs_set_protected_nopar:Npx \fp_tmp:w ##1##2
+ {
+ \group_end:
+ ##1 ##2
+ {
+ \if_int_compare:w
+ \int_eval:w
+ \l_fp_input_a_sign_int * \l_fp_input_b_sign_int
+ < \c_zero
+ \if_int_compare:w
+ \int_eval:w
+ \l_fp_output_integer_int + \l_fp_output_decimal_int
+ = \c_zero
+ +
+ \else:
+ -
+ \fi:
+ \else:
+ +
+ \fi:
+ \int_use:N \l_fp_output_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \int_value:w \int_eval:w
+ \l_fp_output_decimal_int + \c_one_thousand_million
+ \int_eval_end:
+ e
+ \int_use:N \l_fp_output_exponent_int
+ }
+ }
+}
+% \end{macrocode}
+% The main loop implements the approach described above. The storing
+% function is done as a function so that the integer and decimal parts
+% can be done separately but rapidly.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_div_loop:
+ {
+ \l_fp_count_int \c_zero
+ \fp_div_divide:
+ \fp_div_store:
+ \tex_multiply:D \l_fp_input_a_integer_int \c_ten
+ \tex_advance:D \l_fp_input_a_decimal_int \c_one_thousand_million
+ \exp_after:wN \fp_div_loop_step:w
+ \int_use:N \l_fp_input_a_decimal_int \q_stop
+ \if_int_compare:w
+ \int_eval:w \l_fp_input_a_integer_int + \l_fp_input_a_decimal_int
+ > \c_zero
+ \if_int_compare:w \l_fp_div_offset_int > \c_zero
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \fp_div_loop:
+ \fi:
+ \fi:
+ }
+% \end{macrocode}
+% Checking to see if the numerator can be divides needs quite an
+% involved check. Either the integer part has to be bigger for the
+% numerator or, if it is not smaller then the decimal part of the
+% numerator must not be smaller than that of the denominator. Once
+% the test is right the rest is much as elsewhere.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_div_divide:
+ {
+ \if_int_compare:w \l_fp_input_a_integer_int > \l_fp_input_b_integer_int
+ \exp_after:wN \fp_div_divide_aux:
+ \else:
+ \if_int_compare:w \l_fp_input_a_integer_int < \l_fp_input_b_integer_int
+ \else:
+ \if_int_compare:w
+ \l_fp_input_a_decimal_int < \l_fp_input_b_decimal_int
+ \else:
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \exp_after:wN \fp_div_divide_aux:
+ \fi:
+ \fi:
+ \fi:
+ }
+\cs_new_protected_nopar:Npn \fp_div_divide_aux:
+ {
+ \tex_advance:D \l_fp_count_int \c_one
+ \tex_advance:D \l_fp_input_a_integer_int -\l_fp_input_b_integer_int
+ \tex_advance:D \l_fp_input_a_decimal_int -\l_fp_input_b_decimal_int
+ \if_int_compare:w \l_fp_input_a_decimal_int < \c_zero
+ \tex_advance:D \l_fp_input_a_integer_int \c_minus_one
+ \tex_advance:D \l_fp_input_a_decimal_int \c_one_thousand_million
+ \fi:
+ \fp_div_divide:
+ }
+% \end{macrocode}
+% Storing the number of each division is done differently for the
+% integer and decimal. The integer is easy and a one-off, while the
+% decimal also needs to account for the position of the digit to store.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_div_store: { }
+\cs_new_protected_nopar:Npn \fp_div_store_integer:
+ {
+ \l_fp_output_integer_int \l_fp_count_int
+ \cs_set_eq:NN \fp_div_store: \fp_div_store_decimal:
+ }
+\cs_new_protected_nopar:Npn \fp_div_store_decimal:
+ {
+ \l_fp_output_decimal_int
+ \int_eval:w
+ \l_fp_output_decimal_int +
+ \l_fp_count_int * \l_fp_div_offset_int
+ \int_eval_end:
+ \tex_divide:D \l_fp_div_offset_int \c_ten
+ }
+\cs_new_protected_nopar:Npn \fp_div_loop_step:w #1#2#3#4#5#6#7#8#9 \q_stop
+ {
+ \l_fp_input_a_integer_int
+ \int_eval:w #2 + \l_fp_input_a_integer_int \int_eval_end:
+ \l_fp_input_a_decimal_int #3#4#5#6#7#8#9 0 \scan_stop:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Arithmetic for internal use}
+%
+% For the more complex functions, it is only possible to deliver
+% reliable $10$ digit accuracy if the internal calculations are
+% carried out to a higher degree of precision. This is done using a
+% second set of functions so that the `user' versions are not
+% slowed down. These versions are also focussed on the needs of internal
+% calculations. No error checking, sign checking or exponent levelling
+% is done. For addition and subtraction, the arguments are:
+% \begin{itemize}
+% \item Integer part of input |a|.
+% \item Decimal part of input |a|.
+% \item Additional decimal part of input |a|.
+% \item Integer part of input |b|.
+% \item Decimal part of input |b|.
+% \item Additional decimal part of input |b|.
+% \item Integer part of output.
+% \item Decimal part of output.
+% \item Additional decimal part of output.
+% \end{itemize}
+% The situation for multiplication and division is a little different as
+% they only deal with the decimal part.
+%
+% \begin{macro}{\fp_add:NNNNNNNNN}
+% The internal sum is always exactly that: it is always a sum and there
+% is no sign check.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_add:NNNNNNNNN #1#2#3#4#5#6#7#8#9
+ {
+ #7 \int_eval:w #1 + #4 \int_eval_end:
+ #8 \int_eval:w #2 + #5 \int_eval_end:
+ #9 \int_eval:w #3 + #6 \int_eval_end:
+ \if_int_compare:w #9 < \c_one_thousand_million
+ \else:
+ \tex_advance:D #8 \c_one
+ \tex_advance:D #9 -\c_one_thousand_million
+ \fi:
+ \if_int_compare:w #8 < \c_one_thousand_million
+ \else:
+ \tex_advance:D #7 \c_one
+ \tex_advance:D #8 -\c_one_thousand_million
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\fp_sub:NNNNNNNNN}
+% Internal subtraction is needed only when the first number is bigger
+% than the second, so there is no need to worry about the sign. This is
+% a good job as there are no arguments left. The flipping flag is
+% used in the rare case where a sign change is possible.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_sub:NNNNNNNNN #1#2#3#4#5#6#7#8#9
+ {
+ #7 \int_eval:w #1 - #4 \int_eval_end:
+ #8 \int_eval:w #2 - #5 \int_eval_end:
+ #9 \int_eval:w #3 - #6 \int_eval_end:
+ \if_int_compare:w #9 < \c_zero
+ \tex_advance:D #8 \c_minus_one
+ \tex_advance:D #9 \c_one_thousand_million
+ \fi:
+ \if_int_compare:w #8 < \c_zero
+ \tex_advance:D #7 \c_minus_one
+ \tex_advance:D #8 \c_one_thousand_million
+ \fi:
+ \if_int_compare:w #7 < \c_zero
+ \if_int_compare:w \int_eval:w #8 + #9 = \c_zero
+ #7 -#7
+ \else:
+ \tex_advance:D #7 \c_one
+ #8 \int_eval:w \c_one_thousand_million - #8 \int_eval_end:
+ #9 \int_eval:w \c_one_thousand_million - #9 \int_eval_end:
+ \fi:
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\fp_mul:NNNNNN}
+% Decimal-part only multiplication but with higher accuracy than the
+% user version.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_mul:NNNNNN #1#2#3#4#5#6
+ {
+ \fp_mul_split:NNNN #1
+ \l_fp_mul_a_i_int \l_fp_mul_a_ii_int \l_fp_mul_a_iii_int
+ \fp_mul_split:NNNN #2
+ \l_fp_mul_a_iv_int \l_fp_mul_a_v_int \l_fp_mul_a_vi_int
+ \fp_mul_split:NNNN #3
+ \l_fp_mul_b_i_int \l_fp_mul_b_ii_int \l_fp_mul_b_iii_int
+ \fp_mul_split:NNNN #4
+ \l_fp_mul_b_iv_int \l_fp_mul_b_v_int \l_fp_mul_b_vi_int
+ \l_fp_mul_output_int \c_zero
+ \tl_clear:N \l_fp_mul_output_tl
+ \fp_mul_product:NN \l_fp_mul_a_i_int \l_fp_mul_b_vi_int
+ \fp_mul_product:NN \l_fp_mul_a_ii_int \l_fp_mul_b_v_int
+ \fp_mul_product:NN \l_fp_mul_a_iii_int \l_fp_mul_b_iv_int
+ \fp_mul_product:NN \l_fp_mul_a_iv_int \l_fp_mul_b_iii_int
+ \fp_mul_product:NN \l_fp_mul_a_v_int \l_fp_mul_b_ii_int
+ \fp_mul_product:NN \l_fp_mul_a_vi_int \l_fp_mul_b_i_int
+ \tex_divide:D \l_fp_mul_output_int \c_one_thousand
+ \fp_mul_product:NN \l_fp_mul_a_i_int \l_fp_mul_b_v_int
+ \fp_mul_product:NN \l_fp_mul_a_ii_int \l_fp_mul_b_iv_int
+ \fp_mul_product:NN \l_fp_mul_a_iii_int \l_fp_mul_b_iii_int
+ \fp_mul_product:NN \l_fp_mul_a_iv_int \l_fp_mul_b_ii_int
+ \fp_mul_product:NN \l_fp_mul_a_v_int \l_fp_mul_b_i_int
+ \fp_mul_end_level:
+ \fp_mul_product:NN \l_fp_mul_a_i_int \l_fp_mul_b_iv_int
+ \fp_mul_product:NN \l_fp_mul_a_ii_int \l_fp_mul_b_iii_int
+ \fp_mul_product:NN \l_fp_mul_a_iii_int \l_fp_mul_b_ii_int
+ \fp_mul_product:NN \l_fp_mul_a_iv_int \l_fp_mul_b_i_int
+ \fp_mul_end_level:
+ \fp_mul_product:NN \l_fp_mul_a_i_int \l_fp_mul_b_iii_int
+ \fp_mul_product:NN \l_fp_mul_a_ii_int \l_fp_mul_b_ii_int
+ \fp_mul_product:NN \l_fp_mul_a_iii_int \l_fp_mul_b_i_int
+ \fp_mul_end_level:
+ #6 0 \l_fp_mul_output_tl \scan_stop:
+ \tl_clear:N \l_fp_mul_output_tl
+ \fp_mul_product:NN \l_fp_mul_a_i_int \l_fp_mul_b_ii_int
+ \fp_mul_product:NN \l_fp_mul_a_ii_int \l_fp_mul_b_i_int
+ \fp_mul_end_level:
+ \fp_mul_product:NN \l_fp_mul_a_i_int \l_fp_mul_b_i_int
+ \fp_mul_end_level:
+ \fp_mul_end_level:
+ #5 0 \l_fp_mul_output_tl \scan_stop:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\fp_mul:NNNNNNNNN}
+% For internal multiplication where the integer does need to be
+% retained. This means of course that this code is quite slow, and so
+% is only used when necessary.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_mul:NNNNNNNNN #1#2#3#4#5#6#7#8#9
+ {
+ \fp_mul_split:NNNN #2
+ \l_fp_mul_a_i_int \l_fp_mul_a_ii_int \l_fp_mul_a_iii_int
+ \fp_mul_split:NNNN #3
+ \l_fp_mul_a_iv_int \l_fp_mul_a_v_int \l_fp_mul_a_vi_int
+ \fp_mul_split:NNNN #5
+ \l_fp_mul_b_i_int \l_fp_mul_b_ii_int \l_fp_mul_b_iii_int
+ \fp_mul_split:NNNN #6
+ \l_fp_mul_b_iv_int \l_fp_mul_b_v_int \l_fp_mul_b_vi_int
+ \l_fp_mul_output_int \c_zero
+ \tl_clear:N \l_fp_mul_output_tl
+ \fp_mul_product:NN \l_fp_mul_a_i_int \l_fp_mul_b_vi_int
+ \fp_mul_product:NN \l_fp_mul_a_ii_int \l_fp_mul_b_v_int
+ \fp_mul_product:NN \l_fp_mul_a_iii_int \l_fp_mul_b_iv_int
+ \fp_mul_product:NN \l_fp_mul_a_iv_int \l_fp_mul_b_iii_int
+ \fp_mul_product:NN \l_fp_mul_a_v_int \l_fp_mul_b_ii_int
+ \fp_mul_product:NN \l_fp_mul_a_vi_int \l_fp_mul_b_i_int
+ \tex_divide:D \l_fp_mul_output_int \c_one_thousand
+ \fp_mul_product:NN #1 \l_fp_mul_b_vi_int
+ \fp_mul_product:NN \l_fp_mul_a_i_int \l_fp_mul_b_v_int
+ \fp_mul_product:NN \l_fp_mul_a_ii_int \l_fp_mul_b_iv_int
+ \fp_mul_product:NN \l_fp_mul_a_iii_int \l_fp_mul_b_iii_int
+ \fp_mul_product:NN \l_fp_mul_a_iv_int \l_fp_mul_b_ii_int
+ \fp_mul_product:NN \l_fp_mul_a_v_int \l_fp_mul_b_i_int
+ \fp_mul_product:NN \l_fp_mul_a_vi_int #4
+ \fp_mul_end_level:
+ \fp_mul_product:NN #1 \l_fp_mul_b_v_int
+ \fp_mul_product:NN \l_fp_mul_a_i_int \l_fp_mul_b_iv_int
+ \fp_mul_product:NN \l_fp_mul_a_ii_int \l_fp_mul_b_iii_int
+ \fp_mul_product:NN \l_fp_mul_a_iii_int \l_fp_mul_b_ii_int
+ \fp_mul_product:NN \l_fp_mul_a_iv_int \l_fp_mul_b_i_int
+ \fp_mul_product:NN \l_fp_mul_a_v_int #4
+ \fp_mul_end_level:
+ \fp_mul_product:NN #1 \l_fp_mul_b_iv_int
+ \fp_mul_product:NN \l_fp_mul_a_i_int \l_fp_mul_b_iii_int
+ \fp_mul_product:NN \l_fp_mul_a_ii_int \l_fp_mul_b_ii_int
+ \fp_mul_product:NN \l_fp_mul_a_iii_int \l_fp_mul_b_i_int
+ \fp_mul_product:NN \l_fp_mul_a_iv_int #4
+ \fp_mul_end_level:
+ #9 0 \l_fp_mul_output_tl \scan_stop:
+ \tl_clear:N \l_fp_mul_output_tl
+ \fp_mul_product:NN #1 \l_fp_mul_b_iii_int
+ \fp_mul_product:NN \l_fp_mul_a_i_int \l_fp_mul_b_ii_int
+ \fp_mul_product:NN \l_fp_mul_a_ii_int \l_fp_mul_b_i_int
+ \fp_mul_product:NN \l_fp_mul_a_iii_int #4
+ \fp_mul_end_level:
+ \fp_mul_product:NN #1 \l_fp_mul_b_ii_int
+ \fp_mul_product:NN \l_fp_mul_a_i_int \l_fp_mul_b_i_int
+ \fp_mul_product:NN \l_fp_mul_a_ii_int #4
+ \fp_mul_end_level:
+ \fp_mul_product:NN #1 \l_fp_mul_b_i_int
+ \fp_mul_product:NN \l_fp_mul_a_i_int #4
+ \fp_mul_end_level:
+ #8 0 \l_fp_mul_output_tl \scan_stop:
+ \tl_clear:N \l_fp_mul_output_tl
+ \fp_mul_product:NN #1 #4
+ \fp_mul_end_level:
+ #7 0 \l_fp_mul_output_tl \scan_stop:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\fp_div_integer:NNNNN}
+% Here, division is always by an integer, and so it is possible to
+% use \TeX{}'s native calculations rather than doing it in macros.
+% The idea here is to divide the decimal part, find any remainder,
+% then do the real division of the two parts before adding in what
+% is needed for the remainder.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_div_integer:NNNNN #1#2#3#4#5
+ {
+ \l_fp_tmp_int #1
+ \tex_divide:D \l_fp_tmp_int #3
+ \l_fp_tmp_int \int_eval:w #1 - \l_fp_tmp_int * #3 \int_eval_end:
+ #4 #1
+ \tex_divide:D #4 #3
+ #5 #2
+ \tex_divide:D #5 #3
+ \tex_multiply:D \l_fp_tmp_int \c_one_thousand
+ \tex_divide:D \l_fp_tmp_int #3
+ #5 \int_eval:w #5 + \l_fp_tmp_int * \c_one_million \int_eval_end:
+ \if_int_compare:w #5 > \c_one_thousand_million
+ \tex_advance:D #4 \c_one
+ \tex_advance:D #5 -\c_one_thousand_million
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\fp_extended_normalise:}
+% \begin{macro}[aux]{\fp_extended_normalise_aux_i:}
+% \begin{macro}[aux]{\fp_extended_normalise_aux_i:w}
+% \begin{macro}[aux]{\fp_extended_normalise_aux_ii:w}
+% \begin{macro}[aux]{\fp_extended_normalise_aux_ii:}
+% \begin{macro}[aux]{\fp_extended_normalise_aux:NNNNNNNNN}
+% The \enquote{extended} integers for internal use are mainly used in
+% fixed-point mode. This comes up in a few places, so a generalised
+% utility is made available to carry out the change. This function
+% simply calls the two loops to shift the input to the point of
+% having a zero exponent.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_extended_normalise:
+ {
+ \fp_extended_normalise_aux_i:
+ \fp_extended_normalise_aux_ii:
+ }
+\cs_new_protected_nopar:Npn \fp_extended_normalise_aux_i:
+ {
+ \if_int_compare:w \l_fp_input_a_exponent_int > \c_zero
+ \tex_multiply:D \l_fp_input_a_integer_int \c_ten
+ \tex_advance:D \l_fp_input_a_decimal_int \c_one_thousand_million
+ \exp_after:wN \fp_extended_normalise_aux_i:w
+ \int_use:N \l_fp_input_a_decimal_int \q_stop
+ \exp_after:wN \fp_extended_normalise_aux_i:
+ \fi:
+ }
+\cs_new_protected_nopar:Npn \fp_extended_normalise_aux_i:w
+ #1#2#3#4#5#6#7#8#9 \q_stop
+ {
+ \l_fp_input_a_integer_int
+ \int_eval:w \l_fp_input_a_integer_int + #2 \scan_stop:
+ \l_fp_input_a_decimal_int #3#4#5#6#7#8#9 0 \scan_stop:
+ \tex_advance:D \l_fp_input_a_extended_int \c_one_thousand_million
+ \exp_after:wN \fp_extended_normalise_aux_ii:w
+ \int_use:N \l_fp_input_a_extended_int \q_stop
+ }
+\cs_new_protected_nopar:Npn \fp_extended_normalise_aux_ii:w
+ #1#2#3#4#5#6#7#8#9 \q_stop
+ {
+ \l_fp_input_a_decimal_int
+ \int_eval:w \l_fp_input_a_decimal_int + #2 \scan_stop:
+ \l_fp_input_a_extended_int #3#4#5#6#7#8#9 0 \scan_stop:
+ \tex_advance:D \l_fp_input_a_exponent_int \c_minus_one
+ }
+\cs_new_protected_nopar:Npn \fp_extended_normalise_aux_ii:
+ {
+ \if_int_compare:w \l_fp_input_a_exponent_int < \c_zero
+ \tex_advance:D \l_fp_input_a_decimal_int \c_one_thousand_million
+ \exp_after:wN \use_i:nn \exp_after:wN
+ \fp_extended_normalise_ii_aux:NNNNNNNNN
+ \int_use:N \l_fp_input_a_decimal_int
+ \exp_after:wN \fp_extended_normalise_aux_ii:
+ \fi:
+ }
+\cs_new_protected_nopar:Npn \fp_extended_normalise_ii_aux:NNNNNNNNN
+ #1#2#3#4#5#6#7#8#9
+ {
+ \if_int_compare:w \l_fp_input_a_integer_int = \c_zero
+ \l_fp_input_a_decimal_int #1#2#3#4#5#6#7#8 \scan_stop:
+ \else:
+ \tl_set:Nx \l_fp_tmp_tl
+ {
+ \int_use:N \l_fp_input_a_integer_int
+ #1#2#3#4#5#6#7#8
+ }
+ \l_fp_input_a_integer_int \c_zero
+ \l_fp_input_a_decimal_int \l_fp_tmp_tl \scan_stop:
+ \fi:
+ \tex_divide:D \l_fp_input_a_extended_int \c_ten
+ \tl_set:Nx \l_fp_tmp_tl
+ {
+ #9
+ \int_use:N \l_fp_input_a_extended_int
+ }
+ \l_fp_input_a_extended_int \l_fp_tmp_tl \scan_stop:
+ \tex_advance:D \l_fp_input_a_exponent_int \c_one
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\fp_extended_normalise_output:}
+% \begin{macro}[aux]{\fp_extended_normalise_output_aux_i:NNNNNNNNN}
+% \begin{macro}[aux]{\fp_extended_normalise_output_aux_ii:NNNNNNNNN}
+% \begin{macro}[aux]{\fp_extended_normalise_output_aux:N}
+% At some stages in working out extended output, it is possible for the
+% value to need shifting to keep the integer part in range. This only
+% ever happens such that the integer needs to be made smaller.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_extended_normalise_output:
+ {
+ \if_int_compare:w \l_fp_output_integer_int > \c_nine
+ \tex_advance:D \l_fp_output_integer_int \c_one_thousand_million
+ \exp_after:wN \use_i:nn \exp_after:wN
+ \fp_extended_normalise_output_aux_i:NNNNNNNNN
+ \int_use:N \l_fp_output_integer_int
+ \exp_after:wN \fp_extended_normalise_output:
+ \fi:
+ }
+\cs_new_protected_nopar:Npn \fp_extended_normalise_output_aux_i:NNNNNNNNN
+ #1#2#3#4#5#6#7#8#9
+ {
+ \l_fp_output_integer_int #1#2#3#4#5#6#7#8 \scan_stop:
+ \tex_advance:D \l_fp_output_decimal_int \c_one_thousand_million
+ \tl_set:Nx \l_fp_tmp_tl
+ {
+ #9
+ \exp_after:wN \use_none:n
+ \int_use:N \l_fp_output_decimal_int
+ }
+ \exp_after:wN \fp_extended_normalise_output_aux_ii:NNNNNNNNN
+ \l_fp_tmp_tl
+ }
+\cs_new_protected_nopar:Npn \fp_extended_normalise_output_aux_ii:NNNNNNNNN
+ #1#2#3#4#5#6#7#8#9
+ {
+ \l_fp_output_decimal_int #1#2#3#4#5#6#7#8#9 \scan_stop:
+ \fp_extended_normalise_output_aux:N
+ }
+\cs_new_protected_nopar:Npn \fp_extended_normalise_output_aux:N #1
+ {
+ \tex_advance:D \l_fp_output_extended_int \c_one_thousand_million
+ \tex_divide:D \l_fp_output_extended_int \c_ten
+ \tl_set:Nx \l_fp_tmp_tl
+ {
+ #1
+ \exp_after:wN \use_none:n
+ \int_use:N \l_fp_output_extended_int
+ }
+ \l_fp_output_extended_int \l_fp_tmp_tl \scan_stop:
+ \tex_advance:D \l_fp_output_exponent_int \c_one
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Trigonometric functions}
+%
+% \begin{macro}{\fp_trig_normalise:}
+% \begin{macro}[aux]{\fp_trig_normalise_aux:}
+% \begin{macro}[aux]{\fp_trig_sub:NNN}
+% For normalisation, the code essentially switches to fixed-point
+% arithmetic. There is a shift of the exponent, then repeated
+% subtractions. The end result is a number in the range
+% $ -\pi < x \le \pi $.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_trig_normalise:
+ {
+ \if_int_compare:w \l_fp_input_a_exponent_int < \c_ten
+ \l_fp_input_a_extended_int \c_zero
+ \fp_extended_normalise:
+ \fp_trig_normalise_aux:
+ \if_int_compare:w \l_fp_input_a_integer_int < \c_zero
+ \l_fp_input_a_sign_int -\l_fp_input_a_sign_int
+ \l_fp_input_a_integer_int -\l_fp_input_a_integer_int
+ \fi:
+ \exp_after:wN \fp_trig_octant:
+ \else:
+ \l_fp_input_a_sign_int \c_one
+ \l_fp_output_integer_int \c_zero
+ \l_fp_output_decimal_int \c_zero
+ \l_fp_output_exponent_int \c_zero
+ \exp_after:wN \fp_trig_overflow_msg:
+ \fi:
+ }
+\cs_new_protected_nopar:Npn \fp_trig_normalise_aux:
+ {
+ \if_int_compare:w \l_fp_input_a_integer_int > \c_three
+ \fp_trig_sub:NNN
+ \c_six \c_fp_two_pi_decimal_int \c_fp_two_pi_extended_int
+ \exp_after:wN \fp_trig_normalise_aux:
+ \else:
+ \if_int_compare:w \l_fp_input_a_integer_int > \c_two
+ \if_int_compare:w \l_fp_input_a_decimal_int > \c_fp_pi_decimal_int
+ \fp_trig_sub:NNN
+ \c_six \c_fp_two_pi_decimal_int \c_fp_two_pi_extended_int
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \exp_after:wN \fp_trig_normalise_aux:
+ \fi:
+ \fi:
+ \fi:
+ }
+% \end{macrocode}
+% Here, there may be a sign change but there will never be any
+% variation in the input. So a dedicated function can be used.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_trig_sub:NNN #1#2#3
+ {
+ \l_fp_input_a_integer_int
+ \int_eval:w \l_fp_input_a_integer_int - #1 \int_eval_end:
+ \l_fp_input_a_decimal_int
+ \int_eval:w \l_fp_input_a_decimal_int - #2 \int_eval_end:
+ \l_fp_input_a_extended_int
+ \int_eval:w \l_fp_input_a_extended_int - #3 \int_eval_end:
+ \if_int_compare:w \l_fp_input_a_extended_int < \c_zero
+ \tex_advance:D \l_fp_input_a_decimal_int \c_minus_one
+ \tex_advance:D \l_fp_input_a_extended_int \c_one_thousand_million
+ \fi:
+ \if_int_compare:w \l_fp_input_a_decimal_int < \c_zero
+ \tex_advance:D \l_fp_input_a_integer_int \c_minus_one
+ \tex_advance:D \l_fp_input_a_decimal_int \c_one_thousand_million
+ \fi:
+ \if_int_compare:w \l_fp_input_a_integer_int < \c_zero
+ \l_fp_input_a_sign_int -\l_fp_input_a_sign_int
+ \if_int_compare:w
+ \int_eval:w
+ \l_fp_input_a_decimal_int + \l_fp_input_a_extended_int
+ = \c_zero
+ \l_fp_input_a_integer_int -\l_fp_input_a_integer_int
+ \else:
+ \l_fp_input_a_integer_int
+ \int_eval:w
+ - \l_fp_input_a_integer_int - \c_one
+ \int_eval_end:
+ \l_fp_input_a_decimal_int
+ \int_eval:w
+ \c_one_thousand_million - \l_fp_input_a_decimal_int
+ \int_eval_end:
+ \l_fp_input_a_extended_int
+ \int_eval:w
+ \c_one_thousand_million - \l_fp_input_a_extended_int
+ \int_eval_end:
+ \fi:
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\fp_trig_octant:}
+% \begin{macro}[aux]{\fp_trig_octant_aux:}
+% Here, the input is further reduced into the range
+% $ 0 \le x < \pi / 4 $. This is pretty simple: check if
+% $ \pi / 4 $ can be taken off and if it can do it and loop. The
+% check at the end is to \enquote{mop up} values which are so close to
+% $ \pi / 4 $ that they should be treated as such. The test for
+% an even octant is needed as the `remainder' needed is from
+% the nearest $ \pi / 2 $.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_trig_octant:
+ {
+ \l_fp_trig_octant_int \c_one
+ \fp_trig_octant_aux:
+ \if_int_compare:w \l_fp_input_a_decimal_int < \c_ten
+ \l_fp_input_a_decimal_int \c_zero
+ \l_fp_input_a_extended_int \c_zero
+ \fi:
+ \if_int_odd:w \l_fp_trig_octant_int
+ \else:
+ \fp_sub:NNNNNNNNN
+ \c_zero \c_fp_pi_by_four_decimal_int \c_fp_pi_by_four_extended_int
+ \l_fp_input_a_integer_int \l_fp_input_a_decimal_int
+ \l_fp_input_a_extended_int
+ \l_fp_input_a_integer_int \l_fp_input_a_decimal_int
+ \l_fp_input_a_extended_int
+ \fi:
+ }
+\cs_new_protected_nopar:Npn \fp_trig_octant_aux:
+ {
+ \if_int_compare:w \l_fp_input_a_integer_int > \c_zero
+ \fp_sub:NNNNNNNNN
+ \l_fp_input_a_integer_int \l_fp_input_a_decimal_int
+ \l_fp_input_a_extended_int
+ \c_zero \c_fp_pi_by_four_decimal_int \c_fp_pi_by_four_extended_int
+ \l_fp_input_a_integer_int \l_fp_input_a_decimal_int
+ \l_fp_input_a_extended_int
+ \tex_advance:D \l_fp_trig_octant_int \c_one
+ \exp_after:wN \fp_trig_octant_aux:
+ \else:
+ \if_int_compare:w
+ \l_fp_input_a_decimal_int > \c_fp_pi_by_four_decimal_int
+ \fp_sub:NNNNNNNNN
+ \l_fp_input_a_integer_int \l_fp_input_a_decimal_int
+ \l_fp_input_a_extended_int
+ \c_zero \c_fp_pi_by_four_decimal_int
+ \c_fp_pi_by_four_extended_int
+ \l_fp_input_a_integer_int \l_fp_input_a_decimal_int
+ \l_fp_input_a_extended_int
+ \tex_advance:D \l_fp_trig_octant_int \c_one
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \fp_trig_octant_aux:
+ \fi:
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\fp_sin:Nn, \fp_sin:cn}
+% \UnitTested
+% \begin{macro}{\fp_gsin:Nn,\fp_gsin:cn}
+% \UnitTested
+% \begin{macro}[aux]{\fp_sin_aux:NNn}
+% \begin{macro}[aux]{\fp_sin_aux_i:}
+% \begin{macro}[aux]{\fp_sin_aux_ii:}
+% Calculating the sine starts off in the usual way. There is a check
+% to see if the value has already been worked out before proceeding
+% further.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_sin:Nn { \fp_sin_aux:NNn \tl_set:Nn }
+\cs_new_protected_nopar:Npn \fp_gsin:Nn { \fp_sin_aux:NNn \tl_gset:Nn }
+\cs_generate_variant:Nn \fp_sin:Nn { c }
+\cs_generate_variant:Nn \fp_gsin:Nn { c }
+% \end{macrocode}
+% The internal routine for sines does a check to see if the value is
+% already known. This saves a lot of repetition when doing rotations.
+% For very small values it is best to simply return the input as the
+% sine: the cut-off is $ 1 \times 10^{-5} $.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_sin_aux:NNn #1#2#3
+ {
+ \group_begin:
+ \fp_split:Nn a {#3}
+ \fp_standardise:NNNN
+ \l_fp_input_a_sign_int
+ \l_fp_input_a_integer_int
+ \l_fp_input_a_decimal_int
+ \l_fp_input_a_exponent_int
+ \tl_set:Nx \l_fp_arg_tl
+ {
+ \if_int_compare:w \l_fp_input_a_sign_int < \c_zero
+ -
+ \else:
+ +
+ \fi:
+ \int_use:N \l_fp_input_a_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \int_value:w \int_eval:w
+ \l_fp_input_a_decimal_int + \c_one_thousand_million
+ e
+ \int_use:N \l_fp_input_a_exponent_int
+ }
+ \if_int_compare:w \l_fp_input_a_exponent_int < -\c_five
+ \cs_set_protected_nopar:Npx \fp_tmp:w
+ {
+ \group_end:
+ #1 \exp_not:N #2 { \l_fp_arg_tl }
+ }
+ \else:
+ \if_cs_exist:w
+ c_fp_sin ( \l_fp_arg_tl ) _fp
+ \cs_end:
+ \else:
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \fp_sin_aux_i:
+ \fi:
+ \cs_set_protected_nopar:Npx \fp_tmp:w
+ {
+ \group_end:
+ #1 \exp_not:N #2
+ { \use:c { c_fp_sin ( \l_fp_arg_tl ) _fp } }
+ }
+ \fi:
+ \fp_tmp:w
+ }
+% \end{macrocode}
+% The internals for sine first normalise the input into an octant, then
+% choose the correct set up for the Taylor series. The sign for the sine
+% function is easy, so there is no worry about it. So the only thing to
+% do is to get the output standardised.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_sin_aux_i:
+ {
+ \fp_trig_normalise:
+ \fp_sin_aux_ii:
+ \if_int_compare:w \l_fp_output_integer_int = \c_one
+ \l_fp_output_exponent_int \c_zero
+ \else:
+ \l_fp_output_integer_int \l_fp_output_decimal_int
+ \l_fp_output_decimal_int \l_fp_output_extended_int
+ \l_fp_output_exponent_int -\c_nine
+ \fi:
+ \fp_standardise:NNNN
+ \l_fp_input_a_sign_int
+ \l_fp_output_integer_int
+ \l_fp_output_decimal_int
+ \l_fp_output_exponent_int
+ \tl_new:c { c_fp_sin ( \l_fp_arg_tl ) _fp }
+ \tl_gset:cx { c_fp_sin ( \l_fp_arg_tl ) _fp }
+ {
+ \if_int_compare:w \l_fp_input_a_sign_int > \c_zero
+ +
+ \else:
+ -
+ \fi:
+ \int_use:N \l_fp_output_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \int_value:w \int_eval:w
+ \l_fp_output_decimal_int + \c_one_thousand_million
+ e
+ \int_use:N \l_fp_output_exponent_int
+ }
+ }
+\cs_new_protected_nopar:Npn \fp_sin_aux_ii:
+ {
+ \if_case:w \l_fp_trig_octant_int
+ \or:
+ \exp_after:wN \fp_trig_calc_sin:
+ \or:
+ \exp_after:wN \fp_trig_calc_cos:
+ \or:
+ \exp_after:wN \fp_trig_calc_cos:
+ \or:
+ \exp_after:wN \fp_trig_calc_sin:
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\fp_cos:Nn, \fp_cos:cn}
+% \UnitTested
+% \begin{macro}{\fp_gcos:Nn,\fp_gcos:cn}
+% \UnitTested
+% \begin{macro}[aux]{\fp_cos_aux:NNn}
+% \begin{macro}[aux]{\fp_cos_aux_i:}
+% \begin{macro}[aux]{\fp_cos_aux_ii:}
+% Cosine is almost identical, but there is no short cut code here.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_cos:Nn { \fp_cos_aux:NNn \tl_set:Nn }
+\cs_new_protected_nopar:Npn \fp_gcos:Nn { \fp_cos_aux:NNn \tl_gset:Nn }
+\cs_generate_variant:Nn \fp_cos:Nn { c }
+\cs_generate_variant:Nn \fp_gcos:Nn { c }
+\cs_new_protected_nopar:Npn \fp_cos_aux:NNn #1#2#3
+ {
+ \group_begin:
+ \fp_split:Nn a {#3}
+ \fp_standardise:NNNN
+ \l_fp_input_a_sign_int
+ \l_fp_input_a_integer_int
+ \l_fp_input_a_decimal_int
+ \l_fp_input_a_exponent_int
+ \tl_set:Nx \l_fp_arg_tl
+ {
+ \if_int_compare:w \l_fp_input_a_sign_int < \c_zero
+ -
+ \else:
+ +
+ \fi:
+ \int_use:N \l_fp_input_a_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \int_value:w \int_eval:w
+ \l_fp_input_a_decimal_int + \c_one_thousand_million
+ e
+ \int_use:N \l_fp_input_a_exponent_int
+ }
+ \if_cs_exist:w c_fp_cos ( \l_fp_arg_tl ) _fp \cs_end:
+ \else:
+ \exp_after:wN \fp_cos_aux_i:
+ \fi:
+ \cs_set_protected_nopar:Npx \fp_tmp:w
+ {
+ \group_end:
+ #1 \exp_not:N #2
+ { \use:c { c_fp_cos ( \l_fp_arg_tl ) _fp } }
+ }
+ \fp_tmp:w
+ }
+% \end{macrocode}
+% Almost the same as for sine: just a bit of correction for the sign
+% of the output.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_cos_aux_i:
+ {
+ \fp_trig_normalise:
+ \fp_cos_aux_ii:
+ \if_int_compare:w \l_fp_output_integer_int = \c_one
+ \l_fp_output_exponent_int \c_zero
+ \else:
+ \l_fp_output_integer_int \l_fp_output_decimal_int
+ \l_fp_output_decimal_int \l_fp_output_extended_int
+ \l_fp_output_exponent_int -\c_nine
+ \fi:
+ \fp_standardise:NNNN
+ \l_fp_input_a_sign_int
+ \l_fp_output_integer_int
+ \l_fp_output_decimal_int
+ \l_fp_output_exponent_int
+ \tl_new:c { c_fp_cos ( \l_fp_arg_tl ) _fp }
+ \tl_gset:cx { c_fp_cos ( \l_fp_arg_tl ) _fp }
+ {
+ \if_int_compare:w \l_fp_input_a_sign_int > \c_zero
+ +
+ \else:
+ -
+ \fi:
+ \int_use:N \l_fp_output_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \int_value:w \int_eval:w
+ \l_fp_output_decimal_int + \c_one_thousand_million
+ e
+ \int_use:N \l_fp_output_exponent_int
+ }
+ }
+\cs_new_protected_nopar:Npn \fp_cos_aux_ii:
+ {
+ \if_case:w \l_fp_trig_octant_int
+ \or:
+ \exp_after:wN \fp_trig_calc_cos:
+ \or:
+ \exp_after:wN \fp_trig_calc_sin:
+ \or:
+ \exp_after:wN \fp_trig_calc_sin:
+ \or:
+ \exp_after:wN \fp_trig_calc_cos:
+ \fi:
+ \if_int_compare:w \l_fp_input_a_sign_int > \c_zero
+ \if_int_compare:w \l_fp_trig_octant_int > \c_two
+ \l_fp_input_a_sign_int \c_minus_one
+ \fi:
+ \else:
+ \if_int_compare:w \l_fp_trig_octant_int > \c_two
+ \else:
+ \l_fp_input_a_sign_int \c_one
+ \fi:
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\fp_trig_calc_cos:}
+% \begin{macro}{\fp_trig_calc_sin:}
+% \begin{macro}[aux]{\fp_trig_calc_Taylor:}
+% These functions actually do the calculation for sine and cosine.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_trig_calc_cos:
+ {
+ \if_int_compare:w \l_fp_input_a_decimal_int = \c_zero
+ \l_fp_output_integer_int \c_one
+ \l_fp_output_decimal_int \c_zero
+ \else:
+ \l_fp_trig_sign_int \c_minus_one
+ \fp_mul:NNNNNN
+ \l_fp_input_a_decimal_int \l_fp_input_a_extended_int
+ \l_fp_input_a_decimal_int \l_fp_input_a_extended_int
+ \l_fp_trig_decimal_int \l_fp_trig_extended_int
+ \fp_div_integer:NNNNN
+ \l_fp_trig_decimal_int \l_fp_trig_extended_int
+ \c_two
+ \l_fp_trig_decimal_int \l_fp_trig_extended_int
+ \l_fp_count_int \c_three
+ \if_int_compare:w \l_fp_trig_extended_int = \c_zero
+ \if_int_compare:w \l_fp_trig_decimal_int = \c_zero
+ \l_fp_output_integer_int \c_one
+ \l_fp_output_decimal_int \c_zero
+ \l_fp_output_extended_int \c_zero
+ \else:
+ \l_fp_output_integer_int \c_zero
+ \l_fp_output_decimal_int \c_one_thousand_million
+ \l_fp_output_extended_int \c_zero
+ \fi:
+ \else:
+ \l_fp_output_integer_int \c_zero
+ \l_fp_output_decimal_int 999999999 \scan_stop:
+ \l_fp_output_extended_int \c_one_thousand_million
+ \fi:
+ \tex_advance:D \l_fp_output_extended_int -\l_fp_trig_extended_int
+ \tex_advance:D \l_fp_output_decimal_int -\l_fp_trig_decimal_int
+ \exp_after:wN \fp_trig_calc_Taylor:
+ \fi:
+ }
+\cs_new_protected_nopar:Npn \fp_trig_calc_sin:
+ {
+ \l_fp_output_integer_int \c_zero
+ \if_int_compare:w \l_fp_input_a_decimal_int = \c_zero
+ \l_fp_output_decimal_int \c_zero
+ \else:
+ \l_fp_output_decimal_int \l_fp_input_a_decimal_int
+ \l_fp_output_extended_int \l_fp_input_a_extended_int
+ \l_fp_trig_sign_int \c_one
+ \l_fp_trig_decimal_int \l_fp_input_a_decimal_int
+ \l_fp_trig_extended_int \l_fp_input_a_extended_int
+ \l_fp_count_int \c_two
+ \exp_after:wN \fp_trig_calc_Taylor:
+ \fi:
+ }
+% \end{macrocode}
+% This implements a Taylor series calculation for the trigonometric
+% functions. Lots of shuffling about as \TeX\ is not exactly a natural
+% choice for this sort of thing.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_trig_calc_Taylor:
+ {
+ \l_fp_trig_sign_int -\l_fp_trig_sign_int
+ \fp_mul:NNNNNN
+ \l_fp_trig_decimal_int \l_fp_trig_extended_int
+ \l_fp_input_a_decimal_int \l_fp_input_a_extended_int
+ \l_fp_trig_decimal_int \l_fp_trig_extended_int
+ \fp_mul:NNNNNN
+ \l_fp_trig_decimal_int \l_fp_trig_extended_int
+ \l_fp_input_a_decimal_int \l_fp_input_a_extended_int
+ \l_fp_trig_decimal_int \l_fp_trig_extended_int
+ \fp_div_integer:NNNNN
+ \l_fp_trig_decimal_int \l_fp_trig_extended_int
+ \l_fp_count_int
+ \l_fp_trig_decimal_int \l_fp_trig_extended_int
+ \tex_advance:D \l_fp_count_int \c_one
+ \fp_div_integer:NNNNN
+ \l_fp_trig_decimal_int \l_fp_trig_extended_int
+ \l_fp_count_int
+ \l_fp_trig_decimal_int \l_fp_trig_extended_int
+ \tex_advance:D \l_fp_count_int \c_one
+ \if_int_compare:w \l_fp_trig_decimal_int > \c_zero
+ \if_int_compare:w \l_fp_trig_sign_int > \c_zero
+ \tex_advance:D \l_fp_output_decimal_int \l_fp_trig_decimal_int
+ \tex_advance:D \l_fp_output_extended_int
+ \l_fp_trig_extended_int
+ \if_int_compare:w \l_fp_output_extended_int < \c_one_thousand_million
+ \else:
+ \tex_advance:D \l_fp_output_decimal_int \c_one
+ \tex_advance:D \l_fp_output_extended_int
+ -\c_one_thousand_million
+ \fi:
+ \if_int_compare:w \l_fp_output_decimal_int < \c_one_thousand_million
+ \else:
+ \tex_advance:D \l_fp_output_integer_int \c_one
+ \tex_advance:D \l_fp_output_decimal_int
+ -\c_one_thousand_million
+ \fi:
+ \else:
+ \tex_advance:D \l_fp_output_decimal_int -\l_fp_trig_decimal_int
+ \tex_advance:D \l_fp_output_extended_int
+ -\l_fp_input_a_extended_int
+ \if_int_compare:w \l_fp_output_extended_int < \c_zero
+ \tex_advance:D \l_fp_output_decimal_int \c_minus_one
+ \tex_advance:D \l_fp_output_extended_int \c_one_thousand_million
+ \fi:
+ \if_int_compare:w \l_fp_output_decimal_int < \c_zero
+ \tex_advance:D \l_fp_output_integer_int \c_minus_one
+ \tex_advance:D \l_fp_output_decimal_int \c_one_thousand_million
+ \fi:
+ \fi:
+ \exp_after:wN \fp_trig_calc_Taylor:
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\fp_tan:Nn, \fp_tan:cn}
+% \UnitTested
+% \begin{macro}{\fp_gtan:Nn,\fp_gtan:cn}
+% \UnitTested
+% \begin{macro}[aux]{\fp_tan_aux:NNn}
+% \begin{macro}[aux]{\fp_tan_aux_i:}
+% \begin{macro}[aux]{\fp_tan_aux_ii:}
+% \begin{macro}[aux]{\fp_tan_aux_iii:}
+% \begin{macro}[aux]{\fp_tan_aux_iv:}
+% As might be expected, tangents are calculated from the sine and cosine
+% by division. So there is a bit of set up, the two subsidiary pieces
+% of work are done and then a division takes place. For small numbers,
+% the same approach is used as for sines, with the input value simply
+% returned as is.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_tan:Nn { \fp_tan_aux:NNn \tl_set:Nn }
+\cs_new_protected_nopar:Npn \fp_gtan:Nn { \fp_tan_aux:NNn \tl_gset:Nn }
+\cs_generate_variant:Nn \fp_tan:Nn { c }
+\cs_generate_variant:Nn \fp_gtan:Nn { c }
+\cs_new_protected_nopar:Npn \fp_tan_aux:NNn #1#2#3
+ {
+ \group_begin:
+ \fp_split:Nn a {#3}
+ \fp_standardise:NNNN
+ \l_fp_input_a_sign_int
+ \l_fp_input_a_integer_int
+ \l_fp_input_a_decimal_int
+ \l_fp_input_a_exponent_int
+ \tl_set:Nx \l_fp_arg_tl
+ {
+ \if_int_compare:w \l_fp_input_a_sign_int < \c_zero
+ -
+ \else:
+ +
+ \fi:
+ \int_use:N \l_fp_input_a_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \int_value:w \int_eval:w
+ \l_fp_input_a_decimal_int + \c_one_thousand_million
+ e
+ \int_use:N \l_fp_input_a_exponent_int
+ }
+ \if_int_compare:w \l_fp_input_a_exponent_int < -\c_five
+ \cs_set_protected_nopar:Npx \fp_tmp:w
+ {
+ \group_end:
+ #1 \exp_not:N #2 { \l_fp_arg_tl }
+ }
+ \else:
+ \if_cs_exist:w
+ c_fp_tan ( \l_fp_arg_tl ) _fp
+ \cs_end:
+ \else:
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \fp_tan_aux_i:
+ \fi:
+ \cs_set_protected_nopar:Npx \fp_tmp:w
+ {
+ \group_end:
+ #1 \exp_not:N #2
+ { \use:c { c_fp_tan ( \l_fp_arg_tl ) _fp } }
+ }
+ \fi:
+ \fp_tmp:w
+ }
+% \end{macrocode}
+% The business of the calculation does not check for stored sines or
+% cosines as there would then be an overhead to reading them back in.
+% There is also no need to worry about \enquote{small} sine values as
+% these will have been dealt with earlier. There is a two-step lead off
+% so that undefined division is not even attempted.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_tan_aux_i:
+ {
+ \if_int_compare:w \l_fp_input_a_exponent_int < \c_ten
+ \exp_after:wN \fp_tan_aux_ii:
+ \else:
+ \cs_new_eq:cN { c_fp_tan ( \l_fp_arg_tl ) _fp }
+ \c_zero_fp
+ \exp_after:wN \fp_trig_overflow_msg:
+ \fi:
+ }
+\cs_new_protected_nopar:Npn \fp_tan_aux_ii:
+ {
+ \fp_trig_normalise:
+ \if_int_compare:w \l_fp_input_a_sign_int > \c_zero
+ \if_int_compare:w \l_fp_trig_octant_int > \c_two
+ \l_fp_output_sign_int \c_minus_one
+ \else:
+ \l_fp_output_sign_int \c_one
+ \fi:
+ \else:
+ \if_int_compare:w \l_fp_trig_octant_int > \c_two
+ \l_fp_output_sign_int \c_one
+ \else:
+ \l_fp_output_sign_int \c_minus_one
+ \fi:
+ \fi:
+ \fp_cos_aux_ii:
+ \if_int_compare:w \l_fp_input_a_decimal_int = \c_zero
+ \if_int_compare:w \l_fp_input_a_integer_int = \c_zero
+ \cs_new_eq:cN { c_fp_tan ( \l_fp_arg_tl ) _fp }
+ \c_undefined_fp
+ \else:
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \fp_tan_aux_iii:
+ \fi:
+ \else:
+ \exp_after:wN \fp_tan_aux_iii:
+ \fi:
+ }
+% \end{macrocode}
+% The division is done here using the same code as the standard division
+% unit, shifting the digits in the calculated sine and cosine to
+% maintain accuracy.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_tan_aux_iii:
+ {
+ \l_fp_input_b_integer_int \l_fp_output_decimal_int
+ \l_fp_input_b_decimal_int \l_fp_output_extended_int
+ \l_fp_input_b_exponent_int -\c_nine
+ \fp_standardise:NNNN
+ \l_fp_input_b_sign_int
+ \l_fp_input_b_integer_int
+ \l_fp_input_b_decimal_int
+ \l_fp_input_b_exponent_int
+ \fp_sin_aux_ii:
+ \l_fp_input_a_integer_int \l_fp_output_decimal_int
+ \l_fp_input_a_decimal_int \l_fp_output_extended_int
+ \l_fp_input_a_exponent_int -\c_nine
+ \fp_standardise:NNNN
+ \l_fp_input_a_sign_int
+ \l_fp_input_a_integer_int
+ \l_fp_input_a_decimal_int
+ \l_fp_input_a_exponent_int
+ \if_int_compare:w \l_fp_input_a_decimal_int = \c_zero
+ \if_int_compare:w \l_fp_input_a_integer_int = \c_zero
+ \cs_new_eq:cN { c_fp_tan ( \l_fp_arg_tl ) _fp }
+ \c_zero_fp
+ \else:
+ \exp_after:wN \exp_after:wN \exp_after:wN \fp_tan_aux_iv:
+ \fi:
+ \else:
+ \exp_after:wN \fp_tan_aux_iv:
+ \fi:
+ }
+\cs_new_protected_nopar:Npn \fp_tan_aux_iv:
+ {
+ \l_fp_output_integer_int \c_zero
+ \l_fp_output_decimal_int \c_zero
+ \cs_set_eq:NN \fp_div_store: \fp_div_store_integer:
+ \l_fp_div_offset_int \c_one_hundred_million
+ \fp_div_loop:
+ \l_fp_output_exponent_int
+ \int_eval:w
+ \l_fp_input_a_exponent_int - \l_fp_input_b_exponent_int
+ \int_eval_end:
+ \fp_standardise:NNNN
+ \l_fp_output_sign_int
+ \l_fp_output_integer_int
+ \l_fp_output_decimal_int
+ \l_fp_output_exponent_int
+ \tl_new:c { c_fp_tan ( \l_fp_arg_tl ) _fp }
+ \tl_gset:cx { c_fp_tan ( \l_fp_arg_tl ) _fp }
+ {
+ \if_int_compare:w \l_fp_output_sign_int > \c_zero
+ +
+ \else:
+ -
+ \fi:
+ \int_use:N \l_fp_output_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \int_value:w \int_eval:w
+ \l_fp_output_decimal_int + \c_one_thousand_million
+ e
+ \int_use:N \l_fp_output_exponent_int
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Exponent and logarithm functions}
+%
+% \begin{variable}{\c_fp_exp_1_tl}
+% \begin{variable}{\c_fp_exp_2_tl}
+% \begin{variable}{\c_fp_exp_3_tl}
+% \begin{variable}{\c_fp_exp_4_tl}
+% \begin{variable}{\c_fp_exp_5_tl}
+% \begin{variable}{\c_fp_exp_6_tl}
+% \begin{variable}{\c_fp_exp_7_tl}
+% \begin{variable}{\c_fp_exp_8_tl}
+% \begin{variable}{\c_fp_exp_9_tl}
+% \begin{variable}{\c_fp_exp_10_tl}
+% \begin{variable}{\c_fp_exp_20_tl}
+% \begin{variable}{\c_fp_exp_30_tl}
+% \begin{variable}{\c_fp_exp_40_tl}
+% \begin{variable}{\c_fp_exp_50_tl}
+% \begin{variable}{\c_fp_exp_60_tl}
+% \begin{variable}{\c_fp_exp_70_tl}
+% \begin{variable}{\c_fp_exp_80_tl}
+% \begin{variable}{\c_fp_exp_90_tl}
+% \begin{variable}{\c_fp_exp_100_tl}
+% \begin{variable}{\c_fp_exp_200_tl}
+% Calculation of exponentials requires a number of precomputed values:
+% first the positive integers.
+% \begin{macrocode}
+\tl_const:cn { c_fp_exp_1_tl } { { 2 } { 718281828 } { 459045235 } { 0 } }
+\tl_const:cn { c_fp_exp_2_tl } { { 7 } { 389056098 } { 930650227 } { 0 } }
+\tl_const:cn { c_fp_exp_3_tl } { { 2 } { 008553692 } { 318766774 } { 1 } }
+\tl_const:cn { c_fp_exp_4_tl } { { 5 } { 459815003 } { 314423908 } { 1 } }
+\tl_const:cn { c_fp_exp_5_tl } { { 1 } { 484131591 } { 025766034 } { 2 } }
+\tl_const:cn { c_fp_exp_6_tl } { { 4 } { 034287934 } { 927351226 } { 2 } }
+\tl_const:cn { c_fp_exp_7_tl } { { 1 } { 096633158 } { 428458599 } { 3 } }
+\tl_const:cn { c_fp_exp_8_tl } { { 2 } { 980957987 } { 041728275 } { 3 } }
+\tl_const:cn { c_fp_exp_9_tl } { { 8 } { 103083927 } { 575384008 } { 3 } }
+\tl_const:cn { c_fp_exp_10_tl } { { 2 } { 202646579 } { 480671652 } { 4 } }
+\tl_const:cn { c_fp_exp_20_tl } { { 4 } { 851651954 } { 097902280 } { 8 } }
+\tl_const:cn { c_fp_exp_30_tl } { { 1 } { 068647458 } { 152446215 } { 13 } }
+\tl_const:cn { c_fp_exp_40_tl } { { 2 } { 353852668 } { 370199854 } { 17 } }
+\tl_const:cn { c_fp_exp_50_tl } { { 5 } { 184705528 } { 587072464 } { 21 } }
+\tl_const:cn { c_fp_exp_60_tl } { { 1 } { 142007389 } { 815684284 } { 26 } }
+\tl_const:cn { c_fp_exp_70_tl } { { 2 } { 515438670 } { 919167006 } { 30 } }
+\tl_const:cn { c_fp_exp_80_tl } { { 5 } { 540622384 } { 393510053 } { 34 } }
+\tl_const:cn { c_fp_exp_90_tl } { { 1 } { 220403294 } { 317840802 } { 39 } }
+\tl_const:cn { c_fp_exp_100_tl } { { 2 } { 688117141 } { 816135448 } { 43 } }
+\tl_const:cn { c_fp_exp_200_tl } { { 7 } { 225973768 } { 125749258 } { 86 } }
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+%
+% \begin{variable}{\c_fp_exp_-1_tl}
+% \begin{variable}{\c_fp_exp_-2_tl}
+% \begin{variable}{\c_fp_exp_-3_tl}
+% \begin{variable}{\c_fp_exp_-4_tl}
+% \begin{variable}{\c_fp_exp_-5_tl}
+% \begin{variable}{\c_fp_exp_-6_tl}
+% \begin{variable}{\c_fp_exp_-7_tl}
+% \begin{variable}{\c_fp_exp_-8_tl}
+% \begin{variable}{\c_fp_exp_-9_tl}
+% \begin{variable}{\c_fp_exp_-10_tl}
+% \begin{variable}{\c_fp_exp_-20_tl}
+% \begin{variable}{\c_fp_exp_-30_tl}
+% \begin{variable}{\c_fp_exp_-40_tl}
+% \begin{variable}{\c_fp_exp_-50_tl}
+% \begin{variable}{\c_fp_exp_-60_tl}
+% \begin{variable}{\c_fp_exp_-70_tl}
+% \begin{variable}{\c_fp_exp_-80_tl}
+% \begin{variable}{\c_fp_exp_-90_tl}
+% \begin{variable}{\c_fp_exp_-100_tl}
+% \begin{variable}{\c_fp_exp_-200_tl}
+% Now the negative integers.
+% \begin{macrocode}
+\tl_const:cn { c_fp_exp_-1_tl } { { 3 } { 678794411 } { 71442322 } { -1 } }
+\tl_const:cn { c_fp_exp_-2_tl } { { 1 } { 353352832 } { 366132692 } { -1 } }
+\tl_const:cn { c_fp_exp_-3_tl } { { 4 } { 978706836 } { 786394298 } { -2 } }
+\tl_const:cn { c_fp_exp_-4_tl } { { 1 } { 831563888 } { 873418029 } { -2 } }
+\tl_const:cn { c_fp_exp_-5_tl } { { 6 } { 737946999 } { 085467097 } { -3 } }
+\tl_const:cn { c_fp_exp_-6_tl } { { 2 } { 478752176 } { 666358423 } { -3 } }
+\tl_const:cn { c_fp_exp_-7_tl } { { 9 } { 118819655 } { 545162080 } { -4 } }
+\tl_const:cn { c_fp_exp_-8_tl } { { 3 } { 354626279 } { 025118388 } { -4 } }
+\tl_const:cn { c_fp_exp_-9_tl } { { 1 } { 234098040 } { 866795495 } { -4 } }
+\tl_const:cn { c_fp_exp_-10_tl } { { 4 } { 539992976 } { 248451536 } { -5 } }
+\tl_const:cn { c_fp_exp_-20_tl } { { 2 } { 061153622 } { 438557828 } { -9 } }
+\tl_const:cn { c_fp_exp_-30_tl } { { 9 } { 357622968 } { 840174605 } { -14 } }
+\tl_const:cn { c_fp_exp_-40_tl } { { 4 } { 248354255 } { 291588995 } { -18 } }
+\tl_const:cn { c_fp_exp_-50_tl } { { 1 } { 928749847 } { 963917783 } { -22 } }
+\tl_const:cn { c_fp_exp_-60_tl } { { 8 } { 756510762 } { 696520338 } { -27 } }
+\tl_const:cn { c_fp_exp_-70_tl } { { 3 } { 975449735 } { 908646808 } { -31 } }
+\tl_const:cn { c_fp_exp_-80_tl } { { 1 } { 804851387 } { 845415172 } { -35 } }
+\tl_const:cn { c_fp_exp_-90_tl } { { 8 } { 194012623 } { 990515430 } { -40 } }
+\tl_const:cn { c_fp_exp_-100_tl } { { 3 } { 720075976 } { 020835963 } { -44 } }
+\tl_const:cn { c_fp_exp_-200_tl } { { 1 } { 383896526 } { 736737530 } { -87 } }
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+%
+% \begin{macro}{\fp_exp:Nn, \fp_exp:cn}
+% \UnitTested
+% \begin{macro}{\fp_gexp:Nn,\fp_gexp:cn}
+% \UnitTested
+% \begin{macro}[aux]{\fp_exp_aux:NNn}
+% \begin{macro}[aux]{\fp_exp_internal:}
+% \begin{macro}[aux]{\fp_exp_aux:}
+% \begin{macro}[aux]{\fp_exp_integer:}
+% \begin{macro}[aux]{\fp_exp_integer_tens:}
+% \begin{macro}[aux]{\fp_exp_integer_units:}
+% \begin{macro}[aux]{\fp_exp_integer_const:n}
+% \begin{macro}[aux]{\fp_exp_integer_const:nnnn}
+% \begin{macro}[aux]{\fp_exp_decimal:}
+% \begin{macro}[aux]{\fp_exp_Taylor:}
+% \begin{macro}[aux]{\fp_exp_const:Nx}
+% \begin{macro}[aux]{\fp_exp_const:cx}
+% The calculation of an exponent starts off starts in much the same
+% way as the trigonometric functions: normalise the input, look for
+% a pre-defined value and if one is not found hand off to the real
+% workhorse function. The test for a definition of the result is used
+% so that overflows do not result in any outcome being defined.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_exp:Nn { \fp_exp_aux:NNn \tl_set:Nn }
+\cs_new_protected_nopar:Npn \fp_gexp:Nn { \fp_exp_aux:NNn \tl_gset:Nn }
+\cs_generate_variant:Nn \fp_exp:Nn { c }
+\cs_generate_variant:Nn \fp_gexp:Nn { c }
+\cs_new_protected_nopar:Npn \fp_exp_aux:NNn #1#2#3
+ {
+ \group_begin:
+ \fp_split:Nn a {#3}
+ \fp_standardise:NNNN
+ \l_fp_input_a_sign_int
+ \l_fp_input_a_integer_int
+ \l_fp_input_a_decimal_int
+ \l_fp_input_a_exponent_int
+ \l_fp_input_a_extended_int \c_zero
+ \tl_set:Nx \l_fp_arg_tl
+ {
+ \if_int_compare:w \l_fp_input_a_sign_int < \c_zero
+ -
+ \else:
+ +
+ \fi:
+ \int_use:N \l_fp_input_a_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \int_value:w \int_eval:w
+ \l_fp_input_a_decimal_int + \c_one_thousand_million
+ e
+ \int_use:N \l_fp_input_a_exponent_int
+ }
+ \if_cs_exist:w c_fp_exp ( \l_fp_arg_tl ) _fp \cs_end:
+ \else:
+ \exp_after:wN \fp_exp_internal:
+ \fi:
+ \cs_set_protected_nopar:Npx \fp_tmp:w
+ {
+ \group_end:
+ #1 \exp_not:N #2
+ {
+ \if_cs_exist:w c_fp_exp ( \l_fp_arg_tl ) _fp
+ \cs_end:
+ \use:c { c_fp_exp ( \l_fp_arg_tl ) _fp }
+ \else:
+ \c_zero_fp
+ \fi:
+ }
+ }
+ \fp_tmp:w
+ }
+% \end{macrocode}
+% The first real step is to convert the input into a fixed-point
+% representation for further calculation: anything which is dropped
+% here as too small would not influence the output in any case. There
+% are a couple of overflow tests: the maximum
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_exp_internal:
+ {
+ \if_int_compare:w \l_fp_input_a_exponent_int < \c_three
+ \fp_extended_normalise:
+ \if_int_compare:w \l_fp_input_a_sign_int > \c_zero
+ \if_int_compare:w \l_fp_input_a_integer_int < 230 \scan_stop:
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \exp_after:wN \fp_exp_aux:
+ \else:
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \exp_after:wN \fp_exp_overflow_msg:
+ \fi:
+ \else:
+ \if_int_compare:w \l_fp_input_a_integer_int < 230 \scan_stop:
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \exp_after:wN \fp_exp_aux:
+ \else:
+ \fp_exp_const:cx { c_fp_exp ( \l_fp_arg_tl ) _fp }
+ { \c_zero_fp }
+ \fi:
+ \fi:
+ \else:
+ \exp_after:wN \fp_exp_overflow_msg:
+ \fi:
+ }
+% \end{macrocode}
+% The main algorithm makes use of the fact that
+% \[
+% \mathrm{e}^{nmp.q} =
+% \mathrm{e}^{n}
+% \mathrm{e}^{m}
+% \mathrm{e}^{p}
+% \mathrm{e}^{0.q}
+% \]
+% and that there is a Taylor series that can be used to calculate
+% $ \mathrm{e}^{0.q} $. Thus the approach needed is in three parts.
+% First, the exponent of the integer part of the input is found
+% using the pre-calculated constants. Second, the Taylor series is
+% used to find the exponent for the decimal part of the input. Finally,
+% the two parts are multiplied together to give the result. As the
+% normalisation code will already have dealt with any overflowing
+% values, there are no further checks needed.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_exp_aux:
+ {
+ \if_int_compare:w \l_fp_input_a_integer_int > \c_zero
+ \exp_after:wN \fp_exp_integer:
+ \else:
+ \l_fp_output_integer_int \c_one
+ \l_fp_output_decimal_int \c_zero
+ \l_fp_output_extended_int \c_zero
+ \l_fp_output_exponent_int \c_zero
+ \exp_after:wN \fp_exp_decimal:
+ \fi:
+ }
+% \end{macrocode}
+% The integer part calculation starts with the hundreds. This is
+% set up such that very large negative numbers can short-cut the entire
+% procedure and simply return zero. In other cases, the code either
+% recovers the exponent of the hundreds value or sets the appropriate
+% storage to one (so that multiplication works correctly).
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_exp_integer:
+ {
+ \if_int_compare:w \l_fp_input_a_integer_int < \c_one_hundred
+ \l_fp_exp_integer_int \c_one
+ \l_fp_exp_decimal_int \c_zero
+ \l_fp_exp_extended_int \c_zero
+ \l_fp_exp_exponent_int \c_zero
+ \exp_after:wN \fp_exp_integer_tens:
+ \else:
+ \tl_set:Nx \l_fp_tmp_tl
+ {
+ \exp_after:wN \use_i:nnn
+ \int_use:N \l_fp_input_a_integer_int
+ }
+ \l_fp_input_a_integer_int
+ \int_eval:w
+ \l_fp_input_a_integer_int - \l_fp_tmp_tl 00
+ \int_eval_end:
+ \if_int_compare:w \l_fp_input_a_sign_int < \c_zero
+ \if_int_compare:w \l_fp_output_integer_int > 200 \scan_stop:
+ \fp_exp_const:cx { c_fp_exp ( \l_fp_arg_tl ) _fp }
+ { \c_zero_fp }
+ \else:
+ \fp_exp_integer_const:n { - \l_fp_tmp_tl 00 }
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \exp_after:wN \fp_exp_integer_tens:
+ \fi:
+ \else:
+ \fp_exp_integer_const:n { \l_fp_tmp_tl 00 }
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \exp_after:wN \fp_exp_integer_tens:
+ \fi:
+ \fi:
+ }
+% \end{macrocode}
+% The tens and units parts are handled in a similar way, with a
+% multiplication step to build up the final value. That also includes a
+% correction step to avoid an overflow of the integer part.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_exp_integer_tens:
+ {
+ \l_fp_output_integer_int \l_fp_exp_integer_int
+ \l_fp_output_decimal_int \l_fp_exp_decimal_int
+ \l_fp_output_extended_int \l_fp_exp_extended_int
+ \l_fp_output_exponent_int \l_fp_exp_exponent_int
+ \if_int_compare:w \l_fp_input_a_integer_int > \c_nine
+ \tl_set:Nx \l_fp_tmp_tl
+ {
+ \exp_after:wN \use_i:nn
+ \int_use:N \l_fp_input_a_integer_int
+ }
+ \l_fp_input_a_integer_int
+ \int_eval:w
+ \l_fp_input_a_integer_int - \l_fp_tmp_tl 0
+ \int_eval_end:
+ \if_int_compare:w \l_fp_input_a_sign_int > \c_zero
+ \fp_exp_integer_const:n { \l_fp_tmp_tl 0 }
+ \else:
+ \fp_exp_integer_const:n { - \l_fp_tmp_tl 0 }
+ \fi:
+ \fp_mul:NNNNNNNNN
+ \l_fp_exp_integer_int \l_fp_exp_decimal_int \l_fp_exp_extended_int
+ \l_fp_output_integer_int \l_fp_output_decimal_int
+ \l_fp_output_extended_int
+ \l_fp_output_integer_int \l_fp_output_decimal_int
+ \l_fp_output_extended_int
+ \tex_advance:D \l_fp_output_exponent_int \l_fp_exp_exponent_int
+ \fp_extended_normalise_output:
+ \fi:
+ \fp_exp_integer_units:
+ }
+\cs_new_protected_nopar:Npn \fp_exp_integer_units:
+ {
+ \if_int_compare:w \l_fp_input_a_integer_int > \c_zero
+ \if_int_compare:w \l_fp_input_a_sign_int > \c_zero
+ \fp_exp_integer_const:n { \int_use:N \l_fp_input_a_integer_int }
+ \else:
+ \fp_exp_integer_const:n
+ { - \int_use:N \l_fp_input_a_integer_int }
+ \fi:
+ \fp_mul:NNNNNNNNN
+ \l_fp_exp_integer_int \l_fp_exp_decimal_int \l_fp_exp_extended_int
+ \l_fp_output_integer_int \l_fp_output_decimal_int
+ \l_fp_output_extended_int
+ \l_fp_output_integer_int \l_fp_output_decimal_int
+ \l_fp_output_extended_int
+ \tex_advance:D \l_fp_output_exponent_int \l_fp_exp_exponent_int
+ \fp_extended_normalise_output:
+ \fi:
+ \fp_exp_decimal:
+ }
+% \end{macrocode}
+% Recovery of the stored constant values into the separate registers
+% is done with a simple expansion then assignment.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_exp_integer_const:n #1
+ {
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \fp_exp_integer_const:nnnn
+ \cs:w c_fp_exp_ #1 _tl \cs_end:
+ }
+\cs_new_protected_nopar:Npn \fp_exp_integer_const:nnnn #1#2#3#4
+ {
+ \l_fp_exp_integer_int #1 \scan_stop:
+ \l_fp_exp_decimal_int #2 \scan_stop:
+ \l_fp_exp_extended_int #3 \scan_stop:
+ \l_fp_exp_exponent_int #4 \scan_stop:
+ }
+% \end{macrocode}
+% Finding the exponential for the decimal part of the number requires
+% a Taylor series calculation. The set up is done here with the loop
+% itself a separate function. Once the decimal part is available this
+% is multiplied by the integer part already worked out to give
+% the final result.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_exp_decimal:
+ {
+ \if_int_compare:w \l_fp_input_a_decimal_int > \c_zero
+ \if_int_compare:w \l_fp_input_a_sign_int > \c_zero
+ \l_fp_exp_integer_int \c_one
+ \l_fp_exp_decimal_int \l_fp_input_a_decimal_int
+ \l_fp_exp_extended_int \l_fp_input_a_extended_int
+ \else:
+ \l_fp_exp_integer_int \c_zero
+ \if_int_compare:w \l_fp_exp_extended_int = \c_zero
+ \l_fp_exp_decimal_int
+ \int_eval:w
+ \c_one_thousand_million - \l_fp_input_a_decimal_int
+ \int_eval_end:
+ \l_fp_exp_extended_int \c_zero
+ \else:
+ \l_fp_exp_decimal_int
+ \int_eval:w
+ 999999999 - \l_fp_input_a_decimal_int
+ \scan_stop:
+ \l_fp_exp_extended_int
+ \int_eval:w
+ \c_one_thousand_million - \l_fp_input_a_extended_int
+ \int_eval_end:
+ \fi:
+ \fi:
+ \l_fp_input_b_sign_int \l_fp_input_a_sign_int
+ \l_fp_input_b_decimal_int \l_fp_input_a_decimal_int
+ \l_fp_input_b_extended_int \l_fp_input_a_extended_int
+ \l_fp_count_int \c_one
+ \fp_exp_Taylor:
+ \fp_mul:NNNNNNNNN
+ \l_fp_exp_integer_int \l_fp_exp_decimal_int \l_fp_exp_extended_int
+ \l_fp_output_integer_int \l_fp_output_decimal_int
+ \l_fp_output_extended_int
+ \l_fp_output_integer_int \l_fp_output_decimal_int
+ \l_fp_output_extended_int
+ \fi:
+ \if_int_compare:w \l_fp_output_extended_int < \c_five_hundred_million
+ \else:
+ \tex_advance:D \l_fp_output_decimal_int \c_one
+ \if_int_compare:w \l_fp_output_decimal_int < \c_one_thousand_million
+ \else:
+ \l_fp_output_decimal_int \c_zero
+ \tex_advance:D \l_fp_output_integer_int \c_one
+ \fi:
+ \fi:
+ \fp_standardise:NNNN
+ \l_fp_output_sign_int
+ \l_fp_output_integer_int
+ \l_fp_output_decimal_int
+ \l_fp_output_exponent_int
+ \fp_exp_const:cx { c_fp_exp ( \l_fp_arg_tl ) _fp }
+ {
+ +
+ \int_use:N \l_fp_output_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \int_value:w \int_eval:w
+ \l_fp_output_decimal_int + \c_one_thousand_million
+ e
+ \int_use:N \l_fp_output_exponent_int
+ }
+ }
+% \end{macrocode}
+% The Taylor series for $ \exp(x) $ is
+% \[
+% 1 + x + \frac{x^2}{2!} + \frac{x^3}{3!} + \frac{x^4}{4!} + \cdots
+% \]
+% which converges for $ -1 < x < 1 $. The code above sets up
+% the $ x $ part, leaving the loop to multiply the running
+% value by $ x / n $ and add it onto the sum. The way that this is
+% done is that the running total is stored in the \texttt{exp} set of
+% registers, while the current item is stored as \texttt{input_b}.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_exp_Taylor:
+ {
+ \tex_advance:D \l_fp_count_int \c_one
+ \tex_multiply:D \l_fp_input_b_sign_int \l_fp_input_a_sign_int
+ \fp_mul:NNNNNN
+ \l_fp_input_a_decimal_int \l_fp_input_a_extended_int
+ \l_fp_input_b_decimal_int \l_fp_input_b_extended_int
+ \l_fp_input_b_decimal_int \l_fp_input_b_extended_int
+ \fp_div_integer:NNNNN
+ \l_fp_input_b_decimal_int \l_fp_input_b_extended_int
+ \l_fp_count_int
+ \l_fp_input_b_decimal_int \l_fp_input_b_extended_int
+ \if_int_compare:w
+ \int_eval:w
+ \l_fp_input_b_decimal_int + \l_fp_input_b_extended_int
+ > \c_zero
+ \if_int_compare:w \l_fp_input_b_sign_int > \c_zero
+ \tex_advance:D \l_fp_exp_decimal_int \l_fp_input_b_decimal_int
+ \tex_advance:D \l_fp_exp_extended_int
+ \l_fp_input_b_extended_int
+ \if_int_compare:w \l_fp_exp_extended_int < \c_one_thousand_million
+ \else:
+ \tex_advance:D \l_fp_exp_decimal_int \c_one
+ \tex_advance:D \l_fp_exp_extended_int
+ -\c_one_thousand_million
+ \fi:
+ \if_int_compare:w \l_fp_exp_decimal_int < \c_one_thousand_million
+ \else:
+ \tex_advance:D \l_fp_exp_integer_int \c_one
+ \tex_advance:D \l_fp_exp_decimal_int
+ -\c_one_thousand_million
+ \fi:
+ \else:
+ \tex_advance:D \l_fp_exp_decimal_int -\l_fp_input_b_decimal_int
+ \tex_advance:D \l_fp_exp_extended_int
+ -\l_fp_input_a_extended_int
+ \if_int_compare:w \l_fp_exp_extended_int < \c_zero
+ \tex_advance:D \l_fp_exp_decimal_int \c_minus_one
+ \tex_advance:D \l_fp_exp_extended_int \c_one_thousand_million
+ \fi:
+ \if_int_compare:w \l_fp_exp_decimal_int < \c_zero
+ \tex_advance:D \l_fp_exp_integer_int \c_minus_one
+ \tex_advance:D \l_fp_exp_decimal_int \c_one_thousand_million
+ \fi:
+ \fi:
+ \exp_after:wN \fp_exp_Taylor:
+ \fi:
+ }
+% \end{macrocode}
+% This is set up as a function so that the power code can redirect
+% the effect.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_exp_const:Nx #1#2
+ {
+ \tl_new:N #1
+ \tl_gset:Nx #1 {#2}
+ }
+\cs_generate_variant:Nn \fp_exp_const:Nx { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{variable}{\c_fp_ln_10_1_tl}
+% \begin{variable}{\c_fp_ln_10_2_tl}
+% \begin{variable}{\c_fp_ln_10_3_tl}
+% \begin{variable}{\c_fp_ln_10_4_tl}
+% \begin{variable}{\c_fp_ln_10_5_tl}
+% \begin{variable}{\c_fp_ln_10_6_tl}
+% \begin{variable}{\c_fp_ln_10_7_tl}
+% \begin{variable}{\c_fp_ln_10_8_tl}
+% \begin{variable}{\c_fp_ln_10_9_tl}
+% Constants for working out logarithms: first those for the powers of
+% ten.
+% \begin{macrocode}
+\tl_const:cn { c_fp_ln_10_1_tl } { { 2 } { 302585092 } { 994045684 } { 0 } }
+\tl_const:cn { c_fp_ln_10_2_tl } { { 4 } { 605170185 } { 988091368 } { 0 } }
+\tl_const:cn { c_fp_ln_10_3_tl } { { 6 } { 907755278 } { 982137052 } { 0 } }
+\tl_const:cn { c_fp_ln_10_4_tl } { { 9 } { 210340371 } { 976182736 } { 0 } }
+\tl_const:cn { c_fp_ln_10_5_tl } { { 1 } { 151292546 } { 497022842 } { 1 } }
+\tl_const:cn { c_fp_ln_10_6_tl } { { 1 } { 381551055 } { 796427410 } { 1 } }
+\tl_const:cn { c_fp_ln_10_7_tl } { { 1 } { 611809565 } { 095831979 } { 1 } }
+\tl_const:cn { c_fp_ln_10_8_tl } { { 1 } { 842068074 } { 395226547 } { 1 } }
+\tl_const:cn { c_fp_ln_10_9_tl } { { 2 } { 072326583 } { 694641116 } { 1 } }
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+%^^A 0.69...309 4.
+% \begin{variable}{\c_fp_ln_2_1_tl }
+% \begin{variable}{\c_fp_ln_2_2_tl }
+% \begin{variable}{\c_fp_ln_2_3_tl }
+% The smaller set for powers of two.
+% \begin{macrocode}
+\tl_const:cn { c_fp_ln_2_1_tl } { { 0 } { 693147180 } { 559945309 } { 0 } }
+\tl_const:cn { c_fp_ln_2_2_tl } { { 1 } { 386294361 } { 119890618 } { 0 } }
+\tl_const:cn { c_fp_ln_2_3_tl } { { 2 } { 079441541 } { 679835928 } { 0 } }
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+%
+% \begin{macro}{\fp_ln:Nn, \fp_ln:cn}
+% \UnitTested
+% \begin{macro}{\fp_gln:Nn,\fp_gln:cn}
+% \UnitTested
+% \begin{macro}[aux]{\fp_ln_aux:NNn}
+% \begin{macro}[aux]{\fp_ln_aux:}
+% \begin{macro}[aux]{\fp_ln_exponent:}
+% \begin{macro}[aux]{\fp_ln_internal:}
+% \begin{macro}[aux]{\fp_ln_exponent_tens:}
+% \begin{macro}[aux]{\fp_ln_exponent_units:}
+% \begin{macro}[aux]{\fp_ln_normalise:}
+% \begin{macro}[aux]{\fp_ln_nornalise_aux:NNNNNNNNN}
+% \begin{macro}[aux]{\fp_ln_mantissa:}
+% \begin{macro}[aux]{\fp_ln_mantissa_aux:}
+% \begin{macro}[aux]{\fp_ln_mantissa_divide_two:}
+% \begin{macro}[aux]{\fp_ln_integer_const:nn}
+% \begin{macro}[aux]{\fp_ln_Taylor:}
+% \begin{macro}[aux]{\fp_ln_fixed:}
+% \begin{macro}[aux]{\fp_ln_fixed_aux:NNNNNNNNN}
+% \begin{macro}[aux]{\fp_ln_Taylor_aux:}
+% The approach for logarithms is again based on a mix of tables and
+% Taylor series. Here, the initial validation is a bit easier and so it
+% is set up earlier, meaning less need to escape later on.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_ln:Nn { \fp_ln_aux:NNn \tl_set:Nn }
+\cs_new_protected_nopar:Npn \fp_gln:Nn { \fp_ln_aux:NNn \tl_gset:Nn }
+\cs_generate_variant:Nn \fp_ln:Nn { c }
+\cs_generate_variant:Nn \fp_gln:Nn { c }
+\cs_new_protected_nopar:Npn \fp_ln_aux:NNn #1#2#3
+ {
+ \group_begin:
+ \fp_split:Nn a {#3}
+ \fp_standardise:NNNN
+ \l_fp_input_a_sign_int
+ \l_fp_input_a_integer_int
+ \l_fp_input_a_decimal_int
+ \l_fp_input_a_exponent_int
+ \if_int_compare:w \l_fp_input_a_sign_int > \c_zero
+ \if_int_compare:w
+ \int_eval:w
+ \l_fp_input_a_integer_int + \l_fp_input_a_decimal_int
+ > \c_zero
+ \exp_after:wN \exp_after:wN \exp_after:wN \fp_ln_aux:
+ \else:
+ \cs_set_protected_nopar:Npx \fp_tmp:w ##1##2
+ {
+ \group_end:
+ ##1 \exp_not:N ##2 { \c_zero_fp }
+ }
+ \exp_after:wN \exp_after:wN \exp_after:wN \fp_ln_error_msg:
+ \fi:
+ \else:
+ \cs_set_protected_nopar:Npx \fp_tmp:w ##1##2
+ {
+ \group_end:
+ ##1 \exp_not:N ##2 { \c_zero_fp }
+ }
+ \exp_after:wN \fp_ln_error_msg:
+ \fi:
+ \fp_tmp:w #1 #2
+ }
+% \end{macrocode}
+% As the input at this stage meets the validity criteria above, the
+% argument can now be saved for further processing. There is no need
+% to look at the sign of the input as it must be positive. The function
+% here simply sets up to either do the full calculation or recover
+% the stored value, as appropriate.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_ln_aux:
+ {
+ \tl_set:Nx \l_fp_arg_tl
+ {
+ +
+ \int_use:N \l_fp_input_a_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \int_value:w \int_eval:w
+ \l_fp_input_a_decimal_int + \c_one_thousand_million
+ e
+ \int_use:N \l_fp_input_a_exponent_int
+ }
+ \if_cs_exist:w c_fp_ln ( \l_fp_arg_tl ) _fp \cs_end:
+ \else:
+ \exp_after:wN \fp_ln_exponent:
+ \fi:
+ \cs_set_protected_nopar:Npx \fp_tmp:w ##1##2
+ {
+ \group_end:
+ ##1 \exp_not:N ##2
+ { \use:c { c_fp_ln ( \l_fp_arg_tl ) _fp } }
+ }
+ }
+% \end{macrocode}
+% The main algorithm here uses the fact the logarithm can be divided
+% up, first taking out the powers of ten, then powers of two and finally
+% using a Taylor series for the remainder.
+% \[
+% \ln ( 10^{n} \times 2^{m} \times x )
+% = \ln ( 10^{n} ) + \ln ( 2^{m} ) + \ln ( x )
+% \]
+% The second point to remember is that
+% \[
+% \ln ( x^{-1} ) = - \ln ( x )
+% \]
+% which means that for the powers of $ 10 $ and $ 2 $ constants
+% are only needed for positive powers.
+%
+% The first step is to set up the sign for the output functions and
+% work out the powers of ten in the exponent. First the larger powers
+% are sorted out. The values for the constants are the same as those
+% for the smaller ones, just with a shift in the exponent.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_ln_exponent:
+ {
+ \fp_ln_internal:
+ \if_int_compare:w \l_fp_output_extended_int < \c_five_hundred_million
+ \else:
+ \tex_advance:D \l_fp_output_decimal_int \c_one
+ \if_int_compare:w \l_fp_output_decimal_int < \c_one_thousand_million
+ \else:
+ \l_fp_output_decimal_int \c_zero
+ \tex_advance:D \l_fp_output_integer_int \c_one
+ \fi:
+ \fi:
+ \fp_standardise:NNNN
+ \l_fp_output_sign_int
+ \l_fp_output_integer_int
+ \l_fp_output_decimal_int
+ \l_fp_output_exponent_int
+ \tl_const:cx { c_fp_ln ( \l_fp_arg_tl ) _fp }
+ {
+ \if_int_compare:w \l_fp_output_sign_int > \c_zero
+ +
+ \else:
+ -
+ \fi:
+ \int_use:N \l_fp_output_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \int_value:w \int_eval:w
+ \l_fp_output_decimal_int + \c_one_thousand_million
+ \scan_stop:
+ e
+ \int_use:N \l_fp_output_exponent_int
+ }
+ }
+\cs_new_protected_nopar:Npn \fp_ln_internal:
+ {
+ \if_int_compare:w \l_fp_input_a_exponent_int < \c_zero
+ \l_fp_input_a_exponent_int -\l_fp_input_a_exponent_int
+ \l_fp_output_sign_int \c_minus_one
+ \else:
+ \l_fp_output_sign_int \c_one
+ \fi:
+ \if_int_compare:w \l_fp_input_a_exponent_int > \c_nine
+ \exp_after:wN \fp_ln_exponent_tens:NN
+ \int_use:N \l_fp_input_a_exponent_int
+ \else:
+ \l_fp_output_integer_int \c_zero
+ \l_fp_output_decimal_int \c_zero
+ \l_fp_output_extended_int \c_zero
+ \l_fp_output_exponent_int \c_zero
+ \fi:
+ \fp_ln_exponent_units:
+ }
+\cs_new_protected_nopar:Npn \fp_ln_exponent_tens:NN #1 #2
+ {
+ \l_fp_input_a_exponent_int #2 \scan_stop:
+ \fp_ln_const:nn { 10 } { #1 }
+ \tex_advance:D \l_fp_exp_exponent_int \c_one
+ \l_fp_output_integer_int \l_fp_exp_integer_int
+ \l_fp_output_decimal_int \l_fp_exp_decimal_int
+ \l_fp_output_extended_int \l_fp_exp_extended_int
+ \l_fp_output_exponent_int \l_fp_exp_exponent_int
+ }
+% \end{macrocode}
+% Next the smaller powers of ten, which will need to be combined
+% with the above: always an additive process.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_ln_exponent_units:
+ {
+ \if_int_compare:w \l_fp_input_a_exponent_int > \c_zero
+ \fp_ln_const:nn { 10 } { \int_use:N \l_fp_input_a_exponent_int }
+ \fp_ln_normalise:
+ \fp_add:NNNNNNNNN
+ \l_fp_exp_integer_int \l_fp_exp_decimal_int \l_fp_exp_extended_int
+ \l_fp_output_integer_int \l_fp_output_decimal_int
+ \l_fp_output_extended_int
+ \l_fp_output_integer_int \l_fp_output_decimal_int
+ \l_fp_output_extended_int
+ \fi:
+ \fp_ln_mantissa:
+ }
+% \end{macrocode}
+% The smaller table-based parts may need to be exponent shifted so that
+% they stay in line with the larger parts. This is similar to the
+% approach in other places, but here there is a need to watch the
+% extended part of the number. The only case where the new exponent is
+% larger than the old is if there was no previous part. Then simply set
+% the exponent.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_ln_normalise:
+ {
+ \if_int_compare:w \l_fp_exp_exponent_int < \l_fp_output_exponent_int
+ \tex_advance:D \l_fp_exp_decimal_int \c_one_thousand_million
+ \exp_after:wN \use_i:nn \exp_after:wN
+ \fp_ln_normalise_aux:NNNNNNNNN
+ \int_use:N \l_fp_exp_decimal_int
+ \exp_after:wN \fp_ln_normalise:
+ \else:
+ \l_fp_output_exponent_int \l_fp_exp_exponent_int
+ \fi:
+ }
+\cs_new_protected_nopar:Npn \fp_ln_normalise_aux:NNNNNNNNN #1#2#3#4#5#6#7#8#9
+ {
+ \if_int_compare:w \l_fp_exp_integer_int = \c_zero
+ \l_fp_exp_decimal_int #1#2#3#4#5#6#7#8 \scan_stop:
+ \else:
+ \tl_set:Nx \l_fp_tmp_tl
+ {
+ \int_use:N \l_fp_exp_integer_int
+ #1#2#3#4#5#6#7#8
+ }
+ \l_fp_exp_integer_int \c_zero
+ \l_fp_exp_decimal_int \l_fp_tmp_tl \scan_stop:
+ \fi:
+ \tex_divide:D \l_fp_exp_extended_int \c_ten
+ \tl_set:Nx \l_fp_tmp_tl
+ {
+ #9
+ \int_use:N \l_fp_exp_extended_int
+ }
+ \l_fp_exp_extended_int \l_fp_tmp_tl \scan_stop:
+ \tex_advance:D \l_fp_exp_exponent_int \c_one
+ }
+% \end{macrocode}
+% The next phase is to decompose the mantissa by division by two to
+% leave a value which is in the range $ 1 \le x < 2 $. The sum of the
+% two powers needs to take account of the sign of the output: if it
+% is negative then the result gets \emph{smaller} as the mantissa gets
+% \emph{bigger}.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_ln_mantissa:
+ {
+ \l_fp_count_int \c_zero
+ \l_fp_input_a_extended_int \c_zero
+ \fp_ln_mantissa_aux:
+ \if_int_compare:w \l_fp_count_int > \c_zero
+ \fp_ln_const:nn { 2 } { \int_use:N \l_fp_count_int }
+ \fp_ln_normalise:
+ \if_int_compare:w \l_fp_output_sign_int > \c_zero
+ \exp_after:wN \fp_add:NNNNNNNNN
+ \else:
+ \exp_after:wN \fp_sub:NNNNNNNNN
+ \fi:
+ \l_fp_output_integer_int \l_fp_output_decimal_int
+ \l_fp_output_extended_int
+ \l_fp_exp_integer_int \l_fp_exp_decimal_int \l_fp_exp_extended_int
+ \l_fp_output_integer_int \l_fp_output_decimal_int
+ \l_fp_output_extended_int
+ \fi:
+ \if_int_compare:w
+ \int_eval:w
+ \l_fp_input_a_integer_int + \l_fp_input_a_decimal_int > \c_one
+ \exp_after:wN \fp_ln_Taylor:
+ \fi:
+ }
+\cs_new_protected_nopar:Npn \fp_ln_mantissa_aux:
+ {
+ \if_int_compare:w \l_fp_input_a_integer_int > \c_one
+ \tex_advance:D \l_fp_count_int \c_one
+ \fp_ln_mantissa_divide_two:
+ \exp_after:wN \fp_ln_mantissa_aux:
+ \fi:
+ }
+% \end{macrocode}
+% A fast one-shot division by two.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_ln_mantissa_divide_two:
+ {
+ \if_int_odd:w \l_fp_input_a_decimal_int
+ \tex_advance:D \l_fp_input_a_extended_int \c_one_thousand_million
+ \fi:
+ \if_int_odd:w \l_fp_input_a_integer_int
+ \tex_advance:D \l_fp_input_a_decimal_int \c_one_thousand_million
+ \fi:
+ \tex_divide:D \l_fp_input_a_integer_int \c_two
+ \tex_divide:D \l_fp_input_a_decimal_int \c_two
+ \tex_divide:D \l_fp_input_a_extended_int \c_two
+ }
+% \end{macrocode}
+% Recovering constants makes use of the same auxiliary code as for
+% exponents.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_ln_const:nn #1#2
+ {
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \fp_exp_integer_const:nnnn
+ \cs:w c_fp_ln_ #1 _ #2 _tl \cs_end:
+ }
+% \end{macrocode}
+% The Taylor series for the logarithm function is best implemented using
+% the identity
+% \[
+% \ln(x) = \ln\left( \frac{y + 1}{y - 1} \right)
+% \]
+% with
+% \[
+% y = \frac{x - 1}{x + 1}
+% \]
+% This leads to the series
+% \[
+% \ln(x)
+% = 2y
+% \left(
+% 1 + y^{2}
+% \left(
+% \frac{1}{3} + y^{2}
+% \left(
+% \frac{1}{5} + y^{2}
+% \left(
+% \frac{1}{7} + y^{2}
+% \left(
+% \frac{1}{9} + \cdots
+% \right)
+% \right)
+% \right)
+% \right)
+% \right)
+% \]
+% This expansion has the advantage that a lot of the work can be
+% loaded up early by finding $ y^{2} $ before the loop itself starts.
+% (In practice, the implementation does the multiplication by two at the
+% end of the loop, and expands out the brackets as this is an overall
+% more efficient approach.)
+%
+% At the implementation level, the code starts by calculating $ y $
+% and storing that in input \texttt{a} (which is no longer needed
+% for other purposes). That is done using the full division system
+% avoiding the parsing step. The value is then switched to a fixed-point
+% representation. There is then some shuffling to get all of the working
+% space set up. At this stage, a lot of registers are in use and so
+% the Taylor series is calculated within a group so that the
+% \texttt{output} variables can be used to hold the result. The value
+% of $ y^{2} $ is held in input \texttt{b} (there are a few
+% assignments saved by choosing this over \texttt{a}), while input
+% \texttt{a} is used for the \enquote{loop value}.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_ln_Taylor:
+ {
+ \group_begin:
+ \l_fp_input_a_integer_int \c_zero
+ \l_fp_input_a_exponent_int \c_zero
+ \l_fp_input_b_integer_int \c_two
+ \l_fp_input_b_decimal_int \l_fp_input_a_decimal_int
+ \l_fp_input_b_exponent_int \c_zero
+ \fp_div_internal:
+ \fp_ln_fixed:
+ \l_fp_input_a_integer_int \l_fp_output_integer_int
+ \l_fp_input_a_decimal_int \l_fp_output_decimal_int
+ \l_fp_input_a_extended_int \c_zero
+ \l_fp_input_a_exponent_int \l_fp_output_exponent_int
+ \l_fp_output_decimal_int \c_zero %^^A Bug?
+ \l_fp_output_decimal_int \l_fp_input_a_decimal_int
+ \l_fp_output_extended_int \l_fp_input_a_extended_int
+ \fp_mul:NNNNNN
+ \l_fp_input_a_decimal_int \l_fp_input_a_extended_int
+ \l_fp_input_a_decimal_int \l_fp_input_a_extended_int
+ \l_fp_input_b_decimal_int \l_fp_input_b_extended_int
+ \l_fp_count_int \c_one
+ \fp_ln_Taylor_aux:
+ \cs_set_protected_nopar:Npx \fp_tmp:w
+ {
+ \group_end:
+ \l_fp_exp_integer_int \c_zero
+ \exp_not:N \l_fp_exp_decimal_int
+ \int_use:N \l_fp_output_decimal_int \scan_stop:
+ \exp_not:N \l_fp_exp_extended_int
+ \int_use:N \l_fp_output_extended_int \scan_stop:
+ \exp_not:N \l_fp_exp_exponent_int
+ \int_use:N \l_fp_output_exponent_int \scan_stop:
+ }
+ \fp_tmp:w
+% \end{macrocode}
+% After the loop part of the Taylor series, the factor of $ 2 $ needs
+% to be included. The total for the result can then be constructed.
+% \begin{macrocode}
+ \tex_advance:D \l_fp_exp_decimal_int \l_fp_exp_decimal_int
+ \if_int_compare:w \l_fp_exp_extended_int < \c_five_hundred_million
+ \else:
+ \tex_advance:D \l_fp_exp_extended_int -\c_five_hundred_million
+ \tex_advance:D \l_fp_exp_decimal_int \c_one
+ \fi:
+ \tex_advance:D \l_fp_exp_extended_int \l_fp_exp_extended_int
+ \fp_ln_normalise:
+ \if_int_compare:w \l_fp_output_sign_int > \c_zero
+ \exp_after:wN \fp_add:NNNNNNNNN
+ \else:
+ \exp_after:wN \fp_sub:NNNNNNNNN
+ \fi:
+ \l_fp_output_integer_int \l_fp_output_decimal_int
+ \l_fp_output_extended_int
+ \c_zero \l_fp_exp_decimal_int \l_fp_exp_extended_int
+ \l_fp_output_integer_int \l_fp_output_decimal_int
+ \l_fp_output_extended_int
+ }
+% \end{macrocode}
+% The usual shifts to move to fixed-point working. This is done using
+% the \texttt{output} registers as this saves a reassignment here.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_ln_fixed:
+ {
+ \if_int_compare:w \l_fp_output_exponent_int < \c_zero
+ \tex_advance:D \l_fp_output_decimal_int \c_one_thousand_million
+ \exp_after:wN \use_i:nn \exp_after:wN
+ \fp_ln_fixed_aux:NNNNNNNNN
+ \int_use:N \l_fp_output_decimal_int
+ \exp_after:wN \fp_ln_fixed:
+ \fi:
+ }
+\cs_new_protected_nopar:Npn \fp_ln_fixed_aux:NNNNNNNNN #1#2#3#4#5#6#7#8#9
+ {
+ \if_int_compare:w \l_fp_output_integer_int = \c_zero
+ \l_fp_output_decimal_int #1#2#3#4#5#6#7#8 \scan_stop:
+ \else:
+ \tl_set:Nx \l_fp_tmp_tl
+ {
+ \int_use:N \l_fp_output_integer_int
+ #1#2#3#4#5#6#7#8
+ }
+ \l_fp_output_integer_int \c_zero
+ \l_fp_output_decimal_int \l_fp_tmp_tl \scan_stop:
+ \fi:
+ \tex_advance:D \l_fp_output_exponent_int \c_one
+ }
+% \end{macrocode}
+% The main loop for the Taylor series: unlike some of the other similar
+% functions, the result here is not the final value and is therefore
+% subject to further manipulation outside of the loop.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_ln_Taylor_aux:
+ {
+ \tex_advance:D \l_fp_count_int \c_two
+ \fp_mul:NNNNNN
+ \l_fp_input_a_decimal_int \l_fp_input_a_extended_int
+ \l_fp_input_b_decimal_int \l_fp_input_b_extended_int
+ \l_fp_input_a_decimal_int \l_fp_input_a_extended_int
+ \if_int_compare:w
+ \int_eval:w
+ \l_fp_input_a_decimal_int + \l_fp_input_a_extended_int
+ > \c_zero
+ \fp_div_integer:NNNNN
+ \l_fp_input_a_decimal_int \l_fp_input_a_extended_int
+ \l_fp_count_int
+ \l_fp_exp_decimal_int \l_fp_exp_extended_int
+ \tex_advance:D \l_fp_output_decimal_int \l_fp_exp_decimal_int
+ \tex_advance:D \l_fp_output_extended_int \l_fp_exp_extended_int
+ \if_int_compare:w \l_fp_output_extended_int < \c_one_thousand_million
+ \else:
+ \tex_advance:D \l_fp_output_decimal_int \c_one
+ \tex_advance:D \l_fp_output_extended_int
+ -\c_one_thousand_million
+ \fi:
+ \if_int_compare:w \l_fp_output_decimal_int < \c_one_thousand_million
+ \else:
+ \tex_advance:D \l_fp_output_integer_int \c_one
+ \tex_advance:D \l_fp_output_decimal_int
+ -\c_one_thousand_million
+ \fi:
+ \exp_after:wN \fp_ln_Taylor_aux:
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\fp_pow:Nn, \fp_pow:cn}
+% \UnitTested
+% \begin{macro}{\fp_gpow:Nn,\fp_gpow:cn}
+% \UnitTested
+% \begin{macro}[aux]{\fp_pow_aux:NNn}
+% \begin{macro}[aux]{\fp_pow_aux_i:}
+% \begin{macro}[aux]{\fp_pow_positive:}
+% \begin{macro}[aux]{\fp_pow_negative:}
+% \begin{macro}[aux]{\fp_pow_aux_ii:}
+% \begin{macro}[aux]{\fp_pow_aux_iii:}
+% \begin{macro}[aux]{\fp_pow_aux_iv:}
+% The approach used for working out powers is to first filter out the
+% various special cases and then do most of the work using the
+% logarithm and exponent functions. The two storage areas are used
+% in the reverse of the `natural' logic as this avoids some
+% re-assignment in the sanity checking code.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_pow:Nn { \fp_pow_aux:NNn \tl_set:Nn }
+\cs_new_protected_nopar:Npn \fp_gpow:Nn { \fp_pow_aux:NNn \tl_gset:Nn }
+\cs_generate_variant:Nn \fp_pow:Nn { c }
+\cs_generate_variant:Nn \fp_gpow:Nn { c }
+\cs_new_protected_nopar:Npn \fp_pow_aux:NNn #1#2#3
+ {
+ \group_begin:
+ \fp_read:N #2
+ \l_fp_input_b_sign_int \l_fp_input_a_sign_int
+ \l_fp_input_b_integer_int \l_fp_input_a_integer_int
+ \l_fp_input_b_decimal_int \l_fp_input_a_decimal_int
+ \l_fp_input_b_exponent_int \l_fp_input_a_exponent_int
+ \fp_split:Nn a {#3}
+ \fp_standardise:NNNN
+ \l_fp_input_a_sign_int
+ \l_fp_input_a_integer_int
+ \l_fp_input_a_decimal_int
+ \l_fp_input_a_exponent_int
+ \if_int_compare:w
+ \int_eval:w
+ \l_fp_input_b_integer_int + \l_fp_input_b_decimal_int
+ = \c_zero
+ \if_int_compare:w
+ \int_eval:w
+ \l_fp_input_a_integer_int + \l_fp_input_a_decimal_int
+ = \c_zero
+ \cs_set_protected_nopar:Npx \fp_tmp:w ##1##2
+ {
+ \group_end:
+ ##1 ##2 { \c_undefined_fp }
+ }
+ \else:
+ \cs_set_protected_nopar:Npx \fp_tmp:w ##1##2
+ {
+ \group_end:
+ ##1 ##2 { \c_zero_fp }
+ }
+ \fi:
+ \else:
+ \if_int_compare:w
+ \int_eval:w
+ \l_fp_input_a_integer_int + \l_fp_input_a_decimal_int
+ = \c_zero
+ \cs_set_protected_nopar:Npx \fp_tmp:w ##1##2
+ {
+ \group_end:
+ ##1 ##2 { \c_one_fp }
+ }
+ \else:
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \fp_pow_aux_i:
+ \fi:
+ \fi:
+ \fp_tmp:w #1 #2
+}
+% \end{macrocode}
+% Simply using the logarithm function directly will fail when negative
+% numbers are raised to integer powers, which is a mathematically valid
+% operation. So there are some more tests to make, after forcing the
+% power into an integer and decimal parts, if necessary.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_pow_aux_i:
+ {
+ \if_int_compare:w \l_fp_input_b_sign_int > \c_zero
+ \tl_set:Nn \l_fp_sign_tl { + }
+ \exp_after:wN \fp_pow_aux_ii:
+ \else:
+ \l_fp_input_a_extended_int \c_zero
+ \if_int_compare:w \l_fp_input_a_exponent_int < \c_ten
+ \group_begin:
+ \fp_extended_normalise:
+ \if_int_compare:w
+ \int_eval:w
+ \l_fp_input_a_decimal_int + \l_fp_input_a_extended_int
+ = \c_zero
+ \group_end:
+ \tl_set:Nn \l_fp_sign_tl { - }
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \exp_after:wN \fp_pow_aux_ii:
+ \else:
+ \group_end:
+ \cs_set_protected_nopar:Npx \fp_tmp:w ##1##2
+ {
+ \group_end:
+ ##1 ##2 { \c_undefined_fp }
+ }
+ \fi:
+ \else:
+ \cs_set_protected_nopar:Npx \fp_tmp:w ##1##2
+ {
+ \group_end:
+ ##1 ##2 { \c_undefined_fp }
+ }
+ \fi:
+ \fi:
+ }
+% \end{macrocode}
+% The approach used here for powers works well in most cases but gives
+% poorer results for negative integer powers, which often have exact
+% values. So there is some filtering to do. For negative powers where
+% the power is small, an alternative approach is used in which the
+% positive value is worked out and the reciprocal is then taken. The
+% filtering is unfortunately rather long.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_pow_aux_ii:
+ {
+ \if_int_compare:w \l_fp_input_a_sign_int > \c_zero
+ \exp_after:wN \fp_pow_aux_iv:
+ \else:
+ \if_int_compare:w \l_fp_input_a_exponent_int < \c_ten
+ \group_begin:
+ \l_fp_input_a_extended_int \c_zero
+ \fp_extended_normalise:
+ \if_int_compare:w \l_fp_input_a_decimal_int = \c_zero
+ \if_int_compare:w \l_fp_input_a_integer_int > \c_ten
+ \group_end:
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \fp_pow_aux_iv:
+ \else:
+ \group_end:
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \exp_after:wN \fp_pow_aux_iii:
+ \fi:
+ \else:
+ \group_end:
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \exp_after:wN \fp_pow_aux_iv:
+ \fi:
+ \else:
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \fp_pow_aux_iv:
+ \fi:
+ \fi:
+ \cs_set_protected_nopar:Npx \fp_tmp:w ##1##2
+ {
+ \group_end:
+ ##1 ##2
+ {
+ \l_fp_sign_tl
+ \int_use:N \l_fp_output_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \int_value:w \int_eval:w
+ \l_fp_output_decimal_int + \c_one_thousand_million
+ e
+ \int_use:N \l_fp_output_exponent_int
+ }
+ }
+ }
+% \end{macrocode}
+% For the small negative integer powers, the calculation is done for
+% the positive power and the reciprocal is then taken.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_pow_aux_iii:
+ {
+ \l_fp_input_a_sign_int \c_one
+ \fp_pow_aux_iv:
+ \l_fp_input_a_integer_int \c_one
+ \l_fp_input_a_decimal_int \c_zero
+ \l_fp_input_a_exponent_int \c_zero
+ \l_fp_input_b_integer_int \l_fp_output_integer_int
+ \l_fp_input_b_decimal_int \l_fp_output_decimal_int
+ \l_fp_input_b_exponent_int \l_fp_output_exponent_int
+ \fp_div_internal:
+ }
+% \end{macrocode}
+% The business end of the code starts by finding the logarithm of the
+% given base. There is a bit of a shuffle so that this does not have
+% to be re-parsed and so that the output ends up in the correct place.
+% There is also a need to enable using the short-cut for a
+% pre-calculated result. The internal part of the multiplication
+% function can then be used to do the second part of the calculation
+% directly. There is some more set up before doing the exponential:
+% the idea here is to deactivate some internals so that everything works
+% smoothly.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \fp_pow_aux_iv:
+ {
+ \group_begin:
+ \l_fp_input_a_integer_int \l_fp_input_b_integer_int
+ \l_fp_input_a_decimal_int \l_fp_input_b_decimal_int
+ \l_fp_input_a_exponent_int \l_fp_input_b_exponent_int
+ \fp_ln_internal:
+ \cs_set_protected_nopar:Npx \fp_tmp:w
+ {
+ \group_end:
+ \exp_not:N \l_fp_input_b_sign_int
+ \int_use:N \l_fp_output_sign_int \scan_stop:
+ \exp_not:N \l_fp_input_b_integer_int
+ \int_use:N \l_fp_output_integer_int \scan_stop:
+ \exp_not:N \l_fp_input_b_decimal_int
+ \int_use:N \l_fp_output_decimal_int \scan_stop:
+ \exp_not:N \l_fp_input_b_extended_int
+ \int_use:N \l_fp_output_extended_int \scan_stop:
+ \exp_not:N \l_fp_input_b_exponent_int
+ \int_use:N \l_fp_output_exponent_int \scan_stop:
+ }
+ \fp_tmp:w
+ \l_fp_input_a_extended_int \c_zero
+ \fp_mul:NNNNNNNNN
+ \l_fp_input_a_integer_int \l_fp_input_a_decimal_int
+ \l_fp_input_a_extended_int
+ \l_fp_input_b_integer_int \l_fp_input_b_decimal_int
+ \l_fp_input_b_extended_int
+ \l_fp_output_integer_int \l_fp_output_decimal_int
+ \l_fp_output_extended_int
+ \l_fp_output_exponent_int
+ \int_eval:w
+ \l_fp_input_a_exponent_int + \l_fp_input_b_exponent_int
+ \scan_stop:
+ \fp_extended_normalise_output:
+ \tex_multiply:D \l_fp_input_a_sign_int \l_fp_input_b_sign_int
+ \l_fp_input_a_integer_int \l_fp_output_integer_int
+ \l_fp_input_a_decimal_int \l_fp_output_decimal_int
+ \l_fp_input_a_extended_int \l_fp_output_extended_int
+ \l_fp_input_a_exponent_int \l_fp_output_exponent_int
+ \l_fp_output_integer_int \c_zero
+ \l_fp_output_decimal_int \c_zero
+ \l_fp_output_extended_int \c_zero
+ \l_fp_output_exponent_int \c_zero
+ \cs_set_eq:NN \fp_exp_const:Nx \use_none:nn
+ \fp_exp_internal:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Tests for special values}
+%
+% \begin{macro}[pTF]{\fp_if_undefined:N}
+% \UnitTested
+% Testing for an undefined value is easy.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \fp_if_undefined:N #1 { p , T , F , TF }
+ {
+ \if_meaning:w #1 \c_undefined_fp
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\fp_if_zero:N}
+% \UnitTested
+% Testing for a zero fixed-point is also easy.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \fp_if_zero:N #1 { p , T , F , TF }
+ {
+ \if_meaning:w #1 \c_zero_fp
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Floating-point conditionals}
+%
+% \begin{macro}[TF]{\fp_compare:nNn}
+% \begin{macro}[TF]{\fp_compare:NNN}
+% \UnitTested
+% \begin{macro}[aux]{\fp_compare_aux:N}
+% \begin{macro}[aux]{\fp_compare_=:}
+% \begin{macro}[aux]{\fp_compare_<:}
+% \begin{macro}[aux]{\fp_compare_<_aux:}
+% \begin{macro}[aux]{\fp_compare_absolute_a>b:}
+% \begin{macro}[aux]{\fp_compare_absolute_a<b:}
+% \begin{macro}[aux]{\fp_compare_>:}
+% The idea for the comparisons is to provide two versions: slower and
+% faster. The lead off for both is the same: get the two numbers
+% read and then look for a function to handle the comparison.
+% \begin{macrocode}
+\prg_new_protected_conditional:Npnn \fp_compare:nNn #1#2#3 { T , F , TF }
+ {
+ \group_begin:
+ \fp_split:Nn a {#1}
+ \fp_standardise:NNNN
+ \l_fp_input_a_sign_int
+ \l_fp_input_a_integer_int
+ \l_fp_input_a_decimal_int
+ \l_fp_input_a_exponent_int
+ \fp_split:Nn b {#3}
+ \fp_standardise:NNNN
+ \l_fp_input_b_sign_int
+ \l_fp_input_b_integer_int
+ \l_fp_input_b_decimal_int
+ \l_fp_input_b_exponent_int
+ \fp_compare_aux:N #2
+ }
+\prg_new_protected_conditional:Npnn \fp_compare:NNN #1#2#3 { T , F , TF }
+ {
+ \group_begin:
+ \fp_read:N #3
+ \l_fp_input_b_sign_int \l_fp_input_a_sign_int
+ \l_fp_input_b_integer_int \l_fp_input_a_integer_int
+ \l_fp_input_b_decimal_int \l_fp_input_a_decimal_int
+ \l_fp_input_b_exponent_int \l_fp_input_a_exponent_int
+ \fp_read:N #1
+ \fp_compare_aux:N #2
+ }
+\cs_new_protected_nopar:Npn \fp_compare_aux:N #1
+ {
+ \cs_if_exist:cTF { fp_compare_#1: }
+ { \use:c { fp_compare_#1: } }
+ {
+ \group_end:
+ \prg_return_false:
+ }
+ }
+% \end{macrocode}
+% For equality, the test is pretty easy as things are either equal or
+% they are not.
+% \begin{macrocode}
+\cs_new_protected_nopar:cpn { fp_compare_=: }
+ {
+ \if_int_compare:w \l_fp_input_a_sign_int = \l_fp_input_b_sign_int
+ \if_int_compare:w \l_fp_input_a_integer_int = \l_fp_input_b_integer_int
+ \if_int_compare:w \l_fp_input_a_decimal_int = \l_fp_input_b_decimal_int
+ \if_int_compare:w
+ \l_fp_input_a_exponent_int = \l_fp_input_b_exponent_int
+ \group_end:
+ \prg_return_true:
+ \else:
+ \group_end:
+ \prg_return_false:
+ \fi:
+ \else:
+ \group_end:
+ \prg_return_false:
+ \fi:
+ \else:
+ \group_end:
+ \prg_return_false:
+ \fi:
+ \else:
+ \group_end:
+ \prg_return_false:
+ \fi:
+ }
+% \end{macrocode}
+% Comparing two values is quite complex. First, there is a filter step
+% to check if one or other of the given values is zero. If it is then
+% the result is relatively easy to determine.
+% \begin{macrocode}
+\cs_new_protected_nopar:cpn { fp_compare_>: }
+ {
+ \if_int_compare:w \int_eval:w
+ \l_fp_input_a_integer_int + \l_fp_input_a_decimal_int
+ = \c_zero
+ \if_int_compare:w \int_eval:w
+ \l_fp_input_b_integer_int + \l_fp_input_b_decimal_int
+ = \c_zero
+ \group_end:
+ \prg_return_false:
+ \else:
+ \if_int_compare:w \l_fp_input_b_sign_int > \c_zero
+ \group_end:
+ \prg_return_false:
+ \else:
+ \group_end:
+ \prg_return_true:
+ \fi:
+ \fi:
+ \else:
+ \if_int_compare:w \int_eval:w
+ \l_fp_input_b_integer_int + \l_fp_input_b_decimal_int
+ = \c_zero
+ \if_int_compare:w \l_fp_input_a_sign_int > \c_zero
+ \group_end:
+ \prg_return_true:
+ \else:
+ \group_end:
+ \prg_return_false:
+ \fi:
+ \else:
+ \use:c { fp_compare_>_aux: }
+ \fi:
+ \fi:
+ }
+% \end{macrocode}
+% Next, check the sign of the input: this again may give an obvious
+% result. If both signs are the same, then hand off to comparing the
+% absolute values.
+% \begin{macrocode}
+\cs_new_protected_nopar:cpn { fp_compare_>_aux: }
+ {
+ \if_int_compare:w \l_fp_input_a_sign_int > \l_fp_input_b_sign_int
+ \group_end:
+ \prg_return_true:
+ \else:
+ \if_int_compare:w \l_fp_input_a_sign_int < \l_fp_input_b_sign_int
+ \group_end:
+ \prg_return_false:
+ \else:
+ \if_int_compare:w \l_fp_input_a_sign_int > \c_zero
+ \use:c { fp_compare_absolute_a>b: }
+ \else:
+ \use:c { fp_compare_absolute_a<b: }
+ \fi:
+ \fi:
+ \fi:
+ }
+% \end{macrocode}
+% Rather long runs of checks, as there is the need to go through each
+% layer of the input and do the comparison. There is also the need to
+% avoid messing up with equal inputs at each stage.
+% \begin{macrocode}
+\cs_new_protected_nopar:cpn { fp_compare_absolute_a>b: }
+ {
+ \if_int_compare:w \l_fp_input_a_exponent_int > \l_fp_input_b_exponent_int
+ \group_end:
+ \prg_return_true:
+ \else:
+ \if_int_compare:w \l_fp_input_a_exponent_int < \l_fp_input_b_exponent_int
+ \group_end:
+ \prg_return_false:
+ \else:
+ \if_int_compare:w \l_fp_input_a_integer_int > \l_fp_input_b_integer_int
+ \group_end:
+ \prg_return_true:
+ \else:
+ \if_int_compare:w
+ \l_fp_input_a_integer_int < \l_fp_input_b_integer_int
+ \group_end:
+ \prg_return_false:
+ \else:
+ \if_int_compare:w
+ \l_fp_input_a_decimal_int > \l_fp_input_b_decimal_int
+ \group_end:
+ \prg_return_true:
+ \else:
+ \group_end:
+ \prg_return_false:
+ \fi:
+ \fi:
+ \fi:
+ \fi:
+ \fi:
+ }
+\cs_new_protected_nopar:cpn { fp_compare_absolute_a<b: }
+ {
+ \if_int_compare:w \l_fp_input_b_exponent_int > \l_fp_input_a_exponent_int
+ \group_end:
+ \prg_return_true:
+ \else:
+ \if_int_compare:w \l_fp_input_b_exponent_int < \l_fp_input_a_exponent_int
+ \group_end:
+ \prg_return_false:
+ \else:
+ \if_int_compare:w \l_fp_input_b_integer_int > \l_fp_input_a_integer_int
+ \group_end:
+ \prg_return_true:
+ \else:
+ \if_int_compare:w
+ \l_fp_input_b_integer_int < \l_fp_input_a_integer_int
+ \group_end:
+ \prg_return_false:
+ \else:
+ \if_int_compare:w
+ \l_fp_input_b_decimal_int > \l_fp_input_a_decimal_int
+ \group_end:
+ \prg_return_true:
+ \else:
+ \group_end:
+ \prg_return_false:
+ \fi:
+ \fi:
+ \fi:
+ \fi:
+ \fi:
+ }
+% \end{macrocode}
+% This is just a case of reversing the two input values and then
+% running the tests already defined.
+% \begin{macrocode}
+\cs_new_protected_nopar:cpn { fp_compare_<: }
+ {
+ \tl_set:Nx \l_fp_tmp_tl
+ {
+ \int_set:Nn \exp_not:N \l_fp_input_a_sign_int
+ { \int_use:N \l_fp_input_b_sign_int }
+ \int_set:Nn \exp_not:N \l_fp_input_a_integer_int
+ { \int_use:N \l_fp_input_b_integer_int }
+ \int_set:Nn \exp_not:N \l_fp_input_a_decimal_int
+ { \int_use:N \l_fp_input_b_decimal_int }
+ \int_set:Nn \exp_not:N \l_fp_input_a_exponent_int
+ { \int_use:N \l_fp_input_b_exponent_int }
+ \int_set:Nn \exp_not:N \l_fp_input_b_sign_int
+ { \int_use:N \l_fp_input_a_sign_int }
+ \int_set:Nn \exp_not:N \l_fp_input_b_integer_int
+ { \int_use:N \l_fp_input_a_integer_int }
+ \int_set:Nn \exp_not:N \l_fp_input_b_decimal_int
+ { \int_use:N \l_fp_input_a_decimal_int }
+ \int_set:Nn \exp_not:N \l_fp_input_b_exponent_int
+ { \int_use:N \l_fp_input_a_exponent_int }
+ }
+ \l_fp_tmp_tl
+ \use:c { fp_compare_>: }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[TF]{\fp_compare:n}
+% \begin{macro}[aux]
+% {
+% \fp_compare_aux_i:w, \fp_compare_aux_ii:w, \fp_compare_aux_iii:w,
+% \fp_compare_aux_iv:w, \fp_compare_aux_v:w, \fp_compare_aux_vi:w,
+% \fp_compare_aux_vii:w
+% }
+% As \TeX{} cannot help out here, a daisy-chain of delimited functions
+% are used. This is very much a first-generation approach: revision will
+% be needed if these functions are really useful.
+% \begin{macrocode}
+\prg_new_protected_conditional:Npnn \fp_compare:n #1 { T , F , TF }
+ {
+ \group_begin:
+ \tl_set:Nx \l_fp_tmp_tl
+ {
+ \group_end:
+ \fp_compare_aux_i:w #1 \exp_not:n { == \q_nil == \q_stop }
+ }
+ \l_fp_tmp_tl
+ }
+\cs_new_protected_nopar:Npn \fp_compare_aux_i:w #1 == #2 == #3 \q_stop
+ {
+ \quark_if_nil:nTF {#2}
+ { \fp_compare_aux_ii:w #1 != \q_nil != \q_stop }
+ { \fp_compare:nNnTF {#1} = {#2} \prg_return_true: \prg_return_false: }
+ }
+\cs_new_protected_nopar:Npn \fp_compare_aux_ii:w #1 != #2 != #3 \q_stop
+ {
+ \quark_if_nil:nTF {#2}
+ { \fp_compare_aux_iii:w #1 <= \q_nil <= \q_stop }
+ { \fp_compare:nNnTF {#1} = {#2} \prg_return_false: \prg_return_true: }
+ }
+\cs_new_protected_nopar:Npn \fp_compare_aux_iii:w #1 <= #2 <= #3 \q_stop
+ {
+ \quark_if_nil:nTF {#2}
+ { \fp_compare_aux_iv:w #1 >= \q_nil >= \q_stop }
+ { \fp_compare:nNnTF {#1} > {#2} \prg_return_false: \prg_return_true: }
+ }
+\cs_new_protected_nopar:Npn \fp_compare_aux_iv:w #1 >= #2 >= #3 \q_stop
+ {
+ \quark_if_nil:nTF {#2}
+ { \fp_compare_aux_v:w #1 = \q_nil \q_stop }
+ { \fp_compare:nNnTF {#1} < {#2} \prg_return_false: \prg_return_true: }
+ }
+\cs_new_protected_nopar:Npn \fp_compare_aux_v:w #1 = #2 = #3 \q_stop
+ {
+ \quark_if_nil:nTF {#2}
+ { \fp_compare_aux_vi:w #1 < \q_nil < \q_stop }
+ { \fp_compare:nNnTF {#1} = {#2} \prg_return_true: \prg_return_false: }
+ }
+\cs_new_protected_nopar:Npn \fp_compare_aux_vi:w #1 < #2 < #3 \q_stop
+ {
+ \quark_if_nil:nTF {#2}
+ { \fp_compare_aux_vii:w #1 > \q_nil > \q_stop }
+ { \fp_compare:nNnTF {#1} < {#2} \prg_return_true: \prg_return_false: }
+ }
+\cs_new_protected_nopar:Npn \fp_compare_aux_vii:w #1 > #2 > #3 \q_stop
+ {
+ \quark_if_nil:nTF {#2}
+ { \prg_return_false: }
+ { \fp_compare:nNnTF {#1} > {#2} \prg_return_true: \prg_return_false: }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Messages}
+%
+% \begin{macro}{\fp_overflow_msg:}
+% A generic overflow message, used whenever there is a possible
+% overflow.
+% \begin{macrocode}
+\msg_kernel_new:nnnn { fpu } { overflow }
+ { Number~too~big. }
+ {
+ The~input~given~is~too~big~for~the~LaTeX~floating~point~unit. \\
+ Further~errors~may~well~occur!
+ }
+\cs_new_protected_nopar:Npn \fp_overflow_msg:
+ { \msg_kernel_error:nn { fpu } { overflow } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\fp_exp_overflow_msg:}
+% A slightly more helpful message for exponent overflows.
+% \begin{macrocode}
+\msg_kernel_new:nnnn { fpu } { exponent-overflow }
+ { Number~too~big~for~exponent~unit. }
+ {
+ The~exponent~of~the~input~given~is~too~big~for~the~floating~point~
+ unit:~the~maximum~input~value~for~an~exponent~is~230.
+ }
+\cs_new_protected_nopar:Npn \fp_exp_overflow_msg:
+ { \msg_kernel_error:nn { fpu } { exponent-overflow } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\fp_ln_error_msg:}
+% Logarithms are only valid for positive number
+% \begin{macrocode}
+\msg_kernel_new:nnnn { fpu } { logarithm-input-error }
+ { Invalid~input~to~ln~function. }
+ { Logarithms~can~only~be~calculated~for~positive~numbers. }
+\cs_new_protected_nopar:Npn \fp_ln_error_msg: {
+ \msg_kernel_error:nn { fpu } { logarithm-input-error }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\fp_trig_overflow_msg:}
+% A slightly more helpful message for trigonometric overflows.
+% \begin{macrocode}
+\msg_kernel_new:nnnn { fpu } { trigonometric-overflow }
+ { Number~too~big~for~trigonometry~unit. }
+ {
+ The~trigonometry~code~can~only~work~with~numbers~smaller~
+ than~1000000000.
+ }
+\cs_new_protected_nopar:Npn \fp_trig_overflow_msg:
+ { \msg_kernel_error:nn { fpu } { trigonometric-overflow } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</initex|package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+%\PrintIndex
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3int.dtx b/Master/texmf-dist/source/latex/l3kernel/l3int.dtx
new file mode 100644
index 00000000000..70264286d27
--- /dev/null
+++ b/Master/texmf-dist/source/latex/l3kernel/l3int.dtx
@@ -0,0 +1,2197 @@
+% \iffalse meta-comment
+%
+%% File: l3int.dtx Copyright (C) 1990-2011 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 "expl3 bundle" (The Work in LPPL)
+%% and all files in that bundle must be distributed together.
+%%
+%% The released version of this bundle is available from CTAN.
+%%
+%% -----------------------------------------------------------------------
+%%
+%% The development version of the bundle can be found at
+%%
+%% http://www.latex-project.org/svnroot/experimental/trunk/
+%%
+%% for those people who are interested.
+%%
+%%%%%%%%%%%
+%% NOTE: %%
+%%%%%%%%%%%
+%%
+%% Snapshots taken from the repository represent work in progress and may
+%% not work or may contain conflicting material! We therefore ask
+%% people _not_ to put them into distributions, archives, etc. without
+%% prior consultation with the LaTeX3 Project.
+%%
+%% -----------------------------------------------------------------------
+%
+%<*driver|package>
+\RequirePackage{l3names}
+\GetIdInfo$Id: l3int.dtx 2478 2011-06-19 21:34:23Z joseph $
+ {L3 Experimental integers}
+%</driver|package>
+%<*driver>
+\documentclass[full]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3int} package\\ Integers^^A
+% \thanks{This file describes v\ExplFileVersion,
+% last revised \ExplFileDate.}^^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 \ExplFileDate}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% Calculation and comparison of integer values can be carried out
+% using literal numbers, \texttt{int} registers, constants and
+% integers stored in token list variables. The standard operators
+% \texttt{+}, \texttt{-}, \texttt{/} and \texttt{*} and
+% parentheses can be used within such expressions to carry
+% arithmetic operations. This module carries out these functions
+% on \emph{integer expressions} (\enquote{\texttt{int expr}}).
+%
+% \section{Integer expressions}
+%
+% \begin{function}[EXP]{\int_eval:n}
+% \begin{syntax}
+% \cs{int_eval:n} \Arg{integer expression}
+% \end{syntax}
+% Evaluates the \meta{integer expression}, expanding any
+% integer and token list variables within the \meta{expression}
+% to their content (without requiring \cs{int_use:N}/\cs{tl_use:N})
+% and applying the standard mathematical rules. For example both
+% \begin{verbatim}
+% \int_eval:n { 5 + 4 * 3 - ( 3 + 4 * 5 ) }
+% \end{verbatim}
+% and
+% \begin{verbatim}
+% \tl_new:N \l_my_tl
+% \tl_set:Nn \l_my_tl { 5 }
+% \int_new:N \l_my_int
+% \int\set:Nn \l_my_int { 4 }
+% \int_eval:n { \l_my_tl + \l_my_int * 3 - ( 3 + 4 * 5 ) }
+% \end{verbatim}
+% both evaluate to \( -6 \). The \Arg{integer expression} may
+% contain the operators \texttt{+}, \texttt{-}, \texttt{*} and
+% \texttt{/}, along with parenthesis \texttt{(} and \texttt{)}.
+% After two expansions, \cs{int_eval:n} yields a
+% \meta{integer denotation} which is left in the input stream. This is
+% \emph{not} an \meta{internal integer}, and therefore requires
+% suitable termination if used in a \TeX{}-style integer assignment.
+% \end{function}
+%
+% \begin{function}[EXP]{\int_abs:n}
+% \begin{syntax}
+% \cs{int_abs:n} \Arg{integer expression}
+% \end{syntax}
+% Evaluates the \meta{integer expression} as described for
+% \cs{int_eval:n} and leaves the absolute value of the result in
+% the input stream as an \meta{integer denotation} after two
+% expansions.
+% \end{function}
+%
+% \begin{function}[EXP]{\int_div_round:nn}
+% \begin{syntax}
+% \cs{int_div_round:nn} \Arg{intexpr1} \Arg{intexpr2}
+% \end{syntax}
+% Evaluates the two \meta{integer expressions} as described earlier,
+% then calculates the result of dividing the first value by the
+% second, round any remainder. Note that this is identical to using
+% |/| directly in an \meta{integer expression}. The result is left in
+% the input stream as a \meta{integer denotation} after two expansions.
+% \end{function}
+%
+% \begin{function}[EXP]{\int_div_truncate:nn}
+% \begin{syntax}
+% \cs{int_div_truncate:nn} \Arg{intexpr1} \Arg{intexpr2}
+% \end{syntax}
+% Evaluates the two \meta{integer expressions} as described earlier,
+% then calculates the result of dividing the first value by the
+% second, truncating any remainder. Note that division using |/|
+% rounds the result. The result is left in the input stream as a
+% \meta{integer denotation} after two expansions.
+% \end{function}
+%
+% \begin{function}[EXP]{\int_max:nn, \int_min:nn}
+% \begin{syntax}
+% \cs{int_max:nn} \Arg{intexpr1} \Arg{intexpr2}
+% \cs{int_min:nn} \Arg{intexpr1} \Arg{intexpr2}
+% \end{syntax}
+% Evaluates the \meta{integer expressions} as described for
+% \cs{int_eval:n} and leaves either the larger or smaller value
+% in the input stream as an \meta{integer denotation} after two
+% expansions.
+% \end{function}
+%
+% \begin{function}[EXP]{\int_mod:nn}
+% \begin{syntax}
+% \cs{int_mod:nn} \Arg{intexpr1} \Arg{intexpr2}
+% \end{syntax}
+% Evaluates the two \meta{integer expressions} as described earlier,
+% then calculates the integer remainder of dividing the first
+% expression by the second. This is left in the input stream as an
+% \meta{integer denotation} after two expansions.
+% \end{function}
+%
+% \section{Creating and initialising integers}
+%
+% \begin{function}{\int_new:N, \int_new:c}
+% \begin{syntax}
+% \cs{int_new:N} \meta{integer}
+% \end{syntax}
+% Creates a new \meta{integer} or raises an error if the name is
+% already taken. The declaration is global. The \meta{integer} will
+% initially be equal to $0$.
+% \end{function}
+%
+% \begin{function}{\int_const:Nn, \int_const:cn}
+% \begin{syntax}
+% \cs{int_const:Nn} \meta{integer} \Arg{integer expression}
+% \end{syntax}
+% Creates a new constant \meta{integer} or raises an error if the name
+% is already taken. The value of the \meta{integer} will be set
+% globally to the \meta{integer expression}.
+% \end{function}
+%
+% \begin{function}{\int_zero:N, \int_zero:c}
+% \begin{syntax}
+% \cs{int_zero:N} \meta{integer}
+% \end{syntax}
+% Sets \meta{integer} to $0$ within the scope of the current \TeX{} group.
+% \end{function}
+%
+% \begin{function}{\int_gzero:N, \int_gzero:c}
+% \begin{syntax}
+% \cs{int_gzero:N} \meta{integer}
+% \end{syntax}
+% Sets \meta{integer} to $0$ globally, \emph{i.e.}~not
+% restricted by the current \TeX{} group level.
+% \end{function}
+%
+% \begin{function}
+% {\int_set_eq:NN, \int_set_eq:cN, \int_set_eq:Nc, \int_set_eq:cc}
+% \begin{syntax}
+% \cs{int_set_eq:NN} \meta{integer1} \meta{integer2}
+% \end{syntax}
+% Sets the content of \meta{integer1} equal to that of
+% \meta{integer2}. This assignment is restricted to the current
+% \TeX{} group level.
+% \end{function}
+%
+% \begin{function}
+% {\int_gset_eq:NN, \int_gset_eq:cN, \int_gset_eq:Nc, \int_gset_eq:cc}
+% \begin{syntax}
+% \cs{int_gset_eq:NN} \meta{integer1} \meta{integer2}
+% \end{syntax}
+% Sets the content of \meta{integer1} equal to that of \meta{integer2}.
+% This assignment is global and so is not limited by the current
+% \TeX{} group level.
+% \end{function}
+%
+% \section{Setting and incrementing integers}
+%
+% \begin{function}{\int_add:Nn, \int_add:cn}
+% \begin{syntax}
+% \cs{int_add:Nn} \meta{integer} \Arg{integer expression}
+% \end{syntax}
+% Adds the result of the \meta{integer expression} to the current
+% content of the \meta{integer}. This assignment is local.
+% \end{function}
+%
+% \begin{function}{\int_gadd:Nn, \int_gadd:cn}
+% \begin{syntax}
+% \cs{int_gadd:Nn} \meta{integer} \Arg{integer expression}
+% \end{syntax}
+% Adds the result of the \meta{integer expression} to the current
+% content of the \meta{integer}. This assignment is global.
+% \end{function}
+%
+% \begin{function}{\int_decr:N, \int_decr:c}
+% \begin{syntax}
+% \cs{int_decr:N} \meta{integer}
+% \end{syntax}
+% Decreases the value stored in \meta{integer} by $1$ within
+% the scope of the current \TeX{} group.
+% \end{function}
+%
+% \begin{function}{\int_gdecr:N, \int_gdecr:c}
+% \begin{syntax}
+% \cs{int_incr:N} \meta{integer}
+% \end{syntax}
+% Decreases the value stored in \meta{integer} by $1$ globally
+% (\emph{i.e.}~not limited by the current group level).
+% \end{function}
+%
+% \begin{function}{\int_incr:N, \int_incr:c}
+% \begin{syntax}
+% \cs{int_incr:N} \meta{integer}
+% \end{syntax}
+% Increases the value stored in \meta{integer} by $1$ within
+% the scope of the current \TeX{} group.
+% \end{function}
+%
+% \begin{function}{\int_gincr:N, \int_gincr:c}
+% \begin{syntax}
+% \cs{int_incr:N} \meta{integer}
+% \end{syntax}
+% Increases the value stored in \meta{integer} by $1$ globally
+% (\emph{i.e.}~not limited by the current group level).
+% \end{function}
+%
+% \begin{function}{\int_set:Nn, \int_set:cn}
+% \begin{syntax}
+% \cs{int_set:Nn} \meta{integer} \Arg{integer expression}
+% \end{syntax}
+% Sets \meta{integer} to the value of \meta{integer expression},
+% which must evaluate to an integer (as described for
+% \cs{int_eval:n}). This assignment is restricted to the
+% current \TeX{} group.
+% \end{function}
+%
+% \begin{function}{\int_gset:Nn, \int_gset:cn}
+% \begin{syntax}
+% \cs{int_gset:Nn} \meta{integer} \Arg{integer expression}
+% \end{syntax}
+% Sets \meta{integer} to the value of \meta{integer expression},
+% which must evaluate to an integer (as described for
+% \cs{int_eval:n}). This assignment is global and is not limited
+% to the current \TeX{} group level.
+% \end{function}
+%
+% \begin{function}{\int_sub:Nn, \int_sub:cn}
+% \begin{syntax}
+% \cs{int_sub:Nn} \meta{integer} \Arg{integer expression}
+% \end{syntax}
+% Subtracts the result of the \meta{integer expression} to the
+% current content of the \meta{integer}. This assignment is local.
+% \end{function}
+%
+% \begin{function}{\int_gsub:Nn, \int_gsub:cn}
+% \begin{syntax}
+% \cs{int_gsub:Nn} \meta{integer} \Arg{integer expression}
+% \end{syntax}
+% Subtracts the result of the \meta{integer expression} to the
+% current content of the \meta{integer}. This assignment is global.
+% \end{function}
+%
+% \section{Using integers}
+%
+% \begin{function}[EXP]{\int_use:N, \int_use:c}
+% \begin{syntax}
+% \cs{int_use:N} \meta{integer}
+% \end{syntax}
+% Recovers the content of a \meta{integer} and places it directly
+% in the input stream. An error will be raised if the variable does
+% not exist or if it is invalid. Can be omitted in places where a
+% \meta{integer} is required (such as in the first and third arguments
+% of \cs{int_compare:nNnTF}).
+% \begin{texnote}
+% \cs{int_use:N} is the \TeX{} primitive \cs{the}: this is one of
+% several \LaTeX3 names for this primitive.
+% \end{texnote}
+% \end{function}
+%
+% \section{Integer expression conditionals}
+%
+% \begin{function}[EXP,pTF]{\int_compare:nNn}
+% \begin{syntax}
+% \cs{int_compare_p:nNn}
+% ~~\Arg{intexpr1} \meta{relation} \Arg{intexpr2}
+% \cs{int_compare:nNnTF}
+% ~~\Arg{intexpr1} \meta{relation} \Arg{intexpr2}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% This function first evaluates each of the \meta{integer expressions}
+% as described for \cs{int_eval:n}. The two results are then
+% compared using the \meta{relation}:
+% \begin{center}
+% \begin{tabular}{ll}
+% Equal & |=| \\
+% Greater than & |>| \\
+% Less than & |<| \\
+% \end{tabular}
+% \end{center}
+% The branching versions then leave either \meta{true code} or
+% \meta{false code} in the input stream, as appropriate to the truth
+% of the test and the variant of the function chosen. The logical
+% truth of the test is left in the input stream by the predicate
+% version.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\int_compare:n}
+% \begin{syntax}
+% \cs{int_compare_p:n}
+% ~~\{ \meta{intexpr1} \meta{relation} \meta{intexpr2} \}
+% \cs{int_compare:nTF}
+% ~~\{ \meta{intexpr1} \meta{relation} \meta{intexpr2} \}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% This function first evaluates each of the \meta{integer expressions}
+% as described for \cs{int_eval:n}. The two results are then
+% compared using the \meta{relation}:
+% \begin{center}
+% \begin{tabular}{ll}
+% Equal & |=| or |==| \\
+% Greater than or equal to & |=>| \\
+% Greater than & |>| \\
+% Less than or equal to & |=<| \\
+% Less than & |<| \\
+% Not equal & |!=| \\
+% \end{tabular}
+% \end{center}
+% The branching versions then leave either \meta{true code} or
+% \meta{false code} in the input stream, as appropriate to the truth
+% of the test and the variant of the function chosen. The logical
+% truth of the test is left in the input stream by the predicate
+% version.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\int_if_even:n, \int_if_odd:n}
+% \begin{syntax}
+% \cs{int_if_odd_p:n} \Arg{integer expression}
+% \cs{int_if_odd:nTF} \Arg{integer expression}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% This function first evaluates the \meta{integer expression}
+% as described for \cs{int_eval:n}. It then evaluates if this
+% is odd or even, as appropriate. The branching versions then leave
+% either \meta{true code} or \meta{false code} in the input stream,
+% as appropriate to the truth of the test and the variant of the
+% function chosen. The logical truth of the test is left in the input
+% stream by the predicate version.
+% \end{function}
+%
+% \section{Integer expression loops}
+%
+% \begin{function}[EXP]{\int_do_while:nNnn}
+% \begin{syntax}
+% \cs{int_do_while:nNnn}
+% ~~\Arg{intexpr1} \meta{relation} \Arg{intexpr2} \Arg{code}
+% \end{syntax}
+% Evaluates the relationship between the two \meta{integer expressions}
+% as described for \cs{int_compare:nNnTF}, and then places the
+% \meta{code} in the input stream if the \meta{relation} is
+% \texttt{true}. After the \meta{code} has been processed by \TeX{} the
+% test will be repeated, and a loop will occur until the test is
+% \texttt{false}.
+% \end{function}
+%
+% \begin{function}[EXP]{\int_do_until:nNnn}
+% \begin{syntax}
+% \cs{int_do_until:nNnn}
+% ~~\Arg{intexpr1} \meta{relation} \Arg{intexpr2} \Arg{code}
+% \end{syntax}
+% Evaluates the relationship between the two \meta{integer expressions}
+% as described for \cs{int_compare:nNnTF}, and then places the
+% \meta{code} in the input stream if the \meta{relation} is
+% \texttt{false}. After the \meta{code} has been processed by \TeX{} the
+% test will be repeated, and a loop will occur until the test is
+% \texttt{true}.
+% \end{function}
+%
+% \begin{function}[EXP]{\int_until_do:nNnn}
+% \begin{syntax}
+% \cs{int_until_do:nNnn}
+% ~~\Arg{intexpr1} \meta{relation} \Arg{intexpr2} \Arg{code}
+% \end{syntax}
+% Places the \meta{code} in the input stream for \TeX{} to process, and
+% then evaluates the relationship between the two
+% \meta{integer expressions} as described for \cs{int_compare:nNnTF}.
+% If the test is \texttt{false} then the \meta{code} will be inserted
+% into the input stream again and a loop will occur until the
+% \meta{relation} is \texttt{true}.
+% \end{function}
+%
+% \begin{function}[EXP]{\int_while_do:nNnn}
+% \begin{syntax}
+% \cs{int_while_do:nNnn} \
+% ~~\Arg{intexpr1} \meta{relation} \Arg{intexpr2} \Arg{code}
+% \end{syntax}
+% Places the \meta{code} in the input stream for \TeX{} to process, and
+% then evaluates the relationship between the two
+% \meta{integer expressions} as described for \cs{int_compare:nNnTF}.
+% If the test is \texttt{true} then the \meta{code} will be inserted
+% into the input stream again and a loop will occur until the
+% \meta{relation} is \texttt{false}.
+% \end{function}
+%
+% \begin{function}[EXP]{\int_do_while:nn}
+% \begin{syntax}
+% \cs{int_do_while:nNnn}
+% ~~\{ \meta{intexpr1} \meta{relation} \meta{intexpr2} \} \Arg{code}
+% \end{syntax}
+% Evaluates the relationship between the two \meta{integer expressions}
+% as described for \cs{int_compare:nTF}, and then places the
+% \meta{code} in the input stream if the \meta{relation} is
+% \texttt{true}. After the \meta{code} has been processed by \TeX{} the
+% test will be repeated, and a loop will occur until the test is
+% \texttt{false}.
+% \end{function}
+%
+% \begin{function}[EXP]{\int_do_until:nn}
+% \begin{syntax}
+% \cs{int_do_until:nn}
+% ~~\{ \meta{intexpr1} \meta{relation} \meta{intexpr2} \} \Arg{code}
+% \end{syntax}
+% Evaluates the relationship between the two \meta{integer expressions}
+% as described for \cs{int_compare:nTF}, and then places the
+% \meta{code} in the input stream if the \meta{relation} is
+% \texttt{false}. After the \meta{code} has been processed by \TeX{} the
+% test will be repeated, and a loop will occur until the test is
+% \texttt{true}.
+% \end{function}
+%
+% \begin{function}[EXP]{\int_until_do:nn}
+% \begin{syntax}
+% \cs{int_until_do:nn}
+% ~~\{ \meta{intexpr1} \meta{relation} \meta{intexpr2} \} \Arg{code}
+% \end{syntax}
+% Places the \meta{code} in the input stream for \TeX\ to process, and
+% then evaluates the relationship between the two
+% \meta{integer expressions} as described for \cs{int_compare:nTF}.
+% If the test is \texttt{false} then the \meta{code} will be inserted
+% into the input stream again and a loop will occur until the
+% \meta{relation} is \texttt{true}.
+% \end{function}
+%
+% \begin{function}[EXP]{\int_while_do:nn}
+% \begin{syntax}
+% \cs{int_while_do:nn} \
+% ~~\{ \meta{intexpr1} \meta{relation} \meta{intexpr2} \} \Arg{code}
+% \end{syntax}
+% Places the \meta{code} in the input stream for \TeX{} to process, and
+% then evaluates the relationship between the two
+% \meta{integer expressions} as described for \cs{int_compare:nTF}.
+% If the test is \texttt{true} then the \meta{code} will be inserted
+% into the input stream again and a loop will occur until the
+% \meta{relation} is \texttt{false}.
+% \end{function}
+%
+% \section{Formatting integers}
+%
+% Integers can be placed into the output stream with formatting. These
+% conversions apply to any integer expressions.
+%
+% \begin{function}[EXP]{\int_to_arabic:n}
+% \begin{syntax}
+% \cs{int_to_arabic:n} \Arg{integer expression}
+% \end{syntax}
+% Places the value of the \meta{integer expression} in the input
+% stream as digits, with category code $12$ (other).
+% \end{function}
+%
+% \begin{function}[EXP]{\int_to_alph:n, \int_to_Alph:n}
+% \begin{syntax}
+% \cs{int_to_alph:n} \Arg{integer expression}
+% \end{syntax}
+% Evaluates the \meta{integer expression} and converts the result
+% into a series of letters, which are then left in the input stream.
+% The conversion rule uses the $26$ letters of the English
+% alphabet, in order. Thus
+% \begin{verbatim}
+% \int_to_alph:n { 1 }
+% \end{verbatim}
+% places |a| in the input stream,
+% \begin{verbatim}
+% \int_to_alph:n { 26 }
+% \end{verbatim}
+% is represented as |z| and
+% \begin{verbatim}
+% \int_to_alph:n { 27 }
+% \end{verbatim}
+% is converted to |aa|. For conversions using other alphabets, use
+% \cs{int_convert_to_symbols:nnn} to define an alphabet-specific
+% function. The basic \cs{int_to_alph:n} and \cs{int_to_Alph:n}
+% functions should not be modified.
+% \end{function}
+%
+% \begin{function}[EXP]{\int_to_symbols:nnn}
+% \begin{syntax}
+% \cs{int_to_symbols:nnn}
+% ~~\Arg{integer expression} \Arg{total symbols}
+% ~~\meta{value to symbol mapping}
+% \end{syntax}
+% This is the low-level function for conversion of an
+% \meta{integer expression} into a symbolic form (which will often
+% be letters). The \meta{total symbols} available should be given
+% as an integer expression. Values are actually converted to symbols
+% according to the \meta{value to symbol mapping}. This should be given
+% as \meta{total symbols} pairs of entries, a number and the
+% appropriate symbol. Thus the \cs{int_to_alph:n} function is defined
+% as
+% \begin{verbatim}
+% \cs_new:Npn \int_to_alph:n #1
+% {
+% \int_convert_to_sybols:nnn {#1} { 26 }
+% {
+% { 1 } { a }
+% { 2 } { b }
+% { 3 } { c }
+% { 4 } { d }
+% { 5 } { e }
+% { 6 } { f }
+% { 7 } { g }
+% { 8 } { h }
+% { 9 } { i }
+% { 10 } { j }
+% { 11 } { k }
+% { 12 } { l }
+% { 13 } { m }
+% { 14 } { n }
+% { 15 } { o }
+% { 16 } { p }
+% { 17 } { q }
+% { 18 } { r }
+% { 19 } { s }
+% { 20 } { t }
+% { 21 } { u }
+% { 22 } { v }
+% { 23 } { w }
+% { 24 } { x }
+% { 25 } { y }
+% { 26 } { z }
+% }
+% }
+% \end{verbatim}
+% \end{function}
+%
+% \begin{function}[EXP]{\int_to_binary:n}
+% \begin{syntax}
+% \cs{int_to_binary:n} \Arg{integer expression}
+% \end{syntax}
+% Calculates the value of the \meta{integer expression} and places
+% the binary representation of the result in the input stream.
+% \end{function}
+%
+% \begin{function}[EXP]{\int_to_hexadecimal:n}
+% \begin{syntax}
+% \cs{int_to_binary:n} \Arg{integer expression}
+% \end{syntax}
+% Calculates the value of the \meta{integer expression} and places
+% the hexadecimal (base~$16$) representation of the result in the
+% input stream. Upper case letters are used for digits beyond $9$.
+% \end{function}
+%
+% \begin{function}[EXP]{\int_to_octal:n}
+% \begin{syntax}
+% \cs{int_to_octal:n} \Arg{integer expression}
+% \end{syntax}
+% Calculates the value of the \meta{integer expression} and places
+% the octal (base~$8$) representation of the result in the input
+% stream.
+% \end{function}
+%
+% \begin{function}[EXP]{\int_to_base:nn}
+% \begin{syntax}
+% \cs{int_to_base:nn} \Arg{integer expression} \Arg{base}
+% \end{syntax}
+% Calculates the value of the \meta{integer expression} and
+% converts it into the appropriate representation in the \meta{base};
+% the later may be given as an integer expression. For bases greater
+% than $10$ the higher \enquote{digits} are represented by the upper case
+% letters from the English alphabet.
+% The maximum \meta{base} value is $36$.
+% \begin{texnote}
+% This is a generic version of \cs{int_to_binary:n}, \emph{etc.}
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[EXP]{\int_to_roman:n, \int_to_Roman:n}
+% \begin{syntax}
+% \cs{int_to_roman:n} \Arg{integer expression}
+% \end{syntax}
+% Places the value of the \meta{integer expression} in the input
+% stream as Roman numerals, either lower case (\cs{int_to_roman:n})
+% or upper case (\cs{int_to_Roman:n}). The Roman numerals are letters
+% with category code $11$ (letter).
+% \end{function}
+%
+% \begin{function}[EXP]{\int_to_symbol:n}
+% \begin{syntax}
+% \cs{int_to_symbol:n} \Arg{integer expression}
+% \end{syntax}
+% Calculates the value of the \meta{integer expression} and places
+% the symbol representation of the result in the input stream. The
+% list of symbols used is equivalent to \LaTeXe{}'s \cs{@fnsymbol}
+% set.
+% \end{function}
+%
+% \section{Converting from other formats to integers}
+%
+% \begin{function}[EXP]{\int_from_alph:n}
+% \begin{syntax}
+% \cs{int_from_alpa:n} \Arg{letters}
+% \end{syntax}
+% Converts the \meta{letters} into the integer (base~$10$)
+% representation and leaves this in the input stream. The
+% \meta{letters} are treated using the English alphabet only, with
+% \enquote{a} equal to $1$ through to \enquote{z} equal to $26$. Either lower
+% or upper case letters may be used. This is the inverse function of
+% \cs{int_to_alph:n}.
+% \end{function}
+%
+% \begin{function}[EXP]{\int_from_binary:n}
+% \begin{syntax}
+% \cs{int_from_binary:n} \Arg{binary number}
+% \end{syntax}
+% Converts the \meta{binary number} into the integer (base~$10$)
+% representation and leaves this in the input stream.
+% \end{function}
+%
+% \begin{function}[EXP]{\int_from_hexadecimal:n}
+% \begin{syntax}
+% \cs{int_from_binary:n} \Arg{hexadecimal number}
+% \end{syntax}
+% Converts the \meta{hexadecimal number} into the integer
+% (base~$10$) representation and leaves this in the input stream.
+% Digits greater than $9$ may be represented in the
+% \meta{hexadecimal number} by upper or lower case letters.
+% \end{function}
+%
+% \begin{function}[EXP]{\int_from_octal:n}
+% \begin{syntax}
+% \cs{int_from_octal:n} \Arg{octal number}
+% \end{syntax}
+% Converts the \meta{octal number} into the integer (base~$10$)
+% representation and leaves this in the input stream.
+% \end{function}
+%
+% \begin{function}[EXP]{\int_from_roman:n}
+% \begin{syntax}
+% \cs{int_from_roman:n} \Arg{roman numeral}
+% \end{syntax}
+% Converts the \meta{roman numeral} into the integer (base~$10$)
+% representation and leaves this in the input stream. The
+% \meta{roman numeral} may be in upper or lower case; if the numeral
+% is not valid then the resulting value will be $-1$.
+% \end{function}
+%
+% \begin{function}[EXP]{\int_from_base:nn}
+% \begin{syntax}
+% \cs{int_from_base:nn} \Arg{number}
+% ~~\Arg{base}
+% \end{syntax}
+% Converts the \meta{number} in \meta{base} into the appropriate
+% value in base $10$. The \meta{number} should consist of
+% digits and letters (either lower or upper case), plus optionally
+% a leading sign. The maximum \meta{base} value is $36$.
+% \end{function}
+%
+% \section{Viewing integers}
+%
+% \begin{function}{\int_show:N, \int_show:c}
+% \begin{syntax}
+% \cs{int_show:N} \meta{integer}
+% \end{syntax}
+% Displays the value of the \meta{integer} on the terminal.
+% \end{function}
+%
+% \section{Constant integers}
+%
+% \begin{variable}
+% {
+% \c_minus_one ,
+% \c_zero ,
+% \c_one ,
+% \c_two ,
+% \c_three ,
+% \c_four ,
+% \c_five ,
+% \c_six ,
+% \c_seven ,
+% \c_eight ,
+% \c_nine ,
+% \c_ten ,
+% \c_eleven ,
+% \c_twelve ,
+% \c_thirteen ,
+% \c_fourteen ,
+% \c_fifteen ,
+% \c_sixteen ,
+% \c_thirty_two ,
+% \c_one_hundred ,
+% \c_two_hundred_fifty_five ,
+% \c_two_hundred_fifty_six ,
+% \c_one_thousand ,
+% \c_ten_thousand
+% }
+% Integer values used with primitive tests and assignments:
+% self-terminating nature makes these more convenient and faster than
+% literal numbers.
+% \end{variable}
+%
+% \begin{variable}{\c_max_int}
+% The maximum value that can be stored as an integer.
+% \end{variable}
+%
+% \begin{variable}{\c_max_register_int}
+% Maximum number of registers.
+% \end{variable}
+%
+% \section{Scratch integers}
+%
+% \begin{variable}{\l_tmpa_int, \l_tmpb_int, \l_tmpc_int}
+% Scratch integer for local assignment. These are never used by
+% the kernel code, and so are safe for use with any \LaTeX3-defined
+% function. However, they may be overwritten by other non-kernel
+% code and so should only be used for short-term storage.
+% \end{variable}
+%
+% \begin{variable}{\g_tmpa_int, \g_tmpb_int}
+% Scratch integer for global assignment. These are never used by
+% the kernel code, and so are safe for use with any \LaTeX3-defined
+% function. However, they may be overwritten by other non-kernel
+% code and so should only be used for short-term storage.
+% \end{variable}
+%
+% \section{Internal functions}
+%
+% \begin{function}[EXP]{int_get_digits:n}
+% \begin{syntax}
+% \cs{int_get_digits:n} \meta{value}
+% \end{syntax}
+% Parses the \meta{value} to leave the absolute \meta{value}
+% in the input stream. This may therefore be used
+% to remove multiple sign tokens from the \meta{value}
+% (which may be symbolic).
+% \end{function}
+%
+% \begin{function}[EXP]{int_get_sign:n}
+% \begin{syntax}
+% \cs{int_get_sign:n} \meta{value}
+% \end{syntax}
+% Parses the \meta{value} to leave a single sign token
+% (either |+| or |-|) in the input stream. This may therefore be used
+% to sanitise sign tokens from the \meta{value} (which may be symbolic).
+% \end{function}
+%
+% \begin{function}[EXP]{int_to_letter:n}
+% \begin{syntax}
+% \cs{int_to_letter:n} \meta{integer value}
+% \end{syntax}
+% For \meta{integer values} from $0$ to $9$, leaves the \meta{value}
+% in the input stream unchanged. For \meta{integer values} from
+% $10$ to $35$, leaves the appropriate upper case letter (from the
+% standard English alphabet) in the input stream: for example,
+% $10$ is converted to |A|, $11$ to |B|, \emph{etc.}
+% \end{function}
+%
+% \begin{function}[EXP]{\int_to_roman:w}
+% \begin{syntax}
+% \cs{int_to_roman:w} \meta{integer}
+% ~~\meta{space} \textit{or} \meta{non-expandable token}
+% \end{syntax}
+% Converts \meta{integer} to it lower case Roman representation. Expansion
+% ends when a space or non-expandable token is found.
+% Note that this function produces a string of letters with category code
+% $12$ and that protected functions \emph{are} expanded by this
+% process. Negative \meta{integer} values result in no output, although
+% the function does not terminate expansion until a suitable endpoint
+% is found in the same way as for positive numbers.
+% \begin{texnote}
+% This is the \TeX{} primitive \tn{romannumeral} renamed.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[EXP]{\if_num:w, \if_int_compare:w}
+% \begin{syntax}
+% \cs{if_num:w} \meta{integer1} \meta{relation} \meta{integer2}
+% ~~\meta{true code}
+% \cs{else:}
+% ~~\meta{false code}
+% \cs{fi:}
+% \end{syntax}
+% Compare two integers using \meta{relation}, which must be one of
+% |=|, |<| or |>| with category code $12$.
+% The \cs{else:} branch is optional.
+% \begin{texnote}
+% These are both names for the \TeX{} primitive \cs{ifnum}.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[EXP]{\if_case:w, \or:}
+% \begin{syntax}
+% \cs{if_case:w} \meta{integer} \meta{case0}
+% ~~\cs{or:} \meta{case1}
+% ~~\cs{or:} |...|
+% ~~\cs{else:} \meta{default}
+% \cs{fi:}
+% \end{syntax}
+% Selects a case to execute based on the value of the \meta{integer}. The
+% first case (\meta{case0}) is executed if \meta{integer} is $0$, the second
+% (\meta{case1}) if the \meta{integer} is $1$, \emph{etc.} The
+% \meta{integer} may be a literal, a constant or an integer
+% expression (\emph{e.g.}~using \cs{int_eval:n}).
+% \begin{texnote}
+% These are the \TeX{} primitives \cs{ifcase} and \cs{or}.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[EXP]{\int_value:w}
+% \begin{syntax}
+% \cs{int_value:w} \meta{integer}
+% \cs{int_value:w} \meta{tokens} \meta{optional space}
+% \end{syntax}
+% Expands \meta{tokens} until an \meta{integer} is formed. One space may be
+% gobbled in the process.
+% \begin{texnote}
+% This is the \TeX{} primitive \cs{number}.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[EXP]{\int_eval:w, \int_eval_end:}
+% \begin{syntax}
+% \cs{int_eval:w} \meta{intexpr} \cs{int_eval_end:}
+% \end{syntax}
+% Evaluates \meta{integer expression} as described for \cs{int_eval:n}.
+% The evaluation stops when an unexpandable token which is not a valid
+% part of an integer is read or when \cs{int_eval_end:} is
+% reached. The latter is gobbled by the scanner mechanism:
+% \cs{int_eval_end:} itself is unexpandable but used correctly
+% the entire construct is expandable.
+% \begin{texnote}
+% This is the \eTeX{} primitive \cs{numexpr}.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[EXP]{\if_int_odd:w}
+% \begin{syntax}
+% \cs{if_int_odd:w} \meta{tokens} \meta{optional space}
+% ~~\meta{true code}
+% \cs{else:}
+% ~~\meta{true code}
+% \cs{fi:}
+% \end{syntax}
+% Expands \meta{tokens} until a non-numeric token or a space is found, and
+% tests whether the resulting \meta{integer} is odd. If so, \meta{true code}
+% is executed. The \cs{else:} branch is optional.
+% \begin{texnote}
+% This is the \TeX{} primitive \cs{ifodd}.
+% \end{texnote}
+% \end{function}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3int} implementation}
+%
+% \begin{macrocode}
+%<*initex|package>
+% \end{macrocode}
+%
+% \TestFiles{m3int001,m3int002,m3int03}
+%
+% \begin{macrocode}
+%<*package>
+\ProvidesExplPackage
+ {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
+\package_check_loaded_expl:
+%</package>
+% \end{macrocode}
+%
+% \begin{macro}{\int_to_roman:w}
+% \begin{macro}{\if_int_compare:w}
+% Done in \pkg{l3basics}.
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\int_value:w}
+% \begin{macro}{\int_eval:w}
+% \begin{macro}{\int_eval_end:}
+% \begin{macro}{\if_num:w}
+% \begin{macro}{\if_int_odd:w}
+% \begin{macro}{\if_case:w}
+% Here are the remaining primitives for number comparisons and
+% expressions.
+% \begin{macrocode}
+\cs_set_eq:NN \int_value:w \tex_number:D
+\cs_set_eq:NN \int_eval:w \etex_numexpr:D
+\cs_new_eq:NN \int_eval_end: \tex_relax:D
+\cs_new_eq:NN \if_num:w \tex_ifnum:D
+\cs_set_eq:NN \if_int_odd:w \tex_ifodd:D
+\cs_new_eq:NN \if_case:w \tex_ifcase:D
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Integer expressions}
+%
+% \begin{macro}{\int_eval:n}
+% Wrapper for \cs{int_eval:w}. Can be used in an integer expression
+% or directly in the input stream.
+% \begin{macrocode}
+\cs_new:Npn \int_eval:n #1
+ { \int_value:w \int_eval:w #1 \int_eval_end: }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\int_max:nn}
+% \UnitTested
+% \begin{macro}{\int_min:nn}
+% \UnitTested
+% \begin{macro}{\int_abs:n}
+% \UnitTested
+% Functions for $\min$, $\max$, and absolute value.
+% \begin{macrocode}
+\cs_new:Npn \int_abs:n #1
+ {
+ \int_value:w
+ \if_int_compare:w \int_eval:w #1 < \c_zero
+ -
+ \fi:
+ \int_eval:w #1 \int_eval_end:
+ }
+\cs_new:Npn \int_max:nn #1#2
+ {
+ \int_value:w \int_eval:w
+ \if_int_compare:w
+ \int_eval:w #1 > \int_eval:w #2 \int_eval_end:
+ #1
+ \else:
+ #2
+ \fi:
+ \int_eval_end:
+ }
+\cs_new:Npn \int_min:nn #1#2
+ {
+ \int_value:w \int_eval:w
+ \if_int_compare:w
+ \int_eval:w #1 < \int_eval:w #2 \int_eval_end:
+ #1
+ \else:
+ #2
+ \fi:
+ \int_eval_end:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\int_div_truncate:nn}
+% \UnitTested
+% \begin{macro}{\int_div_round:nn}
+% \UnitTested
+% \begin{macro}{\int_mod:nn}
+% \UnitTested
+% As \cs{int_eval:w} rounds the result of a division we also
+% provide a version that truncates the result. This version is thanks
+% to Heiko Oberdiek: getting things right in all cases is not so easy.
+% \begin{macrocode}
+\cs_new:Npn \int_div_truncate:nn #1#2
+ {
+ \int_value:w \int_eval:w
+ \if_int_compare:w \int_eval:w #1 = \c_zero
+ 0
+ \else:
+ ( #1 % )
+ \if_int_compare:w \int_eval:w #1 < \c_zero
+ \if_int_compare:w \int_eval:w #2 < \c_zero
+ - ( #2 + % )
+ \else:
+ + ( #2 - % )
+ \fi:
+ \else:
+ \if_int_compare:w \int_eval:w #2 < \c_zero
+ + ( #2 + % )
+ \else:
+ - ( #2 - % )
+ \fi:
+ \fi: % ( (
+ 1 ) / 2 )
+ \fi:
+ / ( #2 )
+ \int_eval_end:
+ }
+% \end{macrocode}
+% For the sake of completeness:
+% \begin{macrocode}
+\cs_new:Npn \int_div_round:nn #1#2 { \int_eval:n { ( #1 ) / ( #2 ) } }
+% \end{macrocode}
+% Finally there's the modulus operation.
+% \begin{macrocode}
+\cs_new:Npn \int_mod:nn #1#2
+ {
+ \int_value:w \int_eval:w
+ #1 - \int_div_truncate:nn {#1} {#2} * ( #2 )
+ \int_eval_end:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Creating and initialising integers}
+%
+% \begin{macro}{\int_new:N, \int_new:c}
+% \UnitTested
+% Two ways to do this: one for the format and one for the \LaTeXe{}
+% package.
+% \begin{macrocode}
+%<*initex>
+\alloc_new:nnnN { int } { 11 } { \c_max_register_int } \tex_countdef:D
+%</initex>
+%<*package>
+\cs_new_protected_nopar:Npn \int_new:N #1
+ {
+ \chk_if_free_cs:N #1
+ \newcount #1
+ }
+%</package>
+\cs_generate_variant:Nn \int_new:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\int_const:Nn, \int_const:cn}
+% \UnitTested
+% As stated, most constants can be defined as \cs{tex_chardef:D} or
+% \cs{tex_mathchardef:D} but that's engine dependent.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \int_const:Nn #1#2
+ {
+ \int_compare:nNnTF {#2} > \c_minus_one
+ {
+ \int_compare:nNnTF {#2} > \c_max_register_int
+ {
+ \int_new:N #1
+ \int_gset:Nn #1 {#2}
+ }
+ {
+ \chk_if_free_cs:N #1
+ \pref_global:D \tex_mathchardef:D #1 =
+ \int_eval:w #2 \int_eval_end:
+ }
+ }
+ {
+ \int_new:N #1
+ \int_gset:Nn #1 {#2}
+ }
+ }
+\cs_generate_variant:Nn \int_const:Nn { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\int_zero:N, \int_zero:c}
+% \UnitTested
+% \begin{macro}{\int_gzero:N, \int_gzero:c}
+% \UnitTested
+% Functions that reset an \meta{integer} register to zero.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \int_zero:N #1 { #1 = \c_zero }
+\cs_new_protected_nopar:Npn \int_gzero:N #1 { \pref_global:D #1 = \c_zero }
+\cs_generate_variant:Nn \int_zero:N { c }
+\cs_generate_variant:Nn \int_gzero:N { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\int_set_eq:NN,\int_set_eq:cN, \int_set_eq:Nc,\int_set_eq:cc}
+% \UnitTested
+% \begin{macro}
+% {\int_gset_eq:NN,\int_gset_eq:cN, \int_gset_eq:Nc,\int_gset_eq:cc}
+% \UnitTested
+% Setting equal means using one integer inside the set function of
+% another.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \int_set_eq:NN #1#2 { #1 = #2 }
+\cs_generate_variant:Nn \int_set_eq:NN { c }
+\cs_generate_variant:Nn \int_set_eq:NN { Nc , cc }
+\cs_new_protected_nopar:Npn \int_gset_eq:NN #1#2 { \pref_global:D #1 = #2 }
+\cs_generate_variant:Nn \int_gset_eq:NN { c }
+\cs_generate_variant:Nn \int_gset_eq:NN { Nc , cc }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Setting and incrementing integers}
+%
+% \begin{macro}{\int_add:Nn, \int_add:cn}
+% \UnitTested
+% \begin{macro}{\int_gadd:Nn, \int_gadd:cn}
+% \UnitTested
+% \begin{macro}{\int_sub:Nn, \int_sub:cn}
+% \UnitTested
+% \begin{macro}{\int_gsub:Nn, \int_gsub:cn}
+% \UnitTested
+% Adding and subtracting to and from a counter \ldots
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \int_add:Nn #1#2
+ { \tex_advance:D #1 by \int_eval:w #2 \int_eval_end: }
+\cs_new_nopar:Npn \int_sub:Nn #1#2
+ { \tex_advance:D #1 by - \int_eval:w #2 \int_eval_end: }
+\cs_new_protected_nopar:Npn \int_gadd:Nn
+ { \pref_global:D \int_add:Nn }
+\cs_new_protected_nopar:Npn \int_gsub:Nn
+ { \pref_global:D \int_sub:Nn }
+\cs_generate_variant:Nn \int_add:Nn { c }
+\cs_generate_variant:Nn \int_gadd:Nn { c }
+\cs_generate_variant:Nn \int_sub:Nn { c }
+\cs_generate_variant:Nn \int_gsub:Nn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\int_incr:N, \int_incr:c}
+% \UnitTested
+% \begin{macro}{\int_gincr:N, \int_gincr:c}
+% \UnitTested
+% \begin{macro}{\int_decr:N, \int_decr:c}
+% \UnitTested
+% \begin{macro}{\int_gdecr:N, \int_gdecr:c}
+% \UnitTested
+% Incrementing and decrementing of integer registers is done with
+% the following functions.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \int_incr:N #1
+ { \tex_advance:D #1 \c_one }
+\cs_new_protected_nopar:Npn \int_decr:N #1
+ { \tex_advance:D #1 \c_minus_one }
+\cs_new_protected_nopar:Npn \int_gincr:N
+ { \pref_global:D \int_incr:N }
+\cs_new_protected_nopar:Npn \int_gdecr:N
+ { \pref_global:D \int_decr:N }
+\cs_generate_variant:Nn \int_incr:N { c }
+\cs_generate_variant:Nn \int_decr:N { c }
+\cs_generate_variant:Nn \int_gincr:N { c }
+\cs_generate_variant:Nn \int_gdecr:N { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\int_set:Nn, \int_set:cn}
+% \UnitTested
+% \begin{macro}{\int_gset:Nn, \int_gset:cn}
+% \UnitTested
+% As integers are register-based \TeX{} will issue an error
+% if they are not defined. Thus there is no need for the checking
+% code seen with token list variables.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \int_set:Nn #1#2
+ { #1 ~ \int_eval:w #2\int_eval_end: }
+\cs_new_protected_nopar:Npn \int_gset:Nn { \pref_global:D \int_set:Nn }
+\cs_generate_variant:Nn \int_set:Nn { c }
+\cs_generate_variant:Nn \int_gset:Nn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Using integers}
+%
+% \begin{macro}{\int_use:N, \int_use:c}
+% \UnitTested
+% Here is how counters are accessed:
+% \begin{macrocode}
+\cs_new_eq:NN \int_use:N \tex_the:D
+\cs_new_nopar:Npn \int_use:c #1 { \int_use:N \cs:w #1 \cs_end: }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Integer expression conditionals}
+%
+% \begin{macro}[pTF]{\int_compare:n}
+% \begin{macro}[aux]{\int_compare_aux:nw}
+% \begin{macro}[aux]{\int_compare_aux:Nw}
+% \begin{macro}[aux]{int_compare_=:w}
+% \begin{macro}[aux]{int_compare_==:w}
+% \begin{macro}[aux]{int_compare_!=:w}
+% \begin{macro}[aux]{int_compare_<:w}
+% \begin{macro}[aux]{int_compare_>:w}
+% \begin{macro}[aux]{int_compare_<=:w}
+% \begin{macro}[aux]{int_compare_>=:w}
+% Comparison tests using a simple syntax where only one set of braces
+% is required and additional operators such as |!=| and |>=| are
+% supported. First some notes on the idea behind this. We wish to
+% support writing code like
+% \begin{verbatim}
+% \int_compare_p:n { 5 + \l_tmpa_int != 4 - \l_tmpb_int }
+% \end{verbatim}
+% In other words, we want to somehow add the missing \cs{int_eval:w}
+% where required. We can start evaluating from the left using
+% \cs{int_eval:w}, and we know that since the relation symbols |<|, |>|,
+% |=| and |!| are not allowed in such expressions, they will terminate
+% the expression. Therefore, we first let \TeX{} evaluate this left
+% hand side of the (in)equality.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \int_compare:n #1 { p , T , F , TF }
+ { \exp_after:wN \int_compare_aux:nw \int_value:w \int_eval:w #1 \q_stop }
+% \end{macrocode}
+% Then the next step is to figure out which relation we should use, so
+% we have to somehow get rid of the first evaluation so that we can
+% see what stopped it. \cs{int_to_roman:w} is handy here since its
+% expansion given a non-positive number is \meta{null}. We therefore
+% simply check if the first token of the left hand side evaluation is
+% a minus. If not, we insert it and issue \cs{int_to_roman:w},
+% thereby ridding us of the left hand side evaluation. We do however
+% save it for later.
+% \begin{macrocode}
+\cs_new:Npn \int_compare_aux:nw #1#2 \q_stop
+ {
+ \exp_after:wN \int_compare_aux:Nw
+ \int_to_roman:w
+ \if:w #1 -
+ \else:
+ -
+ \fi:
+ #1#2 \q_mark #1#2 \q_stop
+ }
+% \end{macrocode}
+% This leaves the first relation symbol in front and assuming the
+% right hand side has been input, at least one other token as well. We
+% support the following forms: |=|, |<|, |>| and the extended |!=|,
+% |==|, |<=| and |>=|. All the extended forms have an extra |=| so we
+% check if that is present as well. Then use specific function to
+% perform the test.
+% \begin{macrocode}
+\cs_new:Npn \int_compare_aux:Nw #1#2#3 \q_mark
+ { \use:c { int_compare_ #1 \if_meaning:w = #2 = \fi: :w } }
+% \end{macrocode}
+% The actual comparisons are then simple function calls, using the
+% relation as delimiter for a delimited argument.
+% Equality is easy:
+% \begin{macrocode}
+\cs_new:cpn { int_compare_=:w } #1 = #2 \q_stop
+ {
+ \if_int_compare:w #1 = \int_eval:w #2 \int_eval_end:
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+% \end{macrocode}
+% So is the one using |==| we just have to use |==| in the
+% parameter text.
+% \begin{macrocode}
+\cs_new:cpn { int_compare_==:w } #1 == #2 \q_stop
+ {
+ \if_int_compare:w #1 = \int_eval:w #2 \int_eval_end:
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+% \end{macrocode}
+% Not equal is just about reversing the truth value.
+% \begin{macrocode}
+\cs_new:cpn { int_compare_!=:w } #1 != #2 \q_stop
+ {
+ \if_int_compare:w #1 = \int_eval:w #2 \int_eval_end:
+ \prg_return_false:
+ \else:
+ \prg_return_true:
+ \fi:
+ }
+% \end{macrocode}
+% Less than and greater than are also straight forward.
+% \begin{macrocode}
+\cs_new:cpn { int_compare_<:w } #1 < #2 \q_stop
+ {
+ \if_int_compare:w #1 < \int_eval:w #2 \int_eval_end:
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\cs_new:cpn { int_compare_>:w } #1 > #2 \q_stop
+ {
+ \if_int_compare:w #1 > \int_eval:w #2 \int_eval_end:
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+% \end{macrocode}
+% The less than or equal operation is just the opposite of the greater
+% than operation. \emph{Vice versa} for less than or equal.
+% \begin{macrocode}
+\cs_new:cpn { int_compare_<=:w } #1 <= #2 \q_stop
+ {
+ \if_int_compare:w #1 > \int_eval:w #2 \int_eval_end:
+ \prg_return_false:
+ \else:
+ \prg_return_true:
+ \fi:
+ }
+\cs_new:cpn { int_compare_>=:w } #1 >= #2 \q_stop
+ {
+ \if_int_compare:w #1 < \int_eval:w #2 \int_eval_end:
+ \prg_return_false:
+ \else:
+ \prg_return_true:
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\int_compare:nNn}
+% \UnitTested
+% More efficient but less natural in typing.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \int_compare:nNn #1#2#3 { p , T , F , TF}
+ {
+ \if_int_compare:w \int_eval:w #1 #2 \int_eval:w #3 \int_eval_end:
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\int_if_odd:n}
+% \UnitTested
+% \begin{macro}[pTF]{\int_if_even:n}
+% \UnitTested
+% A predicate function.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \int_if_odd:n #1 { p , T , F , TF}
+ {
+ \if_int_odd:w \int_eval:w #1 \int_eval_end:
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\prg_new_conditional:Npnn \int_if_even:n #1 { p , T , F , TF}
+ {
+ \if_int_odd:w \int_eval:w #1 \int_eval_end:
+ \prg_return_false:
+ \else:
+ \prg_return_true:
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Integer expression loops}
+%
+% \begin{macro}{\int_while_do:nn}
+% \UnitTested
+% \TestMissing{Boundary cases}
+% \begin{macro}{\int_until_do:nn}
+% \UnitTested
+% \TestMissing{Boundary cases}
+% \begin{macro}{\int_do_while:nn}
+% \UnitTested
+% \TestMissing{Boundary cases}
+% \begin{macro}{\int_do_until:nn}
+% \UnitTested
+% \TestMissing{Boundary cases}
+% These are quite easy given the above functions. The |while| versions
+% test first and then execute the body. The |do_while| does it the
+% other way round.
+% \begin{macrocode}
+\cs_new:Npn \int_while_do:nn #1#2
+ {
+ \int_compare:nT {#1}
+ {
+ #2
+ \int_while_do:nn {#1} {#2}
+ }
+ }
+\cs_new:Npn \int_until_do:nn #1#2
+ {
+ \int_compare:nF {#1}
+ {
+ #2
+ \int_until_do:nn {#1} {#2}
+ }
+ }
+\cs_new:Npn \int_do_while:nn #1#2
+ {
+ #2
+ \int_compare:nT {#1}
+ { \int_do_while:nNnn {#1} {#2} }
+ }
+\cs_new:Npn \int_do_until:nn #1#2
+ {
+ #2
+ \int_compare:nF {#1}
+ { \int_do_until:nn {#1} {#2} }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\int_while_do:nNnn}
+% \begin{macro}{\int_until_do:nNnn}
+% \begin{macro}{\int_do_while:nNnn}
+% \begin{macro}{\int_do_until:nNnn}
+% As above but not using the more natural syntax.
+% \begin{macrocode}
+\cs_new:Npn \int_while_do:nNnn #1#2#3#4
+ {
+ \int_compare:nNnT {#1} #2 {#3}
+ {
+ #4
+ \int_while_do:nNnn {#1} #2 {#3} {#4}
+ }
+ }
+\cs_new:Npn \int_until_do:nNnn #1#2#3#4
+ {
+ \int_compare:nNnF {#1} #2 {#3}
+ {
+ #4
+ \int_until_do:nNnn {#1} #2 {#3} {#4}
+ }
+ }
+\cs_new:Npn \int_do_while:nNnn #1#2#3#4
+ {
+ #4
+ \int_compare:nNnT {#1} #2 {#3}
+ { \int_do_while:nNnn {#1} #2 {#3} {#4} }
+ }
+\cs_new:Npn \int_do_until:nNnn #1#2#3#4
+ {
+ #4
+ \int_compare:nNnF {#1} #2 {#3}
+ { \int_do_until:nNnn {#1} #2 {#3} {#4} }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Formatting integers}
+%
+% \begin{macro}{\int_to_arabic:n}
+% \UnitTested
+% Nothing exciting here.
+% \begin{macrocode}
+\cs_new_nopar:Npn \int_to_arabic:n #1 { \int_eval:n {#1} }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\int_to_symbols:nnn}
+% \UnitTested
+% For conversion of integers to arbitrary symbols the method is in
+% general as follows. The input number (|#1|) is compared to the total
+% number of symbols available at each place (|#2|). If the input is larger
+% than the total number of symbols available then the modulus is needed,
+% with one added so that the positions don't have to number from
+% zero. Using an \texttt{f}-type expansion, this is done so that the system
+% is recursive. The actual conversion function therefore gets a `nice'
+% number at each stage. Of course, if the initial input was small enough
+% then there is no problem and everything is easy. This is more or less the
+% same as \cs{int_convert_number_with_rule:nnN} but \enquote{pre-packaged}.
+% \begin{macrocode}
+\cs_new_nopar:Npn \int_to_symbols:nnn #1#2#3
+ {
+ \int_compare:nNnTF {#1} > {#2}
+ {
+ \exp_args:Nf \int_to_symbols:nnn
+ { \int_div_truncate:nn { #1 - 1 } {#2} } {#2} {#3}
+ \exp_args:Nf \prg_case_int:nnn
+ { \int_eval:n { 1 + \int_mod:nn { #1 - 1 } {#2} } }
+ {#3} { }
+ }
+ { \exp_args:Nf \prg_case_int:nnn { \int_eval:n {#1} } {#3} { } }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\int_to_alph:n,\int_to_Alph:n}
+% \UnitTested
+% These both use the above function with input functions that make sense
+% for the alphabet in English.
+% \begin{macrocode}
+\cs_new:Npn \int_to_alph:n #1
+ {
+ \int_to_symbols:nnn {#1} { 26 }
+ {
+ { 1 } { a }
+ { 2 } { b }
+ { 3 } { c }
+ { 4 } { d }
+ { 5 } { e }
+ { 6 } { f }
+ { 7 } { g }
+ { 8 } { h }
+ { 9 } { i }
+ { 10 } { j }
+ { 11 } { k }
+ { 12 } { l }
+ { 13 } { m }
+ { 14 } { n }
+ { 15 } { o }
+ { 16 } { p }
+ { 17 } { q }
+ { 18 } { r }
+ { 19 } { s }
+ { 20 } { t }
+ { 21 } { u }
+ { 22 } { v }
+ { 23 } { w }
+ { 24 } { x }
+ { 25 } { y }
+ { 26 } { z }
+ }
+ }
+\cs_new:Npn \int_to_Alph:n #1
+ {
+ \int_to_symbols:nnn {#1} { 26 }
+ {
+ { 1 } { A }
+ { 2 } { B }
+ { 3 } { C }
+ { 4 } { D }
+ { 5 } { E }
+ { 6 } { F }
+ { 7 } { G }
+ { 8 } { H }
+ { 9 } { I }
+ { 10 } { J }
+ { 11 } { K }
+ { 12 } { L }
+ { 13 } { M }
+ { 14 } { N }
+ { 15 } { O }
+ { 16 } { P }
+ { 17 } { Q }
+ { 18 } { R }
+ { 19 } { S }
+ { 20 } { T }
+ { 21 } { U }
+ { 22 } { V }
+ { 23 } { W }
+ { 24 } { X }
+ { 25 } { Y }
+ { 26 } { Z }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\int_to_base:nn}
+% \UnitTested
+% \begin{macro}[aux]{\int_to_base_aux:nnn}
+% \begin{macro}[int]{\int_to_letter:n}
+% \UnitTested
+% Converting from base ten (|#1|) to a second base (|#2|) starts with
+% a simple sign check. As the input is base $10$ \TeX{} can then
+% do the actual work with the sign itself.
+% \begin{macrocode}
+\cs_new:Npn \int_to_base:nn #1#2
+ {
+ \int_compare:nNnTF {#1} < \c_zero
+ {
+ -
+ \exp_args:Nnf \int_to_base_aux:nnn
+ { } { \int_eval:n { 0 - ( #1 ) } } {#2}
+ }
+ {
+ \exp_args:Nnf \int_to_base_aux:nnn
+ { } { \int_eval:n {#1} } {#2}
+ }
+}
+% \end{macrocode}
+% Here, the idea is to provide a recursive system to deal with the
+% input. The output is build up as argument |#1|, which is why it
+% starts off empty in the above. At each pass, the value in |#2| is
+% checked to see if it is less than the new base (|#3|). If it is
+% the it is converted directly and the rest of the output is added in.
+% On the other hand, if the value to convert is greater than or equal
+% to the new base then the modulus and remainder values are found. The
+% modulus is converted to a symbol and the remainder is carried forward
+% to the next round.
+% \begin{macrocode}
+\cs_new:Npn \int_to_base_aux:nnn #1#2#3 {
+ \int_compare:nNnTF {#2} < {#3}
+ {
+ \int_to_letter:n {#2}
+ #1
+ }
+ {
+ \exp_args:Nff \int_to_base_aux:nnn
+ {
+ \int_to_letter:n { \int_mod:nn {#2} {#3} }
+ #1
+ }
+ { \int_div_truncate:nn {#2} {#3} }
+ {#3}
+ }
+ }
+% \end{macrocode}
+% Convert to a letter only if necessary, otherwise simply return the
+% value unchanged.
+% \begin{macrocode}
+\cs_new:Npn \int_to_letter:n #1
+ {
+ \prg_case_int:nnn { #1 - 9 }
+ {
+ { 1 } { A }
+ { 2 } { B }
+ { 3 } { C }
+ { 4 } { D }
+ { 5 } { E }
+ { 6 } { F }
+ { 7 } { G }
+ { 8 } { H }
+ { 9 } { I }
+ { 10 } { J }
+ { 11 } { K }
+ { 12 } { L }
+ { 13 } { M }
+ { 14 } { N }
+ { 15 } { O }
+ { 16 } { P }
+ { 17 } { Q }
+ { 18 } { R }
+ { 19 } { S }
+ { 20 } { T }
+ { 21 } { U }
+ { 22 } { V }
+ { 23 } { W }
+ { 24 } { X }
+ { 25 } { Y }
+ { 26 } { Z }
+ }
+ {#1}
+ }
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%
+% \begin{macro}{\int_to_binary:n, \int_to_hexadecimal:n, \int_to_octal:n}
+% \UnitTested
+% Wrappers around the generic function.
+% \begin{macrocode}
+\cs_new:Npn \int_to_binary:n #1
+ { \int_to_base:nn {#1} { 2 } }
+\cs_new:Npn \int_to_hexadecimal:n #1
+ { \int_to_base:nn {#1} { 16 } }
+\cs_new:Npn \int_to_octal:n #1
+ { \int_to_base:nn {#1} { 8 } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\int_to_roman:n, \int_to_Roman:n}
+% \UnitTested
+% \begin{macro}[aux]{\int_to_roman_aux:N, \int_to_roman_aux:N}
+% \begin{macro}[aux]
+% {
+% \int_to_roman_i:w, \int_to_roman_v:w, \int_to_roman_x:w,
+% \int_to_roman_l:w, \int_to_roman_c:w, \int_to_roman_d:w,
+% \int_to_roman_m:w, \int_to_roman_Q:w,
+% \int_to_Roman_i:w, \int_to_Roman_v:w, \int_to_Roman_x:w,
+% \int_to_Roman_l:w, \int_to_Roman_c:w, \int_to_Roman_d:w,
+% \int_to_Roman_m:w, \int_to_Roman_Q:w,
+% }
+% The \cs{int_to_roman:w} primitive creates tokens of category
+% code $12$ (other). Usually, what is actually wanted is letters.
+% The approach here is to convert the output of the primitive into
+% letters using appropriate control sequence names. That keeps
+% everything expandable. The loop will be terminated by the conversion
+% of the |Q|.
+% \begin{macrocode}
+\cs_new_nopar:Npn \int_to_roman:n #1
+ {
+ \exp_after:wN \int_to_roman_aux:N
+ \int_to_roman:w \int_eval:n {#1} Q
+ }
+\cs_new_nopar:Npn \int_to_roman_aux:N #1
+ {
+ \use:c { int_to_roman_ #1 :w }
+ \int_to_roman_aux:N
+ }
+\cs_new_nopar:Npn \int_to_Roman:n #1
+ {
+ \exp_after:wN \int_to_Roman_aux:N
+ \int_to_roman:w \int_eval:n {#1} Q
+ }
+\cs_new_nopar:Npn \int_to_Roman_aux:N #1
+ {
+ \use:c { int_to_Roman_ #1 :w }
+ \int_to_Roman_aux:N
+ }
+\cs_new_nopar:Npn \int_to_roman_i:w { i }
+\cs_new_nopar:Npn \int_to_roman_v:w { v }
+\cs_new_nopar:Npn \int_to_roman_x:w { x }
+\cs_new_nopar:Npn \int_to_roman_l:w { l }
+\cs_new_nopar:Npn \int_to_roman_c:w { c }
+\cs_new_nopar:Npn \int_to_roman_d:w { d }
+\cs_new_nopar:Npn \int_to_roman_m:w { m }
+\cs_new_nopar:Npn \int_to_roman_Q:w #1 { }
+\cs_new_nopar:Npn \int_to_Roman_i:w { I }
+\cs_new_nopar:Npn \int_to_Roman_v:w { V }
+\cs_new_nopar:Npn \int_to_Roman_x:w { X }
+\cs_new_nopar:Npn \int_to_Roman_l:w { L }
+\cs_new_nopar:Npn \int_to_Roman_c:w { C }
+\cs_new_nopar:Npn \int_to_Roman_d:w { D }
+\cs_new_nopar:Npn \int_to_Roman_m:w { M }
+\cs_new_nopar:Npn \int_to_Roman_Q:w #1 { }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Converting from other formats to integers}
+%
+% \begin{macro}[int]{\int_get_sign:n}
+% \begin{macro}[int]{\int_get_digits:n}
+% \begin{macro}[aux]
+% {\int_get_sign_and_digits_aux:nNNN, \int_get_sign_and_digits_aux:oNNN}
+% Finding a number and its sign requires dealing with an arbitrary
+% list of |+| and |-| symbols. This is done by working through token
+% by token until there is something else at the start of the input.
+% The sign of the input is tracked by the first Boolean used by the
+% auxiliary function.
+% \begin{macrocode}
+\cs_new:Npn \int_get_sign:n #1
+ {
+ \int_get_sign_and_digits_aux:nNNN {#1}
+ \c_true_bool \c_true_bool \c_false_bool
+ }
+\cs_new:Npn \int_get_digits:n #1
+ {
+ \int_get_sign_and_digits_aux:nNNN {#1}
+ \c_true_bool \c_false_bool \c_true_bool
+ }
+% \end{macrocode}
+% The auxiliary loops through, finding sign tokens and removing them.
+% The sign itself is carried through as a flag.
+% \begin{macrocode}
+\cs_new:Npn \int_get_sign_and_digits_aux:nNNN #1#2#3#4
+ {
+ \tl_if_head_eq_charcode:fNTF {#1} -
+ {
+ \bool_if:NTF #2
+ {
+ \int_get_sign_and_digits_aux:oNNN
+ { \use_none:n #1 } \c_false_bool #3#4
+ }
+ {
+ \int_get_sign_and_digits_aux:oNNN
+ { \use_none:n #1 } \c_true_bool #3#4
+ }
+ }
+ {
+ \tl_if_head_eq_charcode:fNTF {#1} +
+ { \int_get_sign_and_digits_aux:oNNN { \use_none:n #1 } #2#3#4 }
+ {
+ \bool_if:NT #3 { \bool_if:NF #2 - }
+ \bool_if:NT #4 {#1}
+ }
+ }
+ }
+\cs_generate_variant:Nn \int_get_sign_and_digits_aux:nNNN { o }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\int_from_alph:n}
+% \UnitTested
+% \begin{macro}[aux]{\int_from_alph_aux:n}
+% \begin{macro}[aux]{\int_from_alph_aux:nN}
+% \begin{macro}[aux]{\int_from_alph_aux:N}
+% The aim here is to iterate through the input, converting one letter at
+% a time to a number. The same approach is also used for base
+% conversion, but this needs a different final auxiliary.
+% \begin{macrocode}
+\cs_new:Npn \int_from_alph:n #1
+ {
+ \int_eval:n
+ {
+ \int_get_sign:n {#1}
+ \exp_args:Nf \int_from_alph_aux:n { \int_get_digits:n {#1} }
+ }
+ }
+\cs_new:Npn \int_from_alph_aux:n #1
+ { \int_from_alph_aux:nN { 0 } #1 \q_nil }
+\cs_new:Npn \int_from_alph_aux:nN #1#2
+ {
+ \quark_if_nil:NTF #2
+ {#1}
+ {
+ \exp_args:Nf \int_from_alph_aux:nN
+ { \int_eval:n { #1 * 26 + \int_from_alph_aux:N #2 } }
+ }
+ }
+\cs_new:Npn \int_from_alph_aux:N #1
+ { \int_eval:n { `#1 - \int_compare:nNnTF { `#1 } < { 91 } { 64 } { 96 } } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\int_from_base:nn}
+% \UnitTested
+% \begin{macro}[aux]{\int_from_base_aux:nn}
+% \begin{macro}[aux]{\int_from_base_aux:nnN}
+% \begin{macro}[aux]{\int_from_base_aux:N}
+% Conversion to base ten means stripping off the sign then iterating
+% through the input one token at a time. The total number is then added
+% up as the code loops.
+% \begin{macrocode}
+\cs_new:Npn \int_from_base:nn #1#2
+ {
+ \int_eval:n
+ {
+ \int_get_sign:n {#1}
+ \exp_args:Nf \int_from_base_aux:nn
+ { \int_get_digits:n {#1} } {#2}
+ }
+ }
+\cs_new:Npn \int_from_base_aux:nn #1#2
+ { \int_from_base_aux:nnN { 0 } { #2 } #1 \q_nil }
+\cs_new:Npn \int_from_base_aux:nnN #1#2#3
+ {
+ \quark_if_nil:NTF #3
+ {#1}
+ {
+ \exp_args:Nf \int_from_base_aux:nnN
+ { \int_eval:n { #1 * #2 + \int_from_base_aux:N #3 } }
+ {#2}
+ }
+ }
+% \end{macrocode}
+% The conversion here will take lower or upper case letters and turn
+% them into the appropriate number, hence the two-part nature of the
+% function.
+% \begin{macrocode}
+\cs_new:Npn \int_from_base_aux:N #1
+ {
+ \int_compare:nNnTF { `#1 } < { 58 }
+ {#1}
+ {
+ \int_eval:n
+ { `#1 - \int_compare:nNnTF { `#1 } < { 91 } { 55 } { 87 } }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\int_from_binary:n, \int_from_hexadecimal:n, \int_from_octal:n}
+% \UnitTested
+% Wrappers around the generic function.
+% \begin{macrocode}
+\cs_new:Npn \int_from_binary:n #1
+ { \int_from_base:nn {#1} \c_two }
+\cs_new:Npn \int_from_hexadecimal:n #1
+ { \int_from_base:nn {#1} \c_sixteen }
+\cs_new:Npn \int_from_octal:n #1
+ { \int_from_base:nn {#1} \c_eight }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}[aux]
+% {
+% \c_int_from_roman_i_int, \c_int_from_roman_v_int,
+% \c_int_from_roman_x_int, \c_int_from_roman_l_int,
+% \c_int_from_roman_c_int, \c_int_from_roman_d_int,
+% \c_int_from_roman_m_int,
+% \c_int_from_roman_I_int, \c_int_from_roman_V_int,
+% \c_int_from_roman_X_int, \c_int_from_roman_L_int,
+% \c_int_from_roman_C_int, \c_int_from_roman_D_int,
+% \c_int_from_roman_M_int
+% }
+% Constants used to convert from Roman numerals to integers.
+% \begin{macrocode}
+\int_const:cn { c_int_from_roman_i_int } { 1 }
+\int_const:cn { c_int_from_roman_v_int } { 5 }
+\int_const:cn { c_int_from_roman_x_int } { 10 }
+\int_const:cn { c_int_from_roman_l_int } { 50 }
+\int_const:cn { c_int_from_roman_c_int } { 100 }
+\int_const:cn { c_int_from_roman_d_int } { 500 }
+\int_const:cn { c_int_from_roman_m_int } { 1000 }
+\int_const:cn { c_int_from_roman_I_int } { 1 }
+\int_const:cn { c_int_from_roman_V_int } { 5 }
+\int_const:cn { c_int_from_roman_X_int } { 10 }
+\int_const:cn { c_int_from_roman_L_int } { 50 }
+\int_const:cn { c_int_from_roman_C_int } { 100 }
+\int_const:cn { c_int_from_roman_D_int } { 500 }
+\int_const:cn { c_int_from_roman_M_int } { 1000 }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\int_from_roman:n}
+% \UnitTested
+% \TestMissing{boundary cases / wrong input?}
+% \begin{macro}[aux]{\int_from_roman_aux:NN}
+% \begin{macro}[aux]{\int_from_roman_end:w}
+% \begin{macro}[aux]{\int_from_roman_clean_up:w}
+% The method here is to iterate through the input, finding the
+% appropriate value for each letter and building up a sum. This is
+% then evaluated by \TeX{}.
+% \begin{macrocode}
+\cs_new_nopar:Npn \int_from_roman:n #1
+ {
+ \tl_if_blank:nF {#1}
+ {
+ \exp_after:wN \int_from_roman_end:w
+ \int_value:w \int_eval:w
+ \int_from_roman_aux:NN #1 Q \q_stop
+ }
+ }
+\cs_new_nopar:Npn \int_from_roman_aux:NN #1#2
+ {
+ \str_if_eq:nnTF {#1} { Q }
+ {#1#2}
+ {
+ \str_if_eq:nnTF {#2} { Q }
+ {
+ \cs_if_exist:cF { c_int_from_roman_ #1 _int }
+ { \int_from_roman_clean_up:w }
+ +
+ \use:c { c_int_from_roman_ #1 _int }
+ #2
+ }
+ {
+ \cs_if_exist:cF { c_int_from_roman_ #1 _int }
+ { \int_from_roman_clean_up:w }
+ \cs_if_exist:cF { c_int_from_roman_ #2 _int }
+ { \int_from_roman_clean_up:w }
+ \int_compare:nNnTF
+ { \use:c { c_int_from_roman_ #1 _int } }
+ <
+ { \use:c { c_int_from_roman_ #2 _int } }
+ {
+ + \use:c { c_int_from_roman_ #2 _int }
+ - \use:c { c_int_from_roman_ #1 _int }
+ \int_from_roman_aux:NN
+ }
+ {
+ + \use:c { c_int_from_roman_ #1 _int }
+ \int_from_roman_aux:NN #2
+ }
+ }
+ }
+ }
+\cs_new_nopar:Npn \int_from_roman_end:w #1 Q #2 \q_stop
+ { \tl_if_empty:nTF {#2} {#1} {#2} }
+\cs_new_nopar:Npn \int_from_roman_clean_up:w #1 Q { + 0 Q -1 }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Viewing integer}
+%
+% \begin{macro}{\int_show:N,\int_show:c}
+% \UnitTested
+% \begin{macrocode}
+\cs_new_eq:NN \int_show:N \kernel_register_show:N
+\cs_new_eq:NN \int_show:c \kernel_register_show:c
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Constant integers}
+%
+% \begin{variable}{\c_minus_one}
+% This is needed early, and so is in \pkg{l3basics}
+% \end{variable}
+%
+% \begin{variable}{\c_zero}
+% Again, one in \pkg{l3basics} for obvious reasons.
+% \end{variable}
+%
+% \begin{variable}{\c_six, \c_seven}
+% \begin{variable}{\c_twelve}
+% \begin{variable}{\c_sixteen}
+% Once again, in \pkg{l3basics}.
+% \end{variable}
+% \end{variable}
+% \end{variable}
+%
+% \begin{variable}
+% {
+% \c_one, \c_two, \c_three, \c_four, \c_five, \c_eight, \c_nine, \c_ten,
+% \c_eleven, \c_thirteen, \c_fourteen, \c_fifteen,
+% }
+% Low-number values not previously defined.
+% \begin{macrocode}
+\int_const:Nn \c_one { 1 }
+\int_const:Nn \c_two { 2 }
+\int_const:Nn \c_three { 3 }
+\int_const:Nn \c_four { 4 }
+\int_const:Nn \c_five { 5 }
+\int_const:Nn \c_eight { 8 }
+\int_const:Nn \c_nine { 9 }
+\int_const:Nn \c_ten { 10 }
+\int_const:Nn \c_eleven { 11 }
+\int_const:Nn \c_thirteen { 13 }
+\int_const:Nn \c_fourteen { 14 }
+\int_const:Nn \c_fifteen { 15 }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\c_thirty_two}
+% One middling value.
+% \begin{macrocode}
+\int_const:Nn \c_thirty_two { 32 }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\c_two_hundred_fifty_five, \c_two_hundred_fifty_six}
+% Two classic mid-range integer constants.
+% \begin{macrocode}
+\int_const:Nn \c_two_hundred_fifty_five { 255 }
+\int_const:Nn \c_two_hundred_fifty_six { 256 }
+% \end{macrocode}
+%\end{variable}
+%
+% \begin{variable}
+% {\c_one_hundred, \c_one_thousand, \c_ten_thousand}
+% Simple runs of powers of ten.
+% \begin{macrocode}
+\int_const:Nn \c_one_hundred { 100 }
+\int_const:Nn \c_one_thousand { 1000 }
+\int_const:Nn \c_ten_thousand { 10000 }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\c_max_int}
+% The largest number allowed is $2^{31}-1$
+% \begin{macrocode}
+\int_const:Nn \c_max_int { 2 147 483 647 }
+% \end{macrocode}
+% \end{variable}
+%
+% \subsection{Scratch integers}
+%
+% \begin{variable}{\l_tmpa_int, \l_tmpb_int, \l_tmpc_int}
+% \begin{variable}{\g_tmpa_int, \g_tmpb_int}
+% We provide four local and two global scratch counters, maybe we
+% need more or less.
+% \begin{macrocode}
+\int_new:N \l_tmpa_int
+\int_new:N \l_tmpb_int
+\int_new:N \l_tmpc_int
+\int_new:N \g_tmpa_int
+\int_new:N \g_tmpb_int
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+%
+% \subsection{Registers for earlier modules}
+%
+% Needed from other modules:
+% \begin{macrocode}
+\int_new:N \g_seq_nesting_depth_int
+\int_new:N \g_tl_inline_level_int
+% \end{macrocode}
+%
+% \subsection{Deprecated functions}
+%
+% Deprecated on 2011-05-27, for removal by 2011-08-31.
+%
+% \begin{macro}{\int_convert_from_base_ten:nn}
+% \begin{macro}{\int_convert_to_symbols:nnn}
+% \begin{macro}{\int_convert_to_base_ten:nn}
+% Some simple renames.
+% \begin{macrocode}
+\cs_new_eq:NN \int_convert_from_base_ten:nn \int_to_base:nn
+\cs_new_eq:NN \int_convert_to_symbols:nnn \int_to_symbols:nnn
+\cs_new_eq:NN \int_convert_to_base_ten:nn \int_from_base:nn
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\int_to_symbol:n}
+% \begin{macro}[aux]{\int_to_symbol_math:n}
+% \begin{macro}[aux]{\int_to_symbol_text:n}
+% \UnitTested
+% This is rather too tied to \LaTeXe{}.
+% \begin{macrocode}
+\cs_new_nopar:Npn \int_to_symbol:n
+ {
+ \mode_if_math:TF
+ { \int_to_symbol_math:n }
+ { \int_to_symbol_text:n }
+ }
+\cs_new:Npn \int_to_symbol_math:n #1
+ {
+ \int_to_symbols:nnn {#1} { 9 }
+ {
+ { 1 } { * }
+ { 2 } { \dagger }
+ { 3 } { \ddagger }
+ { 4 } { \mathsection }
+ { 5 } { \mathparagraph }
+ { 6 } { \| }
+ { 7 } { ** }
+ { 8 } { \dagger \dagger }
+ { 9 } { \ddagger \ddagger }
+ }
+ }
+\cs_new:Npn \int_to_symbol_text:n #1
+ {
+ \int_to_symbols:nnn {#1} { 9 }
+ {
+ { 1 } { \textasteriskcentered }
+ { 2 } { \textdagger }
+ { 3 } { \textdaggerdbl }
+ { 4 } { \textsection }
+ { 5 } { \textparagraph }
+ { 6 } { \textbardbl }
+ { 7 } { \textasteriskcentered \textasteriskcentered }
+ { 8 } { \textdagger \textdagger }
+ { 9 } { \textdaggerdbl \textdaggerdbl }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macrocode}
+%</initex|package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3io.dtx b/Master/texmf-dist/source/latex/l3kernel/l3io.dtx
new file mode 100644
index 00000000000..bf71c3df878
--- /dev/null
+++ b/Master/texmf-dist/source/latex/l3kernel/l3io.dtx
@@ -0,0 +1,1185 @@
+% \iffalse meta-comment
+%
+%% File: l3io.dtx Copyright (C) 1990-2011 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 "expl3 bundle" (The Work in LPPL)
+%% and all files in that bundle must be distributed together.
+%%
+%% The released version of this bundle is available from CTAN.
+%%
+%% -----------------------------------------------------------------------
+%%
+%% The development version of the bundle can be found at
+%%
+%% http://www.latex-project.org/svnroot/experimental/trunk/
+%%
+%% for those people who are interested.
+%%
+%%%%%%%%%%%
+%% NOTE: %%
+%%%%%%%%%%%
+%%
+%% Snapshots taken from the repository represent work in progress and may
+%% not work or may contain conflicting material! We therefore ask
+%% people _not_ to put them into distributions, archives, etc. without
+%% prior consultation with the LaTeX3 Project.
+%%
+%% -----------------------------------------------------------------------
+%
+%<*driver|package>
+\RequirePackage{l3names}
+\GetIdInfo$Id: l3io.dtx 2478 2011-06-19 21:34:23Z joseph $
+ {L3 Experimental input-output operations}
+%</driver|package>
+%<*driver>
+\documentclass[full]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3io} package\\ Input--output operations^^A
+% \thanks{This file describes v\ExplFileVersion,
+% last revised \ExplFileDate.}^^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 \ExplFileDate}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% Reading and writing from file streams is handled in \LaTeX3 using
+% functions with prefixes \cs{iow_\ldots} (file reading) and
+% \cs{ior_\ldots} (file writing). Many of the basic functions are
+% very similar, with reading and writing using the same syntax and
+% function concepts. As a result, the reading and writing functions
+% are documented together where this makes sense.
+%
+% As \TeX{} is limited to $16$ input streams and $16$ output
+% streams, direct use of the streams by the programmer is not
+% supported in \LaTeX3. Instead, an internal pool of streams is
+% maintained, and these are allocated and deallocated as needed
+% by other modules. As a result, the programmer should close streams
+% when they are no longer needed, to release them for other processes.
+%
+% Reading from or writing to a file requires a \meta{stream} to
+% be used. This is a csname which refers to the file being processed,
+% and is independent of the name of the file (except of course that
+% the file name is needed when the file is opened).
+%
+% \section{Opening and closing streams}
+%
+% \begin{function}{\ior_open:Nn, \ior_open:cn}
+% \begin{syntax}
+% \cs{ior_open:Nn} \meta{stream} \Arg{file name}
+% \end{syntax}
+% Opens \meta{file name} for reading using \meta{stream} as the
+% control sequence for file access. If the \meta{stream} was already
+% open it is closed before the new operation begins. The
+% \meta{stream} is available for access immediately and will remain
+% allocated to \meta{file name} until a \cs{ior_close:N} instruction
+% is given or the file ends.
+% \end{function}
+%
+% \begin{function}{\iow_open:Nn, \iow_open:cn}
+% \begin{syntax}
+% \cs{iow_open:Nn} \meta{stream} \Arg{file name}
+% \end{syntax}
+% Opens \meta{file name} for writing using \meta{stream} as the
+% control sequence for file access. If the \meta{stream} was already
+% open it is closed before the new operation begins. The
+% \meta{stream} is available for access immediately and will remain
+% allocated to \meta{file name} until a \cs{iow_close:N} instruction
+% is given or the file ends. Opening a file for writing will clear
+% any existing content in the file (\emph{i.e.}~writing is \emph{not}
+% additive).
+% \end{function}
+%
+% \begin{function}{\ior_close:N, \ior_close:c}
+% \begin{syntax}
+% \cs{ior_close:N} \meta{stream}
+% \end{syntax}
+% Closes the \meta{stream}. Streams should always be closed when
+% they are finished with as this ensures that they remain available
+% to other programmer. The name of the \meta{stream} will be freed at
+% this stage, to ensure that any further attempts to read from it results
+% in an error.
+% \end{function}
+%
+% \begin{function}{\iow_close:N, \iow_close:c}
+% \begin{syntax}
+% \cs{iow_close:N} \meta{stream}
+% \end{syntax}
+% Closes the \meta{stream}. Streams should always be closed when
+% they are finished with as this ensures that they remain available
+% to other programmer. The name of the \meta{stream} will be freed at
+% this stage, to ensure that any further attempts to write to it results
+% in an error.
+% \end{function}
+%
+% \begin{function}{\ior_list_streams:, \iow_list_streams:}
+% \begin{syntax}
+% \cs{ior_list_streams:} \\
+% \cs{iow_list_streams:}
+% \end{syntax}
+% Displays a list of the file names associated with each open
+% stream: intended for tracking down problems.
+% \end{function}
+%
+% \section{Writing to files}
+%
+% \begin{function}{\iow_now:Nn, \iow_now:Nx}
+% \begin{syntax}
+% \cs{iow_now:Nn} \meta{stream} \Arg{tokens}
+% \end{syntax}
+% This functions writes \meta{tokens} to the specified
+% \meta{stream} immediately (\emph{i.e.}~the write operation is called
+% on expansion of \cs{iow_now:Nn}).
+% \begin{texnote}
+% \cs{iow_now:Nx} is a protected macro which expands to
+% the two \TeX{} primitives \cs{immediate}\cs{write}.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{\iow_log:n, \iow_log:x}
+% \begin{syntax}
+% \cs{iow_log:n} \Arg{tokens}
+% \end{syntax}
+% This function writes the given \meta{tokens} to the log (transcript)
+% file immediately: it is a dedicated version of \cs{iow_now:Nn}.
+% \end{function}
+%
+% \begin{function}{\iow_term:n, \iow_term:x}
+% \begin{syntax}
+% \cs{iow_term:n} \Arg{tokens}
+% \end{syntax}
+% This function writes the given \meta{tokens} to the terminal
+% file immediately: it is a dedicated version of \cs{iow_now:Nn}.
+% \end{function}
+%
+% \begin{function}{\iow_now_when_avail:Nn, \iow_now_when_avail:Nx}
+% \begin{syntax}
+% \cs{iow_now_when_avail:Nn} \meta{stream} \Arg{tokens}
+% \end{syntax}
+% If \meta{stream} is open, writes the \meta{tokens} to the \meta{stream}
+% in the same manner as \cs{iow_now:Nn}. If the \meta{stream} is not open,
+% the \meta{tokens}are simply thrown away.
+% \end{function}
+%
+% \begin{function}{\iow_shipout:Nn, \iow_shipout:Nx}
+% \begin{syntax}
+% \cs{iow_shipout:Nn} \meta{stream} \Arg{tokens}
+% \end{syntax}
+% This functions writes \meta{tokens} to the specified
+% \meta{stream} when the current page is finalised (\emph{i.e.}~at
+% shipout). The \texttt{x}-type variants expand the \meta{tokens}
+% at the point where the function is used but \emph{not} when the
+% resulting tokens are written to the \meta{stream}
+% (\emph{cf.}~\cs{iow_shipout_x:Nn}).
+% \end{function}
+%
+% \begin{function}{\iow_shipout_x:Nn, \iow_shipout_x:Nx}
+% \begin{syntax}
+% \cs{iow_shipout_x:Nn} \meta{stream} \Arg{tokens}
+% \end{syntax}
+% This functions writes \meta{tokens} to the specified
+% \meta{stream} when the current page is finalised (\emph{i.e}.~at
+% shipout). The \meta{tokens} are expanded at the time of writing
+% in addition to any expansion when the function is used. This makes
+% these functions suitable for including material finalised during
+% the page building process (such as the page number integer).
+% \begin{texnote}
+% \cs{iow_shipout_x:Nn} is the \TeX{} primitive \cs{write} renamed.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[EXP]{\iow_char:N}
+% \begin{syntax}
+% \cs{iow_char:N} \meta{token}
+% \end{syntax}
+% Inserts \meta{token} into the output stream. Useful when trying to
+% write difficult characters such as "%", "{", "}",
+% \emph{etc}.~in messages, for example:
+% \begin{verbatim}
+% \iow_now:Nx \g_my_stream { \iow_char:N \{ text \iow_char:N \} }
+% \end{verbatim}
+% The function has no effect if writing is taking place without
+% expansion (\emph{e.g.}~in the second argument of \cs{iow_now:Nn}).
+% \end{function}
+%
+% \begin{function}[EXP]{\iow_newline:}
+% \begin{syntax}
+% \cs{iow_newline:}
+% \end{syntax}
+% Function to add a new line within the \meta{tokens} written to a
+% file. The function has no effect if writing is taking place without
+% expansion (\emph{e.g.}~in the second argument of \cs{iow_now:Nn}).
+% \end{function}
+%
+% \section{Wrapping lines in output}
+%
+% \begin{function}{\iow_wrap:xnnnN}
+% \begin{syntax}
+% \cs{iow_wrap:xnnnN} \Arg{text} \Arg{run-on text} \Arg{run-on length}
+% ~~\Arg{set up} \meta{function}
+% \end{syntax}
+% This function will wrap the \meta{text} to a fixed number of
+% characters per line. At the start of each line which is wrapped,
+% the \meta{run-on text} will be inserted. The line length targeted
+% will be the value of \cs{l_iow_line_length_int} minus the
+% \meta{run-on length}. The later value should be the number of
+% characters in the \meta{run-on text}. Additional functions may be
+% added to the wrapping by using the \meta{set up}, which is executed
+% before the wrapping takes place. The result of the wrapping operation
+% is passed as a braced argument to the \meta{function}, which will
+% typically be a wrapper around a writing operation. Within the
+% \meta{text}, |\\| may be used to force a new line and \verb|\ | may be
+% used to represent a forced space (for example after a control
+% sequence). Both the wrapping process and the subsequent write operation
+% will perform \texttt{x}-type expansion. For this reason, material which
+% is to be written \enquote{as is} should be given as the argument to
+% \cs{token_to_str:N} or \cs{tl_to_str:n} (as appropriate) within
+% the \meta{text}. The output of \cs{iow_wrap:xnnnN} (\emph{i.e.}~the
+% argument passed to the \meta{function}) will consist of characters of
+% category code $12$ (other) and $10$ (space) only. This means that the
+% output will \emph{not} expand further when written to a file.
+% \end{function}
+%
+% \begin{variable}{\l_iow_line_length_int}
+% The maximum length of a line to be written by the \cs{iow_wrap:xxnnN}
+% function. This value depends on the \TeX{} system in use: the standard
+% value is $78$, which is typically correct for unmodified \TeX{}live
+% and MiK\TeX{} systems.
+% \end{variable}
+%
+% \section{Reading from files}
+%
+% \begin{function}{\ior_to:NN}
+% \begin{syntax}
+% \cs{ior_to:NN} \meta{stream} \meta{token list variable}
+% \end{syntax}
+% Functions that reads one or more lines (until an equal number of left
+% and right braces are found) from the input \meta{stream} and stores
+% the result locally in the \meta{token list} variable. If the
+% \meta{stream} is not open, input is requested from the terminal.
+% The material read from the \meta{stream} will be tokenized by
+% \TeX{} according to the category codes in force when the function
+% is used.
+% \begin{texnote}
+% The is protected macro which expands to the \TeX{} primitive \cs{read}
+% along with the |to| keyword.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{\ior_gto:NN}
+% \begin{syntax}
+% \cs{ior_gto:NN} \meta{stream} \meta{token list variable}
+% \end{syntax}
+% Functions that reads one or more lines (until an equal number of left
+% and right braces are found) from the input \meta{stream} and stores
+% the result globally in the \meta{token list} variable. If the
+% \meta{stream} is not open, input is requested from the terminal.
+% The material read from the \meta{stream} will be tokenized by
+% \TeX{} according to the category codes in force when the function
+% is used.
+% \begin{texnote}
+% The is protected macro which expands to the \TeX{} primitives
+% \cs{global} \cs{read} along with the |to| keyword.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{\ior_str_to:NN}
+% \begin{syntax}
+% \cs{ior_str_to:NN} \meta{stream} \meta{token list variable}
+% \end{syntax}
+% Functions that reads one or more lines (until an equal number of left
+% and right braces are found) from the input \meta{stream} and stores
+% the result locally in the \meta{token list} variable. If the
+% \meta{stream} is not open, input is requested from the terminal.
+% The material read from the \meta{stream} as a series of tokens with
+% category code $12$ (other), with the exception of space
+% characters which are given category code $10$ (space).
+% \begin{texnote}
+% The is protected macro which expands to the \eTeX{} primitive
+% \cs{readline} along with the |to| keyword.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{\ior_str_gto:NN}
+% \begin{syntax}
+% \cs{ior_str_gto:NN} \meta{stream} \meta{token list variable}
+% \end{syntax}
+% Functions that reads one or more lines (until an equal number of left
+% and right braces are found) from the input \meta{stream} and stores
+% the result globally in the \meta{token list} variable. If the
+% \meta{stream} is not open, input is requested from the terminal.
+% The material read from the \meta{stream} as a series of tokens with
+% category code $12$ (other), with the exception of space
+% characters which are given category code $10$ (space).
+% \begin{texnote}
+% The is protected macro which expands to the primitives
+% \cs{global} \cs{readline} along with the |to| keyword.
+% \end{texnote}
+% \end{function}
+%
+%\begin{function}[EXP,pTF]{\ior_if_eof:N}
+% \begin{syntax}
+% \cs{ior_if_eof_p:N} \meta{stream}
+% \cs{ior_if_eof:NTF} \meta{stream} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the end of a \meta{stream} has been reached during a reading
+% operation. The test will also return a \texttt{true} value if
+% the \meta{stream} is not open or the \meta{file name} associated with
+% a \meta{stream} does not exist at all. The branching versions then
+% leave either \meta{true code} or \meta{false code} in the input
+% stream, as appropriate to the truth of the test and the variant of
+% the function chosen. The logical truth of the test is left in the
+% input stream by the predicate version.
+%\end{function}
+%
+% \section{Internal input--output functions}
+%
+% \begin{function}[EXP]{\if_eof:w}
+% \begin{syntax}
+% \cs{if_eof:w} \meta{stream}
+% ~~\meta{true code}
+% \cs{else:}
+% ~~\meta{false code}
+% \cs{fi:}
+% \end{syntax}
+% Tests if the \meta{stream} returns \enquote{end of file}, which is true
+% for non-existent files. The \cs{else:} branch is optional.
+% \begin{texnote}
+% This is the \TeX{} primitive \cs{ifeof}.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{\ior_raw_new:N, \ior_raw_new:c}
+% \begin{syntax}
+% \cs{ior_raw_new:N} \meta{stream}
+% \end{syntax}
+% Directly allocates a new stream for reading, bypassing the stack
+% system. This is to be used only when a new stream is required at a
+% \TeX{} level, when a new stream is requested by the stack itself.
+% \end{function}
+%
+% \begin{function}{\iow_raw_new:N, \iow_raw_new:c}
+% \begin{syntax}
+% \cs{iow_raw_new:N} \meta{stream}
+% \end{syntax}
+% Directly allocates a new stream for writing, bypassing the stack
+% system. This is to be used only when a new stream is required at a
+% \TeX{} level, when a new stream is requested by the stack itself.
+% \end{function}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3io} implementation}
+%
+% \begin{macrocode}
+%<*initex|package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*package>
+\ProvidesExplPackage
+ {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
+\package_check_loaded_expl:
+%</package>
+% \end{macrocode}
+%
+% \subsection{Primitives}
+%
+% \begin{macro}{\if_eof:w}
+% The primitive conditional
+% \begin{macrocode}
+\cs_new_eq:NN \if_eof:w \tex_ifeof:D
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Variables and constants}
+%
+% \begin{variable}{\c_iow_term_stream, \c_ior_term_stream}
+% \begin{variable}{\c_iow_log_stream, \c_ior_log_stream}
+% Here we allocate two output streams for writing to the transcript
+% file only (\cs{c_iow_log_stream}) and to both the terminal and
+% transcript file (\cs{c_iow_term_stream}). Both can be used to read
+% from and have equivalent \cs{c_ior} versions.
+% \begin{macrocode}
+\cs_new_eq:NN \c_iow_term_stream \c_sixteen
+\cs_new_eq:NN \c_ior_term_stream \c_sixteen
+\cs_new_eq:NN \c_iow_log_stream \c_minus_one
+\cs_new_eq:NN \c_ior_log_stream \c_minus_one
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+%
+% \begin{variable}{\c_iow_streams_tl, \c_ior_streams_tl}
+% The list of streams available, by number.
+% \begin{macrocode}
+\tl_const:Nn \c_iow_streams_tl
+ {
+ \c_zero
+ \c_one
+ \c_two
+ \c_three
+ \c_four
+ \c_five
+ \c_six
+ \c_seven
+ \c_eight
+ \c_nine
+ \c_ten
+ \c_eleven
+ \c_twelve
+ \c_thirteen
+ \c_fourteen
+ \c_fifteen
+ }
+\cs_new_eq:NN \c_ior_streams_tl \c_iow_streams_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\g_iow_streams_prop, \g_ior_streams_prop}
+% The allocations for streams are stored in property lists, which
+% are set up to have a \enquote{full} set of allocations from the start.
+% In package mode, a few slots are always taken, so these are
+% blocked off from use.
+% \begin{macrocode}
+\prop_new:N \g_iow_streams_prop
+\prop_new:N \g_ior_streams_prop
+%<*package>
+\prop_put:Nnn \g_iow_streams_prop { 0 } { LaTeX2e~reserved }
+\prop_put:Nnn \g_iow_streams_prop { 1 } { LaTeX2e~reserved }
+\prop_put:Nnn \g_iow_streams_prop { 2 } { LaTeX2e~reserved }
+\prop_put:Nnn \g_ior_streams_prop { 0 } { LaTeX2e~reserved }
+%</package>
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_iow_stream_int, \l_ior_stream_int}
+% Used to track the number allocated to the stream being created:
+% this is taken from the property list but does alter.
+% \begin{macrocode}
+\int_new:N \l_iow_stream_int
+\cs_new_eq:NN \l_ior_stream_int \l_iow_stream_int
+% \end{macrocode}
+% \end{variable}
+%
+% \subsection{Stream management}
+%
+% \begin{macro}[int]{\ior_raw_new:N, \ior_raw_new:c}
+% \begin{macro}[int]{\iow_raw_new:N, \iow_raw_new:c}
+% The lowest level for stream management is actually creating raw \TeX{}
+% streams. As these are very limited (even with \eTeX{}), this should not
+% be addressed directly.
+% \begin{macrocode}
+%<*initex>
+\alloc_setup_type:nnn { ior } \c_zero \c_sixteen
+\cs_new_protected_nopar:Npn \ior_raw_new:N #1
+ { \alloc_reg:NnNN g { ior } \tex_chardef:D #1 }
+\alloc_setup_type:nnn { iow } \c_zero \c_sixteen
+\cs_new_protected_nopar:Npn \iow_raw_new:N #1
+ { \alloc_reg:NnNN g { iow } \tex_chardef:D #1 }
+%</initex>
+%<*package>
+\cs_set_eq:NN \iow_raw_new:N \newwrite
+\cs_set_eq:NN \ior_raw_new:N \newread
+%</package>
+\cs_generate_variant:Nn \ior_raw_new:N { c }
+\cs_generate_variant:Nn \iow_raw_new:N { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\ior_open:Nn, \ior_open:cn}
+% \begin{macro}{\iow_open:Nn, \iow_open:cn}
+% In both cases, opening a stream starts with a call to the closing
+% function: this is safest. There is then a loop through the
+% allocation number list to find the first free stream number.
+% When one is found the allocation can take place, the information
+% can be stored and finally the file can actually be opened.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \ior_open:Nn #1#2
+ {
+ \ior_close:N #1
+ \int_set:Nn \l_ior_stream_int \c_sixteen
+ \tl_map_function:NN \c_ior_streams_tl \ior_alloc_read:n
+ \int_compare:nNnTF \l_ior_stream_int = \c_sixteen
+ { \msg_kernel_error:nn { ior } { streams-exhausted } }
+ {
+ \ior_stream_alloc:N #1
+ \prop_gput:NVn \g_ior_streams_prop \l_ior_stream_int {#2}
+ \tex_openin:D #1#2 \scan_stop:
+ }
+ }
+\cs_new_protected_nopar:Npn \iow_open:Nn #1#2
+ {
+ \iow_close:N #1
+ \int_set:Nn \l_iow_stream_int \c_sixteen
+ \tl_map_function:NN \c_iow_streams_tl \iow_alloc_write:n
+ \int_compare:nNnTF \l_iow_stream_int = \c_sixteen
+ { \msg_kernel_error:nn { iow } { streams-exhausted } }
+ {
+ \iow_stream_alloc:N #1
+ \prop_gput:NVn \g_iow_streams_prop \l_iow_stream_int {#2}
+ \tex_immediate:D \tex_openout:D #1#2 \scan_stop:
+ }
+ }
+\cs_generate_variant:Nn \ior_open:Nn { c }
+\cs_generate_variant:Nn \iow_open:Nn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[aux]{\ior_alloc_read:n}
+% \begin{macro}[aux]{\iow_alloc_write:n}
+% These functions are used to see if a particular stream is available.
+% The property list contains file names for streams in use, so
+% any unused ones are for the taking.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \iow_alloc_write:n #1
+ {
+ \prop_if_in:NnF \g_iow_streams_prop {#1}
+ {
+ \int_set:Nn \l_iow_stream_int {#1}
+ \tl_map_break:
+ }
+ }
+\cs_new_protected_nopar:Npn \ior_alloc_read:n #1
+ {
+ \prop_if_in:NnF \g_iow_streams_prop {#1}
+ {
+ \int_set:Nn \l_ior_stream_int {#1}
+ \tl_map_break:
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[aux]{\iow_stream_alloc:N}
+% \begin{macro}[aux]{\ior_stream_alloc:N}
+% \begin{macro}[aux]{\iow_stream_alloc_aux:}
+% \begin{macro}[aux]{\ior_stream_alloc_aux:}
+% \begin{variable}{\g_iow_tmp_stream}
+% \begin{variable}{\g_ior_tmp_stream}
+% Allocating a raw stream is much easier in \IniTeX{} mode than for
+% the package. For the format, all streams will be allocated by
+% \pkg{l3io} and so there is a simple check to see if a raw
+% stream is actually available. On the other hand, for the
+% package there will be non-managed streams. So if the managed
+% one is not open, a check is made to see if some other managed
+% stream is available before deciding to open a new one. If a new
+% one is needed, we get the number allocated by \LaTeXe{} to get
+% \enquote{back on track} with allocation.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \iow_stream_alloc:N #1
+ {
+ \cs_if_exist:cTF { g_iow_ \int_use:N \l_iow_stream_int _stream }
+ { \cs_gset_eq:Nc #1 { g_iow_ \int_use:N \l_iow_stream_int _stream } }
+ {
+%<*package>
+ \iow_stream_alloc_aux:
+ \int_compare:nNnT \l_iow_stream_int = \c_sixteen
+ {
+ \iow_raw_new:N \g_iow_tmp_stream
+ \int_set:Nn \l_iow_stream_int { \g_iow_tmp_stream }
+ \cs_gset_eq:cN
+ { g_iow_ \int_use:N \l_iow_stream_int _stream }
+ \g_iow_tmp_stream
+ }
+%</package>
+%<*initex>
+ \iow_raw_new:c { g_iow_ \int_use:N \l_iow_stream_int _stream }
+%</initex>
+ \cs_gset_eq:Nc #1 { g_iow_ \int_use:N \l_iow_stream_int _stream }
+ }
+ }
+%<*package>
+\cs_new_protected_nopar:Npn \iow_stream_alloc_aux:
+ {
+ \int_incr:N \l_iow_stream_int
+ \int_compare:nNnT \l_iow_stream_int < \c_sixteen
+ {
+ \cs_if_exist:cTF { g_iow_ \int_use:N \l_iow_stream_int _stream }
+ {
+ \prop_if_in:NVT \g_iow_streams_prop \l_iow_stream_int
+ { \iow_stream_alloc_aux: }
+ }
+ { \iow_stream_alloc_aux: }
+ }
+ }
+%</package>
+\cs_new_protected_nopar:Npn \ior_stream_alloc:N #1
+ {
+ \cs_if_exist:cTF { g_ior_ \int_use:N \l_ior_stream_int _stream }
+ { \cs_gset_eq:Nc #1 { g_ior_ \int_use:N \l_ior_stream_int _stream } }
+ {
+%<*package>
+ \ior_stream_alloc_aux:
+ \int_compare:nNnT \l_ior_stream_int = \c_sixteen
+ {
+ \ior_raw_new:N \g_ior_tmp_stream
+ \int_set:Nn \l_ior_stream_int { \g_ior_tmp_stream }
+ \cs_gset_eq:cN
+ { g_ior_ \int_use:N \l_iow_stream_int _stream }
+ \g_ior_tmp_stream
+ }
+%</package>
+%<*initex>
+ \ior_raw_new:c { g_ior_ \int_use:N \l_ior_stream_int _stream }
+%</initex>
+ \cs_gset_eq:Nc #1 { g_ior_ \int_use:N \l_ior_stream_int _stream }
+ }
+ }
+%<*package>
+\cs_new_protected_nopar:Npn \ior_stream_alloc_aux:
+ {
+ \int_incr:N \l_ior_stream_int
+ \int_compare:nNnT \l_ior_stream_int < \c_sixteen
+ {
+ \cs_if_exist:cTF { g_ior_ \int_use:N \l_ior_stream_int _stream }
+ {
+ \prop_if_in:NVT \g_ior_streams_prop \l_ior_stream_int
+ { \ior_stream_alloc_aux: }
+ }
+ { \ior_stream_alloc_aux: }
+ }
+ }
+%</package>
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\iow_close:N, \iow_close:c}
+% \begin{macro}{\iow_close:N, \iow_close:c}
+% Closing a stream is not quite the reverse of opening one. First,
+% the close operation is easier than the open one, and second as the
+% stream is actually a number we can use it directly to show that the
+% slot has been freed up.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \ior_close:N #1
+ {
+ \cs_if_exist:NT #1
+ {
+ \int_compare:nNnF #1 = \c_minus_one
+ {
+ \tex_closein:D #1
+ \prop_gdel:NV \g_ior_streams_prop #1
+ \cs_undefine:N #1
+ }
+ }
+ }
+\cs_new_protected_nopar:Npn \iow_close:N #1
+ {
+ \cs_if_exist:NT #1
+ {
+ \int_compare:nNnF #1 = \c_minus_one
+ {
+ \tex_immediate:D \tex_closeout:D #1
+ \prop_gdel:NV \g_iow_streams_prop #1
+ \cs_undefine:N #1
+ }
+ }
+ }
+\cs_generate_variant:Nn \ior_close:N { c }
+\cs_generate_variant:Nn \iow_close:N { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\ior_list_streams:}
+% \begin{macro}{\iow_list_streams:}
+% \begin{macro}[aux]{\iow_show_aux:nn}
+% \begin{macro}[aux]{\ior_show_aux:nn}
+% Show the property lists, but with some \enquote{pretty printing}.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \ior_list_streams:
+ {
+ \prop_if_empty:NTF \g_ior_streams_prop
+ {
+ \iow_term:x { No~input~streams~are~open }
+ \tl_show:n { }
+ }
+ {
+ \iow_term:x { The~following~input~streams~are~in~use: }
+ \tl_set:Nx \l_prop_show_tl
+ { \prop_map_function:NN \g_ior_streams_prop \ior_show_aux:nn }
+ \etex_showtokens:D \exp_after:wN \exp_after:wN \exp_after:wN
+ { \exp_after:wN \prop_show_aux:w \l_prop_show_tl }
+ }
+ }
+\cs_new:Npn \ior_show_aux:nn #1#2
+ {
+ \iow_newline: > \c_space_tl \c_space_tl
+ #1 \iow_char:N
+ \c_space_tl \c_space_tl => \c_space_tl \c_space_tl
+ \exp_not:n {#2}
+ }
+\cs_new_protected_nopar:Npn \iow_list_streams:
+ {
+ \prop_if_empty:NTF \g_iow_streams_prop
+ {
+ \iow_term:x { No~output~streams~are~open }
+ \tl_show:n { }
+ }
+ {
+ \iow_term:x { The~following~output~streams~are~in~use: }
+ \tl_set:Nx \l_prop_show_tl
+ { \prop_map_function:NN \g_iow_streams_prop \iow_show_aux:nn }
+ \etex_showtokens:D \exp_after:wN \exp_after:wN \exp_after:wN
+ { \exp_after:wN \prop_show_aux:w \l_prop_show_tl }
+ }
+ }
+\cs_new_eq:NN \iow_show_aux:nn \ior_show_aux:nn
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% Text for the error messages.
+% \begin{macrocode}
+\msg_kernel_new:nnnn { iow } { streams-exhausted }
+ { Output~streams~exhausted }
+ {
+ TeX~can~only~open~up~to~16~output~streams~at~one~time.\\
+ All~16 are currently~in~use,~and~something~wanted~to~open
+ another~one.
+ }
+\msg_kernel_new:nnnn { ior } { streams-exhausted }
+ { Input~streams~exhausted }
+ {
+ TeX~can~only~open~up~to~16~input~streams~at~one~time.\\
+ All~16 are currently~in~use,~and~something~wanted~to~open
+ another~one.
+ }
+% \end{macrocode}
+%
+% \subsection{Deferred writing}
+%
+% \begin{macro}{\iow_shipout_x:Nn, \iow_shipout_x:Nx}
+% First the easy part, this is the primitive.
+% \begin{macrocode}
+\cs_new_eq:NN \iow_shipout_x:Nn \tex_write:D
+\cs_generate_variant:Nn \iow_shipout_x:Nn { Nx }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\iow_shipout:Nn, \iow_shipout:Nx}
+% With \eTeX{} available deferred writing is easy.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \iow_shipout:Nn #1#2
+ { \iow_shipout_x:Nn #1 { \exp_not:n {#2} } }
+\cs_generate_variant:Nn \iow_shipout:Nn { Nx }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Immediate writing}
+%
+% \begin{macro}{\iow_now:Nx}
+% An abbreviation for an often used operation, which immediately
+% writes its second argument expanded to the output stream.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \iow_now:Nx { \tex_immediate:D \iow_shipout_x:Nn }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\iow_now:Nn}
+% This routine writes the second argument onto the output stream without
+% expansion. If this stream isn't open, the output goes to the terminal
+% instead. If the first argument is no output stream at all, we get an
+% internal error.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \iow_now:Nn #1#2
+ { \iow_now:Nx #1 { \exp_not:n {#2} } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\iow_log:n, \iow_log:x}
+% \begin{macro}{\iow_term:n, \iow_term:x}
+% Writing to the log and the terminal directly are relatively easy.
+% \begin{macrocode}
+\cs_set_protected_nopar:Npn \iow_log:x { \iow_now:Nx \c_iow_log_stream }
+\cs_new_protected_nopar:Npn \iow_log:n { \iow_now:Nn \c_iow_log_stream }
+\cs_set_protected_nopar:Npn \iow_term:x { \iow_now:Nx \c_iow_term_stream }
+\cs_new_protected_nopar:Npn \iow_term:n { \iow_now:Nn \c_iow_term_stream }
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%
+% \begin{macro}{\iow_now_when_avail:Nn, \iow_now_when_avail:Nx}
+% For writing only if the stream requested is open at all.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \iow_now_when_avail:Nn #1
+ { \cs_if_free:NTF #1 { \use_none:n } { \iow_now:Nn #1 } }
+\cs_new_protected_nopar:Npn \iow_now_when_avail:Nx #1
+ { \cs_if_free:NTF #1 { \use_none:n } { \iow_now:Nx #1 } }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Hard-wrapping lines based on length}
+%
+% The code here implements a generic hard-wrapping function. This is
+% used by the messaging system, but is designed such that it is
+% available for other uses.
+%
+% \begin{macro}{\l_iow_line_length_int}
+% The is the \enquote{raw} length of a line which can be written to
+% file. The standard value is the line length typically used by
+% \TeX{}Live and Mik\TeX{}.
+% \begin{macrocode}
+\int_new:N \l_iow_line_length_int
+\int_set:Nn \l_iow_line_length_int { 78 }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[aux]{\l_iow_target_length_int}
+% This stores the target line length: the full length minus any
+% part for a leader at the start of each line.
+% \begin{macrocode}
+\int_new:N \l_iow_target_length_int
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[aux]{\l_iow_current_line_int, \l_iow_current_word_int}
+% These store the number of characters in the line and word currently
+% being constructed, respectively.
+% \begin{macrocode}
+\int_new:N \l_iow_current_line_int
+\int_new:N \l_iow_current_word_int
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[aux]{\l_iow_current_line_tl, \l_iow_current_word_tl}
+% These hold the current line of text and current word, respectively.
+% \begin{macrocode}
+\tl_new:N \l_iow_current_line_tl
+\tl_new:N \l_iow_current_word_tl
+% \end{macrocode}
+%\end{macro}
+%
+% \begin{macro}[aux]{\l_iow_wrap_tl}
+% Used for the expansion step before detokenizing.
+% \begin{macrocode}
+\tl_new:N \l_iow_wrap_tl
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[aux]{\l_iow_wrapped_tl}
+% The output from wrapping text: fully expanded and with lines
+% which are not overly long.
+% \begin{macrocode}
+\tl_new:N \l_iow_wrapped_tl
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\q_iow_stop}
+% A quark which will not appear elsewhere.
+% \begin{macrocode}
+\quark_new:N \q_iow_stop
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\l_iow_line_start_bool}
+% Boolean to avoid adding a space at the beginning of lines.
+% \begin{macrocode}
+\bool_new:N \l_iow_line_start_bool
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\iow_wrap:xnnnN}
+% \begin{macro}[aux]{\iow_wrap_loop:w}
+% \begin{macro}[aux]{\iow_wrap_word:}
+% \begin{macro}[aux]{\iow_wrap_word_fits:}
+% \begin{macro}[aux]{\iow_wrap_word_newline:}
+% \begin{macro}[aux]{\iow_wrap_newline:}
+% \begin{macro}[aux]{\iow_wrap_end:}
+% The main wrapping function works as follows. The target number of
+% characters in a line is calculated, before fully-expanding the input
+% such that |\\| and \verb*|\ | are converted into the appropriate
+% values. There is then a loop over each word in the input, which
+% will do the actual wrapping. After the loop, the resulting text is
+% passed on to the function which has been given as a post-processor.
+% The argument |#4| is available for additional set up steps for
+% the output.
+% \begin{macrocode}
+\cs_new_protected:Npn \iow_wrap:xnnnN #1#2#3#4#5
+ {
+ \group_begin:
+ \int_set:Nn \l_iow_target_length_int { \l_iow_line_length_int - ( #3 ) }
+ \int_zero:N \l_iow_current_line_int
+ \tl_clear:N \l_iow_current_line_tl
+ \tl_clear:N \l_iow_wrap_tl
+ \bool_set_true:N \l_iow_line_start_bool
+ \cs_set:Npx \\ { \c_space_tl \iow_newline: \c_space_tl }
+ \cs_set_eq:NN \ \c_space_tl
+ #4
+%<*initex>
+ \tl_set:Nx \l_iow_wrap_tl {#1}
+%</initex>
+%<*package>
+ \protected@edef \l_iow_wrap_tl {#1}
+%</package>
+ \cs_set:Npn \\ { \iow_newline: #2 }
+ \use:x
+ {
+ \exp_not:N \iow_wrap_loop:w
+ \tl_to_str:N \l_iow_wrap_tl \c_space_tl
+ \exp_not:N \q_iow_stop \c_space_tl
+ }
+ \exp_args:NNo \group_end:
+ #5 \l_iow_wrapped_tl
+ }
+% \end{macrocode}
+% The loop grabs one word in the input, and checks whether it is
+% the end, or a forced new line, or a normal word.
+% \begin{macrocode}
+\cs_new_protected:Npn \iow_wrap_loop:w #1 ~ %
+ {
+ \tl_set:Nn \l_iow_current_word_tl {#1}
+ \tl_if_eq:NNTF \l_iow_current_word_tl \iow_newline:
+ { \iow_wrap_newline: }
+ {
+ \tl_if_eq:NNTF \l_iow_current_word_tl \q_iow_stop
+ { \iow_wrap_end: }
+ { \iow_wrap_word: }
+ }
+ }
+% \end{macrocode}
+% For a normal word, update the line length, then test if the current
+% word would fit in the current line, and call the appropriate function.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \iow_wrap_word:
+ {
+ \int_set:Nn \l_iow_current_word_int
+ { \str_length_skip_spaces:N \l_iow_current_word_tl }
+ \int_add:Nn \l_iow_current_line_int { \l_iow_current_word_int }
+ \int_compare:nNnTF \l_iow_current_line_int
+ < \l_iow_target_length_int
+ { \iow_wrap_word_fits: }
+ { \iow_wrap_word_newline: }
+ \iow_wrap_loop:w
+ }
+% \end{macrocode}
+% If the word fits in the current line, add it to the line, preceded by
+% a space unless it is the first word of the line.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \iow_wrap_word_fits:
+ {
+ \bool_if:NTF \l_iow_line_start_bool
+ {
+ \bool_set_false:N \l_iow_line_start_bool
+ \tl_set_eq:NN \l_iow_current_line_tl \l_iow_current_word_tl
+ }
+ {
+ \tl_put_right:Nx \l_iow_current_line_tl
+ { ~ \l_iow_current_word_tl }
+ \int_incr:N \l_iow_current_line_int
+ }
+ }
+% \end{macrocode}
+% Otherwise, the current line is added to the result, with the run-on text.
+% The current word (and its length) are then put in the new line.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \iow_wrap_word_newline:
+ {
+ \tl_put_right:Nx \l_iow_wrapped_tl
+ { \l_iow_current_line_tl \\ }
+ \int_set_eq:NN \l_iow_current_line_int \l_iow_current_word_int
+ \tl_set_eq:NN \l_iow_current_line_tl \l_iow_current_word_tl
+ }
+% \end{macrocode}
+% Forced newlines are almost identical to those caused by overflow,
+% except that here the word is empty. And remember to continue the loop!
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \iow_wrap_newline:
+ {
+ \tl_put_right:Nx \l_iow_wrapped_tl
+ { \l_iow_current_line_tl \\ }
+ \int_zero:N \l_iow_current_line_int
+ \tl_clear:N \l_iow_current_line_tl
+ \bool_set_true:N \l_iow_line_start_bool
+ \iow_wrap_loop:w
+ }
+% \end{macrocode}
+% At the end, we simply save the last line (without the run-on text).
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \iow_wrap_end:
+ {
+ \tl_put_right:Nx \l_iow_wrapped_tl
+ { \l_iow_current_line_tl }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\str_length_skip_spaces:N}
+% \begin{macro}{\str_length_skip_spaces:n}
+% \begin{macro}{\str_length_loop:NNNNNNNNN}
+% The wrapping code requires to measure the number of character
+% in each word. This could be done with \cs{tl_length:n}, but
+% it is ten times faster (literally) to use the code below.
+% \begin{macrocode}
+\cs_new_nopar:Npn \str_length_skip_spaces:N
+ { \exp_args:No \str_length_skip_spaces:n }
+\cs_new:Npn \str_length_skip_spaces:n #1
+ {
+ \int_value:w \int_eval:w
+ \exp_after:wN \str_length_loop:NNNNNNNNN \tl_to_str:n {#1}
+ {X8}{X7}{X6}{X5}{X4}{X3}{X2}{X1}{X0} \q_stop
+ \int_eval_end:
+ }
+\cs_new:Npn \str_length_loop:NNNNNNNNN #1#2#3#4#5#6#7#8#9
+ {
+ \if_catcode:w X #9
+ \exp_after:wN \use_none_delimit_by_q_stop:w
+ \else:
+ 9 +
+ \exp_after:wN \str_length_loop:NNNNNNNNN
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Special characters for writing}
+%
+% \begin{macro}{\iow_newline:}
+% Global variable holding the character that forces a new line when
+% something is written to an output stream
+% \begin{macrocode}
+\cs_new_nopar:Npn \iow_newline: { ^^J }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\iow_char:N}
+% Function to write any escaped char to an output stream.
+% \begin{macrocode}
+\cs_new_eq:NN \iow_char:N \cs_to_str:N
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Reading input}
+%
+% \begin{macro}[pTF]{\ior_if_eof_p:N}
+% To test if some particular input stream is exhausted the following
+% conditional is provided. As the pool model means that closed
+% streams are undefined control sequences, the test has two parts.
+% \begin{macrocode}
+\prg_new_conditional:Nnn \ior_if_eof:N { p , T , F , TF }
+ {
+ \cs_if_exist:NTF #1
+ {
+ \if_eof:w #1
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+ { \prg_return_true: }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\ior_to:NN}
+% \begin{macro}{\ior_gto:NN}
+% And here we read from files.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \ior_to:NN #1#2
+ { \tex_read:D #1 to #2 }
+\cs_new_protected_nopar:Npn \ior_gto:NN #1#2
+ { \pref_global:D \tex_read:D #1 to #2 }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\ior_str_to:NN}
+% \begin{macro}{\ior_str_gto:NN}
+% Reading as strings is also a primitive wrapper.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \ior_str_to:NN #1#2
+ { \etex_readline:D #1 to #2 }
+\cs_new_protected_nopar:Npn \ior_str_gto:NN #1#2
+ { \pref_global:D \etex_readline:D #1 to #2 }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Deprecated functions}
+%
+% Deprecated on 2011-05-27, for removal by 2011-08-31.
+%
+% \begin{macro}{\iow_now_buffer_safe:Nn, \iow_now_buffer_safe:Nx}
+% This is much more easily done using the wrapping system: there is
+% an expansion there, so a bit of a hack is needed.
+% \begin{macrocode}
+\cs_new_protected:Npn \iow_now_buffer_safe:Nn #1#2
+ { \iow_wrap:xnnnN { \exp_not:n {#2} } { } \c_zero { } \iow_now:Nn #1 }
+\cs_new_protected:Npn \iow_now_buffer_safe:Nx #1#2
+ { \iow_wrap:xnnnN {#2} { } \c_zero { } \iow_now:Nn #1 }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\ior_new:N, \ior_new:c}
+% \begin{macro}{\iow_new:N, \iow_new:c}
+% As input--output operations are done using a stack, |new| operations seem
+% out-of-place. They are therefore set up just to gobble the input.
+% \begin{macrocode}
+\cs_new_eq:NN \ior_new:N \use_none:n
+\cs_new_eq:NN \ior_new:c \use_none:n
+\cs_new_eq:NN \iow_new:N \use_none:n
+\cs_new_eq:NN \iow_new:c \use_none:n
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\ior_open_streams:}
+% \begin{macro}{\iow_open_streams:}
+% Slightly misleading names.
+% \begin{macrocode}
+\cs_new_eq:NN \ior_open_streams: \ior_list_streams:
+\cs_new_eq:NN \iow_open_streams: \iow_list_streams:
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macrocode}
+%</initex|package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3keys.dtx b/Master/texmf-dist/source/latex/l3kernel/l3keys.dtx
new file mode 100644
index 00000000000..cbc1fb62a7d
--- /dev/null
+++ b/Master/texmf-dist/source/latex/l3kernel/l3keys.dtx
@@ -0,0 +1,1365 @@
+% \iffalse meta-comment
+%
+%% File: l3keys.dtx Copyright (C) 2009-2011 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 "expl3 bundle" (The Work in LPPL)
+%% and all files in that bundle must be distributed together.
+%%
+%% The released version of this bundle is available from CTAN.
+%%
+%% -----------------------------------------------------------------------
+%%
+%% The development version of the bundle can be found at
+%%
+%% http://www.latex-project.org/svnroot/experimental/trunk/
+%%
+%% for those people who are interested.
+%%
+%%%%%%%%%%%
+%% NOTE: %%
+%%%%%%%%%%%
+%%
+%% Snapshots taken from the repository represent work in progress and may
+%% not work or may contain conflicting material! We therefore ask
+%% people _not_ to put them into distributions, archives, etc. without
+%% prior consultation with the LaTeX3 Project.
+%%
+%% -----------------------------------------------------------------------
+%
+%<*driver|package>
+\RequirePackage{l3names}
+\GetIdInfo$Id: l3keys.dtx 2478 2011-06-19 21:34:23Z joseph $
+ {L3 Experimental key-value interfaces}
+%</driver|package>
+%<*driver>
+\documentclass[full]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3keys} package\\ Key--value interfaces^^A
+% \thanks{This file describes v\ExplFileVersion,
+% last revised \ExplFileDate.}^^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 \ExplFileDate}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% The key--value method is a popular system for creating large numbers
+% of settings for controlling function or package behaviour. For the
+% user, the system normally results in input of the form
+% \begin{verbatim}
+% \PackageControlMacro{
+% key-one = value one,
+% key-two = value two
+% }
+% \end{verbatim}
+% or
+% \begin{verbatim}
+% \PackageMacro[
+% key-one = value one,
+% key-two = value two
+% ]{argument}.
+% \end{verbatim}
+%
+% The high level functions here are intended as a method to create
+% key--value controls. Keys are themselves created using a key--value
+% interface, minimising the number of functions and arguments
+% required. Each key is created by setting one or more \emph{properties}
+% of the key:
+% \begin{verbatim}
+% \keys_define:nn { module }
+% {
+% key-one .code:n = code including parameter #1,
+% key-two .tl_set:N = \l_module_store_tl
+% }
+% \end{verbatim}
+% These values can then be set as with other key--value approaches:
+% \begin{verbatim}
+% \keys_set:nn { module }
+% {
+% key-one = value one,
+% key-two = value two
+% }
+% \end{verbatim}
+%
+% At a document level, \cs{keys_set:nn} will be used within a
+% document function, for example
+% \begin{verbatim}
+% \DeclareDocumentCommand \SomePackageSetup { m }
+% { \keys_set:nn { module } { #1 } }
+% \DeclareDocumentCommand \SomePackageMacro { o m }
+% {
+% \group_begin:
+% \keys_set:nn { module } { #1 }
+% % Main code for \SomePackageMacro
+% \group_end:
+% }
+% \end{verbatim}
+%
+% Key names may contain any tokens, as they are handled internally
+% using \cs{tl_to_str:n}. As will be discussed in
+% section~\ref{sec:subdivision}, it is suggested that the character
+% |/| is reserved for sub-division of keys into logical
+% groups. Functions and variables are \emph{not} expanded when creating
+% key names, and so
+% \begin{verbatim}
+% \tl_set:Nn \l_module_tmp_tl { key }
+% \keys_define:nn { module }
+% {
+% \l_module_tmp_tl .code:n = code
+% }
+% \end{verbatim}
+% will create a key called \cs{l_module_tmp_tl}, and not one called
+% \texttt{key}.
+%
+% \section{Creating keys}
+%
+% \begin{function}{\keys_define:nn}
+% \begin{syntax}
+% \cs{keys_define:nn} \Arg{module} \Arg{keyval list}
+% \end{syntax}
+% Parses the \meta{keyval list} and defines the keys listed there for
+% \meta{module}. The \meta{module} name should be a text value, but
+% there are no restrictions on the nature of the text. In practice the
+% \meta{module} should be chosen to be unique to the module in question
+% (unless deliberately adding keys to an existing module).
+%
+% The \meta{keyval list} should consist of one or more key names along
+% with an associated key \emph{property}. The properties of a key
+% determine how it acts. The individual properties are described
+% in the following text; a typical use of \cs{keys_define:nn} might
+% read
+% \begin{verbatim}
+% \keys_define:nn { mymodule }
+% {
+% keyname .code:n = Some~code~using~#1,
+% keyname .value_required:
+% }
+% \end{verbatim}
+% where the properties of the key begin from the |.| after the key
+% name.
+% \end{function}
+%
+% The various properties available take either no arguments at
+% all, or require exactly one argument. This is indicated in the
+% name of the property using an argument specification. In the following
+% discussion, each property is illustrated attached to an
+% arbitrary \meta{key}, which when used may be supplied with a
+% \meta{value}. All key \emph{definitions} are local.
+%
+% \begin{function}{.bool_set:N}
+% \begin{syntax}
+% \meta{key} .bool_set:N = \meta{boolean}
+% \end{syntax}
+% Defines \meta{key} to set \meta{boolean} to \meta{value} (which
+% must be either \texttt{true} or \texttt{false}). If the variable
+% does not exist, it will be created at the point that the key is
+% set up. The \meta{boolean} will be assigned locally.
+% \end{function}
+%
+% \begin{function}{.bool_gset:N}
+% \begin{syntax}
+% \meta{key} .bool_gset:N = \meta{boolean}
+% \end{syntax}
+% Defines \meta{key} to set \meta{boolean} to \meta{value} (which
+% must be either \texttt{true} or \texttt{false}). If the variable
+% does not exist, it will be created at the point that the key is
+% set up. The \meta{boolean} will be assigned globally.
+% \end{function}
+%
+% \begin{function}{.choice:}
+% \begin{syntax}
+% \meta{key} .choice:
+% \end{syntax}
+% Sets \meta{key} to act as a multiple choice key. Each valid choice
+% for \meta{key} must then be created, as discussed in
+% section~\ref{sec:choice}.
+% \end{function}
+%
+% \begin{function}{.choice_code:n, .choice_code:x}
+% \begin{syntax}
+% \meta{key} .choice_code:n = \meta{code}
+% \end{syntax}
+% Stores \meta{code} for use when \texttt{.generate_choices:n} creates
+% one or more choice sub-keys of the current key. Inside \meta{code},
+% \cs{l_keys_choice_tl} will expand to the name of the choice made, and
+% \cs{l_keys_choice_int} will be the position of the choice in the list
+% given to \texttt{.generate_choices:n}. Choices are discussed in
+% detail in section~\ref{sec:choice}.
+% \end{function}
+%
+% \begin{function}{.code:n, .code:x}
+% \begin{syntax}
+% \meta{key} .code:n = \meta{code}
+% \end{syntax}
+% Stores the \meta{code} for execution when \meta{key} is used. The
+% The \meta{code} can include one parameter ("#1"), which will be the
+% \meta{value} given for the \meta{key}. The \texttt{x}-type variant
+% will expand \meta{code} at the point where the \meta{key} is
+% created.
+% \end{function}
+%
+% \begin{function}{.default:n, .default:V}
+% \begin{syntax}
+% \meta{key} .default:n = \meta{default}
+% \end{syntax}
+% Creates a \meta{default} value for \meta{key}, which is used if no
+% value is given. This will be used if only the key name is given,
+% but not if a blank \meta{value} is given:
+% \begin{verbatim}
+% \keys_define:nn { module }
+% {
+% key .code:n = Hello~#1,
+% key .default:n = World
+% }
+% \keys_set:nn { module }
+% {
+% key = Fred, % Prints 'Hello Fred'
+% key, % Prints 'Hello World'
+% key = , % Prints 'Hello '
+% }
+% \end{verbatim}
+% \end{function}
+%
+% \begin{function}{.dim_set:N, .dim_set:c}
+% \begin{syntax}
+% \meta{key} .dim_set:N = \meta{dimension}
+% \end{syntax}
+% Defines \meta{key} to set \meta{dimension} to \meta{value} (which
+% must a dimension expression). If the variable does not exist, it
+% will be created at the point that the key is set up. The
+% \meta{dimension} will be assigned locally.
+% \end{function}
+%
+% \begin{function}{.dim_gset:N, .dim_gset:c}
+% \begin{syntax}
+% \meta{key} .dim_gset:N = \meta{dimension}
+% \end{syntax}
+% Defines \meta{key} to set \meta{dimension} to \meta{value} (which
+% must a dimension expression). If the variable does not exist, it
+% will be created at the point that the key is set up. The
+% \meta{dimension} will be assigned globally.
+% \end{function}
+%
+% \begin{function}{.fp_set:N, .fp_set:c}
+% \begin{syntax}
+% \meta{key} .fp_set:N = \meta{floating point}
+% \end{syntax}
+% Defines \meta{key} to set \meta{floating point} to \meta{value}
+% (which must a integer expression). If the variable does not exist,
+% it will be created at the point that the key is set up. The
+% \meta{integer} will be assigned locally.
+% \end{function}
+%
+% \begin{function}{.fp_gset:N, .fp_gset:c}
+% \begin{syntax}
+% \meta{key} .fp_gset:N = \meta{floating point}
+% \end{syntax}
+% Defines \meta{key} to set \meta{floating-point} to \meta{value}
+% (which must a integer expression). If the variable does not exist,
+% it will be created at the point that the key is set up. The
+% \meta{integer} will be assigned globally.
+% \end{function}
+%
+% \begin{function}{.generate_choices:n}
+% \begin{syntax}
+% \meta{key} .generate_choices:n = \Arg{list}
+% \end{syntax}
+% This property will mark \meta{key} as a multiple choice key,
+% and will use the \meta{list} to define the choices. The \meta{list}
+% should consist of a comma-separated list of choice names. Each
+% choice will be set up to execute \meta{code} as set using
+% \texttt{.choice_code:n} (or \texttt{.choice_code:x}). Choices are
+% discussed in detail in section~\ref{sec:choice}.
+% \end{function}
+%
+% \begin{function}{.int_set:N, .int_set:c}
+% \begin{syntax}
+% \meta{key} .int_set:N = \meta{integer}
+% \end{syntax}
+% Defines \meta{key} to set \meta{integer} to \meta{value} (which
+% must a integer expression). If the variable does not exist, it
+% will be created at the point that the key is set up. The
+% \meta{integer} will be assigned locally.
+% \end{function}
+%
+% \begin{function}{.int_gset:N, .int_gset:c}
+% \begin{syntax}
+% \meta{key} .int_gset:N = \meta{integer}
+% \end{syntax}
+% Defines \meta{key} to set \meta{integer} to \meta{value} (which
+% must a integer expression). If the variable does not exist, it
+% will be created at the point that the key is set up. The
+% \meta{integer} will be assigned globally.
+% \end{function}
+%
+% \begin{function}{.meta:n, .meta:x}
+% \begin{syntax}
+% \meta{key} .meta:n = \Arg{keyval list}
+% \end{syntax}
+% Makes \meta{key} a meta-key, which will set \meta{keyval list} in
+% one go. If \meta{key} is given with a value at the time the key
+% is used, then the value will be passed through to the subsidiary
+% \meta{keys} for processing (as |#1|).
+% \end{function}
+%
+% \begin{function}{.skip_set:N, .skip_set:c}
+% \begin{syntax}
+% \meta{key} .skip_set:N = \meta{skip}
+% \end{syntax}
+% Defines \meta{key} to set \meta{skip} to \meta{value} (which
+% must a skip expression). If the variable does not exist, it
+% will be created at the point that the key is set up. The
+% \meta{skip} will be assigned locally.
+% \end{function}
+%
+% \begin{function}{.skip_gset:N, .skip_gset:c}
+% \begin{syntax}
+% \meta{key} .skip_gset:N = \meta{skip}
+% \end{syntax}
+% Defines \meta{key} to set \meta{skip} to \meta{value} (which
+% must a skip expression). If the variable does not exist, it
+% will be created at the point that the key is set up. The
+% \meta{skip} will be assigned globally.
+% \end{function}
+%
+% \begin{function}{.tl_set:N, .tl_set:c}
+% \begin{syntax}
+% \meta{key} .tl_set:N = \meta{token list variable}
+% \end{syntax}
+% Defines \meta{key} to set \meta{token list variable} to \meta{value}.
+% If the variable does not exist, it will be created at the point that
+% the key is set up. The \meta{token list variable} will be assigned
+% locally.
+% \end{function}
+%
+% \begin{function}{.tl_gset:N, .tl_gset:c}
+% \begin{syntax}
+% \meta{key} .tl_gset:N = \meta{token list variable}
+% \end{syntax}
+% Defines \meta{key} to set \meta{token list variable} to \meta{value}.
+% If the variable does not exist, it will be created at the point that
+% the key is set up. The \meta{token list variable} will be assigned
+% globally.
+% \end{function}
+%
+% \begin{function}{.tl_set_x:N, .tl_set_x:c}
+% \begin{syntax}
+% \meta{key} .tl_set_x:N = \meta{token list variable}
+% \end{syntax}
+% Defines \meta{key} to set \meta{token list variable} to \meta{value},
+% which will be subjected to an \texttt{x}-type expansion
+% (\emph{i.e.}~using \cs{tl_set:Nx}). If the variable does not exist,
+% it will be created at the point that the key is set up. The
+% \meta{token list variable} will be assigned locally.
+% \end{function}
+%
+% \begin{function}{.tl_gset_x:N, .tl_gset_x:c}
+% \begin{syntax}
+% \meta{key} .tl_gset_x:N = \meta{token list variable}
+% \end{syntax}
+% Defines \meta{key} to set \meta{token list variable} to \meta{value},
+% which will be subjected to an \texttt{x}-type expansion
+% (\emph{i.e.}~using \cs{tl_set:Nx}). If the variable does not exist,
+% it will be created at the point that the key is set up. The
+% \meta{token list variable} will be assigned globally.
+% \end{function}
+%
+% \begin{function}{.value_forbidden:}
+% \begin{syntax}
+% \meta{key} .value_forbidden:
+% \end{syntax}
+% Specifies that \meta{key} cannot receive a \meta{value} when used.
+% If a \meta{value} is given then an error will be issued.
+% \end{function}
+%
+% \begin{function}{.value_required:}
+% \begin{syntax}
+% \meta{key} .value_required:
+% \end{syntax}
+% Specifies that \meta{key} must receive a \meta{value} when used.
+% If a \meta{value} is not given then an error will be issued.
+% \end{function}
+%
+% \section{Sub-dividing keys}
+% \label{sec:subdivision}
+%
+% When creating large numbers of keys, it may be desirable to divide
+% them into several sub-groups for a given module. This can be achieved
+% either by adding a sub-division to the module name:
+% \begin{verbatim}
+% \keys_define:nn { module / subgroup }
+% { key .code:n = code }
+% \end{verbatim}
+% or to the key name:
+% \begin{verbatim}
+% \keys_define:nn { module }
+% { subgroup / key .code:n = code }
+% \end{verbatim}
+% As illustrated, the best choice of token for sub-dividing keys in
+% this way is |/|. This is because of the method that is
+% used to represent keys internally. Both of the above code fragments
+% set the same key, which has full name \texttt{module/subgroup/key}.
+%
+% As will be illustrated in the next section, this subdivision is
+% particularly relevant to making multiple choices.
+%
+% \section{Multiple choice keys}
+% \label{sec:choice}
+%
+% Multiple choices are created by setting the \texttt{.choice:}
+% property:
+% \begin{verbatim}
+% \keys_define:nn { module }
+% { key .choice: }
+% \end{verbatim}
+% For keys which are set up as choices, the valid choices are generated
+% by creating sub-keys of the choice key. This can be carried out in
+% two ways.
+%
+% In many cases, choices execute similar code which is dependant only
+% on the name of the choice or the position of the choice in the
+% list of choices. Here, the keys can share the same code, and can
+% be rapidly created using the \texttt{.choice_code:n} and
+% \texttt{.generate_choices:n} properties:
+% \begin{verbatim}
+% \keys_define:nn { module }
+% {
+% key .choice_code:n =
+% {
+% You~gave~choice~'\int_use:N \l_keys_choice_tl',~
+% which~is~in~position~
+% \int_use:N \l_keys_choice_int \c_space_tl
+% in~the~list.
+% },
+% key .generate_choices:n =
+% { choice-a, choice-b, choice-c }
+% }
+% \end{verbatim}
+% Following common computing practice, \cs{l_keys_choice_int} is
+% indexed from $0$ (as an offset), so that the value of
+% \cs{l_keys_choice_int} for the first choice in a list will be
+% zero.
+%
+% \begin{variable}{\l_keys_choice_int, \l_keys_choice_tl}
+% Inside the code block for a choice generated using
+% \texttt{.generate_choice:}, the variables \cs{l_keys_choice_tl} and
+% \cs{l_keys_choice_int} are available to indicate the name of the
+% current choice, and its position in the comma list. The position
+% is indexed from $0$.
+% \end{variable}
+%
+% On the other hand, it is sometimes useful to create choices which
+% use entirely different code from one another. This can be achieved
+% by setting the \texttt{.choice:} property of a key, then manually
+% defining sub-keys.
+% \begin{verbatim}
+% \keys_define:nn { module }
+% {
+% key .choice:n,
+% key / choice-a .code:n = code-a,
+% key / choice-b .code:n = code-b,
+% key / choice-c .code:n = code-c,
+% }
+%\end{verbatim}
+%
+% It is possible to mix the two methods, but manually-created choices
+% should \emph{not} use \cs{l_keys_choice_tl} or \cs{l_keys_choice_int}.
+% These variables do not have defined behaviour when used outside of
+% code created using \texttt{.generate_choices:n}
+% (\emph{i.e.}~anything might happen).
+%
+% \section{Setting keys}
+%
+% \begin{function}{\keys_set:nn, \keys_set:nV, \keys_set:nv, \keys_set:no}
+% \begin{syntax}
+% \cs{keys_set:nn} \Arg{module} \Arg{keyval list}
+% \end{syntax}
+% Parses the \meta{keyval list}, and sets those keys which are defined
+% for \meta{module}. The behaviour on finding an unknown key can be set
+% by defining a special \texttt{unknown} key: this will be illustrated
+% later. In contrast to \cs{keys_define:nn}, this function does check
+% category codes and ignore spaces, and is therefore suitable for user
+% input.
+% \end{function}
+%
+% If a key is not known, \cs{keys_set:nn} will look for a special
+% \texttt{unknown} key for the same module. This mechanism can be
+% used to create new keys from user input.
+% \begin{verbatim}
+% \keys_define:nn { module }
+% {
+% unknown .code:n =
+% You~tried~to~set~key~'\l_keys_key_tl'~to~'#1'.
+% }
+%\end{verbatim}
+%
+% \begin{variable}{\l_keys_key_tl}
+% When processing an unknown key, the name of the key is available
+% as \cs{l_keys_key_tl}. Note that this will have been processed
+% using \cs{tl_to_str:n}. The value passed to the key (if any) is
+% available as the macro parameter |#1|.
+% \end{variable}
+%
+% \begin{variable}{\l_keys_path_tl}
+% When processing an unknown key, the path of the key used is available
+% as \cs{l_keys_path_tl}. Note that this will have been processed
+% using \cs{tl_to_str:n}.
+% \end{variable}
+%
+% \section{Utility functions for keys}
+%
+% \begin{function}[EXP,pTF]{\keys_if_exist:nn}
+% \begin{syntax}
+% \cs{keys_if_exist:nn} \meta{module} \meta{key}
+% \cs{keys_if_exist:nn} \meta{module} \meta{key}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{key} exists for \meta{module}, \emph{i.e.}~if any code
+% has been defined for \meta{key}.
+% The branching versions then leave either \meta{true code} or
+% \meta{false code} in the input stream, as appropriate to the truth
+% of the test and the variant of the function chosen. The logical
+% truth of the test is left in the input stream by the predicate
+% version.
+% \end{function}
+%
+% \begin{function}{\keys_show:nn}
+% \begin{syntax}
+% \cs{keys_show:nn} \Arg{module} \Arg{key}
+% \end{syntax}
+% Shows the function which is used to actually implement a
+% \meta{key} for a \meta{module}.
+% \end{function}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3keys} Implementation}
+%
+% \begin{macrocode}
+%<*initex|package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*package>
+\ProvidesExplPackage
+ {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
+\package_check_loaded_expl:
+%</package>
+% \end{macrocode}
+%
+% \subsection{Constants and variables}
+%
+% \begin{variable}{\c_keys_code_root_tl, \c_keys_vars_root_tl}
+% The prefixes for the code and variables of the keys themselves.
+% \begin{macrocode}
+\tl_const:Nn \c_keys_code_root_tl { key~code~>~ }
+\tl_const:Nn \c_keys_vars_root_tl { key~var~>~ }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\c_keys_props_root_tl}
+% The prefix for storing properties.
+% \begin{macrocode}
+\tl_const:Nn \c_keys_props_root_tl { key~prop~>~ }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\c_keys_value_forbidden_tl, \c_keys_value_required_tl}
+% Two marker token lists.
+% \begin{macrocode}
+\tl_const:Nn \c_keys_value_forbidden_tl { forbidden }
+\tl_const:Nn \c_keys_value_required_tl { required }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_keys_choice_int, \l_keys_choices_tl}
+% Publicly accessible data on which choice is being used when several
+% are generated as a set.
+% \begin{macrocode}
+\int_new:N \l_keys_choice_int
+\tl_new:N \l_keys_choices_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_keys_key_tl}
+% The name of a key itself: needed when setting keys.
+% \begin{macrocode}
+\tl_new:N \l_keys_key_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_keys_module_tl}
+% The module for an entire set of keys.
+% \begin{macrocode}
+\tl_new:N \l_keys_module_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_keys_no_value_bool}
+% A marker is needed internally to show if only a key or a key plus a
+% value was seen: this is recorded here.
+% \begin{macrocode}
+\bool_new:N \l_keys_no_value_bool
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_keys_path_tl}
+% The \enquote{path} of the current key is stored here: this is
+% available to the programmer and so is public.
+% \begin{macrocode}
+\tl_new:N \l_keys_path_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_keys_property_tl}
+% The \enquote{property} begin set for a key at definition time is
+% stored here.
+% \begin{macrocode}
+\tl_new:N \l_keys_property_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_keys_value_tl}
+% The value given for a key: may be empty if no value was given.
+% \begin{macrocode}
+\tl_new:N \l_keys_value_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \subsection{The key defining mechanism}
+%
+% \begin{macro}{\keys_define:nn}
+% \begin{macro}[aux]{\keys_define_aux:nnn, \keys_define_aux:onn}
+% The public function for definitions is just a wrapper for the lower
+% level mechanism, more or less. The outer function is designed to
+% keep a track of the current module, to allow safe nesting.
+% \begin{macrocode}
+\cs_new_protected:Npn \keys_define:nn
+ { \keys_define_aux:onn \l_keys_module_tl }
+\cs_new_protected:Npn \keys_define_aux:nnn #1#2#3
+ {
+ \tl_set:Nx \l_keys_module_tl { \tl_to_str:n {#2} }
+ \keyval_parse:NNn \keys_define_elt:n \keys_define_elt:nn {#3}
+ \tl_set:Nn \l_keys_module_tl {#1}
+ }
+\cs_generate_variant:Nn \keys_define_aux:nnn { o }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[int]{\keys_define_elt:n}
+% \begin{macro}[int]{\keys_define_elt:nn}
+% \begin{macro}[aux]{\keys_define_elt_aux:nn}
+% The outer functions here record whether a value was given and then
+% converge on a common internal mechanism. There is first a search for
+% a property in the current key name, then a check to make sure it is
+% known before the code hands off to the next step.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \keys_define_elt:n #1
+ {
+ \bool_set_true:N \l_keys_no_value_bool
+ \keys_define_elt_aux:nn {#1} { }
+ }
+\cs_new_protected:Npn \keys_define_elt:nn #1#2
+ {
+ \bool_set_false:N \l_keys_no_value_bool
+ \keys_define_elt_aux:nn {#1} {#2}
+ }
+\cs_new_protected:Npn \keys_define_elt_aux:nn #1#2 {
+ \keys_property_find:n {#1}
+ \cs_if_exist:cTF { \c_keys_props_root_tl \l_keys_property_tl }
+ { \keys_define_key:n {#2} }
+ {
+ \msg_kernel_error:nnxx { keys } { property-unknown }
+ { \l_keys_property_tl } { \l_keys_path_tl }
+ }
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[int]{\keys_property_find:n}
+% \begin{macro}[aux]{\keys_property_find_aux:w}
+% Searching for a property means finding the last |.| in the input,
+% and storing the text before and after it. Everything is turned into
+% strings, so there is no problem using an \texttt{x}-type expansion.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \keys_property_find:n #1
+ {
+ \tl_set:Nx \l_keys_path_tl { \l_keys_module_tl / }
+ \tl_if_in:nnTF {#1} { . }
+ { \keys_property_find_aux:w #1 \q_stop }
+ { \msg_kernel_error:nnx { keys } { key-no-property } {#1} }
+ }
+\cs_new_protected_nopar:Npn \keys_property_find_aux:w #1 . #2 \q_stop
+ {
+ \tl_set:Nx \l_keys_path_tl { \l_keys_path_tl \tl_to_str:n {#1} }
+ \tl_if_in:nnTF {#2} { . }
+ {
+ \tl_set:Nx \l_keys_path_tl { \l_keys_path_tl . }
+ \keys_property_find_aux:w #2 \q_stop
+ }
+ { \tl_set:Nn \l_keys_property_tl { . #2 } }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[int]{\keys_define_key:n}
+% \begin{macro}[aux]{\keys_define_key_aux:w}
+% Two possible cases. If there is a value for the key, then just use
+% the function. If not, then a check to make sure there is no need for
+% a value with the property. If there should be one then complain,
+% otherwise execute it. There is no need to check for a |:| as if it
+% is missing the earlier tests will have failed.
+% \begin{macrocode}
+\cs_new_protected:Npn \keys_define_key:n #1
+ {
+ \bool_if:NTF \l_keys_no_value_bool
+ {
+ \exp_after:wN \keys_define_key_aux:w
+ \l_keys_property_tl \q_stop
+ { \use:c { \c_keys_props_root_tl \l_keys_property_tl } }
+ {
+ \msg_kernel_error:nnxx { keys }
+ { property-requires-value } { \l_keys_property_tl }
+ { \l_keys_path_tl }
+ }
+ }
+ { \use:c { \c_keys_props_root_tl \l_keys_property_tl } {#1} }
+ }
+\cs_new_protected:Npn \keys_define_key_aux:w #1 : #2 \q_stop
+ { \tl_if_empty:nTF {#2} }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Turning properties into actions}
+%
+% \begin{macro}[int]{\keys_bool_set:NN}
+% Boolean keys are really just choices, but all done by hand. The
+% second argument here is the scope: either empty or \texttt{g} for
+% global.
+% \begin{macrocode}
+\cs_new_nopar:Npn \keys_bool_set:NN #1#2
+ {
+ \cs_if_exist:NF #1 { \bool_new:N #1 }
+ \keys_choice_make:
+ \keys_cmd_set:nx { \l_keys_path_tl / true }
+ { \exp_not:c { bool_ #2 set_true:N } \exp_not:N #1 }
+ \keys_cmd_set:nx { \l_keys_path_tl / false }
+ { \exp_not:c { bool_ #2 set_false:N } \exp_not:N #1 }
+ \keys_cmd_set:nn { \l_keys_path_tl / unknown }
+ {
+ \msg_kernel_error:nnx { keys } { boolean-values-only }
+ { \l_keys_key_tl }
+ }
+ \keys_default_set:n { true }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\keys_choice_make:}
+% To make a choice from a key, two steps: set the code, and set the
+% unknown key.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \keys_choice_make:
+ {
+ \keys_cmd_set:nn { \l_keys_path_tl }
+ { \keys_choice_find:n {##1} }
+ \keys_cmd_set:nn { \l_keys_path_tl / unknown }
+ {
+ \msg_kernel_error:nnxx { keys } { choice-unknown }
+ { \l_keys_path_tl } {##1}
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\keys_choices_generate:n}
+% \begin{macro}[aux]{\keys_choices_generate_aux:n}
+% Creating multiple-choices means setting up the \enquote{indicator}
+% code, then applying whatever the user wanted.
+% \begin{macrocode}
+\cs_new_protected:Npn \keys_choices_generate:n #1
+ {
+ \cs_if_exist:cTF
+ { \c_keys_vars_root_tl \l_keys_path_tl .choice~code }
+ {
+ \keys_choice_make:
+ \int_zero:N \l_keys_choice_int
+ \clist_map_function:nN {#1} \keys_choices_generate_aux:n
+ }
+ {
+ \msg_kernel_error:nnx { keys }
+ { generate-choices-before-code } { \l_keys_path_tl }
+ }
+ }
+\cs_new_protected_nopar:Npn \keys_choices_generate_aux:n #1
+ {
+ \keys_cmd_set:nx { \l_keys_path_tl / #1 }
+ {
+ \exp_not:n { \tl_set:Nn \l_keys_choice_tl } {#1}
+ \exp_not:n { \int_set:Nn \l_keys_choice_int }
+ { \int_use:N \l_keys_choice_int }
+ \exp_not:v
+ { \c_keys_vars_root_tl \l_keys_path_tl .choice~code }
+ }
+ \int_incr:N \l_keys_choice_int
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[int]{\keys_choice_code_store:x}
+% The code for making multiple choices is stored in a token list.
+% \begin{macrocode}
+\cs_new_protected:Npn \keys_choice_code_store:x #1
+ {
+ \cs_if_exist:cF
+ { \c_keys_vars_root_tl \l_keys_path_tl .choice~code }
+ {
+ \tl_new:c
+ { \c_keys_vars_root_tl \l_keys_path_tl .choice~code }
+ }
+ \tl_set:cx { \c_keys_vars_root_tl \l_keys_path_tl .choice~code }
+ {#1}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\keys_cmd_set:nn, \keys_cmd_set:nx}
+% \begin{macro}[aux]{\keys_cmd_set_aux:n}
+% Creating a new command means tidying up the properties and then making
+% the internal function which actually does the work.
+% \begin{macrocode}
+\cs_new_protected:Npn \keys_cmd_set:nn #1#2
+ {
+ \keys_cmd_set_aux:n {#1}
+ \cs_set:cpn { \c_keys_code_root_tl #1 } ##1 {#2}
+ }
+\cs_new_protected:Npn \keys_cmd_set:nx #1#2
+ {
+ \keys_cmd_set_aux:n {#1}
+ \cs_set:cpx { \c_keys_code_root_tl #1 } ##1 {#2}
+ }
+\cs_new_protected_nopar:Npn \keys_cmd_set_aux:n #1
+ {
+ \tl_clear_new:c { \c_keys_vars_root_tl #1 .default }
+ \tl_set:cn { \c_keys_vars_root_tl #1 .default } { \q_no_value }
+ \tl_clear_new:c { \c_keys_vars_root_tl #1 .req }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[int]{\keys_default_set:n, \keys_default_set:V}
+% Setting a default value is easy.
+% \begin{macrocode}
+\cs_new_protected:Npn \keys_default_set:n #1
+ { \tl_set:cn { \c_keys_vars_root_tl \l_keys_path_tl .default } {#1} }
+\cs_generate_variant:Nn \keys_default_set:n { V }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\keys_meta_make:n, \keys_meta_make:x}
+% To create a meta-key, simply set up to pass data through.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \keys_meta_make:n #1
+ {
+ \exp_args:NNo \keys_cmd_set:nn \l_keys_path_tl
+ { \exp_after:wN \keys_set:nn \exp_after:wN { \l_keys_module_tl } {#1} }
+ }
+\cs_new_protected_nopar:Npn \keys_meta_make:x #1
+ {
+ \keys_cmd_set:nx { \l_keys_path_tl }
+ { \exp_not:N \keys_set:nn { \l_keys_module_tl } {#1} }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\keys_value_requirement:n}
+% Values can be required or forbidden by having the appropriate marker
+% set.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \keys_value_requirement:n #1
+ {
+ \tl_set_eq:cc
+ { \c_keys_vars_root_tl \l_keys_path_tl .req }
+ { c_keys_value_ #1 _tl }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\keys_variable_set:NnNN, \keys_variable_set:cnNN}
+% \begin{macro}[int]{\keys_variable_set:NnN, \keys_variable_set:cnN}
+% Setting a variable takes the type and scope separately so that
+% it is easy to make a new variable if needed. The three-argument
+% version is set up so that the use of |{ }| as an \texttt{N}-type
+% variable is only done once!
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \keys_variable_set:NnNN #1#2#3#4
+ {
+ \cs_if_exist:NF #1 { \use:c { #2 _new:N } #1 }
+ \keys_cmd_set:nx { \l_keys_path_tl }
+ { \exp_not:c { #2 _ #3 set:N #4 } \exp_not:N #1 {##1} }
+ }
+\cs_new_protected_nopar:Npn \keys_variable_set:NnN #1#2#3
+ { \keys_variable_set:NnNN #1 {#2} { } #3 }
+\cs_generate_variant:Nn \keys_variable_set:NnNN { c }
+\cs_generate_variant:Nn \keys_variable_set:NnN { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Creating key properties}
+%
+% The key property functions are all wrappers for internal functions,
+% meaning that things stay readable and can also be altered later on.
+%
+% \begin{macro}{.bool_set:N}
+% \begin{macro}{.bool_gset:N}
+% One function for this.
+% \begin{macrocode}
+\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .bool_set:N } #1
+ { \keys_bool_set:NN #1 { } }
+\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .bool_gset:N } #1
+ { \keys_bool_set:NN #1 g }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{.choice:}
+% Making a choice is handled internally, as it is also needed by
+% \texttt{.generate_choices:n}.
+% \begin{macrocode}
+\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .choice: }
+ { \keys_choice_make: }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{.code:n, .code:x}
+% Creating code is simply a case of passing through to the underlying
+% \texttt{set} function.
+% \begin{macrocode}
+\cs_new_protected:cpn { \c_keys_props_root_tl .code:n } #1
+ { \keys_cmd_set:nn { \l_keys_path_tl } {#1} }
+\cs_new_protected:cpn { \c_keys_props_root_tl .code:x } #1
+ { \keys_cmd_set:nx { \l_keys_path_tl } {#1} }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{.choice_code:n, .choice_code:x}
+% Storing the code for choices, using \cs{exp_not:n} to avoid needing
+% two internal functions.
+% \begin{macrocode}
+\cs_new_protected:cpn { \c_keys_props_root_tl .choice_code:n } #1
+ { \keys_choice_code_store:x { \exp_not:n {#1} } }
+\cs_new_protected:cpn { \c_keys_props_root_tl .choice_code:x } #1
+ { \keys_choice_code_store:x {#1} }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{.default:n, .default:V}
+% Expansion is left to the internal functions.
+% \begin{macrocode}
+\cs_new_protected:cpn { \c_keys_props_root_tl .default:n } #1
+ { \keys_default_set:n {#1} }
+\cs_new_protected:cpn { \c_keys_props_root_tl .default:V } #1
+ { \keys_default_set:V #1 }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{.dim_set:N, .dim_set:c}
+% \begin{macro}{.dim_gset:N, .dim_gset:c}
+% Setting a variable is very easy: just pass the data along.
+% \begin{macrocode}
+\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .dim_set:N } #1
+ { \keys_variable_set:NnN #1 { dim } n }
+\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .dim_set:c } #1
+ { \keys_variable_set:cnN {#1} { dim } n }
+\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .dim_gset:N } #1
+ { \keys_variable_set:NnNN #1 { dim } g n }
+\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .dim_gset:c } #1
+ { \keys_variable_set:cnNN {#1} { dim } g n }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{.fp_set:N, .fp_set:c}
+% \begin{macro}{.fp_gset:N, .fp_gset:c}
+% Setting a variable is very easy: just pass the data along.
+% \begin{macrocode}
+\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .fp_set:N } #1
+ { \keys_variable_set:NnN #1 { fp } n }
+\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .fp_set:c } #1
+ { \keys_variable_set:cnN {#1} { fp } n }
+\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .fp_gset:N } #1
+ { \keys_variable_set:NnNN #1 { fp } g n }
+\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .fp_gset:c } #1
+ { \keys_variable_set:cnNN {#1} { fp } g n }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{.generate_choices:n}
+% Making choices is easy.
+% \begin{macrocode}
+\cs_new_protected:cpn { \c_keys_props_root_tl .generate_choices:n } #1
+ { \keys_choices_generate:n {#1} }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{.int_set:N, .int_set:c}
+% \begin{macro}{.int_gset:N, .int_gset:c}
+% Setting a variable is very easy: just pass the data along.
+% \begin{macrocode}
+\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .int_set:N } #1
+ { \keys_variable_set:NnN #1 { int } n }
+\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .int_set:c } #1
+ { \keys_variable_set:cnN {#1} { int } n }
+\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .int_gset:N } #1
+ { \keys_variable_set:NnNN #1 { int } g n }
+\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .int_gset:c } #1
+ { \keys_variable_set:cnNN {#1} { int } g n }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+%\begin{macro}{.meta:n, .meta:x}
+% Making a meta is handled internally.
+% \begin{macrocode}
+\cs_new_protected:cpn { \c_keys_props_root_tl .meta:n } #1
+ { \keys_meta_make:n {#1} }
+\cs_new_protected:cpn { \c_keys_props_root_tl .meta:x } #1
+ { \keys_meta_make:x {#1} }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{.skip_set:N, .skip_set:c}
+% \begin{macro}{.skip_gset:N, .skip_gset:c}
+% Setting a variable is very easy: just pass the data along.
+% \begin{macrocode}
+\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .skip_set:N } #1
+ { \keys_variable_set:NnN #1 { skip } n }
+\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .skip_set:c } #1
+ { \keys_variable_set:cnN {#1} { skip } n }
+\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .skip_gset:N } #1
+ { \keys_variable_set:NnNN #1 { skip } g n }
+\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .skip_gset:c } #1
+ { \keys_variable_set:cnNN {#1} { skip } g n }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+%
+% \begin{macro}{.tl_set:N, .tl_set:c}
+% \begin{macro}{.tl_gset:N, .tl_gset:c}
+% \begin{macro}{.tl_set_x:N, .tl_set_x:c}
+% \begin{macro}{.tl_gset_x:N, .tl_gset_x:c}
+% Setting a variable is very easy: just pass the data along.
+% \begin{macrocode}
+\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .tl_set:N } #1
+ { \keys_variable_set:NnN #1 { tl } n }
+\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .tl_set:c } #1
+ { \keys_variable_set:cnN {#1} { tl } n }
+\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .tl_set_x:N } #1
+ { \keys_variable_set:NnN #1 { tl } x }
+\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .tl_set_x:c } #1
+ { \keys_variable_set:cnN {#1} { tl } x }
+\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .tl_gset:N } #1
+ { \keys_variable_set:NnNN #1 { tl } g n }
+\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .tl_gset:c } #1
+ { \keys_variable_set:cnNN {#1} { tl } g n }
+\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .tl_gset_x:N } #1
+ { \keys_variable_set:NnNN #1 { tl } g x }
+\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .tl_gset_x:c } #1
+ { \keys_variable_set:cnNN {#1} { tl } g x }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{.value_forbidden:}
+% \begin{macro}{.value_required:}
+% These are very similar, so both call the same function.
+% \begin{macrocode}
+\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .value_forbidden: }
+ { \keys_value_requirement:n { forbidden } }
+\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .value_required: }
+ { \keys_value_requirement:n { required } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Setting keys}
+%
+% \begin{macro}{\keys_set:nn, \keys_set:nV, \keys_set:nv, \keys_set:no}
+% \begin{macro}[aux]{\keys_set_aux:nnn, \keys_set_aux:onn}
+% A simple wrapper again.
+% \begin{macrocode}
+\cs_new_protected:Npn \keys_set:nn
+ { \keys_set_aux:onn { \l_keys_module_tl } }
+\cs_new_protected:Npn \keys_set_aux:nnn #1#2#3
+ {
+ \tl_set:Nn \l_keys_module_tl {#2}
+ \keyval_parse:NNn \keys_set_elt:n \keys_set_elt:nn {#3}
+ \tl_set:Nn \l_keys_module_tl {#1}
+ }
+\cs_generate_variant:Nn \keys_set:nn { nV , nv , no }
+\cs_generate_variant:Nn \keys_set_aux:nnn { o }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[int]{\keys_set_elt:n, \keys_set_elt:nn}
+% \begin{macro}[aux]{\keys_set_elt_aux:nn}
+% A shared system once again. First, set the current path and add a
+% default if needed. There are then checks to see if the a value is
+% required or forbidden. If everything passes, move on to execute the
+% code.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \keys_set_elt:n #1
+ {
+ \bool_set_true:N \l_keys_no_value_bool
+ \keys_set_elt_aux:nn {#1} { }
+ }
+\cs_new_protected:Npn \keys_set_elt:nn #1#2
+ {
+ \bool_set_false:N \l_keys_no_value_bool
+ \keys_set_elt_aux:nn {#1} {#2}
+ }
+\cs_new_protected:Npn \keys_set_elt_aux:nn #1#2
+ {
+ \tl_set:Nx \l_keys_key_tl { \tl_to_str:n {#1} }
+ \tl_set:Nx \l_keys_path_tl { \l_keys_module_tl / \l_keys_key_tl }
+ \keys_value_or_default:n {#2}
+ \bool_if:nTF
+ {
+ \keys_if_value_p:n { required } &&
+ \l_keys_no_value_bool
+ }
+ {
+ \msg_kernel_error:nnx { keys } { value-required }
+ { \l_keys_path_tl }
+ }
+ {
+ \bool_if:nTF
+ {
+ \keys_if_value_p:n { forbidden } &&
+ ! \l_keys_no_value_bool
+ }
+ {
+ \msg_kernel_error:nnxx { keys } { value-forbidden }
+ { \l_keys_path_tl } { \l_keys_value_tl }
+ }
+ { \keys_execute: }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[int]{\keys_value_or_default:n}
+% If a value is given, return it as |#1|, otherwise send a default if
+% available.
+% \begin{macrocode}
+\cs_new_protected:Npn \keys_value_or_default:n #1
+ {
+ \tl_set:Nn \l_keys_value_tl {#1}
+ \bool_if:NT \l_keys_no_value_bool
+ {
+ \quark_if_no_value:cF { \c_keys_vars_root_tl \l_keys_path_tl .default }
+ {
+ \tl_set_eq:Nc \l_keys_value_tl
+ { \c_keys_vars_root_tl \l_keys_path_tl .default }
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\keys_if_value_p:n}
+% To test if a value is required or forbidden. A simple check for
+% the existence of the appropriate marker.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \keys_if_value:n #1 { p }
+ {
+ \tl_if_eq:ccTF { c_keys_value_ #1 _tl }
+ { \c_keys_vars_root_tl \l_keys_path_tl .req }
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\keys_execute:}
+% \begin{macro}[aux]{\keys_execute_unknown:}
+% \begin{macro}[aux]{\keys_execute:nn}
+% Actually executing a key is done in two parts. First, look for the
+% key itself, then look for the \texttt{unknown} key with the same
+% path. If both of these fail, complain.
+% \begin{macrocode}
+\cs_new_nopar:Npn \keys_execute:
+ { \keys_execute:nn { \l_keys_path_tl } { \keys_execute_unknown: } }
+\cs_new_nopar:Npn \keys_execute_unknown:
+ {
+ \keys_execute:nn { \l_keys_module_tl / unknown }
+ {
+ \msg_kernel_error:nnxx { keys } { key-unknown }
+ { \l_keys_path_tl } { \l_keys_module_tl }
+ }
+ }
+\cs_new_nopar:Npn \keys_execute:nn #1#2
+ {
+ \cs_if_exist:cTF { \c_keys_code_root_tl #1 }
+ {
+ \exp_args:Nno \use:c { \c_keys_code_root_tl #1 }
+ \l_keys_value_tl
+ }
+ {#2}
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\keys_choice_find:n}
+% Executing a choice has two parts. First, try the choice given, then
+% if that fails call the unknown key. That will exist, as it is created
+% when a choice is first made. So there is no need for any escape code.
+% \begin{macrocode}
+\cs_new_nopar:Npn \keys_choice_find:n #1
+ {
+ \keys_execute:nn { \l_keys_path_tl / \tl_to_str:n {#1} }
+ { \keys_execute:nn { \l_keys_path_tl / unknown } { } }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Utilities}
+%
+% \begin{macro}[pTF]{\keys_if_exist:nn}
+% A utility for others to see if a key exists.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \keys_if_exist:nn #1#2 { p , T , F , TF }
+ {
+ \cs_if_exist:cTF { \c_keys_code_root_tl #1 / #2 }
+ { \prg_return_true:}
+ { \prg_return_false:}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\keys_show:nn}
+% Showing a key is just a question of using the correct name.
+% \begin{macrocode}
+\cs_new_nopar:Npn \keys_show:nn #1#2
+ { \cs_show:c { \c_keys_code_root_tl #1 / \tl_to_str:n {#2} } }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Messages}
+%
+% For when there is a need to complain.
+% \begin{macrocode}
+\msg_kernel_new:nnnn { keys } { boolean-values-only }
+ { Key~'#1'~accepts~boolean~values~only. }
+ { The~key~'#1'~only~accepts~the~values~'true'~and~'false'. }
+\msg_kernel_new:nnnn { keys } { choice-unknown }
+ { Choice~'#2'~unknown~for~key~'#1'. }
+ {
+ The~key~'#1'~takes~a~limited~number~of~values.\\
+ The~input~given,~'#2',~is~not~on~the~list~accepted.
+ }
+\msg_kernel_new:nnnn { keys } { generate-choices-before-code }
+ { No~code~available~to~generate~choices~for~key~'#1'. }
+ {
+ \c_msg_coding_error_text_tl
+ Before~using~.generate_choices:n~the~code~should~be~defined~
+ with~'.choice_code:n'~or~'.choice_code:x'.
+ }
+\msg_kernel_new:nnnn { keys } { key-no-property }
+ { No~property~given~in~definition~of~key~'#1'. }
+ {
+ \c_msg_coding_error_text_tl
+ Inside~\keys_define:nn each~key~name
+ needs~a~property: \\
+ ~ ~ #1 .<property> \\
+ LaTeX~did~not~find~a~'.'~to~indicate~the~start~of~a~property.
+ }
+\msg_kernel_new:nnnn { keys } { key-unknown }
+ { The~key~'#1'~is~unknown~and~is~being~ignored. }
+ {
+ The~module~'#2'~does~not~have~a~key~called~#1'.\\
+ Check~that~you~have~spelled~the~key~name~correctly.
+ }
+\msg_kernel_new:nnnn { keys } { option-unknown }
+ { Unknown~option~'#1'~for~package~#2. }
+ {
+ LaTeX~has~been~asked~to~set~an~option~called~'#1'~
+ but~the~#2~package~has~not~created~an~option~with~this~name.
+ }
+\msg_kernel_new:nnnn { keys } { property-requires-value }
+ { The~property~'#1'~requires~a~value. }
+ {
+ \c_msg_coding_error_text_tl
+ LaTeX~was~asked~to~set~property~'#2'~for~key~'#1'.\\
+ No~value~was~given~for~the~property,~and~one~is~required.
+ }
+\msg_kernel_new:nnnn { keys } { property-unknown }
+ { The~key~property~'#1'~is~unknown. }
+ {
+ \c_msg_coding_error_text_tl
+ LaTeX~has~been~asked~to~set~the~property~'#1'~for~key~'#2':~
+ this~property~is~not~defined.
+ }
+\msg_kernel_new:nnnn { keys } { value-forbidden }
+ { The~key~'#1'~does~not~taken~a~value. }
+ {
+ The~key~'#1'~should~be~given~without~a~value.\\
+ LaTeX~will~ignore~the~given~value~'#2'.
+ }
+\msg_kernel_new:nnnn { keys } { value-required }
+ { The~key~'#1'~requires~a~value. }
+ {
+ The~key~'#1'~must~have~a~value.\\
+ No~value~was~present:~the~key~will~be~ignored.
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</initex|package>
+% \end{macrocode}
+%
+%\end{implementation}
+%
+%\PrintIndex \ No newline at end of file
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3keyval.dtx b/Master/texmf-dist/source/latex/l3kernel/l3keyval.dtx
new file mode 100644
index 00000000000..999ae7e5b08
--- /dev/null
+++ b/Master/texmf-dist/source/latex/l3kernel/l3keyval.dtx
@@ -0,0 +1,405 @@
+% \iffalse meta-comment
+%
+%% File: l3keyval.dtx Copyright (C) 2006-2011 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 "expl3 bundle" (The Work in LPPL)
+%% and all files in that bundle must be distributed together.
+%%
+%% The released version of this bundle is available from CTAN.
+%%
+%% -----------------------------------------------------------------------
+%%
+%% The development version of the bundle can be found at
+%%
+%% http://www.latex-project.org/svnroot/experimental/trunk/
+%%
+%% for those people who are interested.
+%%
+%%%%%%%%%%%
+%% NOTE: %%
+%%%%%%%%%%%
+%%
+%% Snapshots taken from the repository represent work in progress and may
+%% not work or may contain conflicting material! We therefore ask
+%% people _not_ to put them into distributions, archives, etc. without
+%% prior consultation with the LaTeX3 Project.
+%%
+%% -----------------------------------------------------------------------
+%
+%<*driver|package>
+\RequirePackage{l3names}
+\GetIdInfo$Id: l3keyval.dtx 2478 2011-06-19 21:34:23Z joseph $
+ {L3 Experimental key-value parsing}
+%</driver|package>
+%<*driver>
+\documentclass[full]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3keyval} package\\ Key--value parsing^^A
+% \thanks{This file describes v\ExplFileVersion,
+% last revised \ExplFileDate.}^^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 \ExplFileDate}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% A key--value list is input of the form
+% \begin{verbatim}
+% KeyOne = ValueOne ,
+% KeyTwo = ValueTwo ,
+% KeyThree
+% \end{verbatim}
+% where each key--value pair is separated by a comma from the rest of
+% the list, and each key--value pair does not necessarily contain an
+% equals sign or a value! Processing this type of input correctly
+% requires a number of careful steps, to correctly account for
+% braces, spaces and the category codes of separators.
+%
+% This module provides the low-level machinery for processing arbitrary
+% key--value lists. The \pkg{l3keys} module provides a higher-level
+% interface for managing run-time settings using key--value input,
+% while other parts of \LaTeX3 also use key--value input based on
+% \pkg{l3keyval} (for example the \pkg{xtemplate} module).
+%
+ %\section{Parsing key--value lists}
+%
+% The low-level parsing system converts a \meta{key--value list}
+% into \meta{keys} and associated \meta{values}. After the parsing phase
+% is completed, the resulting keys and values (or keys alone) are
+% available for further processing. This is not carried out by the
+% low-level parser, and so the parser requires the names of
+% two functions along with the key--value list. One function is
+% needed to process key--value pairs (\emph{i.e}~two arguments),
+% and a second function if required for keys given without arguments
+% (\emph{i.e.}~a single argument).
+%
+% The parser does not double |#| tokens or expand any input. The tokens
+% |=| and |,| are corrected so that the parser does not \enquote{miss}
+% any due to category code changes. Spaces are removed from the ends
+% of the keys and values. Values which are given in braces will have
+% exactly one set removed, thus
+% \begin{verbatim}
+% key = {value here},
+% \end{verbatim}
+% and
+% \begin{verbatim}
+% key = value here,
+% \end{verbatim}
+% are treated identically.
+%
+ %\begin{function}{\keyval_parse:NNn}
+% \begin{syntax}
+% \cs{keyval_parse:NNn} \meta{function1} \meta{function2}
+% ~~\Arg{key--value list}
+% \end{syntax}
+% Parses the \meta{key--value list} into a series of \meta{keys} and
+% associated \meta{values}, or keys alone (if no \meta{value} was
+% given). \meta{function1} should take one argument, while
+% \meta{function2} should absorb two arguments. After
+% \cs{keyval_parse:NNn} has parsed the \meta{key--value list},
+% \meta{function1} will be used to process keys given with no value
+% and \meta{function2} will be used to process keys given with a
+% value. The order of the \meta{keys} in the \meta{key--value list}
+% will be preserved. Thus
+% \begin{verbatim}
+% \keyval_parse:NNn \function:n \function:nn
+% { key1 = value1 , key2 = value2, key3 = , key4 }
+% \end{verbatim}
+% will be converted into an input stream
+% \begin{verbatim}
+% \function:nn { key1 } { value1 }
+% \function:nn { key2 } { value2 }
+% \function:nn { key3 } { }
+% \function:n { key4 }
+% \end{verbatim}
+% Note that there is a difference between an empty value (an equals
+% sign followed by nothing) and a missing value (no equals sign at
+% all).
+% \end{function}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3keyval} implementation}
+%
+% \begin{macrocode}
+%<*initex|package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*package>
+\ProvidesExplPackage
+ {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
+\package_check_loaded_expl:
+%</package>
+% \end{macrocode}
+%
+% \begin{variable}{\g_keyval_level_int}
+% For nesting purposes an integer is needed for the current level.
+% \begin{macrocode}
+\int_new:N \g_keyval_level_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_keyval_key_tl, \l_keyval_value_tl}
+% The current key name and value.
+% \begin{macrocode}
+\tl_new:N \l_keyval_key_tl
+\tl_new:N \l_keyval_value_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_keyval_sanitise_tl}
+% \begin{variable}{\l_keyval_parse_tl}
+% Token list variables for dealing with awkward category codes in the
+% input.
+% \begin{macrocode}
+\tl_new:N \l_keyval_sanitise_tl
+\tl_new:N \l_keyval_parse_tl
+% \end{macrocode}
+%\end{variable}
+%\end{variable}
+%
+% \begin{macro}{\keyval_parse:n}
+% The parsing function first deals with the category codes for
+% |=| and |,|, so that there are no odd events. The input is then
+% handed off to the element by element system.
+% \begin{macrocode}
+\group_begin:
+ \char_set_catcode_active:n { `\= }
+ \char_set_catcode_active:n { `\, }
+ \char_set_lccode:nn { `\8 } { `\= }
+ \char_set_lccode:nn { `\9 } { `\, }
+\tl_to_lowercase:n
+ {
+ \group_end:
+ \cs_new_protected:Npn \keyval_parse:n #1
+ {
+ \group_begin:
+ \tl_clear:N \l_keyval_sanitise_tl
+ \tl_set:Nn \l_keyval_sanitise_tl {#1}
+ \tl_replace_all_in:Nnn \l_keyval_sanitise_tl { = } { 8 }
+ \tl_replace_all_in:Nnn \l_keyval_sanitise_tl { , } { 9 }
+ \tl_clear:N \l_keyval_parse_tl
+ \exp_after:wN \keyval_parse_elt:w \exp_after:wN
+ \q_no_value \l_keyval_sanitise_tl 9 \q_nil 9
+ \exp_after:wN \group_end:
+ \l_keyval_parse_tl
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\keyval_parse_elt:w}
+% Each item to be parsed will have \cs{q_no_value} added to the front.
+% Hence the blank test here can always be used to find a totally
+% empty argument. If this is the case, the system loops round. If there
+% is something to parse, there is a check for the \cs{q_nil} marker
+% and if not a hand-off.
+% \begin{macrocode}
+\cs_new_protected:Npn \keyval_parse_elt:w #1 ,
+ {
+ \tl_if_blank:oTF { \use_none:n #1 }
+ { \keyval_parse_elt:w \q_no_value }
+ {
+ \quark_if_nil:oF { \use_ii:nn #1 }
+ {
+ \keyval_split_key_value:w #1 = = \q_stop
+ \keyval_parse_elt:w \q_no_value
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\keyval_split_key_value:w}
+% \begin{macro}[aux]{\keyval_split_key_value_aux:wTF}
+% The key and value are handled separately. First the key is grabbed and
+% saved as \cs{l_keyval_key_tl}. Then a check is need to see if there is
+% a value at all: if not then the key name is simply added to the output.
+% If there is a value then there is a check to ensure that there was
+% only one |=| in the input (remembering some extra ones are around at
+% the moment to prevent errors). All being well, there is an
+% hand-off to find the value: the \cs{q_nil} is there to prevent loss
+% of braces.
+% \begin{macrocode}
+\cs_new_protected:Npn \keyval_split_key_value:w #1 = #2 \q_stop
+ {
+ \keyval_split_key:w #1 \q_stop
+ \str_if_eq:nnTF {#2} { = }
+ {
+ \tl_put_right:Nx \l_keyval_parse_tl
+ {
+ \exp_not:c { keyval_key_no_value_elt_ \int_use:N \g_keyval_level_int :n }
+ { \exp_not:o \l_keyval_key_tl }
+ }
+ }
+ {
+ \keyval_split_key_value_aux:wTF #2 \q_no_value \q_stop
+ { \keyval_split_value:w \q_nil #2 }
+ { \msg_kernel_error:nn { keyval } { misplaced-equals-sign } }
+ }
+ }
+\cs_new:Npn \keyval_split_key_value_aux:wTF #1 = #2#3 \q_stop
+ { \tl_if_head_eq_meaning:nNTF {#3} \q_no_value }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\keyval_split_key:w}
+% \begin{macro}{\keyval_remove_spaces:w}
+% \begin{macro}[aux]{\keyval_split_key_aux:w}
+% \begin{macro}[aux]{\keyval_remove_spaces_aux:w}
+% The aim here is to remove spaces and also exactly one set of braces.
+% The spaces are trimmed off from each end using a \enquote{funny}
+% |Q|, which will never turn up in normal use. The idea is that
+% the \texttt{f}-type expansion will stop if it finds an unexpandable
+% token or a space, and will gobble the space. To avoid expanding
+% anything else, the \cs{exp_not:N} works by ensuring that the first
+% non-space token in the setting will stop the \texttt{f}-type
+% expansion. The \cs{use_none:n} is needed to remove the leading
+% quark, while the second setting of \cs{l_keyval_key_tl}
+% removes exactly one set of braces.
+% \begin{macrocode}
+\group_begin:
+ \char_set_catcode_math_toggle:n { `\Q }
+ \cs_new_protected:Npn \keyval_split_key:w #1 \q_stop
+ {
+ \exp_args:NNf \tl_set:Nn \l_keyval_key_tl
+ {
+ \exp_after:wN \keyval_remove_spaces:w \exp_after:wN
+ \exp_not:N \use_none:n #1 Q ~ Q
+ }
+ \tl_set:Nx \l_keyval_key_tl
+ { \exp_after:wN \keyval_split_key_aux:w \l_keyval_key_tl \q_stop }
+ }
+ \cs_gset:Npn \keyval_split_key_aux:w #1 \q_stop { \exp_not:n {#1} }
+ \cs_gset:Npn \keyval_remove_spaces:w #1 ~ Q { \keyval_remove_spaces_aux:w #1 Q }
+ \cs_gset:Npn \keyval_remove_spaces_aux:w #1 Q #2 {#1}
+\group_end:
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\keyval_split_value:w}
+% Here the value has to be separated from the equals signs and the
+% leading \cs{q_nil} added in to keep the brace levels. Fist the
+% processing function can be added to the output list. If there is no
+% value, setting \cs{l_keyval_value_tl} with three groups removed will
+% leave nothing at all, and so an empty group can be added to the
+% parsed list. On the other hand, if the value is entirely contained
+% within a set of braces then \cs{l_keyval_value_tl} will contain
+% \cs{q_nil} only. In that case, strip off the leading quark using
+% \cs{use_ii:nnn}, which also deals with any spaces.
+% \begin{macrocode}
+\cs_new_protected:Npn \keyval_split_value:w #1 = =
+ {
+ \tl_put_right:Nx \l_keyval_parse_tl
+ {
+ \exp_not:c { keyval_key_value_elt_ \int_use:N \g_keyval_level_int :nn }
+ { \exp_not:o \l_keyval_key_tl }
+ }
+ \tl_set:Nx \l_keyval_value_tl { \exp_not:o { \use_none:nnn #1 \q_nil \q_nil } }
+ \tl_if_empty:NTF \l_keyval_value_tl
+ { \tl_put_right:Nn \l_keyval_parse_tl { { } } }
+ {
+ \quark_if_nil:NTF \l_keyval_value_tl
+ {
+ \tl_put_right:Nx \l_keyval_parse_tl
+ { { \exp_not:o { \use_ii:nnn #1 \q_nil } } }
+ }
+ { \keyval_split_value_aux:w #1 \q_stop }
+ }
+ }
+% \end{macrocode}
+% A similar idea to the key code: remove the spaces from each end and
+% deal with one set of braces.
+% \begin{macrocode}
+\group_begin:
+ \char_set_catcode_math_toggle:n { `\Q }
+ \cs_new_protected:Npn \keyval_split_value_aux:w \q_nil #1 \q_stop
+ {
+ \exp_args:NNf \tl_set:Nn \l_keyval_value_tl
+ { \keyval_remove_spaces:w \exp_not:N #1 Q ~ Q }
+ \tl_put_right:Nx \l_keyval_parse_tl { { \exp_not:o \l_keyval_value_tl } }
+ }
+\group_end:
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\keyval_parse:NNn}
+% The outer parsing routine just sets up the processing functions and
+% hands off.
+% \begin{macrocode}
+\cs_new_protected:Npn \keyval_parse:NNn #1#2#3
+ {
+ \int_gincr:N \g_keyval_level_int
+ \cs_gset_eq:cN { keyval_key_no_value_elt_ \int_use:N \g_keyval_level_int :n } #1
+ \cs_gset_eq:cN { keyval_key_value_elt_ \int_use:N \g_keyval_level_int :nn } #2
+ \keyval_parse:n {#3}
+ \int_gdecr:N \g_keyval_level_int
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% One message for the low level parsing system.
+% \begin{macrocode}
+\msg_kernel_new:nnnn { keyval } { misplaced-equals-sign }
+ { Misplaced~equals~sign~in~key-value~input~\msg_line_number: }
+ {
+ LaTeX~is~attempting~to~parse~some~key-value~input~but~found~
+ two~equals~signs~not~separated~by~a~comma.
+ }
+% \end{macrocode}
+%
+% \subsection{Deprecated functions}
+%
+% Deprecated on 2011-05-27, for removal by 2011-08-31.
+%
+% \begin{macro}{\KV_process_space_removal_sanitize:NNn}
+% \begin{macro}{\KV_process_space_removal_no_sanitize:NNn}
+% \begin{macro}{\KV_process_no_space_removal_no_sanitize:NNn}
+% There is just one function for this now.
+% \begin{macrocode}
+\cs_new_eq:NN \KV_process_space_removal_sanitize:NNn \keyval_parse:NNn
+\cs_new_eq:NN \KV_process_space_removal_no_sanitize:NNn \keyval_parse:NNn
+\cs_new_eq:NN \KV_process_no_space_removal_no_sanitize:NNn \keyval_parse:NNn
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macrocode}
+%</initex|package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3luatex.dtx b/Master/texmf-dist/source/latex/l3kernel/l3luatex.dtx
new file mode 100644
index 00000000000..70259184340
--- /dev/null
+++ b/Master/texmf-dist/source/latex/l3kernel/l3luatex.dtx
@@ -0,0 +1,459 @@
+% \iffalse meta-comment
+%
+%% File: l3luatex.dtx Copyright (C) 2010,2011 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 "expl3 bundle" (The Work in LPPL)
+%% and all files in that bundle must be distributed together.
+%%
+%% The released version of this bundle is available from CTAN.
+%%
+%% -----------------------------------------------------------------------
+%%
+%% The development version of the bundle can be found at
+%%
+%% http://www.latex-project.org/svnroot/experimental/trunk/
+%%
+%% for those people who are interested.
+%%
+%%%%%%%%%%%
+%% NOTE: %%
+%%%%%%%%%%%
+%%
+%% Snapshots taken from the repository represent work in progress and may
+%% not work or may contain conflicting material! We therefore ask
+%% people _not_ to put them into distributions, archives, etc. without
+%% prior consultation with the LaTeX3 Project.
+%%
+%% -----------------------------------------------------------------------
+%
+%<*driver|package>
+\RequirePackage{l3names}
+\GetIdInfo$Id: l3luatex.dtx 2478 2011-06-19 21:34:23Z joseph $
+ {L3 Experimental LuaTeX-specific functions}
+%</driver|package>
+%<*driver>
+\documentclass[full]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3luatex} package\\ LuaTeX-specific functions^^A
+% \thanks{This file describes v\ExplFileVersion,
+% last revised \ExplFileDate.}^^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 \ExplFileDate}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% \section{Breaking out to \Lua{}}
+%
+% The \LuaTeX{} engine provides access to the \Lua{} programming language,
+% and with it access to the \enquote{internals} of \TeX{}. In order to use
+% this within the framework provided here, a family of functions is
+% available. When used with \pdfTeX{} or \XeTeX{} these will raise an
+% error: use \cs{luatex_if_engine:T} to avoid this. Details of coding
+% the \LuaTeX{} engine are detailed in the \LuaTeX{} manual.
+%
+% \begin{function}[EXP]{\lua_now:n, \lua_now:x}
+% \begin{syntax}
+% \cs{lua_now:n} \Arg{token list}
+% \end{syntax}
+% The \meta{token list} is first tokenized by \TeX{}, which will include
+% converting line ends to spaces in the usual \TeX{} manner and which
+% respects currently-applicable \TeX\ category codes. The resulting
+% \meta{\Lua{} input} is passed to the \Lua{} interpreter for processing.
+% Each \cs{lua_now:n} block is treated by \Lua{} as a separate chunk.
+% The \Lua{} interpreter will execute the \meta{\Lua{} input} immediately,
+% and in an expandable manner.
+% \begin{texnote}
+% \cs{lua_now:x} is the \LuaTeX{} primitive \cs{directlua} renamed.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{\lua_shipout:n, \lua_shipout:x}
+% \begin{syntax}
+% \cs{lua_shipout:x} \Arg{token list}
+% \end{syntax}
+% The \meta{token list} is first tokenized by \TeX{}, which will include
+% converting line ends to spaces in the usual \TeX{} manner and which
+% respects currently-applicable \TeX{} category codes. The resulting
+% \meta{\Lua{} input} is passed to the \Lua\ interpreter when the
+% current page is finalised (\emph{i.e.}~at shipout). Each
+% \cs{lua_shipout:n} block is treated by \Lua{} as a separate chunk.
+% The \Lua{} interpreter will execute the \meta{\Lua{} input} during the
+% page-building routine: no \TeX{} expansion of the \meta{\Lua{} input}
+% will occur at this stage.
+% \begin{texnote}
+% At a \TeX{} level, the \meta{\Lua{} input} is stored as a
+% \enquote{whatsit}.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{\lua_shipout_x:n, \lua_shipout_x:x}
+% \begin{syntax}
+% \cs{lua_shipout:n} \Arg{token list}
+% \end{syntax}
+% The \meta{token list} is first tokenized by \TeX{}, which will include
+% converting line ends to spaces in the usual \TeX{} manner and which
+% respects currently-applicable \TeX{} category codes. The resulting
+% \meta{\Lua{} input} is passed to the \Lua{} interpreter when the
+% current page is finalised (\emph{i.e.}~at shipout). Each
+% \cs{lua_shipout:n} block is treated by \Lua{} as a separate chunk.
+% The \Lua{} interpreter will execute the \meta{\Lua{} input} during the
+% page-building routine: the \meta{\Lua{} input} is expanded during this
+% process in addition to any expansion when the argument was read. This
+% makes these functions suitable for including material finalised
+% during the page building process (such as the page number).
+% \begin{texnote}
+% \cs{lua_shipout_x:n} is the \LuaTeX{} primitive \cs{latelua}
+% named using the \LaTeX3 scheme.
+%
+% At a \TeX{} level, the \meta{\Lua{} input} is stored as a
+% \enquote{whatsit}.
+% \end{texnote}
+% \end{function}
+%
+% \section{Category code tables}
+%
+% As well as providing methods to break out into \Lua{}, there are
+% places where additional \LaTeX3 functions are provided by the
+% \LuaTeX{} engine. In particular, \LuaTeX{} provides category code
+% tables. These can be used to ensure that a set of category codes
+% are in force in a more robust way than is possible with other
+% engines. These are therefore used by \cs{ExplSyntaxOn} and
+% \pkg{ExplSyntaxOff} when using the \LuaTeX{} engine.
+%
+% \begin{function}{\cctab_new:N}
+% \begin{syntax}
+% \cs{cctab_new:N} \meta{category code table}
+% \end{syntax}
+% Creates a new category code table, initially with the codes as
+% used by \IniTeX{}.
+% \end{function}
+%
+% \begin{function}{\cctab_gset:Nn}
+% \begin{syntax}
+% \cs{cctab_gset:Nn} \meta{category code table}
+% \Arg{category code set up}
+% \end{syntax}
+% Sets the \meta{category code table} to apply the category codes
+% which apply when the prevailing regime is modified by the
+% \meta{category code set up}. Thus within a standard code block
+% the starting point will be the code applied by \cs{c_code_cctab}.
+% The assignment of the table is global: the underlying primitive does
+% not respect grouping.
+% \end{function}
+%
+% \begin{function}{\cctab_begin:N}
+% \begin{syntax}
+% \cs{cctab_begin:N} \meta{category code table}
+% \end{syntax}
+% Switches the category codes in force to those stored in the
+% \meta{category code table}. The prevailing codes before the
+% function is called are added to a stack, for use with
+% \cs{cctab_end:}.
+% \end{function}
+%
+% \begin{function}{\cctab_end:}
+% \begin{syntax}
+% \cs{cctab_end:}
+% \end{syntax}
+% Ends the scope of a \meta{category code table} started using
+% \cs{cctab_begin:N}, retuning the codes to those in force before the
+% matching \cs{cctab_begin:N} was used.
+% \end{function}
+%
+% \begin{variable}{\c_code_cctab}
+% Category code table for the code environment. This does not include
+% setting the behaviour of the line-end character, which is only
+% altered by \cs{ExplSyntaxOn}.
+% \end{variable}
+%
+% \begin{variable}{\c_document_cctab}
+% Category code table for a standard \LaTeX{} document. This does not
+% include setting the behaviour of the line-end character, which is
+% only altered by \cs{ExplSyntaxOff}.
+% \end{variable}
+%
+% \begin{variable}{\c_initex_cctab}
+% Category code table as set up by \IniTeX{}.
+% \end{variable}
+%
+% \begin{variable}{\c_other_cctab}
+% Category code table where all characters have category code $12$
+% (other).
+% \end{variable}
+%
+% \begin{variable}{\c_string_cctab}
+% Category code table where all characters have category code $12$
+% (other) with the exception of spaces, which have category code
+% $10$ (space).
+% \end{variable}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3luatex} implementation}
+%
+% \begin{macrocode}
+%<*initex|package>
+% \end{macrocode}
+%
+% Announce and ensure that the required packages are loaded.
+% \begin{macrocode}
+%<*package>
+\ProvidesExplPackage
+ {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
+\package_check_loaded_expl:
+%</package>
+%<*initex|package>
+% \end{macrocode}
+%
+% \begin{macro}{\lua_now:n, \lua_now:x}
+% \begin{macro}{\lua_shipout_x:n, \lua_shipout_x:x}
+% \begin{macro}{\lua_shipout:n, \lua_shipout:x}
+% \begin{macro}[aux]{\lua_wrong_engine:}
+% When \LuaTeX{} is in use, this is all a question of primitives with new
+% names. On the other hand, for \pdfTeX{} and \XeTeX{} the argument should
+% be removed from the input stream before issuing an error. This needs
+% to be expandable, so the same idea is used as for \texttt{V}-type
+% expansion, with an appropriately-named but undefined function.
+% \begin{macrocode}
+\luatex_if_engine:TF
+ {
+ \cs_new_eq:NN \lua_now:x \luatex_directlua:D
+ \cs_new_eq:NN \lua_shipout_x:n \luatex_latelua:D
+ }
+ {
+ \cs_new:Npn \lua_now:x #1 { \lua_wrong_engine: }
+ \cs_new_protected:Npn \lua_shipout_x:n #1 { \lua_wrong_engine: }
+ }
+\cs_new:Npn \lua_now:n #1
+ { \lua_now:x { \exp_not:n {#1} } }
+\cs_generate_variant:Nn \lua_shipout_x:n { x }
+\cs_new_protected:Npn \lua_shipout:n #1
+ { \lua_shipout_x:n { \exp_not:n {#1} } }
+\cs_generate_variant:Nn \lua_shipout:n { x }
+\group_begin:
+\char_set_catcode_letter:N\!
+\char_set_catcode_letter:N\ %
+\cs_gset:Npn\lua_wrong_engine:{%
+\LuaTeX engine not in use!%
+}%
+\group_end:%
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Category code tables}
+%
+% \begin{variable}{\g_cctab_allocate_int}
+% \begin{variable}{\g_cctab_stack_int}
+% \begin{variable}{\g_cctab_stack_seq}
+% To allocate category code tables, both the read-only and stack
+% tables need to be followed. There is also a sequence stack for the
+% dynamic tables themselves.
+% \begin{macrocode}
+\int_new:N \g_cctab_allocate_int
+\int_set:Nn \g_cctab_allocate_int { -1 }
+\int_new:N \g_cctab_stack_int
+\seq_new:N \g_cctab_stack_seq
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+%
+% \begin{macro}{\cctab_new:N}
+% Creating a new category code table is done slightly differently
+% from other registers. Low-numbered tables are more efficiently-stored
+% than high-numbered ones. There is also a need to have a stack of
+% flexible tables as well as the set of read-only ones. To satisfy both
+% of these requirements, odd numbered tables are used for read-only
+% tables, and even ones for the stack. Here, therefore, the odd numbers
+% are allocated.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \cctab_new:N #1
+ {
+ \cs_if_free:NTF #1
+ {
+ \int_gadd:Nn \g_cctab_allocate_int { 2 }
+ \int_compare:nNnTF
+ { \g_cctab_allocate_int } < { \c_max_register_int + 1 }
+ {
+ \pref_global:D \tex_mathchardef:D #1 \g_cctab_allocate_int
+ \luatex_initcatcodetable:D #1
+ }
+ { \msg_kernel_fatal:nnx { alloc } { out-of-registers } { cctab } }
+ }
+ {
+ \msg_kernel_error:nnx { code } { variable-already-defined }
+ { \token_to_str:N #1 }
+ }
+ }
+\luatex_if_engine:F
+ { \cs_set_protected_nopar:Npn \cctab_new:N #1 { \lua_wrong_engine: } }
+%<*package>
+\luatex_if_engine:T
+ {
+ \cs_set_protected_nopar:Npn \cctab_new:N #1
+ {
+ \newcatcodetable #1
+ \luatex_initcatcodetable:D #1
+ }
+ }
+%</package>
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\cctab_begin:N}
+% \begin{macro}{\cctab_end:}
+% \begin{variable}{\l_cctab_tmp_tl}
+% The aim here is to ensure that the saved tables are read-only. This is
+% done by using a stack of tables which are not read only, and actually
+% having them as \enquote{in use} copies.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \cctab_begin:N #1
+ {
+ \seq_gpush:Nx \g_cctab_stack_seq { \tex_the:D \luatex_catcodetable:D }
+ \luatex_catcodetable:D #1
+ \int_gadd:Nn \g_cctab_stack_int { 2 }
+ \int_compare:nNnT { \g_cctab_stack_int } > { 268 435 453 }
+ { \msg_kernel_error:nn { code } { cctab-stack-full } }
+ \luatex_savecatcodetable:D \g_cctab_stack_int
+ \luatex_catcodetable:D \g_cctab_stack_int
+ }
+\cs_new_protected_nopar:Npn \cctab_end:
+ {
+ \int_gsub:Nn \g_cctab_stack_int { 2 }
+ \seq_gpop:NN \g_cctab_stack_seq \l_cctab_tmp_tl
+ \quark_if_no_value:NT \l_cctab_tmp_tl
+ { \tl_set:Nn \l_cctab_tmp_tl { 0 } }
+ \luatex_catcodetable:D \l_cctab_tmp_tl \scan_stop:
+ }
+\luatex_if_engine:F
+ {
+ \cs_set_protected_nopar:Npn \cctab_begin:N #1 { \lua_wrong_engine: }
+ \cs_set_protected_nopar:Npn \cctab_end: { \lua_wrong_engine: }
+ }
+%<*package>
+\luatex_if_engine:T
+ {
+ \cs_set_protected_nopar:Npn \cctab_begin:N #1 { \BeginCatcodeRegime #1 }
+ \cs_set_protected_nopar:Npn \cctab_end: { \EndCatcodeRegime }
+ }
+%</package>
+\tl_new:N \l_cctab_tmp_tl
+% \end{macrocode}
+% \end{variable}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\cctab_gset:Nn}
+% Category code tables are always global, so only one version is needed.
+% The set up here is simple, and means that at the point of use there is
+% no need to worry about escaping category codes.
+% \begin{macrocode}
+\cs_new_protected:Npn \cctab_gset:Nn #1#2
+ {
+ \group_begin:
+ #2
+ \luatex_savecatcodetable:D #1
+ \group_end:
+ }
+\luatex_if_engine:F
+ { \cs_set_protected_nopar:Npn \cctab_gset:Nn #1#2 { \lua_wrong_engine: } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}{\c_code_cctab}
+% \begin{variable}{\c_document_cctab}
+% \begin{variable}{\c_initex_cctab}
+% \begin{variable}{\c_other_cctab}
+% \begin{variable}{\c_string_cctab}
+% Creating category code tables is easy using the function above.
+% The \texttt{other} and \texttt{string} ones are done by completely
+% ignoring the existing codes as this makes life a lot less complex. The
+% table for \pkg{expl3} category codes is always needed, whereas when in
+% package mode the rest can be copied from the existing \LaTeXe{} package
+% \pkg{luatex}.
+% \begin{macrocode}
+\luatex_if_engine:T
+ {
+ \cctab_new:N \c_code_cctab
+ \cctab_gset:Nn \c_code_cctab { }
+ }
+%<*package>
+\luatex_if_engine:T
+ {
+ \cs_new_eq:NN \c_document_cctab \CatcodeTableLaTeX
+ \cs_new_eq:NN \c_initex_cctab \CatcodeTableIniTeX
+ \cs_new_eq:NN \c_other_cctab \CatcodeTableOther
+ \cs_new_eq:NN \c_string_cctab \CatcodeTableString
+ }
+%</package>
+%<*initex>
+\luatex_if_engine:T
+ {
+ \cctab_new:N \c_document_cctab
+ \cctab_new:N \c_other_cctab
+ \cctab_new:N \c_string_cctab
+ \cctab_gset:Nn \c_document_cctab
+ {
+ \char_set_catcode_space:n { 9 }
+ \char_set_catcode_space:n { 32 }
+ \char_set_catcode_other:n { 58 }
+ \char_set_catcode_math_subscript:n { 95 }
+ \char_set_catcode_active:n { 126 }
+ }
+ \cctab_gset:Nn \c_other_cctab
+ {
+ \prg_stepwise_inline:nnnn { 0 } { 1 } { 127 }
+ { \char_set_catcode_other:n {#1} }
+ }
+ \cctab_gset:Nn \c_string_cctab
+ {
+ \prg_stepwise_inline:nnnn { 0 } { 1 } { 127 }
+ { \char_set_catcode_other:n {#1} }
+ \char_set_catcode_space:n { 32 }
+ }
+ }
+%</initex>
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+%
+% \begin{macrocode}
+%</initex|package>
+% \end{macrocode}
+%
+%\end{implementation}
+%
+%\PrintIndex \ No newline at end of file
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3msg.dtx b/Master/texmf-dist/source/latex/l3kernel/l3msg.dtx
new file mode 100644
index 00000000000..eceadf3c1a8
--- /dev/null
+++ b/Master/texmf-dist/source/latex/l3kernel/l3msg.dtx
@@ -0,0 +1,1609 @@
+% \iffalse meta-comment
+%
+%% File: l3msg.dtx Copyright (C) 2009-2011 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 "expl3 bundle" (The Work in LPPL)
+%% and all files in that bundle must be distributed together.
+%%
+%% The released version of this bundle is available from CTAN.
+%%
+%% -----------------------------------------------------------------------
+%%
+%% The development version of the bundle can be found at
+%%
+%% http://www.latex-project.org/svnroot/experimental/trunk/
+%%
+%% for those people who are interested.
+%%
+%%%%%%%%%%%
+%% NOTE: %%
+%%%%%%%%%%%
+%%
+%% Snapshots taken from the repository represent work in progress and may
+%% not work or may contain conflicting material! We therefore ask
+%% people _not_ to put them into distributions, archives, etc. without
+%% prior consultation with the LaTeX3 Project.
+%%
+%% -----------------------------------------------------------------------
+%
+%<*driver|package>
+\RequirePackage{l3names}
+\GetIdInfo$Id: l3msg.dtx 2478 2011-06-19 21:34:23Z joseph $
+ {L3 Experimental messages}
+%</driver|package>
+%<*driver>
+\documentclass[full]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3msg} package\\ Messages^^A
+% \thanks{This file describes v\ExplFileVersion,
+% last revised \ExplFileDate.}^^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 \ExplFileDate}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% Messages need to be passed to the user by modules, either when errors
+% occur or to indicate how the code is proceeding. The \pkg{l3msg}
+% module provides a consistent method for doing this (as opposed to
+% writing directly to the terminal or log).
+%
+% The system used by \pkg{l3msg} to create messages divides the process
+% into two distinct parts. Named messages are created in the first part
+% of the process; at this stage, no decision is made about the type
+% output that the message will produce. The second part of the process
+% is actually producing a message. At this stage a choice of message
+% \emph{class} has to be made, for example \texttt{error},
+% \texttt{warning} or \texttt{info}.
+%
+% By separating out the creation and use of messages, several benefits
+% are available. First, the messages can be altered later without
+% needing details of where they are used in the code. This makes it
+% possible to alter the language used, the detail level and so on.
+% Secondly, the output which results from a given message can be
+% altered. This can be done on a message class, module or message name
+% basis. In this way, message behaviour can be altered and messages can
+% be entirely suppressed.
+%
+% \section{Creating new messages}
+%
+% All messages have to be created before they can be used. All message
+% setting is local, with the general assumption that messages will
+% be managed as part of module set up outside of any \TeX{} grouping.
+%
+% The text of messages will automatically by wrapped to the length
+% available in the console. As a result, formatting is only needed
+% where it will help to show meaning. In particular, |\\| may be
+% used to force a new line and \verb*|\ | forces an explicit space.
+%
+% \begin{function}{\msg_new:nnnn, \msg_new:nnn}
+% \begin{syntax}
+% \cs{msg_new:nnnn} \Arg{module} \Arg{message} \Arg{text}
+% ~~\Arg{more text}
+% \end{syntax}
+% Creates a \meta{message} for a given \meta{module}.
+% The message will be defined to first give \meta{text} and then
+% \meta{more text} if the user requests it. If no \meta{more text} is
+% available then a standard text is given instead. Within \meta{text}
+% and \meta{more text} four parameters (|#1| to |#4|) can be used:
+% these will be supplied at the time the message is used. The
+% parameters will be expanded when the message is used. Within the
+% \meta{text} and \meta{more text} |\\| can be used to start a new
+% line. An error will be raised if the \meta{message} already exists.
+% \end{function}
+%
+% \begin{function}{\msg_set:nnnn, \msg_set:nnn}
+% \begin{syntax}
+% \cs{msg_set:nnnn} \Arg{module} \Arg{message} \Arg{text}
+% ~~\Arg{more text}
+% \end{syntax}
+% Sets up the text for a \meta{message} for a given \meta{module}.
+% The message will be defined to first give \meta{text} and then
+% \meta{more text} if the user requests it. If no \meta{more text} is
+% available then a standard text is given instead. Within \meta{text}
+% and \meta{more text} four parameters (|#1| to |#4|) can be used:
+% these will be supplied at the time the message is used. The
+% parameters will be expanded when the message is used. Within the
+% \meta{text} and \meta{more text} |\\| can be used to start a new
+% line.
+% \end{function}
+%
+% \section{Contextual information for messages}
+%
+% \begin{function}[EXP]{\msg_line_context:}
+% \begin{syntax}
+% \cs{msg_line_context:}
+% \end{syntax}
+% Prints the current line number when a message is given, and
+% thus suitable for giving context to messages. The number itself
+% is proceeded by the text |on line|.
+% \end{function}
+%
+% \begin{function}[EXP]{\msg_line_number:}
+% \begin{syntax}
+% \cs{msg_line_number:}
+% \end{syntax}
+% Prints the current line number when a message is given.
+% \end{function}
+%
+% \begin{variable}{\c_msg_return_text_tl}
+% Standard text to indicate that the user should try pressing
+% \meta{return} to continue. The standard definition reads:
+% \begin{verbatim}
+% Try typing <return> to proceed.
+%
+% If that doesn't work, type X <return> to quit.
+% \end{verbatim}
+% \end{variable}
+%
+% \begin{variable}{\c_msg_trouble_text_tl}
+% Standard text to indicate that the more errors are likely and
+% that aborting the run is advised. The standard definition reads:
+% \begin{verbatim}
+% More errors will almost certainly follow:
+% the LaTeX run should be aborted.
+% \end{verbatim}
+% \end{variable}
+%
+% \begin{function}[EXP]{\msg_fatal_text:n}
+% \begin{syntax}
+% \cs{msg_fatal_text:n} \Arg{module}
+% \end{syntax}
+% Produces the standard text:
+% \begin{verbatim}
+% Fatal <module> error
+% \end{verbatim}
+% This function can be redefined to alter the language in which the
+% message is give, using |#1| as the name of the \meta{module} to
+% be included.
+% \end{function}
+%
+% \begin{function}[EXP]{\msg_critical_text:n}
+% \begin{syntax}
+% \cs{msg_critical_text:n} \Arg{module}
+% \end{syntax}
+% Produces the standard text:
+% \begin{verbatim}
+% Critical <module> error
+% \end{verbatim}
+% This function can be redefined to alter the language in which the
+% message is give, using |#1| as the name of the \meta{module} to
+% be included.
+% \end{function}
+%
+% \begin{function}[EXP]{\msg_error_text:n}
+% \begin{syntax}
+% \cs{msg_error_text:n} \Arg{module}
+% \end{syntax}
+% Produces the standard text:
+% \begin{verbatim}
+% <module> error
+% \end{verbatim}
+% This function can be redefined to alter the language in which the
+% message is give, using |#1| as the name of the \meta{module} to
+% be included.
+% \end{function}
+%
+% \begin{function}[EXP]{\msg_warning_text:n}
+% \begin{syntax}
+% \cs{msg_warning_text:n} \Arg{module}
+% \end{syntax}
+% Produces the standard text:
+% \begin{verbatim}
+% <module> warning
+% \end{verbatim}
+% This function can be redefined to alter the language in which the
+% message is give, using |#1| as the name of the \meta{module} to
+% be included.
+% \end{function}
+%
+% \begin{function}[EXP]{\msg_info_text:n}
+% \begin{syntax}
+% \cs{msg_info_text:n} \Arg{module}
+% \end{syntax}
+% Produces the standard text:
+% \begin{verbatim}
+% <module> info
+% \end{verbatim}
+% This function can be redefined to alter the language in which the
+% message is give, using |#1| as the name of the \meta{module} to
+% be included.
+% \end{function}
+%
+% \section{Issuing messages}
+%
+% Messages behave differently depending on the message class. A number
+% of standard message classes are supplied, but more can be
+% created.
+%
+% When issuing messages, any arguments passed should use
+% \cs{tl_to_str:n} or \cs{token_to_str:N} to prevent unwanted expansion
+% of the material.
+%
+% \begin{function}{\msg_class_set:nn}
+% \begin{syntax}
+% \cs{msg_class_set:nn} \Arg{class} \Arg{code}
+% \end{syntax}
+% Sets a \meta{class} to output a message, using \meta{code}
+% to process the message text. The \meta{class} should be a text
+% value, while the \meta{code} may be any arbitrary material.
+% The \meta{code} will receive $6$ arguments: the module
+% name (|#1|), the message name (|#2|) and the four arguments
+% taken by the message text (|#3| to |#6|).
+% \end{function}
+%
+% The kernel defines several common message classes. The following
+% describes the standard behaviour of each class if no redirection of
+% the class or message is active. In all cases, the message may be
+% issued supplying $0$ to $4$ arguments. The code will
+% ensure that there an no errors if the number of arguments supplied
+% here does not match the number in the definition of the message
+% (although of course the sense of the message may be impaired).
+%
+% \begin{function}
+% {
+% \msg_fatal:nnxxxx ,
+% \msg_fatal:nnxxx ,
+% \msg_fatal:nnxx ,
+% \msg_fatal:nnx ,
+% \msg_fatal:nn
+% }
+% \begin{syntax}
+% \cs{msg_fatal:nnxxxx} \Arg{module} \Arg{message} \Arg{arg one}
+% ~~\Arg{arg two} \Arg{arg three} \Arg{arg four}
+% \end{syntax}
+% Issues \meta{module} error \meta{message}, passing \meta{arg one} to
+% \meta{arg four} to the text-creating functions. After issuing a
+% fatal error the \TeX{} run will halt.
+% \end{function}
+%
+% \begin{function}
+% {
+% \msg_critical:nnxxxx ,
+% \msg_critical:nnxxx ,
+% \msg_critical:nnxx ,
+% \msg_critical:nnx ,
+% \msg_critical:nn
+% }
+% \begin{syntax}
+% \cs{msg_critical:nnxxxx} \Arg{module} \Arg{message} \Arg{arg one}
+% ~~\Arg{arg two} \Arg{arg three} \Arg{arg four}
+% \end{syntax}
+% Issues \meta{module} error \meta{message}, passing \meta{arg one} to
+% \meta{arg four} to the text-creating functions. After issuing the
+% message reading the current input file will stop. This may halt
+% the \TeX{} run (if the current file is the main file) or
+% may abort reading a sub-file.
+% \end{function}
+%
+% \begin{function}
+% {
+% \msg_error:nnxxxx ,
+% \msg_error:nnxxx ,
+% \msg_error:nnxx ,
+% \msg_error:nnx ,
+% \msg_error:nn
+% }
+% \begin{syntax}
+% \cs{msg_error:nnxxxx} \Arg{module} \Arg{message} \Arg{arg one}
+% ~~\Arg{arg two} \Arg{arg three} \Arg{arg four}
+% \end{syntax}
+% Issues \meta{module} error \meta{message}, passing \meta{arg one} to
+% \meta{arg four} to the text-creating functions. The error will
+% stop processing and issue the text at the terminal. After user input,
+% the run will continue.
+% \end{function}
+%
+% \begin{function}
+% {
+% \msg_warning:nnxxxx ,
+% \msg_warning:nnxxx ,
+% \msg_warning:nnxx ,
+% \msg_warning:nnx ,
+% \msg_warning:nn
+% }
+% \begin{syntax}
+% \cs{msg_warning:nnxxxx} \Arg{module} \Arg{message} \Arg{arg one}
+% ~~\Arg{arg two} \Arg{arg three} \Arg{arg four}
+% \end{syntax}
+% Issues \meta{module} warning \meta{message}, passing \meta{arg one} to
+% \meta{arg four} to the text-creating functions. The warning text
+% will be added to the log file, but the \TeX{} run will not be
+% interrupted.
+% \end{function}
+%
+% \begin{function}
+% {
+% \msg_info:nnxxxx ,
+% \msg_info:nnxxx ,
+% \msg_info:nnxx ,
+% \msg_info:nnx ,
+% \msg_info:nn
+% }
+% \begin{syntax}
+% \cs{msg_info:nnxxxx} \Arg{module} \Arg{message} \Arg{arg one}
+% ~~\Arg{arg two} \Arg{arg three} \Arg{arg four}
+% \end{syntax}
+% Issues \meta{module} information \meta{message}, passing
+% \meta{arg one} to \meta{arg four} to the text-creating functions.
+% The information text will be added to the log file.
+% \end{function}
+%
+% \begin{function}
+% {
+% \msg_log:nnxxxx ,
+% \msg_log:nnxxx ,
+% \msg_log:nnxx ,
+% \msg_log:nnx ,
+% \msg_log:nn
+% }
+% \begin{syntax}
+% \cs{msg_log:nnxxxx} \Arg{module} \Arg{message} \Arg{arg one}
+% ~~\Arg{arg two} \Arg{arg three} \Arg{arg four}
+% \end{syntax}
+% Issues \meta{module} information \meta{message}, passing
+% \meta{arg one} to \meta{arg four} to the text-creating functions.
+% The information text will be added to the log file: the output
+% is briefer than \cs{msg_info:nnxxxx}.
+% \end{function}
+%
+% \begin{function}
+% {
+% \msg_none:nnxxxx ,
+% \msg_none:nnxxx ,
+% \msg_none:nnxx ,
+% \msg_none:nnx ,
+% \msg_none:nn
+% }
+% \begin{syntax}
+% \cs{msg_none:nnxxxx} \Arg{module} \Arg{message} \Arg{arg one}
+% ~~\Arg{arg two} \Arg{arg three} \Arg{arg four}
+% \end{syntax}
+% Does nothing: used as a message class to prevent any output at
+% all (see the discussion of message redirection).
+% \end{function}
+%
+% \section{Redirecting messages}
+%
+% \begin{function}{\msg_redirect_class:nn}
+% \begin{syntax}
+% \cs{msg_redirect_class:nn} \Arg{class one} \Arg{class two}
+% \end{syntax}
+% Changes the behaviour of messages of \meta{class one} so that they
+% are processed using the code for those of \meta{class two}. Multiple
+% redirections are possible. Redirection to a missing class or
+% infinite loops will raise errors when the messages are used,
+% rather than at the point of redirection.
+% \end{function}
+%
+% \begin{function}{\msg_redirect_module:nnn}
+% \begin{syntax}
+% \cs{msg_redirect_module:nnn} \Arg{module} \Arg{class one}
+% ~~\Arg{class two}
+% \end{syntax}
+% Redirects message of \meta{class one} for \meta{module} to act as
+% though they were from \meta{class two}. Messages of \meta{class one}
+% from sources other than \meta{module} are not affected by this
+% redirection. This function can be used to make some messages
+% \enquote{silent} by default. For example, all of the
+% \texttt{trace} messages of \meta{module} could be turned off with:
+% \begin{verbatim}
+% \msg_redirect_module:nnn { module } { trace } { none }
+% \end{verbatim}
+% \end{function}
+%
+% \begin{function}{\msg_redirect_name:nnn}
+% \begin{syntax}
+% \cs{msg_redirect_name:nn} \Arg{module} \Arg{message} \Arg{class}
+% \end{syntax}
+% Redirects a specific \meta{message} from a specific \meta{module}
+% to act as a member of \meta{class} of messages. This function can
+% be used to make a selected message \enquote{silent} without
+% changing global parameters:
+% \begin{verbatim}
+% \msg_redirect_name:nnn { module } { annoying-message } { none }
+% \end{verbatim}
+% \end{function}
+%
+% \section{Low-level message functions}
+%
+% The lower-level message functions should usually be accessed from the
+% higher-level system. However, there are occasions where direct
+% access to these functions is desirable.
+%
+% \begin{function}[EXP]{\msg_newline:, \msg_two_newlines:}
+% \begin{syntax}
+% \cs{msg_newline:}
+% \end{syntax}
+% Forces a new line in a message. This is a low-level function, which
+% will not include any additional printing information in the message:
+% contrast with |\\| in messages. The |two| version adds two lines.
+% \end{function}
+%
+% \begin{function}{\msg_interrupt:xxx}
+% \begin{syntax}
+% \cs{msg_interrupt:xxx} \Arg{first line} \Arg{text} \Arg{extra text}
+% \end{syntax}
+% Interrupts the \TeX{} run, issuing a formatted message comprising
+% \meta{first line} and \meta{text} laid out in the format
+% \begin{verbatim}
+% !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+% !
+% ! <first line>
+% !
+% ! <text>
+% !...............................................
+% \end{verbatim}
+% where the \meta{text} will be wrapped to fit within the current
+% line length. The user may then request more information, at which
+% stage the \meta{extra text} will be shown in the terminal in the
+% format
+% \begin{verbatim}
+% |'''''''''''''''''''''''''''''''''''''''''''''''
+% | <extra text>
+% |...............................................
+% \end{verbatim}
+% where the \meta{extra text} will be wrapped to fit within the current
+% line length.
+% \end{function}
+%
+% \begin{function}{\msg_log:x}
+% \begin{syntax}
+% \cs{msg_log:x} \Arg{text}
+% \end{syntax}
+% Writes to the log file with the \meta{text} laid out in the format
+% \begin{verbatim}
+% .................................................
+% . <text>
+% .................................................
+% \end{verbatim}
+% where the \meta{text} will be wrapped to fit within the current
+% line length.
+% \end{function}
+%
+% \begin{function}{\msg_term:x}
+% \begin{syntax}
+% \cs{msg_term:x} \Arg{text}
+% \end{syntax}
+% Writes to the terminal and log file with the \meta{text} laid out in the
+% format
+% \begin{verbatim}
+% *************************************************
+% * <text>
+% *************************************************
+% \end{verbatim}
+% where the \meta{text} will be wrapped to fit within the current
+% line length.
+% \end{function}
+%
+% \section{Kernel-specific functions}
+%
+% Messages from \LaTeX3 itself are handled by the general message system,
+% but have their own functions. This allows some text to be pre-defined,
+% and also ensures that serious errors can be handled properly.
+%
+% \begin{function}{\msg_kernel_new:nnnn, \msg_kernel_new:nnn}
+% \begin{syntax}
+% \cs{msg_kernel_new:nnnn} \Arg{module} \Arg{message} \Arg{text}
+% ~~\Arg{more text}
+% \end{syntax}
+% Creates a kernel \meta{message} for a given \meta{module}.
+% The message will be defined to first give \meta{text} and then
+% \meta{more text} if the user requests it. If no \meta{more text} is
+% available then a standard text is given instead. Within \meta{text}
+% and \meta{more text} four parameters (|#1| to |#4|) can be used:
+% these will be supplied at the time the message is used. The
+% parameters will be expanded when the message is used. Within the
+% \meta{text} and \meta{more text} |\\| can be used to start a new
+% line. An error will be raised if the \meta{message} already exists.
+% \end{function}
+%
+% \begin{function}{\msg_kernel_set:nnnn, \msg_kernel_set:nnn}
+% \begin{syntax}
+% \cs{msg_kernel_set:nnnn} \Arg{module} \Arg{message} \Arg{text}
+% ~~\Arg{more text}
+% \end{syntax}
+% Sets up the text for a kernel \meta{message} for a given \meta{module}.
+% The message will be defined to first give \meta{text} and then
+% \meta{more text} if the user requests it. If no \meta{more text} is
+% available then a standard text is given instead. Within \meta{text}
+% and \meta{more text} four parameters (|#1| to |#4|) can be used:
+% these will be supplied at the time the message is used. The
+% parameters will be expanded when the message is used. Within the
+% \meta{text} and \meta{more text} |\\| can be used to start a new
+% line.
+% \end{function}
+%
+% \begin{function}
+% {
+% \msg_kernel_fatal:nnxxxx ,
+% \msg_kernel_fatal:nnxxx ,
+% \msg_kernel_fatal:nnxx ,
+% \msg_kernel_fatal:nnx ,
+% \msg_kernel_fatal:nn
+% }
+% \begin{syntax}
+% \cs{msg_kernel_fatal:nnxxxx} \Arg{module} \Arg{message} \Arg{arg one}
+% ~~\Arg{arg two} \Arg{arg three} \Arg{arg four}
+% \end{syntax}
+% Issues kernel \meta{module} error \meta{message}, passing \meta{arg one}
+% to \meta{arg four} to the text-creating functions. After issuing a
+% fatal error the \TeX{} run will halt. Cannot be redirected.
+% \end{function}
+%
+% \begin{function}
+% {
+% \msg_kernel_error:nnxxxx ,
+% \msg_kernel_error:nnxxx ,
+% \msg_kernel_error:nnxx ,
+% \msg_kernel_error:nnx ,
+% \msg_kernel_error:nn
+% }
+% \begin{syntax}
+% \cs{msg_kernel_error:nnxxxx} \Arg{module} \Arg{message} \Arg{arg one}
+% ~~\Arg{arg two} \Arg{arg three} \Arg{arg four}
+% \end{syntax}
+% Issues kernel \meta{module} error \meta{message}, passing \meta{arg one}
+% to
+% \meta{arg four} to the text-creating functions. The error will
+% stop processing and issue the text at the terminal. After user input,
+% the run will continue. Cannot be redirected.
+% \end{function}
+%
+% \begin{function}
+% {
+% \msg_kernel_warning:nnxxxx ,
+% \msg_kernel_warning:nnxxx ,
+% \msg_kernel_warning:nnxx ,
+% \msg_kernel_warning:nnx ,
+% \msg_kernel_warning:nn
+% }
+% \begin{syntax}
+% \cs{msg_kernel_warning:nnxxxx} \Arg{module} \Arg{message} \Arg{arg one}
+% ~~\Arg{arg two} \Arg{arg three} \Arg{arg four}
+% \end{syntax}
+% Issues kernel \meta{module} warning \meta{message}, passing
+% \meta{arg one} to
+% \meta{arg four} to the text-creating functions. The warning text
+% will be added to the log file, but the \TeX{} run will not be
+% interrupted.
+% \end{function}
+%
+% \begin{function}
+% {
+% \msg_kernel_info:nnxxxx ,
+% \msg_kernel_info:nnxxx ,
+% \msg_kernel_info:nnxx ,
+% \msg_kernel_info:nnx ,
+% \msg_kernel_info:nn
+% }
+% \begin{syntax}
+% \cs{msg_kernel_info:nnxxxx} \Arg{module} \Arg{message} \Arg{arg one}
+% ~~\Arg{arg two} \Arg{arg three} \Arg{arg four}
+% \end{syntax}
+% Issues kernel \meta{module} information \meta{message}, passing
+% \meta{arg one} to \meta{arg four} to the text-creating functions.
+% The information text will be added to the log file.
+% \end{function}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3msg} implementation}
+%
+% \begin{macrocode}
+%<*initex|package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*package>
+\ProvidesExplPackage
+ {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
+\package_check_loaded_expl:
+%</package>
+% \end{macrocode}
+%
+% \begin{variable}{\l_msg_tmp_tl}
+% A general scratch for the module.
+% \begin{macrocode}
+\tl_new:N \l_msg_tmp_tl
+% \end{macrocode}
+% \end{variable}
+%
+%\section{Creating messages}
+%
+% Messages are created and used separately, so there two parts to
+% the code here. First, a mechanism for creating message text.
+% This is pretty simple, as there is not actually a lot to do.
+%
+%\begin{variable}{\c_msg_text_prefix_tl, \c_msg_more_text_prefix_tl}
+% Locations for the text of messages.
+% \begin{macrocode}
+\tl_const:Nn \c_msg_text_prefix_tl { msg~text~>~ }
+\tl_const:Nn \c_msg_more_text_prefix_tl { msg~extra~text~>~ }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\msg_new:nnnn, \msg_new:nnn}
+% \begin{macro}{\msg_set:nnnn, \msg_set:nnn}
+% Setting a message simply means saving the appropriate text
+% into two functions. A sanity check first.
+% \begin{macrocode}
+\cs_new_protected:Npn \msg_new:nnnn #1#2
+ {
+ \cs_if_exist:cT { \c_msg_text_prefix_tl #1 / #2 }
+ {
+ \msg_kernel_error:nn { msg } { message-already-defined }
+ {#1} {#2}
+ }
+ \msg_set:nnnn {#1} {#2}
+ }
+\cs_new_protected:Npn \msg_new:nnn #1#2#3
+ { \msg_new:nnnn {#1} {#2} {#3} { } }
+\cs_new_protected:Npn \msg_set:nnnn #1#2#3#4
+ {
+ \cs_set:cpn { \c_msg_text_prefix_tl #1 / #2 }
+ ##1##2##3##4 {#3}
+ \cs_set:cpn { \c_msg_more_text_prefix_tl #1 / #2 }
+ ##1##2##3##4 {#4}
+ }
+\cs_new_protected:Npn \msg_set:nnn #1#2#3
+ { \msg_set:nnnn {#1} {#2} {#3} { } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Messages: support functions and text}
+%
+% \begin{variable}
+% {
+% \c_msg_coding_error_text_tl ,
+% \c_msg_continue_text_tl ,
+% \c_msg_critical_text_tl ,
+% \c_msg_fatal_text_tl ,
+% \c_msg_help_text_tl ,
+% \c_msg_no_info_text_tl ,
+% \c_msg_on_line_tl ,
+% \c_msg_return_text_tl ,
+% \c_msg_trouble_text_tl
+% }
+% Simple pieces of text for messages.
+% \begin{macrocode}
+\tl_const:Nn \c_msg_coding_error_text_tl
+ {
+ This~is~a~coding~error.
+ \\ \\
+ }
+\tl_const:Nn \c_msg_continue_text_tl
+ { Type~<return>~to~continue }
+\tl_const:Nn \c_msg_critical_text_tl
+ { Reading~the~current~file~will~stop }
+\tl_const:Nn \c_msg_fatal_text_tl
+ { This~is~a~fatal~error:~LaTeX~will~abort }
+\tl_const:Nn \c_msg_help_text_tl
+ { For~immediate~help~type~H~<return> }
+\tl_const:Nn \c_msg_no_info_text_tl
+ {
+ LaTeX~does~not~know~anything~more~about~this~error,~sorry.
+ \c_msg_return_text_tl
+ }
+\tl_const:Nn \c_msg_on_line_text_tl { on~line }
+\tl_const:Nn \c_msg_return_text_tl
+ {
+ \\ \\
+ Try~typing~<return>~to~proceed.
+ \\
+ If~that~doesn't~work,~type~X~<return>~to~quit.
+ }
+\tl_const:Nn \c_msg_trouble_text_tl
+ {
+ \\ \\
+ More~errors~will~almost~certainly~follow: \\
+ the~LaTeX~run~should~be~aborted.
+ }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\msg_newline:, \msg_two_newlines:}
+% New lines are printed in the same way as for low-level file writing.
+% \begin{macrocode}
+\cs_new_nopar:Npn \msg_newline: { ^^J }
+\cs_new_nopar:Npn \msg_two_newlines: { ^^J ^^J }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\msg_line_number:}
+% \begin{macro}{\msg_line_context:}
+% For writing the line number nicely.
+% \begin{macrocode}
+\cs_new_nopar:Npn \msg_line_number: { \int_use:N \tex_inputlineno:D }
+\cs_set_nopar:Npn \msg_line_context:
+ {
+ \c_msg_on_line_text_tl
+ \c_space_tl
+ \msg_line_number:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Showing messages: low level mechanism}
+%
+% \begin{variable}{\c_msg_hide_tl}
+% \begin{variable}[aux]{\c_msg_hide_tl<dots>}
+% An empty variable with a number of (category code 11) periods at the
+% end of its name. This is used to push the \TeX{} part of an error
+% message \enquote{off the screen}. Using two variables here means that
+% later life is a little easier.
+% \begin{macrocode}
+\char_set_catcode_letter:N \.
+\tl_new:N
+ \c_msg_hide_tl..........................................................
+\tl_const:Nn \c_msg_hide_tl
+ { \c_msg_hide_tl.......................................................... }
+\char_set_catcode_other:N \.
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+%
+% \begin{macro}{\msg_interrupt:xxx}
+% \begin{macro}[aux]{\msg_interrupt_no_details:xx}
+% \begin{macro}[aux]{\msg_interrupt_details:xxx}
+% \begin{macro}[aux]{\msg_interrupt_text:n}
+% \begin{macro}[aux]{\msg_interrupt_more_text:n}
+% \begin{macro}[aux]{\msg_interrupt_aux:}
+% The low-level interruption macro is rather opaque, unfortunately. The
+% idea here is to create a a message which hides all of \TeX{}'s own
+% information by filling the output up with dots. To achieve this,
+% dots have to be letters. The odd
+% \cs{c_msg_hide_tl<dots>} actually does the hiding: it is the
+% large run of dots in the name that is important here. The meaning
+% of |\\| is altered so that the explanation text is a simple run
+% whilst the initial error has line-continuation shown.
+% \begin{macrocode}
+\cs_new_protected:Npn \msg_interrupt:xxx #1#2#3
+ {
+ \group_begin:
+ \tl_if_empty:nTF {#3}
+ { \msg_interrupt_no_details:xx {#1} {#2} }
+ { \msg_interrupt_details:xxx {#1} {#2} {#3} }
+ \msg_interrupt_aux:
+ \group_end:
+ }
+% \end{macrocode}
+% \begin{macrocode}
+% Depending on the availability of more information there is a choice of
+% how to set up the further help. The extra help text has to be set
+% before the message itself can be issued. Everything is done using
+% \texttt{x}-type expansion as the new line markers are different for
+% the two type of text and need to be correctly set up.
+% \begin{macrocode}
+\cs_new_protected:Npn \msg_interrupt_no_details:xx #1#2
+ {
+ \iow_wrap:xnnnN
+ { \\ \c_msg_no_info_text_tl }
+ { |~ } { 2 } { } \msg_interrupt_more_text:n
+ \iow_wrap:xnnnN { #1 \\ \\ #2 \\ \\ \c_msg_continue_text_tl }
+ { ! ~ } { 2 } {} \msg_interrupt_text:n
+ }
+\cs_new_protected:Npn \msg_interrupt_details:xxx #1#2#3
+ {
+ \iow_wrap:xnnnN
+ { \\ #3 }
+ { |~ } { 2 } { } \msg_interrupt_more_text:n
+ \iow_wrap:xnnnN { #1 \\ \\ #2 \\ \\ \c_msg_help_text_tl }
+ { ! ~ } { 2 } { } \msg_interrupt_text:n
+ }
+\cs_new_protected:Npn \msg_interrupt_text:n #1
+ { \tl_set:Nn \l_msg_text_tl {#1} }
+\cs_new_protected:Npn \msg_interrupt_more_text:n #1
+ {
+%<*initex>
+ \tl_set:Nx \l_msg_tmp_tl
+%</initex>
+%<*package>
+ \protected@edef \l_msg_tmp_tl
+%</package>
+ {
+ |'''''''''''''''''''''''''''''''''''''''''''''''
+ #1
+ \msg_newline:
+ |...............................................
+ }
+ \tex_errhelp:D \exp_after:wN { \l_msg_tmp_tl }
+ }
+% \end{macrocode}
+% The business end of the process starts by producing some visual
+% separation of the message from the main part of the log. It then
+% adds the hiding text to the message to print. The error message needs
+% to be printed with everything made \enquote{invisible}: this is where
+% the strange business with |&| comes in: this is made into another
+% |!|. There is also a closing brace that will show up in the output,
+% which is turned into a blank space.
+% \begin{macrocode}
+\group_begin: % {
+ \char_set_lccode:w `\} = `\ \scan_stop:
+ \char_set_lccode:w `\& = `\! \scan_stop:
+ \char_set_catcode_active:N \&
+\tl_to_lowercase:n
+ {
+ \group_end:
+ \cs_new_protected:Npn \msg_interrupt_aux:
+ {
+ \iow_term:x
+ {
+ \iow_newline:
+ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ \iow_newline:
+ !
+ }
+ \tl_put_right:No \l_msg_text_tl { \c_msg_hide_tl }
+ \cs_set_protected_nopar:Npx &
+ { \tex_errmessage:D { \exp_not:o { \l_msg_text_tl } } }
+ &
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\msg_log:x}
+% \begin{macro}{\msg_term:x}
+% Printing to the log or terminal without a stop is rather easier.
+% A bit of simple visual work sets things off nicely.
+% \begin{macrocode}
+\cs_new_protected:Npn \msg_log:x #1
+ {
+ \iow_log:x { ................................................. }
+ \iow_wrap:xnnnN { . ~ #1} { . ~ } { 2 } { }
+ \iow_log:x
+ \iow_log:x { ................................................. }
+ }
+\cs_new_protected:Npn \msg_term:x #1
+ {
+ \iow_term:x { ************************************************* }
+ \iow_wrap:xnnnN { * ~ #1} { * ~ } { 2 } { }
+ \iow_term:x
+ \iow_term:x { ************************************************* }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \subsection{Displaying messages}
+%
+% \LaTeX{} is handling error messages and so the \TeX{} ones are disabled.
+% \begin{macrocode}
+\int_set:Nn \tex_errorcontextlines:D { -1 }
+% \end{macrocode}
+%
+% \begin{macro}
+% {
+% \msg_fatal_text:n ,
+% \msg_critical_text:n ,
+% \msg_error_text:n ,
+% \msg_warning_text:n ,
+% \msg_info_text:n
+% }
+% A function for issuing messages: both the text and order could
+% in principal vary.
+% \begin{macrocode}
+\cs_new_nopar:Npn \msg_fatal_text:n #1 { Fatal~#1~error }
+\cs_new_nopar:Npn \msg_critical_text:n #1 { Critical~#1~error }
+\cs_new_nopar:Npn \msg_error_text:n #1 { #1~error }
+\cs_new_nopar:Npn \msg_warning_text:n #1 { #1~warning }
+\cs_new_nopar:Npn \msg_info_text:n #1 { #1~info }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\msg_see_documentation_text:n}
+% Contextual footer information.
+% \begin{macrocode}
+\cs_new_nopar:Npn \msg_see_documentation_text:n #1
+ { \\ \\ See~the~#1~documentation~for~further~information. }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}{\l_msg_redirect_classes_prop, \l_msg_redirect_names_prop}
+% For filtering messages, a list of all messages and of those which have
+% to be modified is required.
+% \begin{macrocode}
+\prop_new:N \l_msg_redirect_classes_prop
+\prop_new:N \l_msg_redirect_names_prop
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\msg_class_set:nn}
+% Setting up a message class does two tasks. Any existing redirection
+% is cleared, and the various message functions are created
+% to simply use the code stored for the message.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \msg_class_set:nn #1#2
+ {
+ \prop_clear_new:c { l_msg_redirect_ #1 _prop }
+ \cs_set_protected:cpn { msg_ #1 :nnxxxx } ##1##2##3##4##5##6
+ { \msg_use:nnnnxxxx {#1} {#2} {##1} {##2} {##3} {##4} {##5} {##6} }
+ \cs_set_protected:cpx { msg_ #1 :nnxxx } ##1##2##3##4##5
+ { \exp_not:c { msg_ #1 :nnxxxx } {##1} {##2} {##3} {##4} {##5} { } }
+ \cs_set_protected:cpx { msg_ #1 :nnxx } ##1##2##3##4
+ { \exp_not:c { msg_ #1 :nnxxxx } {##1} {##2} {##3} {##4} { } { } }
+ \cs_set_protected:cpx { msg_ #1 :nnx } ##1##2##3
+ { \exp_not:c { msg_ #1 :nnxxxx } {##1} {##2} {##3} { } { } { } }
+ \cs_set_protected:cpx { msg_ #1 :nn } ##1##2
+ { \exp_not:c { msg_ #1 :nnxxxx } {##1} {##2} { } { } { } { } }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\msg_if_more_text:N, \msg_if_more_text:c}
+% \begin{macro}[aux]{\msg_no_more_text:xxxx}
+% A test to see if any more text is available, using a
+% permanently-empty text function.
+% \begin{macrocode}
+\prg_set_conditional:Npnn \msg_if_more_text:N #1 { p , T , F , TF }
+ {
+ \cs_if_eq:NNTF #1 \msg_no_more_text:xxxx
+ { \prg_return_false: }
+ { \prg_return_true: }
+ }
+\cs_new:Npn \msg_no_more_text:xxxx #1#2#3#4 { }
+\cs_generate_variant:Nn \msg_if_more_text_p:N { c }
+\cs_generate_variant:Nn \msg_if_more_text:NT { c }
+\cs_generate_variant:Nn \msg_if_more_text:NF { c }
+\cs_generate_variant:Nn \msg_if_more_text:NTF { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+%\begin{macro}
+% {
+% \msg_fatal:nnxxxx ,
+% \msg_fatal:nnxxx ,
+% \msg_fatal:nnxx ,
+% \msg_fatal:nnx ,
+% \msg_fatal:nn
+% }
+% For fatal errors, after the error message \TeX{} bails out.
+% \begin{macrocode}
+\msg_class_set:nn { fatal }
+ {
+ \msg_interrupt:xxx
+ { \msg_fatal_text:n {#1} : ~ "#2" }
+ {
+ \use:c { \c_msg_text_prefix_tl #1 / #2 } {#3} {#4} {#5} {#6}
+ \msg_see_documentation_text:n {#1}
+ }
+ { \c_msg_fatal_text_tl }
+ \tex_end:D
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \msg_critical:nnxxxx ,
+% \msg_critical:nnxxx ,
+% \msg_critical:nnxx ,
+% \msg_critical:nnx ,
+% \msg_critical:nn
+% }
+% Not quite so bad: just end the current file.
+% \begin{macrocode}
+\msg_class_set:nn { critical }
+ {
+ \msg_interrupt:xxx
+ { \msg_critical_text:n {#1} : ~ "#2" }
+ {
+ \use:c { \c_msg_text_prefix_tl #1 / #2 } {#3} {#4} {#5} {#6}
+ \msg_see_documentation_text:n {#1}
+ }
+ { \c_msg_critical_text_tl }
+ \tex_endinput:D
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \msg_error:nnxxxx ,
+% \msg_error:nnxxx ,
+% \msg_error:nnxx ,
+% \msg_error:nnx ,
+% \msg_error:nn
+% }
+% For an error, the interrupt routine is called, then any recovery code
+% is tried.
+% \begin{macrocode}
+\msg_class_set:nn { error }
+ {
+ \msg_if_more_text:cTF { \c_msg_more_text_prefix_tl #1 / #2 }
+ {
+ \msg_interrupt:xxx
+ { \msg_error_text:n {#1} : ~ "#2" }
+ {
+ \use:c { \c_msg_text_prefix_tl #1 / #2 } {#3} {#4} {#5} {#6}
+ \msg_see_documentation_text:n {#1}
+ }
+ { \use:c { \c_msg_more_text_prefix_tl #1 / #2 } {#3} {#4} {#5} {#6} }
+ }
+ {
+ \msg_interrupt:xxx
+ { \msg_error_text:n {#1} : ~ "#2" }
+ {
+ \use:c { \c_msg_text_prefix_tl #1 / #2 } {#3} {#4} {#5} {#6}
+ \msg_see_documentation_text:n {#1}
+ }
+ { }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \msg_warning:nnxxxx ,
+% \msg_warning:nnxxx ,
+% \msg_warning:nnxx ,
+% \msg_warning:nnx ,
+% \msg_warning:nn
+% }
+% Warnings are printed to the terminal.
+% \begin{macrocode}
+\msg_class_set:nn { warning }
+ {
+ \msg_term:x
+ {
+ \msg_warning_text:n {#1} : ~ "#2" \\ \\
+ \use:c { \c_msg_text_prefix_tl #1 / #2 } {#3} {#4} {#5} {#6}
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \msg_info:nnxxxx ,
+% \msg_info:nnxxx ,
+% \msg_info:nnxx ,
+% \msg_info:nnx ,
+% \msg_info:nn
+% }
+% Information only goes into the log.
+% \begin{macrocode}
+\msg_class_set:nn { info }
+ {
+ \msg_log:x
+ {
+ \msg_info_text:n {#1} : ~ "#2" \\ \\
+ \use:c { \c_msg_text_prefix_tl #1 / #2 } {#3} {#4} {#5} {#6}
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \msg_log:nnxxxx ,
+% \msg_log:nnxxx ,
+% \msg_log:nnxx ,
+% \msg_log:nnx ,
+% \msg_log:nn
+% }
+% \enquote{Log} data is very similar to information, but with no extras
+% added.
+% \begin{macrocode}
+\msg_class_set:nn { log }
+ {
+ \msg_log:x
+ { \use:c { \c_msg_text_prefix_tl #1 / #2 } {#3} {#4} {#5} {#6} }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \msg_none:nnxxxx ,
+% \msg_none:nnxxx ,
+% \msg_none:nnxx ,
+% \msg_none:nnx ,
+% \msg_none:nn
+% }
+% The \texttt{none} message type is needed so that input can be gobbled.
+% \begin{macrocode}
+\msg_class_set:nn { none } { }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}
+% {
+% \l_msg_redirect_classes_seq ,
+% \l_msg_class_tl ,
+% \l_msg_current_class_tl ,
+% \l_msg_current_module_tl
+% }
+% Support variables needed for the redirection system.
+% \begin{macrocode}
+\seq_new:N \l_msg_redirect_classes_seq
+\tl_new:N \l_msg_class_tl
+\tl_new:N \l_msg_current_class_tl
+\tl_new:N \l_msg_current_module_tl
+% \end{macrocode}
+%\end{variable}
+%
+% \begin{macro}[int]{\msg_use:nnnnxxxx}
+% \begin{macro}[aux]{\msg_use_aux:nnn}
+% \begin{macro}[aux]{\msg_use_aux:nn}
+% \begin{macro}[aux]{\msg_use_loop_check:nn}
+% \begin{macro}[aux]{\msg_use_code:}
+% \begin{macro}[aux]{\msg_use_loop:n, \msg_use_loop:o}
+% The main message-using macro creates two auxiliary functions: one
+% containing the code for the message, and the second a loop function.
+% There is then a hand-off to the system for checking if redirection is
+% needed.
+% \begin{macrocode}
+\cs_new_protected:Npn \msg_use:nnnnxxxx #1#2#3#4#5#6#7#8
+ {
+ \cs_set_protected_nopar:Npx \msg_use_code:
+ {
+ \seq_clear:N \exp_not:N \l_msg_redirect_classes_seq
+ \exp_not:n {#2}
+ }
+ \cs_set_protected:Npx \msg_use_loop:n ##1
+ {
+ \seq_if_in:NnTF \exp_not:n \l_msg_redirect_classes_seq {#1}
+ { \msg_kernel_error:nn { msg } { message-loop } {#1} }
+ {
+ \seq_put_right:Nn \exp_not:N \l_msg_redirect_classes_seq {#1}
+ \exp_not:N \cs_if_exist:cTF { msg_ ##1 :nnxxxx }
+ {
+ \exp_not:N \use:c { msg_ ##1 :nnxxxx }
+ \exp_not:n { {#3} {#4} {#5} {#6} {#7} {#8} }
+ }
+ {
+ \msg_kernel_error:nnx { msg } { message-class-unknown } {##1}
+ }
+ }
+ }
+ \cs_if_exist:cTF { \c_msg_text_prefix_tl #3 / #4 }
+ { \msg_use_aux:nnn {#1} {#3} {#4} }
+ { \msg_kernel_error:nnxx { msg } { message-unknown } {#3} {#4} }
+ }
+% \end{macrocode}
+% The first auxiliary macro looks for a match by name: the most
+% restrictive check.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \msg_use_aux:nnn #1#2#3
+ {
+ \tl_set:Nn \l_msg_current_class_tl {#1}
+ \tl_set:Nn \l_msg_current_module_tl {#2}
+ \prop_if_in:NnTF \l_msg_redirect_names_prop { // #2 / #3 / }
+ { \msg_use_loop_check:nn { names } { // #2 / #3 / } }
+ { \msg_use_aux:nn {#1} {#2} }
+ }
+% \end{macrocode}
+% The second function checks for general matches by module or for
+% all modules.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \msg_use_aux:nn #1#2
+ {
+ \prop_if_in:cnTF { l_msg_redirect_ #1 _prop } {#2}
+ { \msg_use_loop_check:nn {#1} {#2} }
+ {
+ \prop_if_in:cnTF { l_msg_redirect_ #1 _prop } { * }
+ { \msg_use_loop_check:nn {#1} { * } }
+ { \msg_use_code: }
+ }
+ }
+% \end{macrocode}
+% When checking whether to loop, the same code is needed in a few
+% places.
+% \begin{macrocode}
+\cs_new_protected:Npn \msg_use_loop_check:nn #1#2
+ {
+ \prop_get:cnN { l_msg_redirect_ #1 _prop } {#2} \l_msg_class_tl
+ \tl_if_eq:NNTF \l_msg_current_class_tl \l_msg_class_tl
+ {
+ { \msg_use_code: }
+ { \msg_use_loop:o \l_msg_class_tl }
+ }
+ }
+\cs_new_protected_nopar:Npn \msg_use_code: { }
+\cs_new_protected:Npn \msg_use_loop:n #1 { }
+\cs_generate_variant:Nn \msg_use_loop:n { o }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\msg_redirect_class:nn}
+% Converts class one into class two.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \msg_redirect_class:nn #1#2
+ { \prop_put:cnn { l_msg_redirect_ #1 _prop } { * } {#2} }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\msg_redirect_module:nnn}
+% For when all messages of a class should be altered for a given module.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \msg_redirect_module:nnn #1#2#3
+ { \prop_put:cnn { l_msg_redirect_ #2 _prop } {#1} {#3} }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\msg_redirect_name:nnn}
+% Named message will always use the given class.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \msg_redirect_name:nnn #1#2#3
+ { \prop_put:Nnn \l_msg_redirect_names_prop { // #1 / #2 / } {#3} }
+% \end{macrocode}
+%\end{macro}
+%
+% \subsection{Kernel-specific functions}
+%
+% \begin{macro}{\msg_kernel_new:nnnn}
+% \begin{macro}{\msg_kernel_new:nnn}
+% \begin{macro}{\msg_kernel_set:nnnn}
+% \begin{macro}{\msg_kernel_set:nnn}
+% The kernel needs some messages of its own. These are created using
+% pre-built functions. Two functions are provided: one more general
+% and one which only has the short text part.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \msg_kernel_new:nnnn #1#2
+ { \msg_new:nnnn { LaTeX } { #1 / #2 } }
+\cs_new_protected_nopar:Npn \msg_kernel_new:nnn #1#2
+ { \msg_new:nnn { LaTeX } { #1 / #2 } }
+\cs_new_protected_nopar:Npn \msg_kernel_set:nnnn #1#2
+ { \msg_set:nnnn { LaTeX } { #1 / #2 } }
+\cs_new_protected_nopar:Npn \msg_kernel_set:nnn #1#2
+ { \msg_set:nnn { LaTeX } { #1 / #2 } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\msg_kernel_fatal:nnxxxx}
+% \begin{macro}{\msg_kernel_fatal:nnxxx}
+% \begin{macro}{\msg_kernel_fatal:nnxx}
+% \begin{macro}{\msg_kernel_fatal:nnx}
+% \begin{macro}{\msg_kernel_fatal:nn}
+% Fatal kernel errors cannot be re-defined.
+% \begin{macrocode}
+\cs_new_protected:Npn \msg_kernel_fatal:nnxxxx #1#2#3#4#5#6
+ {
+ \msg_interrupt:xxx
+ { \msg_fatal_text:n { LaTeX } : ~ "#1 / #2" }
+ {
+ \use:c { \c_msg_text_prefix_tl LaTeX / #1 / #2 }
+ {#3} {#4} {#5} {#6}
+ \msg_see_documentation_text:n { LaTeX3 }
+ }
+ { \c_msg_fatal_text_tl }
+ \tex_end:D
+ }
+\cs_new_protected:Npn \msg_kernel_fatal:nnxxx #1#2#3#4#5
+ {\msg_kernel_fatal:nnxxxx {#1} {#2} {#3} {#4} {#5} { } }
+\cs_new_protected:Npn \msg_kernel_fatal:nnxx #1#2#3#4
+ { \msg_kernel_fatal:nnxxxx {#1} {#2} {#3} {#4} { } { } }
+\cs_new_protected:Npn \msg_kernel_fatal:nnx #1#2#3
+ { \msg_kernel_fatal:nnxxxx {#1} {#2} {#3} { } { } { } }
+\cs_new_protected:Npn \msg_kernel_fatal:nn #1#2
+ { \msg_kernel_fatal:nnxxxx {#1} {#2} { } { } { } { } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\msg_kernel_error:nnxxxx}
+% \begin{macro}{\msg_kernel_error:nnxxx}
+% \begin{macro}{\msg_kernel_error:nnxx}
+% \begin{macro}{\msg_kernel_error:nnx}
+% \begin{macro}{\msg_kernel_error:nn}
+% Neither can kernel errors.
+% \begin{macrocode}
+\cs_new_protected:Npn \msg_kernel_error:nnxxxx #1#2#3#4#5#6
+ {
+ \msg_if_more_text:cTF { \c_msg_more_text_prefix_tl LaTeX / #1 / #2 }
+ {
+ \msg_interrupt:xxx
+ { \msg_error_text:n { LaTeX } : ~ " #1 / #2 " }
+ {
+ \use:c { \c_msg_text_prefix_tl LaTeX / #1 / #2 }
+ {#3} {#4} {#5} {#6}
+ \msg_see_documentation_text:n { LaTeX3 }
+ }
+ {
+ \use:c { \c_msg_more_text_prefix_tl LaTeX / #1 / #2 }
+ {#3} {#4} {#5} {#6}
+ }
+ }
+ {
+ \msg_interrupt:xxx
+ { \msg_error_text:n { LaTeX } : ~ " #1 / #2 " }
+ {
+ \use:c { \c_msg_text_prefix_tl LaTeX / #1 / #2 }
+ {#3} {#4} {#5} {#6}
+ \msg_see_documentation_text:n { LaTeX3 }
+ }
+ { }
+ }
+ }
+\cs_new_protected:Npn \msg_kernel_error:nnxxx #1#2#3#4#5
+ {\msg_kernel_error:nnxxxx {#1} {#2} {#3} {#4} {#5} { } }
+\cs_set_protected:Npn \msg_kernel_error:nnxx #1#2#3#4
+ { \msg_kernel_error:nnxxxx {#1} {#2} {#3} {#4} { } { } }
+\cs_set_protected:Npn \msg_kernel_error:nnx #1#2#3
+ { \msg_kernel_error:nnxxxx {#1} {#2} {#3} { } { } { } }
+\cs_set_protected:Npn \msg_kernel_error:nn #1#2
+ { \msg_kernel_error:nnxxxx {#1} {#2} { } { } { } { } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\msg_kernel_warning:nnxxxx}
+% \begin{macro}{\msg_kernel_warning:nnxxx}
+% \begin{macro}{\msg_kernel_warning:nnxx}
+% \begin{macro}{\msg_kernel_warning:nnx}
+% \begin{macro}{\msg_kernel_warning:nn}
+% \begin{macro}{\msg_kernel_info:nnxxxx}
+% \begin{macro}{\msg_kernel_info:nnxxx}
+% \begin{macro}{\msg_kernel_info:nnxx}
+% \begin{macro}{\msg_kernel_info:nnx}
+% \begin{macro}{\msg_kernel_info:nn}
+% Kernel messages which can be redirected.
+% \begin{macrocode}
+\prop_new:N \l_msg_redirect_kernel_warning_prop
+\cs_new_protected:Npn \msg_kernel_warning:nnxxxx #1#2#3#4#5#6
+ {
+ \msg_use:nnnnxxxx { warning }
+ {
+ \msg_term:x
+ {
+ \msg_warning_text:n { LaTeX } : ~ " #1 / #2 " \\ \\
+ \use:c { \c_msg_text_prefix_tl LaTeX / #1 / #2 }
+ {#3} {#4} {#5} {#6}
+ }
+ }
+ { LaTeX } { #1 / #2 } {#3} {#4} {#5} {#6}
+ }
+\cs_new_protected:Npn \msg_kernel_warning:nnxxx #1#2#3#4#5
+ { \msg_kernel_warning:nnxxxx {#1} {#2} {#3} {#4} {#5} { } }
+\cs_new_protected:Npn \msg_kernel_warning:nnxx #1#2#3#4
+ { \msg_kernel_warning:nnxxxx {#1} {#2} {#3} {#4} { } { } }
+\cs_new_protected:Npn \msg_kernel_warning:nnx #1#2#3
+ { \msg_kernel_warning:nnxxxx {#1} {#2} {#3} { } { } { } }
+\cs_new_protected:Npn \msg_kernel_warning:nn #1#2
+ { \msg_kernel_warning:nnxxxx {#1} {#2} { } { } { } { } }
+\prop_new:N \l_msg_redirect_kernel_info_prop
+\cs_new_protected:Npn \msg_kernel_info:nnxxxx #1#2#3#4#5#6
+ {
+ \msg_use:nnnnxxxx { info }
+ {
+ \msg_log:x
+ {
+ \msg_info_text:n { LaTeX } : ~ " #1 / #2 " \\ \\
+ \use:c { \c_msg_text_prefix_tl LaTeX / #1 / #2 }
+ {#3} {#4} {#5} {#6}
+ }
+ }
+ { LaTeX } { #1 / #2 } {#3} {#4} {#5} {#6}
+ }
+\cs_new_protected:Npn \msg_kernel_info:nnxxx #1#2#3#4#5
+ { \msg_kernel_info:nnxxxx {#1} {#2} {#3} {#4} {#5} { } }
+\cs_new_protected:Npn \msg_kernel_info:nnxx #1#2#3#4
+ { \msg_kernel_info:nnxxxx {#1} {#2} {#3} {#4} { } { } }
+\cs_new_protected:Npn \msg_kernel_info:nnx #1#2#3
+ { \msg_kernel_info:nnxxxx {#1} {#2} {#3} { } { } { } }
+\cs_new_protected:Npn \msg_kernel_info:nn #1#2
+ { \msg_kernel_info:nnxxxx {#1} {#2} { } { } { } { } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% Error messages needed to actually implement the message system
+% itself.
+% \begin{macrocode}
+\msg_kernel_new:nnnn { msg } { message-already-defined }
+ { Message~'#2'~for~module~'#1'~already~defined. }
+ {
+ \c_msg_coding_error_text_tl
+ LaTeX~was~asked~to~define~a~new~message~called~'#2'
+ by~the~module~'#1'~module:\\
+ this~message~already~exists.
+ \c_msg_return_text_tl
+ }
+\msg_kernel_new:nnnn { msg } { message-unknown }
+ { Unknown~message~'#2'~for~module~'#1'. }
+ {
+ \c_msg_coding_error_text_tl
+ LaTeX~was~asked~to~display~a~message~called~'#2'\\
+ by~the~module~'#1'~module:~this~message~does~not~exist.
+ \c_msg_return_text_tl
+ }
+\msg_kernel_new:nnnn { msg } { message-class-unknown }
+ { Unknown~message~class~'#1'. }
+ {
+ LaTeX~has~been~asked~to~redirect~messages~to~a~class~'#1':\\
+ this~was~never~defined.
+ \c_msg_return_text_tl
+ }
+\msg_kernel_new:nnnn { msg } { redirect-loop }
+ { Message~redirection~loop~for~message~class~'#1'. }
+ {
+ LaTeX~has~been~asked~to~redirect~messages~in~an~infinite~loop.\\
+ The~original~message~here~has~been~lost.
+ \c_msg_return_text_tl
+ }
+% \end{macrocode}
+%
+% Messages for earlier kernel modules.
+% \begin{macrocode}
+\msg_kernel_new:nnnn { kernel } { bad-number-of-arguments }
+ { Function~'#1'~cannot~be~defined~with~#2~arguments. }
+ {
+ \c_msg_coding_error_text_tl
+ LaTeX~has~been~asked~to~define~a~function~'#1'~with~
+ #2~arguments. \\
+ TeX~allows~between~0~and~9~arguments~for~a~single~function.
+ }
+\msg_kernel_new:nnnn { kernel } { command-already-defined }
+ { Control~sequence~#1~already~defined. }
+ {
+ \c_msg_coding_error_text_tl
+ LaTeX~has~been~asked~to~create~a~new~control~sequence~'#1'~
+ but~this~name~has~already~been~used~elsewhere. \\ \\
+ The~current~meaning~is:\\
+ \ \ #2
+ }
+\msg_kernel_new:nnnn { kernel } { command-not-defined }
+ { Control~sequence~#1~undefined. }
+ {
+ \c_msg_coding_error_text_tl
+ LaTeX~has~been~asked~to~use~a~command~#1,~but~this~has~not~
+ been~defined~yet.
+ }
+\msg_kernel_new:nnnn { kernel } { variable-not-defined }
+ { Variable~#1~undefined. }
+ {
+ \c_msg_coding_error_text_tl
+ LaTeX~has~been~asked~to~show~a~variable~#1,~but~this~has~not~
+ been~defined~yet.
+ }
+\msg_kernel_new:nnnn { seq } { empty-sequence }
+ { Empty~sequence~#1. }
+ {
+ \c_msg_coding_error_text_tl
+ LaTeX~has~been~asked~to~recover~an~entry~from~a~sequence~that~
+ has~no~content:~that~cannot~happen!
+ }
+% \end{macrocode}
+%
+% \begin{macro}{\msg_kernel_bug:x}
+% \begin{variable}{\c_msg_kernel_bug_text_tl, \c_msg_kernel_bug_more_text_tl}
+% The \LaTeX{} coding bug error gets re-visited here.
+% \begin{macrocode}
+\cs_set_protected:Npn \msg_kernel_bug:x #1
+ {
+ \msg_interrupt:xxx { \c_msg_kernel_bug_text_tl }
+ {
+ #1
+ \msg_see_documentation_text:n { LaTeX3 }
+ }
+ { \c_msg_kernel_bug_more_text_tl }
+ }
+\tl_const:Nn \c_msg_kernel_bug_text_tl
+ { This~is~a~LaTeX~bug:~check~coding! }
+\tl_const:Nn \c_msg_kernel_bug_more_text_tl
+ {
+ There~is~a~coding~bug~somewhere~around~here. \\
+ This~probably~needs~examining~by~an~expert.
+ \c_msg_return_text_tl
+ }
+% \end{macrocode}
+% \end{variable}
+% \end{macro}
+%
+% \subsection{Deprecated functions}
+%
+% Deprecated on 2011-05-27, for removal by 2011-08-31.
+%
+% \begin{macro}{\msg_class_new:nn}
+% This is only ever used in a |set| fashion.
+% \begin{macrocode}
+\cs_new_eq:NN \msg_class_new:nn \msg_class_set:nn
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \msg_trace:nnxxxx, \msg_trace:nnxxx, \msg_trace:nnxx,
+% \msg_trace:nnx, \msg_trace:nn
+% }
+% The performance here is never going to be good enough for tracing
+% code, so let's be realistic.
+% \begin{macrocode}
+\cs_new_eq:NN \msg_trace:nnxxxx \msg_log:nnxxxx
+\cs_new_eq:NN \msg_trace:nnxxx \msg_log:nnxxx
+\cs_new_eq:NN \msg_trace:nnxx \msg_log:nnxx
+\cs_new_eq:NN \msg_trace:nnx \msg_log:nnx
+\cs_new_eq:NN \msg_trace:nn \msg_log:nn
+% \end{macrocode}
+%\end{macro}
+%
+% \begin{macro}{\msg_generic_new:nnn}
+% \begin{macro}{\msg_generic_new:nn}
+% \begin{macro}{\msg_generic_set:nnn}
+% \begin{macro}{\msg_generic_set:nn}
+% \begin{macro}{\msg_direct_interrupt:xxxxx}
+% \begin{macro}{\msg_direct_log:xx}
+% \begin{macro}{\msg_direct_term:xx}
+% These were all too low-level.
+% \begin{macrocode}
+\cs_new_protected:Npn \msg_generic_new:nnn #1#2#3 { \deprecated }
+\cs_new_protected:Npn \msg_generic_new:nn #1#2 { \deprecated }
+\cs_new_protected:Npn \msg_generic_set:nnn #1#2#3 { \deprecated }
+\cs_new_protected:Npn \msg_generic_set:nn #1#2 { \deprecated }
+\cs_new_protected:Npn \msg_direct_interrupt:xxxxx #1#2#3#4#5 { \deprecated }
+\cs_new_protected:Npn \msg_direct_log:xx #1#2 { \deprecated }
+\cs_new_protected:Npn \msg_direct_term:xx #1#2 { \deprecated }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macrocode}
+%</initex|package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3names.dtx b/Master/texmf-dist/source/latex/l3kernel/l3names.dtx
new file mode 100644
index 00000000000..d8a33196962
--- /dev/null
+++ b/Master/texmf-dist/source/latex/l3kernel/l3names.dtx
@@ -0,0 +1,629 @@
+% \iffalse meta-comment
+%
+%% File: l3names.dtx Copyright (C) 1990-2011 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 "expl3 bundle" (The Work in LPPL)
+%% and all files in that bundle must be distributed together.
+%%
+%% The released version of this bundle is available from CTAN.
+%%
+%% -----------------------------------------------------------------------
+%%
+%% The development version of the bundle can be found at
+%%
+%% http://www.latex-project.org/svnroot/experimental/trunk/
+%%
+%% for those people who are interested.
+%%
+%%%%%%%%%%%
+%% NOTE: %%
+%%%%%%%%%%%
+%%
+%% Snapshots taken from the repository represent work in progress and may
+%% not work or may contain conflicting material! We therefore ask
+%% people _not_ to put them into distributions, archives, etc. without
+%% prior consultation with the LaTeX3 Project.
+%%
+%% -----------------------------------------------------------------------
+%
+%<*package>
+\RequirePackage{l3bootstrap}
+\GetIdInfo$Id: l3names.dtx 2478 2011-06-19 21:34:23Z joseph $
+ {L3 Experimental namespace for primitives}
+%</package>
+%<*driver>
+\documentclass[full]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3names} package\\ Namespace for primitives^^A
+% \thanks{This file describes v\ExplFileVersion,
+% last revised \ExplFileDate.}^^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 \ExplFileDate}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% \section{Setting up the \LaTeX3 programming language}
+%
+% This module is at the core of the \LaTeX3 programming language. It
+% performs the following tasks:
+% \begin{itemize}
+% \item defines new names for all \TeX{} primitives;
+% \item switches to the category code regime for programming;
+% \item provides support settings for building the code as a \TeX{} format.
+% \end{itemize}
+%
+% This module is entirely dedicated to primitives, which should not
+% be used directly within \LaTeX3 code (outside of \enquote{kernel-level}
+% code). As such, the primitives are not documented here:
+% \emph{The \TeX{}book}, \emph{\TeX{} by Topic} and the manuals for
+% \pdfTeX{}, \XeTeX{} and \LuaTeX{} should be consulted for details of
+% the primitives. These are named based on the engine which first introduced
+% them:
+% \begin{itemize}
+% \item[\cs{tex_\ldots}] Introduced by \TeX{} itself;
+% \item[\cs{etex_\ldots}] Introduced by the \eTeX{} extensions;
+% \item[\cs{pdftex_\ldots}] Introduced by \pdfTeX{};
+% \item[\cs{xetex_\ldots}] Introduced by \XeTeX{};
+% \item[\cs{luatex_\ldots}] Introduced by \LuaTeX{}.
+% \end{itemize}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3names} implementation}
+%
+% \begin{macrocode}
+%<*initex|package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*package>
+\ProvidesExplPackage
+ {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
+%</package>
+% \end{macrocode}
+%
+% The code here simply renames all of the primitives to new, internal,
+% names. In format mode, it also deletes all of the existing names (although
+% some od come back later).
+%
+% \begin{macro}{\tex_undefined:D}
+% This function does not exist at all, but is the name used by the
+% plain \TeX{} format for an undefined function. So it should
+% be marked here as \enquote{taken}.
+% \end{macro}
+%
+% The \cs{let} primitive is renamed by hand first as it is essential for
+% the entire process to follow. This also uses \cs{global}, as that way
+% we avoid leaving an unneeded csname in the hash table.
+% \begin{macrocode}
+\let \tex_global:D \global
+\let \tex_let:D \let
+% \end{macrocode}
+%
+% Everything is inside a (rather long) group, which kees \cs{name_primitve:NN}
+% trapped.
+% \begin{macrocode}
+\begingroup
+% \end{macrocode}
+%
+% \begin{macro}[aux]{\name_primitive:NN}
+% A temporary function to actually do the renaming. This also allows the
+% original names to be removed in format mode.
+% \begin{macrocode}
+ \long \def \name_primitive:NN #1#2
+ {
+ \tex_global:D \tex_let:D #2 #1
+%<*initex>
+ \tex_global:D \tex_let:D #1 \tex_undefined:D
+%</initex>
+ }
+% \end{macrocode}
+%\end{macro}
+%
+% In the current incarnation of this package, all \TeX{} primitives
+% are given a new name of the form |\tex_|\emph{oldname}|:D|.
+% But first three special cases which have symbolic original names.
+% These are given modified new names, so that they may be entered
+% without catcode tricks.
+% \begin{macrocode}
+ \name_primitive:NN \ \tex_space:D
+ \name_primitive:NN \/ \tex_italiccor:D
+ \name_primitive:NN \- \tex_hyphen:D
+% \end{macrocode}
+%
+% Now all the other primitives.
+% \begin{macrocode}
+ \name_primitive:NN \let \tex_let:D
+ \name_primitive:NN \def \tex_def:D
+ \name_primitive:NN \edef \tex_edef:D
+ \name_primitive:NN \gdef \tex_gdef:D
+ \name_primitive:NN \xdef \tex_xdef:D
+ \name_primitive:NN \chardef \tex_chardef:D
+ \name_primitive:NN \countdef \tex_countdef:D
+ \name_primitive:NN \dimendef \tex_dimendef:D
+ \name_primitive:NN \skipdef \tex_skipdef:D
+ \name_primitive:NN \muskipdef \tex_muskipdef:D
+ \name_primitive:NN \mathchardef \tex_mathchardef:D
+ \name_primitive:NN \toksdef \tex_toksdef:D
+ \name_primitive:NN \futurelet \tex_futurelet:D
+ \name_primitive:NN \advance \tex_advance:D
+ \name_primitive:NN \divide \tex_divide:D
+ \name_primitive:NN \multiply \tex_multiply:D
+ \name_primitive:NN \font \tex_font:D
+ \name_primitive:NN \fam \tex_fam:D
+ \name_primitive:NN \global \tex_global:D
+ \name_primitive:NN \long \tex_long:D
+ \name_primitive:NN \outer \tex_outer:D
+ \name_primitive:NN \setlanguage \tex_setlanguage:D
+ \name_primitive:NN \globaldefs \tex_globaldefs:D
+ \name_primitive:NN \afterassignment \tex_afterassignment:D
+ \name_primitive:NN \aftergroup \tex_aftergroup:D
+ \name_primitive:NN \expandafter \tex_expandafter:D
+ \name_primitive:NN \noexpand \tex_noexpand:D
+ \name_primitive:NN \begingroup \tex_begingroup:D
+ \name_primitive:NN \endgroup \tex_endgroup:D
+ \name_primitive:NN \halign \tex_halign:D
+ \name_primitive:NN \valign \tex_valign:D
+ \name_primitive:NN \cr \tex_cr:D
+ \name_primitive:NN \crcr \tex_crcr:D
+ \name_primitive:NN \noalign \tex_noalign:D
+ \name_primitive:NN \omit \tex_omit:D
+ \name_primitive:NN \span \tex_span:D
+ \name_primitive:NN \tabskip \tex_tabskip:D
+ \name_primitive:NN \everycr \tex_everycr:D
+ \name_primitive:NN \if \tex_if:D
+ \name_primitive:NN \ifcase \tex_ifcase:D
+ \name_primitive:NN \ifcat \tex_ifcat:D
+ \name_primitive:NN \ifnum \tex_ifnum:D
+ \name_primitive:NN \ifodd \tex_ifodd:D
+ \name_primitive:NN \ifdim \tex_ifdim:D
+ \name_primitive:NN \ifeof \tex_ifeof:D
+ \name_primitive:NN \ifhbox \tex_ifhbox:D
+ \name_primitive:NN \ifvbox \tex_ifvbox:D
+ \name_primitive:NN \ifvoid \tex_ifvoid:D
+ \name_primitive:NN \ifx \tex_ifx:D
+ \name_primitive:NN \iffalse \tex_iffalse:D
+ \name_primitive:NN \iftrue \tex_iftrue:D
+ \name_primitive:NN \ifhmode \tex_ifhmode:D
+ \name_primitive:NN \ifmmode \tex_ifmmode:D
+ \name_primitive:NN \ifvmode \tex_ifvmode:D
+ \name_primitive:NN \ifinner \tex_ifinner:D
+ \name_primitive:NN \else \tex_else:D
+ \name_primitive:NN \fi \tex_fi:D
+ \name_primitive:NN \or \tex_or:D
+ \name_primitive:NN \immediate \tex_immediate:D
+ \name_primitive:NN \closeout \tex_closeout:D
+ \name_primitive:NN \openin \tex_openin:D
+ \name_primitive:NN \openout \tex_openout:D
+ \name_primitive:NN \read \tex_read:D
+ \name_primitive:NN \write \tex_write:D
+ \name_primitive:NN \closein \tex_closein:D
+ \name_primitive:NN \newlinechar \tex_newlinechar:D
+ \name_primitive:NN \input \tex_input:D
+ \name_primitive:NN \endinput \tex_endinput:D
+ \name_primitive:NN \inputlineno \tex_inputlineno:D
+ \name_primitive:NN \errmessage \tex_errmessage:D
+ \name_primitive:NN \message \tex_message:D
+ \name_primitive:NN \show \tex_show:D
+ \name_primitive:NN \showthe \tex_showthe:D
+ \name_primitive:NN \showbox \tex_showbox:D
+ \name_primitive:NN \showlists \tex_showlists:D
+ \name_primitive:NN \errhelp \tex_errhelp:D
+ \name_primitive:NN \errorcontextlines \tex_errorcontextlines:D
+ \name_primitive:NN \tracingcommands \tex_tracingcommands:D
+ \name_primitive:NN \tracinglostchars \tex_tracinglostchars:D
+ \name_primitive:NN \tracingmacros \tex_tracingmacros:D
+ \name_primitive:NN \tracingonline \tex_tracingonline:D
+ \name_primitive:NN \tracingoutput \tex_tracingoutput:D
+ \name_primitive:NN \tracingpages \tex_tracingpages:D
+ \name_primitive:NN \tracingparagraphs \tex_tracingparagraphs:D
+ \name_primitive:NN \tracingrestores \tex_tracingrestores:D
+ \name_primitive:NN \tracingstats \tex_tracingstats:D
+ \name_primitive:NN \pausing \tex_pausing:D
+ \name_primitive:NN \showboxbreadth \tex_showboxbreadth:D
+ \name_primitive:NN \showboxdepth \tex_showboxdepth:D
+ \name_primitive:NN \batchmode \tex_batchmode:D
+ \name_primitive:NN \errorstopmode \tex_errorstopmode:D
+ \name_primitive:NN \nonstopmode \tex_nonstopmode:D
+ \name_primitive:NN \scrollmode \tex_scrollmode:D
+ \name_primitive:NN \end \tex_end:D
+ \name_primitive:NN \csname \tex_csname:D
+ \name_primitive:NN \endcsname \tex_endcsname:D
+ \name_primitive:NN \ignorespaces \tex_ignorespaces:D
+ \name_primitive:NN \relax \tex_relax:D
+ \name_primitive:NN \the \tex_the:D
+ \name_primitive:NN \mag \tex_mag:D
+ \name_primitive:NN \language \tex_language:D
+ \name_primitive:NN \mark \tex_mark:D
+ \name_primitive:NN \topmark \tex_topmark:D
+ \name_primitive:NN \firstmark \tex_firstmark:D
+ \name_primitive:NN \botmark \tex_botmark:D
+ \name_primitive:NN \splitfirstmark \tex_splitfirstmark:D
+ \name_primitive:NN \splitbotmark \tex_splitbotmark:D
+ \name_primitive:NN \fontname \tex_fontname:D
+ \name_primitive:NN \escapechar \tex_escapechar:D
+ \name_primitive:NN \endlinechar \tex_endlinechar:D
+ \name_primitive:NN \mathchoice \tex_mathchoice:D
+ \name_primitive:NN \delimiter \tex_delimiter:D
+ \name_primitive:NN \mathaccent \tex_mathaccent:D
+ \name_primitive:NN \mathchar \tex_mathchar:D
+ \name_primitive:NN \mskip \tex_mskip:D
+ \name_primitive:NN \radical \tex_radical:D
+ \name_primitive:NN \vcenter \tex_vcenter:D
+ \name_primitive:NN \mkern \tex_mkern:D
+ \name_primitive:NN \above \tex_above:D
+ \name_primitive:NN \abovewithdelims \tex_abovewithdelims:D
+ \name_primitive:NN \atop \tex_atop:D
+ \name_primitive:NN \atopwithdelims \tex_atopwithdelims:D
+ \name_primitive:NN \over \tex_over:D
+ \name_primitive:NN \overwithdelims \tex_overwithdelims:D
+ \name_primitive:NN \displaystyle \tex_displaystyle:D
+ \name_primitive:NN \textstyle \tex_textstyle:D
+ \name_primitive:NN \scriptstyle \tex_scriptstyle:D
+ \name_primitive:NN \scriptscriptstyle \tex_scriptscriptstyle:D
+ \name_primitive:NN \nonscript \tex_nonscript:D
+ \name_primitive:NN \eqno \tex_eqno:D
+ \name_primitive:NN \leqno \tex_leqno:D
+ \name_primitive:NN \abovedisplayshortskip \tex_abovedisplayshortskip:D
+ \name_primitive:NN \abovedisplayskip \tex_abovedisplayskip:D
+ \name_primitive:NN \belowdisplayshortskip \tex_belowdisplayshortskip:D
+ \name_primitive:NN \belowdisplayskip \tex_belowdisplayskip:D
+ \name_primitive:NN \displaywidowpenalty \tex_displaywidowpenalty:D
+ \name_primitive:NN \displayindent \tex_displayindent:D
+ \name_primitive:NN \displaywidth \tex_displaywidth:D
+ \name_primitive:NN \everydisplay \tex_everydisplay:D
+ \name_primitive:NN \predisplaysize \tex_predisplaysize:D
+ \name_primitive:NN \predisplaypenalty \tex_predisplaypenalty:D
+ \name_primitive:NN \postdisplaypenalty \tex_postdisplaypenalty:D
+ \name_primitive:NN \mathbin \tex_mathbin:D
+ \name_primitive:NN \mathclose \tex_mathclose:D
+ \name_primitive:NN \mathinner \tex_mathinner:D
+ \name_primitive:NN \mathop \tex_mathop:D
+ \name_primitive:NN \displaylimits \tex_displaylimits:D
+ \name_primitive:NN \limits \tex_limits:D
+ \name_primitive:NN \nolimits \tex_nolimits:D
+ \name_primitive:NN \mathopen \tex_mathopen:D
+ \name_primitive:NN \mathord \tex_mathord:D
+ \name_primitive:NN \mathpunct \tex_mathpunct:D
+ \name_primitive:NN \mathrel \tex_mathrel:D
+ \name_primitive:NN \overline \tex_overline:D
+ \name_primitive:NN \underline \tex_underline:D
+ \name_primitive:NN \left \tex_left:D
+ \name_primitive:NN \right \tex_right:D
+ \name_primitive:NN \binoppenalty \tex_binoppenalty:D
+ \name_primitive:NN \relpenalty \tex_relpenalty:D
+ \name_primitive:NN \delimitershortfall \tex_delimitershortfall:D
+ \name_primitive:NN \delimiterfactor \tex_delimiterfactor:D
+ \name_primitive:NN \nulldelimiterspace \tex_nulldelimiterspace:D
+ \name_primitive:NN \everymath \tex_everymath:D
+ \name_primitive:NN \mathsurround \tex_mathsurround:D
+ \name_primitive:NN \medmuskip \tex_medmuskip:D
+ \name_primitive:NN \thinmuskip \tex_thinmuskip:D
+ \name_primitive:NN \thickmuskip \tex_thickmuskip:D
+ \name_primitive:NN \scriptspace \tex_scriptspace:D
+ \name_primitive:NN \noboundary \tex_noboundary:D
+ \name_primitive:NN \accent \tex_accent:D
+ \name_primitive:NN \char \tex_char:D
+ \name_primitive:NN \discretionary \tex_discretionary:D
+ \name_primitive:NN \hfil \tex_hfil:D
+ \name_primitive:NN \hfilneg \tex_hfilneg:D
+ \name_primitive:NN \hfill \tex_hfill:D
+ \name_primitive:NN \hskip \tex_hskip:D
+ \name_primitive:NN \hss \tex_hss:D
+ \name_primitive:NN \vfil \tex_vfil:D
+ \name_primitive:NN \vfilneg \tex_vfilneg:D
+ \name_primitive:NN \vfill \tex_vfill:D
+ \name_primitive:NN \vskip \tex_vskip:D
+ \name_primitive:NN \vss \tex_vss:D
+ \name_primitive:NN \unskip \tex_unskip:D
+ \name_primitive:NN \kern \tex_kern:D
+ \name_primitive:NN \unkern \tex_unkern:D
+ \name_primitive:NN \hrule \tex_hrule:D
+ \name_primitive:NN \vrule \tex_vrule:D
+ \name_primitive:NN \leaders \tex_leaders:D
+ \name_primitive:NN \cleaders \tex_cleaders:D
+ \name_primitive:NN \xleaders \tex_xleaders:D
+ \name_primitive:NN \lastkern \tex_lastkern:D
+ \name_primitive:NN \lastskip \tex_lastskip:D
+ \name_primitive:NN \indent \tex_indent:D
+ \name_primitive:NN \par \tex_par:D
+ \name_primitive:NN \noindent \tex_noindent:D
+ \name_primitive:NN \vadjust \tex_vadjust:D
+ \name_primitive:NN \baselineskip \tex_baselineskip:D
+ \name_primitive:NN \lineskip \tex_lineskip:D
+ \name_primitive:NN \lineskiplimit \tex_lineskiplimit:D
+ \name_primitive:NN \clubpenalty \tex_clubpenalty:D
+ \name_primitive:NN \widowpenalty \tex_widowpenalty:D
+ \name_primitive:NN \exhyphenpenalty \tex_exhyphenpenalty:D
+ \name_primitive:NN \hyphenpenalty \tex_hyphenpenalty:D
+ \name_primitive:NN \linepenalty \tex_linepenalty:D
+ \name_primitive:NN \doublehyphendemerits \tex_doublehyphendemerits:D
+ \name_primitive:NN \finalhyphendemerits \tex_finalhyphendemerits:D
+ \name_primitive:NN \adjdemerits \tex_adjdemerits:D
+ \name_primitive:NN \hangafter \tex_hangafter:D
+ \name_primitive:NN \hangindent \tex_hangindent:D
+ \name_primitive:NN \parshape \tex_parshape:D
+ \name_primitive:NN \hsize \tex_hsize:D
+ \name_primitive:NN \lefthyphenmin \tex_lefthyphenmin:D
+ \name_primitive:NN \righthyphenmin \tex_righthyphenmin:D
+ \name_primitive:NN \leftskip \tex_leftskip:D
+ \name_primitive:NN \rightskip \tex_rightskip:D
+ \name_primitive:NN \looseness \tex_looseness:D
+ \name_primitive:NN \parskip \tex_parskip:D
+ \name_primitive:NN \parindent \tex_parindent:D
+ \name_primitive:NN \uchyph \tex_uchyph:D
+ \name_primitive:NN \emergencystretch \tex_emergencystretch:D
+ \name_primitive:NN \pretolerance \tex_pretolerance:D
+ \name_primitive:NN \tolerance \tex_tolerance:D
+ \name_primitive:NN \spaceskip \tex_spaceskip:D
+ \name_primitive:NN \xspaceskip \tex_xspaceskip:D
+ \name_primitive:NN \parfillskip \tex_parfillskip:D
+ \name_primitive:NN \everypar \tex_everypar:D
+ \name_primitive:NN \prevgraf \tex_prevgraf:D
+ \name_primitive:NN \spacefactor \tex_spacefactor:D
+ \name_primitive:NN \shipout \tex_shipout:D
+ \name_primitive:NN \vsize \tex_vsize:D
+ \name_primitive:NN \interlinepenalty \tex_interlinepenalty:D
+ \name_primitive:NN \brokenpenalty \tex_brokenpenalty:D
+ \name_primitive:NN \topskip \tex_topskip:D
+ \name_primitive:NN \maxdeadcycles \tex_maxdeadcycles:D
+ \name_primitive:NN \maxdepth \tex_maxdepth:D
+ \name_primitive:NN \output \tex_output:D
+ \name_primitive:NN \deadcycles \tex_deadcycles:D
+ \name_primitive:NN \pagedepth \tex_pagedepth:D
+ \name_primitive:NN \pagestretch \tex_pagestretch:D
+ \name_primitive:NN \pagefilstretch \tex_pagefilstretch:D
+ \name_primitive:NN \pagefillstretch \tex_pagefillstretch:D
+ \name_primitive:NN \pagefilllstretch \tex_pagefilllstretch:D
+ \name_primitive:NN \pageshrink \tex_pageshrink:D
+ \name_primitive:NN \pagegoal \tex_pagegoal:D
+ \name_primitive:NN \pagetotal \tex_pagetotal:D
+ \name_primitive:NN \outputpenalty \tex_outputpenalty:D
+ \name_primitive:NN \hoffset \tex_hoffset:D
+ \name_primitive:NN \voffset \tex_voffset:D
+ \name_primitive:NN \insert \tex_insert:D
+ \name_primitive:NN \holdinginserts \tex_holdinginserts:D
+ \name_primitive:NN \floatingpenalty \tex_floatingpenalty:D
+ \name_primitive:NN \insertpenalties \tex_insertpenalties:D
+ \name_primitive:NN \lower \tex_lower:D
+ \name_primitive:NN \moveleft \tex_moveleft:D
+ \name_primitive:NN \moveright \tex_moveright:D
+ \name_primitive:NN \raise \tex_raise:D
+ \name_primitive:NN \copy \tex_copy:D
+ \name_primitive:NN \lastbox \tex_lastbox:D
+ \name_primitive:NN \vsplit \tex_vsplit:D
+ \name_primitive:NN \unhbox \tex_unhbox:D
+ \name_primitive:NN \unhcopy \tex_unhcopy:D
+ \name_primitive:NN \unvbox \tex_unvbox:D
+ \name_primitive:NN \unvcopy \tex_unvcopy:D
+ \name_primitive:NN \setbox \tex_setbox:D
+ \name_primitive:NN \hbox \tex_hbox:D
+ \name_primitive:NN \vbox \tex_vbox:D
+ \name_primitive:NN \vtop \tex_vtop:D
+ \name_primitive:NN \prevdepth \tex_prevdepth:D
+ \name_primitive:NN \badness \tex_badness:D
+ \name_primitive:NN \hbadness \tex_hbadness:D
+ \name_primitive:NN \vbadness \tex_vbadness:D
+ \name_primitive:NN \hfuzz \tex_hfuzz:D
+ \name_primitive:NN \vfuzz \tex_vfuzz:D
+ \name_primitive:NN \overfullrule \tex_overfullrule:D
+ \name_primitive:NN \boxmaxdepth \tex_boxmaxdepth:D
+ \name_primitive:NN \splitmaxdepth \tex_splitmaxdepth:D
+ \name_primitive:NN \splittopskip \tex_splittopskip:D
+ \name_primitive:NN \everyhbox \tex_everyhbox:D
+ \name_primitive:NN \everyvbox \tex_everyvbox:D
+ \name_primitive:NN \nullfont \tex_nullfont:D
+ \name_primitive:NN \textfont \tex_textfont:D
+ \name_primitive:NN \scriptfont \tex_scriptfont:D
+ \name_primitive:NN \scriptscriptfont \tex_scriptscriptfont:D
+ \name_primitive:NN \fontdimen \tex_fontdimen:D
+ \name_primitive:NN \hyphenchar \tex_hyphenchar:D
+ \name_primitive:NN \skewchar \tex_skewchar:D
+ \name_primitive:NN \defaulthyphenchar \tex_defaulthyphenchar:D
+ \name_primitive:NN \defaultskewchar \tex_defaultskewchar:D
+ \name_primitive:NN \number \tex_number:D
+ \name_primitive:NN \romannumeral \tex_romannumeral:D
+ \name_primitive:NN \string \tex_string:D
+ \name_primitive:NN \lowercase \tex_lowercase:D
+ \name_primitive:NN \uppercase \tex_uppercase:D
+ \name_primitive:NN \meaning \tex_meaning:D
+ \name_primitive:NN \penalty \tex_penalty:D
+ \name_primitive:NN \unpenalty \tex_unpenalty:D
+ \name_primitive:NN \lastpenalty \tex_lastpenalty:D
+ \name_primitive:NN \special \tex_special:D
+ \name_primitive:NN \dump \tex_dump:D
+ \name_primitive:NN \patterns \tex_patterns:D
+ \name_primitive:NN \hyphenation \tex_hyphenation:D
+ \name_primitive:NN \time \tex_time:D
+ \name_primitive:NN \day \tex_day:D
+ \name_primitive:NN \month \tex_month:D
+ \name_primitive:NN \year \tex_year:D
+ \name_primitive:NN \jobname \tex_jobname:D
+ \name_primitive:NN \everyjob \tex_everyjob:D
+ \name_primitive:NN \count \tex_count:D
+ \name_primitive:NN \dimen \tex_dimen:D
+ \name_primitive:NN \skip \tex_skip:D
+ \name_primitive:NN \toks \tex_toks:D
+ \name_primitive:NN \muskip \tex_muskip:D
+ \name_primitive:NN \box \tex_box:D
+ \name_primitive:NN \wd \tex_wd:D
+ \name_primitive:NN \ht \tex_ht:D
+ \name_primitive:NN \dp \tex_dp:D
+ \name_primitive:NN \catcode \tex_catcode:D
+ \name_primitive:NN \delcode \tex_delcode:D
+ \name_primitive:NN \sfcode \tex_sfcode:D
+ \name_primitive:NN \lccode \tex_lccode:D
+ \name_primitive:NN \uccode \tex_uccode:D
+ \name_primitive:NN \mathcode \tex_mathcode:D
+% \end{macrocode}
+% Since \LaTeX3 requires at least the \eTeX{} extensions,
+% we also rename the additional primitives. These are all
+% given the prefix |\etex_|.
+% \begin{macrocode}
+ \name_primitive:NN \ifdefined \etex_ifdefined:D
+ \name_primitive:NN \ifcsname \etex_ifcsname:D
+ \name_primitive:NN \unless \etex_unless:D
+ \name_primitive:NN \eTeXversion \etex_eTeXversion:D
+ \name_primitive:NN \eTeXrevision \etex_eTeXrevision:D
+ \name_primitive:NN \marks \etex_marks:D
+ \name_primitive:NN \topmarks \etex_topmarks:D
+ \name_primitive:NN \firstmarks \etex_firstmarks:D
+ \name_primitive:NN \botmarks \etex_botmarks:D
+ \name_primitive:NN \splitfirstmarks \etex_splitfirstmarks:D
+ \name_primitive:NN \splitbotmarks \etex_splitbotmarks:D
+ \name_primitive:NN \unexpanded \etex_unexpanded:D
+ \name_primitive:NN \detokenize \etex_detokenize:D
+ \name_primitive:NN \scantokens \etex_scantokens:D
+ \name_primitive:NN \showtokens \etex_showtokens:D
+ \name_primitive:NN \readline \etex_readline:D
+ \name_primitive:NN \tracingassigns \etex_tracingassigns:D
+ \name_primitive:NN \tracingscantokens \etex_tracingscantokens:D
+ \name_primitive:NN \tracingnesting \etex_tracingnesting:D
+ \name_primitive:NN \tracingifs \etex_tracingifs:D
+ \name_primitive:NN \currentiflevel \etex_currentiflevel:D
+ \name_primitive:NN \currentifbranch \etex_currentifbranch:D
+ \name_primitive:NN \currentiftype \etex_currentiftype:D
+ \name_primitive:NN \tracinggroups \etex_tracinggroups:D
+ \name_primitive:NN \currentgrouplevel \etex_currentgrouplevel:D
+ \name_primitive:NN \currentgrouptype \etex_currentgrouptype:D
+ \name_primitive:NN \showgroups \etex_showgroups:D
+ \name_primitive:NN \showifs \etex_showifs:D
+ \name_primitive:NN \interactionmode \etex_interactionmode:D
+ \name_primitive:NN \lastnodetype \etex_lastnodetype:D
+ \name_primitive:NN \iffontchar \etex_iffontchar:D
+ \name_primitive:NN \fontcharht \etex_fontcharht:D
+ \name_primitive:NN \fontchardp \etex_fontchardp:D
+ \name_primitive:NN \fontcharwd \etex_fontcharwd:D
+ \name_primitive:NN \fontcharic \etex_fontcharic:D
+ \name_primitive:NN \parshapeindent \etex_parshapeindent:D
+ \name_primitive:NN \parshapelength \etex_parshapelength:D
+ \name_primitive:NN \parshapedimen \etex_parshapedimen:D
+ \name_primitive:NN \numexpr \etex_numexpr:D
+ \name_primitive:NN \dimexpr \etex_dimexpr:D
+ \name_primitive:NN \glueexpr \etex_glueexpr:D
+ \name_primitive:NN \muexpr \etex_muexpr:D
+ \name_primitive:NN \gluestretch \etex_gluestretch:D
+ \name_primitive:NN \glueshrink \etex_glueshrink:D
+ \name_primitive:NN \gluestretchorder \etex_gluestretchorder:D
+ \name_primitive:NN \glueshrinkorder \etex_glueshrinkorder:D
+ \name_primitive:NN \gluetomu \etex_gluetomu:D
+ \name_primitive:NN \mutoglue \etex_mutoglue:D
+ \name_primitive:NN \lastlinefit \etex_lastlinefit:D
+ \name_primitive:NN \interlinepenalties \etex_interlinepenalties:D
+ \name_primitive:NN \clubpenalties \etex_clubpenalties:D
+ \name_primitive:NN \widowpenalties \etex_widowpenalties:D
+ \name_primitive:NN \displaywidowpenalties \etex_displaywidowpenalties:D
+ \name_primitive:NN \middle \etex_middle:D
+ \name_primitive:NN \savinghyphcodes \etex_savinghyphcodes:D
+ \name_primitive:NN \savingvdiscards \etex_savingvdiscards:D
+ \name_primitive:NN \pagediscards \etex_pagediscards:D
+ \name_primitive:NN \splitdiscards \etex_splitdiscards:D
+ \name_primitive:NN \TeXXETstate \etex_TeXXETstate:D
+ \name_primitive:NN \beginL \etex_beginL:D
+ \name_primitive:NN \endL \etex_endL:D
+ \name_primitive:NN \beginR \etex_beginR:D
+ \name_primitive:NN \endR \etex_endR:D
+ \name_primitive:NN \predisplaydirection \etex_predisplaydirection:D
+ \name_primitive:NN \everyeof \etex_everyeof:D
+ \name_primitive:NN \protected \etex_protected:D
+% \end{macrocode}
+% The newer primitives are more complex: there are an awful lot of them,
+% and we don't use them all at the moment. So the following is selective.
+% In the case of the \pdfTeX{} primitives, we retain |pdf| at the start
+% of the names \emph{only} for directly PDF-related primitives, as
+% there are a lot of \pdfTeX{} primitives that start \cs{pdf\ldots} but
+% are not related to PDF output. These ones re
+% \begin{macrocode}
+ \name_primitive:NN \pdfcreationdate \pdftex_pdfcreationdate:D
+ \name_primitive:NN \pdfcolorstack \pdftex_pdfcolorstack:D
+ \name_primitive:NN \pdfcompresslevel \pdftex_pdfcompresslevel:D
+ \name_primitive:NN \pdfdecimaldigits \pdftex_pdfdecimaldigits:D
+ \name_primitive:NN \pdfhorigin \pdftex_pdfhorigin:D
+ \name_primitive:NN \pdfinfo \pdftex_pdfinfo:D
+ \name_primitive:NN \pdfliteral \pdftex_pdfliteral:D
+ \name_primitive:NN \pdfminorversion \pdftex_pdfminorversion:D
+ \name_primitive:NN \pdfobjcompresslevel \pdftex_pdfobjcompresslevel:D
+ \name_primitive:NN \pdfoutput \pdftex_pdfoutput:D
+ \name_primitive:NN \pdfrestore \pdftex_pdfrestore:D
+ \name_primitive:NN \pdfsave \pdftex_pdfsave:D
+ \name_primitive:NN \pdfsetmatrix \pdftex_pdfsetmatrix:D
+ \name_primitive:NN \pdfpkresolution \pdftex_pdfpkresolution:D
+ \name_primitive:NN \pdftexrevision \pdftex_pdftextrevision:D
+ \name_primitive:NN \pdfvorigin \pdftex_pdfvorigin:D
+% \end{macrocode}
+% While these are not.
+% \begin{macrocode}
+ \name_primitive:NN \pdfstrcmp \pdftex_strcmp:D
+% \end{macrocode}
+% \XeTeX{}-specific primitives.
+% \begin{macrocode}
+ \name_primitive:NN \XeTeXversion \xetex_XeTeXversion:D
+% \end{macrocode}
+% Primitives from \LuaTeX.
+% \begin{macrocode}
+ \name_primitive:NN \catcodetable \luatex_catcodetable:D
+ \name_primitive:NN \directlua \luatex_directlua:D
+ \name_primitive:NN \initcatcodetable \luatex_initcatcodetable:D
+ \name_primitive:NN \latelua \luatex_latelua:D
+ \name_primitive:NN \luatexversion \luatex_luatexversion:D
+ \name_primitive:NN \savecatcodetable \luatex_savecatcodetable:D
+% \end{macrocode}
+% The job is done: close the group (using the primitive renamed!).
+% \begin{macrocode}
+\tex_endgroup:D
+% \end{macrocode}
+%
+% \LaTeXe{} will have moved a few primitives, so these are sorted out.
+% \begin{macrocode}
+%<*package>
+\tex_let:D \tex_end:D \@@end
+\tex_let:D \tex_everydisplay:D \frozen@everydisplay
+\tex_let:D \tex_everymath:D \frozen@everymath
+\tex_let:D \tex_hyphen:D \@@hyph
+\tex_let:D \tex_input:D \@@input
+\tex_let:D \tex_italic_correction:D \@@italiccorr
+\tex_let:D \tex_underline:D \@@underline
+% \end{macrocode}
+% That is also true for the \pkg{luatex} package for \LaTeXe{}.
+% \begin{macrocode}
+\tex_let:D \luatex_catcodetable:D \luatexcatcodetable
+\tex_let:D \luatex_initcatcodetable:D \luatexinitcatcodetable
+\tex_let:D \luatex_latelua:D \luatexlatelua
+\tex_let:D \luatex_savecatcodetable:D \luatexsavecatcodetable
+%</package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</initex|package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex \ No newline at end of file
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx b/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx
new file mode 100644
index 00000000000..b4cf9368f2a
--- /dev/null
+++ b/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx
@@ -0,0 +1,2046 @@
+% \iffalse meta-comment
+%
+%% File: l3prg.dtx Copyright (C) 2005-2011 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 "expl3 bundle" (The Work in LPPL)
+%% and all files in that bundle must be distributed together.
+%%
+%% The released version of this bundle is available from CTAN.
+%%
+%% -----------------------------------------------------------------------
+%%
+%% The development version of the bundle can be found at
+%%
+%% http://www.latex-project.org/svnroot/experimental/trunk/
+%%
+%% for those people who are interested.
+%%
+%%%%%%%%%%%
+%% NOTE: %%
+%%%%%%%%%%%
+%%
+%% Snapshots taken from the repository represent work in progress and may
+%% not work or may contain conflicting material! We therefore ask
+%% people _not_ to put them into distributions, archives, etc. without
+%% prior consultation with the LaTeX3 Project.
+%%
+%% -----------------------------------------------------------------------
+%
+%<*driver|package>
+\RequirePackage{l3names}
+\GetIdInfo$Id: l3prg.dtx 2495 2011-07-06 16:57:08Z bruno $
+ {L3 Experimental control structures}
+%</driver|package>
+%<*driver>
+\documentclass[full]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3prg} package\\ Control structures^^A
+% \thanks{This file describes v\ExplFileVersion,
+% last revised \ExplFileDate.}^^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 \ExplFileDate}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% Conditional processing in \LaTeX3 is defined as something that
+% performs a series of tests, possibly involving assignments and
+% calling other functions that do not read further ahead in the input
+% stream. After processing the input, a \emph{state} is returned. The
+% typical states returned are \meta{true} and \meta{false} but other
+% states are possible, say an \meta{error} state for erroneous
+% input, \emph{e.g.}, text as input in a function comparing integers.
+%
+% \LaTeX3 has two primary forms of conditional flow processing based
+% on these states. One type is predicate functions that turn the
+% returned state into a boolean \meta{true} or \meta{false}. For
+% example, the function |\cs_if_free_p:N| checks whether the control
+% sequence given as its argument is free and then returns the boolean
+% \meta{true} or \meta{false} values to be used in testing with
+% |\if_predicate:w| or in functions to be described below. The other type
+% is the kind of functions choosing a particular argument from the
+% input stream based on the result of the testing as in
+% |\cs_if_free:NTF| which also takes one argument (the |N|) and then
+% executes either \meta{true} or \meta{false} depending on the
+% result. Important to note here is that the arguments are executed
+% after exiting the underlying |\if...\fi:| structure
+%
+% \section{Defining a set of conditional functions}
+%
+% \begin{function}
+% {
+% \prg_new_conditional:Npnn, \prg_set_conditional:Npnn,
+% \prg_new_conditional:Nnn, \prg_set_conditional:Nnn
+% }
+% \begin{syntax}
+% \cs{prg_set_conditional:Npnn} \cs{\meta{name}:\meta{arg spec}}
+% ~~\meta{parameters} \Arg{conditions} \Arg{code}
+% \cs{prg_set_conditional:Nnn} \cs{\meta{name}:\meta{arg spec}}
+% ~~\Arg{conditions} \Arg{code}
+% \end{syntax}
+% These functions creates a family of conditionals using the same
+% \Arg{code} to perform the test created. The \texttt{new} version will
+% check for existing definitions (\emph{cf.}~\cs{cs_new:Npn}) whereas
+% the \texttt{set} version will not (\emph{cf.}~\cs{cs_set:Npn}). The
+% conditionals created are depended on the comma-separated list of
+% \meta{conditions}, which should be one or more of \texttt{p},
+% \texttt{T}, \texttt{F} and \texttt{TF}. The conditionals are then
+% defined in the obvious way as:
+% \begin{itemize}
+% \item \cs{\meta{name}_p:\meta{arg spec}}, a predicate function
+% which will supply either a logical \texttt{true} or
+% logical \texttt{false}. This function is intended for use
+% in cases where one or more logical tests are combined to
+% lead to a final outcome.
+% \item \cs{\meta{name}:\meta{arg spec}T}, a function with one
+% more argument than the original \meta{arg spec} demands. The
+% \meta{true branch} code in this additional argument will be
+% left on the input stream only if the test is \texttt{true}.
+% \item \cs{\meta{name}:\meta{arg spec}F}, a function with one
+% more argument than the original \meta{arg spec} demands. The
+% \meta{false branch} code in this additional argument will be
+% left on the input stream only if the test is \texttt{false}.
+% \item \cs{\meta{name}:\meta{arg spec}TF} , a function with two
+% more argument than the original \meta{arg spec} demands. The
+% \meta{true branch} code in the first additional argument will
+% be left on the input stream if the test is \texttt{true}, while
+% the \meta{false branch} code in the second argument will be
+% left on the input stream if the test is \texttt{false}.
+% \end{itemize}
+% The \meta{code} of the test may use \meta{parameters} as specified
+% by the second argument to \cs{prg_set_conditional:Npnn}: this should
+% match the \meta{argument specification} but this is not enforced.
+% The |Nnn| versions infer the number of arguments from the argument
+% specification given (\emph{cf.}~\cs{cs_new:Nn}, \emph{etc.}).
+% Within the \meta{code}, the functions \cs{prg_return_true:} and
+% \cs{prg_return_false:} are used to indicate the logical outcomes of
+% the test. If \meta{code} is expandable then
+% \cs{prg_set_conditional:Npnn} will generate a family of conditionals
+% which are also expandable. All of the functions are created globally.
+%
+% An example can easily clarify matters here:
+% \begin{verbatim}
+% \prg_set_conditional:Nnn \foo_if_bar:NN { p , T , TF }
+% {
+% \if_meaning:w \l_tmpa_tl #1
+% \prg_return_true:
+% \else:
+% \if_meaning:w \l_tmpa_tl #2
+% \prg_return_true:
+% \else:
+% \prg_return_false:
+% \fi:
+% \fi:
+% }
+% \end{verbatim}
+% This defines the function |\foo_if_bar_p:NN|, |\foo_if_bar:NNTF|,
+% |\foo_if_bar:NNT| but not |\foo_if_bar:NNF| (because |F| is missing from
+% the \meta{conds} list). The return statements
+% take care of resolving the remaining |\else:| and |\fi:| before
+% returning the state. There must be a return statement for each
+% branch, failing to do so will result in an error if that branch is
+% executed.
+% \end{function}
+%
+% \begin{function}
+% {
+% \prg_new_protected_conditional:Npnn, \prg_set_protected_conditional:Npnn,
+% \prg_new_protected_conditional:Nnn, \prg_set_protected_conditional:Nnn
+% }
+% \begin{syntax}
+% \cs{prg_set_protected_conditional:Npnn}
+% ~~\cs{\meta{name}:\meta{arg spec}} \meta{parameters}
+% ~~\meta{conditions} \Arg{code}
+% \cs{prg_set_protected_conditional:Nnn}
+% ~~\cs{\meta{name}:\meta{arg spec}} \meta{conditions} \Arg{code}
+% \end{syntax}
+% These functions creates a family of conditionals using the same
+% \Arg{code} to perform the test created. The \texttt{new} version will
+% check for existing definitions (\emph{cf.}~\cs{cs_new:Npn}) whereas
+% the \texttt{set} version will not (\emph{cf.}~\cs{cs_set:Npn}). The
+% conditionals created are depended on the comma-separated list of
+% \meta{conditions}, which should be one or more of \texttt{T},
+% \texttt{F} and \texttt{TF}. The conditionals are then defined in the
+% obvious way as:
+% \begin{itemize}
+% \item \cs{\meta{name}:\meta{arg spec}T}, a function with one
+% more argument than the original \meta{arg spec} demands. The
+% \meta{true branch} code in this additional argument will be
+% left on the input stream only if the test is \texttt{true}.
+% \item \cs{\meta{name}:\meta{arg spec}F}, a function with one
+% more argument than the original \meta{arg spec} demands. The
+% \meta{false branch} code in this additional argument will be
+% left on the input stream only if the test is \texttt{false}.
+% \item \cs{\meta{name}:\meta{arg spec}TF} , a function with two
+% more argument than the original \meta{arg spec} demands. The
+% \meta{true branch} code in the first additional argument will
+% be left on the input stream if the test is \texttt{true}, while
+% the \meta{false branch} code in the second argument will be
+% left on the input stream if the test is \texttt{false}.
+% \end{itemize}
+% The \meta{code} of the test may use \meta{parameters} as specified
+% by the second argument to \cs{prg_set_conditional:Npn}: this should
+% match the \meta{argument specification} but this is not enforced.
+% The |Nnn| versions infer the number of arguments from the argument
+% specification given (\emph{cf.}~\cs{cs_new:Nn}, \emph{etc.}).
+% Within the \meta{code}, the functions \cs{prg_return_true:} and
+% \cs{prg_return_false:} are used to indicate the logical outcomes of
+% the test. \cs{prg_set_protected_conditional:Npn} will generate
+% a family of protected conditional functions, and so \meta{code}
+% does not need to be expandable. All of the functions are created
+% globally.
+%\end{function}
+%
+% \begin{function}{\prg_new_eq_conditional:NN, \prg_set_eq_conditional:NN}
+% \begin{syntax}
+% \cs{prg_new_eq_conditional:NN}
+% ~~\cs{\meta{name1}:\meta{arg spec1}} \cs{\meta{name2}:\meta{arg spec2}}
+% \end{syntax}
+% These will set the definitions of the functions
+% \begin{itemize}
+% \item \cs{\meta{name1}_p:\meta{arg spec1}}
+% \item \cs{\meta{name1}:\meta{arg spec1}T}
+% \item \cs{\meta{name1}:\meta{arg spec1}F}
+% \item \cs{\meta{name1}:\meta{arg spec1}TF}
+% \end{itemize}
+% equal to those for
+% \begin{itemize}
+% \item \cs{\meta{name2}_p:\meta{arg spec2}}
+% \item \cs{\meta{name2}:\meta{arg spec2}T}
+% \item \cs{\meta{name2}:\meta{arg spec2}F}
+% \item \cs{\meta{name2}:\meta{arg spec2}TF}
+% \end{itemize}
+% In most cases, the two \meta{arg specs} will be identical, although
+% this is not enforced. In the case of the \texttt{new} function, a
+% check is made for any existing definitions for \meta{name1}. The
+% functions are set globally.
+% \end{function}
+%
+% \begin{function}[EXP]{\prg_return_true:, \prg_return_false:}
+% \begin{syntax}
+% \cs{prg_return_true:}
+% \cs{prg_return_false:}
+% \end{syntax}
+% These functions define the logical state at the end of a conditional.
+% As such, they should appear within the code for a conditional
+% statement generated by \cs{prg_set_conditional:Npnn}, \emph{etc}.
+% \end{function}
+%
+% \section{The boolean data type}
+%
+% This section describes a boolean data type which is closely
+% connected to conditional processing as sometimes you want to
+% execute some code depending on the value of a switch
+% (\emph{e.g.},~draft/final) and other times you perhaps want to use it as a
+% predicate function in an |\if_predicate:w| test. The problem of the
+% primitive |\if_false:| and |\if_true:| tokens is that it is not
+% always safe to pass them around as they may interfere with scanning
+% for termination of primitive conditional processing. Therefore, we
+% employ two canonical booleans: |\c_true_bool| or
+% |\c_false_bool|. Besides preventing problems as described above, it
+% also allows us to implement a simple boolean parser supporting the
+% logical operations And, Or, Not, \emph{etc.}\ which can then be used on
+% both the boolean type and predicate functions.
+%
+% All conditional |\bool_| functions are expandable and expect the
+% input to also be fully expandable (which will generally mean being
+% constructed from predicate functions, possibly nested).
+%
+% \begin{function}{\bool_new:N, \bool_new:c}
+% \begin{syntax}
+% \cs{bool_new:N} \meta{boolean}
+% \end{syntax}
+% Creates a new \meta{boolean} or raises an error if the
+% name is already taken. The declaration is global. The
+% \meta{boolean} will initially be \texttt{false}.
+% \end{function}
+%
+% \begin{function}{\bool_set_false:N, \bool_set_false:c}
+% \begin{syntax}
+% \cs{bool_set_false:N} \meta{boolean}
+% \end{syntax}
+% Sets \meta{boolean} logically \texttt{false} within the current
+% \TeX{} group.
+% \end{function}
+%
+% \begin{function}{\bool_gset_false:N, \bool_gset_false:c}
+% \begin{syntax}
+% \cs{bool_sget_false:N} \meta{boolean}
+% \end{syntax}
+% Sets \meta{boolean} logically \texttt{false} globally.
+% \end{function}
+%
+% \begin{function}{\bool_set_true:N, \bool_set_true:c}
+% \begin{syntax}
+% \cs{bool_set_true:N} \meta{boolean}
+% \end{syntax}
+% Sets \meta{boolean} logically \texttt{true} within the current
+% \TeX{} group.
+% \end{function}
+%
+% \begin{function}{\bool_gset_true:N, \bool_gset_true:c}
+% \begin{syntax}
+% \cs{bool_gset_true:N} \meta{boolean}
+% \end{syntax}
+% Sets \meta{boolean} logically \texttt{true} globally.
+% \end{function}
+%
+% \begin{function}
+% {\bool_set_eq:NN, \bool_set_eq:cN, \bool_set_eq:Nc, \bool_set_eq:cc}
+% \begin{syntax}
+% \cs{bool_set_eq:NN} \meta{boolean1} \meta{boolean2}
+% \end{syntax}
+% Sets the content of \meta{boolean1} equal to that of \meta{boolean2}.
+% This assignment is restricted to the current \TeX{} group level.
+% \end{function}
+%
+% \begin{function}
+% {\bool_gset_eq:NN, \bool_gset_eq:cN, \bool_gset_eq:Nc, \bool_gset_eq:cc}
+% \begin{syntax}
+% \cs{bool_gset_eq:NN} \meta{boolean1} \meta{boolean2}
+% \end{syntax}
+% Sets the content of \meta{boolean1} equal to that of \meta{boolean2}.
+% This assignment is global and so is not limited by the current
+% \TeX{} group level.
+% \end{function}
+%
+% \begin{function}{\bool_set:Nn, \bool_set:cn}
+% \begin{syntax}
+% \cs{bool_set:Nn} \meta{boolean} \Arg{boolexpr}
+% \end{syntax}
+% Evaluates the \meta{boolean expression} as described for
+% \cs{bool_if:n(TF)}, and sets the \meta{boolean} variable to
+% the logical truth of this evaluation. This assignment is local.
+% \end{function}
+%
+% \begin{function}{\bool_gset:Nn, \bool_gset:cn}
+% \begin{syntax}
+% \cs{bool_gset:Nn} \meta{boolean} \Arg{boolexpr}
+% \end{syntax}
+% Evaluates the \meta{boolean expression} as described for
+% \cs{bool_if:n(TF)}, and sets the \meta{boolean} variable to
+% the logical truth of this evaluation. This assignment is global.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\bool_if:N, \bool_if:c}
+% \begin{syntax}
+% \cs{bool_if_p:N} \Arg{boolean}
+% \cs{bool_if:NTF} \Arg{boolean} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests the current truth of \meta{boolean}, and continues expansion
+% based on this result. The branching versions then leave either
+% \meta{true code} or \meta{false code} in the input stream, as
+% appropriate to the truth of the test and the variant of the function
+% chosen. The logical truth of the test is left in the input stream by
+% the predicate version.
+% \end{function}
+%
+% \begin{variable}{\l_tmpa_bool}
+% A scratch boolean for local assignment. It is never used by
+% the kernel code, and so is safe for use with any \LaTeX3-defined
+% function. However, it may be overwritten by other non-kernel
+% code and so should only be used for short-term storage.
+% \end{variable}
+%
+% \begin{variable}{\g_tmpa_bool}
+% A scratch boolean for global assignment. It is never used by
+% the kernel code, and so is safe for use with any \LaTeX3-defined
+% function. However, it may be overwritten by other non-kernel
+% code and so should only be used for short-term storage.
+% \end{variable}
+%
+% \section{Boolean expressions}
+%
+% As we have a boolean datatype and predicate functions returning
+% boolean \meta{true} or \meta{false} values, it seems only fitting
+% that we also provide a parser for \meta{boolean expressions}.
+%
+% A boolean expression is an expression which given input in the form
+% of predicate functions and boolean variables, return boolean
+% \meta{true} or \meta{false}. It supports the logical operations And,
+% Or and Not as the well-known infix operators |&&|, \verb"||" and |!|. In
+% addition to this, parentheses can be used to isolate
+% sub-expressions. For example,
+% \begin{verbatim}
+% \int_compare_p:n { 1 = 1 } &&
+% (
+% \int_compare_p:n { 2 = 3 } ||
+% \int_compare_p:n { 4 = 4 } ||
+% \int_compare_p:n { 1 = \error } % is skipped
+% ) &&
+% ! ( \int_compare_p:n { 2 = 4 } )
+% \end{verbatim}
+% is a valid boolean expression. Note that minimal evaluation is
+% carried out whenever possible so that whenever a truth value cannot
+% be changed any more, the remaining tests within the current group
+% are skipped.
+%
+% \begin{function}[EXP,pTF]{\bool_if:n}
+% \begin{syntax}
+% \cs{bool_if_p:n} \Arg{boolean expression}
+% \cs{bool_if:nTF} \Arg{boolean expression} \Arg{true code}
+% ~~\Arg{false code}
+% \end{syntax}
+% Tests the current truth of \meta{boolean expression}, and
+% continues expansion based on this result. The
+% \meta{boolean expression} should consist of a series of predicates
+% or boolean variables with the logical relationship between these
+% defined using |&&| (\enquote{And}), \verb"||" (\enquote{Or}),
+% |!| (\enquote{Not}) and parentheses. Minimal evaluation is used
+% in the processing, so that once a result is defined there is
+% not further expansion of the tests. For example
+% \begin{verbatim}
+% \bool_if_p:n
+% {
+% \int_compare_p:nNn { 1 } = { 1 }
+% &&
+% (
+% \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 } = { 4 } )
+% }
+% \end{verbatim}
+% will be \texttt{true} and will not evaluate
+% |\int_compare_p:nNn { 1 } = { \error }|. The logical Not applies to
+% the next single predicate or group. As shown above, this means that
+% any predicates requiring an argument have to be given within
+% parentheses. The branching versions then leave either
+% \meta{true code} or \meta{false code} in the input stream, as
+% appropriate to the truth of the test and the variant of the function
+% chosen. The logical truth of the test is left in the input stream by
+% the predicate version.
+% \end{function}
+%
+% \begin{function}[EXP]{\bool_not_p:n}
+% \begin{syntax}
+% \cs{bool_not_p:n} \Arg{boolean expression}
+% \end{syntax}
+% Function version of |!(|\meta{boolean expression}|)| within a boolean
+% expression.
+% \end{function}
+%
+% \begin{function}[EXP]{\bool_xor_p:nn}
+% \begin{syntax}
+% \cs{bool_xor_p:nn} \Arg{boolexpr1} \Arg{boolexpr1}
+% \end{syntax}
+% Implements an \enquote{exclusive or} operation between two boolean
+% expressions. There is no infix operation for this logical
+% operator.
+% \end{function}
+%
+% \section{Logical loops}
+%
+% Loops using either boolean expressions or stored boolean values.
+%
+% \begin{function}[EXP]{\bool_until_do:Nn, \bool_until_do:cn}
+% \begin{syntax}
+% \cs{bool_until_do:Nn} \Arg{boolean} \Arg{code}
+% \end{syntax}
+% This function firsts checks the logical value of the \meta{boolean}.
+% If it is \texttt{false} the \meta{code} is placed in the input stream
+% and expanded. After the completion of the \meta{code} the truth
+% of the \meta{boolean} is re-evaluated. The process will then loop
+% until the \meta{boolean} is \texttt{true}.
+% \end{function}
+%
+% \begin{function}[EXP]{\bool_while_do:Nn, \bool_while_do:cn}
+% \begin{syntax}
+% \cs{bool_while_do:Nn} \Arg{boolean} \Arg{code}
+% \end{syntax}
+% This function firsts checks the logical value of the \meta{boolean}.
+% If it is \texttt{true} the \meta{code} is placed in the input stream
+% and expanded. After the completion of the \meta{code} the truth
+% of the \meta{boolean} is re-evaluated. The process will then loop
+% until the \meta{boolean} is \texttt{false}.
+% \end{function}
+%
+% \begin{function}[EXP]{\bool_until_do:nn}
+% \begin{syntax}
+% \cs{bool_until_do:nn} \Arg{boolean expression} \Arg{code}
+% \end{syntax}
+% This function firsts checks the logical value of the
+% \meta{boolean expression} (as described for \cs{bool_if:nTF}).
+% If it is \texttt{false} the \meta{code} is placed in the input stream
+% and expanded. After the completion of the \meta{code} the truth
+% of the \meta{boolean expression} is re-evaluated. The process will
+% then loop until the \meta{boolean expression} is \texttt{true}.
+% \end{function}
+%
+% \begin{function}[EXP]{\bool_while_do:nn}
+% \begin{syntax}
+% \cs{bool_while_do:nn} \Arg{boolean expression} \Arg{code}
+% \end{syntax}
+% This function firsts checks the logical value of the
+% \meta{boolean expression} (as described for \cs{bool_if:nTF}).
+% If it is \texttt{true} the \meta{code} is placed in the input stream
+% and expanded. After the completion of the \meta{code} the truth
+% of the \meta{boolean expression} is re-evaluated. The process will
+% then loop until the \meta{boolean expression} is \texttt{false}.
+% \end{function}
+%
+% \section{Switching by case}
+%
+% For cases where a number of cases need to be considered a family of
+% case-selecting functions are available.
+%
+% \begin{function}[EXP]{\prg_case_int:nnn}
+% \begin{syntax}
+% \cs{prg_case_int:nnn}
+% ~~\Arg{test integer expression}
+% ~~|{|
+% ~~~~\Arg{intexpr case1} \Arg{code case1}
+% ~~~~\Arg{intexpr case2} \Arg{code case2}
+% ~~~~\ldots
+% ~~~~\Arg{intexpr case$_n$} \Arg{code case$_n$}
+% ~~|}|
+% ~~\Arg{else case}
+% \end{syntax}
+% This function evaluates the \meta{test integer expression} and
+% compares this in turn to each of the
+% \meta{integer expression cases}. If the two are equal then the
+% associated \meta{code} is left in the input stream. If none of
+% the tests are \texttt{true} then the \texttt{else code} will be
+% left in the input stream. For example
+% \begin{verbatim}
+% \prg_case_int:nnn
+% { 2 * 5 }
+% {
+% { 5 } { Small }
+% { 4 + 6 } { Medium }
+% { -2 * 10 } { Negative }
+% }
+% { No idea! }
+% \end{verbatim}
+% will leave \enquote{\texttt{Medium}} in the input stream.
+% \end{function}
+%
+% \begin{function}[EXP]{\prg_case_dim:nnn}
+% \begin{syntax}
+% \cs{prg_case_dim:nnn}
+% ~~\Arg{test dimension expression}
+% ~~|{|
+% ~~~~\Arg{dimexpr case1} \Arg{code case1}
+% ~~~~\Arg{dimexpr case2} \Arg{code case2}
+% ~~~~\ldots
+% ~~~~\Arg{dimexpr case$_n$} \Arg{code case$_n$}
+% ~~|}|
+% ~~\Arg{else case}
+% \end{syntax}
+% This function evaluates the \meta{test dimension expression} and
+% compares this in turn to each of the
+% \meta{dimension expression cases}. If the two are equal then the
+% associated \meta{code} is left in the input stream. If none of
+% the tests are \texttt{true} then the \texttt{else code} will be
+% left in the input stream.
+% \end{function}
+%
+% \begin{function}[EXP]
+% {\prg_case_str:nnn, \prg_case_str:onn, \prg_case_str:xxn}
+% \begin{syntax}
+% \cs{prg_case_str:nnn}
+% ~~\Arg{test string}
+% ~~|{|
+% ~~~~\Arg{string case1} \Arg{code case1}
+% ~~~~\Arg{string case2} \Arg{code case2}
+% ~~~~\ldots
+% ~~~~\Arg{string case$_n$} \Arg{code case$_n$}
+% ~~|}|
+% ~~\Arg{else case}
+% \end{syntax}
+% This function compares the \meta{test string} in turn with each
+% of the \meta{string cases}. If the two are equal (as described for
+% \cs{str_if_eq:nnTF} then the
+% associated \meta{code} is left in the input stream. If none of
+% the tests are \texttt{true} then the \texttt{else code} will be
+% left in the input stream. The |xx| variant is fully expandable,
+% in the same way as the underlying \cs{str_if_eq:xxTF} test.
+% \end{function}
+%
+% \begin{function}[EXP]{\prg_case_tl:Nnn, \prg_case_tl:cnn}
+% \begin{syntax}
+% \cs{prg_case_tl:Nnn}
+% ~~\meta{test token list variable}
+% ~~"{"
+% ~~~~\meta{token list variable case1} \Arg{code case1}
+% ~~~~\meta{token list variable case2} \Arg{code case2}
+% ~~~~\ldots
+% ~~~~\meta{token list variable case$_n$} \Arg{code case$_n$}
+% ~~"}"
+% ~~\Arg{else case}
+% \end{syntax}
+% This function compares the \meta{test token list variable} in turn
+% with each of the \meta{token list variable cases}. If the two
+% are equal (as described for
+% \cs{tl_if_eq:nnTF}
+% then the associated \meta{code} is left in the input
+% stream. If none of the tests are \texttt{true} then the
+% \texttt{else code} will be left in the input stream.
+% \end{function}
+%
+% \section{Producing $n$ copies}
+%
+% \begin{function}[EXP]{\prg_replicate:nn}
+% \begin{syntax}
+% \cs{prg_replicate:nn} \Arg{integer expression} \Arg{tokens}
+% \end{syntax}
+% Evaluates the \meta{integer expression} (which should be
+% zero or positive) and creates the resulting number of copies
+% of the \meta{tokens}. The function is both expandable and safe for
+% nesting. It yields its result after two expansion steps.
+% \end{function}
+%
+% \begin{function}[EXP]{\prg_stepwise_function:nnnN}
+% \begin{syntax}
+% \cs{prg_stepwise_function:nnnN} \Arg{initial value} \Arg{step}
+% ~~\Arg{final value} \meta{function}
+% \end{syntax}
+% This function first evaluates the \meta{initial value}, \meta{step}
+% and \meta{final value}, all of which should be integer expressions.
+% The \meta{function} is then placed in front of each \meta{value}
+% from the \meta{initial value} to the \meta{final value} in turn
+% (using \meta{step} between each \meta{value}). Thus \meta{function}
+% should absorb one numerical argument. For example
+% \begin{verbatim}
+% \cs_set_nopar:Npn \my_func:n #1 { I~saw~#1 \\ }
+% \prg_stepwise_function:nnnN { 1 } { 5 } { 1 } \my_func:n
+% \end{verbatim}
+% would print
+% \begin{quote}
+% I saw 1 \\
+% I saw 2 \\
+% I saw 3 \\
+% I saw 4 \\
+% I saw 5 \\
+% \end{quote}
+% \end{function}
+%
+% \begin{function}{\prg_stepwise_inline:nnnn}
+% \begin{syntax}
+% \cs{prg_stepwise_inline:nnnn} \Arg{initial value} \Arg{step}
+% ~~\Arg{final value} \Arg{code}
+% \end{syntax}
+% This function first evaluates the \meta{initial value}, \meta{step}
+% and \meta{final value}, all of which should be integer expressions.
+% The \meta{code} is then placed in front of each \meta{value}
+% from the \meta{initial value} to the \meta{final value} in turn
+% (using \meta{step} between each \meta{value}). Thus the \meta{code}
+% should define a function of one argument (|#1|).
+% \end{function}
+%
+% \begin{function}{\prg_stepwise_variable:nnnn}
+% \begin{syntax}
+% \cs{prg_stepwise_inline:nnnn} \Arg{initial value} \Arg{step}
+% ~~\Arg{final value} \meta{tl~var} \Arg{code}
+% \end{syntax}
+% This function first evaluates the \meta{initial value}, \meta{step}
+% and \meta{final value}, all of which should be integer expressions.
+% The \meta{code} is inserted into the input stream, with the
+% \meta{tl~var} defined as the current \meta{value}. Thus the
+% \meta{code} should make use of the \meta{tl~var}.
+% \end{function}
+%
+% \section{Detecting \TeX{}'s mode}
+%
+% \begin{function}[EXP,pTF]{\mode_if_horizontal:}
+% \begin{syntax}
+% \cs{mode_if_horizontal_p:}
+% \cs{mode_if_horizontal:TF} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Detects if \TeX{} is currently in horizontal mode. The branching
+% versions then leave either \meta{true code} or \meta{false code}
+% in the input stream, as appropriate to the truth of the test and
+% the variant of the function chosen. The logical truth of the test
+% is left in the input stream by the predicate version.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\mode_if_inner:}
+% \begin{syntax}
+% \cs{mode_if_inner_p:}
+% \cs{mode_if_inner:TF} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Detects if \TeX{} is currently in inner mode. The branching
+% versions then leave either \meta{true code} or \meta{false code}
+% in the input stream, as appropriate to the truth of the test and
+% the variant of the function chosen. The logical truth of the test
+% is left in the input stream by the predicate version.
+% \end{function}
+%
+% \begin{function}[EXP,TF]{\mode_if_math:}
+% \begin{syntax}
+% \cs{mode_if_math:TF} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Detects if \TeX{} is currently in maths mode. The branching
+% versions then leave either \meta{true code} or \meta{false code}
+% in the input stream, as appropriate to the truth of the test and
+% the variant of the function chosen.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\mode_if_vertical:}
+% \begin{syntax}
+% \cs{mode_if_vertical_p:}
+% \cs{mode_if_vertical:TF} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Detects if \TeX{} is currently in vertical mode. The branching
+% versions then leave either \meta{true code} or \meta{false code}
+% in the input stream, as appropriate to the truth of the test and
+% the variant of the function chosen. The logical truth of the test
+% is left in the input stream by the predicate version.
+% \end{function}
+%
+% \section{Internal programming functions}
+%
+% \begin{function}[EXP]{\group_align_safe_begin:, \group_align_safe_end:}
+% \begin{syntax}
+% \cs{group_align_safe_begin:}
+% \ldots
+% \cs{group_align_safe_end:}
+% \end{syntax}
+% These functions are used to enclose material in a \TeX{} alignment
+% environment within a specially-constructed group. This group is
+% designed in such a way that it does not add brace groups to the
+% output but does act as a group for the |&| token inside
+% \cs{tex_halign:D}. This is necessary to allow grabbing of tokens
+% for testing purposes, as \TeX{} uses group level to determine the
+% effect of alignment tokens. Without the special grouping, the use of
+% a function such as \cs{peek_after:Nw} will result in a forbidden
+% comparison of the internal \cs{endtemplate} token, yielding a
+% fatal error. Each \cs{group_align_safe_begin:} must be matched by a
+% \cs{group_align_safe_end:}, although this does not have to occur
+% within the same function.
+% \end{function}
+%
+% \begin{function}{\scan_align_safe_stop:}
+% \begin{syntax}
+% \cs{scan_align_safe_stop:}
+% \end{syntax}
+% This function gets \TeX{} on the right track inside an alignment
+% cell but without destroying any kerning.
+% \end{function}
+%
+% \begin{function}[EXP]{\prg_variable_get_scope:N}
+% \begin{syntax}
+% \cs{prg_variable_get_scope:N} \meta{variable}
+% \end{syntax}
+% Returns the scope (\texttt{g} for global, blank otherwise) for the
+% \meta{variable}.
+% \end{function}
+%
+% \begin{function}[EXP]{\prg_variable_get_type:N}
+% \begin{syntax}
+% \cs{prg_variable_get_type:N} \meta{variable}
+% \end{syntax}
+% Returns the type of \meta{variable} (\texttt{tl}, \texttt{int},
+% \emph{etc.})
+% \end{function}
+%
+% \section{Experimental programmings functions}
+%
+% \begin{function}{\prg_quicksort:n}
+% \begin{syntax}
+% \cs{prg_quicksort:n} |{| \Arg{item~1} \Arg{item~2} \dots \Arg{item~n} |}|
+% \end{syntax}
+% Performs a quicksort on the token list. The comparisons are
+% performed by the function \cs{prg_quicksort_compare:nnTF} which is up
+% to the programmer to define. When the sorting process is over, all
+% items are given as argument to the function
+% \cs{prg_quicksort_function:n} which the programmer also controls.
+% \end{function}
+%
+% \begin{function}{
+% \prg_quicksort_function:n |
+% \prg_quicksort_compare:nnTF
+% }
+% \begin{syntax}
+% "\prg_quicksort_function:n" \Arg{element} \\
+% "\prg_quicksort_compare:nnTF" \Arg{element 1} \Arg{element 2}\\
+% \end{syntax}
+% The two functions the programmer must define before calling
+% |\prg_quicksort:n|. As an example we could define
+% \begin{quote}
+% |\cs_set_nopar:Npn\prg_quicksort_function:n #1{{#1}}|\\
+% |\cs_set_nopar:Npn\prg_quicksort_compare:nnTF #1#2#3#4 {\int_compare:nNnTF{#1}>{#2}}|
+% \end{quote}
+% Then the function call
+% \begin{quote}
+% |\prg_quicksort:n {876234520}|
+% \end{quote}
+% would return |{0}{2}{2}{3}{4}{5}{6}{7}{8}|. An alternative example
+% where one sorts a list of words, |\prg_quicksort_compare:nnTF| could
+% be defined as
+% \begin{quote}
+% |\cs_set_nopar:Npn\prg_quicksort_compare:nnTF #1#2 {|\\
+% | \int_compare:nNnTF{\tl_compare:nn{#1}{#2}}>\c_zero }|
+% \end{quote}
+%
+% \end{function}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3prg} implementation}
+%
+% \TestFiles{m3prg001.lvt,m3prg002.lvt,m3prg003.lvt}
+%%
+% \begin{macrocode}
+%<*initex|package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*package>
+\ProvidesExplPackage
+ {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
+\package_check_loaded_expl:
+%</package>
+% \end{macrocode}
+%
+% \subsection{Defining a set of conditional functions}
+%
+% \begin{macro}
+% {
+% \prg_set_conditional:Npnn,
+% \prg_new_conditional:Npnn,
+% \prg_set_protected_conditional:Npnn,
+% \prg_new_protected_conditional:Npnn
+% }
+% \begin{macro}
+% {
+% \prg_set_conditional:Nnn,
+% \prg_new_conditional:Nnn,
+% \prg_set_protected_conditional:Nnn,
+% \prg_new_protected_conditional:Nnn
+% }
+% \begin{macro}{\prg_set_eq_conditional:NNn, \prg_new_eq_conditional:NNn}
+% \begin{macro}{\prg_return_true:}
+% \TestMissing
+% {This function is implicitly tested with all other conditionals!}
+% \begin{macro}{\prg_return_false:}
+% \TestMissing
+% {This function is also implicitly tested with all other conditionals!}
+% These are all defined in \pkg{l3basics}, as they are needed
+% \enquote{early}. This is just a reminder that that is the case!
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{The boolean data type}
+%
+% \begin{macro}{\bool_new:N, \bool_new:c}
+% \UnitTested
+% Boolean variables have to be initiated when they are created. Other
+% than that there is not much to say here.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \bool_new:N #1 { \cs_new_eq:NN #1 \c_false_bool }
+\cs_generate_variant:Nn \bool_new:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \bool_set_true:N, \bool_set_true:c,
+% \bool_gset_true:N, \bool_gset_true:c,
+% \bool_set_false:N, \bool_set_false:c,
+% \bool_gset_false:N, \bool_gset_false:c
+% }
+% \UnitTested
+% Setting is already pretty easy.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \bool_set_true:N #1
+ { \cs_set_eq:NN #1 \c_true_bool }
+\cs_new_protected_nopar:Npn \bool_set_false:N #1
+ { \cs_set_eq:NN #1 \c_false_bool }
+\cs_new_protected_nopar:Npn \bool_gset_true:N #1
+ { \cs_gset_eq:NN #1 \c_true_bool }
+\cs_new_protected_nopar:Npn \bool_gset_false:N #1
+ { \cs_gset_eq:NN #1 \c_false_bool }
+\cs_generate_variant:Nn \bool_set_true:N { c }
+\cs_generate_variant:Nn \bool_set_false:N { c }
+\cs_generate_variant:Nn \bool_gset_true:N { c }
+\cs_generate_variant:Nn \bool_gset_false:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \bool_set_eq:NN, \bool_set_eq:cN,
+% \bool_set_eq:Nc, \bool_set_eq:cc,
+% \bool_gset_eq:NN, \bool_gset_eq:cN,
+% \bool_gset_eq:Nc, \bool_gset_eq:cc
+% }
+% \UnitTested
+% The usual copy code.
+% \begin{macrocode}
+\cs_new_eq:NN \bool_set_eq:NN \cs_set_eq:NN
+\cs_new_eq:NN \bool_set_eq:Nc \cs_set_eq:Nc
+\cs_new_eq:NN \bool_set_eq:cN \cs_set_eq:cN
+\cs_new_eq:NN \bool_set_eq:cc \cs_set_eq:cc
+\cs_new_eq:NN \bool_gset_eq:NN \cs_gset_eq:NN
+\cs_new_eq:NN \bool_gset_eq:Nc \cs_gset_eq:Nc
+\cs_new_eq:NN \bool_gset_eq:cN \cs_gset_eq:cN
+\cs_new_eq:NN \bool_gset_eq:cc \cs_gset_eq:cc
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\bool_set:Nn,\bool_set:cn}
+% \begin{macro}{\bool_gset:Nn,\bool_gset:cn}
+% This function evaluates a boolean expression and assigns the first
+% argument the meaning |\c_true_bool| or |\c_false_bool|.
+% \begin{macrocode}
+\cs_new:Npn \bool_set:Nn #1#2
+ { \tex_chardef:D #1 = \bool_if_p:n {#2} }
+\cs_new:Npn \bool_gset:Nn #1#2
+ { \tex_global:D \tex_chardef:D #1 = \bool_if_p:n {#2} }
+\cs_generate_variant:Nn \bool_set:Nn { c }
+\cs_generate_variant:Nn \bool_gset:Nn { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\bool_if:N, \bool_if:c}
+% \UnitTested
+% Straight forward here. We could optimize here if we wanted to as
+% the boolean can just be input directly.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \bool_if:N #1 { p , T , F , TF }
+ {
+ \if_bool:N #1
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\cs_generate_variant:Nn \bool_if_p:N { c }
+\cs_generate_variant:Nn \bool_if:NT { c }
+\cs_generate_variant:Nn \bool_if:NF { c }
+\cs_generate_variant:Nn \bool_if:NTF { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{variable}{\l_tmpa_bool, \g_tmpa_bool}
+% A few booleans just if you need them.
+% \begin{macrocode}
+\bool_new:N \l_tmpa_bool
+\bool_new:N \g_tmpa_bool
+% \end{macrocode}
+% \end{variable}
+%
+% \subsection{Boolean expressions}
+%
+% \begin{macro}[pTF]{\bool_if:n}
+% \UnitTested
+% \begin{macro}[aux]{\bool_get_next:N}
+% \begin{macro}[aux]{\bool_cleanup:N}
+% \begin{macro}[aux]{\bool_choose:NN}
+% \begin{macro}[aux]
+% {
+% bool_!:w,
+% \bool_Not:w,
+% \bool_Not:w,
+% \bool_(:w,
+% \bool_p:w,
+% \bool_8_1:w,
+% \bool_I_1:w,
+% \bool_8_0:w,
+% \bool_I_0:w,
+% \bool_)_0:w,
+% \bool_)_1:w,
+% \bool_S_0:w,
+% \bool_S_1:w
+% }
+% \begin{macro}[aux]
+% {
+% \bool_eval_skip_to_end:Nw, \bool_eval_skip_to_end_aux:Nw,
+% \bool_eval_skip_to_end_aux_ii:Nw
+% }
+% Evaluating the truth value of a list of predicates is done using
+% an input syntax somewhat similar to the one found in other
+% programming languages with |(| and |)| for grouping, |!| for
+% logical \enquote{Not}, |&&| for logical \enquote{And} and \verb"||"
+% for logical \enquote{Or}. We shall use the terms Not, And, Or, Open and
+% Close for these operations.
+%
+% Any expression is terminated by a Close operation. Evaluation
+% happens from left to right in the following manner using a GetNext
+% function:
+% \begin{itemize}
+% \item If an Open is seen, start evaluating a new expression using
+% the Eval function and call GetNext again.
+% \item If a Not is seen, insert a negating function (if-even in
+% this case) and call GetNext.
+% \item If none of the above, start evaluating a new expression by
+% reinserting the token found (this is supposed to be a predicate
+% function) in front of Eval.
+% \end{itemize}
+% The Eval function then contains a post-processing operation which
+% grabs the instruction following the predicate. This is either And,
+% Or or Close. In each case the truth value is used to determine
+% where to go next. The following situations can arise:
+% \begin{description}
+% \item[\meta{true}And] Current truth value is true, logical And
+% seen, continue with GetNext to examine truth value of next
+% boolean (sub-)expression.
+% \item[\meta{false}And] Current truth value is false, logical And
+% seen, stop evaluating the predicates within this sub-expression
+% and break to the nearest Close. Then return \meta{false}.
+% \item[\meta{true}Or] Current truth value is true, logical Or
+% seen, stop evaluating the predicates within this sub-expression
+% and break to the nearest Close. Then return \meta{true}.
+% \item[\meta{false}Or] Current truth value is false, logical Or
+% seen, continue with GetNext to examine truth value of next
+% boolean (sub-)expression.
+% \item[\meta{true}Close] Current truth value is true, Close
+% seen, return \meta{true}.
+% \item[\meta{false}Close] Current truth value is false, Close
+% seen, return \meta{false}.
+% \end{description}
+% We introduce an additional Stop operation with the following
+% semantics:
+% \begin{description}
+% \item[\meta{true}Stop] Current truth value is true, return
+% \meta{true}.
+% \item[\meta{false}Stop] Current truth value is false, return
+% \meta{false}.
+% \end{description}
+% The reasons for this follow below.
+%
+% Now for how these works in practice. The canonical true and false
+% values have numerical values $1$ and $0$ respectively. We evaluate
+% this using the primitive |\int_value:w:D| operation. First we
+% issue a |\group_align_safe_begin:| as we are using |&&| as syntax
+% shorthand for the And operation and we need to hide it for \TeX{}.
+% We also need to finish this special group before finally
+% returning a |\c_true_bool| or |\c_false_bool| as there might
+% otherwise be something left in front in the input stream. For
+% this we call the Stop operation, denoted simply by a |S|
+% following the last Close operation.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \bool_if:n #1 { T , F , TF }
+ {
+ \if_predicate:w \bool_if_p:n {#1}
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\cs_new:Npn \bool_if_p:n #1
+ {
+ \group_align_safe_begin:
+ \bool_get_next:N ( #1 ) S
+ }
+% \end{macrocode}
+% The GetNext operation. We make it a switch: If not a |!| or |(|, we
+% assume it is a predicate.
+% \begin{macrocode}
+\cs_new:Npn \bool_get_next:N #1
+ {
+ \use:c
+ {
+ bool_
+ \if_meaning:w !#1 ! \else: \if_meaning:w (#1 ( \else: p \fi: \fi:
+ :w
+ }
+ #1
+ }
+% \end{macrocode}
+% This variant gets called when a Not has just been entered.
+% It (eventually) results in a reversal of the logic of the directly
+% following material.
+% \begin{macrocode}
+\cs_new:Npn \bool_get_not_next:N #1
+ {
+ \use:c
+ {
+ bool_not_
+ \if_meaning:w !#1 ! \else: \if_meaning:w (#1 ( \else: p \fi: \fi:
+ :w
+ }
+ #1
+ }
+% \end{macrocode}
+% We need these later on to nullify the unity operation |!!|.
+% \begin{macrocode}
+\cs_new:Npn \bool_get_next:NN #1#2 { \bool_get_next:N #2 }
+\cs_new:Npn \bool_get_not_next:NN #1#2 { \bool_get_not_next:N #2 }
+% \end{macrocode}
+% The Not operation. Discard the token read and reverse the truth
+% value of the next expression if there
+% are brackets; otherwise
+% if we're coming up to a |!| then we don't need to reverse anything
+% (but we then want to continue scanning ahead in case some fool has written
+% |!!(...)|);
+% otherwise we have a boolean that we can reverse here and now.
+% \begin{macrocode}
+\cs_new:cpn { bool_!:w } #1#2
+ {
+ \if_meaning:w ( #2
+ \exp_after:wN \bool_Not:w
+ \else:
+ \if_meaning:w ! #2
+ \exp_after:wN \exp_after:wN \exp_after:wN \bool_get_next:NN
+ \else:
+ \exp_after:wN \exp_after:wN \exp_after:wN \bool_Not:N
+ \fi:
+ \fi:
+ #2
+ }
+% \end{macrocode}
+% Variant called when already inside a Not.
+% Essentially the opposite of the above.
+% \begin{macrocode}
+\cs_new:cpn { bool_not_!:w } #1#2
+ {
+ \if_meaning:w ( #2
+ \exp_after:wN \bool_not_Not:w
+ \else:
+ \if_meaning:w ! #2
+ \exp_after:wN \exp_after:wN \exp_after:wN \bool_get_not_next:NN
+ \else:
+ \exp_after:wN \exp_after:wN \exp_after:wN \bool_not_Not:N
+ \fi:
+ \fi:
+ #2
+ }
+% \end{macrocode}
+% These occur when processing |!(...)|. The idea is to use a variant
+% of |\bool_get_next:N| that finishes its parsing with a logic reversal.
+% Of course, the double logic reversal gets us back to where we started.
+% \begin{macrocode}
+\cs_new:Npn \bool_Not:w { \exp_after:wN \int_value:w \bool_get_not_next:N }
+\cs_new:Npn \bool_not_Not:w { \exp_after:wN \int_value:w \bool_get_next:N }
+% \end{macrocode}
+% These occur when processing |!<bool>| and can be evaluated directly.
+% \begin{macrocode}
+\cs_new:Npn \bool_Not:N #1
+ {
+ \exp_after:wN \bool_p:w
+ \if_meaning:w #1 \c_true_bool
+ \c_false_bool
+ \else:
+ \c_true_bool
+ \fi:
+ }
+\cs_new:Npn \bool_not_Not:N #1
+ {
+ \exp_after:wN \bool_p:w
+ \if_meaning:w #1 \c_true_bool
+ \c_true_bool
+ \else:
+ \c_false_bool
+ \fi:
+ }
+% \end{macrocode}
+% The Open operation. Discard the token read and start a
+% sub-expression.
+% |\bool_get_next:N| continues building up the logical expressions as usual;
+% |\bool_not_cleanup:N| is what reverses the logic if we're inside |!(...)|.
+% \begin{macrocode}
+\cs_new:cpn { bool_(:w } #1
+ { \exp_after:wN \bool_cleanup:N \int_value:w \bool_get_next:N }
+\cs_new:cpn { bool_not_(:w } #1
+ { \exp_after:wN \bool_not_cleanup:N \int_value:w \bool_get_next:N }
+% \end{macrocode}
+% Otherwise just evaluate the predicate and look for And, Or or Close
+% afterwards.
+% \begin{macrocode}
+\cs_new:cpn { bool_p:w } { \exp_after:wN \bool_cleanup:N \int_value:w }
+\cs_new:cpn { bool_not_p:w } {\exp_after:wN \bool_not_cleanup:N \int_value:w }
+% \end{macrocode}
+% This cleanup function can be omitted once predicates return their
+% true/false booleans outside the conditionals.
+% \begin{macrocode}
+\cs_new:Npn \bool_cleanup:N #1
+ {
+ \exp_after:wN \bool_choose:NN \exp_after:wN #1
+ \int_to_roman:w - `\q
+ }
+\cs_new:Npn \bool_not_cleanup:N #1
+ {
+ \exp_after:wN \bool_not_choose:NN \exp_after:wN #1
+ \int_to_roman:w - `\q
+ }
+% \end{macrocode}
+% Branching the six way switch.
+% Reversals should be reasonably straightforward.
+% \begin{macrocode}
+\cs_new_nopar:Npn \bool_choose:NN #1#2 { \use:c { bool_ #2 _ #1 :w } }
+\cs_new_nopar:Npn \bool_not_choose:NN #1#2 { \use:c { bool_not_ #2 _ #1 :w } }
+% \end{macrocode}
+% Continues scanning. Must remove the second "&" or \verb"|".
+% \begin{macrocode}
+\cs_new_nopar:cpn { bool_&_1:w } & { \bool_get_next:N }
+\cs_new_nopar:cpn { bool_|_0:w } | { \bool_get_next:N }
+\cs_new_nopar:cpn { bool_not_&_0:w } & { \bool_get_next:N }
+\cs_new_nopar:cpn { bool_not_|_1:w } | { \bool_get_next:N }
+% \end{macrocode}
+% Closing a group is just about returning the result. The Stop
+% operation is similar except it closes the special alignment group
+% before returning the boolean.
+% \begin{macrocode}
+\cs_new_nopar:cpn { bool_)_0:w } { \c_false_bool }
+\cs_new_nopar:cpn { bool_)_1:w } { \c_true_bool }
+\cs_new_nopar:cpn { bool_not_)_0:w } { \c_true_bool }
+\cs_new_nopar:cpn { bool_not_)_1:w } { \c_false_bool }
+\cs_new_nopar:cpn { bool_S_0:w } { \group_align_safe_end: \c_false_bool }
+\cs_new_nopar:cpn { bool_S_1:w } { \group_align_safe_end: \c_true_bool }
+% \end{macrocode}
+% When the truth value has already been decided, we have to throw away
+% the remainder of the current group as we are doing minimal
+% evaluation. This is slightly tricky as there are no braces so we
+% have to play match the |()| manually.
+% \begin{macrocode}
+\cs_new_nopar:cpn { bool_&_0:w } & { \bool_eval_skip_to_end:Nw \c_false_bool }
+\cs_new_nopar:cpn { bool_|_1:w } | { \bool_eval_skip_to_end:Nw \c_true_bool }
+\cs_new_nopar:cpn { bool_not_&_1:w } &
+ { \bool_eval_skip_to_end:Nw \c_false_bool }
+\cs_new_nopar:cpn { bool_not_|_0:w } |
+ { \bool_eval_skip_to_end:Nw \c_true_bool }
+% \end{macrocode}
+% There is always at least one |)| waiting, namely the outer
+% one. However, we are facing the problem that there may be more than
+% one that need to be finished off and we have to detect the correct
+% number of them. Here is a complicated example showing how this is
+% done. After evaluating the following, we realize we must skip
+% everything after the first And. Note the extra Close at the end.
+% \begin{quote}
+% |\c_false_bool && ((abc) && xyz) && ((xyz) && (def)))|
+% \end{quote}
+% First read up to the first Close. This gives us the list we first
+% read up until the first right parenthesis so we are looking at the
+% token list
+% \begin{quote}
+% |((abc|
+% \end{quote}
+% This contains two Open markers so we must remove two groups. Since
+% no evaluation of the contents is to be carried out, it doesn't
+% matter how we remove the groups as long as we wind up with the
+% correct result. We therefore first remove a |()| pair and what
+% preceded the Open -- but leave the contents as it may contain Open
+% tokens itself -- leaving
+% \begin{quote}
+% |(abc && xyz) && ((xyz) && (def)))|
+% \end{quote}
+% Another round of this gives us
+% \begin{quote}
+% |(abc && xyz|
+% \end{quote}
+% which still contains an Open so we remove another |()| pair, giving us
+% \begin{quote}
+% |abc && xyz && ((xyz) && (def)))|
+% \end{quote}
+% Again we read up to a Close and again find Open tokens:
+% \begin{quote}
+% |abc && xyz && ((xyz|
+% \end{quote}
+% Further reduction gives us
+% \begin{quote}
+% |(xyz && (def)))|
+% \end{quote}
+% and then
+% \begin{quote}
+% |(xyz && (def|
+% \end{quote}
+% with reduction to
+% \begin{quote}
+% |xyz && (def))|
+% \end{quote}
+% and ultimately we arrive at no Open tokens being skipped and we can
+% finally close the group nicely.
+% \begin{macrocode}
+%% (
+\cs_new:Npn \bool_eval_skip_to_end:Nw #1#2 )
+ {
+ \bool_eval_skip_to_end_aux:Nw #1#2 ( % )
+ \q_no_value \q_stop
+ {#2}
+ }
+% \end{macrocode}
+% If no right parenthesis, then |#3| is no_value and we are done, return
+% the boolean |#1|. If there is, we need to grab a |()| pair and then
+% recurse
+% \begin{macrocode}
+\cs_new:Npn \bool_eval_skip_to_end_aux:Nw #1#2 ( #3#4 \q_stop #5 % )
+ {
+ \quark_if_no_value:NTF #3
+ {#1}
+ { \bool_eval_skip_to_end_aux_ii:Nw #1 #5 }
+ }
+% \end{macrocode}
+% Keep the boolean, throw away anything up to the |(| as it is
+% irrelevant, remove a |()| pair but remember to reinsert |#3| as it may
+% contain |(| tokens!
+% \begin{macrocode}
+\cs_new:Npn \bool_eval_skip_to_end_aux_ii:Nw #1#2 ( #3 )
+ { % (
+ \bool_eval_skip_to_end:Nw #1#3 )
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\bool_not_p:n}
+% \UnitTested
+% The Not variant just reverses the outcome of |\bool_if_p:n|. Can
+% be optimized but this is nice and simple and according to the
+% implementation plan. Not even particularly useful to have it when
+% the infix notation is easier to use.
+% \begin{macrocode}
+\cs_new:Npn \bool_not_p:n #1 { \bool_if_p:n { ! ( #1 ) } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\bool_xor_p:nn}
+% \UnitTested
+% Exclusive or. If the boolean expressions have same truth value,
+% return false, otherwise return true.
+% \begin{macrocode}
+\cs_new:Npn \bool_xor_p:nn #1#2
+ {
+ \int_compare:nNnTF { \bool_if_p:n {#1} } = { \bool_if_p:n {#2} }
+ \c_false_bool
+ \c_true_bool
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Logical loops}
+%
+% \begin{macro}{\bool_while_do:Nn,\bool_while_do:cn}
+% \UnitTested
+% \begin{macro}{\bool_until_do:Nn,\bool_until_do:cn}
+% \UnitTested
+% A |while| loop where the boolean is tested before executing the
+% statement. The \enquote{while} version executes the code as long as the
+% boolean is true; the \enquote{until} version executes the code as
+% long as the boolean is false.
+% \begin{macrocode}
+\cs_new:Npn \bool_while_do:Nn #1#2
+ { \bool_if:NT #1 { #2 \bool_while_do:Nn #1 {#2} } }
+\cs_new:Npn \bool_until_do:Nn #1#2
+ { \bool_if:NF #1 { #2 \bool_until_do:Nn #1 {#2} } }
+\cs_generate_variant:Nn \bool_while_do:Nn { c }
+\cs_generate_variant:Nn \bool_until_do:Nn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\bool_do_while:Nn,\bool_do_while:cn}
+% \UnitTested
+% \begin{macro}{\bool_do_until:Nn,\bool_do_until:cn}
+% \UnitTested
+% A |do-while| loop where the body is performed at least once and the
+% boolean is tested after executing the body. Otherwise identical to
+% the above functions.
+% \begin{macrocode}
+\cs_new:Npn \bool_do_while:Nn #1#2
+ { #2 \bool_if:NT #1 { \bool_do_while:Nn #1 {#2} } }
+\cs_new:Npn \bool_do_until:Nn #1#2
+ { #2 \bool_if:NF #1 { \bool_do_until:Nn #1 {#2} } }
+\cs_generate_variant:Nn \bool_do_while:Nn { c }
+\cs_generate_variant:Nn \bool_do_until:Nn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \bool_while_do:nn, \bool_do_while:nn ,
+% \bool_until_do:nn, \bool_do_until:nn
+% }
+% \UnitTested
+% Loop functions with the test either before or after the first body
+% expansion.
+% \begin{macrocode}
+\cs_new:Npn \bool_while_do:nn #1#2
+ {
+ \bool_if:nT {#1}
+ {
+ #2
+ \bool_while_do:nn {#1} {#2}
+ }
+ }
+\cs_new:Npn \bool_do_while:nn #1#2
+ {
+ #2
+ \bool_if:nT {#1} { \bool_do_while:nn {#1} {#2} }
+ }
+\cs_new:Npn \bool_until_do:nn #1#2
+ {
+ \bool_if:nF {#1}
+ {
+ #2
+ \bool_until_do:nn {#1} {#2}
+ }
+ }
+\cs_new:Npn \bool_do_until:nn #1#2
+ {
+ #2
+ \bool_if:nF {#1} { \bool_do_until:nn {#1} {#2} }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Switching by case}
+%
+% A family of functions to select one case of a number: the same ideas
+% are used for a number of different situations.
+%
+% \begin{macro}[aux]{\prg_case_end:nw}
+% In all cases the end statement is the same. Here, |#1| will be the
+% code needed, |#2| the other cases to throw away, including the
+% \enquote{else} case.
+% \begin{macrocode}
+\cs_new_eq:NN \prg_case_end:nw \use_i_delimit_by_q_recursion_stop:nw
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\prg_case_int:nnn}
+% \UnitTested
+% \begin{macro}[aux]{\prg_case_int_aux:nnn,\prg_case_int_aux:nw}
+% For integer cases, the first task to fully expand the check
+% condition. After that, a loop is started to compare each possible
+% value and stop if the test is true. The tested value is put at the
+% end to ensure that there is necessarily a match, which will fire the
+% \enquote{else} pathway.
+% \begin{macrocode}
+\cs_new:Npn \prg_case_int:nnn #1
+ { \exp_args:Nf \prg_case_int_aux:nnn { \int_eval:n {#1} } }
+\cs_new:Npn \prg_case_int_aux:nnn #1 #2 #3
+ { \prg_case_int_aux:nw {#1} #2 {#1} {#3} \q_recursion_stop }
+\cs_new:Npn \prg_case_int_aux:nw #1#2#3
+ {
+ \int_compare:nNnTF {#1} = {#2}
+ { \prg_case_end:nw {#3} }
+ { \prg_case_int_aux:nw {#1} }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\prg_case_dim:nnn}
+% \UnitTested
+% \begin{macro}[aux]{\prg_case_dim_aux:nnn,\prg_case_dim_aux:nw}
+% The dimension function is the same, just a change of calculation
+% method.
+% \begin{macrocode}
+\cs_new:Npn \prg_case_dim:nnn #1
+ { \exp_args:Nf \prg_case_dim_aux:nnn { \dim_eval:n {#1} } }
+\cs_new:Npn \prg_case_dim_aux:nnn #1 #2 #3
+ { \prg_case_dim_aux:nw {#1} #2 {#1} {#3} \q_recursion_stop }
+\cs_new:Npn \prg_case_dim_aux:nw #1#2#3
+ {
+ \dim_compare:nNnTF {#1} = {#2}
+ { \prg_case_end:nw {#3} }
+ { \prg_case_dim_aux:nw {#1} }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\prg_case_str:nnn, \prg_case_str:onn, \prg_case_str:xxn}
+% \UnitTested
+% \begin{macro}[aux]{\prg_case_str_aux:nw, \prg_case_str_x_aux:nw}
+% No calculations for strings, otherwise no surprises.
+% \begin{macrocode}
+\cs_new:Npn \prg_case_str:nnn #1#2#3
+ { \prg_case_str_aux:nw {#1} #2 {#1} {#3} \q_recursion_stop }
+\cs_new:Npn \prg_case_str_aux:nw #1#2#3
+ {
+ \str_if_eq:nnTF {#1} {#2}
+ { \prg_case_end:nw {#3} }
+ { \prg_case_str_aux:nw {#1} }
+ }
+\cs_generate_variant:Nn \prg_case_str:nnn { o }
+\cs_new:Npn \prg_case_str:xxn #1#2#3
+ { \prg_case_str_x_aux:nw {#1} #2 {#1} {#3} \q_recursion_stop }
+\cs_new:Npn \prg_case_str_x_aux:nw #1#2#3
+ {
+ \str_if_eq:xxTF {#1} {#2}
+ { \prg_case_end:nw {#3} }
+ { \prg_case_str_aux:nw {#1} }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\prg_case_tl:Nnn, \prg_case_tl:cnn}
+% \UnitTested
+% \begin{macro}[aux]{\prg_case_tl_aux:Nw}
+% Similar again, but this time with some variants.
+% \begin{macrocode}
+\cs_new:Npn \prg_case_tl:Nnn #1#2#3
+ { \prg_case_tl_aux:Nw #1 #2 #1 {#3} \q_recursion_stop }
+\cs_new:Npn \prg_case_tl_aux:Nw #1#2#3
+ {
+ \tl_if_eq:NNTF #1 #2
+ { \prg_case_end:nw {#3} }
+ { \prg_case_tl_aux:Nw #1 }
+ }
+\cs_generate_variant:Nn \prg_case_tl:Nnn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Producing $n$ copies}
+%
+% \begin{macro}{\prg_replicate:nn}
+% \UnitTested
+% \begin{macro}[aux]{\prg_replicate_aux:N, \prg_replicate_first_aux:N}
+% \begin{macro}[aux]{\prg_replicate_}
+% \begin{macro}[aux]
+% {
+% \prg_replicate_0:n,
+% \prg_replicate_1:n,
+% \prg_replicate_2:n,
+% \prg_replicate_3:n,
+% \prg_replicate_4:n,
+% \prg_replicate_5:n,
+% \prg_replicate_6:n,
+% \prg_replicate_7:n,
+% \prg_replicate_8:n,
+% \prg_replicate_9:n
+% }
+% \begin{macro}[aux]
+% {
+% \prg_replicate_first_-:n,
+% \prg_replicate_first_0:n,
+% \prg_replicate_first_1:n,
+% \prg_replicate_first_2:n,
+% \prg_replicate_first_3:n,
+% \prg_replicate_first_4:n,
+% \prg_replicate_first_5:n,
+% \prg_replicate_first_6:n,
+% \prg_replicate_first_7:n,
+% \prg_replicate_first_8:n,
+% \prg_replicate_first_9:n
+% }
+% This function uses a cascading csname technique by David Kastrup
+% (who else :-)
+%
+% The idea is to make the input |25| result in first adding five, and
+% then 20 copies of the code to be replicated. The technique uses
+% cascading csnames which means that we start building several csnames
+% so we end up with a list of functions to be called in reverse
+% order. This is important here (and other places) because it means
+% that we can for instance make the function that inserts five copies
+% of something to also hand down ten to the next function in
+% line. This is exactly what happens here: in the example with |25|
+% then the next function is the one that inserts two copies but it
+% sees the ten copies handed down by the previous function. In order
+% to avoid the last function to insert say, $100$ copies of the original
+% argument just to gobble them again we define separate functions to
+% be inserted first. These functions also close the expansion of
+% \cs{int_to_roman:w}, which ensures that \cs{prg_replicate:nn} only
+% requires two steps of expansion.
+%
+% This function has one flaw though: Since it constantly passes down
+% ten copies of its previous argument it will severely affect the main
+% memory once you start demanding hundreds of thousands of copies. Now
+% I don't think this is a real limitation for any ordinary use, and if
+% necessary, it is possible to write
+% |\prg_replicate:nn{1000}{\prg_replicate:nn{1000}{|\meta{code}|}}|. An
+% alternative approach is to create a string of |m|'s with
+% \cs{int_to_roman:w} which can be done with just four macros but that
+% method has its own problems since it can exhaust the string
+% pool. Also, it is considerably slower than what we use here so the
+% few extra csnames are well spent I would say.
+% \begin{macrocode}
+\cs_new_nopar:Npn \prg_replicate:nn #1
+ {
+ \int_to_roman:w
+ \exp_after:wN \prg_replicate_first_aux:N
+ \int_value:w \int_eval:w #1 \int_eval_end:
+ \cs_end:
+ }
+\cs_new_nopar:Npn \prg_replicate_aux:N #1
+ { \cs:w prg_replicate_#1 :n \prg_replicate_aux:N }
+\cs_new_nopar:Npn \prg_replicate_first_aux:N #1
+ { \cs:w prg_replicate_first_ #1 :n \prg_replicate_aux:N }
+% \end{macrocode}
+% \end{macro}
+% Then comes all the functions that do the hard work of inserting all
+% the copies.
+% \begin{macrocode}
+\cs_new_nopar:Npn \prg_replicate_ :n #1 { \cs_end: }
+\cs_new:cpn { prg_replicate_0:n } #1 { \cs_end: {#1#1#1#1#1#1#1#1#1#1} }
+\cs_new:cpn { prg_replicate_1:n } #1 { \cs_end: {#1#1#1#1#1#1#1#1#1#1} #1 }
+\cs_new:cpn { prg_replicate_2:n } #1 { \cs_end: {#1#1#1#1#1#1#1#1#1#1} #1#1 }
+\cs_new:cpn { prg_replicate_3:n } #1
+ { \cs_end: {#1#1#1#1#1#1#1#1#1#1} #1#1#1 }
+\cs_new:cpn { prg_replicate_4:n } #1
+ { \cs_end: {#1#1#1#1#1#1#1#1#1#1} #1#1#1#1 }
+\cs_new:cpn { prg_replicate_5:n } #1
+ { \cs_end: {#1#1#1#1#1#1#1#1#1#1} #1#1#1#1#1 }
+\cs_new:cpn { prg_replicate_6:n } #1
+ { \cs_end: {#1#1#1#1#1#1#1#1#1#1} #1#1#1#1#1#1 }
+\cs_new:cpn { prg_replicate_7:n } #1
+ { \cs_end: {#1#1#1#1#1#1#1#1#1#1} #1#1#1#1#1#1#1 }
+\cs_new:cpn { prg_replicate_8:n } #1
+ { \cs_end: {#1#1#1#1#1#1#1#1#1#1} #1#1#1#1#1#1#1#1 }
+\cs_new:cpn { prg_replicate_9:n } #1
+ { \cs_end: {#1#1#1#1#1#1#1#1#1#1} #1#1#1#1#1#1#1#1#1 }
+% \end{macrocode}
+% Users shouldn't ask for something to be replicated once or even
+% not at all but\dots
+% \begin{macrocode}
+\cs_new:cpn { prg_replicate_first_-:n } #1 { \c_zero \negative_replication }
+\cs_new:cpn { prg_replicate_first_0:n } #1 { \c_zero }
+\cs_new:cpn { prg_replicate_first_1:n } #1 { \c_zero #1 }
+\cs_new:cpn { prg_replicate_first_2:n } #1 { \c_zero #1#1 }
+\cs_new:cpn { prg_replicate_first_3:n } #1 { \c_zero #1#1#1 }
+\cs_new:cpn { prg_replicate_first_4:n } #1 { \c_zero #1#1#1#1 }
+\cs_new:cpn { prg_replicate_first_5:n } #1 { \c_zero #1#1#1#1#1 }
+\cs_new:cpn { prg_replicate_first_6:n } #1 { \c_zero #1#1#1#1#1#1 }
+\cs_new:cpn { prg_replicate_first_7:n } #1 { \c_zero #1#1#1#1#1#1#1 }
+\cs_new:cpn { prg_replicate_first_8:n } #1 { \c_zero #1#1#1#1#1#1#1#1 }
+\cs_new:cpn { prg_replicate_first_9:n } #1 { \c_zero #1#1#1#1#1#1#1#1#1 }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\prg_stepwise_function:nnnN}
+% \begin{macro}[aux]
+% {\prg_stepwise_function_incr:nnnN, \prg_stepwise_function_decr:nnnN}
+% Repeating a function by steps fist needs a check on the direction
+% of the steps. After that, do the function for the start value
+% then step and loop around.
+% \begin{macrocode}
+\cs_new:Npn \prg_stepwise_function:nnnN #1#2
+ {
+ \int_compare:nNnTF {#2} > { 0 }
+ { \exp_args:Nf \prg_stepwise_function_incr:nnnN }
+ { \exp_args:Nf \prg_stepwise_function_decr:nnnN }
+ { \int_eval:n {#1} } {#2}
+ }
+\cs_new:Npn \prg_stepwise_function_incr:nnnN #1#2#3#4
+ {
+ \int_compare:nNnF {#1} > {#3}
+ {
+ #4 {#1}
+ \exp_args:Nf \prg_stepwise_function_incr:nnnN
+ { \int_eval:n { #1 + #2 } } {#2} {#3} #4
+ }
+ }
+\cs_new:Npn \prg_stepwise_function_decr:nnnN #1#2#3#4
+ {
+ \int_compare:nNnF {#1} < {#3}
+ {
+ #4 {#1}
+ \exp_args:Nf \prg_stepwise_function_decr:nnnN
+ { \int_eval:n { #1 + #2 } } {#2} {#3} #4
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+%\begin{macro}[aux]{\g_prg_stepwise_level_int}
+% For nesting, the usual approach of using a counter.
+% \begin{macrocode}
+\int_new:N \g_prg_stepwise_level_int
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\prg_stepwise_inline:nnnn}
+%\begin{macro}[aux]
+% {\prg_stepwise_inline_incr:Nnnn, \prg_stepwise_inline_decr:Nnnn}
+% The approach here is similar but with a global integer required
+% to make the nesting safe (as seen in other in line functions).
+% \begin{macrocode}
+\cs_new_protected:Npn \prg_stepwise_inline:nnnn #1#2#3#4
+ {
+ \int_gincr:N \g_prg_stepwise_level_int
+ \cs_gset_nopar:cpn
+ { g_prg_stepwise_ \int_use:N \g_prg_stepwise_level_int :n }
+ ##1 {#4}
+ \int_compare:nNnTF {#2} > { 0 }
+ { \exp_args:Ncf \prg_stepwise_inline_incr:Nnnn }
+ { \exp_args:Ncf \prg_stepwise_inline_decr:Nnnn }
+ { g_prg_stepwise_ \int_use:N \g_prg_stepwise_level_int :n }
+ { \int_eval:n {#1} } {#2} {#3}
+ \int_gdecr:N \g_prg_stepwise_level_int
+ }
+\cs_new_protected:Npn \prg_stepwise_inline_incr:Nnnn #1#2#3#4
+ {
+ \int_compare:nNnF {#2} > {#4}
+ {
+ #1 {#2}
+ \exp_args:NNf \prg_stepwise_inline_incr:Nnnn #1
+ { \int_eval:n { #2 + #3 } } {#3} {#4}
+ }
+ }
+\cs_new_protected:Npn \prg_stepwise_inline_decr:Nnnn #1#2#3#4
+ {
+ \int_compare:nNnF {#2} < {#4}
+ {
+ #1 {#2}
+ \exp_args:NNf \prg_stepwise_inline_decr:Nnnn #1
+ { \int_eval:n { #2 + #3 } } {#3} {#4}
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\prg_stepwise_variable:nnnNn}
+% \UnitTested
+% A wrapper for the above.
+% \begin{macrocode}
+\cs_new_protected:Npn \prg_stepwise_variable:nnnNn #1#2#3#4#5
+ {
+ \prg_stepwise_inline:nnnn {#1} {#2} {#3}
+ {
+ \tl_set:Nn #4 {##1}
+ #5
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Detecting \TeX{}'s mode}
+%
+% \begin{macro}[pTF]{\mode_if_vertical:}
+% \UnitTested
+% For testing vertical mode. Strikes me here on the bus with David,
+% that as long as we are just talking about returning true and
+% false states, we can just use the primitive conditionals for this
+% and gobbling the |\c_zero| in the input stream. However this
+% requires knowledge of the implementation so we keep things nice
+% and clean and use the return statements.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \mode_if_vertical: { p , T , F , TF }
+ { \if_mode_vertical: \prg_return_true: \else: \prg_return_false: \fi: }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\mode_if_horizontal:}
+% \UnitTested
+% For testing horizontal mode.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \mode_if_horizontal: { p , T , F , TF }
+ { \if_mode_horizontal: \prg_return_true: \else: \prg_return_false: \fi: }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\mode_if_inner:}
+% \UnitTested
+% For testing inner mode.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \mode_if_inner: { p , T , F , TF }
+ { \if_mode_inner: \prg_return_true: \else: \prg_return_false: \fi: }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\mode_if_math:}
+% \UnitTested
+% For testing math mode: without \cs{} things go wrong in alignments.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \mode_if_math: { p , T , F , TF }
+ {
+ \scan_align_safe_stop:
+ \if_mode_math: \prg_return_true: \else: \prg_return_false: \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Internal programming functions}
+%
+% \begin{macro}[int]{\group_align_safe_begin:, \group_align_safe_end:}
+% \TeX{}'s alignment structures present many problems. As Knuth says
+% himself in \emph{\TeX : The Program}: \enquote{It's sort of a miracle
+% whenever \cs{halign} or \cs{valign} work, [\ldots]} One problem relates
+% to commands that internally issues a |\cr| but also peek ahead for
+% the next character for use in, say, an optional argument. If the
+% next token happens to be a |&| with category code~4 we will get some
+% sort of weird error message because the underlying
+% |\tex_futurelet:D| will store the token at the end of the alignment
+% template. This could be a |&|$_4$ giving a message like
+% |! Misplaced \cr.| or even worse: it could be the |\endtemplate|
+% token causing even more trouble! To solve this we have to open a
+% special group so that \TeX{} still thinks it's on safe ground but at
+% the same time we don't want to introduce any brace group that may
+% find its way to the output. The following functions help with this
+% by using code documented only in Appendix~D of
+% \emph{The \TeX{}book}\dots
+% \begin{macrocode}
+\cs_new_nopar:Npn \group_align_safe_begin:
+ { \if_false: { \fi: \if_int_compare:w `} = \c_zero \fi: }
+\cs_new_nopar:Npn \group_align_safe_end:
+ { \if_int_compare:w `{ = \c_zero } \fi: }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\scan_align_safe_stop:}
+% When \TeX{} is in the beginning of an align cell (right after the
+% |\cr|) it is in a somewhat strange mode as it is looking ahead to
+% find an |\tex_omit:D| or |\tex_noalign:D| and hasn't looked at the
+% preamble yet. Thus an |\tex_ifmmode:D| test will always fail unless
+% we insert |\scan_stop:| to stop \TeX{}'s scanning ahead. On the other
+% hand we don't want to insert a |\scan_stop:| every time as that will
+% destroy kerning between letters\footnote{Unless we enforce an extra
+% pass with an appropriate value of \cs{pretolerance}.}
+% Unfortunately there is no way to detect if we're in the beginning of
+% an alignment cell as they have different characteristics depending
+% on column number, \emph{etc.} However we \emph{can} detect if we're in an
+% alignment cell by checking the current group type and we can also
+% check if the previous node was a character or ligature. What is done
+% here is that |\scan_stop:| is only inserted if an only
+% if a)~we're in the
+% outer part of an alignment cell and b)~the last node \emph{wasn't} a
+% char node or a ligature node.
+% \begin{macrocode}
+\cs_new_nopar:Npn \scan_align_safe_stop:
+ {
+ \int_compare:nNnT \etex_currentgrouptype:D = \c_six
+ {
+ \int_compare:nNnF \etex_lastnodetype:D = \c_zero
+ { \int_compare:nNnF \etex_lastnodetype:D = \c_seven { \scan_stop: } }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\prg_variable_get_scope:N}
+% \begin{macro}[aux]{\prg_variable_get_scope_aux:w}
+% \begin{macro}[int]{\prg_variable_get_type:N}
+% \begin{macro}[aux]{\prg_variable_get_type:w}
+% Expandable functions to find the type of a variable, and to
+% return \texttt{g} if the variable is global. The trick for
+% \cs{prg_variable_get_scope:N} is the same as that in
+% \cs{cs_split_function:NN}, but it can be simplified as the
+% requirements here are less complex.
+% \begin{macrocode}
+\group_begin:
+ \tex_lccode:D `\& = `\g \scan_stop:
+ \tex_catcode:D `\& = \c_twelve
+\tl_to_lowercase:n
+ {
+ \group_end:
+ \cs_new_nopar:Npn \prg_variable_get_scope:N #1
+ {
+ \exp_last_unbraced:Nf \prg_variable_get_scope_aux:w
+ { \cs_to_str:N #1 \exp_stop_f: \q_stop }
+ }
+ \cs_new_nopar:Npn \prg_variable_get_scope_aux:w #1#2 \q_stop
+ { \token_if_eq_meaning:NNT & #1 { g } }
+ }
+\group_begin:
+ \tex_lccode:D `\& = `\_ \scan_stop:
+ \tex_catcode:D `\& = \c_twelve
+\tl_to_lowercase:n
+ {
+ \group_end:
+ \cs_new_nopar:Npn \prg_variable_get_type:N #1
+ {
+ \exp_after:wN \prg_variable_get_type_aux:w
+ \token_to_str:N #1 & a \q_stop
+ }
+ \cs_new_nopar:Npn \prg_variable_get_type_aux:w #1 & #2#3 \q_stop
+ {
+ \token_if_eq_meaning:NNTF a #2
+ {#1}
+ { \prg_variable_get_type_aux:w #2#3 \q_stop }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Experimental programmings functions}
+%
+%
+% \begin{macro}[aux]{\prg_define_quicksort:nnn}
+% |#1| is the name, |#2| and |#3| are the tokens enclosing the
+% argument. For the somewhat strange \meta{clist} type which doesn't
+% enclose the items but uses a separator we define it by hand
+% afterwards. When doing the first pass, the algorithm wraps all
+% elements in braces and then uses a generic quicksort which works
+% on token lists.
+%
+% As an example
+% \begin{quote}
+% |\prg_define_quicksort:nnn{seq}{\seq_elt:w}{\seq_elt_end:w}|
+% \end{quote}
+% defines the user function |\seq_quicksort:n| and furthermore
+% expects to use the two functions |\seq_quicksort_compare:nnTF|
+% which compares the items and |\seq_quicksort_function:n| which is
+% placed before each sorted item. It is up to the programmer to
+% define these functions when needed. For the |seq| type a sequence
+% is a token list variable, so one additionally has to define
+% \begin{quote}
+% |\cs_set_nopar:Npn \seq_quicksort:N{\exp_args:No\seq_quicksort:n}|
+% \end{quote}
+%
+%
+% For details on the implementation see \enquote{Sorting in \TeX{}'s Mouth}
+% by Bernd Raichle. Firstly we define the function for parsing the
+% initial list and then the braced list afterwards.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \prg_define_quicksort:nnn #1#2#3 {
+ \cs_set:cpx{#1_quicksort:n}##1{
+ \exp_not:c{#1_quicksort_start_partition:w} ##1
+ \exp_not:n{#2\q_nil#3\q_stop}
+ }
+ \cs_set:cpx{#1_quicksort_braced:n}##1{
+ \exp_not:c{#1_quicksort_start_partition_braced:n} ##1
+ \exp_not:N\q_nil\exp_not:N\q_stop
+ }
+ \cs_set:cpx {#1_quicksort_start_partition:w} #2 ##1 #3{
+ \exp_not:N \quark_if_nil:nT {##1}\exp_not:N \use_none_delimit_by_q_stop:w
+ \exp_not:c{#1_quicksort_do_partition_i:nnnw} {##1}{}{}
+ }
+ \cs_set:cpx {#1_quicksort_start_partition_braced:n} ##1 {
+ \exp_not:N \quark_if_nil:nT {##1}\exp_not:N \use_none_delimit_by_q_stop:w
+ \exp_not:c{#1_quicksort_do_partition_i_braced:nnnn} {##1}{}{}
+ }
+% \end{macrocode}
+% Now for doing the partitions.
+% \begin{macrocode}
+ \cs_set:cpx {#1_quicksort_do_partition_i:nnnw} ##1##2##3 #2 ##4 #3 {
+ \exp_not:N \quark_if_nil:nTF {##4} \exp_not:c {#1_do_quicksort_braced:nnnnw}
+ {
+ \exp_not:c{#1_quicksort_compare:nnTF}{##1}{##4}
+ \exp_not:c{#1_quicksort_partition_greater_ii:nnnn}
+ \exp_not:c{#1_quicksort_partition_less_ii:nnnn}
+ }
+ {##1}{##2}{##3}{##4}
+ }
+ \cs_set:cpx {#1_quicksort_do_partition_i_braced:nnnn} ##1##2##3##4 {
+ \exp_not:N \quark_if_nil:nTF {##4} \exp_not:c {#1_do_quicksort_braced:nnnnw}
+ {
+ \exp_not:c{#1_quicksort_compare:nnTF}{##1}{##4}
+ \exp_not:c{#1_quicksort_partition_greater_ii_braced:nnnn}
+ \exp_not:c{#1_quicksort_partition_less_ii_braced:nnnn}
+ }
+ {##1}{##2}{##3}{##4}
+ }
+ \cs_set:cpx {#1_quicksort_do_partition_ii:nnnw} ##1##2##3 #2 ##4 #3 {
+ \exp_not:N \quark_if_nil:nTF {##4} \exp_not:c {#1_do_quicksort_braced:nnnnw}
+ {
+ \exp_not:c{#1_quicksort_compare:nnTF}{##4}{##1}
+ \exp_not:c{#1_quicksort_partition_less_i:nnnn}
+ \exp_not:c{#1_quicksort_partition_greater_i:nnnn}
+ }
+ {##1}{##2}{##3}{##4}
+ }
+ \cs_set:cpx {#1_quicksort_do_partition_ii_braced:nnnn} ##1##2##3##4 {
+ \exp_not:N \quark_if_nil:nTF {##4} \exp_not:c {#1_do_quicksort_braced:nnnnw}
+ {
+ \exp_not:c{#1_quicksort_compare:nnTF}{##4}{##1}
+ \exp_not:c{#1_quicksort_partition_less_i_braced:nnnn}
+ \exp_not:c{#1_quicksort_partition_greater_i_braced:nnnn}
+ }
+ {##1}{##2}{##3}{##4}
+ }
+% \end{macrocode}
+% This part of the code handles the two branches in each
+% sorting. Again we will also have to do it braced.
+% \begin{macrocode}
+ \cs_set:cpx {#1_quicksort_partition_less_i:nnnn} ##1##2##3##4{
+ \exp_not:c{#1_quicksort_do_partition_i:nnnw}{##1}{##2}{{##4}##3}}
+ \cs_set:cpx {#1_quicksort_partition_less_ii:nnnn} ##1##2##3##4{
+ \exp_not:c{#1_quicksort_do_partition_ii:nnnw}{##1}{##2}{##3{##4}}}
+ \cs_set:cpx {#1_quicksort_partition_greater_i:nnnn} ##1##2##3##4{
+ \exp_not:c{#1_quicksort_do_partition_i:nnnw}{##1}{{##4}##2}{##3}}
+ \cs_set:cpx {#1_quicksort_partition_greater_ii:nnnn} ##1##2##3##4{
+ \exp_not:c{#1_quicksort_do_partition_ii:nnnw}{##1}{##2{##4}}{##3}}
+ \cs_set:cpx {#1_quicksort_partition_less_i_braced:nnnn} ##1##2##3##4{
+ \exp_not:c{#1_quicksort_do_partition_i_braced:nnnn}{##1}{##2}{{##4}##3}}
+ \cs_set:cpx {#1_quicksort_partition_less_ii_braced:nnnn} ##1##2##3##4{
+ \exp_not:c{#1_quicksort_do_partition_ii_braced:nnnn}{##1}{##2}{##3{##4}}}
+ \cs_set:cpx {#1_quicksort_partition_greater_i_braced:nnnn} ##1##2##3##4{
+ \exp_not:c{#1_quicksort_do_partition_i_braced:nnnn}{##1}{{##4}##2}{##3}}
+ \cs_set:cpx {#1_quicksort_partition_greater_ii_braced:nnnn} ##1##2##3##4{
+ \exp_not:c{#1_quicksort_do_partition_ii_braced:nnnn}{##1}{##2{##4}}{##3}}
+% \end{macrocode}
+% Finally, the big kahuna! This is where the sub-lists are sorted.
+% \begin{macrocode}
+ \cs_set:cpx {#1_do_quicksort_braced:nnnnw} ##1##2##3##4\q_stop {
+ \exp_not:c{#1_quicksort_braced:n}{##2}
+ \exp_not:c{#1_quicksort_function:n}{##1}
+ \exp_not:c{#1_quicksort_braced:n}{##3}
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\prg_quicksort:n}
+% \UnitTested
+% A simple version. Sorts a list of tokens, uses the function
+% |\prg_quicksort_compare:nnTF| to compare items, and places the
+% function |\prg_quicksort_function:n| in front of each of them.
+% \begin{macrocode}
+\prg_define_quicksort:nnn {prg}{}{}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\prg_quicksort_function:n}
+% \UnitTested
+% \begin{macro}{\prg_quicksort_compare:nnTF}
+% \UnitTested
+% \begin{macrocode}
+\cs_set:Npn \prg_quicksort_function:n {\ERROR}
+\cs_set:Npn \prg_quicksort_compare:nnTF {\ERROR}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Deprecated functions}
+%
+% These were depreciated on 2011-05-27 and will be removed entirely by
+% 2011-08-31.
+%
+% \begin{macro}{\prg_new_map_functions:Nn}
+% \begin{macro}{\prg_set_map_functions:Nn}
+% As we have restructured the structured variables, these are no
+% longer needed.
+% \begin{macrocode}
+\cs_new_protected:Npn \prg_new_map_functions:Nn #1#2 { \deprectiated }
+\cs_new_protected:Npn \prg_set_map_functions:Nn #1#2 { \deprectiated }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macrocode}
+%</initex|package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex \ No newline at end of file
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx b/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx
new file mode 100644
index 00000000000..744cea629fc
--- /dev/null
+++ b/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx
@@ -0,0 +1,1206 @@
+% \iffalse meta-comment
+%
+%% File: l3prop.dtx Copyright (C) 1990-2011 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 "expl3 bundle" (The Work in LPPL)
+%% and all files in that bundle must be distributed together.
+%%
+%% The released version of this bundle is available from CTAN.
+%%
+%% -----------------------------------------------------------------------
+%%
+%% The development version of the bundle can be found at
+%%
+%% http://www.latex-project.org/svnroot/experimental/trunk/
+%%
+%% for those people who are interested.
+%%
+%%%%%%%%%%%
+%% NOTE: %%
+%%%%%%%%%%%
+%%
+%% Snapshots taken from the repository represent work in progress and may
+%% not work or may contain conflicting material! We therefore ask
+%% people _not_ to put them into distributions, archives, etc. without
+%% prior consultation with the LaTeX3 Project.
+%%
+%% -----------------------------------------------------------------------
+%
+%<*driver|package>
+\RequirePackage{l3names}
+\GetIdInfo$Id: l3prop.dtx 2478 2011-06-19 21:34:23Z joseph $
+ {L3 Experimental property lists}
+%</driver|package>
+%<*driver>
+\documentclass[full]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3prop} package\\ Property lists^^A
+% \thanks{This file describes v\ExplFileVersion,
+% last revised \ExplFileDate.}^^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 \ExplFileDate}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% \LaTeX3 implements a \enquote{property list} data type, which contain
+% an unordered list of entries each of which consists of a \meta{key} and
+% an associated \meta{value}. The \meta{key} and \meta{value} may both be
+% any \meta{balanced text}. It is possible to map functions to property lists
+% such that the function is applied to every key--value pair within
+% the list.
+%
+% Each entry in a property list must have a unique \meta{key}: if an entry is
+% added to a property list which already contains the \meta{key} then the new
+% entry will overwrite the existing one. The \meta{keys} are compared on a
+% string basis, using the same method as \cs{str_if_eq:nn}.
+%
+% \section{Creating and initialising property lists}
+%
+% \begin{function}{\prop_new:N, \prop_new:c}
+% \begin{syntax}
+% \cs{prop_new:N} \meta{property list}
+% \end{syntax}
+% Creates a new \meta{property list} or raises an error if the name is
+% already taken. The declaration is global. The \meta{property lists} will
+% initially contain no entries.
+% \end{function}
+%
+% \begin{function}{\prop_clear:N, \prop_clear:c}
+% \begin{syntax}
+% \cs{prop_clear:N} \meta{property list}
+% \end{syntax}
+% Clears all entries from the \meta{property list} within the scope of
+% the current \TeX{} group.
+% \end{function}
+%
+% \begin{function}{\prop_gclear:N, \prop_gclear:c}
+% \begin{syntax}
+% \cs{prop_gclear:N} \meta{property list}
+% \end{syntax}
+% Clears all entries from the \meta{property list} globally.
+% \end{function}
+%
+% \begin{function}{\prop_clear_new:N, \prop_clear_new:c}
+% \begin{syntax}
+% \cs{prop_clear_new:N} \meta{property list}
+% \end{syntax}
+% If the \meta{property list} already exists, clears it within the scope
+% of the current \TeX{} group. If the \meta{property list} is not defined,
+% it will be created (using \cs{prop_new:N}). Thus the property list is
+% guaranteed to be available and clear within the current \TeX{}
+% group. The \meta{property list} will exist globally, but the content
+% outside of the current \TeX{} group is not specified.
+% \end{function}
+%
+% \begin{function}{\prop_gclear_new:N, \prop_gclear_new:c}
+% \begin{syntax}
+% \cs{prop_gclear_new:N} \meta{property list}
+% \end{syntax}
+% If the \meta{property list} already exists, clears it globally. If the
+% \meta{property list} is not defined, it will be created (using
+% \cs{prop_new:N}). Thus the property list is guaranteed to be available
+% and globally clear.
+% \end{function}
+%
+% \begin{function}
+% {\prop_set_eq:NN, \prop_set_eq:cN, \prop_set_eq:Nc, \prop_set_eq:cc}
+% \begin{syntax}
+% \cs{prop_set_eq:NN} \meta{property list1} \meta{property list2}
+% \end{syntax}
+% Sets the content of \meta{property list1} equal to that of
+% \meta{property list2}. This assignment is restricted to the current
+% \TeX{} group level.
+% \end{function}
+%
+% \begin{function}
+% {\prop_gset_eq:NN, \prop_gset_eq:cN, \prop_gset_eq:Nc, \prop_gset_eq:cc}
+% \begin{syntax}
+% \cs{prop_gset_eq:NN} \meta{property list1} \meta{property list2}
+% \end{syntax}
+% Sets the content of \meta{property list1} equal to that of
+% \meta{property list2}. This assignment is global and so is not
+% limited by the current \TeX{} group level.
+% \end{function}
+%
+% \section{Adding entries to property lists}
+%
+% \begin{function}
+% {
+% \prop_put:Nnn, \prop_put:NnV, \prop_put:Nno, \prop_put:Nnx,
+% \prop_put:NVn, \prop_put:NVV, \prop_put:Non, \prop_put:Noo,
+% \prop_put:cnn, \prop_put:cnV, \prop_put:cno, \prop_put:cnx,
+% \prop_put:cVn, \prop_put:cVV, \prop_put:con, \prop_put:coo
+% }
+% \begin{syntax}
+% \cs{prop_put:Nnn} \meta{property list} \Arg{key} \Arg{value}
+% \end{syntax}
+% Adds an entry to the \meta{property list} which may be accessed
+% using the \meta{key} and which has \meta{value}. Both the \meta{key}
+% and \meta{value} may contain any \meta{balanced text}. The \meta{key}
+% is stored after processing with \cs{tl_to_str:n}, meaning that
+% category codes are ignored. If the \meta{key} is already present
+% in the \meta{property list}, the existing entry is overwritten
+% by the new \meta{value}. The assignment is restricted to the current
+% \TeX{} group.
+% \end{function}
+%
+% \begin{function}
+% {
+% \prop_gput:Nnn, \prop_gput:NnV, \prop_gput:Nno, \prop_gput:Nnx,
+% \prop_gput:NVn, \prop_gput:NVV, \prop_gput:Non, \prop_gput:Noo,
+% \prop_gput:cnn, \prop_gput:cnV, \prop_gput:cno, \prop_gput:cnx,
+% \prop_gput:cVn, \prop_gput:cVV, \prop_gput:con, \prop_gput:coo
+% }
+% \begin{syntax}
+% \cs{prop_gput:Nnn} \meta{property list} \Arg{key} \Arg{value}
+% \end{syntax}
+% Adds an entry to the \meta{property list} which may be accessed
+% using the \meta{key} and which has \meta{value}. Both the \meta{key}
+% and \meta{value} may contain any \meta{balanced text}. The \meta{key}
+% is stored after processing with \cs{tl_to_str:n}, meaning that
+% category codes are ignored. If the \meta{key} is already present
+% in the \meta{property list}, the existing entry is overwritten
+% by the new \meta{value}. The assignment is global.
+% \end{function}
+%
+% \begin{function}{\prop_put_if_new:Nnn, \prop_put_if_new:cnn}
+% \begin{syntax}
+% \cs{prop_put_if_new:Nnn} \meta{property list} \Arg{key} \Arg{value}
+% \end{syntax}
+% If the \meta{key} is present in the \meta{property list} then
+% no action is taken. If the \meta{key} is not present in the
+% \meta{property list} then a new entry is added. Both the \meta{key}
+% and \meta{value} may contain any \meta{balanced text}. The \meta{key}
+% is stored after processing with \cs{tl_to_str:n}, meaning that
+% category codes are ignored. The assignment is restricted to the current
+% \TeX{} group.
+% \end{function}
+%
+% \begin{function}{\prop_gput_if_new:Nnn, \prop_gput_if_new:cnn}
+% \begin{syntax}
+% \cs{prop_gput_if_new:Nnn} \meta{property list} \Arg{key} \Arg{value}
+% \end{syntax}
+% If the \meta{key} is present in the \meta{property list} then
+% no action is taken. If the \meta{key} is not present in the
+% \meta{property list} then a new entry is added. Both the \meta{key}
+% and \meta{value} may contain any \meta{balanced text}. The \meta{key}
+% is stored after processing with \cs{tl_to_str:n}, meaning that
+% category codes are ignored. The assignment is global.
+% \end{function}
+%
+% \section{Recovering values from property lists}
+%
+% \begin{function}
+% {
+% \prop_get:NnN, \prop_get:NVN, \prop_get:NoN,
+% \prop_get:cnN, \prop_get:cVN, \prop_get:coN,
+% }
+% \begin{syntax}
+% \cs{prop_get:NnN} \meta{property list} \Arg{key} \meta{tl var}
+% \end{syntax}
+% Recovers the \meta{value} stored with \meta{key} from the
+% \meta{property list}, and places this in the \meta{token list
+% variable}. If the \meta{key} is not found in the
+% \meta{property list} then the \meta{token list variable} will
+% contain the special marker \cs{q_no_value}. The \meta{token list
+% variable} is set within the current \TeX{} group.
+% \end{function}
+%
+% \begin{function}{\prop_pop:NnN, \prop_pop:NoN, \prop_pop:cnN, \prop_pop:coN}
+% \begin{syntax}
+% \cs{prop_pop:NnN} \meta{property list} \Arg{key} \meta{tl var}
+% \end{syntax}
+% Recovers the \meta{value} stored with \meta{key} from the
+% \meta{property list}, and places this in the \meta{token list
+% variable}. If the \meta{key} is not found in the
+% \meta{property list} then the \meta{token list variable} will
+% contain the special marker \cs{q_no_value}. The \meta{key} and
+% \meta{value} are then deleted from the property list. Both
+% assignments are local.
+% \end{function}
+%
+% \begin{function}
+% {\prop_gpop:NnN, \prop_gpop:NoN, \prop_gpop:cnN, \prop_gpop:coN}
+% \begin{syntax}
+% \cs{prop_gpop:NnN} \meta{property list} \Arg{key} \meta{tl var}
+% \end{syntax}
+% Recovers the \meta{value} stored with \meta{key} from the
+% \meta{property list}, and places this in the \meta{token list
+% variable}. If the \meta{key} is not found in the
+% \meta{property list} then the \meta{token list variable} will
+% contain the special marker \cs{q_no_value}. The \meta{key} and
+% \meta{value} are then deleted from the property list.
+% The \meta{property list} is modified globally, while the assignment of
+% the \meta{token list variable} is local.
+% \end{function}
+%
+% \section{Modifying property lists}
+%
+% \begin{function}{\prop_del:Nn, \prop_del:NV, \prop_del:cn, \prop_del:cV}
+% \begin{syntax}
+% \cs{prop_del:Nn} \meta{property list} \Arg{key}
+% \end{syntax}
+% Deletes the entry listed under \meta{key} from the
+% \meta{property list} which may be accessed. If the \meta{key} is
+% not found in the \meta{property list} no change occurs,
+% \emph{i.e}~there is no need to test for the existence of a key before
+% deleting it. The deletion is restricted to the current \TeX{} group.
+% \end{function}
+%
+% \begin{function}{\prop_gdel:Nn, \prop_gdel:NV, \prop_gdel:cn, \prop_gdel:cV}
+% \begin{syntax}
+% \cs{prop_gdel:Nn} \meta{property list} \Arg{key}
+% \end{syntax}
+% Deletes the entry listed under \meta{key} from the
+% \meta{property list} which may be accessed. If the \meta{key} is
+% not found in the \meta{property list} no change occurs,
+% \emph{i.e}~there is no need to test for the existence of a key before
+% deleting it. The deletion is not restricted to the current \TeX{}
+% group: it is global.
+% \end{function}
+%
+% \section{Property list conditionals}
+%
+% \begin{function}[EXP,pTF]{\prop_if_empty:N, \prop_if_empty:c}
+% \begin{syntax}
+% \cs{prop_if_empty_p:N} \meta{property list}
+% \cs{prop_if_empty:NTF} \meta{property list}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{property list} is empty (containing no entries). The
+% branching versions then leave either \meta{true code} or
+% \meta{false code} in the input stream, as appropriate to the truth of
+% the test and the variant of the function chosen. The logical truth of
+% the test is left in the input stream by the predicate version.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{
+% \prop_if_in:Nn, \prop_if_in:NV, \prop_if_in:No,
+% \prop_if_in:cn, \prop_if_in:cV, \prop_if_in:co
+% }
+% \begin{syntax}
+% \cs{prop_if_in:NnTF} \meta{property list} \Arg{key}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{key} is present in the \meta{property list},
+% making the comparison using the method described by \cs{str_if_eq:nnTF}.
+% Either the \meta{true code} or \meta{false code} in the input stream, as
+% appropriate to the truth of the test and the variant of the function
+% chosen.
+% \begin{texnote}
+% This function iterates through every key--value pair in the
+% \meta{property list} and is therefore slower than using the
+% non-expandable \cs{prop_get:NnNTF}.
+% \end{texnote}
+% \end{function}
+%
+% \section{Mapping to property lists}
+%
+% \begin{function}[EXP]{\prop_map_function:NN, \prop_map_function:cN}
+% \begin{syntax}
+% \cs{prop_map_function:NN} \meta{property list} \meta{function}
+% \end{syntax}
+% Applies \meta{function} to every \meta{entry} stored in the
+% \meta{property list}. The \meta{function} will receive two argument for
+% each iteration.: the \meta{key} and associated \meta{value}.
+% The order in which \meta{entries} are returned is not defined and
+% should not be relied upon.
+% \end{function}
+%
+% \begin{function}{\prop_map_inline:Nn, \prop_map_inline:cn}
+% \begin{syntax}
+% \cs{prop_map_inline:Nn} \meta{property list} \Arg{inline function}
+% \end{syntax}
+% Applies \meta{inline function} to every \meta{entry} stored
+% within the \meta{property list}. The \meta{inline function} should
+% consist of code which will receive the \meta{key} as |#1| and the
+% \meta{value} as |#2|.
+% The order in which \meta{entries} are returned is not defined and
+% should not be relied upon.
+% \end{function}
+%
+% \begin{function}[EXP]{\prop_map_break:}
+% \begin{syntax}
+% \cs{prop_map_break:}
+% \end{syntax}
+% Used to terminate a \cs{prop_map_\ldots} function before all
+% entries in the \meta{property list} have been processed. This will
+% normally take place within a conditional statement, for example
+% \begin{verbatim}
+% \prop_map_inline:Nn \l_my_prop
+% {
+% \str_if_eq:nnTF { #1 } { bingo }
+% { \prop_map_break: }
+% {
+% % Do something useful
+% }
+% }
+% \end{verbatim}
+% Use outside of a \cs{prop_map_\ldots} scenario will lead low
+% level \TeX{} errors.
+% \end{function}
+%
+% \begin{function}[EXP]{\prop_map_break:n}
+% \begin{syntax}
+% \cs{prop_map_break:n} \Arg{tokens}
+% \end{syntax}
+% Used to terminate a \cs{prop_map_\ldots} function before all
+% entries in the \meta{property list} have been processed, inserting
+% the \meta{tokens} after the mapping has ended. This will
+% normally take place within a conditional statement, for example
+% \begin{verbatim}
+% \prop_map_inline:Nn \l_my_prop
+% {
+% \str_if_eq:nnTF { #1 } { bingo }
+% { \prop_map_break:n { <tokens> } }
+% {
+% % Do something useful
+% }
+% }
+% \end{verbatim}
+% Use outside of a \cs{prop_map_\ldots} scenario will lead low
+% level \TeX{} errors.
+% \end{function}
+%
+% \section{Viewing property lists}
+%
+% \begin{function}{\prop_show:N, \prop_show:c}
+% \begin{syntax}
+% \cs{prop_show:N} \meta{property list}
+% \end{syntax}
+% Displays the entries in the \meta{property list} in the terminal.
+% \end{function}
+%
+% \section{Experimental property list functions}
+%
+% This section contains functions which may or may not be retained, depending
+% on how useful they are found to be.
+%
+% \begin{function}[TF]{\prop_get:NnN}
+% \begin{syntax}
+% \cs{prop_get:NnNTF} \meta{property list} \Arg{key}
+% ~~\meta{token list variable} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% If the \meta{key} is not present in the \meta{property list}, leaves
+% the \meta{false code} in the input stream and leaves the
+% \meta{token list variable} unchanged. If the \meta{key} is present in
+% the \meta{property list}, stores the corresponding \meta{value}
+% in the \meta{token list variable} without removing it from the
+% \meta{property list}. The \meta{true code} is then left in the input
+% stream. The \meta{token list variable} is assigned locally.
+% \end{function}
+%
+% \begin{function}[TF]{\prop_pop:NnN}
+% \begin{syntax}
+% \cs{prop_pop:NnNTF} \meta{property list} \Arg{key}
+% ~~\meta{token list variable} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% If the \meta{key} is not present in the \meta{property list}, leaves
+% the \meta{false code} in the input stream and leaves the
+% \meta{token list variable} unchanged. If the \meta{key} is present in
+% the \meta{property list}, pops the corresponding \meta{value}
+% in the \meta{token list variable}, \emph{i.e.}~removes the item from
+% the \meta{property list}. The \meta{true code} is then left in the input
+% stream. Both the \meta{property list} and the \meta{token list variable}
+% are assigned locally.
+% \end{function}
+%
+% \begin{function}[TF]{\prop_gpop:NnN}
+% \begin{syntax}
+% \cs{prop_gpop:NnNTF} \meta{property list} \Arg{key}
+% ~~\meta{token list variable} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% If the \meta{key} is not present in the \meta{property list}, leaves
+% the \meta{false code} in the input stream and leaves the
+% \meta{token list variable} unchanged. If the \meta{key} is present in
+% the \meta{property list}, pops the corresponding \meta{value}
+% in the \meta{token list variable}, \emph{i.e.}~removes the item from
+% the \meta{property list}. The \meta{true code} is then left in the input
+% stream. The \meta{property list} is modified globally, while the
+% \meta{token list variable} is assigned locally.
+% \end{function}
+%
+% \begin{function}[EXP]{\prop_map_tokens:Nn}
+% \begin{syntax}
+% \cs{prop_map_tokens:Nn} \meta{property list} \Arg{code}
+% \end{syntax}
+% Analogue of \cs{prop_map_function:NN} which maps several tokens instead
+% of a single function. Useful in particular when mapping through a
+% property list while keeping track of a given key.
+% \end{function}
+%
+% \begin{function}[EXP]{\prop_get:Nn}
+% \begin{syntax}
+% \cs{prop_get:Nn} \meta{property list} \Arg{key}
+% \end{syntax}
+% Expands to the \meta{value} corresponding to the \meta{key} in
+% the \meta{property list}. If the \meta{key} is missing, this has
+% an empty expansion.
+% \begin{texnote}
+% This function is slower than the non-expandable analogue
+% \cs{prop_get:NnN}.
+% \end{texnote}
+% \end{function}
+%
+% \section{Internal property list functions}
+%
+% \begin{function}{\q_prop}
+% The internal token used to separate out property list entries, separating
+% both the \meta{key} from the \meta{value} and also one entry from another.
+% \end{function}
+%
+% \begin{function}{\c_empty_prop}
+% A permanently-empty property list used for internal comparisons.
+% \end{function}
+%
+% \begin{function}{\prop_split:Nnn}
+% \begin{syntax}
+% \cs{prop_spilt:Nnn} \meta{property list} \Arg{key} \Arg{code}
+% \end{syntax}
+% Splits the \meta{property list} at the \meta{key}, giving three
+% groups: the \meta{extract} of \meta{property list} before the
+% \meta{key}, the \meta{value} associated with the \meta{key} and the
+% \meta{extract} of the \meta{property list} after the \meta{value}.
+% The first \meta{extract} retains the internal structure of a property
+% list. The second is only missing the leading separator \cs{q_prop}.
+% This ensures that the concatenation of the two \meta{extracts} is a
+% property list.
+% If the \meta{key} is not present in the \meta{property list} then
+% the second group will contain the marker \cs{q_no_value} and the third
+% is empty.
+% Once the split has occurred, the \meta{code} is inserted followed by the
+% three groups: thus the \meta{code} should properly absorb three
+% arguments.
+% The \meta{key} comparison takes place as described for \cs{str_if_eq:nn}.
+% \end{function}
+%
+% \begin{function}{\prop_split:NnTF}
+% \begin{syntax}
+% \cs{prop_spilt:NnTF} \meta{property list} \Arg{key}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% Splits the \meta{property list} at the \meta{key}, giving three
+% groups: the \meta{extract} of \meta{property list} before the
+% \meta{key}, the \meta{value} associated with the \meta{key} and the
+% \meta{extract} of the \meta{property list} after the \meta{value}.
+% The first \meta{extract} retains the internal structure of a property
+% list. The second is only missing the leading separator \cs{q_prop}.
+% This ensures that the concatenation of the two \meta{extracts} is a
+% property list.
+% If the \meta{key} is present in the \meta{property list} then the
+% \meta{true code} is left in the input stream, followed by the three
+% groups: thus the \meta{true code} should properly absorb three arguments.
+% If the \meta{key} is not present in the \meta{property list} then
+% the \meta{false code} is left in the input stream, with no trailing
+% material.
+% The \meta{key} comparison takes place as described for \cs{str_if_eq:nn}.
+% \end{function}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3prop} implementation}
+%
+% \TestFiles{m3prop001}
+%
+% \begin{macrocode}
+%<*initex|package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*package>
+\ProvidesExplPackage
+ {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
+\package_check_loaded_expl:
+%</package>
+% \end{macrocode}
+%
+% A property list is a macro whose top-level expansion is for the form
+% \enquote{\cs{q_prop} \meta{key$_0$} \cs{q_prop} \Arg{value$_0$} \cs{q_prop}
+% \ldots \cs{q_prop} \meta{key$_{n-1}$} \cs{q_prop} \Arg{value$_{n-1}$}
+% \cs{q_prop}}.
+% The trailing \cs{q_prop} is always present for performance reasons: this
+% means that empty property lists are not actually empty.
+%
+% \begin{macro}[int]{\q_prop}
+% A private quark is used as a marker between entries.
+% \begin{macrocode}
+\quark_new:N \q_prop
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}{\c_empty_prop}
+% An empty prop contains exactly one \cs{q_prop}.
+% \begin{macrocode}
+\tl_const:Nn \c_empty_prop { \q_prop }
+% \end{macrocode}
+% \end{variable}
+%
+% \subsection{Allocation and initialisation}
+%
+% \begin{macro}{\prop_new:N,\prop_new:c}
+% Internally, property lists are token lists, but an empty prop
+% is not an empty tl, so we need to do things by hand.
+% \begin{macrocode}
+\cs_new_protected:Npn \prop_new:N #1 { \cs_new_eq:NN #1 \c_empty_prop }
+\cs_new_protected:Npn \prop_new:c #1 { \cs_new_eq:cN {#1} \c_empty_prop }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\prop_clear:N, \prop_clear:c}
+% \begin{macro}{\prop_gclear:N, \prop_gclear:c}
+% The same idea for clearing
+% \begin{macrocode}
+\cs_new_protected:Npn \prop_clear:N #1 { \cs_set_eq:NN #1 \c_empty_prop }
+\cs_new_protected:Npn \prop_clear:c #1 { \cs_set_eq:cN {#1} \c_empty_prop }
+\cs_new_protected:Npn \prop_gclear:N #1 { \cs_gset_eq:NN #1 \c_empty_prop }
+\cs_new_protected:Npn \prop_gclear:c #1 { \cs_gset_eq:cN {#1} \c_empty_prop }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\prop_clear_new:N, \prop_clear_new:c}
+% \begin{macro}{\prop_gclear_new:N, \prop_gclear_new:c}
+% Once again a simple copy from the token list functions.
+% \begin{macrocode}
+\cs_new_protected:Npn \prop_clear_new:N #1
+ { \cs_if_exist:NTF #1 { \prop_clear:N #1 } { \prop_new:N #1 } }
+\cs_generate_variant:Nn \prop_clear_new:N {c}
+\cs_new_protected:Npn \prop_gclear_new:N #1
+ { \cs_if_exist:NTF #1 { \prop_gclear:N #1 } { \prop_new:N #1 } }
+\cs_new_eq:NN \prop_gclear_new:c \prop_gclear:c
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {\prop_set_eq:NN, \prop_set_eq:cN, \prop_set_eq:Nc, \prop_set_eq:cc}
+% \begin{macro}
+% {\prop_gset_eq:NN, \prop_gset_eq:cN, \prop_gset_eq:Nc, \prop_gset_eq:cc}
+% Once again, these are simply copies from the token list functions.
+% \begin{macrocode}
+\cs_new_eq:NN \prop_set_eq:NN \tl_set_eq:NN
+\cs_new_eq:NN \prop_set_eq:Nc \tl_set_eq:Nc
+\cs_new_eq:NN \prop_set_eq:cN \tl_set_eq:cN
+\cs_new_eq:NN \prop_set_eq:cc \tl_set_eq:cc
+\cs_new_eq:NN \prop_gset_eq:NN \tl_gset_eq:NN
+\cs_new_eq:NN \prop_gset_eq:Nc \tl_gset_eq:Nc
+\cs_new_eq:NN \prop_gset_eq:cN \tl_gset_eq:cN
+\cs_new_eq:NN \prop_gset_eq:cc \tl_gset_eq:cc
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Accessing data in property lists}
+%
+% \begin{macro}[int]{\prop_split:NnTF}
+% \begin{macro}[aux]{\prop_split_aux:NnTF}
+% \begin{macro}[aux]{\prop_split_aux:nnnn}
+% \begin{macro}[aux]{\prop_split_aux:w}
+% This function is used by most of the module, and hence must be fast.
+% The aim here is to split a property list at a given key into the part
+% before the key--value pair, the value associated with the key and the part
+% after the key--value pair. To do this, the key is first detokenized (to
+% avoid repeatedly doing this), then a delimited function is constructed to
+% match the key. It will match \cs{q_prop} \meta{detokenized key} \cs{q_prop}
+% \marg{value} \meta{extra argument}, effectively separating an
+% \meta{extract1} before the key in the property list and an \meta{extract2}
+% after the key.
+%
+% If the key is present in the property list, then \meta{extra argument}
+% is simply \cs{q_prop}, and \cs{prop_splot_aux:nnnn} will gobble this
+% and the false branch (|#4|), leaving the correct code on the input
+% stream. More precisely, it leaves the user code (true branch), followed
+% by three groups, \Arg{extract1} \Arg{value} \Arg{extract2}.
+% In order for \meta{extract1}\meta{extract2} to be a well-formed
+% property list, \meta{extract1} has a leading and trailing \cs{q_prop},
+% retaining exactly the structure of a property list, while \meta{extract2}
+% omits the leading \cs{q_prop}.
+%
+% If the key is not there, then \meta{extra argument} is
+% |? \use_ii:nn { }|, and |\prop_split_aux:nnnn ? \use_ii:nn { }| removes
+% the three brace groups that just follow. Then \cs{use_ii:nn} removes
+% the true branch, leaving the false branch, with no trailing material.
+% \begin{macrocode}
+\cs_set_protected:Npn \prop_split:NnTF #1#2
+ { \exp_args:NNo \prop_split_aux:NnTF #1 { \tl_to_str:n {#2} } }
+\cs_new_protected:Npn \prop_split_aux:NnTF #1#2
+ {
+ \cs_set_protected:Npn \prop_split_aux:w
+ ##1 \q_prop #2 \q_prop ##2 ##3 ##4 \q_mark ##5 \q_stop
+ { \prop_split_aux:nnnn ##3 { {##1 \q_prop } {##2} {##4} } }
+ \exp_after:wN \prop_split_aux:w #1 \q_mark
+ \q_prop #2 \q_prop { } { ? \use_ii:nn { } } \q_mark \q_stop
+ }
+\cs_new:Npn \prop_split_aux:nnnn #1#2#3#4 { #3 #2 }
+\cs_new_protected:Npn \prop_split_aux:w { }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[int]{\prop_split:Nnn}
+% The goal here is to provide a common interface for both true and false
+% branches of \cs{prop_split:NnTF}. In both cases, the code given by the
+% user will be placed in front of three brace groups, \Arg{extract1}
+% \Arg{value} \Arg{extract2}.
+% If the key was missing from the property list, then \meta{extract1}
+% is the full property list, \meta{value} is \cs{q_no_value}, and
+% \meta{extract2} is empty.
+% Otherwise, \meta{extract1} is the part of the property list before the
+% \meta{key}, and has the structure of a property list, \meta{value} is
+% the value corresponding to the \meta{key}, and \meta{extract2} (the part
+% after the \meta{key}) is missing the leading \cs{q_prop}.
+% \begin{macrocode}
+\cs_set_protected:Npn \prop_split:Nnn #1#2#3
+ {
+ \prop_split:NnTF #1 {#2}
+ {#3}
+ { \exp_args:Nno \use:n {#3} {#1} { \q_no_value } { } }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\prop_del:Nn, \prop_del:NV, \prop_del:cn, \prop_del:cV}
+% \begin{macro}{\prop_gdel:Nn, \prop_gdel:NV, \prop_gdel:cn, \prop_gdel:cV}
+% \begin{macro}[aux]{\prop_del_aux:NNnnn}
+% Deleting from a property starts by splitting the list.
+% If the key is present in the property list, the returned value is ignored.
+% If the key is missing, nothing happens.
+% \begin{macrocode}
+\cs_new_protected:Npn \prop_del:Nn #1#2
+ { \prop_split:NnTF #1 {#2} { \prop_del_aux:NNnnn \tl_set:Nn #1 } { } }
+\cs_new_protected:Npn \prop_gdel:Nn #1#2
+ { \prop_split:NnTF #1 {#2} { \prop_del_aux:NNnnn \tl_gset:Nn #1 } { } }
+\cs_new_protected:Npn \prop_del_aux:NNnnn #1#2#3#4#5
+ { #1 #2 { #3 #5 } }
+\cs_generate_variant:Nn \prop_del:Nn { NV }
+\cs_generate_variant:Nn \prop_del:Nn { c , cV }
+\cs_generate_variant:Nn \prop_gdel:Nn { NV }
+\cs_generate_variant:Nn \prop_gdel:Nn { c , cV }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \prop_get:NnN, \prop_get:NVN, \prop_get:NoN,
+% \prop_get:cnN, \prop_get:cVN, \prop_get:NoN
+% }
+% \begin{macro}[aux]{\prop_get_aux:Nnnn}
+% Getting an item from a list is very easy: after splitting,
+% if the key is in the property list, just set the token list variable
+% to the return value, otherwise to \cs{q_no_value}.
+% \begin{macrocode}
+\cs_new_protected:Npn \prop_get:NnN #1#2#3
+ {
+ \prop_split:NnTF #1 {#2}
+ { \prop_get_aux:Nnnn #3 }
+ { \tl_set:Nn #3 { \q_no_value } }
+ }
+\cs_new_protected:Npn \prop_get_aux:Nnnn #1#2#3#4
+ { \tl_set:Nn #1 {#3} }
+\cs_generate_variant:Nn \prop_get:NnN { NV , No }
+\cs_generate_variant:Nn \prop_get:NnN { c , cV , co }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\prop_pop:NnN, \prop_pop:NoN, \prop_pop:cnN, \prop_pop:coN}
+% \begin{macro}{\prop_gpop:NnN, \prop_gpop:NoN, \prop_gpop:cnN, \prop_gpop:coN}
+% \begin{macro}[aux]{\prop_pop_aux:NNNnnn}
+% Popping a value also starts by doing the split.
+% If the key is present, save the value in the token list and update the
+% property list as when deleting.
+% If the key is missing, save \cs{q_no_value} in the token list.
+% \begin{macrocode}
+\cs_new_protected:Npn \prop_pop:NnN #1#2#3
+ {
+ \prop_split:NnTF #1 {#2}
+ { \prop_pop_aux:NNNnnn \tl_set:Nn #1 #3 }
+ { \tl_set:Nn #3 { \q_no_value } }
+ }
+\cs_new_protected:Npn \prop_gpop:NnN #1#2#3
+ {
+ \prop_split:NnTF #1 {#2}
+ { \prop_pop_aux:NNNnnn \tl_gset:Nn #1 #3 }
+ { \tl_set:Nn #3 { \q_no_value } }
+ }
+\cs_new_protected:Npn \prop_pop_aux:NNNnnn #1#2#3#4#5#6
+ {
+ \tl_set:Nn #3 {#5}
+ #1 #2 { #4 #6 }
+ }
+\cs_generate_variant:Nn \prop_pop:NnN { No }
+\cs_generate_variant:Nn \prop_pop:NnN { c , co }
+\cs_generate_variant:Nn \prop_gpop:NnN { No }
+\cs_generate_variant:Nn \prop_gpop:NnN { c , co }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \prop_put:Nnn, \prop_put:NnV, \prop_put:Nno, \prop_put:Nnx,
+% \prop_put:NVn, \prop_put:NVV, \prop_put:Non, \prop_put:Noo,
+% \prop_put:cnn, \prop_put:cnV, \prop_put:cno, \prop_put:cnx,
+% \prop_put:cVn, \prop_put:cVV, \prop_put:con, \prop_put:coo
+% }
+% \begin{macro}
+% {
+% \prop_gput:Nnn, \prop_gput:NnV, \prop_gput:Nno, \prop_gput:Nnx,
+% \prop_gput:NVn, \prop_gput:NVV, \prop_gput:Non, \prop_gput:Noo,
+% \prop_gput:cnn, \prop_gput:cnV, \prop_gput:cno, \prop_gput:cnx,
+% \prop_gput:cVn, \prop_gput:cVV, \prop_gput:con, \prop_gput:coo
+% }
+% \begin{macro}[aux]{\prop_put_aux:NNnnnnn}
+% Putting a key--value pair in a property list starts by splitting
+% to remove any existing value. The property list is then
+% reconstructed with the two remaining parts |#5| and |#7| first,
+% followed by the new or updated entry.
+% \begin{macrocode}
+\cs_new_protected:Npn \prop_put:Nnn { \prop_put_aux:NNnn \tl_set:Nx }
+\cs_new_protected:Npn \prop_gput:Nnn { \prop_put_aux:NNnn \tl_gset:Nx }
+\cs_new_protected:Npn \prop_put_aux:NNnn #1#2#3#4
+ {
+ \prop_split:Nnn #2 {#3} { \prop_put_aux:NNnnnnn #1 #2 {#3} {#4} }
+ }
+\cs_new_protected:Npn \prop_put_aux:NNnnnnn #1#2#3#4#5#6#7
+ {
+ #1 #2
+ {
+ \exp_not:n { #5 #7 }
+ \tl_to_str:n {#3} \exp_not:n { \q_prop {#4} \q_prop }
+ }
+ }
+\cs_generate_variant:Nn \prop_put:Nnn
+ { NnV , Nno , Nnx , NV , NVV , No , Noo }
+\cs_generate_variant:Nn \prop_put:Nnn
+ { c , cnV , cno , cnx , cV , cVV , co , coo }
+\cs_generate_variant:Nn \prop_gput:Nnn
+ { NnV , Nno , Nnx , NV , NVV , No , Noo }
+\cs_generate_variant:Nn \prop_gput:Nnn
+ { c , cnV , cno , cnx , cV , cVV , co , coo }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\prop_put_if_new:Nnn, \prop_put_if_new:cnn}
+% \begin{macro}{\prop_gput_if_new:Nnn, \prop_gput_if_new:cnn}
+% Adding conditionally also splits. If the key is already present,
+% the three brace groups given by \cs{prop_split:NnTF} are removed.
+% If the key is new, then the value is added, being careful to
+% convert the key to a string using \cs{tl_to_str:n}.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \prop_put_if_new:Nnn
+ { \prop_put_if_new_aux:NNnn \tl_put_right:Nx }
+\cs_new_protected_nopar:Npn \prop_gput_if_new:Nnn
+ { \prop_put_if_new_aux:NNnn \tl_gput_right:Nx }
+\cs_new_protected:Npn \prop_put_if_new_aux:NNnn #1#2#3#4
+ {
+ \prop_split:NnTF #2 {#3}
+ { \use_none:nnn }
+ {
+ #1 #2
+ { \tl_to_str:n {#3} \exp_not:n { \q_prop {#4} \q_prop } }
+ }
+ }
+\cs_generate_variant:Nn \prop_put_if_new:Nnn { c }
+\cs_generate_variant:Nn \prop_gput_if_new:Nnn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Property list conditionals}
+%
+% \begin{macro}[pTF]{\prop_if_empty:N, \prop_if_empty:c}
+% The test here uses \cs{c_empty_prop} as it is not really empty!
+% \begin{macrocode}
+\prg_new_conditional:Npnn \prop_if_empty:N #1 { p, T , F , TF }
+ {
+ \if_meaning:w #1 \c_empty_prop
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\cs_generate_variant:Nn \prop_if_empty_p:N {c}
+\cs_generate_variant:Nn \prop_if_empty:NTF {c}
+\cs_generate_variant:Nn \prop_if_empty:NT {c}
+\cs_generate_variant:Nn \prop_if_empty:NF {c}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]
+% {
+% \prop_if_in:Nn, \prop_if_in:NV, \prop_if_in:No,
+% \prop_if_in:cn, \prop_if_in:cV, \prop_if_in:co
+% }
+% \begin{macro}[aux]{\prop_if_in_aux:w}
+% Testing expandably if a key is in a property list
+% requires to go through the key--value pairs one by one.
+% This is rather slow, and a faster test would be
+% \begin{verbatim}
+% \prg_new_protected_conditional:Npnn \prop_if_in:Nn #1 #2
+% {
+% \prop_split:NnTF #1 {#2}
+% {
+% \prg_return_true:
+% \use_none:nnn
+% }
+% { \prg_return_false: }
+% }
+% \end{verbatim}
+% but \cs{prop_split:NnTF} is non-expandable.
+%
+% Instead, the key is compared to each key in turn using \cs{str_if_eq:nn},
+% which is expandable. The mapping is stopped using |A|, which cannot appear
+% within a key of the property list, since keys are strings.
+% Here, \cs{prop_map_function:NN} is not sufficient for the mapping,
+% since it can only map a single token, and cannot carry the key that
+% is searched for.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \prop_if_in:Nn #1#2 { p , T , F , TF }
+ {
+ \exp_last_unbraced:Noo \prop_if_in_aux:nwn
+ { \tl_to_str:n {#2} } #1
+ A \q_prop { } \q_stop
+ }
+\cs_new:Npn \prop_if_in_aux:nwn #1 \q_prop #2 \q_prop #3
+ {
+ \if_catcode:w A #2
+ \prg_return_false:
+ \exp_after:wN \use_none_delimit_by_q_stop:w
+ \fi:
+ \str_if_eq:nnT {#1} {#2}
+ {
+ \prg_return_true:
+ \use_none_delimit_by_q_stop:w
+ }
+ \prop_if_in_aux:nwn {#1}
+ }
+\cs_generate_variant:Nn \prop_if_in_p:Nn { NV , No }
+\cs_generate_variant:Nn \prop_if_in_p:Nn { c , cV , co }
+\cs_generate_variant:Nn \prop_if_in:NnT { NV , No }
+\cs_generate_variant:Nn \prop_if_in:NnT { c , cV , co }
+\cs_generate_variant:Nn \prop_if_in:NnF { NV , No }
+\cs_generate_variant:Nn \prop_if_in:NnF { c , cV , co }
+\cs_generate_variant:Nn \prop_if_in:NnTF { NV , No }
+\cs_generate_variant:Nn \prop_if_in:NnTF { c , cV , co }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Mapping to property lists}
+%
+% \begin{macro}
+% {
+% \prop_map_function:NN, \prop_map_function:Nc,
+% \prop_map_function:cN, \prop_map_function:cc
+% }
+% \begin{macro}[aux]{\prop_map_function_aux:Nwn}
+% The fastest way to do a recursion here is to use an
+% \cs{if_catcode:w} test: the keys are strings, and thus
+% cannot match the marker |A| (which has catcode \enquote{letter}).
+% \begin{macrocode}
+\cs_new_nopar:Npn \prop_map_function:NN #1#2
+ {
+ \exp_last_unbraced:NNo \prop_map_function_aux:Nwn #2
+ #1 A \q_prop { } \q_recursion_stop
+ }
+\cs_new:Npn \prop_map_function_aux:Nwn #1 \q_prop #2 \q_prop #3
+ {
+ \if_catcode:w A #2
+ \exp_after:wN \prop_map_break:
+ \fi:
+ #1 {#2} {#3}
+ \prop_map_function_aux:Nwn #1
+ }
+\cs_generate_variant:Nn \prop_map_function:NN { Nc }
+\cs_generate_variant:Nn \prop_map_function:NN { c , cc }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{variable}{\g_prop_map_inline_int}
+% A nesting counter for mapping.
+% \begin{macrocode}
+\int_new:N \g_prop_map_inline_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\prop_map_inline:Nn, \prop_map_inline:cn}
+% Mapping in line requires a nesting level counter.
+% \begin{macrocode}
+\cs_new_protected:Npn \prop_map_inline:Nn #1#2
+ {
+ \int_gincr:N \g_prop_map_inline_int
+ \cs_gset:cpn { prop_map_inline_ \int_use:N \g_prop_map_inline_int :nn }
+ ##1##2 {#2}
+ \prop_map_function:Nc #1
+ { prop_map_inline_ \int_use:N \g_prop_map_inline_int :nn }
+ \int_gdecr:N \g_prop_map_inline_int
+ }
+\cs_generate_variant:Nn \prop_map_inline:Nn { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\prop_map_break:}
+% Breaking the map function simply means removing everything up to
+% the \cs{q_stop} marker.
+% \begin{macrocode}
+\cs_new_eq:NN \prop_map_break: \use_none_delimit_by_q_recursion_stop:w
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\prop_map_break:n}
+% The same idea for using one set of tokens.
+% \begin{macrocode}
+\cs_new_eq:NN \prop_map_break:n \use_i_delimit_by_q_recursion_stop:nw
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Viewing property lists}
+%
+% \begin{variable}{\l_prop_show_tl}
+% Used to store the material for display.
+% \begin{macrocode}
+\tl_new:N \l_prop_show_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\prop_show:N, \prop_show:c}
+% \begin{macro}[aux]{\prop_show_aux:n}
+% \begin{macro}[aux]{\prop_show_aux:w}
+% The aim of the mapping here is to create a token list containing the
+% formatted property list. The very first item needs the new line and
+% \verb*|> | removing, which is achieved using a \texttt{w}-type auxiliary.
+% To avoid a low-level \TeX{} error if there is an empty property list, a
+% simple test is used to keep the output \enquote{clean}.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \prop_show:N #1
+ {
+ \prop_if_empty:NTF #1
+ {
+ \iow_term:x { Property~list~\token_to_str:N #1 \c_space_tl is~empty }
+ \tl_show:n { }
+ }
+ {
+ \iow_term:x
+ {
+ Property~list~\token_to_str:N #1 \c_space_tl
+ contains~the~pairs~(without~outer~braces):
+ }
+ \tl_set:Nx \l_prop_show_tl
+ { \prop_map_function:NN #1 \prop_show_aux:nn }
+ \tl_show:n \exp_after:wN \exp_after:wN \exp_after:wN
+ { \exp_after:wN \prop_show_aux:w \l_prop_show_tl }
+ }
+ }
+\cs_new:Npn \prop_show_aux:nn #1#2
+ {
+ \iow_newline: > \c_space_tl \c_space_tl
+ \iow_char:N \{ #1 \iow_char:N \}
+ \c_space_tl \c_space_tl => \c_space_tl \c_space_tl
+ \iow_char:N \{ \exp_not:n {#2} \iow_char:N \}
+ }
+\cs_new:Npn \prop_show_aux:w #1 > ~ { }
+\cs_generate_variant:Nn \prop_show:N { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Experimental functions}
+%
+% \begin{macro}[TF]{\prop_get:NnN}
+% \begin{macro}[aux]{\prop_get_aux_true:Nnnn}
+% Getting the value corresponding to a key, keeping track of whether
+% the key was present or not, is implemented as a conditional (with
+% side effects). If the key was absent, the token list is not altered.
+% \begin{macrocode}
+\prg_new_protected_conditional:Npnn \prop_get:NnN #1#2#3 { T , F , TF }
+ {
+ \prop_split:NnTF #1 {#2}
+ { \prop_get_aux_true:Nnnn #3 }
+ { \prg_return_false: }
+ }
+\cs_new_protected:Npn \prop_get_aux_true:Nnnn #1#2#3#4
+ {
+ \tl_set:Nn #1 {#3}
+ \prg_return_true:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[TF]{\prop_pop:NnN,\prop_gpop:NnN}
+% \begin{macro}[aux]{\prop_pop_aux_true:NNNnnn}
+% Popping an item from a property list, keeping track of whether
+% the key was present or not, is implemented as a conditional.
+% If the key was missing, neither the property list, nor the token
+% list are altered. Otherwise, \cs{prg_return_true:} is used after
+% the assignments.
+% \begin{macrocode}
+\prg_new_protected_conditional:Npnn \prop_pop:NnN #1#2#3 {T,F,TF}
+ {
+ \prop_split:NnTF #1 {#2}
+ { \prop_pop_aux_true:NNNnnn \tl_set:Nn #1 #3 }
+ { \prg_return_false: }
+ }
+\prg_new_protected_conditional:Npnn \prop_gpop:NnN #1#2#3 {T,F,TF}
+ {
+ \prop_split:NnTF #1 {#2}
+ { \prop_pop_aux_true:NNNnnn \tl_gset:Nn #1 #3 }
+ { \prg_return_false: }
+ }
+\cs_new_protected:Npn \prop_pop_aux_true:NNNnnn #1#2#3#4#5#6
+ {
+ \tl_set:Nn #3 {#5}
+ #1 #2 { #4 #6 }
+ \prg_return_true:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\prop_map_tokens:Nn}
+% \begin{macro}[aux]{\prop_map_tokens_aux:nwn}
+% The mapping grabs one key--value pair at a time, and stops when
+% reaching the marker key |A|, with catcode \enquote{letter}, which
+% cannot appear in normal keys since those are strings. The odd
+% construction |\use:n {#1}| allows |#1| to contain any token.
+% \begin{macrocode}
+\cs_new:Npn \prop_map_tokens:Nn #1#2
+ {
+ \exp_last_unbraced:Nno \prop_map_tokens_aux:nwn {#2} #1
+ A \q_prop { } \q_recursion_stop
+ }
+\cs_new:Npn \prop_map_tokens_aux:nwn #1 \q_prop #2 \q_prop #3
+ {
+ \if_catcode:w A #2
+ \exp_after:wN \prop_map_break:
+ \fi:
+ \use:n {#1} {#2} {#3}
+ \prop_map_tokens_aux:nwn {#1}
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\prop_get:Nn}
+% \begin{macro}[aux]{\prop_get_aux:nnn}
+% Getting expandably the value corresponding to a key in a property list
+% is a simple instance of mapping some tokens.
+% Map the function \cs{prop_get_aux:nnn} which takes as its three
+% arguments the \meta{key} that we are looking for, the current
+% \meta{key} and the current \meta{value}. If the \meta{keys} match,
+% the \meta{value} is returned. If none of the keys match, this expands
+% to nothing.
+% \begin{macrocode}
+\cs_new:Npn \prop_get:Nn #1 #2
+ { \prop_map_tokens:Nn #1 { \prop_get_aux:nnn {#2} } }
+\cs_new:Npn \prop_get_aux:nnn #1 #2 #3
+ { \str_if_eq:nnT {#1} {#2} { \prop_map_break:n {#3} } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Deprecated interfaces}
+%
+% Deprecated on 2011-05-27, for removal by 2011-08-31.
+%
+% \begin{macro}{\prop_display:N, \prop_display:c}
+% An older name for \cs{prop_show:N}.
+% \begin{macrocode}
+\cs_new_eq:NN \prop_display:N \prop_show:N
+\cs_new_eq:NN \prop_display:c \prop_show:c
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\prop_gget:NnN, \prop_gget:NVN, \prop_gget:cnN, \prop_gget:cVN}
+% \begin{macro}[aux]{\prop_gget_aux:Nnnn}
+% Getting globally is no longer supported: this is a conceptual change, so
+% the necessary code for the transition is provided directly.
+% \begin{macrocode}
+\cs_new_protected:Npn \prop_gget:NnN #1#2#3
+ { \prop_split:Nnn #1 {#2} { \prop_gget_aux:Nnnn #3 } }
+\cs_new_protected:Npn \prop_gget_aux:Nnnn #1#2#3#4
+ { \tl_gset:Nn #1 {#3} }
+\cs_generate_variant:Nn \prop_gget:NnN { NV }
+\cs_generate_variant:Nn \prop_gget:NnN { c , cV }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\prop_get_gdel:NnN}
+% This name seems very odd.
+% \begin{macrocode}
+\cs_new_eq:NN \prop_get_gdel:NnN \prop_gpop:NnN
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[TF]{\prop_if_in:cc}
+% A hang-over from an ancient implementation
+% \begin{macrocode}
+\cs_generate_variant:Nn \prop_if_in:NnT { cc }
+\cs_generate_variant:Nn \prop_if_in:NnF { cc }
+\cs_generate_variant:Nn \prop_if_in:NnTF { cc }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\prop_gput:ccx}
+% Another one.
+% \begin{macrocode}
+\cs_generate_variant:Nn \prop_gput:Nnn { ccx }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]
+% {\prop_if_eq:NN, \prop_if_eq:Nc, \prop_if_eq:cN, \prop_if_eq:cc}
+% These ones do no even make sense!
+% \begin{macrocode}
+\prg_new_eq_conditional:NNn \prop_if_eq:NN \tl_if_eq:NN { p , T , F , TF }
+\prg_new_eq_conditional:NNn \prop_if_eq:cN \tl_if_eq:cN { p , T , F , TF }
+\prg_new_eq_conditional:NNn \prop_if_eq:Nc \tl_if_eq:Nc { p , T , F , TF }
+\prg_new_eq_conditional:NNn \prop_if_eq:cc \tl_if_eq:cc { p , T , F , TF }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</initex|package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex \ No newline at end of file
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3quark.dtx b/Master/texmf-dist/source/latex/l3kernel/l3quark.dtx
new file mode 100644
index 00000000000..2326fd4519d
--- /dev/null
+++ b/Master/texmf-dist/source/latex/l3kernel/l3quark.dtx
@@ -0,0 +1,486 @@
+% \iffalse meta-comment
+%
+%% File: l3quark.dtx Copyright (C) 1990-2011 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 "expl3 bundle" (The Work in LPPL)
+%% and all files in that bundle must be distributed together.
+%%
+%% The released version of this bundle is available from CTAN.
+%%
+%% -----------------------------------------------------------------------
+%%
+%% The development version of the bundle can be found at
+%%
+%% http://www.latex-project.org/svnroot/experimental/trunk/
+%%
+%% for those people who are interested.
+%%
+%%%%%%%%%%%
+%% NOTE: %%
+%%%%%%%%%%%
+%%
+%% Snapshots taken from the repository represent work in progress and may
+%% not work or may contain conflicting material! We therefore ask
+%% people _not_ to put them into distributions, archives, etc. without
+%% prior consultation with the LaTeX3 Project.
+%%
+%% -----------------------------------------------------------------------
+%
+%<*driver|package>
+\RequirePackage{l3names}
+\GetIdInfo$Id: l3quark.dtx 2478 2011-06-19 21:34:23Z joseph $
+ {L3 Experimental quarks}
+%</driver|package>
+%<*driver>
+\documentclass[full]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3quark} package\\ Quarks^^A
+% \thanks{This file describes v\ExplFileVersion,
+% last revised \ExplFileDate.}^^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 \ExplFileDate}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% A special type of constants in \LaTeX3 are \enquote{quarks}. These are
+% control
+% sequences that expand to themselves and should therefore \emph{never} be
+% executed directly in the code. This would result in an endless loop!
+%
+% They are meant to be used as delimiter is weird functions (for
+% example as the stop token (\emph{i.e.}~\cs{q_stop}). They also permit the
+% following ingenious trick: when you pick up a token in a temporary,
+% and you want to know whether you have picked up a particular quark,
+% all you have to do is compare the temporary to the quark using
+% \cs{if_meaning:w}. A set of special quark testing functions is set up
+% below. All the quark testing functions are expandable although the
+% ones testing only single tokens are much faster.
+%
+% By convention all constants of type quark start out with |\q_|.
+%
+% \section{Defining quarks}
+%
+% \begin{function}{\quark_new:N}
+% \begin{syntax}
+% \cs{quark_new:N} \meta{quark}
+% \end{syntax}
+% Creates a new \meta{quark} which expands only to \meta{quark}.
+% The \meta{quark} will be defined globally, and an error message
+% will be raised if the name was already taken.
+% \end{function}
+%
+% \begin{variable}{\q_stop}
+% Used as a marker for delimited arguments, such as
+% \begin{verbatim}
+% \cs_set:Npn \tmp:w #1#2 \q_stop {#1}
+% \end{verbatim}
+% \end{variable}
+%
+% \begin{variable}{\q_mark}
+% Used as a marker for delimited arguments when \cs{q_stop} is
+% already in use.
+% \end{variable}
+%
+% \begin{variable}{\q_nil}
+% Quark to mark a null value in structured variables or functions. Used
+% as an end delimiter when this may itself may need to be tested
+% (in contrast to \cs{q_stop}, which is only ever used as a delimiter).
+% \end{variable}
+%
+% \begin{variable}{\q_no_value}
+% A canonical value for a missing value, when one is requested from
+% a data structure. This is therefore used as a \enquote{return} value
+% by functions such as \cs{prop_get:NnN} if there is no data to
+% return.
+% \end{variable}
+%
+% \section{Quark tests}
+%
+% The method used to define quarks means that the single token (\texttt{N})
+% tests are faster than the multi-token (\texttt{n}) tests. The later
+% should therefore only be used when the argument can definitely take
+% more than a single token.
+%
+% \begin{function}[EXP,pTF]{\quark_if_nil:N}
+% \begin{syntax}
+% \cs{quark_if_nil_p:N} \meta{token}
+% \cs{quark_if_nil:NTF} \meta{token} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{token} is equal to \cs{q_nil}. The branching
+% versions then leave either \meta{true code} or \meta{false code} in
+% the input stream, as appropriate to the truth of the test and the
+% variant of the function chosen. The logical truth of the test is
+% left in the input stream by the predicate version.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\quark_if_nil:n, \quark_if_nil:o, \quark_if_nil:V}
+% \begin{syntax}
+% \cs{quark_if_nil_p:n} \Arg{token list}
+% \cs{quark_if_nil:nTF} \Arg{token list} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{token list} contains only \cs{q_nil} (distinct
+% from \meta{token list} being empty or containing \cs{q_nil} plus one
+% or more other tokens). The branching versions then leave either
+% \meta{true code} or \meta{false code} in the input stream, as
+% appropriate to the truth of the test and the variant of the
+% function chosen. The logical truth of the test is left in the input
+% stream by the predicate version.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\quark_if_no_value:N, \quark_if_no_value:c}
+% \begin{syntax}
+% \cs{quark_if_no_value_p:N} \meta{token}
+% \cs{quark_if_no_value:NTF} \meta{token} \Arg{true code}
+% ~~\Arg{false code}
+% \end{syntax}
+% Tests if the \meta{token} is equal to \cs{q_no_value}. The branching
+% versions then leave either \meta{true code} or \meta{false code} in
+% the input stream, as appropriate to the truth of the test and the
+% variant of the function chosen. The logical truth of the test is
+% left in the input stream by the predicate version.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\quark_if_no_value:n}
+% \begin{syntax}
+% \cs{quark_if_no_value_p:n} \Arg{token list}
+% \cs{quark_if_no_value:nTF} \Arg{token list} \Arg{true code}
+% ~~\Arg{false code}
+% \end{syntax}
+% Tests if the \meta{token list} contains only \cs{q_no_value}
+% (distinct from \meta{token list} being empty or containing
+% \cs{q_no_value} plus one or more other tokens). The branching
+% versions then leave either \meta{true code} or \meta{false code} in
+% the input stream, as appropriate to the truth of the test and the
+% variant of the function chosen. The logical truth of the test is
+% left in the input stream by the predicate version.
+% \end{function}
+%
+% \section{Recursion}
+%
+% This module provides a uniform interface to intercepting and
+% terminating loops as when one is doing tail recursion. The building
+% blocks follow below.
+%
+% \begin{variable}{\q_recursion_tail}
+% This quark is appended to the data structure in question and
+% appears as a real element there. This means it gets any list
+% separators around it.
+% \end{variable}
+%
+% \begin{variable}{\q_recursion_stop}
+% This quark is added \emph{after} the data structure. Its purpose
+% is to make it possible to terminate the recursion at any point
+% easily.
+% \end{variable}
+%
+% \begin{function}{\quark_if_recursion_tail_stop:N}
+% \begin{syntax}
+% \cs{quark_if_recursion_tail_stop:N} \Arg{token}
+% \end{syntax}
+% Tests if \meta{token} contains only the marker
+% \cs{q_recursion_tail}, and if so terminates the recursion this is
+% part of using \cs{use_none_delimit_by_q_recursion_stop:w}. The
+% recursion input must include the marker tokens \cs{q_recursion_tail}
+% and \cs{q_recursion_stop} as the last two items.
+% \end{function}
+%
+% \begin{function}
+% {\quark_if_recursion_tail_stop:n, \quark_if_recursion_tail_stop:o}
+% \begin{syntax}
+% \cs{quark_if_recursion_tail_stop:n} \Arg{tokens}
+% \end{syntax}
+% Tests if \meta{tokens} consists of the single token
+% \cs{q_recursion_tail}, and if so terminates the recursion this is
+% part of using \cs{use_none_delimit_by_q_recursion_stop:w}. The
+% recursion input must include the marker tokens \cs{q_recursion_tail}
+% and \cs{q_recursion_stop} as the last two items.
+% \end{function}
+%
+% \begin{function}{\quark_if_recursion_tail_stop_do:Nn}
+% \begin{syntax}
+% \cs{quark_if_recursion_tail_stop_do:nn} \Arg{token} \Arg{insertion}
+% \end{syntax}
+% Tests if \meta{token} contains only the marker
+% \cs{q_recursion_tail}, and if so terminates the recursion this is
+% part of using \cs{use_none_delimit_by_q_recursion_stop:w}. The
+% recursion input must include the marker tokens \cs{q_recursion_tail}
+% and \cs{q_recursion_stop} as the last two items. The \meta{insertion}
+% code is then added to the input stream after the recursion has
+% ended.
+% \end{function}
+%
+% \begin{function}
+% {\quark_if_recursion_tail_stop_do:nn, \quark_if_recursion_tail_stop_do:on}
+% \begin{syntax}
+% \cs{quark_if_recursion_tail_stop_do:nn} \Arg{tokens} \Arg{insertion}
+% \end{syntax}
+% Tests if \meta{tokens} consists of the single token
+% \cs{q_recursion_tail}, and if so terminates the recursion this is
+% part of using \cs{use_none_delimit_by_q_recursion_stop:w}. The
+% recursion input must include the marker tokens \cs{q_recursion_tail}
+% and \cs{q_recursion_stop} as the last two items. The \meta{insertion}
+% code is then added to the input stream after the recursion has
+% ended.
+% \end{function}
+%
+% \section{Internal quark functions}
+%
+% \begin{function}{\use_none_delimit_by_q_recursion_stop:w}
+% \begin{syntax}
+% \cs{use_none_delimit_by_q_recursion_stop:w}
+% ~~\meta{tokens} \cs{q_recursion_stop}
+% \end{syntax}
+% Used to prematurely terminate a recursion using \cs{q_recursion_stop}
+% as the end marker, removing any remaining \meta{tokens} from the
+% input stream.
+% \end{function}
+%
+% \begin{function}{\use_i_delimit_by_q_recursion_stop:nw}
+% \begin{syntax}
+% \cs{use_i_delimit_by_q_recursion_stop:nw} \Arg{insertion}
+% ~~\meta{tokens} \cs{q_recursion_stop}
+% \end{syntax}
+% Used to prematurely terminate a recursion using \cs{q_recursion_stop}
+% as the end marker, removing any remaining \meta{tokens} from the
+% input stream. The \meta{insertion} is then made into the input
+% stream after the end of the recursion.
+% \end{function}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3quark} implementation}
+%
+% \TestFiles{m3quark001.lvt}
+%
+% \begin{macrocode}
+%<*initex|package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*package>
+\ProvidesExplPackage
+ {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
+\package_check_loaded_expl:
+%</package>
+% \end{macrocode}
+%
+% \begin{macro}{\quark_new:N}
+% \UnitTested
+% Allocate a new quark.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \quark_new:N #1 { \tl_const:Nn #1 {#1} }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}{\q_nil, \q_mark, \q_no_value, \q_stop}
+% Some \enquote{public} quarks. \cs{q_stop} is an \enquote{end of
+% argument} marker, \cs{q_nil} is a empty value and \cs{q_no_value}
+% marks an empty argument.
+% \begin{macrocode}
+\quark_new:N \q_nil
+\quark_new:N \q_mark
+\quark_new:N \q_no_value
+\quark_new:N \q_stop
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\q_recursion_tail,\q_recursion_stop}
+% Quarks for ending recursions. Only ever used there!
+% \cs{q_recursion_tail} is appended to whatever list structure we are
+% doing recursion on, meaning it is added as a proper list item with
+% whatever list separator is in use. \cs{q_recursion_stop} is placed
+% directly after the list.
+% \begin{macrocode}
+\quark_new:N \q_recursion_tail
+\quark_new:N \q_recursion_stop
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\quark_if_recursion_tail_stop:N}
+% \UnitTested
+% \begin{macro}{\quark_if_recursion_tail_stop_do:Nn}
+% \UnitTested
+% When doing recursions, it is easy to spend a lot of time testing if the
+% end marker has been found. To avoid this, a dedicated end marker is used
+% each time a recursion is set up. Thus if the marker is found everything
+% can be wrapper up and finished off. The simple case is when the test
+% can guarantee that only a single token is being tested. In this case,
+% there is just a dedicated copy of the standard quark test. Both a gobbling
+% version and one inserting end code are provided.
+% \begin{macrocode}
+\cs_new:Npn \quark_if_recursion_tail_stop:N #1
+ {
+ \if_meaning:w #1 \q_recursion_tail
+ \exp_after:wN \use_none_delimit_by_q_recursion_stop:w
+ \fi:
+ }
+\cs_new:Npn \quark_if_recursion_tail_stop_do:Nn #1#2
+ {
+ \if_meaning:w #1 \q_recursion_tail
+ \exp_after:wN \use_i_delimit_by_q_recursion_stop:nw
+ \else:
+ \exp_after:wN \use_none:n
+ \fi:
+ {#2}
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {\quark_if_recursion_tail_stop:n,\quark_if_recursion_tail_stop:o}
+% \UnitTested
+% \begin{macro}
+% {\quark_if_recursion_tail_stop_do:nn,\quark_if_recursion_tail_stop_do:on}
+% \UnitTested
+% \begin{macro}[aux]{\quark_if_recursion_tail_aux:w}
+% The same idea applies when testing multiple tokens, but here a little more
+% care is needed. It is possible that |#1| might be something like
+% |{{{a}}}| or |{ab\iffalse}\fi|, which will therefore need to be tested
+% in a detokenized manner. The way that this is done is using
+% \cs{if_catcode:w}, with the idea being that this test will be \texttt{true}
+% provided the auxiliary function returns nothing at all. If the auxiliary
+% returns anything, it will be detokenized and so the test will be both
+% \texttt{false} and safe.
+% \begin{macrocode}
+\cs_new:Npn \quark_if_recursion_tail_stop:n #1
+ {
+ \if_catcode:w
+ A
+ \etex_detokenize:D \exp_after:wN
+ {
+ \quark_if_recursion_tail_aux:w #1 \q_recursion_stop
+ \q_recursion_tail \q_recursion_stop \q_stop
+ }
+ A
+ \exp_after:wN \use_none_delimit_by_q_recursion_stop:w
+ \fi:
+ }
+\cs_new:Npn \quark_if_recursion_tail_stop_do:nn #1#2
+ {
+ \if_catcode:w
+ A
+ \etex_detokenize:D \exp_after:wN
+ {
+ \quark_if_recursion_tail_aux:w #1 \q_recursion_stop
+ \q_recursion_tail \q_recursion_stop \q_stop
+ }
+ A
+ \exp_after:wN \use_i_delimit_by_q_recursion_stop:nw
+ \else:
+ \exp_after:wN \use_none:n
+ \fi:
+ {#2}
+ }
+\cs_new:Npn \quark_if_recursion_tail_aux:w
+ #1 \q_recursion_tail #2 \q_recursion_stop #3 \q_stop
+ { #1 #2 }
+\cs_generate_variant:Nn \quark_if_recursion_tail_stop:n { o }
+\cs_generate_variant:Nn \quark_if_recursion_tail_stop_do:nn { o }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\quark_if_nil:N}
+% \UnitTested
+% \begin{macro}[pTF]{\quark_if_no_value:N., \quark_if_no_value:c}
+% \UnitTested
+% Here we test if we found a special quark as the first argument.
+% We better start with \cs{q_no_value} as the first argument since
+% the whole thing may otherwise loop if |#1| is wrongly given
+% a string like |aabc| instead of a single token.\footnote{It may
+% still loop in special circumstances however!}
+% \begin{macrocode}
+\prg_new_conditional:Nnn \quark_if_nil:N { p, T , F , TF }
+ {
+ \if_meaning:w \q_nil #1
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\prg_new_conditional:Nnn \quark_if_no_value:N { p, T , F , TF }
+ {
+ \if_meaning:w \q_no_value #1
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\cs_generate_variant:Nn \quark_if_no_value_p:N { c }
+\cs_generate_variant:Nn \quark_if_no_value:NT { c }
+\cs_generate_variant:Nn \quark_if_no_value:NF { c }
+\cs_generate_variant:Nn \quark_if_no_value:NTF { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\quark_if_nil:n, \quark_if_nil:V, \quark_if_nil:o}
+% \UnitTested
+% \begin{macro}[pTF]{\quark_if_no_value:n}
+% \UnitTested
+% These are essentially \cs{str_if_eq:nn} tests but done directly.
+% \begin{macrocode}
+\prg_new_conditional:Nnn \quark_if_nil:n { p, T , F , TF }
+ {
+ \if_int_compare:w \pdftex_strcmp:D
+ { \exp_not:N \q_nil } { \exp_not:n {#1} } = \c_zero
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\prg_new_conditional:Nnn \quark_if_no_value:n { p, T , F , TF }
+ {
+ \if_int_compare:w \pdftex_strcmp:D
+ { \exp_not:N \q_no_value } { \exp_not:n {#1} } = \c_zero
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\cs_generate_variant:Nn \quark_if_nil_p:n { V , o }
+\cs_generate_variant:Nn \quark_if_nil:nTF { V , o }
+\cs_generate_variant:Nn \quark_if_nil:nT { V , o }
+\cs_generate_variant:Nn \quark_if_nil:nF { V , o }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macrocode}
+%</initex|package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
+%
+% \endinput
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx b/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx
new file mode 100644
index 00000000000..088165a02fc
--- /dev/null
+++ b/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx
@@ -0,0 +1,1812 @@
+% \iffalse meta-comment
+%
+%% File: l3seq.dtx Copyright (C) 1990-2011 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 "expl3 bundle" (The Work in LPPL)
+%% and all files in that bundle must be distributed together.
+%%
+%% The released version of this bundle is available from CTAN.
+%%
+%% -----------------------------------------------------------------------
+%%
+%% The development version of the bundle can be found at
+%%
+%% http://www.latex-project.org/svnroot/experimental/trunk/
+%%
+%% for those people who are interested.
+%%
+%%%%%%%%%%%
+%% NOTE: %%
+%%%%%%%%%%%
+%%
+%% Snapshots taken from the repository represent work in progress and may
+%% not work or may contain conflicting material! We therefore ask
+%% people _not_ to put them into distributions, archives, etc. without
+%% prior consultation with the LaTeX3 Project.
+%%
+%% -----------------------------------------------------------------------
+%
+%<*driver|package>
+\RequirePackage{l3names}
+\GetIdInfo$Id: l3seq.dtx 2478 2011-06-19 21:34:23Z joseph $
+ {L3 Experimental sequences and stacks}
+%</driver|package>
+%<*driver>
+\documentclass[full]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3seq} package\\ Sequences and stacks^^A
+% \thanks{This file describes v\ExplFileVersion,
+% last revised \ExplFileDate.}^^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 \ExplFileDate}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% \LaTeX3 implements a \enquote{sequence} data type, which contain
+% an ordered list of entries which may contain any \meta{balanced text}.
+% It is possible to map functions to sequences such that the function
+% is applied to every item in the sequence.
+%
+% Sequences are also used to implement stack functions in \LaTeX3. This
+% is achieved using a number of dedicated stack functions.
+%
+% \section{Creating and initialising sequences}
+%
+% \begin{function}{\seq_new:N, \seq_new:c}
+% \begin{syntax}
+% \cs{seq_new:N} \meta{sequence}
+% \end{syntax}
+% Creates a new \meta{sequence} or raises an error if the name is
+% already taken. The declaration is global. The \meta{sequence} will
+% initially contain no items.
+% \end{function}
+%
+% \begin{function}{\seq_clear:N, \seq_clear:c}
+% \begin{syntax}
+% \cs{seq_clear:N} \meta{sequence}
+% \end{syntax}
+% Clears all items from the \meta{sequence} within the scope of
+% the current \TeX{} group.
+% \end{function}
+%
+% \begin{function}{\seq_gclear:N, \seq_gclear:c}
+% \begin{syntax}
+% \cs{seq_gclear:N} \meta{sequence}
+% \end{syntax}
+% Clears all entries from the \meta{sequence} globally.
+% \end{function}
+%
+% \begin{function}{\seq_clear_new:N, \seq_clear_new:c}
+% \begin{syntax}
+% \cs{seq_clear_new:N} \meta{sequence}
+% \end{syntax}
+% If the \meta{sequence} already exists, clears it within the scope
+% of the current \TeX{} group. If the \meta{sequence} is not defined,
+% it will be created (using \cs{seq_new:N}). Thus the sequence is
+% guaranteed to be available and clear within the current \TeX{}
+% group. The \meta{sequence} will exist globally, but the content
+% outside of the current \TeX{} group is not specified.
+% \end{function}
+%
+% \begin{function}{\seq_gclear_new:N, \seq_gclear_new:c}
+% \begin{syntax}
+% \cs{seq_gclear_new:N} \meta{sequence}
+% \end{syntax}
+% If the \meta{sequence} already exists, clears it globally. If the
+% \meta{sequence} is not defined, it will be created (using
+% \cs{seq_new:N}). Thus the sequence is guaranteed to be available
+% and globally clear.
+% \end{function}
+%
+% \begin{function}
+% {\seq_set_eq:NN, \seq_set_eq:cN, \seq_set_eq:Nc, \seq_set_eq:cc}
+% \begin{syntax}
+% \cs{seq_set_eq:NN} \meta{sequence1} \meta{sequence2}
+% \end{syntax}
+% Sets the content of \meta{sequence1} equal to that of
+% \meta{sequence2}. This assignment is restricted to the current
+% \TeX{} group level.
+% \end{function}
+%
+% \begin{function}
+% {\seq_gset_eq:NN, \seq_gset_eq:cN, \seq_gset_eq:Nc, \seq_gset_eq:cc}
+% \begin{syntax}
+% \cs{seq_gset_eq:NN} \meta{sequence1} \meta{sequence2}
+% \end{syntax}
+% Sets the content of \meta{sequence1} equal to that of
+% \meta{sequence2}. This assignment is global and so is not
+% limited by the current \TeX{} group level.
+% \end{function}
+%
+% \begin{function}{\seq_concat:NNN, \seq_concat:ccc}
+% \begin{syntax}
+% \cs{seq_concat:NNN} \meta{sequence1} \meta{sequence2} \meta{sequence3}
+% \end{syntax}
+% Concatenates the content of \meta{sequence2} and \meta{sequence3}
+% together and saves the result in \meta{sequence1}. The items in
+% \meta{sequence2} will be placed at the left side of the new sequence.
+% This operation is local to the current \TeX{} group and will
+% remove any existing content in \meta{sequence1}.
+% \end{function}
+%
+% \begin{function}{\seq_gconcat:NNN, \seq_gconcat:ccc}
+% \begin{syntax}
+% \cs{seq_gconcat:NNN} \meta{sequence1} \meta{sequence2} \meta{sequence3}
+% \end{syntax}
+% Concatenates the content of \meta{sequence2} and \meta{sequence3}
+% together and saves the result in \meta{sequence1}. The items in
+% \meta{sequence2} will be placed at the left side of the new sequence.
+% This operation is global and will remove any existing content in
+% \meta{sequence1}.
+% \end{function}
+%
+% \section{Appending data to sequences}
+%
+% \begin{function}{
+% \seq_put_left:Nn, \seq_put_left:NV, \seq_put_left:Nv,
+% \seq_put_left:No, \seq_put_left:Nx,
+% \seq_put_left:cn, \seq_put_left:cV, \seq_put_left:cv,
+% \seq_put_left:co, \seq_put_left:cx
+% }
+% \begin{syntax}
+% \cs{seq_put_left:Nn} \meta{sequence} \Arg{item}
+% \end{syntax}
+% Appends the \meta{item} to the left of the \meta{sequence}.
+% The assignment is restricted to the current \TeX{} group.
+% \end{function}
+%
+% \begin{function}{
+% \seq_gput_left:Nn, \seq_gput_left:NV, \seq_gput_left:Nv,
+% \seq_gput_left:No, \seq_gput_left:Nx,
+% \seq_gput_left:cn, \seq_gput_left:cV, \seq_gput_left:cv,
+% \seq_gput_left:co, \seq_gput_left:cx
+% }
+% \begin{syntax}
+% \cs{seq_gput_left:Nn} \meta{sequence} \Arg{item}
+% \end{syntax}
+% Appends the \meta{item} to the left of the \meta{sequence}.
+% The assignment is global.
+% \end{function}
+%
+% \begin{function}{
+% \seq_put_right:Nn, \seq_put_right:NV, \seq_put_right:Nv,
+% \seq_put_right:No, \seq_put_right:Nx,
+% \seq_put_right:cn, \seq_put_right:cV, \seq_put_right:cv,
+% \seq_put_right:co, \seq_put_right:cx
+% }
+% \begin{syntax}
+% \cs{seq_put_right:Nn} \meta{sequence} \Arg{item}
+% \end{syntax}
+% Appends the \meta{item} to the right of the \meta{sequence}.
+% The assignment is restricted to the current \TeX{} group.
+% \end{function}
+%
+% \begin{function}{
+% \seq_gput_right:Nn, \seq_gput_right:NV, \seq_gput_right:Nv,
+% \seq_gput_right:No, \seq_gput_right:Nx,
+% \seq_gput_right:cn, \seq_gput_right:cV, \seq_gput_right:cv,
+% \seq_gput_right:co, \seq_gput_right:cx
+% }
+% \begin{syntax}
+% \cs{seq_gput_right:Nn} \meta{sequence} \Arg{item}
+% \end{syntax}
+% Appends the \meta{item} to the right of the \meta{sequence}.
+% The assignment is global.
+% \end{function}
+%
+% \section{Recovering items from sequences}
+%
+% Items can be recovered from either the left or the right of sequences.
+% For implementation reasons, the actions at the left of the sequence are
+% faster than those acting on the right. These functions all assign the
+% recovered material locally, \emph{i.e.}~setting the
+% \meta{token list variable} used with \cs{tl_set:Nn} and \emph{never}
+% \cs{tl_gset:Nn}.
+%
+% \begin{function}{\seq_get_left:NN, \seq_get_left:cN}
+% \begin{syntax}
+% \cs{seq_get_left:NN} \meta{sequence} \meta{token list variable}
+% \end{syntax}
+% Stores the left-most item from a \meta{sequence} in the
+% \meta{token list variable} without removing it from the
+% \meta{sequence}. The \meta{token list variable} is assigned locally.
+% If \meta{sequence} is empty an error will be raised.
+% \end{function}
+%
+% \begin{function}{\seq_get_right:NN, \seq_get_right:cN}
+% \begin{syntax}
+% \cs{seq_get_right:NN} \meta{sequence} \meta{token list variable}
+% \end{syntax}
+% Stores the right-most item from a \meta{sequence} in the
+% \meta{token list variable} without removing it from the
+% \meta{sequence}. The \meta{token list variable} is assigned locally.
+% If \meta{sequence} is empty an error will be raised.
+% \end{function}
+%
+% \begin{function}{\seq_pop_left:NN, \seq_pop_left:cN}
+% \begin{syntax}
+% \cs{seq_pop_left:NN} \meta{sequence} \meta{token list variable}
+% \end{syntax}
+% Pops the left-most item from a \meta{sequence} into the
+% \meta{token list variable}, \emph{i.e.}~removes the item from the
+% sequence and stores it in the \meta{token list variable}.
+% Both of the variables are assigned locally. If \meta{sequence} is
+% empty an error will be raised.
+% \end{function}
+%
+% \begin{function}{\seq_gpop_left:NN, \seq_gpop_left:cN}
+% \begin{syntax}
+% \cs{seq_gpop_left:NN} \meta{sequence} \meta{token list variable}
+% \end{syntax}
+% Pops the left-most item from a \meta{sequence} into the
+% \meta{token list variable}, \emph{i.e.}~removes the item from the
+% sequence and stores it in the \meta{token list variable}.
+% The \meta{sequence} is modified globally, while the assignment of
+% the \meta{token list variable} is local.
+% If \meta{sequence} is empty an error will be raised.
+% \end{function}
+%
+% \begin{function}{\seq_pop_right:NN, \seq_pop_right:cN}
+% \begin{syntax}
+% \cs{seq_pop_right:NN} \meta{sequence} \meta{token list variable}
+% \end{syntax}
+% Pops the right-most item from a \meta{sequence} into the
+% \meta{token list variable}, \emph{i.e.}~removes the item from the
+% sequence and stores it in in the \meta{token list variable}.
+% Both of the variables are assigned locally. If \meta{sequence} is
+% empty an error will be raised.
+% \end{function}
+%
+% \begin{function}{\seq_gpop_right:NN, \seq_gpop_right:cN}
+% \begin{syntax}
+% \cs{seq_gpop_right:NN} \meta{sequence} \meta{token list variable}
+% \end{syntax}
+% Pops the right-most item from a \meta{sequence} into the
+% \meta{token list variable}, \emph{i.e.}~removes the item from the
+% sequence and stores it in the \meta{token list variable}.
+% The \meta{sequence} is modified globally, while the assignment of
+% the \meta{token list variable} is local.
+% If \meta{sequence} is empty an error will be raised.
+% \end{function}
+%
+% \section{Modifying sequences}
+%
+% While sequences are normally used as ordered lists, it may be
+% necessary to modify the content. The functions here may be used
+% to update sequences, while retaining the order of the unaffected
+% entries.
+%
+% \begin{function}{\seq_remove_duplicates:N, \seq_remove_duplicates:c}
+% \begin{syntax}
+% \cs{seq_remove_duplicates:N} \meta{sequence}
+% \end{syntax}
+% Removes duplicate items from the \meta{sequence}, leaving the
+% left most copy of each item in the \meta{sequence}. The \meta{item}
+% comparison takes place on a token basis, as for \cs{tl_if_eq:nn(TF)}.
+% The removal is local to the current \TeX{} group.
+% \begin{texnote}
+% This function iterates through every item in the \meta{sequence} and
+% does a comparison with the \meta{items} already checked. It is therefore
+% relatively slow with large sequences.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{\seq_gremove_duplicates:N, \seq_gremove_duplicates:c}
+% \begin{syntax}
+% \cs{seq_gremove_duplicates:N} \meta{sequence}
+% \end{syntax}
+% Removes duplicate items from the \meta{sequence}, leaving the
+% left most copy of each item in the \meta{sequence}. The \meta{item}
+% comparison takes place on a token basis, as for \cs{tl_if_eq:nn(TF)}.
+% The removal is applied globally.
+% \begin{texnote}
+% This function iterates through every item in the \meta{sequence} and
+% does a comparison with the \meta{items} already checked. It is therefore
+% relatively slow with large sequences.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{\seq_remove_all:Nn, \seq_remove_all:cn}
+% \begin{syntax}
+% \cs{seq_remove_all:Nn} \meta{sequence} \Arg{item}
+% \end{syntax}
+% Removes every occurrence of \meta{item} from the \meta{sequence}.
+% The \meta{item} comparison takes place on a token basis, as for
+% \cs{tl_if_eq:nn(TF)}. The removal is local to the current \TeX{} group.
+% \end{function}
+%
+% \begin{function}{\seq_gremove_all:Nn, \seq_gremove_all:cn}
+% \begin{syntax}
+% \cs{seq_gremove_all:Nn} \meta{sequence} \Arg{item}
+% \end{syntax}
+% Removes each occurrence of \meta{item} from the \meta{sequence}.
+% The \meta{item} comparison takes place on a token basis, as for
+% \cs{tl_if_eq:nn(TF)}. The removal is applied globally.
+% \end{function}
+%
+% \section{Sequence conditionals}
+%
+% \begin{function}[EXP,pTF]{\seq_if_empty:N, \seq_if_empty:c}
+% \begin{syntax}
+% \cs{seq_if_empty_p:N} \meta{sequence}
+% \cs{seq_if_empty:NTF} \meta{sequence} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{sequence} is empty (containing no items). The
+% branching versions then leave either \meta{true code} or
+% \meta{false code} in the input stream, as appropriate to the truth of
+% the test and the variant of the function chosen. The logical truth of
+% the test is left in the input stream by the predicate version.
+% \end{function}
+%
+% \begin{function}[TF]{
+% \seq_if_in:Nn, \seq_if_in:NV, \seq_if_in:Nv, \seq_if_in:No, \seq_if_in:Nx,
+% \seq_if_in:cn, \seq_if_in:cV, \seq_if_in:cv, \seq_if_in:co, \seq_if_in:cx
+% }
+% \begin{syntax}
+% \cs{seq_if_in:NnTF} \meta{sequence} \Arg{item}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{item} is present in the \meta{sequence}.
+% Either the \meta{true code} or \meta{false code} is left in the input
+% stream, as appropriate to the truth of the test and the variant of the
+% function
+% chosen.
+% \end{function}
+%
+% \section{Mapping to sequences}
+%
+% \begin{function}[EXP]{\seq_map_function:NN, \seq_map_function:cN}
+% \begin{syntax}
+% \cs{seq_map_function:NN} \meta{sequence} \meta{function}
+% \end{syntax}
+% Applies \meta{function} to every \meta{item} stored in the
+% \meta{sequence}. The \meta{function} will receive one argument for
+% each iteration. The \meta{items} are returned from left to right.
+% The function \cs{seq_map_inline:Nn} is in general more efficient
+% than \cs{seq_map_function:NN}.
+% One mapping may be nested inside another.
+% \end{function}
+%
+% \begin{function}{\seq_map_inline:Nn, \seq_map_inline:cn}
+% \begin{syntax}
+% \cs{seq_map_inline:Nn} \meta{sequence} \Arg{inline function}
+% \end{syntax}
+% Applies \meta{inline function} to every \meta{item} stored
+% within the \meta{sequence}. The \meta{inline function} should
+% consist of code which will receive the \meta{item} as |#1|.
+% One in line mapping can be nested inside another. The \meta{items}
+% are returned from left to right.
+% \end{function}
+%
+% \begin{function}{
+% \seq_map_variable:NNn, \seq_map_variable:Ncn,
+% \seq_map_variable:cNn, \seq_map_variable:ccn
+% }
+% \begin{syntax}
+% \cs{seq_map_variable:NNn} \meta{sequence}
+% ~~\meta{tl~var.} \Arg{function using tl~var.}
+% \end{syntax}
+% Stores each entry in the \meta{sequence} in turn in the
+% \meta{tl~var.}\ and applies the \meta{function using tl~var.}
+% The \meta{function} will usually consist of code making use of
+% the \meta{tl~var.}, but this is not enforced. One variable
+% mapping can be nested inside another. The \meta{items}
+% are returned from left to right.
+% \end{function}
+%
+% \begin{function}[EXP]{\seq_map_break:}
+% \begin{syntax}
+% \cs{seq_map_break:}
+% \end{syntax}
+% Used to terminate a \cs{seq_map_\ldots} function before all
+% entries in the \meta{sequence} have been processed. This will
+% normally take place within a conditional statement, for example
+% \begin{verbatim}
+% \seq_map_inline:Nn \l_my_seq
+% {
+% \str_if_eq:nnTF { #1 } { bingo }
+% { \seq_map_break: }
+% {
+% % Do something useful
+% }
+% }
+% \end{verbatim}
+% Use outside of a \cs{seq_map_\ldots} scenario will lead to low
+% level \TeX{} errors.
+% \begin{texnote}
+% When the mapping is broken, additional tokens may be inserted by the
+% internal macro \cs{seq_break_point:n} before further items are taken
+% from the input stream. This will depend on the design of the mapping
+% function.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[EXP]{\seq_map_break:n}
+% \begin{syntax}
+% \cs{seq_map_break:n} \Arg{tokens}
+% \end{syntax}
+% Used to terminate a \cs{seq_map_\ldots} function before all
+% entries in the \meta{sequence} have been processed, inserting
+% the \meta{tokens} after the mapping has ended. This will
+% normally take place within a conditional statement, for example
+% \begin{verbatim}
+% \seq_map_inline:Nn \l_my_seq
+% {
+% \str_if_eq:nnTF { #1 } { bingo }
+% { \seq_map_break:n { <tokens> } }
+% {
+% % Do something useful
+% }
+% }
+% \end{verbatim}
+% Use outside of a \cs{seq_map_\ldots} scenario will lead to low
+% level \TeX{} errors.
+% \begin{texnote}
+% When the mapping is broken, additional tokens may be inserted by the
+% internal macro \cs{seq_break_point:n} before the \meta{tokens} are
+% inserted into the input stream.
+% This will depend on the design of the mapping function.
+% \end{texnote}
+% \end{function}
+%
+% \section{Sequences as stacks}
+%
+% Sequences can be used as stacks, where data is pushed to and popped
+% from the top of the sequence. (The left of a sequence is the top, for
+% performance reasons.) The stack functions for sequences are not
+% intended to be mixed with the general ordered data functions detailed
+% in the previous section: a sequence should either be used as an
+% ordered data type or as a stack, but not in both ways.
+%
+% \begin{function}{\seq_get:NN, \seq_get:cN}
+% \begin{syntax}
+% \cs{seq_get:NN} \meta{sequence} \meta{token list variable}
+% \end{syntax}
+% Reads the top item from a \meta{sequence} into the
+% \meta{token list variable} without removing it from the
+% \meta{sequence}. The \meta{token list variable} is assigned locally.
+% If \meta{sequence} is empty an error will be raised.
+% \end{function}
+%
+% \begin{function}{\seq_pop:NN, \seq_pop:cN}
+% \begin{syntax}
+% \cs{seq_pop:NN} \meta{sequence} \meta{token list variable}
+% \end{syntax}
+% Pops the top item from a \meta{sequence} into the
+% \meta{token list variable}. Both of the variables are assigned
+% locally. If \meta{sequence} is empty an error will be raised.
+% \end{function}
+%
+% \begin{function}{\seq_gpop:NN, \seq_gpop:cN}
+% \begin{syntax}
+% \cs{seq_gpop:NN} \meta{sequence} \meta{token list variable}
+% \end{syntax}
+% Pops the top item from a \meta{sequence} into the
+% \meta{token list variable}. The \meta{sequence} is modified globally,
+% while the \meta{token list variable} is assigned locally. If
+% \meta{sequence} is empty an error will be raised.
+% \end{function}
+%
+% \begin{function}
+% {
+% \seq_push:Nn, \seq_push:NV, \seq_push:Nv, \seq_push:No, \seq_push:Nx,
+% seq_push:cn, \seq_push:cV, \seq_push:cv, \seq_push:co, \seq_push:cx
+% }
+% \begin{syntax}
+% \cs{seq_push:Nn} \meta{sequence} \Arg{item}
+% \end{syntax}
+% Adds the \Arg{item} to the top of the \meta{sequence}.
+% The assignment is restricted to the current \TeX{} group.
+% \end{function}
+%
+% \begin{function}
+% {
+% \seq_gpush:Nn, \seq_gpush:NV, \seq_gpush:Nv,
+% \seq_gpush:No, \seq_gpush:Nx,
+% \seq_gpush:cn, \seq_gpush:cV, \seq_gpush:cv,
+% \seq_gpush:co, \seq_gpush:cx
+% }
+% \begin{syntax}
+% \cs{seq_gpush:Nn} \meta{sequence} \Arg{item}
+% \end{syntax}
+% Pushes the \meta{item} onto the end of the top of the
+% \meta{sequence}. The assignment is global.
+% \end{function}
+%
+% \section{Viewing sequences}
+%
+% \begin{function}{\seq_show:N, \seq_show:c}
+% \begin{syntax}
+% \cs{seq_show:N} \meta{sequence}
+% \end{syntax}
+% Displays the entries in the \meta{sequence} in the terminal.
+% \end{function}
+%
+% \section{Experimental sequence functions}
+%
+% This section contains functions which may or may not be retained, depending
+% on how useful they are found to be.
+%
+% \begin{function}[TF]{\seq_get_left:NN, \seq_get_left:cN}
+% \begin{syntax}
+% \cs{seq_get_left:NNTF} \meta{sequence} \meta{token list variable}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% If the \meta{sequence} is empty, leaves the \meta{false code} in the
+% input stream and leaves the \meta{token list variable} unchanged. If the
+% \meta{sequence} is non-empty, stores the left-most item from a \meta{sequence}
+% in the \meta{token list variable} without removing it from a
+% \meta{sequence}. The \meta{true code} is then left in the input stream.
+% The \meta{token list variable} is assigned locally.
+% \end{function}
+%
+% \begin{function}[TF]{\seq_get_right:NN, \seq_get_right:cN}
+% \begin{syntax}
+% \cs{seq_get_right:NNTF} \meta{sequence} \meta{token list variable}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% If the \meta{sequence} is empty, leaves the \meta{false code} in the
+% input stream and leaves the \meta{token list variable} unchanged. If the
+% \meta{sequence} is non-empty, stores the right-most item from a \meta{sequence}
+% in the \meta{token list variable} without removing it from a
+% \meta{sequence}. The \meta{true code} is then left in the input stream.
+% The \meta{token list variable} is assigned locally.
+% \end{function}
+%
+% \begin{function}[TF]{\seq_pop_left:NN, \seq_pop_left:cN}
+% \begin{syntax}
+% \cs{seq_pop_left:NNTF} \meta{sequence} \meta{token list variable}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% If the \meta{sequence} is empty, leaves the \meta{false code} in the
+% input stream and leaves the \meta{token list variable} unchanged. If the
+% \meta{sequence} is non-empty, pops the left-most item from a \meta{sequence}
+% in the \meta{token list variable}, \emph{i.e.}~removes the item from a
+% \meta{sequence}. The \meta{true code} is then left in the input stream.
+% Both the \meta{sequence} and the \meta{token list variable} are assigned
+% locally.
+% \end{function}
+%
+% \begin{function}[TF]{\seq_gpop_left:NN, \seq_gpop_left:cN}
+% \begin{syntax}
+% \cs{seq_gpop_left:NNTF} \meta{sequence} \meta{token list variable}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% If the \meta{sequence} is empty, leaves the \meta{false code} in the
+% input stream and leaves the \meta{token list variable} unchanged. If the
+% \meta{sequence} is non-empty, pops the left-most item from a \meta{sequence}
+% in the \meta{token list variable}, \emph{i.e.}~removes the item from a
+% \meta{sequence}. The \meta{true code} is then left in the input stream.
+% The \meta{sequence} is modified globally, while the \meta{token list variable}
+% is assigned locally.
+% \end{function}
+%
+% \begin{function}[TF]{\seq_pop_right:NN, \seq_pop_right:cN}
+% \begin{syntax}
+% \cs{seq_pop_right:NNTF} \meta{sequence} \meta{token list variable}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% If the \meta{sequence} is empty, leaves the \meta{false code} in the
+% input stream and leaves the \meta{token list variable} unchanged. If the
+% \meta{sequence} is non-empty, pops the right-most item from a \meta{sequence}
+% in the \meta{token list variable}, \emph{i.e.}~removes the item from a
+% \meta{sequence}. The \meta{true code} is then left in the input stream.
+% Both the \meta{sequence} and the \meta{token list variable} are assigned
+% locally.
+% \end{function}
+%
+% \begin{function}[TF]{\seq_gpop_right:NN, \seq_gpop_right:cN}
+% \begin{syntax}
+% \cs{seq_gpop_right:NNTF} \meta{sequence} \meta{token list variable}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% If the \meta{sequence} is empty, leaves the \meta{false code} in the
+% input stream and leaves the \meta{token list variable} unchanged. If the
+% \meta{sequence} is non-empty, pops the right-most item from a \meta{sequence}
+% in the \meta{token list variable}, \emph{i.e.}~removes the item from a
+% \meta{sequence}. The \meta{true code} is then left in the input stream.
+% The \meta{sequence} is modified globally, while the \meta{token list variable}
+% is assigned locally.
+% \end{function}
+%
+% \begin{function}[EXP]{\seq_length:N, \seq_length:c}
+% \begin{syntax}
+% \cs{seq_length:N} \meta{sequence}
+% \end{syntax}
+% Leaves the number of items in the \meta{sequence} in the input
+% stream as an \meta{integer denotation}. The total number of items
+% in a \meta{sequence} will include those which are empty and duplicates,
+% \emph{i.e.}~every item in a \meta{sequence} is unique.
+% \end{function}
+%
+% \begin{function}[EXP]{\seq_item:Nn, \seq_item:cn}
+% \begin{syntax}
+% \cs{seq_item:Nn} \meta{sequence} \Arg{integer expression}
+% \end{syntax}
+% Indexing items in the \meta{sequence} from $0$ at the top (left), this
+% function will evaluate the \meta{integer expression} and leave the
+% appropriate item from the sequence in the input stream. If the
+% \meta{integer expression} is negative, indexing occurs from the
+% bottom (right) of the sequence. When the \meta{integer expression}
+% is larger than the number of items in the \meta{sequence} (as
+% calculated by \cs{seq_length:N}) then the function will expand to
+% nothing.
+% \end{function}
+%
+% \begin{function}[EXP]{\seq_use:N, \seq_use:c}
+% \begin{syntax}
+% \cs{seq_use:N} \meta{sequence}
+% \end{syntax}
+% Places each \meta{item} in the \meta{sequence} in turn in the input stream.
+% This occurs in an expandable fashion, and is implemented as a mapping.
+% This means that the process may be prematurely terminated using
+% \cs{seq_map_break:} or \cs{seq_map_break:n}. The \meta{items} in the
+% \meta{sequence} will be used from left (top) to right (bottom).
+% \end{function}
+%
+% \begin{function}[EXP]
+% {
+% \seq_mapthread_function:NNN, \seq_mapthread_function:NcN,
+% \seq_mapthread_function:cNN, \seq_mapthread_function:ccN
+% }
+% \begin{syntax}
+% \cs{seq_mapthread_function:NNN} \meta{seq1} \meta{seq2} \meta{function}
+% \end{syntax}
+% Applies \meta{function} to every pair of items
+% \meta{seq1-item}--\meta{seq2-item} from the two sequences, returning
+% items from both sequences from left to right. The \meta{function} will
+% receive two \texttt{n}-type arguments for each iteration. The mapping
+% will terminate when
+% the end of either sequence is reached (\emph{i.e.}~whichever sequence has
+% fewer items determines how many iterations
+% occur).
+% \end{function}
+%
+% \begin{function}
+% {
+% \seq_set_from_clist:NN, \seq_set_from_clist:cN,
+% \seq_set_from_clist:Nc, \seq_set_from_clist:cc,
+% \seq_set_from_clist:Nn, \seq_set_from_clist:cn
+% }
+% \begin{syntax}
+% \cs{seq_set_from_clist:NN} \meta{sequence} \meta{comma-list}
+% \end{syntax}
+% Sets the \meta{sequence} within the current \TeX{} group to be equal
+% to the content of the \meta{comma-list}.
+% \end{function}
+%
+% \begin{function}
+% {
+% \seq_gset_from_clist:NN, \seq_gset_from_clist:cN,
+% \seq_gset_from_clist:Nc, \seq_gset_from_clist:cc,
+% \seq_gset_from_clist:Nn, \seq_gset_from_clist:cn
+% }
+% \begin{syntax}
+% \cs{seq_gset_from_clist:NN} \meta{sequence} \meta{comma-list}
+% \end{syntax}
+% Sets the \meta{sequence} globally to equal to the content of the
+% \meta{comma-list}.
+% \end{function}
+%
+% \section{Internal sequence functions}
+%
+% \begin{function}{\seq_if_empty_err_break:N}
+% \begin{syntax}
+% \cs{seq_if_empty_err_break:N} \meta{sequence}
+% \end{syntax}
+% Tests if the \meta{sequence} is empty, and if so issues an error
+% message before skipping over any tokens up to \cs{seq_break_point:n}.
+% This function is used to avoid more serious errors which would
+% otherwise occur if some internal functions were applied to an
+% empty \meta{sequence}.
+% \end{function}
+%
+% \begin{function}[EXP]{\seq_item:n}
+% \begin{syntax}
+% \cs{seq_item:n} \meta{item}
+% \end{syntax}
+% The internal token used to begin each sequence entry. If expanded
+% outside of a mapping or manipulation function, an error will be
+% raised. The definition should always be set globally.
+% \end{function}
+%
+% \begin{function}{\seq_push_item_def:n, \seq_push_item_def:x}
+% \begin{syntax}
+% \cs{seq_push_item_def:n} \Arg{code}
+% \end{syntax}
+% Saves the definition of \cs{seq_item:n} and redefines it to
+% accept one parameter and expand to \meta{code}. This function
+% should always be balanced by use of \cs{seq_pop_item_def:}.
+% \end{function}
+%
+% \begin{function}{\seq_pop_item_def:}
+% \begin{syntax}
+% \cs{seq_pop_item_def:}
+% \end{syntax}
+% Restores the definition of \cs{seq_item:n} most recently saved by
+% \cs{seq_push_item_def:n}. This function should always be used in
+% a balanced pair with \cs{seq_push_item_def:n}.
+% \end{function}
+%
+% \begin{function}[EXP]{\seq_break:}
+% \begin{syntax}
+% \cs{seq_break:}
+% \end{syntax}
+% Used to terminate sequence functions by gobbling all tokens
+% up to \cs{seq_break_point:n}. This function is a copy of
+% \cs{seq_map_break:}, but is used in situations which are
+% not mappings.
+% \end{function}
+%
+% \begin{function}[EXP]{\seq_break:n}
+% \begin{syntax}
+% \cs{seq_break:n} \Arg{tokens}
+% \end{syntax}
+% Used to terminate sequence functions by gobbling all tokens
+% up to \cs{seq_break_point:n}, then inserting the \meta{tokens}
+% before continuing reading the input stream. This function is a copy
+% of \cs{seq_map_break:n}, but is used in situations which are
+% not mappings.
+% \end{function}
+%
+% \begin{function}[EXP]{\seq_break_point:n}
+% \begin{syntax}
+% \cs{seq_break_point:n} \meta{tokens}
+% \end{syntax}
+% Used to mark the end of a recursion or mapping: the functions
+% \cs{seq_map_break:} and \cs{seq_map_break:n} use this to break out
+% of the loop. After the loop ends, the \meta{tokens} are inserted into
+% the input stream. This occurs even if the the break functions are
+% \emph{not} applied: \cs{seq_break_point:n} is functionally-equivalent
+% in these cases to \cs{use:n}.
+% \end{function}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3seq} implementation}
+%
+% \TestFiles{m3seq002,m3seq003}
+%
+% \begin{macrocode}
+%<*initex|package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*package>
+\ProvidesExplPackage
+ {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
+\package_check_loaded_expl:
+%</package>
+% \end{macrocode}
+%
+% A sequence is a control sequence whose top-level expansion is of
+% the form \enquote{\cs{seq_item:n} \marg{item$_0$}
+% \ldots \cs{seq_item:n} \marg{item$_{n-1}$}}. An earlier implementation
+% used the structure \enquote{\cs{seq_elt:w} \meta{item$_1$}
+% \cs{seq_elt_end:} \ldots \cs{seq_elt:w} \meta{item$_n$}
+% \cs{seq_elt_end:}}. This allows rapid searching using a delimited
+% function, but is not suitable for items containing |{|, |}| and |#|
+% tokens, and also leads to the loss of surrounding braces
+% around items.
+%
+% \begin{macro}[int]{\seq_item:n}
+% The delimiter is always defined, but when used incorrectly simply
+% removes its argument and hits an undefined control sequence to
+% raise an error.
+% \begin{macrocode}
+\cs_new:Npn \seq_item:n
+ {
+ \seq_use_error:
+ \use_none:n
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}{\l_seq_tmpa_tl, \l_seq_tmpb_tl}
+% Scratch space for various internal uses.
+% \begin{macrocode}
+\tl_new:N \l_seq_tmpa_tl
+\tl_new:N \l_seq_tmpb_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \subsection{Allocation and initialisation}
+%
+% \begin{macro}{\seq_new:N,\seq_new:c}
+% \UnitTested
+% Internally, sequences are just token lists.
+% \begin{macrocode}
+\cs_new_eq:NN \seq_new:N \tl_new:N
+\cs_new_eq:NN \seq_new:c \tl_new:c
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\seq_clear:N, \seq_clear:c}
+% \UnitTested
+% \begin{macro}{\seq_gclear:N, \seq_gclear:c}
+% \UnitTested
+% Clearing sequences is just the same as clearing token lists.
+% \begin{macrocode}
+\cs_new_eq:NN \seq_clear:N \tl_clear:N
+\cs_new_eq:NN \seq_clear:c \tl_clear:c
+\cs_new_eq:NN \seq_gclear:N \tl_gclear:N
+\cs_new_eq:NN \seq_gclear:c \tl_gclear:c
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\seq_clear_new:N, \seq_clear_new:c}
+% \UnitTested
+% \begin{macro}{\seq_gclear_new:N, \seq_gclear_new:c}
+% \UnitTested
+% Once again a copy from the token list functions.
+% \begin{macrocode}
+\cs_new_eq:NN \seq_clear_new:N \tl_clear_new:N
+\cs_new_eq:NN \seq_clear_new:c \tl_clear_new:c
+\cs_new_eq:NN \seq_gclear_new:N \tl_gclear_new:N
+\cs_new_eq:NN \seq_gclear_new:c \tl_gclear_new:c
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\seq_set_eq:NN, \seq_set_eq:cN, \seq_set_eq:Nc, \seq_set_eq:cc}
+% \UnitTested
+% \begin{macro}
+% {\seq_gset_eq:NN, \seq_gset_eq:cN, \seq_gset_eq:Nc, \seq_gset_eq:cc}
+% \UnitTested
+% Once again, these are simple copies from the token list functions.
+% \begin{macrocode}
+\cs_new_eq:NN \seq_set_eq:NN \tl_set_eq:NN
+\cs_new_eq:NN \seq_set_eq:Nc \tl_set_eq:Nc
+\cs_new_eq:NN \seq_set_eq:cN \tl_set_eq:cN
+\cs_new_eq:NN \seq_set_eq:cc \tl_set_eq:cc
+\cs_new_eq:NN \seq_gset_eq:NN \tl_gset_eq:NN
+\cs_new_eq:NN \seq_gset_eq:Nc \tl_gset_eq:Nc
+\cs_new_eq:NN \seq_gset_eq:cN \tl_gset_eq:cN
+\cs_new_eq:NN \seq_gset_eq:cc \tl_gset_eq:cc
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\seq_concat:NNN, \seq_concat:ccc}
+% \UnitTested
+% \begin{macro}{\seq_gconcat:NNN, \seq_gconcat:ccc}
+% \UnitTested
+% Concatenating sequences is easy.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \seq_concat:NNN #1#2#3
+ { \tl_set:Nx #1 { \exp_not:o {#2} \exp_not:o {#3} } }
+\cs_new_protected_nopar:Npn \seq_gconcat:NNN #1#2#3
+ { \tl_gset:Nx #1 { \exp_not:o {#2} \exp_not:o {#3} } }
+\cs_generate_variant:Nn \seq_concat:NNN { ccc }
+\cs_generate_variant:Nn \seq_gconcat:NNN { ccc }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Appending data to either end}
+%
+% \begin{macro}{
+% \seq_put_left:Nn, \seq_put_left:NV, \seq_put_left:Nv,
+% \seq_put_left:No, \seq_put_left:Nx,
+% \seq_put_left:cn, \seq_put_left:cV, \seq_put_left:cv,
+% \seq_put_left:co, \seq_put_left:cx
+% }
+% \UnitTested
+% \begin{macro}{
+% \seq_put_right:Nn, \seq_put_right:NV, \seq_put_right:Nv,
+% \seq_put_right:No, \seq_put_right:Nx,
+% \seq_put_right:cn, \seq_put_right:cV, \seq_put_right:cv,
+% \seq_put_right:co, \seq_put_right:cx
+% }
+% \UnitTested
+% The code here is just a wrapper for adding to token lists.
+% \begin{macrocode}
+\cs_new_protected:Npn \seq_put_left:Nn #1#2
+ { \tl_put_left:Nn #1 { \seq_item:n {#2} } }
+\cs_new_protected:Npn \seq_put_right:Nn #1#2
+ { \tl_put_right:Nn #1 { \seq_item:n {#2} } }
+\cs_generate_variant:Nn \seq_put_left:Nn { NV , Nv , No , Nx }
+\cs_generate_variant:Nn \seq_put_left:Nn { c , cV , cv , co , cx }
+\cs_generate_variant:Nn \seq_put_right:Nn { NV , Nv , No , Nx }
+\cs_generate_variant:Nn \seq_put_right:Nn { c , cV , cv , co , cx }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{
+% \seq_gput_left:Nn, \seq_gput_left:NV, \seq_gput_left:Nv,
+% \seq_gput_left:No, \seq_gput_left:Nx,
+% \seq_gput_left:cn, \seq_gput_left:cV, \seq_gput_left:cv,
+% \seq_gput_left:co, \seq_gput_left:cx
+% }
+% \begin{macro}{
+% \seq_gput_right:Nn, \seq_gput_right:NV, \seq_gput_right:Nv,
+% \seq_gput_right:No, \seq_gput_right:Nx,
+% \seq_gput_right:cn, \seq_gput_right:cV,\seq_gput_right:cv,
+% \seq_gput_right:co, \seq_gput_right:cx
+% }
+% The same for global addition.
+% \begin{macrocode}
+\cs_new_protected:Npn \seq_gput_left:Nn #1#2
+ { \tl_gput_left:Nn #1 { \seq_item:n {#2} } }
+\cs_new_protected:Npn \seq_gput_right:Nn #1#2
+ { \tl_gput_right:Nn #1 { \seq_item:n {#2} } }
+\cs_generate_variant:Nn \seq_gput_left:Nn { NV , Nv , No , Nx }
+\cs_generate_variant:Nn \seq_gput_left:Nn { c , cV , cv , co , cx }
+\cs_generate_variant:Nn \seq_gput_right:Nn { NV , Nv , No , Nx }
+\cs_generate_variant:Nn \seq_gput_right:Nn { c , cV , cv , co , cx }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Modifying sequences}
+%
+% \begin{variable}{\l_seq_remove_seq}
+% An internal sequence for the removal routines.
+% \begin{macrocode}
+\seq_new:N \l_seq_remove_seq
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\seq_remove_duplicates:N, \seq_remove_duplicates:c}
+% \UnitTested
+% \begin{macro}{\seq_gremove_duplicates:N, \seq_gremove_duplicates:c}
+% \UnitTested
+% \begin{macro}[aux]{\seq_remove_duplicates_aux:NN}
+% Removing duplicates means making a new list then copying it.
+% \begin{macrocode}
+\cs_new_protected:Npn \seq_remove_duplicates:N
+ { \seq_remove_duplicates_aux:NN \seq_set_eq:NN }
+\cs_new_protected:Npn \seq_gremove_duplicates:N
+ { \seq_remove_duplicates_aux:NN \seq_gset_eq:NN }
+\cs_new_protected:Npn \seq_remove_duplicates_aux:NN #1#2
+ {
+ \seq_clear:N \l_seq_remove_seq
+ \seq_map_inline:Nn #2
+ {
+ \seq_if_in:NnF \l_seq_remove_seq {##1}
+ { \seq_put_right:Nn \l_seq_remove_seq {##1} }
+ }
+ #1 #2 \l_seq_remove_seq
+ }
+\cs_generate_variant:Nn \seq_remove_duplicates:N { c }
+\cs_generate_variant:Nn \seq_gremove_duplicates:N { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\seq_remove_all:Nn, \seq_remove_all:cn}
+% \UnitTested
+% \begin{macro}{\seq_gremove_all:Nn, \seq_gremove_all:cn}
+% \UnitTested
+% \begin{macro}[aux]{\seq_remove_all_aux:NNn}
+% The idea of the code here is to avoid a relatively expensive addition of
+% items one at a time to an intermediate sequence.
+% The approach taken is therefore similar to
+% that in \cs{seq_pop_right_aux_ii:NNN}, using a \enquote{flexible}
+% \texttt{x}-type expansion to do most of the work. As \cs{tl_if_eq:nnT}
+% is not expandable, a two-part strategy is needed. First, the
+% \texttt{x}-type expansion uses \cs{str_if_eq:nnT} to find potential
+% matches. If one is found, the expansion is halted and the necessary
+% set up takes place to use the \cs{tl_if_eq:NNT} test. The \texttt{x}-type
+% is started again, including all of the items copied already. This will
+% happen repeatedly until the entire sequence has been scanned. The code
+% is set up to avoid needing and intermediate scratch list: the lead-off
+% \texttt{x}-type expansion (|#1 #2 {#2}|) will ensure that nothing is
+% lost.
+% \begin{macrocode}
+\cs_new_protected:Npn \seq_remove_all:Nn
+ { \seq_remove_all_aux:NNn \tl_set:Nx }
+\cs_new_protected:Npn \seq_gremove_all:Nn
+ { \seq_remove_all_aux:NNn \tl_gset:Nx }
+\cs_new_protected:Npn \seq_remove_all_aux:NNn #1#2#3
+ {
+ \seq_push_item_def:n
+ {
+ \str_if_eq:nnT {##1} {#3}
+ {
+ \if_false: { \fi: }
+ \tl_set:Nn \l_seq_tmpb_tl {##1}
+ #1 #2
+ { \if_false: } \fi:
+ \exp_not:o {#2}
+ \tl_if_eq:NNT \l_seq_tmpa_tl \l_seq_tmpb_tl
+ { \use_none:nn }
+ }
+ \exp_not:n { \seq_item:n {##1} }
+ }
+ \tl_set:Nn \l_seq_tmpa_tl {#3}
+ #1 #2 {#2}
+ \seq_pop_item_def:
+ }
+\cs_generate_variant:Nn \seq_remove_all:Nn { c }
+\cs_generate_variant:Nn \seq_gremove_all:Nn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Sequence conditionals}
+%
+% \begin{macro}[pTF]{\seq_if_empty:N, \seq_if_empty:c}
+% \UnitTested
+% Simple copies from the token list variable material.
+% \begin{macrocode}
+\prg_new_eq_conditional:NNn \seq_if_empty:N \tl_if_empty:N
+ { p , T , F , TF }
+\prg_new_eq_conditional:NNn \seq_if_empty:c \tl_if_empty:c
+ { p , T , F , TF }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[TF]{
+% \seq_if_in:Nn, \seq_if_in:NV, \seq_if_in:Nv, \seq_if_in:No, \seq_if_in:Nx,
+% \seq_if_in:cn, \seq_if_in:cV, \seq_if_in:cv, \seq_if_in:co, \seq_if_in:cx
+% }
+% \UnitTested
+% \begin{macro}[aux]{\seq_if_in_aux:}
+% The approach here is to define \cs{seq_item:n} to compare its
+% argument with the test sequence. If the two items are equal, the
+% mapping is terminated and \cs{prg_return_true:} is inserted. On the
+% other hand, if there is no match then the loop will break returning
+% \cs{prg_return_false:}. In either case, \cs{seq_break_point:n}
+% ensures that the group ends before the logical value is returned.
+% Everything is inside a group so that \cs{seq_item:n} is preserved
+% in nested situations.
+% \begin{macrocode}
+\prg_new_protected_conditional:Npnn \seq_if_in:Nn #1#2
+ { T , F , TF }
+ {
+ \group_begin:
+ \tl_set:Nn \l_seq_tmpa_tl {#2}
+ \cs_set_protected:Npn \seq_item:n ##1
+ {
+ \tl_set:Nn \l_seq_tmpb_tl {##1}
+ \if_meaning:w \l_seq_tmpa_tl \l_seq_tmpb_tl
+ \exp_after:wN \seq_if_in_aux:
+ \fi:
+ }
+ #1
+ \seq_break:n { \prg_return_false: }
+ \seq_break_point:n { \group_end: }
+ }
+\cs_new_nopar:Npn \seq_if_in_aux: { \seq_break:n { \prg_return_true: } }
+\cs_generate_variant:Nn \seq_if_in:NnT { NV , Nv , No , Nx }
+\cs_generate_variant:Nn \seq_if_in:NnT { c , cV , cv , co , cx }
+\cs_generate_variant:Nn \seq_if_in:NnF { NV , Nv , No , Nx }
+\cs_generate_variant:Nn \seq_if_in:NnF { c , cV , cv , co , cx }
+\cs_generate_variant:Nn \seq_if_in:NnTF { NV , Nv , No , Nx }
+\cs_generate_variant:Nn \seq_if_in:NnTF { c , cV , cv , co , cx }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Recovering data from sequences}
+%
+% \begin{macro}{\seq_get_left:NN, \seq_get_left:cN}
+% \UnitTested
+% \begin{macro}[aux]{\seq_get_left_aux:NnwN}
+% Getting an item from the left of a sequence is pretty easy: just
+% trim off the first item after removing the \cs{seq_item:n} at
+% the start.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \seq_get_left:NN #1#2
+ {
+ \seq_if_empty_err_break:N #1
+ \exp_after:wN \seq_get_left_aux:NnwN #1 \q_stop #2
+ \seq_break_point:n { }
+ }
+\cs_new_protected:Npn \seq_get_left_aux:NnwN \seq_item:n #1#2 \q_stop #3
+ { \tl_set:Nn #3 {#1} }
+\cs_generate_variant:Nn \seq_get_left:NN { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\seq_pop_left:NN, \seq_pop_left:cN}
+% \UnitTested
+% \begin{macro}{\seq_gpop_left:NN, \seq_gpop_left:cN}
+% \UnitTested
+% \begin{macro}[aux]{\seq_pop_left_aux:NNN}
+% \begin{macro}[aux]{\seq_pop_left_aux:NnwNNN}
+% The approach to popping an item is pretty similar to that to get
+% an item, with the only difference being that the sequence itself has
+% to be redefined. This makes it more sensible to use an auxiliary
+% function for the local and global cases.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \seq_pop_left:NN
+ { \seq_pop_left_aux:NNN \tl_set:Nn }
+\cs_new_protected_nopar:Npn \seq_gpop_left:NN
+ { \seq_pop_left_aux:NNN \tl_gset:Nn }
+\cs_new_protected_nopar:Npn \seq_pop_left_aux:NNN #1#2#3
+ {
+ \seq_if_empty_err_break:N #2
+ \exp_after:wN \seq_pop_left_aux:NnwNNN #2 \q_stop #1#2#3
+ \seq_break_point:n { }
+ }
+\cs_new_protected:Npn \seq_pop_left_aux:NnwNNN \seq_item:n #1#2 \q_stop #3#4#5
+ {
+ #3 #4 {#2}
+ \tl_set:Nn #5 {#1}
+ }
+\cs_generate_variant:Nn \seq_pop_left:NN { c }
+\cs_generate_variant:Nn \seq_gpop_left:NN { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\seq_get_right:NN, \seq_get_right:cN}
+% \UnitTested
+% \begin{macro}[aux]{\seq_get_right_aux:NN}
+% \begin{macro}[aux]{\seq_get_right_loop:nn}
+% The idea here is to remove the very first \cs{seq_item:n} from the
+% sequence, leaving a token list starting with the first braced entry.
+% Two arguments at a time are then grabbed: apart from the right-hand end of
+% the sequence, this will be a brace group followed by \cs{seq_item:n}. The
+% set up code means that these all disappear. At the end of the sequence,
+% the assignment is placed in front of the very last entry in the sequence,
+% before a tidying-up step takes place to remove the loop and reset the
+% meaning of \cs{seq_item:n}.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \seq_get_right:NN #1#2
+ {
+ \seq_if_empty_err_break:N #1
+ \seq_get_right_aux:NN #1#2
+ \seq_break_point:n { }
+ }
+\cs_new_protected_nopar:Npn \seq_get_right_aux:NN #1#2
+ {
+ \seq_push_item_def:n { }
+ \exp_after:wN \exp_after:wN \exp_after:wN \seq_get_right_loop:nn
+ \exp_after:wN \use_none:n #1
+ { \tl_set:Nn #2 }
+ { }
+ {
+ \seq_pop_item_def:
+ \seq_break:
+ }
+}
+\cs_new:Npn \seq_get_right_loop:nn #1#2
+ {
+ #2 {#1}
+ \seq_get_right_loop:nn
+ }
+\cs_generate_variant:Nn \seq_get_right:NN { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\seq_pop_right:NN, \seq_pop_right:cN}
+% \UnitTested
+% \begin{macro}{\seq_gpop_right:NN, \seq_gpop_right:cN}
+% \UnitTested
+% \begin{macro}[aux]{\seq_pop_right_aux:NNN, \seq_pop_right_aux_ii:NNN}
+% The approach to popping from the right is a bit more involved, but does
+% use some of the same ideas as getting from the right. What is needed is a
+% \enquote{flexible length} way to set a token list variable. This is
+% supplied by the |{ \if_false:} \fi:| \ldots
+% |\if_false: { \fi: }| construct. Using an \texttt{x}-type
+% expansion and a \enquote{non-expanding} definition for \cs{seq_item:n},
+% the left-most $n - 1$ entries in a sequence of $n$ items will be stored
+% back in the sequence. That needs a loop of unknown length, hence using the
+% strange \cs{if_false:} way of including brackets. When the last item
+% of the sequence is reached, the closing bracket for the assignment is
+% inserted, and |\tl_set:Nn #3| is inserted in front of the final entry.
+% This therefore does the pop assignment, then a final loop clears up the
+% code.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \seq_pop_right:NN
+ { \seq_pop_right_aux:NNN \tl_set:Nx }
+\cs_new_protected_nopar:Npn \seq_gpop_right:NN
+ { \seq_pop_right_aux:NNN \tl_gset:Nx }
+\cs_new_protected_nopar:Npn \seq_pop_right_aux:NNN #1#2#3
+ {
+ \seq_if_empty_err_break:N #2
+ \seq_pop_right_aux_ii:NNN #1 #2 #3
+ \seq_break_point:n { }
+ }
+\cs_new_protected_nopar:Npn \seq_pop_right_aux_ii:NNN #1#2#3
+ {
+ \seq_push_item_def:n { \exp_not:n { \seq_item:n {##1} } }
+ #1 #2 { \if_false: } \fi:
+ \exp_after:wN \exp_after:wN \exp_after:wN \seq_get_right_loop:nn
+ \exp_after:wN \use_none:n #2
+ {
+ \if_false: { \fi: }
+ \tl_set:Nn #3
+ }
+ { }
+ {
+ \seq_pop_item_def:
+ \seq_break:
+ }
+ }
+\cs_generate_variant:Nn \seq_pop_right:NN { c }
+\cs_generate_variant:Nn \seq_gpop_right:NN { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Mapping to sequences}
+%
+% \begin{macro}[int]{\seq_break:}
+% \begin{macro}[int]{\seq_break:n}
+% To break a function, the special token \cs{seq_break_point:n} is
+% used to find the end of the code. Any ending code is then inserted
+% before the return value of \cs{seq_map_break:n} is inserted.
+% \begin{macrocode}
+\cs_new:Npn \seq_break: #1 \seq_break_point:n #2 {#2}
+\cs_new:Npn \seq_break:n #1#2 \seq_break_point:n #3 { #3 #1 }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\seq_map_break:}
+% \UnitTested
+% \begin{macro}{\seq_map_break:n}
+% \UnitTested
+% Semantically-logical copies of the break functions for use inside
+% mappings.
+% \begin{macrocode}
+\cs_new_eq:NN \seq_map_break: \seq_break:
+\cs_new_eq:NN \seq_map_break:n \seq_break:n
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[int]{\seq_break_point:n}
+% Normally, the marker token will not be executed, but if it is then
+% the end code is simply inserted.
+% \begin{macrocode}
+\cs_new_eq:NN \seq_break_point:n \use:n
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\seq_if_empty_err_break:N}
+% A function to check that sequences really have some content. This
+% is optimised for speed, hence the direct primitive use.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \seq_if_empty_err_break:N #1
+ {
+ \if_meaning:w #1 \c_empty_tl
+ \msg_kernel_error:nnx { seq } { empty-sequence } { \token_to_str:N #1 }
+ \exp_after:wN \seq_break:
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\seq_map_function:NN, \seq_map_function:cN}
+% \UnitTested
+% \begin{macro}[aux]{\seq_map_function_aux:NNn}
+% The idea here is to apply the code of |#2| to each item in the
+% sequence without altering the definition of \cs{seq_item:n}. This
+% is done as by noting that every odd token in the sequence must be
+% \cs{seq_item:n}, which can be gobbled by \cs{use_none:n}. At the end of
+% the loop, |#2| is instead |? \seq_map_break:|, which therefore breaks the
+% loop without needing to do a (relatively-expensive) quark test.
+% \begin{macrocode}
+\cs_new:Npn \seq_map_function:NN #1#2
+ {
+ \exp_after:wN \seq_map_function_aux:NNn \exp_after:wN #2 #1
+ { ? \seq_map_break: } { }
+ \seq_break_point:n { }
+ }
+\cs_new:Npn \seq_map_function_aux:NNn #1#2#3
+ {
+ \use_none:n #2
+ #1 {#3}
+ \seq_map_function_aux:NNn #1
+ }
+\cs_generate_variant:Nn \seq_map_function:NN { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{variable}{\g_seq_nesting_depth_int}
+% A counter to keep track of nested functions: defined in \pkg{l3int}.
+% \end{variable}
+%
+% \begin{macro}[int]{\seq_push_item_def:n, \seq_push_item_def:x}
+% \begin{macro}[aux]{\seq_push_item_def_aux:}
+% \begin{macro}[int]{\seq_pop_item_def:}
+% The definition of \cs{seq_item:n} needs to be saved and restored at
+% various points within the mapping and manipulation code. That is handled
+% here: as always, this approach uses global assignments.
+% \begin{macrocode}
+\cs_new_protected:Npn \seq_push_item_def:n
+ {
+ \seq_push_item_def_aux:
+ \cs_gset:Npn \seq_item:n ##1
+ }
+\cs_new_protected:Npn \seq_push_item_def:x
+ {
+ \seq_push_item_def_aux:
+ \cs_gset:Npx \seq_item:n ##1
+ }
+\cs_new_protected:Npn \seq_push_item_def_aux:
+ {
+ \cs_gset_eq:cN { seq_item_ \int_use:N \g_seq_nesting_depth_int :n }
+ \seq_item:n
+ \int_gincr:N \g_seq_nesting_depth_int
+ }
+\cs_new_protected_nopar:Npn \seq_pop_item_def:
+ {
+ \int_gdecr:N \g_seq_nesting_depth_int
+ \cs_gset_eq:Nc \seq_item:n
+ { seq_item_ \int_use:N \g_seq_nesting_depth_int :n }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\seq_map_inline:Nn, \seq_map_inline:cn}
+% \UnitTested
+% The idea here is that \cs{seq_item:n} is already \enquote{applied} to
+% each item in a sequence, and so an in-line mapping is just a case of
+% redefining \cs{seq_item:n}.
+% \begin{macrocode}
+\cs_new_protected:Npn \seq_map_inline:Nn #1#2
+ {
+ \seq_push_item_def:n {#2}
+ #1
+ \seq_break_point:n { \seq_pop_item_def: }
+ }
+\cs_generate_variant:Nn \seq_map_inline:Nn { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \seq_map_variable:NNn,\seq_map_variable:Ncn,
+% \seq_map_variable:cNn,\seq_map_variable:ccn
+% }
+% \UnitTested
+% This is just a specialised version of the in-line mapping function,
+% using an \texttt{x}-type expansion for the code set up so that the
+% number of |#| tokens required is as expected.
+% \begin{macrocode}
+\cs_new_protected:Npn \seq_map_variable:NNn #1#2#3
+ {
+ \seq_push_item_def:x
+ {
+ \tl_set:Nn \exp_not:N #2 {##1}
+ \exp_not:n {#3}
+ }
+ #1
+ \seq_break_point:n { \seq_pop_item_def: }
+ }
+\cs_generate_variant:Nn \seq_map_variable:NNn { Nc }
+\cs_generate_variant:Nn \seq_map_variable:NNn { c , cc }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Sequence stacks}
+%
+% The same functions as for sequences, but with the correct naming.
+%
+% \begin{macro}{
+% \seq_push:Nn, \seq_push:NV, \seq_push:Nv, \seq_push:No, \seq_push:Nx,
+% \seq_push:cn, \seq_push:cV, \seq_push:cV, \seq_push:co, \seq_push:cx
+% }
+% \UnitTested
+% \begin{macro}{
+% \seq_gpush:Nn, \seq_gpush:NV, \seq_gpush:Nv, \seq_gpush:No, \seq_gpush:Nx,
+% \seq_gpush:cn, \seq_gpush:cV, \seq_gpush:cv, \seq_gpush:co, \seq_gpush:cx
+% }
+% \UnitTested
+% Pushing to a sequence is the same as adding on the left.
+% \begin{macrocode}
+\cs_new_eq:NN \seq_push:Nn \seq_put_left:Nn
+\cs_new_eq:NN \seq_push:NV \seq_put_left:NV
+\cs_new_eq:NN \seq_push:Nv \seq_put_left:Nv
+\cs_new_eq:NN \seq_push:No \seq_put_left:No
+\cs_new_eq:NN \seq_push:Nx \seq_put_left:Nx
+\cs_new_eq:NN \seq_push:cn \seq_put_left:cn
+\cs_new_eq:NN \seq_push:cV \seq_put_left:cV
+\cs_new_eq:NN \seq_push:cv \seq_put_left:cv
+\cs_new_eq:NN \seq_push:co \seq_put_left:co
+\cs_new_eq:NN \seq_push:cx \seq_put_left:cx
+\cs_new_eq:NN \seq_gpush:Nn \seq_gput_left:Nn
+\cs_new_eq:NN \seq_gpush:NV \seq_gput_left:NV
+\cs_new_eq:NN \seq_gpush:Nv \seq_gput_left:Nv
+\cs_new_eq:NN \seq_gpush:No \seq_gput_left:No
+\cs_new_eq:NN \seq_gpush:Nx \seq_gput_left:Nx
+\cs_new_eq:NN \seq_gpush:cn \seq_gput_left:cn
+\cs_new_eq:NN \seq_gpush:cV \seq_gput_left:cV
+\cs_new_eq:NN \seq_gpush:cv \seq_gput_left:cv
+\cs_new_eq:NN \seq_gpush:co \seq_gput_left:co
+\cs_new_eq:NN \seq_gpush:cx \seq_gput_left:cx
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\seq_get:NN, \seq_get:cN}
+% \UnitTested
+% \begin{macro}{\seq_pop:NN, \seq_pop:cN}
+% \UnitTested
+% \begin{macro}{\seq_gpop:NN, \seq_gpop:cN}
+% \UnitTested
+% In most cases, getting items from the stack does not need to specify
+% that this is from the left. So alias are provided.
+% \begin{macrocode}
+\cs_new_eq:NN \seq_get:NN \seq_get_left:NN
+\cs_new_eq:NN \seq_get:cN \seq_get_left:cN
+\cs_new_eq:NN \seq_pop:NN \seq_pop_left:NN
+\cs_new_eq:NN \seq_pop:cN \seq_pop_left:cN
+\cs_new_eq:NN \seq_gpop:NN \seq_gpop_left:NN
+\cs_new_eq:NN \seq_gpop:cN \seq_gpop_left:cN
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Viewing sequences}
+%
+% \begin{variable}{\l_seq_show_tl}
+% Used to store the material for display.
+% \begin{macrocode}
+\tl_new:N \l_seq_show_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\seq_show:N, \seq_show:c}
+% \UnitTested
+% \begin{macro}[aux]{\seq_show_aux:n}
+% \begin{macro}[aux]{\seq_show_aux:w}
+% The aim of the mapping here is to create a token list containing the
+% formatted sequence. The very first item needs the new line and \verb*|> |
+% removing, which is achieved using a \texttt{w}-type auxiliary. To avoid
+% a low-level \TeX{} error if there is an empty sequence, a simple test is
+% used to keep the output \enquote{clean}.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \seq_show:N #1
+ {
+ \seq_if_empty:NTF #1
+ {
+ \iow_term:x { Sequence~\token_to_str:N #1 \c_space_tl is~empty }
+ \tl_show:n { }
+ }
+ {
+ \iow_term:x
+ {
+ Sequence~\token_to_str:N #1 \c_space_tl
+ contains~the~items~(without~outer~braces):
+ }
+ \tl_set:Nx \l_seq_show_tl
+ { \seq_map_function:NN #1 \seq_show_aux:n }
+ \etex_showtokens:D \exp_after:wN \exp_after:wN \exp_after:wN
+ { \exp_after:wN \seq_show_aux:w \l_seq_show_tl }
+ }
+ }
+\cs_new:Npn \seq_show_aux:n #1
+ {
+ \iow_newline: > \c_space_tl \c_space_tl
+ \iow_char:N \{ \exp_not:n {#1} \iow_char:N \}
+ }
+\cs_new:Npn \seq_show_aux:w #1 > ~ { }
+\cs_generate_variant:Nn \seq_show:N { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Experimental functions}
+%
+% \begin{macro}[aux]{\seq_if_empty_break_return_false:N}
+% The name says it all: of the sequence is empty, returns logical
+% \texttt{false}.
+% \begin{macrocode}
+\cs_new_nopar:Npn \seq_if_empty_break_return_false:N #1
+ {
+ \if_meaning:w #1 \c_empty_tl
+ \prg_return_false:
+ \exp_after:wN \seq_break:
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[TF]{\seq_get_left:NN, \seq_get_left:cN}
+% \begin{macro}[TF]{\seq_get_right:NN, \seq_get_right:cN}
+% Getting from the left or right with a check on the results.
+% \begin{macrocode}
+\prg_new_protected_conditional:Npnn \seq_get_left:NN #1 #2 { T , F , TF }
+ {
+ \seq_if_empty_break_return_false:N #1
+ \exp_after:wN \seq_get_left_aux:Nw #1 \q_stop #2
+ \prg_return_true:
+ \seq_break:
+ \seq_break_point:n { }
+ }
+\prg_new_protected_conditional:Npnn \seq_get_right:NN #1#2 { T , F , TF }
+ {
+ \seq_if_empty_break_return_false:N #1
+ \seq_get_right_aux:NN #1#2
+ \prg_return_true: \seq_break:
+ \seq_break_point:n { }
+ }
+\cs_generate_variant:Nn \seq_get_left:NNT { c }
+\cs_generate_variant:Nn \seq_get_left:NNF { c }
+\cs_generate_variant:Nn \seq_get_left:NNTF { c }
+\cs_generate_variant:Nn \seq_get_right:NNT { c }
+\cs_generate_variant:Nn \seq_get_right:NNF { c }
+\cs_generate_variant:Nn \seq_get_right:NNTF { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[TF]{\seq_pop_left:NN, \seq_pop_left:cN}
+% \begin{macro}[TF]{\seq_gpop_left:NN, \seq_gpop_left:cN}
+% \begin{macro}[TF]{\seq_pop_right:NN, \seq_pop_right:cN}
+% \begin{macro}[TF]{\seq_gpop_right:NN, \seq_gpop_right:cN}
+% More or less the same for popping.
+% \begin{macrocode}
+\prg_new_protected_conditional:Npnn \seq_pop_left:NN #1#2 { T , F , TF }
+ {
+ \seq_if_empty_break_return_false:N #1
+ \exp_after:wN \seq_pop_left_aux:NnwNNN #1 \q_stop \tl_set:Nn #1#2
+ \prg_return_true: \seq_break:
+ \seq_break_point:n { }
+ }
+\prg_new_protected_conditional:Npnn \seq_gpop_left:NN #1#2 { T , F , TF }
+ {
+ \seq_if_empty_break_return_false:N #1
+ \exp_after:wN \seq_pop_left_aux:NnwNNN #1 \q_stop \tl_gset:Nn #1#2
+ \prg_return_true: \seq_break:
+ \seq_break_point:n { }
+ }
+\prg_new_protected_conditional:Npnn \seq_pop_right:NN #1#2 { T , F , TF }
+ {
+ \seq_if_empty_break_return_false:N #1
+ \seq_pop_right_aux_ii:NNN \tl_set:Nx #1 #2
+ \prg_return_true: \seq_break:
+ \seq_break_point:n { }
+ }
+\prg_new_protected_conditional:Npnn \seq_gpop_right:NN #1#2 { T , F , TF }
+ {
+ \seq_if_empty_break_return_false:N #1
+ \seq_pop_right_aux_ii:NNN \tl_gset:Nx #1 #2
+ \prg_return_true: \seq_break:
+ \seq_break_point:n { }
+ }
+\cs_generate_variant:Nn \seq_pop_left:NNT { c }
+\cs_generate_variant:Nn \seq_pop_left:NNF { c }
+\cs_generate_variant:Nn \seq_pop_left:NNTF { c }
+\cs_generate_variant:Nn \seq_gpop_left:NNT { c }
+\cs_generate_variant:Nn \seq_gpop_left:NNF { c }
+\cs_generate_variant:Nn \seq_gpop_left:NNTF { c }
+\cs_generate_variant:Nn \seq_pop_right:NNT { c }
+\cs_generate_variant:Nn \seq_pop_right:NNF { c }
+\cs_generate_variant:Nn \seq_pop_right:NNTF { c }
+\cs_generate_variant:Nn \seq_gpop_right:NNT { c }
+\cs_generate_variant:Nn \seq_gpop_right:NNF { c }
+\cs_generate_variant:Nn \seq_gpop_right:NNTF { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\seq_length:N, \seq_length:c}
+% \begin{macro}[aux]{\seq_length_aux:n}
+% Counting the items in a sequence is done using the same approach as for
+% other length functions: turn each entry into a \texttt{+1} then use
+% integer evaluation to actually do the mathematics.
+% \begin{macrocode}
+\cs_new:Npn \seq_length:N #1
+ {
+ \int_eval:n
+ {
+ 0
+ \seq_map_function:NN #1 \seq_length_aux:n
+ }
+ }
+\cs_new:Npn \seq_length_aux:n #1 { +1 }
+\cs_generate_variant:Nn \seq_length:N { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\seq_item:Nn, \seq_item:cn}
+% \begin{macro}[aux]{\seq_item_aux:nnn}
+% The idea here is to find the offset of the item from the left, then use
+% a loop to grab the correct item. If the resulting offset is too large,
+% then the stop code |{ ? \seq_break } { }| will be used by the auxiliary,
+% terminating the loop and returning nothing at all.
+% \begin{macrocode}
+\cs_new_nopar:Npn \seq_item:Nn #1#2
+ {
+ \exp_last_unbraced:Nfo \seq_item_aux:nnn
+ {
+ \int_eval:n
+ {
+ \int_compare:nNnT {#2} < \c_zero
+ { \seq_length:N #1 + }
+ #2
+ }
+ }
+ #1
+ { ? \seq_break: }
+ { }
+ \seq_break_point:n { }
+ }
+\cs_new_nopar:Npn \seq_item_aux:nnn #1#2#3
+ {
+ \use_none:n #2
+ \int_compare:nNnTF {#1} = \c_zero
+ { \seq_break:n {#3} }
+ { \exp_args:Nf \seq_item_aux:nnn { #1 - 1 } }
+ }
+\cs_generate_variant:Nn \seq_item:Nn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\seq_use:N, \seq_use:c}
+% A simple short cut for a mapping.
+% \begin{macrocode}
+\cs_new_nopar:Npn \seq_use:N #1 { \seq_map_function:NN #1 \use:n }
+\cs_generate_variant:Nn \seq_use:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \seq_mapthread_function:NNN, \seq_mapthread_function:NcN,
+% \seq_mapthread_function:cNN, \seq_mapthread_function:ccN
+% }
+% \begin{macro}[aux]{\seq_mapthread_function_aux:NN}
+% \begin{macro}[aux]{\seq_mapthread_function_aux:Nnnwnn}
+% The idea here is to first expand both of the sequences, adding the usual
+% |{ ? \seq_break: } { }| to the end of each on. This is most conveniently
+% done in two steps using an auxiliary function. The mapping then throws
+% away the first token of |#2| and |#5|, which for items in the sequences
+% will both be \cs{seq_item:n}. The function to be mapped will then be
+% applied to the two entries. When the code hits the end of one of the
+% sequences, the break material will stop the entire loop and tidy up. This
+% avoids needing to find the length of the two sequences, or worrying about
+% which is longer.
+% \begin{macrocode}
+\cs_new_nopar:Npn \seq_mapthread_function:NNN #1#2#3
+ {
+ \exp_after:wN \seq_mapthread_function_aux:NN
+ \exp_after:wN #3
+ \exp_after:wN #1
+ #2
+ { ? \seq_break: } { }
+ \seq_break_point:n { }
+ }
+\cs_new_nopar:Npn \seq_mapthread_function_aux:NN #1#2
+ {
+ \exp_after:wN \seq_mapthread_function_aux:Nnnwnn
+ \exp_after:wN #1
+ #2
+ { ? \seq_break: } { }
+ \q_stop
+ }
+\cs_new:Npn \seq_mapthread_function_aux:Nnnwnn #1#2#3#4 \q_stop #5#6
+ {
+ \use_none:n #2
+ \use_none:n #5
+ #1 {#3} {#6}
+ \seq_mapthread_function_aux:Nnnwnn #1 #4 \q_stop
+ }
+\cs_generate_variant:Nn \seq_mapthread_function:NNN { Nc }
+\cs_generate_variant:Nn \seq_mapthread_function:NNN { c , cc }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \seq_set_from_clist:NN, \seq_set_from_clist:cN,
+% \seq_set_from_clist:Nc, \seq_set_from_clist:cc,
+% \seq_set_from_clist:Nn, \seq_set_from_clist:cn
+% }
+% \begin{macro}
+% {
+% \seq_gset_from_clist:NN, \seq_gset_from_clist:cN,
+% \seq_gset_from_clist:Nc, \seq_gset_from_clist:cc,
+% \seq_gset_from_clist:Nn, \seq_gset_from_clist:cn
+% }
+% \begin{macro}[aux]{\seq_wrap_item:n}
+% Setting a sequence from a comma-separated list is done using a simple
+% mapping.
+% \begin{macrocode}
+\cs_new_protected:Npn \seq_set_from_clist:NN #1#2
+ {
+ \tl_set:Nx #1
+ { \clist_map_function:NN #2 \seq_wrap_item:n }
+ }
+\cs_new_protected:Npn \seq_set_from_clist:Nn #1#2
+ {
+ \tl_set:Nx #1
+ { \clist_map_function:nN {#2} \seq_wrap_item:n }
+ }
+\cs_new_protected:Npn \seq_gset_from_clist:NN #1#2
+ {
+ \tl_gset:Nx #1
+ { \clist_map_function:NN #2 \seq_wrap_item:n }
+ }
+\cs_new_protected:Npn \seq_gset_from_clist:Nn #1#2
+ {
+ \tl_gset:Nx #1
+ { \clist_map_function:nN {#2} \seq_wrap_item:n }
+ }
+\cs_new:Npn \seq_wrap_item:n #1 { \exp_not:n { \seq_item:n {#1} } }
+\cs_generate_variant:Nn \seq_set_from_clist:NN { Nc }
+\cs_generate_variant:Nn \seq_set_from_clist:NN { c , cc }
+\cs_generate_variant:Nn \seq_set_from_clist:Nn { c }
+\cs_generate_variant:Nn \seq_gset_from_clist:NN { Nc }
+\cs_generate_variant:Nn \seq_gset_from_clist:NN { c , cc }
+\cs_generate_variant:Nn \seq_gset_from_clist:Nn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Deprecated interfaces}
+%
+% A few functions which are no longer documented: these were moved
+% here on or before 2011-04-20, and will be removed entirely by
+% 2011-07-20.
+%
+% \begin{macro}{\seq_top:NN, \seq_top:cN}
+% These are old stack functions.
+% \begin{macrocode}
+\cs_new_eq:NN \seq_top:NN \seq_get_left:NN
+\cs_new_eq:NN \seq_top:cN \seq_get_left:cN
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\seq_display:N, \seq_display:c}
+% An older name for \cs{seq_show:N}.
+% \begin{macrocode}
+\cs_new_eq:NN \seq_display:N \seq_show:N
+\cs_new_eq:NN \seq_display:c \seq_show:c
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</initex|package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex \ No newline at end of file
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3skip.dtx b/Master/texmf-dist/source/latex/l3kernel/l3skip.dtx
new file mode 100644
index 00000000000..ecd3ca2e397
--- /dev/null
+++ b/Master/texmf-dist/source/latex/l3kernel/l3skip.dtx
@@ -0,0 +1,1675 @@
+% \iffalse meta-comment
+%
+%% File: l3skip.dtx Copyright (C) 2004-2011 Frank Mittelbach, 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 "expl3 bundle" (The Work in LPPL)
+%% and all files in that bundle must be distributed together.
+%%
+%% The released version of this bundle is available from CTAN.
+%%
+%% -----------------------------------------------------------------------
+%%
+%% The development version of the bundle can be found at
+%%
+%% http://www.latex-project.org/svnroot/experimental/trunk/
+%%
+%% for those people who are interested.
+%%
+%%%%%%%%%%%
+%% NOTE: %%
+%%%%%%%%%%%
+%%
+%% Snapshots taken from the repository represent work in progress and may
+%% not work or may contain conflicting material! We therefore ask
+%% people _not_ to put them into distributions, archives, etc. without
+%% prior consultation with the LaTeX3 Project.
+%%
+%% -----------------------------------------------------------------------
+%
+%<*driver|package>
+\RequirePackage{l3names}
+\GetIdInfo$Id: l3skip.dtx 2478 2011-06-19 21:34:23Z joseph $
+ {L3 Experimental dimensions and skips}
+%</driver|package>
+%<*driver>
+\documentclass[full]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3skip} package\\ Dimensions and skips^^A
+% \thanks{This file describes v\ExplFileVersion,
+% last revised \ExplFileDate.}^^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 \ExplFileDate}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% \LaTeX3 provides two general length variables: \texttt{dim} and
+% \texttt{skip}. Lengths stored as \texttt{dim} variables have a fixed
+% length, whereas \texttt{skip} lengths have a rubber (stretch/shrink)
+% component. In addition, the \texttt{muskip} type is available for
+% use in math mode: this is a special form of \texttt{skip} where the
+% lengths involved are determined by the current math font (in
+% \texttt{mu)}. There are common features in the creation and setting of
+% length variables, but for clarity the functions are grouped by variable
+% type.
+%
+% \section{Creating and initialising \texttt{dim} variables}
+%
+% \begin{function}{\dim_new:N, \dim_new:c}
+% \begin{syntax}
+% \cs{dim_new:N} \meta{dimension}
+% \end{syntax}
+% Creates a new \meta{dimension} or raises an error if the name is
+% already taken. The declaration is global. The \meta{dimension}
+% will initially be equal to $0$\,pt.
+% \end{function}
+%
+% \begin{function}{\dim_zero:N, \dim_zero:c}
+% \begin{syntax}
+% \cs{dim_zero:N} \meta{dimension}
+% \end{syntax}
+% Sets \meta{dimension} to $0$\,pt within the scope of the current
+% \TeX{} group.
+% \end{function}
+%
+% \begin{function}{\dim_gzero:N, \dim_gzero:c}
+% \begin{syntax}
+% \cs{dim_gzero:N} \meta{dimension}
+% \end{syntax}
+% Sets \meta{dimension} to $0$\,pt globally, \emph{i.e.}~not
+% restricted by the current \TeX{} group level.
+% \end{function}
+%
+% \section{Setting \texttt{dim} variables}
+%
+% \begin{function}{\dim_add:Nn, \dim_add:cn}
+% \begin{syntax}
+% \cs{dim_add:Nn} \meta{dimension} \Arg{dimension expression}
+% \end{syntax}
+% Adds the result of the \meta{dimension expression} to the current
+% content of the \meta{dimension}. This assignment is local.
+% \end{function}
+%
+% \begin{function}{\dim_gadd:Nn, \dim_gadd:cn}
+% \begin{syntax}
+% \cs{dim_gadd:Nn} \meta{dimension} \Arg{dimension expression}
+% \end{syntax}
+% Adds the result of the \meta{dimension expression} to the
+% current content of the \meta{dimension}. This assignment is global.
+% \end{function}
+%
+% \begin{function}{\dim_set:Nn, \dim_set:cn}
+% \begin{syntax}
+% \cs{dim_set:Nn} \meta{dimension} \Arg{dimension expression}
+% \end{syntax}
+% Sets \meta{dimension} to the value of \meta{dimension expression}, which
+% must evaluate to a length with units. This assignment is
+% restricted to the current \TeX{} group.
+% \end{function}
+%
+% \begin{function}{\dim_gset:Nn, \dim_gset:cn}
+% \begin{syntax}
+% \cs{dim_gset:Nn} \meta{dimension} \Arg{dimension expression}
+% \end{syntax}
+% Sets \meta{dimension} to the value of \meta{dimension expression}, which
+% must evaluate to a length with units and may include a rubber
+% component (for example |1 cm plus 0.5 cm|. This assignment is
+% global and is not limited to the current \TeX{} group level.
+% \end{function}
+%
+% \begin{function}
+% {\dim_set_eq:NN, \dim_set_eq:cN, \dim_set_eq:Nc, \dim_set_eq:cc}
+% \begin{syntax}
+% \cs{dim_set_eq:NN} \meta{dimension1} \meta{dimension2}
+% \end{syntax}
+% Sets the content of \meta{dimension1} equal to that of
+% \meta{dimension2}. This assignment is restricted to the current
+% \TeX{} group level.
+% \end{function}
+%
+% \begin{function}
+% {\dim_gset_eq:NN, \dim_gset_eq:cN, \dim_gset_eq:Nc, \dim_gset_eq:cc}
+% \begin{syntax}
+% \cs{dim_gset_eq:NN} \meta{dimension1} \meta{dimension2}
+% \end{syntax}
+% Sets the content of \meta{dimension1} equal to that of \meta{dimension2}.
+% This assignment is global and so is not limited by the current
+% \TeX{} group level.
+% \end{function}
+%
+% \begin{function}{\dim_set_max:Nn, \dim_set_max:cn}
+% \begin{syntax}
+% \cs{dim_set_max:Nn} \meta{dimension} \Arg{dimension expression}
+% \end{syntax}
+% Compares the current value of the \meta{dimension} with that of the
+% \meta{dimension expression}, and sets the \meta{dimension} to the
+% larger of these two value. This assignment is local to the current
+% \TeX{} group.
+% \end{function}
+%
+% \begin{function}{\dim_gset_max:Nn, \dim_gset_max:cn}
+% \begin{syntax}
+% \cs{dim_gset_max:Nn} \meta{dimension} \Arg{dimension expression}
+% \end{syntax}
+% Compares the current value of the \meta{dimension} with that of the
+% \meta{dimension expression}, and sets the \meta{dimension} to the
+% larger of these two value. This assignment is global.
+% \end{function}
+%
+% \begin{function}{\dim_set_min:Nn, \dim_set_min:cn}
+% \begin{syntax}
+% \cs{dim_set_min:Nn} \meta{dimension} \Arg{dimension expression}
+% \end{syntax}
+% Compares the current value of the \meta{dimension} with that of the
+% \meta{dimension expression}, and sets the \meta{dimension} to the
+% smaller of these two value. This assignment is local to the current
+% \TeX{} group.
+% \end{function}
+%
+% \begin{function}{\dim_gset_min:Nn, \dim_gset_min:cn}
+% \begin{syntax}
+% \cs{dim_gset_min:Nn} \meta{dimension} \Arg{dimension expression}
+% \end{syntax}
+% Compares the current value of the \meta{dimension} with that of the
+% \meta{dimension expression}, and sets the \meta{dimension} to the
+% smaller of these two value. This assignment is global.
+% \end{function}
+%
+% \begin{function}{\dim_sub:Nn, \dim_sub:cn}
+% \begin{syntax}
+% \cs{dim_sub:Nn} \meta{dimension} \Arg{dimension expression}
+% \end{syntax}
+% Subtracts the result of the \meta{dimension expression} to the
+% current content of the \meta{dimension}. This assignment is local.
+% \end{function}
+%
+% \begin{function}{\dim_gsub:Nn, \dim_gsub:cn}
+% \begin{syntax}
+% \cs{dim_gsub:Nn} \meta{dimension} \Arg{dimension expression}
+% \end{syntax}
+% Subtracts the result of the \meta{dimension expression} to the
+% current content of the \meta{dimension}. This assignment is global.
+% \end{function}
+%
+% \section{Utilities for dimension calculations}
+%
+% \begin{function}[EXP]{\dim_ratio:nn}
+% \begin{syntax}
+% \cs{dim_ratio:nn} \Arg{dimexpr1} \Arg{dimexpr2}
+% \end{syntax}
+% Parses the two \meta{dimension expressions} and converts the ratio of
+% the two to a form suitable for use inside a \meta{dimension expression}.
+% This ratio is then left in the input stream, allowing syntax such as
+% \begin{verbatim}
+% \dim_set:Nn \l_my_dim
+% { 10 pt * \dim_ratio:nn { 5 pt } { 10 pt } }
+% \end{verbatim}
+% The output of \cs{dim_ratio:nn} on full expansion is a ration expression
+% between two integers, with all distances converted to scaled points.
+% Thus
+% \begin{verbatim}
+% \tl_set:Nx \l_my_tl { \dim_ratio:nn { 5 pt } { 10 pt } }
+% \tl_show:N \l_my_tl
+% \end{verbatim}
+% will display |327680/655360| on the terminal.
+% \end{function}
+%
+% \section{Dimension expression conditionals}
+%
+% \begin{function}[EXP,pTF]{\dim_compare:nNn}
+% \begin{syntax}
+% \cs{dim_compare_p:nNn}
+% ~~\Arg{dimexpr1} \meta{relation} \Arg{dimexpr2}
+% \cs{dim_compare:nNnTF}
+% ~~\Arg{dimexpr1} \meta{relation} \Arg{dimexpr2}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% This function first evaluates each of the \meta{dimension expressions}
+% as described for \cs{dim_eval:n}. The two results are then
+% compared using the \meta{relation}:
+% \begin{center}
+% \begin{tabular}{ll}
+% Equal & |=| \\
+% Greater than & |>| \\
+% Less than & |<| \\
+% \end{tabular}
+% \end{center}
+% The branching versions then leave either \meta{true code} or
+% \meta{false code} in the input stream, as appropriate to the truth
+% of the test and the variant of the function chosen. The logical
+% truth of the test is left in the input stream by the predicate
+% version.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\dim_compare:n}
+% \begin{syntax}
+% \cs{dim_compare_p:n}
+% ~~\{ \meta{dimexpr1} \meta{relation} \meta{dimexpr2} \}
+% \cs{dim_compare:nTF}
+% ~~\{ \meta{dimexpr1} \meta{relation} \meta{dimexpr2} \}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% This function first evaluates each of the \meta{dimension expressions}
+% as described for \cs{dim_eval:n}. The two results are then
+% compared using the \meta{relation}:
+% \begin{center}
+% \begin{tabular}{ll}
+% Equal & |=| or |==| \\
+% Greater than or equal to & |=>| \\
+% Greater than & |>| \\
+% Less than or equal to & |=<| \\
+% Less than & |<| \\
+% Not equal & |!=| \\
+% \end{tabular}
+% \end{center}
+% The branching versions then leave either \meta{true code} or
+% \meta{false code} in the input stream, as appropriate to the truth
+% of the test and the variant of the function chosen. The logical
+% truth of the test is left in the input stream by the predicate
+% version.
+% \end{function}
+%
+% \section{Dimension expression loops}
+%
+% \begin{function}[EXP]{\dim_do_while:nNnn}
+% \begin{syntax}
+% \cs{dim_do_while:nNnn}
+% ~~\Arg{dimexpr1} \meta{relation} \Arg{dimexpr2} \Arg{code}
+% \end{syntax}
+% Evaluates the relationship between the two \meta{dimension expressions}
+% as described for \cs{dim_compare:nNnTF}, and then places the
+% \meta{code} in the input stream if the \meta{relation} is
+% \texttt{true}. After the \meta{code} has been processed by \TeX{} the
+% test will be repeated, and a loop will occur until the test is
+% \texttt{false}.
+% \end{function}
+%
+% \begin{function}[EXP]{\dim_do_until:nNnn}
+% \begin{syntax}
+% \cs{dim_do_until:nNnn}
+% ~~\Arg{dimexpr1} \meta{relation} \Arg{dimexpr2} \Arg{code}
+% \end{syntax}
+% Evaluates the relationship between the two \meta{dimension expressions}
+% as described for \cs{dim_compare:nNnTF}, and then places the
+% \meta{code} in the input stream if the \meta{relation} is
+% \texttt{false}. After the \meta{code} has been processed by \TeX{} the
+% test will be repeated, and a loop will occur until the test is
+% \texttt{true}.
+% \end{function}
+%
+% \begin{function}[EXP]{\dim_until_do:nNnn}
+% \begin{syntax}
+% \cs{dim_until_do:nNnn}
+% ~~\Arg{dimexpr1} \meta{relation} \Arg{dimexpr2} \Arg{code}
+% \end{syntax}
+% Places the \meta{code} in the input stream for \TeX{} to process, and
+% then evaluates the relationship between the two
+% \meta{dimension expressions} as described for \cs{dim_compare:nNnTF}.
+% If the test is \texttt{false} then the \meta{code} will be inserted
+% into the input stream again and a loop will occur until the
+% \meta{relation} is \texttt{true}.
+% \end{function}
+%
+% \begin{function}[EXP]{\dim_while_do:nNnn}
+% \begin{syntax}
+% \cs{dim_while_do:nNnn}
+% ~~\Arg{dimexpr1} \meta{relation} \Arg{dimexpr2} \Arg{code}
+% \end{syntax}
+% Places the \meta{code} in the input stream for \TeX{} to process, and
+% then evaluates the relationship between the two
+% \meta{dimension expressions} as described for \cs{dim_compare:nNnTF}.
+% If the test is \texttt{true} then the \meta{code} will be inserted
+% into the input stream again and a loop will occur until the
+% \meta{relation} is \texttt{false}.
+% \end{function}
+%
+% \begin{function}[EXP]{\dim_do_while:nn}
+% \begin{syntax}
+% \cs{dim_do_while:nNnn}
+% ~~\{ \meta{dimexpr1} \meta{relation} \meta{dimexpr2} \} \Arg{code}
+% \end{syntax}
+% Evaluates the relationship between the two \meta{dimension expressions}
+% as described for \cs{dim_compare:nTF}, and then places the
+% \meta{code} in the input stream if the \meta{relation} is
+% \texttt{true}. After the \meta{code} has been processed by \TeX{} the
+% test will be repeated, and a loop will occur until the test is
+% \texttt{false}.
+% \end{function}
+%
+% \begin{function}[EXP]{\dim_do_until:nn}
+% \begin{syntax}
+% \cs{dim_do_until:nn}
+% ~~\{ \meta{dimexpr1} \meta{relation} \meta{dimexpr2} \} \Arg{code}
+% \end{syntax}
+% Evaluates the relationship between the two \meta{dimension expressions}
+% as described for \cs{dim_compare:nTF}, and then places the
+% \meta{code} in the input stream if the \meta{relation} is
+% \texttt{false}. After the \meta{code} has been processed by \TeX{} the
+% test will be repeated, and a loop will occur until the test is
+% \texttt{true}.
+% \end{function}
+%
+% \begin{function}[EXP]{\dim_until_do:nn}
+% \begin{syntax}
+% \cs{dim_until_do:nn}
+% ~~\{ \meta{dimexpr1} \meta{relation} \meta{dimexpr2} \} \Arg{code}
+% \end{syntax}
+% Places the \meta{code} in the input stream for \TeX{} to process, and
+% then evaluates the relationship between the two
+% \meta{dimension expressions} as described for \cs{dim_compare:nTF}.
+% If the test is \texttt{false} then the \meta{code} will be inserted
+% into the input stream again and a loop will occur until the
+% \meta{relation} is \texttt{true}.
+% \end{function}
+%
+% \begin{function}[EXP]{\dim_while_do:nn}
+% \begin{syntax}
+% \cs{dim_while_do:nn}
+% ~~\{ \meta{dimexpr1} \meta{relation} \meta{dimexpr2} \} \Arg{code}
+% \end{syntax}
+% Places the \meta{code} in the input stream for \TeX{} to process, and
+% then evaluates the relationship between the two
+% \meta{dimension expressions} as described for \cs{dim_compare:nTF}.
+% If the test is \texttt{true} then the \meta{code} will be inserted
+% into the input stream again and a loop will occur until the
+% \meta{relation} is \texttt{false}.
+% \end{function}
+%
+% \section{Using \texttt{dim} expressions and variables}
+%
+% \begin{function}[EXP]{\dim_eval:n}
+% \begin{syntax}
+% \cs{dim_eval:n} \Arg{dimension expression}
+% \end{syntax}
+% Evaluates the \meta{dimension expression}, expanding any
+% dimensions and token list variables within the \meta{expression}
+% to their content (without requiring \cs{dim_use:N}/\cs{tl_use:N})
+% and applying the standard mathematical rules. The result of the
+% calculation is left in the input stream as a
+% \meta{dimension denotation} after two expansions. This will be
+% expressed in points (\texttt{pt}), and will require suitable
+% termination if used in a \TeX{}-style assignment as it is \emph{not}
+% an \meta{internal dimension}.
+% \end{function}
+%
+% \begin{function}[EXP]{\dim_use:N, \dim_use:c}
+% \begin{syntax}
+% \cs{dim_use:N} \meta{dimension}
+% \end{syntax}
+% Recovers the content of a \meta{dimension} and places it directly
+% in the input stream. An error will be raised if the variable does
+% not exist or if it is invalid. Can be omitted in places where a
+% \meta{dimension} is required (such as in the argument of
+% \cs{dim_eval:n}).
+% \begin{texnote}
+% \cs{dim_use:N} is the \TeX{} primitive \cs{the}: this is one of
+% several \LaTeX3 names for this primitive.
+% \end{texnote}
+% \end{function}
+%
+% \section{Viewing \texttt{dim} variables}
+%
+% \begin{function}{\dim_show:N, \dim_show:c}
+% \begin{syntax}
+% \cs{dim_show:N} \meta{dimension}
+% \end{syntax}
+% Displays the value of the \meta{dimension} on the terminal.
+% \end{function}
+%
+% \section{Constant dimensions}
+%
+% \begin{variable}{\c_max_dim}
+% The maximum value that can be stored as a dimension or skip (these
+% are equivalent).
+% \end{variable}
+%
+% \begin{variable}{\c_zero_dim}
+% A zero length as a dimension or a skip (these are equivalent).
+% \end{variable}
+%
+% \section{Scratch dimensions}
+%
+% \begin{variable}{\l_tmpa_dim, \l_tmpb_dim, \l_tmpc_dim}
+% Scratch dimension for local assignment. These are never used by
+% the kernel code, and so are safe for use with any \LaTeX3-defined
+% function. However, they may be overwritten by other non-kernel
+% code and so should only be used for short-term storage.
+% \end{variable}
+%
+% \begin{variable}{\g_tmpa_dim, \g_tmpb_dim}
+% Scratch dimension for global assignment. These are never used by
+% the kernel code, and so are safe for use with any \LaTeX3-defined
+% function. However, they may be overwritten by other non-kernel
+% code and so should only be used for short-term storage.
+% \end{variable}
+%
+% \section{Creating and initialising \texttt{skip} variables}
+%
+% \begin{function}{\skip_new:N, \skip_new:c}
+% \begin{syntax}
+% \cs{skip_new:N} \meta{skip}
+% \end{syntax}
+% Creates a new \meta{skip} or raises an error if the name is
+% already taken. The declaration is global. The \meta{skip}
+% will initially be equal to $0$\,pt.
+% \end{function}
+%
+% \begin{function}{\skip_zero:N, \skip_zero:c}
+% \begin{syntax}
+% \cs{skip_zero:N} \meta{skip}
+% \end{syntax}
+% Sets \meta{skip} to $0$\,pt within the scope of the current
+% \TeX{} group.
+% \end{function}
+%
+% \begin{function}{\skip_gzero:N, \skip_gzero:c}
+% \begin{syntax}
+% \cs{skip_gzero:N} \meta{skip}
+% \end{syntax}
+% Sets \meta{skip} to $0$\,pt globally, \emph{i.e.}~not
+% restricted by the current \TeX{} group level.
+% \end{function}
+%
+% \section{Setting \texttt{skip} variables}
+%
+% \begin{function}{\skip_add:Nn, \skip_add:cn}
+% \begin{syntax}
+% \cs{skip_add:Nn} \meta{skip} \Arg{skip expression}
+% \end{syntax}
+% Adds the result of the \meta{skip expression} to the current
+% content of the \meta{skip}. This assignment is local.
+% \end{function}
+%
+% \begin{function}{\skip_gadd:Nn, \skip_gadd:cn}
+% \begin{syntax}
+% \cs{skip_gadd:Nn} \meta{skip} \Arg{skip expression}
+% \end{syntax}
+% Adds the result of the \meta{skip expression} to the
+% current content of the \meta{skip}. This assignment is global.
+% \end{function}
+%
+% \begin{function}{\skip_set:Nn, \skip_set:cn}
+% \begin{syntax}
+% \cs{skip_set:Nn} \meta{skip} \Arg{skip expression}
+% \end{syntax}
+% Sets \meta{skip} to the value of \meta{skip expression}, which
+% must evaluate to a length with units and may include a rubber
+% component (for example |1 cm plus 0.5 cm|. This assignment is
+% restricted to the current \TeX{} group.
+% \end{function}
+%
+% \begin{function}
+% {\skip_gset_eq:NN, \skip_gset_eq:cN, \skip_gset_eq:Nc, \skip_gset_eq:cc}
+% \begin{syntax}
+% \cs{skip_gset_eq:NN} \meta{skip1} \meta{skip2}
+% \end{syntax}
+% Sets the content of \meta{skip1} equal to that of \meta{skip2}.
+% This assignment is global and so is not limited by the current
+% \TeX{} group level.
+% \end{function}
+%
+% \begin{function}{\skip_gset:Nn, \skip_gset:cn}
+% \begin{syntax}
+% \cs{skip_gset:Nn} \meta{skip} \Arg{skip expression}
+% \end{syntax}
+% Sets \meta{skip} to the value of \meta{skip expression}, which
+% must evaluate to a length with units and may include a rubber
+% component (for example |1 cm plus 0.5 cm|. This assignment is
+% global and is not limited to the current \TeX{} group level.
+% \end{function}
+%
+% \begin{function}
+% {\skip_set_eq:NN, \skip_set_eq:cN, \skip_set_eq:Nc, \skip_set_eq:cc}
+% \begin{syntax}
+% \cs{skip_set_eq:NN} \meta{skip1} \meta{skip2}
+% \end{syntax}
+% Sets the content of \meta{skip1} equal to that of
+% \meta{skip2}. This assignment is restricted to the current
+% \TeX{} group level.
+% \end{function}
+%
+% \begin{function}{\skip_sub:Nn, \skip_sub:cn}
+% \begin{syntax}
+% \cs{skip_sub:Nn} \meta{skip} \Arg{skip expression}
+% \end{syntax}
+% Subtracts the result of the \meta{skip expression} to the
+% current content of the \meta{skip}. This assignment is local.
+% \end{function}
+%
+% \begin{function}{\skip_gsub:Nn, \skip_gsub:cn}
+% \begin{syntax}
+% \cs{skip_gsub:Nn} \meta{skip} \Arg{skip expression}
+% \end{syntax}
+% Subtracts the result of the \meta{skip expression} to the
+% current content of the \meta{skip}. This assignment is global.
+% \end{function}
+%
+% \section{Skip expression conditionals}
+%
+% \begin{function}[EXP,pTF]{\skip_if_eq:nn}
+% \begin{syntax}
+% \cs{skip_if_eq_p:nn}
+% ~~\Arg{skipexpr1} \Arg{skipexpr2}
+% \cs{dim_compare:nTF}
+% ~~\Arg{skipexpr1} \Arg{skipexpr2}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% This function first evaluates each of the
+% \meta{skip expressions} as described for \cs{skip_eval:n}.
+% The two results are then compared for exact equality,
+% \emph{i.e.}~both the fixed and rubber components must be the same
+% for the test to be true. The branching versions then leave either
+% \meta{true code} or \meta{false code} in the input stream, as
+% appropriate to the truth of the test and the variant of the function
+% chosen. The logical truth of the test is left in the input stream by
+% the predicate version.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\skip_if_infinite_glue:n}
+% \begin{syntax}
+% \cs{skip_if_infinite_glue_p:n} \Arg{skipexpr}
+% \cs{skip_if_infinite_glue:nTF} \Arg{skipexpr}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% Evaluates the \meta{skip expression} as described for \cs{skip_eval:n},
+% and then tests if this contains an infinite stretch or shrink
+% component (or both).
+% The branching versions then leave either \meta{true code} or
+% \meta{false code} in the input stream, as appropriate to the truth
+% of the test and the variant of the function chosen. The logical
+% truth of the test is left in the input stream by the predicate
+% \end{function}
+%
+% \section{Using \texttt{skip} expressions and variables}
+%
+% \begin{function}[EXP]{\skip_eval:n}
+% \begin{syntax}
+% \cs{skip_eval:n} \Arg{skip expression}
+% \end{syntax}
+% Evaluates the \meta{skip expression}, expanding any skips
+% and token list variables within the \meta{expression}
+% to their content (without requiring \cs{skip_use:N}/\cs{tl_use:N})
+% and applying the standard mathematical rules. The result of the
+% calculation is left in the input stream as a \meta{glue denotation}
+% after two expansions. This will be expressed in points (\texttt{pt}),
+% and will require suitable termination if used in a \TeX{}-style
+% assignment as it is \emph{not} an \meta{internal glue}.
+% \end{function}
+%
+% \begin{function}[EXP]{\skip_use:N, \skip_use:c}
+% \begin{syntax}
+% \cs{skip_use:N} \meta{skip}
+% \end{syntax}
+% Recovers the content of a \meta{skip} and places it directly
+% in the input stream. An error will be raised if the variable does
+% not exist or if it is invalid. Can be omitted in places where a
+% \meta{dimension} is required (such as in the argument of
+% \cs{skip_eval:n}).
+% \begin{texnote}
+% \cs{skip_use:N} is the \TeX{} primitive \cs{the}: this is one of
+% several \LaTeX3 names for this primitive.
+% \end{texnote}
+% \end{function}
+%
+% \section{Viewing \texttt{skip} variables}
+%
+% \begin{function}{\skip_show:N, \skip_show:c}
+% \begin{syntax}
+% \cs{skip_show:N} \meta{skip}
+% \end{syntax}
+% Displays the value of the \meta{skip} on the terminal.
+% \end{function}
+%
+% \section{Constant skips}
+%
+% \begin{variable}{\c_max_skip}
+% The maximum value that can be stored as a dimension or skip (these
+% are equivalent).
+% \end{variable}
+%
+% \begin{variable}{\c_zero_skip}
+% A zero length as a dimension or a skip (these are equivalent).
+% \end{variable}
+%
+% \section{Scratch skips}
+%
+% \begin{variable}{\l_tmpa_skip, \l_tmpb_skip, \l_tmpc_skip}
+% Scratch skip for local assignment. These are never used by
+% the kernel code, and so are safe for use with any \LaTeX3-defined
+% function. However, they may be overwritten by other non-kernel
+% code and so should only be used for short-term storage.
+% \end{variable}
+%
+% \begin{variable}{\g_tmpa_skip, \g_tmpb_skip}
+% Scratch skip for global assignment. These are never used by
+% the kernel code, and so are safe for use with any \LaTeX3-defined
+% function. However, they may be overwritten by other non-kernel
+% code and so should only be used for short-term storage.
+% \end{variable}
+%
+% \section{Creating and initialising \texttt{muskip} variables}
+%
+% \begin{function}{\muskip_new:N, \muskip_new:c}
+% \begin{syntax}
+% \cs{muskip_new:N} \meta{muskip}
+% \end{syntax}
+% Creates a new \meta{muskip} or raises an error if the name is
+% already taken. The declaration is global. The \meta{muskip}
+% will initially be equal to $0$\,mu.
+% \end{function}
+%
+% \begin{function}{\muskip_zero:N, \muskip_zero:c}
+% \begin{syntax}
+% \cs{skip_zero:N} \meta{muskip}
+% \end{syntax}
+% Sets \meta{muskip} to $0$\,mu within the scope of the current
+% \TeX{} group.
+% \end{function}
+%
+% \begin{function}{\muskip_gzero:N, \muskip_gzero:c}
+% \begin{syntax}
+% \cs{muskip_gzero:N} \meta{muskip}
+% \end{syntax}
+% Sets \meta{muskip} to $0$\,mu globally, \emph{i.e.}~not
+% restricted by the current \TeX{} group level.
+% \end{function}
+%
+% \section{Setting \texttt{muskip} variables}
+%
+% \begin{function}{\muskip_add:Nn, \muskip_add:cn}
+% \begin{syntax}
+% \cs{muskip_add:Nn} \meta{muskip} \Arg{muskip expression}
+% \end{syntax}
+% Adds the result of the \meta{muskip expression} to the current
+% content of the \meta{muskip}. This assignment is local.
+% \end{function}
+%
+% \begin{function}{\muskip_gadd:Nn, \muskip_gadd:cn}
+% \begin{syntax}
+% \cs{muskip_gadd:Nn} \meta{muskip} \Arg{muskip expression}
+% \end{syntax}
+% Adds the result of the \meta{muskip expression} to the
+% current content of the \meta{muskip}. This assignment is global.
+% \end{function}
+%
+% \begin{function}{\muskip_set:Nn, \muskip_set:cn}
+% \begin{syntax}
+% \cs{muskip_set:Nn} \meta{muskip} \Arg{muskip expression}
+% \end{syntax}
+% Sets \meta{muskip} to the value of \meta{muskip expression}, which
+% must evaluate to a math length with units and may include a rubber
+% component (for example |1 mu plus 0.5 mu|. This assignment is
+% restricted to the current \TeX{} group.
+% \end{function}
+%
+% \begin{function}{\muskip_gset:Nn, \muskip_gset:cn}
+% \begin{syntax}
+% \cs{muskip_gset:Nn} \meta{muskip} \Arg{muskip expression}
+% \end{syntax}
+% Sets \meta{muskip} to the value of \meta{muskip expression}, which
+% must evaluate to a math length with units and may include a rubber
+% component (for example |1 mu plus 0.5 mu|. This assignment is
+% global and is not limited to the current \TeX{} group level.
+% \end{function}
+%
+% \begin{function}
+% {
+% \muskip_set_eq:NN, \muskip_set_eq:cN,
+% \muskip_set_eq:Nc, \muskip_set_eq:cc
+% }
+% \begin{syntax}
+% \cs{muskip_set_eq:NN} \meta{muskip1} \meta{muskip2}
+% \end{syntax}
+% Sets the content of \meta{muskip1} equal to that of
+% \meta{muskip2}. This assignment is restricted to the current
+% \TeX{} group level.
+% \end{function}
+%
+% \begin{function}
+% {
+% \muskip_gset_eq:NN, \muskip_gset_eq:cN,
+% \muskip_gset_eq:Nc, \muskip_gset_eq:cc
+% }
+% \begin{syntax}
+% \cs{muskip_gset_eq:NN} \meta{muskip1} \meta{muskip2}
+% \end{syntax}
+% Sets the content of \meta{muskip1} equal to that of \meta{muskip2}.
+% This assignment is global and so is not limited by the current
+% \TeX{} group level.
+% \end{function}
+%
+% \begin{function}{\muskip_sub:Nn, \muskip_sub:cn}
+% \begin{syntax}
+% \cs{muskip_sub:Nn} \meta{muskip} \Arg{muskip expression}
+% \end{syntax}
+% Subtracts the result of the \meta{muskip expression} to the
+% current content of the \meta{skip}. This assignment is local.
+% \end{function}
+%
+% \begin{function}{\muskip_gsub:Nn, \muskip_gsub:cn}
+% \begin{syntax}
+% \cs{muskip_gsub:Nn} \meta{muskip} \Arg{muskip expression}
+% \end{syntax}
+% Subtracts the result of the \meta{muskip expression} to the
+% current content of the \meta{muskip}. This assignment is global.
+% \end{function}
+%
+% \section{Using \texttt{muskip} expressions and variables}
+%
+% \begin{function}[EXP]{\muskip_eval:n}
+% \begin{syntax}
+% \cs{muskip_eval:n} \Arg{muskip expression}
+% \end{syntax}
+% Evaluates the \meta{muskip expression}, expanding any skips
+% and token list variables within the \meta{expression}
+% to their content (without requiring \cs{muskip_use:N}/\cs{tl_use:N})
+% and applying the standard mathematical rules. The result of the
+% calculation is left in the input stream as a \meta{muglue denotation}
+% after two expansions. This will be expressed in \texttt{mu},
+% and will require suitable termination if used in a \TeX{}-style
+% assignment as it is \emph{not} an \meta{internal muglue}.
+% \end{function}
+%
+% \begin{function}[EXP]{\muskip_use:N, \muskip_use:c}
+% \begin{syntax}
+% \cs{muskip_use:N} \meta{muskip}
+% \end{syntax}
+% Recovers the content of a \meta{skip} and places it directly
+% in the input stream. An error will be raised if the variable does
+% not exist or if it is invalid. Can be omitted in places where a
+% \meta{dimension} is required (such as in the argument of
+% \cs{muskip_eval:n}).
+% \begin{texnote}
+% \cs{muskip_use:N} is the \TeX{} primitive \cs{the}: this is one of
+% several \LaTeX3 names for this primitive.
+% \end{texnote}
+% \end{function}
+%
+% \section{Inserting skips into the output}
+%
+% \begin{function}{\skip_horizontal:N, \skip_horizontal:c, \skip_horizontal:n}
+% \begin{syntax}
+% \cs{skip_horizontal:N} \meta{skip}
+% \cs{skip_horizontal:n} \Arg{skipexpr}
+% \end{syntax}
+% Inserts a horizontal \meta{skip} into the current list.
+% \begin{texnote}
+% \cs{skip_horizontal:N} is the \TeX{} primitive \cs{hskip} renamed.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{\skip_vertical:N, \skip_vertical:c, \skip_vertical:n}
+% \begin{syntax}
+% \cs{skip_vertical:N} \meta{skip}
+% \cs{skip_vertical:n} \Arg{skipexpr}
+% \end{syntax}
+% Inserts a vertical \meta{skip} into the current list.
+% \begin{texnote}
+% \cs{skip_vertical:N} is the \TeX{} primitive \cs{vskip} renamed.
+% \end{texnote}
+% \end{function}
+%
+% \section{Viewing \texttt{muskip} variables}
+%
+% \begin{function}{\muskip_show:N, \muskip_show:c}
+% \begin{syntax}
+% \cs{muskip_show:N} \meta{muskip}
+% \end{syntax}
+% Displays the value of the \meta{muskip} on the terminal.
+% \end{function}
+%
+% \section{Internal functions}
+%
+% \begin{function}{\if_dim:w}
+% \begin{syntax}
+% \cs{if_dim:w} \meta{dimen1} \meta{relation} \meta{dimen1}
+% ~~\meta{true code}
+% \cs{else:}
+% ~~\meta{false}
+% \cs{fi:}
+% \end{syntax}
+% Compare two dimensions. The \meta{relation} is one of
+% |<|, |=| or |>| with category code $12$.
+% \begin{texnote}
+% This is the \TeX{} primitive \cs{ifdim}.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[EXP]{\dim_eval:w, \dim_eval_end:}
+% \begin{syntax}
+% \cs{dim_eval:w} \meta{dimexpr} \cs{dim_eval_end:}
+% \end{syntax}
+% Evaluates \meta{dimension expression} as described for \cs{dim_eval:n}.
+% The evaluation stops when an unexpandable token which is not a valid
+% part of a dimension is read or when \cs{dim_eval_end:} is
+% reached. The latter is gobbled by the scanner mechanism:
+% \cs{dim_eval_end:} itself is unexpandable but used correctly
+% the entire construct is expandable.
+% \begin{texnote}
+% This is the \eTeX{} primitive \cs{dimexpr}.
+% \end{texnote}
+% \end{function}
+%
+% \section{Experimental skip functions}
+%
+% \begin{function}{\skip_split_finite_else_action:nnNN}
+% \begin{syntax}
+% \cs{skip_split_finite_else_action:nnNN} \Arg{skipexpr} \Arg{action}
+% ~~\meta{dimen1} \meta{dimen2}
+% \end{syntax}
+% Checks if the \meta{skipexpr} contains finite glue. If it does then it
+% assigns
+% \meta{dimen1} the stretch component and \meta{dimen2} the shrink
+% component. If
+% it contains infinite glue set \meta{dimen1} and \meta{dimen2} to $0$\,pt
+% and place |#2| into the input stream: this is usually an error or
+% warning message of some sort.
+% \end{function}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3skip} implementation}
+%
+% \begin{macrocode}
+%<*initex|package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*package>
+\ProvidesExplPackage
+ {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
+\package_check_loaded_expl:
+%</package>
+% \end{macrocode}
+%
+% \subsection{Length primitives renamed}
+%
+% \begin{macro}{\if_dim:w}
+% \begin{macro}{\dim_eval:w}
+% \begin{macro}{\dim_eval_end:}
+% Primitives renamed.
+% \begin{macrocode}
+\cs_new_eq:NN \if_dim:w \tex_ifdim:D
+\cs_new_eq:NN \dim_eval:w \etex_dimexpr:D
+\cs_new_eq:NN \dim_eval_end: \tex_relax:D
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Creating and initialising \texttt{dim} variables}
+%
+% \begin{macro}{\dim_new:N,\dim_new:c}
+% Allocating \meta{dim} registers \ldots
+% \begin{macrocode}
+%<*initex>
+\alloc_new:nnnN { dim } \c_zero \c_max_register_int \tex_dimendef:D
+%</initex>
+%<*package>
+\cs_new_protected_nopar:Npn \dim_new:N #1
+ {
+ \chk_if_free_cs:N #1
+ \newdimen #1
+ }
+%</package>
+\cs_generate_variant:Nn \dim_new:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\dim_zero:N, \dim_zero:c}
+% \begin{macro}{\dim_gzero:N, \dim_gzero:c}
+% Reset the register to zero.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \dim_zero:N #1 { #1 \c_zero_dim }
+\cs_new_protected_nopar:Npn \dim_gzero:N { \pref_global:D \dim_zero:N }
+\cs_generate_variant:Nn \dim_zero:N { c }
+\cs_generate_variant:Nn \dim_gzero:N { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Setting \texttt{dim} variables}
+%
+% \begin{macro}{\dim_set:Nn, \dim_set:cn}
+% \begin{macro}{\dim_gset:Nn, \dim_gset:cn}
+% Setting dimensions is easy enough.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \dim_set:Nn #1#2
+ { #1 ~ \dim_eval:w #2 \dim_eval_end: }
+\cs_new_protected_nopar:Npn \dim_gset:Nn { \pref_global:D \dim_set:Nn }
+\cs_generate_variant:Nn \dim_set:Nn { c }
+\cs_generate_variant:Nn \dim_gset:Nn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\dim_set_eq:NN,\dim_set_eq:cN, \dim_set_eq:Nc,\dim_set_eq:cc}
+% \begin{macro}
+% {\dim_gset_eq:NN,\dim_gset_eq:cN, \dim_gset_eq:Nc,\dim_gset_eq:cc}
+% All straightforward.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \dim_set_eq:NN #1#2 { #1 = #2 }
+\cs_generate_variant:Nn \dim_set_eq:NN { c }
+\cs_generate_variant:Nn \dim_set_eq:NN { Nc , cc }
+\cs_new_protected_nopar:Npn \dim_gset_eq:NN #1#2 { \pref_global:D #1 = #2 }
+\cs_generate_variant:Nn \dim_gset_eq:NN { c }
+\cs_generate_variant:Nn \dim_gset_eq:NN { Nc , cc }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\dim_set_max:Nn, \dim_set_max:cn}
+% \begin{macro}{\dim_set_min:Nn, \dim_set_min:cn}
+% \begin{macro}{\dim_gset_max:Nn, \dim_gset_max:cn}
+% \begin{macro}{\dim_gset_min:Nn, \dim_gset_min:cn}
+% Setting maximum and minimum values is simply a case of so build-in
+% comparison. This only applies to dimensions as skips are not ordered.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \dim_set_max:Nn #1#2
+ { \dim_compare:nNnT {#1} < {#2} { \dim_set:Nn #1 {#2} } }
+\cs_new_protected_nopar:Npn \dim_gset_max:Nn #1#2
+ { \dim_compare:nNnT {#1} < {#2} { \dim_gset:Nn #1 {#2} } }
+\cs_new_protected_nopar:Npn \dim_set_min:Nn #1#2
+ { \dim_compare:nNnT {#1} > {#2} { \dim_set:Nn #1 {#2} } }
+\cs_new_protected_nopar:Npn \dim_gset_min:Nn #1#2
+ { \dim_compare:nNnT {#1} > {#2} { \dim_gset:Nn #1 {#2} } }
+\cs_generate_variant:Nn \dim_set_max:Nn { c }
+\cs_generate_variant:Nn \dim_gset_max:Nn { c }
+\cs_generate_variant:Nn \dim_set_min:Nn { c }
+\cs_generate_variant:Nn \dim_gset_min:Nn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\dim_add:Nn, \dim_add:cn}
+% \begin{macro}{\dim_gadd:Nn, \dim_gadd:cn}
+% \begin{macro}{\dim_sub:Nn, \dim_sub:cn}
+% \begin{macro}{\dim_gsub:Nn, \dim_gsub:cn}
+% Using |by| here deals with the (incorrect) case |\dimen123|.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \dim_add:Nn #1#2
+ { \tex_advance:D #1 by \dim_eval:w #2 \dim_eval_end: }
+\cs_new_protected_nopar:Npn \dim_gadd:Nn { \pref_global:D \dim_add:Nn }
+\cs_generate_variant:Nn \dim_add:Nn { c }
+\cs_generate_variant:Nn \dim_gadd:Nn { c }
+\cs_new_protected_nopar:Npn \dim_sub:Nn #1#2
+ { \tex_advance:D #1 by - \dim_eval:w #2 \dim_eval_end: }
+\cs_new_protected_nopar:Npn \dim_gsub:Nn { \pref_global:D \dim_sub:Nn }
+\cs_generate_variant:Nn \dim_sub:Nn { c }
+\cs_generate_variant:Nn \dim_gsub:Nn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Utilities for dimension calculations}
+%
+% \begin{macro}{\dim_ratio:nn}
+% \begin{macro}[aux]{\dim_ratio_aux:n}
+% With dimension expressions, something like |10 pt * ( 5 pt / 10 pt )| will
+% not work. Instead, the ratio part needs to be converted to an integer
+% expression. Using \cs{int_value:w} forces everything into |sp|, avoiding
+% any decimal parts.
+% \begin{macrocode}
+\cs_new_nopar:Npn \dim_ratio:nn #1#2
+ { \dim_ratio_aux:n {#1} / \dim_ratio_aux:n {#2} }
+\cs_new_nopar:Npn \dim_ratio_aux:n #1
+ { \exp_after:wN \int_value:w \dim_eval:w #1 \dim_eval_end: }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Dimension expression conditionals}
+%
+% \begin{macro}{\dim_compare_p:nNn}
+% \begin{macro}[TF]{\dim_compare:nNn}
+% \begin{macrocode}
+\prg_new_conditional:Npnn \dim_compare:nNn #1#2#3 { p , T , F , TF }
+ {
+ \if_dim:w \dim_eval:w #1 #2 \dim_eval:w #3 \dim_eval_end:
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\dim_compare:n}
+% \begin{macro}[aux]{\dim_compare_aux:wNN}
+% \begin{macro}[aux]{\dim_compare_<:nw}
+% \begin{macro}[aux]{\dim_compare_=:nw}
+% \begin{macro}[aux]{\dim_compare_>:nw}
+% \begin{macro}[aux]{\dim_compare_==:nw}
+% \begin{macro}[aux]{\dim_compare_<=:nw}
+% \begin{macro}[aux]{\dim_compare_!=:nw}
+% \begin{macro}[aux]{\dim_compare_>=:nw}
+% [This code plus comments are adapted from the \cs{int_compare:nTF}
+% function.]
+% Comparison tests using a simple syntax where only one set of braces
+% is required and additional operators such as |!=| and |>=| are
+% supported. First some notes on the idea behind this. We wish to
+% support writing code like
+% \begin{verbatim}
+% \dim_compare_p:n { 5mm + \l_tmpa_dim >= 4pt - \l_tmpb_dim }
+% \end{verbatim}
+% In other words, we want to somehow add the missing |\dim_eval:w|
+% where required. We can start evaluating from the left using
+% |\dim_use:N \dim_eval:w|, and we know that since the relation
+% symbols |<|, |>|, |=| and |!| are not allowed in such expressions,
+% they will terminate the expression. Therefore, we first let \TeX{}
+% evaluate this left hand side of the (in)equality.
+%
+% Eventually, we will convert the relation symbol to the appropriate
+% version of \cs{if_dim:w}, and add \cs{dim_eval:w} after it. We
+% optimize by placing the end-code already here: this avoids needless
+% grabbing of arguments later.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \dim_compare:n #1 { p , T , F , TF }
+ {
+ \exp_after:wN \dim_compare_aux:wNN \dim_use:N \dim_eval:w #1
+ \dim_eval_end:
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+% \end{macrocode}
+%
+% Contrarily to the case of integers, where we have to remove the
+% result in order to access the relation, \cs{dim_use:N} nicely
+% produces a result which ends in |pt|. We can thus use a delimited
+% argument to find the relation. \cs{tl_to_str:n} is needed to
+% convert |pt| to \enquote{other} characters.
+%
+% The relation might be one character, |#2|, or two characters |#2#3|.
+% We support the following forms: |=|, |<|, |>| and the extended |!=|,
+% |==|, |<=| and |>=|. All the extended forms have an extra |=| so we
+% check if that is present as well. Then use specific function to
+% perform the (unbalanced) test.
+% \begin{macrocode}
+\exp_args:Nno \use:nn
+ { \cs_new:Npn \dim_compare_aux:wNN #1 }
+ { \tl_to_str:n { pt } }
+ #2 #3
+ {
+ \use:c
+ {
+ dim_compare_ #2
+ \if_meaning:w = #3 = \fi:
+ :nw
+ }
+ { #1 pt } #3
+ }
+% \end{macrocode}
+% Here, \cs{dim_eval:w} will begin the right hand side of a dimension
+% comparison (with \cs{if_dim:w}), closed cleanly by the trailing tokens
+% we put in the definition of \cs{dim_compare:n}.
+%
+% The actual comparisons take as a first argument the left-hand side
+% of the comparison (a length). In the case of normal comparisons,
+% just place the relevant \cs{if_dim:w}, with a trailing \cs{dim_eval:w}
+% to evaluate the right hand side. For extended comparisons, remove
+% the trailing |=| that we left, before evaluating with \cs{dim_eval:w}.
+% In both cases, the expansion of \cs{dim_eval:w} is stopped properly,
+% and the conditional ended correctly by the tokens we put in the
+% definition of \cs{dim_compare:n}.
+%
+% Equal, less than and greater than are straighforward.
+% \begin{macrocode}
+\cs_new:cpn { dim_compare_<:nw } #1 { \if_dim:w #1 < \dim_eval:w }
+\cs_new:cpn { dim_compare_=:nw } #1 { \if_dim:w #1 = \dim_eval:w }
+\cs_new:cpn { dim_compare_>:nw } #1 { \if_dim:w #1 > \dim_eval:w }
+% \end{macrocode}
+% For the extended syntax |==|, we remove |#2|, trailing |=| sign,
+% and otherwise act as for |=|.
+% \begin{macrocode}
+\cs_new:cpn {dim_compare_==:nw} #1#2 { \if_dim:w #1 = \dim_eval:w }
+% \end{macrocode}
+%
+% Not equal, greater than or equal, less than or equal follow the
+% same scheme as the extended equality syntax, with an additional
+% \cs{reverse_if:N} to get the opposite of their \enquote{simple}
+% analog.
+% \begin{macrocode}
+\cs_new:cpn {dim_compare_<=:nw} #1#2 {\reverse_if:N \if_dim:w #1 > \dim_eval:w}
+\cs_new:cpn {dim_compare_!=:nw} #1#2 {\reverse_if:N \if_dim:w #1 = \dim_eval:w}
+\cs_new:cpn {dim_compare_>=:nw} #1#2 {\reverse_if:N \if_dim:w #1 < \dim_eval:w}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+%
+%
+% \subsection{Dimension expression loops}
+%
+% \begin{macro}{\dim_while_do:nn}
+% \begin{macro}{\dim_until_do:nn}
+% \begin{macro}{\dim_do_while:nn}
+% \begin{macro}{\dim_do_until:nn}
+% |while_do| and |do_while| functions for dimensions. Same as for the
+% |int| type only the names have changed.
+% \begin{macrocode}
+\cs_set:Npn \dim_while_do:nn #1#2
+ {
+ \dim_compare:nT {#1}
+ {
+ #2
+ \dim_while_do:nn {#1} {#2}
+ }
+ }
+\cs_set:Npn \dim_until_do:nn #1#2
+ {
+ \dim_compare:nF {#1}
+ {
+ #2
+ \dim_until_do:nn {#1} {#2}
+ }
+ }
+\cs_set:Npn \dim_do_while:nn #1#2
+ {
+ #2
+ \dim_compare:nT {#1}
+ { \dim_do_while:nNnn {#1} {#2} }
+ }
+\cs_set:Npn \dim_do_until:nn #1#2
+ {
+ #2
+ \dim_compare:nF {#1}
+ { \dim_do_until:nn {#1} {#2} }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\dim_while_do:nNnn}
+% \begin{macro}{\dim_until_do:nNnn}
+% \begin{macro}{\dim_do_while:nNnn}
+% \begin{macro}{\dim_do_until:nNnn}
+% |while_do| and |do_while| functions for dimensions. Same as for the
+% |int| type only the names have changed.
+% \begin{macrocode}
+\cs_set:Npn \dim_while_do:nNnn #1#2#3#4
+ {
+ \dim_compare:nNnT {#1} #2 {#3}
+ {
+ #4
+ \dim_while_do:nNnn {#1} #2 {#3} {#4}
+ }
+ }
+\cs_set:Npn \dim_until_do:nNnn #1#2#3#4
+ {
+ \dim_compare:nNnF {#1} #2 {#3}
+ {
+ #4
+ \dim_until_do:nNnn {#1} #2 {#3} {#4}
+ }
+ }
+\cs_set:Npn \dim_do_while:nNnn #1#2#3#4
+ {
+ #4
+ \dim_compare:nNnT {#1} #2 {#3}
+ { \dim_do_while:nNnn {#1} #2 {#3} {#4} }
+ }
+\cs_set:Npn \dim_do_until:nNnn #1#2#3#4
+ {
+ #4
+ \dim_compare:nNnF {#1} #2 {#3}
+ { \dim_do_until:nNnn {#1} #2 {#3} {#4} }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Using \texttt{dim} expressions and variables}
+%
+% \begin{macro}{\dim_eval:n}
+% Evaluating a dimension expression expandably.
+% \begin{macrocode}
+\cs_new_nopar:Npn \dim_eval:n #1
+ { \dim_use:N \dim_eval:w #1 \dim_eval_end: }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\dim_use:N, \dim_use:c}
+% Accessing a \meta{dim}.
+% \begin{macrocode}
+\cs_new_eq:NN \dim_use:N \tex_the:D
+\cs_generate_variant:Nn \dim_use:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Viewing \texttt{dim} variables}
+%
+% \begin{macro}{\dim_show:N, \dim_show:c}
+% Diagnostics.
+% \begin{macrocode}
+\cs_new_eq:NN \dim_show:N \kernel_register_show:N
+\cs_generate_variant:Nn \dim_show:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Constant dimensions}
+%
+% \begin{variable}{\c_zero_dim}
+% \begin{variable}{\c_max_dim}
+% The source for these depends on whether we are in package mode.
+% \begin{macrocode}
+%<*initex>
+\dim_new:N \c_zero_dim
+\dim_new:N \c_max_dim
+\dim_set:Nn \c_max_dim { 16383.99999 pt }
+%</initex>
+%<*package>
+\cs_new_eq:NN \c_zero_dim \z@
+\cs_new_eq:NN \c_max_dim \maxdimen
+%</package>
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+%
+% \subsection{Scratch dimensions}
+%
+% \begin{variable}{\l_tmpa_dim, \l_tmpb_dim, \l_tmpc_dim}
+% \begin{variable}{\g_tmpa_dim, \g_tmpb_dim}
+% We provide three local and two global scratch registers, maybe we
+% need more or less.
+% \begin{macrocode}
+\dim_new:N \l_tmpa_dim
+\dim_new:N \l_tmpb_dim
+\dim_new:N \l_tmpc_dim
+\dim_new:N \g_tmpa_dim
+\dim_new:N \g_tmpb_dim
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+%
+% \subsection{Creating and initialising \texttt{skip} variables}
+%
+% \begin{macro}{\skip_new:N,\skip_new:c}
+% Allocation of a new internal registers.
+% \begin{macrocode}
+%<*initex>
+\alloc_new:nnnN { skip } \c_zero \c_max_register_int \tex_skipdef:D
+%</initex>
+%<*package>
+\cs_new_protected_nopar:Npn \skip_new:N #1
+ {
+ \chk_if_free_cs:N #1
+ \newskip #1
+ }
+%</package>
+\cs_generate_variant:Nn \skip_new:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\skip_zero:N, \skip_zero:c}
+% \begin{macro}{\skip_gzero:N, \skip_gzero:c}
+% Reset the register to zero.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \skip_zero:N #1 { #1 \c_zero_skip }
+\cs_new_protected_nopar:Npn \skip_gzero:N { \pref_global:D \skip_zero:N }
+\cs_generate_variant:Nn \skip_zero:N { c }
+\cs_generate_variant:Nn \skip_gzero:N { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Setting \texttt{skip} variables}
+%
+% \begin{macro}{\skip_set:Nn, \skip_set:cn}
+% \begin{macro}{\skip_gset:Nn, \skip_gset:cn}
+% Much the same as for dimensions.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \skip_set:Nn #1#2
+ { #1 ~ \etex_glueexpr:D #2 \scan_stop: }
+\cs_new_protected_nopar:Npn \skip_gset:Nn { \pref_global:D \skip_set:Nn }
+\cs_generate_variant:Nn \skip_set:Nn { c }
+\cs_generate_variant:Nn \skip_gset:Nn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {\skip_set_eq:NN,\skip_set_eq:cN, \skip_set_eq:Nc,\skip_set_eq:cc}
+% \begin{macro}
+% {\skip_gset_eq:NN,\skip_gset_eq:cN, \skip_gset_eq:Nc,\skip_gset_eq:cc}
+% All straightforward.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \skip_set_eq:NN #1#2 { #1 = #2 }
+\cs_generate_variant:Nn \skip_set_eq:NN { c }
+\cs_generate_variant:Nn \skip_set_eq:NN { Nc , cc }
+\cs_new_protected_nopar:Npn \skip_gset_eq:NN #1#2 { \pref_global:D #1 = #2 }
+\cs_generate_variant:Nn \skip_gset_eq:NN { c }
+\cs_generate_variant:Nn \skip_gset_eq:NN { Nc , cc }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\skip_add:Nn, \skip_add:cn}
+% \begin{macro}{\skip_gadd:Nn, \skip_gadd:cn}
+% \begin{macro}{\skip_sub:Nn, \skip_sub:cn}
+% \begin{macro}{\skip_gsub:Nn, \skip_gsub:cn}
+% Using |by| here deals with the (incorrect) case |\skip123|.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \skip_add:Nn #1#2
+ { \tex_advance:D #1 by \etex_glueexpr:D #2 \scan_stop: }
+\cs_new_protected_nopar:Npn \skip_gadd:Nn { \pref_global:D \skip_add:Nn }
+\cs_generate_variant:Nn \skip_add:Nn { c }
+\cs_generate_variant:Nn \skip_gadd:Nn { c }
+\cs_new_protected_nopar:Npn \skip_sub:Nn #1#2
+ { \tex_advance:D #1 by - \etex_glueexpr:D #2 \scan_stop: }
+\cs_new_protected_nopar:Npn \skip_gsub:Nn { \pref_global:D \skip_sub:Nn }
+\cs_generate_variant:Nn \skip_sub:Nn { c }
+\cs_generate_variant:Nn \skip_gsub:Nn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Skip expression conditionals}
+%
+% \begin{macro}[pTF]{\skip_if_eq:nn}
+% Comparing skips means doing two expansions to make strings, and then
+% testing them. As a result, only equality is tested.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \skip_if_eq:nn #1#2 { p , T , F , TF }
+ {
+ \if_int_compare:w
+ \pdftex_strcmp:D { \skip_eval:n { #1 } } { \skip_eval:n { #2 } }
+ = \c_zero
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\skip_if_infinite_glue:n}
+% With \eTeX{} we all of a sudden get access to a lot information we
+% should otherwise consider ourselves lucky to get. One is
+% the stretch and shrink components of a skip register and the order
+% or those components. cs{skip_if_infinite_glue:nTF} tests it directly by
+% looking at the stretch and shrink order. If either of the predicate
+% functions return \meta{true}, |\bool_if:nTF| will return \meta{true}
+% and the logic test will take the true branch.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \skip_if_infinite_glue:n #1 { p , T , F , TF }
+ {
+ \bool_if:nTF
+ {
+ \int_compare_p:nNn { \etex_gluestretchorder:D #1 } > \c_zero ||
+ \int_compare_p:nNn { \etex_glueshrinkorder:D #1 } > \c_zero
+ }
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Using \texttt{skip} expressions and variables}
+%
+% \begin{macro}{\skip_eval:n}
+% Evaluating a skip expression expandably.
+% \begin{macrocode}
+\cs_new_nopar:Npn \skip_eval:n #1
+ { \skip_use:N \etex_glueexpr:D #1 \scan_stop: }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\skip_use:N, \skip_use:c}
+% Accessing a \meta{skip}.
+% \begin{macrocode}
+\cs_new_eq:NN \skip_use:N \tex_the:D
+\cs_generate_variant:Nn \skip_use:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Inserting skips into the output}
+%
+% \begin{macro}{\skip_horizontal:N, \skip_horizontal:c, \skip_horizontal:n}
+% \begin{macro}{\skip_vertical:N, \skip_vertical:c, \skip_vertical:n}
+% Inserting skips.
+% \begin{macrocode}
+\cs_new_eq:NN \skip_horizontal:N \tex_hskip:D
+\cs_new_nopar:Npn \skip_horizontal:n #1
+ { \skip_horizontal:N \etex_glueexpr:D #1 \scan_stop: }
+\cs_new_eq:NN \skip_vertical:N \tex_vskip:D
+\cs_new_nopar:Npn \skip_vertical:n #1
+ { \skip_vertical:N \etex_glueexpr:D #1 \scan_stop: }
+\cs_generate_variant:Nn \skip_horizontal:N { c }
+\cs_generate_variant:Nn \skip_vertical:N { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Viewing \texttt{skip} variables}
+%
+% \begin{macro}{\skip_show:N, \skip_show:c}
+% Diagnostics.
+% \begin{macrocode}
+\cs_new_eq:NN \skip_show:N \kernel_register_show:N
+\cs_generate_variant:Nn \skip_show:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Constant skips}
+%
+% \begin{macro}{\c_zero_skip}
+% \begin{macro}{\c_max_skip}
+% Skips with no rubber component are just dimensions
+% \begin{macrocode}
+\cs_new_eq:NN \c_zero_skip \c_zero_dim
+\cs_new_eq:NN \c_max_skip \c_max_dim
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Scratch skips}
+%
+% \begin{variable}{\l_tmpa_skip, \l_tmpb_skip, \l_tmpc_skip}
+% \begin{variable}{\g_tmpa_skip, \g_tmpb_skip}
+% We provide three local and two global scratch registers, maybe we
+% need more or less.
+% \begin{macrocode}
+\skip_new:N \l_tmpa_skip
+\skip_new:N \l_tmpb_skip
+\skip_new:N \l_tmpc_skip
+\skip_new:N \g_tmpa_skip
+\skip_new:N \g_tmpb_skip
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+%
+% \subsection{Creating and initialising \texttt{muskip} variables}
+%
+% \begin{macro}{\muskip_new:N, \muskip_new:c}
+% And then we add muskips.
+% \begin{macrocode}
+%<*initex>
+\alloc_new:nnnN { muskip } \c_zero \c_max_register_int \tex_muskipdef:D
+%</initex>
+%<*package>
+\cs_new_protected_nopar:Npn \muskip_new:N #1
+ {
+ \chk_if_free_cs:N #1
+ \newmuskip #1
+ }
+%</package>
+\cs_generate_variant:Nn \muskip_new:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\muskip_zero:N, \muskip_zero:c}
+% \begin{macro}{\muskip_gzero:N, \muskip_gzero:c}
+% Reset the register to zero.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \muskip_zero:N #1
+ { #1 \c_zero_muskip }
+\cs_new_protected_nopar:Npn \muskip_gzero:N { \pref_global:D \muskip_zero:N }
+\cs_generate_variant:Nn \muskip_zero:N { c }
+\cs_generate_variant:Nn \muskip_gzero:N { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Setting \texttt{muskip} variables}
+%
+% \begin{macro}{\muskip_set:Nn, \muskip_set:cn}
+% \begin{macro}{\muskip_gset:Nn, \muskip_gset:cn}
+% This should be pretty familiar.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \muskip_set:Nn #1#2
+ { #1 ~ \etex_muexpr:D #2 \scan_stop: }
+\cs_new_protected_nopar:Npn \muskip_gset:Nn { \pref_global:D \muskip_set:Nn }
+\cs_generate_variant:Nn \muskip_set:Nn { c }
+\cs_generate_variant:Nn \muskip_gset:Nn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \muskip_set_eq:NN, \muskip_set_eq:cN,
+% \muskip_set_eq:Nc, \muskip_set_eq:cc
+% }
+% \begin{macro}
+% {
+% \muskip_gset_eq:NN,\muskip_gset_eq:cN,
+% \muskip_gset_eq:Nc,\muskip_gset_eq:cc
+% }
+% All straightforward.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \muskip_set_eq:NN #1#2 { #1 = #2 }
+\cs_generate_variant:Nn \muskip_set_eq:NN { c }
+\cs_generate_variant:Nn \muskip_set_eq:NN { Nc , cc }
+\cs_new_protected_nopar:Npn \muskip_gset_eq:NN #1#2 { \pref_global:D #1 = #2 }
+\cs_generate_variant:Nn \muskip_gset_eq:NN { c }
+\cs_generate_variant:Nn \muskip_gset_eq:NN { Nc , cc }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\muskip_add:Nn, \muskip_add:cn}
+% \begin{macro}{\muskip_gadd:Nn, \muskip_gadd:cn}
+% \begin{macro}{\muskip_sub:Nn, \muskip_sub:cn}
+% \begin{macro}{\muskip_gsub:Nn, \muskip_gsub:cn}
+% Using |by| here deals with the (incorrect) case |\muskip123|.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \muskip_add:Nn #1#2
+ { \tex_advance:D #1 by \etex_muexpr:D #2 \scan_stop: }
+\cs_new_protected_nopar:Npn \muskip_gadd:Nn { \pref_global:D \muskip_add:Nn }
+\cs_generate_variant:Nn \muskip_add:Nn { c }
+\cs_generate_variant:Nn \muskip_gadd:Nn { c }
+\cs_new_protected_nopar:Npn \muskip_sub:Nn #1#2
+ { \tex_advance:D #1 by - \etex_muexpr:D #2 \scan_stop: }
+\cs_new_protected_nopar:Npn \muskip_gsub:Nn { \pref_global:D \muskip_sub:Nn }
+\cs_generate_variant:Nn \muskip_sub:Nn { c }
+\cs_generate_variant:Nn \muskip_gsub:Nn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Using \texttt{muskip} expressions and variables}
+%
+% \begin{macro}{\muskip_eval:n}
+% Evaluating a muskip expression expandably.
+% \begin{macrocode}
+\cs_new_nopar:Npn \muskip_eval:n #1
+ { \muskip_use:N \etex_muexpr:D #1 \scan_stop: }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\muskip_use:N, \muskip_use:c}
+% Accessing a \meta{muskip}.
+% \begin{macrocode}
+\cs_new_eq:NN \muskip_use:N \tex_the:D
+\cs_generate_variant:Nn \muskip_use:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Viewing \texttt{muskip} variables}
+%
+% \begin{macro}{\muskip_show:N, \muskip_show:c}
+% Diagnostics.
+% \begin{macrocode}
+\cs_new_eq:NN \muskip_show:N \kernel_register_show:N
+\cs_generate_variant:Nn \muskip_show:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Experimental skip functions}
+%
+% \begin{macro}{\skip_split_finite_else_action:nnNN}
+% This macro is useful when performing error checking in certain
+% circumstances. If the \m{skip} register holds finite glue it sets
+% |#3| and |#4| to the stretch and shrink component, resp. If it holds
+% infinite glue set |#3| and |#4| to zero and issue the special action
+% |#2| which is probably an error message.
+% Assignments are global.
+% \begin{macrocode}
+\cs_new_nopar:Npn \skip_split_finite_else_action:nnNN #1#2#3#4
+ {
+ \skip_if_infinite_glue:nTF {#1}
+ {
+ #3 = \c_zero_skip
+ #4 = \c_zero_skip
+ #2
+ }
+ {
+ #3 = \etex_gluestretch:D #1 \scan_stop:
+ #4 = \etex_glueshrink:D #1 \scan_stop:
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</initex|package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx b/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx
new file mode 100644
index 00000000000..a7f292d14c7
--- /dev/null
+++ b/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx
@@ -0,0 +1,2268 @@
+% \iffalse meta-comment
+%
+%% File: l3tl.dtx Copyright (C) 1990-2011 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 "expl3 bundle" (The Work in LPPL)
+%% and all files in that bundle must be distributed together.
+%%
+%% The released version of this bundle is available from CTAN.
+%%
+%% -----------------------------------------------------------------------
+%%
+%% The development version of the bundle can be found at
+%%
+%% http://www.latex-project.org/svnroot/experimental/trunk/
+%%
+%% for those people who are interested.
+%%
+%%%%%%%%%%%
+%% NOTE: %%
+%%%%%%%%%%%
+%%
+%% Snapshots taken from the repository represent work in progress and may
+%% not work or may contain conflicting material! We therefore ask
+%% people _not_ to put them into distributions, archives, etc. without
+%% prior consultation with the LaTeX3 Project.
+%%
+%% -----------------------------------------------------------------------
+%
+%<*driver|package>
+\RequirePackage{l3names}
+\GetIdInfo$Id: l3tl.dtx 2498 2011-07-09 17:51:47Z joseph $
+ {L3 Experimental token lists}
+%</driver|package>
+%<*driver>
+\documentclass[full]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3tl} package\\ Token lists^^A
+% \thanks{This file describes v\ExplFileVersion,
+% last revised \ExplFileDate.}^^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 \ExplFileDate}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% \LaTeX3 stores lists of token in variables also called \enquote{token lists}.
+% Variables of this type get the suffix |tl| and functions of this type
+% have the prefix |tl|. To use a token list variable you simply call
+% the corresponding variable.
+%
+% Often you find yourself with not a token list variable but an
+% arbitrary token list which has to undergo certain tests. We will \emph{also}
+% prefix these functions with |tl|. While token list variables are
+% always single tokens, token lists are always surrounded by
+% braces. Many of the functions for token lists and token list variables
+% are very similar, and so are grouped together here.
+%
+% \section{Creating and initialising token list variables}
+%
+% \begin{function}{\tl_new:N, \tl_new:c}
+% \begin{syntax}
+% \cs{tl_new:N} \meta{tl~var}
+% \end{syntax}
+% Creates a new \meta{tl~var} or raises an error if the
+% name is already taken. The declaration is global. The
+% \meta{tl~var} will initially be empty.
+% \end{function}
+%
+% \begin{function}{\tl_const:Nn, \tl_const:Nx, \tl_const:cn, \tl_const:cx}
+% \begin{syntax}
+% \cs{tl_const:Nn} \meta{tl~var} \Arg{token list}
+% \end{syntax}
+% Creates a new constant \meta{tl~var} or raises an error
+% if the name is already taken. The value of the
+% \meta{tl~var} will be set globally to the
+% \meta{token list}.
+% \end{function}
+%
+% \begin{function}{\tl_clear:N, \tl_clear:c}
+% \begin{syntax}
+% \cs{tl_clear:N} \meta{tl~var}
+% \end{syntax}
+% Clears all entries from the \meta{tl~var} within the scope of
+% the current \TeX{} group.
+% \end{function}
+%
+% \begin{function}{\tl_gclear:N, \tl_gclear:c}
+% \begin{syntax}
+% \cs{tl_gclear:N} \meta{tl~var}
+% \end{syntax}
+% Clears all entries from the \meta{tl~var} globally.
+% \end{function}
+%
+% \begin{function}{\tl_clear_new:N, \tl_clear_new:c}
+% \begin{syntax}
+% \cs{tl_clear_new:N} \meta{tl~var}
+% \end{syntax}
+% If the \meta{tl~var} already exists, clears it within the scope
+% of the current \TeX{} group. If the \meta{tl~var} is not defined,
+% it will be created (using \cs{tl_new:N}). Thus the sequence is
+% guaranteed to be available and clear within the current \TeX{}
+% group. The \meta{tl~var} will exist globally, but the content
+% outside of the current \TeX{} group is not specified.
+% \end{function}
+%
+% \begin{function}{\tl_gclear_new:N, \tl_gclear_new:c}
+% \begin{syntax}
+% \cs{tl_gclear_new:N} \meta{tl~var}
+% \end{syntax}
+% If the \meta{tl~var} already exists, clears it globally. If the
+% \meta{tl~var} is not defined, it will be created (using
+% \cs{tl_new:N}). Thus the sequence is guaranteed to be available
+% and globally clear.
+% \end{function}
+%
+% \begin{function}{\tl_set_eq:NN, \tl_set_eq:cN, \tl_set_eq:Nc, \tl_set_eq:cc}
+% \begin{syntax}
+% \cs{tl_set_eq:NN} \meta{tl~var1} \meta{tl~var2}
+% \end{syntax}
+% Sets the content of \meta{tl~var1} equal to that of
+% \meta{tl~var2}. This assignment is restricted to the current
+% \TeX{} group level.
+% \end{function}
+%
+% \begin{function}
+% {\tl_gset_eq:NN, \tl_gset_eq:cN, \tl_gset_eq:Nc, \tl_gset_eq:cc}
+% \begin{syntax}
+% \cs{tl_gset_eq:NN} \meta{tl~var1} \meta{tl~var2}
+% \end{syntax}
+% Sets the content of \meta{tl~var1} equal to that of
+% \meta{tl~var2}. This assignment is global and so is not
+% limited by the current \TeX{} group level.
+% \end{function}
+%
+% \section{Adding data to token list variables}
+%
+% \begin{function}
+% {
+% \tl_set:Nn, \tl_set:NV, \tl_set:Nv, \tl_set:No, \tl_set:Nf, \tl_set:Nx,
+% \tl_set:cn, \tl_set:NV, \tl_set:Nv, \tl_set:co, \tl_set:cf, \tl_set:cx
+% }
+% \begin{syntax}
+% \cs{tl_set:Nn} \meta{tl~var} \Arg{tokens}
+% \end{syntax}
+% Sets \meta{tl~var} to contain \meta{tokens},
+% removing any previous content from the variable. This assignment
+% is restricted to the current \TeX{} group.
+% \end{function}
+%
+% \begin{function}
+% {
+% \tl_gset:Nn, \tl_gset:NV, \tl_gset:Nv,
+% \tl_gset:No, \tl_gset:Nf, \tl_gset:Nx,
+% \tl_gset:cn, \tl_gset:cV, \tl_gset:cv,
+% \tl_gset:co, \tl_gset:cf, \tl_gset:cx
+% }
+% \begin{syntax}
+% \cs{tl_gset:Nn} \meta{tl~var} \Arg{tokens}
+% \end{syntax}
+% Sets \meta{tl~var} to contain \meta{tokens},
+% removing any previous content from the variable. This assignment
+% is global and is not limited to the current \TeX{} group level.
+% \end{function}
+%
+% \begin{function}
+% {
+% \tl_put_left:Nn, \tl_put_left:NV, \tl_put_left:No, \tl_put_left:Nx,
+% \tl_put_left:cn, \tl_put_left:cV, \tl_put_left:co, \tl_put_left:cx
+% }
+% \begin{syntax}
+% \cs{tl_put_left:Nn} \meta{tl~var} \Arg{tokens}
+% \end{syntax}
+% Appends \meta{tokens} to the left side of the current content of
+% \meta{tl~var}. This modification is restricted to the
+% current \TeX{} group level.
+% \end{function}
+%
+% \begin{function}
+% {
+% \tl_gput_left:Nn, \tl_gput_left:NV, \tl_gput_left:No, \tl_gput_left:Nx,
+% \tl_gput_left:cn, \tl_gput_left:cV, \tl_gput_left:co, \tl_gput_left:cx
+% }
+% \begin{syntax}
+% \cs{tl_gput_left:Nn} \meta{tl~var} \Arg{tokens}
+% \end{syntax}
+% Globally appends \meta{tokens} to the left side of the current
+% content of \meta{tl~var}. This modification is not
+% limited by \TeX{} grouping.
+% \end{function}
+%
+% \begin{function}
+% {
+% \tl_put_right:Nn, \tl_put_right:NV, \tl_put_right:No, \tl_put_right:Nx,
+% \tl_put_right:cn, \tl_put_right:cV, \tl_put_right:co, \tl_put_right:cx
+% }
+% \begin{syntax}
+% \cs{tl_put_right:Nn} \meta{tl~var} \Arg{tokens}
+% \end{syntax}
+% Appends \meta{tokens} to the right side of the current content of
+% \meta{tl~var}. This modification is restricted to the
+% current \TeX{} group level.
+% \end{function}
+%
+% \begin{function}
+% {
+% \tl_gput_right:Nn, \tl_gput_right:NV, \tl_gput_right:No,
+% \tl_gput_right:Nx,
+% \tl_gput_right:cn, \tl_gput_right:cV, \tl_gput_right:co,
+% \tl_gput_right:cx
+% }
+% \begin{syntax}
+% \cs{tl_gput_right:Nn} \meta{tl~var} \Arg{tokens}
+% \end{syntax}
+% Globally appends \meta{tokens} to the right side of the current
+% content of \meta{tl~var}. This modification is not
+% limited by \TeX{} grouping.
+% \end{function}
+%
+% \section{Modifying token list variables}
+%
+% \begin{function}{\tl_replace_once:Nnn, \tl_replace_once:cnn}
+% \begin{syntax}
+% \cs{tl_replace_once:Nnn} \meta{tl~var} \Arg{old tokens}
+% ~~\Arg{new tokens}
+% \end{syntax}
+% Replaces the first (leftmost) occurrence of \meta{old tokens} in the
+% \meta{tl~var} with \meta{new tokens}. \meta{Old tokens}
+% cannot contain |{|, |}| or |#|
+% (assuming normal \TeX{} category codes). The assignment is
+% restricted to the current \TeX{} group.
+% \end{function}
+%
+% \begin{function}{\tl_greplace_once:Nnn, \tl_greplace_once:cnn}
+% \begin{syntax}
+% \cs{tl_greplace_once:Nnn} \meta{tl~var} \Arg{old tokens}
+% ~~\Arg{new tokens}
+% \end{syntax}
+% Replaces the first (leftmost) occurrence of \meta{old tokens} in the
+% \meta{tl~var} with \meta{new tokens}. \meta{Old tokens}
+% cannot contain |{|, |}| or |#|
+% (assuming normal \TeX{} category codes). The assignment is
+% applied globally.
+% \end{function}
+%
+% \begin{function}{\tl_replace_all:Nnn, \tl_replace_all:cnn}
+% \begin{syntax}
+% \cs{tl_replace_all:Nnn} \meta{tl~var} \Arg{old tokens}
+% ~~\Arg{new tokens}
+% \end{syntax}
+% Replaces all occurrences of \meta{old tokens} in the
+% \meta{tl~var} with \meta{new tokens}. \meta{Old tokens}
+% cannot contain |{|, |}| or |#|
+% (assuming normal \TeX{} category codes). The assignment is
+% restricted to the current \TeX{} group.
+% \end{function}
+%
+% \begin{function}{\tl_greplace_all:Nnn, \tl_greplace_all:cnn}
+% \begin{syntax}
+% \cs{tl_greplace_all:Nnn} \meta{tl~var} \Arg{old tokens}
+% ~~\Arg{new tokens}
+% \end{syntax}
+% Replaces all occurrences of \meta{old tokens} in the
+% \meta{tl~var} with \meta{new tokens}. \meta{Old tokens}
+% cannot contain |{|, |}| or |#|
+% (assuming normal \TeX{} category codes). The assignment is
+% applied globally.
+% \end{function}
+%
+% \begin{function}{\tl_remove_once:Nn, \tl_remove_once:cn}
+% \begin{syntax}
+% \cs{tl_remove_once:Nn} \meta{tl~var} \Arg{tokens}
+% \end{syntax}
+% Removes the first (leftmost) occurrence of \meta{tokens} from the
+% \meta{tl~var}. \meta{Tokens} cannot contain |{|, |}| or
+% |#| (assuming normal \TeX{} category codes). The assignment is
+% restricted to the current \TeX{} group.
+% \end{function}
+%
+% \begin{function}{\tl_gremove_once:Nn, \tl_gremove_once:cn}
+% \begin{syntax}
+% \cs{tl_gremove_once:Nn} \meta{tl~var} \Arg{tokens}
+% \end{syntax}
+% Removes the first (leftmost) occurrence of \meta{tokens} from the
+% \meta{tl~var}. \meta{Tokens} cannot contain |{|, |}| or
+% |#| (assuming normal \TeX{} category codes). The assignment is
+% applied globally.
+% \end{function}
+%
+% \begin{function}{\tl_remove_all:Nn, \tl_remove_all:cn}
+% \begin{syntax}
+% \cs{tl_remove_all:Nn} \meta{tl~var} \Arg{tokens}
+% \end{syntax}
+% Removes all occurrences of \meta{tokens} from the
+% \meta{tl~var}. \meta{Tokens} cannot contain |{|, |}| or
+% |#| (assuming normal \TeX{} category codes). The assignment is
+% restricted to the current \TeX{} group.
+% \end{function}
+%
+% \begin{function}{\tl_gremove_all:Nn, \tl_gremove_all:cn}
+% \begin{syntax}
+% \cs{tl_gremove_all:Nn} \meta{tl~var} \Arg{tokens}
+% \end{syntax}
+% Removes all occurrences of \meta{tokens} from the
+% \meta{tl~var}. \meta{Tokens} cannot contain |{|, |}| or
+% |#| (assuming normal \TeX{} category codes). The assignment is
+% applied globally.
+% \end{function}
+%
+% \section{Reassigning token list category codes}
+%
+% \begin{function}
+% {
+% \tl_set_rescan:Nnn, \tl_set_rescan:Nno, \tl_set_rescan:Nnx,
+% \tl_set_rescan:cnn, \tl_set_rescan:cno, \tl_set_rescan:cnx,
+% }
+% \begin{syntax}
+% \cs{tl_set_rescan:Nnn} \meta{tl~var} \Arg{setup}
+% ~~\Arg{tokens}
+% \end{syntax}
+% Sets \meta{tl~var} to contain \meta{tokens},
+% applying the category code regim{\'e} specified in the
+% \meta{setup} before carrying out the assignment. This allows the
+% \meta{tl~var} to contain material with category codes
+% other than those that apply when \meta{tokens} are absorbed. The
+% assignment is local to the current \TeX{} group. See also
+% \cs{tl_rescan:nn}.
+% \end{function}
+%
+% \begin{function}
+% {
+% \tl_gset_rescan:Nnn, \tl_gset_rescan:Nno, \tl_gset_rescan:Nnx,
+% \tl_gset_rescan:cnn, \tl_gset_rescan:cno, \tl_gset_rescan:cnx,
+% }
+% \begin{syntax}
+% \cs{tl_gset_rescan:Nnn} \meta{tl~var} \Arg{setup}
+% ~~\Arg{tokens}
+% \end{syntax}
+% Sets \meta{tl~var} to contain \meta{tokens},
+% applying the category code regim{\'e} specified in the
+% \meta{setup} before carrying out the assignment. This allows the
+% \meta{tl~var} to contain material with category codes
+% other than those that apply when \meta{tokens} are absorbed. The
+% assignment is global. See also \cs{tl_rescan:nn}.
+% \end{function}
+%
+% \begin{function}{\tl_rescan:nn}
+% \begin{syntax}
+% \cs{tl_rescan:nn} \Arg{setup} \Arg{tokens}
+% \end{syntax}
+% Rescans \meta{tokens} applying the category code regim{\'e} specified
+% in the \meta{setup}, and leaves the resulting tokens in the input
+% stream. See also \cs{tl_set_rescan:Nnn}.
+% \end{function}
+%
+% \section{Reassigning token list character codes}
+%
+% \begin{function}{\tl_to_lowercase:n}
+% \begin{syntax}
+% \cs{tl_to_lowercase:n} \Arg{tokens}
+% \end{syntax}
+% Works through all of the \meta{tokens}, replacing each character
+% with the lower case equivalent as defined by \cs{char_set_lccode:nn}.
+% Characters with no defined lower case character code are left
+% unchanged. This process does not alter the category code assigned
+% to the \meta{tokens}.
+% \begin{texnote}
+% This is the \TeX{} primitive \cs{lowercase} renamed.
+% As a result, this function takes place on execution and
+% not on expansion.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{\tl_to_uppercase:n}
+% \begin{syntax}
+% \cs{tl_to_uppercase:n} \Arg{tokens}
+% \end{syntax}
+% Works through all of the \meta{tokens}, replacing each character
+% with the upper case equivalent as defined by \cs{char_set_uccode:nn}.
+% Characters with no defined lower case character code are left
+% unchanged. This process does not alter the category code assigned
+% to the \meta{tokens}.
+% \begin{texnote}
+% This is the \TeX{} primitive \cs{uppercase} renamed..
+% As a result, this function takes place on execution and
+% not on expansion.
+% \end{texnote}
+% \end{function}
+%
+% \section{Token list conditionals}
+%
+% \begin{function}[EXP,pTF]{\tl_if_blank:n, \tl_if_blank:V, \tl_if_blank:o}
+% \begin{syntax}
+% \cs{tl_if_blank_p:n} \Arg{token list}
+% \cs{tl_if_blank:nTF} \Arg{token list} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{token list} consists only of blank spaces. The
+% test is \texttt{true} if \meta{token list} is empty or consists
+% entirely of explicit tokens of character code $32$
+% and category code $10$, and is \texttt{false}
+% otherwise. The branching versions then leave either \meta{true code}
+% or \meta{false code} in the input stream, as appropriate to the
+% truth of the test and the variant of the function chosen. The logical
+% truth of the test is left in the input stream by the predicate
+% version.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\tl_if_empty:N, \tl_if_empty:c}
+% \begin{syntax}
+% \cs{tl_if_empty_p:N} \meta{tl var}
+% \cs{tl_if_empty:NTF} \meta{tl var} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{token list variable} is entirely empty
+% (\emph{i.e.}~contains no tokens at all). The branching versions then
+% leave either \meta{true code} or \meta{false code} in the input
+% stream, as appropriate to the truth of the test and the variant of
+% the function chosen. The logical truth of the test is left in the
+% input stream by the predicate version.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\tl_if_empty:n, \tl_if_empty:V, \tl_if_empty:o}
+% \begin{syntax}
+% \cs{tl_if_empty_p:n} \Arg{token list}
+% \cs{tl_if_empty:nTF} \Arg{token list} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{token list} is entirely empty
+% (\emph{i.e.}~contains no tokens at all). The branching versions then
+% leave either \meta{true code} or \meta{false code} in the input
+% stream, as appropriate to the truth of the test and the variant of
+% the function chosen. The logical truth of the test is left in the
+% input stream by the predicate version.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]
+% {\tl_if_eq:NN, \tl_if_eq:Nc, \tl_if_eq:cN, \tl_if_eq:cc}
+% \begin{syntax}
+% \cs{tl_if_eq_p:NN} \Arg{tl var1} \Arg{tl var2}
+% \cs{tl_if_eq:NNTF} \Arg{tl var1} \Arg{tl var2} \Arg{true code}
+% ~~\Arg{false code}
+% \end{syntax}
+% Compares the content of two \meta{token list variables} and
+% is logically \texttt{true} if the two contain the same list of
+% tokens (\emph{i.e.}~identical in both the list of characters they
+% contain and the category codes of those characters). Thus for example
+% \begin{verbatim}
+% \tl_set:Nn \l_tmpa_tl { abc }
+% \tl_set:Nx \l_tmpb_tl { \tl_to_str:n { abc } }
+% \tl_if_eq_p:NN \l_tmpa_tl \l_tmpb_tl
+% \end{verbatim}
+% is logically \texttt{false}. The branching versions then leave either
+% \meta{true code} or \meta{false code} in the input stream, as
+% appropriate to the truth of the test and the variant of the function
+% chosen. The logical truth of the test is left in the input stream by
+% the predicate version.
+% \end{function}
+%
+% \begin{function}[TF]{\tl_if_eq:nn}
+% \begin{syntax}
+% \cs{tl_if_eq:nnTF} \meta{token list1} \Arg{token list2} \Arg{true code}
+% ~~\Arg{false code}
+% \end{syntax}
+% Tests if \meta{token list1} and \meta{token list2} are equal, both in
+% respect of character codes and category codes. Either the
+% \meta{true code} or \meta{false code} in the input stream, as
+% appropriate to the truth of the test and the variant of the function
+% chosen.
+% \end{function}
+%
+% \begin{function}[TF]{\tl_if_in:Nn, \tl_if_in:cn}
+% \begin{syntax}
+% \cs{tl_if_in:NnTF} \meta{tl~var} \Arg{token list} \Arg{true code}
+% ~~\Arg{false code}
+% \end{syntax}
+% Tests if the \meta{token list} is found in the content of the
+% \meta{token list variable}. The \meta{token list} cannot contain
+% the tokens |{|, |}| or |#| (assuming the usual \TeX{} category
+% codes apply). Either the \meta{true code} or \meta{false code}
+% is left in the
+% input stream, as appropriate to the truth of the test and the variant
+% of the function chosen.
+% \end{function}
+%
+% \begin{function}[TF]
+% {\tl_if_in:nn, \tl_if_in:Vn, \tl_if_in:on, \tl_if_in:on}
+% \begin{syntax}
+% \cs{tl_if_in:nnTF} \meta{token list1} \Arg{token list2} \Arg{true code}
+% ~~\Arg{false code}
+% \end{syntax}
+% Tests if the \meta{token list1} is found inside \meta{token list2}.
+% The \meta{token list} cannot contain the tokens |{|, |}| or |#|
+% (assuming the usual \TeX{} category codes apply). Either the
+% \meta{true code} or \meta{false code} is left in the input stream, as
+% appropriate to the truth of the test and the variant of the function
+% chosen.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\tl_if_single:N, \tl_if_single:c}
+% \begin{syntax}
+% \cs{tl_if_single_p:N} \Arg{tl~var}
+% \cs{tl_if_single:nTF} \Arg{tl~var} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the content of the \meta{tl~var} consists of a
+% single token or token group. The test is \texttt{true} if
+% \meta{token list} contains exactly one token, if it consists
+% entirely of explicit tokens of character code $32$ and category
+% code $10$, or if it contains one braced token group (optionally
+% preceeded by spaces), and it is \texttt{false} otherwise. The branching
+% versions then leave either \meta{true code} or \meta{false code}
+% in the input stream, as appropriate to the truth of the test and the
+% variant of the function chosen. The logical truth of the test is left
+% in the input stream by the predicate version.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\tl_if_single:n}
+% \begin{syntax}
+% \cs{tl_if_single_p:n} \Arg{token list}
+% \cs{tl_if_single:nTF} \Arg{token list} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{token list} consists of a single token
+% or token group. The test is \texttt{true} if \meta{token list}
+% contains exactly one token, or if it consists entirely of
+% explicit tokens of character code $32$ and category code $10$,
+% or if it contains a braced token group (optionally preceeded by blank
+% spaces), and it is
+% \texttt{false} otherwise. The branching versions then leave
+% either \meta{true code} or \meta{false code} in the input stream, as
+% appropriate to the truth of the test and the variant of the function
+% chosen. The logical truth of the test is left in the input stream by
+% the predicate version.
+% \end{function}
+%
+% \section{Mapping to token lists}
+%
+% \begin{function}[EXP]{\tl_map_function:NN, \tl_map_function:cN}
+% \begin{syntax}
+% \cs{tl_map_function:NN} \meta{tl~var} \meta{function}
+% \end{syntax}
+% Applies \meta{function} to every \meta{token group} stored in the
+% \meta{tl~var}. The \meta{function}
+% will receive one argument for each iteration. This may be a number
+% of tokens if the \meta{token group} was an item stored within
+% braces. Hence the \meta{function} should anticipate receiving
+% \texttt{n}-type arguments. See also \cs{tl_map_function:nN}.
+% \end{function}
+%
+% \begin{function}[EXP]{\tl_map_function:nN}
+% \begin{syntax}
+% \cs{tl_map_function:nN} \meta{token list} \meta{function}
+% \end{syntax}
+% Applies \meta{function} to every \meta{token group} in the
+% \meta{token list}. The \meta{function}
+% will receive one argument for each iteration. This may be a number
+% of tokens if the \meta{token group} was an item stored within
+% braces. Hence the \meta{function} should anticipate receiving
+% \texttt{n}-type arguments. See also \cs{tl_map_function:NN}.
+% \end{function}
+%
+% \begin{function}{\tl_map_inline:Nn, \tl_map_inline:cn}
+% \begin{syntax}
+% \cs{tl_map_inline:Nn} \meta{tl~var} \Arg{inline function}
+% \end{syntax}
+% Applies the \meta{inline function} to every \meta{token group} stored
+% within the \meta{tl~var}. The \meta{inline function}
+% should consist of code which will receive the \meta{token group} as
+% |#1|. One in line mapping can be nested inside another. See also
+% \cs{tl_map_function:Nn}.
+% \end{function}
+%
+% \begin{function}{\tl_map_inline:nn}
+% \begin{syntax}
+% \cs{tl_map_inline:nn} \meta{token list} \Arg{inline function}
+% \end{syntax}
+% Applies the \meta{inline function} to every \meta{token group} stored
+% within the \meta{token list}. The \meta{inline function} should
+% consist of code which will receive the \meta{token group} as
+% |#1|. One in line mapping can be nested inside another. See also
+% \cs{tl_map_function:nn}.
+% \end{function}
+%
+% \begin{function}{\tl_map_variable:NNn, \tl_map_variable:cNn}
+% \begin{syntax}
+% \cs{tl_map_variable:NNn} \meta{tl~var} \meta{variable} \Arg{function}
+% \end{syntax}
+% Applies the \meta{function} to every \meta{token group} stored
+% within the \meta{tl~var}. The \meta{function} should consist of code
+% which will receive the \meta{token group} stored in the \meta{variable}.
+% One variable mapping can be nested inside another. See also
+% \cs{tl_map_inline:Nn}.
+% \end{function}
+%
+% \begin{function}{\tl_map_variable:nNn}
+% \begin{syntax}
+% \cs{tl_map_variable:nNn} \meta{token list} \meta{variable} \Arg{function}
+% \end{syntax}
+% Applies the \meta{function} to every \meta{token group} stored
+% within the \meta{token list}. The \meta{function} should consist of code
+% which will receive the \meta{token group} stored in the \meta{variable}.
+% One variable mapping can be nested inside another. See also
+% \cs{tl_map_inline:nn}.
+% \end{function}
+%
+% \begin{function}[EXP]{\tl_map_break:}
+% \begin{syntax}
+% \cs{tl_map_break:}
+% \end{syntax}
+% Used to terminate a \cs{tl_map_\ldots} function before all
+% entries in the \meta{token list variable} have been processed. This
+% will normally take place within a conditional statement, for example
+% \begin{verbatim}
+% \tl_map_inline:Nn \l_my_tl
+% {
+% \str_if_eq:nnTF { #1 } { bingo }
+% { \tl_map_break: }
+% {
+% % Do something useful
+% }
+% }
+% \end{verbatim}
+% Use outside of a \cs{tl_map_\ldots} scenario will lead low
+% level \TeX{} errors.
+% \end{function}
+%
+% \section{Using token lists}
+%
+% \begin{function}[EXP]{\tl_to_str:N, \tl_to_str:c}
+% \begin{syntax}
+% \cs{tl_to_str:N} \meta{tl~var}
+% \end{syntax}
+% Converts the content of the \meta{tl~var} into a series of characters
+% with category code $12$ (other) with the exception of spaces, which
+% retain category code $10$ (space). This \meta{string} is then left
+% in the input stream.
+% \end{function}
+%
+% \begin{function}[EXP]{\tl_to_str:n}
+% \begin{syntax}
+% \cs{tl_to_str:n} \Arg{tokens}
+% \end{syntax}
+% Converts the given \meta{tokens} into a series of characters with
+% category code $12$ (other) with the exception of spaces, which
+% retain category code $10$ (space). This \meta{string} is then left
+% in the input stream. Note that this function requires only a single
+% expansion.
+% \begin{texnote}
+% This is the \eTeX{} primitive \cs{detokenize}.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[EXP]{\tl_use:N, \tl_use:c}
+% \begin{syntax}
+% \cs{tl_use:N} \meta{tl~var}
+% \end{syntax}
+% Recovers the content of a \meta{tl~var} and places it
+% directly in the input stream. An error will be raised if the variable
+% does not exist or if it is invalid. Note that it is possible to use
+% a \meta{tl~var} directly without an accessor function.
+% \end{function}
+%
+% \section{Working with the content of token lists}
+%
+% \begin{function}[EXP]{\tl_length:n, \tl_length:V, \tl_length:o}
+% \begin{syntax}
+% \cs{tl_length:n} \Arg{tokens}
+% \end{syntax}
+% Counts the number of token groups in \meta{tokens} and leaves this
+% information in the input stream. Unbraced tokens count as one
+% element as do each token group (|{|\ldots|}|). This process will
+% ignore any unprotected spaces within \meta{tokens}. See also
+% \cs{tl_length:N}. This function requires three expansions,
+% giving an \meta{integer denotation}.
+% \end{function}
+%
+% \begin{function}[EXP]{\tl_length:N, \tl_length:c}
+% \begin{syntax}
+% \cs{tl_length:N} \Arg{tl~var}
+% \end{syntax}
+% Counts the number of token groups in the \meta{tl~var}
+% and leaves this information in the input stream. Unbraced tokens
+% count as one element as do each token group (|{|\ldots|}|). This
+% process will ignore any unprotected spaces within \meta{tokens}.
+% See also \cs{tl_length:n}. This function requires three expansions,
+% giving an \meta{integer denotation}.
+% \end{function}
+%
+% \begin{function}[EXP]{\tl_reverse:n, \tl_reverse:V, \tl_reverse:o}
+% \begin{syntax}
+% \cs{tl_reverse:n} \Arg{tokens}
+% \end{syntax}
+% Reverses the order of the \meta{tokens}, so that
+% \meta{token1}\meta{token2}\meta{token3} \ldots \meta{token$_n$}
+% becomes \meta{token$_n$}\ldots
+% \meta{token3}\meta{token2}\meta{token1}. This process will remove
+% any unprotected space within the \meta{tokens}. Tokens are not reversed
+% within braced token groups, which lose their outer set of braces.
+% See also \cs{tl_reverse:N}.
+% \end{function}
+%
+% \begin{function}{\tl_reverse:N, \tl_reverse:c}
+% \begin{syntax}
+% \cs{tl_reverse:N} \Arg{tl~var}
+% \end{syntax}
+% Reverses the order of the \meta{tokens} stored in
+% \meta{tl~var}, so that
+% \meta{token1}\meta{token2}\meta{token3} \ldots \meta{token$_n$}
+% becomes \meta{token$_n$}\ldots
+% \meta{token3}\meta{token2}\meta{token1}. This process will
+% remove any unprotected spaces within the
+% \meta{token list variable}. Braced token groups are copied without
+% reversing the order of tokens, and the outer set of braces is removed.
+% The reversal is local to the current
+% \TeX{} group. See also \cs{tl_reverse:n}.
+% \end{function}
+%
+% \begin{function}[EXP]{\tl_trim_spaces:n}
+% \begin{syntax}
+% \cs{tl_trim_spaces:n} \meta{token list}
+% \end{syntax}
+% Removes any leading and trailing spaces from the \meta{token list}
+% and leaves the result in the input stream. This process requires
+% two expansions.
+% \end{function}
+%
+% \begin{function}{\tl_trim_spaces:N, \tl_trim_spaces:c}
+% \begin{syntax}
+% \cs{tl_trim_spaces:N} \meta{tl~var}
+% \end{syntax}
+% Removes any leading and trailing spaces from the content of the
+% \meta{tl~var} within the current \TeX{} group.
+% \end{function}
+%
+% \begin{function}{\tl_gtrim_spaces:N, \tl_gtrim_spaces:c}
+% \begin{syntax}
+% \cs{tl_gtrim_spaces:N} \meta{tl~var}
+% \end{syntax}
+% Removes any leading and trailing spaces from the content of the
+% \meta{tl~var} globally.
+% \end{function}
+%
+% \section{The first token from a token list}
+%
+% Functions which deal with either onlt the very first token of a
+% token list or everything except the first token.
+%
+% \begin{function}[EXP]{\tl_head:n, \tl_head:V, \tl_head:v, \tl_head:f}
+% \begin{syntax}
+% \cs{tl_head:n} \Arg{tokens}
+% \end{syntax}
+% Leaves only the first \meta{token} in \meta{tokens} in the input
+% stream, discarding the remainder.
+% \end{function}
+%
+% \begin{function}[EXP]{\tl_head:w}
+% \begin{syntax}
+% \cs{tl_head:w} \Arg{tokens} \cs{q_stop}
+% \end{syntax}
+% Leaves only the first \meta{token} in \meta{tokens} in the input
+% stream, discarding the remainder. This function requires only a
+% single expansion, and so is suitable for use inside an
+% \texttt{o}-type expansion. In general \cs{tl_head:n} should be
+% preferred.
+% \end{function}
+%
+% \begin{function}[EXP]{\tl_tail:n, \tl_tail:V, \tl_tail:v, \tl_tail:f}
+% \begin{syntax}
+% \cs{tl_tail:n} \Arg{tokens}
+% \end{syntax}
+% Discards the first \meta{token} of the \meta{tokens} and leaves the
+% remainder in the input stream.
+% \end{function}
+%
+% \begin{function}[EXP]{\tl_tail:w}
+% \begin{syntax}
+% \cs{tl_tail:w} \Arg{tokens} \cs{q_stop}
+% \end{syntax}
+% Discards the first \meta{token} of the \meta{tokens} and leaves the
+% remainder in the input stream. This function requires only a
+% single expansion, and so is suitable for use inside an
+% \texttt{o}-type expansion. In general \cs{tl_tail:n} should be
+% preferred.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\tl_if_head_eq_catcode:nN}
+% \begin{syntax}
+% \cs{tl_if_head_eq_catcode_p:n} \Arg{token list} \meta{test token}
+% \cs{tl_if_head_eq_catcode:nTF} \Arg{token list} \meta{test token}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the first \meta{token} in the \meta{token list} has the same
+% category code as the \meta{test token}. The branching versions then
+% leave either \meta{true code} or \meta{false code} in the input
+% stream, as appropriate to the truth of the test and the variant of
+% the function chosen. The logical truth of the test is left in the
+% input stream by the predicate
+% version.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]
+% {\tl_if_head_eq_charcode:nN, \tl_if_head_eq_charcode:fN}
+% \begin{syntax}
+% \cs{tl_if_head_eq_charcode_p:n} \Arg{token list} \meta{test token}
+% \cs{tl_if_head_eq_charcode:nTF} \Arg{token list} \meta{test token}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the first \meta{token} in the \meta{token list} has the same
+% character code as the \meta{test token}. The branching versions then
+% leave either \meta{true code} or \meta{false code} in the input
+% stream, as appropriate to the truth of the test and the variant of
+% the function chosen. The logical truth of the test is left in the
+% input stream by the predicate
+% version.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\tl_if_head_eq_meaning:nN}
+% \begin{syntax}
+% \cs{tl_if_head_eq_meaning_p:n} \Arg{token list} \meta{test token}
+% \cs{tl_if_head_eq_meaning:nTF} \Arg{token list} \meta{test token}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the first \meta{token} in the \meta{token list} has the same
+% meaning as the \meta{test token}. The branching versions then
+% leave either \meta{true code} or \meta{false code} in the input
+% stream, as appropriate to the truth of the test and the variant of
+% the function chosen. The logical truth of the test is left in the
+% input stream by the predicate
+% version.
+% \end{function}
+%
+% \section{Viewing token lists}
+%
+% \begin{function}{\tl_show:N, \tl_show:c}
+% \begin{syntax}
+% \cs{tl_show:N} \meta{tl~var}
+% \end{syntax}
+% Displays the content of the \meta{tl~var} on the terminal.
+% \begin{texnote}
+% \cs{tl_show:N} is the \TeX{} primitive \cs{show}.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{\tl_show:n}
+% \begin{syntax}
+% \cs{tl_show:n} \meta{token list}
+% \end{syntax}
+% Displays the \meta{token list} on the terminal.
+% \begin{texnote}
+% \cs{tl_show:n} is the \eTeX{} primitive \cs{showtokens}.
+% \end{texnote}
+% \end{function}
+%
+% \section{Constant token lists}
+%
+% \begin{variable}{\c_job_name_tl}
+% Constant that gets the \enquote{job name} assigned when \TeX{} starts.
+% \begin{texnote}
+% This is the new name for the primitive \cs{jobname}. It is a constant
+% that is set by \TeX{} and should not be overwritten by the package.
+% \end{texnote}
+% \end{variable}
+%
+% \begin{variable}{\c_empty_tl}
+% Constant that is always empty.
+% \end{variable}
+%
+% \begin{variable}{\c_space_tl}
+% A space token contained in a token list (compare this with
+% \cs{c_space_token}). For use where an explicit space is required.
+% \end{variable}
+%
+% \section{Scratch token lists}
+%
+% \begin{variable}{\l_tmpa_tl, \l_tmpb_tl}
+% Scratch token lists for local assignment. These are never used by
+% the kernel code, and so are safe for use with any \LaTeX3-defined
+% function. However, they may be overwritten by other non-kernel
+% code and so should only be used for short-term storage.
+% \end{variable}
+%
+% \begin{variable}{\g_tmpa_tl, \g_tmpb_tl}
+% Scratch token lists for global assignment. These are never used by
+% the kernel code, and so are safe for use with any \LaTeX3-defined
+% function. However, they may be overwritten by other non-kernel
+% code and so should only be used for short-term storage.
+% \end{variable}
+%
+% \section{Experimental token list functions}
+%
+% \begin{function}[EXP,pTF]{\tl_if_single_item:n}
+% \begin{syntax}
+% \cs{tl_if_single_item_p:n} \Arg{token list}
+% \cs{tl_if_single_item:nTF} \Arg{token list}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the token list has exactly one item, i.e., is either
+% a single normal token or a single brace group, surrounded by
+% optional spaces on both sides. In other words, such a token list
+% has length $1$ according to \cs{tl_length:n}. The branching
+% versions then leave either \meta{true code} or \meta{false code}
+% in the input stream, as appropriate to the truth of the test and
+% the variant of the function chosen. The logical truth of the test
+% is left in the input stream by the predicate.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\tl_if_head_begin_group:n}
+% \begin{syntax}
+% \cs{tl_if_head_begin_group_p:n} \Arg{token list}
+% \cs{tl_if_head_begin_group:nTF} \Arg{token list}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the first \meta{token} in the \meta{token list}
+% has catcode~1, i.e., is a begin-group character. This conditional
+% is mainly intended to be used in combination with
+% \cs{tl_if_head_eq_space:n} to check if grabbing an undelimited
+% argument from the token list is safe. The branching
+% versions leave either \meta{true code} or \meta{false code}
+% in the input stream, as appropriate to the truth of the test and
+% the variant of the function chosen. The logical truth of the test
+% is left in the input stream by the predicate.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\tl_if_head_eq_space:n}
+% \begin{syntax}
+% \cs{tl_if_head_eq_space_p:n} \Arg{token list}
+% \cs{tl_if_head_eq_space:nTF} \Arg{token list}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+%^^A Needs rewriting. We need to add a discussion of
+%^^A explicit vs implicit tokens somewhere in the doc.
+% Tests if the first token of the token list is an explicit space,
+% i.e., a token which matches \verb*+ + both in character code and
+% in category code. In the case of an implicit space token, such as
+% \cs{c_space_token}, the test will return \meta{false}.
+% This conditional is mainly intended to be used in combination with
+% \cs{tl_if_head_begin_group:n} to test if grabbing an undelimited
+% argument is safe (see \cs{tl_if_single_token:n} for an example.
+% The branching versions leave either \meta{true code} or
+% \meta{false code} in the input stream, as appropriate to the truth
+% of the test and the variant of the function chosen. The logical
+% truth of the test is left in the input stream by the predicate.
+% \begin{texnote}
+% When \TeX{}'s reads a character of category code $10$ for the
+% first time, it is converted to an explicit space token, with
+% character code $32$, regardless of the initial character code.
+% ``Funny'' spaces with a different category code, can be produced
+% using \cs{tex_lowercase:D}. Explicit spaces are also produced
+% as a result of \cs{token_to_str:N}, \cs{tl_to_str:n}, etc.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\tl_if_single_token:n}
+% \begin{syntax}
+% \cs{tl_if_single_token_p:n} \Arg{token list}
+% \cs{tl_if_single_token:nTF} \Arg{token list}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the token list consists of exactly one token, i.e.,
+% is either a single space character or a single ``normal'' token.
+% Token groups are not single tokens. The branching
+% versions leaves either \meta{true code} or \meta{false code}
+% in the input stream, as appropriate to the truth of the test and
+% the variant of the function chosen. The logical truth of the test
+% is left in the input stream by the predicate.
+% \end{function}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3tl} implementation}
+%
+% \begin{macrocode}
+%<*initex|package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*package>
+\ProvidesExplPackage
+ {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
+\package_check_loaded_expl:
+%</package>
+% \end{macrocode}
+%
+% A token list variable is a \TeX{} macro that holds tokens. By using the
+% \eTeX{} primitive \cs{unexpanded} inside a \TeX{} \cs{edef} it is
+% possible to store any tokens, including |#|, in this way.
+%
+% \subsection{Functions}
+%
+% \begin{macro}{\tl_new:N, \tl_new:c}
+% Creating new token list variables is a case of checking for an
+% existing definition and if free doing the definition.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \tl_new:N #1
+ {
+ \chk_if_free_cs:N #1
+ \cs_gset_eq:NN #1 \c_empty_tl
+ }
+\cs_generate_variant:Nn \tl_new:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\tl_const:Nn, \tl_const:Nx, \tl_const:cn, \tl_const:cx}
+% Constants are also easy to generate.
+% \begin{macrocode}
+\cs_new_protected:Npn \tl_const:Nn #1#2
+ {
+ \chk_if_free_cs:N #1
+ \cs_gset_nopar:Npx #1 { \exp_not:n {#2} }
+ }
+\cs_new_protected:Npn \tl_const:Nx #1#2
+ {
+ \chk_if_free_cs:N #1
+ \cs_gset_nopar:Npx #1 {#2}
+ }
+\cs_generate_variant:Nn \tl_const:Nn { c }
+\cs_generate_variant:Nn \tl_const:Nx { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\tl_clear:N, \tl_clear:c}
+% \begin{macro}{\tl_gclear:N, \tl_gclear:c}
+% Clearing a token list variable means setting it to an empty value.
+% Error checking will be sorted out by the parent function.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \tl_clear:N #1
+ { \tl_set_eq:NN #1 \c_empty_tl }
+\cs_new_protected_nopar:Npn \tl_gclear:N #1
+ { \tl_gset_eq:NN #1 \c_empty_tl }
+\cs_generate_variant:Nn \tl_clear:N { c }
+\cs_generate_variant:Nn \tl_gclear:N { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\tl_clear_new:N, \tl_clear_new:c}
+% \begin{macro}{\tl_gclear_new:N, \tl_gclear_new:c}
+% Clearing a token list variable means setting it to an empty value.
+% Error checking will be sorted out by the parent function.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \tl_clear_new:N #1
+ { \cs_if_exist:NTF #1 { \tl_clear:N #1 } { \tl_new:N #1 } }
+\cs_new_protected_nopar:Npn \tl_gclear_new:N #1
+ { \cs_if_exist:NTF #1 { \tl_gclear:N #1 } { \tl_new:N #1 } }
+\cs_generate_variant:Nn \tl_clear_new:N { c }
+\cs_generate_variant:Nn \tl_gclear_new:N { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\tl_set_eq:NN, \tl_set_eq:Nc, \tl_set_eq:cN, \tl_set_eq:cc}
+% \begin{macro}{\tl_gset_eq:NN, \tl_gset_eq:Nc, \tl_gset_eq:cN, \tl_gset_eq:cc}
+% For setting token list variables equal to each other.
+% \begin{macrocode}
+\cs_new_eq:NN \tl_set_eq:NN \cs_set_eq:NN
+\cs_new_eq:NN \tl_set_eq:cN \cs_set_eq:cN
+\cs_new_eq:NN \tl_set_eq:Nc \cs_set_eq:Nc
+\cs_new_eq:NN \tl_set_eq:cc \cs_set_eq:cc
+\cs_new_eq:NN \tl_gset_eq:NN \cs_gset_eq:NN
+\cs_new_eq:NN \tl_gset_eq:cN \cs_gset_eq:cN
+\cs_new_eq:NN \tl_gset_eq:Nc \cs_gset_eq:Nc
+\cs_new_eq:NN \tl_gset_eq:cc \cs_gset_eq:cc
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Adding to token list variables}
+%
+% \begin{macro}
+% {
+% \tl_set:Nn, \tl_set:NV, \tl_set:Nv, \tl_set:No, \tl_set:Nf, \tl_set:Nx,
+% \tl_set:cn, \tl_set:NV, \tl_set:Nv, \tl_set:co, \tl_set:cf, \tl_set:cx
+% }
+% \begin{macro}
+% {
+% \tl_gset:Nn, \tl_gset:NV, \tl_gset:Nv,
+% \tl_gset:No, \tl_gset:Nf, \tl_gset:Nx,
+% \tl_gset:cn, \tl_gset:NV, \tl_gset:Nv,
+% \tl_gset:co, \tl_gset:cf, \tl_gset:cx
+% }
+% By using \cs{exp_not:n} token list variables can contain |#| tokens,
+% which makes the token list registers provided by \TeX{}
+% more or less redundant. The \cs{tl_set:No} version is done
+% \enquote{by hand} as it is used quite a lot.
+% \begin{macrocode}
+\cs_new_protected:Npn \tl_set:Nn #1#2
+ { \cs_set_nopar:Npx #1 { \exp_not:n {#2} } }
+\cs_new_protected:Npn \tl_set:No #1#2
+ { \cs_set_nopar:Npx #1 { \exp_not:o {#2} } }
+\cs_new_protected:Npn \tl_set:Nx #1#2
+ { \cs_set_nopar:Npx #1 {#2} }
+\cs_new_protected:Npn \tl_gset:Nn #1#2
+ { \cs_gset_nopar:Npx #1 { \exp_not:n {#2} } }
+\cs_new_protected:Npn \tl_gset:No #1#2
+ { \cs_gset_nopar:Npx #1 { \exp_not:o {#2} } }
+\cs_new_protected:Npn \tl_gset:Nx #1#2
+ { \cs_gset_nopar:Npx #1 {#2} }
+\cs_generate_variant:Nn \tl_set:Nn { NV , Nv , Nf }
+\cs_generate_variant:Nn \tl_set:Nx { c }
+\cs_generate_variant:Nn \tl_set:Nn { c, co , cV , cv , cf }
+\cs_generate_variant:Nn \tl_gset:Nn { NV , Nv , Nf }
+\cs_generate_variant:Nn \tl_gset:Nx { c }
+\cs_generate_variant:Nn \tl_gset:Nn { c, co , cV , cv , cf }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \tl_put_left:Nn, \tl_put_left:NV, \tl_put_left:No, \tl_put_left:Nx,
+% \tl_put_left:cn, \tl_put_left:cV, \tl_put_left:co, \tl_put_left:cx
+% }
+% \begin{macro}
+% {
+% \tl_gput_left:Nn, \tl_gput_left:NV, \tl_gput_left:No, \tl_gput_left:Nx,
+% \tl_gput_left:cn, \tl_gput_left:cV, \tl_gput_left:co, \tl_gput_left:cx
+% }
+% Adding to the left is done directly to gain a little performance.
+% \begin{macrocode}
+\cs_new_protected:Npn \tl_put_left:Nn #1#2
+ { \cs_set_nopar:Npx #1 { \exp_not:n {#2} \exp_not:o #1 } }
+\cs_new_protected:Npn \tl_put_left:NV #1#2
+ { \cs_set_nopar:Npx #1 { \exp_not:V #2 \exp_not:o #1 } }
+\cs_new_protected:Npn \tl_put_left:No #1#2
+ { \cs_set_nopar:Npx #1 { \exp_not:o {#2} \exp_not:o #1 } }
+\cs_new_protected:Npn \tl_put_left:Nx #1#2
+ { \cs_set_nopar:Npx #1 { #2 \exp_not:o #1 } }
+\cs_new_protected:Npn \tl_gput_left:Nn #1#2
+ { \cs_gset_nopar:Npx #1 { \exp_not:n {#2} \exp_not:o #1 } }
+\cs_new_protected:Npn \tl_gput_left:NV #1#2
+ { \cs_gset_nopar:Npx #1 { \exp_not:V #2 \exp_not:o #1 } }
+\cs_new_protected:Npn \tl_gput_left:No #1#2
+ { \cs_gset_nopar:Npx #1 { \exp_not:o {#2} \exp_not:o #1 } }
+\cs_new_protected:Npn \tl_gput_left:Nx #1#2
+ { \cs_gset_nopar:Npx #1 { #2 \exp_not:o {#1} } }
+\cs_generate_variant:Nn \tl_put_left:Nn { c }
+\cs_generate_variant:Nn \tl_put_left:NV { c }
+\cs_generate_variant:Nn \tl_put_left:No { c }
+\cs_generate_variant:Nn \tl_put_left:Nx { c }
+\cs_generate_variant:Nn \tl_gput_left:Nn { c }
+\cs_generate_variant:Nn \tl_gput_left:NV { c }
+\cs_generate_variant:Nn \tl_gput_left:No { c }
+\cs_generate_variant:Nn \tl_gput_left:Nx { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \tl_put_right:Nn, \tl_put_right:NV, \tl_put_right:No, \tl_put_right:Nx,
+% \tl_put_right:cn, \tl_put_right:cV, \tl_put_right:co, \tl_put_right:cx
+% }
+% \begin{macro}
+% {
+% \tl_gput_right:Nn, \tl_gput_right:NV, \tl_gput_right:No,
+% \tl_gput_right:Nx,
+% \tl_gput_right:cn, \tl_gput_right:cV, \tl_gput_right:co,
+% \tl_gput_right:cx
+% }
+% The same on the right.
+% \begin{macrocode}
+\cs_new_protected:Npn \tl_put_right:Nn #1#2
+ { \cs_set_nopar:Npx #1 { \exp_not:o #1 \exp_not:n {#2} } }
+\cs_new_protected:Npn \tl_put_right:NV #1#2
+ { \cs_set_nopar:Npx #1 { \exp_not:o #1 \exp_not:V #2 } }
+\cs_new_protected:Npn \tl_put_right:No #1#2
+ { \cs_set_nopar:Npx #1 { \exp_not:o #1 \exp_not:o {#2} } }
+\cs_new_protected:Npn \tl_put_right:Nx #1#2
+ { \cs_set_nopar:Npx #1 { \exp_not:o #1 #2 } }
+\cs_new_protected:Npn \tl_gput_right:Nn #1#2
+ { \cs_gset_nopar:Npx #1 { \exp_not:o #1 \exp_not:n {#2} } }
+\cs_new_protected:Npn \tl_gput_right:NV #1#2
+ { \cs_gset_nopar:Npx #1 { \exp_not:o #1 \exp_not:V #2 } }
+\cs_new_protected:Npn \tl_gput_right:No #1#2
+ { \cs_gset_nopar:Npx #1 { \exp_not:o #1 \exp_not:o {#2} } }
+\cs_new_protected:Npn \tl_gput_right:Nx #1#2
+ { \cs_gset_nopar:Npx #1 { \exp_not:o {#1} #2 } }
+\cs_generate_variant:Nn \tl_put_right:Nn { c }
+\cs_generate_variant:Nn \tl_put_right:NV { c }
+\cs_generate_variant:Nn \tl_put_right:No { c }
+\cs_generate_variant:Nn \tl_put_right:Nx { c }
+\cs_generate_variant:Nn \tl_gput_right:Nn { c }
+\cs_generate_variant:Nn \tl_gput_right:NV { c }
+\cs_generate_variant:Nn \tl_gput_right:No { c }
+\cs_generate_variant:Nn \tl_gput_right:Nx { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Reassigning token list category codes}
+%
+% \begin{variable}{\c_tl_rescan_marker_tl}
+% The rescanning code needs a special token list containing the same
+% character with two different category codes. This is set up here,
+% while the detail is described below.
+% \begin{macrocode}
+\group_begin:
+ \tex_lccode:D `\A = `\@ \scan_stop:
+ \tex_lccode:D `\B = `\@ \scan_stop:
+ \tex_catcode:D `\A = 8 \scan_stop:
+ \tex_catcode:D `\B = 3 \scan_stop:
+\tex_lowercase:D
+ {
+ \group_end:
+ \tl_const:Nn \c_tl_rescan_marker_tl { A B }
+ }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_tl_rescan_tl}
+% A token list variable to actually store the material being processed.
+% \begin{macrocode}
+\tl_new:N \l_tl_rescan_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}
+% {
+% \tl_set_rescan:Nnn, \tl_set_rescan:Nno,
+% \tl_set_rescan:cnn, \tl_set_rescan:cno
+% }
+% \begin{macro}
+% {
+% \tl_gset_rescan:Nnn, \tl_gset_rescan:Nno,
+% \tl_gset_rescan:cnn, \tl_gset_rescan:cno
+% }
+% \begin{macro}[aux]{\tl_set_rescan_aux:NNnn}
+% \begin{macro}[aux]{\tl_rescan_aux:w}
+% The idea here is to deal cleanly with the problem that
+% \cs{tex_scantokens:D} treats the argument as a file, and without
+% the correct settings a \TeX{} error occurs:
+% \begin{verbatim}
+% ! File ended while scanning definition of ...
+% \end{verbatim}
+% When expanding a token list this can be handled using \cs{exp_not:N}
+% but this fails if the token list is not being expanded. So instead
+% a delimited argument is used with an end marker which cannot appear
+% within the token list which is scanned: two |@| symbols with different
+% category codes. The rescanned token list cannot contain the end marker,
+% because all |@| present in the token list are read with the same category
+% code. The setting of \cs{tex_endlinechar:D}
+% is needed to avoid introducing an extraneous space in the result.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \tl_set_rescan:Nnn
+ { \tl_set_rescan_aux:NNnn \tl_set:Nn }
+\cs_new_protected_nopar:Npn \tl_gset_rescan:Nnn
+ { \tl_set_rescan_aux:NNnn \tl_gset:Nn }
+\cs_new_protected:Npn \tl_set_rescan_aux:NNnn #1#2#3#4
+ {
+ \group_begin:
+ \exp_args:No \etex_everyeof:D { \c_tl_rescan_marker_tl }
+ \tex_endlinechar:D \c_minus_one
+ #3
+ \tl_clear:N \l_tl_rescan_tl
+ \exp_after:wN \tl_rescan_aux:w \etex_scantokens:D {#4}
+ \exp_args:NNNo \group_end:
+ #1 #2 \l_tl_rescan_tl
+ }
+\cs_new_nopar:Npx \tl_rescan_aux:w
+ {
+ \cs_set_protected:Npn \exp_not:N \tl_rescan_aux:w ##1
+ \c_tl_rescan_marker_tl
+ { \tl_set:Nn \exp_not:N \l_tl_rescan_tl {##1} }
+ }
+\tl_rescan_aux:w
+\cs_generate_variant:Nn \tl_set_rescan:Nnn { Nno }
+\cs_generate_variant:Nn \tl_set_rescan:Nnn { c , cno }
+\cs_generate_variant:Nn \tl_gset_rescan:Nnn { Nno }
+\cs_generate_variant:Nn \tl_gset_rescan:Nnn { c , cno }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\tl_set_rescan:Nnx, \tl_set_rescan:cnx}
+% \begin{macro}{\tl_gset_rescan:Nnx, \tl_gset_rescan:cnx}
+% \begin{macro}[aux]{\tl_set_rescan_aux:NNnx}
+% With \texttt{x}-type expansion the \cs{tex_everyoef:D} method
+% does apply and the code is simple.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \tl_set_rescan:Nnx
+ { \tl_set_rescan_aux:NNnx \tl_set:Nn }
+\cs_new_protected_nopar:Npn \tl_gset_rescan:Nnx
+ { \tl_set_rescan_aux:NNnx \tl_gset:Nn }
+\cs_new_protected_nopar:Npn \tl_set_rescan_aux:NNnx #1#2#3#4
+ {
+ \group_begin:
+ \etex_everyeof:D { \exp_not:N }
+ \tex_endlinechar:D \c_minus_one
+ #3
+ \tl_set:Nx \l_tl_rescan_tl { \etex_scantokens:D {#4} }
+ \exp_args:NNNo \group_end:
+ #1 #2 \l_tl_rescan_tl
+ }
+\cs_generate_variant:Nn \tl_set_rescan:Nnx { c }
+\cs_generate_variant:Nn \tl_gset_rescan:Nnx { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\tl_rescan:nn}
+% The same idea is also applied to in line token lists.
+% \begin{macrocode}
+\cs_new_protected:Npn \tl_rescan:nn #1#2
+ {
+ \group_begin:
+ \exp_args:No \etex_everyeof:D { \c_tl_rescan_marker_tl }
+ \tex_endlinechar:D \c_minus_one
+ #1
+ \exp_after:wN \tl_rescan_aux:w \etex_scantokens:D {#2}
+ \exp_args:No \group_end:
+ \l_tl_rescan_tl
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Reassigning token list character codes}
+%
+% \begin{macro}{\tl_to_lowercase:n}
+% \begin{macro}{\tl_to_uppercase:n}
+% Just some names for a few primitives.
+% \begin{macrocode}
+\cs_new_eq:NN \tl_to_lowercase:n \tex_lowercase:D
+\cs_new_eq:NN \tl_to_uppercase:n \tex_uppercase:D
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Modifying token list variables}
+%
+% \begin{variable}{\l_tl_replace_tl}
+% A scratch variable for doing token replacement.
+% \begin{macrocode}
+\tl_new:N \l_tl_replace_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\tl_replace_once:Nnn, \tl_replace_once:cnn}
+% \begin{macro}{\tl_greplace_once:Nnn, \tl_greplace_once:cnn}
+% \begin{macro}[aux]{\tl_replace_once_aux:NNnn}
+% The concept here is that only the first occurrence should be
+% replaced. The first step is to define an auxiliary which will
+% match the appropriate item, with a trailing marker. If the last token
+% is the marker there is nothing to do, otherwise replace the token
+% and clean up (hence the second use of \cs{tl_tmp:w}). To prevent
+% loosing braces or spaces there are a couple of empty groups and
+% the strange-looking \cs{use:n}. There is a \cs{q_nil} between the
+% original and the search input, to prevent cases where
+% the end of the original and the start of the search run together
+% to give an erroneous test result.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \tl_replace_once:Nnn
+ { \tl_replace_once_aux:NNnn \tl_set_eq:NN }
+\cs_new_protected_nopar:Npn \tl_greplace_once:Nnn
+ { \tl_replace_once_aux:NNnn \tl_gset_eq:NN }
+\cs_new_protected:Npn \tl_replace_once_aux:NNnn #1#2#3#4
+ {
+ \cs_set_protected:Npx \tl_tmp:w ##1 #3 ##2 \q_stop
+ {
+ \exp_not:N \quark_if_no_value:nF {##2}
+ {
+ \tl_set:No \exp_not:N \l_tl_replace_tl { ##1 \exp_not:n{#4} }
+ \exp_not:n
+ {
+ \cs_set_protected:Npn \tl_tmp:w ##1 \q_nil #3 \q_no_value
+ { \tl_put_right:No \l_tl_replace_tl {##1} }
+ }
+ \exp_not:n { \tl_tmp:w \prg_do_nothing: } ##2
+ \exp_not:n { #1 #2 \l_tl_replace_tl }
+ }
+ }
+ \exp_after:wN \tl_tmp:w \exp_after:wN \prg_do_nothing:
+ #2 \q_nil #3 \q_no_value \q_stop
+ }
+\cs_generate_variant:Nn \tl_replace_once:Nnn { c }
+\cs_generate_variant:Nn \tl_greplace_once:Nnn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\tl_replace_all:Nnn, \tl_replace_all:cnn}
+% \begin{macro}{\tl_greplace_all:Nnn, \tl_greplace_all:cnn}
+% \begin{macro}[aux]{\tl_replace_all_aux:NNnn}
+% A similar approach here but with a loop built in.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \tl_replace_all:Nnn
+ { \tl_replace_all_aux:NNnn \tl_set_eq:NN }
+\cs_new_protected_nopar:Npn \tl_greplace_all:Nnn
+ { \tl_replace_all_aux:NNnn \tl_gset_eq:NN }
+\cs_new_protected:Npn \tl_replace_all_aux:NNnn #1#2#3#4
+ {
+ \tl_clear:N \l_tl_replace_tl
+ \cs_set_protected:Npx \tl_tmp:w ##1 #3 ##2 \q_stop
+ {
+ \exp_not:N \quark_if_no_value:nTF {##2}
+ {
+ \exp_not:n
+ {
+ \cs_set_protected:Npn \tl_tmp:w ##1 \q_nil ##2 \q_stop
+ { \tl_put_right:No \l_tl_replace_tl {##1} }
+ }
+ \exp_not:N \tl_tmp:w ##1 \exp_not:N \q_stop
+ }
+ {
+ \exp_not:n { \tl_put_right:No \l_tl_replace_tl }
+ { ##1 \exp_not:n{#4} }
+ \exp_not:n { \tl_tmp:w \prg_do_nothing: } ##2 \exp_not:N \q_stop
+ }
+ }
+ \exp_after:wN \tl_tmp:w \exp_after:wN \prg_do_nothing:
+ #2 \q_nil #3 \q_no_value \q_stop
+ #1 #2 \l_tl_replace_tl
+ }
+\cs_generate_variant:Nn \tl_replace_all:Nnn { c }
+\cs_generate_variant:Nn \tl_greplace_all:Nnn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\tl_remove_once:Nn, \tl_remove_once:cn}
+% \begin{macro}{\tl_gremove_once:Nn, \tl_gremove_once:cn}
+% Removal is just a special case of replacement.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \tl_remove_once:Nn #1#2
+ { \tl_replace_once:Nnn #1 {#2} { } }
+\cs_new_protected_nopar:Npn \tl_gremove_once:Nn #1#2
+ { \tl_greplace_once:Nnn #1 {#2} { } }
+\cs_generate_variant:Nn \tl_remove_once:Nn { c }
+\cs_generate_variant:Nn \tl_gremove_once:Nn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\tl_remove_all:Nn, \tl_remove_all:cn}
+% \begin{macro}{\tl_gremove_all:Nn, \tl_gremove_all:cn}
+% Removal is just a special case of replacement.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \tl_remove_all:Nn #1#2
+ { \tl_replace_all:Nnn #1 {#2} { } }
+\cs_new_protected_nopar:Npn \tl_gremove_all:Nn #1#2
+ { \tl_greplace_all:Nnn #1 {#2} { } }
+\cs_generate_variant:Nn \tl_remove_all:Nn { c }
+\cs_generate_variant:Nn \tl_gremove_all:Nn { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Token list conditionals}
+%
+% \begin{macro}[pTF]{\tl_if_blank:n,\tl_if_blank:V,\tl_if_blank:o}
+% \begin{macro}[aux]{\tl_if_blank_p_aux:NNw}
+% \TeX{} skips spaces when reading a non-delimited arguments. Thus,
+% a \meta{token list} is blank if and only if \cs{use_none:n}
+% \meta{token list} |?| is empty. For performance reasons, we hard-code
+% the emptyness test done in \cs{tl_if_empty:n(TF)}: convert to harmless
+% characters with \cs{tl_to_str:n}, and then use
+% \cs{if_meaning:w} \cs{q_nil} |...| \cs{q_nil}.
+% Note that converting to a string is done after reading the delimited
+% argument for \cs{use_none:n}. The similar construction
+% \cs{exp_after:wN} \cs{use_none:n} \cs{tl_to_str:n} \Arg{token list} |?|
+% would fail if the token list contains the control sequence \cs{ },
+% while \cs{tex_escapechar:D} is a space or is unprintable.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \tl_if_blank:n #1 { p , T , F , TF }
+ { \tl_if_empty_return:o { \use_none:n #1 ? } }
+\cs_generate_variant:Nn \tl_if_blank_p:n { V }
+\cs_generate_variant:Nn \tl_if_blank:nT { V }
+\cs_generate_variant:Nn \tl_if_blank:nF { V }
+\cs_generate_variant:Nn \tl_if_blank:nTF { V }
+\cs_generate_variant:Nn \tl_if_blank_p:n { o }
+\cs_generate_variant:Nn \tl_if_blank:nT { o }
+\cs_generate_variant:Nn \tl_if_blank:nF { o }
+\cs_generate_variant:Nn \tl_if_blank:nTF { o }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\tl_if_empty:N,\tl_if_empty:c}
+% These functions check whether the token list in the argument is
+% empty and execute the proper code from their argument(s).
+% \begin{macrocode}
+\prg_set_conditional:Npnn \tl_if_empty:N #1 { p , T , F , TF }
+ {
+ \if_meaning:w #1 \c_empty_tl
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\cs_generate_variant:Nn \tl_if_empty_p:N { c }
+\cs_generate_variant:Nn \tl_if_empty:NT { c }
+\cs_generate_variant:Nn \tl_if_empty:NF { c }
+\cs_generate_variant:Nn \tl_if_empty:NTF { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\tl_if_empty:n,\tl_if_empty:V}
+% It would be tempting to just use |\if_meaning:w \q_nil #1 \q_nil| as
+% a test since this works really well. However, it fails on a token
+% list starting with |\q_nil| of course but more troubling is the
+% case where argument is a complete conditional such as |\if_true:|
+% a |\else:| b |\fi:| because then |\if_true:| is used by
+% |\if_meaning:w|, the test turns out false, the |\else:| executes
+% the false branch, the |\fi:| ends it and the |\q_nil| at the end
+% starts executing\dots{} A safer route is to convert the entire
+% token list into harmless characters first and then compare
+% that. This way the test will even accept |\q_nil| as the first
+% token.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \tl_if_empty:n #1 { p,TF,T,F} {
+ \exp_after:wN \if_meaning:w \exp_after:wN \q_nil \tl_to_str:n {#1} \q_nil
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+}
+\cs_generate_variant:Nn \tl_if_empty_p:n { V }
+\cs_generate_variant:Nn \tl_if_empty:nTF { V }
+\cs_generate_variant:Nn \tl_if_empty:nT { V }
+\cs_generate_variant:Nn \tl_if_empty:nF { V }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\tl_if_empty:o}
+% \begin{macro}[EXP,aux]{\tl_if_empty_return:o}
+% The auxiliary function \cs{tl_if_empty_return:o} is for use
+% in conditionals on token lists, which mostly reduce to testing
+% if a given token list is empty after applying a simple function
+% to it.
+% The test for emptyness is based on \cs{tl_if_empty:n(TF)}, but
+% the expansion is hard-coded for efficiency, as this auxiliary
+% function is used in many places.
+% Note that this works because \cs{tl_to_str:n} expands tokens
+% that follow until reading a catcode $1$ (begin-group) token.
+% \begin{macrocode}
+\cs_new:Npn \tl_if_empty_return:o #1 {
+ \exp_after:wN \if_meaning:w \exp_after:wN \q_nil
+ \tl_to_str:n \exp_after:wN {#1} \q_nil
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+}
+\prg_new_conditional:Npnn \tl_if_empty:o #1 { p,TF,T,F}
+ { \tl_if_empty_return:o {#1} }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\tl_if_eq:NN,\tl_if_eq:Nc,\tl_if_eq:cN,\tl_if_eq:cc}
+% Returns \cs{c_true_bool} if and only if the two token list variables are
+% equal.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \tl_if_eq:NN #1#2 { p , T , F , TF }
+ {
+ \if_meaning:w #1 #2
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\cs_generate_variant:Nn \tl_if_eq_p:NN { Nc , c , cc }
+\cs_generate_variant:Nn \tl_if_eq:NNTF { Nc , c , cc }
+\cs_generate_variant:Nn \tl_if_eq:NNT { Nc , c , cc }
+\cs_generate_variant:Nn \tl_if_eq:NNF { Nc , c , cc }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[TF]{\tl_if_eq:nn}
+% \begin{variable}{\l_tl_tmpa_tl, \l_tl_tmpb_tl}
+% A simple store and compare routine.
+% \begin{macrocode}
+\prg_new_protected_conditional:Npnn \tl_if_eq:nn #1#2 { T , F , TF }
+ {
+ \group_begin:
+ \tl_set:Nn \l_tl_tmpa_tl {#1}
+ \tl_set:Nn \l_tl_tmpb_tl {#2}
+ \if_meaning:w \l_tl_tmpa_tl \l_tl_tmpb_tl
+ \group_end:
+ \prg_return_true:
+ \else:
+ \group_end:
+ \prg_return_false:
+ \fi:
+ }
+\tl_new:N \l_tl_tmpa_tl
+\tl_new:N \l_tl_tmpb_tl
+% \end{macrocode}
+% \end{variable}
+% \end{macro}
+%
+% \begin{macro}[TF]{\tl_if_in:Nn, \tl_if_in:cn}
+% See \cs{tl_if_in:nn(TF)} for further comments. Here we simply
+% expand the token list variable and pass it to \cs{tl_if_in:nn(TF)}.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \tl_if_in:NnT { \exp_args:No \tl_if_in:nnT }
+\cs_new_protected_nopar:Npn \tl_if_in:NnF { \exp_args:No \tl_if_in:nnF }
+\cs_new_protected_nopar:Npn \tl_if_in:NnTF { \exp_args:No \tl_if_in:nnTF }
+\cs_generate_variant:Nn \tl_if_in:NnT { c }
+\cs_generate_variant:Nn \tl_if_in:NnF { c }
+\cs_generate_variant:Nn \tl_if_in:NnTF { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[TF]{\tl_if_in:nn, \tl_if_in:Vn, \tl_if_in:on, \tl_if_in:no}
+% Once more, the test relies on \cs{tl_to_str:n} for robustness.
+% The function \cs{tl_tmp:w} removes tokens until the first occurrence
+% of |#2|. If this does not appear in |#1|, then the final |#2| is removed,
+% leaving an empty token list. Otherwise some tokens remain, and the
+% test is false. See \cs{tl_if_empty:n(TF)} for details on
+% the emptyness test.
+%
+% Special care is needed to treat correctly cases like
+% |\tl_if_in:nnTF {a state}{states}|, where |#1#2| contains |#2| before
+% the end. To cater for this case, we insert |{}{}| between the two token
+% lists. This marker may not appear in |#2| because of \TeX{} limitations
+% on what can delimit a parameter, hence we are safe. Using two brace
+% groups makes the test work also for empty arguments.
+% \begin{macrocode}
+\prg_new_protected_conditional:Npnn \tl_if_in:nn #1#2 { T , F , TF }
+ {
+ \cs_set:Npn \tl_tmp:w ##1 #2 { }
+ \tl_if_empty:oTF { \tl_tmp:w #1 {} {} #2 }
+ { \prg_return_false: } { \prg_return_true: }
+ }
+\cs_generate_variant:Nn \tl_if_in:nnT { V }
+\cs_generate_variant:Nn \tl_if_in:nnF { V }
+\cs_generate_variant:Nn \tl_if_in:nnTF { V }
+\cs_generate_variant:Nn \tl_if_in:nnT { o }
+\cs_generate_variant:Nn \tl_if_in:nnF { o }
+\cs_generate_variant:Nn \tl_if_in:nnTF { o }
+\cs_generate_variant:Nn \tl_if_in:nnT { no }
+\cs_generate_variant:Nn \tl_if_in:nnF { no }
+\cs_generate_variant:Nn \tl_if_in:nnTF { no }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\tl_if_single:n}
+% \begin{macro}[aux]{\tl_if_single_aux:n}
+% If the argument is a single token, or a single brace group
+% preceeded by optional (explicit) spaces, or a non-zero number
+% of spaces.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \tl_if_single:n #1 { p , T , F , TF }
+ {
+ \tl_if_blank:nTF {#1}
+ { \tl_if_empty:nTF {#1} { \prg_return_false: } { \prg_return_true: } }
+ { \tl_if_single_aux:n {#1} }
+ }
+\prg_new_conditional:Npnn \tl_if_single:N #1 { p , T , F , TF }
+ {
+ \tl_if_blank:oTF #1
+ { \tl_if_empty:NTF #1 { \prg_return_false: } { \prg_return_true: } }
+ { \exp_args:No \tl_if_single_aux:n {#1} }
+ }
+\cs_new:Npn \tl_if_single_aux:n #1
+ { \tl_if_empty_return:o { \use_none:n #1 } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Mapping to token lists}
+%
+% \begin{macro}{\tl_map_function:nN}
+% \begin{macro}{\tl_map_function:NN, \tl_map_function:cN}
+% \begin{macro}[aux]{\tl_map_function_aux:NN}
+% Expandable loop macro for token lists. These have the advantage of not
+% needing to test if the argument is empty, because if it is, the stop
+% marker will be read immediately and the loop terminated.
+% \begin{macrocode}
+\cs_new:Npn \tl_map_function:nN #1#2
+ { \tl_map_function_aux:Nn #2 #1 \q_recursion_tail \q_recursion_stop }
+\cs_new_nopar:Npn \tl_map_function:NN #1#2
+ {
+ \exp_after:wN \tl_map_function_aux:Nn
+ \exp_after:wN #2 #1 \q_recursion_tail \q_recursion_stop
+ }
+\cs_new:Npn \tl_map_function_aux:Nn #1#2
+ {
+ \quark_if_recursion_tail_stop:n {#2}
+ #1 {#2} \tl_map_function_aux:Nn #1
+ }
+\cs_generate_variant:Nn \tl_map_function:NN { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\tl_map_inline:nn}
+% \begin{macro}{\tl_map_inline:Nn, \tl_map_inline:cn}
+% \begin{macro}[aux]{\tl_map_inline_aux:n}
+% \begin{variable}{\g_tl_inline_level_int}
+% The inline functions are straight forward by now. We use a little
+% trick with the counter \cs{g_tl_inline_level_int} to make
+% them nestable. We can also make use of \cs{tl_map_function:Nn}
+% from before. (\cs{g_tl_inline_level_int} is defined in \pkg{l3int}
+% for order-of-loading reasons.)
+% \begin{macrocode}
+\cs_new_protected:Npn \tl_map_inline:nn #1#2
+ {
+ \int_gincr:N \g_tl_inline_level_int
+ \cs_gset:cpn { tl_map_inline_ \int_use:N \g_tl_inline_level_int :n }
+ ##1 {#2}
+ \exp_args:Nc \tl_map_function_aux:Nn
+ { tl_map_inline_ \int_use:N \g_tl_inline_level_int :n }
+ #1 \q_recursion_tail \q_recursion_stop
+ \int_gdecr:N \g_tl_inline_level_int
+ }
+\cs_new_protected:Npn \tl_map_inline:Nn #1#2
+ {
+ \int_gincr:N \g_tl_inline_level_int
+ \cs_gset:cpn { tl_map_inline_ \int_use:N \g_tl_inline_level_int :n }
+ ##1 {#2}
+ \exp_last_unbraced:NcV \tl_map_function_aux:Nn
+ { tl_map_inline_ \int_use:N \g_tl_inline_level_int :n }
+ #1 \q_recursion_tail\q_recursion_stop
+ \int_gdecr:N \g_tl_inline_level_int
+ }
+\cs_generate_variant:Nn \tl_map_inline:Nn { c }
+% \end{macrocode}
+% \end{variable}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\tl_map_variable:nNn}
+% \begin{macro}{\tl_map_variable:NNn, \tl_map_variable:cNn}
+% \begin{macro}[aux]{\tl_map_variable_aux:NnN}
+% \cs{tl_map_variable:nNn} \meta{token list} \meta{temp} \meta{action}
+% assigns
+% \meta{temp} to each element and executes \meta{action}.
+% \begin{macrocode}
+\cs_new_protected:Npn \tl_map_variable:nNn #1#2#3
+ { \tl_map_variable_aux:Nnn #2 {#3} #1 \q_recursion_tail \q_recursion_stop }
+\cs_new_protected_nopar:Npn \tl_map_variable:NNn
+ { \exp_args:No \tl_map_variable:nNn }
+\cs_new_protected:Npn \tl_map_variable_aux:Nnn #1#2#3
+ {
+ \tl_set:Nn #1 {#3}
+ \quark_if_recursion_tail_stop:N #1
+ #2 \tl_map_variable_aux:Nnn #1 {#2}
+ }
+\cs_generate_variant:Nn \tl_map_variable:NNn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\tl_map_break:}
+% The break statement.
+% \begin{macrocode}
+\cs_new_eq:NN \tl_map_break: \use_none_delimit_by_q_recursion_stop:w
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Using token lists}
+%
+% \begin{macro}{\tl_to_str:n}
+% Another name for a primitive.
+% \begin{macrocode}
+\cs_new_eq:NN \tl_to_str:n \etex_detokenize:D
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\tl_to_str:N, \tl_to_str:c}
+% These functions return the replacement text of a token list as a
+% string.
+% \begin{macrocode}
+\cs_new_nopar:Npn \tl_to_str:N #1 { \etex_detokenize:D \exp_after:wN {#1} }
+\cs_generate_variant:Nn \tl_to_str:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\tl_use:N, \tl_use:c}
+% \begin{macro}[aux]{\tl_error_message:}
+% Token lists which are simply not defined will give a clear \TeX{}
+% error here. No such luck for ones equal to \cs{scan_stop:} so
+% instead a test is made and if there is an issue an error is forced.
+% \begin{macrocode}
+\cs_new_eq:NN \tl_use:N \prg_do_nothing:
+\cs_new_nopar:Npn \tl_use:c #1
+ {
+ \if_cs_exist:w #1 \cs_end:
+ \cs:w #1 \exp_after:wN \cs_end:
+ \else:
+ \exp_after:wN \tl_error_message:
+ \fi:
+ }
+\group_begin:
+\tex_catcode:D `\! = 11 \scan_stop:
+\tex_catcode:D `\ = 11\scan_stop:%
+\cs_gset_nopar:Npn\tl_error_message:{\undefined variable name!}%
+\group_end:%
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Working with the contents of token lists}
+%
+% \begin{macro}{\tl_length:n, \tl_length:V, \tl_length:o}
+% \begin{macro}{\tl_length:N, \tl_length:c}
+% \begin{macro}[aux]{\tl_length_aux:n}
+% Count number of elements within a token list or token list
+% variable. Brace groups within the list are read as a single
+% element. Spaces are ignored.
+% \cs{tl_length_aux:n} grabs the element and replaces it by |+1|.
+% The |0| to ensure it works on an empty list.
+% \begin{macrocode}
+\cs_new:Npn \tl_length:n #1
+ {
+ \int_eval:n
+ { 0 \tl_map_function:nN {#1} \tl_length_aux:n }
+ }
+\cs_new_nopar:Npn \tl_length:N #1
+ {
+ \int_eval:n
+ { 0 \tl_map_function:NN #1 \tl_length_aux:n }
+ }
+\cs_new:Npn \tl_length_aux:n #1 { + 1 }
+\cs_generate_variant:Nn \tl_length:n { V , o }
+\cs_generate_variant:Nn \tl_length:N { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\tl_reverse:n, \tl_reverse:V, \tl_reverse:o}
+% \begin{macro}[aux]{\tl_reverse_aux:nN}
+% Reversal of a token list is done by taking one token at a time
+% and putting it in front of the ones before it.
+% \begin{macrocode}
+\cs_new:Npn \tl_reverse:n #1
+ { \tl_reverse_aux:nN { } #1 \q_recursion_tail \q_recursion_stop }
+\cs_new:Npn \tl_reverse_aux:nN #1#2
+ {
+ \quark_if_recursion_tail_stop_do:nn {#2} {#1}
+ \tl_reverse_aux:nN { #2 #1 }
+ }
+\cs_generate_variant:Nn \tl_reverse:n {V,o}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\tl_reverse:N, \tl_reverse:c}
+% This reverses the list, leaving |\exp_stop_f:| in front, which in turn
+% is removed by the |f| expansion which comes to a halt.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \tl_reverse:N #1
+ { \tl_set:Nf #1 { \tl_reverse:o { #1 \exp_stop_f: } } }
+\cs_generate_variant:Nn \tl_reverse:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\tl_trim_spaces:n}
+% \begin{macro}
+% {
+% \tl_trim_spaces:N, \tl_trim_spaces:c,
+% \tl_gtrim_spaces:N, \tl_gtrim_spaces:c
+% }
+% \begin{macro}[aux]{\tl_trim_spaces_exp:n}
+% \begin{macro}[aux]{\tl_trim_spaces_aux_i:w}
+% \begin{macro}[aux]{\tl_trim_spaces_aux_ii:w}
+% Trimming spaces from around the input uses the idea of a sufficiently
+% odd token to allow for a delimited argument to do this. Here, the
+% standard approach [a |Q| with category code 3 (math toggle)] is used.
+% The \cs{etex_unexpanded:D} here is used so that space trimming will
+% behave correctly within an \texttt{x}-type expansion.
+% \begin{macrocode}
+\cs_new:Npn \tl_trim_spaces:n #1
+ {
+ \etex_unexpanded:D \exp_after:wN \exp_after:wN \exp_after:wN
+ { \tl_trim_spaces_exp:n {#1} }
+ }
+\cs_new_protected:Npn \tl_trim_spaces:N #1
+ { \tl_set:Nx #1 { \exp_after:wN \tl_trim_spaces:n \exp_after:wN {#1} } }
+\cs_new_protected:Npn \tl_gtrim_spaces:N #1
+ { \tl_gset:Nx #1 { \exp_after:wN \tl_trim_spaces:n \exp_after:wN {#1} } }
+\group_begin:
+ \tex_catcode:D `\Q = 3 \scan_stop:
+ \cs_new:Npn \tl_trim_spaces_exp:n #1
+ { \tex_romannumeral:D - `0 \tl_trim_spaces_aux_i:w \exp_not:N #1 Q ~ Q }
+ \cs_new:Npn \tl_trim_spaces_aux_i:w #1 ~ Q { \tl_trim_spaces_aux_ii:w #1 Q }
+ \cs_new:Npn \tl_trim_spaces_aux_ii:w #1 Q #2 {#1}
+\group_end:
+\cs_generate_variant:Nn \tl_trim_spaces:N { c }
+\cs_generate_variant:Nn \tl_gtrim_spaces:N { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{The first token from a token list}
+%
+% \begin{macro}{\tl_head:n, \tl_head:V, \tl_head:v, \tl_head:f}
+% \begin{macro}{\tl_head:w}
+% \begin{macro}{\tl_tail:n, \tl_tail:V, \tl_tail:v, \tl_tail:f}
+% \begin{macro}{\tl_tail:w}
+% These functions pick up either the head or the tail of a list.
+% \begin{macrocode}
+\cs_new:Npn \tl_head:n #1 { \tl_head:w #1 \q_stop }
+\cs_new:Npn \tl_tail:n #1 { \tl_tail:w #1 \q_stop }
+\cs_new:Npn \tl_head:w #1#2 \q_stop {#1}
+\cs_new:Npn \tl_tail:w #1#2 \q_stop {#2}
+\cs_generate_variant:Nn \tl_head:n { V , v , f }
+\cs_generate_variant:Nn \tl_tail:n { V , v , f }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\tl_if_head_eq_meaning:nN}
+% \begin{macro}[pTF]{\tl_if_head_eq_charcode:nN}
+% \begin{macro}[pTF]{\tl_if_head_eq_charcode:fN}
+% \begin{macro}[pTF]{\tl_if_head_eq_catcode:nN}
+% When we want to check if the first token of a list equals something
+% specific it is usually either to see if it is a control sequence or
+% a character. Hence we make two different functions as the internal
+% test is different.
+% \cs{tl_if_head_meaning_eq:nNTF} uses \cs{if_meaning:w} and will
+% consider the tokens |b|$\sb{11}$ and |b|$\sb{12}$ different.
+% \cs{tl_if_head_char_eq:nNTF} on the other hand only compares
+% character codes so would regard |b|$\sb{11}$ and |b|$\sb{12}$ as
+% equal but would also regard two primitives as equal.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \tl_if_head_eq_meaning:nN #1#2 { p , T , F , TF }
+ {
+ \exp_after:wN \if_meaning:w \tl_head:w #1 \q_stop #2
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+% \end{macrocode}
+% For the charcode and catcode versions we insert |\exp_not:N| in
+% front of both tokens. If you need them to expand fully as \TeX{}
+% does itself with these you can use an |f| type expansion.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \tl_if_head_eq_charcode:nN #1#2 { p , T , F , TF }
+ {
+ \exp_after:wN \if:w
+ \exp_after:wN \exp_not:N \tl_head:w #1 \q_stop \exp_not:N #2
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\cs_generate_variant:Nn \tl_if_head_eq_charcode_p:nN { f }
+\cs_generate_variant:Nn \tl_if_head_eq_charcode:nNTF { f }
+\cs_generate_variant:Nn \tl_if_head_eq_charcode:nNT { f }
+\cs_generate_variant:Nn \tl_if_head_eq_charcode:nNF { f }
+% \end{macrocode}
+% And now catcodes:
+% \begin{macrocode}
+\prg_new_conditional:Npnn \tl_if_head_eq_catcode:nN #1#2 { p , T , F , TF }
+ {
+ \exp_after:wN \if_catcode:w \exp_after:wN \exp_not:N
+ \tl_head:w #1 \q_stop \exp_not:N #2
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Viewing token lists}
+%
+% \begin{macro}{\tl_show:N, \tl_show:c}
+% Showing token list variables is done directly: at the moment do not
+% worry if they are defined.
+% \begin{macrocode}
+\cs_new_protected:Npn \tl_show:N #1 { \cs_show:N #1 }
+\cs_generate_variant:Nn \tl_show:N { c }
+% \end{macrocode}
+%\end{macro}
+%
+% \begin{macro}{\tl_show:n}
+% For literal token lists, life is easy.
+% \begin{macrocode}
+\cs_new_eq:NN \tl_show:n \etex_showtokens:D
+% \end{macrocode}
+%\end{macro}
+%
+% \subsection{Constant token lists}
+%
+% \begin{variable}{\c_job_name_tl}
+% Inherited from the \LaTeX3 name for the primitive: this needs to
+% actually contain the text of the job name rather than the name of
+% the primitive, of course.
+% \begin{macrocode}
+%<*package>
+\tl_const:Nx \c_job_name_tl { \tex_jobname:D }
+%</package>
+%<*initex>
+\tex_everyjob:D \exp_after:wN
+ {
+ \tex_the:D \tex_everyjob:D
+ \luatex_if_engine:TF
+ {
+ \tl_if_in:onTF { \tex_jobname:D } { ~ }
+ { \tl_const:Nx \c_job_name_tl { " \tex_jobname:D " } }
+ { \tl_const:Nx \c_job_name_tl { \tex_jobname:D } }
+ }
+ { \tl_const:Nx \c_job_name_tl { \tex_jobname:D } }
+ }
+%</initex>
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\c_empty_tl}
+% Never full.
+% \begin{macrocode}
+\tl_const:Nn \c_empty_tl { }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\c_space_tl}
+% A space as a token list (as opposed to as a character).
+% \begin{macrocode}
+\tl_const:Nn \c_space_tl { ~ }
+% \end{macrocode}
+% \end{variable}
+%
+% \subsection{Scratch token lists}
+%
+% \begin{variable}{\g_tmpa_tl, \g_tmpb_tl}
+% Global temporary token list variables.
+% They are supposed to be set and used immediately,
+% with no delay between the definition and the use because you
+% can't count on other macros not to redefine them from under you.
+% \begin{macrocode}
+\tl_new:N \g_tmpa_tl
+\tl_new:N \g_tmpb_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_tmpa_tl, \l_tmpb_tl}
+% These are local temporary token list variables. Be sure not to assume
+% that the value you put into them will survive for
+% long---see discussion above.
+% \begin{macrocode}
+\tl_new:N \l_tmpa_tl
+\tl_new:N \l_tmpb_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \subsection{Experimental functions}
+%
+% \begin{macro}[EXP,pTF]{\tl_if_single_item:n}
+% A token list has exactly one item if it is either a single
+% token surrounded by optional explicit spaces, or a single brace
+% group surrounded by optional explicit spaces. The naive
+% version of this test would do \cs{use_none:n} |#1|, and
+% test if the result is empty. However, this will fail when
+% the token list is empty. Furthermore, it does not allow optional
+% trailing spaces.
+% \begin{macrocode}
+\cs_new:Npn \tl_if_single_item:nTF #1
+ { \str_if_eq:onTF { \use_ii:nn #1 {?} ? } {??} }
+\cs_new:Npn \tl_if_single_item:nT #1
+ { \str_if_eq:onT { \use_ii:nn #1 {?} ? } {??} }
+\cs_new:Npn \tl_if_single_item:nF #1
+ { \str_if_eq:onF { \use_ii:nn #1 {?} ? } {??} }
+\cs_new:Npn \tl_if_single_item_p:n #1
+ { \str_if_eq_p:on { \use_ii:nn #1 {?} ? } {??} }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP,pTF]{\tl_if_head_begin_group:n}
+% \begin{macrocode}
+\prg_new_conditional:Npnn \tl_if_head_begin_group:n #1 { p , T , F , TF }
+ {
+ \exp_after:wN \use_none:n
+ \exp_after:wN {
+ \exp_after:wN {
+ \token_to_str:N #1 .
+ }
+ \prg_return_true: \exp_after:wN \use_none:nn \token_to_str:N
+ }
+ \prg_return_false:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP,pTF]{\tl_if_head_eq_space:n}
+% \begin{macro}[EXP,aux]{\tl_if_head_eq_space_aux:w}
+% If the first token of the token list is an explicit space, i.e.,
+% a character token with character code $32$ and category code $10$,
+% then this test will be \meta{true}. It is \meta{false} if the token
+% list is empty, if the first token is an implicit space token,
+% such as \cs{c_space_token}, or any token other than an explicit space.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \tl_if_head_eq_space:n #1 { p , T , F , TF }
+ {
+ \if_false: { \fi:
+ \tl_if_head_eq_space_aux:w \prg_do_nothing: #1 ? ~ }
+ }
+\cs_new:Npn \tl_if_head_eq_space_aux:w #1 ~ %
+ {
+ \tl_if_empty_return:o { #1 }
+ \exp_after:wN \use_none:n \exp_after:wN { \if_false: } \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP,pTF]{\tl_if_single_token:n}
+% If the token list starts with a space, then it is
+% a single token if and only if its string representation
+% is exactly one space character. Otherwise, we check if removing
+% the first token group makes the token list empty. If it doesn't,
+% the token list is not a single token. If it does, then the token
+% list is either a single token or a single brace group. This is
+% tested for using \cs{tl_if_head_begin_group:n}.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \tl_if_single_token:n #1 { p , T , F , TF }
+ {
+ \tl_if_head_eq_space:nTF {#1}
+ {
+ \str_if_eq:nnTF {#1} {~}
+ \prg_return_true: \prg_return_false:
+ }
+ {
+ \str_if_eq:onTF { \use_none:n #1 ? } {?}
+ {
+ \tl_if_head_begin_group:nTF {#1}
+ \prg_return_false: \prg_return_true:
+ }
+ \prg_return_false:
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Deprecated functions}
+%
+% \begin{macro}{\tl_new:Nn, \tl_new:cn, \tl_new:Nx}
+% Use either \cs{tl_const:Nn} or \cs{tl_new:N}.
+% \begin{macrocode}
+\cs_new_protected:Npn \tl_new:Nn #1#2
+ {
+ \tl_new:N #1
+ \tl_gset:Nn #1 {#2}
+ }
+\cs_generate_variant:Nn \tl_new:Nn { c }
+\cs_generate_variant:Nn \tl_new:Nn { Nx }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\tl_gset:Nc}
+% \begin{macro}{\tl_set:Nc}
+% This was useful once, but nowadays does not make much sense.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \tl_gset:Nc
+ { \pref_global:D \tl_set:Nc }
+\cs_new_protected_nopar:Npn \tl_set:Nc #1#2
+ { \tl_set:No #1 { \cs:w #2 \cs_end: } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\tl_replace_in:Nnn, \tl_replace_in:cnn}
+% \begin{macro}{\tl_greplace_in:Nnn, \tl_greplace_in:cnn}
+% \begin{macro}{\tl_replace_all_in:Nnn, \tl_replace_all_in:cnn}
+% \begin{macro}{\tl_greplace_all_in:Nnn, \tl_greplace_all_in:cnn}
+% These are renamed.
+% \begin{macrocode}
+\cs_new_eq:NN \tl_replace_in:Nnn \tl_replace_once:Nnn
+\cs_new_eq:NN \tl_replace_in:cnn \tl_replace_once:cnn
+\cs_new_eq:NN \tl_greplace_in:Nnn \tl_greplace_once:Nnn
+\cs_new_eq:NN \tl_greplace_in:cnn \tl_greplace_once:cnn
+\cs_new_eq:NN \tl_replace_all_in:Nnn \tl_replace_all:Nnn
+\cs_new_eq:NN \tl_replace_all_in:cnn \tl_replace_all:cnn
+\cs_new_eq:NN \tl_greplace_all_in:Nnn \tl_greplace_all:Nnn
+\cs_new_eq:NN \tl_greplace_all_in:cnn \tl_greplace_all:cnn
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\tl_remove_in:Nn, \tl_remove_in:cn}
+% \begin{macro}{\tl_gremove_in:Nn, \tl_gremove_in:cn}
+% \begin{macro}{\tl_remove_all_in:Nn, \tl_remove_all_in:cn}
+% \begin{macro}{\tl_gremove_all_in:Nn, \tl_gremove_all_in:cn}
+% Also renamed.
+% \begin{macrocode}
+\cs_new_eq:NN \tl_remove_in:Nn \tl_remove_once:Nn
+\cs_new_eq:NN \tl_remove_in:cn \tl_remove_once:cn
+\cs_new_eq:NN \tl_gremove_in:Nn \tl_gremove_once:Nn
+\cs_new_eq:NN \tl_gremove_in:cn \tl_gremove_once:cn
+\cs_new_eq:NN \tl_remove_all_in:Nn \tl_remove_all:Nn
+\cs_new_eq:NN \tl_remove_all_in:cn \tl_remove_all:cn
+\cs_new_eq:NN \tl_gremove_all_in:Nn \tl_gremove_all:Nn
+\cs_new_eq:NN \tl_gremove_all_in:cn \tl_gremove_all:cn
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\tl_elt_count:n, \tl_elt_count:V, \tl_elt_count:o}
+% \begin{macro}{\tl_elt_count:N, \tl_elt_count:c}
+% Another renaming job.
+% \begin{macrocode}
+\cs_new_eq:NN \tl_elt_count:n \tl_length:n
+\cs_new_eq:NN \tl_elt_count:V \tl_length:V
+\cs_new_eq:NN \tl_elt_count:o \tl_length:o
+\cs_new_eq:NN \tl_elt_count:N \tl_length:N
+\cs_new_eq:NN \tl_elt_count:c \tl_length:c
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\tl_head_i:n}
+% \begin{macro}{\tl_head_i:w}
+% \begin{macro}{\tl_head_iii:n}
+% \begin{macro}{\tl_head_iii:f}
+% \begin{macro}{\tl_head_iii:w}
+% Two renames, and a few that are rather too specialised.
+% \begin{macrocode}
+\cs_new_eq:NN \tl_head_i:n \tl_head:n
+\cs_new_eq:NN \tl_head_i:w \tl_head:w
+\cs_new:Npn \tl_head_iii:n #1 { \tl_head_iii:w #1 \q_stop }
+\cs_generate_variant:Nn \tl_head_iii:n { f }
+\cs_new:Npn \tl_head_iii:w #1#2#3#4 \q_stop {#1#2#3}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macrocode}
+%</initex|package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3token.dtx b/Master/texmf-dist/source/latex/l3kernel/l3token.dtx
new file mode 100644
index 00000000000..153ca92f7e0
--- /dev/null
+++ b/Master/texmf-dist/source/latex/l3kernel/l3token.dtx
@@ -0,0 +1,2495 @@
+% \iffalse meta-comment
+%
+%% File: l3token.dtx Copyright (C) 2005-2011 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 "expl3 bundle" (The Work in LPPL)
+%% and all files in that bundle must be distributed together.
+%%
+%% The released version of this bundle is available from CTAN.
+%%
+%% -----------------------------------------------------------------------
+%%
+%% The development version of the bundle can be found at
+%%
+%% http://www.latex-project.org/svnroot/experimental/trunk/
+%%
+%% for those people who are interested.
+%%
+%%%%%%%%%%%
+%% NOTE: %%
+%%%%%%%%%%%
+%%
+%% Snapshots taken from the repository represent work in progress and may
+%% not work or may contain conflicting material! We therefore ask
+%% people _not_ to put them into distributions, archives, etc. without
+%% prior consultation with the LaTeX3 Project.
+%%
+%% -----------------------------------------------------------------------
+%
+%<*driver|package>
+\RequirePackage{l3names}
+\GetIdInfo$Id: l3token.dtx 2491 2011-07-02 11:49:37Z joseph $
+ {L3 Experimental token manipulation}
+%</driver|package>
+%<*driver>
+\documentclass[full]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3token} package\\ Token manipulation^^A
+% \thanks{This file describes v\ExplFileVersion,
+% last revised \ExplFileDate.}^^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 \ExplFileDate}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% This module deals with tokens. Now this is perhaps not the most
+% precise description so let's try with a better description: When
+% programming in \TeX{}, it is often desirable to know just what a
+% certain token is: is it a control sequence or something
+% else. Similarly one often needs to know if a control sequence is
+% expandable or not, a macro or a primitive, how many arguments it
+% takes etc. Another thing of great importance (especially when it
+% comes to document commands) is looking ahead in the token stream to
+% see if a certain character is present and maybe even remove it or
+% disregard other tokens while scanning. This module provides
+% functions for both and as such will have two primary function
+% categories: |\token| for anything that deals with tokens and
+% |\peek| for looking ahead in the token stream.
+%
+% Most of the time we will be using the term \enquote{token} but most of the
+% time the function we're describing can equally well by used on a
+% control sequence as such one is one token as well.
+%
+% We shall refer to list of tokens as |tlist|s and such lists
+% represented by a single control sequence is a \enquote{token list variable}
+% |tl var|. Functions for these two types are found in the \textsf{l3tl}
+% module.
+%
+% \section{All possible tokens}
+%
+% Let us start by reviewing every case that a given token can fall into.
+% It is very important to distinguish two aspects of a token: its meaning,
+% and what it looks like.
+%
+% For instance, \cs{if:w}, \cs{if_charcode:w}, and \cs{tex_if:D} are
+% three for the same internal operation of \TeX{}, namely the primitive
+% testing the next two characters for equality of their character code.
+% They behave identically in many situations. However, \TeX{}
+% distinguishes them when searching for a delimited argument. Namely, the
+% example function \cs{show_until_if:w} defined below will take everything
+% until \cs{if:w} as an argument, despite the presence of other copies of
+% \cs{if:w} under different names.
+% \begin{verbatim}
+% \cs_new:Npn \show_until_if:w #1 \if:w { \tl_show:n {#1} }
+% \show_until_if:w \tex_if:D \if_charcode:w \if:w
+% \end{verbatim}
+%
+% It is easier to start by considering the possibilities for what a
+% token looks like, in other words, how \TeX{} sees it from the point
+% of view of delimited arguments. Two cases: the token is either a
+% control sequence or a single character.
+% \begin{center}
+% \begin{tabular}{p{4cm}p{4cm}}
+% \toprule
+% Control sequence & Character \\
+% \midrule
+% Control word: an escape character followed by some letters. &
+% \end{tabular}
+% \end{center}
+% The token can be a control sequence,
+% in other words, an escape character followed by some letters, or by
+% a single non-letter character. Examples of this include \cs{begin},
+% \cs{;}, \cs{emph}\ldots{} The other case
+% There are two cases. either the token
+% is a single character, in which case it is associated with a category
+% code:
+%
+%
+% \section{Character tokens}
+%
+% \begin{function}
+% {
+% \char_set_catcode_escape:N ,
+% \char_set_catcode_group_begin:N ,
+% \char_set_catcode_group_end:N ,
+% \char_set_catcode_math_toggle:N ,
+% \char_set_catcode_alignment:N ,
+% \char_set_catcode_end_line:N ,
+% \char_set_catcode_parameter:N ,
+% \char_set_catcode_math_superscript:N ,
+% \char_set_catcode_math_subscript:N ,
+% \char_set_catcode_ignore:N ,
+% \char_set_catcode_space:N ,
+% \char_set_catcode_letter:N ,
+% \char_set_catcode_other:N ,
+% \char_set_catcode_active:N ,
+% \char_set_catcode_comment:N ,
+% \char_set_catcode_invalid:N
+% }
+% \begin{syntax}
+% \cs{char_make_letter:N} \meta{character}
+% \end{syntax}
+% Sets the category code of the \meta{character} to that indicated in
+% the function name. Depending on the current category code of the
+% \meta{token} the escape token may also be needed:
+% \begin{verbatim}
+% \char_set_catcode_other:N \%
+% \end{verbatim}
+% The assignment is local.
+% \end{function}
+%
+% \begin{function}
+% {
+% \char_set_catcode_escape:n ,
+% \char_set_catcode_group_begin:n ,
+% \char_set_catcode_group_end:n ,
+% \char_set_catcode_math_toggle:n ,
+% \char_set_catcode_alignment:n ,
+% \char_set_catcode_end_line:n ,
+% \char_set_catcode_parameter:n ,
+% \char_set_catcode_math_superscript:n ,
+% \char_set_catcode_math_subscript:n ,
+% \char_set_catcode_ignore:n ,
+% \char_set_catcode_space:n ,
+% \char_set_catcode_letter:n ,
+% \char_set_catcode_other:n ,
+% \char_set_catcode_active:n ,
+% \char_set_catcode_comment:n ,
+% \char_set_catcode_invalid:n
+% }
+% \begin{syntax}
+% \cs{char_make_letter:n} \Arg{integer expression}
+% \end{syntax}
+% Sets the category code of the \meta{character} which has character
+% code as given by the \meta{integer expression}. This version can be
+% used to set up characters which cannot otherwise be given
+% (\emph{cf.}~the \texttt{N}-type variants). The assignment is local.
+% \end{function}
+%
+% \begin{function}{\char_set_catcode:nn}
+% \begin{syntax}
+% \cs{char_set_catcode:nn} \Arg{intexpr1} \Arg{intexpr2}
+% \end{syntax}
+% These functions set the category code of the \meta{character} which
+% has character code as given by the \meta{integer expression}.
+% The first \meta{integer expression}
+% is the character code and the second is the category code to apply.
+% The setting applies within the current \TeX{} group. In general, the
+% symbolic functions \cs{char_make_\meta{type}} should be preferred,
+% but there are cases where these lower-level functions may be useful.
+% \end{function}
+%
+% \begin{function}[EXP]{\char_value_catcode:n}
+% \begin{syntax}
+% \cs{char_value_catcode:n} \Arg{integer expression}
+% \end{syntax}
+% Expands to the current category code of the \meta{character} with
+% character code given by the
+% \meta{integer expression}.
+% \end{function}
+%
+% \begin{function}{\char_show_value_catcode:n}
+% \begin{syntax}
+% \cs{char_show_value_catcode:n} \Arg{integer expression}
+% \end{syntax}
+% Displays the current category code of the \meta{character} with
+% character code given by the \meta{integer expression} on the
+% terminal.
+% \end{function}
+%
+% \begin{function}{\char_set_lccode:nn}
+% \begin{syntax}
+% \cs{char_set_lcode:nn} \Arg{intexpr1} \Arg{intexpr2}
+% \end{syntax}
+% This function set up the behaviour of \meta{character} when
+% found inside \cs{tl_to_lowercase:n}, such that \meta{character1}
+% will be converted into \meta{character2}. The two \meta{characters}
+% may be specified using an \meta{integer expression} for the character code
+% concerned. This may include the \TeX{} |`|\meta{character}
+% method for converting a single character into its character
+% code:
+% \begin{verbatim}
+% \char_set_lccode:nn { `\A } { `\a } % Standard behaviour
+% \char_set_lccode:nn { `\A } { `\A + 32 }
+% \char_set_lccode:nn { 50 } { 60 }
+% \end{verbatim}
+% The setting applies within the current \TeX{} group.
+% \end{function}
+%
+% \begin{function}[EXP]{\char_value_lccode:n}
+% \begin{syntax}
+% \cs{char_value_lccode:n} \Arg{integer expression}
+% \end{syntax}
+% Expands to the current lower case code of the \meta{character} with
+% character code given by the
+% \meta{integer expression}.
+% \end{function}
+%
+% \begin{function}{\char_show_value_lccode:n}
+% \begin{syntax}
+% \cs{char_show_value_lccode:n} \Arg{integer expression}
+% \end{syntax}
+% Displays the current lower case code of the \meta{character} with
+% character code given by the \meta{integer expression} on the
+% terminal.
+% \end{function}
+%
+% \begin{function}{\char_set_uccode:nn}
+% \begin{syntax}
+% \cs{char_set_uccode:nn} \Arg{intexpr1} \Arg{intexpr2}
+% \end{syntax}
+% This function set up the behaviour of \meta{character} when
+% found inside \cs{tl_to_uppeercase:n}, such that \meta{character1}
+% will be converted into \meta{character2}. The two \meta{characters}
+% may be specified using an \meta{integer expression} for the character code
+% concerned. This may include the \TeX{} |`|\meta{character}
+% method for converting a single character into its character
+% code:
+% \begin{verbatim}
+% \char_set_uccode:nn { `\a } { `\A } % Standard behaviour
+% \char_set_uccode:nn { `\A } { `\A - 32 }
+% \char_set_uccode:nn { 60 } { 50 }
+% \end{verbatim}
+% The setting applies within the current \TeX{} group.
+% \end{function}
+%
+% \begin{function}[EXP]{\char_value_uccode:n}
+% \begin{syntax}
+% \cs{char_value_uccode:n} \Arg{integer expression}
+% \end{syntax}
+% Expands to the current upper case code of the \meta{character} with
+% character code given by the
+% \meta{integer expression}.
+% \end{function}
+%
+% \begin{function}{\char_show_value_uccode:n}
+% \begin{syntax}
+% \cs{char_show_value_uccode:n} \Arg{integer expression}
+% \end{syntax}
+% Displays the current upper case code of the \meta{character} with
+% character code given by the \meta{integer expression} on the
+% terminal.
+% \end{function}
+%
+% \begin{function}{\char_set_mathcode:nn}
+% \begin{syntax}
+% \cs{char_set_mathcode:nn} \Arg{intexpr1} \Arg{intexpr2}
+% \end{syntax}
+% This function sets up the math code of \meta{character}.
+% The \meta{character} is specified as
+% an \meta{integer expression} which will be used as the character
+% code of the relevant character. The setting applies within the
+% current \TeX{} group.
+% \end{function}
+%
+% \begin{function}[EXP]{\char_value_mathcode:n}
+% \begin{syntax}
+% \cs{char_value_mathcode:n} \Arg{integer expression}
+% \end{syntax}
+% Expands to the current math code of the \meta{character} with
+% character code given by the
+% \meta{integer expression}.
+% \end{function}
+%
+% \begin{function}{\char_show_value_mathcode:n}
+% \begin{syntax}
+% \cs{char_show_value_mathcode:n} \Arg{integer expression}
+% \end{syntax}
+% Displays the current math code of the \meta{character} with
+% character code given by the \meta{integer expression} on the
+% terminal.
+% \end{function}
+%
+% \begin{function}{\char_set_sfcode:nn}
+% \begin{syntax}
+% \cs{char_set_sfcode:nn} \Arg{intexpr1} \Arg{intexpr2}
+% \end{syntax}
+% This function sets up the space factor for the \meta{character}.
+% The \meta{character} is specified as
+% an \meta{integer expression} which will be used as the character
+% code of the relevant character. The setting applies within the
+% current \TeX{} group.
+% \end{function}
+%
+% \begin{function}[EXP]{\char_value_sfcode:n}
+% \begin{syntax}
+% \cs{char_value_sfcode:n} \Arg{integer expression}
+% \end{syntax}
+% Expands to the current space factor for the \meta{character} with
+% character code given by the
+% \meta{integer expression}.
+% \end{function}
+%
+% \begin{function}{\char_show_value_sfcode:n}
+% \begin{syntax}
+% \cs{char_show_value_sfcode:n} \Arg{integer expression}
+% \end{syntax}
+% Displays the current space factor for the \meta{character} with
+% character code given by the \meta{integer expression} on the
+% terminal.
+% \end{function}
+%
+% \section{Generic tokens}
+%
+% \begin{function}{\token_new:Nn}
+% \begin{syntax}
+% \cs{token_new:Nn} \meta{token1} \Arg{token2}
+% \end{syntax}
+% Defines \meta{token1} to globally be a snapshot of \meta{token2}.
+% This will be an implicit representation of \meta{token2}.
+% \end{function}
+%
+% \begin{variable}
+% {
+% \c_group_begin_token,
+% \c_group_end_token,
+% \c_math_toggle_token,
+% \c_alignment_token,
+% \c_parameter_token,
+% \c_math_superscript_token,
+% \c_math_subscript_token,
+% \c_space_token
+% }
+% These are implicit tokens which have the category code described
+% by their name. They are used internally for test purposes but
+% are also available to the programmer for other uses.
+% \end{variable}
+%
+% \begin{variable}
+% {
+% \c_catcode_letter_token,
+% \c_catcode_other_token
+% }
+% These are implicit tokens which have the category code described
+% by their name. They are used internally for test purposes and should
+% not be used other than for category code tests.
+% \end{variable}
+%
+% \begin{variable}{\c_catcode_active_tl}
+% A token list containing an active token. This is used internally
+% for test purposes and should not be used other than in
+% appropriately-constructed category code tests.
+% \end{variable}
+%
+% \section{Converting tokens}
+%
+% \begin{function}[EXP]{\token_to_meaning:N}
+% \begin{syntax}
+% \cs{token_to_meaning:N} \meta{token}
+% \end{syntax}
+% Inserts the current meaning of the \meta{token} into the input
+% stream as a series of characters of category code $12$ (other).
+% This will be the primitive \TeX{} description of the \meta{token},
+% thus for example both functions defined by \cs{cs_set_nopar:Npn}
+% and token list variables defined using \cs{tl_new:N} will be described
+% as |macro|s.
+% \begin{texnote}
+% This is the \TeX{} primitive \tn{meaning}.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[EXP]{\token_to_str:N, \token_to_str:c}
+% \begin{syntax}
+% \cs{token_to_str:N} \meta{token}
+% \end{syntax}
+% Converts the given \meta{token} into a series of characters with
+% category code $12$ (other). The current escape character will be
+% the first character in the sequence, although this will also have
+% category code $12$ (the escape character is part of the
+% \meta{token}). This function requires only a single expansion.
+% \begin{texnote}
+% \cs{token_to_str:N} is the \TeX{} primitive \cs{string} renamed.
+% \end{texnote}
+% \end{function}
+%
+% \section{Token conditionals}
+%
+% \begin{function}[EXP,pTF]{\token_if_group_begin:N}
+% \begin{syntax}
+% \cs{token_if_group_begin_p:N} \meta{token}
+% \cs{token_if_group_begin:NTF} \meta{token} \Arg{true code}
+% ~~\Arg{false code}
+% \end{syntax}
+% Tests if \meta{token} has the category code of a begin group token
+% (|{| when normal \TeX{} category codes are in ^^A }
+% force). The branching versions then leave either \meta{true code} or
+% \meta{false code} in the input stream, as appropriate to the truth of
+% the test and the variant of the function chosen. The logical truth of
+% the test is left in the input stream by the predicate version.
+% Note that an explicit begin group token cannot be tested in this way,
+% as it is not a valid \texttt{N}-type argument.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\token_if_group_end:N}
+% \begin{syntax}
+% \cs{token_if_group_end_p:N} \meta{token}
+% \cs{token_if_group_end:NTF} \meta{token} \Arg{true code}
+% ~~\Arg{false code}
+% \end{syntax}
+% Tests if \meta{token} has the category code of an end group token
+% (^^A {
+% |}| when normal \TeX{} category codes are in force). The branching
+% versions then leave either \meta{true code} or \meta{false code} in the
+% input stream, as appropriate to the truth of the test and the variant
+% of the function chosen. The logical truth of the test is left in the
+% input stream by the predicate version.
+% Note that an explicit end group token cannot be tested in this way,
+% as it is not a valid \texttt{N}-type argument.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\token_if_math_toggle:N}
+% \begin{syntax}
+% \cs{token_if_math_toggle_p:N} \meta{token}
+% \cs{token_if_math_toggle:NTF} \meta{token} \Arg{true code}
+% ~~\Arg{false code}
+% \end{syntax}
+% Tests if \meta{token} has the category code of a math shift token
+% (|$| when normal \TeX{} category codes are in force). The
+% branching versions then leave either \meta{true code} or
+% \meta{false code} in the input stream, as appropriate to the truth of
+% the test and the variant of the function chosen. The logical truth of
+% the test is left in the input stream by the predicate version.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\token_if_alignment:N}
+% \begin{syntax}
+% \cs{token_if_alignment_p:N} \meta{token}
+% \cs{token_if_alignment:NTF} \meta{token} \Arg{true code}
+% ~~\Arg{false code}
+% \end{syntax}
+% Tests if \meta{token} has the category code of an alignment token
+% (|&| when normal \TeX{} category codes are in force). The
+% branching versions then leave either \meta{true code} or
+% \meta{false code} in the input stream, as appropriate to the truth of
+% the test and the variant of the function chosen. The logical truth of
+% the test is left in the input stream by the predicate version.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\token_if_parameter:N}
+% \begin{syntax}
+% \cs{token_if_parameter_p:N} \meta{token}
+% \cs{token_if_alignment:NTF} \meta{token} \Arg{true code}
+% ~~\Arg{false code}
+% \end{syntax}
+% Tests if \meta{token} has the category code of a macro parameter token
+% (|#| when normal \TeX{} category codes are in force). The
+% branching versions then leave either \meta{true code} or
+% \meta{false code} in the input stream, as appropriate to the truth of
+% the test and the variant of the function chosen. The logical truth of
+% the test is left in the input stream by the predicate version.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\token_if_math_superscript:N}
+% \begin{syntax}
+% \cs{token_if_math_superscript_p:N} \meta{token}
+% \cs{token_if_math_superscript:NTF} \meta{token} \Arg{true code}
+% ~~\Arg{false code}
+% \end{syntax}
+% Tests if \meta{token} has the category code of a superscript token
+% (|^| when normal \TeX{} category codes are in force). The
+% branching versions then leave either \meta{true code} or
+% \meta{false code} in the input stream, as appropriate to the truth of
+% the test and the variant of the function chosen. The logical truth of
+% the test is left in the input stream by the predicate version.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\token_if_math_subscript:N}
+% \begin{syntax}
+% \cs{token_if_math_subscript_p:N} \meta{token}
+% \cs{token_if_math_subscript:NTF} \meta{token} \Arg{true code}
+% ~~\Arg{false code}
+% \end{syntax}
+% Tests if \meta{token} has the category code of a subscript token
+% (|_| when normal \TeX{} category codes are in force). The
+% branching versions then leave either \meta{true code} or
+% \meta{false code} in the input stream, as appropriate to the truth of
+% the test and the variant of the function chosen. The logical truth of
+% the test is left in the input stream by the predicate version.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\token_if_space:N}
+% \begin{syntax}
+% \cs{token_if_space_p:N} \meta{token}
+% \cs{token_if_space:NTF} \meta{token} \Arg{true code}
+% ~~\Arg{false code}
+% \end{syntax}
+% Tests if \meta{token} has the category code of a space token. The
+% branching versions then leave either \meta{true code} or
+% \meta{false code} in the input stream, as appropriate to the truth of
+% the test and the variant of the function chosen. The logical truth of
+% the test is left in the input stream by the predicate version.
+% Note that an explicit space token with character code $32$ cannot
+% be tested in this way, as it is not a valid \texttt{N}-type argument.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\token_if_letter:N}
+% \begin{syntax}
+% \cs{token_if_letter_p:N} \meta{token}
+% \cs{token_if_letter:NTF} \meta{token} \Arg{true code}
+% ~~\Arg{false code}
+% \end{syntax}
+% Tests if \meta{token} has the category code of a letter token. The
+% branching versions then leave either \meta{true code} or
+% \meta{false code} in the input stream, as appropriate to the truth of
+% the test and the variant of the function chosen. The logical truth of
+% the test is left in the input stream by the predicate version.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\token_if_other:N}
+% \begin{syntax}
+% \cs{token_if_other_p:N} \meta{token}
+% \cs{token_if_other:NTF} \meta{token} \Arg{true code}
+% ~~\Arg{false code}
+% \end{syntax}
+% Tests if \meta{token} has the category code of an \enquote{other}
+% token. The branching versions then leave either \meta{true code} or
+% \meta{false code} in the input stream, as appropriate to the truth of
+% the test and the variant of the function chosen. The logical truth of
+% the test is left in the input stream by the predicate version.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\token_if_active:N}
+% \begin{syntax}
+% \cs{token_if_active_p:N} \meta{token}
+% \cs{token_if_active:NTF} \meta{token} \Arg{true code}
+% ~~\Arg{false code}
+% \end{syntax}
+% Tests if \meta{token} has the category code of an active character.
+% The branching versions then leave either \meta{true code} or
+% \meta{false code} in the input stream, as appropriate to the truth of
+% the test and the variant of the function chosen. The logical truth of
+% the test is left in the input stream by the predicate version.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\token_if_eq_catcode:NN}
+% \begin{syntax}
+% \cs{token_if_eq_catcode_p:NN} \meta{token1} \meta{token2}
+% \cs{token_if_eq_catcode:NNTF} \meta{token1} \meta{token2}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the two \meta{tokens} have the same category code. The
+% branching versions then leave either \meta{true code} or
+% \meta{false code} in the input stream, as appropriate to the truth of
+% the test and the variant of the function chosen. The logical truth of
+% the test is left in the input stream by the predicate version.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\token_if_eq_charcode:NN}
+% \begin{syntax}
+% \cs{token_if_eq_charcode_p:NN} \meta{token1} \meta{token2}
+% \cs{token_if_eq_charcode:NNTF} \meta{token1} \meta{token2}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the two \meta{tokens} have the same character code. The
+% branching versions then leave either \meta{true code} or
+% \meta{false code} in the input stream, as appropriate to the truth of
+% the test and the variant of the function chosen. The logical truth of
+% the test is left in the input stream by the predicate version.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\token_if_eq_meaning:NN}
+% \begin{syntax}
+% \cs{token_if_eq_meaning_p:NN} \meta{token1} \meta{token2}
+% \cs{token_if_eq_meaning:NNTF} \meta{token1} \meta{token2}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the two \meta{tokens} have the same meaning when expanded.
+% The branching versions then leave either \meta{true code} or
+% \meta{false code} in the input stream, as appropriate to the truth of
+% the test and the variant of the function chosen. The logical truth of
+% the test is left in the input stream by the predicate version.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\token_if_macro:N}
+% \begin{syntax}
+% \cs{token_if_macro_p:N} \meta{token}
+% \cs{token_if_macro:NTF} \meta{token} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{token} is a \TeX{} macro.
+% The branching versions then leave either \meta{true code} or
+% \meta{false code} in the input stream, as appropriate to the truth of
+% the test and the variant of the function chosen. The logical truth of
+% the test is left in the input stream by the predicate version.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\token_if_cs:N}
+% \begin{syntax}
+% \cs{token_if_cs_p:N} \meta{token}
+% \cs{token_if_cs:NTF} \meta{token} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{token} is a control sequence.
+% The branching versions then leave either \meta{true code} or
+% \meta{false code} in the input stream, as appropriate to the truth of
+% the test and the variant of the function chosen. The logical truth of
+% the test is left in the input stream by the predicate version.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\token_if_expandable:N}
+% \begin{syntax}
+% \cs{token_if_expandable_p:N} \meta{token}
+% \cs{token_if_expandable:NTF} \meta{token}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{token} is expandable. This test returns \meta{false}
+% for an undefined token.
+% The branching versions then leave either \meta{true code} or
+% \meta{false code} in the input stream, as appropriate to the truth of
+% the test and the variant of the function chosen. The logical truth of
+% the test is left in the input stream by the predicate version.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\token_if_long_macro:N}
+% \begin{syntax}
+% \cs{token_if_long_macro_p:N} \meta{token}
+% \cs{token_if_long_macro:NTF} \meta{token}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{token} is a long macro.
+% The branching versions then leave either \meta{true code} or
+% \meta{false code} in the input stream, as appropriate to the truth of
+% the test and the variant of the function chosen. The logical truth of
+% the test is left in the input stream by the predicate version.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\token_if_protected_macro:N}
+% \begin{syntax}
+% \cs{token_if_protected_macro_p:N} \meta{token}
+% \cs{token_if_protected_macro:NTF} \meta{token}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{token} is a protected macro: a macro which
+% is both protected and long will return logical false.
+% The branching versions then leave either \meta{true code} or
+% \meta{false code} in the input stream, as appropriate to the truth of
+% the test and the variant of the function chosen. The logical truth of
+% the test is left in the input stream by the predicate version.
+% \end{function}
+%
+%% \begin{function}[EXP,pTF]{\token_if_protected_long_macro:N}
+% \begin{syntax}
+% \cs{token_if_protected_long_macro_p:N} \meta{token}
+% \cs{token_if_protected_long_macro:NTF} \meta{token}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{token} is a protected long macro.
+% The branching versions then leave either \meta{true code} or
+% \meta{false code} in the input stream, as appropriate to the truth of
+% the test and the variant of the function chosen. The logical truth of
+% the test is left in the input stream by the predicate version.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\token_if_chardef:N}
+% \begin{syntax}
+% \cs{token_if_chardef_p:N} \meta{token}
+% \cs{token_if_chardef:NTF} \meta{token}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{token} is defined to be a chardef.
+% The branching versions then leave either \meta{true code} or
+% \meta{false code} in the input stream, as appropriate to the truth of
+% the test and the variant of the function chosen. The logical truth of
+% the test is left in the input stream by the predicate version.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\token_if_mathchardef:N}
+% \begin{syntax}
+% \cs{token_if_mathchardef_p:N} \meta{token}
+% \cs{token_if_mathchardef:NTF} \meta{token}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{token} is defined to be a mathchardef.
+% The branching versions then leave either \meta{true code} or
+% \meta{false code} in the input stream, as appropriate to the truth of
+% the test and the variant of the function chosen. The logical truth of
+% the test is left in the input stream by the predicate version.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\token_if_dim_register:N}
+% \begin{syntax}
+% \cs{token_if_dim_register_p:N} \meta{token}
+% \cs{token_if_dim_register:NTF} \meta{token}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{token} is defined to be a dimension register.
+% The branching versions then leave either \meta{true code} or
+% \meta{false code} in the input stream, as appropriate to the truth of
+% the test and the variant of the function chosen. The logical truth of
+% the test is left in the input stream by the predicate version.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\token_if_int_register:N}
+% \begin{syntax}
+% \cs{token_if_int_register_p:N} \meta{token}
+% \cs{token_if_int_register:NTF} \meta{token}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{token} is defined to be a integer register.
+% The branching versions then leave either \meta{true code} or
+% \meta{false code} in the input stream, as appropriate to the truth of
+% the test and the variant of the function chosen. The logical truth of
+% the test is left in the input stream by the predicate version.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\token_if_skip_register:N}
+% \begin{syntax}
+% \cs{token_if_skip_register_p:N} \meta{token}
+% \cs{token_if_skip_register:NTF} \meta{token}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{token} is defined to be a skip register.
+% The branching versions then leave either \meta{true code} or
+% \meta{false code} in the input stream, as appropriate to the truth of
+% the test and the variant of the function chosen. The logical truth of
+% the test is left in the input stream by the predicate version.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\token_if_toks_register:N}
+% \begin{syntax}
+% \cs{token_if_toks_register_p:N} \meta{token}
+% \cs{token_if_toks_register:NTF} \meta{token}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{token} is defined to be a toks register
+% (not used by\LaTeX3).
+% The branching versions then leave either \meta{true code} or
+% \meta{false code} in the input stream, as appropriate to the truth of
+% the test and the variant of the function chosen. The logical truth of
+% the test is left in the input stream by the predicate version.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\token_if_primitive:N}
+% \begin{syntax}
+% \cs{token_if_primitive_p:N} \meta{token}
+% \cs{token_if_primitive:NTF} \meta{token}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{token} is an engine primitive.
+% The branching versions then leave either \meta{true code} or
+% \meta{false code} in the input stream, as appropriate to the truth of
+% the test and the variant of the function chosen. The logical truth of
+% the test is left in the input stream by the predicate version.
+% \end{function}
+%
+% \section{Peeking ahead at the next token}
+%
+% There is often a need to look ahead at the next token in the input
+% stream while leaving it in place. This is handled using the
+% \enquote{peek} functions. The generic \cs{peek_after:Nw} is
+% provided along with a family of predefined tests for common cases.
+% As peeking ahead does \emph{not} skip spaces the predefined tests
+% include both a space-respecting and space-skipping version.
+%
+% \begin{function}{\peek_after:Nw}
+% \begin{syntax}
+% \cs{peek_after:Nw} \meta{function} \meta{token}
+% \end{syntax}
+% Locally sets the test variable \cs{l_peek_token} equal to \meta{token}
+% (as an implicit token, \emph{not} as a token list), and then
+% expands the \meta{function}. The \meta{token} will remain in
+% the input stream as the next item after the \meta{function}.
+% The \meta{token} here may be \verb*| |, |{| or |}| (assuming
+% normal \TeX{} category codes), \emph{i.e.}~it is not necessarily the
+% next argument which would be grabbed by a normal function.
+% \end{function}
+%
+% \begin{function}{\peek_gafter:Nw}
+% \begin{syntax}
+% \cs{peek_gafter:Nw} \meta{function} \meta{token}
+% \end{syntax}
+% Globally sets the test variable \cs{g_peek_token} equal to \meta{token}
+% (as an implicit token, \emph{not} as a token list), and then
+% expands the \meta{function}. The \meta{token} will remain in
+% the input stream as the next item after the \meta{function}.
+% The \meta{token} here may be \verb*| |, |{| or |}| (assuming
+% normal \TeX{} category codes), \emph{i.e.}~it is not necessarily the
+% next argument which would be grabbed by a normal function.
+% \end{function}
+%
+% \begin{variable}{\l_peek_token}
+% Token set by \cs{peek_after:Nw} and available for testing
+% as described above.
+% \end{variable}
+%
+% \begin{variable}{\g_peek_token}
+% Token set by \cs{peek_gafter:Nw} and available for testing
+% as described above.
+% \end{variable}
+%
+% \begin{function}[TF]{\peek_catcode:N}
+% \begin{syntax}
+% \cs{peek_catcode:NTF} \meta{test token} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the next \meta{token} in the input stream has the same
+% category code as the \meta{test token} (as defined by the test
+% \cs{token_if_eq_catcode:NNTF}). Spaces are respected by the test
+% and the \meta{token} will be left in the input stream after
+% the \meta{true code} or \meta{false code} (as appropriate to the
+% result of the test).
+% \end{function}
+%
+% \begin{function}[TF]{\peek_catcode_ignore_spaces:N}
+% \begin{syntax}
+% \cs{peek_catcode_ignore_spaces:NTF} \meta{test token}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the next \meta{token} in the input stream has the same
+% category code as the \meta{test token} (as defined by the test
+% \cs{token_if_eq_catcode:NNTF}). Spaces are ignored by the test
+% and the \meta{token} will be left in the input stream after
+% the \meta{true code} or \meta{false code} (as appropriate to the
+% result of the test).
+% \end{function}
+%
+% \begin{function}[TF]{\peek_catcode_remove:N}
+% \begin{syntax}
+% \cs{peek_catcode_remove:NTF} \meta{test token}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the next \meta{token} in the input stream has the same
+% category code as the \meta{test token} (as defined by the test
+% \cs{token_if_eq_catcode:NNTF}). Spaces are respected by the test
+% and the \meta{token} will be removed from the input stream if the
+% test is true. The function will then place either the
+% \meta{true code} or \meta{false code} in the input stream (as
+% appropriate to the result of the test).
+% \end{function}
+%
+% \begin{function}[TF]{\peek_catcode_remove_ignore_spaces:N}
+% \begin{syntax}
+% \cs{peek_catcode_remove_ignore_spaces:NTF} \meta{test token}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the next \meta{token} in the input stream has the same
+% category code as the \meta{test token} (as defined by the test
+% \cs{token_if_eq_catcode:NNTF}). Spaces are ignored by the test
+% and the \meta{token} will be removed from the input stream if the
+% test is true. The function will then place either the
+% \meta{true code} or \meta{false code} in the input stream (as
+% appropriate to the result of the test).
+% \end{function}
+%
+% \begin{function}[TF]{\peek_charcode:N}
+% \begin{syntax}
+% \cs{peek_charcode:NTF} \meta{test token}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the next \meta{token} in the input stream has the same
+% character code as the \meta{test token} (as defined by the test
+% \cs{token_if_eq_charcode:NNTF}). Spaces are respected by the test
+% and the \meta{token} will be left in the input stream after
+% the \meta{true code} or \meta{false code} (as appropriate to the
+% result of the test).
+% \end{function}
+%
+% \begin{function}[TF]{\peek_charcode_ignore_spaces:N}
+% \begin{syntax}
+% \cs{peek_charcode_ignore_spaces:NTF} \meta{test token}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the next \meta{token} in the input stream has the same
+% character code as the \meta{test token} (as defined by the test
+% \cs{token_if_eq_charcode:NNTF}). Spaces are ignored by the test
+% and the \meta{token} will be left in the input stream after
+% the \meta{true code} or \meta{false code} (as appropriate to the
+% result of the test).
+% \end{function}
+%
+% \begin{function}[TF]{\peek_charcode_remove:N}
+% \begin{syntax}
+% \cs{peek_charcode_remove:NTF} \meta{test token}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the next \meta{token} in the input stream has the same
+% character code as the \meta{test token} (as defined by the test
+% \cs{token_if_eq_charcode:NNTF}). Spaces are respected by the test
+% and the \meta{token} will be removed from the input stream if the
+% test is true. The function will then place either the
+% \meta{true code} or \meta{false code} in the input stream (as
+% appropriate to the result of the test).
+% \end{function}
+%
+% \begin{function}[TF]{\peek_charcode_remove_ignore_spaces:N}
+% \begin{syntax}
+% \cs{peek_charcode_remove_ignore_spaces:NTF} \meta{test token}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the next \meta{token} in the input stream has the same
+% character code as the \meta{test token} (as defined by the test
+% \cs{token_if_eq_charcode:NNTF}). Spaces are ignored by the test
+% and the \meta{token} will be removed from the input stream if the
+% test is true. The function will then place either the
+% \meta{true code} or \meta{false code} in the input stream (as
+% appropriate to the result of the test).
+% \end{function}
+%
+% \begin{function}[TF]{\peek_meaning:N}
+% \begin{syntax}
+% \cs{peek_meaning:NTF} \meta{test token} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the next \meta{token} in the input stream has the same
+% meaning as the \meta{test token} (as defined by the test
+% \cs{token_if_eq_meaning:NNTF}). Spaces are respected by the test
+% and the \meta{token} will be left in the input stream after
+% the \meta{true code} or \meta{false code} (as appropriate to the
+% result of the test).
+% \end{function}
+%
+% \begin{function}[TF]{\peek_meaning_ignore_spaces:N}
+% \begin{syntax}
+% \cs{peek_meaning_ignore_spaces:NTF} \meta{test token}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the next \meta{token} in the input stream has the same
+% meaning as the \meta{test token} (as defined by the test
+% \cs{token_if_eq_meaning:NNTF}). Spaces are ignored by the test
+% and the \meta{token} will be left in the input stream after
+% the \meta{true code} or \meta{false code} (as appropriate to the
+% result of the test).
+% \end{function}
+%
+% \begin{function}[TF]{\peek_meaning_remove:N}
+% \begin{syntax}
+% \cs{peek_meaning_remove:NTF} \meta{test token}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the next \meta{token} in the input stream has the same
+% meaning as the \meta{test token} (as defined by the test
+% \cs{token_if_eq_meaning:NNTF}). Spaces are respected by the test
+% and the \meta{token} will be removed from the input stream if the
+% test is true. The function will then place either the
+% \meta{true code} or \meta{false code} in the input stream (as
+% appropriate to the result of the test).
+% \end{function}
+%
+% \begin{function}[TF]{\peek_meaning_remove_ignore_spaces:N}
+% \begin{syntax}
+% \cs{peek_meaning_remove_ignore_spaces:NTF} \meta{test token}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the next \meta{token} in the input stream has the same
+% meaning as the \meta{test token} (as defined by the test
+% \cs{token_if_eq_meaning:NNTF}). Spaces are ignored by the test
+% and the \meta{token} will be removed from the input stream if the
+% test is true. The function will then place either the
+% \meta{true code} or \meta{false code} in the input stream (as
+% appropriate to the result of the test).
+% \end{function}
+%
+% \section{Decomposing a macro definition}
+%
+% These functions decompose \TeX{} macros into their constituent
+% parts: if the \meta{token} passed is not a macro then no decomposition
+% can occur. In the later case, all three functions leave \cs{scan_stop:}
+% in the input stream.
+%
+% \begin{function}[EXP]{\token_get_arg_spec:N}
+% \begin{syntax}
+% \cs{token_get_arg_spec:N} \meta{token}
+% \end{syntax}
+% If the \meta{token} is a macro, this function will leave
+% the primitive \TeX{} argument specification in input stream as
+% a string of tokens of category code $12$ (with spaces having category
+% code $10$). Thus for example for a token \cs{next} defined by
+% \begin{verbatim}
+% \cs_set:Npn \next #1#2 { x #1 y #2 }
+% \end{verbatim}
+% will leave |#1#2| in the input stream. If the \meta{token} is
+% not a macro then \cs{scan_stop:} will be left in the input stream
+% \begin{texnote}
+% If the arg~spec. contains the string |->|, then the |spec| function
+% will produce incorrect results.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[EXP]{\token_get_replacement_text:N}
+% \begin{syntax}
+% \cs{token_get_replacement_text:N} \meta{token}
+% \end{syntax}
+% If the \meta{token} is a macro, this function will leave
+% the replacement text in input stream as
+% a string of tokens of category code $12$ (with spaces having category
+% code $10$). Thus for example for a token \cs{next} defined by
+% \begin{verbatim}
+% \cs_set:Npn \next #1#2 { x #1~y #2 }
+% \end{verbatim}
+% will leave \verb|x#1 y#2| in the input stream. If the \meta{token} is
+% not a macro then \cs{scan_stop:} will be left in the input stream
+% \end{function}
+%
+% \begin{function}[EXP]{\token_get_prefix_spec:N}
+% \begin{syntax}
+% \cs{token_get_prefix_spec:N} \meta{token}
+% \end{syntax}
+% If the \meta{token} is a macro, this function will leave
+% the \TeX{} prefixes applicable in input stream as
+% a string of tokens of category code $12$ (with spaces having category
+% code $10$). Thus for example for a token \cs{next} defined by
+% \begin{verbatim}
+% \cs_set:Npn \next #1#2 { x #1~y #2 }
+% \end{verbatim}
+% will leave |\long| in the input stream. If the \meta{token} is
+% not a macro then \cs{scan_stop:} will be left in the input stream
+% \end{function}
+%
+% \section{Experimental token functions}
+%
+% \begin{function}{\char_active_set:Npn, \char_active_set:Npx}
+% \begin{syntax}
+% \cs{char_active_set:Npn} \meta{char} \meta{parameters} \Arg{code}
+% \end{syntax}
+% Makes \meta{char} an active character to expand to \meta{code} as
+% replacement text.
+% Within the \meta{code}, the \meta{parameters} (|#1|, |#2|,
+% \emph{etc.}) will be replaced by those absorbed
+% This definition is local to the current \TeX{} group.
+% \end{function}
+%
+% \begin{function}{\char_active_gset:Npn, \char_active_gset:Npx}
+% \begin{syntax}
+% \cs{char_active_gset:Npn} \meta{char} \meta{parameters} \Arg{code}
+% \end{syntax}
+% Makes \meta{char} an active character to expand to \meta{code} as
+% replacement text.
+% Within the \meta{code}, the \meta{parameters} (|#1|, |#2|,
+% \emph{etc.}) will be replaced by those absorbed
+% This definition is global.
+% \end{function}
+%
+% \begin{function}{\char_active_set_eq:NN}
+% \begin{syntax}
+% \cs{char_active_set_eq:NN} \meta{char} \meta{function}
+% \end{syntax}
+% Makes \meta{char} an active character equivalent in meaning to the
+% \meta{fiucntion} (which may itself be an active character). This
+% definition is local to the current \TeX{} group.
+% \end{function}
+%
+% \begin{function}{\char_active_gset_eq:NN}
+% \begin{syntax}
+% \cs{char_active_gset_eq:NN} \meta{char} \meta{function}
+% \end{syntax}
+% Makes \meta{char} an active character equivalent in meaning to the
+% \meta{fiucntion} (which may itself be an active character). This
+% definition is global.
+% \end{function}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3token} implementation}
+%
+% \begin{macrocode}
+%<*initex|package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*package>
+\ProvidesExplPackage
+ {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
+\package_check_loaded_expl:
+%</package>
+% \end{macrocode}
+%
+% \subsection{Character tokens}
+%
+% \begin{macro}{\char_set_catcode:nn}
+% \begin{macro}{\char_value_catcode:n}
+% \begin{macro}{\char_show_value_catcode:n}
+% Category code changes.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \char_set_catcode:nn #1#2
+ { \tex_catcode:D #1 = \int_eval:w #2 \int_eval_end: }
+\cs_new_nopar:Npn \char_value_catcode:n #1
+ { \tex_the:D \tex_catcode:D \int_eval:w #1\int_eval_end: }
+\cs_new_nopar:Npn \char_show_value_catcode:n #1
+ { \tex_showthe:D \tex_catcode:D \int_eval:w #1 \int_eval_end: }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \char_set_catcode_escape:N ,
+% \char_set_catcode_group_begin:N ,
+% \char_set_catcode_group_end:N ,
+% \char_set_catcode_math_toggle:N ,
+% \char_set_catcode_alignment:N ,
+% \char_set_catcode_end_line:N ,
+% \char_set_catcode_parameter:N ,
+% \char_set_catcode_math_superscript:N ,
+% \char_set_catcode_math_subscript:N ,
+% \char_set_catcode_ignore:N ,
+% \char_set_catcode_space:N ,
+% \char_set_catcode_letter:N ,
+% \char_set_catcode_other:N ,
+% \char_set_catcode_active:N ,
+% \char_set_catcode_comment:N ,
+% \char_set_catcode_invalid:N
+% }
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \char_set_catcode_escape:N #1
+ { \char_set_catcode:nn { `#1 } \c_zero }
+\cs_new_protected_nopar:Npn \char_set_catcode_group_begin:N #1
+ { \char_set_catcode:nn { `#1 } \c_one }
+\cs_new_protected_nopar:Npn \char_set_catcode_group_end:N #1
+ { \char_set_catcode:nn { `#1 } \c_two }
+\cs_new_protected_nopar:Npn \char_set_catcode_math_toggle:N #1
+ { \char_set_catcode:nn { `#1 } \c_three }
+\cs_new_protected_nopar:Npn \char_set_catcode_alignment:N #1
+ { \char_set_catcode:nn { `#1 } \c_four }
+\cs_new_protected_nopar:Npn \char_set_catcode_end_line:N #1
+ { \char_set_catcode:nn { `#1 } \c_five }
+\cs_new_protected_nopar:Npn \char_set_catcode_parameter:N #1
+ { \char_set_catcode:nn { `#1 } \c_six }
+\cs_new_protected_nopar:Npn \char_set_catcode_math_superscript:N #1
+ { \char_set_catcode:nn { `#1 } \c_seven }
+\cs_new_protected_nopar:Npn \char_set_catcode_math_subscript:N #1
+ { \char_set_catcode:nn { `#1 } \c_eight }
+\cs_new_protected_nopar:Npn \char_set_catcode_ignore:N #1
+ { \char_set_catcode:nn { `#1 } \c_nine }
+\cs_new_protected_nopar:Npn \char_set_catcode_space:N #1
+ { \char_set_catcode:nn { `#1 } \c_ten }
+\cs_new_protected_nopar:Npn \char_set_catcode_letter:N #1
+ { \char_set_catcode:nn { `#1 } \c_eleven }
+\cs_new_protected_nopar:Npn \char_set_catcode_other:N #1
+ { \char_set_catcode:nn { `#1 } \c_twelve }
+\cs_new_protected_nopar:Npn \char_set_catcode_active:N #1
+ { \char_set_catcode:nn { `#1 } \c_thirteen }
+\cs_new_protected_nopar:Npn \char_set_catcode_comment:N #1
+ { \char_set_catcode:nn { `#1 } \c_fourteen }
+\cs_new_protected_nopar:Npn \char_set_catcode_invalid:N #1
+ { \char_set_catcode:nn { `#1 } \c_fifteen }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \char_set_catcode_escape:n ,
+% \char_set_catcode_group_begin:n ,
+% \char_set_catcode_group_end:n ,
+% \char_set_catcode_math_toggle:n ,
+% \char_set_catcode_alignment:n ,
+% \char_set_catcode_end_line:n ,
+% \char_set_catcode_parameter:n ,
+% \char_set_catcode_math_superscript:n ,
+% \char_set_catcode_math_subscript:n ,
+% \char_set_catcode_ignore:n ,
+% \char_set_catcode_space:n ,
+% \char_set_catcode_letter:n ,
+% \char_set_catcode_other:n ,
+% \char_set_catcode_active:n ,
+% \char_set_catcode_comment:n ,
+% \char_set_catcode_invalid:n
+% }
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \char_set_catcode_escape:n #1
+ { \char_set_catcode:nn {#1} \c_zero }
+\cs_new_protected_nopar:Npn \char_set_catcode_group_begin:n #1
+ { \char_set_catcode:nn {#1} \c_one }
+\cs_new_protected_nopar:Npn \char_set_catcode_group_end:n #1
+ { \char_set_catcode:nn {#1} \c_two }
+\cs_new_protected_nopar:Npn \char_set_catcode_math_toggle:n #1
+ { \char_set_catcode:nn {#1} \c_three }
+\cs_new_protected_nopar:Npn \char_set_catcode_alignment:n #1
+ { \char_set_catcode:nn {#1} \c_four }
+\cs_new_protected_nopar:Npn \char_set_catcode_end_line:n #1
+ { \char_set_catcode:nn {#1} \c_five }
+\cs_new_protected_nopar:Npn \char_set_catcode_parameter:n #1
+ { \char_set_catcode:nn {#1} \c_six }
+\cs_new_protected_nopar:Npn \char_set_catcode_math_superscript:n #1
+ { \char_set_catcode:nn {#1} \c_seven }
+\cs_new_protected_nopar:Npn \char_set_catcode_math_subscript:n #1
+ { \char_set_catcode:nn {#1} \c_eight }
+\cs_new_protected_nopar:Npn \char_set_catcode_ignore:n #1
+ { \char_set_catcode:nn {#1} \c_nine }
+\cs_new_protected_nopar:Npn \char_set_catcode_space:n #1
+ { \char_set_catcode:nn {#1} \c_ten }
+\cs_new_protected_nopar:Npn \char_set_catcode_letter:n #1
+ { \char_set_catcode:nn {#1} \c_eleven }
+\cs_new_protected_nopar:Npn \char_set_catcode_other:n #1
+ { \char_set_catcode:nn {#1} \c_twelve }
+\cs_new_protected_nopar:Npn \char_set_catcode_active:n #1
+ { \char_set_catcode:nn {#1} \c_thirteen }
+\cs_new_protected_nopar:Npn \char_set_catcode_comment:n #1
+ { \char_set_catcode:nn {#1} \c_fourteen }
+\cs_new_protected_nopar:Npn \char_set_catcode_invalid:n #1
+ { \char_set_catcode:nn {#1} \c_fifteen }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\char_set_mathcode:nn}
+% \begin{macro}{\char_value_mathcode:n}
+% \begin{macro}{\char_show_value_mathcode:n}
+% \begin{macro}{\char_set_lccode:nn}
+% \begin{macro}{\char_value_lccode:n}
+% \begin{macro}{\char_show_value_lccode:n}
+% \begin{macro}{\char_set_uccode:nn}
+% \begin{macro}{\char_value_uccode:n}
+% \begin{macro}{\char_show_value_uccode:n}
+% \begin{macro}{\char_set_sfcode:nn}
+% \begin{macro}{\char_value_sfcode:n}
+% \begin{macro}{\char_show_value_sfcode:n}
+% Pretty repetitive, but necessary!
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \char_set_mathcode:nn #1#2
+ { \tex_mathcode:D #1 = \int_eval:w #2 \int_eval_end: }
+\cs_new_nopar:Npn \char_value_mathcode:n #1
+ { \tex_the:D \tex_mathcode:D \int_eval:w #1\int_eval_end: }
+\cs_new_nopar:Npn \char_show_value_mathcode:n #1
+ { \tex_showthe:D \tex_mathcode:D \int_eval:w #1 \int_eval_end: }
+\cs_new_protected_nopar:Npn \char_set_lccode:nn #1#2
+ { \tex_lccode:D #1 = \int_eval:w #2 \int_eval_end: }
+\cs_new_nopar:Npn \char_value_lccode:n #1
+ { \tex_the:D \tex_lccode:D \int_eval:w #1\int_eval_end: }
+\cs_new_nopar:Npn \char_show_value_lccode:n #1
+ { \tex_showthe:D \tex_lccode:D \int_eval:w #1 \int_eval_end: }
+\cs_new_protected_nopar:Npn \char_set_uccode:nn #1#2
+ { \tex_uccode:D #1 = \int_eval:w #2 \int_eval_end: }
+\cs_new_nopar:Npn \char_value_uccode:n #1
+ { \tex_the:D \tex_uccode:D \int_eval:w #1\int_eval_end: }
+\cs_new_nopar:Npn \char_show_value_uccode:n #1
+ { \tex_showthe:D \tex_uccode:D \int_eval:w #1 \int_eval_end: }
+\cs_new_protected_nopar:Npn \char_set_sfcode:nn #1#2
+ { \tex_sfcode:D #1 = \int_eval:w #2 \int_eval_end: }
+\cs_new_nopar:Npn \char_value_sfcode:n #1
+ { \tex_the:D \tex_sfcode:D \int_eval:w #1\int_eval_end: }
+\cs_new_nopar:Npn \char_show_value_sfcode:n #1
+ { \tex_showthe:D \tex_sfcode:D \int_eval:w #1 \int_eval_end: }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Generic tokens}
+%
+% \begin{macro}{\token_new:Nn}
+% Creates a new token.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \token_new:Nn #1#2 { \cs_new_eq:NN #1 #2 }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \c_group_begin_token,
+% \c_group_end_token,
+% \c_math_toggle_token,
+% \c_alignment_token,
+% \c_parameter_token,
+% \c_math_superscript_token,
+% \c_math_subscript_token,
+% \c_space_token,
+% \c_catcode_letter_token,
+% \c_catcode_other_token
+% }
+% We define these useful tokens. We have to do it by hand with the
+% brace tokens for obvious reasons.
+% \begin{macrocode}
+\cs_new_eq:NN \c_group_begin_token {
+\cs_new_eq:NN \c_group_end_token }
+\group_begin:
+ \char_set_catcode_math_toggle:N \*
+ \token_new:Nn \c_math_toggle_token { * }
+ \char_set_catcode_alignment:N \*
+ \token_new:Nn \c_alignment_token { * }
+ \token_new:Nn \c_parameter_token { # }
+ \token_new:Nn \c_math_superscript_token { ^ }
+ \char_set_catcode_math_subscript:N \*
+ \token_new:Nn \c_math_subscript_token { * }
+ \token_new:Nn \c_space_token { ~ }
+ \token_new:Nn \c_catcode_letter_token { a }
+ \token_new:Nn \c_catcode_other_token { 1 }
+\group_end:
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}{\c_catcode_active_tl}
+% Not an implicit token!
+% \begin{macrocode}
+\group_begin:
+ \char_set_catcode_active:N \*
+ \cs_new_nopar:Npn \c_catcode_active_tl { \exp_not:N * }
+\group_end:
+% \end{macrocode}
+% \end{variable}
+%
+% \subsection{Token conditionals}
+%
+% \begin{macro}[pTF]{\token_if_group_begin:N}
+% Check if token is a begin group token. We use the constant
+% |\c_group_begin_token| for this.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \token_if_group_begin:N #1 { p , T , F , TF }
+ {
+ \if_catcode:w \exp_not:N #1 \c_group_begin_token
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\token_if_group_end:N}
+% Check if token is a end group token. We use the constant
+% |\c_group_end_token| for this.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \token_if_group_end:N #1 { p , T , F , TF }
+ {
+ \if_catcode:w \exp_not:N #1 \c_group_end_token
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\token_if_math_toggle:N}
+% Check if token is a math shift token. We use the constant
+% |\c_math_toggle_token| for this.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \token_if_math_toggle:N #1 { p , T , F , TF }
+ {
+ \if_catcode:w \exp_not:N #1 \c_math_toggle_token
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\token_if_alignment:N}
+% Check if token is an alignment tab token. We use the constant
+% |\c_alignment_tab_token| for this.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \token_if_alignment:N #1 { p , T , F , TF }
+ {
+ \if_catcode:w \exp_not:N #1 \c_alignment_token
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\token_if_parameter:N}
+% Check if token is a parameter token. We use the constant
+% |\c_parameter_token| for this. We have to trick \TeX{} a bit to
+% avoid an error message: within a group we prevent
+% \cs{c_parameter_token} from behaving like a macro parameter character.
+% The definitions of \cs{prg_new_conditional:Npnn} are global, so they
+% will remain after the group.
+% \begin{macrocode}
+\group_begin:
+\cs_set_eq:NN \c_parameter_token \scan_stop:
+\prg_new_conditional:Npnn \token_if_parameter:N #1 { p , T , F , TF }
+ {
+ \if_catcode:w \exp_not:N #1 \c_parameter_token
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+\group_end:
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\token_if_math_superscript:N}
+% Check if token is a math superscript token. We use the constant
+% |\c_superscript_token| for this.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \token_if_math_superscript:N #1 { p , T , F , TF }
+ {
+ \if_catcode:w \exp_not:N #1 \c_math_superscript_token
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\token_if_math_subscript:N}
+% Check if token is a math subscript token. We use the constant
+% |\c_subscript_token| for this.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \token_if_math_subscript:N #1 { p , T , F , TF }
+ {
+ \if_catcode:w \exp_not:N #1 \c_math_subscript_token
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\token_if_space:N}
+% Check if token is a space token. We use the constant
+% |\c_space_token| for this.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \token_if_space:N #1 { p , T , F , TF }
+ {
+ \if_catcode:w \exp_not:N #1 \c_space_token
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\token_if_letter:N}
+% Check if token is a letter token. We use the constant
+% |\c_letter_token| for this.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \token_if_letter:N #1 { p , T , F , TF }
+ {
+ \if_catcode:w \exp_not:N #1 \c_catcode_letter_token
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\token_if_other:N}
+% Check if token is an other char token. We use the constant
+% |\c_other_char_token| for this.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \token_if_other:N #1 { p , T , F , TF }
+ {
+ \if_catcode:w \exp_not:N #1 \c_catcode_other_token
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\token_if_active:N}
+% Check if token is an active char token. We use the constant
+% |\c_active_char_tl| for this. A technical point is that
+% \cs{c_active_char_tl} is in fact a macro expanding to
+% |\exp_not:N *|, where |*| is active.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \token_if_active:N #1 { p , T , F , TF }
+ {
+ \if_catcode:w \exp_not:N #1 \c_catcode_active_tl
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\token_if_eq_meaning:NN}
+% Check if the tokens |#1| and |#2| have same meaning.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \token_if_eq_meaning:NN #1#2 { p , T , F , TF }
+ {
+ \if_meaning:w #1 #2
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\token_if_eq_catcode:NN}
+% Check if the tokens |#1| and |#2| have same category code.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \token_if_eq_catcode:NN #1#2 { p , T , F , TF }
+ {
+ \if_catcode:w \exp_not:N #1 \exp_not:N #2
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\token_if_eq_charcode:NN}
+% Check if the tokens |#1| and |#2| have same character code.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \token_if_eq_charcode:NN #1#2 { p , T , F , TF }
+ {
+ \if_charcode:w \exp_not:N #1 \exp_not:N #2
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\token_if_macro:N}
+% \begin{macro}[aux]{\token_if_macro_p_aux:w}
+% When a token is a macro, |\token_to_meaning:N| will always output
+% something like |\long macro:#1->#1| so we could naively check to
+% see if the meaning contains |->|. However, this can fail the five
+% \cs{tex_...mark:D} primitives, whose meaning has the form
+% |...mark:|\meta{user material}. The problem is that the
+% \meta{user material} can contain |->|.
+%
+% However, only characters, macros, and marks can contain the colon
+% character. The idea is thus to grab until the first |:|, and analyse
+% what is left. However, macros can have any combination of |\long|,
+% |\protected| or |\outer| (not used in \LaTeX3) before the string
+% |macro:|. We thus only select the part of the meaning between
+% the first |ma| and the first following |:|. If this string is
+% |cro|, then we have a macro. If the string is |rk|, then we have
+% a mark. The string can also be |cro parameter character | for a
+% colon with a weird category code (namely the usual category code
+% of |#|). Otherwise, it is empty.
+%
+% This relies on the fact that |\long|, |\protected|, |\outer|
+% cannot contain |ma|, regardless of the escape character, even if
+% the escape character is |m|\ldots{}
+%
+% Both |ma| and |:| must be of category code $12$ (other), and we
+% achieve using the standard lowercasing technique.
+%
+% \begin{macrocode}
+\group_begin:
+\char_set_catcode_other:N \M
+\char_set_catcode_other:N \A
+\char_set_lccode:nn { `\; } { `\: }
+\char_set_lccode:nn { `\T } { `\T }
+\char_set_lccode:nn { `\F } { `\F }
+\tl_to_lowercase:n
+ {
+ \group_end:
+ \prg_new_conditional:Npnn \token_if_macro:N #1 { p , T , F , TF }
+ {
+ \exp_after:wN \token_if_macro_p_aux:w
+ \token_to_meaning:N #1 MA; \q_stop
+ }
+ \cs_new_nopar:Npn \token_if_macro_p_aux:w #1 MA #2 ; #3 \q_stop
+ {
+ \if_int_compare:w \pdftex_strcmp:D { #2 } { cro } = \c_zero
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\token_if_cs:N}
+% Check if token has same catcode as a control sequence. This
+% follows the same pattern as for \cs{token_if_letter:N} \emph{etc.}
+% We use |\scan_stop:| for this.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \token_if_cs:N #1 { p , T , F , TF }
+ {
+ \if_catcode:w \exp_not:N #1 \scan_stop:
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\token_if_expandable:N}
+% Check if token is expandable. We use the fact that \TeX{} will
+% temporarily convert |\exp_not:N| \meta{token} into |\scan_stop:| if
+% \meta{token} is expandable.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \token_if_expandable:N #1 { p , T , F , TF }
+ {
+ \cs_if_exist:NTF #1
+ {
+ \exp_after:wN \if_meaning:w \exp_not:N #1 #1
+ \prg_return_false: \else: \prg_return_true: \fi:
+ }
+ { \prg_return_false: }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\token_if_chardef:N,\token_if_mathchardef:N,
+% \token_if_long_macro:N, \token_if_protected_macro:N,
+% \token_if_protected_long_macro:N, \token_if_dim_register:N,
+% \token_if_skip_register:N, \token_if_int_register:N,
+% \token_if_toks_register:N}
+% \begin{macro}[aux]{
+% \token_if_chardef_p_aux:w,
+% \token_if_mathchardef_p_aux:w,
+% \token_if_int_register_p_aux:w,
+% \token_if_skip_register_p_aux:w,
+% \token_if_dim_register_p_aux:w,
+% \token_if_toks_register_p_aux:w,
+% \token_if_protected_macro_p_aux:w,
+% \token_if_long_macro_p_aux:w,
+% \token_if_protected_long_macro_p_aux:w}
+% Most of these functions have to check the meaning of the token in
+% question so we need to do some checkups on which characters are
+% output by |\token_to_meaning:N|. As usual, these characters have
+% catcode 12 so we must do some serious substitutions in the code
+% below\dots
+% \begin{macrocode}
+\group_begin:
+ \char_set_lccode:nn { `\T } { `\T }
+ \char_set_lccode:nn { `\F } { `\F }
+ \char_set_lccode:nn { `\X } { `\n }
+ \char_set_lccode:nn { `\Y } { `\t }
+ \char_set_lccode:nn { `\Z } { `\d }
+ \char_set_lccode:nn { `\? } { `\\ }
+ \tl_map_inline:nn { \X \Y \Z \M \C \H \A \R \O \U \S \K \I \P \L \G \P \E }
+ { \char_set_catcode:nn { `#1 } \c_twelve }
+% \end{macrocode}
+% We convert the token list to lower case and restore the catcode and
+% lowercase code changes.
+% \begin{macrocode}
+\tl_to_lowercase:n
+ {
+ \group_end:
+% \end{macrocode}
+% First up is checking if something has been defined with
+% |\tex_chardef:D| or |\tex_mathchardef:D|. This is easy since \TeX{}
+% thinks of such tokens as hexadecimal so it stores them as
+% |\char"|\meta{hex~number} or |\mathchar"|\meta{hex~number}.
+% \begin{macrocode}
+ \prg_new_conditional:Npnn \token_if_chardef:N #1 { p , T , F , TF }
+ {
+ \exp_after:wN \token_if_chardef_aux:w
+ \token_to_meaning:N #1 ?CHAR" \q_stop
+ }
+ \cs_new_nopar:Npn \token_if_chardef_aux:w #1 ?CHAR" #2 \q_stop
+ { \tl_if_empty:nTF {#1} { \prg_return_true: } { \prg_return_false: } }
+% \end{macrocode}
+%
+% \begin{macrocode}
+ \prg_new_conditional:Npnn \token_if_mathchardef:N #1 { p , T , F , TF }
+ {
+ \exp_after:wN \token_if_mathchardef_aux:w
+ \token_to_meaning:N #1 ?MAYHCHAR" \q_stop
+ }
+ \cs_new_nopar:Npn \token_if_mathchardef_aux:w #1 ?MAYHCHAR" #2 \q_stop
+ { \tl_if_empty:nTF {#1} { \prg_return_true: } { \prg_return_false: } }
+% \end{macrocode}
+% Integer registers are a little more difficult since they expand to
+% |\count|\meta{number} and there is also a primitive |\countdef|. So
+% we have to check for that primitive as well.
+% \begin{macrocode}
+ \prg_new_conditional:Npnn \token_if_int_register:N #1 { p , T , F , TF }
+ {
+ \if_meaning:w \tex_countdef:D #1
+ \prg_return_false:
+ \else:
+ \exp_after:wN \token_if_int_register_aux:w
+ \token_to_meaning:N #1 ?COUXY \q_stop
+ \fi:
+ }
+ \cs_new_nopar:Npn \token_if_int_register_aux:w #1 ?COUXY #2 \q_stop
+ { \tl_if_empty:nTF {#1} { \prg_return_true: } { \prg_return_false: } }
+% \end{macrocode}
+% Skip registers are done the same way as the integer registers.
+% \begin{macrocode}
+ \prg_new_conditional:Npnn \token_if_skip_register:N #1 { p , T , F , TF }
+ {
+ \if_meaning:w \tex_skipdef:D #1
+ \prg_return_false:
+ \else:
+ \exp_after:wN \token_if_skip_register_aux:w
+ \token_to_meaning:N #1?SKIP\q_stop
+ \fi:
+ }
+ \cs_new_nopar:Npn \token_if_skip_register_aux:w #1 ?SKIP #2 \q_stop
+ { \tl_if_empty:nTF {#1} { \prg_return_true: } { \prg_return_false: } }
+% \end{macrocode}
+% Dim registers. No news here
+% \begin{macrocode}
+ \prg_new_conditional:Npnn \token_if_dim_register:N #1 { p , T , F , TF }
+ {
+ \if_meaning:w \tex_dimendef:D #1
+ \c_false_bool
+ \else:
+ \exp_after:wN \token_if_dim_register_aux:w
+ \token_to_meaning:N #1 ?ZIMEX \q_stop
+ \fi:
+ }
+ \cs_new_nopar:Npn \token_if_dim_register_aux:w #1 ?ZIMEX #2 \q_stop
+ { \tl_if_empty:nTF {#1} { \prg_return_true: } { \prg_return_false: } }
+% \end{macrocode}
+% Toks registers.
+% \begin{macrocode}
+ \prg_new_conditional:Npnn \token_if_toks_register:N #1 { p , T , F , TF }
+ {
+ \if_meaning:w \tex_toksdef:D #1
+ \prg_return_false:
+ \else:
+ \exp_after:wN \token_if_toks_register_aux:w
+ \token_to_meaning:N #1 ?YOKS \q_stop
+ \fi:
+ }
+ \cs_new_nopar:Npn \token_if_toks_register_aux:w #1 ?YOKS #2 \q_stop
+ { \tl_if_empty:nTF {#1} { \prg_return_true: } { \prg_return_false: } }
+% \end{macrocode}
+% Protected macros.
+% \begin{macrocode}
+ \prg_new_conditional:Npnn \token_if_protected_macro:N #1
+ { p , T , F , TF }
+ {
+ \exp_after:wN \token_if_protected_macro_aux:w
+ \token_to_meaning:N #1 ?PROYECYEZ~MACRO \q_stop
+ }
+ \cs_new_nopar:Npn \token_if_protected_macro_aux:w
+ #1 ?PROYECYEZ~MACRO #2 \q_stop
+ { \tl_if_empty:nTF {#1} { \prg_return_true: } { \prg_return_false: } }
+% \end{macrocode}
+% Long macros.
+% \begin{macrocode}
+ \prg_new_conditional:Npnn \token_if_long_macro:N #1 { p , T , F , TF }
+ {
+ \exp_after:wN \token_if_long_macro_aux:w
+ \token_to_meaning:N #1 ?LOXG~MACRO \q_stop
+ }
+ \cs_new_nopar:Npn \token_if_long_macro_aux:w #1 ?LOXG~MACRO #2 \q_stop
+ { \tl_if_empty:nTF {#1} { \prg_return_true: } { \prg_return_false: } }
+% \end{macrocode}
+% Finally protected long macros where we for once don't have to add an
+% extra test since there is no primitive for the combined prefixes.
+% \begin{macrocode}
+ \prg_new_conditional:Npnn \token_if_protected_long_macro:N #1
+ { p , T , F , TF }
+ {
+ \exp_after:wN \token_if_protected_long_macro_aux:w
+ \token_to_meaning:N #1 ?PROYECYEZ?LOXG~MACRO \q_stop
+ }
+ \cs_new_nopar:Npn \token_if_protected_long_macro_aux:w
+ #1 ?PROYECYEZ?LOXG~MACRO #2 \q_stop
+ { \tl_if_empty:nTF {#1} { \prg_return_true: } { \prg_return_false: } }
+% \end{macrocode}
+% Finally the |\tl_to_lowercase:n| ends!
+% \begin{macrocode}
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\token_if_primitive:N}
+% \begin{macro}[aux]{\token_if_primitive_aux:NNw,
+% \token_if_primitive_aux_space:w,
+% \token_if_primitive_aux_nullfont:N,
+% \token_if_primitive_aux_loop:N,
+% \token_if_primitive_auxii:Nw,
+% \token_if_primitive_aux_undefined:N}
+%^^A See http://groups.google.com/group/comp.text.tex/browse_thread/thread/0a72666873f8753d#
+%
+% We filter out macros first, because they cause endless trouble later
+% otherwise.
+%
+% Primitives are almost distinguished by the fact that the result
+% of \cs{token_to_meaning:N} is formed from letters only. Every other
+% token has either a space (e.g., |the letter A|), a digit
+% (e.g., |\count123|) or a double quote (e.g., |\char"A|).
+%
+% Ten exceptions: on the one hand, \cs{c_undefined:D} is not a
+% primitive, but its meaning is |undefined|, only letters;
+% on the other hand, \cs{tex_space:D}, \cs{tex_italiccorr:D},
+% \cs{tex_hyphen:D}, \cs{tex_firstmark:D}, \cs{tex_topmark:D},
+% \cs{tex_botmark:D}, \cs{tex_splitfirstmark:D}, \cs{tex_splitbotmark:D},
+% and \cs{tex_nullfont:D} are primitives, but have non-letters
+% in their meaning.
+%
+% We start by removing the two first (non-space) characters from
+% the meaning. This removes the escape character (which may be
+% inexistent depending on \cs{tex_endlinechar:D}), and takes care
+% of three of the exceptions: \cs{tex_space:D}, \cs{tex_italiccorr:D}
+% and \cs{tex_hyphen:D}, whose meaning is at most two characters.
+% This leaves a string terminated by some |:|, and \cs{q_stop}.
+%
+% The meaning of each one of the five \cs{tex_...mark:D} primitives
+% has the form \meta{letters}|:|\meta{user material}. In other words,
+% the first non-letter is a colon. We remove everything after the first
+% colon.
+%
+% We are now left with a string, which we must analyze. For primitives,
+% it contains only letters. For non-primitives, it contains either
+% |"|, or a space, or a digit. Two exceptions remain: \cs{c_undefined:D},
+% which is not a primitive, and \cs{tex_nullfont:D}, which is a primitive.
+%
+% Spaces cannot be grabbed in an undelimited way, so we check them
+% separately. If there is a space, we test for \cs{tex_nullfont:D}.
+% Otherwise, we go through characters one by one, and stop at the
+% first character less than |`A| (this is not quite a test for
+% \enquote{only letters}, but is close enough to work in this context).
+% If this first character is |:| then we have a primitive, or
+% \cs{c_undefined:D}, and if it is |"| or a digit, then the token
+% is not a primitive.
+%
+% \begin{macrocode}
+\tex_chardef:D \c_token_A_int = `A ~ %
+\group_begin:
+\char_set_catcode_other:N \;
+\char_set_lccode:nn { `\; } { `\: }
+\char_set_lccode:nn { `\T } { `\T }
+\char_set_lccode:nn { `\F } { `\F }
+\tl_to_lowercase:n {
+ \group_end:
+ \prg_new_conditional:Npnn \token_if_primitive:N #1 { p , T , F , TF }
+ {
+ \token_if_macro:NTF #1
+ \prg_return_false:
+ {
+ \exp_after:wN \token_if_primitive_aux:NNw
+ \token_to_meaning:N #1 ; ; ; \q_stop #1
+ }
+ }
+ \cs_new_nopar:Npn \token_if_primitive_aux:NNw #1#2 #3 ; #4 \q_stop
+ {
+ \tl_if_empty:oTF { \token_if_primitive_aux_space:w #3 ~ }
+ { \token_if_primitive_aux_loop:N #3 ; \q_stop }
+ { \token_if_primitive_aux_nullfont:N }
+ }
+}
+\cs_new_nopar:Npn \token_if_primitive_aux_space:w #1 ~ { }
+\cs_new:Npn \token_if_primitive_aux_nullfont:N #1
+ {
+ \if_meaning:w \tex_nullfont:D #1
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\cs_new_nopar:Npn \token_if_primitive_aux_loop:N #1
+ {
+ \if_num:w `#1 < \c_token_A_int %
+ \exp_after:wN \token_if_primitive_auxii:Nw
+ \exp_after:wN #1
+ \else:
+ \exp_after:wN \token_if_primitive_aux_loop:N
+ \fi:
+ }
+\cs_new_nopar:Npn \token_if_primitive_auxii:Nw #1 #2 \q_stop
+ {
+ \if:w : #1
+ \exp_after:wN \token_if_primitive_aux_undefined:N
+ \else:
+ \prg_return_false:
+ \exp_after:wN \use_none:n
+ \fi:
+ }
+\cs_new:Npn \token_if_primitive_aux_undefined:N #1
+ {
+ \if_cs_exist:N #1
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Peeking ahead at the next token}
+%
+% Peeking ahead is implemented using a two part mechanism. The
+% outer level provides a defined interface to the lower level material.
+% This allows a large amount of code to be shared. There are four
+% cases:
+% \begin{enumerate}
+% \item peek at the next token;
+% \item peek at the next non-space token;
+% \item peek at the next token and remove it;
+% \item peek at the next non-space token and remove it.
+% \end{enumerate}
+%
+% \begin{variable}{\l_peek_token}
+% \begin{variable}{\g_peek_token}
+% Storage tokens which are publicly documented: the token peeked.
+% \begin{macrocode}
+\cs_new_eq:NN \l_peek_token ?
+\cs_new_eq:NN \g_peek_token ?
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+%
+% \begin{variable}{\l_peek_search_token}
+% The token to search for as an implicit token:
+% \emph{cf.}~\cs{l_peek_search_tl}.
+% \begin{macrocode}
+\cs_new_eq:NN \l_peek_search_token ?
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_peek_search_tl}
+% The token to search for as an explicit token:
+% \emph{cf.}~\cs{l_peek_search_token}.
+% \begin{macrocode}
+\cs_new_nopar:Npn \l_peek_search_tl { }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}[aux]
+% {\peek_true:w, \peek_true_aux:w, \peek_false:w, \peek_tmp:w}
+% Functions used by the branching and space-stripping code.
+% \begin{macrocode}
+\cs_new_nopar:Npn \peek_true:w { }
+\cs_new_nopar:Npn \peek_true_aux:w { }
+\cs_new_nopar:Npn \peek_false:w { }
+\cs_new:Npn \peek_tmp:w { }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\peek_after:Nw}
+% \begin{macro}{\peek_after:Nw}
+% Simple wrappers for \cs{tex_futurelet:D}: no arguments absorbed
+% here.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \peek_after:Nw
+ { \tex_futurelet:D \l_peek_token }
+\cs_new_protected_nopar:Npn \peek_gafter:Nw
+ { \pref_global:D \tex_futurelet:D \g_peek_token }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[aux]{\peek_true_remove:w}
+% A function to remove the next token and then regain control.
+% \begin{macrocode}
+\cs_new_protected:Npn \peek_true_remove:w
+ {
+ \group_align_safe_end:
+ \tex_afterassignment:D \peek_true_aux:w
+ \cs_set_eq:NN \peek_tmp:w
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[TF]{\peek_token_generic:NN}
+% The generic function stores the test token in both implicit and
+% explicit modes, and the \texttt{true} and \texttt{false} code as
+% token lists, more or less. The two branches have to be absorbed here
+% as the input stream needs to be cleared for the peek function itself.
+% \begin{macrocode}
+\cs_new_protected:Npn \peek_token_generic:NNTF #1#2#3#4
+ {
+ \cs_set_eq:NN \l_peek_search_token #2
+ \tl_set:Nn \l_peek_search_tl {#2}
+ \cs_set_nopar:Npx \peek_true:w
+ {
+ \exp_not:N \group_align_safe_end:
+ \exp_not:n {#3}
+ }
+ \cs_set_nopar:Npx \peek_false:w
+ {
+ \exp_not:N \group_align_safe_end:
+ \exp_not:n {#4}
+ }
+ \group_align_safe_begin:
+ \peek_after:Nw #1
+ }
+\cs_new_protected:Npn \peek_token_generic:NNT #1#2#3
+ { \peek_token_generic:NNTF #1 #2 {#3} { } }
+\cs_new_protected:Npn \peek_token_generic:NNF #1#2#3
+ { \peek_token_generic:NNTF #1 #2 { } {#3} }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[TF]{\peek_token_remove_generic:NN}
+% For token removal there needs to be a call to the auxiliary
+% function which does the work.
+% \begin{macrocode}
+\cs_new_protected:Npn \peek_token_remove_generic:NNTF #1#2#3#4
+ {
+ \cs_set_eq:NN \l_peek_search_token #2
+ \tl_set:Nn \l_peek_search_tl {#2}
+ \cs_set_eq:NN \peek_true:w \peek_true_remove:w
+ \cs_set_nopar:Npx \peek_true_aux:w { \exp_not:n {#3} }
+ \cs_set_nopar:Npx \peek_false:w
+ {
+ \exp_not:N \group_align_safe_end:
+ \exp_not:n {#4}
+ }
+ \group_align_safe_begin:
+ \peek_after:Nw #1
+ }
+\cs_new_protected:Npn \peek_token_remove_generic:NNT #1#2#3
+ { \peek_token_remove_generic:NNTF #1 #2 {#3} { } }
+\cs_new_protected:Npn \peek_token_remove_generic:NNF #1#2#3
+ { \peek_token_remove_generic:NNTF #1 #2 { } {#3} }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {\peek_execute_branches_catcode:, \peek_execute_branches_meaning:}
+% The category code and meaning tests are straight forward.
+% \begin{macrocode}
+\cs_new_nopar:Npn \peek_execute_branches_catcode:
+ {
+ \if_catcode:w
+ \exp_not:N \l_peek_token \exp_not:N \l_peek_search_token
+ \exp_after:wN \peek_true:w
+ \else:
+ \exp_after:wN \peek_false:w
+ \fi:
+ }
+\cs_new_nopar:Npn \peek_execute_branches_meaning:
+ {
+ \if_meaning:w \l_peek_token \l_peek_search_token
+ \exp_after:wN \peek_true:w
+ \else:
+ \exp_after:wN \peek_false:w
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\peek_execute_branches_charcode:}
+% \begin{macro}[aux]{\peek_execute_branches_charcode:NN}
+% First the character code test there is a need to worry about \TeX{}
+% grabbing brace group or skipping spaces. These are all tested for
+% using a category code check before grabbing what must be a real
+% single token and doing the comparison.
+% \begin{macrocode}
+\cs_new_nopar:Npn \peek_execute_branches_charcode:
+ {
+ \bool_if:nTF
+ {
+ \token_if_eq_catcode_p:NN \l_peek_token \c_group_begin_token
+ || \token_if_eq_catcode_p:NN \l_peek_token \c_group_end_token
+ || \token_if_eq_meaning_p:NN \l_peek_token \c_space_token
+ }
+ { \peek_false:w }
+ {
+ \exp_after:wN \peek_execute_branches_charcode_aux:NN
+ \l_peek_search_tl
+ }
+ }
+\cs_new:Npn \peek_execute_branches_charcode_aux:NN #1#2
+ {
+ \if:w \exp_not:N #1 \exp_not:N #2
+ \exp_after:wN \peek_true:w
+ \else:
+ \exp_after:wN \peek_false:w
+ \fi:
+ #2
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\peek_ignore_spaces_execute_branches:}
+% \begin{macro}[aux]{\peek_ignore_spaces_execute_branches_aux:}
+% This function removes one token at a time with a mechanism that can
+% be applied to things other than spaces.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \peek_ignore_spaces_execute_branches:
+ {
+ \token_if_eq_meaning:NNTF \l_peek_token \c_space_token
+ {
+ \tex_afterassignment:D \peek_ignore_spaces_execute_branches_aux:
+ \cs_set_eq:NN \peek_tmp:w
+ }
+ { \peek_execute_branches: }
+ }
+\cs_new_protected_nopar:Npn \peek_ignore_spaces_execute_branches_aux:
+ { \peek_after:Nw \peek_ignore_spaces_execute_branches: }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[aux]{\peek_def:nnnn}
+% \begin{macro}[aux]{\peek_def_aux:nnnnn}
+% The public functions themselves cannot be defined using
+% \cs{prg_set_conditional:Npnn} and so a couple of auxiliary functions
+% are used. As a result, everything is done inside a group. As a result
+% things are a bit complicated.
+% \begin{macrocode}
+\group_begin:
+ \cs_set_nopar:Npn \peek_def:nnnn #1#2#3#4
+ {
+ \peek_def_aux:nnnnn {#1} {#2} {#3} {#4} { TF }
+ \peek_def_aux:nnnnn {#1} {#2} {#3} {#4} { T }
+ \peek_def_aux:nnnnn {#1} {#2} {#3} {#4} { F }
+ }
+ \cs_set_nopar:Npn \peek_def_aux:nnnnn #1#2#3#4#5
+ {
+ \cs_gset_nopar:cpx { #1 #5 }
+ {
+ \tl_if_empty:nF {#2}
+ { \exp_not:n { \cs_set_eq:NN \peek_execute_branches: #2 } }
+ \exp_not:c { #3 #5 }
+ \exp_not:n {#4}
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \begin{macro}[TF]
+% {
+% \peek_catcode:N, \peek_catcode_ignore_spaces:N,
+% \peek_catcode_remove:N, \peek_catcode_remove_ignore_spaces:N
+% }
+% With everything in place the definitions can take place. First for
+% category codes.
+% \begin{macrocode}
+ \peek_def:nnnn { peek_catcode:N }
+ { }
+ { peek_token_generic:NN }
+ { \peek_execute_branches_catcode: }
+ \peek_def:nnnn { peek_catcode_ignore_spaces:N }
+ { \peek_execute_branches_catcode: }
+ { peek_token_generic:NN }
+ { \peek_ignore_spaces_execute_branches: }
+ \peek_def:nnnn { peek_catcode_remove:N }
+ { }
+ { peek_token_remove_generic:NN }
+ { \peek_execute_branches_catcode: }
+ \peek_def:nnnn { peek_catcode_remove_ignore_spaces:N }
+ { \peek_execute_branches_catcode: }
+ { peek_token_remove_generic:NN }
+ { \peek_ignore_spaces_execute_branches: }
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}[TF]
+% {
+% \peek_charcode:N, \peek_charcode_ignore_spaces:N,
+% \peek_charcode_remove:N, \peek_charcode_remove_ignore_spaces:N
+% }
+% Then for character codes.
+% \begin{macrocode}
+ \peek_def:nnnn { peek_charcode:N }
+ { }
+ { peek_token_generic:NN }
+ { \peek_execute_branches_charcode: }
+ \peek_def:nnnn { peek_charcode_ignore_spaces:N }
+ { \peek_execute_branches_charcode: }
+ { peek_token_generic:NN }
+ { \peek_ignore_spaces_execute_branches: }
+ \peek_def:nnnn { peek_charcode_remove:N }
+ { }
+ { peek_token_remove_generic:NN }
+ { \peek_execute_branches_charcode: }
+ \peek_def:nnnn { peek_charcode_remove_ignore_spaces:N }
+ { \peek_execute_branches_charcode: }
+ { peek_token_remove_generic:NN }
+ { \peek_ignore_spaces_execute_branches: }
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}[TF]
+% {
+% \peek_meaning:N, \peek_meaning_ignore_spaces:N,
+% \peek_meaning_remove:N, \peek_meaning_remove_ignore_spaces:N
+% }
+% Finally for meaning, with the group closed to remove the temporary
+% definition functions.
+% \begin{macrocode}
+ \peek_def:nnnn { peek_meaning:N }
+ { }
+ { peek_token_generic:NN }
+ { \peek_execute_branches_meaning: }
+ \peek_def:nnnn { peek_meaning_ignore_spaces:N }
+ { \peek_execute_branches_meaning: }
+ { peek_token_generic:NN }
+ { \peek_ignore_spaces_execute_branches: }
+ \peek_def:nnnn { peek_meaning_remove:N }
+ { }
+ { peek_token_remove_generic:NN }
+ { \peek_execute_branches_meaning: }
+ \peek_def:nnnn { peek_meaning_remove_ignore_spaces:N }
+ { \peek_execute_branches_meaning: }
+ { peek_token_remove_generic:NN }
+ { \peek_ignore_spaces_execute_branches: }
+\group_end:
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Decomposing a macro definition}
+%
+% \begin{macro}{\token_get_prefix_spec:N}
+% \begin{macro}{\token_get_arg_spec:N}
+% \begin{macro}{\token_get_replacement_spec:N}
+% \begin{macro}[aux]{\token_get_prefix_arg_replacement_aux:wN}
+% We sometimes want to test if a
+% control sequence can be expanded to reveal a hidden
+% value. However, we cannot just expand the macro blindly as it may
+% have arguments and none might be present. Therefore we define
+% these functions to pick either the prefix(es), the argument
+% specification, or the replacement text from a macro. All of this
+% information is returned as characters with catcode~$12$. If the
+% token in question isn't a macro, the token |\scan_stop:| is
+% returned instead.
+% \begin{macrocode}
+\exp_args:Nno \use:nn
+ { \cs_new_nopar:Npn \token_get_prefix_arg_replacement_aux:wN #1 }
+ { \tl_to_str:n { macro : } #2 -> #3 \q_stop #4 }
+ { #4 {#1} {#2} {#3} }
+\cs_new:Npn \token_get_prefix_spec:N #1
+ {
+ \token_if_macro:NTF #1
+ {
+ \exp_after:wN \token_get_prefix_arg_replacement_aux:wN
+ \token_to_meaning:N #1 \q_stop \use_i:nnn
+ }
+ { \scan_stop: }
+ }
+\cs_new:Npn \token_get_arg_spec:N #1
+ {
+ \token_if_macro:NTF #1
+ {
+ \exp_after:wN \token_get_prefix_arg_replacement_aux:wN
+ \token_to_meaning:N #1 \q_stop \use_ii:nnn
+ }
+ { \scan_stop: }
+ }
+\cs_new:Npn \token_get_replacement_spec:N #1
+ {
+ \token_if_macro:NTF #1
+ {
+ \exp_after:wN \token_get_prefix_arg_replacement_aux:wN
+ \token_to_meaning:N #1 \q_stop \use_iii:nnn
+ }
+ { \scan_stop: }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Experimental token functions}
+%
+% \begin{macro}{\char_active_set:Npn,\char_active_set:Npx}
+% \begin{macro}{\char_active_set:Npn,\char_active_set:Npx}
+% \begin{macro}{\char_active_set_eq:NN,\char_active_gset_eq:NN}
+% \begin{macrocode}
+\group_begin:
+ \char_set_catcode_active:N \^^@
+ \cs_set:Npn \char_tmp:NN #1#2
+ {
+ \cs_new:Npn #1 ##1
+ {
+ \char_set_catcode_active:n { `##1 }
+ \group_begin:
+ \char_set_lccode:nn { `\^^@ } { `##1 }
+ \tl_to_lowercase:n { \group_end: #2 ^^@ }
+ }
+ }
+ \char_tmp:NN \char_active_set:Npn \cs_set:Npn
+ \char_tmp:NN \char_active_set:Npx \cs_set:Npx
+ \char_tmp:NN \char_active_gset:Npn \cs_gset:Npn
+ \char_tmp:NN \char_active_gset:Npx \cs_gset:Npx
+ \char_tmp:NN \char_active_set_eq:NN \cs_set_eq:NN
+ \char_tmp:NN \char_active_gset_eq:NN \cs_gset_eq:NN
+\group_end:
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Deprecated functions}
+%
+% Deprecated on 2011-05-27, for removal by 2011-08-31.
+%
+% \begin{macro}{\char_set_catcode:w}
+% \begin{macro}{\char_set_mathcode:w}
+% \begin{macro}{\char_set_lccode:w}
+% \begin{macro}{\char_set_uccode:w}
+% \begin{macro}{\char_set_sfcode:w}
+% Primitives renamed.
+% \begin{macrocode}
+\cs_new_eq:NN \char_set_catcode:w \tex_catcode:D
+\cs_new_eq:NN \char_set_mathcode:w \tex_mathcode:D
+\cs_new_eq:NN \char_set_lccode:w \tex_lccode:D
+\cs_new_eq:NN \char_set_uccode:w \tex_uccode:D
+\cs_new_eq:NN \char_set_sfcode:w \tex_sfcode:D
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\char_value_catcode:w}
+% \begin{macro}{\char_show_value_catcode:w}
+% \begin{macro}{\char_value_mathcode:w}
+% \begin{macro}{\char_show_value_mathcode:w}
+% \begin{macro}{\char_value_lccode:w}
+% \begin{macro}{\char_show_value_lccode:w}
+% \begin{macro}{\char_value_uccode:w}
+% \begin{macro}{\char_show_value_uccode:w}
+% \begin{macro}{\char_value_sfcode:w}
+% \begin{macro}{\char_show_value_sfcode:w}
+% More |w| functions we should not have.
+% \begin{macrocode}
+\cs_new_nopar:Npn \char_value_catcode:w { \tex_the:D \char_set_catcode:w }
+\cs_new_nopar:Npn \char_show_value_catcode:w
+ { \tex_showthe:D \char_set_catcode:w }
+\cs_new_nopar:Npn \char_value_mathcode:w { \tex_the:D \char_set_mathcode:w }
+\cs_new_nopar:Npn \char_show_value_mathcode:w
+ { \tex_showthe:D \char_set_mathcode:w }
+\cs_new_nopar:Npn \char_value_lccode:w { \tex_the:D \char_set_lccode:w }
+\cs_new_nopar:Npn \char_show_value_lccode:w
+ { \tex_showthe:D \char_set_lccode:w }
+\cs_new_nopar:Npn \char_value_uccode:w { \tex_the:D \char_set_uccode:w }
+\cs_new_nopar:Npn \char_show_value_uccode:w
+ { \tex_showthe:D \char_set_uccode:w }
+\cs_new_nopar:Npn \char_value_sfcode:w { \tex_the:D \char_set_sfcode:w }
+\cs_new_nopar:Npn \char_show_value_sfcode:w
+ { \tex_showthe:D \char_set_sfcode:w }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\peek_after:NN}
+% \begin{macro}{\peek_gafter:NN}
+% The second argument here must be |w|.
+% \begin{macrocode}
+\cs_new_eq:NN \peek_after:NN \peek_after:Nw
+\cs_new_eq:NN \peek_gafter:NN \peek_gafter:Nw
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% Functions deprecated 2011-05-28 for removal by 2011-08-31.
+%
+% \begin{macro}{\c_alignment_tab_token}
+% \begin{macro}{\c_math_shift_token}
+% \begin{macro}{\c_letter_token}
+% \begin{macro}{\c_other_char_token}
+% \begin{macrocode}
+\cs_new_eq:NN \c_alignment_tab_token \c_alignment_token
+\cs_new_eq:NN \c_math_shift_token \c_math_toggle_token
+\cs_new_eq:NN \c_letter_token \c_catcode_letter_token
+\cs_new_eq:NN \c_other_char_token \c_catcode_other_token
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\c_active_char_token}
+% An odd one: this was never a |token|!
+% \begin{macrocode}
+\cs_new_eq:NN \c_active_char_token \c_catcode_active_tl
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \char_make_escape:N ,
+% \char_make_group_begin:N ,
+% \char_make_group_end:N ,
+% \char_make_math_toggle:N ,
+% \char_make_alignment:N ,
+% \char_make_end_line:N ,
+% \char_make_parameter:N ,
+% \char_make_math_superscript:N ,
+% \char_make_math_subscript:N ,
+% \char_make_ignore:N ,
+% \char_make_space:N ,
+% \char_make_letter:N ,
+% \char_make_other:N ,
+% \char_make_active:N ,
+% \char_make_comment:N ,
+% \char_make_invalid:N
+% }
+% \begin{macro}
+% {
+% \char_make_escape:n ,
+% \char_make_group_begin:n ,
+% \char_make_group_end:n ,
+% \char_make_math_toggle:n ,
+% \char_make_alignment:n ,
+% \char_make_end_line:n ,
+% \char_make_parameter:n ,
+% \char_make_math_superscript:n ,
+% \char_make_math_subscript:n ,
+% \char_make_ignore:n ,
+% \char_make_space:n ,
+% \char_make_letter:n ,
+% \char_make_other:n ,
+% \char_make_active:n ,
+% \char_make_comment:n ,
+% \char_make_invalid:n
+% }
+% Two renames in one block!
+% \begin{macrocode}
+\cs_new_eq:NN \char_make_escape:N \char_set_catcode_escape:N
+\cs_new_eq:NN \char_make_begin_group:N \char_set_catcode_group_begin:N
+\cs_new_eq:NN \char_make_end_group:N \char_set_catcode_group_end:N
+\cs_new_eq:NN \char_make_math_shift:N \char_set_catcode_math_toggle:N
+\cs_new_eq:NN \char_make_alignment_tab:N \char_set_catcode_alignment:N
+\cs_new_eq:NN \char_make_end_line:N \char_set_catcode_end_line:N
+\cs_new_eq:NN \char_make_parameter:N \char_set_catcode_parameter:N
+\cs_new_eq:NN \char_make_math_superscript:N
+ \char_set_catcode_math_superscript:N
+\cs_new_eq:NN \char_make_math_subscript:N
+ \char_set_catcode_math_subscript:N
+\cs_new_eq:NN \char_make_ignore:N \char_set_catcode_ignore:N
+\cs_new_eq:NN \char_make_space:N \char_set_catcode_space:N
+\cs_new_eq:NN \char_make_letter:N \char_set_catcode_letter:N
+\cs_new_eq:NN \char_make_other:N \char_set_catcode_other:N
+\cs_new_eq:NN \char_make_active:N \char_set_catcode_active:N
+\cs_new_eq:NN \char_make_comment:N \char_set_catcode_comment:N
+\cs_new_eq:NN \char_make_invalid:N \char_set_catcode_invalid:N
+\cs_new_eq:NN \char_make_escape:n \char_set_catcode_escape:n
+\cs_new_eq:NN \char_make_begin_group:n \char_set_catcode_group_begin:n
+\cs_new_eq:NN \char_make_end_group:n \char_set_catcode_group_end:n
+\cs_new_eq:NN \char_make_math_shift:n \char_set_catcode_math_toggle:n
+\cs_new_eq:NN \char_make_alignment_tab:n \char_set_catcode_alignment:n
+\cs_new_eq:NN \char_make_end_line:n \char_set_catcode_end_line:n
+\cs_new_eq:NN \char_make_parameter:n \char_set_catcode_parameter:n
+\cs_new_eq:NN \char_make_math_superscript:n
+ \char_set_catcode_math_superscript:n
+\cs_new_eq:NN \char_make_math_subscript:n
+ \char_set_catcode_math_subscript:n
+\cs_new_eq:NN \char_make_ignore:n \char_set_catcode_ignore:n
+\cs_new_eq:NN \char_make_space:n \char_set_catcode_space:n
+\cs_new_eq:NN \char_make_letter:n \char_set_catcode_letter:n
+\cs_new_eq:NN \char_make_other:n \char_set_catcode_other:n
+\cs_new_eq:NN \char_make_active:n \char_set_catcode_active:n
+\cs_new_eq:NN \char_make_comment:n \char_set_catcode_comment:n
+\cs_new_eq:NN \char_make_invalid:n \char_set_catcode_invalid:n
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\token_if_alignment_tab:N}
+% \begin{macro}[pTF]{\token_if_math_shift:N}
+% \begin{macro}[pTF]{\token_if_other_char:N}
+% \begin{macro}[pTF]{\token_if_active_char:N}
+% \begin{macrocode}
+\cs_new_eq:NN \token_if_alignment_tab_p:N \token_if_alignment_p:N
+\cs_new_eq:NN \token_if_alignment_tab:NT \token_if_alignment:NT
+\cs_new_eq:NN \token_if_alignment_tab:NF \token_if_alignment:NF
+\cs_new_eq:NN \token_if_alignment_tab:NTF \token_if_alignment:NTF
+\cs_new_eq:NN \token_if_math_shift_p:N \token_if_math_toggle_p:N
+\cs_new_eq:NN \token_if_math_shift:NT \token_if_math_toggle:NT
+\cs_new_eq:NN \token_if_math_shift:NF \token_if_math_toggle:NF
+\cs_new_eq:NN \token_if_math_shift:NTF \token_if_math_toggle:NTF
+\cs_new_eq:NN \token_if_other_char_p:N \token_if_other_p:N
+\cs_new_eq:NN \token_if_other_char:NT \token_if_other:NT
+\cs_new_eq:NN \token_if_other_char:NF \token_if_other:NF
+\cs_new_eq:NN \token_if_other_char:NTF \token_if_other:NTF
+\cs_new_eq:NN \token_if_active_char_p:N \token_if_active_p:N
+\cs_new_eq:NN \token_if_active_char:NT \token_if_active:NT
+\cs_new_eq:NN \token_if_active_char:NF \token_if_active:NF
+\cs_new_eq:NN \token_if_active_char:NTF \token_if_active:NTF
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macrocode}
+%</initex|package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3toks.dtx b/Master/texmf-dist/source/latex/l3kernel/l3toks.dtx
new file mode 100644
index 00000000000..62824848afc
--- /dev/null
+++ b/Master/texmf-dist/source/latex/l3kernel/l3toks.dtx
@@ -0,0 +1,548 @@
+% \iffalse meta-comment
+%
+%% File: l3toks.dtx Copyright (C) 1990-2011 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 "expl3 bundle" (The Work in LPPL)
+%% and all files in that bundle must be distributed together.
+%%
+%% The released version of this bundle is available from CTAN.
+%%
+%% -----------------------------------------------------------------------
+%%
+%% The development version of the bundle can be found at
+%%
+%% http://www.latex-project.org/svnroot/experimental/trunk/
+%%
+%% for those people who are interested.
+%%
+%%%%%%%%%%%
+%% NOTE: %%
+%%%%%%%%%%%
+%%
+%% Snapshots taken from the repository represent work in progress and may
+%% not work or may contain conflicting material! We therefore ask
+%% people _not_ to put them into distributions, archives, etc. without
+%% prior consultation with the LaTeX3 Project.
+%%
+%% -----------------------------------------------------------------------
+%
+%<*driver|package>
+\RequirePackage{l3names}
+\GetIdInfo$Id: l3toks.dtx 2478 2011-06-19 21:34:23Z joseph $
+ {L3 Experimental token registers}
+%</driver|package>
+%<*driver>
+\documentclass[full]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3toks} package\\ Token registers^^A
+% \thanks{This file describes v\ExplFileVersion,
+% last revised \ExplFileDate.}^^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 \ExplFileDate}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% \textbf{THIS ENTIRE MODULE IS DEPRECIATED: DO NOT USE \cs{TOKS_\ldots}
+% FUNCTIONS}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3toks} implementation}
+%
+% We start by ensuring that the required packages are loaded.
+% \begin{macrocode}
+%<*package>
+\ProvidesExplPackage
+ {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
+\package_check_loaded_expl:
+%</package>
+%<*initex|package>
+% \end{macrocode}
+%
+% \subsection{Allocation and use}
+%
+% \begin{macro}{\toks_new:N,\toks_new:c}
+% Allocates a new token register.
+% \begin{macrocode}
+%<*initex>
+\alloc_new:nnnN {toks} \c_zero \c_max_register_int \tex_toksdef:D
+%</initex>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*package>
+\cs_new_protected_nopar:Npn \toks_new:N #1 {
+ \chk_if_free_cs:N #1
+ \newtoks #1
+}
+%</package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_generate_variant:Nn \toks_new:N {c}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\toks_use:N}
+% \begin{macro}{\toks_use:c}
+% This function returns the contents of a token register.
+% \begin{macrocode}
+\cs_new_eq:NN \toks_use:N \tex_the:D
+\cs_generate_variant:Nn \toks_use:N {c}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\toks_set:Nn}
+% \begin{macro}{\toks_set:NV}
+% \begin{macro}{\toks_set:Nv}
+% \begin{macro}{\toks_set:No}
+% \begin{macro}{\toks_set:Nx}
+% \begin{macro}{\toks_set:Nf}
+% \begin{macro}{\toks_set:cn}
+% \begin{macro}{\toks_set:co}
+% \begin{macro}{\toks_set:cV}
+% \begin{macro}{\toks_set:cv}
+% \begin{macro}{\toks_set:cx}
+% \begin{macro}{\toks_set:cf}
+% |\toks_set:Nn|\m{toks}\m{stuff} stores \m{stuff} without expansion
+% in \m{toks}. |\toks_set:No| and |\toks_set:Nx| expand \m{stuff} once
+% and fully.
+% \begin{macrocode}
+%<*check>
+\cs_new_protected_nopar:Npn \toks_set:Nn #1 { \chk_local:N #1 #1 }
+\cs_generate_variant:Nn \toks_set:Nn {No,Nf}
+%</check>
+% \end{macrocode}
+% If we don't check if \m{toks} is a local register then the
+% |\toks_set:Nn| function has nothing to do.
+% We implement |\toks_set:No|/|d|/|f| by hand when not checking because this
+% is going to be used \emph{extensively} in keyval processing!
+% TODO: (Will) Can we get some numbers published on how necessary this is?
+% On the other hand I'm happy to believe Morten |:)|
+% \begin{macrocode}
+%<*!check>
+\cs_new_eq:NN \toks_set:Nn \prg_do_nothing:
+\cs_new_protected:Npn \toks_set:NV #1#2 {
+ #1 \exp_after:wN { \int_to_roman:w -`0 \exp_eval_register:N #2 }
+}
+\cs_new_protected:Npn \toks_set:Nv #1#2 {
+ #1 \exp_after:wN { \int_to_roman:w -`0 \exp_eval_register:c {#2} }
+}
+\cs_new_protected:Npn \toks_set:No #1#2 { #1 \exp_after:wN {#2} }
+\cs_new_protected:Npn \toks_set:Nf #1#2 {
+ #1 \exp_after:wN { \int_to_roman:w -`0#2 }
+}
+%</!check>
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_generate_variant:Nn \toks_set:Nn {Nx,cn,cV,cv,co,cx,cf}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\toks_gset:Nn}
+% \begin{macro}{\toks_gset:NV}
+% \begin{macro}{\toks_gset:No}
+% \begin{macro}{\toks_gset:Nx}
+% \begin{macro}{\toks_gset:cn}
+% \begin{macro}{\toks_gset:cV}
+% \begin{macro}{\toks_gset:co}
+% \begin{macro}{\toks_gset:cx}
+% These functions are the global variants of the above.
+% \begin{macrocode}
+%<check>\cs_new_protected_nopar:Npn \toks_gset:Nn #1 { \chk_global:N #1 \pref_global:D #1 }
+%<!check>\cs_new_eq:NN \toks_gset:Nn \pref_global:D
+\cs_generate_variant:Nn \toks_gset:Nn {NV,No,Nx,cn,cV,co,cx}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\toks_set_eq:NN}
+% \begin{macro}{\toks_set_eq:Nc}
+% \begin{macro}{\toks_set_eq:cN}
+% \begin{macro}{\toks_set_eq:cc}
+% \begin{macro}{\toks_gset_eq:NN}
+% \begin{macro}{\toks_gset_eq:Nc}
+% \begin{macro}{\toks_gset_eq:cN}
+% \begin{macro}{\toks_gset_eq:cc}
+% |\toks_set_eq:NN|\m{toks1}\m{toks2} copies the contents of \m{toks2}
+% in \m{toks1}.
+% \begin{macrocode}
+%<*check>
+\cs_new_protected_nopar:Npn\toks_set_eq:NN #1#2 {
+ \chk_local:N #1
+ \chk_var_or_const:N #2
+ #1 #2
+}
+\cs_new_protected_nopar:Npn\toks_gset_eq:NN #1#2 {
+ \chk_global:N #1
+ \chk_var_or_const:N #2
+ \pref_global:D #1 #2
+}
+%</check>
+%<*!check>
+\cs_new_eq:NN \toks_set_eq:NN \prg_do_nothing:
+\cs_new_eq:NN \toks_gset_eq:NN \pref_global:D
+%</!check>
+\cs_generate_variant:Nn \toks_set_eq:NN {Nc,cN,cc}
+\cs_generate_variant:Nn \toks_gset_eq:NN {Nc,cN,cc}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\toks_clear:N,\toks_gclear:N,\toks_clear:c,\toks_gclear:c}
+% These functions clear a token register, either locally or globally.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \toks_clear:N #1 {
+ #1\c_empty_toks
+%<check>\chk_local_or_pref_global:N #1
+}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \toks_gclear:N {
+%<check> \pref_global_chk:
+%<!check> \pref_global:D
+ \toks_clear:N
+}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_generate_variant:Nn \toks_clear:N {c}
+\cs_generate_variant:Nn \toks_gclear:N {c}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\toks_use_clear:N}
+% \begin{macro}{\toks_use_clear:c}
+% \begin{macro}{\toks_use_gclear:N}
+% \begin{macro}{\toks_use_gclear:c}
+% These functions clear a token register (locally or globally) after
+% returning the contents.
+%
+% They make sure that clearing the register does not
+% interfere with following tokens. In other words, the contents of
+% the register might operate on what follows in the input stream.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \toks_use_clear:N #1 {
+ \exp_last_unbraced:NNV \toks_clear:N #1 #1
+}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \toks_use_gclear:N {
+%<check> \pref_global_chk:
+%<!check> \pref_global:D
+ \toks_use_clear:N
+}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_generate_variant:Nn \toks_use_clear:N {c}
+\cs_generate_variant:Nn \toks_use_gclear:N {c}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\toks_show:N}
+% \begin{macro}{\toks_show:c}
+% This function shows the contents of a token register on the terminal.
+% \begin{macrocode}
+\cs_new_eq:NN \toks_show:N \kernel_register_show:N
+\cs_generate_variant:Nn \toks_show:N {c}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Adding to token registers' contents}
+%
+% \begin{macro}{\toks_put_left:Nn}
+% \begin{macro}{\toks_put_left:NV}
+% \begin{macro}{\toks_put_left:No}
+% \begin{macro}{\toks_put_left:Nx}
+% \begin{macro}{\toks_put_left:cn}
+% \begin{macro}{\toks_put_left:cV}
+% \begin{macro}{\toks_put_left:co}
+% \begin{macro}{\toks_gput_left:Nn}
+% \begin{macro}{\toks_gput_left:NV}
+% \begin{macro}{\toks_gput_left:No}
+% \begin{macro}{\toks_gput_left:Nx}
+% \begin{macro}{\toks_gput_left:cn}
+% \begin{macro}{\toks_gput_left:cV}
+% \begin{macro}{\toks_gput_left:co}
+% \begin{macro}[aux]{\toks_put_left_aux:w}
+% |\toks_put_left:Nn |\meta{toks}\meta{stuff\/} adds the tokens of
+% \textsl{stuff} on the `left-side' of the token register
+% \m{toks}. |\toks_put_left:No| does the same, but expands the
+% tokens once. We need to look out for brace stripping so we add a
+% token, which is then later removed.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \toks_put_left:Nn #1 {
+ \exp_after:wN \toks_put_left_aux:w \exp_after:wN \q_nil
+ \toks_use:N #1 \q_stop #1
+}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_generate_variant:Nn \toks_put_left:Nn {NV,No,Nx,cn,co,cV}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \toks_gput_left:Nn {
+%<check> \pref_global_chk:
+%<!check> \pref_global:D
+ \toks_put_left:Nn
+}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_generate_variant:Nn \toks_gput_left:Nn {NV,No,Nx,cn,cV,co}
+% \end{macrocode}
+% A helper function for |\toks_put_left:Nn|. Its arguments are
+% subsequently the tokens of \meta{stuff\/}, the token register
+% \meta{toks} and the current contents of \meta{toks}. We make sure to
+% remove the token we inserted earlier.
+% \begin{macrocode}
+\cs_new:Npn \toks_put_left_aux:w #1\q_stop #2#3 {
+ #2 \exp_after:wN { \use_i:nn {#3} #1 }
+%<check> \chk_local_or_pref_global:N #2
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\toks_put_right:Nn}
+% \begin{macro}{\toks_put_right:NV}
+% \begin{macro}{\toks_put_right:No}
+% \begin{macro}{\toks_put_right:Nx}
+% \begin{macro}{\toks_put_right:cn}
+% \begin{macro}{\toks_put_right:cV}
+% \begin{macro}{\toks_put_right:co}
+% \begin{macro}{\toks_gput_right:Nn}
+% \begin{macro}{\toks_gput_right:NV}
+% \begin{macro}{\toks_gput_right:No}
+% \begin{macro}{\toks_gput_right:Nx}
+% \begin{macro}{\toks_gput_right:cn}
+% \begin{macro}{\toks_gput_right:cV}
+% \begin{macro}{\toks_gput_right:co}
+% These macros add a list of tokens to the right of a token register.
+% \begin{macrocode}
+\cs_new_protected:Npn \toks_put_right:Nn #1#2 {
+ #1 \exp_after:wN { \toks_use:N #1 #2 }
+%<check> \chk_local_or_pref_global:N #1
+}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \toks_gput_right:Nn {
+%<check> \pref_global_chk:
+%<!check> \pref_global:D
+ \toks_put_right:Nn
+}
+% \end{macrocode}
+% A couple done by hand for speed.
+% \begin{macrocode}
+%<check>\cs_generate_variant:Nn \toks_put_right:Nn {No}
+%<*!check>
+\cs_new_protected:Npn \toks_put_right:NV #1#2 {
+ #1 \exp_after:wN \exp_after:wN \exp_after:wN {
+ \exp_after:wN \toks_use:N \exp_after:wN #1
+ \int_to_roman:w -`0 \exp_eval_register:N #2
+ }
+}
+\cs_new_protected:Npn \toks_put_right:No #1#2 {
+ #1 \exp_after:wN \exp_after:wN \exp_after:wN {
+ \exp_after:wN \toks_use:N \exp_after:wN #1 #2
+ }
+}
+%</!check>
+\cs_generate_variant:Nn \toks_put_right:Nn {Nx,cn,cV,co}
+\cs_generate_variant:Nn \toks_gput_right:Nn {NV,No,Nx,cn,cV,co}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\toks_put_right:Nf}
+% We implement |\toks_put_right:Nf| by hand because I think I might
+% use it in the \textsf{l3keyval} module in which case it is going to
+% be used a lot.
+% \begin{macrocode}
+%<check>\cs_generate_variant:Nn \toks_put_right:Nn {Nf}
+%<*!check>
+\cs_new_protected:Npn \toks_put_right:Nf #1#2 {
+ #1 \exp_after:wN \exp_after:wN \exp_after:wN {
+ \exp_after:wN \toks_use:N \exp_after:wN #1 \int_to_roman:w -`0#2
+ }
+}
+%</!check>
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Predicates and conditionals}
+%
+% \begin{macro}{\toks_if_empty_p:N,\toks_if_empty_p:c}
+% \begin{macro}[TF]{\toks_if_empty:N,\toks_if_empty:c}
+% |\toks_if_empty:NTF|\m{toks}\m{true code}\m{false code} tests if a
+% token register is empty and executes either \m{true code} or
+% \m{false code}. This test had the advantage of being
+% expandable. Otherwise one has to do an |x| type expansion in order
+% to prevent problems with parameter tokens.
+% \begin{macrocode}
+\prg_new_conditional:Nnn \toks_if_empty:N {p,TF,T,F} {
+ \tl_if_empty:VTF #1 {\prg_return_true:} {\prg_return_false:}
+}
+% \end{macrocode}
+% \begin{macrocode}
+\cs_generate_variant:Nn \toks_if_empty_p:N {c}
+\cs_generate_variant:Nn \toks_if_empty:NTF {c}
+\cs_generate_variant:Nn \toks_if_empty:NT {c}
+\cs_generate_variant:Nn \toks_if_empty:NF {c}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\toks_if_eq_p:NN,\toks_if_eq_p:cN,\toks_if_eq_p:Nc,\toks_if_eq_p:cc}
+% \begin{macro}[TF]{\toks_if_eq:NN,\toks_if_eq:Nc,\toks_if_eq:cN,\toks_if_eq:cc}
+% This function test whether two token registers have the same contents.
+% \begin{macrocode}
+\prg_new_conditional:Nnn \toks_if_eq:NN {p,TF,T,F} {
+ \str_if_eq:xxTF {\toks_use:N #1} {\toks_use:N #2}
+ {\prg_return_true:} {\prg_return_false:}
+}
+\cs_generate_variant:Nn \toks_if_eq_p:NN {Nc,c,cc}
+\cs_generate_variant:Nn \toks_if_eq:NNTF {Nc,c,cc}
+\cs_generate_variant:Nn \toks_if_eq:NNT {Nc,c,cc}
+\cs_generate_variant:Nn \toks_if_eq:NNF {Nc,c,cc}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Variables and constants}
+%
+% \begin{macro}{\l_tmpa_toks}
+% \begin{macro}{\l_tmpb_toks}
+% \begin{macro}{\l_tmpc_toks}
+% \begin{macro}{\g_tmpa_toks}
+% \begin{macro}{\g_tmpb_toks}
+% \begin{macro}{\g_tmpc_toks}
+% Some scratch registers \ldots
+% \begin{macrocode}
+\tex_toksdef:D \l_tmpa_toks = 255\scan_stop:
+%<initex>\seq_put_right:Nn \g_toks_allocation_seq {255}
+\toks_new:N \l_tmpb_toks
+\toks_new:N \l_tmpc_toks
+\toks_new:N \g_tmpa_toks
+\toks_new:N \g_tmpb_toks
+\toks_new:N \g_tmpc_toks
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\c_empty_toks}
+% And here is a constant, which is a (permanently) empty token register.
+% \begin{macrocode}
+\toks_new:N \c_empty_toks
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\l_tl_replace_toks}
+% And here is one for tl vars. Can't define it there as the allocation
+% isn't set up at that point.
+% \begin{macrocode}
+\toks_new:N \l_tl_replace_toks
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</initex|package>
+% \end{macrocode}
+%
+%
+% \end{implementation}
+% \PrintIndex
+%
+% \endinput
+
diff --git a/Master/texmf-dist/tex/latex/l3kernel/expl3.sty b/Master/texmf-dist/tex/latex/l3kernel/expl3.sty
new file mode 100644
index 00000000000..d0ac38f18e1
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/l3kernel/expl3.sty
@@ -0,0 +1,179 @@
+%%
+%% This is file `expl3.sty',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% expl3.dtx (with options: `package')
+%%
+%% EXPERIMENTAL CODE
+%%
+%% Do not distribute this file without also distributing the
+%% source files specified above.
+%%
+%% Do not distribute a modified version of this file.
+%%
+%% File: expl3.dtx Copyright (C) 1990-2011 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 "expl3 bundle" (The Work in LPPL)
+%% and all files in that bundle must be distributed together.
+%%
+%% The released version of this bundle is available from CTAN.
+%%
+%% -----------------------------------------------------------------------
+%%
+%% The development version of the bundle can be found at
+%%
+%% http://www.latex-project.org/svnroot/experimental/trunk/
+%%
+%% for those people who are interested.
+%%
+%%%%%%%%%%%
+%% NOTE: %%
+%%%%%%%%%%%
+%%
+%% Snapshots taken from the repository represent work in progress and may
+%% not work or may contain conflicting material! We therefore ask
+%% people _not_ to put them into distributions, archives, etc. without
+%% prior consultation with the LaTeX3 Project.
+%%
+%% -----------------------------------------------------------------------
+\RequirePackage{l3names}
+\GetIdInfo$Id: expl3.dtx 2478 2011-06-19 21:34:23Z joseph $
+ {L3 Experimental code bundle wrapper}
+ %\subsubsection{Variables: scope and type}
+\RequirePackage{etex}
+\reserveinserts{32}
+\RequirePackage{calc}
+\ProvidesExplPackage
+ {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
+\newcommand* \@l@expl@check@declarations@bool { 0 }
+\newcommand*\@l@expl@log@functions@bool { 0 }
+\DeclareOption { check-declarations }
+ { \def \@l@expl@check@declarations@bool { 1 } }
+\DeclareOption { log-functions }
+ {\def \@l@expl@log@functions@bool { 1 } }
+\ProcessOptions \relax
+\RequirePackage{ l3basics, l3expan, l3tl }
+\ifodd \@l@expl@check@declarations@bool \relax
+ \cs_new_protected:Npn \tl_check_exists:N #1
+ {
+ \cs_if_exist:NF #1
+ {
+ \msg_kernel_error:nnx { check } { non-declared-variable }
+ { \token_to_str:N #1 }
+ }
+ }
+ \cs_set_protected:Npn \tl_set:Nn #1#2
+ {
+ \tl_check_exists:N #1
+ \cs_set_nopar:Npx #1 { \exp_not:n {#2} }
+ }
+ \cs_set_protected:Npn \tl_set:Nx #1#2
+ {
+ \tl_check_exists:N #1
+ \cs_set_nopar:Npx #1 {#2}
+ }
+ \cs_set_protected:Npn \tl_gset:Nn #1#2
+ {
+ \tl_check_exists:N #1
+ \cs_gset_nopar:Npx #1 { \exp_not:n {#2} }
+ }
+ \cs_set_protected:Npn \tl_gset:Nx #1#2
+ {
+ \tl_check_exists:N #1
+ \cs_gset_nopar:Npx #1 {#2}
+ }
+ \cs_set_protected:Npn \tl_set_eq:NN #1#2
+ {
+ \tl_check_exists:N #1
+ \tl_check_exists:N #2
+ \cs_set_eq:NN #1 #2
+ }
+ \cs_set_protected:Npn \tl_gset_eq:NN #1#2
+ {
+ \tl_check_exists:N #1
+ \tl_check_exists:N #2
+ \cs_gset_eq:NN #1 #2
+ }
+\fi
+\RequirePackage{
+ l3seq,
+ l3int,
+ l3quark,
+ l3prg,
+ l3clist,
+ l3token,
+ l3prop,
+ l3msg,
+ l3io,
+ l3file,
+ l3skip,
+ l3box,
+ l3keyval,
+ l3keys,
+ l3fp,
+ l3luatex
+}
+\RequirePackage{l3toks}
+\bool_if:nT { \@l@expl@check@declarations@bool }
+ {
+ \msg_kernel_new:nnnn { check } { non-declared-variable }
+ { The~variable~#1~has~not~been~declared~\msg_line_context:. }
+ {
+ Checking~is~active,~and~you~have~tried~do~so~something~like: \\
+ \ \ \tl_set:Nn #1 ~
+ \iow_char:N \{ ~ ... ~ \iow_char:N \} \\
+ without~first~having: \\
+ \ \ \tl_new:N #1 \\
+ \\
+ LaTeX~will~create~the~variable~and~continue.
+ }
+ }
+\cs_set_protected_nopar:Npn \ExplSyntaxOn
+ {
+ \bool_if:NF \l_expl_status_bool
+ {
+ \cs_set_protected_nopar:Npx \ExplSyntaxOff
+ {
+ \char_set_catcode:nn { 9 } { \char_value_catcode:n { 9 } }
+ \char_set_catcode:nn { 32 } { \char_value_catcode:n { 32 } }
+ \char_set_catcode:nn { 34 } { \char_value_catcode:n { 34 } }
+ \char_set_catcode:nn { 38 } { \char_value_catcode:n { 38 } }
+ \char_set_catcode:nn { 58 } { \char_value_catcode:n { 58 } }
+ \char_set_catcode:nn { 94 } { \char_value_catcode:n { 94 } }
+ \char_set_catcode:nn { 95 } { \char_value_catcode:n { 95 } }
+ \char_set_catcode:nn { 124 } { \char_value_catcode:n { 124 } }
+ \char_set_catcode:nn { 126 } { \char_value_catcode:n { 126 } }
+ \tex_endlinechar:D = \tex_the:D \tex_endlinechar:D \scan_stop:
+ \bool_set_false:N \l_expl_status_bool
+ \cs_set_protected_nopar:Npn \ExplSyntaxOff { }
+ }
+ }
+ \char_set_catcode_ignore:n { 9 } % tab
+ \char_set_catcode_ignore:n { 32 } % space
+ \char_set_catcode_other:n { 34 } % double quote
+ \char_set_catcode_alignment:n { 38 } % ampersand
+ \char_set_catcode_letter:n { 58 } % colon
+ \char_set_catcode_math_superscript:n { 94 } % circumflex
+ \char_set_catcode_letter:n { 95 } % underscore
+ \char_set_catcode_other:n { 124 } % pipe
+ \char_set_catcode_space:n { 126 } % tilde
+ \tex_endlinechar:D = 32 \scan_stop:
+ \bool_set_true:N \l_expl_status_bool
+ }
+\cs_set_protected_nopar:Npx \ExplSyntaxOff
+ {
+ \exp_not:o \ExplSyntaxOff
+ \cs_set_protected_nopar:Npn \ExplSyntaxOff { }
+ }
+%%
+%%
+%% End of file `expl3.sty'.
diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3basics.sty b/Master/texmf-dist/tex/latex/l3kernel/l3basics.sty
new file mode 100644
index 00000000000..edecb52c1c7
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/l3kernel/l3basics.sty
@@ -0,0 +1,784 @@
+%%
+%% This is file `l3basics.sty',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% l3basics.dtx (with options: `package')
+%%
+%% EXPERIMENTAL CODE
+%%
+%% Do not distribute this file without also distributing the
+%% source files specified above.
+%%
+%% Do not distribute a modified version of this file.
+%%
+%% File: l3basics.dtx Copyright (C) 1990-2011 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 "expl3 bundle" (The Work in LPPL)
+%% and all files in that bundle must be distributed together.
+%%
+%% The released version of this bundle is available from CTAN.
+%%
+%% -----------------------------------------------------------------------
+%%
+%% The development version of the bundle can be found at
+%%
+%% http://www.latex-project.org/svnroot/experimental/trunk/
+%%
+%% for those people who are interested.
+%%
+%%%%%%%%%%%
+%% NOTE: %%
+%%%%%%%%%%%
+%%
+%% Snapshots taken from the repository represent work in progress and may
+%% not work or may contain conflicting material! We therefore ask
+%% people _not_ to put them into distributions, archives, etc. without
+%% prior consultation with the LaTeX3 Project.
+%%
+%% -----------------------------------------------------------------------
+\RequirePackage{l3names}
+\GetIdInfo$Id: l3basics.dtx 2493 2011-07-04 09:50:22Z bruno $
+ {L3 Experimental basic definitions}
+
+\ProvidesExplPackage
+ {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
+\package_check_loaded_expl:
+\tex_let:D \cs_set_eq:NwN \tex_let:D
+\cs_set_eq:NwN \if_true: \tex_iftrue:D
+\cs_set_eq:NwN \if_false: \tex_iffalse:D
+\cs_set_eq:NwN \or: \tex_or:D
+\cs_set_eq:NwN \else: \tex_else:D
+\cs_set_eq:NwN \fi: \tex_fi:D
+\cs_set_eq:NwN \reverse_if:N \etex_unless:D
+\cs_set_eq:NwN \if:w \tex_if:D
+\cs_set_eq:NwN \if_bool:N \tex_ifodd:D
+\cs_set_eq:NwN \if_predicate:w \tex_ifodd:D
+\cs_set_eq:NwN \if_charcode:w \tex_if:D
+\cs_set_eq:NwN \if_catcode:w \tex_ifcat:D
+\cs_set_eq:NwN \if_meaning:w \tex_ifx:D
+\cs_set_eq:NwN \if_mode_math: \tex_ifmmode:D
+\cs_set_eq:NwN \if_mode_horizontal: \tex_ifhmode:D
+\cs_set_eq:NwN \if_mode_vertical: \tex_ifvmode:D
+\cs_set_eq:NwN \if_mode_inner: \tex_ifinner:D
+\cs_set_eq:NwN \if_cs_exist:N \etex_ifdefined:D
+\cs_set_eq:NwN \if_cs_exist:w \etex_ifcsname:D
+\cs_set_eq:NwN \exp_after:wN \tex_expandafter:D
+\cs_set_eq:NwN \exp_not:N \tex_noexpand:D
+\cs_set_eq:NwN \exp_not:n \etex_unexpanded:D
+\cs_set_eq:NwN \token_to_meaning:N \tex_meaning:D
+\cs_set_eq:NwN \token_to_str:N \tex_string:D
+\cs_set_eq:NwN \cs:w \tex_csname:D
+\cs_set_eq:NwN \cs_end: \tex_endcsname:D
+\cs_set_eq:NwN \cs_meaning:N \tex_meaning:D
+\cs_set_eq:NwN \cs_show:N \tex_show:D
+\cs_set_eq:NwN \scan_stop: \tex_relax:D
+\cs_set_eq:NwN \group_begin: \tex_begingroup:D
+\cs_set_eq:NwN \group_end: \tex_endgroup:D
+\cs_set_eq:NwN \if_int_compare:w \tex_ifnum:D
+\cs_set_eq:NwN \int_to_roman:w \tex_romannumeral:D
+\cs_set_eq:NwN \group_insert_after:N \tex_aftergroup:D
+\cs_set_eq:NwN \pref_global:D \tex_global:D
+\cs_set_eq:NwN \pref_long:D \tex_long:D
+\cs_set_eq:NwN \pref_protected:D \etex_protected:D
+\tex_long:D \tex_def:D \exp_args:Nc #1#2 { \exp_after:wN #1 \cs:w #2 \cs_end: }
+%% A small number of variants by hand.
+\tex_def:D \cs_meaning:c { \exp_args:Nc \cs_meaning:N }
+\tex_def:D \token_to_str:c { \exp_args:Nc \token_to_str:N }
+\tex_def:D \cs_show:c { \exp_args:Nc \cs_show:N }
+\cs_set_eq:NwN \cs_set_nopar:Npn \tex_def:D
+\cs_set_eq:NwN \cs_set_nopar:Npx \tex_edef:D
+\pref_protected:D \cs_set_nopar:Npn \cs_set:Npn
+ { \pref_long:D \cs_set_nopar:Npn }
+\pref_protected:D \cs_set_nopar:Npn \cs_set:Npx
+ { \pref_long:D \cs_set_nopar:Npx }
+\pref_protected:D \cs_set_nopar:Npn \cs_set_protected_nopar:Npn
+ { \pref_protected:D \cs_set_nopar:Npn }
+\pref_protected:D \cs_set_nopar:Npn \cs_set_protected_nopar:Npx
+ { \pref_protected:D \cs_set_nopar:Npx }
+\cs_set_protected_nopar:Npn \cs_set_protected:Npn
+ { \pref_protected:D \pref_long:D \cs_set_nopar:Npn }
+\cs_set_protected_nopar:Npn \cs_set_protected:Npx
+ { \pref_protected:D \pref_long:D \cs_set_nopar:Npx }
+\cs_set_eq:NwN \cs_gset_nopar:Npn \tex_gdef:D
+\cs_set_eq:NwN \cs_gset_nopar:Npx \tex_xdef:D
+\cs_set_protected_nopar:Npn \cs_gset:Npn
+ { \pref_long:D \cs_gset_nopar:Npn }
+\cs_set_protected_nopar:Npn \cs_gset:Npx
+ { \pref_long:D \cs_gset_nopar:Npx }
+\cs_set_protected_nopar:Npn \cs_gset_protected_nopar:Npn
+ { \pref_protected:D \cs_gset_nopar:Npn }
+\cs_set_protected_nopar:Npn \cs_gset_protected_nopar:Npx
+ { \pref_protected:D \cs_gset_nopar:Npx }
+\cs_set_protected_nopar:Npn \cs_gset_protected:Npn
+ { \pref_protected:D \pref_long:D \cs_gset_nopar:Npn }
+\cs_set_protected_nopar:Npn \cs_gset_protected:Npx
+ { \pref_protected:D \pref_long:D \cs_gset_nopar:Npx }
+\cs_set:Npn \use:c #1 { \cs:w #1 \cs_end: }
+\cs_set_protected:Npn \use:x #1
+ {
+ \group_begin:
+ \cs_set:Npx \cs_tmp:w {#1}
+ \exp_after:wN
+ \group_end:
+ \cs_tmp:w
+ }
+\cs_set:Npn \cs_tmp:w { }
+\cs_set:Npn \use:n #1 {#1}
+\cs_set:Npn \use:nn #1#2 {#1#2}
+\cs_set:Npn \use:nnn #1#2#3 {#1#2#3}
+\cs_set:Npn \use:nnnn #1#2#3#4 {#1#2#3#4}
+\cs_set:Npn \use_i:nn #1#2 {#1}
+\cs_set:Npn \use_ii:nn #1#2 {#2}
+\cs_set:Npn \use_i:nnn #1#2#3 {#1}
+\cs_set:Npn \use_ii:nnn #1#2#3 {#2}
+\cs_set:Npn \use_iii:nnn #1#2#3 {#3}
+\cs_set:Npn \use_i_ii:nnn #1#2#3 {#1#2}
+\cs_set:Npn \use_i:nnnn #1#2#3#4 {#1}
+\cs_set:Npn \use_ii:nnnn #1#2#3#4 {#2}
+\cs_set:Npn \use_iii:nnnn #1#2#3#4 {#3}
+\cs_set:Npn \use_iv:nnnn #1#2#3#4 {#4}
+\cs_set:Npn \use_none_delimit_by_q_nil:w #1 \q_nil { }
+\cs_set:Npn \use_none_delimit_by_q_stop:w #1 \q_stop { }
+\cs_set:Npn \use_none_delimit_by_q_recursion_stop:w #1 \q_recursion_stop { }
+\cs_set:Npn \use_i_delimit_by_q_nil:nw #1#2 \q_nil {#1}
+\cs_set:Npn \use_i_delimit_by_q_stop:nw #1#2 \q_stop {#1}
+\cs_set:Npn \use_i_delimit_by_q_recursion_stop:nw #1#2 \q_recursion_stop {#1}
+\cs_set:Npn \use_i_after_fi:nw #1 \fi: { \fi: #1 }
+\cs_set:Npn \use_i_after_else:nw #1 \else: #2 \fi: { \fi: #1 }
+\cs_set:Npn \use_i_after_or:nw #1 \or: #2 \fi: { \fi: #1 }
+\cs_set:Npn \use_i_after_orelse:nw #1#2#3 \fi: { \fi: #1 }
+\cs_set:Npn \use_none:n #1 { }
+\cs_set:Npn \use_none:nn #1#2 { }
+\cs_set:Npn \use_none:nnn #1#2#3 { }
+\cs_set:Npn \use_none:nnnn #1#2#3#4 { }
+\cs_set:Npn \use_none:nnnnn #1#2#3#4#5 { }
+\cs_set:Npn \use_none:nnnnnn #1#2#3#4#5#6 { }
+\cs_set:Npn \use_none:nnnnnnn #1#2#3#4#5#6#7 { }
+\cs_set:Npn \use_none:nnnnnnnn #1#2#3#4#5#6#7#8 { }
+\cs_set:Npn \use_none:nnnnnnnnn #1#2#3#4#5#6#7#8#9 { }
+\cs_set_nopar:Npn \prg_return_true:
+ { \exp_after:wN \use_i:nn \int_to_roman:w }
+\cs_set_nopar:Npn \prg_return_false:
+ { \exp_after:wN \use_ii:nn \int_to_roman:w}
+\cs_set_protected:Npn \prg_set_conditional:Npnn #1
+ {
+ \prg_get_parm_aux:nw
+ {
+ \cs_split_function:NN #1 \prg_generate_conditional_aux:nnNNnnnn
+ \cs_set:Npn { parm }
+ }
+ }
+\cs_set_protected:Npn \prg_new_conditional:Npnn #1
+ {
+ \prg_get_parm_aux:nw
+ {
+ \cs_split_function:NN #1 \prg_generate_conditional_aux:nnNNnnnn
+ \cs_new:Npn { parm }
+ }
+ }
+\cs_set_protected:Npn \prg_set_protected_conditional:Npnn #1
+ {
+ \prg_get_parm_aux:nw{
+ \cs_split_function:NN #1 \prg_generate_conditional_aux:nnNNnnnn
+ \cs_set_protected:Npn { parm }
+ }
+ }
+\cs_set_protected:Npn \prg_new_protected_conditional:Npnn #1
+ {
+ \prg_get_parm_aux:nw
+ {
+ \cs_split_function:NN #1 \prg_generate_conditional_aux:nnNNnnnn
+ \cs_new_protected:Npn { parm }
+ }
+ }
+\cs_set_protected:Npn \prg_set_conditional:Nnn #1
+ {
+ \exp_args:Nnf \prg_get_count_aux:nn
+ {
+ \cs_split_function:NN #1 \prg_generate_conditional_aux:nnNNnnnn
+ \cs_set:Npn { count }
+ }
+ { \cs_get_arg_count_from_signature:N #1 }
+ }
+\cs_set_protected:Npn \prg_new_conditional:Nnn #1
+ {
+ \exp_args:Nnf \prg_get_count_aux:nn
+ {
+ \cs_split_function:NN #1 \prg_generate_conditional_aux:nnNNnnnn
+ \cs_new:Npn { count}
+ }
+ { \cs_get_arg_count_from_signature:N #1 }
+ }
+
+\cs_set_protected:Npn \prg_set_protected_conditional:Nnn #1{
+ \exp_args:Nnf \prg_get_count_aux:nn{
+ \cs_split_function:NN #1 \prg_generate_conditional_aux:nnNNnnnn
+ \cs_set_protected:Npn {count}
+ }{\cs_get_arg_count_from_signature:N #1}
+}
+
+\cs_set_protected:Npn \prg_new_protected_conditional:Nnn #1
+ {
+ \exp_args:Nnf \prg_get_count_aux:nn
+ {
+ \cs_split_function:NN #1 \prg_generate_conditional_aux:nnNNnnnn
+ \cs_new_protected:Npn {count}
+ }
+ { \cs_get_arg_count_from_signature:N #1 }
+ }
+\cs_set_protected:Npn \prg_set_eq_conditional:NNn #1#2#3
+ { \prg_set_eq_conditional_aux:NNNn \cs_set_eq:cc #1#2 {#3} }
+\cs_set_protected:Npn \prg_new_eq_conditional:NNn #1#2#3
+ { \prg_set_eq_conditional_aux:NNNn \cs_new_eq:cc #1#2 {#3} }
+\cs_set:Npn \prg_get_count_aux:nn #1#2 { #1 {#2} }
+\cs_set:Npn \prg_get_parm_aux:nw #1#2# { #1 {#2} }
+\cs_set_protected:Npn \prg_generate_conditional_aux:nnNNnnnn #1#2#3#4#5#6#7#8
+ {
+ \prg_generate_conditional_aux:nnw {#5}
+ {
+ #4 {#1} {#2} {#6} {#8}
+ }
+ #7 , ? , \q_recursion_stop
+ }
+\cs_set_protected:Npn \prg_generate_conditional_aux:nnw #1#2#3 ,
+ {
+ \if:w ?#3
+ \exp_after:wN \use_none_delimit_by_q_recursion_stop:w
+ \fi:
+ \use:c { prg_generate_#3_form_#1:Nnnnn } #2
+ \prg_generate_conditional_aux:nnw {#1} {#2}
+ }
+\cs_set_protected:Npn \prg_generate_p_form_parm:Nnnnn #1#2#3#4#5
+ {
+ \exp_args:Nc #1 { #2 _p: #3 } #4
+ {
+ #5 \c_zero
+ \c_true_bool \c_false_bool
+ }
+ }
+\cs_set_protected:Npn \prg_generate_T_form_parm:Nnnnn #1#2#3#4#5
+ {
+ \exp_args:Nc #1 { #2 : #3 T } #4
+ {
+ #5 \c_zero
+ \use:n \use_none:n
+ }
+ }
+\cs_set_protected:Npn \prg_generate_F_form_parm:Nnnnn #1#2#3#4#5
+ {
+ \exp_args:Nc #1 { #2 : #3 F } #4
+ {
+ #5 \c_zero
+ { }
+ }
+ }
+\cs_set_protected:Npn \prg_generate_TF_form_parm:Nnnnn #1#2#3#4#5
+ {
+ \exp_args:Nc #1 { #2 : #3 TF } #4
+ { #5 \c_zero }
+ }
+\cs_set_protected:Npn \prg_generate_p_form_count:Nnnnn #1#2#3#4#5
+ {
+ \cs_generate_from_arg_count:cNnn { #2 _p: #3 } #1 {#4}
+ {
+ #5 \c_zero
+ \c_true_bool \c_false_bool
+ }
+ }
+\cs_set_protected:Npn \prg_generate_T_form_count:Nnnnn #1#2#3#4#5
+ {
+ \cs_generate_from_arg_count:cNnn { #2 : #3 T } #1 {#4}
+ {
+ #5 \c_zero
+ \use:n \use_none:n
+ }
+ }
+\cs_set_protected:Npn \prg_generate_F_form_count:Nnnnn #1#2#3#4#5
+ {
+ \cs_generate_from_arg_count:cNnn { #2 : #3 F } #1 {#4}
+ {
+ #5 \c_zero
+ { }
+ }
+ }
+\cs_set_protected:Npn \prg_generate_TF_form_count:Nnnnn #1#2#3#4#5
+ {
+ \cs_generate_from_arg_count:cNnn { #2 : #3 TF } #1 {#4}
+ { #5 \c_zero }
+ }
+\cs_set_protected:Npn \prg_set_eq_conditional_aux:NNNn #1#2#3#4
+ { \prg_set_eq_conditional_aux:NNNw #1#2#3#4 , ? , \q_recursion_stop }
+\cs_set_protected:Npn \prg_set_eq_conditional_aux:NNNw #1#2#3#4 ,
+ {
+ \if:w ? #4 \scan_stop:
+ \exp_after:wN \use_none_delimit_by_q_recursion_stop:w
+ \fi:
+ #1
+ { \exp_args:NNc \cs_split_function:NN #2 { prg_conditional_form_#4:nnn } }
+ { \exp_args:NNc \cs_split_function:NN #3 { prg_conditional_form_#4:nnn } }
+ \prg_set_eq_conditional_aux:NNNw #1 {#2} {#3}
+ }
+\cs_set:Npn \prg_conditional_form_p:nnn #1#2#3 { #1 _p : #2 }
+\cs_set:Npn \prg_conditional_form_TF:nnn #1#2#3 { #1 : #2 TF }
+\cs_set:Npn \prg_conditional_form_T:nnn #1#2#3 { #1 : #2 T }
+\cs_set:Npn \prg_conditional_form_F:nnn #1#2#3 { #1 : #2 F }
+\tex_chardef:D \c_true_bool = 1~
+\tex_chardef:D \c_false_bool = 0~
+\cs_set_nopar:Npn \cs_to_str:N
+ {
+ \if:w \int_to_roman:w - `0 \token_to_str:N \ %
+ \cs_to_str_aux:w
+ \fi:
+ \exp_after:wN \use_none:n \token_to_str:N
+ }
+\cs_set_nopar:Npn \cs_to_str_aux:w #1 \use_none:n
+ { ~ \int_to_roman:w - `0 \fi: }
+\group_begin:
+ \tex_lccode:D `\@ = `\: \scan_stop:
+ \tex_catcode:D `\@ = 12~
+\tex_lowercase:D
+ {
+ \group_end:
+ \cs_set:Npn \cs_split_function:NN #1#2
+ {
+ \exp_after:wN \cs_split_function_aux:w
+ \int_to_roman:w - `\q \cs_to_str:N #1 @ a \q_stop #2
+ }
+ \cs_set:Npn \cs_split_function_aux:w #1 @ #2#3 \q_stop #4
+ {
+ \if_meaning:w a #2
+ \exp_after:wN \use_i:nn
+ \else:
+ \exp_after:wN\use_ii:nn
+ \fi:
+ { #4 {#1} { } \c_false_bool }
+ { \cs_split_function_auxii:w #2#3 \q_stop #4 {#1} }
+ }
+ \cs_set:Npn \cs_split_function_auxii:w #1 @a \q_stop #2#3
+ { #2{#3}{#1}\c_true_bool }
+ }
+\cs_set:Npn \cs_get_function_name:N #1
+ { \cs_split_function:NN #1 \use_i:nnn }
+\cs_set:Npn \cs_get_function_signature:N #1
+ { \cs_split_function:NN #1 \use_ii:nnn }
+\prg_set_conditional:Npnn \cs_if_exist:N #1 { p , T , F , TF }
+ {
+ \if_meaning:w #1 \scan_stop:
+ \prg_return_false:
+ \else:
+ \if_cs_exist:N #1
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ \fi:
+ }
+\prg_set_conditional:Npnn \cs_if_exist:c #1 { p , T , F , TF }
+ {
+ \if_cs_exist:w #1 \cs_end:
+ \exp_after:wN \use_i:nn
+ \else:
+ \exp_after:wN \use_ii:nn
+ \fi:
+ {
+ \exp_after:wN \if_meaning:w \cs:w #1 \cs_end: \scan_stop:
+ \prg_return_false:
+ \else:
+ \prg_return_true:
+ \fi:
+ }
+ \prg_return_false:
+ }
+\prg_set_conditional:Npnn \cs_if_free:N #1 { p , T , F , TF }
+ {
+ \if_meaning:w #1 \scan_stop:
+ \prg_return_true:
+ \else:
+ \if_cs_exist:N #1
+ \prg_return_false:
+ \else:
+ \prg_return_true:
+ \fi:
+ \fi:
+ }
+\prg_set_conditional:Npnn \cs_if_free:c #1 { p , T , F , TF }
+ {
+ \if_cs_exist:w #1 \cs_end:
+ \exp_after:wN \use_i:nn
+ \else:
+ \exp_after:wN \use_ii:nn
+ \fi:
+ {
+ \exp_after:wN \if_meaning:w \cs:w #1 \cs_end: \scan_stop:
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+ { \prg_return_true: }
+ }
+\cs_set_eq:NwN \c_minus_one \m@ne
+\tex_chardef:D \c_sixteen = 16~
+\tex_chardef:D \c_zero = 0~
+\tex_chardef:D \c_six = 6~
+\tex_chardef:D \c_seven = 7~
+\tex_chardef:D \c_twelve = 12~
+\tex_mathchardef:D \c_max_register_int = 32 767 \scan_stop:
+\cs_set_protected_nopar:Npn \iow_log:x
+ { \tex_immediate:D \tex_write:D \c_minus_one }
+\cs_set_protected_nopar:Npn \iow_term:x
+ { \tex_immediate:D \tex_write:D \c_sixteen }
+\cs_set_protected_nopar:Npn \msg_kernel_error:nnxx #1#2#3#4
+ {
+ \tex_errmessage:D
+ {
+ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!~! ^^J
+ Argh,~internal~LaTeX3~error! ^^J ^^J
+ Module ~ #1 , ~ message~name~"#2": ^^J
+ Arguments~'#3'~and~'#4' ^^J ^^J
+ This~is~one~for~The~LaTeX3~Project:~bailing~out
+ }
+ \tex_end:D
+ }
+\cs_set_protected_nopar:Npn \msg_kernel_error:nnx #1#2#3
+ { \msg_kernel_error:nnxx {#1} {#2} {#3} { } }
+\cs_set_protected_nopar:Npn \msg_kernel_error:nn #1#2
+ { \msg_kernel_error:nnxx {#1} {#2} { } { } }
+\cs_set_nopar:Npn \msg_line_context:
+ { on~line~\tex_the:D \tex_inputlineno:D }
+\cs_set:Npn \cs_record_meaning:N #1 { }
+\cs_set_protected_nopar:Npn \chk_if_free_cs:N #1
+ {
+ \cs_if_free:NF #1
+ {
+ \msg_kernel_error:nnxx { kernel } { command-already-defined }
+ { \token_to_str:N #1 } { \token_to_meaning:N #1 }
+ }
+}
+\tex_ifodd:D \@l@expl@log@functions@bool
+ \cs_set_protected_nopar:Npn \chk_if_free_cs:N #1
+ {
+ \cs_if_free:NF #1
+ {
+ \msg_kernel_error:nnxx { kernel } { command-already-defined }
+ { \token_to_str:N #1 } { \token_to_meaning:N #1 }
+ }
+ \iow_log:x { Defining~\token_to_str:N #1~ \msg_line_context: }
+ }
+\fi:
+\cs_set_protected_nopar:Npn \chk_if_free_cs:c
+ { \exp_args:Nc \chk_if_free_cs:N }
+\cs_set_protected_nopar:Npn \chk_if_exist_cs:N #1
+ {
+ \cs_if_exist:NF #1
+ {
+ \msg_kernel_error:nnxx { kernel } { command-not-defined }
+ { \token_to_str:N #1 } { \token_to_meaning:N #1 }
+ }
+ }
+\cs_set_protected_nopar:Npn \chk_if_exist_cs:c
+ { \exp_args:Nc \chk_if_exist_cs:N }
+\cs_set:Npn \cs_tmp:w #1#2
+ {
+ \cs_set_protected_nopar:Npn #1 ##1
+ {
+ \chk_if_free_cs:N ##1
+ #2 ##1
+ }
+ }
+\cs_tmp:w \cs_new_nopar:Npn \cs_gset_nopar:Npn
+\cs_tmp:w \cs_new_nopar:Npx \cs_gset_nopar:Npx
+\cs_tmp:w \cs_new:Npn \cs_gset:Npn
+\cs_tmp:w \cs_new:Npx \cs_gset:Npx
+\cs_tmp:w \cs_new_protected_nopar:Npn \cs_gset_protected_nopar:Npn
+\cs_tmp:w \cs_new_protected_nopar:Npx \cs_gset_protected_nopar:Npx
+\cs_tmp:w \cs_new_protected:Npn \cs_gset_protected:Npn
+\cs_tmp:w \cs_new_protected:Npx \cs_gset_protected:Npx
+\cs_set:Npn \cs_tmp:w #1#2
+ { \cs_new_protected_nopar:Npn #1 { \exp_args:Nc #2 } }
+\cs_tmp:w \cs_set_nopar:cpn \cs_set_nopar:Npn
+\cs_tmp:w \cs_set_nopar:cpx \cs_set_nopar:Npx
+\cs_tmp:w \cs_gset_nopar:cpn \cs_gset_nopar:Npn
+\cs_tmp:w \cs_gset_nopar:cpx \cs_gset_nopar:Npx
+\cs_tmp:w \cs_new_nopar:cpn \cs_new_nopar:Npn
+\cs_tmp:w \cs_new_nopar:cpx \cs_new_nopar:Npx
+\cs_tmp:w \cs_set:cpn \cs_set:Npn
+\cs_tmp:w \cs_set:cpx \cs_set:Npx
+\cs_tmp:w \cs_gset:cpn \cs_gset:Npn
+\cs_tmp:w \cs_gset:cpx \cs_gset:Npx
+\cs_tmp:w \cs_new:cpn \cs_new:Npn
+\cs_tmp:w \cs_new:cpx \cs_new:Npx
+\cs_tmp:w \cs_set_protected_nopar:cpn \cs_set_protected_nopar:Npn
+\cs_tmp:w \cs_set_protected_nopar:cpx \cs_set_protected_nopar:Npx
+\cs_tmp:w \cs_gset_protected_nopar:cpn \cs_gset_protected_nopar:Npn
+\cs_tmp:w \cs_gset_protected_nopar:cpx \cs_gset_protected_nopar:Npx
+\cs_tmp:w \cs_new_protected_nopar:cpn \cs_new_protected_nopar:Npn
+\cs_tmp:w \cs_new_protected_nopar:cpx \cs_new_protected_nopar:Npx
+\cs_tmp:w \cs_set_protected:cpn \cs_set_protected:Npn
+\cs_tmp:w \cs_set_protected:cpx \cs_set_protected:Npx
+\cs_tmp:w \cs_gset_protected:cpn \cs_gset_protected:Npn
+\cs_tmp:w \cs_gset_protected:cpx \cs_gset_protected:Npx
+\cs_tmp:w \cs_new_protected:cpn \cs_new_protected:Npn
+\cs_tmp:w \cs_new_protected:cpx \cs_new_protected:Npx
+\cs_new_nopar:cpn { use_0_parameter: } { }
+\cs_new_nopar:cpn { use_1_parameter: } { {##1} }
+\cs_new_nopar:cpn { use_2_parameter: } { {##1} {##2} }
+\cs_new_nopar:cpn { use_3_parameter: } { {##1} {##2} {##3} }
+\cs_new_nopar:cpn { use_4_parameter: } { {##1} {##2} {##3} {##4} }
+\cs_new_nopar:cpn { use_5_parameter: } { {##1} {##2} {##3} {##4} {##5} }
+\cs_new_nopar:cpn { use_6_parameter: } { {##1} {##2} {##3} {##4} {##5} {##6} }
+\cs_new_nopar:cpn { use_7_parameter: }
+ { {##1} {##2} {##3} {##4} {##5}{##6} {##7} }
+\cs_new_nopar:cpn { use_8_parameter: }
+ { {##1} {##2} {##3} {##4} {##5} {##6} {##7} {##8} }
+\cs_new_nopar:cpn{ use_9_parameter: }
+ { {##1} {##2} {##3} {##4} {##5} {##6} {##7} {##8} {##9} }
+\cs_new_protected:Npn \cs_set_eq:NN #1 { \cs_set_eq:NwN #1 =~ }
+\cs_new_protected_nopar:Npn \cs_set_eq:cN { \exp_args:Nc \cs_set_eq:NN }
+\cs_new_protected_nopar:Npn \cs_set_eq:Nc { \exp_args:NNc \cs_set_eq:NN }
+\cs_new_protected_nopar:Npn \cs_set_eq:cc { \exp_args:Ncc \cs_set_eq:NN }
+\cs_new_protected:Npn \cs_new_eq:NN #1
+ {
+ \chk_if_free_cs:N #1
+ \pref_global:D \cs_set_eq:NN #1
+ }
+\cs_new_protected_nopar:Npn \cs_new_eq:cN { \exp_args:Nc \cs_new_eq:NN }
+\cs_new_protected_nopar:Npn \cs_new_eq:Nc { \exp_args:NNc \cs_new_eq:NN }
+\cs_new_protected_nopar:Npn \cs_new_eq:cc { \exp_args:Ncc \cs_new_eq:NN }
+\cs_new_protected_nopar:Npn \cs_gset_eq:NN { \pref_global:D \cs_set_eq:NN }
+\cs_new_protected_nopar:Npn \cs_gset_eq:Nc { \exp_args:NNc \cs_gset_eq:NN }
+\cs_new_protected_nopar:Npn \cs_gset_eq:cN { \exp_args:Nc \cs_gset_eq:NN }
+\cs_new_protected_nopar:Npn \cs_gset_eq:cc { \exp_args:Ncc \cs_gset_eq:NN }
+\cs_new_protected_nopar:Npn \cs_undefine:N #1
+ { \cs_gset_eq:NN #1 \c_undefined:D }
+\cs_new_protected_nopar:Npn \cs_undefine:c #1
+ { \cs_gset_eq:cN {#1} \c_undefined:D }
+\cs_new:Npn \cs_get_arg_count_from_signature:N #1
+ { \cs_split_function:NN #1 \cs_get_arg_count_from_signature_aux:nnN }
+\cs_new:Npn \cs_get_arg_count_from_signature_aux:nnN #1#2#3
+ {
+ \if_predicate:w #3
+ \exp_after:wN \use_i:nn
+ \else:
+ \exp_after:wN\use_ii:nn
+ \fi:
+ {
+ \exp_after:wN \cs_get_arg_count_from_signature_auxii:w
+ \use_none:nnnnnnnnn #2 9876543210 \q_stop
+ }
+ { -1 }
+}
+\cs_new:Npn \cs_get_arg_count_from_signature_auxii:w #1#2 \q_stop {#1}
+\cs_new_nopar:Npn \cs_get_arg_count_from_signature:c
+ { \exp_args:Nc \cs_get_arg_count_from_signature:N }
+\cs_new_protected:Npn \cs_generate_from_arg_count:NNnn #1#2#3#4
+ {
+ \if_case:w \int_eval:w #3 \int_eval_end:
+ \use_i_after_orelse:nw {#2#1}
+ \or:
+ \use_i_after_orelse:nw {#2#1 ##1}
+ \or:
+ \use_i_after_orelse:nw {#2#1 ##1##2}
+ \or:
+ \use_i_after_orelse:nw {#2#1 ##1##2##3}
+ \or:
+ \use_i_after_orelse:nw {#2#1 ##1##2##3##4}
+ \or:
+ \use_i_after_orelse:nw {#2#1 ##1##2##3##4##5}
+ \or:
+ \use_i_after_orelse:nw {#2#1 ##1##2##3##4##5##6}
+ \or:
+ \use_i_after_orelse:nw {#2#1 ##1##2##3##4##5##6##7}
+ \or:
+ \use_i_after_orelse:nw {#2#1 ##1##2##3##4##5##6##7##8}
+ \or:
+ \use_i_after_orelse:nw {#2#1 ##1##2##3##4##5##6##7##8##9}
+ \else:
+ \use_i_after_fi:nw
+ {
+ \cs_generate_from_arg_count_error_msg:Nn #1 {#3}
+ \use_none:n
+ }
+ \fi:
+ {#4}
+ }
+\cs_new_nopar:Npn \cs_generate_from_arg_count:cNnn
+ { \exp_args:Nc \cs_generate_from_arg_count:NNnn }
+\cs_new:Npn \cs_generate_from_arg_count_error_msg:Nn #1#2
+ {
+ \msg_kernel_error:nnxx { kernel } { bad-number-of-arguments }
+ { \token_to_str:N #1 } { \int_eval:n {#2} }
+ }
+\cs_set:Npn \cs_tmp:w #1#2#3
+ {
+ \cs_set_protected:cpx { cs_ #1 : #2 } ##1##2
+ {
+ \exp_not:N \cs_generate_from_arg_count:NNnn ##1
+ \exp_after:wN \exp_not:N \cs:w cs_#1 : #3 \cs_end:
+ { \exp_not:N\cs_get_arg_count_from_signature:N ##1 }{##2}
+ }
+ }
+\cs_tmp:w { set } { Nn } { Npn }
+\cs_tmp:w { set } { Nx } { Npx }
+\cs_tmp:w { set_nopar } { Nn } { Npn }
+\cs_tmp:w { set_nopar } { Nx } { Npx }
+\cs_tmp:w { set_protected } { Nn } { Npn }
+\cs_tmp:w { set_protected } { Nx } { Npx }
+\cs_tmp:w { set_protected_nopar } { Nn } { Npn }
+\cs_tmp:w { set_protected_nopar } { Nx } { Npx }
+\cs_tmp:w { gset } { Nn } { Npn }
+\cs_tmp:w { gset } { Nx } { Npx }
+\cs_tmp:w { gset_nopar } { Nn } { Npn }
+\cs_tmp:w { gset_nopar } { Nx } { Npx }
+\cs_tmp:w { gset_protected } { Nn } { Npn }
+\cs_tmp:w { gset_protected } { Nx } { Npx }
+\cs_tmp:w { gset_protected_nopar } { Nn } { Npn }
+\cs_tmp:w { gset_protected_nopar } { Nx } { Npx }
+\cs_tmp:w { new } { Nn } { Npn }
+\cs_tmp:w { new } { Nx } { Npx }
+\cs_tmp:w { new_nopar } { Nn } { Npn }
+\cs_tmp:w { new_nopar } { Nx } { Npx }
+\cs_tmp:w { new_protected } { Nn } { Npn }
+\cs_tmp:w { new_protected } { Nx } { Npx }
+\cs_tmp:w { new_protected_nopar } { Nn } { Npn }
+\cs_tmp:w { new_protected_nopar } { Nx } { Npx }
+\cs_set:Npn \cs_tmp:w #1#2#3
+ {
+ \cs_set_protected:cpx {cs_#1:#2}##1##2{
+ \exp_not:N\cs_generate_from_arg_count:cNnn {##1}
+ \exp_after:wN \exp_not:N \cs:w cs_#1:#3 \cs_end:
+ { \exp_not:N \cs_get_arg_count_from_signature:c {##1} } {##2}
+ }
+ }
+\cs_tmp:w { set } { cn } { Npn }
+\cs_tmp:w { set } { cx } { Npx }
+\cs_tmp:w { set_nopar } { cn } { Npn }
+\cs_tmp:w { set_nopar } { cx } { Npx }
+\cs_tmp:w { set_protected } { cn } { Npn }
+\cs_tmp:w { set_protected } { cx } { Npx }
+\cs_tmp:w { set_protected_nopar } { cn } { Npn }
+\cs_tmp:w { set_protected_nopar } { cx } { Npx }
+\cs_tmp:w { gset } { cn } { Npn }
+\cs_tmp:w { gset } { cx } { Npx }
+\cs_tmp:w { gset_nopar } { cn } { Npn }
+\cs_tmp:w { gset_nopar } { cx } { Npx }
+\cs_tmp:w { gset_protected } { cn } { Npn }
+\cs_tmp:w { gset_protected } { cx } { Npx }
+\cs_tmp:w { gset_protected_nopar } { cn } { Npn }
+\cs_tmp:w { gset_protected_nopar } { cx } { Npx }
+\cs_tmp:w { new } { cn } { Npn }
+\cs_tmp:w { new } { cx } { Npx }
+\cs_tmp:w { new_nopar } { cn } { Npn }
+\cs_tmp:w { new_nopar } { cx } { Npx }
+\cs_tmp:w { new_protected } { cn } { Npn }
+\cs_tmp:w { new_protected } { cx } { Npx }
+\cs_tmp:w { new_protected_nopar } { cn } { Npn }
+\cs_tmp:w { new_protected_nopar } { cx } { Npx }
+\prg_new_conditional:Npnn \cs_if_eq:NN #1#2 { p , T , F , TF }
+ {
+ \if_meaning:w #1#2
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+\cs_new_nopar:Npn \cs_if_eq_p:cN { \exp_args:Nc \cs_if_eq_p:NN }
+\cs_new_nopar:Npn \cs_if_eq:cNTF { \exp_args:Nc \cs_if_eq:NNTF }
+\cs_new_nopar:Npn \cs_if_eq:cNT { \exp_args:Nc \cs_if_eq:NNT }
+\cs_new_nopar:Npn \cs_if_eq:cNF { \exp_args:Nc \cs_if_eq:NNF }
+\cs_new_nopar:Npn \cs_if_eq_p:Nc { \exp_args:NNc \cs_if_eq_p:NN }
+\cs_new_nopar:Npn \cs_if_eq:NcTF { \exp_args:NNc \cs_if_eq:NNTF }
+\cs_new_nopar:Npn \cs_if_eq:NcT { \exp_args:NNc \cs_if_eq:NNT }
+\cs_new_nopar:Npn \cs_if_eq:NcF { \exp_args:NNc \cs_if_eq:NNF }
+\cs_new_nopar:Npn \cs_if_eq_p:cc { \exp_args:Ncc \cs_if_eq_p:NN }
+\cs_new_nopar:Npn \cs_if_eq:ccTF { \exp_args:Ncc \cs_if_eq:NNTF }
+\cs_new_nopar:Npn \cs_if_eq:ccT { \exp_args:Ncc \cs_if_eq:NNT }
+\cs_new_nopar:Npn \cs_if_eq:ccF { \exp_args:Ncc \cs_if_eq:NNF }
+\cs_new_nopar:Npn \kernel_register_show:N #1
+ {
+ \cs_if_exist:NTF #1
+ { \tex_showthe:D #1 }
+ {
+ \msg_kernel_error:nnx { kernel } { variable-not-defined }
+ { \token_to_str:N #1 }
+ }
+ }
+\cs_new_nopar:Npn \kernel_register_show:c { \exp_args:Nc \int_show:N }
+\cs_new_eq:NN \luatex_if_engine:T \use_none:n
+\cs_new_eq:NN \luatex_if_engine:F \use:n
+\cs_new_eq:NN \luatex_if_engine:TF \use_ii:nn
+\cs_new_eq:NN \pdftex_if_engine:T \use:n
+\cs_new_eq:NN \pdftex_if_engine:F \use_none:n
+\cs_new_eq:NN \pdftex_if_engine:TF \use_i:nn
+\cs_new_eq:NN \xetex_if_engine:T \use_none:n
+\cs_new_eq:NN \xetex_if_engine:F \use:n
+\cs_new_eq:NN \xetex_if_engine:TF \use_ii:nn
+\cs_new_eq:NN \c_luatex_is_engine_bool \c_false_bool
+\cs_new_eq:NN \c_pdftex_is_engine_bool \c_true_bool
+\cs_new_eq:NN \c_xetex_is_engine_bool \c_false_bool
+\cs_if_exist:NT \xetex_XeTeXversion:D
+ {
+ \cs_set_eq:NN \pdftex_if_engine:T \use_none:n
+ \cs_set_eq:NN \pdftex_if_engine:F \use:n
+ \cs_set_eq:NN \pdftex_if_engine:TF \use_ii:nn
+ \cs_set_eq:NN \xetex_if_engine:T \use:n
+ \cs_set_eq:NN \xetex_if_engine:F \use_none:n
+ \cs_set_eq:NN \xetex_if_engine:TF \use_i:nn
+ \cs_set_eq:NN \c_pdftex_is_engine_bool \c_false_bool
+ \cs_set_eq:NN \c_xetex_is_engine_bool \c_true_bool
+ }
+\cs_if_exist:NT \luatex_directlua:D
+ {
+ \cs_set_eq:NN \luatex_if_engine:T \use:n
+ \cs_set_eq:NN \luatex_if_engine:F \use_none:n
+ \cs_set_eq:NN \luatex_if_engine:TF \use_i:nn
+ \cs_set_eq:NN \pdftex_if_engine:T \use_none:n
+ \cs_set_eq:NN \pdftex_if_engine:F \use:n
+ \cs_set_eq:NN \pdftex_if_engine:TF \use_ii:nn
+ \cs_set_eq:NN \c_luatex_is_engine_bool \c_true_bool
+ \cs_set_eq:NN \c_pdftex_is_engine_bool \c_false_bool
+ }
+\cs_new_nopar:Npn \prg_do_nothing: { }
+\prg_new_conditional:Npnn \str_if_eq:nn #1#2 { p , T , F , TF }
+ {
+ \if_int_compare:w \pdftex_strcmp:D { \exp_not:n {#1} } { \exp_not:n {#2} }
+ = \c_zero
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+\prg_new_conditional:Npnn \str_if_eq:xx #1#2 { p , T , F , TF }
+ {
+ \if_int_compare:w \pdftex_strcmp:D {#1} {#2} = \c_zero
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+\cs_new_eq:NN \cs_gnew_nopar:Npn \cs_new_nopar:Npn
+\cs_new_eq:NN \cs_gnew:Npn \cs_new:Npn
+\cs_new_eq:NN \cs_gnew_protected_nopar:Npn \cs_new_protected_nopar:Npn
+\cs_new_eq:NN \cs_gnew_protected:Npn \cs_new_protected:Npn
+\cs_new_eq:NN \cs_gnew_nopar:Npx \cs_new_nopar:Npx
+\cs_new_eq:NN \cs_gnew:Npx \cs_new:Npx
+\cs_new_eq:NN \cs_gnew_protected_nopar:Npx \cs_new_protected_nopar:Npx
+\cs_new_eq:NN \cs_gnew_protected:Npx \cs_new_protected:Npx
+\cs_new_eq:NN \cs_gnew_nopar:cpn \cs_new_nopar:cpn
+\cs_new_eq:NN \cs_gnew:cpn \cs_new:cpn
+\cs_new_eq:NN \cs_gnew_protected_nopar:cpn \cs_new_protected_nopar:cpn
+\cs_new_eq:NN \cs_gnew_protected:cpn \cs_new_protected:cpn
+\cs_new_eq:NN \cs_gnew_nopar:cpx \cs_new_nopar:cpx
+\cs_new_eq:NN \cs_gnew:cpx \cs_new:cpx
+\cs_new_eq:NN \cs_gnew_protected_nopar:cpx \cs_new_protected_nopar:cpx
+\cs_new_eq:NN \cs_gnew_protected:cpx \cs_new_protected:cpx
+\cs_new_eq:NN \cs_gnew_eq:NN \cs_new_eq:NN
+\cs_new_eq:NN \cs_gnew_eq:cN \cs_new_eq:cN
+\cs_new_eq:NN \cs_gnew_eq:Nc \cs_new_eq:Nc
+\cs_new_eq:NN \cs_gnew_eq:cc \cs_new_eq:cc
+\cs_new_eq:NN \cs_gundefine:N \cs_undefine:N
+\cs_new_eq:NN \cs_gundefine:c \cs_undefine:c
+\cs_new_eq:NN \group_execute_after:N \group_insert_after:N
+%%
+%%
+%% End of file `l3basics.sty'.
diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3bootstrap.sty b/Master/texmf-dist/tex/latex/l3kernel/l3bootstrap.sty
new file mode 100644
index 00000000000..54b4a0cf7c4
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/l3kernel/l3bootstrap.sty
@@ -0,0 +1,256 @@
+%%
+%% This is file `l3bootstrap.sty',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% l3bootstrap.dtx (with options: `package')
+%%
+%% EXPERIMENTAL CODE
+%%
+%% Do not distribute this file without also distributing the
+%% source files specified above.
+%%
+%% Do not distribute a modified version of this file.
+%%
+%% File: l3bootstrap.dtx Copyright (C) 2011 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 "expl3 bundle" (The Work in LPPL)
+%% and all files in that bundle must be distributed together.
+%%
+%% The released version of this bundle is available from CTAN.
+%%
+%% -----------------------------------------------------------------------
+%%
+%% The development version of the bundle can be found at
+%%
+%% http://www.latex-project.org/svnroot/experimental/trunk/
+%%
+%% for those people who are interested.
+%%
+%%%%%%%%%%%
+%% NOTE: %%
+%%%%%%%%%%%
+%%
+%% Snapshots taken from the repository represent work in progress and may
+%% not work or may contain conflicting material! We therefore ask
+%% people _not_ to put them into distributions, archives, etc. without
+%% prior consultation with the LaTeX3 Project.
+%%
+%% -----------------------------------------------------------------------
+\def\GetIdInfo$%
+ Id: #1 #2 #3-#4-#5 #6 #7 $#8%
+ {%
+ \def\ExplFileDate{#3/#4/#5}%
+ \def\ExplFileVersion{#2}%
+ }
+\GetIdInfo$Id: l3bootstrap.dtx 2478 2011-06-19 21:34:23Z joseph $
+ {L3 experimental bootstrap code}
+\ProvidesPackage{l3bootstrap}
+ [%
+ \ExplFileDate\space v\ExplFileVersion\space
+ L3 Experimental bootstrap code%
+ ]
+\def\@tempa%
+ {%
+ \def\@tempa{}%
+ \RequirePackage{luatex}%
+ \RequirePackage{pdftexcmds}%
+ \let\pdfstrcmp\pdf@strcmp
+ }
+\begingroup\expandafter\expandafter\expandafter\endgroup
+\expandafter\ifx\csname directlua\endcsname\relax
+\else
+ \expandafter\@tempa
+\fi
+\protected\edef\ExplSyntaxOff
+ {%
+ \catcode 9 = \the\catcode 9\relax
+ \catcode 32 = \the\catcode 32\relax
+ \catcode 34 = \the\catcode 34\relax
+ \catcode 38 = \the\catcode 38\relax
+ \catcode 58 = \the\catcode 58\relax
+ \catcode 94 = \the\catcode 94\relax
+ \catcode 95 = \the\catcode 95\relax
+ \catcode 124 = \the\catcode 124\relax
+ \catcode 126 = \the\catcode 126\relax
+ \endlinechar = \the\endlinechar\relax
+ \chardef\csname\detokenize{l_expl_status_bool}\endcsname = 0 \relax
+ }
+\protected\edef\ExplSyntaxOn
+ {
+ \catcode 9 = 9 \relax
+ \catcode 32 = 9 \relax
+ \catcode 34 = 12 \relax
+ \catcode 58 = 11 \relax
+ \catcode 94 = 7 \relax
+ \catcode 95 = 11 \relax
+ \catcode 124 = 12 \relax
+ \catcode 126 = 10 \relax
+ \endlinechar = 32 \relax
+ \chardef\csname\detokenize{l_expl_status_bool}\endcsname = 1 \relax
+ }
+\expandafter\chardef\csname\detokenize{l_expl_status_bool}\endcsname = 0 \relax
+\protected\def\GetIdInfo
+ {
+ \begingroup
+ \catcode 32 = 10 \relax
+ \GetIdInfoAuxI
+ }
+\protected\def\GetIdInfoAuxI$#1$#2%
+ {
+ \def\tempa{#1}%
+ \def\tempb{Id}%
+ \ifx\tempa\tempb
+ \def\tempa
+ {%
+ \endgroup
+ \def\ExplFileDate{0000/00/00}%
+ \def\ExplFileDescription{#2}%
+ \def\ExplFileName{[unknown~name]}%
+ \def\ExplFileVersion{000}%
+ }%
+ \else
+ \def\tempa
+ {%
+ \endgroup
+ \GetIdInfoAuxII$#1${#2}%
+ }%
+ \fi
+ \tempa
+ }
+\protected\def\GetIdInfoAuxII$#1 #2.#3 #4 #5 #6 #7 #8$#9%
+ {%
+ \def\ExplFileName{#2}%
+ \def\ExplFileVersion{#4}%
+ \def\ExplFileDescription{#9}%
+ \GetIdInfoAuxIII#5\relax#3\relax#5\relax#6\relax
+ }
+\protected\def\GetIdInfoAuxIII#1#2#3#4#5#6\relax
+ {%
+ \ifx#5/%
+ \expandafter\GetIdInfoAuxCVS
+ \else
+ \expandafter\GetIdInfoAuxSVN
+ \fi
+ }
+\protected\def\GetIdInfoAuxCVS#1,v\relax#2\relax#3\relax
+ {\def\ExplFileDate{#2}}
+\protected\def\GetIdInfoAuxSVN#1\relax#2-#3-#4\relax#5Z\relax
+ {\def\ExplFileDate{#2/#3/#4}}
+\protected\def\ProvidesExplPackage#1#2#3#4%
+ {%
+ \ProvidesPackage{#1}[#2 v#3 #4]%
+ \ExplSyntaxOn
+ }
+\protected\def\ProvidesExplClass#1#2#3#4%
+ {%
+ \ProvidesClass{#1}[#2 v#3 #4]%
+ \ExplSyntaxOn
+ }
+\protected\def\ProvidesExplFile#1#2#3#4%
+ {%
+ \ProvidesFile{#1}[#2 v#3 #4]%
+ \ExplSyntaxOn
+ }
+\edef\@pushfilename
+ {%
+ \edef\expandafter\noexpand
+ \csname\detokenize{l_expl_status_stack_tl}\endcsname
+ {%
+ \noexpand\ifodd\expandafter\noexpand
+ \csname\detokenize{l_expl_status_bool}\endcsname
+ 1%
+ \noexpand\else
+ 0%
+ \noexpand\fi
+ \expandafter\noexpand
+ \csname\detokenize{l_expl_status_stack_tl}\endcsname
+ }%
+ \ExplSyntaxOff
+ \unexpanded\expandafter{\@pushfilename}%
+ }
+\edef\@popfilename
+ {%
+ \unexpanded\expandafter{\@popfilename}%
+ \noexpand\if a\expandafter\noexpand\csname
+ \detokenize{l_expl_status_stack_tl}\endcsname a%
+ \ExplSyntaxOff
+ \noexpand\else
+ \noexpand\expandafter
+ \expandafter\noexpand\csname
+ \detokenize{expl_status_pop:w}\endcsname
+ \expandafter\noexpand\csname
+ \detokenize{l_expl_status_stack_tl}\endcsname
+ \noexpand\@nil
+ \noexpand\fi
+ }
+\@namedef{\detokenize{l_expl_status_stack_tl}}{0}
+\expandafter\edef\csname\detokenize{expl_status_pop:w}\endcsname#1#2\@nil
+ {%
+ \def\expandafter\noexpand
+ \csname\detokenize{l_expl_status_stack_tl}\endcsname{#2}%
+ \noexpand\ifodd#1\space
+ \noexpand\expandafter\noexpand\ExplSyntaxOn
+ \noexpand\else
+ \noexpand\expandafter\ExplSyntaxOff
+ \noexpand\fi
+ }
+\expandafter\protected\expandafter\def
+ \csname\detokenize{package_check_loaded_expl:}\endcsname
+ {%
+ \@ifpackageloaded{expl3}
+ {}
+ {%
+ \PackageError{expl3}
+ {Cannot load the expl3 modules separately}
+ {%
+ The expl3 modules cannot be loaded separately;\MessageBreak
+ please \string\usepackage\string{expl3\string} instead.
+ }%
+ }%
+ }
+\begingroup\expandafter\expandafter\expandafter\endgroup
+ \expandafter\ifx\csname pdfstrcmp\endcsname\relax
+ \let\pdfstrcmp\strcmp
+\fi
+\begingroup\expandafter\expandafter\expandafter\endgroup
+\expandafter\ifx\csname pdfstrcmp\endcsname\relax
+ \PackageError{l3names}{Required primitive not found: \protect\pdfstrcmp}
+ {%
+ LaTeX3 requires the e-TeX primitives and
+ \string\pdfstrcmp.\MessageBreak
+ These are available in engine versions: \MessageBreak
+ - pdfTeX 1.30 \MessageBreak
+ - XeTeX 0.9994 \MessageBreak
+ - LuaTeX 0.60 \MessageBreak
+ or later. \MessageBreak
+ \MessageBreak
+ Loading of expl3 will abort!
+ }
+ \expandafter\endinput
+\fi
+\protected\edef\ExplSyntaxNamesOn
+ {%
+ \expandafter\noexpand
+ \csname\detokenize{char_set_catcode_letter:n}\endcsname{58}%
+ \expandafter\noexpand
+ \csname\detokenize{char_set_catcode_letter:n}\endcsname{95}%
+ }
+\protected\edef\ExplSyntaxNamesOff
+ {%
+ \expandafter\noexpand
+ \csname\detokenize{char_set_catcode_math_subscript:n}\endcsname{58}%
+ \expandafter\noexpand
+ \csname\detokenize{char_set_catcode_other:n}\endcsname{95}%
+ }
+%%
+%%
+%% End of file `l3bootstrap.sty'.
diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3box.sty b/Master/texmf-dist/tex/latex/l3kernel/l3box.sty
new file mode 100644
index 00000000000..68db799fdf3
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/l3kernel/l3box.sty
@@ -0,0 +1,219 @@
+%%
+%% This is file `l3box.sty',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% l3box.dtx (with options: `package')
+%%
+%% EXPERIMENTAL CODE
+%%
+%% Do not distribute this file without also distributing the
+%% source files specified above.
+%%
+%% Do not distribute a modified version of this file.
+%%
+%% File: l3box.dtx Copyright (C) 2005-2011 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 "expl3 bundle" (The Work in LPPL)
+%% and all files in that bundle must be distributed together.
+%%
+%% The released version of this bundle is available from CTAN.
+%%
+%% -----------------------------------------------------------------------
+%%
+%% The development version of the bundle can be found at
+%%
+%% http://www.latex-project.org/svnroot/experimental/trunk/
+%%
+%% for those people who are interested.
+%%
+%%%%%%%%%%%
+%% NOTE: %%
+%%%%%%%%%%%
+%%
+%% Snapshots taken from the repository represent work in progress and may
+%% not work or may contain conflicting material! We therefore ask
+%% people _not_ to put them into distributions, archives, etc. without
+%% prior consultation with the LaTeX3 Project.
+%%
+%% -----------------------------------------------------------------------
+\RequirePackage{l3names}
+\GetIdInfo$Id: l3box.dtx 2478 2011-06-19 21:34:23Z joseph $
+ {L3 Experimental boxes}
+\ProvidesExplPackage
+ {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
+\package_check_loaded_expl:
+\cs_new_protected:Npn \box_new:N #1
+ {
+ \chk_if_free_cs:N #1
+ \newbox #1
+ }
+\cs_generate_variant:Nn \box_new:N { c }
+\cs_new_protected_nopar:Npn \box_clear:N #1
+ { \box_set_eq:NN #1 \c_empty_box }
+\cs_new_protected_nopar:Npn \box_gclear:N #1
+ { \box_gset_eq:NN #1 \c_empty_box }
+\cs_generate_variant:Nn \box_clear:N { c }
+\cs_generate_variant:Nn \box_gclear:N { c }
+\cs_new_protected_nopar:Npn \box_clear_new:N #1
+ {
+ \cs_if_exist:NTF #1
+ { \box_set_eq:NN #1 \c_empty_box }
+ { \box_new:N #1 }
+ }
+\cs_new_protected_nopar:Npn \box_gclear_new:N #1
+ {
+ \cs_if_exist:NTF #1
+ { \box_gset_eq:NN #1 \c_empty_box }
+ { \box_new:N #1 }
+ }
+\cs_generate_variant:Nn \box_clear_new:N { c }
+\cs_generate_variant:Nn \box_gclear_new:N { c }
+\cs_new_protected_nopar:Npn \box_set_eq:NN #1#2
+ { \tex_setbox:D #1 \tex_copy:D #2 }
+\cs_new_protected_nopar:Npn \box_gset_eq:NN
+ { \pref_global:D \box_set_eq:NN }
+\cs_generate_variant:Nn \box_set_eq:NN { cN , Nc , cc }
+\cs_generate_variant:Nn \box_gset_eq:NN { cN , Nc , cc }
+\cs_new_protected_nopar:Npn \box_set_eq_clear:NN #1#2
+ { \tex_setbox:D #1 \tex_box:D #2 }
+\cs_new_protected_nopar:Npn \box_gset_eq_clear:NN
+ { \pref_global:D \box_set_eq_clear:NN }
+\cs_generate_variant:Nn \box_set_eq_clear:NN { cN , Nc , cc }
+\cs_generate_variant:Nn \box_gset_eq_clear:NN { cN , Nc , cc }
+\cs_new_eq:NN \box_ht:N \tex_ht:D
+\cs_new_eq:NN \box_dp:N \tex_dp:D
+\cs_new_eq:NN \box_wd:N \tex_wd:D
+\cs_generate_variant:Nn \box_ht:N { c }
+\cs_generate_variant:Nn \box_dp:N { c }
+\cs_generate_variant:Nn \box_wd:N { c }
+\cs_new_protected_nopar:Npn \box_set_dp:Nn #1#2
+ { \box_dp:N #1 \dim_eval:w #2 \dim_eval_end: }
+\cs_new_protected_nopar:Npn \box_set_ht:Nn #1#2
+ { \box_ht:N #1 \dim_eval:w #2 \dim_eval_end: }
+\cs_new_protected_nopar:Npn \box_set_wd:Nn #1#2
+ { \box_wd:N #1 \dim_eval:w #2 \dim_eval_end: }
+\cs_generate_variant:Nn \box_set_ht:Nn { c }
+\cs_generate_variant:Nn \box_set_dp:Nn { c }
+\cs_generate_variant:Nn \box_set_wd:Nn { c }
+\cs_new_eq:NN \box_use_clear:N \tex_box:D
+\cs_new_eq:NN \box_use:N \tex_copy:D
+\cs_generate_variant:Nn \box_use_clear:N { c }
+\cs_generate_variant:Nn \box_use:N { c }
+\cs_new_protected:Npn \box_move_left:nn #1#2
+ { \tex_moveleft:D \dim_eval:w #1 \dim_eval_end: #2 }
+\cs_new_protected:Npn \box_move_right:nn #1#2
+ { \tex_moveright:D \dim_eval:w #1 \dim_eval_end: #2 }
+\cs_new_protected:Npn \box_move_up:nn #1#2
+ { \tex_raise:D \dim_eval:w #1 \dim_eval_end: #2 }
+\cs_new_protected:Npn \box_move_down:nn #1#2
+ { \tex_lower:D \dim_eval:w #1 \dim_eval_end: #2 }
+\cs_new_eq:NN \if_hbox:N \tex_ifhbox:D
+\cs_new_eq:NN \if_vbox:N \tex_ifvbox:D
+\cs_new_eq:NN \if_box_empty:N \tex_ifvoid:D
+\prg_new_conditional:Npnn \box_if_horizontal:N #1 { p , T , F , TF }
+ { \if_hbox:N #1 \prg_return_true: \else: \prg_return_false: \fi: }
+\prg_new_conditional:Npnn \box_if_vertical:N #1 { p , T , F , TF }
+ { \if_vbox:N #1 \prg_return_true: \else: \prg_return_false: \fi: }
+\cs_generate_variant:Nn \box_if_horizontal_p:N { c }
+\cs_generate_variant:Nn \box_if_horizontal:NT { c }
+\cs_generate_variant:Nn \box_if_horizontal:NF { c }
+\cs_generate_variant:Nn \box_if_horizontal:NTF { c }
+\cs_generate_variant:Nn \box_if_vertical_p:N { c }
+\cs_generate_variant:Nn \box_if_vertical:NT { c }
+\cs_generate_variant:Nn \box_if_vertical:NF { c }
+\cs_generate_variant:Nn \box_if_vertical:NTF { c }
+\prg_new_conditional:Npnn \box_if_empty:N #1 { p , T , F , TF }
+ { \if_box_empty:N #1 \prg_return_true: \else: \prg_return_false: \fi: }
+\cs_generate_variant:Nn \box_if_empty_p:N { c }
+\cs_generate_variant:Nn \box_if_empty:NT { c }
+\cs_generate_variant:Nn \box_if_empty:NF { c }
+\cs_generate_variant:Nn \box_if_empty:NTF { c }
+\cs_new_eq:NN \l_last_box \tex_lastbox:D
+\cs_new_protected_nopar:Npn \box_set_to_last:N #1
+ { \tex_setbox:D #1 \l_last_box }
+\cs_new_protected_nopar:Npn \box_gset_to_last:N
+ { \pref_global:D \box_set_to_last:N }
+\cs_generate_variant:Nn \box_set_to_last:N { c }
+\cs_generate_variant:Nn \box_gset_to_last:N { c }
+\cs_new_eq:NN \c_empty_box \voidb@x
+\cs_new_eq:NN \l_tmpa_box \@tempboxa
+\box_new:N \l_tmpb_box
+\cs_new_eq:NN \box_show:N \tex_showbox:D
+\cs_generate_variant:Nn \box_show:N { c }
+\cs_new_protected_nopar:Npn \hbox:n { \tex_hbox:D \scan_stop: }
+\cs_new_protected:Npn \hbox_set:Nn #1#2 { \tex_setbox:D #1 \tex_hbox:D {#2} }
+\cs_new_protected_nopar:Npn \hbox_gset:Nn { \pref_global:D \hbox_set:Nn }
+\cs_generate_variant:Nn \hbox_set:Nn { c }
+\cs_generate_variant:Nn \hbox_gset:Nn { c }
+\cs_new_protected:Npn \hbox_set_to_wd:Nnn #1#2#3
+ { \tex_setbox:D #1 \tex_hbox:D to \dim_eval:w #2 \dim_eval_end: {#3} }
+\cs_new_protected_nopar:Npn \hbox_gset_to_wd:Nnn
+ { \pref_global:D \hbox_set_to_wd:Nnn }
+\cs_generate_variant:Nn \hbox_set_to_wd:Nnn { c }
+\cs_generate_variant:Nn \hbox_gset_to_wd:Nnn {cnn}
+\cs_new_protected_nopar:Npn \hbox_set_inline_begin:N #1
+ { \tex_setbox:D #1 \tex_hbox:D \c_group_begin_token }
+\cs_new_protected_nopar:Npn \hbox_gset_inline_begin:N
+ { \pref_global:D \hbox_set_inline_begin:N }
+\cs_generate_variant:Nn \hbox_set_inline_begin:N { c }
+\cs_generate_variant:Nn \hbox_gset_inline_begin:N { c }
+\cs_new_eq:NN \hbox_set_inline_end: \c_group_end_token
+\cs_new_eq:NN \hbox_gset_inline_end: \c_group_end_token
+\cs_new_protected:Npn \hbox_to_wd:nn #1#2
+ { \tex_hbox:D to \dim_eval:w #1 \dim_eval_end: {#2} }
+\cs_new_protected:Npn \hbox_to_zero:n #1 { \tex_hbox:D to \c_zero_skip {#1} }
+\cs_new_protected:Npn \hbox_overlap_left:n #1
+ { \hbox_to_zero:n { \tex_hss:D #1 } }
+\cs_new_protected:Npn \hbox_overlap_right:n #1
+ { \hbox_to_zero:n { #1 \tex_hss:D } }
+\cs_new_eq:NN \hbox_unpack:N \tex_unhcopy:D
+\cs_new_eq:NN \hbox_unpack_clear:N \tex_unhbox:D
+\cs_generate_variant:Nn \hbox_unpack:N { c }
+\cs_generate_variant:Nn \hbox_unpack_clear:N { c }
+\cs_new_protected_nopar:Npn \vbox:n { \tex_vbox:D \scan_stop: }
+\cs_new_protected_nopar:Npn \vbox_top:n { \tex_vtop:D \scan_stop: }
+\cs_new_protected:Npn \vbox_to_ht:nn #1#2
+ { \tex_vbox:D to \dim_eval:w #1 \dim_eval_end: {#2} }
+\cs_new_protected:Npn \vbox_to_zero:n #1 { \tex_vbox:D to \c_zero_dim {#1} }
+\cs_new_protected:Npn \vbox_set:Nn #1#2 { \tex_setbox:D #1 \tex_vbox:D {#2} }
+\cs_new_protected_nopar:Npn \vbox_gset:Nn { \pref_global:D \vbox_set:Nn }
+\cs_generate_variant:Nn \vbox_set:Nn { c }
+\cs_generate_variant:Nn \vbox_gset:Nn { c }
+\cs_new_protected:Npn \vbox_set_top:Nn #1#2
+ { \tex_setbox:D #1 \tex_vtop:D {#2} }
+\cs_new_protected_nopar:Npn \vbox_gset_top:Nn
+ { \pref_global:D \vbox_set_top:Nn }
+\cs_generate_variant:Nn \vbox_set_top:Nn { c }
+\cs_generate_variant:Nn \vbox_gset_top:Nn { c }
+\cs_new_protected:Npn \vbox_set_to_ht:Nnn #1#2#3
+ { \tex_setbox:D #1 \tex_vbox:D to \dim_eval:w #2 \dim_eval_end: {#3} }
+\cs_new_protected_nopar:Npn \vbox_gset_to_ht:Nnn
+ { \pref_global:D \vbox_set_to_ht:Nnn }
+\cs_generate_variant:Nn \vbox_set_to_ht:Nnn { c }
+\cs_generate_variant:Nn \vbox_gset_to_ht:Nnn { c }
+\cs_new_nopar:Npn \vbox_set_inline_begin:N #1
+ { \tex_setbox:D #1 \tex_vbox:D \c_group_begin_token }
+\cs_new_protected_nopar:Npn \vbox_gset_inline_begin:N
+ { \pref_global:D \vbox_set_inline_begin:N }
+\cs_generate_variant:Nn \vbox_set_inline_begin:N { c }
+\cs_generate_variant:Nn \vbox_gset_inline_begin:N { c }
+\cs_new_eq:NN \vbox_set_inline_end: \c_group_end_token
+\cs_new_eq:NN \vbox_gset_inline_end: \c_group_end_token
+\cs_new_eq:NN \vbox_unpack:N \tex_unvcopy:D
+\cs_new_eq:NN \vbox_unpack_clear:N \tex_unvbox:D
+\cs_generate_variant:Nn \vbox_unpack:N { c }
+\cs_generate_variant:Nn \vbox_unpack_clear:N { c }
+\cs_new_protected_nopar:Npn \vbox_set_split_to_ht:NNn #1#2#3
+ { \tex_setbox:D #1 \tex_vsplit:D #2 to \dim_eval:w #3 \dim_eval_end: }
+%%
+%%
+%% End of file `l3box.sty'.
diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3clist.sty b/Master/texmf-dist/tex/latex/l3kernel/l3clist.sty
new file mode 100644
index 00000000000..ab92e649563
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/l3kernel/l3clist.sty
@@ -0,0 +1,426 @@
+%%
+%% This is file `l3clist.sty',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% l3clist.dtx (with options: `package')
+%%
+%% EXPERIMENTAL CODE
+%%
+%% Do not distribute this file without also distributing the
+%% source files specified above.
+%%
+%% Do not distribute a modified version of this file.
+%%
+%% File: l3clist.dtx Copyright (C) 2004-2011 Frank Mittelbach,
+%% 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 "expl3 bundle" (The Work in LPPL)
+%% and all files in that bundle must be distributed together.
+%%
+%% The released version of this bundle is available from CTAN.
+%%
+%% -----------------------------------------------------------------------
+%%
+%% The development version of the bundle can be found at
+%%
+%% http://www.latex-project.org/svnroot/experimental/trunk/
+%%
+%% for those people who are interested.
+%%
+%%%%%%%%%%%
+%% NOTE: %%
+%%%%%%%%%%%
+%%
+%% Snapshots taken from the repository represent work in progress and may
+%% not work or may contain conflicting material! We therefore ask
+%% people _not_ to put them into distributions, archives, etc. without
+%% prior consultation with the LaTeX3 Project.
+%%
+%% -----------------------------------------------------------------------
+\RequirePackage{l3names}
+\GetIdInfo$Id: l3clist.dtx 2498 2011-07-09 17:51:47Z joseph $
+ {L3 Experimental comma separated lists}
+\ProvidesExplPackage
+ {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
+\package_check_loaded_expl:
+\tl_new:N \l_clist_tmpa_tl
+\tl_new:N \l_clist_tmpb_tl
+\cs_new_eq:NN \clist_new:N \tl_new:N
+\cs_new_eq:NN \clist_new:c \tl_new:c
+\cs_new_eq:NN \clist_clear:N \tl_clear:N
+\cs_new_eq:NN \clist_clear:c \tl_clear:c
+\cs_new_eq:NN \clist_gclear:N \tl_gclear:N
+\cs_new_eq:NN \clist_gclear:c \tl_gclear:c
+\cs_new_eq:NN \clist_clear_new:N \tl_clear_new:N
+\cs_new_eq:NN \clist_clear_new:c \tl_clear_new:c
+\cs_new_eq:NN \clist_gclear_new:N \tl_gclear_new:N
+\cs_new_eq:NN \clist_gclear_new:c \tl_gclear_new:c
+\cs_new_eq:NN \clist_set_eq:NN \tl_set_eq:NN
+\cs_new_eq:NN \clist_set_eq:Nc \tl_set_eq:Nc
+\cs_new_eq:NN \clist_set_eq:cN \tl_set_eq:cN
+\cs_new_eq:NN \clist_set_eq:cc \tl_set_eq:cc
+\cs_new_eq:NN \clist_gset_eq:NN \tl_gset_eq:NN
+\cs_new_eq:NN \clist_gset_eq:Nc \tl_gset_eq:Nc
+\cs_new_eq:NN \clist_gset_eq:cN \tl_gset_eq:cN
+\cs_new_eq:NN \clist_gset_eq:cc \tl_gset_eq:cc
+\cs_new_protected_nopar:Npn \clist_concat:NNN
+ { \clist_concat_aux:NNNN \tl_set:Nx }
+\cs_new_protected_nopar:Npn \clist_gconcat:NNN
+ { \clist_concat_aux:NNNN \tl_gset:Nx }
+\cs_new_protected_nopar:Npn \clist_concat_aux:NNNN #1#2#3#4
+ {
+ #1 #2
+ {
+ \clist_if_empty:NTF #3
+ { \exp_not:o #4 }
+ {
+ \exp_not:o #3
+ \clist_if_empty:NF #4
+ {
+ ,
+ \exp_not:o #4
+ }
+ }
+ }
+ }
+\cs_generate_variant:Nn \clist_concat:NNN { ccc }
+\cs_generate_variant:Nn \clist_gconcat:NNN { ccc }
+\cs_new_protected_nopar:Npn \clist_put_left:Nn
+ { \clist_put_aux:NNnnNn \tl_set:Nn \tl_put_left:Nn { } , }
+\cs_new_protected_nopar:Npn \clist_gput_left:Nn
+ { \clist_put_aux:NNnnNn \tl_gset:Nn \tl_gput_left:Nn { } , }
+\cs_new_protected:Npn \clist_put_aux:NNnnNn #1#2#3#4#5#6
+ {
+ \clist_if_empty:NTF #5
+ { #1 #5 {#6} }
+ { \tl_if_empty:nF {#6} { #2 #5 { #3 #6 #4 } } }
+ }
+\cs_generate_variant:Nn \clist_put_left:Nn { NV , No , Nx }
+\cs_generate_variant:Nn \clist_put_left:Nn { c , cV , co , cx }
+\cs_generate_variant:Nn \clist_gput_left:Nn { NV , No , Nx }
+\cs_generate_variant:Nn \clist_gput_left:Nn { c , cV , co , cx }
+\cs_new_protected:Npn \clist_put_right:Nn
+ { \clist_put_aux:NNnnNn \tl_set:Nn \tl_put_right:Nn , { } }
+\cs_new_protected_nopar:Npn \clist_gput_right:Nn
+ { \clist_put_aux:NNnnNn \tl_gset:Nn \tl_gput_right:Nn , { } }
+\cs_generate_variant:Nn \clist_put_right:Nn { NV , No , Nx }
+\cs_generate_variant:Nn \clist_put_right:Nn { c , cV , co , cx }
+\cs_generate_variant:Nn \clist_gput_right:Nn { NV , No , Nx }
+\cs_generate_variant:Nn \clist_gput_right:Nn { c , cV , co , cx }
+\cs_new_protected_nopar:Npn \clist_get:NN #1#2
+ { \exp_after:wN \clist_get_aux:wN #1 , \q_stop #2 }
+\cs_new_protected:Npn \clist_get_aux:wN #1 , #2 \q_stop #3
+ { \tl_set:Nn #3 {#1} }
+\cs_generate_variant:Nn \clist_get:NN { c }
+\cs_new_protected_nopar:Npn \clist_pop:NN
+ { \clist_pop_aux:NNN \tl_set:Nn }
+\cs_new_protected_nopar:Npn \clist_gpop:NN
+ { \clist_pop_aux:NNN \tl_gset:Nn }
+\cs_new_protected_nopar:Npn \clist_pop_aux:NNN #1#2#3
+ { \exp_after:wN \clist_pop_aux:wNNN #2 , \q_nil , \q_nil , \q_stop #1#2#3 }
+\cs_new_protected:Npn \clist_pop_aux:wNNN #1 , #2 , \q_nil , #3 \q_stop #4#5#6
+ {
+ \quark_if_nil:nTF {#2}
+ { #4 #5 { } }
+ { #4 #5 {#2} }
+ \tl_set:Nn #6 {#1}
+ }
+\cs_generate_variant:Nn \clist_pop:NN { c }
+\cs_generate_variant:Nn \clist_gpop:NN { c }
+\cs_new_eq:NN \clist_push:Nn \clist_put_left:Nn
+\cs_new_eq:NN \clist_push:NV \clist_put_left:NV
+\cs_new_eq:NN \clist_push:No \clist_put_left:No
+\cs_new_eq:NN \clist_push:Nx \clist_put_left:Nx
+\cs_new_eq:NN \clist_push:cn \clist_put_left:cn
+\cs_new_eq:NN \clist_push:cV \clist_put_left:cV
+\cs_new_eq:NN \clist_push:co \clist_put_left:co
+\cs_new_eq:NN \clist_push:cx \clist_put_left:cx
+\cs_new_eq:NN \clist_gpush:Nn \clist_gput_left:Nn
+\cs_new_eq:NN \clist_gpush:NV \clist_gput_left:NV
+\cs_new_eq:NN \clist_gpush:No \clist_gput_left:No
+\cs_new_eq:NN \clist_gpush:Nx \clist_gput_left:Nx
+\cs_new_eq:NN \clist_gpush:cn \clist_gput_left:cn
+\cs_new_eq:NN \clist_gpush:cV \clist_gput_left:cV
+\cs_new_eq:NN \clist_gpush:co \clist_gput_left:co
+\cs_new_eq:NN \clist_gpush:cx \clist_gput_left:cx
+\cs_new_eq:NN \clist_use:N \tl_use:N
+\cs_new_eq:NN \clist_use:c \tl_use:c
+\clist_new:N \l_clist_remove_clist
+\cs_new_protected:Npn \clist_remove_duplicates:N
+ { \clist_remove_duplicates_aux:NN \clist_set_eq:NN }
+\cs_new_protected:Npn \clist_gremove_duplicates:N
+ { \clist_remove_duplicates_aux:NN \clist_gset_eq:NN }
+\cs_new_protected:Npn \clist_remove_duplicates_aux:NN #1#2
+ {
+ \clist_clear:N \l_clist_remove_clist
+ \clist_map_inline:Nn #2
+ {
+ \clist_if_in:NnF \l_clist_remove_clist {##1}
+ { \clist_put_right:Nn \l_clist_remove_clist {##1} }
+ }
+ #1 #2 \l_clist_remove_clist
+ }
+\cs_generate_variant:Nn \clist_remove_duplicates:N { c }
+\cs_generate_variant:Nn \clist_gremove_duplicates:N { c }
+\cs_new_protected:Npn \clist_remove_all:Nn
+ { \clist_remove_all_aux:NNn \clist_set_eq:NN }
+\cs_new_protected:Npn \clist_gremove_all:Nn
+ { \clist_remove_all_aux:NNn \clist_gset_eq:NN }
+\cs_new_protected:Npn \clist_remove_all_aux:NNn #1#2#3
+ {
+ \clist_if_empty:NF #2
+ {
+ \clist_clear:N \l_clist_remove_clist
+ \cs_set_protected:Npn \clist_remove_all_aux:w
+ ##1 , #3 , ##2 \q_stop
+ {
+ \tl_put_right:Nn \l_clist_remove_clist {##1}
+ \quark_if_no_value:nF {##2}
+ { \clist_remove_all_aux:w , ##2 \q_stop }
+ }
+ \exp_after:wN \clist_remove_all_aux:w
+ \exp_after:wN , #2 , #3 , \q_no_value \q_stop
+ \tl_if_empty:NF \l_clist_remove_clist
+ {
+ \exp_after:wN \tl_set:No \exp_after:wN
+ \l_clist_remove_clist \exp_after:wN
+ { \exp_after:wN \use_none:n \l_clist_remove_clist }
+ }
+ #1 #2 \l_clist_remove_clist
+ }
+ }
+\cs_new_protected:Npn \clist_remove_all_aux:w { }
+\cs_generate_variant:Nn \clist_remove_all:Nn { c }
+\cs_generate_variant:Nn \clist_gremove_all:Nn { c }
+\cs_new:Npn \clist_trim_spaces:n #1
+ {
+ \exp_args:Nf \clist_trim_spaces_aux_i:n
+ { \clist_map_function:nN {#1} \clist_trim_spaces_aux_ii:n }
+ }
+\cs_new:Npn \clist_trim_spaces_aux_i:n #1 { \use_ii:nn #1 }
+\cs_new:Npn \clist_trim_spaces_aux_ii:n #1
+ { , \tl_trim_spaces:n {#1} }
+\cs_new_protected:Npn \clist_trim_spaces:N #1
+ { \tl_set:Nf #1 { \exp_args:No \clist_trim_spaces:n #1 } }
+\cs_new_protected:Npn \clist_gtrim_spaces:N #1
+ { \tl_gset:Nf #1 { \exp_args:No \clist_trim_spaces:n #1 } }
+\cs_generate_variant:Nn \clist_trim_spaces:N { c }
+\cs_generate_variant:Nn \clist_gtrim_spaces:N { c }
+\cs_new_protected:Npn \clist_tmp:w { }
+\prg_new_eq_conditional:NNn \clist_if_empty:N \tl_if_empty:N { p , T , F , TF }
+\prg_new_eq_conditional:NNn \clist_if_empty:c \tl_if_empty:c { p , T , F , TF }
+\prg_new_eq_conditional:NNn \clist_if_eq:NN \tl_if_eq:NN { p , T , F , TF }
+\prg_new_eq_conditional:NNn \clist_if_eq:Nc \tl_if_eq:Nc { p , T , F , TF }
+\prg_new_eq_conditional:NNn \clist_if_eq:cN \tl_if_eq:cN { p , T , F , TF }
+\prg_new_eq_conditional:NNn \clist_if_eq:cc \tl_if_eq:cc { p , T , F , TF }
+\prg_new_protected_conditional:Npnn \clist_if_in:Nn #1#2
+ { T , F , TF }
+ {
+ \cs_set_protected:Npn \clist_tmp:w ##1 , #2 , ##2##3 \q_stop
+ {
+ \if_meaning:w \q_no_value ##2
+ \prg_return_false:
+ \else:
+ \prg_return_true:
+ \fi:
+ }
+ \exp_last_unbraced:NNo \clist_tmp:w , #1 , #2 , \q_no_value \q_stop
+ }
+\prg_new_protected_conditional:Npnn \clist_if_in:nn #1#2
+ { T , F , TF }
+ {
+ \cs_set_protected:Npn \clist_tmp:w ##1 , #2 , ##2##3 \q_stop
+ {
+ \if_meaning:w \q_no_value ##2
+ \prg_return_false:
+ \else:
+ \prg_return_true:
+ \fi:
+ }
+ \clist_tmp:w , #1 , #2 , \q_no_value \q_stop
+ }
+\cs_generate_variant:Nn \clist_if_in:NnT { NV , No }
+\cs_generate_variant:Nn \clist_if_in:NnT { c , cV , co }
+\cs_generate_variant:Nn \clist_if_in:NnF { NV , No }
+\cs_generate_variant:Nn \clist_if_in:NnF { c , cV , co }
+\cs_generate_variant:Nn \clist_if_in:NnTF { NV , No }
+\cs_generate_variant:Nn \clist_if_in:NnTF { c , cV , co }
+\cs_generate_variant:Nn \clist_if_in:nnT { nV , no }
+\cs_generate_variant:Nn \clist_if_in:nnF { nV , no }
+\cs_generate_variant:Nn \clist_if_in:nnTF { nV , no }
+\cs_new_nopar:Npn \clist_map_function:NN #1#2
+ {
+ \clist_if_empty:NF #1
+ {
+ \exp_last_unbraced:NNo \clist_map_function_aux:Nw #2 #1
+ , \q_recursion_tail , \q_recursion_stop
+ }
+ }
+\cs_new:Npn \clist_map_function:nN #1#2
+ {
+ \tl_if_empty:nF {#1}
+ {
+ \clist_map_function_aux:Nw #2 #1
+ , \q_recursion_tail , \q_recursion_stop
+ }
+ }
+\cs_new:Npn \clist_map_function_aux:Nw #1#2 ,
+ {
+ \quark_if_recursion_tail_stop:n {#2}
+ #1 {#2}
+ \clist_map_function_aux:Nw #1
+ }
+\cs_generate_variant:Nn \clist_map_function:NN { c }
+\int_new:N \g_clist_map_inline_int
+\cs_new_protected:Npn \clist_map_inline:Nn #1#2
+ {
+ \int_gincr:N \g_clist_map_inline_int
+ \cs_gset:cpn { clist_map_inline_ \int_use:N \g_clist_map_inline_int :n }
+ ##1
+ {#2}
+ \exp_args:NNc \clist_map_function:NN #1
+ { clist_map_inline_ \int_use:N \g_clist_map_inline_int :n }
+ \int_gdecr:N \g_clist_map_inline_int
+ }
+\cs_new_protected:Npn \clist_map_inline:nn #1#2
+ {
+ \int_gincr:N \g_clist_map_inline_int
+ \cs_gset:cpn { clist_map_inline_ \int_use:N \g_clist_map_inline_int :n }
+ ##1
+ {#2}
+ \exp_args:Nnc \clist_map_function:nN {#1}
+ { clist_map_inline_ \int_use:N \g_clist_map_inline_int :n }
+ \int_gdecr:N \g_clist_map_inline_int
+ }
+\cs_generate_variant:Nn \clist_map_inline:Nn { c }
+\cs_new_protected:Npn \clist_map_variable:NNn #1#2#3
+ {
+ \clist_map_inline:Nn #1
+ {
+ \tl_set:Nn #2 {##1}
+ #3
+ }
+ }
+\cs_new_protected:Npn \clist_map_variable:nNn #1#2#3
+ {
+ \clist_map_inline:nn {#1}
+ {
+ \tl_set:Nn #2 {##1}
+ #3
+ }
+ }
+\cs_generate_variant:Nn \clist_map_variable:NNn { c }
+\cs_new_eq:NN \clist_map_break: \use_none_delimit_by_q_recursion_stop:w
+\cs_new_eq:NN \clist_map_break:n \use_i_delimit_by_q_recursion_stop:nw
+\cs_new_protected_nopar:Npn \clist_show:N #1
+ {
+ \clist_if_empty:NTF #1
+ {
+ \iow_term:x { Comma~list~\token_to_str:N #1 \c_space_tl is~empty }
+ \tl_show:n { }
+ }
+ {
+ \iow_term:x
+ {
+ Comma~list~\token_to_str:N #1 \c_space_tl
+ contains~the~items~(without~outer~braces):
+ }
+ \tl_set:Nx \l_clist_show_tl
+ { \clist_map_function:NN #1 \clist_show_aux:n }
+ \etex_showtokens:D \exp_after:wN \exp_after:wN \exp_after:wN
+ { \exp_after:wN \clist_show_aux:w \l_clist_show_tl }
+ }
+ }
+\cs_new:Npn \clist_show_aux:n #1
+ {
+ \iow_newline: > \c_space_tl \c_space_tl
+ \iow_char:N \{ \exp_not:n {#1} \iow_char:N \}
+ }
+\cs_new:Npn \clist_show_aux:w #1 > ~ { }
+\cs_generate_variant:Nn \clist_show:N { c }
+\cs_new:Npn \clist_length:N #1
+ {
+ \int_eval:n
+ {
+ 0
+ \clist_map_function:NN #1 \clist_length_aux:n
+ }
+ }
+\cs_new:Npn \clist_length:n #1
+ {
+ \int_eval:n
+ {
+ 0
+ \clist_map_function:nN {#1} \clist_length_aux:n
+ }
+ }
+\cs_new:Npn \clist_length_aux:n #1 { +1 }
+\cs_generate_variant:Nn \clist_length:N { c }
+\cs_set_nopar:Npn \clist_item:Nn #1#2
+ { \exp_args:No \clist_item:nn #1 {#2} }
+\cs_set:Npn \clist_item:nn #1#2
+ {
+ \int_compare:nNnTF {#2} < \c_zero
+ {
+ \exp_args:Nf \clist_item_aux:nw
+ { \int_eval:n { \clist_length:n {#1} + #2 } }
+ #1 , \q_recursion_tail \q_recursion_stop
+ }
+ { \clist_item_aux:nw {#2} #1 , \q_recursion_tail \q_recursion_stop }
+ }
+\cs_set:Npn \clist_item_aux:nw #1#2 , #3
+ {
+ \int_compare:nNnTF {#1} = \c_zero
+ { \use_i_delimit_by_q_recursion_stop:nw {#2} }
+ {
+ \quark_if_recursion_tail_stop:n {#3}
+ \exp_args:Nf \clist_item_aux:nw
+ { \int_eval:n { #1 - 1 } }
+ #3
+ }
+ }
+\cs_generate_variant:Nn \clist_item:Nn { c }
+\cs_new_protected:Npn \clist_set_from_seq:NN #1#2
+ {
+ \seq_if_empty:NTF #2
+ { \clist_clear:N #1 }
+ {
+ \seq_push_item_def:n { , \exp_not:n {{##1}} }
+ \tl_set:Nx #1
+ { \exp_after:wN \use_none:n \tex_romannumeral:D -`\0 #2 }
+ \seq_pop_item_def:
+ }
+ }
+\cs_new_protected:Npn \clist_gset_from_seq:NN #1#2
+ {
+ \seq_if_empty:NTF #2
+ { \clist_gclear:N #1 }
+ {
+ \seq_push_item_def:n { , \exp_not:n {##1} }
+ \tl_gset:Nx #1
+ { \exp_after:wN \use_none:n \tex_romannumeral:D -`\0 #2 }
+ \seq_pop_item_def:
+ }
+ }
+\cs_generate_variant:Nn \clist_set_from_seq:NN { Nc }
+\cs_generate_variant:Nn \clist_set_from_seq:NN { c , cc }
+\cs_generate_variant:Nn \clist_gset_from_seq:NN { Nc }
+\cs_generate_variant:Nn \clist_gset_from_seq:NN { c , cc }
+\cs_new_eq:NN \clist_top:NN \clist_get:NN
+\cs_new_eq:NN \clist_top:cN \clist_get:cN
+\cs_new_eq:NN \clist_remove_element:Nn \clist_remove_all:Nn
+\cs_new_eq:NN \clist_gremove_element:Nn \clist_gremove_all:Nn
+\cs_new_eq:NN \clist_display:N \clist_show:N
+\cs_new_eq:NN \clist_display:c \clist_show:c
+%%
+%%
+%% End of file `l3clist.sty'.
diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3doc.cls b/Master/texmf-dist/tex/latex/l3kernel/l3doc.cls
new file mode 100644
index 00000000000..258a8475eb9
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/l3kernel/l3doc.cls
@@ -0,0 +1,1001 @@
+%%
+%% This is file `l3doc.cls',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% l3doc.dtx (with options: `class')
+%%
+%%
+%% EXPERIMENTAL CODE
+%%
+%% Do not distribute this file without also distributing the
+%% source files specified above.
+%%
+%% Do not distribute a modified version of this file.
+%%
+%%
+%% File: l3doc.dtx Copyright (C) 1990-2011 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 "expl3 bundle" (The Work in LPPL)
+%% and all files in that bundle must be distributed together.
+%%
+%% The released version of this bundle is available from CTAN.
+%%
+%% -----------------------------------------------------------------------
+%%
+%% The development version of the bundle can be found at
+%%
+%% http://www.latex-project.org/svnroot/experimental/trunk/
+%%
+%% for those people who are interested.
+%%
+%%%%%%%%%%%
+%% NOTE: %%
+%%%%%%%%%%%
+%%
+%% Snapshots taken from the repository represent work in progress and may
+%% not work or may contain conflicting material! We therefore ask
+%% people _not_ to put them into distributions, archives, etc. without
+%% prior consultation with the LaTeX3 Project.
+%%
+%% -----------------------------------------------------------------------
+\RequirePackage{l3names}
+\let \filenameOld \ExplFileName
+\let \filedateOld \ExplFileDate
+\let \fileversionOld \ExplFileVersion
+\let \filedescriptionOld \ExplFileDescription
+\GetIdInfo$Id: l3doc.dtx 2478 2011-06-19 21:34:23Z joseph $
+ {L3 Experimental documentation class}
+\ProvidesExplClass
+ {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
+\RequirePackage{expl3,xparse}
+\let \ExplFileName \filenameOld
+\let \ExplFileDate \filedateOld
+\let \ExplFileVersion \fileversionOld
+\let \ExplFileDescription \filedescriptionOld
+\cs_new_nopar:Npn\Team{%
+ The~\LaTeX3~Project\thanks{%
+ Frank~Mittelbach,~Denys~Duchier,~Chris~Rowley,~
+ Rainer~Sch\"opf,~Johannes~Braams,~Michael~Downes,~
+ David~Carlisle,~Alan~Jeffrey,~Morten~H\o{}gholm,~Thomas~Lotze,~
+ Javier~Bezos,~Will~Robertson,~Joseph~Wright}}
+\DeclareOption{a5paper}{\@latexerr{Option not supported}{}}
+\bool_new:N \g_doc_full_bool
+\bool_new:N \g_doc_lmodern_bool
+\bool_new:N \g_doc_checkfunc_bool
+\bool_new:N \g_doc_checktest_bool
+\DeclareOption{full}{ \bool_set_true:N \g_doc_full_bool }
+\DeclareOption{onlydoc}{ \bool_set_false:N \g_doc_full_bool }
+\DeclareOption{check}{ \bool_set_true:N \g_doc_checkfunc_bool }
+\DeclareOption{nocheck}{ \bool_set_false:N \g_doc_checkfunc_bool }
+\DeclareOption{checktest}{ \bool_set_true:N \g_doc_checktest_bool }
+\DeclareOption{nochecktest}{ \bool_set_false:N \g_doc_checktest_bool }
+\DeclareOption{cm-default}{ \bool_set_false:N \g_doc_lmodern_bool }
+\DeclareOption{lm-default}{ \bool_set_true:N \g_doc_lmodern_bool }
+\DeclareOption*{\PassOptionsToClass{\CurrentOption}{article}}
+\ExecuteOptions{full,a4paper,nocheck,nochecktest,lm-default}
+\InputIfFileExists{l3doc.cfg}
+ {
+ \typeout{*************************************^^J
+ *~Local~config~file~l3doc.cfg~used ^^J
+ *************************************}
+ }
+ { \@input{l3doc.ltx} }
+\ProcessOptions
+\LoadClass{article}
+\RequirePackage{doc}
+\RequirePackage{array,alphalph,booktabs,color,fixltx2e,enumitem,textcomp,trace,underscore,csquotes}
+\bool_if:NT \g_doc_lmodern_bool {
+ \RequirePackage[T1]{fontenc}
+ \RequirePackage{lmodern}
+}
+\RequirePackage{hypdoc}
+\let\doc@verbatim\verbatim
+\let\enddoc@verbatim\endverbatim
+\let\doc@@verbatim\@verbatim
+\expandafter\let\csname doc@verbatim*\expandafter\endcsname
+ \csname verbatim*\endcsname
+\expandafter\let\csname enddoc@verbatim*\expandafter\endcsname
+ \csname endverbatim*\endcsname
+\expandafter\let\csname doc@@verbatim*\expandafter\endcsname
+ \csname @verbatim*\endcsname
+\RequirePackage{verbatim}
+\AtBeginDocument{%
+ \let\verbatim\doc@verbatim
+ \let\endverbatim\enddoc@verbatim
+ \let\@verbatim\doc@@verbatim
+ \expandafter\let\csname verbatim*\expandafter\endcsname
+ \csname doc@verbatim*\endcsname
+ \expandafter\let\csname endverbatim*\expandafter\endcsname
+ \csname enddoc@verbatim*\endcsname
+ \expandafter\let\csname @verbatim*\expandafter\endcsname
+ \csname doc@@verbatim*\endcsname
+}
+\cs_set_nopar:Npn \MakePrivateLetters {
+ \char_set_catcode_letter:N \@
+ \char_set_catcode_letter:N \_
+ \char_set_catcode_letter:N \:
+}
+\setcounter{StandardModuleDepth}{1}
+\@addtoreset{CodelineNo}{part}
+\cs_set_nopar:Npn \theCodelineNo {
+ \textcolor[gray]{0.5}{ \sffamily\tiny\arabic{CodelineNo} }
+}
+\setlength \textwidth { 385pt }
+\addtolength \marginparwidth { 30pt }
+\addtolength \oddsidemargin { 20pt }
+\addtolength \evensidemargin { 20pt }
+\cs_set_eq:NN \@@oldlist\list
+\cs_set_nopar:Npn \list#1#2{\@@oldlist{#1}{#2\listparindent\z@}}
+\setlength \parindent { 0pt }
+\setlength \itemindent { 0pt }
+\setlength \parskip { \medskipamount }
+\AtBeginDocument {
+ \MakeShortVerb \"
+ \MakeShortVerb \|
+}
+\providecommand*\eTeX{
+ \if b\expandafter\@car\f@series\@nil\boldmath\fi
+ $\m@th\varepsilon$-\TeX
+}
+\providecommand*\IniTeX{Ini\TeX}
+\providecommand*\Lua{Lua}
+\providecommand*\LuaTeX{\Lua\TeX}
+\providecommand*\pdfTeX{pdf\TeX}
+\RequirePackage{graphicx}
+\cs_if_free:NT \XeTeX {
+ \cs_new_protected_nopar:Npn \XeTeX
+ {X\kern-.125em\lower.5ex\hbox{\reflectbox{E}}\kern-.1667em\TeX}
+}
+\cs_set_nopar:Npn \cmd #1 { \cs{\expandafter\cmd@to@cs\string#1} }
+\cs_set_nopar:Npn \cmd@to@cs #1#2 { \char\number`#2\relax }
+\DeclareRobustCommand \cs [1] { \texttt { \char`\\ #1 } }
+\providecommand\marg[1]{ \texttt{\char`\{} \meta{#1} \texttt{\char`\}} }
+\providecommand\oarg[1]{ \texttt[ \meta{#1} \texttt] }
+\providecommand\parg[1]{ \texttt( \meta{#1} \texttt) }
+\cs_set_eq:NN \m \meta
+\cs_set_eq:NN \file \nolinkurl
+\DeclareRobustCommand \env {\texttt}
+\DeclareRobustCommand \pkg {\textsf}
+\DeclareRobustCommand \cls {\textsf}
+\newenvironment{texnote}{
+ \endgraf
+ \vspace{3mm}
+ \small\textbf{\TeX~hackers~note:}
+}{
+ \vspace{3mm}
+}
+\newcommand\tn[1]{
+ \texttt{\bslash #1}
+ \index{TeX~and~LaTeX2e~commands\actualchar
+ \string\TeX{}~and~\string\LaTeXe{}~commands:\levelchar
+ #1\actualchar{\string\ttfamily\string\bslash{}#1}}}
+\cs_new:Npn \doc_implementation: {
+ \cs_set:Npn \variable {\macro[var]}
+}
+\cs_new:Npn \doc_docu: {
+ \cs_set_eq:NN \variable \variabledoc
+}
+\AtEndOfPackage{\doc_docu:}
+\newenvironment{documentation}{\doc_docu:}{}
+\newenvironment{implementation}{\doc_implementation:}{}
+\newcommand\EnableDocumentation{%
+ \renewenvironment{documentation}{\doc_docu:}{}%
+}
+\newcommand\EnableImplementation{%
+ \renewenvironment{implementation}{\doc_implementation:}{}%
+}
+\newcommand\DisableDocumentation{%
+ \cs_set_eq:NN \documentation \comment
+ \cs_set_eq:NN \enddocumentation \endcomment
+}
+\newcommand\DisableImplementation{%
+ \cs_set_eq:NN \implementation \comment
+ \cs_set_eq:NN \endimplementation \endcomment
+}
+\newenvironment{arguments}{
+ \enumerate[
+ nolistsep,
+ label=\texttt{\#\arabic*}~:,
+ labelsep=*,
+ ]
+}{
+ \endenumerate
+}
+\char_set_catcode_active:N \<
+\DeclareDocumentCommand \function { O{} } {
+
+ \phantomsection
+
+ \bool_gset_false:N \l_doc_meta_TF_bool
+ \bool_gset_false:N \l_doc_meta_pTF_bool
+ \bool_gset_false:N \l_doc_meta_EXP_bool
+
+ \cs_set_nopar:Npn \KV_key_no_value_elt:n ##1 { \use:c {doc_meta_opt_##1:} }
+ \keyval_parse:NNn \KV_key_no_value_elt:n \use_none:nn {#1}
+
+ \char_set_catcode_active:N \<
+ \cs_set_eq:NN < \doc_open_meta:n
+
+ \group_begin:
+ \MakePrivateLetters
+ \char_set_catcode_other:N \|
+ \char_set_catcode_other:N \\
+ \char_set_catcode_space:N \~
+ \char_set_catcode_ignore:N \ % space
+ \char_set_catcode_ignore:N \^^M
+ \char_set_catcode_ignore:N \^^I
+ \function_aux:n
+}
+\char_set_catcode_other:N \<
+\cs_set_eq:NN \variabledoc \function
+\cs_set:Nn \doc_meta_opt_TF: {
+ \bool_gset_true:N \l_doc_meta_TF_bool
+}
+\cs_set:Nn \doc_meta_opt_EXP: {
+ \bool_gset_true:N \l_doc_meta_EXP_bool
+}
+\cs_set:Nn \doc_meta_opt_pTF: {
+ \bool_gset_true:N \l_doc_meta_pTF_bool
+ \bool_gset_true:N \l_doc_meta_TF_bool
+ \bool_gset_true:N \l_doc_meta_EXP_bool
+}
+\group_begin:
+\char_set_catcode_other:N \|
+\cs_gset_nopar:Npn \function_aux:n #1 {
+ \cs_set_nopar:Npn \nextnewline{\cs_gset_nopar:Npn\nextnewline{\\}}
+ \tl_gset_eq:NN \g_doc_macro_tl \c_empty_tl
+ \bigskip\endgraf\noindent\ttfamily
+ \tabular[b]{ | l @{} c | }
+ \hline
+ \clist_map_inline:nn {#1} {\doc_showmacro:w ##1 | \q_stop} \\
+ \hline
+ \endtabular
+ \group_end:
+}
+\group_end:
+\group_begin:
+\char_set_catcode_other:N \|
+\cs_gset_nopar:Npn \doc_showmacro:w #1 | {
+ \tl_if_blank:nTF {#1} {
+ \use_none:n
+ }{
+ \doc_showmacro_aux:w #1 / \q_stop
+ \peek_meaning:NTF \q_stop { \use_none:n } { \doc_showmacro:w }
+ }
+}
+\group_end:
+\bool_new:N \l_doc_meta_TF_bool
+\bool_new:N \l_doc_meta_pTF_bool
+\bool_new:N \l_doc_meta_EXP_bool
+\cs_new_nopar:Npn \doc_showmacro_aux:w #1 / #2 \q_stop {
+
+ \tl_if_in:nnT {#2} { (TF) } {
+ \bool_gset_true:N \l_doc_meta_TF_bool
+ }
+
+ \tl_if_in:nnT {#2} { (EXP) } {
+ \bool_gset_true:N \l_doc_meta_EXP_bool
+ }
+
+ \tl_if_in:nnT {#2} { (pTF) } {
+ \bool_gset_true:N \l_doc_meta_TF_bool
+ \bool_gset_true:N \l_doc_meta_pTF_bool
+ \bool_gset_true:N \l_doc_meta_EXP_bool
+ }
+
+ \bool_if:NT \l_doc_meta_pTF_bool {
+ \tl_set:Nx \l_doc_pTF_name_tl { \doc_predicate_from_base:w #1 \q_nil }
+ \doc_special_main_index:o { \l_doc_pTF_name_tl }
+ \seq_gput_right:Nx \g_doc_functions_seq { \tl_to_str:N \l_doc_pTF_name_tl }
+ }
+
+ \bool_if:NTF \l_doc_meta_TF_bool {
+ \doc_special_main_index:o { #1 TF }
+ \seq_gput_right:Nx \g_doc_functions_seq { \tl_to_str:n { #1 TF } }
+ \seq_gput_right:Nx \g_doc_functions_seq { \tl_to_str:n { #1 T } }
+ \seq_gput_right:Nx \g_doc_functions_seq { \tl_to_str:n { #1 F } }
+ }{
+ \doc_special_main_index:o { #1 }
+ \seq_gput_right:Nx \g_doc_functions_seq { \tl_to_str:n { #1 } }
+ }
+
+ \bool_if:NTF \l_doc_meta_pTF_bool {
+ \bool_gset_false:N \l_doc_meta_TF_bool
+ \exp_after:wN \doc_showmacro_aux_ii:w \l_doc_pTF_name_tl ::\q_stop
+ \bool_gset_true:N \l_doc_meta_TF_bool
+ \doc_showmacro_aux_ii:w #1::\q_stop
+ }{
+ \doc_showmacro_aux_ii:w #1::\q_stop
+ }
+}
+\cs_set_nopar:Npn \doc_showmacro_aux_ii:w #1:#2:#3 \q_stop {
+ \nextnewline
+ \str_if_eq:xxTF {#1} {\g_doc_macro_tl} {
+ \doc_typeset_aux:n
+ }{
+ \tl_gset:Nn \g_doc_macro_tl {#1}
+ \use:n
+ }
+ { \g_doc_macro_tl }
+ #3
+ #2
+ \bool_if:NT \l_doc_meta_TF_bool { \doc_typeset_TF: }
+ &
+ \bool_if:NT \l_doc_meta_EXP_bool {
+ \hspace{\tabcolsep}
+ $\star$
+ }
+ \tl_set:Nx \g_doc_macro_tl { \tl_to_str:N \g_doc_macro_tl }
+ \exp_args:NNf \tl_replace_all_in:Nnn \g_doc_macro_tl {\token_to_str:N _} {/}
+ \exp_args:NNf \tl_replace_all_in:Nnn \g_doc_macro_tl {\@backslashchar} {}
+ \bool_if:NT \g_doc_full_bool {
+ \exp_args:Nf\label{doc/function/\g_doc_macro_tl#3#2}
+ }
+}
+\dim_new:N \g_doc_syntax_dim
+\dim_set:Nn \g_doc_syntax_dim {0.7\textwidth}
+\newenvironment{syntax}{
+ \minipage[b]{\g_doc_syntax_dim}
+ \cs_set_nopar:Npn \meta@font@select{\rmfamily\itshape} % (Will: I HATE italic cmtt!)
+ \small\ttfamily\raggedright
+ \obeyspaces\obeylines
+}{
+ \endminipage
+ \hfil\break
+ \global\@ignoretrue
+}
+\tl_map_inline:nn {0123456789} { \cs_gset_eq:cN {char_other_#1} #1 }
+\group_begin:
+ \tl_map_inline:nn {0123456789} { \char_set_catcode_active:N #1 }
+ \cs_new:Npn \doc_open_meta:n {
+ \group_begin:
+ \tl_map_function:nN {0123456789} \doc_assign_num:n
+ \doc_close_meta:w
+ }
+ \cs_new:Npn \Arg {
+ \texttt{ \char`\{ }
+ \group_begin:
+ \tl_map_function:nN {0123456789} \doc_assign_num:n
+ \doc_close_Arg:n
+ }
+\group_end:
+\cs_new_nopar:Npn \doc_close_meta:w #1> { \meta {#1} \group_end: }
+\cs_new_nopar:Npn \doc_close_Arg:n #1 {
+ \meta {#1}
+ \group_end:
+ \texttt{ \char`\} }
+}
+\cs_new_nopar:Npn \doc_assign_num:n #1 {
+ \cs_set_eq:cc { \string #1 } { char_other_\string #1 }
+ \char_set_catcode_active:N #1
+ \cs_set_nopar:Npn #1 { \unskip \, $ {} \sb { \use:c { char_other_\string #1 } } $ }
+}
+\renewcommand \macro [1][] {
+
+ \int_compare:nNnTF \currentgrouplevel=2
+ { \int_gzero:N \g_doc_nested_macro_int }
+ { \int_incr:N \g_doc_nested_macro_int }
+
+ \bool_set_false:N \l_doc_macro_aux_bool
+ \bool_set_false:N \l_doc_macro_internal_bool
+ \bool_set_false:N \l_doc_macro_TF_bool
+ \bool_set_false:N \l_doc_macro_pTF_bool
+ \bool_set_false:N \l_doc_macro_var_bool
+ \bool_set_false:N \l_doc_tested_bool
+
+ \cs_set_eq:NN \doc_macroname_prefix:n \use:n
+ \cs_set_eq:NN \doc_macroname_suffix: \c_empty_tl
+
+ \cs_set_nopar:Npn \KV_key_no_value_elt:n ##1 { \use:c {doc_macro_opt_##1:} }
+ \keyval_parse:NNn \KV_key_no_value_elt:n \use_none:nn {#1}
+
+ \cs_set_eq:NN \testfile \doc_print_testfile:n
+
+ \group_begin:
+ \MakePrivateLetters
+ \char_set_catcode_letter:N \\
+ \char_set_catcode_ignore:N \ % space
+ \char_set_catcode_ignore:N \^^M
+ \char_set_catcode_ignore:N \^^I
+ \doc_macro_aux:n
+}
+\cs_new_nopar:Npn \doc_macro_aux:n #1 {
+ \group_end:
+ \cs_set:Npn \l_doc_macro_input_clist {#1}
+ \bool_if:NTF \l_doc_macro_pTF_bool
+ {
+ \clist_map_inline:nn {#1}
+ {
+ \tl_if_blank:nF {##1}
+ {
+ \exp_args:Nf \doc_macro_single
+ { \doc_predicate_from_base:w ##1 \q_nil }
+ }
+ }
+ \bool_set_true:N \l_doc_macro_TF_bool
+ \clist_map_inline:nn {#1}
+ { \tl_if_blank:nF {##1} { \doc_macro_single {##1} } }
+ \bool_set_false:N \l_doc_macro_TF_bool
+ }
+ {
+ \clist_map_inline:nn {#1}
+ { \tl_if_blank:nF {##1} { \doc_macro_single {##1} } }
+ }
+}
+\bool_new:N \l_doc_macro_internal_bool
+\bool_new:N \l_doc_macro_aux_bool
+\bool_new:N \l_doc_macro_TF_bool
+\bool_new:N \l_doc_macro_pTF_bool
+\bool_new:N \l_doc_macro_var_bool
+\cs_set_nopar:Npn \doc_macro_opt_aux: { \bool_set_true:N \l_doc_macro_aux_bool }
+\cs_set_nopar:Npn \doc_macro_opt_internal: { \bool_set_true:N \l_doc_macro_internal_bool }
+\cs_set_nopar:Npn \doc_macro_opt_TF: { \bool_set_true:N \l_doc_macro_TF_bool }
+\cs_set_nopar:Npn \doc_macro_opt_pTF: { \bool_set_true:N \l_doc_macro_pTF_bool }
+\cs_set_nopar:Npn \doc_macro_opt_var: { \bool_set_true:N \l_doc_macro_var_bool }
+\cs_set:Npn \doc_predicate_from_base:w #1:#2 \q_nil {#1_p:#2}
+\int_new:N \l_doc_macro_int
+\cs_set_nopar:Npn \doc_macro_single #1 {
+ \int_incr:N \l_doc_macro_int
+ \tl_set:Nx \saved@macroname { \token_to_str:N #1 }
+ \topsep\MacroTopsep
+ \trivlist
+ \cs_set_nopar:Npn \makelabel ##1 { \llap{##1} }
+ \if@inlabel
+ \cs_set_eq:NN \@tempa \@empty
+ \count@ \macro@cnt
+ \loop \ifnum\count@>\z@
+ \cs_set_nopar:Npx \@tempa{\@tempa\hbox{\strut}}
+ \advance\count@\m@ne
+ \repeat
+ \cs_set_nopar:Npx \makelabel ##1 {
+ \llap{\vtop to\baselineskip {\@tempa\hbox{##1}\vss}}
+ }
+ \advance \macro@cnt \@ne
+ \else
+ \macro@cnt \@ne
+ \fi
+
+ \bool_if:NT \l_doc_macro_aux_bool {
+ \cs_set_eq:NN \doc_macroname_prefix:n \doc_typeset_aux:n
+ }
+ \bool_if:NT \l_doc_macro_TF_bool {
+ \cs_set_eq:NN \doc_macroname_suffix: \doc_typeset_TF:
+ }
+
+ \bool_if:NF \l_doc_macro_aux_bool {
+ \tl_gset:Nx \l_doc_macro_tl { \tl_to_str:n {#1} }
+ \exp_args:NNf \tl_greplace_all_in:Nnn \l_doc_macro_tl {\token_to_str:N _} {/}
+ \exp_args:NNf \tl_greplace_all_in:Nnn \l_doc_macro_tl {\@backslashchar} {}
+ }
+
+ \use:x {
+ \exp_not:N \item [ \exp_not:N \doc_print_macroname:n {
+ \tl_to_str:n {#1}
+ }]
+ }
+ \global\advance \c@CodelineNo \@ne
+
+ \bool_if:NF \l_doc_macro_aux_bool {
+ \bool_if:NTF \l_doc_macro_TF_bool {
+ \seq_gput_right:Nx \g_doc_macros_seq { \tl_to_str:n { #1 TF } }
+ \seq_gput_right:Nx \g_doc_macros_seq { \tl_to_str:n { #1 T } }
+ \seq_gput_right:Nx \g_doc_macros_seq { \tl_to_str:n { #1 F } }
+ }{
+ \seq_gput_right:Nx \g_doc_macros_seq { \tl_to_str:n {#1} }
+ }
+ }
+ \bool_if:NTF \l_doc_macro_TF_bool {
+ \SpecialMainIndex{#1 TF}\nobreak
+ \DoNotIndex{#1 TF}
+ }{
+ \SpecialMainIndex{#1}\nobreak
+ \DoNotIndex{#1}
+ }
+
+ \global\advance \c@CodelineNo \m@ne
+ \ignorespaces
+}
+\tl_clear:N \l_doc_macro_tl
+\cs_set_nopar:Npn \doc_print_macroname:n #1 {
+ \strut
+ \int_compare:nTF { \tl_elt_count:n {#1} <= 28 }
+ { \MacroFont } { \MacroLongFont }
+
+ % INEFFICIENT: (!)
+ \exp_args:NNx \seq_if_in:NnTF \g_doc_functions_seq
+ { #1 \bool_if:NT \l_doc_macro_TF_bool { \tl_to_str:n {TF} } }
+ {
+ \hyperref [doc/function/\l_doc_macro_tl]
+ }
+ { \use:n }
+ {
+ \doc_macroname_prefix:n {#1} \doc_macroname_suffix: \ % space!
+ }
+}
+\providecommand \MacroLongFont {
+ \fontfamily{lmtt}\fontseries{lc}\small
+}
+\cs_set_nopar:Npn \doc_typeset_TF: {
+ \itshape TF%
+ \makebox[0pt][r]{%
+ \color[gray]{0.5}
+ \underline { \phantom{\itshape TF} \kern-0.1em }
+ }
+}
+\cs_set_nopar:Npn \doc_typeset_aux:n #1 {
+ {\color[gray]{0.5} #1}
+}
+\DeclareDocumentCommand \doc_print_testfile:n {m} {
+ \bool_set_true:N \l_doc_tested_bool
+ \tl_if_eq:nnF {#1} {*} {
+ \seq_if_in:NnF \g_doc_testfiles_seq {#1}
+ {
+ \par{\footnotesize(\textit{
+ The~ test~ suite~ for~ this~ command,~ and~ others~ in~ this~ file,~ is~ \textsf{#1}}.
+ )\par}
+ \seq_gput_right:Nn \g_doc_testfiles_seq {#1}
+ }
+ }
+}
+\seq_new:N \g_doc_testfiles_seq
+\DeclareDocumentCommand \TestFiles {m} {
+ \par
+ {\itshape
+ The~ following~ test~ files~ are~ used~ for~ this~ code:~ \textsf{#1}.
+ }
+ \par\ignorespaces
+}
+\DeclareDocumentCommand \UnitTested {} {
+ \testfile*
+}
+\cs_generate_variant:Nn \prop_gput:Nnn {NVx}
+\prop_new:N \g_doc_missing_tests_prop
+\DeclareDocumentCommand \TestMissing {m} {
+ \prop_if_in:NVTF \g_doc_missing_tests_prop \l_doc_macro_input_clist
+ {
+ \prop_get:NVN \g_doc_missing_tests_prop \l_doc_macro_input_clist \l_tmpa_tl
+ \prop_gput:NVx \g_doc_missing_tests_prop \l_doc_macro_input_clist
+ {
+ *~ \l_tmpa_tl
+ ^^J \exp_not:n {\space\space\space\space\space\space}
+ *~ #1
+ }
+ }
+ { \prop_gput:NVn \g_doc_missing_tests_prop \l_doc_macro_input_clist {#1} }
+}
+\int_new:N \g_doc_nested_macro_int
+\cs_set:Nn \doc_texttt_comma:n {\,,~\texttt{#1}}
+\cs_set:Npn \endmacro {
+ \int_compare:nT {\g_doc_nested_macro_int<1}
+ {
+ \par\nobreak{\footnotesize(\emph{
+ End~ definition~ for~
+ \prg_case_int:nnn { \clist_length:N \l_doc_macro_input_clist }
+ {
+ {1} { \texttt{ \clist_use:N \l_doc_macro_input_clist }. }
+ {2}
+ {
+ \tl_set:Nx \l_clist_first_tl { \clist_item:Nn \l_doc_macro_input_clist {0} }
+ \tl_set:Nx \l_clist_last_tl { \clist_item:Nn \l_doc_macro_input_clist {1} }
+ \texttt{\l_clist_first_tl}\,~ and~ \texttt{\l_clist_last_tl}\,.
+ }
+ {3}
+ {
+ \tl_set:Nx \l_clist_first_tl { \clist_item:Nn \l_doc_macro_input_clist {0} }
+ \tl_set:Nx \l_clist_mid_tl { \clist_item:Nn \l_doc_macro_input_clist {1} }
+ \tl_set:Nx \l_clist_last_tl { \clist_item:Nn \l_doc_macro_input_clist {2} }
+ \texttt{\l_clist_first_tl}\,,~
+ \texttt{\l_clist_mid_tl}\,,~
+ and~ \texttt{\l_clist_last_tl}\,.
+ }
+ }
+ {
+ \tl_set:Nx \l_clist_first_tl { \clist_item:Nn \l_doc_macro_input_clist {0} }
+ \texttt{\l_clist_first_tl}\,~and~others.
+ }
+ \bool_if:nT {
+ !\l_doc_macro_aux_bool &&
+ !\l_doc_macro_internal_bool &&
+ \int_compare_p:n {\g_doc_nested_macro_int<1}
+ }
+ {
+ \int_compare:nNnTF \l_doc_macro_int=1 {~This~} {~These~}
+ \bool_if:NTF \l_doc_macro_var_bool{variable}{function}
+ \int_compare:nNnTF \l_doc_macro_int=1 {~is~}{s~are~}
+ documented~on~page~
+ \exp_args:Nx\pageref{doc/function/\l_doc_macro_tl}.
+ }
+ })\par}
+ }
+ \bool_if:nT
+ { \g_doc_checktest_bool &&
+ !( \l_doc_macro_aux_bool || \l_doc_macro_var_bool ) &&
+ !\l_doc_tested_bool
+ }
+ {
+ \seq_gput_right:Nx \g_doc_not_tested_seq
+ {
+ \l_doc_macro_input_clist
+ \bool_if:NT \l_doc_macro_pTF_bool {~(pTF)}
+ \bool_if:NT \l_doc_macro_TF_bool {~(TF)}
+ }
+ }
+}
+\newcommand*{\DescribeOption}{
+ \leavevmode
+ \@bsphack
+ \begingroup
+ \MakePrivateLetters
+ \Describe@Option
+}
+\newcommand*{\Describe@Option}[1]{
+ \endgroup
+ \marginpar{
+ \raggedleft
+ \PrintDescribeEnv{#1}
+ }
+ \SpecialOptionIndex{#1}
+ \@esphack
+ \ignorespaces
+}
+\newcommand*{\SpecialOptionIndex}[1]{
+ \@bsphack
+ \begingroup
+ \HD@target
+ \let\HDorg@encapchar\encapchar
+ \edef\encapchar usage{
+ \HDorg@encapchar hdclindex{\the\c@HD@hypercount}{usage}
+ }
+ \index{
+ #1\actualchar{\protect\ttfamily#1}~(option)
+ \encapchar usage
+ }
+ \index{
+ options:\levelchar#1\actualchar{\protect\ttfamily#1}
+ \encapchar usage
+ }
+ \endgroup
+ \@esphack
+}
+\font\manual=manfnt
+\cs_set_nopar:Npn \dbend { {\manual\char127} }
+\newenvironment {danger} {
+ \begin{trivlist}\item[]\noindent
+ \begingroup\hangindent=2pc\hangafter=-2
+ \cs_set_nopar:Npn \par{\endgraf\endgroup}
+ \hbox to0pt{\hskip-\hangindent\dbend\hfill}\ignorespaces
+}{
+ \par\end{trivlist}
+}
+\newenvironment {ddanger} {
+ \begin{trivlist}\item[]\noindent
+ \begingroup\hangindent=3.5pc\hangafter=-2
+ \cs_set_nopar:Npn \par{\endgraf\endgroup}
+ \hbox to0pt{\hskip-\hangindent\dbend\kern2pt\dbend\hfill}\ignorespaces
+}{
+ \par\end{trivlist}
+}
+\newenvironment{TemplateInterfaceDescription}[1]
+ {\subsection{The~object~type~`#1'}%
+ \begingroup
+ \@beginparpenalty\@M
+ \description
+ \def\TemplateArgument##1##2{\item[Arg:~##1]##2\par}%
+ \def\TemplateSemantics{\enddescription\endgroup
+ \subsubsection*{Semantics:}}%
+ }
+ {\par\bigskip}
+\newenvironment{TemplateDescription}[2]
+ {\subsection{The~template~`#2'~(object~type~#1)}%
+ \subsubsection*{Attributes:}%
+ \begingroup
+ \@beginparpenalty\@M
+ \description
+ \def\TemplateKey##1##2##3##4{\item[##1~(##2)]##3%
+ \ifx\TemplateKey##4\TemplateKey\else
+ \hfill\penalty500\hbox{}\hfill Default:~##4%
+ \nobreak\hskip-\parfillskip\hskip0pt\relax
+ \fi
+ \par}%
+ \def\TemplateSemantics{\enddescription\endgroup
+ \subsubsection*{Semantics~\&~Comments:}}%
+ }
+ {\par\bigskip}
+\newenvironment{InstanceDescription}[4][xxxxxxxxxxxxxxx]
+ {\subsubsection{The~instance~`#3'~(template~#2/#4)}%
+ \subsubsection*{Attribute~values:}%
+ \begingroup
+ \@beginparpenalty\@M
+ \def\InstanceKey##1##2{\>\textbf{##1}\>##2\\}%
+ \def\InstanceSemantics{\endtabbing\endgroup
+ \vskip-30pt\vskip0pt
+ \subsubsection*{Layout~description~\&~Comments:}}%
+ \tabbing
+ xxxx\=#1\=\kill
+ }
+ {\par\bigskip}
+\bool_new:N \g_doc_implementation_bool
+\cs_set_nopar:Npn \AlsoImplementation {
+ \bool_set_true:N \g_doc_implementation_bool
+ \cs_set:Npn \StopEventually ##1 {
+ \@bsphack
+ \cs_gset_nopar:Npn \Finale { ##1 \check@checksum }
+ \init@checksum
+ \@esphack
+ }
+}
+\AlsoImplementation
+\cs_set_nopar:Npn \OnlyDescription {
+ \@bsphack
+ \bool_set_false:N \g_doc_implementation_bool
+ \cs_set:Npn \StopEventually ##1 { ##1 \endinput }
+ \@esphack
+}
+\cs_set_eq:NN \Finale \relax
+\cs_set_nopar:Npn \partname{File}
+\clist_new:N \g_docinput_clist
+\cs_set:Npn \DocInput #1 {
+ \clist_map_inline:nn {#1} {
+ \clist_put_right:Nn \g_docinput_clist {##1}
+ \MakePercentIgnore
+ \input{##1}
+ \MakePercentComment
+ }
+}
+\cs_set:Npn \DocInputAgain {
+ \clist_map_inline:Nn \g_docinput_clist {
+ \MakePercentIgnore
+ \input{##1}
+ \MakePercentComment
+ }
+}
+\cs_set_nopar:Npn \partname{File}
+\newcommand*{\DocInclude}[1]{%
+ \relax\clearpage
+ \docincludeaux
+ \IfFileExists{#1.fdd}{
+ \cs_set_nopar:Npn \currentfile{#1.fdd}
+ }{
+ \cs_set_nopar:Npn \currentfile{#1.dtx}
+ }
+ \ifnum\@auxout=\@partaux
+ \@latexerr{\string\include\space cannot~be~nested}\@eha
+ \else
+ \@docinclude #1
+ \fi
+}
+\cs_set_nopar:Npn \@docinclude #1 {
+ \clearpage
+ \immediate\write\@mainaux{\string\@input{#1.aux}}
+ \@tempswatrue
+ \if@partsw
+ \@tempswafalse
+ \cs_set_nopar:Npx \@tempb{#1}
+ \@for\@tempa:=\@partlist\do{
+ \ifx\@tempa\@tempb\@tempswatrue\fi
+ }
+ \fi
+ \if@tempswa
+ \cs_set_eq:NN \@auxout\@partaux
+ \immediate\openout\@partaux #1.aux
+ \immediate\write\@partaux{\relax}
+ \cs_set_eq:NN \@ltxdoc@PrintIndex\PrintIndex
+ \cs_set_eq:NN \PrintIndex\relax
+ \cs_set_eq:NN \@ltxdoc@PrintChanges\PrintChanges
+ \cs_set_eq:NN \PrintChanges\relax
+ \cs_set_eq:NN \@ltxdoc@theglossary\theglossary
+ \cs_set_eq:NN \@ltxdoc@endtheglossary\endtheglossary
+ \part{\currentfile}
+ {
+ \cs_set_eq:NN \ttfamily\relax
+ \cs_gset_nopar:Npx \filekey{\filekey, \thepart={\ttfamily\currentfile}}
+ }
+ \DocInput{\currentfile}
+ \cs_set_eq:NN \PrintIndex\@ltxdoc@PrintIndex
+ \cs_set_eq:NN \PrintChanges\@ltxdoc@PrintChanges
+ \cs_set_eq:NN \theglossary\@ltxdoc@theglossary
+ \cs_set_eq:NN \endtheglossary\@ltxdoc@endtheglossary
+ \clearpage
+ \@writeckpt{#1}
+ \immediate\closeout\@partaux
+ \else
+ \@nameuse{cp@#1}
+ \fi
+ \cs_set_eq:NN \@auxout\@mainaux
+}
+\cs_gset_nopar:Npn \codeline@wrindex #1 {
+ \immediate\write\@indexfile {
+ \string\indexentry{#1}
+ {\filesep\number\c@CodelineNo}
+ }
+}
+\cs_set_eq:NN \filesep \@empty
+\cs_set_nopar:Npn \docincludeaux {
+ \cs_set_nopar:Npn \thepart {\alphalph{part}}
+ \cs_set_nopar:Npn \filesep {\thepart-}
+ \cs_set_eq:NN \filekey\@gobble
+ \g@addto@macro\index@prologue{
+ \cs_gset_nopar:Npn\@oddfoot{
+ \parbox{\textwidth}{
+ \strut\footnotesize
+ \raggedright{\bfseries File~Key:}~\filekey
+ }
+ }
+ \cs_set_eq:NN \@evenfoot\@oddfoot
+ }
+ \cs_gset_eq:NN \docincludeaux\relax
+ \cs_gset_nopar:Npn\@oddfoot{
+ \expandafter\ifx\csname ver@\currentfile\endcsname\relax
+ File~\thepart :~{\ttfamily\currentfile}~
+ \else
+ \GetFileInfo{\currentfile}
+ File~\thepart :~{\ttfamily\filename}~
+ Date:~\ExplFileDate\ % space
+ Version~\ExplFileVersion
+ \fi
+ \hfill\thepage
+ }
+ \cs_set_eq:NN \@evenfoot \@oddfoot
+}
+\seq_new:N \g_doc_functions_seq
+\seq_new:N \g_doc_macros_seq
+\seq_new:N \g_doc_not_tested_seq
+\iow_open:Nn \g_write_func_stream { \jobname.cmds }
+\cs_new_nopar:Npn \doc_show_functions_defined: {
+ \bool_if:nT { \g_doc_implementation_bool && \g_doc_checkfunc_bool } {
+ \typeout{ ======================================== ^^J }
+
+ \tl_clear:N \l_tmpa_tl
+ \seq_map_inline:Nn \g_doc_functions_seq {
+ \seq_if_in:NnT \g_doc_macros_seq {##1} {
+ \tl_put_right:Nn \l_tmpa_tl { ##1 ^^J }
+ \iow_now:Nn \g_write_func_stream { ##1 }
+ }
+ }
+ \iow_close:N \g_write_func_stream
+ \doc_functions_typeout:n {
+ Functions~both~documented~and~defined:^^J (In~order~of~being~documented)
+ }
+
+ \seq_map_inline:Nn \g_doc_functions_seq {
+ \seq_if_in:NnF \g_doc_macros_seq {##1} {
+ \tl_put_right:Nn \l_tmpa_tl { ##1 ^^J }
+ }
+ }
+ \doc_functions_typeout:n { Functions~documented~but~not~defined: }
+
+ \seq_map_inline:Nn \g_doc_macros_seq {
+ \seq_if_in:NnF \g_doc_functions_seq {##1} {
+ \tl_put_right:Nn \l_tmpa_tl { ##1 ^^J }
+ }
+ }
+ \doc_functions_typeout:n { Functions~defined~but~not~documented: }
+
+ \typeout{ ======================================== }
+ }
+}
+\AtEndDocument{ \doc_show_functions_defined: }
+\cs_set_nopar:Npn \doc_functions_typeout:n #1 {
+ \tl_if_empty:NF \l_tmpa_tl {
+ \typeout{
+ -------------------------------------- ^^J #1 ^^J
+ -------------------------------------- ^^J \l_tmpa_tl
+ }
+ \tl_clear:N \l_tmpa_tl
+ }
+}
+\cs_new:Npn \doc_show_not_tested: {
+ \bool_if:NT \g_doc_checktest_bool
+ {
+ \bool_if:nT { !(\seq_if_empty_p:N \g_doc_not_tested_seq) ||
+ !(\prop_if_empty_p:N \g_doc_missing_tests_prop) }
+ {
+ \tl_clear:N \l_tmpa_tl
+ \prop_if_empty:NF \g_doc_missing_tests_prop
+ {
+ \tl_put_right:Nn \l_tmpa_tl
+ {
+ ^^J^^JThe~ following~ macro(s)~ have~ incomplete~ tests:^^J
+ }
+ \prop_map_inline:Nn \g_doc_missing_tests_prop
+ {
+ \tl_put_right:Nn \l_tmpa_tl
+ {^^J\space\space\space\space ##1
+ ^^J\space\space\space\space\space\space ##2}
+ }
+ }
+ \seq_if_empty:NF \g_doc_not_tested_seq
+ {
+ \tl_put_right:Nn \l_tmpa_tl
+ {
+ ^^J^^J
+ The~ following~ macro(s)~ do~ not~ have~ any~ tests:^^J
+ }
+ \seq_map_inline:Nn \g_doc_not_tested_seq
+ {
+ \clist_map_inline:nn {##1}
+ {
+ \tl_put_right:Nn \l_tmpa_tl {^^J\space\space\space\space ####1}
+ }
+ }
+ \int_set:Nn \l_tmpa_int {\etex_interactionmode:D}
+ \errorstopmode
+ \ClassError{l3doc}{\l_tmpa_tl}{}
+ \int_set:Nn \etex_interactionmode:D {\l_tmpa_int}
+ }
+ }
+ }
+}
+\AtEndDocument{ \doc_show_not_tested: }
+\g@addto@macro\theindex{\MakePrivateLetters}
+\cs_set:Npn \verbatimchar {&}
+\setcounter{IndexColumns}{2}
+\IndexPrologue{
+ \part*{Index}
+ \markboth{Index}{Index}
+ \addcontentsline{toc}{part}{Index}
+ The~italic~numbers~denote~the~pages~where~the~
+ corresponding~entry~is~described,~
+ numbers~underlined~point~to~the~definition,~
+ all~others~indicate~the~places~where~it~is~used.
+}
+
+\cs_set_nopar:Npn \doc_special_main_index:n #1 {
+ \index{
+ \@gobble#1
+ \actualchar
+ \string\verb\quotechar*\verbatimchar#1\verbatimchar
+ \encapchar
+ hdpgindex{\thepage}{usage}
+ }
+}
+\cs_set_nopar:Npn \doc_special_main_index:o { \exp_args:No \doc_special_main_index:n }
+\cs_set_nopar:Npn \hdpgindex #1#2#3 {
+ \csname\ifx\\#2\\relax\else#2\fi\endcsname{
+ \hyperlink{page.#1}{#3}
+ }
+}
+\g@addto@macro \PrintIndex { \AtEndDocument{ \typeout{^^J
+ ========================================^^J
+ Generate~the~index~by~executing^^J
+ \c_space_tl \c_space_tl \c_space_tl \c_space_tl
+ makeindex~-s~l3doc.ist~-o~\jobname.ind~\jobname.idx^^J
+ ========================================^^J
+ }}
+}
+\GlossaryPrologue{
+ \part*{Change~History}
+ {\GlossaryParms\ttfamily\hyphenchar\font=`\-}
+ \markboth{Change~History}{Change~History}
+ \addcontentsline{toc}{part}{Change~History}
+}
+\g@addto@macro \PrintChanges { \AtEndDocument{ \typeout{^^J
+ ========================================^^J
+ Generate~the~change~list~by~executing^^J
+ \c_space_tl \c_space_tl \c_space_tl \c_space_tl
+ makeindex~-s~gglo.ist~~-o~\jobname.gls~\jobname.glo^^J
+ ========================================^^J
+ }}
+}
+\bool_if:NTF \g_doc_full_bool {
+ \RecordChanges
+ \CodelineIndex
+ \EnableCrossrefs
+ \AlsoImplementation
+}{
+ \CodelineNumbered
+ \DisableCrossrefs
+ \OnlyDescription
+}
+%%
+%%
+%% End of file `l3doc.cls'.
diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3expan.sty b/Master/texmf-dist/tex/latex/l3kernel/l3expan.sty
new file mode 100644
index 00000000000..028e9cd3bc0
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/l3kernel/l3expan.sty
@@ -0,0 +1,394 @@
+%%
+%% This is file `l3expan.sty',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% l3expan.dtx (with options: `package')
+%%
+%% EXPERIMENTAL CODE
+%%
+%% Do not distribute this file without also distributing the
+%% source files specified above.
+%%
+%% Do not distribute a modified version of this file.
+%%
+%% File: l3expan.dtx Copyright (C) 1990-2011 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 "expl3 bundle" (The Work in LPPL)
+%% and all files in that bundle must be distributed together.
+%%
+%% The released version of this bundle is available from CTAN.
+%%
+%% -----------------------------------------------------------------------
+%%
+%% The development version of the bundle can be found at
+%%
+%% http://www.latex-project.org/svnroot/experimental/trunk/
+%%
+%% for those people who are interested.
+%%
+%%%%%%%%%%%
+%% NOTE: %%
+%%%%%%%%%%%
+%%
+%% Snapshots taken from the repository represent work in progress and may
+%% not work or may contain conflicting material! We therefore ask
+%% people _not_ to put them into distributions, archives, etc. without
+%% prior consultation with the LaTeX3 Project.
+%%
+%% -----------------------------------------------------------------------
+\RequirePackage{l3names}
+\GetIdInfo$Id: l3expan.dtx 2480 2011-06-20 17:25:23Z bruno $
+ {L3 Experimental argument expansion}
+\ProvidesExplPackage
+ {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
+\package_check_loaded_expl:
+\cs_new_nopar:Npn \l_exp_tl { }
+\cs_new:Npn \exp_arg_next:nnn #1#2#3 { #2 \::: { #3 {#1} } }
+\cs_new:Npn \exp_arg_next_nobrace:nnn #1#2#3 { #2 \::: { #3 #1 } }
+\cs_new:Npn \::: #1 {#1}
+\cs_new:Npn \::n #1 \::: #2#3 { #1 \::: { #2 {#3} } }
+\cs_new:Npn \::N #1 \::: #2#3 { #1 \::: {#2#3} }
+\cs_new:Npn \::c #1 \::: #2#3
+ { \exp_after:wN \exp_arg_next_nobrace:nnn \cs:w #3 \cs_end: {#1} {#2} }
+\cs_new:Npn \::o #1 \::: #2#3
+ { \exp_after:wN \exp_arg_next:nnn \exp_after:wN {#3} {#1} {#2} }
+\cs_new:Npn \::f #1 \::: #2#3
+ {
+ \exp_after:wN \exp_arg_next:nnn
+ \exp_after:wN { \tex_romannumeral:D -`0 #3 }
+ {#1} {#2}
+ }
+\use:nn { \cs_new_eq:NN \exp_stop_f: } { ~ }
+\cs_new_protected:Npn \::x #1 \::: #2#3
+ {
+ \cs_set_nopar:Npx \l_exp_tl { {#3} }
+ \exp_after:wN \exp_arg_next:nnn \l_exp_tl {#1} {#2}
+ }
+\cs_new:Npn \::V #1 \::: #2#3
+ {
+ \exp_after:wN \exp_arg_next:nnn
+ \exp_after:wN { \tex_romannumeral:D \exp_eval_register:N #3 }
+ {#1} {#2}
+}
+\cs_new:Npn \::v # 1\::: #2#3
+ {
+ \exp_after:wN \exp_arg_next:nnn
+ \exp_after:wN { \tex_romannumeral:D \exp_eval_register:c {#3} }
+ {#1} {#2}
+ }
+\cs_new_nopar:Npn \exp_eval_register:N #1
+ {
+ \exp_after:wN \if_meaning:w \exp_not:N #1 #1
+ \if_meaning:w \scan_stop: #1
+ \exp_eval_error_msg:w
+ \fi:
+ \else:
+ \exp_after:wN \use_i_ii:nnn
+ \fi:
+ \exp_after:wN \c_zero \tex_the:D #1
+ }
+\cs_new_nopar:Npn \exp_eval_register:c #1
+ { \exp_after:wN \exp_eval_register:N \cs:w #1 \cs_end: }
+\group_begin:%
+\tex_catcode:D`\!=11\scan_stop:%
+\tex_catcode:D`\ =11\scan_stop:%
+\cs_new:Npn\exp_eval_error_msg:w#1\tex_the:D#2{%
+\fi:\fi:\exp_after:wN\c_zero\erroneous variable used!}%
+\group_end:%
+\cs_new:Npn \exp_args:No #1#2 { \exp_after:wN #1 \exp_after:wN {#2} }
+\cs_new:Npn \exp_args:NNo #1#2#3
+ { \exp_after:wN #1 \exp_after:wN #2 \exp_after:wN {#3} }
+\cs_new:Npn \exp_args:NNNo #1#2#3#4
+ { \exp_after:wN #1 \exp_after:wN#2 \exp_after:wN #3 \exp_after:wN {#4} }
+\cs_new:Npn \exp_args:cc #1#2
+ { \cs:w #1 \exp_after:wN \cs_end: \cs:w #2 \cs_end: }
+\cs_new:Npn \exp_args:NNc #1#2#3
+ { \exp_after:wN #1 \exp_after:wN #2 \cs:w # 3\cs_end: }
+\cs_new:Npn \exp_args:Ncc #1#2#3
+ { \exp_after:wN #1 \cs:w #2 \exp_after:wN \cs_end: \cs:w #3 \cs_end: }
+\cs_new:Npn \exp_args:Nccc #1#2#3#4
+ {
+ \exp_after:wN #1
+ \cs:w #2 \exp_after:wN \cs_end:
+ \cs:w #3 \exp_after:wN \cs_end:
+ \cs:w #4 \cs_end:
+ }
+\cs_new:Npn \exp_args:Nf #1#2
+ { \exp_after:wN #1 \exp_after:wN { \tex_romannumeral:D -`0 #2 } }
+\cs_new:Npn \exp_args:Nv #1#2
+ {
+ \exp_after:wN #1 \exp_after:wN
+ { \tex_romannumeral:D \exp_eval_register:c {#2} }
+ }
+\cs_new:Npn \exp_args:NV #1#2
+ {
+ \exp_after:wN #1 \exp_after:wN
+ { \tex_romannumeral:D \exp_eval_register:N #2 }
+ }
+\cs_new:Npn \exp_args:NNf #1#2#3
+ {
+ \exp_after:wN #1
+ \exp_after:wN #2
+ \exp_after:wN { \tex_romannumeral:D -`0 #3 }
+ }
+\cs_new:Npn \exp_args:NNv #1#2#3
+ {
+ \exp_after:wN #1
+ \exp_after:wN #2
+ \exp_after:wN { \tex_romannumeral:D \exp_eval_register:c {#3} }
+ }
+\cs_new:Npn \exp_args:NNV #1#2#3
+ {
+ \exp_after:wN #1
+ \exp_after:wN #2
+ \exp_after:wN { \tex_romannumeral:D \exp_eval_register:N #3 }
+ }
+\cs_new:Npn \exp_args:Nco #1#2#3
+ {
+ \exp_after:wN #1
+ \cs:w #2 \exp_after:wN \cs_end:
+ \exp_after:wN {#3}
+ }
+\cs_new:Npn \exp_args:Ncf #1#2#3
+ {
+ \exp_after:wN #1
+ \cs:w #2 \exp_after:wN \cs_end:
+ \exp_after:wN { \tex_romannumeral:D -`0 #3 }
+ }
+\cs_new_nopar:Npn \exp_args:NVV #1#2#3
+ {
+ \exp_after:wN #1
+ \exp_after:wN { \tex_romannumeral:D \exp_after:wN
+ \exp_eval_register:N \exp_after:wN #2 \exp_after:wN }
+ \exp_after:wN { \tex_romannumeral:D \exp_eval_register:N #3 }
+ }
+\cs_new:Npn \exp_args:NNNV #1#2#3#4
+ {
+ \exp_after:wN #1
+ \exp_after:wN #2
+ \exp_after:wN #3
+ \exp_after:wN { \tex_romannumeral:D \exp_eval_register:N #4 }
+ }
+\cs_new:Npn \exp_args:NcNc #1#2#3#4
+ {
+ \exp_after:wN #1
+ \cs:w #2 \exp_after:wN \cs_end:
+ \exp_after:wN #3
+ \cs:w #4 \cs_end:
+ }
+\cs_new:Npn \exp_args:NcNo #1#2#3#4
+ {
+ \exp_after:wN #1
+ \cs:w #2 \exp_after:wN \cs_end:
+ \exp_after:wN #3
+ \exp_after:wN {#4}
+ }
+\cs_new:Npn \exp_args:Ncco #1#2#3#4
+ {
+ \exp_after:wN #1
+ \cs:w #2 \exp_after:wN \cs_end:
+ \cs:w #3 \exp_after:wN \cs_end:
+ \exp_after:wN {#4}
+ }
+\cs_new_protected_nopar:Npn \exp_args:Nx { \::x \::: }
+\cs_new_nopar:Npn \exp_args:Nnc { \::n \::c \::: }
+\cs_new_nopar:Npn \exp_args:Nfo { \::f \::o \::: }
+\cs_new_nopar:Npn \exp_args:Nff { \::f \::f \::: }
+\cs_new_nopar:Npn \exp_args:Nnf { \::n \::f \::: }
+\cs_new_nopar:Npn \exp_args:Nno { \::n \::o \::: }
+\cs_new_nopar:Npn \exp_args:NnV { \::n \::V \::: }
+\cs_new_nopar:Npn \exp_args:Noc { \::o \::c \::: }
+\cs_new_nopar:Npn \exp_args:Noo { \::o \::o \::: }
+\cs_new_protected_nopar:Npn \exp_args:NNx { \::N \::x \::: }
+\cs_new_protected_nopar:Npn \exp_args:Ncx { \::c \::x \::: }
+\cs_new_protected_nopar:Npn \exp_args:Nnx { \::n \::x \::: }
+\cs_new_protected_nopar:Npn \exp_args:Nox { \::o \::x \::: }
+\cs_new_protected_nopar:Npn \exp_args:Nxo { \::x \::o \::: }
+\cs_new_protected_nopar:Npn \exp_args:Nxx { \::x \::x \::: }
+\cs_new_nopar:Npn \exp_args:NNno { \::N \::n \::o \::: }
+\cs_new_nopar:Npn \exp_args:NNoo { \::N \::o \::o \::: }
+\cs_new_nopar:Npn \exp_args:Nnnc { \::n \::n \::c \::: }
+\cs_new_nopar:Npn \exp_args:Nnno { \::n \::n \::o \::: }
+\cs_new_nopar:Npn \exp_args:Nooo { \::o \::o \::o \::: }
+\cs_new_protected_nopar:Npn \exp_args:NNnx { \::N \::n \::x \::: }
+\cs_new_protected_nopar:Npn \exp_args:NNox { \::N \::o \::x \::: }
+\cs_new_protected_nopar:Npn \exp_args:Nnnx { \::n \::n \::x \::: }
+\cs_new_protected_nopar:Npn \exp_args:Nnox { \::n \::o \::x \::: }
+\cs_new_protected_nopar:Npn \exp_args:Nccx { \::c \::c \::x \::: }
+\cs_new_protected_nopar:Npn \exp_args:Ncnx { \::c \::n \::x \::: }
+\cs_new_protected_nopar:Npn \exp_args:Noox { \::o \::o \::x \::: }
+\cs_new:Npn \exp_arg_last_unbraced:nn #1#2 { #2#1 }
+\cs_new:Npn \::f_unbraced \::: #1#2
+ {
+ \exp_after:wN \exp_arg_last_unbraced:nn
+ \exp_after:wN { \tex_romannumeral:D -`0 #2 } {#1}
+ }
+\cs_new:Npn \::o_unbraced \::: #1#2
+ { \exp_after:wN \exp_arg_last_unbraced:nn \exp_after:wN {#2} {#1} }
+\cs_new:Npn \::V_unbraced \::: #1#2
+ {
+ \exp_after:wN \exp_arg_last_unbraced:nn
+ \exp_after:wN { \tex_romannumeral:D \exp_eval_register:N #2 } {#1}
+ }
+\cs_new:Npn \::v_unbraced \::: #1#2
+ {
+ \exp_after:wN \exp_arg_last_unbraced:nn
+ \exp_after:wN { \tex_romannumeral:D \exp_eval_register:c {#2} } {#1}
+ }
+\cs_new:Npn \exp_last_unbraced:NV #1#2
+ { \exp_after:wN #1 \tex_romannumeral:D \exp_eval_register:N #2 }
+\cs_new:Npn \exp_last_unbraced:Nv #1#2
+ { \exp_after:wN #1 \tex_romannumeral:D \exp_eval_register:c {#2} }
+\cs_new:Npn \exp_last_unbraced:No #1#2 { \exp_after:wN #1 #2 }
+\cs_new:Npn \exp_last_unbraced:Nf #1#2
+ { \exp_after:wN #1 \tex_romannumeral:D -`0 #2 }
+\cs_new:Npn \exp_last_unbraced:NcV #1#2#3
+ {
+ \exp_after:wN #1
+ \cs:w #2 \exp_after:wN \cs_end:
+ \tex_romannumeral:D \exp_eval_register:N #3
+ }
+\cs_new:Npn \exp_last_unbraced:NNV #1#2#3
+ {
+ \exp_after:wN #1
+ \exp_after:wN #2
+ \tex_romannumeral:D \exp_eval_register:N #3
+ }
+\cs_new:Npn \exp_last_unbraced:NNo #1#2#3
+ { \exp_after:wN #1 \exp_after:wN #2 #3 }
+\cs_new_nopar:Npn \exp_last_unbraced:Noo { \::o \::o_unbraced \::: }
+\cs_new_nopar:Npn \exp_last_unbraced:Nfo { \::f \::o_unbraced \::: }
+\cs_new:Npn \exp_last_unbraced:NNNV #1#2#3#4
+ {
+ \exp_after:wN #1
+ \exp_after:wN #2
+ \exp_after:wN #3
+ \tex_romannumeral:D \exp_eval_register:N #4
+ }
+\cs_new:Npn \exp_last_unbraced:NNNo #1#2#3#4
+ { \exp_after:wN #1 \exp_after:wN #2 \exp_after:wN #3 #4 }
+\cs_new:Npn \exp_last_two_unbraced:Noo #1#2#3
+ { \exp_after:wN \exp_last_two_unbraced_aux:nnN \exp_after:wN {#3} {#2} #1 }
+\cs_new:Npn \exp_last_two_unbraced_aux:nnN #1#2#3
+ { \exp_after:wN #3 #2 #1 }
+\cs_new:Npn \exp_not:o #1 { \etex_unexpanded:D \exp_after:wN {#1} }
+\cs_new:Npn \exp_not:f #1
+ { \etex_unexpanded:D \exp_after:wN { \tex_romannumeral:D -`0 #1 } }
+\cs_new:Npn \exp_not:V #1
+ {
+ \etex_unexpanded:D \exp_after:wN
+ { \tex_romannumeral:D \exp_eval_register:N #1 }
+ }
+\cs_new:Npn \exp_not:v #1
+ {
+ \etex_unexpanded:D \exp_after:wN
+ { \tex_romannumeral:D \exp_eval_register:c {#1} }
+ }
+\cs_new:Npn \exp_not:c #1 { \exp_after:wN \exp_not:N \cs:w #1 \cs_end: }
+\cs_new_protected:Npn \cs_generate_variant:Nn #1
+ {
+ \chk_if_exist_cs:N #1
+ \cs_split_function:NN #1 \cs_generate_variant_aux:nnNNn
+ #1
+ }
+\cs_new:Npn \cs_generate_variant_aux:nnNNn #1#2#3#4#5
+ { \cs_generate_variant_aux:Nnnw #4 {#1}{#2} #5 , ? , \q_recursion_stop }
+\cs_new:Npn \cs_generate_variant_aux:Nnnw #1#2#3#4 ,
+ {
+ \if:w ? #4
+ \exp_after:wN \use_none_delimit_by_q_recursion_stop:w
+ \fi:
+ \exp_args:NNc \cs_generate_variant_aux:NNn
+ #1
+ { #2 : #4 \use:c { use_none: \cs_generate_variant_aux:N #4 ? } #3 }
+ {#4}
+ \cs_generate_variant_aux:Nnnw #1 {#2} {#3}
+ }
+\cs_new:Npn \cs_generate_variant_aux:NNn #1 #2 #3
+ {
+ \cs_if_free:NTF #2
+ {
+ \cs_generate_variant_aux:NNpx #1 #2
+ { \exp_not:c { exp_args:N #3 } \exp_not:N #1 }
+ \cs_generate_internal_variant:n {#3}
+ }
+ {
+ \iow_log:x
+ {
+ Variant~\token_to_str:N #2~%
+ already~defined;~ not~ changing~ it~on~line~%
+ \tex_the:D \tex_inputlineno:D
+ }
+ }
+ }
+\cs_new:Npn \cs_generate_variant_aux:N #1
+ {
+ \if:w ? #1
+ \exp_after:wN \use_none:nn
+ \fi:
+ n
+ \cs_generate_variant_aux:N
+ }
+\group_begin:
+ \tex_lccode:D `\Z = `\d \scan_stop:
+ \tex_lccode:D `\? =`\\ \scan_stop:
+ \tex_catcode:D `\P = 12 \scan_stop:
+ \tex_catcode:D `\R = 12 \scan_stop:
+ \tex_catcode:D `\O = 12 \scan_stop:
+ \tex_catcode:D `\T = 12 \scan_stop:
+ \tex_catcode:D `\E = 12 \scan_stop:
+ \tex_catcode:D `\C = 12 \scan_stop:
+ \tex_catcode:D `\Z = 12 \scan_stop:
+\tex_lowercase:D
+ {
+ \group_end:
+ \cs_new_nopar:Npn \cs_generate_variant_aux:NNpx #1
+ {
+ \exp_after:wN \cs_generate_variant_aux:w
+ \token_to_meaning:N #1 ? PROTECTEZ \q_stop
+ }
+ \cs_new:Npn \cs_generate_variant_aux:w #1 ? PROTECTEZ #2 \q_stop
+ {
+ \if_catcode:w a \etex_detokenize:D \exp_after:wN {#1} a
+ \exp_after:wN \cs_new_protected_nopar:Npx
+ \else:
+ \exp_after:wN \cs_new_nopar:Npx
+ \fi:
+ }
+ }
+\cs_new_protected:Npn \cs_generate_internal_variant:n #1
+ {
+ \cs_if_free:cT { exp_args:N #1 }
+ {
+ \cs_new:cpx { exp_args:N #1 }
+ { \cs_generate_internal_variant_aux:N #1 : }
+ }
+ }
+\cs_new:Npn \cs_generate_internal_variant_aux:N #1
+ {
+ \exp_not:c { :: #1 }
+ \if_meaning:w #1 :
+ \exp_after:wN \use_none:n
+ \fi:
+ \cs_generate_internal_variant_aux:N
+ }
+\cs_generate_variant:Nn \str_if_eq_p:nn { V , o }
+\cs_generate_variant:Nn \str_if_eq_p:nn { nV , no , VV }
+\cs_generate_variant:Nn \str_if_eq:nnT { V , o }
+\cs_generate_variant:Nn \str_if_eq:nnT { nV , no , VV }
+\cs_generate_variant:Nn \str_if_eq:nnF { V , o }
+\cs_generate_variant:Nn \str_if_eq:nnF { nV , no , VV }
+\cs_generate_variant:Nn \str_if_eq:nnTF { V , o }
+\cs_generate_variant:Nn \str_if_eq:nnTF { nV , no , VV }
+%%
+%%
+%% End of file `l3expan.sty'.
diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3file.sty b/Master/texmf-dist/tex/latex/l3kernel/l3file.sty
new file mode 100644
index 00000000000..e8272cde35f
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/l3kernel/l3file.sty
@@ -0,0 +1,133 @@
+%%
+%% This is file `l3file.sty',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% l3file.dtx (with options: `package')
+%%
+%% EXPERIMENTAL CODE
+%%
+%% Do not distribute this file without also distributing the
+%% source files specified above.
+%%
+%% Do not distribute a modified version of this file.
+%%
+%% File: l3file.dtx Copyright (C) 2009-2011 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 "expl3 bundle" (The Work in LPPL)
+%% and all files in that bundle must be distributed together.
+%%
+%% The released version of this bundle is available from CTAN.
+%%
+%% -----------------------------------------------------------------------
+%%
+%% The development version of the bundle can be found at
+%%
+%% http://www.latex-project.org/svnroot/experimental/trunk/
+%%
+%% for those people who are interested.
+%%
+%%%%%%%%%%%
+%% NOTE: %%
+%%%%%%%%%%%
+%%
+%% Snapshots taken from the repository represent work in progress and may
+%% not work or may contain conflicting material! We therefore ask
+%% people _not_ to put them into distributions, archives, etc. without
+%% prior consultation with the LaTeX3 Project.
+%%
+%% -----------------------------------------------------------------------
+\RequirePackage{l3names}
+\GetIdInfo$Id: l3file.dtx 2478 2011-06-19 21:34:23Z joseph $
+ {L3 Experimental file operations}
+\ProvidesExplPackage
+ {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
+\package_check_loaded_expl:
+\tl_new:N \g_file_current_name_tl
+\tl_gset_eq:NN \g_file_current_name_tl \@currname
+\seq_new:N \g_file_stack_seq
+\seq_new:N \g_file_record_seq
+\tl_new:N \l_file_name_tl
+\seq_new:N \l_file_search_path_seq
+\seq_new:N \l_file_search_path_saved_seq
+\cs_new_protected_nopar:Npn \file_add_path:nN #1#2
+ {
+ \ior_open:Nn \g_file_test_stream {#1}
+ \ior_if_eof:NTF \g_file_test_stream
+ { \file_add_path_search:nN {#1} #2 }
+ {
+ \ior_close:N \g_file_test_stream
+ \tl_set:Nx #2 {#1}
+ }
+ }
+\cs_new_protected_nopar:Npn \file_add_path_search:nN #1#2
+ {
+ \tl_clear:N #2
+ \cs_if_exist:NT \input@path
+ {
+ \seq_set_eq:NN \l_file_search_path_saved_seq \l_file_search_path_seq
+ \clist_map_inline:Nn \input@path
+ { \seq_put_right:Nn \l_file_search_path_seq {##1} }
+ }
+ \seq_map_inline:Nn \l_file_search_path_seq
+ {
+ \ior_open:Nn \g_file_test_stream { ##1 #1 }
+ \ior_if_eof:NF \g_file_test_stream
+ {
+ \tl_set:Nx #2 { ##1 #1 }
+ \seq_map_break:
+ }
+ }
+ \cs_if_exist:NT \input@path
+ { \seq_set_eq:NN \l_file_search_path_seq \l_file_search_path_saved_seq }
+ \ior_close:N \g_file_test_stream
+ }
+\prg_new_protected_conditional:Nnn \file_if_exist:n { T , F , TF }
+ {
+ \file_add_path:nN {#1} \l_file_name_tl
+ \tl_if_empty:NTF \l_file_name_tl
+ { \prg_return_false: }
+ { \prg_return_true: }
+ }
+\cs_new_protected_nopar:Npn \file_input:n #1
+ {
+ \file_add_path:nN {#1} \l_file_name_tl
+ \tl_if_empty:NF \l_file_name_tl
+ {
+ \@addtofilelist {#1}
+ \seq_gpush:NV \g_file_stack_seq \g_file_current_name_tl
+ \tl_gset:Nn \g_file_current_name_tl {#1}
+ \exp_after:wN \tex_input:D \l_file_name_tl ~
+ \seq_gpop:NN \g_file_stack_seq \g_file_current_name_tl
+ }
+ }
+\cs_new_protected_nopar:Npn \file_path_include:n #1
+ {
+ \seq_if_in:NnF \l_file_search_path_seq {#1}
+ { \seq_put_right:Nn \l_file_search_path_seq {#1} }
+ }
+\cs_new_protected_nopar:Npn \file_path_remove:n #1
+ { \seq_remove_all:Nn \l_file_search_path_seq {#1} }
+\cs_new_protected_nopar:Npn \file_list:
+ {
+ \seq_remove_duplicates:N \g_file_record_seq
+ \iow_log:n { *~File~List~* }
+ \seq_map_inline:Nn \g_file_record_seq { \iow_log:n {##1} }
+ \iow_log:n { ************* }
+ }
+\AtBeginDocument
+ {
+ \clist_map_inline:Nn \@filelist
+ { \seq_put_right:Nn \g_file_record_seq {#1} }
+ }
+%%
+%%
+%% End of file `l3file.sty'.
diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3fp.sty b/Master/texmf-dist/tex/latex/l3kernel/l3fp.sty
new file mode 100644
index 00000000000..d3f98d4353a
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/l3kernel/l3fp.sty
@@ -0,0 +1,3403 @@
+%%
+%% This is file `l3fp.sty',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% l3fp.dtx (with options: `package')
+%%
+%% EXPERIMENTAL CODE
+%%
+%% Do not distribute this file without also distributing the
+%% source files specified above.
+%%
+%% Do not distribute a modified version of this file.
+%%
+%% File: l3fp.dtx Copyright (C) 2010,2011 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 "expl3 bundle" (The Work in LPPL)
+%% and all files in that bundle must be distributed together.
+%%
+%% The released version of this bundle is available from CTAN.
+%%
+%% -----------------------------------------------------------------------
+%%
+%% The development version of the bundle can be found at
+%%
+%% http://www.latex-project.org/svnroot/experimental/trunk/
+%%
+%% for those people who are interested.
+%%
+%%%%%%%%%%%
+%% NOTE: %%
+%%%%%%%%%%%
+%%
+%% Snapshots taken from the repository represent work in progress and may
+%% not work or may contain conflicting material! We therefore ask
+%% people _not_ to put them into distributions, archives, etc. without
+%% prior consultation with the LaTeX3 Project.
+%%
+%% -----------------------------------------------------------------------
+\RequirePackage{l3names}
+\GetIdInfo$Id: l3fp.dtx 2478 2011-06-19 21:34:23Z joseph $
+ {L3 Experimental floating-point operations}
+\ProvidesExplPackage
+ {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
+\package_check_loaded_expl:
+\int_const:Nn \c_forty_four { 44 }
+\int_const:Nn \c_one_million { 1 000 000 }
+\int_const:Nn \c_one_hundred_million { 100 000 000 }
+\int_const:Nn \c_five_hundred_million { 500 000 000 }
+\int_const:Nn \c_one_thousand_million { 1 000 000 000 }
+\int_new:N \c_fp_pi_by_four_decimal_int
+\int_set:Nn \c_fp_pi_by_four_decimal_int { 785 398 158 }
+\int_new:N \c_fp_pi_by_four_extended_int
+\int_set:Nn \c_fp_pi_by_four_extended_int { 897 448 310 }
+\int_new:N \c_fp_pi_decimal_int
+\int_set:Nn \c_fp_pi_decimal_int { 141 592 653 }
+\int_new:N \c_fp_pi_extended_int
+\int_set:Nn \c_fp_pi_extended_int { 589 793 238 }
+\int_new:N \c_fp_two_pi_decimal_int
+\int_set:Nn \c_fp_two_pi_decimal_int { 283 185 307 }
+\int_new:N \c_fp_two_pi_extended_int
+\int_set:Nn \c_fp_two_pi_extended_int { 179 586 477 }
+\tl_const:Nn \c_e_fp { + 2.718281828 e 0 }
+\tl_const:Nn \c_one_fp { + 1.000000000 e 0 }
+\tl_const:Nn \c_pi_fp { + 3.141592654 e 0 }
+\tl_const:Nn \c_undefined_fp { X 0.000000000 e 0 }
+\tl_const:Nn \c_zero_fp { + 0.000000000 e 0 }
+\tl_new:N \l_fp_arg_tl
+\int_new:N \l_fp_count_int
+\int_new:N \l_fp_div_offset_int
+\int_new:N \l_fp_exp_integer_int
+\int_new:N \l_fp_exp_decimal_int
+\int_new:N \l_fp_exp_extended_int
+\int_new:N \l_fp_exp_exponent_int
+\int_new:N \l_fp_input_a_sign_int
+\int_new:N \l_fp_input_a_integer_int
+\int_new:N \l_fp_input_a_decimal_int
+\int_new:N \l_fp_input_a_exponent_int
+\int_new:N \l_fp_input_b_sign_int
+\int_new:N \l_fp_input_b_integer_int
+\int_new:N \l_fp_input_b_decimal_int
+\int_new:N \l_fp_input_b_exponent_int
+\int_new:N \l_fp_input_a_extended_int
+\int_new:N \l_fp_input_b_extended_int
+\int_new:N \l_fp_mul_a_i_int
+\int_new:N \l_fp_mul_a_ii_int
+\int_new:N \l_fp_mul_a_iii_int
+\int_new:N \l_fp_mul_a_iv_int
+\int_new:N \l_fp_mul_a_v_int
+\int_new:N \l_fp_mul_a_vi_int
+\int_new:N \l_fp_mul_b_i_int
+\int_new:N \l_fp_mul_b_ii_int
+\int_new:N \l_fp_mul_b_iii_int
+\int_new:N \l_fp_mul_b_iv_int
+\int_new:N \l_fp_mul_b_v_int
+\int_new:N \l_fp_mul_b_vi_int
+\int_new:N \l_fp_mul_output_int
+\tl_new:N \l_fp_mul_output_tl
+\int_new:N \l_fp_output_sign_int
+\int_new:N \l_fp_output_integer_int
+\int_new:N \l_fp_output_decimal_int
+\int_new:N \l_fp_output_exponent_int
+\int_new:N \l_fp_output_extended_int
+\bool_new:N \l_fp_round_carry_bool
+\tl_new:N \l_fp_round_decimal_tl
+\int_new:N \l_fp_round_position_int
+\int_new:N \l_fp_round_target_int
+\tl_new:N \l_fp_sign_tl
+\int_new:N \l_fp_split_sign_int
+\int_new:N \l_fp_tmp_int
+\tl_new:N \l_fp_tmp_tl
+\int_new:N \l_fp_trig_octant_int
+\int_new:N \l_fp_trig_sign_int
+\int_new:N \l_fp_trig_decimal_int
+\int_new:N \l_fp_trig_extended_int
+\cs_new_protected_nopar:Npn \fp_read:N #1
+ { \exp_after:wN \fp_read_aux:w #1 \q_stop }
+\cs_new_protected_nopar:Npn \fp_read_aux:w #1#2 . #3 e #4 \q_stop
+ {
+ \if:w #1 -
+ \l_fp_input_a_sign_int \c_minus_one
+ \else:
+ \l_fp_input_a_sign_int \c_one
+ \fi:
+ \l_fp_input_a_integer_int #2 \scan_stop:
+ \l_fp_input_a_decimal_int #3 \scan_stop:
+ \l_fp_input_a_exponent_int #4 \scan_stop:
+ }
+\cs_new_protected_nopar:Npn \fp_split:Nn #1#2
+ {
+ \tl_set:Nx \l_fp_tmp_tl {#2}
+ \tl_set_rescan:Nno \l_fp_tmp_tl { \char_set_catcode_ignore:n { 32 } }
+ { \l_fp_tmp_tl }
+ \l_fp_split_sign_int \c_one
+ \fp_split_sign:
+ \use:c { l_fp_input_ #1 _sign_int } \l_fp_split_sign_int
+ \exp_after:wN \fp_split_exponent:w \l_fp_tmp_tl e e \q_stop #1
+ }
+\cs_new_protected_nopar:Npn \fp_split_sign:
+ {
+ \if_int_compare:w \pdftex_strcmp:D
+ { \exp_after:wN \tl_head:w \l_fp_tmp_tl ? \q_stop } { - }
+ = \c_zero
+ \tl_set:Nx \l_fp_tmp_tl
+ {
+ \exp_after:wN
+ \tl_tail:w \l_fp_tmp_tl \prg_do_nothing: \q_stop
+ }
+ \l_fp_split_sign_int -\l_fp_split_sign_int
+ \exp_after:wN \fp_split_sign:
+ \else:
+ \if_int_compare:w \pdftex_strcmp:D
+ { \exp_after:wN \tl_head:w \l_fp_tmp_tl ? \q_stop } { + }
+ = \c_zero
+ \tl_set:Nx \l_fp_tmp_tl
+ {
+ \exp_after:wN
+ \tl_tail:w \l_fp_tmp_tl \prg_do_nothing: \q_stop
+ }
+ \exp_after:wN \exp_after:wN \exp_after:wN \fp_split_sign:
+ \fi:
+ \fi:
+ }
+\cs_new_protected_nopar:Npn \fp_split_exponent:w #1 e #2 e #3 \q_stop #4
+ {
+ \use:c { l_fp_input_ #4 _exponent_int }
+ \int_eval:w 0 #2 \scan_stop:
+ \tex_afterassignment:D \fp_split_aux_i:w
+ \use:c { l_fp_input_ #4 _integer_int }
+ \int_eval:w 0 #1 . . \q_stop #4
+ }
+\cs_new_protected_nopar:Npn \fp_split_aux_i:w #1 . #2 . #3 \q_stop
+ { \fp_split_aux_ii:w #2 000000000 \q_stop }
+\cs_new_protected_nopar:Npn \fp_split_aux_ii:w #1#2#3#4#5#6#7#8#9
+ { \fp_split_aux_iii:w {#1#2#3#4#5#6#7#8#9} }
+\cs_new_protected_nopar:Npn \fp_split_aux_iii:w #1#2 \q_stop
+ {
+ \l_fp_tmp_int 1 #1 \scan_stop:
+ \exp_after:wN \fp_split_decimal:w
+ \int_use:N \l_fp_tmp_int 000000000 \q_stop
+ }
+\cs_new_protected_nopar:Npn \fp_split_decimal:w #1#2#3#4#5#6#7#8#9
+ { \fp_split_decimal_aux:w {#2#3#4#5#6#7#8#9} }
+\cs_new_protected_nopar:Npn \fp_split_decimal_aux:w #1#2#3 \q_stop #4
+ {
+ \use:c { l_fp_input_ #4 _decimal_int } #1#2 \scan_stop:
+ \if_int_compare:w
+ \int_eval:w
+ \use:c { l_fp_input_ #4 _integer_int } +
+ \use:c { l_fp_input_ #4 _decimal_int }
+ \scan_stop:
+ = \c_zero
+ \use:c { l_fp_input_ #4 _sign_int } \c_one
+ \fi:
+ \if_int_compare:w
+ \use:c { l_fp_input_ #4 _integer_int } < \c_one_thousand_million
+ \else:
+ \exp_after:wN \fp_overflow_msg:
+ \fi:
+ }
+\cs_new_protected_nopar:Npn \fp_standardise:NNNN #1#2#3#4
+ {
+ \if_int_compare:w
+ \int_eval:w #2 + #3 = \c_zero
+ #1 \c_one
+ #4 \c_zero
+ \exp_after:wN \use_none:nnnn
+ \else:
+ \exp_after:wN \fp_standardise_aux:NNNN
+ \fi:
+ #1#2#3#4
+ }
+\cs_new_protected_nopar:Npn \fp_standardise_aux:NNNN #1#2#3#4
+ {
+ \cs_set_protected_nopar:Npn \fp_standardise_aux:
+ {
+ \if_int_compare:w #2 = \c_zero
+ \tex_advance:D #3 \c_one_thousand_million
+ \exp_after:wN \fp_standardise_aux:w
+ \int_use:N #3 \q_stop
+ \exp_after:wN \fp_standardise_aux:
+ \fi:
+ }
+ \cs_set_protected_nopar:Npn
+ \fp_standardise_aux:w ##1##2##3##4##5##6##7##8##9 \q_stop
+ {
+ #2 ##2 \scan_stop:
+ #3 ##3##4##5##6##7##8##9 0 \scan_stop:
+ \tex_advance:D #4 \c_minus_one
+ }
+ \fp_standardise_aux:
+ \cs_set_protected_nopar:Npn \fp_standardise_aux:
+ {
+ \if_int_compare:w #2 > \c_nine
+ \tex_advance:D #2 \c_one_thousand_million
+ \exp_after:wN \use_i:nn \exp_after:wN
+ \fp_standardise_aux:w \int_use:N #2
+ \exp_after:wN \fp_standardise_aux:
+ \fi:
+ }
+ \cs_set_protected_nopar:Npn
+ \fp_standardise_aux:w ##1##2##3##4##5##6##7##8##9
+ {
+ #2 ##1##2##3##4##5##6##7##8 \scan_stop:
+ \tex_advance:D #3 \c_one_thousand_million
+ \tex_divide:D #3 \c_ten
+ \tl_set:Nx \l_fp_tmp_tl
+ {
+ ##9
+ \exp_after:wN \use_none:n \int_use:N #3
+ }
+ #3 \l_fp_tmp_tl \scan_stop:
+ \tex_advance:D #4 \c_one
+ }
+ \fp_standardise_aux:
+ \if_int_compare:w #4 < \c_one_hundred
+ \if_int_compare:w #4 > -\c_one_hundred
+ \else:
+ #1 \c_one
+ #2 \c_zero
+ #3 \c_zero
+ #4 \c_zero
+ \fi:
+ \else:
+ \exp_after:wN \fp_overflow_msg:
+ \fi:
+ }
+\cs_new_protected_nopar:Npn \fp_standardise_aux: { }
+\cs_new_protected_nopar:Npn \fp_standardise_aux:w { }
+\cs_new_protected_nopar:Npn \fp_level_input_exponents:
+ {
+ \if_int_compare:w \l_fp_input_a_exponent_int > \l_fp_input_b_exponent_int
+ \exp_after:wN \fp_level_input_exponents_a:
+ \else:
+ \exp_after:wN \fp_level_input_exponents_b:
+ \fi:
+ }
+\cs_new_protected_nopar:Npn \fp_level_input_exponents_a:
+ {
+ \if_int_compare:w \l_fp_input_a_exponent_int > \l_fp_input_b_exponent_int
+ \tex_advance:D \l_fp_input_b_integer_int \c_one_thousand_million
+ \exp_after:wN \use_i:nn \exp_after:wN
+ \fp_level_input_exponents_a:NNNNNNNNN
+ \int_use:N \l_fp_input_b_integer_int
+ \exp_after:wN \fp_level_input_exponents_a:
+ \fi:
+ }
+\cs_new_protected_nopar:Npn \fp_level_input_exponents_a:NNNNNNNNN
+ #1#2#3#4#5#6#7#8#9
+ {
+ \l_fp_input_b_integer_int #1#2#3#4#5#6#7#8 \scan_stop:
+ \tex_advance:D \l_fp_input_b_decimal_int \c_one_thousand_million
+ \tex_divide:D \l_fp_input_b_decimal_int \c_ten
+ \tl_set:Nx \l_fp_tmp_tl
+ {
+ #9
+ \exp_after:wN \use_none:n
+ \int_use:N \l_fp_input_b_decimal_int
+ }
+ \l_fp_input_b_decimal_int \l_fp_tmp_tl \scan_stop:
+ \tex_advance:D \l_fp_input_b_exponent_int \c_one
+ }
+\cs_new_protected_nopar:Npn \fp_level_input_exponents_b:
+ {
+ \if_int_compare:w \l_fp_input_b_exponent_int > \l_fp_input_a_exponent_int
+ \tex_advance:D \l_fp_input_a_integer_int \c_one_thousand_million
+ \exp_after:wN \use_i:nn \exp_after:wN
+ \fp_level_input_exponents_b:NNNNNNNNN
+ \int_use:N \l_fp_input_a_integer_int
+ \exp_after:wN \fp_level_input_exponents_b:
+ \fi:
+ }
+\cs_new_protected_nopar:Npn \fp_level_input_exponents_b:NNNNNNNNN
+ #1#2#3#4#5#6#7#8#9
+ {
+ \l_fp_input_a_integer_int #1#2#3#4#5#6#7#8 \scan_stop:
+ \tex_advance:D \l_fp_input_a_decimal_int \c_one_thousand_million
+ \tex_divide:D \l_fp_input_a_decimal_int \c_ten
+ \tl_set:Nx \l_fp_tmp_tl
+ {
+ #9
+ \exp_after:wN \use_none:n
+ \int_use:N \l_fp_input_a_decimal_int
+ }
+ \l_fp_input_a_decimal_int \l_fp_tmp_tl \scan_stop:
+ \tex_advance:D \l_fp_input_a_exponent_int \c_one
+ }
+\cs_new_protected_nopar:Npn \fp_tmp:w #1#2 { }
+\cs_new_protected_nopar:Npn \fp_new:N #1
+ {
+ \tl_new:N #1
+ \tl_gset_eq:NN #1 \c_zero_fp
+ }
+\cs_generate_variant:Nn \fp_new:N { c }
+\cs_new_protected_nopar:Npn \fp_const:Nn #1#2
+ {
+ \fp_new:N #1
+ \fp_gset:Nn #1 {#2}
+ }
+\cs_generate_variant:Nn \fp_const:Nn { c }
+\cs_new_protected_nopar:Npn \fp_zero:N #1
+ { \tl_set_eq:NN #1 \c_zero_fp }
+\cs_new_protected_nopar:Npn \fp_gzero:N #1
+ { \tl_gset_eq:NN #1 \c_zero_fp }
+\cs_generate_variant:Nn \fp_zero:N { c }
+\cs_generate_variant:Nn \fp_gzero:N { c }
+\cs_new_protected_nopar:Npn \fp_set:Nn { \fp_set_aux:NNn \tl_set:Nn }
+\cs_new_protected_nopar:Npn \fp_gset:Nn { \fp_set_aux:NNn \tl_gset:Nn }
+\cs_new_protected_nopar:Npn \fp_set_aux:NNn #1#2#3
+ {
+ \group_begin:
+ \fp_split:Nn a {#3}
+ \fp_standardise:NNNN
+ \l_fp_input_a_sign_int
+ \l_fp_input_a_integer_int
+ \l_fp_input_a_decimal_int
+ \l_fp_input_a_exponent_int
+ \tex_advance:D \l_fp_input_a_decimal_int \c_one_thousand_million
+ \cs_set_protected_nopar:Npx \fp_tmp:w
+ {
+ \group_end:
+ #1 \exp_not:N #2
+ {
+ \if_int_compare:w \l_fp_input_a_sign_int < \c_zero
+ -
+ \else:
+ +
+ \fi:
+ \int_use:N \l_fp_input_a_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \int_use:N \l_fp_input_a_decimal_int
+ e
+ \int_use:N \l_fp_input_a_exponent_int
+ }
+ }
+ \fp_tmp:w
+ }
+\cs_generate_variant:Nn \fp_set:Nn { c }
+\cs_generate_variant:Nn \fp_gset:Nn { c }
+\cs_new_protected_nopar:Npn \fp_set_from_dim:Nn
+ { \fp_set_from_dim_aux:NNn \tl_set:Nx }
+\cs_new_protected_nopar:Npn \fp_gset_from_dim:Nn
+ { \fp_set_from_dim_aux:NNn \tl_gset:Nx }
+\cs_new_protected_nopar:Npn \fp_set_from_dim_aux:NNn #1#2#3
+ {
+ \group_begin:
+ \l_fp_tmp_skip \etex_glueexpr:D #3 \scan_stop:
+ \l_fp_tmp_dim \l_fp_tmp_skip
+ \fp_split:Nn a
+ {
+ \exp_after:wN \fp_set_from_dim_aux:w
+ \dim_use:N \l_fp_tmp_dim
+ }
+ \fp_standardise:NNNN
+ \l_fp_input_a_sign_int
+ \l_fp_input_a_integer_int
+ \l_fp_input_a_decimal_int
+ \l_fp_input_a_exponent_int
+ \tex_advance:D \l_fp_input_a_decimal_int \c_one_thousand_million
+ \cs_set_protected_nopar:Npx \fp_tmp:w
+ {
+ \group_end:
+ #1 \exp_not:N #2
+ {
+ \if_int_compare:w \l_fp_input_a_sign_int < \c_zero
+ -
+ \else:
+ +
+ \fi:
+ \int_use:N \l_fp_input_a_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \int_use:N \l_fp_input_a_decimal_int
+ e
+ \int_use:N \l_fp_input_a_exponent_int
+ }
+ }
+ \fp_tmp:w
+ }
+\cs_set_protected_nopar:Npx \fp_set_from_dim_aux:w
+ {
+ \cs_set_nopar:Npn \exp_not:N \fp_set_from_dim_aux:w
+ ##1 \tl_to_str:n { pt } {##1}
+ }
+\fp_set_from_dim_aux:w
+\cs_generate_variant:Nn \fp_set_from_dim:Nn { c }
+\cs_generate_variant:Nn \fp_gset_from_dim:Nn { c }
+\dim_new:N \l_fp_tmp_dim
+\skip_new:N \l_fp_tmp_skip
+\cs_new_eq:NN \fp_set_eq:NN \tl_set_eq:NN
+\cs_new_eq:NN \fp_set_eq:cN \tl_set_eq:cN
+\cs_new_eq:NN \fp_set_eq:Nc \tl_set_eq:Nc
+\cs_new_eq:NN \fp_set_eq:cc \tl_set_eq:cc
+\cs_new_eq:NN \fp_gset_eq:NN \tl_gset_eq:NN
+\cs_new_eq:NN \fp_gset_eq:cN \tl_gset_eq:cN
+\cs_new_eq:NN \fp_gset_eq:Nc \tl_gset_eq:Nc
+\cs_new_eq:NN \fp_gset_eq:cc \tl_gset_eq:cc
+\cs_new_eq:NN \fp_show:N \tl_show:N
+\cs_new_eq:NN \fp_show:c \tl_show:c
+\cs_new_nopar:Npn \fp_use:N #1
+ { \exp_after:wN \fp_use_aux:w #1 \q_stop }
+\cs_generate_variant:Nn \fp_use:N { c }
+\cs_new_nopar:Npn \fp_use_aux:w #1#2 e #3 \q_stop
+ {
+ \if:w #1 -
+ -
+ \fi:
+ \if_int_compare:w #3 > \c_zero
+ \exp_after:wN \fp_use_large:w
+ \else:
+ \if_int_compare:w #3 < \c_zero
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \fp_use_small:w
+ \else:
+ \exp_after:wN \exp_after:wN \exp_after:wN \fp_use_none:w
+ \fi:
+ \fi:
+ #2 e #3 \q_stop
+ }
+\cs_new_nopar:Npn \fp_use_none:w #1 e #2 \q_stop {#1}
+\cs_new_nopar:Npn \fp_use_small:w #1 . #2 e #3 \q_stop
+ {
+ 0 .
+ \prg_replicate:nn { -#3 - 1 } { 0 }
+ #1#2
+ }
+\cs_new_nopar:Npn \fp_use_large:w #1 . #2 e #3 \q_stop
+ {
+ \if_int_compare:w #3 < \c_ten
+ \exp_after:wN \fp_use_large_aux_i:w
+ \else:
+ \exp_after:wN \fp_use_large_aux_ii:w
+ \fi:
+ #1#2 e #3 \q_stop
+ }
+\cs_new_nopar:Npn \fp_use_large_aux_i:w #1#2 e #3 \q_stop
+ {
+ #1
+ \use:c { fp_use_large_aux_ #3 :w } #2 \q_stop
+ }
+\cs_new_nopar:cpn { fp_use_large_aux_1:w } #1#2 \q_stop { #1 . #2 }
+\cs_new_nopar:cpn { fp_use_large_aux_2:w } #1#2#3 \q_stop
+ { #1#2 . #3 }
+\cs_new_nopar:cpn { fp_use_large_aux_3:w } #1#2#3#4 \q_stop
+ { #1#2#3 . #4 }
+\cs_new_nopar:cpn { fp_use_large_aux_4:w } #1#2#3#4#5 \q_stop
+ { #1#2#3#4 . #5 }
+\cs_new_nopar:cpn { fp_use_large_aux_5:w } #1#2#3#4#5#6 \q_stop
+ { #1#2#3#4#5 . #6 }
+\cs_new_nopar:cpn { fp_use_large_aux_6:w } #1#2#3#4#5#6#7 \q_stop
+ { #1#2#3#4#5#6 . #7 }
+\cs_new_nopar:cpn { fp_use_large_aux_7:w } #1#2#3#4#5#6#7#8 \q_stop
+ { #1#2#3#4#6#7 . #8 }
+\cs_new_nopar:cpn { fp_use_large_aux_8:w } #1#2#3#4#5#6#7#8#9 \q_stop
+ { #1#2#3#4#5#6#7#8 . #9 }
+\cs_new_nopar:cpn { fp_use_large_aux_9:w } #1 \q_stop { #1 . }
+\cs_new_nopar:Npn \fp_use_large_aux_ii:w #1 e #2 \q_stop
+ {
+ #1
+ \prg_replicate:nn { #2 - 9 } { 0 }
+ .
+ }
+\cs_new_nopar:Npn \fp_to_dim:N #1 { \fp_use:N #1 pt }
+\cs_generate_variant:Nn \fp_to_dim:N { c }
+\cs_new_nopar:Npn \fp_to_int:N #1
+ { \exp_after:wN \fp_to_int_aux:w #1 \q_stop }
+\cs_generate_variant:Nn \fp_to_int:N { c }
+\cs_new_nopar:Npn \fp_to_int_aux:w #1#2 e #3 \q_stop
+ {
+ \if:w #1 -
+ -
+ \fi:
+ \if_int_compare:w #3 < \c_zero
+ \exp_after:wN \fp_to_int_small:w
+ \else:
+ \exp_after:wN \fp_to_int_large:w
+ \fi:
+ #2 e #3 \q_stop
+ }
+\cs_new_nopar:Npn \fp_to_int_small:w #1 . #2 e #3 \q_stop
+ {
+ \if_int_compare:w #3 > \c_one
+ \else:
+ \if_int_compare:w #1 < \c_five
+ 0
+ \else:
+ 1
+ \fi:
+ \fi:
+ }
+\cs_new_nopar:Npn \fp_to_int_large:w #1 . #2 e #3 \q_stop
+ {
+ \if_int_compare:w #3 < \c_ten
+ \exp_after:wN \fp_to_int_large_aux_i:w
+ \else:
+ \exp_after:wN \fp_to_int_large_aux_ii:w
+ \fi:
+ #1#2 e #3 \q_stop
+ }
+\cs_new_nopar:Npn \fp_to_int_large_aux_i:w #1#2 e #3 \q_stop
+ { \use:c { fp_to_int_large_aux_ #3 :w } #2 \q_stop {#1} }
+\cs_new_nopar:cpn { fp_to_int_large_aux_1:w } #1#2 \q_stop
+ { \fp_to_int_large_aux:nnn { #2 0 } {#1} }
+\cs_new_nopar:cpn { fp_to_int_large_aux_2:w } #1#2#3 \q_stop
+ { \fp_to_int_large_aux:nnn { #3 00 } {#1#2} }
+\cs_new_nopar:cpn { fp_to_int_large_aux_3:w } #1#2#3#4 \q_stop
+ { \fp_to_int_large_aux:nnn { #4 000 } {#1#2#3} }
+\cs_new_nopar:cpn { fp_to_int_large_aux_4:w } #1#2#3#4#5 \q_stop
+ { \fp_to_int_large_aux:nnn { #5 0000 } {#1#2#3#4} }
+\cs_new_nopar:cpn { fp_to_int_large_aux_5:w } #1#2#3#4#5#6 \q_stop
+ { \fp_to_int_large_aux:nnn { #6 00000 } {#1#2#3#4#5} }
+\cs_new_nopar:cpn { fp_to_int_large_aux_6:w } #1#2#3#4#5#6#7 \q_stop
+ { \fp_to_int_large_aux:nnn { #7 000000 } {#1#2#3#4#5#6} }
+\cs_new_nopar:cpn { fp_to_int_large_aux_7:w } #1#2#3#4#5#6#7#8 \q_stop
+ { \fp_to_int_large_aux:nnn { #8 0000000 } {#1#2#3#4#5#6#7} }
+\cs_new_nopar:cpn { fp_to_int_large_aux_8:w } #1#2#3#4#5#6#7#8#9 \q_stop
+ { \fp_to_int_large_aux:nnn { #9 00000000 } {#1#2#3#4#5#6#7#8} }
+\cs_new_nopar:cpn { fp_to_int_large_aux_9:w } #1 \q_stop {#1}
+\cs_new_nopar:Npn \fp_to_int_large_aux:nnn #1#2#3
+ {
+ \if_int_compare:w #1 < \c_five_hundred_million
+ #3#2
+ \else:
+ \int_value:w \int_eval:w #3#2 + 1 \int_eval_end:
+ \fi:
+ }
+\cs_new_nopar:Npn \fp_to_int_large_aux_ii:w #1 e #2 \q_stop
+ {
+ #1
+ \prg_replicate:nn { #2 - 9 } { 0 }
+ }
+\cs_new_nopar:Npn \fp_to_tl:N #1
+ { \exp_after:wN \fp_to_tl_aux:w #1 \q_stop }
+\cs_generate_variant:Nn \fp_to_tl:N { c }
+\cs_new_nopar:Npn \fp_to_tl_aux:w #1#2 e #3 \q_stop
+ {
+ \if:w #1 -
+ -
+ \fi:
+ \if_int_compare:w #3 < \c_zero
+ \exp_after:wN \fp_to_tl_small:w
+ \else:
+ \exp_after:wN \fp_to_tl_large:w
+ \fi:
+ #2 e #3 \q_stop
+ }
+\cs_new_nopar:Npn \fp_to_tl_large:w #1 e #2 \q_stop
+ {
+ \if_int_compare:w #2 < \c_ten
+ \exp_after:wN \fp_to_tl_large_aux_i:w
+ \else:
+ \exp_after:wN \fp_to_tl_large_aux_ii:w
+ \fi:
+ #1 e #2 \q_stop
+ }
+\cs_new_nopar:Npn \fp_to_tl_large_aux_i:w #1 e #2 \q_stop
+ { \use:c { fp_to_tl_large_ #2 :w } #1 \q_stop }
+\cs_new_nopar:Npn \fp_to_tl_large_aux_ii:w #1 . #2 e #3 \q_stop
+ {
+ #1
+ \fp_to_tl_large_zeros:NNNNNNNNN #2
+ e #3
+ }
+\cs_new_nopar:cpn { fp_to_tl_large_0:w } #1 . #2 \q_stop
+ {
+ #1
+ \fp_to_tl_large_zeros:NNNNNNNNN #2
+ }
+\cs_new_nopar:cpn { fp_to_tl_large_1:w } #1 . #2#3 \q_stop
+ {
+ #1#2
+ \fp_to_tl_large_zeros:NNNNNNNNN #3 0
+ }
+\cs_new_nopar:cpn { fp_to_tl_large_2:w } #1 . #2#3#4 \q_stop
+ {
+ #1#2#3
+ \fp_to_tl_large_zeros:NNNNNNNNN #4 00
+ }
+\cs_new_nopar:cpn { fp_to_tl_large_3:w } #1 . #2#3#4#5 \q_stop
+ {
+ #1#2#3#4
+ \fp_to_tl_large_zeros:NNNNNNNNN #5 000
+ }
+\cs_new_nopar:cpn { fp_to_tl_large_4:w } #1 . #2#3#4#5#6 \q_stop
+ {
+ #1#2#3#4#5
+ \fp_to_tl_large_zeros:NNNNNNNNN #6 0000
+ }
+\cs_new_nopar:cpn { fp_to_tl_large_5:w } #1 . #2#3#4#5#6#7 \q_stop
+ {
+ #1#2#3#4#5#6
+ \fp_to_tl_large_zeros:NNNNNNNNN #7 00000
+ }
+\cs_new_nopar:cpn { fp_to_tl_large_6:w } #1 . #2#3#4#5#6#7#8 \q_stop
+ {
+ #1#2#3#4#5#6#7
+ \fp_to_tl_large_zeros:NNNNNNNNN #8 000000
+ }
+\cs_new_nopar:cpn { fp_to_tl_large_7:w } #1 . #2#3#4#5#6#7#8#9 \q_stop
+ {
+ #1#2#3#4#5#6#7#8
+ \fp_to_tl_large_zeros:NNNNNNNNN #9 0000000
+ }
+\cs_new_nopar:cpn { fp_to_tl_large_8:w } #1 .
+ {
+ #1
+ \use:c { fp_to_tl_large_8_aux:w }
+ }
+\cs_new_nopar:cpn { fp_to_tl_large_8_aux:w } #1#2#3#4#5#6#7#8#9 \q_stop
+ {
+ #1#2#3#4#5#6#7#8
+ \fp_to_tl_large_zeros:NNNNNNNNN #9 00000000
+ }
+\cs_new_nopar:cpn { fp_to_tl_large_9:w } #1 . #2 \q_stop {#1#2}
+\cs_new_nopar:Npn \fp_to_tl_small:w #1 e #2 \q_stop
+ {
+ \if_int_compare:w #2 = \c_minus_one
+ \exp_after:wN \fp_to_tl_small_one:w
+ \else:
+ \if_int_compare:w #2 = -\c_two
+ \exp_after:wN \exp_after:wN \exp_after:wN \fp_to_tl_small_two:w
+ \else:
+ \exp_after:wN \exp_after:wN \exp_after:wN \fp_to_tl_small_aux:w
+ \fi:
+ \fi:
+ #1 e #2 \q_stop
+ }
+\cs_new_nopar:Npn \fp_to_tl_small_one:w #1 . #2 e #3 \q_stop
+ {
+ \if_int_compare:w \fp_use_ix:NNNNNNNNN #2 > \c_four
+ \if_int_compare:w
+ \int_eval:w #1 \fp_use_i_to_iix:NNNNNNNNN #2 + 1
+ < \c_one_thousand_million
+ 0.
+ \exp_after:wN \fp_to_tl_small_zeros:NNNNNNNNN
+ \int_value:w \int_eval:w
+ #1 \fp_use_i_to_iix:NNNNNNNNN #2 + 1
+ \int_eval_end:
+ \else:
+ 1
+ \fi:
+ \else:
+ 0. #1
+ \fp_to_tl_small_zeros:NNNNNNNNN #2
+ \fi:
+ }
+\cs_new_nopar:Npn \fp_to_tl_small_two:w #1 . #2 e #3 \q_stop
+ {
+ \if_int_compare:w \fp_use_iix_ix:NNNNNNNNN #2 > \c_forty_four
+ \if_int_compare:w
+ \int_eval:w #1 \fp_use_i_to_vii:NNNNNNNNN #2 0 + \c_ten
+ < \c_one_thousand_million
+ 0.0
+ \exp_after:wN \fp_to_tl_small_zeros:NNNNNNNNN
+ \int_value:w \int_eval:w
+ #1 \fp_use_i_to_vii:NNNNNNNNN #2 0 + \c_ten
+ \int_eval_end:
+ \else:
+ 0.1
+ \fi:
+ \else:
+ 0.0
+ #1
+ \fp_to_tl_small_zeros:NNNNNNNNN #2
+ \fi:
+ }
+\cs_new_nopar:Npn \fp_to_tl_small_aux:w #1 . #2 e #3 \q_stop
+ {
+ #1
+ \fp_to_tl_large_zeros:NNNNNNNNN #2
+ e #3
+ }
+\cs_new_nopar:Npn \fp_to_tl_large_zeros:NNNNNNNNN #1#2#3#4#5#6#7#8#9
+ {
+ \if_int_compare:w #9 = \c_zero
+ \if_int_compare:w #8 = \c_zero
+ \if_int_compare:w #7 = \c_zero
+ \if_int_compare:w #6 = \c_zero
+ \if_int_compare:w #5 = \c_zero
+ \if_int_compare:w #4 = \c_zero
+ \if_int_compare:w #3 = \c_zero
+ \if_int_compare:w #2 = \c_zero
+ \if_int_compare:w #1 = \c_zero
+ \else:
+ . #1
+ \fi:
+ \else:
+ . #1#2
+ \fi:
+ \else:
+ . #1#2#3
+ \fi:
+ \else:
+ . #1#2#3#4
+ \fi:
+ \else:
+ . #1#2#3#4#5
+ \fi:
+ \else:
+ . #1#2#3#4#5#6
+ \fi:
+ \else:
+ . #1#2#3#4#5#6#7
+ \fi:
+ \else:
+ . #1#2#3#4#5#6#7#8
+ \fi:
+ \else:
+ . #1#2#3#4#5#6#7#8#9
+ \fi:
+ }
+\cs_new_nopar:Npn \fp_to_tl_small_zeros:NNNNNNNNN #1#2#3#4#5#6#7#8#9
+ {
+ \if_int_compare:w #9 = \c_zero
+ \if_int_compare:w #8 = \c_zero
+ \if_int_compare:w #7 = \c_zero
+ \if_int_compare:w #6 = \c_zero
+ \if_int_compare:w #5 = \c_zero
+ \if_int_compare:w #4 = \c_zero
+ \if_int_compare:w #3 = \c_zero
+ \if_int_compare:w #2 = \c_zero
+ \if_int_compare:w #1 = \c_zero
+ \else:
+ #1
+ \fi:
+ \else:
+ #1#2
+ \fi:
+ \else:
+ #1#2#3
+ \fi:
+ \else:
+ #1#2#3#4
+ \fi:
+ \else:
+ #1#2#3#4#5
+ \fi:
+ \else:
+ #1#2#3#4#5#6
+ \fi:
+ \else:
+ #1#2#3#4#5#6#7
+ \fi:
+ \else:
+ #1#2#3#4#5#6#7#8
+ \fi:
+ \else:
+ #1#2#3#4#5#6#7#8#9
+ \fi:
+ }
+\cs_new_nopar:Npn \fp_use_iix_ix:NNNNNNNNN #1#2#3#4#5#6#7#8#9 {#8#9}
+\cs_new_nopar:Npn \fp_use_ix:NNNNNNNNN #1#2#3#4#5#6#7#8#9 {#9}
+\cs_new_nopar:Npn \fp_use_i_to_vii:NNNNNNNNN #1#2#3#4#5#6#7#8#9
+ {#1#2#3#4#5#6#7}
+\cs_new_nopar:Npn \fp_use_i_to_iix:NNNNNNNNN #1#2#3#4#5#6#7#8#9
+ {#1#2#3#4#5#6#7#8}
+\cs_new_protected_nopar:Npn \fp_round_figures:Nn
+ { \fp_round_figures_aux:NNn \tl_set:Nn }
+\cs_generate_variant:Nn \fp_round_figures:Nn { c }
+\cs_new_protected_nopar:Npn \fp_ground_figures:Nn
+ { \fp_round_figures_aux:NNn \tl_gset:Nn }
+\cs_generate_variant:Nn \fp_ground_figures:Nn { c }
+\cs_new_protected_nopar:Npn \fp_round_figures_aux:NNn #1#2#3
+ {
+ \group_begin:
+ \fp_read:N #2
+ \int_set:Nn \l_fp_round_target_int { #3 - 1 }
+ \if_int_compare:w \l_fp_round_target_int < \c_ten
+ \exp_after:wN \fp_round:
+ \fi:
+ \tex_advance:D \l_fp_input_a_decimal_int \c_one_thousand_million
+ \cs_set_protected_nopar:Npx \fp_tmp:w
+ {
+ \group_end:
+ #1 \exp_not:N #2
+ {
+ \if_int_compare:w \l_fp_input_a_sign_int < \c_zero
+ -
+ \else:
+ +
+ \fi:
+ \int_use:N \l_fp_input_a_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \int_use:N \l_fp_input_a_decimal_int
+ e
+ \int_use:N \l_fp_input_a_exponent_int
+ }
+ }
+ \fp_tmp:w
+ }
+\cs_new_protected_nopar:Npn \fp_round_places:Nn
+ { \fp_round_places_aux:NNn \tl_set:Nn }
+\cs_generate_variant:Nn \fp_round_places:Nn { c }
+\cs_new_protected_nopar:Npn \fp_ground_places:Nn
+ { \fp_round_places_aux:NNn \tl_gset:Nn }
+\cs_generate_variant:Nn \fp_ground_places:Nn { c }
+\cs_new_protected_nopar:Npn \fp_round_places_aux:NNn #1#2#3
+ {
+ \group_begin:
+ \fp_read:N #2
+ \int_set:Nn \l_fp_round_target_int
+ { #3 + \l_fp_input_a_exponent_int }
+ \if_int_compare:w \l_fp_round_target_int < \c_ten
+ \exp_after:wN \fp_round:
+ \fi:
+ \tex_advance:D \l_fp_input_a_decimal_int \c_one_thousand_million
+ \cs_set_protected_nopar:Npx \fp_tmp:w
+ {
+ \group_end:
+ #1 \exp_not:N #2
+ {
+ \if_int_compare:w \l_fp_input_a_sign_int < \c_zero
+ -
+ \else:
+ +
+ \fi:
+ \int_use:N \l_fp_input_a_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \int_use:N \l_fp_input_a_decimal_int
+ e
+ \int_use:N \l_fp_input_a_exponent_int
+ }
+ }
+ \fp_tmp:w
+ }
+\cs_new_protected_nopar:Npn \fp_round:
+ {
+ \bool_set_false:N \l_fp_round_carry_bool
+ \l_fp_round_position_int \c_eight
+ \tl_clear:N \l_fp_round_decimal_tl
+ \tex_advance:D \l_fp_input_a_decimal_int \c_one_thousand_million
+ \exp_after:wN \use_i:nn \exp_after:wN
+ \fp_round_aux:NNNNNNNNN \int_use:N \l_fp_input_a_decimal_int
+ }
+\cs_new_protected_nopar:Npn \fp_round_aux:NNNNNNNNN #1#2#3#4#5#6#7#8#9
+ {
+ \fp_round_loop:N #9#8#7#6#5#4#3#2#1
+ \bool_if:NT \l_fp_round_carry_bool
+ { \tex_advance:D \l_fp_input_a_integer_int \c_one }
+ \l_fp_input_a_decimal_int \l_fp_round_decimal_tl \scan_stop:
+ \if_int_compare:w \l_fp_input_a_integer_int < \c_ten
+ \else:
+ \l_fp_input_a_integer_int \c_one
+ \tex_divide:D \l_fp_input_a_decimal_int \c_ten
+ \tex_advance:D \l_fp_input_a_exponent_int \c_one
+ \fi:
+ }
+\cs_new_protected_nopar:Npn \fp_round_loop:N #1
+ {
+ \if_int_compare:w \l_fp_round_position_int < \l_fp_round_target_int
+ \bool_if:NTF \l_fp_round_carry_bool
+ { \l_fp_tmp_int \int_eval:w #1 + \c_one \scan_stop: }
+ { \l_fp_tmp_int \int_eval:w #1 \scan_stop: }
+ \if_int_compare:w \l_fp_tmp_int = \c_ten
+ \l_fp_tmp_int \c_zero
+ \else:
+ \bool_set_false:N \l_fp_round_carry_bool
+ \fi:
+ \tl_set:Nx \l_fp_round_decimal_tl
+ { \int_use:N \l_fp_tmp_int \l_fp_round_decimal_tl }
+ \else:
+ \tl_set:Nx \l_fp_round_decimal_tl { 0 \l_fp_round_decimal_tl }
+ \if_int_compare:w \l_fp_round_position_int = \l_fp_round_target_int
+ \if_int_compare:w #1 > \c_four
+ \bool_set_true:N \l_fp_round_carry_bool
+ \fi:
+ \fi:
+ \fi:
+ \tex_advance:D \l_fp_round_position_int \c_minus_one
+ \if_int_compare:w \l_fp_round_position_int > \c_minus_one
+ \exp_after:wN \fp_round_loop:N
+ \fi:
+ }
+\cs_new_protected_nopar:Npn \fp_abs:N { \fp_abs_aux:NN \tl_set:Nn }
+\cs_new_protected_nopar:Npn \fp_gabs:N { \fp_abs_aux:NN \tl_gset:Nn }
+\cs_generate_variant:Nn \fp_abs:N { c }
+\cs_generate_variant:Nn \fp_gabs:N { c }
+\cs_new_protected_nopar:Npn \fp_abs_aux:NN #1#2
+ {
+ \group_begin:
+ \fp_read:N #2
+ \tex_advance:D \l_fp_input_a_decimal_int \c_one_thousand_million
+ \cs_set_protected_nopar:Npx \fp_tmp:w
+ {
+ \group_end:
+ #1 \exp_not:N #2
+ {
+ +
+ \int_use:N \l_fp_input_a_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \int_use:N \l_fp_input_a_decimal_int
+ e
+ \int_use:N \l_fp_input_a_exponent_int
+ }
+ }
+ \fp_tmp:w
+ }
+\cs_new_protected_nopar:Npn \fp_neg:N { \fp_neg_aux:NN \tl_set:Nn }
+\cs_new_protected_nopar:Npn \fp_gneg:N { \fp_neg_aux:NN \tl_gset:Nn }
+\cs_generate_variant:Nn \fp_neg:N { c }
+\cs_generate_variant:Nn \fp_gneg:N { c }
+\cs_new_protected_nopar:Npn \fp_neg_aux:NN #1#2
+ {
+ \group_begin:
+ \fp_read:N #2
+ \tex_advance:D \l_fp_input_a_decimal_int \c_one_thousand_million
+ \tl_set:Nx \l_fp_tmp_tl
+ {
+ \if_int_compare:w \l_fp_input_a_sign_int < \c_zero
+ +
+ \else:
+ -
+ \fi:
+ \int_use:N \l_fp_input_a_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \int_use:N \l_fp_input_a_decimal_int
+ e
+ \int_use:N \l_fp_input_a_exponent_int
+ }
+ \exp_after:wN \group_end: \exp_after:wN
+ #1 \exp_after:wN #2 \exp_after:wN { \l_fp_tmp_tl }
+ }
+\cs_new_protected_nopar:Npn \fp_add:Nn { \fp_add_aux:NNn \tl_set:Nn }
+\cs_new_protected_nopar:Npn \fp_gadd:Nn { \fp_add_aux:NNn \tl_gset:Nn }
+\cs_generate_variant:Nn \fp_add:Nn { c }
+\cs_generate_variant:Nn \fp_gadd:Nn { c }
+\cs_new_protected_nopar:Npn \fp_add_aux:NNn #1#2#3
+ {
+ \group_begin:
+ \fp_read:N #2
+ \fp_split:Nn b {#3}
+ \fp_standardise:NNNN
+ \l_fp_input_b_sign_int
+ \l_fp_input_b_integer_int
+ \l_fp_input_b_decimal_int
+ \l_fp_input_b_exponent_int
+ \fp_add_core:
+ \fp_tmp:w #1#2
+ }
+\cs_new_protected_nopar:Npn \fp_add_core:
+ {
+ \fp_level_input_exponents:
+ \if_int_compare:w
+ \int_eval:w
+ \l_fp_input_a_sign_int * \l_fp_input_b_sign_int
+ > \c_zero
+ \exp_after:wN \fp_add_sum:
+ \else:
+ \exp_after:wN \fp_add_difference:
+ \fi:
+ \l_fp_output_exponent_int \l_fp_input_a_exponent_int
+ \fp_standardise:NNNN
+ \l_fp_output_sign_int
+ \l_fp_output_integer_int
+ \l_fp_output_decimal_int
+ \l_fp_output_exponent_int
+ \cs_set_protected_nopar:Npx \fp_tmp:w ##1##2
+ {
+ \group_end:
+ ##1 ##2
+ {
+ \if_int_compare:w \l_fp_output_sign_int < \c_zero
+ -
+ \else:
+ +
+ \fi:
+ \int_use:N \l_fp_output_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \int_value:w \int_eval:w
+ \l_fp_output_decimal_int + \c_one_thousand_million
+ e
+ \int_use:N \l_fp_output_exponent_int
+ }
+ }
+ }
+\cs_new_protected_nopar:Npn \fp_add_sum:
+ {
+ \l_fp_output_sign_int \l_fp_input_a_sign_int
+ \l_fp_output_integer_int
+ \int_eval:w
+ \l_fp_input_a_integer_int + \l_fp_input_b_integer_int
+ \scan_stop:
+ \l_fp_output_decimal_int
+ \int_eval:w
+ \l_fp_input_a_decimal_int + \l_fp_input_b_decimal_int
+ \scan_stop:
+ \if_int_compare:w \l_fp_output_decimal_int < \c_one_thousand_million
+ \else:
+ \tex_advance:D \l_fp_output_integer_int \c_one
+ \tex_advance:D \l_fp_output_decimal_int -\c_one_thousand_million
+ \fi:
+ }
+\cs_new_protected_nopar:Npn \fp_add_difference:
+ {
+ \l_fp_output_integer_int
+ \int_eval:w
+ \l_fp_input_a_integer_int - \l_fp_input_b_integer_int
+ \scan_stop:
+ \l_fp_output_decimal_int
+ \int_eval:w
+ \l_fp_input_a_decimal_int - \l_fp_input_b_decimal_int
+ \scan_stop:
+ \if_int_compare:w \l_fp_output_decimal_int < \c_zero
+ \tex_advance:D \l_fp_output_integer_int \c_minus_one
+ \tex_advance:D \l_fp_output_decimal_int \c_one_thousand_million
+ \fi:
+ \if_int_compare:w \l_fp_output_integer_int < \c_zero
+ \l_fp_output_sign_int \l_fp_input_b_sign_int
+ \if_int_compare:w \l_fp_output_decimal_int = \c_zero
+ \l_fp_output_integer_int -\l_fp_output_integer_int
+ \else:
+ \l_fp_output_decimal_int
+ \int_eval:w
+ \c_one_thousand_million - \l_fp_output_decimal_int
+ \scan_stop:
+ \l_fp_output_integer_int
+ \int_eval:w
+ - \l_fp_output_integer_int - \c_one
+ \scan_stop:
+ \fi:
+ \else:
+ \l_fp_output_sign_int \l_fp_input_a_sign_int
+ \fi:
+ }
+\cs_new_protected_nopar:Npn \fp_sub:Nn { \fp_sub_aux:NNn \tl_set:Nn }
+\cs_new_protected_nopar:Npn \fp_gsub:Nn { \fp_sub_aux:NNn \tl_gset:Nn }
+\cs_generate_variant:Nn \fp_sub:Nn { c }
+\cs_generate_variant:Nn \fp_gsub:Nn { c }
+\cs_new_protected_nopar:Npn \fp_sub_aux:NNn #1#2#3
+ {
+ \group_begin:
+ \fp_read:N #2
+ \fp_split:Nn b {#3}
+ \fp_standardise:NNNN
+ \l_fp_input_b_sign_int
+ \l_fp_input_b_integer_int
+ \l_fp_input_b_decimal_int
+ \l_fp_input_b_exponent_int
+ \tex_multiply:D \l_fp_input_b_sign_int \c_minus_one
+ \fp_add_core:
+ \fp_tmp:w #1#2
+ }
+\cs_new_protected_nopar:Npn \fp_mul:Nn { \fp_mul_aux:NNn \tl_set:Nn }
+\cs_new_protected_nopar:Npn \fp_gmul:Nn { \fp_mul_aux:NNn \tl_gset:Nn }
+\cs_generate_variant:Nn \fp_mul:Nn { c }
+\cs_generate_variant:Nn \fp_gmul:Nn { c }
+\cs_new_protected_nopar:Npn \fp_mul_aux:NNn #1#2#3
+ {
+ \group_begin:
+ \fp_read:N #2
+ \fp_split:Nn b {#3}
+ \fp_standardise:NNNN
+ \l_fp_input_b_sign_int
+ \l_fp_input_b_integer_int
+ \l_fp_input_b_decimal_int
+ \l_fp_input_b_exponent_int
+ \fp_mul_internal:
+ \l_fp_output_exponent_int
+ \int_eval:w
+ \l_fp_input_a_exponent_int + \l_fp_input_b_exponent_int
+ \scan_stop:
+ \fp_standardise:NNNN
+ \l_fp_output_sign_int
+ \l_fp_output_integer_int
+ \l_fp_output_decimal_int
+ \l_fp_output_exponent_int
+ \cs_set_protected_nopar:Npx \fp_tmp:w
+ {
+ \group_end:
+ #1 \exp_not:N #2
+ {
+ \if_int_compare:w
+ \int_eval:w
+ \l_fp_input_a_sign_int * \l_fp_input_b_sign_int
+ < \c_zero
+ \if_int_compare:w
+ \int_eval:w
+ \l_fp_output_integer_int + \l_fp_output_decimal_int
+ = \c_zero
+ +
+ \else:
+ -
+ \fi:
+ \else:
+ +
+ \fi:
+ \int_use:N \l_fp_output_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \int_value:w \int_eval:w
+ \l_fp_output_decimal_int + \c_one_thousand_million
+ e
+ \int_use:N \l_fp_output_exponent_int
+ }
+ }
+ \fp_tmp:w
+ }
+\cs_new_protected_nopar:Npn \fp_mul_internal:
+ {
+ \fp_mul_split:NNNN \l_fp_input_a_decimal_int
+ \l_fp_mul_a_i_int \l_fp_mul_a_ii_int \l_fp_mul_a_iii_int
+ \fp_mul_split:NNNN \l_fp_input_b_decimal_int
+ \l_fp_mul_b_i_int \l_fp_mul_b_ii_int \l_fp_mul_b_iii_int
+ \l_fp_mul_output_int \c_zero
+ \tl_clear:N \l_fp_mul_output_tl
+ \fp_mul_product:NN \l_fp_mul_a_i_int \l_fp_mul_b_iii_int
+ \fp_mul_product:NN \l_fp_mul_a_ii_int \l_fp_mul_b_ii_int
+ \fp_mul_product:NN \l_fp_mul_a_iii_int \l_fp_mul_b_i_int
+ \tex_divide:D \l_fp_mul_output_int \c_one_thousand
+ \fp_mul_product:NN \l_fp_input_a_integer_int \l_fp_mul_b_iii_int
+ \fp_mul_product:NN \l_fp_mul_a_i_int \l_fp_mul_b_ii_int
+ \fp_mul_product:NN \l_fp_mul_a_ii_int \l_fp_mul_b_i_int
+ \fp_mul_product:NN \l_fp_mul_a_iii_int \l_fp_input_b_integer_int
+ \fp_mul_end_level:
+ \fp_mul_product:NN \l_fp_input_a_integer_int \l_fp_mul_b_ii_int
+ \fp_mul_product:NN \l_fp_mul_a_i_int \l_fp_mul_b_i_int
+ \fp_mul_product:NN \l_fp_mul_a_ii_int \l_fp_input_b_integer_int
+ \fp_mul_end_level:
+ \fp_mul_product:NN \l_fp_input_a_integer_int \l_fp_mul_b_i_int
+ \fp_mul_product:NN \l_fp_mul_a_i_int \l_fp_input_b_integer_int
+ \fp_mul_end_level:
+ \l_fp_output_decimal_int 0 \l_fp_mul_output_tl \scan_stop:
+ \tl_clear:N \l_fp_mul_output_tl
+ \fp_mul_product:NN \l_fp_input_a_integer_int \l_fp_input_b_integer_int
+ \fp_mul_end_level:
+ \l_fp_output_integer_int 0 \l_fp_mul_output_tl \scan_stop:
+ }
+\cs_new_protected_nopar:Npn \fp_mul_split:NNNN #1#2#3#4
+ {
+ \tex_advance:D #1 \c_one_thousand_million
+ \cs_set_protected_nopar:Npn \fp_mul_split_aux:w
+ ##1##2##3##4##5##6##7##8##9 \q_stop {
+ #2 ##2##3##4 \scan_stop:
+ #3 ##5##6##7 \scan_stop:
+ #4 ##8##9 \scan_stop:
+ }
+ \exp_after:wN \fp_mul_split_aux:w \int_use:N #1 \q_stop
+ \tex_advance:D #1 -\c_one_thousand_million
+ }
+\cs_new_protected_nopar:Npn \fp_mul_product:NN #1#2
+ {
+ \l_fp_mul_output_int
+ \int_eval:w \l_fp_mul_output_int + #1 * #2 \scan_stop:
+ }
+\cs_new_protected_nopar:Npn \fp_mul_end_level:
+ {
+ \tex_advance:D \l_fp_mul_output_int \c_one_thousand_million
+ \exp_after:wN \use_i:nn \exp_after:wN
+ \fp_mul_end_level:NNNNNNNNN \int_use:N \l_fp_mul_output_int
+ }
+\cs_new_protected_nopar:Npn \fp_mul_end_level:NNNNNNNNN #1#2#3#4#5#6#7#8#9
+ {
+ \tl_set:Nx \l_fp_mul_output_tl { #7#8#9 \l_fp_mul_output_tl }
+ \l_fp_mul_output_int #1#2#3#4#5#6 \scan_stop:
+ }
+\cs_new_protected_nopar:Npn \fp_div:Nn { \fp_div_aux:NNn \tl_set:Nn }
+\cs_new_protected_nopar:Npn \fp_gdiv:Nn { \fp_div_aux:NNn \tl_gset:Nn }
+\cs_generate_variant:Nn \fp_div:Nn { c }
+\cs_generate_variant:Nn \fp_gdiv:Nn { c }
+\cs_new_protected_nopar:Npn \fp_div_aux:NNn #1#2#3
+ {
+ \group_begin:
+ \fp_read:N #2
+ \fp_split:Nn b {#3}
+ \fp_standardise:NNNN
+ \l_fp_input_b_sign_int
+ \l_fp_input_b_integer_int
+ \l_fp_input_b_decimal_int
+ \l_fp_input_b_exponent_int
+ \if_int_compare:w
+ \int_eval:w
+ \l_fp_input_b_integer_int + \l_fp_input_b_decimal_int
+ = \c_zero
+ \cs_set_protected_nopar:Npx \fp_tmp:w ##1##2
+ {
+ \group_end:
+ #1 \exp_not:N #2 { \c_undefined_fp }
+ }
+ \else:
+ \if_int_compare:w
+ \int_eval:w
+ \l_fp_input_a_integer_int + \l_fp_input_a_decimal_int
+ = \c_zero
+ \cs_set_protected_nopar:Npx \fp_tmp:w ##1##2
+ {
+ \group_end:
+ #1 \exp_not:N #2 { \c_zero_fp }
+ }
+ \else:
+ \exp_after:wN \exp_after:wN \exp_after:wN \fp_div_internal:
+ \fi:
+ \fi:
+ \fp_tmp:w #1#2
+ }
+\cs_new_protected_nopar:Npn \fp_div_internal: {
+ \l_fp_output_integer_int \c_zero
+ \l_fp_output_decimal_int \c_zero
+ \cs_set_eq:NN \fp_div_store: \fp_div_store_integer:
+ \l_fp_div_offset_int \c_one_hundred_million
+ \fp_div_loop:
+ \l_fp_output_exponent_int
+ \int_eval:w
+ \l_fp_input_a_exponent_int - \l_fp_input_b_exponent_int
+ \scan_stop:
+ \fp_standardise:NNNN
+ \l_fp_output_sign_int
+ \l_fp_output_integer_int
+ \l_fp_output_decimal_int
+ \l_fp_output_exponent_int
+ \cs_set_protected_nopar:Npx \fp_tmp:w ##1##2
+ {
+ \group_end:
+ ##1 ##2
+ {
+ \if_int_compare:w
+ \int_eval:w
+ \l_fp_input_a_sign_int * \l_fp_input_b_sign_int
+ < \c_zero
+ \if_int_compare:w
+ \int_eval:w
+ \l_fp_output_integer_int + \l_fp_output_decimal_int
+ = \c_zero
+ +
+ \else:
+ -
+ \fi:
+ \else:
+ +
+ \fi:
+ \int_use:N \l_fp_output_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \int_value:w \int_eval:w
+ \l_fp_output_decimal_int + \c_one_thousand_million
+ \int_eval_end:
+ e
+ \int_use:N \l_fp_output_exponent_int
+ }
+ }
+}
+\cs_new_protected_nopar:Npn \fp_div_loop:
+ {
+ \l_fp_count_int \c_zero
+ \fp_div_divide:
+ \fp_div_store:
+ \tex_multiply:D \l_fp_input_a_integer_int \c_ten
+ \tex_advance:D \l_fp_input_a_decimal_int \c_one_thousand_million
+ \exp_after:wN \fp_div_loop_step:w
+ \int_use:N \l_fp_input_a_decimal_int \q_stop
+ \if_int_compare:w
+ \int_eval:w \l_fp_input_a_integer_int + \l_fp_input_a_decimal_int
+ > \c_zero
+ \if_int_compare:w \l_fp_div_offset_int > \c_zero
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \fp_div_loop:
+ \fi:
+ \fi:
+ }
+\cs_new_protected_nopar:Npn \fp_div_divide:
+ {
+ \if_int_compare:w \l_fp_input_a_integer_int > \l_fp_input_b_integer_int
+ \exp_after:wN \fp_div_divide_aux:
+ \else:
+ \if_int_compare:w \l_fp_input_a_integer_int < \l_fp_input_b_integer_int
+ \else:
+ \if_int_compare:w
+ \l_fp_input_a_decimal_int < \l_fp_input_b_decimal_int
+ \else:
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \exp_after:wN \fp_div_divide_aux:
+ \fi:
+ \fi:
+ \fi:
+ }
+\cs_new_protected_nopar:Npn \fp_div_divide_aux:
+ {
+ \tex_advance:D \l_fp_count_int \c_one
+ \tex_advance:D \l_fp_input_a_integer_int -\l_fp_input_b_integer_int
+ \tex_advance:D \l_fp_input_a_decimal_int -\l_fp_input_b_decimal_int
+ \if_int_compare:w \l_fp_input_a_decimal_int < \c_zero
+ \tex_advance:D \l_fp_input_a_integer_int \c_minus_one
+ \tex_advance:D \l_fp_input_a_decimal_int \c_one_thousand_million
+ \fi:
+ \fp_div_divide:
+ }
+\cs_new_protected_nopar:Npn \fp_div_store: { }
+\cs_new_protected_nopar:Npn \fp_div_store_integer:
+ {
+ \l_fp_output_integer_int \l_fp_count_int
+ \cs_set_eq:NN \fp_div_store: \fp_div_store_decimal:
+ }
+\cs_new_protected_nopar:Npn \fp_div_store_decimal:
+ {
+ \l_fp_output_decimal_int
+ \int_eval:w
+ \l_fp_output_decimal_int +
+ \l_fp_count_int * \l_fp_div_offset_int
+ \int_eval_end:
+ \tex_divide:D \l_fp_div_offset_int \c_ten
+ }
+\cs_new_protected_nopar:Npn \fp_div_loop_step:w #1#2#3#4#5#6#7#8#9 \q_stop
+ {
+ \l_fp_input_a_integer_int
+ \int_eval:w #2 + \l_fp_input_a_integer_int \int_eval_end:
+ \l_fp_input_a_decimal_int #3#4#5#6#7#8#9 0 \scan_stop:
+ }
+\cs_new_protected_nopar:Npn \fp_add:NNNNNNNNN #1#2#3#4#5#6#7#8#9
+ {
+ #7 \int_eval:w #1 + #4 \int_eval_end:
+ #8 \int_eval:w #2 + #5 \int_eval_end:
+ #9 \int_eval:w #3 + #6 \int_eval_end:
+ \if_int_compare:w #9 < \c_one_thousand_million
+ \else:
+ \tex_advance:D #8 \c_one
+ \tex_advance:D #9 -\c_one_thousand_million
+ \fi:
+ \if_int_compare:w #8 < \c_one_thousand_million
+ \else:
+ \tex_advance:D #7 \c_one
+ \tex_advance:D #8 -\c_one_thousand_million
+ \fi:
+ }
+\cs_new_protected_nopar:Npn \fp_sub:NNNNNNNNN #1#2#3#4#5#6#7#8#9
+ {
+ #7 \int_eval:w #1 - #4 \int_eval_end:
+ #8 \int_eval:w #2 - #5 \int_eval_end:
+ #9 \int_eval:w #3 - #6 \int_eval_end:
+ \if_int_compare:w #9 < \c_zero
+ \tex_advance:D #8 \c_minus_one
+ \tex_advance:D #9 \c_one_thousand_million
+ \fi:
+ \if_int_compare:w #8 < \c_zero
+ \tex_advance:D #7 \c_minus_one
+ \tex_advance:D #8 \c_one_thousand_million
+ \fi:
+ \if_int_compare:w #7 < \c_zero
+ \if_int_compare:w \int_eval:w #8 + #9 = \c_zero
+ #7 -#7
+ \else:
+ \tex_advance:D #7 \c_one
+ #8 \int_eval:w \c_one_thousand_million - #8 \int_eval_end:
+ #9 \int_eval:w \c_one_thousand_million - #9 \int_eval_end:
+ \fi:
+ \fi:
+ }
+\cs_new_protected_nopar:Npn \fp_mul:NNNNNN #1#2#3#4#5#6
+ {
+ \fp_mul_split:NNNN #1
+ \l_fp_mul_a_i_int \l_fp_mul_a_ii_int \l_fp_mul_a_iii_int
+ \fp_mul_split:NNNN #2
+ \l_fp_mul_a_iv_int \l_fp_mul_a_v_int \l_fp_mul_a_vi_int
+ \fp_mul_split:NNNN #3
+ \l_fp_mul_b_i_int \l_fp_mul_b_ii_int \l_fp_mul_b_iii_int
+ \fp_mul_split:NNNN #4
+ \l_fp_mul_b_iv_int \l_fp_mul_b_v_int \l_fp_mul_b_vi_int
+ \l_fp_mul_output_int \c_zero
+ \tl_clear:N \l_fp_mul_output_tl
+ \fp_mul_product:NN \l_fp_mul_a_i_int \l_fp_mul_b_vi_int
+ \fp_mul_product:NN \l_fp_mul_a_ii_int \l_fp_mul_b_v_int
+ \fp_mul_product:NN \l_fp_mul_a_iii_int \l_fp_mul_b_iv_int
+ \fp_mul_product:NN \l_fp_mul_a_iv_int \l_fp_mul_b_iii_int
+ \fp_mul_product:NN \l_fp_mul_a_v_int \l_fp_mul_b_ii_int
+ \fp_mul_product:NN \l_fp_mul_a_vi_int \l_fp_mul_b_i_int
+ \tex_divide:D \l_fp_mul_output_int \c_one_thousand
+ \fp_mul_product:NN \l_fp_mul_a_i_int \l_fp_mul_b_v_int
+ \fp_mul_product:NN \l_fp_mul_a_ii_int \l_fp_mul_b_iv_int
+ \fp_mul_product:NN \l_fp_mul_a_iii_int \l_fp_mul_b_iii_int
+ \fp_mul_product:NN \l_fp_mul_a_iv_int \l_fp_mul_b_ii_int
+ \fp_mul_product:NN \l_fp_mul_a_v_int \l_fp_mul_b_i_int
+ \fp_mul_end_level:
+ \fp_mul_product:NN \l_fp_mul_a_i_int \l_fp_mul_b_iv_int
+ \fp_mul_product:NN \l_fp_mul_a_ii_int \l_fp_mul_b_iii_int
+ \fp_mul_product:NN \l_fp_mul_a_iii_int \l_fp_mul_b_ii_int
+ \fp_mul_product:NN \l_fp_mul_a_iv_int \l_fp_mul_b_i_int
+ \fp_mul_end_level:
+ \fp_mul_product:NN \l_fp_mul_a_i_int \l_fp_mul_b_iii_int
+ \fp_mul_product:NN \l_fp_mul_a_ii_int \l_fp_mul_b_ii_int
+ \fp_mul_product:NN \l_fp_mul_a_iii_int \l_fp_mul_b_i_int
+ \fp_mul_end_level:
+ #6 0 \l_fp_mul_output_tl \scan_stop:
+ \tl_clear:N \l_fp_mul_output_tl
+ \fp_mul_product:NN \l_fp_mul_a_i_int \l_fp_mul_b_ii_int
+ \fp_mul_product:NN \l_fp_mul_a_ii_int \l_fp_mul_b_i_int
+ \fp_mul_end_level:
+ \fp_mul_product:NN \l_fp_mul_a_i_int \l_fp_mul_b_i_int
+ \fp_mul_end_level:
+ \fp_mul_end_level:
+ #5 0 \l_fp_mul_output_tl \scan_stop:
+ }
+\cs_new_protected_nopar:Npn \fp_mul:NNNNNNNNN #1#2#3#4#5#6#7#8#9
+ {
+ \fp_mul_split:NNNN #2
+ \l_fp_mul_a_i_int \l_fp_mul_a_ii_int \l_fp_mul_a_iii_int
+ \fp_mul_split:NNNN #3
+ \l_fp_mul_a_iv_int \l_fp_mul_a_v_int \l_fp_mul_a_vi_int
+ \fp_mul_split:NNNN #5
+ \l_fp_mul_b_i_int \l_fp_mul_b_ii_int \l_fp_mul_b_iii_int
+ \fp_mul_split:NNNN #6
+ \l_fp_mul_b_iv_int \l_fp_mul_b_v_int \l_fp_mul_b_vi_int
+ \l_fp_mul_output_int \c_zero
+ \tl_clear:N \l_fp_mul_output_tl
+ \fp_mul_product:NN \l_fp_mul_a_i_int \l_fp_mul_b_vi_int
+ \fp_mul_product:NN \l_fp_mul_a_ii_int \l_fp_mul_b_v_int
+ \fp_mul_product:NN \l_fp_mul_a_iii_int \l_fp_mul_b_iv_int
+ \fp_mul_product:NN \l_fp_mul_a_iv_int \l_fp_mul_b_iii_int
+ \fp_mul_product:NN \l_fp_mul_a_v_int \l_fp_mul_b_ii_int
+ \fp_mul_product:NN \l_fp_mul_a_vi_int \l_fp_mul_b_i_int
+ \tex_divide:D \l_fp_mul_output_int \c_one_thousand
+ \fp_mul_product:NN #1 \l_fp_mul_b_vi_int
+ \fp_mul_product:NN \l_fp_mul_a_i_int \l_fp_mul_b_v_int
+ \fp_mul_product:NN \l_fp_mul_a_ii_int \l_fp_mul_b_iv_int
+ \fp_mul_product:NN \l_fp_mul_a_iii_int \l_fp_mul_b_iii_int
+ \fp_mul_product:NN \l_fp_mul_a_iv_int \l_fp_mul_b_ii_int
+ \fp_mul_product:NN \l_fp_mul_a_v_int \l_fp_mul_b_i_int
+ \fp_mul_product:NN \l_fp_mul_a_vi_int #4
+ \fp_mul_end_level:
+ \fp_mul_product:NN #1 \l_fp_mul_b_v_int
+ \fp_mul_product:NN \l_fp_mul_a_i_int \l_fp_mul_b_iv_int
+ \fp_mul_product:NN \l_fp_mul_a_ii_int \l_fp_mul_b_iii_int
+ \fp_mul_product:NN \l_fp_mul_a_iii_int \l_fp_mul_b_ii_int
+ \fp_mul_product:NN \l_fp_mul_a_iv_int \l_fp_mul_b_i_int
+ \fp_mul_product:NN \l_fp_mul_a_v_int #4
+ \fp_mul_end_level:
+ \fp_mul_product:NN #1 \l_fp_mul_b_iv_int
+ \fp_mul_product:NN \l_fp_mul_a_i_int \l_fp_mul_b_iii_int
+ \fp_mul_product:NN \l_fp_mul_a_ii_int \l_fp_mul_b_ii_int
+ \fp_mul_product:NN \l_fp_mul_a_iii_int \l_fp_mul_b_i_int
+ \fp_mul_product:NN \l_fp_mul_a_iv_int #4
+ \fp_mul_end_level:
+ #9 0 \l_fp_mul_output_tl \scan_stop:
+ \tl_clear:N \l_fp_mul_output_tl
+ \fp_mul_product:NN #1 \l_fp_mul_b_iii_int
+ \fp_mul_product:NN \l_fp_mul_a_i_int \l_fp_mul_b_ii_int
+ \fp_mul_product:NN \l_fp_mul_a_ii_int \l_fp_mul_b_i_int
+ \fp_mul_product:NN \l_fp_mul_a_iii_int #4
+ \fp_mul_end_level:
+ \fp_mul_product:NN #1 \l_fp_mul_b_ii_int
+ \fp_mul_product:NN \l_fp_mul_a_i_int \l_fp_mul_b_i_int
+ \fp_mul_product:NN \l_fp_mul_a_ii_int #4
+ \fp_mul_end_level:
+ \fp_mul_product:NN #1 \l_fp_mul_b_i_int
+ \fp_mul_product:NN \l_fp_mul_a_i_int #4
+ \fp_mul_end_level:
+ #8 0 \l_fp_mul_output_tl \scan_stop:
+ \tl_clear:N \l_fp_mul_output_tl
+ \fp_mul_product:NN #1 #4
+ \fp_mul_end_level:
+ #7 0 \l_fp_mul_output_tl \scan_stop:
+ }
+\cs_new_protected_nopar:Npn \fp_div_integer:NNNNN #1#2#3#4#5
+ {
+ \l_fp_tmp_int #1
+ \tex_divide:D \l_fp_tmp_int #3
+ \l_fp_tmp_int \int_eval:w #1 - \l_fp_tmp_int * #3 \int_eval_end:
+ #4 #1
+ \tex_divide:D #4 #3
+ #5 #2
+ \tex_divide:D #5 #3
+ \tex_multiply:D \l_fp_tmp_int \c_one_thousand
+ \tex_divide:D \l_fp_tmp_int #3
+ #5 \int_eval:w #5 + \l_fp_tmp_int * \c_one_million \int_eval_end:
+ \if_int_compare:w #5 > \c_one_thousand_million
+ \tex_advance:D #4 \c_one
+ \tex_advance:D #5 -\c_one_thousand_million
+ \fi:
+ }
+\cs_new_protected_nopar:Npn \fp_extended_normalise:
+ {
+ \fp_extended_normalise_aux_i:
+ \fp_extended_normalise_aux_ii:
+ }
+\cs_new_protected_nopar:Npn \fp_extended_normalise_aux_i:
+ {
+ \if_int_compare:w \l_fp_input_a_exponent_int > \c_zero
+ \tex_multiply:D \l_fp_input_a_integer_int \c_ten
+ \tex_advance:D \l_fp_input_a_decimal_int \c_one_thousand_million
+ \exp_after:wN \fp_extended_normalise_aux_i:w
+ \int_use:N \l_fp_input_a_decimal_int \q_stop
+ \exp_after:wN \fp_extended_normalise_aux_i:
+ \fi:
+ }
+\cs_new_protected_nopar:Npn \fp_extended_normalise_aux_i:w
+ #1#2#3#4#5#6#7#8#9 \q_stop
+ {
+ \l_fp_input_a_integer_int
+ \int_eval:w \l_fp_input_a_integer_int + #2 \scan_stop:
+ \l_fp_input_a_decimal_int #3#4#5#6#7#8#9 0 \scan_stop:
+ \tex_advance:D \l_fp_input_a_extended_int \c_one_thousand_million
+ \exp_after:wN \fp_extended_normalise_aux_ii:w
+ \int_use:N \l_fp_input_a_extended_int \q_stop
+ }
+\cs_new_protected_nopar:Npn \fp_extended_normalise_aux_ii:w
+ #1#2#3#4#5#6#7#8#9 \q_stop
+ {
+ \l_fp_input_a_decimal_int
+ \int_eval:w \l_fp_input_a_decimal_int + #2 \scan_stop:
+ \l_fp_input_a_extended_int #3#4#5#6#7#8#9 0 \scan_stop:
+ \tex_advance:D \l_fp_input_a_exponent_int \c_minus_one
+ }
+\cs_new_protected_nopar:Npn \fp_extended_normalise_aux_ii:
+ {
+ \if_int_compare:w \l_fp_input_a_exponent_int < \c_zero
+ \tex_advance:D \l_fp_input_a_decimal_int \c_one_thousand_million
+ \exp_after:wN \use_i:nn \exp_after:wN
+ \fp_extended_normalise_ii_aux:NNNNNNNNN
+ \int_use:N \l_fp_input_a_decimal_int
+ \exp_after:wN \fp_extended_normalise_aux_ii:
+ \fi:
+ }
+\cs_new_protected_nopar:Npn \fp_extended_normalise_ii_aux:NNNNNNNNN
+ #1#2#3#4#5#6#7#8#9
+ {
+ \if_int_compare:w \l_fp_input_a_integer_int = \c_zero
+ \l_fp_input_a_decimal_int #1#2#3#4#5#6#7#8 \scan_stop:
+ \else:
+ \tl_set:Nx \l_fp_tmp_tl
+ {
+ \int_use:N \l_fp_input_a_integer_int
+ #1#2#3#4#5#6#7#8
+ }
+ \l_fp_input_a_integer_int \c_zero
+ \l_fp_input_a_decimal_int \l_fp_tmp_tl \scan_stop:
+ \fi:
+ \tex_divide:D \l_fp_input_a_extended_int \c_ten
+ \tl_set:Nx \l_fp_tmp_tl
+ {
+ #9
+ \int_use:N \l_fp_input_a_extended_int
+ }
+ \l_fp_input_a_extended_int \l_fp_tmp_tl \scan_stop:
+ \tex_advance:D \l_fp_input_a_exponent_int \c_one
+ }
+\cs_new_protected_nopar:Npn \fp_extended_normalise_output:
+ {
+ \if_int_compare:w \l_fp_output_integer_int > \c_nine
+ \tex_advance:D \l_fp_output_integer_int \c_one_thousand_million
+ \exp_after:wN \use_i:nn \exp_after:wN
+ \fp_extended_normalise_output_aux_i:NNNNNNNNN
+ \int_use:N \l_fp_output_integer_int
+ \exp_after:wN \fp_extended_normalise_output:
+ \fi:
+ }
+\cs_new_protected_nopar:Npn \fp_extended_normalise_output_aux_i:NNNNNNNNN
+ #1#2#3#4#5#6#7#8#9
+ {
+ \l_fp_output_integer_int #1#2#3#4#5#6#7#8 \scan_stop:
+ \tex_advance:D \l_fp_output_decimal_int \c_one_thousand_million
+ \tl_set:Nx \l_fp_tmp_tl
+ {
+ #9
+ \exp_after:wN \use_none:n
+ \int_use:N \l_fp_output_decimal_int
+ }
+ \exp_after:wN \fp_extended_normalise_output_aux_ii:NNNNNNNNN
+ \l_fp_tmp_tl
+ }
+\cs_new_protected_nopar:Npn \fp_extended_normalise_output_aux_ii:NNNNNNNNN
+ #1#2#3#4#5#6#7#8#9
+ {
+ \l_fp_output_decimal_int #1#2#3#4#5#6#7#8#9 \scan_stop:
+ \fp_extended_normalise_output_aux:N
+ }
+\cs_new_protected_nopar:Npn \fp_extended_normalise_output_aux:N #1
+ {
+ \tex_advance:D \l_fp_output_extended_int \c_one_thousand_million
+ \tex_divide:D \l_fp_output_extended_int \c_ten
+ \tl_set:Nx \l_fp_tmp_tl
+ {
+ #1
+ \exp_after:wN \use_none:n
+ \int_use:N \l_fp_output_extended_int
+ }
+ \l_fp_output_extended_int \l_fp_tmp_tl \scan_stop:
+ \tex_advance:D \l_fp_output_exponent_int \c_one
+ }
+\cs_new_protected_nopar:Npn \fp_trig_normalise:
+ {
+ \if_int_compare:w \l_fp_input_a_exponent_int < \c_ten
+ \l_fp_input_a_extended_int \c_zero
+ \fp_extended_normalise:
+ \fp_trig_normalise_aux:
+ \if_int_compare:w \l_fp_input_a_integer_int < \c_zero
+ \l_fp_input_a_sign_int -\l_fp_input_a_sign_int
+ \l_fp_input_a_integer_int -\l_fp_input_a_integer_int
+ \fi:
+ \exp_after:wN \fp_trig_octant:
+ \else:
+ \l_fp_input_a_sign_int \c_one
+ \l_fp_output_integer_int \c_zero
+ \l_fp_output_decimal_int \c_zero
+ \l_fp_output_exponent_int \c_zero
+ \exp_after:wN \fp_trig_overflow_msg:
+ \fi:
+ }
+\cs_new_protected_nopar:Npn \fp_trig_normalise_aux:
+ {
+ \if_int_compare:w \l_fp_input_a_integer_int > \c_three
+ \fp_trig_sub:NNN
+ \c_six \c_fp_two_pi_decimal_int \c_fp_two_pi_extended_int
+ \exp_after:wN \fp_trig_normalise_aux:
+ \else:
+ \if_int_compare:w \l_fp_input_a_integer_int > \c_two
+ \if_int_compare:w \l_fp_input_a_decimal_int > \c_fp_pi_decimal_int
+ \fp_trig_sub:NNN
+ \c_six \c_fp_two_pi_decimal_int \c_fp_two_pi_extended_int
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \exp_after:wN \fp_trig_normalise_aux:
+ \fi:
+ \fi:
+ \fi:
+ }
+\cs_new_protected_nopar:Npn \fp_trig_sub:NNN #1#2#3
+ {
+ \l_fp_input_a_integer_int
+ \int_eval:w \l_fp_input_a_integer_int - #1 \int_eval_end:
+ \l_fp_input_a_decimal_int
+ \int_eval:w \l_fp_input_a_decimal_int - #2 \int_eval_end:
+ \l_fp_input_a_extended_int
+ \int_eval:w \l_fp_input_a_extended_int - #3 \int_eval_end:
+ \if_int_compare:w \l_fp_input_a_extended_int < \c_zero
+ \tex_advance:D \l_fp_input_a_decimal_int \c_minus_one
+ \tex_advance:D \l_fp_input_a_extended_int \c_one_thousand_million
+ \fi:
+ \if_int_compare:w \l_fp_input_a_decimal_int < \c_zero
+ \tex_advance:D \l_fp_input_a_integer_int \c_minus_one
+ \tex_advance:D \l_fp_input_a_decimal_int \c_one_thousand_million
+ \fi:
+ \if_int_compare:w \l_fp_input_a_integer_int < \c_zero
+ \l_fp_input_a_sign_int -\l_fp_input_a_sign_int
+ \if_int_compare:w
+ \int_eval:w
+ \l_fp_input_a_decimal_int + \l_fp_input_a_extended_int
+ = \c_zero
+ \l_fp_input_a_integer_int -\l_fp_input_a_integer_int
+ \else:
+ \l_fp_input_a_integer_int
+ \int_eval:w
+ - \l_fp_input_a_integer_int - \c_one
+ \int_eval_end:
+ \l_fp_input_a_decimal_int
+ \int_eval:w
+ \c_one_thousand_million - \l_fp_input_a_decimal_int
+ \int_eval_end:
+ \l_fp_input_a_extended_int
+ \int_eval:w
+ \c_one_thousand_million - \l_fp_input_a_extended_int
+ \int_eval_end:
+ \fi:
+ \fi:
+ }
+\cs_new_protected_nopar:Npn \fp_trig_octant:
+ {
+ \l_fp_trig_octant_int \c_one
+ \fp_trig_octant_aux:
+ \if_int_compare:w \l_fp_input_a_decimal_int < \c_ten
+ \l_fp_input_a_decimal_int \c_zero
+ \l_fp_input_a_extended_int \c_zero
+ \fi:
+ \if_int_odd:w \l_fp_trig_octant_int
+ \else:
+ \fp_sub:NNNNNNNNN
+ \c_zero \c_fp_pi_by_four_decimal_int \c_fp_pi_by_four_extended_int
+ \l_fp_input_a_integer_int \l_fp_input_a_decimal_int
+ \l_fp_input_a_extended_int
+ \l_fp_input_a_integer_int \l_fp_input_a_decimal_int
+ \l_fp_input_a_extended_int
+ \fi:
+ }
+\cs_new_protected_nopar:Npn \fp_trig_octant_aux:
+ {
+ \if_int_compare:w \l_fp_input_a_integer_int > \c_zero
+ \fp_sub:NNNNNNNNN
+ \l_fp_input_a_integer_int \l_fp_input_a_decimal_int
+ \l_fp_input_a_extended_int
+ \c_zero \c_fp_pi_by_four_decimal_int \c_fp_pi_by_four_extended_int
+ \l_fp_input_a_integer_int \l_fp_input_a_decimal_int
+ \l_fp_input_a_extended_int
+ \tex_advance:D \l_fp_trig_octant_int \c_one
+ \exp_after:wN \fp_trig_octant_aux:
+ \else:
+ \if_int_compare:w
+ \l_fp_input_a_decimal_int > \c_fp_pi_by_four_decimal_int
+ \fp_sub:NNNNNNNNN
+ \l_fp_input_a_integer_int \l_fp_input_a_decimal_int
+ \l_fp_input_a_extended_int
+ \c_zero \c_fp_pi_by_four_decimal_int
+ \c_fp_pi_by_four_extended_int
+ \l_fp_input_a_integer_int \l_fp_input_a_decimal_int
+ \l_fp_input_a_extended_int
+ \tex_advance:D \l_fp_trig_octant_int \c_one
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \fp_trig_octant_aux:
+ \fi:
+ \fi:
+ }
+\cs_new_protected_nopar:Npn \fp_sin:Nn { \fp_sin_aux:NNn \tl_set:Nn }
+\cs_new_protected_nopar:Npn \fp_gsin:Nn { \fp_sin_aux:NNn \tl_gset:Nn }
+\cs_generate_variant:Nn \fp_sin:Nn { c }
+\cs_generate_variant:Nn \fp_gsin:Nn { c }
+\cs_new_protected_nopar:Npn \fp_sin_aux:NNn #1#2#3
+ {
+ \group_begin:
+ \fp_split:Nn a {#3}
+ \fp_standardise:NNNN
+ \l_fp_input_a_sign_int
+ \l_fp_input_a_integer_int
+ \l_fp_input_a_decimal_int
+ \l_fp_input_a_exponent_int
+ \tl_set:Nx \l_fp_arg_tl
+ {
+ \if_int_compare:w \l_fp_input_a_sign_int < \c_zero
+ -
+ \else:
+ +
+ \fi:
+ \int_use:N \l_fp_input_a_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \int_value:w \int_eval:w
+ \l_fp_input_a_decimal_int + \c_one_thousand_million
+ e
+ \int_use:N \l_fp_input_a_exponent_int
+ }
+ \if_int_compare:w \l_fp_input_a_exponent_int < -\c_five
+ \cs_set_protected_nopar:Npx \fp_tmp:w
+ {
+ \group_end:
+ #1 \exp_not:N #2 { \l_fp_arg_tl }
+ }
+ \else:
+ \if_cs_exist:w
+ c_fp_sin ( \l_fp_arg_tl ) _fp
+ \cs_end:
+ \else:
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \fp_sin_aux_i:
+ \fi:
+ \cs_set_protected_nopar:Npx \fp_tmp:w
+ {
+ \group_end:
+ #1 \exp_not:N #2
+ { \use:c { c_fp_sin ( \l_fp_arg_tl ) _fp } }
+ }
+ \fi:
+ \fp_tmp:w
+ }
+\cs_new_protected_nopar:Npn \fp_sin_aux_i:
+ {
+ \fp_trig_normalise:
+ \fp_sin_aux_ii:
+ \if_int_compare:w \l_fp_output_integer_int = \c_one
+ \l_fp_output_exponent_int \c_zero
+ \else:
+ \l_fp_output_integer_int \l_fp_output_decimal_int
+ \l_fp_output_decimal_int \l_fp_output_extended_int
+ \l_fp_output_exponent_int -\c_nine
+ \fi:
+ \fp_standardise:NNNN
+ \l_fp_input_a_sign_int
+ \l_fp_output_integer_int
+ \l_fp_output_decimal_int
+ \l_fp_output_exponent_int
+ \tl_new:c { c_fp_sin ( \l_fp_arg_tl ) _fp }
+ \tl_gset:cx { c_fp_sin ( \l_fp_arg_tl ) _fp }
+ {
+ \if_int_compare:w \l_fp_input_a_sign_int > \c_zero
+ +
+ \else:
+ -
+ \fi:
+ \int_use:N \l_fp_output_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \int_value:w \int_eval:w
+ \l_fp_output_decimal_int + \c_one_thousand_million
+ e
+ \int_use:N \l_fp_output_exponent_int
+ }
+ }
+\cs_new_protected_nopar:Npn \fp_sin_aux_ii:
+ {
+ \if_case:w \l_fp_trig_octant_int
+ \or:
+ \exp_after:wN \fp_trig_calc_sin:
+ \or:
+ \exp_after:wN \fp_trig_calc_cos:
+ \or:
+ \exp_after:wN \fp_trig_calc_cos:
+ \or:
+ \exp_after:wN \fp_trig_calc_sin:
+ \fi:
+ }
+\cs_new_protected_nopar:Npn \fp_cos:Nn { \fp_cos_aux:NNn \tl_set:Nn }
+\cs_new_protected_nopar:Npn \fp_gcos:Nn { \fp_cos_aux:NNn \tl_gset:Nn }
+\cs_generate_variant:Nn \fp_cos:Nn { c }
+\cs_generate_variant:Nn \fp_gcos:Nn { c }
+\cs_new_protected_nopar:Npn \fp_cos_aux:NNn #1#2#3
+ {
+ \group_begin:
+ \fp_split:Nn a {#3}
+ \fp_standardise:NNNN
+ \l_fp_input_a_sign_int
+ \l_fp_input_a_integer_int
+ \l_fp_input_a_decimal_int
+ \l_fp_input_a_exponent_int
+ \tl_set:Nx \l_fp_arg_tl
+ {
+ \if_int_compare:w \l_fp_input_a_sign_int < \c_zero
+ -
+ \else:
+ +
+ \fi:
+ \int_use:N \l_fp_input_a_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \int_value:w \int_eval:w
+ \l_fp_input_a_decimal_int + \c_one_thousand_million
+ e
+ \int_use:N \l_fp_input_a_exponent_int
+ }
+ \if_cs_exist:w c_fp_cos ( \l_fp_arg_tl ) _fp \cs_end:
+ \else:
+ \exp_after:wN \fp_cos_aux_i:
+ \fi:
+ \cs_set_protected_nopar:Npx \fp_tmp:w
+ {
+ \group_end:
+ #1 \exp_not:N #2
+ { \use:c { c_fp_cos ( \l_fp_arg_tl ) _fp } }
+ }
+ \fp_tmp:w
+ }
+\cs_new_protected_nopar:Npn \fp_cos_aux_i:
+ {
+ \fp_trig_normalise:
+ \fp_cos_aux_ii:
+ \if_int_compare:w \l_fp_output_integer_int = \c_one
+ \l_fp_output_exponent_int \c_zero
+ \else:
+ \l_fp_output_integer_int \l_fp_output_decimal_int
+ \l_fp_output_decimal_int \l_fp_output_extended_int
+ \l_fp_output_exponent_int -\c_nine
+ \fi:
+ \fp_standardise:NNNN
+ \l_fp_input_a_sign_int
+ \l_fp_output_integer_int
+ \l_fp_output_decimal_int
+ \l_fp_output_exponent_int
+ \tl_new:c { c_fp_cos ( \l_fp_arg_tl ) _fp }
+ \tl_gset:cx { c_fp_cos ( \l_fp_arg_tl ) _fp }
+ {
+ \if_int_compare:w \l_fp_input_a_sign_int > \c_zero
+ +
+ \else:
+ -
+ \fi:
+ \int_use:N \l_fp_output_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \int_value:w \int_eval:w
+ \l_fp_output_decimal_int + \c_one_thousand_million
+ e
+ \int_use:N \l_fp_output_exponent_int
+ }
+ }
+\cs_new_protected_nopar:Npn \fp_cos_aux_ii:
+ {
+ \if_case:w \l_fp_trig_octant_int
+ \or:
+ \exp_after:wN \fp_trig_calc_cos:
+ \or:
+ \exp_after:wN \fp_trig_calc_sin:
+ \or:
+ \exp_after:wN \fp_trig_calc_sin:
+ \or:
+ \exp_after:wN \fp_trig_calc_cos:
+ \fi:
+ \if_int_compare:w \l_fp_input_a_sign_int > \c_zero
+ \if_int_compare:w \l_fp_trig_octant_int > \c_two
+ \l_fp_input_a_sign_int \c_minus_one
+ \fi:
+ \else:
+ \if_int_compare:w \l_fp_trig_octant_int > \c_two
+ \else:
+ \l_fp_input_a_sign_int \c_one
+ \fi:
+ \fi:
+ }
+\cs_new_protected_nopar:Npn \fp_trig_calc_cos:
+ {
+ \if_int_compare:w \l_fp_input_a_decimal_int = \c_zero
+ \l_fp_output_integer_int \c_one
+ \l_fp_output_decimal_int \c_zero
+ \else:
+ \l_fp_trig_sign_int \c_minus_one
+ \fp_mul:NNNNNN
+ \l_fp_input_a_decimal_int \l_fp_input_a_extended_int
+ \l_fp_input_a_decimal_int \l_fp_input_a_extended_int
+ \l_fp_trig_decimal_int \l_fp_trig_extended_int
+ \fp_div_integer:NNNNN
+ \l_fp_trig_decimal_int \l_fp_trig_extended_int
+ \c_two
+ \l_fp_trig_decimal_int \l_fp_trig_extended_int
+ \l_fp_count_int \c_three
+ \if_int_compare:w \l_fp_trig_extended_int = \c_zero
+ \if_int_compare:w \l_fp_trig_decimal_int = \c_zero
+ \l_fp_output_integer_int \c_one
+ \l_fp_output_decimal_int \c_zero
+ \l_fp_output_extended_int \c_zero
+ \else:
+ \l_fp_output_integer_int \c_zero
+ \l_fp_output_decimal_int \c_one_thousand_million
+ \l_fp_output_extended_int \c_zero
+ \fi:
+ \else:
+ \l_fp_output_integer_int \c_zero
+ \l_fp_output_decimal_int 999999999 \scan_stop:
+ \l_fp_output_extended_int \c_one_thousand_million
+ \fi:
+ \tex_advance:D \l_fp_output_extended_int -\l_fp_trig_extended_int
+ \tex_advance:D \l_fp_output_decimal_int -\l_fp_trig_decimal_int
+ \exp_after:wN \fp_trig_calc_Taylor:
+ \fi:
+ }
+\cs_new_protected_nopar:Npn \fp_trig_calc_sin:
+ {
+ \l_fp_output_integer_int \c_zero
+ \if_int_compare:w \l_fp_input_a_decimal_int = \c_zero
+ \l_fp_output_decimal_int \c_zero
+ \else:
+ \l_fp_output_decimal_int \l_fp_input_a_decimal_int
+ \l_fp_output_extended_int \l_fp_input_a_extended_int
+ \l_fp_trig_sign_int \c_one
+ \l_fp_trig_decimal_int \l_fp_input_a_decimal_int
+ \l_fp_trig_extended_int \l_fp_input_a_extended_int
+ \l_fp_count_int \c_two
+ \exp_after:wN \fp_trig_calc_Taylor:
+ \fi:
+ }
+\cs_new_protected_nopar:Npn \fp_trig_calc_Taylor:
+ {
+ \l_fp_trig_sign_int -\l_fp_trig_sign_int
+ \fp_mul:NNNNNN
+ \l_fp_trig_decimal_int \l_fp_trig_extended_int
+ \l_fp_input_a_decimal_int \l_fp_input_a_extended_int
+ \l_fp_trig_decimal_int \l_fp_trig_extended_int
+ \fp_mul:NNNNNN
+ \l_fp_trig_decimal_int \l_fp_trig_extended_int
+ \l_fp_input_a_decimal_int \l_fp_input_a_extended_int
+ \l_fp_trig_decimal_int \l_fp_trig_extended_int
+ \fp_div_integer:NNNNN
+ \l_fp_trig_decimal_int \l_fp_trig_extended_int
+ \l_fp_count_int
+ \l_fp_trig_decimal_int \l_fp_trig_extended_int
+ \tex_advance:D \l_fp_count_int \c_one
+ \fp_div_integer:NNNNN
+ \l_fp_trig_decimal_int \l_fp_trig_extended_int
+ \l_fp_count_int
+ \l_fp_trig_decimal_int \l_fp_trig_extended_int
+ \tex_advance:D \l_fp_count_int \c_one
+ \if_int_compare:w \l_fp_trig_decimal_int > \c_zero
+ \if_int_compare:w \l_fp_trig_sign_int > \c_zero
+ \tex_advance:D \l_fp_output_decimal_int \l_fp_trig_decimal_int
+ \tex_advance:D \l_fp_output_extended_int
+ \l_fp_trig_extended_int
+ \if_int_compare:w \l_fp_output_extended_int < \c_one_thousand_million
+ \else:
+ \tex_advance:D \l_fp_output_decimal_int \c_one
+ \tex_advance:D \l_fp_output_extended_int
+ -\c_one_thousand_million
+ \fi:
+ \if_int_compare:w \l_fp_output_decimal_int < \c_one_thousand_million
+ \else:
+ \tex_advance:D \l_fp_output_integer_int \c_one
+ \tex_advance:D \l_fp_output_decimal_int
+ -\c_one_thousand_million
+ \fi:
+ \else:
+ \tex_advance:D \l_fp_output_decimal_int -\l_fp_trig_decimal_int
+ \tex_advance:D \l_fp_output_extended_int
+ -\l_fp_input_a_extended_int
+ \if_int_compare:w \l_fp_output_extended_int < \c_zero
+ \tex_advance:D \l_fp_output_decimal_int \c_minus_one
+ \tex_advance:D \l_fp_output_extended_int \c_one_thousand_million
+ \fi:
+ \if_int_compare:w \l_fp_output_decimal_int < \c_zero
+ \tex_advance:D \l_fp_output_integer_int \c_minus_one
+ \tex_advance:D \l_fp_output_decimal_int \c_one_thousand_million
+ \fi:
+ \fi:
+ \exp_after:wN \fp_trig_calc_Taylor:
+ \fi:
+ }
+\cs_new_protected_nopar:Npn \fp_tan:Nn { \fp_tan_aux:NNn \tl_set:Nn }
+\cs_new_protected_nopar:Npn \fp_gtan:Nn { \fp_tan_aux:NNn \tl_gset:Nn }
+\cs_generate_variant:Nn \fp_tan:Nn { c }
+\cs_generate_variant:Nn \fp_gtan:Nn { c }
+\cs_new_protected_nopar:Npn \fp_tan_aux:NNn #1#2#3
+ {
+ \group_begin:
+ \fp_split:Nn a {#3}
+ \fp_standardise:NNNN
+ \l_fp_input_a_sign_int
+ \l_fp_input_a_integer_int
+ \l_fp_input_a_decimal_int
+ \l_fp_input_a_exponent_int
+ \tl_set:Nx \l_fp_arg_tl
+ {
+ \if_int_compare:w \l_fp_input_a_sign_int < \c_zero
+ -
+ \else:
+ +
+ \fi:
+ \int_use:N \l_fp_input_a_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \int_value:w \int_eval:w
+ \l_fp_input_a_decimal_int + \c_one_thousand_million
+ e
+ \int_use:N \l_fp_input_a_exponent_int
+ }
+ \if_int_compare:w \l_fp_input_a_exponent_int < -\c_five
+ \cs_set_protected_nopar:Npx \fp_tmp:w
+ {
+ \group_end:
+ #1 \exp_not:N #2 { \l_fp_arg_tl }
+ }
+ \else:
+ \if_cs_exist:w
+ c_fp_tan ( \l_fp_arg_tl ) _fp
+ \cs_end:
+ \else:
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \fp_tan_aux_i:
+ \fi:
+ \cs_set_protected_nopar:Npx \fp_tmp:w
+ {
+ \group_end:
+ #1 \exp_not:N #2
+ { \use:c { c_fp_tan ( \l_fp_arg_tl ) _fp } }
+ }
+ \fi:
+ \fp_tmp:w
+ }
+\cs_new_protected_nopar:Npn \fp_tan_aux_i:
+ {
+ \if_int_compare:w \l_fp_input_a_exponent_int < \c_ten
+ \exp_after:wN \fp_tan_aux_ii:
+ \else:
+ \cs_new_eq:cN { c_fp_tan ( \l_fp_arg_tl ) _fp }
+ \c_zero_fp
+ \exp_after:wN \fp_trig_overflow_msg:
+ \fi:
+ }
+\cs_new_protected_nopar:Npn \fp_tan_aux_ii:
+ {
+ \fp_trig_normalise:
+ \if_int_compare:w \l_fp_input_a_sign_int > \c_zero
+ \if_int_compare:w \l_fp_trig_octant_int > \c_two
+ \l_fp_output_sign_int \c_minus_one
+ \else:
+ \l_fp_output_sign_int \c_one
+ \fi:
+ \else:
+ \if_int_compare:w \l_fp_trig_octant_int > \c_two
+ \l_fp_output_sign_int \c_one
+ \else:
+ \l_fp_output_sign_int \c_minus_one
+ \fi:
+ \fi:
+ \fp_cos_aux_ii:
+ \if_int_compare:w \l_fp_input_a_decimal_int = \c_zero
+ \if_int_compare:w \l_fp_input_a_integer_int = \c_zero
+ \cs_new_eq:cN { c_fp_tan ( \l_fp_arg_tl ) _fp }
+ \c_undefined_fp
+ \else:
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \fp_tan_aux_iii:
+ \fi:
+ \else:
+ \exp_after:wN \fp_tan_aux_iii:
+ \fi:
+ }
+\cs_new_protected_nopar:Npn \fp_tan_aux_iii:
+ {
+ \l_fp_input_b_integer_int \l_fp_output_decimal_int
+ \l_fp_input_b_decimal_int \l_fp_output_extended_int
+ \l_fp_input_b_exponent_int -\c_nine
+ \fp_standardise:NNNN
+ \l_fp_input_b_sign_int
+ \l_fp_input_b_integer_int
+ \l_fp_input_b_decimal_int
+ \l_fp_input_b_exponent_int
+ \fp_sin_aux_ii:
+ \l_fp_input_a_integer_int \l_fp_output_decimal_int
+ \l_fp_input_a_decimal_int \l_fp_output_extended_int
+ \l_fp_input_a_exponent_int -\c_nine
+ \fp_standardise:NNNN
+ \l_fp_input_a_sign_int
+ \l_fp_input_a_integer_int
+ \l_fp_input_a_decimal_int
+ \l_fp_input_a_exponent_int
+ \if_int_compare:w \l_fp_input_a_decimal_int = \c_zero
+ \if_int_compare:w \l_fp_input_a_integer_int = \c_zero
+ \cs_new_eq:cN { c_fp_tan ( \l_fp_arg_tl ) _fp }
+ \c_zero_fp
+ \else:
+ \exp_after:wN \exp_after:wN \exp_after:wN \fp_tan_aux_iv:
+ \fi:
+ \else:
+ \exp_after:wN \fp_tan_aux_iv:
+ \fi:
+ }
+\cs_new_protected_nopar:Npn \fp_tan_aux_iv:
+ {
+ \l_fp_output_integer_int \c_zero
+ \l_fp_output_decimal_int \c_zero
+ \cs_set_eq:NN \fp_div_store: \fp_div_store_integer:
+ \l_fp_div_offset_int \c_one_hundred_million
+ \fp_div_loop:
+ \l_fp_output_exponent_int
+ \int_eval:w
+ \l_fp_input_a_exponent_int - \l_fp_input_b_exponent_int
+ \int_eval_end:
+ \fp_standardise:NNNN
+ \l_fp_output_sign_int
+ \l_fp_output_integer_int
+ \l_fp_output_decimal_int
+ \l_fp_output_exponent_int
+ \tl_new:c { c_fp_tan ( \l_fp_arg_tl ) _fp }
+ \tl_gset:cx { c_fp_tan ( \l_fp_arg_tl ) _fp }
+ {
+ \if_int_compare:w \l_fp_output_sign_int > \c_zero
+ +
+ \else:
+ -
+ \fi:
+ \int_use:N \l_fp_output_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \int_value:w \int_eval:w
+ \l_fp_output_decimal_int + \c_one_thousand_million
+ e
+ \int_use:N \l_fp_output_exponent_int
+ }
+ }
+\tl_const:cn { c_fp_exp_1_tl } { { 2 } { 718281828 } { 459045235 } { 0 } }
+\tl_const:cn { c_fp_exp_2_tl } { { 7 } { 389056098 } { 930650227 } { 0 } }
+\tl_const:cn { c_fp_exp_3_tl } { { 2 } { 008553692 } { 318766774 } { 1 } }
+\tl_const:cn { c_fp_exp_4_tl } { { 5 } { 459815003 } { 314423908 } { 1 } }
+\tl_const:cn { c_fp_exp_5_tl } { { 1 } { 484131591 } { 025766034 } { 2 } }
+\tl_const:cn { c_fp_exp_6_tl } { { 4 } { 034287934 } { 927351226 } { 2 } }
+\tl_const:cn { c_fp_exp_7_tl } { { 1 } { 096633158 } { 428458599 } { 3 } }
+\tl_const:cn { c_fp_exp_8_tl } { { 2 } { 980957987 } { 041728275 } { 3 } }
+\tl_const:cn { c_fp_exp_9_tl } { { 8 } { 103083927 } { 575384008 } { 3 } }
+\tl_const:cn { c_fp_exp_10_tl } { { 2 } { 202646579 } { 480671652 } { 4 } }
+\tl_const:cn { c_fp_exp_20_tl } { { 4 } { 851651954 } { 097902280 } { 8 } }
+\tl_const:cn { c_fp_exp_30_tl } { { 1 } { 068647458 } { 152446215 } { 13 } }
+\tl_const:cn { c_fp_exp_40_tl } { { 2 } { 353852668 } { 370199854 } { 17 } }
+\tl_const:cn { c_fp_exp_50_tl } { { 5 } { 184705528 } { 587072464 } { 21 } }
+\tl_const:cn { c_fp_exp_60_tl } { { 1 } { 142007389 } { 815684284 } { 26 } }
+\tl_const:cn { c_fp_exp_70_tl } { { 2 } { 515438670 } { 919167006 } { 30 } }
+\tl_const:cn { c_fp_exp_80_tl } { { 5 } { 540622384 } { 393510053 } { 34 } }
+\tl_const:cn { c_fp_exp_90_tl } { { 1 } { 220403294 } { 317840802 } { 39 } }
+\tl_const:cn { c_fp_exp_100_tl } { { 2 } { 688117141 } { 816135448 } { 43 } }
+\tl_const:cn { c_fp_exp_200_tl } { { 7 } { 225973768 } { 125749258 } { 86 } }
+\tl_const:cn { c_fp_exp_-1_tl } { { 3 } { 678794411 } { 71442322 } { -1 } }
+\tl_const:cn { c_fp_exp_-2_tl } { { 1 } { 353352832 } { 366132692 } { -1 } }
+\tl_const:cn { c_fp_exp_-3_tl } { { 4 } { 978706836 } { 786394298 } { -2 } }
+\tl_const:cn { c_fp_exp_-4_tl } { { 1 } { 831563888 } { 873418029 } { -2 } }
+\tl_const:cn { c_fp_exp_-5_tl } { { 6 } { 737946999 } { 085467097 } { -3 } }
+\tl_const:cn { c_fp_exp_-6_tl } { { 2 } { 478752176 } { 666358423 } { -3 } }
+\tl_const:cn { c_fp_exp_-7_tl } { { 9 } { 118819655 } { 545162080 } { -4 } }
+\tl_const:cn { c_fp_exp_-8_tl } { { 3 } { 354626279 } { 025118388 } { -4 } }
+\tl_const:cn { c_fp_exp_-9_tl } { { 1 } { 234098040 } { 866795495 } { -4 } }
+\tl_const:cn { c_fp_exp_-10_tl } { { 4 } { 539992976 } { 248451536 } { -5 } }
+\tl_const:cn { c_fp_exp_-20_tl } { { 2 } { 061153622 } { 438557828 } { -9 } }
+\tl_const:cn { c_fp_exp_-30_tl } { { 9 } { 357622968 } { 840174605 } { -14 } }
+\tl_const:cn { c_fp_exp_-40_tl } { { 4 } { 248354255 } { 291588995 } { -18 } }
+\tl_const:cn { c_fp_exp_-50_tl } { { 1 } { 928749847 } { 963917783 } { -22 } }
+\tl_const:cn { c_fp_exp_-60_tl } { { 8 } { 756510762 } { 696520338 } { -27 } }
+\tl_const:cn { c_fp_exp_-70_tl } { { 3 } { 975449735 } { 908646808 } { -31 } }
+\tl_const:cn { c_fp_exp_-80_tl } { { 1 } { 804851387 } { 845415172 } { -35 } }
+\tl_const:cn { c_fp_exp_-90_tl } { { 8 } { 194012623 } { 990515430 } { -40 } }
+\tl_const:cn { c_fp_exp_-100_tl } { { 3 } { 720075976 } { 020835963 } { -44 } }
+\tl_const:cn { c_fp_exp_-200_tl } { { 1 } { 383896526 } { 736737530 } { -87 } }
+\cs_new_protected_nopar:Npn \fp_exp:Nn { \fp_exp_aux:NNn \tl_set:Nn }
+\cs_new_protected_nopar:Npn \fp_gexp:Nn { \fp_exp_aux:NNn \tl_gset:Nn }
+\cs_generate_variant:Nn \fp_exp:Nn { c }
+\cs_generate_variant:Nn \fp_gexp:Nn { c }
+\cs_new_protected_nopar:Npn \fp_exp_aux:NNn #1#2#3
+ {
+ \group_begin:
+ \fp_split:Nn a {#3}
+ \fp_standardise:NNNN
+ \l_fp_input_a_sign_int
+ \l_fp_input_a_integer_int
+ \l_fp_input_a_decimal_int
+ \l_fp_input_a_exponent_int
+ \l_fp_input_a_extended_int \c_zero
+ \tl_set:Nx \l_fp_arg_tl
+ {
+ \if_int_compare:w \l_fp_input_a_sign_int < \c_zero
+ -
+ \else:
+ +
+ \fi:
+ \int_use:N \l_fp_input_a_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \int_value:w \int_eval:w
+ \l_fp_input_a_decimal_int + \c_one_thousand_million
+ e
+ \int_use:N \l_fp_input_a_exponent_int
+ }
+ \if_cs_exist:w c_fp_exp ( \l_fp_arg_tl ) _fp \cs_end:
+ \else:
+ \exp_after:wN \fp_exp_internal:
+ \fi:
+ \cs_set_protected_nopar:Npx \fp_tmp:w
+ {
+ \group_end:
+ #1 \exp_not:N #2
+ {
+ \if_cs_exist:w c_fp_exp ( \l_fp_arg_tl ) _fp
+ \cs_end:
+ \use:c { c_fp_exp ( \l_fp_arg_tl ) _fp }
+ \else:
+ \c_zero_fp
+ \fi:
+ }
+ }
+ \fp_tmp:w
+ }
+\cs_new_protected_nopar:Npn \fp_exp_internal:
+ {
+ \if_int_compare:w \l_fp_input_a_exponent_int < \c_three
+ \fp_extended_normalise:
+ \if_int_compare:w \l_fp_input_a_sign_int > \c_zero
+ \if_int_compare:w \l_fp_input_a_integer_int < 230 \scan_stop:
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \exp_after:wN \fp_exp_aux:
+ \else:
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \exp_after:wN \fp_exp_overflow_msg:
+ \fi:
+ \else:
+ \if_int_compare:w \l_fp_input_a_integer_int < 230 \scan_stop:
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \exp_after:wN \fp_exp_aux:
+ \else:
+ \fp_exp_const:cx { c_fp_exp ( \l_fp_arg_tl ) _fp }
+ { \c_zero_fp }
+ \fi:
+ \fi:
+ \else:
+ \exp_after:wN \fp_exp_overflow_msg:
+ \fi:
+ }
+\cs_new_protected_nopar:Npn \fp_exp_aux:
+ {
+ \if_int_compare:w \l_fp_input_a_integer_int > \c_zero
+ \exp_after:wN \fp_exp_integer:
+ \else:
+ \l_fp_output_integer_int \c_one
+ \l_fp_output_decimal_int \c_zero
+ \l_fp_output_extended_int \c_zero
+ \l_fp_output_exponent_int \c_zero
+ \exp_after:wN \fp_exp_decimal:
+ \fi:
+ }
+\cs_new_protected_nopar:Npn \fp_exp_integer:
+ {
+ \if_int_compare:w \l_fp_input_a_integer_int < \c_one_hundred
+ \l_fp_exp_integer_int \c_one
+ \l_fp_exp_decimal_int \c_zero
+ \l_fp_exp_extended_int \c_zero
+ \l_fp_exp_exponent_int \c_zero
+ \exp_after:wN \fp_exp_integer_tens:
+ \else:
+ \tl_set:Nx \l_fp_tmp_tl
+ {
+ \exp_after:wN \use_i:nnn
+ \int_use:N \l_fp_input_a_integer_int
+ }
+ \l_fp_input_a_integer_int
+ \int_eval:w
+ \l_fp_input_a_integer_int - \l_fp_tmp_tl 00
+ \int_eval_end:
+ \if_int_compare:w \l_fp_input_a_sign_int < \c_zero
+ \if_int_compare:w \l_fp_output_integer_int > 200 \scan_stop:
+ \fp_exp_const:cx { c_fp_exp ( \l_fp_arg_tl ) _fp }
+ { \c_zero_fp }
+ \else:
+ \fp_exp_integer_const:n { - \l_fp_tmp_tl 00 }
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \exp_after:wN \fp_exp_integer_tens:
+ \fi:
+ \else:
+ \fp_exp_integer_const:n { \l_fp_tmp_tl 00 }
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \exp_after:wN \fp_exp_integer_tens:
+ \fi:
+ \fi:
+ }
+\cs_new_protected_nopar:Npn \fp_exp_integer_tens:
+ {
+ \l_fp_output_integer_int \l_fp_exp_integer_int
+ \l_fp_output_decimal_int \l_fp_exp_decimal_int
+ \l_fp_output_extended_int \l_fp_exp_extended_int
+ \l_fp_output_exponent_int \l_fp_exp_exponent_int
+ \if_int_compare:w \l_fp_input_a_integer_int > \c_nine
+ \tl_set:Nx \l_fp_tmp_tl
+ {
+ \exp_after:wN \use_i:nn
+ \int_use:N \l_fp_input_a_integer_int
+ }
+ \l_fp_input_a_integer_int
+ \int_eval:w
+ \l_fp_input_a_integer_int - \l_fp_tmp_tl 0
+ \int_eval_end:
+ \if_int_compare:w \l_fp_input_a_sign_int > \c_zero
+ \fp_exp_integer_const:n { \l_fp_tmp_tl 0 }
+ \else:
+ \fp_exp_integer_const:n { - \l_fp_tmp_tl 0 }
+ \fi:
+ \fp_mul:NNNNNNNNN
+ \l_fp_exp_integer_int \l_fp_exp_decimal_int \l_fp_exp_extended_int
+ \l_fp_output_integer_int \l_fp_output_decimal_int
+ \l_fp_output_extended_int
+ \l_fp_output_integer_int \l_fp_output_decimal_int
+ \l_fp_output_extended_int
+ \tex_advance:D \l_fp_output_exponent_int \l_fp_exp_exponent_int
+ \fp_extended_normalise_output:
+ \fi:
+ \fp_exp_integer_units:
+ }
+\cs_new_protected_nopar:Npn \fp_exp_integer_units:
+ {
+ \if_int_compare:w \l_fp_input_a_integer_int > \c_zero
+ \if_int_compare:w \l_fp_input_a_sign_int > \c_zero
+ \fp_exp_integer_const:n { \int_use:N \l_fp_input_a_integer_int }
+ \else:
+ \fp_exp_integer_const:n
+ { - \int_use:N \l_fp_input_a_integer_int }
+ \fi:
+ \fp_mul:NNNNNNNNN
+ \l_fp_exp_integer_int \l_fp_exp_decimal_int \l_fp_exp_extended_int
+ \l_fp_output_integer_int \l_fp_output_decimal_int
+ \l_fp_output_extended_int
+ \l_fp_output_integer_int \l_fp_output_decimal_int
+ \l_fp_output_extended_int
+ \tex_advance:D \l_fp_output_exponent_int \l_fp_exp_exponent_int
+ \fp_extended_normalise_output:
+ \fi:
+ \fp_exp_decimal:
+ }
+\cs_new_protected_nopar:Npn \fp_exp_integer_const:n #1
+ {
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \fp_exp_integer_const:nnnn
+ \cs:w c_fp_exp_ #1 _tl \cs_end:
+ }
+\cs_new_protected_nopar:Npn \fp_exp_integer_const:nnnn #1#2#3#4
+ {
+ \l_fp_exp_integer_int #1 \scan_stop:
+ \l_fp_exp_decimal_int #2 \scan_stop:
+ \l_fp_exp_extended_int #3 \scan_stop:
+ \l_fp_exp_exponent_int #4 \scan_stop:
+ }
+\cs_new_protected_nopar:Npn \fp_exp_decimal:
+ {
+ \if_int_compare:w \l_fp_input_a_decimal_int > \c_zero
+ \if_int_compare:w \l_fp_input_a_sign_int > \c_zero
+ \l_fp_exp_integer_int \c_one
+ \l_fp_exp_decimal_int \l_fp_input_a_decimal_int
+ \l_fp_exp_extended_int \l_fp_input_a_extended_int
+ \else:
+ \l_fp_exp_integer_int \c_zero
+ \if_int_compare:w \l_fp_exp_extended_int = \c_zero
+ \l_fp_exp_decimal_int
+ \int_eval:w
+ \c_one_thousand_million - \l_fp_input_a_decimal_int
+ \int_eval_end:
+ \l_fp_exp_extended_int \c_zero
+ \else:
+ \l_fp_exp_decimal_int
+ \int_eval:w
+ 999999999 - \l_fp_input_a_decimal_int
+ \scan_stop:
+ \l_fp_exp_extended_int
+ \int_eval:w
+ \c_one_thousand_million - \l_fp_input_a_extended_int
+ \int_eval_end:
+ \fi:
+ \fi:
+ \l_fp_input_b_sign_int \l_fp_input_a_sign_int
+ \l_fp_input_b_decimal_int \l_fp_input_a_decimal_int
+ \l_fp_input_b_extended_int \l_fp_input_a_extended_int
+ \l_fp_count_int \c_one
+ \fp_exp_Taylor:
+ \fp_mul:NNNNNNNNN
+ \l_fp_exp_integer_int \l_fp_exp_decimal_int \l_fp_exp_extended_int
+ \l_fp_output_integer_int \l_fp_output_decimal_int
+ \l_fp_output_extended_int
+ \l_fp_output_integer_int \l_fp_output_decimal_int
+ \l_fp_output_extended_int
+ \fi:
+ \if_int_compare:w \l_fp_output_extended_int < \c_five_hundred_million
+ \else:
+ \tex_advance:D \l_fp_output_decimal_int \c_one
+ \if_int_compare:w \l_fp_output_decimal_int < \c_one_thousand_million
+ \else:
+ \l_fp_output_decimal_int \c_zero
+ \tex_advance:D \l_fp_output_integer_int \c_one
+ \fi:
+ \fi:
+ \fp_standardise:NNNN
+ \l_fp_output_sign_int
+ \l_fp_output_integer_int
+ \l_fp_output_decimal_int
+ \l_fp_output_exponent_int
+ \fp_exp_const:cx { c_fp_exp ( \l_fp_arg_tl ) _fp }
+ {
+ +
+ \int_use:N \l_fp_output_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \int_value:w \int_eval:w
+ \l_fp_output_decimal_int + \c_one_thousand_million
+ e
+ \int_use:N \l_fp_output_exponent_int
+ }
+ }
+\cs_new_protected_nopar:Npn \fp_exp_Taylor:
+ {
+ \tex_advance:D \l_fp_count_int \c_one
+ \tex_multiply:D \l_fp_input_b_sign_int \l_fp_input_a_sign_int
+ \fp_mul:NNNNNN
+ \l_fp_input_a_decimal_int \l_fp_input_a_extended_int
+ \l_fp_input_b_decimal_int \l_fp_input_b_extended_int
+ \l_fp_input_b_decimal_int \l_fp_input_b_extended_int
+ \fp_div_integer:NNNNN
+ \l_fp_input_b_decimal_int \l_fp_input_b_extended_int
+ \l_fp_count_int
+ \l_fp_input_b_decimal_int \l_fp_input_b_extended_int
+ \if_int_compare:w
+ \int_eval:w
+ \l_fp_input_b_decimal_int + \l_fp_input_b_extended_int
+ > \c_zero
+ \if_int_compare:w \l_fp_input_b_sign_int > \c_zero
+ \tex_advance:D \l_fp_exp_decimal_int \l_fp_input_b_decimal_int
+ \tex_advance:D \l_fp_exp_extended_int
+ \l_fp_input_b_extended_int
+ \if_int_compare:w \l_fp_exp_extended_int < \c_one_thousand_million
+ \else:
+ \tex_advance:D \l_fp_exp_decimal_int \c_one
+ \tex_advance:D \l_fp_exp_extended_int
+ -\c_one_thousand_million
+ \fi:
+ \if_int_compare:w \l_fp_exp_decimal_int < \c_one_thousand_million
+ \else:
+ \tex_advance:D \l_fp_exp_integer_int \c_one
+ \tex_advance:D \l_fp_exp_decimal_int
+ -\c_one_thousand_million
+ \fi:
+ \else:
+ \tex_advance:D \l_fp_exp_decimal_int -\l_fp_input_b_decimal_int
+ \tex_advance:D \l_fp_exp_extended_int
+ -\l_fp_input_a_extended_int
+ \if_int_compare:w \l_fp_exp_extended_int < \c_zero
+ \tex_advance:D \l_fp_exp_decimal_int \c_minus_one
+ \tex_advance:D \l_fp_exp_extended_int \c_one_thousand_million
+ \fi:
+ \if_int_compare:w \l_fp_exp_decimal_int < \c_zero
+ \tex_advance:D \l_fp_exp_integer_int \c_minus_one
+ \tex_advance:D \l_fp_exp_decimal_int \c_one_thousand_million
+ \fi:
+ \fi:
+ \exp_after:wN \fp_exp_Taylor:
+ \fi:
+ }
+\cs_new_protected_nopar:Npn \fp_exp_const:Nx #1#2
+ {
+ \tl_new:N #1
+ \tl_gset:Nx #1 {#2}
+ }
+\cs_generate_variant:Nn \fp_exp_const:Nx { c }
+\tl_const:cn { c_fp_ln_10_1_tl } { { 2 } { 302585092 } { 994045684 } { 0 } }
+\tl_const:cn { c_fp_ln_10_2_tl } { { 4 } { 605170185 } { 988091368 } { 0 } }
+\tl_const:cn { c_fp_ln_10_3_tl } { { 6 } { 907755278 } { 982137052 } { 0 } }
+\tl_const:cn { c_fp_ln_10_4_tl } { { 9 } { 210340371 } { 976182736 } { 0 } }
+\tl_const:cn { c_fp_ln_10_5_tl } { { 1 } { 151292546 } { 497022842 } { 1 } }
+\tl_const:cn { c_fp_ln_10_6_tl } { { 1 } { 381551055 } { 796427410 } { 1 } }
+\tl_const:cn { c_fp_ln_10_7_tl } { { 1 } { 611809565 } { 095831979 } { 1 } }
+\tl_const:cn { c_fp_ln_10_8_tl } { { 1 } { 842068074 } { 395226547 } { 1 } }
+\tl_const:cn { c_fp_ln_10_9_tl } { { 2 } { 072326583 } { 694641116 } { 1 } }
+\tl_const:cn { c_fp_ln_2_1_tl } { { 0 } { 693147180 } { 559945309 } { 0 } }
+\tl_const:cn { c_fp_ln_2_2_tl } { { 1 } { 386294361 } { 119890618 } { 0 } }
+\tl_const:cn { c_fp_ln_2_3_tl } { { 2 } { 079441541 } { 679835928 } { 0 } }
+\cs_new_protected_nopar:Npn \fp_ln:Nn { \fp_ln_aux:NNn \tl_set:Nn }
+\cs_new_protected_nopar:Npn \fp_gln:Nn { \fp_ln_aux:NNn \tl_gset:Nn }
+\cs_generate_variant:Nn \fp_ln:Nn { c }
+\cs_generate_variant:Nn \fp_gln:Nn { c }
+\cs_new_protected_nopar:Npn \fp_ln_aux:NNn #1#2#3
+ {
+ \group_begin:
+ \fp_split:Nn a {#3}
+ \fp_standardise:NNNN
+ \l_fp_input_a_sign_int
+ \l_fp_input_a_integer_int
+ \l_fp_input_a_decimal_int
+ \l_fp_input_a_exponent_int
+ \if_int_compare:w \l_fp_input_a_sign_int > \c_zero
+ \if_int_compare:w
+ \int_eval:w
+ \l_fp_input_a_integer_int + \l_fp_input_a_decimal_int
+ > \c_zero
+ \exp_after:wN \exp_after:wN \exp_after:wN \fp_ln_aux:
+ \else:
+ \cs_set_protected_nopar:Npx \fp_tmp:w ##1##2
+ {
+ \group_end:
+ ##1 \exp_not:N ##2 { \c_zero_fp }
+ }
+ \exp_after:wN \exp_after:wN \exp_after:wN \fp_ln_error_msg:
+ \fi:
+ \else:
+ \cs_set_protected_nopar:Npx \fp_tmp:w ##1##2
+ {
+ \group_end:
+ ##1 \exp_not:N ##2 { \c_zero_fp }
+ }
+ \exp_after:wN \fp_ln_error_msg:
+ \fi:
+ \fp_tmp:w #1 #2
+ }
+\cs_new_protected_nopar:Npn \fp_ln_aux:
+ {
+ \tl_set:Nx \l_fp_arg_tl
+ {
+ +
+ \int_use:N \l_fp_input_a_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \int_value:w \int_eval:w
+ \l_fp_input_a_decimal_int + \c_one_thousand_million
+ e
+ \int_use:N \l_fp_input_a_exponent_int
+ }
+ \if_cs_exist:w c_fp_ln ( \l_fp_arg_tl ) _fp \cs_end:
+ \else:
+ \exp_after:wN \fp_ln_exponent:
+ \fi:
+ \cs_set_protected_nopar:Npx \fp_tmp:w ##1##2
+ {
+ \group_end:
+ ##1 \exp_not:N ##2
+ { \use:c { c_fp_ln ( \l_fp_arg_tl ) _fp } }
+ }
+ }
+\cs_new_protected_nopar:Npn \fp_ln_exponent:
+ {
+ \fp_ln_internal:
+ \if_int_compare:w \l_fp_output_extended_int < \c_five_hundred_million
+ \else:
+ \tex_advance:D \l_fp_output_decimal_int \c_one
+ \if_int_compare:w \l_fp_output_decimal_int < \c_one_thousand_million
+ \else:
+ \l_fp_output_decimal_int \c_zero
+ \tex_advance:D \l_fp_output_integer_int \c_one
+ \fi:
+ \fi:
+ \fp_standardise:NNNN
+ \l_fp_output_sign_int
+ \l_fp_output_integer_int
+ \l_fp_output_decimal_int
+ \l_fp_output_exponent_int
+ \tl_const:cx { c_fp_ln ( \l_fp_arg_tl ) _fp }
+ {
+ \if_int_compare:w \l_fp_output_sign_int > \c_zero
+ +
+ \else:
+ -
+ \fi:
+ \int_use:N \l_fp_output_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \int_value:w \int_eval:w
+ \l_fp_output_decimal_int + \c_one_thousand_million
+ \scan_stop:
+ e
+ \int_use:N \l_fp_output_exponent_int
+ }
+ }
+\cs_new_protected_nopar:Npn \fp_ln_internal:
+ {
+ \if_int_compare:w \l_fp_input_a_exponent_int < \c_zero
+ \l_fp_input_a_exponent_int -\l_fp_input_a_exponent_int
+ \l_fp_output_sign_int \c_minus_one
+ \else:
+ \l_fp_output_sign_int \c_one
+ \fi:
+ \if_int_compare:w \l_fp_input_a_exponent_int > \c_nine
+ \exp_after:wN \fp_ln_exponent_tens:NN
+ \int_use:N \l_fp_input_a_exponent_int
+ \else:
+ \l_fp_output_integer_int \c_zero
+ \l_fp_output_decimal_int \c_zero
+ \l_fp_output_extended_int \c_zero
+ \l_fp_output_exponent_int \c_zero
+ \fi:
+ \fp_ln_exponent_units:
+ }
+\cs_new_protected_nopar:Npn \fp_ln_exponent_tens:NN #1 #2
+ {
+ \l_fp_input_a_exponent_int #2 \scan_stop:
+ \fp_ln_const:nn { 10 } { #1 }
+ \tex_advance:D \l_fp_exp_exponent_int \c_one
+ \l_fp_output_integer_int \l_fp_exp_integer_int
+ \l_fp_output_decimal_int \l_fp_exp_decimal_int
+ \l_fp_output_extended_int \l_fp_exp_extended_int
+ \l_fp_output_exponent_int \l_fp_exp_exponent_int
+ }
+\cs_new_protected_nopar:Npn \fp_ln_exponent_units:
+ {
+ \if_int_compare:w \l_fp_input_a_exponent_int > \c_zero
+ \fp_ln_const:nn { 10 } { \int_use:N \l_fp_input_a_exponent_int }
+ \fp_ln_normalise:
+ \fp_add:NNNNNNNNN
+ \l_fp_exp_integer_int \l_fp_exp_decimal_int \l_fp_exp_extended_int
+ \l_fp_output_integer_int \l_fp_output_decimal_int
+ \l_fp_output_extended_int
+ \l_fp_output_integer_int \l_fp_output_decimal_int
+ \l_fp_output_extended_int
+ \fi:
+ \fp_ln_mantissa:
+ }
+\cs_new_protected_nopar:Npn \fp_ln_normalise:
+ {
+ \if_int_compare:w \l_fp_exp_exponent_int < \l_fp_output_exponent_int
+ \tex_advance:D \l_fp_exp_decimal_int \c_one_thousand_million
+ \exp_after:wN \use_i:nn \exp_after:wN
+ \fp_ln_normalise_aux:NNNNNNNNN
+ \int_use:N \l_fp_exp_decimal_int
+ \exp_after:wN \fp_ln_normalise:
+ \else:
+ \l_fp_output_exponent_int \l_fp_exp_exponent_int
+ \fi:
+ }
+\cs_new_protected_nopar:Npn \fp_ln_normalise_aux:NNNNNNNNN #1#2#3#4#5#6#7#8#9
+ {
+ \if_int_compare:w \l_fp_exp_integer_int = \c_zero
+ \l_fp_exp_decimal_int #1#2#3#4#5#6#7#8 \scan_stop:
+ \else:
+ \tl_set:Nx \l_fp_tmp_tl
+ {
+ \int_use:N \l_fp_exp_integer_int
+ #1#2#3#4#5#6#7#8
+ }
+ \l_fp_exp_integer_int \c_zero
+ \l_fp_exp_decimal_int \l_fp_tmp_tl \scan_stop:
+ \fi:
+ \tex_divide:D \l_fp_exp_extended_int \c_ten
+ \tl_set:Nx \l_fp_tmp_tl
+ {
+ #9
+ \int_use:N \l_fp_exp_extended_int
+ }
+ \l_fp_exp_extended_int \l_fp_tmp_tl \scan_stop:
+ \tex_advance:D \l_fp_exp_exponent_int \c_one
+ }
+\cs_new_protected_nopar:Npn \fp_ln_mantissa:
+ {
+ \l_fp_count_int \c_zero
+ \l_fp_input_a_extended_int \c_zero
+ \fp_ln_mantissa_aux:
+ \if_int_compare:w \l_fp_count_int > \c_zero
+ \fp_ln_const:nn { 2 } { \int_use:N \l_fp_count_int }
+ \fp_ln_normalise:
+ \if_int_compare:w \l_fp_output_sign_int > \c_zero
+ \exp_after:wN \fp_add:NNNNNNNNN
+ \else:
+ \exp_after:wN \fp_sub:NNNNNNNNN
+ \fi:
+ \l_fp_output_integer_int \l_fp_output_decimal_int
+ \l_fp_output_extended_int
+ \l_fp_exp_integer_int \l_fp_exp_decimal_int \l_fp_exp_extended_int
+ \l_fp_output_integer_int \l_fp_output_decimal_int
+ \l_fp_output_extended_int
+ \fi:
+ \if_int_compare:w
+ \int_eval:w
+ \l_fp_input_a_integer_int + \l_fp_input_a_decimal_int > \c_one
+ \exp_after:wN \fp_ln_Taylor:
+ \fi:
+ }
+\cs_new_protected_nopar:Npn \fp_ln_mantissa_aux:
+ {
+ \if_int_compare:w \l_fp_input_a_integer_int > \c_one
+ \tex_advance:D \l_fp_count_int \c_one
+ \fp_ln_mantissa_divide_two:
+ \exp_after:wN \fp_ln_mantissa_aux:
+ \fi:
+ }
+\cs_new_protected_nopar:Npn \fp_ln_mantissa_divide_two:
+ {
+ \if_int_odd:w \l_fp_input_a_decimal_int
+ \tex_advance:D \l_fp_input_a_extended_int \c_one_thousand_million
+ \fi:
+ \if_int_odd:w \l_fp_input_a_integer_int
+ \tex_advance:D \l_fp_input_a_decimal_int \c_one_thousand_million
+ \fi:
+ \tex_divide:D \l_fp_input_a_integer_int \c_two
+ \tex_divide:D \l_fp_input_a_decimal_int \c_two
+ \tex_divide:D \l_fp_input_a_extended_int \c_two
+ }
+\cs_new_protected_nopar:Npn \fp_ln_const:nn #1#2
+ {
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \fp_exp_integer_const:nnnn
+ \cs:w c_fp_ln_ #1 _ #2 _tl \cs_end:
+ }
+\cs_new_protected_nopar:Npn \fp_ln_Taylor:
+ {
+ \group_begin:
+ \l_fp_input_a_integer_int \c_zero
+ \l_fp_input_a_exponent_int \c_zero
+ \l_fp_input_b_integer_int \c_two
+ \l_fp_input_b_decimal_int \l_fp_input_a_decimal_int
+ \l_fp_input_b_exponent_int \c_zero
+ \fp_div_internal:
+ \fp_ln_fixed:
+ \l_fp_input_a_integer_int \l_fp_output_integer_int
+ \l_fp_input_a_decimal_int \l_fp_output_decimal_int
+ \l_fp_input_a_extended_int \c_zero
+ \l_fp_input_a_exponent_int \l_fp_output_exponent_int
+ \l_fp_output_decimal_int \c_zero %^^A Bug?
+ \l_fp_output_decimal_int \l_fp_input_a_decimal_int
+ \l_fp_output_extended_int \l_fp_input_a_extended_int
+ \fp_mul:NNNNNN
+ \l_fp_input_a_decimal_int \l_fp_input_a_extended_int
+ \l_fp_input_a_decimal_int \l_fp_input_a_extended_int
+ \l_fp_input_b_decimal_int \l_fp_input_b_extended_int
+ \l_fp_count_int \c_one
+ \fp_ln_Taylor_aux:
+ \cs_set_protected_nopar:Npx \fp_tmp:w
+ {
+ \group_end:
+ \l_fp_exp_integer_int \c_zero
+ \exp_not:N \l_fp_exp_decimal_int
+ \int_use:N \l_fp_output_decimal_int \scan_stop:
+ \exp_not:N \l_fp_exp_extended_int
+ \int_use:N \l_fp_output_extended_int \scan_stop:
+ \exp_not:N \l_fp_exp_exponent_int
+ \int_use:N \l_fp_output_exponent_int \scan_stop:
+ }
+ \fp_tmp:w
+ \tex_advance:D \l_fp_exp_decimal_int \l_fp_exp_decimal_int
+ \if_int_compare:w \l_fp_exp_extended_int < \c_five_hundred_million
+ \else:
+ \tex_advance:D \l_fp_exp_extended_int -\c_five_hundred_million
+ \tex_advance:D \l_fp_exp_decimal_int \c_one
+ \fi:
+ \tex_advance:D \l_fp_exp_extended_int \l_fp_exp_extended_int
+ \fp_ln_normalise:
+ \if_int_compare:w \l_fp_output_sign_int > \c_zero
+ \exp_after:wN \fp_add:NNNNNNNNN
+ \else:
+ \exp_after:wN \fp_sub:NNNNNNNNN
+ \fi:
+ \l_fp_output_integer_int \l_fp_output_decimal_int
+ \l_fp_output_extended_int
+ \c_zero \l_fp_exp_decimal_int \l_fp_exp_extended_int
+ \l_fp_output_integer_int \l_fp_output_decimal_int
+ \l_fp_output_extended_int
+ }
+\cs_new_protected_nopar:Npn \fp_ln_fixed:
+ {
+ \if_int_compare:w \l_fp_output_exponent_int < \c_zero
+ \tex_advance:D \l_fp_output_decimal_int \c_one_thousand_million
+ \exp_after:wN \use_i:nn \exp_after:wN
+ \fp_ln_fixed_aux:NNNNNNNNN
+ \int_use:N \l_fp_output_decimal_int
+ \exp_after:wN \fp_ln_fixed:
+ \fi:
+ }
+\cs_new_protected_nopar:Npn \fp_ln_fixed_aux:NNNNNNNNN #1#2#3#4#5#6#7#8#9
+ {
+ \if_int_compare:w \l_fp_output_integer_int = \c_zero
+ \l_fp_output_decimal_int #1#2#3#4#5#6#7#8 \scan_stop:
+ \else:
+ \tl_set:Nx \l_fp_tmp_tl
+ {
+ \int_use:N \l_fp_output_integer_int
+ #1#2#3#4#5#6#7#8
+ }
+ \l_fp_output_integer_int \c_zero
+ \l_fp_output_decimal_int \l_fp_tmp_tl \scan_stop:
+ \fi:
+ \tex_advance:D \l_fp_output_exponent_int \c_one
+ }
+\cs_new_protected_nopar:Npn \fp_ln_Taylor_aux:
+ {
+ \tex_advance:D \l_fp_count_int \c_two
+ \fp_mul:NNNNNN
+ \l_fp_input_a_decimal_int \l_fp_input_a_extended_int
+ \l_fp_input_b_decimal_int \l_fp_input_b_extended_int
+ \l_fp_input_a_decimal_int \l_fp_input_a_extended_int
+ \if_int_compare:w
+ \int_eval:w
+ \l_fp_input_a_decimal_int + \l_fp_input_a_extended_int
+ > \c_zero
+ \fp_div_integer:NNNNN
+ \l_fp_input_a_decimal_int \l_fp_input_a_extended_int
+ \l_fp_count_int
+ \l_fp_exp_decimal_int \l_fp_exp_extended_int
+ \tex_advance:D \l_fp_output_decimal_int \l_fp_exp_decimal_int
+ \tex_advance:D \l_fp_output_extended_int \l_fp_exp_extended_int
+ \if_int_compare:w \l_fp_output_extended_int < \c_one_thousand_million
+ \else:
+ \tex_advance:D \l_fp_output_decimal_int \c_one
+ \tex_advance:D \l_fp_output_extended_int
+ -\c_one_thousand_million
+ \fi:
+ \if_int_compare:w \l_fp_output_decimal_int < \c_one_thousand_million
+ \else:
+ \tex_advance:D \l_fp_output_integer_int \c_one
+ \tex_advance:D \l_fp_output_decimal_int
+ -\c_one_thousand_million
+ \fi:
+ \exp_after:wN \fp_ln_Taylor_aux:
+ \fi:
+ }
+\cs_new_protected_nopar:Npn \fp_pow:Nn { \fp_pow_aux:NNn \tl_set:Nn }
+\cs_new_protected_nopar:Npn \fp_gpow:Nn { \fp_pow_aux:NNn \tl_gset:Nn }
+\cs_generate_variant:Nn \fp_pow:Nn { c }
+\cs_generate_variant:Nn \fp_gpow:Nn { c }
+\cs_new_protected_nopar:Npn \fp_pow_aux:NNn #1#2#3
+ {
+ \group_begin:
+ \fp_read:N #2
+ \l_fp_input_b_sign_int \l_fp_input_a_sign_int
+ \l_fp_input_b_integer_int \l_fp_input_a_integer_int
+ \l_fp_input_b_decimal_int \l_fp_input_a_decimal_int
+ \l_fp_input_b_exponent_int \l_fp_input_a_exponent_int
+ \fp_split:Nn a {#3}
+ \fp_standardise:NNNN
+ \l_fp_input_a_sign_int
+ \l_fp_input_a_integer_int
+ \l_fp_input_a_decimal_int
+ \l_fp_input_a_exponent_int
+ \if_int_compare:w
+ \int_eval:w
+ \l_fp_input_b_integer_int + \l_fp_input_b_decimal_int
+ = \c_zero
+ \if_int_compare:w
+ \int_eval:w
+ \l_fp_input_a_integer_int + \l_fp_input_a_decimal_int
+ = \c_zero
+ \cs_set_protected_nopar:Npx \fp_tmp:w ##1##2
+ {
+ \group_end:
+ ##1 ##2 { \c_undefined_fp }
+ }
+ \else:
+ \cs_set_protected_nopar:Npx \fp_tmp:w ##1##2
+ {
+ \group_end:
+ ##1 ##2 { \c_zero_fp }
+ }
+ \fi:
+ \else:
+ \if_int_compare:w
+ \int_eval:w
+ \l_fp_input_a_integer_int + \l_fp_input_a_decimal_int
+ = \c_zero
+ \cs_set_protected_nopar:Npx \fp_tmp:w ##1##2
+ {
+ \group_end:
+ ##1 ##2 { \c_one_fp }
+ }
+ \else:
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \fp_pow_aux_i:
+ \fi:
+ \fi:
+ \fp_tmp:w #1 #2
+}
+\cs_new_protected_nopar:Npn \fp_pow_aux_i:
+ {
+ \if_int_compare:w \l_fp_input_b_sign_int > \c_zero
+ \tl_set:Nn \l_fp_sign_tl { + }
+ \exp_after:wN \fp_pow_aux_ii:
+ \else:
+ \l_fp_input_a_extended_int \c_zero
+ \if_int_compare:w \l_fp_input_a_exponent_int < \c_ten
+ \group_begin:
+ \fp_extended_normalise:
+ \if_int_compare:w
+ \int_eval:w
+ \l_fp_input_a_decimal_int + \l_fp_input_a_extended_int
+ = \c_zero
+ \group_end:
+ \tl_set:Nn \l_fp_sign_tl { - }
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \exp_after:wN \fp_pow_aux_ii:
+ \else:
+ \group_end:
+ \cs_set_protected_nopar:Npx \fp_tmp:w ##1##2
+ {
+ \group_end:
+ ##1 ##2 { \c_undefined_fp }
+ }
+ \fi:
+ \else:
+ \cs_set_protected_nopar:Npx \fp_tmp:w ##1##2
+ {
+ \group_end:
+ ##1 ##2 { \c_undefined_fp }
+ }
+ \fi:
+ \fi:
+ }
+\cs_new_protected_nopar:Npn \fp_pow_aux_ii:
+ {
+ \if_int_compare:w \l_fp_input_a_sign_int > \c_zero
+ \exp_after:wN \fp_pow_aux_iv:
+ \else:
+ \if_int_compare:w \l_fp_input_a_exponent_int < \c_ten
+ \group_begin:
+ \l_fp_input_a_extended_int \c_zero
+ \fp_extended_normalise:
+ \if_int_compare:w \l_fp_input_a_decimal_int = \c_zero
+ \if_int_compare:w \l_fp_input_a_integer_int > \c_ten
+ \group_end:
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \fp_pow_aux_iv:
+ \else:
+ \group_end:
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \exp_after:wN \fp_pow_aux_iii:
+ \fi:
+ \else:
+ \group_end:
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \exp_after:wN \fp_pow_aux_iv:
+ \fi:
+ \else:
+ \exp_after:wN \exp_after:wN \exp_after:wN
+ \fp_pow_aux_iv:
+ \fi:
+ \fi:
+ \cs_set_protected_nopar:Npx \fp_tmp:w ##1##2
+ {
+ \group_end:
+ ##1 ##2
+ {
+ \l_fp_sign_tl
+ \int_use:N \l_fp_output_integer_int
+ .
+ \exp_after:wN \use_none:n
+ \int_value:w \int_eval:w
+ \l_fp_output_decimal_int + \c_one_thousand_million
+ e
+ \int_use:N \l_fp_output_exponent_int
+ }
+ }
+ }
+\cs_new_protected_nopar:Npn \fp_pow_aux_iii:
+ {
+ \l_fp_input_a_sign_int \c_one
+ \fp_pow_aux_iv:
+ \l_fp_input_a_integer_int \c_one
+ \l_fp_input_a_decimal_int \c_zero
+ \l_fp_input_a_exponent_int \c_zero
+ \l_fp_input_b_integer_int \l_fp_output_integer_int
+ \l_fp_input_b_decimal_int \l_fp_output_decimal_int
+ \l_fp_input_b_exponent_int \l_fp_output_exponent_int
+ \fp_div_internal:
+ }
+\cs_new_protected_nopar:Npn \fp_pow_aux_iv:
+ {
+ \group_begin:
+ \l_fp_input_a_integer_int \l_fp_input_b_integer_int
+ \l_fp_input_a_decimal_int \l_fp_input_b_decimal_int
+ \l_fp_input_a_exponent_int \l_fp_input_b_exponent_int
+ \fp_ln_internal:
+ \cs_set_protected_nopar:Npx \fp_tmp:w
+ {
+ \group_end:
+ \exp_not:N \l_fp_input_b_sign_int
+ \int_use:N \l_fp_output_sign_int \scan_stop:
+ \exp_not:N \l_fp_input_b_integer_int
+ \int_use:N \l_fp_output_integer_int \scan_stop:
+ \exp_not:N \l_fp_input_b_decimal_int
+ \int_use:N \l_fp_output_decimal_int \scan_stop:
+ \exp_not:N \l_fp_input_b_extended_int
+ \int_use:N \l_fp_output_extended_int \scan_stop:
+ \exp_not:N \l_fp_input_b_exponent_int
+ \int_use:N \l_fp_output_exponent_int \scan_stop:
+ }
+ \fp_tmp:w
+ \l_fp_input_a_extended_int \c_zero
+ \fp_mul:NNNNNNNNN
+ \l_fp_input_a_integer_int \l_fp_input_a_decimal_int
+ \l_fp_input_a_extended_int
+ \l_fp_input_b_integer_int \l_fp_input_b_decimal_int
+ \l_fp_input_b_extended_int
+ \l_fp_output_integer_int \l_fp_output_decimal_int
+ \l_fp_output_extended_int
+ \l_fp_output_exponent_int
+ \int_eval:w
+ \l_fp_input_a_exponent_int + \l_fp_input_b_exponent_int
+ \scan_stop:
+ \fp_extended_normalise_output:
+ \tex_multiply:D \l_fp_input_a_sign_int \l_fp_input_b_sign_int
+ \l_fp_input_a_integer_int \l_fp_output_integer_int
+ \l_fp_input_a_decimal_int \l_fp_output_decimal_int
+ \l_fp_input_a_extended_int \l_fp_output_extended_int
+ \l_fp_input_a_exponent_int \l_fp_output_exponent_int
+ \l_fp_output_integer_int \c_zero
+ \l_fp_output_decimal_int \c_zero
+ \l_fp_output_extended_int \c_zero
+ \l_fp_output_exponent_int \c_zero
+ \cs_set_eq:NN \fp_exp_const:Nx \use_none:nn
+ \fp_exp_internal:
+ }
+\prg_new_conditional:Npnn \fp_if_undefined:N #1 { p , T , F , TF }
+ {
+ \if_meaning:w #1 \c_undefined_fp
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\prg_new_conditional:Npnn \fp_if_zero:N #1 { p , T , F , TF }
+ {
+ \if_meaning:w #1 \c_zero_fp
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\prg_new_protected_conditional:Npnn \fp_compare:nNn #1#2#3 { T , F , TF }
+ {
+ \group_begin:
+ \fp_split:Nn a {#1}
+ \fp_standardise:NNNN
+ \l_fp_input_a_sign_int
+ \l_fp_input_a_integer_int
+ \l_fp_input_a_decimal_int
+ \l_fp_input_a_exponent_int
+ \fp_split:Nn b {#3}
+ \fp_standardise:NNNN
+ \l_fp_input_b_sign_int
+ \l_fp_input_b_integer_int
+ \l_fp_input_b_decimal_int
+ \l_fp_input_b_exponent_int
+ \fp_compare_aux:N #2
+ }
+\prg_new_protected_conditional:Npnn \fp_compare:NNN #1#2#3 { T , F , TF }
+ {
+ \group_begin:
+ \fp_read:N #3
+ \l_fp_input_b_sign_int \l_fp_input_a_sign_int
+ \l_fp_input_b_integer_int \l_fp_input_a_integer_int
+ \l_fp_input_b_decimal_int \l_fp_input_a_decimal_int
+ \l_fp_input_b_exponent_int \l_fp_input_a_exponent_int
+ \fp_read:N #1
+ \fp_compare_aux:N #2
+ }
+\cs_new_protected_nopar:Npn \fp_compare_aux:N #1
+ {
+ \cs_if_exist:cTF { fp_compare_#1: }
+ { \use:c { fp_compare_#1: } }
+ {
+ \group_end:
+ \prg_return_false:
+ }
+ }
+\cs_new_protected_nopar:cpn { fp_compare_=: }
+ {
+ \if_int_compare:w \l_fp_input_a_sign_int = \l_fp_input_b_sign_int
+ \if_int_compare:w \l_fp_input_a_integer_int = \l_fp_input_b_integer_int
+ \if_int_compare:w \l_fp_input_a_decimal_int = \l_fp_input_b_decimal_int
+ \if_int_compare:w
+ \l_fp_input_a_exponent_int = \l_fp_input_b_exponent_int
+ \group_end:
+ \prg_return_true:
+ \else:
+ \group_end:
+ \prg_return_false:
+ \fi:
+ \else:
+ \group_end:
+ \prg_return_false:
+ \fi:
+ \else:
+ \group_end:
+ \prg_return_false:
+ \fi:
+ \else:
+ \group_end:
+ \prg_return_false:
+ \fi:
+ }
+\cs_new_protected_nopar:cpn { fp_compare_>: }
+ {
+ \if_int_compare:w \int_eval:w
+ \l_fp_input_a_integer_int + \l_fp_input_a_decimal_int
+ = \c_zero
+ \if_int_compare:w \int_eval:w
+ \l_fp_input_b_integer_int + \l_fp_input_b_decimal_int
+ = \c_zero
+ \group_end:
+ \prg_return_false:
+ \else:
+ \if_int_compare:w \l_fp_input_b_sign_int > \c_zero
+ \group_end:
+ \prg_return_false:
+ \else:
+ \group_end:
+ \prg_return_true:
+ \fi:
+ \fi:
+ \else:
+ \if_int_compare:w \int_eval:w
+ \l_fp_input_b_integer_int + \l_fp_input_b_decimal_int
+ = \c_zero
+ \if_int_compare:w \l_fp_input_a_sign_int > \c_zero
+ \group_end:
+ \prg_return_true:
+ \else:
+ \group_end:
+ \prg_return_false:
+ \fi:
+ \else:
+ \use:c { fp_compare_>_aux: }
+ \fi:
+ \fi:
+ }
+\cs_new_protected_nopar:cpn { fp_compare_>_aux: }
+ {
+ \if_int_compare:w \l_fp_input_a_sign_int > \l_fp_input_b_sign_int
+ \group_end:
+ \prg_return_true:
+ \else:
+ \if_int_compare:w \l_fp_input_a_sign_int < \l_fp_input_b_sign_int
+ \group_end:
+ \prg_return_false:
+ \else:
+ \if_int_compare:w \l_fp_input_a_sign_int > \c_zero
+ \use:c { fp_compare_absolute_a>b: }
+ \else:
+ \use:c { fp_compare_absolute_a<b: }
+ \fi:
+ \fi:
+ \fi:
+ }
+\cs_new_protected_nopar:cpn { fp_compare_absolute_a>b: }
+ {
+ \if_int_compare:w \l_fp_input_a_exponent_int > \l_fp_input_b_exponent_int
+ \group_end:
+ \prg_return_true:
+ \else:
+ \if_int_compare:w \l_fp_input_a_exponent_int < \l_fp_input_b_exponent_int
+ \group_end:
+ \prg_return_false:
+ \else:
+ \if_int_compare:w \l_fp_input_a_integer_int > \l_fp_input_b_integer_int
+ \group_end:
+ \prg_return_true:
+ \else:
+ \if_int_compare:w
+ \l_fp_input_a_integer_int < \l_fp_input_b_integer_int
+ \group_end:
+ \prg_return_false:
+ \else:
+ \if_int_compare:w
+ \l_fp_input_a_decimal_int > \l_fp_input_b_decimal_int
+ \group_end:
+ \prg_return_true:
+ \else:
+ \group_end:
+ \prg_return_false:
+ \fi:
+ \fi:
+ \fi:
+ \fi:
+ \fi:
+ }
+\cs_new_protected_nopar:cpn { fp_compare_absolute_a<b: }
+ {
+ \if_int_compare:w \l_fp_input_b_exponent_int > \l_fp_input_a_exponent_int
+ \group_end:
+ \prg_return_true:
+ \else:
+ \if_int_compare:w \l_fp_input_b_exponent_int < \l_fp_input_a_exponent_int
+ \group_end:
+ \prg_return_false:
+ \else:
+ \if_int_compare:w \l_fp_input_b_integer_int > \l_fp_input_a_integer_int
+ \group_end:
+ \prg_return_true:
+ \else:
+ \if_int_compare:w
+ \l_fp_input_b_integer_int < \l_fp_input_a_integer_int
+ \group_end:
+ \prg_return_false:
+ \else:
+ \if_int_compare:w
+ \l_fp_input_b_decimal_int > \l_fp_input_a_decimal_int
+ \group_end:
+ \prg_return_true:
+ \else:
+ \group_end:
+ \prg_return_false:
+ \fi:
+ \fi:
+ \fi:
+ \fi:
+ \fi:
+ }
+\cs_new_protected_nopar:cpn { fp_compare_<: }
+ {
+ \tl_set:Nx \l_fp_tmp_tl
+ {
+ \int_set:Nn \exp_not:N \l_fp_input_a_sign_int
+ { \int_use:N \l_fp_input_b_sign_int }
+ \int_set:Nn \exp_not:N \l_fp_input_a_integer_int
+ { \int_use:N \l_fp_input_b_integer_int }
+ \int_set:Nn \exp_not:N \l_fp_input_a_decimal_int
+ { \int_use:N \l_fp_input_b_decimal_int }
+ \int_set:Nn \exp_not:N \l_fp_input_a_exponent_int
+ { \int_use:N \l_fp_input_b_exponent_int }
+ \int_set:Nn \exp_not:N \l_fp_input_b_sign_int
+ { \int_use:N \l_fp_input_a_sign_int }
+ \int_set:Nn \exp_not:N \l_fp_input_b_integer_int
+ { \int_use:N \l_fp_input_a_integer_int }
+ \int_set:Nn \exp_not:N \l_fp_input_b_decimal_int
+ { \int_use:N \l_fp_input_a_decimal_int }
+ \int_set:Nn \exp_not:N \l_fp_input_b_exponent_int
+ { \int_use:N \l_fp_input_a_exponent_int }
+ }
+ \l_fp_tmp_tl
+ \use:c { fp_compare_>: }
+ }
+\prg_new_protected_conditional:Npnn \fp_compare:n #1 { T , F , TF }
+ {
+ \group_begin:
+ \tl_set:Nx \l_fp_tmp_tl
+ {
+ \group_end:
+ \fp_compare_aux_i:w #1 \exp_not:n { == \q_nil == \q_stop }
+ }
+ \l_fp_tmp_tl
+ }
+\cs_new_protected_nopar:Npn \fp_compare_aux_i:w #1 == #2 == #3 \q_stop
+ {
+ \quark_if_nil:nTF {#2}
+ { \fp_compare_aux_ii:w #1 != \q_nil != \q_stop }
+ { \fp_compare:nNnTF {#1} = {#2} \prg_return_true: \prg_return_false: }
+ }
+\cs_new_protected_nopar:Npn \fp_compare_aux_ii:w #1 != #2 != #3 \q_stop
+ {
+ \quark_if_nil:nTF {#2}
+ { \fp_compare_aux_iii:w #1 <= \q_nil <= \q_stop }
+ { \fp_compare:nNnTF {#1} = {#2} \prg_return_false: \prg_return_true: }
+ }
+\cs_new_protected_nopar:Npn \fp_compare_aux_iii:w #1 <= #2 <= #3 \q_stop
+ {
+ \quark_if_nil:nTF {#2}
+ { \fp_compare_aux_iv:w #1 >= \q_nil >= \q_stop }
+ { \fp_compare:nNnTF {#1} > {#2} \prg_return_false: \prg_return_true: }
+ }
+\cs_new_protected_nopar:Npn \fp_compare_aux_iv:w #1 >= #2 >= #3 \q_stop
+ {
+ \quark_if_nil:nTF {#2}
+ { \fp_compare_aux_v:w #1 = \q_nil \q_stop }
+ { \fp_compare:nNnTF {#1} < {#2} \prg_return_false: \prg_return_true: }
+ }
+\cs_new_protected_nopar:Npn \fp_compare_aux_v:w #1 = #2 = #3 \q_stop
+ {
+ \quark_if_nil:nTF {#2}
+ { \fp_compare_aux_vi:w #1 < \q_nil < \q_stop }
+ { \fp_compare:nNnTF {#1} = {#2} \prg_return_true: \prg_return_false: }
+ }
+\cs_new_protected_nopar:Npn \fp_compare_aux_vi:w #1 < #2 < #3 \q_stop
+ {
+ \quark_if_nil:nTF {#2}
+ { \fp_compare_aux_vii:w #1 > \q_nil > \q_stop }
+ { \fp_compare:nNnTF {#1} < {#2} \prg_return_true: \prg_return_false: }
+ }
+\cs_new_protected_nopar:Npn \fp_compare_aux_vii:w #1 > #2 > #3 \q_stop
+ {
+ \quark_if_nil:nTF {#2}
+ { \prg_return_false: }
+ { \fp_compare:nNnTF {#1} > {#2} \prg_return_true: \prg_return_false: }
+ }
+\msg_kernel_new:nnnn { fpu } { overflow }
+ { Number~too~big. }
+ {
+ The~input~given~is~too~big~for~the~LaTeX~floating~point~unit. \\
+ Further~errors~may~well~occur!
+ }
+\cs_new_protected_nopar:Npn \fp_overflow_msg:
+ { \msg_kernel_error:nn { fpu } { overflow } }
+\msg_kernel_new:nnnn { fpu } { exponent-overflow }
+ { Number~too~big~for~exponent~unit. }
+ {
+ The~exponent~of~the~input~given~is~too~big~for~the~floating~point~
+ unit:~the~maximum~input~value~for~an~exponent~is~230.
+ }
+\cs_new_protected_nopar:Npn \fp_exp_overflow_msg:
+ { \msg_kernel_error:nn { fpu } { exponent-overflow } }
+\msg_kernel_new:nnnn { fpu } { logarithm-input-error }
+ { Invalid~input~to~ln~function. }
+ { Logarithms~can~only~be~calculated~for~positive~numbers. }
+\cs_new_protected_nopar:Npn \fp_ln_error_msg: {
+ \msg_kernel_error:nn { fpu } { logarithm-input-error }
+}
+\msg_kernel_new:nnnn { fpu } { trigonometric-overflow }
+ { Number~too~big~for~trigonometry~unit. }
+ {
+ The~trigonometry~code~can~only~work~with~numbers~smaller~
+ than~1000000000.
+ }
+\cs_new_protected_nopar:Npn \fp_trig_overflow_msg:
+ { \msg_kernel_error:nn { fpu } { trigonometric-overflow } }
+%%
+%%
+%% End of file `l3fp.sty'.
diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3int.sty b/Master/texmf-dist/tex/latex/l3kernel/l3int.sty
new file mode 100644
index 00000000000..7f009832fcf
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/l3kernel/l3int.sty
@@ -0,0 +1,743 @@
+%%
+%% This is file `l3int.sty',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% l3int.dtx (with options: `package')
+%%
+%% EXPERIMENTAL CODE
+%%
+%% Do not distribute this file without also distributing the
+%% source files specified above.
+%%
+%% Do not distribute a modified version of this file.
+%%
+%% File: l3int.dtx Copyright (C) 1990-2011 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 "expl3 bundle" (The Work in LPPL)
+%% and all files in that bundle must be distributed together.
+%%
+%% The released version of this bundle is available from CTAN.
+%%
+%% -----------------------------------------------------------------------
+%%
+%% The development version of the bundle can be found at
+%%
+%% http://www.latex-project.org/svnroot/experimental/trunk/
+%%
+%% for those people who are interested.
+%%
+%%%%%%%%%%%
+%% NOTE: %%
+%%%%%%%%%%%
+%%
+%% Snapshots taken from the repository represent work in progress and may
+%% not work or may contain conflicting material! We therefore ask
+%% people _not_ to put them into distributions, archives, etc. without
+%% prior consultation with the LaTeX3 Project.
+%%
+%% -----------------------------------------------------------------------
+\RequirePackage{l3names}
+\GetIdInfo$Id: l3int.dtx 2478 2011-06-19 21:34:23Z joseph $
+ {L3 Experimental integers}
+\ProvidesExplPackage
+ {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
+\package_check_loaded_expl:
+\cs_set_eq:NN \int_value:w \tex_number:D
+\cs_set_eq:NN \int_eval:w \etex_numexpr:D
+\cs_new_eq:NN \int_eval_end: \tex_relax:D
+\cs_new_eq:NN \if_num:w \tex_ifnum:D
+\cs_set_eq:NN \if_int_odd:w \tex_ifodd:D
+\cs_new_eq:NN \if_case:w \tex_ifcase:D
+\cs_new:Npn \int_eval:n #1
+ { \int_value:w \int_eval:w #1 \int_eval_end: }
+\cs_new:Npn \int_abs:n #1
+ {
+ \int_value:w
+ \if_int_compare:w \int_eval:w #1 < \c_zero
+ -
+ \fi:
+ \int_eval:w #1 \int_eval_end:
+ }
+\cs_new:Npn \int_max:nn #1#2
+ {
+ \int_value:w \int_eval:w
+ \if_int_compare:w
+ \int_eval:w #1 > \int_eval:w #2 \int_eval_end:
+ #1
+ \else:
+ #2
+ \fi:
+ \int_eval_end:
+ }
+\cs_new:Npn \int_min:nn #1#2
+ {
+ \int_value:w \int_eval:w
+ \if_int_compare:w
+ \int_eval:w #1 < \int_eval:w #2 \int_eval_end:
+ #1
+ \else:
+ #2
+ \fi:
+ \int_eval_end:
+ }
+\cs_new:Npn \int_div_truncate:nn #1#2
+ {
+ \int_value:w \int_eval:w
+ \if_int_compare:w \int_eval:w #1 = \c_zero
+ 0
+ \else:
+ ( #1 % )
+ \if_int_compare:w \int_eval:w #1 < \c_zero
+ \if_int_compare:w \int_eval:w #2 < \c_zero
+ - ( #2 + % )
+ \else:
+ + ( #2 - % )
+ \fi:
+ \else:
+ \if_int_compare:w \int_eval:w #2 < \c_zero
+ + ( #2 + % )
+ \else:
+ - ( #2 - % )
+ \fi:
+ \fi: % ( (
+ 1 ) / 2 )
+ \fi:
+ / ( #2 )
+ \int_eval_end:
+ }
+\cs_new:Npn \int_div_round:nn #1#2 { \int_eval:n { ( #1 ) / ( #2 ) } }
+\cs_new:Npn \int_mod:nn #1#2
+ {
+ \int_value:w \int_eval:w
+ #1 - \int_div_truncate:nn {#1} {#2} * ( #2 )
+ \int_eval_end:
+ }
+\cs_new_protected_nopar:Npn \int_new:N #1
+ {
+ \chk_if_free_cs:N #1
+ \newcount #1
+ }
+\cs_generate_variant:Nn \int_new:N { c }
+\cs_new_protected_nopar:Npn \int_const:Nn #1#2
+ {
+ \int_compare:nNnTF {#2} > \c_minus_one
+ {
+ \int_compare:nNnTF {#2} > \c_max_register_int
+ {
+ \int_new:N #1
+ \int_gset:Nn #1 {#2}
+ }
+ {
+ \chk_if_free_cs:N #1
+ \pref_global:D \tex_mathchardef:D #1 =
+ \int_eval:w #2 \int_eval_end:
+ }
+ }
+ {
+ \int_new:N #1
+ \int_gset:Nn #1 {#2}
+ }
+ }
+\cs_generate_variant:Nn \int_const:Nn { c }
+\cs_new_protected_nopar:Npn \int_zero:N #1 { #1 = \c_zero }
+\cs_new_protected_nopar:Npn \int_gzero:N #1 { \pref_global:D #1 = \c_zero }
+\cs_generate_variant:Nn \int_zero:N { c }
+\cs_generate_variant:Nn \int_gzero:N { c }
+\cs_new_protected_nopar:Npn \int_set_eq:NN #1#2 { #1 = #2 }
+\cs_generate_variant:Nn \int_set_eq:NN { c }
+\cs_generate_variant:Nn \int_set_eq:NN { Nc , cc }
+\cs_new_protected_nopar:Npn \int_gset_eq:NN #1#2 { \pref_global:D #1 = #2 }
+\cs_generate_variant:Nn \int_gset_eq:NN { c }
+\cs_generate_variant:Nn \int_gset_eq:NN { Nc , cc }
+\cs_new_protected_nopar:Npn \int_add:Nn #1#2
+ { \tex_advance:D #1 by \int_eval:w #2 \int_eval_end: }
+\cs_new_nopar:Npn \int_sub:Nn #1#2
+ { \tex_advance:D #1 by - \int_eval:w #2 \int_eval_end: }
+\cs_new_protected_nopar:Npn \int_gadd:Nn
+ { \pref_global:D \int_add:Nn }
+\cs_new_protected_nopar:Npn \int_gsub:Nn
+ { \pref_global:D \int_sub:Nn }
+\cs_generate_variant:Nn \int_add:Nn { c }
+\cs_generate_variant:Nn \int_gadd:Nn { c }
+\cs_generate_variant:Nn \int_sub:Nn { c }
+\cs_generate_variant:Nn \int_gsub:Nn { c }
+\cs_new_protected_nopar:Npn \int_incr:N #1
+ { \tex_advance:D #1 \c_one }
+\cs_new_protected_nopar:Npn \int_decr:N #1
+ { \tex_advance:D #1 \c_minus_one }
+\cs_new_protected_nopar:Npn \int_gincr:N
+ { \pref_global:D \int_incr:N }
+\cs_new_protected_nopar:Npn \int_gdecr:N
+ { \pref_global:D \int_decr:N }
+\cs_generate_variant:Nn \int_incr:N { c }
+\cs_generate_variant:Nn \int_decr:N { c }
+\cs_generate_variant:Nn \int_gincr:N { c }
+\cs_generate_variant:Nn \int_gdecr:N { c }
+\cs_new_protected_nopar:Npn \int_set:Nn #1#2
+ { #1 ~ \int_eval:w #2\int_eval_end: }
+\cs_new_protected_nopar:Npn \int_gset:Nn { \pref_global:D \int_set:Nn }
+\cs_generate_variant:Nn \int_set:Nn { c }
+\cs_generate_variant:Nn \int_gset:Nn { c }
+\cs_new_eq:NN \int_use:N \tex_the:D
+\cs_new_nopar:Npn \int_use:c #1 { \int_use:N \cs:w #1 \cs_end: }
+\prg_new_conditional:Npnn \int_compare:n #1 { p , T , F , TF }
+ { \exp_after:wN \int_compare_aux:nw \int_value:w \int_eval:w #1 \q_stop }
+\cs_new:Npn \int_compare_aux:nw #1#2 \q_stop
+ {
+ \exp_after:wN \int_compare_aux:Nw
+ \int_to_roman:w
+ \if:w #1 -
+ \else:
+ -
+ \fi:
+ #1#2 \q_mark #1#2 \q_stop
+ }
+\cs_new:Npn \int_compare_aux:Nw #1#2#3 \q_mark
+ { \use:c { int_compare_ #1 \if_meaning:w = #2 = \fi: :w } }
+\cs_new:cpn { int_compare_=:w } #1 = #2 \q_stop
+ {
+ \if_int_compare:w #1 = \int_eval:w #2 \int_eval_end:
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\cs_new:cpn { int_compare_==:w } #1 == #2 \q_stop
+ {
+ \if_int_compare:w #1 = \int_eval:w #2 \int_eval_end:
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\cs_new:cpn { int_compare_!=:w } #1 != #2 \q_stop
+ {
+ \if_int_compare:w #1 = \int_eval:w #2 \int_eval_end:
+ \prg_return_false:
+ \else:
+ \prg_return_true:
+ \fi:
+ }
+\cs_new:cpn { int_compare_<:w } #1 < #2 \q_stop
+ {
+ \if_int_compare:w #1 < \int_eval:w #2 \int_eval_end:
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\cs_new:cpn { int_compare_>:w } #1 > #2 \q_stop
+ {
+ \if_int_compare:w #1 > \int_eval:w #2 \int_eval_end:
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\cs_new:cpn { int_compare_<=:w } #1 <= #2 \q_stop
+ {
+ \if_int_compare:w #1 > \int_eval:w #2 \int_eval_end:
+ \prg_return_false:
+ \else:
+ \prg_return_true:
+ \fi:
+ }
+\cs_new:cpn { int_compare_>=:w } #1 >= #2 \q_stop
+ {
+ \if_int_compare:w #1 < \int_eval:w #2 \int_eval_end:
+ \prg_return_false:
+ \else:
+ \prg_return_true:
+ \fi:
+ }
+\prg_new_conditional:Npnn \int_compare:nNn #1#2#3 { p , T , F , TF}
+ {
+ \if_int_compare:w \int_eval:w #1 #2 \int_eval:w #3 \int_eval_end:
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\prg_new_conditional:Npnn \int_if_odd:n #1 { p , T , F , TF}
+ {
+ \if_int_odd:w \int_eval:w #1 \int_eval_end:
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\prg_new_conditional:Npnn \int_if_even:n #1 { p , T , F , TF}
+ {
+ \if_int_odd:w \int_eval:w #1 \int_eval_end:
+ \prg_return_false:
+ \else:
+ \prg_return_true:
+ \fi:
+ }
+\cs_new:Npn \int_while_do:nn #1#2
+ {
+ \int_compare:nT {#1}
+ {
+ #2
+ \int_while_do:nn {#1} {#2}
+ }
+ }
+\cs_new:Npn \int_until_do:nn #1#2
+ {
+ \int_compare:nF {#1}
+ {
+ #2
+ \int_until_do:nn {#1} {#2}
+ }
+ }
+\cs_new:Npn \int_do_while:nn #1#2
+ {
+ #2
+ \int_compare:nT {#1}
+ { \int_do_while:nNnn {#1} {#2} }
+ }
+\cs_new:Npn \int_do_until:nn #1#2
+ {
+ #2
+ \int_compare:nF {#1}
+ { \int_do_until:nn {#1} {#2} }
+ }
+\cs_new:Npn \int_while_do:nNnn #1#2#3#4
+ {
+ \int_compare:nNnT {#1} #2 {#3}
+ {
+ #4
+ \int_while_do:nNnn {#1} #2 {#3} {#4}
+ }
+ }
+\cs_new:Npn \int_until_do:nNnn #1#2#3#4
+ {
+ \int_compare:nNnF {#1} #2 {#3}
+ {
+ #4
+ \int_until_do:nNnn {#1} #2 {#3} {#4}
+ }
+ }
+\cs_new:Npn \int_do_while:nNnn #1#2#3#4
+ {
+ #4
+ \int_compare:nNnT {#1} #2 {#3}
+ { \int_do_while:nNnn {#1} #2 {#3} {#4} }
+ }
+\cs_new:Npn \int_do_until:nNnn #1#2#3#4
+ {
+ #4
+ \int_compare:nNnF {#1} #2 {#3}
+ { \int_do_until:nNnn {#1} #2 {#3} {#4} }
+ }
+\cs_new_nopar:Npn \int_to_arabic:n #1 { \int_eval:n {#1} }
+\cs_new_nopar:Npn \int_to_symbols:nnn #1#2#3
+ {
+ \int_compare:nNnTF {#1} > {#2}
+ {
+ \exp_args:Nf \int_to_symbols:nnn
+ { \int_div_truncate:nn { #1 - 1 } {#2} } {#2} {#3}
+ \exp_args:Nf \prg_case_int:nnn
+ { \int_eval:n { 1 + \int_mod:nn { #1 - 1 } {#2} } }
+ {#3} { }
+ }
+ { \exp_args:Nf \prg_case_int:nnn { \int_eval:n {#1} } {#3} { } }
+ }
+\cs_new:Npn \int_to_alph:n #1
+ {
+ \int_to_symbols:nnn {#1} { 26 }
+ {
+ { 1 } { a }
+ { 2 } { b }
+ { 3 } { c }
+ { 4 } { d }
+ { 5 } { e }
+ { 6 } { f }
+ { 7 } { g }
+ { 8 } { h }
+ { 9 } { i }
+ { 10 } { j }
+ { 11 } { k }
+ { 12 } { l }
+ { 13 } { m }
+ { 14 } { n }
+ { 15 } { o }
+ { 16 } { p }
+ { 17 } { q }
+ { 18 } { r }
+ { 19 } { s }
+ { 20 } { t }
+ { 21 } { u }
+ { 22 } { v }
+ { 23 } { w }
+ { 24 } { x }
+ { 25 } { y }
+ { 26 } { z }
+ }
+ }
+\cs_new:Npn \int_to_Alph:n #1
+ {
+ \int_to_symbols:nnn {#1} { 26 }
+ {
+ { 1 } { A }
+ { 2 } { B }
+ { 3 } { C }
+ { 4 } { D }
+ { 5 } { E }
+ { 6 } { F }
+ { 7 } { G }
+ { 8 } { H }
+ { 9 } { I }
+ { 10 } { J }
+ { 11 } { K }
+ { 12 } { L }
+ { 13 } { M }
+ { 14 } { N }
+ { 15 } { O }
+ { 16 } { P }
+ { 17 } { Q }
+ { 18 } { R }
+ { 19 } { S }
+ { 20 } { T }
+ { 21 } { U }
+ { 22 } { V }
+ { 23 } { W }
+ { 24 } { X }
+ { 25 } { Y }
+ { 26 } { Z }
+ }
+ }
+\cs_new:Npn \int_to_base:nn #1#2
+ {
+ \int_compare:nNnTF {#1} < \c_zero
+ {
+ -
+ \exp_args:Nnf \int_to_base_aux:nnn
+ { } { \int_eval:n { 0 - ( #1 ) } } {#2}
+ }
+ {
+ \exp_args:Nnf \int_to_base_aux:nnn
+ { } { \int_eval:n {#1} } {#2}
+ }
+}
+\cs_new:Npn \int_to_base_aux:nnn #1#2#3 {
+ \int_compare:nNnTF {#2} < {#3}
+ {
+ \int_to_letter:n {#2}
+ #1
+ }
+ {
+ \exp_args:Nff \int_to_base_aux:nnn
+ {
+ \int_to_letter:n { \int_mod:nn {#2} {#3} }
+ #1
+ }
+ { \int_div_truncate:nn {#2} {#3} }
+ {#3}
+ }
+ }
+\cs_new:Npn \int_to_letter:n #1
+ {
+ \prg_case_int:nnn { #1 - 9 }
+ {
+ { 1 } { A }
+ { 2 } { B }
+ { 3 } { C }
+ { 4 } { D }
+ { 5 } { E }
+ { 6 } { F }
+ { 7 } { G }
+ { 8 } { H }
+ { 9 } { I }
+ { 10 } { J }
+ { 11 } { K }
+ { 12 } { L }
+ { 13 } { M }
+ { 14 } { N }
+ { 15 } { O }
+ { 16 } { P }
+ { 17 } { Q }
+ { 18 } { R }
+ { 19 } { S }
+ { 20 } { T }
+ { 21 } { U }
+ { 22 } { V }
+ { 23 } { W }
+ { 24 } { X }
+ { 25 } { Y }
+ { 26 } { Z }
+ }
+ {#1}
+ }
+\cs_new:Npn \int_to_binary:n #1
+ { \int_to_base:nn {#1} { 2 } }
+\cs_new:Npn \int_to_hexadecimal:n #1
+ { \int_to_base:nn {#1} { 16 } }
+\cs_new:Npn \int_to_octal:n #1
+ { \int_to_base:nn {#1} { 8 } }
+\cs_new_nopar:Npn \int_to_roman:n #1
+ {
+ \exp_after:wN \int_to_roman_aux:N
+ \int_to_roman:w \int_eval:n {#1} Q
+ }
+\cs_new_nopar:Npn \int_to_roman_aux:N #1
+ {
+ \use:c { int_to_roman_ #1 :w }
+ \int_to_roman_aux:N
+ }
+\cs_new_nopar:Npn \int_to_Roman:n #1
+ {
+ \exp_after:wN \int_to_Roman_aux:N
+ \int_to_roman:w \int_eval:n {#1} Q
+ }
+\cs_new_nopar:Npn \int_to_Roman_aux:N #1
+ {
+ \use:c { int_to_Roman_ #1 :w }
+ \int_to_Roman_aux:N
+ }
+\cs_new_nopar:Npn \int_to_roman_i:w { i }
+\cs_new_nopar:Npn \int_to_roman_v:w { v }
+\cs_new_nopar:Npn \int_to_roman_x:w { x }
+\cs_new_nopar:Npn \int_to_roman_l:w { l }
+\cs_new_nopar:Npn \int_to_roman_c:w { c }
+\cs_new_nopar:Npn \int_to_roman_d:w { d }
+\cs_new_nopar:Npn \int_to_roman_m:w { m }
+\cs_new_nopar:Npn \int_to_roman_Q:w #1 { }
+\cs_new_nopar:Npn \int_to_Roman_i:w { I }
+\cs_new_nopar:Npn \int_to_Roman_v:w { V }
+\cs_new_nopar:Npn \int_to_Roman_x:w { X }
+\cs_new_nopar:Npn \int_to_Roman_l:w { L }
+\cs_new_nopar:Npn \int_to_Roman_c:w { C }
+\cs_new_nopar:Npn \int_to_Roman_d:w { D }
+\cs_new_nopar:Npn \int_to_Roman_m:w { M }
+\cs_new_nopar:Npn \int_to_Roman_Q:w #1 { }
+\cs_new:Npn \int_get_sign:n #1
+ {
+ \int_get_sign_and_digits_aux:nNNN {#1}
+ \c_true_bool \c_true_bool \c_false_bool
+ }
+\cs_new:Npn \int_get_digits:n #1
+ {
+ \int_get_sign_and_digits_aux:nNNN {#1}
+ \c_true_bool \c_false_bool \c_true_bool
+ }
+\cs_new:Npn \int_get_sign_and_digits_aux:nNNN #1#2#3#4
+ {
+ \tl_if_head_eq_charcode:fNTF {#1} -
+ {
+ \bool_if:NTF #2
+ {
+ \int_get_sign_and_digits_aux:oNNN
+ { \use_none:n #1 } \c_false_bool #3#4
+ }
+ {
+ \int_get_sign_and_digits_aux:oNNN
+ { \use_none:n #1 } \c_true_bool #3#4
+ }
+ }
+ {
+ \tl_if_head_eq_charcode:fNTF {#1} +
+ { \int_get_sign_and_digits_aux:oNNN { \use_none:n #1 } #2#3#4 }
+ {
+ \bool_if:NT #3 { \bool_if:NF #2 - }
+ \bool_if:NT #4 {#1}
+ }
+ }
+ }
+\cs_generate_variant:Nn \int_get_sign_and_digits_aux:nNNN { o }
+\cs_new:Npn \int_from_alph:n #1
+ {
+ \int_eval:n
+ {
+ \int_get_sign:n {#1}
+ \exp_args:Nf \int_from_alph_aux:n { \int_get_digits:n {#1} }
+ }
+ }
+\cs_new:Npn \int_from_alph_aux:n #1
+ { \int_from_alph_aux:nN { 0 } #1 \q_nil }
+\cs_new:Npn \int_from_alph_aux:nN #1#2
+ {
+ \quark_if_nil:NTF #2
+ {#1}
+ {
+ \exp_args:Nf \int_from_alph_aux:nN
+ { \int_eval:n { #1 * 26 + \int_from_alph_aux:N #2 } }
+ }
+ }
+\cs_new:Npn \int_from_alph_aux:N #1
+ { \int_eval:n { `#1 - \int_compare:nNnTF { `#1 } < { 91 } { 64 } { 96 } } }
+\cs_new:Npn \int_from_base:nn #1#2
+ {
+ \int_eval:n
+ {
+ \int_get_sign:n {#1}
+ \exp_args:Nf \int_from_base_aux:nn
+ { \int_get_digits:n {#1} } {#2}
+ }
+ }
+\cs_new:Npn \int_from_base_aux:nn #1#2
+ { \int_from_base_aux:nnN { 0 } { #2 } #1 \q_nil }
+\cs_new:Npn \int_from_base_aux:nnN #1#2#3
+ {
+ \quark_if_nil:NTF #3
+ {#1}
+ {
+ \exp_args:Nf \int_from_base_aux:nnN
+ { \int_eval:n { #1 * #2 + \int_from_base_aux:N #3 } }
+ {#2}
+ }
+ }
+\cs_new:Npn \int_from_base_aux:N #1
+ {
+ \int_compare:nNnTF { `#1 } < { 58 }
+ {#1}
+ {
+ \int_eval:n
+ { `#1 - \int_compare:nNnTF { `#1 } < { 91 } { 55 } { 87 } }
+ }
+ }
+\cs_new:Npn \int_from_binary:n #1
+ { \int_from_base:nn {#1} \c_two }
+\cs_new:Npn \int_from_hexadecimal:n #1
+ { \int_from_base:nn {#1} \c_sixteen }
+\cs_new:Npn \int_from_octal:n #1
+ { \int_from_base:nn {#1} \c_eight }
+\int_const:cn { c_int_from_roman_i_int } { 1 }
+\int_const:cn { c_int_from_roman_v_int } { 5 }
+\int_const:cn { c_int_from_roman_x_int } { 10 }
+\int_const:cn { c_int_from_roman_l_int } { 50 }
+\int_const:cn { c_int_from_roman_c_int } { 100 }
+\int_const:cn { c_int_from_roman_d_int } { 500 }
+\int_const:cn { c_int_from_roman_m_int } { 1000 }
+\int_const:cn { c_int_from_roman_I_int } { 1 }
+\int_const:cn { c_int_from_roman_V_int } { 5 }
+\int_const:cn { c_int_from_roman_X_int } { 10 }
+\int_const:cn { c_int_from_roman_L_int } { 50 }
+\int_const:cn { c_int_from_roman_C_int } { 100 }
+\int_const:cn { c_int_from_roman_D_int } { 500 }
+\int_const:cn { c_int_from_roman_M_int } { 1000 }
+\cs_new_nopar:Npn \int_from_roman:n #1
+ {
+ \tl_if_blank:nF {#1}
+ {
+ \exp_after:wN \int_from_roman_end:w
+ \int_value:w \int_eval:w
+ \int_from_roman_aux:NN #1 Q \q_stop
+ }
+ }
+\cs_new_nopar:Npn \int_from_roman_aux:NN #1#2
+ {
+ \str_if_eq:nnTF {#1} { Q }
+ {#1#2}
+ {
+ \str_if_eq:nnTF {#2} { Q }
+ {
+ \cs_if_exist:cF { c_int_from_roman_ #1 _int }
+ { \int_from_roman_clean_up:w }
+ +
+ \use:c { c_int_from_roman_ #1 _int }
+ #2
+ }
+ {
+ \cs_if_exist:cF { c_int_from_roman_ #1 _int }
+ { \int_from_roman_clean_up:w }
+ \cs_if_exist:cF { c_int_from_roman_ #2 _int }
+ { \int_from_roman_clean_up:w }
+ \int_compare:nNnTF
+ { \use:c { c_int_from_roman_ #1 _int } }
+ <
+ { \use:c { c_int_from_roman_ #2 _int } }
+ {
+ + \use:c { c_int_from_roman_ #2 _int }
+ - \use:c { c_int_from_roman_ #1 _int }
+ \int_from_roman_aux:NN
+ }
+ {
+ + \use:c { c_int_from_roman_ #1 _int }
+ \int_from_roman_aux:NN #2
+ }
+ }
+ }
+ }
+\cs_new_nopar:Npn \int_from_roman_end:w #1 Q #2 \q_stop
+ { \tl_if_empty:nTF {#2} {#1} {#2} }
+\cs_new_nopar:Npn \int_from_roman_clean_up:w #1 Q { + 0 Q -1 }
+\cs_new_eq:NN \int_show:N \kernel_register_show:N
+\cs_new_eq:NN \int_show:c \kernel_register_show:c
+\int_const:Nn \c_one { 1 }
+\int_const:Nn \c_two { 2 }
+\int_const:Nn \c_three { 3 }
+\int_const:Nn \c_four { 4 }
+\int_const:Nn \c_five { 5 }
+\int_const:Nn \c_eight { 8 }
+\int_const:Nn \c_nine { 9 }
+\int_const:Nn \c_ten { 10 }
+\int_const:Nn \c_eleven { 11 }
+\int_const:Nn \c_thirteen { 13 }
+\int_const:Nn \c_fourteen { 14 }
+\int_const:Nn \c_fifteen { 15 }
+\int_const:Nn \c_thirty_two { 32 }
+\int_const:Nn \c_two_hundred_fifty_five { 255 }
+\int_const:Nn \c_two_hundred_fifty_six { 256 }
+\int_const:Nn \c_one_hundred { 100 }
+\int_const:Nn \c_one_thousand { 1000 }
+\int_const:Nn \c_ten_thousand { 10000 }
+\int_const:Nn \c_max_int { 2 147 483 647 }
+\int_new:N \l_tmpa_int
+\int_new:N \l_tmpb_int
+\int_new:N \l_tmpc_int
+\int_new:N \g_tmpa_int
+\int_new:N \g_tmpb_int
+\int_new:N \g_seq_nesting_depth_int
+\int_new:N \g_tl_inline_level_int
+\cs_new_eq:NN \int_convert_from_base_ten:nn \int_to_base:nn
+\cs_new_eq:NN \int_convert_to_symbols:nnn \int_to_symbols:nnn
+\cs_new_eq:NN \int_convert_to_base_ten:nn \int_from_base:nn
+\cs_new_nopar:Npn \int_to_symbol:n
+ {
+ \mode_if_math:TF
+ { \int_to_symbol_math:n }
+ { \int_to_symbol_text:n }
+ }
+\cs_new:Npn \int_to_symbol_math:n #1
+ {
+ \int_to_symbols:nnn {#1} { 9 }
+ {
+ { 1 } { * }
+ { 2 } { \dagger }
+ { 3 } { \ddagger }
+ { 4 } { \mathsection }
+ { 5 } { \mathparagraph }
+ { 6 } { \| }
+ { 7 } { ** }
+ { 8 } { \dagger \dagger }
+ { 9 } { \ddagger \ddagger }
+ }
+ }
+\cs_new:Npn \int_to_symbol_text:n #1
+ {
+ \int_to_symbols:nnn {#1} { 9 }
+ {
+ { 1 } { \textasteriskcentered }
+ { 2 } { \textdagger }
+ { 3 } { \textdaggerdbl }
+ { 4 } { \textsection }
+ { 5 } { \textparagraph }
+ { 6 } { \textbardbl }
+ { 7 } { \textasteriskcentered \textasteriskcentered }
+ { 8 } { \textdagger \textdagger }
+ { 9 } { \textdaggerdbl \textdaggerdbl }
+ }
+ }
+%%
+%%
+%% End of file `l3int.sty'.
diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3io.sty b/Master/texmf-dist/tex/latex/l3kernel/l3io.sty
new file mode 100644
index 00000000000..7239fbae288
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/l3kernel/l3io.sty
@@ -0,0 +1,430 @@
+%%
+%% This is file `l3io.sty',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% l3io.dtx (with options: `package')
+%%
+%% EXPERIMENTAL CODE
+%%
+%% Do not distribute this file without also distributing the
+%% source files specified above.
+%%
+%% Do not distribute a modified version of this file.
+%%
+%% File: l3io.dtx Copyright (C) 1990-2011 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 "expl3 bundle" (The Work in LPPL)
+%% and all files in that bundle must be distributed together.
+%%
+%% The released version of this bundle is available from CTAN.
+%%
+%% -----------------------------------------------------------------------
+%%
+%% The development version of the bundle can be found at
+%%
+%% http://www.latex-project.org/svnroot/experimental/trunk/
+%%
+%% for those people who are interested.
+%%
+%%%%%%%%%%%
+%% NOTE: %%
+%%%%%%%%%%%
+%%
+%% Snapshots taken from the repository represent work in progress and may
+%% not work or may contain conflicting material! We therefore ask
+%% people _not_ to put them into distributions, archives, etc. without
+%% prior consultation with the LaTeX3 Project.
+%%
+%% -----------------------------------------------------------------------
+\RequirePackage{l3names}
+\GetIdInfo$Id: l3io.dtx 2478 2011-06-19 21:34:23Z joseph $
+ {L3 Experimental input-output operations}
+\ProvidesExplPackage
+ {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
+\package_check_loaded_expl:
+\cs_new_eq:NN \if_eof:w \tex_ifeof:D
+\cs_new_eq:NN \c_iow_term_stream \c_sixteen
+\cs_new_eq:NN \c_ior_term_stream \c_sixteen
+\cs_new_eq:NN \c_iow_log_stream \c_minus_one
+\cs_new_eq:NN \c_ior_log_stream \c_minus_one
+\tl_const:Nn \c_iow_streams_tl
+ {
+ \c_zero
+ \c_one
+ \c_two
+ \c_three
+ \c_four
+ \c_five
+ \c_six
+ \c_seven
+ \c_eight
+ \c_nine
+ \c_ten
+ \c_eleven
+ \c_twelve
+ \c_thirteen
+ \c_fourteen
+ \c_fifteen
+ }
+\cs_new_eq:NN \c_ior_streams_tl \c_iow_streams_tl
+\prop_new:N \g_iow_streams_prop
+\prop_new:N \g_ior_streams_prop
+\prop_put:Nnn \g_iow_streams_prop { 0 } { LaTeX2e~reserved }
+\prop_put:Nnn \g_iow_streams_prop { 1 } { LaTeX2e~reserved }
+\prop_put:Nnn \g_iow_streams_prop { 2 } { LaTeX2e~reserved }
+\prop_put:Nnn \g_ior_streams_prop { 0 } { LaTeX2e~reserved }
+\int_new:N \l_iow_stream_int
+\cs_new_eq:NN \l_ior_stream_int \l_iow_stream_int
+\cs_set_eq:NN \iow_raw_new:N \newwrite
+\cs_set_eq:NN \ior_raw_new:N \newread
+\cs_generate_variant:Nn \ior_raw_new:N { c }
+\cs_generate_variant:Nn \iow_raw_new:N { c }
+\cs_new_protected_nopar:Npn \ior_open:Nn #1#2
+ {
+ \ior_close:N #1
+ \int_set:Nn \l_ior_stream_int \c_sixteen
+ \tl_map_function:NN \c_ior_streams_tl \ior_alloc_read:n
+ \int_compare:nNnTF \l_ior_stream_int = \c_sixteen
+ { \msg_kernel_error:nn { ior } { streams-exhausted } }
+ {
+ \ior_stream_alloc:N #1
+ \prop_gput:NVn \g_ior_streams_prop \l_ior_stream_int {#2}
+ \tex_openin:D #1#2 \scan_stop:
+ }
+ }
+\cs_new_protected_nopar:Npn \iow_open:Nn #1#2
+ {
+ \iow_close:N #1
+ \int_set:Nn \l_iow_stream_int \c_sixteen
+ \tl_map_function:NN \c_iow_streams_tl \iow_alloc_write:n
+ \int_compare:nNnTF \l_iow_stream_int = \c_sixteen
+ { \msg_kernel_error:nn { iow } { streams-exhausted } }
+ {
+ \iow_stream_alloc:N #1
+ \prop_gput:NVn \g_iow_streams_prop \l_iow_stream_int {#2}
+ \tex_immediate:D \tex_openout:D #1#2 \scan_stop:
+ }
+ }
+\cs_generate_variant:Nn \ior_open:Nn { c }
+\cs_generate_variant:Nn \iow_open:Nn { c }
+\cs_new_protected_nopar:Npn \iow_alloc_write:n #1
+ {
+ \prop_if_in:NnF \g_iow_streams_prop {#1}
+ {
+ \int_set:Nn \l_iow_stream_int {#1}
+ \tl_map_break:
+ }
+ }
+\cs_new_protected_nopar:Npn \ior_alloc_read:n #1
+ {
+ \prop_if_in:NnF \g_iow_streams_prop {#1}
+ {
+ \int_set:Nn \l_ior_stream_int {#1}
+ \tl_map_break:
+ }
+ }
+\cs_new_protected_nopar:Npn \iow_stream_alloc:N #1
+ {
+ \cs_if_exist:cTF { g_iow_ \int_use:N \l_iow_stream_int _stream }
+ { \cs_gset_eq:Nc #1 { g_iow_ \int_use:N \l_iow_stream_int _stream } }
+ {
+ \iow_stream_alloc_aux:
+ \int_compare:nNnT \l_iow_stream_int = \c_sixteen
+ {
+ \iow_raw_new:N \g_iow_tmp_stream
+ \int_set:Nn \l_iow_stream_int { \g_iow_tmp_stream }
+ \cs_gset_eq:cN
+ { g_iow_ \int_use:N \l_iow_stream_int _stream }
+ \g_iow_tmp_stream
+ }
+ \cs_gset_eq:Nc #1 { g_iow_ \int_use:N \l_iow_stream_int _stream }
+ }
+ }
+\cs_new_protected_nopar:Npn \iow_stream_alloc_aux:
+ {
+ \int_incr:N \l_iow_stream_int
+ \int_compare:nNnT \l_iow_stream_int < \c_sixteen
+ {
+ \cs_if_exist:cTF { g_iow_ \int_use:N \l_iow_stream_int _stream }
+ {
+ \prop_if_in:NVT \g_iow_streams_prop \l_iow_stream_int
+ { \iow_stream_alloc_aux: }
+ }
+ { \iow_stream_alloc_aux: }
+ }
+ }
+\cs_new_protected_nopar:Npn \ior_stream_alloc:N #1
+ {
+ \cs_if_exist:cTF { g_ior_ \int_use:N \l_ior_stream_int _stream }
+ { \cs_gset_eq:Nc #1 { g_ior_ \int_use:N \l_ior_stream_int _stream } }
+ {
+ \ior_stream_alloc_aux:
+ \int_compare:nNnT \l_ior_stream_int = \c_sixteen
+ {
+ \ior_raw_new:N \g_ior_tmp_stream
+ \int_set:Nn \l_ior_stream_int { \g_ior_tmp_stream }
+ \cs_gset_eq:cN
+ { g_ior_ \int_use:N \l_iow_stream_int _stream }
+ \g_ior_tmp_stream
+ }
+ \cs_gset_eq:Nc #1 { g_ior_ \int_use:N \l_ior_stream_int _stream }
+ }
+ }
+\cs_new_protected_nopar:Npn \ior_stream_alloc_aux:
+ {
+ \int_incr:N \l_ior_stream_int
+ \int_compare:nNnT \l_ior_stream_int < \c_sixteen
+ {
+ \cs_if_exist:cTF { g_ior_ \int_use:N \l_ior_stream_int _stream }
+ {
+ \prop_if_in:NVT \g_ior_streams_prop \l_ior_stream_int
+ { \ior_stream_alloc_aux: }
+ }
+ { \ior_stream_alloc_aux: }
+ }
+ }
+\cs_new_protected_nopar:Npn \ior_close:N #1
+ {
+ \cs_if_exist:NT #1
+ {
+ \int_compare:nNnF #1 = \c_minus_one
+ {
+ \tex_closein:D #1
+ \prop_gdel:NV \g_ior_streams_prop #1
+ \cs_undefine:N #1
+ }
+ }
+ }
+\cs_new_protected_nopar:Npn \iow_close:N #1
+ {
+ \cs_if_exist:NT #1
+ {
+ \int_compare:nNnF #1 = \c_minus_one
+ {
+ \tex_immediate:D \tex_closeout:D #1
+ \prop_gdel:NV \g_iow_streams_prop #1
+ \cs_undefine:N #1
+ }
+ }
+ }
+\cs_generate_variant:Nn \ior_close:N { c }
+\cs_generate_variant:Nn \iow_close:N { c }
+\cs_new_protected_nopar:Npn \ior_list_streams:
+ {
+ \prop_if_empty:NTF \g_ior_streams_prop
+ {
+ \iow_term:x { No~input~streams~are~open }
+ \tl_show:n { }
+ }
+ {
+ \iow_term:x { The~following~input~streams~are~in~use: }
+ \tl_set:Nx \l_prop_show_tl
+ { \prop_map_function:NN \g_ior_streams_prop \ior_show_aux:nn }
+ \etex_showtokens:D \exp_after:wN \exp_after:wN \exp_after:wN
+ { \exp_after:wN \prop_show_aux:w \l_prop_show_tl }
+ }
+ }
+\cs_new:Npn \ior_show_aux:nn #1#2
+ {
+ \iow_newline: > \c_space_tl \c_space_tl
+ #1 \iow_char:N
+ \c_space_tl \c_space_tl => \c_space_tl \c_space_tl
+ \exp_not:n {#2}
+ }
+\cs_new_protected_nopar:Npn \iow_list_streams:
+ {
+ \prop_if_empty:NTF \g_iow_streams_prop
+ {
+ \iow_term:x { No~output~streams~are~open }
+ \tl_show:n { }
+ }
+ {
+ \iow_term:x { The~following~output~streams~are~in~use: }
+ \tl_set:Nx \l_prop_show_tl
+ { \prop_map_function:NN \g_iow_streams_prop \iow_show_aux:nn }
+ \etex_showtokens:D \exp_after:wN \exp_after:wN \exp_after:wN
+ { \exp_after:wN \prop_show_aux:w \l_prop_show_tl }
+ }
+ }
+\cs_new_eq:NN \iow_show_aux:nn \ior_show_aux:nn
+\msg_kernel_new:nnnn { iow } { streams-exhausted }
+ { Output~streams~exhausted }
+ {
+ TeX~can~only~open~up~to~16~output~streams~at~one~time.\\
+ All~16 are currently~in~use,~and~something~wanted~to~open
+ another~one.
+ }
+\msg_kernel_new:nnnn { ior } { streams-exhausted }
+ { Input~streams~exhausted }
+ {
+ TeX~can~only~open~up~to~16~input~streams~at~one~time.\\
+ All~16 are currently~in~use,~and~something~wanted~to~open
+ another~one.
+ }
+\cs_new_eq:NN \iow_shipout_x:Nn \tex_write:D
+\cs_generate_variant:Nn \iow_shipout_x:Nn { Nx }
+\cs_new_protected_nopar:Npn \iow_shipout:Nn #1#2
+ { \iow_shipout_x:Nn #1 { \exp_not:n {#2} } }
+\cs_generate_variant:Nn \iow_shipout:Nn { Nx }
+\cs_new_protected_nopar:Npn \iow_now:Nx { \tex_immediate:D \iow_shipout_x:Nn }
+\cs_new_protected_nopar:Npn \iow_now:Nn #1#2
+ { \iow_now:Nx #1 { \exp_not:n {#2} } }
+\cs_set_protected_nopar:Npn \iow_log:x { \iow_now:Nx \c_iow_log_stream }
+\cs_new_protected_nopar:Npn \iow_log:n { \iow_now:Nn \c_iow_log_stream }
+\cs_set_protected_nopar:Npn \iow_term:x { \iow_now:Nx \c_iow_term_stream }
+\cs_new_protected_nopar:Npn \iow_term:n { \iow_now:Nn \c_iow_term_stream }
+\cs_new_protected_nopar:Npn \iow_now_when_avail:Nn #1
+ { \cs_if_free:NTF #1 { \use_none:n } { \iow_now:Nn #1 } }
+\cs_new_protected_nopar:Npn \iow_now_when_avail:Nx #1
+ { \cs_if_free:NTF #1 { \use_none:n } { \iow_now:Nx #1 } }
+\int_new:N \l_iow_line_length_int
+\int_set:Nn \l_iow_line_length_int { 78 }
+\int_new:N \l_iow_target_length_int
+\int_new:N \l_iow_current_line_int
+\int_new:N \l_iow_current_word_int
+\tl_new:N \l_iow_current_line_tl
+\tl_new:N \l_iow_current_word_tl
+\tl_new:N \l_iow_wrap_tl
+\tl_new:N \l_iow_wrapped_tl
+\quark_new:N \q_iow_stop
+\bool_new:N \l_iow_line_start_bool
+\cs_new_protected:Npn \iow_wrap:xnnnN #1#2#3#4#5
+ {
+ \group_begin:
+ \int_set:Nn \l_iow_target_length_int { \l_iow_line_length_int - ( #3 ) }
+ \int_zero:N \l_iow_current_line_int
+ \tl_clear:N \l_iow_current_line_tl
+ \tl_clear:N \l_iow_wrap_tl
+ \bool_set_true:N \l_iow_line_start_bool
+ \cs_set:Npx \\ { \c_space_tl \iow_newline: \c_space_tl }
+ \cs_set_eq:NN \ \c_space_tl
+ #4
+ \protected@edef \l_iow_wrap_tl {#1}
+ \cs_set:Npn \\ { \iow_newline: #2 }
+ \use:x
+ {
+ \exp_not:N \iow_wrap_loop:w
+ \tl_to_str:N \l_iow_wrap_tl \c_space_tl
+ \exp_not:N \q_iow_stop \c_space_tl
+ }
+ \exp_args:NNo \group_end:
+ #5 \l_iow_wrapped_tl
+ }
+\cs_new_protected:Npn \iow_wrap_loop:w #1 ~ %
+ {
+ \tl_set:Nn \l_iow_current_word_tl {#1}
+ \tl_if_eq:NNTF \l_iow_current_word_tl \iow_newline:
+ { \iow_wrap_newline: }
+ {
+ \tl_if_eq:NNTF \l_iow_current_word_tl \q_iow_stop
+ { \iow_wrap_end: }
+ { \iow_wrap_word: }
+ }
+ }
+\cs_new_protected_nopar:Npn \iow_wrap_word:
+ {
+ \int_set:Nn \l_iow_current_word_int
+ { \str_length_skip_spaces:N \l_iow_current_word_tl }
+ \int_add:Nn \l_iow_current_line_int { \l_iow_current_word_int }
+ \int_compare:nNnTF \l_iow_current_line_int
+ < \l_iow_target_length_int
+ { \iow_wrap_word_fits: }
+ { \iow_wrap_word_newline: }
+ \iow_wrap_loop:w
+ }
+\cs_new_protected_nopar:Npn \iow_wrap_word_fits:
+ {
+ \bool_if:NTF \l_iow_line_start_bool
+ {
+ \bool_set_false:N \l_iow_line_start_bool
+ \tl_set_eq:NN \l_iow_current_line_tl \l_iow_current_word_tl
+ }
+ {
+ \tl_put_right:Nx \l_iow_current_line_tl
+ { ~ \l_iow_current_word_tl }
+ \int_incr:N \l_iow_current_line_int
+ }
+ }
+\cs_new_protected_nopar:Npn \iow_wrap_word_newline:
+ {
+ \tl_put_right:Nx \l_iow_wrapped_tl
+ { \l_iow_current_line_tl \\ }
+ \int_set_eq:NN \l_iow_current_line_int \l_iow_current_word_int
+ \tl_set_eq:NN \l_iow_current_line_tl \l_iow_current_word_tl
+ }
+\cs_new_protected_nopar:Npn \iow_wrap_newline:
+ {
+ \tl_put_right:Nx \l_iow_wrapped_tl
+ { \l_iow_current_line_tl \\ }
+ \int_zero:N \l_iow_current_line_int
+ \tl_clear:N \l_iow_current_line_tl
+ \bool_set_true:N \l_iow_line_start_bool
+ \iow_wrap_loop:w
+ }
+\cs_new_protected_nopar:Npn \iow_wrap_end:
+ {
+ \tl_put_right:Nx \l_iow_wrapped_tl
+ { \l_iow_current_line_tl }
+ }
+\cs_new_nopar:Npn \str_length_skip_spaces:N
+ { \exp_args:No \str_length_skip_spaces:n }
+\cs_new:Npn \str_length_skip_spaces:n #1
+ {
+ \int_value:w \int_eval:w
+ \exp_after:wN \str_length_loop:NNNNNNNNN \tl_to_str:n {#1}
+ {X8}{X7}{X6}{X5}{X4}{X3}{X2}{X1}{X0} \q_stop
+ \int_eval_end:
+ }
+\cs_new:Npn \str_length_loop:NNNNNNNNN #1#2#3#4#5#6#7#8#9
+ {
+ \if_catcode:w X #9
+ \exp_after:wN \use_none_delimit_by_q_stop:w
+ \else:
+ 9 +
+ \exp_after:wN \str_length_loop:NNNNNNNNN
+ \fi:
+ }
+\cs_new_nopar:Npn \iow_newline: { ^^J }
+\cs_new_eq:NN \iow_char:N \cs_to_str:N
+\prg_new_conditional:Nnn \ior_if_eof:N { p , T , F , TF }
+ {
+ \cs_if_exist:NTF #1
+ {
+ \if_eof:w #1
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+ { \prg_return_true: }
+ }
+\cs_new_protected_nopar:Npn \ior_to:NN #1#2
+ { \tex_read:D #1 to #2 }
+\cs_new_protected_nopar:Npn \ior_gto:NN #1#2
+ { \pref_global:D \tex_read:D #1 to #2 }
+\cs_new_protected_nopar:Npn \ior_str_to:NN #1#2
+ { \etex_readline:D #1 to #2 }
+\cs_new_protected_nopar:Npn \ior_str_gto:NN #1#2
+ { \pref_global:D \etex_readline:D #1 to #2 }
+\cs_new_protected:Npn \iow_now_buffer_safe:Nn #1#2
+ { \iow_wrap:xnnnN { \exp_not:n {#2} } { } \c_zero { } \iow_now:Nn #1 }
+\cs_new_protected:Npn \iow_now_buffer_safe:Nx #1#2
+ { \iow_wrap:xnnnN {#2} { } \c_zero { } \iow_now:Nn #1 }
+\cs_new_eq:NN \ior_new:N \use_none:n
+\cs_new_eq:NN \ior_new:c \use_none:n
+\cs_new_eq:NN \iow_new:N \use_none:n
+\cs_new_eq:NN \iow_new:c \use_none:n
+\cs_new_eq:NN \ior_open_streams: \ior_list_streams:
+\cs_new_eq:NN \iow_open_streams: \iow_list_streams:
+%%
+%%
+%% End of file `l3io.sty'.
diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3keys.sty b/Master/texmf-dist/tex/latex/l3kernel/l3keys.sty
new file mode 100644
index 00000000000..b12add10c9c
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/l3kernel/l3keys.sty
@@ -0,0 +1,475 @@
+%%
+%% This is file `l3keys.sty',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% l3keys.dtx (with options: `package')
+%%
+%% EXPERIMENTAL CODE
+%%
+%% Do not distribute this file without also distributing the
+%% source files specified above.
+%%
+%% Do not distribute a modified version of this file.
+%%
+%% File: l3keys.dtx Copyright (C) 2009-2011 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 "expl3 bundle" (The Work in LPPL)
+%% and all files in that bundle must be distributed together.
+%%
+%% The released version of this bundle is available from CTAN.
+%%
+%% -----------------------------------------------------------------------
+%%
+%% The development version of the bundle can be found at
+%%
+%% http://www.latex-project.org/svnroot/experimental/trunk/
+%%
+%% for those people who are interested.
+%%
+%%%%%%%%%%%
+%% NOTE: %%
+%%%%%%%%%%%
+%%
+%% Snapshots taken from the repository represent work in progress and may
+%% not work or may contain conflicting material! We therefore ask
+%% people _not_ to put them into distributions, archives, etc. without
+%% prior consultation with the LaTeX3 Project.
+%%
+%% -----------------------------------------------------------------------
+\RequirePackage{l3names}
+\GetIdInfo$Id: l3keys.dtx 2478 2011-06-19 21:34:23Z joseph $
+ {L3 Experimental key-value interfaces}
+\ProvidesExplPackage
+ {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
+\package_check_loaded_expl:
+\tl_const:Nn \c_keys_code_root_tl { key~code~>~ }
+\tl_const:Nn \c_keys_vars_root_tl { key~var~>~ }
+\tl_const:Nn \c_keys_props_root_tl { key~prop~>~ }
+\tl_const:Nn \c_keys_value_forbidden_tl { forbidden }
+\tl_const:Nn \c_keys_value_required_tl { required }
+\int_new:N \l_keys_choice_int
+\tl_new:N \l_keys_choices_tl
+\tl_new:N \l_keys_key_tl
+\tl_new:N \l_keys_module_tl
+\bool_new:N \l_keys_no_value_bool
+\tl_new:N \l_keys_path_tl
+\tl_new:N \l_keys_property_tl
+\tl_new:N \l_keys_value_tl
+\cs_new_protected:Npn \keys_define:nn
+ { \keys_define_aux:onn \l_keys_module_tl }
+\cs_new_protected:Npn \keys_define_aux:nnn #1#2#3
+ {
+ \tl_set:Nx \l_keys_module_tl { \tl_to_str:n {#2} }
+ \keyval_parse:NNn \keys_define_elt:n \keys_define_elt:nn {#3}
+ \tl_set:Nn \l_keys_module_tl {#1}
+ }
+\cs_generate_variant:Nn \keys_define_aux:nnn { o }
+\cs_new_protected_nopar:Npn \keys_define_elt:n #1
+ {
+ \bool_set_true:N \l_keys_no_value_bool
+ \keys_define_elt_aux:nn {#1} { }
+ }
+\cs_new_protected:Npn \keys_define_elt:nn #1#2
+ {
+ \bool_set_false:N \l_keys_no_value_bool
+ \keys_define_elt_aux:nn {#1} {#2}
+ }
+\cs_new_protected:Npn \keys_define_elt_aux:nn #1#2 {
+ \keys_property_find:n {#1}
+ \cs_if_exist:cTF { \c_keys_props_root_tl \l_keys_property_tl }
+ { \keys_define_key:n {#2} }
+ {
+ \msg_kernel_error:nnxx { keys } { property-unknown }
+ { \l_keys_property_tl } { \l_keys_path_tl }
+ }
+}
+\cs_new_protected_nopar:Npn \keys_property_find:n #1
+ {
+ \tl_set:Nx \l_keys_path_tl { \l_keys_module_tl / }
+ \tl_if_in:nnTF {#1} { . }
+ { \keys_property_find_aux:w #1 \q_stop }
+ { \msg_kernel_error:nnx { keys } { key-no-property } {#1} }
+ }
+\cs_new_protected_nopar:Npn \keys_property_find_aux:w #1 . #2 \q_stop
+ {
+ \tl_set:Nx \l_keys_path_tl { \l_keys_path_tl \tl_to_str:n {#1} }
+ \tl_if_in:nnTF {#2} { . }
+ {
+ \tl_set:Nx \l_keys_path_tl { \l_keys_path_tl . }
+ \keys_property_find_aux:w #2 \q_stop
+ }
+ { \tl_set:Nn \l_keys_property_tl { . #2 } }
+ }
+\cs_new_protected:Npn \keys_define_key:n #1
+ {
+ \bool_if:NTF \l_keys_no_value_bool
+ {
+ \exp_after:wN \keys_define_key_aux:w
+ \l_keys_property_tl \q_stop
+ { \use:c { \c_keys_props_root_tl \l_keys_property_tl } }
+ {
+ \msg_kernel_error:nnxx { keys }
+ { property-requires-value } { \l_keys_property_tl }
+ { \l_keys_path_tl }
+ }
+ }
+ { \use:c { \c_keys_props_root_tl \l_keys_property_tl } {#1} }
+ }
+\cs_new_protected:Npn \keys_define_key_aux:w #1 : #2 \q_stop
+ { \tl_if_empty:nTF {#2} }
+\cs_new_nopar:Npn \keys_bool_set:NN #1#2
+ {
+ \cs_if_exist:NF #1 { \bool_new:N #1 }
+ \keys_choice_make:
+ \keys_cmd_set:nx { \l_keys_path_tl / true }
+ { \exp_not:c { bool_ #2 set_true:N } \exp_not:N #1 }
+ \keys_cmd_set:nx { \l_keys_path_tl / false }
+ { \exp_not:c { bool_ #2 set_false:N } \exp_not:N #1 }
+ \keys_cmd_set:nn { \l_keys_path_tl / unknown }
+ {
+ \msg_kernel_error:nnx { keys } { boolean-values-only }
+ { \l_keys_key_tl }
+ }
+ \keys_default_set:n { true }
+ }
+\cs_new_protected_nopar:Npn \keys_choice_make:
+ {
+ \keys_cmd_set:nn { \l_keys_path_tl }
+ { \keys_choice_find:n {##1} }
+ \keys_cmd_set:nn { \l_keys_path_tl / unknown }
+ {
+ \msg_kernel_error:nnxx { keys } { choice-unknown }
+ { \l_keys_path_tl } {##1}
+ }
+ }
+\cs_new_protected:Npn \keys_choices_generate:n #1
+ {
+ \cs_if_exist:cTF
+ { \c_keys_vars_root_tl \l_keys_path_tl .choice~code }
+ {
+ \keys_choice_make:
+ \int_zero:N \l_keys_choice_int
+ \clist_map_function:nN {#1} \keys_choices_generate_aux:n
+ }
+ {
+ \msg_kernel_error:nnx { keys }
+ { generate-choices-before-code } { \l_keys_path_tl }
+ }
+ }
+\cs_new_protected_nopar:Npn \keys_choices_generate_aux:n #1
+ {
+ \keys_cmd_set:nx { \l_keys_path_tl / #1 }
+ {
+ \exp_not:n { \tl_set:Nn \l_keys_choice_tl } {#1}
+ \exp_not:n { \int_set:Nn \l_keys_choice_int }
+ { \int_use:N \l_keys_choice_int }
+ \exp_not:v
+ { \c_keys_vars_root_tl \l_keys_path_tl .choice~code }
+ }
+ \int_incr:N \l_keys_choice_int
+ }
+\cs_new_protected:Npn \keys_choice_code_store:x #1
+ {
+ \cs_if_exist:cF
+ { \c_keys_vars_root_tl \l_keys_path_tl .choice~code }
+ {
+ \tl_new:c
+ { \c_keys_vars_root_tl \l_keys_path_tl .choice~code }
+ }
+ \tl_set:cx { \c_keys_vars_root_tl \l_keys_path_tl .choice~code }
+ {#1}
+ }
+\cs_new_protected:Npn \keys_cmd_set:nn #1#2
+ {
+ \keys_cmd_set_aux:n {#1}
+ \cs_set:cpn { \c_keys_code_root_tl #1 } ##1 {#2}
+ }
+\cs_new_protected:Npn \keys_cmd_set:nx #1#2
+ {
+ \keys_cmd_set_aux:n {#1}
+ \cs_set:cpx { \c_keys_code_root_tl #1 } ##1 {#2}
+ }
+\cs_new_protected_nopar:Npn \keys_cmd_set_aux:n #1
+ {
+ \tl_clear_new:c { \c_keys_vars_root_tl #1 .default }
+ \tl_set:cn { \c_keys_vars_root_tl #1 .default } { \q_no_value }
+ \tl_clear_new:c { \c_keys_vars_root_tl #1 .req }
+ }
+\cs_new_protected:Npn \keys_default_set:n #1
+ { \tl_set:cn { \c_keys_vars_root_tl \l_keys_path_tl .default } {#1} }
+\cs_generate_variant:Nn \keys_default_set:n { V }
+\cs_new_protected_nopar:Npn \keys_meta_make:n #1
+ {
+ \exp_args:NNo \keys_cmd_set:nn \l_keys_path_tl
+ { \exp_after:wN \keys_set:nn \exp_after:wN { \l_keys_module_tl } {#1} }
+ }
+\cs_new_protected_nopar:Npn \keys_meta_make:x #1
+ {
+ \keys_cmd_set:nx { \l_keys_path_tl }
+ { \exp_not:N \keys_set:nn { \l_keys_module_tl } {#1} }
+ }
+\cs_new_protected_nopar:Npn \keys_value_requirement:n #1
+ {
+ \tl_set_eq:cc
+ { \c_keys_vars_root_tl \l_keys_path_tl .req }
+ { c_keys_value_ #1 _tl }
+ }
+\cs_new_protected_nopar:Npn \keys_variable_set:NnNN #1#2#3#4
+ {
+ \cs_if_exist:NF #1 { \use:c { #2 _new:N } #1 }
+ \keys_cmd_set:nx { \l_keys_path_tl }
+ { \exp_not:c { #2 _ #3 set:N #4 } \exp_not:N #1 {##1} }
+ }
+\cs_new_protected_nopar:Npn \keys_variable_set:NnN #1#2#3
+ { \keys_variable_set:NnNN #1 {#2} { } #3 }
+\cs_generate_variant:Nn \keys_variable_set:NnNN { c }
+\cs_generate_variant:Nn \keys_variable_set:NnN { c }
+\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .bool_set:N } #1
+ { \keys_bool_set:NN #1 { } }
+\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .bool_gset:N } #1
+ { \keys_bool_set:NN #1 g }
+\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .choice: }
+ { \keys_choice_make: }
+\cs_new_protected:cpn { \c_keys_props_root_tl .code:n } #1
+ { \keys_cmd_set:nn { \l_keys_path_tl } {#1} }
+\cs_new_protected:cpn { \c_keys_props_root_tl .code:x } #1
+ { \keys_cmd_set:nx { \l_keys_path_tl } {#1} }
+\cs_new_protected:cpn { \c_keys_props_root_tl .choice_code:n } #1
+ { \keys_choice_code_store:x { \exp_not:n {#1} } }
+\cs_new_protected:cpn { \c_keys_props_root_tl .choice_code:x } #1
+ { \keys_choice_code_store:x {#1} }
+\cs_new_protected:cpn { \c_keys_props_root_tl .default:n } #1
+ { \keys_default_set:n {#1} }
+\cs_new_protected:cpn { \c_keys_props_root_tl .default:V } #1
+ { \keys_default_set:V #1 }
+\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .dim_set:N } #1
+ { \keys_variable_set:NnN #1 { dim } n }
+\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .dim_set:c } #1
+ { \keys_variable_set:cnN {#1} { dim } n }
+\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .dim_gset:N } #1
+ { \keys_variable_set:NnNN #1 { dim } g n }
+\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .dim_gset:c } #1
+ { \keys_variable_set:cnNN {#1} { dim } g n }
+\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .fp_set:N } #1
+ { \keys_variable_set:NnN #1 { fp } n }
+\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .fp_set:c } #1
+ { \keys_variable_set:cnN {#1} { fp } n }
+\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .fp_gset:N } #1
+ { \keys_variable_set:NnNN #1 { fp } g n }
+\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .fp_gset:c } #1
+ { \keys_variable_set:cnNN {#1} { fp } g n }
+\cs_new_protected:cpn { \c_keys_props_root_tl .generate_choices:n } #1
+ { \keys_choices_generate:n {#1} }
+\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .int_set:N } #1
+ { \keys_variable_set:NnN #1 { int } n }
+\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .int_set:c } #1
+ { \keys_variable_set:cnN {#1} { int } n }
+\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .int_gset:N } #1
+ { \keys_variable_set:NnNN #1 { int } g n }
+\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .int_gset:c } #1
+ { \keys_variable_set:cnNN {#1} { int } g n }
+\cs_new_protected:cpn { \c_keys_props_root_tl .meta:n } #1
+ { \keys_meta_make:n {#1} }
+\cs_new_protected:cpn { \c_keys_props_root_tl .meta:x } #1
+ { \keys_meta_make:x {#1} }
+\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .skip_set:N } #1
+ { \keys_variable_set:NnN #1 { skip } n }
+\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .skip_set:c } #1
+ { \keys_variable_set:cnN {#1} { skip } n }
+\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .skip_gset:N } #1
+ { \keys_variable_set:NnNN #1 { skip } g n }
+\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .skip_gset:c } #1
+ { \keys_variable_set:cnNN {#1} { skip } g n }
+\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .tl_set:N } #1
+ { \keys_variable_set:NnN #1 { tl } n }
+\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .tl_set:c } #1
+ { \keys_variable_set:cnN {#1} { tl } n }
+\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .tl_set_x:N } #1
+ { \keys_variable_set:NnN #1 { tl } x }
+\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .tl_set_x:c } #1
+ { \keys_variable_set:cnN {#1} { tl } x }
+\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .tl_gset:N } #1
+ { \keys_variable_set:NnNN #1 { tl } g n }
+\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .tl_gset:c } #1
+ { \keys_variable_set:cnNN {#1} { tl } g n }
+\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .tl_gset_x:N } #1
+ { \keys_variable_set:NnNN #1 { tl } g x }
+\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .tl_gset_x:c } #1
+ { \keys_variable_set:cnNN {#1} { tl } g x }
+\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .value_forbidden: }
+ { \keys_value_requirement:n { forbidden } }
+\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .value_required: }
+ { \keys_value_requirement:n { required } }
+\cs_new_protected:Npn \keys_set:nn
+ { \keys_set_aux:onn { \l_keys_module_tl } }
+\cs_new_protected:Npn \keys_set_aux:nnn #1#2#3
+ {
+ \tl_set:Nn \l_keys_module_tl {#2}
+ \keyval_parse:NNn \keys_set_elt:n \keys_set_elt:nn {#3}
+ \tl_set:Nn \l_keys_module_tl {#1}
+ }
+\cs_generate_variant:Nn \keys_set:nn { nV , nv , no }
+\cs_generate_variant:Nn \keys_set_aux:nnn { o }
+\cs_new_protected_nopar:Npn \keys_set_elt:n #1
+ {
+ \bool_set_true:N \l_keys_no_value_bool
+ \keys_set_elt_aux:nn {#1} { }
+ }
+\cs_new_protected:Npn \keys_set_elt:nn #1#2
+ {
+ \bool_set_false:N \l_keys_no_value_bool
+ \keys_set_elt_aux:nn {#1} {#2}
+ }
+\cs_new_protected:Npn \keys_set_elt_aux:nn #1#2
+ {
+ \tl_set:Nx \l_keys_key_tl { \tl_to_str:n {#1} }
+ \tl_set:Nx \l_keys_path_tl { \l_keys_module_tl / \l_keys_key_tl }
+ \keys_value_or_default:n {#2}
+ \bool_if:nTF
+ {
+ \keys_if_value_p:n { required } &&
+ \l_keys_no_value_bool
+ }
+ {
+ \msg_kernel_error:nnx { keys } { value-required }
+ { \l_keys_path_tl }
+ }
+ {
+ \bool_if:nTF
+ {
+ \keys_if_value_p:n { forbidden } &&
+ ! \l_keys_no_value_bool
+ }
+ {
+ \msg_kernel_error:nnxx { keys } { value-forbidden }
+ { \l_keys_path_tl } { \l_keys_value_tl }
+ }
+ { \keys_execute: }
+ }
+ }
+\cs_new_protected:Npn \keys_value_or_default:n #1
+ {
+ \tl_set:Nn \l_keys_value_tl {#1}
+ \bool_if:NT \l_keys_no_value_bool
+ {
+ \quark_if_no_value:cF { \c_keys_vars_root_tl \l_keys_path_tl .default }
+ {
+ \tl_set_eq:Nc \l_keys_value_tl
+ { \c_keys_vars_root_tl \l_keys_path_tl .default }
+ }
+ }
+ }
+\prg_new_conditional:Npnn \keys_if_value:n #1 { p }
+ {
+ \tl_if_eq:ccTF { c_keys_value_ #1 _tl }
+ { \c_keys_vars_root_tl \l_keys_path_tl .req }
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+\cs_new_nopar:Npn \keys_execute:
+ { \keys_execute:nn { \l_keys_path_tl } { \keys_execute_unknown: } }
+\cs_new_nopar:Npn \keys_execute_unknown:
+ {
+ \keys_execute:nn { \l_keys_module_tl / unknown }
+ {
+ \msg_kernel_error:nnxx { keys } { key-unknown }
+ { \l_keys_path_tl } { \l_keys_module_tl }
+ }
+ }
+\cs_new_nopar:Npn \keys_execute:nn #1#2
+ {
+ \cs_if_exist:cTF { \c_keys_code_root_tl #1 }
+ {
+ \exp_args:Nno \use:c { \c_keys_code_root_tl #1 }
+ \l_keys_value_tl
+ }
+ {#2}
+ }
+\cs_new_nopar:Npn \keys_choice_find:n #1
+ {
+ \keys_execute:nn { \l_keys_path_tl / \tl_to_str:n {#1} }
+ { \keys_execute:nn { \l_keys_path_tl / unknown } { } }
+ }
+\prg_new_conditional:Npnn \keys_if_exist:nn #1#2 { p , T , F , TF }
+ {
+ \cs_if_exist:cTF { \c_keys_code_root_tl #1 / #2 }
+ { \prg_return_true:}
+ { \prg_return_false:}
+ }
+\cs_new_nopar:Npn \keys_show:nn #1#2
+ { \cs_show:c { \c_keys_code_root_tl #1 / \tl_to_str:n {#2} } }
+\msg_kernel_new:nnnn { keys } { boolean-values-only }
+ { Key~'#1'~accepts~boolean~values~only. }
+ { The~key~'#1'~only~accepts~the~values~'true'~and~'false'. }
+\msg_kernel_new:nnnn { keys } { choice-unknown }
+ { Choice~'#2'~unknown~for~key~'#1'. }
+ {
+ The~key~'#1'~takes~a~limited~number~of~values.\\
+ The~input~given,~'#2',~is~not~on~the~list~accepted.
+ }
+\msg_kernel_new:nnnn { keys } { generate-choices-before-code }
+ { No~code~available~to~generate~choices~for~key~'#1'. }
+ {
+ \c_msg_coding_error_text_tl
+ Before~using~.generate_choices:n~the~code~should~be~defined~
+ with~'.choice_code:n'~or~'.choice_code:x'.
+ }
+\msg_kernel_new:nnnn { keys } { key-no-property }
+ { No~property~given~in~definition~of~key~'#1'. }
+ {
+ \c_msg_coding_error_text_tl
+ Inside~\keys_define:nn each~key~name
+ needs~a~property: \\
+ ~ ~ #1 .<property> \\
+ LaTeX~did~not~find~a~'.'~to~indicate~the~start~of~a~property.
+ }
+\msg_kernel_new:nnnn { keys } { key-unknown }
+ { The~key~'#1'~is~unknown~and~is~being~ignored. }
+ {
+ The~module~'#2'~does~not~have~a~key~called~#1'.\\
+ Check~that~you~have~spelled~the~key~name~correctly.
+ }
+\msg_kernel_new:nnnn { keys } { option-unknown }
+ { Unknown~option~'#1'~for~package~#2. }
+ {
+ LaTeX~has~been~asked~to~set~an~option~called~'#1'~
+ but~the~#2~package~has~not~created~an~option~with~this~name.
+ }
+\msg_kernel_new:nnnn { keys } { property-requires-value }
+ { The~property~'#1'~requires~a~value. }
+ {
+ \c_msg_coding_error_text_tl
+ LaTeX~was~asked~to~set~property~'#2'~for~key~'#1'.\\
+ No~value~was~given~for~the~property,~and~one~is~required.
+ }
+\msg_kernel_new:nnnn { keys } { property-unknown }
+ { The~key~property~'#1'~is~unknown. }
+ {
+ \c_msg_coding_error_text_tl
+ LaTeX~has~been~asked~to~set~the~property~'#1'~for~key~'#2':~
+ this~property~is~not~defined.
+ }
+\msg_kernel_new:nnnn { keys } { value-forbidden }
+ { The~key~'#1'~does~not~taken~a~value. }
+ {
+ The~key~'#1'~should~be~given~without~a~value.\\
+ LaTeX~will~ignore~the~given~value~'#2'.
+ }
+\msg_kernel_new:nnnn { keys } { value-required }
+ { The~key~'#1'~requires~a~value. }
+ {
+ The~key~'#1'~must~have~a~value.\\
+ No~value~was~present:~the~key~will~be~ignored.
+ }
+%%
+%%
+%% End of file `l3keys.sty'.
diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3keyval.sty b/Master/texmf-dist/tex/latex/l3kernel/l3keyval.sty
new file mode 100644
index 00000000000..c42867b5b48
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/l3kernel/l3keyval.sty
@@ -0,0 +1,177 @@
+%%
+%% This is file `l3keyval.sty',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% l3keyval.dtx (with options: `package')
+%%
+%% EXPERIMENTAL CODE
+%%
+%% Do not distribute this file without also distributing the
+%% source files specified above.
+%%
+%% Do not distribute a modified version of this file.
+%%
+%% File: l3keyval.dtx Copyright (C) 2006-2011 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 "expl3 bundle" (The Work in LPPL)
+%% and all files in that bundle must be distributed together.
+%%
+%% The released version of this bundle is available from CTAN.
+%%
+%% -----------------------------------------------------------------------
+%%
+%% The development version of the bundle can be found at
+%%
+%% http://www.latex-project.org/svnroot/experimental/trunk/
+%%
+%% for those people who are interested.
+%%
+%%%%%%%%%%%
+%% NOTE: %%
+%%%%%%%%%%%
+%%
+%% Snapshots taken from the repository represent work in progress and may
+%% not work or may contain conflicting material! We therefore ask
+%% people _not_ to put them into distributions, archives, etc. without
+%% prior consultation with the LaTeX3 Project.
+%%
+%% -----------------------------------------------------------------------
+\RequirePackage{l3names}
+\GetIdInfo$Id: l3keyval.dtx 2478 2011-06-19 21:34:23Z joseph $
+ {L3 Experimental key-value parsing}
+ %\section{Parsing key--value lists}
+ %\begin{function}{\keyval_parse:NNn}
+\ProvidesExplPackage
+ {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
+\package_check_loaded_expl:
+\int_new:N \g_keyval_level_int
+\tl_new:N \l_keyval_key_tl
+\tl_new:N \l_keyval_value_tl
+\tl_new:N \l_keyval_sanitise_tl
+\tl_new:N \l_keyval_parse_tl
+\group_begin:
+ \char_set_catcode_active:n { `\= }
+ \char_set_catcode_active:n { `\, }
+ \char_set_lccode:nn { `\8 } { `\= }
+ \char_set_lccode:nn { `\9 } { `\, }
+\tl_to_lowercase:n
+ {
+ \group_end:
+ \cs_new_protected:Npn \keyval_parse:n #1
+ {
+ \group_begin:
+ \tl_clear:N \l_keyval_sanitise_tl
+ \tl_set:Nn \l_keyval_sanitise_tl {#1}
+ \tl_replace_all_in:Nnn \l_keyval_sanitise_tl { = } { 8 }
+ \tl_replace_all_in:Nnn \l_keyval_sanitise_tl { , } { 9 }
+ \tl_clear:N \l_keyval_parse_tl
+ \exp_after:wN \keyval_parse_elt:w \exp_after:wN
+ \q_no_value \l_keyval_sanitise_tl 9 \q_nil 9
+ \exp_after:wN \group_end:
+ \l_keyval_parse_tl
+ }
+ }
+\cs_new_protected:Npn \keyval_parse_elt:w #1 ,
+ {
+ \tl_if_blank:oTF { \use_none:n #1 }
+ { \keyval_parse_elt:w \q_no_value }
+ {
+ \quark_if_nil:oF { \use_ii:nn #1 }
+ {
+ \keyval_split_key_value:w #1 = = \q_stop
+ \keyval_parse_elt:w \q_no_value
+ }
+ }
+ }
+\cs_new_protected:Npn \keyval_split_key_value:w #1 = #2 \q_stop
+ {
+ \keyval_split_key:w #1 \q_stop
+ \str_if_eq:nnTF {#2} { = }
+ {
+ \tl_put_right:Nx \l_keyval_parse_tl
+ {
+ \exp_not:c { keyval_key_no_value_elt_ \int_use:N \g_keyval_level_int :n }
+ { \exp_not:o \l_keyval_key_tl }
+ }
+ }
+ {
+ \keyval_split_key_value_aux:wTF #2 \q_no_value \q_stop
+ { \keyval_split_value:w \q_nil #2 }
+ { \msg_kernel_error:nn { keyval } { misplaced-equals-sign } }
+ }
+ }
+\cs_new:Npn \keyval_split_key_value_aux:wTF #1 = #2#3 \q_stop
+ { \tl_if_head_eq_meaning:nNTF {#3} \q_no_value }
+\group_begin:
+ \char_set_catcode_math_toggle:n { `\Q }
+ \cs_new_protected:Npn \keyval_split_key:w #1 \q_stop
+ {
+ \exp_args:NNf \tl_set:Nn \l_keyval_key_tl
+ {
+ \exp_after:wN \keyval_remove_spaces:w \exp_after:wN
+ \exp_not:N \use_none:n #1 Q ~ Q
+ }
+ \tl_set:Nx \l_keyval_key_tl
+ { \exp_after:wN \keyval_split_key_aux:w \l_keyval_key_tl \q_stop }
+ }
+ \cs_gset:Npn \keyval_split_key_aux:w #1 \q_stop { \exp_not:n {#1} }
+ \cs_gset:Npn \keyval_remove_spaces:w #1 ~ Q { \keyval_remove_spaces_aux:w #1 Q }
+ \cs_gset:Npn \keyval_remove_spaces_aux:w #1 Q #2 {#1}
+\group_end:
+\cs_new_protected:Npn \keyval_split_value:w #1 = =
+ {
+ \tl_put_right:Nx \l_keyval_parse_tl
+ {
+ \exp_not:c { keyval_key_value_elt_ \int_use:N \g_keyval_level_int :nn }
+ { \exp_not:o \l_keyval_key_tl }
+ }
+ \tl_set:Nx \l_keyval_value_tl { \exp_not:o { \use_none:nnn #1 \q_nil \q_nil } }
+ \tl_if_empty:NTF \l_keyval_value_tl
+ { \tl_put_right:Nn \l_keyval_parse_tl { { } } }
+ {
+ \quark_if_nil:NTF \l_keyval_value_tl
+ {
+ \tl_put_right:Nx \l_keyval_parse_tl
+ { { \exp_not:o { \use_ii:nnn #1 \q_nil } } }
+ }
+ { \keyval_split_value_aux:w #1 \q_stop }
+ }
+ }
+\group_begin:
+ \char_set_catcode_math_toggle:n { `\Q }
+ \cs_new_protected:Npn \keyval_split_value_aux:w \q_nil #1 \q_stop
+ {
+ \exp_args:NNf \tl_set:Nn \l_keyval_value_tl
+ { \keyval_remove_spaces:w \exp_not:N #1 Q ~ Q }
+ \tl_put_right:Nx \l_keyval_parse_tl { { \exp_not:o \l_keyval_value_tl } }
+ }
+\group_end:
+\cs_new_protected:Npn \keyval_parse:NNn #1#2#3
+ {
+ \int_gincr:N \g_keyval_level_int
+ \cs_gset_eq:cN { keyval_key_no_value_elt_ \int_use:N \g_keyval_level_int :n } #1
+ \cs_gset_eq:cN { keyval_key_value_elt_ \int_use:N \g_keyval_level_int :nn } #2
+ \keyval_parse:n {#3}
+ \int_gdecr:N \g_keyval_level_int
+ }
+\msg_kernel_new:nnnn { keyval } { misplaced-equals-sign }
+ { Misplaced~equals~sign~in~key-value~input~\msg_line_number: }
+ {
+ LaTeX~is~attempting~to~parse~some~key-value~input~but~found~
+ two~equals~signs~not~separated~by~a~comma.
+ }
+\cs_new_eq:NN \KV_process_space_removal_sanitize:NNn \keyval_parse:NNn
+\cs_new_eq:NN \KV_process_space_removal_no_sanitize:NNn \keyval_parse:NNn
+\cs_new_eq:NN \KV_process_no_space_removal_no_sanitize:NNn \keyval_parse:NNn
+%%
+%%
+%% End of file `l3keyval.sty'.
diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3luatex.sty b/Master/texmf-dist/tex/latex/l3kernel/l3luatex.sty
new file mode 100644
index 00000000000..b7e63c89882
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/l3kernel/l3luatex.sty
@@ -0,0 +1,160 @@
+%%
+%% This is file `l3luatex.sty',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% l3luatex.dtx (with options: `package')
+%%
+%% EXPERIMENTAL CODE
+%%
+%% Do not distribute this file without also distributing the
+%% source files specified above.
+%%
+%% Do not distribute a modified version of this file.
+%%
+%% File: l3luatex.dtx Copyright (C) 2010,2011 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 "expl3 bundle" (The Work in LPPL)
+%% and all files in that bundle must be distributed together.
+%%
+%% The released version of this bundle is available from CTAN.
+%%
+%% -----------------------------------------------------------------------
+%%
+%% The development version of the bundle can be found at
+%%
+%% http://www.latex-project.org/svnroot/experimental/trunk/
+%%
+%% for those people who are interested.
+%%
+%%%%%%%%%%%
+%% NOTE: %%
+%%%%%%%%%%%
+%%
+%% Snapshots taken from the repository represent work in progress and may
+%% not work or may contain conflicting material! We therefore ask
+%% people _not_ to put them into distributions, archives, etc. without
+%% prior consultation with the LaTeX3 Project.
+%%
+%% -----------------------------------------------------------------------
+\RequirePackage{l3names}
+\GetIdInfo$Id: l3luatex.dtx 2478 2011-06-19 21:34:23Z joseph $
+ {L3 Experimental LuaTeX-specific functions}
+\ProvidesExplPackage
+ {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
+\package_check_loaded_expl:
+\luatex_if_engine:TF
+ {
+ \cs_new_eq:NN \lua_now:x \luatex_directlua:D
+ \cs_new_eq:NN \lua_shipout_x:n \luatex_latelua:D
+ }
+ {
+ \cs_new:Npn \lua_now:x #1 { \lua_wrong_engine: }
+ \cs_new_protected:Npn \lua_shipout_x:n #1 { \lua_wrong_engine: }
+ }
+\cs_new:Npn \lua_now:n #1
+ { \lua_now:x { \exp_not:n {#1} } }
+\cs_generate_variant:Nn \lua_shipout_x:n { x }
+\cs_new_protected:Npn \lua_shipout:n #1
+ { \lua_shipout_x:n { \exp_not:n {#1} } }
+\cs_generate_variant:Nn \lua_shipout:n { x }
+\group_begin:
+\char_set_catcode_letter:N\!
+\char_set_catcode_letter:N\ %
+\cs_gset:Npn\lua_wrong_engine:{%
+\LuaTeX engine not in use!%
+}%
+\group_end:%
+\int_new:N \g_cctab_allocate_int
+\int_set:Nn \g_cctab_allocate_int { -1 }
+\int_new:N \g_cctab_stack_int
+\seq_new:N \g_cctab_stack_seq
+\cs_new_protected_nopar:Npn \cctab_new:N #1
+ {
+ \cs_if_free:NTF #1
+ {
+ \int_gadd:Nn \g_cctab_allocate_int { 2 }
+ \int_compare:nNnTF
+ { \g_cctab_allocate_int } < { \c_max_register_int + 1 }
+ {
+ \pref_global:D \tex_mathchardef:D #1 \g_cctab_allocate_int
+ \luatex_initcatcodetable:D #1
+ }
+ { \msg_kernel_fatal:nnx { alloc } { out-of-registers } { cctab } }
+ }
+ {
+ \msg_kernel_error:nnx { code } { variable-already-defined }
+ { \token_to_str:N #1 }
+ }
+ }
+\luatex_if_engine:F
+ { \cs_set_protected_nopar:Npn \cctab_new:N #1 { \lua_wrong_engine: } }
+\luatex_if_engine:T
+ {
+ \cs_set_protected_nopar:Npn \cctab_new:N #1
+ {
+ \newcatcodetable #1
+ \luatex_initcatcodetable:D #1
+ }
+ }
+\cs_new_protected_nopar:Npn \cctab_begin:N #1
+ {
+ \seq_gpush:Nx \g_cctab_stack_seq { \tex_the:D \luatex_catcodetable:D }
+ \luatex_catcodetable:D #1
+ \int_gadd:Nn \g_cctab_stack_int { 2 }
+ \int_compare:nNnT { \g_cctab_stack_int } > { 268 435 453 }
+ { \msg_kernel_error:nn { code } { cctab-stack-full } }
+ \luatex_savecatcodetable:D \g_cctab_stack_int
+ \luatex_catcodetable:D \g_cctab_stack_int
+ }
+\cs_new_protected_nopar:Npn \cctab_end:
+ {
+ \int_gsub:Nn \g_cctab_stack_int { 2 }
+ \seq_gpop:NN \g_cctab_stack_seq \l_cctab_tmp_tl
+ \quark_if_no_value:NT \l_cctab_tmp_tl
+ { \tl_set:Nn \l_cctab_tmp_tl { 0 } }
+ \luatex_catcodetable:D \l_cctab_tmp_tl \scan_stop:
+ }
+\luatex_if_engine:F
+ {
+ \cs_set_protected_nopar:Npn \cctab_begin:N #1 { \lua_wrong_engine: }
+ \cs_set_protected_nopar:Npn \cctab_end: { \lua_wrong_engine: }
+ }
+\luatex_if_engine:T
+ {
+ \cs_set_protected_nopar:Npn \cctab_begin:N #1 { \BeginCatcodeRegime #1 }
+ \cs_set_protected_nopar:Npn \cctab_end: { \EndCatcodeRegime }
+ }
+\tl_new:N \l_cctab_tmp_tl
+\cs_new_protected:Npn \cctab_gset:Nn #1#2
+ {
+ \group_begin:
+ #2
+ \luatex_savecatcodetable:D #1
+ \group_end:
+ }
+\luatex_if_engine:F
+ { \cs_set_protected_nopar:Npn \cctab_gset:Nn #1#2 { \lua_wrong_engine: } }
+\luatex_if_engine:T
+ {
+ \cctab_new:N \c_code_cctab
+ \cctab_gset:Nn \c_code_cctab { }
+ }
+\luatex_if_engine:T
+ {
+ \cs_new_eq:NN \c_document_cctab \CatcodeTableLaTeX
+ \cs_new_eq:NN \c_initex_cctab \CatcodeTableIniTeX
+ \cs_new_eq:NN \c_other_cctab \CatcodeTableOther
+ \cs_new_eq:NN \c_string_cctab \CatcodeTableString
+ }
+%%
+%%
+%% End of file `l3luatex.sty'.
diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3msg.sty b/Master/texmf-dist/tex/latex/l3kernel/l3msg.sty
new file mode 100644
index 00000000000..bf1d732514f
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/l3kernel/l3msg.sty
@@ -0,0 +1,574 @@
+%%
+%% This is file `l3msg.sty',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% l3msg.dtx (with options: `package')
+%%
+%% EXPERIMENTAL CODE
+%%
+%% Do not distribute this file without also distributing the
+%% source files specified above.
+%%
+%% Do not distribute a modified version of this file.
+%%
+%% File: l3msg.dtx Copyright (C) 2009-2011 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 "expl3 bundle" (The Work in LPPL)
+%% and all files in that bundle must be distributed together.
+%%
+%% The released version of this bundle is available from CTAN.
+%%
+%% -----------------------------------------------------------------------
+%%
+%% The development version of the bundle can be found at
+%%
+%% http://www.latex-project.org/svnroot/experimental/trunk/
+%%
+%% for those people who are interested.
+%%
+%%%%%%%%%%%
+%% NOTE: %%
+%%%%%%%%%%%
+%%
+%% Snapshots taken from the repository represent work in progress and may
+%% not work or may contain conflicting material! We therefore ask
+%% people _not_ to put them into distributions, archives, etc. without
+%% prior consultation with the LaTeX3 Project.
+%%
+%% -----------------------------------------------------------------------
+\RequirePackage{l3names}
+\GetIdInfo$Id: l3msg.dtx 2478 2011-06-19 21:34:23Z joseph $
+ {L3 Experimental messages}
+\ProvidesExplPackage
+ {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
+\package_check_loaded_expl:
+\tl_new:N \l_msg_tmp_tl
+\tl_const:Nn \c_msg_text_prefix_tl { msg~text~>~ }
+\tl_const:Nn \c_msg_more_text_prefix_tl { msg~extra~text~>~ }
+\cs_new_protected:Npn \msg_new:nnnn #1#2
+ {
+ \cs_if_exist:cT { \c_msg_text_prefix_tl #1 / #2 }
+ {
+ \msg_kernel_error:nn { msg } { message-already-defined }
+ {#1} {#2}
+ }
+ \msg_set:nnnn {#1} {#2}
+ }
+\cs_new_protected:Npn \msg_new:nnn #1#2#3
+ { \msg_new:nnnn {#1} {#2} {#3} { } }
+\cs_new_protected:Npn \msg_set:nnnn #1#2#3#4
+ {
+ \cs_set:cpn { \c_msg_text_prefix_tl #1 / #2 }
+ ##1##2##3##4 {#3}
+ \cs_set:cpn { \c_msg_more_text_prefix_tl #1 / #2 }
+ ##1##2##3##4 {#4}
+ }
+\cs_new_protected:Npn \msg_set:nnn #1#2#3
+ { \msg_set:nnnn {#1} {#2} {#3} { } }
+\tl_const:Nn \c_msg_coding_error_text_tl
+ {
+ This~is~a~coding~error.
+ \\ \\
+ }
+\tl_const:Nn \c_msg_continue_text_tl
+ { Type~<return>~to~continue }
+\tl_const:Nn \c_msg_critical_text_tl
+ { Reading~the~current~file~will~stop }
+\tl_const:Nn \c_msg_fatal_text_tl
+ { This~is~a~fatal~error:~LaTeX~will~abort }
+\tl_const:Nn \c_msg_help_text_tl
+ { For~immediate~help~type~H~<return> }
+\tl_const:Nn \c_msg_no_info_text_tl
+ {
+ LaTeX~does~not~know~anything~more~about~this~error,~sorry.
+ \c_msg_return_text_tl
+ }
+\tl_const:Nn \c_msg_on_line_text_tl { on~line }
+\tl_const:Nn \c_msg_return_text_tl
+ {
+ \\ \\
+ Try~typing~<return>~to~proceed.
+ \\
+ If~that~doesn't~work,~type~X~<return>~to~quit.
+ }
+\tl_const:Nn \c_msg_trouble_text_tl
+ {
+ \\ \\
+ More~errors~will~almost~certainly~follow: \\
+ the~LaTeX~run~should~be~aborted.
+ }
+\cs_new_nopar:Npn \msg_newline: { ^^J }
+\cs_new_nopar:Npn \msg_two_newlines: { ^^J ^^J }
+\cs_new_nopar:Npn \msg_line_number: { \int_use:N \tex_inputlineno:D }
+\cs_set_nopar:Npn \msg_line_context:
+ {
+ \c_msg_on_line_text_tl
+ \c_space_tl
+ \msg_line_number:
+ }
+\char_set_catcode_letter:N \.
+\tl_new:N
+ \c_msg_hide_tl..........................................................
+\tl_const:Nn \c_msg_hide_tl
+ { \c_msg_hide_tl.......................................................... }
+\char_set_catcode_other:N \.
+\cs_new_protected:Npn \msg_interrupt:xxx #1#2#3
+ {
+ \group_begin:
+ \tl_if_empty:nTF {#3}
+ { \msg_interrupt_no_details:xx {#1} {#2} }
+ { \msg_interrupt_details:xxx {#1} {#2} {#3} }
+ \msg_interrupt_aux:
+ \group_end:
+ }
+\cs_new_protected:Npn \msg_interrupt_no_details:xx #1#2
+ {
+ \iow_wrap:xnnnN
+ { \\ \c_msg_no_info_text_tl }
+ { |~ } { 2 } { } \msg_interrupt_more_text:n
+ \iow_wrap:xnnnN { #1 \\ \\ #2 \\ \\ \c_msg_continue_text_tl }
+ { ! ~ } { 2 } {} \msg_interrupt_text:n
+ }
+\cs_new_protected:Npn \msg_interrupt_details:xxx #1#2#3
+ {
+ \iow_wrap:xnnnN
+ { \\ #3 }
+ { |~ } { 2 } { } \msg_interrupt_more_text:n
+ \iow_wrap:xnnnN { #1 \\ \\ #2 \\ \\ \c_msg_help_text_tl }
+ { ! ~ } { 2 } { } \msg_interrupt_text:n
+ }
+\cs_new_protected:Npn \msg_interrupt_text:n #1
+ { \tl_set:Nn \l_msg_text_tl {#1} }
+\cs_new_protected:Npn \msg_interrupt_more_text:n #1
+ {
+ \protected@edef \l_msg_tmp_tl
+ {
+ |'''''''''''''''''''''''''''''''''''''''''''''''
+ #1
+ \msg_newline:
+ |...............................................
+ }
+ \tex_errhelp:D \exp_after:wN { \l_msg_tmp_tl }
+ }
+\group_begin: % {
+ \char_set_lccode:w `\} = `\ \scan_stop:
+ \char_set_lccode:w `\& = `\! \scan_stop:
+ \char_set_catcode_active:N \&
+\tl_to_lowercase:n
+ {
+ \group_end:
+ \cs_new_protected:Npn \msg_interrupt_aux:
+ {
+ \iow_term:x
+ {
+ \iow_newline:
+ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ \iow_newline:
+ !
+ }
+ \tl_put_right:No \l_msg_text_tl { \c_msg_hide_tl }
+ \cs_set_protected_nopar:Npx &
+ { \tex_errmessage:D { \exp_not:o { \l_msg_text_tl } } }
+ &
+ }
+ }
+\cs_new_protected:Npn \msg_log:x #1
+ {
+ \iow_log:x { ................................................. }
+ \iow_wrap:xnnnN { . ~ #1} { . ~ } { 2 } { }
+ \iow_log:x
+ \iow_log:x { ................................................. }
+ }
+\cs_new_protected:Npn \msg_term:x #1
+ {
+ \iow_term:x { ************************************************* }
+ \iow_wrap:xnnnN { * ~ #1} { * ~ } { 2 } { }
+ \iow_term:x
+ \iow_term:x { ************************************************* }
+ }
+\int_set:Nn \tex_errorcontextlines:D { -1 }
+\cs_new_nopar:Npn \msg_fatal_text:n #1 { Fatal~#1~error }
+\cs_new_nopar:Npn \msg_critical_text:n #1 { Critical~#1~error }
+\cs_new_nopar:Npn \msg_error_text:n #1 { #1~error }
+\cs_new_nopar:Npn \msg_warning_text:n #1 { #1~warning }
+\cs_new_nopar:Npn \msg_info_text:n #1 { #1~info }
+\cs_new_nopar:Npn \msg_see_documentation_text:n #1
+ { \\ \\ See~the~#1~documentation~for~further~information. }
+\prop_new:N \l_msg_redirect_classes_prop
+\prop_new:N \l_msg_redirect_names_prop
+\cs_new_protected_nopar:Npn \msg_class_set:nn #1#2
+ {
+ \prop_clear_new:c { l_msg_redirect_ #1 _prop }
+ \cs_set_protected:cpn { msg_ #1 :nnxxxx } ##1##2##3##4##5##6
+ { \msg_use:nnnnxxxx {#1} {#2} {##1} {##2} {##3} {##4} {##5} {##6} }
+ \cs_set_protected:cpx { msg_ #1 :nnxxx } ##1##2##3##4##5
+ { \exp_not:c { msg_ #1 :nnxxxx } {##1} {##2} {##3} {##4} {##5} { } }
+ \cs_set_protected:cpx { msg_ #1 :nnxx } ##1##2##3##4
+ { \exp_not:c { msg_ #1 :nnxxxx } {##1} {##2} {##3} {##4} { } { } }
+ \cs_set_protected:cpx { msg_ #1 :nnx } ##1##2##3
+ { \exp_not:c { msg_ #1 :nnxxxx } {##1} {##2} {##3} { } { } { } }
+ \cs_set_protected:cpx { msg_ #1 :nn } ##1##2
+ { \exp_not:c { msg_ #1 :nnxxxx } {##1} {##2} { } { } { } { } }
+ }
+\prg_set_conditional:Npnn \msg_if_more_text:N #1 { p , T , F , TF }
+ {
+ \cs_if_eq:NNTF #1 \msg_no_more_text:xxxx
+ { \prg_return_false: }
+ { \prg_return_true: }
+ }
+\cs_new:Npn \msg_no_more_text:xxxx #1#2#3#4 { }
+\cs_generate_variant:Nn \msg_if_more_text_p:N { c }
+\cs_generate_variant:Nn \msg_if_more_text:NT { c }
+\cs_generate_variant:Nn \msg_if_more_text:NF { c }
+\cs_generate_variant:Nn \msg_if_more_text:NTF { c }
+\msg_class_set:nn { fatal }
+ {
+ \msg_interrupt:xxx
+ { \msg_fatal_text:n {#1} : ~ "#2" }
+ {
+ \use:c { \c_msg_text_prefix_tl #1 / #2 } {#3} {#4} {#5} {#6}
+ \msg_see_documentation_text:n {#1}
+ }
+ { \c_msg_fatal_text_tl }
+ \tex_end:D
+ }
+\msg_class_set:nn { critical }
+ {
+ \msg_interrupt:xxx
+ { \msg_critical_text:n {#1} : ~ "#2" }
+ {
+ \use:c { \c_msg_text_prefix_tl #1 / #2 } {#3} {#4} {#5} {#6}
+ \msg_see_documentation_text:n {#1}
+ }
+ { \c_msg_critical_text_tl }
+ \tex_endinput:D
+ }
+\msg_class_set:nn { error }
+ {
+ \msg_if_more_text:cTF { \c_msg_more_text_prefix_tl #1 / #2 }
+ {
+ \msg_interrupt:xxx
+ { \msg_error_text:n {#1} : ~ "#2" }
+ {
+ \use:c { \c_msg_text_prefix_tl #1 / #2 } {#3} {#4} {#5} {#6}
+ \msg_see_documentation_text:n {#1}
+ }
+ { \use:c { \c_msg_more_text_prefix_tl #1 / #2 } {#3} {#4} {#5} {#6} }
+ }
+ {
+ \msg_interrupt:xxx
+ { \msg_error_text:n {#1} : ~ "#2" }
+ {
+ \use:c { \c_msg_text_prefix_tl #1 / #2 } {#3} {#4} {#5} {#6}
+ \msg_see_documentation_text:n {#1}
+ }
+ { }
+ }
+ }
+\msg_class_set:nn { warning }
+ {
+ \msg_term:x
+ {
+ \msg_warning_text:n {#1} : ~ "#2" \\ \\
+ \use:c { \c_msg_text_prefix_tl #1 / #2 } {#3} {#4} {#5} {#6}
+ }
+ }
+\msg_class_set:nn { info }
+ {
+ \msg_log:x
+ {
+ \msg_info_text:n {#1} : ~ "#2" \\ \\
+ \use:c { \c_msg_text_prefix_tl #1 / #2 } {#3} {#4} {#5} {#6}
+ }
+ }
+\msg_class_set:nn { log }
+ {
+ \msg_log:x
+ { \use:c { \c_msg_text_prefix_tl #1 / #2 } {#3} {#4} {#5} {#6} }
+ }
+\msg_class_set:nn { none } { }
+\seq_new:N \l_msg_redirect_classes_seq
+\tl_new:N \l_msg_class_tl
+\tl_new:N \l_msg_current_class_tl
+\tl_new:N \l_msg_current_module_tl
+\cs_new_protected:Npn \msg_use:nnnnxxxx #1#2#3#4#5#6#7#8
+ {
+ \cs_set_protected_nopar:Npx \msg_use_code:
+ {
+ \seq_clear:N \exp_not:N \l_msg_redirect_classes_seq
+ \exp_not:n {#2}
+ }
+ \cs_set_protected:Npx \msg_use_loop:n ##1
+ {
+ \seq_if_in:NnTF \exp_not:n \l_msg_redirect_classes_seq {#1}
+ { \msg_kernel_error:nn { msg } { message-loop } {#1} }
+ {
+ \seq_put_right:Nn \exp_not:N \l_msg_redirect_classes_seq {#1}
+ \exp_not:N \cs_if_exist:cTF { msg_ ##1 :nnxxxx }
+ {
+ \exp_not:N \use:c { msg_ ##1 :nnxxxx }
+ \exp_not:n { {#3} {#4} {#5} {#6} {#7} {#8} }
+ }
+ {
+ \msg_kernel_error:nnx { msg } { message-class-unknown } {##1}
+ }
+ }
+ }
+ \cs_if_exist:cTF { \c_msg_text_prefix_tl #3 / #4 }
+ { \msg_use_aux:nnn {#1} {#3} {#4} }
+ { \msg_kernel_error:nnxx { msg } { message-unknown } {#3} {#4} }
+ }
+\cs_new_protected_nopar:Npn \msg_use_aux:nnn #1#2#3
+ {
+ \tl_set:Nn \l_msg_current_class_tl {#1}
+ \tl_set:Nn \l_msg_current_module_tl {#2}
+ \prop_if_in:NnTF \l_msg_redirect_names_prop { // #2 / #3 / }
+ { \msg_use_loop_check:nn { names } { // #2 / #3 / } }
+ { \msg_use_aux:nn {#1} {#2} }
+ }
+\cs_new_protected_nopar:Npn \msg_use_aux:nn #1#2
+ {
+ \prop_if_in:cnTF { l_msg_redirect_ #1 _prop } {#2}
+ { \msg_use_loop_check:nn {#1} {#2} }
+ {
+ \prop_if_in:cnTF { l_msg_redirect_ #1 _prop } { * }
+ { \msg_use_loop_check:nn {#1} { * } }
+ { \msg_use_code: }
+ }
+ }
+\cs_new_protected:Npn \msg_use_loop_check:nn #1#2
+ {
+ \prop_get:cnN { l_msg_redirect_ #1 _prop } {#2} \l_msg_class_tl
+ \tl_if_eq:NNTF \l_msg_current_class_tl \l_msg_class_tl
+ {
+ { \msg_use_code: }
+ { \msg_use_loop:o \l_msg_class_tl }
+ }
+ }
+\cs_new_protected_nopar:Npn \msg_use_code: { }
+\cs_new_protected:Npn \msg_use_loop:n #1 { }
+\cs_generate_variant:Nn \msg_use_loop:n { o }
+\cs_new_protected_nopar:Npn \msg_redirect_class:nn #1#2
+ { \prop_put:cnn { l_msg_redirect_ #1 _prop } { * } {#2} }
+\cs_new_protected_nopar:Npn \msg_redirect_module:nnn #1#2#3
+ { \prop_put:cnn { l_msg_redirect_ #2 _prop } {#1} {#3} }
+\cs_new_protected_nopar:Npn \msg_redirect_name:nnn #1#2#3
+ { \prop_put:Nnn \l_msg_redirect_names_prop { // #1 / #2 / } {#3} }
+\cs_new_protected_nopar:Npn \msg_kernel_new:nnnn #1#2
+ { \msg_new:nnnn { LaTeX } { #1 / #2 } }
+\cs_new_protected_nopar:Npn \msg_kernel_new:nnn #1#2
+ { \msg_new:nnn { LaTeX } { #1 / #2 } }
+\cs_new_protected_nopar:Npn \msg_kernel_set:nnnn #1#2
+ { \msg_set:nnnn { LaTeX } { #1 / #2 } }
+\cs_new_protected_nopar:Npn \msg_kernel_set:nnn #1#2
+ { \msg_set:nnn { LaTeX } { #1 / #2 } }
+\cs_new_protected:Npn \msg_kernel_fatal:nnxxxx #1#2#3#4#5#6
+ {
+ \msg_interrupt:xxx
+ { \msg_fatal_text:n { LaTeX } : ~ "#1 / #2" }
+ {
+ \use:c { \c_msg_text_prefix_tl LaTeX / #1 / #2 }
+ {#3} {#4} {#5} {#6}
+ \msg_see_documentation_text:n { LaTeX3 }
+ }
+ { \c_msg_fatal_text_tl }
+ \tex_end:D
+ }
+\cs_new_protected:Npn \msg_kernel_fatal:nnxxx #1#2#3#4#5
+ {\msg_kernel_fatal:nnxxxx {#1} {#2} {#3} {#4} {#5} { } }
+\cs_new_protected:Npn \msg_kernel_fatal:nnxx #1#2#3#4
+ { \msg_kernel_fatal:nnxxxx {#1} {#2} {#3} {#4} { } { } }
+\cs_new_protected:Npn \msg_kernel_fatal:nnx #1#2#3
+ { \msg_kernel_fatal:nnxxxx {#1} {#2} {#3} { } { } { } }
+\cs_new_protected:Npn \msg_kernel_fatal:nn #1#2
+ { \msg_kernel_fatal:nnxxxx {#1} {#2} { } { } { } { } }
+\cs_new_protected:Npn \msg_kernel_error:nnxxxx #1#2#3#4#5#6
+ {
+ \msg_if_more_text:cTF { \c_msg_more_text_prefix_tl LaTeX / #1 / #2 }
+ {
+ \msg_interrupt:xxx
+ { \msg_error_text:n { LaTeX } : ~ " #1 / #2 " }
+ {
+ \use:c { \c_msg_text_prefix_tl LaTeX / #1 / #2 }
+ {#3} {#4} {#5} {#6}
+ \msg_see_documentation_text:n { LaTeX3 }
+ }
+ {
+ \use:c { \c_msg_more_text_prefix_tl LaTeX / #1 / #2 }
+ {#3} {#4} {#5} {#6}
+ }
+ }
+ {
+ \msg_interrupt:xxx
+ { \msg_error_text:n { LaTeX } : ~ " #1 / #2 " }
+ {
+ \use:c { \c_msg_text_prefix_tl LaTeX / #1 / #2 }
+ {#3} {#4} {#5} {#6}
+ \msg_see_documentation_text:n { LaTeX3 }
+ }
+ { }
+ }
+ }
+\cs_new_protected:Npn \msg_kernel_error:nnxxx #1#2#3#4#5
+ {\msg_kernel_error:nnxxxx {#1} {#2} {#3} {#4} {#5} { } }
+\cs_set_protected:Npn \msg_kernel_error:nnxx #1#2#3#4
+ { \msg_kernel_error:nnxxxx {#1} {#2} {#3} {#4} { } { } }
+\cs_set_protected:Npn \msg_kernel_error:nnx #1#2#3
+ { \msg_kernel_error:nnxxxx {#1} {#2} {#3} { } { } { } }
+\cs_set_protected:Npn \msg_kernel_error:nn #1#2
+ { \msg_kernel_error:nnxxxx {#1} {#2} { } { } { } { } }
+\prop_new:N \l_msg_redirect_kernel_warning_prop
+\cs_new_protected:Npn \msg_kernel_warning:nnxxxx #1#2#3#4#5#6
+ {
+ \msg_use:nnnnxxxx { warning }
+ {
+ \msg_term:x
+ {
+ \msg_warning_text:n { LaTeX } : ~ " #1 / #2 " \\ \\
+ \use:c { \c_msg_text_prefix_tl LaTeX / #1 / #2 }
+ {#3} {#4} {#5} {#6}
+ }
+ }
+ { LaTeX } { #1 / #2 } {#3} {#4} {#5} {#6}
+ }
+\cs_new_protected:Npn \msg_kernel_warning:nnxxx #1#2#3#4#5
+ { \msg_kernel_warning:nnxxxx {#1} {#2} {#3} {#4} {#5} { } }
+\cs_new_protected:Npn \msg_kernel_warning:nnxx #1#2#3#4
+ { \msg_kernel_warning:nnxxxx {#1} {#2} {#3} {#4} { } { } }
+\cs_new_protected:Npn \msg_kernel_warning:nnx #1#2#3
+ { \msg_kernel_warning:nnxxxx {#1} {#2} {#3} { } { } { } }
+\cs_new_protected:Npn \msg_kernel_warning:nn #1#2
+ { \msg_kernel_warning:nnxxxx {#1} {#2} { } { } { } { } }
+\prop_new:N \l_msg_redirect_kernel_info_prop
+\cs_new_protected:Npn \msg_kernel_info:nnxxxx #1#2#3#4#5#6
+ {
+ \msg_use:nnnnxxxx { info }
+ {
+ \msg_log:x
+ {
+ \msg_info_text:n { LaTeX } : ~ " #1 / #2 " \\ \\
+ \use:c { \c_msg_text_prefix_tl LaTeX / #1 / #2 }
+ {#3} {#4} {#5} {#6}
+ }
+ }
+ { LaTeX } { #1 / #2 } {#3} {#4} {#5} {#6}
+ }
+\cs_new_protected:Npn \msg_kernel_info:nnxxx #1#2#3#4#5
+ { \msg_kernel_info:nnxxxx {#1} {#2} {#3} {#4} {#5} { } }
+\cs_new_protected:Npn \msg_kernel_info:nnxx #1#2#3#4
+ { \msg_kernel_info:nnxxxx {#1} {#2} {#3} {#4} { } { } }
+\cs_new_protected:Npn \msg_kernel_info:nnx #1#2#3
+ { \msg_kernel_info:nnxxxx {#1} {#2} {#3} { } { } { } }
+\cs_new_protected:Npn \msg_kernel_info:nn #1#2
+ { \msg_kernel_info:nnxxxx {#1} {#2} { } { } { } { } }
+\msg_kernel_new:nnnn { msg } { message-already-defined }
+ { Message~'#2'~for~module~'#1'~already~defined. }
+ {
+ \c_msg_coding_error_text_tl
+ LaTeX~was~asked~to~define~a~new~message~called~'#2'
+ by~the~module~'#1'~module:\\
+ this~message~already~exists.
+ \c_msg_return_text_tl
+ }
+\msg_kernel_new:nnnn { msg } { message-unknown }
+ { Unknown~message~'#2'~for~module~'#1'. }
+ {
+ \c_msg_coding_error_text_tl
+ LaTeX~was~asked~to~display~a~message~called~'#2'\\
+ by~the~module~'#1'~module:~this~message~does~not~exist.
+ \c_msg_return_text_tl
+ }
+\msg_kernel_new:nnnn { msg } { message-class-unknown }
+ { Unknown~message~class~'#1'. }
+ {
+ LaTeX~has~been~asked~to~redirect~messages~to~a~class~'#1':\\
+ this~was~never~defined.
+ \c_msg_return_text_tl
+ }
+\msg_kernel_new:nnnn { msg } { redirect-loop }
+ { Message~redirection~loop~for~message~class~'#1'. }
+ {
+ LaTeX~has~been~asked~to~redirect~messages~in~an~infinite~loop.\\
+ The~original~message~here~has~been~lost.
+ \c_msg_return_text_tl
+ }
+\msg_kernel_new:nnnn { kernel } { bad-number-of-arguments }
+ { Function~'#1'~cannot~be~defined~with~#2~arguments. }
+ {
+ \c_msg_coding_error_text_tl
+ LaTeX~has~been~asked~to~define~a~function~'#1'~with~
+ #2~arguments. \\
+ TeX~allows~between~0~and~9~arguments~for~a~single~function.
+ }
+\msg_kernel_new:nnnn { kernel } { command-already-defined }
+ { Control~sequence~#1~already~defined. }
+ {
+ \c_msg_coding_error_text_tl
+ LaTeX~has~been~asked~to~create~a~new~control~sequence~'#1'~
+ but~this~name~has~already~been~used~elsewhere. \\ \\
+ The~current~meaning~is:\\
+ \ \ #2
+ }
+\msg_kernel_new:nnnn { kernel } { command-not-defined }
+ { Control~sequence~#1~undefined. }
+ {
+ \c_msg_coding_error_text_tl
+ LaTeX~has~been~asked~to~use~a~command~#1,~but~this~has~not~
+ been~defined~yet.
+ }
+\msg_kernel_new:nnnn { kernel } { variable-not-defined }
+ { Variable~#1~undefined. }
+ {
+ \c_msg_coding_error_text_tl
+ LaTeX~has~been~asked~to~show~a~variable~#1,~but~this~has~not~
+ been~defined~yet.
+ }
+\msg_kernel_new:nnnn { seq } { empty-sequence }
+ { Empty~sequence~#1. }
+ {
+ \c_msg_coding_error_text_tl
+ LaTeX~has~been~asked~to~recover~an~entry~from~a~sequence~that~
+ has~no~content:~that~cannot~happen!
+ }
+\cs_set_protected:Npn \msg_kernel_bug:x #1
+ {
+ \msg_interrupt:xxx { \c_msg_kernel_bug_text_tl }
+ {
+ #1
+ \msg_see_documentation_text:n { LaTeX3 }
+ }
+ { \c_msg_kernel_bug_more_text_tl }
+ }
+\tl_const:Nn \c_msg_kernel_bug_text_tl
+ { This~is~a~LaTeX~bug:~check~coding! }
+\tl_const:Nn \c_msg_kernel_bug_more_text_tl
+ {
+ There~is~a~coding~bug~somewhere~around~here. \\
+ This~probably~needs~examining~by~an~expert.
+ \c_msg_return_text_tl
+ }
+\cs_new_eq:NN \msg_class_new:nn \msg_class_set:nn
+\cs_new_eq:NN \msg_trace:nnxxxx \msg_log:nnxxxx
+\cs_new_eq:NN \msg_trace:nnxxx \msg_log:nnxxx
+\cs_new_eq:NN \msg_trace:nnxx \msg_log:nnxx
+\cs_new_eq:NN \msg_trace:nnx \msg_log:nnx
+\cs_new_eq:NN \msg_trace:nn \msg_log:nn
+\cs_new_protected:Npn \msg_generic_new:nnn #1#2#3 { \deprecated }
+\cs_new_protected:Npn \msg_generic_new:nn #1#2 { \deprecated }
+\cs_new_protected:Npn \msg_generic_set:nnn #1#2#3 { \deprecated }
+\cs_new_protected:Npn \msg_generic_set:nn #1#2 { \deprecated }
+\cs_new_protected:Npn \msg_direct_interrupt:xxxxx #1#2#3#4#5 { \deprecated }
+\cs_new_protected:Npn \msg_direct_log:xx #1#2 { \deprecated }
+\cs_new_protected:Npn \msg_direct_term:xx #1#2 { \deprecated }
+%%
+%%
+%% End of file `l3msg.sty'.
diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3names.sty b/Master/texmf-dist/tex/latex/l3kernel/l3names.sty
new file mode 100644
index 00000000000..a504049d1ed
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/l3kernel/l3names.sty
@@ -0,0 +1,489 @@
+%%
+%% This is file `l3names.sty',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% l3names.dtx (with options: `package')
+%%
+%% EXPERIMENTAL CODE
+%%
+%% Do not distribute this file without also distributing the
+%% source files specified above.
+%%
+%% Do not distribute a modified version of this file.
+%%
+%% File: l3names.dtx Copyright (C) 1990-2011 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 "expl3 bundle" (The Work in LPPL)
+%% and all files in that bundle must be distributed together.
+%%
+%% The released version of this bundle is available from CTAN.
+%%
+%% -----------------------------------------------------------------------
+%%
+%% The development version of the bundle can be found at
+%%
+%% http://www.latex-project.org/svnroot/experimental/trunk/
+%%
+%% for those people who are interested.
+%%
+%%%%%%%%%%%
+%% NOTE: %%
+%%%%%%%%%%%
+%%
+%% Snapshots taken from the repository represent work in progress and may
+%% not work or may contain conflicting material! We therefore ask
+%% people _not_ to put them into distributions, archives, etc. without
+%% prior consultation with the LaTeX3 Project.
+%%
+%% -----------------------------------------------------------------------
+\RequirePackage{l3bootstrap}
+\GetIdInfo$Id: l3names.dtx 2478 2011-06-19 21:34:23Z joseph $
+ {L3 Experimental namespace for primitives}
+\ProvidesExplPackage
+ {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
+\let \tex_global:D \global
+\let \tex_let:D \let
+\begingroup
+ \long \def \name_primitive:NN #1#2
+ {
+ \tex_global:D \tex_let:D #2 #1
+ }
+ \name_primitive:NN \ \tex_space:D
+ \name_primitive:NN \/ \tex_italiccor:D
+ \name_primitive:NN \- \tex_hyphen:D
+ \name_primitive:NN \let \tex_let:D
+ \name_primitive:NN \def \tex_def:D
+ \name_primitive:NN \edef \tex_edef:D
+ \name_primitive:NN \gdef \tex_gdef:D
+ \name_primitive:NN \xdef \tex_xdef:D
+ \name_primitive:NN \chardef \tex_chardef:D
+ \name_primitive:NN \countdef \tex_countdef:D
+ \name_primitive:NN \dimendef \tex_dimendef:D
+ \name_primitive:NN \skipdef \tex_skipdef:D
+ \name_primitive:NN \muskipdef \tex_muskipdef:D
+ \name_primitive:NN \mathchardef \tex_mathchardef:D
+ \name_primitive:NN \toksdef \tex_toksdef:D
+ \name_primitive:NN \futurelet \tex_futurelet:D
+ \name_primitive:NN \advance \tex_advance:D
+ \name_primitive:NN \divide \tex_divide:D
+ \name_primitive:NN \multiply \tex_multiply:D
+ \name_primitive:NN \font \tex_font:D
+ \name_primitive:NN \fam \tex_fam:D
+ \name_primitive:NN \global \tex_global:D
+ \name_primitive:NN \long \tex_long:D
+ \name_primitive:NN \outer \tex_outer:D
+ \name_primitive:NN \setlanguage \tex_setlanguage:D
+ \name_primitive:NN \globaldefs \tex_globaldefs:D
+ \name_primitive:NN \afterassignment \tex_afterassignment:D
+ \name_primitive:NN \aftergroup \tex_aftergroup:D
+ \name_primitive:NN \expandafter \tex_expandafter:D
+ \name_primitive:NN \noexpand \tex_noexpand:D
+ \name_primitive:NN \begingroup \tex_begingroup:D
+ \name_primitive:NN \endgroup \tex_endgroup:D
+ \name_primitive:NN \halign \tex_halign:D
+ \name_primitive:NN \valign \tex_valign:D
+ \name_primitive:NN \cr \tex_cr:D
+ \name_primitive:NN \crcr \tex_crcr:D
+ \name_primitive:NN \noalign \tex_noalign:D
+ \name_primitive:NN \omit \tex_omit:D
+ \name_primitive:NN \span \tex_span:D
+ \name_primitive:NN \tabskip \tex_tabskip:D
+ \name_primitive:NN \everycr \tex_everycr:D
+ \name_primitive:NN \if \tex_if:D
+ \name_primitive:NN \ifcase \tex_ifcase:D
+ \name_primitive:NN \ifcat \tex_ifcat:D
+ \name_primitive:NN \ifnum \tex_ifnum:D
+ \name_primitive:NN \ifodd \tex_ifodd:D
+ \name_primitive:NN \ifdim \tex_ifdim:D
+ \name_primitive:NN \ifeof \tex_ifeof:D
+ \name_primitive:NN \ifhbox \tex_ifhbox:D
+ \name_primitive:NN \ifvbox \tex_ifvbox:D
+ \name_primitive:NN \ifvoid \tex_ifvoid:D
+ \name_primitive:NN \ifx \tex_ifx:D
+ \name_primitive:NN \iffalse \tex_iffalse:D
+ \name_primitive:NN \iftrue \tex_iftrue:D
+ \name_primitive:NN \ifhmode \tex_ifhmode:D
+ \name_primitive:NN \ifmmode \tex_ifmmode:D
+ \name_primitive:NN \ifvmode \tex_ifvmode:D
+ \name_primitive:NN \ifinner \tex_ifinner:D
+ \name_primitive:NN \else \tex_else:D
+ \name_primitive:NN \fi \tex_fi:D
+ \name_primitive:NN \or \tex_or:D
+ \name_primitive:NN \immediate \tex_immediate:D
+ \name_primitive:NN \closeout \tex_closeout:D
+ \name_primitive:NN \openin \tex_openin:D
+ \name_primitive:NN \openout \tex_openout:D
+ \name_primitive:NN \read \tex_read:D
+ \name_primitive:NN \write \tex_write:D
+ \name_primitive:NN \closein \tex_closein:D
+ \name_primitive:NN \newlinechar \tex_newlinechar:D
+ \name_primitive:NN \input \tex_input:D
+ \name_primitive:NN \endinput \tex_endinput:D
+ \name_primitive:NN \inputlineno \tex_inputlineno:D
+ \name_primitive:NN \errmessage \tex_errmessage:D
+ \name_primitive:NN \message \tex_message:D
+ \name_primitive:NN \show \tex_show:D
+ \name_primitive:NN \showthe \tex_showthe:D
+ \name_primitive:NN \showbox \tex_showbox:D
+ \name_primitive:NN \showlists \tex_showlists:D
+ \name_primitive:NN \errhelp \tex_errhelp:D
+ \name_primitive:NN \errorcontextlines \tex_errorcontextlines:D
+ \name_primitive:NN \tracingcommands \tex_tracingcommands:D
+ \name_primitive:NN \tracinglostchars \tex_tracinglostchars:D
+ \name_primitive:NN \tracingmacros \tex_tracingmacros:D
+ \name_primitive:NN \tracingonline \tex_tracingonline:D
+ \name_primitive:NN \tracingoutput \tex_tracingoutput:D
+ \name_primitive:NN \tracingpages \tex_tracingpages:D
+ \name_primitive:NN \tracingparagraphs \tex_tracingparagraphs:D
+ \name_primitive:NN \tracingrestores \tex_tracingrestores:D
+ \name_primitive:NN \tracingstats \tex_tracingstats:D
+ \name_primitive:NN \pausing \tex_pausing:D
+ \name_primitive:NN \showboxbreadth \tex_showboxbreadth:D
+ \name_primitive:NN \showboxdepth \tex_showboxdepth:D
+ \name_primitive:NN \batchmode \tex_batchmode:D
+ \name_primitive:NN \errorstopmode \tex_errorstopmode:D
+ \name_primitive:NN \nonstopmode \tex_nonstopmode:D
+ \name_primitive:NN \scrollmode \tex_scrollmode:D
+ \name_primitive:NN \end \tex_end:D
+ \name_primitive:NN \csname \tex_csname:D
+ \name_primitive:NN \endcsname \tex_endcsname:D
+ \name_primitive:NN \ignorespaces \tex_ignorespaces:D
+ \name_primitive:NN \relax \tex_relax:D
+ \name_primitive:NN \the \tex_the:D
+ \name_primitive:NN \mag \tex_mag:D
+ \name_primitive:NN \language \tex_language:D
+ \name_primitive:NN \mark \tex_mark:D
+ \name_primitive:NN \topmark \tex_topmark:D
+ \name_primitive:NN \firstmark \tex_firstmark:D
+ \name_primitive:NN \botmark \tex_botmark:D
+ \name_primitive:NN \splitfirstmark \tex_splitfirstmark:D
+ \name_primitive:NN \splitbotmark \tex_splitbotmark:D
+ \name_primitive:NN \fontname \tex_fontname:D
+ \name_primitive:NN \escapechar \tex_escapechar:D
+ \name_primitive:NN \endlinechar \tex_endlinechar:D
+ \name_primitive:NN \mathchoice \tex_mathchoice:D
+ \name_primitive:NN \delimiter \tex_delimiter:D
+ \name_primitive:NN \mathaccent \tex_mathaccent:D
+ \name_primitive:NN \mathchar \tex_mathchar:D
+ \name_primitive:NN \mskip \tex_mskip:D
+ \name_primitive:NN \radical \tex_radical:D
+ \name_primitive:NN \vcenter \tex_vcenter:D
+ \name_primitive:NN \mkern \tex_mkern:D
+ \name_primitive:NN \above \tex_above:D
+ \name_primitive:NN \abovewithdelims \tex_abovewithdelims:D
+ \name_primitive:NN \atop \tex_atop:D
+ \name_primitive:NN \atopwithdelims \tex_atopwithdelims:D
+ \name_primitive:NN \over \tex_over:D
+ \name_primitive:NN \overwithdelims \tex_overwithdelims:D
+ \name_primitive:NN \displaystyle \tex_displaystyle:D
+ \name_primitive:NN \textstyle \tex_textstyle:D
+ \name_primitive:NN \scriptstyle \tex_scriptstyle:D
+ \name_primitive:NN \scriptscriptstyle \tex_scriptscriptstyle:D
+ \name_primitive:NN \nonscript \tex_nonscript:D
+ \name_primitive:NN \eqno \tex_eqno:D
+ \name_primitive:NN \leqno \tex_leqno:D
+ \name_primitive:NN \abovedisplayshortskip \tex_abovedisplayshortskip:D
+ \name_primitive:NN \abovedisplayskip \tex_abovedisplayskip:D
+ \name_primitive:NN \belowdisplayshortskip \tex_belowdisplayshortskip:D
+ \name_primitive:NN \belowdisplayskip \tex_belowdisplayskip:D
+ \name_primitive:NN \displaywidowpenalty \tex_displaywidowpenalty:D
+ \name_primitive:NN \displayindent \tex_displayindent:D
+ \name_primitive:NN \displaywidth \tex_displaywidth:D
+ \name_primitive:NN \everydisplay \tex_everydisplay:D
+ \name_primitive:NN \predisplaysize \tex_predisplaysize:D
+ \name_primitive:NN \predisplaypenalty \tex_predisplaypenalty:D
+ \name_primitive:NN \postdisplaypenalty \tex_postdisplaypenalty:D
+ \name_primitive:NN \mathbin \tex_mathbin:D
+ \name_primitive:NN \mathclose \tex_mathclose:D
+ \name_primitive:NN \mathinner \tex_mathinner:D
+ \name_primitive:NN \mathop \tex_mathop:D
+ \name_primitive:NN \displaylimits \tex_displaylimits:D
+ \name_primitive:NN \limits \tex_limits:D
+ \name_primitive:NN \nolimits \tex_nolimits:D
+ \name_primitive:NN \mathopen \tex_mathopen:D
+ \name_primitive:NN \mathord \tex_mathord:D
+ \name_primitive:NN \mathpunct \tex_mathpunct:D
+ \name_primitive:NN \mathrel \tex_mathrel:D
+ \name_primitive:NN \overline \tex_overline:D
+ \name_primitive:NN \underline \tex_underline:D
+ \name_primitive:NN \left \tex_left:D
+ \name_primitive:NN \right \tex_right:D
+ \name_primitive:NN \binoppenalty \tex_binoppenalty:D
+ \name_primitive:NN \relpenalty \tex_relpenalty:D
+ \name_primitive:NN \delimitershortfall \tex_delimitershortfall:D
+ \name_primitive:NN \delimiterfactor \tex_delimiterfactor:D
+ \name_primitive:NN \nulldelimiterspace \tex_nulldelimiterspace:D
+ \name_primitive:NN \everymath \tex_everymath:D
+ \name_primitive:NN \mathsurround \tex_mathsurround:D
+ \name_primitive:NN \medmuskip \tex_medmuskip:D
+ \name_primitive:NN \thinmuskip \tex_thinmuskip:D
+ \name_primitive:NN \thickmuskip \tex_thickmuskip:D
+ \name_primitive:NN \scriptspace \tex_scriptspace:D
+ \name_primitive:NN \noboundary \tex_noboundary:D
+ \name_primitive:NN \accent \tex_accent:D
+ \name_primitive:NN \char \tex_char:D
+ \name_primitive:NN \discretionary \tex_discretionary:D
+ \name_primitive:NN \hfil \tex_hfil:D
+ \name_primitive:NN \hfilneg \tex_hfilneg:D
+ \name_primitive:NN \hfill \tex_hfill:D
+ \name_primitive:NN \hskip \tex_hskip:D
+ \name_primitive:NN \hss \tex_hss:D
+ \name_primitive:NN \vfil \tex_vfil:D
+ \name_primitive:NN \vfilneg \tex_vfilneg:D
+ \name_primitive:NN \vfill \tex_vfill:D
+ \name_primitive:NN \vskip \tex_vskip:D
+ \name_primitive:NN \vss \tex_vss:D
+ \name_primitive:NN \unskip \tex_unskip:D
+ \name_primitive:NN \kern \tex_kern:D
+ \name_primitive:NN \unkern \tex_unkern:D
+ \name_primitive:NN \hrule \tex_hrule:D
+ \name_primitive:NN \vrule \tex_vrule:D
+ \name_primitive:NN \leaders \tex_leaders:D
+ \name_primitive:NN \cleaders \tex_cleaders:D
+ \name_primitive:NN \xleaders \tex_xleaders:D
+ \name_primitive:NN \lastkern \tex_lastkern:D
+ \name_primitive:NN \lastskip \tex_lastskip:D
+ \name_primitive:NN \indent \tex_indent:D
+ \name_primitive:NN \par \tex_par:D
+ \name_primitive:NN \noindent \tex_noindent:D
+ \name_primitive:NN \vadjust \tex_vadjust:D
+ \name_primitive:NN \baselineskip \tex_baselineskip:D
+ \name_primitive:NN \lineskip \tex_lineskip:D
+ \name_primitive:NN \lineskiplimit \tex_lineskiplimit:D
+ \name_primitive:NN \clubpenalty \tex_clubpenalty:D
+ \name_primitive:NN \widowpenalty \tex_widowpenalty:D
+ \name_primitive:NN \exhyphenpenalty \tex_exhyphenpenalty:D
+ \name_primitive:NN \hyphenpenalty \tex_hyphenpenalty:D
+ \name_primitive:NN \linepenalty \tex_linepenalty:D
+ \name_primitive:NN \doublehyphendemerits \tex_doublehyphendemerits:D
+ \name_primitive:NN \finalhyphendemerits \tex_finalhyphendemerits:D
+ \name_primitive:NN \adjdemerits \tex_adjdemerits:D
+ \name_primitive:NN \hangafter \tex_hangafter:D
+ \name_primitive:NN \hangindent \tex_hangindent:D
+ \name_primitive:NN \parshape \tex_parshape:D
+ \name_primitive:NN \hsize \tex_hsize:D
+ \name_primitive:NN \lefthyphenmin \tex_lefthyphenmin:D
+ \name_primitive:NN \righthyphenmin \tex_righthyphenmin:D
+ \name_primitive:NN \leftskip \tex_leftskip:D
+ \name_primitive:NN \rightskip \tex_rightskip:D
+ \name_primitive:NN \looseness \tex_looseness:D
+ \name_primitive:NN \parskip \tex_parskip:D
+ \name_primitive:NN \parindent \tex_parindent:D
+ \name_primitive:NN \uchyph \tex_uchyph:D
+ \name_primitive:NN \emergencystretch \tex_emergencystretch:D
+ \name_primitive:NN \pretolerance \tex_pretolerance:D
+ \name_primitive:NN \tolerance \tex_tolerance:D
+ \name_primitive:NN \spaceskip \tex_spaceskip:D
+ \name_primitive:NN \xspaceskip \tex_xspaceskip:D
+ \name_primitive:NN \parfillskip \tex_parfillskip:D
+ \name_primitive:NN \everypar \tex_everypar:D
+ \name_primitive:NN \prevgraf \tex_prevgraf:D
+ \name_primitive:NN \spacefactor \tex_spacefactor:D
+ \name_primitive:NN \shipout \tex_shipout:D
+ \name_primitive:NN \vsize \tex_vsize:D
+ \name_primitive:NN \interlinepenalty \tex_interlinepenalty:D
+ \name_primitive:NN \brokenpenalty \tex_brokenpenalty:D
+ \name_primitive:NN \topskip \tex_topskip:D
+ \name_primitive:NN \maxdeadcycles \tex_maxdeadcycles:D
+ \name_primitive:NN \maxdepth \tex_maxdepth:D
+ \name_primitive:NN \output \tex_output:D
+ \name_primitive:NN \deadcycles \tex_deadcycles:D
+ \name_primitive:NN \pagedepth \tex_pagedepth:D
+ \name_primitive:NN \pagestretch \tex_pagestretch:D
+ \name_primitive:NN \pagefilstretch \tex_pagefilstretch:D
+ \name_primitive:NN \pagefillstretch \tex_pagefillstretch:D
+ \name_primitive:NN \pagefilllstretch \tex_pagefilllstretch:D
+ \name_primitive:NN \pageshrink \tex_pageshrink:D
+ \name_primitive:NN \pagegoal \tex_pagegoal:D
+ \name_primitive:NN \pagetotal \tex_pagetotal:D
+ \name_primitive:NN \outputpenalty \tex_outputpenalty:D
+ \name_primitive:NN \hoffset \tex_hoffset:D
+ \name_primitive:NN \voffset \tex_voffset:D
+ \name_primitive:NN \insert \tex_insert:D
+ \name_primitive:NN \holdinginserts \tex_holdinginserts:D
+ \name_primitive:NN \floatingpenalty \tex_floatingpenalty:D
+ \name_primitive:NN \insertpenalties \tex_insertpenalties:D
+ \name_primitive:NN \lower \tex_lower:D
+ \name_primitive:NN \moveleft \tex_moveleft:D
+ \name_primitive:NN \moveright \tex_moveright:D
+ \name_primitive:NN \raise \tex_raise:D
+ \name_primitive:NN \copy \tex_copy:D
+ \name_primitive:NN \lastbox \tex_lastbox:D
+ \name_primitive:NN \vsplit \tex_vsplit:D
+ \name_primitive:NN \unhbox \tex_unhbox:D
+ \name_primitive:NN \unhcopy \tex_unhcopy:D
+ \name_primitive:NN \unvbox \tex_unvbox:D
+ \name_primitive:NN \unvcopy \tex_unvcopy:D
+ \name_primitive:NN \setbox \tex_setbox:D
+ \name_primitive:NN \hbox \tex_hbox:D
+ \name_primitive:NN \vbox \tex_vbox:D
+ \name_primitive:NN \vtop \tex_vtop:D
+ \name_primitive:NN \prevdepth \tex_prevdepth:D
+ \name_primitive:NN \badness \tex_badness:D
+ \name_primitive:NN \hbadness \tex_hbadness:D
+ \name_primitive:NN \vbadness \tex_vbadness:D
+ \name_primitive:NN \hfuzz \tex_hfuzz:D
+ \name_primitive:NN \vfuzz \tex_vfuzz:D
+ \name_primitive:NN \overfullrule \tex_overfullrule:D
+ \name_primitive:NN \boxmaxdepth \tex_boxmaxdepth:D
+ \name_primitive:NN \splitmaxdepth \tex_splitmaxdepth:D
+ \name_primitive:NN \splittopskip \tex_splittopskip:D
+ \name_primitive:NN \everyhbox \tex_everyhbox:D
+ \name_primitive:NN \everyvbox \tex_everyvbox:D
+ \name_primitive:NN \nullfont \tex_nullfont:D
+ \name_primitive:NN \textfont \tex_textfont:D
+ \name_primitive:NN \scriptfont \tex_scriptfont:D
+ \name_primitive:NN \scriptscriptfont \tex_scriptscriptfont:D
+ \name_primitive:NN \fontdimen \tex_fontdimen:D
+ \name_primitive:NN \hyphenchar \tex_hyphenchar:D
+ \name_primitive:NN \skewchar \tex_skewchar:D
+ \name_primitive:NN \defaulthyphenchar \tex_defaulthyphenchar:D
+ \name_primitive:NN \defaultskewchar \tex_defaultskewchar:D
+ \name_primitive:NN \number \tex_number:D
+ \name_primitive:NN \romannumeral \tex_romannumeral:D
+ \name_primitive:NN \string \tex_string:D
+ \name_primitive:NN \lowercase \tex_lowercase:D
+ \name_primitive:NN \uppercase \tex_uppercase:D
+ \name_primitive:NN \meaning \tex_meaning:D
+ \name_primitive:NN \penalty \tex_penalty:D
+ \name_primitive:NN \unpenalty \tex_unpenalty:D
+ \name_primitive:NN \lastpenalty \tex_lastpenalty:D
+ \name_primitive:NN \special \tex_special:D
+ \name_primitive:NN \dump \tex_dump:D
+ \name_primitive:NN \patterns \tex_patterns:D
+ \name_primitive:NN \hyphenation \tex_hyphenation:D
+ \name_primitive:NN \time \tex_time:D
+ \name_primitive:NN \day \tex_day:D
+ \name_primitive:NN \month \tex_month:D
+ \name_primitive:NN \year \tex_year:D
+ \name_primitive:NN \jobname \tex_jobname:D
+ \name_primitive:NN \everyjob \tex_everyjob:D
+ \name_primitive:NN \count \tex_count:D
+ \name_primitive:NN \dimen \tex_dimen:D
+ \name_primitive:NN \skip \tex_skip:D
+ \name_primitive:NN \toks \tex_toks:D
+ \name_primitive:NN \muskip \tex_muskip:D
+ \name_primitive:NN \box \tex_box:D
+ \name_primitive:NN \wd \tex_wd:D
+ \name_primitive:NN \ht \tex_ht:D
+ \name_primitive:NN \dp \tex_dp:D
+ \name_primitive:NN \catcode \tex_catcode:D
+ \name_primitive:NN \delcode \tex_delcode:D
+ \name_primitive:NN \sfcode \tex_sfcode:D
+ \name_primitive:NN \lccode \tex_lccode:D
+ \name_primitive:NN \uccode \tex_uccode:D
+ \name_primitive:NN \mathcode \tex_mathcode:D
+ \name_primitive:NN \ifdefined \etex_ifdefined:D
+ \name_primitive:NN \ifcsname \etex_ifcsname:D
+ \name_primitive:NN \unless \etex_unless:D
+ \name_primitive:NN \eTeXversion \etex_eTeXversion:D
+ \name_primitive:NN \eTeXrevision \etex_eTeXrevision:D
+ \name_primitive:NN \marks \etex_marks:D
+ \name_primitive:NN \topmarks \etex_topmarks:D
+ \name_primitive:NN \firstmarks \etex_firstmarks:D
+ \name_primitive:NN \botmarks \etex_botmarks:D
+ \name_primitive:NN \splitfirstmarks \etex_splitfirstmarks:D
+ \name_primitive:NN \splitbotmarks \etex_splitbotmarks:D
+ \name_primitive:NN \unexpanded \etex_unexpanded:D
+ \name_primitive:NN \detokenize \etex_detokenize:D
+ \name_primitive:NN \scantokens \etex_scantokens:D
+ \name_primitive:NN \showtokens \etex_showtokens:D
+ \name_primitive:NN \readline \etex_readline:D
+ \name_primitive:NN \tracingassigns \etex_tracingassigns:D
+ \name_primitive:NN \tracingscantokens \etex_tracingscantokens:D
+ \name_primitive:NN \tracingnesting \etex_tracingnesting:D
+ \name_primitive:NN \tracingifs \etex_tracingifs:D
+ \name_primitive:NN \currentiflevel \etex_currentiflevel:D
+ \name_primitive:NN \currentifbranch \etex_currentifbranch:D
+ \name_primitive:NN \currentiftype \etex_currentiftype:D
+ \name_primitive:NN \tracinggroups \etex_tracinggroups:D
+ \name_primitive:NN \currentgrouplevel \etex_currentgrouplevel:D
+ \name_primitive:NN \currentgrouptype \etex_currentgrouptype:D
+ \name_primitive:NN \showgroups \etex_showgroups:D
+ \name_primitive:NN \showifs \etex_showifs:D
+ \name_primitive:NN \interactionmode \etex_interactionmode:D
+ \name_primitive:NN \lastnodetype \etex_lastnodetype:D
+ \name_primitive:NN \iffontchar \etex_iffontchar:D
+ \name_primitive:NN \fontcharht \etex_fontcharht:D
+ \name_primitive:NN \fontchardp \etex_fontchardp:D
+ \name_primitive:NN \fontcharwd \etex_fontcharwd:D
+ \name_primitive:NN \fontcharic \etex_fontcharic:D
+ \name_primitive:NN \parshapeindent \etex_parshapeindent:D
+ \name_primitive:NN \parshapelength \etex_parshapelength:D
+ \name_primitive:NN \parshapedimen \etex_parshapedimen:D
+ \name_primitive:NN \numexpr \etex_numexpr:D
+ \name_primitive:NN \dimexpr \etex_dimexpr:D
+ \name_primitive:NN \glueexpr \etex_glueexpr:D
+ \name_primitive:NN \muexpr \etex_muexpr:D
+ \name_primitive:NN \gluestretch \etex_gluestretch:D
+ \name_primitive:NN \glueshrink \etex_glueshrink:D
+ \name_primitive:NN \gluestretchorder \etex_gluestretchorder:D
+ \name_primitive:NN \glueshrinkorder \etex_glueshrinkorder:D
+ \name_primitive:NN \gluetomu \etex_gluetomu:D
+ \name_primitive:NN \mutoglue \etex_mutoglue:D
+ \name_primitive:NN \lastlinefit \etex_lastlinefit:D
+ \name_primitive:NN \interlinepenalties \etex_interlinepenalties:D
+ \name_primitive:NN \clubpenalties \etex_clubpenalties:D
+ \name_primitive:NN \widowpenalties \etex_widowpenalties:D
+ \name_primitive:NN \displaywidowpenalties \etex_displaywidowpenalties:D
+ \name_primitive:NN \middle \etex_middle:D
+ \name_primitive:NN \savinghyphcodes \etex_savinghyphcodes:D
+ \name_primitive:NN \savingvdiscards \etex_savingvdiscards:D
+ \name_primitive:NN \pagediscards \etex_pagediscards:D
+ \name_primitive:NN \splitdiscards \etex_splitdiscards:D
+ \name_primitive:NN \TeXXETstate \etex_TeXXETstate:D
+ \name_primitive:NN \beginL \etex_beginL:D
+ \name_primitive:NN \endL \etex_endL:D
+ \name_primitive:NN \beginR \etex_beginR:D
+ \name_primitive:NN \endR \etex_endR:D
+ \name_primitive:NN \predisplaydirection \etex_predisplaydirection:D
+ \name_primitive:NN \everyeof \etex_everyeof:D
+ \name_primitive:NN \protected \etex_protected:D
+ \name_primitive:NN \pdfcreationdate \pdftex_pdfcreationdate:D
+ \name_primitive:NN \pdfcolorstack \pdftex_pdfcolorstack:D
+ \name_primitive:NN \pdfcompresslevel \pdftex_pdfcompresslevel:D
+ \name_primitive:NN \pdfdecimaldigits \pdftex_pdfdecimaldigits:D
+ \name_primitive:NN \pdfhorigin \pdftex_pdfhorigin:D
+ \name_primitive:NN \pdfinfo \pdftex_pdfinfo:D
+ \name_primitive:NN \pdfliteral \pdftex_pdfliteral:D
+ \name_primitive:NN \pdfminorversion \pdftex_pdfminorversion:D
+ \name_primitive:NN \pdfobjcompresslevel \pdftex_pdfobjcompresslevel:D
+ \name_primitive:NN \pdfoutput \pdftex_pdfoutput:D
+ \name_primitive:NN \pdfrestore \pdftex_pdfrestore:D
+ \name_primitive:NN \pdfsave \pdftex_pdfsave:D
+ \name_primitive:NN \pdfsetmatrix \pdftex_pdfsetmatrix:D
+ \name_primitive:NN \pdfpkresolution \pdftex_pdfpkresolution:D
+ \name_primitive:NN \pdftexrevision \pdftex_pdftextrevision:D
+ \name_primitive:NN \pdfvorigin \pdftex_pdfvorigin:D
+ \name_primitive:NN \pdfstrcmp \pdftex_strcmp:D
+ \name_primitive:NN \XeTeXversion \xetex_XeTeXversion:D
+ \name_primitive:NN \catcodetable \luatex_catcodetable:D
+ \name_primitive:NN \directlua \luatex_directlua:D
+ \name_primitive:NN \initcatcodetable \luatex_initcatcodetable:D
+ \name_primitive:NN \latelua \luatex_latelua:D
+ \name_primitive:NN \luatexversion \luatex_luatexversion:D
+ \name_primitive:NN \savecatcodetable \luatex_savecatcodetable:D
+\tex_endgroup:D
+\tex_let:D \tex_end:D \@@end
+\tex_let:D \tex_everydisplay:D \frozen@everydisplay
+\tex_let:D \tex_everymath:D \frozen@everymath
+\tex_let:D \tex_hyphen:D \@@hyph
+\tex_let:D \tex_input:D \@@input
+\tex_let:D \tex_italic_correction:D \@@italiccorr
+\tex_let:D \tex_underline:D \@@underline
+\tex_let:D \luatex_catcodetable:D \luatexcatcodetable
+\tex_let:D \luatex_initcatcodetable:D \luatexinitcatcodetable
+\tex_let:D \luatex_latelua:D \luatexlatelua
+\tex_let:D \luatex_savecatcodetable:D \luatexsavecatcodetable
+%%
+%%
+%% End of file `l3names.sty'.
diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3prg.sty b/Master/texmf-dist/tex/latex/l3kernel/l3prg.sty
new file mode 100644
index 00000000000..4a20c040547
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/l3kernel/l3prg.sty
@@ -0,0 +1,563 @@
+%%
+%% This is file `l3prg.sty',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% l3prg.dtx (with options: `package')
+%%
+%% EXPERIMENTAL CODE
+%%
+%% Do not distribute this file without also distributing the
+%% source files specified above.
+%%
+%% Do not distribute a modified version of this file.
+%%
+%% File: l3prg.dtx Copyright (C) 2005-2011 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 "expl3 bundle" (The Work in LPPL)
+%% and all files in that bundle must be distributed together.
+%%
+%% The released version of this bundle is available from CTAN.
+%%
+%% -----------------------------------------------------------------------
+%%
+%% The development version of the bundle can be found at
+%%
+%% http://www.latex-project.org/svnroot/experimental/trunk/
+%%
+%% for those people who are interested.
+%%
+%%%%%%%%%%%
+%% NOTE: %%
+%%%%%%%%%%%
+%%
+%% Snapshots taken from the repository represent work in progress and may
+%% not work or may contain conflicting material! We therefore ask
+%% people _not_ to put them into distributions, archives, etc. without
+%% prior consultation with the LaTeX3 Project.
+%%
+%% -----------------------------------------------------------------------
+\RequirePackage{l3names}
+\GetIdInfo$Id: l3prg.dtx 2495 2011-07-06 16:57:08Z bruno $
+ {L3 Experimental control structures}
+%%
+\ProvidesExplPackage
+ {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
+\package_check_loaded_expl:
+\cs_new_protected_nopar:Npn \bool_new:N #1 { \cs_new_eq:NN #1 \c_false_bool }
+\cs_generate_variant:Nn \bool_new:N { c }
+\cs_new_protected_nopar:Npn \bool_set_true:N #1
+ { \cs_set_eq:NN #1 \c_true_bool }
+\cs_new_protected_nopar:Npn \bool_set_false:N #1
+ { \cs_set_eq:NN #1 \c_false_bool }
+\cs_new_protected_nopar:Npn \bool_gset_true:N #1
+ { \cs_gset_eq:NN #1 \c_true_bool }
+\cs_new_protected_nopar:Npn \bool_gset_false:N #1
+ { \cs_gset_eq:NN #1 \c_false_bool }
+\cs_generate_variant:Nn \bool_set_true:N { c }
+\cs_generate_variant:Nn \bool_set_false:N { c }
+\cs_generate_variant:Nn \bool_gset_true:N { c }
+\cs_generate_variant:Nn \bool_gset_false:N { c }
+\cs_new_eq:NN \bool_set_eq:NN \cs_set_eq:NN
+\cs_new_eq:NN \bool_set_eq:Nc \cs_set_eq:Nc
+\cs_new_eq:NN \bool_set_eq:cN \cs_set_eq:cN
+\cs_new_eq:NN \bool_set_eq:cc \cs_set_eq:cc
+\cs_new_eq:NN \bool_gset_eq:NN \cs_gset_eq:NN
+\cs_new_eq:NN \bool_gset_eq:Nc \cs_gset_eq:Nc
+\cs_new_eq:NN \bool_gset_eq:cN \cs_gset_eq:cN
+\cs_new_eq:NN \bool_gset_eq:cc \cs_gset_eq:cc
+\cs_new:Npn \bool_set:Nn #1#2
+ { \tex_chardef:D #1 = \bool_if_p:n {#2} }
+\cs_new:Npn \bool_gset:Nn #1#2
+ { \tex_global:D \tex_chardef:D #1 = \bool_if_p:n {#2} }
+\cs_generate_variant:Nn \bool_set:Nn { c }
+\cs_generate_variant:Nn \bool_gset:Nn { c }
+\prg_new_conditional:Npnn \bool_if:N #1 { p , T , F , TF }
+ {
+ \if_bool:N #1
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\cs_generate_variant:Nn \bool_if_p:N { c }
+\cs_generate_variant:Nn \bool_if:NT { c }
+\cs_generate_variant:Nn \bool_if:NF { c }
+\cs_generate_variant:Nn \bool_if:NTF { c }
+\bool_new:N \l_tmpa_bool
+\bool_new:N \g_tmpa_bool
+\prg_new_conditional:Npnn \bool_if:n #1 { T , F , TF }
+ {
+ \if_predicate:w \bool_if_p:n {#1}
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\cs_new:Npn \bool_if_p:n #1
+ {
+ \group_align_safe_begin:
+ \bool_get_next:N ( #1 ) S
+ }
+\cs_new:Npn \bool_get_next:N #1
+ {
+ \use:c
+ {
+ bool_
+ \if_meaning:w !#1 ! \else: \if_meaning:w (#1 ( \else: p \fi: \fi:
+ :w
+ }
+ #1
+ }
+\cs_new:Npn \bool_get_not_next:N #1
+ {
+ \use:c
+ {
+ bool_not_
+ \if_meaning:w !#1 ! \else: \if_meaning:w (#1 ( \else: p \fi: \fi:
+ :w
+ }
+ #1
+ }
+\cs_new:Npn \bool_get_next:NN #1#2 { \bool_get_next:N #2 }
+\cs_new:Npn \bool_get_not_next:NN #1#2 { \bool_get_not_next:N #2 }
+\cs_new:cpn { bool_!:w } #1#2
+ {
+ \if_meaning:w ( #2
+ \exp_after:wN \bool_Not:w
+ \else:
+ \if_meaning:w ! #2
+ \exp_after:wN \exp_after:wN \exp_after:wN \bool_get_next:NN
+ \else:
+ \exp_after:wN \exp_after:wN \exp_after:wN \bool_Not:N
+ \fi:
+ \fi:
+ #2
+ }
+\cs_new:cpn { bool_not_!:w } #1#2
+ {
+ \if_meaning:w ( #2
+ \exp_after:wN \bool_not_Not:w
+ \else:
+ \if_meaning:w ! #2
+ \exp_after:wN \exp_after:wN \exp_after:wN \bool_get_not_next:NN
+ \else:
+ \exp_after:wN \exp_after:wN \exp_after:wN \bool_not_Not:N
+ \fi:
+ \fi:
+ #2
+ }
+\cs_new:Npn \bool_Not:w { \exp_after:wN \int_value:w \bool_get_not_next:N }
+\cs_new:Npn \bool_not_Not:w { \exp_after:wN \int_value:w \bool_get_next:N }
+\cs_new:Npn \bool_Not:N #1
+ {
+ \exp_after:wN \bool_p:w
+ \if_meaning:w #1 \c_true_bool
+ \c_false_bool
+ \else:
+ \c_true_bool
+ \fi:
+ }
+\cs_new:Npn \bool_not_Not:N #1
+ {
+ \exp_after:wN \bool_p:w
+ \if_meaning:w #1 \c_true_bool
+ \c_true_bool
+ \else:
+ \c_false_bool
+ \fi:
+ }
+\cs_new:cpn { bool_(:w } #1
+ { \exp_after:wN \bool_cleanup:N \int_value:w \bool_get_next:N }
+\cs_new:cpn { bool_not_(:w } #1
+ { \exp_after:wN \bool_not_cleanup:N \int_value:w \bool_get_next:N }
+\cs_new:cpn { bool_p:w } { \exp_after:wN \bool_cleanup:N \int_value:w }
+\cs_new:cpn { bool_not_p:w } {\exp_after:wN \bool_not_cleanup:N \int_value:w }
+\cs_new:Npn \bool_cleanup:N #1
+ {
+ \exp_after:wN \bool_choose:NN \exp_after:wN #1
+ \int_to_roman:w - `\q
+ }
+\cs_new:Npn \bool_not_cleanup:N #1
+ {
+ \exp_after:wN \bool_not_choose:NN \exp_after:wN #1
+ \int_to_roman:w - `\q
+ }
+\cs_new_nopar:Npn \bool_choose:NN #1#2 { \use:c { bool_ #2 _ #1 :w } }
+\cs_new_nopar:Npn \bool_not_choose:NN #1#2 { \use:c { bool_not_ #2 _ #1 :w } }
+\cs_new_nopar:cpn { bool_&_1:w } & { \bool_get_next:N }
+\cs_new_nopar:cpn { bool_|_0:w } | { \bool_get_next:N }
+\cs_new_nopar:cpn { bool_not_&_0:w } & { \bool_get_next:N }
+\cs_new_nopar:cpn { bool_not_|_1:w } | { \bool_get_next:N }
+\cs_new_nopar:cpn { bool_)_0:w } { \c_false_bool }
+\cs_new_nopar:cpn { bool_)_1:w } { \c_true_bool }
+\cs_new_nopar:cpn { bool_not_)_0:w } { \c_true_bool }
+\cs_new_nopar:cpn { bool_not_)_1:w } { \c_false_bool }
+\cs_new_nopar:cpn { bool_S_0:w } { \group_align_safe_end: \c_false_bool }
+\cs_new_nopar:cpn { bool_S_1:w } { \group_align_safe_end: \c_true_bool }
+\cs_new_nopar:cpn { bool_&_0:w } & { \bool_eval_skip_to_end:Nw \c_false_bool }
+\cs_new_nopar:cpn { bool_|_1:w } | { \bool_eval_skip_to_end:Nw \c_true_bool }
+\cs_new_nopar:cpn { bool_not_&_1:w } &
+ { \bool_eval_skip_to_end:Nw \c_false_bool }
+\cs_new_nopar:cpn { bool_not_|_0:w } |
+ { \bool_eval_skip_to_end:Nw \c_true_bool }
+%% (
+\cs_new:Npn \bool_eval_skip_to_end:Nw #1#2 )
+ {
+ \bool_eval_skip_to_end_aux:Nw #1#2 ( % )
+ \q_no_value \q_stop
+ {#2}
+ }
+\cs_new:Npn \bool_eval_skip_to_end_aux:Nw #1#2 ( #3#4 \q_stop #5 % )
+ {
+ \quark_if_no_value:NTF #3
+ {#1}
+ { \bool_eval_skip_to_end_aux_ii:Nw #1 #5 }
+ }
+\cs_new:Npn \bool_eval_skip_to_end_aux_ii:Nw #1#2 ( #3 )
+ { % (
+ \bool_eval_skip_to_end:Nw #1#3 )
+ }
+\cs_new:Npn \bool_not_p:n #1 { \bool_if_p:n { ! ( #1 ) } }
+\cs_new:Npn \bool_xor_p:nn #1#2
+ {
+ \int_compare:nNnTF { \bool_if_p:n {#1} } = { \bool_if_p:n {#2} }
+ \c_false_bool
+ \c_true_bool
+ }
+\cs_new:Npn \bool_while_do:Nn #1#2
+ { \bool_if:NT #1 { #2 \bool_while_do:Nn #1 {#2} } }
+\cs_new:Npn \bool_until_do:Nn #1#2
+ { \bool_if:NF #1 { #2 \bool_until_do:Nn #1 {#2} } }
+\cs_generate_variant:Nn \bool_while_do:Nn { c }
+\cs_generate_variant:Nn \bool_until_do:Nn { c }
+\cs_new:Npn \bool_do_while:Nn #1#2
+ { #2 \bool_if:NT #1 { \bool_do_while:Nn #1 {#2} } }
+\cs_new:Npn \bool_do_until:Nn #1#2
+ { #2 \bool_if:NF #1 { \bool_do_until:Nn #1 {#2} } }
+\cs_generate_variant:Nn \bool_do_while:Nn { c }
+\cs_generate_variant:Nn \bool_do_until:Nn { c }
+\cs_new:Npn \bool_while_do:nn #1#2
+ {
+ \bool_if:nT {#1}
+ {
+ #2
+ \bool_while_do:nn {#1} {#2}
+ }
+ }
+\cs_new:Npn \bool_do_while:nn #1#2
+ {
+ #2
+ \bool_if:nT {#1} { \bool_do_while:nn {#1} {#2} }
+ }
+\cs_new:Npn \bool_until_do:nn #1#2
+ {
+ \bool_if:nF {#1}
+ {
+ #2
+ \bool_until_do:nn {#1} {#2}
+ }
+ }
+\cs_new:Npn \bool_do_until:nn #1#2
+ {
+ #2
+ \bool_if:nF {#1} { \bool_do_until:nn {#1} {#2} }
+ }
+\cs_new_eq:NN \prg_case_end:nw \use_i_delimit_by_q_recursion_stop:nw
+\cs_new:Npn \prg_case_int:nnn #1
+ { \exp_args:Nf \prg_case_int_aux:nnn { \int_eval:n {#1} } }
+\cs_new:Npn \prg_case_int_aux:nnn #1 #2 #3
+ { \prg_case_int_aux:nw {#1} #2 {#1} {#3} \q_recursion_stop }
+\cs_new:Npn \prg_case_int_aux:nw #1#2#3
+ {
+ \int_compare:nNnTF {#1} = {#2}
+ { \prg_case_end:nw {#3} }
+ { \prg_case_int_aux:nw {#1} }
+ }
+\cs_new:Npn \prg_case_dim:nnn #1
+ { \exp_args:Nf \prg_case_dim_aux:nnn { \dim_eval:n {#1} } }
+\cs_new:Npn \prg_case_dim_aux:nnn #1 #2 #3
+ { \prg_case_dim_aux:nw {#1} #2 {#1} {#3} \q_recursion_stop }
+\cs_new:Npn \prg_case_dim_aux:nw #1#2#3
+ {
+ \dim_compare:nNnTF {#1} = {#2}
+ { \prg_case_end:nw {#3} }
+ { \prg_case_dim_aux:nw {#1} }
+ }
+\cs_new:Npn \prg_case_str:nnn #1#2#3
+ { \prg_case_str_aux:nw {#1} #2 {#1} {#3} \q_recursion_stop }
+\cs_new:Npn \prg_case_str_aux:nw #1#2#3
+ {
+ \str_if_eq:nnTF {#1} {#2}
+ { \prg_case_end:nw {#3} }
+ { \prg_case_str_aux:nw {#1} }
+ }
+\cs_generate_variant:Nn \prg_case_str:nnn { o }
+\cs_new:Npn \prg_case_str:xxn #1#2#3
+ { \prg_case_str_x_aux:nw {#1} #2 {#1} {#3} \q_recursion_stop }
+\cs_new:Npn \prg_case_str_x_aux:nw #1#2#3
+ {
+ \str_if_eq:xxTF {#1} {#2}
+ { \prg_case_end:nw {#3} }
+ { \prg_case_str_aux:nw {#1} }
+ }
+\cs_new:Npn \prg_case_tl:Nnn #1#2#3
+ { \prg_case_tl_aux:Nw #1 #2 #1 {#3} \q_recursion_stop }
+\cs_new:Npn \prg_case_tl_aux:Nw #1#2#3
+ {
+ \tl_if_eq:NNTF #1 #2
+ { \prg_case_end:nw {#3} }
+ { \prg_case_tl_aux:Nw #1 }
+ }
+\cs_generate_variant:Nn \prg_case_tl:Nnn { c }
+\cs_new_nopar:Npn \prg_replicate:nn #1
+ {
+ \int_to_roman:w
+ \exp_after:wN \prg_replicate_first_aux:N
+ \int_value:w \int_eval:w #1 \int_eval_end:
+ \cs_end:
+ }
+\cs_new_nopar:Npn \prg_replicate_aux:N #1
+ { \cs:w prg_replicate_#1 :n \prg_replicate_aux:N }
+\cs_new_nopar:Npn \prg_replicate_first_aux:N #1
+ { \cs:w prg_replicate_first_ #1 :n \prg_replicate_aux:N }
+\cs_new_nopar:Npn \prg_replicate_ :n #1 { \cs_end: }
+\cs_new:cpn { prg_replicate_0:n } #1 { \cs_end: {#1#1#1#1#1#1#1#1#1#1} }
+\cs_new:cpn { prg_replicate_1:n } #1 { \cs_end: {#1#1#1#1#1#1#1#1#1#1} #1 }
+\cs_new:cpn { prg_replicate_2:n } #1 { \cs_end: {#1#1#1#1#1#1#1#1#1#1} #1#1 }
+\cs_new:cpn { prg_replicate_3:n } #1
+ { \cs_end: {#1#1#1#1#1#1#1#1#1#1} #1#1#1 }
+\cs_new:cpn { prg_replicate_4:n } #1
+ { \cs_end: {#1#1#1#1#1#1#1#1#1#1} #1#1#1#1 }
+\cs_new:cpn { prg_replicate_5:n } #1
+ { \cs_end: {#1#1#1#1#1#1#1#1#1#1} #1#1#1#1#1 }
+\cs_new:cpn { prg_replicate_6:n } #1
+ { \cs_end: {#1#1#1#1#1#1#1#1#1#1} #1#1#1#1#1#1 }
+\cs_new:cpn { prg_replicate_7:n } #1
+ { \cs_end: {#1#1#1#1#1#1#1#1#1#1} #1#1#1#1#1#1#1 }
+\cs_new:cpn { prg_replicate_8:n } #1
+ { \cs_end: {#1#1#1#1#1#1#1#1#1#1} #1#1#1#1#1#1#1#1 }
+\cs_new:cpn { prg_replicate_9:n } #1
+ { \cs_end: {#1#1#1#1#1#1#1#1#1#1} #1#1#1#1#1#1#1#1#1 }
+\cs_new:cpn { prg_replicate_first_-:n } #1 { \c_zero \negative_replication }
+\cs_new:cpn { prg_replicate_first_0:n } #1 { \c_zero }
+\cs_new:cpn { prg_replicate_first_1:n } #1 { \c_zero #1 }
+\cs_new:cpn { prg_replicate_first_2:n } #1 { \c_zero #1#1 }
+\cs_new:cpn { prg_replicate_first_3:n } #1 { \c_zero #1#1#1 }
+\cs_new:cpn { prg_replicate_first_4:n } #1 { \c_zero #1#1#1#1 }
+\cs_new:cpn { prg_replicate_first_5:n } #1 { \c_zero #1#1#1#1#1 }
+\cs_new:cpn { prg_replicate_first_6:n } #1 { \c_zero #1#1#1#1#1#1 }
+\cs_new:cpn { prg_replicate_first_7:n } #1 { \c_zero #1#1#1#1#1#1#1 }
+\cs_new:cpn { prg_replicate_first_8:n } #1 { \c_zero #1#1#1#1#1#1#1#1 }
+\cs_new:cpn { prg_replicate_first_9:n } #1 { \c_zero #1#1#1#1#1#1#1#1#1 }
+\cs_new:Npn \prg_stepwise_function:nnnN #1#2
+ {
+ \int_compare:nNnTF {#2} > { 0 }
+ { \exp_args:Nf \prg_stepwise_function_incr:nnnN }
+ { \exp_args:Nf \prg_stepwise_function_decr:nnnN }
+ { \int_eval:n {#1} } {#2}
+ }
+\cs_new:Npn \prg_stepwise_function_incr:nnnN #1#2#3#4
+ {
+ \int_compare:nNnF {#1} > {#3}
+ {
+ #4 {#1}
+ \exp_args:Nf \prg_stepwise_function_incr:nnnN
+ { \int_eval:n { #1 + #2 } } {#2} {#3} #4
+ }
+ }
+\cs_new:Npn \prg_stepwise_function_decr:nnnN #1#2#3#4
+ {
+ \int_compare:nNnF {#1} < {#3}
+ {
+ #4 {#1}
+ \exp_args:Nf \prg_stepwise_function_decr:nnnN
+ { \int_eval:n { #1 + #2 } } {#2} {#3} #4
+ }
+ }
+\int_new:N \g_prg_stepwise_level_int
+\cs_new_protected:Npn \prg_stepwise_inline:nnnn #1#2#3#4
+ {
+ \int_gincr:N \g_prg_stepwise_level_int
+ \cs_gset_nopar:cpn
+ { g_prg_stepwise_ \int_use:N \g_prg_stepwise_level_int :n }
+ ##1 {#4}
+ \int_compare:nNnTF {#2} > { 0 }
+ { \exp_args:Ncf \prg_stepwise_inline_incr:Nnnn }
+ { \exp_args:Ncf \prg_stepwise_inline_decr:Nnnn }
+ { g_prg_stepwise_ \int_use:N \g_prg_stepwise_level_int :n }
+ { \int_eval:n {#1} } {#2} {#3}
+ \int_gdecr:N \g_prg_stepwise_level_int
+ }
+\cs_new_protected:Npn \prg_stepwise_inline_incr:Nnnn #1#2#3#4
+ {
+ \int_compare:nNnF {#2} > {#4}
+ {
+ #1 {#2}
+ \exp_args:NNf \prg_stepwise_inline_incr:Nnnn #1
+ { \int_eval:n { #2 + #3 } } {#3} {#4}
+ }
+ }
+\cs_new_protected:Npn \prg_stepwise_inline_decr:Nnnn #1#2#3#4
+ {
+ \int_compare:nNnF {#2} < {#4}
+ {
+ #1 {#2}
+ \exp_args:NNf \prg_stepwise_inline_decr:Nnnn #1
+ { \int_eval:n { #2 + #3 } } {#3} {#4}
+ }
+ }
+\cs_new_protected:Npn \prg_stepwise_variable:nnnNn #1#2#3#4#5
+ {
+ \prg_stepwise_inline:nnnn {#1} {#2} {#3}
+ {
+ \tl_set:Nn #4 {##1}
+ #5
+ }
+ }
+\prg_new_conditional:Npnn \mode_if_vertical: { p , T , F , TF }
+ { \if_mode_vertical: \prg_return_true: \else: \prg_return_false: \fi: }
+\prg_new_conditional:Npnn \mode_if_horizontal: { p , T , F , TF }
+ { \if_mode_horizontal: \prg_return_true: \else: \prg_return_false: \fi: }
+\prg_new_conditional:Npnn \mode_if_inner: { p , T , F , TF }
+ { \if_mode_inner: \prg_return_true: \else: \prg_return_false: \fi: }
+\prg_new_conditional:Npnn \mode_if_math: { p , T , F , TF }
+ {
+ \scan_align_safe_stop:
+ \if_mode_math: \prg_return_true: \else: \prg_return_false: \fi:
+ }
+\cs_new_nopar:Npn \group_align_safe_begin:
+ { \if_false: { \fi: \if_int_compare:w `} = \c_zero \fi: }
+\cs_new_nopar:Npn \group_align_safe_end:
+ { \if_int_compare:w `{ = \c_zero } \fi: }
+\cs_new_nopar:Npn \scan_align_safe_stop:
+ {
+ \int_compare:nNnT \etex_currentgrouptype:D = \c_six
+ {
+ \int_compare:nNnF \etex_lastnodetype:D = \c_zero
+ { \int_compare:nNnF \etex_lastnodetype:D = \c_seven { \scan_stop: } }
+ }
+ }
+\group_begin:
+ \tex_lccode:D `\& = `\g \scan_stop:
+ \tex_catcode:D `\& = \c_twelve
+\tl_to_lowercase:n
+ {
+ \group_end:
+ \cs_new_nopar:Npn \prg_variable_get_scope:N #1
+ {
+ \exp_last_unbraced:Nf \prg_variable_get_scope_aux:w
+ { \cs_to_str:N #1 \exp_stop_f: \q_stop }
+ }
+ \cs_new_nopar:Npn \prg_variable_get_scope_aux:w #1#2 \q_stop
+ { \token_if_eq_meaning:NNT & #1 { g } }
+ }
+\group_begin:
+ \tex_lccode:D `\& = `\_ \scan_stop:
+ \tex_catcode:D `\& = \c_twelve
+\tl_to_lowercase:n
+ {
+ \group_end:
+ \cs_new_nopar:Npn \prg_variable_get_type:N #1
+ {
+ \exp_after:wN \prg_variable_get_type_aux:w
+ \token_to_str:N #1 & a \q_stop
+ }
+ \cs_new_nopar:Npn \prg_variable_get_type_aux:w #1 & #2#3 \q_stop
+ {
+ \token_if_eq_meaning:NNTF a #2
+ {#1}
+ { \prg_variable_get_type_aux:w #2#3 \q_stop }
+ }
+ }
+\cs_new_protected_nopar:Npn \prg_define_quicksort:nnn #1#2#3 {
+ \cs_set:cpx{#1_quicksort:n}##1{
+ \exp_not:c{#1_quicksort_start_partition:w} ##1
+ \exp_not:n{#2\q_nil#3\q_stop}
+ }
+ \cs_set:cpx{#1_quicksort_braced:n}##1{
+ \exp_not:c{#1_quicksort_start_partition_braced:n} ##1
+ \exp_not:N\q_nil\exp_not:N\q_stop
+ }
+ \cs_set:cpx {#1_quicksort_start_partition:w} #2 ##1 #3{
+ \exp_not:N \quark_if_nil:nT {##1}\exp_not:N \use_none_delimit_by_q_stop:w
+ \exp_not:c{#1_quicksort_do_partition_i:nnnw} {##1}{}{}
+ }
+ \cs_set:cpx {#1_quicksort_start_partition_braced:n} ##1 {
+ \exp_not:N \quark_if_nil:nT {##1}\exp_not:N \use_none_delimit_by_q_stop:w
+ \exp_not:c{#1_quicksort_do_partition_i_braced:nnnn} {##1}{}{}
+ }
+ \cs_set:cpx {#1_quicksort_do_partition_i:nnnw} ##1##2##3 #2 ##4 #3 {
+ \exp_not:N \quark_if_nil:nTF {##4} \exp_not:c {#1_do_quicksort_braced:nnnnw}
+ {
+ \exp_not:c{#1_quicksort_compare:nnTF}{##1}{##4}
+ \exp_not:c{#1_quicksort_partition_greater_ii:nnnn}
+ \exp_not:c{#1_quicksort_partition_less_ii:nnnn}
+ }
+ {##1}{##2}{##3}{##4}
+ }
+ \cs_set:cpx {#1_quicksort_do_partition_i_braced:nnnn} ##1##2##3##4 {
+ \exp_not:N \quark_if_nil:nTF {##4} \exp_not:c {#1_do_quicksort_braced:nnnnw}
+ {
+ \exp_not:c{#1_quicksort_compare:nnTF}{##1}{##4}
+ \exp_not:c{#1_quicksort_partition_greater_ii_braced:nnnn}
+ \exp_not:c{#1_quicksort_partition_less_ii_braced:nnnn}
+ }
+ {##1}{##2}{##3}{##4}
+ }
+ \cs_set:cpx {#1_quicksort_do_partition_ii:nnnw} ##1##2##3 #2 ##4 #3 {
+ \exp_not:N \quark_if_nil:nTF {##4} \exp_not:c {#1_do_quicksort_braced:nnnnw}
+ {
+ \exp_not:c{#1_quicksort_compare:nnTF}{##4}{##1}
+ \exp_not:c{#1_quicksort_partition_less_i:nnnn}
+ \exp_not:c{#1_quicksort_partition_greater_i:nnnn}
+ }
+ {##1}{##2}{##3}{##4}
+ }
+ \cs_set:cpx {#1_quicksort_do_partition_ii_braced:nnnn} ##1##2##3##4 {
+ \exp_not:N \quark_if_nil:nTF {##4} \exp_not:c {#1_do_quicksort_braced:nnnnw}
+ {
+ \exp_not:c{#1_quicksort_compare:nnTF}{##4}{##1}
+ \exp_not:c{#1_quicksort_partition_less_i_braced:nnnn}
+ \exp_not:c{#1_quicksort_partition_greater_i_braced:nnnn}
+ }
+ {##1}{##2}{##3}{##4}
+ }
+ \cs_set:cpx {#1_quicksort_partition_less_i:nnnn} ##1##2##3##4{
+ \exp_not:c{#1_quicksort_do_partition_i:nnnw}{##1}{##2}{{##4}##3}}
+ \cs_set:cpx {#1_quicksort_partition_less_ii:nnnn} ##1##2##3##4{
+ \exp_not:c{#1_quicksort_do_partition_ii:nnnw}{##1}{##2}{##3{##4}}}
+ \cs_set:cpx {#1_quicksort_partition_greater_i:nnnn} ##1##2##3##4{
+ \exp_not:c{#1_quicksort_do_partition_i:nnnw}{##1}{{##4}##2}{##3}}
+ \cs_set:cpx {#1_quicksort_partition_greater_ii:nnnn} ##1##2##3##4{
+ \exp_not:c{#1_quicksort_do_partition_ii:nnnw}{##1}{##2{##4}}{##3}}
+ \cs_set:cpx {#1_quicksort_partition_less_i_braced:nnnn} ##1##2##3##4{
+ \exp_not:c{#1_quicksort_do_partition_i_braced:nnnn}{##1}{##2}{{##4}##3}}
+ \cs_set:cpx {#1_quicksort_partition_less_ii_braced:nnnn} ##1##2##3##4{
+ \exp_not:c{#1_quicksort_do_partition_ii_braced:nnnn}{##1}{##2}{##3{##4}}}
+ \cs_set:cpx {#1_quicksort_partition_greater_i_braced:nnnn} ##1##2##3##4{
+ \exp_not:c{#1_quicksort_do_partition_i_braced:nnnn}{##1}{{##4}##2}{##3}}
+ \cs_set:cpx {#1_quicksort_partition_greater_ii_braced:nnnn} ##1##2##3##4{
+ \exp_not:c{#1_quicksort_do_partition_ii_braced:nnnn}{##1}{##2{##4}}{##3}}
+ \cs_set:cpx {#1_do_quicksort_braced:nnnnw} ##1##2##3##4\q_stop {
+ \exp_not:c{#1_quicksort_braced:n}{##2}
+ \exp_not:c{#1_quicksort_function:n}{##1}
+ \exp_not:c{#1_quicksort_braced:n}{##3}
+ }
+}
+\prg_define_quicksort:nnn {prg}{}{}
+\cs_set:Npn \prg_quicksort_function:n {\ERROR}
+\cs_set:Npn \prg_quicksort_compare:nnTF {\ERROR}
+\cs_new_protected:Npn \prg_new_map_functions:Nn #1#2 { \deprectiated }
+\cs_new_protected:Npn \prg_set_map_functions:Nn #1#2 { \deprectiated }
+%%
+%%
+%% End of file `l3prg.sty'.
diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3prop.sty b/Master/texmf-dist/tex/latex/l3kernel/l3prop.sty
new file mode 100644
index 00000000000..5d2a1ff69d0
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/l3kernel/l3prop.sty
@@ -0,0 +1,333 @@
+%%
+%% This is file `l3prop.sty',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% l3prop.dtx (with options: `package')
+%%
+%% EXPERIMENTAL CODE
+%%
+%% Do not distribute this file without also distributing the
+%% source files specified above.
+%%
+%% Do not distribute a modified version of this file.
+%%
+%% File: l3prop.dtx Copyright (C) 1990-2011 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 "expl3 bundle" (The Work in LPPL)
+%% and all files in that bundle must be distributed together.
+%%
+%% The released version of this bundle is available from CTAN.
+%%
+%% -----------------------------------------------------------------------
+%%
+%% The development version of the bundle can be found at
+%%
+%% http://www.latex-project.org/svnroot/experimental/trunk/
+%%
+%% for those people who are interested.
+%%
+%%%%%%%%%%%
+%% NOTE: %%
+%%%%%%%%%%%
+%%
+%% Snapshots taken from the repository represent work in progress and may
+%% not work or may contain conflicting material! We therefore ask
+%% people _not_ to put them into distributions, archives, etc. without
+%% prior consultation with the LaTeX3 Project.
+%%
+%% -----------------------------------------------------------------------
+\RequirePackage{l3names}
+\GetIdInfo$Id: l3prop.dtx 2478 2011-06-19 21:34:23Z joseph $
+ {L3 Experimental property lists}
+\ProvidesExplPackage
+ {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
+\package_check_loaded_expl:
+\quark_new:N \q_prop
+\tl_const:Nn \c_empty_prop { \q_prop }
+\cs_new_protected:Npn \prop_new:N #1 { \cs_new_eq:NN #1 \c_empty_prop }
+\cs_new_protected:Npn \prop_new:c #1 { \cs_new_eq:cN {#1} \c_empty_prop }
+\cs_new_protected:Npn \prop_clear:N #1 { \cs_set_eq:NN #1 \c_empty_prop }
+\cs_new_protected:Npn \prop_clear:c #1 { \cs_set_eq:cN {#1} \c_empty_prop }
+\cs_new_protected:Npn \prop_gclear:N #1 { \cs_gset_eq:NN #1 \c_empty_prop }
+\cs_new_protected:Npn \prop_gclear:c #1 { \cs_gset_eq:cN {#1} \c_empty_prop }
+\cs_new_protected:Npn \prop_clear_new:N #1
+ { \cs_if_exist:NTF #1 { \prop_clear:N #1 } { \prop_new:N #1 } }
+\cs_generate_variant:Nn \prop_clear_new:N {c}
+\cs_new_protected:Npn \prop_gclear_new:N #1
+ { \cs_if_exist:NTF #1 { \prop_gclear:N #1 } { \prop_new:N #1 } }
+\cs_new_eq:NN \prop_gclear_new:c \prop_gclear:c
+\cs_new_eq:NN \prop_set_eq:NN \tl_set_eq:NN
+\cs_new_eq:NN \prop_set_eq:Nc \tl_set_eq:Nc
+\cs_new_eq:NN \prop_set_eq:cN \tl_set_eq:cN
+\cs_new_eq:NN \prop_set_eq:cc \tl_set_eq:cc
+\cs_new_eq:NN \prop_gset_eq:NN \tl_gset_eq:NN
+\cs_new_eq:NN \prop_gset_eq:Nc \tl_gset_eq:Nc
+\cs_new_eq:NN \prop_gset_eq:cN \tl_gset_eq:cN
+\cs_new_eq:NN \prop_gset_eq:cc \tl_gset_eq:cc
+\cs_set_protected:Npn \prop_split:NnTF #1#2
+ { \exp_args:NNo \prop_split_aux:NnTF #1 { \tl_to_str:n {#2} } }
+\cs_new_protected:Npn \prop_split_aux:NnTF #1#2
+ {
+ \cs_set_protected:Npn \prop_split_aux:w
+ ##1 \q_prop #2 \q_prop ##2 ##3 ##4 \q_mark ##5 \q_stop
+ { \prop_split_aux:nnnn ##3 { {##1 \q_prop } {##2} {##4} } }
+ \exp_after:wN \prop_split_aux:w #1 \q_mark
+ \q_prop #2 \q_prop { } { ? \use_ii:nn { } } \q_mark \q_stop
+ }
+\cs_new:Npn \prop_split_aux:nnnn #1#2#3#4 { #3 #2 }
+\cs_new_protected:Npn \prop_split_aux:w { }
+\cs_set_protected:Npn \prop_split:Nnn #1#2#3
+ {
+ \prop_split:NnTF #1 {#2}
+ {#3}
+ { \exp_args:Nno \use:n {#3} {#1} { \q_no_value } { } }
+ }
+\cs_new_protected:Npn \prop_del:Nn #1#2
+ { \prop_split:NnTF #1 {#2} { \prop_del_aux:NNnnn \tl_set:Nn #1 } { } }
+\cs_new_protected:Npn \prop_gdel:Nn #1#2
+ { \prop_split:NnTF #1 {#2} { \prop_del_aux:NNnnn \tl_gset:Nn #1 } { } }
+\cs_new_protected:Npn \prop_del_aux:NNnnn #1#2#3#4#5
+ { #1 #2 { #3 #5 } }
+\cs_generate_variant:Nn \prop_del:Nn { NV }
+\cs_generate_variant:Nn \prop_del:Nn { c , cV }
+\cs_generate_variant:Nn \prop_gdel:Nn { NV }
+\cs_generate_variant:Nn \prop_gdel:Nn { c , cV }
+\cs_new_protected:Npn \prop_get:NnN #1#2#3
+ {
+ \prop_split:NnTF #1 {#2}
+ { \prop_get_aux:Nnnn #3 }
+ { \tl_set:Nn #3 { \q_no_value } }
+ }
+\cs_new_protected:Npn \prop_get_aux:Nnnn #1#2#3#4
+ { \tl_set:Nn #1 {#3} }
+\cs_generate_variant:Nn \prop_get:NnN { NV , No }
+\cs_generate_variant:Nn \prop_get:NnN { c , cV , co }
+\cs_new_protected:Npn \prop_pop:NnN #1#2#3
+ {
+ \prop_split:NnTF #1 {#2}
+ { \prop_pop_aux:NNNnnn \tl_set:Nn #1 #3 }
+ { \tl_set:Nn #3 { \q_no_value } }
+ }
+\cs_new_protected:Npn \prop_gpop:NnN #1#2#3
+ {
+ \prop_split:NnTF #1 {#2}
+ { \prop_pop_aux:NNNnnn \tl_gset:Nn #1 #3 }
+ { \tl_set:Nn #3 { \q_no_value } }
+ }
+\cs_new_protected:Npn \prop_pop_aux:NNNnnn #1#2#3#4#5#6
+ {
+ \tl_set:Nn #3 {#5}
+ #1 #2 { #4 #6 }
+ }
+\cs_generate_variant:Nn \prop_pop:NnN { No }
+\cs_generate_variant:Nn \prop_pop:NnN { c , co }
+\cs_generate_variant:Nn \prop_gpop:NnN { No }
+\cs_generate_variant:Nn \prop_gpop:NnN { c , co }
+\cs_new_protected:Npn \prop_put:Nnn { \prop_put_aux:NNnn \tl_set:Nx }
+\cs_new_protected:Npn \prop_gput:Nnn { \prop_put_aux:NNnn \tl_gset:Nx }
+\cs_new_protected:Npn \prop_put_aux:NNnn #1#2#3#4
+ {
+ \prop_split:Nnn #2 {#3} { \prop_put_aux:NNnnnnn #1 #2 {#3} {#4} }
+ }
+\cs_new_protected:Npn \prop_put_aux:NNnnnnn #1#2#3#4#5#6#7
+ {
+ #1 #2
+ {
+ \exp_not:n { #5 #7 }
+ \tl_to_str:n {#3} \exp_not:n { \q_prop {#4} \q_prop }
+ }
+ }
+\cs_generate_variant:Nn \prop_put:Nnn
+ { NnV , Nno , Nnx , NV , NVV , No , Noo }
+\cs_generate_variant:Nn \prop_put:Nnn
+ { c , cnV , cno , cnx , cV , cVV , co , coo }
+\cs_generate_variant:Nn \prop_gput:Nnn
+ { NnV , Nno , Nnx , NV , NVV , No , Noo }
+\cs_generate_variant:Nn \prop_gput:Nnn
+ { c , cnV , cno , cnx , cV , cVV , co , coo }
+\cs_new_protected_nopar:Npn \prop_put_if_new:Nnn
+ { \prop_put_if_new_aux:NNnn \tl_put_right:Nx }
+\cs_new_protected_nopar:Npn \prop_gput_if_new:Nnn
+ { \prop_put_if_new_aux:NNnn \tl_gput_right:Nx }
+\cs_new_protected:Npn \prop_put_if_new_aux:NNnn #1#2#3#4
+ {
+ \prop_split:NnTF #2 {#3}
+ { \use_none:nnn }
+ {
+ #1 #2
+ { \tl_to_str:n {#3} \exp_not:n { \q_prop {#4} \q_prop } }
+ }
+ }
+\cs_generate_variant:Nn \prop_put_if_new:Nnn { c }
+\cs_generate_variant:Nn \prop_gput_if_new:Nnn { c }
+\prg_new_conditional:Npnn \prop_if_empty:N #1 { p, T , F , TF }
+ {
+ \if_meaning:w #1 \c_empty_prop
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\cs_generate_variant:Nn \prop_if_empty_p:N {c}
+\cs_generate_variant:Nn \prop_if_empty:NTF {c}
+\cs_generate_variant:Nn \prop_if_empty:NT {c}
+\cs_generate_variant:Nn \prop_if_empty:NF {c}
+\prg_new_conditional:Npnn \prop_if_in:Nn #1#2 { p , T , F , TF }
+ {
+ \exp_last_unbraced:Noo \prop_if_in_aux:nwn
+ { \tl_to_str:n {#2} } #1
+ A \q_prop { } \q_stop
+ }
+\cs_new:Npn \prop_if_in_aux:nwn #1 \q_prop #2 \q_prop #3
+ {
+ \if_catcode:w A #2
+ \prg_return_false:
+ \exp_after:wN \use_none_delimit_by_q_stop:w
+ \fi:
+ \str_if_eq:nnT {#1} {#2}
+ {
+ \prg_return_true:
+ \use_none_delimit_by_q_stop:w
+ }
+ \prop_if_in_aux:nwn {#1}
+ }
+\cs_generate_variant:Nn \prop_if_in_p:Nn { NV , No }
+\cs_generate_variant:Nn \prop_if_in_p:Nn { c , cV , co }
+\cs_generate_variant:Nn \prop_if_in:NnT { NV , No }
+\cs_generate_variant:Nn \prop_if_in:NnT { c , cV , co }
+\cs_generate_variant:Nn \prop_if_in:NnF { NV , No }
+\cs_generate_variant:Nn \prop_if_in:NnF { c , cV , co }
+\cs_generate_variant:Nn \prop_if_in:NnTF { NV , No }
+\cs_generate_variant:Nn \prop_if_in:NnTF { c , cV , co }
+\cs_new_nopar:Npn \prop_map_function:NN #1#2
+ {
+ \exp_last_unbraced:NNo \prop_map_function_aux:Nwn #2
+ #1 A \q_prop { } \q_recursion_stop
+ }
+\cs_new:Npn \prop_map_function_aux:Nwn #1 \q_prop #2 \q_prop #3
+ {
+ \if_catcode:w A #2
+ \exp_after:wN \prop_map_break:
+ \fi:
+ #1 {#2} {#3}
+ \prop_map_function_aux:Nwn #1
+ }
+\cs_generate_variant:Nn \prop_map_function:NN { Nc }
+\cs_generate_variant:Nn \prop_map_function:NN { c , cc }
+\int_new:N \g_prop_map_inline_int
+\cs_new_protected:Npn \prop_map_inline:Nn #1#2
+ {
+ \int_gincr:N \g_prop_map_inline_int
+ \cs_gset:cpn { prop_map_inline_ \int_use:N \g_prop_map_inline_int :nn }
+ ##1##2 {#2}
+ \prop_map_function:Nc #1
+ { prop_map_inline_ \int_use:N \g_prop_map_inline_int :nn }
+ \int_gdecr:N \g_prop_map_inline_int
+ }
+\cs_generate_variant:Nn \prop_map_inline:Nn { c }
+\cs_new_eq:NN \prop_map_break: \use_none_delimit_by_q_recursion_stop:w
+\cs_new_eq:NN \prop_map_break:n \use_i_delimit_by_q_recursion_stop:nw
+\tl_new:N \l_prop_show_tl
+\cs_new_protected_nopar:Npn \prop_show:N #1
+ {
+ \prop_if_empty:NTF #1
+ {
+ \iow_term:x { Property~list~\token_to_str:N #1 \c_space_tl is~empty }
+ \tl_show:n { }
+ }
+ {
+ \iow_term:x
+ {
+ Property~list~\token_to_str:N #1 \c_space_tl
+ contains~the~pairs~(without~outer~braces):
+ }
+ \tl_set:Nx \l_prop_show_tl
+ { \prop_map_function:NN #1 \prop_show_aux:nn }
+ \tl_show:n \exp_after:wN \exp_after:wN \exp_after:wN
+ { \exp_after:wN \prop_show_aux:w \l_prop_show_tl }
+ }
+ }
+\cs_new:Npn \prop_show_aux:nn #1#2
+ {
+ \iow_newline: > \c_space_tl \c_space_tl
+ \iow_char:N \{ #1 \iow_char:N \}
+ \c_space_tl \c_space_tl => \c_space_tl \c_space_tl
+ \iow_char:N \{ \exp_not:n {#2} \iow_char:N \}
+ }
+\cs_new:Npn \prop_show_aux:w #1 > ~ { }
+\cs_generate_variant:Nn \prop_show:N { c }
+\prg_new_protected_conditional:Npnn \prop_get:NnN #1#2#3 { T , F , TF }
+ {
+ \prop_split:NnTF #1 {#2}
+ { \prop_get_aux_true:Nnnn #3 }
+ { \prg_return_false: }
+ }
+\cs_new_protected:Npn \prop_get_aux_true:Nnnn #1#2#3#4
+ {
+ \tl_set:Nn #1 {#3}
+ \prg_return_true:
+ }
+\prg_new_protected_conditional:Npnn \prop_pop:NnN #1#2#3 {T,F,TF}
+ {
+ \prop_split:NnTF #1 {#2}
+ { \prop_pop_aux_true:NNNnnn \tl_set:Nn #1 #3 }
+ { \prg_return_false: }
+ }
+\prg_new_protected_conditional:Npnn \prop_gpop:NnN #1#2#3 {T,F,TF}
+ {
+ \prop_split:NnTF #1 {#2}
+ { \prop_pop_aux_true:NNNnnn \tl_gset:Nn #1 #3 }
+ { \prg_return_false: }
+ }
+\cs_new_protected:Npn \prop_pop_aux_true:NNNnnn #1#2#3#4#5#6
+ {
+ \tl_set:Nn #3 {#5}
+ #1 #2 { #4 #6 }
+ \prg_return_true:
+ }
+\cs_new:Npn \prop_map_tokens:Nn #1#2
+ {
+ \exp_last_unbraced:Nno \prop_map_tokens_aux:nwn {#2} #1
+ A \q_prop { } \q_recursion_stop
+ }
+\cs_new:Npn \prop_map_tokens_aux:nwn #1 \q_prop #2 \q_prop #3
+ {
+ \if_catcode:w A #2
+ \exp_after:wN \prop_map_break:
+ \fi:
+ \use:n {#1} {#2} {#3}
+ \prop_map_tokens_aux:nwn {#1}
+ }
+\cs_new:Npn \prop_get:Nn #1 #2
+ { \prop_map_tokens:Nn #1 { \prop_get_aux:nnn {#2} } }
+\cs_new:Npn \prop_get_aux:nnn #1 #2 #3
+ { \str_if_eq:nnT {#1} {#2} { \prop_map_break:n {#3} } }
+\cs_new_eq:NN \prop_display:N \prop_show:N
+\cs_new_eq:NN \prop_display:c \prop_show:c
+\cs_new_protected:Npn \prop_gget:NnN #1#2#3
+ { \prop_split:Nnn #1 {#2} { \prop_gget_aux:Nnnn #3 } }
+\cs_new_protected:Npn \prop_gget_aux:Nnnn #1#2#3#4
+ { \tl_gset:Nn #1 {#3} }
+\cs_generate_variant:Nn \prop_gget:NnN { NV }
+\cs_generate_variant:Nn \prop_gget:NnN { c , cV }
+\cs_new_eq:NN \prop_get_gdel:NnN \prop_gpop:NnN
+\cs_generate_variant:Nn \prop_if_in:NnT { cc }
+\cs_generate_variant:Nn \prop_if_in:NnF { cc }
+\cs_generate_variant:Nn \prop_if_in:NnTF { cc }
+\cs_generate_variant:Nn \prop_gput:Nnn { ccx }
+\prg_new_eq_conditional:NNn \prop_if_eq:NN \tl_if_eq:NN { p , T , F , TF }
+\prg_new_eq_conditional:NNn \prop_if_eq:cN \tl_if_eq:cN { p , T , F , TF }
+\prg_new_eq_conditional:NNn \prop_if_eq:Nc \tl_if_eq:Nc { p , T , F , TF }
+\prg_new_eq_conditional:NNn \prop_if_eq:cc \tl_if_eq:cc { p , T , F , TF }
+%%
+%%
+%% End of file `l3prop.sty'.
diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3quark.sty b/Master/texmf-dist/tex/latex/l3kernel/l3quark.sty
new file mode 100644
index 00000000000..35a8ca8f8e7
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/l3kernel/l3quark.sty
@@ -0,0 +1,154 @@
+%%
+%% This is file `l3quark.sty',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% l3quark.dtx (with options: `package')
+%%
+%% EXPERIMENTAL CODE
+%%
+%% Do not distribute this file without also distributing the
+%% source files specified above.
+%%
+%% Do not distribute a modified version of this file.
+%%
+%% File: l3quark.dtx Copyright (C) 1990-2011 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 "expl3 bundle" (The Work in LPPL)
+%% and all files in that bundle must be distributed together.
+%%
+%% The released version of this bundle is available from CTAN.
+%%
+%% -----------------------------------------------------------------------
+%%
+%% The development version of the bundle can be found at
+%%
+%% http://www.latex-project.org/svnroot/experimental/trunk/
+%%
+%% for those people who are interested.
+%%
+%%%%%%%%%%%
+%% NOTE: %%
+%%%%%%%%%%%
+%%
+%% Snapshots taken from the repository represent work in progress and may
+%% not work or may contain conflicting material! We therefore ask
+%% people _not_ to put them into distributions, archives, etc. without
+%% prior consultation with the LaTeX3 Project.
+%%
+%% -----------------------------------------------------------------------
+\RequirePackage{l3names}
+\GetIdInfo$Id: l3quark.dtx 2478 2011-06-19 21:34:23Z joseph $
+ {L3 Experimental quarks}
+\ProvidesExplPackage
+ {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
+\package_check_loaded_expl:
+\cs_new_protected_nopar:Npn \quark_new:N #1 { \tl_const:Nn #1 {#1} }
+\quark_new:N \q_nil
+\quark_new:N \q_mark
+\quark_new:N \q_no_value
+\quark_new:N \q_stop
+\quark_new:N \q_recursion_tail
+\quark_new:N \q_recursion_stop
+\cs_new:Npn \quark_if_recursion_tail_stop:N #1
+ {
+ \if_meaning:w #1 \q_recursion_tail
+ \exp_after:wN \use_none_delimit_by_q_recursion_stop:w
+ \fi:
+ }
+\cs_new:Npn \quark_if_recursion_tail_stop_do:Nn #1#2
+ {
+ \if_meaning:w #1 \q_recursion_tail
+ \exp_after:wN \use_i_delimit_by_q_recursion_stop:nw
+ \else:
+ \exp_after:wN \use_none:n
+ \fi:
+ {#2}
+ }
+\cs_new:Npn \quark_if_recursion_tail_stop:n #1
+ {
+ \if_catcode:w
+ A
+ \etex_detokenize:D \exp_after:wN
+ {
+ \quark_if_recursion_tail_aux:w #1 \q_recursion_stop
+ \q_recursion_tail \q_recursion_stop \q_stop
+ }
+ A
+ \exp_after:wN \use_none_delimit_by_q_recursion_stop:w
+ \fi:
+ }
+\cs_new:Npn \quark_if_recursion_tail_stop_do:nn #1#2
+ {
+ \if_catcode:w
+ A
+ \etex_detokenize:D \exp_after:wN
+ {
+ \quark_if_recursion_tail_aux:w #1 \q_recursion_stop
+ \q_recursion_tail \q_recursion_stop \q_stop
+ }
+ A
+ \exp_after:wN \use_i_delimit_by_q_recursion_stop:nw
+ \else:
+ \exp_after:wN \use_none:n
+ \fi:
+ {#2}
+ }
+\cs_new:Npn \quark_if_recursion_tail_aux:w
+ #1 \q_recursion_tail #2 \q_recursion_stop #3 \q_stop
+ { #1 #2 }
+\cs_generate_variant:Nn \quark_if_recursion_tail_stop:n { o }
+\cs_generate_variant:Nn \quark_if_recursion_tail_stop_do:nn { o }
+\prg_new_conditional:Nnn \quark_if_nil:N { p, T , F , TF }
+ {
+ \if_meaning:w \q_nil #1
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\prg_new_conditional:Nnn \quark_if_no_value:N { p, T , F , TF }
+ {
+ \if_meaning:w \q_no_value #1
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\cs_generate_variant:Nn \quark_if_no_value_p:N { c }
+\cs_generate_variant:Nn \quark_if_no_value:NT { c }
+\cs_generate_variant:Nn \quark_if_no_value:NF { c }
+\cs_generate_variant:Nn \quark_if_no_value:NTF { c }
+\prg_new_conditional:Nnn \quark_if_nil:n { p, T , F , TF }
+ {
+ \if_int_compare:w \pdftex_strcmp:D
+ { \exp_not:N \q_nil } { \exp_not:n {#1} } = \c_zero
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\prg_new_conditional:Nnn \quark_if_no_value:n { p, T , F , TF }
+ {
+ \if_int_compare:w \pdftex_strcmp:D
+ { \exp_not:N \q_no_value } { \exp_not:n {#1} } = \c_zero
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\cs_generate_variant:Nn \quark_if_nil_p:n { V , o }
+\cs_generate_variant:Nn \quark_if_nil:nTF { V , o }
+\cs_generate_variant:Nn \quark_if_nil:nT { V , o }
+\cs_generate_variant:Nn \quark_if_nil:nF { V , o }
+%%
+%%
+%% End of file `l3quark.sty'.
diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3seq.sty b/Master/texmf-dist/tex/latex/l3kernel/l3seq.sty
new file mode 100644
index 00000000000..13136da4828
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/l3kernel/l3seq.sty
@@ -0,0 +1,531 @@
+%%
+%% This is file `l3seq.sty',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% l3seq.dtx (with options: `package')
+%%
+%% EXPERIMENTAL CODE
+%%
+%% Do not distribute this file without also distributing the
+%% source files specified above.
+%%
+%% Do not distribute a modified version of this file.
+%%
+%% File: l3seq.dtx Copyright (C) 1990-2011 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 "expl3 bundle" (The Work in LPPL)
+%% and all files in that bundle must be distributed together.
+%%
+%% The released version of this bundle is available from CTAN.
+%%
+%% -----------------------------------------------------------------------
+%%
+%% The development version of the bundle can be found at
+%%
+%% http://www.latex-project.org/svnroot/experimental/trunk/
+%%
+%% for those people who are interested.
+%%
+%%%%%%%%%%%
+%% NOTE: %%
+%%%%%%%%%%%
+%%
+%% Snapshots taken from the repository represent work in progress and may
+%% not work or may contain conflicting material! We therefore ask
+%% people _not_ to put them into distributions, archives, etc. without
+%% prior consultation with the LaTeX3 Project.
+%%
+%% -----------------------------------------------------------------------
+\RequirePackage{l3names}
+\GetIdInfo$Id: l3seq.dtx 2478 2011-06-19 21:34:23Z joseph $
+ {L3 Experimental sequences and stacks}
+\ProvidesExplPackage
+ {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
+\package_check_loaded_expl:
+\cs_new:Npn \seq_item:n
+ {
+ \seq_use_error:
+ \use_none:n
+ }
+\tl_new:N \l_seq_tmpa_tl
+\tl_new:N \l_seq_tmpb_tl
+\cs_new_eq:NN \seq_new:N \tl_new:N
+\cs_new_eq:NN \seq_new:c \tl_new:c
+\cs_new_eq:NN \seq_clear:N \tl_clear:N
+\cs_new_eq:NN \seq_clear:c \tl_clear:c
+\cs_new_eq:NN \seq_gclear:N \tl_gclear:N
+\cs_new_eq:NN \seq_gclear:c \tl_gclear:c
+\cs_new_eq:NN \seq_clear_new:N \tl_clear_new:N
+\cs_new_eq:NN \seq_clear_new:c \tl_clear_new:c
+\cs_new_eq:NN \seq_gclear_new:N \tl_gclear_new:N
+\cs_new_eq:NN \seq_gclear_new:c \tl_gclear_new:c
+\cs_new_eq:NN \seq_set_eq:NN \tl_set_eq:NN
+\cs_new_eq:NN \seq_set_eq:Nc \tl_set_eq:Nc
+\cs_new_eq:NN \seq_set_eq:cN \tl_set_eq:cN
+\cs_new_eq:NN \seq_set_eq:cc \tl_set_eq:cc
+\cs_new_eq:NN \seq_gset_eq:NN \tl_gset_eq:NN
+\cs_new_eq:NN \seq_gset_eq:Nc \tl_gset_eq:Nc
+\cs_new_eq:NN \seq_gset_eq:cN \tl_gset_eq:cN
+\cs_new_eq:NN \seq_gset_eq:cc \tl_gset_eq:cc
+\cs_new_protected_nopar:Npn \seq_concat:NNN #1#2#3
+ { \tl_set:Nx #1 { \exp_not:o {#2} \exp_not:o {#3} } }
+\cs_new_protected_nopar:Npn \seq_gconcat:NNN #1#2#3
+ { \tl_gset:Nx #1 { \exp_not:o {#2} \exp_not:o {#3} } }
+\cs_generate_variant:Nn \seq_concat:NNN { ccc }
+\cs_generate_variant:Nn \seq_gconcat:NNN { ccc }
+\cs_new_protected:Npn \seq_put_left:Nn #1#2
+ { \tl_put_left:Nn #1 { \seq_item:n {#2} } }
+\cs_new_protected:Npn \seq_put_right:Nn #1#2
+ { \tl_put_right:Nn #1 { \seq_item:n {#2} } }
+\cs_generate_variant:Nn \seq_put_left:Nn { NV , Nv , No , Nx }
+\cs_generate_variant:Nn \seq_put_left:Nn { c , cV , cv , co , cx }
+\cs_generate_variant:Nn \seq_put_right:Nn { NV , Nv , No , Nx }
+\cs_generate_variant:Nn \seq_put_right:Nn { c , cV , cv , co , cx }
+\cs_new_protected:Npn \seq_gput_left:Nn #1#2
+ { \tl_gput_left:Nn #1 { \seq_item:n {#2} } }
+\cs_new_protected:Npn \seq_gput_right:Nn #1#2
+ { \tl_gput_right:Nn #1 { \seq_item:n {#2} } }
+\cs_generate_variant:Nn \seq_gput_left:Nn { NV , Nv , No , Nx }
+\cs_generate_variant:Nn \seq_gput_left:Nn { c , cV , cv , co , cx }
+\cs_generate_variant:Nn \seq_gput_right:Nn { NV , Nv , No , Nx }
+\cs_generate_variant:Nn \seq_gput_right:Nn { c , cV , cv , co , cx }
+\seq_new:N \l_seq_remove_seq
+\cs_new_protected:Npn \seq_remove_duplicates:N
+ { \seq_remove_duplicates_aux:NN \seq_set_eq:NN }
+\cs_new_protected:Npn \seq_gremove_duplicates:N
+ { \seq_remove_duplicates_aux:NN \seq_gset_eq:NN }
+\cs_new_protected:Npn \seq_remove_duplicates_aux:NN #1#2
+ {
+ \seq_clear:N \l_seq_remove_seq
+ \seq_map_inline:Nn #2
+ {
+ \seq_if_in:NnF \l_seq_remove_seq {##1}
+ { \seq_put_right:Nn \l_seq_remove_seq {##1} }
+ }
+ #1 #2 \l_seq_remove_seq
+ }
+\cs_generate_variant:Nn \seq_remove_duplicates:N { c }
+\cs_generate_variant:Nn \seq_gremove_duplicates:N { c }
+\cs_new_protected:Npn \seq_remove_all:Nn
+ { \seq_remove_all_aux:NNn \tl_set:Nx }
+\cs_new_protected:Npn \seq_gremove_all:Nn
+ { \seq_remove_all_aux:NNn \tl_gset:Nx }
+\cs_new_protected:Npn \seq_remove_all_aux:NNn #1#2#3
+ {
+ \seq_push_item_def:n
+ {
+ \str_if_eq:nnT {##1} {#3}
+ {
+ \if_false: { \fi: }
+ \tl_set:Nn \l_seq_tmpb_tl {##1}
+ #1 #2
+ { \if_false: } \fi:
+ \exp_not:o {#2}
+ \tl_if_eq:NNT \l_seq_tmpa_tl \l_seq_tmpb_tl
+ { \use_none:nn }
+ }
+ \exp_not:n { \seq_item:n {##1} }
+ }
+ \tl_set:Nn \l_seq_tmpa_tl {#3}
+ #1 #2 {#2}
+ \seq_pop_item_def:
+ }
+\cs_generate_variant:Nn \seq_remove_all:Nn { c }
+\cs_generate_variant:Nn \seq_gremove_all:Nn { c }
+\prg_new_eq_conditional:NNn \seq_if_empty:N \tl_if_empty:N
+ { p , T , F , TF }
+\prg_new_eq_conditional:NNn \seq_if_empty:c \tl_if_empty:c
+ { p , T , F , TF }
+\prg_new_protected_conditional:Npnn \seq_if_in:Nn #1#2
+ { T , F , TF }
+ {
+ \group_begin:
+ \tl_set:Nn \l_seq_tmpa_tl {#2}
+ \cs_set_protected:Npn \seq_item:n ##1
+ {
+ \tl_set:Nn \l_seq_tmpb_tl {##1}
+ \if_meaning:w \l_seq_tmpa_tl \l_seq_tmpb_tl
+ \exp_after:wN \seq_if_in_aux:
+ \fi:
+ }
+ #1
+ \seq_break:n { \prg_return_false: }
+ \seq_break_point:n { \group_end: }
+ }
+\cs_new_nopar:Npn \seq_if_in_aux: { \seq_break:n { \prg_return_true: } }
+\cs_generate_variant:Nn \seq_if_in:NnT { NV , Nv , No , Nx }
+\cs_generate_variant:Nn \seq_if_in:NnT { c , cV , cv , co , cx }
+\cs_generate_variant:Nn \seq_if_in:NnF { NV , Nv , No , Nx }
+\cs_generate_variant:Nn \seq_if_in:NnF { c , cV , cv , co , cx }
+\cs_generate_variant:Nn \seq_if_in:NnTF { NV , Nv , No , Nx }
+\cs_generate_variant:Nn \seq_if_in:NnTF { c , cV , cv , co , cx }
+\cs_new_protected_nopar:Npn \seq_get_left:NN #1#2
+ {
+ \seq_if_empty_err_break:N #1
+ \exp_after:wN \seq_get_left_aux:NnwN #1 \q_stop #2
+ \seq_break_point:n { }
+ }
+\cs_new_protected:Npn \seq_get_left_aux:NnwN \seq_item:n #1#2 \q_stop #3
+ { \tl_set:Nn #3 {#1} }
+\cs_generate_variant:Nn \seq_get_left:NN { c }
+\cs_new_protected_nopar:Npn \seq_pop_left:NN
+ { \seq_pop_left_aux:NNN \tl_set:Nn }
+\cs_new_protected_nopar:Npn \seq_gpop_left:NN
+ { \seq_pop_left_aux:NNN \tl_gset:Nn }
+\cs_new_protected_nopar:Npn \seq_pop_left_aux:NNN #1#2#3
+ {
+ \seq_if_empty_err_break:N #2
+ \exp_after:wN \seq_pop_left_aux:NnwNNN #2 \q_stop #1#2#3
+ \seq_break_point:n { }
+ }
+\cs_new_protected:Npn \seq_pop_left_aux:NnwNNN \seq_item:n #1#2 \q_stop #3#4#5
+ {
+ #3 #4 {#2}
+ \tl_set:Nn #5 {#1}
+ }
+\cs_generate_variant:Nn \seq_pop_left:NN { c }
+\cs_generate_variant:Nn \seq_gpop_left:NN { c }
+\cs_new_protected_nopar:Npn \seq_get_right:NN #1#2
+ {
+ \seq_if_empty_err_break:N #1
+ \seq_get_right_aux:NN #1#2
+ \seq_break_point:n { }
+ }
+\cs_new_protected_nopar:Npn \seq_get_right_aux:NN #1#2
+ {
+ \seq_push_item_def:n { }
+ \exp_after:wN \exp_after:wN \exp_after:wN \seq_get_right_loop:nn
+ \exp_after:wN \use_none:n #1
+ { \tl_set:Nn #2 }
+ { }
+ {
+ \seq_pop_item_def:
+ \seq_break:
+ }
+}
+\cs_new:Npn \seq_get_right_loop:nn #1#2
+ {
+ #2 {#1}
+ \seq_get_right_loop:nn
+ }
+\cs_generate_variant:Nn \seq_get_right:NN { c }
+\cs_new_protected_nopar:Npn \seq_pop_right:NN
+ { \seq_pop_right_aux:NNN \tl_set:Nx }
+\cs_new_protected_nopar:Npn \seq_gpop_right:NN
+ { \seq_pop_right_aux:NNN \tl_gset:Nx }
+\cs_new_protected_nopar:Npn \seq_pop_right_aux:NNN #1#2#3
+ {
+ \seq_if_empty_err_break:N #2
+ \seq_pop_right_aux_ii:NNN #1 #2 #3
+ \seq_break_point:n { }
+ }
+\cs_new_protected_nopar:Npn \seq_pop_right_aux_ii:NNN #1#2#3
+ {
+ \seq_push_item_def:n { \exp_not:n { \seq_item:n {##1} } }
+ #1 #2 { \if_false: } \fi:
+ \exp_after:wN \exp_after:wN \exp_after:wN \seq_get_right_loop:nn
+ \exp_after:wN \use_none:n #2
+ {
+ \if_false: { \fi: }
+ \tl_set:Nn #3
+ }
+ { }
+ {
+ \seq_pop_item_def:
+ \seq_break:
+ }
+ }
+\cs_generate_variant:Nn \seq_pop_right:NN { c }
+\cs_generate_variant:Nn \seq_gpop_right:NN { c }
+\cs_new:Npn \seq_break: #1 \seq_break_point:n #2 {#2}
+\cs_new:Npn \seq_break:n #1#2 \seq_break_point:n #3 { #3 #1 }
+\cs_new_eq:NN \seq_map_break: \seq_break:
+\cs_new_eq:NN \seq_map_break:n \seq_break:n
+\cs_new_eq:NN \seq_break_point:n \use:n
+\cs_new_protected_nopar:Npn \seq_if_empty_err_break:N #1
+ {
+ \if_meaning:w #1 \c_empty_tl
+ \msg_kernel_error:nnx { seq } { empty-sequence } { \token_to_str:N #1 }
+ \exp_after:wN \seq_break:
+ \fi:
+ }
+\cs_new:Npn \seq_map_function:NN #1#2
+ {
+ \exp_after:wN \seq_map_function_aux:NNn \exp_after:wN #2 #1
+ { ? \seq_map_break: } { }
+ \seq_break_point:n { }
+ }
+\cs_new:Npn \seq_map_function_aux:NNn #1#2#3
+ {
+ \use_none:n #2
+ #1 {#3}
+ \seq_map_function_aux:NNn #1
+ }
+\cs_generate_variant:Nn \seq_map_function:NN { c }
+\cs_new_protected:Npn \seq_push_item_def:n
+ {
+ \seq_push_item_def_aux:
+ \cs_gset:Npn \seq_item:n ##1
+ }
+\cs_new_protected:Npn \seq_push_item_def:x
+ {
+ \seq_push_item_def_aux:
+ \cs_gset:Npx \seq_item:n ##1
+ }
+\cs_new_protected:Npn \seq_push_item_def_aux:
+ {
+ \cs_gset_eq:cN { seq_item_ \int_use:N \g_seq_nesting_depth_int :n }
+ \seq_item:n
+ \int_gincr:N \g_seq_nesting_depth_int
+ }
+\cs_new_protected_nopar:Npn \seq_pop_item_def:
+ {
+ \int_gdecr:N \g_seq_nesting_depth_int
+ \cs_gset_eq:Nc \seq_item:n
+ { seq_item_ \int_use:N \g_seq_nesting_depth_int :n }
+ }
+\cs_new_protected:Npn \seq_map_inline:Nn #1#2
+ {
+ \seq_push_item_def:n {#2}
+ #1
+ \seq_break_point:n { \seq_pop_item_def: }
+ }
+\cs_generate_variant:Nn \seq_map_inline:Nn { c }
+\cs_new_protected:Npn \seq_map_variable:NNn #1#2#3
+ {
+ \seq_push_item_def:x
+ {
+ \tl_set:Nn \exp_not:N #2 {##1}
+ \exp_not:n {#3}
+ }
+ #1
+ \seq_break_point:n { \seq_pop_item_def: }
+ }
+\cs_generate_variant:Nn \seq_map_variable:NNn { Nc }
+\cs_generate_variant:Nn \seq_map_variable:NNn { c , cc }
+\cs_new_eq:NN \seq_push:Nn \seq_put_left:Nn
+\cs_new_eq:NN \seq_push:NV \seq_put_left:NV
+\cs_new_eq:NN \seq_push:Nv \seq_put_left:Nv
+\cs_new_eq:NN \seq_push:No \seq_put_left:No
+\cs_new_eq:NN \seq_push:Nx \seq_put_left:Nx
+\cs_new_eq:NN \seq_push:cn \seq_put_left:cn
+\cs_new_eq:NN \seq_push:cV \seq_put_left:cV
+\cs_new_eq:NN \seq_push:cv \seq_put_left:cv
+\cs_new_eq:NN \seq_push:co \seq_put_left:co
+\cs_new_eq:NN \seq_push:cx \seq_put_left:cx
+\cs_new_eq:NN \seq_gpush:Nn \seq_gput_left:Nn
+\cs_new_eq:NN \seq_gpush:NV \seq_gput_left:NV
+\cs_new_eq:NN \seq_gpush:Nv \seq_gput_left:Nv
+\cs_new_eq:NN \seq_gpush:No \seq_gput_left:No
+\cs_new_eq:NN \seq_gpush:Nx \seq_gput_left:Nx
+\cs_new_eq:NN \seq_gpush:cn \seq_gput_left:cn
+\cs_new_eq:NN \seq_gpush:cV \seq_gput_left:cV
+\cs_new_eq:NN \seq_gpush:cv \seq_gput_left:cv
+\cs_new_eq:NN \seq_gpush:co \seq_gput_left:co
+\cs_new_eq:NN \seq_gpush:cx \seq_gput_left:cx
+\cs_new_eq:NN \seq_get:NN \seq_get_left:NN
+\cs_new_eq:NN \seq_get:cN \seq_get_left:cN
+\cs_new_eq:NN \seq_pop:NN \seq_pop_left:NN
+\cs_new_eq:NN \seq_pop:cN \seq_pop_left:cN
+\cs_new_eq:NN \seq_gpop:NN \seq_gpop_left:NN
+\cs_new_eq:NN \seq_gpop:cN \seq_gpop_left:cN
+\tl_new:N \l_seq_show_tl
+\cs_new_protected_nopar:Npn \seq_show:N #1
+ {
+ \seq_if_empty:NTF #1
+ {
+ \iow_term:x { Sequence~\token_to_str:N #1 \c_space_tl is~empty }
+ \tl_show:n { }
+ }
+ {
+ \iow_term:x
+ {
+ Sequence~\token_to_str:N #1 \c_space_tl
+ contains~the~items~(without~outer~braces):
+ }
+ \tl_set:Nx \l_seq_show_tl
+ { \seq_map_function:NN #1 \seq_show_aux:n }
+ \etex_showtokens:D \exp_after:wN \exp_after:wN \exp_after:wN
+ { \exp_after:wN \seq_show_aux:w \l_seq_show_tl }
+ }
+ }
+\cs_new:Npn \seq_show_aux:n #1
+ {
+ \iow_newline: > \c_space_tl \c_space_tl
+ \iow_char:N \{ \exp_not:n {#1} \iow_char:N \}
+ }
+\cs_new:Npn \seq_show_aux:w #1 > ~ { }
+\cs_generate_variant:Nn \seq_show:N { c }
+\cs_new_nopar:Npn \seq_if_empty_break_return_false:N #1
+ {
+ \if_meaning:w #1 \c_empty_tl
+ \prg_return_false:
+ \exp_after:wN \seq_break:
+ \fi:
+ }
+\prg_new_protected_conditional:Npnn \seq_get_left:NN #1 #2 { T , F , TF }
+ {
+ \seq_if_empty_break_return_false:N #1
+ \exp_after:wN \seq_get_left_aux:Nw #1 \q_stop #2
+ \prg_return_true:
+ \seq_break:
+ \seq_break_point:n { }
+ }
+\prg_new_protected_conditional:Npnn \seq_get_right:NN #1#2 { T , F , TF }
+ {
+ \seq_if_empty_break_return_false:N #1
+ \seq_get_right_aux:NN #1#2
+ \prg_return_true: \seq_break:
+ \seq_break_point:n { }
+ }
+\cs_generate_variant:Nn \seq_get_left:NNT { c }
+\cs_generate_variant:Nn \seq_get_left:NNF { c }
+\cs_generate_variant:Nn \seq_get_left:NNTF { c }
+\cs_generate_variant:Nn \seq_get_right:NNT { c }
+\cs_generate_variant:Nn \seq_get_right:NNF { c }
+\cs_generate_variant:Nn \seq_get_right:NNTF { c }
+\prg_new_protected_conditional:Npnn \seq_pop_left:NN #1#2 { T , F , TF }
+ {
+ \seq_if_empty_break_return_false:N #1
+ \exp_after:wN \seq_pop_left_aux:NnwNNN #1 \q_stop \tl_set:Nn #1#2
+ \prg_return_true: \seq_break:
+ \seq_break_point:n { }
+ }
+\prg_new_protected_conditional:Npnn \seq_gpop_left:NN #1#2 { T , F , TF }
+ {
+ \seq_if_empty_break_return_false:N #1
+ \exp_after:wN \seq_pop_left_aux:NnwNNN #1 \q_stop \tl_gset:Nn #1#2
+ \prg_return_true: \seq_break:
+ \seq_break_point:n { }
+ }
+\prg_new_protected_conditional:Npnn \seq_pop_right:NN #1#2 { T , F , TF }
+ {
+ \seq_if_empty_break_return_false:N #1
+ \seq_pop_right_aux_ii:NNN \tl_set:Nx #1 #2
+ \prg_return_true: \seq_break:
+ \seq_break_point:n { }
+ }
+\prg_new_protected_conditional:Npnn \seq_gpop_right:NN #1#2 { T , F , TF }
+ {
+ \seq_if_empty_break_return_false:N #1
+ \seq_pop_right_aux_ii:NNN \tl_gset:Nx #1 #2
+ \prg_return_true: \seq_break:
+ \seq_break_point:n { }
+ }
+\cs_generate_variant:Nn \seq_pop_left:NNT { c }
+\cs_generate_variant:Nn \seq_pop_left:NNF { c }
+\cs_generate_variant:Nn \seq_pop_left:NNTF { c }
+\cs_generate_variant:Nn \seq_gpop_left:NNT { c }
+\cs_generate_variant:Nn \seq_gpop_left:NNF { c }
+\cs_generate_variant:Nn \seq_gpop_left:NNTF { c }
+\cs_generate_variant:Nn \seq_pop_right:NNT { c }
+\cs_generate_variant:Nn \seq_pop_right:NNF { c }
+\cs_generate_variant:Nn \seq_pop_right:NNTF { c }
+\cs_generate_variant:Nn \seq_gpop_right:NNT { c }
+\cs_generate_variant:Nn \seq_gpop_right:NNF { c }
+\cs_generate_variant:Nn \seq_gpop_right:NNTF { c }
+\cs_new:Npn \seq_length:N #1
+ {
+ \int_eval:n
+ {
+ 0
+ \seq_map_function:NN #1 \seq_length_aux:n
+ }
+ }
+\cs_new:Npn \seq_length_aux:n #1 { +1 }
+\cs_generate_variant:Nn \seq_length:N { c }
+\cs_new_nopar:Npn \seq_item:Nn #1#2
+ {
+ \exp_last_unbraced:Nfo \seq_item_aux:nnn
+ {
+ \int_eval:n
+ {
+ \int_compare:nNnT {#2} < \c_zero
+ { \seq_length:N #1 + }
+ #2
+ }
+ }
+ #1
+ { ? \seq_break: }
+ { }
+ \seq_break_point:n { }
+ }
+\cs_new_nopar:Npn \seq_item_aux:nnn #1#2#3
+ {
+ \use_none:n #2
+ \int_compare:nNnTF {#1} = \c_zero
+ { \seq_break:n {#3} }
+ { \exp_args:Nf \seq_item_aux:nnn { #1 - 1 } }
+ }
+\cs_generate_variant:Nn \seq_item:Nn { c }
+\cs_new_nopar:Npn \seq_use:N #1 { \seq_map_function:NN #1 \use:n }
+\cs_generate_variant:Nn \seq_use:N { c }
+\cs_new_nopar:Npn \seq_mapthread_function:NNN #1#2#3
+ {
+ \exp_after:wN \seq_mapthread_function_aux:NN
+ \exp_after:wN #3
+ \exp_after:wN #1
+ #2
+ { ? \seq_break: } { }
+ \seq_break_point:n { }
+ }
+\cs_new_nopar:Npn \seq_mapthread_function_aux:NN #1#2
+ {
+ \exp_after:wN \seq_mapthread_function_aux:Nnnwnn
+ \exp_after:wN #1
+ #2
+ { ? \seq_break: } { }
+ \q_stop
+ }
+\cs_new:Npn \seq_mapthread_function_aux:Nnnwnn #1#2#3#4 \q_stop #5#6
+ {
+ \use_none:n #2
+ \use_none:n #5
+ #1 {#3} {#6}
+ \seq_mapthread_function_aux:Nnnwnn #1 #4 \q_stop
+ }
+\cs_generate_variant:Nn \seq_mapthread_function:NNN { Nc }
+\cs_generate_variant:Nn \seq_mapthread_function:NNN { c , cc }
+\cs_new_protected:Npn \seq_set_from_clist:NN #1#2
+ {
+ \tl_set:Nx #1
+ { \clist_map_function:NN #2 \seq_wrap_item:n }
+ }
+\cs_new_protected:Npn \seq_set_from_clist:Nn #1#2
+ {
+ \tl_set:Nx #1
+ { \clist_map_function:nN {#2} \seq_wrap_item:n }
+ }
+\cs_new_protected:Npn \seq_gset_from_clist:NN #1#2
+ {
+ \tl_gset:Nx #1
+ { \clist_map_function:NN #2 \seq_wrap_item:n }
+ }
+\cs_new_protected:Npn \seq_gset_from_clist:Nn #1#2
+ {
+ \tl_gset:Nx #1
+ { \clist_map_function:nN {#2} \seq_wrap_item:n }
+ }
+\cs_new:Npn \seq_wrap_item:n #1 { \exp_not:n { \seq_item:n {#1} } }
+\cs_generate_variant:Nn \seq_set_from_clist:NN { Nc }
+\cs_generate_variant:Nn \seq_set_from_clist:NN { c , cc }
+\cs_generate_variant:Nn \seq_set_from_clist:Nn { c }
+\cs_generate_variant:Nn \seq_gset_from_clist:NN { Nc }
+\cs_generate_variant:Nn \seq_gset_from_clist:NN { c , cc }
+\cs_generate_variant:Nn \seq_gset_from_clist:Nn { c }
+\cs_new_eq:NN \seq_top:NN \seq_get_left:NN
+\cs_new_eq:NN \seq_top:cN \seq_get_left:cN
+\cs_new_eq:NN \seq_display:N \seq_show:N
+\cs_new_eq:NN \seq_display:c \seq_show:c
+%%
+%%
+%% End of file `l3seq.sty'.
diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3skip.sty b/Master/texmf-dist/tex/latex/l3kernel/l3skip.sty
new file mode 100644
index 00000000000..ae4a46fc805
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/l3kernel/l3skip.sty
@@ -0,0 +1,332 @@
+%%
+%% This is file `l3skip.sty',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% l3skip.dtx (with options: `package')
+%%
+%% EXPERIMENTAL CODE
+%%
+%% Do not distribute this file without also distributing the
+%% source files specified above.
+%%
+%% Do not distribute a modified version of this file.
+%%
+%% File: l3skip.dtx Copyright (C) 2004-2011 Frank Mittelbach, 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 "expl3 bundle" (The Work in LPPL)
+%% and all files in that bundle must be distributed together.
+%%
+%% The released version of this bundle is available from CTAN.
+%%
+%% -----------------------------------------------------------------------
+%%
+%% The development version of the bundle can be found at
+%%
+%% http://www.latex-project.org/svnroot/experimental/trunk/
+%%
+%% for those people who are interested.
+%%
+%%%%%%%%%%%
+%% NOTE: %%
+%%%%%%%%%%%
+%%
+%% Snapshots taken from the repository represent work in progress and may
+%% not work or may contain conflicting material! We therefore ask
+%% people _not_ to put them into distributions, archives, etc. without
+%% prior consultation with the LaTeX3 Project.
+%%
+%% -----------------------------------------------------------------------
+\RequirePackage{l3names}
+\GetIdInfo$Id: l3skip.dtx 2478 2011-06-19 21:34:23Z joseph $
+ {L3 Experimental dimensions and skips}
+\ProvidesExplPackage
+ {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
+\package_check_loaded_expl:
+\cs_new_eq:NN \if_dim:w \tex_ifdim:D
+\cs_new_eq:NN \dim_eval:w \etex_dimexpr:D
+\cs_new_eq:NN \dim_eval_end: \tex_relax:D
+\cs_new_protected_nopar:Npn \dim_new:N #1
+ {
+ \chk_if_free_cs:N #1
+ \newdimen #1
+ }
+\cs_generate_variant:Nn \dim_new:N { c }
+\cs_new_protected_nopar:Npn \dim_zero:N #1 { #1 \c_zero_dim }
+\cs_new_protected_nopar:Npn \dim_gzero:N { \pref_global:D \dim_zero:N }
+\cs_generate_variant:Nn \dim_zero:N { c }
+\cs_generate_variant:Nn \dim_gzero:N { c }
+\cs_new_protected_nopar:Npn \dim_set:Nn #1#2
+ { #1 ~ \dim_eval:w #2 \dim_eval_end: }
+\cs_new_protected_nopar:Npn \dim_gset:Nn { \pref_global:D \dim_set:Nn }
+\cs_generate_variant:Nn \dim_set:Nn { c }
+\cs_generate_variant:Nn \dim_gset:Nn { c }
+\cs_new_protected_nopar:Npn \dim_set_eq:NN #1#2 { #1 = #2 }
+\cs_generate_variant:Nn \dim_set_eq:NN { c }
+\cs_generate_variant:Nn \dim_set_eq:NN { Nc , cc }
+\cs_new_protected_nopar:Npn \dim_gset_eq:NN #1#2 { \pref_global:D #1 = #2 }
+\cs_generate_variant:Nn \dim_gset_eq:NN { c }
+\cs_generate_variant:Nn \dim_gset_eq:NN { Nc , cc }
+\cs_new_protected_nopar:Npn \dim_set_max:Nn #1#2
+ { \dim_compare:nNnT {#1} < {#2} { \dim_set:Nn #1 {#2} } }
+\cs_new_protected_nopar:Npn \dim_gset_max:Nn #1#2
+ { \dim_compare:nNnT {#1} < {#2} { \dim_gset:Nn #1 {#2} } }
+\cs_new_protected_nopar:Npn \dim_set_min:Nn #1#2
+ { \dim_compare:nNnT {#1} > {#2} { \dim_set:Nn #1 {#2} } }
+\cs_new_protected_nopar:Npn \dim_gset_min:Nn #1#2
+ { \dim_compare:nNnT {#1} > {#2} { \dim_gset:Nn #1 {#2} } }
+\cs_generate_variant:Nn \dim_set_max:Nn { c }
+\cs_generate_variant:Nn \dim_gset_max:Nn { c }
+\cs_generate_variant:Nn \dim_set_min:Nn { c }
+\cs_generate_variant:Nn \dim_gset_min:Nn { c }
+\cs_new_protected_nopar:Npn \dim_add:Nn #1#2
+ { \tex_advance:D #1 by \dim_eval:w #2 \dim_eval_end: }
+\cs_new_protected_nopar:Npn \dim_gadd:Nn { \pref_global:D \dim_add:Nn }
+\cs_generate_variant:Nn \dim_add:Nn { c }
+\cs_generate_variant:Nn \dim_gadd:Nn { c }
+\cs_new_protected_nopar:Npn \dim_sub:Nn #1#2
+ { \tex_advance:D #1 by - \dim_eval:w #2 \dim_eval_end: }
+\cs_new_protected_nopar:Npn \dim_gsub:Nn { \pref_global:D \dim_sub:Nn }
+\cs_generate_variant:Nn \dim_sub:Nn { c }
+\cs_generate_variant:Nn \dim_gsub:Nn { c }
+\cs_new_nopar:Npn \dim_ratio:nn #1#2
+ { \dim_ratio_aux:n {#1} / \dim_ratio_aux:n {#2} }
+\cs_new_nopar:Npn \dim_ratio_aux:n #1
+ { \exp_after:wN \int_value:w \dim_eval:w #1 \dim_eval_end: }
+\prg_new_conditional:Npnn \dim_compare:nNn #1#2#3 { p , T , F , TF }
+ {
+ \if_dim:w \dim_eval:w #1 #2 \dim_eval:w #3 \dim_eval_end:
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+\prg_new_conditional:Npnn \dim_compare:n #1 { p , T , F , TF }
+ {
+ \exp_after:wN \dim_compare_aux:wNN \dim_use:N \dim_eval:w #1
+ \dim_eval_end:
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\exp_args:Nno \use:nn
+ { \cs_new:Npn \dim_compare_aux:wNN #1 }
+ { \tl_to_str:n { pt } }
+ #2 #3
+ {
+ \use:c
+ {
+ dim_compare_ #2
+ \if_meaning:w = #3 = \fi:
+ :nw
+ }
+ { #1 pt } #3
+ }
+\cs_new:cpn { dim_compare_<:nw } #1 { \if_dim:w #1 < \dim_eval:w }
+\cs_new:cpn { dim_compare_=:nw } #1 { \if_dim:w #1 = \dim_eval:w }
+\cs_new:cpn { dim_compare_>:nw } #1 { \if_dim:w #1 > \dim_eval:w }
+\cs_new:cpn {dim_compare_==:nw} #1#2 { \if_dim:w #1 = \dim_eval:w }
+\cs_new:cpn {dim_compare_<=:nw} #1#2 {\reverse_if:N \if_dim:w #1 > \dim_eval:w}
+\cs_new:cpn {dim_compare_!=:nw} #1#2 {\reverse_if:N \if_dim:w #1 = \dim_eval:w}
+\cs_new:cpn {dim_compare_>=:nw} #1#2 {\reverse_if:N \if_dim:w #1 < \dim_eval:w}
+\cs_set:Npn \dim_while_do:nn #1#2
+ {
+ \dim_compare:nT {#1}
+ {
+ #2
+ \dim_while_do:nn {#1} {#2}
+ }
+ }
+\cs_set:Npn \dim_until_do:nn #1#2
+ {
+ \dim_compare:nF {#1}
+ {
+ #2
+ \dim_until_do:nn {#1} {#2}
+ }
+ }
+\cs_set:Npn \dim_do_while:nn #1#2
+ {
+ #2
+ \dim_compare:nT {#1}
+ { \dim_do_while:nNnn {#1} {#2} }
+ }
+\cs_set:Npn \dim_do_until:nn #1#2
+ {
+ #2
+ \dim_compare:nF {#1}
+ { \dim_do_until:nn {#1} {#2} }
+ }
+\cs_set:Npn \dim_while_do:nNnn #1#2#3#4
+ {
+ \dim_compare:nNnT {#1} #2 {#3}
+ {
+ #4
+ \dim_while_do:nNnn {#1} #2 {#3} {#4}
+ }
+ }
+\cs_set:Npn \dim_until_do:nNnn #1#2#3#4
+ {
+ \dim_compare:nNnF {#1} #2 {#3}
+ {
+ #4
+ \dim_until_do:nNnn {#1} #2 {#3} {#4}
+ }
+ }
+\cs_set:Npn \dim_do_while:nNnn #1#2#3#4
+ {
+ #4
+ \dim_compare:nNnT {#1} #2 {#3}
+ { \dim_do_while:nNnn {#1} #2 {#3} {#4} }
+ }
+\cs_set:Npn \dim_do_until:nNnn #1#2#3#4
+ {
+ #4
+ \dim_compare:nNnF {#1} #2 {#3}
+ { \dim_do_until:nNnn {#1} #2 {#3} {#4} }
+ }
+\cs_new_nopar:Npn \dim_eval:n #1
+ { \dim_use:N \dim_eval:w #1 \dim_eval_end: }
+\cs_new_eq:NN \dim_use:N \tex_the:D
+\cs_generate_variant:Nn \dim_use:N { c }
+\cs_new_eq:NN \dim_show:N \kernel_register_show:N
+\cs_generate_variant:Nn \dim_show:N { c }
+\cs_new_eq:NN \c_zero_dim \z@
+\cs_new_eq:NN \c_max_dim \maxdimen
+\dim_new:N \l_tmpa_dim
+\dim_new:N \l_tmpb_dim
+\dim_new:N \l_tmpc_dim
+\dim_new:N \g_tmpa_dim
+\dim_new:N \g_tmpb_dim
+\cs_new_protected_nopar:Npn \skip_new:N #1
+ {
+ \chk_if_free_cs:N #1
+ \newskip #1
+ }
+\cs_generate_variant:Nn \skip_new:N { c }
+\cs_new_protected_nopar:Npn \skip_zero:N #1 { #1 \c_zero_skip }
+\cs_new_protected_nopar:Npn \skip_gzero:N { \pref_global:D \skip_zero:N }
+\cs_generate_variant:Nn \skip_zero:N { c }
+\cs_generate_variant:Nn \skip_gzero:N { c }
+\cs_new_protected_nopar:Npn \skip_set:Nn #1#2
+ { #1 ~ \etex_glueexpr:D #2 \scan_stop: }
+\cs_new_protected_nopar:Npn \skip_gset:Nn { \pref_global:D \skip_set:Nn }
+\cs_generate_variant:Nn \skip_set:Nn { c }
+\cs_generate_variant:Nn \skip_gset:Nn { c }
+\cs_new_protected_nopar:Npn \skip_set_eq:NN #1#2 { #1 = #2 }
+\cs_generate_variant:Nn \skip_set_eq:NN { c }
+\cs_generate_variant:Nn \skip_set_eq:NN { Nc , cc }
+\cs_new_protected_nopar:Npn \skip_gset_eq:NN #1#2 { \pref_global:D #1 = #2 }
+\cs_generate_variant:Nn \skip_gset_eq:NN { c }
+\cs_generate_variant:Nn \skip_gset_eq:NN { Nc , cc }
+\cs_new_protected_nopar:Npn \skip_add:Nn #1#2
+ { \tex_advance:D #1 by \etex_glueexpr:D #2 \scan_stop: }
+\cs_new_protected_nopar:Npn \skip_gadd:Nn { \pref_global:D \skip_add:Nn }
+\cs_generate_variant:Nn \skip_add:Nn { c }
+\cs_generate_variant:Nn \skip_gadd:Nn { c }
+\cs_new_protected_nopar:Npn \skip_sub:Nn #1#2
+ { \tex_advance:D #1 by - \etex_glueexpr:D #2 \scan_stop: }
+\cs_new_protected_nopar:Npn \skip_gsub:Nn { \pref_global:D \skip_sub:Nn }
+\cs_generate_variant:Nn \skip_sub:Nn { c }
+\cs_generate_variant:Nn \skip_gsub:Nn { c }
+\prg_new_conditional:Npnn \skip_if_eq:nn #1#2 { p , T , F , TF }
+ {
+ \if_int_compare:w
+ \pdftex_strcmp:D { \skip_eval:n { #1 } } { \skip_eval:n { #2 } }
+ = \c_zero
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\prg_new_conditional:Npnn \skip_if_infinite_glue:n #1 { p , T , F , TF }
+ {
+ \bool_if:nTF
+ {
+ \int_compare_p:nNn { \etex_gluestretchorder:D #1 } > \c_zero ||
+ \int_compare_p:nNn { \etex_glueshrinkorder:D #1 } > \c_zero
+ }
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+\cs_new_nopar:Npn \skip_eval:n #1
+ { \skip_use:N \etex_glueexpr:D #1 \scan_stop: }
+\cs_new_eq:NN \skip_use:N \tex_the:D
+\cs_generate_variant:Nn \skip_use:N { c }
+\cs_new_eq:NN \skip_horizontal:N \tex_hskip:D
+\cs_new_nopar:Npn \skip_horizontal:n #1
+ { \skip_horizontal:N \etex_glueexpr:D #1 \scan_stop: }
+\cs_new_eq:NN \skip_vertical:N \tex_vskip:D
+\cs_new_nopar:Npn \skip_vertical:n #1
+ { \skip_vertical:N \etex_glueexpr:D #1 \scan_stop: }
+\cs_generate_variant:Nn \skip_horizontal:N { c }
+\cs_generate_variant:Nn \skip_vertical:N { c }
+\cs_new_eq:NN \skip_show:N \kernel_register_show:N
+\cs_generate_variant:Nn \skip_show:N { c }
+\cs_new_eq:NN \c_zero_skip \c_zero_dim
+\cs_new_eq:NN \c_max_skip \c_max_dim
+\skip_new:N \l_tmpa_skip
+\skip_new:N \l_tmpb_skip
+\skip_new:N \l_tmpc_skip
+\skip_new:N \g_tmpa_skip
+\skip_new:N \g_tmpb_skip
+\cs_new_protected_nopar:Npn \muskip_new:N #1
+ {
+ \chk_if_free_cs:N #1
+ \newmuskip #1
+ }
+\cs_generate_variant:Nn \muskip_new:N { c }
+\cs_new_protected_nopar:Npn \muskip_zero:N #1
+ { #1 \c_zero_muskip }
+\cs_new_protected_nopar:Npn \muskip_gzero:N { \pref_global:D \muskip_zero:N }
+\cs_generate_variant:Nn \muskip_zero:N { c }
+\cs_generate_variant:Nn \muskip_gzero:N { c }
+\cs_new_protected_nopar:Npn \muskip_set:Nn #1#2
+ { #1 ~ \etex_muexpr:D #2 \scan_stop: }
+\cs_new_protected_nopar:Npn \muskip_gset:Nn { \pref_global:D \muskip_set:Nn }
+\cs_generate_variant:Nn \muskip_set:Nn { c }
+\cs_generate_variant:Nn \muskip_gset:Nn { c }
+\cs_new_protected_nopar:Npn \muskip_set_eq:NN #1#2 { #1 = #2 }
+\cs_generate_variant:Nn \muskip_set_eq:NN { c }
+\cs_generate_variant:Nn \muskip_set_eq:NN { Nc , cc }
+\cs_new_protected_nopar:Npn \muskip_gset_eq:NN #1#2 { \pref_global:D #1 = #2 }
+\cs_generate_variant:Nn \muskip_gset_eq:NN { c }
+\cs_generate_variant:Nn \muskip_gset_eq:NN { Nc , cc }
+\cs_new_protected_nopar:Npn \muskip_add:Nn #1#2
+ { \tex_advance:D #1 by \etex_muexpr:D #2 \scan_stop: }
+\cs_new_protected_nopar:Npn \muskip_gadd:Nn { \pref_global:D \muskip_add:Nn }
+\cs_generate_variant:Nn \muskip_add:Nn { c }
+\cs_generate_variant:Nn \muskip_gadd:Nn { c }
+\cs_new_protected_nopar:Npn \muskip_sub:Nn #1#2
+ { \tex_advance:D #1 by - \etex_muexpr:D #2 \scan_stop: }
+\cs_new_protected_nopar:Npn \muskip_gsub:Nn { \pref_global:D \muskip_sub:Nn }
+\cs_generate_variant:Nn \muskip_sub:Nn { c }
+\cs_generate_variant:Nn \muskip_gsub:Nn { c }
+\cs_new_nopar:Npn \muskip_eval:n #1
+ { \muskip_use:N \etex_muexpr:D #1 \scan_stop: }
+\cs_new_eq:NN \muskip_use:N \tex_the:D
+\cs_generate_variant:Nn \muskip_use:N { c }
+\cs_new_eq:NN \muskip_show:N \kernel_register_show:N
+\cs_generate_variant:Nn \muskip_show:N { c }
+\cs_new_nopar:Npn \skip_split_finite_else_action:nnNN #1#2#3#4
+ {
+ \skip_if_infinite_glue:nTF {#1}
+ {
+ #3 = \c_zero_skip
+ #4 = \c_zero_skip
+ #2
+ }
+ {
+ #3 = \etex_gluestretch:D #1 \scan_stop:
+ #4 = \etex_glueshrink:D #1 \scan_stop:
+ }
+ }
+%%
+%%
+%% End of file `l3skip.sty'.
diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3tl.sty b/Master/texmf-dist/tex/latex/l3kernel/l3tl.sty
new file mode 100644
index 00000000000..34238f643f0
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/l3kernel/l3tl.sty
@@ -0,0 +1,628 @@
+%%
+%% This is file `l3tl.sty',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% l3tl.dtx (with options: `package')
+%%
+%% EXPERIMENTAL CODE
+%%
+%% Do not distribute this file without also distributing the
+%% source files specified above.
+%%
+%% Do not distribute a modified version of this file.
+%%
+%% File: l3tl.dtx Copyright (C) 1990-2011 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 "expl3 bundle" (The Work in LPPL)
+%% and all files in that bundle must be distributed together.
+%%
+%% The released version of this bundle is available from CTAN.
+%%
+%% -----------------------------------------------------------------------
+%%
+%% The development version of the bundle can be found at
+%%
+%% http://www.latex-project.org/svnroot/experimental/trunk/
+%%
+%% for those people who are interested.
+%%
+%%%%%%%%%%%
+%% NOTE: %%
+%%%%%%%%%%%
+%%
+%% Snapshots taken from the repository represent work in progress and may
+%% not work or may contain conflicting material! We therefore ask
+%% people _not_ to put them into distributions, archives, etc. without
+%% prior consultation with the LaTeX3 Project.
+%%
+%% -----------------------------------------------------------------------
+\RequirePackage{l3names}
+\GetIdInfo$Id: l3tl.dtx 2498 2011-07-09 17:51:47Z joseph $
+ {L3 Experimental token lists}
+\ProvidesExplPackage
+ {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
+\package_check_loaded_expl:
+\cs_new_protected_nopar:Npn \tl_new:N #1
+ {
+ \chk_if_free_cs:N #1
+ \cs_gset_eq:NN #1 \c_empty_tl
+ }
+\cs_generate_variant:Nn \tl_new:N { c }
+\cs_new_protected:Npn \tl_const:Nn #1#2
+ {
+ \chk_if_free_cs:N #1
+ \cs_gset_nopar:Npx #1 { \exp_not:n {#2} }
+ }
+\cs_new_protected:Npn \tl_const:Nx #1#2
+ {
+ \chk_if_free_cs:N #1
+ \cs_gset_nopar:Npx #1 {#2}
+ }
+\cs_generate_variant:Nn \tl_const:Nn { c }
+\cs_generate_variant:Nn \tl_const:Nx { c }
+\cs_new_protected_nopar:Npn \tl_clear:N #1
+ { \tl_set_eq:NN #1 \c_empty_tl }
+\cs_new_protected_nopar:Npn \tl_gclear:N #1
+ { \tl_gset_eq:NN #1 \c_empty_tl }
+\cs_generate_variant:Nn \tl_clear:N { c }
+\cs_generate_variant:Nn \tl_gclear:N { c }
+\cs_new_protected_nopar:Npn \tl_clear_new:N #1
+ { \cs_if_exist:NTF #1 { \tl_clear:N #1 } { \tl_new:N #1 } }
+\cs_new_protected_nopar:Npn \tl_gclear_new:N #1
+ { \cs_if_exist:NTF #1 { \tl_gclear:N #1 } { \tl_new:N #1 } }
+\cs_generate_variant:Nn \tl_clear_new:N { c }
+\cs_generate_variant:Nn \tl_gclear_new:N { c }
+\cs_new_eq:NN \tl_set_eq:NN \cs_set_eq:NN
+\cs_new_eq:NN \tl_set_eq:cN \cs_set_eq:cN
+\cs_new_eq:NN \tl_set_eq:Nc \cs_set_eq:Nc
+\cs_new_eq:NN \tl_set_eq:cc \cs_set_eq:cc
+\cs_new_eq:NN \tl_gset_eq:NN \cs_gset_eq:NN
+\cs_new_eq:NN \tl_gset_eq:cN \cs_gset_eq:cN
+\cs_new_eq:NN \tl_gset_eq:Nc \cs_gset_eq:Nc
+\cs_new_eq:NN \tl_gset_eq:cc \cs_gset_eq:cc
+\cs_new_protected:Npn \tl_set:Nn #1#2
+ { \cs_set_nopar:Npx #1 { \exp_not:n {#2} } }
+\cs_new_protected:Npn \tl_set:No #1#2
+ { \cs_set_nopar:Npx #1 { \exp_not:o {#2} } }
+\cs_new_protected:Npn \tl_set:Nx #1#2
+ { \cs_set_nopar:Npx #1 {#2} }
+\cs_new_protected:Npn \tl_gset:Nn #1#2
+ { \cs_gset_nopar:Npx #1 { \exp_not:n {#2} } }
+\cs_new_protected:Npn \tl_gset:No #1#2
+ { \cs_gset_nopar:Npx #1 { \exp_not:o {#2} } }
+\cs_new_protected:Npn \tl_gset:Nx #1#2
+ { \cs_gset_nopar:Npx #1 {#2} }
+\cs_generate_variant:Nn \tl_set:Nn { NV , Nv , Nf }
+\cs_generate_variant:Nn \tl_set:Nx { c }
+\cs_generate_variant:Nn \tl_set:Nn { c, co , cV , cv , cf }
+\cs_generate_variant:Nn \tl_gset:Nn { NV , Nv , Nf }
+\cs_generate_variant:Nn \tl_gset:Nx { c }
+\cs_generate_variant:Nn \tl_gset:Nn { c, co , cV , cv , cf }
+\cs_new_protected:Npn \tl_put_left:Nn #1#2
+ { \cs_set_nopar:Npx #1 { \exp_not:n {#2} \exp_not:o #1 } }
+\cs_new_protected:Npn \tl_put_left:NV #1#2
+ { \cs_set_nopar:Npx #1 { \exp_not:V #2 \exp_not:o #1 } }
+\cs_new_protected:Npn \tl_put_left:No #1#2
+ { \cs_set_nopar:Npx #1 { \exp_not:o {#2} \exp_not:o #1 } }
+\cs_new_protected:Npn \tl_put_left:Nx #1#2
+ { \cs_set_nopar:Npx #1 { #2 \exp_not:o #1 } }
+\cs_new_protected:Npn \tl_gput_left:Nn #1#2
+ { \cs_gset_nopar:Npx #1 { \exp_not:n {#2} \exp_not:o #1 } }
+\cs_new_protected:Npn \tl_gput_left:NV #1#2
+ { \cs_gset_nopar:Npx #1 { \exp_not:V #2 \exp_not:o #1 } }
+\cs_new_protected:Npn \tl_gput_left:No #1#2
+ { \cs_gset_nopar:Npx #1 { \exp_not:o {#2} \exp_not:o #1 } }
+\cs_new_protected:Npn \tl_gput_left:Nx #1#2
+ { \cs_gset_nopar:Npx #1 { #2 \exp_not:o {#1} } }
+\cs_generate_variant:Nn \tl_put_left:Nn { c }
+\cs_generate_variant:Nn \tl_put_left:NV { c }
+\cs_generate_variant:Nn \tl_put_left:No { c }
+\cs_generate_variant:Nn \tl_put_left:Nx { c }
+\cs_generate_variant:Nn \tl_gput_left:Nn { c }
+\cs_generate_variant:Nn \tl_gput_left:NV { c }
+\cs_generate_variant:Nn \tl_gput_left:No { c }
+\cs_generate_variant:Nn \tl_gput_left:Nx { c }
+\cs_new_protected:Npn \tl_put_right:Nn #1#2
+ { \cs_set_nopar:Npx #1 { \exp_not:o #1 \exp_not:n {#2} } }
+\cs_new_protected:Npn \tl_put_right:NV #1#2
+ { \cs_set_nopar:Npx #1 { \exp_not:o #1 \exp_not:V #2 } }
+\cs_new_protected:Npn \tl_put_right:No #1#2
+ { \cs_set_nopar:Npx #1 { \exp_not:o #1 \exp_not:o {#2} } }
+\cs_new_protected:Npn \tl_put_right:Nx #1#2
+ { \cs_set_nopar:Npx #1 { \exp_not:o #1 #2 } }
+\cs_new_protected:Npn \tl_gput_right:Nn #1#2
+ { \cs_gset_nopar:Npx #1 { \exp_not:o #1 \exp_not:n {#2} } }
+\cs_new_protected:Npn \tl_gput_right:NV #1#2
+ { \cs_gset_nopar:Npx #1 { \exp_not:o #1 \exp_not:V #2 } }
+\cs_new_protected:Npn \tl_gput_right:No #1#2
+ { \cs_gset_nopar:Npx #1 { \exp_not:o #1 \exp_not:o {#2} } }
+\cs_new_protected:Npn \tl_gput_right:Nx #1#2
+ { \cs_gset_nopar:Npx #1 { \exp_not:o {#1} #2 } }
+\cs_generate_variant:Nn \tl_put_right:Nn { c }
+\cs_generate_variant:Nn \tl_put_right:NV { c }
+\cs_generate_variant:Nn \tl_put_right:No { c }
+\cs_generate_variant:Nn \tl_put_right:Nx { c }
+\cs_generate_variant:Nn \tl_gput_right:Nn { c }
+\cs_generate_variant:Nn \tl_gput_right:NV { c }
+\cs_generate_variant:Nn \tl_gput_right:No { c }
+\cs_generate_variant:Nn \tl_gput_right:Nx { c }
+\group_begin:
+ \tex_lccode:D `\A = `\@ \scan_stop:
+ \tex_lccode:D `\B = `\@ \scan_stop:
+ \tex_catcode:D `\A = 8 \scan_stop:
+ \tex_catcode:D `\B = 3 \scan_stop:
+\tex_lowercase:D
+ {
+ \group_end:
+ \tl_const:Nn \c_tl_rescan_marker_tl { A B }
+ }
+\tl_new:N \l_tl_rescan_tl
+\cs_new_protected_nopar:Npn \tl_set_rescan:Nnn
+ { \tl_set_rescan_aux:NNnn \tl_set:Nn }
+\cs_new_protected_nopar:Npn \tl_gset_rescan:Nnn
+ { \tl_set_rescan_aux:NNnn \tl_gset:Nn }
+\cs_new_protected:Npn \tl_set_rescan_aux:NNnn #1#2#3#4
+ {
+ \group_begin:
+ \exp_args:No \etex_everyeof:D { \c_tl_rescan_marker_tl }
+ \tex_endlinechar:D \c_minus_one
+ #3
+ \tl_clear:N \l_tl_rescan_tl
+ \exp_after:wN \tl_rescan_aux:w \etex_scantokens:D {#4}
+ \exp_args:NNNo \group_end:
+ #1 #2 \l_tl_rescan_tl
+ }
+\cs_new_nopar:Npx \tl_rescan_aux:w
+ {
+ \cs_set_protected:Npn \exp_not:N \tl_rescan_aux:w ##1
+ \c_tl_rescan_marker_tl
+ { \tl_set:Nn \exp_not:N \l_tl_rescan_tl {##1} }
+ }
+\tl_rescan_aux:w
+\cs_generate_variant:Nn \tl_set_rescan:Nnn { Nno }
+\cs_generate_variant:Nn \tl_set_rescan:Nnn { c , cno }
+\cs_generate_variant:Nn \tl_gset_rescan:Nnn { Nno }
+\cs_generate_variant:Nn \tl_gset_rescan:Nnn { c , cno }
+\cs_new_protected_nopar:Npn \tl_set_rescan:Nnx
+ { \tl_set_rescan_aux:NNnx \tl_set:Nn }
+\cs_new_protected_nopar:Npn \tl_gset_rescan:Nnx
+ { \tl_set_rescan_aux:NNnx \tl_gset:Nn }
+\cs_new_protected_nopar:Npn \tl_set_rescan_aux:NNnx #1#2#3#4
+ {
+ \group_begin:
+ \etex_everyeof:D { \exp_not:N }
+ \tex_endlinechar:D \c_minus_one
+ #3
+ \tl_set:Nx \l_tl_rescan_tl { \etex_scantokens:D {#4} }
+ \exp_args:NNNo \group_end:
+ #1 #2 \l_tl_rescan_tl
+ }
+\cs_generate_variant:Nn \tl_set_rescan:Nnx { c }
+\cs_generate_variant:Nn \tl_gset_rescan:Nnx { c }
+\cs_new_protected:Npn \tl_rescan:nn #1#2
+ {
+ \group_begin:
+ \exp_args:No \etex_everyeof:D { \c_tl_rescan_marker_tl }
+ \tex_endlinechar:D \c_minus_one
+ #1
+ \exp_after:wN \tl_rescan_aux:w \etex_scantokens:D {#2}
+ \exp_args:No \group_end:
+ \l_tl_rescan_tl
+ }
+\cs_new_eq:NN \tl_to_lowercase:n \tex_lowercase:D
+\cs_new_eq:NN \tl_to_uppercase:n \tex_uppercase:D
+\tl_new:N \l_tl_replace_tl
+\cs_new_protected_nopar:Npn \tl_replace_once:Nnn
+ { \tl_replace_once_aux:NNnn \tl_set_eq:NN }
+\cs_new_protected_nopar:Npn \tl_greplace_once:Nnn
+ { \tl_replace_once_aux:NNnn \tl_gset_eq:NN }
+\cs_new_protected:Npn \tl_replace_once_aux:NNnn #1#2#3#4
+ {
+ \cs_set_protected:Npx \tl_tmp:w ##1 #3 ##2 \q_stop
+ {
+ \exp_not:N \quark_if_no_value:nF {##2}
+ {
+ \tl_set:No \exp_not:N \l_tl_replace_tl { ##1 \exp_not:n{#4} }
+ \exp_not:n
+ {
+ \cs_set_protected:Npn \tl_tmp:w ##1 \q_nil #3 \q_no_value
+ { \tl_put_right:No \l_tl_replace_tl {##1} }
+ }
+ \exp_not:n { \tl_tmp:w \prg_do_nothing: } ##2
+ \exp_not:n { #1 #2 \l_tl_replace_tl }
+ }
+ }
+ \exp_after:wN \tl_tmp:w \exp_after:wN \prg_do_nothing:
+ #2 \q_nil #3 \q_no_value \q_stop
+ }
+\cs_generate_variant:Nn \tl_replace_once:Nnn { c }
+\cs_generate_variant:Nn \tl_greplace_once:Nnn { c }
+\cs_new_protected_nopar:Npn \tl_replace_all:Nnn
+ { \tl_replace_all_aux:NNnn \tl_set_eq:NN }
+\cs_new_protected_nopar:Npn \tl_greplace_all:Nnn
+ { \tl_replace_all_aux:NNnn \tl_gset_eq:NN }
+\cs_new_protected:Npn \tl_replace_all_aux:NNnn #1#2#3#4
+ {
+ \tl_clear:N \l_tl_replace_tl
+ \cs_set_protected:Npx \tl_tmp:w ##1 #3 ##2 \q_stop
+ {
+ \exp_not:N \quark_if_no_value:nTF {##2}
+ {
+ \exp_not:n
+ {
+ \cs_set_protected:Npn \tl_tmp:w ##1 \q_nil ##2 \q_stop
+ { \tl_put_right:No \l_tl_replace_tl {##1} }
+ }
+ \exp_not:N \tl_tmp:w ##1 \exp_not:N \q_stop
+ }
+ {
+ \exp_not:n { \tl_put_right:No \l_tl_replace_tl }
+ { ##1 \exp_not:n{#4} }
+ \exp_not:n { \tl_tmp:w \prg_do_nothing: } ##2 \exp_not:N \q_stop
+ }
+ }
+ \exp_after:wN \tl_tmp:w \exp_after:wN \prg_do_nothing:
+ #2 \q_nil #3 \q_no_value \q_stop
+ #1 #2 \l_tl_replace_tl
+ }
+\cs_generate_variant:Nn \tl_replace_all:Nnn { c }
+\cs_generate_variant:Nn \tl_greplace_all:Nnn { c }
+\cs_new_protected_nopar:Npn \tl_remove_once:Nn #1#2
+ { \tl_replace_once:Nnn #1 {#2} { } }
+\cs_new_protected_nopar:Npn \tl_gremove_once:Nn #1#2
+ { \tl_greplace_once:Nnn #1 {#2} { } }
+\cs_generate_variant:Nn \tl_remove_once:Nn { c }
+\cs_generate_variant:Nn \tl_gremove_once:Nn { c }
+\cs_new_protected_nopar:Npn \tl_remove_all:Nn #1#2
+ { \tl_replace_all:Nnn #1 {#2} { } }
+\cs_new_protected_nopar:Npn \tl_gremove_all:Nn #1#2
+ { \tl_greplace_all:Nnn #1 {#2} { } }
+\cs_generate_variant:Nn \tl_remove_all:Nn { c }
+\cs_generate_variant:Nn \tl_gremove_all:Nn { c }
+\prg_new_conditional:Npnn \tl_if_blank:n #1 { p , T , F , TF }
+ { \tl_if_empty_return:o { \use_none:n #1 ? } }
+\cs_generate_variant:Nn \tl_if_blank_p:n { V }
+\cs_generate_variant:Nn \tl_if_blank:nT { V }
+\cs_generate_variant:Nn \tl_if_blank:nF { V }
+\cs_generate_variant:Nn \tl_if_blank:nTF { V }
+\cs_generate_variant:Nn \tl_if_blank_p:n { o }
+\cs_generate_variant:Nn \tl_if_blank:nT { o }
+\cs_generate_variant:Nn \tl_if_blank:nF { o }
+\cs_generate_variant:Nn \tl_if_blank:nTF { o }
+\prg_set_conditional:Npnn \tl_if_empty:N #1 { p , T , F , TF }
+ {
+ \if_meaning:w #1 \c_empty_tl
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\cs_generate_variant:Nn \tl_if_empty_p:N { c }
+\cs_generate_variant:Nn \tl_if_empty:NT { c }
+\cs_generate_variant:Nn \tl_if_empty:NF { c }
+\cs_generate_variant:Nn \tl_if_empty:NTF { c }
+\prg_new_conditional:Npnn \tl_if_empty:n #1 { p,TF,T,F} {
+ \exp_after:wN \if_meaning:w \exp_after:wN \q_nil \tl_to_str:n {#1} \q_nil
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+}
+\cs_generate_variant:Nn \tl_if_empty_p:n { V }
+\cs_generate_variant:Nn \tl_if_empty:nTF { V }
+\cs_generate_variant:Nn \tl_if_empty:nT { V }
+\cs_generate_variant:Nn \tl_if_empty:nF { V }
+\cs_new:Npn \tl_if_empty_return:o #1 {
+ \exp_after:wN \if_meaning:w \exp_after:wN \q_nil
+ \tl_to_str:n \exp_after:wN {#1} \q_nil
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+}
+\prg_new_conditional:Npnn \tl_if_empty:o #1 { p,TF,T,F}
+ { \tl_if_empty_return:o {#1} }
+\prg_new_conditional:Npnn \tl_if_eq:NN #1#2 { p , T , F , TF }
+ {
+ \if_meaning:w #1 #2
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\cs_generate_variant:Nn \tl_if_eq_p:NN { Nc , c , cc }
+\cs_generate_variant:Nn \tl_if_eq:NNTF { Nc , c , cc }
+\cs_generate_variant:Nn \tl_if_eq:NNT { Nc , c , cc }
+\cs_generate_variant:Nn \tl_if_eq:NNF { Nc , c , cc }
+\prg_new_protected_conditional:Npnn \tl_if_eq:nn #1#2 { T , F , TF }
+ {
+ \group_begin:
+ \tl_set:Nn \l_tl_tmpa_tl {#1}
+ \tl_set:Nn \l_tl_tmpb_tl {#2}
+ \if_meaning:w \l_tl_tmpa_tl \l_tl_tmpb_tl
+ \group_end:
+ \prg_return_true:
+ \else:
+ \group_end:
+ \prg_return_false:
+ \fi:
+ }
+\tl_new:N \l_tl_tmpa_tl
+\tl_new:N \l_tl_tmpb_tl
+\cs_new_protected_nopar:Npn \tl_if_in:NnT { \exp_args:No \tl_if_in:nnT }
+\cs_new_protected_nopar:Npn \tl_if_in:NnF { \exp_args:No \tl_if_in:nnF }
+\cs_new_protected_nopar:Npn \tl_if_in:NnTF { \exp_args:No \tl_if_in:nnTF }
+\cs_generate_variant:Nn \tl_if_in:NnT { c }
+\cs_generate_variant:Nn \tl_if_in:NnF { c }
+\cs_generate_variant:Nn \tl_if_in:NnTF { c }
+\prg_new_protected_conditional:Npnn \tl_if_in:nn #1#2 { T , F , TF }
+ {
+ \cs_set:Npn \tl_tmp:w ##1 #2 { }
+ \tl_if_empty:oTF { \tl_tmp:w #1 {} {} #2 }
+ { \prg_return_false: } { \prg_return_true: }
+ }
+\cs_generate_variant:Nn \tl_if_in:nnT { V }
+\cs_generate_variant:Nn \tl_if_in:nnF { V }
+\cs_generate_variant:Nn \tl_if_in:nnTF { V }
+\cs_generate_variant:Nn \tl_if_in:nnT { o }
+\cs_generate_variant:Nn \tl_if_in:nnF { o }
+\cs_generate_variant:Nn \tl_if_in:nnTF { o }
+\cs_generate_variant:Nn \tl_if_in:nnT { no }
+\cs_generate_variant:Nn \tl_if_in:nnF { no }
+\cs_generate_variant:Nn \tl_if_in:nnTF { no }
+\prg_new_conditional:Npnn \tl_if_single:n #1 { p , T , F , TF }
+ {
+ \tl_if_blank:nTF {#1}
+ { \tl_if_empty:nTF {#1} { \prg_return_false: } { \prg_return_true: } }
+ { \tl_if_single_aux:n {#1} }
+ }
+\prg_new_conditional:Npnn \tl_if_single:N #1 { p , T , F , TF }
+ {
+ \tl_if_blank:oTF #1
+ { \tl_if_empty:NTF #1 { \prg_return_false: } { \prg_return_true: } }
+ { \exp_args:No \tl_if_single_aux:n {#1} }
+ }
+\cs_new:Npn \tl_if_single_aux:n #1
+ { \tl_if_empty_return:o { \use_none:n #1 } }
+\cs_new:Npn \tl_map_function:nN #1#2
+ { \tl_map_function_aux:Nn #2 #1 \q_recursion_tail \q_recursion_stop }
+\cs_new_nopar:Npn \tl_map_function:NN #1#2
+ {
+ \exp_after:wN \tl_map_function_aux:Nn
+ \exp_after:wN #2 #1 \q_recursion_tail \q_recursion_stop
+ }
+\cs_new:Npn \tl_map_function_aux:Nn #1#2
+ {
+ \quark_if_recursion_tail_stop:n {#2}
+ #1 {#2} \tl_map_function_aux:Nn #1
+ }
+\cs_generate_variant:Nn \tl_map_function:NN { c }
+\cs_new_protected:Npn \tl_map_inline:nn #1#2
+ {
+ \int_gincr:N \g_tl_inline_level_int
+ \cs_gset:cpn { tl_map_inline_ \int_use:N \g_tl_inline_level_int :n }
+ ##1 {#2}
+ \exp_args:Nc \tl_map_function_aux:Nn
+ { tl_map_inline_ \int_use:N \g_tl_inline_level_int :n }
+ #1 \q_recursion_tail \q_recursion_stop
+ \int_gdecr:N \g_tl_inline_level_int
+ }
+\cs_new_protected:Npn \tl_map_inline:Nn #1#2
+ {
+ \int_gincr:N \g_tl_inline_level_int
+ \cs_gset:cpn { tl_map_inline_ \int_use:N \g_tl_inline_level_int :n }
+ ##1 {#2}
+ \exp_last_unbraced:NcV \tl_map_function_aux:Nn
+ { tl_map_inline_ \int_use:N \g_tl_inline_level_int :n }
+ #1 \q_recursion_tail\q_recursion_stop
+ \int_gdecr:N \g_tl_inline_level_int
+ }
+\cs_generate_variant:Nn \tl_map_inline:Nn { c }
+\cs_new_protected:Npn \tl_map_variable:nNn #1#2#3
+ { \tl_map_variable_aux:Nnn #2 {#3} #1 \q_recursion_tail \q_recursion_stop }
+\cs_new_protected_nopar:Npn \tl_map_variable:NNn
+ { \exp_args:No \tl_map_variable:nNn }
+\cs_new_protected:Npn \tl_map_variable_aux:Nnn #1#2#3
+ {
+ \tl_set:Nn #1 {#3}
+ \quark_if_recursion_tail_stop:N #1
+ #2 \tl_map_variable_aux:Nnn #1 {#2}
+ }
+\cs_generate_variant:Nn \tl_map_variable:NNn { c }
+\cs_new_eq:NN \tl_map_break: \use_none_delimit_by_q_recursion_stop:w
+\cs_new_eq:NN \tl_to_str:n \etex_detokenize:D
+\cs_new_nopar:Npn \tl_to_str:N #1 { \etex_detokenize:D \exp_after:wN {#1} }
+\cs_generate_variant:Nn \tl_to_str:N { c }
+\cs_new_eq:NN \tl_use:N \prg_do_nothing:
+\cs_new_nopar:Npn \tl_use:c #1
+ {
+ \if_cs_exist:w #1 \cs_end:
+ \cs:w #1 \exp_after:wN \cs_end:
+ \else:
+ \exp_after:wN \tl_error_message:
+ \fi:
+ }
+\group_begin:
+\tex_catcode:D `\! = 11 \scan_stop:
+\tex_catcode:D `\ = 11\scan_stop:%
+\cs_gset_nopar:Npn\tl_error_message:{\undefined variable name!}%
+\group_end:%
+\cs_new:Npn \tl_length:n #1
+ {
+ \int_eval:n
+ { 0 \tl_map_function:nN {#1} \tl_length_aux:n }
+ }
+\cs_new_nopar:Npn \tl_length:N #1
+ {
+ \int_eval:n
+ { 0 \tl_map_function:NN #1 \tl_length_aux:n }
+ }
+\cs_new:Npn \tl_length_aux:n #1 { + 1 }
+\cs_generate_variant:Nn \tl_length:n { V , o }
+\cs_generate_variant:Nn \tl_length:N { c }
+\cs_new:Npn \tl_reverse:n #1
+ { \tl_reverse_aux:nN { } #1 \q_recursion_tail \q_recursion_stop }
+\cs_new:Npn \tl_reverse_aux:nN #1#2
+ {
+ \quark_if_recursion_tail_stop_do:nn {#2} {#1}
+ \tl_reverse_aux:nN { #2 #1 }
+ }
+\cs_generate_variant:Nn \tl_reverse:n {V,o}
+\cs_new_protected_nopar:Npn \tl_reverse:N #1
+ { \tl_set:Nf #1 { \tl_reverse:o { #1 \exp_stop_f: } } }
+\cs_generate_variant:Nn \tl_reverse:N { c }
+\cs_new:Npn \tl_trim_spaces:n #1
+ {
+ \etex_unexpanded:D \exp_after:wN \exp_after:wN \exp_after:wN
+ { \tl_trim_spaces_exp:n {#1} }
+ }
+\cs_new_protected:Npn \tl_trim_spaces:N #1
+ { \tl_set:Nx #1 { \exp_after:wN \tl_trim_spaces:n \exp_after:wN {#1} } }
+\cs_new_protected:Npn \tl_gtrim_spaces:N #1
+ { \tl_gset:Nx #1 { \exp_after:wN \tl_trim_spaces:n \exp_after:wN {#1} } }
+\group_begin:
+ \tex_catcode:D `\Q = 3 \scan_stop:
+ \cs_new:Npn \tl_trim_spaces_exp:n #1
+ { \tex_romannumeral:D - `0 \tl_trim_spaces_aux_i:w \exp_not:N #1 Q ~ Q }
+ \cs_new:Npn \tl_trim_spaces_aux_i:w #1 ~ Q { \tl_trim_spaces_aux_ii:w #1 Q }
+ \cs_new:Npn \tl_trim_spaces_aux_ii:w #1 Q #2 {#1}
+\group_end:
+\cs_generate_variant:Nn \tl_trim_spaces:N { c }
+\cs_generate_variant:Nn \tl_gtrim_spaces:N { c }
+\cs_new:Npn \tl_head:n #1 { \tl_head:w #1 \q_stop }
+\cs_new:Npn \tl_tail:n #1 { \tl_tail:w #1 \q_stop }
+\cs_new:Npn \tl_head:w #1#2 \q_stop {#1}
+\cs_new:Npn \tl_tail:w #1#2 \q_stop {#2}
+\cs_generate_variant:Nn \tl_head:n { V , v , f }
+\cs_generate_variant:Nn \tl_tail:n { V , v , f }
+\prg_new_conditional:Npnn \tl_if_head_eq_meaning:nN #1#2 { p , T , F , TF }
+ {
+ \exp_after:wN \if_meaning:w \tl_head:w #1 \q_stop #2
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\prg_new_conditional:Npnn \tl_if_head_eq_charcode:nN #1#2 { p , T , F , TF }
+ {
+ \exp_after:wN \if:w
+ \exp_after:wN \exp_not:N \tl_head:w #1 \q_stop \exp_not:N #2
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\cs_generate_variant:Nn \tl_if_head_eq_charcode_p:nN { f }
+\cs_generate_variant:Nn \tl_if_head_eq_charcode:nNTF { f }
+\cs_generate_variant:Nn \tl_if_head_eq_charcode:nNT { f }
+\cs_generate_variant:Nn \tl_if_head_eq_charcode:nNF { f }
+\prg_new_conditional:Npnn \tl_if_head_eq_catcode:nN #1#2 { p , T , F , TF }
+ {
+ \exp_after:wN \if_catcode:w \exp_after:wN \exp_not:N
+ \tl_head:w #1 \q_stop \exp_not:N #2
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+\cs_new_protected:Npn \tl_show:N #1 { \cs_show:N #1 }
+\cs_generate_variant:Nn \tl_show:N { c }
+\cs_new_eq:NN \tl_show:n \etex_showtokens:D
+\tl_const:Nx \c_job_name_tl { \tex_jobname:D }
+\tl_const:Nn \c_empty_tl { }
+\tl_const:Nn \c_space_tl { ~ }
+\tl_new:N \g_tmpa_tl
+\tl_new:N \g_tmpb_tl
+\tl_new:N \l_tmpa_tl
+\tl_new:N \l_tmpb_tl
+\cs_new:Npn \tl_if_single_item:nTF #1
+ { \str_if_eq:onTF { \use_ii:nn #1 {?} ? } {??} }
+\cs_new:Npn \tl_if_single_item:nT #1
+ { \str_if_eq:onT { \use_ii:nn #1 {?} ? } {??} }
+\cs_new:Npn \tl_if_single_item:nF #1
+ { \str_if_eq:onF { \use_ii:nn #1 {?} ? } {??} }
+\cs_new:Npn \tl_if_single_item_p:n #1
+ { \str_if_eq_p:on { \use_ii:nn #1 {?} ? } {??} }
+\prg_new_conditional:Npnn \tl_if_head_begin_group:n #1 { p , T , F , TF }
+ {
+ \exp_after:wN \use_none:n
+ \exp_after:wN {
+ \exp_after:wN {
+ \token_to_str:N #1 .
+ }
+ \prg_return_true: \exp_after:wN \use_none:nn \token_to_str:N
+ }
+ \prg_return_false:
+ }
+\prg_new_conditional:Npnn \tl_if_head_eq_space:n #1 { p , T , F , TF }
+ {
+ \if_false: { \fi:
+ \tl_if_head_eq_space_aux:w \prg_do_nothing: #1 ? ~ }
+ }
+\cs_new:Npn \tl_if_head_eq_space_aux:w #1 ~ %
+ {
+ \tl_if_empty_return:o { #1 }
+ \exp_after:wN \use_none:n \exp_after:wN { \if_false: } \fi:
+ }
+\prg_new_conditional:Npnn \tl_if_single_token:n #1 { p , T , F , TF }
+ {
+ \tl_if_head_eq_space:nTF {#1}
+ {
+ \str_if_eq:nnTF {#1} {~}
+ \prg_return_true: \prg_return_false:
+ }
+ {
+ \str_if_eq:onTF { \use_none:n #1 ? } {?}
+ {
+ \tl_if_head_begin_group:nTF {#1}
+ \prg_return_false: \prg_return_true:
+ }
+ \prg_return_false:
+ }
+ }
+\cs_new_protected:Npn \tl_new:Nn #1#2
+ {
+ \tl_new:N #1
+ \tl_gset:Nn #1 {#2}
+ }
+\cs_generate_variant:Nn \tl_new:Nn { c }
+\cs_generate_variant:Nn \tl_new:Nn { Nx }
+\cs_new_protected_nopar:Npn \tl_gset:Nc
+ { \pref_global:D \tl_set:Nc }
+\cs_new_protected_nopar:Npn \tl_set:Nc #1#2
+ { \tl_set:No #1 { \cs:w #2 \cs_end: } }
+\cs_new_eq:NN \tl_replace_in:Nnn \tl_replace_once:Nnn
+\cs_new_eq:NN \tl_replace_in:cnn \tl_replace_once:cnn
+\cs_new_eq:NN \tl_greplace_in:Nnn \tl_greplace_once:Nnn
+\cs_new_eq:NN \tl_greplace_in:cnn \tl_greplace_once:cnn
+\cs_new_eq:NN \tl_replace_all_in:Nnn \tl_replace_all:Nnn
+\cs_new_eq:NN \tl_replace_all_in:cnn \tl_replace_all:cnn
+\cs_new_eq:NN \tl_greplace_all_in:Nnn \tl_greplace_all:Nnn
+\cs_new_eq:NN \tl_greplace_all_in:cnn \tl_greplace_all:cnn
+\cs_new_eq:NN \tl_remove_in:Nn \tl_remove_once:Nn
+\cs_new_eq:NN \tl_remove_in:cn \tl_remove_once:cn
+\cs_new_eq:NN \tl_gremove_in:Nn \tl_gremove_once:Nn
+\cs_new_eq:NN \tl_gremove_in:cn \tl_gremove_once:cn
+\cs_new_eq:NN \tl_remove_all_in:Nn \tl_remove_all:Nn
+\cs_new_eq:NN \tl_remove_all_in:cn \tl_remove_all:cn
+\cs_new_eq:NN \tl_gremove_all_in:Nn \tl_gremove_all:Nn
+\cs_new_eq:NN \tl_gremove_all_in:cn \tl_gremove_all:cn
+\cs_new_eq:NN \tl_elt_count:n \tl_length:n
+\cs_new_eq:NN \tl_elt_count:V \tl_length:V
+\cs_new_eq:NN \tl_elt_count:o \tl_length:o
+\cs_new_eq:NN \tl_elt_count:N \tl_length:N
+\cs_new_eq:NN \tl_elt_count:c \tl_length:c
+\cs_new_eq:NN \tl_head_i:n \tl_head:n
+\cs_new_eq:NN \tl_head_i:w \tl_head:w
+\cs_new:Npn \tl_head_iii:n #1 { \tl_head_iii:w #1 \q_stop }
+\cs_generate_variant:Nn \tl_head_iii:n { f }
+\cs_new:Npn \tl_head_iii:w #1#2#3#4 \q_stop {#1#2#3}
+%%
+%%
+%% End of file `l3tl.sty'.
diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3token.sty b/Master/texmf-dist/tex/latex/l3kernel/l3token.sty
new file mode 100644
index 00000000000..c4ca0549b2f
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/l3kernel/l3token.sty
@@ -0,0 +1,739 @@
+%%
+%% This is file `l3token.sty',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% l3token.dtx (with options: `package')
+%%
+%% EXPERIMENTAL CODE
+%%
+%% Do not distribute this file without also distributing the
+%% source files specified above.
+%%
+%% Do not distribute a modified version of this file.
+%%
+%% File: l3token.dtx Copyright (C) 2005-2011 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 "expl3 bundle" (The Work in LPPL)
+%% and all files in that bundle must be distributed together.
+%%
+%% The released version of this bundle is available from CTAN.
+%%
+%% -----------------------------------------------------------------------
+%%
+%% The development version of the bundle can be found at
+%%
+%% http://www.latex-project.org/svnroot/experimental/trunk/
+%%
+%% for those people who are interested.
+%%
+%%%%%%%%%%%
+%% NOTE: %%
+%%%%%%%%%%%
+%%
+%% Snapshots taken from the repository represent work in progress and may
+%% not work or may contain conflicting material! We therefore ask
+%% people _not_ to put them into distributions, archives, etc. without
+%% prior consultation with the LaTeX3 Project.
+%%
+%% -----------------------------------------------------------------------
+\RequirePackage{l3names}
+\GetIdInfo$Id: l3token.dtx 2491 2011-07-02 11:49:37Z joseph $
+ {L3 Experimental token manipulation}
+%% \begin{function}[EXP,pTF]{\token_if_protected_long_macro:N}
+\ProvidesExplPackage
+ {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
+\package_check_loaded_expl:
+\cs_new_protected_nopar:Npn \char_set_catcode:nn #1#2
+ { \tex_catcode:D #1 = \int_eval:w #2 \int_eval_end: }
+\cs_new_nopar:Npn \char_value_catcode:n #1
+ { \tex_the:D \tex_catcode:D \int_eval:w #1\int_eval_end: }
+\cs_new_nopar:Npn \char_show_value_catcode:n #1
+ { \tex_showthe:D \tex_catcode:D \int_eval:w #1 \int_eval_end: }
+\cs_new_protected_nopar:Npn \char_set_catcode_escape:N #1
+ { \char_set_catcode:nn { `#1 } \c_zero }
+\cs_new_protected_nopar:Npn \char_set_catcode_group_begin:N #1
+ { \char_set_catcode:nn { `#1 } \c_one }
+\cs_new_protected_nopar:Npn \char_set_catcode_group_end:N #1
+ { \char_set_catcode:nn { `#1 } \c_two }
+\cs_new_protected_nopar:Npn \char_set_catcode_math_toggle:N #1
+ { \char_set_catcode:nn { `#1 } \c_three }
+\cs_new_protected_nopar:Npn \char_set_catcode_alignment:N #1
+ { \char_set_catcode:nn { `#1 } \c_four }
+\cs_new_protected_nopar:Npn \char_set_catcode_end_line:N #1
+ { \char_set_catcode:nn { `#1 } \c_five }
+\cs_new_protected_nopar:Npn \char_set_catcode_parameter:N #1
+ { \char_set_catcode:nn { `#1 } \c_six }
+\cs_new_protected_nopar:Npn \char_set_catcode_math_superscript:N #1
+ { \char_set_catcode:nn { `#1 } \c_seven }
+\cs_new_protected_nopar:Npn \char_set_catcode_math_subscript:N #1
+ { \char_set_catcode:nn { `#1 } \c_eight }
+\cs_new_protected_nopar:Npn \char_set_catcode_ignore:N #1
+ { \char_set_catcode:nn { `#1 } \c_nine }
+\cs_new_protected_nopar:Npn \char_set_catcode_space:N #1
+ { \char_set_catcode:nn { `#1 } \c_ten }
+\cs_new_protected_nopar:Npn \char_set_catcode_letter:N #1
+ { \char_set_catcode:nn { `#1 } \c_eleven }
+\cs_new_protected_nopar:Npn \char_set_catcode_other:N #1
+ { \char_set_catcode:nn { `#1 } \c_twelve }
+\cs_new_protected_nopar:Npn \char_set_catcode_active:N #1
+ { \char_set_catcode:nn { `#1 } \c_thirteen }
+\cs_new_protected_nopar:Npn \char_set_catcode_comment:N #1
+ { \char_set_catcode:nn { `#1 } \c_fourteen }
+\cs_new_protected_nopar:Npn \char_set_catcode_invalid:N #1
+ { \char_set_catcode:nn { `#1 } \c_fifteen }
+\cs_new_protected_nopar:Npn \char_set_catcode_escape:n #1
+ { \char_set_catcode:nn {#1} \c_zero }
+\cs_new_protected_nopar:Npn \char_set_catcode_group_begin:n #1
+ { \char_set_catcode:nn {#1} \c_one }
+\cs_new_protected_nopar:Npn \char_set_catcode_group_end:n #1
+ { \char_set_catcode:nn {#1} \c_two }
+\cs_new_protected_nopar:Npn \char_set_catcode_math_toggle:n #1
+ { \char_set_catcode:nn {#1} \c_three }
+\cs_new_protected_nopar:Npn \char_set_catcode_alignment:n #1
+ { \char_set_catcode:nn {#1} \c_four }
+\cs_new_protected_nopar:Npn \char_set_catcode_end_line:n #1
+ { \char_set_catcode:nn {#1} \c_five }
+\cs_new_protected_nopar:Npn \char_set_catcode_parameter:n #1
+ { \char_set_catcode:nn {#1} \c_six }
+\cs_new_protected_nopar:Npn \char_set_catcode_math_superscript:n #1
+ { \char_set_catcode:nn {#1} \c_seven }
+\cs_new_protected_nopar:Npn \char_set_catcode_math_subscript:n #1
+ { \char_set_catcode:nn {#1} \c_eight }
+\cs_new_protected_nopar:Npn \char_set_catcode_ignore:n #1
+ { \char_set_catcode:nn {#1} \c_nine }
+\cs_new_protected_nopar:Npn \char_set_catcode_space:n #1
+ { \char_set_catcode:nn {#1} \c_ten }
+\cs_new_protected_nopar:Npn \char_set_catcode_letter:n #1
+ { \char_set_catcode:nn {#1} \c_eleven }
+\cs_new_protected_nopar:Npn \char_set_catcode_other:n #1
+ { \char_set_catcode:nn {#1} \c_twelve }
+\cs_new_protected_nopar:Npn \char_set_catcode_active:n #1
+ { \char_set_catcode:nn {#1} \c_thirteen }
+\cs_new_protected_nopar:Npn \char_set_catcode_comment:n #1
+ { \char_set_catcode:nn {#1} \c_fourteen }
+\cs_new_protected_nopar:Npn \char_set_catcode_invalid:n #1
+ { \char_set_catcode:nn {#1} \c_fifteen }
+\cs_new_protected_nopar:Npn \char_set_mathcode:nn #1#2
+ { \tex_mathcode:D #1 = \int_eval:w #2 \int_eval_end: }
+\cs_new_nopar:Npn \char_value_mathcode:n #1
+ { \tex_the:D \tex_mathcode:D \int_eval:w #1\int_eval_end: }
+\cs_new_nopar:Npn \char_show_value_mathcode:n #1
+ { \tex_showthe:D \tex_mathcode:D \int_eval:w #1 \int_eval_end: }
+\cs_new_protected_nopar:Npn \char_set_lccode:nn #1#2
+ { \tex_lccode:D #1 = \int_eval:w #2 \int_eval_end: }
+\cs_new_nopar:Npn \char_value_lccode:n #1
+ { \tex_the:D \tex_lccode:D \int_eval:w #1\int_eval_end: }
+\cs_new_nopar:Npn \char_show_value_lccode:n #1
+ { \tex_showthe:D \tex_lccode:D \int_eval:w #1 \int_eval_end: }
+\cs_new_protected_nopar:Npn \char_set_uccode:nn #1#2
+ { \tex_uccode:D #1 = \int_eval:w #2 \int_eval_end: }
+\cs_new_nopar:Npn \char_value_uccode:n #1
+ { \tex_the:D \tex_uccode:D \int_eval:w #1\int_eval_end: }
+\cs_new_nopar:Npn \char_show_value_uccode:n #1
+ { \tex_showthe:D \tex_uccode:D \int_eval:w #1 \int_eval_end: }
+\cs_new_protected_nopar:Npn \char_set_sfcode:nn #1#2
+ { \tex_sfcode:D #1 = \int_eval:w #2 \int_eval_end: }
+\cs_new_nopar:Npn \char_value_sfcode:n #1
+ { \tex_the:D \tex_sfcode:D \int_eval:w #1\int_eval_end: }
+\cs_new_nopar:Npn \char_show_value_sfcode:n #1
+ { \tex_showthe:D \tex_sfcode:D \int_eval:w #1 \int_eval_end: }
+\cs_new_protected_nopar:Npn \token_new:Nn #1#2 { \cs_new_eq:NN #1 #2 }
+\cs_new_eq:NN \c_group_begin_token {
+\cs_new_eq:NN \c_group_end_token }
+\group_begin:
+ \char_set_catcode_math_toggle:N \*
+ \token_new:Nn \c_math_toggle_token { * }
+ \char_set_catcode_alignment:N \*
+ \token_new:Nn \c_alignment_token { * }
+ \token_new:Nn \c_parameter_token { # }
+ \token_new:Nn \c_math_superscript_token { ^ }
+ \char_set_catcode_math_subscript:N \*
+ \token_new:Nn \c_math_subscript_token { * }
+ \token_new:Nn \c_space_token { ~ }
+ \token_new:Nn \c_catcode_letter_token { a }
+ \token_new:Nn \c_catcode_other_token { 1 }
+\group_end:
+\group_begin:
+ \char_set_catcode_active:N \*
+ \cs_new_nopar:Npn \c_catcode_active_tl { \exp_not:N * }
+\group_end:
+\prg_new_conditional:Npnn \token_if_group_begin:N #1 { p , T , F , TF }
+ {
+ \if_catcode:w \exp_not:N #1 \c_group_begin_token
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+\prg_new_conditional:Npnn \token_if_group_end:N #1 { p , T , F , TF }
+ {
+ \if_catcode:w \exp_not:N #1 \c_group_end_token
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+\prg_new_conditional:Npnn \token_if_math_toggle:N #1 { p , T , F , TF }
+ {
+ \if_catcode:w \exp_not:N #1 \c_math_toggle_token
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+\prg_new_conditional:Npnn \token_if_alignment:N #1 { p , T , F , TF }
+ {
+ \if_catcode:w \exp_not:N #1 \c_alignment_token
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+\group_begin:
+\cs_set_eq:NN \c_parameter_token \scan_stop:
+\prg_new_conditional:Npnn \token_if_parameter:N #1 { p , T , F , TF }
+ {
+ \if_catcode:w \exp_not:N #1 \c_parameter_token
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+\group_end:
+\prg_new_conditional:Npnn \token_if_math_superscript:N #1 { p , T , F , TF }
+ {
+ \if_catcode:w \exp_not:N #1 \c_math_superscript_token
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+\prg_new_conditional:Npnn \token_if_math_subscript:N #1 { p , T , F , TF }
+ {
+ \if_catcode:w \exp_not:N #1 \c_math_subscript_token
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+\prg_new_conditional:Npnn \token_if_space:N #1 { p , T , F , TF }
+ {
+ \if_catcode:w \exp_not:N #1 \c_space_token
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+\prg_new_conditional:Npnn \token_if_letter:N #1 { p , T , F , TF }
+ {
+ \if_catcode:w \exp_not:N #1 \c_catcode_letter_token
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+\prg_new_conditional:Npnn \token_if_other:N #1 { p , T , F , TF }
+ {
+ \if_catcode:w \exp_not:N #1 \c_catcode_other_token
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+\prg_new_conditional:Npnn \token_if_active:N #1 { p , T , F , TF }
+ {
+ \if_catcode:w \exp_not:N #1 \c_catcode_active_tl
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+\prg_new_conditional:Npnn \token_if_eq_meaning:NN #1#2 { p , T , F , TF }
+ {
+ \if_meaning:w #1 #2
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+\prg_new_conditional:Npnn \token_if_eq_catcode:NN #1#2 { p , T , F , TF }
+ {
+ \if_catcode:w \exp_not:N #1 \exp_not:N #2
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+\prg_new_conditional:Npnn \token_if_eq_charcode:NN #1#2 { p , T , F , TF }
+ {
+ \if_charcode:w \exp_not:N #1 \exp_not:N #2
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+\group_begin:
+\char_set_catcode_other:N \M
+\char_set_catcode_other:N \A
+\char_set_lccode:nn { `\; } { `\: }
+\char_set_lccode:nn { `\T } { `\T }
+\char_set_lccode:nn { `\F } { `\F }
+\tl_to_lowercase:n
+ {
+ \group_end:
+ \prg_new_conditional:Npnn \token_if_macro:N #1 { p , T , F , TF }
+ {
+ \exp_after:wN \token_if_macro_p_aux:w
+ \token_to_meaning:N #1 MA; \q_stop
+ }
+ \cs_new_nopar:Npn \token_if_macro_p_aux:w #1 MA #2 ; #3 \q_stop
+ {
+ \if_int_compare:w \pdftex_strcmp:D { #2 } { cro } = \c_zero
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+ }
+\prg_new_conditional:Npnn \token_if_cs:N #1 { p , T , F , TF }
+ {
+ \if_catcode:w \exp_not:N #1 \scan_stop:
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+\prg_new_conditional:Npnn \token_if_expandable:N #1 { p , T , F , TF }
+ {
+ \cs_if_exist:NTF #1
+ {
+ \exp_after:wN \if_meaning:w \exp_not:N #1 #1
+ \prg_return_false: \else: \prg_return_true: \fi:
+ }
+ { \prg_return_false: }
+ }
+\group_begin:
+ \char_set_lccode:nn { `\T } { `\T }
+ \char_set_lccode:nn { `\F } { `\F }
+ \char_set_lccode:nn { `\X } { `\n }
+ \char_set_lccode:nn { `\Y } { `\t }
+ \char_set_lccode:nn { `\Z } { `\d }
+ \char_set_lccode:nn { `\? } { `\\ }
+ \tl_map_inline:nn { \X \Y \Z \M \C \H \A \R \O \U \S \K \I \P \L \G \P \E }
+ { \char_set_catcode:nn { `#1 } \c_twelve }
+\tl_to_lowercase:n
+ {
+ \group_end:
+ \prg_new_conditional:Npnn \token_if_chardef:N #1 { p , T , F , TF }
+ {
+ \exp_after:wN \token_if_chardef_aux:w
+ \token_to_meaning:N #1 ?CHAR" \q_stop
+ }
+ \cs_new_nopar:Npn \token_if_chardef_aux:w #1 ?CHAR" #2 \q_stop
+ { \tl_if_empty:nTF {#1} { \prg_return_true: } { \prg_return_false: } }
+ \prg_new_conditional:Npnn \token_if_mathchardef:N #1 { p , T , F , TF }
+ {
+ \exp_after:wN \token_if_mathchardef_aux:w
+ \token_to_meaning:N #1 ?MAYHCHAR" \q_stop
+ }
+ \cs_new_nopar:Npn \token_if_mathchardef_aux:w #1 ?MAYHCHAR" #2 \q_stop
+ { \tl_if_empty:nTF {#1} { \prg_return_true: } { \prg_return_false: } }
+ \prg_new_conditional:Npnn \token_if_int_register:N #1 { p , T , F , TF }
+ {
+ \if_meaning:w \tex_countdef:D #1
+ \prg_return_false:
+ \else:
+ \exp_after:wN \token_if_int_register_aux:w
+ \token_to_meaning:N #1 ?COUXY \q_stop
+ \fi:
+ }
+ \cs_new_nopar:Npn \token_if_int_register_aux:w #1 ?COUXY #2 \q_stop
+ { \tl_if_empty:nTF {#1} { \prg_return_true: } { \prg_return_false: } }
+ \prg_new_conditional:Npnn \token_if_skip_register:N #1 { p , T , F , TF }
+ {
+ \if_meaning:w \tex_skipdef:D #1
+ \prg_return_false:
+ \else:
+ \exp_after:wN \token_if_skip_register_aux:w
+ \token_to_meaning:N #1?SKIP\q_stop
+ \fi:
+ }
+ \cs_new_nopar:Npn \token_if_skip_register_aux:w #1 ?SKIP #2 \q_stop
+ { \tl_if_empty:nTF {#1} { \prg_return_true: } { \prg_return_false: } }
+ \prg_new_conditional:Npnn \token_if_dim_register:N #1 { p , T , F , TF }
+ {
+ \if_meaning:w \tex_dimendef:D #1
+ \c_false_bool
+ \else:
+ \exp_after:wN \token_if_dim_register_aux:w
+ \token_to_meaning:N #1 ?ZIMEX \q_stop
+ \fi:
+ }
+ \cs_new_nopar:Npn \token_if_dim_register_aux:w #1 ?ZIMEX #2 \q_stop
+ { \tl_if_empty:nTF {#1} { \prg_return_true: } { \prg_return_false: } }
+ \prg_new_conditional:Npnn \token_if_toks_register:N #1 { p , T , F , TF }
+ {
+ \if_meaning:w \tex_toksdef:D #1
+ \prg_return_false:
+ \else:
+ \exp_after:wN \token_if_toks_register_aux:w
+ \token_to_meaning:N #1 ?YOKS \q_stop
+ \fi:
+ }
+ \cs_new_nopar:Npn \token_if_toks_register_aux:w #1 ?YOKS #2 \q_stop
+ { \tl_if_empty:nTF {#1} { \prg_return_true: } { \prg_return_false: } }
+ \prg_new_conditional:Npnn \token_if_protected_macro:N #1
+ { p , T , F , TF }
+ {
+ \exp_after:wN \token_if_protected_macro_aux:w
+ \token_to_meaning:N #1 ?PROYECYEZ~MACRO \q_stop
+ }
+ \cs_new_nopar:Npn \token_if_protected_macro_aux:w
+ #1 ?PROYECYEZ~MACRO #2 \q_stop
+ { \tl_if_empty:nTF {#1} { \prg_return_true: } { \prg_return_false: } }
+ \prg_new_conditional:Npnn \token_if_long_macro:N #1 { p , T , F , TF }
+ {
+ \exp_after:wN \token_if_long_macro_aux:w
+ \token_to_meaning:N #1 ?LOXG~MACRO \q_stop
+ }
+ \cs_new_nopar:Npn \token_if_long_macro_aux:w #1 ?LOXG~MACRO #2 \q_stop
+ { \tl_if_empty:nTF {#1} { \prg_return_true: } { \prg_return_false: } }
+ \prg_new_conditional:Npnn \token_if_protected_long_macro:N #1
+ { p , T , F , TF }
+ {
+ \exp_after:wN \token_if_protected_long_macro_aux:w
+ \token_to_meaning:N #1 ?PROYECYEZ?LOXG~MACRO \q_stop
+ }
+ \cs_new_nopar:Npn \token_if_protected_long_macro_aux:w
+ #1 ?PROYECYEZ?LOXG~MACRO #2 \q_stop
+ { \tl_if_empty:nTF {#1} { \prg_return_true: } { \prg_return_false: } }
+ }
+\tex_chardef:D \c_token_A_int = `A ~ %
+\group_begin:
+\char_set_catcode_other:N \;
+\char_set_lccode:nn { `\; } { `\: }
+\char_set_lccode:nn { `\T } { `\T }
+\char_set_lccode:nn { `\F } { `\F }
+\tl_to_lowercase:n {
+ \group_end:
+ \prg_new_conditional:Npnn \token_if_primitive:N #1 { p , T , F , TF }
+ {
+ \token_if_macro:NTF #1
+ \prg_return_false:
+ {
+ \exp_after:wN \token_if_primitive_aux:NNw
+ \token_to_meaning:N #1 ; ; ; \q_stop #1
+ }
+ }
+ \cs_new_nopar:Npn \token_if_primitive_aux:NNw #1#2 #3 ; #4 \q_stop
+ {
+ \tl_if_empty:oTF { \token_if_primitive_aux_space:w #3 ~ }
+ { \token_if_primitive_aux_loop:N #3 ; \q_stop }
+ { \token_if_primitive_aux_nullfont:N }
+ }
+}
+\cs_new_nopar:Npn \token_if_primitive_aux_space:w #1 ~ { }
+\cs_new:Npn \token_if_primitive_aux_nullfont:N #1
+ {
+ \if_meaning:w \tex_nullfont:D #1
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\cs_new_nopar:Npn \token_if_primitive_aux_loop:N #1
+ {
+ \if_num:w `#1 < \c_token_A_int %
+ \exp_after:wN \token_if_primitive_auxii:Nw
+ \exp_after:wN #1
+ \else:
+ \exp_after:wN \token_if_primitive_aux_loop:N
+ \fi:
+ }
+\cs_new_nopar:Npn \token_if_primitive_auxii:Nw #1 #2 \q_stop
+ {
+ \if:w : #1
+ \exp_after:wN \token_if_primitive_aux_undefined:N
+ \else:
+ \prg_return_false:
+ \exp_after:wN \use_none:n
+ \fi:
+ }
+\cs_new:Npn \token_if_primitive_aux_undefined:N #1
+ {
+ \if_cs_exist:N #1
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\cs_new_eq:NN \l_peek_token ?
+\cs_new_eq:NN \g_peek_token ?
+\cs_new_eq:NN \l_peek_search_token ?
+\cs_new_nopar:Npn \l_peek_search_tl { }
+\cs_new_nopar:Npn \peek_true:w { }
+\cs_new_nopar:Npn \peek_true_aux:w { }
+\cs_new_nopar:Npn \peek_false:w { }
+\cs_new:Npn \peek_tmp:w { }
+\cs_new_protected_nopar:Npn \peek_after:Nw
+ { \tex_futurelet:D \l_peek_token }
+\cs_new_protected_nopar:Npn \peek_gafter:Nw
+ { \pref_global:D \tex_futurelet:D \g_peek_token }
+\cs_new_protected:Npn \peek_true_remove:w
+ {
+ \group_align_safe_end:
+ \tex_afterassignment:D \peek_true_aux:w
+ \cs_set_eq:NN \peek_tmp:w
+ }
+\cs_new_protected:Npn \peek_token_generic:NNTF #1#2#3#4
+ {
+ \cs_set_eq:NN \l_peek_search_token #2
+ \tl_set:Nn \l_peek_search_tl {#2}
+ \cs_set_nopar:Npx \peek_true:w
+ {
+ \exp_not:N \group_align_safe_end:
+ \exp_not:n {#3}
+ }
+ \cs_set_nopar:Npx \peek_false:w
+ {
+ \exp_not:N \group_align_safe_end:
+ \exp_not:n {#4}
+ }
+ \group_align_safe_begin:
+ \peek_after:Nw #1
+ }
+\cs_new_protected:Npn \peek_token_generic:NNT #1#2#3
+ { \peek_token_generic:NNTF #1 #2 {#3} { } }
+\cs_new_protected:Npn \peek_token_generic:NNF #1#2#3
+ { \peek_token_generic:NNTF #1 #2 { } {#3} }
+\cs_new_protected:Npn \peek_token_remove_generic:NNTF #1#2#3#4
+ {
+ \cs_set_eq:NN \l_peek_search_token #2
+ \tl_set:Nn \l_peek_search_tl {#2}
+ \cs_set_eq:NN \peek_true:w \peek_true_remove:w
+ \cs_set_nopar:Npx \peek_true_aux:w { \exp_not:n {#3} }
+ \cs_set_nopar:Npx \peek_false:w
+ {
+ \exp_not:N \group_align_safe_end:
+ \exp_not:n {#4}
+ }
+ \group_align_safe_begin:
+ \peek_after:Nw #1
+ }
+\cs_new_protected:Npn \peek_token_remove_generic:NNT #1#2#3
+ { \peek_token_remove_generic:NNTF #1 #2 {#3} { } }
+\cs_new_protected:Npn \peek_token_remove_generic:NNF #1#2#3
+ { \peek_token_remove_generic:NNTF #1 #2 { } {#3} }
+\cs_new_nopar:Npn \peek_execute_branches_catcode:
+ {
+ \if_catcode:w
+ \exp_not:N \l_peek_token \exp_not:N \l_peek_search_token
+ \exp_after:wN \peek_true:w
+ \else:
+ \exp_after:wN \peek_false:w
+ \fi:
+ }
+\cs_new_nopar:Npn \peek_execute_branches_meaning:
+ {
+ \if_meaning:w \l_peek_token \l_peek_search_token
+ \exp_after:wN \peek_true:w
+ \else:
+ \exp_after:wN \peek_false:w
+ \fi:
+ }
+\cs_new_nopar:Npn \peek_execute_branches_charcode:
+ {
+ \bool_if:nTF
+ {
+ \token_if_eq_catcode_p:NN \l_peek_token \c_group_begin_token
+ || \token_if_eq_catcode_p:NN \l_peek_token \c_group_end_token
+ || \token_if_eq_meaning_p:NN \l_peek_token \c_space_token
+ }
+ { \peek_false:w }
+ {
+ \exp_after:wN \peek_execute_branches_charcode_aux:NN
+ \l_peek_search_tl
+ }
+ }
+\cs_new:Npn \peek_execute_branches_charcode_aux:NN #1#2
+ {
+ \if:w \exp_not:N #1 \exp_not:N #2
+ \exp_after:wN \peek_true:w
+ \else:
+ \exp_after:wN \peek_false:w
+ \fi:
+ #2
+ }
+\cs_new_protected_nopar:Npn \peek_ignore_spaces_execute_branches:
+ {
+ \token_if_eq_meaning:NNTF \l_peek_token \c_space_token
+ {
+ \tex_afterassignment:D \peek_ignore_spaces_execute_branches_aux:
+ \cs_set_eq:NN \peek_tmp:w
+ }
+ { \peek_execute_branches: }
+ }
+\cs_new_protected_nopar:Npn \peek_ignore_spaces_execute_branches_aux:
+ { \peek_after:Nw \peek_ignore_spaces_execute_branches: }
+\group_begin:
+ \cs_set_nopar:Npn \peek_def:nnnn #1#2#3#4
+ {
+ \peek_def_aux:nnnnn {#1} {#2} {#3} {#4} { TF }
+ \peek_def_aux:nnnnn {#1} {#2} {#3} {#4} { T }
+ \peek_def_aux:nnnnn {#1} {#2} {#3} {#4} { F }
+ }
+ \cs_set_nopar:Npn \peek_def_aux:nnnnn #1#2#3#4#5
+ {
+ \cs_gset_nopar:cpx { #1 #5 }
+ {
+ \tl_if_empty:nF {#2}
+ { \exp_not:n { \cs_set_eq:NN \peek_execute_branches: #2 } }
+ \exp_not:c { #3 #5 }
+ \exp_not:n {#4}
+ }
+ }
+ \peek_def:nnnn { peek_catcode:N }
+ { }
+ { peek_token_generic:NN }
+ { \peek_execute_branches_catcode: }
+ \peek_def:nnnn { peek_catcode_ignore_spaces:N }
+ { \peek_execute_branches_catcode: }
+ { peek_token_generic:NN }
+ { \peek_ignore_spaces_execute_branches: }
+ \peek_def:nnnn { peek_catcode_remove:N }
+ { }
+ { peek_token_remove_generic:NN }
+ { \peek_execute_branches_catcode: }
+ \peek_def:nnnn { peek_catcode_remove_ignore_spaces:N }
+ { \peek_execute_branches_catcode: }
+ { peek_token_remove_generic:NN }
+ { \peek_ignore_spaces_execute_branches: }
+ \peek_def:nnnn { peek_charcode:N }
+ { }
+ { peek_token_generic:NN }
+ { \peek_execute_branches_charcode: }
+ \peek_def:nnnn { peek_charcode_ignore_spaces:N }
+ { \peek_execute_branches_charcode: }
+ { peek_token_generic:NN }
+ { \peek_ignore_spaces_execute_branches: }
+ \peek_def:nnnn { peek_charcode_remove:N }
+ { }
+ { peek_token_remove_generic:NN }
+ { \peek_execute_branches_charcode: }
+ \peek_def:nnnn { peek_charcode_remove_ignore_spaces:N }
+ { \peek_execute_branches_charcode: }
+ { peek_token_remove_generic:NN }
+ { \peek_ignore_spaces_execute_branches: }
+ \peek_def:nnnn { peek_meaning:N }
+ { }
+ { peek_token_generic:NN }
+ { \peek_execute_branches_meaning: }
+ \peek_def:nnnn { peek_meaning_ignore_spaces:N }
+ { \peek_execute_branches_meaning: }
+ { peek_token_generic:NN }
+ { \peek_ignore_spaces_execute_branches: }
+ \peek_def:nnnn { peek_meaning_remove:N }
+ { }
+ { peek_token_remove_generic:NN }
+ { \peek_execute_branches_meaning: }
+ \peek_def:nnnn { peek_meaning_remove_ignore_spaces:N }
+ { \peek_execute_branches_meaning: }
+ { peek_token_remove_generic:NN }
+ { \peek_ignore_spaces_execute_branches: }
+\group_end:
+\exp_args:Nno \use:nn
+ { \cs_new_nopar:Npn \token_get_prefix_arg_replacement_aux:wN #1 }
+ { \tl_to_str:n { macro : } #2 -> #3 \q_stop #4 }
+ { #4 {#1} {#2} {#3} }
+\cs_new:Npn \token_get_prefix_spec:N #1
+ {
+ \token_if_macro:NTF #1
+ {
+ \exp_after:wN \token_get_prefix_arg_replacement_aux:wN
+ \token_to_meaning:N #1 \q_stop \use_i:nnn
+ }
+ { \scan_stop: }
+ }
+\cs_new:Npn \token_get_arg_spec:N #1
+ {
+ \token_if_macro:NTF #1
+ {
+ \exp_after:wN \token_get_prefix_arg_replacement_aux:wN
+ \token_to_meaning:N #1 \q_stop \use_ii:nnn
+ }
+ { \scan_stop: }
+ }
+\cs_new:Npn \token_get_replacement_spec:N #1
+ {
+ \token_if_macro:NTF #1
+ {
+ \exp_after:wN \token_get_prefix_arg_replacement_aux:wN
+ \token_to_meaning:N #1 \q_stop \use_iii:nnn
+ }
+ { \scan_stop: }
+ }
+\group_begin:
+ \char_set_catcode_active:N \^^@
+ \cs_set:Npn \char_tmp:NN #1#2
+ {
+ \cs_new:Npn #1 ##1
+ {
+ \char_set_catcode_active:n { `##1 }
+ \group_begin:
+ \char_set_lccode:nn { `\^^@ } { `##1 }
+ \tl_to_lowercase:n { \group_end: #2 ^^@ }
+ }
+ }
+ \char_tmp:NN \char_active_set:Npn \cs_set:Npn
+ \char_tmp:NN \char_active_set:Npx \cs_set:Npx
+ \char_tmp:NN \char_active_gset:Npn \cs_gset:Npn
+ \char_tmp:NN \char_active_gset:Npx \cs_gset:Npx
+ \char_tmp:NN \char_active_set_eq:NN \cs_set_eq:NN
+ \char_tmp:NN \char_active_gset_eq:NN \cs_gset_eq:NN
+\group_end:
+\cs_new_eq:NN \char_set_catcode:w \tex_catcode:D
+\cs_new_eq:NN \char_set_mathcode:w \tex_mathcode:D
+\cs_new_eq:NN \char_set_lccode:w \tex_lccode:D
+\cs_new_eq:NN \char_set_uccode:w \tex_uccode:D
+\cs_new_eq:NN \char_set_sfcode:w \tex_sfcode:D
+\cs_new_nopar:Npn \char_value_catcode:w { \tex_the:D \char_set_catcode:w }
+\cs_new_nopar:Npn \char_show_value_catcode:w
+ { \tex_showthe:D \char_set_catcode:w }
+\cs_new_nopar:Npn \char_value_mathcode:w { \tex_the:D \char_set_mathcode:w }
+\cs_new_nopar:Npn \char_show_value_mathcode:w
+ { \tex_showthe:D \char_set_mathcode:w }
+\cs_new_nopar:Npn \char_value_lccode:w { \tex_the:D \char_set_lccode:w }
+\cs_new_nopar:Npn \char_show_value_lccode:w
+ { \tex_showthe:D \char_set_lccode:w }
+\cs_new_nopar:Npn \char_value_uccode:w { \tex_the:D \char_set_uccode:w }
+\cs_new_nopar:Npn \char_show_value_uccode:w
+ { \tex_showthe:D \char_set_uccode:w }
+\cs_new_nopar:Npn \char_value_sfcode:w { \tex_the:D \char_set_sfcode:w }
+\cs_new_nopar:Npn \char_show_value_sfcode:w
+ { \tex_showthe:D \char_set_sfcode:w }
+\cs_new_eq:NN \peek_after:NN \peek_after:Nw
+\cs_new_eq:NN \peek_gafter:NN \peek_gafter:Nw
+\cs_new_eq:NN \c_alignment_tab_token \c_alignment_token
+\cs_new_eq:NN \c_math_shift_token \c_math_toggle_token
+\cs_new_eq:NN \c_letter_token \c_catcode_letter_token
+\cs_new_eq:NN \c_other_char_token \c_catcode_other_token
+\cs_new_eq:NN \c_active_char_token \c_catcode_active_tl
+\cs_new_eq:NN \char_make_escape:N \char_set_catcode_escape:N
+\cs_new_eq:NN \char_make_begin_group:N \char_set_catcode_group_begin:N
+\cs_new_eq:NN \char_make_end_group:N \char_set_catcode_group_end:N
+\cs_new_eq:NN \char_make_math_shift:N \char_set_catcode_math_toggle:N
+\cs_new_eq:NN \char_make_alignment_tab:N \char_set_catcode_alignment:N
+\cs_new_eq:NN \char_make_end_line:N \char_set_catcode_end_line:N
+\cs_new_eq:NN \char_make_parameter:N \char_set_catcode_parameter:N
+\cs_new_eq:NN \char_make_math_superscript:N
+ \char_set_catcode_math_superscript:N
+\cs_new_eq:NN \char_make_math_subscript:N
+ \char_set_catcode_math_subscript:N
+\cs_new_eq:NN \char_make_ignore:N \char_set_catcode_ignore:N
+\cs_new_eq:NN \char_make_space:N \char_set_catcode_space:N
+\cs_new_eq:NN \char_make_letter:N \char_set_catcode_letter:N
+\cs_new_eq:NN \char_make_other:N \char_set_catcode_other:N
+\cs_new_eq:NN \char_make_active:N \char_set_catcode_active:N
+\cs_new_eq:NN \char_make_comment:N \char_set_catcode_comment:N
+\cs_new_eq:NN \char_make_invalid:N \char_set_catcode_invalid:N
+\cs_new_eq:NN \char_make_escape:n \char_set_catcode_escape:n
+\cs_new_eq:NN \char_make_begin_group:n \char_set_catcode_group_begin:n
+\cs_new_eq:NN \char_make_end_group:n \char_set_catcode_group_end:n
+\cs_new_eq:NN \char_make_math_shift:n \char_set_catcode_math_toggle:n
+\cs_new_eq:NN \char_make_alignment_tab:n \char_set_catcode_alignment:n
+\cs_new_eq:NN \char_make_end_line:n \char_set_catcode_end_line:n
+\cs_new_eq:NN \char_make_parameter:n \char_set_catcode_parameter:n
+\cs_new_eq:NN \char_make_math_superscript:n
+ \char_set_catcode_math_superscript:n
+\cs_new_eq:NN \char_make_math_subscript:n
+ \char_set_catcode_math_subscript:n
+\cs_new_eq:NN \char_make_ignore:n \char_set_catcode_ignore:n
+\cs_new_eq:NN \char_make_space:n \char_set_catcode_space:n
+\cs_new_eq:NN \char_make_letter:n \char_set_catcode_letter:n
+\cs_new_eq:NN \char_make_other:n \char_set_catcode_other:n
+\cs_new_eq:NN \char_make_active:n \char_set_catcode_active:n
+\cs_new_eq:NN \char_make_comment:n \char_set_catcode_comment:n
+\cs_new_eq:NN \char_make_invalid:n \char_set_catcode_invalid:n
+\cs_new_eq:NN \token_if_alignment_tab_p:N \token_if_alignment_p:N
+\cs_new_eq:NN \token_if_alignment_tab:NT \token_if_alignment:NT
+\cs_new_eq:NN \token_if_alignment_tab:NF \token_if_alignment:NF
+\cs_new_eq:NN \token_if_alignment_tab:NTF \token_if_alignment:NTF
+\cs_new_eq:NN \token_if_math_shift_p:N \token_if_math_toggle_p:N
+\cs_new_eq:NN \token_if_math_shift:NT \token_if_math_toggle:NT
+\cs_new_eq:NN \token_if_math_shift:NF \token_if_math_toggle:NF
+\cs_new_eq:NN \token_if_math_shift:NTF \token_if_math_toggle:NTF
+\cs_new_eq:NN \token_if_other_char_p:N \token_if_other_p:N
+\cs_new_eq:NN \token_if_other_char:NT \token_if_other:NT
+\cs_new_eq:NN \token_if_other_char:NF \token_if_other:NF
+\cs_new_eq:NN \token_if_other_char:NTF \token_if_other:NTF
+\cs_new_eq:NN \token_if_active_char_p:N \token_if_active_p:N
+\cs_new_eq:NN \token_if_active_char:NT \token_if_active:NT
+\cs_new_eq:NN \token_if_active_char:NF \token_if_active:NF
+\cs_new_eq:NN \token_if_active_char:NTF \token_if_active:NTF
+%%
+%%
+%% End of file `l3token.sty'.
diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3toks.sty b/Master/texmf-dist/tex/latex/l3kernel/l3toks.sty
new file mode 100644
index 00000000000..1b1ab880687
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/l3kernel/l3toks.sty
@@ -0,0 +1,163 @@
+%%
+%% This is file `l3toks.sty',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% l3toks.dtx (with options: `package')
+%%
+%% EXPERIMENTAL CODE
+%%
+%% Do not distribute this file without also distributing the
+%% source files specified above.
+%%
+%% Do not distribute a modified version of this file.
+%%
+%% File: l3toks.dtx Copyright (C) 1990-2011 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 "expl3 bundle" (The Work in LPPL)
+%% and all files in that bundle must be distributed together.
+%%
+%% The released version of this bundle is available from CTAN.
+%%
+%% -----------------------------------------------------------------------
+%%
+%% The development version of the bundle can be found at
+%%
+%% http://www.latex-project.org/svnroot/experimental/trunk/
+%%
+%% for those people who are interested.
+%%
+%%%%%%%%%%%
+%% NOTE: %%
+%%%%%%%%%%%
+%%
+%% Snapshots taken from the repository represent work in progress and may
+%% not work or may contain conflicting material! We therefore ask
+%% people _not_ to put them into distributions, archives, etc. without
+%% prior consultation with the LaTeX3 Project.
+%%
+%% -----------------------------------------------------------------------
+\RequirePackage{l3names}
+\GetIdInfo$Id: l3toks.dtx 2478 2011-06-19 21:34:23Z joseph $
+ {L3 Experimental token registers}
+\ProvidesExplPackage
+ {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
+\package_check_loaded_expl:
+\cs_new_protected_nopar:Npn \toks_new:N #1 {
+ \chk_if_free_cs:N #1
+ \newtoks #1
+}
+\cs_generate_variant:Nn \toks_new:N {c}
+\cs_new_eq:NN \toks_use:N \tex_the:D
+\cs_generate_variant:Nn \toks_use:N {c}
+\cs_new_eq:NN \toks_set:Nn \prg_do_nothing:
+\cs_new_protected:Npn \toks_set:NV #1#2 {
+ #1 \exp_after:wN { \int_to_roman:w -`0 \exp_eval_register:N #2 }
+}
+\cs_new_protected:Npn \toks_set:Nv #1#2 {
+ #1 \exp_after:wN { \int_to_roman:w -`0 \exp_eval_register:c {#2} }
+}
+\cs_new_protected:Npn \toks_set:No #1#2 { #1 \exp_after:wN {#2} }
+\cs_new_protected:Npn \toks_set:Nf #1#2 {
+ #1 \exp_after:wN { \int_to_roman:w -`0#2 }
+}
+\cs_generate_variant:Nn \toks_set:Nn {Nx,cn,cV,cv,co,cx,cf}
+\cs_new_eq:NN \toks_gset:Nn \pref_global:D
+\cs_generate_variant:Nn \toks_gset:Nn {NV,No,Nx,cn,cV,co,cx}
+\cs_new_eq:NN \toks_set_eq:NN \prg_do_nothing:
+\cs_new_eq:NN \toks_gset_eq:NN \pref_global:D
+\cs_generate_variant:Nn \toks_set_eq:NN {Nc,cN,cc}
+\cs_generate_variant:Nn \toks_gset_eq:NN {Nc,cN,cc}
+\cs_new_protected_nopar:Npn \toks_clear:N #1 {
+ #1\c_empty_toks
+}
+\cs_new_protected_nopar:Npn \toks_gclear:N {
+ \pref_global:D
+ \toks_clear:N
+}
+\cs_generate_variant:Nn \toks_clear:N {c}
+\cs_generate_variant:Nn \toks_gclear:N {c}
+\cs_new_protected_nopar:Npn \toks_use_clear:N #1 {
+ \exp_last_unbraced:NNV \toks_clear:N #1 #1
+}
+\cs_new_protected_nopar:Npn \toks_use_gclear:N {
+ \pref_global:D
+ \toks_use_clear:N
+}
+\cs_generate_variant:Nn \toks_use_clear:N {c}
+\cs_generate_variant:Nn \toks_use_gclear:N {c}
+\cs_new_eq:NN \toks_show:N \kernel_register_show:N
+\cs_generate_variant:Nn \toks_show:N {c}
+\cs_new_protected_nopar:Npn \toks_put_left:Nn #1 {
+ \exp_after:wN \toks_put_left_aux:w \exp_after:wN \q_nil
+ \toks_use:N #1 \q_stop #1
+}
+\cs_generate_variant:Nn \toks_put_left:Nn {NV,No,Nx,cn,co,cV}
+\cs_new_protected_nopar:Npn \toks_gput_left:Nn {
+ \pref_global:D
+ \toks_put_left:Nn
+}
+\cs_generate_variant:Nn \toks_gput_left:Nn {NV,No,Nx,cn,cV,co}
+\cs_new:Npn \toks_put_left_aux:w #1\q_stop #2#3 {
+ #2 \exp_after:wN { \use_i:nn {#3} #1 }
+}
+\cs_new_protected:Npn \toks_put_right:Nn #1#2 {
+ #1 \exp_after:wN { \toks_use:N #1 #2 }
+}
+\cs_new_protected_nopar:Npn \toks_gput_right:Nn {
+ \pref_global:D
+ \toks_put_right:Nn
+}
+\cs_new_protected:Npn \toks_put_right:NV #1#2 {
+ #1 \exp_after:wN \exp_after:wN \exp_after:wN {
+ \exp_after:wN \toks_use:N \exp_after:wN #1
+ \int_to_roman:w -`0 \exp_eval_register:N #2
+ }
+}
+\cs_new_protected:Npn \toks_put_right:No #1#2 {
+ #1 \exp_after:wN \exp_after:wN \exp_after:wN {
+ \exp_after:wN \toks_use:N \exp_after:wN #1 #2
+ }
+}
+\cs_generate_variant:Nn \toks_put_right:Nn {Nx,cn,cV,co}
+\cs_generate_variant:Nn \toks_gput_right:Nn {NV,No,Nx,cn,cV,co}
+\cs_new_protected:Npn \toks_put_right:Nf #1#2 {
+ #1 \exp_after:wN \exp_after:wN \exp_after:wN {
+ \exp_after:wN \toks_use:N \exp_after:wN #1 \int_to_roman:w -`0#2
+ }
+}
+\prg_new_conditional:Nnn \toks_if_empty:N {p,TF,T,F} {
+ \tl_if_empty:VTF #1 {\prg_return_true:} {\prg_return_false:}
+}
+\cs_generate_variant:Nn \toks_if_empty_p:N {c}
+\cs_generate_variant:Nn \toks_if_empty:NTF {c}
+\cs_generate_variant:Nn \toks_if_empty:NT {c}
+\cs_generate_variant:Nn \toks_if_empty:NF {c}
+\prg_new_conditional:Nnn \toks_if_eq:NN {p,TF,T,F} {
+ \str_if_eq:xxTF {\toks_use:N #1} {\toks_use:N #2}
+ {\prg_return_true:} {\prg_return_false:}
+}
+\cs_generate_variant:Nn \toks_if_eq_p:NN {Nc,c,cc}
+\cs_generate_variant:Nn \toks_if_eq:NNTF {Nc,c,cc}
+\cs_generate_variant:Nn \toks_if_eq:NNT {Nc,c,cc}
+\cs_generate_variant:Nn \toks_if_eq:NNF {Nc,c,cc}
+\tex_toksdef:D \l_tmpa_toks = 255\scan_stop:
+\toks_new:N \l_tmpb_toks
+\toks_new:N \l_tmpc_toks
+\toks_new:N \g_tmpa_toks
+\toks_new:N \g_tmpb_toks
+\toks_new:N \g_tmpc_toks
+\toks_new:N \c_empty_toks
+\toks_new:N \l_tl_replace_toks
+
+%%
+%%
+%% End of file `l3toks.sty'.
diff --git a/Master/tlpkg/bin/tlpkg-ctan-check b/Master/tlpkg/bin/tlpkg-ctan-check
index 322b2078dff..27c3fad9b79 100755
--- a/Master/tlpkg/bin/tlpkg-ctan-check
+++ b/Master/tlpkg/bin/tlpkg-ctan-check
@@ -198,6 +198,7 @@ my @TLP_working = qw(
knitting knittingpattern knuth
koma-moderncvclassic koma-script kpfonts kurier
l2picfaq l2tabu l2tabu-english l2tabu-french l2tabu-it l2tabu-spanish
+ l3kernel
labbook labelcas labels lastpage
latex latex-bib-ex latex-course latex-doc-ptr latex-notes-zh-cn
latex-referenz latex-tabellen
diff --git a/Master/tlpkg/tlpsrc/collection-latexrecommended.tlpsrc b/Master/tlpkg/tlpsrc/collection-latexrecommended.tlpsrc
index ac0e739d737..8ad7bb8bdde 100644
--- a/Master/tlpkg/tlpsrc/collection-latexrecommended.tlpsrc
+++ b/Master/tlpkg/tlpsrc/collection-latexrecommended.tlpsrc
@@ -25,6 +25,7 @@ depend fp
depend index
depend jknapltx
depend koma-script
+depend l3kernel
depend listings
depend mdwtools
depend memoir
diff --git a/Master/tlpkg/tlpsrc/l3kernel.tlpsrc b/Master/tlpkg/tlpsrc/l3kernel.tlpsrc
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/Master/tlpkg/tlpsrc/l3kernel.tlpsrc