summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2009-06-09 23:31:15 +0000
committerKarl Berry <karl@freefriends.org>2009-06-09 23:31:15 +0000
commit215b9a864d5829070bdc66ba736986eb72e5143e (patch)
treefe0882c81fc4ec945cee4b512f72eaa21ea5f791 /Master/texmf-dist/source
parentdf90ec06321940c2f066b05e12f1b5ab099105da (diff)
expl3 1407 (9jun09)
git-svn-id: svn://tug.org/texlive/trunk@13686 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source')
-rw-r--r--Master/texmf-dist/source/latex/expl3/expl3.dtx970
-rw-r--r--Master/texmf-dist/source/latex/expl3/expl3.tex753
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3.ins225
-rw-r--r--Master/texmf-dist/source/latex/expl3/l32eproc.tex523
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3alloc.dtx146
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3basics.dtx3950
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3box.dtx541
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3calc.dtx493
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3chk.dtx173
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3clist.dtx988
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3doc.dtx1674
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3expan.dtx1378
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3file.dtx412
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3final.dtx54
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3format.ins147
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3int.dtx904
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3intexpr.dtx642
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3io.dtx524
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3keyval.dtx273
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3messages.dtx966
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3msg.dtx1336
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3names.dtx705
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3num.dtx504
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3precom.dtx192
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3prg.dtx1599
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3prop.dtx786
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3quark.dtx375
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3seq.dtx841
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3skip.dtx575
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3tl.dtx2269
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3tlp.dtx2054
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3token.dtx1751
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3toks.dtx963
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3vers.dtx72
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3xref.dtx180
-rw-r--r--Master/texmf-dist/source/latex/expl3/source3.tex633
-rw-r--r--Master/texmf-dist/source/latex/expl3/test1.tex89
-rw-r--r--Master/texmf-dist/source/latex/expl3/test2.tex73
-rw-r--r--Master/texmf-dist/source/latex/expl3/test3.tex135
39 files changed, 17080 insertions, 13788 deletions
diff --git a/Master/texmf-dist/source/latex/expl3/expl3.dtx b/Master/texmf-dist/source/latex/expl3/expl3.dtx
new file mode 100644
index 00000000000..a22e1b53417
--- /dev/null
+++ b/Master/texmf-dist/source/latex/expl3/expl3.dtx
@@ -0,0 +1,970 @@
+% \iffalse
+%% File: expl3.dtx Copyright (C) 1990-2009 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 LaTeX Project Team.
+%%
+%% -----------------------------------------------------------------------
+%
+%<*driver|package>
+\RequirePackage{l3names}
+%</driver|package>
+%\fi
+\GetIdInfo$Id: expl3.dtx 1381 2009-06-01 20:36:02Z joseph $
+ {L3 Experimental code bundle wrapper}%
+%\iffalse
+%<*driver>
+%\fi
+\ProvidesFile{\filename.\filenameext}
+ [\filedate\space v\fileversion\space\filedescription]
+%\iffalse
+\documentclass{l3doc}
+\usepackage{shortvrb,hypdoc}
+\MakeShortVerb{\|}
+\hyphenation{para-meters para-meter}
+% I have found at least 3 other hyphenations of this in various refs,
+% but I did also find this, which is my personal favourite ---chris
+\hyphenation{ignore ignored ignores}
+\begin{document}
+\DocInput{\filename.\filenameext}
+\end{document}
+%</driver>
+% \fi
+%
+% \providecommand\acro[1]{\textsc{\MakeLowercase{#1}}}
+% \providecommand\ie{i.e.,~}
+% \providecommand\eg{e.g.,~}
+% \newenvironment{arg-description}{%
+% \begin{itemize}\def\makelabel##1{\hss\llap{\bfseries##1}}}{\end{itemize}}
+%
+% \title{The \textsf{expl3} package and philosophy\thanks{This file
+% has version number \fileversion, last
+% revised \filedate.}}
+% \author{\Team}
+% \date{\filedate}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% \begin{abstract}
+%
+% This paper gives a brief 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.
+%
+% 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.
+%
+% An earlier description of the \LaTeX3 programming language is
+% available from \url{http://www.latex-project.org/papers}.
+% \end{abstract}
+%
+%
+% \section{Introduction}
+%
+% This paper describes the conventions for a \TeX-based programming
+% language which is intended to provide a more consistent and rational
+% environment for the construction of large scale systems, such as
+% \LaTeX, using \TeX{} macros.
+%
+% Variants of this language have been in use by The \LaTeX3 Project Team
+% since around 1990 but the syntax specification to be outlined here
+% should \emph{not} be considered final. This is an experimental
+% language thus many aspects, such as the syntax conventions and naming
+% schemes, may (and probably will) change as more experience is gained
+% with using the language in practice.
+%
+% 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 semantics of the expansion control mechanism and the
+% interface used to define variant forms of functions. The paper also
+% discusses some advantages of the syntax for parameter names.
+%
+% 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
+% (especially when using a reasonably intelligent editor).
+%
+% The final section gives some details of our plans to distribute parts
+% of this system. Although the paper is now a little dated, more general
+% information concerning the work of the \LaTeX3 Project can be found
+% in Ref.~\cite{tub:MR97-1}.
+%
+%
+% \section{Languages and interfaces}
+% \label{sec:langs}
+%
+% 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{SGML} 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
+% `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 (\eg
+% |\box| or |\special|).
+%
+% \item[Designer interface] This relates a (human) typographic
+% designer's specification for a document to a program that `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
+% \acro{SGML}-based systems the \acro{DSSSL} language may come to play
+% this role. 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 `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 `within' \TeX, as in the current \LaTeX\ system.
+% \end{description}
+%
+% Only the last of these three interfaces is covered by this paper,
+% which describes a system aimed at providing a suitable basis for
+% coding large scale projects in \TeX{} (but this should not preclude its
+% use for smaller projects). 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}
+% \label{sec:scheme}
+%
+% The naming conventions for this programming language distinguish
+% between \textit{functions} and \textit{parameters}. Functions can have
+% arguments and they are executed. Parameters can be assigned values
+% and they are used in arguments to functions; they are not directly
+% executed but are manipulated by mutator and accessor functions.
+% Functions and parameters with a related functionality (for example
+% accessing counters, or manipulating token-lists, etc.)\ are collected
+% together into a
+% \textit{module}.
+%
+%
+% Note that all these terms are only \LaTeX{} terminology and are not,
+% for example, intended to indicate that the commands have these
+% properties when considered in the context of basic \TeX{} or in any
+% more general programming context.
+%
+%
+% \subsection{Examples}
+% \label{sec:ex}
+%
+% Before giving the details of the naming scheme, here are a few typical
+% examples to indicate the flavour of the scheme; first some parameter
+% names.
+% \begin{quote}
+% |\l_tmpa_box| is a local parameter (hence the~|l_| prefix)
+% corresponding to a box register.\\
+% |\g_tmpa_int| is a global parameter (hence the~|g_| prefix)
+% corresponding to an integer register (\ie a \TeX{} count register).\\
+% |\c_empty_toks|
+% is the constant~(|c_|) token register parameter that is for ever empty.
+% \end{quote}
+% Now here is an example of a typical function name.
+%
+% |\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 `names'
+% the stack parameter: such single-token arguments are denoted~|N|.
+% The second argument is a normal \TeX\ `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 `normal' argument form. The name of the function
+% indicates it belongs to the |seq| module.
+%
+%^^A |\seq_push:cn| would be similar to the above, but in this case the~|c|
+%^^A means that the stack-name is specified in the first argument by a
+%^^A token list that expands, using |\csname...|, to a control sequence that
+%^^A is the \emph{name} of the stack parameter.
+%^^A
+%^^A \noindent
+%^^A The names of these two functions also indicate that they are in the
+%^^A module called |seq|.
+%
+%
+% \subsection{Formal syntax of the conventions}
+% \label{sec:namesyn}
+%
+% We shall now look in more detail at the syntax of these names.\\
+% The syntax of parameter names is as follows:
+% \begin{quote}
+% |\|\m{access}|_|\m{module}|_|\m{description}|_|\m{type}
+% \end{quote}
+% The syntax of function names is as follows:
+% \begin{quote}
+% |\|\m{module}|_|\m{description}|:|\m{arg-spec}
+% \end{quote}
+%
+%
+% \subsection{Modules and descriptions}
+% \label{sec:modules}
+%
+% The syntax of all names contains
+% \begin{quote}
+% \m{module} and \m{description}:
+% \end{quote}
+% these both give information about the command.
+%
+% A \textit{module} is a collection of
+% closely related functions and parameters.
+% 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.
+%
+% The \textit{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.
+%
+% As a semi-formalized concept the letter |g| is sometimes used to
+% prefix certain parts of the \m{description}
+% to mark the function as ``globally acting'', e.g., |\int_set:Nn| is
+% a local operation while |\int_gset:Nn| is a global operation. This
+% of course goes hand in hand with when to use |\l_| and |\g_|
+% variable prefixes.
+%
+% \subsection{Parameters: access and type}
+% \label{sec:parms}
+%
+% The \m{access} part of the name describes how the parameter can be
+% accessed. Parameters are primarily classified as local, global or
+% constant (there are further, more technical, classes). This
+% \textit{access} type appears as a code at the beginning of the name;
+% the codes used include:
+% \begin{arg-description}
+% \item[c]
+% constants (global parameters whose value should not be changed);
+% \item[g]
+% parameters whose value should only be set globally;
+% \item[l]
+% parameters whose value should only be set locally.
+% \end{arg-description}
+%
+% The \m{type} will normally (except when introducing a new data-type)
+% be in the list of available \textit{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.
+%
+% Here are some typical data-type names:
+% \begin{description}
+% \item[int] integer-valued count register;
+% \item[tl] token list variables: placeholders for token lists;
+% \item[toks] token register;
+% \item[box] box register;
+% \item[skip] `rubber' lengths;
+% \item[dim] `rigid' lengths;
+% \item[num] A `fake' integer type using only macros. Useful for
+% setting up allocation routines;
+% \item[seq] `sequence': a data-type used to implement lists
+% (with access at both ends) and stacks;
+% \item[prop] property list;
+% \item[clist] comma separated list;
+% \item[stream] an input or output stream (for reading from or writing to, respectively);
+% \item[bool] either true or false.
+% \end{description}
+% When the \m{type} and \m{module} are identical (as often happens in
+% the more basic modules) the \m{module} part is often omitted for
+% aesthetic reasons.
+%
+%
+% \subsection{Functions: basic argument specifications}
+% \label{sec:args}
+%
+% Function names end with an \m{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 \m{arg-spec} consists of a (possibly empty) list of characters,
+% each denoting one argument of the function. It is important to
+% understand that `argument' here refers to the effective argument of
+% the \LaTeX{} function, not to an argument at the \TeX-level. Indeed,
+% the top level \TeX\ macro that has this name typically has no
+% arguments. This is an extension of the existing \LaTeX\ convention
+% where one says that |\section| has an optional argument and a
+% mandatory argument, whereas the \TeX\ macro |\section| actually has
+% zero parameters at the \TeX\ level, it merely calls an internal \LaTeX\
+% command which in turn calls others that look ahead for star forms and
+% optional arguments.
+%
+% 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. If the \TeX\ primitive
+% needs to be used in other contexts it will be given an alternative,
+% more appropriate, name with a useful argument specification. The
+% argument syntax of these is often weird, in the sense described next.
+% \item[w] This means that the argument syntax is `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. For example, "\seq_gpush:Nn"
+% is a function that takes two arguments, the first is a single token
+% (the sequence) and the second may consist of several tokens surrounded
+% by braces.
+%
+% This concept of argument specification makes it easy to read the code
+% and should be followed when defining new functions.
+%
+%
+%
+%
+% \section{Expansion control}
+% \label{sec:exp}
+%
+% 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_io_file_name_seq| to keep track of them (|io| is the
+% input-output file module). 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_io_file_name_seq" \\
+% " {#1}"
+% \end{quote}
+% where |#1| is the filename. In other words, this operation would
+% push the file name as is.
+%
+% However, we might face a situation where
+% the filename is stored in a register of some sort, say
+% |\l_io_curr_file_tl|. In this case we want to retrieve the value of
+% the register. 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 register pushed onto the stack,
+% only the register name itself. Instead a suitable number of
+% "\exp_after:wN" would be necessary (together with extra braces) to
+% change the order of execution, 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 argument part of the function to
+% mark the desired behavior. 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" is for ``retrieve the
+% value of the register'' (the second argument) 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 (via~|\csname|, |\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_stack} \l_tmpa_tl"
+% \end{quote}
+% is equivalent to
+% \begin{quote}
+% "\seq_gpush:NV \g_file_name_stack \l_tmpa_tl".
+% \end{quote}
+%
+% \item[V] Value of a register.\\
+% This means that the register in question is returned, be it an
+% integer, a length type register, a macro storage register or
+% similar. The value is returned 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 returns the value.
+%
+% \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
+% |\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.
+%
+% \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}
+% \label{sec;simpler}
+%
+% 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 \string #1}
+% {?\string #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.
+%
+% 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 `\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}
+% \label{sec:newfunc}
+%
+% 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 `normal'
+% \TeX\ undelimited arguments.
+%
+% To illustrate this let us suppose you have a `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{Parameter assignments and accessor functions}
+% \label{sec:access}
+%
+% \subsection{Checking assignments}
+% \label{sec:check}
+%
+% One of the advantages of having a consistent scheme is that the system
+% can provide more extensive error-checking and debugging facilities.
+% For example, an accessor function that makes a \emph{global}
+% assignment of a value to a parameter can check that it is not passed
+% the name of a \emph{local} parameter as that argument: it does this by
+% checking that the name starts with~|\g_|.
+%
+% Such checking is probably too slow for normal use, but the code can
+% have hooks built in that allow a format to be made in which all
+% functions perform this kind of check.
+%
+% A typical section of the source^^A
+% \footnote{This code uses the \textsf{docstrip}
+% system described in~\cite{A-W:GMS94}, Section~14.3.}
+% for such code might look like this
+% (recall that all white space is ignored):
+%
+% \begin{verbatim}
+% %<*!check>
+% \cs_new_eq:NN
+% \toks_gset:Nn \tex_global:D
+% %</!check>
+% %<*check>
+% \cs_new_nopar:Npn
+% \toks_gset:Nn #1
+% {
+% \chk_global:N #1
+% \tex_global:D #1
+% }
+% %</check>
+% \end{verbatim}
+% In the above code the function |\toks_gset:Nn| takes a single
+% token~(|N|) specifying a token register, and globally sets it to the
+% value passed in the second argument.
+%
+% A typical use of it would be:
+% \begin{verbatim}
+% \toks_gset:Nn \g_xxx_toks {<some value>}
+% \end{verbatim}
+% In the normal definition, |\toks_gset:Nn| can be simply~|\let|
+% to~|\global| because the primitive \TeX{} token register does not
+% require any explicit assignment function:
+% this is done by the |%<*!check>| code above.
+%
+% The alternative definition first checks that the argument
+% passed as~|#1| is the name of a global parameter and raises an error
+% if it is not. It does this by taking apart the command name passed
+% as~|#1| and checking that it starts~|\g_|.
+%
+% \subsection{Consistency}
+% \label{sec:cons}
+%
+% The primitive \TeX\ syntax for register assignments has a very minimal
+% syntax and, apart from box functions, there are no explicit functions
+% for assigning values to these registers.
+%
+% This makes it impossible to implement alternative data-types with a
+% syntax that is both consistent and at all similar to the syntax for
+% the primitives; moreover, it encourages a coding style that is very
+% error prone.
+%
+% As in the |\toks_gset:Nn| example given above, all \LaTeX\ data-types
+% are provided with explicit functions for assignment and for use, even
+% when these have essentially empty definitions. This allows for better
+% error-checking as described above; it also allows the construction of
+% further data-types with a similar interface, even when the
+% implementation of the associated functions is very complex.
+%
+% For example, the `fake-integer' (\texttt{num}) data-type mentioned
+% above will appear at the \LaTeX{} programming level to be exactly like
+% the data-type based on primitive count registers; however, internally
+% it makes no use of count registers. Typical functions in this module
+% are illustrated here.
+%
+% \begin{verbatim}
+% \num_new:N \l_tmpa_num
+% \end{verbatim}
+% This declares the local parameter |\l_example_num| as a fake-counter.
+%
+% \begin{verbatim}
+% \num_add:Nn \l_example_num \c_thirty_two
+% \end{verbatim}
+% This increments the value of this fake-counter by 32.
+%
+%
+% \section{The experimental distribution}
+% \label{sec:dist}
+%
+% The initial implementations of a \LaTeX\ programming language using
+% this kind of syntax remain unreleased (and not completely functional);
+% they partly pre-date \LaTeXe! The planned distribution will provide a
+% subset of the functionality of those implementations, in the form of
+% packages to be used on top of \LaTeXe.
+%
+% The intention is to allow experienced \TeX\ programmers to experiment
+% with the system and to comment on the interface. This means that
+% \textbf{\itshape the interface will change}. No part of this system,
+% including the name of anything, should be relied upon as being
+% available in a later release. Please do \emph{experiment} with these
+% packages, but do \emph{not} use them for code that you expect to keep
+% unchanged over a long period.
+%
+% In view of the intended experimental use for this distribution we
+% shall, in the first instance, produce only a few modules for use with
+% \LaTeXe. These will set up the conventions and the basic functionality
+% of, for example, the expansion mechanism; they will also implement some
+% of the basic programming constructs, such as token-lists and sequences.
+% They are intended only to give a flavour of the code: the full \LaTeX3
+% kernel will provide a very rich set of programming constructs so that
+% packages can efficiently share code, in contrast with the situation in
+% the current \LaTeX\ where every large package must implement its own
+% version of queues, stacks, etc., as necessary.
+%
+% At time of writing the \textsf{expl3} bundle consists of the
+% following modules.
+%
+% This distribution will also contain the \LaTeX\ source for the latest
+% version of this document, a docstrip install file and three small test
+% files.
+%
+% \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{l3calc}{
+% A re-implementation of the \LaTeXe\ package \pkg{calc} package in
+% \pkg{expl3} that provides extended methods for numeric and dimensional
+% calculations and assignments.
+% }
+% \explpkg{l3chk}{
+% A module that provides functionality comparable to
+% \LaTeX's \cmd{\newcommand} and \cmd{\renewcommand}, and also the
+% extra level of
+% checking for ensure internal consistency in the code.
+% }
+% \explpkg{l3clist}{
+% Methods for manipulating comma-separated token lists.
+% }
+% \explpkg{l3expan}{
+% This is the argument expansion module discussed above.
+% }
+% \explpkg{l3int}{
+% This implements the integer data-type \texttt{int}.
+% }
+% \explpkg{l3io}{
+% A module providing low level input and output functions.
+% }
+% \explpkg{l3keyval}{
+% A re-implementation of the \LaTeXe\ package \pkg{keyval};
+% provides low-level macros for dealing with lists of the form
+% \texttt{\{ key1=val1 , key2=val2 \}}.
+% }
+% \explpkg{l3messages/l3msg}{
+% Communicating with the user.
+% }
+% \explpkg{l3names}{
+% This sets up the basic naming scheme and renames all
+% the \TeX\ primitives. If it is loaded with the option
+% \texttt{[removeoldnames]} then the old primitive names such as~\cmd{\box}
+% become \emph{undefined} and are thus available for user
+% definition. Caution: use of this option will certainly break existing
+% \TeX\ code!
+% }
+% \explpkg{l3num}{
+% This implements the `fake integer' datatype \texttt{num}.
+% }
+% \explpkg{l3precom}{
+% A `pre-compilation' module that provides functions dealing with pointer
+% creation and handling, and using external files to record the state of the current
+% definitions.
+% }
+% \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 `property lists' that are used, in
+% particular, for storing key/value pairs.
+% }
+% \explpkg{l3quark}{
+% A `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, \eg as
+% special markers and delimiters within code.
+% }
+% \explpkg{l3seq}{
+% This implements data-types such as queues and stacks.
+% }
+% \explpkg{l3skip}{
+% Implements the `rubber length' datatype \texttt{skip} and the
+% `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
+% essentially \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.
+% }
+% \explpkg{l3toks}{
+% A data-type corresponding to \TeX's primitive token registers.
+% }
+% \explpkg{l3xref}{
+% Data structure for low-level document cross-referencing. This
+% provided the foundation for Heiko Oberdiek's \pkg{zref} package.
+% }
+% \end{description}
+%
+% \begin{thebibliography}{1}
+%
+% \bibitem{A-W:K-TB}
+% Donald E Knuth
+% \newblock {\em The {\TeX}book}.
+% \newblock Addison-Wesley, Reading, Massachusetts, 1984.
+%
+% \bibitem{A-W:GMS94}
+% Goossens, Mittelbach and Samarin.
+% \newblock {\em The {\LaTeX} Companion}.
+% \newblock Addison-Wesley, Reading, Massachusetts, 1994.
+%
+% \bibitem{A-W:LLa94}
+% Leslie Lamport.
+% \newblock {\em {\LaTeX:} A Document Preparation System}.
+% \newblock Addison-Wesley, Reading, Massachusetts, second edition, 1994.
+%
+% \bibitem{tub:MR97-1}
+% Frank Mittelbach and Chris Rowley.
+% \newblock `The {\LaTeX3} Project'.
+% \newblock {\em {TUG}boat},
+% Vol.\,18, No.\,3, pp.\,195--198, 1997.
+%
+% \end{thebibliography}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \subsection{\pkg{expl3} implementation}
+%
+% Well, it's not complicated |:)|
+%
+%<*package>
+% \begin{macrocode}
+\ProvidesExplPackage
+ {\filename}{\filedate}{\fileversion}{\filedescription}
+% \end{macrocode}
+%
+% We already loaded \pkg{l3names} at the beginning of the \acro{dtx} file.
+%
+% The \pkg{l3chk} package is omitted since it is only used for conditional
+% processing with full error-checking turned on. Most users will generally
+% not need to do this, and we haven't set it up yet, anyway.
+%
+% Fundamentals:
+% \begin{macrocode}
+\RequirePackage{
+ l3basics,
+ l3expan,
+ l3tl,
+ l3num,
+ l3intexpr,
+ l3quark,
+ l3seq,
+ l3toks,
+ l3int,
+ l3prg,
+ l3clist,
+ l3token,
+ l3io,
+ l3prop,
+ l3msg,
+ l3skip,
+}
+% \end{macrocode}
+% All the rest:
+% \begin{macrocode}
+\RequirePackage{
+ l3box,
+ l3keyval,
+ l3precom,
+ l3calc,
+ l3xref,
+ l3file
+}
+% \end{macrocode}
+%</package>
+%
+% \end{implementation}
+%
+% \endinput
diff --git a/Master/texmf-dist/source/latex/expl3/expl3.tex b/Master/texmf-dist/source/latex/expl3/expl3.tex
deleted file mode 100644
index 8d9e1880667..00000000000
--- a/Master/texmf-dist/source/latex/expl3/expl3.tex
+++ /dev/null
@@ -1,753 +0,0 @@
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-% based on version for the TUGboat proceedings
-% Copyright 1997--98 David Carlisle, Chris Rowley, Frank Mittelbach
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-% $Id: expl3.tex 246 2004-11-11 08:20:37Z mittelba $
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\documentclass{article}
-
-\usepackage{shortvrb}
-\MakeShortVerb{\|}
-
-% A couple of \provide.. so document runs with
-% both ltugproc and ltxguide classes
-%
-\providecommand \m [1]{$\langle$\textit{#1}$\rangle$}
-%\providecommand \netaddress {\date}
-\providecommand \acro [1]{\textsc{\MakeLowercase{#1}}}
-\providecommand \ie {i.e.,~}
-\providecommand \eg {e.g.,~}
-
-\hyphenation{para-meters para-meter}
-% I have found at least 3 other hyphenations of this in various refs,
-% but I did also find this, which is my personal favourite ---chris
-
-\hyphenation{ignore ignored ignores}
-
-\begin{document}
-
-\title{The \LaTeX3 Programming Language---\\
-a proposed system for \TeX\ macro programming}
-
-
-\author{\copyright~David Carlisle, Chris Rowley and\\ Frank Mittelbach\\
-\LaTeX3 project\\
-\texttt{latex-l@urz.uni-heidelberg.de}}
-
-
-\maketitle
-
-\begin{abstract}
-
-This paper gives s brief 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.
-
-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}
-A system such as this is being used experimentally 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.
-
-This paper is based on a talk given by David Carlisle in San
-Francisco, July 1997, but it describes the work of several people:
-principally
- Frank Mittelbach and
- Denys Duchier,
-together with
- Johannes Braams,
- David Carlisle,
- Michael Downes,
- Alan Jeffrey,
- Chris Rowley and
- Rainer Sch\"opf.
-\end{abstract}
-
-\vspace{4pt}
-
-
-\section{Introduction}
-
-This paper describes the conventions for a \TeX-based programming
-language which is intended to provide a more consistent and rational
-environment for the construction of large scale systems, such as
-\LaTeX, using \TeX{} macros.
-
-Variants of this language have been in use by The \LaTeX3 Project Team
-since around 1990 but the syntax specification to be outlined here
-should \emph{not} be considered final. This is an experimental
-language thus many aspects, such as the syntax conventions and naming
-schemes, may (and probably will) change as more experience is gained
-with using the language in practice.
-
-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 semantics of the expansion control mechanism and the
-interface used to define variant forms of functions. The paper also
-discusses some advantages of the syntax for parameter names.
-
-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
-(especially when using a reasonably intelligent editor).
-
-The final section gives some details of our plans to distribute parts
-of this system during the next year.
-More general information concerning the work of the \LaTeX3 Project
-can be found in~\cite{tub:MR98-1}.
-
-
-\section{Languages and interfaces}
-\label{sec:langs}
-
-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{SGML} 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
- `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 (\eg
- |\box| or |\special|).
-
-\item[Designer interface] This relates a (human) typographic
- designer's specification for a document to a program that `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
- \acro{SGML}-based systems the \acro{DSSSL} language may come to play
- this role. 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 `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 `within' \TeX, as in the current \LaTeX\ system.
-\end{description}
-
-Only the last of these three interfaces is covered by this paper,
-which describes a system aimed at providing a suitable basis for
-coding large scale projects in \TeX{} (but this should not preclude its
-use for smaller projects). 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}
-\label{sec:scheme}
-
-The naming conventions for this programming language distinguish
-between \textit{functions} and \textit{parameters}. Functions can have
-arguments and they are executed. Parameters can be assigned values
-and they are used in arguments to functions; they are not directly
-executed but are manipulated by mutator and accessor functions.
-Functions and parameters with a related functionality (for example
-accessing counters, or manipulating token-lists, etc.)\ are collected
-together into a
-\textit{module}.
-
-
-Note that all these terms are only \LaTeX{} terminology and are not,
-for example, intended to indicate that the commands have these
-properties when considered in the context of basic \TeX{} or in any
-more general programming context.
-
-
-\subsection{Examples}
-\label{sec:ex}
-
-Before giving the details of the naming scheme, here are a few typical
-examples to indicate the flavour of the scheme; first some parameter
-names.
-\begin{quote}
-|\l_tmpa_box| is a local parameter (hence the~|l_| prefix)
-corresponding to a box register.\\
-|\g_tmpa_int| is a global parameter (hence the~|g_| prefix)
-corresponding to an integer register (\ie a \TeX{} count register).\\
-|\c_empty_toks|
-is the constant~(|c_|) token register parameter that is for ever empty.
-\end{quote}
-Now here is an example of a typical function name.
-
-|\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 `names'
-the stack parameter: such single-token arguments are denoted~|N|.
-The second argument is a normal \TeX\ `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 `normal' argument form.
-
-|\seq_push:cn| would be similar to the above, but in this case the~|c|
-means that the stack-name is specified in the first argument by a
-token list that expands, using |\csname...|, to a control sequence that
-is the \emph{name} of the stack parameter.
-
-\noindent
-The names of these two functions also indicate that they are in the
-module called |seq|.
-
-
-\subsection{Formal syntax of the conventions}
-\label{sec:namesyn}
-
-We shall now look in more detail at the syntax of these names.\\
-The syntax of parameter names is as follows:
- \begin{quote}
- |\|\m{access}|_|\m{module}|_|\m{description}|_|\m{type}
- \end{quote}
-The syntax of function names is as follows:
- \begin{quote}
- |\|\m{module}|_|\m{description}|:|\m{arg-spec}
- \end{quote}
-
-
-\subsection{Modules and descriptions}
-\label{sec:modules}
-
-The syntax of all names contains
-\begin{quote}
- \m{module} and \m{description}:
-\end{quote}
-these both give information about the command.
-
-A \textit{module} is a collection of
-closely related functions and parameters.
-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.
-
-The \textit{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.
-
-\subsection{Parameters: access and type}
-\label{sec:parms}
-
-The \m{access} part of the name describes how the parameter can be
-accessed. Parameters are primarily classified as local, global or
-constant (there are further, more technical, classes). This
-\textit{access} type appears as a code at the beginning of the name;
-the codes used include:
-\begin{itemize}
-\item[\bf c]
- constants (global parameters whose value should not be changed);
-\item[\bf g]
- parameters whose value should only be set globally;
-\item[\bf l]
- parameters whose value should only be set locally.
-\end{itemize}
-
-The \m{type} will normally (except when introducing a new data-type)
-be in the list of available \textit{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.
-
-Here are some typical data-type names:
-\begin{description}
-\item[int] integer-valued count register;
-\item[toks] token register;
-\item[box] box register;
-\item[fint] `Fake-integer': (or fake-counter) a data type created to
- avoid problems with the limited number of available count registers
- in (standard) \TeX;
-\item[seq] `sequence': a data-type used to implement lists
- (with access at both ends) and stacks;
-\item[plist] property list
-\end{description}
-When the \m{type} and \m{module} are identical (as often happens in
-the more basic modules) the \m{module} part is often omitted for
-aesthetic reasons.
-
-
-\subsection{Functions: argument specifications}
-\label{sec:args}
-
- Function names end with an \m{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 \m{arg-spec} consists of a (possibly empty) list of characters,
- each denoting one argument of the function. It is important to
- understand that `argument' here refers to the effective argument of
- the \LaTeX{} function, not to an argument at the \TeX-level. Indeed,
- the top level \TeX\ macro that has this name typically has no
- arguments. This is an extension of the existing \LaTeX\ convention
- where one says that |\section| has an optional argument and a
- mandatory argument, whereas the \TeX\ macro |\section| actually has
- zero parameters at the \TeX\ level, it merely calls an internal \LaTeX\
- command which in turn calls others that look ahead for star forms and
- optional arguments.
-
-The list of possible argument specifiers includes the following.
-\begin{itemize}
-\item[\bf n] Unexpanded token or braced token list.\\
- This is a standard \TeX\ undelimited macro argument.
-\item[\bf o] One-level-expanded token or braced token list.\\
- This means that the argument is expanded one level, as by
- |\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.
-\item[\bf 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.
-\item[\bf 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 (via~|\csname|, |\endcsname|). This command name is the single
- token that is passed to the function as the argument.
-\item[\bf 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~|\def|, in which the command being defined must be
- unbraced.
- \item[\bf O] One-level-expanded single token (unbraced).\\
- As for~|o|, the one-level expansion is passed (as a
- braced token list) to the function.
- \item[\bf X] Fully-expanded single token (unbraced).\\
- As for~|x|, the full expansion is passed (as a
- braced token list) to the function.
- \item[\bf C] Character string used as a command name
- then one-level expanded.\\
- The form of the argument is exactly as for~|c|, but the
- resulting token is then expanded one level (as for~|O|), and
- the expansion is passed to the function as a braced token list.
- \item[\bf 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|.
- \item[\bf T,F\hspace{-10pt}]
- \hspace{10pt}%
- These are special cases of~|n| arguments, used for the
- true and false code in conditional commands.
-\end{itemize}
-There are two other specifiers with more general meanings:
-\begin{itemize}
-\item[\bf 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. If the \TeX\ primitive
- needs to be used in other contexts it will be given an alternative,
- more appropriate, name with a useful argument specification. The
- argument syntax of these is often weird, in the sense described next.
- \item[\bf w] This means that the argument syntax is `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{itemize}
-
-
-\section{Expansion control}
-\label{sec:exp}
-
-\subsection{Simpler means better}
-\label{sec;simpler}
-
-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
- \expandafter
- \expandafter
- \let
- \expandafter
- \reserved@a
- \csname \curr@fontshape \endcsname
-\end{verbatim}
-This first piece of code is in essence simply a
-global |\let|. However, the token to be defined is obtained by
-expanding |\reserved@a| one level; and, worse, the token to which it
-is to be let is obtained by fully expanding |\curr@fontshape| and then
-using the characters produced by that expansion to construct a command
-name. 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}
- \glet:Oc \g_reserved_a_tlp
- \l_current_font_shape_tlp
-\end{verbatim}
-The command |\glet:Oc| is a global~|\let| that expands its
-first argument once, and generates a command name out of its second
-argument, before making the definition. This produces code that
-is far more readable and more likely to be correct first time.
-
-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 `\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:cO|. Now this code fragment will be simply:
-\begin{verbatim}
- \seq_test_in:cO {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}
-\label{sec:newfunc}
-
-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 `normal'
-\TeX\ undelimited arguments.
-
-To illustrate this let us suppose you have a `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}
- \exp_def_form:nnn {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
- \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}
- \exp_def_form:nnn
- {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{Parameter assignments and accessor functions}
-\label{sec:access}
-
-\subsection{Checking assignments}
-\label{sec:check}
-
-One of the advantages of having a consistent scheme is that the system
-can provide more extensive error-checking and debugging facilities.
-For example, an accessor function that makes a \emph{global}
-assignment of a value to a parameter can check that it is not passed
-the name of a \emph{local} parameter as that argument: it does this by
-checking that the name starts with~|\g_|.
-
-Such checking is probably too slow for normal use, but the code can
-have hooks built in that allow a format to be made in which all
-functions perform this kind of check.
-
-A typical section of the source%
-\footnote{This code uses the \textsf{docstrip}
-system described in~\cite{A-W:GMS94}, Section~14.3.}
-for such code might look like this
-(recall that all white space is ignored):
-
-\begin{verbatim}
- %<*!check>
- \let_new:NN
- \toks_gset:Nn \tex_global:D
- %</!check>
- %<*check>
- \def_new:Npn
- \toks_gset:Nn #1
- {
- \chk_global:N #1
- \tex_global:D #1
- }
- %</check>
-\end{verbatim}
-In the above code the function |\toks_gset:Nn| takes a single
-token~(|N|) specifying a token register, and globally sets it to the
-value passed in the second argument.
-
-A typical use of it would be:
-\begin{verbatim}
- \toks_gset \g_xxx_toks {<some value>}
-\end{verbatim}
-In the normal definition, |\toks_gset| can be simply~|\let|
-to~|\global| because the primitive \TeX{} token register does not
-require any explicit assignment function:
-this is done by the |%<*!check>| code above.
-
-The alternative definition first checks that the argument
-passed as~|#1| is the name of a global parameter and raises an error
-if it is not. It does this by taking apart the command name passed
-as~|#1| and checking that it starts~|\g_|.
-
-\subsection{Consistency}
-\label{sec:cons}
-
-The primitive \TeX\ syntax for register assignments has a very minimal
-syntax and, apart from box functions, there are no explicit functions
-for assigning values to these registers.
-
-This makes it impossible to implement alternative data-types with a
-syntax that is both consistent and at all similar to the syntax for
-the primitives; moreover, it encourages a coding style that is very
-error prone.
-
-As in the |\toks_gset:Nn| example given above, all \LaTeX\ data-types
-are provided with explicit functions for assignment and for use, even
-when these have essentially empty definitions. This allows for better
-error-checking as described above; it also allows the construction of
-further data-types with a similar interface, even when the
-implementation of the associated functions is very complex.
-
-For example, the `fake-counter' (\texttt{fint}) data-type mentioned
-above will appear at the \LaTeX{} programming level to be exactly like
-the data-type based on primitive count registers; however, internally
-it makes no use of count registers. Typical functions in this module
-are illustrated here.
-
-\begin{verbatim}
-\fint_new:N \l_tmpa_fint
-\end{verbatim}
-This declares the local parameter |\l_example_fint| as a fake-counter.
-
-\begin{verbatim}
-\fint_add:Nn \l_example_fint \c_thirty_two
-\end{verbatim}
-This increments the value of this fake-counter by 32.
-
-
-\section{The experimental distribution}
-\label{sec:dist}
-
-The initial implementations of a \LaTeX\ programming language using
-this kind of syntax remain unreleased (and not completely functional);
-they partly pre-date \LaTeXe! The planned distribution will provide a
-subset of the functionality of those implementations, in the form of
-packages to be used on top of \LaTeXe.
-
-The intention is to allow experienced \TeX\ programmers to experiment
-with the system and to comment on the interface. This means that
-\textbf{\itshape the interface will change}. No part of this system,
-including the name of anything, should be relied upon as being
-available in a later release. Please do \emph{experiment} with these
-packages, but do \emph{not} use them for code that you expect to keep
-unchanged over a long period.
-
-In view of the intended experimental use for this distribution we
-shall, in the first instance, produce only a few modules for use with
-\LaTeXe. These will set up the conventions and the basic functionality
-of, for example, the expansion mechanism; they will also implement some
-of the basic programming constructs, such as token-lists and sequences.
-They are intended only to give a flavour of the code: the full \LaTeX3
-kernel will provide a very rich set of programming constructs so that
-packages can efficiently share code, in contrast with the situation in
-the current \LaTeX\ where every large package must implement its own
-version of queues, stacks, etc., as necessary.
-
-In the first release of this experimental system at least the
-following modules will be distributed.
-\begin{description}
-\item[l3names] This sets up the basic naming scheme and renames all
-the \TeX\ primitives. If it is loaded with the option
-\texttt{[removeoldnames]} then the old primitive names such as~|\box|
-become \emph{undefined} and are thus available for user
-definition. Caution: use of this option will certainly break existing
-\TeX\ code!
-
-\item [l3basics]
-This contains the basic definition modules used
-by the other packages.
-
-\item[l3chk] A module that provides functionality comparable to
-\LaTeX's |\newcommand| and |\renewcommand|, and also the extra level of
-checking described above in section~\ref{sec:check}.
-
-\item[l3tlp]
-This implements a basic data-type, called a \textit{token-list
-pointer}, used for storing named token lists: these are essentially
-\TeX{} macros with no arguments.
-
-\item[l3expan] This is the argument expansion module discussed above.
-
-\item[l3quark] A `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, \eg as
-special markers and delimiters within code.
-
-\item[l3seq]
-This implements data-types such as queues and stacks.
-
-\item[l3prop]
-This implements the data-type for `property lists' that are used, in
-particular, for storing key/value pairs.
-
-\item[l3int]
-This implements the integer and `fake integer' data-types.
-
-\item[l3toks]
-A data-type corresponding to \TeX's primitive token registers.
-
-\item[l3io]
-A module providing low level input and output functions.
-
-\item[l3precom]
-A `pre-compilation' module that provides functions dealing with pointer
-creation and handling, and using external files to record the state of the current
-definitions.
-\end{description}
-This distribution will also contain the \LaTeX\ source for the latest
-version of this document, a docstrip install file and three small test
-files.
-
-
-In later releases we plan to add further modules and a full-fledged
-example of the use of the new language: a proto-type implementation
-for the ideas described in the article `Language Information in
-Structured Documents: A Model for Mark-up and
-Rendering'~\cite{tub:MR98-2}.
-
-\begin{thebibliography}{1}
-
-\bibitem{A-W:K-TB}
-Donald E Knuth
-\newblock {\em The {\TeX}book}.
-\newblock Addison-Wesley, Reading, Massachusetts, 1984.
-
-\bibitem{A-W:GMS94}
-Goossens, Mittelbach and Samarin.
-\newblock {\em The {\LaTeX} Companion}.
-\newblock Addison-Wesley, Reading, Massachusetts, 1994.
-
-\bibitem{A-W:LLa94}
-Leslie Lamport.
-\newblock {\em {\LaTeX:} A Document Preparation System}.
-\newblock Addison-Wesley, Reading, Massachusetts, second edition, 1994.
-
-\bibitem{tub:MR98-1}
-Frank Mittelbach and Chris Rowley.
-\newblock The {\LaTeX3} Project.
-\newblock {\em {TUG}boat}, ????? ??? 1998.
-
-\bibitem{tub:MR98-2}
-Frank Mittelbach and Chris Rowley.
-\newblock Language Information in
-Structured Documents: A Model for Mark-up and Rendering.
-\newblock {\em {TUG}boat}, ????? ??? 1998.
-
-\end{thebibliography}
-
-\end{document}
-
-
-
-
-
diff --git a/Master/texmf-dist/source/latex/expl3/l3.ins b/Master/texmf-dist/source/latex/expl3/l3.ins
index 14ac72c8532..9280d68eac5 100644
--- a/Master/texmf-dist/source/latex/expl3/l3.ins
+++ b/Master/texmf-dist/source/latex/expl3/l3.ins
@@ -1,107 +1,118 @@
-
-\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
-
-\keepsilent
-
-% l3names.sty sets up the naming scheme for TeX primitives.
-\generate{\file{l3names.sty}{\from{l3names.dtx}{package}}}
-
-
-
-% Define some basic commands to get us started with the new
-% programming style.
-\generate{\file{l3basics.sty}{\from{l3basics.dtx}{package,trace}}}
-
-
-% Define some basic commands that check various conditions
-% related to defining commands eg defined/undefined global/local
-% Not sure how much of this really makes sense as a package, but...
-\generate{\file{l3chk.sty}{\from{l3chk.dtx}{package,trace}}}
-
-
-%% toks register handling (can be compiled with check module)
-\generate{\file{l3toks.sty}{\from{l3toks.dtx}{package,trace}}}
-
-
-%% tlp handling
-\generate{\file{l3tlp.sty}{\from{l3tlp.dtx}{package,trace}}}
-
-
-%% LaTeX3 expansion module
-\generate{\file{l3expan.sty}{\from{l3expan.dtx}{package,trace}}}
-
-
-%% LaTeX3 quarks.
-\generate{\file{l3quark.sty}{\from{l3quark.dtx}{package,trace}}}
-
-
-%% LaTeX3 sequences.
-\generate{\file{l3seq.sty}{\from{l3seq.dtx}{package,trace}}}
-
-
-%% LaTeX3 clists.
-\generate{\file{l3clist.sty}{\from{l3clist.dtx}{package,trace}}}
-
-
-%% LaTeX3 property lists.
-\generate{\file{l3prop.sty}{\from{l3prop.dtx}{package,trace}}}
-
-
-%% LaTeX3 integer registers. (can be compiled with check module)
-\generate{\file{l3int.sty}{\from{l3int.dtx}{package,trace}}}
-
-
-%% LaTeX3 fake integer macros.
-\generate{\file{l3num.sty}{\from{l3num.dtx}{package,trace}}}
-
-%% LaTeX3 skip registers.
-\generate{\file{l3skip.sty}{\from{l3skip.dtx}{package,trace}}}
-
-
-%% LaTeX3 precompilation
-\generate{\file{l3precom.sty}{\from{l3precom.dtx}{package,precompile,trace}}}
-
-%% LaTeX3 I/O module.
-\generate{\file{l3io.sty}{\from{l3io.dtx}{package,trace}}}
-
-%% LaTeX3 program control structures (loops, booleans, ...)
-\generate{\file{l3prg.sty}{\from{l3prg.dtx}{package}}}
-
-%% LaTeX3 box module
-\generate{\file{l3box.sty}{\from{l3box.dtx}{package}}}
-
-%% LaTeX3 messages
-\generate{\file{l3messages.sty}{\from{l3messages.dtx}{package}}}
-
-%% LaTeX3 tokens
-\generate{\file{l3token.sty}{\from{l3token.dtx}{package}}}
-
-%% LaTeX3 cross references
-\generate{\file{l3xref.sty}{\from{l3xref.dtx}{package}}}
-\generate{\file{l3xref-test.tex}{\from{l3xref.dtx}{testfile}}}
-
-%% LaTeX3 calc module
-\generate{\file{l3calc.sty}{\from{l3calc.dtx}{package}}}
-
-%% LaTeX3 keyval module
-\generate{\file{l3keyval.sty}{\from{l3keyval.dtx}{package}}}
-
-
-\endbatchfile
+
+\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
+
+\keepsilent
+
+% wrapper package for the expl3 bundle
+\generate{\file{expl3.sty}{\from{expl3.dtx}{package}}}
+
+
+% l3names.sty sets up the naming scheme for TeX primitives.
+\generate{\file{l3names.sty}{\from{l3names.dtx}{package}}}
+
+
+
+% Define some basic commands to get us started with the new
+% programming style.
+\generate{\file{l3basics.sty}{\from{l3basics.dtx}{package,trace}}}
+
+
+% Define some basic commands that check various conditions
+% related to defining commands eg defined/undefined global/local
+% Not sure how much of this really makes sense as a package, but...
+\generate{\file{l3chk.sty}{\from{l3chk.dtx}{package,trace}}}
+
+
+%% toks register handling (can be compiled with check module)
+\generate{\file{l3toks.sty}{\from{l3toks.dtx}{package,trace}}}
+
+
+%% token lists
+\generate{\file{l3tl.sty}{\from{l3tl.dtx}{package,trace}}}
+
+
+%% LaTeX3 expansion module
+\generate{\file{l3expan.sty}{\from{l3expan.dtx}{package,trace}}}
+
+
+%% LaTeX3 quarks.
+\generate{\file{l3quark.sty}{\from{l3quark.dtx}{package,trace}}}
+
+
+%% LaTeX3 sequences.
+\generate{\file{l3seq.sty}{\from{l3seq.dtx}{package,trace}}}
+
+
+%% LaTeX3 clists.
+\generate{\file{l3clist.sty}{\from{l3clist.dtx}{package,trace}}}
+
+
+%% LaTeX3 property lists.
+\generate{\file{l3prop.sty}{\from{l3prop.dtx}{package,trace}}}
+
+
+%% LaTeX3 integer registers. (can be compiled with check module)
+\generate{\file{l3int.sty}{\from{l3int.dtx}{package,trace}}}
+
+
+%% LaTeX3 fake integer macros.
+\generate{\file{l3num.sty}{\from{l3num.dtx}{package,trace}}}
+
+%% LaTeX3 integer expressions.
+\generate{\file{l3intexpr.sty}{\from{l3intexpr.dtx}{package,trace}}}
+
+
+%% LaTeX3 skip registers.
+\generate{\file{l3skip.sty}{\from{l3skip.dtx}{package,trace}}}
+
+
+%% LaTeX3 precompilation
+\generate{\file{l3precom.sty}{\from{l3precom.dtx}{package,precompile,trace}}}
+
+%% LaTeX3 I/O module.
+\generate{\file{l3io.sty}{\from{l3io.dtx}{package,trace}}}
+
+%% LaTeX3 program control structures (loops, booleans, ...)
+\generate{\file{l3prg.sty}{\from{l3prg.dtx}{package}}}
+
+%% LaTeX3 box module
+\generate{\file{l3box.sty}{\from{l3box.dtx}{package}}}
+
+%% LaTeX3 messages
+\generate{\file{l3msg.sty}{\from{l3msg.dtx}{package}}}
+
+%% LaTeX3 tokens
+\generate{\file{l3token.sty}{\from{l3token.dtx}{package}}}
+
+%% LaTeX3 cross references
+\generate{\file{l3xref.sty}{\from{l3xref.dtx}{package}}}
+%%\generate{\file{l3xref-test.tex}{\from{l3xref.dtx}{testfile}}}
+
+%% LaTeX3 calc module
+\generate{\file{l3calc.sty}{\from{l3calc.dtx}{package}}}
+
+%% LaTeX3 keyval module
+\generate{\file{l3keyval.sty}{\from{l3keyval.dtx}{package}}}
+
+%% LaTeX3 file loading
+\generate{\file{l3file.sty}{\from{l3file.dtx}{package}}}
+
+
+\endbatchfile
diff --git a/Master/texmf-dist/source/latex/expl3/l32eproc.tex b/Master/texmf-dist/source/latex/expl3/l32eproc.tex
deleted file mode 100644
index d560c0c2338..00000000000
--- a/Master/texmf-dist/source/latex/expl3/l32eproc.tex
+++ /dev/null
@@ -1,523 +0,0 @@
-\documentclass
- {ltugproc}
-% {ltxguide}
-
-\usepackage{shortvrb}
-\MakeShortVerb{\|}
-\setlength\hfuzz{10pt}
-
-% A couple of \provide.. so document runs with
-% both ltugproc and ltxguide classes
-%
-\providecommand\m[1]{$\langle$\textit{#1}$\rangle$}
-\providecommand\netaddress{\date}
-\providecommand\acro[1]{\textsc{\MakeLowercase{#1}}}
-
-\begin{document}
-\title{The \LaTeX3 Programming Language\\
-A syntax proposal for \TeX\ macro programming}
-
-
-\author{The \LaTeX3 Project}
-\netaddress{latex-l@urz.uni-heidelberg.de}
-
-
-
-\begin{abstract}
-This paper proposes a new set of programming conventions suitable for
-implementing large scale \TeX\ programming projects such as \LaTeX.
-(This syntax is not suitable for either document
-markup, or as a style specification language.)
-
-The main features include a systematic naming scheme for all commands,
-and a systematic mechanism for controlling the expansion of arguments
-to functions.
-
-The syntax is under consideration as a basis for programming within
-the \LaTeX3 project.
-
-This paper is based on a talk given by David
-Carlisle but describes the work of several people, principally:
- Frank Mittelbach,
- Denys Duchier,
- Rainer Sch\"opf,
- Chris Rowley,
- Michael Downes,
- Johannes Braams,
- David Carlisle and
- Alan Jeffrey.
-\end{abstract}
-
-\maketitle
-
-
-\section{Introduction}
-This paper describes a \TeX\ based language which is intended to
-provide a more consistent and rational programming environment for the
-construction of large scale \TeX\ macro projects such as \LaTeX.
-
-Variants of this language have been in use within the \LaTeX3 project
-since around 1990 but the syntax specification to be outlined here
-should \emph{not} be considered final. This is an experimental
-language, and the syntax and command names may (and probably will)
-change as more experience is gained with using the language in
-practice.
-
-\section{Programming Interface levels for \LaTeX}
-
-One may identify several distinct languages that one might want to see
-in a \TeX\ based system. This paper will \emph{only} be concerned with
-the last of these three.
-
-\begin{description}
-\item[Document Markup] This language consists of the commands that are
- to be embedded in the document instance. It is generally accepted
- that such a language should be essentially \emph{declarative}.
- One might consider a traditional \TeX\ based markup such as the
- \LaTeX2 markup as described in \cite{A-W:LLa94}, or alternatively one
- might consider an \acro{SGML} based markup.
-
- One problem with more traditional \TeX\ coding conventions is that
- the command names and syntax of the \TeX\ primitives are designed to
- have a `natural' syntax when used directly by the author as document
- markup. In fact one almost never uses the primitives in this
- way, rather they are just used to define higher level commands.
-
-\item[Designer's Interface] In order to easily translate a (human)
- designer's design specification into a program that accepts the
- document instance one would ideally like to have a declarative
- language that allows the relationships and spacing rules of the
- various document elements to be easily expressed. As this language
- is not embedded within the document text, it may take a rather
- different form to the markup language described above. For
- \acro{SGML} based systems one may consider the \acro{DSSSL} language
- as playing this role. For \LaTeX2, then this level was essentially
- missing in \LaTeX2.09. \LaTeXe\ made some improvements in this area
- but it is still the case that implementing a design specification in
- \LaTeX\ requires more `low level' coding than would be desired.
-\item[Programmer's Interface]
- This language, the subject of this paper, is the implementation
- language in which the basic typesetting functionality is
- implemented, building upon the primitives supplied by \TeX\ (or a
- successor program). It may also be used to implement the previous
- two languages `within' \TeX, as in the current \LaTeX\ system.
-\end{description}
-
-
-\section{Programming language: Main Features}
-
-The language outlined in this paper aims to provide a suitable
-base for coding large (and small) scale projects in \TeX.
-Its main distinguishing features are the following.
-\begin{itemize}
-\item Consistent naming scheme for all functions, including \TeX\
- primitives.
-\item Standard mechanisms for controlling argument expansion.
-\item Provision of sufficiently rich set of core functions for
- handling programming constructs such as:
- sequences, sets, stacks, property lists, etc.
-\item White space ignored.
-\end{itemize}
-
-\section{Naming Scheme}
-
-The name space is divided between \emph{Functions} and
-\emph{Parameters}. Functions (normally) take arguments and are
-executed, Parameters are usually passed as arguments to functions.
-They are not directly executed, but accessed though accessor functions.
-
-Functions and parameters associated with a similar function (for
-example accessing counters, or manipulating lists, etc.) are arranged
-into \emph{modules}. Before giving the details of the form of the
-command names, we give a few examples.
-
-|\l_tmpa_box| is a local parameter (hence the |l_| prefix)
-corresponding to a box register.
-
-|\g_tmpa_box| is a global parameter (hence the |g_| prefix)
-corresponding to a box register.
-
-|\c_one| is the constant (|c_|) parameter with value one.
-
-|\cnt_add:Nn| is the function which adds the value specified by
-its second argument to the count register 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 specifying
-the name of the count parameter. Such single token arguments are
-denoted |N|. The second argument is a normal \TeX\ `non-delimited
-argument' which may either be a single token, or a brace delimited
-token list containing an expression for the value to be added.
-The |n| denotes such `normal' argument forms.
-
-|\cnt_add:cn| is similar to the above, but in this case the the
-counter is specified in the first argument by a list of tokens that
-expands to the \emph{name} of the count parameter.
-
-These examples should give the basic flavour of the scheme. Parameters
-are classified into local, global or constant (there are further more
-technical cases in addition to these three) and this access type is
-shown by |\l_|, |\g_| or |\c_|. Functions are arranged by
-\emph{module} (The |cnt| module in these cases) with a descriptive
-name followed by an indication of the type of argument to be passed.
-
-In more detail the specification of the names is as follows.
-
-Functions have the following general syntax:
- \begin{quote}
- |\|\m{module}|_|\m{description}|:|\m{arg-spec}
- \end{quote}
- The programmer can chose an arbitrary \m{module} name (consisting
- of letters only) a group of functions with related functionality are
- then all given names prefixed by this module name. The \m{description}
- is a description of the functionality of the function, and should
- consist of letters, and possibly |_| characters. \m{arg-spec}
- describes the type of arguments as will be described below.
-
-The syntax of parameters is as follows:
- \begin{quote}
- |\|\m{access}|_|\m{module}|_|\m{description}|_|\m{type}
- \end{quote}
- \m{access} describes how the parameter can be accessed. The
- principal access types are \emph{constant}, \emph{local} or
- \emph{global}. As described below, some special access types relate
- to \TeX\ primitive parameters. The meanings of \m{module} and
- \m{description} in the parameter syntax is the same as that for
- functions. Finally \m{type} should denote the type of parameter,
- such as |cnt| for count registers, etc.
-
-
-
-Typical \m{module} names in the kernel include |cnt| for integer count
-related functions, |seq| for functions relating to sequences, |box|,
-etc. Normally additional packages adding new functionality would add
-new modules as needed.
-
-The \m{description} is an arbitrary name for the function or
-parameter, consisting of letters, or the |_| character.
-
-Function names always end with an \m{arg-spec} after a final colon.
-This gives an indication of the types of argument that a function
-takes, and provides a convenient method of naming similar functions
-that just differ by their argument forms, as will be explained below.
-
-The \m{arg-spec} consists of a (possibly empty) list of characters
-each denoting one argument that the function takes. It is important to
-note that `argument' here refers to the conceptual argument of the
-function.
-The top level \TeX\ macro that has this name typically has no
-arguments. This is similar to the existing \LaTeX\ convention where one
-says that |\section| has an optional argument and a mandatory
-argument, whereas the \TeX\ macro |\section| actually takes no
-parameters at the \TeX\ level, it merely calls some standard \LaTeX\
-internal functions which look ahead for star forms and optional
-arguments. The list of possible argument specifiers includes:
-\begin{description}
-\item[n] Unexpanded token (or token-list if in braces). In other words
- this is a standard \TeX\ undelimited macro argument.
-\item[o] One time expanded token or token-list. In the case of a token
- list then only the first token in the list is expanded.
-\item[x] Fully expanded token or token-list. Typically this means that
- the argument is expanded in the style of |\edef| (|\def:Npx|) before
- being passed to the function.
-\item[c] A character string used (after expansion) as a command name.
- The argument (a token or braced token list) should expand to a
- sequence of characters which is then used to construct a command
- name (via |\csname|, |\cs:w|). This command token is passed as the
- argument to the function.
- \item[N] A single token. (Unlike |n|, this argument must not be
- surrounded by braces). A typical example of a command taking an N
- argument is |\def|, in which the command being defined must be
- unbraced.
- \item[O] Single unbraced token that is expanded once and passed (as a
- braced token list) to the function.
- \item[X] Single unbraced token that is fully expanded and passed (as a
- braced token list) to the function.
- \item[C] A character string used as for |c| arguments but the
- resulting command token is then expanded (as for |O|) and the
- result passed as a braced token list to the function.
- \item[p] A primitive \TeX\ parameter specification. This can be
- something simple like |#1#2#3| but may be arbitrary delimited
- argument syntax, such as |#1,#2\q_stop#3|.
- \item[T, F] These are special cases of |n| arguments, used as the
- true and false cases in conditional tests.
- \item[D] `Do not use'. This special case is used for \TeX\ primitives
- that are only used while bootstrapping the \LaTeX\ kernel. If the
- \TeX\ primitive needs to be used in other contexts it will be given
- an alternative name with a more appropriate argument specification.
- \item[w] `weird' syntax. Used for arguments that take non standard
- forms, usually delimited arguments that are needed internally to
- implement certain modules, and also the boolean tests of many of the
- primitive |\if|\ldots\ tests.
-\end{description}
-
-
-For parameters, the \m{type} should be from the list of available
-data types (which include the primitive \TeX\ registers, but also
-data types built within the system).
-
-Possible values for \m{type} include:
-\begin{description}
-\item[cnt] Integer valued counter.
-\item[toks] Token register.
-\item[box] Box register.
-\item[fcnt] `Fake' count register. A data type supplied by the kernel
- to avoid problems with the limited number of available count
- registers in (standard) \TeX.
-\end{description}
-
-The \m{access} codes that are used in parameter names include
-\begin{description}
-\item[c] Constants.
-\item[l] Parameters that should only be set locally.
-\item[g] Parameters that should only be set globally.
-\end{description}
-
-\section{Checking Parameter assignments}
-One of the advantages of having a consistent scheme is that the system
-can provide more extensive error checking and debugging facilities.
-For example a function that makes a global assignment can check that
-it is not passed a local parameter as argument by checking that the
-name of the command to be assigned starts with |\g_|. Such checking is
-probably too slow for production runs, but the kernel has hooks built
-in to allow a format to be made in which all functions perform this
-kind of check. A typical section of code might look like
-\begin{verbatim}
-%<*check>
-\def_new:Npn \toks_gset:Nn #1 {
- \chk_global:N #1
- \pref_global:D #1
-}
-%</check>
-%<*!check>
-\let_new:NN
- \toks_gset:Nn \pref_global:D
-%</!check>
-\end{verbatim}
-The function |\toks_gset:Nn| takes a single token (|N|) specifying a
-token register, and globally sets it to the value passed in the second
-argument. So typical use would be
-\begin{verbatim}
-\toks_gset \g_xxx_toks {some value}
-\end{verbatim}
-In the normal definition, |\toks_gset| can be defined just to be |\let|
-to |\global|, as the primitive token register does not require any
-explicit assignment function. This is the |%<*!check>| code above.
-However the alternative definition first checks that the argument
-passed as |#1| is a global parameter and raises an error if it is not.
-It does this by taking apart the command name passed as |#1| and
-checking that it starts |\g_|.
-
-\section{Consistent use of accessor functions}
-The primitive \TeX\ syntax for register assignments has a very minimal
-syntax, and apart from box functions there are no explicit functions
-for assignment or use of the registers. This makes it very difficult
-to implement alternative data types with a syntax that is at all
-similar to the syntax for the primitives, and also encourages a coding
-style that is very error prone.
-
-As noted in the example given above, The \LaTeX\ data types are
-provided with explicit functions for setting and using the parameters
-even when these have essentially empty definitions. This allows for
-better error checking as described above, and also allows the
-construction of alternative data types with a similar interface.
-For example the `fake counter' data type mentioned previously works at
-the user level just like the data type based on primitive count
-registers, internally it does not use count registers though.
-Typical functions in the |fcnt| module include:
-
-
-\verb|\fcnt_new:N \l_tempa_fcnt|\\
-Declare the local parameter |\l_tempa_fcnt| as a fake counter.
-
-\verb|\fcnt_add:Nn \l_tempa_fcnt \c_thirty_two|\\
-Increment the counter by 32.
-
-\section{Expansion Control}
-Anyone who programs in \TeX\ is used to the problem of arranging that
-arguments to functions are suitably expanded before the function is
-called. A couple of real examples copied from \texttt{latex.ltx}:
-\begin{verbatim}
-\global
- \expandafter\expandafter\expandafter
- \let
- \expandafter
- \reserved@a
- \csname\curr@fontshape\endcsname
-
-\expandafter
- \in@
- \csname sym#3\expandafter\endcsname
- \expandafter{\group@list}%
-\end{verbatim}
-The first piece of code is a global |\let|. The token to be defined
-is obtained by expanding \verb|\reserved@a| one level. The command
-that it is to be let too is obtained by fully expanding
-\verb|\curr@fontshape| and then using the tokens produced by that
-expansion to construct a command name. This results in the mess
-of interwoven \verb|\expandafter| and \verb|\csname| beloved of all
-\TeX\ programmers, and code that is essentially unreadable.
-
-A similar construction using the conventions outlined here would be
-\begin{verbatim}
-\glet:Oc
- \reserved_a: \l_current_font_shape_tlp
-\end{verbatim}
-The command \verb|\glet:Oc| is a global |\let| that expands its
-argument once, and generates a command name out of its second
-argument, before making the definition. This produces coe that
-is far more readable.
-
-Similarly the second piece of code above produces a token list by
-expanding \verb|\group@list| once, and then creates a command name out
-of `\verb|sym#3|' (this is inside the definition of another fumction).
-The function |\in@| is called which tests if its first argument occurs
-in the token list of its second argument.
-
-Again it would be much clearer, if the above function \verb|\in@| was
-called (say) \verb|\test_if_in:nn| (a function taking two normal
-`\texttt{n}' arguments) and then a variant function was defined with
-the appropriate argument types and simply called as follows:
-\begin{verbatim}
-\test_if_in:co {sym#3} \group_list:
-\end{verbatim}
-Note that apart from the lack of \verb|\expandafter| the space after
-\verb|}| will be silently ignored.
-
-
-For many common functions the kernel will provide functions with a
-range of argument forms, and similarly it is expected that extension
-packages providing new functions will make then available in the more
-common forms. However There will be occasions where it is necessary
-to construct such a variant form.
-
-A consistent mechanism is provided by the kernel to produce functions
-with any argument type, starting from a function that takes `normal'
-\TeX\ delimited arguments. Suppose you have a function \verb|\cmd:nnn|
-that takes two arguments, and you need to construct \verb|\cmd:cnx|
-a variant form in which the first argument is passed as a \emph{name}
-of a command, and the third argument must be fully expanded before
-being passed to \verb|\cmd:nnn|.
-
-One simply defines \verb|\cmd:cx| as follows:
-\begin{verbatim}
-\def:Nn \cmd:cnx {\exp_args:Ncnx \cmd:nnn}
-\end{verbatim}
-The function \verb|\exp_args:Ncnx| takes as its first (\texttt{N})
-argument the `base' function, and then grabs the next three arguments
-from the token stream, acts on the first with \verb|\csname|, and the
-last with \verb|\edef| and then constructs a call to the base function
-with suitably transformed arguments. So
-\begin{verbatim}
-\cmd:cnx {abc}{pq}{\rst\xyz}
-\end{verbatim}
-is equivalent, but emminently more readable, to
-\begin{verbatim}
-\edef\temp{\rst\xyz}
-\expandafter\cmd:nnn
- \csname abc\expandafter\endcsname
- \expandafter{%
- \expandafter p\expandafter q%
- \expandafter}%
- \expandafter{\temp}
-\end{verbatim}
-
-A large range of argument processing functions are provided in
-addition to \verb|\exp_args:Ncnx|. If you need a particular argument
-combination for which a function is not provided, one may be
-constructed in a simple way. For example you need to construct
-\verb|\exp_args:Nxcxcxc| a function that fully expands arguments
-1,~3 and~5 of a given function, and produces commands to pass as
-arguments 2,~4 and~6 using \verb|\csname|. The definition is simply
-\begin{verbatim}
-\def:Npn \exp_args:Nxcxcxc
- {\::x\::c\::x\::c\::x\::c\:::}
-\end{verbatim}
-Similar functions, |::o| etc exist for all the other argument types,
-and they may be strung together in any order, terminated by
-\verb|\:::| to create a function which processes arguments in the
-desired way.
-
-As hopefully demonstrated, the use of variant forms greatly improves
-the readability of the code, and experience shows that the longer
-command names which result from the new syntax do not realy make the
-process of \emph{writing} the code any harder.
-
-\section{The Current Experimental Distribution}
-The initial implementations of a \TeX\ format using this kind of
-syntax were made with an unreleased (and non functional) format
-(which pre-dates \LaTeXe!) The current distribution consists of a
-subset of the functionality of that format, converted to run as
-packages on top of \LaTeXe.
-
-The intention is to allow experienced \TeX\ programmers to experiment
-on the system and to comment on the interface. This means that
-\textbf{\itshape the interface will change}. No part of this system,
-including the names of any commands should be relied upon as being
-available in a later release. Please do \emph{experiment} with these
-packages, but do not use them for documents that you expect to keep
-unchanged over a long period.
-
-In view of the proposed experimental use for this distribution, we
-currently have only converted a few modules for use with \LaTeXe.
-These set up the basic conventions, and then implement a few basic
-programming constructs such as lists and sequences. These are really
-to give a flavour of the code, and to indicate that the intention is
-that the kernel provide a sufficiently rich set of programming
-constructs so that packages may use them and thus more efficiently
-share code, unlike the situation in the current \LaTeX\ where every
-large package implements its own version of lists, stacks etc.
-
-The current packages are:
-\begin{description}
-\item[l3names]
-Sets up the basic naming scheme, including naming the \TeX\
-primitives. If used with the option \texttt{[removeoldnames]}
-then the old primitive names such as \verb|\box| are \emph{undefined}
-and thus made available for user definitions. Use of this option might
-possibly break existing \TeX\ code!
-
-\item [l3basics]
-Some basic definitions that are used by the other packages.
-
-\item[l3chk]
-Functions to check (and make) definitions (comparable to the existing
-\verb|\newcommand| or \verb|\renewcommand|).
-
-\item[l3tlp]
-Token List Pointers. A basic \LaTeX3 data type for storing token lists.
-(These are essentially macros with no arguments.)
-
-
-\item[l3expan]
-The argument expansion module discussed in the previous section.
-
-
-\item[l3quarq]
-
-A `quark' is a command that is defined to expand to itself. So it may
-not be directly used (it would generate an infinite loop) but has many
-uses as special markers within \LaTeX\ code.
-
-
-\item[l3seq]
-A module implementing the basic list and stack data types.
-
-\item[l3prop]
-Property lists are the data type for handling key/value assignments.
-\end{description}
-
-The distribution also contains the \TeX\ source for this document, a
-docstrip install file and two small test files.
-
-\begin{thebibliography}{1}
-
-\bibitem{A-W:LLa94}
-Leslie Lamport.
-\newblock {\em {\LaTeX:} A Document Preparation System}.
-\newblock Addison-Wesley, Reading, Massachusetts, second edition, 1994.
-
-\end{thebibliography}
-
-\end{document}
-
-
diff --git a/Master/texmf-dist/source/latex/expl3/l3alloc.dtx b/Master/texmf-dist/source/latex/expl3/l3alloc.dtx
index 76f141a25b0..a2031c45493 100644
--- a/Master/texmf-dist/source/latex/expl3/l3alloc.dtx
+++ b/Master/texmf-dist/source/latex/expl3/l3alloc.dtx
@@ -1,5 +1,5 @@
% \iffalse
-%% File: l3alloc.dtx Copyright (C) 1990-2006 LaTeX3 project
+%% File: l3alloc.dtx Copyright (C) 1990-2006,2009 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
@@ -17,7 +17,7 @@
%%
%% The development version of the bundle can be found at
%%
-%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/
+%% http://www.latex-project.org/svnroot/experimental/trunk/
%%
%% for those people who are interested.
%%
@@ -36,7 +36,7 @@
\RequirePackage{l3names}
%</driver|package>
%\fi
-\GetIdInfo$Id: l3alloc.dtx 621 2007-09-01 20:14:19Z morten $
+\GetIdInfo$Id: l3alloc.dtx 1362 2009-05-28 20:19:21Z joseph $
{L3 Experimental register allocation}%
%\iffalse
%<*driver>
@@ -44,7 +44,7 @@
\ProvidesFile{\filename.\filenameext}
[\filedate\space v\fileversion\space\filedescription]
%\iffalse
-\documentclass{l3doc}
+\documentclass[full]{l3doc}
\begin{document}
\DocInput{\filename.\filenameext}
\end{document}
@@ -60,6 +60,8 @@
% \date{\filedate}
% \maketitle
%
+% \begin{documentation}
+%
% \section{Allocating registers and the like}
%
% This module provides the basic mechanism for allocating \TeX's
@@ -77,9 +79,9 @@
% \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 efficient.
+% accessed somewhat less efficiently.
% \item Registers could be allocated both globally and locally; the
-% use of regsiters could also be globaly or locally. Here we
+% use of registers could also be globaly or locally. Here we
% provide support for globally allocated registers for both
% gloabl and local use and for locally allocated registers for
% local use only.
@@ -88,60 +90,67 @@
% register was allocated last and which registers can not be
% allocated by the standard mechanisms.
%
-% \subsection{Functions}
+% \section{Functions}
%
% \begin{function}{\alloc_setup_type:nnn}
% \begin{syntax}
-% "\alloc_setup_type:nnn" <type> <g_start_num> <l_start_num>
+% "\alloc_setup_type:nnn" \Arg{type} \Arg{g_start_num} \Arg{l_start_num}
% \end{syntax}
% Sets up the storage needed for the administration of registers of
% type <type>.\\
% <type> should be a token list in braces, it can be one of
% "int", "dimen", "skip", "muskip", "box", "toks", "ior", "iow",
% "pattern", or "ins".\\
-% <g_start_num> is the number of the first not allocated global
+% <g_start_num> is the number of the first non-allocated global
% register, it will be incremented by 1 when the allocation is done.
-% <l_start_num> is the number of the first not allocated local
+% <l_start_num> is the number of the first non-allocated local
% register, it will be decremented by 1 when the allocation is done.
% \end{function}
%
% \begin{function}{\alloc_reg:NnNN}
% \begin{syntax}
-% "\alloc_reg:NnNN" <g-l> <type> <alloc_cmd> <cs>
+% "\alloc_reg:NnNN" "g"$\big/$"l" <type> <alloc_cmd> <cs>
% \end{syntax}
-% Performs the allocation of a register of type <type> to copntrol
+% Performs the allocation of a register of type <type> to control
% sequence <cs>, using the command <alloc_cmd>. The "g" or "l"
-% indicaties whether the allocation should be global or local.
+% indicates whether the allocation should be global or local.
% This macro is the basic building block for the definition of the
% "\"<type>"_new:N" commands
% \end{function}
%
-% \StopEventually{}
+% \end{documentation}
%
-% \subsection{The Implementation}
+% \begin{implementation}
%
-% We start by ensuring that the required packages are loaded when
-% this file is loaded as a package on top of \LaTeXe.
+% \section{\pkg{l3alloc} implementation}
%
-% \begin{macrocode}
-%<package>\ProvidesExplPackage
-%<package> {\filename}{\filedate}{\fileversion}{\filedescription}
-%<package>\RequirePackage{l3expan}
-%<package>\RequirePackage{l3num}
-%<package>\RequirePackage{l3seq}\par
-% \end{macrocode}
+% \subsection{Internal functions}
%
+% \begin{function}{ \alloc_next_g:n |
+% \alloc_next_l:n }
+% \begin{syntax}
+% "\alloc_next_g:n" \Arg{type}
+% \end{syntax}
+% These functions find the next free register for the specified type.
+% \end{function}
+%
+% \subsection{Module code}
%
% \begin{macrocode}
+%<*package>
+\ProvidesExplPackage
+ {\filename}{\filedate}{\fileversion}{\filedescription}
+\package_check_loaded_expl:
+%</package>
%<*initex|package>
% \end{macrocode}
%
% \begin{macro}{\alloc_setup_type:nnn}
% For each type of register we need to `counters' that hold the
% last allocated global or local register. We also need a sequence
-% to store the `excpetions'.
+% to store the `exceptions'.
% \begin{macrocode}
-\def_new:Npn \alloc_setup_type:nnn #1 #2 #3{
+\cs_new_nopar:Npn \alloc_setup_type:nnn #1 #2 #3{
\num_new:c {g_ #1 _allocation_num}
\num_new:c {l_ #1 _allocation_num}
\seq_new:c {g_ #1 _allocation_seq}
@@ -156,27 +165,28 @@
% These routines find the next free register. For globally allocated
% registers we first increment the counter that keeps track of them.
% \begin{macrocode}
-\def_new:Npn \alloc_next_g:n #1 {
+\cs_new_nopar:Npn \alloc_next_g:n #1 {
\num_gincr:c {g_ #1 _allocation_num}
% \end{macrocode}
% Then we need to check whether we have run out of registers.
% \begin{macrocode}
- \num_compare:cNcTF {g_ #1 _allocation_num} = {l_ #1 _allocation_num}
- {\io_put_term:x{We~ ran~ out~ of~ registers~ of~ type~ g_#1!}}
- {
+ \intexpr_compare:nTF {
+ \num_use:c{g_ #1 _allocation_num} = \num_use:c{l_ #1 _allocation_num}
+ }
+ {\iow_term:x{We~ ran~ out~ of~ registers~ of~ type~ g_#1!}}
+ {
% \end{macrocode}
-% We also need to check wether the value of the counter already
+% We also need to check whether the value of the counter already
% occurs in the list of already allocated registers.
% \begin{macrocode}
- \seq_if_in:cxTF {g_ #1 _allocation_seq}
- {\num_use:c{g_ #1 _allocation_num}}
- {\io_put_term:x{\num_use:c{g_ #1 _allocation_num}~Already~ allocated!}
+ \seq_if_in:cxT {g_ #1 _allocation_seq}
+ {\num_use:c{g_ #1 _allocation_num}}
% \end{macrocode}
% If it does, we find the next value.
% \begin{macrocode}
+ { \iow_term:x{\num_use:c{g_ #1 _allocation_num}~already~allocated!}
\alloc_next_g:n {#1} }
- {\use_noop:}
- }
+ }
% \end{macrocode}
% By now the |.._allocation_num| counter will contain the number of
% the register we will assign a control seuence for.
@@ -185,42 +195,47 @@
% \end{macrocode}
% For the locally allocated registers we have a similar function.
% \begin{macrocode}
-\def_new:Npn \alloc_next_l:n #1 {
+\cs_new_nopar:Npn \alloc_next_l:n #1 {
\num_gdecr:c {l_ #1 _allocation_num}
- \num_compare:cNcTF {g_ #1 _allocation_num} = {l_ #1 _allocation_num}
- {\io_put_term:x{We~ ran~ out~ of~ registers~ of~ type~ l_#1!}}
+% \end{macrocode}
+% (Will: should that be "\num_decr" (no "g") ?!)
+% \begin{macrocode}
+ \intexpr_compare:nTF {
+ \num_use:c{g_ #1 _allocation_num} = \num_use:c{l_ #1 _allocation_num}
+ }
+ {\iow_term:x{We~ ran~ out~ of~ registers~ of~ type~ l_#1!}}
{
\seq_if_in:cxTF {g_ #1 _allocation_seq}
{\num_use:c{l_ #1 _allocation_num}}
- {\io_put_term:x{\num_use:c{l_ #1 _allocation_num}~Already~ allocated!}
+ { \iow_term:x{\num_use:c{l_ #1 _allocation_num}~already~allocated!}
\alloc_next_l:n {#1} }
- {\io_put_term:x{\num_use:c{l_ #1 _allocation_num}~Free!}}
- }
+ { \iow_term:x{\num_use:c{l_ #1 _allocation_num}~free!} }
+ }
}
% \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\alloc_reg:NnNN}
-% This internal macro performs the actual allocation. It's first
+% This internal macro performs the actual allocation. Its first
% argument is either 'g' for a globally allocated register or `l'
% for a locally allocated register. The second argument is the
% type of register to allocate, the third argument is the command
% to use and the fourth argument is the control sequence that is to
% be defined to point to the register.
% \begin{macrocode}
-\def_new:Npn \alloc_reg:NnNN #1 #2 #3 #4{
+\cs_new_nopar:Npn \alloc_reg:NnNN #1 #2 #3 #4{
% \end{macrocode}
% It first checks that the control sequence that is to denote the
% register does not already exist.
% \begin{macrocode}
- \chk_new_cs:N #4
+ \chk_if_free_cs:N #4
% \end{macrocode}
% Next, it decides whether a prefix is needed for the allocation
% command;
% \begin{macrocode}
- \if:w#1g
- \exp_after:NN \pref_global:D
+ \if:w #1 g
+ \exp_after:wN \pref_global:D
\fi:
% \end{macrocode}
% And finally the actual allocation takes place.
@@ -230,45 +245,28 @@
% \end{macrocode}
% All that's left to do is write a message in the log file.
% \begin{macrocode}
- \io_put_log:x{
- \token_to_string:N#4=#2~register~\num_use:c{#1_ #2 _allocation_num}}
+ \iow_log:x{
+ \token_to_str:N#4=#2~register~\num_use:c{#1_ #2 _allocation_num}}
% \end{macrocode}
-% Finally, it calls |\alloc_next_<g/l>| to find the next free register
+% Finally, it calls |\alloc_next_|\meta{\texttt{\textup g}/\texttt{\textup l}} to find the next free register
% number.
% \begin{macrocode}
- \cs_use:c{alloc_next_#1:n} {#2}
+ \use:c{alloc_next_#1:n} {#2}
}
% \end{macrocode}
% \end{macro}
%
+% \begin{macrocode}
+%</initex|package>
+% \end{macrocode}
%
% \begin{macrocode}
%<*showmemory>
\showMemUsage
%</showmemory>
-%</initex|package>
% \end{macrocode}
%
-% \endinput
-%
-% $Log$
-% Revision 1.6 2006/03/20 18:26:32 braams
-% Updated the copyright notice (2006) and demoted all implementation
-% sections to subsections and so on to clean up the toc for source3.tex
-%
-% Revision 1.5 2006/01/15 14:02:58 braams
-% Added a \SopEventually{} command
-%
-% Revision 1.4 2005/12/27 16:02:18 morten
-% Changed RCS information retrieval
-%
-% Revision 1.3 2005/04/06 22:32:38 braams
-% Removed the functins that belong in other modules;
-% Fixed the naming conventions
-%
-% Revision 1.2 2005/04/05 22:12:44 braams
-% First, working, version of the regsiter allocation support
-%
-% Revision 1.1 2005/03/16 22:50:02 braams
-% Initial register allocation module
+% \end{implementation}
+% \PrintIndex
%
+% \endinput
diff --git a/Master/texmf-dist/source/latex/expl3/l3basics.dtx b/Master/texmf-dist/source/latex/expl3/l3basics.dtx
index e34e42f2732..ecbafc5d6b9 100644
--- a/Master/texmf-dist/source/latex/expl3/l3basics.dtx
+++ b/Master/texmf-dist/source/latex/expl3/l3basics.dtx
@@ -1,5 +1,5 @@
% \iffalse
-%% File: l3basics.dtx Copyright (C) 1990-2006 LaTeX3 project
+%% File: l3basics.dtx Copyright (C) 1990-2008 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
@@ -17,7 +17,7 @@
%%
%% The development version of the bundle can be found at
%%
-%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/
+%% http://www.latex-project.org/svnroot/experimental/trunk/
%%
%% for those people who are interested.
%%
@@ -35,7 +35,7 @@
\RequirePackage{l3names}
%</driver|package>
%\fi
-\GetIdInfo$Id: l3basics.dtx 702 2007-11-27 14:21:49Z morten $
+\GetIdInfo$Id: l3basics.dtx 1365 2009-05-31 17:26:17Z mittelba $
{L3 Experimental basic definitions}
%\iffalse
%<*driver>
@@ -43,9 +43,9 @@
\ProvidesFile{\filename.\filenameext}
[\filedate\space v\fileversion\space\filedescription]
%\iffalse
-\documentclass{l3doc}
+\documentclass[full]{l3doc}
\begin{document}
-\DocInput{\filename.\filenameext}
+\DocInput{l3basics.dtx}
\end{document}
%</driver>
% \fi
@@ -59,41 +59,116 @@
% \date{\filedate}
% \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.
%
-% \section{Basics}
-%
-% Here we describe those functions that used all over the place. With
+% 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.
%
-% \subsection{Predicates and conditionals}
+% \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 \m{true arg} or the \m{false
+% arg}.
+% These arguments are denoted with "T" and "F" repectively. 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 `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 \m{true
+% code} and/or \m{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 `predicate' for the same test
+% as described below.
+%
+% \item[Predicates]
+% `Predicates' are functions that return a special type of boolean
+% value which can be tested by the function "\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 `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" \m{true code} "\else:"
+% \m{false code} "\fi:"
+% \end{quote}
+% or in expressions utilizing the boolean logic parser:
+% \begin{quote}
+% "\bool_if:nTF {" \\
+% " \cs_if_free_p:N \l_tmpz_tl || \cs_if_free_p:N \g_tmpz_tl " \\
+% "}"
+% \Arg{true code} \Arg{false code}
+% \end{quote}
%
-% \subsubsection{Primitive conditionals}
+% 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 `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 \LaTeX. 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}
+%
+%
+% \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|.
+% |\intexpr_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}{%
-% \if_true: |
-% \if_false: |
-% \else: |
-% \fi: |
-% \reverse_if:N |
-% }
+% \begin{function}{ \if_true: / (EXP) |
+% \if_false: / (EXP) |
+% \or: / (EXP) |
+% \else: / (EXP) |
+% \fi: / (EXP) |
+% \reverse_if:N / (EXP) }
% \begin{syntax}
% "\if_true:" <true code> "\else:" <false code> "\fi:" \\
% "\if_false:" <true code> "\else:" <false code> "\fi:" \\
@@ -101,37 +176,31 @@
% \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.
+% 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}{%
-% \if_meaning:NN |
-% \if_cs_meaning_eq:NN |
-% \if_token_eq:NN |
-% }
+% \begin{function}{ \if_meaning:w / (EXP) }
% \begin{syntax}
-% "\if_meaning:NN" <cs1> <cs2> <true code> "\else:" <false code>
-% "\fi:" \\
-% "\if_cs_meaning_eq:NN" <cs1> <cs2> <true code> "\else:"
-% <false code> "\fi:" \\
-% "\if_token_eq:NN" <token1> <token2> <true code> "\else:" <false
-% code> "\fi:"
+% "\if_meaning:w" <arg1> <arg2> <true code> "\else:" <false code> "\fi:"
% \end{syntax}
-% "\if_meaning:NN" executes <true code> when the replacement text,
-% i.e., the expansion of <cs1> and <cs2> are the same, otherwise it
-% executes <false code>. However this name isn't really that
-% good. What the \TeX\ primitive does is compare two tokens to see if
-% they are equal. Hence this is actually a "token" functions. A
-% similar argument applies to the situation where it is used to
-% compare control sequences, where it is the meaning being compared.
-% Something to be cleaned up at some point.
+% "\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}{%
-% \if:w |
-% \if_charcode:w |
-% \if_catcode:w
-% }
+% \begin{function}{ \if:w / (EXP) |
+% \if_charcode:w / (EXP) |
+% \if_catcode:w / (EXP) }
% \begin{syntax}
% "\if:w" <token1> <token2> <true code> "\else:" <false code> "\fi:" \\
% "\if_catcode:w" <token1> <token2> <true code> "\else:" <false
@@ -145,10 +214,30 @@
% identical. "\if_charcode:w" is an alternative name for "\if:w".
% \end{function}
%
-% \begin{function}{%
-% \if_cs_exist:N |
-% \if_cs_exist:w
-% }
+%
+% \begin{function}{\if_predicate:w / (EXP)}
+% \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}{\if_bool:N / (EXP)}
+% \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}{ \if_cs_exist:N / (EXP) |
+% \if_cs_exist:w / (EXP) }
% \begin{syntax}
% "\if_cs_exist:N" <cs> <true code> "\else:" <false code> "\fi:" \\
% "\if_cs_exist:w" <tokens> "\cs_end:" <true code> "\else:" <false
@@ -162,357 +251,388 @@
% \end{function}
%
% \begin{function}{
-% \if_mode_horizontal: |
-% \if_mode_vertical: |
-% \if_mode_math: |
-% \if_mode_inner:
-% }
+% \if_mode_horizontal: / (EXP) |
+% \if_mode_vertical: / (EXP) |
+% \if_mode_math: / (EXP) |
+% \if_mode_inner: / (EXP) }
% \begin{syntax}
-% "\if_horizontal_mode:" <true code> "\else:" <false code> "\fi:"
+% "\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}
%
-% \subsubsection{Non-primitive conditionals}
+% \subsection{Non-primitive conditionals}
%
-% \begin{function}{%
-% \cs_if_eq_p:NN
-% }
+% \begin{function}{ \cs_if_eq_name_p:NN }
% \begin{syntax}
-% "\cs_if_eq_p:NN" <cs1> <cs2>
+% "\cs_if_eq_name_p:NN" <cs1> <cs2>
% \end{syntax}
% Returns `true' if <cs1> and <cs2> are textually the same, i.e.\ have
% the same name, otherwise it returns `false'.
% \end{function}
%
-% \begin{function}{%
-% \cs_if_eq:NNTF |
-% \cs_if_eq:NNT |
-% \cs_if_eq:NNF |
-% \cs_if_eq:cNTF |
-% \cs_if_eq:cNT |
-% \cs_if_eq:cNF |
-% \cs_if_eq:NcTF |
-% \cs_if_eq:NcT |
-% \cs_if_eq:NcF |
-% \cs_if_eq:ccTF |
-% \cs_if_eq:ccT |
-% \cs_if_eq:ccF
-% }
+% \begin{function}{ \cs_if_eq_p:NN / (EXP) |
+% \cs_if_eq_p:cN / (EXP) |
+% \cs_if_eq_p:Nc / (EXP) |
+% \cs_if_eq_p:cc / (EXP) |
+% \cs_if_eq:NN / (TF)(EXP) |
+% \cs_if_eq:cN / (TF)(EXP) |
+% \cs_if_eq:Nc / (TF)(EXP) |
+% \cs_if_eq:cc / (TF)(EXP) }
% \begin{syntax}
-% "\cs_if_eq:NNTF" <cs1> <cs2> "{"<true code>"}{"<false code>"}"
+% "\cs_if_eq_p:NNTF" <cs1> <cs2>
+% "\cs_if_eq:NNTF" <cs1> <cs2> \Arg{true code} \Arg{false code}
% \end{syntax}
-% These functions check if <cs1> and <cs2> have same meaning and then
-% execute either <true code> or <false code>.
+% These functions check if <cs1> and <cs2> have same meaning.
% \end{function}
%
%
-% \begin{function}{%
-% \cs_if_free_p:N
-% }
+% \begin{function}{ \cs_if_free_p:N / (EXP) |
+% \cs_if_free_p:c / (EXP) |
+% \cs_if_free:N / (TF)(EXP) |
+% \cs_if_free:c / (TF)(EXP) }
% \begin{syntax}
% "\cs_if_free_p:N" <cs>
+% "\cs_if_free:NTF" <cs> \Arg{true code} \Arg{false code}
% \end{syntax}
-% Returns `true' if <cs> is either undefined or equal to "\scan_stop:".
-% However, it returns `false' if <cs> is textually "\c_undefined" (the
-% constantly undefined function), or textually "\scan_stop:".
+% Returns `true' if <cs> is either undefined or equal to
+% "\tex_relax:D" (the function that is assigned to newly created
+% control sequences by \TeX{} when "\cs:w" "..." "\cs_end:" is
+% used). In addition to this, `true' is only returned if <cs> does not
+% have a signature equal to "D", i.e., `do not use' functions are not
+% free to be redefined.
% \end{function}
%
-% \begin{function}{%
-% \cs_if_free:NTF |
-% \cs_if_free:NT |
-% \cs_if_free:NF |
-% \cs_if_free:cTF |
-% \cs_if_free:cT |
-% \cs_if_free:cF
-% }
+% \begin{function}{ \cs_if_exist_p:N / (EXP) |
+% \cs_if_exist_p:c / (EXP) |
+% \cs_if_exist:N / (TF)(EXP) |
+% \cs_if_exist:c / (TF)(EXP) }
% \begin{syntax}
-% "\cs_if_free:NTF" <cs> "{"<true code>"}{"<false code>"}"
+% "\cs_if_exist_p:N" <cs>
+% "\cs_if_exist:NTF" <cs> \Arg{true code} \Arg{false code}
% \end{syntax}
-% These functions check if <cs> is free and then execute either <true
-% code> or <false code>.
-% \begin{texnote}
-% The conditional "\cs_if_free:cTF" is the \LaTeX3 implementation of
-% the \LaTeX2 function \tn{@ifundefined}. The other functions
-% haven't been around before.
-% \end{texnote}
+% These functions check if <cs> exists, i.e., if <cs> is present in
+% the hash table and is not the primitive "\tex_relax:D".
% \end{function}
%
-% \begin{function}{%
-% \cs_if_really_free:cTF |
-% \cs_if_really_free:cF |
-% \cs_if_really_free:cT
-% }
+% \begin{function}{ \cs_if_do_not_use_p:N / (EXP) }
% \begin{syntax}
-% "\cs_if_really_free:cTF" "{"<tokens>"}" "{"<true code>"} {"<false
-% code>"}"
+% "\cs_if_do_not_use_p:N" <cs>
% \end{syntax}
-% Similar to "\cs_if_free:cTF" but does not put anything previously
-% undefined into the hash table. Useful for special control sequences
-% like "\foo/bar" which cannot be entered as one token.
+% These functions check if <cs> has the arg spec "D" for `\emph{do not use}'.
+% There are no "TF"-type conditionals for this function as it is only used
+% internally and not expected to be widely used. (For now, anyway.)
% \end{function}
%
-% \begin{function}{%
-% \cs_if_exist_p:N
-% }
+% \begin{function}{ \chk_if_free_cs:N }
% \begin{syntax}
-% "\cs_if_exist_p:N" <cs>
+% "\chk_if_free_cs:N" <cs>
% \end{syntax}
-% This function does the opposite of "\cs_if_free_p:N".
+% This function checks that <cs> is \m{free} according to the criteria
+% for "\cs_if_free_p:N" above. If not, an error is generated.
% \end{function}
%
-% \begin{function}{%
-% \cs_if_exist:NTF |
-% \cs_if_exist:NT |
-% \cs_if_exist:NF |
-% \cs_if_exist:cTF |
-% \cs_if_exist:cT |
-% \cs_if_exist:cF
-% }
+% \begin{function}{ \chk_if_exist_cs:N |
+% \chk_if_exist_cs:c }
% \begin{syntax}
-% "\cs_if_exist:NTF" <cs> "{"<true code>"}{"<false code>"}"
+% "\chk_if_exist_cs:N" <cs>
% \end{syntax}
-% These functions check if <cs> exists and then execute either <true
-% code> or <false code>. Exactly the opposite of "\cs_if_free:NTF".
+% This function checks that <cs> is defined. If it is not an error
+% is generated.
% \end{function}
%
-% \begin{function}{%
-% \cs_if_really_exist:cTF |
-% \cs_if_really_exist:cF |
-% \cs_if_really_exist:cT
-% }
+% \begin{variable}{ \c_true_bool | \c_false_bool }
% \begin{syntax}
-% "\cs_if_really_exist:cTF" "{"<tokens>"}" "{"<true code>"} {"<false
-% code>"}"
% \end{syntax}
-% The opposite of "\cs_if_really_free:cTF".
-% \end{function}
+% Constants that represent `true' or `false', respectively. Used to
+% implement predicates.
+% \end{variable}
%
+% \subsection{Applications}
%
-% \begin{function}{%
-% \chk_new_cs:N |
-% }
+% \begin{function}{ \str_if_eq_p:nn / (EXP) }
% \begin{syntax}
-% "\chk_new_cs:N" <cs>
+% "\str_if_eq_p:nn" \Arg{string1} \Arg{string2}
% \end{syntax}
-% This function checks that <cs> is so far either undefined or equals
-% "\scan_stop:" (the function that is assigned to newly created
-% control sequences by \TeX{} when "\cs:w" "..." "\cs_end:" is
-% used).
+% Expands to `true' if <string1> is the same as <string2>,
+% otherwise `false'. Ignores spaces within the strings.
% \end{function}
%
-% \begin{function}{%
-% \chk_exist_cs:N |
-% \chk_exist_cs:c
-% }
+% \begin{function}{ \str_if_eq_var_p:nf / (EXP) }
% \begin{syntax}
-% "\chk_exist_cs:N" <cs>
+% "\str_if_eq_var_p:nf" \Arg{string1} \Arg{string2}
% \end{syntax}
-% This function checks that <cs> is defined. If it is not an error
-% is generated.
+% A variant of "\str_if_eq_p:nn" which has the advantage of
+% obeying spaces in at least the second argument.
% \end{function}
%
%
-% \begin{variable}{%
-% \c_true |
-% \c_false
-% }
+% \section{Control sequences}
+%
+% \begin{function}{ \cs:w / (EXP) | \cs_end: / (EXP) }
% \begin{syntax}
+% "\cs:w" <tokens> "\cs_end:"
% \end{syntax}
-% Constants that represent `true' or `false', respectively. Used to
-% implement predicates.
-% \end{variable}
+% This is the \TeX{} internal way of generating a control sequence from
+% some token list. <tokens> get expanded and must ultimately result in a
+% sequence of characters.
+% \begin{texnote}
+% These functions are the primitives \tn{csname} and \tn{endcsname}.
+% "\cs:w" is considered weird because it expands tokens until it reaches
+% "\cs_end:".
+% \end{texnote}
+% \end{function}
%
+% \begin{function}{ \cs_show:N |
+% \cs_show:c }
+% \begin{syntax}
+% "\cs_show:N" <cs>
+% "\cs_show:c" \Arg{arg}
+% \end{syntax}
+% This function shows in the console output the \emph{meaning} of the control
+% sequence <cs> or that created by <arg>.
+% \begin{texnote}
+% This is \TeX's |\show| and associated csname version of it.
+% \end{texnote}
+% \end{function}
%
+% \begin{function}{ \cs_meaning:N / (EXP) |
+% \cs_meaning:c / (EXP) }
+% \begin{syntax}
+% "\cs_meaning:N" <cs>
+% "\cs_meaning:c" \Arg{arg}
+% \end{syntax}
+% This function expands to the \emph{meaning} of the control sequence <cs> or
+% that created by <arg>.
+% \begin{texnote}
+% This is \TeX's |\meaning| and associated csname version of it.
+% \end{texnote}
+% \end{function}
%
-% \subsection{Selecting and discarding tokens from the input stream}
+% \section{Selecting and discarding tokens from the input stream}
%
-% The conditional processing could not have been implemented without
+% The conditional processing cannot be implemented without
% being able to gobble and select which tokens to use from the input
% stream.
+%
%
-% \begin{function}{%
-% \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{function}{ \use:n / (EXP) |
+% \use:nn / (EXP) |
+% \use:nnn / (EXP) |
+% \use:nnnn / (EXP) }
% \begin{syntax}
-% "\use_none:n" "{"<arg1>"}"\\
-% "\use_none:nn" "{"<arg1>"}{"<arg2>"}"
+% "\use:n" \Arg{arg}
% \end{syntax}
-% These functions gobble the tokens or brace groups from the input
-% stream.
+% Functions that returns all of their arguments to the input stream after
+% removing the surrounding braces around each argument.
+% \begin{texnote}
+% "\use:n" is \LaTeXe's "\@firstofone"/"\@iden".
+% \end{texnote}
% \end{function}
%
+% \begin{function}{ \use:c / (EXP) }
+% \begin{syntax}
+% "\use:c" \Arg{cs}
+% \end{syntax}
+% Function that returns to the input stream the control sequence created from
+% its argument. Requires two expansions before a control sequence is returned.
+% \begin{texnote}
+% "\use:c" is \LaTeXe's "\@nameuse".
+% \end{texnote}
+% \end{function}
%
-% \begin{function}{\use_arg_i:n}
+% \begin{function}{ \use_none:n / (EXP) |
+% \use_none:nn / (EXP) |
+% \use_none:nnn / (EXP) |
+% \use_none:nnnn / (EXP) |
+% \use_none:nnnnn / (EXP) |
+% \use_none:nnnnnn / (EXP) |
+% \use_none:nnnnnnn / (EXP) |
+% \use_none:nnnnnnnn / (EXP) |
+% \use_none:nnnnnnnnn / (EXP) }
% \begin{syntax}
-% "\use_arg_i:n" "{" <code1> "}"
+% "\use_none:n" \Arg{arg1}\\
+% "\use_none:nn" \Arg{arg1} \Arg{arg2}
% \end{syntax}
-% Function that executes the next argument after removing the
-% surrounding braces. Used to implement conditionals.
+% These functions gobble the tokens or brace groups from the input
+% stream.
+% \begin{texnote}
+% "\use_none:n", "\use_none:nn", "\use_none:nnnn" are \LaTeXe's
+% "\@gobble", "\@gobbletwo", and "\@gobblefour".
+% \end{texnote}
% \end{function}
%
-% \begin{function}{%
-% \use_arg_i:nn |
-% \use_arg_ii:nn |
-% }
+% \begin{function}{ \use_i:nn / (EXP) |
+% \use_ii:nn / (EXP) }
% \begin{syntax}
-% "\use_arg_i:nn" "{" <code1> "}{" <code2> "}"
+% "\use_i:nn" \Arg{code1} \Arg{code2}
% \end{syntax}
% Functions that execute the first or second argument respectively,
% after removing the surrounding braces. Primarily used to implement
% conditionals.
+% \begin{texnote}
+% These are \LaTeXe's "\@firstoftwo" and "\@secondoftwo", respectively.
+% \end{texnote}
% \end{function}
%
-% \begin{function}{%
-% \use_arg_i:nnn |
-% \use_arg_ii:nnn |
-% \use_arg_iii:nnn |
-% }
+% \begin{function}{ \use_i:nnn / (EXP) |
+% \use_ii:nnn / (EXP) |
+% \use_iii:nnn / (EXP) }
% \begin{syntax}
-% "\use_arg_i:nnn" "{" <arg1> "}{" <arg2> "}{" <arg3> "}"
+% "\use_i:nnn" \Arg{arg1} \Arg{arg2} \Arg{arg3}
% \end{syntax}
% Functions that pick up one of three arguments and execute them after
-% removing the surrounding braces. Should be described somewhere else.
+% removing the surrounding braces.
+% \begin{texnote}
+% \LaTeXe\ has only "\@thirdofthree".
+% \end{texnote}
% \end{function}
%
-% \begin{function}{%
-% \use_arg_i:nnnn |
-% \use_arg_ii:nnnn |
-% \use_arg_iii:nnnn |
-% \use_arg_iv:nnnn |
-% }
+% \begin{function}{ \use_i:nnnn / (EXP) |
+% \use_ii:nnnn / (EXP) |
+% \use_iii:nnnn / (EXP) |
+% \use_iv:nnnn / (EXP) }
% \begin{syntax}
-% "\use_arg_i:nnnn" "{" <arg1> "}{" <arg2> "}{" <arg3> "}{" <arg4> "}"
+% "\use_i:nnnn" \Arg{arg1} \Arg{arg2} \Arg{arg3} \Arg{arg4}
% \end{syntax}
% Functions that pick up one of four arguments and execute them after
% removing the surrounding braces.
% \end{function}
%
-% A different kind of functions for selecting tokens from the token
-% stream are those that use delimited arguments.
+% \subsection{Extending the interface}
%
-% \begin{function}{%
-% \use_none_delimit_by_q_nil:w |
-% \use_none_delimit_by_q_stop:w |
-% }
+% \begin{function}{ \use_i_ii:nnn / (EXP) }
+% \begin{syntax}
+% "\use_i_ii:nnn" \Arg{arg1} \Arg{arg2} \Arg{arg3}
+% \end{syntax}
+% This function used in the expansion module reads three arguments and
+% returns (without braces) the first and second argument while
+% discarding the third argument.
+%
+% If you wish to select multiple arguments while discarding others,
+% use a syntax like this. Its definition is
+% \begin{verbatim}
+% \cs_set:Npn \use_i_ii:nnn #1#2#3 {#1#2}
+% \end{verbatim}
+% \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}{ \use_none_delimit_by_q_nil:w / (EXP) |
+% \use_none_delimit_by_q_stop:w / (EXP) |
+% \use_none_delimit_by_q_recursion_stop:w / (EXP) }
% \begin{syntax}
% "\use_none_delimit_by_q_nil:w" <balanced text> "\q_nil"
% \end{syntax}
% Gobbles <balanced text>. Useful in gobbling the remainder in a list
-% structure.
+% structure or terminating recursion.
% \end{function}
%
-% \begin{function}{%
-% \use_arg_i_delimit_by_q_nil:nw |
-% \use_arg_i_delimit_by_q_stop:nw |
-% }
+% \begin{function}{ \use_i_delimit_by_q_nil:nw / (EXP) |
+% \use_i_delimit_by_q_stop:nw / (EXP) |
+% \use_i_delimit_by_q_recursion_stop:nw / (EXP) }
% \begin{syntax}
-% "\use_arg_i_delimit_by_q_nil:nw" "{"<arg>"}" <balanced text> "\q_nil"
+% "\use_i_delimit_by_q_nil:nw" \Arg{arg} <balanced text> "\q_nil"
% \end{syntax}
% Gobbles <balanced text> and executes <arg> afterwards. This can also
% be used to get the first item in a token list.
% \end{function}
%
%
-% \begin{function}{%
-% \use_arg_i_after_fi:nw |
-% \use_arg_i_after_else:nw |
-% \use_arg_i_after_or:nw |
-% \use_arg_i_after_orelse:nw
-% }
+% \begin{function}{ \use_i_after_fi:nw / (EXP) |
+% \use_i_after_else:nw / (EXP) |
+% \use_i_after_or:nw / (EXP) |
+% \use_i_after_orelse:nw / (EXP) }
% \begin{syntax}
-% "\use_arg_i_after_fi:nw" "{"<arg>"}" "\fi:"
-% "\use_arg_i_after_else:nw" "{"<arg>"}" "\else:" <balanced text> "\fi:"
-% "\use_arg_i_after_or:nw" "{"<arg>"}" "\or:" <balanced text> "\fi:"
-% "\use_arg_i_after_orelse:nw" "{"<arg>"}" "\or:/\else:" <balanced text> "\fi:"
+% "\use_i_after_fi:nw" \Arg{arg} "\fi:"
+% "\use_i_after_else:nw" \Arg{arg} "\else:" <balanced text> "\fi:"
+% "\use_i_after_or:nw" \Arg{arg} "\or:" <balanced text> "\fi:"
+% "\use_i_after_orelse:nw" \Arg{arg} "\or:/\else:" <balanced text> "\fi:"
% \end{syntax}
% Executes <arg> after executing closing out
-% "\fi:". "\use_arg_i_after_orelse:nw" can be used anywhere where
-% "\use_arg_i_after_else:nw" or "\use_arg_i_after_or:nw" are used.
+% "\fi:". "\use_i_after_orelse:nw" can be used anywhere where
+% "\use_i_after_else:nw" or "\use_i_after_or:nw" are used.
% \end{function}
%
-% \subsection{Internal functions}
%
-% \begin{function}{%
-% \cs:w |
-% \cs_end:
-% }
+% \section{That which belongs in other modules but needs to be defined earlier}
+%
+% \begin{function}{ \exp_after:wN / (EXP) }
% \begin{syntax}
-% "\cs:w" <tokens> "\cs_end:"
+% "\exp_after:wN" <token1> <token2>
% \end{syntax}
-% This is the \TeX{} internal way of generating a control sequence from
-% some token list. <tokens> get expanded and must ultimately result in a
-% sequence of characters.
+% Expands <token2> once and then continues processing from <token1>.
% \begin{texnote}
-% These functions are the primitives \tn{csname} and \tn{endcsname}.
-% "\cs:w" is considered weird because it expands tokens until it reaches
-% "\cs_end:".
-% \end{texnote}
+% This is \TeX's \tn{expandafter}.
+% \end{texnote}
% \end{function}
%
-% \begin{function}{\pref_global:D |
-% \pref_long:D |
-% \pref_protected:D |
-% }
+% \begin{function}{ \exp_not:N / (EXP) | \exp_not:n / (EXP) }
% \begin{syntax}
-% "\pref_global:D" "\def:Npn"
+% "\exp_not:N" <token>
+% "\exp_not:n" \Arg{tokens}
% \end{syntax}
-% Prefix functions that can be used in front of some definition
-% functions (namely \ldots). The result of prefixing a function
-% definition with "\pref_global:D" makes the definition global,
-% "\pref_long:D" change the argument scanning mechanism so that it
-% allows "\par" tokens in the argument of the prefixed function,
-% and "\pref_protected:D" makes the definition robust in "\write"s etc.
-%
-%
-% None of these internal functions should be used by a programmer since
-% the necessary combinations are all available as separate function,
-% e.g., "\def_long:Npn" is internally implemented as "\pref_long:D"
-% "\def:Npn".
+% In an expanding context, this function prevents <token> or <tokens> from
+% expanding.
% \begin{texnote}
-% These prefixes are the primitives \tn{global}, \tn{long}, and
-% \tn{protected}. The \tn{outer} isn't used at all within \LaTeX3
-% because \ldots
+% These are \TeX's \tn{noexpand} and \eTeX's \tn{unexpanded}, respectively.
% \end{texnote}
% \end{function}
%
+% \begin{function}{ \prg_do_nothing: / (EXP) }
+% This is as close as we get to a null operation or no-op.
+% \begin{texnote}
+% Definition as in \LaTeX's \tn{\@empty} but not used for the same thing.
+% \end{texnote}
+% \end{function}
%
-%
-% \begin{function}{\io_put_log:x |
-% \io_put_term:x |
-% \io_put_deferred:Nx |
-% }
+% \begin{function}{ \iow_log:x |
+% \iow_term:x |
+% \iow_shipout_x:Nn }
% \begin{syntax}
-% "\io_put_log:x" "{"<message>"}"
-% "\io_put_deferred:Nx" <write_stream> "{"<message>"}"
+% "\iow_log:x" \Arg{message}
+% "\iow_shipout_x:Nn" <write_stream> \Arg{message}
% \end{syntax}
% Writes <message> to either to log or the terminal.
% \end{function}
%
-% \subsection{Defining functions}
+% \begin{function}{ \msg_kernel_bug:x }
+% \begin{syntax}
+% "\msg_kernel_bug:x" \Arg{message}
+% \end{syntax}
+% Internal function for calling errors in our code.
+% \end{function}
+%
+% \begin{function}{ \cs_record_meaning:N }
+% Placeholder for a function to be defined by \file{l3chk}.
+% \end{function}
+%
+% \begin{variable}{ \c_minus_one | \c_zero | \c_sixteen }
+% Numeric constants.
+% \end{variable}
+%
+%
+%
+% \section{Defining functions}
%
%
% There are two types of function definitions in \LaTeX3: versions
% that check if the function name is still unused, and versions that
-% simply make the definition. The later are used for internal scratch
+% simply make the definition. The latter are used for internal scratch
% functions that get new meanings all over the place.
%
% For each type there is an additional choice to be made: Does the
% function to be defined contain delimited arguments? The answer in
-% 99\% of the cases is no, so in most cases the programmer just want
-% to input the number of arguments, which is basically how
-% \cs{newcommand} in \LaTeXe{} works. Therefore we provide functions
-% that expect a number as the primary type and later on in this module
-% you can find the ones with the more primitive syntax.
+% 99\% of the cases is no. For this type the programmer will know the
+% number of arguments and in most cases use the argument signature to
+% signal this, e.g., "\foo_bar:nnn" presumably takes three
+% arguments. We therefore also provide functions that automatically
+% detect how many arguments are required and construct the parameter
+% text on the fly.
%
% A definition of a new function can be done locally and globally. Currently
% nearly all function definitions are done locally on top level, in
@@ -528,104 +648,126 @@
% as individual functions.
% \end{texnote}
%
-%
-% \subsubsection{Defining new functions}
-%
-% Firstly comes to variants most used namely those taking a number to
-% denote the number of arguments.
-%
-% \begin{function}{\def_new:NNn |
-% \def_new:NNx |
-% \def_new:cNn |
-% \def_new:cNx
+% A slew of functions are defined in the following sections for defining
+% new functions. Here's a quick summary to get an idea of what's available:
+% {\centering
+% "\cs_"("g")("new"/"set")("_protected")("_nopar")":"("N"/"c")("p")("n"/"x")
+% \par}
+% That stands for, respectively, the following variations:
+% \begin{description}
+% \item[\texttt g] Global or local;
+% \item[\texttt{new}/\texttt{set}]
+% Define a new function or re-define an existing one;
+% \item[\texttt{protected}]
+% Prevent expansion of the function in "x" arguments;
+% \item[\texttt{nopar}] Restrict the argument(s) from containing "\par";
+% \item[\texttt N/\texttt c] Either a control sequence or a `csname';
+% \item[\texttt p]
+% Either the a primitive \TeX\ argument or the number of arguments
+% is detected from the argument signature, i.e., |\foo:nnn| is
+% assumed to have three arguments |#1#2#3|;
+% \item[\texttt n/\texttt x] Either an unexpanded or an expanded definition.
+% \end{description}
+% That adds up to 128 variations (!). However, the system is very
+% logical and only a handful will usually be required often.
+%
+%
+%
+% \subsection{Defining new functions using primitive parameter text}
+%
+%
+% \begin{function}{\cs_new:Npn |
+% \cs_new:Npx |
+% \cs_new:cpn |
+% \cs_new:cpx
% }
% \begin{syntax}
-% "\def_new:NNn" <cs> <num> "{" <code> "}"
+% "\cs_new:Npn" <cs> <parms> \Arg{code}
% \end{syntax}
-% Defines a new function, making sure that <cs> is unused so far.
-% <num> is the number of arguments which is in the interval $[0,9]$
-% otherwise an error is raised. It is under the responsibility of the
-% programmer to name the new function according to the rules laid out
-% in the previous section. <code> is either passed literally or may
-% be subject to expansion (under the "x" variants).
+% Defines a function that may contain "\par" tokens in the argument(s)
+% when called. This is not allowed for normal functions.
% \end{function}
%
-% \begin{function}{\gdef_new:NNn |
-% \gdef_new:cNn |
-% \gdef_new:NNx |
-% \gdef_new:cNx
+% \begin{function}{\cs_gnew:Npn |
+% \cs_gnew:Npx |
+% \cs_gnew:cpn |
+% \cs_gnew:cpx
% }
% \begin{syntax}
-% "\gdef_new:NNn" <cs> <num> "{" <code> "}"
+% "\cs_gnew:Npn" <cs> <parms> \Arg{code}
% \end{syntax}
-% Like "\def_new:NNn" but defines the new function globally.
+% Global versions of the above functions.
% \end{function}
%
-% \begin{function}{\def_long_new:NNn |
-% \def_long_new:NNx |
-% \def_long_new:cNn |
-% \def_long_new:cNx
+% \begin{function}{\cs_new_nopar:Npn |
+% \cs_new_nopar:Npx |
+% \cs_new_nopar:cpn |
+% \cs_new_nopar:cpx
% }
% \begin{syntax}
-% "\def_long_new:NNn" <cs> <num> "{" <code> "}"
+% "\cs_new_nopar:Npn" <cs> <parms> \Arg{code}
% \end{syntax}
-% Defines a function that may contain "\par" tokens in the argument(s)
-% when called. This is not allowed for normal functions.
+% Defines a new function, making sure that <cs> is unused so far.
+% <parms> may consist of arbitrary parameter specification in \TeX{}
+% syntax. It is under the responsibility of the programmer to name the
+% new function according to the rules laid out in the previous section.
+% <code> is either passed literally or may be subject to expansion
+% (under the "x" variants).
% \end{function}
%
-% \begin{function}{\gdef_long_new:NNn |
-% \gdef_long_new:NNx |
-% \gdef_long_new:cNn |
-% \gdef_long_new:cNx
+% \begin{function}{\cs_gnew_nopar:Npn |
+% \cs_gnew_nopar:Npx |
+% \cs_gnew_nopar:cpn |
+% \cs_gnew_nopar:cpx
% }
% \begin{syntax}
-% "\gdef_long_new:NNn" <cs> <num> "{" <code> "}"
+% "\cs_gnew_nopar:Npn" <cs> <parms> \Arg{code}
% \end{syntax}
-% Global versions of the above functions.
+% Like "\cs_new_nopar:Npn" but defines the new function globally. See
+% comments above.
% \end{function}
%
-% \begin{function}{\def_protected_new:NNn |
-% \def_protected_new:NNx |
-% \def_protected_new:cNn |
-% \def_protected_new:cNx
+% \begin{function}{\cs_new_protected:Npn |
+% \cs_new_protected:Npx |
+% \cs_new_protected:cpn |
+% \cs_new_protected:cpx
% }
% \begin{syntax}
-% "\def_protected_new:NNn" <cs> <num> "{" <code> "}"
+% "\cs_new_protected:Npn" <cs> <parms> \Arg{code}
% \end{syntax}
-% Defines a function that does not expand when inside an |x| type
-% expansion.
+% Defines a function that is both robust and may contain "\par" tokens
+% in the argument(s) when called.
% \end{function}
%
-% \begin{function}{\gdef_protected_new:NNn |
-% \gdef_protected_new:NNx |
-% \gdef_protected_new:cNn |
-% \gdef_protected_new:cNx
-% }
+% \begin{function}{ \cs_gnew_protected:Npn |
+% \cs_gnew_protected:Npx |
+% \cs_gnew_protected:cpn |
+% \cs_gnew_protected:cpx }
% \begin{syntax}
-% "\gdef_protected_new:NNn" <cs> <num> "{" <code> "}"
+% "\cs_gnew_protected:Npn" <cs> <parms> \Arg{code}
% \end{syntax}
% Global versions of the above functions.
% \end{function}
%
-% \begin{function}{\def_protected_long_new:NNn |
-% \def_protected_long_new:NNx |
-% \def_protected_long_new:cNn |
-% \def_protected_long_new:cNx
+% \begin{function}{\cs_new_protected_nopar:Npn |
+% \cs_new_protected_nopar:Npx |
+% \cs_new_protected_nopar:cpn |
+% \cs_new_protected_nopar:cpx
% }
% \begin{syntax}
-% "\def_protected_long_new:NNn" <cs> <num> "{" <code> "}"
+% "\cs_new_protected_nopar:Npn" <cs> <parms> \Arg{code}
% \end{syntax}
-% Defines a function that is both robust and may contain "\par" tokens
-% in the argument(s) when called.
+% Defines a function that does not expand when inside an |x| type
+% expansion.
% \end{function}
%
-% \begin{function}{\gdef_protected_long_new:NNn |
-% \gdef_protected_long_new:NNx |
-% \gdef_protected_long_new:cNn |
-% \gdef_protected_long_new:cNx
+% \begin{function}{\cs_gnew_protected_nopar:Npn |
+% \cs_gnew_protected_nopar:Npx |
+% \cs_gnew_protected_nopar:cpn |
+% \cs_gnew_protected_nopar:cpx
% }
% \begin{syntax}
-% "\gdef_protected_long_new:NNn" <cs> <num> "{" <code> "}"
+% "\cs_gnew_protected_nopar:Npn" <cs> <parms> \Arg{code}
% \end{syntax}
% Global versions of the above functions.
% \end{function}
@@ -634,367 +776,385 @@
%
%
%
-% Secondly comes the ones where the programmer can use delimited
-% arguments. Rarely needed outside the kernel.
%
%
-% \begin{function}{\def_new:Npn |
-% \def_new:Npx |
-% \def_new:cpn |
-% \def_new:cpx
-% }
-% \begin{syntax}
-% "\def_new:Npn" <cs> <parms> "{" <code> "}"
-% \end{syntax}
-% Defines a new function, making sure that <cs> is unused so far.
-% <parms> may consist of arbitrary parameter specification in \TeX{}
-% syntax. It is under the responsibility of the programmer to name the
-% new function according to the rules laid out in the previous section.
-% <code> is either passed literally or may be subject to expansion
-% (under the "x" variants).
-% \end{function}
%
-% \begin{function}{\gdef_new:Npn |
-% \gdef_new:cpn |
-% \gdef_new:Npx |
-% \gdef_new:cpx
-% }
-% \begin{syntax}
-% "\gdef_new:Npn" <cs> <parms> "{" <code> "}"
-% \end{syntax}
-% Like "\def_new:Npn" but defines the new function globally. See
-% comments above.
-% \end{function}
%
-% \begin{function}{\def_long_new:Npn |
-% \def_long_new:Npx |
-% \def_long_new:cpn |
-% \def_long_new:cpx
+% \subsection{Defining new functions using the signature}
+%
+%
+% \begin{function}{\cs_new:Nn |
+% \cs_new:Nx |
+% \cs_new:cn |
+% \cs_new:cx
% }
% \begin{syntax}
-% "\def_long_new:Npn" <cs> <parms> "{" <code> "}"
+% "\cs_new:Nn" <cs> \Arg{code}
% \end{syntax}
-% Defines a function that may contain "\par" tokens in the argument(s)
-% when called. This is not allowed for normal functions.
+% Defines a new function, making sure that <cs> is unused so far. The
+% parameter text is automatically detected from the length of the
+% function signature. If <cs> is missing a colon in its name, an error
+% is raised. It is under the responsibility of the programmer to name
+% the new function according to the rules laid out in the previous
+% section. <code> is either passed literally or may be subject to
+% expansion (under the "x" variants).
+% \begin{texnote}
+% Internally, these use \TeX's "\long". These forms are
+% recommended for low-level definitions as experience has shown that "\par"
+% tokens often turn up in programming situations that wouldn't have been
+% expected.
+% \end{texnote}
% \end{function}
%
-% \begin{function}{\gdef_long_new:Npn |
-% \gdef_long_new:Npx |
-% \gdef_long_new:cpn |
-% \gdef_long_new:cpx
+% \begin{function}{\cs_gnew:Nn |
+% \cs_gnew:Nx |
+% \cs_gnew:cn |
+% \cs_gnew:cx
% }
% \begin{syntax}
-% "\gdef_long_new:Npn" <cs> <parms> "{" <code> "}"
+% "\cs_gnew:Nn" <cs> \Arg{code}
% \end{syntax}
% Global versions of the above functions.
% \end{function}
%
-% \begin{function}{\def_protected_new:Npn |
-% \def_protected_new:Npx |
-% \def_protected_new:cpn |
-% \def_protected_new:cpx
+% \begin{function}{\cs_new_nopar:Nn |
+% \cs_new_nopar:Nx |
+% \cs_new_nopar:cn |
+% \cs_new_nopar:cx
% }
% \begin{syntax}
-% "\def_protected_new:Npn" <cs> <parms> "{" <code> "}"
+% "\cs_new_nopar:Nn" <cs> \Arg{code}
% \end{syntax}
-% Defines a function that does not expand when inside an |x| type
-% expansion.
+% Version of the above in which "\par" is not allowed to appear within the
+% argument(s) of the defined functions.
% \end{function}
%
-% \begin{function}{\gdef_protected_new:Npn |
-% \gdef_protected_new:Npx |
-% \gdef_protected_new:cpn |
-% \gdef_protected_new:cpx
+% \begin{function}{\cs_gnew_nopar:Nn |
+% \cs_gnew_nopar:Nx |
+% \cs_gnew_nopar:cn |
+% \cs_gnew_nopar:cx
% }
% \begin{syntax}
-% "\gdef_protected_new:Npn" <cs> <parms> "{" <code> "}"
+% "\cs_gnew_nopar:Nn" <cs> \Arg{code}
% \end{syntax}
% Global versions of the above functions.
% \end{function}
%
-% \begin{function}{\def_protected_long_new:Npn |
-% \def_protected_long_new:Npx |
-% \def_protected_long_new:cpn |
-% \def_protected_long_new:cpx
+% \begin{function}{\cs_new_protected:Nn |
+% \cs_new_protected:Nx |
+% \cs_new_protected:cn |
+% \cs_new_protected:cx
% }
% \begin{syntax}
-% "\def_protected_long_new:Npn" <cs> <parms> "{" <code> "}"
+% "\cs_new_protected:Nn" <cs> \Arg{code}
% \end{syntax}
% Defines a function that is both robust and may contain "\par" tokens
% in the argument(s) when called.
% \end{function}
%
-% \begin{function}{\gdef_protected_long_new:Npn |
-% \gdef_protected_long_new:Npx |
-% \gdef_protected_long_new:cpn |
-% \gdef_protected_long_new:cpx
+% \begin{function}{\cs_gnew_protected:Nn |
+% \cs_gnew_protected:Nx |
+% \cs_gnew_protected:cn |
+% \cs_gnew_protected:cx
% }
% \begin{syntax}
-% "\gdef_protected_long_new:Npn" <cs> <parms> "{" <code> "}"
+% "\cs_gnew_protected:Nn" <cs> \Arg{code}
% \end{syntax}
% Global versions of the above functions.
% \end{function}
%
-% \begin{function}{\let_new:NN |
-% \let_new:cN |
-% \let_new:Nc |
-% \let_new:cc |
-% \glet_new:NN|
-% \glet_new:cN|
-% \glet_new:Nc|
-% \glet_new:cc }
+% \begin{function}{\cs_new_protected_nopar:Nn |
+% \cs_new_protected_nopar:Nx |
+% \cs_new_protected_nopar:cn |
+% \cs_new_protected_nopar:cx
+% }
% \begin{syntax}
-% "\let_new:NN" <cs1> <cs2>
+% "\cs_new_protected_nopar:Nn" <cs> \Arg{code}
% \end{syntax}
-% Gives the function <cs1> the current meaning of <cs2>. Again, we may
-% do this always globally.
+% Defines a function that does not expand when inside an |x| type
+% expansion. "\par" is not allowed in the argument(s) of the defined function.
% \end{function}
%
-%
-%
-% \subsubsection{Undefining functions}
-%
-% \begin{function}{ \cs_gundefine:N
+% \begin{function}{\cs_gnew_protected_nopar:Nn |
+% \cs_gnew_protected_nopar:Nx |
+% \cs_gnew_protected_nopar:cn |
+% \cs_gnew_protected_nopar:cx
% }
% \begin{syntax}
-% "\cs_gundefine:N" <cs>
+% "\cs_gnew_protected_nopar:Nn" <cs> \Arg{code}
% \end{syntax}
-% Undefines the control sequence.
+% Global versions of the above functions.
% \end{function}
%
-% \subsubsection{Defining internal functions (no checks)}
+%
+%
+% \subsection{Defining functions using primitive parameter text}
+%
%
% Besides the function definitions that check whether or not their
% argument is an unused function we need function definitions that
% overwrite currently used definitions. The following functions are
% provided for this purpose.
%
-% First comes the versions expecting a number to denote the number of
-% arguments.
-%
-% \begin{function}{\def:NNn |
-% \def:NNx |
-% \def:cNn |
-% \def:cNx |
+% \begin{function}{\cs_set:Npn |
+% \cs_set:Npx |
+% \cs_set:cpn |
+% \cs_set:cpx |
% }
% \begin{syntax}
-% "\def:NNn" <cs> <num> "{" <code> "}"
+% "\cs_set:Npn" <cs> <parms> \Arg{code}
% \end{syntax}
-% Like "\def_new:NNn" etc.\ but does not check the <cs> name.
+% Like "\cs_set_nopar:Npn" but allows "\par" tokens in the arguments of the
+% function being defined.
+% \begin{texnote}
+% These are equivalent to \TeX's "\long\def" and so on. These forms are
+% recommended for low-level definitions as experience has shown that "\par"
+% tokens often turn up in programming situations that wouldn't have been
+% expected.
+% \end{texnote}
% \end{function}
%
-% \begin{function}{\gdef:NNn |
-% \gdef:NNx |
-% \gdef:cNn |
-% \gdef:cNx |
+% \begin{function}{\cs_gset:Npn |
+% \cs_gset:Npx |
+% \cs_gset:cpn |
+% \cs_gset:cpx |
% }
% \begin{syntax}
-% "\gdef:NNn" <cs> <num> "{" <code> "}"
+% "\cs_gset:Npn" <cs> <parms> \Arg{code}
% \end{syntax}
-% Like "\def:NNn" but defines the <cs> globally.
+% Global variant of "\cs_set:Npn".
% \end{function}
%
-%
-% \begin{function}{\def_long:NNn |
-% \def_long:NNx |
-% \def_long:cNn |
-% \def_long:cNx |
+% \begin{function}{\cs_set_nopar:Npn |
+% \cs_set_nopar:Npx |
+% \cs_set_nopar:cpn |
+% \cs_set_nopar:cpx |
% }
% \begin{syntax}
-% "\def_long:NNn" <cs> <num> "{" <code> "}"
+% "\cs_set_nopar:Npn" <cs> <parms> \Arg{code}
% \end{syntax}
-% Like "\def:NNn" but allows "\par" tokens in the arguments of the
-% function being defined.
+% Like "\cs_new_nopar:Npn" etc.\ but does not check the <cs> name.
+% \begin{texnote}
+% "\cs_set_nopar:Npn" is the \LaTeX3 name for \TeX{}'s \tn{def} and
+% "\cs_set_nopar:Npx" corresponds to the primitive \tn{edef}. The
+% "\cs_set_nopar:cpn" function was known in \LaTeX2 as \tn{@namedef}.
+% "\cs_set_nopar:cpx" has no equivalent.
+% \end{texnote}
% \end{function}
%
-% \begin{function}{\gdef_long:NNn |
-% \gdef_long:NNx |
-% \gdef_long:cNn |
-% \gdef_long:cNx |
+% \begin{function}{\cs_gset_nopar:Npn |
+% \cs_gset_nopar:Npx |
+% \cs_gset_nopar:cpn |
+% \cs_gset_nopar:cpx |
% }
% \begin{syntax}
-% "\gdef_long:NNn" <cs> <num> "{" <code> "}"
+% "\cs_gset_nopar:Npn" <cs> <parms> \Arg{code}
% \end{syntax}
-% Global variant of "\def_long:NNn".
+% Like "\cs_set_nopar:Npn" but defines the <cs> globally.
+% \begin{texnote}
+% "\cs_gset_nopar:Npn" and "\cs_gset_nopar:Npx"
+% are \TeX's \tn{gdef} and \tn{xdef}.
+% \end{texnote}
% \end{function}
%
-% \begin{function}{\def_protected:NNn |
-% \def_protected:cNn |
-% \def_protected:NNx |
-% \def_protected:cNx |
+%
+% \begin{function}{\cs_set_protected:Npn |
+% \cs_set_protected:Npx |
+% \cs_set_protected:cpn |
+% \cs_set_protected:cpx |
% }
% \begin{syntax}
-% "\def_protected:NNn" <cs> <num> "{" <code> "}"
+% "\cs_set_protected:Npn" <cs> <parms> \Arg{code}
% \end{syntax}
% Naturally robust macro that won't expand in an |x| type argument.
-% This also comes as a |long| version. If you for some reason want to
-% expand it inside an |x| type expansion, prefix it with
-% |\exp_after:NN \use_noop:|.
+% These varieties allow |\par| tokens in the arguments of the
+% function being defined.
% \end{function}
%
-% \begin{function}{\gdef_protected:NNn |
-% \gdef_protected:cNn |
-% \gdef_protected:NNx |
-% \gdef_protected:cNx |
+% \begin{function}{\cs_gset_protected:Npn |
+% \cs_gset_protected:Npx |
+% \cs_gset_protected:cpn |
+% \cs_gset_protected:cpx |
% }
% \begin{syntax}
-% "\gdef_protected:NNn" <cs> <num> "{" <code> "}"
+% "\cs_gset_protected:Npn" <cs> <parms> \Arg{code}
% \end{syntax}
% Global versions of the above functions.
% \end{function}
%
-% \begin{function}{\def_protected_long:NNn |
-% \def_protected_long:cNn |
-% \def_protected_long:NNx |
-% \def_protected_long:cNx |
+% \begin{function}{\cs_set_protected_nopar:Npn |
+% \cs_set_protected_nopar:Npx |
+% \cs_set_protected_nopar:cpn |
+% \cs_set_protected_nopar:cpx |
% }
% \begin{syntax}
-% "\def_protected_long:NNn" <cs> <num> "{" <code> "}"
+% "\cs_set_protected_nopar:Npn" <cs> <parms> \Arg{code}
% \end{syntax}
% Naturally robust macro that won't expand in an |x| type argument.
-% These varieties also allow |\par| tokens in the arguments of the
-% function being defined.
+% If you want for some reason to expand it inside an |x| type expansion,
+% prefix it with |\exp_after:wN \prg_do_nothing:|.
% \end{function}
%
-% \begin{function}{\gdef_protected_long:NNn |
-% \gdef_protected_long:cNn |
-% \gdef_protected_long:NNx |
-% \gdef_protected_long:cNx |
+% \begin{function}{\cs_gset_protected_nopar:Npn |
+% \cs_gset_protected_nopar:Npx |
+% \cs_gset_protected_nopar:cpn |
+% \cs_gset_protected_nopar:cpx |
% }
% \begin{syntax}
-% "\gdef_protected_long:NNn" <cs> <num> "{" <code> "}"
+% "\cs_gset_protected_nopar:Npn" <cs> <parms> \Arg{code}
% \end{syntax}
% Global versions of the above functions.
% \end{function}
%
-% Secondly the ones that use the primitive parameter build-up:
%
-% \begin{function}{\def:Npn |
-% \def:Npx |
-% \def:cpn |
-% \def:cpx |
+% \subsection{Defining functions using the signature (no checks)}
+%
+% As above but now detecting the parameter text from inspecting the
+% signature.
+%
+% \begin{function}{\cs_set:Nn |
+% \cs_set:Nx |
+% \cs_set:cn |
+% \cs_set:cx |
% }
% \begin{syntax}
-% "\def:Npn" <cs> <parms> "{" <code> "}"
+% "\cs_set:Nn" <cs> \Arg{code}
% \end{syntax}
-% Like "\def_new:Npn" etc.\ but does not check the <cs> name.
-% \begin{texnote}
-% "\def:Npn" is the \LaTeX3 name for \TeX{}'s \tn{def} and "\def:Npx"
-% corresponds to the primitive \tn{edef}. The "\def:cpn" function was
-% known in \LaTeX2 as \tn{@namedef}. "\def:cpx" has no equivalent.
-% \end{texnote}
+% Like "\cs_set_nopar:Nn" but allows "\par" tokens in the arguments of the
+% function being defined.
% \end{function}
%
-% \begin{function}{\gdef:Npn |
-% \gdef:Npx |
-% \gdef:cpn |
-% \gdef:cpx |
+% \begin{function}{\cs_gset:Nn |
+% \cs_gset:Nx |
+% \cs_gset:cn |
+% \cs_gset:cx |
% }
% \begin{syntax}
-% "\gdef:Npn" <cs> <parms> "{" <code> "}"
+% "\cs_gset:Nn" <cs> \Arg{code}
% \end{syntax}
-% Like "\def:Npn" but defines the <cs> globally.
-% \begin{texnote}
-% "\gdef:Npn" and "\gdef:Npx" are known to \TeX{}hackers as \tn{gdef}
-% and \tn{xdef}.
-% \end{texnote}
+% Global variant of "\cs_set:Nn".
% \end{function}
%
-%
-% \begin{function}{\def_long:Npn |
-% \def_long:Npx |
-% \def_long:cpn |
-% \def_long:cpx |
+% \begin{function}{\cs_set_nopar:Nn |
+% \cs_set_nopar:Nx |
+% \cs_set_nopar:cn |
+% \cs_set_nopar:cx |
% }
% \begin{syntax}
-% "\def_long:Npn" <cs> <parms> "{" <code> "}"
+% "\cs_set_nopar:Nn" <cs> \Arg{code}
% \end{syntax}
-% Like "\def:Npn" but allows "\par" tokens in the arguments of the
-% function being defined.
+% Like "\cs_new_nopar:Nn" etc.\ but does not check the <cs> name.
% \end{function}
%
-% \begin{function}{\gdef_long:Npn |
-% \gdef_long:Npx |
-% \gdef_long:cpn |
-% \gdef_long:cpx |
+% \begin{function}{\cs_gset_nopar:Nn |
+% \cs_gset_nopar:Nx |
+% \cs_gset_nopar:cn |
+% \cs_gset_nopar:cx |
% }
% \begin{syntax}
-% "\gdef_long:Npn" <cs> <parms> "{" <code> "}"
+% "\cs_gset_nopar:Nn" <cs> \Arg{code}
% \end{syntax}
-% Global variant of "\def_long:Npn".
+% Like "\cs_set_nopar:Nn" but defines the <cs> globally.
% \end{function}
%
-% \begin{function}{\def_protected:Npn |
-% \def_protected:cpn |
-% \def_protected:Npx |
-% \def_protected:cpx |
+% \begin{function}{\cs_set_protected:Nn |
+% \cs_set_protected:cn |
+% \cs_set_protected:Nx |
+% \cs_set_protected:cx |
% }
% \begin{syntax}
-% "\def_protected:Npn" <cs> <parms> "{" <code> "}"
+% "\cs_set_protected:Nn" <cs> \Arg{code}
% \end{syntax}
% Naturally robust macro that won't expand in an |x| type argument.
-% This also comes as a |long| version. If you for some reason want to
-% expand it inside an |x| type expansion, prefix it with
-% |\exp_after:NN \use_noop:|.
+% These varieties also allow |\par| tokens in the arguments of the
+% function being defined.
% \end{function}
%
-% \begin{function}{\gdef_protected:Npn |
-% \gdef_protected:cpn |
-% \gdef_protected:Npx |
-% \gdef_protected:cpx |
+% \begin{function}{\cs_gset_protected:Nn |
+% \cs_gset_protected:cn |
+% \cs_gset_protected:Nx |
+% \cs_gset_protected:cx |
% }
% \begin{syntax}
-% "\gdef_protected:Npn" <cs> <parms> "{" <code> "}"
+% "\cs_gset_protected:Nn" <cs> \Arg{code}
% \end{syntax}
% Global versions of the above functions.
% \end{function}
%
-% \begin{function}{\def_protected_long:Npn |
-% \def_protected_long:cpn |
-% \def_protected_long:Npx |
-% \def_protected_long:cpx |
+% \begin{function}{\cs_set_protected_nopar:Nn |
+% \cs_set_protected_nopar:cn |
+% \cs_set_protected_nopar:Nx |
+% \cs_set_protected_nopar:cx |
% }
% \begin{syntax}
-% "\def_protected_long:Npn" <cs> <parms> "{" <code> "}"
+% "\cs_set_protected_nopar:Nn" <cs> \Arg{code}
% \end{syntax}
% Naturally robust macro that won't expand in an |x| type argument.
-% These varieties also allow |\par| tokens in the arguments of the
-% function being defined.
+% This also comes as a |long| version. If you for some reason want to
+% expand it inside an |x| type expansion, prefix it with
+% |\exp_after:wN \prg_do_nothing:|.
% \end{function}
%
-% \begin{function}{\gdef_protected_long:Npn |
-% \gdef_protected_long:cpn |
-% \gdef_protected_long:Npx |
-% \gdef_protected_long:cpx |
+% \begin{function}{\cs_gset_protected_nopar:Nn |
+% \cs_gset_protected_nopar:cn |
+% \cs_gset_protected_nopar:Nx |
+% \cs_gset_protected_nopar:cx |
% }
% \begin{syntax}
-% "\gdef_protected_long:Npn" <cs> <parms> "{" <code> "}"
+% "\cs_gset_protected_nopar:Nn" <cs> \Arg{code}
% \end{syntax}
% Global versions of the above functions.
% \end{function}
%
%
%
-% \begin{function}{\let:NN |
-% \let:cN |
-% \let:Nc |
-% \let:cc |
-% \glet:NN |
-% \glet:cN |
-% \glet:Nc |
-% \glet:cc
-% }
+% \subsection{Undefining functions}
+%
+% \begin{function}{ \cs_gundefine:N }
+% \begin{syntax}
+% "\cs_gundefine:N" <cs>
+% \end{syntax}
+% Undefines the control sequence globally.
+% \end{function}
+%
+%
+% \subsection{Copying function definitions}
+%
+% \begin{function}{ \cs_new_eq:NN |
+% \cs_new_eq:cN |
+% \cs_new_eq:Nc |
+% \cs_new_eq:cc |
+% \cs_gnew_eq:NN |
+% \cs_gnew_eq:cN |
+% \cs_gnew_eq:Nc |
+% \cs_gnew_eq:cc }
+% \begin{syntax}
+% "\cs_new_eq:NN" <cs1> <cs2>
+% \end{syntax}
+% Gives the function <cs1> locally or globally the current meaning of <cs2>.
+% If <cs1> already exists then an error is called.
+% \end{function}
+%
+%
+% \begin{function}{\cs_set_eq:NN |
+% \cs_set_eq:cN |
+% \cs_set_eq:Nc |
+% \cs_set_eq:cc |
+% \cs_gset_eq:NN |
+% \cs_gset_eq:cN |
+% \cs_gset_eq:Nc |
+% \cs_gset_eq:cc }
% \begin{syntax}
-% "\let:cN" <cs1> <cs2>
+% "\cs_set_eq:cN" <cs1> <cs2>
% \end{syntax}
% Gives the function <cs1> the current meaning of <cs2>. Again, we may
% always do this globally.
% \end{function}
%
-% \begin{function}{\let:NwN}
+% \begin{function}{\cs_set_eq:NwN}
% \begin{syntax}
-% "\let:NwN" <cs1> <cs2>
-% "\let:NwN" <cs1> "=" <cs2>
+% "\cs_set_eq:NwN" <cs1> <cs2>
+% "\cs_set_eq:NwN" <cs1> "=" <cs2>
% \end{syntax}
% These functions assign the meaning of <cs2> locally or globally to the
% function <cs1>. Because the \TeX{} primitive operation is being used
@@ -1002,67 +1162,109 @@
% <cs1> and <cs2> the name contains a "w". (Not happy about this
% convention!).
% \begin{texnote}
-% "\let:NwN" is the \LaTeX3 name for \TeX{}'s \tn{let}.
+% "\cs_set_eq:NwN" is the \LaTeX3 name for \TeX{}'s \tn{let}.
% \end{texnote}
% \end{function}
%
+% \subsection{Internal functions}
%
-% \subsection{Defining test functions}
%
+% \begin{function}{ \pref_global:D |
+% \pref_long:D |
+% \pref_protected:D }
+% \begin{syntax}
+% "\pref_global:D" "\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 "\pref_global:D" makes the definition global,
+% "\pref_long:D" change the argument scanning mechanism so that it
+% allows "\par" tokens in the argument of the prefixed function,
+% and "\pref_protected:D" makes the definition robust in "\write"s etc.
%
-% \begin{function}{
-% \def_test_function:npn |
-% \def_long_test_function:npn |
-% \def_test_function_new:npn |
-% \def_long_test_function_new:npn |
-% }
-% \begin{syntax}
-% "\def_test_function_new:npn" "{"name"}" <parms> "{"<test>"}"
-% \end{syntax}
-% Define all the common test cases for a simple test to reduce the
-% risk of typos. As an example here's how we defined the functions
-% "\cs_free:cTF", "\cs_free:cT" and "\cs_free:cF". You just have to
-% fill in the test.
-% \begin{verbatim}
-% \def_test_function:npn{cs_free:c} #1 {
-% \exp_after:NN \if_meaning:NN \cs:w#1\cs_end: \scan_stop:}
-% \end{verbatim}
-% Be careful not to use this function inside some primitive
-% conditional as \TeX\ will most likely get confused because of the
-% unmatched conditionals.
+% None of these internal functions should be used by a programmer since
+% the necessary combinations are all available as separate function,
+% e.g., "\cs_set:Npn" is internally implemented as "\pref_long:D"
+% "\cs_set_nopar:Npn".
+% \begin{texnote}
+% These prefixes are the primitives \tn{global}, \tn{long}, and
+% \tn{protected}. The \tn{outer} prefix isn't used at all within \LaTeX3
+% because \ldots (it causes more hassle than it's worth? It's nevery proved
+% useful in any meaningful way?)
+% \end{texnote}
% \end{function}
%
+% \section{The innards of a function}
%
-% \subsection{The innards of a function}
-%
-% \begin{function}{\cs_to_str:N}
+% \begin{function}{\cs_to_str:N / (EXP)}
% \begin{syntax}
% "\cs_to_str:N" <cs>
% \end{syntax}
-% This function return the name of <cs> as a sequence of letters with
+% This function returns the name of <cs> as a sequence of letters with
% the escape character removed.
% \end{function}
%
-% \begin{function}{\token_to_string:N}
+% \begin{function}{\token_to_str:N / (EXP) | \token_to_str:c / (EXP)}
% \begin{syntax}
-% "\token_to_string:N" <arg>
+% "\token_to_str:N" <arg>
% \end{syntax}
% This function return the name of <arg> as a sequence of letters
% including the escape character.
+% \begin{texnote}
+% This is \TeX's \tn{string}.
+% \end{texnote}
% \end{function}
%
-% \begin{function}{\token_to_meaning:N}
+% \begin{function}{\token_to_meaning:N / (EXP)}
% \begin{syntax}
% "\token_to_meaning:N" <arg>
% \end{syntax}
% This function returns the type and definition of <arg> as a sequence
% of letters.
+% \begin{texnote}
+% This is \TeX's \tn{meaning}.
+% \end{texnote}
+% \end{function}
+%
+%
+% \begin{function}{\cs_get_function_name:N / (EXP) |
+% \cs_get_function_signature:N / (EXP)}
+% \begin{syntax}
+% "\cs_get_function_name:N" "\"<fn>":"<args>
+% \end{syntax}
+% The "name" variant strips off the leading escape character and the
+% trailing argument specification (including the colon) to return
+% <fn>. The "signature" variants does the same but returns the
+% signature <args> instead.
% \end{function}
%
+%
+% \begin{function}{\cs_split_function:NN / (EXP)}
+% \begin{syntax}
+% "\cs_split_function:NN" "\"<fn>":"<args> <post process>
+% \end{syntax}
+% Strips off the leading escape character, splits off the signature
+% without the colon, informs whether or not a colon was present and
+% then prefixes these results with <post process>, i.e., <post
+% process>\Arg{name}\Arg{signature}\meta{true}/\meta{false}. For
+% example, "\cs_get_function_name:N" is nothing more than
+% "\cs_split_function:NN" "\"<fn>":"<args> "\use_i:nnn".
+% \end{function}
+%
+%
+% \begin{function}{\cs_get_arg_count_from_signature:N / (EXP)}
+% \begin{syntax}
+% "\cs_get_arg_count_from_signature:N" "\"<fn>":"<args>
+% \end{syntax}
+% Returns the number of chars in <args>, signifying the number of arguments
+% that the function uses.
+% \end{function}
+%
+%
% Other functions regarding arbitrary tokens can be found in the
% \textsf{l3token} module.
%
-% \subsection{Grouping and scanning}
+% \section{Grouping and scanning}
%
% \begin{function}{\scan_stop:}
% \begin{syntax}
@@ -1087,32 +1289,52 @@
% \end{texnote}
% \end{function}
%
+% \begin{function}{\group_execute_after:N}
+% \begin{syntax}
+% "\group_execute_after:N" <token>
+% \end{syntax}
+% Adds <token> to the list of tokens to be inserted after the
+% current group ends (through an explicit or implicit "\group_end:").
+% \begin{texnote}
+% This is \TeX's \tn{aftergroup}.
+% \end{texnote}
+% \end{function}
+%
%
-% \subsection{Engine specific definitions}
+% \section{Checking the engine}
+%
+% \begin{function}{\xetex_if_engine: / (TF)(EXP)}
+% \begin{syntax}
+% "\xetex_if_engine:TF" \Arg{true code} \Arg{false code}
+% \end{syntax}
+% This function detects if we're running a Xe\TeX-based format.
+% \end{function}
%
-% \begin{function}{\engine_if_aleph:TF}
+% \begin{function}{\luatex_if_engine: / (TF)(EXP)}
% \begin{syntax}
-% "\engine_if_aleph:TF" "{"<true code>"}" "{"<false code>"}"
+% "\luatex_if_engine:TF" \Arg{true code} \Arg{false code}
% \end{syntax}
-% This function detects if we're running an Aleph based format. This
-% is particularly useful when allocating registers.
+% This function detects if we're running a Lua\TeX-based format.
% \end{function}
%
+% \begin{variable}{\c_xetex_is_engine_bool|\c_luatex_is_engine_bool}
+% Boolean variables used for the above functions.
+% \end{variable}
%
+% \end{documentation}
%
-% \StopEventually{}
+% \begin{implementation}
%
+% \section{\pkg{l3basics} implementation}
%
-% \subsection{The Implementation}
-% We start by ensuring that the required packages are loaded. We need
-% \textsf{l3names} to get things going but we actually need it very
-% early on, so it is loaded at the very top of this file. Also, most
-% of the code below won't run until \textsf{l3expan} has been
+% We need \textsf{l3names} to get things going but we actually need it very
+% early on, so it is loaded at the very top of the file \file{l3basics.dtx}.
+% Also, most of the code below won't run until \textsf{l3expan} has been
% loaded.
%
-% \subsubsection{Renaming some \TeX{} primitives (again)}
+% \subsection{Renaming some \TeX{} primitives (again)}
%
-% \begin{macro}{\let:NwN}
+% \begin{macro}{\cs_set_eq:NwN}
% 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
@@ -1120,30 +1342,39 @@
% in terms of csname usage, an alternative scheme would be to just use
% the ``tex\ldots D'' name in the cases where no good alternative exists.}
% \begin{macrocode}
-%<package>\ProvidesExplPackage
-%<package> {\filename}{\filedate}{\fileversion}{\filedescription}
+%<*package>
+\ProvidesExplPackage
+ {\filename}{\filedate}{\fileversion}{\filedescription}
+\package_check_loaded_expl:
+%</package>
%<*initex|package>
-\tex_let:D \let:NwN \tex_let:D
+\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}
-\let:NwN \if_true: \tex_iftrue:D
-\let:NwN \if_false: \tex_iffalse:D
-\let:NwN \else: \tex_else:D
-\let:NwN \fi: \tex_fi:D
-\let:NwN \reverse_if:N \etex_unless:D
-\let:NwN \if:w \tex_if:D
-\let:NwN \if_charcode:w \tex_if:D
-\let:NwN \if_catcode:w \tex_ifcat: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
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -1153,28 +1384,26 @@
% \end{macro}
% \end{macro}
% \end{macro}
-% \begin{macro}{\if_meaning:NN}
-% \begin{macro}{\if_token_eq:NN}
-% \begin{macro}{\if_cs_meaning_eq:NN}
-% Some different names for |\ifx|.\footnote{MH: Clean up at some point}
-% \begin{macrocode}
-\let:NwN \if_meaning:NN \tex_ifx:D
-\let:NwN \if_token_eq:NN \tex_ifx:D
-\let:NwN \if_cs_meaning_eq:NN\tex_ifx:D
-% \end{macrocode}
% \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}
-\let:NwN \if_mode_math: \tex_ifmmode:D
-\let:NwN \if_mode_horizontal:\tex_ifhmode:D
-\let:NwN \if_mode_vertical: \tex_ifvmode:D
-\let:NwN \if_mode_inner: \tex_ifinner: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
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -1183,29 +1412,30 @@
% \begin{macro}{\if_cs_exist:N}
% \begin{macro}{\if_cs_exist:w}
% \begin{macrocode}
-\let:NwN \if_cs_exist:N \etex_ifdefined:D
-\let:NwN \if_cs_exist:w \etex_ifcsname:D
+\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:NN}
+% \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}
-\let:NwN \exp_after:NN \tex_expandafter:D
-\let:NwN \exp_not:N \tex_noexpand:D
-\let:NwN \exp_not:n \etex_unexpanded: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
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
-% \begin{macro}{\io_put_deferred:Nx}
+% \begin{macro}{\iow_shipout_x:Nn}
% \begin{macro}{\token_to_meaning:N}
-% \begin{macro}{\token_to_string:N}
+% \begin{macro}{\token_to_str:N}
+% \begin{macro}{\token_to_str:c}
% \begin{macro}{\cs:w}
% \begin{macro}{\cs_end:}
% \begin{macro}{\cs_meaning:N}
@@ -1213,15 +1443,16 @@
% \begin{macro}{\cs_show:N}
% \begin{macro}{\cs_show:c}
% \begin{macrocode}
-\let:NwN \io_put_deferred:Nx \tex_write:D
-\let:NwN \token_to_meaning:N \tex_meaning:D
-\let:NwN \token_to_string:N \tex_string:D
-\let:NwN \cs:w \tex_csname:D
-\let:NwN \cs_end: \tex_endcsname:D
-\let:NwN \cs_meaning:N \tex_meaning:D
-\tex_def:D \cs_meaning:c #1{\exp_after:NN\cs_meaning:N\cs:w #1\cs_end:}
-\let:NwN \cs_show:N \tex_show:D
-\tex_def:D \cs_show:c #1{\exp_after:NN\cs_show:N\cs:w #1\cs_end:}
+\cs_set_eq:NwN \iow_shipout_x:Nn \tex_write: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
+\tex_def:D \cs_meaning:c {\exp_args:Nc\cs_meaning:N}
+\cs_set_eq:NwN \cs_show:N \tex_show:D
+\tex_def:D \cs_show:c {\exp_args:Nc\cs_show:N}
+\tex_def:D \token_to_str:c {\exp_args:Nc\token_to_str:N}
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -1232,6 +1463,8 @@
% \end{macro}
% \end{macro}
% \end{macro}
+% \end{macro}
+%
% \begin{macro}{\scan_stop:}
% \begin{macro}{\group_begin:}
% \begin{macro}{\group_end:}
@@ -1239,70 +1472,69 @@
% versions that are safe inside alignments. These safe versions are
% defined in the \textsf{l3prg} module.
% \begin{macrocode}
-\let:NwN \scan_stop: \tex_relax:D
-\let:NwN \group_begin: \tex_begingroup:D
-\let:NwN \group_end: \tex_endgroup: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
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \begin{macro}{\group_execute_after:N}
% \begin{macrocode}
-\let:NwN \group_execute_after:N \tex_aftergroup:D
+\cs_set_eq:NwN \group_execute_after:N \tex_aftergroup:D
% \end{macrocode}
% \end{macro}
-% \begin{macro}{\the_internal:D}
% \begin{macro}{\pref_global:D}
% \begin{macro}{\pref_long:D}
% \begin{macro}{\pref_protected:D}
-% These following names are temporary and should be removed as soon
-% as possible (April 1998).
-% \begin{macrocode}
-\let:NwN \the_internal:D \tex_the:D
-\let:NwN \pref_global:D \tex_global:D
-% \end{macrocode}
-% "\pref_long:D" has been documented for years but didn't exist\dots{}
-% Added it and the robustness prefix.
% \begin{macrocode}
-\let:NwN \pref_long:D \tex_long:D
-\let:NwN \pref_protected:D \etex_protected: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
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
-% \end{macro}
%
%
%
-% \subsubsection {Defining functions}
+% \subsection {Defining functions}
%
%
% We start by providing functions for the typical definition
% functions. First the local ones.
%
-% \begin{macro}{\def:Npn}
-% \begin{macro}{\def:Npx}
-% \begin{macro}{\def_long:Npn}
-% \begin{macro}{\def_long:Npx}
-% \begin{macro}{\def_protected:Npn}
-% \begin{macro}{\def_protected:Npx}
-% \begin{macro}{\def_protected_long:Npn}
-% \begin{macro}{\def_protected_long:Npx}
+% \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}
-\let:NwN \def:Npn \tex_def:D
-\let:NwN \def:Npx \tex_edef:D
-\pref_protected:D \def:Npn \def_long:Npn {\pref_long:D \def:Npn}
-\pref_protected:D \def:Npn \def_long:Npx {\pref_long:D \def:Npx}
-\pref_protected:D \def:Npn \def_protected:Npn {\pref_protected:D \def:Npn}
-\pref_protected:D \def:Npn \def_protected:Npx {\pref_protected:D \def:Npx}
-\def_protected:Npn \def_protected_long:Npn {
- \pref_protected:D \pref_long:D \def:Npn
+\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
}
-\def_protected:Npn \def_protected_long:Npx {
- \pref_protected:D \pref_long:D \def:Npx
+\cs_set_protected_nopar:Npn \cs_set_protected:Npx {
+ \pref_protected:D \pref_long:D \cs_set_nopar:Npx
}
% \end{macrocode}
% \end{macro}
@@ -1314,27 +1546,35 @@
% \end{macro}
% \end{macro}
%
-% \begin{macro}{\gdef:Npn}
-% \begin{macro}{\gdef:Npx}
-% \begin{macro}{\gdef_long:Npn}
-% \begin{macro}{\gdef_long:Npx}
-% \begin{macro}{\gdef_protected:Npn}
-% \begin{macro}{\gdef_protected:Npx}
-% \begin{macro}{\gdef_protected_long:Npn}
-% \begin{macro}{\gdef_protected_long:Npx}
+% \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}
-\let:NwN \gdef:Npn \tex_gdef:D
-\let:NwN \gdef:Npx \tex_xdef:D
-\def_protected:Npn \gdef_long:Npn {\pref_long:D \gdef:Npn}
-\def_protected:Npn \gdef_long:Npx {\pref_long:D \gdef:Npx}
-\def_protected:Npn \gdef_protected:Npn {\pref_protected:D \gdef:Npn}
-\def_protected:Npn \gdef_protected:Npx {\pref_protected:D \gdef:Npx}
-\def_protected:Npn \gdef_protected_long:Npn {
- \pref_protected:D \pref_long:D \gdef:Npn
+\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
}
-\def_protected:Npn \gdef_protected_long:Npx {
- \pref_protected:D \pref_long:D \gdef:Npx
+\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}
@@ -1346,34 +1586,666 @@
% \end{macro}
% \end{macro}
%
-% \subsubsection{Predicate implementation}
%
+%
+% \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: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). "\use:n" is defined earlier for bootstrapping.
+% \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}
+% These macros are needed to provide functions with true and false
+% cases, as introduced by Michael some time ago. By using
+% |\exp_after:wN| |\use_i:nn | |\else:| constructions it
+% is possible to write code where the true or false case is able to
+% access the following tokens from the input stream, which is not
+% possible if the |\c_true_bool| syntax is used.
+% \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:nnnn}
+% \begin{macro}{\use_ii:nnnn}
+% \begin{macro}{\use_iii:nnnn}
+% \begin{macro}{\use_iv:nnnn}
+% \begin{macro}{\use_i_ii:nnn}
+% 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: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_i_ii:nnn #1#2#3{#1#2}
+% \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 |\q_nil| or
+% |\q_stop| resp.
+% \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{Expansion control from l3expan}
+%
+% \begin{macro}{\exp_args:Nc}
+% Moved here for now as it is going to be used right away.
+% \begin{macrocode}
+\cs_set:Npn \exp_args:Nc #1#2{\exp_after:wN#1\cs:w#2\cs_end:}
+% \end{macrocode}
+% \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:}
+% These break statements put \TeX\ in a \m{true} or \m{false} state.
+% The idea is that the expansion of |\tex_romannumeral:D \c_zero| is
+% \m{null} so we set off a |\tex_romannumeral:D|. It will on its
+% way expand any |\else:| or |\fi:| that are waiting to be discarded
+% anyway before finally arriving at the |\c_zero| we will place
+% right after the conditional. After this expansion has terminated,
+% we issue either |\if_true:| or |\if_false:| to put \TeX\ in the
+% correct state.
+% \begin{macrocode}
+\cs_set:Npn \prg_return_true: { \exp_after:wN\if_true:\tex_romannumeral:D }
+\cs_set:Npn \prg_return_false: {\exp_after:wN\if_false:\tex_romannumeral:D }
+% \end{macrocode}
+% An extended state space could instead utilize |\tex_ifcase:D|:
+% \begin{verbatim}
+% \cs_set:Npn \prg_return_true: {
+% \exp_after:wN\tex_ifcase:D \exp_after:wN \c_zero \tex_romannumeral:D
+% }
+% \cs_set:Npn \prg_return_false: {
+% \exp_after:wN\tex_ifcase:D \exp_after:wN \c_one \tex_romannumeral:D
+% }
+% \cs_set:Npn \prg_return_error: {
+% \exp_after:wN\tex_ifcase:D \exp_after:wN \c_two \tex_romannumeral:D
+% }
+% \end{verbatim}
+% \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, e.g., |\cs_set:Npn|
+% to define it with.
+% \begin{macrocode}
+\cs_set: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: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: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: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, e.g., |\cs_set:Npn| to
+% define it with.
+% \begin{macrocode}
+\cs_set: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: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: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: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}[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, 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: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: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.
+% \begin{macrocode}
+\cs_set:Npn \prg_generate_p_form_parm:Nnnnn #1#2#3#4#5{
+ \exp_args:Nc #1 {#2_p:#3}#4{#5 \c_zero
+ \exp_after:wN\c_true_bool\else:\exp_after:wN\c_false_bool\fi:
+ }
+}
+\cs_set:Npn \prg_generate_TF_form_parm:Nnnnn #1#2#3#4#5{
+ \exp_args:Nc#1 {#2:#3TF}#4{#5 \c_zero
+ \exp_after:wN \use_i:nn \else: \exp_after:wN \use_ii:nn \fi:
+ }
+}
+\cs_set:Npn \prg_generate_T_form_parm:Nnnnn #1#2#3#4#5{
+ \exp_args:Nc#1 {#2:#3T}#4{#5 \c_zero
+ \else:\exp_after:wN\use_none:nn\fi:\use:n
+ }
+}
+\cs_set:Npn \prg_generate_F_form_parm:Nnnnn #1#2#3#4#5{
+ \exp_args:Nc#1 {#2:#3F}#4{#5 \c_zero
+ \exp_after:wN\use_none:nn\fi:\use:n
+ }
+}
+% \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
+% }
+% How to generate the various forms. The "count" types here use a
+% number to insert the correct parameter text, otherwise like the
+% "parm" functions above.
+% \begin{macrocode}
+\cs_set: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
+ \exp_after:wN\c_true_bool\else:\exp_after:wN\c_false_bool\fi:
+ }
+}
+\cs_set:Npn \prg_generate_TF_form_count:Nnnnn #1#2#3#4#5{
+ \cs_generate_from_arg_count:cNnn {#2:#3TF} #1 {#4}{#5 \c_zero
+ \exp_after:wN\use_i:nn\else:\exp_after:wN\use_ii:nn\fi:
+ }
+}
+\cs_set:Npn \prg_generate_T_form_count:Nnnnn #1#2#3#4#5{
+ \cs_generate_from_arg_count:cNnn {#2:#3T} #1 {#4}{#5 \c_zero
+ \else:\exp_after:wN\use_none:nn\fi:\use:n
+ }
+}
+\cs_set:Npn \prg_generate_F_form_count:Nnnnn #1#2#3#4#5{
+ \cs_generate_from_arg_count:cNnn {#2:#3F} #1 {#4}{#5 \c_zero
+ \exp_after:wN\use_none:nn\fi:\use:n
+ }
+}
+% \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
-% \texttt{00} and \texttt{01}, so they can be used in logical
-% operations (see the \textsf{l3prg} module). We need this from the
-% get-go.
+% \texttt{00} and \texttt{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}
-% \begin{macro}{\c_false}
+% \begin{macro}{\c_true_bool}
+% \begin{macro}{\c_false_bool}
% Here are the canonical boolean values.
% \begin{macrocode}
-\def:Npn \c_true {00}
-\def:Npn \c_false {01}
+\tex_chardef:D \c_true_bool = 1~
+\tex_chardef:D \c_false_bool = 0~
% \end{macrocode}
% \end{macro}
% \end{macro}
%
-% \subsubsection {Defining and checking (new) functions}
+%
+% \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}
+% The route chosen is this: If |\token_to_str:N \a| produces a
+% non-space escape char, then this will produce two tokens. If the
+% escape char is non-printable, only one token is produced. If the
+% escape char is a space, then a space token plus one token
+% character token is produced. If we augment the result of this
+% expansion with the letters |ax| we get the following three
+% scenarios (with \meta{X} being a printable non-space escape
+% character):
+% \begin{itemize}
+% \item \meta{X}"aax"
+% \item "aax"
+% \item " aax"
+% \end{itemize}
+% In the second and third case, putting an auxiliary function in front
+% reading undelimited arguments will treat them the same, removing the
+% space token for us automatically. Therefore, if we test the second
+% and third argument of what such a function reads, in case 1 we will
+% get true and in cases 2 and 3 we will get false. If we choose to
+% optimize for the usual case of a printable escape char, we can do it
+% like this (again getting TeX to remove the leading space for us):
+% \begin{macrocode}
+\cs_set_nopar:Npn \cs_to_str:N {
+ \if:w \exp_after:wN \cs_str_aux:w\token_to_str:N \a ax\q_nil
+ \else:
+ \exp_after:wN \exp_after:wN\exp_after:wN \use_ii:nn
+ \fi:
+ \exp_after:wN \use_none:n \token_to_str:N
+}
+\cs_set:Npn \cs_str_aux:w #1#2#3#4\q_nil{#2#3}
+% \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 \m{true} or \m{false} is
+% returned with \m{true} for when there is a colon in the function
+% and \m{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
+ \tex_romannumeral:D -`\q \cs_to_str:N #1 @a \q_nil #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_nil#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_nil #4{#1}}
+}
+\cs_set:Npn \cs_split_function_auxii:w #1@a\q_nil#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 and also meets the
+% requirement that it does not contain a "D" signature. The reasoning
+% behind this is that most of the time, a check for a free control
+% sequence is when we wish to make a new control sequence and we do
+% not want to let the user define a new ``do not use'' control
+% sequence.
+%
+% \begin{macro}{\cs_if_exist_p:N,\cs_if_exist_p:c}
+% \begin{macro}[TF]{\cs_if_exist:N,\cs_if_exist:c}
+% Two versions for checking existence. For the "N" form we firstly
+% check for "\tex_relax:D" 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 "\tex_relax:D".
+% \begin{macrocode}
+\prg_set_conditional:Npnn \cs_if_exist:N #1 {p,TF,T,F}{
+ \if_meaning:w #1\tex_relax:D
+ \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 "\tex_relax:D" 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,TF,T,F}{
+ \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: \tex_relax:D
+ \prg_return_false:
+ \else:
+ \prg_return_true:
+ \fi:
+ }
+ \prg_return_false:
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\cs_if_do_not_use_p:N}
+% \begin{macro}[aux]{\cs_if_do_not_use_aux:nnN}
+% \begin{macrocode}
+\cs_set:Npn \cs_if_do_not_use_p:N #1{
+ \cs_split_function:NN #1 \cs_if_do_not_use_aux:nnN
+}
+\cs_set:Npn \cs_if_do_not_use_aux:nnN #1#2#3{
+ \exp_after:wN\str_if_eq_p:nn \token_to_str:N D {#2}
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\cs_if_free_p:N,\cs_if_free_p:c}
+% \begin{macro}[TF]{\cs_if_free:N,\cs_if_free:c}
+% The simple implementation is one using the boolean expression
+% parser: If it is exists or is do not use, then return false.
+% \begin{verbatim}
+% \prg_set_conditional:Npnn \cs_if_free:N #1{p,TF,T,F}{
+% \bool_if:nTF {\cs_if_exist_p:N #1 || \cs_if_do_not_use_p:N #1}
+% {\prg_return_false:}{\prg_return_true:}
+% }
+% \end{verbatim}
+% However, this functionality may not be available this early on. We
+% do something similar: The numerical values of true and false is one
+% and zero respectively, which we can use. The problem again here is
+% that the token we are checking may in fact be something that can
+% disturb the scanner, so we have to be careful. We would like to do
+% minimal evaluation so we ensure this.
+% \begin{macrocode}
+\prg_set_conditional:Npnn \cs_if_free:N #1{p,TF,T,F}{
+ \tex_ifnum:D \cs_if_exist_p:N #1 =\c_zero
+ \exp_after:wN \use_i:nn
+ \else:
+ \exp_after:wN \use_ii:nn
+ \fi:
+ {
+ \tex_ifnum:D \cs_if_do_not_use_p:N #1 =\c_zero
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+ \prg_return_false:
+}
+\cs_set_nopar:Npn \cs_if_free_p:c{\exp_args:Nc\cs_if_free_p:N}
+\cs_set_nopar:Npn \cs_if_free:cTF{\exp_args:Nc\cs_if_free:NTF}
+\cs_set_nopar:Npn \cs_if_free:cT{\exp_args:Nc\cs_if_free:NT}
+\cs_set_nopar:Npn \cs_if_free:cF{\exp_args:Nc\cs_if_free:NF}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+%
+% \subsection{Defining and checking (new) functions}
%
% \begin{macro}{\c_minus_one}
+% \begin{macro}{\c_zero}
% \begin{macro}{\c_sixteen}
% We need the constants |\c_minus_one| and |\c_sixteen| now for
-% writing information to the log and the terminal but the
-% rest are defined in the \textsf{l3num} module -- at least for the
+% writing information to the log and the terminal and |\c_zero|
+% which is used by some functions in the \textsf{l3num}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|. Otherwise the \textsf{l3int} module is
+% |\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
@@ -1381,16 +2253,18 @@
% |\c_minus_one|.
% \begin{macrocode}
%<*!initex>
-\let:NwN \c_minus_one\m@ne
+\cs_set_eq:NwN \c_minus_one\m@ne
%</!initex>
%<*!package>
-\tex_countdef:D \c_minus_one = 10 \scan_stop:
-\c_minus_one = -1 \scan_stop:
+\tex_countdef:D \c_minus_one = 10 ~
+\c_minus_one = -1 ~
%</!package>
-\tex_chardef:D \c_sixteen = 16\scan_stop:
+\tex_chardef:D \c_sixteen = 16~
+\tex_chardef:D \c_zero = 0~
% \end{macrocode}
% \end{macro}
% \end{macro}
+% \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
@@ -1402,25 +2276,29 @@
% allow us to generate error messages. The definitions here are
% only temporary, they will be redefined later on.
%
-% \begin{macro}{\io_put_log:x}
-% \begin{macro}{\io_put_term:x}
+% \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.
%
% \begin{macrocode}
-\def:Npn \io_put_log:x{
- \tex_immediate:D\io_put_deferred:Nx \c_minus_one }
-\def:Npn \io_put_term:x{
- \tex_immediate:D\io_put_deferred:Nx \c_sixteen }
+\cs_set_nopar:Npn \iow_log:x {
+ \tex_immediate:D \iow_shipout_x:Nn \c_minus_one
+}
+\cs_set_nopar:Npn \iow_term:x {
+ \tex_immediate:D \iow_shipout_x:Nn \c_sixteen
+}
% \end{macrocode}
% \end{macro}
% \end{macro}
%
-% \begin{macro}{\err_latex_bug:x}
+% \begin{macro}{\msg_kernel_bug:x}
% This will show internal errors.
% \begin{macrocode}
-\def:Npn\err_latex_bug:x#1{
- \io_put_term:x{This~is~a~LaTeX~bug!~Check~coding!}\tex_errmessage:D{#1}}
+\cs_set_nopar:Npn \msg_kernel_bug:x #1 {
+ \iow_term:x { This~is~a~LaTeX~bug:~check~coding! }
+ \tex_errmessage:D {#1}
+}
% \end{macrocode}
% \end{macro}
%
@@ -1430,123 +2308,72 @@
% definition here.
% \begin{macrocode}
%<*trace>
-\def:Npn \cs_record_meaning:N#1{}
+\cs_set:Npn \cs_record_meaning:N #1{}
%</trace>
% \end{macrocode}
% \end{macro}
%
-% We need these two to make |\chk_new_cs:N| bulletproof.
-% \begin{macrocode}
-\def_long:Npn \use_none:n #1{}
-\def_long:Npn \use_arg_i:n #1{#1}
-% \end{macrocode}
-% \begin{macro}{\chk_new_cs:N}
-% This command is called by |\def_new:Npn| and |\let_new:NN| etc.\
+% \begin{macro}{\chk_if_free_cs:N}
+% This command is called by |\cs_new_nopar:Npn| and |\cs_new_eq:NN| etc.\
% to make sure that the argument sequence is not already in use. If
% it is, an error is signalled. It checks if \m{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}
-\def:Npn \chk_new_cs:N #1{
- \if:w \cs_if_free_p:N #1
- \exp_after:NN \use_none:n
- \else:
- \exp_after:NN \use_arg_i:n
- \fi:
+\cs_set_nopar:Npn \chk_if_free_cs:N #1{
+ \cs_if_free:NF #1
{
- \err_latex_bug:x {Command~name~`\token_to_string:N #1'~
+ \msg_kernel_bug:x {Command~name~`\token_to_str:N #1'~
already~defined!~
Current~meaning:~\token_to_meaning:N #1
}
}
%<*trace>
\cs_record_meaning:N#1
-% \io_put_term:x{Defining~\token_to_string:N #1~on~%}
- \io_put_log:x{Defining~\token_to_string:N #1~on~
+% \iow_term:x{Defining~\token_to_str:N #1~on~%}
+ \iow_log:x{Defining~\token_to_str:N #1~on~
line~\tex_the:D \tex_inputlineno:D}
%</trace>
}
% \end{macrocode}
% \end{macro}
%
-% On 2005/11/20 Morten said: I think names for testing if a certain
-% condition is true or false should always contain |if| to avoid
-% confusion. This is what we do for lots of other types of test
-% functions. For now I have defined both names for the functions
-% checking names of control sequences.
-%
-% \begin{macro}{\cs_if_exist_p:N}
-% Expands into |\c_true| if the control sequence given as its
-% argument \emph{is} in use.
-% \begin{macrocode}
-\def:Npn \cs_if_exist_p:N #1{
- \if:w \cs_if_free_p:N #1
- \c_false
- \else:
- \c_true \fi:}
-% \end{macrocode}
-% \end{macro}
-%
% \begin{macro}{\chk_if_exist_cs:N }
% \begin{macro}{\chk_if_exist_cs:c }
% This function issues a warning message when the control sequence
% in its argument does not exist.
% \begin{macrocode}
-\def:Npn \chk_if_exist_cs:N #1 {
- \if:w \cs_if_exist_p:N #1
- \else:
- \err_latex_bug:x{Command~ `\token_to_string:N #1'~
+\cs_set_nopar:Npn \chk_if_exist_cs:N #1 {
+ \cs_if_exist:NF #1
+ {
+ \msg_kernel_bug:x {Command~ `\token_to_str:N #1'~
not~ yet~ defined!}
- \fi:}
-\def:Npn \chk_if_exist_cs:c #1 {
- \exp_after:NN \chk_if_exist_cs:N \cs:w #1\cs_end: }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\cs_if_free_p:N}
-% Expands into |\c_true| if the control sequence given as its
-% argument is not yet in use. Note that we make sure to expand
-% into |\c_false| if the control sequence is textually
-% |\c_undefined| or |\scan_stop:|, so that we don't end up
-% (re)defining them.
-% \begin{macrocode}
-\def:Npn \cs_if_free_p:N #1{
- \if_cs_exist:N #1
- \if_meaning:NN#1\scan_stop:
- \if:w\cs_if_eq_name_p:NN #1\scan_stop:
- \c_false \else: \c_true \fi:
- \else:
- \c_false
- \fi:
- \else:
- \if:w \cs_if_eq_name_p:NN #1\c_undefined
- \c_false \else: \c_true \fi:
- \fi:
+ }
}
-\let:NwN \cs_free_p:N \cs_if_free_p:N
+\cs_set_nopar:Npn \chk_if_exist_cs:c {\exp_args:Nc \chk_if_exist_cs:N }
% \end{macrocode}
% \end{macro}
+% \end{macro}
%
%
% \begin{macro}{\str_if_eq_p:nn}
-% \begin{macro}{\str_if_eq_p_aux:w}
+% \begin{macro}[aux]{\str_if_eq_p_aux:w}
% Takes 2 lists of characters as arguments and expands into
-% |\c_true| if they are equal, and |\c_false| otherwise. Note that
+% |\c_true_bool| if they are equal, and |\c_false_bool| otherwise. Note that
% in the current implementation spaces in these strings are
% ignored.\footnote{This is a function which could use
% \cs{tlist_compare:xx}.}
% \begin{macrocode}
-\def:Npn \str_if_eq_p:nn #1#2{
+\prg_set_conditional:Npnn \str_if_eq:nn #1#2{p}{
\str_if_eq_p_aux:w #1\scan_stop:\\#2\scan_stop:\\
}
-\def:Npn \str_if_eq_p_aux:w #1#2\\#3#4\\{
- \if_meaning:NN#1#3
- \if_meaning:NN#1\scan_stop:\c_true \else:
- \if_meaning:NN#3\scan_stop:\c_false \else:
+\cs_set_nopar:Npn \str_if_eq_p_aux:w #1#2\\#3#4\\{
+ \if_meaning:w#1#3
+ \if_meaning:w#1\scan_stop:\prg_return_true: \else:
+ \if_meaning:w#3\scan_stop:\prg_return_false: \else:
\str_if_eq_p_aux:w #2\\#4\\\fi:\fi:
- \else:\c_false \fi:}
+ \else:\prg_return_false: \fi:}
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -1557,21 +2384,21 @@
% arguments and expands into true iff they have the same name.
% We make it long in case one of them is |\par|!
% \begin{macrocode}
-\def_long:Npn \cs_if_eq_name_p:NN #1#2{
- \exp_after:NN\exp_after:NN
- \exp_after:NN\str_if_eq_p_aux:w
- \exp_after:NN\token_to_string:N
- \exp_after:NN#1
- \exp_after:NN\scan_stop:
- \exp_after:NN\\
- \token_to_string:N#2\scan_stop:\\}
+\prg_set_conditional:Npnn \cs_if_eq_name:NN #1#2{p}{
+ \exp_after:wN\exp_after:wN
+ \exp_after:wN\str_if_eq_p_aux:w
+ \exp_after:wN\token_to_str:N
+ \exp_after:wN#1
+ \exp_after:wN\scan_stop:
+ \exp_after:wN\\
+ \token_to_str:N#2\scan_stop:\\}
% \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\str_if_eq_var_p:nf}
-% \begin{macro}{\str_if_eq_var_start:nnN}
-% \begin{macro}{\str_if_eq_var_stop:w}
+% \begin{macro}[aux]{\str_if_eq_var_start:nnN}
+% \begin{macro}[aux]{\str_if_eq_var_stop:w}
% A variant of |\str_if_eq_p:nn| which has the advantage of obeying
% spaces in at least the second argument. See \textsf{l3quark} for
% an application. From the hand of David Kastrup with slight
@@ -1591,19 +2418,19 @@
% octal notation so |\tex_number:D| returns |11|. If one test
% returns false the |'| is never seen and then we get just |13|. We
% wrap the whole process in an external |\if:w| in order to make it
-% return either |\c_true| or |\c_false| since some parts of
+% return either |\c_true_bool| or |\c_false_bool| since some parts of
% \textsf{l3prg} expect a predicate to return one of these two
% tokens.
% \begin{macrocode}
-\def:Npn \str_if_eq_var_p:nf#1{
- \if:w \tex_number:D\str_if_eq_var_start:nnN{}{}#1\scan_stop:
+\prg_set_conditional:Npnn \str_if_eq_var:nf #1#2 {p} {
+ \if:w \tex_number:D\str_if_eq_var_start:nnN{}{}#1\scan_stop:{#2}
}
-\def:Npn\str_if_eq_var_start:nnN#1#2#3{
- \if:w#3\scan_stop:\exp_after:NN\str_if_eq_var_stop:w\fi:
+\cs_set_nopar:Npn\str_if_eq_var_start:nnN#1#2#3{
+ \if:w#3\scan_stop:\exp_after:wN\str_if_eq_var_stop:w\fi:
\str_if_eq_var_start:nnN{\if:w#3#1}{#2\fi:}
}
-\def:Npn\str_if_eq_var_stop:w\str_if_eq_var_start:nnN#1#2#3{
- #1#3\scan_stop:'#213~\c_true\else:\c_false\fi:
+\cs_set:Npn\str_if_eq_var_stop:w\str_if_eq_var_start:nnN#1#2#3{
+ #1#3\scan_stop:'#213~\prg_return_true:\else:\prg_return_false:\fi:
}
% \end{macrocode}
% \end{macro}
@@ -1613,39 +2440,37 @@
%
%
%
-% \subsubsection{More new definitions}
+% \subsection{More new definitions}
%
%
%
-% \begin{macro}{\def_new:Npn}
-% \begin{macro}{\def_new:Npx}
-% \begin{macro}{\def_long_new:Npn}
-% \begin{macro}{\def_long_new:Npx}
-% \begin{macro}{\def_protected_new:Npn}
-% \begin{macro}{\def_protected_new:Npx}
-% \begin{macro}{\def_protected_long_new:Npn}
-% \begin{macro}{\def_protected_long_new:Npx}
-% These are like |\def:Npn| and |\let:NN|, but they first check that
-% the argument command is not already in use. You may use
-% |\pref_global:D|, |\pref_long:D|, |\pref_protected:D|, and
+% \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}
+% These are like |\cs_set_nopar:Npn| and |\cs_set_eq:NN|, but they
+% first check that the argument command is not already in use. You
+% may use |\pref_global:D|, |\pref_long:D|, |\pref_protected:D|, and
% |\tex_outer:D| as prefixes.
% \begin {macrocode}
-\def_protected:Npn \def_new:Npn #1{\chk_new_cs:N #1
- \def:Npn #1}
-\def_protected:Npn \def_new:Npx #1{\chk_new_cs:N #1
- \def:Npx #1}
-\def_protected:Npn \def_long_new:Npn #1{\chk_new_cs:N #1
- \def_long:Npn #1}
-\def_protected:Npn \def_long_new:Npx #1{\chk_new_cs:N #1
- \def_long:Npx #1}
-\def_protected:Npn \def_protected_new:Npn #1{\chk_new_cs:N #1
- \def_protected:Npn #1}
-\def_protected:Npn \def_protected_new:Npx #1{\chk_new_cs:N #1
- \def_protected:Npx #1}
-\def_protected:Npn \def_protected_long_new:Npn #1{\chk_new_cs:N #1
- \def_protected_long:Npn #1}
-\def_protected:Npn \def_protected_long_new:Npx #1{\chk_new_cs:N #1
- \def_protected_long:Npx #1}
+\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_set_nopar:Npn
+\cs_tmp:w \cs_new_nopar:Npx\cs_set_nopar:Npx
+\cs_tmp:w \cs_new:Npn \cs_set:Npn
+\cs_tmp:w \cs_new:Npx\cs_set:Npx
+\cs_tmp:w \cs_new_protected_nopar:Npn \cs_set_protected_nopar:Npn
+\cs_tmp:w \cs_new_protected_nopar:Npx\cs_set_protected_nopar:Npx
+\cs_tmp:w \cs_new_protected:Npn \cs_set_protected:Npn
+\cs_tmp:w \cs_new_protected:Npx\cs_set_protected:Npx
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -1656,32 +2481,24 @@
% \end{macro}
% \end{macro}
%
-% \begin{macro}{\gdef_new:Npn}
-% \begin{macro}{\gdef_new:Npx}
-% \begin{macro}{\gdef_long_new:Npn}
-% \begin{macro}{\gdef_long_new:Npx}
-% \begin{macro}{\gdef_protected_new:Npn}
-% \begin{macro}{\gdef_protected_new:Npx}
-% \begin{macro}{\gdef_protected_long_new:Npn}
-% \begin{macro}{\gdef_protected_long_new:Npx}
+% \begin{macro}{\cs_gnew_nopar:Npn}
+% \begin{macro}{\cs_gnew_nopar:Npx}
+% \begin{macro}{\cs_gnew:Npn}
+% \begin{macro}{\cs_gnew:Npx}
+% \begin{macro}{\cs_gnew_protected_nopar:Npn}
+% \begin{macro}{\cs_gnew_protected_nopar:Npx}
+% \begin{macro}{\cs_gnew_protected:Npn}
+% \begin{macro}{\cs_gnew_protected:Npx}
% Global versions of the above functions.
% \begin {macrocode}
-\def_protected_new:Npn \gdef_new:Npn #1{\chk_new_cs:N #1
- \gdef:Npn #1}
-\def_protected_new:Npn \gdef_new:Npx #1{\chk_new_cs:N #1
- \gdef:Npx #1}
-\def_protected_new:Npn \gdef_long_new:Npn #1{\chk_new_cs:N #1
- \gdef_long:Npn #1}
-\def_protected_new:Npn \gdef_long_new:Npx #1{\chk_new_cs:N #1
- \gdef_long:Npx #1}
-\def_protected_new:Npn \gdef_protected_new:Npn #1{\chk_new_cs:N #1
- \gdef_protected:Npn #1}
-\def_protected_new:Npn \gdef_protected_new:Npx #1{\chk_new_cs:N #1
- \gdef_protected:Npx #1}
-\def_protected_new:Npn \gdef_protected_long_new:Npn #1{\chk_new_cs:N #1
- \gdef_protected_long:Npn #1}
-\def_protected_new:Npn \gdef_protected_long_new:Npx #1{\chk_new_cs:N #1
- \gdef_protected_long:Npx #1}
+\cs_tmp:w \cs_gnew_nopar:Npn \cs_gset_nopar:Npn
+\cs_tmp:w \cs_gnew_nopar:Npx \cs_gset_nopar:Npx
+\cs_tmp:w \cs_gnew:Npn \cs_gset:Npn
+\cs_tmp:w \cs_gnew:Npx \cs_gset:Npx
+\cs_tmp:w \cs_gnew_protected_nopar:Npn \cs_gset_protected_nopar:Npn
+\cs_tmp:w \cs_gnew_protected_nopar:Npx \cs_gset_protected_nopar:Npx
+\cs_tmp:w \cs_gnew_protected:Npn \cs_gset_protected:Npn
+\cs_tmp:w \cs_gnew_protected:Npx \cs_gset_protected:Npx
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -1693,33 +2510,36 @@
% \end{macro}
%
%
-% \begin{macro}{\def:cpn}
-% \begin{macro}{\def:cpx}
-% \begin{macro}{\gdef:cpn}
-% \begin{macro}{\gdef:cpx}
-% \begin{macro}{\def_new:cpn}
-% \begin{macro}{\def_new:cpx}
-% \begin{macro}{\gdef_new:cpn}
-% \begin{macro}{\gdef_new:cpx}
-% Like |\def:Npn| and |\def_new: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.
+% \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}
+% \begin{macro}{\cs_gnew_nopar:cpn}
+% \begin{macro}{\cs_gnew_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.
%
-% |\def:cpn|\m{string}\m{rep-text} will turn \m{string} into a
-% csname and then assign \m {rep-text} to it by using |\def:Npn|.
-% This means that there might be a parameter string between the two
-% arguments.
+% |\cs_set_nopar:cpn|\m{string}\m{rep-text} will turn \m{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}
-\def_new:Npn \def:cpn #1{\exp_after:NN \def:Npn \cs:w #1\cs_end:}
-\def_new:Npn \def:cpx #1{\exp_after:NN \def:Npx \cs:w #1\cs_end:}
-\def_new:Npn \gdef:cpn #1{\exp_after:NN \gdef:Npn \cs:w #1\cs_end:}
-\def_new:Npn \gdef:cpx #1{\exp_after:NN \gdef:Npx \cs:w #1\cs_end:}
-\def_new:Npn \def_new:cpn #1{\exp_after:NN \def_new:Npn \cs:w #1\cs_end:}
-\def_new:Npn \def_new:cpx #1{\exp_after:NN \def_new:Npx \cs:w #1\cs_end:}
-\def_new:Npn \gdef_new:cpn #1{\exp_after:NN \gdef_new:Npn \cs:w #1\cs_end:}
-\def_new:Npn \gdef_new:cpx #1{\exp_after:NN \gdef_new:Npx \cs:w #1\cs_end:}
+\cs_set:Npn \cs_tmp:w #1#2{
+ \cs_new_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_gnew_nopar:cpn \cs_gnew_nopar:Npn
+\cs_tmp:w \cs_gnew_nopar:cpx \cs_gnew_nopar:Npx
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -1732,32 +2552,25 @@
%
%
%
-% \begin{macro}{\def_long:cpn}
-% \begin{macro}{\def_long:cpx}
-% \begin{macro}{\gdef_long:cpn}
-% \begin{macro}{\gdef_long:cpx}
-% \begin{macro}{\def_long_new:cpn}
-% \begin{macro}{\def_long_new:cpx}
-% \begin{macro}{\gdef_long_new:cpn}
-% \begin{macro}{\gdef_long_new:cpx}
-% Variants of the |\def_long:Npn| versions which make a csname out
+% \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}
+% \begin{macro}{\cs_gnew:cpn}
+% \begin{macro}{\cs_gnew: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}
-\def_new:Npn \def_long:cpn #1{\exp_after:NN \def_long:Npn \cs:w #1\cs_end:}
-\def_new:Npn \def_long:cpx #1{
- \exp_after:NN\def_long:Npx\cs:w #1\cs_end:}
-\def_new:Npn \gdef_long:cpn #1{
- \exp_after:NN \gdef_long:Npn \cs:w #1\cs_end:}
-\def_new:Npn \gdef_long:cpx #1{
- \exp_after:NN\gdef_long:Npx\cs:w #1\cs_end:}
-\def_new:Npn \def_long_new:cpn #1{
- \exp_after:NN \def_long_new:Npn \cs:w #1\cs_end:}
-\def_new:Npn \def_long_new:cpx #1{
- \exp_after:NN \def_long_new:Npx \cs:w #1\cs_end:}
-\def_new:Npn \gdef_long_new:cpn #1{
- \exp_after:NN \gdef_long_new:Npn \cs:w #1\cs_end:}
-\def_new:Npn \gdef_long_new:cpx #1{
- \exp_after:NN \gdef_long_new:Npx \cs:w #1\cs_end:}
+\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_gnew:cpn \cs_gnew:Npn
+\cs_tmp:w \cs_gnew:cpx \cs_gnew:Npx
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -1768,33 +2581,25 @@
% \end{macro}
% \end{macro}
%
-% \begin{macro}{\def_protected:cpn}
-% \begin{macro}{\def_protected:cpx}
-% \begin{macro}{\gdef_protected:cpn}
-% \begin{macro}{\gdef_protected:cpx}
-% \begin{macro}{\def_protected_new:cpn}
-% \begin{macro}{\def_protected_new:cpx}
-% \begin{macro}{\gdef_protected_new:cpn}
-% \begin{macro}{\gdef_protected_new:cpx}
-% Variants of the |\def_protected:Npn| versions which make a csname
+% \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}
+% \begin{macro}{\cs_gnew_protected_nopar:cpn}
+% \begin{macro}{\cs_gnew_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}
-\def_new:Npn \def_protected:cpn #1{
- \exp_after:NN \def_protected:Npn \cs:w #1\cs_end:}
-\def_new:Npn \def_protected:cpx #1{
- \exp_after:NN\def_protected:Npx\cs:w #1\cs_end:}
-\def_new:Npn \gdef_protected:cpn #1{
- \exp_after:NN \gdef_protected:Npn \cs:w #1\cs_end:}
-\def_new:Npn \gdef_protected:cpx #1{
- \exp_after:NN\gdef_protected:Npx\cs:w #1\cs_end:}
-\def_new:Npn \def_protected_new:cpn #1{
- \exp_after:NN \def_protected_new:Npn \cs:w #1\cs_end:}
-\def_new:Npn \def_protected_new:cpx #1{
- \exp_after:NN \def_protected_new:Npx \cs:w #1\cs_end:}
-\def_new:Npn \gdef_protected_new:cpn #1{
- \exp_after:NN \gdef_protected_new:Npn \cs:w #1\cs_end:}
-\def_new:Npn \gdef_protected_new:cpx #1{
- \exp_after:NN \gdef_protected_new:Npx \cs:w #1\cs_end:}
+\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_gnew_protected_nopar:cpn \cs_gnew_protected_nopar:Npn
+\cs_tmp:w \cs_gnew_protected_nopar:cpx \cs_gnew_protected_nopar:Npx
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -1805,33 +2610,25 @@
% \end{macro}
% \end{macro}
%
-% \begin{macro}{\def_protected_long:cpn}
-% \begin{macro}{\def_protected_long:cpx}
-% \begin{macro}{\gdef_protected_long:cpn}
-% \begin{macro}{\gdef_protected_long:cpx}
-% \begin{macro}{\def_protected_long_new:cpn}
-% \begin{macro}{\def_protected_long_new:cpx}
-% \begin{macro}{\gdef_protected_long_new:cpn}
-% \begin{macro}{\gdef_protected_long_new:cpx}
-% Variants of the |\def_protected_long:Npn| versions which make a csname
+% \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}
+% \begin{macro}{\cs_gnew_protected:cpn}
+% \begin{macro}{\cs_gnew_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}
-\def_new:Npn \def_protected_long:cpn #1{
- \exp_after:NN \def_protected_long:Npn \cs:w #1\cs_end:}
-\def_new:Npn \def_protected_long:cpx #1{
- \exp_after:NN\def_protected_long:Npx\cs:w #1\cs_end:}
-\def_new:Npn \gdef_protected_long:cpn #1{
- \exp_after:NN \gdef_protected_long:Npn \cs:w #1\cs_end:}
-\def_new:Npn \gdef_protected_long:cpx #1{
- \exp_after:NN\gdef_protected_long:Npx\cs:w #1\cs_end:}
-\def_new:Npn \def_protected_long_new:cpn #1{
- \exp_after:NN \def_protected_long_new:Npn \cs:w #1\cs_end:}
-\def_new:Npn \def_protected_long_new:cpx #1{
- \exp_after:NN \def_protected_long_new:Npx \cs:w #1\cs_end:}
-\def_new:Npn \gdef_protected_long_new:cpn #1{
- \exp_after:NN \gdef_protected_long_new:Npn \cs:w #1\cs_end:}
-\def_new:Npn \gdef_protected_long_new:cpx #1{
- \exp_after:NN \gdef_protected_long_new:Npx \cs:w #1\cs_end:}
+\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_tmp:w \cs_gnew_protected:cpn \cs_gnew_protected:Npn
+\cs_tmp:w \cs_gnew_protected:cpx \cs_gnew_protected:Npx
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -1843,56 +2640,31 @@
% \end{macro}
%
%
-% \begin{macro}{\def_aux_0:NNn}
-% \begin{macro}{\def_aux_1:NNn}
-% \begin{macro}{\def_aux_2:NNn}
-% \begin{macro}{\def_aux_3:NNn}
-% \begin{macro}{\def_aux_4:NNn}
-% \begin{macro}{\def_aux_5:NNn}
-% \begin{macro}{\def_aux_6:NNn}
-% \begin{macro}{\def_aux_7:NNn}
-% \begin{macro}{\def_aux_8:NNn}
-% \begin{macro}{\def_aux_9:NNn}
-% \begin{macro}{\def_aux:NNnn}
-% \begin{macro}{\def_aux:Ncnn}
-% \begin{macro}{\def_arg_number_error_msg:Nn}
-% Defining a function with $n$ arguments. First some helper functions.
-% \begin{macrocode}
-\def_new:cpn {def_aux_0:NNn} #1#2 {#1 #2 }
-\def_new:cpn {def_aux_1:NNn} #1#2 {#1 #2 ##1 }
-\def_new:cpn {def_aux_2:NNn} #1#2 {#1 #2 ##1##2 }
-\def_new:cpn {def_aux_3:NNn} #1#2 {#1 #2 ##1##2##3 }
-\def_new:cpn {def_aux_4:NNn} #1#2 {#1 #2 ##1##2##3##4 }
-\def_new:cpn {def_aux_5:NNn} #1#2 {#1 #2 ##1##2##3##4##5 }
-\def_new:cpn {def_aux_6:NNn} #1#2 {#1 #2 ##1##2##3##4##5##6 }
-\def_new:cpn {def_aux_7:NNn} #1#2 {#1 #2 ##1##2##3##4##5##6##7 }
-\def_new:cpn {def_aux_8:NNn} #1#2 {#1 #2 ##1##2##3##4##5##6##7##8 }
-\def_new:cpn {def_aux_9:NNn} #1#2 {#1 #2 ##1##2##3##4##5##6##7##8##9 }
-% \end{macrocode}
-% Then the function itself which checks for the existance of such a
-% helper function. If it doesn't exist, return an error. Otherwise
-% call it to define \verb|#2| with the correct number of arguments.
+% \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, i.e., when you need to define a function to
+% process three parameters. See \textsf{xparse} for an application.
% \begin{macrocode}
-\def_protected_long_new:Npn \def_aux:NNnn #1#2#3#4 {
- \cs_if_really_exist:cTF {def_aux_\tex_the:D\etex_numexpr:D #3 :NNn}
- {
- \cs_use:c {def_aux_\tex_the:D\etex_numexpr:D #3 :NNn} #1 #2 {#4}
- }
- { \def_arg_number_error_msg:Nn #2{#3} }
-}
-\def_new:Npn \def_aux:Ncnn #1#2{
- \exp_after:NN \def_aux:NNnn \exp_after:NN #1 \cs:w #2\cs_end:}
-% \end{macrocode}
-% The error message.
-% \begin{macrocode}
-\def_new:Npn \def_arg_number_error_msg:Nn #1#2 {
- \err_latex_bug:x{
- You're~ trying~ to~ define~ the~ command~ `\token_to_string:N #1'~
- with~ \use_arg_i:n{\tex_the:D\etex_numexpr:D #2\scan_stop:} ~
- arguments~ but~ I~ only~ allow~ 0-9~ arguments.~ I~ can~ probably~
- not~ help~ you~ here
- }
-}
+\cs_set_nopar:cpn{use_0_parameter:}{}
+\cs_set_nopar:cpn{use_1_parameter:}{{##1}}
+\cs_set_nopar:cpn{use_2_parameter:}{{##1}{##2}}
+\cs_set_nopar:cpn{use_3_parameter:}{{##1}{##2}{##3}}
+\cs_set_nopar:cpn{use_4_parameter:}{{##1}{##2}{##3}{##4}}
+\cs_set_nopar:cpn{use_5_parameter:}{{##1}{##2}{##3}{##4}{##5}}
+\cs_set_nopar:cpn{use_6_parameter:}{{##1}{##2}{##3}{##4}{##5}{##6}}
+\cs_set_nopar:cpn{use_7_parameter:}{{##1}{##2}{##3}{##4}{##5}{##6}{##7}}
+\cs_set_nopar:cpn{use_8_parameter:}{
+ {##1}{##2}{##3}{##4}{##5}{##6}{##7}{##8}}
+\cs_set_nopar:cpn{use_9_parameter:}{
+ {##1}{##2}{##3}{##4}{##5}{##6}{##7}{##8}{##9}}
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -1904,409 +2676,332 @@
% \end{macro}
% \end{macro}
% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
%
-% \begin{macro}{\def_aux_use_0_parameter:}
-% \begin{macro}{\def_aux_use_1_parameter:}
-% \begin{macro}{\def_aux_use_2_parameter:}
-% \begin{macro}{\def_aux_use_3_parameter:}
-% \begin{macro}{\def_aux_use_4_parameter:}
-% \begin{macro}{\def_aux_use_5_parameter:}
-% \begin{macro}{\def_aux_use_6_parameter:}
-% \begin{macro}{\def_aux_use_7_parameter:}
-% \begin{macro}{\def_aux_use_8_parameter:}
-% \begin{macro}{\def_aux_use_9_parameter:}
-% Something similar to |\def_aux_9:NNn| but for using the
-% parameters.
+% \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_chartok{~}| 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 `already defined' error rather than `runaway argument'.
+%
+% The |c| variants are not protected in order for their arguments to
+% be constructed in the correct context.
+%
% \begin{macrocode}
-\def:cpn{def_aux_use_0_parameter:}{}
-\def:cpn{def_aux_use_1_parameter:}{{##1}}
-\def:cpn{def_aux_use_2_parameter:}{{##1}{##2}}
-\def:cpn{def_aux_use_3_parameter:}{{##1}{##2}{##3}}
-\def:cpn{def_aux_use_4_parameter:}{{##1}{##2}{##3}{##4}}
-\def:cpn{def_aux_use_5_parameter:}{{##1}{##2}{##3}{##4}{##5}}
-\def:cpn{def_aux_use_6_parameter:}{{##1}{##2}{##3}{##4}{##5}{##6}}
-\def:cpn{def_aux_use_7_parameter:}{{##1}{##2}{##3}{##4}{##5}{##6}{##7}}
-\def:cpn{def_aux_use_8_parameter:}{
- {##1}{##2}{##3}{##4}{##5}{##6}{##7}{##8}}
-\def:cpn{def_aux_use_9_parameter:}{
- {##1}{##2}{##3}{##4}{##5}{##6}{##7}{##8}{##9}}
+\cs_set_protected:Npn \cs_set_eq:NN #1 { \cs_set_eq:NwN #1=~ }
+\cs_set_nopar:Npn \cs_set_eq:cN { \exp_args:Nc \cs_set_eq:NN }
+\cs_set_nopar:Npn \cs_set_eq:Nc { \exp_args:NNc \cs_set_eq:NN }
+\cs_set_nopar:Npn \cs_set_eq:cc { \exp_args:Ncc \cs_set_eq:NN }
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
%
-% \begin{macro}{\def:NNn}
-% \begin{macro}{\def:NNx}
-% \begin{macro}{\def:cNn}
-% \begin{macro}{\def:cNx}
-% \begin{macro}{\gdef:NNn}
-% \begin{macro}{\gdef:NNx}
-% \begin{macro}{\gdef:cNn}
-% \begin{macro}{\gdef:cNx}
-% \begin{macro}{\def_new:NNn}
-% \begin{macro}{\def_new:NNx}
-% \begin{macro}{\def_new:cNn}
-% \begin{macro}{\def_new:cNx}
-% \begin{macro}{\gdef_new:NNn}
-% \begin{macro}{\gdef_new:NNx}
-% \begin{macro}{\gdef_new:cNn}
-% \begin{macro}{\gdef_new:cNx}
-% Defining macros without delimited arguments is now relatively
-% easy. First local and global versions of the usual |\def:Npn|
-% operation.
+% \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}
-\def_new:Npn \def:NNn { \def_aux:NNnn \def:Npn }
-\def_new:Npn \def:NNx { \def_aux:NNnn \def:Npx }
-\def_new:Npn \def:cNn { \def_aux:Ncnn \def:Npn }
-\def_new:Npn \def:cNx { \def_aux:Ncnn \def:Npx }
-\def_new:Npn \gdef:NNn { \def_aux:NNnn \gdef:Npn }
-\def_new:Npn \gdef:NNx { \def_aux:NNnn \gdef:Npx }
-\def_new:Npn \gdef:cNn { \def_aux:Ncnn \gdef:Npn }
-\def_new:Npn \gdef:cNx { \def_aux:Ncnn \gdef:Npx }
-\def_new:Npn \def_new:NNn { \def_aux:NNnn \def_new:Npn }
-\def_new:Npn \def_new:NNx { \def_aux:NNnn \def_new:Npx }
-\def_new:Npn \def_new:cNn { \def_aux:Ncnn \def_new:Npn }
-\def_new:Npn \def_new:cNx { \def_aux:Ncnn \def_new:Npx }
-\def_new:Npn \gdef_new:NNn { \def_aux:NNnn \gdef_new:Npn }
-\def_new:Npn \gdef_new:NNx { \def_aux:NNnn \gdef_new:Npx }
-\def_new:Npn \gdef_new:cNn { \def_aux:Ncnn \gdef_new:Npn }
-\def_new:Npn \gdef_new:cNx { \def_aux:Ncnn \gdef_new:Npx }
+\cs_new_protected:Npn \cs_new_eq:NN #1 {
+ \chk_if_free_cs:N #1
+ \cs_set_eq:NN #1
+}
+\cs_new_nopar:Npn \cs_new_eq:cN { \exp_args:Nc \cs_new_eq:NN }
+\cs_new_nopar:Npn \cs_new_eq:Nc { \exp_args:NNc \cs_new_eq:NN }
+\cs_new_nopar:Npn \cs_new_eq:cc { \exp_args:Ncc \cs_new_eq:NN }
% \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}{\def_long:NNn}
-% \begin{macro}{\def_long:NNx}
-% \begin{macro}{\def_long:cNn}
-% \begin{macro}{\def_long:cNx}
-% \begin{macro}{\gdef_long:NNn}
-% \begin{macro}{\gdef_long:NNx}
-% \begin{macro}{\gdef_long:cNn}
-% \begin{macro}{\gdef_long:cNx}
-% \begin{macro}{\def_long_new:NNn}
-% \begin{macro}{\def_long_new:NNx}
-% \begin{macro}{\def_long_new:cNn}
-% \begin{macro}{\def_long_new:cNx}
-% \begin{macro}{\gdef_long_new:NNn}
-% \begin{macro}{\gdef_long_new:NNx}
-% \begin{macro}{\gdef_long_new:cNn}
-% \begin{macro}{\gdef_long_new:cNx}
-% Long versions of the above.
+% \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}
-\def_new:Npn \def_long:NNn { \def_aux:NNnn \def_long:Npn }
-\def_new:Npn \def_long:NNx { \def_aux:NNnn \def_long:Npx }
-\def_new:Npn \def_long:cNn { \def_aux:Ncnn \def_long:Npn }
-\def_new:Npn \def_long:cNx { \def_aux:Ncnn \def_long:Npx }
-\def_new:Npn \gdef_long:NNn { \def_aux:NNnn \gdef_long:Npn }
-\def_new:Npn \gdef_long:NNx { \def_aux:NNnn \gdef_long:Npx }
-\def_new:Npn \gdef_long:cNn { \def_aux:Ncnn \gdef_long:Npn }
-\def_new:Npn \gdef_long:cNx { \def_aux:Ncnn \gdef_long:Npx }
-\def_new:Npn \def_long_new:NNn { \def_aux:NNnn \def_long_new:Npn }
-\def_new:Npn \def_long_new:NNx { \def_aux:NNnn \def_long_new:Npx }
-\def_new:Npn \def_long_new:cNn { \def_aux:Ncnn \def_long_new:Npn }
-\def_new:Npn \def_long_new:cNx { \def_aux:Ncnn \def_long_new:Npx }
-\def_new:Npn \gdef_long_new:NNn { \def_aux:NNnn \gdef_long_new:Npn }
-\def_new:Npn \gdef_long_new:NNx { \def_aux:NNnn \gdef_long_new:Npx }
-\def_new:Npn \gdef_long_new:cNn { \def_aux:Ncnn \gdef_long_new:Npn }
-\def_new:Npn \gdef_long_new:cNx { \def_aux:Ncnn \gdef_long_new:Npx }
+\cs_new_protected:Npn \cs_gset_eq:NN { \pref_global:D \cs_set_eq:NN }
+\cs_new_nopar:Npn \cs_gset_eq:Nc { \exp_args:NNc \cs_gset_eq:NN }
+\cs_new_nopar:Npn \cs_gset_eq:cN { \exp_args:Nc \cs_gset_eq:NN }
+\cs_new_nopar:Npn \cs_gset_eq:cc { \exp_args:Ncc \cs_gset_eq:NN }
% \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}{\def_protected:NNn}
-% \begin{macro}{\def_protected:NNx}
-% \begin{macro}{\def_protected:cNn}
-% \begin{macro}{\def_protected:cNx}
-% \begin{macro}{\gdef_protected:NNn}
-% \begin{macro}{\gdef_protected:NNx}
-% \begin{macro}{\gdef_protected:cNn}
-% \begin{macro}{\gdef_protected:cNx}
-% \begin{macro}{\def_protected_new:NNn}
-% \begin{macro}{\def_protected_new:NNx}
-% \begin{macro}{\def_protected_new:cNn}
-% \begin{macro}{\def_protected_new:cNx}
-% \begin{macro}{\gdef_protected_new:NNn}
-% \begin{macro}{\gdef_protected_new:NNx}
-% \begin{macro}{\gdef_protected_new:cNn}
-% \begin{macro}{\gdef_protected_new:cNx}
-% Protected versions of the above.
+% \begin{macro}{\cs_gnew_eq:NN}
+% \begin{macro}{\cs_gnew_eq:cN}
+% \begin{macro}{\cs_gnew_eq:Nc}
+% \begin{macro}{\cs_gnew_eq:cc}
% \begin{macrocode}
-\def_new:Npn \def_protected:NNn { \def_aux:NNnn \def_protected:Npn }
-\def_new:Npn \def_protected:NNx { \def_aux:NNnn \def_protected:Npx }
-\def_new:Npn \def_protected:cNn { \def_aux:Ncnn \def_protected:Npn }
-\def_new:Npn \def_protected:cNx { \def_aux:Ncnn \def_protected:Npx }
-\def_new:Npn \gdef_protected:NNn { \def_aux:NNnn \gdef_protected:Npn }
-\def_new:Npn \gdef_protected:NNx { \def_aux:NNnn \gdef_protected:Npx }
-\def_new:Npn \gdef_protected:cNn { \def_aux:Ncnn \gdef_protected:Npn }
-\def_new:Npn \gdef_protected:cNx { \def_aux:Ncnn \gdef_protected:Npx }
-\def_new:Npn \def_protected_new:NNn { \def_aux:NNnn \def_protected_new:Npn }
-\def_new:Npn \def_protected_new:NNx { \def_aux:NNnn \def_protected_new:Npx }
-\def_new:Npn \def_protected_new:cNn { \def_aux:Ncnn \def_protected_new:Npn }
-\def_new:Npn \def_protected_new:cNx { \def_aux:Ncnn \def_protected_new:Npx }
-\def_new:Npn \gdef_protected_new:NNn { \def_aux:NNnn \gdef_protected_new:Npn }
-\def_new:Npn \gdef_protected_new:NNx { \def_aux:NNnn \gdef_protected_new:Npx }
-\def_new:Npn \gdef_protected_new:cNn { \def_aux:Ncnn \gdef_protected_new:Npn }
-\def_new:Npn \gdef_protected_new:cNx { \def_aux:Ncnn \gdef_protected_new:Npx }
+\cs_new_protected:Npn \cs_gnew_eq:NN #1 {
+ \chk_if_free_cs:N #1
+ \pref_global:D \cs_set_eq:NN #1
+}
+\cs_new_nopar:Npn \cs_gnew_eq:cN { \exp_args:Nc \cs_gnew_eq:NN }
+\cs_new_nopar:Npn \cs_gnew_eq:Nc { \exp_args:NNc \cs_gnew_eq:NN }
+\cs_new_nopar:Npn \cs_gnew_eq:cc { \exp_args:Ncc \cs_gnew_eq:NN }
% \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}{\def_protected_long:NNn}
-% \begin{macro}{\def_protected_long:NNx}
-% \begin{macro}{\def_protected_long:cNn}
-% \begin{macro}{\def_protected_long:cNx}
-% \begin{macro}{\gdef_protected_long:NNn}
-% \begin{macro}{\gdef_protected_long:NNx}
-% \begin{macro}{\gdef_protected_long:cNn}
-% \begin{macro}{\gdef_protected_long:cNx}
-% \begin{macro}{\def_protected_long_new:NNn}
-% \begin{macro}{\def_protected_long_new:NNx}
-% \begin{macro}{\def_protected_long_new:cNn}
-% \begin{macro}{\def_protected_long_new:cNx}
-% \begin{macro}{\gdef_protected_long_new:NNn}
-% \begin{macro}{\gdef_protected_long_new:NNx}
-% \begin{macro}{\gdef_protected_long_new:cNn}
-% \begin{macro}{\gdef_protected_long_new:cNx}
-% And finally both long and protected.
+%
+% \subsection{Undefining functions}
+%
+% \begin{macro}{\cs_gundefine:N }
+% 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}
-\def_new:Npn \def_protected_long:NNn { \def_aux:NNnn \def_protected_long:Npn }
-\def_new:Npn \def_protected_long:NNx { \def_aux:NNnn \def_protected_long:Npx }
-\def_new:Npn \def_protected_long:cNn { \def_aux:Ncnn \def_protected_long:Npn }
-\def_new:Npn \def_protected_long:cNx { \def_aux:Ncnn \def_protected_long:Npx }
-\def_new:Npn \gdef_protected_long:NNn { \def_aux:NNnn \gdef_protected_long:Npn }
-\def_new:Npn \gdef_protected_long:NNx { \def_aux:NNnn \gdef_protected_long:Npx }
-\def_new:Npn \gdef_protected_long:cNn { \def_aux:Ncnn \gdef_protected_long:Npn }
-\def_new:Npn \gdef_protected_long:cNx { \def_aux:Ncnn \gdef_protected_long:Npx }
-\def_new:Npn \def_protected_long_new:NNn {
- \def_aux:NNnn \def_protected_long_new:Npn }
-\def_new:Npn \def_protected_long_new:NNx {
- \def_aux:NNnn \def_protected_long_new:Npx }
-\def_new:Npn \def_protected_long_new:cNn {
- \def_aux:Ncnn \def_protected_long_new:Npn }
-\def_new:Npn \def_protected_long_new:cNx {
- \def_aux:Ncnn \def_protected_long_new:Npx }
-\def_new:Npn \gdef_protected_long_new:NNn {
- \def_aux:NNnn \gdef_protected_long_new:Npn }
-\def_new:Npn \gdef_protected_long_new:NNx {
- \def_aux:NNnn \gdef_protected_long_new:Npx }
-\def_new:Npn \gdef_protected_long_new:cNn {
- \def_aux:Ncnn \gdef_protected_long_new:Npn }
-\def_new:Npn \gdef_protected_long_new:cNx {
- \def_aux:Ncnn \gdef_protected_long_new:Npx }
+\cs_new_nopar:Npn \cs_gundefine:N #1{\cs_gset_eq:NN #1\c_undefined: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}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
%
%
-% \begin{macro}{\let:NN}
-% \begin{macro}{\let:cN}
-% \begin{macro}{\let:Nc}
-% \begin{macro}{\let:cc}
-% \begin{macro}{\let_new:NN}
-% \begin{macro}{\let_new:cN}
-% \begin{macro}{\let_new:Nc}
-% \begin{macro}{\let_new:cc}
-% These macros allow us to copy the definition of a control sequence
-% to another control sequence.
-% \begin{macrocode}
-\def_protected_long_new:Npn \let:NN #1{
+% \subsection{Engine specific definitions}
+%
+% \begin{macro}{\c_xetex_is_engine_bool,\c_luatex_is_engine_bool}
+% \begin{macro}[TF]{\xetex_if_engine:,\luatex_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.
+% \begin{macrocode}
+\if_cs_exist:N \xetex_version:D
+ \cs_new_eq:NN \c_xetex_is_engine_bool \c_true_bool
+\else:
+ \cs_new_eq:NN \c_xetex_is_engine_bool \c_false_bool
+\fi:
+\prg_new_conditional:Npnn \xetex_if_engine: {TF,T,F} {
+ \if_bool:N \c_xetex_is_engine_bool
+ \prg_return_true: \else: \prg_return_false: \fi:
+}
% \end{macrocode}
-% The |=| sign allows us to define funny char tokens like .|=|
-% itself or \verb*= = with this function. For the definition of
-% |\c_space_chartok{~}| to work we need the |~| after the |=|
+%
% \begin{macrocode}
- \let:NwN #1=~}
-\def_new:Npn\let:cN #1 {\exp_after:NN\let:NN\cs:w#1\cs_end:}
-\def_new:Npn\let:Nc{\exp_args:NNc\let:NN}
-\def_new:Npn\let:cc{\exp_args:Ncc\let:NN}
-\def_new:Npn \let_new:NN #1{\chk_new_cs:N #1
- \let:NN #1}
-\def_new:Npn \let_new:cN {\exp_args:Nc \let_new:NN}
-\def_new:Npn \let_new:Nc {\exp_args:NNc \let_new:NN}
-\def_new:Npn \let_new:cc {\exp_args:Ncc \let_new:NN}
+\if_cs_exist:N \luatex_directlua:D
+ \cs_new_eq:NN \c_luatex_is_engine_bool \c_true_bool
+\else:
+ \cs_new_eq:NN \c_luatex_is_engine_bool \c_false_bool
+\fi:
+\prg_set_conditional:Npnn \xetex_if_engine: {TF,T,F}{
+ \if_bool:N \c_xetex_is_engine_bool \prg_return_true:
+ \else: \prg_return_false: \fi:
+}
+\prg_set_conditional:Npnn \luatex_if_engine: {TF,T,F}{
+ \if_bool:N \c_luatex_is_engine_bool \prg_return_true:
+ \else: \prg_return_false: \fi:
+}
% \end{macrocode}
% \end{macro}
% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
%
-% \begin{macro}{\glet:NN}
-% \begin{macro}{\glet:cN}
-% \begin{macro}{\glet:Nc}
-% \begin{macro}{\glet:cc}
-% \begin{macro}{\glet_new:NN}
-% \begin{macro}{\glet_new:cN}
-% \begin{macro}{\glet_new:Nc}
-% \begin{macro}{\glet_new:cc}
-% These are global versions of some of the previously defined functions.
+%
+%
+%
+% \subsection{Scratch functions}
+%
+% \begin{macro}{\prg_do_nothing:}
+% I don't think this function belongs here, but one place is as
+% good as any other. I want to use this function when I want to
+% express `no operation'. It is for example used in templates where
+% depending on the users settings we have to either select an function that
+% does something, or one that does nothing.
% \begin{macrocode}
-\def_protected_new:Npn \glet:NN {\pref_global:D \let:NN}
-\def_protected_new:Npn \glet:Nc {\exp_args:NNc \glet:NN}
-\def_protected_new:Npn \glet:cN {\exp_args:Nc \glet:NN}
-\def_new:Npn \glet:cc {\exp_args:Ncc \glet:NN}
-\def_new:Npn \glet_new:NN #1{\chk_new_cs:N #1
- \tex_global:D\let:NN #1}
-\def_new:Npn \glet_new:cN {\exp_args:Nc \glet_new:NN}
-\def_new:Npn \glet_new:Nc {\exp_args:NNc \glet_new:NN}
-\def_new:Npn \glet_new:cc {\exp_args:Ncc \glet_new:NN}
+\cs_new_nopar:Npn \prg_do_nothing: {}
% \end{macrocode}
% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
%
%
-% \begin{macro}{\def:No}
-% \begin{macro}{\gdef:No}
-% |\def:No| expands its second argument one time before making
-% the definition.
+% \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_set:Npn \cs_get_arg_count_from_signature:N #1{
+ \cs_split_function:NN #1 \cs_get_arg_count_from_signature_aux:nnN
+}
+\cs_set:Npn \cs_get_arg_count_from_signature_aux:nnN #1#2#3{
+ \if_predicate:w #3 % \bool_if:NTF here
+ \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_nil
+ }
+ {-1}
+}
+\cs_set:Npn \cs_get_arg_count_from_signature_auxii:w #1#2\q_nil{#1}
+% \end{macrocode}
+% A variant form we need right away.
% \begin{macrocode}
-\def_new:Npn \def:No{\exp_args:NNo\def:Npn}
-\def_new:Npn \gdef:No {\exp_args:NNo\gdef:Npn}
+\cs_set_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}{\def_test_function_aux:Nnnn}
-% \begin{macro}{\def_test_function_aux:Nnnx}
-% \begin{macro}{\def_test_function:npn}
-% \begin{macro}{\def_test_function:npx}
-% \begin{macro}{\def_long_test_function:npn}
-% \begin{macro}{\def_long_test_function:npx}
-% \begin{macro}{\def_test_function_new:npn}
-% \begin{macro}{\def_test_function_new:npx}
-% \begin{macro}{\def_long_test_function_new:npn}
-% \begin{macro}{\def_long_test_function_new:npx}
-% We will often be defining several almost identical TF, T and F
-% type functions so it makes sense for us to define a small function
-% that will do this for us so that we are less likely to introduce
-% typos (it does tend to happen). By doing it in two steps as below
-% we can still retain a simple interface where you write the \TeX\
-% parameters as usual. Just don't do it when you're already within a
-% conditional!
%
-% I think the ways of exiting conditionals below are as fast as they
-% get. Using |\reverse_if:N| instead of |\else:| didn't give any
-% difference I could measure.
+%
+%
+% \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}
-\def_long_new:Npn \def_test_function_aux:Nnnn #1#2#3#4{
- #1 {#2TF} #3 {#4
- \exp_after:NN\use_arg_i:nn\else:\exp_after:NN\use_arg_ii:nn\fi:}
- #1 {#2FT} #3 {#4
- \exp_after:NN\use_arg_ii:nn\else:\exp_after:NN\use_arg_i:nn\fi:}
- #1 {#2T} #3 {#4
- \else:\exp_after:NN\use_none:nn\fi:\use_arg_i:n}
- #1 {#2F} #3 {#4
- \exp_after:NN\use_none:nn\fi:\use_arg_i:n}}
-\def_long_new:Npn \def_test_function_aux:Nnnx #1#2#3#4{
- #1 {#2TF} #3 {#4
- \exp_not:n{\exp_after:NN\use_arg_i:nn\else:\exp_after:NN\use_arg_ii:nn\fi:}}
- #1 {#2FT} #3 {#4
- \exp_not:n{\exp_after:NN\use_arg_ii:nn\else:\exp_after:NN\use_arg_i:nn\fi:}}
- #1 {#2T} #3 {#4
- \exp_not:n{\else:\exp_after:NN\use_none:nn\fi:\use_arg_i:n}}
- #1 {#2F} #3 {#4
- \exp_not:n{\exp_after:NN\use_none:nn\fi:\use_arg_i:n}}}
-\def_long_new:Npn \def_test_function:npn #1#2#{
- \def_test_function_aux:Nnnn \def:cpn {#1}{#2}
-}
-\def_long_new:Npn \def_test_function:npx #1#2#{
- \def_test_function_aux:Nnnx \def:cpx {#1}{#2}
-}
-\def_long_new:Npn \def_long_test_function:npn #1#2#{
- \def_test_function_aux:Nnnn \def_long:cpn {#1}{#2}
-}
-\def_long_new:Npn \def_long_test_function:npx #1#2#{
- \def_test_function_aux:Nnnx \def_long:cpx {#1}{#2}
-}
-\def_long_new:Npn \def_test_function_new:npn #1#2#{
- \def_test_function_aux:Nnnn \def_new:cpn {#1}{#2}
+\cs_set:Npn \cs_generate_from_arg_count:NNnn #1#2#3#4{
+ \tex_ifcase:D \etex_numexpr:D #3\tex_relax:D
+ \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 % to remove replacement text
+ }
+ \fi:
+ {#4}
}
-\def_long_new:Npn \def_long_test_function_new:npn #1#2#{
- \def_test_function_aux:Nnnn \def_long_new:cpn {#1}{#2}
+% \end{macrocode}
+% A variant form we need right away.
+% \begin{macrocode}
+\cs_set_nopar:Npn \cs_generate_from_arg_count:cNnn {
+ \exp_args:Nc \cs_generate_from_arg_count:NNnn
}
-\def_long_new:Npn \def_test_function_new:npx #1#2#{
- \def_test_function_aux:Nnnx \def_new:cpx {#1}{#2}
+% \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_set:Npn \cs_generate_from_arg_count_error_msg:Nn #1#2 {
+ \msg_kernel_bug:x {
+ You're~ trying~ to~ define~ the~ command~ `\token_to_str:N #1'~
+ with~ \use:n{\tex_the:D\etex_numexpr:D #2\tex_relax:D} ~
+ arguments~ but~ I~ only~ allow~ 0-9~arguments.~Perhaps~you~
+ forgot~to~use~a~colon~in~the~function~name?~
+ I~ can~ probably~ not~ help~ you~ here
+ }
}
-\def_long_new:Npn \def_long_test_function_new:npx #1#2#{
- \def_test_function_aux:Nnnx \def_long_new:cpx {#1}{#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}|, 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}
@@ -2317,86 +3012,50 @@
% \end{macro}
% \end{macro}
% \end{macro}
-%
-%
-% \subsubsection{Further checking}
-%
-% \begin{macro}{\cs_if_free:NTF}
-% \begin{macro}{\cs_if_free:NT}
-% \begin{macro}{\cs_if_free:NF}
-% The old |\@ifundefined| of \LaTeX{} 2.09 is re-implemented in the
-% function |\cs_free:cTF|, again in a way that |\else:| and |\fi:|
-% are removed. In this implementation this is absolutely
-% necessary because functions inside the conditional parts expect
-% to read further input from outside the conditional. Actually,
-% the first part of the code below is more general, since it checks
-% \m{csnames} directly and therefore allows both |\scan_stop:| and
-% |\c_undefined|.
-% \begin{macrocode}
-\def_long_test_function_new:npn {cs_if_free:N}#1{\if:w\cs_if_free_p:N #1}
-\let:NN \cs_free:NTF \cs_if_free:NTF
-\let:NN \cs_free:NT \cs_if_free:NT
-\let:NN \cs_free:NF \cs_if_free:NF
-% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
-%
-% \begin{macro}{\cs_if_free:cTF}
-% \begin{macro}{\cs_if_free:cT}
-% \begin{macro}{\cs_if_free:cF}
-% We have to implement the |c| variants `by hand' because a different
-% test is necessary and I don't want the overhead for the test with
-% |\if:w|. What a mistake Don made by making this a
-% feature of |\cs:w|. If I'm not totally mistaken this
-% feature alone has cost him more than 600\$ for bug-checks.
-% \begin{macrocode}
-\def_long_test_function_new:npn {cs_if_free:c}#1{
- \exp_after:NN \if_meaning:NN \cs:w#1\cs_end: \scan_stop:}
-\let:NN \cs_free:cTF \cs_if_free:cTF
-\let:NN \cs_free:cT \cs_if_free:cT
-\let:NN \cs_free:cF \cs_if_free:cF
-% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
-% \begin{macro}{\cs_if_really_free:cTF}
-% \begin{macro}{\cs_if_really_free:cT}
-% \begin{macro}{\cs_if_really_free:cF}
-% These versions are for special control sequences that can only be
-% formed through |\cs:w ... \cs_end:|. They do not turn the control
-% sequence formed into |\scan_stop:|.
+% \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{macro}{\cs_gnew:Nn}
+% \begin{macro}{\cs_gnew:Nx}
+% \begin{macro}{\cs_gnew_nopar:Nn}
+% \begin{macro}{\cs_gnew_nopar:Nx}
+% \begin{macro}{\cs_gnew_protected:Nn}
+% \begin{macro}{\cs_gnew_protected:Nx}
+% \begin{macro}{\cs_gnew_protected_nopar:Nn}
+% \begin{macro}{\cs_gnew_protected_nopar:Nx}
% \begin{macrocode}
-\def_long_test_function_new:npn {cs_if_really_free:c}#1{
- \reverse_if:N\if_cs_exist:w #1\cs_end:}
-\let:NN \cs_really_free:cTF \cs_if_really_free:cTF
-\let:NN \cs_really_free:cT \cs_if_really_free:cT
-\let:NN \cs_really_free:cF \cs_if_really_free:cF
+\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_tmp:w {gnew}{Nn}{Npn}
+\cs_tmp:w {gnew}{Nx}{Npx}
+\cs_tmp:w {gnew_nopar}{Nn}{Npn}
+\cs_tmp:w {gnew_nopar}{Nx}{Npx}
+\cs_tmp:w {gnew_protected}{Nn}{Npn}
+\cs_tmp:w {gnew_protected}{Nx}{Npx}
+\cs_tmp:w {gnew_protected_nopar}{Nn}{Npn}
+\cs_tmp:w {gnew_protected_nopar}{Nx}{Npx}
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
-%
-% \begin{macro}{\cs_if_exist:NTF}
-% \begin{macro}{\cs_if_exist:NT}
-% \begin{macro}{\cs_if_exist:NF}
-% \begin{macro}{\cs_if_exist:cTF}
-% \begin{macro}{\cs_if_exist:cT}
-% \begin{macro}{\cs_if_exist:cF}
-% \begin{macro}{\cs_if_really_exist:cTF}
-% \begin{macro}{\cs_if_really_exist:cT}
-% \begin{macro}{\cs_if_really_exist:cF}
-% Now the same functions but with reverse logic: test if the control
-% sequence exists.
-% \begin{macrocode}
-\def_long_test_function_new:npn {cs_if_exist:N}#1{\if:w\cs_if_exist_p:N #1}
-\def_long_test_function_new:npn {cs_if_exist:c}#1{
- \exp_after:NN\reverse_if:N
- \exp_after:NN \if_meaning:NN \cs:w#1\cs_end: \scan_stop:}
-\def_long_test_function_new:npn {cs_if_really_exist:c}#1{
- \if_cs_exist:w #1\cs_end:}
-% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
@@ -2406,93 +3065,67 @@
% \end{macro}
% \end{macro}
% \end{macro}
-%
-%
-% \subsubsection{Freeing memory}
-%
-% \begin{macro}{\cs_gundefine:N }
-% 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}
-\def_new:Npn \cs_gundefine:N #1{\glet:NN #1\c_undefined}
-% \end{macrocode}
% \end{macro}
-%
-%
-% \subsubsection{Engine specific definitions}
-%
-% \begin{macro}{\engine_if_aleph:TF}
-% In some cases it will be useful to know which engine we're running.
-% \begin{macrocode}
-\def_test_function_new:npn {engine_if_aleph:}{\if_cs_exist:N \aleph_textdir:D}
-% \end{macrocode}
% \end{macro}
-%
-%
-%
-% \subsubsection{Selecting tokens}
-%
-% \begin{macro}{\use_arg_i:n}
-% This macro grabs its argument and returns it back to the input
-% (with outer braces removed).
-% \begin{macrocode}
-%\def_long_new:Npn \use_arg_i:n #1{#1}% moved earlier
-% \end{macrocode}
+% \end{macro}
% \end{macro}
%
-% \begin{macro}{\use:c}
-% \begin{macro}{\cs_use:c}
-% \begin{macro}{\use:cc}
-% This macro grabs its argument and returns a csname from it.
+% 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}
-\def_new:Npn \use:c #1{\cs:w #1\cs_end:}
-\def_new:Npn \cs_use:c #1 { \cs:w#1\cs_end: }
+\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}
-% THE NAME IS COMPLETELY WRONG!!!!!
-% Morten says: Perhaps this is really |\exp_args:cc| instead?
+% \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}
-\def_new:Npn \use:cc #1#2
- {\cs:w #1\exp_after:NN\cs_end:\cs:w #2\cs_end:}
+\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}
-%
-% \begin{macro}{\use_arg_i:nn}
-% \begin{macro}{\use_arg_ii:nn}
-% These macros are needed to provide functions with true and false
-% cases, as introduced by Michael some time ago. By using
-% |\exp_after:NN| |\use_arg_i:nn | |\else:| constructions it
-% is possible to write code where the true or false case is able to
-% access the following tokens from the input stream, which is not
-% possible if the |\c_true| syntax is used.
-% \begin{macrocode}
-\def_long_new:Npn \use_arg_i:nn #1#2{#1}
-\def_long_new:Npn \use_arg_ii:nn #1#2{#2}
-% \end{macrocode}
% \end{macro}
% \end{macro}
-%
-%
-%
-% \begin{macro}{\use_arg_i:nnn}
-% \begin{macro}{\use_arg_ii:nnn}
-% \begin{macro}{\use_arg_iii:nnn}
-% \begin{macro}{\use_arg_i:nnnn}
-% \begin{macro}{\use_arg_ii:nnnn}
-% \begin{macro}{\use_arg_iii:nnnn}
-% \begin{macro}{\use_arg_iv:nnnn}
-% We also need something for picking up arguments from a longer
-% list.
-% \begin{macrocode}
-\def_long_new:NNn \use_arg_i:nnn 3{#1}
-\def_long_new:NNn \use_arg_ii:nnn 3{#2}
-\def_long_new:NNn \use_arg_iii:nnn 3{#3}
-\def_long_new:NNn \use_arg_i:nnnn 4{#1}
-\def_long_new:NNn \use_arg_ii:nnnn 4{#2}
-\def_long_new:NNn \use_arg_iii:nnnn 4{#3}
-\def_long_new:NNn \use_arg_iv:nnnn 4{#4}
-% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
@@ -2500,84 +3133,49 @@
% \end{macro}
% \end{macro}
% \end{macro}
-%
-% \begin{macro}{\use_arg_i_ii:nn}
-% And a function for grabbing two arguments and returning them
-% again.
-% \begin{macrocode}
-\def_long_new:NNn\use_arg_i_ii:nn 2{#1#2}
-% \end{macrocode}
% \end{macro}
-%
-% \begin{macro}{\use_none_delimit_by_q_nil:w}
-% \begin{macro}{\use_none_delimit_by_q_stop:w}
-% Functions that gobble everything until they see either |\q_nil| or
-% |\q_stop| resp.
-% \begin{macrocode}
-\def_long_new:Npn \use_none_delimit_by_q_nil:w #1\q_nil{}
-\def_long_new:Npn \use_none_delimit_by_q_stop:w #1\q_stop{}
-% \end{macrocode}
% \end{macro}
% \end{macro}
-%
-% \begin{macro}{\use_arg_i_delimit_by_q_nil:nw}
-% \begin{macro}{\use_arg_i_delimit_by_q_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}
-\def_long_new:Npn \use_arg_i_delimit_by_q_nil:nw #1#2\q_nil{#1}
-\def_long_new:Npn \use_arg_i_delimit_by_q_stop:nw #1#2\q_stop{#1}
-% \end{macrocode}
-% \end{macro}
% \end{macro}
%
-%
-% \begin{macro}{\use_arg_i_after_fi:nw}
-% \begin{macro}{\use_arg_i_after_else:nw}
-% \begin{macro}{\use_arg_i_after_or:nw}
-% \begin{macro}{\use_arg_i_after_or:nw}
-% Returns the first argument after ending the conditional.
+% \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{macro}{\cs_gnew:cn}
+% \begin{macro}{\cs_gnew:cx}
+% \begin{macro}{\cs_gnew_nopar:cn}
+% \begin{macro}{\cs_gnew_nopar:cx}
+% \begin{macro}{\cs_gnew_protected:cn}
+% \begin{macro}{\cs_gnew_protected:cx}
+% \begin{macro}{\cs_gnew_protected_nopar:cn}
+% \begin{macro}{\cs_gnew_protected_nopar:cx}
% \begin{macrocode}
-\def_long_new:Npn \use_arg_i_after_fi:nw #1\fi:{\fi: #1}
-\def_long_new:Npn \use_arg_i_after_else:nw #1\else:#2\fi:{\fi: #1}
-\def_long_new:Npn \use_arg_i_after_or:nw #1\or: #2\fi: {\fi:#1}
-\def_long_new:Npn \use_arg_i_after_orelse:nw #1 #2#3\fi: {\fi:#1}
+\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}
+\cs_tmp:w {gnew}{cn}{Npn}
+\cs_tmp:w {gnew}{cx}{Npx}
+\cs_tmp:w {gnew_nopar}{cn}{Npn}
+\cs_tmp:w {gnew_nopar}{cx}{Npx}
+\cs_tmp:w {gnew_protected}{cn}{Npn}
+\cs_tmp:w {gnew_protected}{cx}{Npx}
+\cs_tmp:w {gnew_protected_nopar}{cn}{Npn}
+\cs_tmp:w {gnew_protected_nopar}{cx}{Npx}
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
-%
-% \subsubsection{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}
-%\def_long_new:NNn \use_none:n 1{}% moved earlier
-\def_long_new:NNn \use_none:nn 2{}
-\def_long_new:NNn \use_none:nnn 3{}
-\def_long_new:NNn \use_none:nnnn 4{}
-\def_long_new:NNn \use_none:nnnnn 5{}
-\def_long_new:NNn \use_none:nnnnnn 6{}
-\def_long_new:NNn \use_none:nnnnnnn 7{}
-\def_long_new:NNn \use_none:nnnnnnnn 8{}
-\def_long_new:NNn \use_none:nnnnnnnnn 9{}
-% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
@@ -2587,240 +3185,100 @@
% \end{macro}
% \end{macro}
% \end{macro}
-%
-%
-% \subsubsection{Scratch functions}
-%
-% \begin{macro}{\gtmp:w}
-% This function is for global scratch definitions that are used
-% immediately afterwards. It should be used when we need a function
-% that operates on input, i.e.\ has arguments. If we want to save
-% only some tokens for later use, token-list scratch variables
-% should be used.
-% \begin{macrocode}
-\def_new:Npn \gtmp:w {}
-% \end{macrocode}
% \end{macro}
-%
-% \begin{macro}{\tmp:w}
-% This is a local version of the previous function.
-% \begin{macrocode}
-\def_new:Npn \tmp:w {}
-% \end{macrocode}
% \end{macro}
-%
-% \begin{macro}{\use_noop:}
-% I don't think this function belongs here, but one place is as
-% good as any other. I want to use this function when I want to
-% express `no operation'.
-% \begin{macrocode}
-\def_new:Npn \use_noop: {}
-% \end{macrocode}
% \end{macro}
%
-% \subsubsection{Strings and input stream token lists}
-%
-% \begin{macro}{\cs_to_str:N}
-% This converts a control sequence into the character string of its
-% name, removing the leading escape character.
-% \begin{macrocode}
-\def_new:Npn \cs_to_str:N {\exp_after:NN\use_none:n \token_to_string:N}
-% \end{macrocode}
-% \end{macro}
%
%
%
%
%
-% \begin{macro}{\cs_if_eq:NNTF}
-% \begin{macro}{\cs_if_eq:NNT}
-% \begin{macro}{\cs_if_eq:NNF}
-% \begin{macro}{\cs_if_eq:cNTF}
-% \begin{macro}{\cs_if_eq:cNT}
-% \begin{macro}{\cs_if_eq:cNF}
-% \begin{macro}{\cs_if_eq:NcTF}
-% \begin{macro}{\cs_if_eq:NcT}
-% \begin{macro}{\cs_if_eq:NcF}
-% \begin{macro}{\cs_if_eq:ccTF}
-% \begin{macro}{\cs_if_eq:ccT}
-% \begin{macro}{\cs_if_eq:ccF}
+% \begin{macro}{\cs_if_eq_p:NN,\cs_if_eq_p:cN,\cs_if_eq_p:Nc,\cs_if_eq_p:cc}
+% \begin{macro}[TF]{\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}
-\def_test_function_new:npn {cs_if_eq:NN} #1#2{\if_meaning:NN #1#2}
-\def_new:Npn \cs_if_eq:cNTF {\exp_args:Nc \cs_if_eq:NNTF}
-\def_new:Npn \cs_if_eq:cNT {\exp_args:Nc \cs_if_eq:NNT}
-\def_new:Npn \cs_if_eq:cNF {\exp_args:Nc \cs_if_eq:NNF}
-\def_new:Npn \cs_if_eq:NcTF {\exp_args:NNc \cs_if_eq:NNTF}
-\def_new:Npn \cs_if_eq:NcT {\exp_args:NNc \cs_if_eq:NNT}
-\def_new:Npn \cs_if_eq:NcF {\exp_args:NNc \cs_if_eq:NNF}
-\def_new:Npn \cs_if_eq:ccTF {\exp_args:Ncc \cs_if_eq:NNTF}
-\def_new:Npn \cs_if_eq:ccT {\exp_args:Ncc \cs_if_eq:NNT}
-\def_new:Npn \cs_if_eq:ccF {\exp_args:Ncc \cs_if_eq:NNF}
+\prg_set_conditional:Npnn \cs_if_eq:NN #1#2{p,TF,T,F}{
+ \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}
% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
%
% Finally some code that is needed as we do not distribute the file
% module at the moment (so we simply define the needed function via an
% existing \LaTeX{} command) and some other stuff which was set up
% elsewhere, in undistributed modules.
% \begin{macrocode}
-\def_new:Npn\file_not_found:nTF #1#2#3{\IfFileExists{#1}{#3}{#2}}
+\cs_new_nopar:Npn\file_not_found:nTF #1#2#3{\IfFileExists{#1}{#3}{#2}}
% \end{macrocode}
%
%
-% \subsubsection{Predicates and conditionals}
-% \label{sec:predicates}
-%
-% \LaTeX3 has three concepts for conditional flow processing:
-% \begin{enumerate}
-%
-% \item
-% Functions that carry out a test an then execute, depending on its
-% result, either the code supplied in the \m{true arg} or the \m{false
-% arg}. These arguments are denoted with "T" and "F" repectively. An
-% example would be
-% \begin{quote}
-% "\cs_free:cTF{abc}{...}{...}"
-% \end{quote}
-% a function that will turn the first argument into a control sequence
-% (since its 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).
-%
-% \item
-% Functions that return a special type of boolean value which can be
-% tested by the function "\if:w". All functions of this type
-% have names that end with "_p" in the description part. For example
-% \begin{quote}
-% "\cs_free_p:N"
-% \end{quote}
-% would be a predicate function for the same type of test as the
-% function above. It would return `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:w \cs_free_p:N \l_foo_bar ... \else: ... \fi:"
-% \end{quote}
-%
-% \item
-% Actually there is a third one, namely the original concept used in
-% plain \TeX{}. This belongs to the second form but needs further
-% thoughts.
-% \end{enumerate}
-%
-% Important to note is that conditionals with \m{true code} and/or
-% \m{false code} are always defined in a way that the code of the chosen
-% alternative can operate on following tokens in the input stream while
-% the predicate implementations always have an "\else:" or "\fi:"
-% interfering. This can be important in scanner implementations.
%
+% \begin{macro}{\prg_set_eq_conditional:NNn,\prg_new_eq_conditional:NNn}
+% \begin{macrocode}
+\cs_set:Npn \prg_set_eq_conditional:NNn #1#2#3 {
+ \prg_set_eq_conditional_aux:NNNn \cs_set_eq:cc #1#2 {#3}
+}
+\cs_set:Npn \prg_new_eq_conditional:NNn #1#2#3 {
+ \prg_set_eq_conditional_aux:NNNn \cs_new_eq:cc #1#2 {#3}
+}
+% \end{macrocode}
+% \begin{macro}[aux]{\prg_set_eq_conditional_aux:NNNn,
+% \prg_set_eq_conditional_aux:NNNw}
+% \begin{macrocode}
+\cs_set: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: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:#2TF}
+\cs_set:Npn \prg_conditional_form_T:nnn #1#2#3 {#1:#2T}
+\cs_set:Npn \prg_conditional_form_F:nnn #1#2#3 {#1:#2F}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
%
% \begin{macrocode}
%</initex|package>
+% \end{macrocode}
+%
+% \begin{macrocode}
%<*showmemory>
\showMemUsage
%</showmemory>
% \end{macrocode}
%
-% \endinput
-%
-% $Log$
-% Revision 1.38 2006/08/06 17:05:25 morten
-% Make \chk_new_cs:N bulletproof
-%
-% Revision 1.37 2006/07/30 14:37:47 morten
-% Added \str_if_eq_var_p:nf
-%
-% Revision 1.36 2006/07/23 13:43:21 morten
-% Removed extra occurrence of \str_if_eq_p:nn
-%
-% Revision 1.35 2006/07/17 22:25:31 morten
-% Fix logic of \chk_new_cs:N and rename \cs_if_eq_p:NN to
-% \cs_if_eq_name_p:NN because it is not their meaning but their names
-% which are compared.
-%
-% Revision 1.34 2006/07/08 22:46:17 morten
-% Rearranged some code and added complete set of \use_none:<args>
-% functions.
-%
-% Revision 1.33 2006/07/06 14:53:56 morten
-% Added \def:NNn functions, reorganized code and much much more.
-%
-% Revision 1.32 2006/06/03 17:14:43 morten
-% Added more \use_arg_... functions.
-%
-% Revision 1.31 2006/03/20 18:26:33 braams
-% Updated the copyright notice (2006) and demoted all implementation
-% sections to subsections and so on to clean up the toc for source3.tex
-%
-% Revision 1.30 2006/01/22 19:35:46 morten
-% Changed \use_none:nnn to gobble all tokens in one go and added
-% \use_arg_i_ii:nn for l3keyval.
-%
-% Revision 1.29 2006/01/16 09:47:49 morten
-% Fixed deleted brace
-%
-% Revision 1.28 2006/01/15 19:08:28 morten
-% Fixed typos in some \if names
-%
-% Revision 1.27 2006/01/04 01:29:36 morten
-% Changed "robust" to "protected".
+% \end{implementation}
%
-% Revision 1.26 2005/12/27 09:53:55 morten
-% Fixed some names, added a few more \use_... functions, changed RCS
-% information retrieval
-%
-% Revision 1.25 2005/12/23 11:16:15 morten
-% *** empty log message ***
-%
-% Revision 1.24 2005/12/02 15:21:55 morten
-% Fixed minor typo
-%
-% Revision 1.23 2005/11/20 07:10:03 morten
-% Added a few missing functions. New function type
-% \def_test_function:npn to help define TF-type functions.
-%
-% Revision 1.22 2005/11/08 04:16:17 morten
-% Fixed typo.
-%
-% Revision 1.21 2005/10/27 22:35:13 morten
-% Cleaned up a bit and moved some code to l3num.
-%
-% Revision 1.20 2005/07/12 16:10:24 morten
-% Allow \cs_if_eq_p:NN to accept \par. (Yes, real life experience)
-%
-% Revision 1.19 2005/04/06 21:34:55 morten
-% Added more functions. Moved \engine_aleph:TF from l3prg
-%
-% Revision 1.18 2005/03/25 23:52:24 braams
-% The definition of \next needs to be seen at initex time,
-% not at typesetting time
-%
-% Revision 1.17 2005/03/22 23:28:46 morten
-% Moved some code to l3prg, removed obsolete code, cleaned up documentation.
-%
-% Revision 1.16 2005/03/16 22:31:44 braams
-% Changed definition of \c_zero and \c_minus_one
-%
-% Revision 1.15 2005/03/15 23:16:27 braams
-% Some tweaking with the docstrip guards to get the documentation to
-% come out right.
-%
-% Revision 1.14 2005/03/15 22:50:00 braams
-% Made loadable by initex as the second file
-%
-% Revision 1.13 2005/03/11 21:32:21 braams
-% Fixed the use of RCS information;
-% moved \RequirePackage after \StopEventually
+% \PrintIndex
%
+% \endinput
diff --git a/Master/texmf-dist/source/latex/expl3/l3box.dtx b/Master/texmf-dist/source/latex/expl3/l3box.dtx
index c697225b8b3..bf619435d63 100644
--- a/Master/texmf-dist/source/latex/expl3/l3box.dtx
+++ b/Master/texmf-dist/source/latex/expl3/l3box.dtx
@@ -1,5 +1,5 @@
% \iffalse
-%% File: l3box.dtx Copyright (C) 2005-2007 LaTeX3 project
+%% File: l3box.dtx Copyright (C) 2005-2009 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
@@ -17,7 +17,7 @@
%%
%% The development version of the bundle can be found at
%%
-%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/
+%% http://www.latex-project.org/svnroot/experimental/trunk/
%%
%% for those people who are interested.
%%
@@ -36,7 +36,7 @@
\RequirePackage{l3names}
%</driver|package>
%\fi
-\GetIdInfo$Id: l3box.dtx 718 2007-12-16 22:59:58Z morten $
+\GetIdInfo$Id: l3box.dtx 1375 2009-06-01 12:28:52Z joseph $
{L3 Experimental Box module}
%\iffalse
%<*driver>
@@ -44,9 +44,9 @@
\ProvidesFile{\filename.\filenameext}
[\filedate\space v\fileversion\space\filedescription]
%\iffalse
-\documentclass{l3doc}
+\documentclass[full]{l3doc}
\begin{document}
-\DocInput{\filename.\filenameext}
+\DocInput{l3box.dtx}
\end{document}
%</driver>
% \fi
@@ -60,20 +60,19 @@
% \date{\filedate}
% \maketitle
%
-% \section{Boxes}
-%
+% \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_|.
%
%
-% \subsection{Generic functions}
+% \section{Generic functions}
%
% \begin{function}{%
% \box_new:N |
% \box_new:c |
-% \box_new_l:N
+%^^A \box_new_l:N
% }
% \begin{syntax}
% "\box_new:N" <box>
@@ -103,18 +102,34 @@
% \end{texnote}
% \end{function}
%
+% \begin{function}{\box_if_horizontal_p:N |
+% \box_if_horizontal_p:c |
+% \box_if_horizontal:N / (TF) |
+% \box_if_horizontal:c / (TF) }
+% \begin{syntax}
+% "\box_if_horizontal:NTF" <box> \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if <box> is an horizontal box and executes <code> accordingly.
+% \end{function}
+%
+% \begin{function}{\box_if_vertical_p:N |
+% \box_if_vertical_p:c |
+% \box_if_vertical:N / (TF) |
+% \box_if_vertical:c / (TF) }
+% \begin{syntax}
+% "\box_if_vertical:NTF" <box> \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if <box> is a vertical box and executes <code> accordingly.
+% \end{function}
+%
% \begin{function}{%
% \box_if_empty_p:N |
% \box_if_empty_p:c |
-% \box_if_empty:NTF |
-% \box_if_empty:cTF |
-% \box_if_empty:NT |
-% \box_if_empty:cT |
-% \box_if_empty:NF |
-% \box_if_empty:cF |
+% \box_if_empty:N / (TF) |
+% \box_if_empty:c / (TF) |
% }
% \begin{syntax}
-% "\box_if_empty:NTF" <box> "{"\m{true code}"}" "{"\m{false code}"}"
+% "\box_if_empty:NTF" <box> \Arg{true code} \Arg{false code}
% \end{syntax}
% Tests if <box> is empty (void) and executes "code" according to the
% test outcome.
@@ -160,8 +175,8 @@
% \begin{syntax}
% "\box_set_to_last:N" <box>
% \end{syntax}
-% Sets <box> equal to the previous box |\R_last_box| and removes
-% |\R_last_box| from the current list (unless in outer vertical
+% Sets <box> equal to the previous box |\l_last_box| and removes
+% |\l_last_box| from the current list (unless in outer vertical
% or math mode).
% \end{function}
%
@@ -172,7 +187,7 @@
% \box_move_down:nn |
% }
% \begin{syntax}
-% "\box_move_left:nn" "{"<dimen>"}" "{"<box function>"}"
+% "\box_move_left:nn" \Arg{dimen} \Arg{box function}
% \end{syntax}
% Moves <box function> <dimen> in the direction specified. <box
% function> is either an operation on a box such as "\box_use:N" or a
@@ -258,23 +273,25 @@
%
%
% \begin{variable}{%
-% \R_last_box |
+% \l_last_box |
% }
% \begin{syntax}
% \end{syntax}
-% "\R_last_box" is a read-only box register. You can set other
-% boxes to this box, which will then be removed from the current
-% list.
+% "\l_last_box" is more or less a read-only box register managed by the
+% engine. It denotes the last box on the current list if there is one,
+% otherwise it is void. You can set other
+% boxes to this box, with the result that the last box on the current list is
+% removed at the same time (so it is with variable with side-effects).
% \end{variable}
%
%
-% \subsection{Horizontal mode}
+% \section{Horizontal mode}
%
% \begin{function}{%
% \hbox:n |
% }
% \begin{syntax}
-% "\hbox:n" "{"<contents>"}"
+% "\hbox:n" \Arg{contents}
% \end{syntax}
% Places a "hbox" of natural size.
% \end{function}
@@ -286,7 +303,7 @@
% \hbox_gset:cn |
% }
% \begin{syntax}
-% "\hbox_set:Nn" <box> "{"\m{contents}"}"
+% "\hbox_set:Nn" <box> \Arg{contents}
% \end{syntax}
% Sets <box> to be a vertical mode box containing \m{contents}. It has
% it's natural size. "\hbox_gset:Nn" does it globally.
@@ -300,7 +317,7 @@
% \hbox_gset_to_wd:cnn |
% }
% \begin{syntax}
-% "\hbox_set_to_wd:Nnn" <box> "{"\m{dimen}"}" "{"\m{contents}"}"
+% "\hbox_set_to_wd:Nnn" <box> \Arg{dimen} \Arg{contents}
% \end{syntax}
% Sets <box> to contain \m{contents} and have width <dimen>.
% "\hbox_gset_to_wd:Nn" does it globally.
@@ -309,11 +326,14 @@
%
% \begin{function}{%
% \hbox_to_wd:nn |
+% \hbox_to_zero:n |
% }
% \begin{syntax}
-% "\hbox_to_wd:nn" "{"<dimen>"}" <contents>
+% "\hbox_to_wd:nn" \Arg{dimen} <contents>
+% "\hbox_to_zero:n" <contents>
% \end{syntax}
-% Places a <box> of width <dimen> containing <contents>.
+% Places a <box> of width <dimen> containing <contents>. "\hbox_to_zero:n"
+% is a shorthand for a width of zero.
% \end{function}
%
%
@@ -336,7 +356,9 @@
%
% \begin{function}{%
% \hbox_unpack:N |
+% \hbox_unpack:c |
% \hbox_unpack_clear:N |
+% \hbox_unpack_clear:c |
% }
% \begin{syntax}
% "\hbox_unpack:N" <box>
@@ -352,7 +374,17 @@
%
%
%
-% \subsection{Vertical mode}
+% \section{Vertical mode}
+%
+% \begin{function}{%
+% \vbox:n |
+% }
+% \begin{syntax}
+% "\vbox:n" \Arg{contents}
+% \end{syntax}
+% Places a "vbox" of natural size with baseline equal to the baseline
+% of the last line in the box.
+% \end{function}
%
% \begin{function}{%
% \vbox_set:Nn |
@@ -361,10 +393,10 @@
% \vbox_gset:cn |
% }
% \begin{syntax}
-% "\vbox_set:Nn" <box> "{"\m{contents}"}"
+% "\vbox_set:Nn" <box> \Arg{contents}
% \end{syntax}
% Sets <box> to be a vertical mode box containing \m{contents}. It has
-% it's natural size. "\vbox_gset:Nn" does it globally.
+% its natural size. "\vbox_gset:Nn" does it globally.
% \end{function}
%
%
@@ -376,7 +408,7 @@
% \vbox_gset_to_ht:ccn |
% }
% \begin{syntax}
-% "\vbox_set_to_ht:Nnn" <box> "{"\m{dimen}"}" "{"\m{contents}"}"
+% "\vbox_set_to_ht:Nnn" <box> \Arg{dimen} \Arg{contents}
% \end{syntax}
% Sets <box> to contain \m{contents} and have total height <dimen>.
% "\vbox_gset_to_ht:Nn" does it globally.
@@ -401,7 +433,7 @@
% \vbox_set_split_to_ht:NNn |
% }
% \begin{syntax}
-% "\vbox_set_split_to_ht:NNn" <box1> <box2> "{"<dimen>"}"
+% "\vbox_set_split_to_ht:NNn" <box1> <box2> \Arg{dimen}
% \end{syntax}
% Sets <box1> to contain the top <dimen> part of <box2>.
% \begin{texnote}
@@ -410,21 +442,11 @@
% \end{function}
%
% \begin{function}{%
-% \vbox:n |
-% }
-% \begin{syntax}
-% "\vbox:n" "{"<contents>"}"
-% \end{syntax}
-% Places a "vbox" of natural size with baseline equal to the baseline
-% of the last line in the box.
-% \end{function}
-%
-% \begin{function}{%
% \vbox_to_ht:nn |
% \vbox_to_zero:n |
% }
% \begin{syntax}
-% "\vbox_to_ht:nn" "{"<dimen>"}" <contents> \\
+% "\vbox_to_ht:nn" \Arg{dimen} <contents> \\
% "\vbox_to_zero:n" <contents>
% \end{syntax}
% Places a <box> of size <dimen> containing <contents>.
@@ -433,7 +455,9 @@
%
% \begin{function}{%
% \vbox_unpack:N |
+% \vbox_unpack:c |
% \vbox_unpack_clear:N |
+% \vbox_unpack_clear:c |
% }
% \begin{syntax}
% "\vbox_unpack:N" <box>
@@ -446,19 +470,22 @@
% \end{function}
%
%
-% \StopEventually{}
+% \end{documentation}
%
+% \begin{implementation}
%
%
-% \subsection{The Implementation}
+%
+% \section{\pkg{l3box} implementation}
%
%
% Announce and ensure that the required packages are loaded.
% \begin{macrocode}
-%<package>\ProvidesExplPackage
-%<package> {\filename}{\filedate}{\fileversion}{\filedescription}
-%<package&!check>\RequirePackage{l3prg,l3token}\par
-%<package&check>\RequirePackage{l3chk}\par
+%<*package>
+\ProvidesExplPackage
+ {\filename}{\filedate}{\fileversion}{\filedescription}
+\package_check_loaded_expl:
+%</package>
%<*initex|package>
% \end{macrocode}
%
@@ -466,11 +493,10 @@
% comment it very extensively.
%
%
-% \subsubsection{Generic boxes}
+% \subsection{Generic boxes}
%
-% \begin{macro}{\box_new:N}
-% \begin{macro}{\box_new_l:N}
-% \begin{macro}{\box_new:c}
+% \begin{macro}{\box_new:N,\box_new:c}
+%^^A \begin{macro}{\box_new_l:N}
% Defining a new \m{box} register.
% \begin{macrocode}
%<*initex>
@@ -480,19 +506,26 @@
% shouldn't be allocated\dots
% \begin{macrocode}
\seq_put_right:Nn \g_box_allocation_seq {255}
-\def_new:Npn \box_new:N #1 {\alloc_reg:NnNN g {box} \tex_mathchardef:D #1}
-\def_new:Npn \box_new_l:N #1 {\alloc_reg:NnNN l {box} \tex_mathchardef:D #1}
+\cs_new_nopar:Npn \box_new:N #1 {\alloc_reg:NnNN g {box} \tex_mathchardef:D #1}
+\cs_new_nopar:Npn \box_new_l:N #1 {\alloc_reg:NnNN l {box} \tex_mathchardef:D #1}
%</initex>
% \end{macrocode}
% When we run on top of \LaTeX, we just use its allocation
% mechanism.
% \begin{macrocode}
-%<package>\let_new:NN \box_new:N \newbox
-\def_new:Npn \box_new:c {\exp_args:Nc \box_new:N}
+%<*package>
+\cs_new:Npn \box_new:N #1 {
+ \chk_if_free_cs:N #1
+ \newbox #1
+}
+%</package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_generate_variant:Nn \box_new:N {c}
% \end{macrocode}
% \end{macro}
-% \end{macro}
-% \end{macro}
+%^^A \end{macro}
%
% \begin{macro}{\if_hbox:N}
% \begin{macro}{\if_vbox:N}
@@ -500,97 +533,97 @@
% The primitives for testing if a \m{box} is empty/void or which
% type of box it is.
% \begin{macrocode}
-\let_new:NN \if_hbox:N \tex_ifhbox:D
-\let_new:NN \if_vbox:N \tex_ifvbox:D
-\let_new:NN \if_box_empty:N \tex_ifvoid:D
+\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}{\box_if_horizontal_p:N,\box_if_horizontal_p:c}
+% \begin{macro}{\box_if_vertical_p:N,\box_if_vertical_p:c}
+% \begin{macro}[TF]{\box_if_horizontal:N,\box_if_horizontal:c}
+% \begin{macro}[TF]{\box_if_vertical:N,\box_if_vertical:c}
+% \begin{macrocode}
+\prg_new_conditional:Nnn \box_if_horizontal:N {p,TF,T,F} {
+ \tex_ifhbox:D #1 \prg_return_true: \else: \prg_return_false: \fi:
+}
+\prg_new_conditional:Nnn \box_if_vertical:N {p,TF,T,F} {
+ \tex_ifvbox:D #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:NTF {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_vertical_p:N {c}
+\cs_generate_variant:Nn \box_if_vertical:NTF {c}
+\cs_generate_variant:Nn \box_if_vertical:NT {c}
+\cs_generate_variant:Nn \box_if_vertical:NF {c}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
% \begin{macro}{\box_if_empty_p:N}
% \begin{macro}{\box_if_empty_p:c}
-% \begin{macro}{\box_if_empty:NTF}
-% \begin{macro}{\box_if_empty:cTF}
-% \begin{macro}{\box_if_empty:NT}
-% \begin{macro}{\box_if_empty:cT}
-% \begin{macro}{\box_if_empty:NF}
-% \begin{macro}{\box_if_empty:cF}
+% \begin{macro}[TF]{\box_if_empty:N}
+% \begin{macro}[TF]{\box_if_empty:c}
% Testing if a \m{box} is empty/void.
% \begin{macrocode}
-\def_new:Npn \box_if_empty_p:N #1{
- \if_box_empty:N #1 \c_true \else: \c_false \fi:}
-\def_new:Npn \box_if_empty_p:c {\exp_args:Nc \box_if_empty_p:N}
-\def_test_function_new:npn {box_if_empty:N}#1{\if_box_empty:N #1}
-\def_new:Npn \box_if_empty:cTF {\exp_args:Nc \box_if_empty:NTF}
-\def_new:Npn \box_if_empty:cT {\exp_args:Nc \box_if_empty:NT}
-\def_new:Npn \box_if_empty:cF {\exp_args:Nc \box_if_empty:NF}
+\prg_new_conditional:Nnn \box_if_empty:N {p,TF,T,F} {
+ \tex_ifvoid:D #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:NTF {c}
+\cs_generate_variant:Nn \box_if_empty:NT {c}
+\cs_generate_variant:Nn \box_if_empty:NF {c}
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
%
%
-% \begin{macro}{\box_set_eq:NN}
-% \begin{macro}{\box_set_eq:cN}
-% \begin{macro}{\box_set_eq:Nc}
-% \begin{macro}{\box_set_eq:cc}
+% \begin{macro}{\box_set_eq:NN,\box_set_eq:cN,
+% \box_set_eq:Nc,\box_set_eq:cc}
% Assigning the contents of a box to be another box.
% This clears the second box globally (that's how \TeX{} does it).
% \begin{macrocode}
-\def_new:Npn \box_set_eq:NN #1#2 {\tex_setbox:D #1 \tex_box:D #2}
-\def_new:Npn \box_set_eq:cN {\exp_args:Nc \box_set_eq:NN}
-\def_new:Npn \box_set_eq:Nc {\exp_args:NNc \box_set_eq:NN}
-\def_new:Npn \box_set_eq:cc {\exp_args:Ncc \box_set_eq:NN}
+\cs_new_nopar:Npn \box_set_eq:NN #1#2 {\tex_setbox:D #1 \tex_box:D #2}
+\cs_generate_variant:Nn \box_set_eq:NN {cN,Nc,cc}
% \end{macrocode}
% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
%
-% \begin{macro}{\box_gset_eq:NN}
-% \begin{macro}{\box_gset_eq:cN}
-% \begin{macro}{\box_gset_eq:Nc}
-% \begin{macro}{\box_gset_eq:cc}
+% \begin{macro}{\box_gset_eq:NN,\box_gset_eq:cN,
+% \box_gset_eq:Nc,\box_gset_eq:cc}
% Global version of the above.
% \begin{macrocode}
-\def_new:Npn \box_gset_eq:NN {\pref_global:D\box_set_eq:NN}
-\def_new:Npn \box_gset_eq:cN {\exp_args:Nc \box_gset_eq:NN}
-\def_new:Npn \box_gset_eq:Nc {\exp_args:NNc \box_gset_eq:NN}
-\def_new:Npn \box_gset_eq:cc {\exp_args:Ncc \box_gset_eq:NN}
+\cs_new_nopar:Npn \box_gset_eq:NN {\pref_global:D\box_set_eq:NN}
+\cs_generate_variant:Nn \box_gset_eq:NN {cN,Nc,cc}
% \end{macrocode}
% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
%
-% \begin{macro}{\R_last_box}
+% \begin{macro}{\l_last_box}
% A different name for this read-only primitive.
% \begin{macrocode}
-\let_new:NN \R_last_box \tex_lastbox:D
+\cs_new_eq:NN \l_last_box \tex_lastbox:D
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\box_set_to_last:N}
-% \begin{macro}{\box_set_to_last:c}
-% \begin{macro}{\box_gset_to_last:N}
-% \begin{macro}{\box_gset_to_last:c}
+% \begin{macro}{\box_set_to_last:N,\box_set_to_last:c}
+% \begin{macro}{\box_gset_to_last:N,\box_gset_to_last:c}
% Set a box to the previous box.
% \begin{macrocode}
-\def_new:Npn \box_set_to_last:N #1{\tex_setbox:D#1\R_last_box}
-\def_new:Npn \box_set_to_last:c {\exp_args:Nc \box_set_to_last:N}
-\def_new:Npn \box_gset_to_last:N {\pref_global:D \box_set_to_last:N}
-\def_new:Npn \box_gset_to_last:c {\exp_args:Nc \box_gset_to_last:N}
+\cs_new_nopar:Npn \box_set_to_last:N #1{\tex_setbox:D#1\l_last_box}
+\cs_generate_variant:Nn \box_set_to_last:N {c}
+\cs_new_nopar:Npn \box_gset_to_last:N {\pref_global:D \box_set_to_last:N}
+\cs_generate_variant:Nn \box_gset_to_last:N {c}
% \end{macrocode}
% \end{macro}
% \end{macro}
-% \end{macro}
-% \end{macro}
%
% \begin{macro}{\box_move_left:nn}
% \begin{macro}{\box_move_right:nn}
@@ -598,89 +631,73 @@
% \begin{macro}{\box_move_down:nn}
% Move box material in different directions.
% \begin{macrocode}
-\def_long_new:Npn \box_move_left:nn #1#2{\tex_moveleft:D\dim_eval:n{#1}{#2}}
-\def_long_new:Npn \box_move_right:nn #1#2{\tex_moveright:D\dim_eval:n{#1}{#2}}
-\def_long_new:Npn \box_move_up:nn #1#2{\tex_raise:D\dim_eval:n{#1}{#2}}
-\def_long_new:Npn \box_move_down:nn #1#2{\tex_lower:D\dim_eval:n{#1}{#2}}
+\cs_new:Npn \box_move_left:nn #1#2{\tex_moveleft:D\dim_eval:n{#1}{#2}}
+\cs_new:Npn \box_move_right:nn #1#2{\tex_moveright:D\dim_eval:n{#1}{#2}}
+\cs_new:Npn \box_move_up:nn #1#2{\tex_raise:D\dim_eval:n{#1}{#2}}
+\cs_new:Npn \box_move_down:nn #1#2{\tex_lower:D\dim_eval:n{#1}{#2}}
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
-% \begin{macro}{\box_clear:N}
-% \begin{macro}{\box_clear:c}
-% \begin{macro}{\box_gclear:N}
-% \begin{macro}{\box_gclear:c}
+% \begin{macro}{\box_clear:N,\box_clear:c}
+% \begin{macro}{\box_gclear:N,\box_gclear:c}
% Clear a \m{box} register.
% \begin{macrocode}
-\def_new:Npn \box_clear:N #1{\box_set_eq:NN #1 \c_empty_box }
-\def_new:Npn \box_clear:c {\exp_args:Nc \box_clear:N }
-\def_new:Npn \box_gclear:N {\pref_global:D\box_clear:N}
-\def_new:Npn \box_gclear:c {\exp_args:Nc \box_gclear:c }
+\cs_new_nopar:Npn \box_clear:N #1{\box_set_eq:NN #1 \c_empty_box }
+\cs_generate_variant:Nn \box_clear:N {c}
+\cs_new_nopar:Npn \box_gclear:N {\pref_global:D\box_clear:N}
+\cs_generate_variant:Nn \box_gclear:N {c}
% \end{macrocode}
% \end{macro}
% \end{macro}
-% \end{macro}
-% \end{macro}
%
%
-% \begin{macro}{\box_ht:N}
-% \begin{macro}{\box_ht:c}
-% \begin{macro}{\box_dp:N}
-% \begin{macro}{\box_dp:c}
-% \begin{macro}{\box_wd:n}
-% \begin{macro}{\box_wd:c}
+% \begin{macro}{\box_ht:N,\box_ht:c}
+% \begin{macro}{\box_dp:N,\box_dp:c}
+% \begin{macro}{\box_wd:N,\box_wd:c}
% Accessing the height, depth, and width of a \m{box} register.
% \begin{macrocode}
-\let_new:NN \box_ht:N \tex_ht:D
-\def_new:Npn \box_ht:c {\exp_args:Nc \box_ht:N}
-\let_new:NN \box_dp:N \tex_dp:D
-\def_new:Npn \box_dp:c {\exp_args:Nc \box_dp:N}
-\let_new:NN \box_wd:N \tex_wd:D
-\def_new:Npn \box_wd:c {\exp_args:Nc \box_wd:N}
+\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}
-% \end{macro}
-% \end{macro}
-% \end{macro}
%
-% \begin{macro}{\box_use_clear:N}
-% \begin{macro}{\box_use_clear:c}
-% \begin{macro}{\box_use:N}
-% \begin{macro}{\box_use:c}
-% Using a \m{box}. This is just \TeX{} primitives with meaningful
+% \begin{macro}{\box_use_clear:N,\box_use_clear:c}
+% \begin{macro}{\box_use:N,\box_use:c}
+% Using a \m{box}. These are just \TeX{} primitives with meaningful
% names.
% \begin{macrocode}
-\let_new:NN \box_use_clear:N \tex_box:D
-\def_new:Npn \box_use_clear:c {\exp_args:Nc \box_use_clear:N}
-\let_new:NN \box_use:N \tex_copy:D
-\def_new:Npn \box_use:c {\exp_args:Nc \box_use:N}
+\cs_new_eq:NN \box_use_clear:N \tex_box:D
+\cs_generate_variant:Nn \box_use_clear:N {c}
+\cs_new_eq:NN \box_use:N \tex_copy:D
+\cs_generate_variant:Nn \box_use:N {c}
% \end{macrocode}
% \end{macro}
% \end{macro}
-% \end{macro}
-% \end{macro}
%
-% \begin{macro}{\box_show:N}
-% \begin{macro}{\box_show:c}
+% \begin{macro}{\box_show:N,\box_show:c}
% Show the contents of a box and write it into the log file.
% \begin{macrocode}
-\let:NN \box_show:N \tex_showbox:D
-\def_new:Npn \box_show:c {\exp_args:Nc \box_show:N}
+\cs_set_eq:NN \box_show:N \tex_showbox:D
+\cs_generate_variant:Nn \box_show:N {c}
% \end{macrocode}
% \end{macro}
-% \end{macro}
%
% \begin{macro}{\c_empty_box}
% \begin{macro}{\l_tmpa_box}
% \begin{macro}{\l_tmpb_box}
% We allocate some \m{box} registers here (and borrow a few from \LaTeX).
% \begin{macrocode}
-%<package>\let:NN \c_empty_box \voidb@x
-%<package>\let_new:NN \l_tmpa_box \@tempboxa
+%<package>\cs_set_eq:NN \c_empty_box \voidb@x
+%<package>\cs_new_eq:NN \l_tmpa_box \@tempboxa
%<initex>\box_new:N \c_empty_box
%<initex>\box_new:N \l_tmpa_box
\box_new:N \l_tmpb_box
@@ -690,66 +707,56 @@
% \end{macro}
%
%
-% \subsubsection{Vertical boxes}
+% \subsection{Vertical boxes}
%
%
% \begin{macro}{\vbox:n}
% Put a vertical box directly into the input stream.
% \begin{macrocode}
-\def_new:Npn \vbox:n {\tex_vbox:D \scan_stop:}
+\cs_new_nopar:Npn \vbox:n {\tex_vbox:D \scan_stop:}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\vbox_set:Nn}
-% \begin{macro}{\vbox_set:cn}
-% \begin{macro}{\vbox_gset:Nn}
-% \begin{macro}{\vbox_gset:cn}
+% \begin{macro}{\vbox_set:Nn,\vbox_set:cn}
+% \begin{macro}{\vbox_gset:Nn,\vbox_gset:cn}
% Storing material in a vertical box with a natural height.
% \begin{macrocode}
-\def_long_new:Npn \vbox_set:Nn #1#2 {\tex_setbox:D #1 \tex_vbox:D {#2}}
-\def_new:Npn \vbox_set:cn {\exp_args:Nc \vbox_set:Nn}
-\def_new:Npn \vbox_gset:Nn {\pref_global:D \vbox_set:Nn}
-\def_new:Npn \vbox_gset:cn {\exp_args:Nc \vbox_gset:Nn}
+\cs_new:Npn \vbox_set:Nn #1#2 {\tex_setbox:D #1 \tex_vbox:D {#2}}
+\cs_generate_variant:Nn \vbox_set:Nn {cn}
+\cs_new_nopar:Npn \vbox_gset:Nn {\pref_global:D \vbox_set:Nn}
+\cs_generate_variant:Nn \vbox_gset:Nn {cn}
% \end{macrocode}
% \end{macro}
% \end{macro}
-% \end{macro}
-% \end{macro}
%
-% \begin{macro}{\vbox_set_to_ht:Nnn}
-% \begin{macro}{\vbox_set_to_ht:cnn}
-% \begin{macro}{\vbox_gset_to_ht:Nnn}
-% \begin{macro}{\vbox_gset_to_ht:cnn}
-% \begin{macro}{\vbox_gset_to_ht:ccn}
+% \begin{macro}{\vbox_set_to_ht:Nnn,\vbox_set_to_ht:cnn}
+% \begin{macro}{\vbox_gset_to_ht:Nnn,\vbox_gset_to_ht:cnn,\vbox_gset_to_ht:ccn}
% Storing material in a vertical box with a specified height.
% \begin{macrocode}
-\def_long_new:Npn \vbox_set_to_ht:Nnn #1#2#3 {
- \tex_setbox:D #1 \tex_vbox:D to #2 {#3}}
-\def_new:Npn \vbox_set_to_ht:cnn{\exp_args:Nc \vbox_set_to_ht:Nnn }
-\def_new:Npn \vbox_gset_to_ht:Nnn {\pref_global:D \vbox_set_to_ht:Nnn }
-\def_new:Npn \vbox_gset_to_ht:cnn{\exp_args:Nc \vbox_gset_to_ht:Nnn }
-\def_new:Npn \vbox_gset_to_ht:ccn {\exp_args:Ncc \vbox_gset_to_ht:Nnn}
+\cs_new:Npn \vbox_set_to_ht:Nnn #1#2#3 {
+ \tex_setbox:D #1 \tex_vbox:D to #2 {#3}
+}
+\cs_generate_variant:Nn \vbox_set_to_ht:Nnn {cnn}
+\cs_new_nopar:Npn \vbox_gset_to_ht:Nnn { \pref_global:D \vbox_set_to_ht:Nnn }
+\cs_generate_variant:Nn \vbox_gset_to_ht:Nnn {cnn,ccn}
% \end{macrocode}
% \end{macro}
% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
%
%
% \begin{macro}{\vbox_set_inline_begin:N}
% \begin{macro}{\vbox_set_inline_end:}
% \begin{macro}{\vbox_gset_inline_begin:N}
-% \begin{macro}{\vbox_set_inline_end:}
+% \begin{macro}{\vbox_gset_inline_end:}
% Storing material in a vertical box. This type is useful in
% environment definitions.
% \begin{macrocode}
-\def_new:Npn \vbox_set_inline_begin:N #1 {
+\cs_new_nopar:Npn \vbox_set_inline_begin:N #1 {
\tex_setbox:D #1 \tex_vbox:D \c_group_begin_token }
-\let_new:NN \vbox_set_inline_end: \c_group_end_token
-\def_new:Npn \vbox_gset_inline_begin:N {
+\cs_new_eq:NN \vbox_set_inline_end: \c_group_end_token
+\cs_new_nopar:Npn \vbox_gset_inline_begin:N {
\pref_global:D \vbox_set_inline_begin:N }
-\let_new:NN \vbox_gset_inline_end: \c_group_end_token
+\cs_new_eq:NN \vbox_gset_inline_end: \c_group_end_token
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -761,8 +768,8 @@
% \begin{macro}{\vbox_to_zero:n}
% Put a vertical box directly into the input stream.
% \begin{macrocode}
-\def_long_new:Npn \vbox_to_ht:nn #1#2{\tex_vbox:D to \dim_eval:n{#1}{#2}}
-\def_long_new:Npn \vbox_to_zero:n #1 {\tex_vbox:D to \c_zero_dim {#1}}
+\cs_new:Npn \vbox_to_ht:nn #1#2{\tex_vbox:D to \dim_eval:n{#1}{#2}}
+\cs_new:Npn \vbox_to_zero:n #1 {\tex_vbox:D to \c_zero_dim {#1}}
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -770,130 +777,111 @@
% \begin{macro}{\vbox_set_split_to_ht:NNn}
% Splitting a vertical box in two.
% \begin{macrocode}
-\def_new:Npn \vbox_set_split_to_ht:NNn #1#2#3{
+\cs_new_nopar:Npn \vbox_set_split_to_ht:NNn #1#2#3{
\tex_setbox:D #1 \tex_vsplit:D #2 to #3
}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\vbox_unpack:N}
-% \begin{macro}{\vbox_unpack:c}
-% \begin{macro}{\vbox_unpack_clear:N}
-% \begin{macro}{\vbox_unpack_clear:c}
+% \begin{macro}{\vbox_unpack:N,\vbox_unpack:c}
+% \begin{macro}{\vbox_unpack_clear:N,\vbox_unpack_clear:c}
% Unpacking a box and if requested also clear it.
% \begin{macrocode}
-\let_new:NN \vbox_unpack:N \tex_unvcopy:D
-\def_new:Npn \vbox_unpack:c {\exp_args:Nc \vbox_unpack:N}
-\let_new:NN \vbox_unpack_clear:N \tex_unvbox:D
-\def_new:Npn \vbox_unpack_clear:c {\exp_args:Nc \vbox_unpack_clear:N}
+\cs_new_eq:NN \vbox_unpack:N \tex_unvcopy:D
+\cs_generate_variant:Nn \vbox_unpack:N {c}
+\cs_new_eq:NN \vbox_unpack_clear:N \tex_unvbox:D
+\cs_generate_variant:Nn \vbox_unpack_clear:N {c}
% \end{macrocode}
% \end{macro}
% \end{macro}
-% \end{macro}
-% \end{macro}
%
%
%
%
%
%
-% \subsubsection{Horizontal boxes}
+% \subsection{Horizontal boxes}
%
%
% \begin{macro}{\hbox:n}
% Put a horizontal box directly into the input stream.
% \begin{macrocode}
-\def_new:Npn \hbox:n {\tex_hbox:D \scan_stop:}
+\cs_new_nopar:Npn \hbox:n {\tex_hbox:D \scan_stop:}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\hbox_set:Nn}
-% \begin{macro}{\hbox_set:cn}
-% \begin{macro}{\hbox_gset:Nn}
-% \begin{macro}{\hbox_gset:cn}
+% \begin{macro}{\hbox_set:Nn,\hbox_set:cn}
+% \begin{macro}{\hbox_gset:Nn,\hbox_gset:cn}
% Assigning the contents of a box to be another box.
% This clears the second box globally (that's how \TeX{} does it).
% \begin{macrocode}
-\def_long_new:Npn \hbox_set:Nn #1#2 {\tex_setbox:D #1 \tex_hbox:D {#2}}
-\def_new:Npn \hbox_set:cn {\exp_args:Nc \hbox_set:Nn}
-\def_new:Npn \hbox_gset:Nn {\pref_global:D \hbox_set:Nn}
-\def_new:Npn \hbox_gset:cn {\exp_args:Nc \hbox_gset:Nn}
+\cs_new:Npn \hbox_set:Nn #1#2 {\tex_setbox:D #1 \tex_hbox:D {#2}}
+\cs_generate_variant:Nn \hbox_set:Nn {cn}
+\cs_new_nopar:Npn \hbox_gset:Nn {\pref_global:D \hbox_set:Nn}
+\cs_generate_variant:Nn \hbox_gset:Nn {cn}
% \end{macrocode}
% \end{macro}
% \end{macro}
-% \end{macro}
-% \end{macro}
%
-% \begin{macro}{\hbox_set_to_wd:Nnn}
-% \begin{macro}{\hbox_set_to_wd:cnn}
-% \begin{macro}{\hbox_gset_to_wd:Nnn}
-% \begin{macro}{\hbox_gset_to_wd:cnn}
+% \begin{macro}{\hbox_set_to_wd:Nnn,\hbox_set_to_wd:cnn}
+% \begin{macro}{\hbox_gset_to_wd:Nnn,\hbox_gset_to_wd:cnn}
% Storing material in a horizontal box with a specified width.
% \begin{macrocode}
-\def_long_new:Npn \hbox_set_to_wd:Nnn #1#2#3 {
- \tex_setbox:D #1 \tex_hbox:D to \dim_eval:n{#2} {#3}}
-\def_new:Npn \hbox_set_to_wd:cnn{\exp_args:Nc \hbox_set_to_wd:Nnn }
-\def_new:Npn \hbox_gset_to_wd:Nnn {\pref_global:D \hbox_set_to_wd:Nnn }
-\def_new:Npn \hbox_gset_to_wd:cnn{\exp_args:Nc \hbox_gset_to_wd:Nnn }
+\cs_new:Npn \hbox_set_to_wd:Nnn #1#2#3 {
+ \tex_setbox:D #1 \tex_hbox:D to \dim_eval:n{#2} {#3}
+}
+\cs_generate_variant:Nn \hbox_set_to_wd:Nnn {cnn}
+\cs_new_nopar:Npn \hbox_gset_to_wd:Nnn {\pref_global:D \hbox_set_to_wd:Nnn }
+\cs_generate_variant:Nn \hbox_gset_to_wd:Nnn {cnn}
% \end{macrocode}
% \end{macro}
% \end{macro}
-% \end{macro}
-% \end{macro}
%
%
-% \begin{macro}{\hbox_set_inline_begin:N}
-% \begin{macro}{\hbox_set_inline_begin:c}
-% \begin{macro}{\hbox_set_inline_end:}
-% \begin{macro}{\hbox_gset_inline_begin:N}
-% \begin{macro}{\hbox_gset_inline_begin:c}
+% \begin{macro}{\hbox_set_inline_begin:N,\hbox_set_inline_begin:c}
% \begin{macro}{\hbox_set_inline_end:}
+% \begin{macro}{\hbox_gset_inline_begin:N,\hbox_gset_inline_begin:c}
+% \begin{macro}{\hbox_gset_inline_end:}
% Storing material in a horizontal box. This type is useful in
% environment definitions.
% \begin{macrocode}
-\def_new:Npn \hbox_set_inline_begin:N #1 {
- \tex_setbox:D #1 \tex_hbox:D \c_group_begin_token }
-\def:Npn \hbox_set_inline_begin:c {\exp_args:Nc
- \hbox_set_inline_begin:N}
-\let_new:NN \hbox_set_inline_end: \c_group_end_token
-\def_new:Npn \hbox_gset_inline_begin:N {
- \pref_global:D \hbox_set_inline_begin:N }
-\def:Npn \hbox_gset_inline_begin:c {\exp_args:Nc
- \hbox_gset_inline_begin:N }
-\let_new:NN \hbox_gset_inline_end: \c_group_end_token
+\cs_new_nopar:Npn \hbox_set_inline_begin:N #1 {
+ \tex_setbox:D #1 \tex_hbox:D \c_group_begin_token
+}
+\cs_generate_variant:Nn \hbox_set_inline_begin:N {c}
+\cs_new_eq:NN \hbox_set_inline_end: \c_group_end_token
+\cs_new_nopar:Npn \hbox_gset_inline_begin:N {
+ \pref_global:D \hbox_set_inline_begin:N
+}
+\cs_generate_variant:Nn \hbox_gset_inline_begin:N {c}
+\cs_new_eq:NN \hbox_gset_inline_end: \c_group_end_token
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
-% \end{macro}
-% \end{macro}
%
% \begin{macro}{\hbox_to_wd:nn}
% \begin{macro}{\hbox_to_zero:n}
% Put a horizontal box directly into the input stream.
% \begin{macrocode}
-\def_long_new:Npn \hbox_to_wd:nn #1#2 {\tex_hbox:D to #1 {#2}}
-\def_long_new:Npn \hbox_to_zero:n #1 {\tex_hbox:D to \c_zero_skip {#1}}
+\cs_new:Npn \hbox_to_wd:nn #1#2 {\tex_hbox:D to #1 {#2}}
+\cs_new:Npn \hbox_to_zero:n #1 {\tex_hbox:D to \c_zero_skip {#1}}
% \end{macrocode}
% \end{macro}
% \end{macro}
%
-% \begin{macro}{\hbox_unpack:N}
-% \begin{macro}{\hbox_unpack:c}
-% \begin{macro}{\hbox_unpack_clear:N}
-% \begin{macro}{\hbox_unpack_clear:c}
+% \begin{macro}{\hbox_unpack:N,\hbox_unpack:c}
+% \begin{macro}{\hbox_unpack_clear:N,\hbox_unpack_clear:c}
% Unpacking a box and if requested also clear it.
% \begin{macrocode}
-\let_new:NN \hbox_unpack:N \tex_unhcopy:D
-\def_new:Npn \hbox_unpack:c {\exp_args:Nc \hbox_unpack:N}
-\let_new:NN \hbox_unpack_clear:N \tex_unhbox:D
-\def_new:Npn \hbox_unpack_clear:c {\exp_args:Nc \hbox_unpack_clear:N}
+\cs_new_eq:NN \hbox_unpack:N \tex_unhcopy:D
+\cs_generate_variant:Nn \hbox_unpack:N {c}
+\cs_new_eq:NN \hbox_unpack_clear:N \tex_unhbox:D
+\cs_generate_variant:Nn \hbox_unpack_clear:N {c}
% \end{macrocode}
% \end{macro}
% \end{macro}
-% \end{macro}
-% \end{macro}
%
%
%
@@ -910,40 +898,15 @@
%
% \begin{macrocode}
%</initex|package>
+% \end{macrocode}
+%
+% \begin{macrocode}
%<*showmemory>
\showMemUsage
%</showmemory>
% \end{macrocode}
%
-% \endinput
-%
-% $Log$
-% Revision 1.10 2006/03/20 18:26:34 braams
-% Updated the copyright notice (2006) and demoted all implementation
-% sections to subsections and so on to clean up the toc for source3.tex
-%
-% Revision 1.9 2006/01/19 22:30:30 morten
-% Added functions for accessing \tex_lastbox:D and moving box material
-% in the four directions.
-%
-% Revision 1.8 2005/12/27 16:04:12 morten
-% Changed RCS information retrieval
-%
-% Revision 1.7 2005/10/27 23:11:12 morten
-% Moved \if_hbox:N, \if_vbox:N and _if_box_empty:N here
-%
-% Revision 1.6 2005/04/25 16:15:17 morten
-% Fixed \bgroup/\egroup and made it run under initex
-%
-% Revision 1.5 2005/04/06 22:35:33 braams
-% Now we have register allocation fitted
-%
-% Revision 1.4 2005/03/26 21:08:12 morten
-% Fix \c_zero -> \c_zero_skip
-%
-% Revision 1.3 2005/03/16 22:36:46 braams
-% Added the tweaks necessary to be able to load with initex
-%
-% Revision 1.2 2005/03/11 21:31:07 braams
-% Fixed the use of RCS information; added \StopEventually
+% \end{implementation}
+% \PrintIndex
%
+% \endinput
diff --git a/Master/texmf-dist/source/latex/expl3/l3calc.dtx b/Master/texmf-dist/source/latex/expl3/l3calc.dtx
index 842e68864c7..c9519f13ca4 100644
--- a/Master/texmf-dist/source/latex/expl3/l3calc.dtx
+++ b/Master/texmf-dist/source/latex/expl3/l3calc.dtx
@@ -1,5 +1,5 @@
% \iffalse
-%% File: l3calc.dtx Copyright (C) 2006 LaTeX3 project
+%% File: l3calc.dtx Copyright (C) 2006,2009 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
@@ -17,7 +17,7 @@
%%
%% The development version of the bundle can be found at
%%
-%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/
+%% http://www.latex-project.org/svnroot/experimental/trunk/
%%
%% for those people who are interested.
%%
@@ -35,7 +35,7 @@
\RequirePackage{l3names}
%</driver|package>
%\fi
-\GetIdInfo$Id: l3calc.dtx 621 2007-09-01 20:14:19Z morten $
+\GetIdInfo$Id: l3calc.dtx 1362 2009-05-28 20:19:21Z joseph $
{L3 Experimental calc module}
%\iffalse
%<*driver>
@@ -43,7 +43,7 @@
\ProvidesFile{\filename.\filenameext}
[\filedate\space v\fileversion\space\filedescription]
%\iffalse
-\documentclass{l3doc}
+\documentclass[full]{l3doc}
\begin{document}
\DocInput{\filename.\filenameext}
\end{document}
@@ -58,8 +58,8 @@
% \date{\filedate}
% \maketitle
%
-% \section{Infix notation arithmetic}
-%
+% \begin{documentation}
+%
% This is pretty much a straight adaption of the \textsf{calc} package
% and as such has same syntax for the \meta{calc expression}. However,
% there are some noticeable differences.
@@ -83,16 +83,51 @@
% the original \textsf{calc} package providing the same functionality
% and will prevent the original \textsf{calc} package from loading.
%
+% \section{User functions}
+%
+%
+% \begin{function}{ \maxof |
+% \minof |
+% \widthof |
+% \heightof |
+% \depthof |
+% \totalheightof |
+% \ratio |
+% \real |
+% \setlength |
+% \gsetlength |
+% \addtolength |
+% \gaddtolength |
+% \setcounter |
+% \addtocounter |
+% \stepcounter }
+% See documentation for \LaTeXe\ package \pkg{calc}.
+% \end{function}
+%
+% \begin{function}{ \calc_maxof:nn |
+% \calc_minof:nn |
+% \calc_widthof:n |
+% \calc_heightof:n |
+% \calc_depthof:n |
+% \calc_totalheightof:n |
+% \calc_ratio:nn |
+% \calc_real:n |
+% \calc_setcounter:nn |
+% \calc_addtocounter:nn |
+% \calc_stepcounter:n }
+% Equivalent commands as the above in the \pkg{expl3} namespace.
+% \end{function}
+%
% \begin{function}{
% \calc_int_set:Nn |
% \calc_int_gset:Nn |
% \calc_int_add:Nn |
% \calc_int_gadd:Nn |
% \calc_int_sub:Nn |
-% \calc_int_gsub:Nn |
+% \calc_int_gsub:Nn
% }
% \begin{syntax}
-% "\calc_int_set:Nn" <int> "{"<calc expression>"}"
+% "\calc_int_set:Nn" <int> \Arg{calc expression}
% \end{syntax}
% Evaluates <calc expression> and either adds or subtracts it from
% <int> or sets <int> to it. These operations can also be global.
@@ -108,7 +143,7 @@
% \calc_dim_gsub:Nn |
% }
% \begin{syntax}
-% "\calc_dim_set:Nn" <dim> "{"<calc expression>"}"
+% "\calc_dim_set:Nn" <dim> \Arg{calc expression}
% \end{syntax}
% Evaluates <calc expression> and either adds or subtracts it from
% <dim> or sets <dim> to it. These operations can also be global.
@@ -124,7 +159,7 @@
% \calc_skip_gsub:Nn |
% }
% \begin{syntax}
-% "\calc_skip_set:Nn" <skip> "{"<calc expression>"}"
+% "\calc_skip_set:Nn" <skip> \Arg{calc expression}
% \end{syntax}
% Evaluates <calc expression> and either adds or subtracts it from
% <skip> or sets <skip> to it. These operations can also be global.
@@ -140,7 +175,7 @@
% \calc_muskip_gsub:Nn |
% }
% \begin{syntax}
-% "\calc_muskip_set:Nn" <muskip> "{"<calc expression>"}"
+% "\calc_muskip_set:Nn" <muskip> \Arg{calc expression}
% \end{syntax}
% Evaluates <calc expression> and either adds or subtracts it from
% <muskip> or sets <muskip> to it. These operations can also be
@@ -152,8 +187,8 @@
% \calc_calculate_box_size:nnn |
% }
% \begin{syntax}
-% "\calc_calculate_box_size:nnn" "{"<dim-set>"}" \\
-% "{"<item 1> <item 2> ... <item n>"}" "{"<contents>"}"
+% "\calc_calculate_box_size:nnn" \Arg{dim-set} \\
+% "{"<item 1> <item 2> ... <item n>"}" \Arg{contents}
% \end{syntax}
% Sets <contents> in a temporary box "\l_tmpa_box". Then <dim-set>
% is put in front of a loop that inserts "+"\meta{item$\sb{i}$} in
@@ -172,9 +207,72 @@
% \end{verbatim}
% \end{function}
%
-% \StopEventually{}
+% \end{documentation}
+%
+% \begin{implementation}
+%
%
-% \subsection{The Implementation}
+% \section{\pkg{l3calc} implementation}
+%
+% \subsection{Variables}
+%
+% \begin{function}{ \l_calc_expression_tl |
+% \g_calc_A_register |
+% \l_calc_B_register |
+% \l_calc_current_type_int |
+% \g_calc_A_int |
+% \l_calc_B_int |
+% \l_calc_C_int |
+% \g_calc_A_dim |
+% \l_calc_B_dim |
+% \l_calc_C_dim |
+% \g_calc_A_skip |
+% \l_calc_B_skip |
+% \l_calc_C_skip |
+% \g_calc_A_muskip |
+% \l_calc_B_muskip |
+% \l_calc_C_muskip }
+% Internal registers.
+% \end{function}
+%
+% \subsection{Internal functions}
+%
+% \begin{function}{ \calc_assign_generic:NNNNnn |
+% \calc_pre_scan:N |
+% \calc_open:w |
+% \calc_init_B: |
+% \calc_numeric: |
+% \calc_close: |
+% \calc_post_scan:N |
+% \calc_multiply:N |
+% \calc_divide:N |
+% \calc_generic_add_or_subtract:N |
+% \calc_add: |
+% \calc_subtract: |
+% \calc_add_A_to_B: |
+% \calc_subtract_A_from_B: |
+% \calc_generic_multiply_or_divide:N |
+% \calc_multiply_B_by_A: |
+% \calc_divide_B_by_A: |
+% \calc_multiply: |
+% \calc_divide: |
+% \calc_textsize:Nn |
+% \calc_ratio_multiply:nn |
+% \calc_ratio_divide:nn |
+% \calc_real_evaluate:nn |
+% \calc_real_multiply:n |
+% \calc_real_divide:n |
+% \calc_maxmin_operation:Nnn |
+% \calc_maxmin_generic:Nnn |
+% \calc_maxmin_div_or_mul:NNnn |
+% \calc_maxmin_multiply: |
+% \calc_maxmin_multiply: |
+% \calc_error:N |
+% \calc_chk_document_counter:nn }
+% Awaiting better documentation ":)"
+% \end{function}
+%
+% \subsection{Module code}
%
% Since this is basically a re-worked version of the \textsf{calc}
% package, I haven't bothered with too many comments except for in the
@@ -186,23 +284,21 @@
%<*package>
\ProvidesExplPackage
{\filename}{\filedate}{\fileversion}{\filedescription}
-\RequirePackage{l3int}
-\RequirePackage{l3skip}
-\RequirePackage{l3box}
+\package_check_loaded_expl:
%</package>
%<*initex|package>
% \end{macrocode}
%
%
-% \begin{macro}{\l_calc_expression_tlp}
+% \begin{macro}{\l_calc_expression_tl}
% \begin{macro}{\g_calc_A_register}
% \begin{macro}{\l_calc_B_register}
% \begin{macro}{\l_calc_current_type_int}
% Here we define some registers and pointers we will need.
% \begin{macrocode}
-\tlp_new:Nn\l_calc_expression_tlp{}
-\def_new:Npn \g_calc_A_register{}
-\def_new:Npn \l_calc_B_register{}
+\tl_new:Nn\l_calc_expression_tl{}
+\cs_new_nopar:Npn \g_calc_A_register{}
+\cs_new_nopar:Npn \l_calc_B_register{}
\int_new:N \l_calc_current_type_int
% \end{macrocode}
% \end{macro}
@@ -261,17 +357,17 @@
% little extra work so that |\real| and |\ratio| can still be used
% by the user.
% \begin{macrocode}
-\def_long_new:Npn \calc_assign_generic:NNNNnn#1#2#3#4#5#6{
- \let:NN\g_calc_A_register#2
- \let:NN\l_calc_B_register#3
+\cs_new:Npn \calc_assign_generic:NNNNnn#1#2#3#4#5#6{
+ \cs_set_eq:NN\g_calc_A_register#2
+ \cs_set_eq:NN\l_calc_B_register#3
\int_set:Nn \l_calc_current_type_int {#1}
\group_begin:
- \let:NN \real \calc_real:n
- \let:NN \ratio\calc_ratio:nn
- \tlp_set:Nx\l_calc_expression_tlp{#6}
- \exp_after:NN
+ \cs_set_eq:NN \real \calc_real:n
+ \cs_set_eq:NN \ratio\calc_ratio:nn
+ \tl_set:Nx\l_calc_expression_tl{#6}
+ \exp_after:wN
\group_end:
- \exp_after:NN\calc_open:w\exp_after:NN(\l_calc_expression_tlp !
+ \exp_after:wN\calc_open:w\exp_after:wN(\l_calc_expression_tl !
\pref_global:D\g_calc_A_register\l_calc_B_register
\group_end:
#4{#5}\l_calc_B_register
@@ -280,11 +376,11 @@
% A simpler version relying on |\real| and |\ratio| having our
% definition is
% \begin{verbatim}
-% \def_long_new:Npn \calc_assign_generic:NNNNnn#1#2#3#4#5#6{
-% \let:NN\g_calc_A_register#2\let:NN\l_calc_B_register#3
+% \cs_new:Npn \calc_assign_generic:NNNNnn#1#2#3#4#5#6{
+% \cs_set_eq:NN\g_calc_A_register#2\cs_set_eq:NN\l_calc_B_register#3
% \int_set:Nn \l_calc_current_type_int {#1}
-% \tlp_set:Nx\l_calc_expression_tlp{#6}
-% \exp_after:NN\calc_open:w\exp_after:NN(\l_calc_expression_tlp !
+% \tl_set:Nx\l_calc_expression_tl{#6}
+% \exp_after:wN\calc_open:w\exp_after:wN(\l_calc_expression_tl !
% \pref_global:D\g_calc_A_register\l_calc_B_register
% \group_end:
% #4{#5}\l_calc_B_register
@@ -303,22 +399,22 @@
% Here are the individual versions for the different register
% types. First integer registers.
% \begin{macrocode}
-\def_new:Npn\calc_int_set:Nn{
+\cs_new_nopar:Npn\calc_int_set:Nn{
\calc_assign_generic:NNNNnn\c_zero\g_calc_A_int\l_calc_B_int\int_set:Nn
}
-\def_new:Npn\calc_int_gset:Nn{
+\cs_new_nopar:Npn\calc_int_gset:Nn{
\calc_assign_generic:NNNNnn\c_zero\g_calc_A_int\l_calc_B_int\int_gset:Nn
}
-\def_new:Npn\calc_int_add:Nn{
+\cs_new_nopar:Npn\calc_int_add:Nn{
\calc_assign_generic:NNNNnn\c_zero\g_calc_A_int\l_calc_B_int\int_add:Nn
}
-\def_new:Npn\calc_int_gadd:Nn{
+\cs_new_nopar:Npn\calc_int_gadd:Nn{
\calc_assign_generic:NNNNnn\c_zero\g_calc_A_int\l_calc_B_int\int_gadd:Nn
}
-\def_new:Npn\calc_int_sub:Nn{
+\cs_new_nopar:Npn\calc_int_sub:Nn{
\calc_assign_generic:NNNNnn\c_zero\g_calc_A_int\l_calc_B_int\int_sub:Nn
}
-\def_new:Npn\calc_int_gsub:Nn{
+\cs_new_nopar:Npn\calc_int_gsub:Nn{
\calc_assign_generic:NNNNnn\c_zero\g_calc_A_int\l_calc_B_int\int_gsub:Nn
}
% \end{macrocode}
@@ -337,22 +433,22 @@
% \begin{macro}{\calc_dim_gsub:Nn}
% Dimens.
% \begin{macrocode}
-\def_new:Npn\calc_dim_set:Nn{
+\cs_new_nopar:Npn\calc_dim_set:Nn{
\calc_assign_generic:NNNNnn\c_one\g_calc_A_dim\l_calc_B_dim\dim_set:Nn
}
-\def_new:Npn\calc_dim_gset:Nn{
+\cs_new_nopar:Npn\calc_dim_gset:Nn{
\calc_assign_generic:NNNNnn\c_one\g_calc_A_dim\l_calc_B_dim\dim_gset:Nn
}
-\def_new:Npn\calc_dim_add:Nn{
+\cs_new_nopar:Npn\calc_dim_add:Nn{
\calc_assign_generic:NNNNnn\c_one\g_calc_A_dim\l_calc_B_dim\dim_add:Nn
}
-\def_new:Npn\calc_dim_gadd:Nn{
+\cs_new_nopar:Npn\calc_dim_gadd:Nn{
\calc_assign_generic:NNNNnn\c_one\g_calc_A_dim\l_calc_B_dim\dim_gadd:Nn
}
-\def_new:Npn\calc_dim_sub:Nn{
+\cs_new_nopar:Npn\calc_dim_sub:Nn{
\calc_assign_generic:NNNNnn\c_one\g_calc_A_int\l_calc_B_int\dim_sub:Nn
}
-\def_new:Npn\calc_dim_gsub:Nn{
+\cs_new_nopar:Npn\calc_dim_gsub:Nn{
\calc_assign_generic:NNNNnn\c_one\g_calc_A_int\l_calc_B_int\dim_gsub:Nn
}
% \end{macrocode}
@@ -371,22 +467,22 @@
% \begin{macro}{\calc_skip_gsub:Nn}
% Skips.
% \begin{macrocode}
-\def_new:Npn\calc_skip_set:Nn{
+\cs_new_nopar:Npn\calc_skip_set:Nn{
\calc_assign_generic:NNNNnn\c_two\g_calc_A_skip\l_calc_B_skip\skip_set:Nn
}
-\def_new:Npn\calc_skip_gset:Nn{
+\cs_new_nopar:Npn\calc_skip_gset:Nn{
\calc_assign_generic:NNNNnn\c_two\g_calc_A_skip\l_calc_B_skip\skip_gset:Nn
}
-\def_new:Npn\calc_skip_add:Nn{
+\cs_new_nopar:Npn\calc_skip_add:Nn{
\calc_assign_generic:NNNNnn\c_two\g_calc_A_skip\l_calc_B_skip\skip_add:Nn
}
-\def_new:Npn\calc_skip_gadd:Nn{
+\cs_new_nopar:Npn\calc_skip_gadd:Nn{
\calc_assign_generic:NNNNnn\c_two\g_calc_A_skip\l_calc_B_skip\skip_gadd:Nn
}
-\def_new:Npn\calc_skip_sub:Nn{
+\cs_new_nopar:Npn\calc_skip_sub:Nn{
\calc_assign_generic:NNNNnn\c_two\g_calc_A_skip\l_calc_B_skip\skip_sub:Nn
}
-\def_new:Npn\calc_skip_gsub:Nn{
+\cs_new_nopar:Npn\calc_skip_gsub:Nn{
\calc_assign_generic:NNNNnn\c_two\g_calc_A_skip\l_calc_B_skip\skip_gsub:Nn
}
% \end{macrocode}
@@ -405,27 +501,27 @@
% \begin{macro}{\calc_muskip_gsub:Nn}
% Muskips.
% \begin{macrocode}
-\def_new:Npn\calc_muskip_set:Nn{
+\cs_new_nopar:Npn\calc_muskip_set:Nn{
\calc_assign_generic:NNNNnn\c_three\g_calc_A_muskip\l_calc_B_muskip
\muskip_set:Nn
}
-\def_new:Npn\calc_muskip_gset:Nn{
+\cs_new_nopar:Npn\calc_muskip_gset:Nn{
\calc_assign_generic:NNNNnn\c_three\g_calc_A_muskip\l_calc_B_muskip
\muskip_gset:Nn
}
-\def_new:Npn\calc_muskip_add:Nn{
+\cs_new_nopar:Npn\calc_muskip_add:Nn{
\calc_assign_generic:NNNNnn\c_three\g_calc_A_muskip\l_calc_B_muskip
\muskip_add:Nn
}
-\def_new:Npn\calc_muskip_gadd:Nn{
+\cs_new_nopar:Npn\calc_muskip_gadd:Nn{
\calc_assign_generic:NNNNnn\c_three\g_calc_A_muskip\l_calc_B_muskip
\muskip_gadd:Nn
}
-\def_new:Npn\calc_muskip_sub:Nn{
+\cs_new_nopar:Npn\calc_muskip_sub:Nn{
\calc_assign_generic:NNNNnn\c_three\g_calc_A_muskip\l_calc_B_muskip
\muskip_add:Nn
}
-\def_new:Npn\calc_muskip_gsub:Nn{
+\cs_new_nopar:Npn\calc_muskip_gsub:Nn{
\calc_assign_generic:NNNNnn\c_three\g_calc_A_muskip\l_calc_B_muskip
\muskip_gadd:Nn
}
@@ -442,13 +538,13 @@
% In case we found one of the special operations, this should just
% be executed.
% \begin{macrocode}
-\def_new:Npn \calc_pre_scan:N #1{
- \if_meaning:NN(#1
- \exp_after:NN\calc_open:w
+\cs_new_nopar:Npn \calc_pre_scan:N #1{
+ \if_meaning:w(#1
+ \exp_after:wN\calc_open:w
\else:
- \if_meaning:NN \calc_textsize:Nn #1
+ \if_meaning:w \calc_textsize:Nn #1
\else:
- \if_meaning:NN \calc_maxmin_operation:Nnn #1
+ \if_meaning:w \calc_maxmin_operation:Nnn #1
\else:
% \end{macrocode}
% |\calc_numeric:| uses a primitive assignment so doesn't care about
@@ -464,7 +560,7 @@
%
% \begin{macro}{\calc_open:w}
% \begin{macrocode}
-\def_new:Npn \calc_open:w({
+\cs_new_nopar:Npn \calc_open:w({
\group_begin:\group_execute_after:N\calc_init_B:
\group_begin:\group_execute_after:N\calc_init_B:
\calc_pre_scan:N
@@ -476,12 +572,12 @@
% \begin{macro}{\calc_numeric:}
% \begin{macro}{\calc_close:}
% \begin{macrocode}
-\def_new:Npn\calc_init_B:{\l_calc_B_register\g_calc_A_register}
-\def_new:Npn\calc_numeric:{
+\cs_new_nopar:Npn\calc_init_B:{\l_calc_B_register\g_calc_A_register}
+\cs_new_nopar:Npn\calc_numeric:{
\tex_afterassignment:D\calc_post_scan:N
\pref_global:D\g_calc_A_register
}
-\def_new:Npn\calc_close:{
+\cs_new_nopar:Npn\calc_close:{
\group_end:\pref_global:D\g_calc_A_register\l_calc_B_register
\group_end:\pref_global:D\g_calc_A_register\l_calc_B_register
\calc_post_scan:N}
@@ -493,21 +589,21 @@
% \begin{macro}{\calc_post_scan:N}
% Look at what token we have and decide where to go.
% \begin{macrocode}
-\def_new:Npn\calc_post_scan:N#1{
- \if_meaning:NN#1!\let:NN\calc_next:w\group_end: \else:
- \if_meaning:NN#1+\let:NN\calc_next:w\calc_add: \else:
- \if_meaning:NN#1-\let:NN\calc_next:w\calc_subtract: \else:
- \if_meaning:NN#1*\let:NN\calc_next:w\calc_multiply:N \else:
- \if_meaning:NN#1/\let:NN\calc_next:w\calc_divide:N \else:
- \if_meaning:NN#1)\let:NN\calc_next:w\calc_close: \else:
- \if_meaning:NN#1\scan_stop:\let:NN\calc_next:w\calc_post_scan:N
+\cs_new_nopar:Npn\calc_post_scan:N#1{
+ \if_meaning:w#1!\cs_set_eq:NN\calc_next:w\group_end: \else:
+ \if_meaning:w#1+\cs_set_eq:NN\calc_next:w\calc_add: \else:
+ \if_meaning:w#1-\cs_set_eq:NN\calc_next:w\calc_subtract: \else:
+ \if_meaning:w#1*\cs_set_eq:NN\calc_next:w\calc_multiply:N \else:
+ \if_meaning:w#1/\cs_set_eq:NN\calc_next:w\calc_divide:N \else:
+ \if_meaning:w#1)\cs_set_eq:NN\calc_next:w\calc_close: \else:
+ \if_meaning:w#1\scan_stop:\cs_set_eq:NN\calc_next:w\calc_post_scan:N
\else:
% \end{macrocode}
% If we get here, there is an error but let's also disable
% |\calc_next:w| since it is otherwise undefined. No need to give
% extra errors just for that.
% \begin{macrocode}
- \let:NN \calc_next:w \use_noop:
+ \cs_set_eq:NN \calc_next:w \prg_do_nothing:
\calc_error:N#1
\fi:
\fi:
@@ -524,33 +620,33 @@
% \begin{macro}{\calc_divide:N}
% The switches for multiplication and division.
% \begin{macrocode}
-\def_new:Npn \calc_multiply:N #1{
- \if_meaning:NN \calc_maxmin_operation:Nnn #1
- \let:NN \calc_next:w \calc_maxmin_multiply:
+\cs_new_nopar:Npn \calc_multiply:N #1{
+ \if_meaning:w \calc_maxmin_operation:Nnn #1
+ \cs_set_eq:NN \calc_next:w \calc_maxmin_multiply:
\else:
- \if_meaning:NN \calc_ratio_multiply:nn #1
- \let:NN \calc_next:w \calc_ratio_multiply:nn
+ \if_meaning:w \calc_ratio_multiply:nn #1
+ \cs_set_eq:NN \calc_next:w \calc_ratio_multiply:nn
\else:
- \if_meaning:NN \calc_real_evaluate:nn #1
- \let:NN \calc_next:w \calc_real_multiply:n
+ \if_meaning:w \calc_real_evaluate:nn #1
+ \cs_set_eq:NN \calc_next:w \calc_real_multiply:n
\else:
- \def:Npn \calc_next:w{\calc_multiply: #1}
+ \cs_set_nopar:Npn \calc_next:w{\calc_multiply: #1}
\fi:
\fi:
\fi:
\calc_next:w
}
-\def_new:Npn \calc_divide:N #1{
- \if_meaning:NN \calc_maxmin_operation:Nnn #1
- \let:NN \calc_next:w \calc_maxmin_divide:
+\cs_new_nopar:Npn \calc_divide:N #1{
+ \if_meaning:w \calc_maxmin_operation:Nnn #1
+ \cs_set_eq:NN \calc_next:w \calc_maxmin_divide:
\else:
- \if_meaning:NN \calc_ratio_multiply:nn #1
- \let:NN \calc_next:w \calc_ratio_divide:nn
+ \if_meaning:w \calc_ratio_multiply:nn #1
+ \cs_set_eq:NN \calc_next:w \calc_ratio_divide:nn
\else:
- \if_meaning:NN \calc_real_evaluate:nn #1
- \let:NN \calc_next:w \calc_real_divide:n
+ \if_meaning:w \calc_real_evaluate:nn #1
+ \cs_set_eq:NN \calc_next:w \calc_real_divide:n
\else:
- \def:Npn \calc_next:w{\calc_divide: #1}
+ \cs_set_nopar:Npn \calc_next:w{\calc_divide: #1}
\fi:
\fi:
\fi:
@@ -560,26 +656,26 @@
% \end{macro}
% \end{macro}
%
-% \begin{macro}{\calc_generic_add:N}
+% \begin{macro}{\calc_generic_add_or_subtract:N}
% \begin{macro}{\calc_add:}
% \begin{macro}{\calc_subtract:}
% \begin{macro}{\calc_add_A_to_B:}
% \begin{macro}{\calc_subtract_A_from_B:}
% Here is how we add and subtract.
% \begin{macrocode}
-\def_new:Npn\calc_generic_add_or_subtract:N#1{
+\cs_new_nopar:Npn\calc_generic_add_or_subtract:N#1{
\group_end:
\pref_global:D\g_calc_A_register\l_calc_B_register\group_end:
\group_begin:\group_execute_after:N#1\group_begin:
\group_execute_after:N\calc_init_B:
\calc_pre_scan:N}
-\def_new:Npn\calc_add:{\calc_generic_add_or_subtract:N\calc_add_A_to_B:}
-\def_new:Npn\calc_subtract:{
+\cs_new_nopar:Npn\calc_add:{\calc_generic_add_or_subtract:N\calc_add_A_to_B:}
+\cs_new_nopar:Npn\calc_subtract:{
\calc_generic_add_or_subtract:N\calc_subtract_A_from_B:}
% \end{macrocode}
% Don't use |\tex_advance:D| since it allows overflows.
% \begin{macrocode}
-\def_new:Npn\calc_add_A_to_B:{
+\cs_new_nopar:Npn\calc_add_A_to_B:{
\l_calc_B_register
\if_case:w\l_calc_current_type_int
\etex_numexpr:D\or:
@@ -588,7 +684,7 @@
\etex_muexpr:D\fi:
\l_calc_B_register + \g_calc_A_register\scan_stop:
}
-\def_new:Npn\calc_subtract_A_from_B:{
+\cs_new_nopar:Npn\calc_subtract_A_from_B:{
\l_calc_B_register
\if_case:w\l_calc_current_type_int
\etex_numexpr:D\or:
@@ -613,15 +709,15 @@
% primitive \TeX{} operations but the expandable operations provided
% by \eTeX. This means that all results are rounded not truncated!
% \begin{macrocode}
-\def_new:Npn\calc_generic_multiply_or_divide:N#1{
+\cs_new_nopar:Npn\calc_generic_multiply_or_divide:N#1{
\group_end:
\group_begin:
- \let:NN\g_calc_A_register\g_calc_A_int
- \let:NN\l_calc_B_register\l_calc_B_int
+ \cs_set_eq:NN\g_calc_A_register\g_calc_A_int
+ \cs_set_eq:NN\l_calc_B_register\l_calc_B_int
\int_zero:N \l_calc_current_type_int
\group_execute_after:N#1\calc_pre_scan:N
}
-\def_new:Npn\calc_multiply_B_by_A:{
+\cs_new_nopar:Npn\calc_multiply_B_by_A:{
\l_calc_B_register
\if_case:w\l_calc_current_type_int
\etex_numexpr:D\or:
@@ -630,7 +726,7 @@
\etex_muexpr:D\fi:
\l_calc_B_register*\g_calc_A_int\scan_stop:
}
-\def_new:Npn\calc_divide_B_by_A:{
+\cs_new_nopar:Npn\calc_divide_B_by_A:{
\l_calc_B_register
\if_case:w\l_calc_current_type_int
\etex_numexpr:D\or:
@@ -639,9 +735,9 @@
\etex_muexpr:D\fi:
\l_calc_B_register/\g_calc_A_int\scan_stop:
}
-\def_new:Npn\calc_multiply:{
+\cs_new_nopar:Npn\calc_multiply:{
\calc_generic_multiply_or_divide:N\calc_multiply_B_by_A:}
-\def_new:Npn\calc_divide:{
+\cs_new_nopar:Npn\calc_divide:{
\calc_generic_multiply_or_divide:N\calc_divide_B_by_A:}
% \end{macrocode}
% \end{macro}
@@ -651,19 +747,19 @@
% \end{macro}
%
% \begin{macro}{\calc_calculate_box_size:nnn}
-% \begin{macro}{\calc_calculate_box_size_aux:n}
+% \begin{macro}[aux]{\calc_calculate_box_size_aux:n}
% Put something in a box and measure it. |#1| is a list of
% |\box_ht:N| etc., |#2| should be |\dim_set:Nn|\meta{dim register}
% or |\dim_gset:Nn|\meta{dim register} and |#3| is the contents.
% \begin{macrocode}
-\def_long_new:Npn \calc_calculate_box_size:nnn #1#2#3{
+\cs_new:Npn \calc_calculate_box_size:nnn #1#2#3{
\hbox_set:Nn \l_tmpa_box {{#3}}
- #2{\c_zero_dim \tlist_map_function:nN{#1}\calc_calculate_box_size_aux:n}
+ #2{\c_zero_dim \tl_map_function:nN{#1}\calc_calculate_box_size_aux:n}
}
% \end{macrocode}
% Helper for calculating the final dimension.
% \begin{macrocode}
-\def:Npn \calc_calculate_box_size_aux:n#1{ + #1\l_tmpa_box}
+\cs_set_nopar:Npn \calc_calculate_box_size_aux:n#1{ + #1\l_tmpa_box}
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -672,12 +768,12 @@
% \begin{macro}{\calc_textsize:Nn}
% Now we can define |\calc_textsize:Nn|.
% \begin{macrocode}
-\def_protected_long:Npn \calc_textsize:Nn#1#2{
+\cs_set_protected:Npn \calc_textsize:Nn#1#2{
\group_begin:
- \let:NN\calc_widthof_aux:n\box_wd:N
- \let:NN\calc_heightof_aux:n\box_ht:N
- \let:NN\calc_depthof_aux:n\box_dp:N
- \def:Npn\calc_totalheightof_aux:n{\box_ht:N\box_dp:N}
+ \cs_set_eq:NN\calc_widthof_aux:n\box_wd:N
+ \cs_set_eq:NN\calc_heightof_aux:n\box_ht:N
+ \cs_set_eq:NN\calc_depthof_aux:n\box_dp:N
+ \cs_set_nopar:Npn\calc_totalheightof_aux:n{\box_ht:N\box_dp:N}
\exp_args:No\calc_calculate_box_size:nnn{#1}
{\dim_gset:Nn\g_calc_A_register}
% \end{macrocode}
@@ -685,10 +781,10 @@
% call.
% \begin{macrocode}
{
- \let:NN \calc_depthof_aux:n \calc_depthof_auxi:n
- \let:NN \calc_widthof_aux:n \calc_widthof_auxi:n
- \let:NN \calc_heightof_aux:n \calc_heightof_auxi:n
- \let:NN \calc_totalheightof_aux:n \calc_totalheightof_auxi:n
+ \cs_set_eq:NN \calc_depthof_aux:n \calc_depthof_auxi:n
+ \cs_set_eq:NN \calc_widthof_aux:n \calc_widthof_auxi:n
+ \cs_set_eq:NN \calc_heightof_aux:n \calc_heightof_auxi:n
+ \cs_set_eq:NN \calc_totalheightof_aux:n \calc_totalheightof_auxi:n
#2
}
\group_end:
@@ -703,7 +799,7 @@
% register, the ratio is probably also done with this type and we'll
% have to convert them to regular points.
% \begin{macrocode}
-\def_protected_long:Npn\calc_ratio_multiply:nn#1#2{
+\cs_set_protected:Npn\calc_ratio_multiply:nn#1#2{
\group_end:\group_begin:
\if_num:w\l_calc_current_type_int < \c_three
\calc_dim_set:Nn\l_calc_B_int{#1}
@@ -715,7 +811,7 @@
% \end{macrocode}
% Then store the ratio as a fraction, which we just pass on.
% \begin{macrocode}
- \gdef:Npx\calc_calculated_ratio:{
+ \cs_gset_nopar:Npx\calc_calculated_ratio:{
\int_use:N\l_calc_B_int/\int_use:N\l_calc_C_int
}
\group_end:
@@ -738,7 +834,7 @@
% \end{macrocode}
% Division is just flipping the arguments around.
% \begin{macrocode}
-\def_long_new:Npn \calc_ratio_divide:nn#1#2{\calc_ratio_multiply:nn{#2}{#1}}
+\cs_new:Npn \calc_ratio_divide:nn#1#2{\calc_ratio_multiply:nn{#2}{#1}}
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -750,7 +846,7 @@
% |\ratio|, this is horribly inefficient since we just want to convert
% the decimal to a fraction.
% \begin{macrocode}
-\def_protected_new:Npn\calc_real_evaluate:nn #1#2{
+\cs_new_protected_nopar:Npn\calc_real_evaluate:nn #1#2{
\group_end:
\l_calc_B_register
\if_case:w\l_calc_current_type_int
@@ -764,8 +860,8 @@
\scan_stop:
\group_begin:
\calc_post_scan:N}
-\def_new:Npn \calc_real_multiply:n #1{\calc_real_evaluate:nn{#1}{1}}
-\def_new:Npn \calc_real_divide:n {\calc_real_evaluate:nn{1}}
+\cs_new_nopar:Npn \calc_real_multiply:n #1{\calc_real_evaluate:nn{#1}{1}}
+\cs_new_nopar:Npn \calc_real_divide:n {\calc_real_evaluate:nn{1}}
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -778,7 +874,7 @@
% \begin{macro}{\calc_maxmin_multiply:}
% The max and min functions.
% \begin{macrocode}
-\def_protected_long:Npn\calc_maxmin_operation:Nnn#1#2#3{
+\cs_set_protected:Npn\calc_maxmin_operation:Nnn#1#2#3{
\group_begin:
\calc_maxmin_generic:Nnn#1{#2}{#3}
\group_end:
@@ -787,7 +883,7 @@
% \end{macrocode}
% |#1| is either |>| or |<| and was expanded into this initially.
% \begin{macrocode}
-\def_protected_long_new:Npn \calc_maxmin_generic:Nnn#1#2#3{
+\cs_new_protected:Npn \calc_maxmin_generic:Nnn#1#2#3{
\group_begin:
\if_case:w\l_calc_current_type_int
\calc_int_set:Nn\l_calc_C_int{#2}%
@@ -816,7 +912,7 @@
\fi:
\group_end:
}
-\def_long_new:Npn\calc_maxmin_div_or_mul:NNnn#1#2#3#4{
+\cs_new:Npn\calc_maxmin_div_or_mul:NNnn#1#2#3#4{
\group_end:
\group_begin:
\int_zero:N\l_calc_current_type_int
@@ -826,9 +922,9 @@
\group_begin:
\calc_post_scan:N
}
-\def_new:Npn\calc_maxmin_multiply:{
+\cs_new_nopar:Npn\calc_maxmin_multiply:{
\calc_maxmin_div_or_mul:NNnn\calc_multiply_B_by_A:}
-\def_new:Npn\calc_maxmin_divide: {
+\cs_new_nopar:Npn\calc_maxmin_divide: {
\calc_maxmin_div_or_mul:NNnn\calc_divide_B_by_A:}
% \end{macrocode}
% \end{macro}
@@ -840,9 +936,9 @@
% \begin{macro}{\calc_error:N}
% The error message.
% \begin{macrocode}
-\def_new:Npn\calc_error:N#1{
+\cs_new_nopar:Npn\calc_error:N#1{
\PackageError{calc}
- {`\token_to_string:N#1'~ invalid~ at~ this~ point}
+ {`\token_to_str:N#1'~ invalid~ at~ this~ point}
{I~ expected~ to~ see~ one~ of:~ +~ -~ *~ /~ )}
}
% \end{macrocode}
@@ -858,14 +954,14 @@
% \begin{macro}{\minof}
% Max and min operations
% \begin{macrocode}
-\def_long_new:Npn \calc_maxof:nn#1#2{
+\cs_new:Npn \calc_maxof:nn#1#2{
\calc_maxmin_operation:Nnn > \exp_not:n{{#1}{#2}}
}
-\def_long_new:Npn \calc_minof:nn#1#2{
+\cs_new:Npn \calc_minof:nn#1#2{
\calc_maxmin_operation:Nnn < \exp_not:n{{#1}{#2}}
}
-\let:NN \maxof \calc_maxof:nn
-\let:NN \minof \calc_minof:nn
+\cs_set_eq:NN \maxof \calc_maxof:nn
+\cs_set_eq:NN \minof \calc_minof:nn
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -873,47 +969,47 @@
% \end{macro}
%
% \begin{macro}{\calc_widthof:n}
-% \begin{macro}{\calc_widthof_aux:n}
-% \begin{macro}{\calc_widthof_auxi:n}
+% \begin{macro}[aux]{\calc_widthof_aux:n}
+% \begin{macro}[aux]{\calc_widthof_auxi:n}
% \begin{macro}{\calc_heightof:n}
-% \begin{macro}{\calc_heightof_aux:n}
-% \begin{macro}{\calc_heightof_auxi:n}
+% \begin{macro}[aux]{\calc_heightof_aux:n}
+% \begin{macro}[aux]{\calc_heightof_auxi:n}
% \begin{macro}{\calc_depthof:n}
-% \begin{macro}{\calc_depthof_aux:n}
-% \begin{macro}{\calc_depthof_auxi:n}
+% \begin{macro}[aux]{\calc_depthof_aux:n}
+% \begin{macro}[aux]{\calc_depthof_auxi:n}
% \begin{macro}{\calc_totalheightof:n}
-% \begin{macro}{\calc_totalheightof_aux:n}
-% \begin{macro}{\calc_totalheightof_auxi:n}
+% \begin{macro}[aux]{\calc_totalheightof_aux:n}
+% \begin{macro}[aux]{\calc_totalheightof_auxi:n}
% Text dimension commands.
% \begin{macrocode}
-\def_long_new:Npn \calc_widthof:n#1{
+\cs_new:Npn \calc_widthof:n#1{
\calc_textsize:Nn \exp_not:N\calc_widthof_aux:n\exp_not:n{{#1}}
}
-\def_long_new:Npn \calc_heightof:n#1{
+\cs_new:Npn \calc_heightof:n#1{
\calc_textsize:Nn \exp_not:N\calc_heightof_aux:n\exp_not:n{{#1}}
}
-\def_long_new:Npn \calc_depthof:n#1{
+\cs_new:Npn \calc_depthof:n#1{
\calc_textsize:Nn \exp_not:N\calc_depthof_aux:n\exp_not:n{{#1}}
}
-\def_long_new:Npn \calc_totalheightof:n#1{
+\cs_new:Npn \calc_totalheightof:n#1{
\calc_textsize:Nn \exp_not:N\calc_totalheightof_aux:n \exp_not:n{{#1}}
}
-\def_long_new:Npn \calc_widthof_aux:n #1{
+\cs_new:Npn \calc_widthof_aux:n #1{
\exp_not:N\calc_widthof_aux:n\exp_not:n{{#1}}
}
-\let_new:NN \calc_widthof_auxi:n \calc_widthof_aux:n
-\def_long_new:Npn \calc_depthof_aux:n #1{
+\cs_new_eq:NN \calc_widthof_auxi:n \calc_widthof_aux:n
+\cs_new:Npn \calc_depthof_aux:n #1{
\exp_not:N\calc_depthof_aux:n\exp_not:n{{#1}}
}
-\let_new:NN \calc_depthof_auxi:n \calc_depthof_aux:n
-\def_long_new:Npn \calc_heightof_aux:n #1{
+\cs_new_eq:NN \calc_depthof_auxi:n \calc_depthof_aux:n
+\cs_new:Npn \calc_heightof_aux:n #1{
\exp_not:N\calc_heightof_aux:n\exp_not:n{{#1}}
}
-\let_new:NN \calc_heightof_auxi:n \calc_heightof_aux:n
-\def_long_new:Npn \calc_totalheightof_aux:n #1{
+\cs_new_eq:NN \calc_heightof_auxi:n \calc_heightof_aux:n
+\cs_new:Npn \calc_totalheightof_aux:n #1{
\exp_not:N\calc_totalheightof_aux:n\exp_not:n{{#1}}
}
-\let_new:NN \calc_totalheightof_auxi:n \calc_totalheightof_aux:n
+\cs_new_eq:NN \calc_totalheightof_auxi:n \calc_totalheightof_aux:n
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -932,9 +1028,9 @@
% \begin{macro}{\calc_real:n}
% Ratio and real.
% \begin{macrocode}
-\def_long_new:Npn \calc_ratio:nn#1#2{
+\cs_new:Npn \calc_ratio:nn#1#2{
\calc_ratio_multiply:nn\exp_not:n{{#1}{#2}}}
-\def_new:Npn \calc_real:n {\calc_real_evaluate:nn}
+\cs_new_nopar:Npn \calc_real:n {\calc_real_evaluate:nn}
% \end{macrocode}
% We can implement real and ratio without actually using these
% names. We'll see.
@@ -951,12 +1047,12 @@
% \begin{macro}{\real}
% User commands.
% \begin{macrocode}
-\let:NN \depthof\calc_depthof:n
-\let:NN \widthof\calc_widthof:n
-\let:NN \heightof\calc_heightof:n
-\let:NN \totalheightof\calc_totalheightof:n
-%%\let:NN \ratio\calc_ratio:nn
-%%\let:NN \real\calc_real:n
+\cs_set_eq:NN \depthof\calc_depthof:n
+\cs_set_eq:NN \widthof\calc_widthof:n
+\cs_set_eq:NN \heightof\calc_heightof:n
+\cs_set_eq:NN \totalheightof\calc_totalheightof:n
+%%\cs_set_eq:NN \ratio\calc_ratio:nn
+%%\cs_set_eq:NN \real\calc_real:n
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -970,10 +1066,10 @@
% \begin{macro}{\addtolength}
% \begin{macro}{\gaddtolength}
% \begin{macrocode}
-\def_protected:Npn \setlength{\calc_skip_set:Nn}
-\def_protected:Npn \gsetlength{\calc_skip_gset:Nn}
-\def_protected:Npn \addtolength{\calc_skip_add:Nn}
-\def_protected:Npn \gaddtolength{\calc_skip_gadd:Nn}
+\cs_set_protected_nopar:Npn \setlength{\calc_skip_set:Nn}
+\cs_set_protected_nopar:Npn \gsetlength{\calc_skip_gset:Nn}
+\cs_set_protected_nopar:Npn \addtolength{\calc_skip_add:Nn}
+\cs_set_protected_nopar:Npn \gaddtolength{\calc_skip_gadd:Nn}
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -992,44 +1088,67 @@
% |\mathchoice| will no longer need this switch as the argument is
% only executed once.
% \begin{macrocode}
+%</initex|package>
+%<*package>
\newif\iffirstchoice@ \firstchoice@true
-\def_protected:Npn \calc_setcounter:nn#1#2{
+%</package>
+%<*initex|package>
+\cs_set_protected_nopar:Npn \calc_setcounter:nn#1#2{
\calc_chk_document_counter:nn{#1}{
\exp_args:Nc\calc_int_gset:Nn {c@#1}{#2}
}
}
-\def_protected:Npn \calc_addtocounter:nn#1#2{
+\cs_set_protected_nopar:Npn \calc_addtocounter:nn#1#2{
+%</initex|package>
+%<*package>
\iffirstchoice@
+%</package>
+%<*initex|package>
\calc_chk_document_counter:nn{#1}{
\exp_args:Nc\calc_int_gadd:Nn {c@#1}{#2}
}
+%</initex|package>
+%<*package>
\fi:
+%</package>
+%<*initex|package>
}
-\def_protected:Npn \calc_stepcounter:n#1{
+\cs_set_protected_nopar:Npn \calc_stepcounter:n#1{
+%</initex|package>
+%<*package>
\iffirstchoice@
+%</package>
+%<*initex|package>
\calc_chk_document_counter:nn{#1}{
\int_gincr:c {c@#1}
\group_begin:
- \let:NN \@elt\@stpelt \cs_use:c{cl@#1}
+ \cs_set_eq:NN \@elt\@stpelt \use:c{cl@#1}
\group_end:
}
+%</initex|package>
+%<*package>
\fi:
+%</package>
+%<*initex|package>
}
-\def_new:Npn \calc_chk_document_counter:nn#1{
+\cs_new_nopar:Npn \calc_chk_document_counter:nn#1{
\cs_if_free:cTF{c@#1}{\@nocounterr {#1}}
}
-\let:NN \setcounter \calc_setcounter:nn
-\let:NN \addtocounter \calc_addtocounter:nn
-\let:NN \stepcounter \calc_stepcounter:n
+\cs_set_eq:NN \setcounter \calc_setcounter:nn
+\cs_set_eq:NN \addtocounter \calc_addtocounter:nn
+\cs_set_eq:NN \stepcounter \calc_stepcounter:n
+%</initex|package>
+%<*package>
\AtBeginDocument{
- \let:NN \setcounter \calc_setcounter:nn
- \let:NN \addtocounter \calc_addtocounter:nn
- \let:NN \stepcounter \calc_stepcounter:n
+ \cs_set_eq:NN \setcounter \calc_setcounter:nn
+ \cs_set_eq:NN \addtocounter \calc_addtocounter:nn
+ \cs_set_eq:NN \stepcounter \calc_stepcounter:n
}
% \end{macrocode}
% Prevent the usual \textsf{calc} from loading.
% \begin{macrocode}
-%<package>\def:cpn{ver@calc.sty}{2005/08/06}
+\cs_set_nopar:cpn{ver@calc.sty}{2005/08/06}
+%</package>
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -1038,22 +1157,14 @@
% \end{macro}
% \end{macro}
% \end{macro}
-%
-%
+%
% \begin{macrocode}
-%</initex|package>
%<*showmemory>
\showMemUsage
%</showmemory>
% \end{macrocode}
%
-% \endinput
-%
-% $Log$
-% Revision 1.2 2006/01/27 23:11:47 morten
-% Fixed bug in \calc_pre_scan:N and avoid using \advance in order to
-% catch overflows.
-%
-% Revision 1.1 2006/01/27 07:51:13 morten
-% Initial version of a calc module
+% \end{implementation}
+% \PrintIndex
%
+% \endinput
diff --git a/Master/texmf-dist/source/latex/expl3/l3chk.dtx b/Master/texmf-dist/source/latex/expl3/l3chk.dtx
index 281ba7bc1cc..ad016f91c91 100644
--- a/Master/texmf-dist/source/latex/expl3/l3chk.dtx
+++ b/Master/texmf-dist/source/latex/expl3/l3chk.dtx
@@ -1,5 +1,5 @@
% \iffalse
-%% File: l3chk.dtx Copyright (C) 1990-2006 LaTeX3 project
+%% File: l3chk.dtx Copyright (C) 1990-2006,2009 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
@@ -17,7 +17,7 @@
%%
%% The development version of the bundle can be found at
%%
-%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/
+%% http://www.latex-project.org/svnroot/experimental/trunk/
%%
%% for those people who are interested.
%%
@@ -36,7 +36,7 @@
\RequirePackage{l3names}
%</driver|package>
%\fi
-\GetIdInfo$Id: l3chk.dtx 621 2007-09-01 20:14:19Z morten $
+\GetIdInfo$Id: l3chk.dtx 1362 2009-05-28 20:19:21Z joseph $
{L3 Experimental check module}
%\iffalse
%<*driver>
@@ -44,7 +44,7 @@
\ProvidesFile{\filename.\filenameext}
[\filedate\space v\fileversion\space\filedescription]
%\iffalse
-\documentclass{l3doc}
+\documentclass[full]{l3doc}
\begin{document}
\DocInput{\filename.\filenameext}
\end{document}
@@ -59,17 +59,27 @@
% \date{\filedate}
% \maketitle
%
-% \section{The chk module}
+% \begin{documentation}
%
% To ensure that functions and variables are properly used certain
% checking functions are implemented that may or may not be compiled
% into the final format.
%
-% \subsection{Functions}
+% \section{Tracing}
+%
+% \begin{function}{\tracingall |
+% \absolutelytracingall |
+% \donotcheck |
+% \tracingoff |
+% \traceon |
+% \traceoff }
+% Commands to control the level of verbosity in the tracing output.
+% \end{function}
+%
+% \section{Functions}
%
% \begin{function}{%
% \chk_var_or_const:N |
-% \chk_var_or_const:c |
% }
% \begin{syntax}
% "\chk_var_or_const:N" <cs>
@@ -80,9 +90,7 @@
%
% \begin{function}{%
% \chk_local:N |
-% \chk_local:c |
% \chk_global:N |
-% \chk_global:c |
% }
% \begin{syntax}
% "\chk_local:N" <cs>
@@ -108,40 +116,26 @@
% "\chk_local_or_pref_global:N" inside some function "\foo_bar:n" we can
% implement a global version "\foo_gbar:n" by defining
% \begin{quote}
-% "\def_new:Npn \foo_gbar:n {\pref_global_chk: \foo_bar:n }"
+% "\cs_new_nopar:Npn \foo_gbar:n {\pref_global_chk: \foo_bar:n }"
% \end{quote}
% provided that "\foo_bar:n" is built in a way that prefixing it with
% "\pref_global:D" turns its operation into a global one. See
% implementation for details.
% \end{function}
%
-% \subsection{Constants}
-%
-% \begin{variable}{\c_undefined}
-% This constant is always undefined and therefore can be used to check
-% for free function names.
-% \end{variable}
-%
-% \subsection{Internal functions}
-%
-% \begin{function}{%
-% \chk_global_aux:w |
-% \chk_local_aux:w |
-% \chk_var_or_const_aux:w |
-% }
-% Helper functions that implement the checking.
-% \end{function}
+% \end{documentation}
%
-% \StopEventually{}
+% \begin{implementation}
%
-% \subsection{The Implementation}
+% \section{\pkg{l3chk} implementation}
%
% We start by ensuring that the required packages are loaded.
% \begin{macrocode}
-%<package>\ProvidesExplPackage
-%<package> {\filename}{\filedate}{\fileversion}{\filedescription}
-%<package>\RequirePackage{l3basics}
-%<package>\RequirePackage{l3int,l3prg}
+%<*package>
+\ProvidesExplPackage
+ {\filename}{\filedate}{\fileversion}{\filedescription}
+\package_check_loaded_expl:
+%</package>
%<*initex|package>
% \end{macrocode}
%
@@ -150,10 +144,10 @@
% too badly. All these functions are of type `{\tt e}' since they
% issue error messages if certain conditions are violated.
%
-% \subsubsection{Checking variable assignments}
+% \subsection{Checking variable assignments}
%
% \begin{macro}{\chk_local:N}
-% \begin{macro}{\chk_local_aux:w}
+% \begin{macro}[aux]{\chk_local_aux:w}
% This function checks that its argument is a proper local
% variable, i.e.\ its name starts with |\l| or |\L|.
% It is not allowed that the name starts with |\g| or |\G|,
@@ -166,18 +160,18 @@
% during the implementation since it will find certain errors
% involving wrong expansion in earlier stage.
% \begin{macrocode}
-\def_new:Npn \chk_local:N #1{
- \exp_after:NN \chk_local_aux:w \token_to_string:N#1\q_stop}
+\cs_new_nopar:Npn \chk_local:N #1{
+ \exp_after:wN \chk_local_aux:w \token_to_str:N#1\q_stop}
-\def_new:Npn \chk_local_aux:w #1#2#3\q_stop{
+\cs_new_nopar:Npn \chk_local_aux:w #1#2#3\q_stop{
\if_num:w\tex_uccode:D`#2=`G\scan_stop:
- \err_latex_bug:x{Local~mismatch:~local~function~called~with~
+ \msg_kernel_bug:x {Local~mismatch:~local~function~called~with~
global~variable:^^J\text_put_four_sp: #1#2#3~
on~line~\tex_the:D\tex_inputlineno:D}
\else:
\if_num:w\tex_uccode:D`#2=`L\scan_stop:
\else:
- \err_latex_bug:x{Variable~mismatch:~function~not~called~with~
+ \msg_kernel_bug:x {Variable~mismatch:~function~not~called~with~
proper~variable:^^J\text_put_four_sp: #1#2#3~
on~line~\tex_the:D\tex_inputlineno:D}\fi:
\fi:}
@@ -191,21 +185,21 @@
% \end{macro}
%
% \begin{macro}{\chk_global:N}
-% \begin{macro}{\chk_global_aux:w}
+% \begin{macro}[aux]{\chk_global_aux:w}
% |\chk_global:N| is similar to |\chk_local:N| but looks only
% for global variables.
% \begin{macrocode}
-\def_new:Npn \chk_global:N #1{\exp_after:NN
- \chk_global_aux:w \token_to_string:N#1\q_stop}
-\def_new:Npn \chk_global_aux:w #1#2#3\q_stop{
+\cs_new_nopar:Npn \chk_global:N #1{\exp_after:wN
+ \chk_global_aux:w \token_to_str:N#1\q_stop}
+\cs_new_nopar:Npn \chk_global_aux:w #1#2#3\q_stop{
\if_num:w\tex_uccode:D`#2=`L\scan_stop:
- \err_latex_bug:x{Global~mismatch:~global~function~called~with~
+ \msg_kernel_bug:x {Global~mismatch:~global~function~called~with~
local~variable:~#1#2#3~
on~line~\tex_the:D\tex_inputlineno:D}
\else:
\if_num:w\tex_uccode:D`#2=`G\scan_stop:
\else:
- \err_latex_bug:x{Variable~mismatch:~function~not~called~with~
+ \msg_kernel_bug:x {Variable~mismatch:~function~not~called~with~
proper~variable:~#1#2#3~
on~line~\tex_the:D\tex_inputlineno:D}\fi:\fi:}
% \end{macrocode}
@@ -218,7 +212,7 @@
% |\pref_global:D| without loosing the possibility to check for the
% correct type of a variable, the following helper functions can be
% used: |\chk_local_or_pref_global:N| \m{variable} is the variable
-% check which is usually |\let:NN| to |\chk_local:N|, i.e.\ it will
+% check which is usually |\cs_set_eq:NN| to |\chk_local:N|, i.e.\ it will
% check for local variables. This behavior will be changed by
% |\pref_global_chk:|. This function first changes
% |\chk_local_or_pref_global:N| to check for global variables, then
@@ -228,7 +222,7 @@
% inside some function |\foo_bar:n| we can implement a global
% version |\foo_gbar:n| by defining
% \begin{verbatim}
-% \def_new:Npn \foo_gbar:n {\pref_global_chk: \foo_bar:n }
+% \cs_new_nopar:Npn \foo_gbar:n {\pref_global_chk: \foo_bar:n }
%\end{verbatim}
% provided of course, that |\foo_bar:n| is defined in a way that a
% |\pref_global:D| does work. Such a scheme has to be used
@@ -237,25 +231,25 @@
% |\pref_global_chk:| into |\pref_global:D| and omit the
% |\chk_local_or_pref_global:N| function in the body.
% \begin{macrocode}
-\def_new:Npn \pref_global_chk: {
- \gdef:Npn \chk_local_or_pref_global:N ##1{
+\cs_new_nopar:Npn \pref_global_chk: {
+ \cs_gset_nopar:Npn \chk_local_or_pref_global:N ##1{
\chk_global:N ##1
- \glet:NN \chk_local_or_pref_global:N \chk_local:N}
+ \cs_gset_eq:NN \chk_local_or_pref_global:N \chk_local:N}
\pref_global:D}
-\let_new:NN \chk_local_or_pref_global:N \chk_local:N
+\cs_new_eq:NN \chk_local_or_pref_global:N \chk_local:N
% \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\chk_var_or_const:N}
-% \begin{macro}{\chk_var_or_const_aux:w}
+% \begin{macro}[aux]{\chk_var_or_const_aux:w}
% |\chk_var_or_const:N| is used in situations where we want to check
% that we have a variable (or a constant) but do not care whether
% or not it is global (for example, in allocation routines).
% \begin{macrocode}
-\def_new:Npn \chk_var_or_const:N #1{\exp_after:NN
- \chk_var_or_const_aux:w \token_to_string:N#1\q_stop }
-\def_new:Npn \chk_var_or_const_aux:w #1#2#3\q_stop {
+\cs_new_nopar:Npn \chk_var_or_const:N #1{\exp_after:wN
+ \chk_var_or_const_aux:w \token_to_str:N#1\q_stop }
+\cs_new_nopar:Npn \chk_var_or_const_aux:w #1#2#3\q_stop {
\if_num:w\tex_uccode:D`#2=`L\scan_stop:
\else:
\if_num:w\tex_uccode:D`#2=`G\scan_stop:
@@ -273,7 +267,7 @@
% could check this by testing that there is no |_|, but this is not
% implemented so far.
% \begin{macrocode}
- \err_latex_bug:x{Variable~mismatch:~function~not~called~with~
+ \msg_kernel_bug:x {Variable~mismatch:~function~not~called~with~
proper~variable:^^J\text_put_four_sp: #1#2#3~
on~line~\tex_the:D\tex_inputlineno:D}\fi:\fi:\fi:
\fi:}
@@ -282,7 +276,7 @@
% \end{macro}
%
%
-% \subsubsection{Doing some tracing}
+% \subsection{Doing some tracing}
%
% \begin{macro}{\tracingall}
% \begin{macro}{\absolutelytracingall}
@@ -292,20 +286,20 @@
% probably wrong. Therefore this definition of it turns the
% functions of as far as possible.
% \begin{macrocode}
-\def_new:Npn\donotcheck{
- \let:NN \chk_global:N \use_none:n
- \let:NN \chk_local:N \use_none:n
- \let:NN \chk_local_or_pref_global:N \use_none:n
- \let:NN \pref_global_chk: \pref_global:D
- \let:NN \chk_new_cs:N \use_none:n
- \let:NN \chk_exist_cs:N \use_none:n
- \let:NN \chk_var_or_const:N \use_none:n
- \let:NN \cs_record_name:N \use_none:n
- \let:NN \cs_record_name:c \use_none:n
- \let:NN \cs_record_meaning:N \use_none:n
- \let:NN \register_record_name:N \use_none:n
+\cs_new_nopar:Npn\donotcheck{
+ \cs_set_eq:NN \chk_global:N \use_none:n
+ \cs_set_eq:NN \chk_local:N \use_none:n
+ \cs_set_eq:NN \chk_local_or_pref_global:N \use_none:n
+ \cs_set_eq:NN \pref_global_chk: \pref_global:D
+ \cs_set_eq:NN \chk_if_free_cs:N \use_none:n
+ \cs_set_eq:NN \chk_exist_cs:N \use_none:n
+ \cs_set_eq:NN \chk_var_or_const:N \use_none:n
+ \cs_set_eq:NN \cs_record_name:N \use_none:n
+ \cs_set_eq:NN \cs_record_name:c \use_none:n
+ \cs_set_eq:NN \cs_record_meaning:N \use_none:n
+ \cs_set_eq:NN \register_record_name:N \use_none:n
}
-\def_new:Npn\absolutelytracingall{
+\cs_new_nopar:Npn\absolutelytracingall{
% \end{macrocode}
% \end{macro}
%
@@ -326,7 +320,7 @@
\tex_errorstopmode:D}
%
% Use LaTeX2e definition for now.
-%\def_new:Npn\tracingall{
+%\cs_new_nopar:Npn\tracingall{
% \donotcheck
% \absolutelytracingall
%}
@@ -337,7 +331,7 @@
% \begin{macro}{\tracingoff}
% This macro turns off all tracing.
% \begin{macrocode}
-\def_new:Npn\tracingoff{
+\cs_new_nopar:Npn\tracingoff{
% \end{macrocode}
% First we turn off |\g_trace_online_status| so that we get minimal
% rubbish on the terminal. Of course, in the log file all
@@ -358,28 +352,28 @@
% \end{macrocode}
% \end{macro}
%
-% \subsubsection{Tracing modules}
+% \subsection{Tracing modules}
%
% \begin{macro}{\traceon}
% \begin{macro}{\traceoff}
% Turning the tracing of modules on or off. (primitive version).
% \begin{macrocode}
%<*trace>
-\def_new:Npn\traceon#1{
+\cs_new_nopar:Npn\traceon#1{
\clist_map_inline:nn {#1}{
- \cs_free:cF{g_trace_ ##1 _status}
+ \cs_if_free:cF{g_trace_ ##1 _status}
{\int_gincr:c{g_trace_ ##1 _status}}
}
}
-\def_new:Npn\traceoff#1{
+\cs_new_nopar:Npn\traceoff#1{
\clist_map_inline:nn {#1}{
- \cs_free:cF{g_trace_ ##1 _status}
+ \cs_if_free:cF{g_trace_ ##1 _status}
{\int_gdecr:c{g_trace_ ##1 _status}}
}
}
%</trace>
-%<-trace>\let_new:NN\traceon\use_none:n
-%<-trace>\let_new:NN\traceoff\use_none:n
+%<-trace>\cs_new_eq:NN\traceon\use_none:n
+%<-trace>\cs_new_eq:NN\traceoff\use_none:n
%</initex|package>
% \end{macrocode}
% \end{macro}
@@ -393,22 +387,7 @@
%</showmemory>
% \end{macrocode}
%
-% \endinput
-%
-% $Log$
-% Revision 1.14 2006/03/20 18:26:34 braams
-% Updated the copyright notice (2006) and demoted all implementation
-% sections to subsections and so on to clean up the toc for source3.tex
-%
-% Revision 1.13 2005/12/27 09:58:01 morten
-% Minor changes plus changed RCS information retrieval
-%
-% Revision 1.12 2005/04/12 12:07:53 morten
-% Removed unnecessary functions
-%
-% Revision 1.11 2005/03/15 23:31:54 braams
-% Some fiddling with docstrip guards for initex use
-%
-% Revision 1.10 2005/03/11 21:33:31 braams
-% Fixed the use of RCS information
+% \end{implementation}
+% \PrintIndex
%
+% \endinput
diff --git a/Master/texmf-dist/source/latex/expl3/l3clist.dtx b/Master/texmf-dist/source/latex/expl3/l3clist.dtx
index 0155c64f394..f875b7e0cbc 100644
--- a/Master/texmf-dist/source/latex/expl3/l3clist.dtx
+++ b/Master/texmf-dist/source/latex/expl3/l3clist.dtx
@@ -1,5 +1,5 @@
% \iffalse
-%% File: l3clist.dtx Copyright (C) 2005-2006 Frank Mittelbach, LaTeX3 project
+%% File: l3clist.dtx Copyright (C) 2005-2008 Frank Mittelbach, 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
@@ -17,7 +17,7 @@
%%
%% The development version of the bundle can be found at
%%
-%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/
+%% http://www.latex-project.org/svnroot/experimental/trunk/
%%
%% for those people who are interested.
%%
@@ -36,7 +36,7 @@
\RequirePackage{l3names}
%</driver|package>
%\fi
-\GetIdInfo$Id: l3clist.dtx 745 2008-08-03 18:50:46Z morten $
+\GetIdInfo$Id: l3clist.dtx 1362 2009-05-28 20:19:21Z joseph $
{L3 Experimental comma separated lists}
%\iffalse
%<*driver>
@@ -44,7 +44,7 @@
\ProvidesFile{\filename.\filenameext}
[\filedate\space v\fileversion\space\filedescription]
%\iffalse
-\documentclass{l3doc}
+\documentclass[full]{l3doc}
\begin{document}
\DocInput{\filename.\filenameext}
\end{document}
@@ -61,9 +61,7 @@
% \date{\filedate}
% \maketitle
%
-%
-%
-% \section{Comma lists}
+% \begin{documentation}
%
% \LaTeX3 implements a data type called `clist (comma-lists)'. These
% are special
@@ -75,8 +73,8 @@
% part of the value). It is also possible to map functions on such
% comma-lists so that they are executed for every item of the comma-list.
%
-% All functions that return items from a comma-list in some \m{tlp} assume
-% that the \m{tlp} is local. See remarks below if you need a global
+% All functions that return items from a comma-list in some \m{tl var.}~assume
+% that the \m{tl var.}~is local. See remarks below if you need a global
% returned value.
%
% The defined functions are not orthogonal in the sense that every
@@ -89,7 +87,7 @@
% like "\clist_push:Nn" which has the same effect. Maybe one should
% therefore remove the ``left'' functions totally.
%
-% \subsection{Functions}
+% \section{Functions for creating/initialising comma-lists}
%
% \begin{function}{%
% \clist_new:N |
@@ -113,117 +111,153 @@
% These functions locally or globally clear <comma-list>.
% \end{function}
%
+% \begin{function}{ \clist_clear_new:N |
+% \clist_clear_new:c |
+% \clist_gclear_new:N |
+% \clist_gclear_new:c }
+% \begin{syntax}
+% "\clist_clear_new:N" <comma-list>
+% \end{syntax}
+% These functions locally or globally clear <comma-list> if it exists or
+% otherwise allocates it.
+% \end{function}
+%
+% \begin{function}{ \clist_set_eq:NN |
+% \clist_set_eq:cN |
+% \clist_set_eq:Nc |
+% \clist_set_eq:cc }
+% \begin{syntax}
+% "\clist_set_eq:NN" <clist1> <clist2>
+% \end{syntax}
+% Function that locally makes <clist1> identical to <clist2>.
+% \end{function}
+%
+%
+% \begin{function}{ \clist_gset_eq:NN |
+% \clist_gset_eq:cN |
+% \clist_gset_eq:Nc |
+% \clist_gset_eq:cc }
+% \begin{syntax}
+% "\clist_gset_eq:NN" <clist1> <clist2>
+% \end{syntax}
+% Function that globally makes <clist1> identical to <clist2>.
+% \end{function}
+%
+% \section{Putting data in}
+%
% \begin{function}{%
% \clist_put_left:Nn |
+% \clist_put_left:NV |
% \clist_put_left:No |
% \clist_put_left:Nx |
% \clist_put_left:cn |
-% \clist_put_right:Nn |
-% \clist_put_right:No |
-% \clist_put_right:Nx |
+% \clist_put_left:co |
+% \clist_put_left:cV |
% }
% \begin{syntax}
% "\clist_put_left:Nn" <comma-list> <token list>
% \end{syntax}
% Locally appends <token list> as a single item to the left
-% or right of <comma-list>. <token list> might get expanded before
-% appending.
+% of <comma-list>. <token list> might get expanded before
+% appending according to the variant used.
% \end{function}
%
% \begin{function}{%
-% \clist_gput_left:Nn |
-% \clist_gput_right:Nn |
-% \clist_gput_right:No |
-% \clist_gput_right:cn |
-% \clist_gput_right:co |
-% \clist_gput_right:cc |
+% \clist_put_right:Nn |
+% \clist_put_right:No |
+% \clist_put_right:NV |
+% \clist_put_right:Nx |
+% \clist_put_right:cn |
+% \clist_put_right:co |
+% \clist_put_right:cV |
% }
% \begin{syntax}
-% "\clist_gput_left:Nn" <comma-list> <token list>
+% "\clist_put_right:Nn" <comma-list> <token list>
% \end{syntax}
-% Globally appends <token list> as a single item to the left
-% or right of <comma-list>.
+% Locally appends <token list> as a single item to the right
+% of <comma-list>. <token list> might get expanded before
+% appending according to the variant used.
% \end{function}
%
% \begin{function}{%
-% \clist_get:NN |
-% \clist_get:cN |
+% \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 |
% }
% \begin{syntax}
-% "\clist_get:NN" <comma-list> <tlp>
+% "\clist_gput_left:Nn" <comma-list> <token list>
% \end{syntax}
-% Functions that locally assign the left-most item of <comma-list> to the
-% token list pointer <tlp>. Item is not removed from <comma-list>! If you
-% need a global return value you need to code something like this:
-% \begin{quote}
-% "\clist_get:NN" <comma-list> "\l_tmpa_tlp" \\
-% "\tlp_gset_eq:NN" <global tlp> "\l_tmpa_tlp"
-% \end{quote}
-% But if this kind of construction is used often enough a separate
-% function should be provided.
+% Globally appends <token list> as a single item to the
+% right of <comma-list>.
% \end{function}
%
% \begin{function}{%
-% \clist_set_eq:NN
+% \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 |
% }
% \begin{syntax}
-% "\clist_set_eq:NN" <clist1> <clist2>
+% "\clist_gput_right:Nn" <comma-list> <token list>
% \end{syntax}
-% Function that locally makes <clist1> identical to <clist2>.
+% Globally appends <token list> as a single item to the
+% right of <comma-list>.
% \end{function}
%
+% \section{Getting data out}
%
-% \begin{function}{%
-% \clist_gset_eq:NN |
-% \clist_gset_eq:cN |
-% \clist_gset_eq:Nc |
-% \clist_gset_eq:cc
-% }
+% \begin{function}{ \clist_use:N |
+% \clist_use:c }
% \begin{syntax}
-% "\clist_gset_eq:NN" <clist1> <clist2>
+% "\clist_use:N" <clist>
% \end{syntax}
-% Function that globally makes <clist1> identical to <clist2>.
+% Function that inserts the <clist> into the processing stream. Mainly
+% useful if one knows what the <clist> contains, e.g., for displaying
+% the content of template parameters.
% \end{function}
%
-%
-% \begin{function}{%
-% \clist_concat:NNN |
-% \clist_gconcat:NNN |
-% \clist_gconcat:NNc |
-% \clist_gconcat:ccc |
-% }
+% \begin{function}{ \clist_show:N |
+% \clist_show:c }
% \begin{syntax}
-% "\clist_gconcat:NNN" <clist1> <clist2> <clist3>
+% "\clist_show:N" <clist>
% \end{syntax}
-% Function that concatenates <clist2> and <clist3> and globally assigns the
-% result to <clist1>.
+% Function that pauses the compilation and displays <clist> in the terminal
+% output and in the log file. (Usually used for diagnostic purposes.)
% \end{function}
%
-%
-% \begin{function}{%
-% \clist_remove_duplicates:N |
-% \clist_gremove_duplicates:N |
-% }
+% \begin{function}{ \clist_display:N |
+% \clist_display:c }
% \begin{syntax}
-% "\clist_gremove_duplicates:N" <clist>
+% "\clist_display:N" <clist>
% \end{syntax}
-% Function that removes any duplicate entries in <clist>.
+% As with "\clist_show:N" but pretty prints the output one line per element.
% \end{function}
%
-% \begin{function}{%
-% \clist_use:N |
-% \clist_use:c
-% }
+% \begin{function}{ \clist_get:NN |
+% \clist_get:cN }
% \begin{syntax}
-% "\clist_use:N" <clist>
+% "\clist_get:NN" <comma-list> <tl var.>
% \end{syntax}
-% Function that inserts the <clist> into the processing stream. Mainly
-% useful if one knows what the <clist> contains, e.g., for displaying
-% the content of template parameters.
+% Functions that locally assign the left-most item of <comma-list> to the
+% token list variable <tl var.>. Item is not removed from <comma-list>! If you
+% need a global return value you need to code something like this:
+% \begin{quote}
+% "\clist_get:NN" <comma-list> "\l_tmpa_tl" \\
+% "\tl_gset_eq:NN" <global tl var.> "\l_tmpa_tl"
+% \end{quote}
+% But if this kind of construction is used often enough a separate
+% function should be provided.
% \end{function}
%
%
-% \subsection{Mapping functions}
+% \section{Mapping functions}
%
%
% We provide three types of mapping functions, each with their own
@@ -253,7 +287,7 @@
% \clist_map_inline:nn |
% }
% \begin{syntax}
-% "\clist_map_inline:Nn" <comma-list> "{" <inline function> "}"
+% "\clist_map_inline:Nn" <comma-list> \Arg{inline function}
% \end{syntax}
% Applies <inline function> (which should be the direct coding for a
% function with one argument (i.e.\ use "##1" as the placeholder for
@@ -269,7 +303,7 @@
% \clist_map_variable:nNn |
% }
% \begin{syntax}
-% "\clist_map_variable:NNn" <comma-list> <temp-var> "{" <action> "}"
+% "\clist_map_variable:NNn" <comma-list> <temp-var> \Arg{action}
% \end{syntax}
% Assigns <temp-var> to each element in <clist> and then executes
% <action> which should contain <temp-var>. As the
@@ -281,16 +315,16 @@
% \end{function}
%
% \begin{function}{%
-% \clist_map_break:w |
+% \clist_map_break: |
% }
% \begin{syntax}
-% "\clist_map_break:w"
+% "\clist_map_break:"
% \end{syntax}
% For breaking out of a loop. To be used inside "TF" type functions as
% in the example below.
% \begin{verbatim}
-% \def_new:Npn \test_function:n #1 {
-% \int_compare:nNnTF {#1}> 3 {\clist_map_break:w}{``#1''}
+% \cs_new_nopar:Npn \test_function:n #1 {
+% \intexpr_compare:nTF {#1 > 3} {\clist_map_break:}{``#1''}
% }
% \clist_map_function:nN {1,2,3,4,5,6,7,8}\test_function:n
% \end{verbatim}
@@ -298,9 +332,10 @@
% \end{function}
%
%
-% \subsection{Predicates and conditionals}
+% \section{Predicates and conditionals}
%
-% \begin{function}{\clist_if_empty_p:N}
+% \begin{function}{ \clist_if_empty_p:N |
+% \clist_if_empty_p:c }
% \begin{syntax}
% "\clist_if_empty_p:N" <comma-list>
% \end{syntax}
@@ -308,99 +343,87 @@
% contain any tokens.
% \end{function}
%
-% \begin{function}{%
-% \clist_if_empty:NTF |
-% \clist_if_empty:cTF |
-% \clist_if_empty:NF |
-% \clist_if_empty:cF |
-% }
+% \begin{function}{ \clist_if_empty:N / (TF)(EXP) |
+% \clist_if_empty:c / (TF)(EXP)}
% \begin{syntax}
-% "\clist_if_empty:NTF" <comma-list> "{" <true code> "}{" <false code> "}"
+% "\clist_if_empty:NTF" <comma-list> \Arg{true code} \Arg{false code}
% \end{syntax}
% Set of conditionals that test whether or not a particular <comma-list>
% is empty and if so executes either <true code> or <false code>.
% \end{function}
%
-% \begin{function}{%
-% \clist_if_eq:NNTF |
-% }
+% \begin{function}{ \clist_if_eq_p:NN / (EXP) |
+% \clist_if_eq_p:cN / (EXP) |
+% \clist_if_eq_p:Nc / (EXP) |
+% \clist_if_eq_p:cc / (EXP) }
% \begin{syntax}
-% "\clist_if_eq:NNTF" <comma-list1> <comma-list2> "{" <true code>
-% "}{" <false code> "}"
+% "\clist_if_eq_p:N" <comma-list1> <comma-list2>
+% \end{syntax}
+% This predicate returns `true' if the two comma lists are identical.
+% \end{function}
+%
+% \begin{function}{ \clist_if_eq:NN / (TF)(EXP) |
+% \clist_if_eq:cN / (TF)(EXP) |
+% \clist_if_eq:Nc / (TF)(EXP) |
+% \clist_if_eq:cc / (TF)(EXP) }
+% \begin{syntax}
+% "\clist_if_eq:NNTF" <comma-list1> <comma-list2> \Arg{true code} \Arg{false code}
% \end{syntax}
% Check if <comma-list1> and <comma-list2> are equal and execute
% either <true code> or <false code> accordingly.
% \end{function}
%
-% \begin{function}{%
-% \clist_if_in:NnTF |
-% \clist_if_in:NoTF |
-% \clist_if_in:cnTF |
-% \clist_if_in:coTF |
-% }
+% \begin{function}{ \clist_if_in:Nn / (TF) |
+% \clist_if_in:NV / (TF) |
+% \clist_if_in:No / (TF) |
+% \clist_if_in:cn / (TF) |
+% \clist_if_in:cV / (TF) |
+% \clist_if_in:co / (TF) }
% \begin{syntax}
-% "\clist_if_in:NnTF" <comma-list> "{" <item> "}{" <true code> "}{"
-% <false code> "}"
+% "\clist_if_in:NnTF" <comma-list> \Arg{item} \Arg{true code} \Arg{false code}
% \end{syntax}
% Function that tests if <item> is in <comma-list>. Depending on the result
% either <true code> or <false code> is executed.
% \end{function}
%
-% \subsection{Internal functions}
+% \section{Higher level functions}
%
-% \begin{function}{\clist_if_empty_err:N}
+% \begin{function}{ \clist_concat:NNN |
+% \clist_concat:ccc |
+% \clist_gconcat:NNN |
+% \clist_gconcat:ccc }
% \begin{syntax}
-% "\clist_if_empty_err:N" <comma-list>
+% "\clist_gconcat:NNN" <clist1> <clist2> <clist3>
% \end{syntax}
-% Signals an \LaTeX3 error if <comma-list> is empty.
+% Function that concatenates <clist2> and <clist3> and locally or globally
+% assigns the result to <clist1>.
% \end{function}
%
-% \begin{function}{\clist_pop_aux:nnNN}
+%
+% \begin{function}{ \clist_remove_duplicates:N |
+% \clist_gremove_duplicates:N }
% \begin{syntax}
-% "\clist_pop_aux:nnNN" <assign1> <assign2> <comma-list> <tlp>
+% "\clist_gremove_duplicates:N" <clist>
% \end{syntax}
-% Function that assigns the left-most item of <comma-list> to <tlp> using
-% <assign1> and assigns the tail to <comma-list> using <assign2>. This
-% function could be used to implement a global return function.
+% Function that removes any duplicate entries in <clist>.
% \end{function}
-%
-% \begin{function}{%
-% \clist_get_aux:w |
-% \clist_pop_aux:w |
-% \clist_pop_auxi:w |
-% \clist_put_aux:NNnnNn |
-% }
-% \begin{syntax}\end{syntax}
-% Functions used to implement put and get operations. They are not for
-% meant for direct use.
+%
+% \begin{function}{
+% \clist_remove_element:Nn |
+% \clist_gremove_element:Nn
+%}
+% \begin{syntax}
+% "\clist_gremove_element:Nn" <clist> <element>
+% \end{syntax}
+% Function that removes <element> from <clist>, if present.
+% \begin{texnote}
+% This is similar in concept to \cs{@removeelement}, except that the
+% syntax is clearer and the initial and final lists have the same
+% name automatically.
+% \end{texnote}
% \end{function}
%
-%
-%
-% \begin{function}{%
-% \clist_map_function_aux:Nw |
-% \clist_map_inline_aux:Nw |
-% \clist_map_variable_aux:Nnw |
-% }
-% \begin{syntax}\end{syntax}
-% Internal helper functions for the <clist> mapping functions.
-% \end{function}
-%
-%
-% \begin{function}{%
-% \clist_concat_aux:NNNN |
-% \clist_remove_duplicates_aux:NN |
-% \clist_remove_duplicates_aux:n |
-% \l_clist_remove_duplicates_clist |
-% }
-% \begin{syntax}\end{syntax}
-% Functions that help concatenate <clist>s and remove duplicate
-% elements from a <clist>.
-% \end{function}
-%
-%
-%
-% \subsection{Comma list Stacks}
+% \section{Functions for `comma-list stacks'}
%
% Special comma-lists in \LaTeX3 are `stacks' with their usual operations
% of `push', `pop', and `top'. They are internally implemented as
@@ -409,14 +432,16 @@
%
% \begin{function}{%
% \clist_push:Nn |
+% \clist_push:NV |
% \clist_push:No |
% \clist_push:cn |
% \clist_gpush:Nn |
+% \clist_gpush:NV |
% \clist_gpush:No |
% \clist_gpush:cn |
% }
% \begin{syntax}
-% "\clist_push:Nn" <stack> "{" <token list> "}"
+% "\clist_push:Nn" <stack> \Arg{token list}
% \end{syntax}
% Locally or globally pushes <token list> as a single item onto the
% <stack>. <token list> might get expanded before the operation.
@@ -429,10 +454,10 @@
% \clist_gpop:cN |
% }
% \begin{syntax}
-% "\clist_pop:NN" <stack> <tlp>
+% "\clist_pop:NN" <stack> <tl var.>
% \end{syntax}
% Functions that assign the top item of <stack> to the token
-% list pointer <tlp> and removes it from <stack>!
+% list variable <tl var.> and removes it from <stack>!
% \end{function}
%
% \begin{function}{%
@@ -440,38 +465,65 @@
% \clist_top:cN |
% }
% \begin{syntax}
-% "\clist_top:NN" <stack> <tlp>
+% "\clist_top:NN" <stack> <tl var.>
% \end{syntax}
% Functions that locally assign the top item of <stack> to the token
-% list pointer <tlp>. Item is not removed from <stack>!
+% list variable <tl var.>. Item is not removed from <stack>!
% \end{function}
%
-% \StopEventually{}
+% \section{Internal functions}
%
-% Use "clist" functions.
+% \begin{function}{\clist_if_empty_err:N}
+% \begin{syntax}
+% "\clist_if_empty_err:N" <comma-list>
+% \end{syntax}
+% Signals an \LaTeX3 error if <comma-list> is empty.
+% \end{function}
%
+% \begin{function}{\clist_pop_aux:nnNN}
+% \begin{syntax}
+% "\clist_pop_aux:nnNN" <assign1> <assign2> <comma-list> <tl var.>
+% \end{syntax}
+% Function that assigns the left-most item of <comma-list> to <tl var.> using
+% <assign1> and assigns the tail to <comma-list> using <assign2>. This
+% function could be used to implement a global return function.
+% \end{function}
%
-% \subsection {The Implementation}
+% \begin{function}{%
+% \clist_get_aux:w |
+% \clist_pop_aux:w |
+% \clist_pop_auxi:w |
+% \clist_put_aux:NNnnNn |
+% }
+% \begin{syntax}\end{syntax}
+% Functions used to implement put and get operations. They are not for
+% meant for direct use.
+% \end{function}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3clist} implementation}
%
% We start by ensuring that the required packages are loaded.
% \begin{macrocode}
-%<package>\ProvidesExplPackage
-%<package> {\filename}{\filedate}{\fileversion}{\filedescription}
%<*package>
-\NeedsTeXFormat{LaTeX2e}
-%<!check>\RequirePackage{l3prg,l3quark}
-%<check>\RequirePackage{l3chk}
+\ProvidesExplPackage
+ {\filename}{\filedate}{\fileversion}{\filedescription}
+\package_check_loaded_expl:
%</package>
%<*initex|package>
% \end{macrocode}
%
+% \subsection{Allocation and initialisation}
%
% \begin{macro}{\clist_new:N}
% \begin{macro}{\clist_new:c}
% Comma-Lists are implemented using token lists.
% \begin{macrocode}
-\def_new:Npn \clist_new:N #1{\tlp_new:Nn #1{}}
-\def_new:Npn \clist_new:c {\exp_args:Nc \clist_new:N}
+\cs_new_eq:NN \clist_new:N \tl_new:N
+\cs_generate_variant:Nn \clist_new:N {c}
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -482,10 +534,10 @@
% \begin{macro}{\clist_gclear:c}
% Clearing a comma-list is the same as clearing a token list.
% \begin{macrocode}
-\let_new:NN \clist_clear:N \tlp_clear:N
-\let_new:NN \clist_clear:c \tlp_clear:c
-\let_new:NN \clist_gclear:N \tlp_gclear:N
-\let_new:NN \clist_gclear:c \tlp_gclear:c
+\cs_new_eq:NN \clist_clear:N \tl_clear:N
+\cs_generate_variant:Nn \clist_clear:N {c}
+\cs_new_eq:NN \clist_gclear:N \tl_gclear:N
+\cs_generate_variant:Nn \clist_gclear:N {c}
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -493,24 +545,32 @@
% \end{macro}
%
%
-% \begin{macro}{\clist_set_eq:NN}
-% We can set one \meta{clist} equal to another.
+% \begin{macro}{\clist_clear_new:N}
+% \begin{macro}{\clist_clear_new:c}
+% \begin{macro}{\clist_gclear_new:N}
+% \begin{macro}{\clist_gclear_new:c}
+% Clearing a comma-list is the same as clearing a token list.
% \begin{macrocode}
-\let_new:NN \clist_set_eq:NN \let:NN
+\cs_new_eq:NN \clist_clear_new:N \tl_clear_new:N
+\cs_generate_variant:Nn \clist_clear_new:N {c}
+\cs_new_eq:NN \clist_gclear_new:N \tl_gclear_new:N
+\cs_generate_variant:Nn \clist_gclear_new:N {c}
% \end{macrocode}
% \end{macro}
-%
+% \end{macro}
+% \end{macro}
+% \end{macro}
%
% \begin{macro}{\clist_set_eq:NN}
% \begin{macro}{\clist_set_eq:cN}
% \begin{macro}{\clist_set_eq:Nc}
% \begin{macro}{\clist_set_eq:cc}
-% An of course globally which seems to be needed far more often.
+% We can set one \meta{clist} equal to another.
% \begin{macrocode}
-\let_new:NN \clist_gset_eq:NN \glet:NN
-\def_new:Npn \clist_gset_eq:cN {\exp_args:Nc \clist_gset_eq:NN}
-\def_new:Npn \clist_gset_eq:Nc {\exp_args:NNc \clist_gset_eq:NN}
-\def_new:Npn \clist_gset_eq:cc {\exp_args:Ncc \clist_gset_eq:NN}
+\cs_new_eq:NN \clist_set_eq:NN \cs_set_eq:NN
+\cs_new_eq:NN \clist_set_eq:cN \cs_set_eq:cN
+\cs_new_eq:NN \clist_set_eq:Nc \cs_set_eq:Nc
+\cs_new_eq:NN \clist_set_eq:cc \cs_set_eq:cc
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -518,33 +578,30 @@
% \end{macro}
%
%
-% \begin{macro}{\clist_if_empty_p:N}
-% A predicate which evaluates to |\c_true| iff the comma-list is empty.
-% \begin{macrocode}
-\let_new:NN \clist_if_empty_p:N \tlp_if_empty_p:N
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\clist_if_empty:NTF}
-% \begin{macro}{\clist_if_empty:NT}
-% \begin{macro}{\clist_if_empty:NF}
-% \begin{macro}{\clist_if_empty:cTF}
-% \begin{macro}{\clist_if_empty:cT}
-% \begin{macro}{\clist_if_empty:cF}
-% |\clist_if_empty:NTF|\m{clist}\m{true~case}\m{false~case} will check
-% whether the \m{clist} is empty and then select one of the other
-% arguments. |\clist_if_empty:cTF| turns its first argument into a
-% control comma-list to get the name of the comma-list.
+% \begin{macro}{\clist_gset_eq:NN}
+% \begin{macro}{\clist_gset_eq:cN}
+% \begin{macro}{\clist_gset_eq:Nc}
+% \begin{macro}{\clist_gset_eq:cc}
+% An of course globally which seems to be needed far more often.
% \begin{macrocode}
-\def_test_function_new:npn {clist_if_empty:N}#1{\if_meaning:NN#1\c_empty_tlp}
-\def_new:Npn \clist_if_empty:cTF {\exp_args:Nc\clist_if_empty:NTF}
-\def_new:Npn \clist_if_empty:cT {\exp_args:Nc\clist_if_empty:NT}
-\def_new:Npn \clist_if_empty:cF {\exp_args:Nc\clist_if_empty:NF}
+\cs_new_eq:NN \clist_gset_eq:NN \cs_gset_eq:NN
+\cs_new_eq:NN \clist_gset_eq:cN \cs_gset_eq:cN
+\cs_new_eq:NN \clist_gset_eq:Nc \cs_gset_eq:Nc
+\cs_new_eq:NN \clist_gset_eq:cc \cs_gset_eq:cc
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
+%
+% \subsection{Predicates and conditionals}
+%
+% \begin{macro}{\clist_if_empty_p:N,\clist_if_empty_p:c}
+% \begin{macro}[TF]{\clist_if_empty:N,\clist_if_empty:c}
+% \begin{macrocode}
+\prg_new_eq_conditional:NNn \clist_if_empty:N \tl_if_empty:N {p,TF,T,F}
+\prg_new_eq_conditional:NNn \clist_if_empty:c \tl_if_empty:c {p,TF,T,F}
+% \end{macrocode}
% \end{macro}
% \end{macro}
%
@@ -552,154 +609,257 @@
% \begin{macro}{\clist_if_empty_err:N}
% Signals an error if the comma-list is empty.
% \begin{macrocode}
-\def_new:Npn \clist_if_empty_err:N #1{
- \if_meaning:NN#1\c_empty_tlp
- \tlp_clear:N \l_testa_tlp % catch prefixes
- \err_latex_bug:x{Empty~comma-list~`\token_to_string:N#1'}
- \fi:}
+\cs_new_nopar:Npn \clist_if_empty_err:N #1 {
+ \if_meaning:w #1 \c_empty_tl
+ \tl_clear:N \l_testa_tl % catch prefixes
+ \msg_kernel_bug:x {Empty~comma-list~`\token_to_str:N #1'}
+ \fi:
+}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\clist_if_eq:NNTF}
-% As comma lists are token list pointers internally this is just an
-% alias.
+% \begin{macro}{\clist_if_eq_p:NN,\clist_if_eq_p:Nc,
+% \clist_if_eq_p:cN,\clist_if_eq_p:cc}
+% \begin{macro}[TF]{\clist_if_eq:NN,\clist_if_eq:cN,
+% \clist_if_eq:Nc,\clist_if_eq:cc}
+% Returns |\c_true| iff the two comma-lists are equal.
% \begin{macrocode}
-\let_new:NN \clist_if_eq:NNTF \tlp_if_eq:NNTF
+\prg_new_eq_conditional:NNn \clist_if_eq:NN \tl_if_eq:NN {p,TF,T,F}
+\prg_new_eq_conditional:NNn \clist_if_eq:cN \tl_if_eq:cN {p,TF,T,F}
+\prg_new_eq_conditional:NNn \clist_if_eq:Nc \tl_if_eq:Nc {p,TF,T,F}
+\prg_new_eq_conditional:NNn \clist_if_eq:cc \tl_if_eq:cc {p,TF,T,F}
% \end{macrocode}
-% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[TF]{\clist_if_in:Nn}
+% \begin{macro}[TF]{\clist_if_in:NV,\clist_if_in:No,\clist_if_in:cn,
+% \clist_if_in:cV,\clist_if_in:co}
+% |\clist_if_in:NnTF| \m{clist}\m{item} \m{true~case} \m{false~case}
+% will check whether \m{item} is in \m{clist} and then either execute
+% the \m{true~case} or the \m{false~case}. \m{true~case} and
+% \m{false~case} may contain incomplete |\if_charcode:w|
+% statements.
+% \begin{macrocode}
+\prg_new_conditional:Nnn \clist_if_in:Nn {TF,T,F} {
+ \cs_set: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
+}
+% \end{macrocode}
+% \begin{macrocode}
+\cs_generate_variant:Nn \clist_if_in:NnTF {NV,No,cn,cV,co}
+\cs_generate_variant:Nn \clist_if_in:NnT {NV,No,cn,cV,co}
+\cs_generate_variant:Nn \clist_if_in:NnF {NV,No,cn,cV,co}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+%
+% \subsection{Retrieving data}
+%
+% \begin{macro}{\clist_use:N}
+% \begin{macro}{\clist_use:c}
+% Using a \meta{clist} is just executing it but
+% if \m{clist} equals |\scan_stop:| it is probably stemming
+% from a |\cs:w ... \cs_end:| that was created by mistake somewhere.
+% \begin{macrocode}
+\cs_new_nopar:Npn \clist_use:N #1 {
+ \if_meaning:w #1 \scan_stop:
+ \msg_kernel_bug:x {
+ Comma~list~ `\token_to_str:N #1'~ has~ an~ erroneous~ structure!}
+ \else:
+ \exp_after:wN #1
+ \fi:
+}
+\cs_generate_variant:Nn \clist_use:N {c}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
%
% \begin{macro}{\clist_get:NN}
% \begin{macro}{\clist_get:cN}
-% |\clist_get:NN |\zz{comma-list}\zz{cmd} defines \zz{cmd} to be the
-% left-most element of \zz{comma-list}.
+% \begin{macro}{\clist_get_aux:w}
+% |\clist_get:NN |\meta{comma-list}\meta{cmd} defines \meta{cmd} to be the
+% left-most element of \meta{comma-list}.
% \begin{macrocode}
-\def_new:Npn \clist_get:NN #1{
+\cs_new_nopar:Npn \clist_get:NN #1 {
\clist_if_empty_err:N #1
- \exp_after:NN\clist_get_aux:w #1,\q_stop}
+ \exp_after:wN \clist_get_aux:w #1,\q_stop
+}
% \end{macrocode}
% \begin{macrocode}
-\def_new:Npn \clist_get_aux:w #1,#2\q_stop #3{\tlp_set:Nn #3{#1}}
+\cs_new:Npn \clist_get_aux:w #1,#2\q_stop #3 { \tl_set:Nn #3{#1} }
% \end{macrocode}
% \begin{macrocode}
-\def_new:Npn \clist_get:cN {\exp_args:Nc \clist_get:NN}
+\cs_generate_variant:Nn \clist_get:NN {cN}
% \end{macrocode}
% \end{macro}
% \end{macro}
+% \end{macro}
%
% \begin{macro}{\clist_pop_aux:nnNN}
% \begin{macro}{\clist_pop_aux:w}
% \begin{macro}{\clist_pop_auxi:w}
-% |\clist_pop_aux:nnNN| \zz{def$\sb1$} \zz{def$\sb2$} \zz{comma-list}
-% \zz{cmd} assigns the left-most element of \zz{comma-list} to
-% \zz{cmd} using \zz{def$\sb2$}, and assigns the tail of
-% \zz{comma-list} to \zz{comma-list} using \zz{def$\sb1$}.
+% |\clist_pop_aux:nnNN| \meta{def$\sb1$} \meta{def$\sb2$} \meta{comma-list}
+% \meta{cmd} assigns the left-most element of \meta{comma-list} to
+% \meta{cmd} using \meta{def$\sb2$}, and assigns the tail of
+% \meta{comma-list} to \meta{comma-list} using \meta{def$\sb1$}.
% \begin{macrocode}
-\def_new:Npn \clist_pop_aux:nnNN #1#2#3{
+\cs_new:Npn \clist_pop_aux:nnNN #1#2#3 {
\clist_if_empty_err:N #3
- \exp_after:NN\clist_pop_aux:w #3,\q_nil\q_stop #1#2#3}
+ \exp_after:wN \clist_pop_aux:w #3,\q_nil\q_stop #1#2#3
+}
% \end{macrocode}
+% After the assignmnets below, if there was only one element in the original
+% clist, it now contains only |\q_nil|.
% \begin{macrocode}
-\def_new:Npn \clist_pop_aux:w #1,#2\q_stop #3#4#5#6{
- #4#6{#1}
- #3#5{#2}
+\cs_new:Npn \clist_pop_aux:w #1,#2\q_stop #3#4#5#6 {
+ #4 #6 {#1}
+ #3 #5 {#2}
+ \quark_if_nil:NTF #5 { #3 #5 {} }{ \clist_pop_auxi:w #2 #3#5 }
+}
% \end{macrocode}
-% If there was only one element in the original clist, it now contains
-% only |\q_nil|.
% \begin{macrocode}
- \quark_if_nil:NTF #5
- { #3#5{} }
- { \clist_pop_auxi:w #2 #3#5 }
-}
+\cs_new:Npn \clist_pop_auxi:w #1,\q_nil #2#3 { #2#3{#1} }
% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\clist_show:N}
+% \begin{macro}{\clist_show:c}
% \begin{macrocode}
-\def_new:Npn\clist_pop_auxi:w #1,\q_nil #2#3 {#2#3{#1}}
+\cs_new_eq:NN \clist_show:N \tl_show:N
+\cs_new_eq:NN \clist_show:c \tl_show:c
% \end{macrocode}
% \end{macro}
% \end{macro}
+%
+% \begin{macro}{\clist_display:N}
+% \begin{macro}{\clist_display:c}
+% \begin{macrocode}
+\cs_new_nopar:Npn \clist_display:N #1 {
+ \iow_term:x { Comma-list~\token_to_str:N #1~contains~
+ the~elements~(without~outer~braces): }
+ \toks_clear:N \l_tmpa_toks
+ \clist_map_inline:Nn #1 {
+ \toks_if_empty:NF \l_tmpa_toks {
+ \toks_put_right:Nx \l_tmpa_toks {^^J>~}
+ }
+ \toks_put_right:Nx \l_tmpa_toks {
+ \iow_space: \iow_char:N \{ \exp_not:n {##1} \iow_char:N \}
+ }
+ }
+ \toks_show:N \l_tmpa_toks
+}
+\cs_generate_variant:Nn \clist_display:N {c}
+% \end{macrocode}
+% \end{macro}
% \end{macro}
%
+% \subsection{Storing data}
+%
% \begin{macro}{\clist_put_aux:NNnnNn}
% The generic put function.
-% \begin{macrocode}
-\def_new:Npn \clist_put_aux:NNnnNn #1#2#3#4#5#6{
-% \end{macrocode}
% When adding we have to distinguish between an empty \meta{clist}
% and one that contains at least one item (otherwise we accumulate
% commas).
-% \begin{macrocode}
- \clist_if_empty:NTF#5 {#1 #5{#6}}
-% \end{macrocode}
+%
% MH says: Perhaps we should make sure that empty arguments don't get
% on the stack as that is probably a mistake. That's what I've
-% implemented here. Since |\tlist_if_empty:nF| is expandable prefixes
+% implemented here. Since |\tl_if_empty:nF| is expandable prefixes
% are still allowed.
% \begin{macrocode}
- { \tlist_if_empty:nF {#6}{ #2 #5{#3#6#4} } }
+\cs_new: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} }
+ }
}
% \end{macrocode}
% \end{macro}
+%
% \begin{macro}{\clist_put_left:Nn}
+% \begin{macro}{\clist_put_left:NV}
% \begin{macro}{\clist_put_left:No}
% \begin{macro}{\clist_put_left:Nx}
% \begin{macro}{\clist_put_left:cn}
+% \begin{macro}{\clist_put_left:cV}
+% \begin{macro}{\clist_put_left:co}
% The operations for adding to the left.
% \begin{macrocode}
-\def_new:Npn \clist_put_left:Nn {
- \clist_put_aux:NNnnNn \tlp_set:Nn \tlp_put_left:Nn {} ,
+\cs_new_nopar:Npn \clist_put_left:Nn {
+ \clist_put_aux:NNnnNn \tl_set:Nn \tl_put_left:Nn {} ,
}
-\def_new:Npn \clist_put_left:cn {\exp_args:Nc \clist_put_left:Nn}
-\def_new:Npn \clist_put_left:No {\exp_args:NNo\clist_put_left:Nn}
-\def_new:Npn \clist_put_left:Nx {\exp_args:Nnx\clist_put_left:Nn}
+\cs_generate_variant:Nn \clist_put_left:Nn {NV,No,Nx,cn,cV,co}
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
% \begin{macro}{\clist_gput_left:Nn}
+% \begin{macro}{\clist_gput_left:NV}
+% \begin{macro}{\clist_gput_left:No}
+% \begin{macro}{\clist_gput_left:Nx}
+% \begin{macro}{\clist_gput_left:cn}
+% \begin{macro}{\clist_gput_left:cV}
+% \begin{macro}{\clist_gput_left:co}
% Global versions.
% \begin{macrocode}
-\def_new:Npn \clist_gput_left:Nn {
- \clist_put_aux:NNnnNn \tlp_gset:Nn \tlp_gput_left:Nn {} ,
+\cs_new_nopar:Npn \clist_gput_left:Nn {
+ \clist_put_aux:NNnnNn \tl_gset:Nn \tl_gput_left:Nn {} ,
}
+\cs_generate_variant:Nn \clist_gput_left:Nn {NV,No,Nx,cn,cV,co}
% \end{macrocode}
% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
%
% \begin{macro}{\clist_put_right:Nn}
-% \begin{macro}{\clist_put_right:cn}
+% \begin{macro}{\clist_put_right:NV}
% \begin{macro}{\clist_put_right:No}
% \begin{macro}{\clist_put_right:Nx}
+% \begin{macro}{\clist_put_right:cn}
+% \begin{macro}{\clist_put_right:cV}
+% \begin{macro}{\clist_put_right:co}
% Adding something to the right side is almost the same.
% \begin{macrocode}
-\def_new:Npn \clist_put_right:Nn {
- \clist_put_aux:NNnnNn \tlp_set:Nn \tlp_put_right:Nn , {}
+\cs_new_nopar:Npn \clist_put_right:Nn {
+ \clist_put_aux:NNnnNn \tl_set:Nn \tl_put_right:Nn , {}
}
-\def_new:Npn \clist_put_right:cn {\exp_args:Nc \clist_put_right:Nn}
-\def_new:Npn \clist_put_right:No {\exp_args:Nno\clist_put_right:Nn}
-\def_new:Npn \clist_put_right:Nx {\exp_args:Nnx\clist_put_right:Nn}
+\cs_generate_variant:Nn \clist_put_right:Nn {NV,No,Nx,cn,cV,co}
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
%
% \begin{macro}{\clist_gput_right:Nn}
+% \begin{macro}{\clist_gput_right:NV}
% \begin{macro}{\clist_gput_right:No}
+% \begin{macro}{\clist_gput_right:Nx}
% \begin{macro}{\clist_gput_right:cn}
+% \begin{macro}{\clist_gput_right:cV}
% \begin{macro}{\clist_gput_right:co}
-% \begin{macro}{\clist_gput_right:cc}
-% \begin{macro}{\clist_gput_right:NC}
-% An here the global variants.
+% And here the global variants.
% \begin{macrocode}
-\def_new:Npn \clist_gput_right:Nn {
- \clist_put_aux:NNnnNn \tlp_gset:Nn \tlp_gput_right:Nn , {}
+\cs_new_nopar:Npn \clist_gput_right:Nn {
+ \clist_put_aux:NNnnNn \tl_gset:Nn \tl_gput_right:Nn , {}
}
-\def_new:Npn \clist_gput_right:No {\exp_args:NNo \clist_gput_right:Nn}
-\def_new:Npn \clist_gput_right:cn {\exp_args:Nc \clist_gput_right:Nn}
-\def_new:Npn \clist_gput_right:co {\exp_args:Nco \clist_gput_right:Nn}
-\def_new:Npn \clist_gput_right:cc {\exp_args:Ncc \clist_gput_right:Nn}
-% \end{macrocode}
-% \begin{macrocode}
-\def_new:Npn \clist_gput_right:NC {\exp_args:NNC \clist_gput_right:Nn}
+\cs_generate_variant:Nn \clist_gput_right:Nn {NV,No,Nx,cn,cV,co}
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -707,36 +867,42 @@
% \end{macro}
% \end{macro}
% \end{macro}
+% \end{macro}
+%
+%
+% \subsection{Mapping}
%
-% \begin{macro}{\clist_map_function:nN}
-% \begin{macro}{\clist_map_function:cN}
% \begin{macro}{\clist_map_function:NN}
-% |\clist_map_function:NN| \zz{comma-list} \zz{cmd} applies \zz{cmd} to each
-% element of \zz{comma-list}, from left to right.
+% \begin{macro}{\clist_map_function:cN}
+% \begin{macro}{\clist_map_function:nN}
+% |\clist_map_function:NN| \meta{comma-list} \meta{cmd} applies \meta{cmd} to each
+% element of \meta{comma-list}, from left to right.
% \begin{macrocode}
-\def_new:Npn \clist_map_function:NN #1#2{
- \clist_if_empty:NF #1
- {
- \exp_after:NN \clist_map_function_aux:Nw
- \exp_after:NN #2 #1 , \q_recursion_tail , \q_recursion_stop
+\cs_new_nopar:Npn \clist_map_function:NN #1#2 {
+ \clist_if_empty:NF #1 {
+ \exp_after:wN \clist_map_function_aux:Nw
+ \exp_after:wN #2 #1 , \q_recursion_tail , \q_recursion_stop
}
}
-\def_new:Npn \clist_map_function:cN{\exp_args:Nc\clist_map_function:NN}
-\def_new:Npn \clist_map_function:nN #1#2{
- \tlist_if_blank:nF {#1}
- { \clist_map_function_aux:Nw #2 #1 , \q_recursion_tail , \q_recursion_stop }
+\cs_generate_variant:Nn \clist_map_function:NN {cN}
+% \end{macrocode}
+% \begin{macrocode}
+\cs_new:Npn \clist_map_function:nN #1#2 {
+ \tl_if_blank:nF {#1} {
+ \clist_map_function_aux:Nw #2 #1 , \q_recursion_tail , \q_recursion_stop
+ }
}
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
-% \begin{macro}{\clist_map_function_aux:Nw}
+% \begin{macro}[aux]{\clist_map_function_aux:Nw}
% The general loop. Tests if we hit the first stop marker and exits if
% we did. If we didn't, place the function "#1" in front of the
% element "#2", which is surrounded by braces.
% \begin{macrocode}
-\def_long_new:Npn \clist_map_function_aux:Nw #1#2,{
+\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
@@ -744,11 +910,11 @@
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\clist_map_break:w}
+% \begin{macro}{\clist_map_break:}
% The break statement is easy. Same as in other modules, gobble
% everything up to the special recursion stop marker.
% \begin{macrocode}
-\let_new:NN \clist_map_break:w \use_none_delimit_by_q_recursion_stop:w
+\cs_new_eq:NN \clist_map_break: \use_none_delimit_by_q_recursion_stop:w
% \end{macrocode}
% \end{macro}
%
@@ -769,31 +935,28 @@
% every operation globally.
% \begin{macrocode}
\int_new:N \g_clist_inline_level_int
-\def_long_new:Npn \clist_map_inline:Nn #1#2{
- \clist_if_empty:NF #1
- {
+\cs_new:Npn \clist_map_inline:Nn #1#2 {
+ \clist_if_empty:NF #1 {
\int_gincr:N \g_clist_inline_level_int
- \gdef_long:cpn {clist_map_inline_ \int_use:N \g_clist_inline_level_int :n}
+ \cs_gset:cpn {clist_map_inline_ \int_use:N \g_clist_inline_level_int :n}
##1{#2}
% \end{macrocode}
-% Recall that the |E| in |\exp_args:NcE| means `single token expanded
-% once and no braces added'. It is a lot more efficient to carry over
+% It is a lot more efficient to carry over
% the special function rather than constructing the same csname over
% and over again, so we just do it once. We reuse
% |\clist_map_function_aux:Nw| for the actual loop.
% \begin{macrocode}
- \exp_args:NcE \clist_map_function_aux:Nw
+ \exp_last_unbraced:NcV \clist_map_function_aux:Nw
{clist_map_inline_ \int_use:N \g_clist_inline_level_int :n}
#1 , \q_recursion_tail , \q_recursion_stop
\int_gdecr:N \g_clist_inline_level_int
}
}
-\def_new:Npn \clist_map_inline:cn{\exp_args:Nc\clist_map_inline:Nn}
-\def_long_new:Npn \clist_map_inline:nn #1#2{
- \tlist_if_empty:nF {#1}
- {
+\cs_generate_variant:Nn \clist_map_inline:Nn {c}
+\cs_new:Npn \clist_map_inline:nn #1#2 {
+ \tl_if_empty:nF {#1} {
\int_gincr:N \g_clist_inline_level_int
- \gdef_long:cpn {clist_map_inline_ \int_use:N \g_clist_inline_level_int :n}
+ \cs_gset:cpn {clist_map_inline_ \int_use:N \g_clist_inline_level_int :n}
##1{#2}
\exp_args:Nc \clist_map_function_aux:Nw
{clist_map_inline_ \int_use:N \g_clist_inline_level_int :n}
@@ -810,76 +973,78 @@
% \begin{macro}{\clist_map_variable:nNn}
% \begin{macro}{\clist_map_variable:NNn}
% \begin{macro}{\clist_map_variable:cNn}
-% |\clist_map:NNn| \zz{comma-list} \zz{temp} \zz{action} assigns
-% \zz{temp} to each element and executes \zz{action}.
+% |\clist_map_variable:NNn| \meta{comma-list} \meta{temp} \meta{action} assigns
+% \meta{temp} to each element and executes \meta{action}.
% \begin{macrocode}
-\def_new:Npn \clist_map_variable:nNn #1#2#3{
- \tlist_if_empty:nF{#1}
- {
+\cs_new:Npn \clist_map_variable:nNn #1#2#3 {
+ \tl_if_empty:nF {#1} {
\clist_map_variable_aux:Nnw #2 {#3} #1
, \q_recursion_tail , \q_recursion_stop
}
}
-\def_new:Npn \clist_map_variable:NNn {\exp_args:No \clist_map_variable:nNn}
-\def_new:Npn \clist_map_variable:cNn {\exp_args:Nc \clist_map_variable:NNn}
+% \end{macrocode}
+% Something for v/V
+% \begin{macrocode}
+\cs_new_nopar:Npn \clist_map_variable:NNn {\exp_args:No \clist_map_variable:nNn}
+\cs_generate_variant:Nn\clist_map_variable:NNn {cNn}
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
-% \begin{macro}{\clist_map_variable_aux:Nnw}
+% \begin{macro}[aux]{\clist_map_variable_aux:Nnw}
% The general loop. Assign the temp variable |#1| to the current item
% |#3| and then check if that's the stop marker. If it is, break the
% loop. If not, execute the action |#2| and continue.
% \begin{macrocode}
-\def_new:Npn \clist_map_variable_aux:Nnw #1#2#3,{
- \def:Npn #1{#3}
+\cs_new:Npn \clist_map_variable_aux:Nnw #1#2#3,{
+ \cs_set_nopar:Npn #1{#3}
\quark_if_recursion_tail_stop:N #1
#2 \clist_map_variable_aux:Nnw #1{#2}
}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\clist_concat_aux:NNNN}
-% \begin{macro}{\clist_concat:NNN}
-% \begin{macro}{\clist_gconcat:NNN}
-% \begin{macro}{\clist_gconcat:NNc}
-% \begin{macro}{\clist_gconcat:ccc}
+% \subsection{Higher level functions}
+%
+% \begin{macro}[aux]{\clist_concat_aux:NNNN}
+% \begin{macro}{\clist_concat:NNN,\clist_concat:ccc}
+% \begin{macro}{\clist_gconcat:NNN,\clist_gconcat:ccc}
% |\clist_gconcat:NNN| \m{clist~1} \m{clist~2} \m{clist~3} will globally
% assign \m{clist~1} the concatenation of \m{clist~2} and
% \m{clist~3}.
+%
+% Again the situation is a bit more complicated because of the use
+% of commas between items, so if either list is empty we have to avoid
+% adding a comma.
% \begin{macrocode}
-\def_new:Npn \clist_concat_aux:NNNN #1#2#3#4{
+\cs_new_nopar:Npn \clist_concat_aux:NNNN #1#2#3#4 {
\toks_set:No \l_tmpa_toks {#3}
\toks_set:No \l_tmpb_toks {#4}
#1 #2 {
\toks_use:N \l_tmpa_toks
-% \end{macrocode}
-% Again the situation is a bit more complicated because of the use
-% of commas between items, so if either list is empty we have to avoid
-% adding a comma.
-% \begin{macrocode}
- \toks_if_empty:NF \l_tmpa_toks {\toks_if_empty:NF \l_tmpb_toks ,}
+ \toks_if_empty:NF \l_tmpa_toks { \toks_if_empty:NF \l_tmpb_toks , }
\toks_use:N \l_tmpb_toks
}
}
-\def_new:Npn \clist_concat:NNN {\clist_concat_aux:NNNN \tlp_set:Nx}
-\def_new:Npn \clist_gconcat:NNN {\clist_concat_aux:NNNN \tlp_gset:Nx}
+\cs_new_nopar:Npn \clist_concat:NNN { \clist_concat_aux:NNNN \tl_set:Nx }
+\cs_new_nopar:Npn \clist_gconcat:NNN { \clist_concat_aux:NNNN \tl_gset:Nx }
+\cs_generate_variant:Nn \clist_concat:NNN {ccc}
+\cs_generate_variant:Nn \clist_gconcat:NNN {ccc}
% \end{macrocode}
-% And the usual versions.
-% \begin{macrocode}
-\def_new:Npn \clist_gconcat:NNc{\exp_args:Nnnc\clist_gconcat:NNN}
-\def_new:Npn \clist_gconcat:ccc{\exp_args:Nccc\clist_gconcat:NNN}
-% \end{macrocode}
-% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
-% \end{macro}
-%
+%
+% \begin{macro}[aux]{\l_clist_remove_clist}
+% A common scratch space for the removal routines.
+% \begin{macrocode}
+\clist_new:N \l_clist_remove_clist
+% \end{macrocode}
+% \end{macro}
%
-% \begin{macro}{\clist_remove_duplicates_aux:NN}
-% \begin{macro}{\clist_remove_duplicates_aux:n}
+% \begin{macro}[aux]{\clist_remove_duplicates_aux:NN}
+% \begin{macro}[aux]{\clist_remove_duplicates_aux:n}
% \begin{macro}{\clist_remove_duplicates:N}
% \begin{macro}{\clist_gremove_duplicates:N}
% Removing duplicate entries in a \meta{clist} is fairly straight
@@ -887,23 +1052,24 @@
% from left to right. For each element check if the element is
% already present in the list.
% \begin{macrocode}
-\def:Npn \clist_remove_duplicates_aux:NN #1#2 {
- \clist_clear:N \l_clist_remove_duplicates_clist
+\cs_new:Nn \clist_remove_duplicates_aux:NN {
+ \clist_clear:N \l_clist_remove_clist
\clist_map_function:NN #2 \clist_remove_duplicates_aux:n
- #1 #2 \l_clist_remove_duplicates_clist
+ #1 #2 \l_clist_remove_clist
}
-\def:Npn \clist_remove_duplicates_aux:n #1 {
- \clist_if_in:NnTF \l_clist_remove_duplicates_clist {#1} {}
- {\clist_put_right:Nn \l_clist_remove_duplicates_clist {#1}}
+\cs_new:Nn \clist_remove_duplicates_aux:n {
+ \clist_if_in:NnF \l_clist_remove_clist {#1} {
+ \clist_put_right:Nn \l_clist_remove_clist {#1}
+ }
}
% \end{macrocode}
% The high level functions are just for telling if it should be a
% local or global setting.
% \begin{macrocode}
-\def_new:Npn \clist_remove_duplicates:N {
+\cs_new_nopar:Npn \clist_remove_duplicates:N {
\clist_remove_duplicates_aux:NN \clist_set_eq:NN
}
-\def_new:Npn \clist_gremove_duplicates:N {
+\cs_new_nopar:Npn \clist_gremove_duplicates:N {
\clist_remove_duplicates_aux:NN \clist_gset_eq:NN
}
% \end{macrocode}
@@ -911,67 +1077,38 @@
% \end{macro}
% \end{macro}
% \end{macro}
-%
-% \begin{macro}{\l_clist_remove_duplicates_clist}
-% \begin{macrocode}
-\clist_new:N \l_clist_remove_duplicates_clist
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\clist_use:N}
-% \begin{macro}{\clist_use:c}
-% Using a \meta{clist} is just executing it but\dots
-% \begin{macrocode}
-\def_new:Npn \clist_use:N #1 {
- \if_meaning:NN #1 \scan_stop:
-% \end{macrocode}
-% \dots\ if \m{clist} equals |\scan_stop:| it is probably stemming
-% from a |\cs:w ... \cs_end:| that was created by mistake somewhere.
+%
+%\begin{macro}{\clist_remove_element:Nn}
+%\begin{macro}{\clist_gremove_element:Nn}
+%\begin{macro}[aux]{\clist_remove_element_aux:NNn}
+%\begin{macro}[aux]{\clist_remove_element_aux:n}
+% The same general idea is used for removing elements: the parent
+% functions just set things up for the internal ones.
% \begin{macrocode}
- \err_latex_bug:x {Comma~list~ `\token_to_string:N #1'~
- has~ an~ erroneous~ structure!}
- \else:
- \exp_after:NN #1
- \fi:
+\cs_new_nopar:Npn \clist_remove_element:Nn {
+ \clist_remove_element_aux:NNn \clist_set_eq:NN
}
-\def_new:Npn \clist_use:c {\exp_args:Nc \clist_use:N}
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\clist_if_in:NnTF}
-% \begin{macro}{\clist_if_in:NoTF}
-% \begin{macro}{\clist_if_in:cnTF}
-% \begin{macro}{\clist_if_in:coTF}
-% |\clist_if_in:NnTF| \m{clist}\m{item} \m{true~case} \m{false~case}
-% will check whether \m{item} is in \m{clist} and then either execute
-% the \m{true~case} or the \m{false~case}. \m{true~case} and
-% \m{false~case} may contain incomplete |\if_charcode:w|
-% statements.
-% \begin{macrocode}
-\def_new:Npn \clist_if_in:NnTF #1#2{
- \def:Npn \tmp:w ##1 ,#2, ##2##3\q_stop{
- \if_meaning:NN\q_no_value##2
- \exp_after:NN\use_arg_ii:nn
- \else:
- \exp_after:NN\use_arg_i:nn
- \fi:
+\cs_new_nopar:Npn \clist_gremove_element:Nn {
+ \clist_remove_element_aux:NNn \clist_gset_eq:NN
+}
+\cs_new:Nn \clist_remove_element_aux:NNn {
+ \clist_clear:N \l_clist_remove_clist
+ \cs_set:Nn \clist_remove_element_aux:n {
+ \tl_if_eq:nnF {#3} {##1} {
+ \clist_put_right:Nn \l_clist_remove_clist {##1}
+ }
}
- \exp_after:NN \tmp:w
- \exp_after:NN , #1, #2, \q_no_value \q_stop
+ \clist_map_function:NN #2 \clist_remove_element_aux:n
+ #1 #2 \l_clist_remove_clist
}
-\def_new:Npn \clist_if_in:NoTF {\exp_args:NNo \clist_if_in:NnTF}
-\def_new:Npn \clist_if_in:coTF {\exp_args:Nco \clist_if_in:NnTF}
-\def_new:Npn \clist_if_in:cnTF {\exp_args:Nc \clist_if_in:NnTF}
+\cs_new:Nn \clist_remove_element_aux:n { }
% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
%
-%
-% \subsubsection{Stack operations}
+% \subsection{Stack operations}
%
% We build stacks from comma-lists, but here we put the
% specific functions together.
@@ -979,6 +1116,7 @@
%
% \begin{macro}{\clist_push:Nn}
% \begin{macro}{\clist_push:No}
+% \begin{macro}{\clist_push:NV}
% \begin{macro}{\clist_push:cn}
% \begin{macro}{\clist_pop:NN}
% \begin{macro}{\clist_pop:cN}
@@ -986,22 +1124,25 @@
% `push' and `pop'. In most cases they are nothing more then new
% names for old functions.
% \begin{macrocode}
-\let_new:NN \clist_push:Nn \clist_put_left:Nn
-\let_new:NN \clist_push:No \clist_put_left:No
-\let_new:NN \clist_push:cn \clist_put_left:cn
-\def_new:Npn \clist_pop:NN {\clist_pop_aux:nnNN \tlp_set:Nn \tlp_set:Nn}
-\def_new:Npn \clist_pop:cN {\exp_args:Nc \clist_pop:NN}
+\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:cn \clist_put_left:cn
+\cs_new_nopar:Npn \clist_pop:NN {\clist_pop_aux:nnNN \tl_set:Nn \tl_set:Nn}
+\cs_generate_variant:Nn \clist_pop:NN {cN}
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
+% \end{macro}
%
%
%
% \begin{macro}{\clist_gpush:Nn}
% \begin{macro}{\clist_gpush:No}
+% \begin{macro}{\clist_gpush:NV}
% \begin{macro}{\clist_gpush:cn}
% \begin{macro}{\clist_gpop:NN}
% \begin{macro}{\clist_gpop:cN}
@@ -1010,12 +1151,17 @@
% here more often. In case of |\clist_gpop:NN| the value is
% nevertheless returned locally.
% \begin{macrocode}
-\let_new:NN \clist_gpush:Nn \clist_gput_left:Nn
-\def_new:Npn \clist_gpush:No {\exp_args:NNo \clist_gpush:Nn}
-\def_new:Npn \clist_gpush:cn {\exp_args:Nc \clist_gpush:Nn}
-\def_new:Npn \clist_gpop:NN {\clist_pop_aux:nnNN \tlp_gset:Nn \tlp_set:Nn}
-\def_new:Npn \clist_gpop:cN {\exp_args:Nc \clist_gpop:NN}
+\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_generate_variant:Nn \clist_gpush:Nn {cn}
% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_new_nopar:Npn \clist_gpop:NN {\clist_pop_aux:nnNN \tl_gset:Nn \tl_set:Nn}
+\cs_generate_variant:Nn \clist_gpop:NN {cN}
+% \end{macrocode}
+% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
@@ -1028,58 +1174,26 @@
% Looking at the top element of the stack without removing it is
% done with this operation.
% \begin{macrocode}
-\let_new:NN \clist_top:NN \clist_get:NN
-\let_new:NN \clist_top:cN \clist_get:cN
+\cs_new_eq:NN \clist_top:NN \clist_get:NN
+\cs_new_eq:NN \clist_top:cN \clist_get:cN
% \end{macrocode}
% \end{macro}
% \end{macro}
%
-%
-% Show token usage:
% \begin{macrocode}
%</initex|package>
+% \end{macrocode}
+%
+% Show token usage:
+% \begin{macrocode}
%<*showmemory>
%\showMemUsage
%</showmemory>
% \end{macrocode}
%
+% \end{implementation}
+% \PrintIndex
%
%
-% \endinput
-%
-% $Log$
-% Revision 1.16 2006/07/30 15:45:46 morten
-% Made \clist_map_inline:Nn and variants nestable plus a little cleanup.
-%
-% Revision 1.15 2006/03/20 18:26:34 braams
-% Updated the copyright notice (2006) and demoted all implementation
-% sections to subsections and so on to clean up the toc for source3.tex
-%
-% Revision 1.14 2006/01/04 01:32:09 morten
-% Minor changes to code to reflect changes in l3tlp.
-%
-% Revision 1.13 2005/12/27 09:52:51 morten
-% Minor changes plus changed RCS information retrieval
-%
-% Revision 1.12 2005/10/27 23:14:49 morten
-% Improved loops.
-%
-% Revision 1.11 2005/04/12 16:45:22 morten
-% Enabled put operations. Added function that removes duplicate entries (mostly for
-% use after concatenating to clists)
-%
-% Revision 1.10 2005/04/12 13:22:13 morten
-% Mostly cosmetic changes. \clist_gconcat:NNN reprogrammed using "proper" methods, \clist_put_right:Nn likewise.
-%
-% Revision 1.9 2005/03/22 23:26:54 morten
-% Fix error message
-%
-% Revision 1.8 2005/03/16 22:36:43 braams
-% Added the tweaks necessary to be able to load with initex
-%
-% Revision 1.7 2005/03/11 21:36:36 braams
-% Fixed the use of RCS information;
-% Fixed a few documentation typos; added \StopEventually
-% Replaced \ifx by \if_meaning:NN, \c_if_empty_toks became \c_empty_toks
-% but needs further work according to Morten
%
+% \endinput
diff --git a/Master/texmf-dist/source/latex/expl3/l3doc.dtx b/Master/texmf-dist/source/latex/expl3/l3doc.dtx
new file mode 100644
index 00000000000..d9674ee724e
--- /dev/null
+++ b/Master/texmf-dist/source/latex/expl3/l3doc.dtx
@@ -0,0 +1,1674 @@
+% \iffalse
+%% File: l3doc.dtx Copyright (C) 1990-2009 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 LaTeX Project Team.
+%%
+%% -----------------------------------------------------------------------
+%<*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 \filename
+%<class>\let \filenameextOld \filenameext
+%<class>\let \filedateOld \filedate
+%<class>\let \fileversionOld \fileversion
+%<class>\let \filedescriptionOld \filedescription
+% \end{macrocode}
+%
+%<*driver|class>
+\GetIdInfo$Id: l3doc.dtx 1398 2009-06-08 15:53:26Z joseph $
+ {L3 Experimental documentation class}
+%</driver|class>
+%
+%<*driver>
+\ProvidesFile{\filename.\filenameext}
+ [\filedate\space v\fileversion\space\filedescription]
+\documentclass{l3doc}
+\begin{document}
+\DocInput{l3doc.dtx}
+\end{document}
+%</driver>
+%
+% This isn't included in the typeset documentation because it's a bit ugly:
+%<*class>
+\ProvidesExplClass
+ {\filename}{\filedate}{\fileversion}{\filedescription}
+\RequirePackage{expl3}
+\let \filename \filenameOld
+\let \filenameext \filenameextOld
+\let \filedate \filedateOld
+\let \fileversion \fileversionOld
+\let \filedescription \filedescriptionOld
+%</class>
+% \fi
+%
+% \title{The \pkg{l3doc} class\thanks{This file
+% has version number \fileversion, last
+% revised \filedate.}}
+% \author{\Team}
+% \date{\filedate}
+% \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 (using `"|"' as a delimiter and the odd `"/ (...)"' tags; (3)~no obvious link to the "\begin{macro}" function that's used analogously in the implementation.
+%
+% The environments "function" and "macro" should probably
+% be renamed to something like \env{funcdoc} and \env{funcimpl},
+% respectively.
+%
+% 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.
+% \item Hyperlink documentation and implementation of macros (also see
+% the \textsc{dtx} file of \pkg{svn-multi} v2).
+% \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{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{verbatim}
+% \begin{function}{ list_of | functions }
+% \begin{syntax}
+% "\foo_bar:" \Arg{meta} <test1>
+% \end{syntax}
+% <description>
+% \end{function}
+% \end{verbatim}
+%
+% \begin{function}{ list_of | functions }
+% \begin{syntax}
+% "\foo_bar:" \Arg{meta} <test1>
+% \end{syntax}
+% <description>
+% \end{function}
+%
+% Note that the list of functions use "|" as a separator.
+%
+% \bigskip
+% \textbf{MAJOR PROPOSED CHANGE}\qquad
+% I think we should probably discourage this sort of free-form markup in
+% \LaTeX3 and change this to a plain ol' comma-separated list instead.
+%
+% Alternatively, we could provide programmatic means of looping through
+% lists with arbitary separators and promote this kind of thing.
+%
+% \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.
+% One major change 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}
+%
+% \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 exactly
+% like a list 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}
+%
+% \begin{macrocode}
+\DeclareOption{a5paper}{\@latexerr{Option not supported}{}}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\bool_new:N \g_doc_full_bool
+\bool_set_false:N \g_doc_full_bool
+\DeclareOption{full}{ \bool_set_true:N \g_doc_full_bool }
+\DeclareOption{onlydoc}{ \bool_set_false:N \g_doc_full_bool }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\bool_new:N \g_doc_checkfunc_bool
+\bool_set_true:N \g_doc_checkfunc_bool
+\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*{\PassOptionsToClass{\CurrentOption}{article}}
+\ExecuteOptions{full}
+\ProcessOptions
+% \end{macrocode}
+%
+%
+% \subsection{Class and package loading}
+%
+% \begin{macrocode}
+\LoadClass[a4paper]{article}
+\RequirePackage{doc}
+\RequirePackage{array,alphalph,color,fixltx2e,enumitem,trace,underscore}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\RequirePackage[T1]{fontenc}
+\RequirePackage{lmodern,textcomp}
+\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
+\usepackage{verbatim}
+\AtBeginDocument{%
+ \let\verbatim\doc@verbatim
+ \let\endverbatim\enddoc@verbatim
+ \let\@verbatim\doc@@verbatim
+}
+% \end{macrocode}
+%
+% \subsection{Configuration}
+%
+% \begin{macro}{\MakePrivateLetters}
+% \begin{macrocode}
+\cs_set_nopar:Npn \MakePrivateLetters {
+ \char_make_letter:N \@
+ \char_make_letter:N \_
+ \char_make_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
+}
+% \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}
+% \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}
+\newenvironment{documentation}{}{}
+\newenvironment{implementation}{}{}
+\newcommand\EnableDocumentation{%
+ \renewenvironment{documentation}{}{}%
+}
+\newcommand\EnableImplementation{%
+ \renewenvironment{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}{variable}
+% 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}
+\group_begin:
+\char_make_active:N \<
+\cs_gnew_nopar:Npn \function {
+ \char_make_active:N \<
+ \cs_set_eq:NN < \doc_open_meta:n
+ \group_begin:
+ \MakePrivateLetters
+ \char_make_other:N \|
+ \char_make_other:N \^
+ \char_make_other:N \\
+ \char_make_space:N \~
+ \char_make_ignore:N \ % space
+ \char_make_ignore:N \^^M
+ \char_make_ignore:N \^^I
+ \function_aux:n
+}
+\group_end:
+% \end{macrocode}
+% And the "variable" function is exactly the same for now:
+% \begin{macrocode}
+\cs_set_eq:NN \variable \function
+% \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}
+% \begin{macrocode}
+\cs_set_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
+ \doc_showmacro:w #1 | \q_stop \\
+ \hline
+ \endtabular
+ \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}
+\cs_set_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 }
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+\bool_new:N \l_doc_meta_TF_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:nnTF {#2} { (TF) } {
+ \bool_gset_true:N \l_doc_meta_TF_bool
+ }{
+ \bool_gset_false:N \l_doc_meta_TF_bool
+ }
+ \tl_if_in:nnTF {#2} { (EXP) } {
+ \bool_gset_true:N \l_doc_meta_EXP_bool
+ }{
+ \bool_gset_false:N \l_doc_meta_EXP_bool
+ }
+
+ \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 } }
+ }
+
+ \doc_showmacro_aux_ii:w #1::\q_stop
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\doc_showmacro_aux_ii:w}
+% This macro is passed one of:
+% \begin{quote}
+% "\showexplmacro "^^A
+% \makebox[\widthof{\texttt{123456}}]{\meta{name}}^^A
+% " ::\q_stop" \\
+% "\showexplmacro \foo ::\q_stop" \\
+% "\showexplmacro \foo: ::\q_stop" \\
+% "\showexplmacro \foo:Z ::\q_stop" \\
+% \end{quote}
+% Notice that for "\foo", "#2" and "#3" are empty,\\
+% for "\foo:", "#2" is empty,\\
+% and for both "\foo:" and "\foo:Z", "#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
+
+ \tl_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$
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{environment}{syntax}
+% Syntax block placed next to the list of functions to illustrate their use.
+% \begin{macrocode}
+\newenvironment{syntax}{%
+ \minipage[b]{.7\textwidth}%
+ \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_make_active:N #1 }
+ \cs_gnew:Npn \doc_open_meta:n {
+ \group_begin:
+ \tl_map_function:nN {0123456789} \doc_assign_num:n
+ \doc_close_meta:w
+ }
+ \cs_gnew: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_make_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][] {
+ \bool_set_false:N \l_doc_macro_aux_bool
+ \bool_set_false:N \l_doc_macro_TF_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:} }
+ \KV_parse_space_removal_sanitize:n {#1}
+
+ \group_begin:
+ \MakePrivateLetters
+ \char_make_letter:N \\
+ \char_make_ignore:N \ % space
+ \char_make_ignore:N \^^M
+ \char_make_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:
+ \clist_map_inline:nn {#1} { \doc_macro_single {##1} }
+}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\bool_new:N \l_doc_macro_aux_bool
+\bool_new:N \l_doc_macro_TF_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_TF: { \bool_set_true:N \l_doc_macro_TF_bool }
+% \end{macrocode}
+% \end{environment}
+%
+% \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}
+\cs_set_nopar:Npn \doc_macro_single #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:
+ }
+
+ \cs_set_nopar:Npx \@tempa {
+ \exp_not:N \item [ \exp_not:N \doc_print_macroname:n {
+ \tl_to_str:n {#1}
+ }]
+ } \@tempa
+ \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}
+\cs_set_nopar:Npn \doc_print_macroname:n #1 {
+ \strut \MacroFont
+ \doc_macroname_prefix:n {#1} \doc_macroname_suffix: \ % space!
+}
+% \end{macrocode}
+% \end{macro}
+% \end{environment}
+%
+% \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: {
+ \color[gray]{0.5}
+ \underline { \color{black} \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}{\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 template 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' (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:~\filedate\ % space
+ Version~\fileversion
+ \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
+% \end{macrocode}
+%
+% \begin{macrocode}
+\iow_new:N \g_write_func_stream
+\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}
+%
+% \subsection{Indexing}
+%
+% Fix index (for now):
+% \begin{macrocode}
+\g@addto@macro\theindex{\MakePrivateLetters}
+% \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
+ \msg_four_spaces: 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
+ \msg_four_spaces: 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{Patch file}
+%
+% Will: Do we still need this?
+%
+% \begin{macro}{\includeltpatch}
+% This command will be used to input the patch file
+% if that file exists.
+% \begin{macrocode}
+\cs_new_nopar:Npn \includeltpatch {
+ \cs_set_nopar:Npn \currentfile {l3patch.ltx}
+ \part{l3patch}
+ {\cs_set_eq:NN \ttfamily\relax
+ \cs_gset_nopar:Npx \filekey{\filekey, \thepart={\ttfamily\currentfile}}}
+ Things~we~did~wrong\ldots
+ \IndexInput{l3patch.ltx}}
+% \end{macrocode}
+% Get the date from ltvers.dtx
+% \begin{macrocode}
+\cs_set_nopar:Npn \patchdate{0}
+\begingroup
+ %%\cs_set_nopar:Npn \ProvidesFile#1\fmtversion#2{\date{#2}\endinput}
+ \cs_set_nopar:Npn \ProvidesFile#1[#2#3]{\date{#2}\endinput}
+ \input{l3vers.dtx}
+ \cs_gset_nopar:Npx \@date{\@date}
+ \cs_gset_eq:NN \X@date \@date
+% Add the patch version if available.
+ \cs_set:Npn \Xdef#1#2#3\def#4#5 {
+ \cs_gset_nopar:Npx \X@date{#2}
+ \cs_gset_nopar:Npx \patchdate{#5}
+ \endinput
+ }
+ \InputIfFileExists{l3patch.ltx}{
+ \cs_set_eq:NN \cs_set_nopar:Npn \Xdef
+ }{
+ \cs_gset_eq:NN \includeltpatch \relax
+ }
+\endgroup
+\ifx\@date\X@date
+ \cs_set_nopar:Npn \Xpatch{0}
+ \ifx\patchdate\Xpatch\else
+ \cs_set_nopar:Npx \@date {\@date\space Patch level \patchdate}
+ \fi
+\else
+ \@warning{l3patch.ltx does not match l3vers.dtx!}
+ \cs_set_eq:NN \includeltpatch \relax
+\fi
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{cfg}
+%
+% \begin{macrocode}
+\bool_if:NTF \g_doc_full_bool {
+ \RecordChanges
+ \CodelineIndex
+ \EnableCrossrefs
+ \AlsoImplementation
+}{
+ \CodelineNumbered
+ \DisableCrossrefs
+ \OnlyDescription
+}
+% \end{macrocode}
+%
+% Input a local configuration file, if it exists.
+% \begin{macrocode}
+\InputIfFileExists{l3doc.cfg}{
+ \typeout{*************************************^^J
+ *~Local~config~file~l3doc.cfg~used ^^J
+ *************************************}
+}{}
+% \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}{ \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}
+%
+%\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
+%
+% \bigskip\bigskip
+%
+% \begin{macro}{\c_minus_one}
+% \begin{macro}{\c_zero}
+% \begin{macro}{\c_one}
+% \begin{macro}{\c_two}
+% \begin{macro}{\c_three}
+% \begin{macro}{\c_four}
+% \begin{macro}{\c_five}
+% \begin{macro}{\c_six}
+% \begin{macro}{\c_seven}
+% \begin{macro}{\c_eight}
+% \begin{macro}{\c_nine}
+% \begin{macro}{\c_ten}
+% \begin{macro}{\c_eleven}
+% \begin{macro}{\c_sixteen}
+% \begin{macro}{\c_thirty_two}
+% \begin{macro}{\c_hundred_one}
+% \begin{macro}{\c_twohundred_fifty_five}
+% \begin{macro}{\c_twohundred_fifty_six}
+% \begin{macro}{\c_thousand}
+% \begin{macro}{\c_ten_thousand}
+% \begin{macro}{\c_ten_thousand_one}
+% \begin{arguments}
+% \item name
+% \item parameters
+% \end{arguments}
+% Another test.
+% \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{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/expl3/l3expan.dtx b/Master/texmf-dist/source/latex/expl3/l3expan.dtx
index 1efadb1dab3..7f2323b2e0c 100644
--- a/Master/texmf-dist/source/latex/expl3/l3expan.dtx
+++ b/Master/texmf-dist/source/latex/expl3/l3expan.dtx
@@ -1,5 +1,5 @@
% \iffalse
-%% File: l3expan.dtx Copyright (C) 1990-2006 LaTeX3 project
+%% File: l3expan.dtx Copyright (C) 1990-2009 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
@@ -17,7 +17,7 @@
%%
%% The development version of the bundle can be found at
%%
-%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/
+%% http://www.latex-project.org/svnroot/experimental/trunk/
%%
%% for those people who are interested.
%%
@@ -36,7 +36,7 @@
\RequirePackage{l3names}
%</driver|package>
%\fi
-\GetIdInfo$Id: l3expan.dtx 735 2008-01-14 22:31:02Z morten $
+\GetIdInfo$Id: l3expan.dtx 1376 2009-06-01 17:01:30Z morten $
{L3 Experimental Argument Expansion module}
%\iffalse
%<*driver>
@@ -44,153 +44,37 @@
\ProvidesFile{\filename.\filenameext}
[\filedate\space v\fileversion\space\filedescription]
%\iffalse
-\documentclass{l3doc}
+\documentclass[full]{l3doc}
\begin{document}
-\DocInput{\filename.\filenameext}
+\DocInput{l3expan.dtx}
\end{document}
%</driver>
% \fi
%
%
-% \title{The \textsf{l3expan} package\thanks{This file
+% \title{The \pkg{l3expan} package\thanks{This file
% has version number \fileversion, last
% revised \filedate.}\\
-% Controlling Expansion of Command Arguments}
+% Controlling Expansion of Function Arguments}
% \author{\Team}
% \date{\filedate}
% \maketitle
%
+% \begin{documentation}
%
-% \section{\LaTeX3 functions}
+% \section{Brief overview}
%
-% All \LaTeX3 functions contain a colon in their
-% name. Characters following the colon are used to denote the number and
-% the ``type'' of arguments that the function takes. An uppercase "N" is
-% used to denote an argument that consists of a single token and a
-% lowercase "n" is used when the argument can consist of several tokens
-% surrounded by braces. 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. For example, "\seq_gpush:Nn"
-% is a function that takes two arguments, the first is a single token
-% (the sequence) and the second may consist of several tokens surrounded
-% by braces.
+% The functions in this module all have prefix |exp|.
%
-% This concept of argument specification makes it easy to read the code
-% and should be followed when defining new functions.
-%
-% \subsection{Expanding arguments of functions}
-%
-% Within code it is often necessary to expand or partially expand
-% arguments before passing it on to some function. For example, if the
-% token list pointer "\l_tmpa_tlp" contains the current file
-% that should be pushed onto some stack, we can not write
-% \begin{quote}
-% "\seq_gpush:Nn" \\
-% " \g_file_name_stack" \\
-% " \l_tmpa_tlp"
-% \end{quote}
-% since this would put the token "\l_tmpa_tlp" and not its
-% contents on the stack. Instead a suitable number of "\exp_after:NN"
-% would be necessary (together with extra braces) to change the order of
-% execution, i.e.
-% \begin{quote}
-% "\exp_after:NN" \\
-% " \seq_gpush:Nn" \\
-% "\exp_after:NN" \\
-% " \g_file_name_stack" \\
-% "\exp_after:NN" \\
-% " {\l_tmpa_tlp}"
-% \end{quote}
-%
-% The above example is probably the simplest case but is already shows
-% how the code changes to something difficult to understand. 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 argument part of the function to
-% mark the desired behavior. In the above example one would write
-% \begin{quote}
-% "\seq_gpush:No" \\
-% " \g_file_name_stack" \\
-% " \l_tmpa_tlp"
-% \end{quote}
-% to achieve the desired effect. Here the "o" stands for expand this
-% (the second) argument once before passing it to the function.
-%
-% The following letters can be used to denote special treatment of
-% arguments before passing it to the basic function:
-% \begin{description}
-% \item[o] One time expanded token or token-list. In the latter case,
-% effectively only the first token in the list gets expanded. Since
-% the expansion might result in more than one token, the result is
-% surrounded for further processing with braces.
-%
-% \item[x] Fully expanded token or token-list. Like "o" but the
-% argument is expanded using "\def:Npx" before it is passed on. This means
-% that expansion takes place until only unexpandable tokens are left.
-%
-% \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.
-%
-% \item[N,O,X] Like "n", "o", "x" but the argument must be a single
-% token without any braces around it.
-%
-% \item[c] A character string or a token-list that ultimately expands
-% to characters. This string (after expansion) is used to construct a
-% command name that is eventually passed on.
-%
-% \item[C] A character string or a token-list that ultimately expands
-% to characters. From this string (after expansion) a command name is
-% constructed and then this command name is expanded once (like "o").
-% The result of this is eventually passed on. In other words
-% \begin{quote}
-% "\seq_gpush:NC" \\
-% " \g_file_name_stack" \\
-% " {l_tmpa_tlp}"
-% \end{quote}
-% Has the same effect as the example above.
-%
-%
-% \end{description}
-%
-% Here are three new expansion types that may be useful but I'm not
-% sure yet. Only time will tell\dots{} Proper documentation of these
-% functions is postponed until later.
-% \begin{description}
-% \item[d] This is pretty much like the |o| type except the token list
-% get's expanded twice before being passed on. (|d| is for double.)
-% It is often useful in conjunction with a forced expansion.
-%
-% \item[E] Sometimes you need to unpack a token list or something else
-% but you don't want it to add the braces that the |o| type
-% does. This is where you usually wind up with a lot of
-% |\exp_after:NN|s and we would like to avoid that. This type works
-% quite well with the other syntax but it won't work in certain
-% circumstances: Since the generic expansion functions read their
-% arguments when the expanded code is shuffled around, this type
-% will have a problem if the last token you want to expand once is
-% |\token_to_str:N| \emph{and} you're in an argument expansion
-% process involving arguments in braces such as the |n| and |o| type
-% arguments. If you stick to functions invloving only |N| and |E|
-% everything will work just fine. (|E| is for expanded, single
-% token.)
-%
-% \item[e] Same as above but the argument must be given in braces.
-% \end{description}
-%
-% Due to memory constraints 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.
+% 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.
+%
%
-% \subsection{Defining new 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
@@ -202,11 +86,11 @@
% second are a single tokens the third argument gets
% expanded once. If "\seq_gpush:No" wouldn't be defined the example
% above could be coded in the following way:
-% \begin{quote}
-% "\exp_args:NNo\seq_gpush:Nn" \\
-% " \g_file_name_stack" \\
-% " \l_tmpa_tlp"
-% \end{quote}
+% \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
@@ -215,85 +99,132 @@
% how the variants are defined. They just expand into the appropriate
% "\exp_" function followed by the desired base function, e.g.
% \begin{quote}
-% "\def_new:Npn\seq_gpush:No{\exp_args:NNo\seq_gpush:Nn}"
+% "\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
-% "\def_new:Npn" function will silently accept definitions whenever 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 |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_tlp b" into a control
-% sequence. Furthermore we want to store the execution of it in a
-% \m{toks} register. In this example we assume "\l_tmpa_tlp" contains
-% the text string "lur". The straight forward approach is
-% \begin{quote}
-% "\toks_set:No \l_tmpa_toks {\let:Nc \aaa {b \l_tmpa_tlp b}}"
-% \end{quote}
-% Unfortunately this only puts
-% "\exp_args:NNc \let:NN \aaa {b \l_tmpa_tlp b}" into "\l_tmpa_toks"
-% and not "\let:NwN \aaa = \blurb" as we probably wanted. Using
-% "\toks_set:Nx" is not an option as that will die horribly. Instead
-% we can do a
-% \begin{quote}
-% "\toks_set:Nf \l_tmpa_toks {\let:Nc \aaa {b \l_tmpa_tlp b}}"
-% \end{quote}
-% which puts the desired result in "\l_tmpa_toks". It requires
-% "\toks_set:Nf" to be defined as
-% \begin{quote}
-% "\def:Npn \toks_set:Nf {\exp_args:NNf \toks_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!
-%
-%
-%
-%
-%
-% The available internal functions for argument expansion come in to
+% The steps above may be automated by using the function
+% "\cs_generate_variant:Nn", described next.
+%
+% \subsection{Methods for defining variants}
+%
+% \begin{function}{\cs_generate_variant:Nn}
+% \begin{syntax}
+% "\cs_generate_variant:Nn" <function> <variant argument>
+% "\cs_generate_variant:Nn " "\foo:Nn" "{c}"
+% "\cs_generate_variant:Nn" "\foo:Nn" "{c,Nx,cx}"
+% \end{syntax}
+% This function greatly simplify the task of defining
+% variantions on a base function with differing expansion control.
+% The first example is equivalent to writing
+% \begin{verbatim}
+% \cs_set_nopar:Npn \foo:cn { \exp_args:Nc \foo:Nn }
+% \end{verbatim}
+% If used with a comma-separated list of variants, it does so for each
+% variant form, i.e., the second example is equivalent to
+% \begin{verbatim}
+% \cs_set_nopar:Npn \foo:cn { \exp_args:Nc \foo:Nn }
+% \cs_set_nopar:Npn \foo:Nx { \exp_args:NNx \foo:Nn }
+% \cs_set_nopar:Npn \foo:cx { \exp_args:Ncx \foo:Nn }
+% \end{verbatim}
+% \end{function}
+%
+% \paragraph{Internal functions} \mbox{}
+%
+% \begin{function}{\cs_generate_internal_variant:n}
+% \begin{syntax}
+% "\cs_generate_internal_variant:n" \Arg{args}
+% \end{syntax}
+% Defines the appropriate "\exp_args:N"<args> function, if necessary,
+% to perform the expansion control specified by <args>.
+% \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.
+% arguments to make processing faster.
% \item
% Arguments that should consist of single tokens should come first.
% \item
% Arguments that need full expansion (i.e., are denoted with "x")
-% should be avoided if possible as they can not be processed very fast.
+% should be avoided if possible as they can not be processed very fast.
% \item
% In general "n", "x", and "o" (if not in the last position) will
% need special processing which is not fast and not expandable,
% i.e., functions of this type may not work correctly in arguments
% that are itself subject to "x" expansion. Therefore it is best to
% use the ``expandable'' functions (i.e., those that contain only
-% "c", "N", "O", "o" or "f" in the last position) whenever possible.
+% "c", "N", "o" or "f" in the last position) whenever possible.
% \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
+% \m{toks} register. In this example we assume "\l_tmpa_tl" contains
+% the text string "lur". The straight forward approach is
+% \begin{quote}
+% "\toks_set:No \l_tmpa_toks {\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_tmpa_toks"
+% and not "\cs_set_eq:NwN \aaa = \blurb" as we probably wanted. Using
+% "\toks_set:Nx" is not an option as that will die horribly. Instead
+% we can do a
+% \begin{quote}
+% "\toks_set:Nf \l_tmpa_toks {\cs_set_eq:Nc \aaa {b \l_tmpa_tl b}}"
+% \end{quote}
+% which puts the desired result in "\l_tmpa_toks". It requires
+% "\toks_set:Nf" to be defined as
+% \begin{quote}
+% "\cs_set_nopar:Npn \toks_set:Nf {\exp_args:NNf \toks_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!
+%
%
% When pdf\TeX\ 1.50 arrives, it will contain a primitive for
% performing the equivalent of an "x" expansion after only one
% expansion and most importantly: as an expandable operation.
-% \begin{function}{%
-% \exp_arg:x
-% }
+% \begin{function}{\exp_arg:x}
% \begin{syntax}
-% " \exp_arg:x" "{" <arg> "}"
+% "\exp_arg:x" \Arg{arg}
% \end{syntax}
% <arg> is expanded fully using an "x" expansion.
% \end{function}
%
%
-% \subsection{Manipulating the first argument}
%
-% \begin{function}{%
-% \exp_args:No
-% }
+% \section{Manipulating the first argument}
+%
+% \begin{function}{ \exp_args:No / (EXP) }
% \begin{syntax}
% " \exp_args:No" <funct> <arg1> <arg2> "..."
% \end{syntax}
@@ -302,9 +233,16 @@
% more than one argument---all others are passed unchanged.
% \end{function}
%
-% \begin{function}{%
-% \exp_args:Nc
-% }
+% \begin{function}{ \exp_args:Nd / (EXP) }
+% \begin{syntax}
+% " \exp_args:Nd" <funct> <arg1> <arg2> "..."
+% \end{syntax}
+% The first argument of <funct> (i.e., <arg1>) is expanded twice, the
+% result is surrounded by braces and passed to <funct>. <funct> may have
+% more than one argument---all others are passed unchanged.
+% \end{function}
+%
+% \begin{function}{ \exp_args:Nc / (EXP) | \exp_args:cc / (EXP) }
% \begin{syntax}
% " \exp_args:Nc" <funct> <arg1> <arg2> "..."
% \end{syntax}
@@ -313,25 +251,32 @@
% result of this expansion.) Then the result is turned into a control
% sequence and passed to <funct> as the first argument. <funct> may have
% more than one argument---all others are passed unchanged.
+%
+% In the ":cc" variant, the <funct> control sequence itself is constructed
+% (with the same process as described above) before <arg1> is turned into a
+% control sequence and passed as its argument.
% \end{function}
%
-% \begin{function}{%
-% \exp_args:NC
-% }
+% \begin{function}{ \exp_args:NV / (EXP) }
% \begin{syntax}
-% " \exp_args:Nc" <funct> <arg1> <arg2> "..."
+% " \exp_args:NV" <funct> <register>
% \end{syntax}
-% The first argument of <funct> (i.e., <arg1>) is expanded until only
-% characters remain. (An internal error occurs if something else is the
-% result of this expansion.) Then the result is turned into a control
-% sequence which is then expanded once more. The result of this is then
-% passed to <funct> as the first argument. <funct> may have more than
-% one argument---all others are passed unchanged.
+% The first argument of <funct> (i.e., <register>) is expanded to its
+% value. By value we mean a number stored in an |int| or |num|
+% register, the length value of a |dim|, |skip| or |muskip| register, the
+% contents of a |toks| register or the unexpanded contents of a |tl var.|
+% register. The value is passed onto <funct> in braces.
% \end{function}
%
-% \begin{function}{%
-% \exp_args:Nx
-% }
+% \begin{function}{ \exp_args:Nv / (EXP) }
+% \begin{syntax}
+% " \exp_args:Nv" <funct> \Arg{register}
+% \end{syntax}
+% Like the |V| type except the register is given by a list of
+% characters from which a control sequence name is generated.
+% \end{function}
+%
+% \begin{function}{ \exp_args:Nx }
% \begin{syntax}
% " \exp_args:Nx" <funct> <arg1> <arg2> "..."
% \end{syntax}
@@ -342,9 +287,7 @@
% As mentioned before, this type of function is relatively slow.
% \end{function}
%
-% \begin{function}{%
-% \exp_args:Nf
-% }
+% \begin{function}{ \exp_args:Nf / (EXP) }
% \begin{syntax}
% " \exp_args:Nf" <funct> <arg1> <arg2> "..."
% \end{syntax}
@@ -355,8 +298,7 @@
% Beware of its special behavior as explained above.
% \end{function}
%
-%
-% \subsection{Manipulating two arguments}
+% \section{Manipulating two arguments}
%
% \begin{function}{%
% \exp_args:NNx |
@@ -374,16 +316,22 @@
% \end{function}
%
% \begin{function}{%
-% \exp_args:NNo |
-% \exp_args:NNf |
-% \exp_args:Nno |
-% \exp_args:NNc |
-% \exp_args:Noo |
-% \exp_args:NOo |
-% \exp_args:NOc |
-% \exp_args:Nco |
-% \exp_args:Ncc |
-% \exp_args:NNC |
+% \exp_args:NNo / (EXP) |
+% \exp_args:NNc / (EXP) |
+% \exp_args:NNv / (EXP) |
+% \exp_args:NNV / (EXP) |
+% \exp_args:NNd / (EXP) |
+% \exp_args:NNf / (EXP) |
+% \exp_args:Nno / (EXP) |
+% \exp_args:Nnf / (EXP) |
+% \exp_args:Noo / (EXP) |
+% \exp_args:Noc / (EXP) |
+% \exp_args:Nco / (EXP) |
+% \exp_args:Ncf / (EXP) |
+% \exp_args:Ncc / (EXP) |
+% \exp_args:Nff / (EXP) |
+% \exp_args:Nfo / (EXP) |
+% \exp_args:NVV / (EXP) |
% }
% \begin{syntax}
% "\exp_args:NNo" <funct> <arg1> <arg2> "..."
@@ -391,17 +339,20 @@
% These are the fast and expandable functions for the first two arguments.
% \end{function}
%
-% \subsection{Manipulating three arguments}
+% \section{Manipulating three arguments}
%
% So far not all possible functions are provided and even the selection
% below may be reduced in the future as far as the non-expandable
% functions are concerned.
%
% \begin{function}{%
+% \exp_args:NNnx |
+% \exp_args:NNox |
% \exp_args:Nnnx |
-% \exp_args:Noox |
% \exp_args:Nnox |
+% \exp_args:Noox |
% \exp_args:Ncnx |
+% \exp_args:Nccx |
% }
% \begin{syntax}
% "\exp_args:Nnnx" <funct> <arg1> <arg2> <arg3> "..."
@@ -410,44 +361,32 @@
% \end{function}
%
% \begin{function}{%
-% \exp_args:NnnN |
-% \exp_args:Nnno |
-% \exp_args:NNOo |
-% \exp_args:NOOo |
-% \exp_args:Nccc |
-% \exp_args:NcNc |
-% \exp_args:Nnnc |
-% \exp_args:NcNo |
-% \exp_args:Ncco |
+% \exp_args:NNNo / (EXP) |
+% \exp_args:NNoo / (EXP) |
+% \exp_args:NNno / (EXP) |
+% \exp_args:Nnno / (EXP) |
+% \exp_args:Nnnc / (EXP) |
+% \exp_args:Nooo / (EXP) |
+% \exp_args:Nccc / (EXP) |
+% \exp_args:NcNc / (EXP) |
+% \exp_args:NcNo / (EXP) |
+% \exp_args:Ncco / (EXP) |
% }
% \begin{syntax}
-% "\exp_args:NNOo" <funct> <arg1> <arg2> <arg3> "..."
+% "\exp_args:NNoo" <funct> <arg1> <arg2> <arg3> "..."
% \end{syntax}
% These are the fast and expandable functions for the first three
% arguments.
% \end{function}
%
-% \subsection{Internal functions and variables}
-%
-% \begin{function}{\exp_after:NN}
-% \begin{syntax}
-% "\exp_after:NN" <token1> <token2>
-% \end{syntax}
-% This will expand <token2> once before processing <token1>. This is
-% similar to "\exp_args:No" except that no braces are put around the
-% result of expanding <token2>.
-% \begin{texnote}
-% This is the primitive \tn{expandafter} which was renamed to fit into
-% the naming conventions of \LaTeX3.
-% \end{texnote}
-% \end{function}
+% \section{Preventing expansion}
%
% \begin{function}{\exp_not:N |
% \exp_not:c |
% \exp_not:n }
% \begin{syntax}
% "\exp_not:N" <token>
-% "\exp_not:n" "{" <token list> "}"
+% "\exp_not:n" \Arg{token list}
% \end{syntax}
% This function will prohibit the expansion of <token> in situation
% where <token> would otherwise be replaced by it definition, e.g.,
@@ -458,45 +397,40 @@
% \end{texnote}
% \end{function}
%
-%
% \begin{function}{\exp_not:o |
% \exp_not:d |
-% \exp_not:f}
+% \exp_not:f }
% \begin{syntax}
-% "\exp_not:o" "{"<token list>"}"
+% "\exp_not:o" \Arg{token list}
% \end{syntax}
% Same as "\exp_not:n" except <token list> is expanded once for the
% "o" type and twice for the "d" type and the result of this expansion
-% is then prohibited from being expanded further.
+% is then prohibited from being expanded further.
% \end{function}
-%
-% \begin{function}{\exp_not:E}
+%
+% \begin{function}{\exp_not:V |
+% \exp_not:v }
% \begin{syntax}
-% "\exp_not:E" <token>
+% "\exp_not:V" <register>
+% "\exp_not:v" \Arg{token list}
% \end{syntax}
-% The name of this command is a lie. Perhaps it should be called
-% ``"exp_perhaps_once"''. What it actually does is, it expands <token>
-% and then issues an "\exp_not:N" to prohibit further expansion of the
-% first token in the replacement text of <token>. This means that if
-% the replacement text of <token> consists of more than one token all
-% further tokens are still subject to full expansion.
-% \begin{texnote}
-% This command has no equivalent.
-% \end{texnote}
+% The value of <register> is retrieved and then passed on to
+% "\exp_not:n" which will prohibit further expansion. The |v| type
+% first creates a control sequence from <token list> but is otherwise
+% identical to |V|.
% \end{function}
-%
%
-% \begin{function}{\exp_stop_f: }
+% \begin{function}{\exp_stop_f:}
% \begin{syntax}
% <f expansion> ... "\exp_stop_f:"
% \end{syntax}
% This function stops an "f" type expansion. An example use is one such as
% \begin{verbatim}
-% \tlp_set:Nf \l_tmpa_tlp {
+% \tl_set:Nf \l_tmpa_tl {
% \if_case:w \l_tmpa_int
-% \or: \use_arg_i_after_orelse:nw{\exp_stop_f: \textbullet}
-% \or: \use_arg_i_after_orelse:nw{\exp_stop_f: \textendash}
-% \else: \use_arg_i_after_orelse:nw{\exp_stop_f: else-item}
+% \or: \use_i_after_orelse:nw {\exp_stop_f: \textbullet}
+% \or: \use_i_after_orelse:nw {\exp_stop_f: \textendash}
+% \else: \use_i_after_fi:nw {\exp_stop_f: else-item}
% \fi:
% }
% \end{verbatim}
@@ -508,46 +442,122 @@
% writing code.
% \end{texnote}
% \end{function}
+%
+% \section{Unbraced expansion}
+%
+% \begin{function}{
+% \exp_last_unbraced:Nf|
+% \exp_last_unbraced:NV|
+% \exp_last_unbraced:Nv|
+% \exp_last_unbraced:NcV|
+% \exp_last_unbraced:NNo|
+% \exp_last_unbraced:NNV|
+% \exp_last_unbraced:NNNo|
+% }
+% \begin{syntax}
+% "\exp_last_unbraced:NV" <token> <variable name>
+% \end{syntax}
+% There are a small number of occasions where the last argument
+% in an expansion run must be expanded unbraced. These functions
+% should only be used inside functions, \emph{not} for creating
+% variants.
+% \end{function}
+%
+% \end{documentation}
+%
+% \begin{implementation}
%
+% \section{\pkg{l3expan} implementation}
%
-% \begin{variable}{\l_exp_tlp | }
+% \subsection{Internal functions and variables}
+%
+% \begin{function}{\exp_after:wN}
+% \begin{syntax}
+% "\exp_after:wN" <token1> <token2>
+% \end{syntax}
+% This will expand <token2> once before processing <token1>. This is
+% similar to "\exp_args:No" except that no braces are put around the
+% result of expanding <token2>.
+% \begin{texnote}
+% This is the primitive \tn{expandafter} which was renamed to fit into
+% the naming conventions of \LaTeX3.
+% \end{texnote}
+% \end{function}
+%
+% \begin{variable}{\l_exp_tl}
% \begin{syntax}\end{syntax}
% 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}
%
-% \StopEventually{}
+% \begin{function}{ \exp_eval_register:N / (EXP) |
+% \exp_eval_register:c / (EXP) }
+% \begin{syntax}
+% "\exp_eval_register:N" <register>
+% \end{syntax}
+% These functions evaluates a register as part of a "V" or "v" expansion
+% (respectively). A register 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|\::d|\:::}
+% \begin{syntax}
+% "\cs_set_nopar:Npn \exp_args:Ncof {\::c\::o\::f\:::}"
+% \end{syntax}
+% Internal forms for the base expansion types.
+% \end{function}
%
-% \subsection {The Implementation}
+% \subsection{Module code}
%
% We start by ensuring that the required packages are loaded.
% \begin{macrocode}
-%<package>\ProvidesExplPackage
-%<package> {\filename}{\filedate}{\fileversion}{\filedescription}
-%<package>\RequirePackage{l3tlp}
+%<*package>
+\ProvidesExplPackage
+ {\filename}{\filedate}{\fileversion}{\filedescription}
+\package_check_loaded_expl:
+%</package>
%<*initex|package>
% \end{macrocode}
%
-% \subsubsection{General expansion}
+% \begin{macro}{\exp_after:wN}
+% \begin{macro}{\exp_not:N}
+% \begin{macro}{\exp_not:n}
+% These are defined in \pkg{l3basics}.
+% \begin{macrocode}
+%<*bootstrap>
+\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
+%</bootstrap>
+% \end{macrocode}
+% \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 |\def:Npx| at some point, and
+% 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.})
%
-% In a later section some common cases are coded by a more direct
-% method, typically using calls to |\exp_after:NN|.
+% 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{macro}{\l_exp_tlp}
-% We need a scratch token list pointer.
+% \begin{macro}{\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}
-\tlp_new:Nn\l_exp_tlp{}
+\cs_new_nopar:Npn \l_exp_tl {}
% \end{macrocode}
% \end{macro}
%
@@ -555,20 +565,47 @@
% 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.
-% \begin{macro}{\exp_arg_next:nnn}
-% This is basically the same function as |\Dexp_arg_next:nnn|.
+%
+% 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 auxilliary 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}
-\def_long_new:Npn\exp_arg_next:nnn#1#2#3{
+\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}{\:::}
+% The end marker is just another name for the identity function.
+% \begin{macrocode}
+\cs_new:Npn\:::#1{#1}
+% \end{macrocode}
+% \end{macro}
%
% \begin{macro}{\::n}
% This function is used to skip an argument that doesn't need to
% be expanded.
% \begin{macrocode}
-\def_long_new:Npn\::n#1\:::#2#3{
+\cs_new:Npn\::n#1\:::#2#3{
#1\:::{#2{#3}}
}
% \end{macrocode}
@@ -577,9 +614,8 @@
% \begin{macro}{\::N}
% This function is used to skip an argument that consists of a
% single token and doesn't need to be expanded.
-%^^A was \let_new:NN\::N\::n (changed to match \;N above.
% \begin{macrocode}
-\def_long_new:Npn\::N#1\:::#2#3{
+\cs_new:Npn\::N#1\:::#2#3{
#1\:::{#2#3}
}
% \end{macrocode}
@@ -589,8 +625,8 @@
% This function is used to skip an argument that is turned into
% as control sequence without expansion.
% \begin{macrocode}
-\def_long_new:Npn\::c#1\:::#2#3{
- \exp_after:NN\exp_arg_next:nnn\cs:w #3\cs_end:{#1}{#2}
+\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}
@@ -598,8 +634,8 @@
% \begin{macro}{\::o}
% This function is used to expand an argument once.
% \begin{macrocode}
-\def_long_new:Npn\::o#1\:::#2#3{
- \exp_after:NN\exp_arg_next:nnn\exp_after:NN{\exp_after:NN{#3}}{#1}{#2}
+\cs_new:Npn\::o#1\:::#2#3{
+ \exp_after:wN\exp_arg_next:nnn\exp_after:wN{#3}{#1}{#2}
}
% \end{macrocode}
% \end{macro}
@@ -608,7 +644,7 @@
% \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 "\int_to_roman:w -`0"
+% 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
@@ -616,459 +652,541 @@
% 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 "\let:Nc \aaa {b \l_tmpa_tlp b}"
-% into "\let:NwN \aaa = \blurb" which then turned out to contain
-% the non-expandable token "\let:NwN". Since the expansion of
-% "\int_to_roman:w -`0" is \m{null}, we wind up with a fully
+% 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 \m{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}
-\def_long_new:Npn\::f#1\:::#2#3{
- \exp_after:NN\exp_arg_next:nnn
- \exp_after:NN{\exp_after:NN{\int_to_roman:w -`0 #3}}
+\cs_new:Npn\::f#1\:::#2#3{
+ \exp_after:wN\exp_arg_next:nnn
+ \exp_after:wN{\tex_romannumeral:D -`0 #3}
{#1}{#2}
}
-\def_new:Npn \exp_stop_f: {~}
+\cs_new_nopar:Npn \exp_stop_f: {~}
% \end{macrocode}
% \end{macro}
% \end{macro}
%
-% \begin{macro}{\::x}
+% \begin{macro}{\::x,\exp_arg:x}
% This function is used to expand an argument fully. If the
% pdf\TeX\ primitive "\expanded" is present, we use it.
% \begin{macrocode}
-\let_new:NN \exp_arg:x \expanded % Move eventually.
+\cs_new_eq:NN \exp_arg:x \expanded % Move eventually.
\cs_if_free:NTF\exp_arg:x{
- \def_long_new:Npn\::x#1\:::#2#3{
- % \tlp_set:Nx\l_exp_tlp{{{#3}}}
- \def:Npx \l_exp_tlp{{{#3}}}
- \exp_after:NN\exp_arg_next:nnn\l_exp_tlp{#1}{#2}}
+ \cs_new: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}}
}
{
- \def_long_new:Npn\::x#1\:::#2#3{
- \exp_after:NN\exp_arg_next:nnn
- \exp_after:NN{\exp_arg:x{{#3}}}{#1}{#2}
+ \cs_new:Npn\::x#1\:::#2#3{
+ \exp_after:wN\exp_arg_next:nnn
+ \exp_after:wN{\exp_arg:x{{#3}}}{#1}{#2}
}
}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\:::}
-% Just another name for the identity function.
+%
+% \begin{macro}{\::v}
+% \begin{macro}{\::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 sequence |\tex_romannumeral:D -`0| sets off an |f| type
+% expansion. The argument is returned in braces.
% \begin{macrocode}
-\def_long_new:Npn\:::#1{#1}
+\cs_new:Npn \::V#1\:::#2#3{
+ \exp_after:wN\exp_arg_next:nnn
+ \exp_after:wN{
+ \tex_romannumeral:D -`0
+ \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 -`0
+ \exp_eval_register:c {#3}
+ }
+ {#1}{#2}
+}
% \end{macrocode}
% \end{macro}
+% \end{macro}
%
-% \begin{macro}{\::C}
-% This function creates a control sequence out of |#3| and expands
-% that once before passing it on to |\exp_arg_next:nnn|.
+% \begin{macro}{\exp_eval_register:N,\exp_eval_register:c}
+% \begin{macro}{\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
+% |\tex_relax:D|.
% \begin{macrocode}
-\def_long_new:Npn\::C#1\:::#2#3{
- \exp_after:NN\exp_C_aux:nnn\cs:w #3\cs_end:{#1}{#2}}
+\cs_set_nopar:Npn \exp_eval_register:N #1{
+ \exp_after:wN \if_meaning:w \exp_not:N #1#1
% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\exp_C_aux:nnn}
-% A helper function for |\::C| wich expands its argument before
-% passing it on to |\exp_arg_next:nnn|.
+% 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
+% |\tex_relax:D|. 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 \tex_relax:D #1
+ \exp_eval_error_msg:w
+ \fi:
+% \end{macrocode}
+% The next bit requires some explanation. The function must be
+% initiated by the sequence |\tex_romannumeral:D -`0| and we want to
+% terminate this expansion chain by inserting an |\exp_stop_f:|
+% token. 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\exp_stop_f:\tex_the:D #1| and if it is a macro we
+% need to execute |\exp_after:wN\exp_stop_f: #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}
-\def_long_new:Npn\exp_C_aux:nnn #1{
- \exp_after:NN
- \exp_arg_next:nnn
- \exp_after:NN
- {
- \exp_after:NN
- {#1}
- }
+ \else:
+ \exp_after:wN \use_i_ii:nnn
+ \fi:
+ \exp_after:wN \exp_stop_f: \tex_the:D #1
+}
+\cs_set_nopar:Npn \exp_eval_register:c #1{
+ \exp_after:wN\exp_eval_register:N\cs:w #1\cs_end:
}
% \end{macrocode}
-% \end{macro}
+% 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\tex_relax:D%
+\tex_catcode:D`\ =11\tex_relax:D%
+\cs_gset:Npn\exp_eval_error_msg:w#1\tex_the:D#2{%
+\fi:\fi:\erroneous variable used!}%
+\group_end:%
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
%
% Here are some that might not stay but let's see.
-% \begin{macro}{\::E}
-% This function is used to expand an argument once and return it
-% \emph{without} braces. Use this only when you feel pretty
-% comfortable about your input! Actually this is pretty much just
-% generic wrapper for |\exp_after:NN|.
+%
+% \begin{macro}{\::d}
+% This function is used to expand an argument twice. Mostly useful
+% for |toks| type things. This is likely to vanish with |V| around.
% \begin{macrocode}
-\def_long_new:Npn\::E#1\:::#2#3{
- \exp_after:NN\exp_arg_next:nnn \exp_after:NN{#3}{#1}{#2}
+\cs_new:Npn\::d#1\:::#2#3{
+ \exp_after:wN\exp_after:wN\exp_after:wN\exp_arg_next:nnn
+ \exp_after:wN\exp_after:wN\exp_after:wN{#3}{#1}{#2}
}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\::e}
-% Same as |\::E| really but conceptually they are different.
+% \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. This together with the fact that the
+% `general' concept above is slower means that we should convert
+% whenever possible and perhaps remove all remaining occurences by
+% hand-encoding in the end.
+%
+% \begin{macro}{\exp_args:No}
+% \begin{macro}{\exp_args:NNo}
+% \begin{macro}{\exp_args:NNNo}
% \begin{macrocode}
-\def_long_new:Npn\::e#1\:::#2#3{
- \exp_after:NN\exp_arg_next:nnn \exp_after:NN{#3}{#1}{#2}
-}
+\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}{\::d}
-% This function is used to expand an argument twice. Mostly useful
-% for |toks| type things.
+%
+% \begin{macro}{\exp_args:Nc,\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}
-\def_long_new:Npn\::d#1\:::#2#3{
- \exp_after:NN\exp_after:NN\exp_after:NN\exp_arg_next:nnn
- \exp_after:NN\exp_after:NN\exp_after:NN{
- \exp_after:NN\exp_after:NN\exp_after:NN{#3}}{#1}{#2}
-}
+\cs_set:Npn \exp_args:Nc #1#2{\exp_after:wN#1\cs:w#2\cs_end:}
+\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}
%
-% We do most of them by hand here. This also means that we get a name
-% for |\exp_after:NN| that fits with the rest of the code.
+% \begin{macro}{\exp_args:Nco}
+% If we force that the third argument
+% always has braces, we could implement this function
+% with less tokens and only two arguments.
% \begin{macrocode}
-\let:NN \exp_args:NE \exp_after:NN
-\def:Npn \exp_args:NNE #1{\exp_args:NE#1\exp_args:NE}
-\def:Npn \exp_args:NNNE #1#2{\exp_args:NE#1\exp_args:NE#2\exp_args:NE}
-\def:Npn \exp_args:NEE #1{\exp_args:NE\exp_args:NE\exp_args:NE#1\exp_args:NE}
-\def:Npn \exp_args:NcE #1#2{\exp_after:NN #1\cs:w #2\exp_after:NN\cs_end:}
-\def:Npn \exp_args:Nd {\::d\:::}
-\def:Npn \exp_args:NNd {\::N\::d\:::}
+\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}}
% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Definitions with the `general' technique}
+% \label{sec:gendef}
+%
+% \begin{macro}{\exp_args:Nd,\exp_args:Nf,\exp_args:NV,\exp_args:Nv,\exp_args:Nx}
+% \begin{macrocode}
+\cs_set_nopar:Npn \exp_args:Nd {\::d\:::}
+\cs_set_nopar:Npn \exp_args:Nf {\::f\:::}
+\cs_set_nopar:Npn \exp_args:Nv {\::v\:::}
+\cs_set_nopar:Npn \exp_args:NV {\::V\:::}
+\cs_set_nopar:Npn \exp_args:Nx {\::x\:::}
+% \end{macrocode}
+% \end{macro}
%
-% \begin{macro}{\exp_args:NC}
-% \begin{macro}{\exp_args:Ncx}
-% \begin{macro}{\exp_args:Ncco}
-% \begin{macro}{\exp_args:Nccx}
-% \begin{macro}{\exp_args:Ncnx}
-% \begin{macro}{\exp_args:NcNc}
-% \begin{macro}{\exp_args:Nf}
-% \begin{macro}{\exp_args:NNf}
-% \begin{macro}{\exp_args:Nfo}
-% \begin{macro}{\exp_args:Nnf}
-% \begin{macro}{\exp_args:NNno}
-% \begin{macro}{\exp_args:NnnN}
-% \begin{macro}{\exp_args:Nnno}
-% \begin{macro}{\exp_args:Nnnx}
-% \begin{macro}{\exp_args:Nno}
-% \begin{macro}{\exp_args:Nnox}
-% \begin{macro}{\exp_args:NNx}
-% \begin{macro}{\exp_args:Nnx}
-% \begin{macro}{\exp_args:Noo}
-% \begin{macro}{\exp_args:Noox}
-% \begin{macro}{\exp_args:Nox}
-% \begin{macro}{\exp_args:Nx}
-% \begin{macro}{\exp_args:Nxx}
-% \begin{macro}{\exp_args:Nxx}
-% \begin{macro}{\exp_args:NNC}
-% \begin{macro}{\exp_args:Nnnc}
-% \begin{macro}{\exp_args:NNnx}
-% \begin{macro}{\exp_args:NNoo}
-% \begin{macro}{\exp_args:NNox}
+% \begin{macro}{\exp_args:NNV,\exp_args:NNv,\exp_args:NNd,\exp_args:NNf,\exp_args:NNx,
+% \exp_args:NVV,
+% \exp_args:Ncx,
+% \exp_args:Nfo,\exp_args:Nff,
+% \exp_args:Ncf,\exp_args:Nco,
+% \exp_args:Nnf,\exp_args:Nno,\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}
-%\def:Npn \exp_args:NNNo {\::N\::N\::o\:::}
-%\def:Npn \exp_args:NNOo {\::N\::O\::o\:::}
-%\def:Npn \exp_args:NNc {\::N\::c\:::}
-%\def:Npn \exp_args:NNo {\::N\::o\::\:::}
-%\def:Npn \exp_args:NOOo {\::O\::O\::o\:::}
-%\def:Npn \exp_args:NOc {\::O\::c\:::}
-%\def:Npn \exp_args:NOo {\::O\::o\:::}
-%\def:Npn \exp_args:Nc {\::c\:::}
-%\def:Npn \exp_args:Ncc {\::c\::c\:::}
-%\def:Npn \exp_args:Nccc {\::c\::c\::c\:::}
-%\def:Npn \exp_args:Nco {\::c\::o\:::}
-%\def:Npn \exp_args:No {\::o\:::}
+\cs_set_nopar:Npn \exp_args:NNd {\::N\::d\:::}
+\cs_set_nopar:Npn \exp_args:NNf {\::N\::f\:::}
+\cs_set_nopar:Npn \exp_args:NNv {\::N\::v\:::}
+\cs_set_nopar:Npn \exp_args:NNV {\::N\::V\:::}
+\cs_set_nopar:Npn \exp_args:NNx {\::N\::x\:::}
+
+\cs_set_nopar:Npn \exp_args:Ncx {\::c\::x\:::}
+\cs_set_nopar:Npn \exp_args:Nfo {\::f\::o\:::}
+\cs_set_nopar:Npn \exp_args:Nff {\::f\::f\:::}
+\cs_set_nopar:Npn \exp_args:Ncf {\::c\::f\:::}
+\cs_set_nopar:Npn \exp_args:Nnf {\::n\::f\:::}
+\cs_set_nopar:Npn \exp_args:Nno {\::n\::o\:::}
+\cs_set_nopar:Npn \exp_args:Nnx {\::n\::x\:::}
+
+\cs_set_nopar:Npn \exp_args:Noc {\::o\::c\:::}
+\cs_set_nopar:Npn \exp_args:Noo {\::o\::o\:::}
+\cs_set_nopar:Npn \exp_args:Nox {\::o\::x\:::}
-\def:Npn \exp_args:NC {\::C\:::}
-\def:Npn \exp_args:NNC {\::N\::C\:::}
-\def:Npn \exp_args:NNf {\::N\::f\:::}
-\def:Npn \exp_args:NNno {\::N\::n\::o\:::}
-\def:Npn \exp_args:NNnx {\::N\::n\::x\:::} % new
-\def:Npn \exp_args:NNoo {\::N\::o\::o\:::} % new
-\def:Npn \exp_args:NNox {\::N\::o\::x\:::} % new
-\def:Npn \exp_args:NNx {\::N\::x\:::}
-\def:Npn \exp_args:NcNc {\::c\::N\::c\:::}
-\def:Npn \exp_args:NcNo {\::c\::N\::o\:::}
-\def:Npn \exp_args:Ncco {\::c\::c\::o\:::}
-\def:Npn \exp_args:Ncco {\::c\::c\::o\:::}
-\def:Npn \exp_args:Nccx {\::c\::c\::x\:::}
-\def:Npn \exp_args:Ncnx {\::c\::n\::x\:::}
-\def:Npn \exp_args:Ncx {\::c\::x\:::}
-\def:Npn \exp_args:Nf {\::f\:::}
-\def:Npn \exp_args:Nfo{\::f\::o\:::}
-\def:Npn \exp_args:Nnf {\::n\::f\:::}
-\def:Npn \exp_args:NnnN {\::n\::n\::N\:::} %% Strange one this one...
-\def:Npn \exp_args:Nnnc {\::n\::n\::c\:::}
-\def:Npn \exp_args:Nnno {\::n\::n\::o\:::}
-\def:Npn \exp_args:Nnnx {\::n\::n\::x\:::}
-\def:Npn \exp_args:Nno {\::n\::o\:::}
-\def:Npn \exp_args:Nnox {\::n\::o\::x\:::}
-\def:Npn \exp_args:Nnx {\::n\::x\:::}
-\def:Npn \exp_args:Noo {\::o\::o\:::}
-\def:Npn \exp_args:Noox {\::o\::o\::x\:::}
-\def:Npn \exp_args:Nox {\::o\::x\:::}
-\def:Npn \exp_args:Nx {\::x\:::}
-\def:Npn \exp_args:Nxo {\::x\::o\:::}
-\def:Npn \exp_args:Nxx {\::x\::x\:::}
+\cs_set_nopar:Npn \exp_args:NVV {\::V\::V\:::}
+
+\cs_set_nopar:Npn \exp_args:Nxo {\::x\::o\:::}
+\cs_set_nopar:Npn \exp_args:Nxx {\::x\::x\:::}
% \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}
-% \end{macro}
-% \end{macro}
+%
+% \begin{macro}{\exp_args:Ncco,
+% \exp_args:Nccx,
+% \exp_args:Ncnx,
+% \exp_args:NcNc,
+% \exp_args:NcNo,
+% \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_set_nopar:Npn \exp_args:NNno {\::N\::n\::o\:::}
+\cs_set_nopar:Npn \exp_args:NNnx {\::N\::n\::x\:::}
+\cs_set_nopar:Npn \exp_args:NNoo {\::N\::o\::o\:::}
+\cs_set_nopar:Npn \exp_args:NNox {\::N\::o\::x\:::}
+
+\cs_set_nopar:Npn \exp_args:Nnnc {\::n\::n\::c\:::}
+\cs_set_nopar:Npn \exp_args:Nnno {\::n\::n\::o\:::}
+\cs_set_nopar:Npn \exp_args:Nnnx {\::n\::n\::x\:::}
+\cs_set_nopar:Npn \exp_args:Nnox {\::n\::o\::x\:::}
+
+\cs_set_nopar:Npn \exp_args:NcNc {\::c\::N\::c\:::}
+\cs_set_nopar:Npn \exp_args:NcNo {\::c\::N\::o\:::}
+\cs_set_nopar:Npn \exp_args:Ncco {\::c\::c\::o\:::}
+\cs_set_nopar:Npn \exp_args:Ncco {\::c\::c\::o\:::}
+\cs_set_nopar:Npn \exp_args:Nccx {\::c\::c\::x\:::}
+\cs_set_nopar:Npn \exp_args:Ncnx {\::c\::n\::x\:::}
+
+\cs_set_nopar:Npn \exp_args:Noox {\::o\::o\::x\:::}
+\cs_set_nopar:Npn \exp_args:Nooo {\::o\::o\::o\:::}
+% \end{macrocode}
% \end{macro}
%
%
-% \subsubsection{Preventing expansion}
+% \subsection{Preventing expansion}
%
%
% \begin{macro}{\exp_not:o}
% \begin{macro}{\exp_not:d}
% \begin{macro}{\exp_not:f}
+% \begin{macro}{\exp_not:v}
+% \begin{macro}{\exp_not:V}
% \begin{macrocode}
-\def_long_new:Npn\exp_not:o#1{\exp_not:n\exp_after:NN{#1}}
-\def_long_new:Npn\exp_not:d#1{
- \exp_not:n\exp_after:NN\exp_after:NN\exp_after:NN{#1}
+\cs_new:Npn\exp_not:o#1{\exp_not:n\exp_after:wN{#1}}
+\cs_new:Npn\exp_not:d#1{
+ \exp_not:n\exp_after:wN\exp_after:wN\exp_after:wN{#1}
+}
+\cs_new:Npn\exp_not:f#1{
+ \exp_not:n\exp_after:wN{\tex_romannumeral:D -`0 #1}
+}
+\cs_new:Npn\exp_not:v#1{
+ \exp_not:n\exp_after:wN{\tex_romannumeral:D -`0 \exp_eval_register:c {#1}}
}
-\def_long_new:Npn\exp_not:f#1{
- \exp_not:n\exp_after:NN{\int_to_roman:w -`0 #1}
+\cs_new:Npn\exp_not:V#1{
+ \exp_not:n\exp_after:wN{\tex_romannumeral:D -`0 \exp_eval_register:N #1}
}
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
+% \end{macro}
+% \end{macro}
%
-% \begin{macro}{\exp_not:E}
% \begin{macro}{\exp_not:c}
-% Two helper functions, which we can probably live without it.
+% A helper function.
% \begin{macrocode}
-\def_new:Npn\exp_not:E{\exp_after:NN\exp_not:N}
-\def_long_new:Npn\exp_not:c#1{\exp_after:NN\exp_not:N\cs:w#1\cs_end:}
+\cs_new:Npn\exp_not:c#1{\exp_after:wN\exp_not:N\cs:w#1\cs_end:}
% \end{macrocode}
% \end{macro}
-% \end{macro}
-%
-%
-% \subsubsection{Single token expansion}
%
-% Expansion for arguments that are single tokens is done with the
-% functions below. I first thought of using a different module name
-% but then I saw that this wouldn't do since I could then never
-% determine for, say, |\seq_put:no| whether this means single, or
-% general expansion. Therefore I decided to use uppercase `O' for
-% single expansion.
-%
-% 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. This together with the fact that the
-% above concept is much slower in general means that we should convert
-% whenever possible and perhaps remove all remaining occurences by
-% hand-encoding in the end.
%
-% \begin{macro}{\exp_args:No}
-% \begin{macro}{\exp_args:NOo}
-% \begin{macro}{\exp_args:NNo}
-% \begin{macro}{\exp_args:NNO}
-% \begin{macro}{\exp_args:NOOo}
-% \begin{macro}{\exp_args:NNOo}
-% \begin{macro}{\exp_args:NNNo}
-% This looks somewhat horrible but it runs well with the other
-% syntax. It is important to see that these functions really need
-% single tokens as arguments whenever capital letters are used.
+% \subsection{Defining function variants}
+%
+%
+% \begin{macro}{\cs_generate_variant:Nn}
+% \begin{macro}[aux]{\cs_generate_variant_aux:nnNn}
+% \begin{macro}[aux]{\cs_generate_variant_aux:nnw}
+% \begin{macro}[aux]{\cs_generate_variant_aux:N}
+% \begin{arguments}
+% \item Base form of a function; 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}
-\def_long_new:Npn \exp_args:No #1#2{\exp_after:NN#1\exp_after:NN{#2}}
-\def_long_new:Npn \exp_args:NOo #1#2#3{\exp_after:NN\exp_args:No \exp_after:NN#1
- \exp_after:NN#2\exp_after:NN{#3}}
-\def_long_new:Npn \exp_args:NOOo #1#2#3#4{\exp_after:NN\exp_args:NOo
- \exp_after:NN#1\exp_after:NN#2\exp_after:NN#3\exp_after:NN{#4}}
-\def_long_new:Npn \exp_args:NNo #1#2#3{\exp_after:NN#1\exp_after:NN#2
- \exp_after:NN{#3}}
-\def_long_new:Npn \exp_args:NNO #1#2#3 {\exp_after:NN#1
- \exp_after:NN#2 #3}
-\def_long_new:Npn \exp_args:NNOo #1#2#3#4{\exp_after:NN\exp_args:NNo
- \exp_after:NN#1\exp_after:NN#2\exp_after:NN#3\exp_after:NN{#4}}
-\def_long_new:Npn \exp_args:NNNo #1#2#3#4{\exp_after:NN#1\exp_after:NN#2
- \exp_after:NN#3\exp_after:NN{#4}}
+\cs_new:Npn \cs_generate_variant:Nn #1 {
+ \chk_if_exist_cs:N #1
+ \cs_split_function:NN #1 \cs_generate_variant_aux:nnNn
+}
% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-%
-% \begin{macro}{\exp_args:Nc}
-% \begin{macro}{\exp_args:NNc}
-% \begin{macro}{\exp_args:NOc}
-% \begin{macro}{\exp_args:Ncc}
-% \begin{macro}{\exp_args:Nccc}
-% Here are the functions that turn their argument into csnames but
-% are expandable.
+% We discard the boolean and then set off a loop through the desired
+% variant forms.
% \begin{macrocode}
-\def_long_new:Npn \exp_args:Nc #1#2{\exp_after:NN#1\cs:w#2\cs_end:}
-\def_long_new:Npn \exp_args:NNc #1#2#3{\exp_after:NN#1\exp_after:NN#2
- \cs:w#3\cs_end:}
-\def_long_new:Npn \exp_args:NOc#1#2#3{\exp_after:NN\exp_args:No\exp_after:NN
- #1\exp_after:NN#2\cs:w#3\cs_end:}
-\def_long_new:Npn \exp_args:Ncc #1#2#3{\exp_after:NN#1
- \cs:w#2\exp_after:NN\cs_end:\cs:w#3\cs_end:}
-\def_long_new:Npn \exp_args:Nccc #1#2#3#4{\exp_after:NN#1
- \cs:w#2\exp_after:NN\cs_end:\cs:w#3\exp_after:NN
- \cs_end:\cs:w #4\cs_end:}
+\cs_set:Npn \cs_generate_variant_aux:nnNn #1#2#3#4{
+ \cs_generate_variant_aux:nnw {#1}{#2} #4,?,\q_recursion_stop
+}
+% \end{macrocode}
+% Next is the real work to be done. We now have 1: base name, 2: base
+% signature, 3: 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.
+% \begin{macrocode}
+\cs_set:Npn \cs_generate_variant_aux:nnw #1 #2 #3, {
+ \if:w ? #3
+ \exp_after:wN \use_none_delimit_by_q_recursion_stop:w
+ \fi:
+% \end{macrocode}
+% Then check if the variant form has already been defined.
+% \begin{macrocode}
+ \cs_if_free:cTF {
+ #1:#3\use:c {use_none:\cs_generate_variant_aux:N #3 ?}#2
+ }
+ {
+% \end{macrocode}
+% If not, then define it and then additionally check if
+% the |\exp_args:N| form needed is defined.
+% \begin{macrocode}
+ \cs_new_nopar:cpx {
+ #1:#3 \use:c{use_none:\cs_generate_variant_aux:N #3 ?}#2
+ }
+ {
+ \exp_not:c { exp_args:N #3} \exp_not:c {#1:#2}
+ }
+ \cs_generate_internal_variant:n {#3}
+ }
+% \end{macrocode}
+% Otherwise tell that it was already defined.
+% \begin{macrocode}
+ {
+ \iow_log:x{
+ Variant~\token_to_str:c {
+ #1:#3\use:c {use_none:\cs_generate_variant_aux:N #3 ?}#2
+ }~already~defined;~ not~ changing~ it~on~line~
+ \tex_the:D \tex_inputlineno:D
+ }
+ }
+% \end{macrocode}
+% Recurse.
+% \begin{macrocode}
+ \cs_generate_variant_aux:nnw{#1}{#2}
+}
+% \end{macrocode}
+% The small loop for defining the required number of "n"s. Break when
+% seeing a "?".
+% \begin{macrocode}
+\cs_set: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}{\exp_args:Nco}
-% If we force that the third argument
-% always has braces, we could implement this function
-% with less tokens and only two arguments.
-% \begin{macrocode}
-\def_long_new:Npn \exp_args:Nco #1#2#3{\exp_after:NN#1\cs:w#2\exp_after:NN
- \cs_end:\exp_after:NN{#3}}
-% \end{macrocode}
-% \end{macro}
%
%
-% \begin{macro}{\exp_def_form:nnn}
-% This command is a recent addition which was actually added
-% when we wrote the article for TUGboat (while most of the other
-% code goes way back to 1993).
+% \begin{macro}{\cs_generate_internal_variant: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}
-\def:Npn\exp_def_form:nnn#1#2#3{
- \exp_after:NN
- \def:Npn
- \cs:w
- #1:#3
- \exp_after:NN
- \cs_end:
- \exp_after:NN
- {
- \cs:w
- exp_args:N#3
- \exp_after:NN
- \cs_end:
- \cs:w
- #1:#2
- \cs_end:
- }
+\cs_new:Npn \cs_generate_internal_variant:n #1 {
+ \cs_if_free:cT { exp_args:N #1 }{
% \end{macrocode}
-% We also have to test if |exp_args:N#3| is already defined
-% and if not define it via the
-% |\::| commands using the chars in |#3|
+% We use "new" to log the definition if we have to make one.
% \begin{macrocode}
- \cs_if_free:cT
- {exp_args:N#3}
- {\def:cpx {exp_args:N#3}
- {\exp_args_form_x:w #3 :}
- }
+ \cs_new:cpx { exp_args:N #1 }
+ { \cs_generate_internal_variant_aux:n #1 : }
+ }
}
% \end{macrocode}
% \end{macro}
%
-%
-% \begin{macro}{\exp_args_form_x:w}
+% \begin{macro}[aux]{\cs_generate_internal_variant_aux:n}
% 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}
-\def_new:Npn\exp_args_form_x:w #1 {
+\cs_new:Npn \cs_generate_internal_variant_aux:n #1 {
\exp_not:c{::#1}
- \if_meaning:NN #1 :
- \else:
- \exp_after:NN\exp_args_form_x:w
- \fi:}
+ \if_meaning:w #1 :
+ \exp_after:wN \use_none:n
+ \fi:
+ \cs_generate_internal_variant_aux:n
+}
% \end{macrocode}
% \end{macro}
%
-% Show token usage:
+% \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 -`0 \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 -`0 \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:NcV}
+%\begin{macro}{\exp_last_unbraced:NNo}
+%\begin{macro}{\exp_last_unbraced:NNV}
+%\begin{macro}{\exp_last_unbraced:NNNo}
+% Now the business end.
+% \begin{macrocode}
+\cs_new_nopar:Npn \exp_last_unbraced:Nf { \::f_unbraced \::: }
+\cs_new_nopar:Npn \exp_last_unbraced:NV { \::V_unbraced \::: }
+\cs_new_nopar:Npn \exp_last_unbraced:Nv { \::v_unbraced \::: }
+\cs_new_nopar:Npn \exp_last_unbraced:NcV {
+ \::c \::V_unbraced \:::
+}
+\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:NNV {
+ \::N \::V_unbraced \:::
+}
+\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}
+%
% \begin{macrocode}
%</initex|package>
+% \end{macrocode}
+%
+% Show token usage:
+% \begin{macrocode}
%<*showmemory>
\showMemUsage
%</showmemory>
% \end{macrocode}
%
-% \endinput
-%
-% $Log$
-% Revision 1.29 2006/07/30 15:43:38 morten
-% Minor touch-up plus added functions needed by clist module
-%
-% Revision 1.28 2006/06/03 18:56:31 morten
-% A few more functions
-%
-% Revision 1.27 2006/03/20 18:26:35 braams
-% Updated the copyright notice (2006) and demoted all implementation
-% sections to subsections and so on to clean up the toc for source3.tex
-%
-% Revision 1.26 2006/02/17 23:01:47 braams
-% Imported \exp_args:NNO from l3messages
-%
-% Revision 1.25 2005/12/27 10:00:45 morten
-% Changed RCS information retrieval
-%
-% Revision 1.24 2005/12/22 13:56:03 morten
-% Fixed error in \exp_args:NNd
-%
-% Revision 1.23 2005/12/21 20:44:30 morten
-% Corrected typo.
-%
-% Revision 1.22 2005/12/06 15:34:46 morten
-% Made \exp_not:o do what you'd expect
-%
-% Revision 1.21 2005/11/23 07:37:29 morten
-% A few new expansion types, we shall see if they will be useful.
-%
-% Revision 1.20 2005/04/12 16:44:06 morten
-% Fix to make it run as a package
-%
-% Revision 1.19 2005/04/12 13:24:07 morten
-% Minor updates
-%
-% Revision 1.18 2005/04/09 21:06:46 morten
-% Added yet another function.
-%
-% Revision 1.17 2005/04/06 21:38:10 morten
-% Added more functions.
-%
-% Revision 1.16 2005/03/26 21:09:44 morten
-% Added f argument type for "force expansion"
-%
-% Revision 1.15 2005/03/22 23:24:40 morten
-% Fixed documentation error.
-%
-% Revision 1.14 2005/03/16 22:36:37 braams
-% Added the tweaks necessary to be able to load with initex
-%
-% Revision 1.13 2005/03/11 21:37:37 braams
-% Fixed the use of RCS information
+% \end{implementation}
+% \PrintIndex
%
+% \endinput
diff --git a/Master/texmf-dist/source/latex/expl3/l3file.dtx b/Master/texmf-dist/source/latex/expl3/l3file.dtx
new file mode 100644
index 00000000000..e5e3a5e159c
--- /dev/null
+++ b/Master/texmf-dist/source/latex/expl3/l3file.dtx
@@ -0,0 +1,412 @@
+% \iffalse
+%% File: l3file.dtx Copyright (C) 2009 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 LaTeX Project Team.
+%%
+%% -----------------------------------------------------------------------
+%%
+%
+%<*driver|package>
+\RequirePackage{l3names}
+%</driver|package>
+%\fi
+\GetIdInfo$Id: l3file.dtx 1352 2009-05-28 11:50:39Z morten $
+ {L3 Experimental file loading}
+%\iffalse
+%<*driver>
+%\fi
+\ProvidesFile{\filename.\filenameext}
+ [\filedate\space v\fileversion\space\filedescription]
+%\iffalse
+\documentclass[full]{l3doc}
+\begin{document}
+ \DocInput{l3file.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{The \textsf{l3file} package\thanks{This file
+% has version number \fileversion, last
+% revised \filedate.}\\
+% File Loading}
+% \author{\Team}
+% \date{\filedate}
+% \maketitle
+%
+% \begin{documentation}
+%
+%\section{Loading files}
+%
+% The need to test if a file is available and to load a file if found is
+% covered at a low level here.
+%
+%\begin{function}{
+% \file_if_exist_p:n|
+% \file_if_exist:n / (TF)
+%}
+% \begin{syntax}
+% "\file_if_exist:nTF" <file> <true code> <false code>
+% \end{syntax}
+% Tests if <file> exists.
+% \begin{texnote}
+% This is \LaTeXe's \cs{IfFileExists}, although it does not return
+% name of the file (\emph{cf.}~\cs{@filef@und}).
+% \end{texnote}
+%\end{function}
+%
+%\begin{function}{\file_add_path:nN}
+% \begin{syntax}
+% "\file_add_path:nN" <file> <tl~var.>
+% \end{syntax}
+% Searches for <file> on the \TeX\ path and using
+% \cs{l_file_search_path_clist}. If <file> is found, <tl~var.> is set
+% to the file name plus any path information needed. If <file> is not
+% found, <tl~var.> will be blank.
+% \begin{texnote}
+% This is similar to obtaining \cs{@filef@und} from \LaTeXe's
+% \cs{IfFileExists}.
+% \end{texnote}
+%\end{function}
+%
+%\begin{function}{\file_input:n}
+% \begin{syntax}
+% "\file_input:n" <file>
+% \end{syntax}
+% Inputs <file> if it found (according to the same rule as for
+% \cs{file_if_exist:n}.
+% \begin{texnote}
+% This acts in a similar way to \LaTeXe's \cs{input}, as it will not
+% lead to a \TeX\ loop if the file is not found.
+% \end{texnote}
+%\end{function}
+%
+%\begin{function}{\file_input_no_record:n}
+% \begin{syntax}
+% "\file_input_no_record:n" <file>
+% \end{syntax}
+% Inputs <file> if it found (according to the same rule as for
+% \cs{file_if_exist:n}, but does not add it to
+% \cs{g_file_record_clist}. The file is still added to
+% \cs{g_file_record_full_clist}.
+% \begin{texnote}
+% This is similar to \LaTeXe's \cs{@input@}.
+% \end{texnote}
+%\end{function}
+%
+%\begin{function}{
+% \file_input_no_check:n|
+% \file_input_no_check_no_record:n|
+%}
+% \begin{syntax}
+% "\file_input_no_check:n" <file>
+% \end{syntax}
+% Inputs <file> directly without checking if it exists. The
+% \texttt{no_record} version does not record the input in
+% \begin{texnote}\cs{g_file_record_clist}.
+% These are simple wrappers around the \TeX\ \cs{input} primitive
+% \end{texnote}
+%\end{function}
+%
+%\begin{function}{
+% \file_list:|
+% \file_list_full:|
+%}
+% \begin{syntax}
+% "\file_list:" <file>
+% \end{syntax}
+% Lists files loaded in current \LaTeX\ run: the \texttt{full} version
+% lists all files.
+%\end{function}
+%
+%\section{Variables and constants}
+%
+%\begin{variable}{
+% \g_file_record_clist|
+% \g_file_record_full_clist
+%}
+% Used to track the files that have been loaded.
+%\end{variable}
+%
+%\begin{variable}{\l_file_search_path_clist}
+% List of paths to search for a file in addition to those searched by
+% \TeX.
+% \begin{texnote}
+% This is \cs{input@path} in \LaTeXe.
+% \end{texnote}
+%\end{variable}
+%
+%\begin{variable}{\l_file_test_read_stream}
+% Input stream used to carry out file tests.
+%\end{variable}
+%
+%\begin{variable}{\l_file_tmp_bool}
+% Internal scratch switch.
+%\end{variable}
+%
+%\begin{variable}{\l_file_tmp_tl}
+% Internal scratch token list variable.
+%\end{variable}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3file} implementation}
+%
+% The usual lead-off.
+% \begin{macrocode}
+%<*package>
+\ProvidesExplPackage
+ {\filename}{\filedate}{\fileversion}{\filedescription}
+\package_check_loaded_expl:
+%</package>
+%<*initex|package>
+% \end{macrocode}
+%
+%\begin{macro}{\g_file_record_clist}
+%\begin{macro}{\g_file_record_full_clist}
+% When files are read with logging, the names are added here. There are
+% two lists, one for everything and one for only those items which might
+% later be listed (as in \LaTeXe's \cs{listfiles}).
+% \begin{macrocode}
+\clist_new:N \g_file_record_clist
+\clist_new:N \g_file_record_full_clist
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%
+%\begin{macro}{\l_file_search_path_clist}
+% Checking input needs a stream to work with
+% \begin{macrocode}
+\clist_new:N \l_file_search_path_clist
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\l_file_test_read_stream}
+% Checking input needs a stream to work with
+% \begin{macrocode}
+\ior_new:N \l_file_test_read_stream
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\l_file_tmp_bool}
+% A flag is needed for internal purposes.
+% \begin{macrocode}
+\bool_new:N \l_file_tmp_bool
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\l_file_tmp_tl}
+% A scratch token list variable.
+% \begin{macrocode}
+\tl_new:N \l_file_tmp_tl
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\file_if_exist_p:n}
+%\begin{macro}[TF]{\file_if_exist:n}
+%\begin{macro}[aux]{\file_if_exist_path:n}
+%\begin{macro}[aux]{\file_if_exist_aux:n}
+% Checking if a file exists takes place in two parts. First, there is
+% a simple check ``here''. If that fails, then there is a loop over
+% the current search path.
+% \begin{macrocode}
+\prg_new_conditional:Nnn \file_if_exist:n {p,TF,T,F} {
+ \ior_open:Nn \l_file_test_read_stream {#1}
+ \ior_if_eof:NTF \l_file_test_read_stream {
+ \file_if_exist_path:n {#1}
+ }{
+ \ior_close:N \l_file_test_read_stream
+ \prg_return_true:
+ }
+}
+\cs_new_nopar:Nn \file_if_exist_path:n {
+ \bool_set_false:N \l_file_tmp_bool
+ \cs_set_nopar:Nn \file_if_exist_aux:n {
+ \ior_open:Nn \l_file_test_read_stream { #1 ##1 }
+ \ior_if_eof:NF \l_file_test_read_stream {
+ \bool_set_true:N \l_file_tmp_bool
+ \clist_map_break:
+ }
+ }
+%</initex|package>
+%<*package>
+ \cs_if_exist:NT \input@path {
+ \cs_set_eq:NN \l_file_search_path_clist \input@path
+ }
+%</package>
+%<*initex|package>
+ \clist_map_function:NN \l_file_search_path_clist \file_if_exist_aux:n
+ \ior_close:N \l_file_test_read_stream
+ \bool_if:NTF \l_file_tmp_bool {
+ \prg_return_true:
+ }{
+ \prg_return_false:
+ }
+}
+\cs_new_nopar:Nn \file_if_exist_aux:n { }
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%
+%\begin{macro}{\file_add_path:nN}
+%\begin{macro}[aux]{\file_add_path_search:n}
+%\begin{macro}[aux]{\file_add_path_aux:n}
+% Checking if a file exists takes place in two parts. First, there is
+% a simple check ``here''. If that fails, then there is a loop over
+% the current search path.
+% \begin{macrocode}
+\cs_new_nopar:Nn \file_add_path:nN {
+ \tl_clear:N #2
+ \ior_open:Nn \l_file_test_read_stream {#1}
+ \ior_if_eof:NTF \l_file_test_read_stream {
+ \file_add_path_search:nN {#1} #2
+ }{
+ \tl_set:Nn #2 {#1}
+ }
+ \ior_close:N \l_file_test_read_stream
+}
+\cs_new_nopar:Nn \file_add_path_search:nN {
+ \cs_set_nopar:Nn \file_add_path_aux:n {
+ \ior_open:Nn \l_file_test_read_stream { ##1 #1 }
+ \ior_if_eof:NF \l_file_test_read_stream {
+ \tl_set:Nn #2 { ##1 #1 }
+ \clist_map_break:
+ }
+ }
+%</initex|package>
+%<*package>
+ \cs_if_exist:NT \input@path {
+ \cs_set_eq:NN \l_file_search_path_clist \input@path
+ }
+%</package>
+%<*initex|package>
+ \clist_map_function:NN \l_file_search_path_clist \file_add_path_aux:n
+}
+\cs_new_nopar:Nn \file_add_path_aux:n { }
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%
+%\begin{macro}{\file_input:n}
+%\begin{macro}{\file_input_no_record:n}
+% \cs{file_add_path:nN} will return an empty token list variable if the
+% file is not found. This is used rather than \cs{file_if_exist:nT} here
+% as it saves running the same loop twice.
+% \begin{macrocode}
+\cs_new:Nn \file_input:n {
+ \file_add_path:nN {#1} \l_file_tmp_tl
+ \tl_if_empty:NF \l_file_tmp_tl {
+ \file_input_no_check:n \l_file_tmp_tl
+ }
+}
+\cs_new:Nn \file_input_no_record:n {
+ \file_add_path:nN {#1} \l_file_tmp_tl
+ \tl_if_empty:NF \l_file_tmp_tl {
+ \file_input_no_check_no_record:n \l_file_tmp_tl
+ }
+}
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%
+%\begin{macro}{\file_input_no_check:n}
+% File input records what is going on before setting to work.
+% \begin{macrocode}
+\cs_new_nopar:Nn \file_input_no_check:n {
+ \clist_gput_right:Nx \g_file_record_clist {#1}
+ \wlog{ADDING: #1}
+%</initex|package>
+%<*package>
+ \@addtofilelist {#1}
+%</package>
+%<*initex|package>
+ \clist_gput_right:Nx \g_file_record_full_clist {#1}
+ \tex_input:D #1 ~
+}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\file_input_no_check_no_record:n}
+% Inputting a file without adding to the main record is basically the
+% same: even in this case the file goes on the full log.
+% \begin{macrocode}
+\cs_new_nopar:Nn \file_input_no_check_no_record:n {
+ \clist_gput_right:Nx \g_file_record_full_clist {#1}
+ \tex_input:D #1 ~
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\file_list:}
+%\begin{macro}{\file_list_full:}
+%\begin{macro}[aux]{\file_list:N}
+% Two functions to list all files used to the log: the \texttt{full}
+% version includes everything whereas the standard version uses the
+% shorter record.
+% \begin{macrocode}
+\cs_new_nopar:Nn \file_list: {
+ \file_list:N \g_file_record_clist
+}
+\cs_new_nopar:Nn \file_list_full: {
+ \file_list:N \g_file_record_full_clist
+}
+\cs_new_nopar:Nn \file_list:N {
+ \clist_remove_duplicates:N #1
+ \iow_log:x { *~File~List~* }
+ \clist_map_function:NN #1 \file_list_aux:n
+ \iow_log:x { ************* }
+}
+\cs_new_nopar:Nn \file_list_aux:n {
+ \iow_log:x { #1 }
+}
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%\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}
+%</initex|package>
+%<*package>
+% \begin{macrocode}
+\AtBeginDocument{
+ \clist_put_right:NV \g_file_record_clist \@filelist
+ \clist_put_right:NV \g_file_record_full_clist \@filelist
+}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/Master/texmf-dist/source/latex/expl3/l3final.dtx b/Master/texmf-dist/source/latex/expl3/l3final.dtx
index f23db756876..65da64c7f7f 100644
--- a/Master/texmf-dist/source/latex/expl3/l3final.dtx
+++ b/Master/texmf-dist/source/latex/expl3/l3final.dtx
@@ -17,7 +17,7 @@
%%
%% The development version of the bundle can be found at
%%
-%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/
+%% http://www.latex-project.org/svnroot/experimental/trunk/
%%
%% for those people who are interested.
%%
@@ -37,7 +37,7 @@
%</driver|package>
%<*-ini>
%\fi
-\GetIdInfo$Id: l3final.dtx 621 2007-09-01 20:14:19Z morten $
+\GetIdInfo$Id: l3final.dtx 1362 2009-05-28 20:19:21Z joseph $
{L3 Experimental final module}
%\iffalse
%</-ini>
@@ -46,7 +46,7 @@
\ProvidesFile{\filename.\filenameext}
[\filedate\space v\fileversion\space\filedescription]
%\iffalse
-\documentclass{l3doc}
+\documentclass[full]{l3doc}
\begin{document}
\DocInput{\filename.\filenameext}
\end{document}
@@ -63,15 +63,9 @@
% Some of the macros needed in creating the format are no longer
% needed and will either be removed are modified to generate error
% messages.
-%<*initex>
-%
-% \subsection{Closing the error file}
%
-% Earlier on in the format a file was opened to collect all the
-% error messages. This file needs to be closed before the format is
-% dumped.
% \begin{macrocode}
-\err_file_close:N\c_kernel_err_tlp
+%<*initex>
% \end{macrocode}
%
% \subsection{Dumping the format}
@@ -80,45 +74,7 @@
% \begin{macrocode}
\tex_dump:D
% \end{macrocode}
-%</initex>
-% \subsection{Creating the format}
%
-% There is one more thing needed for creating the format; a file
-% called \file{lbase.ini}. For now this is included here.
-%<*ini>
% \begin{macrocode}
-%% Derived from a file by Thomas Esser
-
-\ifx\pdfoutput\undefined \else
- \ifx\pdfoutput\relax \else
- % We're building the latex format with the pdfetex engine (started 2004).
- % See this file for details.
- \input pdftex-dvi.tex
- \fi
-\fi
-
-%% the usual format initialization.
-%%\scrollmode
-\input lbase.ltx
-\endinput
+%</initex>
% \end{macrocode}
-%</ini>
-% \endinput
-%
-% $Log$
-% Revision 1.5 2006/03/19 15:03:22 braams
-% Added code to close the kernel error file
-%
-% Revision 1.4 2006/01/13 23:20:07 braams
-% Added lbase.ini to be generated from this file
-%
-% Revision 1.3 2005/12/27 16:01:48 morten
-% Changed RCS information retrieval
-%
-% Revision 1.2 2005/04/12 22:48:24 braams
-% Corrected a slight mistake
-%
-% Revision 1.1 2005/04/12 22:41:38 braams
-% This file will contain al the last minute things needed in the format.
-% For starters it just dumps the format.
-%
diff --git a/Master/texmf-dist/source/latex/expl3/l3format.ins b/Master/texmf-dist/source/latex/expl3/l3format.ins
index cc3d0d984b8..f42ea71724d 100644
--- a/Master/texmf-dist/source/latex/expl3/l3format.ins
+++ b/Master/texmf-dist/source/latex/expl3/l3format.ins
@@ -1,72 +1,75 @@
-
-\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
-
-\keepsilent
-
-% generate the format file
-\generate{%
- \file{lbase.ltx}{%
- \from{l3names.dtx}{initex} % The naming conventions
- \from{l3basics.dtx}{initex} % Initialisations
- \from{l3chk.dtx}{initex} % Checking functions
- \from{l3tlp.dtx}{initex} % token list pointers
- \from{l3expan.dtx}{initex} % Controlling expansion of arguments
- \from{l3quark.dtx}{initex} % quarks
- \from{l3num.dtx}{initex} % Storing integers in macros
- \from{l3seq.dtx}{initex} % Sequences and Stacks
- \from{l3alloc.dtx}{initex} % Register allocations
- \from{l3io.dtx}{initex} % dealing with I/O
- \from{l3int.dtx}{initex} % dealing with integer registers
- \from{l3clist.dtx}{initex} % Comma separated lists
- \from{l3prop.dtx}{initex} % property lists
- \from{l3token.dtx}{initex} % token investigation
-%
- \from{l3vers.dtx}{initex} % Version information
-%
- \from{l3skip.dtx}{initex} % dealing with skip registers
- \from{l3toks.dtx}{initex} % dealing with token registers
- \from{l3messages.dtx}{initex} % seting up for user communication
- \from{l3box.dtx}{initex} % dealing with box registers
- \from{l3precom.dtx}{initex,precompile} %
- \from{l3prg.dtx}{initex} % Program control structures
- \from{l3xref.dtx}{initex} % Cross references
-%
- \from{l3final.dtx}{initex} % Final wrap-up
- }
-}
-% generate the format initialisation file
-\generate{%
- \file{lbase.ini}{%
- \from{l3final.dtx}{ini}
- }
-}
-
-\Msg{}
-\Msg{*************************************}
-\Msg{*}
-\Msg{* Now run (PDF)EINITEX on *lbase.ini}
-\Msg{*}
-\Msg{* On an up to date system, run }
-\Msg{* pdfetex -ini "*lbase.ini" }
-\Msg{*}
-\Msg{*************************************}
-\Msg{}
-
-\endbatchfile
+
+\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
+
+\keepsilent
+
+% generate the format file
+\generate{%
+ \file{lbase.ltx}{%
+ \from{l3names.dtx}{initex} % The naming conventions
+ \from{l3basics.dtx}{initex} % Initialisations
+ \from{l3expan.dtx}{initex} % Controlling expansion of arguments
+ \from{l3tl.dtx}{initex} % token list variables
+ \from{l3num.dtx}{initex} % Storing integers in macros
+ \from{l3intexpr.dtx}{initex} %
+ \from{l3quark.dtx}{initex} % quarks
+ \from{l3seq.dtx}{initex} % Sequences and stacks
+%
+ \from{l3alloc.dtx}{initex} % Register allocations
+%
+ \from{l3toks.dtx}{initex} % dealing with token registers
+ \from{l3int.dtx}{initex} % dealing with integer registers
+ \from{l3prg.dtx}{initex} % Program control structures
+ \from{l3clist.dtx}{initex} % Comma separated lists
+ \from{l3token.dtx}{initex} % token investigation
+ \from{l3io.dtx}{initex} % dealing with I/O
+ \from{l3prop.dtx}{initex} % property lists
+ \from{l3msg.dtx}{initex} % setting up for user communication
+ \from{l3skip.dtx}{initex} % dealing with skip registers
+ \from{l3box.dtx}{initex} % dealing with box registers
+ \from{l3keyval.dtx}{initex} %
+%
+% \from{l3precom.dtx}{initex,precompile} %
+%
+ \from{l3calc.dtx}{initex} %
+ \from{l3xref.dtx}{initex} % Cross references
+ \from{l3file.dtx}{initex} % file loading
+%
+ \from{l3vers.dtx}{initex} % Version information
+%
+%
+% \from{l3chk.dtx}{initex} % Checking functions
+%
+ \from{l3final.dtx}{initex} % Final wrap-up
+ }
+}
+
+\Msg{}
+\Msg{*************************************}
+\Msg{*}
+\Msg{* Now run (PDF)INITEX on lbase.ltx}
+\Msg{*}
+\Msg{* On an up to date system, run }
+\Msg{* pdftex -ini *lbase.ltx }
+\Msg{*}
+\Msg{*************************************}
+\Msg{}
+
+\endbatchfile
diff --git a/Master/texmf-dist/source/latex/expl3/l3int.dtx b/Master/texmf-dist/source/latex/expl3/l3int.dtx
index 5b13df9cec4..815f7610e9c 100644
--- a/Master/texmf-dist/source/latex/expl3/l3int.dtx
+++ b/Master/texmf-dist/source/latex/expl3/l3int.dtx
@@ -1,5 +1,5 @@
% \iffalse
-%% File: l3int.dtx Copyright (C) 1990-2008 LaTeX3 project
+%% File: l3int.dtx Copyright (C) 1990-2009 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
@@ -17,7 +17,7 @@
%%
%% The development version of the bundle can be found at
%%
-%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/
+%% http://www.latex-project.org/svnroot/experimental/trunk/
%%
%% for those people who are interested.
%%
@@ -36,7 +36,7 @@
\RequirePackage{l3names}
%</driver|package>
%\fi
-\GetIdInfo$Id: l3int.dtx 738 2008-08-01 13:21:42Z morten $
+\GetIdInfo$Id: l3int.dtx 1362 2009-05-28 20:19:21Z joseph $
{L3 Experimental Integer module}
%\iffalse
%<*driver>
@@ -44,9 +44,9 @@
\ProvidesFile{\filename.\filenameext}
[\filedate\space v\fileversion\space\filedescription]
%\iffalse
-\documentclass{l3doc}
+\documentclass[full]{l3doc}
\begin{document}
-\DocInput{\filename.\filenameext}
+\DocInput{l3int.dtx}
\end{document}
%</driver>
% \fi
@@ -55,12 +55,12 @@
% \title{The \textsf{l3int} package\thanks{This file
% has version number \fileversion, last
% revised \filedate.}\\
-% Counters}
+% Integers/counters}
% \author{\Team}
% \date{\filedate}
% \maketitle
%
-% \section{Integers}
+% \begin{documentation}
%
% \LaTeX3 maintains two type of integer registers for internal use.
% One (associated with the name "num") for low level uses in the
@@ -72,12 +72,12 @@
% preferred in all cases as there is little chance we should ever run
% out of registers when being based on at least \eTeX.
%
-% \subsection{Functions}
+% \section{Functions}
%
% \begin{function}{%
% \int_new:N |
% \int_new:c |
-% \int_new_l:N |
+%^^A \int_new_l:N |
% }
% \begin{syntax}
% "\int_new:N" <int>
@@ -85,7 +85,7 @@
% Globally defines <int> to be a new variable of type "int" although
% you can still choose if it should be a an "\l_" or "\g_" type.
% There is no way to define constant counters with these functions.
-% The function "\int_new_l:N" defines <int> locally only.
+%^^A The function "\int_new_l:N" defines <int> locally only.
% \begin{texnote}
% "\int_new:N" is the equivalent to plain \TeX{}'s \tn{newcount}.
% However, the internal register allocation is done differently.
@@ -125,7 +125,7 @@
% \int_gset:cn |
% }
% \begin{syntax}
-% "\int_set:Nn" <int> "{" <integer expr> "}"
+% "\int_set:Nn" <int> \Arg{integer expr}
% \end{syntax}
% These functions will set the <int> register to the <integer expr>
% value. This value can contain simple calc-like expressions as
@@ -154,7 +154,7 @@
% \int_gadd:cn |
% }
% \begin{syntax}
-% "\int_add:Nn" <int> "{" <integer expr> "}"
+% "\int_add:Nn" <int> \Arg{integer expr}
% \end{syntax}
% These functions will add to the <int> register the value <integer
% expr>. If the second argument is a <int> register too, the
@@ -168,7 +168,7 @@
% \int_gsub:cn |
% }
% \begin{syntax}
-% "\int_gsub:Nn" <int> "{" <integer expr> "}"
+% "\int_gsub:Nn" <int> \Arg{integer expr}
% \end{syntax}
% These functions will subtract from the <int> register the value
% <integer expr>. If the second argument is a <int> register too, the
@@ -193,18 +193,34 @@
% \end{texnote}
% \end{function}
%
-% \subsection{Formatting a counter value}
+% \begin{function}{ \int_show:N |
+% \int_show:c }
+% \begin{syntax}
+% "\int_show:N" <int>
+% \end{syntax}
+% This function pauses the compilation and displays the integer value kept
+% in <int> in the console output and log file.
+% \begin{texnote}
+% The function "\int_show:N" could be implemented directly as the \TeX{}
+% primitive "\tex_showthe:D" which is also responsible to produce the values for
+% other internal quantities. We have chosen to use individual functions
+% for counters, dimensions etc.\ to allow checks and to make the code
+% more self-explaining.
+% \end{texnote}
+% \end{function}
+%
+% \section{Formatting a counter value}
%
% \begin{function}{
-% \int_to_arabic:n |
-% \int_to_alph:n |
-% \int_to_Alph:n |
-% \int_to_roman:n |
-% \int_to_Roman:n |
-% \int_to_symbol:n |
+% \int_to_arabic:n / (EXP) |
+% \int_to_alph:n / (EXP) |
+% \int_to_Alph:n / (EXP) |
+% \int_to_roman:n / (EXP) |
+% \int_to_Roman:n / (EXP) |
+% \int_to_symbol:n / (EXP) |
% }
% \begin{syntax}
-% "\int_to_alph:n" "{" <integer> "}"
+% "\int_to_alph:n" \Arg{integer}
% "\int_to_alph:n" <int>
% \end{syntax}
% If some <integer> or the the current value of a <int> should be
@@ -228,9 +244,9 @@
% \end{texnote}
% \end{function}
%
-% \subsubsection{Internal functions}
+% \subsection{Internal functions}
%
-% \begin{function}{\int_to_roman:w}
+% \begin{function}{\int_to_roman:w / (EXP)}
% \begin{syntax}
% "\int_to_roman:w" <integer> <space> \textit{or} <non-expandable token>
% \end{syntax}
@@ -240,12 +256,24 @@
% This is the \TeX{} primitive \tn{romannumeral} renamed.
% \end{texnote}
% \end{function}
+%
+% \begin{function}{\int_to_number:w / (EXP)}
+% \begin{syntax}
+% "\int_to_number:w" <integer> <space>
+% \end{syntax}
+% Converts <integer> to its numerical string. Note that
+% it produces a string of letters with catcode 12.
+% \begin{texnote}
+% This is the \TeX{} primitive \tn{number} renamed.
+% \end{texnote}
+% \end{function}
+%
% \begin{function}{
% \int_roman_lcuc_mapping:Nnn |
% \int_to_roman_lcuc:NN |
% }
% \begin{syntax}
-% "\int_roman_lcuc_mapping:Nnn" <roman_char> "{"<licr>"}" "{"<LICR>"}"
+% "\int_roman_lcuc_mapping:Nnn" <roman_char> \Arg{licr} \Arg{LICR}
% "\int_to_roman_lcuc:NN" <roman_char> <char>
% \end{syntax}
% "\int_roman_lcuc_mapping:Nnn" specifies how the roman
@@ -264,8 +292,8 @@
% \int_symbol_text_conversion_rule:n |
% }
% \begin{syntax}
-% "\int_convert_number_with_rule:nnN" "{"<int1>"}" "{"<int2>"}" <function>
-% "\int_alph_default_conversion_rule:n" "{"<int>"}"
+% "\int_convert_number_with_rule:nnN" \Arg{int1} \Arg{int2} <function>
+% "\int_alph_default_conversion_rule:n" \Arg{int}
% \end{syntax}
% "\int_convert_number_with_rule:nnN" converts <int1> into letters,
% symbols, whatever as defined by <function>. <int2> denotes the base
@@ -277,7 +305,34 @@
%
%
%
-% \subsection{Variable and constants}
+% \section{Variable and constants}
+%
+% \begin{function}{%
+% \int_const:Nn |
+% }
+% \begin{syntax}
+% "\int_const:Nn" "\c_"<value> \Arg{value}
+% \end{syntax}
+% Defines an integer constant of a certain <value>. If the constant is negative
+% or very large it internally uses an <int> register.
+% \end{function}
+%
+% \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_hundred_one |
+% \c_twohundred_fifty_five | \c_twohundred_fifty_six |
+% \c_thousand |
+% \c_ten_thousand | \c_ten_thousand_one |
+% \c_ten_thousand_two | \c_ten_thousand_three |
+% \c_ten_thousand_four | \c_twenty_thousand }
+% Set of constants denoting useful values.
+% \begin{texnote}
+% Some of these constants have been available under \LaTeX2 under names
+% like \tn{m@ne}, \tn{z@}, \tn{@ne},\tn{tw@}, \tn{thr@@}, etc.
+% \end{texnote}
+% \end{variable}
%
% \begin{variable}{%
% \c_max_int |
@@ -299,149 +354,87 @@
% \end{variable}
%
%
-% \subsection{Testing and evaluating integer expressions}
%
-% \begin{function}{%
-% \int_eval:n |
-% \int_div_truncate:nn |
-% \int_div_round:nn |
-% \int_mod:nn |
-% }
-% \begin{syntax}
-% "\int_eval:n" "{"<int~expr>"}" \\
-% "\int_div_truncate:n" "{"<int~expr>"}" "{"<int~expr>"}" \\
-% "\int_mod:nn" "{"<int~expr>"}" "{"<int~expr>"}"
-% \end{syntax}
-% Evaluates the value of a integer expression so that
-% "\int_eval:n {3*5/4}" puts "4" back into the input stream. Note that
-% the results of divisions are rounded by the primitive operations. If
-% you want the result of a division to be truncated use
-% "\int_div_truncate:nn". "\int_div_round:nn" is added for
-% completeness. "\int_mod:nn" returns the remainder of a division. All
-% of these functions are expandable.
-% \begin{texnote}
-% "\int_eval:n" is the \eTeX primitive \tn{numexpr} turned into a function
-% taking an argument.
-% \end{texnote}
-% \end{function}
%
-% \begin{function}{%
-% \int_compare:nNnTF |
-% \int_compare:nNnT |
-% \int_compare:nNnF |
-% }
-% \begin{syntax}
-% "\int_compare:nNnTF" "{"<int~expr>"}" <rel> "{"<int~expr>"}"
-% "{"<true>"}" "{"<false>"}"
-% \end{syntax}
-% These functions test two integer expressions against each other. They
-% are both evaluated by "\int_eval:n". Note that if both expressions
-% are normal integer variables as in
-% \begin{quote}
-% "\int_compare:nNnTF \l_temp_int < \c_zero {negative}{non-negative}"
-% \end{quote}
-% you can safely omit the braces.
-% \begin{texnote}
-% This is the \TeX{} primitive \tn{ifnum} turned into a function.
-% \end{texnote}
-% \end{function}
+% \section{Conversion}
%
% \begin{function}{%
-% \int_compare_p:nNn |
+% \int_convert_from_base_ten:nn |
% }
% \begin{syntax}
-% "\int_compare_p:nNn" "{"<int~expr>"}" <rel> "{"<int~expr>"}"
+% "\int_convert_from_base_ten:nn" \Arg{number} \Arg{base}
% \end{syntax}
-% A predicate version of the above mentioned functions.
+% Converts the base~10 number <number> into its equivalent
+% representation written in base~<base>. Expandable.
% \end{function}
%
-% \begin{function}{%
-% \int_max_of:nn |
-% \int_min_of:nn |
-% }
-% \begin{syntax}
-% "\int_max_of:nn" "{"<int~expr>"}" "{"<int~expr>"}"
-% \end{syntax}
-% Return the largest or smallest of two integer expressions.
-% \end{function}
%
% \begin{function}{%
-% \int_abs:n |
+% \int_convert_to_base_ten:nn |
% }
% \begin{syntax}
-% "\int_abs:n" "{"<int~expr>"}"
+% "\int_convert_to_base_ten:nn" \Arg{number} \Arg{base}
% \end{syntax}
-% Return the numerical value of an integer expression.
+% Converts the base~<base> number <number> into its equivalent
+% representation written in base~10. <number> can consist of digits
+% and ascii letters. Expandable.
% \end{function}
%
-% \begin{function}{%
-% \int_if_odd:nTF |
-% \int_if_odd_p:n |
-% }
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3int} implementation}
+%
+% \subsection{Internal functions and variables}
+%
+% \begin{function}{\int_advance:w}
% \begin{syntax}
-% "\int_if_odd:nTF" "{"<int~expr>"}" "{"<true>"}" "{"<false>"}"
+% "\int_advance:w" <int register> <optional `\texttt{by}'> <number> <space>
% \end{syntax}
-% These functions test if an integer expression is even or odd. We
-% also define a predicate version of it.
+% Increments the count register by the specified amount.
% \begin{texnote}
-% This is the \TeX{} primitive \tn{ifodd} turned into a function.
+% This is \TeX's \tn{advance}.
% \end{texnote}
% \end{function}
%
-% \begin{function}{%
-% \int_whiledo:nNnT |
-% \int_whiledo:nNnF |
-% \int_dowhile:nNnT |
-% \int_dowhile:nNnF |
-% }
+%
+% \begin{function}{\int_convert_number_to_letter:n / (EXP)}
% \begin{syntax}
-% "\int_whiledo:nNnT" <int expr> <rel> <int~expr> "{"<true>"}"
+% "\int_convert_number_to_letter:n" \Arg{integer expression}
% \end{syntax}
-% "\int_whiledo:nNnT" tests the integer expressions and if true performs
-% the body "T" until the test fails. "\int_dowhile:nNnT" is similar
-% but executes the body first and then performs the check, thus
-% ensuring that the body is executed at least once. The "F" versions
-% are similar but continue the loop as long as the test is false. They
-% could be omitted as it is just a matter of switching the arguments
-% in the test.
+% Internal function for turning a number for a different base into a letter or digit.
% \end{function}
%
-
-% \subsection{Conversion}
-%
-% \begin{function}{%
-% \int_convert_from_base_ten:nn |
-% }
+% \begin{function}{\int_pre_eval_one_arg:Nn | \int_pre_eval_two_args:Nnn}
% \begin{syntax}
-% "\int_convert_from_base_ten:nn" "{"<number>"}""{"<base>"}"
+% "\int_pre_eval_one_arg:Nn" <function> \Arg{integer expression}
+% "\int_pre_eval_one_arg:Nnn" <function> \Arg{int~expr~1} \Arg{int~expr~2}
% \end{syntax}
-% Converts the base~10 number <number> into its equivalent
-% representation written in base~<base>. Expandable.
+% These are expansion helpers; they evaluate their integer expressions
+% before handing them off to the specified <function>.
% \end{function}
%
-%
-% \begin{function}{%
-% \int_convert_to_base_ten:nn |
-% }
+% \begin{function}{ \int_get_sign_and_digits:n / (EXP) |
+% \int_get_sign:n / (EXP ) |
+% \int_get_digits:n / (EXP) }
% \begin{syntax}
-% "\int_convert_to_base_ten:nn" "{"<number>"}""{"<base>"}"
+% "\int_get_sign_and_digits:n" \Arg{number}
% \end{syntax}
-% Converts the base~<base> number <number> into its equivalent
-% representation written in base~10. <number> can consist of digits
-% and ascii letters. Expandable.
+% From an argument that may or may not include a "+" or "-" sign, these
+% functions expand to the respective components of the number.
% \end{function}
%
-%
-% \StopEventually{}
-% \subsection{The Implementation}
-%
+% \subsection{Module loading and primitives definitions}
%
% We start by ensuring that the required packages are loaded.
% \begin{macrocode}
-%<package>\ProvidesExplPackage
-%<package> {\filename}{\filedate}{\fileversion}{\filedescription}
-%<package&!check>\RequirePackage{l3num}
-%<package&check>\RequirePackage{l3chk}
+%<*package>
+\ProvidesExplPackage
+ {\filename}{\filedate}{\fileversion}{\filedescription}
+\package_check_loaded_expl:
+%</package>
%<*initex|package>
% \end{macrocode}
%
@@ -450,9 +443,9 @@
% \begin{macro}{\int_advance:w}
% A new name for the primitives.
% \begin{macrocode}
-\let_new:NN \int_to_roman:w \tex_romannumeral:D
-\let_new:NN \int_to_number:w \tex_number:D
-\let_new:NN \int_advance:w \tex_advance:D
+\cs_new_eq:NN \int_to_roman:w \tex_romannumeral:D
+\cs_new_eq:NN \int_to_number:w \tex_number:D
+\cs_new_eq:NN \int_advance:w \tex_advance:D
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -460,6 +453,63 @@
% Functions that support \LaTeX's user accessible counters should be
% added here, too. But first the internal counters.
%
+% \subsection{Allocation and setting}
+%
+% \begin{macro}{\int_new:N,\int_new:c}
+%^^A \begin{macro}{\int_new_l:N}
+% Allocation of a new internal counter is already done above. Here we define
+% the next likely variant.
+%
+% For the \LaTeX3 format:
+% \begin{macrocode}
+%<*initex>
+\alloc_setup_type:nnn {int} {11} \c_max_register_num
+\cs_new_nopar:Npn \int_new:N #1 {\alloc_reg:NnNN g {int} \tex_countdef:D#1}
+\cs_new_nopar:Npn \int_new_l:N #1 {\alloc_reg:NnNN l {int} \tex_countdef:D#1}
+%</initex>
+% \end{macrocode}
+% For `l3in2e':
+% \begin{macrocode}
+%<*package>
+\cs_new_nopar:Npn \int_new:N #1 {
+ \chk_if_free_cs:N #1
+ \newcount #1
+}
+%</package>
+% \end{macrocode}
+% \begin{macrocode}
+\cs_generate_variant:Nn \int_new:N {c}
+% \end{macrocode}
+% \end{macro}
+%^^A \end{macro}
+%
+%
+% \begin{macro}{\int_set:Nn}
+% \begin{macro}{\int_set:cn}
+% \begin{macro}{\int_gset:Nn}
+% \begin{macro}{\int_gset:cn}
+% Setting counters is again something that I would like to make
+% uniform at the moment to get a better overview.
+% \begin{macrocode}
+\cs_new_nopar:Npn \int_set:Nn #1#2{#1 \intexpr_eval:w #2\intexpr_eval_end:
+%<*check>
+\chk_local_or_pref_global:N #1
+%</check>
+}
+\cs_new_nopar:Npn \int_gset:Nn {
+%<*check>
+ \pref_global_chk:
+%</check>
+%<-check> \pref_global:D
+ \int_set:Nn }
+\cs_generate_variant:Nn\int_set:Nn {cn}
+\cs_generate_variant:Nn\int_gset:Nn {cn}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
% \begin{macro}{\int_incr:N}
% \begin{macro}{\int_decr:N}
% \begin{macro}{\int_gincr:N}
@@ -471,17 +521,17 @@
% Incrementing and decrementing of integer registers is done with
% the following functions.
% \begin{macrocode}
-\def_new:Npn \int_incr:N #1{\int_advance:w#1\c_one
+\cs_new_nopar:Npn \int_incr:N #1{\int_advance:w#1\c_one
%<*check>
\chk_local_or_pref_global:N #1
%</check>
}
-\def_new:Npn \int_decr:N #1{\int_advance:w#1\c_minus_one
+\cs_new_nopar:Npn \int_decr:N #1{\int_advance:w#1\c_minus_one
%<*check>
\chk_local_or_pref_global:N #1
%</check>
}
-\def_new:Npn \int_gincr:N {
+\cs_new_nopar:Npn \int_gincr:N {
% \end{macrocode}
% We make sure that a local variable is not updated globally by
% changing the internal test (i.e.\ |\chk_local_or_pref_global:N|) before
@@ -496,7 +546,7 @@
%</check>
%<-check> \pref_global:D
\int_incr:N}
-\def_new:Npn \int_gdecr:N {
+\cs_new_nopar:Npn \int_gdecr:N {
%<*check>
\pref_global_chk:
%</check>
@@ -506,80 +556,41 @@
% With the |\int_add:Nn| functions we can shorten the above code.
% If this makes it too slow \ldots
% \begin{macrocode}
-\def:Npn \int_incr:N #1{\int_add:Nn#1\c_one}
-\def:Npn \int_decr:N #1{\int_add:Nn#1\c_minus_one}
-\def:Npn \int_gincr:N #1{\int_gadd:Nn#1\c_one}
-\def:Npn \int_gdecr:N #1{\int_gadd:Nn#1\c_minus_one}
-\def:Npn \int_incr:c {\exp_args:Nc\int_incr:N}
-\def:Npn \int_decr:c {\exp_args:Nc\int_decr:N}
-\def:Npn \int_gincr:c {\exp_args:Nc\int_gincr:N}
-\def:Npn \int_gdecr:c {\exp_args:Nc\int_gdecr:N}
+\cs_set_nopar:Npn \int_incr:N #1{\int_add:Nn#1\c_one}
+\cs_set_nopar:Npn \int_decr:N #1{\int_add:Nn#1\c_minus_one}
+\cs_set_nopar:Npn \int_gincr:N #1{\int_gadd:Nn#1\c_one}
+\cs_set_nopar:Npn \int_gdecr:N #1{\int_gadd:Nn#1\c_minus_one}
% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-%
-% \begin{macro}{\int_new:N}
-% \begin{macro}{\int_new_l:N}
-% \begin{macro}{\int_new:c}
-% Allocation of a new internal counter is already done above. Here we define
-% the next likely variant.
+%
% \begin{macrocode}
-%<*initex>
-\alloc_setup_type:nnn {int} \c_eleven \c_max_register_num
-\def_new:Npn \int_new:N #1 {\alloc_reg:NnNN g {int} \tex_countdef:D#1}
-\def_new:Npn \int_new_l:N #1 {\alloc_reg:NnNN l {int} \tex_countdef:D#1}
-%</initex>
-%<package>\let:NN \int_new:N \newcount% allocation better nick the LaTeX one...
-\def_new:Npn \int_new:c {\exp_args:Nc \int_new: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}
-%
-%
-% \begin{macro}{\int_set:Nn}
-% \begin{macro}{\int_set:cn}
-% \begin{macro}{\int_gset:Nn}
-% \begin{macro}{\int_gset:cn}
-% Setting counters is again something that I would like to make
-% uniform at the moment to get a better overview.
-% \begin{macrocode}
-\def_new:Npn \int_set:Nn #1#2{#1 \int_eval:w #2\int_eval_end:
-%<*check>
-\chk_local_or_pref_global:N #1
-%</check>
-}
-\def_new:Npn \int_gset:Nn {
-%<*check>
- \pref_global_chk:
-%</check>
-%<-check> \pref_global:D
- \int_set:Nn }
-\def_new:Npn \int_set:cn {\exp_args:Nc \int_set:Nn }
-\def_new:Npn \int_gset:cn {\exp_args:Nc \int_gset:Nn }
-% \end{macrocode}
+% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
+%
% \begin{macro}{\int_zero:N}
% \begin{macro}{\int_zero:c}
% \begin{macro}{\int_gzero:N}
% \begin{macro}{\int_gzero:c}
% Functions that reset an \m{int} register to zero.
% \begin{macrocode}
-\def_new:Npn \int_zero:N #1 {#1=\c_zero}
-\def_new:Npn \int_zero:c #1 {\exp_args:Nc \int_zero:N}
-\def_new:Npn \int_gzero:N #1 {\pref_global:D #1=\c_zero}
-\def_new:Npn \int_gzero:c {\exp_args:Nc \int_gzero:N}
+\cs_new_nopar:Npn \int_zero:N #1 {#1=\c_zero}
+\cs_generate_variant:Nn \int_zero:N {c}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_new_nopar:Npn \int_gzero:N #1 {\pref_global:D #1=\c_zero}
+\cs_generate_variant:Nn \int_gzero:N {c}
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -597,39 +608,39 @@
% Adding and substracting to and from a counter \ldots
% We should think of using these functions
% \begin{macrocode}
-\def_new:Npn \int_add:Nn #1#2{
+\cs_new_nopar:Npn \int_add:Nn #1#2{
% \end{macrocode}
% We need to say |by| in case the first argument is a register
% accessed by its number, e.g., |\count23|. Not that it should
% ever happen but\dots
% \begin{macrocode}
- \int_advance:w #1 by \int_eval:w #2\int_eval_end:
+ \int_advance:w #1 by \intexpr_eval:w #2\intexpr_eval_end:
%<*check>
\chk_local_or_pref_global:N #1
%</check>
}
-\def_new:Npn\int_add:cn{\exp_args:Nc\int_add:Nn}
-\def_new:Npn \int_sub:Nn #1#2{
- \int_advance:w #1-\int_eval:w #2\int_eval_end:
+\cs_new_nopar:Npn \int_sub:Nn #1#2{
+ \int_advance:w #1-\intexpr_eval:w #2\intexpr_eval_end:
%<*check>
\chk_local_or_pref_global:N #1
%</check>
}
-\def_new:Npn \int_gadd:Nn {
+\cs_new_nopar:Npn \int_gadd:Nn {
%<*check>
\pref_global_chk:
%</check>
%<-check> \pref_global:D
\int_add:Nn }
-\def_new:Npn \int_gsub:Nn {
+\cs_new_nopar:Npn \int_gsub:Nn {
%<*check>
\pref_global_chk:
%</check>
%<-check> \pref_global:D
\int_sub:Nn }
-\def_new:Npn \int_gadd:cn{\exp_args:Nc\int_gadd:Nn}
-\def_new:Npn \int_sub:cn{\exp_args:Nc\int_sub:Nn}
-\def_new:Npn \int_gsub:cn{\exp_args:Nc\int_gsub:Nn}
+\cs_generate_variant:Nn \int_add:Nn {cn}
+\cs_generate_variant:Nn \int_gadd:Nn {cn}
+\cs_generate_variant:Nn \int_sub:Nn {cn}
+\cs_generate_variant:Nn \int_gsub:Nn {cn}
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -645,8 +656,18 @@
% \begin{macro}{\int_use:c}
% Here is how counters are accessed:
% \begin{macrocode}
-\let_new:NN \int_use:N \tex_the:D
-\def_new:Npn \int_use:c #1{\int_use:N \cs:w#1\cs_end:}
+\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}
+% \end{macro}
+%
+% \begin{macro}{\int_show:N}
+% \begin{macro}{\int_show:c}
+% Diagnostics.
+% \begin{macrocode}
+\cs_new_eq:NN \int_show:N \tex_showthe:D
+\cs_new_nopar:Npn \int_show:c {\exp_args:Nc \int_show:N }
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -657,7 +678,7 @@
% \begin{macro}{\int_to_arabic:n}
% Nothing exciting here.
% \begin{macrocode}
-\def_new:Npn \int_to_arabic:n #1{\int_to_number:w \int_eval:n{#1}}
+\cs_new_nopar:Npn \int_to_arabic:n #1{ \intexpr_eval:n{#1}}
% \end{macrocode}
% \end{macro}
%
@@ -671,9 +692,9 @@
% character \TeX{} produces to the character we actually want which
% will give us letters with category code~11.%
% \begin{macrocode}
-\def_new:Npn \int_roman_lcuc_mapping:Nnn #1#2#3{
- \def:cpn {int_to_lc_roman_#1:}{#2}
- \def:cpn {int_to_uc_roman_#1:}{#3}
+\cs_new_nopar:Npn \int_roman_lcuc_mapping:Nnn #1#2#3{
+ \cs_set_nopar:cpn {int_to_lc_roman_#1:}{#2}
+ \cs_set_nopar:cpn {int_to_uc_roman_#1:}{#3}
}
% \end{macrocode}
% \end{macro}
@@ -701,18 +722,18 @@
% The commands for producing the lower and upper case roman numerals
% run a loop on one character at a time and also carries some
% information for upper or lower case with it. We put it through
-% |\int_eval:n| first which is safer and more flexible.
+% |\intexpr_eval:n| first which is safer and more flexible.
% \begin{macrocode}
-\def_new:Npn \int_to_roman:n #1 {
- \exp_after:NN \int_to_roman_lcuc:NN \exp_after:NN l
- \int_to_roman:w \int_eval:n {#1} Q
+\cs_new_nopar:Npn \int_to_roman:n #1 {
+ \exp_after:wN \int_to_roman_lcuc:NN \exp_after:wN l
+ \int_to_roman:w \intexpr_eval:n {#1} Q
}
-\def_new:Npn \int_to_Roman:n #1 {
- \exp_after:NN \int_to_roman_lcuc:NN \exp_after:NN u
- \int_to_roman:w \int_eval:n {#1} Q
+\cs_new_nopar:Npn \int_to_Roman:n #1 {
+ \exp_after:wN \int_to_roman_lcuc:NN \exp_after:wN u
+ \int_to_roman:w \intexpr_eval:n {#1} Q
}
-\def_new:Npn \int_to_roman_lcuc:NN #1#2{
- \cs_use:c {int_to_#1c_roman_#2:}
+\cs_new_nopar:Npn \int_to_roman_lcuc:NN #1#2{
+ \use:c {int_to_#1c_roman_#2:}
\int_to_roman_lcuc:NN #1
}
% \end{macrocode}
@@ -743,20 +764,20 @@
% We do a little pre-expansion of the arguments below as they
% otherwise have a tendency to grow quite large.
% \begin{macrocode}
-\def:Npn \int_convert_number_with_rule:nnN #1#2#3{
- \int_compare:nNnTF {#1}>{#2}
+\cs_set_nopar:Npn \int_convert_number_with_rule:nnN #1#2#3{
+ \intexpr_compare:nNnTF {#1}>{#2}
{
- \exp_args:No \int_convert_number_with_rule:nnN
- { \int_use:N\int_div_truncate:nn {#1-1}{#2} }{#2}
+ \exp_args:Nf \int_convert_number_with_rule:nnN
+ { \intexpr_div_truncate:nn {#1-1}{#2} }{#2}
#3
% \end{macrocode}
% Note that we have to nudge our modulus function so it won't
% return~$0$ as that wouldn't work with |\if_case:w| when that
% expects a positive number to produce a letter.
% \begin{macrocode}
- \exp_args:No #3 { \int_use:N\int_eval:n{1+\int_mod:nn {#1-1}{#2}} }
+ \exp_args:Nf #3 { \intexpr_eval:n{1+\intexpr_mod:nn {#1-1}{#2}} }
}
- { \exp_args:No #3{ \int_use:N\int_eval:n{#1} } }
+ { \exp_args:Nf #3{ \intexpr_eval:n{#1} } }
}
% \end{macrocode}
% As can be seen it is even simpler to convert to number systems
@@ -770,7 +791,7 @@
% should have one such rule, as say in Danish there are 29 letters in
% the alphabet.
% \begin{macrocode}
-\def_new:Npn \int_alph_default_conversion_rule:n #1{
+\cs_new_nopar:Npn \int_alph_default_conversion_rule:n #1{
\if_case:w #1
\or: a\or: b\or: c\or: d\or: e\or: f
\or: g\or: h\or: i\or: j\or: k\or: l
@@ -779,7 +800,7 @@
\or: y\or: z
\fi:
}
-\def_new:Npn \int_Alph_default_conversion_rule:n #1{
+\cs_new_nopar:Npn \int_Alph_default_conversion_rule:n #1{
\if_case:w #1
\or: A\or: B\or: C\or: D\or: E\or: F
\or: G\or: H\or: I\or: J\or: K\or: L
@@ -799,11 +820,11 @@
% second argument of |\int_convert_number_with_rule:nnN| should of
% course match the number of |\or:|s in the conversion rule.
% \begin{macrocode}
-\def_new:Npn \int_to_alph:n #1{
+\cs_new_nopar:Npn \int_to_alph:n #1{
\int_convert_number_with_rule:nnN {#1}{26}
\int_alph_default_conversion_rule:n
}
-\def_new:Npn \int_to_Alph:n #1{
+\cs_new_nopar:Npn \int_to_Alph:n #1{
\int_convert_number_with_rule:nnN {#1}{26}
\int_Alph_default_conversion_rule:n
}
@@ -814,7 +835,7 @@
% \begin{macro}{\int_to_symbol:n}
% Turning a number into a symbol is also easy enough.
% \begin{macrocode}
-\def_new:Npn \int_to_symbol:n #1{
+\cs_new_nopar:Npn \int_to_symbol:n #1{
\mode_if_math:TF
{
\int_convert_number_with_rule:nnN {#1}{9}
@@ -831,7 +852,7 @@
% \begin{macro}{\int_symbol_text_conversion_rule:n}
% Nothing spectacular here.
% \begin{macrocode}
-\def_new:Npn \int_symbol_math_conversion_rule:n #1 {
+\cs_new_nopar:Npn \int_symbol_math_conversion_rule:n #1 {
\if_case:w #1
\or: *
\or: \dagger
@@ -844,7 +865,7 @@
\or: \ddagger\ddagger
\fi:
}
-\def_new:Npn \int_symbol_text_conversion_rule:n #1 {
+\cs_new_nopar:Npn \int_symbol_text_conversion_rule:n #1 {
\if_case:w #1
\or: \textasteriskcentered
\or: \textdagger
@@ -866,7 +887,6 @@
% \begin{macro}{\l_tmpc_int}
% \begin{macro}{\g_tmpa_int}
% \begin{macro}{\g_tmpb_int}
-% \begin{macro}{\l_loop_int}
% We provide four local and two global scratch counters, maybe we
% need more or less.
% \begin{macrocode}
@@ -875,202 +895,116 @@
\int_new:N \l_tmpc_int
\int_new:N \g_tmpa_int
\int_new:N \g_tmpb_int
-\int_new:N \l_loop_int % a variable for use in loops (whilenum etc)
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
-% \end{macro}
%
%
-% \begin{macro}{\int_eval:n}
-% \begin{macro}{\int_eval:w}
-% \begin{macro}{\int_eval_end:}
-% Evaluating a calc expression using normal operators. Many of these
-% are exactly the same as the ones in the \textsf{num} module so we
-% just use them.
-% \begin{macrocode}
-\let_new:NN \int_eval:n \num_eval:n
-\let_new:NN \int_eval:w \num_eval:w
-\let_new:NN \int_eval_end: \num_eval_end:
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
%
-% \begin{macro}{\c_max_int}
-% The largest number allowed is $2^{31}-1$
-% \begin{macrocode}
-\const_new:Nn \c_max_int {2147483647}
-% \end{macrocode}
-% \end{macro}
%
% \begin{macro}{\int_pre_eval_one_arg:Nn}
% \begin{macro}{\int_pre_eval_two_args:Nnn}
-% These might be handy when handing down values to other
+% These are handy when handing down values to other
% functions. All they do is evaluate the number in advance.
% \begin{macrocode}
-\def:Npn \int_pre_eval_one_arg:Nnn #1#2{\exp_args:No#1{\int_eval:w#2}}
-\def:Npn \int_pre_eval_two_args:Nnn #1#2#3{
- \exp_args:Noo#1{\int_use:N\int_eval:w#2}{\int_use:N\int_eval:w#3}
+\cs_set_nopar:Npn \int_pre_eval_one_arg:Nn #1#2{
+ \exp_args:Nf#1{\intexpr_eval:n{#2}}}
+\cs_set_nopar:Npn \int_pre_eval_two_args:Nnn #1#2#3{
+ \exp_args:Nff#1{\intexpr_eval:n{#2}}{\intexpr_eval:n{#3}}
}
% \end{macrocode}
% \end{macro}
% \end{macro}
%
-% \begin{macro}{\int_div_truncate:nn}
-% \begin{macro}{\int_div_round:nn}
-% \begin{macro}{\int_mod:nn}
-% \begin{macro}{\int_div_truncate_raw:nn}
-% \begin{macro}{\int_div_round_raw:nn}
-% \begin{macro}{\int_mod_raw:nn}
-% As "\num_eval:w" rounds the result of a division we also
-% provide a version that truncates the result.
-% \begin{macrocode}
-\def_new:Npn \int_div_truncate:nn {
- \int_pre_eval_two_args:Nnn\int_div_truncate_raw:nn
-}
-% \end{macrocode}
-% Initial version didn't work correctly with e\TeX's implementation.
-% \begin{macrocode}
-%\def_new:Npn \int_div_truncate_raw:nn #1#2 {
-% \int_eval:n{ (2*#1 - #2) / (2* #2) }
-%}
-% \end{macrocode}
-% New version by Heiko:
-% \begin{macrocode}
-\def_new:Npn \int_div_truncate_raw:nn #1#2 {
- \int_eval:w
- \if_num:w \int_eval:w#1 = \c_zero
- 0
- \else:
- (#1
- \if_num:w \int_eval:w #1 < \c_zero
- \if_num:w \int_eval:w#2 < \c_zero
- -( #2 +
- \else:
- +( #2 -
- \fi:
- \else:
- \if_num: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}
-\def_new:Npn \int_div_round:nn {
- \int_pre_eval_two_args:Nnn\int_div_round_raw:nn
-}
-\def_new:Npn \int_div_round_raw:nn #1#2 {\int_eval:n{#1/#2}}
-% \end{macrocode}
-% Finally there's the modulus operation.
-% \begin{macrocode}
-\def_new:Npn \int_mod:nn {\int_pre_eval_two_args:Nnn\int_mod_raw:nn}
-\def_new:Npn \int_mod_raw:nn #1#2 {
- \int_eval:n{ #1 - \int_div_truncate_raw:nn {#1}{#2} * #2 }
-}
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
%
%
-% \begin{macro}{\int_compare:nNnTF}
-% \begin{macro}{\int_compare:nNnT}
-% \begin{macro}{\int_compare:nNnF}
-% Simple comparison tests.
-% \begin{macrocode}
-\let_new:NN \int_compare:nNnTF \num_compare:nNnTF
-\let_new:NN \int_compare:nNnT \num_compare:nNnT
-\let_new:NN \int_compare:nNnF \num_compare:nNnF
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
%
-% \begin{macro}{\int_max_of:nn}
-% \begin{macro}{\int_min_of:nn}
-% \begin{macro}{\int_abs:n}
-% Simple comparison tests.
+% \subsection{Defining constants}
+% \begin{macro}{\int_const:Nn}
+% As stated, most constants can be defined as |\tex_chardef:D| or
+% |\tex_mathchardef:D| but that's engine dependent.
% \begin{macrocode}
-\let_new:NN \int_max_of:nn \num_max_of:nn
-\let_new:NN \int_min_of:nn \num_min_of:nn
-\let_new:NN \int_abs:nn \num_abs:nn
+\cs_new_nopar:Npn \int_const:Nn #1#2 {
+ \intexpr_compare:nNnTF {#2} > \c_minus_one {
+ \intexpr_compare:nNnTF {#2} > \c_max_register_num {
+ \int_new:N #1 \int_set:Nn #1{#2}
+ } {
+ \chk_if_free_cs:N #1 \tex_mathchardef:D #1 = \intexpr_eval:n{#2}
+ }
+ } {
+ \int_new:N #1 \int_set:Nn #1{#2}
+ }
+}
% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
+% \end{macro}
%
-% \begin{macro}{\int_compare_p:nNn}
-% A predicate function.
+% \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_twelve, \c_thirteen, \c_fourteen, \c_fifteen,
+% \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, \c_ten_thousand_two,
+% \c_ten_thousand_three, \c_ten_thousand_four,
+% \c_twenty_thousand}
+% And the usual constants, others are still missing. Please, make
+% every constant a real constant at least for the moment. We can
+% easily convert things in the end when we have found what
+% constants are used in critical places and what not.
% \begin{macrocode}
-\let_new:NN \int_compare_p:nNn \num_compare_p:nNn
+ %% \tex_countdef:D \c_minus_one = 10 \scan_stop:
+ %% \c_minus_one = -1 \scan_stop: %% in l3basics
+%\int_const:Nn \c_zero {0}
+\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_six {6}
+\int_const:Nn \c_seven {7}
+\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_twelve {12}
+\int_const:Nn \c_thirteen {13}
+\int_const:Nn \c_fourteen {14}
+\int_const:Nn \c_fifteen {15}
+ %% \tex_chardef:D \c_sixteen = 16\scan_stop: %% in l3basics
+\int_const:Nn \c_thirty_two {32}
% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\int_if_odd_p:n}
-% \begin{macro}{\int_if_odd:nTF}
-% \begin{macro}{\int_if_odd:nT}
-% \begin{macro}{\int_if_odd:nF}
-% A predicate function.
+% The next one may seem a little odd (obviously!) but is useful when
+% dealing with logical operators.
% \begin{macrocode}
-\def_new:Npn \int_if_odd_p:n #1 {
- \if_num_odd:w \int_eval:n{#1}
- \c_true
- \else:
- \c_false
- \fi:
-}
-\def_test_function_new:npn {int_if_odd:n}#1{\if_num_odd:w \int_eval:n{#1}}
+\int_const:Nn \c_hundred_one {101}
+\int_const:Nn \c_twohundred_fifty_five{255}
+\int_const:Nn \c_twohundred_fifty_six {256}
+\int_const:Nn \c_thousand {1000}
+\int_const:Nn \c_ten_thousand {10000}
+\int_const:Nn \c_ten_thousand_one {10001}
+\int_const:Nn \c_ten_thousand_two {10002}
+\int_const:Nn \c_ten_thousand_three {10003}
+\int_const:Nn \c_ten_thousand_four {10004}
+\int_const:Nn \c_twenty_thousand {20000}
% \end{macrocode}
% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
%
-% \begin{macro}{\int_whiledo:nNnT}
-% \begin{macro}{\int_whiledo:nNnF}
-% \begin{macro}{\int_dowhile:nNnT}
-% \begin{macro}{\int_dowhile:nNnF}
-% These are quite easy given the above functions. The "while" versions
-% test first and then execute the body. The "dowhile" does it the
-% other way round. The have to be defined as ``long'' since the "T" argument
-% might contain "\par" tokens.
+% \begin{macro}{\c_max_int}
+% The largest number allowed is $2^{31}-1$
% \begin{macrocode}
-\def_long_new:Npn \int_whiledo:nNnT #1#2#3#4{
- \int_compare:nNnT {#1}#2{#3}{#4 \int_whiledo:nNnT {#1}#2{#3}{#4}}
-}
-\def_long_new:Npn \int_whiledo:nNnF #1#2#3#4{
- \int_compare:nNnF {#1}#2{#3}{#4 \int_whiledo:nNnF {#1}#2{#3}{#4}}
-}
-\def_long_new:Npn \int_dowhile:nNnT #1#2#3#4{
- #4 \int_compare:nNnT {#1}#2{#3}{\int_dowhile:nNnT {#1}#2{#3}{#4}}
-}
-\def_long_new:Npn \int_dowhile:nNnF #1#2#3#4{
- #4 \int_compare:nNnF {#1}#2{#3}{\int_dowhile:nNnF {#1}#2{#3}{#4}}
-}
+\int_const:Nn \c_max_int {2147483647}
% \end{macrocode}
% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
%
%
-% \subsubsection{Scanning and conversion}
+%
+% \subsection{Scanning and conversion}
%
%
% Conversion between different numbering schemes requires meticulous
@@ -1081,54 +1015,50 @@
% \begin{macro}{\int_get_sign_and_digits:n}
% \begin{macro}{\int_get_sign:n}
% \begin{macro}{\int_get_digits:n}
-% \begin{macro}{\int_get_sign_and_digits_aux:nNNN}
-% \begin{macro}{\int_get_sign_and_digits_aux:oNNN}
+% \begin{macro}[aux]{\int_get_sign_and_digits_aux:nNNN}
+% \begin{macro}[aux]{\int_get_sign_and_digits_aux:oNNN}
% A number may be preceeded by any number of |+|s and |-|s. Start out
% by assuming we have a positive number.
% \begin{macrocode}
-\def_new:Npn \int_get_sign_and_digits:n #1{
- \int_get_sign_and_digits_aux:nNNN {#1} \c_true \c_true \c_true
+\cs_new_nopar:Npn \int_get_sign_and_digits:n #1{
+ \int_get_sign_and_digits_aux:nNNN {#1} \c_true_bool \c_true_bool \c_true_bool
}
-\def_new:Npn \int_get_sign:n #1{
- \int_get_sign_and_digits_aux:nNNN {#1} \c_true \c_true \c_false
+\cs_new_nopar:Npn \int_get_sign:n #1{
+ \int_get_sign_and_digits_aux:nNNN {#1} \c_true_bool \c_true_bool \c_false_bool
}
-\def_new:Npn \int_get_digits:n #1{
- \int_get_sign_and_digits_aux:nNNN {#1} \c_true \c_false \c_true
+\cs_new_nopar: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}
% Now check the first character in the string. Only a |-| can change
% if a number is positive or negative, hence we reverse the boolean
% governing this. Then gobble the |-| and start over.
% \begin{macrocode}
-\def_new:Npn \int_get_sign_and_digits_aux:nNNN #1#2#3#4{
- \tlist_if_head_eq_charcode:fNTF {#1} -
+\cs_new_nopar: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 #3#4 }
- { \int_get_sign_and_digits_aux:oNNN {\use_none:n #1} \c_true #3#4 }
+ { \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 }
}
% \end{macrocode}
% The other cases are much simpler since we either just have to gobble
% the |+| or exit immediately and insert the correct sign.
% \begin{macrocode}
{
- \tlist_if_head_eq_charcode:fNTF {#1} +
+ \tl_if_head_eq_charcode:fNTF {#1} +
{ \int_get_sign_and_digits_aux:oNNN {\use_none:n #1} #2#3#4}
{
% \end{macrocode}
% The boolean |#3| is for printing the sign while |#4| is for printing
% the digits.
% \begin{macrocode}
- \bool_double_if:NNnnnn #3#4
- { \bool_if:NF #2 - #1 }
- { \bool_if:NF #2 - }
- { #1 } { }
+ \bool_if:NT #3 { \bool_if:NF #2 - }
+ \bool_if:NT #4 {#1}
}
}
}
-\def_new:Npn \int_get_sign_and_digits_aux:oNNN{
- \exp_args:No\int_get_sign_and_digits_aux:nNNN
-}
+\cs_generate_variant:Nn \int_get_sign_and_digits_aux:nNNN {oNNN}
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -1138,23 +1068,23 @@
%
%
% \begin{macro}{\int_convert_from_base_ten:nn}
-% \begin{macro}{\int_convert_from_base_ten_aux:nnn}
-% \begin{macro}{\int_convert_from_base_ten_aux:non}
-% \begin{macro}{\int_convert_from_base_ten_aux:fon}
+% \begin{macro}[aux]{\int_convert_from_base_ten_aux:nnn}
+% \begin{macro}[aux]{\int_convert_from_base_ten_aux:non}
+% \begin{macro}[aux]{\int_convert_from_base_ten_aux:fon}
% |#1| is the base 10 number to be converted to base |#2|. We split
% off the sign first, print if if there and then convert only the
% number. Since this is supposedly a base~10 number we can let \TeX\
% do the reading of |+| and |-|.
% \begin{macrocode}
-\def:Npn \int_convert_from_base_ten:nn#1#2{
- \num_compare:nNnTF {#1}<\c_zero
+\cs_set_nopar:Npn \int_convert_from_base_ten:nn#1#2{
+ \intexpr_compare:nNnTF {#1}<\c_zero
{
- - \int_convert_from_base_ten_aux:non {}
- { \int_use:N \int_eval:n {-#1} }
+ - \int_convert_from_base_ten_aux:nfn {}
+ { \intexpr_eval:n {-#1} }
}
{
- \int_convert_from_base_ten_aux:non {}
- { \int_use:N \int_eval:n {#1} }
+ \int_convert_from_base_ten_aux:nfn {}
+ { \intexpr_eval:n {#1} }
}
{#2}
}
@@ -1173,44 +1103,42 @@
% |#1| is the carried over result, |#2| the remainder and |#3| the
% base number.
% \begin{macrocode}
-\def_new:Npn \int_convert_from_base_ten_aux:nnn#1#2#3{
- \num_compare:nNnTF {#2}<{#3}
+\cs_new_nopar:Npn \int_convert_from_base_ten_aux:nnn#1#2#3{
+ \intexpr_compare:nNnTF {#2}<{#3}
{ \int_convert_number_to_letter:n{#2} #1 }
{
- \int_convert_from_base_ten_aux:fon
+ \int_convert_from_base_ten_aux:ffn
{
- \int_convert_number_to_letter:n {\int_use:N\int_mod_raw:nn {#2}{#3}}
+ \int_convert_number_to_letter:n {\intexpr_mod:nn {#2}{#3}}
#1
}
- {\int_use:N \int_div_truncate_raw:nn{#2}{#3}}
+ { \intexpr_div_truncate:nn{#2}{#3}}
{#3}
}
}
-\def:Npn \int_convert_from_base_ten_aux:non{
- \exp_args:Nno\int_convert_from_base_ten_aux:nnn
-}
-\def:Npn \int_convert_from_base_ten_aux:fon{
- \exp_args:Nfo\int_convert_from_base_ten_aux:nnn
-}
+\cs_generate_variant:Nn \int_convert_from_base_ten_aux:nnn {nfn}
+\cs_generate_variant:Nn \int_convert_from_base_ten_aux:nnn {ffn}
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
+%
% \begin{macro}{\int_convert_number_to_letter:n}
% Turning a number for a different base into a letter or digit.
% \begin{macrocode}
-\def:Npn \int_convert_number_to_letter:n #1{ \if_case:w \int_eval:w
- #1-10\scan_stop: \exp_after:NN A \or: \exp_after:NN B \or:
- \exp_after:NN C \or: \exp_after:NN D \or: \exp_after:NN E \or:
- \exp_after:NN F \or: \exp_after:NN G \or: \exp_after:NN H \or:
- \exp_after:NN I \or: \exp_after:NN J \or: \exp_after:NN K \or:
- \exp_after:NN L \or: \exp_after:NN M \or: \exp_after:NN N \or:
- \exp_after:NN O \or: \exp_after:NN P \or: \exp_after:NN Q \or:
- \exp_after:NN R \or: \exp_after:NN S \or: \exp_after:NN T \or:
- \exp_after:NN U \or: \exp_after:NN V \or: \exp_after:NN W \or:
- \exp_after:NN X \or: \exp_after:NN Y \or: \exp_after:NN Z \else:
- \use_arg_i_after_fi:nw{ #1 }\fi: }
+\cs_set_nopar:Npn \int_convert_number_to_letter:n #1{
+ \if_case:w \intexpr_eval:w #1-10\intexpr_eval_end:
+ \exp_after:wN A \or: \exp_after:wN B \or:
+ \exp_after:wN C \or: \exp_after:wN D \or: \exp_after:wN E \or:
+ \exp_after:wN F \or: \exp_after:wN G \or: \exp_after:wN H \or:
+ \exp_after:wN I \or: \exp_after:wN J \or: \exp_after:wN K \or:
+ \exp_after:wN L \or: \exp_after:wN M \or: \exp_after:wN N \or:
+ \exp_after:wN O \or: \exp_after:wN P \or: \exp_after:wN Q \or:
+ \exp_after:wN R \or: \exp_after:wN S \or: \exp_after:wN T \or:
+ \exp_after:wN U \or: \exp_after:wN V \or: \exp_after:wN W \or:
+ \exp_after:wN X \or: \exp_after:wN Y \or: \exp_after:wN Z \else:
+ \use_i_after_fi:nw{ #1 }\fi: }
% \end{macrocode}
% \end{macro}
%
@@ -1219,8 +1147,8 @@
% use only the digits/letters from it and pass that onto a new
% function.
% \begin{macrocode}
-\def:Npn \int_convert_to_base_ten:nn #1#2 {
- \int_use:N\int_eval:n{
+\cs_set_nopar:Npn \int_convert_to_base_ten:nn #1#2 {
+ \intexpr_eval:n{
\int_get_sign:n{#1}
\exp_args:Nf\int_convert_to_base_ten_aux:nn {\int_get_digits:n{#1}}{#2}
}
@@ -1228,7 +1156,7 @@
% \end{macrocode}
% This is an intermediate function to get things started.
% \begin{macrocode}
-\def_new:Npn \int_convert_to_base_ten_aux:nn #1#2{
+\cs_new_nopar:Npn \int_convert_to_base_ten_aux:nn #1#2{
\int_convert_to_base_ten_auxi:nnN {0}{#2} #1 \q_nil
}
% \end{macrocode}
@@ -1236,11 +1164,11 @@
% is the previously calculated result (to be multiplied by the base),
% |#2| is the base and |#3| is the next letter/digit to be added.
% \begin{macrocode}
-\def_new:Npn \int_convert_to_base_ten_auxi:nnN#1#2#3{
+\cs_new_nopar:Npn \int_convert_to_base_ten_auxi:nnN#1#2#3{
\quark_if_nil:NTF #3
{#1}
- {\exp_args:No\int_convert_to_base_ten_auxi:nnN
- {\int_use:N \int_eval:n{ #1*#2+\int_convert_letter_to_number:N #3} }
+ {\exp_args:Nf\int_convert_to_base_ten_auxi:nnN
+ {\intexpr_eval:n{ #1*#2+\int_convert_letter_to_number:N #3} }
{#2}
}
}
@@ -1249,80 +1177,30 @@
% also takes care of handling lowercase and uppercase letters. Hence
% |a| is turned into |11| and so is |A|.
% \begin{macrocode}
-\def:Npn \int_convert_letter_to_number:N #1{
- \int_compare:nNnTF{`#1}<{58}{#1}
+\cs_set_nopar:Npn \int_convert_letter_to_number:N #1{
+ \intexpr_compare:nNnTF{`#1}<{58}{#1}
{
- \int_eval:n{ `#1 -
- \if:w\int_compare_p:nNn{`#1}<{91}
- 55
- \else:
- 87
- \fi:
+ \intexpr_eval:n{ `#1 -
+ \intexpr_compare:nNnTF{`#1}<{91}{ 55 }{ 87 }
}
}
}
% \end{macrocode}
% \end{macro}
%
-%
-%
-%
-%
-%
+% \begin{macrocode}
+%</initex|package>
+% \end{macrocode}
%
% Show token usage:
% \begin{macrocode}
-%</initex|package>
%<*showmemory>
\showMemUsage
%</showmemory>
% \end{macrocode}
%
+% \end{implementation}
+% \PrintIndex
%
-% \endinput
-%
-% $Log$
-% Revision 1.26 2006/06/03 17:17:08 morten
-% Functions for converting between number bases
-%
-% Revision 1.25 2006/03/20 18:26:35 braams
-% Updated the copyright notice (2006) and demoted all implementation
-% sections to subsections and so on to clean up the toc for source3.tex
-%
-% Revision 1.24 2006/01/17 22:47:43 morten
-% Changed \int_while:nNnT to \int_whiledo:nNnT to avoid confusion with
-% the dowhile versions.
-%
-% Revision 1.23 2005/12/27 10:02:37 morten
-% Minor changes plus changed RCS information retrieval
-%
-% Revision 1.22 2005/12/21 20:43:32 morten
-% Fixed silly bugs!
-%
-% Revision 1.21 2005/12/06 17:31:23 morten
-% fixed \int_convert_number_with_rule:nnN
-%
-% Revision 1.20 2005/12/06 14:49:36 morten
-% Fixed primitive names plus a few minor touch-ups
-%
-% Revision 1.19 2005/04/25 15:02:47 morten
-% Added ifodd functions
-%
-% Revision 1.18 2005/04/09 21:07:39 morten
-% Added (extensible) implementations of \int_to_roman:n etc.
-%
-% Revision 1.17 2005/04/06 22:35:43 braams
-% Now we have register allocation fitted
-%
-% Revision 1.16 2005/03/25 23:48:47 braams
-% Added a missing \end{macro}
-%
-% Revision 1.15 2005/03/22 23:22:09 morten
-% Moved definitions of constants to l3num
-%
-% Revision 1.14 2005/03/16 22:36:30 braams
-% Added the tweaks necessary to be able to load with initex
-%
-% Revision 1.13 2005/03/11 21:38:31 braams
-% Fixed the use of RCS information; added \StopEventually
%
+% \endinput
diff --git a/Master/texmf-dist/source/latex/expl3/l3intexpr.dtx b/Master/texmf-dist/source/latex/expl3/l3intexpr.dtx
new file mode 100644
index 00000000000..6b454a8ab80
--- /dev/null
+++ b/Master/texmf-dist/source/latex/expl3/l3intexpr.dtx
@@ -0,0 +1,642 @@
+% \iffalse
+%% File: l3intexpr.dtx Copyright (C) 2009 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 LaTeX Project Team.
+%%
+%% -----------------------------------------------------------------------
+%
+%<*driver|package>
+\RequirePackage{l3names}
+%</driver|package>
+%\fi
+\GetIdInfo$Id: l3intexpr.dtx 1086 2009-03-20 19:29:35Z morten $
+ {L3 Integer Expressions}
+%\iffalse
+%<*driver>
+%\fi
+\ProvidesFile{\filename.\filenameext}
+ [\filedate\space v\fileversion\space\filedescription]
+%\iffalse
+\documentclass[full]{l3doc}
+\begin{document}
+\DocInput{\filename.\filenameext}
+\end{document}
+%</driver>
+% \fi
+%
+%
+% \title{The \textsf{l3intexpr} package\thanks{This file
+% has version number \fileversion, last
+% revised \filedate.}\\
+% Integer expressions}
+% \author{\Team}
+% \date{\filedate}
+% \maketitle
+%
+% \begin{documentation}
+%
+% This module sets up evaluation of integer expressions and allows
+% mixing |int| and |num| registers.
+%
+% An integer expression is one that contains integers in the form of
+% numbers, registers containg numbers, i.e., |int| and |num| registers
+% plus constants like |\c_one|, standard operators "+", "-", "/" and
+% "*" and parentheses to group sub-expressions.
+%
+% \section{Functions}
+%
+% \begin{function}{%
+% \intexpr_eval:n / (EXP)
+% }
+% \begin{syntax}
+% "\intexpr_eval:n" \Arg{int~expr}
+% \end{syntax}
+% The result of this expansion is a properly terminated <number>,
+% i.e., one that can be used with "\if_case:w" and others. For example,
+% \begin{quote}
+% |\intexpr_eval:n{ 5 + 4*3 - (3+4*5) }|
+% \end{quote}
+% evaluates to $-6$. The result is returned after two expansions so
+% if you find that you need to pass on the result to another function
+% using the expansion engine, the recommendation is to use an "f" type
+% expansion if in an expandable context or "x" otherwise.
+% \end{function}
+%
+%
+% \begin{function}{%
+% \intexpr_compare_p:n / (EXP) |
+% \intexpr_compare:n / (TF)(EXP)
+% }
+% \begin{syntax}
+% "\intexpr_compare_p:n" \Arg{<int~expr1> <rel> <int~expr2>}
+% \end{syntax}
+% Compares <int~expr1> with <int~expr2> using C-like relational
+% operators, i.e.
+% \begin{center}
+% \begin{tabular}{ll@{\hspace{2cm}}ll}
+% Less than & "<" & Less than or equal & "<=" \\
+% Greater than & "<" & Greater than or equal & ">=" \\
+% Equal & "==" or "=" & Not equal & "!="
+% \end{tabular}
+% \end{center}
+% Both integer expressions are evaluated fully in the process. Note
+% the syntax, which allows natural input in the style of
+% \begin{quote}
+% |\intexpr_compare_p:n {5+3 != \l_tmpb_int}|
+% \end{quote}
+% "=" is added for the sake of \TeX\ users accustomed to using a
+% single equal sign.
+% \end{function}
+%
+%
+% \begin{function}{%
+% \intexpr_compare_p:nNn / (EXP) |
+% \intexpr_compare:nNn / (TF)(EXP)
+% }
+% \begin{syntax}
+% "\intexpr_compare_p:nNn" \Arg{int~expr1}<rel>\Arg{int~expr2}
+% \end{syntax}
+% Compares <int~expr1> with <int~expr2> using one of the relations
+% "=", ">" or "<". This is faster than the variant above but at the
+% cost of requiring a little more typing and not supporting the
+% extended set of relational operators. Note that if both expressions
+% are normal integer variables as in
+% \begin{quote}
+% "\intexpr_compare:nNnTF \l_temp_int < \c_zero {negative}{non-negative}"
+% \end{quote}
+% you can safely omit the braces.
+% \end{function}
+%
+%
+% \begin{function}{%
+% \intexpr_max:nn / (EXP)|
+% \intexpr_min:nn / (EXP)|
+% }
+% \begin{syntax}
+% "\intexpr_max:nn" \Arg{int~expr1} \Arg{int~expr2}
+% \end{syntax}
+% Return the largest or smallest of two integer expressions.
+% \end{function}
+%
+% \begin{function}{%
+% \intexpr_abs:n / (EXP)|
+% }
+% \begin{syntax}
+% "\intexpr_abs:n" \Arg{int~expr}
+% \end{syntax}
+% Return the numerical value of an integer expression.
+% \end{function}
+%
+% \begin{function}{%
+% \intexpr_if_odd:n / (EXP)(TF) |
+% \intexpr_if_odd_p:n / (EXP) |
+% \intexpr_if_even:n / (EXP)(TF) |
+% \intexpr_if_even_p:n / (EXP) |
+% }
+% \begin{syntax}
+% "\intexpr_if_odd:nTF" \Arg{int~expr} \Arg{true} \Arg{false}
+% \end{syntax}
+% These functions test if an integer expression is even or odd.
+% \end{function}
+%
+%
+%
+%
+%
+%
+% \begin{function}{%
+% \intexpr_div_truncate:nn / (EXP) |
+% \intexpr_div_round:nn / (EXP) |
+% \intexpr_mod:nn / (EXP) |
+% }
+% \begin{syntax}
+% "\intexpr_div_truncate:n" \Arg{int~expr} \Arg{int~expr} \\
+% "\intexpr_mod:nn" \Arg{int~expr} \Arg{int~expr}
+% \end{syntax}
+% If
+% you want the result of a division to be truncated use
+% "\intexpr_div_truncate:nn". "\intexpr_div_round:nn" is added for
+% completeness. "\intexpr_mod:nn" returns the remainder of a division.
+% \end{function}
+%
+%
+%
+%
+%
+%
+%
+%
+%
+%
+%
+% \section{Primitive functions}
+%
+%
+% \begin{function}{%
+% \intexpr_value:w |
+% }
+% \begin{syntax}
+% "\intexpr_value:w" <integer> \\
+% "\intexpr_value:w" <tokens> <optional space>
+% \end{syntax}
+% Expands <tokens> until an <integer> is formed. One space may be
+% gobbled in the process.
+% \begin{texnote}
+% This is the \TeX{} primitive \tn{number}.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{%
+% \intexpr_eval:w |
+% \intexpr_eval_end: |
+% }
+% \begin{syntax}
+% "\intexpr_eval:w" <int expr> "\intexpr_eval_end:"
+% \end{syntax}
+% Evaluates <int expr>. The evaluation stops when an
+% unexpandable token of catcode other than 12 is reached or
+% "\intexpr_end:" is read. The latter is gobbled by the scanner
+% mechanism.
+% \begin{texnote}
+% This is the \eTeX{} primitive \tn{numexpr}.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{%
+% \if_intexpr_compare:w |
+% }
+% \begin{syntax}
+% "\if_intexpr_compare:w" <number1> <rel> <number2> <true> "\else:" <false> "\fi:"
+% \end{syntax}
+% Compare two numbers. It is recommended to use "\intexpr_eval:n" to
+% correctly evaluate and terminate these numbers. <rel> is one of
+% "<", "=" or ">" with catcode 12.
+% \begin{texnote}
+% This is the \TeX{} primitive \tn{ifnum}.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{%
+% \if_intexpr_odd:w |
+% }
+% \begin{syntax}
+% "\if_intexpr_odd:w" <number> <true> "\else:" <false> "\fi:"
+% \end{syntax}
+% Execute <true> if <number> is odd, <false> otherwise.
+% \begin{texnote}
+% This is the \TeX{} primitive \tn{ifodd}.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{%
+% \if_intexpr_case:w |
+% \or: |
+% }
+% \begin{syntax}
+% "\if_intexpr_case:w" <number> <case0> "\or:" <case1> "\or:" "..." "\else:"
+% <default> "\fi:"
+% \end{syntax}
+% Chooses case <number>. If you wish to use negative numbers as well,
+% you can offset them with "\intexpr_eval:n".
+% \begin{texnote}
+% These are the \TeX{} primitives \tn{ifcase} and \tn{or}.
+% \end{texnote}
+% \end{function}
+%
+%
+%
+% \begin{function}{%
+% \intexpr_while_do:nn |
+% \intexpr_until_do:nn |
+% \intexpr_do_while:nn |
+% \intexpr_do_until:nn |
+% }
+% \begin{syntax}
+% "\intexpr_while_do:nn" \Arg{<int~expr1> <rel> <int~expr2>} \Arg{code}
+% \end{syntax}
+% "\intexpr_while_do:nn" tests the integer expressions against each
+% other using a C-like <rel> as in "\intexpr_compare_p:n" and if true
+% performs the <code> until the test fails. "\intexpr_do_while:nn" is
+% similar but executes the <code> first and then performs the check,
+% thus ensuring that the body is executed at least once. The `until'
+% versions are similar but continue the loop as long as the test is
+% false. They could be omitted as it is just a matter of switching the
+% arguments in the test.
+% \end{function}
+%
+% \begin{function}{%
+% \intexpr_while_do:nNnn |
+% \intexpr_until_do:nNnn |
+% \intexpr_do_while:nNnn |
+% \intexpr_do_until:nNnn |
+% }
+% \begin{syntax}
+% "\intexpr_while_do:nNnn" <int expr> <rel> <int~expr> \Arg{code}
+% \end{syntax}
+% Exactly as above but instead using the syntax of
+% "\intexpr_compare_p:nNn".
+% \end{function}
+%
+%
+%
+%
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3intexpr} implementation}
+%
+%
+% We start by ensuring that the required packages are loaded.
+% \begin{macrocode}
+%<*package>
+\ProvidesExplPackage
+ {\filename}{\filedate}{\fileversion}{\filedescription}
+\package_check_loaded_expl:
+%</package>
+%<*initex|package>
+% \end{macrocode}
+%
+% \begin{macro}{\intexpr_value:w}
+% \begin{macro}{\intexpr_eval:n,\intexpr_eval:w,\intexpr_eval_end:}
+% \begin{macro}{\if_intexpr_compare:w}
+% \begin{macro}{\if_intexpr_odd:w}
+% \begin{macro}{\if_intexpr_case:w}
+% Here are the remaining primitives for number comparisons and
+% expressions.
+% \begin{macrocode}
+\cs_set_eq:NN \intexpr_value:w \tex_number:D
+\cs_set_eq:NN \intexpr_eval:w \etex_numexpr:D
+\cs_set_protected:Npn \intexpr_eval_end: {\tex_relax:D}
+\cs_set_eq:NN \if_intexpr_compare:w \tex_ifnum:D
+\cs_set_eq:NN \if_intexpr_odd:w \tex_ifodd:D
+\cs_set_eq:NN \if_intexpr_case:w \tex_ifcase:D
+\cs_set:Npn \intexpr_eval:n #1{
+ \intexpr_value:w \intexpr_eval:w #1\intexpr_eval_end:
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+%
+%
+%
+%
+%
+% \begin{macro}{\intexpr_compare_p:n}
+% \begin{macro}[TF]{\intexpr_compare:n}
+% 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}
+% \intexpr_compare_p:n { 5 + \l_tmpa_int != 4 - \l_tmpb_int }
+% \end{verbatim}
+% In other words, we want to somehow add the missing "\intexpr_eval:w"
+% where required. We can start evaluating from the left using
+% "\intexpr: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_set_conditional:Npnn \intexpr_compare:n #1{p,TF,T,F}{
+ \exp_after:wN \intexpr_compare_auxi:w \intexpr_value:w
+ \intexpr_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. "\tex_romannumeral:D" is handy here since its
+% expansion given a non-positive number is \m{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 "\tex_romannumeral:D",
+% thereby ridding us of the left hand side evaluation. We do however
+% save it for later.
+% \begin{macrocode}
+\cs_set:Npn \intexpr_compare_auxi:w #1#2\q_stop{
+ \exp_after:wN \intexpr_compare_auxii:w \tex_romannumeral:D
+ \if:w #1- \else: -\fi: #1#2 \q_stop #1#2 \q_nil
+}
+% \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_set:Npn \intexpr_compare_auxii:w #1#2#3\q_stop{
+ \use:c{
+ intexpr_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_set:cpn {intexpr_compare_=:w} #1=#2\q_nil{
+ \if_intexpr_compare:w #1=\intexpr_eval:w #2 \intexpr_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_set:cpn {intexpr_compare_==:w} #1==#2\q_nil{
+ \if_intexpr_compare:w #1=\intexpr_eval:w #2 \intexpr_eval_end:
+ \prg_return_true: \else: \prg_return_false: \fi:
+}
+% \end{macrocode}
+% Not equal is just about reversing the truth value.
+% \begin{macrocode}
+\cs_set:cpn {intexpr_compare_!=:w} #1!=#2\q_nil{
+ \if_intexpr_compare:w #1=\intexpr_eval:w #2 \intexpr_eval_end:
+ \prg_return_false: \else: \prg_return_true: \fi:
+}
+% \end{macrocode}
+% Less than and greater than are also straight forward.
+% \begin{macrocode}
+\cs_set:cpn {intexpr_compare_<:w} #1<#2\q_nil{
+ \if_intexpr_compare:w #1<\intexpr_eval:w #2 \intexpr_eval_end:
+ \prg_return_true: \else: \prg_return_false: \fi:
+}
+\cs_set:cpn {intexpr_compare_>:w} #1>#2\q_nil{
+ \if_intexpr_compare:w #1>\intexpr_eval:w #2 \intexpr_eval_end:
+ \prg_return_true: \else: \prg_return_false: \fi:
+}
+% \end{macrocode}
+% For the less than or equal operation, we simply add $1$ to the right
+% hand side and then use a less than test. A similar trick for the
+% greater than or equal test except there we subtract $1$.
+% \begin{macrocode}
+\cs_set:cpn {intexpr_compare_<=:w} #1<=#2\q_nil{
+ \if_intexpr_compare:w #1<\intexpr_eval:w #2 +\c_one \intexpr_eval_end:
+ \prg_return_true: \else: \prg_return_false: \fi:
+}
+\cs_set:cpn {intexpr_compare_>=:w} #1>=#2\q_nil{
+ \if_intexpr_compare:w #1>\intexpr_eval:w #2 - \c_one \intexpr_eval_end:
+ \prg_return_true: \else: \prg_return_false: \fi:
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\intexpr_compare_p:nNn}
+% \begin{macro}[TF]{\intexpr_compare:nNn}
+% More efficient but less natural in typing.
+% \begin{macrocode}
+\prg_set_conditional:Npnn \intexpr_compare:nNn #1#2#3{p,TF,T,F}{
+ \if_intexpr_compare:w \intexpr_eval:w #1 #2 \intexpr_eval:w #3 \intexpr_eval_end:
+ \prg_return_true: \else: \prg_return_false: \fi:
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+%
+% \begin{macro}{\intexpr_max:nn}
+% \begin{macro}{\intexpr_min:nn}
+% \begin{macro}{\intexpr_abs:n}
+% Functions for $\min$, $\max$, and absolute value.
+% \begin{macrocode}
+\cs_set:Npn \intexpr_abs:n #1{
+ \intexpr_value:w
+ \if_intexpr_compare:w \intexpr_eval:w #1<\c_zero
+ -
+ \fi:
+ \intexpr_eval:w #1\intexpr_eval_end:
+}
+\cs_set:Npn \intexpr_max:nn #1#2{
+ \intexpr_value:w \intexpr_eval:w
+ \if_intexpr_compare:w
+ \intexpr_eval:w #1>\intexpr_eval:w #2\intexpr_eval_end:
+ #1
+ \else:
+ #2
+ \fi:
+ \intexpr_eval_end:
+}
+\cs_set:Npn \intexpr_min:nn #1#2{
+ \intexpr_value:w \intexpr_eval:w
+ \if_intexpr_compare:w
+ \intexpr_eval:w #1<\intexpr_eval:w #2\intexpr_eval_end:
+ #1
+ \else:
+ #2
+ \fi:
+ \intexpr_eval_end:
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+%
+% \begin{macro}{\intexpr_div_truncate:nn}
+% \begin{macro}{\intexpr_div_round:nn}
+% \begin{macro}{\intexpr_mod:nn}
+% As "\intexpr_eval:w" rounds the result of a division we also
+% provide a version that truncates the result.
+% \begin{macrocode}
+% \end{macrocode}
+% Initial version didn't work correctly with e\TeX's implementation.
+% \begin{macrocode}
+%\cs_set:Npn \intexpr_div_truncate_raw:nn #1#2 {
+% \intexpr_eval:n{ (2*#1 - #2) / (2* #2) }
+%}
+% \end{macrocode}
+% New version by Heiko:
+% \begin{macrocode}
+\cs_set:Npn \intexpr_div_truncate:nn #1#2 {
+ \intexpr_value:w \intexpr_eval:w
+ \if_intexpr_compare:w \intexpr_eval:w #1 = \c_zero
+ 0
+ \else:
+ (#1
+ \if_intexpr_compare:w \intexpr_eval:w #1 < \c_zero
+ \if_intexpr_compare:w \intexpr_eval:w #2 < \c_zero
+ -( #2 +
+ \else:
+ +( #2 -
+ \fi:
+ \else:
+ \if_intexpr_compare:w \intexpr_eval:w #2 < \c_zero
+ +( #2 +
+ \else:
+ -( #2 -
+ \fi:
+ \fi:
+ 1)/2)
+ \fi:
+ /(#2)
+ \intexpr_eval_end:
+}
+% \end{macrocode}
+% For the sake of completeness:
+% \begin{macrocode}
+\cs_set:Npn \intexpr_div_round:nn #1#2 {\intexpr_eval:n{(#1)/(#2)}}
+% \end{macrocode}
+% Finally there's the modulus operation.
+% \begin{macrocode}
+\cs_set:Npn \intexpr_mod:nn #1#2 {
+ \intexpr_value:w
+ \intexpr_eval:w
+ #1 - \intexpr_div_truncate:nn {#1}{#2} * (#2)
+ \intexpr_eval_end:
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\intexpr_if_odd_p:n}
+% \begin{macro}[TF]{\intexpr_if_odd:n}
+% \begin{macro}{\intexpr_if_even_p:n}
+% \begin{macro}[TF]{\intexpr_if_even:n}
+% A predicate function.
+% \begin{macrocode}
+\prg_set_conditional:Npnn \intexpr_if_odd:n #1 {p,TF,T,F} {
+ \if_intexpr_odd:w \intexpr_eval:w #1\intexpr_eval_end:
+ \prg_return_true: \else: \prg_return_false: \fi:
+}
+\prg_set_conditional:Npnn \intexpr_if_even:n #1 {p,TF,T,F} {
+ \if_intexpr_odd:w \intexpr_eval:w #1\intexpr_eval_end:
+ \prg_return_false: \else: \prg_return_true: \fi:
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\intexpr_while_do:nn}
+% \begin{macro}{\intexpr_until_do:nn}
+% \begin{macro}{\intexpr_do_while:nn}
+% \begin{macro}{\intexpr_do_until:nn}
+% 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_set:Npn \intexpr_while_do:nn #1#2{
+ \intexpr_compare:nT {#1}{#2 \intexpr_while_do:nn {#1}{#2}}
+}
+\cs_set:Npn \intexpr_until_do:nn #1#2{
+ \intexpr_compare:nF {#1}{#2 \intexpr_until_do:nn {#1}{#2}}
+}
+\cs_set:Npn \intexpr_do_while:nn #1#2{
+ #2 \intexpr_compare:nT {#1}{\intexpr_do_while:nNnn {#1}{#2}}
+}
+\cs_set:Npn \intexpr_do_until:nn #1#2{
+ #2 \intexpr_compare:nF {#1}{\intexpr_do_until:nn {#1}{#2}}
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\intexpr_while_do:nNnn}
+% \begin{macro}{\intexpr_until_do:nNnn}
+% \begin{macro}{\intexpr_do_while:nNnn}
+% \begin{macro}{\intexpr_do_until:nNnn}
+% As above but not using the more natural syntax.
+% \begin{macrocode}
+\cs_set:Npn \intexpr_while_do:nNnn #1#2#3#4{
+ \intexpr_compare:nNnT {#1}#2{#3}{#4 \intexpr_while_do:nNnn {#1}#2{#3}{#4}}
+}
+\cs_set:Npn \intexpr_until_do:nNnn #1#2#3#4{
+ \intexpr_compare:nNnF {#1}#2{#3}{#4 \intexpr_until_do:nNnn {#1}#2{#3}{#4}}
+}
+\cs_set:Npn \intexpr_do_while:nNnn #1#2#3#4{
+ #4 \intexpr_compare:nNnT {#1}#2{#3}{\intexpr_do_while:nNnn {#1}#2{#3}{#4}}
+}
+\cs_set:Npn \intexpr_do_until:nNnn #1#2#3#4{
+ #4 \intexpr_compare:nNnF {#1}#2{#3}{\intexpr_do_until:nNnn {#1}#2{#3}{#4}}
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macrocode}
+%</initex|package>
+% \end{macrocode}
+%
+% \end{implementation}
+% \PrintIndex
+%
+% \endinput
diff --git a/Master/texmf-dist/source/latex/expl3/l3io.dtx b/Master/texmf-dist/source/latex/expl3/l3io.dtx
index b382744776b..6473c2dca8b 100644
--- a/Master/texmf-dist/source/latex/expl3/l3io.dtx
+++ b/Master/texmf-dist/source/latex/expl3/l3io.dtx
@@ -1,5 +1,5 @@
% \iffalse
-%% File: l3io.dtx Copyright (C) 1990-2006 LaTeX3 project
+%% File: l3io.dtx Copyright (C) 1990-2009 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
@@ -17,7 +17,7 @@
%%
%% The development version of the bundle can be found at
%%
-%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/
+%% http://www.latex-project.org/svnroot/experimental/trunk/
%%
%% for those people who are interested.
%%
@@ -36,7 +36,7 @@
\RequirePackage{l3names}
%</driver|package>
%\fi
-\GetIdInfo$Id: l3io.dtx 621 2007-09-01 20:14:19Z morten $
+\GetIdInfo$Id: l3io.dtx 1369 2009-05-31 21:36:35Z joseph $
{L3 Experimental i/o module}
%\iffalse
%<*driver>
@@ -44,14 +44,22 @@
\ProvidesFile{\filename.\filenameext}
[\filedate\space v\fileversion\space\filedescription]
%\iffalse
-\documentclass{l3doc}
+\documentclass[full]{l3doc}
\begin{document}
-\DocInput{\filename.\filenameext}
+\DocInput{l3io.dtx}
\end{document}
%</driver>
% \fi
%
-% \section{Low-level file i/o}
+% \title{The \textsf{l3io} package\thanks{This file
+% has version number \fileversion, last
+% revised \filedate.}\\
+% Low-level file i/o}
+% \author{\Team}
+% \date{\filedate}
+% \maketitle
+%
+% \begin{documentation}
%
% \TeX{} is capable of reading from and writing up to 16 individual
% streams. These i/o operations are accessable in \LaTeX3 with functions
@@ -60,25 +68,24 @@
% auxiliary file module, but here are the necessary functions for
% manipulating private streams.
%
-% Sometimes it is not know beforehand how much text is going to be
+% Sometimes it is not known beforehand how much text is going to be
% written with a single call. As a result some internal \TeX{} buffer
% may overflow. To avoid this kind of problem, \LaTeX3 maintains beside
-% direct write operations like "\iow_expanded:Nn" also so called ``long''
+% direct write operations like "\iow_now:Nx" also so called ``long''
% writes where the output is broken into individual lines on every blank
% in the text to be written. The resulting files are difficult to read
% for humans but since they usually serve only as internal storage this
% poses no problem.
%
-% Beside the functions that immediately act (e.g., "\iow_expanded:Nn",
+% Beside the functions that immediately act (e.g., "\iow_now:Nx",
% etc.) we also have deferred operations that are saved away until the
% next page is finished. This allow to expand the <tokens> at the right
% time to get correct page numbers etc.
%
-% \subsection{Functions for output streams}
+% \section{Functions for output streams}
%
-% \begin{function}{\iow_new:N |
-% \iow_new:c
-% }
+% \begin{function}{ \iow_new:N |
+% \iow_new:c }
% \begin{syntax}
% "\iow_new:N" <stream>
% \end{syntax}
@@ -90,11 +97,10 @@
% \end{texnote}
% \end{function}
%
-% \begin{function}{\iow_open:Nn |
-% \iow_open:cn
-% }
+% \begin{function}{ \iow_open:Nn |
+% \iow_open:cn }
% \begin{syntax}
-% "\iow_open:Nn" <stream> "{" <file name> "}"
+% "\iow_open:Nn" <stream> \Arg{file name}
% \end{syntax}
% Opens output stream <stream> to write to <file name>. The output
% stream is immediately available for use. If the <stream> was already
@@ -105,65 +111,93 @@
% still open at the end of the \TeX{} run will be automatically closed.
% \end{function}
%
-% \begin{function}{\iow_expanded:Nn |
-% \iow_unexpanded:Nn
-% }
+% \begin{function}{ \iow_close:N }
+% \begin{syntax}
+% "\iow_open:Nn" <stream>
+% \end{syntax}
+% Closes output stream <stream>.
+% \end{function}
+%
+% \subsection{Immediate writing}
+%
+% \begin{function}{ \iow_now:Nx |
+% \iow_now:Nn }
% \begin{syntax}
-% "\iow_expanded:Nn" <stream> "{" <tokens> "}"
+% "\iow_now:Nx" <stream> \Arg{tokens}
% \end{syntax}
-% This function immediately writes the expansion of <tokens> to the
+% "\iow_now:Nx" immediately writes the expansion of <tokens> to the
% output stream <stream>. If <stream> is not open output goes to the
-% terminal. The variant "\iow_unexpanded:Nn" writes out <tokens> without any
-% further expansion (verbatim).
+% terminal. The variant "\iow_now:Nn" writes out <tokens> without any
+% further expansion.
+% \begin{texnote}
+% These are the equivalent of \TeX's "\immediate\write" with and without
+% expansion control.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{ \iow_log:n | \iow_log:x |
+% \iow_term:x | \iow_term:n }
+% \begin{syntax}
+% "\iow_log:x" \Arg{tokens}
+% \end{syntax}
+% These functions write to the log file (also known as the transcript file) or
+% to the terminal respectively. They are equivalent to "\iow_now:Nx" where
+% <stream> is the transcript file ("\c_iow_log_stream") or the terminal
+% ("\c_iow_term_stream").
% \end{function}
%
-% \begin{function}{\iow_expanded_log:n |
-% \iow_expanded_term:n |
-% \iow_unexpanded_term:n
-% }
+% \begin{function}{ \iow_now_buffer_safe:Nn |
+% \iow_now_buffer_safe:Nx }
% \begin{syntax}
-% "\iow_expanded_log:n" "{" <tokens> "}"
+% "\iow_now_buffer_safe:Nn" <stream> \Arg{tokens}
% \end{syntax}
-% These functions write to the transcript or to the terminal
-% respectively. So they are equivalent to "\iow_expanded:Nn" where <stream>
-% is the transcript file ("\c_iow_log_stream") or the terminal
-% ("\c_io_term_stream").
+% Like "\iow_now:Nx" but splits <tokens> at every blank into separate
+% lines. When potentially (very) long token lists are being written, this
+% avoids the problem of
+% buffer overflow when reading back the file.
% \end{function}
%
-% \begin{function}{\iow_long_expanded:Nx |
-% \iow_long_unexpanded:Nn
-% }
+% \begin{function}{ \iow_now_when_avail:Nn |
+% \iow_now_when_avail:cn }
% \begin{syntax}
-% "\iow_long_expanded:Nn" <stream> "{" <tokens> "}"
+% "\iow_now_when_avail:Nn" <stream> \Arg{tokens}
% \end{syntax}
-% Like "\iow_expanded:Nn" but splits <tokens> at every blank into separate
-% lines.
+% This special function first checks if the <stream> is open for writing.
+% If not it does nothing otherwise it behaves like "\iow_now:Nn".
% \end{function}
%
-% \begin{function}{\iow_unexpanded_if_avail:Nn|
-% \iow_unexpanded_if_avail:cn|}
+% \subsection{Deferred writing}
+%
+% \begin{function}{ \iow_shipout:Nn | \iow_shipout:Nx }
% \begin{syntax}
-% "\iow_unexpanded_if_avail:Nn" <stream> "{" <tokens> "}"
+% "\iow_shipout_x:Nn" <stream> \Arg{tokens}
% \end{syntax}
-% This special function first checks if the <stream> is open of writing.
-% If not it does nothing otherwise it behaves like "\iow_unexpanded:Nn".
+% These functions write <tokens> to the specified <stream>, but unlike with
+% "\iow_now:Nn" which write the material immediately, "\iow_shipout:Nn" waits
+% until the processing of the current page has finished.
% \end{function}
%
-% \begin{function}{\iow_deferred_expanded:Nn |
-% \iow_deferred_unexpanded:Nn}
+% \begin{function}{ \iow_shipout_x:Nn | \iow_shipout_x:Nx }
% \begin{syntax}
-% "\iow_deferred_expanded:Nn" <stream> "{" <tokens> "}"
+% "\iow_shipout_x:Nn" <stream> \Arg{tokens}
% \end{syntax}
-% These functions save away <tokens> until the next page is ready to be
-% shipped out. Then, in case of "\iow_deferred_expanded:Nn" <tokens> get
-% expanded and afterwards written to <stream>. "\iow_deferred_expanded:Nn"
-% also always needs "{}" around the second argument. The use of
-% "\iow_deferred_unexpanded:Nn" is probably seldom necessary.
+% More useful than the "\iow_shipout:Nn" functions, these functions also write
+% <tokens> to <stream> at the end of the processing of the current page;
+% however, before <tokens> are written they are subjected to a further
+% "x" expansion stage.
+%
+% This is useful for writing messages that depend
+% on counters (such as the page number) that are not known until the page has
+% been completed.
+%
+% "\iow_shipout_x:Nn" always needs "{}" around the second argument.
% \begin{texnote}
-% "\iow_deferred_expanded:Nn" was known as \tn{write}.
+% "\iow_shipout_x:Nn" is equivalent to \TeX's \tn{write}.
% \end{texnote}
% \end{function}
%
+% \subsection{Special characters for writing}
+%
% \begin{function}{\iow_newline:}
% \begin{syntax}
% "\iow_newline:"
@@ -172,10 +206,26 @@
% that gets written some output stream in non-verbatim mode.
% \end{function}
%
-% \subsection{Functions for input streams}
+% \begin{function}{\iow_space:}
+% \begin{syntax}
+% "\iow_space:"
+% \end{syntax}
+% Function that produces a space when used within the <token list>
+% that gets written to some output stream in an expanding mode.
+% \end{function}
+%
+% \begin{function}{\iow_char:N}
+% \begin{syntax}
+% "\iow_space:N" "\"<char>
+% "\iow_space:N" "\%"
+% \end{syntax}
+% Inserts <char> into the output stream. Useful when trying to write difficult
+% characters such as "%", "{", "}", etc., in messages.
+% \end{function}
+%
+% \section{Functions for input streams}
%
-% \begin{function}{\ior_new:N
-% }
+% \begin{function}{\ior_new:N}
% \begin{syntax}
% "\ior_new:N" <stream>
% \end{syntax}
@@ -188,12 +238,12 @@
%
% \begin{function}{\ior_open:Nn}
% \begin{syntax}
-% "\ior_open:Nn" <stream> "{" <file name> "}"
+% "\ior_open:Nn" <stream> \Arg{file name}
% \end{syntax}
% This function opens <stream> as an input stream for the external file
% <file name>. If <file name> doesn't exist or is an empty file the
% stream is considered to be fully read, a condition which can be tested
-% with "\ior_eof:NTF" etc. If <stream> was already used to read from some
+% with "\ior_if_eof:NTF" etc. If <stream> was already used to read from some
% other file this file will be closed first. The input stream is ready
% for immediate use.
% \end{function}
@@ -209,10 +259,9 @@
% \end{texnote}
% \end{function}
%
-% \begin{function}{\ior_eof:NTF |
-% \ior_eof:NF}
+% \begin{function}{ \ior_if_eof_p:N / (EXP) | \ior_if_eof:N / (TF)(EXP) }
% \begin{syntax}
-% "\ior_eof:NTF" <stream> "{" <true code> "}{" <false code> "}"
+% "\ior_if_eof:NTF" <stream> \Arg{true code} \Arg{false code}
% \end{syntax}
% Conditional that tests if some input stream is fully read. The
% condition is also true if the input stream is not open.
@@ -228,18 +277,18 @@
% \end{texnote}
% \end{function}
%
-% \begin{function}{\ior_to:NN |
-% \ior_gto:NN}
+% \begin{function}{ \ior_to:NN |
+% \ior_gto:NN }
% \begin{syntax}
-% "\ior_to:NN" <stream> <tlp>
+% "\ior_to:NN" <stream> <tl var.>
% \end{syntax}
% Functions that reads one or more lines (until an equal number of left
% and right braces are found) from the input stream <stream> and places
-% the result locally or globally into <tlp>. If <stream> is not open
-% input is requested from the terminal.
+% the result locally or globally into the token list variable.
+% If <stream> is not open, input is requested from the terminal.
% \end{function}
%
-% \subsection{Constants}
+% \section{Constants}
%
% \begin{variable}{\c_iow_comment_char |
% \c_iow_lbrace_char |
@@ -248,55 +297,36 @@
% right brace in token lists that should be written to a file.
% \end{variable}
%
-% \begin{variable}{\c_io_term_stream}
+% \begin{variable}{ \c_iow_term_stream | \c_ior_term_stream }
% Input or output stream denoting the terminal. If used as an input
-% stream the user is prompted with the name of the <tlp> (that is used
+% stream the user is prompted with the name of the token list variable
+% (that is used
% in the call "\ior_to:NN" or "\ior_gto:NN") followed by an equal sign.
% If you don't want an automatic prompt of this sort ``misuse''
% "\c_iow_log_stream" as an input stream.
% \end{variable}
%
-% \begin{variable}{\c_iow_log_stream}
+% \begin{variable}{ \c_iow_log_stream | \c_ior_log_stream }
% Output stream that writes only to the transcript file (e.g., the
-% {\tt.log} file on most systems). You may ``misuse'' this stream as an
+% ".log" file on most systems). You may ``misuse'' this stream as an
% input stream. In this case it acts as a terminal stream without user
% prompting.
% \end{variable}
%
%
-% \subsection{Internal functions}
+% \end{documentation}
%
-% \begin{function}{\iow_long_expanded_aux:w}
-% Function used to implement immediate writing where a new line is
-% started at every blank.
-% \end{function}
-%
-% \begin{function}{%
-% \tex_read:D |
-% \tex_immediate:D |
-% \tex_closeout:D |
-% \tex_openin:D |
-% \tex_openout:D |
-% }
-% These are the functions of the primitive interface to \TeX.
-% \begin{texnote}
-% The \TeX{} primitives \tn{read}, \tn{immediate}, \tn{closeout},
-% \tn{openin}, and \tn{openout} are all renamed and should not be used
-% by a programmer since the functionality is covered by the \LaTeX3
-% functions above.
-% \end{texnote}
-% \end{function}
-%
-% \StopEventually{}
+% \begin{implementation}
%
-% \subsection{The Implementation}
+% \section{\pkg{l3io} implementation}
%
% We start by ensuring that the required packages are loaded.
% \begin{macrocode}
-%<package>\ProvidesExplPackage
-%<package> {\filename}{\filedate}{\fileversion}{\filedescription}
-%<package&check>\RequirePackage{l3chk}\par
-%<package>\RequirePackage{l3toks}\par
+%<*package>
+\ProvidesExplPackage
+ {\filename}{\filedate}{\fileversion}{\filedescription}
+\package_check_loaded_expl:
+%</package>
%<*initex|package>
% \end{macrocode}
%
@@ -305,27 +335,25 @@
% (for write) as module names. e.g.\ |\c_ior_test_stream| is an input stream
% variable called `test'.
%
-% \subsubsection{Output streams}
+% \subsection{Output streams}
%
-% \begin{macro}{\iow_new:N}
-% \begin{macro}{\iow_new:c}
+% \begin{macro}{\iow_new:N,\iow_new:c}
% Allocation of new output streams is done by these functions.
% As we currently do not distribute a new allocation module we nick
% the |\newwrite| function.
% \begin{macrocode}
%<*initex>
\alloc_setup_type:nnn {iow} \c_zero \c_sixteen
-\def_new:Npn \iow_new:N #1 {\alloc_reg:NnNN g {iow} \tex_chardef:D #1}
+\cs_new_nopar:Npn \iow_new:N #1 {\alloc_reg:NnNN g {iow} \tex_chardef:D #1}
%</initex>
-%<package>\let:NN \iow_new:N \newwrite
-\def_new:Npn \iow_new:c {\exp_args:Nc \iow_new:N}
+%<*package>
+\cs_set_eq:NN \iow_new:N \newwrite
+%</package>
+\cs_generate_variant:Nn \iow_new:N {c}
% \end{macrocode}
% \end{macro}
-% \end{macro}
-%
%
-% \begin{macro}{\iow_open:Nn}
-% \begin{macro}{\iow_open:cn}
+% \begin{macro}{\iow_open:Nn,\iow_open:cn}
% To open streams for reading or writing the following two functions
% are provided. The streams are opened immediately.
%
@@ -334,110 +362,99 @@
% We have to check whether this is also necessary in case of
% |\tex_openin:D|.
% \begin{macrocode}
-\def_new:Npn \iow_open:Nn #1#2{\iow_close:N #1
- \tex_immediate:D\tex_openout:D#1#2\scan_stop:}
-\def_new:Npn \iow_open:cn {\exp_args:Nc \iow_open:Nn}
+\cs_new_nopar:Npn \iow_open:Nn #1#2 {
+ \iow_close:N #1
+ \tex_immediate:D \tex_openout:D #1#2 \scan_stop:
+}
+\cs_generate_variant:Nn \iow_open:Nn {c}
% \end{macrocode}
% \end{macro}
-% \end{macro}
-%
%
% \begin{macro}{\iow_close:N}
% Since we close output streams prior to opening, a separate closing
% operation is probably not necessary. But here it is, just in
% case\ldots. Actually you will need this if you intend to write
-% and then read in the same pass from some stream.
+% and then read in the same pass from a stream.
% \begin{macrocode}
-\def_new:Npn \iow_close:N {\tex_immediate:D\tex_closeout:D}
+\cs_new_nopar:Npn \iow_close:N { \tex_immediate:D \tex_closeout:D }
% \end{macrocode}
% \end{macro}
%
%
-% \begin{macro}{\c_io_term_stream}
-% \begin{macro}{\c_iow_log_stream}
+% \begin{macro}{\c_iow_term_stream,\c_ior_term_stream}
+% \begin{macro}{\c_iow_log_stream,\c_ior_log_stream}
% Here we allocate two output streams for writing to the transcript
% file only (|\c_iow_log_stream|) and to both the terminal and transcript
-% file (|\c_io_term_stream|). The latter can also be used to read
-% from therefore it is called |..io_..|.
+% file (|\c_iow_term_stream|). Both can be used to read from and have
+% equivalent "\c_ior" versions.
% \begin{macrocode}
-\let_new:NN \c_io_term_stream \c_sixteen
-\let_new:NN \c_iow_log_stream \c_minus_one
+\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{macro}
% \end{macro}
%
% \paragraph{Immediate writing}
%
-% \begin{macro}{\iow_expanded:Nn}
+% \begin{macro}{\iow_now:Nx}
% An abbreviation for an often used operation, which immediately
-% writes its second argument to the output stream.
+% writes its second argument expanded to the output stream.
% \begin{macrocode}
-\def_new:Npn \iow_expanded:Nn {\tex_immediate:D\iow_deferred_expanded:Nn}
+\cs_new_nopar:Npn \iow_now:Nx { \tex_immediate:D \iow_shipout_x:Nn }
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\iow_unexpanded:Nn}
-% This routine writes the second argument verbatim onto the output
-% stream. If this stream isn't open, the output goes to the terminal.
+% \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}
-\def_new:Npn \iow_unexpanded:Nn #1#2{
- \iow_expanded:Nn #1{\exp_not:n{#2}}}
+\cs_new_nopar:Npn \iow_now:Nn #1#2 {
+ \iow_now:Nx #1 { \exp_not:n {#2} }
+}
% \end{macrocode}
% \end{macro}
%
%
-% \begin{macro}{\iow_expanded_log:n}
-% \begin{macro}{\iow_expanded_term:n}
+% \begin{macro}{\iow_log:n,\iow_log:x,\iow_term:n,\iow_term:x}
% Now we redefine two functions for which we needed a definition
-% very early on. They both write their second argument fully
-% expanded to the output stream.
+% very early on.
% \begin{macrocode}
-\def:Npn \iow_expanded_log:n {\iow_expanded:Nn \c_iow_log_stream}
-\def:Npn \iow_expanded_term:n{\iow_expanded:Nn \c_io_term_stream}
+\cs_set_nopar:Npn \iow_log:x { \iow_now:Nx \c_iow_log_stream }
+\cs_new_nopar:Npn \iow_log:n { \iow_now:Nn \c_iow_log_stream }
+\cs_set_nopar:Npn \iow_term:x { \iow_now:Nx \c_iow_term_stream }
+\cs_new_nopar:Npn \iow_term:n { \iow_now:Nn \c_iow_term_stream }
% \end{macrocode}
-% The second one isn't exactly equivalent to the old |\typeout| since
+% "\iow_term:x" isn't exactly equivalent to the old |\typeout| since
% we need to control expansion in the function we provide for the user.
% \end{macro}
-% \end{macro}
-
-% \begin{macro}{\iow_unexpanded_term:n}
-% This function writes its argument verbatim to the the terminal.
-% \begin{macrocode}
-\def_new:Npn \iow_unexpanded_term:n {\iow_unexpanded:Nn \c_io_term_stream}
-% \end{macrocode}
-% \end{macro}
%
%
-% \begin{macro}{\iow_unexpanded_if_avail:Nn}
-% \begin{macro}{\iow_unexpanded_if_avail:cn}
-% |\iow_unexpanded_if_avail:Nn | \m{stream} \m{code}. This routine writes
+% \begin{macro}{\iow_now_when_avail:Nn,\iow_now_when_avail:cn}
+% |\iow_now_when_avail:Nn | \m{stream} \m{code}. This routine writes
% its second argument unexpanded to the stream given by the first
% argument, provided that this stream was opened for writing. Note,
% that |#| characters get doubled within \m{code}.
-% \begin{macrocode}
-\def_new:Npn \iow_unexpanded_if_avail:Nn #1{
-% \end{macrocode}
+%
% In this routine we have to check whether or not the output stream
% that was requested is defined at all.
% So we check if the name is still free.
+%
% \begin{macrocode}
- \cs_free:NTF #1\use_none:n {\iow_unexpanded:Nn #1}}
-% \end{macrocode}
-% Note: the next function could be streamlined for speed if we use
-% the faster |\cs_free:cTF|. (space viz time).
-% \begin{macrocode}
-\def_new:Npn \iow_unexpanded_if_avail:cn {
- \exp_args:Nc \iow_unexpanded_if_avail:Nn }
+\cs_new_nopar:Npn \iow_now_when_avail:Nn #1 {
+ \cs_if_free:NTF #1 {\use_none:n} {\iow_now:Nn #1}
+}
+\cs_generate_variant:Nn \iow_now_when_avail:Nn {c}
% \end{macrocode}
% \end{macro}
-% \end{macro}
%
%
-% \begin{macro}{\iow_long_expanded:Nn}
-% \begin{macro}{\iow_long_unexpanded:Nn}
-% \begin{macro}{\iow_long_expanded_aux:w}
+% \begin{macro}{\iow_now_buffer_safe:Nn,\iow_now_buffer_safe:Nx}
+% \begin{macro}[aux]{\iow_now_buffer_safe_expanded_aux:w}
% Another type of writing onto an output stream is used for
% potentially long token sequences. We break the output lines at
% every blank in the second argument. This avoids the problem of
@@ -448,61 +465,42 @@
% But this can happen only if things like
% two spaces find their way into the second argument.
% Usually, multiple spaces are removed by \TeX's scanner.
-%
% \begin{macrocode}
-\def_new:Npn \iow_long_expanded_aux:w #1#2#3{
- \group_begin:\tex_newlinechar:D`\ #1#2{#3}\group_end:}
-\def_new:Npn \iow_long_expanded:Nn {\iow_long_expanded_aux:w
- \iow_expanded:Nn}
-\def_new:Npn \iow_long_unexpanded:Nn {\iow_long_expanded_aux:w
- \iow_unexpanded:Nn}
+\cs_new_nopar:Npn \iow_now_buffer_safe_aux:w #1#2#3 {
+ \group_begin: \tex_newlinechar:D`\ #1#2{#3} \group_end:
+}
+\cs_new_nopar:Npn \iow_now_buffer_safe:Nx {
+ \iow_now_buffer_safe_aux:w \iow_now:Nx
+}
+\cs_new_nopar:Npn \iow_now_buffer_safe:Nn {
+ \iow_now_buffer_safe_aux:w \iow_now:Nn
+}
% \end{macrocode}
% \end{macro}
% \end{macro}
-% \end{macro}
%
%
% \paragraph{Deferred writing}
-%
-% With \eTeX\ available deferred writing is easy. The comments below
-% are old.
%
-% Deferred writing to output streams is a bit more complicated because
-% there seems to be no nice hack for writing unexpanded. The only
-% relatively sure bet is to use |\token_to_meaning:N| expansion of some token
-% list. That's the way the following functions are implemented.
-%
-% Another possibility would be to reserve a certain number of scratch
-% token registers that could be used to hold the tokens until after the
-% next |\tex_shipout:D|. But such an approach would probably fail because of
-% the limited number of available token registers that would need to
-% be reserved for this special application.
-%
-%
-% \begin{macro}{\iow_deferred_expanded:Nn}
-% First the easy part, this is the primitive.
+% \begin{macro}{\iow_shipout_x:Nn,\iow_shipout_x:Nx}
+% First the easy part, this is the primitive.
% \begin{macrocode}
-\let:NN \iow_deferred_expanded:Nn \tex_write:D
+\cs_set_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_deferred_unexpanded:Nn}
-% Now the harder part:
+% \begin{macro}{\iow_shipout:Nn,\iow_shipout:Nx}
+% With \eTeX\ available deferred writing is easy.
% \begin{macrocode}
-\def_new:Npn \iow_deferred_unexpanded:Nn #1#2{
- \iow_deferred_expanded:Nn{\exp_not:n{#2}}
+\cs_new_nopar:Npn \iow_shipout:Nn #1#2{
+ \iow_shipout_x:Nn #1 { \exp_not:n {#2} }
}
-%% Old implementation:
-%\def_new:Npn \iow_deferred_unexpanded:Nn #1#2{
-% \tlp_set:Nn \l_tmpa_tlp {#2}
-% \tlp_set:Nx \l_tmpb_tlp
-% {\iow_deferred_expanded:Nn #1{\tlp_to_str:N \l_tmpa_tlp}}
-% \l_tmpb_tlp}
+\cs_generate_variant:Nn \iow_shipout:Nn {Nx}
% \end{macrocode}
% \end{macro}
%
-% Long forms of these functions are not possible since the deferred
+% `Buffer safe' forms of these functions are not possible since the deferred
% writing will restore the value of |\tex_newlinechar:D| before it will have
% a chance to act. But on the other hand it is nevertheless possible
% to make all deferred writes long by setting the |\tex_newlinechar:D|
@@ -515,33 +513,52 @@
%
% \begin{macro}{\iow_newline:}
% Global variable holding the character that forces a new line when
-% something is written to an output stream.
+% something is written to an output stream.
+% \begin{macrocode}
+\cs_new_nopar:Npn \iow_newline: {^^J}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\iow_space:}
+% Global variable holding the character that inserts a space char when
+% writing to an output stream.
+% \begin{macrocode}
+\cs_new_nopar:Npn \iow_space: {~}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\iow_char:N}
+% Function to write any escaped char to an output stream.
% \begin{macrocode}
-\def_new:Npn \iow_newline: {^^J}
+\cs_new:Nn \iow_char:N { \cs_to_str:N #1 }
% \end{macrocode}
% \end{macro}
%
+%
% \begin{macro}{\c_iow_comment_char}
% \begin{macro}{\c_iow_lbrace_char}
% \begin{macro}{\c_iow_rbrace_char}
+% TODO: remove these in favour of "\iow_char:N" (Will, Apr 2009)
+%
% We also need to be able to write braces and the comment character. We
% achieve this by defining global constants to expand into a version of
% these characters with |\tex_catcode:D|${}=12$.
% \begin{macrocode}
-\tlp_new:Nx \c_iow_comment_char {\cs_to_str:N\%}
+\tl_new:Nx \c_iow_comment_char {\cs_to_str:N\%}
% \end{macrocode}
% To avoid another allocation function which is probably only
-% necessary here we use the |\def:Npx| command directly.
+% necessary here we use the |\cs_set_nopar:Npx| command directly.
% \begin{macrocode}
-\tlp_new:Nx \c_iow_lbrace_char{\cs_to_str:N\{}
-\tlp_new:Nx \c_iow_rbrace_char{\cs_to_str:N\}}
+\tl_new:Nx \c_iow_lbrace_char{\cs_to_str:N\{}
+\tl_new:Nx \c_iow_rbrace_char{\cs_to_str:N\}}
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
%
-% \subsubsection{Input streams}
+% \subsection{Input streams}
%
% \begin{macro}{\ior_new:N}
% Allocation of new input streams is done by this function.
@@ -550,100 +567,79 @@
% \begin{macrocode}
%<*initex>
\alloc_setup_type:nnn {ior} \c_zero \c_sixteen
-\def_new:Npn \ior_new:N #1 {\alloc_reg:NnNN g {ior} \tex_chardef:D #1}
+\cs_new_nopar:Npn \ior_new:N #1 {\alloc_reg:NnNN g {ior} \tex_chardef:D #1}
%</initex>
-%<package>\let:NN \ior_new:N \newread
+%<package>\cs_set_eq:NN \ior_new:N \newread
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\ior_open:Nn}
-% \begin{macro}{\ior_close:Nn}
+% \begin{macro}{\ior_close:N}
% Processing of input-streams (via |\tex_openin:D| and |closein|) is
% always `immediate' as far as \TeX{} is concerned. An extra
% |\tex_immediate:D| is silently ignored.
% \begin{macrocode}
-\let:NN \ior_close:N \tex_closein:D
-\def_new:Npn \ior_open:Nn #1#2{\ior_close:N #1\scan_stop:
- \tex_openin:D#1#2\scan_stop:}
+\cs_set_eq:NN \ior_close:N \tex_closein:D
+\cs_new_nopar:Npn \ior_open:Nn #1#2 {
+ \ior_close:N #1 \scan_stop:
+ \tex_openin:D #1#2 \scan_stop:
+}
% \end{macrocode}
% \end{macro}
% \end{macro}
%
-% \begin{macro}{\ior_eof:NTF}
-% |\ior_eof:NTF | \m{stream} \m{true case} \m{false case}. To
-% test if some particular input stream is exhausted the following
-% conditional is provided:
+%
+% \begin{macro}{\if_eof:w}
% \begin{macrocode}
-\def_new:Npn \ior_eof:NTF #1{\if_eof:w#1
- \exp_after:NN\use_arg_i:nn \else:
- \exp_after:NN\use_arg_ii:nn \fi:}
+\cs_new_eq:NN \if_eof:w \tex_ifeof:D
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\ior_eof:NF}
-% \begin{macro}{\if_eof:w}
-% |\ior_eof:NF | \m{stream} \m{false case}. Do something if
-% if there is still something to read from this file:
+%
+% \begin{macro}{\ior_if_eof_p:N}
+% \begin{macro}[TF]{\ior_if_eof:N}
+% |\ior_if_eof:NTF | \m{stream} \m{true case} \m{false case}. To
+% test if some particular input stream is exhausted the following
+% conditional is provided:
% \begin{macrocode}
-\let:NN \if_eof:w \tex_ifeof:D
-\def_new:Npn \ior_eof:NF #1{\if_eof:w#1
- \exp_after:NN \use_none:nn \fi: \use_arg_i:n}
+\prg_new_conditional:Nnn \ior_if_eof:N {p,TF,T,F} {
+ \tex_ifeof:D #1 \prg_return_true: \else: \prg_return_false: \fi:
+}
% \end{macrocode}
% \end{macro}
% \end{macro}
%
%
+%
% \begin{macro}{\ior_to:NN}
% \begin{macro}{\ior_gto:NN}
% And here we read from files.
% \begin{macrocode}
-%<*check>
-\def_new:Npn \ior_to:NN #1#2{\tex_read:D#1to#2
- \chk_local_or_pref_global:N #2}
-%</check>
-%<-check> \def_new:Npn \ior_to:NN #1{\tex_read:D#1to}
-\def_new:Npn \ior_gto:NN {
-%<*check>
- \pref_global_chk:
-%</check>
-%<-check> \pref_global:D
- \ior_to:NN}
+\cs_new_nopar:Npn \ior_to:NN #1#2 {
+ \tex_read:D #1 to #2
+%<check> \chk_local_or_pref_global:N #2
+}
+\cs_new_nopar:Npn \ior_gto:NN {
+%<+check> \pref_global_chk:
+%<-check> \pref_global:D
+ \ior_to:NN
+}
% \end{macrocode}
% \end{macro}
% \end{macro}
%
+% \begin{macrocode}
+%</initex|package>
+% \end{macrocode}
%
% Show token usage:
% \begin{macrocode}
-%</initex|package>
%<*showmemory>
\showMemUsage
%</showmemory>
% \end{macrocode}
%
-% \endinput
-%
-% $Log$
-% Revision 1.16 2006/03/20 18:26:36 braams
-% Updated the copyright notice (2006) and demoted all implementation
-% sections to subsections and so on to clean up the toc for source3.tex
-%
-% Revision 1.15 2005/12/27 09:51:27 morten
-% Changed the use of RCS information
-%
-% Revision 1.14 2005/11/07 17:59:48 morten
-% Fixed definition of \iow_newline: (moved it to the right place)
-%
-% Revision 1.13 2005/04/29 22:29:23 braams
-% Replaced the undefined \g_iow_newline_code with \tex_newlinechar:D
-% and added the definition for \iow_newline:
-%
-% Revision 1.12 2005/04/06 22:35:37 braams
-% Now we have register allocation fitted
-%
-% Revision 1.11 2005/03/16 22:36:24 braams
-% Added the tweaks necessary to be able to load with initex
-%
-% Revision 1.10 2005/03/11 21:39:10 braams
-% Fixed the use of RCS information; added \StopEventually
+% \end{implementation}
+% \PrintIndex
%
+% \endinput
diff --git a/Master/texmf-dist/source/latex/expl3/l3keyval.dtx b/Master/texmf-dist/source/latex/expl3/l3keyval.dtx
index 4134b0fef51..8ac747e5d0a 100644
--- a/Master/texmf-dist/source/latex/expl3/l3keyval.dtx
+++ b/Master/texmf-dist/source/latex/expl3/l3keyval.dtx
@@ -1,5 +1,5 @@
% \iffalse
-%% File: l3keyval.dtx Copyright (C) 2006 LaTeX3 project
+%% File: l3keyval.dtx Copyright (C) 2006-2009 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
@@ -17,7 +17,7 @@
%%
%% The development version of the bundle can be found at
%%
-%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/
+%% http://www.latex-project.org/svnroot/experimental/trunk/
%%
%% for those people who are interested.
%%
@@ -35,7 +35,7 @@
\RequirePackage{l3names}
%</driver|package>
%\fi
-\GetIdInfo$Id: l3keyval.dtx 621 2007-09-01 20:14:19Z morten $
+\GetIdInfo$Id: l3keyval.dtx 1362 2009-05-28 20:19:21Z joseph $
{L3 Experimental keyval processing}
%\iffalse
%<*driver>
@@ -43,9 +43,9 @@
\ProvidesFile{\filename.\filenameext}
[\filedate\space v\fileversion\space\filedescription]
%\iffalse
-\documentclass{l3doc}
+\documentclass[full]{l3doc}
\begin{document}
-\DocInput{\filename.\filenameext}
+\DocInput{l3keyval.dtx}
\end{document}
%</driver>
% \fi
@@ -59,6 +59,8 @@
% \date{\filedate}
% \maketitle
%
+% \begin{documentation}
+%
% \section{Introduction}
%
% Currently, this module only provides functions for extracting keys
@@ -109,16 +111,13 @@
% two functions before starting the parsing process.
%
%
-% \subsection{Functions}
-%
-%
-%
+% \section{Functions}
%
% \begin{function}{
% \KV_parse_no_space_removal_no_sanitize:n |
% }
% \begin{syntax}
-% "\KV_parse_no_space_removal_no_sanitize:n" "{"<keyval list>"}"
+% "\KV_parse_no_space_removal_no_sanitize:n" \Arg{keyval list}
% \end{syntax}
% Parses the keys and values literally. For use when spaces are
% ignored and |=| and |,| have normal catcodes.
@@ -128,7 +127,7 @@
% \KV_parse_space_removal_no_sanitize:n |
% }
% \begin{syntax}
-% "\KV_parse_space_removal_no_sanitize:n" "{"<keyval list>"}"
+% "\KV_parse_space_removal_no_sanitize:n" \Arg{keyval list}
% \end{syntax}
% As above but also removes spaces around keys and values. For use
% when spaces are not ignored.
@@ -138,7 +137,7 @@
% \KV_parse_space_removal_sanitize:n |
% }
% \begin{syntax}
-% "\KV_parse_space_removal_sanitize:n" "{"<keyval list>"}"
+% "\KV_parse_space_removal_sanitize:n" \Arg{keyval list}
% \end{syntax}
% As above but additionally also replaces top-level active |=| and
% |,| with harmless versions.
@@ -166,43 +165,91 @@
% \KV_key_value_elt:nn |
% }
% \begin{syntax}
-% "\KV_key_no_value_elt:n" "{"<key>"}" \\
-% "\KV_key_value_elt:n" "{"<key>"}" "{"<value>"}"
+% "\KV_key_no_value_elt:n" \Arg{key} \\
+% "\KV_key_value_elt:n" \Arg{key} \Arg{value}
% \end{syntax}
% Functions returned by the |\KV_parse_| functions. The default
% definition of these two functions is an error message!
% \end{function}
%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3keyval} implementation}
+%
+% \subsection{Internal functions and variables}
+%
+% \begin{variable}{ \l_KV_tmpa_tl | \l_KV_tmpb_tl |
+% \c_KV_single_equal_sign_tl |
+% \l_KV_parse_toks | \l_KV_currkey_toks |
+% \l_KV_currval_toks }
+% Token list variables and token registers used internally.
+% \end{variable}
+%
+% \begin{function}{ \KV_sanitize_outerlevel_active_equals:N |
+% \KV_sanitize_outerlevel_active_commas:N }
+% \begin{syntax}
+% "\KV_sanitize_outerlevel_active_equals:N" <tl var.>
+% \end{syntax}
+% Replaces catcode other "=" and "," within a <tl var.> with active characters.
+% \end{function}
+%
+% \begin{function}{ \KV_remove_surrounding_spaces:nw |
+% \KV_remove_surrounding_spaces_auxi:w / (EXP) }
+% \begin{syntax}
+%
+% "\KV_remove_surrounding_spaces:nw" <toks> <token list> "\q_nil"
+% "\KV_remove_surrounding_spaces_auxi:w" <token list> \verb*" Q"$\sb3$
+% \end{syntax}
+% Removes a possible
+% leading space plus a possible ending space from a <token list>.
+% The first version (which is not used in the code) stores it in <toks>.
+% \end{function}
%
-% \StopEventually{}
+% \begin{function}{ \KV_add_value_element:w | \KV_set_key_element:w }
+% \begin{syntax}
+% "\KV_set_key_element:w" <token list> "\q_nil"
+% "\KV_add_value_element:w" "\q_stop" <token list> "\q_nil"
+% \end{syntax}
+% Specialised functions to strip spaces from their input and set the
+% token registers "\l_KV_currkey_toks" or "\l_KV_currval_toks"
+% respectively.
+% \end{function}
%
-% \section{Implementation}
+% \begin{function}{ \KV_split_key_value_current:w |
+% \KV_split_key_value_space_removal:w |
+% \KV_split_key_value_space_removal_detect_error:wTF |
+% \KV_split_key_value_no_space_removal:w }
+% \begin{syntax}
+% "\KV_split_key_value_current:w" \dots
+% \end{syntax}
+% These functions split keyval lists into chunks depending which
+% sanitising method is being used. "\KV_split_key_value_current:w" is "\cs_set_eq:NN"
+% to whichever is appropriate.
+% \end{function}
%
+% \subsection{Module code}
%
% We start by ensuring that the required packages are loaded.
% \begin{macrocode}
%<*package>
\ProvidesExplPackage
{\filename}{\filedate}{\fileversion}{\filedescription}
-\RequirePackage{l3quark}
-\RequirePackage{l3toks}
-\RequirePackage{l3int}
-\RequirePackage{l3token}
+\package_check_loaded_expl:
%</package>
%<*initex|package>
% \end{macrocode}
%
%
-%
-%
-% \begin{macro}{\l_KV_tmpa_tlp}
-% \begin{macro}{\l_KV_tmpb_tlp}
-% \begin{macro}{\c_KV_single_equal_sign_tlp}
+% \begin{macro}{\l_KV_tmpa_tl}
+% \begin{macro}{\l_KV_tmpb_tl}
+% \begin{macro}{\c_KV_single_equal_sign_tl}
% Various useful things.
% \begin{macrocode}
-\tlp_new:Nn\l_KV_tmpa_tlp{}
-\tlp_new:Nn\l_KV_tmpb_tlp{}
-\tlp_new:Nn \c_KV_single_equal_sign_tlp{=}
+\tl_new:N \l_KV_tmpa_tl
+\tl_new:N \l_KV_tmpb_tl
+\tl_new:Nn \c_KV_single_equal_sign_tl{=}
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -240,12 +287,12 @@
\char_set_catcode:nn{`\,}{13}
\char_set_lccode:nn{`\8}{`\=}
\char_set_lccode:nn{`\9}{`\,}
-\tlist_to_lowercase:n{\group_end:
-\def_new:Npn \KV_sanitize_outerlevel_active_equals:N #1{
- \tlp_replace_all_in:Nnn #1 = 8
+\tl_to_lowercase:n{\group_end:
+\cs_new_nopar:Npn \KV_sanitize_outerlevel_active_equals:N #1{
+ \tl_replace_all_in:Nnn #1 = 8
}
-\def_new:Npn \KV_sanitize_outerlevel_active_commas:N #1{
- \tlp_replace_all_in:Nnn #1 , 9
+\cs_new_nopar:Npn \KV_sanitize_outerlevel_active_commas:N #1{
+ \tl_replace_all_in:Nnn #1 , 9
}
}
% \end{macrocode}
@@ -258,10 +305,10 @@
%
% \begin{macro}{\KV_remove_surrounding_spaces:nw}
% \begin{macro}{\KV_remove_surrounding_spaces_auxi:w}
-% \begin{macro}{\KV_remove_surrounding_spaces_auxii:w}
+% \begin{macro}[aux]{\KV_remove_surrounding_spaces_auxii:w}
% \begin{macro}{\KV_set_key_element:w}
-% \begin{macro}{\KV_set_value_element:w}
-% The macro |\KV_remove_surrounding_spaces:Nw| removes a possible
+% \begin{macro}{\KV_add_value_element:w}
+% The macro |\KV_remove_surrounding_spaces:nw| removes a possible
% leading space plus a possible ending space from its second
% argument and stores it in the token register |#1|.
%
@@ -274,7 +321,7 @@
\char_set_catcode:nn{`\Q}{3}
% \end{macrocode}
% \begin{macrocode}
-\gdef_long_new:Npn\KV_remove_surrounding_spaces:nw#1#2\q_nil{
+\cs_gnew:Npn\KV_remove_surrounding_spaces:nw#1#2\q_nil{
% \end{macrocode}
% The idea in this processing is to use a Q with strange catcode to
% remove a trailing space. But first, how to get this expansion going?
@@ -312,7 +359,7 @@
% |\KV_remove_surrounding_spaces_auxii:w| to work properly we need to
% put back a Q first.
% \begin{macrocode}
-\gdef_long_new:Npn\KV_remove_surrounding_spaces_auxi:w#1~Q{
+\cs_gnew:Npn\KV_remove_surrounding_spaces_auxi:w#1~Q{
\KV_remove_surrounding_spaces_auxii:w #1 Q
}
% \end{macrocode}
@@ -320,39 +367,41 @@
% taken care of by the function used to initiate the expansion. Simply
% return the argument before the funny Q.
% \begin{macrocode}
-\gdef_long_new:Npn\KV_remove_surrounding_spaces_auxii:w#1Q#2{#1}
+\cs_gnew:Npn\KV_remove_surrounding_spaces_auxii:w#1Q#2{#1}
% \end{macrocode}
+%
% Here are some specialized versions of the above. They do exactly
% what we want in one go. First trim spaces from the value and then
% put the result surrounded in braces onto |\l_KV_parse_toks|.
% \begin{macrocode}
-\gdef_long_new:Npn\KV_add_value_element:w\q_stop#1\q_nil{
+\cs_gnew:Npn\KV_add_value_element:w\q_stop#1\q_nil{
\toks_set:Nf\l_KV_currval_toks {
\KV_remove_surrounding_spaces_auxi:w \exp_not:N#1Q~Q
}
\toks_put_right:No\l_KV_parse_toks{
- \exp_after:NN {\toks_use:N \l_KV_currval_toks}
+ \exp_after:wN {\toks_use:N \l_KV_currval_toks}
}
}
% \end{macrocode}
% When storing the key we firstly remove spaces plus the prepended
% |\q_no_value|.
% \begin{macrocode}
-\gdef_long_new:Npn\KV_set_key_element:w#1\q_nil{
+\cs_gnew:Npn\KV_set_key_element:w#1\q_nil{
\toks_set:Nf\l_KV_currkey_toks
{
- \exp_after:NN\KV_remove_surrounding_spaces_auxi:w
- \exp_after:NN\exp_not:N\use_none:n #1Q~Q
+ \exp_last_unbraced:NNo \KV_remove_surrounding_spaces_auxi:w
+ \exp_not:N \use_none:n #1Q~Q
}
% \end{macrocode}
% Afterwards we gobble an extra level of braces if that's what we are
-% asked to do.
+% asked to do. The next part can be done using \cs{toks_set:Nd}, but
+% this might not be around for long.
% \begin{macrocode}
\bool_if:NT \l_KV_remove_one_level_of_braces_bool
{
- \toks_set:Nd \l_KV_currkey_toks{
- \exp_after:NN \KV_add_element_aux:w
- \toks_use:N \l_KV_currkey_toks \q_nil
+ \exp_args:NNo \toks_set:No \l_KV_currkey_toks {
+ \exp_after:wN \KV_add_element_aux:w
+ \toks_use:N \l_KV_currkey_toks \q_nil
}
}
}
@@ -364,10 +413,10 @@
% \end{macro}
% \end{macro}
%
-% \begin{macro}{\KV_add_element_aux:w}
+% \begin{macro}[aux]{\KV_add_element_aux:w}
% A helper function for fixing braces around keys and values.
% \begin{macrocode}
-\def_long_new:Npn \KV_add_element_aux:w#1\q_nil{#1}
+\cs_new:Npn \KV_add_element_aux:w#1\q_nil{#1}
% \end{macrocode}
% \end{macro}
%
@@ -375,57 +424,58 @@
% Parse a list of keyvals, put them into list form with entries like
% |\KV_key_no_value_elt:n{key1}| and |\KV_key_value_elt:nn{key2}{val2}|.
%
-% \begin{macro}{\KV_parse_sanitize_aux:n}
+% \begin{macro}[aux]{\KV_parse_sanitize_aux:n}
% The slow parsing algorithm sanitizes active commas and equal signs
% at the top level first. Then uses |#1| as inspector of each
% element in the comma list.
% \begin{macrocode}
-\def_long_new:Npn \KV_parse_sanitize_aux:n #1{
+\cs_new:Npn \KV_parse_sanitize_aux:n #1 {
\group_begin:
- \toks_clear:N \l_KV_parse_toks
- \tlp_set:Nx\l_KV_tmpa_tlp{\exp_not:n{#1}}
- \KV_sanitize_outerlevel_active_equals:N\l_KV_tmpa_tlp
- \KV_sanitize_outerlevel_active_commas:N\l_KV_tmpa_tlp
- \exp_after:NN \KV_parse_elt:w \exp_after:NN\q_no_value \l_KV_tmpa_tlp,\q_nil,
+ \toks_clear:N \l_KV_parse_toks
+ \tl_set:Nx \l_KV_tmpa_tl { \exp_not:n {#1} }
+ \KV_sanitize_outerlevel_active_equals:N \l_KV_tmpa_tl
+ \KV_sanitize_outerlevel_active_commas:N \l_KV_tmpa_tl
+ \exp_last_unbraced:NNV \KV_parse_elt:w \q_no_value
+ \l_KV_tmpa_tl , \q_nil ,
% \end{macrocode}
% We evaluate the parsed keys and values outside the group so the
% token register is restored to its previous value.
% \begin{macrocode}
- \exp_after:NN\group_end:
- \toks_use:N \l_KV_parse_toks
+ \exp_last_unbraced:NV \group_end:
+ \l_KV_parse_toks
}
% \end{macrocode}
% \end{macro}
%
%
-% \begin{macro}{\KV_parse_no_sanitize_aux:n}
+% \begin{macro}[aux]{\KV_parse_no_sanitize_aux:n}
% Like above but we don't waste time sanitizing. This is probably
% the one we will use for preamble parsing where catcodes of |=| and
% |,| are as expected!
% \begin{macrocode}
-\def_long_new:Npn \KV_parse_no_sanitize_aux:n #1{
+\cs_new:Npn \KV_parse_no_sanitize_aux:n #1{
\group_begin:
- \toks_clear:N \l_KV_parse_toks
- \KV_parse_elt:w \q_no_value #1,\q_nil,
- \exp_after:NN\group_end:
- \toks_use:N \l_KV_parse_toks
+ \toks_clear:N \l_KV_parse_toks
+ \KV_parse_elt:w \q_no_value #1 , \q_nil ,
+ \exp_last_unbraced:NV \group_end:
+ \l_KV_parse_toks
}
% \end{macrocode}
% \end{macro}
%
%
-% \begin{macro}{\KV_parse_elt:w}
+% \begin{macro}[aux]{\KV_parse_elt:w}
% This function will always have a |\q_no_value| stuffed in as the
% rightmost token in |#1|. In case there was a blank entry in the
% comma separated list we just run it again. The |\use_none:n| makes
% sure to gobble the quark |\q_no_value|. A similar test is made to
% check if we hit the end of the recursion.
% \begin{macrocode}
-\def_long:Npn \KV_parse_elt:w #1,{
- \tlist_if_blank:oTF{\use_none:n #1}
+\cs_set:Npn \KV_parse_elt:w #1,{
+ \tl_if_blank:oTF{\use_none:n #1}
{ \KV_parse_elt:w \q_no_value }
{
- \quark_if_nil:oF {\use_arg_ii:nn #1 }
+ \quark_if_nil:oF {\use_ii:nn #1 }
% \end{macrocode}
% If we made it to here we can start parsing the key and value. When
% done try, try again.
@@ -443,7 +493,7 @@
% \begin{macro}{\KV_split_key_value_current:w}
% The function called to split the keys and values.
% \begin{macrocode}
-\let_new:NN \KV_split_key_value_current:w \ERROR
+\cs_new:Npn \KV_split_key_value_current:w {\ERROR}
% \end{macrocode}
% \end{macro}
%
@@ -462,7 +512,7 @@
%
% \begin{macro}{\KV_split_key_value_space_removal:w}
% \begin{macro}{\KV_split_key_value_space_removal_detect_error:wTF}
-% \begin{macro}{\KV_split_key_value_space_removal_aux:w}
+% \begin{macro}[aux]{\KV_split_key_value_space_removal_aux:w}
% The code below removes extraneous spaces around the keys and
% values plus one set of braces around the entire value.
%
@@ -474,7 +524,7 @@
% this is slightly more tedious (but only slightly) but at least it
% always removes only one level of braces.
% \begin{macrocode}
-\def_long_new:Npn \KV_split_key_value_space_removal:w #1 = #2\q_nil{
+\cs_new:Npn \KV_split_key_value_space_removal:w #1 = #2\q_nil{
% \end{macrocode}
% First grab the key.
% \begin{macrocode}
@@ -483,15 +533,15 @@
% Then we start checking. If only a key was entered, |#2| contains
% |=| and nothing else, so we test for that first.
% \begin{macrocode}
- \tlp_set:Nx\l_KV_tmpa_tlp{\exp_not:n{#2}}
- \tlp_if_eq:NNTF\l_KV_tmpa_tlp\c_KV_single_equal_sign_tlp
+ \tl_set:Nx\l_KV_tmpa_tl{\exp_not:n{#2}}
+ \tl_if_eq:NNTF\l_KV_tmpa_tl\c_KV_single_equal_sign_tl
% \end{macrocode}
% Then we just insert the default key.
% \begin{macrocode}
{
\toks_put_right:No\l_KV_parse_toks{
- \exp_after:NN \KV_key_no_value_elt:n
- \exp_after:NN {\toks_use:N\l_KV_currkey_toks}
+ \exp_after:wN \KV_key_no_value_elt:n
+ \exp_after:wN {\toks_use:N\l_KV_currkey_toks}
}
}
% \end{macrocode}
@@ -510,9 +560,9 @@
% \end{macrocode}
% The error test.
% \begin{macrocode}
-\def_long_new:Npn
+\cs_new:Npn
\KV_split_key_value_space_removal_detect_error:wTF#1=#2#3\q_nil{
- \tlist_if_head_eq_meaning:nNTF{#3}\q_no_value
+ \tl_if_head_eq_meaning:nNTF{#3}\q_no_value
}
% \end{macrocode}
% Now we can start extracting the value. Recall that |#1| here starts
@@ -521,18 +571,18 @@
% is empty or blank, all three quarks are gobbled. If |#1| consists of
% exactly one token or brace group, only the latter quark is left.
% \begin{macrocode}
-\def_long_new:Npn \KV_val_preserve_braces:NnN #1#2#3{{#2}}
-\def_long_new:Npn\KV_split_key_value_space_removal_aux:w #1=={
- \tlp_set:Nx\l_KV_tmpa_tlp{\exp_not:o{\use_none:nnn#1\q_nil\q_nil}}
+\cs_new:Npn \KV_val_preserve_braces:NnN #1#2#3{{#2}}
+\cs_new:Npn\KV_split_key_value_space_removal_aux:w #1=={
+ \tl_set:Nx\l_KV_tmpa_tl{\exp_not:o{\use_none:nnn#1\q_nil\q_nil}}
\toks_put_right:No\l_KV_parse_toks{
- \exp_after:NN \KV_key_value_elt:nn
- \exp_after:NN {\toks_use:N\l_KV_currkey_toks}
+ \exp_after:wN \KV_key_value_elt:nn
+ \exp_after:wN {\toks_use:N\l_KV_currkey_toks}
}
% \end{macrocode}
-% If there a blank space or nothing at all, |\l_KV_tmpa_tlp| is now
+% If there a blank space or nothing at all, |\l_KV_tmpa_tl| is now
% completely empty.
% \begin{macrocode}
- \tlp_if_empty:NTF\l_KV_tmpa_tlp
+ \tl_if_empty:NTF\l_KV_tmpa_tl
% \end{macrocode}
% We just put an empty value on the stack.
% \begin{macrocode}
@@ -540,21 +590,21 @@
{
% \end{macrocode}
% If there was exactly one brace group or token in |#1|,
-% |\l_KV_tmpa_tlp| is now equal to |\q_nil|. Then we can just pick it
+% |\l_KV_tmpa_tl| is now equal to |\q_nil|. Then we can just pick it
% up as the second argument of |#1|. This will also take care of any
% spaces which might surround it.
% \begin{macrocode}
- \quark_if_nil:NTF\l_KV_tmpa_tlp
+ \quark_if_nil:NTF\l_KV_tmpa_tl
{
\bool_if:NTF \l_KV_remove_one_level_of_braces_bool
{
\toks_put_right:No\l_KV_parse_toks{
- \exp_after:NN{\use_arg_ii:nnn #1\q_nil}
+ \exp_after:wN{\use_ii:nnn #1\q_nil}
}
}
{
\toks_put_right:No\l_KV_parse_toks{
- \exp_after:NN{\KV_val_preserve_braces:NnN #1\q_nil}
+ \exp_after:wN{\KV_val_preserve_braces:NnN #1\q_nil}
}
}
}
@@ -575,14 +625,14 @@
% however fun they may be. Since there are no spaces, a set of
% braces around a value is automatically stripped by \TeX.
% \begin{macrocode}
-\def_long_new:Npn \KV_split_key_value_no_space_removal:w #1#2=#3=#4\q_nil{
- \tlp_set:Nn\l_KV_tmpa_tlp{#4}
- \tlp_if_empty:NTF \l_KV_tmpa_tlp
+\cs_new:Npn \KV_split_key_value_no_space_removal:w #1#2=#3=#4\q_nil{
+ \tl_set:Nn\l_KV_tmpa_tl{#4}
+ \tl_if_empty:NTF \l_KV_tmpa_tl
{
\toks_put_right:Nn\l_KV_parse_toks{\KV_key_no_value_elt:n{#2}}
}
{
- \tlp_if_eq:NNTF\c_KV_single_equal_sign_tlp\l_KV_tmpa_tlp
+ \tl_if_eq:NNTF\c_KV_single_equal_sign_tl\l_KV_tmpa_tl
{
\toks_put_right:Nn\l_KV_parse_toks{\KV_key_value_elt:nn{#2}{#3}}
}
@@ -597,8 +647,8 @@
% \begin{macro}{\KV_key_no_value_elt:n}
% \begin{macro}{\KV_key_value_elt:nn}
% \begin{macrocode}
-\def_long_new:Npn \KV_key_no_value_elt:n #1{\ERROR}
-\def_long_new:Npn \KV_key_value_elt:nn #1#2{\ERROR}
+\cs_new:Npn \KV_key_no_value_elt:n #1{\ERROR}
+\cs_new:Npn \KV_key_value_elt:nn #1#2{\ERROR}
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -612,8 +662,8 @@
% version that disallows unmatched conditional and does no space
% removal.
% \begin{macrocode}
-\def_new:Npn \KV_parse_no_space_removal_no_sanitize:n {
- \let:NN \KV_split_key_value_current:w \KV_split_key_value_no_space_removal:w
+\cs_new_nopar:Npn \KV_parse_no_space_removal_no_sanitize:n {
+ \cs_set_eq:NN \KV_split_key_value_current:w \KV_split_key_value_no_space_removal:w
\KV_parse_no_sanitize_aux:n
}
% \end{macrocode}
@@ -624,15 +674,15 @@
% The other varieties can be defined in a similar manner. For the
% version needed at the document level, we can use this one.
% \begin{macrocode}
-\def_new:Npn \KV_parse_space_removal_sanitize:n {
- \let:NN \KV_split_key_value_current:w \KV_split_key_value_space_removal:w
+\cs_new_nopar:Npn \KV_parse_space_removal_sanitize:n {
+ \cs_set_eq:NN \KV_split_key_value_current:w \KV_split_key_value_space_removal:w
\KV_parse_sanitize_aux:n
}
% \end{macrocode}
% For preamble use by the non-programmer this is probably best.
% \begin{macrocode}
-\def_new:Npn \KV_parse_space_removal_no_sanitize:n {
- \let:NN \KV_split_key_value_current:w \KV_split_key_value_space_removal:w
+\cs_new_nopar:Npn \KV_parse_space_removal_no_sanitize:n {
+ \cs_set_eq:NN \KV_split_key_value_current:w \KV_split_key_value_space_removal:w
\KV_parse_no_sanitize_aux:n
}
% \end{macrocode}
@@ -642,24 +692,15 @@
%
% \begin{macrocode}
%</initex|package>
+% \end{macrocode}
+%
+% \begin{macrocode}
%<*showmemory>
\showMemUsage
%</showmemory>
% \end{macrocode}
%
-% \endinput
-%
-% $Log$
-% Revision 1.4 2006/07/25 22:38:58 morten
-% Removed spurious \exp_after:NN in \KV_add_value_element:w. Sigh.
-%
-% Revision 1.3 2006/07/25 22:34:03 morten
-% Fixed silly bug in \KV_set_key_element:w plus clean-up of code
-%
-% Revision 1.2 2006/07/25 16:21:30 morten
-% Allow values to contain unmatched conditionals such as `val
-% \fi:'. Provide option to not strip any braces at all.
-%
-% Revision 1.1 2006/01/27 10:14:24 morten
-% Initial version of keyval parser
+% \end{implementation}
+% \PrintIndex
%
+% \endinput
diff --git a/Master/texmf-dist/source/latex/expl3/l3messages.dtx b/Master/texmf-dist/source/latex/expl3/l3messages.dtx
deleted file mode 100644
index b5ae9e6025f..00000000000
--- a/Master/texmf-dist/source/latex/expl3/l3messages.dtx
+++ /dev/null
@@ -1,966 +0,0 @@
-% \iffalse
-%% File: l3messages.dtx Copyright (C) 1990-2007 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/cgi-bin/cvsweb.cgi/
-%%
-%% 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 LaTeX Project Team.
-%%
-%% -----------------------------------------------------------------------
-%
-%<*driver|package>
-\RequirePackage{l3names}
-%</driver|package>
-%\fi
-\GetIdInfo$Id: l3messages.dtx 673 2007-09-28 20:50:33Z mittelba $
- {L3 Experimental LaTeX Messages module}
-%\iffalse
-%<*driver>
-%\fi
-\ProvidesFile{\filename.\filenameext}
- [\filedate\space v\fileversion\space\filedescription]
-%\iffalse
-\documentclass{l3doc}
-\begin{document}
-\DocInput{\filename.\filenameext}
-\end{document}
-%</driver>
-% \fi
-%
-%
-% \section{Communicating with the user}
-%
-% Sometimes it is necesary to pass information back to the user
-% about what is going on. The information can be just that,
-% information, or it can be a warning that something might not
-% happen to his expectation. It could also be that something has
-% gone awry and that processing can't reliably continue without
-% some help from the user. In such a case an error is signalled.
-% When things are really bad, processing may have to stop as there
-% is no way to enter additional commands that put things right
-% again. In such a case we have a fatal error and the \LaTeX\ run
-% will be aborted.
-%
-% \subsection{Displaying the information}
-%
-% First of all we need a couple of fairly low level functions that
-% deal with the job of passing the information to the user.
-%
-% Real information is usually only written to the log file, while
-% warnings are displayed on the screen as well.
-% \begin{function}{%
-% \err_info:nn |
-% \err_warn:nn
-% }
-% \begin{syntax}
-% "\err_info:nn" "{" <message> "}" "{"<continuation>"}"
-% \end{syntax}
-% The <message> will be written to the log file. When it contains
-% the command "\err_newline:" a line break will occur and the new
-% line will start with the <continuation>. The function
-% "\err_warn:nn" writes the message to the terminal as well.
-% \end{function}
-% When an erroneous situation is encountered, a message is
-% displayed and the user is given the opportunity to enter some
-% additional code in an attempt to put things right. He may first
-% ask for some help, in which case some extra text will be
-% displayed to him.
-% \begin{function}{\err_interrupt:NNw}
-% \begin{syntax}
-% "\err_interrupt:NNw" <err id> <label> <more args>
-% \end{syntax}
-% This function signals a user error by searching the error file
-% denoted by <err id> for an error message associated with <label>,
-% i.e., specified by a corresponding "\err_interrupt_new:NNNnnn"
-% command. Depending on the number of arguments specified as
-% <argno> when the error message was defined, further arguments are
-% read. Then the error message is displayed as explained in
-% "\err_interrupt_new:NNNnnn".
-% \end{function}
-%
-% Finally, when something really serious occurs, \LaTeX\ will tell
-% the user about it and abort the run.
-% \begin{function}{\err_fatal:nn}
-% \begin{syntax}
-% "\err_fatal:nn" "{" <message> "}" "{"<continuation>"}"
-% \end{syntax}
-% Just displays the <message> and then aborts the \LaTeX\ run.
-% \end{function}
-%
-% \begin{function}{\err_newline:}
-% \begin{syntax}
-% "\err_newline:"
-% \end{syntax}
-% Is used to break an informational, warning or error message up
-% into multiple lines. May be defined in such a way that the new
-% line starts with a standard <continuation>. A normal line break in such
-% messages can be achieved with "\iow_newline:" from the l3iow module.
-% \end{function}
-%
-% \subsection{Storing the information}
-%
-% The informational and warning messages are usually short and can
-% be stored as part of a macro; but error messages need to be more
-% verbose. Therefor error messages are stored in external files
-% which are read and searched for the correct error message at the
-% time of the error. In this way it is possible to write extensive
-% help texts without cluttering \TeX{}'s main memory.
-%
-% \subsubsection{Dealing with the error file}
-%
-% \begin{function}{\err_file_new:Nn}
-% \begin{syntax}
-% "\err_file_new:Nn" <err id> "{"<err file name>"}"
-% \end{syntax}
-% Opens a new error file to write errors to. <err id> is a unique
-% identifier for the external <err file name>. By convention <err
-% id> is declared as a constant (i.e., starts with "\c_") und ends
-% with "_tlp". If this command is issued while some other error
-% file is open we get an internal error message.
-% \end{function}
-%
-% \begin{function}{\err_file_close:N}
-% \begin{syntax}
-% "\err_file_close:N" <err id>
-% \end{syntax}
-% Closes the currently open error file and checks that it matches
-% <err id>, i.e., that everything is alright in the code.
-% \end{function}
-%
-% \subsubsection{Declaring an error message in the error file}
-% \begin{function}{\err_interrupt_new:NNNnnn}
-% \begin{syntax}
-% "\err_interrupt_new:NNNnnn" <err id> <label> <argno>
-% "{" <short msg> "}"
-% "{" <long msg> "}"
-% "{" <recovery code> "}"
-% \end{syntax}
-% This function declares an new error message which can be
-% addressed via "\err_interrupt:NNw". The pair (<err id>, <label>)
-% has to be unique where <label> can be some otherwise arbitrary
-% token (usually the function name in which the error routine is
-% called. Actually, the pair (<err id>, expansion of <label>) has
-% to be unique since for reasons of speed, tests are carried out
-% using "\if_meaning:NN".
-%
-% <argno> specifies the number of extra arguments that will be
-% supplied to the error routine when "\err_interrupt:NNw" is
-% called. These arguments can be used within <short msg>, <long
-% msg>, and/or <recovery code> to provide further information to
-% the user. They are denoted with "#1", "#2", etc.\ within these
-% arguments.
-%
-% The <short msg> is displayed directly on the terminal if the
-% error occurs, <long msg> is displayed when the user types "h" in
-% response to the error prompt of \TeX{}, and <recovery code> is
-% executed afterwards. This means that <recovery code> is inserted
-% after any deletions or insertions given by the user. All three
-% arguments are expanded while they are written to the error file,
-% therefore one has to prevent expansion of tokens with
-% "\token_to_string:N" that should be expanded when the error is
-% triggered.
-% \end{function}
-%
-% \subsection{Internal functions}
-%
-% \begin{function}{\err_display_aux:w}
-% This function is constructed on the fly while reading the error file.
-% It grabs following arguments from the code (if any) and then displays
-% the error message and inserts the <recovery code>.
-% \end{function}
-%
-% \begin{function}{\err_interrupt_new_aux:w}
-% Helper function used to write the error message info onto the error
-% file.
-% \end{function}
-%
-% \begin{function}{\err_msgline_aux:NNnnn}
-% \begin{syntax}
-% "\err_msgline_aux:NNnnn" <argno> <label> "{"<short>"}"
-% "{"<long msg>"}{"<recovery code>"}"
-% \end{syntax}
-% Function written in front of every error message on the error file. It
-% will be executed when the error file is read back in comparing <label>
-% to "\l_err_label_token". If they are the same, "\err_display_aux:w"
-% will be defined and the reading process will stop.
-% \end{function}
-%
-% \begin{function}{\err_message:x}
-% \begin{syntax}
-% "\err_message:x" "{"<error message>"}"
-% \end{syntax}
-% Function that directly triggers \TeX{}'s error handler. It should
-% not be used directly.
-% \begin{texnote}
-% This is the \LaTeX3 name for the \tn{errormessage} primitive.
-% \end{texnote}
-% \end{function}
-%
-% \subsection{Kernel specific functions}
-%
-% For a number of the functions described above specific variants
-% are provided that are used in the kernel of \LaTeX3.
-%
-% \begin{function}{%
-% \err_kernel_info:n |
-% \err_kernel_warn:n |
-% \err_kernel_fatal:n
-% }
-% \begin{syntax}
-% "\err_kernel_info:n" "{"<message>"}"
-% \end{syntax}
-% \end{function}
-% \begin{function}{%
-% \err_kernel_interrupt:Nw |
-% \err_kernel_interrupt_new:NNnnn |
-% }
-% Abbrivations for writing and accessing kernel error messages that
-% go to the error file "\c_kernel_err_tlp".
-% \end{function}
-%
-% \begin{function}{\err_latex_bug:x}
-% \begin{syntax}
-% "\err_latex_bug:x" "{"<error message>"}"
-% \end{syntax}
-% Creates an internal error message. This is intended to be used in
-% places that should not be reached in normal operation. Something is
-% wrong with the code.
-% \end{function}
-%
-% \subsection{Variables and constants}
-%
-% \begin{variable}{\c_iow_err_stream}
-% Output stream used to access the error files during their
-% generation.
-% \end{variable}
-%
-% \begin{variable}{\c_kernel_err_tlp}
-% Identifier denoting the kernel error file. (Its contents is the
-% name of the external file.)
-% \end{variable}
-%
-% \begin{variable}{\g_err_curr_fname}
-% Global variable containing the name of the currently open error
-% file. Empty when no such file is open for writing.
-% \end{variable}
-%
-% \begin{variable}{\tex_errorcontextlines:D}
-% Variable determining the amount of macro expansion contents shown
-% to the user when an error is triggered. \LaTeX3 sets this to -1
-% since to the average user this contents is of no interest.
-% \begin{texnote}
-% This is the \LaTeX3 name for the \TeX3 primitive
-% \tn{errorcontextlines}.
-% \end{texnote}
-% \end{variable}
-%
-% \begin{variable}{\g_err_help_toks}
-% Token register that holds the message that will be shown if the
-% user types "h" in response to an error message that was produced
-% by "\err_message:x".
-% \begin{texnote}
-% This is the \LaTeX3 name for the \TeX\ primitive \tn{errhelp}.
-% \end{texnote}
-% \end{variable}
-%
-% \begin{variable}{\l_err_label_token}
-% Variable holding the <label> to look up in an error file.
-% \end{variable}
-%
-% \StopEventually{}
-%
-% \subsection{The implementation}
-%
-% \begin{macrocode}
-%<package>\ProvidesExplPackage
-%<package> {\filename}{\filedate}{\fileversion}{\filedescription}
-%<package>\RequirePackage{l3basics}
-%<package>\RequirePackage{l3tlp}
-%<package>\RequirePackage{l3expan}
-%<package>\RequirePackage{l3num}
-%<package>\RequirePackage{l3io}
-%<package>\RequirePackage{l3int}
-%<package>\RequirePackage{l3toks}
-%<package>\RequirePackage{l3token}
-%<*initex|package>
-% \end{macrocode}
-%
-% \subsubsection{Code to be moved to other modules}
-%
-% \begin{macro}{\g_file_curr_name_tlp}
-% This variable is used to store the name of the file currently
-% being processed. It should be part of the code that defines the
-% higher level I/O commands.
-% \begin{macrocode}
-\tlp_new:Nn \g_file_curr_name_tlp {no~file}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\err_message:x}
-% The \LaTeX3 name for a \TeX\ primitive. This should perhaps move
-% to \texttt{l3names.dtx}.
-% \begin{macrocode}
-\let_new:NN \err_message:x \tex_errmessage:D
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\text_put_sp:}
-% \begin{macro}{\text_put_four_sp:}
-% We need these functions for certain error and warning messages
-% right away. They put one and four spaces into the message stream.
-% \begin{macrocode}
-\def_new:Npn \text_put_sp: {~}
-\def_new:Npn \text_put_four_sp: {\text_put_sp: \text_put_sp:
- \text_put_sp: \text_put_sp: }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\cmd_arg_list_build}
-% This macro takes a digit as its argument and creates a string of
-% |#| characters and argument numbers, such as |##1##2##3|. This
-% list can then later be used in defining a new macro.
-% To do this it locally uses a count register and a token
-% register.
-%
-% \begin{macrocode}
-\def:Npn\cmd_arg_list_build#1{
-% \end{macrocode}
-% First we need to make sure that the token register we will be
-% using for temporary storage is empty.
-% \begin{macrocode}
- \toks_clear:N\l_tmpb_toks
-% \end{macrocode}
-% Then we can store the argument in a count register that will be
-% decremented untill it's value is zero. Beacuse of the use of the
-% result of this macro, the argument needs to be between 1 and 9;
-% this could be tested, but such a test is not (yet) added.
-% \begin{macrocode}
- \int_set:Nn \l_tmpa_int {#1}
- \int_while:nNnT \l_tmpa_int > \c_zero {
-% \end{macrocode}
-% In the loop we first add the value of our counter to the contents
-% of the token register;
-% \begin{macrocode}
- \toks_put_left:No \l_tmpb_toks {\the_internal:D\l_tmpa_int}
-% \end{macrocode}
-% and precede it with two hash marks.
-% \begin{macrocode}
- \toks_put_left:Nn \l_tmpb_toks {##}
-% \end{macrocode}
-% Now the count register is decremented and another iteration will
-% follow so long as zero isn't reached.
-% \begin{macrocode}
- \int_decr:N\l_tmpa_int
- }
-% \end{macrocode}
-% Finally the contents of the token register needs to be copied as
-% the expansion of a local variable.
-% \begin{macrocode}
- \def:Npx\l_cmd_arg_list{\the_internal:D\l_tmpb_toks}
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\cmd_declare:Nnn}
-% This macro is a first replacement for \LaTeXe's |\newcommand|. It
-% takes the name of a new macro as its first argument, the number
-% of arguments for the new macro is taken as the second argument.
-% \begin{macrocode}
-\def:Npn\cmd_declare:Nnn#1[#2]{
- \cmd_arg_list_build{#2}
- \exp_args:NNO\def:Npn#1\l_cmd_arg_list
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\io_show_file_lineno:}
-% A function to add the number of the line and the name of the file
-% to a message as an indication of where the message was triggered.
-% \begin{macrocode}
-\def_new:Npn \io_show_file_lineno:{
- on~line~\the_internal:D\tex_inputlineno:D\text_put_sp:~of~
- file~\g_file_curr_name_tlp}
-% \end{macrocode}
-% \end{macro}
-%
-% \subsubsection{Variables and constants}
-%
-% \begin{macro}{\g_err_help_toks}
-% A token register to store the help text for an error message in.
-% \begin{macrocode}
-\let:NwN \g_err_help_toks \tex_errhelp:D
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\l_err_label_token}
-% This will hold the current error label.
-% \begin{macrocode}
-\def_new:Npn \l_err_label_token {}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\tex_errorcontextlines:D}
-% Since we are producing our own error and help messages we can
-% turn off the nasty stack information coming from \TeX{}'s
-% stomach.
-% \begin{macrocode}
-\int_set:Nn\tex_errorcontextlines:D\c_minus_one
-% \end{macrocode}
-% \end{macro}
-%
-% \subsubsection{Displaying the information}
-%
-% Here we define the fairly low level commands needed to
-% communicate with the user.
-%
-% \begin{macro}{\err_info:nn}
-% \begin{macro}{\err_warn:nn}
-% Write a message to the log file ("\err_info:nn") or to both the
-% log file and the terminal ("\err_warn:nn").
-% \begin{macrocode}
-\def_new:Npn \err_info:nn #1#2{
-% \end{macrocode}
-% Make sure that the \emph{continuation} is part of "\err_newline:".
-% \begin{macrocode}
- \def:Npn\err_newline:{\iow_newline:#2}
-% \end{macrocode}
-% Then write the message.
-% \begin{macrocode}
- \io_put_log:x {#1~\io_show_file_lineno:}}
-\def_new:Npn \err_warn:nn #1#2{
- \def:Npn\err_newline:{\iow_newline:#2}
- \io_put_term:x {#1~\io_show_file_lineno:}}
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\err_info_noline:nn}
-% \begin{macro}{\err_warn_noline:nn}
-% These variants of the above two functions don't add the
-% linenumber to the message.
-% \begin{macrocode}
-\def_new:Npn \err_info_noline:nn #1#2{
- \def:Npn\err_newline:{\iow_newline:#2}
- \io_put_log:x {#1}}
-\def_new:Npn \err_warn_noline:nn #1#2{
- \def:Npn\err_newline:{\iow_newline:#2}
- \io_put_term:x {#1}}
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\err_interrupt:NNw}
-% |\err_interrupt:NNw| is the function that is called when some error
-% occurs in the code. It takes at least two arguments, the
-% \m{errfile} which is a token list that holds the name of the file
-% where the error message should be fetched from, and the label to
-% identify the error message in the error file. However, it may
-% have additional arguments that are picked up by the error handler
-% extracted from the error file. This is specified in the third
-% argument to |\err_interrupt_new:NNNnnn|.
-% \begin{macrocode}
-\def_new:Npn \err_interrupt:NNw #1#2{\let:NwN \l_err_label_token #2
- \group_begin:
-% \end{macrocode}
-% For some reason we get some |\par|s into the file if we use the
-% current definition of |\iow_long_unxepanded:N| to write the messages.
-% This is probably a consequence of using token registers to
-% prohibit the expansion of code.
-% \begin{macrocode}
- \let:NwN \par\use_noop:
-% \end{macrocode}
-% We want to ensure that we are not in programmer's mode (no spaces)
-% but we want to switch on internal naming conventions.
-% \begin{macrocode}
- \CodeStop
- \NamesStart:
-% \end{macrocode}
-% We better clear all short references that are active, otherwise
-% we may get surprising results.
-% \begin{macrocode}
- %\clearshortrefmaps
- \tex_input:D #1~\err_display_aux:w}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\err_fatal:nn}
-% \begin{macro}{\err_fatal_noline:nn}
-% Write a message to the log file and to the terminal.
-% \begin{macrocode}
-\def_new:Npn \err_fatal:nn #1#2{
-% \end{macrocode}
-% Make sure that the \emph{continuation} is part of "\err_newline".
-% \begin{macrocode}
- \def:Npn\err_newline:{\iow_newline:#2}
-% \end{macrocode}
-% Then write the message.
-% \begin{macrocode}
- \io_put_term:x {#1~\io_show_file_lineno:}
-% \end{macrocode}
-% Finally abort the \LaTeX{} run.
-% \begin{macrocode}
- \tex_end:D
- }
-% \end{macrocode}
-% A variant that doesn't include the line number where the error
-% occured.
-% \begin{macrocode}
-\def_new:Npn \err_fatal_noline:nn #1#2{
- \def:Npn\err_newline:{\iow_newline:#2}
- \io_put_term:x {#1}
- \tex_end:D
- }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\err_newline:}
-% |\err_newline:| is used to introduce a new line in an error
-% message. I would like to use |\\| but this would mean
-% redefinition which should be avoided to make the error message
-% the last action before control is given to the user (otherwise
-% something like |\group_end:| would interfere with
-% insertions/deletions by the user). "\err_newline:" will be
-% redefined by the various functions displaying messages to include
-% the correct \emph{continuation}.
-% \begin{macrocode}
-\def_new:Npn \err_newline: {^^J}
-% \end{macrocode}
-% \end{macro}
-%
-% \subsubsection{Dealing with the error file}
-%
-% This section contains code that combines Michaels original thoughts
-% on the the subject with Denys' further ideas.
-%
-% \begin{macro}{\c_iow_err_stream}
-% Error messages are logged using the output stream
-% |\c_iow_err_stream|.
-% \begin{macrocode}
-\iow_new:N \c_iow_err_stream
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\g_err_curr_fname}
-% A nick name for the currently open error file. It is empty
-% if no error file is currently open.
-% \begin{macrocode}
-\tlp_new:Nn \g_err_curr_fname{}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\err_file_new:Nn}
-% This function defines a new error file. The first argument is a
-% token list which should hold the name of the error file, the second
-% argument is the name of the error file. The token list should be
-% a constant defined by this function.
-% \begin{macrocode}
-\def_new:Npn \err_file_new:Nn #1#2{
- \tlp_if_empty:NF\g_err_curr_fname
- {\err_latex_bug:x{Unclosed~error~file~`\g_err_curr_fname'}}
- \iow_open:Nn \c_iow_err_stream {#2}
- \err_kernel_info:n{Errorfile~`#2'~opened~for~output}
- \tlp_gset:Nn \g_err_curr_fname{#2}
- \tlp_new:Nn #1{#2}}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\err_file_close:N}
-% This function closes the current error file.
-% \begin{macrocode}
-\def_new:Npn \err_file_close:N#1{
-% \end{macrocode}
-% Before we close the stream, we write out a final error handler
-% that catches mismatch within error message labels and their
-% calls. Actually this should be integrated into
-% |\err_file_new:Nn|, too.
-% \begin{macrocode}
- \tlp_if_eq:NNF#1\g_err_curr_fname
- {\err_latex_bug:x{You~closed~the~wrong~error~file~`#1'.~
- Open~is~`\g_err_curr_fname'.}}
- \iow_long_unexpanded:Nn \c_iow_err_stream {\err_latex_bug:x{Didn't~find~the~
- correct~error~message~to~show.\iow_newline:
- Was~searching~for~a~function~
- with~the~following~meaning:\iow_newline:
- \token_to_string:N\token_to_meaning:N
- \token_to_string:N\l_err_label_token}
-% \end{macrocode}
-% The |\group_end:| here matches the one from |\err_interrupt:NNw| that
-% is used to hide changes to |\par| etc.
-% \begin{macrocode}
- \group_end:}
- \iow_close:N \c_iow_err_stream
- \err_kernel_info:n{Errorfile~`\g_err_curr_fname'~closed}
- \tlp_gset_eq:NN\g_err_curr_fname\c_empty_tlp
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \subsubsection{Declaring an error message in the error file}
-%
-% \begin{macro}{\err_interrupt_new:NNNnnn}
-% This function declares a new error message.
-% |\err_interrupt_new:NNNnnn| \m{errfile} \m{errlabel} \m{argno}
-% \m{errmsg} \m{helpmsg} \m{code}. That error message is fetched
-% from the error file \m{errfile}. The label to search for is
-% \m{errlabel}, the error handler has \m{argno} number of arguments
-% (actually \m{argno} + 3 since the \m{errmsg}, \m{helpmsg} and
-% \m{code} are also arguments), and \m{errmsg} is the message to
-% display, \m{helpmsg} is the message that is displayed when the
-% user enters |h|, while \m{code} is extra code to perform when the
-% error occurs. \m{code} is perhaps not necessary, we will see.
-%
-% We have to check that the label associated with the error message
-% is unique. This means that its replacement text (labels are
-% simply arbitrary functions) is different from the replacement
-% text of any other label in the same error set.
-% \begin{macrocode}
-\def_new:Npn \err_interrupt_new:NNNnnn #1{
-% \end{macrocode}
-% Both \m{errmsg} and \m{code} might contain hashmarks denoting
-% arguments to the error handler.
-% \begin{macrocode}
- \group_begin: \char_set_catcode:nn{`\#}{12}
-% \end{macrocode}
-% We also have to check that output goes to the correct error file.
-% \begin{macrocode}
- \if_meaning:NN#1\g_err_curr_fname
- \else:
- \err_latex_bug:x{Error~text~goes~to~wrong~err~file:~
- `\g_err_curr_fname'~is~open~but~you~requested~
- `#1'}
- \fi:
- \err_interrupt_new_aux:w}
-\def_long_new:Npn \err_interrupt_new_aux:w #1#2#3#4#5{
- \iow_long_unexpanded:Nn \c_iow_err_stream
- {\err_msgline_aux:NNnnn #1#2{#3}{#4}{#5}\use_noop:}
- \group_end:}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\err_msgline_aux:NNnnn}
-% This function is executed when an error file is read back by
-% |\err_interrupt:NNw|. It compares its first argument against
-% |\l_err_label_token| using |\if_meaning:NN| and if this fails the
-% function does nothing; otherwise it defines |\err_display_aux:w| in
-% a way that it will pick up the arguments (if any) from the code and
-% generates a suitable error message.
-% \begin{macrocode}
-\def_new:Npn \err_msgline_aux:NNnnn #1#2#3#4#5{
- \if_meaning:NN#1\l_err_label_token
-% \end{macrocode}
-% At the moment we simply use the old \LaTeX{} error code and
-% |\renewcommand| to generate the error handler. After displaying
-% the error message we insert error code this can be manipulated by
-% the user with the deletion/insertion facility of \TeX{}'s error
-% mechanism.
-%
-% The |\group_end:| at the very beginning matches the
-% |\group_begin:| when the file starts.
-% \begin{macrocode}
- \cmd_declare:Nnn\err_display_aux:w [#2]{
- \group_end:
- \toks_gset:Nx\g_err_help_toks{#4}
- \io_put_term:x{LaTeX~error~\io_show_file_lineno:.\iow_newline:
- \text_put_sp:\text_put_four_sp: \text_put_sp:
- See~LaTeX~manual~for~explanation.\iow_newline:
- \text_put_sp:\text_put_four_sp: \text_put_sp:
- Type~\text_put_sp: H~<return>~\text_put_sp: for~
- immediate~help.}
- \err_message:x{#3}
- #5}
- \tex_endinput:D
- \fi:}
-% \end{macrocode}
-% \end{macro}
-%
-%
-% \begin{macro}{\err_display_aux:w}
-% We should make sure that this function is definable.
-% \begin{macrocode}
-\def_new:Npn \err_display_aux:w {}
-% \end{macrocode}
-% \end{macro}
-%
-% \subsubsection{Kernel specific functions}
-%
-% \begin{macro}{\err_kernel_interrupt:Nw}
-% |\err_kernel_interrupt:Nw | is just the abbreviation to read from
-% the standard system error file.
-% \begin{macrocode}
-\def_new:Npn \err_kernel_interrupt:Nw {\err_interrupt:NNw \c_kernel_err_tlp}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\err_kernel_interrupt_new:NNnnn}
-% To ease the coding in case of system messages that should all go
-% to one and the same error file (if!) we also have the following
-% function.
-% \begin{macrocode}
-\def_new:Npn \err_kernel_interrupt_new:NNnnn {
- \err_interrupt_new:NNNnnn \c_kernel_err_tlp}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\err_kernel_info:n}
-% \begin{macro}{\err_kernel_warn:n}
-% \begin{macro}{\err_kernel_fatal:n}
-% \begin{macro}{\err_kernel_info_noline:n}
-% \begin{macro}{\err_kernel_warn_noline:n}
-% \begin{macro}{\err_kernel_fatal_noline:n}
-% These variants are specific for the \LaTeX\ kernel.
-% \begin{macrocode}
-\def_new:Npn \err_kernel_info:n #1 {
- \err_info:nn {LaTeX~Info:~#1}
- {\text_put_four_sp:\text_put_four_sp:\text_put_four_sp:}
- }
-\def_new:Npn \err_kernel_warn:n #1 {
- \err_warn:nn {LaTeX~Warning:~#1}
- {\text_put_sp:\text_put_sp:\text_put_sp:
- \text_put_four_sp:\text_put_four_sp:\text_put_four_sp:}
- }
-\def_new:Npn \err_kernel_fatal:n #1 {
- \err_fatal:nn {LaTeX~Fatal:~#1}
- {\text_put_sp:
- \text_put_four_sp:\text_put_four_sp:\text_put_four_sp:}
- }
-\def_new:Npn \err_kernel_info_noline:n #1 {
- \err_info_noline:nn {LaTeX~Info:~#1}
- {\text_put_four_sp:\text_put_four_sp:\text_put_four_sp:}
- }
-\def_new:Npn \err_kernel_warn_noline:n #1 {
- \err_warn_noline:nn {LaTeX~Warning:~#1}
- {\text_put_sp:\text_put_sp:\text_put_sp:
- \text_put_four_sp:\text_put_four_sp:\text_put_four_sp:}
- }
-\def_new:Npn \err_kernel_fatal_noline:n #1 {
- \err_fatal_noline:nn {LaTeX~Fatal:~#1}
- {\text_put_sp:
- \text_put_four_sp:\text_put_four_sp:\text_put_four_sp:}
- }
-%</initex|package>
-% \end{macrocode}
-% At a later stage variants may be provided for what in \LaTeXe{}
-% used to be called document classes and packages.
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\c_kernel_err_tlp}
-% Most error messages will go to the system error file; it's name is
-% stored in |\c_kernel_err_tlp|.
-% \begin{macrocode}
-%<initex>\err_file_new:Nn \c_kernel_err_tlp {ltxkernel.err}
-%<package>\err_file_new:Nn \c_kernel_err_tlp {l3in2e.err}
-% \end{macrocode}
-% \end{macro}
-%
-% The code below is a temporary implementation of a few of
-% \LaTeX209 error messages with the new syntax. They are only
-% included in the package as the \LaTeX3 kernel will certainly have
-% it's own error message definitions that differ from \LaTeXe's way
-% of signalling errors. These primarily serve as an example on how
-% to use this concept of dealing with errors.
-%
-% First we declare a couple of helper macros that contain texts
-% that are used frequently throughout \LaTeX.
-% \begin{macrocode}
-%<*package>
-\def:Npn\err_help_ignored: {
- Your~command~was~ignored.\iow_newline:
- Type \text_put_sp: I~<command>~<return>
- \text_put_sp: to~replace~it~with~another~command,\iow_newline:
- or~\text_put_sp: <return> \text_put_sp: to~continue~without~it.}
-
-\def:Npn\err_help_textlost: {
- You've~lost~some~text.\text_put_sp: \err_help_return_or_X:}
-
-\def:Npn\err_help_return_or_X: {
- Try~typing\text_put_sp: <return>
- \text_put_sp: to~proceed.\iow_newline:
- If~that~doesn't~work,~type
- \text_put_sp: X~<return>\text_put_sp: to~quit.}
-
-\def:Npn\err_help_trouble: {
- You're~ in~ trouble~ here.
- \text_put_sp:\err_help_return_or_X:}
-% \end{macrocode}
-%
-% Below are the definitions of the complete messages
-% \begin{macrocode}
-
-\err_kernel_interrupt_new:NNnnn\cs_free_p:N{1}
- {Command~name~`\tex_string:D#1'~already~used}
- {You~tried~to~define~a~command~which~already~has~
- a~meaning.\iow_newline:
- If~you~really~want~to~redefine~it~try~
- \token_to_string:N\cmd_declare:Nnn\text_put_sp:
- next~time.\iow_newline:
- For~this~run~I~will~ignore~your~definition.}
- {}
-
-\err_kernel_interrupt_new:NNnnn\newline{0}
- {There's~no~line~here~to~end}
- {You~tried~to~end~a~line~at~a~place~where~I~thought~
- we~were~already~between~paragraphs.}
- {}
-
-\err_kernel_interrupt_new:NNnnn\newcnt{0}
- {No~such~counter}
- {The~counter~name~mentioned~in~the~operation~is~not~
- known~to~me.\iow_newline:
- Check~the~spelling.}
- {}
-
-\err_kernel_interrupt_new:NNnnn\nodocument{0}
- {Missing~\token_to_string:N\begin{document}}
- {\err_help_trouble:}
- {}
-
-\err_kernel_interrupt_new:NNnnn\badmath{0}
- {Bad~math~environment~delimiter}
- {\err_help_ignored:}
- {}
-
-\err_kernel_interrupt_new:NNnnn\toodeep{0}
- {Too~deeply~nested}
- {\err_help_trouble:}
- {}
-
-\err_kernel_interrupt_new:NNnnn\badpoptabs{0}
- {\token_to_string:N\pushtabs \text_put_sp:
- and~\token_to_string:N\poptabs
- \text_put_sp: don't~match}
- {\err_help_trouble:}
- {}
-
-\err_kernel_interrupt_new:NNnnn\badtab{0}
- {Undefined~tab~position}
- {\err_help_trouble:}
- {}
-
-\err_kernel_interrupt_new:NNnnn\preamerr{}
- {\if_case:w #1~Illegal~character\or:
- Missing~@-exp\or: Missing~p-arg\fi:\text_put_sp:
- in~array~arg}
- {\err_help_trouble:}
- {}
-
-\err_kernel_interrupt_new:NNnnn\badlinearg{}
- {Bad~\token_to_string:N\line
- \text_put_sp: or~\token_to_string:N\vector
- \text_put_sp: argument}
- {\err_help_textlost:}
- {}
-
-\err_kernel_interrupt_new:NNnnn\parmoderr{0}
- {Not~in~outer~par~mode}
- {\err_help_textlost:}
- {}
-
-\err_kernel_interrupt_new:NNnnn\fltovf{0}
- {Too~many~unprocessed~floats}
- {\err_help_textlost:}
- {}
-
-\err_kernel_interrupt_new:NNnnn\badcrerr{0}
- {Bad~use~of~\token_to_string:N\\}
- {\err_help_return_or_X:}
- {}
-
-\err_kernel_interrupt_new:NNnnn\noitemerr{0}
- {Something's~wrong--perhaps~a~missing~
- \token_to_string:N\item}
- {\err_help_return_or_X:}
- {}
-
-\err_kernel_interrupt_new:NNnnn\notprerr{0}
- {Can~be~used~only~in~preamble}
- {\err_help_ignored:}
- {}
-
-\err_file_close:N\c_kernel_err_tlp
-%<package>
-% \end{macrocode}
-%
-%
-% Show token usage:
-% \begin{macrocode}
-%<*showmemory>
-\showMemUsage
-%</showmemory>
-% \end{macrocode}
-%
-% \endinput
-%
-% $Log$
-% Revision 1.9 2006/03/19 15:07:47 braams
-% Moved some code to other modules, where it belongs;
-% reverted \c_io_newline to \iow_newline (it'scontents might need to be
-% modified sometine)
-% Example messages are not part of the kernel, only for the package.
-%
-% Revision 1.8 2006/02/15 23:45:46 braams
-% Rearranged the file;
-% implemented \err_fatal:nn and \err_fatal_noline:nn
-% Recode the remaining error definitions for testing purposes
-%
-% Revision 1.7 2006/01/15 09:48:54 braams
-% Mostly textual changes
-%
-% Revision 1.6 2005/12/27 16:01:27 morten
-% Changed RCS information retrieval plus a few minor changes
-%
-% Revision 1.5 2005/05/05 23:45:49 braams
-% Worked on the documentation;
-% added commands \err_info:nn, \err_warn:nn and kernel specific versions
-% of these.
-% Changed \iow_newline: into \c_io_newline; introduced \err_newline: to
-% be used in messages with multiple lines to provide a continuation
-% string.
-% Renamed \style_names_start and \style_names_stop: into \NamesStart:
-% and \NamesStop:.
-%
-% Revision 1.4 2005/05/03 23:34:52 braams
-% Added code that performs the basic function of the old \renewcommand
-% Added a couple of new functions that need to live in other modules
-% Documentation still needs to be corrected
-% The module now basically works
-%
-% Revision 1.3 2005/04/29 22:39:47 braams
-% Another one
-%
-% Revision 1.2 2005/04/29 22:34:39 braams
-% Small typo in the RCS tags
-%
-% Revision 1.1 2005/04/29 22:30:44 braams
-% first version that can be loaded without producing errors.
-% Just a translation from the old stuff, haven't looked at the docu yet
diff --git a/Master/texmf-dist/source/latex/expl3/l3msg.dtx b/Master/texmf-dist/source/latex/expl3/l3msg.dtx
new file mode 100644
index 00000000000..4eb211be1a6
--- /dev/null
+++ b/Master/texmf-dist/source/latex/expl3/l3msg.dtx
@@ -0,0 +1,1336 @@
+% \iffalse
+%% File: l3msg.dtx Copyright (C) 2009 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 LaTeX Project Team.
+%%
+%% -----------------------------------------------------------------------
+%%
+%
+%<*driver|package>
+\RequirePackage{l3names}
+%</driver|package>
+%\fi
+\GetIdInfo$Id: l3msg.dtx 1362 2009-05-28 20:19:21Z joseph $
+ {L3 Experimental LaTeX Messages module}
+%\iffalse
+%<*driver>
+%\fi
+\ProvidesFile{\filename.\filenameext}
+ [\filedate\space v\fileversion\space\filedescription]
+%\iffalse
+\documentclass[full]{l3doc}
+\begin{document}
+\DocInput{l3msg.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{The \textsf{l3msg} package\thanks{This file
+% has version number \fileversion, last
+% revised \filedate.}\\
+% Communicating with the user}
+% \author{\Team}
+% \date{\filedate}
+% \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. Inside the
+% message text, spaces are \emph{not} ignored. A space where \TeX\
+% would normally gobble one can be created using |\ |, and a new line
+% with |\\|. New lines may have ``continuation'' text added by the
+% output system.
+%
+%\begin{function}{
+% \msg_new:nnnnn|
+% \msg_new:nnnn|
+% \msg_new:nnn|
+% \msg_set:nnnnn|
+% \msg_set:nnnn|
+% \msg_set:nnn
+%}
+% \begin{syntax}
+% "\msg_new:nnnn" <module> <name> <text> <more text> <code>
+% \end{syntax}
+% Creates new message <name> for <module> to produce <text> initially,
+% <more text> if requested by the user and to insert <code> after the
+% message when used as an error. <text> and <more text> can use up to
+% two macro parameters (|#1| and |#2|), which are supplied by the
+% message system. Inside <text> and <more text> spaces are not ignored.
+%\end{function}
+%
+% \section{Message classes}
+%
+% Creating message output requires the message to be given a class.
+%
+%\begin{function}{
+% \msg_class_new:nn|
+% \msg_class_set:nn
+%}
+% \begin{syntax}
+% "\msg_class_new:nn" <class> <code>
+% \end{syntax}
+% Creates new <class> to output a message, using <code> to process
+% the message text.
+%\end{function}
+%
+% The module defines several common message classes. The following
+% describes the standard behaviour of each class if no redirection of
+% the class or message is active.
+%
+%\begin{function}{
+% \msg_fatal:nnxx|
+% \msg_fatal:nnx|
+% \msg_fatal:nn
+%}
+% \begin{syntax}
+% "\msg_fatal:nnxx" <module> <name> <arg one> <arg two>
+% \end{syntax}
+% Issues <module> error message <name>, passing <arg one> and
+% <arg two> to the text-creating functions. The \TeX\ run then halts.
+%\end{function}
+%
+%\begin{function}{
+% \msg_error:nnxx|
+% \msg_error:nnx|
+% \msg_error:nn
+%}
+% \begin{syntax}
+% "\msg_error:nnxx" <module> <name> <arg one> <arg two>
+% \end{syntax}
+% Issues <module> error message <name>, passing <arg one> and
+% <arg two> to the text-creating functions.
+% \begin{texnote}
+% The standard output here is similar to \cs{PackageError}.
+% \end{texnote}
+%\end{function}
+%
+%\begin{function}{
+% \msg_warning:nnxx|
+% \msg_warning:nnx|
+% \msg_warning:nn
+%}
+% \begin{syntax}
+% "\msg_warning:nnxx" <module> <name> <arg one> <arg two>
+% \end{syntax}
+% Prints <module> message <name> to the terminal, passing <arg one> and
+% <arg two> to the text-creating functions.
+% \begin{texnote}
+% The standard output here is similar to \cs{PackageWarningNoLine}.
+% \end{texnote}
+%\end{function}
+%
+%\begin{function}{
+% \msg_info:nnxx|
+% \msg_info:nnx|
+% \msg_info:nn
+%}
+% \begin{syntax}
+% "\msg_info:nnxx" <module> <name> <arg one> <arg two>
+% \end{syntax}
+% Prints <module> message <name> to the log, passing <arg one> and
+% <arg two> to the text-creating functions.
+% \begin{texnote}
+% The standard output here is similar to \cs{PackageInfoNoLine}.
+% \end{texnote}
+%\end{function}
+%
+%\begin{function}{
+% \msg_log:nnxx|
+% \msg_log:nnx|
+% \msg_log:nn
+%}
+% \begin{syntax}
+% "\msg_info:nnxx" <module> <name> <arg one> <arg two>
+% \end{syntax}
+% Prints <module> message <name> to the log, passing <arg one> and
+% <arg two> to the text-creating functions. No continuation text is
+% added.
+%\end{function}
+%
+%\begin{function}{
+% \msg_trace:nnxx|
+% \msg_trace:nnx|
+% \msg_trace:nn
+%}
+% \begin{syntax}
+% "\msg_info:nnxx" <module> <name> <arg one> <arg two>
+% \end{syntax}
+% Prints <module> message <name> to the log, passing <arg one> and
+% <arg two> to the text-creating functions. No continuation text is
+% added.
+%\end{function}
+%
+%\begin{function}{
+% \msg_none:nnxx|
+% \msg_none:nnx|
+% \msg_none:nn
+%}
+% \begin{syntax}
+% "\msg_none:nnxx" <module> <name> <arg one> <arg two>
+% \end{syntax}
+% Does nothing: used for redirecting other message classes.
+%\end{function}
+%
+% \section{Redirecting messages}
+%
+%\begin{function}{\msg_redirect_class:nn}
+% \begin{syntax}
+% "\msg_redirect_class:nn" <class one> <class two>
+% \end{syntax}
+% Redirect all messages of <class one> to appear as those of
+% <class two>.
+%\end{function}
+%
+%\begin{function}{\msg_redirect_module:nnn}
+% \begin{syntax}
+% "\msg_redirect_module:nnn" <class one> <module> <class two>
+% \end{syntax}
+% Redirect <module> messages of <class one> to appear in <class two>.
+% \begin{texnote}
+% This function can be used to make some messages ``silent'' by
+% default. For example, all of the \texttt{trace} messages of
+% <module> could be turned off with:
+% \begin{verbatim}
+% \msg_redirect_module:nnn { trace } { module } { none }
+% \end{verbatim}
+% \end{texnote}
+%\end{function}
+%
+%\begin{function}{\msg_redirect_name:nnn}
+% \begin{syntax}
+% "\msg_redirect_name:nnn" <module> <message> <class>
+% \end{syntax}
+% Redirect <module> <message> to appear using <class>.
+%\end{function}
+%
+% \section{Support functions for output}
+%
+%\begin{function}{\msg_line_context:}
+% \begin{syntax}
+% "\msg_line_context:"
+% \end{syntax}
+% Prints the current line number preceded by \cs{c_msg_on_line_tl}.
+%\end{function}
+%
+%\begin{function}{\msg_line_number:}
+% \begin{syntax}
+% "\msg_line_number:"
+% \end{syntax}
+% Prints the current line number.
+%\end{function}
+%
+%\begin{function}{
+% \msg_newline:|
+% \msg_two_newlines:
+%}
+% \begin{syntax}
+% "\msg_newline:"
+% \end{syntax}
+% Print one or two newlines with no continuation information.
+%\end{function}
+%
+%\begin{function}{
+% \msg_space:|
+% \msg_two_spaces:|
+% \msg_four_spaces:
+%}
+% \begin{syntax}
+% "\msg_space:"
+% \end{syntax}
+% Print one, two or four spaces: needed where a literal space would
+% otherwise be gobbled by \TeX.
+%\end{function}
+%
+% \section{Low-level functions}
+%
+% The low-level functions do not make assumptions about module names.
+% The output functions here produce messages directly, and do not
+% respond to redirection.
+%
+%\begin{function}{
+% \msg_generic_new:nnnn|
+% \msg_generic_new:nnn|
+% \msg_generic_new:nn|
+% \msg_generic_set:nnnn|
+% \msg_generic_set:nnn|
+% \msg_generic_set:nn
+%}
+% \begin{syntax}
+% "\msg_generic_new:nnnn" <name> <text> <more text> <code>
+% \end{syntax}
+% Creates new message <name> to produce <text> initially, <more text>
+% if requested by the user and to insert <code> after the message when
+% used as an error. <text> and <more text> can use up to two macro
+% parameters (|#1| and |#2|), which are supplied by the message system.
+% Inside <text> and <more text> spaces are not ignored.
+%\end{function}
+%
+%\begin{function}{\msg_direct_interrupt:xxxxn}
+% \begin{syntax}
+% "\msg_direct_interrupt:xxxxn" <first line> <text>
+% ~~~~<continuation> <more text> <code>
+% \end{syntax}
+% Executes a \TeX\ error, interrupting compilation. The <first line>
+% is displayed followed by <text> and the input prompt. <more text> is
+% displays if requested by the user, and <code> is inserted after the
+% message. If <more text> is blank a default is supplied. Each line of
+% <text> (broken with |\\|) begins with <continuation>.
+%\end{function}
+%
+%\begin{function}{
+% \msg_direct_log:xx|
+% \msg_direct_term:xx
+%}
+% \begin{syntax}
+% "\msg_direct_log:xx" <text> <continuation>
+% \end{syntax}
+% Prints <text> to either the log or terminal. New lines (broken
+% with |\\|) start with <continuation>.
+%\end{function}
+%
+% \section{Kernel-specific functions}
+%
+%\begin{function}{
+% \msg_kernel_new:nnnn|
+% \msg_kernel_new:nnn|
+% \msg_kernel_new:nn|
+% \msg_kernel_set:nnnn|
+% \msg_kernel_set:nnn|
+% \msg_kernel_set:nn
+%}
+% \begin{syntax}
+% "\msg_kernel_new:nnn" <name> <text> <more text> <code>
+% \end{syntax}
+% Creates new kernel message <name> to produce <text> initially,
+% <more text> if requested by the user and to insert <code> after the
+% message when used as an error. <text> and <more text> can use up to
+% two macro parameters (|#1| and |#2|), which are supplied by the
+% message system.
+%\end{function}
+%
+%\begin{function}{
+% \msg_kernel_fatal:nxx|
+% \msg_kernel_fatal:nx|
+% \msg_kernel_fatal:n
+%}
+% \begin{syntax}
+% "\msg_kernel_fatal:nxx" <name> <arg one> <arg two>
+% \end{syntax}
+% Issues kernel error message <name>, passing <arg one> and
+% <arg two> to the text-creating functions. The \TeX\ run then halts.
+% Cannot be redirected.
+%\end{function}
+%
+%\begin{function}{
+% \msg_kernel_error:nxx|
+% \msg_kernel_error:nx|
+% \msg_kernel_error:n
+%}
+% \begin{syntax}
+% "\msg_kernel_error:nxx" <name> <arg one> <arg two>
+% \end{syntax}
+% Issues kernel error message <name>, passing <arg one> and
+% <arg two> to the text-creating functions. Cannot be redirected.
+%\end{function}
+%
+%\begin{function}{
+% \msg_kernel_warning:nxx|
+% \msg_kernel_warning:nx|
+% \msg_kernel_warning:n
+%}
+% \begin{syntax}
+% "\msg_kernel_warning:nxx" <name> <arg one> <arg two>
+% \end{syntax}
+% Prints kernel message <name> to the terminal, passing <arg one> and
+% <arg two> to the text-creating functions.
+%\end{function}
+%
+%\begin{function}{
+% \msg_kernel_info:nxx|
+% \msg_kernel_info:nx|
+% \msg_kernel_info:n
+%}
+% \begin{syntax}
+% "\msg_kernel_info:nxx" <name> <arg one> <arg two>
+% \end{syntax}
+% Prints kernel message <name> to the log, passing <arg one> and
+% <arg two> to the text-creating functions.
+%\end{function}
+%
+%\begin{function}{\msg_kernel_bug:x}
+% \begin{syntax}
+% "\msg_kernel_bug:x" <text>
+% \end{syntax}
+% Short-cut for ``This is a LaTeX bug: check coding'' errors.
+%\end{function}
+%
+% \section{Variables and constants}
+%
+%\begin{variable}{
+% \c_msg_fatal_tl|
+% \c_msg_error_tl|
+% \c_msg_warning_tl|
+% \c_msg_info_tl
+%}
+% Simple headers for errors.
+%\end{variable}
+%
+%\begin{variable}{
+% \c_msg_fatal_text_tl|
+% \c_msg_help_text_tl|
+% \c_msg_kernel_bug_text_tl|
+% \c_msg_kernel_bug_more_text_tl|
+% \c_msg_no_info_text_tl|
+% \c_msg_return_text_tl
+%}
+% Various pieces of text for use in messages, which are not changed by
+% the code here although they could be to alter the language.
+%\end{variable}
+%
+%\begin{variable}{\c_msg_on_line_tl}
+% The ``on line'' phrase for line numbers.
+%\end{variable}
+%
+%\begin{variable}{
+% \c_msg_text_prefix_tl|
+% \c_msg_more_text_prefix_tl|
+% \c_msg_code_prefix_tl
+%}
+% Header information for storing the ``paths'' to parts of a message.
+%\end{variable}
+%
+%\begin{variable}{
+% \l_msg_class_tl|
+% \l_msg_current_class_tl
+%}
+% Information about message method, used for filtering.
+%\end{variable}
+%
+%\begin{variable}{\l_msg_names_clist}
+% List of all of the message names defined.
+%\end{variable}
+%
+%\begin{variable}{
+% \l_msg_redirect_classes_prop|
+% \l_msg_redirect_names_prop
+%}
+% Re-direction lists containing the class of message to convert an
+% different one.
+%\end{variable}
+%
+%\begin{variable}{\l_msg_redirect_classes_clist}
+% List so that filtering does not loop.
+%\end{variable}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3msg} implementation}
+%
+% The usual lead-off.
+% \begin{macrocode}
+%<*package>
+\ProvidesExplPackage
+ {\filename}{\filedate}{\fileversion}{\filedescription}
+\package_check_loaded_expl:
+%</package>
+%<*initex|package>
+% \end{macrocode}
+%
+% \LaTeX\ is handling context, so the \TeX\ ``noise'' is turned down.
+% \begin{macrocode}
+\int_set:Nn \tex_errorcontextlines:D { \c_minus_one }
+% \end{macrocode}
+%
+% \subsection{Variables and constants}
+%
+%\begin{macro}{\c_msg_fatal_tl}
+%\begin{macro}{\c_msg_error_tl}
+%\begin{macro}{\c_msg_warning_tl}
+%\begin{macro}{\c_msg_info_tl}
+% Header information.
+% \begin{macrocode}
+\tl_new:Nn \c_msg_fatal_tl { Fatal~Error }
+\tl_new:Nn \c_msg_error_tl { Error }
+\tl_new:Nn \c_msg_warning_tl { Warning }
+\tl_new:Nn \c_msg_info_tl { Info }
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%
+%\begin{macro}{\c_msg_fatal_text_tl}
+%\begin{macro}{\c_msg_help_text_tl}
+%\begin{macro}{\c_msg_kernel_bug_text_tl}
+%\begin{macro}{\c_msg_kernel_bug_more_text_tl}
+%\begin{macro}{\c_msg_no_info_text_tl}
+%\begin{macro}{\c_msg_return_text_tl}
+% Simple pieces of text for messages.
+% \begin{macrocode}
+\tl_new:Nn \c_msg_fatal_text_tl {
+ This~is~a~fatal~error:~LaTeX~will~abort
+}
+\tl_new:Nn \c_msg_help_text_tl {
+ For~immediate~help~type~H~<return>
+}
+\tl_new:Nn \c_msg_kernel_bug_text_tl {
+ This~is~a~LaTeX~bug:~check~coding!
+}
+\tl_new:Nn \c_msg_kernel_bug_more_text_tl {
+ There~is~a~coding~bug~somewhere~around~here.
+ \msg_newline:
+ This~probably~needs~examining~by~an~expert.
+ \c_msg_return_text_tl
+}
+\tl_new:Nn \c_msg_no_info_text_tl {
+ LaTeX~does~not~know~anything~more~about~this~error,~sorry.
+ \c_msg_return_text_tl
+}
+\tl_new:Nn \c_msg_return_text_tl {
+ \msg_two_newlines:
+ Try~typing~<return>~to~proceed.
+ \msg_newline:
+ If~that~doesn't~work,~type~X~<return>~to~quit
+}
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%
+%\begin{macro}[aux]{\c_msg_hide_tl<spaces>}
+% An empty variable with a number of (category code 11) spaces at the
+% end of its name. This is used to push the \TeX\ part of an error
+% message ``off the screen''.
+%
+% No indentation here as \verb*| | is a letter!
+% \begin{macrocode}
+\group_begin:
+\char_make_letter:N\ %
+\tl_to_lowercase:n{%
+\group_end:%
+\tl_new:Nn%
+\c_msg_hide_tl %
+{}%
+}%
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\c_msg_on_line_tl}
+% ``On line''.
+% \begin{macrocode}
+\tl_new:Nn \c_msg_on_line_tl { on~line }
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\c_msg_text_prefix_tl}
+%\begin{macro}{\c_msg_more_text_prefix_tl}
+%\begin{macro}{\c_msg_code_prefix_tl}
+% Prefixes for storage areas.
+% \begin{macrocode}
+\tl_new:Nn \c_msg_text_prefix_tl { msg_text // }
+\tl_new:Nn \c_msg_more_text_prefix_tl { msg_text_more // }
+\tl_new:Nn \c_msg_code_prefix_tl { msg_code // }
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%
+%\begin{macro}{\l_msg_class_tl}
+%\begin{macro}{\l_msg_current_class_tl}
+% For holding the current message method and that for redirection.
+% \begin{macrocode}
+\tl_new:N \l_msg_class_tl
+\tl_new:N \l_msg_current_class_tl
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%
+%\begin{macro}{\l_msg_names_clist}
+% Lists used for filtering.
+% \begin{macrocode}
+\clist_new:N \l_msg_names_clist
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\l_msg_redirect_classes_prop}
+%\begin{macro}{\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{macro}
+%\end{macro}
+%\begin{macro}{\l_msg_redirect_classes_clist}
+% To prevent an infinite loop.
+% \begin{macrocode}
+\clist_new:N \l_msg_redirect_classes_clist
+% \end{macrocode}
+%\end{macro}
+%
+% \subsection{Output helper functions}
+%
+%\begin{macro}{\msg_line_number:}
+%\begin{macro}{\msg_line_context:}
+% For writing the line number nicely.
+% \begin{macrocode}
+\cs_new_nopar:Nn { \msg_line_number: } {
+ \toks_use:N \tex_inputlineno:D
+}
+\cs_new_nopar:Nn { \msg_line_context: } {
+ \msg_space:
+ \c_msg_on_line_tl
+ \msg_space:
+ \msg_line_number:
+}
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%
+%\begin{macro}{\msg_newline:}
+%\begin{macro}{\msg_two_newlines:}
+% Always forces a new line.
+% \begin{macrocode}
+\cs_new_nopar:Nn \msg_newline: { ^^J }
+\cs_new_nopar:Nn \msg_two_newlines: { ^^J ^^J }
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%
+%\begin{macro}{\msg_space:}
+%\begin{macro}{\msg_two_spaces:}
+%\begin{macro}{\msg_four_spaces:}
+% For printing spaces, some very simple functions.
+% \begin{macrocode}
+\cs_new_nopar:Nn \msg_space: { ~ }
+\cs_new_nopar:Nn \msg_two_spaces: { \msg_space: \msg_space: }
+\cs_new_nopar:Nn \msg_four_spaces: { \msg_two_spaces: \msg_two_spaces: }
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%
+%\subsection{Generic functions}
+%
+% The lowest level functions make no assumptions about modules,
+% \emph{etc.}
+%
+%\begin{macro}{\msg_generic_new:nnnn}
+%\begin{macro}{\msg_generic_new:nnn}
+%\begin{macro}{\msg_generic_new:nn}
+% Creating a new message is basically the same as the non-checking
+% version, and so after a check everything hands over.
+% \begin{macrocode}
+\cs_new_nopar:Npn \msg_generic_new:nnnn #1 {
+ \exp_args:Nc \chk_if_free_cs:N { \c_msg_text_prefix_tl #1 :nn }
+ \msg_generic_set:nnnn {#1}
+}
+\cs_new_nopar:Npn \msg_generic_new:nnn #1 {
+ \exp_args:Nc \chk_if_free_cs:N { \c_msg_text_prefix_tl #1 :nn }
+ \msg_generic_set:nnn {#1}
+}
+\cs_new_nopar:Npn \msg_generic_new:nn #1 {
+ \exp_args:Nc \chk_if_free_cs:N { \c_msg_text_prefix_tl #1 :nn }
+ \msg_generic_set:nn {#1}
+}
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%
+%\begin{macro}{\msg_generic_set:nnnn}
+%\begin{macro}{\msg_generic_set:nnn}
+%\begin{macro}{\msg_generic_set:nn}
+%\begin{macro}[aux]{\msg_generic_set_clist:n}
+%\begin{macro}[aux]{\msg_generic_set_text:n}
+%\begin{macro}[aux]{\msg_generic_set_more_text:n}
+%\begin{macro}[aux]{\msg_generic_set_code:n}
+% Creating a message is quite simple. There must be a short text part,
+% while the other parts may not exist. To avoid filling up the hash
+% table with empty functions,only non-empty arguments are stored.
+% The various auxiliary functions are used to allow spaces in the
+% text arguments.
+% \begin{macrocode}
+\cs_new_nopar:Npn \msg_generic_set:nnnn #1 {
+ \msg_generic_set_clist:n {#1}
+ \char_make_space:N \ %
+ \msg_generic_set_code:nnnn{#1}%
+}
+\cs_new_nopar:Npn \msg_generic_set:nnn #1 {
+ \msg_generic_set_clist:n {#1}
+ \char_make_space:N \ %
+ \msg_generic_set_more_text:nnn{#1}%
+}
+\cs_new_nopar:Npn \msg_generic_set:nn #1 {
+ \msg_generic_set_clist:n {#1}
+ \char_make_space:N \ %
+ \msg_generic_set_text:nn{#1}%
+}
+\cs_new_nopar:Npn \msg_generic_set_clist:n #1 {
+ \clist_if_in:NnF \l_msg_names_clist { // #1 / } {
+ \clist_put_right:Nn \l_msg_names_clist { // #1 / }
+ }
+}
+\cs_new:Nn \msg_generic_set_text:nn {
+ \cs_set:cn { \c_msg_text_prefix_tl #1 :nn } {#2}
+ \char_make_ignore:N \
+}
+\cs_new:Nn \msg_generic_set_more_text:nnn {
+ \cs_set:cn { \c_msg_text_prefix_tl #1 :nn } {#2}
+ \tl_if_empty:nTF {#3} {
+ \cs_set_eq:cN { \c_msg_more_text_prefix_tl #1 } \c_undefined
+ }{
+ \cs_set:cn { \c_msg_more_text_prefix_tl #1 :nn } {#3}
+ }
+ \char_make_ignore:N \
+}
+\cs_new:Npn \msg_generic_set_code:nnnn #1#2#3 {
+ \cs_set:cn { \c_msg_text_prefix_tl #1 :nn } {#2}
+ \tl_if_empty:nTF {#3} {
+ \cs_set_eq:cN { \c_msg_more_text_prefix_tl #1 } \c_undefined
+ }{
+ \cs_set:cn { \c_msg_more_text_prefix_tl #1 :nn } {#3}
+ }
+ \char_make_ignore:N \
+ \msg_generic_set_code:nn {#1}
+}
+\cs_new:Nn \msg_generic_set_code:nn {
+ \tl_if_empty:nTF {#2} {
+ \cs_set_eq:cN { \c_msg_code_prefix_tl #1 : } \c_undefined
+ }{
+ \cs_set:cn { \c_msg_code_prefix_tl #1 : } {#2}
+ }
+}
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%
+%\begin{macro}{\msg_direct_interrupt:xxxxn}
+%\begin{macro}[aux]{\msg_direct_interrupt:n}
+% 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 spaces. To achieve this,
+% spaces have to be letters: hence no indentation. The odd
+% \cs{c_msg_hide_tl} actually does the hiding: it is the large run of
+% spaces 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}
+\group_begin:
+ \char_set_lccode:nn {`\&} {`\ } % {
+ \char_set_lccode:w `\} = `\ \scan_stop:
+ \char_make_active:N \&
+ \char_make_letter:N\ %
+\tl_to_lowercase:n{%
+\group_end:%
+\cs_new_protected:Nn\msg_direct_interrupt:xxxxn{%
+\group_begin:%
+\cs_set_eq:NN\\\msg_newline:%
+\cs_set_eq:NN\ \msg_space:%
+\msg_direct_interrupt_aux:n{#4}%
+\cs_set_nopar:Npn\\{\msg_newline:#3}%
+\tex_errhelp:D\l_msg_tmp_tl%
+\cs_set:Npn&{%
+\tex_errmessage:D{%
+#1\msg_newline:%
+#2\msg_two_newlines:%
+\c_msg_help_text_tl%
+\c_msg_hide_tl %
+}%
+}%
+&%
+\group_end:%
+#5%
+}%
+}%
+\cs_new:Nn \msg_direct_interrupt_aux:n {
+ \tl_if_empty:nTF {#1} {
+ \tl_set:Nx \l_msg_tmp_tl { { \c_msg_no_info_text_tl } }
+ }{
+ \tl_set:Nx \l_msg_tmp_tl { {#1 } }
+ }
+}
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%
+%\begin{macro}{\msg_direct_log:xx}
+%\begin{macro}{\msg_direct_term:xx}
+% Printing to the log or terminal without a stop is rather easier.
+% \begin{macrocode}
+\cs_new_protected:Nn \msg_direct_log:xx {
+ \group_begin:
+ \cs_set:Npn \\ { \msg_newline: #2 }
+ \cs_set_eq:NN \ \msg_space:
+ \iow_log:x { #1 \msg_newline: }
+ \group_end:
+}
+\cs_new_protected:Nn \msg_direct_term:xx {
+ \group_begin:
+ \cs_set:Npn \\ { \msg_newline: #2 }
+ \cs_set_eq:NN \ \msg_space:
+ \iow_term:x { #1 \msg_newline: }
+ \group_end:
+}
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%
+%\subsection{General functions}
+%
+% The main functions for messaging are built around the separation of
+% module from the message name. These have short names as they will be
+% widely used.
+%
+%\begin{macro}{\msg_new:nnnnn}
+%\begin{macro}{\msg_new:nnnn}
+%\begin{macro}{\msg_new:nnn}
+%\begin{macro}{\msg_set:nnnnn}
+%\begin{macro}{\msg_set:nnnn}
+%\begin{macro}{\msg_set:nnn}
+% For making messages.
+% \begin{macrocode}
+\cs_new_nopar:Npn \msg_new:nnnnn #1#2 {
+ \msg_generic_new:nnnn { #1 / #2 }
+}
+\cs_new_nopar:Npn \msg_new:nnnn #1#2 {
+ \msg_generic_new:nnn { #1 / #2 }
+}
+\cs_new_nopar:Npn \msg_new:nnn #1#2 {
+ \msg_generic_new:nn { #1 / #2 }
+}
+\cs_new_nopar:Npn \msg_set:nnnnn #1#2 {
+ \msg_generic_set:nnnn { #1 / #2 }
+}
+\cs_new_nopar:Npn \msg_set:nnnn #1#2 {
+ \msg_generic_set:nnn { #1 / #2 }
+}
+\cs_new_nopar:Npn \msg_set:nnn #1#2 {
+ \msg_generic_set:nn { #1 / #2 }
+}
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%
+%\begin{macro}{\msg_class_new:nn}
+%\begin{macro}{\msg_class_set:nn}
+% Creating a new class produces three new functions, with varying
+% numbers of arguments. The \cs{msg_class_loop:n} function is set up
+% so that redirection will work as desired.
+% \begin{macrocode}
+\cs_new_nopar:Npn \msg_class_new:nn #1 {
+ \exp_args:Nc \chk_if_free_cs:N { msg_ #1 :nnxx }
+ \prop_new:c { l_msg_redirect_ #1 _prop }
+ \msg_class_set:nn {#1}
+}
+\cs_new_nopar:Nn \msg_class_set:nn {
+ \prop_clear:c { l_msg_redirect_ #1 _prop }
+ \cs_set_protected:cn { msg_ #1 :nnxx } {
+ \msg_use:nnnnxx {#1} {#2} {##1} {##2} {##3} {##4}
+ }
+ \cs_set_protected:cn { msg_ #1 :nnx } {
+ \use:c { msg_ #1 :nnxx } {##1} {##2} {##3} { }
+ }
+ \cs_set_protected:cn { msg_ #1 :nn } {
+ \use:c { msg_ #1 :nnxx } {##1} {##2} { } { }
+ }
+}
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%
+%\begin{macro}[aux]{\msg_use:nnnnxx}
+% 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:Nn \msg_use:nnnnxx {
+ \cs_set:Nn \msg_use_code: {
+ \clist_clear:N \l_msg_redirect_classes_clist
+ #2
+ }
+ \cs_set:Nn \msg_use_loop:n {
+ \clist_if_in:NnTF \l_msg_redirect_classes_clist {#1} {
+ \msg_kernel_error:n { message~loop }
+ }{
+ \clist_put_right:Nn \l_msg_redirect_classes_clist {#1}
+ \cs_if_exist:cTF { msg_ ##1 :nnxx } {
+ \use:c { msg_ ##1 :nnxx } {#3} {#4} {#5} {#6}
+ }{
+ \msg_kernel_error:nx { message~class~unknown } { ##1 }
+ }
+ }
+ }
+ \cs_if_exist:cTF { \c_msg_text_prefix_tl #3 / #4 :nn } {
+ \msg_use_aux:nnn {#1} {#3} {#4}
+ }{
+ \msg_kernel_error:nxx { message~unknown } { #3 } { #4 }
+ }
+}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}[aux]{\msg_use_code:}
+%\begin{macro}[aux]{\msg_use_loop:}
+% Blank definitions are initially created for these functions.
+% \begin{macrocode}
+\cs_new_nopar:Nn \msg_use_code: { }
+\cs_new_nopar:Nn \msg_use_loop:n { }
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%
+%\begin{macro}[aux]{\msg_use_aux:nnn}
+% The first auxiliary macro looks for a match by name: the most
+% restrictive check.
+% \begin{macrocode}
+\cs_new_nopar:Nn \msg_use_aux:nnn {
+ \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}
+%\end{macro}
+%\begin{macro}[aux]{\msg_use_aux:nn}
+% The second function checks for general matches by module or for
+% all modules.
+% \begin{macrocode}
+\cs_new_nopar:Nn \msg_use_aux:nn {
+ \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}
+%\end{macro}
+%\begin{macro}[aux]{\msg_use_loop_check:nn}
+% When checking whether to loop, the same code is needed in a few
+% places.
+% \begin{macrocode}
+\cs_new:Nn \msg_use_loop_check:nn {
+ \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:n { \l_msg_class_tl }
+ }
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\msg_fatal:nnxx}
+%\begin{macro}{\msg_fatal:nnx}
+%\begin{macro}{\msg_fatal:nn}
+% For fatal errors, after the error message \TeX\ bails out.
+% \begin{macrocode}
+\msg_class_new:nn { fatal } {
+ \msg_direct_interrupt:xxxxn
+ { \c_msg_fatal_tl \msg_two_newlines: }
+ {
+ ( \c_msg_fatal_tl ) \msg_space:
+ \use:c { \c_msg_text_prefix_tl #1 / #2 :nn } {#3} {#4}
+ }
+ { ( \c_msg_fatal_tl ) \msg_space: }
+ { \c_msg_fatal_text_tl }
+ { \tex_end:D }
+}
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%
+%\begin{macro}{\msg_error:nnxx}
+%\begin{macro}{\msg_error:nnx}
+%\begin{macro}{\msg_error:nn}
+% For an error, the interrupt routine is called, then any recovery code
+% is tried.
+% \begin{macrocode}
+\msg_class_new:nn { error } {
+ \msg_direct_interrupt:xxxxn
+ { #1~\c_msg_error_tl \msg_newline: }
+ {
+ ( #1 ) \msg_space:
+ \use:c { \c_msg_text_prefix_tl #1 / #2 :nn } {#3} {#4}
+ }
+ { ( #1 ) \msg_space: }
+ {
+ \cs_if_exist:cTF { \c_msg_more_text_prefix_tl #1 / #2 :nn } {
+ \use:c { \c_msg_more_text_prefix_tl #1 / #2 :nn } {#3} {#4}
+ }{
+ \c_msg_no_info_text_tl
+ }
+ }
+ {
+ \cs_if_exist:cT { \c_msg_code_prefix_tl #1 /#2 :nn } {
+ \use:c { \c_msg_code_prefix_tl #1 / #2 :nn} {#3} {#4}
+ }
+ }
+}
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%
+%\begin{macro}{\msg_warning:nnxx}
+%\begin{macro}{\msg_warning:nnx}
+%\begin{macro}{\msg_warning:nn}
+% Warnings are printed to the terminal.
+% \begin{macrocode}
+\msg_class_new:nn { warning } {
+ \msg_direct_term:xx {
+ \msg_space: #1~\c_msg_warning_tl :~
+ \use:c { \c_msg_text_prefix_tl #1 / #2 :nn } {#3} {#4}
+ }
+ { ( #1 ) \msg_two_spaces: }
+}
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%
+%\begin{macro}{\msg_info:nnxx}
+%\begin{macro}{\msg_info:nnx}
+%\begin{macro}{\msg_info:nn}
+% Information only goes into the log.
+% \begin{macrocode}
+\msg_class_new:nn { info } {
+ \msg_direct_log:xx {
+ \msg_space: #1~\c_msg_info_tl :~
+ \use:c { \c_msg_text_prefix_tl #1 / #2 :nn } {#3} {#4}
+ }
+ { ( #1 ) \msg_two_spaces: }
+}
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%
+%\begin{macro}{\msg_log:nnxx}
+%\begin{macro}{\msg_log:nnx}
+%\begin{macro}{\msg_log:nn}
+% ``Log'' data is very similar to information, but with no extras
+% added.
+% \begin{macrocode}
+\msg_class_new:nn { log } {
+ \msg_direct_log:xx {
+ \use:c { \c_msg_text_prefix_tl #1 / #2 :nn } {#3} {#4}
+ }
+ { }
+}
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%
+%\begin{macro}{\msg_trace:nnxx}
+%\begin{macro}{\msg_trace:nnx}
+%\begin{macro}{\msg_trace:nn}
+% Trace data is the same as log data, more or less
+% \begin{macrocode}
+\msg_class_new:nn { trace } {
+ \msg_direct_log:xx {
+ \use:c { \c_msg_text_prefix_tl #1 / #2 :nn } {#3} {#4}
+ }
+ { }
+}
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%
+%\begin{macro}{\msg_none:nnxx}
+%\begin{macro}{\msg_none:nnx}
+%\begin{macro}{\msg_none:nn}
+% The \texttt{none} message type is needed so that input can be gobbled.
+% \begin{macrocode}
+\msg_class_new:nn { none } { }
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%
+%\subsection{Redirection functions}
+%
+%\begin{macro}{\msg_redirect_class:nn}
+% Converts class one into class two.
+% \begin{macrocode}
+\cs_new_nopar:Nn \msg_redirect_class:nn {
+ \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_nopar:Nn \msg_redirect_module:nnn {
+ \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_nopar:Nn \msg_redirect_name:nnn {
+ \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_new:nn}
+%\begin{macro}{\msg_kernel_set:nnnn}
+%\begin{macro}{\msg_kernel_set:nnn}
+%\begin{macro}{\msg_kernel_set:nn}
+% 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_nopar:Npn \msg_kernel_new:nnnn #1 {
+ \msg_new:nnnnn { LaTeX } {#1}
+}
+\cs_new_nopar:Npn \msg_kernel_new:nnn #1 {
+ \msg_new:nnnn { LaTeX } {#1}
+}
+\cs_new_nopar:Npn \msg_kernel_new:nn #1 {
+ \msg_new:nnn { LaTeX } {#1}
+}
+\cs_new_nopar:Npn \msg_kernel_set:nnnn #1 {
+ \msg_set:nnnnn { LaTeX } {#1}
+}
+\cs_new_nopar:Npn \msg_kernel_set:nnn #1 {
+ \msg_set:nnnn { LaTeX } {#1}
+}
+\cs_new_nopar:Npn \msg_kernel_set:nn #1 {
+ \msg_set:nnn { LaTeX } {#1}
+}
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%
+%\begin{macro}[aux]{\msg_kernel_classes_new:n}
+% Quickly make the fewer-arguments versions.
+% \begin{macrocode}
+\cs_new_nopar:Nn \msg_kernel_classes_new:n {
+ \cs_new_protected:cn { msg_kernel_ #1 :nx } {
+ \use:c { msg_kernel_ #1 :nxx } {##1} {##2} { }
+ }
+ \cs_new_protected:cn { msg_kernel_ #1 :n } {
+ \use:c { msg_kernel_ #1 :nxx } {##1} { } { }
+ }
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\msg_kernel_fatal:nxx}
+%\begin{macro}{\msg_kernel_fatal:nx}
+%\begin{macro}{\msg_kernel_fatal:n}
+% Fatal kernel errors cannot be re-defined.
+% \begin{macrocode}
+\cs_new_protected:Nn \msg_kernel_fatal:nxx {
+ \msg_direct_interrupt:xxxxn
+ { \c_msg_fatal_tl \msg_two_newlines: }
+ {
+ ( LaTeX ) \msg_space:
+ \use:c { \c_msg_text_prefix_tl LaTeX / #1 :nn } {#2} {#3}
+ }
+ { ( LaTeX ) \msg_space: }
+ { \c_msg_fatal_text_tl }
+ { \tex_end:D }
+}
+\msg_kernel_classes_new:n { fatal }
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%
+%\begin{macro}{\msg_kernel_error:nxx}
+%\begin{macro}{\msg_kernel_error:nx}
+%\begin{macro}{\msg_kernel_error:n}
+% Neither can kernel errors.
+% \begin{macrocode}
+\cs_new_protected:Nn \msg_kernel_error:nxx {
+ \msg_direct_interrupt:xxxxn
+ { LaTeX~\c_msg_error_tl \msg_newline: }
+ {
+ ( LaTeX ) \msg_space:
+ \use:c { \c_msg_text_prefix_tl LaTeX / #1 :nn } {#2} {#3}
+ }
+ { ( LaTeX ) \msg_space: }
+ {
+ \cs_if_exist:cTF { \c_msg_more_text_prefix_tl LaTeX / #1 :nn } {
+ \use:c { \c_msg_more_text_prefix_tl LaTeX / #1 :nn } {#2} {#3}
+ }{
+ \c_msg_no_info_text_tl
+ }
+ }
+ {
+ \cs_if_exist:cT { \c_msg_code_prefix_tl LaTeX /#1 :nn } {
+ \use:c { \c_msg_code_prefix_tl LaTeX / #1 :nn} {#2} {#3}
+ }
+ }
+}
+\msg_kernel_classes_new:n { error }
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%
+%\begin{macro}{\msg_kernel_warning:nxx}
+%\begin{macro}{\msg_kernel_warning:nx}
+%\begin{macro}{\msg_kernel_warning:n}
+%\begin{macro}{\msg_kernel_info:nxx}
+%\begin{macro}{\msg_kernel_info:nx}
+%\begin{macro}{\msg_kernel_info:n}
+% Life is much more simple for warnings and information messages, as
+% these are just short-cuts to the standard classes.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \msg_kernel_warning:nxx {
+ \msg_warning:nnxx { LaTeX }
+}
+\msg_kernel_classes_new:n { warning }
+\cs_new_protected_nopar:Npn \msg_kernel_info:nxx {
+ \msg_info:nnxx { LaTeX }
+}
+\msg_kernel_classes_new:n { info }
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%
+% Some very basic error messages.
+% \begin{macrocode}
+\msg_kernel_new:nnn
+ { coding~bug }
+ {This is a LaTeX bug: check coding!\\#1}
+ {#2}
+\msg_kernel_new:nnn
+ { message~unknown }
+ {Unknown message `#2' for module `#1'.}
+ {LaTeX was asked to display a message by the `#1' module.\\
+ The message was supposed to be called `#2', but I can't\\
+ find a message with that name.
+ \c_msg_return_text_tl}
+\msg_kernel_new:nnn
+ { message~class~unknown }
+ {Unknown message class `#1'.}
+ {You have asked for a message to be redirected to class `#1'\\
+ but this class is unknown.
+ \c_msg_return_text_tl}
+\msg_kernel_new:nnn
+ { message~loop }
+ {Message redirection loop.}
+ {You have asked for a message to be redirected,\\
+ but the redirection instructions form a loop:\\
+ you've lost the message.
+ \c_msg_return_text_tl}
+% \end{macrocode}
+%
+%\begin{macro}{\msg_kernel_bug:x}
+% The \LaTeX\ coding bug error gets re-visited here.
+% \begin{macrocode}
+\cs_set_protected:Nn \msg_kernel_bug:x {
+ \msg_direct_interrupt:xxxxn
+ { \c_msg_kernel_bug_text_tl }
+ { !~#1 }
+ { ! }
+ { \c_msg_kernel_bug_more_text_tl }
+ { }
+}
+% \end{macrocode}
+%\end{macro}
+%
+% \begin{macrocode}
+%</initex|package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/Master/texmf-dist/source/latex/expl3/l3names.dtx b/Master/texmf-dist/source/latex/expl3/l3names.dtx
index 3bd4dbf2612..26148a4e7a2 100644
--- a/Master/texmf-dist/source/latex/expl3/l3names.dtx
+++ b/Master/texmf-dist/source/latex/expl3/l3names.dtx
@@ -1,5 +1,5 @@
% \iffalse
-%% File: l3names.dtx Copyright (C) 1990-2006 LaTeX3 project
+%% File: l3names.dtx Copyright (C) 1990-2006,2009 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
@@ -17,7 +17,7 @@
%%
%% The development version of the bundle can be found at
%%
-%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/
+%% http://www.latex-project.org/svnroot/experimental/trunk/
%%
%% for those people who are interested.
%%
@@ -42,7 +42,18 @@
%</initex>
%<package>\begingroup
%<*initex|package>
-\def\GetIdInfo$#1 #2.#3 #4 #5 #6 #7${%
+\def\GetIdInfo$#1${%
+ \begingroup
+ \def\GetIdInfoString{#1}%
+ \def\IdInfoStringUnexp{Id}%
+ \ifx \GetIdInfoString \IdInfoStringUnexp
+ \def\next{\endgroup\GetIdInfoMissing}
+ \else
+ \def\next{\endgroup\GetIdInfoFull$#1$}
+ \fi
+ \next
+}
+\def\GetIdInfoFull$#1 #2.#3 #4 #5 #6 #7${%
\GetIdInfoAux #5\relax{#2}#5\relax{#4}%
}
\def\GetIdInfoAux #1#2#3#4#5#6\relax{%
@@ -60,6 +71,12 @@
\def\GetIdInfoAuxSVN #1#2-#3-#4\relax#5#6{%
\immediate\write-1{#1; #2/#3/#4 v#5 #6}%
}
+\def\GetIdInfoMissing#1{%
+ \gdef\fileversion{000}%
+ \gdef\filedate{0000/00/00}%
+ \gdef\filedescription{#1}%
+ \immediate\write-1{[Loading unknown package: #1]}%
+}
%</initex>
%<*package>
\def\GetIdInfoAuxCVS #1#2\relax#3#4{%
@@ -74,12 +91,18 @@
\gdef\filedescription{#6}%
\ProvidesPackage{#1}[#2/#3/#4 v#5 #6]
}
+\def\GetIdInfoMissing#1{%
+ \gdef\fileversion{000}%
+ \gdef\filedate{0000/00/00}%
+ \gdef\filedescription{#1}%
+ \ProvidesPackage{[unknown package]}[0000/00/00 v0.0 #1]
+}
%</package>
%<*driver>
\RequirePackage{l3names}
%</driver>
%\fi
-\GetIdInfo$Id: l3names.dtx 621 2007-09-01 20:14:19Z morten $
+\GetIdInfo$Id: l3names.dtx 1362 2009-05-28 20:19:21Z joseph $
{L3 Experimental Naming Scheme for TeX Primitives}
%
%
@@ -90,7 +113,7 @@
\ProvidesFile{l3names.dtx}
[\filedate\space v\fileversion\space\filedescription]
%\iffalse
-\documentclass{l3doc}
+\documentclass[full]{l3doc}
\begin{document}
\DocInput{l3names.dtx}
\end{document}
@@ -105,215 +128,30 @@
% \date{\filedate}
% \maketitle
%
-% \changes{v2.0a}{1997/08/04}
-% {new consistent tex module name for \TeX\ primitives}
-%
-% \begin{abstract}
-% This package sets up an experimental naming scheme for
-% \LaTeX\ commands. It allows the \LaTeX\ programmer to systematically
-% name functions and variables, and specify the argument types of
-% functions.
-%
-% The \TeX\ primitives are all given a new name according to these
-% conventions.
-%
-% \begin{bfseries}
-% Warning: This package, and all packages using it should be regarded as
-% \emph{expermiental}!
-%
-% The names of these packages, and the names and syntax of any commands
-% defined in them might change at any time.
-%
-% These conventions are being distributed in this form to encourage
-% discussion and experimentation. It is \emph{not} intentended that
-% these packages be used in `real' documents at this stage.
-% \end{bfseries}
-% \end{abstract}
-%
-%
-% \section{Conventions}
-%
-% This section gives an overview of the syntax for \LaTeX\ commands
-% that is set up for use in these `experimental' pacages.
-%
-% Commands in \LaTeX3 are either functions or parameters. All
-% primitive commands of \TeX{} have private names.
-%
-% \subsection{Functions}
-%
-% Functions have the following general syntax:
-% \begin{quote}
-% |\|\m{module}|_|\m{description}|:|\m{arg-spec}
-% \end{quote}
-% where \m{module} is one of the (to be) chosen module names and
-% \m{description} is a verbal description of the functionality.
-% \m{arg-spec} finally describes the type of arguments that the
-% function takes and is left empty if it is a function without
-% arguments.
-%
-% All three parts consists of letters only \m{description} is allowed
-% to take further |_| characters to separate words is necessary.
-%
-% Currently there exists some functions which don't have a proper
-% \m{module} name.
-%
-% As a semi-formalized concept the letter |g| is sometimes used to
-% prefix the \m{module} name and certain parts of the \m{description}
-% to mark the function as ``globally acting''.
-%
-% The \m{arg-spec} currently supports the following types of
-% arguments:
-% \begin{description}
-%
-% \item[n] Unexpanded token (or token-list if in braces) braces.
-%
-% \item[o] One time expanded token or token-list. In the latter case,
-% effectively only the first token in the list gets expanded. Since
-% the expansion might result in more than one token, the result is
-% surrounded for further processing with braces.
-%
-% \item[x] Fully expanded token or token-list. Like |o| but the
-% argument is expanded using |\def:Npx| before it is passed on.
-%
-% \item[c] A character string or a token-list that expands to
-% characters of catcode 11 or 12. This string (after expansion) is
-% used to construct a command name that is eventually passed on.
-%
-% \item[N,O,X] Like |n|, |o|, |x| but the argument must be a single
-% token without any braces around it.
-%
-% \item[w] One or more arguments with ``weird'' syntax that one has
-% to know by heart or better leave it alone.
-%
-% \item[p] Denotes parameter text specification part, e.g.\^^M
-% |#1#2\q_stop#3|.
-%
-% \item[T,F] denotes the ``true'' or the ``false'' case in a
-% functional predicate.
-%
-% \end{description}
-%
-% Especially for the new names of \TeX{} primitives there are is one
-% more character to denote arguments. It implies that these
-% functions should not be used outside this bootstrapping file.
-% \begin{description}
-%
-% \item[D] Zero or more arguments with ``weird'' syntax. Uppercase
-% ``D'' means (DON'T USE IT), i.e.,
-% that this is a primitive \TeX{} command that should
-% not show up in code except in the very basic functions of \LaTeX3
-% that provide a more sensible interface.
-%
-% \end{description}
-%
-% One could perhaps envisage an extended system which allocated
-% letters to denote the various primitive argument types available in
-% \TeX, however it seems that this just complicates the system
-% without adding any real benefit, as these primitives would never be
-% used in production code, as higher level packages should offer a
-% better interface. Thus the following letters, although they were
-% considered have not been used. ``D'' is used in most cases in
-% preference.
-% \begin{description}
-% \item[i] Denotes an integer in \TeX{} notation (which might be a
-% register or \dots).
-%
-% \item[d] Denotes a dimension in \TeX{} notation.
-%
-% \item[g] Denotes a glue in \TeX{} notation.
-%
-% \item[m] Denotes an muglue or mukern in \TeX{} notation.
-%
-% \item[b] Denotes a box specification in \TeX{} notation (again
-% something pretty arbitrary).
-%
-% \item[r] Denotes a rule specification in \TeX{} notation.
-%
-% \end{description}
-%
-% Some of the primitive functions below are flagged ``D'' even if
-% they actually might be useful in average code. So certainly there
-% are some adjustments necessary. It all depends whether or not we
-% provide some safer interface or leave them alone.
-%
-% \subsection{Parameters}
+% \begin{documentation}
%
-% Parameter names have the following general syntax:
-% \begin{quote}
-% |\|\m{access}|_|\m{module}|_|\m{description}|_|\m{type}
-% \end{quote}
+% \section{Setting up the \LaTeX3 programming language}
%
-% \m{module} and \m{description} is as above. \m{type} should denote
-% the type of parameter if this helps in using it. The currently used
-% types are:
-% \begin{description}
+% 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 defines catcode regimes for programming;
+% \item provides settings for when the code is used in a format;
+% \item provides tools for when the code is used as a package within a
+% \LaTeXe\ context.
+% \end{itemize}
%
-% \item[int] Integer valued.
+% \section{Using the modules}
%
-% \item[factor] Another integer value type. Used for things where the
-% parameter is used as a factor for something else.
+% 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.
%
-% \item[status] The sort of boolean stuff \TeX{} provides. Essentially
-% an integer with the meaning |0| = `off' and other values may or may
-% not have sensible meanings.
-%
-% \item[pen] Another integer describing penalties.
-%
-% \item[dem] The demerits.
-%
-% \item[dim] A dimension.
-%
-% \item[skip] A glue value.
-%
-% \item[toks] A toks register (sort of).
-%
-% \item[char] An integer denoting a character.
-%
-% \item[muskip] A math unit.
-%
-% \end{description}
-%
-% \m{access} describes how the parameter can be accessed. The
-% following characters are possible:
-% \begin{description}
-%
-% \item[c] A constant. Should not be set in the code except with
-% special functions to define the value for the whole processing.
-%
-% \item[C] A constant according to \TeX's rules. Can not be changed at
-% all.
-%
-% \item[l] A local variable which therefore should not be changed
-% globally.
-%
-% \item[L] A local variable that is usually set (and/or reset) by
-% \TeX{} itself.
-%
-% \item[g] A global variable.
-%
-% \item[G] A global variable that is usually set (and/or reset by \TeX.
-%
-% \item[R] A variable that is set (and changed) by \TeX{} and can not
-% be changed by in the code (read-only).
-%
-% \end{description}
-%
-%
-%
-% \section{Modules}
-%
-% Nearly all operations of \LaTeX3 are carried out by calling control
-% sequences. For better programming concepts many types of functions are
-% identified and gathered in modules. Functions in such modules starts
-% with special prefixes, for example "\tlp_" is the prefix for functions
-% dealing with token list pointers.
-%
-% \subsection{Using the modules}
-%
-% Most of the modules can be used on top of \LaTeX\ and are loaded
-% with the usual "\usepackage" or "\RequirePackage" instructions. As
-% the packages use a coding syntax different from standard \LaTeX\ it
-% provides a few functions for setting it up.
+% As the modules use a coding syntax different from standard
+% \LaTeX\ it provides a few functions for setting it up.
%
% \begin{function}{
% \ExplSyntaxOn |
@@ -323,18 +161,28 @@
% "\ExplSyntaxOn" <code> "\ExplSyntaxOff"
% \end{syntax}
% Issues a catcode regime where spaces are ignored and colon and
-% underscore are letters.
+% underscore are letters. A space character may by input with "~" instead.
+% \end{function}
+%
+% \begin{function}{
+% \ExplSyntaxNamesOn |
+% \ExplSyntaxNamesOff
+% }
+% \begin{syntax}
+% "\ExplSyntaxNamesOn" <code> "\ExplSyntaxNamesOff"
+% \end{syntax}
+% Issues a catcode regime where colon and underscore are letters, but
+% spaces remain the same.
% \end{function}
%
% \begin{function}{
-% l3names |
% \ProvidesExplPackage |
% \ProvidesExplClass
% }
% \begin{syntax}
-% "\RequirePackage{l3names}" \\
-% "\ProvidesExplPackage" "{"<package>"}"
-% "{"<date>"}" "{"<version>"}" "{"<description>"}"
+% "\RequirePackage{expl3}" \\
+% "\ProvidesExplPackage" \Arg{package}
+% \Arg{date} \Arg{version} \Arg{description}
% \end{syntax}
% The package "l3names" (this module) provides
% "\ProvidesExplPackage" which is a wrapper for "\ProvidesPackage"
@@ -351,13 +199,14 @@
% \filedate |
% \fileversion |
% \filetimestamp |
-% \fileauthor
+% \fileauthor |
+% \filedescription
% }
% \begin{syntax}
% "\RequirePackage{l3names}" \\
-% "\GetIdInfo" "$Id:" <cvs or svn info field> "$" "{"<description>"}"
+% "\GetIdInfo" "$Id:" <cvs or svn info field> "$" \Arg{description}
% \end{syntax}
-% Extracts all information from a cvs or svn field. Spaces are not
+% Extracts all information from a CVS or SVN field. Spaces are not
% ignored in these fields. The information pieces are stored in
% separate control sequences with "\filename" for the part of the
% file name leading up to the period, "\filenameext" for the
@@ -377,33 +226,79 @@
% \end{verbatim}
%
%
+% \end{documentation}
%
+% \begin{implementation}
%
-% \StopEventually{}
-%
-% \section{Starters}
+% \section{\pkg{l3names} implementation}
%
% This is the base part of \LaTeX3 defining things like |catcode|s
-% and redefining the \TeX{} primitives.
+% and redefining the \TeX{} primitives, as well as setting up the code
+% to load \pkg{expl3} modules in \LaTeXe.
+%
+% \subsection{Internal functions}
%
-% We start by setting up |\catcode|s that we need to define new
-% commands. These are the ones for begin-group and end-group
-% characters.\footnote{Well not needed while this file is running
-% as a package on top of \LaTeXe, so omitted from the package code}
+% \begin{function}{ \ExplSyntaxStatus | \ExplSyntaxPopStack | \ExplSyntaxStack }
+% Functions used to track the state of the catcode regime.
+% \end{function}
+%
+% \begin{function}{\@pushfilename | \@popfilename}
+% Re-definitions of \LaTeX's file-loading functions to support "\ExplSyntax".
+% \end{function}
+%
+% \subsection{Package loading}
+%
+% Before anything else, check that we're using \eTeX;
+% no point continuing otherwise.
% \begin{macrocode}
-%<*initex>
-\catcode`\{=1 % left brace is begin-group character
-\catcode`\}=2 % right brace is end-group character
-\catcode`\#=6 % hash mark is macro parameter character
-\catcode`\^=7 %
-\catcode`\^^I=10 % ascii tab is a blank space
-%</initex>
+%<*initex|package>
+\begingroup
+\def\firstoftwo#1#2{#1}
+\def\secondoftwo#1#2{#2}
+\def\etexmissingerror{Not running under e-TeX}
+\def\etexmissinghelp{%
+ This package requires e-TeX.^^J%
+ Try compiling the document with `elatex' instead of `latex'.^^J%
+ When using pdfTeX, try `pdfelatex' instead of `pdflatex'%
+}%
+\expandafter\ifx\csname eTeXversion\endcsname\relax
+ \expandafter\secondoftwo\else\expandafter\firstoftwo\fi
+ {\endgroup}{%
+%<initex> \expandafter\errhelp\expandafter{\etexmissinghelp}%
+%<initex> \expandafter\errmessage\expandafter{\etexmissingerror}%
+%<package> \PackageError{l3names}{\etexmissingerror}{\etexmissinghelp}%
+ \endgroup
+ \endinput
+ }
+%</initex|package>
% \end{macrocode}
+%
+% \subsection{Catcode assignments}
+%
+% Catcodes for begingroup, endgroup, macro parameter, superscript, and tab,
+% are all assigned before the start of the documented code. (See the beginning
+% of \file{l3names.dtx}.)
+%
% Reason for |\endlinechar=32| is that a line ending with a backslash
% will be interpreted as the token \verb*|\ | which seems most natural
% and since spaces are ignored it works as we intend elsewhere.
+%
+% Before we do this we must however record the settings for the
+% catcode regime as it was when we start changing it.
% \begin{macrocode}
%<*initex|package>
+\edef\ExplSyntaxOff{
+ \unexpanded{\ifodd \ExplSyntaxStatus\relax
+ \def\ExplSyntaxStatus{0}
+ }
+ \catcode 126=\the \catcode 126 \relax
+ \catcode 32=\the \catcode 32 \relax
+ \catcode 9=\the \catcode 9 \relax
+ \endlinechar =\the \endlinechar \relax
+ \catcode 95=\the \catcode 95 \relax
+ \catcode 58=\the \catcode 58 \relax
+ \noexpand\fi
+}
\catcode126=10\relax % tilde is a space char.
\catcode32=9\relax % space is ignored
\catcode9=9\relax % tab also ignored
@@ -412,8 +307,7 @@
\catcode58=11\relax % colon letter
% \end{macrocode}
%
-%
-% \section{Setting up primitive names}
+% \subsection{Setting up primitive names}
%
% Here is the function that renames \TeX{}'s primitives.
%
@@ -477,7 +371,7 @@
}
% \end{macrocode}
%
-% \subsection{Assignments}
+% \subsection{Reassignment of primitives}
%
% In the current incarnation of this package, all \TeX\ primitives
% are given a new name of the form |\tex_|\emph{oldname}|:D|.
@@ -819,7 +713,7 @@
%
%
%
-% Since \LaTeX3 will require at least the \eTeX{} extensions,
+% Since \LaTeX3 requires at least the \eTeX{} extensions,
% we also rename the additional primitives. These are all
% given the prefix |\etex_|.
% \begin{macrocode}
@@ -892,8 +786,7 @@
% \end{macrocode}
%
%
-% All major distributions\footnote{At the time of writing MiK\TeX\
-% does not but I have a gut feeling that will change.} use
+% All major distributions use
% pdf\eTeX{} as engine so we add these names as well. Since the
% pdf\TeX{} team has been very good at prefixing most primitives
% with |pdf| (so far only five do not start with |pdf|) we do not
@@ -1003,14 +896,29 @@
\name_primitive:NN \pdfnoligatures \pdf_noligatures:D
% \end{macrocode}
%
-% What about Omega and Aleph? The status of both are unclear but let's
-% start by adding a single primitive which we can use for testing if
-% we have one of these engines.
+% We're ignoring XeTeX and LuaTeX right
+% now except for a check whether they're in use:
+% \begin{macrocode}
+\name_primitive:NN \XeTeXversion \xetex_version:D
+\name_primitive:NN \directlua \luatex_directlua:D
+% \end{macrocode}
+%
+% XeTeX adds \cs{strcmp} to the set of primitives, with the same
+% implementation as \cs{pdfstrcmp} but a different name. To avoid
+% having to worry about this later, the same internal name is used.
% \begin{macrocode}
-\name_primitive:NN \textdir \aleph_textdir:D
+\etex_ifdefined:D \strcmp
+ \etex_ifdefined:D \xetex_version:D
+ \name_primitive:NN \strcmp \pdf_strcmp:D
+ \tex_fi:D
+\tex_fi:D
% \end{macrocode}
-% \begin{macro}{\CodeStart}
-% \begin{macro}{\CodeStop}
+%
+% \subsection{\pkg{expl3} code switches}
+%
+% \begin{macro}{\ExplSyntaxOn}
+% \begin{macro}{\ExplSyntaxOff}
+% \begin{macro}{\ExplSyntaxStatus}
% Here we define functions that are used to turn on and off the
% special conventions used in the kernel of \LaTeX3.
%
@@ -1019,48 +927,63 @@
% to a space instead. When space characters are needed in \LaTeX3
% code the |~| character will be used for that purpose.
%
+% Specification of the desired behavior:
+% \begin{itemize}
+% \item ExplSyntax can be either On or Off.
+% \item The On switch is \meta{null} if ExplSyntax is on.
+% \item The Off switch is \meta{null} if ExplSyntax is off.
+% \item If the On switch is issued and not \meta{null}, it records
+% the current catcode scheme just prior to it being issued.
+% \item An Off switch restores the catcode scheme to what it was just
+% prior to the previous On switch.
+% \end{itemize}
+%
% \begin{macrocode}
\tex_def:D\ExplSyntaxOn{
- \tex_def:D\ExplSyntaxStatus{00}
- \tex_catcode:D 126=10 \tex_relax:D % tilde is a space char.
- \tex_catcode:D 32=9 \tex_relax:D % space is ignored
- \tex_catcode:D 9=9 \tex_relax:D % tab also ignored
- \tex_endlinechar:D =32 \tex_relax:D % endline is space
- \tex_catcode:D 95=11 \tex_relax:D % underscore letter
- \tex_catcode:D 58=11 \tex_relax:D % colon letter
-}
-% \end{macrocode}
-%
-% \begin{macrocode}
-\tex_def:D\ExplSyntaxOff{
- \tex_def:D\ExplSyntaxStatus{01}
- \tex_catcode:D 126=13 \tex_relax:D
- \tex_catcode:D 32=10 \tex_relax:D
- \tex_catcode:D 9=10 \tex_relax:D
- \tex_endlinechar:D =13 \tex_relax:D
- \tex_catcode:D 95=8 \tex_relax:D
- \tex_catcode:D 58=12 \tex_relax:D
+ \tex_ifodd:D \ExplSyntaxStatus \tex_relax:D
+ \tex_else:D
+ \tex_edef:D\ExplSyntaxOff{
+ \etex_unexpanded:D{
+ \tex_ifodd:D \ExplSyntaxStatus \tex_relax:D
+ \tex_def:D \ExplSyntaxStatus{0}
+ }
+ \tex_catcode:D 126=\tex_the:D \tex_catcode:D 126 \tex_relax:D
+ \tex_catcode:D 32=\tex_the:D \tex_catcode:D 32 \tex_relax:D
+ \tex_catcode:D 9=\tex_the:D \tex_catcode:D 9 \tex_relax:D
+ \tex_endlinechar:D =\tex_the:D \tex_endlinechar:D \tex_relax:D
+ \tex_catcode:D 95=\tex_the:D \tex_catcode:D 95 \tex_relax:D
+ \tex_catcode:D 58=\tex_the:D \tex_catcode:D 58 \tex_relax:D
+ \tex_noexpand:D \tex_fi:D
+ }
+ \tex_def:D\ExplSyntaxStatus{1}
+ \tex_catcode:D 126=10 \tex_relax:D % tilde is a space char.
+ \tex_catcode:D 32=9 \tex_relax:D % space is ignored
+ \tex_catcode:D 9=9 \tex_relax:D % tab also ignored
+ \tex_endlinechar:D =32 \tex_relax:D % endline is space
+ \tex_catcode:D 95=11 \tex_relax:D % underscore letter
+ \tex_catcode:D 58=11 \tex_relax:D % colon letter
+ \tex_fi:D
}
% \end{macrocode}
-% Temporary while names change.
+% At this point we better set the status.
% \begin{macrocode}
-\tex_let:D \CodeStart \ExplSyntaxOn
-\tex_let:D \CodeStop \ExplSyntaxOff
+\tex_def:D\ExplSyntaxStatus{1}
% \end{macrocode}
% \end{macro}
% \end{macro}
+% \end{macro}
%
-% \begin{macro}{\NamesStart}
-% \begin{macro}{\NamesStop}
+% \begin{macro}{\ExplSyntaxNamesOn}
+% \begin{macro}{\ExplSyntaxNamesOff}
% Sometimes we need to be able to use names from the kernel of
% \LaTeX3 without adhering it's conventions according to space
% characters. These macros provide the necessary settings.
% \begin{macrocode}
-\tex_def:D \NamesStart{
+\tex_def:D \ExplSyntaxNamesOn{
\tex_catcode:D `\_=11\tex_relax:D
\tex_catcode:D `\:=11\tex_relax:D
}
-\tex_def:D \NamesStop{
+\tex_def:D \ExplSyntaxNamesOff{
\tex_catcode:D `\_=8\tex_relax:D
\tex_catcode:D `\:=12\tex_relax:D
}
@@ -1068,11 +991,21 @@
% \end{macro}
% \end{macro}
%
+% \subsection{Package loading}
+%
+%
% \begin{macro}{\GetIdInfo}
-% \begin{macro}{\GetIdInfoAuxi:w}
-% \begin{macro}{\GetIdInfoAuxii:w}
-% \begin{macro}{\GetIdInfoAuxCVS:w}
-% \begin{macro}{\GetIdInfoAuxSVN:w}
+% \begin{macro}{ \filedescription ,
+% \filename ,
+% \fileversion ,
+% \fileauthor ,
+% \filedate ,
+% \filenameext ,
+% \filetimestamp }
+% \begin{macro}[aux]{\GetIdInfoAuxi:w}
+% \begin{macro}[aux]{\GetIdInfoAuxii:w}
+% \begin{macro}[aux]{\GetIdInfoAuxCVS:w}
+% \begin{macro}[aux]{\GetIdInfoAuxSVN:w}
% Extract all information from a cvs or svn field. The
% formats are slightly different but at least the information is in
% the same positions so we check in the date format so see if it
@@ -1083,8 +1016,33 @@
\tex_def:D\GetIdInfo{
\tex_begingroup:D
\tex_catcode:D 32=10 \tex_relax:D % needed? Probably for now.
- \GetIdInfoAuxi:w
+ \GetIdInfoMaybeMissing:w
}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\tex_def:D\GetIdInfoMaybeMissing:w$#1$#2{
+ \tex_def:D \l_tmpa_tl {#1}
+ \tex_def:D \l_tmpb_tl {Id}
+ \tex_ifx:D \l_tmpa_tl \l_tmpb_tl
+ \tex_def:D \l_tmpa_tl {
+ \tex_endgroup:D
+ \tex_def:D\filedescription{#2}
+ \tex_def:D\filename {[unknown~name]}
+ \tex_def:D\fileversion {000}
+ \tex_def:D\fileauthor {[unknown~author]}
+ \tex_def:D\filedate {0000/00/00}
+ \tex_def:D\filenameext {[unknown~ext]}
+ \tex_def:D\filetimestamp {[unknown~timestamp]}
+ }
+ \tex_else:D
+ \tex_def:D \l_tmpa_tl {\GetIdInfoAuxi:w$#1${#2}}
+ \tex_fi:D
+ \l_tmpa_tl
+}
+% \end{macrocode}
+%
+% \begin{macrocode}
\tex_def:D\GetIdInfoAuxi:w$#1~#2.#3~#4~#5~#6~#7~#8$#9{
\tex_endgroup:D
\tex_def:D\filename{#2}
@@ -1094,6 +1052,9 @@
\GetIdInfoAuxii:w #5\tex_relax:D
#3\tex_relax:D#5\tex_relax:D#6\tex_relax:D
}
+% \end{macrocode}
+%
+% \begin{macrocode}
\tex_def:D\GetIdInfoAuxii:w #1#2#3#4#5#6\tex_relax:D{
\tex_ifx:D#5/
\tex_expandafter:D\GetIdInfoAuxCVS:w
@@ -1101,6 +1062,9 @@
\tex_expandafter:D\GetIdInfoAuxSVN:w
\tex_fi:D
}
+% \end{macrocode}
+%
+% \begin{macrocode}
\tex_def:D\GetIdInfoAuxCVS:w #1,v\tex_relax:D
#2\tex_relax:D#3\tex_relax:D{
\tex_def:D\filedate{#2}
@@ -1128,11 +1092,10 @@
% \end{macro}
% \end{macro}
% \end{macro}
+% \end{macro}
%
% Finally some corrections in the case we are running over \LaTeXe.
%
-%
-%
% We want to set things up so that experimental packages and regular
% packages can coexist with the former using the \LaTeX3 programming
% catcode settings. Since it cannot be the task of the end user to
@@ -1147,7 +1110,7 @@
% as the packages in this distribution do like this:
% \begin{verbatim}
% \RequirePackage{l3names}
-% \GetIdInfo$Id: l3names.dtx 621 2007-09-01 20:14:19Z morten $
+% \GetIdInfo$Id: l3names.dtx 1362 2009-05-28 20:19:21Z joseph $
% {L3 Experimental Box module}
% \ProvidesExplPackage
% {\filename}{\filedate}{\fileversion}{\filedescription}
@@ -1156,7 +1119,8 @@
%
% \begin{macro}{\ProvidesExplPackage}
% \begin{macro}{\ProvidesExplClass}
-% First up is the identification. Rather trivial
+% First up is the identification. Rather trivial as we don't allow for
+% options just yet.
% \begin{macrocode}
%<*package>
\tex_def:D \ProvidesExplPackage#1#2#3#4{
@@ -1172,58 +1136,106 @@
% \end{macro}
%
%
-% \begin{macro}{\org@onefilewithoptions}
-% \begin{macro}{\@onefilewithoptions}
+% \begin{macro}{\@pushfilename}
% \begin{macro}{\@popfilename}
% The idea behind the code is to record whether or not the \LaTeX3
% syntax is on or off when about to load a file with class or
% package extension. This status stored in the parameter
% |\ExplSyntaxStatus| and set by |\ExplSyntaxOn| and
-% |\ExplSyntaxOff| to |00| and |01| respectively is puched onto the
+% |\ExplSyntaxOff| to |1| and |0| respectively is pushed onto the
% stack |\ExplSyntaxStack|. Then the catcodes are set back to
% normal, the file loaded with its options and finally the stack is
-% popped again.
-%
-% |\@popfilename| is appended with a preamble check. If the catcode
-% of "@" is being reset it is a fair assumption that we are back in
-% the usual preamble and so we switch off our syntax as well.
+% popped again. The whole thing is a bit problematical. So let's
+% take a look at what the desired behavior is: A package or class
+% which declares itself of Expl type by using |\ProvidesExplClass|
+% or |\ProvidesExplPackage| should automatically ensure the correct
+% catcode scheme as soon as the identification part is
+% over. Similarly, a package or class which uses the traditional
+% |\ProvidesClass| or |\ProvidesPackage| commands should go back to
+% the traditional catcode scheme. An example:
+% \begin{verbatim}
+% \RequirePackage{l3names}
+% \ProvidesExplPackage{foobar}{2009/05/07}{0.1}{Foobar package}
+% \cs_new:Nn \foo_bar:nn {#1,#2}
+% ...
+% \RequirePackage{array}
+% ...
+% \cs_new:Nn \foo_bar:nnn {#3,#2,#1}
+% \end{verbatim}
+% Inside the \pkg{array} package, everything should behave as normal
+% under traditional \LaTeX\ but as soon as we are back at the top
+% level, we should use the new catcode regime.
+%
+%
+% Whenever \LaTeX\ inputs a package file or similar, it calls upon
+% |\@pushfilename| to push the name, the extension and the catcode
+% of @ of the file it was currently processing onto a file name
+% stack. Similarly, after inputting such a file, this file name
+% stack is popped again and the catcode of @ is set to what it was
+% before. If it is a package within package, @ maintains catcode 11
+% whereas if it is package within document preamble @ is reset to
+% what it was in the preamble (which is usually catcode 12). We wish
+% to adopt a similar technique. Every time an Expl package or class
+% is declared, they will issue an ExplSyntaxOn. Then whenever we are
+% about to load another file, we will first push this status onto a
+% stack and then turn it off again. Then when done loading a file,
+% we pop the stack and if ExplSyntax was On right before, so should
+% it be now. The only problem with this is that we cannot guarantee
+% that we get to the file name stack very early on. Therefore, if
+% the ExplSyntaxStack is empty when trying to pop it, we ensure to
+% turn ExplSyntax off again.
+%
+% |\@pushfilename| is prepended with a small function pushing the
+% current ExplSyntaxStatus (true/false) onto a stack. Then the
+% current catcode regime is recorded and ExplSyntax is switched off.
+%
+% |\@popfilename| is appended with a function for popping the
+% ExplSyntax stack. However, chances are we didn't get to hook into
+% the file stack early enough so \LaTeX\ might try to pop the file
+% name stack while the ExplSyntaxStack is empty. If the latter is
+% empty, we just switch off ExplSyntax.
% \begin{macrocode}
-\tex_let:D \org@onefilewithoptions\@onefilewithoptions
-\tex_def:D \@onefilewithoptions#1[#2][#3]#4{
- \tex_edef:D \ExplSyntaxStack{ \ExplSyntaxStatus\ExplSyntaxStack }
- \ExplSyntaxOff
- \org@onefilewithoptions{#1}[{#2}][{#3}]{#4}
- \tex_expandafter:D\ExplSyntaxPopStack\ExplSyntaxStack\tex_relax:D
-}
-\g@addto@macro\@popfilename{%
- \tex_ifnum:D\tex_the:D\tex_catcode:D`\@=12\tex_relax:D
+\tex_edef:D \@pushfilename{
+ \etex_unexpanded:D{
+ \tex_edef:D \ExplSyntaxStack{ \ExplSyntaxStatus \ExplSyntaxStack }
\ExplSyntaxOff
- \tex_fi:D
+ }
+ \etex_unexpanded:D\tex_expandafter:D{\@pushfilename }
+}
+\tex_edef:D \@popfilename{
+ \etex_unexpanded:D\tex_expandafter:D{\@popfilename
+ \tex_if:D 2\ExplSyntaxStack 2
+ \ExplSyntaxOff
+ \tex_else:D
+ \tex_expandafter:D\ExplSyntaxPopStack\ExplSyntaxStack\q_nil
+ \tex_fi:D
+ }
}
% \end{macrocode}
% \end{macro}
% \end{macro}
-% \end{macro}
%
% \begin{macro}{\ExplSyntaxPopStack}
% \begin{macro}{\ExplSyntaxStack}
-% Popping the stack is simple: Take the first two tokens which are
-% either the sequence "00" or "01" and use them in an if test. The
-% stack is initially empty.
+% Popping the stack is simple: Take the first token which is either
+% 0 (false) or 1 (true) and test if it is odd. Save the rest. The
+% stack is initially empty set to 0 signalling that before
+% \pkg{l3names} was loaded, the ExplSyntax was off.
% \begin{macrocode}
-\tex_def:D\ExplSyntaxPopStack#1#2#3\tex_relax:D{
- \tex_def:D\ExplSyntaxStack{#3}
- \tex_if:D#1#2
+\tex_def:D\ExplSyntaxPopStack#1#2\q_nil{
+ \tex_def:D\ExplSyntaxStack{#2}
+ \tex_ifodd:D#1\tex_relax:D
\ExplSyntaxOn
\tex_else:D
\ExplSyntaxOff
\tex_fi:D
}
-\tex_def:D\ExplSyntaxStack{}
+\tex_def:D \ExplSyntaxStack{0}
% \end{macrocode}
% \end{macro}
% \end{macro}
%
+% \subsection{Finishing up}
%
% A few of the `primitives' assigned above have already been stolen
% by \LaTeX, so assign them by hand to the saved real primitive.
@@ -1243,18 +1255,11 @@
\tex_let:D\par \tex_par:D
% \end{macrocode}
%
-%
+% This is the end for \file{l3names} when used on top of \LaTeXe:
%
% \begin{macrocode}
\tex_ifx:D\name_undefine:N\@gobble
-% \end{macrocode}
-%
-% \begin{macrocode}
- \AtEndOfPackage{\ExplSyntaxOff}
\tex_def:D\name_pop_stack:w{}
-% \end{macrocode}
-%
-% \begin{macrocode}
\tex_else:D
% \end{macrocode}
%
@@ -1282,8 +1287,8 @@
% \end{macrocode}
%
% In this case the catcode preserving stack is not maintained and
-% |\CodeStart| conventions stay in force once on. You'll need
-% to turn then off explicitly with |\CodeStop| (although as currently
+% |\ExplSyntaxOn| conventions stay in force once on. You'll need
+% to turn then off explicitly with |\ExplSyntaxOff| (although as currently
% built on 2e, nothing except very experimental code will run in
% this mode!) Also note that |\RequirePackage| is a simple definition, just for
% one file, with no options.
@@ -1322,39 +1327,55 @@
% token is in fact |\let| and that may be undefined.)
% \begin{macrocode}
\tex_futurelet:D\name_tmp:\name_pop_stack:w
-%</package>
% \end{macrocode}
%
-% \endinput
-%
-% $Log$
-% Revision 1.17 2006/01/15 07:55:48 morten
-% Fixed minor typo
-%
-% Revision 1.16 2006/01/15 07:17:43 morten
-% Imported \NamesStart and \NamesStop from l3messages.
-%
-% Revision 1.15 2005/12/27 10:00:03 morten
-% Changed RCS information retrieval, code to run as package under 2e
-% changed slightly to not set special catcodes directly.
+% \paragraph{\pkg{expl3} dependency checks}
+% We want the \pkg{expl3} bundle to be loaded `as one'; this command is
+% used to ensure that one of the "l3" packages isn't loaded on its own.
+% \begin{macrocode}
+%<*!initex>
+\tex_def:D \package_check_loaded_expl: {
+ \@ifpackageloaded{expl3}{}{
+ \PackageError{expl3}{Cannot~load~the~expl3~modules~separately}{
+ The~expl3~modules~cannot~be~loaded~separately;\MessageBreak
+ please~\protect\usepackage{expl3}~instead.
+ }
+ }
+}
+%</!initex>
+% \end{macrocode}
%
-% Revision 1.14 2005/12/01 22:58:16 morten
-% Added pdfTeX primitives
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
%
-% Revision 1.13 2005/03/26 21:04:19 morten
-% Fix typo.
+% \subsection{Showing memory usage}
%
-% Revision 1.12 2005/03/22 23:23:57 morten
-% Added an Aleph primitive
+% This section is from some old code from 1993; it'd be good to work out
+% how it should be used in our code today.
%
-% Revision 1.11 2005/03/15 23:16:21 braams
-% Some tweaking with the docstrip guards to get the documentation to
-% come out right.
+% During the development of the \LaTeX3 kernel we need to be able
+% to keep track of the memory usage. Therefore we generate empty
+% pages while loading the kernel code, just to be able to check the
+% memory usage.
%
-% Revision 1.10 2005/03/15 22:48:31 braams
-% Made it possible to load this as the very first file with initex
+% \begin{macrocode}
+%<*showmemory>
+\g_trace_statistics_status=2\scan_stop:
+\cs_set_nopar:Npn\showMemUsage{
+ \if_horizontal_mode:
+ \tex_errmessage:D{Wrong~ mode~ H:~ something~ triggered~
+ hmode~ above}
+ \else:
+ \tex_message:D{Mode ~ okay}
+ \fi:
+ \tex_shipout:D\hbox:w{}
+}
+\showMemUsage
+%</showmemory>
+% \end{macrocode}
%
-% Revision 1.9 2005/03/11 21:29:56 braams
-% Fixed the use of RCS information; moved definition of \eTeX
-% to l3doc.cls
+% \end{implementation}
+% \PrintIndex
%
+% \endinput
diff --git a/Master/texmf-dist/source/latex/expl3/l3num.dtx b/Master/texmf-dist/source/latex/expl3/l3num.dtx
index 325eef2e131..51281eaf7ac 100644
--- a/Master/texmf-dist/source/latex/expl3/l3num.dtx
+++ b/Master/texmf-dist/source/latex/expl3/l3num.dtx
@@ -1,5 +1,5 @@
% \iffalse
-%% File: l3num.dtx Copyright (C) 2005-2008 Frank Mittelbach, LaTeX3 project
+%% File: l3num.dtx Copyright (C) 2005-2009 Frank Mittelbach, 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
@@ -17,7 +17,7 @@
%%
%% The development version of the bundle can be found at
%%
-%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/
+%% http://www.latex-project.org/svnroot/experimental/trunk/
%%
%% for those people who are interested.
%%
@@ -36,7 +36,7 @@
\RequirePackage{l3names}
%</driver|package>
%\fi
-\GetIdInfo$Id: l3num.dtx 741 2008-08-01 13:37:16Z morten $
+\GetIdInfo$Id: l3num.dtx 1362 2009-05-28 20:19:21Z joseph $
{L3 Experimental token numbers}
%\iffalse
%<*driver>
@@ -44,9 +44,9 @@
\ProvidesFile{\filename.\filenameext}
[\filedate\space v\fileversion\space\filedescription]
%\iffalse
-\documentclass{l3doc}
+\documentclass[full]{l3doc}
\begin{document}
-\DocInput{\filename.\filenameext}
+\DocInput{l3num.dtx}
\end{document}
%</driver>
% \fi
@@ -55,12 +55,12 @@
% \title{The \textsf{l3num} package\thanks{This file
% has version number \fileversion, last
% revised \filedate.}\\
-% Integer in macros}
+% Integers in macros}
% \author{\Team}
% \date{\filedate}
% \maketitle
%
-% \section{Macro Counters}
+% \begin{documentation}
%
% Instead of using counter registers for manipulation of
% integer values it is sometimes useful to keep such values in
@@ -75,7 +75,7 @@
% allocation module can do its bookkeeping without the aid of
% \meta{int} registers.
%
-% \subsection{Functions}
+% \section{Functions}
%
% \begin{function}{%
% \num_new:N |
@@ -135,12 +135,24 @@
% \num_gset:cn |
% }
% \begin{syntax}
-% "\num_set:Nn" <num> "{" <integer> "}"
+% "\num_set:Nn" <num> \Arg{integer}
% \end{syntax}
% These functions will set the <num> register to the <integer> value.
% \end{function}
%
% \begin{function}{%
+% \num_set_eq:NN |
+% \num_set_eq:cN |
+% \num_set_eq:Nc |
+% \num_set_eq:cc |
+% }
+% \begin{syntax}
+% "\num_gset_eq:NN" <num1> <num2>
+% \end{syntax}
+% These functions will set the <num1> register equal to <num2>.
+% \end{function}
+%
+% \begin{function}{%
% \num_gset_eq:NN |
% \num_gset_eq:cN |
% \num_gset_eq:Nc |
@@ -149,7 +161,7 @@
% \begin{syntax}
% "\num_gset_eq:NN" <num1> <num2>
% \end{syntax}
-% These functions will set the <num1> register equal to <num2>.
+% These functions will globally set the <num1> register equal to <num2>.
% \end{function}
%
% \begin{function}{%
@@ -159,7 +171,7 @@
% \num_gadd:cn |
% }
% \begin{syntax}
-% "\num_add:Nn" <num> "{" <integer> "}"
+% "\num_add:Nn" <num> \Arg{integer}
% \end{syntax}
% These functions will add to the <num> register the value <integer>. If
% the second argument is a <num> register too, the surrounding braces
@@ -184,112 +196,37 @@
% \end{texnote}
% \end{function}
%
-%
-% \begin{function}{%
-% \num_eval:n |
-% }
-% \begin{syntax}
-% "\num_eval:n" "{" <integer-expr> "}"
-% \end{syntax}
-% Evaluates the integer expression allowing normal mathematical
-% operators like |+-/*|.
-% \end{function}
-%
-%
-% \begin{function}{%
-% \num_compare:nNnTF |
-% \num_compare:cNcTF |
-% \num_compare:nNnT |
-% \num_compare:nNnF |
-% }
-% \begin{syntax}
-% "\num_compare:nNnTF" "{"<num~expr>"}" <rel> "{"<num~expr>"}"
-% "{"<true>"}" "{"<false>"}"
-% \end{syntax}
-% These functions test two \m{num} expressions against each other. They
-% are both evaluated by "\num_eval:n".
-% \end{function}
-%
-% \begin{function}{%
-% \num_compare_p:nNn |
-% }
+% \begin{function}{ \num_show:N |
+% \num_show:c }
% \begin{syntax}
-% "\num_compare_p:nNn" "{"<num~expr>"}" <rel> "{"<num~expr>"}"
+% "\num_show:N" <num>
% \end{syntax}
-% A predicate version of the above functions.
+% This function pauses the compilation and displays the integer value kept
+% in <num> on the console output.
% \end{function}
%
-% \begin{function}{%
-% \num_max_of:nn |
-% \num_min_of:nn |
-% }
-% \begin{syntax}
-% "\num_max_of:nn" "{"<num~expr>"}" "{"<num~expr>"}"
-% \end{syntax}
-% Return the largest or smallest of two \m{num} expressions.
-% \end{function}
%
-% \begin{function}{%
-% \num_abs:n |
-% }
-% \begin{syntax}
-% "\num_abs:n" "{"<num~expr>"}"
-% \end{syntax}
-% Return the numerical value of a \m{num} expression.
-% \end{function}
%
% \begin{function}{%
% \num_elt_count:n |
+% \num_elt_count_prop:Nn |
% }
% \begin{syntax}
-% "\num_elt_count:n" "{"<balanced text>"}"
+% "\num_elt_count:n" \Arg{balanced text}
+% "\num_elt_count_prop:Nn" <prop> \Arg{balanced text}
% \end{syntax}
-% Discards \m{balanced text} and puts a "+1" in the input stream. Used
+% Discards their arguments and puts a "+1" in the input stream. Used
% to count elements in a token list.
% \end{function}
%
-% \subsection{Formatting a counter value}
+% \section{Formatting a counter value}
%
% See the \textsf{l3int} module for ways of doing this.
%
-% \subsection{Variable and constants}
+% \section{Variable and constants}
%
-% \begin{function}{%
-% \const_new:Nn |
-% }
-% \begin{syntax}
-% "\const_new:Nn" "\c_"<value> "{" <value> "}"
-% \end{syntax}
-% Defines a constant with <value>. If the constant is negative
-% or very large it requires an <int> register.
-% \end{function}
-%
-% \begin{variable}{%
-% \c_minus_one |
-% \c_zero |
-% \c_one |
-% \c_two |
-% \c_three |
-% \c_four |
-% \c_six |
-% \c_seven |
-% \c_nine |
-% \c_ten |
-% \c_eleven |
-% \c_sixteen |
-% \c_hundred_one |
-% \c_twohundred_fifty_five |
-% \c_twohundred_fifty_six |
-% \c_thousand |
-% \c_ten_thousand |
-% \c_twenty_thousand
-% }
-% \\
-% Set of constants denoting useful values.
-% \begin{texnote}
-% Most of these constants have been available under \LaTeX2 under names
-% like \tn{tw@}, \tn{thr@@} etc.
-% \end{texnote}
+% \begin{variable}{ \c_max_register_num }
+% Maximum number of registers; possibly engine-specific.
% \end{variable}
%
% \begin{variable}{%
@@ -299,50 +236,20 @@
% \g_tmpa_num |
% \g_tmpb_num |
% }
-% \\
% Scratch register for immediate use. They are not used by conditionals
% or predicate functions.
% \end{variable}
%
-% \subsection{Primitive functions}
+% \section{Primitive functions}
%
%
% \begin{function}{%
-% \num_value:w |
-% }
-% \begin{syntax}
-% "\num_value:w" <integer> \\
-% "\num_value:w" <tokens> <optional space>
-% \end{syntax}
-% Expands <tokens> until an <integer> is formed. One space may be
-% gobbled in the process. Preferably use with "\num_eval:n".
-% \begin{texnote}
-% This is the \TeX{} primitive \tn{number}.
-% \end{texnote}
-% \end{function}
-%
-% \begin{function}{%
-% \num_eval:w |
-% }
-% \begin{syntax}
-% "\num_eval:w" <integer expression> "\num_eval_end:"
-% \end{syntax}
-% Evaluates <integer expression>. The evaluation stops when an
-% unexpandable token of catcode other than 12 is reached or
-% "\num_eval_end:" is read. The latter is gobbled by the scanner
-% mechanism.
-% \begin{texnote}
-% This is the \eTeX{} primitive \tn{numexpr}.
-% \end{texnote}
-% \end{function}
-%
-% \begin{function}{%
% \if_num:w |
% }
% \begin{syntax}
% "\if_num:w" <number1> <rel> <number2> <true> "\else:" <false> "\fi:"
% \end{syntax}
-% Compare two numbers. It is recommended to use "\num_eval:n" to
+% Compare two numbers. It is recommended to use "\intexpr_eval:n" to
% correctly evaluate and terminate these numbers. <rel> is one of
% "<", "=" or ">" with catcode 12.
% \begin{texnote}
@@ -351,18 +258,6 @@
% \end{function}
%
% \begin{function}{%
-% \if_num_odd:w |
-% }
-% \begin{syntax}
-% "\if_num_odd:w" <number> <true> "\else:" <false> "\fi:"
-% \end{syntax}
-% Execute <true> if <number> is odd, <false> otherwise.
-% \begin{texnote}
-% This is the \TeX{} primitive \tn{ifodd}.
-% \end{texnote}
-% \end{function}
-%
-% \begin{function}{%
% \if_case:w |
% \or: |
% }
@@ -370,52 +265,40 @@
% "\if_case:w" <number> <case0> "\or:" <case1> "\or:" "..." "\else:"
% <default> "\fi:"
% \end{syntax}
-% Chooses case<number>. If you wish to use negative numbers as well,
-% you can offset them with "\num_eval:n".
+% Chooses case <number>. If you wish to use negative numbers as well,
+% you can offset them with "\intexpr_eval:n".
% \begin{texnote}
% These are the \TeX{} primitives \tn{ifcase} and \tn{or}.
% \end{texnote}
% \end{function}
%
-% \StopEventually{}
+% \end{documentation}
%
-% \subsection{The Implementation}
+% \begin{implementation}
+%
+% \section{\pkg{l3num} implementation}
%
%
% We start by ensuring that the required packages are loaded.
% \begin{macrocode}
-%<package>\ProvidesExplPackage
-%<package> {\filename}{\filedate}{\fileversion}{\filedescription}
-%<package&!check>\RequirePackage{l3expan}\par
-%<package&check>\RequirePackage{l3chk}\par
+%<*package>
+\ProvidesExplPackage
+ {\filename}{\filedate}{\fileversion}{\filedescription}
+\package_check_loaded_expl:
+%</package>
%<*initex|package>
% \end{macrocode}
%
-% \begin{macro}{\num_value:w}
-% \begin{macro}{\num_eval:w}
-% \begin{macro}{\num_eval_end:}
% \begin{macro}{\if_num:w}
-% \begin{macro}{\if_num_odd:w}
% \begin{macro}{\if_case:w}
-% \begin{macro}{\or:}
% Here are the remaining primitives for number comparisons and
% expressions.
% \begin{macrocode}
-\let_new:NN \num_value:w \tex_number:D
-\let_new:NN \num_eval:w \etex_numexpr:D
-\let_new:NN \num_eval_end: \scan_stop:
-\let_new:NN \if_num:w \tex_ifnum:D
-\let_new:NN \if_num_odd:w \tex_ifodd:D
-\let_new:NN \if_case:w \tex_ifcase:D
-\let_new:NN \or: \tex_or:D
+\cs_new_eq:NN \if_num:w \tex_ifnum: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}
-% \end{macro}
%
% Functions that support \LaTeX's user accessible counters should be
% added here, too. But first the internal counters.
@@ -427,10 +310,10 @@
% Incrementing and decrementing of integer registers is done with
% the following functions.
% \begin{macrocode}
-\def:Npn \num_incr:N #1{\num_add:Nn#1 1}
-\def:Npn \num_decr:N #1{\num_add:Nn#1 \c_minus_one}
-\def:Npn \num_gincr:N #1{\num_gadd:Nn#1 1}
-\def:Npn \num_gdecr:N #1{\num_gadd:Nn#1 \c_minus_one}
+\cs_set_nopar:Npn \num_incr:N #1{\num_add:Nn#1 1}
+\cs_set_nopar:Npn \num_decr:N #1{\num_add:Nn#1 \c_minus_one}
+\cs_set_nopar:Npn \num_gincr:N #1{\num_gadd:Nn#1 1}
+\cs_set_nopar:Npn \num_gdecr:N #1{\num_gadd:Nn#1 \c_minus_one}
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -443,10 +326,10 @@
% \begin{macro}{\num_gdecr:c}
% We also need \ldots
% \begin{macrocode}
-\def_new:Npn \num_incr:c {\exp_args:Nc \num_incr:N}
-\def_new:Npn \num_decr:c {\exp_args:Nc \num_decr:N}
-\def_new:Npn \num_gincr:c {\exp_args:Nc \num_gincr:N}
-\def_new:Npn \num_gdecr:c {\exp_args:Nc \num_gdecr:N}
+\cs_generate_variant:Nn \num_incr:N {c}
+\cs_generate_variant:Nn \num_decr:N {c}
+\cs_generate_variant:Nn \num_gincr:N {c}
+\cs_generate_variant:Nn \num_gdecr:N {c}
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -459,10 +342,13 @@
% \begin{macro}{\num_gzero:c}
% We also need \ldots
% \begin{macrocode}
-\def_new:Npn \num_zero:N #1 {\num_set:Nn #1 0}
-\def_new:Npn \num_gzero:N #1 {\num_gset:Nn #1 0}
-\def_new:Npn \num_zero:c {\exp_args:Nc \num_zero:N}
-\def_new:Npn \num_gzero:c {\exp_args:Nc \num_gzero:N}
+\cs_new_nopar:Npn \num_zero:N #1 {\num_set:Nn #1 0}
+\cs_new_nopar:Npn \num_gzero:N #1 {\num_gset:Nn #1 0}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_generate_variant:Nn \num_zero:N {c}
+\cs_generate_variant:Nn \num_gzero:N {c}
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -475,33 +361,27 @@
% \begin{macro}{\num_new:c}
% Allocate a new \m{num} variable and initialize it with zero.
% \begin{macrocode}
-\def_new:Npn \num_new:N #1{\tlp_new:Nn #1{0}}
-\def_new:Npn \num_new:c {\exp_args:Nc \num_new:N}
+\cs_new_nopar:Npn \num_new:N #1{\tl_new:Nn #1{0}}
+\cs_generate_variant:Nn \num_new:N {c}
% \end{macrocode}
% \end{macro}
% \end{macro}
%
-%
-% \begin{macro}{\num_eval:n}
-% This function enables us to do all the operations without the aid of
-% an \m{int} register.
-% \begin{macrocode}
-\def_new:Npn \num_eval:n #1{\num_eval:w #1\num_eval_end:}
-% \end{macrocode}
-% \end{macro}
-%
% \begin{macro}{\num_set:Nn}
% \begin{macro}{\num_set:cn}
% \begin{macro}{\num_gset:Nn}
% \begin{macro}{\num_gset:cn}
% Assigning values to \m{num} registers.
% \begin{macrocode}
-\def_new:Npn \num_set:Nn #1#2{
- \tlp_set:No #1{ \tex_number:D \num_eval:n {#2} }
+\cs_new_nopar:Npn \num_set:Nn #1#2{
+ \tl_set:No #1{ \tex_number:D \intexpr_eval:n {#2} }
}
-\def_new:Npn \num_gset:Nn {\pref_global:D \num_set:Nn}
-\def_new:Npn \num_set:cn {\exp_args:Nc \num_set:Nn }
-\def_new:Npn \num_gset:cn {\exp_args:Nc \num_gset:Nn }
+\cs_generate_variant:Nn\num_set:Nn {c}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_new_nopar:Npn \num_gset:Nn {\pref_global:D \num_set:Nn}
+\cs_generate_variant:Nn\num_gset:Nn {c}
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -514,10 +394,8 @@
% \begin{macro}{\num_set_eq:cc}
% Setting \m{num} registers equal to each other.
% \begin{macrocode}
-\let_new:NN \num_set_eq:NN \tlp_set_eq:NN
-\def_new:Npn \num_set_eq:cN {\exp_args:Nc \num_set_eq:NN}
-\def_new:Npn \num_set_eq:Nc {\exp_args:NNc \num_set_eq:NN}
-\def_new:Npn \num_set_eq:cc {\exp_args:Ncc \num_set_eq:NN}
+\cs_new_eq:NN \num_set_eq:NN \tl_set_eq:NN
+\cs_generate_variant:Nn\num_set_eq:NN {c,Nc,cc}
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -530,10 +408,8 @@
% \begin{macro}{\num_gset_eq:cc}
% Setting \m{num} registers equal to each other.
% \begin{macrocode}
-\let_new:NN \num_gset_eq:NN \tlp_gset_eq:NN
-\def_new:Npn \num_gset_eq:cN {\exp_args:Nc \num_gset_eq:NN}
-\def_new:Npn \num_gset_eq:Nc {\exp_args:NNc \num_gset_eq:NN}
-\def_new:Npn \num_gset_eq:cc {\exp_args:Ncc \num_gset_eq:NN}
+\cs_new_eq:NN \num_gset_eq:NN \tl_gset_eq:NN
+\cs_generate_variant:Nn\num_gset_eq:NN {c,Nc,cc}
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -545,12 +421,15 @@
% \begin{macro}{\num_gadd:Nn}
% \begin{macro}{\num_gadd:cn}
% Adding is easily done as the second argument goes through
-% |\num_eval:n|.
+% |\intexpr_eval:n|.
% \begin{macrocode}
-\def_new:Npn \num_add:Nn #1#2 {\num_set:Nn #1{#1+#2}}
-\def_new:Npn \num_add:cn {\exp_args:Nc\num_add:Nn}
-\def_new:Npn \num_gadd:Nn {\pref_global:D \num_add:Nn}
-\def_new:Npn \num_gadd:cn {\exp_args:Nc\num_gadd:Nn}
+\cs_new_nopar:Npn \num_add:Nn #1#2 {\num_set:Nn #1{#1+#2}}
+\cs_generate_variant:Nn\num_add:Nn {c}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_new_nopar:Npn \num_gadd:Nn {\pref_global:D \num_add:Nn}
+\cs_generate_variant:Nn\num_gadd:Nn {c}
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -562,61 +441,30 @@
% \begin{macro}{\num_use:c}
% Here is how num macros are accessed:
% \begin{macrocode}
-\let_new:NN\num_use:N \use_arg_i:n
-\let_new:NN\num_use:c \cs_use:c
+\cs_new_eq:NN\num_use:N \use:n
+\cs_new_eq:NN\num_use:c \use:c
% \end{macrocode}
% \end{macro}
% \end{macro}
%
-%
-% \begin{macro}{\num_compare:nNnTF}
-% \begin{macro}{\num_compare:nNnT}
-% \begin{macro}{\num_compare:nNnF}
-% Simple comparison tests.
+% \begin{macro}{\num_show:N}
+% \begin{macro}{\num_show:c}
+% Here is how num macros are diagnosed:
% \begin{macrocode}
-\def_test_function_new:npn {num_compare:nNn}#1#2#3{
- \if_num:w \num_eval:n {#1}#2\num_eval:n {#3}
-}
-\def_new:Npn \num_compare:cNcTF { \exp_args:NcNc\num_compare:nNnTF }
+\cs_new_eq:NN\num_show:N \cs_show:N
+\cs_new_eq:NN\num_show:c \cs_show:c
% \end{macrocode}
% \end{macro}
% \end{macro}
-% \end{macro}
%
-% \begin{macro}{\num_compare_p:nNn}
-% A predicate function.
-% \begin{macrocode}
-\def_new:Npn \num_compare_p:nNn #1#2#3{
- \if_num:w \num_eval:n {#1}#2\num_eval:n {#3}
- \c_true
- \else:
- \c_false
- \fi:
-}
-% \end{macrocode}
-% \end{macro}
%
-% \begin{macro}{\num_max_of:nn}
-% \begin{macro}{\num_min_of:nn}
-% \begin{macro}{\num_abs:n}
-% Functions for $\min$, $\max$, and absolute value.
-% \begin{macrocode}
-\def_new:Npn \num_abs:n#1{
- \if_num:w \num_eval:n{#1}<\c_zero \exp_after:NN -\fi: #1
-}
-\def_new:Npn \num_max_of:nn#1#2{\num_compare:nNnTF {#1}>{#2}{#1}{#2}}
-\def_new:Npn \num_min_of:nn#1#2{\num_compare:nNnTF {#1}<{#2}{#1}{#2}}
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
%
% \begin{macro}{\num_elt_count:n}
% \begin{macro}{\num_elt_count_prop:Nn}
% Helper function for counting elements in a list.
% \begin{macrocode}
-\def_long_new:Npn \num_elt_count:n #1 { + 1 }
-\def_long_new:Npn \num_elt_count_prop:Nn #1#2 { + 1 }
+\cs_new:Npn \num_elt_count:n #1 { + 1 }
+\cs_new:Npn \num_elt_count_prop:Nn #1#2 { + 1 }
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -641,167 +489,17 @@
% \end{macro}
% \end{macro}
%
-% \subsubsection{Defining constants}
-% As stated, most constants can be defined as |\tex_chardef:D| or
-% |\tex_mathchardef:D| but that's engine dependent. Omega/Aleph
-% allows |\tex_chardef:D|s up to 65535 which is also the maximum
-% number of registers of all types.
-% \begin{macro}{\const_new:Nn}
% \begin{macro}{\c_max_register_num}
-% \begin{macro}{\const_new_aux:Nw}
-% \begin{macrocode}
% \begin{macrocode}
-\engine_if_aleph:TF
-{
- \let_new:NN \const_new_aux:Nw \tex_chardef:D
- \const_new_aux:Nw \c_max_register_num = 65535 \scan_stop:
-}
-{
- \let_new:NN \const_new_aux:Nw \tex_mathchardef:D
- \const_new_aux:Nw \c_max_register_num = 32767 \scan_stop:
-}
-\def_new:Npn \const_new:Nn #1#2 {
- \num_compare:nNnTF {#2} > \c_minus_one
- {
- \num_compare:nNnTF {#2} > \c_max_register_num
- {\int_new:N #1 \int_set:Nn #1{#2}}
- {\chk_new_cs:N #1 \const_new_aux:Nw #1 = #2 \scan_stop: }
- }
- {\int_new:N #1 \int_set:Nn #1{#2}}
-}
+\tex_mathchardef:D \c_max_register_num = 32767 \scan_stop:
% \end{macrocode}
% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\c_minus_one}
-% \begin{macro}{\c_zero}
-% \begin{macro}{\c_one}
-% \begin{macro}{\c_two}
-% \begin{macro}{\c_three}
-% \begin{macro}{\c_four}
-% \begin{macro}{\c_six}
-% \begin{macro}{\c_seven}
-% \begin{macro}{\c_nine}
-% \begin{macro}{\c_ten}
-% \begin{macro}{\c_eleven}
-% \begin{macro}{\c_sixteen}
-% \begin{macro}{\c_thirty_two}
-% \begin{macro}{\c_hundred_one}
-% \begin{macro}{\c_twohundred_fifty_five}
-% \begin{macro}{\c_twohundred_fifty_six}
-% \begin{macro}{\c_thousand}
-% \begin{macro}{\c_ten_thousand}
-% \begin{macro}{\c_ten_thousand_one}
-% \begin{macro}{\c_ten_thousand_two}
-% \begin{macro}{\c_ten_thousand_three}
-% \begin{macro}{\c_ten_thousand_four}
-% \begin{macro}{\c_twenty_thousand}
-% And the usual constants, others are still missing. Please, make
-% every constant a real constant at least for the moment. We can
-% easily convert things in the end when we have found what
-% constants are used in critical places and what not.
-% \begin{macrocode}
- %% \tex_countdef:D \c_minus_one = 10 \scan_stop:
- %% \c_minus_one = -1 \scan_stop: %% in l3basics
- %% \tex_chardef:D \c_sixteen = 16\scan_stop: %% in l3basics
-\const_new:Nn \c_zero {0}
-\const_new:Nn \c_one {1}
-\const_new:Nn \c_two {2}
-\const_new:Nn \c_three {3}
-\const_new:Nn \c_four {4}
-\const_new:Nn \c_six {6}
-\const_new:Nn \c_seven {7}
-\const_new:Nn \c_nine {9}
-\const_new:Nn \c_ten {10}
-\const_new:Nn \c_eleven {11}
-\const_new:Nn \c_thirty_two {32}
-% \end{macrocode}
-% The next one may seem a little odd (obviously!) but is useful when
-% dealing with logical operators.
-% \begin{macrocode}
-\const_new:Nn \c_hundred_one {101}
-\const_new:Nn \c_twohundred_fifty_five {255}
-\const_new:Nn \c_twohundred_fifty_six {256}
-\const_new:Nn \c_thousand {1000}
-\const_new:Nn \c_ten_thousand {10000}
-\const_new:Nn \c_ten_thousand_one {10001}
-\const_new:Nn \c_ten_thousand_two {10002}
-\const_new:Nn \c_ten_thousand_three {10003}
-\const_new:Nn \c_ten_thousand_four {10004}
-\const_new:Nn \c_twenty_thousand {20000}
-% \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}
-%
%
% \begin{macrocode}
%</initex|package>
% \end{macrocode}
%
-% \endinput
-%
-% $Log$
-% Revision 1.17 2006/03/20 18:26:37 braams
-% Updated the copyright notice (2006) and demoted all implementation
-% sections to subsections and so on to clean up the toc for source3.tex
-%
-% Revision 1.16 2005/12/27 10:03:01 morten
-% Changed RCS information retrieval
-%
-% Revision 1.15 2005/12/06 13:41:02 morten
-% Added a few functions to ease processing with \if_case:w
-%
-% Revision 1.14 2005/12/03 12:57:36 morten
-% Minor touch-ups.
-%
-% Revision 1.13 2005/10/27 22:39:02 morten
-% Forgot to add \if_num_odd:w
-%
-% Revision 1.12 2005/10/27 22:34:26 morten
-% Added \if_num:w, \if_case:w and \or: as they really belong here.
-%
-% Revision 1.11 2005/04/06 22:36:53 braams
-% Missed one occurence of \c_max_register_int
-%
-% Revision 1.10 2005/04/06 21:38:46 morten
-% Removed dependency on l3prg and added a missing function.
-%
-% Revision 1.9 2005/04/05 22:05:38 braams
-% Renamed \c_max_regsiter_int to \c_max_register_num,
-% Fixed const_new to allow 32767 as a value for \tex_mathchardef:D
-% Added \c_ten and \c_eleven as constants
-%
-% Revision 1.8 2005/03/26 21:06:35 morten
-% Update documentation
-%
-% Revision 1.7 2005/03/22 23:21:32 morten
-% Now independent of l3int and can be used as a very primitive module.
-%
-% Revision 1.6 2005/03/16 22:36:20 braams
-% Added the tweaks necessary to be able to load with initex
-%
-% Revision 1.5 2005/03/11 21:39:47 braams
-% Fixed the use of RCS information; added \StopEventually
+% \end{implementation}
+% \PrintIndex
%
+% \endinput
diff --git a/Master/texmf-dist/source/latex/expl3/l3precom.dtx b/Master/texmf-dist/source/latex/expl3/l3precom.dtx
index 786181d93b5..6b681f1610e 100644
--- a/Master/texmf-dist/source/latex/expl3/l3precom.dtx
+++ b/Master/texmf-dist/source/latex/expl3/l3precom.dtx
@@ -1,5 +1,5 @@
% \iffalse
-%% File: l3precom.dtx Copyright (C) 1990-2006 Frank Mittelbach, LaTeX3 project
+%% File: l3precom.dtx Copyright (C) 1990-2006,2009 Frank Mittelbach, 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
@@ -17,7 +17,7 @@
%%
%% The development version of the bundle can be found at
%%
-%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/
+%% http://www.latex-project.org/svnroot/experimental/trunk/
%%
%% for those people who are interested.
%%
@@ -36,7 +36,7 @@
\RequirePackage{l3names}
%</driver|package>
%\fi
-\GetIdInfo$Id: l3precom.dtx 621 2007-09-01 20:14:19Z morten $
+\GetIdInfo$Id: l3precom.dtx 1362 2009-05-28 20:19:21Z joseph $
{L3 Experimental precompilation module}
%\iffalse
%<*driver>
@@ -44,41 +44,74 @@
\ProvidesFile{\filename.\filenameext}
[\filedate\space v\fileversion\space\filedescription]
%\iffalse
-\documentclass{l3doc}
+\documentclass[full]{l3doc}
\begin{document}
\DocInput{\filename.\filenameext}
\end{document}
%</driver>
% \fi
%
+% \title{The \textsf{l3precom} package\thanks{This file
+% has version number \fileversion, last
+% revised \filedate.}\\
+% Precompilation of complex data}
+% \author{\Team}
+% \date{\filedate}
+% \maketitle
+%
+% \begin{documentation}
+%
+% \section{Introduction}
+%
+% It is possible speed up the processing of documents when complex parts
+% of the document style file are `precompiled' and stored in a
+% separate file.
+%
% \section{Control sequence functions extended \ldots}
%
% \begin{function}{\cs_gen_sym:N |
% \cs_ggen_sym:N}
% \begin{syntax}
-% "\cs_gen_sym:N" <tlp>
+% "\cs_gen_sym:N" <tl var.>
% \end{syntax}
% These functions will generate a new control sequence name for use as a
% pointer, e.g.\ some tree structure like the LDB. The new unique name
-% is returned locally in <tlp> for further use. The names are generated
+% is returned locally in <tl var.> for further use. The names are generated
% using the roman numeral representation of some special counters
% together with a prefix of "\l*" (local) or "\g*"( global).
% \end{function}
%
-% \begin{function}{\cs_record_name:N}
+% \begin{function}{\cs_record_name:N|\cs_record_name:c}
% \begin{syntax}
% "\cs_record_name:N" <cs>
% \end{syntax}
-% Takes the <cs> and saves it in a special places for pre-compiling
+% Takes the <cs> and saves it in a special place for pre-compiling
% purposes on a file later on. All control sequences that are recorded
% with this function will be dumped by "\cs_dump:". This function is
% internally automatically used to record all symbols generated by
% "\cs_gen_sym:N" and "\cs_ggen_sym:N".
% \end{function}
%
+% \begin{function}{\cs_record_meaning:N}
+% \begin{syntax}
+% "\cs_record_meaning:N" <cs>
+% \end{syntax}
+% Takes the <cs> and saves its meaning in a special place for pre-compiling
+% purposes on a file later on. Used for tracing purposes.
+% \end{function}
+%
+% \begin{function}{\register_record_name:N}
+% \begin{syntax}
+% "\register_record_name:N" <register>
+% \end{syntax}
+% Takes the <register> and saves it in a special places for pre-compiling
+% purposes on a file later on. All control sequences that are recorded
+% with this function will be dumped by "\cs_dump:".
+% \end{function}
+%
% \begin{function}{\cs_load_dump:n}
% \begin{syntax}
-% "\cs_load_dump:n" "{" <file name> "}"
+% "\cs_load_dump:n" \Arg{file name}
% \end{syntax}
% Loads and executes the file <file name> if found. Then scans
% further ignoring everything until finding "\cs_dump:" where normal
@@ -93,14 +126,22 @@
% by the argument in "\cs_load_dump:n". Dumping means that for every
% <cs> recorded by "\cs_record_name:N" a line
% \begin{quote}
-% "\def:Npn" <cs> "{" <current meaning of cs> "}"
+% "\cs_set_nopar:Npn" <cs> \Arg{current meaning of cs}
% \end{quote}
% is written to this file. This means that when loading the file the
% definitions of all these <cs>'s are directly available.
% \end{function}
%
+% \begin{function}{\dumpLaTeXstate}
+% \begin{syntax}
+% "\dumpLaTeXstate" \Arg{file}
+% \end{syntax}
+% This function is used to write control sequences
+% and registers, together with their meaning or value in the <file>|.dmp|
+% file.
+% \end{function}
%
-% \subsection{Internal variables}
+% \section{Internal variables}
%
% \begin{variable}{\g_gen_sym_num |
% \g_ggen_sym_num} Holds the number of the last
@@ -113,12 +154,28 @@
%
% \begin{variable}{\c_cs_dump_stream}
% Output stream used for writing out the definitions of the
-% recorded <tlp>.
+% recorded <tl var.>.
% \end{variable}
%
-% \StopEventually{}
+% \begin{variable}{\g_cs_dump_name_tl}
+% Used to store the name of the file to dump to.
+% \end{variable}
%
-% \subsection{The Implementation}
+% \begin{variable}{\g_cs_trace_seq}
+% Sequence which holds the control sequence names that are to
+% be dumped with their corresponding meanings. Used for tracing purposes.
+% \end{variable}
+%
+% \begin{variable}{\g_register_trace_seq}
+% Sequence holding the register names to be dumped with their
+% corresponding values. Used for tracing purposes.
+% \end{variable}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3precom} implementation}
%
% We start by ensuring that the required packages are loaded.
% \begin{macrocode}
@@ -130,10 +187,6 @@
%<package>\RequirePackage{l3int}
% \end{macrocode}
%
-% It might speed up the processing of documents when certain parts
-% of the document style file are `precompiled' and stored in a
-% separate file.
-%
% \begin{macro}{\c_cs_dump_stream}
% We need to allocate an output stream in order to be able to write
% the precompiled code out.
@@ -147,11 +200,11 @@
% \end{macro}
%
%
-% \begin{macro}{\g_cs_dump_name_tlp}
-% This \m{tlp} is used to store the name of the file.
+% \begin{macro}{\g_cs_dump_name_tl}
+% This \m{tl var.}~is used to store the name of the file.
%
% \begin{macrocode}
-\tlp_new:Nn\g_cs_dump_name_tlp{}
+\tl_new:Nn\g_cs_dump_name_tl{}
% \end{macrocode}
% \end{macro}
%
@@ -165,25 +218,23 @@
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\cs_record_name:N}
-% \begin{macro}{\cs_record_name:c}
+% \begin{macro}{\cs_record_name:N,\cs_record_name:c}
% These functions mark a control sequence for dumping into a
% precompiled style.
%
% When the {\sf trace} `module' is included in the code we also write
% information about the control sequence into a |.dmp| file.
% \begin{macrocode}
-\def_new:Npn\cs_record_name:N#1{
+\cs_new_nopar:Npn\cs_record_name:N#1{
%<*trace>
\seq_gput_left:Nn
\g_cs_trace_seq#1
%</trace>
\seq_gput_left:Nn
\g_cs_dump_seq#1}
-\def_new:Npn\cs_record_name:c{\exp_args:Nc\cs_record_name:N}
+\cs_generate_variant:Nn \cs_record_name:N {c}
% \end{macrocode}
% \end{macro}
-% \end{macro}
%
%
% \begin{macro}{\cs_dump:}
@@ -195,42 +246,42 @@
% Before dumping, we write a message to the terminal informing the
% `user' of this fact.
% \begin{macrocode}
-\def_new:Npn\cs_dump:{
-\iow_expanded_term:n{Precompiling~style~into~(\g_cs_dump_name_tlp)}
-\iow_open:Nn\c_cs_dump_stream{\g_cs_dump_name_tlp}
+\cs_new_nopar:Npn\cs_dump:{
+\iow_term:x{Precompiling~style~into~(\g_cs_dump_name_tl)}
+\iow_open:Nn\c_cs_dump_stream{\g_cs_dump_name_tl}
% \end{macrocode}
% The first thing we write on a `dump' file is a command that
% allows us to use |*| in control sequences. We also need to be
% able to write to (and read from) the file internal control
% sequences, containing |_| and |:|.
% \begin{macrocode}
-\iow_expanded:Nn\c_cs_dump_stream
+\iow_now:Nx\c_cs_dump_stream
{\group_begin:
-\tex_catcode:D`\token_to_string:N\*=11\scan_stop:
-\token_to_string:N\CodeStart
+\tex_catcode:D`\token_to_str:N\*=11\scan_stop:
+\token_to_str:N\ExplSyntaxOn
}
\seq_map_inline:Nn
\g_cs_dump_seq
{\tex_message:D{.}
-\iow_expanded:Nn\c_cs_dump_stream
+\iow_now:Nx\c_cs_dump_stream
% \end{macrocode}
-% We use a direct |\gdef:Npn| to disable any type of local/global
+% We use a direct |\cs_gset_nopar:Npn| to disable any type of local/global
% check on the pointers.
% \begin{macrocode}
- {\exp_not:n{\gdef:Npn ##1}
- {\tlp_to_str:N##1}}
+ {\exp_not:n{\cs_gset_nopar:Npn ##1}
+ {\tl_to_str:N##1}}
}
% \end{macrocode}
% We also need to remember the current values of the
% |\g_gen_sym_num| and |\g_ggen_sym_num| counters to allow
% further updates after a database was dumped.
% \begin{macrocode}
-\iow_expanded:Nn \c_cs_dump_stream {\exp_not:n{\num_gset:Nn
+\iow_now:Nx \c_cs_dump_stream {\exp_not:n{\num_gset:Nn
\g_gen_sym_num}
{\num_use:N\g_gen_sym_num}^^J
\exp_not:n{\num_gset:Nn \g_ggen_sym_num}
{\num_use:N\g_ggen_sym_num}}
-\iow_expanded:Nn
+\iow_now:Nx
\c_cs_dump_stream
{\group_end:}
\iow_close:N\c_cs_dump_stream
@@ -246,14 +297,14 @@
% continues and a subsequent |\cs_dump:| command will then create the
% dump file.
% \begin{macrocode}
-\def_new:Npn\cs_load_dump:n#1{
+\cs_new_nopar:Npn\cs_load_dump:n#1{
\file_not_found:nTF{#1.cmp}
%<*precompile>
-{\tlp_gset:Nn\g_cs_dump_name_tlp{#1.cmp}}
+{\tl_gset:Nn\g_cs_dump_name_tl{#1.cmp}}
%</precompile>
%<-precompile> {\tex_errmessage:D{Cannot~ dump~ with~ this~ format}}
{\input{#1.cmp}
-\let:NN\cs_dump:\fi:
+\cs_set_eq:NN\cs_dump:\fi:
\if_false:}}
% \end{macrocode}
% \end{macro}
@@ -279,28 +330,28 @@
% is locally stored in the token that was passed in |#1|.
%
% \begin{macrocode}
-\def_new:Npn\cs_gen_sym:N#1{
+\cs_new_nopar:Npn\cs_gen_sym:N#1{
\num_gincr:N\g_gen_sym_num
-\tlp_set:Nc#1{l*\tex_romannumeral:D\num_use:N\g_gen_sym_num}
+\tl_set:Nc#1{l*\tex_romannumeral:D\num_use:N\g_gen_sym_num}
%<*precompile>
-\exp_after:NN\cs_record_name:N#1
+\exp_after:wN\cs_record_name:N#1
%</precompile>
% \end{macrocode}
% We still want to define the initial value for the new symbol
% globally to make sure that during compilation something is
% written to the output file.
% \begin{macrocode}
-\exp_after:NN\tlp_clear_new:N#1}
+\exp_after:wN\tl_clear_new:N#1}
% \end{macrocode}
% The global variant
% \begin{macrocode}
-\def_new:Npn\cs_ggen_sym:N#1{
+\cs_new_nopar:Npn\cs_ggen_sym:N#1{
\num_gincr:N\g_ggen_sym_num
-\tlp_set:Nc#1{g*\tex_romannumeral:D\num_use:N\g_ggen_sym_num}
+\tl_set:Nc#1{g*\tex_romannumeral:D\num_use:N\g_ggen_sym_num}
%<*precompile>
-\exp_after:NN\cs_record_name:N#1
+\exp_after:wN\cs_record_name:N#1
%</precompile>
-\exp_after:NN\tlp_clear_new:N#1}
+\exp_after:wN\tl_clear_new:N#1}
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -332,7 +383,7 @@
% \begin{macro}{\cs_record_meaning:N}
% Function marking a control sequence for dumping with meaning.
% \begin{macrocode}
-\def:Npn\cs_record_meaning:N#1{
+\cs_set_nopar:Npn\cs_record_meaning:N#1{
\seq_gput_left:Nn
\g_cs_trace_seq#1}
% \end{macrocode}
@@ -341,7 +392,7 @@
% \begin{macro}{\register_record_name:N}
% Function marking a register for dumping with value.
% \begin{macrocode}
-\def:Npn\register_record_name:N#1{
+\cs_set_nopar:Npn\register_record_name:N#1{
\seq_gput_left:Nn
\g_register_trace_seq#1}
% \end{macrocode}
@@ -358,23 +409,23 @@
% for primitive registers this part of the code will dump nothing
% unless |\register_record_name:N| is explicitly used.
% \begin{macrocode}
-\def_new:Npn\dumpLaTeXstate#1{
- \iow_expanded_term:n{Dumping~commands~into~(#1.dmp)}
+\cs_new_nopar:Npn\dumpLaTeXstate#1{
+ \iow_term:x{Dumping~commands~into~(#1.dmp)}
\iow_open:Nn\c_cs_dump_stream{#1.dmp}
\seq_map_inline:Nn
\g_cs_trace_seq
{\tex_message:D{.}
- \iow_expanded:Nn\c_cs_dump_stream
- {\token_to_string:N##1~
+ \iow_now:Nx\c_cs_dump_stream
+ {\token_to_str:N##1~
\token_to_meaning:N##1}
}
\tex_message:D{~registers}
\seq_map_inline:Nn
\g_register_trace_seq
{\tex_message:D{.}
- \iow_expanded:Nn\c_cs_dump_stream
- {\token_to_string:N##1
- \the_internal:D##1}
+ \iow_now:Nx\c_cs_dump_stream
+ {\token_to_str:N##1
+ \toks_use:N##1}
}
\tex_message:D{~finished}
}
@@ -391,26 +442,7 @@
%</showmemory>
% \end{macrocode}
%
-% \endinput
-%
-% $Log$
-% Revision 1.7 2006/03/20 18:26:37 braams
-% Updated the copyright notice (2006) and demoted all implementation
-% sections to subsections and so on to clean up the toc for source3.tex
-%
-% Revision 1.6 2005/12/27 16:03:21 morten
-% Changed RCS information retrieval plus a few name changes
-%
-% Revision 1.5 2005/04/12 12:06:30 morten
-% Fixed the use of fake integers (now known as "num")
-%
-% Revision 1.4 2005/03/16 22:36:14 braams
-% Added the tweaks necessary to be able to load with initex
-%
-% Revision 1.3 2005/03/11 21:51:50 braams
-% Just another small mistake to be corrected
-%
-% Revision 1.2 2005/03/11 21:21:01 braams
-% Added the header for CVS public read access and fixed the
-% use of RCS data
+% \end{implementation}
+% \PrintIndex
%
+% \endinput
diff --git a/Master/texmf-dist/source/latex/expl3/l3prg.dtx b/Master/texmf-dist/source/latex/expl3/l3prg.dtx
index b99caf822d7..ca50697fd0f 100644
--- a/Master/texmf-dist/source/latex/expl3/l3prg.dtx
+++ b/Master/texmf-dist/source/latex/expl3/l3prg.dtx
@@ -1,5 +1,5 @@
% \iffalse
-%% File: l3prg.dtx Copyright (C) 2005-2006 LaTeX3 project
+%% File: l3prg.dtx Copyright (C) 2005-2009 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
@@ -17,7 +17,7 @@
%%
%% The development version of the bundle can be found at
%%
-%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/
+%% http://www.latex-project.org/svnroot/experimental/trunk/
%%
%% for those people who are interested.
%%
@@ -36,7 +36,7 @@
\RequirePackage{l3names}
%</driver|package>
%\fi
-\GetIdInfo$Id: l3prg.dtx 768 2008-08-05 19:45:06Z morten $
+\GetIdInfo$Id: l3prg.dtx 1365 2009-05-31 17:26:17Z mittelba $
{L3 Experimental control structures}
%\iffalse
%<*driver>
@@ -44,9 +44,9 @@
\ProvidesFile{\filename.\filenameext}
[\filedate\space v\fileversion\space\filedescription]
%\iffalse
-\documentclass{l3doc}
+\documentclass[full]{l3doc}
\begin{document}
-\DocInput{\filename.\filenameext}
+\DocInput{l3prg.dtx}
\end{document}
%</driver>
% \fi
@@ -60,167 +60,121 @@
% \date{\filedate}
% \maketitle
%
+% \begin{documentation}
%
-% \section{Control structures}
+% \section{Conditionals and logical operations}
%
-% \subsection{Choosing modes}
+% 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, e.g., text as input in a function comparing integers.
%
-% \begin{function}{\mode_if_vertical_p:|
-% \mode_if_vertical:TF |
-% \mode_if_vertical:T |
-% \mode_if_vertical:F
-% }
-% \begin{syntax}
-% "\mode_if_vertical:TF" "{"<true code>"}" "{"<false code>"}"
-% \end{syntax}
-% Determines if \TeX{} is in vertical mode or not and executes either
-% <true code> or <false code> accordingly.
-% \end{function}
-%
-% \begin{function}{\mode_if_horizontal_p:|
-% \mode_if_horizontal:TF |
-% \mode_if_horizontal:T |
-% \mode_if_horizontal:F
-% }
-% \begin{syntax}
-% "\mode_if_horizontal:TF" "{"<true code>"}" "{"<false code>"}"
-% \end{syntax}
-% Determines if \TeX{} is in horizontal mode or not and executes either
-% <true code> or <false code> accordingly.
-% \end{function}
-%
-%
-% \begin{function}{
-% \mode_if_inner_p:|
-% \mode_if_inner:TF|
-% \mode_if_inner:T|
-% \mode_if_inner:F
-% }
-% \begin{syntax}
-% "\mode_if_inner:TF" "{"<true code>"}" "{"<false code>"}"
-% \end{syntax}
-% Determines if \TeX{} is in inner mode or not and executes either
-% <true code> or <false code> accordingly.
-% \end{function}
-%
-% \begin{function}{
-% \mode_if_math:TF|
-% \mode_if_math:T|
-% \mode_if_math:F|
-% }
-% \begin{syntax}
-% "\mode_if_math:TF" "{"<true code>"}" "{"<false code>"}"
-% \end{syntax}
-% Determines if \TeX{} is in math mode or not and executes either
-% <true code> or <false code> accordingly.
-% \begin{texnote}
-% This version will choose the right branch even at the beginning of
-% an alignment cell.
-% \end{texnote}
-% \end{function}
-%
-%
-% \subsubsection{Alignment safe grouping and scanning}
-%
-% \begin{function}{\scan_align_safe_stop:}
-% \begin{syntax}
-% "\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}
+%
%
+% \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
%
-% \begin{function}{\group_align_safe_begin:|
-% \group_align_safe_end:}
-% \begin{syntax}
-% "\group_align_safe_begin:" <...> "\group_align_safe_end:"
-% \end{syntax}
-% Encloses <...> inside a group but is safe inside an alignment cell.
-% See the implementation of |\peek_token_generic:NNTF| for an
-% application.
-% \end{function}
%
%
-% \subsection{Producing $n$ copies}
-%
-% There are often several different requirements for producing
-% multiple copies of something. Sometimes one might want to produce a
-% number of identical copies of a sequence of tokens whereas at other
-% times the goal is to simulate a for loop as known from most real
-% programming languages.
%
-% \begin{function}{\prg_replicate:nn }
-% \begin{syntax}
-% "\prg_replicate:nn" "{" <number> "}" "{" <arg> "}"
-% \end{syntax}
-% Creates <number> copies of <arg>. Expandable.
-% \end{function}
%
%
-% \begin{function}{\prg_stepwise_function:nnnN}
-% \begin{syntax}
-% "\prg_stepwise_function:nnnN" "{"<start>"}" "{"<step>"}"
-% "{"<end>"}" <function>
-% \end{syntax}
-% This function performs <action> once for each step starting at
-% <start> and ending once <end> is passed. <function> is placed
-% directly in front of a brace group holding the current number so it
-% should usually be a function taking one argument. The
-% |\prg_stepwise_function:nnnN| function is expandable.
-% \end{function}
%
-% \begin{function}{\prg_stepwise_inline:nnnn}
-% \begin{syntax}
-% "\prg_stepwise_inline:nnnn" "{"<start>"}" "{"<step>"}" "{"<end>"}"
-% "{"<action>"}"
-% \end{syntax}
-% Same as |\prg_stepwise_function:nnnN| except here <action> is
-% performed each time with |##1| as a placeholder for the number
-% currently being tested. This function is not expandable and it is
-% nestable.
-% \end{function}
+% \section{Defining a set of conditional functions}
%
-% \begin{function}{\prg_stepwise_variable:nnnNn}
-% \begin{syntax}
-% "\prg_stepwise_variable:nnnn" "{"<start>"}" "{"<step>"}" "{"<end>"}"
-% <temp-var> "{"<action>"}"
-% \end{syntax}
-% Same as |\prg_stepwise_inline:nnnn| except here the current value is
-% stored in <temp-var> and the programmer can use it in <action>. This
-% function is not expandable.
+% \begin{function}{ \prg_return_true: |
+% \prg_return_false: }
+% These functions exit conditional processing when used in
+% conjunction with the generating functions listed below.
% \end{function}
%
+% \begin{function}{%
+% \prg_set_conditional:Nnn |
+% \prg_set_conditional:Npnn |
+% \prg_new_conditional:Nnn |
+% \prg_new_conditional:Npnn |
+% \prg_set_protected_conditional:Nnn |
+% \prg_set_protected_conditional:Npnn |
+% \prg_new_protected_conditional:Nnn |
+% \prg_new_protected_conditional:Npnn |
+% }
+% \begin{syntax}
+% "\prg_set_conditional:Nnn" <test> <conds> <code>
+% "\prg_set_conditional:Npnn" <test> <param> <conds> <code>
+% \end{syntax}
+% This defines a conditional \meta{base function} which upon
+% evaluation using |\prg_return_true:| and |\prg_return_false:| to
+% finish branches,
+% returns a state. Currently the states are either \meta{true} or
+% \meta{false} although this can change as more states may be
+% introduced, say an \meta{error} state. \meta{conds} is a comma
+% separated list possibly consisting of |p| for denoting a predicate function
+% returning the boolean \meta{true} or \meta{false} values and |TF|,
+% |T| and |F| for the functions that act on the tokens following in
+% the input stream. The |:Nnn| form implicitly determines the number
+% of arguments from the function being defined whereas the |:Npnn|
+% form expects a primitive parameter text.
+%
+% An example can easily clarify matters here:
+% \begin{verbatim}
+% \prg_set_conditional:Nnn \foo_if_bar:NN {p,TF,T} {
+% \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}
%
%
-% \subsection{Conditionals and logical operations}
%
%
-% \LaTeX3 has two primary forms of conditional flow processing. The
-% one type deals with the truth value of a test directly as in
-% "\cs_free:NTF" where you test if a control sequence was undefined
-% and then execute either the \m{true} or \m{false} part depending on
-% the result and after exiting the underlying "\if...\fi:" structure.
-% The second type has to do with predicate functions like
-% "\cs_free_p:N" which return either "\c_true" or "\c_false" to be
-% used in testing with "\if:w".
%
+% \section{The boolean data type}
%
% This section describes a boolean data type which is closely
-% connected to both parts as sometimes you want to execute some code
-% depending on the value of a switch (e.g.,~draft/final) and other
-% times you perhaps want to use it as a predicate function in an
-% "\if:w" test. Parsing "\iffalse"
-% and "\iftrue" tokens can be quite tricky at times so the easiest is to
-% simply let a boolean either be "\c_true" or "\c_false". This
-% also means we get the logical operations And, Or, and Not which can
-% then be used on both the boolean type and predicate functions. All
-% functions by the name |\predicate| are expandable and expect the
-% input to also be fully expandable. More generic constructs do not
-% contain |predicate| in their names.
-%
-%
-% \subsubsection{The boolean data type}
+% connected to conditional processing as sometimes you want to
+% execute some code depending on the value of a switch
+% (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, etc.\ which can then be used on
+% both the boolean type and predicate functions.
+%
+% All conditonal "\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 |
@@ -230,7 +184,7 @@
% "\bool_new:N" <bool>
% \end{syntax}
% Define a new boolean variable. The initial value is <false>. A
-% boolean is actually just either "\c_true" or "\c_false".
+% boolean is actually just either "\c_true_bool" or "\c_false_bool".
% \end{function}
%
% \begin{function}{%
@@ -246,7 +200,7 @@
% \begin{syntax}
% "\bool_gset_false:N" <bool>
% \end{syntax}
-% Set <bool> either true or false. We can also do this globally.
+% Set <bool> either <true> or <false>. We can also do this globally.
% \end{function}
%
%
@@ -268,120 +222,145 @@
% \end{function}
%
% \begin{function}{%
-% \bool_if:NTF |
-% \bool_if:NT |
-% \bool_if:NF |
-% \bool_if_p:N |
+% \bool_if_p:N / (EXP) |
+% \bool_if:N / (TF)(EXP) |
+% \bool_if_p:c / (EXP) |
+% \bool_if:c / (TF)(EXP) |
%
% }
% \begin{syntax}
-% "\bool_if:NTF" <bool> "{"\m{true}"}" "{"\m{false}"}" \\
+% "\bool_if:NTF" <bool> \Arg{true} \Arg{false} \\
% "\bool_if_p:N" <bool>
% \end{syntax}
-% Test the truth value of the boolean and execute the \m{true} or
+% Test the truth value of <bool> and execute the \m{true} or
% \m{false} code. "\bool_if_p:N" is a predicate function for use in
-% "\if:w" tests.
+% "\if_predicate:w" tests or "\bool_if:nTF"-type functions described below.
% \end{function}
%
% \begin{function}{%
-% \bool_whiledo:NT |
-% \bool_whiledo:NF |
-% \bool_dowhile:NT |
-% \bool_dowhile:NF |
+% \bool_while_do:Nn |
+% \bool_while_do:cn |
+% \bool_until_do:Nn |
+% \bool_until_do:cn |
+% \bool_do_while:Nn |
+% \bool_do_while:cn |
+% \bool_do_until:Nn |
+% \bool_do_until:cn |
%
% }
% \begin{syntax}
-% "\bool_whiledo:NT" <bool> "{"\m{true}"}" \\
-% "\bool_whiledo:NF" <bool> "{"\m{false}"}" \\
+% "\bool_while_do:Nn" <bool> \Arg{code} \\
+% "\bool_until_do:Nn" <bool> \Arg{code} \\
% \end{syntax}
-% The "T" versions execute the \m{true} code as long as the boolean is
-% true and the "F" versions execute the \m{false} code as long as the
-% boolean is false. The "whiledo" functions execute the body after
-% testing the boolean and the "dowhile" functions executes the body
+% The `while' versions execute <code> as long as the boolean is
+% true and the `until' versions execute <code> as long as the
+% boolean is false. The "while_do" functions execute the body after
+% testing the boolean and the "do_while" functions executes the body
% first and then tests the boolean.
% \end{function}
%
%
-% \begin{function}{%
-% \l_tmpa_bool |
-% \g_tmpa_bool |
-%
-% }
-% \begin{syntax}
-% \end{syntax}
-% Reserved booleans.
-% \end{function}
%
-% \subsubsection{Logical operations}
+% \section{Boolean expressions}
%
-% Somewhat related to the subject of conditional flow processing is
-% logical operators as these deal with \m{true} and \m{false}
-% statements which is precisely what the predicate functions return.
+% 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 "&&", "||" and "!". In
+% addition to this, parentheses can be used to isolate
+% sub-expressions. For example,
+% \begin{verbatim}
+% \intexpr_compare_p:n {1=1} &&
+% (
+% \intexpr_compare_p:n {2=3} ||
+% \intexpr_compare_p:n {4=4} ||
+% \intexpr_compare_p:n {1=\error} % is skipped
+% ) &&
+% !(\intexpr_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 anymore, the remainding tests within the current group
+% are skipped.
%
% \begin{function}{%
-% \predicate_p:n |
-% \predicate:nTF |
-% \predicate:nT |
-% \predicate:nF |
+% \bool_if_p:n / (EXP) |
+% \bool_if:n / (TF)(EXP) |
% }
% \begin{syntax}
-% "\predicate:nTF" "{"<list of predicates>"}" "{"<true>"}"
-% "{"<false>"}"
+% "\bool_if:nTF" \Arg{boolean expression} \Arg{true}
+% \Arg{false}
% \end{syntax}
-% The functions evaluate the truth value of \m{list of predicates}
+% The functions evaluate the truth value of \m{boolean expression}
% where each predicate is separated by \verb+&&+ or \verb+||+
-% denoting logical And and Or functions. Minimal evaluation is
-% carried out so that whenever a truth value cannot be changed
-% anymore, the remainding tests are not carried out. Hence
+% denoting logical `And' and `Or' functions. "(" and ")" denote
+% grouping of sub-expressions while "!" is used to as a prefix to
+% either negate a single expression or a group. Hence
% \begin{verbatim}
-% \predicate_p:n{
-% \int_compare_p:nNn 1=1 &&
-% \predicate_p:n {
-% \int_compare_p:nNn 2=3 ||
-% \int_compare_p:nNn 4=4 ||
-% \int_compare_p:nNn 1=\error % is skipped
-% } &&
-% \int_compare_p:nNn 2=2
+% \bool_if_p:n{
+% \intexpr_compare_p:n {1=1} &&
+% (
+% \intexpr_compare_p:n {2=3} ||
+% \intexpr_compare_p:n {4=4} ||
+% \intexpr_compare_p:n {1=\error} % is skipped
+% ) &&
+% !(\intexpr_compare_p:n {2=4})
% }
% \end{verbatim}
-% returns \meta{true}.
+% from above returns \meta{true}.
+%
+% Logical operators take higher precedence the later in the predicate they
+% appear. ``<x> "||" <y> "&&" <z>'' is interpreted as the equivalent of
+% ``<x> \textsc{or} [~<y> \textsc{and} <z>~]'' (but now we have grouping
+% you shouldn't write this sort of thing, anyway).
% \end{function}
%
%
%
+% \begin{function}{ \bool_not_p:n / (EXP) }
+% \begin{syntax}
+% "\bool_not_p:n" \Arg{boolean expression}
+% \end{syntax}
+% Longhand for writing "!("\meta{boolean expression}")" within a boolean
+% expression. Might not stick around.
+% \end{function}
%
-% \begin{function}{%
-% \predicate_not_p:n |
-% }
+% \begin{function}{ \bool_xor_p:nn / (EXP) }
% \begin{syntax}
-% "\predicate_not_p:n" "{"<list of predicates>"}"
+% "\bool_xor_p:nn" \Arg{boolean expression} \Arg{boolean expression}
% \end{syntax}
-% "\predicate_not_p:n"
-% reverses the truth value of its argument. Thus
-% \begin{quote}
-% "\prg_if_predicate_not_p:n {\prg_if_predicate_not_p:n {\c_true}}"
-% \end{quote}
-% ultimately returns \m{true}.
+% Implements an `exclusive or' operation between two boolean
+% expressions. There is no infix operation for this.
% \end{function}
%
-% \subsubsection{Case switches}
+% \begin{function}{\bool_set:Nn |\bool_set:cn |\bool_gset:Nn |\bool_gset:cn}
+% \begin{syntax}
+% "\bool_set:Nn" <bool> \Arg{boolean expression}
+% \end{syntax}
+% Sets <bool> to the logical outcome of evaluating <boolean expression>.
+% \end{function}
%
%
-% \begin{function}{
-% \prg_case_int:nnn |
+% \section{Case switches}
%
-% }
+%
+% \begin{function}{ \prg_case_int:nnn / (EXP) }
% \begin{syntax}
-% "\prg_case_int:nnn" "{"<integer expr>"}" "{"
-% " {"\m{integer expr$\sb 1$}"}""{"\m{code$\sb 1$}"}""{"\m{integer expr$\sb 2$}"}""{"\m{code$\sb 2$}"}"\\
-% " ...""{"\m{integer expr$\sb n$}"}""{"\m{code$\sb n$}"}"\\
-% "}" "{"\m{else case}"}"
+% "\prg_case_int:nnn" \Arg{integer expr} "{"
+% ~~\Arg{integer expr 1} \Arg{code 1}\\
+% ~~\Arg{integer expr 2} \Arg{code 2}\\
+% ~~\dots\\
+% ~~\Arg{integer expr\,$\sb n$} \Arg{code\,$\sb n$}\\
+% "}" \Arg{else case}
% \end{syntax}
% This function evaluates the first \meta{integer expr} and then compares it
% to the values found in the list. Thus the expression
% \begin{verbatim}
-% \prg_case:nnn{2*5}{
+% \prg_case_int:nnn{2*5}{
% {5}{Small} {4+6}{Medium} {-2*10}{Negative}
% }{Other}
% \end{verbatim}
@@ -396,29 +375,27 @@
% from within the function are left over.
% \end{function}
%
-% \begin{function}{
-% \prg_case_dim:nnn |
-%
-% }
+% \begin{function}{ \prg_case_dim:nnn / (EXP) }
% \begin{syntax}
-% "\prg_case_int:nnn" "{"<dim expr>"}" "{"
-% " {"\m{dim expr$\sb 1$}"}""{"\m{code$\sb 1$}"}""{"\m{dim expr$\sb 2$}"}""{"\m{code$\sb 2$}"}"\\
-% " ...""{"\m{dim expr$\sb n$}"}""{"\m{code$\sb n$}"}"\\
-% "}" "{"\m{else case}"}"
+% "\prg_case_int:nnn" \Arg{dim expr} "{"\\
+% ~~\Arg{dim expr 1} \Arg{code 1}\\
+% ~~\Arg{dim expr 2} \Arg{code 2}\\
+% ~~"..."\\
+% ~~\Arg{dim expr\,$\sb n$} \Arg{code\,$\sb n$}\\
+% "}" \Arg{else case}
% \end{syntax}
% This function works just like |\prg_case_int:nnn| except it works
% for \meta{dim} registers.
% \end{function}
%
-% \begin{function}{
-% \prg_case_str:nnn |
-%
-% }
+% \begin{function}{ \prg_case_str:nnn / (EXP) }
% \begin{syntax}
-% "\prg_case_str:nnn" "{"<string>"}" "{"
-% " {"\m{string$\sb 1$}"}""{"\m{code$\sb 1$}"}""{"\m{string$\sb 2$}"}""{"\m{code$\sb 2$}"}"\\
-% " ...""{"\m{string$\sb n$}"}""{"\m{code$\sb n$}"}"\\
-% "}" "{"\m{else case}"}"
+% "\prg_case_str:nnn" \Arg{string} "{" \\
+% ~~\Arg{string 1} \Arg{code 1}\\
+% ~~\Arg{string 2} \Arg{code 2}\\
+% ~~"..."\\
+% ~~\Arg{string\,$\sb n$} \Arg{code,$\sb n$}\\
+% "}" \Arg{else case}
% \end{syntax}
% This function works just like |\prg_case_int:nnn| except it
% compares strings. Each string is evaluated fully using \texttt{x}
@@ -429,45 +406,169 @@
% \texttt{f} style expansion can take place cleanly, i.e., no tokens
% from within the function are left over.
% \end{function}
-%
-% \subsubsection{Generic loops}
%
+% \begin{function}{ \prg_case_tl:Nnn / (EXP) }
+% \begin{syntax}
+% "\prg_case_tl:Nnn" <tl var.> "{"
+% ~~<tl var.\ 1> \Arg{code 1} <tl var.\ 2> \Arg{code 2} "..." <tl var.\,$\sb n$> \Arg{code\,$\sb n$}\\
+% "}" \Arg{else case}
+% \end{syntax}
+% This function works just like |\prg_case_int:nnn| except it
+% compares token list variables.
%
-% \begin{function}{
-% \prg_whiledo:nT |
-% \prg_whiledo:nF |
-% \prg_dowhile:nT |
-% \prg_dowhile:nF |
+% The function is expandable\footnote{Provided you use pdfTeX v1.30 or
+% later} and is written in such a way that
+% \texttt{f} style expansion can take place cleanly, i.e., no tokens
+% from within the function are left over.
+% \end{function}
+%
+% \section{Generic loops}
%
-% }
+%
+% \begin{function}{ \bool_while_do:nn |
+% \bool_until_do:nn |
+% \bool_do_while:nn |
+% \bool_do_until:nn }
% \begin{syntax}
-% "\prg_whiledo:nT" "{"<test>"}" "{"\m{true}"}" \\
-% "\prg_whiledo:nF" "{"<test>"}" "{"\m{false}"}"
+% "\bool_while_do:nn" \Arg{boolean expression} \Arg{code} \\
+% "\bool_until_do:nn" \Arg{boolean expression} \Arg{code}
% \end{syntax}
-% The "T" versions execute the \m{true} code as long as <test> is
-% true and the "F" versions execute the \m{false} code as long as
-% <test> is false. The "whiledo" functions execute the body after
-% testing the boolean and the "dowhile" functions executes the body
-% first and then tests the boolean. For the "T" versions, <test>
-% should end with a function executing only the \meta{true} code for
-% some test such as |\tlp_if_eq:NNT|. Similarly the "F" types should
-% end with |\tlp_if_eq:NNF|.
+% The `while' versions execute the code as long as <boolean
+% expression> is true and the `until' versions execute <code> as long
+% as <boolean expression> is false. The "while_do" functions execute
+% the body after testing the boolean and the "do_while" functions
+% executes the body first and then tests the boolean.
% \end{function}
%
-% \subsection{Sorting}
+% \section{Choosing modes}
+%
+% \begin{function}{ \mode_if_vertical_p: / (EXP)|
+% \mode_if_vertical: / (TF)(EXP) }
+% \begin{syntax}
+% "\mode_if_vertical:TF" \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Determines if \TeX{} is in vertical mode or not and executes either
+% <true code> or <false code> accordingly.
+% \end{function}
+%
+% \begin{function}{ \mode_if_horizontal_p: / (EXP)|
+% \mode_if_horizontal: / (TF)(EXP) }
+% \begin{syntax}
+% "\mode_if_horizontal:TF" \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Determines if \TeX{} is in horizontal mode or not and executes either
+% <true code> or <false code> accordingly.
+% \end{function}
+%
+%
+% \begin{function}{
+% \mode_if_inner_p: / (EXP)|
+% \mode_if_inner: / (TF)(EXP) }
+% \begin{syntax}
+% "\mode_if_inner:TF" \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Determines if \TeX{} is in inner mode or not and executes either
+% <true code> or <false code> accordingly.
+% \end{function}
+%
+% \begin{function}{
+% \mode_if_math_p: /(EXP) |
+% \mode_if_math: / (TF)(EXP) }
+% \begin{syntax}
+% "\mode_if_math:TF" \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Determines if \TeX{} is in math mode or not and executes either
+% <true code> or <false code> accordingly.
+% \begin{texnote}
+% This version will choose the right branch even at the beginning of
+% an alignment cell.
+% \end{texnote}
+% \end{function}
+%
+%
+% \section{Alignment safe grouping and scanning}
+%
+% \begin{function}{\scan_align_safe_stop:}
+% \begin{syntax}
+% "\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}{\group_align_safe_begin:|
+% \group_align_safe_end:}
+% \begin{syntax}
+% "\group_align_safe_begin:" <...> "\group_align_safe_end:"
+% \end{syntax}
+% Encloses <...> inside a group but is safe inside an alignment cell.
+% See the implementation of |\peek_token_generic:NNTF| for an
+% application.
+% \end{function}
+%
+%
+% \section{Producing $n$ copies}
+%
+% There are often several different requirements for producing
+% multiple copies of something. Sometimes one might want to produce a
+% number of identical copies of a sequence of tokens whereas at other
+% times the goal is to simulate a for loop as known from most real
+% programming languages.
+%
+% \begin{function}{\prg_replicate:nn / (EXP) }
+% \begin{syntax}
+% "\prg_replicate:nn" \Arg{number} \Arg{arg}
+% \end{syntax}
+% Creates <number> copies of <arg>. Note that it is expandable.
+% \end{function}
+%
+%
+% \begin{function}{\prg_stepwise_function:nnnN / (EXP) }
+% \begin{syntax}
+% "\prg_stepwise_function:nnnN" \Arg{start} \Arg{step}
+% \Arg{end} <function>
+% \end{syntax}
+% This function performs <action> once for each step starting at
+% <start> and ending once <end> is passed. <function> is placed
+% directly in front of a brace group holding the current number so it
+% should usually be a function taking one argument.
+% \end{function}
+%
+% \begin{function}{\prg_stepwise_inline:nnnn}
+% \begin{syntax}
+% "\prg_stepwise_inline:nnnn" \Arg{start} \Arg{step} \Arg{end}
+% \Arg{action}
+% \end{syntax}
+% Same as |\prg_stepwise_function:nnnN| except here <action> is
+% performed each time with |##1| as a placeholder for the number
+% currently being tested. This function is not expandable and it is
+% nestable.
+% \end{function}
+%
+% \begin{function}{\prg_stepwise_variable:nnnNn}
+% \begin{syntax}
+% "\prg_stepwise_variable:nnnn" \Arg{start} \Arg{step} \Arg{end}
+% <temp-var> \Arg{action}
+% \end{syntax}
+% Same as |\prg_stepwise_inline:nnnn| except here the current value is
+% stored in <temp-var> and the programmer can use it in <action>. This
+% function is not expandable.
+% \end{function}
+%
+% \section{Sorting}
%
%
% \begin{function}{
% \prg_quicksort:n |
% }
% \begin{syntax}
-% "\prg_quicksort:n" "{" "{"<element~1>"}" "{"<element~2>"}"
-% \dots\space "{"<element~n>"}" "}"
+% "\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 |\prg_quicksort_compare:nnTF| which is up
% to the programmer to define. When the sorting process is over, all
-% elements are given as argument to the function
+% items are given as argument to the function
% |\prg_quicksort_function:n| which the programmer also controls.
% \end{function}
%
@@ -476,14 +577,14 @@
% \prg_quicksort_compare:nnTF
% }
% \begin{syntax}
-% "\prg_quicksort_function:n" "{"<element>"}" \\
-% "\prg_quicksort_compare:nnTF" "{"<element 1>"}" "{"<element 2>"}"\\
+% "\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}
-% |\def:NNn\prg_quicksort_function:n 1{{#1}}|\\
-% |\def:NNn\prg_quicksort_compare:nnTF 2{\num_compare:nNnTF{#1}>{#2}}|
+% |\cs_set_nopar:Nn\prg_quicksort_function:n {{#1}}|\\
+% |\cs_set_nopar:Nn\prg_quicksort_compare:nnTF {\intexpr_compare:nNnTF{#1}>{#2}}|
% \end{quote}
% Then the function call
% \begin{quote}
@@ -493,89 +594,94 @@
% where one sorts a list of words, |\prg_quicksort_compare:nnTF| could
% be defined as
% \begin{quote}
-% |\def:NNn\prg_quicksort_compare:nnTF 2{|\\
-% | \num_compare:nNnTF{\tlist_compare:nn{#1}{#2}}>\c_zero }|
+% |\cs_set_nopar:Nn\prg_quicksort_compare:nnTF {|\\
+% | \intexpr_compare:nNnTF{\tl_compare:nn{#1}{#2}}>\c_zero }|
% \end{quote}
%
% \end{function}
%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3prg} implementation}
+%
+% \subsection{Variables}
%
-% \StopEventually{}
+% \begin{function}{ \l_tmpa_bool | \g_tmpa_bool }
+% Reserved booleans.
+% \end{function}
%
-% \subsection{The Implementation}
+% \begin{variable}{\g_prg_inline_level_int}
+% Global variable to track the nesting of the stepwise inline loop.
+% \end{variable}
%
+% \subsection{Module code}
%
% We start by ensuring that the required packages are loaded.
% \begin{macrocode}
%<*package>
\ProvidesExplPackage
{\filename}{\filedate}{\fileversion}{\filedescription}
-\RequirePackage{l3quark}
-\RequirePackage{l3toks}
-\RequirePackage{l3int}
+\package_check_loaded_expl:
%</package>
%<*initex|package>
% \end{macrocode}
%
-%
-% \subsubsection{Choosing modes}
+% \subsection{Choosing modes}
%
% \begin{macro}{\mode_if_vertical_p:}
-% \begin{macro}{\mode_if_vertical:TF}
-% \begin{macro}{\mode_if_vertical:T}
-% \begin{macro}{\mode_if_vertical:F}
-% For testing vertical mode.
+% \begin{macro}[TF]{\mode_if_vertical:}
+% 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}
-\def_new:Npn \mode_if_vertical_p: {
- \if_mode_vertical: \c_true \else: \c_false\fi:}
-\def_test_function_new:npn{mode_if_vertical:}{\if_mode_vertical:}
+\prg_set_conditional:Npnn \mode_if_vertical: {p,TF,T,F}{
+ \if_mode_vertical:
+ \prg_return_true: \else: \prg_return_false: \fi:
+}
% \end{macrocode}
% \end{macro}
% \end{macro}
-% \end{macro}
-% \end{macro}
%
% \begin{macro}{\mode_if_horizontal_p:}
-% \begin{macro}{\mode_if_horizontal:TF}
-% \begin{macro}{\mode_if_horizontal:T}
-% \begin{macro}{\mode_if_horizontal:F}
+% \begin{macro}[TF]{\mode_if_horizontal:}
% For testing horizontal mode.
% \begin{macrocode}
-\def_new:Npn \mode_if_horizontal_p: {
- \if_mode_horizontal: \c_true \else: \c_false\fi:}
-\def_test_function_new:npn{mode_if_horizontal:}{\if_mode_horizontal:}
+\prg_set_conditional:Npnn \mode_if_horizontal: {p,TF,T,F}{
+ \if_mode_horizontal:
+ \prg_return_true: \else: \prg_return_false: \fi:
+}
% \end{macrocode}
% \end{macro}
% \end{macro}
-% \end{macro}
-% \end{macro}
%
% \begin{macro}{\mode_if_inner_p:}
-% \begin{macro}{\mode_if_inner:TF}
-% \begin{macro}{\mode_if_inner:T}
-% \begin{macro}{\mode_if_inner:F}
+% \begin{macro}[TF]{\mode_if_inner:}
% For testing inner mode.
% \begin{macrocode}
-\def_new:Npn \mode_if_inner_p: {
- \if_mode_inner: \c_true \else: \c_false\fi:}
-\def_test_function_new:npn{mode_if_inner:}{\if_mode_inner:}
+\prg_set_conditional:Npnn \mode_if_inner: {p,TF,T,F}{
+ \if_mode_inner:
+ \prg_return_true: \else: \prg_return_false: \fi:
+}
% \end{macrocode}
% \end{macro}
% \end{macro}
-% \end{macro}
-% \end{macro}
%
-% \begin{macro}{\mode_if_math:TF}
-% \begin{macro}{\mode_if_math:T}
-% \begin{macro}{\mode_if_math:F}
+% \begin{macro}{\mode_if_math_p:}
+% \begin{macro}[TF]{\mode_if_math:}
% For testing math mode. Uses the kern-save |\scan_align_safe_stop:|.
% \begin{macrocode}
-\def_test_function_new:npn{mode_if_math:} {
- \scan_align_safe_stop: \if_mode_math: }
+\prg_set_conditional:Npnn \mode_if_math: {p,TF,T,F}{
+ \scan_align_safe_stop: \if_mode_math:
+ \prg_return_true: \else: \prg_return_false: \fi:
+}
% \end{macrocode}
% \end{macro}
% \end{macro}
-% \end{macro}
%
% \paragraph{Alignment safe grouping and scanning}
%
@@ -583,7 +689,7 @@
% \begin{macro}{\group_align_safe_begin:}
% \begin{macro}{\group_align_safe_end:}
% \TeX's alignment structures present many problems. As Knuth says
-% himself in \emph{\TeX: The Program}: ``It's sort of a miracle
+% himself in \emph{\TeX : The Program}: ``It's sort of a miracle
% whenever |\halign| or |\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
@@ -599,9 +705,9 @@
% by using code documented only in Appendix~D of
% \emph{The \TeX book}\dots
% \begin{macrocode}
-\def_new:Npn \group_align_safe_begin: {
+\cs_new_nopar:Npn \group_align_safe_begin: {
\if_false:{\fi:\if_num:w`}=\c_zero\fi:}
-\def_new:Npn \group_align_safe_end: {\if_num:w`{=\c_zero}\fi:}
+\cs_new_nopar:Npn \group_align_safe_end: {\if_num:w`{=\c_zero}\fi:}
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -625,12 +731,12 @@
% outer part of an alignment cell and b)~the last node \emph{wasn't} a
% char node or a ligature node.
% \begin{macrocode}
-\def_new:Npn \scan_align_safe_stop: {
- \num_compare:nNnT \etex_currentgrouptype:D = \c_six
+\cs_new_nopar:Npn \scan_align_safe_stop: {
+ \intexpr_compare:nNnT \etex_currentgrouptype:D = \c_six
{
- \num_compare:nNnF \etex_lastnodetype:D = \c_zero
+ \intexpr_compare:nNnF \etex_lastnodetype:D = \c_zero
{
- \num_compare:nNnF \etex_lastnodetype:D = \c_seven
+ \intexpr_compare:nNnF \etex_lastnodetype:D = \c_seven
\scan_stop:
}
}
@@ -638,11 +744,10 @@
% \end{macrocode}
% \end{macro}
%
-% \subsubsection{Making $n$ copies}
+% \subsection{Producing $n$ copies}
%
% \begin{macro}{\prg_replicate:nn}
-% \begin{macro}{\prg_replicate_aux:N}
-% \begin{macro}{\prg_replicate_first_aux:N}
+% \begin{macro}[aux]{\prg_replicate_aux:N,\prg_replicate_first_aux:N}
% This function uses a cascading csname technique by David Kastrup
% (who else :-)
%
@@ -660,7 +765,7 @@
% argument just to gobble them again we define separate functions to
% be inserted first. Finally we must ensure that the cascade comes to
% a peaceful end so we make it so that the original csname \TeX{} is
-% creating is simply "\use_noop:" expanding to nothing.
+% creating is simply "\prg_do_nothing:" expanding to nothing.
%
% This function has one flaw though: Since it constantly passes down
% ten copies of its previous argument it will severely affect the main
@@ -672,104 +777,102 @@
% pool. Also, it is considerably slower than what we use here so the
% few extra csnames are well spent I would say.
% \begin{macrocode}
-\def_new:Npn \prg_replicate:nn #1{
- \cs:w use_noop:
- \exp_after:NN\prg_replicate_first_aux:N
- \int_use:N \int_eval:n{#1} \cs_end:
+\cs_new_nopar:Npn \prg_replicate:nn #1{
+ \cs:w prg_do_nothing:
+ \exp_after:wN\prg_replicate_first_aux:N
+ \tex_romannumeral:D -`\q \intexpr_eval:n{#1} \cs_end:
\cs_end:
}
-\def_new:Npn \prg_replicate_aux:N#1{
+\cs_new_nopar:Npn \prg_replicate_aux:N#1{
\cs:w prg_replicate_#1:n\prg_replicate_aux:N
}
-\def_new:Npn \prg_replicate_first_aux:N#1{
+\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}
% \end{macro}
-% \end{macro}
% Then comes all the functions that do the hard work of inserting all
% the copies.
% \begin{macrocode}
-\def_new:Npn \prg_replicate_ :n #1{}% no, this is not a typo!
-\def_long_new:cpn {prg_replicate_0:n}#1{\cs_end:{#1#1#1#1#1#1#1#1#1#1}}
-\def_long_new:cpn {prg_replicate_1:n}#1{\cs_end:{#1#1#1#1#1#1#1#1#1#1}#1}
-\def_long_new:cpn {prg_replicate_2:n}#1{\cs_end:{#1#1#1#1#1#1#1#1#1#1}#1#1}
-\def_long_new:cpn {prg_replicate_3:n}#1{
+\cs_new_nopar:Npn \prg_replicate_ :n #1{}% no, this is not a typo!
+\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}
-\def_long_new:cpn {prg_replicate_4:n}#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}
-\def_long_new:cpn {prg_replicate_5:n}#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}
-\def_long_new:cpn {prg_replicate_6:n}#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}
-\def_long_new:cpn {prg_replicate_7:n}#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}
-\def_long_new:cpn {prg_replicate_8:n}#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}
-\def_long_new:cpn {prg_replicate_9:n}#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}
-\def_long_new:cpn {prg_replicate_first_0:n}#1{\cs_end: }
-\def_long_new:cpn {prg_replicate_first_1:n}#1{\cs_end: #1}
-\def_long_new:cpn {prg_replicate_first_2:n}#1{\cs_end: #1#1}
-\def_long_new:cpn {prg_replicate_first_3:n}#1{\cs_end: #1#1#1}
-\def_long_new:cpn {prg_replicate_first_4:n}#1{\cs_end: #1#1#1#1}
-\def_long_new:cpn {prg_replicate_first_5:n}#1{\cs_end: #1#1#1#1#1}
-\def_long_new:cpn {prg_replicate_first_6:n}#1{\cs_end: #1#1#1#1#1#1}
-\def_long_new:cpn {prg_replicate_first_7:n}#1{\cs_end: #1#1#1#1#1#1#1}
-\def_long_new:cpn {prg_replicate_first_8:n}#1{\cs_end: #1#1#1#1#1#1#1#1}
-\def_long_new:cpn {prg_replicate_first_9:n}#1{\cs_end: #1#1#1#1#1#1#1#1#1}
+\cs_new:cpn {prg_replicate_first_0:n}#1{\cs_end: }
+\cs_new:cpn {prg_replicate_first_1:n}#1{\cs_end: #1}
+\cs_new:cpn {prg_replicate_first_2:n}#1{\cs_end: #1#1}
+\cs_new:cpn {prg_replicate_first_3:n}#1{\cs_end: #1#1#1}
+\cs_new:cpn {prg_replicate_first_4:n}#1{\cs_end: #1#1#1#1}
+\cs_new:cpn {prg_replicate_first_5:n}#1{\cs_end: #1#1#1#1#1}
+\cs_new:cpn {prg_replicate_first_6:n}#1{\cs_end: #1#1#1#1#1#1}
+\cs_new:cpn {prg_replicate_first_7:n}#1{\cs_end: #1#1#1#1#1#1#1}
+\cs_new:cpn {prg_replicate_first_8:n}#1{\cs_end: #1#1#1#1#1#1#1#1}
+\cs_new:cpn {prg_replicate_first_9:n}#1{\cs_end: #1#1#1#1#1#1#1#1#1}
% \end{macrocode}
%
%
%
%
% \begin{macro}{\prg_stepwise_function:nnnN}
-% \begin{macro}{\prg_stepwise_function_incr:nnnN}
-% \begin{macro}{\prg_stepwise_function_decr:nnnN}
+% \begin{macro}[aux]{\prg_stepwise_function_incr:nnnN,
+% \prg_stepwise_function_decr:nnnN}
% A stepwise function. Firstly we check the direction of the steps
% |#2| since that will depend on which test we should use. If the
% step is positive we use a greater than test, otherwise a less than
% test. If the test comes out true exit, otherwise perform |#4|,
% add the step to |#1| and try again with this new value of |#1|.
% \begin{macrocode}
-\def_long_new:NNn \prg_stepwise_function:nnnN 2{
- \num_compare:nNnTF{#2}<\c_zero
- {\exp_args:No\prg_stepwise_function_decr:nnnN }
- {\exp_args:No\prg_stepwise_function_incr:nnnN }
- {\int_use:N\int_eval:n{#1}}{#2}
+\cs_new:Npn \prg_stepwise_function:nnnN #1#2{
+ \intexpr_compare:nNnTF{#2}<\c_zero
+ {\exp_args:Nf\prg_stepwise_function_decr:nnnN }
+ {\exp_args:Nf\prg_stepwise_function_incr:nnnN }
+ {\intexpr_eval:n{#1}}{#2}
}
-\def_long_new:NNn \prg_stepwise_function_incr:nnnN 4{
- \num_compare:nNnF {#1}>{#3}
+\cs_new:Npn \prg_stepwise_function_incr:nnnN #1#2#3#4{
+ \intexpr_compare:nNnF {#1}>{#3}
{
#4{#1}
- \exp_args:No \prg_stepwise_function_incr:nnnN
- {\int_use:N\int_eval:n{#1 + #2}}
+ \exp_args:Nf \prg_stepwise_function_incr:nnnN
+ {\intexpr_eval:n{#1 + #2}}
{#2}{#3}{#4}
}
}
-\def_long_new:NNn \prg_stepwise_function_decr:nnnN 4{
- \num_compare:nNnF {#1}<{#3}
+\cs_new:Npn \prg_stepwise_function_decr:nnnN #1#2#3#4{
+ \intexpr_compare:nNnF {#1}<{#3}
{
#4{#1}
- \exp_args:No \prg_stepwise_function_decr:nnnN
- {\int_use:N\int_eval:n{#1 + #2}}
+ \exp_args:Nf \prg_stepwise_function_decr:nnnN
+ {\intexpr_eval:n{#1 + #2}}
{#2}{#3}{#4}
}
}
% \end{macrocode}
% \end{macro}
% \end{macro}
-% \end{macro}
%
% \begin{macro}{\g_prg_inline_level_int}
% \begin{macro}{\prg_stepwise_inline:nnnn}
-% \begin{macro}{\prg_stepwise_inline_decr:nnnn}
-% \begin{macro}{\prg_stepwise_inline_incr:nnnn}
+% \begin{macro}[aux]{\prg_stepwise_inline_decr:nnnn,
+% \prg_stepwise_inline_incr:nnnn}
% This function uses the same approach as for instance
% |\clist_map_inline:Nn| to allow arbitrary nesting. First construct
% the special function and then call an auxiliary one which just
@@ -777,76 +880,74 @@
% when we maintain our own stack.
% \begin{macrocode}
\int_new:N\g_prg_inline_level_int
-\def_long_new:NNn\prg_stepwise_inline:nnnn 4{
+\cs_new:Npn\prg_stepwise_inline:nnnn #1#2#3#4{
\int_gincr:N \g_prg_inline_level_int
- \gdef:cpn{prg_stepwise_inline_\int_use:N\g_prg_inline_level_int :n}##1{#4}
- \num_compare:nNnTF {#2}<\c_zero
- {\exp_args:Nco \prg_stepwise_inline_decr:Nnnn }
- {\exp_args:Nco \prg_stepwise_inline_incr:Nnnn }
+ \cs_gset_nopar:cpn{prg_stepwise_inline_\int_use:N\g_prg_inline_level_int :n}##1{#4}
+ \intexpr_compare:nNnTF {#2}<\c_zero
+ {\exp_args:Ncf \prg_stepwise_inline_decr:Nnnn }
+ {\exp_args:Ncf \prg_stepwise_inline_incr:Nnnn }
{prg_stepwise_inline_\int_use:N\g_prg_inline_level_int :n}
- {\int_use:N\int_eval:n{#1}} {#2} {#3}
+ {\intexpr_eval:n{#1}} {#2} {#3}
\int_gdecr:N \g_prg_inline_level_int
}
-\def_long_new:NNn \prg_stepwise_inline_incr:Nnnn 4{
- \num_compare:nNnF {#2}>{#4}
+\cs_new:Npn \prg_stepwise_inline_incr:Nnnn #1#2#3#4{
+ \intexpr_compare:nNnF {#2}>{#4}
{
#1{#2}
- \exp_args:NNo \prg_stepwise_inline_incr:Nnnn #1
- {\int_use:N\int_eval:n{#2 + #3}} {#3}{#4}
+ \exp_args:NNf \prg_stepwise_inline_incr:Nnnn #1
+ {\intexpr_eval:n{#2 + #3}} {#3}{#4}
}
}
-\def_long_new:NNn \prg_stepwise_inline_decr:Nnnn 4{
- \num_compare:nNnF {#2}<{#4}
+\cs_new:Npn \prg_stepwise_inline_decr:Nnnn #1#2#3#4{
+ \intexpr_compare:nNnF {#2}<{#4}
{
#1{#2}
- \exp_args:NNo \prg_stepwise_inline_decr:Nnnn #1
- {\int_use:N\int_eval:n{#2 + #3}} {#3}{#4}
+ \exp_args:NNf \prg_stepwise_inline_decr:Nnnn #1
+ {\intexpr_eval:n{#2 + #3}} {#3}{#4}
}
}
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
-% \end{macro}
%
% \begin{macro}{\prg_stepwise_variable:nnnNn}
-% \begin{macro}{\prg_stepwise_variable_decr:nnnNn}
-% \begin{macro}{\prg_stepwise_variable_incr:nnnNn}
+% \begin{macro}[aux]{\prg_stepwise_variable_decr:nnnNn,
+% \prg_stepwise_variable_incr:nnnNn}
% Almost the same as above. Just store the value in |#4| and execute
% |#5|.
% \begin{macrocode}
-\def_long_new:NNn \prg_stepwise_variable:nnnNn 2 {
- \num_compare:nNnTF {#2}<\c_zero
- {\exp_args:No\prg_stepwise_variable_decr:nnnNn}
- {\exp_args:No\prg_stepwise_variable_incr:nnnNn}
- {\int_use:N\int_eval:n{#1}}{#2}
+\cs_new:Npn \prg_stepwise_variable:nnnNn #1#2 {
+ \intexpr_compare:nNnTF {#2}<\c_zero
+ {\exp_args:Nf\prg_stepwise_variable_decr:nnnNn}
+ {\exp_args:Nf\prg_stepwise_variable_incr:nnnNn}
+ {\intexpr_eval:n{#1}}{#2}
}
-\def_long_new:NNn \prg_stepwise_variable_incr:nnnNn 5 {
- \num_compare:nNnF {#1}>{#3}
+\cs_new:Npn \prg_stepwise_variable_incr:nnnNn #1#2#3#4#5 {
+ \intexpr_compare:nNnF {#1}>{#3}
{
- \def:Npn #4{#1} #5
- \exp_args:No \prg_stepwise_variable_incr:nnnNn
- {\int_use:N\int_eval:n{#1 + #2}}{#2}{#3}#4{#5}
+ \cs_set_nopar:Npn #4{#1} #5
+ \exp_args:Nf \prg_stepwise_variable_incr:nnnNn
+ {\intexpr_eval:n{#1 + #2}}{#2}{#3}#4{#5}
}
}
-\def_long_new:NNn \prg_stepwise_variable_decr:nnnNn 5 {
- \num_compare:nNnF {#1}<{#3}
+\cs_new:Npn \prg_stepwise_variable_decr:nnnNn #1#2#3#4#5 {
+ \intexpr_compare:nNnF {#1}<{#3}
{
- \def:Npn #4{#1} #5
- \exp_args:No \prg_stepwise_variable_decr:nnnNn
- {\int_use:N\int_eval:n{#1 + #2}}{#2}{#3}#4{#5}
+ \cs_set_nopar:Npn #4{#1} #5
+ \exp_args:Nf \prg_stepwise_variable_decr:nnnNn
+ {\intexpr_eval:n{#1 + #2}}{#2}{#3}#4{#5}
}
}
% \end{macrocode}
% \end{macro}
% \end{macro}
-% \end{macro}
%
%
-% \subsubsection{Booleans}
-% For normal booleans we set them to either "\c_true" or "\c_false"
-% and then use "\if:w" to choose the right branch. The functions
-% return either the TF, T, or F case \emph{after} ending the |\if:w|.
+% \subsection{Booleans}
+% For normal booleans we set them to either "\c_true_bool" or "\c_false_bool"
+% and then use "\if_bool:N" to choose the right branch. The functions
+% return either the TF, T, or F case \emph{after} ending the |\if_bool:N|.
% We only define the |N| versions here as the |c| versions can easily
% be constructed with the expansion module.
%
@@ -862,16 +963,16 @@
% \begin{macro}{\bool_gset_false:c}
% Defining and setting a boolean is easy.
% \begin{macrocode}
-\def_new:Npn \bool_new:N #1 { \let_new:NN #1 \c_false }
-\def_new:Npn \bool_new:c #1 { \let_new:cN {#1} \c_false }
-\def_new:Npn \bool_set_true:N #1 { \let:NN #1 \c_true }
-\def_new:Npn \bool_set_true:c #1 { \let:cN {#1} \c_true }
-\def_new:Npn \bool_set_false:N #1 { \let:NN #1 \c_false }
-\def_new:Npn \bool_set_false:c #1 { \let:cN {#1} \c_false }
-\def_new:Npn \bool_gset_true:N #1 { \glet:NN #1 \c_true }
-\def_new:Npn \bool_gset_true:c #1 { \glet:cN {#1} \c_true }
-\def_new:Npn \bool_gset_false:N #1 { \glet:NN #1 \c_false }
-\def_new:Npn \bool_gset_false:c #1 { \glet:cN {#1} \c_false }
+\cs_new_nopar:Npn \bool_new:N #1 { \cs_new_eq:NN #1 \c_false_bool }
+\cs_new_nopar:Npn \bool_new:c #1 { \cs_new_eq:cN {#1} \c_false_bool }
+\cs_new_nopar:Npn \bool_set_true:N #1 { \cs_set_eq:NN #1 \c_true_bool }
+\cs_new_nopar:Npn \bool_set_true:c #1 { \cs_set_eq:cN {#1} \c_true_bool }
+\cs_new_nopar:Npn \bool_set_false:N #1 { \cs_set_eq:NN #1 \c_false_bool }
+\cs_new_nopar:Npn \bool_set_false:c #1 { \cs_set_eq:cN {#1} \c_false_bool }
+\cs_new_nopar:Npn \bool_gset_true:N #1 { \cs_gset_eq:NN #1 \c_true_bool }
+\cs_new_nopar:Npn \bool_gset_true:c #1 { \cs_gset_eq:cN {#1} \c_true_bool }
+\cs_new_nopar:Npn \bool_gset_false:N #1 { \cs_gset_eq:NN #1 \c_false_bool }
+\cs_new_nopar:Npn \bool_gset_false:c #1 { \cs_gset_eq:cN {#1} \c_false_bool }
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -894,14 +995,14 @@
% \begin{macro}{\bool_gset_eq:cc}
% Setting a boolean to another is also pretty easy.
% \begin{macrocode}
-\let_new:NN \bool_set_eq:NN \let:NN
-\let_new:NN \bool_set_eq:Nc \let:Nc
-\let_new:NN \bool_set_eq:cN \let:cN
-\let_new:NN \bool_set_eq:cc \let:cc
-\let_new:NN \bool_gset_eq:NN \glet:NN
-\let_new:NN \bool_gset_eq:Nc \glet:Nc
-\let_new:NN \bool_gset_eq:cN \glet:cN
-\let_new:NN \bool_gset_eq:cc \glet:cc
+\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}
% \end{macro}
@@ -922,217 +1023,225 @@
% \end{macro}
% \end{macro}
%
-% \begin{macro}{\bool_if:NTF}
-% \begin{macro}{\bool_if:NT}
-% \begin{macro}{\bool_if:NF}
-% \begin{macro}{\bool_if:cTF}
-% \begin{macro}{\bool_if:cT}
-% \begin{macro}{\bool_if:cF}
-% Straight forward here.
+% \begin{macro}{\bool_if_p:N,\bool_if_p:c}
+% \begin{macro}[TF]{\bool_if:N,\bool_if:c}
+% Straight forward here. We could optimize here if we wanted to as
+% the boolean can just be input directly.
% \begin{macrocode}
-\def_test_function_new:npn{bool_if:N}#1{\if:w #1}
-\def_new:Npn \bool_if:cTF{\exp_args:Nc\bool_if:NTF}
-\def_new:Npn \bool_if:cT{\exp_args:Nc\bool_if:NT}
-\def_new:Npn \bool_if:cF{\exp_args:Nc\bool_if:NF}
+\prg_set_conditional:Npnn \bool_if:N #1 {p,TF,T,F}{
+ \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:NTF {c}
+\cs_generate_variant:Nn \bool_if:NT {c}
+\cs_generate_variant:Nn \bool_if:NF {c}
% \end{macrocode}
% \end{macro}
% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
%
-% \begin{macro}{\bool_if_p:N}
-% \begin{macro}{\bool_if_p:c}
-% We also make a predicate function for the "bool" data type but since
-% we use "\c_true" and "\c_false" it's rather simple\dots{}
-% Not that there's anything wrong in simplicity -- on the contrary!
-% \begin{macrocode}
-\def_new:Npn \bool_if_p:N #1 { #1 }
-\let_new:NN \bool_if_p:c \cs_use:c
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
%
%
-% \begin{macro}{\bool_whiledo:NT}
-% \begin{macro}{\bool_whiledo:cT}
-% \begin{macro}{\bool_whiledo:NF}
-% \begin{macro}{\bool_whiledo:cF}
+% \begin{macro}{\bool_while_do:Nn}
+% \begin{macro}{\bool_while_do:cn}
+% \begin{macro}{\bool_until_do:Nn}
+% \begin{macro}{\bool_until_do:cn}
% A "while" loop where the boolean is tested before executing the
-% statement. The "NT" version executes the "T" part as long as the
-% boolean is true while the "NF" version executes the "F" part as
+% statement. The `while' version executes the code as long as the
+% boolean is true; the `until' version executes the code as
% long as the boolean is false.
% \begin{macrocode}
-\def_long_new:Npn \bool_whiledo:NT #1 #2 {
- \bool_if:NT #1 {#2 \bool_whiledo:NT #1 {#2}}
+\cs_new:Npn \bool_while_do:Nn #1 #2 {
+ \bool_if:NT #1 {#2 \bool_while_do:Nn #1 {#2}}
}
-\def_new:Npn \bool_whiledo:cT{\exp_args:Nc\bool_whiledo:NT}
-\def_long_new:Npn \bool_whiledo:NF #1 #2 {
- \bool_if:NF #1 {#2 \bool_whiledo:NF #1 {#2}}
+\cs_generate_variant:Nn \bool_while_do:Nn {c}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_new:Npn \bool_until_do:Nn #1 #2 {
+ \bool_if:NF #1 {#2 \bool_until_do:Nn #1 {#2}}
}
-\def_new:Npn \bool_whiledo:cF{\exp_args:Nc\bool_whiledo:NF}
+\cs_generate_variant:Nn \bool_until_do:Nn {c}
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
-% \begin{macro}{\bool_dowhile:NT}
-% \begin{macro}{\bool_dowhile:cT}
-% \begin{macro}{\bool_dowhile:NF}
-% \begin{macro}{\bool_dowhile:cF}
+% \begin{macro}{\bool_do_while:Nn}
+% \begin{macro}{\bool_do_while:cn}
+% \begin{macro}{\bool_do_until:Nn}
+% \begin{macro}{\bool_do_until:cn}
% 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}
-\def_long_new:Npn \bool_dowhile:NT #1 #2 {
- #2 \bool_if:NT #1 {\bool_dowhile:NT #1 {#2}}
+\cs_new:Npn \bool_do_while:Nn #1 #2 {
+ #2 \bool_if:NT #1 {\bool_do_while:Nn #1 {#2}}
}
-\def_new:Npn \bool_dowhile:cT{\exp_args:Nc\bool_dowhile:NT}
-\def_long_new:Npn \bool_dowhile:NF #1 #2 {
- #2 \bool_if:NF #1 {\bool_dowhile:NF #1 {#2}}
-}
-\def_new:Npn \bool_dowhiledo:cF{\exp_args:Nc\bool_dowhile:cF}
+\cs_generate_variant:Nn \bool_do_while:Nn {c}
% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\bool_double_if:NNnnnn}
-% \begin{macro}{\bool_double_if:cNnnnn}
-% \begin{macro}{\bool_double_if:Ncnnnn}
-% \begin{macro}{\bool_double_if:ccnnnn}
-% Execute |#3| iff TT, |#4| iff TF, |#5| iff FT and |#6| iff
-% FF. The name isn't that great but I'll have to think about
-% that. Ideally it should be something with |TF| since only one of
-% the cases is executed but we haven't got any naming scheme for
-% this kind of thing so for now I'll just stick to simple |nnnn|.
+%
% \begin{macrocode}
-\def_new:Npn \bool_double_if:NNnnnn#1#2{
- \if_case:w \num_eval:w #1\scan_stop:
- \if_case:w \num_eval:w #2\scan_stop:
- \exp_after:NN\exp_after:NN\exp_after:NN \use_arg_i:nnnn
- \else:
- \exp_after:NN\exp_after:NN\exp_after:NN \use_arg_ii:nnnn
- \fi:
- \else:
- \if_case:w \num_eval:w #2\scan_stop:
- \exp_after:NN\exp_after:NN\exp_after:NN \use_arg_iii:nnnn
- \else:
- \exp_after:NN\exp_after:NN\exp_after:NN \use_arg_iv:nnnn
- \fi:
- \fi:
+\cs_new:Npn \bool_do_until:Nn #1 #2 {
+ #2 \bool_if:NF #1 {\bool_do_until:Nn #1 {#2}}
}
-\def_new:Npn \bool_double_if:cNnnnn{\exp_args:Nc\bool_double_if:NNnnnn}
-\def_new:Npn \bool_double_if:Ncnnnn{\exp_args:NNc\bool_double_if:NNnnnn}
-\def_new:Npn \bool_double_if:ccnnnn{\exp_args:Ncc\bool_double_if:NNnnnn}
+\cs_generate_variant:Nn \bool_do_until:Nn {c}
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
-% \subsubsection{Generic testing}
-%
-% \begin{macro}{\prg_whiledo:nT}
-% \begin{macro}{\prg_whiledo:nF}
-% \begin{macro}{\prg_dowhile:nT}
-% \begin{macro}{\prg_dowhile:nF}
-% We provide these four generic while loops. |#1| is a test function
-% and for the |T| functions it should be a test function ending with
-% just the true case. Similar for the |F| types.
-% \begin{macrocode}
-\def_long_new:Npn \prg_whiledo:nT #1#2{
- #1 {#2 \prg_whiledo:nT {#1}{#2}}
-}
-\def_long_new:Npn \prg_whiledo:nF #1#2{
- #1 {#2 \prg_whiledo:nF {#1}{#2}}
-}
-\def_long_new:Npn \prg_dowhile:nT #1#2{
- #2 #1 {\prg_dowhile:nT {#1}{#2}}
-}
-\def_long_new:Npn \prg_dowhile:nF #1#2{
- #2 #1 {\prg_dowhile:nF {#1}{#2}}
-}
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
%
-% \begin{macro}{\predicate_p:n}
-% \begin{macro}{\predicate:nTF}
-% \begin{macro}{\predicate:nT}
-% \begin{macro}{\predicate:nF}
-% \begin{macro}{\predicate_auxi:NN}
-% \begin{macro}{\predicate_auxii:NNN}
-% \begin{macro}{\predicate_88_0:w}^^A% fix!
-% \begin{macro}{\predicate_88_1:w}^^A% fix!
-% \begin{macro}{\predicate_II_0:w}^^A% fix!
-% \begin{macro}{\predicate_II_1:w}^^A fix!
-% \begin{macro}{\predicate_02_0:w}
-% \begin{macro}{\predicate_02_1:w}
-%
+%
+%
+% \subsection{Parsing boolean expressions}
+%
+% \begin{macro}{\bool_if_p:n}
+% \begin{macro}[TF]{\bool_if:n}
+% \begin{macro}[aux]{\bool_get_next:N, \bool_cleanup:N, \bool_choose:NN}
+% \begin{macro}[aux]{\bool_!:w}
+% \begin{macro}[aux]{\bool_(:w}
+% \begin{macro}[aux]{\bool_p:w}
+% \begin{macro}[aux]{\bool_8_1:w}
+% \begin{macro}[aux]{\bool_I_1:w}
+% \begin{macro}[aux]{\bool_8_0:w}
+% \begin{macro}[aux]{\bool_I_0:w}
+% \begin{macro}[aux]{\bool_)_0:w}
+% \begin{macro}[aux]{\bool_)_1:w}
+% \begin{macro}[aux]{\bool_S_0:w}
+% \begin{macro}[aux]{\bool_S_1:w}
+%
% 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. The function evaluates predicates from
-% left to right, expanding them to 00 and 01 resp., which leads to
-% six different situations of tokens in the input stream:
-% \begin{itemize}
-% \item[\texttt{00\&\&}] Current truth value is true, logical And
-% seen, continue to see if next is also true.
-% \item[\texttt{01\&\&}] Current truth value is false, logical And
-% seen, break the scanning and return \meta{false}.
-% \item[\texttt{00\char`\|\char`\|}] Current truth value is true,
-% logical Or seen, break the scanning and return \meta{true}.
-% \item[\texttt{01\char`\|\char`\|}] Current truth value is false,
-% logical Or seen, continue to see if a later predicate is true.
-% \item[\texttt{0002}] Current truth value is true, end marker
+% programming languages with "(" and ")" for grouping, "!" for
+% logical `Not', "&&" for logical `And' and "||" for logical
+% "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[\texttt{0102}] Current truth value is false, end marker
+% \item[\meta{false}Close] Current truth value is false, Close
% seen, return \meta{false}.
-% \end{itemize}
-% To accomplish this we pre-expand the predicate list using |f|
-% type expansion which leads to |00| or |01|, possibly with a
-% sequence of unfinished |\else: \c_false \fi:| or similar after
-% it, which we remove using the same trick. We also carry over the
-% truth value of the evaluated predicate. The expansion stops when
-% it sees the end marker or \verb+&&+ or \verb+||+ (assuming these
-% are not active characters at the programming level).
+% \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 "\tex_number: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}
-\def_long_new:Npn \predicate_p:n #1{
- \group_align_safe_begin:
- \exp_after:NN \predicate_auxi:NN
- \int_to_roman:w-`\q #1 02\scan_stop:
+\cs_set:Npn \bool_if_p:n #1{
+ \group_align_safe_begin:
+ \bool_get_next:N ( #1 )S
}
-\def_long_test_function_new:npn {predicate:n}#1{
- \group_align_safe_begin:
- \if:w \exp_after:NN \predicate_auxi:NN
- \int_to_roman:w-`\q #1 02\scan_stop:
+% \end{macrocode}
+% The GetNext operation. We make it a switch: If not a "!" or "(", we
+% assume it is a predicate.
+% \begin{macrocode}
+\cs_set:Npn \bool_get_next:N #1{
+ \use:c {
+ bool_
+ \if_meaning:w !#1 ! \else: \if_meaning:w (#1 ( \else: p \fi: \fi:
+ :w
+ } #1
}
-\def_new:Npn \predicate_auxi:NN 0 #1{
- \exp_after:NN \predicate_auxii:NNN \exp_after:NN #1
- \int_to_roman:w-`\q
+% \end{macrocode}
+% The Not operation. Discard the token read and reverse the truth
+% value of the next expression using "\intexpr_if_even_p:n".
+% \begin{macrocode}
+\cs_set:cpn {bool_!:w}#1{
+ \exp_after:wN \intexpr_if_even_p:n \tex_number:D \bool_get_next:N
}
% \end{macrocode}
-% After removing trailing conditionals we call a macro for the case we
-% are in (see list above).
+% The Open operation. Discard the token read and start a
+% sub-expression.
% \begin{macrocode}
-\def_new:Npn \predicate_auxii:NNN #1#2#3{
- \cs_use:c{predicate_#2#3_#1:w} }
-\def_new:cpn{predicate_&&_0:w}{
- \exp_after:NN \predicate_auxi:NN\int_to_roman:w-`\q
+\cs_set:cpn {bool_(:w}#1{
+ \exp_after:wN \bool_cleanup:N \tex_number:D \bool_get_next:N
}
-\def_long_new:cpn{predicate_&&_1:w} #1 02\scan_stop:{
- \group_align_safe_end: 01}
-\def_long_new:cpn{predicate_||_0:w} #1 02\scan_stop:{
- \group_align_safe_end: 00}
-\def_new:cpn{predicate_||_1:w}{
- \exp_after:NN \predicate_auxi:NN\int_to_roman:w-`\q
+% \end{macrocode}
+% Otherwise just evaluate the predicate and look for And, Or or Close
+% afterward.
+% \begin{macrocode}
+\cs_set:cpn {bool_p:w}{\exp_after:wN \bool_cleanup:N \tex_number:D }
+% \end{macrocode}
+% This cleanup function can be omitted once predicates return their
+% true/false booleans outside the conditionals.
+% \begin{macrocode}
+\cs_new_nopar:Npn \bool_cleanup:N #1{
+ \exp_after:wN \bool_choose:NN \exp_after:wN #1
+ \int_to_roman:w-`\q
}
-\def_new:cpn{predicate_02_0:w}\scan_stop:{ \group_align_safe_end: 00 }
-\def_new:cpn{predicate_02_1:w}\scan_stop:{ \group_align_safe_end: 01 }
+% \end{macrocode}
+% Branching the six way switch.
+% \begin{macrocode}
+\cs_new_nopar:Npn \bool_choose:NN #1#2{ \use:c{bool_#2_#1:w} }
+% \end{macrocode}
+% Continues scanning. Must remove the second "&" or "|".
+% \begin{macrocode}
+\cs_new_nopar:cpn{bool_&_1:w}&{\bool_get_next:N}
+\cs_new_nopar:cpn{bool_|_0: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_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_set:cpn{bool_&_0:w}&{\bool_eval_skip_to_end:Nw \c_false_bool}
+\cs_set:cpn{bool_|_1:w}|{\bool_eval_skip_to_end:Nw \c_true_bool}
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -1146,61 +1255,197 @@
% \end{macro}
% \end{macro}
% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[aux]{\bool_eval_skip_to_end:Nw,
+% \bool_eval_skip_to_end_aux:Nw,\bool_eval_skip_to_end_auxii:Nw}
+% 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.
%
+% This whole operation could be made a lot simpler if we were allowed
+% to do simple pattern matching. With a new enough pdf\TeX\ one can do
+% that sort of thing to test for existence of particular tokens.
+% \begin{macrocode}
+\cs_set:Npn \bool_eval_skip_to_end:Nw #1#2){
+ \bool_eval_skip_to_end_aux:Nw #1 #2(\q_no_value\q_nil{#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_set:Npn \bool_eval_skip_to_end_aux:Nw #1#2(#3#4\q_nil#5{
+ \quark_if_no_value:NTF #3
+ { #1 }
+ { \bool_eval_skip_to_end_auxii: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_set:Npn \bool_eval_skip_to_end_auxii:Nw #1#2(#3){
+ \bool_eval_skip_to_end:Nw #1#3 )
+}
+% \end{macrocode}
+% \end{macro}
%
-% \begin{macro}{\predicate_not_p:n}
-% The "not" variant just reverses the outcome of |\predicate_p:n|.
+% \begin{macro}{\bool_set:Nn,\bool_set:cn,\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}
-\def_long_new:Npn \predicate_not_p:n #1{
- \if:w \predicate_p:n{#1} \c_false \else: \c_true \fi:
+\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}{\bool_not_p:n}
+% 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}
%
-% \subsubsection{Case switch}
+% \begin{macro}{\bool_xor_p:nn}
+% 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 {
+ \intexpr_compare:nNnTF {\bool_if_p:n { #1 }} = {\bool_if_p:n { #2 }}
+ {\c_false_bool}{\c_true_bool}
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+\prg_set_conditional:Npnn \bool_if:n #1 {TF,T,F}{
+ \if_predicate:w \bool_if_p:n{#1}
+ \prg_return_true: \else: \prg_return_false: \fi:
+}
+% \end{macrocode}
+%
+% \begin{macro}{\bool_while_do:nn,\bool_until_do:nn}
+% \begin{macro}{\bool_do_while:nn,\bool_do_until:nn}
+% \begin{arguments}
+% \item Predicate test
+% \item Code to execute
+% \end{arguments}
+% \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_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} }
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Case switch}
%
% \begin{macro}{\prg_case_int:nnn}
-% \begin{macro}{\prg_case_int_aux:nnn}
+% \begin{macro}[aux]{\prg_case_int_aux:nnn}
% This case switch is in reality quite simple. It takes three arguments:
% \begin{enumerate}
% \item An integer expression you wish to find.
-% \item A list of pairs of "{"\meta{integer
-% expr}"}""{"\meta{code}"}". The list can be as long as is desired
+% \item A list of pairs of \Arg{integer expr} \Arg{code}.
+% The list can be as long as is desired
% and \meta{integer expr} can be negative.
% \item The code to be executed if the value wasn't found.
% \end{enumerate}
% We don't need the else case here yet, so leave it dangling in the
% input stream.
% \begin{macrocode}
-\def_long:Npn \prg_case_int:nnn #1 #2 {
+\cs_new:Npn \prg_case_int:nnn #1 #2 {
% \end{macrocode}
% We will be parsing on |#1| for each step so we might as well
% evaluate it first in case it is complicated.
% \begin{macrocode}
- \exp_args:No \prg_case_int_aux:nnn {\num_value:w \int_eval:n{#1}} #2
+ \exp_args:Nf \prg_case_int_aux:nnn { \intexpr_eval:n{#1}} #2
% \end{macrocode}
% The \texttt{?} below is just so there are enough arguments when we
% reach the end. And it made you look.~\texttt{;-)}
% \begin{macrocode}
\q_recursion_tail ? \q_recursion_stop
}
-\def_long_new:Npn \prg_case_int_aux:nnn #1#2#3{
+\cs_new:Npn \prg_case_int_aux:nnn #1#2#3{
% \end{macrocode}
% If we reach the end, return the else case. We just remove braces.
% \begin{macrocode}
- \quark_if_recursion_tail_stop_do:nn{#2}{\use_arg_i:n}
+ \quark_if_recursion_tail_stop_do:nn{#2}{\use:n}
% \end{macrocode}
% Otherwise we compare (which evaluates |#2| for us)
% \begin{macrocode}
- \num_compare:nNnTF{#1}={#2}
+ \intexpr_compare:nNnTF{#1}={#2}
% \end{macrocode}
% If true, we want to remove the remainder of the list, the else case
-% and then execute the code specified. Why not use |#3\use_none:n|?
-% Because if we are doing |f| style expansion, we will get
-% leftovers. If the test was false, we try the next pair, carrying the
-% |#1|.
+% and then execute the code specified. |\prg_end_case:nw {#3}| does
+% just that in one go. This means |f| style expansion works the way
+% one wants it to work.
% \begin{macrocode}
- { \use_arg_i_delimit_by_q_recursion_stop:nw {\use_arg_i:nn{#3}} }
+ { \prg_end_case:nw {#3} }
{ \prg_case_int_aux:nnn {#1}}
}
% \end{macrocode}
@@ -1208,17 +1453,17 @@
% \end{macro}
%
% \begin{macro}{\prg_case_dim:nnn}
-% \begin{macro}{\prg_case_dim_aux:nnn}
+% \begin{macro}[aux]{\prg_case_dim_aux:nnn}
% Same as |\prg_case_dim:nnn| except it is for \meta{dim} registers.
% \begin{macrocode}
-\def_long:Npn \prg_case_dim:nnn #1 #2 {
+\cs_new:Npn \prg_case_dim:nnn #1 #2 {
\exp_args:No \prg_case_dim_aux:nnn {\dim_use:N \dim_eval:n{#1}} #2
\q_recursion_tail ? \q_recursion_stop
}
-\def_long_new:Npn \prg_case_dim_aux:nnn #1#2#3{
- \quark_if_recursion_tail_stop_do:nn{#2}{\use_arg_i:n}
+\cs_new:Npn \prg_case_dim_aux:nnn #1#2#3{
+ \quark_if_recursion_tail_stop_do:nn{#2}{\use:n}
\dim_compare:nNnTF{#1}={#2}
- { \use_arg_i_delimit_by_q_recursion_stop:nw {\use_arg_i:nn{#3}} }
+ { \prg_end_case:nw {#3} }
{ \prg_case_dim_aux:nnn {#1}}
}
% \end{macrocode}
@@ -1226,27 +1471,56 @@
% \end{macro}
%
% \begin{macro}{\prg_case_str:nnn}
-% \begin{macro}{\prg_case_str_aux:nnn}
+% \begin{macro}[aux]{\prg_case_str_aux:nnn}
% Same as |\prg_case_dim:nnn| except it is for strings.
% \begin{macrocode}
-\def_long:Npn \prg_case_str:nnn #1 #2 {
+\cs_new:Npn \prg_case_str:nnn #1 #2 {
\prg_case_str_aux:nnn {#1} #2
\q_recursion_tail ? \q_recursion_stop
}
-\def_long_new:Npn \prg_case_str_aux:nnn #1#2#3{
- \quark_if_recursion_tail_stop_do:nn{#2}{\use_arg_i:n}
- \tlist_if_eq:xxTF{#1}{#2}
- { \use_arg_i_delimit_by_q_recursion_stop:nw {\use_arg_i:nn{#3}} }
+\cs_new:Npn \prg_case_str_aux:nnn #1#2#3{
+ \quark_if_recursion_tail_stop_do:nn{#2}{\use:n}
+ \tl_if_eq:xxTF{#1}{#2}
+ { \prg_end_case:nw {#3} }
{ \prg_case_str_aux:nnn {#1}}
}
% \end{macrocode}
% \end{macro}
% \end{macro}
%
-% \subsubsection{Sorting}
+% \begin{macro}{\prg_case_tl:Nnn}
+% \begin{macro}[aux]{\prg_case_tl_aux:NNn}
+% Same as |\prg_case_dim:nnn| except it is for token list variables.
+% \begin{macrocode}
+\cs_new:Npn \prg_case_tl:Nnn #1 #2 {
+ \prg_case_tl_aux:NNn #1 #2
+ \q_recursion_tail ? \q_recursion_stop
+}
+\cs_new:Npn \prg_case_tl_aux:NNn #1#2#3{
+ \quark_if_recursion_tail_stop_do:Nn #2{\use:n}
+ \tl_if_eq:NNTF #1 #2
+ { \prg_end_case:nw {#3} }
+ { \prg_case_tl_aux:NNn #1}
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+%
+% \begin{macro}[aux]{\prg_end_case:nw}
+% Ending a case switch is always performed the same way so we
+% optimize for this. |#1| is the code to execute, |#2| the
+% remainder, and |#3| the dangling else case.
+% \begin{macrocode}
+\cs_new:Npn \prg_end_case:nw #1#2\q_recursion_stop#3{#1}
+% \end{macrocode}
+% \end{macro}
+
%
+% \subsection{Sorting}
%
-% \begin{macro}{\prg_define_quicksort:nnn}
+%
+% \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
@@ -1263,37 +1537,37 @@
% 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 pointer, so one additionally has to define
+% is a token list variable, so one additionally has to define
% \begin{quote}
-% |\def:Npn \seq_quicksort:N{\exp_args:No\seq_quicksort:n}|
+% |\cs_set_nopar:Npn \seq_quicksort:N{\exp_args:No\seq_quicksort:n}|
% \end{quote}
%
%
% For details on the implementation see ``Sorting in \TeX's Mouth''
% by Bernd Raichle. Firstly we define the function for parsing the
-% ininital list and then the braced list afterwards.
+% initial list and then the braced list afterwards.
% \begin{macrocode}
-\def_new:NNn \prg_define_quicksort:nnn 3 {
- \def_long:cNx{#1_quicksort:n}1{
+\cs_new_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}
}
- \def_long:cNx{#1_quicksort_braced:n}1{
+ \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
}
- \def_long:cpx {#1_quicksort_start_partition:w} #2 ##1 #3{
+ \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}{}{}
}
- \def_long:cNx {#1_quicksort_start_partition_braced:n} 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}
- \def_long:cpx {#1_quicksort_do_partition_i:nnnw} ##1##2##3 #2 ##4 #3 {
+ \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}
@@ -1302,7 +1576,7 @@
}
{##1}{##2}{##3}{##4}
}
- \def_long:cNx {#1_quicksort_do_partition_i_braced:nnnn} 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}
@@ -1311,7 +1585,7 @@
}
{##1}{##2}{##3}{##4}
}
- \def_long:cpx {#1_quicksort_do_partition_ii:nnnw} ##1##2##3 #2 ##4 #3 {
+ \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}
@@ -1320,7 +1594,7 @@
}
{##1}{##2}{##3}{##4}
}
- \def_long:cNx {#1_quicksort_do_partition_ii_braced:nnnn} 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}
@@ -1333,26 +1607,26 @@
% This part of the code handles the two branches in each
% sorting. Again we will also have to do it braced.
% \begin{macrocode}
- \def_long:cNx {#1_quicksort_partition_less_i:nnnn} 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}}
- \def_long:cNx {#1_quicksort_partition_less_ii:nnnn} 4{
+ \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}}}
- \def_long:cNx {#1_quicksort_partition_greater_i:nnnn} 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}}
- \def_long:cNx {#1_quicksort_partition_greater_ii:nnnn} 4{
+ \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}}
- \def_long:cNx {#1_quicksort_partition_less_i_braced:nnnn} 4{
+ \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}}
- \def_long:cNx {#1_quicksort_partition_less_ii_braced:nnnn} 4{
+ \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}}}
- \def_long:cNx {#1_quicksort_partition_greater_i_braced:nnnn} 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}}
- \def_long:cNx {#1_quicksort_partition_greater_ii_braced:nnnn} 4{
+ \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}
- \def_long:cpx {#1_do_quicksort_braced:nnnnw} ##1##2##3##4\q_stop {
+ \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}
@@ -1374,77 +1648,24 @@
% \begin{macro}{\prg_quicksort_function:n}
% \begin{macro}{\prg_quicksort_compare:nnTF}
% \begin{macrocode}
-\let:NN \prg_quicksort_function:n \ERROR
-\let:NN \prg_quicksort_compare:nnTF \ERROR
+\cs_set:Npn \prg_quicksort_function:n {\ERROR}
+\cs_set:Npn \prg_quicksort_compare:nnTF {\ERROR}
% \end{macrocode}
% \end{macro}
% \end{macro}
%
-%
% That's it (for now).
% \begin{macrocode}
%</initex|package>
+% \end{macrocode}
+%
+% \begin{macrocode}
%<*showmemory>
\showMemUsage
%</showmemory>
% \end{macrocode}
%
-% \endinput
-%
-% $Log$
-% Revision 1.19 2006/08/08 10:26:09 morten
-% Fixed bugs in stepwise functions
-%
-% Revision 1.18 2006/07/30 14:41:28 morten
-% Added stepwise functions (loops going from i to k with step of j) plus quicksort.
-%
-% Revision 1.17 2006/07/06 14:57:13 morten
-% Moved code in the `miscellaneus' section to l3basics.
-%
-% Revision 1.16 2006/06/03 18:55:12 morten
-% Added special double boolean switches.
-%
-% Revision 1.15 2006/03/20 18:26:38 braams
-% Updated the copyright notice (2006) and demoted all implementation
-% sections to subsections and so on to clean up the toc for source3.tex
-%
-% Revision 1.14 2006/01/19 22:31:56 morten
-% Added \bool_set_eq:NN functions plus made function collection
-% complete.
-%
-% Revision 1.13 2006/01/04 00:58:17 morten
-% Added generic loops. Changed some names plus syntax for some of the
-% logical operations. Added code for defining functions with specified
-% number of arguments.
-%
-% Revision 1.12 2005/12/27 10:01:55 morten
-% Changed RCS information retrieval. Moved tlist code to l3tlp. Added
-% code for inserting n copies of something. Changed \bool_while to
-% \bool_whiledo.
-%
-% Revision 1.11 2005/04/25 15:01:59 morten
-% Fixed some names. Improved \peek_char_generic:NNTF to not use token registers.
-%
-% Revision 1.10 2005/04/23 14:36:12 morten
-% Changed \c_left|right_brace_token to \c_group_begin_token and
-% \c_group_end_token. Fixed definitions of \tlist_if_head_XXX functions.
-% Added example for PR/3080.
-%
-% Revision 1.9 2005/04/09 21:08:43 morten
-% Documentation blunders fixed
-%
-% Revision 1.8 2005/04/06 21:27:15 morten
-% More tlist functions, Moved \engine_aleph:TF to l3basics, new peek-ahead functions, definitions of implicit characters.
-%
-% Revision 1.7 2005/03/26 21:11:14 morten
-% Fix typo in \scan_align_safe_stop:
-%
-% Revision 1.6 2005/03/22 23:23:30 morten
-% Moved \tlist_ functions from l3basics. Added align-safe versions of important functions. Reorganized documentation slightly.
-%
-% Revision 1.5 2005/03/16 22:36:10 braams
-% Added the tweaks necessary to be able to load with initex
-%
-% Revision 1.4 2005/03/11 21:28:20 braams
-% Fixed the use of RCS information; added \StopEventually
+% \end{implementation}
+% \PrintIndex
%
+% \endinput
diff --git a/Master/texmf-dist/source/latex/expl3/l3prop.dtx b/Master/texmf-dist/source/latex/expl3/l3prop.dtx
index d9c9e1271cc..ec76aa7fa6b 100644
--- a/Master/texmf-dist/source/latex/expl3/l3prop.dtx
+++ b/Master/texmf-dist/source/latex/expl3/l3prop.dtx
@@ -1,5 +1,5 @@
% \iffalse
-%% File: l3prop.dtx Copyright (C) 1990-2008 LaTeX3 project
+%% File: l3prop.dtx Copyright (C) 1990-2009 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
@@ -17,7 +17,7 @@
%%
%% The development version of the bundle can be found at
%%
-%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/
+%% http://www.latex-project.org/svnroot/experimental/trunk/
%%
%% for those people who are interested.
%%
@@ -36,7 +36,7 @@
\RequirePackage{l3names}
%</driver|package>
%\fi
-\GetIdInfo$Id: l3prop.dtx 745 2008-08-03 18:50:46Z morten $
+\GetIdInfo$Id: l3prop.dtx 1365 2009-05-31 17:26:17Z mittelba $
{L3 Experimental Property Lists}
%\iffalse
%<*driver>
@@ -44,7 +44,7 @@
\ProvidesFile{\filename.\filenameext}
[\filedate\space v\fileversion\space\filedescription]
%\iffalse
-\documentclass{l3doc}
+\documentclass[full]{l3doc}
\begin{document}
\DocInput{\filename.\filenameext}
\end{document}
@@ -60,105 +60,112 @@
% \date{\filedate}
% \maketitle
%
+% \def\propkey{key}
+% \def\propval{info}
+% \def\proplist{prop}
%
+% \begin{documentation}
%
-% \section{Property lists}
+% \LaTeX3 implements a data structure called a `property list' which allows
+% arbitrary information to be stored and accessed using keywords rather than
+% numerical indexing.
%
-% \LaTeX3 implements a data structure which allows to store information
-% associated with individual tokens.
+% A property list might contain a set of keys such as "name", "age", and "ID",
+% which each have individual values that can be saved and retrieved.
%
-% \subsection{Functions}
+% \section{Functions}
%
% \begin{function}{%
% \prop_new:N |
% \prop_new:c |
% }
% \begin{syntax}
-% "\prop_new:N" <plist>
+% "\prop_new:N" <\proplist>
% \end{syntax}
-% Defines <plist> to be a variable of type p-list.
+% Defines <\proplist> to be a variable of type \meta{\proplist}.
% \end{function}
%
% \begin{function}{%
% \prop_clear:N |
+% \prop_clear:c |
% \prop_gclear:N |
+% \prop_gclear:c |
% }
% \begin{syntax}
-% "\prop_clear:N" <plist>
+% "\prop_clear:N" <\proplist>
% \end{syntax}
-% These functions locally or globally clear <plist>.
+% These functions locally or globally clear <\proplist>.
% \end{function}
%
% \begin{function}{%
% \prop_put:Nnn |
-% \prop_put:ccn |
+% \prop_put:cnn |
% \prop_gput:Nnn |
% \prop_gput:Nno |
-% \prop_gput:Noo |
-% \prop_gput:Ncn |
-% \prop_gput:Ooo |
-% \prop_gput:Nox |
+% \prop_gput:NnV |
+% \prop_gput:Nnx |
% \prop_gput:cnn |
-% \prop_gput:ccn |
-% \prop_gput:cco |
% \prop_gput:ccx |
% }
% \begin{syntax}
-% "\prop_put:Nnn" <plist> "{"<key>"}" "{"<token list>"}"
+% "\prop_put:Nnn" <\proplist> \Arg{\propkey} \Arg{token list}
% \end{syntax}
-% Locally or globally associates <token list> with <key> in the p-list
-% <plist>. If <key> has already a meaning within <plist> this value is
+% Locally or globally associates <token list> with <\propkey> in the <\proplist>
+% <\proplist>. If <\propkey> has already a meaning within <\proplist> this value is
% overwritten.
+%
+% The <\propkey> must not contain unescaped "#" tokens but the <token list> may.
% \end{function}
%
% \begin{function}{%
% \prop_gput_if_new:Nnn |
% }
% \begin{syntax}
-% "\prop_gput_if_new:Nnn" <plist> "{"<key>"}" "{"<token list>"}"
+% "\prop_gput_if_new:Nnn" <\proplist> \Arg{\propkey} \Arg{token list}
% \end{syntax}
-% Globally associates <token list> with <key> in the p-list
-% <plist> but only if <key> has so far no meaning within <plist>.
-% overwritten.
+% Globally associates <token list> with <\propkey> in the <\proplist>
+% <\proplist> but only if <\propkey> has so far no meaning within <\proplist>.
+% Silently ignored if <\propkey> is already set in the <\proplist>.
% \end{function}
%
% \begin{function}{%
% \prop_get:NnN |
% \prop_get:cnN |
% \prop_gget:NnN |
-% \prop_gget:NcN |
% \prop_gget:cnN |
% }
% \begin{syntax}
-% "\prop_get:NnN" <plist> "{"<key>"}" <tlp>
+% "\prop_get:NnN" <\proplist> \Arg{\propkey} <tl var.>
% \end{syntax}
-% If <info> is the information associated with <key> in the p-list
-% <plist> then the token list pointer <tlp> gets <info> assigned.
+% If <\propval> is the information associated with <\propkey> in the <\proplist>
+% <\proplist> then the token list variable <tl var.> gets <\propval> assigned.
% Otherwise its value is the special quark "\q_no_value".
%^^A See section \ref{sec:quarks} to test this.
% The assignment is done either locally or globally.
% \end{function}
%
-% \begin{function}{%
-% \prop_set_eq:NN |
-% \prop_set_eq:cc |
-% \prop_gset_eq:NN |
-% \prop_gset_eq:cc
-% }
+% \begin{function}{ \prop_set_eq:NN |
+% \prop_set_eq:cN |
+% \prop_set_eq:Nc |
+% \prop_set_eq:cc |
+% \prop_gset_eq:NN |
+% \prop_gset_eq:cN |
+% \prop_gset_eq:Nc |
+% \prop_gset_eq:cc }
% \begin{syntax}
-% "\prop_set_eq:NN" <plist 1> <plist 2>
+% "\prop_set_eq:NN" <\proplist 1> <\proplist 2>
% \end{syntax}
-% A fast assignment of <plist>s.
+% A fast assignment of <\proplist>s.
% \end{function}
%
% \begin{function}{%
% \prop_get_gdel:NnN |
% }
% \begin{syntax}
-% "\prop_get_gdel:NnN" <plist> "{"<key>"}" <tlp>
+% "\prop_get_gdel:NnN" <\proplist> \Arg{\propkey} <tl var.>
% \end{syntax}
-% Like "\prop_get:NnN" but additionally removes <key> (and its <info>)
-% from <plist>.
+% Like "\prop_get:NnN" but additionally removes <\propkey> (and its <\propval>)
+% from <\proplist>.
% \end{function}
%
% \begin{function}{%
@@ -166,82 +173,121 @@
% \prop_gdel:Nn |
% }
% \begin{syntax}
-% "\prop_del:Nn" <plist> "{"<key>"}"
+% "\prop_del:Nn" <\proplist> \Arg{\propkey}
% \end{syntax}
-% Locally or globally deletes <key> and its <info> from <plist> if
+% Locally or globally deletes <\propkey> and its <\propval> from <\proplist> if
% found. Otherwise does nothing.
% \end{function}
%
%
-% \begin{function}{\prop_map_function:NN |
-% \prop_map_function:cN |
-% \prop_map_function:Nc |
-% \prop_map_function:cc |
-% }
+% \begin{function}{ \prop_map_function:NN / (EXP) |
+% \prop_map_function:cN / (EXP) |
+% \prop_map_function:Nc / (EXP) |
+% \prop_map_function:cc / (EXP) }
% \begin{syntax}
-% "\prop_map_function:NN" <plist> <function>
+% "\prop_map_function:NN" <\proplist> <function>
% \end{syntax}
-% Maps <function> which should be a function with two arguments (<key>
-% and <info>) over every <key> <info> pair of <plist>. Expandable.
+% Maps <function> which should be a function with two arguments (<\propkey>
+% and <\propval>) over every <\propkey> <\propval> pair of <\proplist>. Expandable.
% \end{function}
%
% \begin{function}{\prop_map_inline:Nn |
% \prop_map_inline:cn
% }
% \begin{syntax}
-% "\prop_map_inline:Nn" <plist> "{" <inline function> "}"
+% "\prop_map_inline:Nn" <\proplist> \Arg{inline function}
% \end{syntax}
% Just like "\prop_map_function:NN" but with the function of two arguments
% supplied as inline code. Within <inline function> refer to the
-% arguments via "#1" (<key>) and "#2" (<info>). Nestable.
+% arguments via "#1" (<\propkey>) and "#2" (<\propval>). Nestable.
+% \end{function}
+%
+%
+% \begin{function}{%
+% \prop_map_break: |
+% }
+% \begin{syntax}
+% "\prop_map_inline:Nn" \meta{\proplist} "{"\\
+% " ... \"\meta{break test}":T {\prop_map_break:} }"
+% \end{syntax}
+% For breaking out of a loop. To be used inside "TF"-type functions as shown
+% in the example above.
% \end{function}
%
+% \begin{function}{ \prop_show:N |
+% \prop_show:c }
+% \begin{syntax}
+% "\prop_show:N" <\proplist>
+% \end{syntax}
+% Pauses the compilation and shows <\proplist> on the terminal output and
+% in the log file.
+% \end{function}
%
-% \begin{function}{%
-% \prop_map_break:w |
-% }
-% \begin{syntax}
-% "\prop_map_break:w"
-% \end{syntax}
-% For breaking out of a loop. To be used inside "TF" type functions.
-% \end{function}
+% \begin{function}{ \prop_display:N |
+% \prop_display:c }
+% \begin{syntax}
+% "\prop_display:N" <prop>
+% \end{syntax}
+% As with "\prop_show:N" but pretty prints the output one line per property pair.
+% \end{function}
%
%
+% \section{Predicates and conditionals}
%
-% \subsection{Predicates and conditionals}
+% \begin{function}{ \prop_if_empty_p:N |
+% \prop_if_empty_p:c }
+% \begin{syntax}
+% "\prop_if_empty_p:N" <\proplist> \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Predicates to test whether or not a particular <\proplist> is empty.
+% \end{function}
%
-% \begin{function}{\prop_if_empty:NTF}
+% \begin{function}{ \prop_if_empty:N / (TF)(EXP) |
+% \prop_if_empty:c / (TF)(EXP) }
% \begin{syntax}
-% "\prop_if_empty:NTF" <plist> "{"<true code>"}{"<false code>"}"
+% "\prop_if_empty:NTF" <\proplist> \Arg{true code} \Arg{false code}
% \end{syntax}
-% Set of conditionals that test whether or not a particular <plist>
+% Set of conditionals that test whether or not a particular <\proplist>
% is empty.
% \end{function}
%
-% \begin{function}{\prop_if_eq:NNF |
-% \prop_if_eq:ccF
+% \begin{function}{
+% \prop_if_eq_p:NN / (EXP) |
+% \prop_if_eq_p:cN / (EXP) |
+% \prop_if_eq_p:Nc / (EXP) |
+% \prop_if_eq_p:cc / (EXP) |
+% \prop_if_eq:NN / (EXP)(TF) |
+% \prop_if_eq:cN / (EXP)(TF) |
+% \prop_if_eq:Nc / (EXP)(TF) |
+% \prop_if_eq:cc / (EXP)(TF) |
% }
% \begin{syntax}
-% "\prop_if_eq:NNF" <plist1> <plist2> "{"<false code>"}"
+% "\prop_if_eq:NNF" <\proplist 1> <\proplist 2> \Arg{false code}
% \end{syntax}
-% Execute <false code> if <plist1> doesn't hold the same token list as
-% <plist2>.
+% Execute <false code> if <\proplist 1> doesn't hold the same token list as
+% <\proplist 2>. Only expandable for new versions of pdf\TeX.
% \end{function}
%
%
% \begin{function}{%
-% \prop_if_in:NnTF |
-% \prop_if_in:NoTF |
-% \prop_if_in:ccTF |
+% \prop_if_in:Nn / (TF) |
+% \prop_if_in:NV / (TF) |
+% \prop_if_in:No / (TF) |
+% \prop_if_in:cn / (TF) |
+% \prop_if_in:cc / (TF) |
% }
% \begin{syntax}
-% "\prop_if_in:NnTF" <plist>"{"<key>"}{"<true code>"}{"<false code>"}"
+% "\prop_if_in:NnTF" <\proplist> \Arg{\propkey} \Arg{true code} \Arg{false code}
% \end{syntax}
-% Tests if <key> is used in <plist> and then either executes <true code>
+% Tests if <\propkey> is used in <\proplist> and then either executes <true code>
% or <false code>.
% \end{function}
%
-% \subsection{Internal functions}
+% \section{Internal functions}
+%
+% \begin{function}{\q_prop}
+% Quark used to delimit property lists internally.
+% \end{function}
%
% \begin{function}{%
% \prop_put_aux:w |
@@ -252,6 +298,7 @@
%
% \begin{function}{%
% \prop_get_aux:w |
+% \prop_gget_aux:w |
% \prop_get_del_aux:w |
% \prop_del_aux:w |
% }
@@ -265,10 +312,9 @@
% \end{function}
%
% \begin{function}{%
-% \prop_map_function_aux:NNn |
-% \prop_map_inline_aux:Nn |
+% \prop_map_function_aux:w |
% }
-% Internal functions implementing the map operations.
+% Internal function implementing the map operations.
% \end{function}
%
% \begin{function}{%
@@ -280,53 +326,60 @@
%
% \begin{function}{\prop_split_aux:Nnn}
% \begin{syntax}
-% "\prop_split_aux:Nnn" <plist> <key> <cmd>
+% "\prop_split_aux:Nnn" <\proplist> <\propkey> <cmd>
% \end{syntax}
% Internal function that invokes <cmd> with 3 arguments: 1st is the
-% beginning of <plist> before <key>, 2nd is the value associated with
-% <key>, 3rd is the rest of <plist> after <key>. If there is no key
-% <key> in <plist>, then the 2 arg is "\q_no_value " and the 3rd arg is
-% empty; otherwise the 3rd argument has the two extra tokens <prop>
+% beginning of <\proplist> before <\propkey>, 2nd is the value associated with
+% <\propkey>, 3rd is the rest of <\proplist> after <\propkey>. If there is no key
+% <\propkey> in <\proplist>, then the 2 arg is "\q_no_value" and the 3rd arg is
+% empty; otherwise the 3rd argument has the two extra tokens <\propkey>
% "\q_no_value" at the end.
%
% This function is used to implement various get operations.
% \end{function}
%
-% \StopEventually{}
+% \end{documentation}
%
-% \subsection {The Implementation}
+% \begin{implementation}
+%
+% \section{\pkg{l3prop} implementation}
+%
+% A property list is a token register whose contents is
+% of the form\par
+% {\centering|\q_prop| \meta{\propkey$\sb1$} |\q_prop| \marg{\propval$\sb1$} \ldots{}
+% |\q_prop| \meta{\propkey$\sb n$} |\q_prop| \marg{\propval$\sb n$}\par}
+%
+% The property \m{\propkey}s and \m{\propval}s might be arbitrary token lists; each
+% \m{\propval} is surrounded by braces.
%
% We start by ensuring that the required packages are loaded.
% \begin{macrocode}
-%<package>\ProvidesExplPackage
-%<package> {\filename}{\filedate}{\fileversion}{\filedescription}
-%<package>\RequirePackage{l3toks}\par
-%<package>\RequirePackage{l3quark}\par
+%<*package>
+\ProvidesExplPackage
+ {\filename}{\filedate}{\fileversion}{\filedescription}
+\package_check_loaded_expl:
+%</package>
%<*initex|package>
% \end{macrocode}
%
-% A property list is a token register whose contents is
-% of the form `\zz{q_prop}key$\sb1$\zz{q_prop}\zv{val$\sb1$} \ldots{}
-% \zz{q_prop}key$\sb n$\zz{q_prop}\zv{val$\sb{}n$}'.
-% The properties have to be single
-% token, the values might be arbitrary token lists they get surrounded
-% by braces.
-%
% \begin{macro}{\q_prop}
+% The separator between \m{\propkey}s and \m{\propval}s and \m{\propkey}s.
% \begin{macrocode}
\quark_new:N\q_prop
% \end{macrocode}
% \end{macro}
-
+%
% To get values from property-lists, token lists should be passed to
% the appropriate functions.
%
+% \subsection{Functions}
+%
% \begin{macro}{\prop_new:N}
% \begin{macro}{\prop_new:c}
-% Property lists are implemented as token lists.
+% Property lists are implemented as token registers.
% \begin{macrocode}
-\def_new:Npn \prop_new:N #1{\toks_new:N #1}
-\def_new:Npn \prop_new:c {\exp_args:Nc \prop_new:N}
+\cs_new_eq:NN \prop_new:N \toks_new:N
+\cs_new_eq:NN \prop_new:c \toks_new:c
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -338,30 +391,94 @@
% The same goes for clearing a property list, either
% locally or globally.
% \begin{macrocode}
-\let_new:NN \prop_clear:N \toks_clear:N
-\def_new:Npn \prop_clear:c {\exp_args:Nc\prop_clear:N}
-\let_new:NN \prop_gclear:N \toks_gclear:N
-\def_new:Npn \prop_gclear:c {\exp_args:Nc\prop_gclear:N}
+\cs_new_eq:NN \prop_clear:N \toks_clear:N
+\cs_new_eq:NN \prop_clear:c \toks_clear:c
+\cs_new_eq:NN \prop_gclear:N \toks_gclear:N
+\cs_new_eq:NN \prop_gclear:c \toks_gclear:c
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
+% \begin{macro}{\prop_set_eq:NN}
+% \begin{macro}{\prop_set_eq:Nc}
+% \begin{macro}{\prop_set_eq:cN}
+% \begin{macro}{\prop_set_eq:cc}
+% \begin{macro}{\prop_gset_eq:NN}
+% \begin{macro}{\prop_gset_eq:Nc}
+% \begin{macro}{\prop_gset_eq:cN}
+% \begin{macro}{\prop_gset_eq:cc}
+% This makes two \m{\proplist}s have the same contents.
+% \begin{macrocode}
+\cs_new_eq:NN \prop_set_eq:NN \toks_set_eq:NN
+\cs_new_eq:NN \prop_set_eq:Nc \toks_set_eq:Nc
+\cs_new_eq:NN \prop_set_eq:cN \toks_set_eq:cN
+\cs_new_eq:NN \prop_set_eq:cc \toks_set_eq:cc
+\cs_new_eq:NN \prop_gset_eq:NN \toks_gset_eq:NN
+\cs_new_eq:NN \prop_gset_eq:Nc \toks_gset_eq:Nc
+\cs_new_eq:NN \prop_gset_eq:cN \toks_gset_eq:cN
+\cs_new_eq:NN \prop_gset_eq:cc \toks_gset_eq:cc
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\prop_show:N}
+% \begin{macro}{\prop_show:c}
+% Show on the console the raw contents of a property list's token register.
+% \begin{macrocode}
+\cs_new_eq:NN \prop_show:N \toks_show:N
+\cs_new_eq:NN \prop_show:c \toks_show:c
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\prop_display:N}
+% \begin{macro}{\prop_display:c}
+% Pretty print the contents of a property list on the console.
+% \begin{macrocode}
+\cs_new_nopar:Npn \prop_display:N #1 {
+ \iow_term:x { Property-list~\token_to_str:N #1~contains~
+ the~pairs~(without~outer~braces): }
+ \toks_clear:N \l_tmpa_toks
+ \prop_map_inline:Nn #1 {
+ \toks_if_empty:NF \l_tmpa_toks {
+ \toks_put_right:Nx \l_tmpa_toks {^^J>~}
+ }
+ \toks_put_right:Nx \l_tmpa_toks {
+ \iow_space: \iow_char:N \{ \exp_not:n {##1} \iow_char:N \} \iow_space:
+ \iow_space: => \iow_space:
+ \iow_space: \iow_char:N \{ \exp_not:n {##2} \iow_char:N \}
+ }
+ }
+ \toks_show:N \l_tmpa_toks
+}
+\cs_generate_variant:Nn \prop_display:N {c}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
%
%
% \begin{macro}{\prop_split_aux:Nnn}
-% |\prop_split_aux:NNn|\zz{plist}\zz{prop}\zz{cmd} invokes \zz{cmd}
-% with 3 arguments: 1st is the beginning of \zz{plist} before
-% \zz{prop}, 2nd is the value associated with \zz{prop}, 3rd is the
-% rest of \zz{plist} after \zz{prop}. If there is no property
-% \zz{prop} in \zz{plist}, then the 2nd argument will be |\q_no_value|
+% |\prop_split_aux:Nnn|\meta{\proplist}\meta{\propkey}\meta{cmd} invokes \meta{cmd}
+% with 3 arguments: 1st is the beginning of \meta{\proplist} before
+% \meta{\propkey}, 2nd is the value associated with \meta{\propkey}, 3rd is the
+% rest of \meta{\proplist} after \meta{\propkey}. If there is no property
+% \meta{\propkey} in \meta{\proplist}, then the 2nd argument will be |\q_no_value|
% and the 3rd argument is empty; otherwise the 3rd argument has the
-% extra tokens |\q_prop| \zz{prop} |\q_prop| |\q_no_value| at the end.
+% extra tokens |\q_prop| \meta{\propkey} |\q_prop| |\q_no_value| at the end.
% \begin{macrocode}
-\def_long_new:Npn \prop_split_aux:Nnn #1#2#3{
- \def:Npn \tmp:w ##1\q_prop#2\q_prop##2##3\q_stop {#3{##1}{##2}{##3}}
- \exp_after:NN\tmp:w \toks_use:N#1\q_prop#2\q_prop\q_no_value \q_stop
+\cs_new:Npn \prop_split_aux:Nnn #1#2#3{
+ \cs_set:Npn \prop_tmp:w ##1 \q_prop #2 \q_prop ##2##3 \q_stop {
+ #3 {##1}{##2}{##3}
+ }
+ \exp_after:wN \prop_tmp:w \toks_use:N #1 \q_prop #2 \q_prop \q_no_value \q_stop
}
% \end{macrocode}
% \end{macro}
@@ -369,109 +486,106 @@
% \begin{macro}{\prop_get:NnN}
% \begin{macro}{\prop_get:cnN}
% \begin{macro}{\prop_get_aux:w}
-% |\prop_get:NNN |\zz{plist}\zz{prop}\zz{tlp} defines
-% \zz{tlp} to be the value associated with \zz{prop} in \zz{plist},
+% |\prop_get:NnN |\meta{\proplist}\meta{\propkey}\meta{tl var.}~defines
+% \meta{tl var.}~to be the value associated with \meta{\propkey} in \meta{\proplist},
% |\q_no_value| if not found.
% \begin{macrocode}
-\def_long_new:NNn \prop_get:NnN 2{
- \prop_split_aux:Nnn #1{#2}\prop_get_aux:w}
-\def_long_new:NNn \prop_get_aux:w 4{\tlp_set:Nx#4{\exp_not:n{#2}}}
-\def_new:Npn \prop_get:cnN { \exp_args:Nc \prop_get:NnN }
+\cs_new:Npn \prop_get:NnN #1#2 {
+ \prop_split_aux:Nnn #1{#2}\prop_get_aux:w
+}
+\cs_new:Npn \prop_get_aux:w #1#2#3#4 { \tl_set:Nx #4 {\exp_not:n{#2}} }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_generate_variant:Nn \prop_get:NnN {cnN}
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\prop_gget:NnN}
-% \begin{macro}{\prop_gget:NcN}
% \begin{macro}{\prop_gget:cnN}
% \begin{macro}{\prop_gget_aux:w}
% The global version of the previous function.
% \begin{macrocode}
-\def_long_new:NNn \prop_gget:NnN 2{
+\cs_new:Npn \prop_gget:NnN #1#2{
\prop_split_aux:Nnn #1{#2}\prop_gget_aux:w}
-\def_new:Npn \prop_gget:NcN {\exp_args:NNc \prop_gget:NnN}
-\def_new:Npn \prop_gget:cnN {\exp_args:Nc \prop_gget:NnN}
-\def_long_new:NNn \prop_gget_aux:w 4{\tlp_gset:Nx#4{\exp_not:n{#2}}}
+\cs_new:Npn \prop_gget_aux:w #1#2#3#4{\tl_gset:Nx#4{\exp_not:n{#2}}}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_generate_variant:Nn \prop_gget:NnN {cnN}
% \end{macrocode}
-% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
-% \begin{macro}{\prop_get_gdel:NNN}
+% \begin{macro}{\prop_get_gdel:NnN}
% \begin{macro}{\prop_get_del_aux:w}
-% |\prop_get_gdel:NNN| is the same as |\prop_get:NNN| but the
-% \m{property_key} and its value are afterwards globally removed
+% |\prop_get_gdel:NnN| is the same as |\prop_get:NnN| but the
+% \m{\propkey} and its value are afterwards globally removed
% from \m{property_list}. One probably also needs the local
% variants or only the local one, or\ldots\ We decide this later.
% \begin{macrocode}
-\def_long_new:NNn \prop_get_gdel:NnN 3{
+\cs_new:Npn \prop_get_gdel:NnN #1#2#3{
\prop_split_aux:Nnn #1{#2}{\prop_get_del_aux:w #3{\toks_gset:Nn #1}{#2}}}
-\def_long_new:NNn \prop_get_del_aux:w 6{
- \tlp_set:Nx #1{\exp_not:n{#5}}
+\cs_new:Npn \prop_get_del_aux:w #1#2#3#4#5#6{
+ \tl_set:Nx #1{\exp_not:n{#5}}
\quark_if_no_value:NF #1 {
- \def:Npn \tmp:w ##1\q_prop#3\q_prop\q_no_value {#2{#4##1}}
- \tmp:w #6}
+ \cs_set_nopar:Npn \prop_tmp:w ##1\q_prop#3\q_prop\q_no_value {#2{#4##1}}
+ \prop_tmp:w #6}
}
% \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\prop_put:Nnn}
-% \begin{macro}{\prop_put:ccn}
+% \begin{macro}{\prop_put:cnn}
% \begin{macro}{\prop_gput:Nnn}
+% \begin{macro}{\prop_gput:NnV}
% \begin{macro}{\prop_gput:Nno}
% \begin{macro}{\prop_gput:Nnx}
-% \begin{macro}{\prop_gput:Nox}
-% \begin{macro}{\prop_gput:Noo}
-% \begin{macro}{\prop_gput:Ncn}
-% \begin{macro}{\prop_gput:Ooo}
-% \begin{macro}{\prop_gput:cNn}
-% \begin{macro}{\prop_gput:ccn}
-% \begin{macro}{\prop_gput:cco}
+% \begin{macro}{\prop_gput:cnn}
% \begin{macro}{\prop_gput:ccx}
% \begin{macro}{\prop_put_aux:w}
-% |\prop_put:Nnn |\zz{plist}\zz{prop}\zv{val} adds/changes the
-% value associated with \zz{prop} in \zz{plist} to \zv{val}.
+% |\prop_put:Nnn| \marg{\proplist} \marg{\propkey} \marg{\propval} adds/changes the
+% value associated with \meta{\propkey} in \meta{\proplist} to \meta{\propval}.
% \begin{macrocode}
-\def_long_new:NNn \prop_put:Nnn 2{
+\cs_new:Npn \prop_put:Nnn #1#2{
\prop_split_aux:Nnn #1{#2}{
\prop_clear:N #1
- \prop_put_aux:w {\toks_put_right:Nn #1}{#2}}
+ \prop_put_aux:w {\toks_put_right:Nn #1}{#2}
+ }
}
-\def_new:Npn \prop_put:ccn {\exp_args:Ncc \prop_put:Nnn }
-
-\def_long_new:NNn \prop_gput:Nnn 2{
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_new:Npn \prop_gput:Nnn #1#2{
\prop_split_aux:Nnn #1{#2}{
\prop_gclear:N #1
- \prop_put_aux:w {\toks_gput_right:Nn #1}{#2}}
+ \prop_put_aux:w {\toks_gput_right:Nn #1}{#2}
+ }
}
-
-\def_long_new:NNn \prop_put_aux:w 6{
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_new:Npn \prop_put_aux:w #1#2#3#4#5#6{
#1{\q_prop#2\q_prop{#6}#3}
- \tlist_if_empty:nF{#5}
+ \tl_if_empty:nF{#5}
{
- \def:Npn \tmp:w ##1\q_prop#2\q_prop\q_no_value {#1{##1}}
- \tmp:w #5
+ \cs_set_nopar:Npn \prop_tmp:w ##1\q_prop#2\q_prop\q_no_value {#1{##1}}
+ \prop_tmp:w #5
}
}
-\def_new:Npn \prop_gput:Nno {\exp_args:NNno \prop_gput:Nnn}
-\def_new:Npn \prop_gput:Nnx {\exp_args:NNnx \prop_gput:Nnn}
-\def_new:Npn \prop_gput:Nox {\exp_args:NNox \prop_gput:Nnn}
-\def_new:Npn \prop_gput:Noo {\exp_args:NNoo \prop_gput:Nnn}
-\def_new:Npn \prop_gput:Ncn {\exp_args:NNc \prop_gput:Nnn}
-\def_new:Npn \prop_gput:Ooo {\exp_args:NOoo \prop_gput:Nnn}
-\def_new:Npn \prop_gput:cnn {\exp_args:Nc \prop_gput:Nnn}
-\def_new:Npn \prop_gput:ccn {\exp_args:Ncc \prop_gput:Nnn}
-\def_new:Npn \prop_gput:cco {\exp_args:Ncco \prop_gput:Nnn}
-\def_new:Npn \prop_gput:ccx {\exp_args:Nccx \prop_gput:Nnn}
% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
+%
+% \begin{macrocode}
+\cs_generate_variant:Nn \prop_put:Nnn {cnn}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_generate_variant:Nn \prop_gput:Nnn {NnV,Nno,Nnx,Nox,cnn,ccx}
+% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
@@ -485,169 +599,105 @@
% \begin{macro}{\prop_del:Nn}
% \begin{macro}{\prop_gdel:Nn}
% \begin{macro}{\prop_del_aux:w}
-% |\prop_del:NN |\zz{plist}\zz{prop} deletes the entry for
-% \zz{prop} in \zz{plist}, if any.
+% |\prop_del:Nn |\meta{\proplist}\meta{\propkey} deletes the entry for
+% \meta{\propkey} in \meta{\proplist}, if any.
% \begin{macrocode}
-\def_long_new:NNn \prop_del:Nn 2{
+\cs_new:Npn \prop_del:Nn #1#2{
\prop_split_aux:Nnn #1{#2}{\prop_del_aux:w {\toks_set:Nn #1}{#2}}}
-\def_long_new:NNn \prop_gdel:Nn 2{
+\cs_new:Npn \prop_gdel:Nn #1#2{
\prop_split_aux:Nnn #1{#2}{\prop_del_aux:w {\toks_gset:Nn #1}{#2}}}
-\def_long_new:NNn \prop_del_aux:w 5{
- \def:Npn \tmp:w {#4}
- \quark_if_no_value:NF \tmp:w
- {\def:Npn \tmp:w ##1\q_prop#2\q_prop\q_no_value {#1{#3##1}}
- \tmp:w #5}}
+\cs_new:Npn \prop_del_aux:w #1#2#3#4#5{
+ \cs_set_nopar:Npn \prop_tmp:w {#4}
+ \quark_if_no_value:NF \prop_tmp:w {
+ \cs_set_nopar:Npn \prop_tmp:w ##1\q_prop#2\q_prop\q_no_value {#1{#3##1}}
+ \prop_tmp:w #5
+ }
+}
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
%
-%
-% \begin{macro}{\prop_if_in:NnTF}
-% \begin{macro}{\prop_if_in:NoTF}
-% \begin{macro}{\prop_if_in:ccTF}
-% \begin{macro}{\prop_if_in_aux:w}
-% |\prop_if_in:NNTF| \m{property_list} \m{property_key}
-% \m{true_case} \m{false_case} will check whether or not
-% \m{property_key} is on the \m{property_list} and then select
-% either the true or false case.
-% \begin{macrocode}
-\def_new:NNn \prop_if_in:NnTF 2{
- \prop_split_aux:Nnn #1{#2}\prop_if_in_aux:w}
-\def_new:NNn \prop_if_in_aux:w 3{\quark_if_no_value:nFT {#2}}
-
-\def_new:Npn \prop_if_in:NoTF {\exp_args:NNo \prop_if_in:NnTF}
-\def_new:Npn \prop_if_in:ccTF {\exp_args:Ncc \prop_if_in:NnTF}
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
% \begin{macro}{\prop_gput_if_new:Nnn}
-% |\prop_gput_if_new:NNn| \m{property_list} \m{property_key}
-% \m{property_value} is equivalent to
+% \begin{macro}{\prop_put_if_new_aux:w}
+% |\prop_gput_if_new:Nnn| \m{\proplist} \m{\propkey}
+% \m{\propval} is equivalent to
% \begin{tabbing}
% xxxxx\=xxxxx\= \kill
-% |\prop_if_in:NNTF |\m{property}\m{property_key} \\
+% |\prop_if_in:NnTF |\m{\proplist}\m{\propkey} \\
% \> |{}%| \\
% \> |{\prop_gput:Nnn| \\
% \>\> \m{property_list} \\
-% \>\> \m{property_key} \\
-% \>\> \m{property_value}|}|
+% \>\> \m{\propkey} \\
+% \>\> \m{\propval}|}|
% \end{tabbing}
% Here we go (listening to Porgy \& Bess in a recording with Ella
% F. and Louis A. which makes writing macros sometimes difficult; I
% find myself humming instead of working):
% \begin{macrocode}
-\def_long_new:NNn \prop_gput_if_new:Nnn 2{
+\cs_new:Npn \prop_gput_if_new:Nnn #1#2{
\prop_split_aux:Nnn #1{#2}{\prop_put_if_new_aux:w #1{#2}}}
-\def_long_new:NNn \prop_put_if_new_aux:w 6{
- \tlist_if_empty:nT {#5}{#1{\q_prop#2\q_prop{#6}#3}}}
+\cs_new:Npn \prop_put_if_new_aux:w #1#2#3#4#5#6{
+ \tl_if_empty:nT {#5}{#1{\q_prop#2\q_prop{#6}#3}}}
% \end{macrocode}
% \end{macro}
+% \end{macro}
%
%
-% \begin{macro}{\prop_set_eq:NN}
-% \begin{macro}{\prop_set_eq:Nc}
-% \begin{macro}{\prop_set_eq:cN}
-% \begin{macro}{\prop_set_eq:cc}
-% \begin{macro}{\prop_gset_eq:NN}
-% \begin{macro}{\prop_gset_eq:Nc}
-% \begin{macro}{\prop_gset_eq:cN}
-% \begin{macro}{\prop_gset_eq:cc}
-% This makes two \m{plist}s have the same contents.
+% \subsection{Predicates and conditionals}
+%
+% \begin{macro}{\prop_if_empty_p:N,\prop_if_empty_p:c}
+% \begin{macro}[TF]{\prop_if_empty:N,\prop_if_empty:c}
+% This conditional takes a \m{\proplist} as its argument and evaluates
+% either the true or the false case, depending on whether or not
+% \m{\proplist} contains any properties.
% \begin{macrocode}
-\let_new:NN \prop_set_eq:NN \toks_set_eq:NN
-\let_new:NN \prop_set_eq:Nc \toks_set_eq:Nc
-\let_new:NN \prop_set_eq:cN \toks_set_eq:cN
-\let_new:NN \prop_set_eq:cc \toks_set_eq:cc
-\let_new:NN \prop_gset_eq:NN \toks_gset_eq:NN
-\let_new:NN \prop_gset_eq:Nc \toks_gset_eq:Nc
-\let_new:NN \prop_gset_eq:cN \toks_gset_eq:cN
-\let_new:NN \prop_gset_eq:cc \toks_gset_eq:cc
+\prg_new_eq_conditional:NNn \prop_if_empty:N \toks_if_empty:N {p,TF,T,F}
+\prg_new_eq_conditional:NNn \prop_if_empty:c \toks_if_empty:c {p,TF,T,F}
% \end{macrocode}
% \end{macro}
% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
%
-% \begin{macro}{\prop_if_empty_p:N}
-% \begin{macro}{\prop_if_empty_p:c}
-% \begin{macro}{\prop_if_empty:NTF}
-% \begin{macro}{\prop_if_empty:NT}
-% \begin{macro}{\prop_if_empty:NF}
-% \begin{macro}{\prop_if_empty:cTF}
-% \begin{macro}{\prop_if_empty:cT}
-% \begin{macro}{\prop_if_empty:cF}
-% This conditional takes a \m{plist} as its argument and evaluates
-% either the true or the false case, depending on whether or not
-% \m{plist} contains any properties.
+%
+% \begin{macro}{\prop_if_eq_p:NN,\prop_if_eq_p:cN,
+% \prop_if_eq_p:Nc,\prop_if_eq_p:cc}
+% \begin{macro}[TF]{\prop_if_eq:NN,\prop_if_eq:Nc,
+% \prop_if_eq:cN,\prop_if_eq:cc}
+% These functions test whether two property lists are equal.
% \begin{macrocode}
-\let_new:NN \prop_if_empty_p:N \toks_if_empty_p:N
-\let_new:NN \prop_if_empty_p:c \toks_if_empty_p:c
-\let_new:NN \prop_if_empty:NTF \toks_if_empty:NTF
-\let_new:NN \prop_if_empty:NT \toks_if_empty:NT
-\let_new:NN \prop_if_empty:NF \toks_if_empty:NF
-\let_new:NN \prop_if_empty:cTF \toks_if_empty:cTF
-\let_new:NN \prop_if_empty:cT \toks_if_empty:cTF
-\let_new:NN \prop_if_empty:cF \toks_if_empty:cF
+\prg_new_eq_conditional:NNn \prop_if_eq:NN \toks_if_eq:NN {p,TF,T,F}
+\prg_new_eq_conditional:NNn \prop_if_eq:cN \toks_if_eq:cN {p,TF,T,F}
+\prg_new_eq_conditional:NNn \prop_if_eq:Nc \toks_if_eq:Nc {p,TF,T,F}
+\prg_new_eq_conditional:NNn \prop_if_eq:cc \toks_if_eq:cc {p,TF,T,F}
% \end{macrocode}
% \end{macro}
% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
%
-% \begin{macro}{\prop_if_eq:NNTF}
-% \begin{macro}{\prop_if_eq:NNT}
-% \begin{macro}{\prop_if_eq:NNF}
-% \begin{macro}{\prop_if_eq:NcTF}
-% \begin{macro}{\prop_if_eq:NcT}
-% \begin{macro}{\prop_if_eq:NcF}
-% \begin{macro}{\prop_if_eq:cNTF}
-% \begin{macro}{\prop_if_eq:cNT}
-% \begin{macro}{\prop_if_eq:cNF}
-% \begin{macro}{\prop_if_eq:ccTF}
-% \begin{macro}{\prop_if_eq:ccT}
-% \begin{macro}{\prop_if_eq:ccF}
-% This function test whether the property lists that are in its first
-% two arguments are equal; if they are not |#3| is executed.
+% \begin{macro}[TF]{\prop_if_in:Nn}
+% \begin{macro}[TF]{\prop_if_in:NV}
+% \begin{macro}[TF]{\prop_if_in:No}
+% \begin{macro}[TF]{\prop_if_in:cn}
+% \begin{macro}[TF]{\prop_if_in:cc}
+% \begin{macro}{\prop_if_in_aux:w}
+% |\prop_if_in:NnTF| \m{property_list} \m{\propkey}
+% \m{true_case} \m{false_case} will check whether or not
+% \m{\propkey} is on the \m{property_list} and then select
+% either the true or false case.
% \begin{macrocode}
-\def_new:NNn \prop_if_eq:NNTF 2 {
- \tlist_if_eq:xxTF{\toks_use:N #1}{\toks_use:N #2}
-}
-\def_new:NNn \prop_if_eq:NNT 2 {
- \tlist_if_eq:xxT{\toks_use:N #1}{\toks_use:N #2}
+\prg_new_conditional:Nnn \prop_if_in:Nn {TF,T,F} {
+ \prop_split_aux:Nnn #1 {#2} {\prop_if_in_aux:w}
}
-\def_new:NNn \prop_if_eq:NNF 2 {
- \tlist_if_eq:xxF{\toks_use:N #1}{\toks_use:N #2}
+\cs_new_nopar:Npn \prop_if_in_aux:w #1#2#3 {
+ \quark_if_no_value:nTF {#2} {\prg_return_false:} {\prg_return_true:}
}
-\def_new:Npn \prop_if_eq:NcTF {\exp_args:NNc \prop_if_eq:NNTF}
-\def_new:Npn \prop_if_eq:NcT {\exp_args:NNc \prop_if_eq:NNT}
-\def_new:Npn \prop_if_eq:NcF {\exp_args:NNc \prop_if_eq:NNF}
-\def_new:Npn \prop_if_eq:cNTF {\exp_args:Nc \prop_if_eq:NNTF}
-\def_new:Npn \prop_if_eq:cNT {\exp_args:Nc \prop_if_eq:NNT}
-\def_new:Npn \prop_if_eq:cNF {\exp_args:Nc \prop_if_eq:NNF}
-\def_new:Npn \prop_if_eq:ccTF {\exp_args:Ncc \prop_if_eq:NNTF}
-\def_new:Npn \prop_if_eq:ccT {\exp_args:Ncc \prop_if_eq:NNT}
-\def_new:Npn \prop_if_eq:ccF {\exp_args:Ncc \prop_if_eq:NNF}
% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
+%
+% \begin{macrocode}
+\cs_generate_variant:Nn \prop_if_in:NnTF {NV,No,cn,cc}
+\cs_generate_variant:Nn \prop_if_in:NnT {NV,No,cn,cc}
+\cs_generate_variant:Nn \prop_if_in:NnF {NV,No,cn,cc}
+% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
@@ -655,6 +705,8 @@
% \end{macro}
% \end{macro}
%
+% \subsection{Mapping functions}
+%
% \begin{macro}{\prop_map_function:NN}
% \begin{macro}{\prop_map_function:cN}
% \begin{macro}{\prop_map_function:Nc}
@@ -662,55 +714,59 @@
% \begin{macro}{\prop_map_function_aux:w}
% Maps a function on every entry in the property list. The
% function must take 2 arguments: a key and a value.
-% \begin{macrocode}
-\def_new:Npn \prop_map_function:NN #1#2{
- \exp_after:NN \prop_map_function_aux:w
- \exp_after:NN #2 \toks_use:N #1 \q_prop{}\q_prop \q_no_value \q_stop
-}
-\def_new:Npn \prop_map_function_aux:w #1\q_prop#2\q_prop#3{
- \if:w \tlist_if_empty_p:n{#2}
- \exp_after:NN \prop_map_break:w
- \fi:
- #1{#2}{#3}
- \prop_map_function_aux:w #1
-}
-% problem with the above impl, is that an empty key stops the mapping but all
+%
+% First, some failed attempts:
+% \begin{verbatim}
+% \cs_new_nopar:Npn \prop_map_function:NN #1#2{
+% \exp_after:wN \prop_map_function_aux:w
+% \exp_after:wN #2 \toks_use:N #1 \q_prop{}\q_prop \q_no_value \q_stop
+% }
+% \cs_new_nopar:Npn \prop_map_function_aux:w #1\q_prop#2\q_prop#3{
+% \if_predicate:w \tl_if_empty_p:n{#2}
+% \exp_after:wN \prop_map_break:
+% \fi:
+% #1{#2}{#3}
+% \prop_map_function_aux:w #1
+% }
+% \end{verbatim}
+% problem with the above implementation is that an empty key stops the mapping but all
% other functions in the module allow the use of empty keys (as one value)
-
-\def:Npn \prop_map_function:NN #1#2{
- \exp_after:NN \prop_map_function_aux:w
- \exp_after:NN #2 \toks_use:N #1 \q_prop \q_no_value \q_prop \q_no_value
-}
-\def:Npn \prop_map_function_aux:w #1\q_prop#2\q_prop#3{
- \quark_if_no_value:nF{#2}
- {
- #1{#2}{#3}
- \prop_map_function_aux:w #1
- }
-}
-% problem with the above impl is that \quark_if_no_value:nF is fairly slow and
-% if \quark_if_no_value:NF is used instead we have to do an assignment thus
+% \begin{verbatim}
+% \cs_set_nopar:Npn \prop_map_function:NN #1#2{
+% \exp_after:wN \prop_map_function_aux:w
+% \exp_after:wN #2 \toks_use:N #1 \q_prop \q_no_value \q_prop \q_no_value
+% }
+% \cs_set_nopar:Npn \prop_map_function_aux:w #1\q_prop#2\q_prop#3{
+% \quark_if_no_value:nF{#2}
+% {
+% #1{#2}{#3}
+% \prop_map_function_aux:w #1
+% }
+% }
+% \end{verbatim}
+% problem with the above implementation is that |\quark_if_no_value:nF| is fairly slow and
+% if |\quark_if_no_value:NF| is used instead we have to do an assignment thus
% making the mapping not expandable (is that important?)
-
-\def:Npn \prop_map_function:NN #1#2{
- \exp_after:NN \prop_map_function_aux:w
- \exp_after:NN #2 \toks_use:N #1 \q_prop \q_nil \q_prop \q_no_value \q_stop
+%
+% Here's the current version of the code:
+% \begin{macrocode}
+\cs_set_nopar:Npn \prop_map_function:NN #1#2 {
+ \exp_after:wN \prop_map_function_aux:w
+ \exp_after:wN #2 \toks_use:N #1 \q_prop \q_nil \q_prop \q_no_value \q_stop
}
-\def:Npn \prop_map_function_aux:w #1\q_prop#2\q_prop#3{
- \if_meaning:NN \q_nil #2
- \exp_after:NN \prop_map_break:w
+\cs_set:Npn \prop_map_function_aux:w #1 \q_prop #2 \q_prop #3 {
+ \if_meaning:w \q_nil #2
+ \exp_after:wN \prop_map_break:
\fi:
#1{#2}{#3}
\prop_map_function_aux:w #1
}
-
-% (potential) problem with the above impl is that it will returns true is #2
-% contains more than just \q_nil thus executing whatever follows. Claim: this
-% can't happen :-) so we should be ok
-
-\def_new:Npn \prop_map_function:cN {\exp_args:Nc \prop_map_function:NN }
-\def_new:Npn \prop_map_function:Nc {\exp_args:NNc \prop_map_function:NN }
-\def_new:Npn \prop_map_function:cc {\exp_args:Ncc \prop_map_function:NN}
+% \end{macrocode}
+% (potential) problem with the above implementation is that it will
+% return true if |#2| contains more than just |\q_nil| thus executing
+% whatever follows. Claim: this can't happen |:-)| so we should be ok
+% \begin{macrocode}
+\cs_generate_variant:Nn \prop_map_function:NN {c,Nc,cc}
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -726,76 +782,42 @@
% we don't waste time doing that.
% \begin{macrocode}
\num_new:N \g_prop_inline_level_num
-\def_new:Npn \prop_map_inline:Nn #1#2 {
+\cs_new_nopar:Npn \prop_map_inline:Nn #1#2 {
\num_gincr:N \g_prop_inline_level_num
- \gdef_long:cpn {prop_map_inline_ \num_use:N \g_prop_inline_level_num :n}
+ \cs_gset:cpn {prop_map_inline_ \num_use:N \g_prop_inline_level_num :n}
##1##2{#2}
\prop_map_function:Nc #1
{prop_map_inline_ \num_use:N \g_prop_inline_level_num :n}
\num_gdecr:N \g_prop_inline_level_num
}
-\def_new:Npn \prop_map_inline:cN { \exp_args:Nc \prop_map_inline:NN }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_generate_variant:Nn\prop_map_inline:Nn {cn}
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
-% \begin{macro}{\prop_map_break:w}
+% \begin{macro}{\prop_map_break:}
% The break statement.
% \begin{macrocode}
-\let_new:NN \prop_map_break:w \use_none_delimit_by_q_stop:w
+\cs_new_eq:NN \prop_map_break: \use_none_delimit_by_q_stop:w
% \end{macrocode}
% \end{macro}
%
-% Finally a bunch of compatibility commands with the old syntax: they will
-% vanish soon!
% \begin{macrocode}
-\def:Npn \prop_put:NNn {\typeout{Warning:~name~
- changed~ to~ \string\prop_put:Nnn}\prop_put:Nnn}
-\def:Npn \prop_gput:NNn {\typeout{Warning:~name~
- changed~ to~ \string\prop_gput:Nnn }\prop_gput:Nnn }
-\def:Npn \prop_gput:NNo {\typeout{Warning:~name~
- changed~ to~ \string\prop_gput:Nno }\prop_gput:Nno }
-\def:Npn \prop_gput:cNn {\typeout{Warning:~name~
- changed~ to~ \string\prop_gput:cnn }\prop_gput:cnn }
-\def:Npn \prop_gput_if_new:NNn {\typeout{Warning:~name~
- changed~ to~ \string\prop_gput_if_new:Nnn }\prop_gput_if_new:Nnn }
-\def:Npn \prop_get:NNN {\typeout{Warning:~name~
- changed~ to~ \string\prop_get:NnN }\prop_get:NnN }
-\def:Npn \prop_get:cNN {\typeout{Warning:~name~
- changed~ to~ \string\prop_get:cnN }\prop_get:cnN }
-\def:Npn \prop_gget:NNN {\typeout{Warning:~name~
- changed~ to~ \string\prop_gget:NnN }\prop_gget:NnN }
-\def:Npn \prop_gget:cNN {\typeout{Warning:~name~
- changed~ to~ \string\prop_gget:cnN }\prop_gget:cnN }
-\def:Npn \prop_get_gdel:NNN {\typeout{Warning:~name~
- changed~ to~ \string\prop_get_gdel:NnN }\prop_get_gdel:NnN }
-\def:Npn \prop_del:NN {\typeout{Warning:~name~
- changed~ to~ \string\prop_del:Nn }\prop_del:Nn }
-\def:Npn \prop_gdel:NN {\typeout{Warning:~name~
- changed~ to~ \string\prop_gdel:Nn }\prop_gdel:Nn }
-\def:Npn \prop_if_in:NNTF {\typeout{Warning:~name~
- changed~ to~ \string\prop_if_in:NnTF }\prop_if_in:NnTF }
+%</initex|package>
% \end{macrocode}
-%
+%
% Show token usage:
% \begin{macrocode}
-%</initex|package>
%<*showmemory>
%\showMemUsage
%</showmemory>
% \end{macrocode}
%
-%
-%
-% \begin{macrocode}
-%<*unused>
-\file_input_stop:
-% \end{macrocode}
-%
-% \begin{macrocode}
-%</unused>
-% \end{macrocode}
+% \end{implementation}
+% \PrintIndex
%
% \endinput
-%
diff --git a/Master/texmf-dist/source/latex/expl3/l3quark.dtx b/Master/texmf-dist/source/latex/expl3/l3quark.dtx
index 80328f6a768..c5c5a22c00c 100644
--- a/Master/texmf-dist/source/latex/expl3/l3quark.dtx
+++ b/Master/texmf-dist/source/latex/expl3/l3quark.dtx
@@ -1,5 +1,5 @@
% \iffalse
-%% File: l3quark.dtx Copyright (C) 1990-2006 LaTeX3 project
+%% File: l3quark.dtx Copyright (C) 1990-2009 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
@@ -17,7 +17,7 @@
%%
%% The development version of the bundle can be found at
%%
-%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/
+%% http://www.latex-project.org/svnroot/experimental/trunk/
%%
%% for those people who are interested.
%%
@@ -36,7 +36,7 @@
\RequirePackage{l3names}
%</driver|package>
%\fi
-\GetIdInfo$Id: l3quark.dtx 761 2008-08-04 21:35:13Z morten $
+\GetIdInfo$Id: l3quark.dtx 1365 2009-05-31 17:26:17Z mittelba $
{L3 Experimental Quark Commands}
%\iffalse
%<*driver>
@@ -44,7 +44,7 @@
\ProvidesFile{\filename.\filenameext}
[\filedate\space v\fileversion\space\filedescription]
%\iffalse
-\documentclass{l3doc}
+\documentclass[full]{l3doc}
\begin{document}
\DocInput{\filename.\filenameext}
\end{document}
@@ -60,10 +60,7 @@
% \date{\filedate}
% \maketitle
%
-%
-% \section{Quarks}
-%^^A \label{sec:quarks}
-%
+% \begin{documentation}
%
% A special type of constants in \LaTeX3 are `quarks'. These are control
% sequences that expand to themselves and should therefore NEVER be
@@ -74,7 +71,7 @@
% 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
-% "\if_meaning:NN". A set of special quark testing functions is set up
+% "\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.
%
@@ -83,45 +80,37 @@
% The documentation needs some updating.
%
%
-% \subsection{Functions}
+% \section{Functions}
%
-% \begin{function}{%
-% \quark_new:N |
-% }
+% \begin{function}{ \quark_new:N }
% \begin{syntax}
-% "\quark_new:N" <quark>
+% "\quark_new:N" <quark>
% \end{syntax}
% Defines <quark> to be a new constant of type "quark".
% \end{function}
%
% \begin{function}{%
-% \quark_if_no_value_p:n |
-% \quark_if_no_value:nTF |
-% \quark_if_no_value:nF |
-% \quark_if_no_value:nT |
-% \quark_if_no_value_p:N |
-% \quark_if_no_value:NTF |
-% \quark_if_no_value:NT |
-% \quark_if_no_value:NF |
+% \quark_if_no_value_p:n / (EXP) |
+% \quark_if_no_value:n / (TF)(EXP) |
+% \quark_if_no_value_p:N / (EXP) |
+% \quark_if_no_value:N / (TF)(EXP) |
% }
% \begin{syntax}
-% "\quark_if_no_value:nTF" "{"<token list>"}"
-% " {"<true code>"}{"<false code>"}"
-% "\quark_if_no_value:NTF" <tlp>
-% " {"<true code>"}{"<false code>"}"
+% "\quark_if_no_value:nTF" \Arg{token list} \Arg{true code} \Arg{false code}
+% "\quark_if_no_value:NTF" <tl var.> \Arg{true code} \Arg{false code}
% \end{syntax}
% This tests whether or not <token list> contains only the quark
% "\q_no_value".
%
-% If <token list> to be tested is stored in a token list pointer use
+% If <token list> to be tested is stored in a token list variable use
% "\quark_if_no_value:NTF", or "\quark_if_no_value:NF" or check the
-% value directly with "\if_meaning:NN". All those cases are faster then
+% value directly with "\if_meaning:w". All those cases are faster then
% "\quark_if_no_value:nTF" so should be preferred.\footnote{Clarify
% semantic of the ``n'' case \ldots{} i think it is not implement
% according to what we originally intended /FMi}
%
% \begin{texnote}
-% But be aware of the fact that "\if_meaning:NN" can result in an
+% But be aware of the fact that "\if_meaning:w" can result in an
% overflow of \TeX{}'s parameter stack since it leaves the corresponding
% "\fi:" on the input until the whole replacement text is processed. It
% is therefore better in recursions to use "\quark_if_no_value:NTF" as
@@ -131,14 +120,11 @@
% \end{function}
%
% \begin{function}{%
-% \quark_if_nil_p:N |
-% \quark_if_nil:NTF |
-% \quark_if_nil:NT |
-% \quark_if_nil:NF |
+% \quark_if_nil_p:N / (EXP) |
+% \quark_if_nil:N / (TF)(EXP) |
% }
% \begin{syntax}
-% "\quark_if_nil:NTF" <token>
-% " {"<true code>"}{"<false code>"}"
+% "\quark_if_nil:NTF" <token> \Arg{true code} \Arg{false code}
% \end{syntax}
% This tests whether or not <token> is equal to the quark
% "\q_nil".
@@ -149,18 +135,15 @@
%
%
% \begin{function}{%
-% \quark_if_nil_p:n |
-% \quark_if_nil:nTF |
-% \quark_if_nil:nT |
-% \quark_if_nil:nF |
-% \quark_if_nil_p:o |
-% \quark_if_nil:oTF |
-% \quark_if_nil:oT |
-% \quark_if_nil:oF |
+% \quark_if_nil_p:n / (EXP) |
+% \quark_if_nil_p:V / (EXP) |
+% \quark_if_nil_p:o / (EXP) |
+% \quark_if_nil:n / (TF)(EXP) |
+% \quark_if_nil:V / (TF)(EXP) |
+% \quark_if_nil:o / (TF)(EXP) |
% }
% \begin{syntax}
-% "\quark_if_nil:nTF" "{"<tokens>"}"
-% "{"<true code>"}{"<false code>"}"
+% "\quark_if_nil:nTF" \Arg{tokens} \Arg{true code} \Arg{false code}
% \end{syntax}
% This tests whether or not <tokens> is equal to the quark
% "\q_nil".
@@ -169,7 +152,7 @@
% "\q_nil" as an end marker.
% \end{function}
%
-% \subsection{Recursion}
+% \section{Recursion}
%
% This module provides a uniform interface to intercepting and
% terminating loops as when one is doing tail recursion. The building
@@ -188,12 +171,12 @@
% \end{variable}
%
% \begin{function}{%
-% \quark_if_recursion_tail_stop:N |
-% \quark_if_recursion_tail_stop:n |
-% \quark_if_recursion_tail_stop:o |
+% \quark_if_recursion_tail_stop:N / (EXP) |
+% \quark_if_recursion_tail_stop:n / (EXP) |
+% \quark_if_recursion_tail_stop:o / (EXP) |
% }
% \begin{syntax}
-% "\quark_if_recursion_tail_stop:n" "{"<list element>"}" \\
+% "\quark_if_recursion_tail_stop:n" \Arg{list element} \\
% "\quark_if_recursion_tail_stop:N" <list element>
% \end{syntax}
% This tests whether or not <list element> is equal to
@@ -205,26 +188,26 @@
% to use the "n". If you wish to use the "N" form you \emph{must}
% ensure it is really a single token such as if you have
% \begin{quote}
-% "\tlp_set:Nn \l_tmpa_tlp {" <list element> "}"
+% "\tl_set:Nn \l_tmpa_tl {" <list element> "}"
% \end{quote}
% \end{function}
%
% \begin{function}{%
-% \quark_if_recursion_tail_stop_do:Nn |
-% \quark_if_recursion_tail_stop_do:nn |
-% \quark_if_recursion_tail_stop_do:on |
+% \quark_if_recursion_tail_stop_do:Nn / (EXP) |
+% \quark_if_recursion_tail_stop_do:nn / (EXP) |
+% \quark_if_recursion_tail_stop_do:on / (EXP) |
% }
% \begin{syntax}
-% "\quark_if_recursion_tail_stop_do:nn"\\
-% "{"<list element>"}" "{" <post action> "}"
+% "\quark_if_recursion_tail_stop_do:nn"
+% ~~~~\Arg{list element} \Arg{post action}
% "\quark_if_recursion_tail_stop_do:Nn"
-% <list element> "{" <post action> "}"
+% ~~~~<list element> \Arg{post action}
% \end{syntax}
% Same as "\quark_if_recursion_tail_stop:N" except here the second
% argument is executed after the recursion has been terminated.
% \end{function}
%
-% \subsection{Constants}
+% \section{Constants}
%
% \begin{variable}{\q_no_value} The canonical `missing value quark'
% that is returned by certain functions to denote that a requested value
@@ -240,30 +223,42 @@
% This constant represent the nil pointer in pointer structures.
% \end{variable}
%
-% \StopEventually{}
+% \begin{variable}{\q_error}
+% Delimits the end of
+% the computation for purposes of error recovery.
+% \end{variable}
+%
+% \begin{variable}{\q_mark}
+% Used in parameter text when we need a scanning boundary that is
+% distinct from |\q_stop|.
+% \end{variable}
%
-% \subsection{The Implementation}
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3quark} implementation}
%
% We start by ensuring that the required packages are loaded.
% We check for \texttt{l3expan} since this a basic package that is
% essential for use of any higher-level package.
% \begin{macrocode}
-%<package>\ProvidesExplPackage
-%<package> {\filename}{\filedate}{\fileversion}{\filedescription}
-%<package>\RequirePackage{l3expan}\par
+%<*package>
+\ProvidesExplPackage
+ {\filename}{\filedate}{\fileversion}{\filedescription}
+\package_check_loaded_expl:
+%</package>
%<*initex|package>
% \end{macrocode}
%
% \begin{macro}{\quark_new:N}
% Allocate a new quark.
% \begin{macrocode}
-\def_new:Npn \quark_new:N #1{\tlp_new:Nn #1{#1}}
+\cs_new_nopar:Npn \quark_new:N #1{\tl_new:Nn #1{#1}}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\q_stop}
-% \begin{macro}{\q_no_value}
-% \begin{macro}{\q_nil}
+% \begin{macro}{\q_stop,\q_no_value,\q_nil}
% |\q_stop| is often used as a marker in parameter text,
% |\q_no_value| is the canonical missing value, and |\q_nil|
% represents a nil pointer in some data structures.
@@ -273,11 +268,8 @@
\quark_new:N \q_nil
% \end{macrocode}
% \end{macro}
-% \end{macro}
-% \end{macro}
%
-% \begin{macro}{\q_error}
-% \begin{macro}{\q_mark}
+% \begin{macro}{\q_error,\q_mark}
% We need two additional quarks. |\q_error| delimits the end of
% the computation for purposes of error recovery. |\q_mark| is
% used in parameter text when we need a scanning boundary that is
@@ -287,11 +279,9 @@
\quark_new:N\q_mark
% \end{macrocode}
% \end{macro}
-% \end{macro}
%
%
-% \begin{macro}{\q_recursion_tail}
-% \begin{macro}{\q_recursion_stop}
+% \begin{macro}{\q_recursion_tail,\q_recursion_stop}
% Quarks for ending recursions. Only ever used there!
% |\q_recursion_tail| is appended to whatever list structure we are
% doing recursion on, meaning it is added as a proper list item with
@@ -302,7 +292,6 @@
\quark_new:N\q_recursion_stop
% \end{macrocode}
% \end{macro}
-% \end{macro}
%
% \begin{macro}{\quark_if_recursion_tail_stop:n}
% \begin{macro}{\quark_if_recursion_tail_stop:N}
@@ -312,20 +301,18 @@
% marker every time we do this kind of task. Also, if the recursion
% end marker is found, we wrap things up and finish.
% \begin{macrocode}
-\def_long_new:Npn \quark_if_recursion_tail_stop:n #1 {
- \exp_after:NN\if_meaning:NN
+\cs_new:Npn \quark_if_recursion_tail_stop:n #1 {
+ \exp_after:wN\if_meaning:w
\quark_if_recursion_tail_aux:w #1?\q_nil\q_recursion_tail\q_recursion_tail
- \exp_after:NN \use_none_delimit_by_q_recursion_stop:w
+ \exp_after:wN \use_none_delimit_by_q_recursion_stop:w
\fi:
}
-\def_long_new:Npn \quark_if_recursion_tail_stop:N #1 {
- \if_meaning:NN#1\q_recursion_tail
- \exp_after:NN \use_none_delimit_by_q_recursion_stop:w
+\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:
}
-\def_new:Npn \quark_if_recursion_tail_stop:o{
- \exp_args:No\quark_if_recursion_tail_stop:n
-}
+\cs_generate_variant:Nn \quark_if_recursion_tail_stop:n {o}
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -335,77 +322,52 @@
% \begin{macro}{\quark_if_recursion_tail_stop_do:Nn}
% \begin{macro}{\quark_if_recursion_tail_stop_do:on}
% \begin{macrocode}
-\def_long_new:Npn \quark_if_recursion_tail_stop_do:nn #1#2 {
- \exp_after:NN\if_meaning:NN
+\cs_new:Npn \quark_if_recursion_tail_stop_do:nn #1#2 {
+ \exp_after:wN\if_meaning:w
\quark_if_recursion_tail_aux:w #1?\q_nil\q_recursion_tail\q_recursion_tail
- \exp_after:NN \use_arg_i_delimit_by_q_recursion_stop:nw
+ \exp_after:wN \use_i_delimit_by_q_recursion_stop:nw
\else:
- \exp_after:NN\use_none:n
+ \exp_after:wN\use_none:n
\fi:
{#2}
}
-\def_long_new:Npn \quark_if_recursion_tail_stop_do:Nn #1#2 {
- \if_meaning:NN #1\q_recursion_tail
- \exp_after:NN \use_arg_i_delimit_by_q_recursion_stop:nw
+\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:NN\use_none:n
+ \exp_after:wN\use_none:n
\fi:
{#2}
}
-\def_new:Npn \quark_if_recursion_tail_stop_do:on{
- \exp_args:No\quark_if_recursion_tail_stop_do:nn
-}
+\cs_generate_variant:Nn \quark_if_recursion_tail_stop_do:nn {on}
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
-% \begin{macro}{\quark_if_recursion_tail_aux:w}
-% \begin{macro}{\use_none_delimit_by_q_recursion_stop:w}
-% \begin{macro}{\use_arg_i_delimit_by_q_recursion_stop:nw}
-% Helper macros for picking up the first token of a list to see if
-% it is "\q_recursion_tail" and to stop the recursion.
+% \begin{macro}[aux]{\quark_if_recursion_tail_aux:w}
% \begin{macrocode}
-\def_long_new:Npn \quark_if_recursion_tail_aux:w
- #1#2\q_nil\q_recursion_tail{#1}
-\def_long_new:Npn\use_none_delimit_by_q_recursion_stop:w
- #1\q_recursion_stop {}
-\def_long_new:Npn\use_arg_i_delimit_by_q_recursion_stop:nw
- #1#2\q_recursion_stop {#1}
+\cs_new:Npn \quark_if_recursion_tail_aux:w #1#2 \q_nil \q_recursion_tail {#1}
% \end{macrocode}
% \end{macro}
-% \end{macro}
-% \end{macro}
-%
%
-% \begin{macro}{\quark_if_no_value_p:N}
-% \begin{macro}{\quark_if_no_value:NTF}
-% \begin{macro}{\quark_if_no_value:NT}
-% \begin{macro}{\quark_if_no_value:NF}
-% \begin{macro}{\quark_if_no_value_p:n}
-% \begin{macro}{\quark_if_no_value:nTF}
-% \begin{macro}{\quark_if_no_value:nT}
-% \begin{macro}{\quark_if_no_value:nF}
-% \begin{macro}{\quark_if_no_value:nFT}
+% \begin{macro}{\quark_if_no_value_p:N,\quark_if_no_value_p:n}
+% \begin{macro}[TF]{\quark_if_no_value:N,\quark_if_no_value:n}
% Here we test if we found a special quark as the first argument.
-% \begin{macrocode}
-\def_long_test_function_new:npn {quark_if_no_value:N} #1 {
-% \end{macrocode}
% We better start with |\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}
- \if_meaning:NN\q_no_value#1}
-\def_long_new:Npn \quark_if_no_value_p:N #1{
- \if_meaning:NN \q_no_value #1 \c_true
- \else: \c_false \fi:
+\prg_new_conditional:Nnn \quark_if_no_value:N {p,TF,T,F} {
+ \if_meaning:w \q_no_value #1
+ \prg_return_true: \else: \prg_return_false: \fi:
}
% \end{macrocode}
% We also provide an |n| type. If run under a sufficiently new
% pdf\eTeX, it uses a built-in primitive for string comparisons,
% otherwise it uses the slower |\str_if_eq_var_p:nf| function. In the
-% latter case it would be faster to use a temporary token list pointer
+% latter case it would be faster to use a temporary token list variable
% but it would render the function non-expandable. Using the pdf\eTeX\
% primitive is the preferred approach. Note that we have to add a
% manual space token in the first part of the comparison, otherwise it
@@ -415,156 +377,87 @@
% latter test function and unfortunately this example turned up in one
% application.
% \begin{macrocode}
-\cs_if_really_free:cTF{pdf_strcmp:D}{
- \def_long_new:Npn \quark_if_no_value_p:n #1{
- \if:w \exp_args:No \str_if_eq_var_p:nf
-%<package> {\token_to_string:N\q_no_value\space}
-%<initex> {\token_to_string:N\q_no_value\text_put_sp:}
- {\tlist_to_str:n{#1}}
- \c_true
- \else:
- \c_false
+\cs_if_exist:cTF {pdf_strcmp:D}
+{
+ \prg_new_conditional:Nnn \quark_if_no_value:n {p,TF,T,F} {
+ \if_num:w \pdf_strcmp:D
+ {\exp_not:N \q_no_value}
+ {\exp_not:n{#1}} = \c_zero
+ \prg_return_true: \else: \prg_return_false:
\fi:
}
}
{
- \def_long_new:Npn \quark_if_no_value_p:n #1{
- \if_num:w
- \pdf_strcmp:D {\exp_not:N \q_no_value}{\exp_not:n{#1}}=\c_zero
- \c_true \else: \c_false \fi:
- }
-}
-\def_long_test_function_new:npn {quark_if_no_value:n} #1 {
- \if:w \quark_if_no_value_p:n{#1}}
-% \end{macrocode}
-% We also define a version where the true and false code is ordered
-% differently.
-% \begin{macrocode}
-\def_long:Npn \quark_if_no_value:nFT #1{
- \if:w \quark_if_no_value_p:n{#1}
- \exp_after:NN\use_arg_ii:nn
- \else:
- \exp_after:NN\use_arg_i:nn
+ \prg_new_conditional:Nnn \quark_if_no_value:n {p,TF,T,F} {
+ \exp_args:NNo
+ \if_predicate:w \str_if_eq_var_p:nf
+ {\token_to_str:N\q_no_value\iow_space:}
+ {\tl_to_str:n{#1}}
+ \prg_return_true: \else: \prg_return_false:
\fi:
+ }
}
% \end{macrocode}
% \end{macro}
% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
%
% \begin{macro}{\quark_if_nil_p:N}
-% \begin{macro}{\quark_if_nil:NTF}
-% \begin{macro}{\quark_if_nil:NT}
-% \begin{macro}{\quark_if_nil:NF}
+% \begin{macro}[TF]{\quark_if_nil:N}
% A function to check for the presence of |\q_nil|.
% \begin{macrocode}
-\def_long_new:Npn \quark_if_nil_p:N #1{
- \if_meaning:NN \q_nil #1 \c_true
- \else: \c_false \fi:
+\prg_new_conditional:Nnn \quark_if_nil:N {p,TF,T,F} {
+ \if_meaning:w \q_nil #1 \prg_return_true: \else: \prg_return_false: \fi:
}
-\def_long_test_function_new:npn {quark_if_nil:N}#1{
- \if_meaning:NN\q_nil#1}
% \end{macrocode}
% \end{macro}
% \end{macro}
-% \end{macro}
-% \end{macro}
%
-% \begin{macro}{\quark_if_nil_p:n}
-% \begin{macro}{\quark_if_nil:nTF}
-% \begin{macro}{\quark_if_nil:nT}
-% \begin{macro}{\quark_if_nil:nF}
-% \begin{macro}{\quark_if_nil_p:o}
-% \begin{macro}{\quark_if_nil:oTF}
-% \begin{macro}{\quark_if_nil:oT}
-% \begin{macro}{\quark_if_nil:oF}
+% \begin{macro}{\quark_if_nil_p:n,\quark_if_nil_p:V,\quark_if_nil_p:o}
+% \begin{macro}[TF]{\quark_if_nil:n,\quark_if_nil:V,\quark_if_nil:o}
% A function to check for the presence of |\q_nil|.
% \begin{macrocode}
-\cs_if_really_free:cTF{pdf_strcmp:D}{
- \def_long_new:Npn \quark_if_nil_p:n #1{
- \if:w \exp_args:No \str_if_eq_var_p:nf
-%<package> {\token_to_string:N\q_nil\space}
-%<initex> {\token_to_string:N\q_nil\text_put_sp:}
- {\tlist_to_str:n{#1}}
- \c_true
- \else:
- \c_false
+\cs_if_exist:cTF {pdf_strcmp:D} {
+ \prg_new_conditional:Nnn \quark_if_nil:n {p,TF,T,F} {
+ \if_num:w \pdf_strcmp:D
+ {\exp_not:N \q_nil}
+ {\exp_not:n{#1}} = \c_zero
+ \prg_return_true: \else: \prg_return_false:
\fi:
}
}
{
- \def_long_new:Npn \quark_if_nil_p:n #1{
- \if_num:w
- \pdf_strcmp:D {\exp_not:N \q_nil}{\exp_not:n{#1}}=\c_zero
- \c_true \else: \c_false \fi:
+ \prg_new_conditional:Nnn \quark_if_nil:n {p,TF,T,F} {
+ \exp_args:NNo
+ \if_predicate:w \str_if_eq_var_p:nf
+ {\token_to_str:N\q_nil\iow_space:}
+ {\tl_to_str:n{#1}}
+ \prg_return_true: \else: \prg_return_false:
+ \fi:
}
}
-\def_long_test_function_new:npn {quark_if_nil:n} #1 {
- \if:w \quark_if_nil_p:n{#1}}
-\def_new:Npn \quark_if_nil_p:o{\exp_args:No\quark_if_nil_p:n}
-\def_new:Npn \quark_if_nil:oTF{\exp_args:No\quark_if_nil:nTF}
-\def_new:Npn \quark_if_nil:oT {\exp_args:No\quark_if_nil:nT}
-\def_new:Npn \quark_if_nil:oF {\exp_args:No\quark_if_nil:nF}
+\cs_generate_variant:Nn \quark_if_nil_p:n {V}
+\cs_generate_variant:Nn \quark_if_nil:nTF {V}
+\cs_generate_variant:Nn \quark_if_nil:nT {V}
+\cs_generate_variant:Nn \quark_if_nil:nF {V}
+\cs_generate_variant:Nn \quark_if_nil_p:n {o}
+\cs_generate_variant:Nn \quark_if_nil:nTF {o}
+\cs_generate_variant:Nn \quark_if_nil:nT {o}
+\cs_generate_variant:Nn \quark_if_nil:nF {o}
% \end{macrocode}
% \end{macro}
% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
+%
+%
%
% Show token usage:
% \begin{macrocode}
-%</initex|package>
+
%<*showmemory>
\showMemUsage
%</showmemory>
% \end{macrocode}
%
-% \endinput
-%
-% $Log$
-% Revision 1.22 2006/07/30 14:39:02 morten
-% Changed all quark functions to be expandable regardless of whether
-% \pdfstrcmp is available.
-%
-% Revision 1.21 2006/07/25 15:34:21 morten
-% Added the non-expandable \quark_if_nil:nTF plus variants.
-%
-% Revision 1.20 2006/07/23 13:43:47 morten
-% Fixed minor bug in \quark_if_no_value_p:n
-%
-% Revision 1.19 2006/03/20 18:26:38 braams
-% Updated the copyright notice (2006) and demoted all implementation
-% sections to subsections and so on to clean up the toc for source3.tex
-%
-% Revision 1.18 2006/01/04 01:18:31 morten
-% Changed \quark_if_no_value:nTF to be expandable. Added a few predicate
-% functions and updated documentation.
-%
-% Revision 1.17 2005/12/27 10:04:41 morten
-% Minor changes plus changed RCS information retrieval
-%
-% Revision 1.16 2005/10/27 14:12:28 morten
-% Added gobble-until-quark functions.
-%
-% Revision 1.15 2005/07/14 18:50:31 morten
-% Added \quark_if_nil:NF
-%
-% Revision 1.14 2005/04/06 13:55:57 morten
-% Fixed \quark_if_nil:NTF
-%
-% Revision 1.13 2005/03/16 22:35:57 braams
-% Added the tweaks necessary to be able to load with initex
-%
-% Revision 1.12 2005/03/11 21:41:27 braams
-% Fixed the use of RCS information; added \StopEventually
+% \end{implementation}
+% \PrintIndex
%
+% \endinput
diff --git a/Master/texmf-dist/source/latex/expl3/l3seq.dtx b/Master/texmf-dist/source/latex/expl3/l3seq.dtx
index 259d5630c43..139e5038579 100644
--- a/Master/texmf-dist/source/latex/expl3/l3seq.dtx
+++ b/Master/texmf-dist/source/latex/expl3/l3seq.dtx
@@ -1,5 +1,5 @@
% \iffalse
-%% File: l3seq.dtx Copyright (C) 1990-2006 LaTeX3 project
+%% File: l3seq.dtx Copyright (C) 1990-2009 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
@@ -17,7 +17,7 @@
%%
%% The development version of the bundle can be found at
%%
-%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/
+%% http://www.latex-project.org/svnroot/experimental/trunk/
%%
%% for those people who are interested.
%%
@@ -36,7 +36,7 @@
\RequirePackage{l3names}
%</driver|package>
%\fi
-\GetIdInfo$Id: l3seq.dtx 621 2007-09-01 20:14:19Z morten $
+\GetIdInfo$Id: l3seq.dtx 1362 2009-05-28 20:19:21Z joseph $
{L3 Experimental sequences and stacks}
%\iffalse
%<*driver>
@@ -44,7 +44,7 @@
\ProvidesFile{\filename.\filenameext}
[\filedate\space v\fileversion\space\filedescription]
%\iffalse
-\documentclass{l3doc}
+\documentclass[full]{l3doc}
\begin{document}
\DocInput{\filename.\filenameext}
\end{document}
@@ -60,9 +60,7 @@
% \date{\filedate}
% \maketitle
%
-%
-%
-% \section{Sequences}
+% \begin{documentation}
%
% \LaTeX3 implements a data type called `sequences'. These are special
% token lists that can be accessed via special function on the `left'.
@@ -73,8 +71,8 @@
% functions below). It is also possible to map functions on such
% sequences so that they are executed for every item on the sequence.
%
-% All functions that return items from a sequence in some \m{tlp} assume
-% that the \m{tlp} is local. See remarks below if you need a global
+% All functions that return items from a sequence in some \m{tl var.}~assume
+% that the \m{tl var.}~is local. See remarks below if you need a global
% returned value.
%
% The defined functions are not orthogonal in the sense that every
@@ -87,130 +85,180 @@
% like "\seq_push:Nn" which has the same effect. Maybe one should
% therefore remove the ``left'' functions totally.
%
-% \subsection{Functions}
+% \section{Functions for creating/initialising sequences}
%
-% \begin{function}{%
-% \seq_new:N |
-% \seq_new:c |
-% }
+% \begin{function}{ \seq_new:N |
+% \seq_new:c }
% \begin{syntax}
% "\seq_new:N" <sequence>
% \end{syntax}
-% Defines <sequence> to be a variable of type sequences.
+% Defines <sequence> to be a variable of type "seq".
% \end{function}
%
-% \begin{function}{%
-% \seq_clear:N |
-% \seq_clear:c |
+% \begin{function}{ \seq_clear:N |
+% \seq_clear:c |
% \seq_gclear:N |
-% \seq_gclear:c |
-% }
+% \seq_gclear:c }
% \begin{syntax}
% "\seq_clear:N" <sequence>
% \end{syntax}
% These functions locally or globally clear <sequence>.
% \end{function}
%
+% \begin{function}{ \seq_clear_new:N |
+% \seq_clear_new:c |
+% \seq_gclear_new:N |
+% \seq_gclear_new:c }
+% \begin{syntax}
+% "\seq_clear_new:N" <sequence>
+% \end{syntax}
+% These functions locally or globally clear <sequence> if it exists or
+% otherwise allocates it.
+% \end{function}
+%
+% \begin{function}{ \seq_set_eq:NN |
+% \seq_set_eq:cN |
+% \seq_set_eq:Nc |
+% \seq_set_eq:cc }
+% \begin{syntax}
+% "\seq_set_eq:NN" <seq1> <seq2>
+% \end{syntax}
+% Function that locally makes <seq1> identical to <seq2>.
+% \end{function}
+%
+% \begin{function}{ \seq_gset_eq:NN |
+% \seq_gset_eq:cN |
+% \seq_gset_eq:Nc |
+% \seq_gset_eq:cc }
+% \begin{syntax}
+% "\seq_gset_eq:NN" <seq1> <seq2>
+% \end{syntax}
+% Function that globally makes <seq1> identical to <seq2>.
+% \end{function}
+%
+% \begin{function}{%
+% \seq_gconcat:NNN |
+% \seq_gconcat:ccc |
+% }
+% \begin{syntax}
+% "\seq_gconcat:NNN" <seq1> <seq2> <seq3>
+% \end{syntax}
+% Function that conatenates <seq2> and <seq3> and globally assigns the
+% result to <seq1>.
+% \end{function}
+%
+% \section{Adding data to sequences}
+%
% \begin{function}{%
% \seq_put_left:Nn |
+% \seq_put_left:NV |
% \seq_put_left:No |
% \seq_put_left:Nx |
% \seq_put_left:cn |
-% \seq_put_right:Nn |
-% \seq_put_right:No |
-% \seq_put_right:Nx |
+% \seq_put_left:cV |
+% \seq_put_left:co |
% }
% \begin{syntax}
% "\seq_put_left:Nn" <sequence> <token list>
% \end{syntax}
% Locally appends <token list> as a single item to the left
-% or right of <sequence>. <token list> might get expanded before
-% appending.
+% of <sequence>. <token list> might get expanded before
+% appending according to the variant.
% \end{function}
%
% \begin{function}{%
-% \seq_gput_left:Nn |
-% \seq_gput_right:Nn |
-% \seq_gput_right:Nc |
-% \seq_gput_right:No |
-% \seq_gput_right:cn |
-% \seq_gput_right:co |
-% \seq_gput_right:cc |
+% \seq_put_right:Nn |
+% \seq_put_right:NV |
+% \seq_put_right:No |
+% \seq_put_right:Nx |
+% \seq_put_right:cn |
+% \seq_put_right:cV |
+% \seq_put_right:co |
% }
% \begin{syntax}
-% "\seq_gput_left:Nn" <sequence> <token list>
+% "\seq_put_right:Nn" <sequence> <token list>
% \end{syntax}
-% Globally appends <token list> as a single item to the left
-% or right of <sequence>.
+% Locally appends <token list> as a single item to the right
+% of <sequence>. <token list> might get expanded before
+% appending according to the variant.
% \end{function}
%
% \begin{function}{%
-% \seq_get:NN |
-% \seq_get:cN |
+% \seq_gput_left:Nn |
+% \seq_gput_left:NV |
+% \seq_gput_left:No |
+% \seq_gput_left:Nx |
+% \seq_gput_left:cn |
+% \seq_gput_left:cV |
+% \seq_gput_left:co |
% }
% \begin{syntax}
-% "\seq_get:NN" <sequence> <tlp>
+% "\seq_gput_left:Nn" <sequence> <token list>
% \end{syntax}
-% Functions that locally assign the left-most item of <sequence> to the
-% token list pointer <tlp>. Item is not removed from <sequence>! If you
-% need a global return value you need to code something like this:
-% \begin{quote}
-% "\seq_get:NN" <sequence> "\l_tmpa_tlp" \\
-% "\tlp_gset_eq:NN" <global tlp> "\l_tmpa_tlp"
-% \end{quote}
-% But if this kind of construction is used often enough a separate
-% function should be provided.
+% Globally appends <token list> as a single item to the left
+% of <sequence>.
% \end{function}
%
% \begin{function}{%
-% \seq_set_eq:NN
+% \seq_gput_right:Nn |
+% \seq_gput_right:NV |
+% \seq_gput_right:No |
+% \seq_gput_right:Nx |
+% \seq_gput_right:cn |
+% \seq_gput_right:cV |
+% \seq_gput_right:co |
% }
% \begin{syntax}
-% "\seq_set_eq:NN" <seq1> <seq2>
+% "\seq_gput_right:Nn" <sequence> <token list>
% \end{syntax}
-% Function that locally makes <seq1> identical to <seq2>.
+% Globally appends <token list> as a single item to the right
+% of <sequence>.
% \end{function}
%
-%
-%
% \begin{function}{%
-% \seq_gset_eq:NN |
-% \seq_gset_eq:cN |
-% \seq_gset_eq:Nc |
-% \seq_gset_eq:cc
+% \seq_gput_right:Nc |
% }
-% \begin{syntax}
-% "\seq_gset_eq:NN" <seq1> <seq2>
-% \end{syntax}
-% Function that globally makes <seq1> identical to <seq2>.
+% Variant of the above used in the |xor| package.
+% Will probably be moved soon to that package. (Sep 2008)
% \end{function}
%
+% \section{Working with sequences}
+%
% \begin{function}{%
-% \seq_gconcat:NNN |
-% \seq_gconcat:ccc |
+% \seq_get:NN |
+% \seq_get:cN |
% }
% \begin{syntax}
-% "\seq_gconcat:NNN" <seq1> <seq2> <seq3>
+% "\seq_get:NN" <sequence> <tl var.>
% \end{syntax}
-% Function that conatenates <seq2> and <seq3> and globally assigns the
-% result to <seq1>.
+% Functions that locally assign the left-most item of <sequence> to the
+% token list variable <tl var.>. Item is not removed from <sequence>! If you
+% need a global return value you need to code something like this:
+% \begin{quote}
+% "\seq_get:NN" <sequence> "\l_tmpa_tl" \\
+% "\tl_gset_eq:NN" <global tl var.> "\l_tmpa_tl"
+% \end{quote}
+% But if this kind of construction is used often enough a separate
+% function should be provided.
% \end{function}
%
+%
% \begin{function}{\seq_map_variable:NNn |
% \seq_map_variable:cNn
% }
% \begin{syntax}
-% "\seq_map_variable:NNn" <sequence> <tlp> "{" <code using tlp> "}"
+% "\seq_map_variable:NNn" <sequence> <tl var.> \Arg{code using tl var.}
% \end{syntax}
-% Every element in <sequence> is assigned to <tlp> and then <code
-% using tlp> is executed. The operation is not expandable which means
+% Every element in <sequence> is assigned to <tl var.> and then <code
+% using tl var.> is executed. The operation is not expandable which means
% that it can't be used within write operations etc. However, this
% function can be nested which the others can't.
% \end{function}
%
-% \begin{function}{\seq_map:NN}
+% \begin{function}{ \seq_map_function:NN |
+% \seq_map_function:cN }
% \begin{syntax}
-% "\seq_map:NN" <sequences> <function>
+% "\seq_map_function:NN" <sequence> <function>
% \end{syntax}
% This function applies <function> (which must be a function with one
% argument) to every item of <sequence>. <function> is not executed
@@ -226,55 +274,67 @@
% \seq_map_inline:cn
% }
% \begin{syntax}
-% "\seq_map_inline:Nn" <sequence> "{" <inline function> "}"
+% "\seq_map_inline:Nn" <sequence> \Arg{inline function}
% \end{syntax}
% Applies <inline function> (which should be the direct coding for a
-% function with one argument (i.e.\ use "##1" as the place holder for
+% function with one argument (i.e.\ use "#1" as the place holder for
% this argument)) to every item of <sequence>. <inline function> is not
% executed within a sub-group so that side effects can be achieved locally.
% The operation is not expandable which means that it can't be used
% within write operations etc.
% \end{function}
%
-% \subsection{Predicates and conditionals}
+% \begin{function}{ \seq_show:N |
+% \seq_show:c }
+% \begin{syntax}
+% "\seq_show:N" <sequence>
+% \end{syntax}
+% Function that pauses the compilation and displays <seq> in the terminal
+% output and in the log file. (Usually used for diagnostic purposes.)
+% \end{function}
+%
+% \begin{function}{ \seq_display:N |
+% \seq_display:c }
+% \begin{syntax}
+% "\seq_display:N" <sequence>
+% \end{syntax}
+% As with "\seq_show:N" but pretty prints the output one line per element.
+% \end{function}
+%
+% \section{Predicates and conditionals}
%
-% \begin{function}{\seq_if_empty_p:N}
+% \begin{function}{ \seq_if_empty_p:N / (EXP) |
+% \seq_if_empty_p:c / (EXP) }
% \begin{syntax}
% "\seq_if_empty_p:N" <sequence>
% \end{syntax}
% This predicate returns `true' if <sequence> is `empty' i.e., doesn't
-% contain any tokens.
+% contain any items. Note that this is `false' even if the <sequence> only
+% contains a single empty item.
% \end{function}
%
-% \begin{function}{%
-% \seq_if_empty:NTF |
-% \seq_if_empty:cTF |
-% \seq_if_empty:NF |
-% \seq_if_empty:cF |
-% }
+% \begin{function}{ \seq_if_empty:N / (TF) |
+% \seq_if_empty:c / (TF) }
% \begin{syntax}
-% "\seq_if_empty:NTF" <sequence> "{" <true code> "}{" <false code> "}"
+% "\seq_if_empty:NTF" <sequence> \Arg{true code} \Arg{false code}
% \end{syntax}
% Set of conditionals that test whether or not a particular <sequence>
% is empty and if so executes either <true code> or <false code>.
% \end{function}
%
-% \begin{function}{%
-% \seq_if_in:NnTF |
-% \seq_if_in:cnTF |
-% \seq_if_in:coTF |
-% \seq_if_in:cxTF |
-% \seq_if_in:NnF |
-% \seq_if_in:cnF |
-% }
+% \begin{function}{ \seq_if_in:Nn / (TF) |
+% \seq_if_in:cn / (TF) |
+% \seq_if_in:cV / (TF) |
+% \seq_if_in:co / (TF) |
+% \seq_if_in:cx / (TF) }
% \begin{syntax}
-% "\seq_if_in:NnTF" <sequ> "{" <item> "}{" <true code> "}{" <false code> "}"
+% "\seq_if_in:NnTF" <sequence> \Arg{item} \Arg{true code} \Arg{false code}
% \end{syntax}
-% Function that tests if <item> is in <sequ>. Depending on the result
+% Functions that test if <item> is in <sequence>. Depending on the result
% either <true code> or <false code> is executed.
% \end{function}
%
-% \subsection{Internal functions}
+% \section{Internal functions}
%
% \begin{function}{\seq_if_empty_err:N}
% \begin{syntax}
@@ -285,9 +345,9 @@
%
% \begin{function}{\seq_pop_aux:nnNN}
% \begin{syntax}
-% "\seq_pop_aux:nnNN" <assign1> <assign2> <sequence> <tlp>
+% "\seq_pop_aux:nnNN" <assign1> <assign2> <sequence> <tl var.>
% \end{syntax}
-% Function that assigns the left-most item of <sequence> to <tlp> using
+% Function that assigns the left-most item of <sequence> to <tl var.> using
% <assign1> and assigns the tail to <sequence> using <assign2>. This
% function could be used to implement a global return function.
% \end{function}
@@ -302,8 +362,12 @@
% meant for direct use.
% \end{function}
%
-% \begin{function}{%
-% \seq_elt:w |
+% \begin{function}{ \seq_map_break: | \seq_map_break:n }
+% Functions used to implement mapping operations. They are not for
+% meant for direct use.
+% \end{function}
+%
+% \begin{function}{ \seq_elt:w |
% \seq_elt_end: }
% Functions (usually used as constants) that separates items within a
% sequence. They might get special meaning during mapping operations and
@@ -311,27 +375,28 @@
% sequence.
% \end{function}
%
-% \section{Sequence Stacks}
+% \section{Functions for `Sequence Stacks'}
%
% Special sequences in \LaTeX3 are `stacks' with their usual operations
-% of`push', `pop', and `top'. They are internally implemented as
+% of `push', `pop', and `top'. They are internally implemented as
% sequences and share some of the functions (like "\seq_new:N" etc.)
%
-% \subsection{Functions}
-%
% \begin{function}{%
% \seq_push:Nn |
+% \seq_push:NV |
% \seq_push:No |
% \seq_push:cn |
% \seq_gpush:Nn |
+% \seq_gpush:NV |
% \seq_gpush:No |
+% \seq_gpush:Nv |
% \seq_gpush:cn |
% }
% \begin{syntax}
-% "\seq_push:Nn" <stack> "{" <token list> "}"
+% "\seq_push:Nn" <stack> \Arg{token list}
% \end{syntax}
% Locally or globally pushes <token list> as a single item onto the
-% <stack>. <token list> might get expanded before the operation.
+% <stack>.
% \end{function}
%
% \begin{function}{%
@@ -341,10 +406,10 @@
% \seq_gpop:cN |
% }
% \begin{syntax}
-% "\seq_pop:NN" <stack> <tlp>
+% "\seq_pop:NN" <stack> <tl var.>
% \end{syntax}
-% Functions that assign the top item of <stack> to the token
-% list pointer <tlp> and removes it from <stack>!
+% Functions that assign the top item of <stack> to <tl var.>
+% and removes it from <stack>!
% \end{function}
%
% \begin{function}{%
@@ -352,34 +417,29 @@
% \seq_top:cN |
% }
% \begin{syntax}
-% "\seq_top:NN" <stack> <tlp>
+% "\seq_top:NN" <stack> <tl var.>
% \end{syntax}
-% Functions that locally assign the top item of <stack> to the token
-% list pointer <tlp>. Item is not removed from <stack>!
+% Functions that locally assign the top item of <stack> to the <tl var.>.
+% Item is \emph{not} removed from <stack>!
% \end{function}
%
-% \subsection{Predicates and conditionals}
-%
-% Use "seq" functions.
+% \end{documentation}
%
-% \StopEventually{}
+% \begin{implementation}
%
-% \subsection {Implementation}
+% \section{\pkg{l3seq} implementation}
%
-%
-% We start by ensuring that the required packages are loaded.
% \begin{macrocode}
-%<package>\ProvidesExplPackage
-%<package> {\filename}{\filedate}{\fileversion}{\filedescription}
-%<package&!check>\RequirePackage{l3quark}
-%<package&!check>\RequirePackage{l3tlp}
-%<package&check>\RequirePackage{l3chk}
-%<package>\RequirePackage{l3expan}
+%<*package>
+\ProvidesExplPackage
+ {\filename}{\filedate}{\fileversion}{\filedescription}
+\package_check_loaded_expl:
+%</package>
% \end{macrocode}
%
% A sequence is a control sequence whose top-level expansion is of the
% form `|\seq_elt:w| \m{text$\sb1$} |\seq_elt_end:| \ldots{}
-% |\seq_elt:w| \zv{text$\sb{n}$} \ldots'. We use explicit delimiters
+% |\seq_elt:w| \meta{text$\sb{n}$} \ldots'. We use explicit delimiters
% instead of braces around \m{text} to allow efficient searching for
% an item in the sequence.
%
@@ -388,19 +448,20 @@
% We allocate the delimiters and make them errors if executed.
% \begin{macrocode}
%<*initex|package>
-\let_new:NN \seq_elt:w \ERROR
-\let_new:NN \seq_elt_end: \ERROR
+\cs_new:Npn \seq_elt:w {\ERROR}
+\cs_new:Npn \seq_elt_end: {\ERROR}
% \end{macrocode}
% \end{macro}
% \end{macro}
%
+% \subsection{Allocating and initialisation}
%
% \begin{macro}{\seq_new:N}
% \begin{macro}{\seq_new:c}
% Sequences are implemented using token lists.
% \begin{macrocode}
-\def_new:Npn \seq_new:N #1{\tlp_new:Nn #1{}}
-\def_new:Npn \seq_new:c {\exp_args:Nc \seq_new:N}
+\cs_new_eq:NN \seq_new:N \tl_new:N
+\cs_new_eq:NN \seq_new:c \tl_new:c
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -411,10 +472,10 @@
% \begin{macro}{\seq_gclear:c}
% Clearing a sequence is the same as clearing a token list.
% \begin{macrocode}
-\let_new:NN \seq_clear:N \tlp_clear:N
-\let_new:NN \seq_clear:c \tlp_clear:c
-\let_new:NN \seq_gclear:N \tlp_gclear:N
-\let_new:NN \seq_gclear:c \tlp_gclear: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
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -427,128 +488,248 @@
% \begin{macro}{\seq_gclear_new:c}
% Clearing a sequence is the same as clearing a token list.
% \begin{macrocode}
-\let_new:NN \seq_clear_new:N \tlp_clear_new:N
-\let_new:NN \seq_clear_new:c \tlp_clear_new:c
-\let_new:NN \seq_gclear_new:N \tlp_gclear_new:N
-\let_new:NN \seq_gclear_new:c \tlp_gclear_new: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
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\seq_set_eq:NN}
+% \begin{macro}{\seq_set_eq:Nc}
+% \begin{macro}{\seq_set_eq:cN}
+% \begin{macro}{\seq_set_eq:cc}
+% We can set one "seq" equal to another.
+% \begin{macrocode}
+\cs_new_eq:NN \seq_set_eq:NN \cs_set_eq:NN
+\cs_new_eq:NN \seq_set_eq:cN \cs_set_eq:cN
+\cs_new_eq:NN \seq_set_eq:Nc \cs_set_eq:Nc
+\cs_new_eq:NN \seq_set_eq:cc \cs_set_eq:cc
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
-% \begin{macro}{\seq_if_empty_p:N}
-% A predicate which evaluates to |\c_true| iff the sequence is empty.
+% \begin{macro}{\seq_gset_eq:NN}
+% \begin{macro}{\seq_gset_eq:cN}
+% \begin{macro}{\seq_gset_eq:Nc}
+% \begin{macro}{\seq_gset_eq:cc}
+% And of course globally which seems to be needed far more
+% often.\footnote{To save a bit of space these functions could be made
+% identical to those from the tl or clist module.}
% \begin{macrocode}
-\let_new:NN \seq_if_empty_p:N \tlp_if_empty_p:N
+\cs_new_eq:NN \seq_gset_eq:NN \cs_gset_eq:NN
+\cs_new_eq:NN \seq_gset_eq:cN \cs_gset_eq:cN
+\cs_new_eq:NN \seq_gset_eq:Nc \cs_gset_eq:Nc
+\cs_new_eq:NN \seq_gset_eq:cc \cs_gset_eq:cc
% \end{macrocode}
% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
%
-% \begin{macro}{\seq_if_empty:NTF}
-% \begin{macro}{\seq_if_empty:cTF}
-% \begin{macro}{\seq_if_empty:NF}
-% \begin{macro}{\seq_if_empty:cF}
-% |\seq_if_empty:NTF|\m{seq}\m{true~case}\m{false~case} will check
-% whether the \m{seq} is empty and then select one of the other
-% arguments. |seq_if_empty:cTF| turns its first argument into a
-% control sequence to get the name of the sequence.
+% \begin{macro}{\seq_gconcat:NNN,\seq_gconcat:ccc}
+% |\seq_gconcat:NNN| \m{seq~1} \m{seq~2} \m{seq~3} will globally
+% assign \m{seq~1} the concatenation of \m{seq~2} and \m{seq~3}.
% \begin{macrocode}
-\let_new:NN \seq_if_empty:NTF \tlp_if_empty:NTF
-\def_new:Npn \seq_if_empty:cTF {\exp_args:Nc\seq_if_empty:NTF}
+\cs_new_nopar:Npn \seq_gconcat:NNN #1#2#3 {
+ \tl_gset:Nx #1 { \exp_not:V #2 \exp_not:V #3 }
+}
+\cs_generate_variant:Nn \seq_gconcat:NNN {ccc}
% \end{macrocode}
-% A variant of this, is only to do something if the sequence is
-% \emph{not} empty.
+% \end{macro}
+%
+% \subsection{Predicates and conditionals}
+%
+% \begin{macro}{\seq_if_empty_p:N,\seq_if_empty_p:c}
+% \begin{macro}[TF]{\seq_if_empty:N,\seq_if_empty:c}
+% A predicate which evaluates to |\c_true_bool| iff the sequence is empty.
% \begin{macrocode}
-\let_new:NN \seq_if_empty:NF \tlp_if_empty:NF
-\def_new:Npn \seq_if_empty:cF {\exp_args:Nc\seq_if_empty:NF}
+\prg_new_eq_conditional:NNn \seq_if_empty:N \tl_if_empty:N {p,TF,T,F}
+\prg_new_eq_conditional:NNn \seq_if_empty:c \tl_if_empty:c {p,TF,T,F}
% \end{macrocode}
% \end{macro}
% \end{macro}
-% \end{macro}
-% \end{macro}
%
%
% \begin{macro}{\seq_if_empty_err:N}
% Signals an error if the sequence is empty.
% \begin{macrocode}
-\def_new:Npn \seq_if_empty_err:N #1{\if_meaning:NN#1\c_empty_tlp
+\cs_new_nopar:Npn \seq_if_empty_err:N #1 {
+ \if_meaning:w #1 \c_empty_tl
% \end{macrocode}
% As I said before, I don't think we need to provide checks for this
% kind of error, since it is a severe internal macro package error
% that can not be produced by the user directly. Can it? So the
% next line of code should be probably removed.
+% (Will: I have no idea what this comment means.)
% \begin{macrocode}
- \tlp_clear:N \l_testa_tlp % catch prefixes
- \err_latex_bug:x{Empty~sequence~`\token_to_string:N#1'}\fi:}
+ \tl_clear:N \l_testa_tl % catch prefixes
+ \msg_kernel_bug:x {Empty~sequence~`\token_to_str:N#1'}
+ \fi:
+}
% \end{macrocode}
% \end{macro}
%
+% \begin{macro}[TF]{\seq_if_in:Nn,\seq_if_in:cn,
+% \seq_if_in:cV,\seq_if_in:co,\seq_if_in:cx}
+% |\seq_if_in:NnTF| \m{seq}\m{item} \m{true~case} \m{false~case}
+% will check whether \m{item} is in \m{seq} and then either execute
+% the \m{true~case} or the \m{false~case}. \m{true~case} and
+% \m{false~case} may contain incomplete |\if_charcode:w|
+% statements.
+%
+% Note that |##2| in the definition below for "\seq_tmp:w" contains
+% exactly one token which we can compare with |\q_no_value|.
+% \begin{macrocode}
+\prg_new_conditional:Nnn \seq_if_in:Nn {TF,T,F} {
+ \cs_set:Npn \seq_tmp:w ##1 \seq_elt:w #2 \seq_elt_end: ##2##3 \q_stop {
+ \if_meaning:w \q_no_value ##2
+ \prg_return_false: \else: \prg_return_true: \fi:
+ }
+ \exp_after:wN \seq_tmp:w #1 \seq_elt:w #2 \seq_elt_end: \q_no_value \q_stop
+}
+% \end{macrocode}
+% \begin{macrocode}
+\cs_generate_variant:Nn \seq_if_in:NnTF {cV,co,c,cx}
+\cs_generate_variant:Nn \seq_if_in:NnT {cV,co,c,cx}
+\cs_generate_variant:Nn \seq_if_in:NnF {cV,co,c,cx}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Getting data out}
+%
% \begin{macro}{\seq_get:NN}
% \begin{macro}{\seq_get:cN}
-% |\seq_get:NN |\zz{sequence}\zz{cmd} defines \zz{cmd} to be the
-% left_most element of \zz{sequence}.
+% \begin{macro}{\seq_get_aux:w}
+% |\seq_get:NN |\meta{sequence}\meta{cmd} defines \meta{cmd} to be the
+% left-most element of \meta{sequence}.
% \begin{macrocode}
-\def_new:Npn \seq_get:NN #1{
+\cs_new_nopar:Npn \seq_get:NN #1 {
\seq_if_empty_err:N #1
- \exp_after:NN\seq_get_aux:w #1\q_stop}
-\def_new:Npn \seq_get_aux:w \seq_elt:w #1\seq_elt_end:
- #2\q_stop #3{\tlp_set:Nn #3{#1}}
-\def_new:Npn \seq_get:cN {\exp_args:Nc \seq_get:NN}
+ \exp_after:wN \seq_get_aux:w #1 \q_stop
+}
+\cs_new:Npn \seq_get_aux:w \seq_elt:w #1 \seq_elt_end: #2 \q_stop #3 {
+ \tl_set:Nn #3 {#1}
+}
+\cs_generate_variant:Nn \seq_get:NN {c}
% \end{macrocode}
% \end{macro}
% \end{macro}
+% \end{macro}
%
% \begin{macro}{\seq_pop_aux:nnNN}
% \begin{macro}{\seq_pop_aux:w}
-% |\seq_pop_aux:nnNN| \zz{def$\sb1$} \zz{def$\sb2$} \zz{sequence}
-% \zz{cmd} assigns the left_most element of \zz{sequence} to
-% \zz{cmd} using \zz{def$\sb2$}, and assigns the tail of
-% \zz{sequence} to \zz{sequence} using \zz{def$\sb1$}.
+% |\seq_pop_aux:nnNN| \meta{def$\sb1$} \meta{def$\sb2$} \meta{sequence}
+% \meta{cmd} assigns the left_most element of \meta{sequence} to
+% \meta{cmd} using \meta{def$\sb2$}, and assigns the tail of
+% \meta{sequence} to \meta{sequence} using \meta{def$\sb1$}.
% \begin{macrocode}
-\def_new:Npn \seq_pop_aux:nnNN #1#2#3{
+\cs_new:Npn \seq_pop_aux:nnNN #1#2#3 {
\seq_if_empty_err:N #3
- \exp_after:NN\seq_pop_aux:w #3\q_stop #1#2#3}
-\def_new:Npn \seq_pop_aux:w \seq_elt:w #1\seq_elt_end:
- #2\q_stop #3#4#5#6{#3#5{#2}#4#6{#1}}
+ \exp_after:wN \seq_pop_aux:w #3 \q_stop #1#2#3
+}
+\cs_new:Npn \seq_pop_aux:w
+ \seq_elt:w #1 \seq_elt_end: #2\q_stop #3#4#5#6 {
+ #3 #5 {#2}
+ #4 #6 {#1}
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\seq_show:N}
+% \begin{macro}{\seq_show:c}
+% \begin{macrocode}
+\cs_new_eq:NN \seq_show:N \tl_show:N
+\cs_new_eq:NN \seq_show:c \tl_show:c
% \end{macrocode}
% \end{macro}
% \end{macro}
%
+% \begin{macro}{\seq_display:N}
+% \begin{macro}{\seq_display:c}
+% \begin{macrocode}
+\cs_new_nopar:Npn \seq_display:N #1 {
+ \iow_term:x { Sequence~\token_to_str:N #1~contains~
+ the~elements~(without~outer~braces): }
+ \toks_clear:N \l_tmpa_toks
+ \seq_map_inline:Nn #1 {
+ \toks_if_empty:NF \l_tmpa_toks {
+ \toks_put_right:Nx \l_tmpa_toks {^^J>~}
+ }
+ \toks_put_right:Nx \l_tmpa_toks {
+ \iow_space: \iow_char:N \{ \exp_not:n {##1} \iow_char:N \}
+ }
+ }
+ \toks_show:N \l_tmpa_toks
+}
+\cs_generate_variant:Nn \seq_display:N {c}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+%
+% \subsection{Putting data in}
+%
% \begin{macro}{\seq_put_aux:Nnn}
-% |\seq_put_aux:Nnn| \zz{sequence} \zv{left} \zv{right} adds the
-% elements specified by \zv{left} to the left of \zz{sequence}, and
-% those specified by \zv{right} to the right.
+% \begin{macro}{\seq_put_aux:w}
+% |\seq_put_aux:Nnn| \meta{sequence} \meta{left} \meta{right} adds the
+% elements specified by \meta{left} to the left of \meta{sequence}, and
+% those specified by \meta{right} to the right.
% \begin{macrocode}
-\def_new:Npn \seq_put_aux:Nnn #1{
- \exp_after:NN\seq_put_aux:w #1\q_stop #1}
-\def_new:Npn \seq_put_aux:w #1\q_stop #2#3#4{\tlp_set:Nn #2{#3#1#4}}
+\cs_new:Npn \seq_put_aux:Nnn #1 {
+ \exp_after:wN \seq_put_aux:w #1 \q_stop #1
+}
+\cs_new:Npn \seq_put_aux:w #1\q_stop #2#3#4 { \tl_set:Nn #2 {#3#1#4} }
% \end{macrocode}
% \end{macro}
+% \end{macro}
%
% \begin{macro}{\seq_put_left:Nn}
+% \begin{macro}{\seq_put_left:NV}
% \begin{macro}{\seq_put_left:No}
% \begin{macro}{\seq_put_left:Nx}
% \begin{macro}{\seq_put_left:cn}
+% \begin{macro}{\seq_put_left:cV}
+% \begin{macro}{\seq_put_left:co}
% \begin{macro}{\seq_put_right:Nn}
% \begin{macro}{\seq_put_right:No}
+% \begin{macro}{\seq_put_right:NV}
% \begin{macro}{\seq_put_right:Nx}
+% \begin{macro}{\seq_put_right:cn}
+% \begin{macro}{\seq_put_right:cV}
+% \begin{macro}{\seq_put_right:co}
% Here are the usual operations for adding to the left and right.
% \begin{macrocode}
-\def_new:Npn \seq_put_left:Nn #1#2{
+\cs_new:Npn \seq_put_left:Nn #1#2 {
+ \seq_put_aux:Nnn #1 {\seq_elt:w #2\seq_elt_end:} {}
+}
+% \end{macrocode}
+% We can't put in a |\prg_do_nothing:| instead of |{}| above since this argument
+% is passed literally (and we would end up with many |\prg_do_nothing:|s inside
+% the sequences).
+% \begin{macrocode}
+\cs_generate_variant:Nn \seq_put_left:Nn {NV,No,Nx,c,cV,co}
% \end{macrocode}
-% We can't put in a |\use_noop:| instead of |{}| since this argument is
-% passed literally (and we would end up with many |\use_noop:|s inside
-% the sequences.
% \begin{macrocode}
- \seq_put_aux:Nnn #1{\seq_elt:w #2\seq_elt_end:}{}}
-\def_new:Npn \seq_put_left:cn {\exp_args:Nc\seq_put_left:Nn}
-\def_new:Npn \seq_put_left:No {\exp_args:NNo\seq_put_left:Nn}
-\def_new:Npn \seq_put_left:Nx {\exp_args:Nnx\seq_put_left:Nn}
-\def_new:Npn \seq_put_right:Nn #1#2{
+\cs_new:Npn \seq_put_right:Nn #1#2{
\seq_put_aux:Nnn #1{}{\seq_elt:w #2\seq_elt_end:}}
-\def_new:Npn \seq_put_right:No {\exp_args:NNo\seq_put_right:Nn}
-\def_new:Npn \seq_put_right:Nx {\exp_args:NNx\seq_put_right:Nn}
% \end{macrocode}
+% \begin{macrocode}
+\cs_generate_variant:Nn \seq_put_right:Nn {NV,No,Nx,c,cV,co}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
@@ -558,31 +739,46 @@
% \end{macro}
%
% \begin{macro}{\seq_gput_left:Nn}
+% \begin{macro}{\seq_gput_left:NV}
+% \begin{macro}{\seq_gput_left:No}
+% \begin{macro}{\seq_gput_left:Nx}
+% \begin{macro}{\seq_gput_left:cn}
+% \begin{macro}{\seq_gput_left:cV}
+% \begin{macro}{\seq_gput_left:co}
% \begin{macro}{\seq_gput_right:Nn}
-% \begin{macro}{\seq_gput_right:Nc}
+% \begin{macro}{\seq_gput_right:NV}
% \begin{macro}{\seq_gput_right:No}
+% \begin{macro}{\seq_gput_right:Nx}
% \begin{macro}{\seq_gput_right:cn}
+% \begin{macro}{\seq_gput_right:cV}
% \begin{macro}{\seq_gput_right:co}
-% \begin{macro}{\seq_gput_right:cc}
-% An here the global variants.
% \begin{macrocode}
-\def_new:Npn \seq_gput_left:Nn {
+\cs_new:Npn \seq_gput_left:Nn {
%<*check>
- \pref_global_chk:
+ \pref_global_chk:
%</check>
-%<-check> \pref_global:D
- \seq_put_left:Nn}
-\def_new:Npn \seq_gput_right:Nn {
+%<*!check>
+ \pref_global:D
+%</!check>
+ \seq_put_left:Nn
+}
+% \end{macrocode}
+% \begin{macrocode}
+\cs_new:Npn \seq_gput_right:Nn {
%<*check>
- \pref_global_chk:
+ \pref_global_chk:
%</check>
-%<-check> \pref_global:D
- \seq_put_right:Nn}
-\def_new:Npn \seq_gput_right:No {\exp_args:NNo \seq_gput_right:Nn}
-\def_new:Npn \seq_gput_right:Nc {\exp_args:NNc \seq_gput_right:Nn}
-\def_new:Npn \seq_gput_right:cn {\exp_args:Nc \seq_gput_right:Nn}
-\def_new:Npn \seq_gput_right:co {\exp_args:Nco \seq_gput_right:Nn}
-\def_new:Npn \seq_gput_right:cc {\exp_args:Ncc \seq_gput_right:Nn}
+%<*!check>
+ \pref_global:D
+%</!check>
+ \seq_put_right:Nn
+}
+% \end{macrocode}
+% \begin{macrocode}
+\cs_generate_variant:Nn \seq_gput_left:Nn {NV,No,Nx,c,cV,co}
+% \end{macrocode}
+% \begin{macrocode}
+\cs_generate_variant:Nn \seq_gput_right:Nn {NV,No,Nx,c,cV,co}
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -591,156 +787,88 @@
% \end{macro}
% \end{macro}
% \end{macro}
-%
-% \begin{macro}{\seq_map_variable:NNn}
-% \begin{macro}{\seq_map_variable:cNn}
-% \begin{macro}{\seq_map_variable_aux:nw}
-% \begin{macro}{\seq_map_break:w}
-% Nothing spectacular here. The shuffling of the arguments in
-% |\seq_map_variable:NNn| below could also be done with
-% |\exp_args:NNnE|.
-% \begin{macrocode}
-\def_new:Npn \seq_map_variable_aux:Nnw #1#2\seq_elt:w#3\seq_elt_end:{
- \tlp_set:Nn #1{#3}
- \quark_if_nil:NT #1 \seq_map_break:w
- #2
- \seq_map_variable_aux:Nnw #1{#2}
-}
-\def_new:Npn \seq_map_variable:NNn #1#2#3{
- \tlp_set:Nx #2 {\exp_not:n{\seq_map_variable_aux:Nnw #2{#3}}}
- \exp_after:NN #2 #1 \seq_elt:w \q_nil\seq_elt_end: \q_stop
-}
-\def_new:Npn \seq_map_variable:cNn{\exp_args:Nc\seq_map_variable:Nn}
-\let_new:NN \seq_map_break:w \use_none_delimit_by_q_stop:w
-% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
-%
-% \begin{macro}{\seq_map:NN}
-% |\seq_map:NN| \zz{sequence} \zz{cmd} applies \zz{cmd} to each
-% element of \zz{sequence}, from left to right. Since we don't have
-% braces, this implementation is not very efficient. It might be
-% better to say that \zz{cmd} must be a function with one argument
-% that is delimited by |\seq_elt_end:|.
-% \begin{macrocode}
-\def_new:Npn \seq_map:NN #1#2{
- \def:Npn \seq_elt:w ##1\seq_elt_end: {#2{##1}}#1
- \let:NN \seq_elt:w \ERROR
-}
-% \end{macrocode}
% \end{macro}
-%
-% \begin{macro}{\seq_map_inline:Nn}
-% \begin{macro}{\seq_map_inline:cn}
-% When no braces are used, this version of mapping seems more
-% natural.
-% \begin{macrocode}
-\def_new:Npn \seq_map_inline:Nn #1#2{
- \def:Npn \seq_elt:w ##1\seq_elt_end: {#2}#1
- \let:NN \seq_elt:w \ERROR
-}
-\def_new:Npn \seq_map_inline:cn{\exp_args:Nc\seq_map_inline:Nn}
-% \end{macrocode}
% \end{macro}
% \end{macro}
%
-% \begin{macro}{\seq_set_eq:NN}
-% \begin{macro}{\seq_set_eq:Nc}
-% We can set one seq equal to another.
+% \begin{macro}{\seq_gput_right:Nc}
+% TODO: move to |xor| (Sep 2008)
% \begin{macrocode}
-\let_new:NN \seq_set_eq:NN \let:NN
-\def_new:Npn \seq_set_eq:Nc {\exp_args:NNc \seq_set_eq:NN}
+\cs_generate_variant:Nn \seq_gput_right:Nn {Nc}
% \end{macrocode}
% \end{macro}
-% \end{macro}
%
+% \subsection{Mapping}
%
-% \begin{macro}{\seq_gset_eq:NN}
-% \begin{macro}{\seq_gset_eq:cN}
-% \begin{macro}{\seq_gset_eq:Nc}
-% \begin{macro}{\seq_gset_eq:cc}
-% An of course globally which seems to be needed far more
-% often.\footnote{To save a bit of space these functions could be made
-% identical to those from the tlp or clist module.}
+% \begin{macro}{\seq_map_variable:NNn}
+% \begin{macro}{\seq_map_variable:cNn}
+% \begin{macro}[aux]{\seq_map_variable_aux:Nnw}
+% \begin{macro}{\seq_map_break:}
+% \begin{macro}{\seq_map_break:n}
+% Nothing spectacular here.
% \begin{macrocode}
-\let_new:NN \seq_gset_eq:NN \glet:NN
-\def_new:Npn \seq_gset_eq:cN {\exp_args:Nc \seq_gset_eq:NN}
-\def_new:Npn \seq_gset_eq:Nc {\exp_args:NNc \seq_gset_eq:NN}
-\def_new:Npn \seq_gset_eq:cc {\exp_args:Ncc \seq_gset_eq:NN}
+\cs_new:Npn \seq_map_variable_aux:Nnw #1#2 \seq_elt:w #3 \seq_elt_end: {
+ \tl_set:Nx #1{\exp_not:n{#3}}
+ \quark_if_nil:NT #1 \seq_map_break:
+ #2
+ \seq_map_variable_aux:Nnw #1{#2}
+}
+\cs_new:Npn \seq_map_variable:NNn #1#2#3 {
+ \tl_set:Nx #2 {\exp_not:n{\seq_map_variable_aux:Nnw #2{#3}}}
+ \exp_after:wN #2 #1 \seq_elt:w \q_nil\seq_elt_end: \q_stop
+}
+\cs_generate_variant:Nn \seq_map_variable:NNn {c}
+
+\cs_new_eq:NN \seq_map_break: \use_none_delimit_by_q_stop:w
+\cs_new_eq:NN \seq_map_break:n \use_i_delimit_by_q_stop:nw
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
+% \end{macro}
%
-% \begin{macro}{\seq_gconcat:NNN}
-% \begin{macro}{\seq_gconcat:ccc}
-% |\seq_gconcat:NNN| \m{seq~1} \m{seq~2} \m{seq~3} will globally
-% assign \m{seq~1} the concatenation of \m{seq~2} and \m{seq~3}.
+% \begin{macro}{\seq_map_function:NN}
+% \begin{macro}{\seq_map_function:cN}
+% |\seq_map_function:NN| \meta{sequence} \meta{cmd} applies \meta{cmd} to each
+% element of \meta{sequence}, from left to right. Since we don't have
+% braces, this implementation is not very efficient. It might be
+% better to say that \meta{cmd} must be a function with one argument
+% that is delimited by |\seq_elt_end:|.
% \begin{macrocode}
-\def_new:Npn \seq_gconcat:NNN #1#2#3{
- \tlp_gset:Nx #1 {\exp_not:o{#2}\exp_not:o{#3}}
+\cs_new_nopar:Npn \seq_map_function:NN #1#2 {
+ \cs_set:Npn \seq_elt:w ##1 \seq_elt_end: {#2{##1}}
+ #1
+ \cs_set_eq:NN \seq_elt:w \ERROR
}
-\def_new:Npn \seq_gconcat:ccc{\exp_args:Nccc\seq_gconcat:NNN}
+\cs_generate_variant:Nn \seq_map_function:NN {c}
% \end{macrocode}
% \end{macro}
% \end{macro}
%
-% \begin{macro}{\seq_if_in:NnTF}
-% \begin{macro}{\seq_if_in:cnTF}
-% \begin{macro}{\seq_if_in:coTF}
-% \begin{macro}{\seq_if_in:cxTF}
-% \begin{macro}{\seq_if_in:NnF}
-% \begin{macro}{\seq_if_in:cnF}
-% |\seq_if_in:NnTF| \m{seq}\m{item} \m{true~case} \m{false~case}
-% will check whether \m{item} is in \m{seq} and then either execute
-% the \m{true~case} or the \m{false~case}. \m{true~case} and
-% \m{false~case} may contain incomplete |\if_charcode:w|
-% statements.
-% \begin{macrocode}
-\def_new:Npn \seq_if_in:NnTF #1#2{
- \def:Npn\tmp:w
- ##1\seq_elt:w #2\seq_elt_end: ##2##3\q_stop{
-% \end{macrocode}
-% Note that |##2| contains exactly one token which we can compare
-% with |\q_no_value|.
-% \begin{macrocode}
- \if_meaning:NN\q_no_value##2
- \exp_after:NN\use_arg_ii:nn
- \else:
- \exp_after:NN\use_arg_i:nn
- \fi:
- }
- \exp_after:NN
- \tmp:w #1\seq_elt:w
- #2\seq_elt_end: \q_no_value \q_stop}
-\def_new:Npn \seq_if_in:coTF {\exp_args:Nco \seq_if_in:NnTF}
-\def_new:Npn \seq_if_in:cnTF {\exp_args:Nc \seq_if_in:NnTF}
-\def_new:Npn \seq_if_in:cxTF {\exp_args:Ncx \seq_if_in:NnTF}
-% \end{macrocode}
-%
+% \begin{macro}{\seq_map_inline:Nn}
+% \begin{macro}{\seq_map_inline:cn}
+% When no braces are used, this version of mapping seems more
+% natural.
% \begin{macrocode}
-\def_new:Npn \seq_if_in:NnF #1#2 { \seq_if_in:NnTF #1{#2}\use_noop: }
-\def_new:Npn \seq_if_in:cnF {\exp_args:Nc \seq_if_in:NnF}
+\cs_new_nopar:Npn \seq_map_inline:Nn #1#2 {
+ \cs_set:Npn \seq_elt:w ##1 \seq_elt_end: {#2}
+ #1
+ \cs_set_eq:NN \seq_elt:w \ERROR
+}
+\cs_generate_variant:Nn \seq_map_inline:Nn {c}
% \end{macrocode}
% \end{macro}
% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-%
-%
-% \subsubsection{Stack operations}
-%
-% We build stacks from sequences, but here we put the
-% specific functions together.
%
+% \subsection{Sequence stacks}
%
% \begin{macro}{\seq_push:Nn}
+% \begin{macro}{\seq_push:NV}
% \begin{macro}{\seq_push:No}
% \begin{macro}{\seq_push:cn}
% \begin{macro}{\seq_pop:NN}
@@ -749,24 +877,25 @@
% `push' and `pop'. In most cases they are nothing more then new
% names for old functions.
% \begin{macrocode}
-\let_new:NN \seq_push:Nn \seq_put_left:Nn
-\let_new:NN \seq_push:No \seq_put_left:No
-\let_new:NN \seq_push:cn \seq_put_left:cn
-\def_new:Npn \seq_pop:NN {\seq_pop_aux:nnNN \tlp_set:Nn \tlp_set:Nn}
-\def_new:Npn \seq_pop:cN {\exp_args:Nc \seq_pop:NN}
+\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:No \seq_put_left:No
+\cs_new_eq:NN \seq_push:cn \seq_put_left:cn
+\cs_new_nopar:Npn \seq_pop:NN { \seq_pop_aux:nnNN \tl_set:Nn \tl_set:Nn }
+\cs_generate_variant:Nn \seq_pop:NN {c}
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
-%
-%
+% \end{macro}
%
% \begin{macro}{\seq_gpush:Nn}
+% \begin{macro}{\seq_gpush:NV}
% \begin{macro}{\seq_gpush:No}
% \begin{macro}{\seq_gpush:cn}
-% \begin{macro}{\seq_gpush:NC}
+% \begin{macro}{\seq_gpush:Nv}
% \begin{macro}{\seq_gpop:NN}
% \begin{macro}{\seq_gpop:cN}
% I don't agree with Denys that one needs only local stacks,
@@ -774,12 +903,10 @@
% here more often. In case of |\seq_gpop:NN| the value is
% nevertheless returned locally.
% \begin{macrocode}
-\let_new:NN \seq_gpush:Nn \seq_gput_left:Nn
-\def_new:Npn \seq_gpush:No {\exp_args:NNo \seq_gpush:Nn}
-\def_new:Npn \seq_gpush:cn {\exp_args:Nc \seq_gpush:Nn}
-\def_new:Npn \seq_gpush:NC {\exp_args:NNC \seq_gpush:Nn}
-\def_new:Npn \seq_gpop:NN {\seq_pop_aux:nnNN \tlp_gset:Nn \tlp_set:Nn}
-\def_new:Npn \seq_gpop:cN {\exp_args:Nc \seq_gpop:NN}
+\cs_new_eq:NN \seq_gpush:Nn \seq_gput_left:Nn
+\cs_new_nopar:Npn \seq_gpop:NN { \seq_pop_aux:nnNN \tl_gset:Nn \tl_set:Nn }
+\cs_generate_variant:Nn \seq_gpush:Nn {NV,No,c,Nv}
+\cs_generate_variant:Nn \seq_gpop:NN {c}
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -787,54 +914,32 @@
% \end{macro}
% \end{macro}
% \end{macro}
-%
+% \end{macro}
%
% \begin{macro}{\seq_top:NN}
% \begin{macro}{\seq_top:cN}
% Looking at the top element of the stack without removing it is
% done with this operation.
% \begin{macrocode}
-\let_new:NN \seq_top:NN \seq_get:NN
-\let_new:NN \seq_top:cN \seq_get:cN
+\cs_new_eq:NN \seq_top:NN \seq_get:NN
+\cs_new_eq:NN \seq_top:cN \seq_get:cN
% \end{macrocode}
% \end{macro}
% \end{macro}
%
%
-% Show token usage:
% \begin{macrocode}
%</initex|package>
+% \end{macrocode}
+%
+% Show token usage:
+% \begin{macrocode}
%<*showmemory>
%\showMemUsage
%</showmemory>
% \end{macrocode}
%
-% \endinput
-%
-% $Log$
-% Revision 1.23 2006/08/09 21:12:50 morten
-% Minor change in \seq_gconcat:NNN
-%
-% Revision 1.22 2006/03/20 18:26:39 braams
-% Updated the copyright notice (2006) and demoted all implementation
-% sections to subsections and so on to clean up the toc for source3.tex
-%
-% Revision 1.21 2005/12/29 01:28:29 morten
-% Added a new mapping function (needed in xparse)
-%
-% Revision 1.20 2005/12/27 10:06:10 morten
-% Minor changes plus changed RCS information retrieval
-%
-% Revision 1.19 2005/04/06 21:36:08 morten
-% Removed dependency on l3toks and added an if_in variant
-%
-% Revision 1.18 2005/03/22 23:28:05 morten
-% Fix coding as Benjamin pointed out
-%
-% Revision 1.17 2005/03/16 22:35:51 braams
-% Added the tweaks necessary to be able to load with initex
-%
-% Revision 1.16 2005/03/11 21:42:10 braams
-% Fixed the use of RCS information; added \StopEventually
-% Fixed a few documentation typos
+% \end{implementation}
+% \PrintIndex
%
+% \endinput
diff --git a/Master/texmf-dist/source/latex/expl3/l3skip.dtx b/Master/texmf-dist/source/latex/expl3/l3skip.dtx
index 11545f09d82..1853812248e 100644
--- a/Master/texmf-dist/source/latex/expl3/l3skip.dtx
+++ b/Master/texmf-dist/source/latex/expl3/l3skip.dtx
@@ -1,5 +1,5 @@
% \iffalse
-%% File: l3skip.dtx Copyright (C) 2005-2007 Frank Mittelbach, LaTeX3 project
+%% File: l3skip.dtx Copyright (C) 2005-2008 Frank Mittelbach, 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
@@ -17,7 +17,7 @@
%%
%% The development version of the bundle can be found at
%%
-%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/
+%% http://www.latex-project.org/svnroot/experimental/trunk/
%%
%% for those people who are interested.
%%
@@ -36,7 +36,7 @@
\RequirePackage{l3names}
%</driver|package>
%\fi
-\GetIdInfo$Id: l3skip.dtx 666 2007-09-27 15:53:26Z mittelba $
+\GetIdInfo$Id: l3skip.dtx 1362 2009-05-28 20:19:21Z joseph $
{L3 Experimental skip registers}
%\iffalse
%<*driver>
@@ -44,9 +44,9 @@
\ProvidesFile{\filename.\filenameext}
[\filedate\space v\fileversion\space\filedescription]
%\iffalse
-\documentclass{l3doc}
+\documentclass[full]{l3doc}
\begin{document}
-\DocInput{\filename.\filenameext}
+\DocInput{l3skip.dtx}
\end{document}
%</driver>
% \fi
@@ -60,23 +60,21 @@
% \date{\filedate}
% \maketitle
%
-%
-% \section{Length registers}
-%
+% \begin{documentation}
%
% \LaTeX3 knows about two types of length registers for internal use:
% rubber lengths ("skip"s) and rigid lengths ("dim"s).
%
-% \subsection{Skip registers}
+% \section{Skip registers}
%
%
%
-% \subsubsection{Functions}
+% \subsection{Functions}
%
% \begin{function}{%
% \skip_new:N |
% \skip_new:c |
-% \skip_new_l:N
+%^^A \skip_new_l:N
% }
% \begin{syntax}
% "\skip_new:N" <skip>
@@ -110,7 +108,7 @@
% \skip_gset:cn |
% }
% \begin{syntax}
-% "\skip_set:Nn" <skip> "{" <skip value> "}"
+% "\skip_set:Nn" <skip> \Arg{skip value}
% \end{syntax}
% These functions will set the <skip> register to the <length> value.
% \end{function}
@@ -123,7 +121,7 @@
% \skip_gadd:cn |
% }
% \begin{syntax}
-% "\skip_add:Nn" <skip> "{" <length> "}"
+% "\skip_add:Nn" <skip> \Arg{length}
% \end{syntax}
% These functions will add to the <skip> register the value <length>. If
% the second argument is a <skip> register too, the surrounding braces
@@ -135,7 +133,7 @@
% \skip_gsub:Nn |
% }
% \begin{syntax}
-% "\skip_gsub:Nn" <skip> "{" <length> "}"
+% "\skip_gsub:Nn" <skip> \Arg{length}
% \end{syntax}
% These functions will subtract from the <skip> register the value
% <length>. If the second argument is a <skip> register too, the
@@ -160,6 +158,21 @@
% \end{texnote}
% \end{function}
%
+% \begin{function}{ \skip_show:N |
+% \skip_show:c }
+% \begin{syntax}
+% "\skip_show:N" <skip>
+% \end{syntax}
+% This function pauses the compilation and displays the length value kept
+% in <skip> in the console output and log file.
+% \begin{texnote}
+% The function "\skip_show:N" could be implemented directly as the \TeX{}
+% primitive "\tex_showthe:D" which is also responsible to produce the values for
+% other internal quantities. We have chosen to use individual functions
+% for counters, dimensions etc.\ to allow checks and to make the code
+% more self-explaining.
+% \end{texnote}
+% \end{function}
%
% \begin{function}{%
% \skip_horizontal:N |
@@ -171,7 +184,7 @@
% }
% \begin{syntax}
% "\skip_horizontal:N" <skip> \\
-% "\skip_horizontal:n" "{" <length> "}"
+% "\skip_horizontal:n" \Arg{length}
% \end{syntax}
% The "hor" functions insert <skip> or <length> with the \TeX\
% primitive \tn{hskip}. The "vertical" variants do the same with
@@ -179,11 +192,10 @@
% \end{function}
%
%
-% \begin{function}{%
-% \skip_infinite_glue:nTF |
-% }
+% \begin{function}{ \skip_if_infinite_glue_p:n |
+% \skip_if_infinite_glue:n / (TF) }
% \begin{syntax}
-% "\skip_infinite_glue:nTF" "{"<skip>"}" "{"<true>"}" "{"<false>"}"
+% "\skip_if_infinite_glue:nTF" \Arg{skip} \Arg{true} \Arg{false}
% \end{syntax}
% Checks if <skip> contains infinite stretch or shrink components
% and executes either <true> or <false>. Also works on input like
@@ -196,7 +208,7 @@
% \skip_split_finite_else_action:nnNN |
% }
% \begin{syntax}
-% "\skip_split_finite_else_action:nnNN" "{"<skip>"}" "{"<action>"}"
+% "\skip_split_finite_else_action:nnNN" \Arg{skip} \Arg{action}
% <dimen1> <dimen2>
% \end{syntax}
% Checks if <skip> contains finite glue. If it does then it assigns
@@ -208,10 +220,10 @@
%
%
% \begin{function}{%
-% \skip_eval:n |
+% \skip_eval:n / (EXP) |
% }
% \begin{syntax}
-% "\skip_eval:n" "{"<skip expr>"}"
+% "\skip_eval:n" \Arg{skip expr}
% \end{syntax}
% Evaluates the value of <skip expr> so that
% "\skip_eval:n {5pt plus 3fil + 3pt minus 1fil}" puts
@@ -224,10 +236,10 @@
% \end{function}
%
%
-% \subsubsection{Formatting a skip register value}
+% \subsection{Formatting a skip register value}
%
%
-% \subsubsection{Variable and constants}
+% \subsection{Variable and constants}
%
% \begin{variable}{%
% \c_max_skip |
@@ -256,10 +268,10 @@
%
%
%
-% \subsection{Dim registers}
+% \section{Dim registers}
%
%
-% \subsubsection{Functions}
+% \subsection{Functions}
%
%
%
@@ -267,7 +279,7 @@
% \begin{function}{%
% \dim_new:N |
% \dim_new:c |
-% \dim_new_l:N
+%^^A \dim_new_l:N
% }
% \begin{syntax}
% "\dim_new:N" <dim>
@@ -296,12 +308,15 @@
%
% \begin{function}{%
% \dim_set:Nn |
+% \dim_set:Nc |
% \dim_set:cn |
% \dim_gset:Nn |
+% \dim_gset:Nc |
% \dim_gset:cn |
+% \dim_gset:cc |
% }
% \begin{syntax}
-% "\dim_set:Nn" <dim> "{" <dim value> "}"
+% "\dim_set:Nn" <dim> \Arg{dim value}
% \end{syntax}
% These functions will set the <dim> register to the <dim value> value.
% \end{function}
@@ -309,12 +324,13 @@
%
% \begin{function}{%
% \dim_add:Nn |
+% \dim_add:Nc |
% \dim_add:cn |
% \dim_gadd:Nn |
% \dim_gadd:cn |
% }
% \begin{syntax}
-% "\dim_add:Nn" <dim> "{" <length> "}"
+% "\dim_add:Nn" <dim> \Arg{length}
% \end{syntax}
% These functions will add to the <dim> register the value <length>. If
% the second argument is a <dim> register too, the surrounding braces
@@ -323,10 +339,13 @@
%
% \begin{function}{%
% \dim_sub:Nn |
+% \dim_sub:Nc |
+% \dim_sub:cn |
% \dim_gsub:Nn |
+% \dim_gsub:cn |
% }
% \begin{syntax}
-% "\dim_gsub:Nn" <dim> "{" <length> "}"
+% "\dim_gsub:Nn" <dim> \Arg{length}
% \end{syntax}
% These functions will subtract from the <dim> register the value
% <length>. If the second argument is a <dim> register too, the
@@ -351,13 +370,28 @@
% \end{texnote}
% \end{function}
%
+% \begin{function}{ \dim_show:N |
+% \dim_show:c }
+% \begin{syntax}
+% "\dim_show:N" <skip>
+% \end{syntax}
+% This function pauses the compilation and displays the length value kept
+% in <skip> in the console output and log file.
+% \begin{texnote}
+% The function "\dim_show:N" could be implemented directly as the \TeX{}
+% primitive "\tex_showthe:D" which is also responsible to produce the values for
+% other internal quantities. We have chosen to use individual functions
+% for counters, dimensions etc.\ to allow checks and to make the code
+% more self-explaining.
+% \end{texnote}
+% \end{function}
%
%
% \begin{function}{%
% \dim_eval:n |
% }
% \begin{syntax}
-% "\dim_eval:n" "{"<dim expr>"}"
+% "\dim_eval:n" \Arg{dim expr}
% \end{syntax}
% Evaluates the value of a dimension expression so that
% "\dim_eval:n {5pt+3pt}" puts "8pt" back into the input stream.
@@ -382,14 +416,10 @@
% \end{texnote}
% \end{function}
%
-% \begin{function}{%
-% \dim_compare:nNnTF |
-% \dim_compare:nNnT |
-% \dim_compare:nNnF |
-% }
+% \begin{function}{ \dim_compare:nNn / (TF)(EXP) | \dim_compare_p:nNn / (EXP)}
% \begin{syntax}
-% "\dim_compare:nNnTF" "{"<dim~expr>"}" <rel> "{"<dim~expr>"}"
-% "{"<true>"}" "{"<false>"}"
+% "\dim_compare:nNnTF" \Arg{dim~expr} <rel> \Arg{dim~expr}
+% \Arg{true} \Arg{false}
% \end{syntax}
% These functions test two dimension expressions against each other. They
% are both evaluated by "\dim_eval:n". Note that if both expressions
@@ -403,34 +433,26 @@
% \end{texnote}
% \end{function}
%
-% \begin{function}{%
-% \dim_compare_p:nNn |
-% }
-% \begin{syntax}
-% "\dim_compare_p:nNn" "{"<dim~expr>"}" <rel> "{"<dim~expr>"}"
-% \end{syntax}
-% Predicate version of the above functions.
-% \end{function}
%
% \begin{function}{%
-% \dim_while:nNnT |
-% \dim_while:nNnF |
-% \dim_dowhile:nNnT |
-% \dim_dowhile:nNnF |
+% \dim_while_do:nNnn |
+% \dim_until_do:nNnn |
+% \dim_do_while:nNnn |
+% \dim_do_until:nNnn |
% }
% \begin{syntax}
-% "\dim_while:nNnT" <dim expr> <rel> <dim~expr> <true>
+% "\dim_while_do:nNnn" <dim expr> <rel> <dim~expr> <code>
% \end{syntax}
-% "\dim_while:nNnT" tests the dimension expressions and if true performs
-% the body "T" until the test fails. "\dim_dowhile:nNnT" is similar
+% "\dim_while_do:nNnn" tests the dimension expressions and if true performs
+% <code> repeatedly while the test remains true. "\dim_do_while:nNnn" is similar
% but executes the body first and then performs the check, thus
-% ensuring that the body is executed at least once. The "F" versions
+% ensuring that the body is executed at least once. The `until' versions
% are similar but continue the loop as long as the test is false.
% \end{function}
%
%
%
-% \subsubsection{Variable and constants}
+% \subsection{Variable and constants}
%
% \begin{variable}{%
% \c_max_dim |
@@ -456,11 +478,11 @@
% Scratch register for immediate use.
% \end{variable}
%
-% \subsection{Muskips}
+% \section{Muskips}
%
% \begin{function}{%
% \muskip_new:N |
-% \muskip_new_l:N
+%^^A \muskip_new_l:N
% }
% \begin{syntax}
% "\muskip_new:N" <muskip>
@@ -477,7 +499,7 @@
% \muskip_gset:Nn |
% }
% \begin{syntax}
-% "\muskip_set:Nn" <muskip> "{" <muskip value> "}"
+% "\muskip_set:Nn" <muskip> \Arg{muskip value}
% \end{syntax}
% These functions will set the <muskip> register to the <length>
% value.
@@ -489,7 +511,7 @@
% \muskip_gadd:Nn |
% }
% \begin{syntax}
-% "\muskip_add:Nn" <muskip> "{" <length> "}"
+% "\muskip_add:Nn" <muskip> \Arg{length}
% \end{syntax}
% These functions will add to the <muskip> register the value
% <length>. If the second argument is a <muskip> register too, the
@@ -501,47 +523,62 @@
% \muskip_gsub:Nn |
% }
% \begin{syntax}
-% "\muskip_gsub:Nn" <muskip> "{" <length> "}"
+% "\muskip_gsub:Nn" <muskip> \Arg{length}
% \end{syntax}
% These functions will subtract from the <muskip> register the value
% <length>. If the second argument is a <muskip> register too, the
% surrounding braces can be left out.
% \end{function}
%
+% \begin{function}{ \muskip_use:N }
+% \begin{syntax}
+% "\muskip_use:N" <muskip>
+% \end{syntax}
+% This function returns the length value kept in <muskip> in a way
+% suitable for further processing.
+% \begin{texnote}
+% See note for "\dim_use:N".
+% \end{texnote}
+% \end{function}
%
-% \StopEventually{}
+% \end{documentation}
%
-% \subsection{The Implementation}
+% \begin{implementation}
+%
+% \section{\pkg{l3skip} implementation}
%
%
% We start by ensuring that the required packages are loaded.
% \begin{macrocode}
-%<package>\ProvidesExplPackage
-%<package> {\filename}{\filedate}{\fileversion}{\filedescription}
-%<package&!check>\RequirePackage{l3int}
-%<package&!check>\RequirePackage{l3prg}
-%<package&check>\RequirePackage{l3chk}
+%<*package>
+\ProvidesExplPackage
+ {\filename}{\filedate}{\fileversion}{\filedescription}
+\package_check_loaded_expl:
+%</package>
%<*initex|package>
% \end{macrocode}
%
-% \subsubsection{Skip registers}
+% \subsection{Skip registers}
%
-% \begin{macro}{\skip_new:N}
-% \begin{macro}{\skip_new:c}
-% \begin{macro}{\skip_new_l:N}
+% \begin{macro}{\skip_new:N,\skip_new:c}
+%^^A \begin{macro}{\skip_new_l:N}
% Allocation of a new internal registers.
% \begin{macrocode}
%<*initex>
\alloc_setup_type:nnn {skip} \c_zero \c_max_register_num
-\def_new:Npn\skip_new:N #1 {\alloc_reg:NnNN g {skip} \tex_skipdef:D #1 }
-\def_new:Npn\skip_new_l:N #1 {\alloc_reg:NnNN l {skip} \tex_skipdef:D #1 }
+\cs_new_nopar:Npn\skip_new:N #1 { \alloc_reg:NnNN g {skip} \tex_skipdef:D #1 }
+\cs_new_nopar:Npn\skip_new_l:N #1 { \alloc_reg:NnNN l {skip} \tex_skipdef:D #1 }
%</initex>
-%<package>\let:NN \skip_new:N \newskip
-\def_new:Npn \skip_new:c {\exp_args:Nc \skip_new:N}
+%<*package>
+\cs_new_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}
-% \end{macro}
-% \end{macro}
+%^^A \end{macro}
%
%
% \begin{macro}{\skip_set:Nn}
@@ -551,19 +588,21 @@
% Setting skips is again something that I would like to make
% uniform at the moment to get a better overview.
% \begin{macrocode}
-\def_new:Npn \skip_set:Nn #1#2{#1\skip_eval:n{#2}
+\cs_new_nopar:Npn \skip_set:Nn #1#2 {
+ #1\skip_eval:n{#2}
%<*check>
\chk_local_or_pref_global:N #1
%</check>
}
-\def_new:Npn \skip_gset:Nn {
+\cs_new_nopar:Npn \skip_gset:Nn {
%<*check>
- \pref_global_chk:
+ \pref_global_chk:
%</check>
%<-check> \pref_global:D
- \skip_set:Nn }
-\def_new:Npn \skip_set:cn {\exp_args:Nc \skip_set:Nn }
-\def_new:Npn \skip_gset:cn {\exp_args:Nc \skip_gset:Nn }
+ \skip_set:Nn
+}
+\cs_generate_variant:Nn \skip_set:Nn {cn}
+\cs_generate_variant:Nn \skip_gset:Nn {cn}
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -576,12 +615,13 @@
% \begin{macro}{\skip_gzero:c}
% Reset the register to zero.
% \begin{macrocode}
-\def_new:Npn \skip_zero:N #1{#1\c_zero_skip \scan_stop:
+\cs_new_nopar:Npn \skip_zero:N #1{
+ #1\c_zero_skip \scan_stop:
%<*check>
- \chk_local_or_pref_global:N #1
+ \chk_local_or_pref_global:N #1
%</check>
}
-\def_new:Npn \skip_gzero:N {
+\cs_new_nopar:Npn \skip_gzero:N {
% \end{macrocode}
% We make sure that a local variable is not updated globally by
% changing the internal test (i.e.\ |\chk_local_or_pref_global:N|) before
@@ -592,12 +632,13 @@
% production versions.
% \begin{macrocode}
%<*check>
- \pref_global_chk:
+ \pref_global_chk:
%</check>
%<-check> \pref_global:D
- \skip_zero:N}
-\def_new:Npn \skip_zero:c {\exp_args:Nc \skip_zero:N}
-\def_new:Npn \skip_gzero:c {\exp_args:Nc \skip_gzero:N}
+ \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}
@@ -608,45 +649,59 @@
% \begin{macro}{\skip_add:Nn}
% \begin{macro}{\skip_add:cn}
% \begin{macro}{\skip_gadd:Nn}
+% \begin{macro}{\skip_gadd:cn}
% \begin{macro}{\skip_sub:Nn}
% \begin{macro}{\skip_gsub:Nn}
% Adding and subtracting to and from <skip>s
% \begin{macrocode}
-\def_new:Npn \skip_add:Nn #1#2{
+\cs_new_nopar:Npn \skip_add:Nn #1#2 {
% \end{macrocode}
% We need to say |by| in case the first argment is a register
% accessed by its number, e.g., |\skip23|.
% \begin{macrocode}
- \tex_advance:D#1 by \skip_eval:n{#2}
+ \tex_advance:D#1 by \skip_eval:n{#2}
%<*check>
- \chk_local_or_pref_global:N #1
+ \chk_local_or_pref_global:N #1
%</check>
}
-\def_new:Npn\skip_add:cn{\exp_args:Nc\skip_add:Nn}
-\def_new:Npn \skip_sub:Nn #1#2{
- \tex_advance:D#1-\skip_eval:n{#2}
+\cs_generate_variant:Nn \skip_add:Nn {cn}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_new_nopar:Npn \skip_sub:Nn #1#2{
+ \tex_advance:D#1-\skip_eval:n{#2}
%<*check>
-\chk_local_or_pref_global:N #1
+ \chk_local_or_pref_global:N #1
%</check>
}
-\def_new:Npn \skip_gadd:Nn {
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_new_nopar:Npn \skip_gadd:Nn {
%<*check>
- \pref_global_chk:
+ \pref_global_chk:
%</check>
%<-check> \pref_global:D
- \skip_add:Nn }
-\def_new:Npn \skip_gsub:Nn {
+ \skip_add:Nn
+}
+\cs_generate_variant:Nn \skip_gadd:Nn {cn}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_new_nopar:Npn \skip_gsub:Nn {
%<*check>
- \pref_global_chk:
+ \pref_global_chk:
%</check>
%<-check> \pref_global:D
- \skip_sub:Nn }
+ \skip_sub:Nn
+}
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
+% \end{macro}
%
%
% \begin{macro}{\skip_horizontal:N}
@@ -657,12 +712,15 @@
% \begin{macro}{\skip_vertical:n}
% Inserting skips.
% \begin{macrocode}
-\let_new:NN \skip_horizontal:N \tex_hskip:D
-\def_new:Npn \skip_horizontal:c {\exp_args:Nc\skip_horizontal:N}
-\def_new:Npn \skip_horizontal:n #1{\skip_horizontal:N \skip_eval:n{#1}}
-\let_new:NN \skip_vertical:N \tex_vskip:D
-\def_new:Npn \skip_vertital:c {\exp_args:Nc\skip_vertical:N}
-\def_new:Npn \skip_vertical:n #1{\skip_vertical:N \skip_eval:n{#1}}
+\cs_new_eq:NN \skip_horizontal:N \tex_hskip:D
+\cs_generate_variant:Nn \skip_horizontal:N {c}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_new_nopar:Npn \skip_horizontal:n #1 { \skip_horizontal:N \skip_eval:n{#1} }
+\cs_new_eq:NN \skip_vertical:N \tex_vskip:D
+\cs_generate_variant:Nn \skip_vertical:N {c}
+\cs_new_nopar:Npn \skip_vertical:n #1 { \skip_vertical:N \skip_eval:n{#1} }
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -675,16 +733,26 @@
% \begin{macro}{\skip_use:c}
% Here is how skip registers are accessed:
% \begin{macrocode}
-\let_new:NN \skip_use:N \tex_the:D
-\def_new:Npn \skip_use:c #1{\exp_args:Nc\skip_use:N}
+\cs_new_eq:NN \skip_use:N \tex_the:D
+\cs_generate_variant:Nn \skip_use:N {c}
% \end{macrocode}
% \end{macro}
% \end{macro}
%
+% \begin{macro}{\skip_show:N}
+% \begin{macro}{\skip_show:c}
+% Diagnostics.
+% \begin{macrocode}
+\cs_new_eq:NN \skip_show:N \tex_showthe:D
+\cs_new_nopar:Npn \skip_show:c #1 { \skip_show:N \cs:w #1 \cs_end: }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
% \begin{macro}{\skip_eval:n}
% Evaluating a calc expression.
% \begin{macrocode}
-\def_new:Npn \skip_eval:n #1 {\etex_glueexpr:D #1 \scan_stop:}
+\cs_new_nopar:Npn \skip_eval:n #1 { \etex_glueexpr:D #1 \scan_stop: }
% \end{macrocode}
% \end{macro}
%
@@ -696,7 +764,7 @@
% We provide three local and two global scratch registers, maybe we
% need more or less.
% \begin{macrocode}
-%%\chk_new_cs:N \l_tmpa_skip
+%%\chk_if_free_cs:N \l_tmpa_skip
%%\tex_skipdef:D\l_tmpa_skip 255 %currently taken up by \skip@
\skip_new:N \l_tmpa_skip
\skip_new:N \l_tmpb_skip
@@ -720,8 +788,8 @@
\skip_set:Nn \c_max_skip {16383.99999pt}
%</!package>
%<*!initex>
-\let:NN \c_zero_skip \z@
-\let:NN \c_max_skip \maxdimen
+\cs_set_eq:NN \c_zero_skip \z@
+\cs_set_eq:NN \c_max_skip \maxdimen
%</!initex>
% \end{macrocode}
% \end{macro}
@@ -729,26 +797,28 @@
%
%
%
-% \begin{macro}{\skip_infinite_glue:nTF}
+% \begin{macro}{\skip_if_infinite_glue_p:n}
+% \begin{macro}[TF]{\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. "\skip_infinite_glue:nTF" tests it directly by
+% or those components. "\skip_if_infinite_glue:nTF" tests it directly by
% looking at the stretch and shrink order. If either of the predicate
-% functions return \m{true} "\prg_logic_or_p:nn" will return \m{true}
+% functions return \m{true} "\bool_if:nTF" will return \m{true}
% and the logic test will take the true branch.
% \begin{macrocode}
-\def_new:Npn \skip_infinite_glue:nTF #1{
- \predicate:nTF {
- \int_compare_p:nNn {\etex_gluestretchorder:D #1 } > \c_zero ||
- \int_compare_p:nNn {\etex_glueshrinkorder:D #1 } > \c_zero
- }
+\prg_new_conditional:Nnn \skip_if_infinite_glue:n {p,TF,T,F} {
+ \bool_if:nTF {
+ \intexpr_compare_p:nNn {\etex_gluestretchorder:D #1 } > \c_zero ||
+ \intexpr_compare_p:nNn {\etex_glueshrinkorder:D #1 } > \c_zero
+ } {\prg_return_true:} {\prg_return_false:}
}
% \end{macrocode}
% \end{macro}
+% \end{macro}
%
%
-% \begin{macro}{\skip_split_finite_else_action:nnNN}
+% \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
@@ -756,8 +826,8 @@
% "#2" which is probably an error message.
% Assignments are global.
% \begin{macrocode}
-\def_new:Npn \skip_split_finite_else_action:nnNN #1#2#3#4{
- \skip_infinite_glue:nTF {#1}
+\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
@@ -773,61 +843,62 @@
%
%
%
-% \subsubsection{Dimen registers}
+% \subsection{Dimen registers}
%
-% \begin{macro}{\dim_new:N}
-% \begin{macro}{\dim_new:c}
-% \begin{macro}{\dim_new_l:N}
+% \begin{macro}{\dim_new:N,\dim_new:c}
+%^^A \begin{macro}{\dim_new_l:N}
% Allocating \meta{dim} registers...
% \begin{macrocode}
%<*initex>
\alloc_setup_type:nnn {dimen} \c_zero \c_max_register_num
-\def_new:Npn \dim_new:N #1 {\alloc_reg:NnNN g {dimen} \tex_dimendef:D #1 }
-\def_new:Npn \dim_new_l:N #1 {\alloc_reg:NnNN l {dimen} \tex_dimendef:D #1 }
+\cs_new_nopar:Npn \dim_new:N #1 {\alloc_reg:NnNN g {dimen} \tex_dimendef:D #1 }
+\cs_new_nopar:Npn \dim_new_l:N #1 {\alloc_reg:NnNN l {dimen} \tex_dimendef:D #1 }
%</initex>
-%<package>\let:NN \dim_new:N \newdimen
-\def_new:Npn \dim_new:c {\exp_args:Nc \dim_new:N}
+%<*package>
+\cs_new_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}
-% \end{macro}
-% \end{macro}
+%^^A \end{macro}
%
% \begin{macro}{\dim_set:Nn}
-% \begin{macro}{\dim_gset:Nn}
% \begin{macro}{\dim_set:cn}
% \begin{macro}{\dim_set:Nc}
+% \begin{macro}{\dim_gset:Nn}
% \begin{macro}{\dim_gset:cn}
% \begin{macro}{\dim_gset:Nc}
% \begin{macro}{\dim_gset:cc}
% We add |\dim_eval:n| in order to allow simple arithmetic
% and a space just for those using |\dimen1| or alike. See OR!
% \begin{macrocode}
-\def_new:Npn \dim_set:Nn #1#2{#1~ \dim_eval:n{#2}}
-\def_new:Npn \dim_gset:Nn {\pref_global:D \dim_set:Nn }
-\def_new:Npn \dim_set:cn {\exp_args:Nc \dim_set:Nn }
-\def_new:Npn \dim_set:Nc {\exp_args:NNc \dim_set:Nn }
-\def_new:Npn \dim_gset:cn {\exp_args:Nc \dim_gset:Nn }
-\def_new:Npn \dim_gset:Nc {\exp_args:NNc \dim_gset:Nn }
-\def_new:Npn \dim_gset:cc {\exp_args:Ncc \dim_gset:Nn }
+\cs_new_nopar:Npn \dim_set:Nn #1#2 { #1~ \dim_eval:n{#2} }
+\cs_generate_variant:Nn \dim_set:Nn {cn,Nc}
% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
+%
+% \begin{macrocode}
+\cs_new_nopar:Npn \dim_gset:Nn { \pref_global:D \dim_set:Nn }
+\cs_generate_variant:Nn \dim_gset:Nn {cn,Nc,cc}
+% \end{macrocode}
+% \end{macro}\end{macro}\end{macro}\end{macro}
+% \end{macro}\end{macro}\end{macro}
%
% \begin{macro}{\dim_zero:N}
% \begin{macro}{\dim_gzero:N}
% \begin{macro}{\dim_zero:c}
-% \begin{macro}{\dim_gzero:N}
+% \begin{macro}{\dim_gzero:c}
% Resetting.
% \begin{macrocode}
-\def_new:Npn \dim_zero:N #1{#1\c_zero_skip}
-\def_new:Npn \dim_gzero:N {\pref_global:D \dim_zero:N}
-\def_new:Npn \dim_zero:c {\exp_args:Nc \dim_zero:N}
-\def_new:Npn \dim_gzero:c {\exp_args:Nc \dim_gzero:N}
+\cs_new_nopar:Npn \dim_zero:N #1 { #1\c_zero_skip }
+\cs_generate_variant:Nn \dim_zero:N {c}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_new_nopar:Npn \dim_gzero:N { \pref_global:D \dim_zero:N }
+\cs_generate_variant:Nn \dim_gzero:N {c}
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -841,17 +912,19 @@
% \begin{macro}{\dim_gadd:cn}
% Addition.
% \begin{macrocode}
-\def_new:Npn \dim_add:Nn #1#2{
+\cs_new_nopar:Npn \dim_add:Nn #1#2{
% \end{macrocode}
% We need to say |by| in case the first argment is a register
% accessed by its number, e.g., |\dimen23|.
% \begin{macrocode}
\tex_advance:D#1 by \dim_eval:n{#2}\scan_stop:
}
-\def_new:Npn\dim_add:cn{\exp_args:Nc\dim_add:Nn}
-\def_new:Npn\dim_add:Nc{\exp_args:NNc\dim_add:Nn}
-\def_new:Npn \dim_gadd:Nn { \pref_global:D \dim_add:Nn }
-\def_new:Npn\dim_gadd:cn{\exp_args:Nc\dim_gadd:Nn}
+\cs_generate_variant:Nn \dim_add:Nn {cn,Nc}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_new_nopar:Npn \dim_gadd:Nn { \pref_global:D \dim_add:Nn }
+\cs_generate_variant:Nn \dim_gadd:Nn {cn}
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -866,11 +939,13 @@
% \begin{macro}{\dim_gsub:cn}
% Subtracting.
% \begin{macrocode}
-\def_new:Npn \dim_sub:Nn #1#2{\tex_advance:D#1-#2\scan_stop:}
-\def_new:Npn\dim_sub:cn{\exp_args:Nc\dim_sub:Nn}
-\def_new:Npn\dim_sub:Nc{\exp_args:NNc\dim_sub:Nn}
-\def_new:Npn \dim_gsub:Nn {\pref_global:D \dim_sub:Nn }
-\def_new:Npn\dim_gsub:cn{\exp_args:Nc\dim_gsub:Nn}
+\cs_new_nopar:Npn \dim_sub:Nn #1#2 { \tex_advance:D#1-#2\scan_stop: }
+\cs_generate_variant:Nn \dim_sub:Nn {cn,Nc}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_new_nopar:Npn \dim_gsub:Nn { \pref_global:D \dim_sub:Nn }
+\cs_generate_variant:Nn \dim_gsub:Nn {cn}
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -882,12 +957,22 @@
% \begin{macro}{\dim_use:c}
% Accessing a \meta{dim}.
% \begin{macrocode}
-\let_new:NN \dim_use:N \tex_the:D
-\def_new:Npn \dim_use:c {\exp_args:Nc\dim_use:N}
+\cs_new_eq:NN \dim_use:N \tex_the:D
+\cs_generate_variant:Nn \dim_use:N {c}
% \end{macrocode}
% \end{macro}
% \end{macro}
%
+% \begin{macro}{\dim_show:N}
+% \begin{macro}{\dim_show:c}
+% Diagnostics.
+% \begin{macrocode}
+\cs_new_eq:NN \dim_show:N \tex_showthe:D
+\cs_new_nopar:Npn \dim_show:c #1 { \dim_show:N \cs:w #1 \cs_end: }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
% \begin{macro}{\l_tmpa_dim}
% \begin{macro}{\l_tmpb_dim}
% \begin{macro}{\l_tmpc_dim}
@@ -914,8 +999,8 @@
% \begin{macro}{\c_max_dim}
% Just aliases.
% \begin{macrocode}
-\let_new:NN \c_zero_dim \c_zero_skip
-\let_new:NN \c_max_dim \c_max_skip
+\cs_new_eq:NN \c_zero_dim \c_zero_skip
+\cs_new_eq:NN \c_max_dim \c_max_skip
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -923,78 +1008,47 @@
% \begin{macro}{\dim_eval:n}
% Evaluating a calc expression.
% \begin{macrocode}
-\def_new:Npn \dim_eval:n #1 {\etex_dimexpr:D #1 \scan_stop:}
+\cs_new_nopar:Npn \dim_eval:n #1 { \etex_dimexpr:D #1 \scan_stop: }
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\if_dim:w}
% The comparison primitive.
% \begin{macrocode}
-\let_new:NN \if_dim:w \tex_ifdim:D
+\cs_new_eq:NN \if_dim:w \tex_ifdim:D
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\dim_compare:nNnTF}
-% \begin{macro}{\dim_compare:nNnT}
-% \begin{macro}{\dim_compare:nNnF}
-% Check the expression and choose branch.
-% \begin{macrocode}
-\def_new:Npn \dim_compare:nNnTF #1#2#3{
- \if_dim:w \dim_eval:n {#1} #2 \dim_eval:n {#3}
- \exp_after:NN \use_arg_i:nn
- \else:
- \exp_after:NN \use_arg_ii:nn
- \fi:
-}
-\def_new:Npn \dim_compare:nNnT #1#2#3{
- \if_dim:w \dim_eval:n {#1} #2 \dim_eval:n {#3}
- \exp_after:NN \use_arg_ii:nn
- \fi:
- \use_none:n
-}
-\def_new:Npn \dim_compare:nNnF #1#2#3{
- \if_dim:w \dim_eval:n {#1} #2 \dim_eval:n {#3}
- \exp_after:NN \use_none:n
- \else:
- \exp_after:NN \use_arg_i:n
- \fi:
-}
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
%
% \begin{macro}{\dim_compare_p:nNn}
-% A predicate function.
+% \begin{macro}[TF]{\dim_compare:nNn}
% \begin{macrocode}
-\def_new:Npn \dim_compare_p:nNn #1#2#3{
+\prg_new_conditional:Nnn \dim_compare:nNn {p,TF,T,F} {
\if_dim:w \dim_eval:n {#1} #2 \dim_eval:n {#3}
- \c_true
- \else:
- \c_false
- \fi:
+ \prg_return_true: \else: \prg_return_false: \fi:
}
% \end{macrocode}
% \end{macro}
+% \end{macro}
%
-% \begin{macro}{\dim_while:nNnT}
-% \begin{macro}{\dim_while:nNnF}
-% \begin{macro}{\dim_dowhile:nNnT}
-% \begin{macro}{\dim_dowhile:nNnF}
-% "while" and "do-while" functions for dimensions. Same as for the
+% \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}
-\def_new:Npn \dim_while:nNnT #1#2#3#4{
- \dim_compare:nNnT {#1}#2{#3}{#4 \dim_while:nNnT {#1}#2{#3}{#4}}
+\cs_new_nopar:Npn \dim_while_do:nNnn #1#2#3#4{
+ \dim_compare:nNnT {#1}#2{#3}{#4 \dim_while_do:nNnn {#1}#2{#3}{#4}}
}
-\def_new:Npn \dim_while:nNnF #1#2#3#4{
- \dim_compare:nNnF {#1}#2{#3}{#4 \dim_while:nNnF {#1}#2{#3}{#4}}
+\cs_new_nopar:Npn \dim_until_do:nNnn #1#2#3#4{
+ \dim_compare:nNnF {#1}#2{#3}{#4 \dim_until_do:nNnn {#1}#2{#3}{#4}}
}
-\def_new:Npn \dim_dowhile:nNnT #1#2#3#4{
- #4 \dim_compare:nNnT {#1}#2{#3}{\dim_dowhile:nNnT {#1}#2{#3}{#4}}
+\cs_new_nopar:Npn \dim_do_while:nNnn #1#2#3#4{
+ #4 \dim_compare:nNnT {#1}#2{#3}{\dim_do_while:nNnn {#1}#2{#3}{#4}}
}
-\def_new:Npn \dim_dowhile:nNnF #1#2#3#4{
- #4 \dim_compare:nNnF {#1}#2{#3}{\dim_dowhile:nNnF {#1}#2{#3}{#4}}
+\cs_new_nopar: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}
@@ -1003,20 +1057,25 @@
% \end{macro}
%
%
-% \subsubsection{Muskips}
+% \subsection{Muskips}
%
% \begin{macro}{\muskip_new:N}
-% \begin{macro}{\muskip_new_l:N}
+%^^A \begin{macro}{\muskip_new_l:N}
% And then we add muskips.
% \begin{macrocode}
%<*initex>
\alloc_setup_type:nnn {muskip} \c_zero \c_max_register_num
-\def_new:Npn \muskip_new:N #1{\alloc_reg:NnNN g {muskip} \tex_muskipdef:D #1}
-\def_new:Npn \muskip_new_l:N #1{\alloc_reg:NnNN l {muskip} \tex_muskipdef:D #1}
+\cs_new_nopar:Npn \muskip_new:N #1{\alloc_reg:NnNN g {muskip} \tex_muskipdef:D #1}
+\cs_new_nopar:Npn \muskip_new_l:N #1{\alloc_reg:NnNN l {muskip} \tex_muskipdef:D #1}
%</initex>
-%<package>\let_new:NN \muskip_new:N \newmuskip % nicked from LaTeX
+%<*package>
+\cs_new_nopar:Npn \muskip_new:N #1 {
+ \chk_if_free_cs:N #1
+ \newmuskip #1
+}
+%</package>
% \end{macrocode}
-% \end{macro}
+%^^A \end{macro}
% \end{macro}
%
% \begin{macro}{\muskip_set:Nn}
@@ -1027,12 +1086,12 @@
% \begin{macro}{\muskip_gsub:Nn}
% Simple functions for muskips.
% \begin{macrocode}
-\def_new:Npn \muskip_set:Nn#1#2{#1\etex_muexpr:D#2\scan_stop:}
-\def_new:Npn \muskip_gset:Nn{\pref_global:D\muskip_set:Nn}
-\def_new:Npn \muskip_add:Nn#1#2{\tex_advance:D#1\etex_muexpr:D#2\scan_stop:}
-\def_new:Npn \muskip_gadd:Nn{\pref_global:D\muskip_add:Nn}
-\def_new:Npn \muskip_sub:Nn#1#2{\tex_advance:D#1-\etex_muexpr:D#2\scan_stop:}
-\def_new:Npn \muskip_gsub:Nn{\pref_global:D\muskip_sub:Nn}
+\cs_new_nopar:Npn \muskip_set:Nn#1#2{#1\etex_muexpr:D#2\scan_stop:}
+\cs_new_nopar:Npn \muskip_gset:Nn{\pref_global:D\muskip_set:Nn}
+\cs_new_nopar:Npn \muskip_add:Nn#1#2{\tex_advance:D#1\etex_muexpr:D#2\scan_stop:}
+\cs_new_nopar:Npn \muskip_gadd:Nn{\pref_global:D\muskip_add:Nn}
+\cs_new_nopar:Npn \muskip_sub:Nn#1#2{\tex_advance:D#1-\etex_muexpr:D#2\scan_stop:}
+\cs_new_nopar:Npn \muskip_gsub:Nn{\pref_global:D\muskip_sub:Nn}
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -1041,50 +1100,18 @@
% \end{macro}
% \end{macro}
%
+% \begin{macro}{\muskip_use:N}
+% Accessing a \meta{muskip}.
% \begin{macrocode}
-%</initex|package>
+\cs_new_eq:NN \muskip_use:N \tex_the:D
% \end{macrocode}
+% \end{macro}
%
-% \endinput
-%
-% $Log$
-% Revision 1.18 2006/03/20 18:26:40 braams
-% Updated the copyright notice (2006) and demoted all implementation
-% sections to subsections and so on to clean up the toc for source3.tex
-%
-% Revision 1.17 2006/01/27 11:22:38 morten
-% Added \muskip_set:Nn and friends (since l3calc uses them).
-%
-% Revision 1.16 2006/01/17 22:46:37 morten
-% Moved \skip_eval:n earlier to avoid error.
-%
-% Revision 1.15 2006/01/17 22:05:35 morten
-% Minor updates
-%
-% Revision 1.14 2006/01/14 19:13:16 morten
-% Added operations for \vskip and \hskip
-%
-% Revision 1.13 2005/12/27 15:54:44 morten
-% Changed RCS information retrieval
-%
-% Revision 1.12 2005/10/27 22:56:15 morten
-% Moved \if_dim:w to this module.
-%
-% Revision 1.11 2005/04/12 12:07:10 morten
-% Added muskips
-%
-% Revision 1.10 2005/04/09 21:09:48 morten
-% Both documentation and implementation cleaned up.
-%
-% Revision 1.9 2005/04/06 22:35:57 braams
-% Now we have register allocation fitted
-%
-% Revision 1.8 2005/03/26 21:05:42 morten
-% Make \c_zero_skip different from \c_zero
-%
-% Revision 1.7 2005/03/16 22:35:47 braams
-% Added the tweaks necessary to be able to load with initex
+% \begin{macrocode}
+%</initex|package>
+% \end{macrocode}
%
-% Revision 1.6 2005/03/11 21:42:48 braams
-% Fixed the use of RCS information; added \StopEventually
+% \end{implementation}
+% \PrintIndex
%
+% \endinput
diff --git a/Master/texmf-dist/source/latex/expl3/l3tl.dtx b/Master/texmf-dist/source/latex/expl3/l3tl.dtx
new file mode 100644
index 00000000000..e63646016e8
--- /dev/null
+++ b/Master/texmf-dist/source/latex/expl3/l3tl.dtx
@@ -0,0 +1,2269 @@
+% \iffalse
+%% File: l3tl.dtx Copyright (C) 1990-2009 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 LaTeX Project Team.
+%%
+%% -----------------------------------------------------------------------
+%
+%<*driver|package>
+\RequirePackage{l3names}
+%</driver|package>
+%\fi
+\GetIdInfo$Id: l3tl.dtx 1365 2009-05-31 17:26:17Z mittelba $
+ {L3 Experimental Token Lists}
+%\iffalse
+%<*driver>
+%\fi
+\ProvidesFile{\filename.\filenameext}
+ [\filedate\space v\fileversion\space\filedescription]
+%\iffalse
+\documentclass[full]{l3doc}
+\begin{document}
+\DocInput{l3tl.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+%
+% \title{The \textsf{l3tl} package\thanks{This file
+% has version number \fileversion, last
+% revised \filedate.}\\
+% Token Lists}
+% \author{\Team}
+% \date{\filedate}
+% \maketitle
+%
+% \def\tlvar{tl var.}
+% \def\tlist{token list}
+%
+% \begin{documentation}
+%
+% \LaTeX3 stores token lists in variables also called `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.
+%
+% \section{Functions}
+%
+% \begin{function}{\tl_new:N |
+% \tl_new:c |
+% \tl_new:Nn |
+% \tl_new:cn |
+% \tl_new:Nx }
+% \begin{syntax}
+% "\tl_new:Nn" <\tlvar> \Arg{initial token list}
+% \end{syntax}
+% Defines <\tlvar> to be a new variable to store a token list.
+% <initial token list> is the initial value of <\tlvar>. This
+% makes it possible to assign values to a constant token list variable.
+%
+% The form "\tl_new:N" initializes the token list variable with an empty value.
+% \end{function}
+%
+% \begin{function}{%
+% \tl_use:N |
+% \tl_use:c
+% }
+% \begin{syntax}
+% "\tl_use:N" <\tlvar>
+% \end{syntax}
+% Function that inserts the <\tlvar> into the processing stream. Instead of
+% |\tl_use:N| simply placing the <\tlvar> into the input stream is also
+% supported. |\tl_use:c| will complain if the <\tlvar> hasn't been declared
+% previously!
+% \end{function}
+%
+% \begin{function}{\tl_show:N |
+% \tl_show:c |
+% \tl_show:n }
+% \begin{syntax}
+% "\tl_show:N" <\tlvar>
+% "\tl_show:n" \Arg{\tlist}
+% \end{syntax}
+% Function that pauses the compilation and displays the <\tlvar>
+% or <\tlist> on the console output and in the log file.
+% \end{function}
+%
+% \begin{function}{%
+% \tl_set:Nn |
+% \tl_set:Nc |
+% \tl_set:NV |
+% \tl_set:No |
+% \tl_set:Nv |
+% \tl_set:Nd |
+% \tl_set:Nf |
+% \tl_set:Nx |
+% \tl_set:cn |
+% \tl_set:co |
+% \tl_set:cV |
+% \tl_set:cx |
+% \tl_gset:Nn |
+% \tl_gset:Nc |
+% \tl_gset:No |
+% \tl_gset:NV |
+% \tl_gset:Nd |
+% \tl_gset:Nv |
+% \tl_gset:Nx |
+% \tl_gset:cn |
+% \tl_gset:cx }
+% \begin{syntax}
+% "\tl_set:Nn" <\tlvar> \Arg{\tlist}
+% \end{syntax}
+% Defines <\tlvar> to hold the token list <\tlist>. Global
+% variants of this command assign the value globally the other variants
+% expand the <\tlist> up to a certain level before the assignment
+% or interpret the <\tlist> as a character list and form a control
+% sequence out of it.
+% \end{function}
+%
+% \begin{function}{%
+% \tl_clear:N |
+% \tl_clear:c |
+% \tl_gclear:N |
+% \tl_gclear:c
+% }
+% \begin{syntax}
+% "\tl_clear:N" <\tlvar>
+% \end{syntax}
+% The <\tlvar> is locally or globally cleared. The "c" variants will
+% generate a control sequence name which is then interpreted as
+% <\tlvar> before clearing.
+% \end{function}
+%
+% \begin{function}{%
+% \tl_clear_new:N |
+% \tl_clear_new:c |
+% \tl_gclear_new:N |
+% \tl_gclear_new:c |
+% }
+% \begin{syntax}
+% "\tl_clear_new:N" <\tlvar>
+% \end{syntax}
+% These functions check if <\tlvar> exists. If it does it will be cleared;
+% if it doesn't it will be allocated.
+% \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 |
+% }
+% \begin{syntax}
+% "\tl_put_left:Nn" <\tlvar> \Arg{\tlist}
+% \end{syntax}
+% These functions will append <\tlist> to the left of
+% <\tlvar>. <\tlist> might be subject to expansion before assignment.
+% \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 |
+% }
+% \begin{syntax}
+% "\tl_put_right:Nn" <\tlvar> \Arg{\tlist}
+% \end{syntax}
+% These functions append <\tlist> to the right of
+% <\tlvar>.
+% \end{function}
+%
+% \begin{function}{%
+% \tl_gput_left:Nn |
+% \tl_gput_left:No |
+% \tl_gput_left:NV |
+% \tl_gput_left:Nx |
+% \tl_gput_left:cn |
+% \tl_gput_left:co |
+% \tl_gput_left:cV |
+% }
+% \begin{syntax}
+% "\tl_gput_left:Nn" <\tlvar> \Arg{\tlist}
+% \end{syntax}
+% These functions will append <\tlist> globally to the left of
+% <\tlvar>.
+% \end{function}
+%
+% \begin{function}{%
+% \tl_gput_right:Nn|
+% \tl_gput_right:No|
+% \tl_gput_right:NV|
+% \tl_gput_right:Nx|
+% \tl_gput_right:cn|
+% \tl_gput_right:co|
+% \tl_gput_right:cV|
+% }
+% \begin{syntax}
+% "\tl_gput_right:Nn" <\tlvar> \Arg{\tlist}
+% \end{syntax}
+% These functions will globally append <\tlist> to the right of
+% <\tlvar>.
+% \end{function}
+%
+% A word of warning is appropriate here: Token list variables are
+% implemented as macros and as such currently inherit some of the
+% peculiarities of how \TeX\ handles "#"s in the argument of
+% macros. In particular, the following actions are legal
+% \begin{verbatim}
+% \tl_set:Nn \l_tmpa_tl{##1}
+% \tl_put_right:Nn \l_tmpa_tl{##2}
+% \tl_set:No \l_tmpb_tl{\l_tmpa_tl ##3}
+% \end{verbatim}
+% |x| type expansions where macros being expanded contain |#|s do not
+% work and will not work until there is an |\expanded| primitive in
+% the engine. If you want them to work you must double |#|s another
+% level.
+%
+%
+% \begin{function}{%
+% \tl_set_eq:NN |
+% \tl_set_eq:Nc |
+% \tl_set_eq:cN |
+% \tl_set_eq:cc |
+% \tl_gset_eq:NN |
+% \tl_gset_eq:Nc |
+% \tl_gset_eq:cN |
+% \tl_gset_eq:cc |
+% }
+% \begin{syntax}
+% "\tl_set_eq:NN" <\tlvar1> <\tlvar2>
+% \end{syntax}
+% Fast form for
+% \begin{syntax}
+% "\tl_set:No" <\tlvar1> \Arg{\tlvar2}
+% \end{syntax}
+% when <\tlvar2> is known to be a variable of type "tl".
+% \end{function}
+%
+% \begin{function}{\tl_to_str:N |
+% \tl_to_str:c
+% }
+% \begin{syntax}
+% "\tl_to_str:N" <\tlvar>
+% \end{syntax}
+% This function returns the token list kept in <\tlvar> as a string list
+% with all characters catcoded to `other'.
+% \end{function}
+%
+% \begin{function}{ \tl_to_str:n }
+% \begin{syntax}
+% "\tl_to_str:n" \Arg{\tlist}
+% \end{syntax}
+% This function turns its argument into a string where all characters
+% have catcode `other'.
+% \begin{texnote}
+% This is the \eTeX\ primitive \tn{detokenize}.
+% \end{texnote}
+% \end{function}
+%
+%
+% \begin{function}{ \tl_rescan:nn }
+% \begin{syntax}
+% "\tl_rescan:nn" \Arg{catcode setup} \Arg{\tlist}
+% \end{syntax}
+% Returns the result of re-tokenising <\tlist> with the catcode setup
+% (and whatever other redefinitions) specified. This is useful because
+% the catcodes of characters are `frozen' when first tokenised; this allows
+% their meaning to be changed even after they've been read as an argument.
+% Also see "\tl_set_rescan:Nnn" below.
+% \begin{texnote}
+% This is a wrapper around \eTeX's "\scantokens".
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{ \tl_set_rescan:Nnn | \tl_set_rescan:Nnx |
+% \tl_gset_rescan:Nnn | \tl_gset_rescan:Nnx }
+% \begin{syntax}
+% "\tl_set_rescan:Nnn" <\tlvar> \Arg{catcode setup} \Arg{\tlist}
+% \end{syntax}
+% Sets <\tlvar> to the result of re-tokenising <\tlist> with the catcode setup
+% (and whatever other redefinitions) specified.
+% \begin{texnote}
+% This is a wrapper around \eTeX's "\scantokens".
+% \end{texnote}
+% \end{function}
+%
+%
+%
+% \section{Predicates and conditionals}
+%
+% \begin{function}{\tl_if_empty_p:N / (EXP) |
+% \tl_if_empty_p:c / (EXP)
+% }
+% \begin{syntax}
+% "\tl_if_empty_p:N" <\tlvar>
+% \end{syntax}
+% This predicate returns `true' if <\tlvar> is `empty' i.e., doesn't
+% contain any tokens.
+% \end{function}
+%
+% \begin{function}{\tl_if_empty:N / (TF)(EXP) |
+% \tl_if_empty:c / (TF)(EXP) |
+% }
+% \begin{syntax}
+% "\tl_if_empty:NTF" <\tlvar> \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Execute <true code> if <\tlvar> is empty and <false code> if it
+% contains any tokens.
+% \end{function}
+%
+% \begin{function}{\tl_if_eq_p:NN / (EXP) |
+% \tl_if_eq_p:cN / (EXP) |
+% \tl_if_eq_p:Nc / (EXP) |
+% \tl_if_eq_p:cc / (EXP) |
+% }
+% \begin{syntax}
+% "\tl_if_eq_p:NN" <\tlvar1> <\tlvar2>
+% \end{syntax}
+% Predicate function which returns `true' if the two token list
+% variables are identical and `false' otherwise.
+% \end{function}
+%
+% \begin{function}{
+% \tl_if_eq:NN / (TF)(EXP) |
+% \tl_if_eq:cN / (TF)(EXP) |
+% \tl_if_eq:Nc / (TF)(EXP) |
+% \tl_if_eq:cc / (TF)(EXP) |
+% }
+% \begin{syntax}
+% "\tl_if_eq:NNTF" <\tlvar1> <\tlvar2> \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Execute <true code> if <\tlvar1> holds the same token list as <\tlvar2>
+% and <false code> otherwise.
+% \end{function}
+%
+%
+% \begin{function}{\tl_if_eq:nn / (TF)(EXP) |
+% \tl_if_eq:nV / (TF)(EXP) |
+% \tl_if_eq:no / (TF)(EXP) |
+% \tl_if_eq:Vn / (TF)(EXP) |
+% \tl_if_eq:on / (TF)(EXP) |
+% \tl_if_eq:VV / (TF)(EXP) |
+% \tl_if_eq:oo / (TF)(EXP) |
+% \tl_if_eq:xx / (TF)(EXP) |
+% \tl_if_eq:xn / (TF)(EXP) |
+% \tl_if_eq:nx / (TF)(EXP) |
+% \tl_if_eq:xV / (TF)(EXP) |
+% \tl_if_eq:xo / (TF)(EXP) |
+% \tl_if_eq:Vx / (TF)(EXP) |
+% \tl_if_eq:ox / (TF)(EXP) }
+% \begin{syntax}
+% "\tl_if_eq:nnTF" \Arg{tlist1} \Arg{tlist2} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Execute <true code> if the two token lists <tlist1> and <tlist2> are
+% identical. These functions are expandable if a new enough version of
+% pdf\TeX\ is being used.
+% \end{function}%
+%
+% \begin{function}{\tl_if_eq_p:nn / (EXP) |
+% \tl_if_eq_p:nV / (EXP) |
+% \tl_if_eq_p:no / (EXP) |
+% \tl_if_eq_p:Vn / (EXP) |
+% \tl_if_eq_p:on / (EXP) |
+% \tl_if_eq_p:VV / (EXP) |
+% \tl_if_eq_p:oo / (EXP) |
+% \tl_if_eq_p:xx / (EXP) |
+% \tl_if_eq_p:xn / (EXP) |
+% \tl_if_eq_p:nx / (EXP) |
+% \tl_if_eq_p:xV / (EXP) |
+% \tl_if_eq_p:xo / (EXP) |
+% \tl_if_eq_p:Vx / (EXP) |
+% \tl_if_eq_p:ox / (EXP) }
+% \begin{syntax}
+% "\tl_if_eq_p:nn" \Arg{tlist1} \Arg{tlist2}
+% \end{syntax}
+% Predicates function which returns `true' if the two token list
+% are identical and `false' otherwise. These are only defined if a new enough version
+% of pdf\TeX\ is in use.
+% \end{function}
+%
+%
+% \begin{function}{\tl_if_empty_p:n / (EXP) |
+% \tl_if_empty_p:V / (EXP) |
+% \tl_if_empty_p:o / (EXP) |
+% \tl_if_empty:n / (TF) |
+% \tl_if_empty:V / (TF) |
+% \tl_if_empty:o / (TF) |
+% }
+% \begin{syntax}
+% "\tl_if_empty:nTF" \Arg{\tlist} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Execute <true code> if <\tlist> doesn't contain any tokens and <false
+% code> otherwise.
+% \end{function}
+%
+% \begin{function}{\tl_if_blank_p:n / (EXP)|
+% \tl_if_blank:n / (TF)(EXP)|
+% \tl_if_blank_p:V / (EXP)|
+% \tl_if_blank_p:o / (EXP)|
+% \tl_if_blank:V / (TF)(EXP)|
+% \tl_if_blank:o / (TF)(EXP)|
+% }
+% \begin{syntax}
+% "\tl_if_blank:nTF" \Arg{\tlist} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Execute <true code> if <\tlist> is blank meaning that it is either
+% empty or contains only blank spaces.
+% \end{function}
+%
+% \begin{function}{\tl_to_lowercase:n |
+% \tl_to_uppercase:n
+% }
+% \begin{syntax}
+% "\tl_to_lowercase:n" \Arg{\tlist}
+% \end{syntax}
+% "\tl_to_lowercase:n" converts all tokens in <\tlist> to their
+% lower case representation. Similar for "\tl_to_uppercase:n".
+% \begin{texnote}
+% These are the \TeX\ primitives \tn{lowercase} and \tn{uppercase}
+% renamed.
+% \end{texnote}
+% \end{function}
+%
+% \section{Working with the contents of token lists}
+%
+% \begin{function}{%
+% \tl_map_function:nN / (EXP) |
+% \tl_map_function:NN |
+% \tl_map_function:cN |
+% }
+% \begin{syntax}
+% "\tl_map_function:nN" \Arg{\tlist} <function> \\
+% "\tl_map_function:NN" <\tlvar> <function>
+% \end{syntax}
+% Runs through all elements in a <\tlist> from left to right and places
+% <function> in front of each element. As this function will also pick
+% up elements in brace groups, the element is returned with braces and
+% hence <function> should be a function with a |:n| suffix even though
+% it may very well only deal with a single token.
+%
+% This function uses a
+% purely expandable loop function and will stay so as long as
+% <function> is expandable too.
+% \end{function}
+%
+% \begin{function}{%
+% \tl_map_inline:nn |
+% \tl_map_inline:Nn |
+% \tl_map_inline:cn |
+% }
+% \begin{syntax}
+% "\tl_map_inline:nn" \Arg{\tlist} \Arg{inline~function} \\
+% "\tl_map_inline:Nn" <\tlvar> \Arg{inline~function}
+% \end{syntax}
+% Allows a syntax like "\tl_map_inline:nn" \Arg{\tlist}
+% "{\token_to_str:N ##1}". This renders it non-expandable though.
+% Remember to double the "#"s for each level.
+% \end{function}
+%
+%
+% \begin{function}{%
+% \tl_map_variable:nNn |
+% \tl_map_variable:NNn |
+% \tl_map_variable:cNn |
+% }
+% \begin{syntax}
+% "\tl_map_variable:nNn" \Arg{\tlist} <temp> \Arg{action} \\
+% "\tl_map_variable:NNn" <\tlvar> <temp> \Arg{action}
+% \end{syntax}
+% Assigns <temp> to each element on <\tlist> and executes <action>.
+% As there is an assignment in this process it is not expandable.
+% \begin{texnote}
+% This is the \LaTeX2{} function \tn{@tfor} but with a more sane syntax.
+% Also it works by tail recursion and so is faster as lists grow longer.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{%
+% \tl_map_break: |
+% }
+% \begin{syntax}
+% "\tl_map_break:"
+% \end{syntax}
+% For breaking out of a loop. Must not be nested inside a primitive
+% "\if" structure.
+% \end{function}
+%
+%
+% \begin{function}{ \tl_reverse:n |
+% \tl_reverse:V |
+% \tl_reverse:o |
+% \tl_reverse:N }
+% \begin{syntax}
+% "\tl_reverse:n" "{"<token1><token2>...<token$\sb n$>"}"\\
+% "\tl_reverse:N" <\tlvar>
+% \end{syntax}
+% Reverse the token list (or the token list in the <\tlvar>) to result in
+% <token$\sb n$>\dots<token2><token1>.
+% Note that spaces in this
+% token list are gobbled in the process.
+%
+% Note also that braces are lost in the process of reversing a <\tlvar>.
+% That is,\\
+% "\tl_set:Nn \l_tmpa_tl {a{bcd}e} \tl_reverse:N \l_tmpa_tl"\\
+% will result in "ebcda". This behaviour is probably more of a bug than
+% a feature.
+% \end{function}
+%
+% \begin{function}{%
+% \tl_elt_count:n / (EXP) |
+% \tl_elt_count:V / (EXP) |
+% \tl_elt_count:o / (EXP) |
+% \tl_elt_count:N / (EXP) |
+% }
+% \begin{syntax}
+% "\tl_elt_count:n" \Arg{\tlist} \\
+% "\tl_elt_count:N" <\tlvar>
+% \end{syntax}
+% Returns the number of elements in the token list. Brace groups
+% encountered count as one element. Note that spaces in this
+% token list are gobbled in the process.
+% \end{function}
+%
+%
+% \section{Variables and constants}
+%
+% \begin{variable}{\c_job_name_tl}
+% Constant that gets the `job name' assigned when \TeX{} starts.
+% \begin{texnote}
+% This is the new name for the primitive \tn{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.
+% \begin{texnote}
+% This was named \tn{@empty} in \LaTeX2 and \tn{empty} in plain \TeX{}.
+% \end{texnote}
+% \end{variable}
+%
+% \begin{variable}{%
+% \l_tmpa_tl |
+% \l_tmpb_tl |
+% \g_tmpa_tl |
+% \g_tmpb_tl
+% }
+% Scratch register for immediate use. They are not used by conditionals
+% or predicate functions.
+% \end{variable}
+%
+% \begin{variable}{%
+% \l_tl_replace_toks |
+% }
+% Internal register used in the replace functions.
+% \end{variable}
+%
+% \begin{variable}{%
+% \l_testa_tl |
+% \l_testb_tl |
+% \g_testa_tl |
+% \g_testb_tl |
+% }
+% Registers used for conditional processing if the engine doesn't
+% support arbitrary string comparison.
+% \end{variable}
+%
+% \begin{variable}{%
+% \g_tl_inline_level_num |
+% }
+% Internal register used in the inline map functions.
+% \end{variable}%
+%
+% \section{Searching for and replacing tokens}
+%
+% \begin{function}{
+% \tl_if_in:Nn / (TF) |
+% \tl_if_in:cn / (TF) |
+% \tl_if_in:nn / (TF) |
+% \tl_if_in:Vn / (TF) |
+% \tl_if_in:on / (TF) |
+% }
+% \begin{syntax}
+% "\tl_if_in:NnTF" <\tlvar> \Arg{item} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Function that tests if <item> is in <\tlvar>. Depending on the result
+% either <true code> or <false code> is executed. Note that <item>
+% cannot contain brace groups nor "#"$_6$ tokens.
+% \end{function}
+%
+% \begin{function}{
+% \tl_replace_in:Nnn |
+% \tl_replace_in:cnn |
+% \tl_greplace_in:Nnn |
+% \tl_greplace_in:cnn |
+% }
+% \begin{syntax}
+% "\tl_replace_in:Nnn" <\tlvar> \Arg{item1} \Arg{item2}
+% \end{syntax}
+% Replaces the leftmost occurrence of <item1> in <\tlvar> with
+% <item2> if present, otherwise the <\tlvar> is left untouched.
+% Note that <item1>
+% cannot contain brace groups nor "#"$_6$ tokens, and <item2>
+% cannot contain "#"$_6$ tokens.
+% \end{function}
+%
+% \begin{function}{
+% \tl_replace_all_in:Nnn |
+% \tl_replace_all_in:cnn |
+% \tl_greplace_all_in:Nnn |
+% \tl_greplace_all_in:cnn |
+% }
+% \begin{syntax}
+% "\tl_replace_all_in:Nnn" <\tlvar> \Arg{item1} \Arg{item2}
+% \end{syntax}
+% Replaces \emph{all} occurrences of <item1> in <\tlvar> with
+% <item2>.
+% Note that <item1>
+% cannot contain brace groups nor "#"$_6$ tokens, and <item2>
+% cannot contain "#"$_6$ tokens.
+% \end{function}
+%
+%
+% \begin{function}{
+% \tl_remove_in:Nn |
+% \tl_remove_in:cn |
+% \tl_gremove_in:Nn |
+% \tl_gremove_in:cn |
+% }
+% \begin{syntax}
+% "\tl_remove_in:Nn" <\tlvar> \Arg{item}
+% \end{syntax}
+% Removes the leftmost occurrence of <item> from <\tlvar> if present.
+% Note that <item>
+% cannot contain brace groups nor "#"$_6$ tokens.
+% \end{function}
+%
+%
+% \begin{function}{
+% \tl_remove_all_in:Nn |
+% \tl_remove_all_in:cn |
+% \tl_gremove_all_in:Nn |
+% \tl_gremove_all_in:cn |
+% }
+% \begin{syntax}
+% "\tl_remove_all_in:Nn" <\tlvar> \Arg{item}
+% \end{syntax}
+% Removes \emph{all} occurrences of <item> from <\tlvar>. Note that <item>
+% cannot contain brace groups nor "#"$_6$ tokens.
+% \end{function}
+%
+%
+% \section{Heads or tails?}
+%
+% Here are some functions for grabbing either the head or tail of a
+% list and perform some tests on it.
+%
+% \begin{function}{%
+% \tl_head:n |
+% \tl_tail:n |
+% \tl_tail:f |
+% \tl_head_i:n |
+% \tl_head_iii:n |
+% \tl_head_iii:f |
+% \tl_head:w |
+% \tl_tail:w |
+% \tl_head_i:w |
+% \tl_head_iii:w
+% }
+% \begin{syntax}
+% "\tl_head:n" "{" <token1><token2>...<token\,$\sb n$> "}" \\
+% "\tl_tail:n" "{" <token1><token2>...<token\,$\sb n$> "}" \\
+% "\tl_head:w" <token1><token2>...<token\,$\sb n$> "\q_nil"
+% \end{syntax}
+% These functions return either the head or the tail of a list, thus in
+% the above example "\tl_head:n" would return <token1> and "\tl_tail:n"
+% would return <token2>\dots<token\,$\sb n$>. "\tl_head_iii:n" returns the first
+% three tokens. The ":w" versions require some care as they use a
+% delimited argument internally.
+% \begin{texnote}
+% These are the Lisp functions "car" and "cdr" but with \LaTeX3 names.
+% \end{texnote}
+% \end{function}
+%
+%
+%
+%
+% \begin{function}{%
+% \tl_if_head_eq_meaning_p:nN / (EXP) |
+% \tl_if_head_eq_meaning:nN / (TF)(EXP) |
+% }
+% \begin{syntax}
+% "\tl_if_head_eq_meaning:nNTF" \Arg{\tlist} <token>
+% \Arg{true} \Arg{false}
+% \end{syntax}
+% Returns <true> if the first token in <\tlist> is equal to
+% <token> and <false> otherwise. The |meaning| version compares the
+% two tokens with |\if_meaning:w|.
+% \end{function}
+%
+% \begin{function}{%
+% \tl_if_head_eq_charcode_p:nN / (EXP) |
+% \tl_if_head_eq_charcode_p:fN / (EXP) |
+% \tl_if_head_eq_charcode:nN / (TF)(EXP) |
+% \tl_if_head_eq_charcode:fN / (TF)(EXP) |
+% }
+% \begin{syntax}
+% "\tl_if_head_eq_charcode:nNTF" \Arg{\tlist} <token>
+% \Arg{true} \Arg{false}
+% \end{syntax}
+% Returns <true> if the first token in <\tlist> is equal to
+% <token> and <false> otherwise. The |meaning| version compares the
+% two tokens with |\if_charcode:w| but it prevents expansion of
+% them. If you want them to expand, you can use an |f| type expansion
+% first (define |\tl_if_head_eq_charcode:fNTF| or similar).
+% \end{function}
+%
+% \begin{function}{%
+% \tl_if_head_eq_catcode_p:nN / (EXP) |
+% \tl_if_head_eq_catcode:nN / (TF)(EXP) |
+% }
+% \begin{syntax}
+% "\tl_if_head_eq_catcode:nNTF" \Arg{\tlist} <token>
+% \Arg{true} \Arg{false}
+% \end{syntax}
+% Returns <true> if the first token in <\tlist> is equal to
+% <token> and <false> otherwise. This version uses |\if_catcode:w| for
+% the test but is otherwise identical to the |charcode| version.
+% \end{function}
+%
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3tl} implementation}
+%
+% We start by ensuring that the required packages are loaded.
+% \begin{macrocode}
+%<*package>
+\ProvidesExplPackage
+ {\filename}{\filedate}{\fileversion}{\filedescription}
+\package_check_loaded_expl:
+%</package>
+% \end{macrocode}
+% \begin{macrocode}
+%<*initex|package>
+% \end{macrocode}
+%
+% A token list variable is a control sequence that holds tokens. The
+% interface is similar to that for token registers, but beware that
+% the behavior vis \'a vis |\cs_set_nopar:Npx| etc. \ldots{} is different. (You
+% see this comes from Denys' implementation.)
+%
+%
+% \subsection{Functions}
+%
+% \begin{macro}{\tl_new:N}
+% \begin{macro}{\tl_new:c}
+% \begin{macro}{\tl_new:Nn}
+% \begin{macro}{\tl_new:cn}
+% \begin{macro}{\tl_new:Nx}
+% We provide one allocation function (which checks that the name is
+% not used) and two clear functions that locally or globally clear
+% the token list. The allocation function has two arguments to
+% specify an initial value. This is the only way to give values to
+% constants.
+% \begin{macrocode}
+\cs_new:Npn \tl_new:Nn #1#2{
+ \chk_if_free_cs:N #1
+% \end{macrocode}
+% If checking we don't allow constants to be defined.
+% \begin{macrocode}
+%<*check>
+ \chk_var_or_const:N #1
+%</check>
+% \end{macrocode}
+% Otherwise any variable type is allowed.
+% \begin{macrocode}
+ \cs_gset_nopar:Npn #1{#2}
+}
+\cs_generate_variant:Nn \tl_new:Nn {cn}
+\cs_new:Npn \tl_new:Nx #1#2{
+ \chk_if_free_cs:N #1
+%<check> \chk_var_or_const:N #1
+ \cs_gset_nopar:Npx #1{#2}
+}
+\cs_new_nopar:Npn \tl_new:N #1{\tl_new:Nn #1{}}
+\cs_new_nopar:Npn \tl_new:c #1{\tl_new:cn {#1}{}}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\tl_use:N}
+% \begin{macro}{\tl_use:c}
+% Perhaps this should just be enabled when checking?
+% \begin{macrocode}
+\cs_new_nopar:Npn \tl_use:N #1 {
+ \if_meaning:w #1 \tex_relax:D
+% \end{macrocode}
+% If \m{\tlvar} equals |\tex_relax:D| it is probably stemming from a
+% |\cs:w|\dots|\cs_end:| that was created by mistake somewhere.
+% \begin{macrocode}
+ \msg_kernel_bug:x {Token~list~variable~ `\token_to_str:N #1'~
+ has~ an~ erroneous~ structure!}
+ \else:
+ \exp_after:wN #1
+ \fi:
+}
+\cs_generate_variant:Nn \tl_use:N {c}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\tl_show:N,\tl_show:c,\tl_show:n}
+% Showing a \meta{\tlvar} is just "\show"ing it and I don't really care
+% about checking that it's malformed at this stage.
+% \begin{macrocode}
+\cs_new_nopar:Npn \tl_show:N #1 { \cs_show:N #1 }
+\cs_generate_variant:Nn \tl_show:N {c}
+\cs_set_eq:NN \tl_show:n \etex_showtokens:D
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\tl_set:Nn}
+% \begin{macro}{\tl_set:NV}
+% \begin{macro}{\tl_set:No}
+% \begin{macro}{\tl_set:Nv}
+% \begin{macro}{\tl_set:Nd}
+% \begin{macro}{\tl_set:Nf}
+% \begin{macro}{\tl_set:Nx}
+% \begin{macro}{\tl_set:cn}
+% \begin{macro}{\tl_set:cV}
+% \begin{macro}{\tl_set:co}
+% \begin{macro}{\tl_set:cx}
+% \begin{macro}{\tl_gset:Nn}
+% \begin{macro}{\tl_gset:NV}
+% \begin{macro}{\tl_gset:No}
+% \begin{macro}{\tl_gset:Nv}
+% \begin{macro}{\tl_gset:Nd}
+% \begin{macro}{\tl_gset:Nx}
+% \begin{macro}{\tl_gset:cn}
+% \begin{macro}{\tl_gset:cx}
+% To set token lists to a specific value to type of functions are
+% available: |\tl_set_eq:NN| takes two token-lists as its
+% arguments assign the first the contents of the second;
+% |\tl_set:Nn| has as its second argument a `real' list of tokens.
+% One can view |\tl_set_eq:NN| as a special form of |\tl_set:No|.
+% Both functions have global counterparts.
+%
+% During development we check if the token list that is being
+% assigned to exists. If not, a warning will be issued.
+% \begin{macrocode}
+%<*check>
+\cs_new:Npn \tl_set:Nn #1#2{
+ \chk_exist_cs:N #1 \cs_set_nopar:Npn #1{#2}
+% \end{macrocode}
+% We use |\chk_local_or_pref_global:N| after the assignment to
+% allow constructs with |\pref_global_chk:|. But one should note
+% that this is less efficient then using the real global variant
+% since they are built-in.
+% \begin{macrocode}
+ \chk_local_or_pref_global:N #1
+}
+\cs_new:Npn \tl_set:Nx #1#2{
+ \chk_exist_cs:N #1 \cs_set_nopar:Npx #1{#2} \chk_local:N #1
+}
+% \end{macrocode}
+% The the global versions.
+% \begin{macrocode}
+\cs_new:Npn \tl_gset:Nn #1#2{
+ \chk_exist_cs:N #1 \cs_gset_nopar:Npn #1{#2} \chk_global:N #1
+}
+\cs_new:Npn \tl_gset:Nx #1#2{
+ \chk_exist_cs:N #1 \cs_gset_nopar:Npx #1{#2} \chk_global:N #1
+}
+%</check>
+% \end{macrocode}
+% For some functions like |\tl_set:Nn| we need to define the
+% `non-check' version with arguments since we want to allow
+% constructions like |\tl_set:Nn\l_tmpa_tl\foo| and so we can't
+% use the primitive \TeX{} command.
+% \begin{macrocode}
+%<*!check>
+\cs_new:Npn\tl_set:Nn#1#2{\cs_set_nopar:Npn#1{#2}}
+\cs_new:Npn\tl_set:Nx#1#2{\cs_set_nopar:Npx#1{#2}}
+\cs_new:Npn\tl_gset:Nn#1#2{\cs_gset_nopar:Npn#1{#2}}
+\cs_new:Npn\tl_gset:Nx#1#2{\cs_gset_nopar:Npx#1{#2}}
+%</!check>
+% \end{macrocode}
+% The remaining functions can just be defined with help from the
+% expansion module.
+% \begin{macrocode}
+\cs_generate_variant:Nn \tl_set:Nn {NV,No,Nv,Nd,Nf,cn,cV,co,cx}
+\cs_generate_variant:Nn \tl_gset:Nn {NV,No,Nv,Nd,cn,cx}
+% \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}
+%
+% \begin{macro}{\tl_set_eq:NN}
+% \begin{macro}{\tl_set_eq:Nc}
+% \begin{macro}{\tl_set_eq:cN}
+% \begin{macro}{\tl_set_eq:cc}
+% \begin{macro}{\tl_gset_eq:NN}
+% \begin{macro}{\tl_gset_eq:Nc}
+% \begin{macro}{\tl_gset_eq:cN}
+% \begin{macro}{\tl_gset_eq:cc}
+% For setting token list variables equal to each other. First checking:
+% \begin{macrocode}
+%<*check>
+\cs_new_nopar:Npn \tl_set_eq:NN #1#2{
+ \chk_exist_cs:N #1 \cs_set_eq:NN #1#2
+ \chk_local_or_pref_global:N #1 \chk_var_or_const:N #2
+}
+\cs_new_nopar:Npn \tl_gset_eq:NN #1#2{
+ \chk_exist_cs:N #1 \cs_gset_eq:NN #1#2
+ \chk_global:N #1 \chk_var_or_const:N #2
+}
+%</check>
+% \end{macrocode}
+% Non-checking versions are easy.
+% \begin{macrocode}
+%<*!check>
+\cs_new_eq:NN \tl_set_eq:NN \cs_set_eq:NN
+\cs_new_eq:NN \tl_gset_eq:NN \cs_gset_eq:NN
+%</!check>
+% \end{macrocode}
+% The rest again with the expansion module.
+% \begin{macrocode}
+\cs_generate_variant:Nn \tl_set_eq:NN {Nc,c,cc}
+\cs_generate_variant:Nn \tl_gset_eq:NN {Nc,c,cc}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+%
+%
+% \begin{macro}{\tl_clear:N}
+% \begin{macro}{\tl_clear:c}
+% \begin{macro}{\tl_gclear:N}
+% \begin{macro}{\tl_gclear:c}
+% Clearing a token list variable.
+% \begin{macrocode}
+\cs_new_nopar:Npn \tl_clear:N #1{\tl_set_eq:NN #1\c_empty_tl}
+\cs_generate_variant:Nn \tl_clear:N {c}
+\cs_new_nopar:Npn \tl_gclear:N #1{\tl_gset_eq:NN #1\c_empty_tl}
+\cs_generate_variant:Nn \tl_gclear:N {c}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\tl_clear_new:N}
+% \begin{macro}{\tl_clear_new:c}
+% These macros check whether a token list exists. If it does it
+% is cleared, if it doesn't it is allocated.
+% \begin{macrocode}
+%<*check>
+\cs_new_nopar:Npn \tl_clear_new:N #1{
+ \chk_var_or_const:N #1
+ \if_predicate:w \cs_if_exist_p:N #1
+ \tl_clear:N #1
+ \else:
+ \tl_new:Nn #1{}
+ \fi:
+}
+%</check>
+%<-check>\cs_new_eq:NN \tl_clear_new:N \tl_clear:N
+\cs_generate_variant:Nn \tl_clear_new:N {c}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\tl_gclear_new:N}
+% \begin{macro}{\tl_gclear_new:c}
+% These are the global versions of the above.
+% \begin{macrocode}
+%<*check>
+\cs_new_nopar:Npn \tl_gclear_new:N #1{
+ \chk_var_or_const:N #1
+ \if_predicate:w \cs_if_exist_p:N #1
+ \tl_gclear:N #1
+ \else:
+ \tl_new:Nn #1{}
+ \fi:}
+%</check>
+%<-check>\cs_new_eq:NN \tl_gclear_new:N \tl_gclear:N
+\cs_generate_variant:Nn \tl_gclear_new:N {c}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\tl_put_left:Nn}
+% \begin{macro}{\tl_put_left:NV}
+% \begin{macro}{\tl_put_left:No}
+% \begin{macro}{\tl_put_left:Nx}
+% \begin{macro}{\tl_put_left:cn}
+% \begin{macro}{\tl_put_left:cV}
+% \begin{macro}{\tl_put_left:co}
+% \begin{macro}{\tl_gput_left:Nn}
+% \begin{macro}{\tl_gput_left:NV}
+% \begin{macro}{\tl_gput_left:No}
+% \begin{macro}{\tl_gput_left:Nx}
+% \begin{macro}{\tl_gput_left:cn}
+% \begin{macro}{\tl_gput_left:cV}
+% \begin{macro}{\tl_gput_left:co}
+% We can add tokens to the left (either globally or locally). It is
+% not quite as easy as we would like because we have to ensure the
+% assignments
+% \begin{verbatim}
+% \tl_set:Nn \l_tmpa_tl{##1abc##2def}
+% \tl_set:Nn \l_tmpb_tl{##1abc}
+% \tl_put_right:Nn \l_tmpb_tl {##2def}
+% \end{verbatim}
+% cause |\l_tmpa_tl| and |\l_tmpb_tl| to be identical. The old
+% code did not succeed in doing this (it gave an error) and so we
+% use a different technique where the item(s) to be added are first
+% stored in a temporary variable and then added using an |x| type
+% expansion combined with the appropriate level of
+% non-expansion. Putting the tokens directly into one assignment
+% does not work unless we want full expansion. Note (according to
+% the warning earlier) \TeX\ does not allow us to treat |#|s the
+% same in all cases. Tough.
+% \begin{macrocode}
+\cs_new:Npn \tl_put_left:Nn #1#2 {
+ \tl_set:Nn \l_exp_tl {#2}
+ \tl_set:Nx #1 { \exp_not:V \l_exp_tl \exp_not:V #1 }
+%<check> \chk_local_or_pref_global:N #1
+}
+\cs_new:Npn \tl_put_left:NV #1#2 {
+ \tl_set:Nx #1 { \exp_not:V #2 \exp_not:V #1 }
+}
+\cs_new:Npn \tl_put_left:No #1#2{
+ \tl_set:No \l_exp_tl {#2}
+ \tl_set:Nx #1 { \exp_not:V \l_exp_tl \exp_not:V #1 }
+%<check> \chk_local_or_pref_global:N #1
+}
+\cs_new:Npn \tl_put_left:Nx #1#2{
+ \tl_set:Nx #1 { #2 \exp_not:V #1 }
+%<check> \chk_local_or_pref_global:N #1
+}
+\cs_new:Npn \tl_gput_left:Nn #1#2{
+ \tl_set:Nn \l_exp_tl{#2}
+ \tl_gset:Nx #1 { \exp_not:V \l_exp_tl \exp_not:V #1 }
+%<check> \chk_local_or_pref_global:N #1
+}
+\cs_new:Npn \tl_gput_left:NV #1#2 {
+ \tl_gset:Nx #1 { \exp_not:V #2 \exp_not:V #1 }
+}
+\cs_new:Npn \tl_gput_left:No #1#2{
+ \tl_set:No \l_exp_tl {#2}
+ \tl_gset:Nx #1 { \exp_not:V \l_exp_tl \exp_not:V #1 }
+%<check> \chk_local_or_pref_global:N #1
+}
+\cs_new:Npn \tl_gput_left:Nx #1#2{
+ \tl_gset:Nx #1 { #2 \exp_not:V #1 }
+%<check> \chk_local_or_pref_global:N #1
+}
+\cs_generate_variant:Nn \tl_put_left:Nn {cn,co}
+\cs_generate_variant:Nn \tl_put_left:NV {cV}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_generate_variant:Nn \tl_gput_left:Nn {cn,co}
+\cs_generate_variant:Nn \tl_gput_left:NV {cV}
+% \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}{\tl_put_right:Nn}
+% \begin{macro}{\tl_put_right:NV}
+% \begin{macro}{\tl_put_right:No}
+% \begin{macro}{\tl_put_right:Nx}
+% \begin{macro}{\tl_put_right:cn}
+% \begin{macro}{\tl_put_right:cV}
+% \begin{macro}{\tl_put_right:co}
+% \begin{macro}{\tl_gput_right:Nn}
+% \begin{macro}{\tl_gput_right:NV}
+% \begin{macro}{\tl_gput_right:No}
+% \begin{macro}{\tl_gput_right:Nx}
+% \begin{macro}{\tl_gput_right:cn}
+% \begin{macro}{\tl_gput_right:cV}
+% \begin{macro}{\tl_gput_right:co}
+% These are variants of the functions above, but for adding tokens
+% to the right.
+% \begin{macrocode}
+\cs_new:Npn \tl_put_right:Nn #1#2 {
+ \tl_set:Nn \l_exp_tl {#2}
+ \tl_set:Nx #1 { \exp_not:V #1 \exp_not:V \l_exp_tl }
+%<check> \chk_local_or_pref_global:N #1
+}
+\cs_new:Npn \tl_gput_right:Nn #1#2{
+ \tl_set:Nn \l_exp_tl {#2}
+ \tl_gset:Nx #1 { \exp_not:V #1 \exp_not:V \l_exp_tl }
+%<check> \chk_local_or_pref_global:N #1
+}
+\cs_new:Npn \tl_put_right:NV #1#2 {
+ \tl_set:Nx #1 { \exp_not:V #1 \exp_not:V #2 }
+}
+\cs_new:Npn \tl_put_right:No #1#2 {
+ \tl_set:No \l_exp_tl {#2}
+ \tl_set:Nx #1 { \exp_not:V #1 \exp_not:V \l_exp_tl }
+%<check> \chk_local_or_pref_global:N #1
+}
+\cs_new:Npn \tl_gput_right:NV #1#2 {
+ \tl_gset:Nx #1 { \exp_not:V #1 \exp_not:V #2 }
+}
+\cs_new:Npn \tl_gput_right:No #1#2 {
+ \tl_set:No \l_exp_tl {#2}
+ \tl_gset:Nx #1 { \exp_not:V #1 \exp_not:V \l_exp_tl }
+%<check> \chk_local_or_pref_global:N #1
+}
+\cs_set:Npn \tl_put_right:Nx #1#2 {
+ \tl_set:Nx #1 { \exp_not:V #1 #2 }
+%<check> \chk_local_or_pref_global:N #1
+}
+\cs_set:Npn \tl_gput_right:Nx #1#2 {
+ \tl_gset:Nx #1 { \exp_not:V #1 #2 }
+%<check> \chk_local_or_pref_global:N #1
+}
+\cs_generate_variant:Nn \tl_put_right:Nn {cn,co}
+\cs_generate_variant:Nn \tl_put_right:NV {cV}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_generate_variant:Nn \tl_gput_right:Nn {cn,co}
+\cs_generate_variant:Nn \tl_gput_right:NV {cV}
+% \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}{\tl_gset:Nc}
+% \begin{macro}{\tl_set:Nc}
+% These two functions are included because they are necessary in
+% Denys' implementations. The |:Nc| convention (see the expansion
+% module) is very unusual at first sight, but it works nicely
+% over all modules, so we would like to keep it.
+%
+% Construct a control sequence on the fly from |#2| and save it in
+% |#1|.
+% \begin{macrocode}
+\cs_new_nopar:Npn \tl_gset:Nc {
+%<*check>
+ \pref_global_chk:
+%</check>
+%<-check> \pref_global:D
+ \tl_set:Nc}
+% \end{macrocode}
+% |\pref_global_chk:| will turn the variable check in |\tl_set:No|
+% into a global check.
+% \begin{macrocode}
+\cs_new_nopar:Npn \tl_set:Nc #1#2{\tl_set:No #1{\cs:w#2\cs_end:}}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Variables and constants}
+%
+% \begin{macro}{\c_job_name_tl}
+% Inherited from the expl3 name for the primitive.
+% \begin{macrocode}
+\tl_new:Nn \c_job_name_tl {\tex_jobname:D}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\c_empty_tl}
+% Two constants which are often used.
+% \begin{macrocode}
+\tl_new:Nn \c_empty_tl {}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\g_tmpa_tl}
+% \begin{macro}{\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:Nn \g_tmpa_tl{}
+\tl_new:Nn \g_tmpb_tl{}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\l_testa_tl}
+% \begin{macro}{\l_testb_tl}
+% \begin{macro}{\g_testa_tl}
+% \begin{macro}{\g_testb_tl}
+% Global and local temporaries. These are the ones for test
+% routines. This means that one can safely use other temporaries
+% when calling test routines.
+% \begin{macrocode}
+\tl_new:Nn \l_testa_tl {}
+\tl_new:Nn \l_testb_tl {}
+\tl_new:Nn \g_testa_tl {}
+\tl_new:Nn \g_testb_tl {}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\l_tmpa_tl}
+% \begin{macro}{\l_tmpb_tl}
+% These are local temporary token list variables.
+% \begin{macrocode}
+\tl_new:Nn \l_tmpa_tl{}
+\tl_new:Nn \l_tmpb_tl{}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+%
+% \subsection{Predicates and conditionals}
+%
+% We also provide a few conditionals, both in expandable form (with
+% |\c_true_bool|) and in `brace-form', the latter are denoted by |TF| at the
+% end, as explained elsewhere.
+%
+%
+% \begin{macro}{\tl_if_empty_p:N,\tl_if_empty_p:c}
+% \begin{macro}[TF]{\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,TF,T,F} {
+ \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:NTF {c}
+\cs_generate_variant:Nn \tl_if_empty:NT {c}
+\cs_generate_variant:Nn \tl_if_empty:NF {c}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\tl_if_eq_p:NN,\tl_if_eq_p:Nc,\tl_if_eq_p:cN,\tl_if_eq_p:cc}
+% \begin{macro}[TF]{\tl_if_eq:NN,\tl_if_eq:Nc,\tl_if_eq:cN,\tl_if_eq:cc}
+% Returns |\c_true_bool| iff the two token list variables are equal.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \tl_if_eq:NN #1#2 {p,TF,T,F} {
+ \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}
+% \end{macro}
+%
+%
+% \begin{macro}{\tl_if_empty_p:n,\tl_if_empty_p:V,\tl_if_empty_p:o}
+% \begin{macro}[TF]{\tl_if_empty:n,\tl_if_empty:V,\tl_if_empty:o}
+% 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}
+\cs_generate_variant:Nn \tl_if_empty_p:n {o}
+\cs_generate_variant:Nn \tl_if_empty:nTF {o}
+\cs_generate_variant:Nn \tl_if_empty:nT {o}
+\cs_generate_variant:Nn \tl_if_empty:nF {o}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\tl_if_blank_p:n,\tl_if_blank_p:V,\tl_if_blank_p:o}
+% \begin{macro}[TF]{\tl_if_blank:n,\tl_if_blank:V,\tl_if_blank:o}
+% \begin{macro}[aux]{\tl_if_blank_p_aux:w}
+% This is based on the answers in ``Around the Bend No~2'' but is
+% safer as the tests listed there all have one small flaw: If the
+% input in the test is two tokens with the same meaning as the
+% internal delimiter, they will fail since one of them is mistaken
+% for the actual delimiter. In our version below we make sure to
+% pass the input through |\tl_to_str:n| which ensures that all
+% the tokens are converted to catcode 12. However we use an |a| with
+% catcode 11 as delimiter so we can \emph{never} get into the same
+% problem as the solutions in ``Around the Bend No~2''.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \tl_if_blank:n #1 {p,TF,T,F} {
+ \exp_after:wN \tl_if_blank_p_aux:w \tl_to_str:n {#1} aa..\q_nil
+}
+\cs_new:Npn \tl_if_blank_p_aux:w #1#2 a #3#4 \q_nil {
+ \if_meaning:w #3 #4 \prg_return_true: \else: \prg_return_false: \fi:
+}
+\cs_generate_variant:Nn \tl_if_blank_p:n {V}
+\cs_generate_variant:Nn \tl_if_blank:nTF {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_p:n {o}
+\cs_generate_variant:Nn \tl_if_blank:nTF {o}
+\cs_generate_variant:Nn \tl_if_blank:nT {o}
+\cs_generate_variant:Nn \tl_if_blank:nF {o}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[TF]{\tl_if_eq:xx,\tl_if_eq:nn,\tl_if_eq:VV,\tl_if_eq:oo,
+% \tl_if_eq:xn,\tl_if_eq:nx,\tl_if_eq:on,\tl_if_eq:no,
+% \tl_if_eq:Vn,\tl_if_eq:nV,
+% \tl_if_eq:xV,\tl_if_eq:xo,\tl_if_eq:Vx,\tl_if_eq:ox}
+% \begin{macro}{\tl_if_eq_p:xx,\tl_if_eq_p:nn,\tl_if_eq_p:VV,\tl_if_eq_p:oo,
+% \tl_if_eq_p:xn,\tl_if_eq_p:nx,\tl_if_eq_p:Vn,\tl_if_eq_p:on,
+% \tl_if_eq_p:nV,\tl_if_eq_p:no,\tl_if_eq_p:xV,\tl_if_eq_p:Vx,
+% \tl_if_eq_p:xo,\tl_if_eq_p:ox}
+% Test if two token lists are identical. pdf\TeX\ contains a most
+% interesting primitive for expandable string comparison so we make
+% use of it if available. Presumable it will be in the final
+% version.
+%
+% Firstly we give it an appropriate name. Note that this primitive
+% actually performs an \texttt{x} type expansion but it is still
+% expandable! Hence we must program these functions backwards to add
+% \verb|\exp_not:n|. We provide the combinations for the types
+% \texttt{n}, \texttt{o} and \texttt{x}.
+% \begin{macrocode}
+\cs_new_eq:NN \tl_compare:xx \pdf_strcmp:D
+\cs_new:Npn \tl_compare:nn #1#2{
+ \tl_compare:xx{\exp_not:n{#1}}{\exp_not:n{#2}}
+}
+\cs_new:Npn \tl_compare:nx #1{
+ \tl_compare:xx{\exp_not:n{#1}}
+}
+\cs_new:Npn \tl_compare:xn #1#2{
+ \tl_compare:xx{#1}{\exp_not:n{#2}}
+}
+\cs_new:Npn \tl_compare:nV #1#2 {
+ \tl_compare:xx { \exp_not:n {#1} } { \exp_not:V #2 }
+}
+\cs_new:Npn \tl_compare:no #1#2{
+ \tl_compare:xx{\exp_not:n{#1}}{\exp_not:n\exp_after:wN{#2}}
+}
+\cs_new:Npn \tl_compare:Vn #1#2 {
+ \tl_compare:xx { \exp_not:V #1 } { \exp_not:n {#2} }
+}
+\cs_new:Npn \tl_compare:on #1#2{
+ \tl_compare:xx{\exp_not:n\exp_after:wN{#1}}{\exp_not:n{#2}}
+}
+\cs_new:Npn \tl_compare:VV #1#2 {
+ \tl_compare:xx { \exp_not:V #1 } { \exp_not:V #2 }
+}
+\cs_new:Npn \tl_compare:oo #1#2{
+ \tl_compare:xx{\exp_not:n\exp_after:wN{#1}}{\exp_not:n\exp_after:wN{#2}}
+}
+\cs_new:Npn \tl_compare:xV #1#2 {
+ \tl_compare:xx {#1} { \exp_not:V #2 }
+}
+\cs_new:Npn \tl_compare:xo #1#2{
+ \tl_compare:xx{#1}{\exp_not:n\exp_after:wN{#2}}
+}
+\cs_new:Npn \tl_compare:Vx #1#2 {
+ \tl_compare:xx { \exp_not:V #1 } {#2}
+}
+\cs_new:Npn \tl_compare:ox #1#2{
+ \tl_compare:xx{\exp_not:n\exp_after:wN{#1}}{#2}
+}
+% \end{macrocode}
+% Since we have a lot of basically identical functions to define we
+% define one to define the rest. Unfortunately we aren't quite set up
+% to use the new \verb|\tl_map_inline:nn| function yet.
+% \begin{macrocode}
+\cs_set_nopar:Npn \tl_tmp:w #1 {
+ \tl_set:Nx \l_tmpa_tl {
+ \exp_not:N \prg_new_conditional:Npnn \exp_not:c {tl_if_eq:#1}
+ ####1 ####2 {p,TF,T,F} {
+ \exp_not:N \tex_ifnum:D
+ \exp_not:c {tl_compare:#1} {####1}{####2}
+ \exp_not:n{ =\c_zero \prg_return_true: \else: \prg_return_false: \fi: }
+ }
+ }
+ \l_tmpa_tl
+}
+\tl_tmp:w{xx} \tl_tmp:w{nx} \tl_tmp:w{ox} \tl_tmp:w{Vx}
+\tl_tmp:w{xn} \tl_tmp:w{nn} \tl_tmp:w{on} \tl_tmp:w{Vn}
+\tl_tmp:w{xo} \tl_tmp:w{no} \tl_tmp:w{oo}
+\tl_tmp:w{xV} \tl_tmp:w{nV} \tl_tmp:w{VV}
+% \end{macrocode}
+% However all of this only makes sense if we actually have that
+% primitive. Therefore we disable it again if it is not there and
+% define \verb|\tl_if_eq:nn| the old fashioned (and unexpandable)
+% way.
+%
+% In some cases below, since arbitrary token lists could be being used in
+% this function, you can't assume (as token list variables usually do) that there won't be
+% any |#| tokens. Therefore, "\tl_set:Nx" and "\exp_not:n" is used instead
+% of plain "\tl_set:Nn".
+%
+% \begin{macrocode}
+\cs_if_exist:cF{pdf_strcmp:D}{
+ \prg_set_protected_conditional:Npnn \tl_if_eq:nn #1#2 {TF,T,F} {
+ \tl_set:Nx \l_testa_tl {\exp_not:n{#1}}
+ \tl_set:Nx \l_testb_tl {\exp_not:n{#2}}
+ \if_meaning:w\l_testa_tl \l_testb_tl
+ \prg_return_true: \else: \prg_return_false:
+ \fi:
+ }
+ \prg_set_protected_conditional:Npnn \tl_if_eq:nV #1#2 {TF,T,F} {
+ \tl_set:Nx \l_testa_tl { \exp_not:n {#1} }
+ \tl_set:Nx \l_testb_tl { \exp_not:V #2 }
+ \if_meaning:w \l_testa_tl \l_testb_tl
+ \prg_return_true: \else: \prg_return_false:
+ \fi:
+ }
+ \prg_set_protected_conditional:Npnn \tl_if_eq:no #1#2 {TF,T,F} {
+ \tl_set:Nx \l_testa_tl {\exp_not:n{#1}}
+ \tl_set:Nx \l_testb_tl {\exp_not:o{#2}}
+ \if_meaning:w\l_testa_tl \l_testb_tl
+ \prg_return_true: \else: \prg_return_false:
+ \fi:
+ }
+ \prg_set_protected_conditional:Npnn \tl_if_eq:nx #1#2 {TF,T,F} {
+ \tl_set:Nx \l_testa_tl {\exp_not:n{#1}}
+ \tl_set:Nx \l_testb_tl {#2}
+ \if_meaning:w\l_testa_tl \l_testb_tl
+ \prg_return_true: \else: \prg_return_false:
+ \fi:
+ }
+ \prg_set_protected_conditional:Npnn \tl_if_eq:Vn #1#2 {TF,T,F} {
+ \tl_set:Nx \l_testa_tl { \exp_not:V #1 }
+ \tl_set:Nx \l_testb_tl { \exp_not:n{#2} }
+ \if_meaning:w \l_testa_tl \l_testb_tl
+ \prg_return_true: \else: \prg_return_false:
+ \fi:
+ }
+ \prg_set_protected_conditional:Npnn \tl_if_eq:on #1#2 {TF,T,F} {
+ \tl_set:Nx \l_testa_tl {\exp_not:o{#1}}
+ \tl_set:Nx \l_testb_tl {\exp_not:n{#2}}
+ \if_meaning:w\l_testa_tl \l_testb_tl
+ \prg_return_true: \else: \prg_return_false:
+ \fi:
+ }
+ \prg_set_protected_conditional:Npnn \tl_if_eq:VV #1#2 {TF,T,F} {
+ \tl_set:Nx \l_testa_tl { \exp_not:V #1 }
+ \tl_set:Nx \l_testb_tl { \exp_not:V #2 }
+ \if_meaning:w \l_testa_tl \l_testb_tl
+ \prg_return_true: \else: \prg_return_false:
+ \fi:
+ }
+ \prg_set_protected_conditional:Npnn \tl_if_eq:oo #1#2 {TF,T,F} {
+ \tl_set:Nx \l_testa_tl {\exp_not:o{#1}}
+ \tl_set:Nx \l_testb_tl {\exp_not:o{#2}}
+ \if_meaning:w\l_testa_tl \l_testb_tl
+ \prg_return_true: \else: \prg_return_false:
+ \fi:
+ }
+ \prg_set_protected_conditional:Npnn \tl_if_eq:Vx #1#2 {TF,T,F} {
+ \tl_set:Nx \l_testa_tl { \exp_not:V #1 }
+ \tl_set:Nx \l_testb_tl {#2}
+ \if_meaning:w \l_testa_tl \l_testb_tl
+ \prg_return_true: \else: \prg_return_false:
+ \fi:
+ }
+ \prg_set_protected_conditional:Npnn \tl_if_eq:ox #1#2 {TF,T,F} {
+ \tl_set:Nx \l_testa_tl {\exp_not:o{#1}}
+ \tl_set:Nx \l_testb_tl {#2}
+ \if_meaning:w\l_testa_tl \l_testb_tl
+ \prg_return_true: \else: \prg_return_false:
+ \fi:
+ }
+ \prg_set_protected_conditional:Npnn \tl_if_eq:xn #1#2 {TF,T,F} {
+ \tl_set:Nx \l_testa_tl {#1}
+ \tl_set:Nx \l_testb_tl {\exp_not:n{#2}}
+ \if_meaning:w\l_testa_tl \l_testb_tl
+ \prg_return_true: \else: \prg_return_false:
+ \fi:
+ }
+ \prg_set_protected_conditional:Npnn \tl_if_eq:xV #1#2 {TF,T,F} {
+ \tl_set:Nx \l_testa_tl {#1}
+ \tl_set:Nx \l_testb_tl { \exp_not:V #2 }
+ \if_meaning:w \l_testa_tl \l_testb_tl
+ \prg_return_true: \else: \prg_return_false:
+ \fi:
+ }
+ \prg_set_protected_conditional:Npnn \tl_if_eq:xo #1#2 {TF,T,F} {
+ \tl_set:Nx \l_testa_tl {#1}
+ \tl_set:Nx \l_testb_tl {\exp_not:o{#2}}
+ \if_meaning:w\l_testa_tl \l_testb_tl
+ \prg_return_true: \else: \prg_return_false:
+ \fi:
+ }
+ \prg_set_protected_conditional:Npnn \tl_if_eq:xx #1#2 {TF,T,F} {
+ \tl_set:Nx \l_testa_tl {#1}
+ \tl_set:Nx \l_testb_tl {#2}
+ \if_meaning:w\l_testa_tl \l_testb_tl
+ \prg_return_true: \else: \prg_return_false:
+ \fi:
+ }
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+%
+% \subsection{Working with the contents of token lists}
+%
+%
+% \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}
+%
+% \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}
+% \begin{macro}{\tl_to_str:c}
+% \begin{macro}[aux]{\tl_to_str_aux:w}
+% These functions return the replacement text of a token list as a
+% string list with all characters catcoded to `other'.
+% \begin{macrocode}
+\cs_new_nopar:Npn \tl_to_str:N {\exp_after:wN\tl_to_str_aux:w
+ \token_to_meaning:N}
+\cs_new_nopar:Npn \tl_to_str_aux:w #1>{}
+\cs_generate_variant:Nn \tl_to_str:N {c}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\tl_map_function:nN}
+% \begin{macro}{\tl_map_function:NN}
+% \begin{macro}{\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 {cN}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+%
+% \begin{macro}{\tl_map_inline:nn}
+% \begin{macro}{\tl_map_inline:Nn}
+% \begin{macro}{\tl_map_inline:cn}
+% \begin{macro}[aux]{\tl_map_inline_aux:n}
+% \begin{macro}{\g_tl_inline_level_num}
+% The inline functions are straight forward by now. We use a little
+% trick with the fake counter |\g_tl_inline_level_num| to make
+% them nestable.\footnote{This should be a proper integer, but I
+% don't want to mess with the dependencies right now\dots} We can
+% also make use of |\tl_map_function:Nn| from before.
+% \begin{macrocode}
+\cs_new:Npn \tl_map_inline:nn #1#2{
+ \num_gincr:N \g_tl_inline_level_num
+ \cs_gset:cpn {tl_map_inline_ \num_use:N \g_tl_inline_level_num :n}
+ ##1{#2}
+ \exp_args:Nc \tl_map_function_aux:Nn
+ {tl_map_inline_ \num_use:N \g_tl_inline_level_num :n}
+ #1 \q_recursion_tail\q_recursion_stop
+ \num_gdecr:N \g_tl_inline_level_num
+}
+\cs_new:Npn \tl_map_inline:Nn #1#2{
+ \num_gincr:N \g_tl_inline_level_num
+ \cs_gset:cpn {tl_map_inline_ \num_use:N \g_tl_inline_level_num :n}
+ ##1{#2}
+ \exp_last_unbraced:NcV \tl_map_function_aux:Nn
+ {tl_map_inline_ \num_use:N \g_tl_inline_level_num :n}
+ #1 \q_recursion_tail\q_recursion_stop
+ \num_gdecr:N \g_tl_inline_level_num
+}
+\cs_generate_variant:Nn \tl_map_inline:Nn {c}
+\tl_new:Nn \g_tl_inline_level_num{0}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+%
+% \begin{macro}{\tl_map_variable:nNn}
+% \begin{macro}{\tl_map_variable:NNn}
+% \begin{macro}{\tl_map_variable:cNn}
+% |\tl_map_variable:nNn| \meta{\tlist} \meta{temp} \meta{action} assigns
+% \meta{temp} to each element and executes \meta{action}.
+% \begin{macrocode}
+\cs_new:Npn \tl_map_variable:nNn #1#2#3{
+ \tl_map_variable_aux:Nnn #2 {#3} #1 \q_recursion_tail \q_recursion_stop
+}
+% \end{macrocode}
+% Next really has to be v/V args
+% \begin{macrocode}
+\cs_new_nopar:Npn \tl_map_variable:NNn {\exp_args:No \tl_map_variable:nNn}
+\cs_generate_variant:Nn \tl_map_variable:NNn {c}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[aux]{\tl_map_variable_aux:NnN}
+% The general loop. Assign the temp variable |#1| to the current item
+% |#3| and then check if that's the stop marker. If it is, break the
+% loop. If not, execute the action |#2| and continue.
+% \begin{macrocode}
+\cs_new: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}
+}
+% \end{macrocode}
+% \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}
+%
+% \begin{macro}{\tl_reverse:n}
+% \begin{macro}{\tl_reverse:V}
+% \begin{macro}{\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}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\tl_reverse:N}
+% 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_nopar:Npn \tl_reverse:N #1 {
+ \tl_set:Nf #1 { \tl_reverse:o { #1 \exp_stop_f: } }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\tl_elt_count:n}
+% \begin{macro}{\tl_elt_count:V}
+% \begin{macro}{\tl_elt_count:o}
+% \begin{macro}{\tl_elt_count:N}
+% Count number of elements within a token list or token list
+% variable. Brace groups within the list are read as a single
+% element.
+% "\num_elt_count: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_elt_count:n #1{
+ \intexpr_eval:n {
+ \tl_map_function:nN {#1}\num_elt_count:n
+ }
+}
+\cs_generate_variant:Nn \tl_elt_count:n {V,o}
+\cs_new_nopar:Npn \tl_elt_count:N #1{
+ \intexpr_eval:n {
+ \tl_map_function:NN #1 \num_elt_count:n
+ }
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\tl_set_rescan:Nnn, \tl_gset_rescan:Nnn}
+% These functions store the \marg{\tlist} in \meta{\tlvar} after
+% redefining catcodes, etc., in argument "#2".
+% \begin{arguments}
+% \item \meta{\tlvar}
+% \item \marg{catcode setup, etc.}
+% \item \marg{\tlist}
+% \end{arguments}
+% \begin{macrocode}
+\cs_new:Npn \tl_set_rescan:Nnn { \tl_set_rescan_aux:NNnn \tl_set:Nn }
+\cs_new:Npn \tl_gset_rescan:Nnn { \tl_set_rescan_aux:NNnn \tl_gset:Nn }
+% \end{macrocode}
+%
+% \begin{macro}[aux]{\tl_set_rescan_aux:NNnn}
+% This macro uses a trick to extract an unexpanded token list after it's
+% rescanned with "\etex_scantokens:D". This technique was first used (as far as I
+% know) by Heiko Oberdiek in his \pkg{catchfile} package, albeit for real
+% files rather than the `fake' "\scantokens" one.
+%
+% The basic problem arises because "\etex_scantokens:D" emulates a file read, which
+% inserts an EOF marker into the expansion; the simplistic\\
+% "\exp_args:NNo \cs_set:Npn \tmp:w { \etex_scantokens:D {some text} }"\\
+% unfortunately doesn't work, calling the error:\\
+% "! File ended while scanning definition of \tmp:w."\\
+% (Lua\TeX\ works around this
+% problem with its "\scantextokens" primitive.)
+%
+% Usually, we'd define "\etex_everyeof:D" to be "\exp_not:N" to gobble the EOF
+% marker, but since we're not expanding the token list, it gets left in there
+% and we have the same basic problem.
+%
+% Instead, we define "\etex_everyeof:D" to contain a marker that's impossible
+% to occur within the scanned text; that is, the same char twice with
+% different catcodes. (For some reason, we \emph{don't} need to insert
+% a "\exp_not:N" token after it to prevent the EOF marker to expand. Anyone
+% know why?)
+%
+% A helper function is can be used to save the token list delimited by the
+% special marker, keeping the catcode redefinitions hidden away in a group.
+%
+% \begin{macro}[aux]{\c_two_ats_with_two_catcodes_tl}
+% A tl with two "@" characters with two different catcodes.
+% Used as a special marker for delimited text.
+% \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:
+\tl_to_lowercase:n {
+ \group_end:
+ \tl_new:Nn \c_two_ats_with_two_catcodes_tl {AB}
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{arguments}
+% \item "\tl_set" function
+% \item \meta{\tlvar}
+% \item \marg{catcode setup, etc.}
+% \item \marg{\tlist}
+% \end{arguments}
+% Note that if you change "\etex_everyeof:D" in "#3"
+% then you'd better do it correctly!
+% \begin{macrocode}
+\cs_new:Npn \tl_set_rescan_aux:NNnn #1#2#3#4 {
+ \group_begin:
+ \toks_set:No \etex_everyeof:D { \c_two_ats_with_two_catcodes_tl }
+ \tex_endlinechar:D = \c_minus_one
+ #3
+ \exp_after:wN \tl_rescan_aux:w \etex_scantokens:D {#4}
+ \exp_args:NNNo
+ \group_end:
+ #1 #2 { \l_tmpa_tl }
+}
+% \end{macrocode}
+%
+% \begin{macro}[aux]{\tl_rescan_aux:w}
+% \begin{macrocode}
+\exp_after:wN \cs_set:Npn
+\exp_after:wN \tl_rescan_aux:w
+\exp_after:wN #
+\exp_after:wN 1 \c_two_ats_with_two_catcodes_tl {
+ \tl_set:Nn \l_tmpa_tl {#1}
+}
+% \end{macrocode}
+%
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\tl_set_rescan:Nnx,\tl_gset_rescan:Nnx}
+% These functions store the full expansion of \marg{\tlist} in
+% \meta{\tlvar} after redefining catcodes, etc., in argument "#2".
+% \begin{arguments}
+% \item \meta{\tlvar}
+% \item \marg{catcode setup, etc.}
+% \item \marg{\tlist}
+% \end{arguments}
+% The expanded versions are much simpler because the "\etex_scantokens:D"
+% can occur within the expansion.
+% \begin{macrocode}
+\cs_new:Npn \tl_set_rescan:Nnx #1#2#3 {
+ \group_begin:
+ \etex_everyeof:D { \exp_not:N }
+ \tex_endlinechar:D = \c_minus_one
+ #2
+ \tl_set:Nx \l_tmpa_tl { \etex_scantokens:D {#3} }
+ \exp_args:NNNo
+ \group_end:
+ \tl_set:Nn #1 { \l_tmpa_tl }
+}
+% \end{macrocode}
+% Globally is easier again:
+% \begin{macrocode}
+\cs_new:Npn \tl_gset_rescan:Nnx #1#2#3 {
+ \group_begin:
+ \etex_everyeof:D { \exp_not:N }
+ \tex_endlinechar:D = \c_minus_one
+ #2
+ \tl_gset:Nx #1 { \etex_scantokens:D {#3} }
+ \group_end:
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\tl_rescan:nn}
+% The inline wrapper for "\etex_scantokens:D".
+% \begin{arguments}
+% \item Catcode changes (etc.)
+% \item Token list to re-tokenise
+% \end{arguments}
+% \begin{macrocode}
+\cs_new:Npn \tl_rescan:nn #1#2 {
+ \group_begin:
+ \etex_everyeof:D { \exp_not:N }
+ \tex_endlinechar:D = \c_minus_one
+ #1
+ \toks_set:Nx \l_tmpa_toks { \etex_scantokens:D {#2} }
+ \exp_args:NV \group_end: \l_tmpa_toks
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Checking for and replacing tokens}
+%
+% \begin{macro}[TF]{\tl_if_in:Nn,\tl_if_in:cn}
+% See the replace functions for further comments. In this part we
+% don't care too much about brace stripping since we are not
+% interested in passing on the tokens which are split off in the
+% process.
+% \begin{macrocode}
+\prg_new_protected_conditional:Npnn \tl_if_in:Nn #1#2 {TF,T,F} {
+ \cs_set:Npn \tl_tmp:w ##1 #2 ##2 \q_stop {
+ \quark_if_no_value:nTF {##2} {\prg_return_false:} {\prg_return_true:}
+ }
+ \exp_after:wN \tl_tmp:w #1 #2 \q_no_value \q_stop
+}
+\cs_generate_variant:Nn \tl_if_in:NnTF {c}
+\cs_generate_variant:Nn \tl_if_in:NnT {c}
+\cs_generate_variant:Nn \tl_if_in:NnF {c}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[TF]{\tl_if_in:nn,\tl_if_in:Vn,\tl_if_in:on}
+% \begin{macrocode}
+\prg_new_protected_conditional:Npnn \tl_if_in:nn #1#2 {TF,T,F} {
+ \cs_set:Npn \tl_tmp:w ##1 #2 ##2 \q_stop {
+ \quark_if_no_value:nTF {##2} {\prg_return_false:} {\prg_return_true:}
+ }
+ \tl_tmp:w #1 #2 \q_no_value \q_stop
+}
+\cs_generate_variant:Nn \tl_if_in:nnTF {V}
+\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 {o}
+\cs_generate_variant:Nn \tl_if_in:nnT {o}
+\cs_generate_variant:Nn \tl_if_in:nnF {o}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\l_tl_replace_toks}
+% A temp variable for the replace operations.
+% \begin{macrocode}
+%%\l_tl_replace_toks % moved to l3token as alloc not set up yet.
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\tl_replace_in:Nnn}
+% \begin{macro}{\tl_replace_in:cnn}
+% \begin{macro}{\tl_greplace_in:Nnn}
+% \begin{macro}{\tl_greplace_in:cnn}
+% Replacing the first item in a token list variable goes like this:
+% Define a temporary function with delimited arguments containing
+% the search term and take a closer look at what is left. We append
+% the expansion of the token list with the search term plus the quark
+% |\q_no_value|. If the search term isn't present this last one is
+% found and the following token is the quark, so we test for
+% that. If the search term is present we will have to split off the
+% |#3\q_no_value| we had, so we define yet another function with
+% delimited arguments to do this. The advantage here is that now we
+% have a special end sequence so there is no problem if the search
+% term appears more than once. Only problem left is to prevent brace
+% stripping in both ends, so we prepend the expansion of the token list
+% with |\prg_do_nothing:| later to be expanded and also prepend the
+% remainder of the first split operation with |\prg_do_nothing:| also to
+% be expanded again later on.
+%
+% \begin{macro}[aux]{\tl_replace_in_aux:NNnn}
+% \begin{arguments}
+% \item "\tl_set:Nx" or "\tl_gset:Nx"
+% \item \meta{\tlvar}
+% \item item to find
+% \item replacement text
+% \end{arguments}
+% \begin{macrocode}
+\cs_new:Npn \tl_replace_in_aux:NNnn #1#2#3#4{
+ \cs_set:Npn \tl_tmp:w ##1#3##2\q_stop{
+ \quark_if_no_value:nF{##2}
+ {
+% \end{macrocode}
+% At this point |##1| starts with a |\prg_do_nothing:| so we expand it to
+% remove it.
+% \begin{macrocode}
+ \toks_set:No\l_tl_replace_toks{##1#4}
+ \cs_set:Npn \tl_tmp:w ####1#3\q_no_value{
+ \toks_put_right:No \l_tl_replace_toks { ####1 }
+ }
+ \tl_tmp:w \prg_do_nothing: ##2
+% \end{macrocode}
+% Now all that is done is setting the token list variable equal to the
+% expansion of the token register.
+% \begin{macrocode}
+ #1#2{\toks_use:N\l_tl_replace_toks}
+ }
+ }
+% \end{macrocode}
+% Here is where we start the process. Note that the token list might start
+% with a space token so we use this little trick with |\use:n|
+% to prevent it from being removed.
+% \begin{macrocode}
+ \use:n{\exp_after:wN \tl_tmp:w\exp_after:wN\prg_do_nothing:}
+ #2#3 \q_no_value\q_stop
+}
+% \end{macrocode}
+% Now the various versions doing the replacement either globally or
+% locally.
+% \begin{macrocode}
+\cs_new_nopar:Npn \tl_replace_in:Nnn {\tl_replace_in_aux:NNnn \tl_set:Nx}
+\cs_generate_variant:Nn\tl_replace_in:Nnn {cnn}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_new_nopar:Npn \tl_greplace_in:Nnn {\tl_replace_in_aux:NNnn \tl_gset:Nx}
+\cs_generate_variant:Nn\tl_greplace_in:Nnn {cnn}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\tl_replace_all_in:Nnn}
+% \begin{macro}{\tl_replace_all_in:cnn}
+% \begin{macro}{\tl_greplace_all_in:Nnn}
+% \begin{macro}{\tl_greplace_all_in:cnn}
+% \begin{macro}[aux]{\tl_replace_all_in_aux:NNnn}
+% The version for replacing \emph{all} occurrences of the search
+% term is fairly easy since we just have to keep doing the
+% replacement on the split-off part until all are
+% replaced. Otherwise it is pretty much the same as above.
+% \begin{macrocode}
+\cs_set:Npn \tl_replace_all_in_aux:NNnn #1#2#3#4{
+ \toks_clear:N \l_tl_replace_toks
+ \cs_set:Npn \tl_tmp:w ##1#3##2\q_stop{
+ \quark_if_no_value:nTF{##2}
+ {
+ \toks_put_right:No \l_tl_replace_toks {##1}
+ }
+ {
+ \toks_put_right:No \l_tl_replace_toks {##1 #4}
+ \tl_tmp:w \prg_do_nothing: ##2 \q_stop
+ }
+ }
+ \use:n{\exp_after:wN \tl_tmp:w \exp_after:wN \prg_do_nothing:}
+ #2#3 \q_no_value\q_stop
+ #1#2{\toks_use:N\l_tl_replace_toks}
+}
+% \end{macrocode}
+% Now the various forms.
+% \begin{macrocode}
+\cs_new_nopar:Npn \tl_replace_all_in:Nnn {
+ \tl_replace_all_in_aux:NNnn \tl_set:Nx}
+\cs_generate_variant:Nn \tl_replace_all_in:Nnn {cnn}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_new_nopar:Npn \tl_greplace_all_in:Nnn {
+ \tl_replace_all_in_aux:NNnn \tl_gset:Nx}
+\cs_generate_variant:Nn \tl_greplace_all_in:Nnn {cnn}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+%
+%
+% \begin{macro}{\tl_remove_in:Nn}
+% \begin{macro}{\tl_remove_in:cn}
+% \begin{macro}{\tl_gremove_in:Nn}
+% \begin{macro}{\tl_gremove_in:cn}
+% Next comes a series of removal functions. I have just implemented
+% them as subcases of the replace functions for now (I'm lazy).
+% \begin{macrocode}
+\cs_new:Npn \tl_remove_in:Nn #1#2{\tl_replace_in:Nnn #1{#2}{}}
+\cs_new:Npn \tl_gremove_in:Nn #1#2{\tl_greplace_in:Nnn #1{#2}{}}
+\cs_generate_variant:Nn \tl_remove_in:Nn {cn}
+\cs_generate_variant:Nn \tl_gremove_in:Nn {cn}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+%
+% \begin{macro}{\tl_remove_all_in:Nn}
+% \begin{macro}{\tl_remove_all_in:cn}
+% \begin{macro}{\tl_gremove_all_in:Nn}
+% \begin{macro}{\tl_gremove_all_in:cn}
+% Same old, same old.
+% \begin{macrocode}
+\cs_new:Npn \tl_remove_all_in:Nn #1#2{
+ \tl_replace_all_in:Nnn #1{#2}{}
+}
+\cs_new:Npn \tl_gremove_all_in:Nn #1#2{
+ \tl_greplace_all_in:Nnn #1{#2}{}
+}
+\cs_generate_variant:Nn \tl_remove_all_in:Nn {cn}
+\cs_generate_variant:Nn \tl_gremove_all_in:Nn {cn}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+%
+% \subsection{Heads or tails?}
+%
+% \begin{macro}{\tl_head:n}
+% \begin{macro}{\tl_head_i:n}
+% \begin{macro}{\tl_tail:n}
+% \begin{macro}{\tl_tail:f}
+% \begin{macro}{\tl_head_iii:n}
+% \begin{macro}{\tl_head_iii:f}
+% \begin{macro}{\tl_head:w}
+% \begin{macro}{\tl_head_i:w}
+% \begin{macro}{\tl_tail:w}
+% \begin{macro}{\tl_head_iii:w}
+% These functions pick up either the head or the tail of a list.
+% "\tl_head_iii:n" returns the first three items on a list.
+% \begin{macrocode}
+\cs_new:Npn \tl_head:n #1{\tl_head:w #1\q_nil}
+\cs_new_eq:NN \tl_head_i:n \tl_head:n
+\cs_new:Npn \tl_tail:n #1{\tl_tail:w #1\q_nil}
+\cs_generate_variant:Nn \tl_tail:n {f}
+\cs_new:Npn \tl_head_iii:n #1{\tl_head_iii:w #1\q_nil}
+\cs_generate_variant:Nn \tl_head_iii:n {f}
+\cs_new_eq:NN \tl_head:w \use_i_delimit_by_q_nil:nw
+\cs_new_eq:NN \tl_head_i:w \tl_head:w
+\cs_new:Npn \tl_tail:w #1#2\q_nil{#2}
+\cs_new:Npn \tl_head_iii:w #1#2#3#4\q_nil{#1#2#3}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\tl_if_head_eq_meaning_p:nN}
+% \begin{macro}[TF]{\tl_if_head_eq_meaning:nN}
+% \begin{macro}{\tl_if_head_eq_charcode_p:nN}
+% \begin{macro}{\tl_if_head_eq_charcode_p:fN}
+% \begin{macro}[TF]{\tl_if_head_eq_charcode:nN}
+% \begin{macro}[TF]{\tl_if_head_eq_charcode:fN}
+% \begin{macro}{\tl_if_head_eq_catcode_p:nN}
+% \begin{macro}[TF]{\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.
+% |\tl_if_head_meaning_eq:nNTF| uses |\if_meaning:w| and will
+% consider the tokens |b|$\sb{11}$ and |b|$\sb{12}$ different.
+% |\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,TF,T,F} {
+ \exp_after:wN \if_meaning:w \tl_head:w #1 \q_nil #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,TF,T,F} {
+ \exp_after:wN \if:w \exp_after:wN \exp_not:N
+ \tl_head:w #1 \q_nil \exp_not:N #2
+ \prg_return_true: \else: \prg_return_false: \fi:
+}
+% \end{macrocode}
+% Actually the default is already an |f| type expansion.
+% \begin{macrocode}
+%% \cs_new:Npn \tl_if_head_eq_charcode_p:fN #1#2{
+%% \exp_after:wN\if_charcode:w \tl_head:w #1\q_nil\exp_not:N#2
+%% \c_true_bool
+%% \else:
+%% \c_false_bool
+%% \fi:
+%% }
+%% \def_long_test_function_new:npn {tl_if_head_eq_charcode:fN}#1#2{
+%% \if_predicate:w \tl_if_head_eq_charcode_p:fN {#1}#2}
+% \end{macrocode}
+% These ":fN" variants are broken; temporary patch:
+% \begin{macrocode}
+\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,TF,T,F} {
+ \exp_after:wN \if_catcode:w \exp_after:wN \exp_not:N
+ \tl_head:w #1 \q_nil \exp_not:N #2
+ \prg_return_true: \else: \prg_return_false: \fi:
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% Show token usage:
+% \begin{macrocode}
+%<*showmemory>
+\showMemUsage
+%</showmemory>
+% \end{macrocode}
+%
+% \end{implementation}
+% \PrintIndex
+%
+% \endinput
diff --git a/Master/texmf-dist/source/latex/expl3/l3tlp.dtx b/Master/texmf-dist/source/latex/expl3/l3tlp.dtx
deleted file mode 100644
index 2d722a77624..00000000000
--- a/Master/texmf-dist/source/latex/expl3/l3tlp.dtx
+++ /dev/null
@@ -1,2054 +0,0 @@
-% \iffalse
-%% File: l3tlp.dtx Copyright (C) 1990-2008 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/cgi-bin/cvsweb.cgi/
-%%
-%% 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 LaTeX Project Team.
-%%
-%% -----------------------------------------------------------------------
-%
-%<*driver|package>
-\RequirePackage{l3names}
-%</driver|package>
-%\fi
-\GetIdInfo$Id: l3tlp.dtx 767 2008-08-05 19:44:21Z morten $
- {L3 Experimental Token List Pointers}
-%\iffalse
-%<*driver>
-%\fi
-\ProvidesFile{\filename.\filenameext}
- [\filedate\space v\fileversion\space\filedescription]
-%\iffalse
-\documentclass{l3doc}
-\begin{document}
-\DocInput{\filename.\filenameext}
-\end{document}
-%</driver>
-% \fi
-%
-%
-% \title{The \textsf{l3tlp} package\thanks{This file
-% has version number \fileversion, last
-% revised \filedate.}\\
-% Token List Pointers}
-% \author{\Team}
-% \date{\filedate}
-% \maketitle
-%
-%
-%
-% \section {Token list pointers}
-%
-% \LaTeX3 stores token lists in so called `token list pointers'.
-% Variables of this type get the suffix "tlp" and functions of this type
-% have the prefix "tlp". To use a token list pointer you simply call
-% the corresponding variable.
-%
-% Often you find yourself with not a token list pointer but an
-% arbitrary token list which has to undergo certain tests. We will
-% prefix these functions with "tlist". While token list pointers are
-% always single tokens, token lists are always surrounded by
-% braces. Perhaps these token lists should have their own module but
-% for now I decided to put them here because there is quite a bit of
-% overlap with token list pointers.
-%
-% \subsection{Functions}
-%
-% \begin{function}{\tlp_new:N |
-% \tlp_new:c |
-% \tlp_new:Nn |
-% \tlp_new:cn |
-% \tlp_new:Nx }
-% \begin{syntax}
-% "\tlp_new:Nn" <tlp> "{" <initial token list> "}"
-% \end{syntax}
-% Defines <tlp> to be a new variable (or constant) of type token list
-% pointer. <initial token list> is the initial value of <tlp>. This
-% makes it possible to assign values to a constant token list pointer.
-%
-% The form "\tlp_new:N" initializes the token list pointer with an empty value.
-% \end{function}
-%
-% \begin{function}{%
-% \tlp_use:N |
-% \tlp_use:c
-% }
-% \begin{syntax}
-% "\tlp_use:N" <tlp>
-% \end{syntax}
-% Function that inserts the <tlp> into the processing stream. Instead of
-% |\tlp_use:N| simply placing the <tlp> into the input stream is also
-% supported.|\tlp_use:c| will complain is the <tlp> hasn't been declared
-% previously!
-% \end{function}
-%
-% \begin{function}{%
-% \tlp_set:Nn |
-% \tlp_set:Nc |
-% \tlp_set:No |
-% \tlp_set:Nd |
-% \tlp_set:Nf |
-% \tlp_set:Nx |
-% \tlp_gset:Nn |
-% \tlp_gset:Nc |
-% \tlp_gset:No |
-% \tlp_gset:Nd |
-% \tlp_gset:Nx |
-% \tlp_gset:cn |
-% \tlp_gset:cx }
-% \begin{syntax}
-% "\tlp_set:Nn" <tlp> "{" <token list> "}"
-% \end{syntax}
-% Defines <tlp> to hold the token list <token list>. Global
-% variants of this command assign the value globally the other variants
-% expand the <token list> up to a certain level before the assignment
-% or interpret the <token list> as a character list and form a control
-% sequence out of it.
-% \end{function}
-%
-% \begin{function}{%
-% \tlp_clear:N |
-% \tlp_clear:c |
-% \tlp_gclear:N |
-% \tlp_gclear:c
-% }
-% \begin{syntax}
-% "\tlp_clear:N" <tlp>
-% \end{syntax}
-% The <tlp> is locally or globally cleared. The "c" variants will
-% generate a control sequence name which is then interpreted as
-% <tlp> before clearing.
-% \end{function}
-%
-% \begin{function}{%
-% \tlp_clear_new:N |
-% \tlp_clear_new:c |
-% \tlp_gclear_new:N |
-% \tlp_gclear_new:c |
-% }
-% \begin{syntax}
-% "\tlp_clear_new:N" <tlp>
-% \end{syntax}
-% These functions check if <tlp> exists. If it does it will be cleared;
-% if it doesn't it will be allocated.
-% \end{function}
-%
-% \begin{function}{%
-% \tlp_put_left:Nn |
-% \tlp_put_left:No |
-% \tlp_put_left:Nx |
-% \tlp_gput_left:Nn |
-% \tlp_gput_left:No |
-% \tlp_gput_left:Nx |
-% \tlp_put_right:Nn |
-% \tlp_put_right:No |
-% \tlp_put_right:Nx |
-% \tlp_put_right:cc |
-% \tlp_gput_right:Nn |
-% \tlp_gput_right:No|
-% \tlp_gput_right:Nx|
-% \tlp_gput_right:cn|
-% \tlp_gput_right:co|
-% }
-% \begin{syntax}
-% "\tlp_put_left:Nn" <tlp> "{" <token list> "}"
-% \end{syntax}
-% These functions will append <token list> to the left or right of
-% <tlp>. Assignment is done either locally or globally and <token
-% list> might be subject to expansion before assignment.
-% \end{function}
-%
-% A word of warning is appropriate here: Token list pointers are
-% implemented as macros and as such currently inherit some of the
-% peculiarities of how \TeX\ handles "#"s in the argument of
-% macros. In particular, the following actions are legal
-% \begin{verbatim}
-% \tlp_set:Nn \l_tmpa_tlp{##1}
-% \tlp_put_right:Nn \l_tmpa_tlp{##2}
-% \tlp_set:No \l_tmpb_tlp{\l_tmpa_tlp ##3}
-% \end{verbatim}
-% |x| type expansions where macros being expanded contain |#|s do not
-% work and will not work until there is an |\expanded| primitive in
-% the engine. If you want them to work you must double |#|s another
-% level.
-%
-%
-% \begin{function}{%
-% \tlp_set_eq:NN |
-% \tlp_set_eq:Nc |
-% \tlp_set_eq:cN |
-% \tlp_set_eq:cc |
-% \tlp_gset_eq:NN |
-% \tlp_gset_eq:Nc |
-% \tlp_gset_eq:cN |
-% \tlp_gset_eq:cc |
-% }
-% \begin{syntax}
-% "\tlp_set_eq:NN" <tlp1> <tlp2>
-% \end{syntax}
-% Fast form for
-% \begin{syntax}
-% "\tlp_set:No" <tlp1> "{" <tlp2> "}"
-% \end{syntax}
-% when <tlp2> is known to be a variable of type token list pointer.
-% \end{function}
-%
-% \begin{function}{\tlp_to_str:N |
-% \tlp_to_str:c
-% }
-% \begin{syntax}
-% "\tlp_to_str:N" <tlp>
-% \end{syntax}
-% This function returns the token list kept in <tlp> as a string list
-% with all characters catcoded to `other'.
-% \end{function}
-%
-% \subsection{Predicates and conditionals}
-%
-% \begin{function}{\tlp_if_empty_p:N|
-% \tlp_if_empty_p:c
-% }
-% \begin{syntax}
-% "\tlp_if_empty_p:N" <tlp>
-% \end{syntax}
-% This predicate returns `true' if <tlp> is `empty' i.e., doesn't
-% contain any tokens.
-% \end{function}
-%
-% \begin{function}{\tlp_if_empty:NTF|
-% \tlp_if_empty:NT|
-% \tlp_if_empty:NF|
-% \tlp_if_empty:cTF |
-% \tlp_if_empty:cT |
-% \tlp_if_empty:cF
-% }
-% \begin{syntax}
-% "\tlp_if_empty:NTF" <tlp> "{"<true code>"}""{"<false code>"}"
-% \end{syntax}
-% Execute <true code> if <tlp> is empty and <false code> if it
-% contains any tokens.
-% \end{function}
-%
-% \begin{function}{\tlp_if_eq_p:NN |
-% \tlp_if_eq_p:cN |
-% \tlp_if_eq_p:Nc |
-% \tlp_if_eq_p:cc |
-% }
-% \begin{syntax}
-% "\tlp_if_eq_p:NN" <tlp1> <tlp2>
-% \end{syntax}
-% Predicate function which returns `true' if the two token list
-% pointers are identical and `false' otherwise.
-% \end{function}
-%
-% \begin{function}{
-% \tlp_if_eq:NNTF |
-% \tlp_if_eq:NNT |
-% \tlp_if_eq:NNF |
-% \tlp_if_eq:cNTF |
-% \tlp_if_eq:cNT |
-% \tlp_if_eq:cNF |
-% \tlp_if_eq:NcTF |
-% \tlp_if_eq:NcT |
-% \tlp_if_eq:NcF |
-% \tlp_if_eq:ccTF |
-% \tlp_if_eq:ccT |
-% \tlp_if_eq:ccF |
-% }
-% \begin{syntax}
-% "\tlp_if_eq:NNTF" <tlp1> <tlp2> "{"<true code>"}""{"<false code>"}"
-% \end{syntax}
-% Execute <true code> if <tlp1> holds the same token list as <tlp2>
-% and <false code> otherwise.
-% \end{function}
-%
-%
-% \subsection{Token lists}
-%
-% \begin{function}{\tlist_if_eq:nnTF |
-% \tlist_if_eq:nnT |
-% \tlist_if_eq:nnF |
-% \tlist_if_eq:noTF |
-% \tlist_if_eq:noT |
-% \tlist_if_eq:noF |
-% }
-% \begin{syntax}
-% "\tlist_if_eq:nnTF" "{"<tlist1>"}" "{"<tlist2>"}" "{"<true
-% code>"}" "{"<false code>"}"
-% \end{syntax}
-% Execute <true code> if the two token lists <tlist1> and <tlist2> are
-% identical.
-% \end{function}
-%
-%
-% \begin{function}{\tlist_if_empty_p:n |
-% \tlist_if_empty_p:o |
-% \tlist_if_empty:nTF |
-% \tlist_if_empty:nT |
-% \tlist_if_empty:nF |
-% \tlist_if_empty:oTF |
-% \tlist_if_empty:oT |
-% \tlist_if_empty:oF |
-% }
-% \begin{syntax}
-% "\tlist_if_empty:nTF" "{"<tlist>"}" "{"<true code>"}" "{"<false code>"}"
-% \end{syntax}
-% Execute <true code> if <tlist> doesn't contain any tokens and <false
-% code> otherwise.
-% \end{function}
-%
-% \begin{function}{\tlist_if_blank_p:n |
-% \tlist_if_blank:nTF |
-% \tlist_if_blank:nT |
-% \tlist_if_blank:nF |
-% \tlist_if_blank_p:o |
-% \tlist_if_blank:oTF |
-% \tlist_if_blank:oT |
-% \tlist_if_blank:oF |
-% }
-% \begin{syntax}
-% "\tlist_if_blank:nTF" "{"<tlist>"}" "{"<true code>"}" "{"<false code>"}"
-% \end{syntax}
-% Execute <true code> if <tlist> is blank meaning that it is either
-% empty or contains only blank spaces.
-% \end{function}
-%
-% \begin{function}{\tlist_to_lowercase:n |
-% \tlist_to_uppercase:n
-% }
-% \begin{syntax}
-% "\tlist_to_lowercase:n" "{"<tlist>"}"
-% \end{syntax}
-% "\tlist_to_lowercase:n" converts all tokens in <tlist> to their
-% lower case representation. Similar for "\tlist_to_uppercase:n".
-% \begin{texnote}
-% These are the \TeX\ primitives \tn{lowercase} and \tn{uppercase}
-% renamed.
-% \end{texnote}
-% \end{function}
-%
-% \begin{function}{\tlist_to_str:n
-% }
-% \begin{syntax}
-% "\tlist_to_str:n" "{"<tlist>"}"
-% \end{syntax}
-% This function turns its argument into a string where all characters
-% have catcode `other'.
-% \begin{texnote}
-% This is the \eTeX\ primitive \tn{detokenize}.
-% \end{texnote}
-% \end{function}
-%
-% \begin{function}{%
-% \tlist_map_function:nN |
-% \tlp_map_function:NN |
-% \tlp_map_function:cN |
-% }
-% \begin{syntax}
-% "\tlist_map_function:nN" "{"<tlist>"}" <function> \\
-% "\tlp_map_function:NN" <tlp> <function>
-% \end{syntax}
-% Runs through all elements in a |tlist| from left to right and places
-% <function> in front of each element. As this function will also pick
-% up elements in brace groups, the element is returned with braces and
-% hence <function> should be a function with a |:n| suffix even though
-% it may very well only deal with a single token. This function uses a
-% purely expandable loop function and will stay so as long as
-% <function> is expandable too.
-% \end{function}
-%
-% \begin{function}{%
-% \tlist_map_inline:nn |
-% \tlp_map_inline:Nn |
-% \tlp_map_inline:cn |
-% }
-% \begin{syntax}
-% "\tlist_map_inline:nn" "{"<tlist>"}" "{"<inline~function>"}" \\
-% "\tlp_map_inline:Nn" <tlp> "{"<inline~function>"}"
-% \end{syntax}
-% Allows a syntax like "\tlist_map_inline:nn" "{"<tlist>"}"
-% "{\token_to_string:N ##1}". This renders it non-expandable though.
-% Remember to double the "#"s for each level.
-% \end{function}
-%
-%
-% \begin{function}{%
-% \tlist_map_variable:nNn |
-% \tlp_map_variable:NNn |
-% \tlp_map_variable:cNn |
-% }
-% \begin{syntax}
-% "\tlist_map_variable:nNn" "{"<tlist>"}" <temp> "{"<action>"}" \\
-% "\tlp_map_variable:NNn" <tlp> <temp> "{"<action>"}"
-% \end{syntax}
-% Assigns <temp> to each element on <tlist> and executes <action>.
-% As there is an assignment in this process it is not expandable.
-% \begin{texnote}
-% This is the \LaTeX2{} function \tn{@tfor} but with a more sane syntax.
-% Also it works by tail recursion and so is faster as lists grow longer.
-% \end{texnote}
-% \end{function}
-%
-% \begin{function}{%
-% \tlist_map_break:w |
-% \tlp_map_break:w |
-% }
-% \begin{syntax}
-% "\tlist_map_break:w"
-% \end{syntax}
-% For breaking out of a loop. You should take note of the ":w" as
-% its usage must be precise!
-% \end{function}
-%
-%
-% \begin{function}{%
-% \tlist_reverse:n |
-% }
-% \begin{syntax}
-% "\tlist_reverse:n" "{"<token$\sb1$><token$\sb2$>...<token$\sb n$>"}"
-% \end{syntax}
-% Reverse the token list to result in
-% <token$\sb n$>\dots<token$\sb2$><token$\sb1$>. Note that spaces in this
-% token list are gobbled in the process.
-% \end{function}
-%
-% \begin{function}{%
-% \tlist_elt_count:n |
-% \tlist_elt_count:o |
-% \tlp_elt_count:N |
-% }
-% \begin{syntax}
-% "\tlist_elt_count:n" "{"<token list>"}" \\
-% "\tlp_elt_count:N" <tlp>
-% \end{syntax}
-% Returns the number of elements in the token list. Brace groups
-% encountered count as one element. Note that spaces in this
-% token list are gobbled in the process.
-% \end{function}
-%
-%
-% \subsubsection{Internal functions}
-%
-%
-% \begin{function}{%
-% \tlist_map_function_aux:Nn |
-% \tlist_map_inline_aux:Nn |
-% \tlist_map_variable_aux:Nnn |
-% }
-% \begin{syntax}\end{syntax}
-% Internal helper functions for the <tlist> loops.
-% \end{function}
-%
-%
-%
-% \begin{function}{\tlist_if_blank_p_aux:w
-% }
-% \end{function}
-%
-%
-%
-% \subsection{Variables and constants}
-%
-% \begin{variable}{\C_job_name_tlp}
-% Constant that gets the `job name' assigned when \TeX{} starts.
-% \begin{texnote}
-% This is the new name for the primitive \tn{jobname}. It is a constant
-% that will be set by \TeX{} and can not be overwritten by the package.
-% Therefore the "C"
-% \end{texnote}
-% \end{variable}
-%
-% \begin{variable}{\c_empty_tlp}
-% Constant that is always empty.
-% \begin{texnote}
-% This was named \tn{@empty} in \LaTeX2 and \tn{empty} in plain \TeX{}.
-% \end{texnote}
-% \end{variable}
-%
-% \begin{variable}{\c_relax_tlp}
-% Constant holding the token that is assigned to a newly created control
-% sequence by \TeX.
-% \end{variable}
-%
-% \begin{variable}{%
-% \l_tmpa_tlp |
-% \l_tmpb_tlp |
-% \g_tmpa_tlp |
-% \g_tmpb_tlp
-% }
-% Scratch register for immediate use. They are not used by conditionals
-% or predicate functions.
-% \end{variable}
-%
-%
-% \subsubsection{Internal functions}
-%
-% \begin{variable}{%
-% \l_replace_tlp |
-% }
-% Internal register used in the replace functions.
-% \end{variable}
-%
-% \begin{variable}{%
-% \l_testa_tlp |
-% \l_testb_tlp |
-% \g_testa_tlp |
-% \g_testb_tlp |
-% }
-% Registers used for conditional processing if the engine doesn't
-% support arbitrary string comparison.
-% \end{variable}
-%
-%
-% \begin{function}{\tlp_to_str_aux:w}
-% Function used to implement "\tlp_to_str:N".
-% \end{function}
-%
-%
-% \subsection{Search and replace}
-%
-%
-% \begin{function}{
-% \tlp_if_in:NnTF |
-% \tlp_if_in:cnTF |
-% \tlp_if_in:NnT |
-% \tlp_if_in:cnT |
-% \tlp_if_in:NnF |
-% \tlp_if_in:cnF |
-% \tlist_if_in:nnTF |
-% \tlist_if_in:onTF |
-% }
-% \begin{syntax}
-% "\tlp_if_in:NnTF" <tlp> "{" <item> "}{" <true code> "}{"
-% <false code> "}"
-% \end{syntax}
-% Function that tests if <item> is in <tlp>. Depending on the result
-% either <true code> or <false code> is executed. Note that <item>
-% cannot contain brace groups.
-% \end{function}
-%
-% \begin{function}{
-% \tlp_replace_in:Nnn |
-% \tlp_replace_in:cnn |
-% \tlp_greplace_in:Nnn |
-% \tlp_greplace_in:cnn |
-% }
-% \begin{syntax}
-% "\tlp_replace_in:Nnn" <tlp> "{" <item1> "}{" <item2> "}"
-% \end{syntax}
-% Replaces the leftmost occurrence of <item1> in <tlp> with
-% <item2> if present, otherwise the <tlp> is left untouched.
-% \end{function}
-%
-% \begin{function}{
-% \tlp_replace_all_in:Nnn |
-% \tlp_replace_all_in:cnn |
-% \tlp_greplace_all_in:Nnn |
-% \tlp_greplace_all_in:cnn |
-% }
-% \begin{syntax}
-% "\tlp_replace_all_in:Nnn" <tlp> "{" <item1> "}{" <item2> "}"
-% \end{syntax}
-% Replaces \emph{all} occurrences of <item1> in <tlp> with
-% <item2>.
-% \end{function}
-%
-%
-% \begin{function}{
-% \tlp_remove_in:Nn |
-% \tlp_remove_in:cn |
-% \tlp_gremove_in:Nn |
-% \tlp_gremove_in:cn |
-% }
-% \begin{syntax}
-% "\tlp_remove_in:Nn" <tlp> "{" <item> "}"
-% \end{syntax}
-% Removes the leftmost occurrence of <item> from <tlp> if present.
-% \end{function}
-%
-%
-% \begin{function}{
-% \tlp_remove_all_in:Nn |
-% \tlp_remove_all_in:cn |
-% \tlp_gremove_all_in:Nn |
-% \tlp_gremove_all_in:cn |
-% }
-% \begin{syntax}
-% "\tlp_remove_all_in:Nn" <tlp> "{" <item> "}"
-% \end{syntax}
-% Removes \emph{all} occurrences of <item> from <tlp>.
-% \end{function}
-%
-%
-% \subsection{Heads or tails?}
-%
-% Here are some functions for grabbing either the head or tail of a
-% list and perform some tests on it.
-%
-% \begin{function}{%
-% \tlist_head:n |
-% \tlist_tail:n |
-% \tlist_head_iii:n |
-% \tlist_head_iii:f |
-% \tlist_head:w |
-% \tlist_tail:w |
-% \tlist_head_iii:w
-% }
-% \begin{syntax}
-% "\tlist_head:n" "{" <token1><token2>...<token-n> "}" \\
-% "\tlist_tail:n" "{" <token1><token2>...<token-n> "}"
-% \end{syntax}
-% These functions return either the head or the tail of a list, thus in
-% the above example "\tlist_head:n" would return <token1> and "\tlist_tail:n"
-% would return <token2>\dots<token-n>. "\tlist_head_iii:n" returns the first
-% three tokens. The ":w" versions require some care as they use a
-% delimited argument internally.
-% \begin{texnote}
-% These are the Lisp functions "car" and "cdr" but with \LaTeX3 names.
-% \end{texnote}
-% \end{function}
-%
-%
-%
-%
-% \begin{function}{%
-% \tlist_if_head_eq_meaning_p:nN |
-% \tlist_if_head_eq_meaning:nNTF |
-% \tlist_if_head_eq_meaning:nNTF |
-% \tlist_if_head_eq_meaning:nNTF |
-% }
-% \begin{syntax}
-% "\tlist_if_head_eq_meaning:nNTF" "{" <token list> "}" <token>
-% "{"<true>"}""{"<false>"}"
-% \end{syntax}
-% Returns <true> if the first token in <token list> is equal to
-% <token> and <false> otherwise. The |meaning| version compares the
-% two tokens with |\if_meaning:NN|.
-% \end{function}
-%
-% \begin{function}{%
-% \tlist_if_head_eq_charcode_p:nN |
-% \tlist_if_head_eq_charcode:nNTF |
-% \tlist_if_head_eq_charcode:nNTF |
-% \tlist_if_head_eq_charcode:nNTF |
-% }
-% \begin{syntax}
-% "\tlist_if_head_eq_charcode:nNTF" "{" <token list> "}" <token>
-% "{"<true>"}""{"<false>"}"
-% \end{syntax}
-% Returns <true> if the first token in <token list> is equal to
-% <token> and <false> otherwise. The |meaning| version compares the
-% two tokens with |\if_charcode:w| but it prevents expansion of
-% them. If you want them to expand, you can use an |f| type expansion
-% first (define |\tlist_if_head_eq_charcode:fNTF| or similar).
-% \end{function}
-%
-% \begin{function}{%
-% \tlist_if_head_eq_catcode_p:nN |
-% \tlist_if_head_eq_catcode:nNTF |
-% \tlist_if_head_eq_catcode:nNTF |
-% \tlist_if_head_eq_catcode:nNTF |
-% }
-% \begin{syntax}
-% "\tlist_if_head_eq_catcode:nNTF" "{" <token list> "}" <token>
-% "{"<true>"}""{"<false>"}"
-% \end{syntax}
-% Returns <true> if the first token in <token list> is equal to
-% <token> and <false> otherwise. This version uses |\if_catcode:w| for
-% the test but is otherwise identical to the |charcode| version.
-% \end{function}
-%
-%
-% \StopEventually{}
-%
-% \subsection{The Implementation}
-%
-% We start by ensuring that the required packages are loaded.
-% \begin{macrocode}
-%<package>\ProvidesExplPackage
-%<package> {\filename}{\filedate}{\fileversion}{\filedescription}
-%<package&!check>\RequirePackage{l3basics}
-%<package&check>\RequirePackage{l3chk}
-% \end{macrocode}
-% \begin{macrocode}
-%<*initex|package>
-% \end{macrocode}
-%
-% A token list pointer is a control sequence that holds tokens. The
-% interface is similar to that for token registers, but beware that
-% the behavior vis \'a vis |\def:Npx| etc. \ldots{} is different. (You
-% see this comes from Denys' implementation.)
-%
-%
-%
-% \begin{macro}{\tlp_new:N}
-% \begin{macro}{\tlp_new:c}
-% \begin{macro}{\tlp_new:Nn}
-% \begin{macro}{\tlp_new:cn}
-% \begin{macro}{\tlp_new:Nx}
-% We provide one allocation function (which checks that the name is
-% not used) and two clear functions that locally or globally clear
-% the token list. The allocation function has two arguments to
-% specify an initial value. This is the only way to give values to
-% constants.
-% \begin{macrocode}
-\def_long_new:Npn \tlp_new:Nn #1#2{
- \chk_new_cs:N #1
-% \end{macrocode}
-% If checking we don't allow constants to be defined.
-% \begin{macrocode}
-%<*check>
- \chk_var_or_const:N #1
-%</check>
-% \end{macrocode}
-% Otherwise any variable type is allowed.
-% \begin{macrocode}
- \gdef:Npn #1{#2}
-}
-\def_new:Npn \tlp_new:cn {\exp_args:Nc \tlp_new:Nn }
-\def_long_new:Npn \tlp_new:Nx #1#2{
- \chk_new_cs:N #1
-%<check> \chk_var_or_const:N #1
- \gdef:Npx #1{#2}
-}
-\def_new:Npn \tlp_new:N #1{\tlp_new:Nn #1{}}
-\def_new:Npn \tlp_new:c #1{\tlp_new:cn {#1}{}}
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-%
-% \begin{macro}{\tlp_use:N}
-% \begin{macro}{\tlp_use:c}
-% Perhaps this should just be enabled when checking?
-% \begin{macrocode}
-\def_new:Npn \tlp_use:N #1 {
- \if_meaning:NN #1 \scan_stop:
-% \end{macrocode}
-% If \m{tlp} equals |\scan_stop:| it is probably stemming from a
-% |\cs:w ... \cd_end:| that was created by mistake somewhere.
-% \begin{macrocode}
- \err_latex_bug:x {Token~list~pointer~ `\token_to_string:N #1'~
- has~ an~ erroneous~ structure!}
- \else:
- \exp_after:NN #1
- \fi:
-}
-\def_new:Npn \tlp_use:c {\exp_args:Nc \tlp_use:N}
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-%
-% \begin{macro}{\tlp_set:Nn}
-% \begin{macro}{\tlp_set:No}
-% \begin{macro}{\tlp_set:Nd}
-% \begin{macro}{\tlp_set:Nf}
-% \begin{macro}{\tlp_set:Nx}
-% \begin{macro}{\tlp_set:cn}
-% \begin{macro}{\tlp_set:co}
-% \begin{macro}{\tlp_set:cx}
-% \begin{macro}{\tlp_gset:Nn}
-% \begin{macro}{\tlp_gset:No}
-% \begin{macro}{\tlp_gset:Nd}
-% \begin{macro}{\tlp_gset:Nx}
-% \begin{macro}{\tlp_gset:cn}
-% \begin{macro}{\tlp_gset:cx}
-% To set token lists to a specific value to type of functions are
-% available: |\tlp_set_eq:NN| takes two token-lists as its
-% arguments assign the first the contents of the second;
-% |\tlp_set:Nn| has as its second argument a `real' list of tokens.
-% One can view |\tlp_set_eq:NN| as a special form of |\tlp_set:No|.
-% Both functions have global counterparts.
-%
-% During development we check if the token list that is being
-% assigned to exists. If not, a warning will be issued.
-% \begin{macrocode}
-%<*check>
-\def_long_new:Npn \tlp_set:Nn #1#2{
- \chk_exist_cs:N #1 \def:Npn #1{#2}
-% \end{macrocode}
-% We use |\chk_local_or_pref_global:N| after the assignment to
-% allow constructs with |\pref_global_chk:|. But one should note
-% that this is less efficient then using the real global variant
-% since they are built-in.
-% \begin{macrocode}
- \chk_local_or_pref_global:N #1
-}
-\def_long_new:Npn \tlp_set:Nx #1#2{
- \chk_exist_cs:N #1 \def:Npx #1{#2} \chk_local:N #1
-}
-% \end{macrocode}
-% The the global versions.
-% \begin{macrocode}
-\def_long_new:Npn \tlp_gset:Nn #1#2{
- \chk_exist_cs:N #1 \gdef:Npn #1{#2} \chk_global:N #1
-}
-\def_long_new:Npn \tlp_gset:Nx #1#2{
- \chk_exist_cs:N #1 \gdef:Npx #1{#2} \chk_global:N #1
-}
-%</check>
-% \end{macrocode}
-% For some functions like |\tlp_set:Nn| we need to define the
-% `non-check' version with arguments since we want to allow
-% constructions like |\tlp_set:Nn\l_tmpa_tlp\foo| and so we can't
-% use the primitive \TeX{} command.
-% \begin{macrocode}
-%<*!check>
-\def_long_new:Npn\tlp_set:Nn#1#2{\def:Npn#1{#2}}
-\def_long_new:Npn\tlp_set:Nx#1#2{\def:Npx#1{#2}}
-\def_long_new:Npn\tlp_gset:Nn#1#2{\gdef:Npn#1{#2}}
-\def_long_new:Npn\tlp_gset:Nx#1#2{\gdef:Npx#1{#2}}
-%</!check>
-% \end{macrocode}
-% The remaining functions can just be defined with help from the
-% expansion module.
-% \begin{macrocode}
-\def_new:Npn \tlp_set:No {\exp_args:NNo \tlp_set:Nn}
-\def_new:Npn \tlp_set:Nd {\exp_args:NNd \tlp_set:Nn}
-\def_new:Npn \tlp_set:Nf {\exp_args:NNf \tlp_set:Nn}
-\def_new:Npn \tlp_set:cn {\exp_args:Nc \tlp_set:Nn}
-\def_new:Npn \tlp_set:co {\exp_args:Nco \tlp_set:Nn}
-\def_new:Npn \tlp_set:cx {\exp_args:Nc \tlp_set:Nx}
-\def_new:Npn \tlp_gset:No {\exp_args:NNo \tlp_gset:Nn}
-\def_new:Npn \tlp_gset:Nd {\exp_args:NNd \tlp_gset:Nn}
-\def_new:Npn \tlp_gset:cn {\exp_args:Nc \tlp_gset:Nn}
-\def_new:Npn \tlp_gset:cx {\exp_args:Nc \tlp_gset:Nx}
-% \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}{\tlp_set_eq:NN}
-% \begin{macro}{\tlp_set_eq:Nc}
-% \begin{macro}{\tlp_set_eq:cN}
-% \begin{macro}{\tlp_set_eq:cc}
-% \begin{macro}{\tlp_gset_eq:NN}
-% \begin{macro}{\tlp_gset_eq:Nc}
-% \begin{macro}{\tlp_gset_eq:cN}
-% \begin{macro}{\tlp_gset_eq:cc}
-% For setting token list pointers equal to each other. First checking:
-% \begin{macrocode}
-%<*check>
-\def_new:Npn \tlp_set_eq:NN #1#2{
- \chk_exist_cs:N #1 \let:NN #1#2
- \chk_local_or_pref_global:N #1 \chk_var_or_const:N #2
-}
-\def_new:Npn \tlp_gset_eq:NN #1#2{
- \chk_exist_cs:N #1 \glet:NN #1#2
- \chk_global:N #1 \chk_var_or_const:N #2
-}
-%</check>
-% \end{macrocode}
-% Non-checking versions are easy.
-% \begin{macrocode}
-%<*!check>
-\let_new:NN \tlp_set_eq:NN \let:NN
-\let_new:NN \tlp_gset_eq:NN \glet:NN
-%</!check>
-% \end{macrocode}
-% The rest again with the expansion module.
-% \begin{macrocode}
-\def_new:Npn \tlp_set_eq:Nc {\exp_args:NNc \tlp_set_eq:NN}
-\def_new:Npn \tlp_set_eq:cN {\exp_args:Nc \tlp_set_eq:NN}
-\def_new:Npn \tlp_set_eq:cc {\exp_args:Ncc \tlp_set_eq:NN}
-\def_new:Npn \tlp_gset_eq:Nc {\exp_args:NNc \tlp_gset_eq:NN}
-\def_new:Npn \tlp_gset_eq:cN {\exp_args:Nc \tlp_gset_eq:NN}
-\def_new:Npn \tlp_gset_eq:cc {\exp_args:Ncc \tlp_gset_eq:NN}
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-%
-%
-% \begin{macro}{\tlp_clear:N}
-% \begin{macro}{\tlp_clear:c}
-% \begin{macro}{\tlp_gclear:N}
-% \begin{macro}{\tlp_gclear:c}
-% Clearing a token list pointer.
-% \begin{macrocode}
-\def_new:Npn \tlp_clear:N #1{\tlp_set_eq:NN #1\c_empty_tlp}
-\def_new:Npn \tlp_clear:c {\exp_args:Nc \tlp_clear:N}
-\def_new:Npn \tlp_gclear:N #1{\tlp_gset_eq:NN #1\c_empty_tlp}
-\def_new:Npn \tlp_gclear:c {\exp_args:Nc \tlp_gclear:N}
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\tlp_clear_new:N}
-% \begin{macro}{\tlp_clear_new:c}
-% These macros check whether a token list exists. If it does it
-% is cleared, if it doesn't it is allocated.
-% \begin{macrocode}
-%<*check>
-\def_new:Npn \tlp_clear_new:N #1{
- \chk_var_or_const:N #1
- \if:w \cs_exist_p:N #1
- \tlp_clear:N #1
- \else:
- \tlp_new:Nn #1{}
- \fi:
-}
-%</check>
-%<-check>\let_new:NN \tlp_clear_new:N \tlp_clear:N
-\def_new:Npn \tlp_clear_new:c {\exp_args:Nc \tlp_clear_new:N}
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\tlp_gclear_new:N}
-% \begin{macro}{\tlp_gclear_new:c}
-% These are the global versions of the above.
-% \begin{macrocode}
-%<*check>
-\def_new:Npn \tlp_gclear_new:N #1{
- \chk_var_or_const:N #1
- \if:w \cs_exist_p:N #1
- \tlp_gclear:N #1
- \else:
- \tlp_new:Nn #1{}
- \fi:}
-%</check>
-%<-check>\let_new:NN \tlp_gclear_new:N \tlp_gclear:N
-\def_new:Npn \tlp_gclear_new:c {\exp_args:Nc \tlp_gclear_new:N}
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\tlp_put_left:Nn}
-% \begin{macro}{\tlp_put_left:No}
-% \begin{macro}{\tlp_put_left:Nx}
-% \begin{macro}{\tlp_gput_left:Nn}
-% \begin{macro}{\tlp_gput_left:No}
-% \begin{macro}{\tlp_gput_left:Nx}
-% We can add tokens to the left (either globally or locally). It is
-% not quite as easy as we would like because we have to ensure the
-% assignments
-% \begin{verbatim}
-% \tlp_set:Nn \l_tmpa_tlp{##1abc##2def}
-% \tlp_set:Nn \l_tmpb_tlp{##1abc}
-% \tlp_put_right:Nn \l_tmpb_tlp {##2def}
-% \end{verbatim}
-% cause |\l_tmpa_tlp| and |\l_tmpb_tlp| to be identical. The old
-% code did not succeed in doing this (it gave an error) and so we
-% use a different technique where the item(s) to be added are first
-% stored in a temporary pointer and then added using an |x| type
-% expansion combined with the appropriate level of
-% non-expansion. Putting the tokens directly into one assignment
-% does not work unless we want full expansion. Note (according to
-% the warning earlier) \TeX\ does not allow us to treat |#|s the
-% same in all cases. Tough.
-% \begin{macrocode}
-\def_long_new:Npn \tlp_put_left:Nn #1#2{
- \tlp_set:Nn \l_exp_tlp{#2}
- \tlp_set:Nx #1{\exp_not:o{\l_exp_tlp}\exp_not:o{#1}}
-%<check> \chk_local_or_pref_global:N #1
-}
-\def_long_new:Npn \tlp_put_left:No #1#2{
- \tlp_set:Nn \l_exp_tlp{#2}
- \tlp_set:Nx #1{\exp_not:d{\l_exp_tlp}\exp_not:o{#1}}
-%<check> \chk_local_or_pref_global:N #1
-}
-\def_long_new:Npn \tlp_put_left:Nx #1#2{
- \tlp_set:Nx #1{#2\exp_not:o{#1}}
-%<check> \chk_local_or_pref_global:N #1
-}
-\def_long_new:Npn \tlp_gput_left:Nn #1#2{
- \tlp_set:Nn \l_exp_tlp{#2}
- \tlp_gset:Nx #1{\exp_not:o{\l_exp_tlp}\exp_not:o{#1}}
-%<check> \chk_local_or_pref_global:N #1
-}
-\def_long_new:Npn \tlp_gput_left:No #1#2{
- \tlp_set:Nn \l_exp_tlp{#2}
- \tlp_gset:Nx #1{\exp_not:d{\l_exp_tlp}\exp_not:o{#1}}
-%<check> \chk_local_or_pref_global:N #1
-}
-\def_long_new:Npn \tlp_gput_left:Nx #1#2{
- \tlp_gset:Nx #1{#2\exp_not:o{#1}}
-%<check> \chk_local_or_pref_global:N #1
-}
-\def_long_new:Npn \tlp_put_left:cn{\exp_args:Nc\tlp_put_left:Nn}
-\def_long_new:Npn \tlp_put_left:co{\exp_args:Nc\tlp_put_left:No}
-\def_long_new:Npn \tlp_put_left:cx{\exp_args:Nc\tlp_put_left:Nx}
-\def_long_new:Npn \tlp_gput_left:cn{\exp_args:Nc\tlp_gput_left:Nn}
-\def_long_new:Npn \tlp_gput_left:co{\exp_args:Nc\tlp_gput_left:No}
-\def_long_new:Npn \tlp_gput_left:cx{\exp_args:Nc\tlp_gput_left:Nx}
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\tlp_put_right:Nn}
-% \begin{macro}{\tlp_put_right:No}
-% \begin{macro}{\tlp_put_right:Nx}
-% \begin{macro}{\tlp_put_right:cc}
-% \begin{macro}{\tlp_gput_right:Nn}
-% \begin{macro}{\tlp_gput_right:No}
-% \begin{macro}{\tlp_gput_right:cn}
-% \begin{macro}{\tlp_gput_right:co}
-% \begin{macro}{\tlp_gput_right:Nx}
-% These are variants of the functions above, but for adding tokens
-% to the right.
-% \begin{macrocode}
-\def_long_new:Npn \tlp_put_right:Nn #1#2{
- \tlp_set:Nn \l_exp_tlp{#2}
- \tlp_set:Nx #1{\exp_not:o{#1}\exp_not:o{\l_exp_tlp}}
-%<check> \chk_local_or_pref_global:N #1
-}
-\def_long_new:Npn \tlp_gput_right:Nn #1#2{
- \tlp_set:Nn \l_exp_tlp{#2}
- \tlp_gset:Nx #1{\exp_not:o{#1}\exp_not:o{\l_exp_tlp}}
-%<check> \chk_local_or_pref_global:N #1
-}
-\def_long_new:Npn \tlp_put_right:No #1#2{
- \tlp_set:Nn \l_exp_tlp{#2}
- \tlp_set:Nx #1{\exp_not:o{#1}\exp_not:d{\l_exp_tlp}}
-%<check> \chk_local_or_pref_global:N #1
-}
-\def_long_new:Npn \tlp_gput_right:No #1#2{
- \tlp_set:Nn \l_exp_tlp{#2}
- \tlp_gset:Nx #1{\exp_not:o{#1}\exp_not:d{\l_exp_tlp}}
-%<check> \chk_local_or_pref_global:N #1
-}
-\def_long:Npn \tlp_put_right:Nx #1#2{
- \tlp_set:Nx #1{\exp_not:o{#1}#2}
-%<check> \chk_local_or_pref_global:N #1
-}
-\def_long:Npn \tlp_gput_right:Nx #1#2{
- \tlp_gset:Nx #1{\exp_not:o{#1}#2}
-%<check> \chk_local_or_pref_global:N #1
-}
-\def_new:Npn \tlp_gput_right:cn {\exp_args:Nc \tlp_gput_right:Nn}
-\def_new:Npn \tlp_gput_right:co {\exp_args:Nc \tlp_gput_right:No}
-\def_new:Npn \tlp_put_right:cc {\exp_args:Ncc \tlp_put_right:Nn}
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-%
-%
-% \begin{macro}{\tlp_gset:Nc}
-% \begin{macro}{\tlp_set:Nc}
-% These two functions are included because they are necessary in
-% Denys' implementations. The |:Nc| convention (see the expansion
-% module) is very unusual at first sight, but it works nicely
-% over all modules, so we would like to keep it.
-%
-% Construct a control sequence on the fly from |#2| and save it in
-% |#1|.
-% \begin{macrocode}
-\def_new:Npn \tlp_gset:Nc {
-%<*check>
- \pref_global_chk:
-%</check>
-%<-check> \pref_global:D
- \tlp_set:Nc}
-% \end{macrocode}
-% |\pref_global_chk:| will turn the variable check in |\tlp_set:No|
-% into a global check.
-% \begin{macrocode}
-\def_new:Npn \tlp_set:Nc #1#2{\tlp_set:No #1{\cs:w#2\cs_end:}}
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-%
-% We also provide a few conditionals, both in expandable form (with
-% |\c_true|) and in `brace-form', the latter are denoted by |TF| at the
-% end, as explained elsewhere.
-%
-%
-% \begin{macro}{\tlp_if_empty_p:N}
-% \begin{macro}{\tlp_if_empty_p:c}
-% Returns |\c_true| iff the token list in the argument is empty.
-% \begin{macrocode}
-\def_new:Npn \tlp_if_empty_p:N #1{
- \if_meaning:NN#1\c_empty_tlp \c_true \else: \c_false \fi:}
-\def_new:Npn \tlp_if_empty_p:c {\exp_args:Nc\tlp_if_empty_p:N}
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-%
-% \begin{macro}{\tlp_if_empty:NTF}
-% \begin{macro}{\tlp_if_empty:NT}
-% \begin{macro}{\tlp_if_empty:NF}
-% \begin{macro}{\tlp_if_empty:cTF}
-% \begin{macro}{\tlp_if_empty:cT}
-% \begin{macro}{\tlp_if_empty:cF}
-% These functions check whether the token list in the argument is
-% empty and execute the proper code from their argument(s).
-% \begin{macrocode}
-\def_test_function_new:npn {tlp_if_empty:N} #1{
- \if_meaning:NN#1\c_empty_tlp}
-\def_new:Npn \tlp_if_empty:cTF {\exp_args:Nc \tlp_if_empty:NTF}
-\def_new:Npn \tlp_if_empty:cT {\exp_args:Nc \tlp_if_empty:NT}
-\def_new:Npn \tlp_if_empty:cF {\exp_args:Nc \tlp_if_empty:NF}
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\tlp_if_eq_p:NN}
-% \begin{macro}{\tlp_if_eq_p:Nc}
-% \begin{macro}{\tlp_if_eq_p:cN}
-% \begin{macro}{\tlp_if_eq_p:cc}
-% Returns |\c_true| iff the two token list pointers are equal.
-% \begin{macrocode}
-\def_new:Npn \tlp_if_eq_p:NN #1#2{
- \if_meaning:NN#1#2 \c_true \else: \c_false \fi:}
-\def_new:Npn \tlp_if_eq_p:Nc {\exp_args:NNc\tlp_if_empty_p:NN}
-\def_new:Npn \tlp_if_eq_p:cN {\exp_args:Nc\tlp_if_empty_p:NN}
-\def_new:Npn \tlp_if_eq_p:cc {\exp_args:Ncc\tlp_if_empty_p:NN}
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\tlp_if_eq:NNTF}
-% \begin{macro}{\tlp_if_eq:NNT}
-% \begin{macro}{\tlp_if_eq:NNF}
-% \begin{macro}{\tlp_if_eq:NcTF}
-% \begin{macro}{\tlp_if_eq:NcT}
-% \begin{macro}{\tlp_if_eq:NcF}
-% \begin{macro}{\tlp_if_eq:cNTF}
-% \begin{macro}{\tlp_if_eq:cNT}
-% \begin{macro}{\tlp_if_eq:cNF}
-% \begin{macro}{\tlp_if_eq:ccTF}
-% \begin{macro}{\tlp_if_eq:ccT}
-% \begin{macro}{\tlp_if_eq:ccF}
-% These function tests whether the token list pointers that are in its
-% first two arguments are equal.
-% \begin{macrocode}
-\def_test_function_new:npn {tlp_if_eq:NN} #1#2{\if_meaning:NN#1#2}
-\def_new:Npn \tlp_if_eq:cNTF{\exp_args:Nc \tlp_if_eq:NNTF}
-\def_new:Npn \tlp_if_eq:cNT {\exp_args:Nc \tlp_if_eq:NNT}
-\def_new:Npn \tlp_if_eq:cNF {\exp_args:Nc \tlp_if_eq:NNF}
-\def_new:Npn \tlp_if_eq:NcTF{\exp_args:NNc \tlp_if_eq:NNTF}
-\def_new:Npn \tlp_if_eq:NcT {\exp_args:NNc \tlp_if_eq:NNT}
-\def_new:Npn \tlp_if_eq:NcF {\exp_args:NNc \tlp_if_eq:NNF}
-\def_new:Npn \tlp_if_eq:ccTF{\exp_args:Ncc \tlp_if_eq:NNTF}
-\def_new:Npn \tlp_if_eq:ccT {\exp_args:Ncc \tlp_if_eq:NNT}
-\def_new:Npn \tlp_if_eq:ccF {\exp_args:Ncc \tlp_if_eq:NNF}
-% \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}{\c_empty_tlp}
-% \begin{macro}{\c_relax_tlp}
-% Two constants which are often used.
-% \begin{macrocode}
-\tlp_new:Nn \c_empty_tlp {}
-\tlp_new:Nn \c_relax_tlp {\scan_stop:}
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \begin{macro}{\g_tmpa_tlp}
-% \begin{macro}{\g_tmpb_tlp}
-% Global temporary token list pointers.
-% 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}
-\tlp_new:Nn \g_tmpa_tlp{}
-\tlp_new:Nn \g_tmpb_tlp{}
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\l_testa_tlp}
-% \begin{macro}{\l_testb_tlp}
-% \begin{macro}{\g_testa_tlp}
-% \begin{macro}{\g_testb_tlp}
-% Global and local temporaries. These are the ones for test
-% routines. This means that one can safely use other temporaries
-% when calling test routines.
-% \begin{macrocode}
-\tlp_new:Nn \l_testa_tlp {}
-\tlp_new:Nn \l_testb_tlp {}
-\tlp_new:Nn \g_testa_tlp {}
-\tlp_new:Nn \g_testb_tlp {}
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\l_tmpa_tlp}
-% \begin{macro}{\l_tmpb_tlp}
-% These are local temporary token list pointers.
-% \begin{macrocode}
-\tlp_new:Nn \l_tmpa_tlp{}
-\tlp_new:Nn \l_tmpb_tlp{}
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\tlp_to_str:N}
-% \begin{macro}{\tlp_to_str:c}
-% \begin{macro}{\tlp_to_str_aux:w}
-% These functions return the replacement text of a token list as a
-% string list with all characters catcoded to `other'.
-% \begin{macrocode}
-\def_new:Npn \tlp_to_str:N {\exp_after:NN\tlp_to_str_aux:w
- \token_to_meaning:N}
-\def_new:Npn \tlp_to_str_aux:w #1>{}
-\def_new:Npn\tlp_to_str:c{\exp_args:Nc\tlp_to_str:N}
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-%
-%
-%
-% \begin{macro}{\tlist_if_empty_p:n}
-% It would be tempting to just use "\if_meaning:NN\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:NN", 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}
-\def_long_new:Npn \tlist_if_empty_p:n #1{
- \exp_after:NN\if_meaning:NN\exp_after:NN\q_nil\tlist_to_str:n{#1}\q_nil
- \c_true
- \else:
- \c_false
- \fi:
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\tlist_if_empty_p:o}
-% \begin{macro}{\tlist_if_empty:nTF}
-% \begin{macro}{\tlist_if_empty:nT}
-% \begin{macro}{\tlist_if_empty:nF}
-% \begin{macro}{\tlist_if_empty:oTF}
-% \begin{macro}{\tlist_if_empty:oT}
-% \begin{macro}{\tlist_if_empty:oF}
-% \begin{macrocode}
-\def_new:Npn \tlist_if_empty_p:o {\exp_args:No\tlist_if_empty_p:n}
-\def_long_test_function_new:npn{tlist_if_empty:n}#1{
- \if:w\tlist_if_empty_p:n{#1}}
-\def_long_test_function_new:npn{tlist_if_empty:o}#1{
- \if:w\tlist_if_empty_p:o{#1}}
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\tlist_if_blank_p:n}
-% \begin{macro}{\tlist_if_blank_p_aux:w}
-% This is based on the answers in ``Around the Bend No~2'' but is
-% safer as the tests listed there all have one small flaw: If the
-% input in the test is two tokens with the same meaning as the
-% internal delimiter, they will fail since one of them is mistaken
-% for the actual delimiter. In our version below we make sure to
-% pass the input through |\tlist_to_str:n| which ensures that all
-% the tokens are converted to catcode 12. However we use an |a| with
-% catcode 11 as delimiter so we can \emph{never} get into the same
-% problem as the solutions in ``Around the Bend No~2''.
-% \begin{macrocode}
-\def_long_new:Npn \tlist_if_blank_p:n #1{
- \exp_after:NN\tlist_if_blank_p_aux:w\tlist_to_str:n{#1}aa..\q_nil
-}
-\def_new:Npn \tlist_if_blank_p_aux:w #1#2a#3#4\q_nil{
- \if_meaning:NN #3#4\c_true\else:\c_false\fi:}
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\tlist_if_blank:nTF}
-% \begin{macro}{\tlist_if_blank:nT}
-% \begin{macro}{\tlist_if_blank:nF}
-% \begin{macro}{\tlist_if_blank_p:o}
-% \begin{macro}{\tlist_if_blank:oTF}
-% \begin{macro}{\tlist_if_blank:oT}
-% \begin{macro}{\tlist_if_blank:oF}
-% Variations on the original function above.
-% \begin{macrocode}
-\def_long_test_function_new:npn{tlist_if_blank:n}#1{
- \if:w\tlist_if_blank_p:n{#1}}
-\def:Npn \tlist_if_blank_p:o{\exp_args:No\tlist_if_blank_p:n}
-\def_long_test_function_new:npn{tlist_if_blank:o}#1{
- \if:w\tlist_if_blank_p:o{#1}}
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\tlist_to_lowercase:n}
-% \begin{macro}{\tlist_to_uppercase:n}
-% Just some names for a few primitives.
-% \begin{macrocode}
-\let_new:NN \tlist_to_lowercase:n \tex_lowercase:D
-\let_new:NN \tlist_to_uppercase:n \tex_uppercase:D
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\tlist_to_str:n}
-% Another name for a primitive.
-% \begin{macrocode}
-\let_new:NN \tlist_to_str:n \etex_detokenize:D
-% \end{macrocode}
-% \end{macro}
-%
-%
-% \begin{macro}{\tlist_map_function:nN}
-% \begin{macro}{\tlp_map_function:NN}
-% \begin{macro}{\tlp_map_function:cN}
-% \begin{macro}{\tlist_map_function_aux:NN}
-% Expandable loop macro for |tlist|s. 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}
-\def_long_new:Npn \tlist_map_function:nN #1#2{
- \tlist_map_function_aux:Nn #2 #1 \q_recursion_tail \q_recursion_stop
-}
-\def_new:Npn \tlp_map_function:NN #1#2{
- \exp_after:NN \tlist_map_function_aux:Nn
- \exp_after:NN #2 #1 \q_recursion_tail \q_recursion_stop
-}
-\def_long_new:Npn \tlist_map_function_aux:Nn #1#2{
- \quark_if_recursion_tail_stop:n{#2}
- #1{#2} \tlist_map_function_aux:Nn #1
-}
-\def_new:Npn\tlp_map_function:cN{\exp_args:Nc\tlp_map_function:NN}
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-%
-% \begin{macro}{\tlist_map_inline:nn}
-% \begin{macro}{\tlp_map_inline:Nn}
-% \begin{macro}{\tlp_map_inline:cn}
-% \begin{macro}{\tlist_map_inline_aux:n}
-% \begin{macro}{\g_tlp_inline_level_num}
-% The inline functions are straight forward by now. We use a little
-% a trick with the fake counter |\g_tlp_inline_level_num| to make
-% them nestable.\footnote{This should be a proper integer, but I
-% don't want to mess with the dependencies right now\dots} We can
-% also make use of |\tlist_map_function:Nn| from before.
-% \begin{macrocode}
-\def_long_new:Npn \tlist_map_inline:nn #1#2{
- \num_gincr:N \g_tlp_inline_level_num
- \gdef_long:cpn {tlist_map_inline_ \num_use:N \g_tlp_inline_level_num :n}
- ##1{#2}
- \exp_args:Nc \tlist_map_function_aux:Nn
- {tlist_map_inline_ \num_use:N \g_tlp_inline_level_num :n}
- #1 \q_recursion_tail\q_recursion_stop
- \num_gdecr:N \g_tlp_inline_level_num
-}
-\def_long_new:Npn \tlp_map_inline:Nn #1#2{
- \num_gincr:N \g_tlp_inline_level_num
- \gdef_long:cpn {tlist_map_inline_ \num_use:N \g_tlp_inline_level_num :n}
- ##1{#2}
- \exp_args:NcE \tlist_map_function_aux:Nn
- {tlist_map_inline_ \num_use:N \g_tlp_inline_level_num :n}
- #1 \q_recursion_tail\q_recursion_stop
- \num_gdecr:N \g_tlp_inline_level_num
-}
-\def_new:Npn\tlp_map_inline:cN{\exp_args:Nc\tlp_map_inline:NN}
-\tlp_new:Nn \g_tlp_inline_level_num{0}
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-%
-% \begin{macro}{\tlist_map_variable:nNn}
-% \begin{macro}{\tlp_map_variable:NNn}
-% \begin{macro}{\tlp_map_variable:cNn}
-% |\tlist_map:nNn| \zz{tlist} \zz{temp} \zz{action} assigns
-% \zz{temp} to each element and executes \zz{action}.
-% \begin{macrocode}
-\def_long_new:Npn \tlist_map_variable:nNn #1#2#3{
- \tlist_map_variable_aux:Nnn #2 {#3} #1 \q_recursion_tail \q_recursion_stop
-}
-\def_new:Npn \tlp_map_variable:NNn {\exp_args:No \tlist_map_variable:nNn}
-\def_new:Npn \tlp_map_variable:cNn {\exp_args:Nc \tlp_map_variable:NNn}
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\tlist_map_variable_aux:NnN}
-% The general loop. Assign the temp variable |#1| to the current item
-% |#3| and then check if that's the stop marker. If it is, break the
-% loop. If not, execute the action |#2| and continue.
-% \begin{macrocode}
-\def_long_new:Npn \tlist_map_variable_aux:Nnn #1#2#3{
- \tlp_set:Nn #1{#3}
- \quark_if_recursion_tail_stop:N #1
- #2 \tlist_map_variable_aux:Nnn #1{#2}
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\tlist_map_break:w}
-% \begin{macro}{\tlp_map_break:w}
-% The break statement.
-% \begin{macrocode}
-\let_new:NN \tlist_map_break:w \use_none_delimit_by_q_recursion_stop:w
-\let_new:NN \tlp_map_break:w \tlist_map_break:w
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-%
-% \begin{macro}{\tlist_elt_count:n}
-% \begin{macro}{\tlist_elt_count:o}
-% \begin{macro}{\tlp_elt_count:n}
-% Count number of elements within a token list or token list
-% pointer. Brace groups within the list are read as a single
-% element.
-% "\num_elt_count:n" grabs the element and replaces it by "+1". The
-% "0" to ensure it works on an empty list.
-% \begin{macrocode}
-\def_long_new:Npn \tlist_elt_count:n #1{
- \num_value:w \num_eval:w 0
- \tlist_map_function:nN {#1}\num_elt_count:n
- \num_eval_end:
-}
-\def_new:Npn \tlist_elt_count:o {\exp_args:No\tlist_elt_count:n}
-\def_new:Npn \tlp_elt_count:N #1{
- \num_value:w \num_eval:w 0
- \tlp_map_function:NN #1 \num_elt_count:n
- \num_eval_end:
-}
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-%
-%
-%
-% \begin{macro}{\tlist_if_eq:nnTF}
-% \begin{macro}{\tlist_if_eq:nnT}
-% \begin{macro}{\tlist_if_eq:nnF}
-% Test if two token lists are identical. pdf\TeX\ contains a most
-% interesting primitive for expandable string comparison so we make
-% use of it if available. Presumable it will be in the final
-% version.
-%
-% Firstly we give it an appropriate name. Note that this primitive
-% actually performs an \texttt{x} type expansion but it is still
-% expandable! Hence we must program these functions backwards to add
-% \verb|\exp_not:n|. We provide the combinations for the types
-% \texttt{n}, \texttt{o} and \texttt{x}.
-% \begin{macrocode}
-\let_new:NN \tlist_compare:xx \pdfstrcmp
-\def_long_new:NNn \tlist_compare:nn 2{
- \tlist_compare:xx{\exp_not:n{#1}}{\exp_not:n{#2}}
-}
-\def_long_new:NNn \tlist_compare:nx 1{
- \tlist_compare:xx{\exp_not:n{#1}}
-}
-\def_long_new:NNn \tlist_compare:xn 2{
- \tlist_compare:xx{#1}{\exp_not:n{#2}}
-}
-\def_long_new:NNn \tlist_compare:no 2{
- \tlist_compare:xx{\exp_not:n{#1}}{\exp_not:n\exp_after:NN{#2}}
-}
-\def_long_new:NNn \tlist_compare:on 2{
- \tlist_compare:xx{\exp_not:n\exp_after:NN{#1}}{\exp_not:n{#2}}
-}
-\def_long_new:NNn \tlist_compare:oo 2{
- \tlist_compare:xx{\exp_not:n\exp_after:NN{#1}}{\exp_not:n\exp_after:NN{#2}}
-}
-\def_long_new:NNn \tlist_compare:xo 2{
- \tlist_compare:xx{#1}{\exp_not:n\exp_after:NN{#2}}
-}
-\def_long_new:NNn \tlist_compare:ox 2{
- \tlist_compare:xx{\exp_not:n\exp_after:NN{#1}}{\exp_not:n{#2}}
-}
-% \end{macrocode}
-% Since we have a lot of basically identical functions to define we
-% define one to define the rest. Unfortunately we aren't quite set up
-% to use the new \verb|\tlist_map_inline:nn| function yet.
-% \begin{macrocode}
-\def:Npn \tmp:w #1{
- \def_long_new:cNx {tlist_if_eq_p:#1} 2{
- \exp_not:N \if_num:w
- \exp_after:NN \exp_not:N \cs:w tlist_compare:#1\cs_end:{##1}{##2}
- \exp_not:n{ =\c_zero \c_true \else: \c_false \fi: }
- }
- \def_long_test_function_new:npx{tlist_if_eq:#1}##1##2{
- \exp_not:N \if_num:w
- \exp_after:NN \exp_not:N \cs:w tlist_compare:#1\cs_end:{##1}{##2}
- \exp_not:n{ =\c_zero }
- }
-}
-\tmp:w{xx} \tmp:w{nn} \tmp:w{oo} \tmp:w{xn} \tmp:w{nx}
-\tmp:w{on} \tmp:w{no} \tmp:w{xo} \tmp:w{ox}
-% \end{macrocode}
-% However all of this only makes sense if we actually have that
-% primitive. Therefore we disable it again if it is not there and
-% define \verb|\tlist_if_eq:nn| the old fashioned (and unexpandable)
-% way.
-% \begin{macrocode}
-\cs_if_really_free:cT{pdf_strcmp:D}{
- \def_long_test_function:npn{tlist_if_eq:nn}#1#2{
- \tlp_set:Nx \l_testa_tlp {\exp_not:n{#1}}
- \tlp_set:Nx \l_testb_tlp {\exp_not:n{#2}}
- \if_meaning:NN\l_testa_tlp \l_testb_tlp
- }
- \def_long_test_function:npn{tlist_if_eq:no}#1#2{
- \tlp_set:Nx \l_testa_tlp {\exp_not:n{#1}}
- \tlp_set:Nx \l_testb_tlp {\exp_not:o{#2}}
- \if_meaning:NN\l_testa_tlp \l_testb_tlp
- }
- \def_long_test_function:npn{tlist_if_eq:nx}#1#2{
- \tlp_set:Nx \l_testa_tlp {\exp_not:n{#1}}
- \tlp_set:Nx \l_testb_tlp {#2}
- \if_meaning:NN\l_testa_tlp \l_testb_tlp
- }
- \def_long_test_function:npn{tlist_if_eq:on}#1#2{
- \tlp_set:Nx \l_testa_tlp {\exp_not:o{#1}}
- \tlp_set:Nx \l_testb_tlp {\exp_not:n{#2}}
- \if_meaning:NN\l_testa_tlp \l_testb_tlp
- }
- \def_long_test_function:npn{tlist_if_eq:oo}#1#2{
- \tlp_set:Nx \l_testa_tlp {\exp_not:o{#1}}
- \tlp_set:Nx \l_testb_tlp {\exp_not:o{#2}}
- \if_meaning:NN\l_testa_tlp \l_testb_tlp
- }
- \def_long_test_function:npn{tlist_if_eq:ox}#1#2{
- \tlp_set:Nx \l_testa_tlp {\exp_not:o{#1}}
- \tlp_set:Nx \l_testb_tlp {#2}
- \if_meaning:NN\l_testa_tlp \l_testb_tlp
- }
- \def_long_test_function:npn{tlist_if_eq:xn}#1#2{
- \tlp_set:Nx \l_testa_tlp {#1}
- \tlp_set:Nx \l_testb_tlp {\exp_not:n{#2}}
- \if_meaning:NN\l_testa_tlp \l_testb_tlp
- }
- \def_long_test_function:npn{tlist_if_eq:xo}#1#2{
- \tlp_set:Nx \l_testa_tlp {#1}
- \tlp_set:Nx \l_testb_tlp {\exp_not:o{#2}}
- \if_meaning:NN\l_testa_tlp \l_testb_tlp
- }
- \def_long_test_function:npn{tlist_if_eq:xx}#1#2{
- \tlp_set:Nx \l_testa_tlp {#1}
- \tlp_set:Nx \l_testb_tlp {#2}
- \if_meaning:NN\l_testa_tlp \l_testb_tlp
- }
-}
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-%
-%
-%
-% \subsubsection{Checking for and replacing tokens}
-%
-% \begin{macro}{\tlp_if_in:NnTF}
-% \begin{macro}{\tlp_if_in:cnTF}
-% \begin{macro}{\tlp_if_in:NnT}
-% \begin{macro}{\tlp_if_in:cnT}
-% \begin{macro}{\tlp_if_in:NnF}
-% \begin{macro}{\tlp_if_in:cnF}
-% \begin{macro}{\tlist_if_in:nnTF}
-% \begin{macro}{\tlist_if_in:onTF}
-% See the replace functions for further comments. In this part we
-% don't care too much about brace stripping since we are not
-% interested in passing on the tokens which are split off in the
-% process.
-% \begin{macrocode}
-\def_long:Npn \tlp_if_in:NnTF #1#2{
- \def_long:Npn\tmp:w ##1 #2 ##2\q_stop{
- \quark_if_no_value:nFT{##2}
- }
- \exp_after:NN \tmp:w #1 #2 \q_no_value \q_stop
-}
-\def_new:Npn \tlp_if_in:cnTF {\exp_args:Nc\tlp_if_in:NnTF}
-\def_long:Npn \tlp_if_in:NnT #1#2{
- \def_long:Npn\tmp:w ##1 #2 ##2\q_stop{
- \quark_if_no_value:nF{##2}
- }
- \exp_after:NN \tmp:w #1 #2 \q_no_value \q_stop
-}
-\def_new:Npn \tlp_if_in:cnT {\exp_args:Nc\tlp_if_in:NnT}
-\def_long:Npn \tlp_if_in:NnF #1#2{
- \def_long:Npn\tmp:w ##1 #2 ##2\q_stop{
- \quark_if_no_value:nT{##2}
- }
- \exp_after:NN \tmp:w #1 #2 \q_no_value \q_stop
-}
-\def_new:Npn \tlp_if_in:cnF {\exp_args:Nc\tlp_if_in:NnF}
-\def_long_new:Npn \tlist_if_in:nnTF #1#2{
- \def_long:Npn\tmp:w ##1 #2 ##2\q_stop{
- \quark_if_no_value:nFT{##2}
- }
- \tmp:w #1 #2 \q_no_value \q_stop
-}
-\def_new:Npn \tlist_if_in:onTF {\exp_args:No\tlist_if_in:nnTF}
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\l_tlp_replace_tlp}
-% A temp variable for the replace operations.
-% \begin{macrocode}
-\tlp_new:Nn\l_tlp_replace_tlp{}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\tlp_replace_in:Nnn}
-% \begin{macro}{\tlp_replace_in:cnn}
-% \begin{macro}{\tlp_greplace_in:Nnn}
-% \begin{macro}{\tlp_greplace_in:cnn}
-% \begin{macro}{\tlp_replace_in_aux:NNnn}
-% Replacing the first item in a token list pointer goes like this:
-% Define a temporary function with delimited arguments containing
-% the search term and take a closer look at what is left. We append
-% the expansion of the tlp with the search term plus the quark
-% |\q_no_value|. If the search term isn't present this last one is
-% found and the following token is the quark, so we test for
-% that. If the search term is present we will have to split off the
-% |#3\q_no_value| we had, so we define yet another function with
-% delimited arguments to do this. The advantage here is that now we
-% have a special end sequence so there is no problem if the search
-% term appears more than once. Only problem left is to prevent brace
-% stripping in both ends, so we prepend the expansion of the tlp
-% with |\q_mark| later to be gobbled and also prepend the remainder
-% of the first split operation with |\q_mark| also to be gobbled
-% again later on.
-% \begin{macrocode}
-\def_long_new:NNn \tlp_replace_in_aux:NNnn 4{
- \def_long:Npn \tmp:w ##1#3##2\q_stop{
- \quark_if_no_value:nF{##2}
- {
-% \end{macrocode}
-% At this point |##1| starts with a |\q_mark| so remove it.
-% \begin{macrocode}
- \tlp_set:Nx\l_tlp_replace_tlp{\exp_not:o{\use_none:n##1#4}}
- \def_long:Npn \tmp:w ####1#3\q_no_value{
- \tlp_put_right:Nx \l_tlp_replace_tlp {\exp_not:o{\use_none:n ####1}}
- }
- \tmp:w \q_mark ##2
- }
-% \end{macrocode}
-% Now all that is done is setting the token list pointer equal to the
-% expansion of the token register.
-% \begin{macrocode}
- #1#2\l_tlp_replace_tlp
- }
-% \end{macrocode}
-% Here is where we start the process. Note that the tlp might start
-% with a space token so we use this little trick with |\use_arg_i:n|
-% to prevent it from being removed.
-% \begin{macrocode}
- \use_arg_i:n{\exp_after:NN \tmp:w\exp_after:NN\q_mark}
- #2#3 \q_no_value\q_stop
-}
-% \end{macrocode}
-% Now the various versions doing the replacement either globally or
-% locally.
-% \begin{macrocode}
-\def_new:Npn \tlp_replace_in:Nnn {\tlp_replace_in_aux:NNnn \tlp_set_eq:NN}
-\def_new:Npn \tlp_replace_in:cnn{\exp_args:Nc\tlp_replace_in:Nnn}
-\def_new:Npn \tlp_greplace_in:Nnn {\tlp_replace_in_aux:NNnn \tlp_gset_eq:NN}
-\def_new:Npn \tlp_greplace_in:cnn{\exp_args:Nc\tlp_greplace_in:Nnn}
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\tlp_replace_all_in:Nnn}
-% \begin{macro}{\tlp_greplace_all_in:cnn}
-% \begin{macro}{\tlp_replace_all_in:Nnn}
-% \begin{macro}{\tlp_greplace_all_in:cnn}
-% \begin{macro}{\tlp_replace_all_in_aux:NNnn}
-% The version for replacing \emph{all} occurrences of the search
-% term is fairly easy since we just have to keep doing the
-% replacement on the split-off part until all are
-% replaced. Otherwise it is pretty much the same as above.
-% \begin{macrocode}
-\def_long:NNn \tlp_replace_all_in_aux:NNnn 4{
- \tlp_clear:N \l_tlp_replace_tlp
- \def_long:Npn \tmp:w ##1#3##2\q_stop{
- \quark_if_no_value:nTF{##2}
- {
- \tlp_put_right:Nx \l_tlp_replace_tlp {\exp_not:o{\use_none:n##1}}
- }
- {
- \tlp_put_right:Nx \l_tlp_replace_tlp {\exp_not:o{\use_none:n##1 #4}}
- \tmp:w \q_mark##2 \q_stop
- }
- }
- \use_arg_i:n{\exp_after:NN \tmp:w\exp_after:NN\q_mark}
- #2#3 \q_no_value\q_stop
- #1#2\l_tlp_replace_tlp
-}
-% \end{macrocode}
-% Now the various forms.
-% \begin{macrocode}
-\def_new:Npn \tlp_replace_all_in:Nnn {
- \tlp_replace_all_in_aux:NNnn \tlp_set_eq:NN}
-\def_new:Npn \tlp_replace_all_in:cnn{\exp_args:Nc\tlp_replace_all_in:Nnn}
-\def_new:Npn \tlp_greplace_all_in:Nnn {
- \tlp_replace_all_in_aux:NNnn \tlp_gset_eq:NN}
-\def_new:Npn \tlp_greplace_all_in:cnn{\exp_args:Nc\tlp_greplace_all_in:Nnn}
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-%
-%
-% \begin{macro}{\tlp_remove_in:Nn}
-% \begin{macro}{\tlp_remove_in:cn}
-% \begin{macro}{\tlp_gremove_in:Nn}
-% \begin{macro}{\tlp_gremove_in:cn}
-% Next comes a series of removal functions. I have just implemented
-% them as subcases of the replace functions for now (I'm lazy).
-% \begin{macrocode}
-\def_long_new:NNn \tlp_remove_in:Nn 2{\tlp_replace_in:Nnn #1{#2}{}}
-\def_long_new:NNn \tlp_gremove_in:Nn 2{\tlp_greplace_in:Nnn #1{#2}{}}
-\def_new:Npn \tlp_remove_in:cn{\exp_args:Nc\tlp_remove_in:Nn}
-\def_new:Npn \tlp_gremove_in:cn{\exp_args:Nc\tlp_gremove_in:Nn}
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-%
-% \begin{macro}{\tlp_remove_all_in:Nn}
-% \begin{macro}{\tlp_remove_all_in:Nn}
-% \begin{macro}{\tlp_gremove_all_in:Nn}
-% \begin{macro}{\tlp_gremove_all_in:Nn}
-% Same old, same old.
-% \begin{macrocode}
-\def_long_new:Npn \tlp_remove_all_in:Nn #1#2{
- \tlp_replace_all_in:Nnn #1{#2}{}
-}
-\def_long_new:Npn \tlp_gremove_all_in:Nn #1#2{
- \tlp_greplace_all_in:Nnn #1{#2}{}
-}
-\def_new:Npn \tlp_remove_all_in:cn{\exp_args:Nc\tlp_remove_all_in:Nn}
-\def_new:Npn \tlp_gremove_all_in:cn{\exp_args:Nc\tlp_gremove_all_in:Nn}
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-%
-% \subsubsection{Heads or tails?}
-%
-% \begin{macro}{\tlist_head:n}
-% \begin{macro}{\tlist_head_i:n}
-% \begin{macro}{\tlist_tail:n}
-% \begin{macro}{\tlist_tail:f}
-% \begin{macro}{\tlist_head_iii:n}
-% \begin{macro}{\tlist_head_iii:f}
-% \begin{macro}{\tlist_head:w}
-% \begin{macro}{\tlist_tail:w}
-% \begin{macro}{\tlist_head_iii:w}
-% These functions pick up either the head or the tail of a list.
-% "\tlist_head_iii:n" returns the first three items on a list.
-% \begin{macrocode}
-\def_long_new:Npn \tlist_head:n #1{\tlist_head:w #1\q_nil}
-\let_new:NN \tlist_head_i:n \tlist_head:n
-\def_long_new:Npn \tlist_tail:n #1{\tlist_tail:w #1\q_nil}
-\def_new:Npn \tlist_tail:f {\exp_args:Nf \tlist_tail:n}
-\def_long_new:Npn \tlist_head_iii:n #1{\tlist_head_iii:w #1\q_nil}
-\def_new:Npn \tlist_head_iii:f {\exp_args:Nf \tlist_head_iii:n}
-\let_new:NN \tlist_head:w \use_arg_i_delimit_by_q_nil:nw
-\def_long_new:Npn \tlist_tail:w #1#2\q_nil{#2}
-\def_long_new:Npn \tlist_head_iii:w #1#2#3#4\q_nil{#1#2#3}
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\tlist_if_head_eq_meaning_p:nN}
-% \begin{macro}{\tlist_if_head_eq_meaning:nNTF}
-% \begin{macro}{\tlist_if_head_eq_meaning:nNT}
-% \begin{macro}{\tlist_if_head_eq_meaning:nNF}
-% \begin{macro}{\tlist_if_head_eq_charcode_p:nNTF}
-% \begin{macro}{\tlist_if_head_eq_charcode:nNTF}
-% \begin{macro}{\tlist_if_head_eq_charcode:nNT}
-% \begin{macro}{\tlist_if_head_eq_charcode:nNF}
-% \begin{macro}{\tlist_if_head_eq_catcode_p:nNTF}
-% \begin{macro}{\tlist_if_head_eq_catcode:nNTF}
-% \begin{macro}{\tlist_if_head_eq_catcode:nNT}
-% \begin{macro}{\tlist_if_head_eq_catcode:nNF}
-% 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.
-% |\tlist_if_head_meaning_eq:nNTF| uses |\if_meaning:NN| and will
-% consider the tokens |b|$\sb{11}$ and |b|$\sb{12}$ different.
-% |\tlist_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}
-\def_long_new:Npn \tlist_if_head_eq_meaning_p:nN #1#2{
- \exp_after:NN \if_meaning:NN \tlist_head:w #1\q_nil#2
- \c_true
- \else:
- \c_false
- \fi:
-}
-\def_long_test_function_new:npn {tlist_if_head_eq_meaning:nN}#1#2{
- \if:w \tlist_if_head_eq_meaning_p:nN{#1}#2}
-% \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}
-\def_long_new:Npn \tlist_if_head_eq_charcode_p:nN #1#2{
- \exp_after:NN\if_charcode:w \exp_after:NN\exp_not:N
- \tlist_head:w #1\q_nil\exp_not:N#2
- \c_true
- \else:
- \c_false
- \fi:
-}
-\def_long_test_function_new:npn {tlist_if_head_eq_charcode:nN}#1#2{
- \if:w\tlist_if_head_eq_charcode_p:nN{#1}#2}
-% \end{macrocode}
-% Actually the default is already an |f| type expansion.
-% \begin{macrocode}
-\def_long_new:Npn \tlist_if_head_eq_charcode_p:fN #1#2{
- \exp_after:NN\if_charcode:w \tlist_head:w #1\q_nil\exp_not:N#2
- \c_true
- \else:
- \c_false
- \fi:
-}
-\def_long_test_function_new:npn {tlist_if_head_eq_charcode:fN}#1#2{
- \if:w\tlist_if_head_eq_charcode_p:fN{#1}#2}
-\def_long_new:Npn \tlist_if_head_eq_catcode_p:nN #1#2{
- \exp_after:NN\if_charcode:w \exp_after:NN\exp_not:N
- \tlist_head:w #1\q_nil\exp_not:N#2
- \c_true
- \else:
- \c_false
- \fi:
-}
-\def_long_test_function_new:npn {tlist_if_head_eq_catcode:nN}#1#2{
- \if:w\tlist_if_head_eq_catcode_p:nN{#1}#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}
-%
-%
-% \begin{macro}{\tlist_reverse:n}
-% \begin{macro}{\tlist_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}
-\def_long_new:Npn \tlist_reverse:n #1{
- \tlist_reverse_aux:nN {} #1 \q_recursion_tail\q_recursion_stop
-}
-\def_long_new:Npn \tlist_reverse_aux:nN #1#2{
- \quark_if_recursion_tail_stop_do:nn {#2}{ #1 }
- \tlist_reverse_aux:nN {#2#1}
-}
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-%
-%
-% As this package relies heavily on a lot of the expansion tricks used
-% in \textsf{l3expan} we make sure to load it automatically at the end
-% when used as a package. Probably not needed but I'm just such a nice
-% guy\dots
-% \begin{macrocode}
-%<package>\RequirePackage{l3expan}
-%<package>\RequirePackage{l3num}\par
-% \end{macrocode}
-% Show token usage:
-% \begin{macrocode}
-%</initex|package>
-%<*showmemory>
-\showMemUsage
-%</showmemory>
-% \end{macrocode}
-%
-% \endinput
-%
-% $Log$
-% Revision 1.28 2006/07/30 15:51:53 morten
-% Made \tlist_map_inline:nn and variants nestable. Reimplemented
-% \tlp_if_in:..., \tlp_replace_in:..., \tlp_replace_all_in:...
-%
-% Revision 1.27 2006/07/25 15:32:48 morten
-% More \tlist_if_blank functions
-%
-% Revision 1.26 2006/07/06 14:58:50 morten
-% Documentation touch-ups. Added more functions plus some new comparison
-% functions which are dependent on a reasonably new pdfTeX.
-%
-% Revision 1.25 2006/06/05 14:55:14 morten
-% Function for reversing a list of tokens.
-%
-% Revision 1.24 2006/06/03 16:31:19 morten
-% Another version of \tlist_head...
-%
-% Revision 1.23 2006/03/20 18:26:41 braams
-% Updated the copyright notice (2006) and demoted all implementation
-% sections to subsections and so on to clean up the toc for source3.tex
-%
-% Revision 1.22 2006/01/26 14:00:42 morten
-% Added a few missing functions (that were documented to be there!)
-%
-% Revision 1.21 2006/01/19 22:27:08 morten
-% Added \tlp_replace_ and \tlp_remove_if_in functions.
-%
-% Revision 1.20 2006/01/17 23:07:06 morten
-% Added "if_in" functions.
-%
-% Revision 1.19 2005/12/27 10:09:07 morten
-% Changed RCS information retrieval, imported all tlist functions since
-% half of them dealt with token list pointers anyway
-%
-% Revision 1.18 2005/07/25 19:50:40 morten
-% Fixed the \long-ness aspects.
-%
-% Revision 1.17 2005/04/12 16:43:03 morten
-% Minor updates
-%
-% Revision 1.16 2005/04/12 12:10:28 morten
-% Rearranged and cleaned up code to avoid much doubling.
-%
-% Revision 1.15 2005/04/06 21:34:07 morten
-% Fixed all tlp_set:XX so that they're \long. Added \tlp_set:Nf
-%
-% Revision 1.14 2005/03/22 23:20:43 morten
-% Fixed \long versions according to Benjamin's suggestions. Slightly reorganized.
-%
-% Revision 1.13 2005/03/16 22:35:41 braams
-% Added the tweaks necessary to be able to load with initex
-%
-% Revision 1.12 2005/03/11 21:43:58 braams
-% Fixed the use of RCS information;
-% Fixed a documentation typo
-%
diff --git a/Master/texmf-dist/source/latex/expl3/l3token.dtx b/Master/texmf-dist/source/latex/expl3/l3token.dtx
index 1df1e08240d..7d0e3110d60 100644
--- a/Master/texmf-dist/source/latex/expl3/l3token.dtx
+++ b/Master/texmf-dist/source/latex/expl3/l3token.dtx
@@ -1,5 +1,5 @@
% \iffalse
-%% File: l3token.dtx Copyright (C) 2005-2006 LaTeX3 project
+%% File: l3token.dtx Copyright (C) 2005-2009 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
@@ -17,7 +17,7 @@
%%
%% The development version of the bundle can be found at
%%
-%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/
+%% http://www.latex-project.org/svnroot/experimental/trunk/
%%
%% for those people who are interested.
%%
@@ -35,7 +35,7 @@
\RequirePackage{l3names}
%</driver|package>
%\fi
-\GetIdInfo$Id: l3token.dtx 701 2007-11-27 14:21:05Z morten $
+\GetIdInfo$Id: l3token.dtx 1365 2009-05-31 17:26:17Z mittelba $
{L3 Experimental token investigation and manipulation}
%\iffalse
%<*driver>
@@ -43,7 +43,7 @@
\ProvidesFile{\filename.\filenameext}
[\filedate\space v\fileversion\space\filedescription]
%\iffalse
-\documentclass{l3doc}
+\documentclass[full]{l3doc}
\begin{document}
\DocInput{\filename.\filenameext}
\end{document}
@@ -53,13 +53,12 @@
% \title{The \textsf{l3token} package\thanks{This file
% has version number \fileversion, last
% revised \filedate.}\\
-% Basic Definitions}
+% A token of my appreciation\dots}
% \author{\Team}
% \date{\filedate}
% \maketitle
%
-%
-% \section{A token of my appreciation\dots}
+% \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
@@ -79,16 +78,12 @@
% 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 py a single control sequence is a `token list pointer'
-% |tlp|. Functions for these two types are found in the \textsf{l3tlp}
+% represented by a single control sequence is a `token list variable'
+% |tl var|. Functions for these two types are found in the \textsf{l3tl}
% module.
%
-% \subsection{Character tokens}
-%
-% Setting category codes of characters.
-%
+% \section{Character tokens}
%
% \begin{function}{
% \char_set_catcode:nn |
@@ -99,22 +94,78 @@
% \char_show_value_catcode:w
% }
% \begin{syntax}
-% "\char_set_catcode:nn" "{"<char>"}" "{"<number>"}"\\
+% "\char_set_catcode:nn" \Arg{char number} \Arg{number}\\
% "\char_set_catcode:w" <char> = <number> \\
-% "\char_value_catcode:n" "{"<char>"}" \\
-% "\char_show_value_catcode:n" "{"<char>"}"
+% "\char_value_catcode:n" \Arg{char number} \\
+% "\char_show_value_catcode:n" \Arg{char number}
% \end{syntax}
% "\char_set_catcode:nn" sets the category code of a character,
% "\char_value_catcode:n" returns its value for use in integer tests
-% and "\char_show_value_catcode:n" prints the value on the terminal
-% and in the log file. The ":w" should be avoided unless you have to
-% fiddle with the catcode of "{" or "}".
+% and "\char_show_value_catcode:n" pausing the typesetting and prints
+% the value on the terminal and in the log file.
+% The ":w" form should be avoided.
+% (Will: should we then just not mention it?)
+%
+% "\char_set_catcode" is more usefully abstracted below.
% \begin{texnote}
% "\char_set_catcode:w" is the \TeX\ primitive \tn{catcode} renamed.
% \end{texnote}
% \end{function}
%
% \begin{function}{
+% \char_make_escape:n |
+% \char_make_begin_group:n |
+% \char_make_end_group:n |
+% \char_make_math_shift: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{syntax}
+% "\char_make_letter:n" \Arg{character number}
+% "\char_make_letter:n {64}"
+% "\char_make_letter:n {`\@}"
+% \end{syntax}
+% Sets the catcode of the character referred to by its <character number>.
+% \end{function}
+%
+% \begin{function}{
+% \char_make_escape:N |
+% \char_make_begin_group:N |
+% \char_make_end_group:N |
+% \char_make_math_shift: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{syntax}
+% "\char_make_letter:N" \Arg{character}
+% "\char_make_letter:N" "@"
+% "\char_make_letter:N" "\%"
+% \end{syntax}
+% Sets the catcode of the <character>, which may have to be escaped.
+% \begin{texnote}
+% "\char_make_other:N" is \LaTeXe's "\@makeother".
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{
% \char_set_lccode:nn |
% \char_set_lccode:w |
% \char_value_lccode:n |
@@ -123,13 +174,13 @@
% \char_show_value_lccode:w
% }
% \begin{syntax}
-% "\char_set_lccode:nn" "{"<char>"}" "{"<number>"}" \\
+% "\char_set_lccode:nn" \Arg{char} \Arg{number} \\
% "\char_set_lccode:w" <char> = <number> \\
-% "\char_value_lccode:n" "{"<char>"}"\\
-% "\char_show_value_lccode:n" "{"<char>"}"
+% "\char_value_lccode:n" \Arg{char}\\
+% "\char_show_value_lccode:n" \Arg{char}
% \end{syntax}
% Set the lower caser representation of <char> for when <char> is
-% being converted in "\tlist_to_lowercase:n". As above, the
+% being converted in "\tl_to_lowercase:n". As above, the
% ":w" form is only for people who really, really know what they are
% doing.
% \begin{texnote}
@@ -146,13 +197,13 @@
% \char_show_value_uccode:w
% }
% \begin{syntax}
-% "\char_set_uccode:nn" "{"<char>"}" "{"<number>"}"\\
+% "\char_set_uccode:nn" \Arg{char} \Arg{number}\\
% "\char_set_uccode:w" <char> = <number> \\
-% "\char_value_uccode:n" "{"<char>"}"\\
-% "\char_show_value_uccode:n" "{"<char>"}"
+% "\char_value_uccode:n" \Arg{char}\\
+% "\char_show_value_uccode:n" \Arg{char}
% \end{syntax}
% Set the uppercase representation of <char> for when <char> is being
-% converted in "\tlist_to_uppercase:n". As above, the ":w"
+% converted in "\tl_to_uppercase:n". As above, the ":w"
% form is only for people who really, really know what they are
% doing.
% \begin{texnote}
@@ -169,10 +220,10 @@
% \char_show_value_sfcode:w
% }
% \begin{syntax}
-% "\char_set_sfcode:nn" "{"<char>"}" "{"<number>"}"\\
+% "\char_set_sfcode:nn" \Arg{char} \Arg{number}\\
% "\char_set_sfcode:w" <char> = <number> \\
-% "\char_value_sfcode:n" "{"<char>"}"\\
-% "\char_show_value_sfcode:n" "{"<char>"}"
+% "\char_value_sfcode:n" \Arg{char}\\
+% "\char_show_value_sfcode:n" \Arg{char}
% \end{syntax}
% Set the space factor for <char>.
% \begin{texnote}
@@ -191,10 +242,10 @@
% \char_show_value_mathcode:w
% }
% \begin{syntax}
-% "\char_set_mathcode:nn" "{"<char>"}" "{"<number>"}"\\
+% "\char_set_mathcode:nn" \Arg{char} \Arg{number}\\
% "\char_set_mathcode:w" <char> = <number> \\
-% "\char_value_mathcode:n" "{"<char>"}"\\
-% "\char_show_value_mathcode:n" "{"<char>"}"
+% "\char_value_mathcode:n" \Arg{char}\\
+% "\char_show_value_mathcode:n" \Arg{char}
% \end{syntax}
% Set the math code for <char>.
% \begin{texnote}
@@ -203,13 +254,13 @@
% \end{function}
%
%
-% \subsection{Generic tokens}
+% \section{Generic tokens}
%
% \begin{function}{%
% \token_new:Nn |
% }
% \begin{syntax}
-% "\token_new:Nn" <token 1> "{"<token 2>"}"
+% "\token_new:Nn" <token 1> \Arg{token 2}
% \end{syntax}
% Defines <token 1> to globally be a snapshot of <token 2>. This will
% be an implicit representation of <token 2>.
@@ -235,217 +286,178 @@
% \end{variable}
%
% \begin{function}{
-% \token_if_group_begin_p:N |
-% \token_if_group_begin:NTF |
-% \token_if_group_begin:NT |
-% \token_if_group_begin:NF |
+% \token_if_group_begin_p:N / (EXP) |
+% \token_if_group_begin:N / (TF) (EXP) |
% }
% \begin{syntax}
-% "\token_if_group_begin:NTF" <token> "{"<true>"}" "{"<false>"}"
+% "\token_if_group_begin:NTF" <token> \Arg{true} \Arg{false}
% \end{syntax}
% Check if <token> is a begin group token.
% \end{function}
%
% \begin{function}{
-% \token_if_group_end_p:N |
-% \token_if_group_end:NTF |
-% \token_if_group_end:NT |
-% \token_if_group_end:NF |
+% \token_if_group_end_p:N / (EXP) |
+% \token_if_group_end:N / (TF) (EXP) |
% }
% \begin{syntax}
-% "\token_if_group_end:NTF" <token> "{"<true>"}" "{"<false>"}"
+% "\token_if_group_end:NTF" <token> \Arg{true} \Arg{false}
% \end{syntax}
% Check if <token> is an end group token.
% \end{function}
%
% \begin{function}{
-% \token_if_math_shift_p:N |
-% \token_if_math_shift:NTF |
-% \token_if_math_shift:NT |
-% \token_if_math_shift:NF |
+% \token_if_math_shift_p:N / (EXP) |
+% \token_if_math_shift:N / (TF) (EXP) |
% }
% \begin{syntax}
-% "\token_if_math_shift:NTF" <token> "{"<true>"}" "{"<false>"}"
+% "\token_if_math_shift:NTF" <token> \Arg{true} \Arg{false}
% \end{syntax}
% Check if <token> is a math shift token.
% \end{function}
%
%
% \begin{function}{
-% \token_if_aligment_tab_p:N |
-% \token_if_aligment_tab:NTF |
-% \token_if_aligment_tab:NT |
-% \token_if_aligment_tab:NF |
+% \token_if_alignment_tab_p:N / (EXP) |
+% \token_if_alignment_tab:N / (TF) (EXP) |
% }
% \begin{syntax}
-% "\token_if_aligment_tab:NTF" <token> "{"<true>"}" "{"<false>"}"
+% "\token_if_aligment_tab:NTF" <token> \Arg{true} \Arg{false}
% \end{syntax}
% Check if <token> is an aligment tab token.
% \end{function}
%
% \begin{function}{
-% \token_if_parameter_p:N |
-% \token_if_parameter:NTF |
-% \token_if_parameter:NT |
-% \token_if_parameter:NF |
+% \token_if_parameter_p:N / (EXP) |
+% \token_if_parameter:N / (TF) (EXP) |
% }
% \begin{syntax}
-% "\token_if_parameter:NTF" <token> "{"<true>"}" "{"<false>"}"
+% "\token_if_parameter:NTF" <token> \Arg{true} \Arg{false}
% \end{syntax}
% Check if <token> is a parameter token.
% \end{function}
%
% \begin{function}{
-% \token_if_math_superscript_p:N |
-% \token_if_math_superscript:NTF |
-% \token_if_math_superscript:NT |
-% \token_if_math_superscript:NF |
+% \token_if_math_superscript_p:N / (EXP) |
+% \token_if_math_superscript:N / (TF) (EXP) |
% }
% \begin{syntax}
-% "\token_if_math_superscript:NTF" <token> "{"<true>"}" "{"<false>"}"
+% "\token_if_math_superscript:NTF" <token> \Arg{true} \Arg{false}
% \end{syntax}
% Check if <token> is a math superscript token.
% \end{function}
%
% \begin{function}{
-% \token_if_math_subscript_p:N |
-% \token_if_math_subscript:NTF |
-% \token_if_math_subscript:NT |
-% \token_if_math_subscript:NF |
+% \token_if_math_subscript_p:N / (EXP) |
+% \token_if_math_subscript:N / (TF) (EXP) |
% }
% \begin{syntax}
-% "\token_if_math_subscript:NTF" <token> "{"<true>"}" "{"<false>"}"
+% "\token_if_math_subscript:NTF" <token> \Arg{true} \Arg{false}
% \end{syntax}
% Check if <token> is a math subscript token.
% \end{function}
%
% \begin{function}{
-% \token_if_space_p:N |
-% \token_if_space:NTF |
-% \token_if_space:NT |
-% \token_if_space:NF |
+% \token_if_space_p:N / (EXP) |
+% \token_if_space:N / (TF) (EXP) |
% }
% \begin{syntax}
-% "\token_if_space:NTF" <token> "{"<true>"}" "{"<false>"}"
+% "\token_if_space:NTF" <token> \Arg{true} \Arg{false}
% \end{syntax}
% Check if <token> is a space token.
% \end{function}
%
%
% \begin{function}{
-% \token_if_letter_p:N |
-% \token_if_letter:NTF |
-% \token_if_letter:NT |
-% \token_if_letter:NF |
+% \token_if_letter_p:N / (EXP) |
+% \token_if_letter:N / (TF) (EXP) |
% }
% \begin{syntax}
-% "\token_if_letter:NTF" <token> "{"<true>"}" "{"<false>"}"
+% "\token_if_letter:NTF" <token> \Arg{true} \Arg{false}
% \end{syntax}
% Check if <token> is a letter token.
% \end{function}
%
%
% \begin{function}{
-% \token_if_other_char_p:N |
-% \token_if_other_char:NTF |
-% \token_if_other_char:NT |
-% \token_if_other_char:NF |
+% \token_if_other_char_p:N / (EXP) |
+% \token_if_other_char:N / (TF) (EXP) |
% }
% \begin{syntax}
-% "\token_if_other_char:NTF" <token> "{"<true>"}" "{"<false>"}"
+% "\token_if_other_char:NTF" <token> \Arg{true} \Arg{false}
% \end{syntax}
% Check if <token> is an other char token.
% \end{function}
%
% \begin{function}{
-% \token_if_active_char_p:N |
-% \token_if_active_char:NTF |
-% \token_if_active_char:NT |
-% \token_if_active_char:NF |
+% \token_if_active_char_p:N / (EXP) |
+% \token_if_active_char:N / (TF) (EXP) |
% }
% \begin{syntax}
-% "\token_if_active_char:NTF" <token> "{"<true>"}" "{"<false>"}"
+% "\token_if_active_char:NTF" <token> \Arg{true} \Arg{false}
% \end{syntax}
% Check if <token> is an active char token.
% \end{function}
%
-%
% \begin{function}{%
-% \token_if_eq_meaning_p:NN |
-% \token_if_eq_meaning:NNTF |
-% \token_if_eq_meaning:NNT |
-% \token_if_eq_meaning:NNF
+% \token_if_eq_meaning_p:NN / (EXP) |
+% \token_if_eq_meaning:NN / (TF) (EXP)
% }
% \begin{syntax}
-% "\token_if_eq_meaning:NNTF" <token1> <token2>"{"<true>"}""{"<false>"}"
+% "\token_if_eq_meaning:NNTF" <token1> <token2>\Arg{true} \Arg{false}
% \end{syntax}
% Check if the meaning of two tokens are identical.
% \end{function}
%
% \begin{function}{%
-% \token_if_eq_catcode_p:NN |
-% \token_if_eq_catcode:NNTF |
-% \token_if_eq_catcode:NNT |
-% \token_if_eq_catcode:NNF
+% \token_if_eq_catcode_p:NN / (EXP) |
+% \token_if_eq_catcode:NN / (TF) (EXP)
% }
% \begin{syntax}
-% "\token_if_eq_catcode:NNTF" <token1> <token2>"{"<true>"}""{"<false>"}"
+% "\token_if_eq_catcode:NNTF" <token1> <token2>\Arg{true} \Arg{false}
% \end{syntax}
% Check if the category codes of two tokens are equal. If both tokens
% are control sequences the test will be true.
% \end{function}
%
% \begin{function}{%
-% \token_if_eq_charcode_p:NN |
-% \token_if_eq_catcode:NNTF |
-% \token_if_eq_catcode:NNT |
-% \token_if_eq_catcode:NNF
+% \token_if_eq_charcode_p:NN / (EXP) |
+% \token_if_eq_charcode:NN / (TF) (EXP)
% }
% \begin{syntax}
-% "\token_if_eq_catcode:NNTF" <token1> <token2>"{"<true>"}""{"<false>"}"
+% "\token_if_eq_catcode:NNTF" <token1> <token2>\Arg{true} \Arg{false}
% \end{syntax}
% Check if the character codes of two tokens are equal. If both tokens
% are control sequences the test will be true.
% \end{function}
%
% \begin{function}{
-% \token_if_macro_p:N |
-% \token_if_macro:NTF |
-% \token_if_macro:NT |
-% \token_if_macro:NF |
+% \token_if_macro_p:N / (EXP) |
+% \token_if_macro:N / (TF) (EXP) |
% }
% \begin{syntax}
-% "\token_if_macro:NTF" <token> "{"<true>"}" "{"<false>"}"
+% "\token_if_macro:NTF" <token> \Arg{true} \Arg{false}
% \end{syntax}
% Check if <token> is a macro.
% \end{function}
%
-%
% \begin{function}{
-% \token_if_cs_p:N |
-% \token_if_cs:NTF |
-% \token_if_cs:NT |
-% \token_if_cs:NF |
+% \token_if_cs_p:N / (EXP) |
+% \token_if_cs:N / (TF) (EXP) |
% }
% \begin{syntax}
-% "\token_if_cs:NTF" <token> "{"<true>"}" "{"<false>"}"
+% "\token_if_cs:NTF" <token> \Arg{true} \Arg{false}
% \end{syntax}
% Check if <token> is a control sequence or not. This can be useful
% for situations where the next token in the input stream is being
% looked at and you want to determine what should be done to it.
% \end{function}
%
-%
-%
-%
% \begin{function}{
-% \token_if_expandable_p:N |
-% \token_if_expandable:NTF |
-% \token_if_expandable:NT |
-% \token_if_expandable:NF
+% \token_if_expandable_p:N / (EXP) |
+% \token_if_expandable:N / (TF) (EXP)
% }
% \begin{syntax}
-% "\token_if_expandable:NTF" <token> "{"<true>"}" "{"<false>"}"
+% "\token_if_expandable:NTF" <token> \Arg{true} \Arg{false}
% \end{syntax}
% Check if <token> is expandable or not. Note that <token> can very
% well be an active character.
@@ -460,151 +472,130 @@
% \m{toks} register at all?
%
% \begin{function}{
-% \token_if_long_macro_p:N |
-% \token_if_long_macro:NTF |
-% \token_if_long_macro:NT |
-% \token_if_long_macro:NF |
+% \token_if_long_macro_p:N / (EXP) |
+% \token_if_long_macro:N / (TF) (EXP) |
% }
% \begin{syntax}
-% "\token_if_long_macro:NTF" <token> "{"<true>"}" "{"<false>"}"
+% "\token_if_long_macro:NTF" <token> \Arg{true} \Arg{false}
% \end{syntax}
% Check if <token> is a ``long'' macro.
% \end{function}
%
%
% \begin{function}{
-% \token_if_protected_macro_p:N |
-% \token_if_protected_macro:NTF |
-% \token_if_protected_macro:NT |
-% \token_if_protected_macro:NF |
+% \token_if_protected_macro_p:N / (EXP) |
+% \token_if_protected_macro:N / (TF) (EXP) |
% }
% \begin{syntax}
-% "\token_if_long_macro:NTF" <token> "{"<true>"}" "{"<false>"}"
+% "\token_if_long_macro:NTF" <token> \Arg{true} \Arg{false}
% \end{syntax}
% Check if <token> is a ``protected'' macro. This test does \emph{not}
% return <true> if the macro is also ``long'', see below.
% \end{function}
%
% \begin{function}{
-% \token_if_protected_long_macro_p:N |
-% \token_if_protected_long_macro:NTF |
-% \token_if_protected_long_macro:NT |
-% \token_if_protected_long_macro:NF |
+% \token_if_protected_long_macro_p:N / (EXP) |
+% \token_if_protected_long_macro:N / (TF) (EXP) |
% }
% \begin{syntax}
-% "\token_if_protected_long_macro:NTF" <token> "{"<true>"}" "{"<false>"}"
+% "\token_if_protected_long_macro:NTF" <token> \Arg{true} \Arg{false}
% \end{syntax}
% Check if <token> is a ``protected long'' macro.
% \end{function}
%
% \begin{function}{
-% \token_if_chardef_p:N |
-% \token_if_chardef:NTF |
-% \token_if_chardef:NT |
-% \token_if_chardef:NF |
+% \token_if_chardef_p:N / (EXP) |
+% \token_if_chardef:N / (TF) (EXP) |
% }
% \begin{syntax}
-% "\token_if_chardef:NTF" <token> "{"<true>"}" "{"<false>"}"
+% "\token_if_chardef:NTF" <token> \Arg{true} \Arg{false}
% \end{syntax}
% Check if <token> is defined to be a chardef.
% \end{function}
%
% \begin{function}{
-% \token_if_mathchardef_p:N |
-% \token_if_mathchardef:NTF |
-% \token_if_mathchardef:NT |
-% \token_if_mathchardef:NF |
+% \token_if_mathchardef_p:N / (EXP) |
+% \token_if_mathchardef:N / (TF) (EXP) |
% }
% \begin{syntax}
-% "\token_if_mathchardef:NTF" <token> "{"<true>"}" "{"<false>"}"
+% "\token_if_mathchardef:NTF" <token> \Arg{true} \Arg{false}
% \end{syntax}
% Check if <token> is defined to be a mathchardef.
% \end{function}
%
% \begin{function}{
-% \token_if_int_register_p:N |
-% \token_if_int_register:NTF |
-% \token_if_int_register:NT |
-% \token_if_int_register:NF |
+% \token_if_int_register_p:N / (EXP) |
+% \token_if_int_register:N / (TF) (EXP) |
% }
% \begin{syntax}
-% "\token_if_int_register:NTF" <token> "{"<true>"}" "{"<false>"}"
+% "\token_if_int_register:NTF" <token> \Arg{true} \Arg{false}
% \end{syntax}
% Check if <token> is defined to be an integer register.
% \end{function}
%
% \begin{function}{
-% \token_if_dim_register_p:N |
-% \token_if_dim_register:NTF |
-% \token_if_dim_register:NT |
-% \token_if_dim_register:NF |
+% \token_if_dim_register_p:N / (EXP) |
+% \token_if_dim_register:N / (TF) (EXP) |
% }
% \begin{syntax}
-% "\token_if_dim_register:NTF" <token> "{"<true>"}" "{"<false>"}"
+% "\token_if_dim_register:NTF" <token> \Arg{true} \Arg{false}
% \end{syntax}
% Check if <token> is defined to be a dimension register.
% \end{function}
%
% \begin{function}{
-% \token_if_skip_register_p:N |
-% \token_if_skip_register:NTF |
-% \token_if_skip_register:NT |
-% \token_ifskip_register:NF |
+% \token_if_skip_register_p:N / (EXP) |
+% \token_if_skip_register:N / (TF) (EXP) |
% }
% \begin{syntax}
-% "\token_if_skip_register:NTF" <token> "{"<true>"}" "{"<false>"}"
+% "\token_if_skip_register:NTF" <token> \Arg{true} \Arg{false}
% \end{syntax}
% Check if <token> is defined to be a skip register.
% \end{function}
%
% \begin{function}{
-% \token_if_toks_register_p:N |
-% \token_if_toks_register:NTF |
-% \token_if_toks_register:NT |
-% \token_if_toks_register:NF |
+% \token_if_toks_register_p:N / (EXP) |
+% \token_if_toks_register:N / (TF) (EXP) |
% }
% \begin{syntax}
-% "\token_if_toks_register:NTF" <token> "{"<true>"}" "{"<false>"}"
+% "\token_if_toks_register:NTF" <token> \Arg{true} \Arg{false}
% \end{syntax}
% Check if <token> is defined to be a toks register.
% \end{function}
%
%
% \begin{function}{
-% \token_get_prefix_spec:N |
-% \token_get_arg_spec:N |
-% \token_get_replacement_spec:N
+% \token_get_prefix_spec:N / (EXP) |
+% \token_get_arg_spec:N / (EXP) |
+% \token_get_replacement_spec:N / (EXP)
% }
% \begin{syntax}
% "\token_get_arg_spec:N" <token>
% \end{syntax}
-% If token is a macro with definition |\def_long:Npn||\next|
+% If token is a macro with definition |\cs_set:Npn||\next|
% |#1#2{x`#1--#2'y}|, the |prefix| function will return the string
% |\long|, the |arg| function returns the string |#1#2| and the
% |replacement| function returns the string |x`#1--#2'y|. If <token>
% isn't a macro, these functions return the |\scan_stop:| token.
+%
+% If the |arg_spec| contains the string |->|, then the |spec| function
+% will produce incorrect results.
% \end{function}
%
-% \subsubsection{Useless code: because we can!}
+% \subsection{Useless code: because we can!}
%
% \begin{function}{
-% \token_if_primitive_p:N |
-% \token_if_primitive:NTF |
-% \token_if_primitive:NT |
-% \token_if_primitive:NF |
+% \token_if_primitive_p:N / (EXP) |
+% \token_if_primitive:N / (TF) (EXP) |
% }
% \begin{syntax}
-% "\token_if_primitive:NTF" <token> "{"<true>"}" "{"<false>"}"
+% "\token_if_primitive:NTF" <token> \Arg{true} \Arg{false}
% \end{syntax}
% Check if <token> is a primitive. Probably not a very useful function.
% \end{function}
%
%
-% \subsection{Peeking ahead at the next token}
-%
-%
-%
-%
+% \section{Peeking ahead at the next token}
%
% \begin{variable}{%
% \l_peek_token |
@@ -634,43 +625,46 @@
% \end{function}
%
% \begin{function}{%
-% \peek_meaning:NTF |
-% \peek_meaning_ignore_spaces:NTF |
-% \peek_meaning_remove:NTF |
-% \peek_meaning_remove_ignore_spaces:NTF
+% \peek_meaning:N / (TF) |
+% \peek_meaning_ignore_spaces:N / (TF) |
+% \peek_meaning_remove:N / (TF) |
+% \peek_meaning_remove_ignore_spaces:N / (TF)
% }
% \begin{syntax}
-% "\peek_meaning:NTF" <token> "{"<true>"}""{"<false>"}"
+% "\peek_meaning:NTF" <token> \Arg{true} \Arg{false}
% \end{syntax}
-% "\peek_meaning:NTF" checks (by using "\if_meaning:NN") if <token>
+% "\peek_meaning:NTF" checks (by using "\if_meaning:w") if <token>
% equals the next token in the input stream and executes either <true
% code> or <false code> accordingly. "\peek_meaning_remove:NTF" does
% the same but additionally removes the token if found. The
% "ignore_spaces" versions skips blank spaces before making the
% decision.
+% \begin{texnote}
+% This is equivalent to \LaTeXe's \tn{@ifnextchar}.
+% \end{texnote}
% \end{function}
%
% \begin{function}{%
-% \peek_charcode:NTF |
-% \peek_charcode_ignore_spaces:NTF |
-% \peek_charcode_remove:NTF |
-% \peek_charcode_remove_ignore_spaces:NTF
+% \peek_charcode:N / (TF) |
+% \peek_charcode_ignore_spaces:N / (TF) |
+% \peek_charcode_remove:N / (TF) |
+% \peek_charcode_remove_ignore_spaces:N / (TF)
% }
% \begin{syntax}
-% "\peek_charcode:NTF" <token> "{"<true>"}""{"<false>"}"
+% "\peek_charcode:NTF" <token> \Arg{true} \Arg{false}
% \end{syntax}
% Same as for the "\peek_meaning:NTF" functions above but these use
% "\if_charcode:w" to compare the tokens.
% \end{function}
%
% \begin{function}{%
-% \peek_catcode:NTF |
-% \peek_catcode_ignore_spaces:NTF |
-% \peek_catcode_remove:NTF |
-% \peek_catcode_remove_ignore_spaces:NTF
+% \peek_catcode:N / (TF) |
+% \peek_catcode_ignore_spaces:N / (TF) |
+% \peek_catcode_remove:N / (TF) |
+% \peek_catcode_remove_ignore_spaces:N / (TF)
% }
% \begin{syntax}
-% "\peek_catcode:NTF" <token> "{"<true>"}""{"<false>"}"
+% "\peek_catcode:NTF" <token> \Arg{true} \Arg{false}
% \end{syntax}
% Same as for the "\peek_meaning:NTF" functions above but these use
% "\if_catcode:w" to compare the tokens.
@@ -678,11 +672,11 @@
%
%
% \begin{function}{%
-% \peek_token_generic:NNTF |
-% \peek_token_remove_generic:NNTF
+% \peek_token_generic:NN / (TF) |
+% \peek_token_remove_generic:NN / (TF)
% }
% \begin{syntax}
-% "\peek_token_generic:NNTF" <token><function> "{"<true>"}""{"<false>"}"
+% "\peek_token_generic:NNTF" <token><function> \Arg{true} \Arg{false}
% \end{syntax}
% "\peek_token_generic:NNTF" looks ahead and checks if the next token
% in the input stream is equal to <token>. It uses <function> to make
@@ -706,219 +700,259 @@
% meaning, character code, and category code.
% \end{function}
%
+% \end{documentation}
%
+% \begin{implementation}
%
+% \section{\pkg{l3token} implementation}
%
-% \subsubsection{Internal functions}
-%
-% \begin{variable}{%
-% \l_peek_true_tlp |
-% \l_peek_false_tlp |
-% }
-% \begin{syntax}
-% \end{syntax}
-% These token list pointers are used internally when choosing either
-% the true or false branches of a test.
-% \end{variable}
-%
-% \begin{function}{%
-% \peek_tmp:w |
-% }
-% \begin{syntax}
-% \end{syntax}
-% Scratch function used to gobble tokens from the input stream.
-% \end{function}
-%
-% \begin{variable}{%
-% \l_peek_true_aux_tlp |
-% \l_peek_true_remove_next_tlp |
-% }
-% \begin{syntax}
-% \end{syntax}
-% These token list pointers are used internally when choosing either
-% the true or false branches of a test.
-% \end{variable}
-%
-% \begin{function}{%
-% \peek_ignore_spaces_execute_branches: |
-% \peek_ignore_spaces_aux: |
-% }
-% \begin{syntax}
-% \end{syntax}
-% Functions used to ignore space tokens in the input stream.
-% \end{function}
-%
-%
+% \subsection{Documentation of internal functions}
%
-% \StopEventually{}
+% \begin{variable}{%
+% \l_peek_true_tl |
+% \l_peek_false_tl |
+% }
+% \begin{syntax}
+% \end{syntax}
+% These token list variables are used internally when choosing either
+% the true or false branches of a test.
+% \end{variable}
+%
+% \begin{variable}{ \l_peek_search_tl }
+% \begin{syntax}
+% \end{syntax}
+% Used to store "\l_peek_search_token".
+% \end{variable}
+%
+% \begin{function}{%
+% \peek_tmp:w |
+% }
+% \begin{syntax}
+% \end{syntax}
+% Scratch function used to gobble tokens from the input stream.
+% \end{function}
+%
+% \begin{variable}{%
+% \l_peek_true_aux_tl |
+% \c_peek_true_remove_next_tl |
+% }
+% \begin{syntax}
+% \end{syntax}
+% These token list variables are used internally when choosing either
+% the true or false branches of a test.
+% \end{variable}
+%
+% \begin{function}{%
+% \peek_ignore_spaces_execute_branches: |
+% \peek_ignore_spaces_aux: |
+% }
+% \begin{syntax}
+% \end{syntax}
+% Functions used to ignore space tokens in the input stream.
+% \end{function}
%
+% \subsection{Module code}
%
-% \subsection{Implementation}
% First a few required packages to get this going.
% \begin{macrocode}
-%<package>\ProvidesExplPackage
-%<package> {\filename}{\filedate}{\fileversion}{\filedescription}
-%<package>\RequirePackage{l3prg}
-%<package>\RequirePackage{l3int}
+%<*package>
+\ProvidesExplPackage
+ {\filename}{\filedate}{\fileversion}{\filedescription}
+\package_check_loaded_expl:
+%</package>
%<*initex|package>
% \end{macrocode}
%
-% \subsubsection{Character tokens}
+% \subsection{Character tokens}
%
-% \begin{macro}{\char_set_catcode:w}
-% \begin{macro}{\char_set_catcode:nn}
-% \begin{macro}{\char_value_catcode:w}
-% \begin{macro}{\char_value_catcode:n}
-% \begin{macro}{\char_show_value_catcode:w}
-% \begin{macro}{\char_show_value_catcode:n}
+% \begin{macro}{ \char_set_catcode:w ,
+% \char_set_catcode:nn ,
+% \char_value_catcode:w ,
+% \char_value_catcode:n ,
+% \char_show_value_catcode:w ,
+% \char_show_value_catcode:n }
% \begin{macrocode}
-\let_new:NN \char_set_catcode:w \tex_catcode:D
-\def_new:Npn \char_set_catcode:nn #1#2{
- \char_set_catcode:w #1 = \int_eval:n{#2}
+\cs_new_eq:NN \char_set_catcode:w \tex_catcode:D
+\cs_new_nopar:Npn \char_set_catcode:nn #1#2 {
+ \char_set_catcode:w #1 = \intexpr_eval:w #2\intexpr_eval_end:
+}
+\cs_new_nopar:Npn \char_value_catcode:w { \int_use:N \tex_catcode:D }
+\cs_new_nopar:Npn \char_value_catcode:n #1 {
+ \char_value_catcode:w \intexpr_eval:w #1\intexpr_eval_end:
+}
+\cs_new_nopar:Npn \char_show_value_catcode:w {
+ \tex_showthe:D \tex_catcode:D
+}
+\cs_new_nopar:Npn \char_show_value_catcode:n #1 {
+ \char_show_value_catcode:w \intexpr_eval:w #1\intexpr_eval_end:
}
-\def_new:Npn \char_value_catcode:w {\int_use:N\tex_catcode:D}
-\def_new:Npn \char_value_catcode:n #1{\char_value_catcode:w \int_eval:n{#1}}
-\def_new:Npn \char_show_value_catcode:w {\tex_showthe:D\tex_catcode:D}
-\def_new:Npn \char_show_value_catcode:n #1{
- \char_show_value_catcode:w \int_eval:n{#1}}
% \end{macrocode}
% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
%
-% \begin{macro}{\char_set_mathcode:w}
-% \begin{macro}{\char_set_mathcode:nn}
-% \begin{macro}{\char_gset_mathcode:w}
-% \begin{macro}{\char_gset_mathcode:nn}
-% \begin{macro}{\char_value_mathcode:w}
-% \begin{macro}{\char_value_mathcode:n}
-% \begin{macro}{\char_show_value_mathcode:w}
-% \begin{macro}{\char_show_value_mathcode:n}
+% \begin{macro}{ \char_make_escape:N , \char_make_begin_group:N ,
+% \char_make_end_group:N , \char_make_math_shift: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{macrocode}
+\cs_new_nopar:Npn \char_make_escape:N #1 { \char_set_catcode:nn {`#1} {\c_zero} }
+\cs_new_nopar:Npn \char_make_begin_group:N #1 { \char_set_catcode:nn {`#1} {\c_one} }
+\cs_new_nopar:Npn \char_make_end_group:N #1 { \char_set_catcode:nn {`#1} {\c_two} }
+\cs_new_nopar:Npn \char_make_math_shift:N #1 { \char_set_catcode:nn {`#1} {\c_three} }
+\cs_new_nopar:Npn \char_make_alignment:N #1 { \char_set_catcode:nn {`#1} {\c_four} }
+\cs_new_nopar:Npn \char_make_end_line:N #1 { \char_set_catcode:nn {`#1} {\c_five} }
+\cs_new_nopar:Npn \char_make_parameter:N #1 { \char_set_catcode:nn {`#1} {\c_six} }
+\cs_new_nopar:Npn \char_make_math_superscript:N #1 { \char_set_catcode:nn {`#1} {\c_seven} }
+\cs_new_nopar:Npn \char_make_math_subscript:N #1 { \char_set_catcode:nn {`#1} {\c_eight} }
+\cs_new_nopar:Npn \char_make_ignore:N #1 { \char_set_catcode:nn {`#1} {\c_nine} }
+\cs_new_nopar:Npn \char_make_space:N #1 { \char_set_catcode:nn {`#1} {\c_ten} }
+\cs_new_nopar:Npn \char_make_letter:N #1 { \char_set_catcode:nn {`#1} {\c_eleven} }
+\cs_new_nopar:Npn \char_make_other:N #1 { \char_set_catcode:nn {`#1} {\c_twelve} }
+\cs_new_nopar:Npn \char_make_active:N #1 { \char_set_catcode:nn {`#1} {\c_thirteen} }
+\cs_new_nopar:Npn \char_make_comment:N #1 { \char_set_catcode:nn {`#1} {\c_fourteen} }
+\cs_new_nopar:Npn \char_make_invalid:N #1 { \char_set_catcode:nn {`#1} {\c_fifteen} }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{ \char_make_escape:n , \char_make_begin_group:n ,
+% \char_make_end_group:n , \char_make_math_shift: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{macrocode}
+\cs_new_nopar:Npn \char_make_escape:n #1 { \char_set_catcode:nn {#1} {\c_zero} }
+\cs_new_nopar:Npn \char_make_begin_group:n #1 { \char_set_catcode:nn {#1} {\c_one} }
+\cs_new_nopar:Npn \char_make_end_group:n #1 { \char_set_catcode:nn {#1} {\c_two} }
+\cs_new_nopar:Npn \char_make_math_shift:n #1 { \char_set_catcode:nn {#1} {\c_three} }
+\cs_new_nopar:Npn \char_make_alignment:n #1 { \char_set_catcode:nn {#1} {\c_four} }
+\cs_new_nopar:Npn \char_make_end_line:n #1 { \char_set_catcode:nn {#1} {\c_five} }
+\cs_new_nopar:Npn \char_make_parameter:n #1 { \char_set_catcode:nn {#1} {\c_six} }
+\cs_new_nopar:Npn \char_make_math_superscript:n #1 { \char_set_catcode:nn {#1} {\c_seven} }
+\cs_new_nopar:Npn \char_make_math_subscript:n #1 { \char_set_catcode:nn {#1} {\c_eight} }
+\cs_new_nopar:Npn \char_make_ignore:n #1 { \char_set_catcode:nn {#1} {\c_nine} }
+\cs_new_nopar:Npn \char_make_space:n #1 { \char_set_catcode:nn {#1} {\c_ten} }
+\cs_new_nopar:Npn \char_make_letter:n #1 { \char_set_catcode:nn {#1} {\c_eleven} }
+\cs_new_nopar:Npn \char_make_other:n #1 { \char_set_catcode:nn {#1} {\c_twelve} }
+\cs_new_nopar:Npn \char_make_active:n #1 { \char_set_catcode:nn {#1} {\c_thirteen} }
+\cs_new_nopar:Npn \char_make_comment:n #1 { \char_set_catcode:nn {#1} {\c_fourteen} }
+\cs_new_nopar:Npn \char_make_invalid:n #1 { \char_set_catcode:nn {#1} {\c_fifteen} }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\char_set_mathcode:w,
+% \char_set_mathcode:nn,
+% \char_gset_mathcode:w,
+% \char_gset_mathcode:nn,
+% \char_value_mathcode:w,
+% \char_value_mathcode:n,
+% \char_show_value_mathcode:w,
+% \char_show_value_mathcode:n}
% Math codes.
% \begin{macrocode}
-\let_new:NN \char_set_mathcode:w \tex_mathcode:D
-\def_new:Npn \char_set_mathcode:nn #1#2{
- \char_set_mathcode:w #1 = \int_eval:n{#2}
+\cs_new_eq:NN \char_set_mathcode:w \tex_mathcode:D
+\cs_new_nopar:Npn \char_set_mathcode:nn #1#2 {
+ \char_set_mathcode:w #1 = \intexpr_eval:w #2\intexpr_eval_end:
+}
+\cs_new_protected_nopar:Npn \char_gset_mathcode:w { \pref_global:D \tex_mathcode:D }
+\cs_new_nopar:Npn \char_gset_mathcode:nn #1#2 {
+ \char_gset_mathcode:w #1 = \intexpr_eval:w #2\intexpr_eval_end:
}
-\def_protected_new:Npn \char_gset_mathcode:w {\pref_global:D\tex_mathcode:D}
-\def_new:Npn \char_gset_mathcode:nn #1#2{
- \char_gset_mathcode:w #1 = \int_eval:n{#2}
+\cs_new_nopar:Npn \char_value_mathcode:w { \int_use:N \tex_mathcode:D }
+\cs_new_nopar:Npn \char_value_mathcode:n #1 {
+ \char_value_mathcode:w \intexpr_eval:w #1\intexpr_eval_end:
+}
+\cs_new_nopar:Npn \char_show_value_mathcode:w { \tex_showthe:D \tex_mathcode:D }
+\cs_new_nopar:Npn \char_show_value_mathcode:n #1 {
+ \char_show_value_mathcode:w \intexpr_eval:w #1\intexpr_eval_end:
}
-\def_new:Npn \char_value_mathcode:w {\int_use:N\tex_mathcode:D}
-\def_new:Npn \char_value_mathcode:n #1{\char_value_mathcode:w \int_eval:n{#1}}
-\def_new:Npn \char_show_value_mathcode:w {\tex_showthe:D\tex_mathcode:D}
-\def_new:Npn \char_show_value_mathcode:n #1{
- \char_show_value_mathcode:w \int_eval:n{#1}}
% \end{macrocode}
% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
%
-% \begin{macro}{\char_set_lccode:w}
-% \begin{macro}{\char_set_lccode:nn}
-% \begin{macro}{\char_value_lccode:w}
-% \begin{macro}{\char_value_lccode:n}
-% \begin{macro}{\char_show_value_lccode:w}
-% \begin{macro}{\char_show_value_lccode:n}
+% \begin{macro}{\char_set_lccode:w, \char_set_lccode:nn,
+% \char_value_lccode:w, \char_value_lccode:n,
+% \char_show_value_lccode:w, \char_show_value_lccode:n}
% \begin{macrocode}
-\let_new:NN \char_set_lccode:w \tex_lccode:D
-\def_new:Npn \char_set_lccode:nn #1#2{
- \char_set_lccode:w #1 = \int_eval:n{#2}
+\cs_new_eq:NN \char_set_lccode:w \tex_lccode:D
+\cs_new_nopar:Npn \char_set_lccode:nn #1#2{
+ \char_set_lccode:w #1 = \intexpr_eval:w #2\intexpr_eval_end:
}
-\def_new:Npn \char_value_lccode:w {\int_use:N\tex_lccode:D}
-\def_new:Npn \char_value_lccode:n #1{\char_value_lccode:w \int_eval:n{#1}}
-\def_new:Npn \char_show_value_lccode:w {\tex_showthe:D\tex_lccode:D}
-\def_new:Npn \char_show_value_lccode:n #1{
- \char_show_value_lccode:w \int_eval:n{#1}}
+\cs_new_nopar:Npn \char_value_lccode:w {\int_use:N\tex_lccode:D}
+\cs_new_nopar:Npn \char_value_lccode:n #1{\char_value_lccode:w
+ \intexpr_eval:w #1\intexpr_eval_end:}
+\cs_new_nopar:Npn \char_show_value_lccode:w {\tex_showthe:D\tex_lccode:D}
+\cs_new_nopar:Npn \char_show_value_lccode:n #1{
+ \char_show_value_lccode:w \intexpr_eval:w #1\intexpr_eval_end:}
% \end{macrocode}
% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
%
-% \begin{macro}{\char_set_uccode:w}
-% \begin{macro}{\char_set_uccode:nn}
-% \begin{macro}{\char_value_uccode:w}
-% \begin{macro}{\char_value_uccode:n}
-% \begin{macro}{\char_show_value_uccode:w}
-% \begin{macro}{\char_show_value_uccode:n}
+% \begin{macro}{\char_set_uccode:w, \char_set_uccode:nn,
+% \char_value_uccode:w, \char_value_uccode:n,
+% \char_show_value_uccode:w, \char_show_value_uccode:n }
% \begin{macrocode}
-\let_new:NN \char_set_uccode:w \tex_uccode:D
-\def_new:Npn \char_set_uccode:nn #1#2{
- \char_set_uccode:w #1 = \int_eval:n{#2}
+\cs_new_eq:NN \char_set_uccode:w \tex_uccode:D
+\cs_new_nopar:Npn \char_set_uccode:nn #1#2{
+ \char_set_uccode:w #1 = \intexpr_eval:w #2\intexpr_eval_end:
}
-\def_new:Npn \char_value_uccode:w {\int_use:N\tex_uccode:D}
-\def_new:Npn \char_value_uccode:n #1{\char_value_uccode:w \int_eval:n{#1}}
-\def_new:Npn \char_show_value_uccode:w {\tex_showthe:D\tex_uccode:D}
-\def_new:Npn \char_show_value_uccode:n #1{
- \char_show_value_uccode:w \int_eval:n{#1}}
+\cs_new_nopar:Npn \char_value_uccode:w {\int_use:N\tex_uccode:D}
+\cs_new_nopar:Npn \char_value_uccode:n #1{\char_value_uccode:w
+ \intexpr_eval:w #1\intexpr_eval_end:}
+\cs_new_nopar:Npn \char_show_value_uccode:w {\tex_showthe:D\tex_uccode:D}
+\cs_new_nopar:Npn \char_show_value_uccode:n #1{
+ \char_show_value_uccode:w \intexpr_eval:w #1\intexpr_eval_end:}
% \end{macrocode}
% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
%
-% \begin{macro}{\char_set_sfcode:w}
-% \begin{macro}{\char_set_sfcode:nn}
-% \begin{macro}{\char_value_sfcode:w}
-% \begin{macro}{\char_value_sfcode:n}
-% \begin{macro}{\char_show_value_sfcode:w}
-% \begin{macro}{\char_show_value_sfcode:n}
+% \begin{macro}{\char_set_sfcode:w, \char_set_sfcode:nn,
+% \char_value_sfcode:w, \char_value_sfcode:n,
+% \char_show_value_sfcode:w, \char_show_value_sfcode:n}
% \begin{macrocode}
-\let_new:NN \char_set_sfcode:w \tex_sfcode:D
-\def_new:Npn \char_set_sfcode:nn #1#2{
- \char_set_sfcode:w #1 = \int_eval:n{#2}
+\cs_new_eq:NN \char_set_sfcode:w \tex_sfcode:D
+\cs_new_nopar:Npn \char_set_sfcode:nn #1#2 {
+ \char_set_sfcode:w #1 = \intexpr_eval:w #2\intexpr_eval_end:
+}
+\cs_new_nopar:Npn \char_value_sfcode:w { \int_use:N \tex_sfcode:D }
+\cs_new_nopar:Npn \char_value_sfcode:n #1 {
+ \char_value_sfcode:w \intexpr_eval:w #1\intexpr_eval_end:
+}
+\cs_new_nopar:Npn \char_show_value_sfcode:w { \tex_showthe:D \tex_sfcode:D }
+\cs_new_nopar:Npn \char_show_value_sfcode:n #1 {
+ \char_show_value_sfcode:w \intexpr_eval:w #1\intexpr_eval_end:
}
-\def_new:Npn \char_value_sfcode:w {\int_use:N\tex_uccode:D}
-\def_new:Npn \char_value_sfcode:n #1{\char_value_sfcode:w \int_eval:n{#1}}
-\def_new:Npn \char_show_value_sfcode:w {\tex_showthe:D\tex_sfcode:D}
-\def_new:Npn \char_show_value_sfcode:n #1{
- \char_show_value_sfcode:w \int_eval:n{#1}}
% \end{macrocode}
% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-% \subsubsection{Generic tokens}
%
+% \subsection{Generic tokens}
%
% \begin{macro}{\token_new:Nn}
-% Creates a new token.
+% Creates a new token. (Will: why can't this just be
+% "\cs_new_eq:NN \token_new:Nn \cs_gnew_eq:NN"? Seriously, that doesn't work!)
% \begin{macrocode}
-\def_new:Npn \token_new:Nn #1#2{\glet_new:NN #1#2}
+\cs_new_nopar:Npn \token_new:Nn #1#2 {\cs_gnew_eq:NN #1#2}
% \end{macrocode}
% \end{macro}
-% \begin{macro}{\c_group_begin_token}
-% \begin{macro}{\c_group_end_token}
-% \begin{macro}{\c_math_shift_token}
-% \begin{macro}{\c_alignment_tab_token}
-% \begin{macro}{\c_parameter_token}
-% \begin{macro}{\c_math_superscript_token}
-% \begin{macro}{\c_math_subscript_token}
-% \begin{macro}{\c_space_token}
-% \begin{macro}{\c_letter_token}
-% \begin{macro}{\c_other_char_token}
-% \begin{macro}{\c_active_char_token}
+%
+% \begin{macro}{\c_group_begin_token,
+% \c_group_end_token,
+% \c_math_shift_token,
+% \c_alignment_tab_token,
+% \c_parameter_token,
+% \c_math_superscript_token,
+% \c_math_subscript_token,
+% \c_space_token,
+% \c_letter_token,
+% \c_other_char_token,
+% \c_active_char_token }
% We define these useful tokens. We have to do it by hand with the
% brace tokens for obvious reasons.
% \begin{macrocode}
-\let_new:NN \c_group_begin_token {
-\let_new:NN \c_group_end_token }
+\cs_new_eq:NN \c_group_begin_token {
+\cs_new_eq:NN \c_group_end_token }
\group_begin:
\char_set_catcode:nn{`\*}{3}
\token_new:Nn \c_math_shift_token {*}
@@ -932,328 +966,196 @@
\token_new:Nn \c_letter_token {a}
\token_new:Nn \c_other_char_token {1}
\char_set_catcode:nn{`\*}{13}
-\token_new:Nn \c_active_char_token {*}
+\cs_gset_nopar:Npn \c_active_char_token {\exp_not:N*}
\group_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}
%
% \begin{macro}{\token_if_group_begin_p:N}
-% \begin{macro}{\token_if_group_begin:NTF}
-% \begin{macro}{\token_if_group_begin:NT}
-% \begin{macro}{\token_if_group_begin:NF}
+% \begin{macro}[TF]{\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}
-\def_new:Npn \token_if_group_begin_p:N #1{
+\prg_new_conditional:Nnn \token_if_group_begin:N {p,TF,T,F} {
\if_catcode:w \exp_not:N #1\c_group_begin_token
- \c_true
- \else:
- \c_false
- \fi:
+ \prg_return_true: \else: \prg_return_false: \fi:
}
-\def_test_function_new:npn {token_if_group_begin:N} #1{
- \if:w\token_if_group_begin_p:N #1}
% \end{macrocode}
% \end{macro}
% \end{macro}
-% \end{macro}
-% \end{macro}
%
-% \begin{macro}{\token_if_group_end_p:N}
-% \begin{macro}{\token_if_group_end:NTF}
-% \begin{macro}{\token_if_group_end:NT}
-% \begin{macro}{\token_if_group_end:NF}
+% \begin{macro}{ \token_if_group_end_p:N }
+% \begin{macro}[TF]{ \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}
-\def_new:Npn \token_if_group_end_p:N #1{
+\prg_new_conditional:Nnn \token_if_group_end:N {p,TF,T,F} {
\if_catcode:w \exp_not:N #1\c_group_end_token
- \c_true
- \else:
- \c_false
- \fi:
+ \prg_return_true: \else: \prg_return_false: \fi:
}
-\def_test_function_new:npn {token_if_group_end:N} #1{
- \if:w\token_if_group_end_p:N #1}
% \end{macrocode}
% \end{macro}
% \end{macro}
-% \end{macro}
-% \end{macro}
+%
% \begin{macro}{\token_if_math_shift_p:N}
-% \begin{macro}{\token_if_math_shift:NTF}
-% \begin{macro}{\token_if_math_shift:NT}
-% \begin{macro}{\token_if_math_shift:NF}
+% \begin{macro}[TF]{\token_if_math_shift:N}
% Check if token is a math shift token. We use the constant
% "\c_math_shift_token" for this.
% \begin{macrocode}
-\def_new:Npn \token_if_math_shift_p:N #1{
+\prg_new_conditional:Nnn \token_if_math_shift:N {p,TF,T,F} {
\if_catcode:w \exp_not:N #1\c_math_shift_token
- \c_true
- \else:
- \c_false
- \fi:
+ \prg_return_true: \else: \prg_return_false: \fi:
}
-\def_test_function_new:npn {token_if_math_shift:N} #1{
- \if:w\token_if_math_shift_p:N#1}
% \end{macrocode}
% \end{macro}
% \end{macro}
-% \end{macro}
-% \end{macro}
+%
% \begin{macro}{\token_if_alignment_tab_p:N}
-% \begin{macro}{\token_if_alignment_tab:NTF}
-% \begin{macro}{\token_if_alignment_tab:NT}
-% \begin{macro}{\token_if_alignment_tab:NF}
+% \begin{macro}[TF]{\token_if_alignment_tab:N}
% Check if token is an alignment tab token. We use the constant
% "\c_alignment_tab_token" for this.
% \begin{macrocode}
-\def_new:Npn \token_if_alignment_tab_p:N #1{
+\prg_new_conditional:Nnn \token_if_alignment_tab:N {p,TF,T,F} {
\if_catcode:w \exp_not:N #1\c_alignment_tab_token
- \c_true
- \else:
- \c_false
- \fi:
+ \prg_return_true: \else: \prg_return_false: \fi:
}
-\def_test_function_new:npn {token_if_alignment_tab:N} #1{
- \if:w\token_if_alignment_tab_p:N#1}
% \end{macrocode}
% \end{macro}
% \end{macro}
-% \end{macro}
-% \end{macro}
+%
% \begin{macro}{\token_if_parameter_p:N}
-% \begin{macro}{\token_if_parameter:NTF}
-% \begin{macro}{\token_if_parameter:NT}
-% \begin{macro}{\token_if_parameter:NF}
+% \begin{macro}[TF]{\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.
% \begin{macrocode}
-\def_new:Npn \token_if_parameter_p:N #1{
- \exp_after:NN\if_catcode:w \cs:w c_parameter_token\cs_end:\exp_not:N #1
- \c_true
- \else:
- \c_false
- \fi:
+\prg_new_conditional:Nnn \token_if_parameter:N {p,TF,T,F} {
+ \exp_after:wN\if_catcode:w \cs:w c_parameter_token\cs_end:\exp_not:N #1
+ \prg_return_true: \else: \prg_return_false: \fi:
}
-\def_test_function_new:npn {token_if_parameter:N} #1{
- \if:w\token_if_parameter_p:N#1}
% \end{macrocode}
% \end{macro}
% \end{macro}
-% \end{macro}
-% \end{macro}
+%
% \begin{macro}{\token_if_math_superscript_p:N}
-% \begin{macro}{\token_if_math_superscript:NTF}
-% \begin{macro}{\token_if_math_superscript:NT}
-% \begin{macro}{\token_if_math_superscript:NF}
+% \begin{macro}[TF]{\token_if_math_superscript:N}
% Check if token is a math superscript token. We use the constant
% "\c_math_superscript_token" for this.
% \begin{macrocode}
-\def_new:Npn \token_if_math_superscript_p:N #1{
+\prg_new_conditional:Nnn \token_if_math_superscript:N {p,TF,T,F} {
\if_catcode:w \exp_not:N #1\c_math_superscript_token
- \c_true
- \else:
- \c_false
- \fi:
+ \prg_return_true: \else: \prg_return_false: \fi:
}
-\def_test_function_new:npn {token_if_math_superscript:N} #1{
- \if:w\token_if_math_superscript_p:N #1}
% \end{macrocode}
% \end{macro}
% \end{macro}
-% \end{macro}
-% \end{macro}
+%
% \begin{macro}{\token_if_math_subscript_p:N}
-% \begin{macro}{\token_if_math_subscript:NTF}
-% \begin{macro}{\token_if_math_subscript:NT}
-% \begin{macro}{\token_if_math_subscript:NF}
+% \begin{macro}[TF]{\token_if_math_subscript:N}
% Check if token is a math subscript token. We use the constant
% "\c_math_subscript_token" for this.
% \begin{macrocode}
-\def_new:Npn \token_if_math_subscript_p:N #1{
+\prg_new_conditional:Nnn \token_if_math_subscript:N {p,TF,T,F} {
\if_catcode:w \exp_not:N #1\c_math_subscript_token
- \c_true
- \else:
- \c_false
- \fi:
+ \prg_return_true: \else: \prg_return_false: \fi:
}
-\def_test_function_new:npn {token_if_math_subscript:N} #1{
- \if:w\token_if_math_subscript_p:N #1}
% \end{macrocode}
% \end{macro}
% \end{macro}
-% \end{macro}
-% \end{macro}
%
% \begin{macro}{\token_if_space_p:N}
-% \begin{macro}{\token_if_space:NTF}
-% \begin{macro}{\token_if_space:NT}
-% \begin{macro}{\token_if_space:NF}
+% \begin{macro}[TF]{\token_if_space:N}
% Check if token is a space token. We use the constant
% "\c_space_token" for this.
% \begin{macrocode}
-\def_new:Npn \token_if_space_p:N #1{
+\prg_new_conditional:Nnn \token_if_space:N {p,TF,T,F} {
\if_catcode:w \exp_not:N #1\c_space_token
- \c_true
- \else:
- \c_false
- \fi:
+ \prg_return_true: \else: \prg_return_false: \fi:
}
-\def_test_function_new:npn {token_if_space:N} #1{
- \if:w\token_if_space_p:N #1}
% \end{macrocode}
% \end{macro}
% \end{macro}
-% \end{macro}
-% \end{macro}
+%
% \begin{macro}{\token_if_letter_p:N}
-% \begin{macro}{\token_if_letter:NTF}
-% \begin{macro}{\token_if_letter:NT}
-% \begin{macro}{\token_if_letter:NF}
+% \begin{macro}[TF]{\token_if_letter:N}
% Check if token is a letter token. We use the constant
% "\c_letter_token" for this.
% \begin{macrocode}
-\def_new:Npn \token_if_letter_p:N #1{
+\prg_new_conditional:Nnn \token_if_letter:N {p,TF,T,F} {
\if_catcode:w \exp_not:N #1\c_letter_token
- \c_true
- \else:
- \c_false
- \fi:
+ \prg_return_true: \else: \prg_return_false: \fi:
}
-\def_test_function_new:npn {token_if_letter:N} #1{
- \if:w\token_if_letter_p:N #1}
% \end{macrocode}
% \end{macro}
% \end{macro}
-% \end{macro}
-% \end{macro}
%
% \begin{macro}{\token_if_other_char_p:N}
-% \begin{macro}{\token_if_other_char:NTF}
-% \begin{macro}{\token_if_other_char:NT}
-% \begin{macro}{\token_if_other_char:NF}
+% \begin{macro}[TF]{\token_if_other_char:N}
% Check if token is an other char token. We use the constant
% "\c_other_char_token" for this.
% \begin{macrocode}
-\def_new:Npn \token_if_other_char_p:N #1{
+\prg_new_conditional:Nnn \token_if_other_char:N {p,TF,T,F} {
\if_catcode:w \exp_not:N #1\c_other_char_token
- \c_true
- \else:
- \c_false
- \fi:
+ \prg_return_true: \else: \prg_return_false: \fi:
}
-\def_test_function_new:npn {token_if_other_char:N} #1{
- \if:w\token_if_other_char_p:N #1}
% \end{macrocode}
% \end{macro}
% \end{macro}
-% \end{macro}
-% \end{macro}
%
% \begin{macro}{\token_if_active_char_p:N}
-% \begin{macro}{\token_if_active_char:NTF}
-% \begin{macro}{\token_if_active_char:NT}
-% \begin{macro}{\token_if_active_char:NF}
+% \begin{macro}[TF]{\token_if_active_char:N}
% Check if token is an active char token. We use the constant
% "\c_active_char_token" for this.
% \begin{macrocode}
-\def_new:Npn \token_if_active_char_p:N #1{
+\prg_new_conditional:Nnn \token_if_active_char:N {p,TF,T,F} {
\if_catcode:w \exp_not:N #1\c_active_char_token
- \c_true
- \else:
- \c_false
- \fi:
+ \prg_return_true: \else: \prg_return_false: \fi:
}
-\def_test_function_new:npn {token_if_active_char:N} #1{
- \if:w\token_if_active_char_p:N #1}
% \end{macrocode}
% \end{macro}
% \end{macro}
-% \end{macro}
-% \end{macro}
%
% \begin{macro}{\token_if_eq_meaning_p:NN}
-% \begin{macro}{\token_if_eq_meaning:NNTF}
-% \begin{macro}{\token_if_eq_meaning:NNT}
-% \begin{macro}{\token_if_eq_meaning:NNF}
+% \begin{macro}[TF]{\token_if_eq_meaning:NN}
% Check if the tokens |#1| and |#2| have same meaning.
% \begin{macrocode}
-\def_new:Npn \token_if_eq_meaning_p:NN #1#2 {
- \if_meaning:NN #1 #2
- \c_true
- \else:
- \c_false
- \fi:
+\prg_new_conditional:Nnn \token_if_eq_meaning:NN {p,TF,T,F} {
+ \if_meaning:w #1 #2
+ \prg_return_true: \else: \prg_return_false: \fi:
}
-\def_test_function_new:npn {token_if_eq_meaning:NN}#1#2{
- \if_meaning:NN #1 #2}
% \end{macrocode}
% \end{macro}
% \end{macro}
-% \end{macro}
-% \end{macro}
%
-% \begin{macro}{\token_if_eq_catcode_p:NN}
-% \begin{macro}{\token_if_eq_catcode:NNTF}
-% \begin{macro}{\token_if_eq_catcode:NNT}
-% \begin{macro}{\token_if_eq_catcode:NNF}
+% \begin{macro}{\token_if_eq_catcode_p:NN}
+% \begin{macro}[TF]{\token_if_eq_catcode:NN}
% Check if the tokens |#1| and |#2| have same category code.
% \begin{macrocode}
-\def_new:Npn \token_if_eq_catcode_p:NN #1#2 {
+\prg_new_conditional:Nnn \token_if_eq_catcode:NN {p,TF,T,F} {
\if_catcode:w \exp_not:N #1 \exp_not:N #2
- \c_true
- \else:
- \c_false
- \fi:
+ \prg_return_true: \else: \prg_return_false: \fi:
}
-\def_test_function_new:npn {token_if_eq_catcode:NN}#1#2{
- \if:w\token_if_eq_catcode_p:NN#1#2}
% \end{macrocode}
-% \end{macro}
-% \end{macro}
% \end{macro}
% \end{macro}
%
%
%
-% \begin{macro}{\token_if_eq_charcode_p:NN}
-% \begin{macro}{\token_if_eq_charcode:NNTF}
-% \begin{macro}{\token_if_eq_charcode:NNT}
-% \begin{macro}{\token_if_eq_charcode:NNF}
+% \begin{macro}{\token_if_eq_charcode_p:NN}
+% \begin{macro}[TF]{\token_if_eq_charcode:NN}
% Check if the tokens |#1| and |#2| have same character code.
% \begin{macrocode}
-\def_new:Npn \token_if_charcode_eq_p:NN #1#2 {
+\prg_new_conditional:Nnn \token_if_eq_charcode:NN {p,TF,T,F} {
\if_charcode:w \exp_not:N #1 \exp_not:N #2
- \c_true
- \else:
- \c_false
- \fi:
+ \prg_return_true: \else: \prg_return_false: \fi:
}
-\def_test_function_new:npn {token_if_eq_charcode:NN}#1#2{
- \if:w\token_if_eq_charcode_p:NN#1#2}
% \end{macrocode}
% \end{macro}
% \end{macro}
-% \end{macro}
-% \end{macro}
%
% \begin{macro}{\token_if_macro_p:N}
-% \begin{macro}{\token_if_macro_p_aux:w}
-% \begin{macro}{\token_if_macro:NTF}
-% \begin{macro}{\token_if_macro:NT}
-% \begin{macro}{\token_if_macro:NF}
+% \begin{macro}[TF]{\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 simply check to see if
% the meaning contains "->". Argument "#2" in the code below will be
@@ -1263,78 +1165,73 @@
% other private functions as well) but that should certainly never
% be a problem!
% \begin{macrocode}
-\def_new:Npn \token_if_macro_p:N #1 {
- \exp_after:NN \token_if_macro_p_aux:w \token_to_meaning:N #1 -> \q_nil
+\prg_new_conditional:Nnn \token_if_macro:N {p,TF,T,F} {
+ \exp_after:wN \token_if_macro_p_aux:w \token_to_meaning:N #1 -> \q_nil
}
-\def_new:Npn \token_if_macro_p_aux:w #1 -> #2 \q_nil{
- \if:w \tlist_if_empty_p:n{#2} \c_false \else: \c_true \fi:
+\cs_new_nopar:Npn \token_if_macro_p_aux:w #1 -> #2 \q_nil{
+ \if_predicate:w \tl_if_empty_p:n{#2}
+ \prg_return_false: \else: \prg_return_true: \fi:
}
-\def_test_function_new:npn {token_if_macro:N} #1{\if:w\token_if_macro_p:N#1}
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
-% \end{macro}
-% \end{macro}
%
% \begin{macro}{\token_if_cs_p:N}
-% \begin{macro}{\token_if_cs:NTF}
-% \begin{macro}{\token_if_cs:NT}
-% \begin{macro}{\token_if_cs:NF}
+% \begin{macro}[TF]{\token_if_cs:N}
% Check if token has same catcode as a control sequence. We use
% "\scan_stop:" for this.
% \begin{macrocode}
-\def_new:Npn \token_if_cs_p:N {\token_if_eq_catcode_p:NN \scan_stop:}
-\def_test_function_new:npn {token_if_cs:N} #1{
- \if:w \token_if_eq_catcode_p:NN \scan_stop: #1}
+\prg_new_conditional:Nnn \token_if_cs:N {p,TF,T,F} {
+ \if_predicate:w \token_if_eq_catcode_p:NN \scan_stop: #1
+ \prg_return_true: \else: \prg_return_false: \fi:}
% \end{macrocode}
% \end{macro}
% \end{macro}
-% \end{macro}
-% \end{macro}
%
%
% \begin{macro}{\token_if_expandable_p:N}
-% \begin{macro}{\token_if_expandable:NTF}
-% \begin{macro}{\token_if_expandable:NT}
-% \begin{macro}{\token_if_expandable:NF}
+% \begin{macro}[TF]{\token_if_expandable:N}
% Check if token is expandable. We use the fact that \TeX\ will
% temporarily convert "\exp_not:N" \m{token} into "\scan_stop:" if
% \m{token} is expandable.
% \begin{macrocode}
-\def_new:Npn \token_if_expandable_p:N #1{
- \exp_after:NN \if_token_eq:NN \exp_not:N #1 \scan_stop:
- \c_true
- \else:
- \c_false
- \fi:
+\prg_new_conditional:Nnn \token_if_expandable:N {p,TF,T,F} {
+ \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:
+ }
}
-\def_test_function_new:npn {token_if_expandable:N} #1{
- \if:w\token_if_expandable_p:N#1}
% \end{macrocode}
% \end{macro}
% \end{macro}
-% \end{macro}
-% \end{macro}
%
-% \begin{macro}{\token_if_chardef_p:N}
-% \begin{macro}{\token_if_chardef_p_aux:w}
-% \begin{macro}{\token_if_mathchardef_p:N}
-% \begin{macro}{\token_if_mathchardef_p_aux:w}
-% \begin{macro}{\token_if_int_register_p:N}
-% \begin{macro}{\token_if_int_register_p_aux:w}
-% \begin{macro}{\token_if_skip_register_p:N}
-% \begin{macro}{\token_if_skip_register_p_aux:w}
-% \begin{macro}{\token_if_dim_register_p:N}
-% \begin{macro}{\token_if_dim_register_p_aux:w}
-% \begin{macro}{\token_if_toks_register_p:N}
-% \begin{macro}{\token_if_toks_register_p_aux:w}
-% \begin{macro}{\token_if_protected_macro_p:N}
-% \begin{macro}{\token_if_protected_macro_p_aux:w}
-% \begin{macro}{\token_if_long_macro_p:N}
-% \begin{macro}{\token_if_long_macro_p_aux:w}
-% \begin{macro}{\token_if_protected_long_macro_p:N}
-% \begin{macro}{\token_if_protected_long_macro_p_aux:w}
+% \begin{macro}{\token_if_chardef_p:N,
+% \token_if_mathchardef_p:N,
+% \token_if_int_register_p:N,
+% \token_if_skip_register_p:N,
+% \token_if_dim_register_p:N,
+% \token_if_toks_register_p:N,
+% \token_if_protected_macro_p:N,
+% \token_if_long_macro_p:N,
+% \token_if_protected_long_macro_p:N}
+% \begin{macro}[TF]{\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
@@ -1342,17 +1239,19 @@
% below\dots
% \begin{macrocode}
\group_begin:
- \char_set_lccode:nn {`\X}{`\n}
+ \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 {`\?}{`\\}
- \tlist_map_inline:nn{\X\Y\Z\M\T\C\H\A\R\O\U\S\K\I\P\L\G\P\E}
+ \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}{12}}
% \end{macrocode}
% We convert the token list to lowercase and restore the catcode and
% lowercase code changes.
% \begin{macrocode}
-\tlist_to_lowercase:n{
+\tl_to_lowercase:n{
\group_end:
% \end{macrocode}
% First up is checking if something has been defined with
@@ -1360,239 +1259,126 @@
% thinks of such tokens as hexadecimal so it stores them as
% |\char"|\meta{hex~number} or |\mathchar"|\meta{hex~number}.
% \begin{macrocode}
-\def_new:Npn \token_if_chardef_p:N #1 {
- \exp_after:NN \token_if_chardef_p_aux:w
+\prg_new_conditional:Nnn \token_if_chardef:N {p,TF,T,F} {
+ \exp_after:wN \token_if_chardef_aux:w
\token_to_meaning:N #1?CHAR"\q_nil
}
-\def_new:Npn \token_if_chardef_p_aux:w #1?CHAR"#2\q_nil{
- \tlist_if_empty_p:n{#1}
+\cs_new_nopar:Npn \token_if_chardef_aux:w #1?CHAR"#2\q_nil{
+ \tl_if_empty:nTF {#1} {\prg_return_true:} {\prg_return_false:}
}
-\def_new:Npn \token_if_mathchardef_p:N #1 {
- \exp_after:NN \token_if_mathchardef_p_aux:w
+% \end{macrocode}
+%
+% \begin{macrocode}
+\prg_new_conditional:Nnn \token_if_mathchardef:N {p,TF,T,F} {
+ \exp_after:wN \token_if_mathchardef_aux:w
\token_to_meaning:N #1?MAYHCHAR"\q_nil
}
-\def_new:Npn \token_if_mathchardef_p_aux:w #1?MAYHCHAR"#2\q_nil{
- \tlist_if_empty_p:n{#1}
+\cs_new_nopar:Npn \token_if_mathchardef_aux:w #1?MAYHCHAR"#2\q_nil{
+ \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}
-\def:Npn \token_if_int_register_p:N #1{
- \if_meaning:NN \tex_countdef:D #1
- \c_false
+\prg_new_conditional:Nnn \token_if_int_register:N {p,TF,T,F} {
+ \if_meaning:w \tex_countdef:D #1
+ \prg_return_false:
\else:
- \exp_after:NN \token_if_int_register_p_aux:w
+ \exp_after:wN \token_if_int_register_aux:w
\token_to_meaning:N #1?COUXY\q_nil
\fi:
}
-\def_new:Npn \token_if_int_register_p_aux:w #1?COUXY#2\q_nil{
- \tlist_if_empty_p:n{#1}
+\cs_new_nopar:Npn \token_if_int_register_aux:w #1?COUXY#2\q_nil{
+ \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}
-\def:Npn \token_if_skip_register_p:N #1{
- \if_meaning:NN \tex_skipdef:D #1
- \c_false
+\prg_new_conditional:Nnn \token_if_skip_register:N {p,TF,T,F} {
+ \if_meaning:w \tex_skipdef:D #1
+ \prg_return_false:
\else:
- \exp_after:NN \token_if_skip_register_p_aux:w
- \token_to_meaning:N #1?SKIP\q_nil
+ \exp_after:wN \token_if_skip_register_aux:w
+ \token_to_meaning:N #1?SKIP\q_nil
\fi:
}
-\def_new:Npn \token_if_skip_register_p_aux:w #1?SKIP#2\q_nil{
- \tlist_if_empty_p:n{#1}
+\cs_new_nopar:Npn \token_if_skip_register_aux:w #1?SKIP#2\q_nil{
+ \tl_if_empty:nTF {#1} {\prg_return_true:} {\prg_return_false:}
}
% \end{macrocode}
% Dim registers. No news here
% \begin{macrocode}
-\def:Npn \token_if_dim_register_p:N #1{
- \if_meaning:NN \tex_dimendef:D #1
- \c_false
+\prg_new_conditional:Nnn \token_if_dim_register:N {p,TF,T,F} {
+ \if_meaning:w \tex_dimendef:D #1
+ \c_false_bool
\else:
- \exp_after:NN \token_if_dim_register_p_aux:w
- \token_to_meaning:N #1?ZIMEX\q_nil
+ \exp_after:wN \token_if_dim_register_aux:w
+ \token_to_meaning:N #1?ZIMEX\q_nil
\fi:
}
-\def_new:Npn \token_if_dim_register_p_aux:w #1?ZIMEX#2\q_nil{
- \tlist_if_empty_p:n{#1}
+\cs_new_nopar:Npn \token_if_dim_register_aux:w #1?ZIMEX#2\q_nil{
+ \tl_if_empty:nTF {#1} {\prg_return_true:} {\prg_return_false:}
}
% \end{macrocode}
-% Toks registers. Ho-hum.
+% Toks registers.
% \begin{macrocode}
-\def:Npn \token_if_toks_register_p:N #1{
- \if_meaning:NN \tex_toksdef:D #1
- \c_false
+\prg_new_conditional:Nnn \token_if_toks_register:N {p,TF,T,F} {
+ \if_meaning:w \tex_toksdef:D #1
+ \prg_return_false:
\else:
- \exp_after:NN \token_if_toks_register_p_aux:w
+ \exp_after:wN \token_if_toks_register_aux:w
\token_to_meaning:N #1?YOKS\q_nil
\fi:
}
-\def_new:Npn \token_if_toks_register_p_aux:w #1?YOKS#2\q_nil{
- \tlist_if_empty_p:n{#1}
+\cs_new_nopar:Npn \token_if_toks_register_aux:w #1?YOKS#2\q_nil{
+ \tl_if_empty:nTF {#1} {\prg_return_true:} {\prg_return_false:}
}
% \end{macrocode}
% Protected macros.
% \begin{macrocode}
-\def_new:Npn \token_if_protected_macro_p:N #1 {
- \exp_after:NN \token_if_protected_macro_p_aux:w
+\prg_new_conditional:Nnn \token_if_protected_macro:N {p,TF,T,F} {
+ \exp_after:wN \token_if_protected_macro_aux:w
\token_to_meaning:N #1?PROYECYEZ~MACRO\q_nil
}
-\def_new:Npn \token_if_protected_macro_p_aux:w #1?PROYECYEZ~MACRO#2\q_nil{
- \tlist_if_empty_p:n{#1}
+\cs_new_nopar:Npn \token_if_protected_macro_aux:w #1?PROYECYEZ~MACRO#2\q_nil{
+ \tl_if_empty:nTF {#1} {\prg_return_true:} {\prg_return_false:}
}
% \end{macrocode}
% Long macros.
% \begin{macrocode}
-\def_new:Npn \token_if_long_macro_p:N #1 {
- \exp_after:NN \token_if_long_macro_p_aux:w
+\prg_new_conditional:Nnn \token_if_long_macro:N {p,TF,T,F} {
+ \exp_after:wN \token_if_long_macro_aux:w
\token_to_meaning:N #1?LOXG~MACRO\q_nil
}
-\def_new:Npn \token_if_long_macro_p_aux:w #1?LOXG~MACRO#2\q_nil{
- \tlist_if_empty_p:n{#1}
+\cs_new_nopar:Npn \token_if_long_macro_aux:w #1?LOXG~MACRO#2\q_nil{
+ \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}
-\def_new:Npn \token_if_protected_long_macro_p:N #1 {
- \exp_after:NN \token_if_protected_long_macro_p_aux:w
- \token_to_meaning:N #1?PROYECYEZ~?LOXG~MACRO\q_nil
+\prg_new_conditional:Nnn \token_if_protected_long_macro:N {p,TF,T,F} {
+ \exp_after:wN \token_if_protected_long_macro_aux:w
+ \token_to_meaning:N #1?PROYECYEZ?LOXG~MACRO\q_nil
}
-\def_new:Npn \token_if_protected_long_macro_p_aux:w #1
- ?PROYECYEZ~?LOXG~MACRO#2\q_nil{
- \tlist_if_empty_p:n{#1}
+\cs_new_nopar:Npn \token_if_protected_long_macro_aux:w #1
+ ?PROYECYEZ?LOXG~MACRO#2\q_nil{
+ \tl_if_empty:nTF {#1} {\prg_return_true:} {\prg_return_false:}
}
% \end{macrocode}
-% Finally the |\tlist_to_lowercase:n| ends!
+% Finally the |\tl_to_lowercase:n| ends!
% \begin{macrocode}
}
% \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}{\token_if_chardef:NTF}
-% \begin{macro}{\token_if_chardef:NT}
-% \begin{macro}{\token_if_chardef:NF}
-% \begin{macrocode}
-\def_test_function_new:npn {token_if_chardef:N} {\if:w \token_if_chardef_p:N}
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\token_if_mathchardef:NTF}
-% \begin{macro}{\token_if_mathchardef:NT}
-% \begin{macro}{\token_if_mathchardef:NF}
-% \begin{macrocode}
-\def_test_function_new:npn {token_if_mathchardef:N} {
- \if:w \token_if_mathchardef_p:N}
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\token_if_long_macro:NTF}
-% \begin{macro}{\token_if_long_macro:NT}
-% \begin{macro}{\token_if_long_macro:NF}
-% \begin{macrocode}
-\def_test_function_new:npn {token_if_long_macro:N} {
- \if:w \token_if_long_macro_p:N}
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\token_if_protected_macro:NTF}
-% \begin{macro}{\token_if_protected_macro:NT}
-% \begin{macro}{\token_if_protected_macro:NF}
-% \begin{macrocode}
-\def_test_function_new:npn {token_if_protected_macro:N} {
- \if:w \token_if_protected_macro_p:N}
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\token_if_protected_long_macro:NTF}
-% \begin{macro}{\token_if_protected_long_macro:NT}
-% \begin{macro}{\token_if_protected_long_macro:NF}
-% \begin{macrocode}
-\def_test_function_new:npn {token_if_protected_long_macro:N} {
- \if:w \token_if_protected_long_macro_p:N}
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\token_if_dim_register:NTF}
-% \begin{macro}{\token_if_dim_register:NT}
-% \begin{macro}{\token_if_dim_register:NF}
-% \begin{macrocode}
-\def_test_function_new:npn {token_if_dim_register:N} {
- \if:w \token_if_dim_register_p:N}
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\token_if_skip_register:NTF}
-% \begin{macro}{\token_if_skip_register:NT}
-% \begin{macro}{\token_if_skip_register:NF}
-% \begin{macrocode}
-\def_test_function_new:npn {token_if_skip_register:N} {
- \if:w \token_if_skip_register_p:N}
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\token_if_int_register:NTF}
-% \begin{macro}{\token_if_int_register:NT}
-% \begin{macro}{\token_if_int_register:NF}
-% \begin{macrocode}
-\def_test_function_new:npn {token_if_int_register:N} {
- \if:w \token_if_int_register_p:N}
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\token_if_toks_register:NTF}
-% \begin{macro}{\token_if_toks_register:NT}
-% \begin{macro}{\token_if_toks_register:NF}
-% \begin{macrocode}
-\def_test_function_new:npn {token_if_toks_register:N} {
- \if:w \token_if_toks_register_p:N}
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-%
-%
%
% We do not provide a function for testing if a control sequence is
% ``outer'' since we don't use that in \LaTeX3.
%
-% \begin{macro}{\token_get_prefix_arg_replacement_aux:w}
+% \begin{macro}[aux]{\token_get_prefix_arg_replacement_aux:w}
% \begin{macro}{\token_get_prefix_spec:N}
% \begin{macro}{\token_get_arg_spec:N}
% \begin{macro}{\token_get_replacement_spec:N}
@@ -1613,27 +1399,27 @@
\char_set_catcode:nn{`\C}{12}
\char_set_catcode:nn{`\R}{12}
\char_set_catcode:nn{`\O}{12}
-\tlist_to_lowercase:n{
+\tl_to_lowercase:n{
\group_end:
- \def_new:Npn \token_get_prefix_arg_replacement_aux:w #1MACRO?#2->#3\q_nil#4{
+ \cs_new_nopar:Npn \token_get_prefix_arg_replacement_aux:w #1MACRO?#2->#3\q_nil#4{
#4{#1}{#2}{#3}
}
- \def_new:Npn\token_get_prefix_spec:N #1{
+ \cs_new_nopar:Npn\token_get_prefix_spec:N #1{
\token_if_macro:NTF #1{
- \exp_after:NN \token_get_prefix_arg_replacement_aux:w
- \token_to_meaning:N #1\q_nil\use_arg_i:nnn
+ \exp_after:wN \token_get_prefix_arg_replacement_aux:w
+ \token_to_meaning:N #1\q_nil\use_i:nnn
}{\scan_stop:}
}
- \def_new:Npn\token_get_arg_spec:N #1{
+ \cs_new_nopar:Npn\token_get_arg_spec:N #1{
\token_if_macro:NTF #1{
- \exp_after:NN \token_get_prefix_arg_replacement_aux:w
- \token_to_meaning:N #1\q_nil\use_arg_ii:nnn
+ \exp_after:wN \token_get_prefix_arg_replacement_aux:w
+ \token_to_meaning:N #1\q_nil\use_ii:nnn
}{\scan_stop:}
}
- \def_new:Npn\token_get_replacement_spec:N #1{
+ \cs_new_nopar:Npn\token_get_replacement_spec:N #1{
\token_if_macro:NTF #1{
- \exp_after:NN \token_get_prefix_arg_replacement_aux:w
- \token_to_meaning:N #1\q_nil\use_arg_iii:nnn
+ \exp_after:wN \token_get_prefix_arg_replacement_aux:w
+ \token_to_meaning:N #1\q_nil\use_iii:nnn
}{\scan_stop:}
}
}
@@ -1646,52 +1432,50 @@
% \paragraph{Useless code: because we can!}
%
% \begin{macro}{\token_if_primitive_p:N}
-% \begin{macro}{\token_if_primitive_p_aux:N}
-% \begin{macro}{\token_if_primitive:NTF}
-% \begin{macro}{\token_if_primitive:NT}
-% \begin{macro}{\token_if_primitive:NF}
+% \begin{macro}[aux]{\token_if_primitive_p_aux:N}
+% \begin{macro}[TF]{\token_if_primitive:N}
% It is rather hard to determine if a token is a primitive. First we
% can check if it is a control sequence or active character. If
% either, we check if it is a macro. Then we can go through a
% tedious process of testing for different register types\dots{} I
% don't actually think this function is useful but you never know.
% \begin{macrocode}
-\def_new:Npn \token_if_primitive_p:N #1{
- \if:w \token_if_cs_p:N #1\scan_stop:
- \if:w \token_if_macro_p:N #1
- \c_false
+\prg_new_conditional:Nnn \token_if_primitive:N {p,TF,T,F} {
+ \if_predicate:w \token_if_cs_p:N #1
+ \if_predicate:w \token_if_macro_p:N #1
+ \prg_return_false:
\else:
\token_if_primitive_p_aux:N #1
\fi:
\else:
- \if:w \token_if_active_p:N #1
- \if:w \token_if_macro_p:N #1
- \c_false
+ \if_predicate:w \token_if_active_char_p:N #1
+ \if_predicate:w \token_if_macro_p:N #1
+ \prg_return_false:
\else:
\token_if_primitive_p_aux:N #1
\fi:
\else:
- \c_false
+ \prg_return_false:
\fi:
\fi:
}
-\def_new:Npn \token_if_primitive_p_aux:N #1{
- \if:w \token_if_chardef_p:N #1 \c_false
+\cs_new_nopar:Npn \token_if_primitive_p_aux:N #1{
+ \if_predicate:w \token_if_chardef_p:N #1 \c_false_bool
\else:
- \if:w \token_if_mathchardef_p:N #1 \c_false
+ \if_predicate:w \token_if_mathchardef_p:N #1 \prg_return_false:
\else:
- \if:w \token_if_int_register_p:N #1 \c_false
+ \if_predicate:w \token_if_int_register_p:N #1 \prg_return_false:
\else:
- \if:w \token_if_skip_register_p:N #1 \c_false
+ \if_predicate:w \token_if_skip_register_p:N #1 \prg_return_false:
\else:
- \if:w \token_if_dim_register_p:N #1 \c_false
+ \if_predicate:w \token_if_dim_register_p:N #1 \prg_return_false:
\else:
- \if:w \token_if_toks_register_p:N #1 \c_false
+ \if_predicate:w \token_if_toks_register_p:N #1 \prg_return_false:
\else:
% \end{macrocode}
% We made it!
% \begin{macrocode}
- \c_true
+ \prg_return_true:
\fi:
\fi:
\fi:
@@ -1699,24 +1483,13 @@
\fi:
\fi:
}
-\def_test_function_new:npn {token_if_primitive:N} #1{
- \if:w\token_if_primitive_p:N#1}
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-%
-%
-%
-% \subsubsection{Peeking ahead at the next token}
-%
-%
-%
%
%
+% \subsection{Peeking ahead at the next token}
%
% \begin{macro}{\l_peek_token}
% \begin{macro}{\g_peek_token}
@@ -1740,8 +1513,8 @@
% input stream which |\l_peek_token| is set equal to.
% |\peek_gafter:NN| does the same globally to |\g_peek_token|.
% \begin{macrocode}
-\def_new:Npn \peek_after:NN {\tex_futurelet:D \l_peek_token }
-\def_new:Npn \peek_gafter:NN {
+\cs_new_nopar:Npn \peek_after:NN {\tex_futurelet:D \l_peek_token }
+\cs_new_nopar:Npn \peek_gafter:NN {
\pref_global:D \tex_futurelet:D \g_peek_token
}
% \end{macrocode}
@@ -1776,13 +1549,13 @@
% in the input stream.
% \end{enumerate}
%
-% \begin{macro}{\l_peek_true_tlp}
-% \begin{macro}{\l_peek_false_tlp}
-% Two dedicated token list pointers that store the true and false
+% \begin{macro}{\l_peek_true_tl}
+% \begin{macro}{\l_peek_false_tl}
+% Two dedicated token list variables that store the true and false
% cases.
% \begin{macrocode}
-\tlp_new:Nn \l_peek_true_tlp {}
-\tlp_new:Nn \l_peek_false_tlp {}
+\tl_new:Nn \l_peek_true_tl {}
+\tl_new:Nn \l_peek_false_tl {}
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -1791,82 +1564,97 @@
% Scratch function used for storing the token to be removed if
% found.
% \begin{macrocode}
-\def_new:Npn \peek_tmp:w{}
+\cs_new_nopar:Npn \peek_tmp:w {}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\l_peek_search_tlp}
-% We also use this token list pointer for storing the token we want
+% \begin{macro}{\l_peek_search_tl}
+% We also use this token list variable for storing the token we want
% to compare. This turns out to be useful.
% \begin{macrocode}
-\tlp_new:Nn \l_peek_search_tlp{}
+\tl_new:Nn \l_peek_search_tl {}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\peek_token_generic:NNTF}
-% |#1| is the function to execute (obey or ignore spaces, etc.),
-% |#2| is the special token we're looking for, and |#3| and |#4|
-% are the \meta{true} and \meta{false} branches.
-% \begin{macrocode}
-\def_long_new:Npn \peek_token_generic:NNTF #1#2#3#4{
- \let:NN \l_peek_search_token #2
- \tlp_set:Nn \l_peek_search_tlp {#2}
- \tlp_set:Nx \l_peek_true_tlp {\exp_not:n{\group_align_safe_end: #3}}
- \tlp_set:Nx \l_peek_false_tlp {\exp_not:n{\group_align_safe_end: #4}}
+% \begin{macro}[TF]{\peek_token_generic:NN}
+% \begin{arguments}
+% \item the function to execute (obey or ignore spaces, etc.),
+% \item the special token we're looking for.
+% \end{arguments}
+% \begin{macrocode}
+\cs_new: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}
+ \tl_set:Nx \l_peek_true_tl {\exp_not:n{\group_align_safe_end: #3}}
+ \tl_set:Nx \l_peek_false_tl {\exp_not:n{\group_align_safe_end: #4}}
\group_align_safe_begin:
\peek_after:NN #1
}
+\cs_new:Npn \peek_token_generic:NNT #1#2#3 {
+ \peek_token_generic:NNTF #1#2 {#3} {}
+}
+\cs_new:Npn \peek_token_generic:NNF #1#2#3 {
+ \peek_token_generic:NNTF #1#2 {} {#3}
+}
% \end{macrocode}
% \end{macro}
-% \begin{macro}{\peek_token_remove_generic:NNTF}
+%
+% \begin{macro}[TF]{\peek_token_remove_generic:NN}
% If we want to be able to remove any character from the input
% stream we might as well do it the same way for all characters so
% we define this as little differently from above.
% \begin{macrocode}
-\def_long_new:Npn \peek_token_remove_generic:NNTF #1#2#3#4{
- \let:NN \l_peek_search_token #2
- \tlp_set:Nn \l_peek_search_tlp {#2}
- \tlp_set:Nx \l_peek_true_aux_tlp { \exp_not:n{ #3 } }
- \tlp_set_eq:NN \l_peek_true_tlp \c_peek_true_remove_next_tlp
- \tlp_set:Nx \l_peek_false_tlp {\exp_not:n{\group_align_safe_end: #4}}
+\cs_new: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}
+ \tl_set:Nx \l_peek_true_aux_tl { \exp_not:n{ #3 } }
+ \tl_set_eq:NN \l_peek_true_tl \c_peek_true_remove_next_tl
+ \tl_set:Nx \l_peek_false_tl {\exp_not:n{\group_align_safe_end: #4}}
\group_align_safe_begin:
\peek_after:NN #1
}
+\cs_new:Npn \peek_token_remove_generic:NNT #1#2#3 {
+ \peek_token_remove_generic:NNTF #1#2 {#3} {}
+}
+\cs_new:Npn \peek_token_remove_generic:NNF #1#2#3 {
+ \peek_token_remove_generic:NNTF #1#2 {} {#3}
+}
% \end{macrocode}
% \end{macro}
-% \begin{macro}{\l_peek_true_aux_tlp}
-% \begin{macro}{\l_peek_true_remove_next_tlp}
-% Two token list pointers to help with removing the character from
+%
+% \begin{macro}{\l_peek_true_aux_tl}
+% \begin{macro}{\c_peek_true_remove_next_tl}
+% Two token list variables to help with removing the character from
% the input stream.
% \begin{macrocode}
-\tlp_new:Nn \l_peek_true_aux_tlp {}
-\tlp_new:Nn \c_peek_true_remove_next_tlp {\group_align_safe_end:
- \tex_afterassignment:D \l_peek_true_aux_tlp \let:NN \peek_tmp:w
+\tl_new:Nn \l_peek_true_aux_tl {}
+\tl_new:Nn \c_peek_true_remove_next_tl {\group_align_safe_end:
+ \tex_afterassignment:D \l_peek_true_aux_tl \cs_set_eq:NN \peek_tmp:w
}
% \end{macrocode}
% \end{macro}
% \end{macro}
%
-% \begin{macro}{\peek_execute_braches_meaning:}
-% \begin{macro}{\peek_execute_braches_catcode:}
-% \begin{macro}{\peek_execute_braches_charcode:}
-% \begin{macro}{\peek_execute_branches_charcode_aux:NN}
+% \begin{macro}{\peek_execute_branches_meaning:}
+% \begin{macro}{\peek_execute_branches_catcode:}
+% \begin{macro}{\peek_execute_branches_charcode:}
+% \begin{macro}[aux]{\peek_execute_branches_charcode_aux:NN}
% There are three major tests between tokens in \TeX: meaning,
% catcode and charcode. Hence we define three basic test functions
% that set in after the ignoring phase is over and done with.
% \begin{macrocode}
-\def_new:Npn \peek_execute_branches_meaning: {
- \if_meaning:NN \l_peek_token \l_peek_search_token
- \exp_after:NN \l_peek_true_tlp
+\cs_new_nopar:Npn \peek_execute_branches_meaning: {
+ \if_meaning:w \l_peek_token \l_peek_search_token
+ \exp_after:wN \l_peek_true_tl
\else:
- \exp_after:NN \l_peek_false_tlp
+ \exp_after:wN \l_peek_false_tl
\fi:
}
-\def_new:Npn \peek_execute_branches_catcode: {
+\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:NN \l_peek_true_tlp
+ \exp_after:wN \l_peek_true_tl
\else:
- \exp_after:NN \l_peek_false_tlp
+ \exp_after:wN \l_peek_false_tl
\fi:
}
% \end{macrocode}
@@ -1880,31 +1668,31 @@
% |charcode| function for searching for |\c_group_begin_token| or
% |\c_space_token|.
% \begin{macrocode}
-\def_new:Npn \peek_execute_branches_charcode: {
- \predicate:nTF {
+\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_meaning_p:NN \l_peek_token \c_space_token
}
- { \l_peek_false_tlp }
+ { \l_peek_false_tl }
% \end{macrocode}
% Otherwise we call a small auxiliary function that just grabs the
% next token. We can do that because it really is a single token; we
% just have insert it again afterwards. Also we stored the token we
-% were looking for in the token list pointer |\l_peek_search_tlp| so
+% were looking for in the token list variable |\l_peek_search_tl| so
% we unpack it again for this function.
% \begin{macrocode}
- { \exp_after:NN \peek_execute_branches_charcode_aux:NN \l_peek_search_tlp }
+ { \exp_after:wN \peek_execute_branches_charcode_aux:NN \l_peek_search_tl }
}
% \end{macrocode}
% Then we just do the usual |\if_charcode:w| comparison. We also
% remember to insert |#2| again after executing the true or false
% branches.
% \begin{macrocode}
-\def_long_new:Npn \peek_execute_branches_charcode_aux:NN #1#2{
+\cs_new:Npn \peek_execute_branches_charcode_aux:NN #1#2{
\if_charcode:w \exp_not:N #1\exp_not:N#2
- \exp_after:NN \l_peek_true_tlp
+ \exp_after:wN \l_peek_true_tl
\else:
- \exp_after:NN \l_peek_false_tlp
+ \exp_after:wN \l_peek_false_tl
\fi:
#2
}
@@ -1914,87 +1702,152 @@
% \end{macro}
% \end{macro}
%
-% \begin{macro}{\peek_meaning:NTF}
-% \begin{macro}{\peek_meaning_ignore_spaces:NTF}
-% \begin{macro}{\peek_meaning_remove:NTF}
-% \begin{macro}{\peek_meaning_remove_ignore_spaces:NTF}
-% Here we use meaning comparison with |\if_meaning:NN|.
-% \begin{macrocode}
-\def_new:Npn \peek_meaning:NTF {
- \peek_token_generic:NNTF \peek_execute_branches_meaning:
-}
-\def_new:Npn \peek_meaning_ignore_spaces:NTF {
- \let:NN \peek_execute_branches: \peek_execute_branches_meaning:
- \peek_token_generic:NNTF \peek_ignore_spaces_execute_branches:
-}
-\def_new:Npn \peek_meaning_remove:NTF {
- \peek_token_remove_generic:NNTF \peek_execute_branches_meaning:
-}
-\def_new:Npn \peek_meaning_remove_ignore_spaces:NTF {
- \let:NN \peek_execute_branches: \peek_execute_branches_meaning:
- \peek_token_remove_generic:NNTF \peek_ignore_spaces_execute_branches:
+% \begin{macro}[aux]{\peek_def_aux:nnnn,\peek_def_aux_ii:nnnnn}
+% This function aids defining conditional variants without too much
+% repeated code. I hope that it doesn't detract too much from the readability.
+% \begin{macrocode}
+\cs_new_nopar:Npn \peek_def_aux:nnnn #1#2#3#4 {
+ \peek_def_aux_ii:nnnnn {#1} {#2} {#3} {#4} { TF }
+ \peek_def_aux_ii:nnnnn {#1} {#2} {#3} {#4} { T }
+ \peek_def_aux_ii:nnnnn {#1} {#2} {#3} {#4} { F }
+}
+\cs_new_nopar:Npn \peek_def_aux_ii:nnnnn #1#2#3#4#5 {
+ \cs_new_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}
+%
+% \begin{macro}[TF]{\peek_meaning:N}
+% Here we use meaning comparison with |\if_meaning:w|.
+% \begin{macrocode}
+\peek_def_aux:nnnn
+ { peek_meaning:N }
+ {}
+ { peek_token_generic:NN }
+ { \peek_execute_branches_meaning: }
+% \end{macrocode}
% \end{macro}
+%
+% \begin{macro}[TF]{\peek_meaning_ignore_spaces:N}
+% \begin{macrocode}
+\peek_def_aux:nnnn
+ { peek_meaning_ignore_spaces:N }
+ { \peek_execute_branches_meaning: }
+ { peek_token_generic:NN }
+ { \peek_ignore_spaces_execute_branches: }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[TF]{\peek_meaning_remove:N}
+% \begin{macrocode}
+\peek_def_aux:nnnn
+ { peek_meaning_remove:N }
+ {}
+ { peek_token_remove_generic:NN }
+ { \peek_execute_branches_meaning: }
+% \end{macrocode}
% \end{macro}
+%
+% \begin{macro}[TF]{\peek_meaning_remove_ignore_spaces:N}
+% \begin{macrocode}
+\peek_def_aux:nnnn
+ { peek_meaning_remove_ignore_spaces:N }
+ { \peek_execute_branches_meaning: }
+ { peek_token_remove_generic:NN }
+ { \peek_ignore_spaces_execute_branches: }
+% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\peek_catcode:NTF}
-% \begin{macro}{\peek_catcode_ignore_spaces:NTF}
-% \begin{macro}{\peek_catcode_remove:NTF}
-% \begin{macro}{\peek_catcode_remove_ignore_spaces:NTF}
+% \begin{macro}[TF]{\peek_catcode:N}
% Here we use catcode comparison with |\if_catcode:w|.
% \begin{macrocode}
-\def_new:Npn \peek_catcode:NTF {
- \peek_token_generic:NNTF \peek_execute_branches_catcode:
-}
-\def_new:Npn \peek_catcode_ignore_spaces:NTF {
- \let:NN \peek_execute_branches: \peek_execute_branches_catcode:
- \peek_token_generic:NNTF \peek_ignore_spaces_execute_branches:
-}
-\def_new:Npn \peek_catcode_remove:NTF {
- \peek_token_remove_generic:NNTF \peek_execute_branches_catcode:
-}
-\def_new:Npn \peek_catcode_remove_ignore_spaces:NTF {
- \let:NN \peek_execute_branches: \peek_execute_branches_catcode:
- \peek_token_remove_generic:NNTF \peek_ignore_spaces_execute_branches:
-}
+\peek_def_aux:nnnn
+ { peek_catcode:N }
+ {}
+ { peek_token_generic:NN }
+ { \peek_execute_branches_catcode: }
% \end{macrocode}
% \end{macro}
+%
+% \begin{macro}[TF]{\peek_catcode_ignore_spaces:N}
+% \begin{macrocode}
+\peek_def_aux:nnnn
+ { peek_catcode_ignore_spaces:N }
+ { \peek_execute_branches_catcode: }
+ { peek_token_generic:NN }
+ { \peek_ignore_spaces_execute_branches: }
+% \end{macrocode}
% \end{macro}
+%
+% \begin{macro}[TF]{\peek_catcode_remove:N}
+% \begin{macrocode}
+\peek_def_aux:nnnn
+ { peek_catcode_remove:N }
+ {}
+ { peek_token_remove_generic:NN }
+ { \peek_execute_branches_catcode: }
+% \end{macrocode}
% \end{macro}
+%
+% \begin{macro}[TF]{\peek_catcode_remove_ignore_spaces:N}
+% \begin{macrocode}
+\peek_def_aux: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}{\peek_charcode:NTF}
-% \begin{macro}{\peek_charcode_ignore_spaces:NTF}
-% \begin{macro}{\peek_charcode_remove:NTF}
-% \begin{macro}{\peek_charcode_remove_ignore_spaces:NTF}
+% \begin{macro}[TF]{\peek_charcode:N}
% Here we use charcode comparison with |\if_charcode:w|.
% \begin{macrocode}
-\def_new:Npn \peek_charcode:NTF {
- \peek_token_generic:NNTF \peek_execute_branches_charcode:
-}
-\def_new:Npn \peek_charcode_ignore_spaces:NTF {
- \let:NN \peek_execute_branches: \peek_execute_branches_charcode:
- \peek_token_generic:NNTF \peek_ignore_spaces_execute_branches:
-}
-\def_new:Npn \peek_charcode_remove:NTF {
- \peek_token_remove_generic:NNTF \peek_execute_branches_charcode:
-}
-
-\def_new:Npn \peek_charcode_remove_ignore_spaces:NTF {
- \let:NN \peek_execute_branches: \peek_execute_branches_charcode:
- \peek_token_remove_generic:NNTF \peek_ignore_spaces_execute_branches:
-}
+\peek_def_aux:nnnn
+ { peek_charcode:N }
+ {}
+ { peek_token_generic:NN }
+ { \peek_execute_branches_charcode: }
% \end{macrocode}
% \end{macro}
+%
+% \begin{macro}[TF]{\peek_charcode_ignore_spaces:N}
+% \begin{macrocode}
+\peek_def_aux:nnnn
+ { peek_charcode_ignore_spaces:N }
+ { \peek_execute_branches_charcode: }
+ { peek_token_generic:NN }
+ { \peek_ignore_spaces_execute_branches: }
+% \end{macrocode}
% \end{macro}
+%
+% \begin{macro}[TF]{\peek_charcode_remove:N}
+% \begin{macrocode}
+\peek_def_aux:nnnn
+ { peek_charcode_remove:N }
+ {}
+ { peek_token_remove_generic:NN }
+ { \peek_execute_branches_charcode: }
+% \end{macrocode}
% \end{macro}
+%
+% \begin{macro}[TF]{\peek_charcode_remove_ignore_spaces:N}
+% \begin{macrocode}
+\peek_def_aux: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}{\peek_ignore_spaces_aux:}
-% \begin{macro}{\peek_ignore_spaces_execute_branches:}
+% \begin{macro}{\peek_ignore_spaces_aux:,
+% \peek_ignore_spaces_execute_branches:}
% Throw away a space token and search again. We could define this in
% a more devious way where the auxiliary function gobbles the space
% token but then what do we do if we decide that a certain function
@@ -2003,53 +1856,33 @@
% ignores |a|'s and |b|'s! Or maybe different kinds of ``funny
% spaces''\dots{} Therefore I have decided to use this version which
% uses |\tex_afterassignment:D| to call the auxiliary function after
-% the next token has been removed by |\let:NN|. That way it is
+% the next token has been removed by |\cs_set_eq:NN|. That way it is
% easily extensible.
% \begin{macrocode}
-\def_new:Npn \peek_ignore_spaces_aux: {
+\cs_new_nopar:Npn \peek_ignore_spaces_aux: {
\peek_after:NN \peek_ignore_spaces_execute_branches:
}
-\def_new:Npn \peek_ignore_spaces_execute_branches: {
+\cs_new_nopar:Npn \peek_ignore_spaces_execute_branches: {
\token_if_eq_meaning:NNTF \l_peek_token \c_space_token
{ \tex_afterassignment:D \peek_ignore_spaces_aux:
- \let:NN \peek_tmp:w
+ \cs_set_eq:NN \peek_tmp:w
}
\peek_execute_branches:
}
% \end{macrocode}
% \end{macro}
-% \end{macro}
-%
-%
-%
%
% \begin{macrocode}
%</initex|package>
+% \end{macrocode}
+%
+% \begin{macrocode}
%<*showmemory>
\showMemUsage
%</showmemory>
% \end{macrocode}
%
-% \endinput
-%
-% $Log$
-% Revision 1.6 2006/03/20 18:26:40 braams
-% Updated the copyright notice (2006) and demoted all implementation
-% sections to subsections and so on to clean up the toc for source3.tex
-%
-% Revision 1.5 2006/01/19 22:33:53 morten
-% Minor changes in \char_set_XXXcode:nn functions.
-%
-% Revision 1.4 2006/01/04 01:28:06 morten
-% Fixed \peek_execute_branches_charcode: properly.
-%
-% Revision 1.3 2005/12/29 12:17:32 morten
-% Fixed \peek_execute_branches_charcode: plus minor bugs elsewhere
-%
-% Revision 1.2 2005/12/27 15:48:41 morten
-% Fixing initial boo-boos. Updated documentation to reflect current code
-% included
-%
-% Revision 1.1 2005/12/27 09:54:58 morten
-% New module
+% \end{implementation}
+% \PrintIndex
%
+% \endinput
diff --git a/Master/texmf-dist/source/latex/expl3/l3toks.dtx b/Master/texmf-dist/source/latex/expl3/l3toks.dtx
index a5d78d7386c..e5575678f27 100644
--- a/Master/texmf-dist/source/latex/expl3/l3toks.dtx
+++ b/Master/texmf-dist/source/latex/expl3/l3toks.dtx
@@ -1,5 +1,5 @@
% \iffalse
-%% File: l3toks.dtx Copyright (C) 1990-2006 LaTeX3 project
+%% File: l3toks.dtx Copyright (C) 1990-2009 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
@@ -17,7 +17,7 @@
%%
%% The development version of the bundle can be found at
%%
-%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/
+%% http://www.latex-project.org/svnroot/experimental/trunk/
%%
%% for those people who are interested.
%%
@@ -36,7 +36,7 @@
\RequirePackage{l3names}
%</driver|package>
%\fi
-\GetIdInfo$Id: l3toks.dtx 728 2008-01-01 16:11:58Z morten $
+\GetIdInfo$Id: l3toks.dtx 1362 2009-05-28 20:19:21Z joseph $
{L3 Experimental Token Registers}
%\iffalse
%<*driver>
@@ -44,9 +44,9 @@
\ProvidesFile{\filename.\filenameext}
[\filedate\space v\fileversion\space\filedescription]
%\iffalse
-\documentclass{l3doc}
+\documentclass[full]{l3doc}
\begin{document}
-\DocInput{\filename.\filenameext}
+\DocInput{l3toks.dtx}
\end{document}
%</driver>
% \fi
@@ -60,70 +60,124 @@
% \date{\filedate}
% \maketitle
%
-% \section {Token Registers}
+% \begin{documentation}
%
-% There is a second form beside token list pointers in which \LaTeX3
+% There is a second form beside token list variables in which \LaTeX3
% stores token lists, namely the internal \TeX{} token registers.
% Functions dealing with these registers got the prefix "\toks_". Unlike
-% token list pointers we have an accessing function as one can see
+% token list variables we have an accessing function as one can see
% below.
%
-% The main difference between \m{toks} (token registers) and \m{tlp} (token
-% list pointers) is their behavior regarding expansion. While \m{tlp}'s
+% The main difference between \m{toks} (token registers) and \m{tl var.}~(token
+% list variable) is their behavior regarding expansion. While \m{tl vars}
% expand fully (i.e., until only unexpandable tokens are left) inside
-% an argument that is subject to expansion (i.e., denote by |x|)
+% an argument that is subject to expansion (i.e., denoted by |x|)
% \m{toks}'s expand always only up to one level, i.e., passing their
% contents without further expansion.
%
-% \subsection{Functions}
-%
-% \begin{function}{%
-% \toks_new:N |
-% \toks_new:c |
-% \toks_new_l:N}
+% There are fewer restrictions on the contents of a token register over
+% a token list variable. So while \meta{token list} is used to describe
+% the contents of both of these, bear in mind that slightly different lists
+% of tokens are allowed in each case. The best (only?) example is that a
+% \meta{toks} can contain the "#" character (i.e., characters of catcode 6),
+% whereas a \meta{tl var.}~will require its input to be sanitised before that is
+% possible.
+%
+% If you're not sure which to use between a \meta{tl var.}~or a \meta{toks},
+% consider what data you're trying to hold. If you're dealing with function
+% parameters involving "#", or building some sort of data structure
+% then you probably want a \meta{toks} (e.g., \file{l3prop} uses \meta{toks}
+% to store its property lists).
+%
+% If you're storing ad-hoc data for later use (possibly from direct user
+% input) then usually a \meta{tl var.}~will be what you want.
+%
+% \section{Allocation and use}
+%
+% \begin{function}{ \toks_new:N |
+% \toks_new:c |
+%^^A \toks_new_l:N |
+% }
% \begin{syntax}
% "\toks_new:N" <toks>
% \end{syntax}
% Defines <toks> to be a new token list register.
+%^^A "\toks_new_l:N" is only defined in the \LaTeX3 kernel.
% \begin{texnote}
% This is the \LaTeX3 allocation for what was called \tn{newtoks} in
% plain \TeX.
% \end{texnote}
% \end{function}
%
-% \begin{function}{%
-% \toks_set:Nn |
-% \toks_set:No |
-% \toks_set:Nd |
-% \toks_set:Nf |
-% \toks_set:Nx |
-% \toks_set:cn |
-% \toks_set:co |
-% \toks_set:cf |
-% \toks_set:cx |
-% \toks_gset:Nn |
-% \toks_gset:No |
-% \toks_gset:Nx}
+% \begin{function}{ \toks_use:N | \toks_use:c }
+% \begin{syntax}
+% "\toks_use:N" <toks>
+% \end{syntax}
+% Accesses the contents of <toks>. Contrary to token list variables
+% <toks> can't be access simply by calling them directly.
+% \begin{texnote}
+% Something like "\the" <toks>.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{ \toks_set:Nn |
+% \toks_set:NV |
+% \toks_set:Nv |
+% \toks_set:No |
+% \toks_set:Nx |
+% \toks_set:Nd |
+% \toks_set:Nf |
+% \toks_set:cn |
+% \toks_set:co |
+% \toks_set:cV |
+% \toks_set:cv |
+% \toks_set:cx |
+% \toks_set:cd |
+% \toks_set:cf }
% \begin{syntax}
-% "\toks_set:Nn" <toks> "{"<token list>"}"
+% "\toks_set:Nn" <toks> \Arg{token list}
% \end{syntax}
-% Defines <toks> to hold the token list <token list>. Global
-% variants of this command assign the value globally the other variants
-% expand the <token list> up to a certain level before the assignment
-% or interpret the <token list> as a character list and form a control
-% sequence out of it.
+% Defines <toks> to hold the token list <token list>.
% \begin{texnote}
% "\toks_set:Nn" could have been specified in plain \TeX{} by <toks> "="
-% "{" <token list> "}" but all other functions have no counterpart in
-% plain \TeX. Additionally the functions above will check for correct
+% \Arg{token list} but all other functions have no counterpart in
+% plain \TeX. Additionally the functions above the global variants described
+% below will check for correct
% local and global assignments, something that isn't available in plain
% \TeX.
% \end{texnote}
% \end{function}
%
-% \begin{function}{%
-% \toks_gset_eq:NN |
-% }
+% \begin{function}{ \toks_gset:Nn |
+% \toks_gset:NV |
+% \toks_gset:No |
+% \toks_gset:Nx |
+% \toks_gset:cn |
+% \toks_gset:cV |
+% \toks_gset:co |
+% \toks_gset:cx }
+% \begin{syntax}
+% "\toks_gset:Nn" <toks> \Arg{token list}
+% \end{syntax}
+% Defines <toks> to globally hold the token list <token list>.
+% \end{function}
+%
+% \begin{function}{ \toks_set_eq:NN |
+% \toks_set_eq:cN |
+% \toks_set_eq:Nc |
+% \toks_set_eq:cc }
+% \begin{syntax}
+% "\toks_set_eq:NN" <toks1> <toks2>
+% \end{syntax}
+% Set <toks1> to the value of <toks2>. Don't try to use
+% "\toks_set:Nn" for this purpose if the second argument is also a
+% token register.
+% \end{function}
+%
+% \begin{function}{ \toks_gset_eq:NN |
+% \toks_gset_eq:cN |
+% \toks_gset_eq:Nc |
+% \toks_gset_eq:cc }
% \begin{syntax}
% "\toks_gset_eq:NN" <toks1> <toks2>
% \end{syntax}
@@ -132,325 +186,251 @@
% token register.
% \end{function}
%
-% \begin{function}{%
-% \toks_clear:N |
-% \toks_gclear:N |
-% }
+% \begin{function}{ \toks_clear:N |
+% \toks_clear:c |
+% \toks_gclear:N |
+% \toks_gclear:c }
% \begin{syntax}
% "\toks_clear:N" <toks>
% \end{syntax}
% The <toks> is locally or globally cleared.
% \end{function}
%
-% \begin{function}{%
-% \toks_put_left:Nn |
-% \toks_gput_left:Nn |
-% \toks_put_right:Nn |
-% \toks_put_right:No |
-% \toks_put_right:Nx |
-% \toks_gput_right:Nn |
-% \toks_gput_right:No |
-% \toks_gput_right:Nx |
-% }
+% \begin{function}{ \toks_use_clear:N |
+% \toks_use_clear:c |
+% \toks_use_gclear:N |
+% \toks_use_gclear:c }
% \begin{syntax}
-% "\toks_put_left:Nn" <toks> "{"<token list>"}"
+% "\toks_use_clear:N" <toks>
% \end{syntax}
-% These functions will append <token list> to the left or right of
-% <toks>. Assignment is done either locally or globally. If possible
-% append to the right since this operation is faster.
+% Accesses the contents of <toks> and clears (locally or globally) it
+% afterwards. Actually the clearing operation is done in a way that does
+% not prohibit the access of the following tokens in the input stream
+% with functions stored in the token register. In other words this
+% function is not exactly the same as calling "\toks_use:N" <toks>
+% "\toks_clear:N" <toks> in sequence.
% \end{function}
%
-% \begin{function}{\toks_use:N}
+% \begin{function}{ \toks_show:N | \toks_show:c}
% \begin{syntax}
-% "\toks_use:N" <toks>
+% "\toks_show:N" <toks>
% \end{syntax}
-% Accesses the contents of <toks>. Contrary to token list pointers
-% <toks> can't be access simply by calling them directly.
+% Displays the contents of <toks> in the terminal output and log file.
+% "#" signs in the <toks> will be shown doubled.
% \begin{texnote}
-% Something like \tn{the} <toks>.
+% Something like "\showthe" <toks>.
% \end{texnote}
% \end{function}
%
-% \begin{function}{\toks_use_clear:N |
-% \toks_use_gclear:N}
+% \section{Adding to the contents of token registers}
+%
+% \begin{function}{ \toks_put_left:Nn |
+% \toks_put_left:NV |
+% \toks_put_left:No |
+% \toks_put_left:Nx |
+% \toks_put_left:cn |
+% \toks_put_left:cV |
+% \toks_put_left:co }
% \begin{syntax}
-% "\toks_use_clear:N" <toks>
+% "\toks_put_left:Nn" <toks> \Arg{token list}
% \end{syntax}
-% Accesses the contents of <toks> and clears (locally or globally) it
-% afterwards. Actually the clearing operation is done in a way that does
-% not prohibit the access of the following tokens in the input stream
-% with functions stored in the token register. In other words this
-% function is not exactly the same as calling "\toks_use:N" <toks>
-% "\toks_clear:N" <toks> in sequence.
+% These functions will append <token list> to the left of
+% <toks>. Assignment is done locally. If possible
+% append to the right since this operation is faster.
% \end{function}
%
-% \subsection{Predicates and conditionals}
+% \begin{function}{ \toks_gput_left:Nn |
+% \toks_gput_left:NV |
+% \toks_gput_left:No |
+% \toks_gput_left:Nx |
+% \toks_gput_left:cn |
+% \toks_gput_left:cV |
+% \toks_gput_left:co }
+% \begin{syntax}
+% "\toks_gput_left:Nn" <toks> \Arg{token list}
+% \end{syntax}
+% These functions will append <token list> to the left of
+% <toks>. Assignment is done globally. If possible
+% append to the right since this operation is faster.
+% \end{function}
%
-% \begin{function}{
-% \toks_if_empty_p:N|
-% \toks_if_empty:NTF|
-% \toks_if_empty:NT |
-% \toks_if_empty:NF|
-% \toks_if_empty_p:c|
-% \toks_if_empty:cTF |
-% \toks_if_empty:cT |
-% \toks_if_empty:cF
-% }
+% \begin{function}{ \toks_put_right:Nn |
+% \toks_put_right:NV |
+% \toks_put_right:No |
+% \toks_put_right:Nx |
+% \toks_put_right:cV |
+% \toks_put_right:cn |
+% \toks_put_right:co }
+% \begin{syntax}
+% "\toks_put_right:Nn" <toks> \Arg{token list}
+% \end{syntax}
+% These functions will append <token list> to the right of
+% <toks>. Assignment is done locally.
+% \end{function}
+%
+% \begin{function}{ \toks_put_right:Nf }
+% \begin{syntax}
+% "\toks_put_right:Nf" <toks> \Arg{token list}
+% \end{syntax}
+% Variant of the above. |:Nf| is used by |template.dtx| and will
+% perhaps be moved to that package.
+% \end{function}
+%
+% \begin{function}{ \toks_gput_right:Nn |
+% \toks_gput_right:NV |
+% \toks_gput_right:No |
+% \toks_gput_right:Nx |
+% \toks_gput_right:cn |
+% \toks_gput_right:cV |
+% \toks_gput_right:co }
% \begin{syntax}
-% "\toks_if_empty:NTF" <toks> "{"<true code>"}{"<false code>"}"
+% "\toks_gput_right:Nn" <toks> \Arg{token list}
% \end{syntax}
-% Tests if <toks> is empty.
+% These functions will append <token list> to the right of
+% <toks>. Assignment is done globally.
% \end{function}
%
-% \subsection{Variable and constants}
+%
+% \section{Predicates and conditionals}
+%
+% \begin{function}{ \toks_if_empty_p:N / (EXP) |
+% \toks_if_empty:N / (EXP)(TF) |
+% \toks_if_empty_p:c / (EXP) |
+% \toks_if_empty:c / (EXP)(TF) }
+% \begin{syntax}
+% "\toks_if_empty:NTF" <toks> \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Expandable test for whether <toks> is empty.
+% \end{function}
+%
+% \begin{function}{ \toks_if_eq:NN / (TF)(EXP) |
+% \toks_if_eq:Nc / (TF)(EXP) |
+% \toks_if_eq:cN / (TF)(EXP) |
+% \toks_if_eq:cc / (TF)(EXP) |
+% \toks_if_eq_p:NN / (EXP) |
+% \toks_if_eq_p:cN / (EXP) |
+% \toks_if_eq_p:Nc / (EXP) |
+% \toks_if_eq_p:cc / (EXP) }
+% \begin{syntax}
+% "\toks_if_eq:NNTF" <toks1> <toks2> \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Expandably tests if <toks1> and <toks2> are equal.
+% \end{function}
+%
+% \section{Variable and constants}
%
% \begin{variable}{\c_empty_toks}
% Constant that is always empty.
% \end{variable}
%
-% \begin{variable}{%
-% \l_tmpa_toks |
-% \l_tmpb_toks |
-% \g_tmpa_toks |
-% \g_tmpb_toks
-% }
+% \begin{variable}{ \l_tmpa_toks |
+% \l_tmpb_toks |
+% \l_tmpc_toks |
+% \g_tmpa_toks |
+% \g_tmpb_toks |
+% \g_tmpc_toks }
% Scratch register for immediate use. They are not used by conditionals
% or predicate functions.
% \end{variable}
%
-% \subsubsection{Internal functions}
+% \begin{variable}{ \l_tl_replace_toks }
+% A placeholder for contents of functions replacing contents of strings.
+% \end{variable}
%
-% \begin{function}{\toks_put_left_aux:w}
-% Used by "\toks_put_left:Nn" and its variants.
-% \end{function}
+% \end{documentation}
%
-% \begin{function}{\tex_toksdef:D}
-% Primitive function for defining a <cs> to correspond to a token
-% register should not be used by a programmer.
-% \begin{texnote}
-% This function was named \tn{toksdef}.
-% \end{texnote}
-% \end{function}
-%
-% \StopEventually{}
+% \begin{implementation}
%
-% \subsection{The Implementation}
+% \section{\pkg{l3toks} implementation}
%
% We start by ensuring that the required packages are loaded.
-% We check for \texttt{l3expan} since this a basic package that is
-% essential for use of any higher-level package.
% \begin{macrocode}
-%<package>\ProvidesExplPackage
-%<package> {\filename}{\filedate}{\fileversion}{\filedescription}
-%<package&check>\RequirePackage{l3chk}\par
-%<package>\RequirePackage{l3expan}\par
+%<*package>
+\ProvidesExplPackage
+ {\filename}{\filedate}{\fileversion}{\filedescription}
+\package_check_loaded_expl:
+%</package>
%<*initex|package>
% \end{macrocode}
%
-% \begin{macro}{\toks_new:N}
-% \begin{macro}{\toks_new_l:N}
-% \begin{macro}{\toks_new:c}
-% Allocates a new token register. This function is already defined above.
+% \subsection{Allocation and use}
+%
+% \begin{macro}{\toks_new:N,\toks_new:c}
+%^^A \begin{macro}{\toks_new_l:N}
+% Allocates a new token register.
% \begin{macrocode}
%<*initex>
\alloc_setup_type:nnn {toks} \c_zero \c_max_register_num
-\def_new:Npn \toks_new:N #1{\alloc_reg:NnNN g {toks} \tex_toksdef:D #1}
-\def_new:Npn \toks_new_l:N #1{\alloc_reg:NnNN l {toks} \tex_toksdef:D #1}
+\cs_new_nopar:Npn \toks_new:N #1 { \alloc_reg:NnNN g {toks} \tex_toksdef:D #1 }
+\cs_new_nopar:Npn \toks_new_l:N #1 { \alloc_reg:NnNN l {toks} \tex_toksdef:D #1 }
%</initex>
-%<package>\let:NN \toks_new:N \newtoks % nick from LaTeX for the moment
-\def_new:Npn \toks_new:c {\exp_args:Nc\toks_new:N}
+%<package>\cs_set_eq:NN \toks_new:N \newtoks % nick from LaTeX for the moment
+\cs_generate_variant:Nn \toks_new:N {c}
% \end{macrocode}
% \end{macro}
-% \end{macro}
-% \end{macro}
+%^^A \end{macro}
%
-% \begin{macro}{\toks_clear:N}
-% \begin{macro}{\toks_gclear:N}
-% These functions clear a token register, either locally or globally.
-% \begin{macrocode}
-\def_new:Npn \toks_clear:N #1{#1\c_empty_toks
-%<*check>
- \chk_local_or_pref_global:N #1
-%</check>
-}
-\def_new:Npn \toks_gclear:N {
-%<*check>
- \pref_global_chk:
-%</check>
-%<-check> \pref_global:D
- \toks_clear:N}
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
%
% \begin{macro}{\toks_use:N}
% \begin{macro}{\toks_use:c}
-% This function just returns the contents of a token register.
+% This function returns the contents of a token register.
% \begin{macrocode}
-\let_new:NN \toks_use:N \the_internal:D
-\def_new:Npn \toks_use:c {\exp_args:Nc\toks_use:N}
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\toks_use_clear:N}
-% \begin{macro}{\toks_use_gclear:N}
-% 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.
-% A direct implementation will save one |\exp_after:NN| but for the
-% sake of checking we do it this way now.
-% \begin{macrocode}
-\def_new:Npn \toks_use_clear:N#1{
- \exp_after:NN
- \toks_clear:N
- \exp_after:NN
- #1
- \toks_use:N#1}
-\def_new:Npn \toks_use_gclear:N{
-%<*check>
- \pref_global_chk:
-%</check>
-%<-check> \pref_global:D
- \toks_use_clear:N}
+\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_put_left:Nn}
-% \begin{macro}{\toks_put_left:No}
-% \begin{macro}{\toks_gput_left:Nn}
-% \begin{macro}{\toks_gput_left:Nx}
-% \begin{macro}{\toks_put_left_aux:w}
-% |\toks_put_left:Nn |\zz{toks}\zv{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}
-\def_new:Npn \toks_put_left:Nn #1{
- \exp_after:NN\toks_put_left_aux:w\exp_after:NN\q_mark
- \toks_use:N #1\q_stop #1}
-\def_new:Npn \toks_put_left:No {\exp_args:NNo \toks_put_left:Nn}
-\def_new:Npn \toks_gput_left:Nn {
-%<*check>
- \pref_global_chk:
-%</check>
-%<-check> \pref_global:D
- \toks_put_left:Nn}
-\def_new:Npn \toks_gput_left:Nx {\exp_args:NNx \toks_gput_left:Nn}
-% \end{macrocode}
-% A helper function for |\toks_put_left:Nn|. Its arguments are
-% subsequently the tokens of \zv{stuff\/}, the token register
-% \zz{toks} and the current contents of \zz{toks}. We make sure to
-% remove the token we inserted earlier.
-% \begin{macrocode}
-\def_long_new:Npn \toks_put_left_aux:w #1\q_stop #2#3{
- #2\exp_after:NN{\use_arg_i:nn{#3}#1}
-%<*check>
- \chk_local_or_pref_global:N #2
-%</check>
-}
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\toks_put_right:Nn}
-% \begin{macro}{\toks_gput_right:Nn}
-% \begin{macro}{\toks_put_right:No}
-% \begin{macro}{\toks_put_right:Nd}
-% \begin{macro}{\toks_put_right:Nf}
-% \begin{macro}{\toks_put_right:Nx}
-% \begin{macro}{\toks_gput_right:No}
-% \begin{macro}{\toks_gput_right:Nx}
-% These macros add a list of tokens to the right of a token register.
-% \begin{macrocode}
-\def_long_new:Npn \toks_put_right:Nn #1#2{#1\exp_after:NN{\toks_use:N #1#2}
-%<*check>
- \chk_local_or_pref_global:N #1
-%</check>
-}
-\def_new:Npn \toks_gput_right:Nn {
-%<*check>
- \pref_global_chk:
-%</check>
-%<-check> \pref_global:D
- \toks_put_right:Nn}
-% \end{macrocode}
-% |\toks_gput_right:Nx| expands its (second) argument.
-% \begin{macrocode}
-%<check>\def_new:Npn \toks_put_right:No {\exp_args:NNo \toks_put_right:Nn }
-%<-check>\def_long_new:Npn\toks_put_right:No#1#2{#1\exp_after:NN\exp_after:NN
-%<-check>\exp_after:NN{\exp_after:NN\toks_use:N\exp_after:NN #1#2}}
-%<check>\def_new:Npn \toks_put_right:Nd {\exp_args:NNd \toks_put_right:Nn }
-%<-check>\def_long_new:Npn\toks_put_right:Nd#1#2{
-%<-check> \exp_after:NN\toks_put_right:No\exp_after:NN#1\exp_after:NN{#2}}
-% \end{macrocode}
-% 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>\def_new:Npn \toks_put_right:Nf {\exp_args:NNf \toks_put_right:Nn }
-%<-check>\def_long_new:Npn \toks_put_right:Nf #1#2{
-%<-check> #1\exp_after:NN\exp_after:NN\exp_after:NN{
-%<-check> \exp_after:NN\toks_use:N\exp_after:NN #1\int_to_roman:w -`0#2}}
-\def_new:Npn \toks_put_right:Nx {\exp_args:NNx \toks_put_right:Nn }
-\def_new:Npn \toks_gput_right:No {\exp_args:NNo\toks_gput_right:Nn}
-\def_new:Npn \toks_gput_right:Nx {\exp_args:NNx\toks_gput_right:Nn}
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \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:Nd}
% \begin{macro}{\toks_set:Nf}
-% \begin{macro}{\toks_set:Nx}
% \begin{macro}{\toks_set:cn}
% \begin{macro}{\toks_set:co}
-% \begin{macro}{\toks_set:cf}
+% \begin{macro}{\toks_set:cV}
+% \begin{macro}{\toks_set:cv}
% \begin{macro}{\toks_set:cx}
+% \begin{macro}{\toks_set:cd}
+% \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>
-\def_new:Npn \toks_set:Nn #1{\chk_local:N #1#1}
+\cs_new_nopar:Npn \toks_set:Nn #1 { \chk_local:N #1 #1 }
+\cs_generate_variant:Nn \toks_set:Nn {No,Nd,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> \let_new:NN \toks_set:Nn\use_noop:
-%<-check> \def_long_new:Npn \toks_set:No#1#2{#1\exp_after:NN{#2}}
-%<-check> \def_long_new:Npn \toks_set:Nd#1#2{
-%<-check> #1\exp_after:NN\exp_after:NN\exp_after:NN{#2}}
-%<check> \def_new:Npn \toks_set:No {\exp_args:NNo \toks_set:Nn}
-%<check> \def_new:Npn \toks_set:Nd {\exp_args:NNd \toks_set:Nn}
-\def_new:Npn \toks_set:Nx {\exp_args:NNx \toks_set:Nn}
+%<*!check>
+\cs_new_eq:NN \toks_set:Nn \prg_do_nothing:
+\cs_new:Npn \toks_set:NV #1#2 {
+ #1 \exp_after:wN { \int_to_roman:w -`0 \exp_eval_register:N #2 }
+}
+\cs_new:Npn \toks_set:Nv #1#2 {
+ #1 \exp_after:wN { \int_to_roman:w -`0 \exp_eval_register:c {#2} }
+}
+\cs_new:Npn \toks_set:No #1#2 { #1 \exp_after:wN {#2} }
+\cs_new:Npn \toks_set:Nd #1#2 {
+ #1 \exp_after:wN \exp_after:wN \exp_after:wN {#2}
+}
+\cs_new:Npn \toks_set:Nf #1#2 {
+ #1 \exp_after:wN { \int_to_roman:w -`0#2 }
+}
+%</!check>
% \end{macrocode}
-% We implement |\toks_set:Nf| by hand when not checking because this
-% is going to be used \emph{extensively} in keyval processing!
+%
% \begin{macrocode}
-%<check>\def_new:Npn \toks_set:Nf {\exp_args:NNf \toks_set:Nn}
-%<-check>\def_long_new:Npn\toks_set:Nf #1#2{
-%<-check> #1\exp_after:NN{\int_to_roman:w -`0#2}}
-\def_new:Npn \toks_set:cf {\exp_args:Nc\toks_set:Nf}
-\def_new:Npn \toks_set:cn {\exp_args:Nc\toks_set:Nn}
-\def_new:Npn \toks_set:co {\exp_args:Nc\toks_set:No}
-\def_new:Npn \toks_set:cx {\exp_args:Nc\toks_set:Nx}
+\cs_generate_variant:Nn \toks_set:Nn {Nx,cn,cV,cv,co,cx,cd,cf}
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -461,24 +441,25 @@
% \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>
-\def_new:Npn \toks_gset:Nn #1{\chk_global:N #1\pref_global:D#1}
-%</check>
-%<-check> \let_new:NN \toks_gset:Nn\pref_global:D
-\def_new:Npn \toks_gset:No {\exp_args:NNo \toks_gset:Nn}
-\def_new:Npn \toks_gset:Nx {\exp_args:NNx \toks_gset:Nn}
-\def_new:Npn \toks_gset:cn {\exp_args:Nc \toks_gset:Nn}
-\def_new:Npn \toks_gset:co {\exp_args:Nc \toks_gset:No}
-\def_new:Npn \toks_gset:cx {\exp_args:Nc \toks_gset:Nx}
+%<check>\cs_new_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}
@@ -486,6 +467,8 @@
% \end{macro}
% \end{macro}
% \end{macro}
+% \end{macro}
+% \end{macro}
%
% \begin{macro}{\toks_set_eq:NN}
% \begin{macro}{\toks_set_eq:Nc}
@@ -499,23 +482,23 @@
% in \m{toks1}.
% \begin{macrocode}
%<*check>
-\def_new:Npn\toks_set_eq:NN#1#2{
- \chk_local:N#1
- \chk_var_or_const:N#2
- #1#2}
-\def_new:Npn\toks_gset_eq:NN#1#2{
- \chk_global:N#1
- \chk_var_or_const:N#2
- \pref_global:D#1#2}
+\cs_new_nopar:Npn\toks_set_eq:NN #1#2 {
+ \chk_local:N #1
+ \chk_var_or_const:N #2
+ #1 #2
+}
+\cs_new_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> \let_new:NN \toks_set_eq:NN \use_noop:
-%<-check> \let_new:NN \toks_gset_eq:NN \pref_global:D
-\def_new:Npn \toks_set_eq:Nc {\exp_args:NNc\toks_set_eq:NN}
-\def_new:Npn \toks_set_eq:cN {\exp_args:Nc\toks_set_eq:NN}
-\def_new:Npn \toks_set_eq:cc {\exp_args:Ncc\toks_set_eq:NN}
-\def_new:Npn \toks_gset_eq:Nc {\exp_args:NNc\toks_gset_eq:NN}
-\def_new:Npn \toks_gset_eq:cN {\exp_args:Nc\toks_gset_eq:NN}
-\def_new:Npn \toks_gset_eq:cc {\exp_args:Ncc\toks_gset_eq:NN}
+%<*!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}
@@ -526,31 +509,126 @@
% \end{macro}
% \end{macro}
%
-% \begin{macro}{\toks_if_empty_p:N}
-% \begin{macro}{\toks_if_empty_p:c}
-% \begin{macro}{\toks_if_empty:NTF}
-% \begin{macro}{\toks_if_empty:cTF}
-% \begin{macro}{\toks_if_empty:NT}
-% \begin{macro}{\toks_if_empty:cT}
-% \begin{macro}{\toks_if_empty:NF}
-% \begin{macro}{\toks_if_empty:cF}
-% |\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{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_nopar:Npn \toks_clear:N #1 {
+ #1\c_empty_toks
+%<check>\chk_local_or_pref_global:N #1
+}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_new_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_nopar:Npn \toks_use_clear:N #1 {
+ \exp_last_unbraced:NNV \toks_clear:N #1 #1
+}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_new_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.
+% TODO: this is not pretty when the argument is a control sequence that doesn't exist!
+% \begin{macrocode}
+\cs_new_eq:NN \toks_show:N \tex_showthe:D
+\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_nopar:Npn \toks_put_left:Nn #1 {
+ \exp_after:wN \toks_put_left_aux:w \exp_after:wN \q_mark
+ \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_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}
-\def_new:Npn\toks_if_empty_p:N#1{
- \if:w \tlist_if_empty_p:o{\toks_use:N #1}
- \c_true
- \else:
- \c_false
- \fi:
+\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
}
-\def_test_function_new:npn{toks_if_empty:N}#1{\if:w \toks_if_empty_p:N #1}
-\def_new:Npn\toks_if_empty:cTF{\exp_args:Nc\toks_if_empty:NTF}
-\def_new:Npn\toks_if_empty:cT{\exp_args:Nc\toks_if_empty:NT}
-\def_new:Npn\toks_if_empty:cF{\exp_args:Nc\toks_if_empty:NF}
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -560,49 +638,61 @@
% \end{macro}
% \end{macro}
% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
%
-% \begin{macro}{\toks_if_eq:NNTF}
-% \begin{macro}{\toks_if_eq:NNT}
-% \begin{macro}{\toks_if_eq:NNF}
-% \begin{macro}{\toks_if_eq:NcTF}
-% \begin{macro}{\toks_if_eq:NcT}
-% \begin{macro}{\toks_if_eq:NcF}
-% \begin{macro}{\toks_if_eq:cNTF}
-% \begin{macro}{\toks_if_eq:cNT}
-% \begin{macro}{\toks_if_eq:cNF}
-% \begin{macro}{\toks_if_eq:ccTF}
-% \begin{macro}{\toks_if_eq:ccT}
-% \begin{macro}{\toks_if_eq:ccF}
-% \begin{macro}{\toks_if_eq_p:NN}
-% \begin{macro}{\toks_if_eq_p:cN}
-% \begin{macro}{\toks_if_eq_p:Nc}
-% \begin{macro}{\toks_if_eq_p:cc}
-% This function test whether two token registers contain the same.
+% \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}
-\def_new:NNn \toks_if_eq:NNTF 2 {
- \tlist_if_eq:xxTF{\toks_use:N #1}{\toks_use:N #2}
+\cs_new:Npn \toks_put_right:Nn #1#2 {
+ #1 \exp_after:wN { \toks_use:N #1 #2 }
+%<check> \chk_local_or_pref_global:N #1
}
-\def_new:NNn \toks_if_eq:NNT 2 {
- \tlist_if_eq:xxT{\toks_use:N #1}{\toks_use:N #2}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_new_nopar:Npn \toks_gput_right:Nn {
+%<check> \pref_global_chk:
+%<!check> \pref_global:D
+ \toks_put_right:Nn
}
-\def_new:NNn \toks_if_eq:NNF 2 {
- \tlist_if_eq:xxF{\toks_use:N #1}{\toks_use:N #2}
+% \end{macrocode}
+% A couple done by hand for speed.
+% \begin{macrocode}
+%<check>\cs_generate_variant:Nn \toks_put_right:Nn {No}
+%<*!check>
+\cs_new: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
+ }
}
-\def_new:Npn \toks_if_eq:NcTF {\exp_args:NNc \toks_if_eq:NNTF}
-\def_new:Npn \toks_if_eq:NcT {\exp_args:NNc \toks_if_eq:NNT}
-\def_new:Npn \toks_if_eq:NcF {\exp_args:NNc \toks_if_eq:NNF}
-\def_new:Npn \toks_if_eq:cNTF {\exp_args:Nc \toks_if_eq:NNTF}
-\def_new:Npn \toks_if_eq:cNT {\exp_args:Nc \toks_if_eq:NNT}
-\def_new:Npn \toks_if_eq:cNF {\exp_args:Nc \toks_if_eq:NNF}
-\def_new:Npn \toks_if_eq:ccTF {\exp_args:Ncc \toks_if_eq:NNTF}
-\def_new:Npn \toks_if_eq:ccT {\exp_args:Ncc \toks_if_eq:NNT}
-\def_new:Npn \toks_if_eq:ccF {\exp_args:Ncc \toks_if_eq:NNF}
-\def_new:NNn \toks_if_eq_p:NN 2 {
- \tlist_if_eq_p:xx {\toks_use:N #1} {\toks_use:N #2}
+\cs_new: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
+ }
}
-\def_new:Npn \toks_if_eq_p:cN {\exp_args:Nc \toks_if_eq_p:NN}
-\def_new:Npn \toks_if_eq_p:Nc {\exp_args:NNc \toks_if_eq_p:NN}
-\def_new:Npn \toks_if_eq_p:cc {\exp_args:Ncc \toks_if_eq_p:NN}
+%</!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}
@@ -618,18 +708,73 @@
% \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: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} {
+ \tl_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 register \ldots
+% Some scratch registers \ldots
% \begin{macrocode}
-\tex_toksdef:D \l_tmpa_toks = 255
+\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
@@ -651,81 +796,27 @@
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\toks_remove_extra_brace_group:N}
-% \begin{macro}{\toks_remove_extra_brace_group_aux:NNw}
-% Small function for removing an extra brace group if present. Hmm,
-% not really needed anymore.
+% \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}
-\def_new:Npn \toks_remove_extra_brace_group:N #1{
- \exp_after:NN \toks_remove_extra_brace_group_aux:NNw
- \exp_after:NN \toks_set:Nn \exp_after:NN #1
- \toks_use:N#1\q_nil
-}
-\def_long_new:Npn\toks_remove_extra_brace_group_aux:NNw #1#2#3\q_nil{#1#2{#3}}
+\toks_new:N \l_tl_replace_toks
% \end{macrocode}
% \end{macro}
-% \end{macro}
%
-% Show token usage:
% \begin{macrocode}
%</initex|package>
+% \end{macrocode}
+%
+% Show token usage:
+% \begin{macrocode}
%<*showmemory>
\showMemUsage
%</showmemory>
% \end{macrocode}
%
-% \endinput
-%
-% $Log$
-% Revision 1.25 2006/08/01 01:54:12 morten
-% Prevent brace stripping in \toks_put_left:Nn and friends.
-%
-% Revision 1.24 2006/03/20 18:26:40 braams
-% Updated the copyright notice (2006) and demoted all implementation
-% sections to subsections and so on to clean up the toc for source3.tex
-%
-% Revision 1.23 2006/02/16 23:32:49 braams
-% Imported \toks_put_left:No from l3messages
-%
-% Revision 1.22 2006/01/21 11:43:20 morten
-% Tuned some of the \toks_set and \toks_put_right functions since they
-% are going to be used intensively in the l3keyval module which is again
-% going to be heavily used.
-%
-% Revision 1.21 2006/01/20 12:22:44 morten
-% Minor changes plus added \toks_remove_extra_brace_group:N for l3keyval
-% module
-%
-% Revision 1.20 2005/12/27 10:03:39 morten
-% Changed RCS information retrieval
-%
-% Revision 1.19 2005/12/23 13:24:39 morten
-% Added a few functions from template
-%
-% Revision 1.18 2005/12/21 20:44:04 morten
-% Corrected typo.
-%
-% Revision 1.17 2005/12/02 15:56:48 morten
-% Added some more functions and improved test for emptiness.
-%
-% Revision 1.16 2005/04/12 13:22:37 morten
-% More functions added
-%
-% Revision 1.15 2005/04/07 08:18:17 morten
-% Only put 255 in the toks stack when running initex
-%
-% Revision 1.14 2005/04/06 22:35:50 braams
-% Now we have register allocation fitted
-%
-% Revision 1.13 2005/04/06 21:37:50 morten
-% Added some more functions
-%
-% Revision 1.12 2005/03/15 23:39:21 braams
-% Some fiddling to get it loaded by initex; needs a way to allocate
-% token registers for it to work.
-%
-% Revision 1.11 2005/03/11 21:25:06 braams
-% Changed copyright year, fixed use of RCS values;
-% fixed a few typos in the documentation;
-% \c_if_empty_toks had to be \c_empty_toks
+% \end{implementation}
+% \PrintIndex
%
+% \endinput
+
diff --git a/Master/texmf-dist/source/latex/expl3/l3vers.dtx b/Master/texmf-dist/source/latex/expl3/l3vers.dtx
index b3cbde577bd..c61d07ce94c 100644
--- a/Master/texmf-dist/source/latex/expl3/l3vers.dtx
+++ b/Master/texmf-dist/source/latex/expl3/l3vers.dtx
@@ -1,5 +1,5 @@
% \iffalse
-%% File: l3vers.dtx Copyright (C) 1990-2008 LaTeX3 project
+%% File: l3vers.dtx Copyright (C) 1990-2009 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
@@ -17,7 +17,7 @@
%%
%% The development version of the bundle can be found at
%%
-%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/
+%% http://www.latex-project.org/svnroot/experimental/trunk/
%%
%% for those people who are interested.
%%
@@ -35,7 +35,7 @@
\RequirePackage{l3names}
%</driver|package>
%\fi
-\GetIdInfo$Id: l3vers.dtx 769 2008-08-05 19:48:40Z morten $
+\GetIdInfo$Id: l3vers.dtx 1378 2009-06-01 19:15:56Z joseph $
{L3 Experimental LaTeX format version}
%\iffalse
%<*driver>
@@ -43,28 +43,45 @@
\ProvidesFile{\filename.\filenameext}
[\filedate\space v\fileversion\space\filedescription]
%\iffalse
-\documentclass{l3doc}
+\documentclass[full]{l3doc}
\begin{document}
\DocInput{\filename.\filenameext}
\end{document}
%</driver>
% \fi
%
+% \begin{documentation}
+%
% \section{Version Identification}
% Here we identify the date and version number of this release of
% \LaTeX3, and set |\tex_everyjob:D| so that it is printed at the start of
% every \LaTeX3 run.
%
-% \StopEventually{}
+% \begin{variable}{\c_format_name|\c_format_date}
+% Name and date.
+% \end{variable}
+%
+% \begin{variable}{\c_fmt_too_old}
+% Age in months past "\c_format_date" after which an error is called
+% during format generation.
+% \end{variable}
+%
+% \begin{function}{\chk_format_age:w}
+% Function that calculates the age of the format and calls an error if it
+% is too old.
+% \end{function}
%
+% \end{documentation}
+%
+% \begin{implementation}
%
% \begin{macro}{\c_format_name}
% \begin{macro}{\c_format_date}
% \begin{macrocode}
%<*initex>
-\def:Npn\c_format_name{Experimental~ LaTeX3}
-\def:Npn\c_format_date{2008/08/05}
-%^^A\def:Npx\c_format_version{--release--date--goes--here--}
+\cs_set_nopar:Npn\c_format_name{Experimental~ LaTeX3}
+\cs_set_nopar:Npn\c_format_date{2009/06/01}
+%^^A\cs_set_nopar:Npx\c_format_version{--release--date--goes--here--}
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -74,18 +91,18 @@
% Check that the format being made is not too old. While in development
% it should be a rather small number.
% \begin{macrocode}
-\const_new:Nn \c_fmt_too_old{12}
-\def:Npn\chk_format_age:w #1/#2/#3\q_stop{
+\int_const:Nn \c_fmt_too_old{12}
+\cs_set_nopar:Npn\chk_format_age:w #1/#2/#3\q_stop{
% \end{macrocode}
% We just calculate the age of this file in months and give a warning
% if deemed too old.
% \begin{macrocode}
- \num_compare:nNnT{(\tex_year:D-#1)*12+\tex_month:D-#2}>\c_fmt_too_old
- {\iow_expanded_term:n{^^J
+ \intexpr_compare:nNnT{(\tex_year:D-#1)*12+\tex_month:D-#2}>\c_fmt_too_old
+ {\iow_term:x{^^J
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!^^J
!~~You~are~attempting~to~make~an~experimental~LaTeX3~format~from^^J
!~~source~files~that~are~more~than~
- \num_value:w\num_eval:n{\c_fmt_too_old}~months~old.^^J
+ \intexpr_eval:n{\c_fmt_too_old}~months~old.^^J
!^^J
!~~If~you~enter~<return>~to~scroll~past~this~message~then~the~format^^J
!~~will~be~built,~but~please~consider~obtaining~newer~source~files^^J
@@ -96,7 +113,7 @@
To~avoid~this~error~message,~obtain~new~Experimental~LaTeX3~sources.}
\tex_errmessage:D{
Experimental~LaTeX3~source~files~are~more~than~
- \num_use:N\num_eval:n{\c_fmt_too_old}~months~old!}
+ \intexpr_eval:n{\c_fmt_too_old}~months~old!}
}
}
% \end{macrocode}
@@ -104,7 +121,7 @@
% \end{macro}
% Then we execute it.
% \begin{macrocode}
-\exp_after:NN\chk_format_age:w\c_format_date\q_stop
+\exp_after:wN\chk_format_age:w\c_format_date\q_stop
% \end{macrocode}
% And since it's no longer needed we remove it again.
% \begin{macrocode}
@@ -114,27 +131,12 @@
% This startup banner may be further modified by the code in
% |ltfinal.dtx| if a patch file is present.
% \begin{macrocode}
-\tex_everyjob:D{\io_put_term:x{\c_format_name,~<\c_format_date>}}
-\io_put_term:x{\c_format_name,~<\c_format_date>}
+\tex_everyjob:D{\iow_term:x{\c_format_name,~<\c_format_date>}}
+\iow_term:x{\c_format_name,~<\c_format_date>}
%</initex>
% \end{macrocode}
%
-% \endinput
-%
-% $Log$
-% Revision 1.5 2005/12/27 15:54:15 morten
-% Changed RCS information retrieval
-%
-% Revision 1.4 2005/04/13 09:52:47 morten
-% Fix spaces in messages, make fast calculation of format age, fixed \DocInput, added \endinput
-%
-% Revision 1.3 2005/04/12 22:42:22 braams
-% Removed a few redundant lines with docstrip instructions
-%
-% Revision 1.2 2005/04/11 22:46:47 braams
-% Translated this file into the ltx3 lingo
-% This file may need further cleanup at a later stage
-%
-% Revision 1.1 2005/03/11 21:26:31 braams
-% File copied from 2e for now, to hold the format version identification
+% \end{implementation}
+% \PrintIndex
%
+% \endinput
diff --git a/Master/texmf-dist/source/latex/expl3/l3xref.dtx b/Master/texmf-dist/source/latex/expl3/l3xref.dtx
index 742def4b143..c0f0fa791ac 100644
--- a/Master/texmf-dist/source/latex/expl3/l3xref.dtx
+++ b/Master/texmf-dist/source/latex/expl3/l3xref.dtx
@@ -1,5 +1,5 @@
% \iffalse
-%% File: l3xref.dtx Copyright (C) 2006 LaTeX3 project
+%% File: l3xref.dtx Copyright (C) 2006,2009 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
@@ -17,7 +17,7 @@
%%
%% The development version of the bundle can be found at
%%
-%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/
+%% http://www.latex-project.org/svnroot/experimental/trunk/
%%
%% for those people who are interested.
%%
@@ -36,7 +36,7 @@
\RequirePackage{l3names}
%</driver|package|testfile>
%\fi
-\GetIdInfo$Id: l3xref.dtx 621 2007-09-01 20:14:19Z morten $
+\GetIdInfo$Id: l3xref.dtx 1362 2009-05-28 20:19:21Z joseph $
{L3 Experimental cross referencing}
%\iffalse
%<*testfile>
@@ -48,7 +48,7 @@
\ProvidesFile{\filename.\filenameext}
[\filedate\space v\fileversion\space\filedescription]
%\iffalse
-\documentclass{l3doc}
+\documentclass[full]{l3doc}
\begin{document}
\DocInput{\filename.\filenameext}
\end{document}
@@ -64,12 +64,11 @@
% \date{\filedate}
% \maketitle
%
-%
-% \section{Cross references}
+% \begin{documentation}
%
% \begin{function}{\xref_set_label:n}
% \begin{syntax}
-% "\xref_set_label:n" "{"<name>"}"
+% "\xref_set_label:n" \Arg{name}
% \end{syntax}
% Sets a label in the text. Note that this function does not do
% anything else than setting the correct labels. In particular, it
@@ -79,10 +78,10 @@
%
% \begin{function}{\xref_new:nn}
% \begin{syntax}
-% "\xref_new:nn" "{"<type>"}" "{"<value>"}"
+% "\xref_new:nn" \Arg{type} \Arg{value}
% \end{syntax}
% Defines a new cross reference type <type>. This defines the token
-% list pointer |\l_xref_curr_|<type>|_tlp| with default value
+% list variable |\l_xref_curr_|<type>|_tl| with default value
% <value> which gets written fully expanded when |\xref_set_label:n|
% is called.
% \end{function}
@@ -90,57 +89,73 @@
%
% \begin{function}{\xref_deferred_new:nn}
% \begin{syntax}
-% "\xref_deferred_new:nn" "{"<type>"}" "{"<value>"}"
+% "\xref_deferred_new:nn" \Arg{type} \Arg{value}
% \end{syntax}
% Same as |\xref_new:n| except for this one, the value written
% happens when \TeX\ ships out the page. Page numbers use this one
% obviously.
% \end{function}
%
-% \begin{function}{\xref_get_value:nn}
+% \begin{function}{\xref_get_value:nn / (EXP)}
% \begin{syntax}
-% "\xref_get_value:nn" "{"<type>"}" "{"<name>"}"
+% "\xref_get_value:nn" \Arg{type} \Arg{name}
% \end{syntax}
% Extracts the cross reference information of type <type> for the
% label <name>. This operation is expandable.
% \end{function}
%
%
-% \StopEventually{}
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3xref} implementation}
%
-% \subsection{Implementation}
+% \subsection{Internal functions and variables}
%
+% \begin{variable}{ \g_xref_all_curr_immediate_fields_prop |
+% \g_xref_all_curr_deferred_fields_prop }
+% What they say they are ":)"
+% \end{variable}
+%
+% \begin{variable}{ \xref_write }
+% A stream for writing cross references, although they are not required
+% to be in a separate file.
+% \end{variable}
+%
+% \begin{function}{\xref_define_label:nn}
+% \begin{syntax}
+% "\xref_define_label:nn" \Arg{name} \Arg{plist contents}
+% \end{syntax}
+% Define the property list for each label; used internally by
+% "\xref_set_label:n".
+% \end{function}
+%
+% \subsection{Module code}
%
% We start by ensuring that the required packages are loaded.
% \begin{macrocode}
%<*package>
\ProvidesExplPackage
{\filename}{\filedate}{\fileversion}{\filedescription}
-\RequirePackage{l3quark}
-\RequirePackage{l3toks}
-\RequirePackage{l3io}
-\RequirePackage{l3prop}
-\RequirePackage{l3int}
-\RequirePackage{l3token}
+\package_check_loaded_expl:
%</package>
%<*initex|package>
% \end{macrocode}
%
-%
-%
% There are two kinds of information, namely information which is
% \emph{immediate} like a section title and then there's \emph{deferred}
% information like page numbers. Each reference type belong to one of
% these categories, which we save internally as the property lists
-% |\g_xref_all_curr_immediate_fields_plist| and
-% |\g_xref_all_curr_deferred_fields_plist| and the reference type
+% |\g_xref_all_curr_immediate_fields_prop| and
+% |\g_xref_all_curr_deferred_fields_prop| and the reference type
% \meta{xyz} exists as the key-info pair |\xref_|\meta{xyz}|_key|
-% |{\l_xref_curr_|\meta{xyz}|_tlp}| on one of these lists. This way each
+% |{\l_xref_curr_|\meta{xyz}|_tl}| on one of these lists. This way each
% new entry type is just added as another key-info pair.
%
% When the cross references are generated at the beginning of the
% document each will turn into a control sequence. Thus |\label{mylab}|
-% will internally refer to the property list |\g_xref_mylab_plist|.
+% will internally refer to the property list |\g_xref_mylab_prop|.
%
% The extraction of values from this property list can be done in
% several different ways but we want to keep the operation
@@ -156,52 +171,54 @@
% argument is the type and the second the label name so here it would
% be |\xref_get_value:nn| |{xyz}| |{mylab}|.
%
-% \begin{macro}{\g_xref_all_curr_immediate_fields_plist}
-% \begin{macro}{\g_xref_all_curr_deferred_fields_plist}
+% \begin{macro}{\g_xref_all_curr_immediate_fields_prop}
+% \begin{macro}{\g_xref_all_curr_deferred_fields_prop}
% The two main property lists for storing information. They contain
% key-info pairs for all known types.
% \begin{macrocode}
-\prop_new:N \g_xref_all_curr_immediate_fields_plist
-\prop_new:N \g_xref_all_curr_deferred_fields_plist
+\prop_new:N \g_xref_all_curr_immediate_fields_prop
+\prop_new:N \g_xref_all_curr_deferred_fields_prop
% \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\xref_new:nn}
% \begin{macro}{\xref_deferred_new:nn}
-% \begin{macro}{\xref_new_aux:nnn}
+% \begin{macro}[aux]{\xref_new_aux:nnn}
% Setting up a new cross reference type is fairly straight forward
% when we follow the game plan mentioned earlier.
% \begin{macrocode}
-\def_new:Npn \xref_new:nn {\xref_new_aux:nnn{immediate}}
-\def_new:Npn \xref_deferred_new:nn {\xref_new_aux:nnn{deferred}}
-\def_new:Npn \xref_new_aux:nnn #1#2#3{
+\cs_new_nopar:Npn \xref_new:nn {\xref_new_aux:nnn{immediate}}
+\cs_new_nopar:Npn \xref_deferred_new:nn {\xref_new_aux:nnn{deferred}}
+\cs_new_nopar:Npn \xref_new_aux:nnn #1#2#3{
% \end{macrocode}
% First put the new type in the relevant property list.
% \begin{macrocode}
- \prop_gput:ccx {g_xref_all_curr_ #1 _fields_plist}
+ \prop_gput:ccx {g_xref_all_curr_ #1 _fields_prop}
{ xref_ #2 _key }
- { \exp_not:c {l_xref_curr_#2_tlp }}
+ { \exp_not:c {l_xref_curr_#2_tl }}
% \end{macrocode}
% Then define the key to be a protected macro.\footnote{We could also
% set it equal to \cs{scan_stop:} but this just feels ``cleaner''.}
% \begin{macrocode}
- \def_protected:cpn { xref_#2_key }{}
- \tlp_new:cn{l_xref_curr_#2_tlp}{#3}
+ \cs_set_protected_nopar:cpn { xref_#2_key }{}
+ \tl_new:cn{l_xref_curr_#2_tl}{#3}
% \end{macrocode}
% Now for the function extracting the value of a reference. We could
% do this with a simple |\prop_if_in| thing put since we want to do
% things in an expandable way we make a separate grabber for each
% type---this is also faster. The grabber function can be defined by
-% using an intricate construction of |\exp_after:NN| and other goodies
+% using an intricate construction of |\exp_after:wN| and other goodies
% but I prefer readable code. The end result for the input |xyz| is
% \begin{verbatim}
-% \def:Npn\xref_get_value_xyz_aux:w #1\xref_xyz_key #2#3\q_nil{#2}
+% \cs_set_nopar:Npn\xref_get_value_xyz_aux:w #1\xref_xyz_key #2#3\q_nil{#2}
% \end{verbatim}
% \begin{macrocode}
\toks_set:Nx \l_tmpa_toks {
- \exp_not:n { \def:cpn {xref_get_value_#2_aux:w} ##1 }
+ \exp_not:n { \cs_set_nopar:cpn {xref_get_value_#2_aux:w} ##1 }
+ \exp_not:N \q_prop
\exp_not:c { xref_#2_key }
+ \exp_not:N \q_prop
}
\toks_use:N \l_tmpa_toks ##2 ##3\q_nil {##2}
}
@@ -215,31 +232,36 @@
% Getting the correct value for a given label-type pair is a matter
% of connecting the correct grabber functions and property list.
% \begin{macrocode}
-\def_new:Npn \xref_get_value:nn #1#2 {
- \cs_if_really_free:cTF{g_xref_#2_plist}
- {??}
+\cs_new_nopar:Npn \xref_get_value:nn #1#2 {
+ \cs_if_exist:cTF{g_xref_#2_prop}
{
% \end{macrocode}
% This next expansion may look a little weird but it isn't if you
% think about it!
% \begin{macrocode}
- \exp_args:NcNc \exp_after:NN {xref_get_value_#1_aux:w}
- \prop_use:N {g_xref_#2_plist}
+ \exp_args:NcNc \exp_after:wN {xref_get_value_#1_aux:w}
+ \toks_use:N {g_xref_#2_prop}
% \end{macrocode}
% Better put in the stop marker.
% \begin{macrocode}
\q_nil
}
+ {??}
}
-\def:NNn \exp_after:cc 2 {
- \exp_after:NN \exp_after:NN
- \cs:w #1\exp_after:NN\cs_end: \cs:w #2\cs_end:
+% \end{macrocode}
+% Temporary! We expand the property list and so we can't have the
+% |\q_prop| marker just expand!
+% \begin{macrocode}
+\cs_set_nopar:Npn \exp_after:cc #1#2 {
+ \exp_after:wN \exp_after:wN
+ \cs:w #1\exp_after:wN\cs_end: \cs:w #2\cs_end:
}
+\cs_set_protected:Npn \q_prop {\q_prop}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\xref_define_label:nn}
-% \begin{macro}{\xref_define_label_aux:nn}
+% \begin{macro}[aux]{\xref_define_label_aux:nn}
% Define the property list for each label. We better do this in two
% steps because the special catcode regime is in effect and since
% some of the info fields are very likely to contain actual text,
@@ -248,7 +270,7 @@
% containing catcode instructions which can then be activated with
% |\etex_scantokens:D|.
% \begin{macrocode}
-\def_protected_new:Npn \xref_define_label:nn {
+\cs_new_protected_nopar:Npn \xref_define_label:nn {
\group_begin:
\char_set_catcode:nn {`\ }\c_ten
\xref_define_label_aux:nn
@@ -258,10 +280,10 @@
% we should do something about it. For now we don't do anything
% spectacular.
% \begin{macrocode}
-\def_new:Npn \xref_define_label_aux:nn #1#2 {
- \cs_if_really_free:cTF{g_xref_#1_plist}
- {\prop_new:c{g_xref_#1_plist}}{\WARNING}
- \toks_gset:cn{g_xref_#1_plist}{#2}
+\cs_new_nopar:Npn \xref_define_label_aux:nn #1#2 {
+ \cs_if_free:cTF{g_xref_#1_prop}
+ {\prop_new:c{g_xref_#1_prop}}{\WARNING}
+ \toks_gset:cn{g_xref_#1_prop}{#2}
\group_end:
}
% \end{macrocode}
@@ -276,12 +298,12 @@
% lists being implemented as token list registers we must expand the
% `immediate' fields twice.
% \begin{macrocode}
-\def:Npn \xref_set_label:n #1{
- \def:Npx \tmp:w{\prop_use:N\g_xref_all_curr_immediate_fields_plist}
- \exp_args:NNx\iow_deferred_expanded:Nn \xref_write{
+\cs_set_nopar:Npn \xref_set_label:n #1{
+ \cs_set_nopar:Npx \xref_tmp:w{\toks_use:N\g_xref_all_curr_immediate_fields_prop}
+ \exp_args:NNx\iow_shipout_x:Nn \xref_write{
\xref_define_label:nn {#1} {
- \tmp:w
- \prop_use:N \g_xref_all_curr_deferred_fields_plist
+ \xref_tmp:w
+ \toks_use:N \g_xref_all_curr_deferred_fields_prop
}
}
}
@@ -299,37 +321,41 @@
% That's it (for now).
% \begin{macrocode}
%</initex|package>
+% \end{macrocode}
+%
+% \begin{macrocode}
%<*showmemory>
\showMemUsage
%</showmemory>
% \end{macrocode}
%
+% \section{\pkg{l3xref} test file}
%
% \begin{macrocode}
%<*testfile>
\documentclass{article}
\usepackage{l3xref}
\ExplSyntaxOn
-\def:Npn \startrecording {\iow_open:Nn \xref_write {\jobname.xref}}
-\def:Npn \DefineCrossReferences {
+\cs_set_nopar:Npn \startrecording {\iow_open:Nn \xref_write {\jobname.xref}}
+\cs_set_nopar:Npn \DefineCrossReferences {
\group_begin:
- \NamesStart
+ \ExplSyntaxNamesOn
\InputIfFileExists{\jobname.xref}{}{}
\group_end:
}
\AtBeginDocument{\DefineCrossReferences\startrecording}
\xref_new:nn {name}{}
-\def:Npn \setname{\tlp_set:Nn\l_xref_curr_name_tlp}
-\def:Npn \getname{\xref_get_value:nn{name}}
+\cs_set_nopar:Npn \setname{\tl_set:Nn\l_xref_curr_name_tl}
+\cs_set_nopar:Npn \getname{\xref_get_value:nn{name}}
\xref_deferred_new:nn {page}{\thepage}
-\def:Npn \getpage{\xref_get_value:nn{page}}
+\cs_set_nopar:Npn \getpage{\xref_get_value:nn{page}}
\xref_deferred_new:nn {valuepage}{\number\value{page}}
-\def:Npn \getvaluepage{\xref_get_value:nn{valuepage}}
+\cs_set_nopar:Npn \getvaluepage{\xref_get_value:nn{valuepage}}
-\let:NN \setlabel \xref_set_label:n
+\cs_set_eq:NN \setlabel \xref_set_label:n
\ExplSyntaxOff
\begin{document}
@@ -358,21 +384,7 @@ Now let's extract some values. \getname{testlabel 7} on page
%</testfile>
% \end{macrocode}
%
+% \end{implementation}
+% \PrintIndex
%
% \endinput
-%
-% $Log$
-% Revision 1.4 2006/03/20 18:26:42 braams
-% Updated the copyright notice (2006) and demoted all implementation
-% sections to subsections and so on to clean up the toc for source3.tex
-%
-% Revision 1.3 2006/01/16 11:26:57 morten
-% Minor changes
-%
-% Revision 1.2 2006/01/15 14:07:31 braams
-% Activated \StopEventually{}
-%
-% Revision 1.1 2006/01/15 07:55:06 morten
-% New cross reference module including test file.
-%
-% \ No newline at end of file
diff --git a/Master/texmf-dist/source/latex/expl3/source3.tex b/Master/texmf-dist/source/latex/expl3/source3.tex
index 1199dbf3209..837260437b1 100644
--- a/Master/texmf-dist/source/latex/expl3/source3.tex
+++ b/Master/texmf-dist/source/latex/expl3/source3.tex
@@ -1,5 +1,5 @@
% \iffalse
-%% File: source3.dtx Copyright (C) 1990-2006 LaTeX3 project
+%% File: source3.dtx Copyright (C) 1990-2009 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
@@ -17,7 +17,7 @@
%%
%% The development version of the bundle can be found at
%%
-%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/
+%% http://www.latex-project.org/svnroot/experimental/trunk/
%%
%% for those people who are interested.
%%
@@ -35,184 +35,343 @@
% This document will typeset the LaTeX3 sources as a single document.
% This will produce quite a large file (roughly ??? pages) and may
-% take a long time.
-%
-% Some notes on processing this document are contained at the end
-% of this document, after \end{document}
-%
-% DPC 1997/11/17
-% JLB 2005/03/09 copied from source2e.tex for l3in2e sources
-% First a special index style for makeindex
-%
-
-\begin{filecontents}{source3.ist}
-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"
-\end{filecontents}
-
-\begin{filecontents}{l3doc.cfg}
- \DisableCrossrefs
- \AtEndOfClass{\OnlyDescription}
-\end{filecontents}
-
-\begin{filecontents}{l3full.cfg}
-
-% Set up the Index and Change History to use \part
- \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.}
-
- \GlossaryPrologue{\part*{Change History}%
-% Allow control names to be hyphenated here...
- {\GlossaryParms\ttfamily\hyphenchar\font=`\-}%
- \markboth{Change History}{Change History}%
- \addcontentsline{toc}{part}{Change History}}
-
- \RecordChanges
- \CodelineIndex
- \EnableCrossrefs
- \AlsoImplementation
- \setcounter{IndexColumns}{2}
-\end{filecontents}
-
+% take a long time on a slow machine.
\documentclass{l3doc}
-
\listfiles
-% Do not index some TeX primitives, and some common plain TeX commands.
-
-%% to be filled in later\DoNotIndex{...}
-% The standard \changes command modified slightly to better cope with
-% this multiple file document.
-%\makeatletter
-%\def\changes@#1#2#3{%
-% \let\protect\@unexpandable@protect
-% \edef\@tempa{\noexpand\glossary{#2\space\currentfile\space#1\levelchar
-% \ifx\saved@macroname\@empty
-% \space
-% \actualchar
-% \generalname
-% \else
-% \expandafter\@gobble
-% \saved@macroname
-% \actualchar
-% \string\verb\quotechar*%
-% \verbatimchar\saved@macroname
-% \verbatimchar
-% \fi
-% :\levelchar #3}}%
-% \@tempa\endgroup\@esphack}
-%\makeatother
-
-% Needed for documentation in ltoutenc.dtx
-\usepackage{textcomp}
-
\begin{document}
- \title{The \LaTeX3 Sources}
- \author{\Team}
-
- \pagenumbering{roman}
- \maketitle
- \renewcommand\maketitle{}
-
- \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
-% latex l3boxes.dtx
-% will typeset the source of the LaTeX3 box commands.
-%
-% If this file is processed, each of these separate dtx files will be
-% contained as a part of a single document. Using ltxdoc.cfg you can
-% then optionally produce a combined index and/or change history for
-% the entire source of the format file. Note that such a document will
-% be quite large (about ??? pages).
-%
+\title{The \LaTeX3 Sources}
+\author{\Team}
- \DocInput{l3names.dtx} % System dependant initialisation
- \DocInput{l3basics.dtx} %
+\pagenumbering{roman}
+\maketitle
- \DocInput{l3chk.dtx} % Checking assignments
+\begin{abstract}
- \DocInput{l3tlp.dtx} %
+\parindent=0pt
+\parskip=\baselineskip
- \DocInput{l3expan.dtx} %
+\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.
- \DocInput{l3num.dtx} %
+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.
- \DocInput{l3seq.dtx} %
+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.
- \DocInput{l3alloc.dtx} %
+\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}.
- \DocInput{l3io.dtx} %
+ New modules will be added to the distributed version of \pkg{expl3} as
+ they reach maturity.
+\end{bfseries}
- \DocInput{l3clist.dtx} %
+\end{abstract}
- \DocInput{l3prop.dtx} %
-
- \DocInput{l3int.dtx} %
-
- \DocInput{l3skip.dtx} %
-
- \DocInput{l3toks.dtx} %
-
- \DocInput{l3messages.dtx} %
-
- \DocInput{l3box.dtx} %
-
- \DocInput{l3precom.dtx} %
-
- \DocInput{l3quark.dtx} %
+\clearpage
- \DocInput{l3prg.dtx} %
+{\def\\{:}% fix "newlines" in the ToC
+\tableofcontents}
- \DocInput{l3token.dtx} %
+\clearpage
+\pagenumbering{arabic}
- \DocInput{l3xref.dtx} %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- \DocInput{l3calc.dtx} %
+% 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 ``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} (``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}] `Rigid' lengths.
+ \item[\texttt{int}] Integer-valued count register.
+ \item[\texttt{num}] A `fake' integer type using only macros. Useful for
+ setting up allocation routines.
+ \item[\texttt{prop}] Property list.
+ \item[\texttt{skip}] `Rubber' lengths.
+ \item[\texttt{seq}] `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}
+
+\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 ``user'' name, this might read:
+\begin{function}{
+ \ExplSyntaxOn |
+ \ExplSyntaxOff
+ }
+ \begin{syntax}
+ "\ExplSyntaxOn"
+ \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}
+ "\seq_new:N" <sequence>
+ \end{syntax}
+ When a number of variants are described, the arguments are usually
+ illustrated only for the base function. Here, <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}{
+ \cs_to_str:N / (EXP)
+ }
+ \begin{syntax}
+ "\cs_to_str:N" <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 <cs>,
+ shorthand for a <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 `true'/`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}{
+ \xetex_if_engine: / (TF) (EXP)
+ }
+ \begin{syntax}
+ "\xetex_if_engine:TF" <true code> <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 <true code>
+ and <false code> will be shown. The two variant forms \texttt{T} and
+ \texttt{F} take only <true code> and <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 `\textbf{\TeX{}hackers
+note}' section:
+\begin{function}{
+ \token_to_str:N / (EXP)
+ }
+ \begin{syntax}
+ "\token_to_str:N" <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{l3names.dtx}
+
+\DocInput{l3basics.dtx}
+\DocInput{l3expan.dtx}
+\DocInput{l3prg.dtx}
+\DocInput{l3quark.dtx}
+\DocInput{l3token.dtx}
+
+\DocInput{l3int.dtx}
+\DocInput{l3num.dtx}
+\DocInput{l3intexpr.dtx}
+\DocInput{l3skip.dtx}
+
+\DocInput{l3tl.dtx}
+\DocInput{l3toks.dtx}
+\DocInput{l3seq.dtx}
+\DocInput{l3clist.dtx}
+\DocInput{l3prop.dtx}
+
+\DocInput{l3io.dtx}
+\DocInput{l3msg.dtx}
+\DocInput{l3box.dtx}
+\DocInput{l3xref.dtx}
+\DocInput{l3keyval.dtx}
+\DocInput{l3calc.dtx}
+\DocInput{l3file.dtx}
+
+% \DocInput{l3precom.dtx}
+% \DocInput{l3alloc.dtx}
+% \DocInput{l3chk.dtx}
+
+\part{Implementation}
+\def\maketitle{}
+\EnableImplementation
+\DisableDocumentation
+\DocInputAgain
%% \DocInput{l3vers.dtx} % Current version date
- \includeltpatch % Corrections distributed after the full release
-
-% Stop here if ltxdoc.cfg says \AtEndOfClass{\OnlyDescription}
-\StopEventually{\PrintIndex\end{document}}
+\includeltpatch % Corrections distributed after the full release
\clearpage
\pagestyle{headings}
@@ -222,178 +381,18 @@ page_precedence "rnaA"
\newcount\hbadness
\hfuzz=\maxdimen
-\typeout{%
- \string # Produce change log with^^J%
- makeindex -s gglo.ist -o source3.gls source3.glo}
-
-
\PrintChanges
-
\clearpage
-% makeindex needs a symbol between the parts of composite page numbers
-% but we dont want one, so:
-\typeout{%
- \string # Produce index with^^J%
- makeindex -s source3.ist source3.idx}
-
\begingroup
\def\endash{--}
\catcode`\-\active
\def-{\futurelet\temp\indexdash}
\def\indexdash{\ifx\temp-\endash\fi}
-\PrintIndex
+\DelayPrintIndex
\endgroup
-% Make sure that the index is not printed twice
-% (ltxdoc.cfg might have a second \PrintIndex command)
-\let\PrintChanges\relax
-\let\PrintIndex\relax
-
\end{document}
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-To use this file to produce a fully indexed source code
-you need to execute the following (or equivalent) commands:
-
- latex source3.tex
-
- makeindex -s source3.ist source3.idx
- makeindex -s gglo.ist -o source3.gls source3.glo
-
- latex source3.tex
- latex source3.tex
-
-
-The makeindex style source3.ist is used in place of the usual
-doc 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.
-
-The third run with latex is only required to get the table of
-contents entries for the change log and index. You may speed things up
-by using the \includeonly mechanism so as not to typeset the source
-files on the second run. This involves changing the file
-ltxdoc.cfg
-between the latex runs.
-
-The following unix script automates this.
- (It could easily be ported to scripts for DOS or VMS,
- rm is ReMove a file, and echo "..." > file writes ... to "file".)
-
-
-After this script (after the second ==============) is a similar script
-that will produce the documentation for all the files in the base
-distribution that are *not* included in source3.dvi. This second script
-was requested, but before using it, beware it will take a long time!
-It may however be modified as required, eg to not typeset the fdd files
-or whatever...
-
-==============
-#!/bin/sh
-
-rm -f source3.gls source3.ind source3.toc
-
-# First run:
-# Create new standard ltxdoc.cfg file
-# Pass the (possibly empty) list of arguments supplied on the
-# command line to article class.
-#
-# If you use A4 paper, running this script with argument
-# a4paper
-# may save about 30 pages.
-#
-echo "\PassOptionsToClass{$*}{article}" > ltxdoc.cfg
-
-
-# Now LaTeX the file with this cfg file.
-#
-latex source3.tex
-
-
-# Make the Change log and Glossary.
-#
-makeindex -s source3.ist source3.idx
-makeindex -s gglo.ist -o source3.gls source3.glo
-
-
-# Second run: append \includeonly{} to ltxdoc.cfg to speed up things
-# (this run needed only to get changes and index listed in .toc file)
-#
-# Note that the index will not be made incorrect by the insertion
-# of the table of contents as the front matter uses a diferent page
-# numbering scheme.
-#
-echo "\includeonly{}" >> ltxdoc.cfg
-
-latex source3.tex
-
-
-# Third and final run, to put everything together.
-# First restore the cfg file:
-#
-echo "\PassOptionsToClass{$*}{article}" > ltxdoc.cfg
-latex source3.tex
-
-
-==============
-#!/bin/sh
-
-# Running this script will process all the dtx fdd and *guide.tex
-# and ltnews*.tex files in the LaTeX distribution, except the dtx
-# files included in source3.tex.
-# (The shell first script in the comments of source3.tex will
-# process those.)
-
-# Any command line arguments (eg a4paper) are taken as options to the
-# article class.
-
-# This script is likely to take ages!
-
-echo "\PassOptionsToClass{$*}{article}" > ltxdoc.cfg
-echo "\batchmode" >> ltxdoc.cfg
-
-# The next four lines produce full indexes and change logs
-# you may not want those.
-echo "\AtBeginDocument{\RecordChanges}" >> ltxdoc.cfg
-echo "\AtEndDocument{\PrintChanges}" >> ltxdoc.cfg
-echo "\AtBeginDocument{\CodelineIndex\EnableCrossrefs}" >> ltxdoc.cfg
-echo "\AtEndDocument{\PrintIndex}" >> ltxdoc.cfg
-
-# If you do not want any code listings, just documentation, then instead
-# of the above four lines, uncomment the following:
-# echo "\AtBeginDocument{\OnlyDescription}" >> ltxdoc.cfg
-
-echo "\PassOptionsToClass{$*}{article}" > ltxguide.cfg
-echo "\batchmode" >> ltxguide.cfg
-
-cp ltxguide.cfg ltnews.cfg
-
-
-for i in *dtx *fdd *guide.tex ltnews*.tex
-do
-B=`basename $i .dtx`
-
-if (grep "Include{$B}" source3.tex >/dev/null ; )
-then
-echo In source3: $i
-else
-echo latex $i
- if (latex $i > /dev/null)
- then
- echo latex $i
- latex $i > /dev/null
- echo makeindex -s gind.ist $B.idx
- makeindex -s gind.ist $B.idx > /dev/null 2> /dev/null
- echo makeindex -s gglo.ist -o $B.gls $B.glo
- makeindex -s gglo.ist -o $B.gls $B.glo > /dev/null 2> /dev/null
- echo latex $i
- latex $i > /dev/null
- else
- echo "!!! LaTeX ERROR: $i. (See $B.log.)"
- fi
-fi
-
-done
diff --git a/Master/texmf-dist/source/latex/expl3/test1.tex b/Master/texmf-dist/source/latex/expl3/test1.tex
deleted file mode 100644
index d40189e37dc..00000000000
--- a/Master/texmf-dist/source/latex/expl3/test1.tex
+++ /dev/null
@@ -1,89 +0,0 @@
-% \iffalse
-%% File: test1 Copyright (C) 1990-2006 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/cgi-bin/cvsweb.cgi/
-%%
-%% 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 LaTeX Project Team.
-%%
-%% -----------------------------------------------------------------------
-%%
-\def\next$Id: #1.tex #2 #3-#4-#5 #6 #7$#8{%
- \def\fileversion{#2}%
- \def\filedate{#3/#4/#5}%
- \ProvidesFile{#1.tex}[#3/#4/#5 v#2 #8]%
-}
-\next$Id: test1.tex 573 2006-08-21 20:59:37Z morten $
- {L3 Test 1}
-% \fi
-
-\documentclass{article}
-
-\tracingmacros2
-\usepackage{l3expan,l3io}
-
-\begin{document}
-
-\CodeStart
-
-
-\def_new:Npn\test_cmd:nn#1#2{
- \iow_unexpanded_term:n{}
- \iow_unexpanded_term:n{Argument~1:~#1}
- \iow_unexpanded_term:n{Argument~2:~#2}}
-
-
-
-\def:Npn\a{A}
-\def:Npn\b{B}
-
-\def:Npn\aa{\a}
-\def:Npn\bb{\b}
-
-\exp_def_form:nnn {test_cmd}{nn}{oo}
-\exp_def_form:nnn {test_cmd}{nn}{xx}
-\exp_def_form:nnn {test_cmd}{nn}{cc}
-\exp_def_form:nnn {test_cmd}{nn}{nx}
-
-\test_cmd:nn{a}{b}
-
-\test_cmd:nn{\a}{\b}
-
-\test_cmd:oo\aa\bb
-
-\test_cmd:xx\aa\bb
-
-\test_cmd:cc{a}{b}
-
-\test_cmd:nx{a}{\b}
-
-\CodeStop
-
-\LaTeX\ still works!
-
-\end{document}
-
diff --git a/Master/texmf-dist/source/latex/expl3/test2.tex b/Master/texmf-dist/source/latex/expl3/test2.tex
deleted file mode 100644
index 764ad74fc39..00000000000
--- a/Master/texmf-dist/source/latex/expl3/test2.tex
+++ /dev/null
@@ -1,73 +0,0 @@
-% \iffalse
-%% File: test2 Copyright (C) 1990-2006 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/cgi-bin/cvsweb.cgi/
-%%
-%% 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 LaTeX Project Team.
-%%
-%% -----------------------------------------------------------------------
-%%
-\def\next$Id: #1.tex #2 #3-#4-#5 #6 #7$#8{%
- \def\fileversion{#2}%
- \def\filedate{#3/#4/#5}%
- \ProvidesFile{#1.tex}[#3/#4/#5 v#2 #8]%
-}
-\next$Id: test2.tex 573 2006-08-21 20:59:37Z morten $
- {L3 Test 2}
-% \fi
-
-
-\RequirePackage[removeoldnames]{l3names}
-\RequirePackage{l3expan}
-
-\CodeStart
-
-
-\def_new:Npn\foo:nn#1#2{\def:Npn\xxx{(#1)(#2)}\tex_show:D\xxx}
-
-\def:Npn\a{A}\def:Npn\b{B}
-\def:Npn\aa{\a}\def:Npn\bb{\b}
-
-\def:Npn\foo:oo{\exp_args:Noo\foo:nn}
-\def:Npn\foo:xx{\exp_args:Nxx\foo:nn}
-\def:Npn\foo:cc{\exp_args:Ncc\foo:nn}
-\def:Npn\foo:nx{\exp_args:Nnx\foo:nn}
-
-\foo:nn{a}{b}
-
-\foo:nn{\a}{\b}
-
-\foo:oo\aa\bb
-
-\foo:xx\aa\bb
-
-\foo:cc{a}{b}
-
-\foo:nx{a}{\b}
-
-\tex_end:D
diff --git a/Master/texmf-dist/source/latex/expl3/test3.tex b/Master/texmf-dist/source/latex/expl3/test3.tex
deleted file mode 100644
index 3dd5f714d35..00000000000
--- a/Master/texmf-dist/source/latex/expl3/test3.tex
+++ /dev/null
@@ -1,135 +0,0 @@
-% \iffalse
-%% File: test2 Copyright (C) 1990-2006 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/cgi-bin/cvsweb.cgi/
-%%
-%% 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 LaTeX Project Team.
-%%
-%% -----------------------------------------------------------------------
-%%
-% \fi
-\documentclass{article}
-
-\usepackage{l3precom}
-
-% let's dump what is known about the LaTeX internals so far.
-% this will not be much as the very basic stuff doesn't get
-% dumped and we haven't got anything else.
-%
-\dumpLaTeXstate{test1}
-
-\CodeStart
-
-% we need some variants of tlp_set which are not yet
-% defined for use in the code below.
-%
-\exp_def_form:nnn{tlp_set}{Nn}{on}
-\exp_def_form:nnn{tlp_gset}{Nn}{on}
-
-% okay, here we either load a dump file (testdump.cmp)
-% and then jump tp \cs_dump: or we compile one for next time.
-% don't forget that if you change code below it will only have any
-% affect if a new dump file is written so you may have to remove
-% the existing one.
-%
-\cs_load_dump:n{testdump}
-
-% two test definitions
-%
-\def_new:Npn\foo{some foo}
-\def_new:Npn\baz{some baz}
-
-% we say that \foo should be dumped in the compiled style.
-% this is pretty useless as it is certainly not faster than defining
-% it in the first place. but this is only done for showing that it
-% works. just assume that \foo is actually a pretty difficult
-% definition which does need a lot of static compilation due to
-% parsing, comparing values, etc., so that it is much faster load the
-% final version rather than do the compilation each time again.
-%
-% btw note that \baz is not dumped and will not be available in the
-% production run (ie the one using the cmp file)
-%
-\cs_record_name:N\foo
-
-% get our self a scratch register (again this will not be available in
-% the production run)
-%
-\tlp_new:Nn\l_scratch_tlp{}
-
-% now we generate a unique cs name and assign it the string "foo".
-% again pretty useless example. but with this mechansim you can build
-% complex graph structures etc using these names as pointers, etc. and
-% in such a case you need to dump the state of your graph at some
-% point to be able to load it very fast in production.
-%
-\cs_gen_sym:N\l_scratch_tlp{}
-\tlp_set:on \l_scratch_tlp {foo}
-
-% ditto for a global unique name
-%
-\cs_ggen_sym:N\l_scratch_tlp{}
-\tlp_gset:on \l_scratch_tlp {bar}
-
-% and now we dump the whole rubbish. In the current implementation
-% only csnames can be precompiled, perhaps registers should be handled
-% similarly.
-%
-\cs_dump:
-
-% and some int register to show something in the second LaTeX state
-% dump.
-%
-\int_new:N\l_my_int
-\int_set:Nn\l_my_int{42}
-%
-% as the allocation routines are not distributed we have to do this
-% manually.
-%
-\register_record_name:N\l_my_int
-
-\dumpLaTeXstate{test2}
-
-% and changing something ... what happens with the LaTeX state?
-%
-\int_set:Nn\l_my_int{0}
-\def:Npn\file_not_found:nTF#1#2#3{}
-
-\dumpLaTeXstate{test3}
-
-\CodeStop
-
-\begin{document}
-
-\LaTeX\ still works!
-
-\end{document}
-
-
-
-