diff options
author | Karl Berry <karl@freefriends.org> | 2018-04-30 22:39:09 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2018-04-30 22:39:09 +0000 |
commit | a28e1bfccd6fe522fcd296426e4d89c7fb4f19b6 (patch) | |
tree | b72347e08575b56fcfed87c4d837b48dcfd1e02a /Master/texmf-dist/source/latex/l3packages/xparse/xparse.dtx | |
parent | b40c37a9e22b8235ff9c0bc256d00f7af94304c3 (diff) |
l3 (30apr18)
git-svn-id: svn://tug.org/texlive/trunk@47516 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex/l3packages/xparse/xparse.dtx')
-rw-r--r-- | Master/texmf-dist/source/latex/l3packages/xparse/xparse.dtx | 180 |
1 files changed, 121 insertions, 59 deletions
diff --git a/Master/texmf-dist/source/latex/l3packages/xparse/xparse.dtx b/Master/texmf-dist/source/latex/l3packages/xparse/xparse.dtx index 045d969b6ba..c7ec377316e 100644 --- a/Master/texmf-dist/source/latex/l3packages/xparse/xparse.dtx +++ b/Master/texmf-dist/source/latex/l3packages/xparse/xparse.dtx @@ -4,7 +4,7 @@ %% David Carlisle %% (C) Copyright 2004-2008 Frank Mittelbach, %% The LaTeX3 Project -%% (C) Copyright 2009-2017 The LaTeX3 Project +%% (C) Copyright 2009-2018 The LaTeX3 Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -27,8 +27,8 @@ %<*driver|package> % The version of expl3 required is tested as early as possible, as % some really old versions do not define \ProvidesExplPackage. -\RequirePackage{expl3}[2018/02/21] -%<package>\@ifpackagelater{expl3}{2018/02/21} +\RequirePackage{expl3}[2018-04-12] +%<package>\@ifpackagelater{expl3}{2018-04-12} %<package> {} %<package> {% %<package> \PackageError{xparse}{Support package l3kernel too old} @@ -67,7 +67,7 @@ % }^^A % } % -% \date{Released 2018/02/21} +% \date{Released 2018-04-30} % % \maketitle % @@ -130,8 +130,6 @@ % 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 -% begin-group token: in standard \LaTeX{} this is a left brace. % \item[r] Reads a \enquote{required} delimited argument, where the % delimiters are given as \meta{char1} and \meta{char2}: % \texttt{r}\meta{char1}\meta{char2}. If the opening \meta{character} @@ -140,9 +138,6 @@ % \item[R] As for \texttt{r}, this is a \enquote{required} delimited % argument but has a user-definable recovery \meta{default}, given % as \texttt{R}\meta{char1}\meta{char2}\marg{default}. -% \item[u] Reads an argument \enquote{until} \meta{tokens} are encountered, -% where the desired \meta{tokens} are given as an argument to the -% specifier: \texttt{u}\marg{tokens}. % \item[v] Reads an argument \enquote{verbatim}, between the following % character and its next occurrence, in a way similar to the argument % of the \LaTeXe{} command \cs{verb}. Thus a \texttt{v}-type argument @@ -174,11 +169,6 @@ % \item[t] An optional \meta{char}, which will result in a value % \cs{BooleanTrue} if \meta{char} is present and \cs{BooleanFalse} % otherwise. Given as \texttt{t}\meta{char}. -% \item[g] An optional argument given inside a pair of \TeX{} group -% tokens (in standard \LaTeX, |{| \ldots |}|), which returns -% |-NoValue-| if not present. -% \item[G] As for \texttt{g} but returns \meta{default} if no value -% is given: \texttt{G}\marg{default}. % \item[e] A set of optional \emph{embellishments}, each of which % requires a \emph{value}: \texttt{e}\marg{chars}. If an % embellishment is not present, |-NoValue-| is returned. Each @@ -257,6 +247,20 @@ % arguments, but also to \texttt{g} or \texttt{G} type arguments % followed by \texttt{m} type arguments. % +% As \pkg{xparse} is also used to describe interfaces that have appeared +% in the wider \LaTeXe{} eco-system, it also defines additional argument +% types, described in Section~\ref{sec:backwards}: the mandatory types +% \texttt{l} and \texttt{u} and the optional brace group types +% \texttt{g} and \texttt{G}. Their use is not recommended because it is +% simpler for a user if all packages use a similar syntax. For the same +% reason, delimited arguments \texttt{r}, \texttt{R}, \texttt{d} and +% \texttt{D} should normally use delimiters that are naturally paired, +% such as |[| and |]| or |(| and |)|, or that are identical, such as |"| +% and~|"|. A very common syntax is to have one optional argument +% \texttt{o} treated as a key--value list (using for instance +% \pkg{l3keys}) followed by some mandatory arguments~\texttt{m} (or +% \texttt{+m}). +% % \subsection{Spacing and optional arguments} % % \TeX{} will find the first argument after a function name irrespective @@ -270,20 +274,31 @@ % \end{verbatim} % the user input |\foo{arg1}[arg2]{arg3}| and % \verb*|\foo{arg1} [arg2] {arg3}| will both be parsed in the same -% way. However, spaces are \emph{not} ignored when parsing optional -% arguments after the last mandatory argument. Thus with +% way. +% +% The behavior of optional arguments \emph{after} any mandatory arguments is +% selectable. The standard settings will allow spaces here, and thus +% with % \begin{verbatim} % \NewDocumentCommand \foobar { m o } { ... } % \end{verbatim} -% |\foobar{arg1}[arg2]| will find an optional argument but -% \verb*|\foobar{arg1} [arg2]| will not. This is so that trailing optional -% arguments are not picked up \enquote{by accident} in input. -% -% There is one major exception to the rules listed above: when -% \pkg{xparse} is used to define what \TeX\ defines as \enquote{control -% symbols} in which the function name is made up of a single character, -% such as \enquote{\cmd{\\}}, spaces are \emph{not} ignored directly -% after them even for mandatory arguments. +% both |\foobar{arg1}[arg2]| and \verb*|\foobar{arg1} [arg2]| will find an +% optional argument. This can be changed by giving the modified |!| in +% the argument specification: +% \begin{verbatim} +% \NewDocumentCommand \foobar { m !o } { ... } +% \end{verbatim} +% where \verb*|\foobar{arg1} [arg2]| will not find an optional argument. +% +% There is one subtly here due to the difference in handling by \TeX{} +% of \enquote{control symbols}, where the command name is made up of a single +% character, such as \enquote{\cmd{\\}}. Spaces are not ignored by \TeX{} +% here, and thus it is possible to require an optional argument directly +% follow such a command. The most common example is the use of \cmd{\\} in +% \pkg{amsmath} environments. In \pkg{xparse} terms it has signature +% \begin{verbatim} +% \DeclareDocumentCommad \\ { !s !o } { ... } +% \end{verbatim} % % \subsection{Required delimited arguments} % @@ -761,6 +776,33 @@ % \end{verbatim} % this may be suppressed and no information messages are produced. % +% \section{Backwards Compatibility} +% \label{sec:backwards} +% +% One role of \pkg{xparse} is to describe existing \LaTeX{} interfaces, +% including some that are rather unusual in \LaTeX{} (as opposed to +% formats such as plain \TeX{}) such as delimited arguments. As such, +% the package defines some argument specifiers that should largely be +% avoided nowadays as using them in packages leads to inconsistent user +% interfaces. The simplest syntax is often best, with argument +% specifications such as |mmmm| or |ommmm|, namely an optional argument +% followed by some standard mandatory ones. The optional argument can +% be made to support key--value syntax using tools from \pkg{l3keys}. +% +% The argument types that are not recommended any longer are: +% \begin{itemize}[font=\ttfamily] +% \item[l] A mandatory argument which reads everything up to the first +% begin-group token: in standard \LaTeX{} this is a left brace. +% \item[u] Reads a mandatory argument \enquote{until} \meta{tokens} are encountered, +% where the desired \meta{tokens} are given as an argument to the +% specifier: \texttt{u}\marg{tokens}. +% \item[g] An optional argument given inside a pair of \TeX{} group +% tokens (in standard \LaTeX{}, |{| \ldots |}|), which returns +% |-NoValue-| if not present. +% \item[G] As for \texttt{g} but returns \meta{default} if no value +% is given: \texttt{G}\marg{default}. +% \end{itemize} +% % \end{documentation} % % \begin{implementation} @@ -776,7 +818,7 @@ % \end{macrocode} % % \begin{macrocode} -\ProvidesExplPackage{xparse}{2018/02/21}{} +\ProvidesExplPackage{xparse}{2018-04-30}{} {L3 Experimental document command parser} % \end{macrocode} % @@ -929,6 +971,13 @@ % \end{macrocode} % \end{variable} % +% \begin{variable}{\l_@@_ignore_spaces_bool} +% For trailing optionals. +% \begin{macrocode} +\bool_new:N \l_@@_ignore_spaces_bool +% \end{macrocode} +% \end{variable} +% % \begin{variable}{\l_@@_m_args_int} % The number of \texttt{m} arguments: if this is the same as the total % number of arguments, then a short-cut can be taken in the creation of @@ -1527,6 +1576,7 @@ \bool_set_false:N \l_@@_long_bool \bool_set_false:N \l_@@_some_long_bool \bool_set_false:N \l_@@_some_short_bool + \bool_set_false:N \l_@@_ignore_spaces_bool \@@_normalize_arg_spec_loop:n #1 \q_recursion_tail \q_recursion_tail \q_recursion_tail \q_recursion_stop \int_compare:nNnT \l_@@_current_arg_int > 9 @@ -1615,6 +1665,7 @@ % { % \@@_normalize_type_>:w, % \@@_normalize_type_+:w, +% \@@_normalize_type_!:w, % } % Check that these prefixes have arguments, namely that the next token % is not \cs{q_recursion_tail}, and remember to leave it after the @@ -1645,6 +1696,13 @@ \int_decr:N \l_@@_current_arg_int \@@_normalize_arg_spec_loop:n {#1} } +\cs_new_protected:cpn { @@_normalize_type_!:w } #1 + { + \quark_if_recursion_tail_stop_do:nn {#1} { \@@_bad_arg_spec:wn } + \tl_put_right:Nn \l_@@_arg_spec_tl { ! } + \int_decr:N \l_@@_current_arg_int + \@@_normalize_arg_spec_loop:n {#1} + } % \end{macrocode} % \end{macro} % @@ -1793,7 +1851,7 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_single_char_check:n #1 { - \exp_args:Nx \tl_if_single_token:nTF { \tl_trim_spaces:n {#1} } + \tl_trim_spaces_apply:nN {#1} \tl_if_single_token:nTF { \group_begin: \tex_escapechar:D = 92 \scan_stop: @@ -1923,6 +1981,7 @@ { \int_zero:N \l_@@_current_arg_int \bool_set_false:N \l_@@_long_bool + \bool_set_false:N \l_@@_ignore_spaces_bool \int_zero:N \l_@@_m_args_int \bool_set_false:N \l_@@_defaults_bool \tl_clear:N \l_@@_defaults_tl @@ -1991,6 +2050,19 @@ % \end{macrocode} % \end{macro} % +% \begin{macro}{\@@_add_type_!:w} +% Much the same for controlling trailing optional arguments. +% \begin{macrocode} +\cs_new_protected:cpn { @@_add_type_!:w } + { + \@@_flush_m_args: + \bool_set_true:N \l_@@_ignore_spaces_bool + \bool_set_true:N \l_@@_prefixed_bool + \@@_prepare_signature_bypass:N + } +% \end{macrocode} +% \end{macro} +% % \begin{macro}{\@@_add_type_>:w} % When a processor is found, the processor code is stored. It will be % used by \cs{@@_args_process:} once arguments are all found. Here, @@ -2195,12 +2267,15 @@ { @@_grab_ #1 \bool_if:NT \l_@@_long_bool { _long } - \int_compare:nNnF \l_@@_mandatory_args_int > 0 - { _trailing } + \bool_lazy_and:nnT + { \l_@@_ignore_spaces_bool } + { \int_compare_p:nNn \l_@@_mandatory_args_int = 0 } + { _ignore_spaces } :w } } \bool_set_false:N \l_@@_long_bool + \bool_set_false:N \l_@@_ignore_spaces_bool \tl_put_right:Nx \l_@@_process_all_tl { { \exp_not:o \l_@@_process_one_tl } } \tl_clear:N \l_@@_process_one_tl @@ -2498,8 +2573,8 @@ % % \begin{macro}{\@@_grab_D:w} % \begin{macro}{\@@_grab_D_long:w} -% \begin{macro}{\@@_grab_D_trailing:w} -% \begin{macro}{\@@_grab_D_long_trailing:w} +% \begin{macro}{\@@_grab_D_ignore_spaces:w} +% \begin{macro}{\@@_grab_D_long_ignore_spaces:w} % The generic delimited argument grabber. The auxiliary function does % a peek test before calling \cs{@@_grab_D_call:Nw}, so that the % optional nature of the argument works as expected. @@ -2514,9 +2589,9 @@ \@@_grab_D_aux:NNnNn #1 #2 {#3} \cs_set_protected:Npn { _ignore_spaces } } -\cs_new_protected:Npn \@@_grab_D_trailing:w #1#2#3 \@@_run_code: +\cs_new_protected:Npn \@@_grab_D_ignore_spaces:w #1#2#3 \@@_run_code: { \@@_grab_D_aux:NNnNn #1 #2 {#3} \cs_set_protected_nopar:Npn { } } -\cs_new_protected:Npn \@@_grab_D_long_trailing:w #1#2#3 \@@_run_code: +\cs_new_protected:Npn \@@_grab_D_long_ignore_spaces:w #1#2#3 \@@_run_code: { \@@_grab_D_aux:NNnNn #1 #2 {#3} \cs_set_protected:Npn { } } % \end{macrocode} % \begin{macro}{\@@_grab_D_aux:NNnNn} @@ -2668,7 +2743,7 @@ % \begin{macro} % { % \@@_grab_E:w, \@@_grab_E_long:w, -% \@@_grab_E_trailing:w, \@@_grab_E_long_trailing:w +% \@@_grab_E_ignore_spaces:w, \@@_grab_E_long_ignore_spaces:w % } % \begin{macro}{\@@_grab_E:nnNn} % \begin{macro}{\@@_grab_E_loop:nnN} @@ -2687,13 +2762,13 @@ \cs_set_protected:Npn { _ignore_spaces } } -\cs_new_protected:Npn \@@_grab_E_trailing:w #1#2 \@@_run_code: +\cs_new_protected:Npn \@@_grab_E_ignore_spaces:w #1#2 \@@_run_code: { \@@_grab_E:nnNn {#1} {#2} \cs_set_protected_nopar:Npn { } } -\cs_new_protected:Npn \@@_grab_E_long_trailing:w #1#2 \@@_run_code: +\cs_new_protected:Npn \@@_grab_E_long_ignore_spaces:w #1#2 \@@_run_code: { \@@_grab_E:nnNn {#1} {#2} \cs_set_protected:Npn @@ -2746,11 +2821,11 @@ % % \begin{macro}{\@@_grab_G:w} % \begin{macro}{\@@_grab_G_long:w} -% \begin{macro}{\@@_grab_G_trailing:w} -% \begin{macro}{\@@_grab_G_long_trailing:w} +% \begin{macro}{\@@_grab_G_ignore_spaces:w} +% \begin{macro}{\@@_grab_G_long_ignore_spaces:w} % \begin{macro}{\@@_grab_G_aux:nNn} % Optional groups are checked by meaning, so that the same code will -% work with, for example, Con\TeX{}t-like input. +% work with, for example, \ConTeXt{}-like input. % \begin{macrocode} \cs_new_protected:Npn \@@_grab_G:w #1 \@@_run_code: { @@ -2761,9 +2836,9 @@ { \@@_grab_G_aux:nNn {#1} \cs_set_protected:Npn { _ignore_spaces } } -\cs_new_protected:Npn \@@_grab_G_trailing:w #1 \@@_run_code: +\cs_new_protected:Npn \@@_grab_G_ignore_spaces:w #1 \@@_run_code: { \@@_grab_G_aux:nNn {#1} \cs_set_protected_nopar:Npn { } } -\cs_new_protected:Npn \@@_grab_G_long_trailing:w #1 \@@_run_code: +\cs_new_protected:Npn \@@_grab_G_long_ignore_spaces:w #1 \@@_run_code: { \@@_grab_G_aux:nNn {#1} \cs_set_protected:Npn { } } \cs_new_protected:Npn \@@_grab_G_aux:nNn #1#2#3 { @@ -2938,8 +3013,8 @@ % % \begin{macro}{\@@_grab_t:w} % \begin{macro}{\@@_grab_t_long:w} -% \begin{macro}{\@@_grab_t_trailing:w} -% \begin{macro}{\@@_grab_t_long_trailing:w} +% \begin{macro}{\@@_grab_t_ignore_spaces:w} +% \begin{macro}{\@@_grab_t_long_ignore_spaces:w} % \begin{macro}{\@@_grab_t_aux:NNw} % Dealing with a token is quite easy. Check the match, remove the % token if needed and add a flag to the output. @@ -2947,9 +3022,9 @@ \cs_new_protected:Npn \@@_grab_t:w { \@@_grab_t_aux:NNw \peek_meaning_remove_ignore_spaces:NTF } \cs_new_eq:NN \@@_grab_t_long:w \@@_grab_t:w -\cs_new_protected:Npn \@@_grab_t_trailing:w +\cs_new_protected:Npn \@@_grab_t_ignore_spaces:w { \@@_grab_t_aux:NNw \peek_meaning_remove:NTF } -\cs_new_eq:NN \@@_grab_t_long_trailing:w \@@_grab_t_trailing:w +\cs_new_eq:NN \@@_grab_t_long_ignore_spaces:w \@@_grab_t_ignore_spaces:w \cs_new_protected:Npn \@@_grab_t_aux:NNw #1#2#3 \@@_run_code: { \tl_set:Nn \l_@@_signature_tl {#3} @@ -3895,7 +3970,7 @@ % local must be closed. % \begin{macrocode} \cs_new_protected:Npn \@@_check_definable:nNT #1 - { \exp_args:Nx \@@_check_definable_aux:nN { \tl_trim_spaces:n {#1} } } + { \tl_trim_spaces_apply:nN {#1} \@@_check_definable_aux:nN } \group_begin: \char_set_catcode_active:n { `? } \cs_new_protected:Npn \@@_check_definable_aux:nN #1#2 @@ -3998,7 +4073,6 @@ \__kernel_msg_new:nnnn { xparse } { bad-arg-spec } { Bad~argument~specification~'#2'~for~command~'#1'. } { - \c__msg_coding_error_text_tl The~argument~specification~provided~was~not~valid:~ one~or~more~mandatory~pieces~of~information~were~missing. \\ \\ LaTeX~will~ignore~this~entire~definition. @@ -4037,7 +4111,6 @@ ends~with~optional~argument. } { - \c__msg_coding_error_text_tl Expandable~commands~must~have~a~final~mandatory~argument~ (or~no~arguments~at~all).~You~cannot~have~a~terminal~optional~ argument~with~expandable~commands. @@ -4045,21 +4118,18 @@ \__kernel_msg_new:nnnn { xparse } { if-boolean } { Invalid~use~\iow_char:N\\IfBooleanTF~{#1} } { - \c__msg_coding_error_text_tl The~first~argument~of~\iow_char:N\\IfBoolean(TF/T/F)~must~be~ a~boolean~argument~obtained~from~parsing~'s'~or~'t'~arguments. } \__kernel_msg_new:nnnn { xparse } { inconsistent-long } { Inconsistent~long~arguments~for~expandable~command~'#1'. } { - \c__msg_coding_error_text_tl The~arguments~for~an~expandable~command~must~not~involve~short~ arguments~after~long~arguments.~You~have~tried~to~mix~the~two~types. } \__kernel_msg_new:nnnn { xparse } { invalid-expandable-argument-type } { Argument~type~'#2'~not~available~for~expandable~command~'#1'. } { - \c__msg_coding_error_text_tl The~letter~'#2'~does~not~specify~an~argument~type~which~can~be~used~ in~an~expandable~command. \\ \\ @@ -4071,7 +4141,6 @@ for~expandable~command~'#1'. } { - \c__msg_coding_error_text_tl The~letter~'#2'~does~not~specify~an~argument~type~which~can~be~used~ in~an~expandable~command~after~an~optional~argument. \\ \\ @@ -4080,7 +4149,6 @@ \__kernel_msg_new:nnnn { xparse } { loop-in-defaults } { Circular~dependency~in~defaults~of~'#1'. } { - \c__msg_coding_error_text_tl The~default~values~of~two~or~more~arguments~of~'#1'~depend~on~each~ other~in~a~way~that~cannot~be~resolved. } @@ -4105,7 +4173,6 @@ \__kernel_msg_new:nnnn { xparse } { not-definable } { First~argument~of~'#2'~must~be~a~command. } { - \c__msg_coding_error_text_tl The~first~argument~of~'#2'~should~be~the~document~command~that~will~ be~defined.~The~provided~argument~'#1'~is~a~character.~Perhaps~a~ backslash~is~missing? @@ -4115,7 +4182,6 @@ \__kernel_msg_new:nnnn { xparse } { not-one-token } { First~argument~of~'#2'~must~be~a~command. } { - \c__msg_coding_error_text_tl The~first~argument~of~'#2'~should~be~the~document~command~that~will~ be~defined.~The~provided~argument~'#1'~contains~more~than~one~ token. @@ -4128,7 +4194,6 @@ a~single~character. } { - \c__msg_coding_error_text_tl The~argument~specification~provided~was~not~valid:~in~a~place~ where~a~single~character~is~required,~LaTeX~found~'#2'. \\ \\ LaTeX~will~ignore~this~entire~definition. @@ -4136,7 +4201,6 @@ \__kernel_msg_new:nnnn { xparse } { processor-in-expandable } { Argument~processor~'>{#2}'~cannot~be~used~for~the~expandable~command~'#1'. } { - \c__msg_coding_error_text_tl The~argument~specification~for~#1~contains~a~processor~function:~ this~is~only~supported~for~standard~robust~commands. \\ \\ LaTeX~will~ignore~this~entire~definition. @@ -4151,7 +4215,6 @@ \__kernel_msg_new:nnnn { xparse } { too-many-arguments } { Too~many~arguments~in~argument~specification~'#2'~of~command~'#1'. } { - \c__msg_coding_error_text_tl The~argument~specification~provided~has~more~than~9~arguments.~ This~cannot~be~implemented. \\ \\ LaTeX~will~ignore~this~entire~definition. @@ -4159,7 +4222,6 @@ \__kernel_msg_new:nnnn { xparse } { unknown-argument-type } { Unknown~argument~type~'#2'~for~the~command~'#1'. } { - \c__msg_coding_error_text_tl The~letter~'#2'~does~not~specify~a~known~argument~type.~ LaTeX~will~ignore~this~entire~definition. } |