summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/l3packages/xparse
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2011-07-31 18:27:40 +0000
committerKarl Berry <karl@freefriends.org>2011-07-31 18:27:40 +0000
commit1b26357f303f48ae0b233a5fee9c2e5b8c3d8647 (patch)
tree7fc300fb4b7a180433559b69e8f2362d1cfe5ac7 /Master/texmf-dist/source/latex/l3packages/xparse
parentdac945b204407dae96f70ec228206516093156d7 (diff)
l3packages (5jun11)
git-svn-id: svn://tug.org/texlive/trunk@23283 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex/l3packages/xparse')
-rw-r--r--Master/texmf-dist/source/latex/l3packages/xparse/xparse.dtx2650
-rw-r--r--Master/texmf-dist/source/latex/l3packages/xparse/xparse.ins40
2 files changed, 2690 insertions, 0 deletions
diff --git a/Master/texmf-dist/source/latex/l3packages/xparse/xparse.dtx b/Master/texmf-dist/source/latex/l3packages/xparse/xparse.dtx
new file mode 100644
index 00000000000..79a996d4fc8
--- /dev/null
+++ b/Master/texmf-dist/source/latex/l3packages/xparse/xparse.dtx
@@ -0,0 +1,2650 @@
+% \iffalse meta-comment
+%
+%% File: xparse.dtx (C) Copyright 1999 Frank Mittelbach, Chris Rowley,
+%% David Carlisle
+%% (C) Copyright 2004-2008 Frank Mittelbach,
+%% The LaTeX3 Project
+%% (C) Copyright 2009-2011 The LaTeX3 Project
+%%
+%% It may be distributed and/or modified under the conditions of the
+%% LaTeX Project Public License (LPPL), either version 1.3c of this
+%% license or (at your option) any later version. The latest version
+%% of this license is in the file
+%%
+%% http://www.latex-project.org/lppl.txt
+%%
+%% This file is part of the "l3packages 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{expl3}
+\GetIdInfo$Id: xparse.dtx 2492 2011-07-02 13:40:38Z joseph $
+ {L3 Experimental document command parser}
+%</driver|package>
+%<*driver>
+\documentclass[full]{l3doc}
+\usepackage{amstext}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \providecommand\acro[1]{\textsc{\MakeLowercase{#1}}}
+% \newenvironment{arg-description}{%
+% \begin{itemize}\def\makelabel##1{\hss\llap{\bfseries##1}}}{\end{itemize}}
+%
+% \title{^^A
+% The \textsf{xparse} package\\ Document command parser^^A
+% \thanks{This file describes v\ExplFileVersion,
+% last revised \ExplFileDate.}^^A
+% }
+%
+% \author{^^A
+% The \LaTeX3 Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released \ExplFileDate}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% The \pkg{xparse} package provides a high-level interface for
+% producing document-level commands. In that way, it is intended as
+% a replacement for the \LaTeXe{} \cs{newcommand} macro. However,
+% \pkg{xparse} works so that the interface to a function (optional
+% arguments, stars and mandatory arguments, for example) is separate
+% from the internal implementation. \pkg{xparse} provides a normalised
+% input for the internal form of a function, independent of the
+% document-level argument arrangement.
+%
+% At present, the functions in \pkg{xparse} which are regarded as
+% \enquote{stable} are:
+% \begin{itemize}
+% \item \cs{DeclareDocumentCommand}
+% \item \cs{NewDocumentCommand}
+% \item \cs{RenewDocumentCommand}
+% \item \cs{ProvideDocumentCommand}
+% \item \cs{DeclareDocumentEnvironment}
+% \item \cs{NewDocumentEnvironment}
+% \item \cs{RenewDocumentEnvironment}
+% \item \cs{ProvideDocumentEnvironment}
+% \item \cs{IfNoValue(TF)} (the need for \cs{IfValue(TF)} is currently
+% an item of active discussion)
+% \item \cs{IfBoolean(TF)}
+% \end{itemize}
+% with the other functions currently regarded as \enquote{experimental}. Please
+% try all of the commands provided here, but be aware that the
+% experimental ones may change or disappear.
+%
+% \subsection{Specifying arguments}
+%
+% Before introducing the functions used to create document commands,
+% the method for specifying arguments with \pkg{xparse} will be
+% illustrated. In order to allow each argument to be defined
+% independently, \pkg{xparse} does not simply need to know the
+% number of arguments for a function, but also the nature of each
+% one. This is done by constructing an \emph{argument specification},
+% which defines the number of arguments, the type of each argument
+% and any additional information needed for \pkg{xparse} to read the
+% user input and properly pass it through to internal functions.
+%
+% The basic form of the argument specifier is a list of letters, where
+% each letter defines a type of argument. As will be described below,
+% some of the types need additional information, such as default values.
+% The argument types can be divided into two, those which define
+% arguments that are mandatory (potentially raising an error if not
+% found) and those which define optional arguments. The mandatory types
+% are:
+% \begin{itemize}[font=\ttfamily]
+% \item[m] A standard mandatory argument, which can either be a single
+% token alone or multiple tokens surrounded by curly braces.
+% Regardless of the input, the argument will be passed to the
+% internal code surrounded by a brace pair. This is the \pkg{xparse}
+% type specifier for a normal \TeX\ argument.
+% \item[l] An argument which reads everything up to the first
+% open group token: in standard \LaTeX\ this is a left brace.
+% \item[u] Reads an argument `until' \meta{tokens} are encountered,
+% where the desired \meta{tokens} are given as an argument to the
+% specifier: \texttt{u}\marg{tokens}.
+% \end{itemize}
+% The types which define optional arguments are:
+% \begin{itemize}[font=\ttfamily]
+% \item[o] A standard \LaTeX\ optional argument, surrounded with square
+% brackets, which will supply
+% the special \cs{NoValue} token if not given (as described later).
+% \item[d] An optional argument which is delimited by \meta{token1}
+% and \meta{token2}, which are given as arguments:
+% \texttt{d}\meta{token1}\meta{token2}. As with \texttt{o}, if no
+% value is given the special token \cs{NoValue} is returned.
+% \item[O] As for \texttt{o}, but returns \meta{default} if no
+% value is given. Should be given as \texttt{O}\marg{default}.
+% \item[D] As for \texttt{d}, but returns \meta{default} if no
+% value is given: \texttt{D}\meta{token1}\meta{token2}\marg{default}.
+% Internally, the \texttt{o}, \texttt{d} and \texttt{O} types are
+% short-cuts to an appropriated-constructed \texttt{D} type argument.
+% \item[s] An optional star, which will result in a value
+% \cs{BooleanTrue} if a star is present and \cs{BooleanFalse}
+% otherwise (as described later).
+% \item[t] An optional \meta{token}, which will result in a value
+% \cs{BooleanTrue} if \meta{token} is present and \cs{BooleanFalse}
+% otherwise. Given as \texttt{t}\meta{token}.
+% \item[g] An optional argument given inside a pair of \TeX\ group
+% tokens (in standard \LaTeX, |{| \ldots |}|), which returns
+% \cs{NoValue} if not present.
+% \item[G] As for \texttt{g} but returns \meta{default} if no value
+% is given: \texttt{G}\marg{default}.
+% \end{itemize}
+%
+% Using these specifiers, it is possible to create complex input syntax
+% very easily. For example, given the argument definition
+% `|s o o m O{default}|', the input `|*[Foo]{Bar}|' would be parsed as:
+% \begin{itemize}[nolistsep]
+% \item |#1| = |\BooleanTrue|
+% \item |#2| = |{Foo}|
+% \item |#3| = |\NoValue|
+% \item |#4| = |{Bar}|
+% \item |#5| = |{default}|
+% \end{itemize}
+% whereas `|[One][Two]{}[Three]|' would be parsed as:
+% \begin{itemize}[nolistsep]
+% \item |#1| = |\BooleanFalse|
+% \item |#2| = |{One}|
+% \item |#3| = |{Two}|
+% \item |#4| = |{}|
+% \item |#5| = |{Three}|
+% \end{itemize}
+% Note that after parsing the input there will be always exactly the
+% same number of \meta{balanced text} arguments as the number of letters
+% in the argument specifier. The \cs{BooleanTrue} and \cs{BooleanFalse}
+% tokens are passed without braces; all other arguments are passed as
+% brace groups.
+%
+% Two more tokens have a special meaning when creating an argument
+% specifier. First, \texttt{+} is used to make an argument long (to
+% accept paragraph tokens). In contrast to \LaTeXe's \cs{newcommand},
+% this applies on an argument-by-argument basis. So modifying the
+% example to `|s o o +m O{default}|' means that the mandatory argument
+% is now \cs{long}, whereas the optional arguments are not.
+%
+% Secondly, the token \texttt{>} is used to declare so-called
+% \enquote{argument processors}, which can be used to modify the contents of an
+% argument before it is passed to the macro definition. The use of
+% argument processors is a somewhat advanced topic, (or at least a less
+% commonly used feature) and is covered in Section~\ref{sec:processors}.
+%
+% \subsection{Spacing and optional arguments}
+%
+% \TeX{} will find the first argument after a function name irrespective
+% of any intervening spaces. This is true for both mandatory and
+% optional arguments. So |\foo[arg]| and \verb*|\foo [arg]| are
+% equivalent. Spaces are also ignored when collecting arguments up
+% to the last mandatory argument to be collected (as it must exist).
+% So after
+% \begin{verbatim}
+% \DeclareDocumentCommand \foo { m o m } { ... }
+% \end{verbatim}
+% the user input |\foo{arg1}[arg2]{arg3}| and
+% \verb*|\foo{arg1} [arg2] {arg3}| will both be parsed in the same
+% way. However, spaces are \emph{not} ignored when parsing optional
+% arguments after the last mandatory argument. Thus with
+% \begin{verbatim}
+% \DeclareDocumentCommand \foo { m o } { ... }
+% \end{verbatim}
+% |\foo{arg1}[arg2]| will find an optional argument but
+% \verb*|\foo{arg1} [arg2]| will not. This is so that trailing optional
+% arguments are not picked up \enquote{by accident} in input.
+%
+% \subsection{Declaring commands and environments}
+%
+% With the concept of an argument specifier defined, it is now
+% possible to describe the methods available for creating both
+% functions and environments using \pkg{xparse}.
+%
+% The interface-building commands are the preferred method for
+% creating document-level functions in \LaTeX3. All of the functions
+% generated in this way are naturally robust (using the \eTeX{}
+% \cs{protected} mechanism).
+%
+% \begin{function}
+% {
+% \DeclareDocumentCommand ,
+% \NewDocumentCommand ,
+% \RenewDocumentCommand ,
+% \ProvideDocumentCommand
+% }
+% \begin{syntax}
+% \cs{DeclareDocumentCommand} \meta{Function} \Arg{arg spec} \Arg{code}
+% \end{syntax}
+% This family of commands are used to create a document-level
+% \meta{function}. The argument specification for the function is
+% given by \meta{arg spec}, and expanding
+% to be replaced by the \meta{code}.
+%
+% As an example:
+% \begin{verbatim}
+% \DeclareDocumentCommand \chapter { s o m }
+% {
+% \IfBooleanTF {#1}
+% { \typesetnormalchapter {#2} {#3} }
+% { \typesetstarchapter {#3} }
+% }
+% \end{verbatim}
+% would be a way to define a \cs{chapter} command which would
+% essentially behave like the current \LaTeXe{} command (except that it
+% would accept an optional argument even when a \texttt{*} was parsed).
+% The \cs{typesetnormalchapter} could test its first argument for being
+% \cs{NoValue} to see if an optional argument was present.
+%
+% The difference between the \cs{Declare\ldots}, \cs{New\ldots}
+% \cs{Renew\ldots} and \cs{Provide\ldots} versions is the behaviour
+% if \meta{function} is already defined.
+% \begin{itemize}
+% \item \cs{DeclareDocumentCommand} will always create the new
+% definition, irrespective of any existing \meta{function} with the
+% same name.
+% \item \cs{NewDocumentCommand} will issue an error if \meta{function}
+% has already been defined.
+% \item \cs{RenewDocumentCommand} will issue an error if \meta{function}
+% has not previously been defined.
+% \item \cs{ProvideDocumentCommand} creates a new definition for
+% \meta{function} only if one has not already been given.
+% \end{itemize}
+%
+% \begin{texnote}
+% Unlike \LaTeXe{}'s \cs{newcommand} and relatives, the
+% \cs{DeclareDocumentCommand} function do not prevent creation of
+% functions with names starting \cs{end\ldots}.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}
+% {
+% \DeclareDocumentEnvironment ,
+% \NewDocumentEnvironment ,
+% \RenewDocumentEnvironment ,
+% \ProvideDocumentEnvironment
+% }
+% \begin{syntax}
+% \cs{DeclareDocumentEnvironment} \Arg{environment} \Arg{arg spec}
+% ~~\Arg{start code} \Arg{end code}
+% \end{syntax}
+% These commands work in the same way as \cs{DeclareDocumentCommand},
+% etc., but create environments (\cs{begin}|{|\meta{function}|}| \ldots
+% \cs{end}|{|\meta{function}|}|). Both the \meta{start code} and
+% \meta{end code}
+% may access the arguments as defined by \meta{arg spec}.
+% \end{function}
+%
+% \subsection{Testing special values}
+%
+% Optional arguments created using \pkg{xparse} make use of dedicated
+% variables to return information about the nature of the argument
+% received.
+%
+% \begin{variable}{\NoValue}
+% \cs{NoValue} is a special marker returned by \pkg{xparse} if no
+% value is given for an optional argument. If typeset (which should
+% not happen), it will print the value \texttt{-NoValue-}.
+% \end{variable}
+%
+% \begin{function}[EXP,TF]{\IfNoValue}
+% \begin{syntax}
+% \cs{IfNoValueTF} \Arg{argument} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% The \cs{IfNoValue} tests are used to check if <argument> (|#1|,
+% |#2|, \emph{etc.}) is the special \cs{NoValue} token. For example
+% \begin{verbatim}
+% \DeclareDocumentCommand \foo { o m }
+% {
+% \IfNoValueTF {#1}
+% { \DoSomethingJustWithMandatoryArgument {#2} }
+% { \DoSomethingWithBothArguments {#1} {#2} }
+% }
+% \end{verbatim}
+% will use a different internal function if the optional argument
+% is given than if it is not present.
+%
+% As the \cs{IfNoValue(TF)} tests are expandable, it is possible to
+% test these values later, for example at the point of typesetting or
+% in an expansion context.
+% \end{function}
+%
+% \begin{function}[EXP,TF]{\IfValue}
+% \begin{syntax}
+% \cs{IfValueTF} \Arg{argument} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% The reverse form of the \cs{IfNoValue(TF)} tests are also available
+% as \cs{IfValue(TF)}. The context will determine which logical
+% form makes the most sense for a given code scenario.
+% \end{function}
+%
+% \begin{variable}{\BooleanFalse, \BooleanTrue}
+% The \texttt{true} and \texttt{false} flags set when searching for
+% an optional token (using \texttt{s} or \texttt{t\meta{token}}) have
+% names which are accessible outside of code blocks.
+% \end{variable}
+%
+% \begin{function}[EXP,TF]{\IfBoolean}
+% \begin{syntax}
+% \cs{IfBooleanTF} \meta{argument} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Used to test if \meta{argument} (|#1|, |#2|, \emph{etc.}) is
+% \cs{BooleanTrue} or \cs{BooleanFalse}. For example
+% \begin{verbatim}
+% \DeclareDocumentCommand \foo { s m }
+% {
+% \IfBooleanTF #1
+% { \DoSomethingWithStar {#2} }
+% { \DoSomethingWithoutStar {#2} }
+% }
+% \end{verbatim}
+% checks for a star as the first argument, then chooses the action to
+% take based on this information.
+% \end{function}
+%
+% \subsection{Argument processors}
+% \label{sec:processors}
+%
+% \pkg{xparse} introduces the idea of an argument processor, which is
+% applied to an argument \emph{after} it has been grabbed by the
+% underlying system but before it is passed to \meta{code}. An argument
+% processor can therefore be used to regularise input at an early stage,
+% allowing the internal functions to be completely independent of input
+% form. Processors are applied to user input and to default values for
+% optional arguments, but \emph{not} to the special \cs{NoValue} marker.
+%
+% Each argument processor is specified by the syntax
+% \texttt{>}\marg{processor} in the argument specification. Processors
+% are applied from right to left, so that
+% \begin{verbatim}
+% >{\ProcessorB} >{\ProcessorA} m
+% \end{verbatim}
+% would apply \cs{ProcessorA}
+% followed by \cs{ProcessorB} to the tokens grabbed by the \texttt{m}
+% argument.
+%
+% \begin{variable}{\ProcessedArgument}
+% \pkg{xparse} defines a very small set of processor functions. In the
+% main, it is anticipated that code writers will want to create their
+% own processors. These need to accept one argument, which is the
+% tokens as grabbed (or as returned by a previous processor function).
+% Processor functions should return the processed argument as the
+% variable \cs{ProcessedArgument}.
+% \end{variable}
+%
+% \begin{function}{\ReverseBoolean}
+% \begin{syntax}
+% \cs{ReverseBoolean}
+% \end{syntax}
+% This processor reverses the logic of \cs{BooleanTrue} and
+% \cs{BooleanFalse}, so that the the example from earlier would become
+% \begin{verbatim}
+% \DeclareDocumentCommand \foo { > { \ReverseBoolean } s m }
+% {
+% \IfBooleanTF #1
+% { \DoSomethingWithoutStar {#2} }
+% { \DoSomethingWithStar {#2} }
+% }
+% \end{verbatim}
+% \end{function}
+%
+% \begin{function}{\SplitArgument}
+% \begin{syntax}
+% \cs{SplitArgument} \Arg{number} \Arg{token}
+% \end{syntax}
+% This processor splits the argument given at each occurrence of the
+% \meta{token} up to a maximum of \meta{number} tokens (thus
+% dividing the input into $\text{\meta{number}} + 1$ parts).
+% An error is given if too many \meta{tokens} are present in the
+% input. The processed input is places inside
+% $\text{\meta{number}} + 1$ sets of braces for further use.
+% If there are less than \Arg{number} of \Arg{tokens} in the argument
+% then empty brace groups are added at the end of the processed
+% argument.
+% \begin{verbatim}
+% \DeclareDocumentCommand \foo
+% { > { \SplitArgument { 2 } { ; } } m }
+% { \InternalFunctionOfThreeArguments #1 }
+% \end{verbatim}
+% Any category code $13$ (active) \meta{tokens} will be replaced
+% before the split takes place.
+% \end{function}
+%
+% \begin{function}{\SplitList}
+% \begin{syntax}
+% \cs{SplitList} \Arg{token}
+% \end{syntax}
+% This processor splits the argument given at each occurrence of the
+% \meta{token} where the number of items is not fixed. Each item is
+% then wrapped in braces within |#1|. The result is that the
+% processed argument can be further processed using a mapping function.
+% \begin{verbatim}
+% \DeclareDocumentCommand \foo
+% { > { \SplitList { ; } } m }
+% { \MappingFunction #1 }
+% \end{verbatim}
+% Any category code $13$ (active) \meta{tokens} will be replaced
+% before the split takes place.
+% \end{function}
+%
+% \subsection{Separating interface and implementation}
+%
+% One \emph{experimental} idea implemented in \pkg{xparse} is to
+% separate out document command interfaces (the argument specification)
+% from the implementation (code). This is carried out using a
+% pair of functions, \cs{DeclareDocumentCommandInterface} and
+% \cs{DeclareDocumentCommandImplementation}
+%
+% \begin{function}{\DeclareDocumentCommandInterface}
+% \begin{syntax}
+% \cs{DeclareDocumentCommandInterface} \meta{function}
+% ~~~~\Arg{implementation} \Arg{arg spec}
+% \end{syntax}
+% This declares a \meta{function}, which will take arguments as detailed
+% in the \meta{arg spec}. When executed, the \meta{function} will look for
+% code stored as an \meta{implementation}.
+% \end{function}
+%
+% \begin{function}{\DeclareDocumentCommandImplementation}
+% \begin{syntax}
+% \cs{DeclareDocumentCommandImplementation}
+% ~~~~\Arg{implementation} \meta{args} \Arg{code}
+% \end{syntax}
+% Declares the \meta{implementation} for a function to accept \meta{args}
+% arguments and expand to \meta{code}. An implementation must take the
+% same number of arguments as a linked interface, although this is not
+% enforced by the code.
+% \end{function}
+%
+% \subsection{Fully-expandable document commands}
+%
+% There are \emph{very rare} occasion when it may be useful to create
+% functions using a fully-expandable argument grabber. To support this,
+% \pkg{xparse} can create expandable functions as well as the usual
+% robust ones. This imposes a number of restrictions on the nature of
+% the arguments accepted by a function, and the code it implements.
+% This facility should only be used when \emph{absolutely necessary};
+% if you do not understand when this might be, \emph{do not use these
+% functions}!
+%
+% \begin{function}{\DeclareExpandableDocumentCommand}
+% \begin{syntax}
+% \cs{DeclareExpandableDocumentCommand}
+% ~~~~\meta{function} \Arg{arg spec} \Arg{code}
+% \end{syntax}
+% This command is used to create a document-level \meta{function},
+% which will grab its arguments in a fully-expandable manner. The
+% argument specification for the function is given by \meta{arg spec},
+% and the function will execute \meta{code}. In general, \meta{code} will
+% also be fully expandable, although it is possible that this will
+% not be the case (for example, a function for use in a table might
+% expand so that \cs{omit} is the first non-expandable token).
+%
+% Parsing arguments expandably imposes a number of restrictions on
+% both the type of arguments that can be read and the error checking
+% available:
+% \begin{itemize}
+% \item The last argument (if any are present) must be one of the
+% mandatory types: \texttt{l}, \texttt{m} or \texttt{u}.
+% \item All arguments are either short or long: it is not possible
+% to mix short and long argument types.
+% \item The `optional group' argument types \texttt{g} and
+% \texttt{G} are not available.
+% \item It is not possible to differentiate between, for example
+% |\foo[| and |\foo{[}|: in both cases the \texttt{[} will be
+% interpreted as the start of an optional argument. As a result
+% result, checking for optional arguments is less robust than
+% in the standard version.
+% \end{itemize}
+% \pkg{xparse} will issue an error if an argument specifier is given
+% which does not conform to the first three requirements. The last
+% item is an issue when the function is used, and so is beyond the
+% scope of \pkg{xparse} itself.
+% \end{function}
+%
+% \subsection{Access to the argument specification}
+%
+% The argument specifications for document commands and environments are
+% available for examination and use.
+%
+% \begin{function}{\GetDocumentCommandArgSpec, \GetDocumentEnvironmentArgSpec}
+% \begin{syntax}
+% \cs{GetDocumentCommandArgSpec} \meta{function}
+% \cs{GetDocumentEnvironmentArgSpec} \meta{environment}
+% \end{syntax}
+% These functions transfer the current argument specification for the
+% requested \meta{function} or \meta{environment} into the token list
+% variable \cs{ArgumentSpecification}. If the \meta{function} or
+% \meta{environment} has no known argument specification then an error
+% is issued. The assignment to \cs{ArgumentSpecification} is local to
+% the current \TeX{} group.
+% \end{function}
+%
+% \begin{function}
+% {\ShowDocumentCommandArgSpec, \ShowDocumentEnvironmentArgSpec}
+% \begin{syntax}
+% \cs{ShowDocumentCommandArgSpec} \meta{function}
+% \cs{ShowDocumentEnvironmentArgSpec} \meta{environment}
+% \end{syntax}
+% These functions show the current argument specification for the
+% requested \meta{function} or \meta{environment} at the terminal. If
+% the \meta{function} or \meta{environment} has no known argument
+% specification then an error is issued.
+% \end{function}
+%
+% \section{Load-time options}
+%
+% \DescribeOption{log-declarations}
+% The package recognises the load-time option \texttt{log-declarations},
+% which is a key--value option taking the value \texttt{true} and
+% \texttt{false}. By default, the option is set to \texttt{true}, meaning
+% that each command or environment declared is logged. By loading
+% \pkg{xparse} using
+% \begin{verbatim}
+% \usepackage[load-declarations=false]{xparse}
+% \end{verbatim}
+% this may be suppressed and no information messages are produced.
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{xparse} implementation}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+\ProvidesExplPackage
+ {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
+\RequirePackage{expl3}
+% \end{macrocode}
+%
+% A check to make sure that \pkg{expl3} is not too old
+% \begin{macrocode}
+\@ifpackagelater { l3token } { 2011/07/02 }
+ { }
+ {
+ \PackageError { xparse } { Support~package~l3kernel~too~old. }
+ {
+ Please~install~an~up~to~date~version~of~l3kernel~
+ using~your~TeX~package~manager~or~from~CTAN.\\ \\
+ Loading~xparse~will~abort!
+ }
+ \tex_endinput:D
+ }
+% \end{macrocode}
+%
+% \subsection{Variables and constants}
+%
+% \begin{variable}{\c_xparse_shorthands_prop}
+% Shorthands are stored as a property list: this is set up here as it
+% is a constant.
+% \begin{macrocode}
+\prop_new:N \c_xparse_shorthands_prop
+\prop_put:Nnn \c_xparse_shorthands_prop { o } { d[] }
+\prop_put:Nnn \c_xparse_shorthands_prop { O } { D[] }
+\prop_put:Nnn \c_xparse_shorthands_prop { s } { t* }
+% \end{macrocode}
+ %\end{variable}
+%
+% \begin{variable}{\l_xparse_arg_tl}
+% Token list variable for single grabbed argument when post-processing.
+% \begin{macrocode}
+\tl_new:N \l_xparse_arg_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_xparse_args_tl}
+% Token list variable for grabbed arguments.
+% \begin{macrocode}
+\tl_new:N \l_xparse_args_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_xparse_environment_bool}
+% Generating environments uses the same mechanism as generating
+% functions. However, full processing of arguments is always needed
+% for environments, and so the function-generating code needs to
+% know this.
+% \begin{macrocode}
+\bool_new:N \l_xparse_environment_bool
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_xparse_error_bool}
+% Used to signal an error when creating expandable functions.
+% \begin{macrocode}
+\bool_new:N \l_xparse_error_bool
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_xparse_function_tl}
+% When creating expandable functions, the current function name needs
+% to be passed along.
+% \begin{macrocode}
+\tl_new:N \l_xparse_function_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_xparse_last_arg_tl}
+% Used when creating expandable arguments.
+% \begin{macrocode}
+\tl_new:N \l_xparse_last_arg_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_xparse_long_bool}
+% A flag for \cs{long} arguments.
+% \begin{macrocode}
+\bool_new:N \l_xparse_long_bool
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_xparse_m_args_int}
+% The number of simple \texttt{m} arguments is tracked so they can be
+% dumped \emph{en masse}.
+% \begin{macrocode}
+\int_new:N \l_xparse_m_args_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_xparse_m_only_bool}
+% A flag to indicate that only \texttt{m} arguments have been found.
+% \begin{macrocode}
+\bool_new:N \l_xparse_m_only_bool
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_xparse_mandatory_args_int}
+% So that trailing optional arguments can be picked up, a count has to
+% be taken of all mandatory arguments. This is then decreased as
+% mandatory arguments are added to the signature, so will be zero
+% only if there are no more mandatory arguments to add.
+% \begin{macrocode}
+\int_new:N \l_xparse_mandatory_args_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_xparse_processor_bool}
+% When reading through the argument specifier, a flag is needed to
+% show that a processor has been found for the current argument. This
+% is used when checking how to handle \texttt{m} arguments.
+% \begin{macrocode}
+\bool_new:N \l_xparse_processor_bool
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_xparse_processor_int}
+% In the grabber routine, each processor is saved with a number
+% recording the order it was found in. The total is then used to work
+% back through the grabbers so they apply to the argument right to left.
+% \begin{macrocode}
+\int_new:N \l_xparse_processor_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_xparse_signature_tl}
+% Token list variable for constructing signatures.
+% \begin{macrocode}
+\tl_new:N \l_xparse_signature_tl
+% \end{macrocode}
+%\end{variable}
+%
+% \begin{variable}{\l_xparse_tmp_tl}
+% A general purpose token list variable.
+% \begin{macrocode}
+\tl_new:N \l_xparse_tmp_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_xparse_total_args_int}
+% The total number of arguments is used to create the internal function
+% which has a fixed number of arguments.
+% \begin{macrocode}
+\int_new:N \l_xparse_total_args_int
+% \end{macrocode}
+% \end{variable}
+%
+% \subsection{Turning the argument specifier into grabbers}
+%
+% \begin{macro}{\xparse_add_grabber_mandatory:N}
+% \begin{macro}{\xparse_add_grabber_optional:N}
+% To keep the various checks needed in one place, adding the grabber to
+% the signature is done here. For mandatory arguments, the only question
+% is whether to add a long grabber. For optional arguments, there is
+% also a check to see if any mandatory arguments are still to be added.
+% This is used to determine whether to skip spaces or not where
+% searching for the argument.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \xparse_add_grabber_mandatory:N #1
+ {
+ \tl_put_right:Nx \l_xparse_signature_tl
+ {
+ \exp_not:c
+ { xparse_grab_ #1 \bool_if:NT \l_xparse_long_bool { _long } :w }
+ }
+ \bool_set_false:N \l_xparse_long_bool
+ \int_decr:N \l_xparse_mandatory_args_int
+ }
+\cs_new_protected_nopar:Npn \xparse_add_grabber_optional:N #1
+ {
+ \tl_put_right:Nx \l_xparse_signature_tl
+ {
+ \exp_not:c
+ {
+ xparse_grab_ #1
+ \bool_if:NT \l_xparse_long_bool { _long }
+ \int_compare:nNnF \l_xparse_mandatory_args_int > \c_zero
+ { _trailing }
+ :w
+ }
+ }
+ \bool_set_false:N \l_xparse_long_bool
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% All of the argument-adding functions work in essentially the same
+% way, except the one for \texttt{m} arguments. Any collected \texttt{m}
+% arguments are added to the signature, then the appropriate grabber
+% is added to the signature. Some of the adding functions also pick up
+% one or more arguments, and are also added to the signature. All of the
+% functions then call the loop function \cs{xparse_prepare_signature:N}.
+%
+% \begin{macro}{\xparse_add_type_+:w}
+% Making the next argument \cs{long} means setting the flag and
+% knocking one back off the total argument count. The \texttt{m}
+% arguments are recorded here as this has to be done for every case
+% where there is then a \cs{long} argument.
+% \begin{macrocode}
+\cs_new_protected_nopar:cpn { xparse_add_type_+:w }
+ {
+ \xparse_flush_m_args:
+ \bool_set_true:N \l_xparse_long_bool
+ \bool_set_false:N \l_xparse_m_only_bool
+ \int_decr:N \l_xparse_total_args_int
+ \xparse_prepare_signature:N
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\xparse_add_type_>:w}
+% When a processor is found, the function \cs{xparse_process_arg:n}
+% is added to the signature along with the processor code itself. When
+% the signature is used, the code will be added to an execution list by
+% \cs{xparse_process_arg:n}. Here, the loop calls
+% \cs{xparse_prepare_signature_aux:N} rather than
+% \cs{xparse_prepare_signature:N} so that the flag is not reset.
+% \begin{macrocode}
+\cs_new_protected:cpn { xparse_add_type_>:w } #1
+ {
+ \bool_set_true:N \l_xparse_processor_bool
+ \xparse_flush_m_args:
+ \int_decr:N \l_xparse_total_args_int
+ \tl_put_right:Nn \l_xparse_signature_tl { \xparse_process_arg:n {#1} }
+ \xparse_prepare_signature_aux:N
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\xparse_add_type_d:w}
+% To save on repeated code, \texttt{d} is actually turned into
+% the same grabber as is used by \texttt{D}, by putting the
+% \cs{NoValue} default in the correct place. So there is some
+% simple argument re-arrangement to do. Remember that |#1| and |#2|
+% should be single tokens.
+% \begin{macrocode}
+\cs_new_protected:Npn \xparse_add_type_d:w #1#2
+ { \xparse_add_type_D:w #1 #2 { \NoValue } }
+% \end{macrocode}
+%\end{macro}
+%
+% \begin{macro}{\xparse_add_type_D:w}
+% All of the optional delimited arguments are handled internally by
+% the \texttt{D} type. At this stage, the two delimiters are stored
+% along with the default value.
+% \begin{macrocode}
+\cs_new_protected:Npn \xparse_add_type_D:w #1#2#3
+ {
+ \xparse_flush_m_args:
+ \xparse_add_grabber_optional:N D
+ \tl_put_right:Nn \l_xparse_signature_tl { #1 #2 {#3} }
+ \xparse_prepare_signature:N
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\xparse_add_type_g:w}
+% The \texttt{g} type is simply an alias for \texttt{G} with the
+% correct default built-in.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \xparse_add_type_g:w
+ { \xparse_add_type_G:w { \NoValue } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\xparse_add_type_G:w}
+% For the \texttt{G} type, the grabber and the default are added to
+% the signature.
+% \begin{macrocode}
+\cs_new_protected:Npn \xparse_add_type_G:w #1
+ {
+ \xparse_flush_m_args:
+ \xparse_add_grabber_optional:N G
+ \tl_put_right:Nn \l_xparse_signature_tl { {#1} }
+ \xparse_prepare_signature:N
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\xparse_add_type_l:w}
+% Finding \texttt{l} arguments is very simple: there is nothing to do
+% other than add the grabber.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \xparse_add_type_l:w
+ {
+ \xparse_flush_m_args:
+ \xparse_add_grabber_mandatory:N l
+ \xparse_prepare_signature:N
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\xparse_add_type_m:w}
+% The \texttt{m} type is special as short arguments which are not
+% post-processed are simply counted at this stage. Thus there is a check
+% to see if either of these cases apply. If so, a one-argument grabber
+% is added to the signature. On the other hand, if a standard short
+% argument is required it is simply counted at this stage, to be
+% added later using \cs{xparse_flush_m_args:}.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \xparse_add_type_m:w
+ {
+ \bool_if:nTF { \l_xparse_long_bool || \l_xparse_processor_bool }
+ {
+ \xparse_flush_m_args:
+ \xparse_add_grabber_mandatory:N m
+ }
+ { \int_incr:N \l_xparse_m_args_int }
+ \xparse_prepare_signature:N
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\xparse_add_type_t:w}
+% Setting up a \texttt{t} argument means collecting one token for the
+% test, and adding it along with the grabber to the signature.
+% \begin{macrocode}
+\cs_new_protected:Npn \xparse_add_type_t:w #1
+ {
+ \xparse_flush_m_args:
+ \xparse_add_grabber_optional:N t
+ \tl_put_right:Nn \l_xparse_signature_tl { #1 }
+ \xparse_prepare_signature:N
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\xparse_add_type_u:w}
+% At the set up stage, the \texttt{u} type argument is identical to the
+% \texttt{G} type except for the name of the grabber function.
+% \begin{macrocode}
+\cs_new_protected:Npn \xparse_add_type_u:w #1
+ {
+ \xparse_flush_m_args:
+ \xparse_add_grabber_mandatory:N u
+ \tl_put_right:Nn \l_xparse_signature_tl { {#1} }
+ \xparse_prepare_signature:N
+ }
+% \end{macrocode}
+%\end{macro}
+%
+% \begin{macro}{\xparse_check_and_add:N}
+% This function checks if the argument type actually exists and gives
+% an error if it doesn't.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \xparse_check_and_add:N #1
+ {
+ \cs_if_free:cTF { xparse_add_type_ #1 :w }
+ {
+ \msg_error:nnx { xparse } { unknown-argument-type }
+ { \tl_to_str:n {#1} }
+ \xparse_add_type_m:w
+ }
+ { \use:c { xparse_add_type_ #1 :w } }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\xparse_count_mandatory:n}
+% \begin{macro}{\xparse_count_mandatory:N}
+% \begin{macro}[aux]{\xparse_count_mandatory_aux:N}
+% To count up mandatory arguments before the main parsing run, the
+% same approach is used. First, check if the current token is a
+% short-cut for another argument type. If it is, expand it and loop
+% again. If not, then look for a `counting' function to check the
+% argument type. No error is raised here if one is not found as one
+% will be raised by later code.
+% \begin{macrocode}
+\cs_new_protected:Npn \xparse_count_mandatory:n #1
+ {
+ \int_zero:N \l_xparse_mandatory_args_int
+ \xparse_count_mandatory:N #1 \q_nil
+ }
+\cs_new_protected:Npn \xparse_count_mandatory:N #1
+ {
+ \quark_if_nil:NF #1
+ {
+ \prop_if_in:NnTF \c_xparse_shorthands_prop {#1}
+ {
+ \prop_get:NnN \c_xparse_shorthands_prop {#1} \l_xparse_tmp_tl
+ \exp_last_unbraced:NV \xparse_count_mandatory:N \l_xparse_tmp_tl
+ }
+ { \xparse_count_mandatory_aux:N #1 }
+ }
+ }
+\cs_new_protected:Npn \xparse_count_mandatory_aux:N #1
+ {
+ \cs_if_free:cTF { xparse_count_type_ #1 :w }
+ { \xparse_count_type_m:w }
+ { \use:c { xparse_count_type_ #1 :w } }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\xparse_count_type_>:w}
+% \begin{macro}{\xparse_count_type_+:w}
+% \begin{macro}{\xparse_count_type_d:w}
+% \begin{macro}{\xparse_count_type_D:w}
+% \begin{macro}{\xparse_count_type_g:w}
+% \begin{macro}{\xparse_count_type_G:w}
+% \begin{macro}{\xparse_count_type_l:w}
+% \begin{macro}{\xparse_count_type_m:w}
+% \begin{macro}{\xparse_count_type_t:w}
+% \begin{macro}{\xparse_count_type_u:w}
+% For counting the mandatory arguments, a function is provided for
+% each argument type that will mop any extra arguments and call the
+% loop function. Only the counting functions for mandatory arguments
+% actually do anything: the rest are simply there to ensure the loop
+% continues correctly.
+% \begin{macrocode}
+\cs_new_protected:cpn { xparse_count_type_>:w } #1
+ { \xparse_count_mandatory:N }
+\cs_new_protected_nopar:cpn { xparse_count_type_+:w }
+ { \xparse_count_mandatory:N }
+\cs_new_protected:Npn \xparse_count_type_d:w #1#2
+ { \xparse_count_mandatory:N }
+\cs_new_protected:Npn \xparse_count_type_D:w #1#2#3
+ { \xparse_count_mandatory:N }
+\cs_new_protected_nopar:Npn \xparse_count_type_g:w
+ { \xparse_count_mandatory:N }
+\cs_new_protected:Npn \xparse_count_type_G:w #1
+ { \xparse_count_mandatory:N }
+\cs_new_protected_nopar:Npn \xparse_count_type_l:w
+ {
+ \int_incr:N \l_xparse_mandatory_args_int
+ \xparse_count_mandatory:N
+ }
+\cs_new_protected_nopar:Npn \xparse_count_type_m:w
+ {
+ \int_incr:N \l_xparse_mandatory_args_int
+ \xparse_count_mandatory:N
+ }
+\cs_new_protected:Npn \xparse_count_type_t:w #1
+ { \xparse_count_mandatory:N }
+\cs_new_protected:Npn \xparse_count_type_u:w #1
+ {
+ \int_incr:N \l_xparse_mandatory_args_int
+ \xparse_count_mandatory:N
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\xparse_declare_cmd:Nnn}
+% \begin{macro}[aux]{\xparse_declare_cmd_aux:Nnn}
+% \begin{macro}[aux]{\xparse_declare_cmd_aux:cnn}
+% \begin{macro}[aux]{\xparse_declare_cmd_all_m:Nn}
+% \begin{macro}[aux]{\xparse_declare_cmd_mixed:Nn}
+% First, the signature is set up from the argument specification. There
+% is then a check: if only \texttt{m} arguments are needed (which
+% includes functions with no arguments at all) then the definition is
+% simple. On the other hand, if the signature is more complex then an
+% internal function actually contains the code with the user function
+% as a simple wrapper.
+% \begin{macrocode}
+\cs_new_protected:Npn \xparse_declare_cmd:Nnn #1#2
+ {
+ \cs_if_exist:NTF #1
+ {
+ \msg_warning:nnxx { xparse } { redefine-command }
+ { \token_to_str:N #1 } { \tl_to_str:n {#2} }
+ }
+ {
+ \msg_info:nnxx { xparse } { define-command }
+ { \token_to_str:N #1 } { \tl_to_str:n {#2} }
+ }
+ \xparse_declare_cmd_aux:Nnn #1 {#2}
+ }
+\cs_new_protected:Npn \xparse_declare_cmd_aux:Nnn #1#2#3
+ {
+ \tl_clear_new:c { l_xparse_ \token_to_str:N #1 _arg_spec_tl }
+ \tl_set:cn { l_xparse_ \token_to_str:N #1 _arg_spec_tl } {#2}
+ \xparse_count_mandatory:n {#2}
+ \xparse_prepare_signature:n {#2}
+ \bool_if:NTF \l_xparse_m_only_bool
+ { \xparse_declare_cmd_all_m:Nn #1 {#3} }
+ { \xparse_declare_cmd_mixed:Nn #1 {#3} }
+ }
+\cs_generate_variant:Nn \xparse_declare_cmd_aux:Nnn { cnn }
+\cs_new_protected:Npn \xparse_declare_cmd_all_m:Nn #1#2
+ {
+ \cs_generate_from_arg_count:NNnn
+ #1 \cs_set_protected_nopar:Npn \l_xparse_total_args_int {#2}
+ }
+\cs_new_protected:Npn \xparse_declare_cmd_mixed:Nn #1#2
+ {
+ \group_begin:
+ \tex_escapechar:D 92 \scan_stop:
+ \tl_set:Nx \l_xparse_function_tl { \token_to_str:N #1 }
+ \exp_args:NNNo \group_end:
+ \tl_set:Nn \l_xparse_function_tl { \l_xparse_function_tl }
+ \cs_set_protected_nopar:Npx #1
+ {
+ \exp_not:n
+ {
+ \int_zero:N \l_xparse_processor_int
+ \tl_set:Nn \l_xparse_args_tl
+ }
+ { \exp_not:c { \l_xparse_function_tl } }
+ \exp_not:o \l_xparse_signature_tl
+ \exp_not:N \l_xparse_args_tl
+ }
+ \cs_generate_from_arg_count:cNnn
+ { \token_to_str:N #1 } \cs_set:Npn \l_xparse_total_args_int {#2}
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%
+% \begin{macro}{\xparse_declare_cmd_implementation:nNn}
+% Creating a stand-alone implementation using the \enquote{two-part}
+% mechanism is quite easy as this is just a wrapper for
+% \cs{cs_generate_from_arg_count:cNnn}.
+% \begin{macrocode}
+\cs_new_protected:Npn \xparse_declare_cmd_implementation:nNn #1#2#3
+ {
+ \cs_generate_from_arg_count:cNnn { implementation_ #1 :w }
+ \cs_set:Npn {#2} {#3}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\xparse_declare_cmd_interface:Nnn}
+% \begin{macro}[aux]{\xparse_declare_cmd_interface_all_m:Nn}
+% \begin{macro}[aux]{\xparse_declare_cmd_interface_mixed:Nn}
+% As with the basic function \cs{xparse_declare_cmd:Nnn}, there are
+% three things to do here. First, generate a signature from the
+% argument specification. Then use that to create a function which
+% will call the implementation part. Finally, a holder implementation
+% is created. As before, there is a short-cut for functions which only
+% have \texttt{m} type arguments.
+% \begin{macrocode}
+\cs_new_protected:Npn \xparse_declare_cmd_interface:Nnn #1#2#3
+ {
+ \xparse_prepare_signature:n {#3}
+ \bool_if:NTF \l_xparse_m_only_bool
+ { \xparse_declare_cmd_interface_all_m:Nn #1 {#2} }
+ { \xparse_declare_cmd_interface_mixed:Nn #1 {#2} }
+ \cs_generate_from_arg_count:cNnn { implementation_ #2 :w }
+ \cs_set:Npn \l_xparse_total_args_int { '#2' }
+ }
+\cs_new_protected:Npn \xparse_declare_cmd_interface_all_m:Nn #1#2
+ {
+ \cs_generate_from_arg_count:NNnn
+ #1 \cs_set_protected_nopar:Npn \l_xparse_total_args_int
+ { \use:c { implementation_ #2 :w } }
+ }
+\cs_new_protected:Npn \xparse_declare_cmd_interface_mixed:Nn #1#2
+ {
+ \cs_set_protected_nopar:Npx #1
+ {
+ \exp_not:n
+ {
+ \int_zero:N \l_xparse_processor_int
+ \tl_set:Nn \l_xparse_args_tl
+ }
+ { \exp_not:c { \token_to_str:N #1 } }
+ \exp_not:o \l_xparse_signature_tl
+ \exp_not:N \l_xparse_args_tl
+ }
+ \cs_generate_from_arg_count:cNnn
+ { \token_to_str:N #1 } \cs_set:Npn \l_xparse_total_args_int
+ { \use:c { implementation_ #2 :w } }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\xparse_declare_env:nnnn}
+% The idea here is to make sure that the end of the environment has the
+% same arguments available as the beginning.
+% \begin{macrocode}
+\cs_new_protected:Npn \xparse_declare_env:nnnn #1#2#3#4
+ {
+ \bool_set_true:N \l_xparse_environment_bool
+ \cs_if_exist:cTF {#1}
+ {
+ \msg_warning:nnxx { xparse } { redefine-environment }
+ { \tl_to_str:n {#1} } { \tl_to_str:n {#2} }
+ }
+ {
+ \msg_info:nnxx { xparse } { define-environment }
+ { \tl_to_str:n {#1} } { \tl_to_str:n {#2} }
+ }
+ \xparse_declare_cmd_aux:cnn { environment_begin_ #1 :w } {#2}
+ {
+ \group_begin:
+ \cs_set_protected_nopar:cpx { environment_end_ #1 :w }
+ {
+ \exp_not:c { environment_end_ #1 _aux:N }
+ \exp_not:o \l_xparse_args_tl
+ \group_end:
+ }
+ #3
+ }
+ \cs_set_protected_nopar:cpx { environment_end_ #1 : }
+ { \exp_not:c { environment_end_ #1 :w } }
+ \bool_set_false:N \l_xparse_environment_bool
+ \cs_set_nopar:cpx { environment_end_ #1 _aux:N } ##1
+ { \exp_not:c { environment_end_ #1 _aux :w } }
+ \cs_generate_from_arg_count:cNnn
+ { environment_end_ #1 _aux :w } \cs_set:Npn
+ \l_xparse_total_args_int {#4}
+ \cs_set_eq:cc {#1} { environment_begin_ #1 :w }
+ \cs_set_eq:cc { end #1 } { environment_end_ #1 : }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\xparse_flush_m_args:}
+% As \texttt{m} arguments are simply counted, there is a need to add
+% them to the token register in a block. As this function can only
+% be called if something other than \texttt{m} turns up, the flag can
+% be switched here. The total number of mandatory arguments added to
+% the signature is also decreased by the appropriate amount.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \xparse_flush_m_args:
+ {
+ \cs_if_exist:cT { xparse_grab_m_ \int_use:N \l_xparse_m_args_int :w }
+ {
+ \tl_put_right:Nx \l_xparse_signature_tl
+ { \exp_not:c { xparse_grab_m_ \int_use:N \l_xparse_m_args_int :w } }
+ \int_set:Nn \l_xparse_mandatory_args_int
+ { \l_xparse_mandatory_args_int - \l_xparse_m_args_int }
+ }
+ \int_zero:N \l_xparse_m_args_int
+ \bool_set_false:N \l_xparse_m_only_bool
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[TF]{\xparse_if_no_value:n}
+% Tests for \cs{NoValue}.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \xparse_if_no_value:n #1 { T , F , TF }
+ { \str_if_eq:nnTF {#1} { \NoValue } \prg_return_true: \prg_return_false: }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\xparse_prepare_signature:n}
+% Creating the signature is a case of working through the input and
+% turning into the output in \cs{l_xparse_signature_tl}. A track is
+% also kept of the total number of arguments. This function sets
+% everything up then hands off to the parser.
+% \begin{macrocode}
+\cs_new_protected:Npn \xparse_prepare_signature:n #1
+ {
+ \bool_set_false:N \l_xparse_long_bool
+ \int_zero:N \l_xparse_m_args_int
+ \bool_if:NTF \l_xparse_environment_bool
+ { \bool_set_false:N \l_xparse_m_only_bool }
+ { \bool_set_true:N \l_xparse_m_only_bool }
+ \bool_set_false:N \l_xparse_processor_bool
+ \tl_clear:N \l_xparse_signature_tl
+ \int_zero:N \l_xparse_total_args_int
+ \xparse_prepare_signature:N #1 \q_nil
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\xparse_prepare_signature:N}
+% \begin{macro}[aux]{\xparse_prepare_signature_aux:N}
+% The main signature-preparation loop is in two parts, to keep the code
+% a little clearer. Most of the checks here is pretty clear, with a key
+% point to watch what is next on the stack so that the loop continues
+% correctly.
+% \begin{macrocode}
+\cs_new_protected:Npn \xparse_prepare_signature:N #1
+ {
+ \bool_set_false:N \l_xparse_processor_bool
+ \xparse_prepare_signature_aux:N #1
+ }
+\cs_new_protected:Npn \xparse_prepare_signature_aux:N #1
+ {
+ \quark_if_nil:NTF #1
+ { \bool_if:NF \l_xparse_m_only_bool { \xparse_flush_m_args: } }
+ {
+ \prop_if_in:NnTF \c_xparse_shorthands_prop {#1}
+ {
+ \prop_get:NnN \c_xparse_shorthands_prop {#1} \l_xparse_tmp_tl
+ \exp_after:wN \xparse_prepare_signature:N \l_xparse_tmp_tl
+ }
+ {
+ \int_incr:N \l_xparse_total_args_int
+ \xparse_check_and_add:N #1
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\xparse_process_arg:n}
+% Processors are saved for use later during the grabbing process.
+% \begin{macrocode}
+\cs_new_protected:Npn \xparse_process_arg:n #1
+ {
+ \int_incr:N \l_xparse_processor_int
+ \cs_set:cpn { xparse_processor_ \int_use:N \l_xparse_processor_int :n } ##1
+ { #1 {##1} }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Grabbing arguments}
+%
+% \begin{macro}{\xparse_add_arg:n, \xparse_add_arg:V}
+% \begin{macro}[aux]{\xparse_add_arg_aux:n, \xparse_add_arg_aux:V}
+% The argument-storing system provides a single point for interfacing
+% with processors. They are done in a loop, counting downward. In this
+% way, the processor which was found last is executed first. The result
+% is that processors apply from right to left, as intended. Notice that
+% a set of braces are added back around the result of processing so that
+% the internal function will correctly pick up one argument for each
+% input argument.
+% \begin{macrocode}
+\cs_new_protected:Npn \xparse_add_arg:n #1
+ {
+ \int_compare:nNnTF \l_xparse_processor_int = \c_zero
+ { \tl_put_right:Nn \l_xparse_args_tl { {#1} } }
+ {
+ \xparse_if_no_value:nTF {#1}
+ {
+ \int_zero:N \l_xparse_processor_int
+ \tl_put_right:Nn \l_xparse_args_tl { {#1} }
+ }
+ { \xparse_add_arg_aux:n {#1} }
+ }
+ }
+\cs_generate_variant:Nn \xparse_add_arg:n { V }
+\cs_new_protected:Npn \xparse_add_arg_aux:n #1
+ {
+ \tl_set_eq:NN \ProcessedArgument \l_xparse_arg_tl
+ \use:c { xparse_processor_ \int_use:N \l_xparse_processor_int :n } {#1}
+ \int_decr:N \l_xparse_processor_int
+ \int_compare:nNnTF \l_xparse_processor_int = \c_zero
+ {
+ \tl_put_right:Nx \l_xparse_args_tl
+ { { \exp_not:V \ProcessedArgument } }
+ }
+ { \xparse_add_arg_aux:V \ProcessedArgument }
+}
+\cs_generate_variant:Nn \xparse_add_arg_aux:n { V }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% All of the grabbers follow the same basic pattern. The initial
+% function sets up the appropriate information to define
+% \cs{parse_grab_arg:w} to grab the argument. This means determining
+% whether to use \cs{cs_set:Npn} or \cs{cs_set_nopar:Npn}, and for
+% optional arguments whether to skip spaces. In all cases,
+% \cs{xparse_grab_arg:w} is then called to actually do the grabbing.
+%
+% \begin{macro}{\xparse_grab_arg:w}
+% \begin{macro}[aux]{\xparse_grab_arg_aux_i:w}
+% \begin{macro}[aux]{\xparse_grab_arg_aux_ii:w}
+% Each time an argument is actually grabbed, \pkg{xparse} defines a
+% function to do it. In that way, long arguments from previous functions
+% can be included in the definition of the grabber function, so that
+% it does not raise an error if not long. The generic function used
+% for this is reserved here. A couple of auxiliary functions are also
+% needed in various places.
+% \begin{macrocode}
+\cs_new_protected:Npn \xparse_grab_arg:w { }
+\cs_new_protected:Npn \xparse_grab_arg_aux_i:w { }
+\cs_new_protected:Npn \xparse_grab_arg_aux_ii:w { }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\xparse_grab_D:w}
+% \begin{macro}{\xparse_grab_D_long:w}
+% \begin{macro}{\xparse_grab_D_trailing:w}
+% \begin{macro}{\xparse_grab_D_long_trailing:w}
+% The generic delimited argument grabber. The auxiliary function does
+% a peek test before calling \cs{xparse_grab_arg:w}, so that the
+% optional nature of the argument works as expected.
+% \begin{macrocode}
+\cs_new_protected:Npn \xparse_grab_D:w #1#2#3#4 \l_xparse_args_tl
+ {
+ \xparse_grab_D_aux:NNnnNn #1 #2 {#3} {#4} \cs_set_protected_nopar:Npn
+ { _ignore_spaces }
+ }
+\cs_new_protected:Npn \xparse_grab_D_long:w #1#2#3#4 \l_xparse_args_tl
+ {
+ \xparse_grab_D_aux:NNnnNn #1 #2 {#3} {#4} \cs_set_protected:Npn
+ { _ignore_spaces }
+ }
+\cs_new_protected:Npn \xparse_grab_D_trailing:w #1#2#3#4 \l_xparse_args_tl
+ { \xparse_grab_D_aux:NNnnNn #1 #2 {#3} {#4} \cs_set_protected_nopar:Npn { } }
+\cs_new_protected:Npn \xparse_grab_D_long_trailing:w #1#2#3#4 \l_xparse_args_tl
+ { \xparse_grab_D_aux:NNnnNn #1 #2 {#3} {#4} \cs_set_protected:Npn { } }
+% \end{macrocode}
+% \begin{macro}[aux]{\xparse_grab_D_aux:NNnnNn}
+% This is a bit complicated. The idea is that, in order to check for
+% nested optional argument tokens (\texttt{[[...]]} and so on) the
+% argument needs to be grabbed without removing any braces at all. If
+% this is not done, then cases like |[{[}]| fail. So after testing for
+% an optional argument, it is collected piece-wise. First, the opening
+% token is removed, then a check is made for a group. If it looks like
+% the entire argument is a group, then an extra set of braces are
+% added back in. The closing token is then used to collect everything
+% else. There is then a test to see if there is nesting, by looking
+% for a \enquote{spare} open-argument token. If that is found, things hand
+% off to a loop to deal with that.
+% \begin{macrocode}
+\cs_new_protected:Npn \xparse_grab_D_aux:NNnnNn #1#2#3#4#5#6
+ {
+ #5 \xparse_grab_arg:w #1
+ {
+ \peek_meaning:NTF \c_group_begin_token
+ { \xparse_grab_arg_aux_i:w }
+ { \xparse_grab_arg_aux_ii:w }
+ }
+ #5 \xparse_grab_arg_aux_i:w ##1
+ {
+ \peek_charcode:NTF #2
+ { \xparse_grab_arg_aux_ii:w { {##1} } }
+ { \xparse_grab_arg_aux_ii:w {##1} }
+ }
+ #5 \xparse_grab_arg_aux_ii:w ##1 #2
+ {
+ \tl_if_in:nnTF {##1} {#1}
+ { \xparse_grab_D_nested:NNnnN #1 #2 {##1} {#4} #5 }
+ {
+ \xparse_add_arg:n {##1}
+ #4 \l_xparse_args_tl
+ }
+ }
+ \use:c { peek_charcode #6 :NTF } #1
+ { \xparse_grab_arg:w }
+ {
+ \xparse_add_arg:n {#3}
+ #4 \l_xparse_args_tl
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \begin{macro}[aux]{\xparse_grab_D_nested:NNnnN}
+% \begin{macro}{\l_xparse_nesting_a_tl}
+% \begin{macro}{\l_xparse_nesting_b_tl}
+% \begin{macro}{\q_xparse}
+% Catching nested optional arguments means more work. The aim here is
+% to collect up each pair of optional tokens without \TeX{} helping out,
+% and without counting anything. The code above will already have
+% removed the leading opening token and a closing token, but the
+% wrong one. The aim is then to work through the the material grabbed
+% so far and divide it up on each opening token, grabbing a closing
+% token to match (thus working in pairs). Once there are no opening
+% tokens, then there is a second check to see if there are any
+% opening tokens in the second part of the argument (for things
+% like |[][]|). Once everything has been found, the entire collected
+% material is added to the output as a single argument.
+% \begin{macrocode}
+\tl_new:N \l_xparse_nesting_a_tl
+\tl_new:N \l_xparse_nesting_b_tl
+\quark_new:N \q_xparse
+\cs_new_protected:Npn \xparse_grab_D_nested:NNnnN #1#2#3#4#5
+ {
+ \tl_clear:N \l_xparse_nesting_a_tl
+ \tl_clear:N \l_xparse_nesting_b_tl
+ #5 \xparse_grab_arg:w ##1 #1 ##2 \q_xparse ##3 #2
+ {
+ \tl_put_right:Nn \l_xparse_nesting_a_tl { ##1 #1 }
+ \tl_put_right:Nn \l_xparse_nesting_b_tl { #2 ##3 }
+ \tl_if_in:nnTF {##2} {#1}
+ { \xparse_grab_arg:w ##2 \q_xparse }
+ {
+ \tl_put_right:Nn \l_xparse_nesting_a_tl {##2}
+ \tl_if_in:NnTF \l_xparse_nesting_b_tl {#1}
+ {
+ \tl_set_eq:NN \l_xparse_tmp_tl \l_xparse_nesting_b_tl
+ \tl_clear:N \l_xparse_nesting_b_tl
+ \exp_after:wN \xparse_grab_arg:w \l_xparse_tmp_tl \q_xparse
+ }
+ {
+ \tl_put_right:No \l_xparse_nesting_a_tl
+ \l_xparse_nesting_b_tl
+ \xparse_add_arg:V \l_xparse_nesting_a_tl
+ #4 \l_xparse_args_tl
+ }
+ }
+ }
+ \xparse_grab_arg:w #3 \q_xparse
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\xparse_grab_G:w}
+% \begin{macro}{\xparse_grab_G_long:w}
+% \begin{macro}{\xparse_grab_G_trailing:w}
+% \begin{macro}{\xparse_grab_G_long_trailing:w}
+% \begin{macro}[aux]{\xparse_grab_G_aux:nnNn}
+% Optional groups are checked by meaning, so that the same code will
+% work with, for example, Con\TeX{}t-like input.
+% \begin{macrocode}
+\cs_new_protected:Npn \xparse_grab_G:w #1#2 \l_xparse_args_tl
+ {
+ \xparse_grab_G_aux:nnNn {#1} {#2} \cs_set_protected_nopar:Npn
+ { _ignore_spaces }
+ }
+\cs_new_protected:Npn \xparse_grab_G_long:w #1#2 \l_xparse_args_tl
+ {
+ \xparse_grab_G_aux:nnNn {#1} {#2} \cs_set_protected:Npn { _ignore_spaces }
+ }
+\cs_new_protected:Npn \xparse_grab_G_trailing:w #1#2 \l_xparse_args_tl
+ { \xparse_grab_G_aux:nnNn {#1} {#2} \cs_set_protected_nopar:Npn { } }
+\cs_new_protected:Npn \xparse_grab_G_long_trailing:w #1#2 \l_xparse_args_tl
+ { \xparse_grab_G_aux:nnNn {#1} {#2} \cs_set_protected:Npn { } }
+\cs_new_protected:Npn \xparse_grab_G_aux:nnNn #1#2#3#4
+ {
+ #3 \xparse_grab_arg:w ##1
+ {
+ \xparse_add_arg:n {##1}
+ #2 \l_xparse_args_tl
+ }
+ \use:c { peek_meaning #4 :NTF } \c_group_begin_token
+ { \xparse_grab_arg:w }
+ {
+ \xparse_add_arg:n {#1}
+ #2 \l_xparse_args_tl
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\xparse_grab_l:w}
+% \begin{macro}{\xparse_grab_l_long:w}
+% \begin{macro}[aux]{\xparse_grab_l_aux:nN}
+% Argument grabbers for mandatory \TeX\ arguments are pretty simple.
+% \begin{macrocode}
+\cs_new_protected:Npn \xparse_grab_l:w #1 \l_xparse_args_tl
+ { \xparse_grab_l_aux:nN {#1} \cs_set_protected_nopar:Npn }
+\cs_new_protected:Npn \xparse_grab_l_long:w #1 \l_xparse_args_tl
+ { \xparse_grab_l_aux:nN {#1} \cs_set_protected:Npn }
+\cs_new_protected:Npn \xparse_grab_l_aux:nN #1#2
+ {
+ #2 \xparse_grab_arg:w ##1##
+ {
+ \xparse_add_arg:n {##1}
+ #1 \l_xparse_args_tl
+ }
+ \xparse_grab_arg:w
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\xparse_grab_m:w}
+% \begin{macro}{\xparse_grab_m_long:w}
+% Collecting a single mandatory argument is quite easy.
+% \begin{macrocode}
+\cs_new_protected:Npn \xparse_grab_m:w #1 \l_xparse_args_tl
+ {
+ \cs_set_protected_nopar:Npn \xparse_grab_arg:w ##1
+ {
+ \xparse_add_arg:n {##1}
+ #1 \l_xparse_args_tl
+ }
+ \xparse_grab_arg:w
+ }
+\cs_new_protected:Npn \xparse_grab_m_long:w #1 \l_xparse_args_tl
+ {
+ \cs_set_protected:Npn \xparse_grab_arg:w ##1
+ {
+ \xparse_add_arg:n {##1}
+ #1 \l_xparse_args_tl
+ }
+ \xparse_grab_arg:w
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\xparse_grab_m_1:w}
+% \begin{macro}{\xparse_grab_m_2:w}
+% \begin{macro}{\xparse_grab_m_3:w}
+% \begin{macro}{\xparse_grab_m_4:w}
+% \begin{macro}{\xparse_grab_m_5:w}
+% \begin{macro}{\xparse_grab_m_6:w}
+% \begin{macro}{\xparse_grab_m_7:w}
+% \begin{macro}{\xparse_grab_m_8:w}
+% Grabbing 1--8 mandatory arguments. We don't need to worry about
+% nine arguments as this is only possible if everything is
+% mandatory. Each function has an auxiliary so that \cs{par} tokens
+% from other arguments still work.
+% \begin{macrocode}
+\cs_new_protected:cpn { xparse_grab_m_1:w } #1 \l_xparse_args_tl
+ {
+ \cs_set_protected_nopar:Npn \xparse_grab_arg:w ##1
+ {
+ \tl_put_right:Nn \l_xparse_args_tl { {##1} }
+ #1 \l_xparse_args_tl
+ }
+ \xparse_grab_arg:w
+ }
+\cs_new_protected:cpn { xparse_grab_m_2:w } #1 \l_xparse_args_tl
+ {
+ \cs_set_protected_nopar:Npn \xparse_grab_arg:w ##1##2
+ {
+ \tl_put_right:Nn \l_xparse_args_tl { {##1} {##2} }
+ #1 \l_xparse_args_tl
+ }
+ \xparse_grab_arg:w
+ }
+\cs_new_protected:cpn { xparse_grab_m_3:w } #1 \l_xparse_args_tl
+ {
+ \cs_set_protected_nopar:Npn \xparse_grab_arg:w ##1##2##3
+ {
+ \tl_put_right:Nn \l_xparse_args_tl { {##1} {##2} {##3} }
+ #1 \l_xparse_args_tl
+ }
+ \xparse_grab_arg:w
+ }
+\cs_new_protected:cpn { xparse_grab_m_4:w } #1 \l_xparse_args_tl
+ {
+ \cs_set_protected_nopar:Npn \xparse_grab_arg:w ##1##2##3##4
+ {
+ \tl_put_right:Nn \l_xparse_args_tl { {##1} {##2} {##3} {##4} }
+ #1 \l_xparse_args_tl
+ }
+ \xparse_grab_arg:w
+ }
+\cs_new_protected:cpn { xparse_grab_m_5:w } #1 \l_xparse_args_tl
+ {
+ \cs_set_protected_nopar:Npn \xparse_grab_arg:w ##1##2##3##4##5
+ {
+ \tl_put_right:Nn \l_xparse_args_tl { {##1} {##2} {##3} {##4} {##5} }
+ #1 \l_xparse_args_tl
+ }
+ \xparse_grab_arg:w
+ }
+\cs_new_protected:cpn { xparse_grab_m_6:w } #1 \l_xparse_args_tl
+ {
+ \cs_set_protected_nopar:Npn \xparse_grab_arg:w ##1##2##3##4##5##6
+ {
+ \tl_put_right:Nn \l_xparse_args_tl
+ { {##1} {##2} {##3} {##4} {##5} {##6} }
+ #1 \l_xparse_args_tl
+ }
+ \xparse_grab_arg:w
+ }
+\cs_new_protected:cpn { xparse_grab_m_7:w } #1 \l_xparse_args_tl
+ {
+ \cs_set_protected_nopar:Npn \xparse_grab_arg:w ##1##2##3##4##5##6##7
+ {
+ \tl_put_right:Nn \l_xparse_args_tl
+ { {##1} {##2} {##3} {##4} {##5} {##6} {##7} }
+ #1 \l_xparse_args_tl
+ }
+ \xparse_grab_arg:w
+ }
+\cs_new_protected:cpn { xparse_grab_m_8:w } #1 \l_xparse_args_tl
+ {
+ \cs_set_protected_nopar:Npn \xparse_grab_arg:w ##1##2##3##4##5##6##7##8
+ {
+ \tl_put_right:Nn \l_xparse_args_tl
+ { {##1} {##2} {##3} {##4} {##5} {##6} {##7} {##8} }
+ #1 \l_xparse_args_tl
+ }
+ \xparse_grab_arg:w
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%\end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\xparse_grab_t:w}
+% \begin{macro}{\xparse_grab_t_long:w}
+% \begin{macro}{\xparse_grab_t_trailing:w}
+% \begin{macro}{\xparse_grab_t_long_trailing:w}
+% \begin{macro}[aux]{\xparse_grab_t_aux:NnNn}
+% Dealing with a token is quite easy. Check the match, remove the
+% token if needed and add a flag to the output.
+% \begin{macrocode}
+\cs_new_protected:Npn \xparse_grab_t:w #1#2 \l_xparse_args_tl
+ {
+ \xparse_grab_t_aux:NnNn #1 {#2} \cs_set_protected_nopar:Npn
+ { _ignore_spaces }
+ }
+\cs_new_protected:Npn \xparse_grab_t_long:w #1#2 \l_xparse_args_tl
+ { \xparse_grab_t_aux:NnNn #1 {#2} \cs_set_protected:Npn { _ignore_spaces } }
+\cs_new_protected:Npn \xparse_grab_t_trailing:w #1#2 \l_xparse_args_tl
+ { \xparse_grab_t_aux:NnNn #1 {#2} \cs_set_protected_nopar:Npn { } }
+\cs_new_protected:Npn \xparse_grab_t_long_trailing:w #1#2 \l_xparse_args_tl
+ { \xparse_grab_t_aux:NnNn #1 {#2} \cs_set_protected:Npn { } }
+\cs_new_protected:Npn \xparse_grab_t_aux:NnNn #1#2#3#4
+ {
+ #3 \xparse_grab_arg:w
+ {
+ \use:c { peek_charcode_remove #4 :NTF } #1
+ {
+ \xparse_add_arg:n { \BooleanTrue }
+ #2 \l_xparse_args_tl
+ }
+ {
+ \xparse_add_arg:n { \BooleanFalse }
+ #2 \l_xparse_args_tl
+ }
+ }
+ \xparse_grab_arg:w
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\xparse_grab_u:w}
+% \begin{macro}{\xparse_grab_u_long:w}
+% \begin{macro}[aux]{\xparse_grab_u_aux:NnN}
+% Grabbing up to a list of tokens is quite easy: define the grabber,
+% and then collect.
+% \begin{macrocode}
+\cs_new_protected:Npn \xparse_grab_u:w #1#2 \l_xparse_args_tl
+ { \xparse_grab_u_aux:NnN {#1} {#2} \cs_set_protected_nopar:Npn }
+\cs_new_protected:Npn \xparse_grab_u_long:w #1#2 \l_xparse_args_tl
+ { \xparse_grab_u_aux:NnN {#1} {#2} \cs_set_protected:Npn }
+\cs_new_protected:Npn \xparse_grab_u_aux:NnN #1#2#3
+ {
+ #3 \xparse_grab_arg:w ##1 #1
+ {
+ \xparse_add_arg:n {##1}
+ #2 \l_xparse_args_tl
+ }
+ \xparse_grab_arg:w
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Argument processors}
+%
+% \begin{macro}{\xparse_process_to_str:n}
+% A basic argument processor: as much an example as anything else.
+% \begin{macrocode}
+\cs_new_protected:Npn \xparse_process_to_str:n #1
+ { \tl_set:Nx \ProcessedArgument { \tl_to_str:n {#1} } }
+% \end{macrocode}
+%\end{macro}
+%
+% \begin{macro}{\xparse_bool_reverse:N}
+% A simple reversal.
+% \begin{macrocode}
+\cs_new_protected:Npn \xparse_bool_reverse:N #1
+ {
+ \bool_if:NTF #1
+ { \tl_set:Nn \ProcessedArgument { \c_false_bool } }
+ { \tl_set:Nn \ProcessedArgument { \c_true_bool } }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\l_xparse_split_argument_tl}
+% \begin{macro}{\xparse_split_argument:nnn}
+% \begin{macro}[aux]{\xparse_split_argument_aux_i:w}
+% \begin{macro}[aux]{\xparse_split_argument_aux_ii:w}
+% \begin{macro}[aux]{\xparse_split_argument_aux_iii:w}
+% The idea of this function is to split the input $n + 1$ times using
+% a given token.
+% \begin{macrocode}
+\tl_new:N \l_xparse_split_argument_tl
+\group_begin:
+ \char_set_catcode_active:N \@
+ \cs_new_protected:Npn \xparse_split_argument:nnn #1#2#3
+ {
+ \tl_set:Nn \l_xparse_split_argument_tl {#3}
+ \group_begin:
+ \char_set_lccode:nn { `\@ } { `#2}
+ \tl_to_lowercase:n
+ {
+ \group_end:
+ \tl_replace_all_in:Nnn \l_xparse_split_argument_tl { @ } {#2}
+ }
+ \cs_set_protected:Npn \xparse_split_argument_aux_i:w
+ ##1 \q_mark ##2 #2 ##3 \q_stop
+ {
+ \tl_put_right:Nn \ProcessedArgument { {##2} }
+ ##1 \q_mark ##3 \q_stop
+ }
+ \cs_set_protected:Npn \xparse_split_argument_aux_iii:w
+ ##1 #2 ##2 \q_stop
+ {
+ \IfNoValueF {##1}
+ {
+ \msg_error:nnxxx { xparse } { split-excess-tokens }
+ { \tl_to_str:n {#2} } { \tl_to_str:n {#1} }
+ { \tl_to_str:n {#3} }
+ }
+ }
+ \tl_set:Nx \l_xparse_tmp_tl
+ {
+ \prg_replicate:nn { #1 + 1 }
+ { \xparse_split_argument_aux_i:w }
+ \xparse_split_argument_aux_ii:w
+ \exp_not:N \q_mark
+ \exp_not:o \l_xparse_split_argument_tl
+ \prg_replicate:nn {#1} { \exp_not:n {#2} \NoValue }
+ \exp_not:n { #2 \q_stop }
+ }
+ \l_xparse_tmp_tl
+ }
+\group_end:
+\cs_new_protected:Npn \xparse_split_argument_aux_i:w { }
+\cs_new_protected:Npn \xparse_split_argument_aux_ii:w
+ #1 \q_mark #2 \q_stop
+ {
+ \tl_if_empty:nF {#2}
+ { \xparse_split_argument_aux_iii:w #2 \q_stop }
+ }
+\cs_new_protected:Npn \xparse_split_argument_aux_iii:w { }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+%\begin{macro}{\l_xparse_split_list_tl}
+%\begin{macro}{\xparse_split_list:nn}
+%\begin{macro}{\xparse_split_list_aux:w}
+% Splitting a list is done again by first dealing with active
+% characters, then looping over the list using the same method as the
+% \cs{clist_map_\ldots} functions.
+% \begin{macrocode}
+\tl_new:N \l_xparse_split_list_tl
+\group_begin:
+ \char_set_catcode_active:N \@
+ \cs_new_protected:Npn \xparse_split_list:nn #1#2
+ {
+ \tl_set:Nn \l_xparse_split_list_tl {#2}
+ \group_begin:
+ \char_set_lccode:nn { `\@ } { `#1 }
+ \tl_to_lowercase:n
+ {
+ \group_end:
+ \tl_replace_all_in:Nnn \l_xparse_split_list_tl { @ } {#1}
+ }
+ \cs_set:Npn \xparse_split_list_aux:w ##1 #1
+ {
+ \quark_if_recursion_tail_stop:n {##1}
+ \tl_put_right:Nn \ProcessedArgument { {##1} }
+ \xparse_split_list_aux:w
+ }
+ \tl_if_empty:NTF \l_xparse_split_list_tl
+ { \tl_set:Nn \ProcessedArgument { { } } }
+ {
+ \tl_clear:N \ProcessedArgument
+ \exp_after:wN \xparse_split_list_aux:w
+ \l_xparse_split_list_tl #1
+ \q_recursion_tail #1 \q_recursion_stop
+ }
+ }
+\group_end:
+\cs_new_protected:Npn \xparse_split_list_aux:w { }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Creating expandable functions}
+%
+% The trick here is to pass each grabbed argument along a chain of
+% auxiliary functions. Each one ultimately calls the next in the chain,
+% so that all of the arguments are passed along delimited using
+% \cs{q_xparse}. At the end of the chain, the marker is removed
+% so that the user-supplied code can be passed the correct number
+% of arguments. All of this is done by expansion!
+%
+% \begin{macro}{\xparse_exp_add_type_d:w}
+% As in the standard case, the trick here is to slot in the default
+% and treat as type \texttt{D}.
+% \begin{macrocode}
+\cs_new_protected:Npn \xparse_exp_add_type_d:w #1#2
+ { \xparse_exp_add_type_D:w #1 #2 { \NoValue } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\xparse_exp_add_type_D:w}
+% The most complex argument to grab in an expandable manner is the
+% general delimited one. First, a short-cut is set up in
+% \cs{l_xparse_tmp_tl} for the name of the current grabber function.
+% This is then created to grab one argument and test if it is equal
+% to the opening delimiter. If the test fails, the code adds the default
+% value and closing delimiter before `recycling' the argument. In either
+% case, the second auxiliary function is called. It finds the closing
+% delimiter and so the optional argument (if any). The function then
+% calls the next one in the chain, passing along the argument(s)
+% grabbed thus-far using \cs{q_xparse} as a marker.
+% \begin{macrocode}
+\cs_new_protected:Npn \xparse_exp_add_type_D:w #1#2#3
+ {
+ \tl_set:Nx \l_xparse_tmp_tl
+ {
+ \exp_after:wN \token_to_str:N \l_xparse_function_tl
+ \int_use:N \l_xparse_total_args_int
+ }
+ \xparse_exp_set:cpx { \l_xparse_tmp_tl } ##1 \q_xparse ##2
+ {
+ \exp_not:N \tl_if_head_eq_charcode:nNTF {##2} #1
+ {
+ \exp_not:c { \l_xparse_tmp_tl aux }
+ ##1 \exp_not:N \q_xparse
+ }
+ {
+ \exp_not:c { \l_xparse_tmp_tl aux }
+ ##1 \exp_not:N \q_xparse #3 #2 {##2}
+ }
+ }
+ \xparse_exp_set:cpx { \l_xparse_tmp_tl aux} ##1 \q_xparse ##2 #2
+ {
+ \exp_not:c
+ {
+ \exp_after:wN \token_to_str:N \l_xparse_function_tl
+ \int_eval:n { \l_xparse_total_args_int + 1 }
+ }
+ ##1 {##2} \exp_not:N \q_xparse
+ }
+ \xparse_exp_prepare_function:N
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\xparse_exp_add_type_l:w}
+% \begin{macro}{\xparse_exp_add_type_m:w}
+% Gathering \texttt{l} and \texttt{m} arguments is almost the same.
+% The grabber for the current argument is created to simply get the
+% necessary argument and pass it along with any others through to the
+% next function in the chain.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \xparse_exp_add_type_l:w
+ {
+ \xparse_exp_set:cpx
+ {
+ \exp_after:wN \token_to_str:N \l_xparse_function_tl
+ \int_use:N \l_xparse_total_args_int
+ }
+ ##1 \q_xparse ##2##
+ {
+ \exp_not:c
+ {
+ \exp_after:wN \token_to_str:N \l_xparse_function_tl
+ \int_eval:n { \l_xparse_total_args_int + 1 }
+ }
+ ##1 {##2} \exp_not:N \q_xparse
+ }
+ \xparse_exp_prepare_function:N
+ }
+\cs_new_protected_nopar:Npn \xparse_exp_add_type_m:w
+ {
+ \int_incr:N \l_xparse_m_args_int
+ \xparse_exp_set:cpx
+ {
+ \exp_after:wN \token_to_str:N \l_xparse_function_tl
+ \int_use:N \l_xparse_total_args_int
+ }
+ ##1 \q_xparse ##2
+ {
+ \exp_not:c
+ {
+ \exp_after:wN \token_to_str:N \l_xparse_function_tl
+ \int_eval:n { \l_xparse_total_args_int + 1 }
+ }
+ ##1 {##2} \exp_not:N \q_xparse
+ }
+ \xparse_exp_prepare_function:N
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\xparse_exp_add_type_t:w}
+% Looking for a single token is a simpler version of the \texttt{D}
+% code. The same idea of picking up one argument is used, but there is
+% no need for a second function as there is no closing token to find. So
+% either \cs{BooleanTrue} or \cs{BooleanFalse} are added to the list of
+% arguments. In the later case, the grabber argument must be `recycled'.
+% \begin{macrocode}
+\cs_new_protected:Npn \xparse_exp_add_type_t:w #1
+ {
+ \tl_set:Nx \l_xparse_tmp_tl
+ {
+ \exp_after:wN \token_to_str:N \l_xparse_function_tl
+ \int_eval:n { \l_xparse_total_args_int + 1 }
+ }
+ \xparse_exp_set:cpx
+ {
+ \exp_after:wN \token_to_str:N \l_xparse_function_tl
+ \int_use:N \l_xparse_total_args_int
+ }
+ ##1 \q_xparse ##2
+ {
+ \exp_not:N \tl_if_head_eq_charcode:nNTF {##2} #1
+ {
+ \exp_not:c { \l_xparse_tmp_tl }
+ ##1 \exp_not:n { { \BooleanTrue } \q_xparse }
+ }
+ {
+ \exp_not:c { \l_xparse_tmp_tl }
+ ##1 \exp_not:n { { \BooleanFalse } \q_xparse {##2} }
+ }
+ }
+ \xparse_exp_prepare_function:N
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\xparse_exp_add_type_u:w}
+% Setting up for a \texttt{u} argument is a case of defining the
+% grabber for the current argument in a delimited fashion. The rest of
+% the process is as the other grabbers: add to the chain and call the
+% next function.
+% \begin{macrocode}
+\cs_new_protected:Npn \xparse_exp_add_type_u:w #1
+ {
+ \xparse_exp_set:cpx
+ {
+ \exp_after:wN \token_to_str:N \l_xparse_function_tl
+ \int_use:N \l_xparse_total_args_int
+ }
+ ##1 \q_xparse ##2 #1
+ {
+ \exp_not:c
+ {
+ \exp_after:wN \token_to_str:N \l_xparse_function_tl
+ \int_eval:n { \l_xparse_total_args_int + 1 }
+ }
+ ##1 {##2} \exp_not:N \q_xparse
+ }
+ \xparse_exp_prepare_function:N
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\xparse_exp_check_and_add:N}
+% Virtually identical to the normal version, except calling the
+% expandable \texttt{add} functions rather than the standard versions.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \xparse_exp_check_and_add:N #1
+ {
+ \cs_if_free:cTF { xparse_exp_add_type_ #1 :w }
+ {
+ \msg_error:nnx { xparse } { unknown-argument-type }
+ { \tl_to_str:n {#1} }
+ \tl_set:Nn \l_xparse_last_arg_tl { m }
+ \xparse_exp_add_type_m:w
+ }
+ {
+ \tl_set:Nn \l_xparse_last_arg_tl {#1}
+ \use:c { xparse_exp_add_type_ #1 :w }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\xparse_exp_declare_cmd:Nnn}
+% \begin{macro}[aux]{\xparse_exp_declare_cmd_all_m:Nn}
+% \begin{macro}[aux]{\xparse_exp_declare_cmd_mixed:Nn}
+% \begin{macro}[aux]{\xparse_exp_declare_cmd_mixed_aux:Nn}
+% The overall scheme here is very different from the standard method.
+% For each argument, an internal function is created to grab an argument
+% and pass along previous ones. Each `daisy chains' to call the next
+% one in the sequence. Thus at the end of the chain, an extra `argument'
+% function is included to unwind the chain and pass data to the the
+% internal function containing the actual code. If all of the arguments
+% are type \texttt{m}, then the same tick is used as in the standard
+% version. The \texttt{x} in the lead-off and mop-up functions makes
+% sure that the braces around the first argument are not lost.
+% \begin{macrocode}
+\cs_new_protected:Npn \xparse_exp_declare_cmd:Nnn #1#2#3
+ {
+ \cs_if_exist:NTF #1
+ {
+ \msg_warning:nnxx { xparse } { redefine-command }
+ { \token_to_str:N #1 } { \tl_to_str:n {#2} }
+ }
+ {
+ \msg_info:nnxx { xparse } { define-command }
+ { \token_to_str:N #1 } { \tl_to_str:n {#2} }
+ }
+ \group_begin:
+ \tex_escapechar:D 92 \scan_stop:
+ \tl_set:Nx \l_xparse_function_tl { \token_to_str:N #1}
+ \exp_args:NNNo \group_end:
+ \tl_set:Nn \l_xparse_function_tl { \l_xparse_function_tl }
+ \xparse_exp_prepare_function:n {#2}
+ \int_compare:nNnTF \l_xparse_total_args_int = \l_xparse_m_args_int
+ { \xparse_exp_declare_cmd_all_m:Nn #1 {#3} }
+ { \xparse_exp_declare_cmd_mixed:Nn #1 {#3} }
+ }
+\cs_new_protected:Npn \xparse_exp_declare_cmd_all_m:Nn #1#2
+ {
+ \bool_if:NTF \l_xparse_long_bool
+ {
+ \cs_generate_from_arg_count:NNnn
+ #1 \cs_set:Npn \l_xparse_total_args_int {#2}
+ }
+ {
+ \cs_generate_from_arg_count:NNnn
+ #1 \cs_set_nopar:Npn \l_xparse_total_args_int {#2}
+ }
+ }
+\cs_new_protected:Npn \xparse_exp_declare_cmd_mixed:Nn #1#2
+ {
+ \tl_if_in:noTF { l m u } \l_xparse_last_arg_tl
+ { \xparse_exp_declare_cmd_mixed_aux:Nn #1 {#2} }
+ { \msg_error:nn { xparse } { expandable-ending-optional } }
+ }
+\cs_new_protected:Npn \xparse_exp_declare_cmd_mixed_aux:Nn #1#2
+ {
+ \cs_set_nopar:Npx #1
+ { \exp_not:c { \token_to_str:N #1 1 } x \exp_not:N \q_xparse }
+ \cs_set_nopar:cpx
+ { \token_to_str:N #1 \int_eval:n { \l_xparse_total_args_int + 1 } }
+ x ##1 \q_xparse
+ { \exp_not:c { \token_to_str:N #1 } ##1 }
+ \cs_generate_from_arg_count:cNnn
+ { \token_to_str:N #1 } \cs_set:Npn \l_xparse_total_args_int {#2}
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\xparse_exp_prepare_function:n}
+% \begin{macro}[aux]{\xparse_exp_prepare_function_aux:n}
+% A couple of early validation tests. Processors are forbidden, as are
+% \texttt{g}, \texttt{l} and \texttt{u} arguments (the later more for
+% ease than any technical reason).
+% \begin{macrocode}
+\cs_new_protected:Npn \xparse_exp_prepare_function:n #1
+ {
+ \bool_set_false:N \l_xparse_error_bool
+ \tl_if_in:nnT {#1} { > }
+ {
+ \msg_error:nnx { xparse } { processor-in-expandable }
+ { \tl_to_str:n {#1} }
+ \bool_set_true:N \l_xparse_error_bool
+ }
+ \tl_if_in:nnT {#1} { g }
+ {
+ \msg_error:nnx { xparse } { grouped-in-expandable }
+ { g } { \tl_to_str:n {#1} }
+ \bool_set_true:N \l_xparse_error_bool
+ }
+ \tl_if_in:nnT {#1} { G }
+ {
+ \msg_error:nnx { xparse } { grouped-in-expandable }
+ { G } { \tl_to_str:n {#1} }
+ \bool_set_true:N \l_xparse_error_bool
+ }
+ \bool_if:NF \l_xparse_error_bool
+ { \xparse_exp_prepare_function_aux:n {#1} }
+ }
+\cs_new_protected:Npn \xparse_exp_prepare_function_aux:n #1
+ {
+ \cs_set_eq:NN \xparse_prepare_next:w \xparse_exp_prepare_function:N
+ \cs_set_eq:NN \xparse_exp_set:cpx \cs_set_nopar:cpx
+ \bool_set_false:N \l_xparse_long_bool
+ \int_zero:N \l_xparse_m_args_int
+ \int_zero:N \l_xparse_total_args_int
+ \tl_if_in:nnT {#1} { + }
+ {
+ \bool_set_true:N \l_xparse_long_bool
+ \cs_set_eq:NN \xparse_exp_set:cpx \cs_set:cpx
+ }
+ \xparse_exp_prepare_function:N #1 \q_nil
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\xparse_exp_prepare_function:N}
+% \begin{macro}[aux]{\xparse_exp_prepare_function_long:N}
+% \begin{macro}[aux]{\xparse_exp_prepare_function_short:N}
+% Preparing functions is a case of reading the signature, as in the
+% normal case. However, everything has to be either short or long, and
+% so there is an extra step to make sure that once one \texttt{+} has
+% been seen everything has one. That detour then takes us back to
+% a standard looping concept.
+% \begin{macrocode}
+\cs_new_protected:Npn \xparse_exp_prepare_function:N #1
+ {
+ \bool_if:NTF \l_xparse_long_bool
+ { \xparse_exp_prepare_function_long:N #1 }
+ { \xparse_exp_prepare_function_short:N #1 }
+}
+\cs_new_protected:Npn \xparse_exp_prepare_function_long:N #1
+ {
+ \quark_if_nil:NF #1
+ {
+ \str_if_eq:nnTF {#1} { + }
+ { \xparse_exp_prepare_function_short:N }
+ {
+ \msg_error:nn { xparse } { inconsistent-long }
+ \xparse_exp_prepare_function_short:N #1
+ }
+ }
+ }
+\cs_new_protected:Npn \xparse_exp_prepare_function_short:N #1
+ {
+ \quark_if_nil:NF #1
+ {
+ \prop_if_in:NnTF \c_xparse_shorthands_prop {#1}
+ {
+ \prop_get:NnN \c_xparse_shorthands_prop {#1} \l_xparse_tmp_tl
+ \bool_if:NT \l_xparse_long_bool
+ { \tl_put_left:Nn \l_xparse_tmp_tl { + } }
+ \exp_after:wN \xparse_exp_prepare_function:N \l_xparse_tmp_tl
+ }
+ {
+ \int_incr:N \l_xparse_total_args_int
+ \xparse_exp_check_and_add:N #1
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\xparse_exp_set:cpx}
+% A short-cut to save constantly re-testing \cs{l_xparse_long_bool}.
+% \begin{macrocode}
+\cs_new_eq:NN \xparse_exp_set:cpx \cs_set_nopar:cpx
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Access to the argument specification}
+%
+% \begin{macro}{\xparse_get_arg_spec:N}
+% \begin{macro}{\xparse_get_arg_spec:n}
+% \begin{macro}{\ArgumentSpecification}
+% Recovering the argument specification is also trivial, using the
+% \cs{tl_set_eq:cN} function.
+% \begin{macrocode}
+\cs_new_protected:Npn \xparse_get_arg_spec:N #1
+ {
+ \cs_if_exist:cTF { l_xparse_ \token_to_str:N #1 _arg_spec_tl }
+ {
+ \tl_set_eq:Nc \ArgumentSpecification
+ { l_xparse_ \token_to_str:N #1 _arg_spec_tl }
+ }
+ {
+ \msg_error:nnx { xparse } { unknown-document-command }
+ { \token_to_str:N #1 }
+ }
+ }
+\cs_new_protected:Npn \xparse_get_arg_spec:n #1
+ {
+ \cs_if_exist:cTF { l_xparse_ #1 _arg_spec_tl }
+ { \tl_set_eq:Nc \ArgumentSpecification { l_xparse_ #1 _arg_spec_tl } }
+ {
+ \msg_error:nnx { xparse } { unknown-document-environment }
+ { \tl_to_str:n {#1} }
+ }
+ }
+\tl_new:N \ArgumentSpecification
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\xparse_show_arg_spec:N}
+% \begin{macro}{\xparse_show_arg_spec:n}
+% Showing the argument specification simply means finding it and then
+% calling the \cs{tl_show:c} function.
+% \begin{macrocode}
+\cs_new_protected:Npn \xparse_show_arg_spec:N #1
+ {
+ \cs_if_exist:cTF { l_xparse_ \token_to_str:N #1 _arg_spec_tl }
+ {
+ \tl_set_eq:Nc \ArgumentSpecification
+ { l_xparse_ \token_to_str:N #1 _arg_spec_tl }
+ \tl_show:N \ArgumentSpecification
+ }
+ {
+ \msg_error:nnx { xparse } { unknown-document-command }
+ { \token_to_str:N #1 }
+ }
+ }
+\cs_new_protected:Npn \xparse_show_arg_spec:n #1
+ {
+ \cs_if_exist:cTF { l_xparse_ #1 _arg_spec_tl }
+ {
+ \tl_set_eq:Nc \ArgumentSpecification { l_xparse_ #1 _arg_spec_tl }
+ \tl_show:N \ArgumentSpecification
+ }
+ {
+ \msg_error:nnx { xparse } { unknown-document-environment }
+ { \tl_to_str:n {#1} }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+%\subsection{Messages}
+%
+% Some messages intended as errors.
+% \begin{macrocode}
+\msg_new:nnnn { xparse } { command-already-defined }
+ { Command~'#1'~already~defined! }
+ {
+ You~have~used~\NewDocumentCommand
+ with~a~command~that~already~has~a~definition. \\
+ The~existing~definition~of~'#1'~will~be~overwritten.
+ }
+\msg_new:nnnn { xparse } { command-not-yet-defined }
+ { Command ~'#1'~not~yet~defined! }
+ {
+ You~have~used~\RenewDocumentCommand
+ with~a~command~that~was~never~defined.\\
+ A~new~command~'#1'~will~be~created.
+ }
+\msg_new:nnnn { xparse } { environment-already-defined }
+ { Environment~'#1'~already~defined! }
+ {
+ You~have~used~\NewDocumentEnvironment
+ with~an~environment~that~already~has~a~definition.\\
+ The~existing~definition~of~'#1'~will~be~overwritten.
+ }
+\msg_new:nnnn { xparse } { environment-mismatch }
+ { Mismatch~between~start~and~end~of~environment. }
+ {
+ The~current~environment~is~called~'#1',~but~you~have~tried~to~
+ end~one~called~'#2'.~Environments~have~to~be~properly~nested.
+ }
+\msg_new:nnnn { xparse } { environment-not-yet-defined }
+ { Environment~'#1'~not~yet~defined! }
+ {
+ You~have~used~\RenewDocumentEnvironment
+ with~an~environment~that~was~never~defined.\\
+ A~new~environment~'#1'~will~be~created.
+ }
+\msg_new:nnnn { xparse } { environment-unknown }
+ { Environment~'#1'~undefined. }
+ {
+ You~have~tried~to~start~an~environment~called~'#1',~
+ but~this~has~never~been~defined.\\
+ The~command~will~be~ignored.
+ }
+\msg_new:nnnn { xparse } { expandable-ending-optional }
+ { Signature~for~expandable~command~ends~with~optional~argument. }
+ {
+ \c_msg_coding_error_text_tl
+ Expandable~commands~must~have~a~final~mandatory~argument~
+ (or~no~arguments~at~all).~You~cannot~have~a~terminal~optional~
+ argument~with~expandable~commands.
+ }
+\msg_new:nnnn { xparse } { grouped-in-expandable }
+ { Argument~specifier~'#1'~forbidden~in~expandable~commands. }
+ {
+ \c_msg_coding_error_text_tl
+ Argument~specification~'#2'~contains~the~optional~grouped~
+ argument~'#1':~
+ this~is only~supported~for~standard~robust~functions.
+ }
+\msg_new:nnnn { xparse } { inconsistent-long }
+ { Inconsistent~long~arguments~for~expandable~command. }
+ {
+ \c_msg_coding_error_text_tl
+ The~arguments~for~an~expandable~command~must~either~all~be~
+ short~or~all~be~long.~You~have~tried~to~mix~the~two~types.
+ }
+\msg_new:nnnn { xparse } { processor-in-expandable }
+ { Argument~processors~cannot~be~used~with~expandable~functions. }
+ {
+ \c_msg_coding_error_text_tl
+ Argument~specification~'#1'~contains~a~processor~function:~
+ this~is~only~supported~for~standard~robust~functions.
+ }
+\msg_new:nnnn { xparse } { split-excess-tokens }
+ { Too~many~'#1'~tokens~when~trying~to~split~argument. }
+ {
+ LaTeX~was~asked~to~split~the~input~'#3'~
+ at~each~occurrence~of~the~token~'#1',~up~to~a~maximum~of~#2~parts.~
+ There~were~too~many~'#1'~tokens.
+ }
+\msg_new:nnnn { xparse } { unknown-argument-type }
+ { Unknown~argument~type~'#1'~replaced~by~'m'. }
+ {
+ \c_msg_coding_error_text_tl
+ The~letter~'#1'~does~not~specify~a~known~argument~type.~
+ LaTeX~will~assume~you~want~a~standard~mandatory~argument~(type~'m').
+ }
+\msg_new:nnnn { xparse } { unknown-document-command }
+ { Unknown~document~command~'#1'. }
+ {
+ You~have~asked~for~the~argument~specification~for~a~command~'#1',~
+ but~this~is~not~a~document~command.
+ }
+\msg_new:nnnn { xparse } { unknown-document-environment }
+ { Unknown~document~environment~'#1'. }
+ {
+ You~have~asked~for~the~argument~specification~for~a~command~'#1',~
+ but~this~is~not~a~document~environment.
+ }
+% \end{macrocode}
+%
+% Intended more for information.
+% \begin{macrocode}
+\msg_new:nnn { xparse } { define-command }
+ {
+ Defining~document~command~#1~
+ with~arg.~spec.~'#2'~\msg_line_context:.
+ }
+\msg_new:nnn { xparse } { define-environment }
+ {
+ Defining~document~environment~'#1'~
+ with~arg.~spec.~'#2'~\msg_line_context:.
+ }
+\msg_new:nnn { xparse } { redefine-command }
+ {
+ Redefining~document~command~#1~
+ with~arg.~spec.~'#2'~\msg_line_context:.
+ }
+\msg_new:nnn { xparse } { redefine-environment }
+ {
+ Redefining~document~environment~'#1'~
+ with~arg.~spec.~'#2'~\msg_line_context:.
+ }
+% \end{macrocode}
+%
+% \subsection{User functions}
+%
+% The user functions are more or less just the internal functions
+% renamed.
+%
+% \begin{macro}{\BooleanFalse}
+% \begin{macro}{\BooleanTrue}
+% Design-space names for the Boolean values.
+% \begin{macrocode}
+\cs_new_eq:NN \BooleanFalse \c_false_bool
+\cs_new_eq:NN \BooleanTrue \c_true_bool
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\DeclareDocumentCommand}
+% \begin{macro}{\NewDocumentCommand}
+% \begin{macro}{\RenewDocumentCommand}
+% \begin{macro}{\ProvideDocumentCommand}
+% The user macros are pretty simple wrappers around the internal ones.
+% \begin{macrocode}
+\cs_new_protected:Npn \DeclareDocumentCommand #1#2#3
+ { \xparse_declare_cmd:Nnn #1 {#2} {#3} }
+\cs_new_protected:Npn \NewDocumentCommand #1#2#3
+ {
+ \cs_if_exist:NTF #1
+ {
+ \msg_error:nnx { xparse } { command-already-defined }
+ { \token_to_str:N #1 }
+ }
+ { \xparse_declare_cmd:Nnn #1 {#2} {#3} }
+ }
+\cs_new_protected:Npn \RenewDocumentCommand #1#2#3
+ {
+ \cs_if_exist:NTF #1
+ { \xparse_declare_cmd_aux:Nnn #1 {#2} {#3} }
+ {
+ \msg_error:nnx { xparse } { command-not-yet-defined }
+ { \token_to_str:N #1 }
+ }
+ }
+\cs_new_protected:Npn \ProvideDocumentCommand #1#2#3
+ { \cs_if_exist:NF #1 { \xparse_declare_cmd:Nnn #1 {#2} {#3} } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\DeclareDocumentCommandImplementation}
+% \begin{macro}{\DeclareDocumentCommandInterface}
+% The separate implementation/interface system is again pretty simple
+% to create at the outer layer.
+% \begin{macrocode}
+\cs_new_protected:Npn \DeclareDocumentCommandImplementation #1#2#3
+ { \xparse_declare_cmd_implementation:nNn {#1} #2 {#3} }
+\cs_new_protected:Npn \DeclareDocumentCommandInterface #1#2#3
+ { \xparse_declare_cmd_interface:Nnn #1 {#2} {#3} }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\DeclareDocumentEnvironment}
+% \begin{macro}{\NewDocumentEnvironment}
+% \begin{macro}{\RenewDocumentEnvironment}
+% \begin{macro}{\ProvideDocumentEnvironment}
+% Very similar for environments.
+% \begin{macrocode}
+\cs_new_protected:Npn \DeclareDocumentEnvironment #1#2#3#4
+ { \xparse_declare_env:nnnn {#1} {#2} {#3} {#4} }
+\cs_new_protected:Npn \NewDocumentEnvironment #1#2#3#4
+ {
+ \cs_if_exist:cTF {#1}
+ { \msg_error:nnx { xparse } { environment-already-defined } {#1} }
+ { \xparse_declare_env:nnnn {#1} {#2} {#3} {#4} }
+}
+\cs_new_protected:Npn \RenewDocumentEnvironment #1#2#3#4
+ {
+ \cs_if_exist:cTF {#1}
+ { \xparse_declare_env:nnnn {#1} {#2} {#3} {#4} }
+ { \msg_error:nnx { xparse } { environment-not-yet-defined } {#1} }
+ }
+\cs_new_protected:Npn \ProvideDocumentEnvironment #1#2#3#4
+ { \cs_if_exist:cF { #1 } { \xparse_declare_env:nnnn {#1} {#2} {#3} {#4} } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\DeclareExpandableDocumentCommand}
+% The expandable version of the basic function is essentially the same.
+% \begin{macrocode}
+\cs_new_protected:Npn \DeclareExpandableDocumentCommand #1#2#3
+ { \xparse_exp_declare_cmd:Nnn #1 {#2} {#3} }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[TF]{\IfBoolean}
+% The logical \meta{true} and \meta{false} statements are just the
+% normal \cs{c_true_bool} and \cs{c_false_bool}, so testing for them is
+% done with the \cs{bool_if:NTF} functions from \textsf{l3prg}.
+% \begin{macrocode}
+\cs_new_eq:NN \IfBooleanTF \bool_if:NTF
+\cs_new_eq:NN \IfBooleanT \bool_if:NT
+\cs_new_eq:NN \IfBooleanF \bool_if:NF
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[TF]{\IfNoValue}
+% Simple re-naming.
+% \begin{macrocode}
+\cs_new_eq:NN \IfNoValueF \xparse_if_no_value:nF
+\cs_new_eq:NN \IfNoValueT \xparse_if_no_value:nT
+\cs_new_eq:NN \IfNoValueTF \xparse_if_no_value:nTF
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}[TF]{\IfValue}
+% Inverted logic.
+% \begin{macrocode}
+\cs_set:Npn \IfValueF { \xparse_if_no_value:nT }
+\cs_set:Npn \IfValueT { \xparse_if_no_value:nF }
+\cs_set:Npn \IfValueTF #1#2#3 { \xparse_if_no_value:nTF {#1} {#3} {#2} }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}{\NoValue}
+% The marker for no value being give: this can be typeset safely.
+% This is coded by hand as making it \cs{protected} ensures that it
+% will not turn into anything else by accident.
+% \begin{macrocode}
+\cs_new_protected:Npn \NoValue { -NoValue- }
+% \end{macrocode}
+%\end{variable}
+%
+% \begin{macro}{\ProcessedArgument}
+% Processed arguments are returned using this name, which is reserved
+% here although the definition will change.
+% \begin{macrocode}
+\tl_new:N \ProcessedArgument
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\ReverseBoolean}
+% A processor to reverse the logic for token detection.
+% \begin{macrocode}
+\cs_new_eq:NN \ReverseBoolean \xparse_bool_reverse:N
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SplitArgument}
+% \begin{macro}{\SplitList}
+% Another simple copy.
+% \begin{macrocode}
+\cs_new_eq:NN \SplitArgument \xparse_split_argument:nnn
+\cs_new_eq:NN \SplitList \xparse_split_list:nn
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\GetDocumentCommandArgSpec}
+% \begin{macro}{\GetDocumentEnvironmentArgSpec}
+% \begin{macro}{\ShowDocumentCommandArgSpec}
+% \begin{macro}{\ShowDocumentEnvironmentArgSpec}
+% More simple mappings.
+% \begin{macrocode}
+\cs_new_eq:NN \GetDocumentCommandArgSpec \xparse_get_arg_spec:N
+\cs_new_eq:NN \GetDocumentEnvironmmentArgSpec \xparse_get_arg_spec:n
+\cs_new_eq:NN \ShowDocumentCommandArgSpec \xparse_show_arg_spec:N
+\cs_new_eq:NN \ShowDocumentEnvironmentArgSpec \xparse_show_arg_spec:n
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Package options}
+%
+% A faked key--value option to keep the log clean. Not yet perfect, but
+% better than nothing.
+% \begin{macrocode}
+\DeclareOption { log-declarations = true } { }
+\DeclareOption { log-declarations = false }
+ {
+ \msg_redirect_module:nnn { xparse } { info } { none }
+ \msg_redirect_module:nnn { xparse } { warning } { none }
+ }
+\DeclareOption { log-declarations } { }
+\ProcessOptions \scan_stop:
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/Master/texmf-dist/source/latex/l3packages/xparse/xparse.ins b/Master/texmf-dist/source/latex/l3packages/xparse/xparse.ins
new file mode 100644
index 00000000000..995ddbb8ff0
--- /dev/null
+++ b/Master/texmf-dist/source/latex/l3packages/xparse/xparse.ins
@@ -0,0 +1,40 @@
+\iffalse meta-comment
+
+File xparse.ins Copyright (C) 2000-2011 The LaTeX3 Project
+
+It may be distributed and/or modified under the conditions of the
+LaTeX Project Public License (LPPL), either version 1.3c of this
+license or (at your option) any later version. The latest version
+of this license is in the file
+
+ http://www.latex-project.org/lppl.txt
+
+This file is part of the "l3packages 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.
+
+\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
+
+\keepsilent
+
+\generate{\file{xparse.sty} {\from{xparse.dtx} {package}}}
+
+\endbatchfile