diff options
Diffstat (limited to 'Master/texmf-dist/source/latex/xbase/xparse.dtx')
-rw-r--r-- | Master/texmf-dist/source/latex/xbase/xparse.dtx | 2168 |
1 files changed, 0 insertions, 2168 deletions
diff --git a/Master/texmf-dist/source/latex/xbase/xparse.dtx b/Master/texmf-dist/source/latex/xbase/xparse.dtx deleted file mode 100644 index 0ecd05af7bc..00000000000 --- a/Master/texmf-dist/source/latex/xbase/xparse.dtx +++ /dev/null @@ -1,2168 +0,0 @@ -% \iffalse -%% File: xparse.dtx (C) Copyright 1999 Frank Mittelbach, Chris Rowley, David Carlisle -%% (C) Copyright 2004-2007 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. -%% -%% ----------------------------------------------------------------------- -%% -%<*driver|package> -\RequirePackage{l3names} -%</driver|package> -%\fi -\GetIdInfo$Id: xparse.dtx 700 2007-11-27 14:18:29Z morten $ - {generic document command parser} -%\iffalse -%<*driver> -%\fi -\ProvidesFile{\filename.\filenameext} - [\filedate\space v\fileversion\space\filedescription] -%\iffalse - \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{626} -% -% -% \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} -% \ExplSyntaxOn -% \makeatletter -% \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} -% } -% \makeatother -% \ExplSyntaxOn -% \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> -\ProvidesExplPackage - {\filename}{\filedate}{\fileversion}{\filedescription} -\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 |\bool_if:NTF| functions from \textsf{l3prg}. -% \begin{macrocode} -\let_new:NN \IfBooleanTF \bool_if:NTF -\let_new:NN \IfBooleanT \bool_if:NT -\let_new:NN \IfBooleanF \bool_if: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. -% -% -% |