summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/xbase/xparse.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/source/latex/xbase/xparse.dtx')
-rw-r--r--Master/texmf-dist/source/latex/xbase/xparse.dtx2167
1 files changed, 2167 insertions, 0 deletions
diff --git a/Master/texmf-dist/source/latex/xbase/xparse.dtx b/Master/texmf-dist/source/latex/xbase/xparse.dtx
new file mode 100644
index 00000000000..90346556975
--- /dev/null
+++ b/Master/texmf-dist/source/latex/xbase/xparse.dtx
@@ -0,0 +1,2167 @@
+% \iffalse
+%% File: xparse.dtx (C) Copyright 1999 Frank Mittelbach, Chris Rowley, David Carlisle
+%% (C) Copyright 2004-2006 Frank Mittelbach, LaTeX3 Project
+%%
+%% It may be distributed and/or modified under the conditions of the
+%% LaTeX Project Public License (LPPL), either version 1.3c of this
+%% 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 ``xbase bundle'' (The Work in LPPL)
+%% and all files in that bundle must be distributed together.
+%%
+%% The released version of this bundle is available from CTAN.
+%%
+%% -----------------------------------------------------------------------
+%%
+%% The development version of the bundle can be found at
+%%
+%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/
+%%
+%% for those people who are interested.
+%%
+%%%%%%%%%%%
+%% NOTE: %%
+%%%%%%%%%%%
+%%
+%% Snapshots taken from the repository represent work in progress and may
+%% not work or may contain conflicting material! We therefore ask
+%% people _not_ to put them into distributions, archives, etc. without
+%% prior consultation with the LaTeX Project Team.
+%%
+%% -----------------------------------------------------------------------
+%%
+%<package>\RequirePackage{l3names}
+%<*dtx>
+%\fi
+\def\GetIdInfo$Id: #1.dtx #2 #3-#4-#5 #6 #7$#8{%
+ \def\fileversion{#2}%
+ \def\filedate{#3/#4/#5}%
+ \ProvidesFile{#1.dtx}[#3/#4/#5 v#2 #8]%
+}
+%\iffalse
+%</dtx>
+%\fi
+\GetIdInfo$Id: xparse.dtx 574 2006-08-21 23:30:10Z morten $
+ {generic document command parser}
+% \iffalse
+%<*driver>
+ \documentclass{ltxdoc}
+ \usepackage[T1]{fontenc}
+ \usepackage{textcomp}
+ \makeatletter
+ \providecommand*\eTeX{%
+ \if b\expandafter\@car\f@series\@nil\boldmath\fi
+ $\m@th\varepsilon$-\TeX}
+ \makeatother
+% \usepackage{ldcdoc}
+ \begin{document}
+ \catcode`\_=11
+ \catcode`\:=11
+ \DocInput{xparse.dtx}
+ \end{document}
+%</driver>
+% \fi
+%
+% \CheckSum{621}
+%
+%
+% \title{The \textsf{xparse} package\thanks{This file
+% has version number \fileversion, last
+% revised \filedate.}}
+% \author{FMi, CAR, DPC, MH}
+% \date{\copyright~\filedate}
+% \maketitle
+%
+% \begin{abstract}
+% The interfaces described in this document are not meant to be final
+% but only as a basis for discussion. Building productive applications
+% using the current code is discouraged.
+% \end{abstract}
+%
+% \section{Interface}
+%
+% This package implements high-level interface commands for class file
+% writers which allows the separation of formatting commands
+% (typically instances of so-called `templates') and their arguments
+% from the signature of document-level commands.
+%
+% This works by declaration commands that provide a general
+% specification method for the typical \LaTeX{} syntax, e.g.,
+% star-form, optional arguments, and mandatory arguments. A command
+% (or environment) declared in this way parses the input according to
+% its spec and presents its findings in a normalized way for further
+% processing.
+%
+% \subsection{Argument spec}
+%
+%
+% An argument specification is a list of letters each representing a
+% type of argument, i.e., |m| is a mandatory argument (surrounded by
+% braces), |o| an optional argument (surrounded by brackets if
+% present), and |s| represents a star (which might be present or not).
+% Thus the argument spec for headings as implemented by
+% |\@startsection| in standard \LaTeX{} would be represented by the
+% three letters |som|. Other argument types are available and can be
+% added at will. For a complete list of built-in argument types see
+% the next section.
+%
+% There is one important argument specifier worth taking note of. The
+% |P| does not behave as a normal argument specifier but allows the
+% next argument to take an argument containing the |\par| token which
+% is not allowed by default.
+%
+%
+% \subsection{Parsing results}
+%
+% To normalise the result of parsing the input according to an
+% argument specification it is important to uniquely identify all
+% arguments found. For this reason each parsing operation initiated by
+% one of the argument spec letters will result in an identifiable
+% output as follows:
+% \begin{description}
+% \item[m] will return the parsed argument surrounded by a brace
+% pair, i.e., will normally be the identity;
+% \item[o] will return the parsed argument surrounded by a brace pair
+% if present. Otherwise it will return the token |\NoValue|;
+% \item[O\{default\}] will return the parsed argument surrounded by a
+% brace pair if present. Otherwise it will return the |{default}|
+% as specified above.
+% \item[S\{\meta{symbol}\}] will return either the token |\c_true| or
+% |\c_false| depending on whether or not the next token is
+% \meta{symbol}.
+% \item[s] will return either the token |\c_true| or |\c_false|
+% depending on whether or not a star was parsed. This is just a
+% shorthand for |S{*}|.
+% \item[c] will parse the syntax |(|\meta{x}|,|\meta{y}|)|, i.e., a
+% coordinate pair and will return |{{|\meta{x}|}{|\meta{y}|}}| as
+% the result. If no open parentheses is scanned an error is
+% signalled.
+% \item[C\{\{x-default\}\{y-default\}\}] behaves like |c|, i.e.,
+% parses a coordinate pair if present. If the coordinate pair is
+% missing it returns the default values instead.
+% \item[l] Reads everything up to the first left brace as the
+% argument.
+% \end{description}
+% For example, given the spec |soomO{default}| the input
+% |*[Foo]{Bar}| would be parsed as
+% |\c_true{Foo}\NoValue{Bar}{default}|. In other words there will be
+% always exactly the same number of brace groups or tokens as the
+% number of letters in the argument spec.
+%
+% There are a few exceptions to this rule as the r\^ole of following
+% letters is to affect how the next argument is read.
+% \begin{description}
+% \item[>] takes a mandatory argument like |{P}| or |{PW}| and
+% inserts these extra argument specifiers so that they act on the
+% next regular argument type. See below.
+% \item[P] will cause the next argument to allow |\par| in it's
+% argument. Thus the specification |m>{P}mm| will cause the command to
+% read three mandatory arguments but only the second can contain the
+% |\par| token.
+% \item[W] will cause the next argument to \emph{not} ignore a space
+% when trying to scan ahead for a special symbol such as a |*| or an
+% optional argument. This is mostly useful when the last argument(s)
+% of a document command are optional (see example later on).
+% \end{description}
+%
+%
+% \subsection{Applying the parsing results}
+%
+% Since the result of the parsing is a well defined number of tokens or
+% brace groups it is easy to pass them on in any order to any
+% processing function. To this end the tokens or brace groups are
+% associated with the standard argument specifiers in \TeX{} macros,
+% i.e., |#1|, |#2|, and so forth. This limits the argument
+% specification to a maximum number of 9 letters, but for practical
+% applications this should be sufficient.
+%
+% \subsection{The class designer interface}
+%
+% This package provides commands for declaring commands
+% and environments to be used within the document body.
+%
+% \DescribeMacro\DeclareDocumentCommand
+% The |\DeclareDocumentCommand| declaration takes three arguments. The
+% first argument is the name of the command to be declared, the second
+% is the argument specification in the syntax described above, and the
+% third is the action to be carried out once the arguments are
+% parsed. Within the third argument |#1|, |#2|, etc.\ denote the
+% result of the parsing, e.g.,
+% \begin{verbatim}
+% \DeclareDocumentCommand{\chapter}{som}
+% { \IfBooleanTF {#1}
+% { \typesetnormalchapter {#2}{#3} }
+% { \typesetstarchapter {#3} }
+% }
+% \end{verbatim}
+% would be a way to define a |\chapter| command which would
+% essentially behave like the current \LaTeX{} command (except that it
+% would accept an optional argument even when a |*| was parsed). The
+% |\typesetnormalchapter| could test its first argument for being
+% |\NoValue| to see if an optional argument was present.
+%
+% Of course something like the |\IfNoValueTF| test could also be
+% placed inside a function that would process all three arguments, thus
+% using the templates and their instances as provided by the
+% \texttt{template} package such a declaration would probably look
+% more like the following example:
+% \begin{verbatim}
+% \DeclareDocumentCommand{\chapter}{som}
+% { \UseInstance {head} {A-head-main} {#1} {#2} {#3} }
+% \end{verbatim}
+%
+% Using the |\DeclareDocumentCommand| interface it is easy to modify
+% the document-level syntax while still applying the same
+% layout-generating functions, e.g., a class that would not support
+% optional arguments or star forms for the heading commands could
+% define |\chapter| like this:
+% \begin{verbatim}
+% \DeclareDocumentCommand{\chapter}{m}
+% { \UseInstance {head} {A-head-main} \BooleanFalse \NoValue {#1} }
+% \end{verbatim}
+% while a class that would allow for an additional optional argument
+% (for whatever reason) could define it like that:
+% \begin{verbatim}
+% \DeclareDocumentCommand{\chapter}{somo}
+% { \doSomethingWithTheExtraOptionalArg {#4}
+% \UseInstance {head} {A-head-main} {#1} {#2} {#3} }
+% \end{verbatim}
+% \DescribeMacro\ReDeclareDocumentCommand
+% \DescribeMacro\ProvideDocumentCommand
+% The commands |\ReDeclareDocumentCommand| and
+% |\ProvideDocumentCommand| work just like |\DeclareDocumentCommand|
+% with the exception that |\Re..| can only redefine an existing
+% command and |\Provide...| will only define the command if it is
+% already free.
+%
+%
+% \DescribeMacro\DeclareDocumentEnvironment
+% \DescribeMacro\ReDeclareDocumentEnvironment
+% \DescribeMacro\ProvideDocumentEnvironment The
+% |\DeclareDocumentEnvironment| declaration is similar to
+% |\DeclareDocumentCommand| except that it takes four arguments: the
+% first being the environment name (without a backslash), the second
+% again the argument-spec, and the third and forth are the actions
+% taken at start aqnd end of the environment. The parsed arguments are
+% available to both the start and the finish as |#1|, |#2|, etc.
+%
+% All commands and environments defined with the above commands are
+% automatically robust.
+%
+%
+%
+% \subsection{A different interface (for class design?)}
+%
+% Combining signature and top-level definition of a command |\foo| as
+% in
+% \begin{verbatim}
+% \DeclareDocumentCommand \foo { m c m }
+% { \typeout{1:#1}
+% \typeout{2:#2}
+% \typeout{3:#3}
+% }
+% \end{verbatim}
+% is fine in certain cases, e.g., if the user wants to declare a few
+% commands this way in the preamble of a document. However in a class
+% file it probably better to completely separate signature (i.e.,
+% argument \#1 and \#2) from top-level implementation (i.e., argument
+% \#3).
+%
+%
+% \begin{verbatim}
+% \DeclareDocumentCommandInterface \foo {bar} { m c m }
+% \end{verbatim}
+% The above now declare only the signature of the command |\foo| and
+% states that the implementation is to be found under the label |bar|.
+%
+% A bunch of such statements would then for the first time clearly
+% define a document class (i.e., what a document class instance needs
+% to define to be compliant).
+%
+% An instance would then consist of a lot of declarations of the type
+% \begin{verbatim}
+% \DeclareDocumentCommandImplementation {bar} {3}
+% { \typeout{1:#1}
+% \typeout{2:#2}
+% \typeout{3:#3}
+% }
+% \end{verbatim}
+% i.e., defining how to format things being referenced as part of the
+% signature.
+%
+% The functions |\DeclareDocumentCommandInterface| and
+% |\DeclareDocumentCommandImplementation| are implemented for now but
+% it is not sure if they will stay. If a document command is defined
+% with |\DeclareDocumentCommandInterface| but there is no matching
+% interface it prints the label in quotes as |``bar''|.
+%
+%
+%
+%
+% \subsection{Checking for a value or boolean}
+%
+% It would make perfect sense to make |\NoValue| a \LaTeX3 quark but
+% as there is a real danger of it getting executed by accident it is
+% best not to as it would result in an infinite loop.
+%
+% \DescribeMacro\NoValue
+% For this reason |\NoValue| is defined to expand to the string
+% |-NoValue-| which would get typeset if ever executed thus clearly
+% indicating the type of error the writer made.
+%
+% However this makes testing for this token slightly complicated as in
+% that case the test
+% \begin{verbatim}
+% \tlp_set:Nn \l_seen_tlp {#1}
+% \tlp_set:Nn \l_hidden_novalue_tlp {\NoValue}
+% \tlp_if_eq:NNTF \l_seen_tlp \l_hidden_novalue_tlp
+% \end{verbatim}
+% will be true if |#1| was |\NoValue| but false if |#1| itself
+% contains a macro which contains |\NoValue|; a case that happens
+% unfortunately very often in practice. Using an unguarded |x| type
+% expansion to define |\l_seen_tlp| is out of the question as |#1| is
+% typically either |\NoValue| or arbitrary user input for which we
+% can't properly guard it unless we are sure people only use robust
+% commands. When running a pure \LaTeX3 format where all document
+% commands are robust this is perhaps something to be looked at again
+% but when running on top of \LaTeXe{} we have to be careful.
+%
+% Therefore we use a somewhat different procedure here, which goes
+% like this:
+% \begin{enumerate}
+% \item Store |#1| in a temporary variable and check if it equals a
+% variable containing |\NoValue|. If true, execute the \meta{true}
+% code, otherwise go to~2.
+% \item Peek at the first token in |#1|. If this is a macro taking no
+% arguments expand |#1| once and go to~1. Otherwise execute the
+% \meta{false} code.
+% \end{enumerate}
+% The reason for the careful peeking ahead is that |#1| may very well
+% be a macro taking arguments and it is not certain that these
+% arguments are present! Hence this could lead to the well-known
+% \begin{verbatim}
+% Argument of \XXX has an extra }
+% \end{verbatim}
+% and we wouldn't want that\dots{} Goes without saying that this
+% procedure is quite tedious but usually it will exit after the first
+% time |#1| has been inspected. One additional test could be added,
+% namely that |#1| should also contain exactly one token but I don't
+% think that is going to matter much.
+%
+% \DescribeMacro\IfNoValueTF
+% \DescribeMacro\IfNoValueT
+% \DescribeMacro\IfNoValueF
+% \DescribeMacro\IfValueTF
+% \DescribeMacro\IfValueT
+% \DescribeMacro\IfValueF
+% These macros are used for checking if an optional argument was
+% present as in the example below.
+% \begin{verbatim}
+% \DeclareDocumentCommand\testcmd{om}{
+% \IfNoValueTF{#1}{``#2''}{#1,#2}
+% }
+% \end{verbatim}
+%
+%
+%
+% \DescribeMacro\IfBooleanTF
+% \DescribeMacro\IfBooleanT
+% \DescribeMacro\IfBooleanF
+% As mentioned earlier, the parsing result for a symbol argument like
+% |s| or |S{+}| is represented as the one of the tokens |\c_true| or
+% |\c_false| respectively. To test for these values the macro
+% |\IfBooleanTF| can be used. It expects as its first argument either
+% |\c_true| or |\c_false| and executes its second or third argument
+% depending on this value. |\IfBooleanT| and |\IfBooleanF| are
+% obvious shortcuts.
+%
+% At one point in time I thought that one can represent everything
+% using |\NoValue|, e.g., for the star case either return |*| or
+% |\NoValue|. However, this slows down processing of commands like
+% |\\*| considerably since they would then have to use a slower
+% internal test instead of a fast two-way switch.
+%
+%
+% \subsection{New argument types and shorthands}
+%
+% New argument types can be added at in a fairly straight forward
+% manner with the command
+% |\DeclareArgumentType|\DescribeMacro\DeclareArgumentType. This
+% command takes seven arguments: |#1| is a symbol denoting the
+% argument type, |#2| is the token the scanner should look for, |#3|
+% is one of the words |meaning|, |charcode| or |catcode| which is
+% handed down to the underlying |\peek_meaning:NTF| or
+% |\peek_charcode:NTF| etc. functions. For instance you can use the
+% |charcode| version if you want to pick up a literal |*| and not
+% just something that has the same \emph{meaning} as a regular
+% |*|. |#4| is for executing a special action (like an error message)
+% if no argument is found, |#5| is the default value in case of a
+% missing argument, |#6| is what the scanner will encounter, and
+% finally |#7| is what the scanner grabs from the argument type. This
+% is perhaps clearer with an example\dots{} This is how the |o| type
+% is implemented:
+% \begin{verbatim}
+% \DeclareArgumentType o [ {meaning} {} {\NoValue} {#1[#2]} {#2}
+% \end{verbatim}
+% In a similar fashion a |b| type expecting its argument inside |<|
+% and |>| would be defined as
+% \begin{verbatim}
+% \DeclareArgumentType b < {meaning} {} {\NoValue} {#1<#2>} {#2}
+% \end{verbatim}
+%
+% \DescribeMacro\DeclareArgumentTypeWithDefault
+% |\DeclareArgumentTypeWithDefault| is even simpler as this type
+% expects the default value to be input at the time of argument
+% specification. Thus arguments |#3| and |#4| from above are
+% unnecessary and are simply absent. Thus the |O| type is
+% implemented\footnote{I would say it is at best wishful thinking
+% that the interface could be something like
+% \texttt{\cs{DeclareArgumentTypeWithDefault}
+% C\{2\}\{meaning\}\{(\#1,\#2)\}\{\{\#1\}\{\#2\}\}} as it would
+% be quite troublesome implementation-wise and the current syntax
+% isn't that difficult to use.} as
+% \begin{verbatim}
+% \DeclareArgumentTypeWithDefault O [ {meaning}{#1[#2]} {#2}
+% \end{verbatim}
+% and again a similar |B| type could be implemented as
+% \begin{verbatim}
+% \DeclareArgumentTypeWithDefault B < {meaning}{#1<#2>} {#2}
+% \end{verbatim}
+%
+%
+% There is also a possibility to define a shorthand for a specific
+% sequence of arguments with the command
+% \DescribeMacro\DeclareArgumentTypeShorthand
+% |\DeclareArgumentTypeShorthand|. As an example the |s| argument
+% type is just a different way of saying |S{*}| so it's simply
+% implemented as
+% \begin{verbatim}
+% \DeclareArgumentTypeShorthand s {S{*}}
+% \end{verbatim}
+% Similarly one could add a shorthand |M| for inserting five
+% mandatory arguments where the latter is allowed to take |\par| in
+% its argument:
+% \begin{verbatim}
+% \DeclareArgumentTypeShorthand M {mmmm>{P}m}
+% \end{verbatim}
+%
+% Finally there is also the command
+% \DescribeMacro\DeclareSymbolArgument|\DeclareSymbolArgument| which
+% defines the low level interface to looking ahead for specific
+% symbols and removing them. For instance the |S| type argument is
+% declared as
+% \begin{verbatim}
+% \DeclareSymbolArgument S{meaning}
+% \end{verbatim}
+% So symbols picked up by this type will compare the meaning of the
+% tokens. One could do a
+% \begin{verbatim}
+% \DeclareSymbolArgument A{charcode}
+% \end{verbatim}
+% and then the |A| type would compare character codes instead. For
+% instance a command which expects a |+| symbol would return
+% \meta{true} if a |+| of any catcode is detected, not just catcode
+% 12 as is usual.
+%
+% \subsection{Some comments on the need for the \texttt{O} specifier}
+%
+% With |\newcommand| there is the possibility of specifying a default
+% for an optional argument which is stored away in a more or less
+% efficient manner. For example below is the old definition of
+% |\linebreak| as can be found in the \LaTeX2e kernel:
+%\begin{verbatim}
+%\def\linebreak{\@testopt{\@no@lnbk-}4}
+%\def\@no@lnbk #1[#2]{%
+% \ifvmode
+% \@nolnerr
+% \else
+% \@tempskipa\lastskip
+% \unskip
+% \penalty #1\@getpen{#2}%
+% \ifdim\@tempskipa>\z@
+% \hskip\@tempskipa
+% \ignorespaces
+% \fi
+% \fi}
+%\end{verbatim}
+% Ignoring for the moment that the above is slightly optimised an
+% expansion of this code under |\tracingall| will result in about 90
+% lines of tracing output. If we reimplement this using
+% |\DeclarDocumentCommand\linebreak{o}| we have to use |\IfNoValueTF|
+% to find out if an argument was present which (because of the careful
+% expansion we do internally) results in about twice as much of
+% tracing lines. In contrast using |O{4}| as below we end up with 110
+% lines, which seems roughly the price we have to pay for the extra
+% generality available (though this could perhaps even be reduced by a
+% better implementation of the parsing machine as originally done by
+% David, before i talked him into adding support for arguments in the
+% end code of an environment).\footnote{These comments were made
+% before the extensive changes in expl3 and xparse in 2005.}
+%
+%\begin{verbatim}
+%\DeclareDocumentCommand\linebreak { O{4} }
+% {
+% \ifvmode
+% \@nolnerr
+% \else
+% \@tempskipa\lastskip
+% \unskip
+% % \IfNoValueTF{#1}
+% % {\break}
+% % {\penalty -\@getpen{#1}}
+% \penalty -\@getpen{#1}
+% \ifdim\@tempskipa>\z@
+% \hskip\@tempskipa
+% \ignorespaces
+% \fi
+% \fi
+% }
+%\end{verbatim}
+%
+%
+% \subsection{A somewhat complicated example}
+%
+% This example reimplements the |\makebox| and |\framebox| interface
+% of \LaTeX{} both of which are unfortunately quite overloaded
+% syntactically. For this reason the example isn't meant to show good
+% coding practice but to show the power of the interface even though
+% applied in a somewhat bad way.
+%
+% |\makebox| and |\framebox| support the following different document
+% syntax forms:
+% \begin{itemize}
+% \item
+% |\makebox{A}|: only a single mandatory argument.
+%
+% \item
+% |\makebox[20pt]{B}|: one optional argument specify the box width.
+%
+%
+% \item
+% |\makebox[30pt][r]{C}|: two optional arguments the second specifying
+% the text position within the box being made (l,c,r being allowed
+% with c being the default).
+%
+% \item
+% |\makebox(20,30){D}|: within picture mode the width is specified not
+% as an optional argument in brackets but as a coordinate pair.
+%
+% \item
+% |\makebox(0,0)[lt]{E}|: in that case an optional argument following
+% coordinate pair denotes the placement within the box which can have
+% different values compared to case C above.
+% \end{itemize}
+%
+% To cater for this overloaded structure we can define |\makebox| to
+% be something like the following:
+%\begin{verbatim}
+%\DeclareDocumentCommand \makebox { C{\NoValue} o O{c} m}
+% { \IfNoValueTF{#1}
+% { \ltx@maketextbox{#2}{#3}{#4} }
+% { \ltx@makepicbox #1 {#2}{#4} } }
+%\end{verbatim}
+% In other words: if we do not see a coordinate pair first (i.e.,
+% first argument is |\NoValue| then we expect up to two optional
+% arguments (the width of the box or |\NoValue| if not given and the
+% placement specifier with a default of |c| if not given) and one
+% mandatory one which is the text. In that case we pass argument 2 to
+% 4 to an internal function |\ltx@maketextbox| which builds the text
+% box.
+%
+% Otherwise, if the first argument is a coordinate pair we parse an
+% optional argument denoting the placement specifier. Since
+% \texttt{xparse} doesn't support variant syntax we actually parse for
+% another optional argument (which has no meaning in that case and is
+% in fact ignored if present) followed by a mandatory one containing
+% the box text. In that case we pass the coordinate pair (|#1|), the
+% specifier (|#2|), and the text (|#4|) to the function
+% |\ltx@makepicbox| which builds the picture box. Note the special
+% handling of the coordinatesD: which are passed without surrounding
+% braces to |\ltx@makepicbox|: since the coordinate argument looks
+% like |{x-val}{y-val}| the receiving function |\ltx@makepicbox| gets
+% the |x-val| as argument one and the |y-val| as argument two.
+%
+% A definition for |\framebox| would look more or less identical
+% except that we would need to pass the arguments to slightly
+% different internal functions. The alternative is to give the
+% internal functions an extra argument that controls whether or not a
+% frame is bying built.
+%
+% \begin{macro}{\ltx@makepicbox}
+% So here is a possible implementation of |\ltx@makepicbox| that
+% builds a picture box with or without frame. It takes the following
+% mandatory arguments:
+% \begin{enumerate}
+% \item x-part of coordinate
+% \item y-part of coordinate
+% \item placement specifier, e.g., |lt| or |\NoValue|
+% \item text of box
+% \item the token |\frame| (if a frame should surround the box) or the
+% token |\@firstofone| --- not pretty i agree
+% \end{enumerate}
+%\begin{verbatim}
+%\def\ltx@makepicbox#1#2#3#4#5
+% {
+% #5{
+% \vbox to#2\unitlength
+% {\let\mb@b\vss \let\mb@l\hss\let\mb@r\hss
+% \let\mb@t\vss
+% \IfNoValueF{#3}
+% {
+% \@tfor\reserved@a :=#3\do{
+% \if s\reserved@a
+% \let\mb@l\relax\let\mb@r\relax
+% \else
+% \expandafter\let\csname mb@\reserved@a\endcsname\relax
+% \fi}%
+% }
+% \mb@t
+% \hb@xt@ #1\unitlength{\mb@l #4\mb@r}
+% \mb@b
+% \kern\z@}
+% }
+% }
+%\end{verbatim}
+% \end{macro}
+%
+%
+%
+% \begin{macro}{\ltx@maketextbox}
+% For the text case the internal function could take the following
+% mandatory arguments:
+% \begin{enumerate}
+% \item width of the box or |\NoValue| (denoting to build the box at
+% natural width)
+% \item placement specifier, e.g., |l|. (No test for |\NoValue| being undertaken)
+% \item text of box
+% \item the token |\fbox| (if a frame should surround the box) or the
+% token |\mbox|
+% \end{enumerate}
+% The actual code is taken straight from the current \LaTeX{} kernel
+% and looks kind of scary.
+%\begin{verbatim}
+%\def\ltx@maketextbox#1#2#3#4
+% {
+% \IfNoValueTF{#1}
+% {#4{#3}}
+% {
+% \leavevmode
+% \@begin@tempboxa\hbox{#3}
+% \setlength\@tempdima{#1}
+% \ifx#4\fbox
+% \setbox\@tempboxa\hb@xt@\@tempdima
+% {\kern\fboxsep\csname bm@#2\endcsname\kern\fboxsep}
+% \@frameb@x{\kern-\fboxrule}
+% \else
+% \hb@xt@\@tempdima{\csname bm@#2\endcsname}
+% \fi
+% \@end@tempboxa
+% }
+% }
+%\end{verbatim}
+% \end{macro}
+%
+% \begin{macro}{\makebox}
+% \begin{macro}{\framebox}
+% Given the above internal functions the declarations of |\makebox|
+% and |\framebox| would then look like this:
+%\begin{verbatim}
+%\DeclareDocumentCommand \makebox { C{\NoValue} o O{c} m}
+% { \IfNoValueTF{#1}
+% { \ltx@maketextbox{#2}{#3}{#4}\mbox }
+% { \ltx@makepicbox #1 {#2}{#4}\@firstofone } }
+%
+%\DeclareDocumentCommand \framebox { C{\NoValue} o O{c} m}
+% { \IfNoValueTF{#1}
+% { \ltx@maketextbox{#2}{#3}{#4}\fbox }
+% { \ltx@makepicbox #1 {#2}{#4}\frame } }
+%\end{verbatim}
+% \end{macro}
+% \end{macro}
+%
+%
+%
+% Here's another example which shows how one can use the |W| specifier.
+% The \textsf{amsmath} environments use their own definition of |\\|
+% which goes under the name |\math@cr|. As there is a good chance the
+% next line of math begins with either an asterisk or something in
+% square brackets this often leads to errors. The following example
+% definition works (I \emph{did} try it).
+% \begin{verbatim}
+% \CodeStart
+% \cs_gundefine:N \math@cr
+% \DeclareDocumentCommand\math@cr{>{W}s >{W}O{\z@}}{
+% \IfBooleanTF{#1}
+% { \global\@eqpen\@M }{
+% \global\@eqpen
+% \ifnum\dspbrk@lvl <\z@
+% \interdisplaylinepenalty
+% \else
+% -\@getpen\dspbrk@lvl
+% \fi
+% }
+% \math@cr@@@
+% \noalign{\vskip#2\relax}
+% }
+% \CodeStop
+% \end{verbatim}
+% Note that this definition automatically avoids problems within the
+% alignments even if it is called as |\\&|.
+%
+%
+%
+%
+% \subsection{Open issues}
+%
+% In this section unresolved issues or ideas to think about and
+% perhaps implement are collected. There is no particular order to
+% them.
+%
+% \begin{itemize}
+% \item
+% Support for parsing verbatim type of arguments was considered (and
+% actually implemented at one stage. E.g.,
+% |g{|\meta{prepare-parsing}|}| where |g| first run
+% \meta{prepare-parsing} (which might involve |catcode|
+% changes)\footnote{urg horror!}, then look at the next token: if
+% that would be a |{| it would scan a brace delimited argument
+% (reverting catcodes of |{| and |}| if needed) otherwise would scan
+% for an argument delimited by that token so that something like
+% |\verb+%\+| would scan |%\| as its argument assuming that the
+% \meta{prepare-parsing} turned |%| and |\| into non-letters.
+%
+% All kind of nasty problems lurking especially no proper error
+% checks possible and of course as we all know such commands would
+% then not work inside arguments of other commands. At least they
+% would have some restrictions.
+%
+% Also no way to make the parsing smart by not accepting newlines as
+% part of the code (|\verb| does this right now and this is really
+% helpful as it catches runaways nicely).
+%
+%
+% \item
+% \textsf{xparse} should probably go into the \LaTeX3 kernel in which
+% case it should also provide the definitions of |\begin| and |\end|
+% and this raises a few questions: Will environments be defined as
+% control sequences |\foo| and |\endfoo|? If they are do we then want
+% to include support for a separate command |\foo| and if so what
+% about using the environment forms in special scanner mechanisms
+% where we \emph{can't} use |\begin{foo}|? In those cases one could
+% use a special command like what the \textsf{fancyvrb} package
+% provides with the command |\VerbatimEnvironment| and all packages
+% that define such special arguments should then also make sure that
+% the |\foo| command issued on its own should cause an error.
+% Another solution would be to simply define environments as
+% |\beginfoo| and |\endfoo| and then let |\begin| check if it was
+% used to call an environment or a command. If the latter is the
+% case then insert grouping as that could be handled by |\beginfoo|
+% itself. When |\end| is reached check if |\endfoo| exists. If it
+% does then use that, otherwise we were probably using a normal
+% command which should just close the group.
+% \end{itemize}
+%
+%
+% \subsection{Rejected ideas---and why}
+%
+% Let's say the document command |\testmo| has signature |mo|. If we
+% call it as |\testmo{arg} [opt]| a following space will be obeyed.
+% However calling it with the mandatory argument only as in
+% |\testmo{arg}| will gobble a following space because the peek ahead
+% in the |o| type ignores spaces. We can record that a space has been
+% gobbled when peeking ahead and we can also put it back in if needed
+% but I have only ever seen one request for this and in that case the
+% better solution was to use a signature |mWo| so that no spaces are
+% allowed between the mandatory and the optional argument. One could
+% even argue that this is the most appropriate thing to do if the user
+% is really that sensitive to spaces! In any case it is not
+% implemented here as it creates an unnecessary overhead for something
+% that is never used and a simple solution exists.
+%
+% \subsection{Experimental features}
+%
+% Experimental features in an experimental packages\dots{} Needless to
+% say that you can't rely on them staying!
+%
+%
+% One new feature is what I decided to call ``pseudo
+% arguments''. Strictly speaking these aren't real arguments but
+% instead read by removing a begin group token and then using
+% |\tex_aftergroup:D| to regain control. The definition of |\footnote|
+% in plain \TeX\ uses this so that people can use
+% |\verb| and the like inside the footnotes. The command
+% |\DeclarePseudoArgument|\DescribeMacro{\DeclarePseudoArgument} takes
+% four arguments: |#1| is a name for the pseudo argument, |#2| is the
+% number of arguments it takes, |#3| is the action to be taken right
+% before the left brace is removed and |#4| is what to be done when
+% the right brace has been read and we regain control. Note that both
+% |#3| and |#4| may use arguments! Here is a silly example:
+% \begin{verbatim}
+% \DeclarePseudoArgument{boxtest}{1}
+% {Before:~`#1',\hbox_set_inline_begin:N \l_tmpa_box }
+% {\hbox_set_inline_end: \text_put_sp: the~ box:~
+% \hbox_unpack_and_clear:N\l_tmpa_box ,~
+% After:~`#1'}
+% \end{verbatim}
+% Now when you want to use it, you simply call it with the macro
+% |\UsePseudoArgument|\DescribeMacro{\UsePseudoArgument}, which as its
+% first argument takes a name and the remaining depend on how many
+% arguments the pseudo argument was defined to have. Hence we could
+% use our |boxtest| definition like this:
+% \begin{verbatim}
+% \DeclareDocumentCommand\sillyboxtest{m}{
+% Testing~#1:~\UsePseudoArgument{boxtest}{#1}
+% }
+% \end{verbatim}
+% Then calling |\sillyboxtest{AB}{a\verb*+% $%&\+b}| produces
+% \begin{quote}
+% Testing AB: Before: `AB', the box:
+% a\verb*+% $%&\+b, After: `AB'
+% \end{quote}
+% |\UsePseudoArgument| should always come last in the document
+% command definition.
+%
+% \StopEventually{}
+%
+% \section{Implementation}
+%
+% Versions prior to and including 1.19 contained several different
+% implementations. These are gone now but can be looked at by
+% getting an older version of the package from the CVS repository.
+%
+% First the required packages.
+% \begin{macrocode}
+%<*package>
+\RequirePackage{l3tlp,l3num,l3toks,l3prg,l3int,l3seq,l3token}
+% \end{macrocode}
+%
+%
+%
+% \subsection{Error and warning messages}
+%
+% Here we define the error message we're going to use in this package.
+%
+% \begin{macro}{\xparse_already_defined_error_msg:N}
+% \begin{macro}{\xparse_not_yet_defined_error_msg:N}
+% \begin{macro}{\xparse_begins_with_end_error_msg:N}
+% \begin{macro}{\xparse_unknown_arg_type_error_msg:N}
+% \begin{macro}{\xparse_number_of_arguments_error_msg:Nn}
+% \begin{macro}{\xparse_no_command_implementation_warning:n}
+% The names should give the function's purpose away.
+% \begin{macrocode}
+\def_new:NNn \xparse_already_defined_error_msg:N 1 {
+ \xparse_error:x {
+ Command~name~`\token_to_string:N #1'~ already~defined!
+ }
+}
+\def_new:NNn \xparse_not_yet_defined_error_msg:N 1 {
+ \xparse_error:x {
+ Command~`\token_to_string:N #1'~ not~ yet~defined!
+ }
+}
+\def_new:NNn \xparse_begins_with_end_error_msg:N 1 {
+ \xparse_error:x {
+ Command~`\token_to_string:N #1'~begins~with~
+ `\token_to_string:N \end'!
+ }
+}
+% \end{macrocode}
+% This one is for when we've encountered an unknown argument type in
+% the argument specification. We can try to recover by putting in an
+% |m| type instead and hope for the best.
+% \begin{macrocode}
+\def_new:NNn \xparse_unknown_arg_type_error_msg:N 1{
+ \xparse_error:x {
+ Unknown~ argument~ type~ `#1'~
+ I'll~ substitute~ it~ with~ `m'~ for~ now.~ Fingers~ crossed...
+ }
+}
+% \end{macrocode}
+% A message for people using the wrong number of arguments.
+% \begin{macrocode}
+\def_new:NNn \xparse_no_command_implementation_warning:n 1 {
+ \xparse_warning:x {No~ implementation~ for~ `#1'~ defined}
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\xparse_error:x}
+% \begin{macro}{\xparse_warning:x}
+% Here's how we produce the error messages and warnings currently.
+% This awaits a proper error message module!
+% \begin{macrocode}
+\def_new:NNn \xparse_error:x 1{\tex_errmessage:D {xparse~error:~#1}}
+\def_new:NNn \xparse_warning:x 1{\io_put_term:x{xparse~warning:~#1}}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+%
+%
+% \subsection{Checking for valid command names}
+%
+%
+% \begin{macro}{\xparse_if_definable:NT}
+% \begin{macro}{\xparse_if_definable:cT}
+% A definable command is either |\c_undefined| or |\scan_stop:| and
+% furthermore we won't allow it to start with |\end|.
+% If the command is definable we do what was asked for otherwise
+% we give an appropriate error message.
+% \begin{macrocode}
+\def_new:NNn \xparse_if_definable:NTF 1 {
+% \end{macrocode}
+% First check if the control sequence is free.
+% \begin{macrocode}
+ \cs_free:NTF #1
+% \end{macrocode}
+% If free check if it begins with |\end|.
+% \begin{macrocode}
+ {
+ \xparse_begins_with_end:NTF #1
+ { \xparse_begins_with_end_error_msg:N #1 \use_arg_ii:nn }
+ \use_arg_i:nn
+ }
+% \end{macrocode}
+% If not free give an error message.
+% \begin{macrocode}
+ { \xparse_already_defined_error_msg:N #1 \use_arg_ii:nn }
+}
+\def_new:NNn \xparse_if_definable:cTF 0 {
+ \exp_args:Nc \xparse_if_definable:NTF
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\xparse_if_redefinable:NTF}
+% \begin{macro}{\xparse_if_redefinable:cTF}
+% A re-definable command is almost the same as above but here we
+% demand that it already exists.
+% \begin{macrocode}
+\def_new:NNn \xparse_if_redefinable:NTF 1 {
+ \cs_free:NTF #1
+ { \xparse_not_yet_defined_error_msg:N #1 \use_arg_ii:nn }
+ {
+ \xparse_begins_with_end:NTF #1
+ { \xparse_begins_with_end_error_msg:N #1 \use_arg_ii:nn }
+ \use_arg_i:nn
+ }
+}
+\def_new:NNn \xparse_if_redefinable:cTF 0 {
+ \exp_args:Nc \xparse_if_redefinable:NTF
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+%
+% \begin{macro}{\xparse_begins_with_end:NTF}
+% \begin{macro}{\xparse_begins_with_end_aux:N}
+% Finally we need the magic function for checking if the control
+% sequence begins with |\end|.
+% We wish to determine if the control sequence in question begins with
+% |\end| which is forbidden. The end goal is to get a control sequence
+% consisting of the first three letters to test against |\end| with
+% |\cs_if_eq_name_p:NN|. The function |\cs_to_str:N| will remove the |\|
+% from a command name and return the rest of the characters with
+% category code 12. Thus using an |f| type expansion to get the first
+% three characters is perfectly safe as it'll stop right there. Then
+% we turn these three letters into a control sequence with a simple
+% expansion which is then tested with |\xparse_begins_with_end_aux:N|.
+% \begin{macrocode}
+\def_new:NNn \xparse_begins_with_end:NTF 1 {
+% \end{macrocode}
+% We do it all in a group as there is no need to fill up the hash
+% table with weird three letter control sequences.
+% \begin{macrocode}
+ \group_begin:
+ \exp_args:Nc \xparse_begins_with_end_aux:N {
+ \tlist_head_iii:f { \cs_to_str:N #1 ??}
+ }
+}
+% \end{macrocode}
+% After the above expansion tricks we now have a real control sequence
+% to test against |\end|. We end the group again.
+% \begin{macrocode}
+\def_new:NNn \xparse_begins_with_end_aux:N 1 {
+ \if:w \cs_if_eq_name_p:NN #1 \end
+ \group_end:
+ \exp_after:NN \use_arg_i:nn
+ \else:
+ \group_end:
+ \exp_after:NN \use_arg_ii:nn
+ \fi:
+}
+% \end{macrocode}
+% Note that these definitions make no use of temporary variables.
+% \end{macro}
+% \end{macro}
+%
+%
+%
+% \subsection{The high level commands}
+%
+%
+% Here we set up the functions for defining and redefining document
+% commands and environments. It's all rather straight forward here so
+% I've saved on the comments.
+%
+% \begin{macro}{\DeclareDocumentCommand}
+% \begin{macro}{\ReDeclareDocumentCommand}
+% In case we can't do what the user wanted we gobble the next
+% arguments from the input stream. For commands there are two
+% arguments waiting.
+% \begin{macrocode}
+\def_new:NNn \DeclareDocumentCommand 1 {
+ \xparse_if_definable:NTF #1
+ { \xparse_declare_document_command:Nnn #1 }
+ \use_none:nn
+}
+\def_new:NNn \ReDeclareDocumentCommand 1 {
+ \xparse_if_redefinable:NTF #1
+ { \xparse_declare_document_command:Nnn #1 }
+ \use_none:nn
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\DeclareDocumentEnvironment}
+% \begin{macro}{\ReDeclareDocumentEnvironment}
+% Three arguments for environments.
+% \begin{macrocode}
+\def_new:NNn \DeclareDocumentEnvironment 1 {
+ \xparse_if_definable:cTF {#1}
+ { \xparse_declare_document_environment:nnnn {#1} }
+ \use_none:nnn
+}
+\def_new:NNn \ReDeclareDocumentEnvironment 1 {
+ \xparse_if_redefinable:cTF {#1}
+ { \xparse_declare_document_environment:nnnn {#1} }
+ \use_none:nnn
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\ProvideDocumentCommand}
+% \begin{macro}{\ProvideDocumentEnvironment}
+% When providing a command we just check if the control sequence is
+% free. If it is let |\DeclareDocument...| do the rest, otherwise
+% gobble the next arguments.
+% \begin{macrocode}
+\def_new:NNn \ProvideDocumentCommand 1{
+ \cs_free:NTF #1
+ { \DeclareDocumentCommand #1}
+ \use_none:nn
+}
+\def_new:NNn \ProvideDocumentEnvironment 1{
+ \cs_free:cTF {#1}
+ { \DeclareDocumentEnvironment {#1} }
+ \use_none:nnn
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+%
+%
+% \subsection{The low level definitions}
+%
+%
+% First some helper functions
+% \begin{macro}{\l_xparse_grabbed_args_toks}
+% \begin{macro}{\l_xparse_end_environment_args_toks}
+% \begin{macro}{\l_xparse_mandatory_args_int}
+% \begin{macro}{\l_xparse_total_args_int}
+% We need some \meta{token} registers to keep track of things. We also
+% allocate an \meta{int} register to keep track of the number of
+% arguments.
+% \begin{macrocode}
+\toks_new:N \l_xparse_grabbed_args_toks
+\toks_new:N \l_xparse_end_environment_args_toks
+\int_new:N \l_xparse_mandatory_args_int
+\int_new:N \l_xparse_total_args_int
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+%
+% \begin{macro}{\xparse_declare_document_command:Nnn}
+% \begin{macro}{\xparse_declare_document_command:cnn}
+% |\xparse_declare_document_command:Nnn| is a two step procedure. The
+% user level command |\|\meta{cmd} contains the argument grabbers
+% while the internal command |\\|\meta{cmd} holds the actual
+% definition of what to do with the arguments. Naturally this calls
+% for every such user level command to be robust which is done using
+% the \eTeX{} protection feature.
+% \begin{macrocode}
+\def_long:NNn \xparse_declare_document_command:Nnn 3{
+% \end{macrocode}
+% First we prepare the signature.
+% \begin{macrocode}
+ \xparse_prepare_signature:n {#2}
+% \end{macrocode}
+% Now for the document command. Make it robust and make sure it starts
+% with |\toks_set:Nn \l_xparse_grabbed_args_toks {\\|\meta{cmd}|}|.
+% \begin{macrocode}
+ \def_protected:Npx #1 {
+ \exp_not:n { \toks_set:Nn \l_xparse_grabbed_args_toks }
+ {\exp_not:c {\token_to_string:N #1}}
+% \end{macrocode}
+% Then add the argument grabbers which contain code gathered when
+% preparing the signature.
+% \begin{macrocode}
+ \toks_use:N \l_xparse_grabbed_args_toks
+% \end{macrocode}
+% Finally execute |\toks_use:N \l_xparse_grabbed_args_toks| which now
+% holds the grabbed arguments enclosed in braces and starts with the
+% internal command |\\|\meta{cmd}.
+% \begin{macrocode}
+ \exp_not:n{ \toks_use:N \l_xparse_grabbed_args_toks}
+ }
+% \end{macrocode}
+% Define the internal command by making it a |\long| macro with number
+% of arguments equal to |\l_xparse_total_args_int| and definition as
+% given by |#3|. Even though this internal macro allows |\par| in its
+% argument the decision is left to the individual argument grabbers.
+% \begin{macrocode}
+ \def_long:cNn {\token_to_string:N #1}\l_xparse_total_args_int{#3}
+}
+\def_new:Npn \xparse_declare_document_command:cnn {
+ \exp_args:Nc \xparse_declare_document_command:Nnn
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\xparse_declare_document_environment:nnnn}
+% |\xparse_declare_document_environment:nnnn| is almost the same. In
+% order to use the grabbed arguments we take them from
+% |\l_xparse_grabbed_args_toks| just before they are executed. We
+% also insert a |\group_begin:| as it will otherwise fail miserably
+% in case a user tries to use it without |\begin ... \end|.
+% \begin{macrocode}
+\def_long_new:NNn \xparse_declare_document_environment:nnnn 4 {
+ \xparse_declare_document_command:cnn {#1}{#2}
+ { \group_begin:
+ \toks_set_eq:NN \l_xparse_end_environment_args_toks
+ \l_xparse_grabbed_args_toks
+ #3
+ }
+% \end{macrocode}
+% We let |\end|\meta{envir} equal to a standard version which will do
+% all the work.
+% \begin{macrocode}
+ \let:cN {end #1} \xparse_parsed_end_environment:
+% \end{macrocode}
+% Now define |\end\\|\meta{envir}.
+% \begin{macrocode}
+ \def_long:cNn {end \token_to_string:N \\ #1}
+ \l_xparse_total_args_int{#4}
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\xparse_parsed_end_environment:}
+% \begin{macro}{\xparse_parsed_end_environment_aux:N}
+% |\end|\meta{envir} is set equal to |\xparse_parsed_end_environment:|
+% which then executes |\end\\|\meta{envir}. The |\\|\meta{envir} comes
+% from the argument grabbing. The remainder of the token list is the
+% grabbed arguments. We better make this robust as well.
+% \begin{macrocode}
+\def_protected_new:NNn \xparse_parsed_end_environment: 0{
+ \exp_after:NN \xparse_parsed_end_environment_aux:N
+ \toks_use:N \l_xparse_end_environment_args_toks
+ \group_end:
+}
+\def_new:NNn \xparse_parsed_end_environment_aux:N 1{
+ \cs_use:c {end \token_to_string:N #1 }
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+%
+% \subsubsection{A class designer interface}
+%
+% Below is the implementation of |\DeclareDocumentCommandInterface|
+% and the close cousin |\DeclareDocumentCommandImplementation|.
+% It is an open issue whether this concept should be supported.
+%
+% \begin{macro}{\DeclareDocumentCommandInterface}
+% With this macro we define the document command |#1| to have
+% signature |#3| which does the argument grabbing. The arguments are
+% passed on to the internal command |\impl-#2|.
+% \begin{macrocode}
+\def_long_new:NNn \DeclareDocumentCommandInterface 3{
+ \xparse_prepare_signature:n {#3}
+ \def_protected:Npx #1 {
+ \exp_not:n { \toks_set:Nn \l_xparse_grabbed_args_toks }
+ {\exp_not:c {impl-#2}}
+ \toks_use:N\l_xparse_grabbed_args_toks
+ \exp_not:n{ \toks_use:N \l_xparse_grabbed_args_toks}
+ }
+% \end{macrocode}
+% Define the internal command by making it a |\long| macro as we did
+% for |\DeclareDocumentCommand| but give it just a default definition
+% instead (usually an error message).
+% \begin{macrocode}
+ \def_long:cNn {impl-#2} \l_xparse_total_args_int
+ {\xparse_undefined_command_implementation:n{#2}}
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\xparse_undefined_command_implementation:n}
+% What to do if no implementation is made and the command is
+% called. Let's just typeset the name in quotes indicating that
+% something is wrong.
+% \begin{macrocode}
+\def_new:NNn \xparse_undefined_command_implementation:n 1{
+ ``#1''
+% \ensuremath{\langle\textit{#1}\rangle}
+ \xparse_no_command_implementation_warning:n {#1}
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\DeclareDocumentCommandImplementation}
+% Defines the internal command |\impl-#1| with |#2| arguments
+% and definition |#3|.
+% \begin{macrocode}
+\def_long_new:NNn \DeclareDocumentCommandImplementation 3{
+ \def_long:cNn {impl-#1}#2{#3}
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \subsection{Creating the signature}
+%
+%
+% \begin{macro}{\xparse_prepare_signature:n}
+% The actual preparation of the signature is always the same but we
+% have different ways of handling it afterwards, so we make it a
+% separate function.
+% \begin{macrocode}
+\def_new:NNn \xparse_prepare_signature:n 1 {
+% \end{macrocode}
+% Initialize the counter taking care of the number of arguments. In
+% case we reach more than nine we will give an error message later on.
+% \begin{macrocode}
+ \int_zero:N \l_xparse_total_args_int
+% \end{macrocode}
+% Clear the token register we use when building the signature and the
+% number of ``normal'' mandatory arguments. Also clear out the special
+% markers and initialize the two booleans to \meta{false}.
+% \begin{macrocode}
+ \toks_clear:N \l_xparse_grabbed_args_toks
+ \int_zero:N \l_xparse_mandatory_args_int
+ \bool_gset_false:N \g_xparse_insert_marker_bool
+ \bool_gset_false:N \g_xparse_allow_par_bool
+ \tlp_gset_eq:NN \g_xparse_ignore_marker_tlp
+ \g_xparse_ignore_spaces_marker_tlp
+% \end{macrocode}
+% Then call |\xparse_parse_signature:n|.
+% \begin{macrocode}
+ \xparse_parse_signature:n #1 \q_nil
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \subsection{The argument types}
+%
+%
+%
+% All argument types must be denoted by single letters.\footnote{You
+% can use a multi-letter sequence to denote a shorthand but it
+% requires you to put two brace groups around it in the signature and
+% it's not officially supported.} We have three categories of letters:
+% Special markers, basic argument types, and shorthands.
+%
+% For certain argument types where we peek ahead in the token stream
+% we have a multitude of choices for how the macro should work:
+% Should it ignore spaces or other tokens? Which test should it use
+% for comparing tokens: meaning, catcode or charcode? Because of
+% these difficulties every argument that require peeking ahead must
+% be declared as one of the three test types.
+%
+% \subsubsection{Special markers}
+%
+% Since there are different markers that may be used at the same
+% time, we use the a special ``insert'' marker |>| to do this.
+%
+% \begin{macro}{\g_xparse_ignore_marker_tlp}
+% The current ignore marker is contained in this string.
+% \begin{macrocode}
+\tlp_new:Nn \g_xparse_ignore_marker_tlp {}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\g_xparse_ignore_marker_seq}
+% We start out by declaring a new sequence to contain all the
+% different types of ignore functions. Each element should be the
+% missing part of a |\peek_meaning|\meta{text}|:NTF| function.
+% \begin{macrocode}
+\seq_new:N \g_xparse_ignore_marker_seq
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\g_xparse_insert_marker_bool}
+% A boolean to check if we just saw an insert marker.
+% \begin{macrocode}
+\bool_new:N \g_xparse_insert_marker_bool
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\xparse_add_arg_type_>:}
+% The insert marker is called when this is seen. Is has a funny
+% definition but it works. |#1| is some test in the loop function
+% and |#2| is the list of markers.
+% \begin{macrocode}
+\def_new:cpn {xparse_add_arg_type_>:} #1
+ \xparse_read_arg_type_or_grab_default:n #2{
+% \end{macrocode}
+% Insert pending |m| args first.
+% \begin{macrocode}
+ \xparse_add_remaining_m_args:
+% \end{macrocode}
+% Then we set the boolean true and subtract one from the argument
+% count.
+% \begin{macrocode}
+ \bool_gset_true:N \g_xparse_insert_marker_bool
+ \int_decr:N \l_xparse_total_args_int
+% \end{macrocode}
+% Then go through the list and call each subtype if it exists.
+% \begin{macrocode}
+ \tlist_map_inline:nn{#2}{
+ \xparse_check_and_add_argument_type:N ##1
+ }
+% \end{macrocode}
+% Finally call the loop again.
+% \begin{macrocode}
+ \xparse_parse_signature:n
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\xparse_add_ignore_marker:Nnn}
+% A small function for adding a new ignore type marker.
+% \begin{macrocode}
+\def_new:NNn \xparse_add_ignore_marker:Nnn 3{
+ \tlp_new:cn {g_xparse #2 _marker_tlp}{#3}
+ \seq_gpush:NC \g_xparse_ignore_marker_seq {g_xparse #2 _marker_tlp}
+ \def_new:cpn {xparse_add_arg_type_#1:}{
+ \tlp_gset_eq:Nc \g_xparse_ignore_marker_tlp {g_xparse #2 _marker_tlp}
+ }
+}
+% \end{macrocode}
+% \end{macro}
+% Here we add some ignore markers.
+% \begin{macrocode}
+\xparse_add_ignore_marker:Nnn W{_ignore_nothing}{}
+\xparse_add_ignore_marker:Nnn i{_ignore_spaces}{_ignore_spaces}
+\xparse_add_ignore_marker:Nnn I{_ignore_pars}{_ignore_pars}
+% \end{macrocode}
+%
+% \begin{macro}{\xparse_add_arg_type_P:}
+% This is simple, just set a boolean.
+% \begin{macrocode}
+\def_new:NNn \xparse_add_arg_type_P: 0{
+ \bool_gset_true:N \g_xparse_allow_par_bool
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\g_xparse_allow_par_bool}
+% The boolean for allowing the |\par| token.
+% \begin{macrocode}
+\bool_new:N \g_xparse_allow_par_bool
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\xparse_parse_signature:n}
+% |\xparse_parse_signature:n| reads the signature one token/brace
+% group at a time and builds a list of argument grabbers which is
+% stored in |\l_xparse_grabbed_args_toks|. The function is recursive
+% which is why we use a quark to delimit it.
+% \begin{macrocode}
+\def_new:NNn \xparse_parse_signature:n 1{
+% \end{macrocode}
+% Check if we reached the end of the signature.
+% \begin{macrocode}
+ \quark_if_nil:NTF #1
+% \end{macrocode}
+% If we did we may have pending |m| type arguments so we clear them
+% out here. Also check if the insert marker is true because if it is,
+% something is wrong. Otherwise we just continue.
+% \begin{macrocode}
+ {
+ \xparse_add_remaining_m_args:
+ }
+% \end{macrocode}
+% Then proceed with adding arguments.
+% \begin{macrocode}
+ {
+ \int_incr:N \l_xparse_total_args_int
+ \xparse_check_and_add_argument_type:N #1
+% \end{macrocode}
+% If the insert marker is true at this point we reset it again and
+% also disallow |\par| in arguments and make all |\peek| functions use
+% the |_ignore_spaces| versions.
+% \begin{macrocode}
+ \bool_if:NT \g_xparse_insert_marker_bool
+ {
+ \bool_gset_false:N \g_xparse_insert_marker_bool
+ \bool_gset_false:N \g_xparse_allow_par_bool
+ \tlp_gset_eq:NN \g_xparse_ignore_marker_tlp
+ \g_xparse_ignore_spaces_marker_tlp
+ }
+% \end{macrocode}
+% After adding arguments we better set the boolean false in case we
+% don't have an insert marker.
+% \begin{macrocode}
+% \end{macrocode}
+% First we add the remaining |m| arguments.
+% \begin{macrocode}
+% \end{macrocode}
+% Then we run the loop again.
+% \begin{macrocode}
+ \xparse_read_arg_type_or_grab_default:n
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\xparse_check_and_add_argument_type:N}
+% This function checks if the argument type actually exists and gives
+% an error if it doesn't.
+% \begin{macrocode}
+\def_new:NNn \xparse_check_and_add_argument_type:N 1 {
+ \cs_free:cTF {xparse_add_arg_type_#1:}
+ { \xparse_unknown_arg_type_error_msg:N #1
+ \int_incr:N \l_xparse_mandatory_args_int
+ }
+% \end{macrocode}
+% Otherwise we just add it with its dedicated function.
+% \begin{macrocode}
+ { \cs_use:c {xparse_add_arg_type_#1:} }
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \begin{macro}{\xparse_read_arg_type_or_grab_default:n}
+% \begin{macro}{\xparse_grab_default_arg:n}
+% \begin{macro}{\xparse_grab_default_arg_allow_par:n}
+% The function for grabbing a default value. The default setting is
+% just to tun the loop again. However, some argument types need to
+% add a default argument so we add these as well.
+% \begin{macrocode}
+\let_new:NN \xparse_read_arg_type_or_grab_default:n
+ \xparse_parse_signature:n
+\def_new:NNn \xparse_grab_default_arg:n 1{
+ \toks_put_right:Nn \l_xparse_grabbed_args_toks {{#1}}
+ \let:NN \xparse_read_arg_type_or_grab_default:n
+ \xparse_parse_signature:n
+ \xparse_parse_signature:n
+}
+\def_long_new:NNn \xparse_grab_default_arg_allow_par:n 1{
+ \toks_put_right:Nn \l_xparse_grabbed_args_toks {{#1}}
+ \let:NN \xparse_read_arg_type_or_grab_default:n
+ \xparse_parse_signature:n
+ \xparse_parse_signature:n
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+%
+%
+%
+%
+%
+% \subsubsection{The default argument types}
+%
+%
+%
+% When scanning the signature we need to add the argument type which
+% is done by a function |\xparse_add_arg_type_|\meta{X}|:|, where
+% \meta{X} is the letter denoting the argument type. If not found an
+% error message is issued ny |\xparse_unknown_arg_type_error_msg:N|.
+%
+% By default the package implements the argument types |m|, |S|, |c|,
+% |C|, |o|, and |O| argument types as low level ones. The |s| type is
+% a shorthand as we shall see later.
+%
+% As we don't make every single |m| argument a separate grabber all
+% other types must clear out any pending |m|s.
+%
+% \paragraph{Mandatory arguments}
+%
+% Below follows the implementation of mandatory arguments.
+%
+% \begin{macro}{\xparse_add_arg_type_m:}
+% Check if the user asked for an |m| argument allowing |\par|
+% tokens and insert it. Otherwise increment the number of
+% non-|\long| argument grabbers.
+% \begin{macrocode}
+\def_new:Npn \xparse_add_arg_type_m: {
+ \bool_if:NTF \g_xparse_allow_par_bool
+ {
+ \toks_put_right:Nn \l_xparse_grabbed_args_toks {\xparse_allow_par_m:w}
+ }
+ { \int_incr:N \l_xparse_mandatory_args_int }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\xparse_add_remaining_m_args:}
+% And here is the function for clearing out normal pending |m|
+% arguments. There is little point in adding any arguments if none
+% are required.
+% \begin{macrocode}
+\def_new:Npn \xparse_add_remaining_m_args: {
+ \int_compare:nNnF \l_xparse_mandatory_args_int = \c_zero
+ {
+ \toks_put_right:Nx \l_xparse_grabbed_args_toks {
+ \exp_not:c{xparse_m
+ \int_use:N \l_xparse_mandatory_args_int
+ :w }
+ }
+ \int_zero:N \l_xparse_mandatory_args_int
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\xparse_m1:w}
+% \begin{macro}{\xparse_m2:w}
+% \begin{macro}{\xparse_m3:w}
+% \begin{macro}{\xparse_m4:w}
+% \begin{macro}{\xparse_m5:w}
+% \begin{macro}{\xparse_m6:w}
+% \begin{macro}{\xparse_m7:w}
+% \begin{macro}{\xparse_m8:w}
+% \begin{macro}{\xparse_m9:w}
+% Grabbing 1--9 mandatory arguments. The one grabbing nine arguments
+% will automatically end with
+% |\toks_use:N \l_xparse_grabbed_args_toks| anyway so we avoid
+% problems with that one.
+% \begin{macrocode}
+\def_new:cpn {xparse_m1:w} #1 \l_xparse_grabbed_args_toks#2{
+ \toks_put_right:Nn \l_xparse_grabbed_args_toks{{#2}}
+ #1 \l_xparse_grabbed_args_toks
+}
+\def_new:cpn {xparse_m2:w} #1 \l_xparse_grabbed_args_toks #2#3{
+ \toks_put_right:Nn \l_xparse_grabbed_args_toks{{#2}{#3}}
+ #1 \l_xparse_grabbed_args_toks
+}
+\def_new:cpn {xparse_m3:w} #1 \l_xparse_grabbed_args_toks #2#3#4{
+ \toks_put_right:Nn \l_xparse_grabbed_args_toks{{#2}{#3}{#4}}
+ #1 \l_xparse_grabbed_args_toks
+}
+\def_new:cpn {xparse_m4:w} #1 \l_xparse_grabbed_args_toks #2#3#4#5{
+ \toks_put_right:Nn \l_xparse_grabbed_args_toks{{#2}{#3}{#4}{#5}}
+ #1 \l_xparse_grabbed_args_toks
+}
+\def_new:cpn {xparse_m5:w} #1 \l_xparse_grabbed_args_toks #2#3#4#5#6{
+ \toks_put_right:Nn \l_xparse_grabbed_args_toks{{#2}{#3}{#4}{#5}{#6}}
+ #1 \l_xparse_grabbed_args_toks
+}
+\def_new:cpn {xparse_m6:w} #1 \l_xparse_grabbed_args_toks #2#3#4#5#6#7{
+ \toks_put_right:Nn \l_xparse_grabbed_args_toks
+ {{#2}{#3}{#4}{#5}{#6}{#7}}
+ #1 \l_xparse_grabbed_args_toks
+}
+\def_new:cpn {xparse_m7:w} #1 \l_xparse_grabbed_args_toks#2#3#4#5#6#7#8{
+ \toks_put_right:Nn \l_xparse_grabbed_args_toks
+ {{#2}{#3}{#4}{#5}{#6}{#7}{#8}}
+ #1 \l_xparse_grabbed_args_toks
+}
+\def_new:cpn {xparse_m8:w} #1\l_xparse_grabbed_args_toks
+ #2#3#4#5#6#7#8#9{
+ \toks_put_right:Nn \l_xparse_grabbed_args_toks
+ {{#2}{#3}{#4}{#5}{#6}{#7}{#8}{#9}}
+ #1 \l_xparse_grabbed_args_toks
+}
+\def_new:cpn {xparse_m9:w} \toks_use:N \l_xparse_grabbed_args_toks
+ #1#2#3#4#5#6#7#8#9{
+ \toks_put_right:Nn \l_xparse_grabbed_args_toks
+ {{#1}{#2}{#3}{#4}{#5}{#6}{#7}{#8}{#9}}
+ \toks_use:N \l_xparse_grabbed_args_toks
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\xparse_allow_par_m:w}
+% The |m| type allowing |\par| tokens. We only define one of them as
+% two in a row would be quite rare.
+% \begin{macrocode}
+\def_long_new:Npn \xparse_allow_par_m:w #1 \l_xparse_grabbed_args_toks#2{
+ \toks_put_right:Nn \l_xparse_grabbed_args_toks{{#2}}
+ #1 \l_xparse_grabbed_args_toks
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \paragraph{Arguments delimited by a left brace}
+%
+% \begin{macro}{\xparse_add_arg_type_l:}
+% \begin{macro}{\xparse_l:w}
+% \begin{macro}{\xparse_allow_par_l:w}
+% This is almost exactly the same as the |m| type except we read
+% everything up to the first left brace.
+% \begin{macrocode}
+\def_new:Npn \xparse_add_arg_type_l: {
+ \xparse_add_remaining_m_args:
+ \bool_if:NTF \g_xparse_allow_par_bool
+ {
+ \toks_put_right:Nn \l_xparse_grabbed_args_toks {\xparse_allow_par_l:w}
+ }
+ { \toks_put_right:Nn \l_xparse_grabbed_args_toks {\xparse_l:w} }
+}
+\def_new:Npn \xparse_l:w #1 \l_xparse_grabbed_args_toks#2#{
+ \toks_put_right:Nn \l_xparse_grabbed_args_toks{{#2}}
+ #1 \l_xparse_grabbed_args_toks
+}
+\def_long_new:Npn \xparse_allow_par_l:w #1 \l_xparse_grabbed_args_toks#2#{
+ \toks_put_right:Nn \l_xparse_grabbed_args_toks{{#2}}
+ #1 \l_xparse_grabbed_args_toks
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \paragraph{Adding a symbol argument type}
+%
+%
+% \begin{macro}{\DeclareSymbolArgument}
+% The actual grabber functions just issue a |\peek_meaning_remove:NTF|
+% or similar on the symbol chosen. If found, we put a |\c_true| on the
+% argument stack and |\c_false| otherwise.
+% \begin{macrocode}
+\def_new:NNn \DeclareSymbolArgument 2{
+ \seq_map_variable:NNn \g_xparse_ignore_marker_seq \l_tmpa_tlp {
+ \def:cpx {xparse \l_tmpa_tlp _#1:w}##1##2\l_xparse_grabbed_args_toks{
+ \exp_not:c{peek_ #2 _remove \l_tmpa_tlp :NTF} ##1
+ {
+ \exp_not:N \toks_put_right:Nn \exp_not:N
+ \l_xparse_grabbed_args_toks \exp_not:N \c_true
+ ##2 \exp_not:N\l_xparse_grabbed_args_toks
+ }
+ {
+ \exp_not:N \toks_put_right:Nn \exp_not:N
+ \l_xparse_grabbed_args_toks \exp_not:N \c_false
+ ##2 \exp_not:N\l_xparse_grabbed_args_toks
+ }
+ }
+ }
+% \end{macrocode}
+% Implementing a symbol type is fairly straight forward. It needs to
+% grab a default argument. First we must clear out any pending |m|
+% arguments.
+% \begin{macrocode}
+ \def:cpn {xparse_add_arg_type_#1:} {
+ \xparse_add_remaining_m_args:
+ \toks_put_right:Nx \l_xparse_grabbed_args_toks
+ { \exp_not:c {xparse \g_xparse_ignore_marker_tlp _#1:w } }
+% \end{macrocode}
+% Nothing special when building the signature: We always grab a single
+% default argument.
+% \begin{macrocode}
+ \let:NN \xparse_read_arg_type_or_grab_default:n \xparse_grab_default_arg:n
+ }
+}
+% \end{macrocode}
+% It is this easy now:
+% \begin{macrocode}
+\DeclareSymbolArgument S{meaning}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \paragraph{Adding delimited arguments}
+%
+%
+% \begin{macro}{\DeclareArgumentType}
+% Argument types that read their argument delimited as the |o| type
+% can be defined with this function. |#1| is the letter associated
+% with the type, |#3| is the test type we should use, i.e.,
+% meaning, charcode or catcode. |#2| is the left delimiter \LaTeX{}
+% will look for, |#4| can be used for an error message or such in
+% case of a missing value, and |#5| the value inserted in case the
+% optional argument is missing. The last two arguments control how
+% the arguments are picked up and parsed on to the inner parsing.
+% \begin{macrocode}
+\def_new:NNn \DeclareArgumentType 7{
+% \end{macrocode}
+% For instance, we want |\DeclareArgumentType a{charcode}[...| to
+% define the function |\xparse_ignore_spaces_a:w| with meaning
+% |\peek_charcode_ignore_spaces:NTF [{...}{...}|. We want to define a
+% series of functions for each of these delimited argument types. One
+% for each of the |ignore| types plus an identical version of each of
+% these allowing the |\par| token in the argument. All the different
+% ignore types are stored in the sequence
+% |\g_xparse_ignore_marker_seq| so we go through that when doing the
+% definitions.
+% \begin{macrocode}
+ \seq_map_variable:NNn \g_xparse_ignore_marker_seq \l_tmpa_tlp {
+ \def:cpx {xparse \l_tmpa_tlp _#1:w}##1\l_xparse_grabbed_args_toks{
+ \exp_not:c{peek_#3 \l_tmpa_tlp :NTF} \exp_not:N #2
+ { \exp_not:c{xparse_#1_#3_help:nw}{##1} }
+ {
+ \exp_not:n {
+ #4 \toks_put_right:Nn \l_xparse_grabbed_args_toks {#5}
+ }
+ ##1 \exp_not:N\l_xparse_grabbed_args_toks
+ }
+ }
+% \end{macrocode}
+% And now an almost identical version which allows the |\par| token.
+% \begin{macrocode}
+ \def_long:cpx {xparse_allow_par \l_tmpa_tlp _#1:w}##1
+ \l_xparse_grabbed_args_toks{
+ \exp_not:c{peek_#3 \l_tmpa_tlp :NTF} \exp_not:N #2
+ { \exp_not:c{xparse_allow_par_#1_#3_help:nw}{##1} }
+ {
+ \exp_not:n {
+ #4 \toks_put_right:Nn \l_xparse_grabbed_args_toks {#5}
+ }
+ ##1 \exp_not:N\l_xparse_grabbed_args_toks
+ }
+ }
+ }
+% \end{macrocode}
+% Here is the function for building the argument grabbing. We clear
+% out the remaining |m| arguments first.
+% \begin{macrocode}
+ \def:cpn {xparse_add_arg_type_#1:} {
+ \xparse_add_remaining_m_args:
+ \toks_put_right:Nx \l_xparse_grabbed_args_toks {
+ \exp_not:c {xparse
+% \end{macrocode}
+% Insert |_allow_par| in the csname if needed. This also applies to
+% the argument grabber (although this should probably just be the
+% default).
+% \begin{macrocode}
+ \bool_if:NT \g_xparse_allow_par_bool {_allow_par}
+ \g_xparse_ignore_marker_tlp
+ _#1:w
+ }
+ }
+ \let:NN \xparse_read_arg_type_or_grab_default:n \xparse_parse_signature:n
+ }
+% \end{macrocode}
+% Now all we need to do is to define the helper functions.
+% \begin{macrocode}
+ \xparse_define_helper:Nnnn #1{#3}{#6}{#7}
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\DeclareArgumentTypeDefaultValue}
+% The same as above but expects a default value in the signature.
+% Therefore it doesn't have the arguments of the default value and
+% what to do if it is missing like the above.
+% \begin{macrocode}
+\def_new:NNn \DeclareArgumentTypeDefaultValue 5{
+ \seq_map_variable:NNn \g_xparse_ignore_marker_seq \l_tmpa_tlp {
+ \def:cpx {xparse \l_tmpa_tlp _#1:w}##1##2\l_xparse_grabbed_args_toks{
+ \exp_not:c{peek_#3 \l_tmpa_tlp :NTF} \exp_not:N #2
+ { \exp_not:c{xparse_#1_#3_help:nw}{##2} }
+ {
+ \exp_not:N \toks_put_right:Nn
+ \exp_not:N \l_xparse_grabbed_args_toks {{##1}}
+ ##2 \exp_not:N \l_xparse_grabbed_args_toks
+ }
+ }
+% \end{macrocode}
+% And now an almost identical version which allows the |\par| token.
+% \begin{macrocode}
+ \def_long:cpx {xparse_allow_par \l_tmpa_tlp _#1:w}##1##2
+ \l_xparse_grabbed_args_toks{
+ \exp_not:c{peek_#3 \l_tmpa_tlp :NTF} \exp_not:N #2
+ { \exp_not:c{xparse_allow_par_#1_#3_help:nw}{##2} }
+ {
+ \exp_not:N \toks_put_right:Nn
+ \exp_not:N \l_xparse_grabbed_args_toks {{##1}}
+ ##2 \exp_not:N \l_xparse_grabbed_args_toks
+ }
+ }
+ }
+% \end{macrocode}
+% Here is the function for building the argument grabbing. We clear
+% out the remaining |m| arguments first.
+% \begin{macrocode}
+ \def:cpn {xparse_add_arg_type_#1:} {
+ \xparse_add_remaining_m_args:
+ \toks_put_right:Nx \l_xparse_grabbed_args_toks {
+ \exp_not:c {xparse
+% \end{macrocode}
+% Insert |_allow_par| in the csname if needed. This also applies to
+% the argument grabber (although this should probably just be the
+% default).
+% \begin{macrocode}
+ \bool_if:NT \g_xparse_allow_par_bool {_allow_par}
+ \g_xparse_ignore_marker_tlp
+ _#1:w
+ }
+ }
+ \let:Nc \xparse_read_arg_type_or_grab_default:n
+ {xparse_grab_default_arg
+ \bool_if:NT \g_xparse_allow_par_bool {_allow_par}
+ :n
+ }
+ }
+% \end{macrocode}
+% Now all we need to do is to define the helper functions.
+% \begin{macrocode}
+ \xparse_define_helper:Nnnn #1{#3}{#4}{#5}
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\xparse_define_helper:Nnnn}
+% All we need now is the helper functions. We define a generic
+% interface that should be fairly easy to use.
+% \begin{macrocode}
+\def_new:NNn \xparse_define_helper:Nnnn 4{
+ \toks_set:Nn \l_tmpa_toks
+ {
+ #3
+ {
+% \end{macrocode}
+% Remember to add an extra set of braces here.
+% \begin{macrocode}
+ \toks_put_right:Nn \l_xparse_grabbed_args_toks {{#4}}
+ ##1 \l_xparse_grabbed_args_toks
+ }
+ }
+% \end{macrocode}
+% The next bit looks a little ugly but that's life.
+% \begin{macrocode}
+ \toks_set:Nx \l_tmpa_toks {
+ \exp_not:n {\def:cpn{xparse_#1_#2_help:nw}}
+ \toks_use:N \l_tmpa_toks
+ \exp_not:n {\def:cpn{xparse_allow_par_#1_#2_help:nw}}
+ \toks_use:N\l_tmpa_toks
+ }
+ \toks_use:N \l_tmpa_toks
+}
+% \end{macrocode}
+% \end{macro}
+%
+% All the above may seem like an awful lot of trouble but it is
+% general and it allows the following simple definitions:
+% \begin{macrocode}
+\DeclareArgumentType o[{meaning}{}{\NoValue}{#1[#2]}{#2}
+% \end{macrocode}
+% For the |c| type we add give an error message.
+% \begin{macrocode}
+\DeclareArgumentType c({meaning}{
+ \xparse_error:x{
+ Missing~ coordinate~ argument.~ A~ value~ of~ (0,0)~ is~ assumed}
+ }
+ {{00}}
+ {#1(#2,#3)}{{#2}{#3}}
+\DeclareArgumentTypeDefaultValue O[{meaning}{#1[#2]}{#2}
+\DeclareArgumentTypeDefaultValue C({meaning}{#1(#2,#3)}{{#2}{#3}}
+% \end{macrocode}
+% One could also do
+% \begin{verbatim}
+% \DeclareArgumentTypeDefaultValue O[{charcode}{#1#2#3]}{#3}
+% \end{verbatim}
+% where argument |#2| is the bracket but not requiring it to have
+% catcode~12. However we can't use the same trick for reading the end
+% of the argument.
+%
+% Another interesting one could be
+% \begin{verbatim}
+% \DeclareArgumentType a\c_group_begin_token{catcode}{}{\NoValue}{#1#2}{#2}
+% \end{verbatim}
+% which would basically be an optional argument in braces.
+%
+%
+%
+% \subsubsection{Argument shorthands}
+%
+%
+% \begin{macro}{\DeclareArgumentTypeShorthand}
+% Letting a letter or symbol be a shorthand for a more complicated
+% structure is rather easy actually. All we need to do is to gobble
+% the remainder of the main loop in the signature creation until
+% |\xparse_parse_signature:n|, decrement the argument counter, put
+% in the replacement argument specifiers and start the loop
+% again. The disadvantage of this scheme is that we have to cheat
+% and give it the wrong name as it should have a |w| argument
+% specification but I hope you can forgive this little white lie.
+% \begin{macrocode}
+\def_new:NNn \DeclareArgumentTypeShorthand 2{
+ \def_new:cpn {xparse_add_arg_type_#1:}
+ ##1 \xparse_read_arg_type_or_grab_default:n {
+ \int_decr:N \l_xparse_total_args_int
+ \xparse_read_arg_type_or_grab_default:n #2
+ }
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\xparse_add_arg_type_s:}
+% Defining the |s| type is easy now since it really means |S{*}|.
+% \begin{macrocode}
+\DeclareArgumentTypeShorthand s {S{*}}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \subsection{Checking for optional values}
+%
+%
+% \begin{macro}{\IfBooleanTF}
+% \begin{macro}{\IfBooleanT}
+% \begin{macro}{\IfBooleanF}
+% The logical \meta{true} and \meta{false} statements are just our
+% normal |\c_true| and |\c_false| so testing for them is done with
+% our usual |\prg_if_predicate:nTF| functions from \textsf{l3prg}.
+% \begin{macrocode}
+\let_new:NN \IfBooleanTF \prg_if_predicate:nTF
+\let_new:NN \IfBooleanT \prg_if_predicate:nT
+\let_new:NN \IfBooleanF \prg_if_predicate:nF
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\NoValue}
+% \begin{macro}{\c_xparse_hidden_no_value_tlp}
+% |\NoValue| is just a text string and we define it as a token list
+% pointer. However we will actually test for token list pointers
+% with \emph{meaning} |\NoValue|. Hence if an argument is really
+% |-NoValue-| it will not be detected but that shouldn't happen.
+% \begin{macrocode}
+\tlp_new:Nn \NoValue {-NoValue-}
+\tlp_new:Nn \c_xparse_hidden_no_value_tlp {\NoValue}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\xparse_if_no_value:nTF}
+% The test start by making a token list pointer out of the first
+% argument and then check if it is equal to
+% |\c_xparse_hidden_no_value_tlp| which contains |\NoValue|.
+% \begin{macrocode}
+\def_long_new:Npn \xparse_if_no_value:nTF #1{
+ \tlp_set:Nx \l_tmpa_tlp{\exp_not:n{#1}}
+ \tlp_if_eq:NNTF \l_tmpa_tlp \c_xparse_hidden_no_value_tlp
+% \end{macrocode}
+% If they are equal we just exit and execute the \meta{true} code.
+% \begin{macrocode}
+ { \use_arg_i:nn }
+% \end{macrocode}
+% If not, take a closer look at |#1|. Peek ahead at the first token in
+% |#1| and then call the function |\xparse_if_no_value_aux:| but only
+% if |#1| is not empty or a blank space: in that case we can execute
+% the \meta{false} code immediately. We must use this test at some
+% point otherwise the macros for checking tokens will break since the
+% argument may be empty.
+% \begin{macrocode}
+ { \tlist_if_blank:nTF {#1}
+ { \use_arg_ii:nn }
+ {\peek_after:NN \xparse_if_no_value_aux: #1 \q_nil {#1} }
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\xparse_if_no_value_aux:}
+% Now we simply check the argument specification of the token. If
+% it is not a macro the function |\token_get_arg_spec:N| returns
+% |\scan_stop:|.
+% \begin{macrocode}
+\def_long_new:Npn \xparse_if_no_value_aux: {
+ \tlp_set:Nx \l_tmpa_tlp{\token_get_arg_spec:N \l_peek_token }
+% \end{macrocode}
+% Then check if |\l_tmpa_tlp| is empty, because this means we have a
+% macro taking zero arguments and we can expand it once
+% safely. Otherwise we just exit and execute the false code. Remember
+% that we have the sequence |{#1}| waiting after the |\q_nil| in
+% |\xparse_if_no_value:nTF| above.
+% \begin{macrocode}
+ \tlp_if_empty:NTF \l_tmpa_tlp
+ {\use_arg_i_delimit_by_q_nil:nw {\exp_args:No\xparse_if_no_value:nTF}}
+ {\use_arg_i_delimit_by_q_nil:nw {\use_arg_iii:nnn}}
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\IfNoValueTF}
+% \begin{macro}{\IfNoValueT}
+% \begin{macro}{\IfNoValueF}
+% \begin{macro}{\IfValueTF}
+% \begin{macro}{\IfValueT}
+% \begin{macro}{\IfValueF}
+% |\IfNoValueTF| and its varieties are implemented as subcases of
+% |\xparse_if_no_value:nTF|.
+% \begin{macrocode}
+\let_new:NN \IfNoValueTF \xparse_if_no_value:nTF
+\def_long_new:NNn \IfNoValueT 2 {\xparse_if_no_value:nTF{#1}{#2}{}}
+\def_long_new:NNn \IfNoValueF 1 {\xparse_if_no_value:nTF {#1}{}}
+% \end{macrocode}
+% For |\IfValueTF| we just reverse the arguments.
+% \begin{macrocode}
+\def_long_new:NNn \IfValueTF 3{\xparse_if_no_value:nTF {#1}{#3}{#2}}
+\let_new:NN \IfValueT \IfNoValueF
+\let_new:NN \IfValueF \IfNoValueT
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+%
+% \subsection{Pseudo arguments}
+%
+% \begin{macro}{\l_xparse_pseudo_post_arg_tlp}
+% A temporary token list pointer to store the post-arguments.
+% \begin{macrocode}
+\tlp_new:Nn \l_xparse_pseudo_post_arg_tlp {}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\DeclarePseudoArgument}
+% Must be called at the end of the replacement text. Can use the
+% parameters picked up so far. |#1| is a name for it, |#2| is the
+% number of arguments, |#3| is the pre-argument definition, |#4| is
+% the post-argument definition. The idea here is to define two
+% functions: One to execute before the special pseudo argument is
+% found and one to to it afterwards. Hence we define such two
+% functions with |#2| arguments and definitions |#3| and |#4|
+% respectively.
+% \begin{macrocode}
+\def_long_new:NNn \DeclarePseudoArgument 4{
+ \def_long:cNn {xparse_pseudo_pre_arg_#1:\prg_replicate:nn{#2}{n}}#2{#3}
+ \def_long:cNn {xparse_pseudo_post_arg_#1:\prg_replicate:nn{#2}{n}}#2{#4}
+% \end{macrocode}
+% In case the user doesn't put the argument in braces, it must be a
+% single token which we just grab and then execute the
+% post-argument. Surely it won't be a |\par| token!
+% \begin{macrocode}
+ \def:cNn {xparse_pseudo_nobrace_arg_#1:N} 1 {
+ ##1 \l_xparse_pseudo_post_arg_tlp
+ }
+% \end{macrocode}
+% The regular version of the command is then this:
+% \begin{enumerate}
+% \item Execute the pre-code at level $n$.
+% \item Store the post-code in a token list pointer at level $n$.
+% \item Look for a begin-group token.
+% \item[4a] If found, remove it, start a group (level $n+1$) and make
+% sure the token list pointer from 2) is executed after the group
+% has ended (at level $n$).
+% \item[4b] If not found, call the |nobrace_arg| version which also
+% executes the token list pointer from 2) at level $n$.
+% \end{enumerate}
+% This scheme enables these commands to be nested since they all
+% appear at different grouping levels.
+%
+% Next we define the function. Also make sure that it gets all the
+% arguments carried over to the post-argument.
+% \begin{macrocode}
+ \def_long:cNx {xparse_pseudo_arg_#1:w} #2
+ {
+ \exp_not:c {
+ xparse_pseudo_pre_arg_#1: \prg_replicate:nn{#2}{n}
+ }
+ \cs_use:c{def_aux_use_\int_use:N \int_eval:n{#2}_parameter:}
+ \exp_not:n {\tlp_set:Nn \l_xparse_pseudo_post_arg_tlp}
+ {
+ \exp_not:c {xparse_pseudo_post_arg_#1:\prg_replicate:nn{#2}{n}}
+ \cs_use:c{def_aux_use_\int_use:N \int_eval:n{#2}_parameter:}
+ }
+ \exp_not:n{ \peek_catcode_remove_ignore_spaces:NTF \c_group_begin_token }
+ {
+% \end{macrocode}
+% Here we insert the left brace token which was removed removed.
+% In case you're wondering then yes, I know that |\c_group_begin_token|
+% and |\group_execute_after:N| are unexpandable but I prefer this method
+% because I don't want to remember which commands are expandable and
+% which are not.
+% \begin{macrocode}
+ \exp_not:n {
+ \c_group_begin_token
+ \group_execute_after:N \l_xparse_pseudo_post_arg_tlp
+ }
+ }
+ {
+ \exp_not:c{xparse_pseudo_nobrace_arg_#1:N}
+ }
+ }
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\UsePseudoArgument}
+% Just a nice wrapper for calling such an argument.
+% \begin{macrocode}
+\def_new:NNn \UsePseudoArgument 1{\cs_use:c{xparse_pseudo_arg_#1:w}}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+% \Finale
+%
+\endinput
+%
+% $Log$
+% Revision 1.25 2006/07/17 22:25:53 morten
+% Minor change to reflect change in l3basics.dtx
+%
+% Revision 1.24 2006/07/08 22:44:29 morten
+% Fixed two lurking problems in \xparse_if_no_value:nTF.
+%
+% Revision 1.23 2006/07/06 14:56:04 morten
+% Change to use new \def:NNn syntax
+%
+% Revision 1.22 2006/01/17 23:04:08 morten
+% Added `l' type argument for reading up to a left brace.
+%
+% Revision 1.21 2006/01/04 02:42:35 morten
+% Changed RCS information retrieval. Rewrote \DeclareArgumentType and
+% its relatives in order for them to work properly with the new \peek_
+% functions. Changed how special markers are inserted into the
+% signature. Added `pseudo arguments'. Updated documentation to reflect
+% all these changes. And more which I can't remember right now :-)
+%
+% Revision 1.20 2005/04/06 21:24:47 morten
+% Total rewrite - there is only one implementation in the package
+% now. Documentation updated to match the changes.
+%
+%
+%