diff options
author | Karl Berry <karl@freefriends.org> | 2009-09-06 23:20:42 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2009-09-06 23:20:42 +0000 |
commit | bfb16a7c8d3c77987590435854c647b54bc6450b (patch) | |
tree | cf65fafece2986d781a52ad28aaeb06fe48eed69 /Master | |
parent | 2b8eb47b09b2d853b8243d0fb61b408edb3d04a7 (diff) |
xpackages (5sep09)
git-svn-id: svn://tug.org/texlive/trunk@15164 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master')
25 files changed, 3950 insertions, 2838 deletions
diff --git a/Master/texmf-dist/doc/latex/xpackages/ldcsetup.pdf b/Master/texmf-dist/doc/latex/xpackages/ldcsetup.pdf Binary files differdeleted file mode 100644 index 1db38a85a57..00000000000 --- a/Master/texmf-dist/doc/latex/xpackages/ldcsetup.pdf +++ /dev/null diff --git a/Master/texmf-dist/doc/latex/xpackages/README b/Master/texmf-dist/doc/latex/xpackages/readme-ctan index ccef2cc6007..ccef2cc6007 100644 --- a/Master/texmf-dist/doc/latex/xpackages/README +++ b/Master/texmf-dist/doc/latex/xpackages/readme-ctan diff --git a/Master/texmf-dist/doc/latex/xpackages/template.pdf b/Master/texmf-dist/doc/latex/xpackages/template.pdf Binary files differdeleted file mode 100644 index c9b199bbda7..00000000000 --- a/Master/texmf-dist/doc/latex/xpackages/template.pdf +++ /dev/null diff --git a/Master/texmf-dist/doc/latex/xpackages/xbase/ldcsetup.pdf b/Master/texmf-dist/doc/latex/xpackages/xbase/ldcsetup.pdf Binary files differnew file mode 100644 index 00000000000..07615093cbe --- /dev/null +++ b/Master/texmf-dist/doc/latex/xpackages/xbase/ldcsetup.pdf diff --git a/Master/texmf-dist/doc/latex/xpackages/xbase/template.pdf b/Master/texmf-dist/doc/latex/xpackages/xbase/template.pdf Binary files differnew file mode 100644 index 00000000000..4d67cb17a13 --- /dev/null +++ b/Master/texmf-dist/doc/latex/xpackages/xbase/template.pdf diff --git a/Master/texmf-dist/doc/latex/xpackages/xbase/xparse.pdf b/Master/texmf-dist/doc/latex/xpackages/xbase/xparse.pdf Binary files differnew file mode 100644 index 00000000000..8dd55866da1 --- /dev/null +++ b/Master/texmf-dist/doc/latex/xpackages/xbase/xparse.pdf diff --git a/Master/texmf-dist/doc/latex/xpackages/xparse.pdf b/Master/texmf-dist/doc/latex/xpackages/xparse.pdf Binary files differdeleted file mode 100644 index bf63758c4aa..00000000000 --- a/Master/texmf-dist/doc/latex/xpackages/xparse.pdf +++ /dev/null diff --git a/Master/texmf-dist/doc/latex/xpackages/xtras/l3keys2e.pdf b/Master/texmf-dist/doc/latex/xpackages/xtras/l3keys2e.pdf Binary files differnew file mode 100644 index 00000000000..75583163f48 --- /dev/null +++ b/Master/texmf-dist/doc/latex/xpackages/xtras/l3keys2e.pdf diff --git a/Master/texmf-dist/source/latex/xpackages/ldcsetup.dtx b/Master/texmf-dist/source/latex/xpackages/xbase/ldcsetup.dtx index 09e37c55cb3..09e37c55cb3 100644 --- a/Master/texmf-dist/source/latex/xpackages/ldcsetup.dtx +++ b/Master/texmf-dist/source/latex/xpackages/xbase/ldcsetup.dtx diff --git a/Master/texmf-dist/source/latex/xpackages/template-test.tex b/Master/texmf-dist/source/latex/xpackages/xbase/template-test.tex index f8c47c82d59..f8c47c82d59 100644 --- a/Master/texmf-dist/source/latex/xpackages/template-test.tex +++ b/Master/texmf-dist/source/latex/xpackages/xbase/template-test.tex diff --git a/Master/texmf-dist/source/latex/xpackages/template-test2.tex b/Master/texmf-dist/source/latex/xpackages/xbase/template-test2.tex index 489e9f2304a..489e9f2304a 100644 --- a/Master/texmf-dist/source/latex/xpackages/template-test2.tex +++ b/Master/texmf-dist/source/latex/xpackages/xbase/template-test2.tex diff --git a/Master/texmf-dist/source/latex/xpackages/template.dtx b/Master/texmf-dist/source/latex/xpackages/xbase/template.dtx index 6c5fd2a686a..8b38f6d216c 100644 --- a/Master/texmf-dist/source/latex/xpackages/template.dtx +++ b/Master/texmf-dist/source/latex/xpackages/xbase/template.dtx @@ -37,7 +37,7 @@ \RequirePackage{expl3} %</driver|package> %\fi -\GetIdInfo$Id: template.dtx 1295 2009-05-06 08:32:25Z will $ +\GetIdInfo$Id: template.dtx 1461 2009-08-15 08:38:12Z joseph $ {template} %\iffalse %<*driver> @@ -1736,10 +1736,7 @@ % % % \begin{macro}{\TP_parse_optional_key_default:nw} -% Look for default value. The |t| argument type here is one we -% define for template so we can change it easily. Currently I just -% set it to be a regular optional argument in brackets. |#1| is what -% we are carrying over, |#2| the optional argument. +% Look for default value. % \begin{macrocode} \cs_set:Npn \TP_ignore_leading_space_in_arg_ii:nn#1#2{ \exp_args:Nf\TP_ignore_leading_space_in_arg_ii_aux:nn @@ -1748,8 +1745,7 @@ \cs_set:Npn \TP_ignore_leading_space_in_arg_ii_aux:nn#1#2{#2{#1}} -\DeclareArgumentType t[{meaning}{}{\NoValue}{#1[#2]}{#2} -\DeclareDocumentCommand\TP_parse_optional_key_default:nw{mt}{ +\DeclareDocumentCommand\TP_parse_optional_key_default:nw{mo}{ \IfNoValueTF{#2} {\TP_templdecl_finish_key_setup:nw{#1}} {\TP_templdecl_finish_key_setup_with_default:nnw{#1}{#2}} diff --git a/Master/texmf-dist/source/latex/xpackages/tprestrict-test.tex b/Master/texmf-dist/source/latex/xpackages/xbase/tprestrict-test.tex index a787694abff..a787694abff 100644 --- a/Master/texmf-dist/source/latex/xpackages/tprestrict-test.tex +++ b/Master/texmf-dist/source/latex/xpackages/xbase/tprestrict-test.tex diff --git a/Master/texmf-dist/source/latex/xpackages/xbase.ins b/Master/texmf-dist/source/latex/xpackages/xbase/xbase.ins index 9f6213a3fb2..742a1aa8dc3 100644 --- a/Master/texmf-dist/source/latex/xpackages/xbase.ins +++ b/Master/texmf-dist/source/latex/xpackages/xbase/xbase.ins @@ -1,73 +1,73 @@ -% \iffalse
-%%
-%% This file will generate fast loadable files and documentation
-%% driver files from the dtx files in this package when run through
-%% LaTeX or TeX.
-%%
-%% (C) Copyright 2000-2005 LaTeX3 Project
-%%
-%% It may be distributed and/or modified under the conditions of the
-%% LaTeX Project Public License (LPPL), either version 1.3a 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.
-%%
-%% -----------------------------------------------------------------------
-%%
-%% $Id: xbase.ins 302 2005-03-01 22:49:14Z morten $
-%%
-% \fi
-%
-
-\input docstrip
-\keepsilent
-\askforoverwritefalse
-
-\preamble
-
-(C) Copyright The LaTeX3 Project and any individual authors
-listed elsewhere in this file.
-
-This is a generated file.
-
-This file was generated from file(s) of the xbase bundle.
----------------------------------------------------------
-
-This file may only be distributed together with a copy of this bundle.
-You may however distribute the bundle without such generated files.
-
-======================================================================
-
-\endpreamble
-
-
-\generate{%
- \file{ldcsetup.sty}{\from{ldcsetup.dtx}{package}}
- \file{template.sty}{\from{template.dtx}{package,trace}}
- \file{xparse.sty}{\from{xparse.dtx}{package}}
-}
-
-\endbatchfile
+% \iffalse +%% +%% This file will generate fast loadable files and documentation +%% driver files from the dtx files in this package when run through +%% LaTeX or TeX. +%% +%% (C) Copyright 2000-2005 LaTeX3 Project +%% +%% It may be distributed and/or modified under the conditions of the +%% LaTeX Project Public License (LPPL), either version 1.3a 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. +%% +%% ----------------------------------------------------------------------- +%% +%% $Id: xbase.ins 302 2005-03-01 22:49:14Z morten $ +%% +% \fi +% + +\input docstrip +\keepsilent +\askforoverwritefalse + +\preamble + +(C) Copyright The LaTeX3 Project and any individual authors +listed elsewhere in this file. + +This is a generated file. + +This file was generated from file(s) of the xbase bundle. +--------------------------------------------------------- + +This file may only be distributed together with a copy of this bundle. +You may however distribute the bundle without such generated files. + +====================================================================== + +\endpreamble + + +\generate{% + \file{ldcsetup.sty}{\from{ldcsetup.dtx}{package}} + \file{template.sty}{\from{template.dtx}{package,trace}} + \file{xparse.sty}{\from{xparse.dtx}{package}} +} + +\endbatchfile diff --git a/Master/texmf-dist/source/latex/xpackages/xparse-test.tex b/Master/texmf-dist/source/latex/xpackages/xbase/xparse-test.tex index f0071b021ab..9e681adf520 100644 --- a/Master/texmf-dist/source/latex/xpackages/xparse-test.tex +++ b/Master/texmf-dist/source/latex/xpackages/xbase/xparse-test.tex @@ -32,7 +32,7 @@ %% %% ----------------------------------------------------------------------- %% -%% $Id: xparse-test.tex 1194 2009-04-19 15:07:07Z will $ +%% $Id: xparse-test.tex 1487 2009-08-22 15:55:24Z joseph $ %% % \fi % @@ -60,14 +60,15 @@ % Another one for being undefined \RenewDocumentCommand \makebox {m}{Even~more~gobbledygook} % Now it should work -\DeclareDocumentCommand \makebox { C{\NoValue} o O{c} m} - { - \IfNoValueTF{#1} +\DeclareDocumentCommand \makebox + { >{\xparse_process_comma_split:n}d() 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} + +\DeclareDocumentCommand \framebox + { >{\xparse_process_comma_split:n} d() o O{c} m} { \IfNoValueTF{#1} { \ltx@maketextbox{#2}{#3}{#4}\fbox } @@ -119,17 +120,6 @@ } } -\DeclarePseudoArgument{boxtest}{1} -{Before:~`#1',\hbox_set_inline_begin:N \l_tmpa_box } -{\hbox_set_inline_end: \space the~ box:~ - \hbox_unpack_clear:N\l_tmpa_box ,~ - After:~`#1'} -\DeclareDocumentCommand\sillyboxtest{m}{ - Testing~#1:~\UsePseudoArgument{boxtest}{#1} -} - - -\cs_set_nopar:Npn \showgrabbedargs{\showthe\l_xparse_grabbed_args_toks} \makeatother \ExplSyntaxOff @@ -163,29 +153,38 @@ \show\foo -\DeclareDocumentCommand \foo { m C{{0}{0}} m } +\ExplSyntaxOn +\DeclareDocumentCommand \foo + { m >{\xparse_process_comma_split:n} D(){0,0} m } { \typeout{1:#1} \typeout{2:#2} \typeout{3:#3} } +\ExplSyntaxOff \show\foo -\foo A (1,2) B +\foo A(1,2)B \foo A B \typeout{Testing mandatory coordinates (gives error on second examples)} -\DeclareDocumentCommand \foo { m c m } -{ \typeout{1:#1} - \typeout{2:#2} - \typeout{3:#3} +\ExplSyntaxOn +\DeclareDocumentCommand \foo { m >{\xparse_process_comma_split:n} d() m } +{ \IfNoValueTF {#2} { + \ERROR + }{ + \typeout{1:#1} + \typeout{2:#2} + \typeout{3:#3} + } } +\ExplSyntaxOff \show\foo -\foo A (1,2) B +\foo A(1,2)B \foo A B @@ -203,7 +202,8 @@ \typeout{8:#8} } -\foo 1234[5]67[8] +\foo 1234 [5]67[8] +\foo 1234 [5]67 [8] % 8 should not be picked up here \foo 123467 \show\foo @@ -227,9 +227,7 @@ \expandafter\show\csname\string\baz\endcsname \baz [1]234[5]678 -\showgrabbedargs \baz 234678 -\showgrabbedargs %\tracingall\tracingassigns=1 \DeclareDocumentCommand \bar { mmmm mmmm m} @@ -248,7 +246,6 @@ \expandafter\show\csname\string\bar\endcsname \bar 123456789 -\showgrabbedargs \DeclareDocumentCommand\chapter{soom} {\typeout{a{#1}^^Jb{#2}^^Jc{#3}^^Jd{#4}^^Je}} @@ -270,18 +267,6 @@ -\typeout{Using pseudo arguments:} - -\sillyboxtest{AB}{a\verb*+% $%&\+b} - -\typeout{Testing environments with args passed to end env} -\typeout{****************} -\typeout{* This works only if xparse is compiled with `perhaps' - docstrip guard} -\typeout{* This part of the code is not activated by default!} -\typeout{****************} - - \DeclareDocumentCommand\chapter{soom} {\typeout{a{#1}^^Jb{#2}^^Jc{#3}^^Jd{#4}^^Je}} @@ -305,7 +290,7 @@ \begin{hello}[1] \typeout{outer body} -\hello [2] \typeout{inner body} \endhello +\hello[2]\typeout{inner body}\endhello \end{hello} \stop diff --git a/Master/texmf-dist/source/latex/xpackages/xbase/xparse.dtx b/Master/texmf-dist/source/latex/xpackages/xbase/xparse.dtx new file mode 100644 index 00000000000..c227c4612f3 --- /dev/null +++ b/Master/texmf-dist/source/latex/xpackages/xbase/xparse.dtx @@ -0,0 +1,2443 @@ +% \iffalse +%% File: xparse.dtx (C) Copyright 1999 Frank Mittelbach, Chris Rowley, +%% David Carlisle +%% (C) Copyright 2004-2008 Frank Mittelbach, +%% LaTeX3 Project +%% (C) Copyright 2009 LaTeX3 Project +%% +%% It may be distributed and/or modified under the conditions of the +%% LaTeX Project Public License (LPPL), either version 1.3c of this +%% license or (at your option) any later version. The latest version +%% of this license is in the file +%% +%% http://www.latex-project.org/lppl.txt +%% +%% This file is part of the ``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/svnroot/experimental/trunk/ +%% +%% for those people who are interested. +%% +%%%%%%%%%%% +%% NOTE: %% +%%%%%%%%%%% +%% +%% Snapshots taken from the repository represent work in progress and may +%% not work or may contain conflicting material! We therefore ask +%% people _not_ to put them into distributions, archives, etc. without +%% prior consultation with the LaTeX Project Team. +%% +%% ----------------------------------------------------------------------- +%% +% +%<*driver|package> +\RequirePackage{l3names} +%</driver|package> +%\fi +\GetIdInfo$Id: xparse.dtx 1497 2009-08-31 19:17:53Z joseph $ + {Generic document command parser} +%\iffalse +%<*driver> +%\fi +\ProvidesFile{\filename.\filenameext} + [\filedate\space v\fileversion\space\filedescription] +%\iffalse +\documentclass{l3doc} +\begin{document} + \DocInput{xparse.dtx} +\end{document} +%</driver> +% \fi +% +% \title{The \textsf{xparse} package\thanks{This file +% has version number \fileversion, last +% revised \filedate.}\\ +% Generic document command parser} +% \author{\Team} +% \date{\filedate} +% \maketitle +% +%\begin{documentation} +% +%\section{Creating document commands} +% +% The \pkg{xparse} package provides a high-level interface for +% producing document-level commands. In that way, it is intended as +% a replacement for the \LaTeXe\ \cs{newcommand} macro. However, +% \pkg{xparse} works so that the interface to a function (optional +% arguments, stars and mandatory arguments, for example) is separate +% from the internal implementation. \pkg{xparse} provides a normalised +% input for the internal form of a function, independent of the +% document-level argument arrangement. +% +% At present, the functions in \pkg{xparse} which are regarded as +% `stable' are: +%\begin{itemize} +% \item \cs{DeclareDocumentCommand} +% \item \cs{NewDocumentCommand} +% \item \cs{RenewDocumentCommand} +% \item \cs{ProvideDocumentCommand} +% \item \cs{DeclareDocumentEnvironment} +% \item \cs{NewDocumentEnvironment} +% \item \cs{RenewDocumentEnvironment} +% \item \cs{ProvideDocumentEnvironment} +% \item \cs{IfNoValue(TF)} (the need for \cs{IfValue(TF)} is currently +% an item of active discussion) +% \item \cs{IfBoolean(TF)} +%\end{itemize} +% with the other functions currently regarded as `experimental'. Please +% try all of the commands provided here, but be aware that the +% experimental ones may change or disappear. +% +%\subsection{Specifying arguments} +% +% Before introducing the functions used to create document commands, +% the method for specifiying arguments with \pkg{xparse} will be +% illustrated. In order to allow each argument to be defined +% independently, \pkg{xparse} does not simply need to know the +% number of arguments for a function, but also the nature of each +% one. This is done by constructing an \emph{argument specification}, +% which defines the number of arguments, the type of each argument +% and any additional information needed for \pkg{xparse} to read the +% user input and properly pass it thorugh to internal functions. +% +% The basic form of the argument specifier is a list of letters, where +% each letter defines a type of argument. As will be described below, +% some of the types need additional information, such as default values. +% The argument types can be divided into two, those which define +% arguments that are mandatory (potentially raising an error if not +% found) and those which define optional arguments. The mandatory types +% are: +%\begin{itemize}[font=\ttfamily] +% \item[m] A standard mandatory argument, which can either be a single +% token alone or multiple tokens surrounded by curly braces. +% Regardless of the input, the argument will be passed to the +% internal code surrounded by a brace pair. This is the \pkg{xparse} +% type specifier for a normal \TeX\ argument. +% \item[l] An argument which reads everything up to the first +% open group token: in standard \LaTeX\ this is a left brace. +% \item[u] Reads an argument `until' \meta{tokens} are encountered, +% where the desired \meta{tokens} are given as an argument to the +% specifier: \texttt{u}\marg{tokens}. +%\end{itemize} +% The types which define optional arguments are: +%\begin{itemize}[font=\ttfamily] +% \item[o] A standard \LaTeX\ optional argument, surrounded with square +% brackets, which will supply +% the special \cs{NoValue} token if not given (as described later). +% \item[d] An optional argument which is delimited by \meta{token1} +% and \meta{token2}, which are given as arguments: +% \texttt{d}\meta{token1}\meta{token2}. As with \texttt{o}, if no +% value is given the special token \cs{NoValue} is returned. +% \item[O] As for \texttt{o}, but returns \meta{default} if no +% value is given. Should be given as \texttt{O}\marg{default}. +% \item[D] As for \texttt{d}, but returns \meta{default} if no +% value is given: \texttt{D}\meta{token1}\meta{token2}\marg{default}. +% Internally, the \texttt{o}, \texttt{d} and \texttt{O} types are +% shortcuts to an appropriated-constructed \texttt{D} type argument. +% \item[s] An optional star, which will result in a value +% \cs{BooleanTrue} if a star is present and \cs{BooleanFalse} +% otherwise (as described later). +% \item[t] An optional \meta{token}, which will result in a value +% \cs{BooleanTrue} if \meta{token} is present and \cs{BooleanFalse} +% otherwise. Given as \texttt{t}\meta{token}. +% \item[g] An optional argument given inside a pair of \TeX\ group +% tokens (in standard \LaTeX, |{| \ldots |}|). +%\end{itemize} +% +% Using these specifiers, it is possible to create complex input syntax +% very easily. For example, given the argument definition +% `|s o o m O{default}|', the input `|*[Foo]{Bar}|' would be parsed as: +%\begin{itemize}[nolistsep] +% \item |#1| = |\BooleanTrue| +% \item |#2| = |{Foo}| +% \item |#3| = |\NoValue| +% \item |#4| = |{Bar}| +% \item |#5| = |{default}| +%\end{itemize} +% whereas `|[One][Two]{}[three]|' would be parsed as: +%\begin{itemize}[nolistsep] +% \item |#1| = |\BooleanFalse| +% \item |#2| = |{One}| +% \item |#3| = |{Two}| +% \item |#4| = |{}| +% \item |#5| = |{Three}| +%\end{itemize} +% Note that after parsing the input there will be always exactly the +% same number of brace groups or tokens as the number of letters in the +% argument specifier. +% +% Two more tokens have a special meaning when creating an argument +% specifier. First, \texttt{+} is used to make an argument long (to +% accept paragraph tokens). In contrast to \LaTeXe's \cs{newcommand}, +% this applies on an argument-by-argument basis. So modifying the +% example to `|s o o +m O{default}|' means that the mandatory argument +% is now \cs{long}, whereas the optional arguments are not. +% +% Secondly, the token \texttt{>} is used to declare so-called +% `argument processors', which can be used to modify the contents of an +% argument before it is passed to the macro definition. The use of +% argument processors is a somewhat advanced topic, (or at least a less +% commonly used feature) and is covered in Section~\ref{sec:processors}. +% +%\subsection{Declaring commands and environments} +% +% With the concept of an argument specifier defined, it is now +% possible to describe the methods available for creating both +% functions and environments using \pkg{xparse}. +% +% The interface-building commands are the preferred method for +% creating document-level functions in \LaTeX3. All of the functions +% generated in this way are naturally robust (using the \eTeX\ +% \cs{protected} mechanism). +% +%\begin{function}{ +% \DeclareDocumentCommand| +% \NewDocumentCommand| +% \RenewDocumentCommand| +% \ProvideDocumentCommand +%} +% \begin{syntax} +% "\DeclareDocumentCommand" <function> \Arg{arg spec} \Arg{code} +% \end{syntax} +% This family of commands are used to create a document-level +% <function>. The argument specification for the function is +% given by <arg spec>, and the function will execute <code>. +% +% As an example: +% \begin{verbatim} +% \DeclareDocumentCommand \chapter { s o m } { +% \IfBooleanTF {#1} { +% \typesetnormalchapter {#2} {#3} +% }{ +% \typesetstarchapter {#3} +% } +% } +% \end{verbatim} +% would be a way to define a \cs{chapter} command which would +% essentially behave like the current \LaTeXe\ command (except that it +% would accept an optional argument even when a \texttt{*} was parsed). +% The \cs{typesetnormalchapter} could test its first argument for being +% \cs{NoValue} to see if an optional argument was present. +% +% The difference between the \cs{Declare\ldots}, \cs{New\ldots} +% \cs{Renew\ldots} and \cs{Provide\ldots} versions is the behaviour +% if <function> is already defined. +% \begin{itemize} +% \item \cs{DeclareDocumentCommand} will always create the new +% definition, irrespective of any existing <function> with the +% same name. +% \item \cs{NewDocumentCommand} will issue an error if <function> +% has already been defined. +% \item \cs{RenewDocumentCommand} will issue an error if <function> +% has not previously been defined. +% \item \cs{ProvideDocumentCommand} creates a new definition for +% <function> only if one has not already been given. +% \end{itemize} +% +% \begin{texnote} +% Unlike \LaTeXe's \cs{newcommand} and relatives, the +% \cs{DeclareDocumentCommand} function do not prevent creation of +% functions with names starting \cs{end\ldots}. +% \end{texnote} +%\end{function} +% +%\begin{function}{% +% \DeclareDocumentEnvironment| +% \NewDocumentEnvironment| +% \RenewDocumentEnvironment| +% \ProvideDocumentEnvironment +%} +% \begin{syntax} +% "\DeclareDocumentEnvironment" \Arg{environment} \Arg{arg spec} +% ~~~~\Arg{start code} \Arg{end code} +% \end{syntax} +% These commands work in the same way as \cs{DeclareDocumentCommand}, +% etc., but create environments (\cs{begin}|{|<function>|}| \ldots +% \cs{end}|{|<function>|}|). Both the <start code> and <end code> +% may access the arguments as defined by <arg spec>. +% +% \begin{texnote} +% When loaded as part of a \LaTeX3 format, these, these commands do +% not create a pair of macros \cs{<environment>} and +% \cs{end<environment>}. Thus \LaTeX3 environments have to be +% accessed using the \cs{begin} \ldots \cs{end} mechanism. When +% \pkg{xparse} is loaded as a \LaTeXe\ package, \cs{<environment>} +% and \cs{end<environment>} are defined, as this is necessary to +% allow the new environment to work! +% \end{texnote} +%\end{function} +% +%\subsection{Testing special values} +% +% Optional arguments created using \pkg{xparse} make use of dedicated +% variables to return information about the nature of the argument +% received. +% +%\begin{variable}{\NoValue} +% \cs{NoValue} is a special marker returned by \pkg{xparse} if no +% value is given for an optional argument. If typeset (which should +% not happen), it will print the value \texttt{-NoValue-}. +%\end{variable} +% +%\begin{function}{\IfNoValue / (TF) (EXP)} +% \begin{syntax} +% "\IfNoValueTF" \Arg{argument} \Arg{true code} \Arg{false code} +% \end{syntax} +% The \cs{IfNoValue} tests are used to check if <argument> (|#1|, +% |#2|, etc.) is the special \cs{NoValue} token. For example +% \begin{verbatim} +% \DeclareDocumentCommand \foo { o m } { +% \IfNoValueTF {#1} { +% \DoSomethingJustWithMandatoryArgument {#2} +% }{ +% \DoSomethingBothArguments {#1} {#2} +% } +% } +% \end{verbatim} +% will use a different internal function if the optional argument +% is given than if it is not present. +% +% As the \cs{IfNoValue} tests are expandable, it is possible to test +% these values later, for example at the point of typesetting or in +% an expansion context. +%\end{function} +% +%\begin{function}{\IfValue / (TF) (EXP)} +% \begin{syntax} +% "\IfValueTF" \Arg{argument} \Arg{true code} \Arg{false code} +% \end{syntax} +% The reverse form of the \cs{IfNoValue(TF)} tests are also available +% as \cs{IfValue(TF)}. The context will determine which logical +% form makes the most sense for a given code senario. +%\end{function} +% +%\begin{variable}{ +% \BooleanFalse| +% \BooleanTrue +%} +% The \texttt{true} and \texttt{false} flags set when searching for +% an optional token (using \texttt{s} or \texttt{t}<token>) have +% names which are accessible outside of code blocks. +%\end{variable} +% +%\begin{function}{\IfBoolean / (TF) (EXP)} +% \begin{syntax} +% "\IfBooleanTF" <argument> \Arg{true code} \Arg{false code} +% \end{syntax} +% Used to test if <argument> (|#1|, |#2|, etc.) is \cs{BooleanTrue} +% or \cs{BooleanFalse}. For example +% \begin{verbatim} +% \DeclareDocumentCommand \foo { s m } { +% \IfBooleanTF #1 { +% \DoSomethingWithStar {#2} +% }{ +% \DoSomethingWithoutStar {#2} +% } +% } +% \end{verbatim} +% checks for a star as the first argument, then chooses the action to +% take based on this information. +%\end{function} +% +%\subsection{Argument processors} +%\label{sec:processors} +% +% \pkg{xparse} introduces the idea of an argument processor, which is +% applied to an argument \emph{after} it has been grabbed by the +% underlying system but before it is passed to \meta{code}. An argument +% processor can therefore be used to regularise input at an early stage, +% allowing the internal functions to be completely independent of input +% form. Processors are applied to user input and to default values for +% optional arguments, but \emph{not} to the special \cs{NoValue} marker. +% +% Each argument processor is specified by the syntax +% \texttt{>}\marg{processor} in the argument specification. Processors +% are applied from right to left, so that +%\begin{verbatim} +% >{\ProcessorB} >{\ProcessorA} m +%\end{verbatim} +% would apply \cs{ProcessorA} +% followed by \cs{ProcessorB} to the tokens grabbed by the \texttt{m} +% argument. +% +%\begin{variable}{\l_xparse_arg_toks} +% \pkg{xparse} defines a very small set of processor functions. In the +% main, it is anticipated that code writers will want to create their +% own processors. These need to accept one argument, which is the +% tokens as grabbed (or as returned by a previous processor function). +% Processor functions should return the processed argument in the +% variable \cs{l_xparse_arg_toks}. This will always be empty when the +% processor function is called by \pkg{xparse}, even if more than one +% argument processor is applied. +%\end{variable} +% +%\begin{function}{\xparse_process_to_str:n} +% \begin{syntax} +% "\xparse_process_to_str:n" \Arg{grabbed argument} +% \end{syntax} +% The \cs{xparse_process_to_str:n} processor applies the \LaTeX3 +% \cs{tl_to_str:n} function to the <grabbed argument>. For example +% \begin{verbatim} +% \DeclareDocumentCommand \foo { >{\xparse_arg_to_str:n} m } { +% #1 % Which is now detokenized +% } +% \end{verbatim} +%\end{function} +% +%\begin{function}{\xparse_process_comma_split:n} +% \begin{syntax} +% "\xparse_process_comma_split:n" +% ~~~~\Arg{grabbed argument} +% \end{syntax} +% The \cs{xparse_process_comma_split:n} processor splits the +% grabbed argument at the first comma, returning the two +% parts of the result in braces. If no comma is found, the second +% part of the returned value \cs{NoValue}. This function is intended to +% aid the processing of co-ordinate pairs. For example, to create +% a co-ordinate argument which raises an error if not given: +% \begin{verbatim} +% \DeclareDocumentCommand \foo +% { >{\xparse_process_comma_split:n} d() } { +% \IfNoValueTF #1 { +% \ERROR +% }{ +% \foo_internal:nn #1 +% } +% } +% \end{verbatim} +% For the input |\foo(1.1,2.2)|, |#1| here would equal |{1.1}{2.2}|, +% and so \cs{foo_internal:nn} receives exactly the correct number of +% arguments. A similar function which takes an optional co-ordinate +% pair, could be created as: +% \begin{verbatim} +% \DeclareDocumentCommand \foo +% { >{\xparse_process_comma_split:n} D(){0,0} } { +% \foo_internal:nn #1 +% } +% \end{verbatim} +% This illustrates that the processor function will be applied to the +% default value, which therefore includes a comma. +%\end{function} +% +%\subsection{Separating interface and implementation} +% +% One \emph{experimental} idea implemented in \pkg{xparse} is to +% separate out document command intefaces (the argument specification) +% from the implementation (code). This is carried out using a +% pair of functions, \cs{DeclareDocumentCommandInterface} and +% \cs{DeclareDocumentCommandImplementation} +% +%\begin{function}{\DeclareDocumentCommandInterface} +% \begin{syntax} +% "\DeclareDocumentCommandInterface" <function> +% ~~~~\Arg{implementation} \Arg{arg.~spec} +% \end{syntax} +% This declares a <function>, which will take arguments as detailed +% in the <arg.~spec>. When executed, the <function> will look for +% code stored as an <implementation>. +%\end{function} +% +%\begin{function}{\DeclareDocumentCommandImplementation} +% \begin{syntax} +% "\DeclareDocumentCommandImplementation" +% ~~~~\Arg{implementation} <args> \Arg{code} +% \end{syntax} +% Declares the <implementation> for a function to accept <args> +% arguments and expand to <code>. An implementation must take the +% same number of arguments as a linked interface, although this is not +% enforced by the code. +%\end{function} +% +%\subsection{Fully-expandable document commands} +% +% There are \emph{very rare} occasion when it may be useful to create +% functions using a fully-expandable argument grabber. To support this, +% \pkg{xparse} can create expandable functions as well as the usual +% robust ones. This imposes a number of restrictions on the nature of +% the arguments accepted by a function, and the code it implements. +% This facility should only be used when \emph{absolutely necessary}; +% if you do not understand when this might be, \emph{do not use these +% functions}! +% +%\begin{function}{\DeclareExpandableDocumentCommand} +% \begin{syntax} +% "\DeclareExpandableDocumentCommand" +% ~~~~<function> \Arg{arg spec} \Arg{code} +% \end{syntax} +% This command is used to create a document-level <function>, +% which will grab its arguments in a fully-expandable manner. The +% argument specification for the function is given by <arg spec>, +% and the function will execute <code>. In general, <code> will +% also be fully expandable, although it is possible that this will +% not be the case (for example, a function for use in a table might +% expand so that \cs{omit} is the first non-expandable token). +% +% Parsing arguments expandably imposes a number of restrictions on +% both the type of arguments that can be read and the error checking +% available: +% \begin{itemize} +% \item The function must have at least one mandatory argument, and +% in particular the last argument must be one of the mandatory +% types (\texttt{l}, \texttt{m} or \texttt{u}). +% \item All arguments are either short or long: it is not possible +% to mix short and long argument types. +% \item The `optional group' argument types \texttt{g} and +% \texttt{G} are not available. +% \item It is not possible to differentiate between, for example +% |\foo[| and |\foo{[}|: in both cases the \texttt{[} will be +% interpretted as the start of an optional argument. As a result +% result, checking for optional arguments is less robust than +% in the standard version. +% \end{itemize} +% \pkg{xparse} will issue an error if an argument specifier is given +% which does not conform to the first three requirements. The last +% item is an issue when the function is used, and so is beyond the +% scope of \pkg{xparse} itself. +%\end{function} +% +%\subsection{Variables and constants} +% +%\begin{variable}{\c_xparse_shorthands_prop} +% Shorthands and replacement text: set up at the start of the package, +% and not be be altered later! +%\end{variable} +% +%\begin{variable}{\l_xparse_args_toks} +% Token register for arguments as they are picked up for passing on to +% user functions. +%\end{variable} +% +%\begin{variable}{\l_xparse_environment_args_toks} +% Token register to pass arguments to the end of an environment from +% the beginning. +%\end{variable} +% +%\begin{variable}{\l_xparse_error_bool} +% For flagging up errors when making expandable commands. +%\end{variable} +% +%\begin{variable}{\l_xparse_function_tl} +% Needed to pass along the function name when creating in an expandable +% manner. This is needed as a series of functions have to be created +% when making expandable functions. (In contrast, standard robust +% functions need at most two functions.) +%\end{variable} +% +%\begin{variable}{\l_xparse_last_arg_tl} +% The last argument type added. As this must be mandatory when creating +% expandable commands, this variable is needed to enforce this +% behaviour. +%\end{variable} +% +%\begin{variable}{\l_xparse_long_bool} +% Flag used to indicate creation of \cs{long} arguments. +%\end{variable} +% +%\begin{variable}{\l_xparse_m_args_int} +% Used to enumerate the \texttt{m} arguments with no modifications +% (i.e., neither long nor processed after grabbing). +%\end{variable} +% +%\begin{variable}{\l_xparse_m_only_bool} +% Flag used to indicate that all arguments are of type \texttt{m}, +% with no no modificiations. +%\end{variable} +% +%\begin{variable}{\l_xparse_mandatory_args_int} +% For counting up all mandatory arguments so that the code can tell +% when optional arguments come after the last mandatory one. Counts +% down again as mandatory arguments are added to the signature, so will +% be zero for any trailing optional arguments. +%\end{variable} +% +%\begin{variable}{\l_xparse_processor_bool} +% When converting an argument specification into a signature there is +% a need to know if there are any argument processors set up. This is +% used to tell if \texttt{m} arguments can simply be counted up or need +% handling on a one-off basis. +%\end{variable} +% +%\begin{variable}{\l_xparse_processor_int} +% Each time a processor is set up in the grabber routine, it is stored +% and the total number of processors is recorded here. Later, the +% variable is counted back down to use the processors in reverse order +% to the collection order. +%\end{variable} +% +%\begin{variable}{\l_xparse_signature_toks} +% For constucting the signature of the function defined. As +% \pkg{xparse} works thorugh an argument specification, grabber +% functions are added to this toks for each argument. +%\end{variable} +% +%\begin{variable}{\l_xparse_tmp_tl} +% Scratch space, used for example to convert shorthand argument types +% into the full versions. +%\end{variable} +% +%\begin{variable}{\l_xparse_total_args_int} +% Used to enumerate the total number of arguments (i.e., the number of +% ingroup letters in the argument specification). +%\end{variable} +% +%\begin{variable}{\q_xparse_stop} +% A private delimiting quark: needed by the expandable function system. +%\end{variable} +% +%\subsection{Internal functions} +% +%\begin{function}{\xparse_add_arg:n} +% \begin{syntax} +% "\xparse_add_arg:n" <grabbed arg> +% \end{syntax} +% Adds <grabbed arg> to the output \pkg{xparse} supplies to the +% defined <code>, applying any post-processing that is needed. +%\end{function} +% +%\begin{function}{ +% \xparse_add_grabber_mandatory:N| +% \xparse_add_grabber_optional:N +%} +% \begin{syntax} +% "\xparse_add_grabber_mandatory:N" <grabber type> +% \end{syntax} +% Adds appropriate grabber for <grabber type> to the signature +% being constructed, making it long if necessary. The +% \texttt{optional} version includes a second check to see if space +% skipping should be on or off. +%\end{function} +% +%\begin{function}{ +% \xparse_add_type_+:w| +% \xparse_add_type_>:w| +% \xparse_add_type_d:w| +% \xparse_add_type_D:w| +% \xparse_add_type_g:w| +% \xparse_add_type_G:w| +% \xparse_add_type_l:w| +% \xparse_add_type_m:w| +% \xparse_add_type_t:w| +% \xparse_add_type_u:w +%} +% \begin{syntax} +% "\xparse_add_type_u:w" +% \end{syntax} +% Carry out necessary processes to add given <type> of argument to +% the signature being constructed. Depending on the argument type +% being added, one or more arguments will be absorbed. +%\end{function} +% +%\begin{function}{\xparse_check_and_add:N} +% \begin{syntax} +% "\xparse_check_and_add:N" <arg spec> +% \end{syntax} +% Ensures that <arg spec> is valid, and if so adds it to the signature +% being constructed. +%\end{function} +% +%\begin{function}{ +% \xparse_count_mandatory:n| +% \xparse_count_mandatory:N +%} +% \begin{syntax} +% "\xparse_count_mandatory:N" <arg spec> +% \end{syntax} +% Used to count how many mandatory arguments an argument specification +% contains. The \texttt{n} function carries out the set up, before +% handing of to the \texttt{N} function. This reads one token, and +% calls the approriate counter function. +%\end{function} +% +%\begin{function}{ +% \xparse_count_type_>:w| +% \xparse_count_type_+:w| +% \xparse_count_type_d:w| +% \xparse_count_type_D:w| +% \xparse_count_type_g:w| +% \xparse_count_type_G:w| +% \xparse_count_type_l:w| +% \xparse_count_type_m:w| +% \xparse_count_type_t:w| +% \xparse_count_type_u:w| +%} +% \begin{syntax} +% "\xparse_count_type_D:w" +% \end{syntax} +% Used to count up mandatory arguments: one function for each argument +% type so that a simple loop can be used. Only the functions for +% mandatory arguments do any more than call the loop again. +%\end{function} +% +%\begin{function}{ +% \xparse_declare_cmd:Nnn| +% \xparse_declare_cmd:cnn +%} +% \begin{syntax} +% "\xparse_declare_cmd:Nnn" <function> \Arg{signature} +% ~~~~\Arg{code} +% \end{syntax} +% Declares <function> using <signature> for argument definition and +% <code> as expansion. +% \begin{texnote} +% This is the internal name for \cs{DeclareDocumentCommand}. +% \end{texnote} +%\end{function} +% +%\begin{function}{\xparse_declare_cmd_interface:Nnn} +% \begin{syntax} +% "\xparse_declare_cmd_interface:Nnn" <function> +% ~~~~\Arg{implementation} \Arg{signature} +% \end{syntax} +% Declares <function> using <signature>, which should have code stored +% as <implementation>. +% \begin{texnote} +% This is the internal name for \cs{DeclareDocumentCommandInterface}. +% \end{texnote} +%\end{function} +% +%\begin{function}{\xparse_declare_cmd_implementation:nNn} +% \begin{syntax} +% "\xparse_declare_cmd_implementation:nNn" +% ~~~~\Arg{implementation} <number> \Arg{code} +% \end{syntax} +% Declares <code> taking <number> arguments as an <implementation>, +% to be accessed using an interface defined elsewhere. +% \begin{texnote} +% This is the internal name for +% \cs{DeclareDocumentCommandImplementation}. +% \end{texnote} +%\end{function} +% +%\begin{function}{\xparse_declare_env:nnnn} +% \begin{syntax} +% "\xparse_declare_env:nnnn" \Arg{env} \Arg{arg spec} +% ~~~~\Arg{start code} \Arg{end code} +% \end{syntax} +% Declares <env> as an environment taking <arg spec> arguments +% at \cs{begin}\{<env>\}. The <start code> is eceutre at the beginning +% of the environment, and the <end code> at the end. Both parts may +% use the arguments defined by <arg spec>. +% \begin{texnote} +% This is the internal name for \cs{DeclareDocumentEnvironment}. +% \end{texnote} +%\end{function} +% +%\begin{function}{\xparse_flush_m_args:} +% \begin{syntax} +% "\xparse_flush_m_args:" +% \end{syntax} +% Adds an outstanding \texttt{m} arguments to the signature. +%\end{function} +% +%\begin{function}{\xparse_grab_arg:w} +% \begin{syntax} +% "\xparse_grab_arg:w" <args> +% \end{syntax} +% Function re-defined each time an argument is grabbed to actually +% do the grabbing. It is this function which will raise an error if +% an argument runs away. +%\end{function} +% +%\begin{function}{ +% \xparse_grab_D:w | +% \xparse_grab_D_long:w | +% \xparse_grab_D_trailing:w | +% \xparse_grab_D_long_trailing:w| +% \xparse_grab_G:w | +% \xparse_grab_G_long:w | +% \xparse_grab_G_trailing:w | +% \xparse_grab_G_long_trailing:w| +% \xparse_grab_l:w | +% \xparse_grab_l_long:w | +% \xparse_grab_m:w | +% \xparse_grab_m_long:w | +% \xparse_grab_m_1:w | +% \xparse_grab_m_2:w | +% \xparse_grab_m_3:w | +% \xparse_grab_m_4:w | +% \xparse_grab_m_5:w | +% \xparse_grab_m_6:w | +% \xparse_grab_m_7:w | +% \xparse_grab_m_8:w | +% \xparse_grab_t:w | +% \xparse_grab_t_long:w | +% \xparse_grab_t_trailing:w | +% \xparse_grab_t_long_trailing:w| +% \xparse_grab_u:w | +% \xparse_grab_u_long:w | +%} +% \begin{syntax} +% "\xparse_grab_D:w" <arg data> "\l_xparse_args_toks" +% \end{syntax} +% Argument grabbing functions, which re-arrange other <arg data> +% so that the argument is read correctly. The \texttt{trailing} +% versions do not skip spaces when searching for optional arguments. +% For each argument type, the various versions feed the approriate +% information to a common auxiliary function which then sets up +% \cs{xparse_grab_arg:w} to actually carry out the argument absorption. +%\end{function} +% +%\begin{function}{\xparse_if_no_value:n / (TF) (EXP)} +% \begin{syntax} +% "\xparse_if_no_value:nTF" \Arg{arg} +% ~~~~\Arg{true code} \Arg{false code} +% \end{syntax} +% Executes <true code> if <arg> is equal to the special +% \cs{NoValue} marker and <false code> otherwise. Provided that +% the primitive \cs{(pdf)strcmp} is available, this function is +% expandable. +%\end{function} +% +%\begin{function}{ +% \xparse_prepare_signature:n| +% \xparse_prepare_signature:N +%} +% \begin{syntax} +% "\xparse_prepare_signature:n" \Arg{arg specs} +% \end{syntax} +% Parse one or more <arg specs> and convert to an output <signature>. +%\end{function} +% +%\begin{function}{\xparse_process_arg:n} +% \begin{syntax} +% "\xparse_process_arg:n" \Arg{processor} +% \end{syntax} +% Sets up code to apply <processor> to next grabbed argument. +%\end{function} +% +%\subsection{Creating expandable commands} +% +%\begin{function}{ +% \xparse_exp_add_type_d:w| +% \xparse_exp_add_type_D:w| +% \xparse_exp_add_type_l:w| +% \xparse_exp_add_type_m:w| +% \xparse_exp_add_type_t:w| +% \xparse_exp_add_type_u:w +%} +% \begin{syntax} +% "\xparse_exp_add_type_u:w" \Arg{delimiter} +% \end{syntax} +% Carry out necessary processes to add given <type> of argument for +% an expandable command. Depending on the argument type being added, +% one or more arguments will be absorbed. +%\end{function} +% +%\begin{function}{\xparse_exp_check_and_add:N} +% \begin{syntax} +% "\xparse_exp_check_and_add:N" <arg spec> +% \end{syntax} +% Ensures that <arg spec> is valid, and if so adds it to expandable +% function being constructed. +%\end{function} +% +%\begin{function}{\xparse_exp_declare_cmd:Nnn} +% \begin{syntax} +% "\xparse_exp_declare_cmd:Nnn" <function> \Arg{signature} +% ~~~~\Arg{code} +% \end{syntax} +% Declares <function> using <signature> for argument definition and +% <code> as expansion, and creating an expandable command. +% \begin{texnote} +% This is the internal name for +% \cs{DeclareExpandableDocumentCommand}. +% \end{texnote} +%\end{function} +% +%\begin{function}{ +% \xparse_exp_prepare_function:n| +% \xparse_exp_prepare_function:N +%} +% \begin{syntax} +% "\xparse_exp_prepare_function:n" \Arg{arg specs} +% \end{syntax} +% Parse one or more <arg specs> and convert to an expandable +% function. +%\end{function} +% +%\begin{function}{\xparse_exp_set:cpx} +% \begin{syntax} +% "\xparse_exp_set:cpx" <csname> <parameters> \Arg{code} +% \end{syntax} +% An alias for either \cs{cs_set:cpx} or \cs{cs_set_nopar:cpx}, +% depending on the \cs{long} status of the expandable function. +%\end{function} +% +%\end{documentation} +% +%\begin{implementation} +% +%\section{\pkg{xparse} implementation} +% +% The usual lead-off: only needed for the package, of course (one day we +% may have a \LaTeX3 kernel). +% \begin{macrocode} +%<*package> +\ProvidesExplPackage + {\filename}{\filedate}{\fileversion}{\filedescription} +\RequirePackage{expl3} +%</package> +%<*initex|package> +% \end{macrocode} +% +%\subsection{Variables and constants} +% +%\begin{macro}{\c_xparse_shorthands_prop} +% Shorthands are stored as a property list: this is set up here as it +% is a constant. +% \begin{macrocode} +\prop_new:N \c_xparse_shorthands_prop +\prop_put:Nnn \c_xparse_shorthands_prop { o } { d[] } +\prop_put:Nnn \c_xparse_shorthands_prop { O } { D[] } +\prop_put:Nnn \c_xparse_shorthands_prop { s } { t* } +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\l_xparse_arg_toks} +% Token registers for single grabbed argument when post-processing. +% \begin{macrocode} +\toks_new:N \l_xparse_arg_toks +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\l_xparse_args_toks} +% Token registers for grabbed arguments. +% \begin{macrocode} +\toks_new:N \l_xparse_args_toks +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\l_xparse_environment_args_toks} +% Used to pass arguments to the end of an environment. +% \begin{macrocode} +\toks_new:N \l_xparse_environment_args_toks +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\l_xparse_error_bool} +% Used to signal an error when creating expandable functions. +% \begin{macrocode} +\bool_new:N \l_xparse_error_bool +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\l_xparse_function_tl} +% When creating expandable functions, the current function name needs +% to be passed along. +% \begin{macrocode} +\tl_new:N \l_xparse_function_tl +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\l_xparse_last_arg_tl} +% Used when creating expandable arguments. +% \begin{macrocode} +\toks_new:N \l_xparse_last_arg_tl +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\l_xparse_long_bool} +% A flag for \cs{long} arguments. +% \begin{macrocode} +\bool_new:N \l_xparse_long_bool +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\l_xparse_m_args_int} +% The number of simple \texttt{m} arguments is tracked so they can be +% dumped \emph{en masse}. +% \begin{macrocode} +\int_new:N \l_xparse_m_args_int +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\l_xparse_m_only_bool} +% A flag to indicate that only \texttt{m} arguments have been found. +% \begin{macrocode} +\bool_new:N \l_xparse_m_only_bool +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\l_xparse_mandatory_args_int} +% So that trailing optional arguments can be picked up, a count has to +% be taken of all mandatory arguments. This is then decreased as +% mandatory arguments are added to the signature, so will be zero +% only if there are no more mandatory arguments to add. +% \begin{macrocode} +\int_new:N \l_xparse_mandatory_args_int +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\l_xparse_processor_bool} +% When reading through the argument specifier, a flag is needed to +% show that a processor has been found for the current argument. This +% is used when checking how to handle \texttt{m} arguments. +% \begin{macrocode} +\bool_new:N \l_xparse_processor_bool +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\l_xparse_processor_int} +% In the grabber routine, each processor is saved with a number +% recording the order it was found in. The total is then used to work +% back through the grabbers so they apply to the argument right to left. +% \begin{macrocode} +\int_new:N \l_xparse_processor_int +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\l_xparse_signature_toks} +% Token registers for constructing signatures. +% \begin{macrocode} +\toks_new:N \l_xparse_signature_toks +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\l_xparse_tmp_tl} +% A general purpose token list variable. +% \begin{macrocode} +\tl_new:N \l_xparse_tmp_tl +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\l_xparse_total_args_int} +% Thje total number of arguments is used to create the internal function +% which has a fixed number of arguments. +% \begin{macrocode} +\int_new:N \l_xparse_total_args_int +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\q_xparse_stop} +% A private quark, used for delimiting arguments when making +% expandable functions. +% \begin{macrocode} +\quark_new:N \q_xparse_stop +% \end{macrocode} +%\end{macro} +% +%\subsection{Turning the argument specifier into grabbers} +% +%\begin{macro}{\xparse_add_grabber_mandatory:N} +%\begin{macro}{\xparse_add_grabber_optional:N} +% To keep the various checks needed in one place, adding the grabber to +% the signature is done here. For mandatory arguments, the only question +% is whether to add a long grabber. For optional arguments, there is +% also a check to see if any mandatory arguments are still to be added. +% This is used to determine whether to skip spaces or not where +% searching for the argument. +% \begin{macrocode} +\cs_new_nopar:Nn \xparse_add_grabber_mandatory:N { + \toks_put_right:Nx \l_xparse_signature_toks { + \exp_not:c { + xparse_grab_ #1 \bool_if:NT \l_xparse_long_bool { _long } :w + } + } + \bool_set_false:N \l_xparse_long_bool + \int_decr:N \l_xparse_mandatory_args_int +} +\cs_new_nopar:Nn \xparse_add_grabber_optional:N { + \toks_put_right:Nx \l_xparse_signature_toks { + \exp_not:c { + xparse_grab_ #1 + \bool_if:NT \l_xparse_long_bool { _long } + \intexpr_compare:nF { + \l_xparse_mandatory_args_int > \c_zero + } { _trailing } + :w + } + } + \bool_set_false:N \l_xparse_long_bool +} +% \end{macrocode} +%\end{macro} +%\end{macro} +% +% All of the argument-adding functions work in essentially the same +% way, except the one for \texttt{m} arguments. Any collected \texttt{m} +% arguments are added to the signature, then the appropriate grabber +% is added to the signature. Some of the adding functions also pick up +% one or more arguments, and are also added to the signature. All of the +% functions then call the loop function \cs{xparse_prepare_signature:N}. +% +%\begin{macro}{\xparse_add_type_+:w} +% Making the next argument \cs{long} means setting the flag and +% knocking one back off the totatl argument count. The \texttt{m} +% arguments are recorded here as this has to be done for every case +% where there is then a \cs{long} argument. +% \begin{macrocode} +\cs_new_nopar:cpn { xparse_add_type_+:w } { + \xparse_flush_m_args: + \bool_set_true:N \l_xparse_long_bool + \bool_set_false:N \l_xparse_m_only_bool + \int_decr:N \l_xparse_total_args_int + \xparse_prepare_signature:N +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\xparse_add_type_>:w} +% When a processor is found, the function \cs{xparse_process_arg:n} +% is added to the signature along with the processor code itself. When +% the signature is used, the code will be added to an excution list by +% \cs{xparse_process_arg:n}. Here, the loop calls +% \cs{xparse_prepare_signature_aux:N} rather than +% \cs{xparse_prepare_signature:N} so that the flag is not reset. +% \begin{macrocode} +\cs_new:cpn { xparse_add_type_>:w } #1 { + \bool_set_true:N \l_xparse_processor_bool + \xparse_flush_m_args: + \int_decr:N \l_xparse_total_args_int + \toks_put_right:Nn \l_xparse_signature_toks { + \xparse_process_arg:n {#1} + } + \xparse_prepare_signature_aux:N +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\xparse_add_type_d:w} +% To save on repeated code, \texttt{d} is actually turned into +% the same grabber as is used by \texttt{D}, by putting the +% \cs{NoValue} default in the correct place. So there is some +% simple argument re-arrangement to do. Remember that |#1| and |#2| +% shoudl be single tokens. +% \begin{macrocode} +\cs_new:Npn \xparse_add_type_d:w #1#2 { + \xparse_add_type_D:w #1 #2 { \NoValue } +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\xparse_add_type_D:w} +% All of the optional delimited arguments are handled internally by +% the \texttt{D} type. At this stage, the two delimiters are stored +% along with the default value. +% \begin{macrocode} +\cs_new:Npn \xparse_add_type_D:w #1#2#3 { + \xparse_flush_m_args: + \xparse_add_grabber_optional:N D + \toks_put_right:Nn \l_xparse_signature_toks { #1 #2 {#3} } + \xparse_prepare_signature:N +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\xparse_add_type_g:w} +% The \texttt{g} type is simply an alias for \texttt{G} with the +% correct default built-in. +% \begin{macrocode} +\cs_new_nopar:Npn \xparse_add_type_g:w { + \xparse_add_type_G:w { \NoValue } +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\xparse_add_type_G:w} +% For the \texttt{G} type, the grabber and the default are added to +% the signature. +% \begin{macrocode} +\cs_new:Npn \xparse_add_type_G:w #1 { + \xparse_flush_m_args: + \xparse_add_grabber_optional:N G + \toks_put_right:Nn \l_xparse_signature_toks { {#1} } + \xparse_prepare_signature:N +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\xparse_add_type_l:w} +% Finding \texttt{l} arguments is very simple: there is nothing to do +% other than add the grabber. +% \begin{macrocode} +\cs_new_nopar:Npn \xparse_add_type_l:w { + \xparse_flush_m_args: + \xparse_add_grabber_mandatory:N l + \xparse_prepare_signature:N +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\xparse_add_type_m:w} +% The \texttt{m} type is special as short arguments which are not +% post-processed are simply counted at this stage. Thus there is a check +% to see if either of these cases apply. If so, a one-argument grabber +% is added to the signature. On the other hand, if a standard short +% argument is required it is simply counted at this stage, to be +% added later using \cs{xparse_flush_m_args:}. +% \begin{macrocode} +\cs_new_nopar:Npn \xparse_add_type_m:w { + \bool_if:nTF { + \l_xparse_long_bool || \l_xparse_processor_bool + } { + \xparse_flush_m_args: + \xparse_add_grabber_mandatory:N m + }{ + \int_incr:N \l_xparse_m_args_int + } + \xparse_prepare_signature:N +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\xparse_add_type_t:w} +% Setting up a \texttt{t} argument means collecting one token for the +% test, and adding it along with the grabber to the signature. +% \begin{macrocode} +\cs_new:Npn \xparse_add_type_t:w #1 { + \xparse_flush_m_args: + \xparse_add_grabber_optional:N t + \toks_put_right:Nn \l_xparse_signature_toks { #1 } + \xparse_prepare_signature:N +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\xparse_add_type_u:w} +% At the set up stage, the \texttt{u} type argument is identical to the +% \texttt{G} type except for the name of the grabber function. +% \begin{macrocode} +\cs_new:Npn \xparse_add_type_u:w #1 { + \xparse_flush_m_args: + \xparse_add_grabber_mandatory:N u + \toks_put_right:Nn \l_xparse_signature_toks { {#1} } + \xparse_prepare_signature:N +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\xparse_check_and_add:N} +% This function checks if the argument type actually exists and gives +% an error if it doesn't. +% \begin{macrocode} +\cs_new_nopar:Nn \xparse_check_and_add:N { + \cs_if_free:cTF { xparse_add_type_ #1 :w } { + \msg_error:nnx { xparse } { unknown-argument-type } {#1} + \xparse_add_type_m:w + }{ + \use:c { xparse_add_type_ #1 :w } + } +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\xparse_count_mandatory:n} +%\begin{macro}{\xparse_count_mandatory:N} +%\begin{macro}[aux]{\xparse_count_mandatory_aux:N} +% To count up mandatory arguments before the main parsing run, the +% same approach is used. First, check if the current token is a +% shrot-cut for another argument type. If it is, expand it and loop +% again. If not, then look for a `counting' function to check the +% argument type. No error is raised here if one is not found as one +% will be raised by later code. +% \begin{macrocode} +\cs_new:Nn \xparse_count_mandatory:n { + \int_zero:N \l_xparse_mandatory_args_int + \xparse_count_mandatory:N #1 \q_nil +} +\cs_new:Nn \xparse_count_mandatory:N { + \quark_if_nil:NF #1 { + \prop_if_in:NnTF \c_xparse_shorthands_prop {#1} { + \prop_get:NnN \c_xparse_shorthands_prop {#1} \l_xparse_tmp_tl + \exp_last_unbraced:NV \xparse_count_mandatory:N \l_xparse_tmp_tl + }{ + \xparse_count_mandatory_aux:N #1 + } + } +} +\cs_new:Nn \xparse_count_mandatory_aux:N { + \cs_if_free:cTF { xparse_count_type_ #1 :w } { + \xparse_count_type_m:w + }{ + \use:c { xparse_count_type_ #1 :w } + } +} +% \end{macrocode} +%\end{macro} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\xparse_count_type_>:w} +%\begin{macro}{\xparse_count_type_+:w} +%\begin{macro}{\xparse_count_type_d:w} +%\begin{macro}{\xparse_count_type_D:w} +%\begin{macro}{\xparse_count_type_g:w} +%\begin{macro}{\xparse_count_type_G:w} +%\begin{macro}{\xparse_count_type_l:w} +%\begin{macro}{\xparse_count_type_m:w} +%\begin{macro}{\xparse_count_type_t:w} +%\begin{macro}{\xparse_count_type_u:w} +% For counting the mandatory arguments, a function is provided for +% each argument type that will mop any extra arguments and call the +% loop function. Only the counting functions for mandatory arguments +% actually do anything: the rest are simply there to ensure the loop +% continues correctly. +% \begin{macrocode} +\cs_new:cpn { xparse_count_type_>:w } #1 { + \xparse_count_mandatory:N +} +\cs_new_nopar:cpn { xparse_count_type_+:w } { + \xparse_count_mandatory:N +} +\cs_new:Npn \xparse_count_type_d:w #1#2 { + \xparse_count_mandatory:N +} +\cs_new:Npn \xparse_count_type_D:w #1#2#3 { + \xparse_count_mandatory:N +} +\cs_new_nopar:Npn \xparse_count_type_g:w { + \xparse_count_mandatory:N +} +\cs_new:Npn \xparse_count_type_G:w #1 { + \xparse_count_mandatory:N +} +\cs_new_nopar:Npn \xparse_count_type_l:w { + \int_incr:N \l_xparse_mandatory_args_int + \xparse_count_mandatory:N +} +\cs_new_nopar:Npn \xparse_count_type_m:w { + \int_incr:N \l_xparse_mandatory_args_int + \xparse_count_mandatory:N +} +\cs_new:Npn \xparse_count_type_t:w #1 { + \xparse_count_mandatory:N +} +\cs_new:Npn \xparse_count_type_u:w #1 { + \int_incr:N \l_xparse_mandatory_args_int + \xparse_count_mandatory:N +} +% \end{macrocode} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\xparse_declare_cmd:Nnn} +%\begin{macro}{\xparse_declare_cmd:cnn} +%\begin{macro}[aux]{\xparse_declare_cmd_all_m:Nn} +%\begin{macro}[aux]{\xparse_declare_cmd_mixed:Nn} +% First, the signature is set up from the argument specification. There +% is then a check: if only \texttt{m} arguments are needed (which +% includes functions with no arguments at all) then the definition is +% simple. On the other hand, if the signature is more complex then an +% internal function actually contains the code with the user function +% as a simple wrapper. +% \begin{macrocode} +\cs_new:Nn \xparse_declare_cmd:Nnn { + \xparse_count_mandatory:n {#2} + \xparse_prepare_signature:n {#2} + \bool_if:NTF \l_xparse_m_only_bool { + \xparse_declare_cmd_all_m:Nn #1 {#3} + }{ + \xparse_declare_cmd_mixed:Nn #1 {#3} + } +} +\cs_generate_variant:Nn \xparse_declare_cmd:Nnn { cnn } +\cs_new:Nn \xparse_declare_cmd_all_m:Nn { + \cs_generate_from_arg_count:NNnn + #1 \cs_set_protected_nopar:Npn \l_xparse_total_args_int {#2} +} +\cs_new:Nn \xparse_declare_cmd_mixed:Nn { + \cs_set_protected_nopar:Npx #1 { + \exp_not:n { + \int_zero:N \l_xparse_processor_int + \toks_set:Nn \l_xparse_args_toks + } { \exp_not:c { \token_to_str:N #1 } } + \toks_use:N \l_xparse_signature_toks + \exp_not:n{ \toks_use:N \l_xparse_args_toks } + } + \cs_generate_from_arg_count:cNnn + { \token_to_str:N #1 } \cs_set:Npn \l_xparse_total_args_int {#2} +} +% \end{macrocode} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\xparse_declare_cmd_implementation:nNn} +% Creating a stand-alone implementation uisn the `two-part' mechanism +% is quite easy as this is just a wrapper for +% \cs{cs_generate_from_arg_count:cNnn}. +% \begin{macrocode} +\cs_new:Nn \xparse_declare_cmd_implementation:nNn { + \cs_generate_from_arg_count:cNnn { implementation_ #1 :w } + \cs_set:Npn {#2} {#3} +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\xparse_declare_cmd_interface:Nnn} +%\begin{macro}[aux]{\xparse_declare_cmd_interface_all_m:Nn} +%\begin{macro}[aux]{\xparse_declare_cmd_interface_mixed:Nn} +% As with the basic function \cs{xparse_declare_cmd:Nnn}, there are +% three things to do here. First, generate a signature from the +% argument specification. Then use that to create a function which +% will call the implementation part. Finally, a holder implementation +% is created. As before, there is a short-cut for functions which only +% have \texttt{m} type arguments. +% \begin{macrocode} +\cs_new:Nn \xparse_declare_cmd_interface:Nnn { + \xparse_prepare_signature:n {#3} + \bool_if:NTF \l_xparse_m_only_bool { + \xparse_declare_cmd_interface_all_m:Nn #1 {#2} + }{ + \xparse_declare_cmd_interface_mixed:Nn #1 {#2} + } + \cs_generate_from_arg_count:cNnn { implementation_ #2 :w } + \cs_set:Npn \l_xparse_total_args_int { ``#2'' } +} +\cs_new:Nn \xparse_declare_cmd_interface_all_m:Nn { + \cs_generate_from_arg_count:NNnn + #1 \cs_set_protected_nopar:Npn \l_xparse_total_args_int + { \use:c { implementation_ #2 :w } } +} +\cs_new:Nn \xparse_declare_cmd_interface_mixed:Nn { + \cs_set_protected_nopar:Npx #1 { + \exp_not:n { + \int_zero:N \l_xparse_processor_int + \toks_set:Nn \l_xparse_args_toks + } { \exp_not:c { \token_to_str:N #1 } } + \toks_use:N \l_xparse_signature_toks + \exp_not:n{ \toks_use:N \l_xparse_args_toks } + } + \cs_generate_from_arg_count:cNnn + { \token_to_str:N #1 } \cs_set:Npn \l_xparse_total_args_int + { \use:c { implementation_ #2 :w } } +} +% \end{macrocode} +%\end{macro} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\xparse_declare_env:nnnn} +% The idea here is to make sure that the end of the environment has the +% same arguments available as the beginning. +% \begin{macrocode} +\cs_new:Nn \xparse_declare_env:nnnn { + \xparse_declare_cmd:cnn { environment_begin_ #1 :w } {#2} { + \group_begin: + \toks_set_eq:NN \l_xparse_environment_args_toks + \l_xparse_args_toks + #3 + } + \cs_set_nopar:cpx { environment_end_ #1 :w } { + \exp_not:N \exp_last_unbraced:NV + \exp_not:c { environment_end_ #1 _aux:N } + \exp_not:N \l_xparse_environment_args_toks + \exp_not:N \group_end: + } + \cs_set_nopar:cx { environment_end_ #1 _aux:N } { + \exp_not:c { environment_end_ #1 _aux :w } + } + \cs_generate_from_arg_count:cNnn + { environment_end_ #1 _aux :w } \cs_set:Npn + \l_xparse_total_args_int {#4} +%</initex|package> +%<*package> + \cs_set_eq:cc {#1} { environment_begin_ #1 :w } + \cs_set_eq:cc { end #1 } { environment_end_ #1 :w } +%</package> +%<*initex|package> +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\xparse_flush_m_args:} +% As \texttt{m} arguments are simply counted, there is a need to add +% them to the token register in a block. As this function can only +% be called if something other than \texttt{m} turns up, the flag can +% be switched here. The total number of mandatory arguments added to +% the signature is also decreased by the appropriate amount. +% \begin{macrocode} +\cs_new_nopar:Nn \xparse_flush_m_args: { + \cs_if_exist:cT { + xparse_grab_m_ \int_use:N \l_xparse_m_args_int :w + } { + \toks_put_right:Nx \l_xparse_signature_toks { + \exp_not:c { xparse_grab_m_ \int_use:N \l_xparse_m_args_int :w } + } + \int_set:Nn \l_xparse_mandatory_args_int { + \l_xparse_mandatory_args_int - \l_xparse_m_args_int + } + } + \int_zero:N \l_xparse_m_args_int + \bool_set_false:N \l_xparse_m_only_bool +} +% \end{macrocode} +%\end{macro} +% +% +%\begin{macro}[TF]{\xparse_if_no_value:n} +% Tests for \cs{NoValue}. +% \begin{macrocode} +\prg_new_conditional:Nnn \xparse_if_no_value:n { TF,T,F } { + \tl_if_eq:nnTF {#1} { \NoValue } { + \prg_return_true: + }{ + \prg_return_false: + } +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\xparse_prepare_signature:n} +% Creating the signature is a case of working through the input and +% turning into the output in \cs{l_xparse_signature_toks}. A track is +% also kept of the total number of arguments. This function sets +% everything up then hands off to the parser. +% \begin{macrocode} +\cs_new:Nn \xparse_prepare_signature:n { + \bool_set_false:N \l_xparse_long_bool + \int_zero:N \l_xparse_m_args_int + \bool_set_true:N \l_xparse_m_only_bool + \bool_set_false:N \l_xparse_processor_bool + \toks_clear:N \l_xparse_signature_toks + \int_zero:N \l_xparse_total_args_int + \xparse_prepare_signature:N #1 \q_nil +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\xparse_prepare_signature:N} +%\begin{macro}[aux]{\xparse_prepare_signature_aux:N} +% The main signature-preparation loop is in two parts, to keep the code +% a little clearer. Most of the checks here is pretty clear, with a key +% point to watch what is next on the stack so that the loop continues +% correctly. +% \begin{macrocode} +\cs_new:Nn \xparse_prepare_signature:N { + \bool_set_false:N \l_xparse_processor_bool + \xparse_prepare_signature_aux:N #1 +} +\cs_new:Nn \xparse_prepare_signature_aux:N { + \quark_if_nil:NTF #1 { + \bool_if:NF \l_xparse_m_only_bool { + \xparse_flush_m_args: + } + }{ + \prop_if_in:NnTF \c_xparse_shorthands_prop {#1} { + \prop_get:NnN \c_xparse_shorthands_prop {#1} \l_xparse_tmp_tl + \exp_last_unbraced:NV \xparse_prepare_signature:N \l_xparse_tmp_tl + }{ + \int_incr:N \l_xparse_total_args_int + \xparse_check_and_add:N #1 + } + } +} +% \end{macrocode} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\xparse_process_arg:n} +% Processors are saved for use later during the grabbbing process. +% \begin{macrocode} +\cs_new:Nn \xparse_process_arg:n { + \int_incr:N \l_xparse_processor_int + \cs_set:cn { + xparse_processor_ \int_use:N \l_xparse_processor_int :n + } + { #1 {##1} } +} +% \end{macrocode} +%\end{macro} +% +%\subsection{Grabbing arguments} +% +%\begin{macro}{\xparse_add_arg:n} +%\begin{macro}[aux]{\xparse_add_arg_aux:n} +%\begin{macro}[aux]{\xparse_add_arg_aux:V} +% The argument-storing system provides a single point for interfacing +% with processors. They are done in a loop, couning downward. In this +% way, the processor which was found last is executed first. The result +% is that processors apply from right to left, as intended. Notice that +% a set of braces are added back around the result of processing so that +% the internal function will correctly pick up one argument for each +% input argument. +% \begin{macrocode} +\cs_new:Nn \xparse_add_arg:n { + \intexpr_compare:nTF { \l_xparse_processor_int = \c_zero } { + \toks_put_right:Nn \l_xparse_args_toks { {#1} } + }{ + \xparse_if_no_value:nTF {#1} { + \int_zero:N \l_xparse_processor_int + \toks_put_right:Nn \l_xparse_args_toks { {#1} } + }{ + \xparse_add_arg_aux:n {#1} + } + } +} +\cs_new:Nn \xparse_add_arg_aux:n { + \use:c { xparse_processor_ \int_use:N \l_xparse_processor_int :n } + {#1} + \int_decr:N \l_xparse_processor_int + \intexpr_compare:nTF { \l_xparse_processor_int = \c_zero } { + \toks_put_right:No \l_xparse_args_toks { + \exp_after:wN { \toks_use:N \l_xparse_arg_toks } + } + }{ + \xparse_add_arg_aux:V \l_xparse_arg_toks + } +} +\cs_generate_variant:Nn \xparse_add_arg_aux:n { V } +% \end{macrocode} +%\end{macro} +%\end{macro} +%\end{macro} +% +% All of the grabbers follow the same basic pattern. The intial function +% sets u the appropriate information to define \cs{parse_grab_arg:w} to +% grab the argument. This means determining whether to use +% \cs{cs_set:Npn} or \cs{cs_set_nopar:Npn}, and for optional arguments +% whether to skip spaces. In all cases, \cs{xparse_grab_arg:w} is then +% called to actually do the grabbing. +% +%\begin{macro}{\xparse_grab_arg:w} +% Each time an argument is actually grabbed, \pkg{xparse} defines a +% function to do it. In that way, long arguments from previous functions +% can be included in the definition of the grabber function, so that +% it does not raise an error if not long. The generic function used +% for this is reserved here. +% \begin{macrocode} +\cs_new:Npn \xparse_grab_aux:w { } +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\xparse_grab_D:w} +%\begin{macro}{\xparse_grab_D_long:w} +%\begin{macro}{\xparse_grab_D_trailing:w} +%\begin{macro}{\xparse_grab_D_long_trailing:w} +%\begin{macro}[aux]{\xparse_grab_D_aux:NNnnNn} +% The generic delimited argument grabber. The auxiliary function does +% a peek test before calling \cs{xparse_grab_arg:w}, so that the +% optional nature of the argument works as expected. +% \begin{macrocode} +\cs_new:Npn \xparse_grab_D:w #1#2#3#4 \l_xparse_args_toks { + \xparse_grab_D_aux:NNnnNn #1 #2 {#3} {#4} \cs_set_nopar:Npn + { _ignore_spaces } +} +\cs_new:Npn \xparse_grab_D_long:w #1#2#3#4 \l_xparse_args_toks { + \xparse_grab_D_aux:NNnnNn #1 #2 {#3} {#4} \cs_set:Npn + { _ignore_spaces } +} +\cs_new:Npn \xparse_grab_D_trailing:w #1#2#3#4 \l_xparse_args_toks { + \xparse_grab_D_aux:NNnnNn #1 #2 {#3} {#4} \cs_set_nopar:Npn { } +} +\cs_new:Npn \xparse_grab_D_long_trailing:w #1#2#3#4 + \l_xparse_args_toks { + \xparse_grab_D_aux:NNnnNn #1 #2 {#3} {#4} \cs_set:Npn { } +} +\cs_set:Nn \xparse_grab_D_aux:NNnnNn { + #5 \xparse_grab_arg:w #1 ##1 #2 { + \xparse_add_arg:n {##1} + #4 \l_xparse_args_toks + } + \use:c { peek_charcode #6 :NTF } #1 { + \xparse_grab_arg:w + }{ + \xparse_add_arg:n {#3} + #4 \l_xparse_args_toks + } +} +% \end{macrocode} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\xparse_grab_G:w} +%\begin{macro}{\xparse_grab_G_long:w} +%\begin{macro}{\xparse_grab_G_trailing:w} +%\begin{macro}{\xparse_grab_G_long_trailing:w} +%\begin{macro}[aux]{\xparse_grab_G_aux:nnNn} +% Optional groups are checed by meaning, so that the same code will +% work with, for example, Con\TeX{}t-like input. +% \begin{macrocode} +\cs_new:Npn \xparse_grab_G:w #1#2 \l_xparse_args_toks { + \xparse_grab_G_aux:nnNn {#1} {#2} \cs_set_nopar:Npn { _ignore_spaces } +} +\cs_new:Npn \xparse_grab_G_long:w #1#2 \l_xparse_args_toks { + \xparse_grab_G_aux:nnNn {#1} {#2} \cs_set:Npn { _ignore_spaces } +} +\cs_new:Npn \xparse_grab_G_trailing:w #1#2 \l_xparse_args_toks { + \xparse_grab_G_aux:nnNn {#1} {#2} \cs_set_nopar:Npn { } +} +\cs_new:Npn \xparse_grab_G_long_trailing:w #1#2 \l_xparse_args_toks { + \xparse_grab_G_aux:nnNn {#1} {#2} \cs_set:Npn { } +} +\cs_set:Nn \xparse_grab_G_aux:nnNn { + #3 \xparse_grab_arg:w ##1 { + \xparse_add_arg:n {##1} + #2 \l_xparse_args_toks + } + \use:c { peek_meaning #4 :NTF } \c_group_begin_token { + \xparse_grab_arg:w + }{ + \xparse_add_arg:n {#1} + #2 \l_xparse_args_toks + } +} +% \end{macrocode} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\xparse_grab_l:w} +%\begin{macro}{\xparse_grab_l_long:w} +%\begin{macro}[aux]{\xparse_grab_l_aux:nN} +% Argument grabbers for mandatory \TeX\ arguments are pretty simple. +% \begin{macrocode} +\cs_new:Npn \xparse_grab_l:w #1 \l_xparse_args_toks { + \xparse_grab_l_aux:nN {#1} \cs_set_nopar:Npn +} +\cs_new:Npn \xparse_grab_l_long:w #1 \l_xparse_args_toks { + \xparse_grab_l_aux:nN {#1} \cs_set:Npn +} +\cs_new:Nn \xparse_grab_l_aux:nN { + #2 \xparse_grab_arg:w ##1## { + \xparse_add_arg:n \l_xparse_args_toks {##1} + #1 \l_xparse_args_toks + } + \xparse_grab_arg:w +} +% \end{macrocode} +%\end{macro} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\xparse_grab_m:w} +%\begin{macro}{\xparse_grab_m_long:w} +% Collecting a single mandatory argument is quite easy. +% \begin{macrocode} +\cs_new:Npn \xparse_grab_m:w #1 \l_xparse_args_toks { + \cs_set_nopar:Npn \xparse_grab_arg:w ##1 { + \xparse_add_arg:n {##1} + #1 \l_xparse_args_toks + } + \xparse_grab_arg:w +} +\cs_new:Npn \xparse_grab_m_long:w #1 \l_xparse_args_toks { + \cs_set:Npn \xparse_grab_arg:w ##1 { + \xparse_add_arg:n {##1} + #1 \l_xparse_args_toks + } + \xparse_grab_arg:w +} +% \end{macrocode} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\xparse_grab_m_1:w} +%\begin{macro}{\xparse_grab_m_2:w} +%\begin{macro}{\xparse_grab_m_3:w} +%\begin{macro}{\xparse_grab_m_4:w} +%\begin{macro}{\xparse_grab_m_5:w} +%\begin{macro}{\xparse_grab_m_6:w} +%\begin{macro}{\xparse_grab_m_7:w} +%\begin{macro}{\xparse_grab_m_8:w} +% Grabbing 1--8 mandatory arguments. We don't need to worry about +% nine arguments as this is only possible if everything is +% mandatory. Each function has an auxiliary so that \cs{par} tokens +% from other arguments still work. +% \begin{macrocode} +\cs_new:cpn { xparse_grab_m_1:w } #1 \l_xparse_args_toks { + \cs_set_nopar:Npn \xparse_grab_arg:w ##1 { + \toks_put_right:Nn \l_xparse_args_toks { {##1} } + #1 \l_xparse_args_toks + } + \xparse_grab_arg:w +} +\cs_new:cpn { xparse_grab_m_2:w } #1 \l_xparse_args_toks { + \cs_set_nopar:Npn \xparse_grab_arg:w ##1##2 { + \toks_put_right:Nn \l_xparse_args_toks { {##1} {##2} } + #1 \l_xparse_args_toks + } + \xparse_grab_arg:w +} +\cs_new:cpn { xparse_grab_m_3:w } #1 \l_xparse_args_toks { + \cs_set_nopar:Npn \xparse_grab_arg:w ##1##2##3 { + \toks_put_right:Nn \l_xparse_args_toks { {##1} {##2} {##3} } + #1 \l_xparse_args_toks + } + \xparse_grab_arg:w +} +\cs_new:cpn { xparse_grab_m_4:w } #1 \l_xparse_args_toks { + \cs_set_nopar:Npn \xparse_grab_arg:w ##1##2##3##4 { + \toks_put_right:Nn \l_xparse_args_toks { {##1} {##2} {##3} {##4} } + #1 \l_xparse_args_toks + } + \xparse_grab_arg:w +} +\cs_new:cpn { xparse_grab_m_5:w } #1 \l_xparse_args_toks { + \cs_set_nopar:Npn \xparse_grab_arg:w ##1##2##3##4##5 { + \toks_put_right:Nn \l_xparse_args_toks { + {##1} {##2} {##3} {##4} {##5} + } + #1 \l_xparse_args_toks + } + \xparse_grab_arg:w +} +\cs_new:cpn { xparse_grab_m_6:w } #1 \l_xparse_args_toks { + \cs_set_nopar:Npn \xparse_grab_arg:w ##1##2##3##4##5##6 { + \toks_put_right:Nn \l_xparse_args_toks { + {##1} {##2} {##3} {##4} {##5} {##6} + } + #1 \l_xparse_args_toks + } + \xparse_grab_arg:w +} +\cs_new:cpn { xparse_grab_m_7:w } #1 \l_xparse_args_toks { + \cs_set_nopar:Npn \xparse_grab_arg:w ##1##2##3##4##5##6##7 { + \toks_put_right:Nn \l_xparse_args_toks { + {##1} {##2} {##3} {##4} {##5} {##6} {##7} + } + #1 \l_xparse_args_toks + } + \xparse_grab_arg:w +} +\cs_new:cpn { xparse_grab_m_8:w } #1 \l_xparse_args_toks { + \cs_set_nopar:Npn \xparse_grab_arg:w ##1##2##3##4##5##6##7##8 { + \toks_put_right:Nn \l_xparse_args_toks { + {##1} {##2} {##3} {##4} {##5} {##6} {##7} {##8} + } + #1 \l_xparse_args_toks + } + \xparse_grab_arg:w +} +% \end{macrocode} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\xparse_grab_t:w} +%\begin{macro}{\xparse_grab_t_long:w} +%\begin{macro}{\xparse_grab_t_trailing:w} +%\begin{macro}{\xparse_grab_t_long_trailing:w} +%\begin{macro}[aux]{\xparse_grab_t_aux:NnNn} +% Dealing with a token is quite easy. Check the match, remove the +% token if needed and add a flag to the output. +% \begin{macrocode} +\cs_new:Npn \xparse_grab_t:w #1#2 \l_xparse_args_toks { + \xparse_grab_t_aux:NnNn #1 {#2} \cs_set_nopar:Npn { _ignore_spaces } +} +\cs_new:Npn \xparse_grab_t_long:w #1#2 \l_xparse_args_toks { + \xparse_grab_t_aux:NnNn #1 {#2} \cs_set:Npn { _ignore_spaces } +} +\cs_new:Npn \xparse_grab_t_trailing:w #1#2 \l_xparse_args_toks { + \xparse_grab_t_aux:NnNn #1 {#2} \cs_set_nopar:Npn { } +} +\cs_new:Npn \xparse_grab_t_long_trailing:w #1#2 \l_xparse_args_toks { + \xparse_grab_t_aux:NnNn #1 {#2} \cs_set:Npn { } +} +\cs_new:Nn \xparse_grab_t_aux:NnNn { + #3 \xparse_grab_arg:w { + \use:c { peek_charcode_remove #4 :NTF } #1 { + \xparse_add_arg:n { \BooleanTrue } + #2 \l_xparse_args_toks + }{ + \xparse_add_arg:n { \BooleanFalse } + #2 \l_xparse_args_toks + } + } + \xparse_grab_arg:w +} +% \end{macrocode} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\xparse_grab_u:w} +%\begin{macro}{\xparse_grab_u_long:w} +%\begin{macro}[aux]{\xparse_grab_u_aux:NnN} +% Grabbing up to a list of tokens is quite easy: define the grabber, +% and then collect. +% \begin{macrocode} +\cs_new:Npn \xparse_grab_u:w #1#2 \l_xparse_args_toks { + \xparse_grab_u_aux:NnN {#1} {#2} \cs_set_nopar:Npn +} +\cs_new:Npn \xparse_grab_u_long:w #1#2 \l_xparse_args_toks { + \xparse_grab_u_aux:NnN {#1} {#2} \cs_set:Npn +} +\cs_new:Nn \xparse_grab_u_aux:NnN { + #3 \xparse_grab_arg:w ##1 #1 { + \xparse_add_arg:n {##1} + #2 \l_xparse_args_toks + } + \xparse_grab_arg:w +} +% \end{macrocode} +%\end{macro} +%\end{macro} +%\end{macro} +% +%\subsection{Argument processors} +% +%\begin{macro}{\xparse_process_to_str:n} +% A basic argument processor: as much an example as anything else. +% \begin{macrocode} +\cs_new:Nn \xparse_process_to_str:n { + \toks_set:Nx \l_xparse_arg_toks { + \tl_to_str:n {#1} + } +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\xparse_process_comma_split:n} +%\begin{macro}[aux]{\xparse_process_comma_split_aux:w} +% Turns a co-ordinate pair into two separate values. +% \begin{macrocode} +\cs_new:Nn \xparse_process_comma_split:n { + \tl_if_in:nnTF {#1} { , } { + \xparse_process_comma_split_aux:w #1 \q_stop + }{ + \toks_set:Nn \l_xparse_arg_toks { {#1} { \NoValue } } + } +} +\cs_new:Npn \xparse_process_comma_split_aux:w #1 , #2 \q_stop { + \toks_set:Nn \l_xparse_arg_toks { {#1} {#2} } +} +% \end{macrocode} +%\end{macro} +%\end{macro} +% +%\subsection{Creating expandable functions} +% +% The trick here is to pass each grabbed argument along a chain of +% auxiliary functions. Each one ultimately calls the next in the chain, +% so that all of the arguments are passed along delimited using +% \cs{q_xparse_stop}. At the end of the chain, the marker is removed +% so that the user-supplied code can be passed the correct number +% of arguments. All of this is done by expansion! +% +%\begin{macro}{\xparse_exp_add_type_d:w} +% As in the standard case, the trick here is to slot in the default +% and treat as type \texttt{D}. +% \begin{macrocode} +\cs_new:Npn \xparse_exp_add_type_d:w #1#2 { + \xparse_exp_add_type_D:w #1 #2 { \NoValue } +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\xparse_exp_add_type_D:w} +% The most complex argument to grab in an expandable manner is the +% general delimited one. First, a shortcut is set up in +% \cs{l_xparse_tmpa_tl} for the name of the current grabber function. +% This is then created to grab one argument and test if it is equal +% to the opening delimiter. If the test fails, the code adds the default +% value and closing delimiter before `recycling' the argument. In either +% case, the second auxiliary function is called. It finds the closing +% delimiter and so the optional argument (if any). The function then +% calls the next one in the chain, passing along the argument(s) +% grabbed thus-far using \cs{q_xparse_stop} as a marker. +% \begin{macrocode} +\cs_new:Npn \xparse_exp_add_type_D:w #1#2#3 { + \tl_set:Nx \l_xparse_tmpa_tl { + \exp_after:wN \token_to_str:N \l_xparse_function_tl + \int_use:N \l_xparse_total_args_int + } + \xparse_exp_set:cpx { \l_xparse_tmpa_tl } ##1 \q_xparse_stop ##2 { + \exp_not:N \tl_if_head_eq_charcode:nNTF {##2} #1 { + \exp_not:c { \l_xparse_tmpa_tl aux } + ##1 \exp_not:N \q_xparse_stop + }{ + \exp_not:c { \l_xparse_tmpa_tl aux } + ##1 \exp_not:N \q_xparse_stop #3 #2 {##2} + } + } + \xparse_exp_set:cpx { \l_xparse_tmpa_tl aux} + ##1 \q_xparse_stop ##2 #2 { + \exp_not:c { + \exp_after:wN \token_to_str:N \l_xparse_function_tl + \intexpr_eval:n { \l_xparse_total_args_int + 1 } + } ##1 {##2} \exp_not:N \q_xparse_stop + } + \xparse_exp_prepare_function:N +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\xparse_exp_add_type_l:w} +%\begin{macro}{\xparse_exp_add_type_m:w} +% Gathering \texttt{l} and \texttt{m} arguments is almost the same. +% The grabber for the current argument is created to simply get the +% necessary argument and pass it along with any others through to the +% next function in the chain. +% \begin{macrocode} +\cs_new_nopar:Npn \xparse_exp_add_type_l:w { + \xparse_exp_set:cpx { + \exp_after:wN \token_to_str:N \l_xparse_function_tl + \int_use:N \l_xparse_total_args_int + } ##1 \q_xparse_stop ##2## { + \exp_not:c { + \exp_after:wN \token_to_str:N \l_xparse_function_tl + \intexpr_eval:n { \l_xparse_total_args_int + 1 } + } + ##1 {##2} \exp_not:N \q_xparse_stop + } + \xparse_exp_prepare_function:N +} +\cs_new_nopar:Npn \xparse_exp_add_type_m:w { + \int_incr:N \l_xparse_m_args_int + \xparse_exp_set:cpx { + \exp_after:wN \token_to_str:N \l_xparse_function_tl + \int_use:N \l_xparse_total_args_int + } ##1 \q_xparse_stop ##2 { + \exp_not:c { + \exp_after:wN \token_to_str:N \l_xparse_function_tl + \intexpr_eval:n { \l_xparse_total_args_int + 1 } + } + ##1 {##2} \exp_not:N \q_xparse_stop + } + \xparse_exp_prepare_function:N +} +% \end{macrocode} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\xparse_exp_add_type_t:w} +% Looking for a single token is a simpler version of the \texttt{D} +% code. The same idea of picking up one argument is used, but there is +% no need for a second function as there is no closing token to find. So +% either \cs{BooleanTrue} or \cs{BooleanFalse} are added to the list of +% arguments. In the later case, the grabber argument must be `recycled'. +% \begin{macrocode} +\cs_new:Npn \xparse_exp_add_type_t:w #1 { + \tl_set:Nx \l_xparse_tmpa_tl { + \exp_after:wN \token_to_str:N \l_xparse_function_tl + \intexpr_eval:n { \l_xparse_total_args_int + 1 } + } + \xparse_exp_set:cpx { + \exp_after:wN \token_to_str:N \l_xparse_function_tl + \int_use:N \l_xparse_total_args_int + } ##1 \q_xparse_stop ##2 { + \exp_not:N \tl_if_head_eq_charcode:nNTF {##2} #1 { + \exp_not:c { \l_xparse_tmpa_tl } + ##1 \exp_not:n { { \BooleanTrue } \q_xparse_stop } + }{ + \exp_not:c { \l_xparse_tmpa_tl } + ##1 \exp_not:n { { \BooleanFalse } \q_xparse_stop {##2} } + } + } + \xparse_exp_prepare_function:N +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\xparse_exp_add_type_u:w} +% Setting up for a \texttt{u} argument is a case of defining the +% grabber for the current argument in a delimited fashion. The rest of +% the process is as the other grabbers: add to the chain and call the +% next function. +% \begin{macrocode} +\cs_new:Npn \xparse_exp_add_type_u:w #1 { + \xparse_exp_set:cpx { + \exp_after:wN \token_to_str:N \l_xparse_function_tl + \int_use:N \l_xparse_total_args_int + } ##1 \q_xparse_stop ##2 #1 { + \exp_not:c { + \exp_after:wN \token_to_str:N \l_xparse_function_tl + \intexpr_eval:n { \l_xparse_total_args_int + 1 } + } + ##1 {##2} \exp_not:N \q_xparse_stop + } + \xparse_exp_prepare_function:N +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\xparse_exp_check_and_add:N} +% Virtually identical to the normal version, except calling the +% expandable \texttt{add} functions rather than the standard versions. +% \begin{macrocode} +\cs_new_nopar:Nn \xparse_exp_check_and_add:N { + \cs_if_free:cTF { xparse_exp_add_type_ #1 :w } { + \msg_error:nnx { xparse } { unknown-argument-type } {#1} + \tl_set:Nn \l_xparse_last_arg_tl { m } + \xparse_exp_add_type_m:w + }{ + \tl_set:Nn \l_xparse_last_arg_tl {#1} + \use:c { xparse_exp_add_type_ #1 :w } + } +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\xparse_exp_declare_cmd:Nnn} +%\begin{macro}[aux]{\xparse_exp_declare_cmd_all_m:Nn} +%\begin{macro}[aux]{\xparse_exp_declare_cmd_mixed:Nn} +%\begin{macro}[aux]{\xparse_exp_declare_cmd_mixed_aux:Nn} +% The overall scheme here is very different from the standard method. +% For each argument, an internal fucntion is created to grab an argument +% and pass along prevous ones. Each `daisy chains' to call the next +% one in the sequence. Thus at the end of the chain, an extra `argument' +% function is included to unwind the chain and pass data to the the +% internal function containing the actual code. If all of the arguments +% are type \texttt{m}, then the same tick is used as in the standard +% version. The \texttt{x} in the lead-off and mop-up functions makes +% sure that the braces around the first argument are not lost. +% \begin{macrocode} +\cs_new:Nn \xparse_exp_declare_cmd:Nnn { + \tl_set:Nn \l_xparse_function_tl {#1} + \xparse_exp_prepare_function:n {#2} + \intexpr_compare:nTF { + \l_xparse_total_args_int = \l_xparse_m_args_int + } { + \xparse_exp_declare_cmd_all_m:Nn #1 {#3} + }{ + \xparse_exp_declare_cmd_mixed:Nn #1 {#3} + } +} +\cs_new:Nn \xparse_exp_declare_cmd_all_m:Nn { + \bool_if:NTF \l_xparse_long_bool { + \cs_generate_from_arg_count:NNnn + #1 \cs_set:Npn \l_xparse_total_args_int {#2} + }{ + \cs_generate_from_arg_count:NNnn + #1 \cs_set_nopar:Npn \l_xparse_total_args_int {#2} + } +} +\cs_new:Nn \xparse_exp_declare_cmd_mixed:Nn { + \exp_args:NnV \tl_if_in:nnTF { l m u } \l_xparse_last_arg_tl { + \xparse_exp_declare_cmd_mixed_aux:Nn #1 {#2} + }{ + \msg_error:nn { xparse } { expandable-ending-optional } + } +} +\cs_new:Nn \xparse_exp_declare_cmd_mixed_aux:Nn { + \cs_set_nopar:Npx #1 { + \exp_not:c { \token_to_str:N #1 1 } x \exp_not:N \q_xparse_stop + } + \cs_set_nopar:cpx { + \token_to_str:N #1 \intexpr_eval:n { \l_xparse_total_args_int + 1 } + } x ##1 \q_xparse_stop { + \exp_not:c { \token_to_str:N #1 } ##1 + } + \cs_generate_from_arg_count:cNnn + { \token_to_str:N #1 } \cs_set:Npn \l_xparse_total_args_int {#2} +} +% \end{macrocode} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\xparse_exp_prepare_function:n} +%\begin{macro}[aux]{\xparse_exp_prepare_function_aux:n} +% A couple of early validation tests. Processors are forbidden, as are +% \texttt{g}, \texttt{l} and \texttt{u} arguments (the later more for +% ease than any technical reason). +% \begin{macrocode} +\cs_new:Nn \xparse_exp_prepare_function:n { + \bool_set_false:N \l_xparse_error_bool + \tl_if_in:nnT {#1} { > } { + \msg_error:nnx { xparse } { processor-in-expandable } {#1} + \bool_set_true:N \l_xparse_error_bool + } + \tl_if_in:nnT {#1} { g } { + \msg_error:nnx { xparse } { grouped-in-expandable } {#1} + \bool_set_true:N \l_xparse_error_bool + } + \tl_if_in:nnT {#1} { G } { + \msg_error:nnx { xparse } { grouped-in-expandable } {#1} + \bool_set_true:N \l_xparse_error_bool + } + \bool_if:NF \l_xparse_error_bool { + \xparse_exp_prepare_function_aux:n {#1} + } +} +\cs_new:Nn \xparse_exp_prepare_function_aux:n { + \cs_set_eq:NN \xparse_prepare_next:w \xparse_exp_prepare_function:N + \cs_set_eq:NN \xparse_exp_set:cpx \cs_set_nopar:cpx + \bool_set_false:N \l_xparse_long_bool + \int_zero:N \l_xparse_m_args_int + \int_zero:N \l_xparse_total_args_int + \tl_if_in:nnT {#1} { + } { + \bool_set_true:N \l_xparse_long_bool + \cs_set_eq:NN \xparse_exp_set:cpx \cs_set:cpx + } + \xparse_exp_prepare_function:N #1 \q_nil +} +% \end{macrocode} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\xparse_exp_prepare_function:N} +%\begin{macro}[aux]{\xparse_exp_prepare_function_long:N} +%\begin{macro}[aux]{\xparse_exp_prepare_function_short:N} +% Preparing functions is a case of +% \begin{macrocode} +\cs_new:Nn \xparse_exp_prepare_function:N { + \bool_if:NTF \l_xparse_long_bool { + \xparse_exp_prepare_function_long:N #1 + }{ + \xparse_exp_prepare_function_short:N #1 + } +} +\cs_new:Nn \xparse_exp_prepare_function_long:N { + \quark_if_nil:NF #1 { + \tl_if_eq:nnTF {#1} { + } { + \xparse_exp_prepare_function_short:N + }{ + \msg_error:nn { xparse } { inconsistent-long } + \xparse_exp_prepare_function_short:N #1 + } + + } +} +\cs_new:Nn \xparse_exp_prepare_function_short:N { + \quark_if_nil:NF #1 { + \prop_if_in:NnTF \c_xparse_shorthands_prop {#1} { + \prop_get:NnN \c_xparse_shorthands_prop {#1} \l_xparse_tmp_tl + \bool_if:NT \l_xparse_long_bool { + \tl_put_left:Nn \l_xparse_tmp_tl { + } + } + \exp_last_unbraced:NV \xparse_exp_prepare_function:N + \l_xparse_tmp_tl + }{ + \int_incr:N \l_xparse_total_args_int + \xparse_exp_check_and_add:N #1 + } + } +} +% \end{macrocode} +%\end{macro} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\xparse_exp_set:cpx} +% A shortcut to save constantly re-testing \cs{l_xparse_long_bool}. +% \begin{macrocode} +\cs_new_eq:NN \xparse_exp_set:cpx \cs_set_nopar:cpx +% \end{macrocode} +%\end{macro} +% +%\subsection{Messages} +% +% Some error messages. +% \begin{macrocode} +\msg_new:nnnn { xparse } { command-already-defined } {% + Command name `\token_to_str:N #1' already defined!% +}{% + You have used \token_to_str:N \NewDocumentCommand\\% + with a command that already has a definition.\\% + Perhaps you meant \token_to_str:N \RenewDocumentCommand.% +} +\msg_new:nnnn { xparse } { command-not-yet-defined } {% + Command `\token_to_str:N #1' not yet defined!% +}{% + You have used \token_to_str:N \RenewDocumentCommand\\% + with a command that was never defined.\\% + Perhaps you meant \token_to_str:N \NewDocumentCommand.% +} +\msg_new:nnn { xparse } { environment-already-defined } {% + Environment `#1' already defined!% +} +\msg_new:nnn { xparse } { environment-not-yet-defined } {% + Environment `#1' not yet defined!% +} +\msg_new:nnnn { xparse } { expandable-ending-optional } {% + Expandable command signature ends in optional argument.% +}{% + Expandable functions must have a final mandatory argument.% +} +\msg_new:nnnn { xparse } { grouped-in-expandable } {% + Optional grouped arguments cannot be used with expandable functions.% +}{% + Argument specification `#1' contains an optional grouped argument:\\% + this is only supported for standard robust functions.% +} +\msg_new:nnnn { xparse } { inconsistent-long } {% + Inconsistent long arguments.% +}{% + Expandable commands must have all arguments long if any at all.% +} +\msg_new:nnnn { xparse } { processor-in-expandable } {% + Argument processors cannot be used with expandable functions.% +}{% + Argument specification `#1' contains a processor function:\\% + this is only supported for standard robust functions.% +} +\msg_new:nnn { xparse } { unknown-argument-type } {% + Unknown argument type `#1' replaced by `m'. Fingers crossed ...% +} +% \end{macrocode} +% +%\subsection{User functions} +% +% The user functions are more or less just the internal functions +% renamed. +% +%\begin{macro}{\BooleanFalse} +%\begin{macro}{\BooleanTrue} +% Design-space names for the Boolean values. +% \begin{macrocode} +\cs_new_eq:NN \BooleanFalse \c_false_bool +\cs_new_eq:NN \BooleanTrue \c_true_bool +% \end{macrocode} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\DeclareDocumentCommand} +%\begin{macro}{\NewDocumentCommand} +%\begin{macro}{\RenewDocumentCommand} +%\begin{macro}{\ProvideDocumentCommand} +% The user macros are pretty simple wrappers around the internal ones. +% \begin{macrocode} +\xparse_declare_cmd:Nnn \DeclareDocumentCommand { +m +m +m } { + \xparse_declare_cmd:Nnn #1 {#2} {#3} +} +\DeclareDocumentCommand \NewDocumentCommand { +m +m +m } { + \cs_if_exist:NTF #1 { + \msg_error:nnx { xparse } { command-already-defined } {#1} + }{ + \xparse_declare_cmd:Nnn #1 {#2} {#3} + } +} +\NewDocumentCommand \RenewDocumentCommand { +m +m +m } { + \cs_if_exist:NTF #1 { + \xparse_declare_cmd:Nnn #1 {#2} {#3} + }{ + \msg_error:nnx { xparse } { command-not-yet-defined } {#1} + } +} +\NewDocumentCommand \ProvideDocumentCommand { +m +m +m } { + \cs_if_exist:NF #1 { + \xparse_declare_cmd:Nnn #1 {#2} {#3} + } +} +% \end{macrocode} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\DeclareDocumentCommandImplementation} +%\begin{macro}{\DeclareDocumentCommandInterface} +% The separate implementation/interface system is again pretty simple +% to create at the outer layer. +% \begin{macrocode} +\NewDocumentCommand \DeclareDocumentCommandImplementation { m m +m } { + \xparse_declare_cmd_implementation:nNn {#1} #2 {#3} +} +\NewDocumentCommand \DeclareDocumentCommandInterface { m m +m } { + \xparse_declare_cmd_interface:Nnn #1 {#2} {#3} +} +% \end{macrocode} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\DeclareDocumentEnvironment} +%\begin{macro}{\NewDocumentEnvironment} +%\begin{macro}{\RenewDocumentEnvironment} +%\begin{macro}{\ProvideDocumentEnvironment} +% Very similar for environments. +% \begin{macrocode} +\NewDocumentCommand \DeclareDocumentEnvironment { m +m +m +m } { + \xparse_declare_env:nnnn {#1} {#2} {#3} {#4} +} +\NewDocumentCommand \NewDocumentEnvironment { m +m +m +m } { + \cs_if_exist:cTF { environment_begin_ #1 :w } { + \msg_error:nnx { xparse } { environment-already-defined } {#1} + }{ + \xparse_declare_env:nnnn {#1} {#2} {#3} {#4} + } +} +\NewDocumentCommand \RenewDocumentEnvironment { m +m +m +m } { + \cs_if_exist:cTF { environment_begin_ #1 :w } { + \xparse_declare_env:nnnn {#1} {#2} {#3} {#4} + }{ + \msg_error:nnx { xparse } { environment-not-yet-defined } {#1} + } +} +\NewDocumentCommand \ProvideDocumentEnvironment { m +m +m +m } { + \cs_if_exist:cF { environment_begin_ #1 :w } { + \xparse_declare_env:nnnn {#1} {#2} {#3} {#4} + } +} +% \end{macrocode} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\DeclareExpandableDocumentCommand} +% The expanable version of the basic function is essentially the same. +% \begin{macrocode} +\NewDocumentCommand \DeclareExpandableDocumentCommand { +m +m +m } { + \xparse_exp_declare_cmd:Nnn #1 {#2} {#3} +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}[TF]{\IfBoolean} +% The logical \meta{true} and \meta{false} statements are just the +% normal \cs{c_true_bool} and \cs{c_false_bool}, so testing for them is +% done with the \cs{bool_if:NTF} functions from \textsf{l3prg}. +% \begin{macrocode} +\cs_new_eq:NN \IfBooleanTF \bool_if:NTF +\cs_new_eq:NN \IfBooleanT \bool_if:NT +\cs_new_eq:NN \IfBooleanF \bool_if:NF +% \end{macrocode} +%\end{macro} +% +%\begin{macro}[TF]{\IfNoValue} +% Simple re-naming. +% \begin{macrocode} +\cs_new_eq:NN \IfNoValueF \xparse_if_no_value:nF +\cs_new_eq:NN \IfNoValueT \xparse_if_no_value:nT +\cs_new_eq:NN \IfNoValueTF \xparse_if_no_value:nTF +% \end{macrocode} +%\end{macro} +%\begin{macro}[TF]{\IfValue} +% Inverted logic. +% \begin{macrocode} +\cs_set:Npn \IfValueF { \xparse_if_no_value:nT } +\cs_set:Npn \IfValueT { \xparse_if_no_value:nF } +\cs_set:Npn \IfValueTF #1#2#3 { + \xparse_if_no_value:nTF {#1} {#3} {#2} +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\NoValue} +% The marker for no value being give: this can be typeset safely. +% This is coded by hand as making it \cs{protected} ensures that it +% will not turn into anything else by accident. +% \begin{macrocode} +\NewDocumentCommand \NoValue { } { -NoValue- } +% \end{macrocode} +%\end{macro} +% +% \begin{macrocode} +%</initex|package> +% \end{macrocode} +% +% \end{implementation} +% +% \PrintIndex diff --git a/Master/texmf-dist/source/latex/xpackages/xparse.dtx b/Master/texmf-dist/source/latex/xpackages/xparse.dtx deleted file mode 100644 index 8b63e346a6a..00000000000 --- a/Master/texmf-dist/source/latex/xpackages/xparse.dtx +++ /dev/null @@ -1,2151 +0,0 @@ -% \iffalse -%% File: xparse.dtx (C) Copyright 1999 Frank Mittelbach, Chris Rowley, David Carlisle -%% (C) Copyright 2004-2008 Frank Mittelbach, LaTeX3 Project -%% -%% It may be distributed and/or modified under the conditions of the -%% LaTeX Project Public License (LPPL), either version 1.3c of this -%% 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{expl3} -%</driver|package> -%\fi -\GetIdInfo$Id: xparse.dtx 1365 2009-05-31 17:26:17Z mittelba $ - {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{632} -% -% -% \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_bool| or -% |\c_false_bool| depending on whether or not the next token is -% \meta{symbol}. -% \item[s] will return either the token |\c_true_bool| or |\c_false_bool| -% 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_bool{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\NewDocumentCommand -% \DescribeMacro\RenewDocumentCommand -% \DescribeMacro\ProvideDocumentCommand If |\DeclareDocumentCommand| -% is used on an already defined command, it'll overwrite it. The -% commands |\NewDocumentCommand|, |\RenewDocumentCommand| and -% |\ProvideDocumentCommand| have identical syntax to that of -% |\DeclareDocumentCommand| with the exception that |\New...| will -% only define the command if it is undefined, |\Renew...| will only -% redefine an existing command and |\Provide...| will only define the -% command if it is already undefined. -% -% -% \DescribeMacro\DeclareDocumentEnvironment -% \DescribeMacro\NewDocumentEnvironment -% \DescribeMacro\RenewDocumentEnvironment -% \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} -% \tl_set:Nn \l_seen_tl {#1} -% \tl_set:Nn \l_hidden_novalue_tl {\NoValue} -% \tl_if_eq:NNTF \l_seen_tl \l_hidden_novalue_tl -% \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_tl| 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_bool| or -% |\c_false_bool| respectively. To test for these values the macro -% |\IfBooleanTF| can be used. It expects as its first argument either -% |\c_true_bool| or |\c_false_bool| 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 -% \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 -% \ExplSyntaxOff -% \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: \iow_space: 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{expl3} -% \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} -\cs_new_nopar:Nn \xparse_already_defined_error_msg:N { - \xparse_error:x { - Command~name~`\token_to_str:N #1'~ already~defined! - } -} -\cs_new_nopar:Nn \xparse_not_yet_defined_error_msg:N { - \xparse_error:x { - Command~`\token_to_str:N #1'~ not~ yet~defined! - } -} -\cs_new_nopar:Nn \xparse_begins_with_end_error_msg:N { - \xparse_error:x { - Command~`\token_to_str:N #1'~begins~with~ - `\token_to_str: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} -\cs_new_nopar:Nn \xparse_unknown_arg_type_error_msg:N { - \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} -\cs_new_nopar:Nn \xparse_no_command_implementation_warning:n { - \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} -\cs_new_nopar:Nn \xparse_error:x {\tex_errmessage:D {xparse~error:~#1}} -\cs_new_nopar:Nn \xparse_warning:x {\iow_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} -% An undefinable 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} -\cs_new_nopar:Npn \xparse_if_definable:NTF #1 { -% \end{macrocode} -% First check if the control sequence is free. -% \begin{macrocode} - \cs_if_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_ii:nn } - \use_i:nn - } -% \end{macrocode} -% If not free give an error message. -% \begin{macrocode} - { \xparse_already_defined_error_msg:N #1 \use_ii:nn } -} -\cs_generate_variant:Nn \xparse_if_definable:NTF {c} -% \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} -\cs_new_nopar:Npn \xparse_if_redefinable:NTF #1 { - \cs_if_free:NTF #1 - { \xparse_not_yet_defined_error_msg:N #1 \use_ii:nn } - { - \xparse_begins_with_end:NTF #1 - { \xparse_begins_with_end_error_msg:N #1 \use_ii:nn } - \use_i:nn - } -} -\cs_generate_variant:Nn \xparse_if_redefinable:NTF {c} -% \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} -\cs_new_nopar:Npn \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 { - \tl_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} -\cs_new_nopar:Nn \xparse_begins_with_end_aux:N { - \if_predicate:w \cs_if_eq_name_p:NN #1 \end - \group_end: - \exp_after:wN \use_i:nn - \else: - \group_end: - \exp_after:wN \use_ii:nn - \fi: -} -% \end{macrocode} -% Note that these definitions make no use of temporary variables. -% \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} -\cs_set:Nn \xparse_declare_document_command:Nnn { -% \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} - \cs_set_protected_nopar:Npx #1 { - \exp_not:n { \toks_set:Nn \l_xparse_grabbed_args_toks } - {\exp_not:c {\token_to_str: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} - \cs_generate_from_arg_count:cNnn {\token_to_str:N #1}\cs_set:Npn - \l_xparse_total_args_int{#3} -} -\cs_generate_variant:Nn \xparse_declare_document_command:Nnn {cnn} -% \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} -\cs_new:Nn \xparse_declare_document_environment:nnnn { - \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} - \cs_set_eq:cN {end #1} \xparse_parsed_end_environment: -% \end{macrocode} -% Now define |\end\\|\meta{envir}. -% \begin{macrocode} - \cs_generate_from_arg_count:cNnn {end \token_to_str:N \\ #1}\cs_set:Npn - \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} -\cs_new_protected_nopar:Nn \xparse_parsed_end_environment: { - \exp_after:wN \xparse_parsed_end_environment_aux:N - \toks_use:N \l_xparse_end_environment_args_toks - \group_end: -} -\cs_new_nopar:Nn \xparse_parsed_end_environment_aux:N { - \use:c {end \token_to_str:N #1 } -} -% \end{macrocode} -% \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}{\NewDocumentCommand} -% \begin{macro}{\RenewDocumentCommand} -% 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} -\cs_new_eq:NN \DeclareDocumentCommand \xparse_declare_document_command:Nnn -\cs_new_nopar:Npn \NewDocumentCommand #1 { - \xparse_if_definable:NTF #1 - { \xparse_declare_document_command:Nnn #1 } - \use_none:nn -} -\cs_new_nopar:Npn \RenewDocumentCommand #1 { - \xparse_if_redefinable:NTF #1 - { \xparse_declare_document_command:Nnn #1 } - \use_none:nn -} -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\DeclareDocumentEnvironment} -% \begin{macro}{\NewDocumentEnvironment} -% \begin{macro}{\RenewDocumentEnvironment} -% Three arguments for environments. -% \begin{macrocode} -\cs_new_eq:NN \DeclareDocumentEnvironment - \xparse_declare_document_environment:nnnn -\cs_new_nopar:Npn \NewDocumentEnvironment #1 { - \xparse_if_definable:cTF {#1} - { \xparse_declare_document_environment:nnnn {#1} } - \use_none:nnn -} -\cs_new_nopar:Npn \RenewDocumentEnvironment #1 { - \xparse_if_redefinable:cTF {#1} - { \xparse_declare_document_environment:nnnn {#1} } - \use_none:nnn -} -% \end{macrocode} -% \end{macro} -% \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} -\cs_new_nopar:Npn \ProvideDocumentCommand #1{ - \cs_if_free:NTF #1 - { \DeclareDocumentCommand #1} - \use_none:nn -} -\cs_new_nopar:Npn \ProvideDocumentEnvironment #1{ - \cs_if_free:cTF {#1} - { \DeclareDocumentEnvironment {#1} } - \use_none:nnn -} -% \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} -\cs_new:Npn \DeclareDocumentCommandInterface #1#2#3{ - \xparse_prepare_signature:n {#3} - \cs_set_protected_nopar: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} - \cs_generate_from_arg_count:cNnn {impl-#2} \cs_set:Npn - \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} -\cs_new_nopar:Nn \xparse_undefined_command_implementation:n { - ``#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} -\cs_new:Npn \DeclareDocumentCommandImplementation #1#2#3{ - \cs_generate_from_arg_count:cNnn {impl-#1}\cs_set:Npn {#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} -\cs_new_nopar:Nn \xparse_prepare_signature:n { -% \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 - \tl_gset_eq:NN \g_xparse_ignore_marker_tl - \g_xparse_ignore_spaces_marker_tl -% \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_tl} -% The current ignore marker is contained in this string. -% \begin{macrocode} -\tl_new:Nn \g_xparse_ignore_marker_tl {} -% \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} -\cs_new_nopar: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} - \tl_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} -\cs_new_nopar:Nn \xparse_add_ignore_marker:Nnn { - \tl_new:cn {g_xparse #2 _marker_tl}{#3} - \seq_gpush:Nv \g_xparse_ignore_marker_seq {g_xparse #2 _marker_tl} - \cs_new_nopar:cpn {xparse_add_arg_type_#1:}{ - \tl_gset_eq:Nc \g_xparse_ignore_marker_tl {g_xparse #2 _marker_tl} - } -} -% \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} -\cs_new_nopar:Nn \xparse_add_arg_type_P: { - \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} -\cs_new_nopar:Nn \xparse_parse_signature:n { -% \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 - \tl_gset_eq:NN \g_xparse_ignore_marker_tl - \g_xparse_ignore_spaces_marker_tl - } -% \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} -\cs_new_nopar:Nn \xparse_check_and_add_argument_type:N { - \cs_if_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} - { \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} -\cs_new_eq:NN \xparse_read_arg_type_or_grab_default:n - \xparse_parse_signature:n -\cs_new_nopar:Nn \xparse_grab_default_arg:n { - \toks_put_right:Nn \l_xparse_grabbed_args_toks {{#1}} - \cs_set_eq:NN \xparse_read_arg_type_or_grab_default:n - \xparse_parse_signature:n - \xparse_parse_signature:n -} -\cs_new:Nn \xparse_grab_default_arg_allow_par:n { - \toks_put_right:Nn \l_xparse_grabbed_args_toks {{#1}} - \cs_set_eq: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} -\cs_new_nopar:Nn \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} -\cs_new_nopar:Nn \xparse_add_remaining_m_args: { - \intexpr_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} -\cs_new_nopar: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 -} -\cs_new_nopar: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 -} -\cs_new_nopar: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 -} -\cs_new_nopar: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 -} -\cs_new_nopar: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 -} -\cs_new_nopar: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 -} -\cs_new_nopar: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 -} -\cs_new_nopar: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 -} -\cs_new_nopar: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} -\cs_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} -\cs_new_nopar:Nn \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} } -} -\cs_new_nopar: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 -} -\cs_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_bool| on the -% argument stack and |\c_false_bool| otherwise. -% \begin{macrocode} -\cs_new_nopar:Npn \DeclareSymbolArgument #1#2{ - \seq_map_variable:NNn \g_xparse_ignore_marker_seq \l_tmpa_tl { - \cs_set_nopar:cpx {xparse \l_tmpa_tl _#1:w}##1##2 - \l_xparse_grabbed_args_toks{ - \exp_not:c{peek_ #2 _remove \l_tmpa_tl :NTF} ##1 - { - \exp_not:N \toks_put_right:Nn \exp_not:N - \l_xparse_grabbed_args_toks \exp_not:N \c_true_bool - ##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_bool - ##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} - \cs_set_nopar: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_tl _#1:w } } -% \end{macrocode} -% Nothing special when building the signature: We always grab a single -% default argument. -% \begin{macrocode} - \cs_set_eq: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} -\cs_new_nopar:Npn \DeclareArgumentType #1#2#3#4#5#6#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_tl { - \cs_set_nopar:cpx {xparse \l_tmpa_tl _#1:w}##1\l_xparse_grabbed_args_toks{ - \exp_not:c{peek_#3 \l_tmpa_tl :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} - \cs_set:cpx {xparse_allow_par \l_tmpa_tl _#1:w}##1 - \l_xparse_grabbed_args_toks{ - \exp_not:c{peek_#3 \l_tmpa_tl :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} - \cs_set_nopar: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_tl - _#1:w - } - } - \cs_set_eq: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} -\cs_new_nopar:Npn \DeclareArgumentTypeDefaultValue #1#2#3#4#5{ - \seq_map_variable:NNn \g_xparse_ignore_marker_seq \l_tmpa_tl { - \cs_set_nopar:cpx {xparse \l_tmpa_tl _#1:w}##1##2\l_xparse_grabbed_args_toks{ - \exp_not:c{peek_#3 \l_tmpa_tl :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} - \cs_set:cpx {xparse_allow_par \l_tmpa_tl _#1:w}##1##2 - \l_xparse_grabbed_args_toks{ - \exp_not:c{peek_#3 \l_tmpa_tl :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} - \cs_set_nopar: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_tl - _#1:w - } - } - \cs_set_eq: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} -\cs_new_nopar:Nn \xparse_define_helper:Nnnn { - \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 {\cs_set_nopar:cpn{xparse_#1_#2_help:nw}} - \toks_use:N \l_tmpa_toks - \exp_not:n {\cs_set_nopar: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} -\cs_new_nopar:Npn \DeclareArgumentTypeShorthand #1#2{ - \cs_new_nopar: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_bool| and |\c_false_bool| so testing for them is done with -% our usual |\bool_if:NTF| functions from \textsf{l3prg}. -% \begin{macrocode} -\cs_new_eq:NN \IfBooleanTF \bool_if:NTF -\cs_new_eq:NN \IfBooleanT \bool_if:NT -\cs_new_eq:NN \IfBooleanF \bool_if:NF -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\NoValue} -% \begin{macro}{\c_xparse_hidden_no_value_tl} -% |\NoValue| is just a text string and we define it as a token list -% variable. However we will actually test for token list variables -% with \emph{meaning} |\NoValue|. Hence if an argument is really -% |-NoValue-| it will not be detected but that shouldn't happen. -% \begin{macrocode} -\tl_new:Nn \NoValue {-NoValue-} -\tl_new:Nn \c_xparse_hidden_no_value_tl {\NoValue} -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\xparse_if_no_value:nTF} -% The test start by making a token list variable out of the first -% argument and then check if it is equal to -% |\c_xparse_hidden_no_value_tl| which contains |\NoValue|. -% \begin{macrocode} -\cs_new:Npn \xparse_if_no_value:nTF #1{ - \tl_set:Nx \l_tmpa_tl{\exp_not:n{#1}} - \tl_if_eq:NNTF \l_tmpa_tl \c_xparse_hidden_no_value_tl -% \end{macrocode} -% If they are equal we just exit and execute the \meta{true} code. -% \begin{macrocode} - { \use_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} - { \tl_if_blank:nTF {#1} - { \use_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} -\cs_new:Nn \xparse_if_no_value_aux: { - \tl_set:Nx \l_tmpa_tl{\token_get_arg_spec:N \l_peek_token } -% \end{macrocode} -% Then check if |\l_tmpa_tl| 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} - \tl_if_empty:NTF \l_tmpa_tl - {\use_i_delimit_by_q_nil:nw {\exp_args:No\xparse_if_no_value:nTF}} - {\use_i_delimit_by_q_nil:nw {\use_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} -\cs_new_eq:NN \IfNoValueTF \xparse_if_no_value:nTF -\cs_new:Npn \IfNoValueT #1#2 {\xparse_if_no_value:nTF{#1}{#2}{}} -\cs_new:Npn \IfNoValueF #1 {\xparse_if_no_value:nTF {#1}{}} -% \end{macrocode} -% For |\IfValueTF| we just reverse the arguments. -% \begin{macrocode} -\cs_new:Npn \IfValueTF #1#2#3{\xparse_if_no_value:nTF {#1}{#3}{#2}} -\cs_new_eq:NN \IfValueT \IfNoValueF -\cs_new_eq: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_tl} -% A temporary token list variable to store the post-arguments. -% \begin{macrocode} -\tl_new:Nn \l_xparse_pseudo_post_arg_tl {} -% \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} -\cs_new:Npn \DeclarePseudoArgument #1#2#3#4{ - \cs_set:cn {xparse_pseudo_pre_arg_#1:\prg_replicate:nn{#2}{n}} {#3} - \cs_set:cn {xparse_pseudo_post_arg_#1:\prg_replicate:nn{#2}{n}} {#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} - \cs_set_nopar:cn {xparse_pseudo_nobrace_arg_#1:N} { - ##1 \l_xparse_pseudo_post_arg_tl - } -% \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 variable 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 variable 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 variable 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} - \cs_generate_from_arg_count:cNnn {xparse_pseudo_arg_#1:w} - \cs_set:Npx {#2} - { - \exp_not:c { - xparse_pseudo_pre_arg_#1: \prg_replicate:nn{#2}{n} - } - \use:c{use_ \intexpr_eval:n{#2} _parameter:} - \exp_not:n {\tl_set:Nn \l_xparse_pseudo_post_arg_tl} - { - \exp_not:c {xparse_pseudo_post_arg_#1:\prg_replicate:nn{#2}{n}} - \use:c{use_ \intexpr_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_tl - } - } - { - \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} -\cs_new_nopar:Npn \UsePseudoArgument #1{\use:c{xparse_pseudo_arg_#1:w}} -% \end{macrocode} -% \end{macro} -% -% -% -% -% \Finale -% -\endinput diff --git a/Master/texmf-dist/source/latex/xpackages/xtras/l3keys2e-demo.tex b/Master/texmf-dist/source/latex/xpackages/xtras/l3keys2e-demo.tex new file mode 100644 index 00000000000..a00531e0741 --- /dev/null +++ b/Master/texmf-dist/source/latex/xpackages/xtras/l3keys2e-demo.tex @@ -0,0 +1,46 @@ +% !TEX encoding = ISO-8859-1 +% !TEX program = pdflatex +% +% This file demonstrates the use of the l3keys2e module to allow +% LaTeX3 keyvals (created using l3keys) to be used as LaTeX2e +% package or class options. +% + +% First, create a class +\begin{filecontents}{l3keys2e-class.cls} + \LoadClass{article} + \RequirePackage{l3keys2e} + \ProvidesExplClass{l3keys2e-class}{0000/00/00}{0.0}{test} + \keys_define:nn { test1 } { + option1 .code:n = {\wlog{You~gave~`#1'~for~option1}} + } + \ProcessKeysOptions { test1 } +\end{filecontents} + +% Load the class with some options. +% The class itself recognises `option1', leaving `option2' and +% `option3' as global optons which are not yet used. +\documentclass[option1=check,option2=more stuff,option3=unused] + {l3keys2e-class} + +%Now create a package +\begin{filecontents}{l3keys2e-package.sty} + \RequirePackage{l3keys2e} + \ProvidesExplPackage{l3keys2e-package}{0000/00/00}{0.0}{test} + \keys_define:nn { test2 } { + option1 .code:n = {\wlog{You~gave~`#1'~for~option1~(again)}}, + option2 .code:n = {\wlog{You~gave~`#1'~for~option2}}, + option4 .code:n = {\wlog{You~gave~`#1'~for~option4}}, + } + \ProcessKeysOptions { test2 } +\end{filecontents} + +% Load the package. +\usepackage[option4={extra stuff},option5=undefined!] + {l3keys2e-package} + +\begin{document} +% The log should show that option3 is an unused global option, and that +% option5 is not known by the l3keys2e-demo package. Everything else +% should simply be listed in the log. +\end{document} diff --git a/Master/texmf-dist/source/latex/xpackages/xtras/l3keys2e.dtx b/Master/texmf-dist/source/latex/xpackages/xtras/l3keys2e.dtx new file mode 100644 index 00000000000..9595206ee53 --- /dev/null +++ b/Master/texmf-dist/source/latex/xpackages/xtras/l3keys2e.dtx @@ -0,0 +1,322 @@ +% \iffalse +%% File: l3keys2e.dtx (C) Copyright 2009 LaTeX3 Project +%% +%% It may be distributed and/or modified under the conditions of the +%% LaTeX Project Public License (LPPL), either version 1.3c of this +%% license or (at your option) any later version. The latest version +%% of this license is in the file +%% +%% http://www.latex-project.org/lppl.txt +%% +%% This file is part of the ``l3keys2e'' (The Work in LPPL) +%% and all files in that bundle must be distributed together. +%% +%% The released version of this bundle is available from CTAN. +%% +%% ----------------------------------------------------------------------- +%% +%% The development version of the bundle can be found at +%% +%% http://www.latex-project.org/svnroot/experimental/trunk/ +%% +%% for those people who are interested. +%% +%%%%%%%%%%% +%% NOTE: %% +%%%%%%%%%%% +%% +%% Snapshots taken from the repository represent work in progress and may +%% not work or may contain conflicting material! We therefore ask +%% people _not_ to put them into distributions, archives, etc. without +%% prior consultation with the LaTeX Project Team. +%% +%% ----------------------------------------------------------------------- +%% +% +%<*driver|package> +\RequirePackage{l3names} +%</driver|package> +%\fi +\GetIdInfo$Id: l3keys2e.dtx 1494 2009-08-24 11:05:44Z joseph $ + {Parsing LaTeX3 keyvals as LaTeX2e package options} +%\iffalse +%<*driver> +%\fi +\ProvidesFile{\filename.\filenameext} + [\filedate\space v\fileversion\space\filedescription] +%\iffalse +\documentclass{l3doc} +\begin{document} + \DocInput{l3keys2e.dtx} +\end{document} +%</driver> +% \fi +% +% \title{The \textsf{l3keys2e} package\thanks{This file +% has version number \fileversion, last +% revised \filedate.}\\ +% Parsing \LaTeX3 keyvals as \LaTeXe\ package options} +% \author{\Team} +% \date{\filedate} +% \maketitle +% +%\begin{documentation} +% +%\section{Key--value arguments as \LaTeXe\ class and package options} +% +% The key--value method for optional arguments is very popular, as it +% allows the class or package author to define a large number of +% options with a simple interface. The \pkg{expl3} bundle of \LaTeX3 +% base code includes the module \pkg{l3keys} for defining keys, but +% to use these when loading \LaTeXe\ packages and classes requires +% extra support. That support is provided by this small package, which +% is intended to enable \LaTeXe\ packages to benefit from the power of +% the \LaTeX3 key--value system. +% +%\subsection{Creating and using keyval options} +% +% As with any key--value input, using key--value pairs as package or +% class options has two parts. The first stage is to define one or +% more keys. This should be done using the \LaTeX3 module \pkg{l3keys}. +% For example, an option which simply stores a value would be created +% using: +%\begin{verbatim} +% \keys_define:nn { module } { +% option .set:N = \l_module_variable_tl +% } +%\end{verbatim} +% On its own, this will not make the key an option for the package or +% class containing the definition. The second stage is therefore to +% process the current options, searching for applicable keys. +% +%\begin{function}{\ProcessKeysOptions} +% \begin{syntax} +% "\ProcessKeysOptions" \Arg{module} +% \end{syntax} +% The \cs{ProcessKeysOptions} function is used to check the current +% option list against the keys defined for <module>. Global (class) +% options and local (package) options are checked when this function +% is called in a package. Each option which does match a key name is +% then used to attempt to set the appropriate key using +% \cs{keys_set:nn}. For example, the option defined earlier would be +% processed by the line +% \begin{verbatim} +% \ProcessKeysOptions { module } +% \end{verbatim} +%\end{function} +% +%\subsection{Internal functions and variables} +% +%\begin{variable}{\keys_latexe_options_clist} +% Local options and applicable global (class) options are collected up +% here prior to processing using \cs{keys_set:nn}. +%\end{variable} +% +%\begin{function}{\keys_latexe_options:n} +% \begin{syntax} +% "\keys_latexe_options:n" \Arg{module} +% \end{syntax} +% Examines current global and local options, comparing them to the +% keys defined for <module>. Option names which match defined keys are +% then executed by passing the appropriate data to \cs{keys_set:nn}. +%\end{function} +% +%\begin{function}{\keys_latexe_options_global:n} +% \begin{syntax} +% "\keys_latexe_options_global:n" \Arg{module} +% \end{syntax} +% Makes appropriate checks on global (class) options, then searches for +% key matches for <module>. +%\end{function} +% +%\begin{function}{\keys_latexe_options_class:n} +% \begin{syntax} +% "\keys_latexe_options_class:n" \Arg{module} +% \end{syntax} +% Processes global options when the current file is itself a class, +% checking the options against keys defined for <module>. +%\end{function} +% +%\begin{function}{\keys_latexe_options_package:n} +% \begin{syntax} +% "\keys_latexe_options_package:n" \Arg{module} +% \end{syntax} +% Processes global options when the current file is a \LaTeXe\ package, +% checking the options against keys defined for <module>. +%\end{function} +% +%\begin{function}{\keys_latexe_options_local:} +% \begin{syntax} +% "\keys_latexe_options_local:" +% \end{syntax} +% Finds local (package) options and adds them to the list to be +% parsed by \cs{keys_set:nn}. +%\end{function} +% +%\begin{function}{ +% \keys_latexe_remove_equals:n / (EXP) | +% \keys_latexe_remove_equals:w / (EXP) +%} +% \begin{syntax} +% "\keys_latexe_remove_equals:n" \Arg{option} +% "\keys_latexe_remove_equals:w" <key> = <value> "\q_stop" +% \end{syntax} +% Returns only the key part of a key--value option by removing +% everything after the first equals sign. It is assumed that, as this +% will apply in the preamble, equals signs have category code 12. +%\end{function} +% +%\end{documentation} +% +%\begin{implementation} +% +%\subsection{Implementation} +% +% The usual lead-off, using \pkg{xparse} at the interface level. +% \begin{macrocode} +%<*package> +\ProvidesExplPackage + {\filename}{\filedate}{\fileversion}{\filedescription} +\RequirePackage{xparse} +% \end{macrocode} +% +%\begin{macro}{\keys_latexe_options_clist} +% The module collects all applicable global and local options into a +% single list before processing them. +% \begin{macrocode} +\clist_new:N \keys_latexe_options_clist +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\keys_latexe_options:n} +% The main function calls functions to collect up the global and local +% options into \cs{keys_latexe_options_clist} before calling the main +% \pkg{l3keys} module to actually do the processing. So that a suitable +% message is produced if the option is unknown, the special +% \texttt{unknown} key is set if it does not already exist for the +% current module. +% \begin{macrocode} +\cs_new:Nn \keys_latexe_options:n { + \clist_clear:N \keys_latexe_options_clist + \keys_latexe_options_global:n {#1} + \keys_latexe_options_local: + \keys_if_exist:nnF {#1} { unknown } { + \keys_define:nn {#1} { + unknown .code:n = { + \msg_warning:nnxx { Option~Processing } { unknown-option } + { \l_keys_key_tl } { \@currname } + } + } + } + \keys_set:nV {#1} \keys_latexe_options_clist + \AtEndOfPackage { \cs_set_eq:NN \@unprocessedoptions \scan_stop: } +} +\msg_new:nnn { Option~Processing } { unknown-option } {% + Unknown~option~`#1'\\% + for~module~#2.% +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\keys_latexe_options_global:n} +% Global (class) options are handled differently for \LaTeXe\ packages +% and classes. Hence this function is essentially a check on the current +% file type. The initial test is needed as \LaTeXe\ allows variables to +% be equal to \cs{scan_stop:}, which is forbidden in \LaTeX3 code. +% \begin{macrocode} +\cs_new:Nn \keys_latexe_options_global:n { + \cs_if_eq:NNF \@classoptionslist \scan_stop: { + \cs_if_eq:NNTF \@currext \@clsextension { + \keys_latexe_options_class:n {#1} + }{ + \keys_latexe_options_package:n {#1} + } + } +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\keys_latexe_options_class:n} +% For classes, each option (stripped of any content after `\texttt{=}') +% is checked for existence as a key. If found, the option is added to +% the combined list for processing. On the other hand, unused options +% are stored up in \cs{@unusedoptionlist}. +% \begin{macrocode} +\cs_new:Nn \keys_latexe_options_class:n { + \clist_map_inline:Nn \@classoptionslist { + \keys_if_exist:nnTF {#1} { \keys_latexe_remove_equals:n {##1} } { + \clist_put_right:Nn \keys_latexe_options_clist {##1} + }{ + \clist_put_right:Nn \@unusedoptionlist {##1} + } + } +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\keys_latexe_options_package:n} +% For global options when processing a package, the tasks are slightly +% different from those for a class. The check is the same, but here +% there is nothing to do if the option is not applicable. Each valid +% option also needs to be removed from \cs{@unusedoptionlist}. +% \begin{macrocode} +\cs_new:Nn \keys_latexe_options_package:n { + \clist_map_inline:Nn \@classoptionslist { + \keys_if_exist:nnT {#1} { \keys_latexe_remove_equals:n {##1} } { + \clist_put_right:Nn \keys_latexe_options_clist {##1} + \clist_remove_element:Nn \@unusedoptionlist {##1} + } + } +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\keys_latexe_options_local:} +% If local options are found, the are added to the processing list. +% \LaTeXe\ stores options for each file in a macro which may or may not +% exist, hence the need to use \cs{cs_if_exist:c}. +% \begin{macrocode} +\cs_new_nopar:Nn \keys_latexe_options_local: { + \cs_if_eq:NNF \@currext \@clsextension { + \cs_if_exist:cT { opt@ \@currname . \@currext } { + \exp_args:NNc \clist_put_right:NV \keys_latexe_options_clist + { opt@ \@currname . \@currext } + } + } +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\keys_latexe_remove_equals:n} +%\begin{macro}{\keys_latexe_remove_equals:w} +% As the name suggests, this is a simple function to remove an equals +% sign from the input. This is all wrapped up in an \texttt{n} function +% so that there will always be a sign available. +% \begin{macrocode} +\cs_new:Nn \keys_latexe_remove_equals:n { + \keys_latexe_remove_equals:w #1 = \q_stop +} +\cs_new:Npn \keys_latexe_remove_equals:w #1 = #2 \q_stop {#1} +% \end{macrocode} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\ProcessKeysOptions} +% The user macro is simply a wrapper around the internal process. In +% contrast to other similar packages, the module name is always required +% here. +% \begin{macrocode} +\NewDocumentCommand \ProcessKeysOptions { m } { + \keys_latexe_options:n {#1} +} +\@onlypreamble \ProcessKeysOptions +% \end{macrocode} +%\end{macro} +% +% \begin{macrocode} +%</package> +% \end{macrocode} +% +% \end{implementation} +% +% \PrintIndex diff --git a/Master/texmf-dist/source/latex/xpackages/xtras/l3keys2e.ins b/Master/texmf-dist/source/latex/xpackages/xtras/l3keys2e.ins new file mode 100644 index 00000000000..75c72b058d4 --- /dev/null +++ b/Master/texmf-dist/source/latex/xpackages/xtras/l3keys2e.ins @@ -0,0 +1,19 @@ +\input docstrip +\keepsilent +\askforoverwritefalse + +\preamble +---------------------------------------------------------------- +l3keys2e --- Parsing LaTeX3 keyvals as LaTeX2e package options +Copyright 2009 The LaTeX3 Project +Released under the LaTeX Project Public License v1.3c or later +See http://www.latex-project.org/lppl.txt +---------------------------------------------------------------- +\endpreamble + + +\generate{% + \file{l3keys2e.sty}{\from{l3keys2e.dtx}{package}} +} + +\endbatchfile diff --git a/Master/texmf-dist/tex/latex/xpackages/ldcsetup.sty b/Master/texmf-dist/tex/latex/xpackages/xbase/ldcsetup.sty index 7f26ce16cbb..7f26ce16cbb 100644 --- a/Master/texmf-dist/tex/latex/xpackages/ldcsetup.sty +++ b/Master/texmf-dist/tex/latex/xpackages/xbase/ldcsetup.sty diff --git a/Master/texmf-dist/tex/latex/xpackages/template.sty b/Master/texmf-dist/tex/latex/xpackages/xbase/template.sty index a64a9cf4cc9..b91b2d6715e 100644 --- a/Master/texmf-dist/tex/latex/xpackages/template.sty +++ b/Master/texmf-dist/tex/latex/xpackages/xbase/template.sty @@ -54,7 +54,7 @@ %% ----------------------------------------------------------------------- %% \RequirePackage{expl3} -\GetIdInfo$Id: template.dtx 1295 2009-05-06 08:32:25Z will $ +\GetIdInfo$Id: template.dtx 1461 2009-08-15 08:38:12Z joseph $ {template} \ProvidesExplPackage {\filename}{\filedate}{\fileversion}{\filedescription} @@ -286,8 +286,7 @@ } \cs_set:Npn \TP_ignore_leading_space_in_arg_ii_aux:nn#1#2{#2{#1}} -\DeclareArgumentType t[{meaning}{}{\NoValue}{#1[#2]}{#2} -\DeclareDocumentCommand\TP_parse_optional_key_default:nw{mt}{ +\DeclareDocumentCommand\TP_parse_optional_key_default:nw{mo}{ \IfNoValueTF{#2} {\TP_templdecl_finish_key_setup:nw{#1}} {\TP_templdecl_finish_key_setup_with_default:nnw{#1}{#2}} diff --git a/Master/texmf-dist/tex/latex/xpackages/xbase/xparse.sty b/Master/texmf-dist/tex/latex/xpackages/xbase/xparse.sty new file mode 100644 index 00000000000..9bc5164a748 --- /dev/null +++ b/Master/texmf-dist/tex/latex/xpackages/xbase/xparse.sty @@ -0,0 +1,899 @@ +%% +%% This is file `xparse.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% xparse.dtx (with options: `package') +%% +%% (C) Copyright The LaTeX3 Project and any individual authors +%% listed elsewhere in this file. +%% +%% This is a generated file. +%% +%% This file was generated from file(s) of the xbase bundle. +%% --------------------------------------------------------- +%% +%% This file may only be distributed together with a copy of this bundle. +%% You may however distribute the bundle without such generated files. +%% +%% ====================================================================== +%% +%% File: xparse.dtx (C) Copyright 1999 Frank Mittelbach, Chris Rowley, +%% David Carlisle +%% (C) Copyright 2004-2008 Frank Mittelbach, +%% LaTeX3 Project +%% (C) Copyright 2009 LaTeX3 Project +%% +%% It may be distributed and/or modified under the conditions of the +%% LaTeX Project Public License (LPPL), either version 1.3c of this +%% license or (at your option) any later version. The latest version +%% of this license is in the file +%% +%% http://www.latex-project.org/lppl.txt +%% +%% This file is part of the ``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/svnroot/experimental/trunk/ +%% +%% for those people who are interested. +%% +%%%%%%%%%%% +%% NOTE: %% +%%%%%%%%%%% +%% +%% Snapshots taken from the repository represent work in progress and may +%% not work or may contain conflicting material! We therefore ask +%% people _not_ to put them into distributions, archives, etc. without +%% prior consultation with the LaTeX Project Team. +%% +%% ----------------------------------------------------------------------- +%% +\RequirePackage{l3names} +\GetIdInfo$Id: xparse.dtx 1497 2009-08-31 19:17:53Z joseph $ + {Generic document command parser} +\ProvidesExplPackage + {\filename}{\filedate}{\fileversion}{\filedescription} +\RequirePackage{expl3} +\prop_new:N \c_xparse_shorthands_prop +\prop_put:Nnn \c_xparse_shorthands_prop { o } { d[] } +\prop_put:Nnn \c_xparse_shorthands_prop { O } { D[] } +\prop_put:Nnn \c_xparse_shorthands_prop { s } { t* } +\toks_new:N \l_xparse_arg_toks +\toks_new:N \l_xparse_args_toks +\toks_new:N \l_xparse_environment_args_toks +\bool_new:N \l_xparse_error_bool +\tl_new:N \l_xparse_function_tl +\toks_new:N \l_xparse_last_arg_tl +\bool_new:N \l_xparse_long_bool +\int_new:N \l_xparse_m_args_int +\bool_new:N \l_xparse_m_only_bool +\int_new:N \l_xparse_mandatory_args_int +\bool_new:N \l_xparse_processor_bool +\int_new:N \l_xparse_processor_int +\toks_new:N \l_xparse_signature_toks +\tl_new:N \l_xparse_tmp_tl +\int_new:N \l_xparse_total_args_int +\quark_new:N \q_xparse_stop +\cs_new_nopar:Nn \xparse_add_grabber_mandatory:N { + \toks_put_right:Nx \l_xparse_signature_toks { + \exp_not:c { + xparse_grab_ #1 \bool_if:NT \l_xparse_long_bool { _long } :w + } + } + \bool_set_false:N \l_xparse_long_bool + \int_decr:N \l_xparse_mandatory_args_int +} +\cs_new_nopar:Nn \xparse_add_grabber_optional:N { + \toks_put_right:Nx \l_xparse_signature_toks { + \exp_not:c { + xparse_grab_ #1 + \bool_if:NT \l_xparse_long_bool { _long } + \intexpr_compare:nF { + \l_xparse_mandatory_args_int > \c_zero + } { _trailing } + :w + } + } + \bool_set_false:N \l_xparse_long_bool +} +\cs_new_nopar:cpn { xparse_add_type_+:w } { + \xparse_flush_m_args: + \bool_set_true:N \l_xparse_long_bool + \bool_set_false:N \l_xparse_m_only_bool + \int_decr:N \l_xparse_total_args_int + \xparse_prepare_signature:N +} +\cs_new:cpn { xparse_add_type_>:w } #1 { + \bool_set_true:N \l_xparse_processor_bool + \xparse_flush_m_args: + \int_decr:N \l_xparse_total_args_int + \toks_put_right:Nn \l_xparse_signature_toks { + \xparse_process_arg:n {#1} + } + \xparse_prepare_signature_aux:N +} +\cs_new:Npn \xparse_add_type_d:w #1#2 { + \xparse_add_type_D:w #1 #2 { \NoValue } +} +\cs_new:Npn \xparse_add_type_D:w #1#2#3 { + \xparse_flush_m_args: + \xparse_add_grabber_optional:N D + \toks_put_right:Nn \l_xparse_signature_toks { #1 #2 {#3} } + \xparse_prepare_signature:N +} +\cs_new_nopar:Npn \xparse_add_type_g:w { + \xparse_add_type_G:w { \NoValue } +} +\cs_new:Npn \xparse_add_type_G:w #1 { + \xparse_flush_m_args: + \xparse_add_grabber_optional:N G + \toks_put_right:Nn \l_xparse_signature_toks { {#1} } + \xparse_prepare_signature:N +} +\cs_new_nopar:Npn \xparse_add_type_l:w { + \xparse_flush_m_args: + \xparse_add_grabber_mandatory:N l + \xparse_prepare_signature:N +} +\cs_new_nopar:Npn \xparse_add_type_m:w { + \bool_if:nTF { + \l_xparse_long_bool || \l_xparse_processor_bool + } { + \xparse_flush_m_args: + \xparse_add_grabber_mandatory:N m + }{ + \int_incr:N \l_xparse_m_args_int + } + \xparse_prepare_signature:N +} +\cs_new:Npn \xparse_add_type_t:w #1 { + \xparse_flush_m_args: + \xparse_add_grabber_optional:N t + \toks_put_right:Nn \l_xparse_signature_toks { #1 } + \xparse_prepare_signature:N +} +\cs_new:Npn \xparse_add_type_u:w #1 { + \xparse_flush_m_args: + \xparse_add_grabber_mandatory:N u + \toks_put_right:Nn \l_xparse_signature_toks { {#1} } + \xparse_prepare_signature:N +} +\cs_new_nopar:Nn \xparse_check_and_add:N { + \cs_if_free:cTF { xparse_add_type_ #1 :w } { + \msg_error:nnx { xparse } { unknown-argument-type } {#1} + \xparse_add_type_m:w + }{ + \use:c { xparse_add_type_ #1 :w } + } +} +\cs_new:Nn \xparse_count_mandatory:n { + \int_zero:N \l_xparse_mandatory_args_int + \xparse_count_mandatory:N #1 \q_nil +} +\cs_new:Nn \xparse_count_mandatory:N { + \quark_if_nil:NF #1 { + \prop_if_in:NnTF \c_xparse_shorthands_prop {#1} { + \prop_get:NnN \c_xparse_shorthands_prop {#1} \l_xparse_tmp_tl + \exp_last_unbraced:NV \xparse_count_mandatory:N \l_xparse_tmp_tl + }{ + \xparse_count_mandatory_aux:N #1 + } + } +} +\cs_new:Nn \xparse_count_mandatory_aux:N { + \cs_if_free:cTF { xparse_count_type_ #1 :w } { + \xparse_count_type_m:w + }{ + \use:c { xparse_count_type_ #1 :w } + } +} +\cs_new:cpn { xparse_count_type_>:w } #1 { + \xparse_count_mandatory:N +} +\cs_new_nopar:cpn { xparse_count_type_+:w } { + \xparse_count_mandatory:N +} +\cs_new:Npn \xparse_count_type_d:w #1#2 { + \xparse_count_mandatory:N +} +\cs_new:Npn \xparse_count_type_D:w #1#2#3 { + \xparse_count_mandatory:N +} +\cs_new_nopar:Npn \xparse_count_type_g:w { + \xparse_count_mandatory:N +} +\cs_new:Npn \xparse_count_type_G:w #1 { + \xparse_count_mandatory:N +} +\cs_new_nopar:Npn \xparse_count_type_l:w { + \int_incr:N \l_xparse_mandatory_args_int + \xparse_count_mandatory:N +} +\cs_new_nopar:Npn \xparse_count_type_m:w { + \int_incr:N \l_xparse_mandatory_args_int + \xparse_count_mandatory:N +} +\cs_new:Npn \xparse_count_type_t:w #1 { + \xparse_count_mandatory:N +} +\cs_new:Npn \xparse_count_type_u:w #1 { + \int_incr:N \l_xparse_mandatory_args_int + \xparse_count_mandatory:N +} +\cs_new:Nn \xparse_declare_cmd:Nnn { + \xparse_count_mandatory:n {#2} + \xparse_prepare_signature:n {#2} + \bool_if:NTF \l_xparse_m_only_bool { + \xparse_declare_cmd_all_m:Nn #1 {#3} + }{ + \xparse_declare_cmd_mixed:Nn #1 {#3} + } +} +\cs_generate_variant:Nn \xparse_declare_cmd:Nnn { cnn } +\cs_new:Nn \xparse_declare_cmd_all_m:Nn { + \cs_generate_from_arg_count:NNnn + #1 \cs_set_protected_nopar:Npn \l_xparse_total_args_int {#2} +} +\cs_new:Nn \xparse_declare_cmd_mixed:Nn { + \cs_set_protected_nopar:Npx #1 { + \exp_not:n { + \int_zero:N \l_xparse_processor_int + \toks_set:Nn \l_xparse_args_toks + } { \exp_not:c { \token_to_str:N #1 } } + \toks_use:N \l_xparse_signature_toks + \exp_not:n{ \toks_use:N \l_xparse_args_toks } + } + \cs_generate_from_arg_count:cNnn + { \token_to_str:N #1 } \cs_set:Npn \l_xparse_total_args_int {#2} +} +\cs_new:Nn \xparse_declare_cmd_implementation:nNn { + \cs_generate_from_arg_count:cNnn { implementation_ #1 :w } + \cs_set:Npn {#2} {#3} +} +\cs_new:Nn \xparse_declare_cmd_interface:Nnn { + \xparse_prepare_signature:n {#3} + \bool_if:NTF \l_xparse_m_only_bool { + \xparse_declare_cmd_interface_all_m:Nn #1 {#2} + }{ + \xparse_declare_cmd_interface_mixed:Nn #1 {#2} + } + \cs_generate_from_arg_count:cNnn { implementation_ #2 :w } + \cs_set:Npn \l_xparse_total_args_int { ``#2'' } +} +\cs_new:Nn \xparse_declare_cmd_interface_all_m:Nn { + \cs_generate_from_arg_count:NNnn + #1 \cs_set_protected_nopar:Npn \l_xparse_total_args_int + { \use:c { implementation_ #2 :w } } +} +\cs_new:Nn \xparse_declare_cmd_interface_mixed:Nn { + \cs_set_protected_nopar:Npx #1 { + \exp_not:n { + \int_zero:N \l_xparse_processor_int + \toks_set:Nn \l_xparse_args_toks + } { \exp_not:c { \token_to_str:N #1 } } + \toks_use:N \l_xparse_signature_toks + \exp_not:n{ \toks_use:N \l_xparse_args_toks } + } + \cs_generate_from_arg_count:cNnn + { \token_to_str:N #1 } \cs_set:Npn \l_xparse_total_args_int + { \use:c { implementation_ #2 :w } } +} +\cs_new:Nn \xparse_declare_env:nnnn { + \xparse_declare_cmd:cnn { environment_begin_ #1 :w } {#2} { + \group_begin: + \toks_set_eq:NN \l_xparse_environment_args_toks + \l_xparse_args_toks + #3 + } + \cs_set_nopar:cpx { environment_end_ #1 :w } { + \exp_not:N \exp_last_unbraced:NV + \exp_not:c { environment_end_ #1 _aux:N } + \exp_not:N \l_xparse_environment_args_toks + \exp_not:N \group_end: + } + \cs_set_nopar:cx { environment_end_ #1 _aux:N } { + \exp_not:c { environment_end_ #1 _aux :w } + } + \cs_generate_from_arg_count:cNnn + { environment_end_ #1 _aux :w } \cs_set:Npn + \l_xparse_total_args_int {#4} + \cs_set_eq:cc {#1} { environment_begin_ #1 :w } + \cs_set_eq:cc { end #1 } { environment_end_ #1 :w } +} +\cs_new_nopar:Nn \xparse_flush_m_args: { + \cs_if_exist:cT { + xparse_grab_m_ \int_use:N \l_xparse_m_args_int :w + } { + \toks_put_right:Nx \l_xparse_signature_toks { + \exp_not:c { xparse_grab_m_ \int_use:N \l_xparse_m_args_int :w } + } + \int_set:Nn \l_xparse_mandatory_args_int { + \l_xparse_mandatory_args_int - \l_xparse_m_args_int + } + } + \int_zero:N \l_xparse_m_args_int + \bool_set_false:N \l_xparse_m_only_bool +} +\prg_new_conditional:Nnn \xparse_if_no_value:n { TF,T,F } { + \tl_if_eq:nnTF {#1} { \NoValue } { + \prg_return_true: + }{ + \prg_return_false: + } +} +\cs_new:Nn \xparse_prepare_signature:n { + \bool_set_false:N \l_xparse_long_bool + \int_zero:N \l_xparse_m_args_int + \bool_set_true:N \l_xparse_m_only_bool + \bool_set_false:N \l_xparse_processor_bool + \toks_clear:N \l_xparse_signature_toks + \int_zero:N \l_xparse_total_args_int + \xparse_prepare_signature:N #1 \q_nil +} +\cs_new:Nn \xparse_prepare_signature:N { + \bool_set_false:N \l_xparse_processor_bool + \xparse_prepare_signature_aux:N #1 +} +\cs_new:Nn \xparse_prepare_signature_aux:N { + \quark_if_nil:NTF #1 { + \bool_if:NF \l_xparse_m_only_bool { + \xparse_flush_m_args: + } + }{ + \prop_if_in:NnTF \c_xparse_shorthands_prop {#1} { + \prop_get:NnN \c_xparse_shorthands_prop {#1} \l_xparse_tmp_tl + \exp_last_unbraced:NV \xparse_prepare_signature:N \l_xparse_tmp_tl + }{ + \int_incr:N \l_xparse_total_args_int + \xparse_check_and_add:N #1 + } + } +} +\cs_new:Nn \xparse_process_arg:n { + \int_incr:N \l_xparse_processor_int + \cs_set:cn { + xparse_processor_ \int_use:N \l_xparse_processor_int :n + } + { #1 {##1} } +} +\cs_new:Nn \xparse_add_arg:n { + \intexpr_compare:nTF { \l_xparse_processor_int = \c_zero } { + \toks_put_right:Nn \l_xparse_args_toks { {#1} } + }{ + \xparse_if_no_value:nTF {#1} { + \int_zero:N \l_xparse_processor_int + \toks_put_right:Nn \l_xparse_args_toks { {#1} } + }{ + \xparse_add_arg_aux:n {#1} + } + } +} +\cs_new:Nn \xparse_add_arg_aux:n { + \use:c { xparse_processor_ \int_use:N \l_xparse_processor_int :n } + {#1} + \int_decr:N \l_xparse_processor_int + \intexpr_compare:nTF { \l_xparse_processor_int = \c_zero } { + \toks_put_right:No \l_xparse_args_toks { + \exp_after:wN { \toks_use:N \l_xparse_arg_toks } + } + }{ + \xparse_add_arg_aux:V \l_xparse_arg_toks + } +} +\cs_generate_variant:Nn \xparse_add_arg_aux:n { V } +\cs_new:Npn \xparse_grab_aux:w { } +\cs_new:Npn \xparse_grab_D:w #1#2#3#4 \l_xparse_args_toks { + \xparse_grab_D_aux:NNnnNn #1 #2 {#3} {#4} \cs_set_nopar:Npn + { _ignore_spaces } +} +\cs_new:Npn \xparse_grab_D_long:w #1#2#3#4 \l_xparse_args_toks { + \xparse_grab_D_aux:NNnnNn #1 #2 {#3} {#4} \cs_set:Npn + { _ignore_spaces } +} +\cs_new:Npn \xparse_grab_D_trailing:w #1#2#3#4 \l_xparse_args_toks { + \xparse_grab_D_aux:NNnnNn #1 #2 {#3} {#4} \cs_set_nopar:Npn { } +} +\cs_new:Npn \xparse_grab_D_long_trailing:w #1#2#3#4 + \l_xparse_args_toks { + \xparse_grab_D_aux:NNnnNn #1 #2 {#3} {#4} \cs_set:Npn { } +} +\cs_set:Nn \xparse_grab_D_aux:NNnnNn { + #5 \xparse_grab_arg:w #1 ##1 #2 { + \xparse_add_arg:n {##1} + #4 \l_xparse_args_toks + } + \use:c { peek_charcode #6 :NTF } #1 { + \xparse_grab_arg:w + }{ + \xparse_add_arg:n {#3} + #4 \l_xparse_args_toks + } +} +\cs_new:Npn \xparse_grab_G:w #1#2 \l_xparse_args_toks { + \xparse_grab_G_aux:nnNn {#1} {#2} \cs_set_nopar:Npn { _ignore_spaces } +} +\cs_new:Npn \xparse_grab_G_long:w #1#2 \l_xparse_args_toks { + \xparse_grab_G_aux:nnNn {#1} {#2} \cs_set:Npn { _ignore_spaces } +} +\cs_new:Npn \xparse_grab_G_trailing:w #1#2 \l_xparse_args_toks { + \xparse_grab_G_aux:nnNn {#1} {#2} \cs_set_nopar:Npn { } +} +\cs_new:Npn \xparse_grab_G_long_trailing:w #1#2 \l_xparse_args_toks { + \xparse_grab_G_aux:nnNn {#1} {#2} \cs_set:Npn { } +} +\cs_set:Nn \xparse_grab_G_aux:nnNn { + #3 \xparse_grab_arg:w ##1 { + \xparse_add_arg:n {##1} + #2 \l_xparse_args_toks + } + \use:c { peek_meaning #4 :NTF } \c_group_begin_token { + \xparse_grab_arg:w + }{ + \xparse_add_arg:n {#1} + #2 \l_xparse_args_toks + } +} +\cs_new:Npn \xparse_grab_l:w #1 \l_xparse_args_toks { + \xparse_grab_l_aux:nN {#1} \cs_set_nopar:Npn +} +\cs_new:Npn \xparse_grab_l_long:w #1 \l_xparse_args_toks { + \xparse_grab_l_aux:nN {#1} \cs_set:Npn +} +\cs_new:Nn \xparse_grab_l_aux:nN { + #2 \xparse_grab_arg:w ##1## { + \xparse_add_arg:n \l_xparse_args_toks {##1} + #1 \l_xparse_args_toks + } + \xparse_grab_arg:w +} +\cs_new:Npn \xparse_grab_m:w #1 \l_xparse_args_toks { + \cs_set_nopar:Npn \xparse_grab_arg:w ##1 { + \xparse_add_arg:n {##1} + #1 \l_xparse_args_toks + } + \xparse_grab_arg:w +} +\cs_new:Npn \xparse_grab_m_long:w #1 \l_xparse_args_toks { + \cs_set:Npn \xparse_grab_arg:w ##1 { + \xparse_add_arg:n {##1} + #1 \l_xparse_args_toks + } + \xparse_grab_arg:w +} +\cs_new:cpn { xparse_grab_m_1:w } #1 \l_xparse_args_toks { + \cs_set_nopar:Npn \xparse_grab_arg:w ##1 { + \toks_put_right:Nn \l_xparse_args_toks { {##1} } + #1 \l_xparse_args_toks + } + \xparse_grab_arg:w +} +\cs_new:cpn { xparse_grab_m_2:w } #1 \l_xparse_args_toks { + \cs_set_nopar:Npn \xparse_grab_arg:w ##1##2 { + \toks_put_right:Nn \l_xparse_args_toks { {##1} {##2} } + #1 \l_xparse_args_toks + } + \xparse_grab_arg:w +} +\cs_new:cpn { xparse_grab_m_3:w } #1 \l_xparse_args_toks { + \cs_set_nopar:Npn \xparse_grab_arg:w ##1##2##3 { + \toks_put_right:Nn \l_xparse_args_toks { {##1} {##2} {##3} } + #1 \l_xparse_args_toks + } + \xparse_grab_arg:w +} +\cs_new:cpn { xparse_grab_m_4:w } #1 \l_xparse_args_toks { + \cs_set_nopar:Npn \xparse_grab_arg:w ##1##2##3##4 { + \toks_put_right:Nn \l_xparse_args_toks { {##1} {##2} {##3} {##4} } + #1 \l_xparse_args_toks + } + \xparse_grab_arg:w +} +\cs_new:cpn { xparse_grab_m_5:w } #1 \l_xparse_args_toks { + \cs_set_nopar:Npn \xparse_grab_arg:w ##1##2##3##4##5 { + \toks_put_right:Nn \l_xparse_args_toks { + {##1} {##2} {##3} {##4} {##5} + } + #1 \l_xparse_args_toks + } + \xparse_grab_arg:w +} +\cs_new:cpn { xparse_grab_m_6:w } #1 \l_xparse_args_toks { + \cs_set_nopar:Npn \xparse_grab_arg:w ##1##2##3##4##5##6 { + \toks_put_right:Nn \l_xparse_args_toks { + {##1} {##2} {##3} {##4} {##5} {##6} + } + #1 \l_xparse_args_toks + } + \xparse_grab_arg:w +} +\cs_new:cpn { xparse_grab_m_7:w } #1 \l_xparse_args_toks { + \cs_set_nopar:Npn \xparse_grab_arg:w ##1##2##3##4##5##6##7 { + \toks_put_right:Nn \l_xparse_args_toks { + {##1} {##2} {##3} {##4} {##5} {##6} {##7} + } + #1 \l_xparse_args_toks + } + \xparse_grab_arg:w +} +\cs_new:cpn { xparse_grab_m_8:w } #1 \l_xparse_args_toks { + \cs_set_nopar:Npn \xparse_grab_arg:w ##1##2##3##4##5##6##7##8 { + \toks_put_right:Nn \l_xparse_args_toks { + {##1} {##2} {##3} {##4} {##5} {##6} {##7} {##8} + } + #1 \l_xparse_args_toks + } + \xparse_grab_arg:w +} +\cs_new:Npn \xparse_grab_t:w #1#2 \l_xparse_args_toks { + \xparse_grab_t_aux:NnNn #1 {#2} \cs_set_nopar:Npn { _ignore_spaces } +} +\cs_new:Npn \xparse_grab_t_long:w #1#2 \l_xparse_args_toks { + \xparse_grab_t_aux:NnNn #1 {#2} \cs_set:Npn { _ignore_spaces } +} +\cs_new:Npn \xparse_grab_t_trailing:w #1#2 \l_xparse_args_toks { + \xparse_grab_t_aux:NnNn #1 {#2} \cs_set_nopar:Npn { } +} +\cs_new:Npn \xparse_grab_t_long_trailing:w #1#2 \l_xparse_args_toks { + \xparse_grab_t_aux:NnNn #1 {#2} \cs_set:Npn { } +} +\cs_new:Nn \xparse_grab_t_aux:NnNn { + #3 \xparse_grab_arg:w { + \use:c { peek_charcode_remove #4 :NTF } #1 { + \xparse_add_arg:n { \BooleanTrue } + #2 \l_xparse_args_toks + }{ + \xparse_add_arg:n { \BooleanFalse } + #2 \l_xparse_args_toks + } + } + \xparse_grab_arg:w +} +\cs_new:Npn \xparse_grab_u:w #1#2 \l_xparse_args_toks { + \xparse_grab_u_aux:NnN {#1} {#2} \cs_set_nopar:Npn +} +\cs_new:Npn \xparse_grab_u_long:w #1#2 \l_xparse_args_toks { + \xparse_grab_u_aux:NnN {#1} {#2} \cs_set:Npn +} +\cs_new:Nn \xparse_grab_u_aux:NnN { + #3 \xparse_grab_arg:w ##1 #1 { + \xparse_add_arg:n {##1} + #2 \l_xparse_args_toks + } + \xparse_grab_arg:w +} +\cs_new:Nn \xparse_process_to_str:n { + \toks_set:Nx \l_xparse_arg_toks { + \tl_to_str:n {#1} + } +} +\cs_new:Nn \xparse_process_comma_split:n { + \tl_if_in:nnTF {#1} { , } { + \xparse_process_comma_split_aux:w #1 \q_stop + }{ + \toks_set:Nn \l_xparse_arg_toks { {#1} { \NoValue } } + } +} +\cs_new:Npn \xparse_process_comma_split_aux:w #1 , #2 \q_stop { + \toks_set:Nn \l_xparse_arg_toks { {#1} {#2} } +} +\cs_new:Npn \xparse_exp_add_type_d:w #1#2 { + \xparse_exp_add_type_D:w #1 #2 { \NoValue } +} +\cs_new:Npn \xparse_exp_add_type_D:w #1#2#3 { + \tl_set:Nx \l_xparse_tmpa_tl { + \exp_after:wN \token_to_str:N \l_xparse_function_tl + \int_use:N \l_xparse_total_args_int + } + \xparse_exp_set:cpx { \l_xparse_tmpa_tl } ##1 \q_xparse_stop ##2 { + \exp_not:N \tl_if_head_eq_charcode:nNTF {##2} #1 { + \exp_not:c { \l_xparse_tmpa_tl aux } + ##1 \exp_not:N \q_xparse_stop + }{ + \exp_not:c { \l_xparse_tmpa_tl aux } + ##1 \exp_not:N \q_xparse_stop #3 #2 {##2} + } + } + \xparse_exp_set:cpx { \l_xparse_tmpa_tl aux} + ##1 \q_xparse_stop ##2 #2 { + \exp_not:c { + \exp_after:wN \token_to_str:N \l_xparse_function_tl + \intexpr_eval:n { \l_xparse_total_args_int + 1 } + } ##1 {##2} \exp_not:N \q_xparse_stop + } + \xparse_exp_prepare_function:N +} +\cs_new_nopar:Npn \xparse_exp_add_type_l:w { + \xparse_exp_set:cpx { + \exp_after:wN \token_to_str:N \l_xparse_function_tl + \int_use:N \l_xparse_total_args_int + } ##1 \q_xparse_stop ##2## { + \exp_not:c { + \exp_after:wN \token_to_str:N \l_xparse_function_tl + \intexpr_eval:n { \l_xparse_total_args_int + 1 } + } + ##1 {##2} \exp_not:N \q_xparse_stop + } + \xparse_exp_prepare_function:N +} +\cs_new_nopar:Npn \xparse_exp_add_type_m:w { + \int_incr:N \l_xparse_m_args_int + \xparse_exp_set:cpx { + \exp_after:wN \token_to_str:N \l_xparse_function_tl + \int_use:N \l_xparse_total_args_int + } ##1 \q_xparse_stop ##2 { + \exp_not:c { + \exp_after:wN \token_to_str:N \l_xparse_function_tl + \intexpr_eval:n { \l_xparse_total_args_int + 1 } + } + ##1 {##2} \exp_not:N \q_xparse_stop + } + \xparse_exp_prepare_function:N +} +\cs_new:Npn \xparse_exp_add_type_t:w #1 { + \tl_set:Nx \l_xparse_tmpa_tl { + \exp_after:wN \token_to_str:N \l_xparse_function_tl + \intexpr_eval:n { \l_xparse_total_args_int + 1 } + } + \xparse_exp_set:cpx { + \exp_after:wN \token_to_str:N \l_xparse_function_tl + \int_use:N \l_xparse_total_args_int + } ##1 \q_xparse_stop ##2 { + \exp_not:N \tl_if_head_eq_charcode:nNTF {##2} #1 { + \exp_not:c { \l_xparse_tmpa_tl } + ##1 \exp_not:n { { \BooleanTrue } \q_xparse_stop } + }{ + \exp_not:c { \l_xparse_tmpa_tl } + ##1 \exp_not:n { { \BooleanFalse } \q_xparse_stop {##2} } + } + } + \xparse_exp_prepare_function:N +} +\cs_new:Npn \xparse_exp_add_type_u:w #1 { + \xparse_exp_set:cpx { + \exp_after:wN \token_to_str:N \l_xparse_function_tl + \int_use:N \l_xparse_total_args_int + } ##1 \q_xparse_stop ##2 #1 { + \exp_not:c { + \exp_after:wN \token_to_str:N \l_xparse_function_tl + \intexpr_eval:n { \l_xparse_total_args_int + 1 } + } + ##1 {##2} \exp_not:N \q_xparse_stop + } + \xparse_exp_prepare_function:N +} +\cs_new_nopar:Nn \xparse_exp_check_and_add:N { + \cs_if_free:cTF { xparse_exp_add_type_ #1 :w } { + \msg_error:nnx { xparse } { unknown-argument-type } {#1} + \tl_set:Nn \l_xparse_last_arg_tl { m } + \xparse_exp_add_type_m:w + }{ + \tl_set:Nn \l_xparse_last_arg_tl {#1} + \use:c { xparse_exp_add_type_ #1 :w } + } +} +\cs_new:Nn \xparse_exp_declare_cmd:Nnn { + \tl_set:Nn \l_xparse_function_tl {#1} + \xparse_exp_prepare_function:n {#2} + \intexpr_compare:nTF { + \l_xparse_total_args_int = \l_xparse_m_args_int + } { + \xparse_exp_declare_cmd_all_m:Nn #1 {#3} + }{ + \xparse_exp_declare_cmd_mixed:Nn #1 {#3} + } +} +\cs_new:Nn \xparse_exp_declare_cmd_all_m:Nn { + \bool_if:NTF \l_xparse_long_bool { + \cs_generate_from_arg_count:NNnn + #1 \cs_set:Npn \l_xparse_total_args_int {#2} + }{ + \cs_generate_from_arg_count:NNnn + #1 \cs_set_nopar:Npn \l_xparse_total_args_int {#2} + } +} +\cs_new:Nn \xparse_exp_declare_cmd_mixed:Nn { + \exp_args:NnV \tl_if_in:nnTF { l m u } \l_xparse_last_arg_tl { + \xparse_exp_declare_cmd_mixed_aux:Nn #1 {#2} + }{ + \msg_error:nn { xparse } { expandable-ending-optional } + } +} +\cs_new:Nn \xparse_exp_declare_cmd_mixed_aux:Nn { + \cs_set_nopar:Npx #1 { + \exp_not:c { \token_to_str:N #1 1 } x \exp_not:N \q_xparse_stop + } + \cs_set_nopar:cpx { + \token_to_str:N #1 \intexpr_eval:n { \l_xparse_total_args_int + 1 } + } x ##1 \q_xparse_stop { + \exp_not:c { \token_to_str:N #1 } ##1 + } + \cs_generate_from_arg_count:cNnn + { \token_to_str:N #1 } \cs_set:Npn \l_xparse_total_args_int {#2} +} +\cs_new:Nn \xparse_exp_prepare_function:n { + \bool_set_false:N \l_xparse_error_bool + \tl_if_in:nnT {#1} { > } { + \msg_error:nnx { xparse } { processor-in-expandable } {#1} + \bool_set_true:N \l_xparse_error_bool + } + \tl_if_in:nnT {#1} { g } { + \msg_error:nnx { xparse } { grouped-in-expandable } {#1} + \bool_set_true:N \l_xparse_error_bool + } + \tl_if_in:nnT {#1} { G } { + \msg_error:nnx { xparse } { grouped-in-expandable } {#1} + \bool_set_true:N \l_xparse_error_bool + } + \bool_if:NF \l_xparse_error_bool { + \xparse_exp_prepare_function_aux:n {#1} + } +} +\cs_new:Nn \xparse_exp_prepare_function_aux:n { + \cs_set_eq:NN \xparse_prepare_next:w \xparse_exp_prepare_function:N + \cs_set_eq:NN \xparse_exp_set:cpx \cs_set_nopar:cpx + \bool_set_false:N \l_xparse_long_bool + \int_zero:N \l_xparse_m_args_int + \int_zero:N \l_xparse_total_args_int + \tl_if_in:nnT {#1} { + } { + \bool_set_true:N \l_xparse_long_bool + \cs_set_eq:NN \xparse_exp_set:cpx \cs_set:cpx + } + \xparse_exp_prepare_function:N #1 \q_nil +} +\cs_new:Nn \xparse_exp_prepare_function:N { + \bool_if:NTF \l_xparse_long_bool { + \xparse_exp_prepare_function_long:N #1 + }{ + \xparse_exp_prepare_function_short:N #1 + } +} +\cs_new:Nn \xparse_exp_prepare_function_long:N { + \quark_if_nil:NF #1 { + \tl_if_eq:nnTF {#1} { + } { + \xparse_exp_prepare_function_short:N + }{ + \msg_error:nn { xparse } { inconsistent-long } + \xparse_exp_prepare_function_short:N #1 + } + + } +} +\cs_new:Nn \xparse_exp_prepare_function_short:N { + \quark_if_nil:NF #1 { + \prop_if_in:NnTF \c_xparse_shorthands_prop {#1} { + \prop_get:NnN \c_xparse_shorthands_prop {#1} \l_xparse_tmp_tl + \bool_if:NT \l_xparse_long_bool { + \tl_put_left:Nn \l_xparse_tmp_tl { + } + } + \exp_last_unbraced:NV \xparse_exp_prepare_function:N + \l_xparse_tmp_tl + }{ + \int_incr:N \l_xparse_total_args_int + \xparse_exp_check_and_add:N #1 + } + } +} +\cs_new_eq:NN \xparse_exp_set:cpx \cs_set_nopar:cpx +\msg_new:nnnn { xparse } { command-already-defined } {% + Command name `\token_to_str:N #1' already defined!% +}{% + You have used \token_to_str:N \NewDocumentCommand\\% + with a command that already has a definition.\\% + Perhaps you meant \token_to_str:N \RenewDocumentCommand.% +} +\msg_new:nnnn { xparse } { command-not-yet-defined } {% + Command `\token_to_str:N #1' not yet defined!% +}{% + You have used \token_to_str:N \RenewDocumentCommand\\% + with a command that was never defined.\\% + Perhaps you meant \token_to_str:N \NewDocumentCommand.% +} +\msg_new:nnn { xparse } { environment-already-defined } {% + Environment `#1' already defined!% +} +\msg_new:nnn { xparse } { environment-not-yet-defined } {% + Environment `#1' not yet defined!% +} +\msg_new:nnnn { xparse } { expandable-ending-optional } {% + Expandable command signature ends in optional argument.% +}{% + Expandable functions must have a final mandatory argument.% +} +\msg_new:nnnn { xparse } { grouped-in-expandable } {% + Optional grouped arguments cannot be used with expandable functions.% +}{% + Argument specification `#1' contains an optional grouped argument:\\% + this is only supported for standard robust functions.% +} +\msg_new:nnnn { xparse } { inconsistent-long } {% + Inconsistent long arguments.% +}{% + Expandable commands must have all arguments long if any at all.% +} +\msg_new:nnnn { xparse } { processor-in-expandable } {% + Argument processors cannot be used with expandable functions.% +}{% + Argument specification `#1' contains a processor function:\\% + this is only supported for standard robust functions.% +} +\msg_new:nnn { xparse } { unknown-argument-type } {% + Unknown argument type `#1' replaced by `m'. Fingers crossed ...% +} +\cs_new_eq:NN \BooleanFalse \c_false_bool +\cs_new_eq:NN \BooleanTrue \c_true_bool +\xparse_declare_cmd:Nnn \DeclareDocumentCommand { +m +m +m } { + \xparse_declare_cmd:Nnn #1 {#2} {#3} +} +\DeclareDocumentCommand \NewDocumentCommand { +m +m +m } { + \cs_if_exist:NTF #1 { + \msg_error:nnx { xparse } { command-already-defined } {#1} + }{ + \xparse_declare_cmd:Nnn #1 {#2} {#3} + } +} +\NewDocumentCommand \RenewDocumentCommand { +m +m +m } { + \cs_if_exist:NTF #1 { + \xparse_declare_cmd:Nnn #1 {#2} {#3} + }{ + \msg_error:nnx { xparse } { command-not-yet-defined } {#1} + } +} +\NewDocumentCommand \ProvideDocumentCommand { +m +m +m } { + \cs_if_exist:NF #1 { + \xparse_declare_cmd:Nnn #1 {#2} {#3} + } +} +\NewDocumentCommand \DeclareDocumentCommandImplementation { m m +m } { + \xparse_declare_cmd_implementation:nNn {#1} #2 {#3} +} +\NewDocumentCommand \DeclareDocumentCommandInterface { m m +m } { + \xparse_declare_cmd_interface:Nnn #1 {#2} {#3} +} +\NewDocumentCommand \DeclareDocumentEnvironment { m +m +m +m } { + \xparse_declare_env:nnnn {#1} {#2} {#3} {#4} +} +\NewDocumentCommand \NewDocumentEnvironment { m +m +m +m } { + \cs_if_exist:cTF { environment_begin_ #1 :w } { + \msg_error:nnx { xparse } { environment-already-defined } {#1} + }{ + \xparse_declare_env:nnnn {#1} {#2} {#3} {#4} + } +} +\NewDocumentCommand \RenewDocumentEnvironment { m +m +m +m } { + \cs_if_exist:cTF { environment_begin_ #1 :w } { + \xparse_declare_env:nnnn {#1} {#2} {#3} {#4} + }{ + \msg_error:nnx { xparse } { environment-not-yet-defined } {#1} + } +} +\NewDocumentCommand \ProvideDocumentEnvironment { m +m +m +m } { + \cs_if_exist:cF { environment_begin_ #1 :w } { + \xparse_declare_env:nnnn {#1} {#2} {#3} {#4} + } +} +\NewDocumentCommand \DeclareExpandableDocumentCommand { +m +m +m } { + \xparse_exp_declare_cmd:Nnn #1 {#2} {#3} +} +\cs_new_eq:NN \IfBooleanTF \bool_if:NTF +\cs_new_eq:NN \IfBooleanT \bool_if:NT +\cs_new_eq:NN \IfBooleanF \bool_if:NF +\cs_new_eq:NN \IfNoValueF \xparse_if_no_value:nF +\cs_new_eq:NN \IfNoValueT \xparse_if_no_value:nT +\cs_new_eq:NN \IfNoValueTF \xparse_if_no_value:nTF +\cs_set:Npn \IfValueF { \xparse_if_no_value:nT } +\cs_set:Npn \IfValueT { \xparse_if_no_value:nF } +\cs_set:Npn \IfValueTF #1#2#3 { + \xparse_if_no_value:nTF {#1} {#3} {#2} +} +\NewDocumentCommand \NoValue { } { -NoValue- } +\endinput +%% +%% End of file `xparse.sty'. diff --git a/Master/texmf-dist/tex/latex/xpackages/xparse.sty b/Master/texmf-dist/tex/latex/xpackages/xparse.sty deleted file mode 100644 index b268d7b0957..00000000000 --- a/Master/texmf-dist/tex/latex/xpackages/xparse.sty +++ /dev/null @@ -1,563 +0,0 @@ -%% -%% This is file `xparse.sty', -%% generated with the docstrip utility. -%% -%% The original source files were: -%% -%% xparse.dtx (with options: `package') -%% -%% (C) Copyright The LaTeX3 Project and any individual authors -%% listed elsewhere in this file. -%% -%% This is a generated file. -%% -%% This file was generated from file(s) of the xbase bundle. -%% --------------------------------------------------------- -%% -%% This file may only be distributed together with a copy of this bundle. -%% You may however distribute the bundle without such generated files. -%% -%% ====================================================================== -%% -%% File: xparse.dtx (C) Copyright 1999 Frank Mittelbach, Chris Rowley, David Carlisle -%% (C) Copyright 2004-2008 Frank Mittelbach, LaTeX3 Project -%% -%% It may be distributed and/or modified under the conditions of the -%% LaTeX Project Public License (LPPL), either version 1.3c of this -%% 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. -%% -%% ----------------------------------------------------------------------- -%% -\RequirePackage{expl3} -\GetIdInfo$Id: xparse.dtx 1365 2009-05-31 17:26:17Z mittelba $ - {generic document command parser} -\ProvidesExplPackage - {\filename}{\filedate}{\fileversion}{\filedescription} -\RequirePackage{expl3} -\cs_new_nopar:Nn \xparse_already_defined_error_msg:N { - \xparse_error:x { - Command~name~`\token_to_str:N #1'~ already~defined! - } -} -\cs_new_nopar:Nn \xparse_not_yet_defined_error_msg:N { - \xparse_error:x { - Command~`\token_to_str:N #1'~ not~ yet~defined! - } -} -\cs_new_nopar:Nn \xparse_begins_with_end_error_msg:N { - \xparse_error:x { - Command~`\token_to_str:N #1'~begins~with~ - `\token_to_str:N \end'! - } -} -\cs_new_nopar:Nn \xparse_unknown_arg_type_error_msg:N { - \xparse_error:x { - Unknown~ argument~ type~ `#1'~ - I'll~ substitute~ it~ with~ `m'~ for~ now.~ Fingers~ crossed... - } -} -\cs_new_nopar:Nn \xparse_no_command_implementation_warning:n { - \xparse_warning:x {No~ implementation~ for~ `#1'~ defined} -} -\cs_new_nopar:Nn \xparse_error:x {\tex_errmessage:D {xparse~error:~#1}} -\cs_new_nopar:Nn \xparse_warning:x {\iow_term:x{xparse~warning:~#1}} -\cs_new_nopar:Npn \xparse_if_definable:NTF #1 { - \cs_if_free:NTF #1 - { - \xparse_begins_with_end:NTF #1 - { \xparse_begins_with_end_error_msg:N #1 \use_ii:nn } - \use_i:nn - } - { \xparse_already_defined_error_msg:N #1 \use_ii:nn } -} -\cs_generate_variant:Nn \xparse_if_definable:NTF {c} -\cs_new_nopar:Npn \xparse_if_redefinable:NTF #1 { - \cs_if_free:NTF #1 - { \xparse_not_yet_defined_error_msg:N #1 \use_ii:nn } - { - \xparse_begins_with_end:NTF #1 - { \xparse_begins_with_end_error_msg:N #1 \use_ii:nn } - \use_i:nn - } -} -\cs_generate_variant:Nn \xparse_if_redefinable:NTF {c} -\cs_new_nopar:Npn \xparse_begins_with_end:NTF #1 { - \group_begin: - \exp_args:Nc \xparse_begins_with_end_aux:N { - \tl_head_iii:f { \cs_to_str:N #1 ??} - } -} -\cs_new_nopar:Nn \xparse_begins_with_end_aux:N { - \if_predicate:w \cs_if_eq_name_p:NN #1 \end - \group_end: - \exp_after:wN \use_i:nn - \else: - \group_end: - \exp_after:wN \use_ii:nn - \fi: -} -\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 -\cs_set:Nn \xparse_declare_document_command:Nnn { - \xparse_prepare_signature:n {#2} - \cs_set_protected_nopar:Npx #1 { - \exp_not:n { \toks_set:Nn \l_xparse_grabbed_args_toks } - {\exp_not:c {\token_to_str:N #1}} - \toks_use:N \l_xparse_grabbed_args_toks - \exp_not:n{ \toks_use:N \l_xparse_grabbed_args_toks} - } - \cs_generate_from_arg_count:cNnn {\token_to_str:N #1}\cs_set:Npn - \l_xparse_total_args_int{#3} -} -\cs_generate_variant:Nn \xparse_declare_document_command:Nnn {cnn} -\cs_new:Nn \xparse_declare_document_environment:nnnn { - \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 - } - \cs_set_eq:cN {end #1} \xparse_parsed_end_environment: - \cs_generate_from_arg_count:cNnn {end \token_to_str:N \\ #1}\cs_set:Npn - \l_xparse_total_args_int{#4} -} -\cs_new_protected_nopar:Nn \xparse_parsed_end_environment: { - \exp_after:wN \xparse_parsed_end_environment_aux:N - \toks_use:N \l_xparse_end_environment_args_toks - \group_end: -} -\cs_new_nopar:Nn \xparse_parsed_end_environment_aux:N { - \use:c {end \token_to_str:N #1 } -} -\cs_new_eq:NN \DeclareDocumentCommand \xparse_declare_document_command:Nnn -\cs_new_nopar:Npn \NewDocumentCommand #1 { - \xparse_if_definable:NTF #1 - { \xparse_declare_document_command:Nnn #1 } - \use_none:nn -} -\cs_new_nopar:Npn \RenewDocumentCommand #1 { - \xparse_if_redefinable:NTF #1 - { \xparse_declare_document_command:Nnn #1 } - \use_none:nn -} -\cs_new_eq:NN \DeclareDocumentEnvironment - \xparse_declare_document_environment:nnnn -\cs_new_nopar:Npn \NewDocumentEnvironment #1 { - \xparse_if_definable:cTF {#1} - { \xparse_declare_document_environment:nnnn {#1} } - \use_none:nnn -} -\cs_new_nopar:Npn \RenewDocumentEnvironment #1 { - \xparse_if_redefinable:cTF {#1} - { \xparse_declare_document_environment:nnnn {#1} } - \use_none:nnn -} -\cs_new_nopar:Npn \ProvideDocumentCommand #1{ - \cs_if_free:NTF #1 - { \DeclareDocumentCommand #1} - \use_none:nn -} -\cs_new_nopar:Npn \ProvideDocumentEnvironment #1{ - \cs_if_free:cTF {#1} - { \DeclareDocumentEnvironment {#1} } - \use_none:nnn -} -\cs_new:Npn \DeclareDocumentCommandInterface #1#2#3{ - \xparse_prepare_signature:n {#3} - \cs_set_protected_nopar: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} - } - \cs_generate_from_arg_count:cNnn {impl-#2} \cs_set:Npn - \l_xparse_total_args_int - {\xparse_undefined_command_implementation:n{#2}} -} -\cs_new_nopar:Nn \xparse_undefined_command_implementation:n { - ``#1'' - \xparse_no_command_implementation_warning:n {#1} -} -\cs_new:Npn \DeclareDocumentCommandImplementation #1#2#3{ - \cs_generate_from_arg_count:cNnn {impl-#1}\cs_set:Npn {#2}{#3} -} -\cs_new_nopar:Nn \xparse_prepare_signature:n { - \int_zero:N \l_xparse_total_args_int - \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 - \tl_gset_eq:NN \g_xparse_ignore_marker_tl - \g_xparse_ignore_spaces_marker_tl - \xparse_parse_signature:n #1 \q_nil -} -\tl_new:Nn \g_xparse_ignore_marker_tl {} -\seq_new:N \g_xparse_ignore_marker_seq -\bool_new:N \g_xparse_insert_marker_bool -\cs_new_nopar:cpn {xparse_add_arg_type_>:} #1 - \xparse_read_arg_type_or_grab_default:n #2{ - \xparse_add_remaining_m_args: - \bool_gset_true:N \g_xparse_insert_marker_bool - \int_decr:N \l_xparse_total_args_int - \tl_map_inline:nn{#2}{ - \xparse_check_and_add_argument_type:N ##1 - } - \xparse_parse_signature:n -} -\cs_new_nopar:Nn \xparse_add_ignore_marker:Nnn { - \tl_new:cn {g_xparse #2 _marker_tl}{#3} - \seq_gpush:Nv \g_xparse_ignore_marker_seq {g_xparse #2 _marker_tl} - \cs_new_nopar:cpn {xparse_add_arg_type_#1:}{ - \tl_gset_eq:Nc \g_xparse_ignore_marker_tl {g_xparse #2 _marker_tl} - } -} -\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} -\cs_new_nopar:Nn \xparse_add_arg_type_P: { - \bool_gset_true:N \g_xparse_allow_par_bool -} -\bool_new:N \g_xparse_allow_par_bool -\cs_new_nopar:Nn \xparse_parse_signature:n { - \quark_if_nil:NTF #1 - { - \xparse_add_remaining_m_args: - } - { - \int_incr:N \l_xparse_total_args_int - \xparse_check_and_add_argument_type:N #1 - \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 - \tl_gset_eq:NN \g_xparse_ignore_marker_tl - \g_xparse_ignore_spaces_marker_tl - } - \xparse_read_arg_type_or_grab_default:n - } -} -\cs_new_nopar:Nn \xparse_check_and_add_argument_type:N { - \cs_if_free:cTF {xparse_add_arg_type_#1:} - { \xparse_unknown_arg_type_error_msg:N #1 - \int_incr:N \l_xparse_mandatory_args_int - } - { \use:c {xparse_add_arg_type_#1:} } -} -\cs_new_eq:NN \xparse_read_arg_type_or_grab_default:n - \xparse_parse_signature:n -\cs_new_nopar:Nn \xparse_grab_default_arg:n { - \toks_put_right:Nn \l_xparse_grabbed_args_toks {{#1}} - \cs_set_eq:NN \xparse_read_arg_type_or_grab_default:n - \xparse_parse_signature:n - \xparse_parse_signature:n -} -\cs_new:Nn \xparse_grab_default_arg_allow_par:n { - \toks_put_right:Nn \l_xparse_grabbed_args_toks {{#1}} - \cs_set_eq:NN \xparse_read_arg_type_or_grab_default:n - \xparse_parse_signature:n - \xparse_parse_signature:n -} -\cs_new_nopar:Nn \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 } -} -\cs_new_nopar:Nn \xparse_add_remaining_m_args: { - \intexpr_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 - } -} -\cs_new_nopar: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 -} -\cs_new_nopar: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 -} -\cs_new_nopar: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 -} -\cs_new_nopar: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 -} -\cs_new_nopar: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 -} -\cs_new_nopar: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 -} -\cs_new_nopar: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 -} -\cs_new_nopar: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 -} -\cs_new_nopar: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 -} -\cs_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 -} -\cs_new_nopar:Nn \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} } -} -\cs_new_nopar: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 -} -\cs_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 -} -\cs_new_nopar:Npn \DeclareSymbolArgument #1#2{ - \seq_map_variable:NNn \g_xparse_ignore_marker_seq \l_tmpa_tl { - \cs_set_nopar:cpx {xparse \l_tmpa_tl _#1:w}##1##2 - \l_xparse_grabbed_args_toks{ - \exp_not:c{peek_ #2 _remove \l_tmpa_tl :NTF} ##1 - { - \exp_not:N \toks_put_right:Nn \exp_not:N - \l_xparse_grabbed_args_toks \exp_not:N \c_true_bool - ##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_bool - ##2 \exp_not:N\l_xparse_grabbed_args_toks - } - } - } - \cs_set_nopar: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_tl _#1:w } } - \cs_set_eq:NN \xparse_read_arg_type_or_grab_default:n - \xparse_grab_default_arg:n - } -} -\DeclareSymbolArgument S{meaning} -\cs_new_nopar:Npn \DeclareArgumentType #1#2#3#4#5#6#7{ - \seq_map_variable:NNn \g_xparse_ignore_marker_seq \l_tmpa_tl { - \cs_set_nopar:cpx {xparse \l_tmpa_tl _#1:w}##1\l_xparse_grabbed_args_toks{ - \exp_not:c{peek_#3 \l_tmpa_tl :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 - } - } - \cs_set:cpx {xparse_allow_par \l_tmpa_tl _#1:w}##1 - \l_xparse_grabbed_args_toks{ - \exp_not:c{peek_#3 \l_tmpa_tl :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 - } - } - } - \cs_set_nopar:cpn {xparse_add_arg_type_#1:} { - \xparse_add_remaining_m_args: - \toks_put_right:Nx \l_xparse_grabbed_args_toks { - \exp_not:c {xparse - \bool_if:NT \g_xparse_allow_par_bool {_allow_par} - \g_xparse_ignore_marker_tl - _#1:w - } - } - \cs_set_eq:NN \xparse_read_arg_type_or_grab_default:n \xparse_parse_signature:n - } - \xparse_define_helper:Nnnn #1{#3}{#6}{#7} -} -\cs_new_nopar:Npn \DeclareArgumentTypeDefaultValue #1#2#3#4#5{ - \seq_map_variable:NNn \g_xparse_ignore_marker_seq \l_tmpa_tl { - \cs_set_nopar:cpx {xparse \l_tmpa_tl _#1:w}##1##2\l_xparse_grabbed_args_toks{ - \exp_not:c{peek_#3 \l_tmpa_tl :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 - } - } - \cs_set:cpx {xparse_allow_par \l_tmpa_tl _#1:w}##1##2 - \l_xparse_grabbed_args_toks{ - \exp_not:c{peek_#3 \l_tmpa_tl :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 - } - } - } - \cs_set_nopar:cpn {xparse_add_arg_type_#1:} { - \xparse_add_remaining_m_args: - \toks_put_right:Nx \l_xparse_grabbed_args_toks { - \exp_not:c {xparse - \bool_if:NT \g_xparse_allow_par_bool {_allow_par} - \g_xparse_ignore_marker_tl - _#1:w - } - } - \cs_set_eq:Nc \xparse_read_arg_type_or_grab_default:n - {xparse_grab_default_arg - \bool_if:NT \g_xparse_allow_par_bool {_allow_par} - :n - } - } - \xparse_define_helper:Nnnn #1{#3}{#4}{#5} -} -\cs_new_nopar:Nn \xparse_define_helper:Nnnn { - \toks_set:Nn \l_tmpa_toks - { - #3 - { - \toks_put_right:Nn \l_xparse_grabbed_args_toks {{#4}} - ##1 \l_xparse_grabbed_args_toks - } - } - \toks_set:Nx \l_tmpa_toks { - \exp_not:n {\cs_set_nopar:cpn{xparse_#1_#2_help:nw}} - \toks_use:N \l_tmpa_toks - \exp_not:n {\cs_set_nopar:cpn{xparse_allow_par_#1_#2_help:nw}} - \toks_use:N\l_tmpa_toks - } - \toks_use:N \l_tmpa_toks -} -\DeclareArgumentType o[{meaning}{}{\NoValue}{#1[#2]}{#2} -\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}} -\cs_new_nopar:Npn \DeclareArgumentTypeShorthand #1#2{ - \cs_new_nopar: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 - } -} -\DeclareArgumentTypeShorthand s {S{*}} -\cs_new_eq:NN \IfBooleanTF \bool_if:NTF -\cs_new_eq:NN \IfBooleanT \bool_if:NT -\cs_new_eq:NN \IfBooleanF \bool_if:NF -\tl_new:Nn \NoValue {-NoValue-} -\tl_new:Nn \c_xparse_hidden_no_value_tl {\NoValue} -\cs_new:Npn \xparse_if_no_value:nTF #1{ - \tl_set:Nx \l_tmpa_tl{\exp_not:n{#1}} - \tl_if_eq:NNTF \l_tmpa_tl \c_xparse_hidden_no_value_tl - { \use_i:nn } - { \tl_if_blank:nTF {#1} - { \use_ii:nn } - {\peek_after:NN \xparse_if_no_value_aux: #1 \q_nil {#1} } - } -} -\cs_new:Nn \xparse_if_no_value_aux: { - \tl_set:Nx \l_tmpa_tl{\token_get_arg_spec:N \l_peek_token } - \tl_if_empty:NTF \l_tmpa_tl - {\use_i_delimit_by_q_nil:nw {\exp_args:No\xparse_if_no_value:nTF}} - {\use_i_delimit_by_q_nil:nw {\use_iii:nnn}} -} -\cs_new_eq:NN \IfNoValueTF \xparse_if_no_value:nTF -\cs_new:Npn \IfNoValueT #1#2 {\xparse_if_no_value:nTF{#1}{#2}{}} -\cs_new:Npn \IfNoValueF #1 {\xparse_if_no_value:nTF {#1}{}} -\cs_new:Npn \IfValueTF #1#2#3{\xparse_if_no_value:nTF {#1}{#3}{#2}} -\cs_new_eq:NN \IfValueT \IfNoValueF -\cs_new_eq:NN \IfValueF \IfNoValueT -\tl_new:Nn \l_xparse_pseudo_post_arg_tl {} -\cs_new:Npn \DeclarePseudoArgument #1#2#3#4{ - \cs_set:cn {xparse_pseudo_pre_arg_#1:\prg_replicate:nn{#2}{n}} {#3} - \cs_set:cn {xparse_pseudo_post_arg_#1:\prg_replicate:nn{#2}{n}} {#4} - \cs_set_nopar:cn {xparse_pseudo_nobrace_arg_#1:N} { - ##1 \l_xparse_pseudo_post_arg_tl - } - \cs_generate_from_arg_count:cNnn {xparse_pseudo_arg_#1:w} - \cs_set:Npx {#2} - { - \exp_not:c { - xparse_pseudo_pre_arg_#1: \prg_replicate:nn{#2}{n} - } - \use:c{use_ \intexpr_eval:n{#2} _parameter:} - \exp_not:n {\tl_set:Nn \l_xparse_pseudo_post_arg_tl} - { - \exp_not:c {xparse_pseudo_post_arg_#1:\prg_replicate:nn{#2}{n}} - \use:c{use_ \intexpr_eval:n{#2}_parameter:} - } - \exp_not:n{ \peek_catcode_remove_ignore_spaces:NTF \c_group_begin_token } - { - \exp_not:n { - \c_group_begin_token - \group_execute_after:N \l_xparse_pseudo_post_arg_tl - } - } - { - \exp_not:c{xparse_pseudo_nobrace_arg_#1:N} - } - } -} -\cs_new_nopar:Npn \UsePseudoArgument #1{\use:c{xparse_pseudo_arg_#1:w}} -\endinput -%% -%% End of file `xparse.sty'. diff --git a/Master/texmf-dist/tex/latex/xpackages/xtras/l3keys2e.sty b/Master/texmf-dist/tex/latex/xpackages/xtras/l3keys2e.sty new file mode 100644 index 00000000000..67e67fe285a --- /dev/null +++ b/Master/texmf-dist/tex/latex/xpackages/xtras/l3keys2e.sty @@ -0,0 +1,117 @@ +%% +%% This is file `l3keys2e.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% l3keys2e.dtx (with options: `package') +%% ---------------------------------------------------------------- +%% l3keys2e --- Parsing LaTeX3 keyvals as LaTeX2e package options +%% Copyright 2009 The LaTeX3 Project +%% Released under the LaTeX Project Public License v1.3c or later +%% See http://www.latex-project.org/lppl.txt +%% ---------------------------------------------------------------- +%% File: l3keys2e.dtx (C) Copyright 2009 LaTeX3 Project +%% +%% It may be distributed and/or modified under the conditions of the +%% LaTeX Project Public License (LPPL), either version 1.3c of this +%% license or (at your option) any later version. The latest version +%% of this license is in the file +%% +%% http://www.latex-project.org/lppl.txt +%% +%% This file is part of the ``l3keys2e'' (The Work in LPPL) +%% and all files in that bundle must be distributed together. +%% +%% The released version of this bundle is available from CTAN. +%% +%% ----------------------------------------------------------------------- +%% +%% The development version of the bundle can be found at +%% +%% http://www.latex-project.org/svnroot/experimental/trunk/ +%% +%% for those people who are interested. +%% +%%%%%%%%%%% +%% NOTE: %% +%%%%%%%%%%% +%% +%% Snapshots taken from the repository represent work in progress and may +%% not work or may contain conflicting material! We therefore ask +%% people _not_ to put them into distributions, archives, etc. without +%% prior consultation with the LaTeX Project Team. +%% +%% ----------------------------------------------------------------------- +%% +\RequirePackage{l3names} +\GetIdInfo$Id: l3keys2e.dtx 1494 2009-08-24 11:05:44Z joseph $ + {Parsing LaTeX3 keyvals as LaTeX2e package options} +\ProvidesExplPackage + {\filename}{\filedate}{\fileversion}{\filedescription} +\RequirePackage{xparse} +\clist_new:N \keys_latexe_options_clist +\cs_new:Nn \keys_latexe_options:n { + \clist_clear:N \keys_latexe_options_clist + \keys_latexe_options_global:n {#1} + \keys_latexe_options_local: + \keys_if_exist:nnF {#1} { unknown } { + \keys_define:nn {#1} { + unknown .code:n = { + \msg_warning:nnxx { Option~Processing } { unknown-option } + { \l_keys_key_tl } { \@currname } + } + } + } + \keys_set:nV {#1} \keys_latexe_options_clist + \AtEndOfPackage { \cs_set_eq:NN \@unprocessedoptions \scan_stop: } +} +\msg_new:nnn { Option~Processing } { unknown-option } {% + Unknown~option~`#1'\\% + for~module~#2.% +} +\cs_new:Nn \keys_latexe_options_global:n { + \cs_if_eq:NNF \@classoptionslist \scan_stop: { + \cs_if_eq:NNTF \@currext \@clsextension { + \keys_latexe_options_class:n {#1} + }{ + \keys_latexe_options_package:n {#1} + } + } +} +\cs_new:Nn \keys_latexe_options_class:n { + \clist_map_inline:Nn \@classoptionslist { + \keys_if_exist:nnTF {#1} { \keys_latexe_remove_equals:n {##1} } { + \clist_put_right:Nn \keys_latexe_options_clist {##1} + }{ + \clist_put_right:Nn \@unusedoptionlist {##1} + } + } +} +\cs_new:Nn \keys_latexe_options_package:n { + \clist_map_inline:Nn \@classoptionslist { + \keys_if_exist:nnT {#1} { \keys_latexe_remove_equals:n {##1} } { + \clist_put_right:Nn \keys_latexe_options_clist {##1} + \clist_remove_element:Nn \@unusedoptionlist {##1} + } + } +} +\cs_new_nopar:Nn \keys_latexe_options_local: { + \cs_if_eq:NNF \@currext \@clsextension { + \cs_if_exist:cT { opt@ \@currname . \@currext } { + \exp_args:NNc \clist_put_right:NV \keys_latexe_options_clist + { opt@ \@currname . \@currext } + } + } +} +\cs_new:Nn \keys_latexe_remove_equals:n { + \keys_latexe_remove_equals:w #1 = \q_stop +} +\cs_new:Npn \keys_latexe_remove_equals:w #1 = #2 \q_stop {#1} +\NewDocumentCommand \ProcessKeysOptions { m } { + \keys_latexe_options:n {#1} +} +\@onlypreamble \ProcessKeysOptions +\endinput +%% +%% End of file `l3keys2e.sty'. |