diff options
Diffstat (limited to 'Master/texmf-dist/source/latex/expl3/l3keyval.dtx')
-rw-r--r-- | Master/texmf-dist/source/latex/expl3/l3keyval.dtx | 422 |
1 files changed, 277 insertions, 145 deletions
diff --git a/Master/texmf-dist/source/latex/expl3/l3keyval.dtx b/Master/texmf-dist/source/latex/expl3/l3keyval.dtx index 79ea988459a..086827188f4 100644 --- a/Master/texmf-dist/source/latex/expl3/l3keyval.dtx +++ b/Master/texmf-dist/source/latex/expl3/l3keyval.dtx @@ -35,7 +35,7 @@ \RequirePackage{l3names} %</driver|package> %\fi -\GetIdInfo$Id: l3keyval.dtx 1424 2009-07-13 06:05:25Z joseph $ +\GetIdInfo$Id: l3keyval.dtx 1872 2010-03-24 07:53:45Z mittelba $ {L3 Experimental keyval processing} %\iffalse %<*driver> @@ -60,116 +60,199 @@ % \maketitle % % \begin{documentation} +% +% A key--value list is input of the form +%\begin{verbatim} +% KeyOne = ValueOne , +% KeyTwo = ValueTwo , +% KeyThree , +%\end{verbatim} +% where each key--value pair is separated by a comma from the rest of +% the list, and each key--value pair does not necessarily contain an +% equals sign or a value! Processing this type of input correctly +% requires a number of careful steps, to correctly account for +% braces, spaces and the category codes of separators. +% +% This module provides the low-level machinery for processing arbitrary +% key--value lists. The \pkg{l3keys} module provides a higher-level +% interface for managing run-time settings using key--value input, +% while other parts of \LaTeX3 also use key--value input based on +% \pkg{l3keyval} (for example the \pkg{xtemplate} module). +% +%\section{Features of \pkg{l3keyval}} +% +% As \pkg{l3keyval} is a low-level module, its functions are +% restricted to converting a \meta{keyval list} into keys and values +% for further processing. Each key and value (or key alone) +% has to be processed further by a function provided when +% \pkg{l3keyval} is called. Typically, this will be \emph{via} +% one of the \cs{KV_process\ldots} functions: +%\begin{verbatim} +% \KV_process_space_removal_sanitize:NNn +% \my_processor_function_one:n +% \my_processor_function_two:nn +% { <keyval list> } +%\end{verbatim} +% The two processor functions here handle the cases where there is +% only a key, and where there is both a key and value, respectively. +% +% \pkg{l3keyval} parses key--value lists in a manner that does not +% double "#" tokens or expand any input. The module has processor +% functions which will sanitize the category codes of \texttt{=} +% and \texttt{,} tokens (for use in the document body) as well +% as faster versions which do not do this (for use inside code +% blocks). Spaces can be removed from each end of the key and +% value (again for the document body), again with faster code +% to be used where this is not necessary. Values which are wrapped +% in braces will have exactly one set removed, meaning that +%\begin{verbatim} +% key = {value here}, +%\end{verbatim} +% and +%\begin{verbatim} +% key = value here, +%\end{verbatim} +% are treated as identical (assuming that space removal is in force). +% \pkg{l3keyval} +% +%\section{Functions for keyval processing} % -% This module only provides functions for extracting keys and values -% from a list. How this information is used is up to the programmer. -% The \pkg{l3keys} module provides a higher-level interface for -% managing run-time key--value input. -% -% A \meta{keyval list} is a list consisting of -% \begin{verbatim} -% key 1 = value 1 , -% key 2 , -% key 3 = value 3 , -% \end{verbatim} +% The \pkg{l3keyval} module should be accessed \emph{via} a small +% set of external functions. These correctly set up the module +% internals for use by other parts of \LaTeX3. % -% The function names for retrieving the keys and values are long but -% explain what they do. All these functions start with the name -% |\KV_parse_|. If a value is surrounded by braces, one level (and -% only one) is removed from the value. This is useful if you need to -% input a value which contains |=| or |,|. There are two primary -% actions we can take on a \meta{keyval list}. -% \begin{itemize} -% \item A \meta{keyval list} can be sanitized so that top level active -% commas or equal signs are converted into catcode 12. When -% declaring templates in the preamble one can probably safely assume -% that there are no active commas or equals; these things should -% only be active in the document. The name for this is either -% |no_sanitize| or |sanitize|. -% \item Spaces on either side of a key or value can be trimmed. When -% using the \LaTeX3 programming interface, spaces are automatically -% ignored so there it would be a waste of time to search for extra -% spaces since there would be none. At the document level however, -% spaces must be removed. The name for this is either -% |no_space_removal| or |space_removal|. Note that when -% |space_removal| is called you get an additional option where you -% can decide if one level of braces should be stripped from the key -% and/or value; see the description of the boolean -% |\l_KV_remove_one_level_of_braces_bool| for details. -% \end{itemize} -% -% During the parsing process, keys or values are not expanded and no -% |#|s are doubled. When the parsing process is over, the keys and -% values are executed in the form -% \begin{quote} -% "\KV_key_value_elt:nn{key 1}{value 1}" \\ -% "\KV_key_no_value_elt:n{key 2}" \\ -% "\KV_key_value_elt:nn{key 3}{value 3}" -% \end{quote} -% It is up to the programmer to provide a suitable definition of these -% two functions before starting the parsing process. -% -% -% \section{Functions} +% In all cases, two functions have to be supplied by the programmer +% to apply to the items from the <keyval list> after \pkg{l3keyval} +% has separated out the entries. The first function should take +% one argument, and will receive the names of keys for which no +% value was supplied. The second function should take two arguments: +% a key name and the associated value. +% +%\begin{function}{\KV_process_space_removal_sanitize:NNn} +% \begin{syntax} +% "\KV_process_space_removal_sanitize:NNn" +% ~~~~<function 1> <function 2> \Arg{keyval list} +% \end{syntax} +% Parses the <keyval list> splitting it into keys and associated +% values. Spaces are removed from the ends of both the key and +% value by this function, and the category codes of non-braced +% \texttt{=} and \texttt{,} tokens are normalised so that +% parsing is `category code safe'. After parsing is completed, +% <function 1> is used to process keys without values and +% <function 2> deals with keys which have associated values. +%\end{function} +% +%\begin{function}{\KV_process_space_removal_no_sanitize:NNn} +% \begin{syntax} +% "\KV_process_space_removal_no_sanitize:NNn" +% ~~~~<function 1> <function 2> \Arg{keyval list} +% \end{syntax} +% Parses the <keyval list> splitting it into keys and associated +% values. Spaces are removed from the ends of both the key and +% value by this function, but category codes are not normalised. +% After parsing is completed, <function 1> is used to process keys +% without values and <function 2> deals with keys which have +% associated values. +%\end{function} +% +%\begin{function}{\KV_process_no_space_removal_no_sanitize:NNn} +% \begin{syntax} +% "\KV_process_no_space_removal_no_sanitize:NNn" +% ~~~~<function 1> <function 2> \Arg{keyval list} +% \end{syntax} +% Parses the <keyval list> splitting it into keys and associated +% values. Spaces are \emph{not} removed from the ends of +% the key and value, and category codes are \emph{not} normalised. +% After parsing is completed, <function 1> is used to process keys +% without values and <function 2> deals with keys which have +% associated values. +%\end{function} +% +% \begin{variable}{\l_KV_remove_one_level_of_braces_bool} +% This boolean controls whether or not one level of braces is +% stripped from the key and value. The default value for this +% boolean is \texttt{true} so that exactly one level of braces is +% stripped. For certain applications it is desirable to keep the +% braces in which case the programmer just has to set the boolean +% false temporarily. Only applicable when spaces are being +% removed. +% \end{variable} % -% \begin{function}{ -% \KV_parse_no_space_removal_no_sanitize:n | -% } +%\section{Internal functions} +% +% The remaining functions provided by \pkg{l3keyval} do not +% have any protection for nesting of one call to the module +% inside another. They should therefore not be called directly by +% other modules. +% +% \begin{function}{\KV_parse_no_space_removal_no_sanitize:n} % \begin{syntax} % "\KV_parse_no_space_removal_no_sanitize:n" \Arg{keyval list} % \end{syntax} -% Parses the keys and values literally. For use when spaces are -% ignored and |=| and |,| have normal catcodes. +% Parses the keys and values, passing the results to +% \cs{KV_key_no_value_elt:n} and \cs{KV_key_value_elt:nn} as +% appropriate. Spaces are not removed in the parsing process and +% the category codes of \texttt{=} and \texttt{,} are not +% normalised. % \end{function} % -% \begin{function}{ -% \KV_parse_space_removal_no_sanitize:n | -% } +% \begin{function}{\KV_parse_space_removal_no_sanitize:n} % \begin{syntax} % "\KV_parse_space_removal_no_sanitize:n" \Arg{keyval list} % \end{syntax} -% As above but also removes spaces around keys and values. For use -% when spaces are not ignored. +% Parses the keys and values, passing the results to +% \cs{KV_key_no_value_elt:n} and \cs{KV_key_value_elt:nn} as +% appropriate. Spaces are removed in the parsing process from the +% ends of the key and value, but the category codes of \texttt{=} +% and \texttt{,} are not normalised. % \end{function} % -% \begin{function}{ -% \KV_parse_space_removal_sanitize:n | -% } +% \begin{function}{\KV_parse_space_removal_sanitize:n} % \begin{syntax} % "\KV_parse_space_removal_sanitize:n" \Arg{keyval list} % \end{syntax} -% As above but additionally also replaces top-level active |=| and -% |,| with harmless versions. +% Parses the keys and values, passing the results to +% \cs{KV_key_no_value_elt:n} and \cs{KV_key_value_elt:nn} as +% appropriate. Spaces are removed in the parsing process from the +% ends of the key and value and the category codes of \texttt{=} +% and \texttt{,} are normalised at the outer level +% (\emph{i.e}.~only unbraced tokens are affected). % \end{function} % -% \begin{variable}{ -% \l_KV_remove_one_level_of_braces_bool | -% } -% \begin{syntax} -% \end{syntax} -% This boolean controls whether or not one level of braces is -% stripped from the key and value. The default value for this -% boolean is \meta{true} so that exactly one level of braces is -% stripped. For certain applications it is desirable to keep the -% braces in which case the programmer just has to set the boolean -% false temporarily. Setting this boolean has no effect when you -% call the |no_space_removal| functions since not stripping braces -% is a rare request and would clutter the otherwise elegant code of -% the |no_space_removal| functions for very little gain. If you need -% to preserve braces choose the slower |space_removal| functions. -% \end{variable} -% % \begin{function}{ % \KV_key_no_value_elt:n | -% \KV_key_value_elt:nn | +% \KV_key_value_elt:nn % } % \begin{syntax} % "\KV_key_no_value_elt:n" \Arg{key} \\ -% "\KV_key_value_elt:n" \Arg{key} \Arg{value} +% "\KV_key_value_elt:n" \Arg{key} \Arg{value} % \end{syntax} -% Functions returned by the |\KV_parse_| functions. The default -% definition of these two functions is an error message! +% Used by \cs{KV_parse\ldots} functions to further process +% keys with no values and keys with values, respectively. The +% standard definitions are error functions: the programmer should +% provide appropriate definitions for both at point of use. % \end{function} +% +%\section{Variables and constants} +% +%\begin{variable}{\c_KV_single_equal_sign_tl} +% Constant token list to make finding \texttt{=} faster. +%\end{variable} +% +%\begin{variable}{ +% \l_KV_tmpa_tl | +% \l_KV_tmpb_tl +%} +% Scratch token lists. +%\end{variable} +% +%\begin{variable}{ +% \l_KV_parse_tl | +% \l_KV_currkey_tl | +% \l_KV_currval_tl +%} +% Token list variables for various parts of the parsed input. +%\end{variable} % % \end{documentation} % @@ -177,15 +260,6 @@ % % \section{\pkg{l3keyval} implementation} % -% \subsection{Internal functions and variables} -% -% \begin{variable}{ \l_KV_tmpa_tl | \l_KV_tmpb_tl | -% \c_KV_single_equal_sign_tl | -% \l_KV_parse_toks | \l_KV_currkey_toks | -% \l_KV_currval_toks } -% Token list variables and token registers used internally. -% \end{variable} -% % \begin{function}{ \KV_sanitize_outerlevel_active_equals:N | % \KV_sanitize_outerlevel_active_commas:N } % \begin{syntax} @@ -198,12 +272,12 @@ % \KV_remove_surrounding_spaces_auxi:w / (EXP) } % \begin{syntax} % -% "\KV_remove_surrounding_spaces:nw" <toks> <token list> "\q_nil" +% "\KV_remove_surrounding_spaces:nw" <tl> <token list> "\q_nil" % "\KV_remove_surrounding_spaces_auxi:w" <token list> \verb*" Q"$\sb3$ % \end{syntax} % Removes a possible % leading space plus a possible ending space from a <token list>. -% The first version (which is not used in the code) stores it in <toks>. +% The first version (which is not used in the code) stores it in <tl>. % \end{function} % % \begin{function}{ \KV_add_value_element:w | \KV_set_key_element:w } @@ -212,7 +286,7 @@ % "\KV_add_value_element:w" "\q_stop" <token list> "\q_nil" % \end{syntax} % Specialised functions to strip spaces from their input and set the -% token registers "\l_KV_currkey_toks" or "\l_KV_currval_toks" +% token registers "\l_KV_currkey_tl" or "\l_KV_currval_tl" % respectively. % \end{function} % @@ -248,24 +322,32 @@ % \begin{macrocode} \tl_new:N \l_KV_tmpa_tl \tl_new:N \l_KV_tmpb_tl -\tl_new:Nn \c_KV_single_equal_sign_tl{=} +\tl_const:Nn \c_KV_single_equal_sign_tl { = } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % -% \begin{macro}{\l_KV_parse_toks} -% \begin{macro}{\l_KV_currkey_toks} -% \begin{macro}{\l_KV_currval_toks} +% \begin{macro}{\l_KV_parse_tl} +% \begin{macro}{\l_KV_currkey_tl} +% \begin{macro}{\l_KV_currval_tl} % Some more useful things. % \begin{macrocode} -\toks_new:N \l_KV_parse_toks -\toks_new:N \l_KV_currkey_toks -\toks_new:N \l_KV_currval_toks +\tl_new:N \l_KV_parse_tl +\tl_new:N \l_KV_currkey_tl +\tl_new:N \l_KV_currval_tl % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} +% +%\begin{macro}{\l_KV_level_int} +% This is used to track how deeply nested calls to the keyval processor +% are, so that the correct functions are always in use. +% \begin{macrocode} +\int_new:N \l_KV_level_int +% \end{macrocode} +%\end{macro} % % \begin{macro}{\l_KV_remove_one_level_of_braces_bool} % A boolean to control @@ -274,6 +356,47 @@ \bool_set_true:N \l_KV_remove_one_level_of_braces_bool % \end{macrocode} % \end{macro} +% +%\begin{macro}{\KV_process_space_removal_sanitize:NNn} +%\begin{macro}{\KV_process_space_removal_no_sanitize:NNn} +%\begin{macro}{\KV_process_no_space_removal_no_sanitize:NNn} +%\begin{macro}[aux]{\KV_process_aux:NNNn} +% The wrapper function takes care of assigning the appropriate +% \texttt{elt} functions before and after the parsing step. In that +% way there is no danger of a mistake with the wrong functions being +% used. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \KV_process_space_removal_sanitize:NNn { + \KV_process_aux:NNNn \KV_parse_space_removal_sanitize:n +} +\cs_new_protected_nopar:Npn \KV_process_space_removal_no_sanitize:NNn { + \KV_process_aux:NNNn \KV_parse_space_removal_no_sanitize:n +} +\cs_new_protected_nopar:Npn \KV_process_no_space_removal_no_sanitize:NNn { + \KV_process_aux:NNNn \KV_parse_no_space_removal_no_sanitize:n +} +\cs_new_protected:Npn \KV_process_aux:NNNn #1#2#3#4 { + \cs_set_eq:cN + { KV_key_no_value_elt_ \int_use:N \l_KV_level_int :n } + \KV_key_no_value_elt:n + \cs_set_eq:cN + { KV_key_value_elt_ \int_use:N \l_KV_level_int :nn } + \KV_key_value_elt:nn + \cs_set_eq:NN \KV_key_no_value_elt:n #2 + \cs_set_eq:NN \KV_key_value_elt:nn #3 + \int_incr:N \l_KV_level_int + #1 {#4} + \int_decr:N \l_KV_level_int + \cs_set_eq:Nc \KV_key_no_value_elt:n + { KV_key_no_value_elt_ \int_use:N \l_KV_level_int :n } + \cs_set_eq:Nc \KV_key_value_elt:nn + { KV_key_value_elt_ \int_use:N \l_KV_level_int :nn } +} +% \end{macrocode} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} % % \begin{macro}{\KV_sanitize_outerlevel_active_equals:N} % \begin{macro}{\KV_sanitize_outerlevel_active_commas:N} @@ -287,7 +410,7 @@ \char_set_lccode:nn{`\8}{`\=} \char_set_lccode:nn{`\9}{`\,} \tl_to_lowercase:n{\group_end: -\cs_new_nopar:Npn \KV_sanitize_outerlevel_active_equals:N #1{ +\cs_new_protected_nopar:Npn \KV_sanitize_outerlevel_active_equals:N #1{ \tl_replace_all_in:Nnn #1 = 8 } \cs_new_nopar:Npn \KV_sanitize_outerlevel_active_commas:N #1{ @@ -342,7 +465,7 @@ % The function here allows you to insert arbitrary functions in the % first argument but they should all be with an |f| type % expansion. For the application in this module, we use -% |\toks_set:Nf|. +% |\tl_set:Nf|. % % Once the expansion has been kick-started, we apply % |\KV_remove_surrounding_spaces_auxi:w| to the replacement text of @@ -371,22 +494,22 @@ % % Here are some specialized versions of the above. They do exactly % what we want in one go. First trim spaces from the value and then -% put the result surrounded in braces onto |\l_KV_parse_toks|. +% put the result surrounded in braces onto |\l_KV_parse_tl|. % \begin{macrocode} -\cs_gnew:Npn\KV_add_value_element:w\q_stop#1\q_nil{ - \toks_set:Nf\l_KV_currval_toks { +\cs_gnew_protected:Npn\KV_add_value_element:w\q_stop#1\q_nil{ + \tl_set:Nf\l_KV_currval_tl { \KV_remove_surrounding_spaces_auxi:w \exp_not:N#1Q~Q } - \toks_put_right:No\l_KV_parse_toks{ - \exp_after:wN {\toks_use:N \l_KV_currval_toks} + \tl_put_right:No\l_KV_parse_tl{ + \exp_after:wN { \l_KV_currval_tl } } } % \end{macrocode} % When storing the key we firstly remove spaces plus the prepended % |\q_no_value|. % \begin{macrocode} -\cs_gnew:Npn\KV_set_key_element:w#1\q_nil{ - \toks_set:Nf\l_KV_currkey_toks +\cs_gnew_protected:Npn\KV_set_key_element:w#1\q_nil{ + \tl_set:Nf\l_KV_currkey_tl { \exp_last_unbraced:NNo \KV_remove_surrounding_spaces_auxi:w \exp_not:N \use_none:n #1Q~Q @@ -397,9 +520,8 @@ % \begin{macrocode} \bool_if:NT \l_KV_remove_one_level_of_braces_bool { - \exp_args:NNo \toks_set:No \l_KV_currkey_toks { - \exp_after:wN \KV_add_element_aux:w - \toks_use:N \l_KV_currkey_toks \q_nil + \exp_args:NNo \tl_set:No \l_KV_currkey_tl { + \exp_after:wN \KV_add_element_aux:w \l_KV_currkey_tl \q_nil } } } @@ -427,10 +549,10 @@ % at the top level first. Then uses |#1| as inspector of each % element in the comma list. % \begin{macrocode} -\cs_new:Npn \KV_parse_sanitize_aux:n #1 { +\cs_new_protected:Npn \KV_parse_sanitize_aux:n #1 { \group_begin: - \toks_clear:N \l_KV_parse_toks - \tl_set:Nx \l_KV_tmpa_tl { \exp_not:n {#1} } + \tl_clear:N \l_KV_parse_tl + \tl_set:Nn \l_KV_tmpa_tl {#1} \KV_sanitize_outerlevel_active_equals:N \l_KV_tmpa_tl \KV_sanitize_outerlevel_active_commas:N \l_KV_tmpa_tl \exp_last_unbraced:NNV \KV_parse_elt:w \q_no_value @@ -439,8 +561,8 @@ % We evaluate the parsed keys and values outside the group so the % token register is restored to its previous value. % \begin{macrocode} - \exp_last_unbraced:NV \group_end: - \l_KV_parse_toks + \exp_after:wN \group_end: + \l_KV_parse_tl } % \end{macrocode} % \end{macro} @@ -451,12 +573,12 @@ % the one we will use for preamble parsing where catcodes of |=| and % |,| are as expected! % \begin{macrocode} -\cs_new:Npn \KV_parse_no_sanitize_aux:n #1{ +\cs_new_protected:Npn \KV_parse_no_sanitize_aux:n #1{ \group_begin: - \toks_clear:N \l_KV_parse_toks + \tl_clear:N \l_KV_parse_tl \KV_parse_elt:w \q_no_value #1 , \q_nil , - \exp_last_unbraced:NV \group_end: - \l_KV_parse_toks + \exp_after:wN \group_end: + \l_KV_parse_tl } % \end{macrocode} % \end{macro} @@ -522,7 +644,7 @@ % this is slightly more tedious (but only slightly) but at least it % always removes only one level of braces. % \begin{macrocode} -\cs_new:Npn \KV_split_key_value_space_removal:w #1 = #2\q_nil{ +\cs_new_protected:Npn \KV_split_key_value_space_removal:w #1 = #2\q_nil{ % \end{macrocode} % First grab the key. % \begin{macrocode} @@ -531,15 +653,15 @@ % Then we start checking. If only a key was entered, |#2| contains % |=| and nothing else, so we test for that first. % \begin{macrocode} - \tl_set:Nx\l_KV_tmpa_tl{\exp_not:n{#2}} + \tl_set:Nn\l_KV_tmpa_tl{#2} \tl_if_eq:NNTF\l_KV_tmpa_tl\c_KV_single_equal_sign_tl % \end{macrocode} % Then we just insert the default key. % \begin{macrocode} { - \toks_put_right:No\l_KV_parse_toks{ + \tl_put_right:No\l_KV_parse_tl{ \exp_after:wN \KV_key_no_value_elt:n - \exp_after:wN {\toks_use:N\l_KV_currkey_toks} + \exp_after:wN {\l_KV_currkey_tl} } } % \end{macrocode} @@ -552,13 +674,13 @@ { \KV_split_key_value_space_removal_detect_error:wTF#2\q_no_value\q_nil {\KV_split_key_value_space_removal_aux:w \q_stop #2} - {\ERROR} + { \msg_kernel_error:nn { keyval } { misplaced-equals-sign } } } } % \end{macrocode} % The error test. % \begin{macrocode} -\cs_new:Npn +\cs_new_protected:Npn \KV_split_key_value_space_removal_detect_error:wTF#1=#2#3\q_nil{ \tl_if_head_eq_meaning:nNTF{#3}\q_no_value } @@ -570,11 +692,11 @@ % exactly one token or brace group, only the latter quark is left. % \begin{macrocode} \cs_new:Npn \KV_val_preserve_braces:NnN #1#2#3{{#2}} -\cs_new:Npn\KV_split_key_value_space_removal_aux:w #1=={ +\cs_new_protected:Npn\KV_split_key_value_space_removal_aux:w #1=={ \tl_set:Nx\l_KV_tmpa_tl{\exp_not:o{\use_none:nnn#1\q_nil\q_nil}} - \toks_put_right:No\l_KV_parse_toks{ + \tl_put_right:No\l_KV_parse_tl{ \exp_after:wN \KV_key_value_elt:nn - \exp_after:wN {\toks_use:N\l_KV_currkey_toks} + \exp_after:wN {\l_KV_currkey_tl} } % \end{macrocode} % If there a blank space or nothing at all, |\l_KV_tmpa_tl| is now @@ -584,7 +706,7 @@ % \end{macrocode} % We just put an empty value on the stack. % \begin{macrocode} - { \toks_put_right:Nn\l_KV_parse_toks{{}} } + { \tl_put_right:Nn\l_KV_parse_tl{{}} } { % \end{macrocode} % If there was exactly one brace group or token in |#1|, @@ -596,12 +718,12 @@ { \bool_if:NTF \l_KV_remove_one_level_of_braces_bool { - \toks_put_right:No\l_KV_parse_toks{ + \tl_put_right:No\l_KV_parse_tl{ \exp_after:wN{\use_ii:nnn #1\q_nil} } } { - \toks_put_right:No\l_KV_parse_toks{ + \tl_put_right:No\l_KV_parse_tl{ \exp_after:wN{\KV_val_preserve_braces:NnN #1\q_nil} } } @@ -623,18 +745,18 @@ % however fun they may be. Since there are no spaces, a set of % braces around a value is automatically stripped by \TeX. % \begin{macrocode} -\cs_new:Npn \KV_split_key_value_no_space_removal:w #1#2=#3=#4\q_nil{ +\cs_new_protected:Npn \KV_split_key_value_no_space_removal:w #1#2=#3=#4\q_nil{ \tl_set:Nn\l_KV_tmpa_tl{#4} \tl_if_empty:NTF \l_KV_tmpa_tl { - \toks_put_right:Nn\l_KV_parse_toks{\KV_key_no_value_elt:n{#2}} + \tl_put_right:Nn\l_KV_parse_tl{\KV_key_no_value_elt:n{#2}} } { \tl_if_eq:NNTF\c_KV_single_equal_sign_tl\l_KV_tmpa_tl { - \toks_put_right:Nn\l_KV_parse_toks{\KV_key_value_elt:nn{#2}{#3}} + \tl_put_right:Nn\l_KV_parse_tl{\KV_key_value_elt:nn{#2}{#3}} } - {\ERROR} + { \msg_kernel_error:nn { keyval } { misplaced-equals-sign } } } } % \end{macrocode} @@ -660,7 +782,7 @@ % version that disallows unmatched conditional and does no space % removal. % \begin{macrocode} -\cs_new_nopar:Npn \KV_parse_no_space_removal_no_sanitize:n { +\cs_new_protected_nopar:Npn \KV_parse_no_space_removal_no_sanitize:n { \cs_set_eq:NN \KV_split_key_value_current:w \KV_split_key_value_no_space_removal:w \KV_parse_no_sanitize_aux:n } @@ -672,14 +794,14 @@ % The other varieties can be defined in a similar manner. For the % version needed at the document level, we can use this one. % \begin{macrocode} -\cs_new_nopar:Npn \KV_parse_space_removal_sanitize:n { +\cs_new_protected_nopar:Npn \KV_parse_space_removal_sanitize:n { \cs_set_eq:NN \KV_split_key_value_current:w \KV_split_key_value_space_removal:w \KV_parse_sanitize_aux:n } % \end{macrocode} % For preamble use by the non-programmer this is probably best. % \begin{macrocode} -\cs_new_nopar:Npn \KV_parse_space_removal_no_sanitize:n { +\cs_new_protected_nopar:Npn \KV_parse_space_removal_no_sanitize:n { \cs_set_eq:NN \KV_split_key_value_current:w \KV_split_key_value_space_removal:w \KV_parse_no_sanitize_aux:n } @@ -687,6 +809,16 @@ % \end{macro} % \end{macro} % +% \begin{macrocode} +\msg_kernel_new:nnnn { keyval } { misplaced-equals-sign } + {Misplaced~equals~sign~in~key--value~input~\msg_line_context:} + { + I~am~trying~to~read~some~key--value~input~but~found~two~equals~ + signs\\% + without~a~comma~between~them. + } +% \end{macrocode} +% % % \begin{macrocode} %</initex|package> |