From 19d25b8009801aa98ea2f46b45c37c257f990491 Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Wed, 4 Mar 2020 03:02:32 +0000 Subject: CTAN sync 202003040302 --- macros/latex/contrib/l3packages/CHANGELOG.md | 9 +- macros/latex/contrib/l3packages/README.md | 2 +- macros/latex/contrib/l3packages/l3keys2e.dtx | 4 +- macros/latex/contrib/l3packages/l3keys2e.pdf | Bin 347493 -> 347184 bytes macros/latex/contrib/l3packages/xfp.dtx | 4 +- macros/latex/contrib/l3packages/xfp.pdf | Bin 309855 -> 309529 bytes macros/latex/contrib/l3packages/xfrac.dtx | 4 +- macros/latex/contrib/l3packages/xfrac.pdf | Bin 454275 -> 480943 bytes macros/latex/contrib/l3packages/xparse.dtx | 282 +++++++++++++++++++++----- macros/latex/contrib/l3packages/xparse.pdf | Bin 501940 -> 505523 bytes macros/latex/contrib/l3packages/xtemplate.dtx | 4 +- macros/latex/contrib/l3packages/xtemplate.pdf | Bin 416360 -> 416042 bytes 12 files changed, 248 insertions(+), 61 deletions(-) (limited to 'macros/latex/contrib/l3packages') diff --git a/macros/latex/contrib/l3packages/CHANGELOG.md b/macros/latex/contrib/l3packages/CHANGELOG.md index 2a56ece1a1..9b92b84018 100644 --- a/macros/latex/contrib/l3packages/CHANGELOG.md +++ b/macros/latex/contrib/l3packages/CHANGELOG.md @@ -7,6 +7,12 @@ this project uses date-based 'snapshot' version identifiers. ## [Unreleased] +## [2020-03-03] + +### Changed +- Delimited arguments (`DdRrEet`) now allow control sequence tokens + as delimiters (issues #367 and #368) + ## [2020-02-25] ### Changed @@ -81,7 +87,8 @@ this project uses date-based 'snapshot' version identifiers. - Switch to ISO date format - Improve cross-module use of internal functions -[Unreleased]: https://github.com/latex3/latex3/compare/2020-02-25...HEAD +[Unreleased]: https://github.com/latex3/latex3/compare/2020-03-03...HEAD +[2020-03-03]: https://github.com/latex3/latex3/compare/2020-02-25...2020-03-03 [2020-02-25]: https://github.com/latex3/latex3/compare/2020-02-14...2020-02-25 [2020-02-14]: https://github.com/latex3/latex3/compare/2020-02-08...2020-02-14 [2020-02-08]: https://github.com/latex3/latex3/compare/2020-02-03...2020-02-08 diff --git a/macros/latex/contrib/l3packages/README.md b/macros/latex/contrib/l3packages/README.md index b7712552ba..60647bde63 100644 --- a/macros/latex/contrib/l3packages/README.md +++ b/macros/latex/contrib/l3packages/README.md @@ -1,7 +1,7 @@ LaTeX3 High-Level Concepts ========================== -Release 2020-02-25 +Release 2020-03-03 Overview -------- diff --git a/macros/latex/contrib/l3packages/l3keys2e.dtx b/macros/latex/contrib/l3packages/l3keys2e.dtx index 2022b0ac00..3b648b7bdd 100644 --- a/macros/latex/contrib/l3packages/l3keys2e.dtx +++ b/macros/latex/contrib/l3packages/l3keys2e.dtx @@ -62,7 +62,7 @@ % }^^A % } % -% \date{Released 2020-02-25} +% \date{Released 2020-03-03} % % \maketitle % @@ -139,7 +139,7 @@ % \end{macrocode} % % \begin{macrocode} -\ProvidesExplPackage{l3keys2e}{2020-02-25}{} +\ProvidesExplPackage{l3keys2e}{2020-03-03}{} {LaTeX2e option processing using LaTeX3 keys} % \end{macrocode} % diff --git a/macros/latex/contrib/l3packages/l3keys2e.pdf b/macros/latex/contrib/l3packages/l3keys2e.pdf index ac7a187f8e..2a1c8fedbd 100644 Binary files a/macros/latex/contrib/l3packages/l3keys2e.pdf and b/macros/latex/contrib/l3packages/l3keys2e.pdf differ diff --git a/macros/latex/contrib/l3packages/xfp.dtx b/macros/latex/contrib/l3packages/xfp.dtx index 6bd7eb53b2..023e0e2ed5 100644 --- a/macros/latex/contrib/l3packages/xfp.dtx +++ b/macros/latex/contrib/l3packages/xfp.dtx @@ -64,7 +64,7 @@ % }^^A % } % -% \date{Released 2020-02-25} +% \date{Released 2020-03-03} % % \maketitle % @@ -167,7 +167,7 @@ % \end{macrocode} % % \begin{macrocode} -\ProvidesExplPackage{xfp}{2020-02-25}{} +\ProvidesExplPackage{xfp}{2020-03-03}{} {L3 Floating point unit} % \end{macrocode} % diff --git a/macros/latex/contrib/l3packages/xfp.pdf b/macros/latex/contrib/l3packages/xfp.pdf index 74dc6b73c3..e5896aa5e8 100644 Binary files a/macros/latex/contrib/l3packages/xfp.pdf and b/macros/latex/contrib/l3packages/xfp.pdf differ diff --git a/macros/latex/contrib/l3packages/xfrac.dtx b/macros/latex/contrib/l3packages/xfrac.dtx index 287c27a744..abbce7d8d1 100644 --- a/macros/latex/contrib/l3packages/xfrac.dtx +++ b/macros/latex/contrib/l3packages/xfrac.dtx @@ -65,7 +65,7 @@ % }^^A % } % -% \date{Released 2020-02-25} +% \date{Released 2020-03-03} % % \maketitle % @@ -535,7 +535,7 @@ % \end{macrocode} % % \begin{macrocode} -\ProvidesExplPackage{xfrac}{2020-02-25}{} +\ProvidesExplPackage{xfrac}{2020-03-03}{} {L3 Experimental split-level fractions} % \end{macrocode} % diff --git a/macros/latex/contrib/l3packages/xfrac.pdf b/macros/latex/contrib/l3packages/xfrac.pdf index 4031e6c18e..4c26aa4286 100644 Binary files a/macros/latex/contrib/l3packages/xfrac.pdf and b/macros/latex/contrib/l3packages/xfrac.pdf differ diff --git a/macros/latex/contrib/l3packages/xparse.dtx b/macros/latex/contrib/l3packages/xparse.dtx index fc0164a8cd..279b2e58c0 100644 --- a/macros/latex/contrib/l3packages/xparse.dtx +++ b/macros/latex/contrib/l3packages/xparse.dtx @@ -67,7 +67,7 @@ % }^^A % } % -% \date{Released 2020-02-25} +% \date{Released 2020-03-03} % % \maketitle % @@ -130,12 +130,12 @@ % Regardless of the input, the argument will be passed to the % internal code without the outer braces. This is the \pkg{xparse} % type specifier for a normal \TeX{} argument. -% \item[r] Given as \texttt{r}\meta{char1}\meta{char2}, this denotes a +% \item[r] Given as \texttt{r}\meta{token1}\meta{token2}, this denotes a % \enquote{required} delimited argument, where the delimiters are -% \meta{char1} and \meta{char2}. If the opening delimiter -% \meta{char1} is missing, the default marker |-NoValue-| will be +% \meta{token1} and \meta{token2}. If the opening delimiter +% \meta{token1} is missing, the default marker |-NoValue-| will be % inserted after a suitable error. -% \item[R] Given as \texttt{R}\meta{char1}\meta{char2}\marg{default}, +% \item[R] Given as \texttt{R}\meta{token1}\meta{token2}\marg{default}, % this is a \enquote{required} delimited argument as for~\texttt{r}, % but it has a user-definable recovery \meta{default} instead of % |-NoValue-|. @@ -158,30 +158,30 @@ % \item[o] A standard \LaTeX{} optional argument, surrounded with square % brackets, which will supply % the special |-NoValue-| marker if not given (as described later). -% \item[d] Given as \texttt{d}\meta{char1}\meta{char2}, an optional -% argument which is delimited by \meta{char1} and \meta{char2}. +% \item[d] Given as \texttt{d}\meta{token1}\meta{token2}, an optional +% argument which is delimited by \meta{token1} and \meta{token2}. % As with \texttt{o}, if no % value is given the special marker |-NoValue-| is returned. % \item[O] Given as \texttt{O}\marg{default}, is like \texttt{o}, but % returns \meta{default} if no value is given. -% \item[D] Given as \texttt{D}\meta{char1}\meta{char2}\marg{default}, +% \item[D] Given as \texttt{D}\meta{token1}\meta{token2}\marg{default}, % it is as for \texttt{d}, but returns \meta{default} if no value is given. % Internally, the \texttt{o}, \texttt{d} and \texttt{O} types are % short-cuts 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{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[e] Given as \texttt{e}\marg{chars}, a set of optional +% \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[e] Given as \texttt{e}\marg{tokens}, a set of optional % \emph{embellishments}, each of which requires a \emph{value}. % If an embellishment is not present, |-NoValue-| is returned. Each % embellishment gives one argument, ordered as for the list of -% \meta{chars} in the argument specification. All \meta{chars} +% \meta{tokens} in the argument specification. All \meta{tokens} % must be distinct. \emph{This is an experimental type}. % \item[E] As for \texttt{e} but returns one or more \meta{defaults} -% if values are not given: \texttt{E}\marg{chars}\marg{defaults}. See +% if values are not given: \texttt{E}\marg{tokens}\marg{defaults}. See % Section~\ref{sec:embellishment} for more details. % \end{itemize} % @@ -213,7 +213,9 @@ % \foo[[] % Error: missing closing "]" % \end{verbatim} % Also note that |{| and |}| cannot be used as delimiters as they are used -% by \TeX{} as grouping tokens. Arguments to be grabbed inside these tokens +% by \TeX{} as grouping tokens. Implicit begin- or end-group tokens (\emph{e.g.}, +% |\bgroup| and |\egroup|) are not allowed for delimited argument tipes. +% Arguments to be grabbed inside these tokens % must be created as either \texttt{m}- or \texttt{g}-type arguments. % % Within delimited arguments, non-balanced or otherwise awkward tokens may @@ -371,13 +373,13 @@ % \subsection{Default values for \enquote{embellishments}} % \label{sec:embellishment} % -% The \texttt{E}-type argument allows one default value per test character. +% The \texttt{E}-type argument allows one default value per test token. % This is achieved by giving a list of defaults for each entry in the % list, for example: % \begin{verbatim} % E{^_}{{UP}{DOWN}} % \end{verbatim} -% If the list of default values is \emph{shorter} than the list of test characters, +% If the list of default values is \emph{shorter} than the list of test tokens, % the special |-NoValue-| marker will be returned (as for the \texttt{e}-type % argument). Thus for example % \begin{verbatim} @@ -487,6 +489,66 @@ % is given: \texttt{G}\marg{default}. % \end{itemize} % +% \subsection{Details about argument delimiters} +% +% In normal (non-expandable) commands, the delimited types look for the +% initial delimiter by peeking ahead (using \pkg{expl3}'s |\peek_...| +% functions) looking for the delimiter token. The token has to have the +% same meaning and \enquote{shape} of the token defined as delimiter. +% There are three possible cases of delimiters: character tokens, control +% sequence tokens, and active character tokens. For all practical purposes +% of this description, active character tokens will behave exactly as +% control sequence tokens. +% +% \subsubsection{Character tokens} +% +% A character token is characterised by its character code, and its meaning +% is the category code~(|\catcode|). When a command is defined, the meaning +% of the character token is fixed into the definition of the command and +% cannot change. A command will correctly see an argument delimiter if +% the open delimiter has the same character and category codes as at the +% time of the definition. For example in: +% \begin{verbatim} +% \NewDocumentCommand { \foobar } { D<>{default} } {(#1)} +% \foobar \par +% \char_set_catcode_letter:N < +% \foobar +% \end{verbatim} +% the output would be: +% \begin{verbatim} +% (hello) +% (default) +% \end{verbatim} +% as the open-delimter |<| changed in meaning between the two calls to +% |\foobar|, so the second one doesn't see the |<| as a valid delimiter. +% Commands assume that if a valid open-delimiter was found, a matching +% close-delimiter will also be there. If it is not (either by being +% omitted or by changing in meaning), a low-level \TeX{} error is raised +% and the command call is aborted. +% +% \subsubsection{Control sequence tokens} +% +% A control sequence (or control character) token is characterised by is +% its name, and its meaning is its definition. +% A token cannot have two different meanings at the same time. +% When a control sequence is defined as delimiter in a command, +% it will be detected as delimiter whenever the control sequence name +% is found in the document regardless of its current definition. +% For example in: +% \begin{verbatim} +% \cs_set:Npn \x { abc } +% \NewDocumentCommand { \foobar } { D\x\y{default} } {(#1)} +% \foobar \x hello\y \par +% \cs_set:Npn \x { def } +% \foobar \x hello\y +% \end{verbatim} +% the output would be: +% \begin{verbatim} +% (hello) +% (hello) +% \end{verbatim} +% with both calls to the command seeing the delimiter |\x|. +% % \section{Declaring commands and environments} % % With the concept of an argument specifier defined, it is now @@ -916,7 +978,7 @@ % \end{macrocode} % % \begin{macrocode} -\ProvidesExplPackage{xparse}{2020-02-25}{} +\ProvidesExplPackage{xparse}{2020-03-03}{} {L3 Experimental document command parser} % \end{macrocode} % @@ -1906,8 +1968,8 @@ \cs_new_protected:Npn \@@_normalize_type_D:w #1#2#3 { \quark_if_recursion_tail_stop_do:nn {#3} { \@@_bad_arg_spec:wn } - \@@_single_char_check:n {#1} - \@@_single_char_check:n {#2} + \@@_single_token_check:n {#1} \@@_allowed_token_check:N #1 + \@@_single_token_check:n {#2} \@@_add_arg_spec:n { D #1 #2 {#3} } \tl_put_right:Nn \l_@@_last_delimiters_tl {#1} \bool_set_false:N \l_@@_grab_expandably_bool @@ -1917,7 +1979,8 @@ { \quark_if_recursion_tail_stop_do:nn {#2} { \@@_bad_arg_spec:wn } \tl_if_blank:nT {#1} { \@@_bad_arg_spec:wn } - \tl_map_function:nN {#1} \@@_single_char_check:n + \tl_map_function:nN {#1} \@@_single_token_check:n + \tl_map_function:nN {#1} \@@_allowed_token_check:N \@@_normalize_E_unique_check:w #1 \q_nil \q_stop \int_compare:nNnT { \tl_count:n {#2} } > { \tl_count:n {#1} } { \@@_bad_arg_spec:wn } @@ -1946,7 +2009,7 @@ \cs_new_protected:Npn \@@_normalize_type_t:w #1 { \quark_if_recursion_tail_stop_do:Nn #1 { \@@_bad_arg_spec:wn } - \@@_single_char_check:n {#1} + \@@_single_token_check:n {#1} \@@_allowed_token_check:N #1 \tl_put_right:Nx \l_@@_arg_spec_tl { \bool_if:NT \l_@@_obey_spaces_bool { ! } @@ -1994,8 +2057,8 @@ \cs_new_protected:Npn \@@_normalize_type_R:w #1#2#3 { \quark_if_recursion_tail_stop_do:nn {#3} { \@@_bad_arg_spec:wn } - \@@_single_char_check:n {#1} - \@@_single_char_check:n {#2} + \@@_single_token_check:n {#1} \@@_allowed_token_check:N #1 + \@@_single_token_check:n {#2} \@@_delimiter_check:nnn {#1} { R/r } { \tl_to_str:n {#1} } \bool_set_false:N \l_@@_grab_expandably_bool \@@_add_arg_spec_mandatory:n { R #1 #2 {#3} } @@ -2042,27 +2105,53 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}{\@@_single_char_check:n} -% Checks that what should be single characters really are single -% characters (possibly surrounded by spaces). +% \begin{macro}{\@@_single_token_check:n} +% Checks that the argument is a single (non-space) token (possibly +% surrounded by spaces), and aborts the definition otherwise. % \begin{macrocode} -\cs_new_protected:Npn \@@_single_char_check:n #1 +\cs_new_protected:Npn \@@_single_token_check:n #1 { - \tl_trim_spaces_apply:nN {#1} \tl_if_single_token:nTF + \tl_trim_spaces_apply:nN {#1} \tl_if_single_token:nF { - \group_begin: - \tex_escapechar:D = 92 \scan_stop: - \exp_args:Nx \tl_if_single_token:nF - { \exp_args:No \tl_to_str:n { \use:nn #1 { } } } - { - \__kernel_msg_warning:nnxx { xparse } { not-single-char } - { \@@_environment_or_command: } { \tl_to_str:n {#1} } - } - \group_end: + \__kernel_msg_error:nnxx { xparse } { not-single-token } + { \@@_environment_or_command: } { \tl_to_str:n {#1} } + \@@_bad_def:wn } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_allowed_token_check:N} +% Some tokens are now allowed as delimiters for some argument types, +% notably implicit begin/end-group tokens (|\bgroup|/|\egroup|). +% The major problem with these tokens is that for |\peek_...| functions, +% a literal~|{|$_1$. is virtually indistinguishable from a |\bgroup| or +% other token which was |\let| to a~|{|$_1$, and the same goes +% for~|}|$_2$. All other tokens can be easily distingushed from their +% implicit counterparts by grabbing them and looking at the string +% length (see \cs{@@_token_if_cs:NTF}), but for begin/end group tokens +% that is not possible without the risk of mistakenly grabbing the +% entire brace group (potentially leading to a~\texttt{!~Runaway argument} +% error) or trying to grab a |}|$_2$, leading to a~\texttt{!~Argument +% of~\dots~has an extra~|}|}. +% \begin{macrocode} +\cs_new_protected:Npn \@@_allowed_token_check:N #1 + { + \token_if_eq_meaning:NNTF #1 \c_group_begin_token + { \use:n } + { + \token_if_eq_meaning:NNTF #1 \c_group_end_token + { \use:n } + { \use_none:n } + } { - \__kernel_msg_error:nnxx { xparse } { not-single-char } + \__kernel_msg_error:nnxxx + { xparse } { forbidden-implicit-group-token } { \@@_environment_or_command: } { \tl_to_str:n {#1} } + { + \token_if_eq_meaning:NNTF #1 \c_group_begin_token + { begin } { end } + } \@@_bad_def:wn } } @@ -2853,12 +2942,12 @@ \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 + \@@_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 + \@@_peek_meaning_remove:NTF } % \end{macrocode} % \begin{macro}{\@@_grab_D_aux:NNnNN} @@ -2991,6 +3080,12 @@ % the grabber. (This assumes that the open and close delimiters are not the % same character with different category codes, but that really should not % happen in any sensible document-level syntax.) +% An exception is when |#1| is a control sequence token, in which case the +% character-token treatment is no good because if hit with \cs{token_to_str:N} +% it would add sputios tokens to the argument. In this case a different +% branch is taken. The token inserted is then the same \meta{csname} as |#1|, +% but with a space appended, so that the grabber don't see it as another +% of the same delimiter. % \begin{macrocode} \cs_new_protected_nopar:Npn \@@_grab_D_call:Nw #1 { @@ -3000,8 +3095,15 @@ \l_@@_fn_tl \char_generate:nn { `#1 } { 11 } } { - \exp_after:wN \l_@@_fn_tl - \token_to_str:N #1 + \@@_token_if_cs:NTF #1 + { + \exp_after:wN \l_@@_fn_tl + \cs:w \cs_to_str:N #1 ~ \cs_end: + } + { + \exp_after:wN \l_@@_fn_tl + \token_to_str:N #1 + } } } % \end{macrocode} @@ -3033,13 +3135,13 @@ { \@@_grab_E:nnNN {#1} {#2} \cs_set_protected_nopar:Npn - \peek_meaning_remove:NTF + \@@_peek_meaning_remove:NTF } \cs_new_protected:Npn \@@_grab_E_long_obey_spaces:w #1#2 \@@_run_code: { \@@_grab_E:nnNN {#1} {#2} \cs_set_protected:Npn - \peek_meaning_remove:NTF + \@@_peek_meaning_remove:NTF } % \end{macrocode} % A loop is needed here to allow a random ordering of keys. These are @@ -3294,7 +3396,7 @@ \cs_new_protected:Npn \@@_grab_t: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 } + { \@@_grab_t_aux:NNw \@@_peek_meaning_remove:NTF } \cs_new_protected:Npn \@@_grab_t_aux:NNw #1#2#3 \@@_run_code: { \tl_set:Nn \l_@@_signature_tl {#3} @@ -4282,6 +4384,28 @@ % \end{macrocode} % \end{macro} % +% \begin{macro}{\@@_token_if_cs:NTF} +% Based on the definition of \cs{@@_check_definable_aux:nN} above, but +% only checks for an actual control sequence (\emph{i.e.}, +% \cs[no-index]{\meta{anything}}). \cs{tex_escapechar:D} is +% temporarily changed to a known value and then it checks if +% |\string#1| contains more than one character: if it does, it's a +% control sequence. This test differs from \cs{token_if_cs:NTF} for +% example in \verb|\token_if_cs:NTF \c_group_begin_token {T}{F}|, +% where \cs{token_if_cs:NTF} returns false. +% \begin{macrocode} +\cs_new_protected:Npn \@@_token_if_cs:NTF #1 + { + \group_begin: + \int_set:Nn \tex_escapechar:D { 92 } + \exp_args:Nx \tl_if_empty:nTF + { \exp_args:No \str_tail:n { \token_to_str:N #1 } } + { \group_end: \use_ii:nn } + { \group_end: \use_i:nn } + } +% \end{macrocode} +% \end{macro} +% % \begin{macro}{\@@_tl_mapthread_function:NNN, \@@_tl_mapthread_function:nnN} % \begin{macro}{\@@_tl_mapthread_loop:w} % Analogue of \cs{seq_mapthread_function:NNN} for token lists. @@ -4351,9 +4475,9 @@ % \cs{peek_meaning_remove:NTF}. % \begin{macrocode} \cs_new_protected:Npn \@@_peek_nonspace:NTF - { \@@_peek_nonspace_aux:nNNTF { } \peek_meaning:NTF } + { \@@_peek_nonspace_aux:nNNTF { } \@@_peek_meaning:NTF } \cs_new_protected:Npn \@@_peek_nonspace_remove:NTF - { \@@_peek_nonspace_aux:nNNTF { } \peek_meaning_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 @@ -4363,6 +4487,55 @@ % \end{macrocode} % \end{macro} % +% \begin{macro}{\@@_peek_meaning:NTF, \@@_peek_meaning_remove:NTF} +% \begin{macro}{\@@_peek_cs_check_equal:NNN, \@@_peek_meaning_aux:NNTF, \@@_peek_true_remove:NNw} +% Peek ahead for a token with a given meaning. In case the search +% token is a control sequence, also check that the \meta{csname} is +% the same as the control sequence peeked at. This extra verification +% is necessary when the command is delimited by control sequence tokens +% (as opposed to character tokens), and we want the the exact same +% control sequence to match. +% \begin{macrocode} +\cs_new_protected:Npn \@@_peek_meaning:NTF + { \@@_peek_meaning_aux:NNTF \c_false_bool } +\cs_new_protected:Npn \@@_peek_meaning_remove:NTF + { \@@_peek_meaning_aux:NNTF \c_true_bool } +\cs_new_protected:Npn \@@_peek_meaning_aux:NNTF #1#2#3#4 + { + \tl_set:Nn \l_@@_tmpa_tl {#3} + \tl_set:Nn \l_@@_tmpb_tl {#4} + \peek_meaning:NTF #2 + { + \token_if_eq_meaning:NNTF #2 \c_group_begin_token + { \@@_peek_true_remove:Nw #1 } + { + \@@_token_if_cs:NTF #2 + { \@@_peek_cs_check_equal:NNN #1 #2 } + { \@@_peek_true_remove:Nw #1 } + } + } + { \l_@@_tmpb_tl } + } +\cs_new_protected:Npn \@@_peek_cs_check_equal:NNN #1#2#3 + { + \str_if_eq:nnTF {#2} {#3} + { \@@_peek_true_remove:Nw #1 } + { \l_@@_tmpb_tl } + #3 + } +\cs_new_protected:Npn \@@_peek_true_remove:Nw #1 + { + \bool_if:NTF #1 + { + \tex_afterassignment:D \l_@@_tmpa_tl + \cs_set_eq:NN \@@_tmp:w + } + { \l_@@_tmpa_tl } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% % \subsection{Messages} % % \begin{macro}{\@@_environment_or_command:} @@ -4493,14 +4666,21 @@ token.~Perhaps~a~backslash~is~missing? \c_@@_ignore_def_tl } -\__kernel_msg_new:nnnn { xparse } { not-single-char } +\__kernel_msg_new:nnnn { xparse } { not-single-token } { Argument~delimiter~'#2'~for~the~#1~should~be~ - a~single~character. + a~single~non-space~token. } { The~argument~specification~provided~was~not~valid:~in~a~place~ - where~a~single~character~is~required,~LaTeX~found~'#2'. + where~a~single~token~is~required,~LaTeX~found~'#2'. + \c_@@_ignore_def_tl + } +\__kernel_msg_new:nnnn { xparse } { forbidden-implicit-group-token } + { Argument~delimiter~'#2'~for~the~#1~is~not~allowed. } + { + The~argument~specification~provided~was~not~valid:~the~implicit~ + #3-group~token~'#2'~is~not~allowed~as~an~argument~delimiter. \c_@@_ignore_def_tl } \__kernel_msg_new:nnnn { xparse } { processor-in-expandable } diff --git a/macros/latex/contrib/l3packages/xparse.pdf b/macros/latex/contrib/l3packages/xparse.pdf index b9bf02a381..98e62db0e1 100644 Binary files a/macros/latex/contrib/l3packages/xparse.pdf and b/macros/latex/contrib/l3packages/xparse.pdf differ diff --git a/macros/latex/contrib/l3packages/xtemplate.dtx b/macros/latex/contrib/l3packages/xtemplate.dtx index 9a10fbca81..d0ced34962 100644 --- a/macros/latex/contrib/l3packages/xtemplate.dtx +++ b/macros/latex/contrib/l3packages/xtemplate.dtx @@ -63,7 +63,7 @@ % }^^A % } % -% \date{Released 2020-02-25} +% \date{Released 2020-03-03} % % \maketitle % @@ -682,7 +682,7 @@ % \end{macrocode} % % \begin{macrocode} -\ProvidesExplPackage{xtemplate}{2020-02-25}{} +\ProvidesExplPackage{xtemplate}{2020-03-03}{} {L3 Experimental prototype document functions} % \end{macrocode} % diff --git a/macros/latex/contrib/l3packages/xtemplate.pdf b/macros/latex/contrib/l3packages/xtemplate.pdf index 40f55ded1a..20ae5c9d3f 100644 Binary files a/macros/latex/contrib/l3packages/xtemplate.pdf and b/macros/latex/contrib/l3packages/xtemplate.pdf differ -- cgit v1.2.3