diff options
Diffstat (limited to 'Master/texmf-dist/source/latex/l3packages/xparse/xparse.dtx')
-rw-r--r-- | Master/texmf-dist/source/latex/l3packages/xparse/xparse.dtx | 373 |
1 files changed, 216 insertions, 157 deletions
diff --git a/Master/texmf-dist/source/latex/l3packages/xparse/xparse.dtx b/Master/texmf-dist/source/latex/l3packages/xparse/xparse.dtx index c9685d264d5..1e24d659fe7 100644 --- a/Master/texmf-dist/source/latex/l3packages/xparse/xparse.dtx +++ b/Master/texmf-dist/source/latex/l3packages/xparse/xparse.dtx @@ -67,7 +67,7 @@ % }^^A % } % -% \date{Released 2018-08-23} +% \date{Released 2018-09-24} % % \maketitle % @@ -818,7 +818,7 @@ % \end{macrocode} % % \begin{macrocode} -\ProvidesExplPackage{xparse}{2018-08-23}{} +\ProvidesExplPackage{xparse}{2018-09-24}{} {L3 Experimental document command parser} % \end{macrocode} % @@ -953,6 +953,13 @@ % \end{macrocode} % \end{variable} % +% \begin{variable}{\l_@@_obey_spaces_bool} +% For trailing optionals. +% \begin{macrocode} +\bool_new:N \l_@@_obey_spaces_bool +% \end{macrocode} +% \end{variable} +% % \begin{variable}{\l_@@_last_delimiters_tl} % Holds the delimiters (first tokens) of all optional arguments since % the previous mandatory argument, to warn about cases where it would @@ -971,13 +978,6 @@ % \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 @@ -1028,15 +1028,20 @@ % \end{macrocode} % \end{variable} % -% \begin{variable}{\l_@@_some_long_bool, \l_@@_some_short_bool} -% Both of these flags are set while normalizing the argument -% specification. To grab arguments expandably, all short arguments -% must appear before long arguments, so as soon as the first long -% argument is seen (other than \texttt{t}-type, whose long status is -% ignored) the \texttt{some_long} flag is set. The -% \texttt{some_short} flag is used for expandable commands, to know -% whether to define a short auxiliary too. -% \begin{macrocode} +% \begin{variable} +% {\l_@@_some_obey_spaces_bool, \l_@@_some_long_bool, \l_@@_some_short_bool} +% These flags are set while normalizing the argument specification. +% The \texttt{obey_spaces} one is used to detect when |!| is used on +% an argument that is not a trailing optional argument. +% The other two are used to check whether all short arguments appear +% before long arguments: this is needed to grab arguments expandably. +% As soon as the first long argument is seen (other than +% \texttt{t}-type, whose long status is ignored) the +% \texttt{some_long} flag is set. The \texttt{some_short} flag is +% used for expandable commands, to know whether to define a short +% auxiliary too. +% \begin{macrocode} +\bool_new:N \l_@@_some_obey_spaces_bool \bool_new:N \l_@@_some_long_bool \bool_new:N \l_@@_some_short_bool % \end{macrocode} @@ -1521,50 +1526,49 @@ % specification is valid before the main parsing run. If it is not % valid the entire set up is abandoned to avoid any strange internal % errors. A function is provided for each argument type that will grab -% any extra arguments and call the loop function. -% -% The first thing that is done in the loop is to check that the various -% argument types have the correct number of data items associated with -% them. The opportunity is also taken to make sure that where a single -% character is required, one has actually been supplied. -% -% The second is that processors and the marker~|+| for long arguments -% must be followed by arguments. -% -% The third is to check for forbidden types for expandable commands, -% namely \texttt{G}/\texttt{v} always, and \texttt{l}/\texttt{u} after -% optional arguments (\pkg{xparse} may have inserted braces due to a -% failed search for an optional argument). -% -% The fourth is that an optional argument should not be followed by a -% mandatory argument with the same delimiter, as otherwise the optional -% argument could never be omitted. -% -% The fifth is to keep track in \cs{l_@@_some_long_bool} and -% \cs{l_@@_some_short_bool} of whether the command has some long/short -% arguments. -% -% The sixth is to keep track in \cs{l_@@_grab_expandably_bool} of -% whether all arguments are \texttt{m}/\texttt{l}/\texttt{u} type and -% short arguments appear before long ones, in which case they can be -% grabbed expandably just as safely as they could be grabbed expandably. -% Regardless of that, arguments of expandable commands will be grabbed -% expandably and arguments of environments will not (because the list of -% arguments built by non-expandable grabbing is used to pass them to the -% end-environment code). -% -% The last is to count mandatory arguments, used later to detect which -% optional arguments are trailing. +% any extra data items and call the loop function after performing the +% following checks and tasks. +% \begin{itemize} +% \item Check that each argument has the correct number of data items +% associated with it, and that where a single character is required, +% one has actually been supplied. +% \item Check that processors and the markers~|+| and~|!| are followed +% by an argument for which they make sense, and are not redundant. +% \item Check the absence of forbidden types for expandable commands, +% namely \texttt{G}/\texttt{v} always, and \texttt{l}/\texttt{u} +% after optional arguments (\pkg{xparse} may have inserted braces +% due to a failed search for an optional argument). +% \item Check that no optional argument is followed by a mandatory +% argument with the same delimiter, as otherwise the optional +% argument could never be omitted. +% \item Keep track in \cs{l_@@_some_long_bool} and +% \cs{l_@@_some_short_bool} of whether the command has some +% long/short arguments. +% \item Keep track in \cs{l_@@_grab_expandably_bool} of whether all +% arguments are \texttt{m}/\texttt{l}/\texttt{u} type and short +% arguments appear before long ones, in which case they can be +% grabbed expandably just as safely as they could be grabbed +% nonexpandably. Regardless of that, arguments of expandable +% commands will be grabbed expandably and arguments of environments +% will not (because the list of arguments built by non-expandable +% grabbing is used to pass them to the end-environment code). +% \item Count mandatory arguments, used later to detect which optional +% arguments are trailing. +% \end{itemize} +% Further checks happen at the end of the loop: +% \begin{itemize} +% \item that there are at most $9$ arguments; +% \item that an expandable command does not end with an optional +% argument (this case is detected by using the fact that +% \cs{l_@@_last_delimiters_tl} is cleared by every mandatory argument +% and filled by every optional argument). +% \end{itemize} % % \begin{macro}{\@@_normalize_arg_spec:n} % \begin{macro}{\@@_normalize_arg_spec_loop:n} % Loop through the argument specification, calling an auxiliary % specific to each argument type. If any argument is unknown stop the -% definition. After the loop, if there are more than -% $9$ arguments, stop. Additionally, expandable commands may not end -% with an optional argument; this case is detected by using the fact -% that \cs{l_@@_last_delimiters_tl} is cleared by every mandatory -% argument and filled by every optional argument. +% definition. % \begin{macrocode} \cs_new_protected:Npn \@@_normalize_arg_spec:n #1 { @@ -1573,10 +1577,11 @@ \tl_clear:N \l_@@_last_delimiters_tl \tl_clear:N \l_@@_arg_spec_tl \bool_set_true:N \l_@@_grab_expandably_bool + \bool_set_false:N \l_@@_obey_spaces_bool \bool_set_false:N \l_@@_long_bool + \bool_set_false:N \l_@@_some_obey_spaces_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 @@ -1691,7 +1696,12 @@ \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 { + } + \bool_if:NT \l_@@_long_bool + { + \__kernel_msg_error:nnxx { xparse } { two-markers } + { \iow_char:N \\ \l_@@_function_tl } { + } + \@@_bad_def:wn + } \bool_set_true:N \l_@@_long_bool \int_decr:N \l_@@_current_arg_int \@@_normalize_arg_spec_loop:n {#1} @@ -1699,7 +1709,14 @@ \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 { ! } + \bool_if:NT \l_@@_obey_spaces_bool + { + \__kernel_msg_error:nnxx { xparse } { two-markers } + { \iow_char:N \\ \l_@@_function_tl } { ! } + \@@_bad_def:wn + } + \bool_set_true:N \l_@@_obey_spaces_bool + \bool_set_true:N \l_@@_some_obey_spaces_bool \int_decr:N \l_@@_current_arg_int \@@_normalize_arg_spec_loop:n {#1} } @@ -1770,9 +1787,14 @@ { \quark_if_recursion_tail_stop_do:Nn #1 { \@@_bad_arg_spec:wn } \@@_single_char_check:n {#1} - \tl_put_right:Nn \l_@@_arg_spec_tl { t #1 } + \tl_put_right:Nx \l_@@_arg_spec_tl + { + \bool_if:NT \l_@@_obey_spaces_bool { ! } + t \exp_not:n {#1} + } \tl_put_right:Nn \l_@@_last_delimiters_tl {#1} \bool_set_false:N \l_@@_grab_expandably_bool + \bool_set_false:N \l_@@_obey_spaces_bool \bool_set_false:N \l_@@_long_bool \@@_normalize_arg_spec_loop:n } @@ -1800,17 +1822,13 @@ \cs_new_protected:Npn \@@_normalize_type_l:w { \@@_normalize_check_lu:N l - \@@_add_arg_spec:n { l } - \int_incr:N \l_@@_mandatory_args_int - \tl_clear:N \l_@@_last_delimiters_tl + \@@_add_arg_spec_mandatory:n { l } \@@_normalize_arg_spec_loop:n } \cs_new_protected:Npn \@@_normalize_type_m:w { \@@_delimiter_check:nnn { } { m } { \iow_char:N \{ } - \@@_add_arg_spec:n { m } - \int_incr:N \l_@@_mandatory_args_int - \tl_clear:N \l_@@_last_delimiters_tl + \@@_add_arg_spec_mandatory:n { m } \@@_normalize_arg_spec_loop:n } \cs_new_protected:Npn \@@_normalize_type_R:w #1#2#3 @@ -1819,27 +1837,21 @@ \@@_single_char_check:n {#1} \@@_single_char_check:n {#2} \@@_delimiter_check:nnn {#1} { R/r } { \tl_to_str:n {#1} } - \@@_add_arg_spec:n { R #1 #2 {#3} } - \int_incr:N \l_@@_mandatory_args_int - \tl_clear:N \l_@@_last_delimiters_tl \bool_set_false:N \l_@@_grab_expandably_bool + \@@_add_arg_spec_mandatory:n { R #1 #2 {#3} } \@@_normalize_arg_spec_loop:n } \cs_new_protected:Npn \@@_normalize_type_u:w #1 { \quark_if_recursion_tail_stop_do:nn {#1} { \@@_bad_arg_spec:wn } \@@_normalize_check_lu:N u - \@@_add_arg_spec:n { u {#1} } - \int_incr:N \l_@@_mandatory_args_int - \tl_clear:N \l_@@_last_delimiters_tl + \@@_add_arg_spec_mandatory:n { u {#1} } \@@_normalize_arg_spec_loop:n } \cs_new_protected:Npn \@@_normalize_type_v:w { \@@_normalize_check_gv:N v - \@@_add_arg_spec:n { v } - \int_incr:N \l_@@_mandatory_args_int - \tl_clear:N \l_@@_last_delimiters_tl + \@@_add_arg_spec_mandatory:n { v } \@@_normalize_arg_spec_loop:n } % \end{macrocode} @@ -1936,13 +1948,16 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}{\@@_add_arg_spec:n} +% \begin{macro}{\@@_add_arg_spec:n, \@@_add_arg_spec_mandatory:n} % When adding an argument to the argument specification, set the % \texttt{some_long} or \texttt{some_short} booleans as appropriate -% and clear the boolean keeping track of whether the argument is long. +% and clear the booleans keeping track of |+| and |!| markers. % Before that, test for a short argument following some long % arguments: this is forbidden for expandable commands and prevents % grabbing arguments expandably. +% +% For mandatory arguments do some more work, in particular complain if +% they were preceeded by~|!|. % \begin{macrocode} \cs_new_protected:Npn \@@_add_arg_spec:n #1 { @@ -1961,8 +1976,26 @@ \bool_if:NTF \l_@@_long_bool { \bool_set_true:N \l_@@_some_long_bool } { \bool_set_true:N \l_@@_some_short_bool } + \tl_put_right:Nx \l_@@_arg_spec_tl + { + \bool_if:NT \l_@@_long_bool { + } + \bool_if:NT \l_@@_obey_spaces_bool { ! } + \exp_not:n {#1} + } \bool_set_false:N \l_@@_long_bool - \tl_put_right:Nn \l_@@_arg_spec_tl {#1} + \bool_set_false:N \l_@@_obey_spaces_bool + } +\cs_new_protected:Npn \@@_add_arg_spec_mandatory:n #1 + { + \bool_if:NT \l_@@_some_obey_spaces_bool + { + \__kernel_msg_error:nnxx { xparse } { non-trailing-obey-spaces } + { \iow_char:N \\ \l_@@_function_tl } { \tl_to_str:n {#1} } + \@@_bad_def:wn + } + \int_incr:N \l_@@_mandatory_args_int + \tl_clear:N \l_@@_last_delimiters_tl + \@@_add_arg_spec:n {#1} } % \end{macrocode} % \end{macro} @@ -1972,8 +2005,8 @@ % \begin{macro}{\@@_prepare_signature:n} % \begin{macro}{\@@_prepare_signature:N} % \begin{macro}{\@@_prepare_signature_bypass:N} -% Actually creating the signature uses the same loop approach as counting -% up mandatory arguments. There are first a number of variables which need +% Actually creating the signature uses the same loop approach as +% normalizing the signature. There are first a number of variables which need % to be set to track what is going on. Many of these variables are unused % when defining expandable commands. % \begin{macrocode} @@ -1981,7 +2014,7 @@ { \int_zero:N \l_@@_current_arg_int \bool_set_false:N \l_@@_long_bool - \bool_set_false:N \l_@@_ignore_spaces_bool + \bool_set_false:N \l_@@_obey_spaces_bool \int_zero:N \l_@@_m_args_int \bool_set_false:N \l_@@_defaults_bool \tl_clear:N \l_@@_defaults_tl @@ -2056,7 +2089,7 @@ \cs_new_protected:cpn { @@_add_type_!:w } { \@@_flush_m_args: - \bool_set_true:N \l_@@_ignore_spaces_bool + \bool_set_true:N \l_@@_obey_spaces_bool \bool_set_true:N \l_@@_prefixed_bool \@@_prepare_signature_bypass:N } @@ -2239,24 +2272,16 @@ % % \begin{macro}{\@@_add_grabber_mandatory:N} % \begin{macro}{\@@_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 when -% searching for the argument. +% To keep the various checks needed in one place, adding the grabber +% to the signature is done here. The only questions are whether the +% grabber should be long or not, and whether to obey spaces. The +% \cs{l_@@_obey_spaces_bool} boolean can only be \texttt{true} for +% trailing optional arguments. In that case spaces will not be +% ignored when looking for that optional argument. % \begin{macrocode} \cs_new_protected:Npn \@@_add_grabber_mandatory:N #1 { - \tl_put_right:Nx \l_@@_signature_tl - { - \exp_not:c - { @@_grab_ #1 \bool_if:NT \l_@@_long_bool { _long } :w } - } - \bool_set_false:N \l_@@_long_bool - \tl_put_right:Nx \l_@@_process_all_tl - { { \exp_not:o \l_@@_process_one_tl } } - \tl_clear:N \l_@@_process_one_tl + \@@_add_grabber_optional:N #1 \int_decr:N \l_@@_mandatory_args_int } \cs_new_protected:Npn \@@_add_grabber_optional:N #1 @@ -2267,15 +2292,12 @@ { @@_grab_ #1 \bool_if:NT \l_@@_long_bool { _long } - \bool_lazy_and:nnT - { \l_@@_ignore_spaces_bool } - { \int_compare_p:nNn \l_@@_mandatory_args_int = 0 } - { _ignore_spaces } + \bool_if:NT \l_@@_obey_spaces_bool { _obey_spaces } :w } } \bool_set_false:N \l_@@_long_bool - \bool_set_false:N \l_@@_ignore_spaces_bool + \bool_set_false:N \l_@@_obey_spaces_bool \tl_put_right:Nx \l_@@_process_all_tl { { \exp_not:o \l_@@_process_one_tl } } \tl_clear:N \l_@@_process_one_tl @@ -2573,28 +2595,34 @@ % % \begin{macro}{\@@_grab_D:w} % \begin{macro}{\@@_grab_D_long:w} -% \begin{macro}{\@@_grab_D_ignore_spaces:w} -% \begin{macro}{\@@_grab_D_long_ignore_spaces:w} +% \begin{macro}{\@@_grab_D_obey_spaces:w} +% \begin{macro}{\@@_grab_D_long_obey_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. % \begin{macrocode} \cs_new_protected:Npn \@@_grab_D:w #1#2#3 \@@_run_code: { - \@@_grab_D_aux:NNnNn #1 #2 {#3} \cs_set_protected_nopar:Npn - { _ignore_spaces } + \@@_grab_D_aux:NNnNN #1 #2 {#3} \cs_set_protected_nopar:Npn + \@@_peek_nonspace_remove:NTF } \cs_new_protected:Npn \@@_grab_D_long:w #1#2#3 \@@_run_code: { - \@@_grab_D_aux:NNnNn #1 #2 {#3} \cs_set_protected:Npn - { _ignore_spaces } + \@@_grab_D_aux:NNnNN #1 #2 {#3} \cs_set_protected:Npn + \@@_peek_nonspace_remove:NTF + } +\cs_new_protected:Npn \@@_grab_D_obey_spaces:w #1#2#3 \@@_run_code: + { + \@@_grab_D_aux:NNnNN #1 #2 {#3} \cs_set_protected_nopar:Npn + \peek_meaning_remove:NTF + } +\cs_new_protected:Npn \@@_grab_D_long_obey_spaces:w #1#2#3 \@@_run_code: + { + \@@_grab_D_aux:NNnNN #1 #2 {#3} \cs_set_protected:Npn + \peek_meaning_remove:NTF } -\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_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} +% \begin{macro}{\@@_grab_D_aux:NNnNN} % \begin{macro}{\@@_grab_D_aux:NNnN} % This is a bit complicated. The idea is that, in order to check for % nested optional argument tokens (\texttt{[[...]]} and so on) the @@ -2604,10 +2632,10 @@ % prevents loss of braces, and there is then a test to see if there are % nested delimiters to handle. % \begin{macrocode} -\cs_new_protected:Npn \@@_grab_D_aux:NNnNn #1#2#3#4#5 +\cs_new_protected:Npn \@@_grab_D_aux:NNnNN #1#2#3#4#5 { \@@_grab_D_aux:NNnN #1#2 {#3} #4 - \use:c { peek_meaning_remove #5 :NTF } #1 + #5 #1 { \@@_grab_D_call:Nw #1 } { \@@_add_arg:o \c_novalue_tl } } @@ -2743,36 +2771,36 @@ % \begin{macro} % { % \@@_grab_E:w, \@@_grab_E_long:w, -% \@@_grab_E_ignore_spaces:w, \@@_grab_E_long_ignore_spaces:w +% \@@_grab_E_obey_spaces:w, \@@_grab_E_long_obey_spaces:w % } -% \begin{macro}{\@@_grab_E:nnNn} -% \begin{macro}{\@@_grab_E_loop:nnN} +% \begin{macro}{\@@_grab_E:nnNN} +% \begin{macro}{\@@_grab_E_loop:NnN} % \begin{macro}{\@@_grab_E_finalise:} % Everything here needs to point to a loop. % \begin{macrocode} \cs_new_protected:Npn \@@_grab_E:w #1#2 \@@_run_code: { - \@@_grab_E:nnNn {#1} {#2} + \@@_grab_E:nnNN {#1} {#2} \cs_set_protected_nopar:Npn - { _ignore_spaces } + \@@_peek_nonspace_remove:NTF } \cs_new_protected:Npn \@@_grab_E_long:w #1#2 \@@_run_code: { - \@@_grab_E:nnNn {#1} {#2} + \@@_grab_E:nnNN {#1} {#2} \cs_set_protected:Npn - { _ignore_spaces } + \@@_peek_nonspace_remove:NTF } -\cs_new_protected:Npn \@@_grab_E_ignore_spaces:w #1#2 \@@_run_code: +\cs_new_protected:Npn \@@_grab_E_obey_spaces:w #1#2 \@@_run_code: { - \@@_grab_E:nnNn {#1} {#2} + \@@_grab_E:nnNN {#1} {#2} \cs_set_protected_nopar:Npn - { } + \peek_meaning_remove:NTF } -\cs_new_protected:Npn \@@_grab_E_long_ignore_spaces:w #1#2 \@@_run_code: +\cs_new_protected:Npn \@@_grab_E_long_obey_spaces:w #1#2 \@@_run_code: { - \@@_grab_E:nnNn {#1} {#2} + \@@_grab_E:nnNN {#1} {#2} \cs_set_protected:Npn - { } + \peek_meaning_remove:NTF } % \end{macrocode} % A loop is needed here to allow a random ordering of keys. These are @@ -2780,12 +2808,12 @@ % they can appear later. The grabbed values are held in a property list % which is then turned into an ordered list to be passed back to the user. % \begin{macrocode} -\cs_new_protected:Npn \@@_grab_E:nnNn #1#2#3#4 +\cs_new_protected:Npn \@@_grab_E:nnNN #1#2#3#4 { \exp_after:wN #3 \l_@@_fn_tl ##1##2##3 { \prop_put:Nnn \l_@@_tmp_prop {##1} {##3} - \@@_grab_E_loop:nnN {#4} { } ##2 \q_recursion_stop + \@@_grab_E_loop:NnN #4 { } ##2 \q_recursion_stop } \prop_clear:N \l_@@_tmp_prop \tl_set:Nn \l_@@_signature_tl {#2} @@ -2800,16 +2828,16 @@ } \l_@@_signature_tl \@@_run_code: } - \@@_grab_E_loop:nnN {#4} { } #1 \q_recursion_tail \q_recursion_stop + \@@_grab_E_loop:NnN #4 { } #1 \q_recursion_tail \q_recursion_stop } -\cs_new_protected:Npn \@@_grab_E_loop:nnN #1#2#3#4 \q_recursion_stop +\cs_new_protected:Npn \@@_grab_E_loop:NnN #1#2#3#4 \q_recursion_stop { \cs_if_eq:NNTF #3 \q_recursion_tail { \@@_grab_E_finalise: } { - \use:c { peek_meaning_remove #1 :NTF } #3 + #1 #3 { \l_@@_fn_tl #3 {#2#4} } - { \@@_grab_E_loop:nnN {#1} {#2#3} #4 \q_recursion_stop } + { \@@_grab_E_loop:NnN #1 {#2#3} #4 \q_recursion_stop } } } \cs_new_protected:Npn \@@_grab_E_finalise: { } @@ -2821,31 +2849,38 @@ % % \begin{macro}{\@@_grab_G:w} % \begin{macro}{\@@_grab_G_long:w} -% \begin{macro}{\@@_grab_G_ignore_spaces:w} -% \begin{macro}{\@@_grab_G_long_ignore_spaces:w} -% \begin{macro}{\@@_grab_G_aux:nNn} +% \begin{macro}{\@@_grab_G_obey_spaces:w} +% \begin{macro}{\@@_grab_G_long_obey_spaces:w} +% \begin{macro}{\@@_grab_G_aux:nNN} % Optional groups are checked by meaning, so that the same code will % work with, for example, \ConTeXt{}-like input. % \begin{macrocode} \cs_new_protected:Npn \@@_grab_G:w #1 \@@_run_code: { - \@@_grab_G_aux:nNn {#1} \cs_set_protected_nopar:Npn - { _ignore_spaces } + \@@_grab_G_aux:nNN {#1} \cs_set_protected_nopar:Npn + \@@_peek_nonspace:NTF } \cs_new_protected:Npn \@@_grab_G_long:w #1 \@@_run_code: { - \@@_grab_G_aux:nNn {#1} \cs_set_protected:Npn { _ignore_spaces } + \@@_grab_G_aux:nNN {#1} \cs_set_protected:Npn + \@@_peek_nonspace:NTF + } +\cs_new_protected:Npn \@@_grab_G_obey_spaces:w #1 \@@_run_code: + { + \@@_grab_G_aux:nNN {#1} \cs_set_protected_nopar:Npn + \peek_meaning:NTF } -\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_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 +\cs_new_protected:Npn \@@_grab_G_long_obey_spaces:w #1 \@@_run_code: + { + \@@_grab_G_aux:nNN {#1} \cs_set_protected:Npn + \peek_meaning:NTF + } +\cs_new_protected:Npn \@@_grab_G_aux:nNN #1#2#3 { \tl_set:Nn \l_@@_signature_tl {#1} \exp_after:wN #2 \l_@@_fn_tl ##1 { \@@_add_arg:n {##1} } - \use:c { peek_meaning #3 :NTF } \c_group_begin_token + #3 \c_group_begin_token { \l_@@_fn_tl } { \@@_add_arg:o \c_novalue_tl } } @@ -2998,7 +3033,7 @@ \cs_new_protected:Npn \@@_grab_R_aux:NNnN #1#2#3#4 { \@@_grab_D_aux:NNnN #1 #2 {#3} #4 - \peek_meaning_remove_ignore_spaces:NTF #1 + \@@_peek_nonspace_remove:NTF #1 { \@@_grab_D_call:Nw #1 } { \__kernel_msg_error:nnxx { xparse } { missing-required } @@ -3012,19 +3047,15 @@ % \end{macro} % % \begin{macro}{\@@_grab_t:w} -% \begin{macro}{\@@_grab_t_long:w} -% \begin{macro}{\@@_grab_t_ignore_spaces:w} -% \begin{macro}{\@@_grab_t_long_ignore_spaces:w} +% \begin{macro}{\@@_grab_t_obey_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. % \begin{macrocode} \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_ignore_spaces:w + { \@@_grab_t_aux:NNw \@@_peek_nonspace_remove:NTF } +\cs_new_protected:Npn \@@_grab_t_obey_spaces:w { \@@_grab_t_aux:NNw \peek_meaning_remove:NTF } -\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} @@ -3040,8 +3071,6 @@ % \end{macro} % \end{macro} % \end{macro} -% \end{macro} -% \end{macro} % % \begin{macro}{\@@_grab_u:w} % \begin{macro}{\@@_grab_u_long:w} @@ -4066,6 +4095,23 @@ % \end{macro} % \end{macro} % +% \begin{macro}{\@@_peek_nonspace:NTF, \@@_peek_nonspace_remove:NTF, \@@_peek_nonspace_aux:nNNTF} +% Collect spaces in a loop, and put the collected spaces back in the +% false branch of a call to \cs{peek_meaning:NTF} or +% \cs{peek_meaning_remove:NTF}. +% \begin{macrocode} +\cs_new_protected:Npn \@@_peek_nonspace:NTF + { \@@_peek_nonspace_aux:nNNTF { } \peek_meaning:NTF } +\cs_new_protected:Npn \@@_peek_nonspace_remove:NTF + { \@@_peek_nonspace_aux:nNNTF { } \peek_meaning_remove:NTF } +\cs_new_protected:Npn \@@_peek_nonspace_aux:nNNTF #1#2#3#4#5 + { + \peek_meaning_remove:NTF \c_space_token + { \@@_peek_nonspace_aux:nNNTF { #1 ~ } #2 #3 {#4} {#5} } + { #2 #3 { #4 } { #5 #1 } } + } +% \end{macro} +% % \subsection{Messages} % % Some messages intended as errors. @@ -4158,6 +4204,13 @@ The~current~command~'#1'~expects~an~argument~starting~with~'#2'.~ LaTeX~did~not~find~it,~and~will~insert~a~default~value~to~be~processed. } +\__kernel_msg_new:nnnn { xparse } { non-trailing-obey-spaces } + { Prefix~'!'~used~before~mandatory~argument~'#2'~of~command~'#1'. } + { + The~prefix~'!'~can~only~apply~to~trailing~optional~arguments. + \\ \\ + LaTeX~will~ignore~this~entire~definition. + } \__kernel_msg_new:nnnn { xparse } { non-xparse-command } { Command~'#1'~not~defined~using~xparse. } { @@ -4219,6 +4272,12 @@ This~cannot~be~implemented. \\ \\ LaTeX~will~ignore~this~entire~definition. } +\__kernel_msg_new:nnnn { xparse } { two-markers } + { Two~'#2'~apply~to~the~same~argument~in~argument~specification~of~command~'#1'. } + { + The~argument~specification~provided~has~two~markers~'#2'~applying~ + to~the~same~argument;~these~are~redundant. + } \__kernel_msg_new:nnnn { xparse } { unknown-argument-type } { Unknown~argument~type~'#2'~for~the~command~'#1'. } { |