From c50b7eaa45c94a09e1087c6c31f144b497057444 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Mon, 21 Dec 2015 23:28:17 +0000 Subject: l3 (21dec15) git-svn-id: svn://tug.org/texlive/trunk@39162 c570f23f-e606-0410-a88d-b1316a301751 --- .../source/latex/l3experimental/l3sort/l3sort.dtx | 6 +- .../source/latex/l3experimental/l3str/l3flag.dtx | 6 +- .../source/latex/l3experimental/l3str/l3regex.dtx | 12 +- .../latex/l3experimental/l3str/l3tl-analysis.dtx | 6 +- .../latex/l3experimental/l3str/l3tl-build.dtx | 6 +- .../latex/l3experimental/xgalley/l3galley.dtx | 6 +- .../source/latex/l3packages/l3keys2e/l3keys2e.dtx | 8 +- .../source/latex/l3packages/xfrac/xfrac.dtx | 8 +- .../source/latex/l3packages/xparse/xparse.dtx | 521 +++++++++++++++------ .../latex/l3packages/xtemplate/xtemplate.dtx | 8 +- 10 files changed, 423 insertions(+), 164 deletions(-) (limited to 'Master/texmf-dist/source/latex') diff --git a/Master/texmf-dist/source/latex/l3experimental/l3sort/l3sort.dtx b/Master/texmf-dist/source/latex/l3experimental/l3sort/l3sort.dtx index bdadbc90d88..f51cd7dfea6 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3sort/l3sort.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3sort/l3sort.dtx @@ -37,8 +37,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}[2015/11/04] -%\@ifpackagelater{expl3}{2015/11/04} +\RequirePackage{expl3}[2015/12/20] +%\@ifpackagelater{expl3}{2015/12/20} % {} % {% % \PackageError{l3sort}{Support package l3kernel too old} @@ -50,7 +50,7 @@ % }% % \endinput % } -\GetIdInfo$Id: l3sort.dtx 6224 2015-11-04 08:38:08Z joseph $ +\GetIdInfo$Id: l3sort.dtx 6326 2015-12-20 18:42:59Z joseph $ {L3 Experimental sorting functions} % %<*driver> diff --git a/Master/texmf-dist/source/latex/l3experimental/l3str/l3flag.dtx b/Master/texmf-dist/source/latex/l3experimental/l3str/l3flag.dtx index 0b24181815d..5fa762e70ee 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3str/l3flag.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3str/l3flag.dtx @@ -36,8 +36,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}[2015/11/04] -%\@ifpackagelater{expl3}{2015/11/04} +\RequirePackage{expl3}[2015/12/20] +%\@ifpackagelater{expl3}{2015/12/20} % {} % {% % \PackageError{l3flag}{Support package l3kernel too old} @@ -49,7 +49,7 @@ % }% % \endinput % } -\GetIdInfo$Id: l3flag.dtx 6224 2015-11-04 08:38:08Z joseph $ +\GetIdInfo$Id: l3flag.dtx 6326 2015-12-20 18:42:59Z joseph $ {L3 Experimental flags} % %<*driver> diff --git a/Master/texmf-dist/source/latex/l3experimental/l3str/l3regex.dtx b/Master/texmf-dist/source/latex/l3experimental/l3str/l3regex.dtx index 0cd706da66d..d35147e002f 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3str/l3regex.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3str/l3regex.dtx @@ -36,8 +36,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}[2015/11/04] -%\@ifpackagelater{expl3}{2015/11/04} +\RequirePackage{expl3}[2015/12/20] +%\@ifpackagelater{expl3}{2015/12/20} % {} % {% % \PackageError{l3regex}{Support package l3kernel too old} @@ -49,7 +49,7 @@ % }% % \endinput % } -\GetIdInfo$Id: l3regex.dtx 6224 2015-11-04 08:38:08Z joseph $ +\GetIdInfo$Id: l3regex.dtx 6326 2015-12-20 18:42:59Z joseph $ {L3 Experimental regular expressions} % %<*driver> @@ -1432,7 +1432,7 @@ } { \char_set_lccode:nn { \c_zero } {#1} - \tl_to_lowercase:n + \tex_lowercase:D { \tl_set:Nx \l_@@_internal_b_tl { \if_false: } \fi: @@ -5016,7 +5016,7 @@ \__msg_kernel_error:nn { regex } { replacement-catcode-end } \else: \tex_lccode:D \c_zero = `#3 \scan_stop: - \tl_to_lowercase:n { \__tl_build_one:n {#1} } + \tex_lowercase:D { \__tl_build_one:n {#1} } \fi: } % \end{macrocode} @@ -5150,7 +5150,7 @@ \__msg_kernel_error:nn { regex } { replacement-null-space } \fi: \tex_lccode:D 32 = `#2 \scan_stop: - \tl_to_lowercase:n { \__tl_build_one:n {~} } + \tex_lowercase:D { \__tl_build_one:n {~} } \fi: } % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/l3experimental/l3str/l3tl-analysis.dtx b/Master/texmf-dist/source/latex/l3experimental/l3str/l3tl-analysis.dtx index 43b7308ca6e..41178195dc6 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3str/l3tl-analysis.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3str/l3tl-analysis.dtx @@ -35,7 +35,7 @@ % %<*driver|package> \RequirePackage{expl3} -\GetIdInfo$Id: l3tl-analysis.dtx 6106 2015-09-26 08:54:30Z joseph $ +\GetIdInfo$Id: l3tl-analysis.dtx 6244 2015-11-09 13:33:20Z joseph $ {L3 Experimental token lists analysis} % %<*driver> @@ -422,7 +422,7 @@ \cs_new_protected:Npn \@@_disable_loop:N #1 { \tex_lccode:D \c_zero `#1 ~ - \tl_to_lowercase:n { \tex_let:D ^^@ } \tex_undefined:D + \tex_lowercase:D { \tex_let:D ^^@ } \tex_undefined:D \@@_disable_loop:N } \group_end: @@ -607,7 +607,7 @@ \cs_new_protected:Npn \@@_a_group:nw #1 { \tex_lccode:D \c_zero = \@@_extract_charcode: \scan_stop: - \tl_to_lowercase:n { \tex_toks:D \l_@@_index_int {#1} } + \tex_lowercase:D { \tex_toks:D \l_@@_index_int {#1} } \if_int_compare:w \tex_lccode:D \c_zero = \tex_escapechar:D \int_set:Nn \tex_escapechar:D { 139 - \tex_escapechar:D } \fi: diff --git a/Master/texmf-dist/source/latex/l3experimental/l3str/l3tl-build.dtx b/Master/texmf-dist/source/latex/l3experimental/l3str/l3tl-build.dtx index 303d73e1863..b37c5a31c28 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3str/l3tl-build.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3str/l3tl-build.dtx @@ -36,8 +36,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}[2015/11/04] -%\@ifpackagelater{expl3}{2015/11/04} +\RequirePackage{expl3}[2015/12/20] +%\@ifpackagelater{expl3}{2015/12/20} % {} % {% % \PackageError{l3tl-build}{Support package l3kernel too old} @@ -49,7 +49,7 @@ % }% % \endinput % } -\GetIdInfo$Id: l3tl-build.dtx 6224 2015-11-04 08:38:08Z joseph $ +\GetIdInfo$Id: l3tl-build.dtx 6326 2015-12-20 18:42:59Z joseph $ {L3 Experimental token list construction} % %<*driver> diff --git a/Master/texmf-dist/source/latex/l3experimental/xgalley/l3galley.dtx b/Master/texmf-dist/source/latex/l3experimental/xgalley/l3galley.dtx index 4ba40fccdce..47270bb408d 100644 --- a/Master/texmf-dist/source/latex/l3experimental/xgalley/l3galley.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/xgalley/l3galley.dtx @@ -38,8 +38,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}[2015/11/04] -%\@ifpackagelater{expl3}{2015/11/04} +\RequirePackage{expl3}[2015/12/20] +%\@ifpackagelater{expl3}{2015/12/20} % {} % {% % \PackageError{l3galley}{Support package l3kernel too old} @@ -51,7 +51,7 @@ % }% % \endinput % } -\GetIdInfo$Id: l3galley.dtx 6224 2015-11-04 08:38:08Z joseph $ +\GetIdInfo$Id: l3galley.dtx 6326 2015-12-20 18:42:59Z joseph $ {L3 Experimental galley code} % %<*driver> diff --git a/Master/texmf-dist/source/latex/l3packages/l3keys2e/l3keys2e.dtx b/Master/texmf-dist/source/latex/l3packages/l3keys2e/l3keys2e.dtx index 79d549806b8..c59d2eeb876 100644 --- a/Master/texmf-dist/source/latex/l3packages/l3keys2e/l3keys2e.dtx +++ b/Master/texmf-dist/source/latex/l3packages/l3keys2e/l3keys2e.dtx @@ -37,8 +37,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}[2015/11/04] -%\@ifpackagelater{expl3}{2015/11/04} +\RequirePackage{expl3}[2015/12/20] +%\@ifpackagelater{expl3}{2015/12/20} % {} % {% % \PackageError{l3keys2e}{Support package l3kernel too old} @@ -52,8 +52,8 @@ % } \def\ExplFileName{l3keys2e} \def\ExplFileDescription{LaTeX2e option processing using LaTeX3 keys} -\def\ExplFileDate{2015/11/04} -\def\ExplFileVersion{6224} +\def\ExplFileDate{2015/12/20} +\def\ExplFileVersion{6326} % %<*driver> \documentclass[full]{l3doc} diff --git a/Master/texmf-dist/source/latex/l3packages/xfrac/xfrac.dtx b/Master/texmf-dist/source/latex/l3packages/xfrac/xfrac.dtx index d6f77268574..94875c846f7 100644 --- a/Master/texmf-dist/source/latex/l3packages/xfrac/xfrac.dtx +++ b/Master/texmf-dist/source/latex/l3packages/xfrac/xfrac.dtx @@ -38,8 +38,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}[2015/11/04] -%\@ifpackagelater{expl3}{2015/11/04} +\RequirePackage{expl3}[2015/12/20] +%\@ifpackagelater{expl3}{2015/12/20} % {} % {% % \PackageError{xfrac}{Support package l3kernel too old} @@ -54,8 +54,8 @@ \RequirePackage{amstext,graphicx,l3keys2e,textcomp,xparse,xtemplate} \def\ExplFileName{xfrac} \def\ExplFileDescription{L3 Experimental split-level fractions} -\def\ExplFileDate{2015/11/04} -\def\ExplFileVersion{6224} +\def\ExplFileDate{2015/12/20} +\def\ExplFileVersion{6326} % %<*driver> \documentclass[full]{l3doc} diff --git a/Master/texmf-dist/source/latex/l3packages/xparse/xparse.dtx b/Master/texmf-dist/source/latex/l3packages/xparse/xparse.dtx index acb89c006d8..392b93262f9 100644 --- a/Master/texmf-dist/source/latex/l3packages/xparse/xparse.dtx +++ b/Master/texmf-dist/source/latex/l3packages/xparse/xparse.dtx @@ -41,8 +41,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}[2015/11/04] -%\@ifpackagelater{expl3}{2015/11/04} +\RequirePackage{expl3}[2015/12/20] +%\@ifpackagelater{expl3}{2015/12/20} % {} % {% % \PackageError{xparse}{Support package l3kernel too old} @@ -56,8 +56,8 @@ % } \def\ExplFileName{xparse} \def\ExplFileDescription{L3 Experimental document command parser} -\def\ExplFileDate{2015/11/04} -\def\ExplFileVersion{6224} +\def\ExplFileDate{2015/12/20} +\def\ExplFileVersion{6326} % %<*driver> \documentclass[full]{l3doc} @@ -195,6 +195,12 @@ % |-NoValue-| if not present. % \item[G] As for \texttt{g} but returns \meta{default} if no value % is given: \texttt{G}\marg{default}. +% \item[k] An optional \emph{key} argument which requires a \emph{value}: +% the key should be a single \meta{token}. If the key is not present, +% returns |-NoValue-|. \emph{This is an experimental type}. +% \item[K] As for \texttt{K} but returns \meta{default} if no value +% is given: \texttt{K}\meta{token}\marg{default}. +% \emph{This is an experimental type}. % \end{itemize} % % Using these specifiers, it is possible to create complex input syntax @@ -282,7 +288,11 @@ % \verb*|\foo{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. +% 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. % % \subsection{Required delimited arguments} % @@ -638,16 +648,17 @@ % \item The \enquote{optional group} argument types \texttt{g} and % \texttt{G} are not available. % \item The \enquote{verbatim} argument type \texttt{v} is not available. +% \item Argument processors (using \texttt{>}) are not available. % \item It is not possible to differentiate between, for example % |\foo[| and |\foo{[}|: in both cases the \texttt{[} will be -% interpreted as the start of an optional argument. As a result +% interpreted as the start of an optional argument. As a % 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 +% which does not conform to the first six requirements. The last % item is an issue when the function is used, and so is beyond the -% scope of \pkg{xparse} itself. +% scope of \pkg{xparse} itself. % \end{function} % % \subsection{Access to the argument specification} @@ -1103,8 +1114,8 @@ % \begin{macro}{\@@_count_mandatory:n} % \begin{macro}{\@@_count_mandatory:N} % \begin{macro}[aux]{\@@_count_mandatory:N} -% To count up mandatory arguments before the main parsing run, the same -% approach is used. First, check if the current token is a short-cut for +% Loop through the signature to count up mandatory arguments before the +% main parsing run. First, check if the current token is a short-cut for % another argument type. If it is, expand it and loop again. If not, then % look for a \enquote{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. @@ -1124,9 +1135,8 @@ } \cs_new_protected:Npn \@@_count_mandatory_aux:N #1 { - \cs_if_free:cTF { @@_count_type_ \token_to_str:N #1 :w } + \cs_if_exist_use:cF { @@_count_type_ \token_to_str:N #1 :w } { \@@_count_type_m:w } - { \use:c { @@_count_type_ \token_to_str:N #1 :w } } } % \end{macrocode} % \end{macro} @@ -1141,7 +1151,11 @@ % \@@_count_type_D:w, % \@@_count_type_g:w, % \@@_count_type_G:w, +% \@@_count_type_k:w, +% \@@_count_type_K:w, % \@@_count_type_m:w, +% \@@_count_type_r:w, +% \@@_count_type_R:w, % \@@_count_type_t:w, % \@@_count_type_u:w % } @@ -1158,14 +1172,22 @@ % the case, the entire set up is abandoned to avoid any strange internal % errors. The opportunity is also taken to make sure that where a single % token is required, one has actually been supplied. +% +% The third is that processors and the marker~|+| for long arguments +% must be followed by arguments. For this, just check that the next +% token is not \cs{q_recursion_tail}, and remember to leave it after +% the looping macro. % \begin{macrocode} -\cs_new_protected:cpn { @@_count_type_>:w } #1 +\cs_new_protected:cpn { @@_count_type_>:w } #1#2 + { + \quark_if_recursion_tail_stop_do:nn {#2} { \@@_bad_arg_spec:wn } + \@@_count_mandatory:N #2 + } +\cs_new_protected:cpn { @@_count_type_+:w } #1 { \quark_if_recursion_tail_stop_do:nn {#1} { \@@_bad_arg_spec:wn } - \@@_count_mandatory:N + \@@_count_mandatory:N #1 } -\cs_new_protected_nopar:cpn { @@_count_type_+:w } - { \@@_count_mandatory:N } \cs_new_protected:Npn \@@_count_type_d:w #1#2 { \@@_single_token_check:n {#1} @@ -1187,6 +1209,18 @@ \quark_if_recursion_tail_stop_do:nn {#1} { \@@_bad_arg_spec:wn } \@@_count_mandatory:N } +\cs_new_protected:Npn \@@_count_type_k:w #1 + { + \@@_single_token_check:n {#1} + \quark_if_recursion_tail_stop_do:Nn #1 { \@@_bad_arg_spec:wn } + \@@_count_mandatory:N + } +\cs_new_protected:Npn \@@_count_type_K:w #1#2 + { + \@@_single_token_check:n {#1} + \quark_if_recursion_tail_stop_do:nn {#2} { \@@_bad_arg_spec:wn } + \@@_count_mandatory:N + } \cs_new_protected_nopar:Npn \@@_count_type_m:w { \int_incr:N \l_@@_mandatory_args_int @@ -1230,7 +1264,7 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_single_token_check:n #1 { - \tl_if_single:nF {#1} + \exp_args:Nx \tl_if_single_token:nF { \tl_trim_spaces:n {#1} } { \@@_single_token_check_aux:nwn {#1} } } \cs_new_protected:Npn \@@_single_token_check_aux:nwn @@ -1273,7 +1307,7 @@ \@@_prepare_signature:N #1 \q_recursion_tail \q_recursion_stop } % \end{macrocode} -% The main looping function does not take an argument,but carries out the +% The main looping function does not take an argument, but carries out the % reset on the processor boolean. This is split off from the rest of the % process so that when actually setting up processors the flag-reset can % be bypassed. @@ -1323,12 +1357,12 @@ % % \subsection{Setting up a standard signature} % -% 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{@@_prepare_signature:N}. +% Each argument-adding function appends to the signature a grabber (and +% for some types, the delimiters or default value), except the one for +% \texttt{m} arguments. These are collected and added to the signature +% all at once by \cs{@@_flush_m_args:}, called for every other argument +% type. All of the functions then call the loop function +% \cs{@@_prepare_signature:N}. % % \begin{macro}{\@@_add_type_+:w} % Making the next argument long means setting the flag and knocking one back @@ -1355,8 +1389,8 @@ % \begin{macrocode} \cs_new_protected:cpn { @@_add_type_>:w } #1 { - \bool_set_true:N \l_@@_processor_bool \@@_flush_m_args: + \bool_set_true:N \l_@@_processor_bool \int_decr:N \l_@@_current_arg_int \tl_put_right:Nn \l_@@_signature_tl { \@@_process_arg:n {#1} } \@@_prepare_signature_bypass:N @@ -1404,6 +1438,22 @@ % \end{macrocode} % \end{macro} % +% \begin{macro}{\@@_add_type_k:w, \@@_add_type_K:w} +% Similar to |d|/|D| type but just one token to store. +% \begin{macrocode} +\cs_new_protected:Npn \@@_add_type_k:w #1 + { \exp_args:NNo \@@_add_type_K:w #1 \c_@@_no_value_tl } +\cs_new_protected:Npn \@@_add_type_K:w #1#2 + { + \@@_flush_m_args: + \@@_add_grabber_optional:N K + \tl_put_right:Nn \l_@@_signature_tl { #1 {#2} } + \@@_prepare_signature:N + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% % \begin{macro}{\@@_add_type_l:w} % Finding \texttt{l} arguments is very simple: there is nothing to do % other than add the grabber. @@ -1462,7 +1512,7 @@ { \@@_flush_m_args: \@@_add_grabber_optional:N t - \tl_put_right:Nn \l_@@_signature_tl { #1 } + \tl_put_right:Nn \l_@@_signature_tl {#1} \@@_prepare_signature:N } % \end{macrocode} @@ -1498,7 +1548,8 @@ % 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 +% be switched here. The total number of mandatory arguments which +% remain to be added to % the signature is also decreased by the appropriate amount. % \begin{macrocode} \cs_new_protected_nopar:Npn \@@_flush_m_args: @@ -1506,9 +1557,8 @@ \int_compare:nNnT \l_@@_m_args_int > \c_zero { \tl_put_right:Nx \l_@@_signature_tl - { \exp_not:c { @@_grab_m_ \int_use:N \l_@@_m_args_int :w } } - \int_set:Nn \l_@@_mandatory_args_int - { \l_@@_mandatory_args_int - \l_@@_m_args_int } + { \exp_not:c { @@_grab_m_ \int_use:N \l_@@_m_args_int :w } } + \int_sub:Nn \l_@@_mandatory_args_int { \l_@@_m_args_int } } \int_zero:N \l_@@_m_args_int } @@ -1607,7 +1657,7 @@ } \cs_new_protected:Npn \@@_add_expandable_type_D:w #1#2 { - \token_if_eq_meaning:NNTF #1 #2 + \tl_if_eq:nnTF {#1} {#2} { \@@_add_expandable_grabber_optional:n { D_alt } \@@_add_expandable_type_D_aux:Nn #1 @@ -1678,6 +1728,34 @@ % \end{macro} % \end{macro} % +% \begin{macro}{\@@_add_expandable_type_k:w} +% \begin{macro}{\@@_add_expandable_type_K:w} +% \begin{macrocode} +\cs_new_protected_nopar:Npn \@@_add_expandable_type_k:w #1 + { + \exp_args:NNo + \@@_add_expandable_type_K:w #1 \c_@@_no_value_tl + } +\cs_new_protected_nopar:Npn \@@_add_expandable_type_K:w #1#2 + { + \@@_add_expandable_grabber_optional:n { K } + \bool_if:NTF \l_@@_all_long_bool + { \cs_set:cpx } + { \cs_set_nopar:cpx } + { \l_@@_expandable_aux_name_tl } ##1 #1 ##2 + { ##1 {##2} } + \tl_put_right:Nx \l_@@_signature_tl + { + \exp_not:c { \l_@@_expandable_aux_name_tl } + \exp_not:n { #1 {#2} } + } + \bool_set_false:N \l_@@_long_bool + \@@_prepare_signature:N + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% % \begin{macro}{\@@_add_expandable_type_l:w} % Invalid in expandable contexts (as the next left brace may have been % inserted by \pkg{xparse} due to a failed search for an optional argument). @@ -1719,13 +1797,13 @@ } \cs_new_protected:Npn \@@_add_expandable_type_R:w #1#2 { - \token_if_eq_meaning:NNTF #1 #2 + \tl_if_eq:nnTF {#1} {#2} { - \@@_add_expandable_grabber_optional:n { R_alt } + \@@_add_expandable_grabber_mandatory:n { R_alt } \@@_add_expandable_type_D_aux:Nn #1 } { - \@@_add_expandable_grabber_optional:n { R } + \@@_add_expandable_grabber_mandatory:n { R } \@@_add_expandable_type_D_aux:NNn #1#2 } } @@ -1744,7 +1822,7 @@ { \l_@@_expandable_aux_name_tl } ##1 #1 {##1} \tl_put_right:Nx \l_@@_signature_tl { - \exp_not:c { \l_@@_expandable_aux_name_tl } + \exp_not:c { \l_@@_expandable_aux_name_tl } \exp_not:N #1 } \bool_set_false:N \l_@@_long_bool @@ -1767,7 +1845,7 @@ % \end{macro} % % \begin{macro}{\@@_add_expandable_type_v:w} -% Another forbidden type. +% Another forbidden type. % \begin{macrocode} \cs_new_protected_nopar:Npn \@@_add_expandable_type_v:w { @@ -1808,7 +1886,7 @@ } \cs_new_protected_nopar:Npn \@@_add_expandable_long_check: { - \bool_if:nT { \l_@@_all_long_bool && ! ( \l_@@_long_bool ) } + \bool_if:nT { \l_@@_all_long_bool && ! \l_@@_long_bool } { \__msg_kernel_error:nn { xparse } { inconsistent-long } } } % \end{macrocode} @@ -1819,7 +1897,7 @@ % % All of the grabbers follow the same basic pattern. The initial % function sets up the appropriate information to define -% \cs{parse_grab_arg:w} to grab the argument. This means determining +% \cs{@@_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{@@_grab_arg:w} is then called to actually do the grabbing. @@ -1890,7 +1968,8 @@ % grabbed argument is entirely enclosed by braces. There are a couple of % extra factors to allow for: the argument might be entirely empty, and % spaces at the start and end of the input must be retained around a brace -% group. +% group. Also notice that a \emph{blank} argument might still contain +% spaces. % \begin{macrocode} \cs_new_protected:Npn \@@_grab_D_aux:NNnN #1#2#3#4 { @@ -2059,6 +2138,56 @@ % \end{macro} % \end{macro} % +% \begin{macro}{\@@_grab_K:w, \@@_grab_K_long:w} +% \begin{macro}[aux]{\@@_grab_K_aux:nnnNn} +% Look ahead at one token and if it matches grab an argument. +% \begin{macrocode} +\cs_new_protected:Npn \@@_grab_K:w #1#2#3 \l_@@_args_tl + { + \@@_grab_K_aux:nnnNn + {#1} {#2} {#3} + \cs_set_protected_nopar:Npn + { _ignore_spaces } + } +\cs_new_protected:Npn \@@_grab_K_long:w #1#2#3 \l_@@_args_tl + { + \@@_grab_K_aux:nnnNn + {#1} {#2} {#3} + \cs_set_protected:Npn + { _ignore_spaces } + } +\cs_new_protected:Npn \@@_grab_K_trailing:w #1#2#3 \l_@@_args_tl + { + \@@_grab_K_aux:nnnNn + {#1} {#2} {#3} + \cs_set_protected_nopar:Npn + { } + } +\cs_new_protected:Npn \@@_grab_K_long_trailing:w #1#2#3 \l_@@_args_tl + { + \@@_grab_K_aux:nnnNn + {#1} {#2} {#3} + \cs_set_protected:Npn + { } + } +\cs_new_protected:Npn \@@_grab_K_aux:nnnNn #1#2#3#4#5 + { + \exp_after:wN #4 \l_@@_fn_tl ##1 + { + \@@_add_arg:n {##1} + #3 \l_@@_args_tl + } + \use:c { peek_meaning_remove #5 :NTF } #1 + { \l_@@_fn_tl } + { + \@@_add_arg:n {#2} + #3 \l_@@_args_tl + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% % \begin{macro}{\@@_grab_l:w} % \begin{macro}{\@@_grab_l_long:w} % \begin{macro}[aux]{\@@_grab_l_aux:nN} @@ -2413,7 +2542,7 @@ { \@@_grab_v_aux_loop:NN #1 } { \@@_grab_v_aux_abort:n { } } } -\cs_new_protected:Npn \@@_grab_v_aux_loop:NN #1 #2 +\cs_new_protected:Npn \@@_grab_v_aux_loop:NN #1#2 { \@@_grab_v_token_if_char:NTF #2 { @@ -2675,7 +2804,7 @@ { \str_if_eq:onTF { #1 { } { } #7 #2 \q_@@ #3 } - { { } { #2 } { } } + { { } {#2} { } } { #1 { \@@_expandable_grab_D:NNNwNnnn #1#2#3#5 \q_@@ #6 } @@ -2717,7 +2846,7 @@ { #3 { \use_none:nnn } #2 \q_@@ #5 #4 \q_@@ #5 } { \tl_if_blank:oTF { \use_none:nn #1#2 } - { \@@_put_arg_expandable:ow { } } + { \@@_put_arg_expandable:ow { \use_none:nn #1#2 } } { \str_if_eq_x:nnTF { \exp_not:o { \use_none:nn #1#2 } } @@ -2725,7 +2854,7 @@ { \@@_put_arg_expandable:ow { \use_iii:nnn #1#2 } } { \@@_put_arg_expandable:ow { \use_none:nn #1#2 } } } - #6 \q_@@ #7 + #6 \q_@@ #7 } { #3 @@ -2763,8 +2892,8 @@ } \cs_new:Npn \@@_expandable_grab_D_alt:Nwn #1#2 \q_@@ #3 { - \tl_if_blank:oTF { \use_none:nn #1#2 } - { \@@_put_arg_expandable:ow { } } + \tl_if_blank:oTF { \use_none:n #3 } + { \@@_put_arg_expandable:ow { \use_none:n #3 } } { \str_if_eq_x:nnTF { \exp_not:o { \use_none:n #3 } } @@ -2772,13 +2901,36 @@ { \@@_put_arg_expandable:ow { \use_ii:nn #3 } } { \@@_put_arg_expandable:ow { \use_none:n #3 } } } - #2 \q_@@ #1 + #2 \q_@@ #1 } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % +% \begin{macro}[EXP]{\@@_expandable_grab_K:w} +% \begin{macro}[EXP, aux]{\@@_expandable_grab_K_aux:NNwn} +% As for the |D|-type grabber, use the auxiliary to do the look ahead +% test then reuse it for the grabbing. +% \begin{macrocode} +\cs_new:Npn \@@_expandable_grab_K:w #1 \q_@@ #2 + { #2 { \@@_expandable_grab_K_aux:NNwn #1 \q_@@ #2 } } +\cs_new:Npn \@@_expandable_grab_K_aux:NNwn #1#2#3#4 \q_@@ #5#6 + { + \str_if_eq:onTF { #1 { } #6 { } #2 { } } { { } #2 { } } + { + #1 + { \@@_expandable_grab_K_aux:Nwn #5 #4 \q_@@ } + #6 + } + { #4 {#3} \q_@@ #5 {#6} } + } +\cs_new:Npn \@@_expandable_grab_K_aux:Nwn #1#2 \q_@@ #3 + { #2 {#3} \q_@@ #1 } +% \end{macrocode} +% \end{macro} +% \end{macro} +% % \begin{macro}[EXP]{\@@_expandable_grab_m:w} % \begin{macro}[EXP, aux]{\@@_expandable_grab_m_aux:wNn} % The mandatory case is easy: find the auxiliary after the \cs{q_@@}, and @@ -2803,7 +2955,7 @@ { \str_if_eq:onTF { #1 { } { } #7 #2 \q_@@ #3 } - { { } { #2 } { } } + { { } {#2} { } } { #1 { \@@_expandable_grab_D:NNNwNnnn #1#2#3#5 \q_@@ #6 } @@ -2857,7 +3009,7 @@ { #2 { \@@_expandable_grab_t_aux:NNwn #1 \q_@@ #2 } } \cs_new:Npn \@@_expandable_grab_t_aux:NNwn #1#2#3 \q_@@ #4#5 { - \str_if_eq:onTF { #1 { } #5 #2 } { #2 } + \str_if_eq:onTF { #1 { } #5 #2 } {#2} { #3 { \BooleanTrue } \q_@@ #4 } { #3 { \BooleanFalse } \q_@@ #4 {#5} } } @@ -2890,20 +3042,13 @@ \cs_new_protected:Npn \@@_process_arg:n #1 { \int_incr:N \l_@@_processor_int - \cs_set:cpn { @@_processor_ \int_use:N \l_@@_processor_int :n } ##1 - { #1 {##1} } + \cs_set_protected:cpx + { @@_processor_ \int_use:N \l_@@_processor_int :n } ##1 + { \exp_not:n {#1} {##1} } } % \end{macrocode} % \end{macro} % -% \begin{macro}{\@@_process_to_str:n} -% A basic argument processor: as much an example as anything else. -% \begin{macrocode} -\cs_new_protected:Npn \@@_process_to_str:n #1 - { \tl_set:Nx \ProcessedArgument { \tl_to_str:n {#1} } } -% \end{macrocode} -% \end{macro} -% % \begin{macro}{\@@_bool_reverse:N} % A simple reversal. % \begin{macrocode} @@ -2928,15 +3073,15 @@ \tl_new:N \l_@@_split_list_tl \cs_new_protected:Npn \@@_split_list:nn #1#2 { - \bool_if:nTF + \tl_if_single:nTF {#1} { - \tl_if_single_p:n {#1} && - ! ( \token_if_cs_p:N #1 ) + \token_if_cs:NTF #1 + { \@@_split_list_multi:nn {#1} {#2} } + { \@@_split_list_single:Nn #1 {#2} } } - { \@@_split_list_single:Nn #1 {#2} } { \@@_split_list_multi:nn {#1} {#2} } - } -\cs_set_protected:Npn \@@_split_list_multi:nn #1#2 + } +\cs_new_protected:Npn \@@_split_list_multi:nn #1#2 { \seq_set_split:Nnn \l_@@_split_list_seq {#1} {#2} \tl_clear:N \ProcessedArgument @@ -2945,16 +3090,16 @@ } \cs_generate_variant:Nn \@@_split_list_multi:nn { nV } \group_begin: -\char_set_catcode_active:N \@ +\char_set_catcode_active:N \^^@ \cs_new_protected:Npn \@@_split_list_single:Nn #1#2 { \tl_set:Nn \l_@@_split_list_tl {#2} \group_begin: - \char_set_lccode:nn { `\@ } { `#1 } + \char_set_lccode:nn { `\^^@ } { `#1 } \tex_lowercase:D { \group_end: - \tl_replace_all:Nnn \l_@@_split_list_tl { @ } + \tl_replace_all:Nnn \l_@@_split_list_tl { ^^@ } } {#1} \@@_split_list_multi:nV {#1} \l_@@_split_list_tl } @@ -2968,7 +3113,7 @@ % \begin{macro}{\@@_split_argument:nnn} % \begin{macro}[aux]{\@@_split_argument_aux:nnnn} % \begin{macro}[aux, EXP]{\@@_split_argument_aux:n} -% \begin{macro}[aux, EXP]{\@@_split_argument_aux:wn} +% \begin{macro}[aux, rEXP]{\@@_split_argument_aux:wn} % Splitting to a known number of items is a special version of splitting % a list, in which the limit is hard-coded and where there will always be % exactly the correct number of output items. An auxiliary function is @@ -3037,33 +3182,58 @@ % % \subsection{Access to the argument specification} % +% \begin{macro}{\@@_get_arg_spec_error:N, \@@_get_arg_spec_error:n} +% Provide an informative error when trying to get the argument +% specification of a non-\pkg{xparse} command or environment. +% \begin{macrocode} +\cs_new_protected:Npn \@@_get_arg_spec_error:N #1 + { + \cs_if_exist:NTF #1 + { + \__msg_kernel_error:nnx { xparse } { non-xparse-command } + { \token_to_str:N #1 } + } + { + \__msg_kernel_error:nnx { xparse } { unknown-command } + { \token_to_str:N #1 } + } + } +\cs_new_protected:Npn \@@_get_arg_spec_error:n #1 + { + \cs_if_exist:cTF {#1} + { + \__msg_kernel_error:nnx { xparse } { non-xparse-environment } + { \tl_to_str:n {#1} } + } + { + \__msg_kernel_error:nnx { xparse } { unknown-environment } + { \tl_to_str:n {#1} } + } + } +% \end{macrocode} +% \end{macro} +% % \begin{macro}{\@@_get_arg_spec:N} % \begin{macro}{\@@_get_arg_spec:n} -% \begin{macro}{\ArgumentSpecification} -% Recovering the argument specification is also trivial, using the -% \cs{tl_set_eq:cN} function. +% \begin{variable}{\ArgumentSpecification} +% Recovering the argument specification is trivial, using the +% branching \cs{prop_get:NnN} function. % \begin{macrocode} \cs_new_protected:Npn \@@_get_arg_spec:N #1 { \prop_get:NnNF \l_@@_command_arg_specs_prop {#1} \ArgumentSpecification - { - \__msg_kernel_error:nnx { xparse } { unknown-document-command } - { \token_to_str:N #1 } - } + { \@@_get_arg_spec_error:N #1 } } \cs_new_protected:Npn \@@_get_arg_spec:n #1 { \prop_get:NnNF \l_@@_environment_arg_specs_prop {#1} \ArgumentSpecification - { - \__msg_kernel_error:nnx { xparse } { unknown-document-environment } - { \tl_to_str:n {#1} } - } + { \@@_get_arg_spec_error:n {#1} } } \tl_new:N \ArgumentSpecification % \end{macrocode} -% \end{macro} +% \end{variable} % \end{macro} % \end{macro} % @@ -3077,20 +3247,14 @@ \prop_get:NnNTF \l_@@_command_arg_specs_prop {#1} \ArgumentSpecification { \tl_show:N \ArgumentSpecification } - { - \__msg_kernel_error:nnx { xparse } { unknown-document-command } - { \token_to_str:N #1 } - } + { \@@_get_arg_spec_error:N #1 } } \cs_new_protected:Npn \@@_show_arg_spec:n #1 { \prop_get:NnNTF \l_@@_environment_arg_specs_prop {#1} \ArgumentSpecification { \tl_show:N \ArgumentSpecification } - { - \__msg_kernel_error:nnx { xparse } { unknown-document-environment } - { \tl_to_str:n {#1} } - } + { \@@_get_arg_spec_error:n {#1} } } % \end{macrocode} % \end{macro} @@ -3100,8 +3264,8 @@ % % \begin{macro}[TF]{\@@_if_no_value:n} % Tests for |-NoValue-|: this is similar to \cs{tl_if_in:nn} but set -% up to be expandable. The question mark prevents the auxiliary from -% losing braces. +% up to be expandable and to check the value exactly. The question +% mark prevents the auxiliary from losing braces. % \begin{macrocode} \use:x { @@ -3118,15 +3282,65 @@ { \exp_not:N \prg_return_false: } } \cs_new:Npn \exp_not:N \@@_if_value_aux:w ##1 \c_@@_no_value_tl - { ##1 } - } + {##1} + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_check_definable:nNT, \@@_check_definable_aux:nN} +% Check that a token list is appropriate as a first argument of +% \cs{DeclareDocumentCommand} and similar functions and otherwise +% produce an error. First trim whitespace to allow for spaces around +% the actual command to be defined. If the result has multiple +% tokens, it is not a valid argument. The single token is a control +% sequence exactly if its string representation has more than one +% character (using \cs{token_to_str:N} rather than \cs{tl_to_str:n} +% to avoid problems with macro parameter characters, and setting +% \cs{tex_escapechar:D} to prevent it from being non-printable). +% Finally, check for an active character: this is done by lowercasing +% the token to fix its character code (arbitrarily to that of~|?|) +% and comparing the result to an active~|?|. Both control sequences +% and active characters are valid arguments, and non-active character +% tokens are not. In all cases, the group opened to keep assignments +% 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} } } +\group_begin: + \char_set_catcode_active:n { `? } + \cs_new_protected:Npn \@@_check_definable_aux:nN #1#2 + { + \group_begin: + \tl_if_single_token:nTF {#1} + { + \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 } } + { + \exp_args:Nx \char_set_lccode:nn + { ` \str_head:n {#1} } { `? } + \tex_lowercase:D { \tl_if_eq:nnTF {#1} } { ? } + { \group_end: \use_iii:nnn } + { \group_end: \use_i:nnn } + } + { \group_end: \use_iii:nnn } + } + { \group_end: \use_ii:nnn } + { + \__msg_kernel_error:nnxx { xparse } { not-definable } + { \tl_to_str:n {#1} } { \token_to_str:N #2 } + } + { + \__msg_kernel_error:nnxx { xparse } { not-one-token } + { \tl_to_str:n {#1} } { \token_to_str:N #2 } + } + } +\group_end: % \end{macrocode} % \end{macro} % % \subsection{Messages} % -% \subsection{Messages} -% % Some messages intended as errors. % \begin{macrocode} \__msg_kernel_new:nnnn { xparse } { bad-arg-spec } @@ -3158,12 +3372,6 @@ with~an~environment~that~already~has~a~definition. \\ The~existing~definition~of~'#1'~will~be~overwritten. } -\__msg_kernel_new:nnnn { xparse } { environment-mismatch } - { Mismatch~between~start~and~end~of~environment. } - { - The~current~environment~is~called~'#1',~but~you~have~tried~to~ - end~one~called~'#2'.~Environments~have~to~be~properly~nested. - } \__msg_kernel_new:nnnn { xparse } { environment-not-yet-defined } { Environment~'#1'~not~yet~defined! } { @@ -3171,13 +3379,6 @@ with~an~environment~that~was~never~defined. \\ A~new~environment~'#1'~will~be~created. } -\__msg_kernel_new:nnnn { xparse } { environment-unknown } - { Environment~'#1'~undefined. } - { - You~have~tried~to~start~an~environment~called~'#1',~ - but~this~has~never~been~defined. \\ - The~command~will~be~ignored. - } \__msg_kernel_new:nnnn { xparse } { expandable-ending-optional } { Argument~specification~for~expandable~command~ends~with~optional~argument. @@ -3211,6 +3412,38 @@ '#1'.~LaTeX~did~not~find~it,~and~will~insert~'#2'~as~the~value~to~be~ processed. } +\__msg_kernel_new:nnnn { xparse } { non-xparse-command } + { Command~'#1'~not~defined~using~xparse. } + { + You~have~asked~for~the~argument~specification~for~a~command~'#1',~ + but~this~is~not~a~command~defined~using~xparse. + } +\__msg_kernel_new:nnnn { xparse } { non-xparse-environment } + { Environment~'#1'~not~defined~using~xparse. } + { + You~have~asked~for~the~argument~specification~for~an~environment~'#1',~ + but~this~is~not~an~environment~defined~using~xparse. + } +\__msg_kernel_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? + \\ \\ + LaTeX~will~ignore~this~entire~definition. + } +\__msg_kernel_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. + \\ \\ + LaTeX~will~ignore~this~entire~definition. + } \__msg_kernel_new:nnnn { xparse } { not-single-token } { Argument~delimiter~should~be~a~single~token:~'#1'. } { @@ -3240,17 +3473,17 @@ The~letter~'#1'~does~not~specify~a~known~argument~type.~ LaTeX~will~assume~you~want~a~standard~mandatory~argument~(type~'m'). } -\__msg_kernel_new:nnnn { xparse } { unknown-document-command } +\__msg_kernel_new:nnnn { xparse } { unknown-command } { Unknown~document~command~'#1'. } { You~have~asked~for~the~argument~specification~for~a~command~'#1',~ - but~this~is~not~a~document~command. + but~it~is~not~defined. } -\__msg_kernel_new:nnnn { xparse } { unknown-document-environment } +\__msg_kernel_new:nnnn { xparse } { unknown-environment } { Unknown~document~environment~'#1'. } { - You~have~asked~for~the~argument~specification~for~a~command~'#1',~ - but~this~is~not~a~document~environment. + You~have~asked~for~the~argument~specification~for~an~environment~'#1',~ + but~it~is~not~defined. } \__msg_kernel_new:nnnn { xparse } { verbatim-newline } { Verbatim~argument~of~'#1'~ended~by~end~of~line. } @@ -3319,29 +3552,43 @@ % \begin{macro}{\RenewDocumentCommand} % \begin{macro}{\ProvideDocumentCommand} % The user macros are pretty simple wrappers around the internal ones. +% There is however a check that the first argument is a single token +% and is definable. % \begin{macrocode} \cs_new_protected:Npn \DeclareDocumentCommand #1#2#3 - { \@@_declare_cmd:Nnn #1 {#2} {#3} } + { + \@@_check_definable:nNT {#1} \DeclareDocumentCommand + { \@@_declare_cmd:Nnn #1 {#2} {#3} } + } \cs_new_protected:Npn \NewDocumentCommand #1#2#3 { - \cs_if_exist:NTF #1 + \@@_check_definable:nNT {#1} \NewDocumentCommand { - \__msg_kernel_error:nnx { xparse } { command-already-defined } - { \token_to_str:N #1 } + \cs_if_exist:NTF #1 + { + \__msg_kernel_error:nnx { xparse } { command-already-defined } + { \token_to_str:N #1 } + } + { \@@_declare_cmd:Nnn #1 {#2} {#3} } } - { \@@_declare_cmd:Nnn #1 {#2} {#3} } } \cs_new_protected:Npn \RenewDocumentCommand #1#2#3 { - \cs_if_exist:NTF #1 - { \@@_declare_cmd:Nnn #1 {#2} {#3} } + \@@_check_definable:nNT {#1} \RenewDocumentCommand { - \__msg_kernel_error:nnx { xparse } { command-not-yet-defined } - { \token_to_str:N #1 } + \cs_if_exist:NTF #1 + { \@@_declare_cmd:Nnn #1 {#2} {#3} } + { + \__msg_kernel_error:nnx { xparse } { command-not-yet-defined } + { \token_to_str:N #1 } + } } } \cs_new_protected:Npn \ProvideDocumentCommand #1#2#3 - { \cs_if_exist:NF #1 { \@@_declare_cmd:Nnn #1 {#2} {#3} } } + { + \@@_check_definable:nNT {#1} \ProvideDocumentCommand + { \cs_if_exist:NF #1 { \@@_declare_cmd:Nnn #1 {#2} {#3} } } + } % \end{macrocode} % \end{macro} % \end{macro} @@ -3369,7 +3616,7 @@ { \__msg_kernel_error:nnx { xparse } { environment-not-yet-defined } {#1} } } \cs_new_protected:Npn \ProvideDocumentEnvironment #1#2#3#4 - { \cs_if_exist:cF { #1 } { \@@_declare_env:nnnn {#1} {#2} {#3} {#4} } } + { \cs_if_exist:cF {#1} { \@@_declare_env:nnnn {#1} {#2} {#3} {#4} } } % \end{macrocode} % \end{macro} % \end{macro} @@ -3380,7 +3627,10 @@ % The expandable version of the basic function is essentially the same. % \begin{macrocode} \cs_new_protected:Npn \DeclareExpandableDocumentCommand #1#2#3 - { \@@_declare_expandable_cmd:Nnn #1 {#2} {#3} } + { + \@@_check_definable:nNT {#1} \DeclareExpandableDocumentCommand + { \@@_declare_expandable_cmd:Nnn #1 {#2} {#3} } + } % \end{macrocode} % \end{macro} % @@ -3406,9 +3656,9 @@ % \begin{macro}[TF]{\IfValue} % Inverted logic. % \begin{macrocode} -\cs_set:Npn \IfValueF { \@@_if_no_value:nT } -\cs_set:Npn \IfValueT { \@@_if_no_value:nF } -\cs_set:Npn \IfValueTF #1#2#3 { \@@_if_no_value:nTF {#1} {#3} {#2} } +\cs_new_nopar:Npn \IfValueF { \@@_if_no_value:nT } +\cs_new_nopar:Npn \IfValueT { \@@_if_no_value:nF } +\cs_new:Npn \IfValueTF #1#2#3 { \@@_if_no_value:nTF {#1} {#3} {#2} } % \end{macrocode} % \end{macro} % @@ -3441,11 +3691,20 @@ % \begin{macro}{\GetDocumentEnvironmentArgSpec} % \begin{macro}{\ShowDocumentCommandArgSpec} % \begin{macro}{\ShowDocumentEnvironmentArgSpec} -% More simple mappings. +% More simple mappings, with a check that the argument is a single +% control sequence or active character. % \begin{macrocode} -\cs_new_eq:NN \GetDocumentCommandArgSpec \@@_get_arg_spec:N -\cs_new_eq:NN \GetDocumentEnvironmmentArgSpec \@@_get_arg_spec:n -\cs_new_eq:NN \ShowDocumentCommandArgSpec \@@_show_arg_spec:N +\cs_new_protected:Npn \GetDocumentCommandArgSpec #1 + { + \@@_check_definable:nNT {#1} \GetDocumentCommandArgSpec + { \@@_get_arg_spec:N #1 } + } +\cs_new_eq:NN \GetDocumentEnvironmentArgSpec \@@_get_arg_spec:n +\cs_new_protected:Npn \ShowDocumentCommandArgSpec #1 + { + \@@_check_definable:nNT {#1} \ShowDocumentCommandArgSpec + { \@@_show_arg_spec:N #1 } + } \cs_new_eq:NN \ShowDocumentEnvironmentArgSpec \@@_show_arg_spec:n % \end{macrocode} % \end{macro} diff --git a/Master/texmf-dist/source/latex/l3packages/xtemplate/xtemplate.dtx b/Master/texmf-dist/source/latex/l3packages/xtemplate/xtemplate.dtx index d08e257b053..b2e0edc7cc6 100644 --- a/Master/texmf-dist/source/latex/l3packages/xtemplate/xtemplate.dtx +++ b/Master/texmf-dist/source/latex/l3packages/xtemplate/xtemplate.dtx @@ -41,8 +41,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}[2015/11/04] -%\@ifpackagelater{expl3}{2015/11/04} +\RequirePackage{expl3}[2015/12/20] +%\@ifpackagelater{expl3}{2015/12/20} % {} % {% % \PackageError{xtemplate}{Support package l3kernel too old} @@ -56,8 +56,8 @@ % } \def\ExplFileName{xtemplate} \def\ExplFileDescription{L3 Experimental prototype document functions} -\def\ExplFileDate{2015/11/04} -\def\ExplFileVersion{6224} +\def\ExplFileDate{2015/12/20} +\def\ExplFileVersion{6326} % %<*driver> \documentclass[full]{l3doc} -- cgit v1.2.3