diff options
Diffstat (limited to 'Master/texmf-dist/source')
-rw-r--r-- | Master/texmf-dist/source/latex/expl3/l3doc.dtx | 60 | ||||
-rw-r--r-- | Master/texmf-dist/source/latex/expl3/l3keys.dtx | 586 | ||||
-rw-r--r-- | Master/texmf-dist/source/latex/expl3/l3prg.dtx | 68 | ||||
-rw-r--r-- | Master/texmf-dist/source/latex/expl3/l3prop.dtx | 29 |
4 files changed, 367 insertions, 376 deletions
diff --git a/Master/texmf-dist/source/latex/expl3/l3doc.dtx b/Master/texmf-dist/source/latex/expl3/l3doc.dtx index e3802a53c91..197a6703a98 100644 --- a/Master/texmf-dist/source/latex/expl3/l3doc.dtx +++ b/Master/texmf-dist/source/latex/expl3/l3doc.dtx @@ -77,7 +77,7 @@ Do not distribute a modified version of this file. % \end{macrocode} % %<*driver|class> -\GetIdInfo$Id: l3doc.dtx 1451 2009-08-08 06:33:34Z joseph $ +\GetIdInfo$Id: l3doc.dtx 1538 2009-09-17 05:14:09Z will $ {L3 Experimental documentation class} %</driver|class> % @@ -179,7 +179,7 @@ Do not distribute a modified version of this file. % % \section{Problems \& Todo} % -% Problems at the moment: (1)~not flexible in the types of things that can be documented; (2)~very nonstandard markup (using `"|"' as a delimiter and the odd `"/ (...)"' tags; (3)~no obvious link to the "\begin{macro}" function that's used analogously in the implementation. +% Problems at the moment: (1)~not flexible in the types of things that can be documented; (2)~very nonstandard markup (using `"|"' as a delimiter and the odd `"/ (...)"' tags; (3)~no obvious link between the "\begin{function}" environment for documenting things to the "\begin{macro}" function that's used analogously in the implementation. % % The environments "function" and "macro" should probably % be renamed to something like \env{funcdoc} and \env{funcimpl}, @@ -201,8 +201,9 @@ Do not distribute a modified version of this file. % \item Something better to replace "\StopEventually"; I'm thinking two % environments \env{documentation} and \env{implementation} that can % conditionally typeset/ignore their material. -% \item Hyperlink documentation and implementation of macros (also see -% the \textsc{dtx} file of \pkg{svn-multi} v2). +% (This has been implemented but needs further consideration.) +% \item Hyperlink documentation and implementation of macros (see +% the \textsc{dtx} file of \pkg{svn-multi} v2 as an example). % \end{itemize} % % \section{Bugs} @@ -284,7 +285,7 @@ Do not distribute a modified version of this file. % \DescribeEnv{macro} % The well-used environment from \LaTeXe\ for marking up the implementation % of macros/functions remains the \env{macro} environment. -% One major change in \pkg{l3doc}: it now accepts comma-separated lists +% One change in \pkg{l3doc}: it now accepts comma-separated lists % of functions, to avoid a very large number of consecutive "\end{macro}" % statements. % \begin{verbatim} @@ -297,8 +298,8 @@ Do not distribute a modified version of this file. % % \DescribeEnv{arguments} % Within a \env{macro} environment, you may use the \env{arguments} environment -% to describe the arguments taken by the function(s). It behaves exactly -% like a list environment. +% to describe the arguments taken by the function(s). It behaves +% like a modified enumerate environment. % \begin{verbatim} % % \begin{macro}{\foo:nn,\foo:VV} % % \begin{arguments} @@ -562,6 +563,8 @@ Do not distribute a modified version of this file. % \end{environment} % % \begin{macro}{\tn} +% As \cs{cs}. Use this to mark up all \TeX\ and \LaTeXe\ commands; they +% then end up together in the index. TODO: hyperlinks in the index entries. % \begin{macrocode} \newcommand\tn[1]{ \texttt{\bslash #1} @@ -727,18 +730,18 @@ Do not distribute a modified version of this file. % \end{macro} % % \begin{macro}{\doc_showmacro_aux_ii:w} -% This macro is passed one of: +% This macro is passed arguments in the following ways: % \begin{quote} -% "\showexplmacro "^^A +% "\doc_showmacro_aux_ii:w "^^A % \makebox[\widthof{\texttt{123456}}]{\meta{name}}^^A % " ::\q_stop" \\ -% "\showexplmacro \foo ::\q_stop" \\ -% "\showexplmacro \foo: ::\q_stop" \\ -% "\showexplmacro \foo:Z ::\q_stop" \\ +% "\doc_showmacro_aux_ii:w \foo ::\q_stop" \\ +% "\doc_showmacro_aux_ii:w \foo: ::\q_stop" \\ +% "\doc_showmacro_aux_ii:w \foo:Z ::\q_stop" \\ % \end{quote} % Notice that for "\foo", "#2" and "#3" are empty,\\ -% for "\foo:", "#2" is empty,\\ -% and for both "\foo:" and "\foo:Z", "#3" is `":"' . +% for "\foo:", "#2" is empty, and "#3" is `":"'\\ +% for "\foo:Z", "#2" is `"Z"' and "#3" is `":"' . % \begin{arguments} % \item Function name \item Possible arg.\ spec. \item Possible colon % \end{arguments} @@ -768,12 +771,14 @@ Do not distribute a modified version of this file. % \begin{environment}{syntax} % Syntax block placed next to the list of functions to illustrate their use. % \begin{macrocode} -\newenvironment{syntax}{% - \minipage[b]{.7\textwidth}% +\dim_new:N \g_doc_syntax_dim +\dim_set:Nn \g_doc_syntax_dim {0.7\textwidth} +\newenvironment{syntax}{ + \minipage[b]{\g_doc_syntax_dim} \cs_set_nopar:Npn \meta@font@select{\rmfamily\itshape} % (Will: I HATE italic cmtt!) \small\ttfamily\raggedright \obeyspaces\obeylines -}{% +}{ \endminipage \hfil\break \global\@ignoretrue @@ -1052,11 +1057,11 @@ Do not distribute a modified version of this file. % % \begin{macrocode} \newenvironment{TemplateInterfaceDescription}[1] - {\subsection{The template type `#1'}% + {\subsection{The~template~type~`#1'}% \begingroup \@beginparpenalty\@M \description - \def\TemplateArgument##1##2{\item[Arg: ##1]##2\par}% + \def\TemplateArgument##1##2{\item[Arg:~##1]##2\par}% \def\TemplateSemantics{\enddescription\endgroup \subsubsection*{Semantics:}}% } @@ -1065,12 +1070,12 @@ Do not distribute a modified version of this file. % % \begin{macrocode} \newenvironment{TemplateDescription}[2] - {\subsection{The template `#2' (type #1)}% + {\subsection{The~template~`#2'~(type~#1)}% \subsubsection*{Attributes:}% \begingroup \@beginparpenalty\@M \description - \def\TemplateKey##1##2##3##4{\item[##1 (##2)]##3% + \def\TemplateKey##1##2##3##4{\item[##1~(##2)]##3% \ifx\TemplateKey##4\TemplateKey\else % \hskip0ptplus3em\penalty-500\hskip 0pt plus 1filll Default:~##4% \hfill\penalty500\hbox{}\hfill Default:~##4% @@ -1078,21 +1083,21 @@ Do not distribute a modified version of this file. \fi \par}% \def\TemplateSemantics{\enddescription\endgroup - \subsubsection*{Semantics \& Comments:}}% + \subsubsection*{Semantics~\&~Comments:}}% } {\par\bigskip} % \end{macrocode} % % \begin{macrocode} \newenvironment{InstanceDescription}[4][xxxxxxxxxxxxxxx] - {\subsubsection{The instance `#3' (template #2/#4)}% - \subsubsection*{Attribute values:}% + {\subsubsection{The~instance~`#3'~(template~#2/#4)}% + \subsubsection*{Attribute~values:}% \begingroup \@beginparpenalty\@M \def\InstanceKey##1##2{\>\textbf{##1}\>##2\\}% \def\InstanceSemantics{\endtabbing\endgroup \vskip-30pt\vskip0pt - \subsubsection*{Layout description \& Comments:}}% + \subsubsection*{Layout~description~\&~Comments:}}% \tabbing xxxx\=#1\=\kill } @@ -1340,6 +1345,8 @@ Do not distribute a modified version of this file. % Fix index (for now): % \begin{macrocode} \g@addto@macro\theindex{\MakePrivateLetters} +\cs_set:Npn \verbatimchar {&} +\cs_set:Npx \levelchar {\string#} % \end{macrocode} % % \begin{macrocode} @@ -1363,6 +1370,7 @@ Do not distribute a modified version of this file. % \begin{macro}{\doc_special_main_index:n,\doc_special_main_index:o,\hdpgindex} % Heiko's replacement to play nicely with |hypdoc|: % \begin{macrocode} + \cs_set_nopar:Npn \doc_special_main_index:n #1 { \index{ \@gobble#1 @@ -1526,7 +1534,7 @@ Do not distribute a modified version of this file. %<*docist> actual '=' quote '!' -level '>' +level '#' preamble "\n \\begin{theindex} \n \\makeatletter\\scan@allowedfalse\n" postamble diff --git a/Master/texmf-dist/source/latex/expl3/l3keys.dtx b/Master/texmf-dist/source/latex/expl3/l3keys.dtx index 2940e7a7842..e11a6907042 100644 --- a/Master/texmf-dist/source/latex/expl3/l3keys.dtx +++ b/Master/texmf-dist/source/latex/expl3/l3keys.dtx @@ -35,7 +35,7 @@ \RequirePackage{l3names} %</driver|package> %\fi -\GetIdInfo$Id: l3keys.dtx 1504 2009-09-03 20:29:00Z joseph $ +\GetIdInfo$Id: l3keys.dtx 1542 2009-09-17 07:38:53Z joseph $ {L3 Experimental key-value support} %\iffalse %<*driver> @@ -162,15 +162,15 @@ % Setting up and altering keys is carried out using one or more % properties. The properties determine how a key acts, and may require % zero, one or two argument: this is indicated by an argument specifier, -% in the same way as a standard \LaTeX3 function. If only a single -% argument is required, braces around \texttt{n} arguments can be -% omitted.\footnote{This is a general feature of key--value input -% methods.} +% in the same way as a standard \LaTeX3 function. % % -%\begin{function}{.bool:N} +%\begin{function}{ +% .bool_set:N | +% .bool_gset:N +%} % \begin{syntax} -% <key> .bool:N = <bool> +% <key> .bool_set:N = <bool> % \end{syntax} % Defines <key> to set <bool> to <value> (which must be either % \texttt{true} or \texttt{false}). @@ -185,6 +185,20 @@ %\end{function} % %\begin{function}{ +% .choice_code:n | +% .choice_code:x +%} +% \begin{syntax} +% <key> .choice_code:n = <code> +% \end{syntax} +% Stores <code> for use when |.generate_choices:n| creates one or more +% choice sub-keys of the current key. Inside <code>, +% \cs{l_keys_choice_tl} contains the name of the choice made, and +% \cs{l_keys_choice_int} is the position of the choice in the list +% given to |.generate_choices:n|. +%\end{function} +% +%\begin{function}{ % .code:n| % .code:x % } @@ -197,20 +211,6 @@ %\end{function} % %\begin{function}{ -% .code:Nn| -% .code:Nx -% } -% \begin{syntax} -% <key> .code:Nn = <number> <code> -% \end{syntax} -% Stores the <code> for execution when <key> is called. The <code> can -% include <number> parameters, which can be in the standard \TeX\ -% range 0--9. If too few parameters are given when the key is used, -% sufficient empty groups will be supplied to prevent an error -% occurring. -%\end{function} -% -%\begin{function}{ % .default:n| % .default:V| % } @@ -222,8 +222,8 @@ % a blank <value> is given: % \begin{verbatim} % \keys_define:nn { module } { -% key .code:n = Hello #1, -% key .default = World +% key .code:n = Hello #1, +% key .default:n = World % } % \keys_set:nn { module} { % key = Fred, % Prints "Hello Fred" @@ -236,42 +236,36 @@ % \end{texnote} %\end{function} % -%\begin{function}{.function:N} +%\begin{function}{ +% .dim_set:N | +% .dim_gset:N | +%} % \begin{syntax} -% <key> .function:N = <function> +% <key> .dim_set:N = <dimension> % \end{syntax} -% The input for <key> is used to define <function>, which internally -% uses \cs{cs_set:Nn}. The effect is the same as \texttt{<key> -% .code:n = \{ \cs{cs_set:Nn} <function> } |{#1}| \texttt{ \} }. -% The <function> should be an internal function, as the number of -% arguments is detected from the argument specifier. If the -% <function> is not defined, it is initialised to empty. +% Sets <key> to store the value it is given in <dimension>, +% which is created if it does not already exist. %\end{function} % -%\begin{function}{ -% .generate_choices:nn| -% .generate_choices:nx| -% } +%\begin{function}{.generate_choices:n} % \begin{syntax} -% <key> .generate_choices:nn = <comma list> <code> +% <key> .generate_choices:n = <comma list> % \end{syntax} % Makes <key> a multiple choice key, accepting the choices specified -% in <comma list>. Each choice will execute <code> if it given. Within -% <code>, the name of the current choice is available as -% \cs{l_keys_choice_tl}, and its position in the <comma list> as -% \cs{l_keys_choice_int}. Multiple choices are discussed further in -% section~\ref{sec:choice}. +% in <comma list>. Each choice will execute code which should +% previously have been defined using |.choice_code:n| or +% |.choice_code:x|. %\end{function} % %\begin{function}{ -% .initial:n| -% .initial:V -% } +% .int_set:N | +% .int_gset:N | +%} % \begin{syntax} -% <key> .initial:n = <initial> +% <key> .int_set:N = <integer> % \end{syntax} -% Sets <key> using the <initial> value given. This can only be given -% after the <key> is created. +% Sets <key> to store the value it is given in <integer>, +% which is created if it does not already exist. %\end{function} % %\begin{function}{ @@ -285,35 +279,30 @@ % one go. If <key> is given with a value, it is passed through to % the subsidiary <keys> for processing. %\end{function} -% +% %\begin{function}{ -% .set:N| -% .set_x:N +% .skip_set:N | +% .skip_gset:N | %} % \begin{syntax} -% <key> .set:N = <variable> +% <key> .skip_set:N = <skip> % \end{syntax} -% Defines <key> to store the value given in <variable>. The type and -% scope (local or global) of <variable> are determined from the -% name. The \texttt{x} version performs an expanded assignment. For -% example -% \begin{verbatim} -% \keys_define:nn { module } { -% key-one .set:N = \l_module_tmpa_tl, % Locally sets a tl var. -% key_two .set:N = \g_module_tmpa_toks % Globally sets a toks -% } -% \keys_set:nn { module } { -% key-one = Value, % \l_module_tmpa_tl contains "Value" -% key-two = Stuff % \g_module_tmpa_toks contains "Stuff" -% } -% \end{verbatim} -% Assignments are automatically global for global variables. -% -% A \cs{<variable>_set:Nn} function must exist to allow setting of the -% <variable>. An error will result if this is not the case. The -% \texttt{.set_x:N} version can only be applied to variable types which -% have a \cs{<variable>_set:Nx} function: other cases will result in an -% error. +% Sets <key> to store the value it is given in <skip>, which is +% created if it does not already exist. +%\end{function} +% +%\begin{function}{ +% .tl_set:N | +% .tl_set_x:N | +% .tl_gset:N | +% .tl_gset_x:N | +%} +% \begin{syntax} +% <key> .tl_set:N = <token list variable> +% \end{syntax} +% Sets <key> to store the value it is given in <token list variable>, +% which is created if it does not already exist. The \texttt{x} +% type properties perform an expansion as well as storing the value. %\end{function} % %\begin{function}{ @@ -369,17 +358,18 @@ % In many cases, choices execute similar code which is dependant only % on the name of the choice or the position of the choice in the % list of choices. Here, the keys can share the same code, and can -% be rapidly created using the \texttt{.generate_choices:nn} -% property: +% be rapidly created using the \texttt{.choice_code:n} and +% \texttt{.generate_choices:n} properties: %\begin{verbatim} % \keys_define:nn { module } { -% key .generate_choices:nn = { -% choice-a, choice-b, choice-c -% } { +% key .choice_code:n = { % You~gave~choice~``\l_keys_choice_tl'',~ % which~is~in~position~\l_keys_choice_int % \~in~the~list. -% } +% }, +% key .generate_choices:n = { +% choice-a, choice-b, choice-c +% } % } %\end{verbatim} % @@ -452,7 +442,7 @@ % ~~~~\Arg{false code} % \end{syntax} % Tests if <key> exists for <module>, by checking for the existence -% of the internal function \cs{keys > <module>/<key>.cmd:w}. +% of the internal function \cs{keys > <module>/<key>.cmd:n}. %\end{function} % %\begin{function}{\keys_show:nn} @@ -460,27 +450,24 @@ % "\keys_show:nn" \Arg{module} \Arg{key} % \end{syntax} % Shows the internal representation of a <key>. The function which -% executes a <key> is called \cs{keys > <module>/<key>.cmd:w}. +% executes a <key> is called \cs{keys > <module>/<key>.cmd:n}. %\end{function} % %\subsection{Internal functions} % -%\begin{function}{\keys_arguments_tidy:w} +%\begin{function}{\keys_bool_set:NN} % \begin{syntax} -% "\keys_arguments_tidy:w " <args> "\q_keys_stop" +% "\keys_bool_set:NN" <bool> <scope> % \end{syntax} -% Clears <args> from the stack: used to clean up after executing a -% key. +% Creates code to set <bool> when <key> is given, with setting using +% <scope>. %\end{function} % -%\begin{function}{ -% \keys_bool_set:N | -% \keys_bool_set_inverse:N -%} +%\begin{function}{\keys_choice_code_store:x} % \begin{syntax} -% "\keys_bool_set:N" <bool> +% "\keys_choice_code_store:x" <code> % \end{syntax} -% Creates code to set <bool> when <key> is given. +% Stores <code> for later use by \texttt{.generate_code:n}. %\end{function} % %\begin{function}{\keys_choice_make:} @@ -490,11 +477,11 @@ % Makes <key> a choice key. %\end{function} % -%\begin{function}{\keys_choices_generate:nx} +%\begin{function}{\keys_choices_generate:n} % \begin{syntax} -% "\keys_choices_generate:nx" \Arg{comma list} \Arg{code} +% "\keys_choices_generate:n" \Arg{comma list} % \end{syntax} -% Makes <comma list> choices for <key>, each using <code>. +% Makes <comma list> choices for <key>. %\end{function} % %\begin{function}{\keys_choice_find:n} @@ -505,13 +492,13 @@ %\end{function} % %\begin{function}{ -% \keys_cmd_set:nNn | -% \keys_cmd_set:nNx +% \keys_cmd_set:nn | +% \keys_cmd_set:nx %} % \begin{syntax} -% "\keys_cmd_set:nNn" \Arg{path} <num args> \Arg{code} +% "\keys_cmd_set:nn" \Arg{path} \Arg{code} % \end{syntax} -% Creates a function for <path>, taking <num args> and using <code>. +% Creates a function for <path> using <code>. %\end{function} % %\begin{function}{ @@ -564,16 +551,6 @@ %\end{function} % %\begin{function}{ -% \keys_initial_value:n | -% \keys_initial_value:V -%} -% \begin{syntax} -% "\keys_initial_value:n" \Arg{value} -% \end{syntax} -% Sets <value> as initial contents for <key>. -%\end{function} -% -%\begin{function}{ % \keys_meta_make:n| % \keys_meta_make:x %} @@ -636,21 +613,13 @@ % Sets <key> to have <requirement> concerning <value>. %\end{function} % -%\begin{function}{\keys_variable_set:NN} +%\begin{function}{\keys_variable_set:NnNN} % \begin{syntax} -% "\keys_variable_set:NN" <expansion> <var> +% "\keys_variable_set:NN" <var> <type> <scope> <expansion> % \end{syntax} -% Sets <key> to assign <value> to <variable> -%\end{function} -% -%\begin{function}{ -% \keys_variable_get_scope:N / (EXP) | -% \keys_variable_get_type:N / (EXP) -%} -% \begin{syntax} -% "\keys_variable_get_scope:N" <var> -% \end{syntax} -% Returns the scope (\texttt{g} or blank) or the type of <var>. +% Sets <key> to assign <value> to <variable>. The <scope> (blank +% for local, \texttt{g} for global) and <type> (\texttt{tl}, +% \texttt{int}, etc.) are given explicitly. %\end{function} % %\subsection{Variables and constants} @@ -668,6 +637,10 @@ %} % Marker text containers. %\end{variable} +% +%\begin{variable}{\l_keys_choice_code_tl} +% Used to transfer code from storage when making multiple choices. +%\end{variable} % %\begin{variable}{ % \l_keys_module_tl| @@ -691,10 +664,6 @@ %\begin{variable}{\l_keys_value_toks} % Holds the currently supplied value. %\end{variable} -% -%\begin{variable}{\q_keys_stop} -% A quark for delimiting arguments. -%\end{variable} % %\end{documentation} % @@ -742,6 +711,13 @@ %\end{macro} %\end{macro} % +%\begin{macro}{\l_keys_choice_code_tl} +% When creating multiple choices, the code is stored here. +% \begin{macrocode} +\tl_new:N \l_keys_choice_code_tl +% \end{macrocode} +%\end{macro} +% %\begin{macro}{\l_keys_key_tl} %\begin{macro}{\l_keys_path_tl} %\begin{macro}{\l_keys_property_tl} @@ -787,51 +763,21 @@ % \end{macrocode} %\end{macro} % -%\begin{macro}{\q_keys_stop} -% A quark for delimiting keys: no one else should use it! -% \begin{macrocode} -\quark_new:N \q_keys_stop -% \end{macrocode} -%\end{macro} -% %\subsubsection{Internal functions} % -%\begin{macro}{\keys_arguments_tidy:w} -% So that nothing runs away, a safety precaution is taken in the code. -% \begin{macrocode} -\cs_new:Npn \keys_arguments_tidy:w #1 \q_keys_stop { } -% \end{macrocode} -%\end{macro} -% -%\begin{macro}{\keys_bool_set:N} -%\begin{macro}{\keys_bool_set_inverse:N} -%\begin{macro}[aux]{\keys_bool_set_aux:N} +%\begin{macro}{\keys_bool_set:NN} % Boolean keys are really just choices, but all done by hand. % \begin{macrocode} -\cs_new_nopar:Nn \keys_bool_set:N { - \keys_cmd_set:nNx { \l_keys_path_tl / true } 1 { - \exp_not:c { bool_ \keys_variable_get_scope:N #1 set_true:N } +\cs_new_nopar:Nn \keys_bool_set:NN { + \keys_cmd_set:nx { \l_keys_path_tl / true } { + \exp_not:c { bool_ #2 set_true:N } \exp_not:N #1 } - \keys_cmd_set:nNx { \l_keys_path_tl / false } 1 { + \keys_cmd_set:nx { \l_keys_path_tl / false } { \exp_not:N \use:c - { bool_ \keys_variable_get_scope:N #1 set_false:N } + { bool_ #2 set_false:N } \exp_not:N #1 } - \keys_bool_set_aux:N #1 -} -\cs_new_nopar:Nn \keys_bool_set_inverse:N { - \keys_cmd_set:nNx { \l_keys_path_tl / true } 1 { - \exp_not:c { bool_ \keys_variable_get_scope:N #1 set_false:N } - \exp_not:N #1 - } - \keys_cmd_set:nNx { \l_keys_path_tl / false } 1 { - \exp_not:c { bool_ \keys_variable_get_scope:N #1 set_true:N } - \exp_not:N #1 - } - \keys_bool_set_aux:N #1 -} -\cs_new_nopar:Nn \keys_bool_set_aux:N { \keys_choice_make: \cs_if_exist:NF #1 { \bool_new:N #1 @@ -840,7 +786,15 @@ } % \end{macrocode} %\end{macro} -%\end{macro} +% +%\begin{macro}{\keys_choice_code_store:x} +% The code for making multiple choices is stored in a token list as there should +% not be any |#| tokens. +% \begin{macrocode} +\cs_new:Nn \keys_choice_code_store:x { + \tl_set:cx { \c_keys_root_tl \l_keys_path_tl .choice_code_tl } {#1} +} +% \end{macrocode} %\end{macro} % %\begin{macro}{\keys_choice_find:n} @@ -861,10 +815,10 @@ % unknown key. % \begin{macrocode} \cs_new_nopar:Nn \keys_choice_make: { - \keys_cmd_set:nNn { \l_keys_path_tl } 1 { + \keys_cmd_set:nn { \l_keys_path_tl } { \keys_choice_find:n {##1} } - \keys_cmd_set:nNn { \l_keys_path_tl / unknown } 1 { + \keys_cmd_set:nn { \l_keys_path_tl / unknown } { \msg_kernel_error:nxx { key-choice-unknown } { \l_keys_path_tl } {##1} } @@ -872,50 +826,57 @@ % \end{macrocode} %\end{macro} % -%\begin{macro}{\keys_choices_generate:nx} +%\begin{macro}{\keys_choices_generate:n} %\begin{macro}[aux]{\keys_choices_generate_aux:n} % Creating multiple-choices means setting up the ``indicator'' code, % then applying whatever the user wanted. % \begin{macrocode} -\cs_new:Nn \keys_choices_generate:nx { +\cs_new:Nn \keys_choices_generate:n { \keys_choice_make: \int_zero:N \l_keys_choice_int - \cs_set_nopar:Nn \keys_choices_generate_aux:n { - \int_incr:N \l_keys_choice_int - \keys_cmd_set:nNx { \l_keys_path_tl / ##1 } 1 { - \exp_not:n { \tl_set:Nn \l_keys_choice_tl } {##1} - \exp_not:n { \int_set:Nn \l_keys_choice_int } - { \int_use:N \l_keys_choice_int } - #2 + \cs_if_exist:cTF { + \c_keys_root_tl \l_keys_path_tl .choice_code_tl + } { + \tl_set:Nv \l_keys_choice_code_tl { + \c_keys_root_tl \l_keys_path_tl .choice_code_tl } + }{ + \tl_clear:N \l_keys_choice_code_tl } \clist_map_function:nN {#1} \keys_choices_generate_aux:n } -\cs_new_nopar:Nn \keys_choices_generate_aux:n { } +\cs_new_nopar:Nn \keys_choices_generate_aux:n { + \int_incr:N \l_keys_choice_int + \keys_cmd_set:nx { \l_keys_path_tl / #1 } { + \exp_not:n { \tl_set:Nn \l_keys_choice_tl } {#1} + \exp_not:n { \int_set:Nn \l_keys_choice_int } + { \int_use:N \l_keys_choice_int } + \exp_not:V \l_keys_choice_code_tl + } +} % \end{macrocode} %\end{macro} %\end{macro} % -%\begin{macro}{\keys_cmd_set:nNn} -%\begin{macro}{\keys_cmd_set:nNx} -%\begin{macro}[aux]{\keys_cmd_set_aux:nN} +%\begin{macro}{\keys_cmd_set:nn} +%\begin{macro}{\keys_cmd_set:nx} +%\begin{macro}[aux]{\keys_cmd_set_aux:n} % Creating a new command means setting properties and then creating % a function with the correct number of arguments. % \begin{macrocode} -\cs_new:Nn \keys_cmd_set:nNn { - \keys_cmd_set_aux:nN {#1} #2 - \cs_generate_from_arg_count:cNnn { \c_keys_root_tl #1 .cmd:w } - \cs_set:Npn #2 { #3 \keys_arguments_tidy:w } +\cs_new:Nn \keys_cmd_set:nn { + \keys_cmd_set_aux:n {#1} + \cs_generate_from_arg_count:cNnn { \c_keys_root_tl #1 .cmd:n } + \cs_set:Npn 1 {#2} } -\cs_new:Nn \keys_cmd_set:nNx { - \keys_cmd_set_aux:nN {#1} #2 - \cs_generate_from_arg_count:cNnn { \c_keys_root_tl #1 .cmd:w } - \cs_set:Npx #2 { #3 \exp_not:N \keys_arguments_tidy:w } +\cs_new:Nn \keys_cmd_set:nx { + \keys_cmd_set_aux:n {#1} + \cs_generate_from_arg_count:cNnn { \c_keys_root_tl #1 .cmd:n } + \cs_set:Npx 1 {#2} } -\cs_new_nopar:Nn \keys_cmd_set_aux:nN { +\cs_new_nopar:Nn \keys_cmd_set_aux:n { \keys_property_undefine:n { #1 .default_tl } - \num_set:cn { \c_keys_root_tl #1 .args_num } {#2} - \tl_set:cn { \c_keys_root_tl #1 .req_tl } { } + \tl_set:cn { \c_keys_root_tl #1 .req_tl } { } } % \end{macrocode} %\end{macro} @@ -998,20 +959,13 @@ \exp_args:Nc \cs_get_arg_count_from_signature:N { \l_keys_property_tl } = \c_zero } { - \keys_tmp:w \q_keys_stop + \keys_tmp:w }{ \msg_kernel_error:nx { key-property-value-required } { \l_keys_property_tl } } }{ - \intexpr_compare:nTF { - \exp_args:Nc \cs_get_arg_count_from_signature:N - { \l_keys_property_tl } = \c_one - } { - \keys_tmp:w {#1} \q_keys_stop - }{ - \keys_tmp:w #1 { } { } { } { } { } { } { } { } { } \q_keys_stop - } + \keys_tmp:w {#1} } } % \end{macrocode} @@ -1043,16 +997,9 @@ % can clean up the spare groups at the end of executing the key. % \begin{macrocode} \cs_new_nopar:Nn \keys_execute_aux:nn { - \cs_set_eq:Nc \keys_tmp:w { \c_keys_root_tl #1 .cmd:w } + \cs_set_eq:Nc \keys_tmp:w { \c_keys_root_tl #1 .cmd:n } \cs_if_exist:NTF \keys_tmp:w { - \intexpr_compare:nTF { - \num_use:c { \c_keys_root_tl #1 .args_num } = \c_one - } { - \exp_args:NV \keys_tmp:w \l_keys_value_toks \q_keys_stop - }{ - \exp_after:wN \keys_tmp:w \toks_use:N \l_keys_value_toks - { } { } { } { } { } { } { } { } { } \q_keys_stop - } + \exp_args:NV \keys_tmp:w \l_keys_value_toks }{ #2 } @@ -1064,10 +1011,10 @@ % %\begin{macro}[TF]{\keys_if_exist:nn} % A check for the existance of a key. This works by looking for the -% command function for the key (which ends \texttt{.cmd:w}). +% command function for the key (which ends \texttt{.cmd:n}). % \begin{macrocode} \prg_set_conditional:Nnn \keys_if_exist:nn {TF,T,F} { - \cs_if_exist:cTF { \c_keys_root_tl #1 / #2 .cmd:w } { + \cs_if_exist:cTF { \c_keys_root_tl #1 / #2 .cmd:n } { \prg_return_true: }{ \prg_return_false: @@ -1088,28 +1035,12 @@ % \end{macrocode} %\end{macro} % -%\begin{macro}{\keys_initial_value:n} -%\begin{macro}{\keys_initial_value:V} -% Pretty easy to set initial values. -% \begin{macrocode} -\cs_new:Nn \keys_initial_value:n { - \toks_set:Nn \l_keys_value_toks {#1} - \keys_execute_aux:nn { \l_keys_path_tl } { - \msg_kernel_error:nx { key-initial-without-code } - { \l_keys_path_tl } - } -} -\cs_generate_variant:Nn \keys_initial_value:n { V } -% \end{macrocode} -%\end{macro} -%\end{macro} -% %\begin{macro}{\keys_meta_make:n} %\begin{macro}{\keys_meta_make:x} % To create a met-key, simply set up to pass data through. % \begin{macrocode} \cs_new_nopar:Nn \keys_meta_make:n { - \keys_cmd_set:nNx { \l_keys_path_tl } 1 { + \keys_cmd_set:nx { \l_keys_path_tl } { \exp_not:N \keys_set:nn { \l_keys_module_tl } {#1} } } @@ -1156,8 +1087,7 @@ % function. % \begin{macrocode} \cs_new_nopar:Nn \keys_property_new:nn { - \cs_new:cn { \c_keys_properties_root_tl #1 } - { #2 \keys_arguments_tidy:w } + \cs_new:cn { \c_keys_properties_root_tl #1 } {#2} } % \end{macrocode} %\end{macro} @@ -1252,7 +1182,7 @@ % Showing a key is just a question of using the correct name. % \begin{macrocode} \cs_new_nopar:Nn \keys_show:nn { - \cs_show:c { \c_keys_root_tl #1 / \tl_to_str:n {#2} .cmd:w } + \cs_show:c { \c_keys_root_tl #1 / \tl_to_str:n {#2} .cmd:n } } % \end{macrocode} %\end{macro} @@ -1292,77 +1222,16 @@ % \end{macrocode} %\end{macro} % -%\begin{macro}{\keys_variable_get_scope:N} -%\begin{macro}[aux]{\keys_variable_get_scope_aux:w} -%\begin{macro}{\keys_variable_get_type:N} -%\begin{macro}[aux]{\keys_variable_get_type:w} -% Expandable functions to find the type of a variable, and to -% return \texttt{g} if the variable is global. The trick for -% \cs{keys_variable_get_scope:N} is the same as that in -% \cs{cs_split_function:NN}, but it can be simplified as the -% requirements here are less complex. -% \begin{macrocode} -\group_begin: - \char_set_lccode:nn {`\&} {`\g} - \char_make_other:N \& -\tl_to_lowercase:n { - \group_end: - \cs_new_nopar:Nn \keys_variable_get_scope:N { - \exp_last_unbraced:Nf \keys_variable_get_scope_aux:w - { \cs_to_str:N #1 \exp_stop_f: \q_nil } - } - \cs_new_nopar:Npn \keys_variable_get_scope_aux:w #1#2 \q_nil { - \token_if_eq_meaning:NNT & #1 {g} - } -} -\group_begin: - \char_set_lccode:nn {`\&} {`\_} - \char_make_other:N \& -\tl_to_lowercase:n { - \group_end: - \cs_new_nopar:Nn \keys_variable_get_type:N { - \exp_after:wN \keys_variable_get_type_aux:w - \token_to_str:N #1 & a \q_nil - } - \cs_new_nopar:Npn \keys_variable_get_type_aux:w #1 & #2#3 \q_nil { - \token_if_eq_meaning:NNTF a #2 { - #1 - }{ - \keys_variable_get_type_aux:w #2#3 \q_nil - } - } -} -% \end{macrocode} -%\end{macro} -%\end{macro} -%\end{macro} -%\end{macro} -% -%\begin{macro}{\keys_variable_set:NN} -% To set a variable, there is first a check so that it must exist. -% The setting function is then created by recovering the type and -% scope from the variable name. +%\begin{macro}{\keys_variable_set:NnNN} +% Setting a variable takes the type and scope separately so that +% it is easy to make a new variable if needed. % \begin{macrocode} -\cs_new_nopar:Nn \keys_variable_set:NN { - \cs_if_exist:cF { - \keys_variable_get_type:N #2 _ - \keys_variable_get_scope:N #2 set:N #1 - } { - \msg_kernel_error:nxx { key-no-set-function } { - \exp_not:c { - \keys_variable_get_type:N #2 _ - \keys_variable_get_scope:N #2 set:N #1 - } - } {#2} - } - \cs_if_exist:NF #2 { - \use:c { \keys_variable_get_type:N #2 _new:N } #2 +\cs_new_nopar:Nn \keys_variable_set:NnNN { + \cs_if_exist:NF #1 { + \use:c { #2 _new:N } #1 } - \keys_cmd_set:nNx { \l_keys_path_tl } 1 { - \exp_not:c { - \keys_variable_get_type:N #2 _ - \keys_variable_get_scope:N #2 set:N #1 - } \exp_not:N #2 {##1} + \keys_cmd_set:nx { \l_keys_path_tl } { + \exp_not:c { #2 _ #3 set:N #4 } \exp_not:N #1 {##1} } } % \end{macrocode} @@ -1370,18 +1239,23 @@ % %\subsubsection{Properties} % -%\begin{macro}{.bool:N} +%\begin{macro}{.bool_set:N} +%\begin{macro}{.bool_gset:N} % One function for this. % \begin{macrocode} -\keys_property_new:nn { .bool:N } { - \keys_bool_set:N #1 +\keys_property_new:nn { .bool_set:N } { + \keys_bool_set:NN #1 { } +} +\keys_property_new:nn { .bool_gset:N } { + \keys_bool_set:NN #1 n } % \end{macrocode} %\end{macro} +%\end{macro} % %\begin{macro}{.choice:} % Making a choice is handled internally, as it is also needed by -% \texttt{.generate_choices:nn}. +% \texttt{.generate_choices:n}. % \begin{macrocode} \keys_property_new:nn { .choice: } { \keys_choice_make: @@ -1389,30 +1263,35 @@ % \end{macrocode} %\end{macro} % +%\begin{macro}{.choice_code:n} +%\begin{macro}{.choice_code:x} +% Storing the code for choices, using \cs{exp_not:n} to avoid needing +% two internal functions. +% \begin{macrocode} +\keys_property_new:nn { .choice_code:n } { + \keys_choice_code_store:x { \exp_not:n {#1} } +} +\keys_property_new:nn { .choice_code:x } { + \keys_choice_code_store:x {#1} +} +% \end{macrocode} +%\end{macro} +%\end{macro} +% %\begin{macro}{.code:n} %\begin{macro}{.code:x} -%\begin{macro}{.code:Nn} -%\begin{macro}{.code:Nx} % Creating code is simply a case of passing through to the underlying % \texttt{set} function. % \begin{macrocode} \keys_property_new:nn { .code:n } { - \keys_cmd_set:nNn { \l_keys_path_tl } 1 {#1} -} -\keys_property_new:nn { .code:Nn } { - \keys_cmd_set:nNn { \l_keys_path_tl } #1 {#2} + \keys_cmd_set:nn { \l_keys_path_tl } {#1} } \keys_property_new:nn { .code:x } { - \keys_cmd_set:nNx { \l_keys_path_tl } 1 {#1} -} -\keys_property_new:nn { .code:Nx } { - \keys_cmd_set:nNx { \l_keys_path_tl } #1 {#2} + \keys_cmd_set:nx { \l_keys_path_tl } {#1} } % \end{macrocode} %\end{macro} %\end{macro} -%\end{macro} -%\end{macro} % %\begin{macro}{.default:n} %\begin{macro}{.default:V} @@ -1428,45 +1307,38 @@ %\end{macro} %\end{macro} % -%\begin{macro}{.function:N} -% Creating functions is pretty easy, so is done without an extra -% internal function. There is a check to ensure that the function is -% defined. +%\begin{macro}{.dim_set:N} +%\begin{macro}{.dim_gset:N} +% Setting a variable is very easy: just pass the data along. % \begin{macrocode} -\keys_property_new:nn { .function:N } { - \keys_cmd_set:nNn { \l_keys_path_tl } 1 { - \cs_set:Nn #1 {##1} - } - \cs_if_free:NT #1 { - \cs_set:Nn #1 { } - } +\keys_property_new:nn { .dim_set:N } { + \keys_variable_set:NnNN #1 { dim } { } n +} +\keys_property_new:nn { .dim_gset:N } { + \keys_variable_set:NnNN #1 { dim } g n } % \end{macrocode} %\end{macro} +%\end{macro} % -%\begin{macro}{.generate_choices:nn} -%\begin{macro}{.generate_choices:nx} -% Making choices is expansion-dependent. +%\begin{macro}{.generate_choices:n} +% Making choices is easy. % \begin{macrocode} -\keys_property_new:nn { .generate_choices:nn } { - \keys_choices_generate:nx {#1} { \exp_not:n {#2} } -} -\keys_property_new:nn { .generate_choices:nx } { - \keys_choices_generate:nx {#1} {#2} +\keys_property_new:nn { .generate_choices:n } { + \keys_choices_generate:n {#1} } % \end{macrocode} %\end{macro} -%\end{macro} % -%\begin{macro}{.initial:n} -%\begin{macro}{.initial:V} -% Sending things off as usual. +%\begin{macro}{.int_set:N} +%\begin{macro}{.int_gset:N} +% Setting a variable is very easy: just pass the data along. % \begin{macrocode} -\keys_property_new:nn { .initial:n } { - \keys_initial_value:n {#1} +\keys_property_new:nn { .int_set:N } { + \keys_variable_set:NnNN #1 { int } { } n } -\keys_property_new:nn { .initial:V } { - \keys_initial_value:V #1 +\keys_property_new:nn { .int_gset:N } { + \keys_variable_set:NnNN #1 { int } g n } % \end{macrocode} %\end{macro} @@ -1486,19 +1358,43 @@ %\end{macro} %\end{macro} % -%\begin{macro}{.set:N} -%\begin{macro}{.set_x:N} +%\begin{macro}{.skip_set:N} +%\begin{macro}{.skip_gset:N} +% Setting a variable is very easy: just pass the data along. +% \begin{macrocode} +\keys_property_new:nn { .skip_set:N } { + \keys_variable_set:NnNN #1 { skip } { } n +} +\keys_property_new:nn { .skip_gset:N } { + \keys_variable_set:NnNN #1 { skip } g n +} +% \end{macrocode} +%\end{macro} +%\end{macro} +% +%\begin{macro}{.tl_set:N} +%\begin{macro}{.tl_set_x:N} +%\begin{macro}{.tl_gset:N} +%\begin{macro}{.tl_gset_x:N} % Setting a variable is very easy: just pass the data along. % \begin{macrocode} -\keys_property_new:nn { .set:N } { - \keys_variable_set:NN n #1 +\keys_property_new:nn { .tl_set:N } { + \keys_variable_set:NnNN #1 { tl } { } n } -\keys_property_new:nn { .set_x:N } { - \keys_variable_set:NN x #1 +\keys_property_new:nn { .tl_set_x:N } { + \keys_variable_set:NnNN #1 { tl } { } x +} +\keys_property_new:nn { .tl_gset:N } { + \keys_variable_set:NnNN #1 { tl } g n +} +\keys_property_new:nn { .tl_gset_x:N } { + \keys_variable_set:NnNN #1 { tl } g x } % \end{macrocode} %\end{macro} %\end{macro} +%\end{macro} +%\end{macro} % %\begin{macro}{.value_forbidden:} %\begin{macro}{.value_required:} diff --git a/Master/texmf-dist/source/latex/expl3/l3prg.dtx b/Master/texmf-dist/source/latex/expl3/l3prg.dtx index 295016f5acd..d2b34c96024 100644 --- a/Master/texmf-dist/source/latex/expl3/l3prg.dtx +++ b/Master/texmf-dist/source/latex/expl3/l3prg.dtx @@ -36,7 +36,7 @@ \RequirePackage{l3names} %</driver|package> %\fi -\GetIdInfo$Id: l3prg.dtx 1451 2009-08-08 06:33:34Z joseph $ +\GetIdInfo$Id: l3prg.dtx 1541 2009-09-17 07:31:55Z joseph $ {L3 Experimental control structures} %\iffalse %<*driver> @@ -601,6 +601,23 @@ % \end{quote} % % \end{function} +% +% \subsection{Variable type and scope} +% +%\begin{function}{\prg_variable_get_scope:N / (EXP) } +% \begin{syntax} +% "\prg_variable_get_scope:N" <variable> +% \end{syntax} +% Returns the scope (\texttt{g} for global, blank otherwise) for the +% <variable>. +%\end{function} +% +%\begin{function}{\prg_variable_get_type:N / (EXP) } +% \begin{syntax} +% "\prg_variable_get_type:N" <variable> +% \end{syntax} +% Returns the type of <variable> (\texttt{tl}, \texttt{int}, etc.) +%\end{function} % % \end{documentation} % @@ -1681,6 +1698,55 @@ % \end{macrocode} % \end{macro} % \end{macro} +% +%\subsection{Variable type and scope} +% +% +%\begin{macro}{\prg_variable_get_scope:N} +%\begin{macro}[aux]{\prg_variable_get_scope_aux:w} +%\begin{macro}{\prg_variable_get_type:N} +%\begin{macro}[aux]{\prg_variable_get_type:w} +% Expandable functions to find the type of a variable, and to +% return \texttt{g} if the variable is global. The trick for +% \cs{prg_variable_get_scope:N} is the same as that in +% \cs{cs_split_function:NN}, but it can be simplified as the +% requirements here are less complex. +% \begin{macrocode} +\group_begin: + \tex_lccode:D `\& = `\g \tex_relax:D + \tex_catcode:D \& = \c_twelve \tex_relax:D +\tl_to_lowercase:n { + \group_end: + \cs_new_nopar:Nn \prg_variable_get_scope:N { + \exp_last_unbraced:Nf \prg_variable_get_scope_aux:w + { \cs_to_str:N #1 \exp_stop_f: \q_nil } + } + \cs_new_nopar:Npn \prg_variable_get_scope_aux:w #1#2 \q_nil { + \token_if_eq_meaning:NNT & #1 {g} + } +} +\group_begin: + \tex_lccode:D `\& = `\_ \tex_relax:D + \tex_catcode:D \& = \c_twelve \tex_relax:D +\tl_to_lowercase:n { + \group_end: + \cs_new_nopar:Nn \prg_variable_get_type:N { + \exp_after:wN \p;rg_variable_get_type_aux:w + \token_to_str:N #1 & a \q_nil + } + \cs_new_nopar:Npn \prg_variable_get_type_aux:w #1 & #2#3 \q_nil { + \token_if_eq_meaning:NNTF a #2 { + #1 + }{ + \prg_variable_get_type_aux:w #2#3 \q_nil + } + } +} +% \end{macrocode} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} % % That's it (for now). % \begin{macrocode} diff --git a/Master/texmf-dist/source/latex/expl3/l3prop.dtx b/Master/texmf-dist/source/latex/expl3/l3prop.dtx index 86ac5508276..73958e5fd56 100644 --- a/Master/texmf-dist/source/latex/expl3/l3prop.dtx +++ b/Master/texmf-dist/source/latex/expl3/l3prop.dtx @@ -36,7 +36,7 @@ \RequirePackage{l3names} %</driver|package> %\fi -\GetIdInfo$Id: l3prop.dtx 1506 2009-09-04 21:52:12Z joseph $ +\GetIdInfo$Id: l3prop.dtx 1536 2009-09-16 07:23:04Z joseph $ {L3 Experimental Property Lists} %\iffalse %<*driver> @@ -133,9 +133,13 @@ % % \begin{function}{% % \prop_get:NnN | +% \prop_get:NVN | % \prop_get:cnN | +% \prop_get:cVN | % \prop_gget:NnN | +% \prop_gget:NVN | % \prop_gget:cnN | +% \prop_gget:cVN | % } % \begin{syntax} % "\prop_get:NnN" <\proplist> \Arg{\propkey} <tl var.> @@ -173,7 +177,9 @@ % % \begin{function}{% % \prop_del:Nn | +% \prop_del:NV | % \prop_gdel:Nn | +% \prop_gdel:NV | % } % \begin{syntax} % "\prop_del:Nn" <\proplist> \Arg{\propkey} @@ -487,7 +493,9 @@ % \end{macro} % % \begin{macro}{\prop_get:NnN} +% \begin{macro}{\prop_get:NVN} % \begin{macro}{\prop_get:cnN} +% \begin{macro}{\prop_get:cVN} % \begin{macro}{\prop_get_aux:w} % |\prop_get:NnN |\meta{\proplist}\meta{\propkey}\meta{tl var.}~defines % \meta{tl var.}~to be the value associated with \meta{\propkey} in \meta{\proplist}, @@ -500,14 +508,18 @@ % \end{macrocode} % % \begin{macrocode} -\cs_generate_variant:Nn \prop_get:NnN {cnN} +\cs_generate_variant:Nn \prop_get:NnN { NVN, cnN, cVN } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} +% \end{macro} +% \end{macro} % % \begin{macro}{\prop_gget:NnN} -% \begin{macro}{\prop_gget:cnN} +% \begin{macro}{\prop_gget:NVN} +% \begin{macro}{\prop_gget:NnN} +% \begin{macro}{\prop_gget:NVN} % \begin{macro}{\prop_gget_aux:w} % The global version of the previous function. % \begin{macrocode} @@ -517,11 +529,13 @@ % \end{macrocode} % % \begin{macrocode} -\cs_generate_variant:Nn \prop_gget:NnN {cnN} +\cs_generate_variant:Nn \prop_gget:NnN { NVN, cnN, cVN } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} +% \end{macro} +% \end{macro} % % \begin{macro}{\prop_get_gdel:NnN} % \begin{macro}{\prop_get_del_aux:w} @@ -606,6 +620,8 @@ % \end{macro} % % \begin{macro}{\prop_del:Nn} +% \begin{macro}{\prop_del:NV} +% \begin{macro}{\prop_gdel:NV} % \begin{macro}{\prop_gdel:Nn} % \begin{macro}{\prop_del_aux:w} % |\prop_del:Nn |\meta{\proplist}\meta{\propkey} deletes the entry for @@ -622,10 +638,15 @@ \prop_tmp:w #5 } } +\cs_generate_variant:Nn \prop_del:Nn { NV } +\cs_generate_variant:Nn \prop_gdel:Nn { NV } +% % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} +% \end{macro} +% \end{macro} % % % \begin{macro}{\prop_gput_if_new:Nnn} |