diff options
Diffstat (limited to 'Master/texmf-dist/source/latex/expl3/l3basics.dtx')
-rw-r--r-- | Master/texmf-dist/source/latex/expl3/l3basics.dtx | 2792 |
1 files changed, 2265 insertions, 527 deletions
diff --git a/Master/texmf-dist/source/latex/expl3/l3basics.dtx b/Master/texmf-dist/source/latex/expl3/l3basics.dtx index 8a4170e79cf..4181fad3182 100644 --- a/Master/texmf-dist/source/latex/expl3/l3basics.dtx +++ b/Master/texmf-dist/source/latex/expl3/l3basics.dtx @@ -1,16 +1,49 @@ % \iffalse -%% File: l3basics.dtx Copyright (C) 1990-1998 LaTeX3 project -% +%% File: l3basics.dtx Copyright (C) 1990-2006 LaTeX3 project +%% +%% It may be distributed and/or modified under the conditions of the +%% LaTeX Project Public License (LPPL), either version 1.3c of this +%% license or (at your option) any later version. The latest version +%% of this license is in the file +%% +%% http://www.latex-project.org/lppl.txt +%% +%% This file is part of the ``expl3 bundle'' (The Work in LPPL) +%% and all files in that bundle must be distributed together. +%% +%% The released version of this bundle is available from CTAN. +%% +%% ----------------------------------------------------------------------- +%% +%% The development version of the bundle can be found at +%% +%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/ +%% +%% for those people who are interested. +%% +%%%%%%%%%%% +%% NOTE: %% +%%%%%%%%%%% +%% +%% Snapshots taken from the repository represent work in progress and may +%% not work or may contain conflicting material! We therefore ask +%% people _not_ to put them into distributions, archives, etc. without +%% prior consultation with the LaTeX Project Team. +%% +%% ----------------------------------------------------------------------- +%<package>\RequirePackage{l3names} %<*dtx> - \ProvidesFile{l3basics.dtx} +%\fi +\def\GetIdInfo$Id: #1.dtx #2 #3-#4-#5 #6 #7$#8{% + \def\fileversion{#2}% + \def\filedate{#3/#4/#5}% + \ProvidesFile{#1.dtx}[#3/#4/#5 v#2 #8]% +} +%\iffalse %</dtx> -%<package>\NeedsTeXFormat{LaTeX2e} -%<package>\ProvidesPackage{l3basics} -%<driver> \ProvidesFile{l3basics.drv} -% \fi -% \ProvidesFile{l3basics.dtx} - [1998/05/04 v1.0i L3 Experimental basic definitions] -% +%\fi +\GetIdInfo$Id: l3basics.dtx 583 2006-12-12 17:26:44Z morten $ + {L3 Experimental basic definitions} % \iffalse %<*driver> \documentclass{l3doc} @@ -21,7 +54,6 @@ %</driver> % \fi % -% \GetFileInfo{l3basics.dtx} % \title{The \textsf{l3basics} package\thanks{This file % has version number \fileversion, last % revised \filedate.}\\ @@ -31,109 +63,236 @@ % \maketitle % % -% We start by ensuring that the required packages are loaded. In -% this case there is a boot-strapping problem since, to use much of -% the code in this file, the `l3expan' package needs to be loaded; -% but this file must be loaded first. -% \begin{macrocode} -%<package>\RequirePackage{l3names}\par -% \end{macrocode} -% % As the name suggest this package holds some basic definitions which % are needed by most or all other packages in this set. % -% \section{Basics} -% -% Here we describe those functions that used all over the place. +% \section{Basics} +% +% Here we describe those functions that used all over the place. With +% that we mean functions dealing with the construction and testing of +% control sequences. Furthermore the basic parts of conditional +% processing are covered; conditional processing dealing with specific +% data types is described in the modules specific for the respective +% data types. +% +% \subsection{Predicates and conditionals} % -% \subsection{Functions} +% \subsubsection{Primitive conditionals} +% +% The \eTeX\ engine itself provides many different conditionals. Some +% expand whatever comes after them and others don't. Hence the names +% for these underlying functions will often contain a |:w| part but +% higher level functions are often available. See for instance +% |\int_compare_p:nNn| which is a wrapper for |\if_num:w|. +% +% Certain conditionals deal with specific data types like boxes and +% fonts and are described there. The ones described below are either +% the universal conditionals or deal with control sequences. We will +% prefix primitive conditionals with |\if_|. % -% \begin{function}{\cs_to_str:N} +% \begin{function}{% +% \if_true: | +% \if_false: | +% \else: | +% \fi: | +% \reverse_if:N | +% } % \begin{syntax} -% "\cs_to_str:N" <cs> +% "\if_true:" <true code> "\else:" <false code> "\fi:" \\ +% "\if_false:" <true code> "\else:" <false code> "\fi:" \\ +% "\reverse_if:N" <primitive conditional> % \end{syntax} -% This function return the name of <cs> as a sequence of letters with -% the escape character removed. +% "\if_true:" always executes <true code>, while "\if_false:" always +% executes <false code>. "\reverse_if:N" reverses any two-way primitive +% conditional. "\else:" and "\fi:" delimit the branches of the conditional. % \end{function} % -% \begin{function}{\cs_gen_sym:N | -% \cs_ggen_sym:N} +% \begin{function}{% +% \if_meaning:NN | +% \if_cs_meaning_eq:NN | +% \if_token_eq:NN | +% } % \begin{syntax} -% "\cs_gen_sym:N" <tlp> +% "\if_meaning:NN" <cs1> <cs2> <true code> "\else:" <false code> +% "\fi:" \\ +% "\if_cs_meaning_eq:NN" <cs1> <cs2> <true code> "\else:" +% <false code> "\fi:" \\ +% "\if_token_eq:NN" <token1> <token2> <true code> "\else:" <false +% code> "\fi:" % \end{syntax} -% These functions will generate a new control sequence name for use as a -% pointer, e.g.\ some tree structure like the LDB. The new unique name -% is returned locally in <tlp> for further use. The names are generated -% using the roman numeral representation of some special counters -% together with a prefix of "\l*" (local) or "\g*"( global). +% "\if_meaning:NN" executes <true code> when the replacement text, +% i.e., the expansion of <cs1> and <cs2> are the same, otherwise it +% executes <false code>. However this name isn't really that +% good. What the \TeX\ primitive does is compare two tokens to see if +% they are equal. Hence this is actually a "token" functions. A +% similar argument applies to the situation where it is used to +% compare control sequences, where it is the meaning being compared. +% Something to be cleaned up at some point. % \end{function} -% -% -% \subsection{Predicates and conditionals} -% +% % \begin{function}{% -% \if_meaning:NN | +% \if:w | +% \if_charcode:w | +% \if_catcode:w % } % \begin{syntax} -% "\if_meaning:NN" <cs1> <cs2> <true code> "\else:" <false code> "\fi:" +% "\if:w" <token1> <token2> <true code> "\else:" <false code> "\fi:" \\ +% "\if_catcode:w" <token1> <token2> <true code> "\else:" <false +% code> "\fi:" % \end{syntax} -% This conditional executes <true code> when the replacement text, i.e., -% the expansion of <cs1> and <cs2> are the same, otherwise it executes -% <false code>. -% \begin{texnote} -% This is the primitive \tn{ifx}. -% \end{texnote} +% These conditionals will expand any following tokens until two +% unexpandable tokens are left. If you wish to prevent this expansion, +% prefix the token in question with "\exp_not:N". "\if_catcode:w" +% tests if the category codes of the two tokens are the same whereas +% "\if:w" tests if the character codes are +% identical. "\if_charcode:w" is an alternative name for "\if:w". % \end{function} +% % \begin{function}{% -% \cs_eq_p:NN | +% \if_cs_exist:N | +% \if_cs_exist:w % } % \begin{syntax} -% "\cs_eq_p:NN" <cs1> <cs2> +% "\if_cs_exist:N" <cs> <true code> "\else:" <false code> "\fi:" \\ +% "\if_cs_exist:w" <tokens> "\cs_end:" <true code> "\else:" <false +% code> "\fi:" +% \end{syntax} +% Check if <cs> appears in the hash table or if the control sequence +% that can be formed from <tokens> appears in the hash table. The +% latter function does not turn the control sequence in question into +% "\scan_stop:"! This can be useful when dealing with control +% sequences which cannot be entered as a single token. +% \end{function} +% +% \begin{function}{ +% \if_mode_horizontal: | +% \if_mode_vertical: | +% \if_mode_math: | +% \if_mode_inner: +% } +% \begin{syntax} +% "\if_horizontal_mode:" <true code> "\else:" <false code> "\fi:" +% \end{syntax} +% Execute <true code> if currently in horizontal mode, otherwise +% execute <false code>. Similar for the other functions. +% \end{function} +% +% \subsubsection{Non-primitive conditionals} +% +% \begin{function}{% +% \cs_if_eq_p:NN +% } +% \begin{syntax} +% "\cs_if_eq_p:NN" <cs1> <cs2> % \end{syntax} % Returns `true' if <cs1> and <cs2> are textually the same, i.e.\ have % the same name, otherwise it returns `false'. % \end{function} -% % % \begin{function}{% -% \cs_free_p:N | +% \cs_if_eq:NNTF | +% \cs_if_eq:NNT | +% \cs_if_eq:NNF | +% \cs_if_eq:cNTF | +% \cs_if_eq:cNT | +% \cs_if_eq:cNF | +% \cs_if_eq:NcTF | +% \cs_if_eq:NcT | +% \cs_if_eq:NcF | +% \cs_if_eq:ccTF | +% \cs_if_eq:ccT | +% \cs_if_eq:ccF +% } +% \begin{syntax} +% "\cs_if_eq:NNTF" <cs1> <cs2> "{"<true code>"}{"<false code>"}" +% \end{syntax} +% These functions check if <cs1> and <cs2> have same meaning and then +% execute either <true code> or <false code>. +% \end{function} +% +% +% \begin{function}{% +% \cs_if_free_p:N % } % \begin{syntax} -% "\cs_free_p:N" <cs> +% "\cs_if_free_p:N" <cs> % \end{syntax} % Returns `true' if <cs> is either undefined or equal to "\scan_stop:". % However, it returns `false' if <cs> is textually "\c_undefined" (the % constantly undefined function), or textually "\scan_stop:". % \end{function} -% +% % \begin{function}{% -% \cs_free:NTF | -% \cs_free:NF | -% \cs_free:NT | -% \cs_free:cF | -% \cs_free:cTF | +% \cs_if_free:NTF | +% \cs_if_free:NT | +% \cs_if_free:NF | +% \cs_if_free:cTF | +% \cs_if_free:cT | +% \cs_if_free:cF % } % \begin{syntax} -% "\cs_free:NTF" <cs> "{"<true code>"}{"<false code>"}" +% "\cs_if_free:NTF" <cs> "{"<true code>"}{"<false code>"}" % \end{syntax} % These functions check if <cs> is free and then execute either <true % code> or <false code>. % \begin{texnote} -% The conditional "\cs_free:cTF" is the \LaTeX3 implementation of the -% \LaTeX2 function \tn{@ifundefined}. The other functions haven't been -% around before. +% The conditional "\cs_if_free:cTF" is the \LaTeX3 implementation of +% the \LaTeX2 function \tn{@ifundefined}. The other functions +% haven't been around before. % \end{texnote} % \end{function} -% +% % \begin{function}{% -% \cs_exist_p:N | +% \cs_if_really_free:cTF | +% \cs_if_really_free:cF | +% \cs_if_really_free:cT % } % \begin{syntax} -% "\cs_exist_p:N" <cs> +% "\cs_if_really_free:cTF" "{"<tokens>"}" "{"<true code>"} {"<false +% code>"}" % \end{syntax} -% This function does the opposite of "\cs_free_p:N". +% Similar to "\cs_if_free:cTF" but does not put anything previously +% undefined into the hash table. Useful for special control sequences +% like "\foo/bar" which cannot be entered as one token. % \end{function} -% +% +% \begin{function}{% +% \cs_if_exist_p:N +% } +% \begin{syntax} +% "\cs_if_exist_p:N" <cs> +% \end{syntax} +% This function does the opposite of "\cs_if_free_p:N". +% \end{function} +% +% \begin{function}{% +% \cs_if_exist:NTF | +% \cs_if_exist:NT | +% \cs_if_exist:NF | +% \cs_if_exist:cTF | +% \cs_if_exist:cT | +% \cs_if_exist:cF +% } +% \begin{syntax} +% "\cs_if_exist:NTF" <cs> "{"<true code>"}{"<false code>"}" +% \end{syntax} +% These functions check if <cs> exists and then execute either <true +% code> or <false code>. Exactly the opposite of "\cs_if_free:NTF". +% \end{function} +% +% \begin{function}{% +% \cs_if_really_exist:cTF | +% \cs_if_really_exist:cF | +% \cs_if_really_exist:cT +% } +% \begin{syntax} +% "\cs_if_really_exist:cTF" "{"<tokens>"}" "{"<true code>"} {"<false +% code>"}" +% \end{syntax} +% The opposite of "\cs_if_really_free:cTF". +% \end{function} +% +% % \begin{function}{% % \chk_new_cs:N | % } @@ -145,9 +304,10 @@ % control sequences by \TeX{} when "\cs:w" "..." "\cs_end:" is % used). % \end{function} -% +% % \begin{function}{% % \chk_exist_cs:N | +% \chk_exist_cs:c % } % \begin{syntax} % "\chk_exist_cs:N" <cs> @@ -155,14 +315,136 @@ % This function checks that <cs> is defined. If it is not an error % is generated. % \end{function} -% -% +% +% +% \begin{variable}{% +% \c_true | +% \c_false +% } +% \begin{syntax} +% \end{syntax} +% Constants that represent `true' or `false', respectively. Used to +% implement predicates. +% \end{variable} +% +% +% +% \subsection{Selecting and discarding tokens from the input stream} +% +% The conditional processing could not have been implemented without +% being able to gobble and select which tokens to use from the input +% stream. +% +% \begin{function}{% +% \use_none:n | +% \use_none:nn | +% \use_none:nnn | +% \use_none:nnnn | +% \use_none:nnnnn | +% \use_none:nnnnnn | +% \use_none:nnnnnnn | +% \use_none:nnnnnnnn | +% \use_none:nnnnnnnnn | +% } +% \begin{syntax} +% "\use_none:n" "{"<arg1>"}"\\ +% "\use_none:nn" "{"<arg1>"}{"<arg2>"}" +% \end{syntax} +% These functions gobble the tokens or brace groups from the input +% stream. +% \end{function} +% +% +% \begin{function}{\use_arg_i:n} +% \begin{syntax} +% "\use_arg_i:n" "{" <code1> "}" +% \end{syntax} +% Function that executes the next argument after removing the +% surrounding braces. Used to implement conditionals. +% \end{function} +% +% \begin{function}{% +% \use_arg_i:nn | +% \use_arg_ii:nn | +% } +% \begin{syntax} +% "\use_arg_i:nn" "{" <code1> "}{" <code2> "}" +% \end{syntax} +% Functions that execute the first or second argument respectively, +% after removing the surrounding braces. Primarily used to implement +% conditionals. +% \end{function} +% +% \begin{function}{% +% \use_arg_i:nnn | +% \use_arg_ii:nnn | +% \use_arg_iii:nnn | +% } +% \begin{syntax} +% "\use_arg_i:nnn" "{" <arg1> "}{" <arg2> "}{" <arg3> "}" +% \end{syntax} +% Functions that pick up one of three arguments and execute them after +% removing the surrounding braces. Should be described somewhere else. +% \end{function} +% +% \begin{function}{% +% \use_arg_i:nnnn | +% \use_arg_ii:nnnn | +% \use_arg_iii:nnnn | +% \use_arg_iv:nnnn | +% } +% \begin{syntax} +% "\use_arg_i:nnnn" "{" <arg1> "}{" <arg2> "}{" <arg3> "}{" <arg4> "}" +% \end{syntax} +% Functions that pick up one of four arguments and execute them after +% removing the surrounding braces. +% \end{function} +% +% A different kind of functions for selecting tokens from the token +% stream are those that use delimited arguments. +% +% \begin{function}{% +% \use_none_delimit_by_q_nil:w | +% \use_none_delimit_by_q_stop:w | +% } +% \begin{syntax} +% "\use_none_delimit_by_q_nil:w" <balanced text> "\q_nil" +% \end{syntax} +% Gobbles <balanced text>. Useful in gobbling the remainder in a list +% structure. +% \end{function} +% +% \begin{function}{% +% \use_arg_i_delimit_by_q_nil:nw | +% \use_arg_i_delimit_by_q_stop:nw | +% } +% \begin{syntax} +% "\use_arg_i_delimit_by_q_nil:nw" "{"<arg>"}" <balanced text> "\q_nil" +% \end{syntax} +% Gobbles <balanced text> and executes <arg> afterwards. This can also +% be used to get the first item in a token list. +% \end{function} +% +% +% \begin{function}{% +% \use_arg_i_after_fi:nw | +% \use_arg_i_after_else:nw | +% \use_arg_i_after_or:nw +% } +% \begin{syntax} +% "\use_arg_i_after_fi:nw" "{"<arg>"}" "\fi:" +% "\use_arg_i_after_else:nw" "{"<arg>"}" "\else:" <balanced text> "\fi:" +% "\use_arg_i_after_or:nw" "{"<arg>"}" "\or:" <balanced text> "\fi:" +% \end{syntax} +% Executes <arg> after executing closing out "\fi:". +% \end{function} +% % \subsection{Internal functions} -% +% % \begin{function}{% % \cs:w | -% \cs_end: | -% } +% \cs_end: +% } % \begin{syntax} % "\cs:w" <tokens> "\cs_end:" % \end{syntax} @@ -175,10 +457,11 @@ % "\cs_end:". % \end{texnote} % \end{function} -% +% % \begin{function}{\pref_global:D | % \pref_long:D | -% } +% \pref_protected:D | +% } % \begin{syntax} % "\pref_global:D" "\def:Npn" % \end{syntax} @@ -186,61 +469,55 @@ % functions (namely \ldots). The result of prefixing a function % definition with "\pref_global:D" makes the definition global, % "\pref_long:D" change the argument scanning mechanism so that it -% allows "\par" tokens in the argument of the prefixed function. -% +% allows "\par" tokens in the argument of the prefixed function, +% and "\pref_protected:D" makes the definition robust in "\write"s etc. +% +% % None of these internal functions should be used by a programmer since % the necessary combinations are all available as separate function, % e.g., "\def_long:Npn" is internally implemented as "\pref_long:D" -% "\def_long:Npn". +% "\def:Npn". % \begin{texnote} -% These prefixes are the primitives \tn{global}, \tn{long}. -% The \tn{outer} isn't used at all within \LaTeX3 -% because \ldots +% These prefixes are the primitives \tn{global}, \tn{long}, and +% \tn{protected}. The \tn{outer} isn't used at all within \LaTeX3 +% because \ldots % \end{texnote} % \end{function} -% -% \subsection{Choice functions} % -% \begin{function}{% -% \use_choice_i:nn | -% \use_choice_ii:nn | -% } -% \begin{syntax} -% "\use_choice_i:nn" "{" <code1> "}{" <code2> "}" -% \end{syntax} -% Functions that execute the first or second argument respectively, -% after removing the surrounding braces. Used to implement conditionals. -% \end{function} % -% \begin{function}{% -% \use_choice_i:nnn | -% \use_choice_ii:nnn | -% \use_choice_iii:nnn | +% +% \begin{function}{\io_put_log:x | +% \io_put_term:x | +% \io_put_deferred:Nx | % } % \begin{syntax} -% "\use_choice_i:nnn" "{" <arg1> "}{" <arg2> "}{" <arg2> "}" +% "\io_put_log:x" "{"<message>"}" +% "\io_put_deferred:Nx" <write_stream> "{"<message>"}" % \end{syntax} -% Functions that pick up one of three arguments and execute them after -% removing the surrounding braces. Should be described somewhere else. +% Writes <message> to either to log or the terminal. % \end{function} % -% \begin{function}{\use:n} -% \begin{syntax} -% "\use:n" "{" <code1> "}" -% \end{syntax} -% Function that executes the next argument after removing the -% surrounding braces. Used to implement conditionals. -% \end{function} +% \subsection{Defining functions} +% % -% \section{Defining functions} -% % There are two types of function definitions in \LaTeX3: versions % that check if the function name is still unused, and versions that % simply make the definition. The later are used for internal scratch % functions that get new meanings all over the place. -% -% (Parts of this module are a mess, as far as naming conventions are -% concerned.) +% +% For each type there is an additional choice to be made: Does the +% function to be defined contain delimited arguments? The answer in +% 99\% of the cases is no, so in most cases the programmer just want +% to input the number of arguments, which is basically how +% \cs{newcommand} in \LaTeXe{} works. Therefore we provide functions +% that expect a number as the primary type and later on in this module +% you can find the ones with the more primitive syntax. +% +% A definition of a new function can be done locally and globally. Currently +% nearly all function definitions are done locally on top level, in +% other words they are global but don't show it. Therefore I think it may +% be better to remove the local variants in the future and declare all +% checked function definitions global. % % \begin{texnote} % While \TeX{} makes all definition functions directly available to the @@ -249,15 +526,117 @@ % \TeX{} a combination of prefixes and definition functions are provided % as individual functions. % \end{texnote} -% -% \subsection{Defining new functions} -% -% A definition of a new function can be done locally and globally. Currently -% nearly all function definitions are done locally on top level, in -% other words they are global but don't show it. Therefore I think it may -% be better to remove the local variants in the future and declare all -% checked function definitions global. -% +% +% +% \subsubsection{Defining new functions} +% +% Firstly comes to variants most used namely those taking a number to +% denote the number of arguments. +% +% \begin{function}{\def_new:NNn | +% \def_new:NNx | +% \def_new:cNn | +% \def_new:cNx +% } +% \begin{syntax} +% "\def_new:NNn" <cs> <num> "{" <code> "}" +% \end{syntax} +% Defines a new function, making sure that <cs> is unused so far. +% <num> is the number of arguments which is in the interval $[0,9]$ +% otherwise an error is raised. It is under the responsibility of the +% programmer to name the new function according to the rules laid out +% in the previous section. <code> is either passed literally or may +% be subject to expansion (under the "x" variants). +% \end{function} +% +% \begin{function}{\gdef_new:NNn | +% \gdef_new:cNn | +% \gdef_new:NNx | +% \gdef_new:cNx +% } +% \begin{syntax} +% "\gdef_new:NNn" <cs> <num> "{" <code> "}" +% \end{syntax} +% Like "\def_new:NNn" but defines the new function globally. +% \end{function} +% +% \begin{function}{\def_long_new:NNn | +% \def_long_new:NNx | +% \def_long_new:cNn | +% \def_long_new:cNx +% } +% \begin{syntax} +% "\def_long_new:NNn" <cs> <num> "{" <code> "}" +% \end{syntax} +% Defines a function that may contain "\par" tokens in the argument(s) +% when called. This is not allowed for normal functions. +% \end{function} +% +% \begin{function}{\gdef_long_new:NNn | +% \gdef_long_new:NNx | +% \gdef_long_new:cNn | +% \gdef_long_new:cNx +% } +% \begin{syntax} +% "\gdef_long_new:NNn" <cs> <num> "{" <code> "}" +% \end{syntax} +% Global versions of the above functions. +% \end{function} +% +% \begin{function}{\def_protected_new:NNn | +% \def_protected_new:NNx | +% \def_protected_new:cNn | +% \def_protected_new:cNx +% } +% \begin{syntax} +% "\def_protected_new:NNn" <cs> <num> "{" <code> "}" +% \end{syntax} +% Defines a function that does not expand when inside an |x| type +% expansion. +% \end{function} +% +% \begin{function}{\gdef_protected_new:NNn | +% \gdef_protected_new:NNx | +% \gdef_protected_new:cNn | +% \gdef_protected_new:cNx +% } +% \begin{syntax} +% "\gdef_protected_new:NNn" <cs> <num> "{" <code> "}" +% \end{syntax} +% Global versions of the above functions. +% \end{function} +% +% \begin{function}{\def_protected_long_new:NNn | +% \def_protected_long_new:NNx | +% \def_protected_long_new:cNn | +% \def_protected_long_new:cNx +% } +% \begin{syntax} +% "\def_protected_long_new:NNn" <cs> <num> "{" <code> "}" +% \end{syntax} +% Defines a function that is both robust and may contain "\par" tokens +% in the argument(s) when called. +% \end{function} +% +% \begin{function}{\gdef_protected_long_new:NNn | +% \gdef_protected_long_new:NNx | +% \gdef_protected_long_new:cNn | +% \gdef_protected_long_new:cNx +% } +% \begin{syntax} +% "\gdef_protected_long_new:NNn" <cs> <num> "{" <code> "}" +% \end{syntax} +% Global versions of the above functions. +% \end{function} +% +% +% +% +% +% Secondly comes the ones where the programmer can use delimited +% arguments. Rarely needed outside the kernel. +% +% % \begin{function}{\def_new:Npn | % \def_new:Npx | % \def_new:cpn | @@ -274,7 +653,10 @@ % (under the "x" variants). % \end{function} % -% \begin{function}{\gdef_new:Npn +% \begin{function}{\gdef_new:Npn | +% \gdef_new:cpn | +% \gdef_new:Npx | +% \gdef_new:cpx % } % \begin{syntax} % "\gdef_new:Npn" <cs> <parms> "{" <code> "}" @@ -282,8 +664,11 @@ % Like "\def_new:Npn" but defines the new function globally. See % comments above. % \end{function} -% +% % \begin{function}{\def_long_new:Npn | +% \def_long_new:Npx | +% \def_long_new:cpn | +% \def_long_new:cpx % } % \begin{syntax} % "\def_long_new:Npn" <cs> <parms> "{" <code> "}" @@ -291,23 +676,198 @@ % Defines a function that may contain "\par" tokens in the argument(s) % when called. This is not allowed for normal functions. % \end{function} -% +% +% \begin{function}{\gdef_long_new:Npn | +% \gdef_long_new:Npx | +% \gdef_long_new:cpn | +% \gdef_long_new:cpx +% } +% \begin{syntax} +% "\gdef_long_new:Npn" <cs> <parms> "{" <code> "}" +% \end{syntax} +% Global versions of the above functions. +% \end{function} +% +% \begin{function}{\def_protected_new:Npn | +% \def_protected_new:Npx | +% \def_protected_new:cpn | +% \def_protected_new:cpx +% } +% \begin{syntax} +% "\def_protected_new:Npn" <cs> <parms> "{" <code> "}" +% \end{syntax} +% Defines a function that does not expand when inside an |x| type +% expansion. +% \end{function} +% +% \begin{function}{\gdef_protected_new:Npn | +% \gdef_protected_new:Npx | +% \gdef_protected_new:cpn | +% \gdef_protected_new:cpx +% } +% \begin{syntax} +% "\gdef_protected_new:Npn" <cs> <parms> "{" <code> "}" +% \end{syntax} +% Global versions of the above functions. +% \end{function} +% +% \begin{function}{\def_protected_long_new:Npn | +% \def_protected_long_new:Npx | +% \def_protected_long_new:cpn | +% \def_protected_long_new:cpx +% } +% \begin{syntax} +% "\def_protected_long_new:Npn" <cs> <parms> "{" <code> "}" +% \end{syntax} +% Defines a function that is both robust and may contain "\par" tokens +% in the argument(s) when called. +% \end{function} +% +% \begin{function}{\gdef_protected_long_new:Npn | +% \gdef_protected_long_new:Npx | +% \gdef_protected_long_new:cpn | +% \gdef_protected_long_new:cpx +% } +% \begin{syntax} +% "\gdef_protected_long_new:Npn" <cs> <parms> "{" <code> "}" +% \end{syntax} +% Global versions of the above functions. +% \end{function} +% % \begin{function}{\let_new:NN | -% \glet_new:NN} +% \let_new:cN | +% \let_new:Nc | +% \let_new:cc | +% \glet_new:NN| +% \glet_new:cN| +% \glet_new:Nc| +% \glet_new:cc } % \begin{syntax} % "\let_new:NN" <cs1> <cs2> % \end{syntax} % Gives the function <cs1> the current meaning of <cs2>. Again, we may -% do this alway globally. +% do this always globally. % \end{function} -% -% \subsection{Defining internal functions (no checks)} -% +% +% +% +% \subsubsection{Undefining functions} +% +% \begin{function}{ \cs_gundefine:N +% } +% \begin{syntax} +% "\cs_gundefine:N" <cs> +% \end{syntax} +% Undefines the control sequence. +% \end{function} +% +% \subsubsection{Defining internal functions (no checks)} +% % Besides the function definitions that check whether or not their % argument is an unused function we need function definitions that % overwrite currently used definitions. The following functions are % provided for this purpose. -% +% +% First comes the versions expecting a number to denote the number of +% arguments. +% +% \begin{function}{\def:NNn | +% \def:NNx | +% \def:cNn | +% \def:cNx | +% } +% \begin{syntax} +% "\def:NNn" <cs> <num> "{" <code> "}" +% \end{syntax} +% Like "\def_new:NNn" etc.\ but does not check the <cs> name. +% \end{function} +% +% \begin{function}{\gdef:NNn | +% \gdef:NNx | +% \gdef:cNn | +% \gdef:cNx | +% } +% \begin{syntax} +% "\gdef:NNn" <cs> <num> "{" <code> "}" +% \end{syntax} +% Like "\def:NNn" but defines the <cs> globally. +% \end{function} +% +% +% \begin{function}{\def_long:NNn | +% \def_long:NNx | +% \def_long:cNn | +% \def_long:cNx | +% } +% \begin{syntax} +% "\def_long:NNn" <cs> <num> "{" <code> "}" +% \end{syntax} +% Like "\def:NNn" but allows "\par" tokens in the arguments of the +% function being defined. +% \end{function} +% +% \begin{function}{\gdef_long:NNn | +% \gdef_long:NNx | +% \gdef_long:cNn | +% \gdef_long:cNx | +% } +% \begin{syntax} +% "\gdef_long:NNn" <cs> <num> "{" <code> "}" +% \end{syntax} +% Global variant of "\def_long:NNn". +% \end{function} +% +% \begin{function}{\def_protected:NNn | +% \def_protected:cNn | +% \def_protected:NNx | +% \def_protected:cNx | +% } +% \begin{syntax} +% "\def_protected:NNn" <cs> <num> "{" <code> "}" +% \end{syntax} +% Naturally robust macro that won't expand in an |x| type argument. +% This also comes as a |long| version. If you for some reason want to +% expand it inside an |x| type expansion, prefix it with +% |\exp_after:NN \use_noop:|. +% \end{function} +% +% \begin{function}{\gdef_protected:NNn | +% \gdef_protected:cNn | +% \gdef_protected:NNx | +% \gdef_protected:cNx | +% } +% \begin{syntax} +% "\gdef_protected:NNn" <cs> <num> "{" <code> "}" +% \end{syntax} +% Global versions of the above functions. +% \end{function} +% +% \begin{function}{\def_protected_long:NNn | +% \def_protected_long:cNn | +% \def_protected_long:NNx | +% \def_protected_long:cNx | +% } +% \begin{syntax} +% "\def_protected_long:NNn" <cs> <num> "{" <code> "}" +% \end{syntax} +% Naturally robust macro that won't expand in an |x| type argument. +% These varieties also allow |\par| tokens in the arguments of the +% function being defined. +% \end{function} +% +% \begin{function}{\gdef_protected_long:NNn | +% \gdef_protected_long:cNn | +% \gdef_protected_long:NNx | +% \gdef_protected_long:cNx | +% } +% \begin{syntax} +% "\gdef_protected_long:NNn" <cs> <num> "{" <code> "}" +% \end{syntax} +% Global versions of the above functions. +% \end{function} +% +% Secondly the ones that use the primitive parameter build-up: +% % \begin{function}{\def:Npn | % \def:Npx | % \def:cpn | @@ -323,7 +883,7 @@ % known in \LaTeX2 as \tn{@namedef}. "\def:cpx" has no equivalent. % \end{texnote} % \end{function} -% +% % \begin{function}{\gdef:Npn | % \gdef:Npx | % \gdef:cpn | @@ -338,21 +898,12 @@ % and \tn{xdef}. % \end{texnote} % \end{function} -% -% \begin{function}{\def:No | -% \gdef:No -% } -% \begin{syntax} -% "\def:No" <cs> "{" <code> "}" -% \end{syntax} -% Local and global variant that expands code once before defining <cs>. -% The function may not take <parms> as the others do. Perhaps this -% should be changed. -% \end{function} -% +% +% % \begin{function}{\def_long:Npn | % \def_long:Npx | % \def_long:cpn | +% \def_long:cpx | % } % \begin{syntax} % "\def_long:Npn" <cs> <parms> "{" <code> "}" @@ -360,21 +911,77 @@ % Like "\def:Npn" but allows "\par" tokens in the arguments of the % function being defined. % \end{function} -% +% % \begin{function}{\gdef_long:Npn | % \gdef_long:Npx | +% \gdef_long:cpn | +% \gdef_long:cpx | % } % \begin{syntax} % "\gdef_long:Npn" <cs> <parms> "{" <code> "}" % \end{syntax} % Global variant of "\def_long:Npn". % \end{function} -% +% +% \begin{function}{\def_protected:Npn | +% \def_protected:cpn | +% \def_protected:Npx | +% \def_protected:cpx | +% } +% \begin{syntax} +% "\def_protected:Npn" <cs> <parms> "{" <code> "}" +% \end{syntax} +% Naturally robust macro that won't expand in an |x| type argument. +% This also comes as a |long| version. If you for some reason want to +% expand it inside an |x| type expansion, prefix it with +% |\exp_after:NN \use_noop:|. +% \end{function} +% +% \begin{function}{\gdef_protected:Npn | +% \gdef_protected:cpn | +% \gdef_protected:Npx | +% \gdef_protected:cpx | +% } +% \begin{syntax} +% "\gdef_protected:Npn" <cs> <parms> "{" <code> "}" +% \end{syntax} +% Global versions of the above functions. +% \end{function} +% +% \begin{function}{\def_protected_long:Npn | +% \def_protected_long:cpn | +% \def_protected_long:Npx | +% \def_protected_long:cpx | +% } +% \begin{syntax} +% "\def_protected_long:Npn" <cs> <parms> "{" <code> "}" +% \end{syntax} +% Naturally robust macro that won't expand in an |x| type argument. +% These varieties also allow |\par| tokens in the arguments of the +% function being defined. +% \end{function} +% +% \begin{function}{\gdef_protected_long:Npn | +% \gdef_protected_long:cpn | +% \gdef_protected_long:Npx | +% \gdef_protected_long:cpx | +% } +% \begin{syntax} +% "\gdef_protected_long:Npn" <cs> <parms> "{" <code> "}" +% \end{syntax} +% Global versions of the above functions. +% \end{function} +% +% +% % \begin{function}{\let:NN | -% \glet:NN | % \let:cN | % \let:Nc | -% \let:cc +% \let:cc | +% \glet:NN | +% \glet:cN | +% \glet:Nc | +% \glet:cc % } % \begin{syntax} % "\let:cN" <cs1> <cs2> @@ -382,7 +989,7 @@ % Gives the function <cs1> the current meaning of <cs2>. Again, we may % always do this globally. % \end{function} -% +% % \begin{function}{\let:NwN} % \begin{syntax} % "\let:NwN" <cs1> <cs2> @@ -399,61 +1006,388 @@ % \end{function} % % +% \subsection{Defining test functions} +% +% +% \begin{function}{ +% \def_test_function:npn | +% \def_long_test_function:npn | +% \def_test_function_new:npn | +% \def_long_test_function_new:npn | +% } +% \begin{syntax} +% "\def_test_function_new:npn" "{"name"}" <parms> "{"<test>"}" +% \end{syntax} +% Define all the common test cases for a simple test to reduce the +% risk of typos. As an example here's how we defined the functions +% "\cs_free:cTF", "\cs_free:cT" and "\cs_free:cF". You just have to +% fill in the test. +% \begin{verbatim} +% \def_test_function:npn{cs_free:c} #1 { +% \exp_after:NN \if_meaning:NN \cs:w#1\cs_end: \scan_stop:} +% \end{verbatim} +% Be careful not to use this function inside some primitive +% conditional as \TeX\ will most likely get confused because of the +% unmatched conditionals. +% \end{function} +% +% +% \subsection{The innards of a function} +% +% \begin{function}{\cs_to_str:N} +% \begin{syntax} +% "\cs_to_str:N" <cs> +% \end{syntax} +% This function return the name of <cs> as a sequence of letters with +% the escape character removed. +% \end{function} +% +% \begin{function}{\token_to_string:N} +% \begin{syntax} +% "\token_to_string:N" <arg> +% \end{syntax} +% This function return the name of <arg> as a sequence of letters +% including the escape character. +% \end{function} +% +% \begin{function}{\token_to_meaning:N} +% \begin{syntax} +% "\token_to_meaning:N" <arg> +% \end{syntax} +% This function returns the type and definition of <arg> as a sequence +% of letters. +% \end{function} +% +% Other functions regarding arbitrary tokens can be found in the +% \textsf{l3token} module. +% +% \subsection{Grouping and scanning} +% +% \begin{function}{\scan_stop:} +% \begin{syntax} +% "\scan_stop:" +% \end{syntax} +% This function stops \TeX's scanning ahead when ending a number. +% \begin{texnote} +% This is the \TeX{} primitive \tn{relax} renamed. +% \end{texnote} +% \end{function} +% +% +% \begin{function}{\group_begin:| +% \group_end:} +% \begin{syntax} +% "\group_begin:" <...> "\group_end:" +% \end{syntax} +% Encloses <...> inside a group. +% \begin{texnote} +% These are the \TeX{} primitives \tn{begingroup} and \tn{endgroup} +% renamed. +% \end{texnote} +% \end{function} +% +% +% \subsection{Engine specific definitions} +% +% \begin{function}{\engine_aleph:TF} +% \begin{syntax} +% "\engine_aleph:TF" "{"<true code>"}" "{"<false code>"}" +% \end{syntax} +% This function detects if we're running an Aleph based format. This +% is particularly useful when allocating registers. +% \end{function} +% +% +% % \StopEventually{} -% -% \section{Renaming some \TeX{} primitives (again)} % +% +% \subsection{The Implementation} +% We start by ensuring that the required packages are loaded. We need +% \textsf{l3names} to get things going but we actually need it very +% early on, so it is loaded at the very top of this file. Also, most +% of the code below won't run until \textsf{l3expan} has been +% loaded. +% +% \subsubsection{Renaming some \TeX{} primitives (again)} +% +% \begin{macro}{\let:NwN} % Having given all the tex primitives a consistent name, we need to % give sensible names to the ones we actually want to use. -% These will be defined as needed in the apropriate modules, but +% These will be defined as needed in the appropriate modules, but % do a few now, just to get started.\footnote{This renaming gets expensive % in terms of csname usage, an alternative scheme would be to just use % the ``tex\ldots D'' name in the cases where no good alternative exists.} % \begin{macrocode} -%<*package> +%<*initex|package> \tex_let:D \let:NwN \tex_let:D -\let:NwN \def:Npn \tex_def:D -\let:NwN \gdef:Npn \tex_gdef:D -\let:NwN \def:Npx \tex_edef:D -\let:NwN \gdef:Npx \tex_xdef:D -\let:NwN \if:w \tex_if:D -\let:NwN \if_num:w \tex_ifnum:D -\let:NwN \if_meaning:NN \tex_ifx:D +% \end{macrocode} +% \end{macro} +% \begin{macro}{\if_true:} +% \begin{macro}{\if_false:} +% \begin{macro}{\else:} +% \begin{macro}{\fi:} +% \begin{macro}{\reverse_if:N} +% \begin{macro}{\if:w} +% \begin{macro}{\if_charcode:w} +% \begin{macro}{\if_catcode:w} +% Then some conditionals. +% \begin{macrocode} +\let:NwN \if_true: \tex_iftrue:D \let:NwN \if_false: \tex_iffalse:D \let:NwN \else: \tex_else:D \let:NwN \fi: \tex_fi:D +\let:NwN \reverse_if:N \etex_unless:D +\let:NwN \if:w \tex_if:D +\let:NwN \if_charcode:w \tex_if:D +\let:NwN \if_catcode:w \tex_ifcat:D +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \begin{macro}{\if_meaning:NN} +% \begin{macro}{\if_token_eq:NN} +% \begin{macro}{\if_cs_meaning_eq:NN} +% Some different names for |\ifx|.\footnote{MH: Clean up at some point} +% \begin{macrocode} +\let:NwN \if_meaning:NN \tex_ifx:D +\let:NwN \if_token_eq:NN \tex_ifx:D +\let:NwN \if_cs_meaning_eq:NN\tex_ifx:D +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \begin{macro}{\if_mode_math:} +% \begin{macro}{\if_mode_horizontal:} +% \begin{macro}{\if_mode_vertical:} +% \begin{macro}{\if_mode_inner:} +% \TeX{} lets us detect some if its modes. +% \begin{macrocode} +\let:NwN \if_mode_math: \tex_ifmmode:D +\let:NwN \if_mode_horizontal:\tex_ifhmode:D +\let:NwN \if_mode_vertical: \tex_ifvmode:D +\let:NwN \if_mode_inner: \tex_ifinner:D +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \begin{macro}{\if_cs_exist:N} +% \begin{macro}{\if_cs_exist:w} +% \begin{macrocode} +\let:NwN \if_cs_exist:N \etex_ifdefined:D +\let:NwN \if_cs_exist:w \etex_ifcsname:D +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\exp_after:NN} +% \begin{macro}{\exp_not:N} +% \begin{macro}{\exp_not:n} +% The three |\exp_| functions are used in the \textsf{l3expan} module +% where they are described. +% \begin{macrocode} +\let:NwN \exp_after:NN \tex_expandafter:D +\let:NwN \exp_not:N \tex_noexpand:D +\let:NwN \exp_not:n \etex_unexpanded:D +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\io_put_deferred:Nx} +% \begin{macro}{\token_to_meaning:N} +% \begin{macro}{\token_to_string:N} +% \begin{macro}{\cs:w} +% \begin{macro}{\cs_end:} +% \begin{macro}{\cs_meaning:N} +% \begin{macro}{\cs_meaning:c} +% \begin{macro}{\cs_show:N} +% \begin{macro}{\cs_show:c} +% \begin{macrocode} \let:NwN \io_put_deferred:Nx \tex_write:D \let:NwN \token_to_meaning:N \tex_meaning:D \let:NwN \token_to_string:N \tex_string:D \let:NwN \cs:w \tex_csname:D \let:NwN \cs_end: \tex_endcsname:D -\let:NwN \exp_after:NN \tex_expandafter:D +\let:NwN \cs_meaning:N \tex_meaning:D +\tex_def:D \cs_meaning:c #1{\exp_after:NN\cs_meaning:N\cs:w #1\cs_end:} +\let:NwN \cs_show:N \tex_show:D +\tex_def:D \cs_show:c #1{\exp_after:NN\cs_show:N\cs:w #1\cs_end:} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \begin{macro}{\scan_stop:} +% \begin{macro}{\group_begin:} +% \begin{macro}{\group_end:} +% The next three are basic functions for which there also exist +% versions that are safe inside alignments. These safe versions are +% defined in the \textsf{l3prg} module. +% \begin{macrocode} \let:NwN \scan_stop: \tex_relax:D -\let:NwN \exp_not:N \tex_noexpand:D \let:NwN \group_begin: \tex_begingroup:D \let:NwN \group_end: \tex_endgroup:D % \end{macrocode} -% +% \end{macro} +% \end{macro} +% \end{macro} +% \begin{macro}{\group_execute_after:N} +% \begin{macrocode} +\let:NwN \group_execute_after:N \tex_aftergroup:D +% \end{macrocode} +% \end{macro} +% \begin{macro}{\the_internal:D} +% \begin{macro}{\pref_global:D} +% \begin{macro}{\pref_long:D} +% \begin{macro}{\pref_protected:D} % These following names are temporary and should be removed as soon % as possible (April 1998). % \begin{macrocode} \let:NwN \the_internal:D \tex_the:D \let:NwN \pref_global:D \tex_global:D % \end{macrocode} +% "\pref_long:D" has been documented for years but didn't exist\dots{} +% Added it and the robustness prefix. +% \begin{macrocode} +\let:NwN \pref_long:D \tex_long:D +\let:NwN \pref_protected:D \etex_protected:D +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% +% \subsubsection {Defining functions} +% +% +% We start by providing functions for the typical definition +% functions. First the local ones. +% +% \begin{macro}{\def:Npn} +% \begin{macro}{\def:Npx} +% \begin{macro}{\def_long:Npn} +% \begin{macro}{\def_long:Npx} +% \begin{macro}{\def_protected:Npn} +% \begin{macro}{\def_protected:Npx} +% \begin{macro}{\def_protected_long:Npn} +% \begin{macro}{\def_protected_long:Npx} +% All assignment functions in \LaTeX3 should be naturally robust; +% after all, the \TeX\ primitives for assignments are and it can be +% a cause of problems if others aren't. +% \begin{macrocode} +\let:NwN \def:Npn \tex_def:D +\let:NwN \def:Npx \tex_edef:D +\pref_protected:D \def:Npn \def_long:Npn {\pref_long:D \def:Npn} +\pref_protected:D \def:Npn \def_long:Npx {\pref_long:D \def:Npx} +\pref_protected:D \def:Npn \def_protected:Npn {\pref_protected:D \def:Npn} +\pref_protected:D \def:Npn \def_protected:Npx {\pref_protected:D \def:Npx} +\def_protected:Npn \def_protected_long:Npn { + \pref_protected:D \pref_long:D \def:Npn +} +\def_protected:Npn \def_protected_long:Npx { + \pref_protected:D \pref_long:D \def:Npx +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} % -% -% \section {Defining and checking (new) functions} +% \begin{macro}{\gdef:Npn} +% \begin{macro}{\gdef:Npx} +% \begin{macro}{\gdef_long:Npn} +% \begin{macro}{\gdef_long:Npx} +% \begin{macro}{\gdef_protected:Npn} +% \begin{macro}{\gdef_protected:Npx} +% \begin{macro}{\gdef_protected_long:Npn} +% \begin{macro}{\gdef_protected_long:Npx} +% Global versions of the above functions. +% \begin{macrocode} +\let:NwN \gdef:Npn \tex_gdef:D +\let:NwN \gdef:Npx \tex_xdef:D +\def_protected:Npn \gdef_long:Npn {\pref_long:D \gdef:Npn} +\def_protected:Npn \gdef_long:Npx {\pref_long:D \gdef:Npx} +\def_protected:Npn \gdef_protected:Npn {\pref_protected:D \gdef:Npn} +\def_protected:Npn \gdef_protected:Npx {\pref_protected:D \gdef:Npx} +\def_protected:Npn \gdef_protected_long:Npn { + \pref_protected:D \pref_long:D \gdef:Npn +} +\def_protected:Npn \gdef_protected_long:Npx { + \pref_protected:D \pref_long:D \gdef:Npx +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \subsubsection{Predicate implementation} % -% We need some constants now, that should actually all be defined -% together. We try to avoid using count registers for constants as -% much as possible. +% I think Michael originated the idea of expandable boolean tests. At +% first these were supposed to expand into either \texttt{TT} or +% \texttt{TF} to be tested using |\if:w| but this was later changed to +% \texttt{00} and \texttt{01}, so they can be used in logical +% operations (see the \textsf{l3prg} module). We need this from the +% get-go. % +% \begin{macro}{\c_true} +% \begin{macro}{\c_false} +% Here are the canonical boolean values. % \begin{macrocode} -\let:NwN\c_minus_one\m@ne -\tex_chardef:D \c_one = 1\scan_stop: +\def:Npn \c_true {00} +\def:Npn \c_false {01} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \subsubsection {Defining and checking (new) functions} +% +% \begin{macro}{\c_minus_one} +% \begin{macro}{\c_sixteen} +% We need the constants |\c_minus_one| and |\c_sixteen| now for +% writing information to the log and the terminal but the +% rest are defined in the \textsf{l3num} module -- at least for the +% ones that can be defined with |\tex_chardef:D| or +% |\tex_mathchardef:D|. Otherwise the \textsf{l3int} module is +% required but it can't be used until the allocation has been set +% up properly! The actual allocation mechanism is in +% \textsf{l3alloc} and as \TeX{} wants to reserve count registers +% 0--9, the first available one is~10 so we use that for +% |\c_minus_one|. +% \begin{macrocode} +%<*!initex> +\let:NwN \c_minus_one\m@ne +%</!initex> +%<*!package> +\tex_countdef:D \c_minus_one = 10 \scan_stop: +\c_minus_one = -1 \scan_stop: +%</!package> \tex_chardef:D \c_sixteen = 16\scan_stop: -\tex_mathchardef:D \c_two_hundred_fifty_six = 256\scan_stop: % \end{macrocode} +% \end{macro} +% \end{macro} % % We provide two kinds of functions that can be used to define % control sequences. On the one hand we have functions that check @@ -462,11 +1396,11 @@ % if the argument is already defined. % % Before we can define them, we need some auxiliary macros that -% allow us to generate error messages. The definitions here are +% allow us to generate error messages. The definitions here are % only temporary, they will be redefined later on. % -% \begin{macro}{\io_put_log:x} -% \begin{macro}{\io_put_term:x} +% \begin{macro}{\io_put_log:x} +% \begin{macro}{\io_put_term:x} % We define a routine to write only to the log file. And a % similar one for writing to both the log file and the terminal. % @@ -476,18 +1410,18 @@ \def:Npn \io_put_term:x{ \tex_immediate:D\io_put_deferred:Nx \c_sixteen } % \end{macrocode} -% \end{macro} -% \end{macro} +% \end{macro} +% \end{macro} % -% \begin{macro}{\err_latex_bug:n} +% \begin{macro}{\err_latex_bug:x} % This will show internal errors. % \begin{macrocode} -\def:Npn\err_latex_bug:n#1{ +\def:Npn\err_latex_bug:x#1{ \io_put_term:x{This~is~a~LaTeX~bug!~Check~coding!}\tex_errmessage:D{#1}} % \end{macrocode} % \end{macro} % -% \begin{macro}{\cs_record_meaning:N} +% \begin{macro}{\cs_record_meaning:N} % This macro will be used later on for tracing purposes. But we % need some more modules to define it, so we just give some dummy % definition here. @@ -496,241 +1430,894 @@ \def:Npn \cs_record_meaning:N#1{} %</trace> % \end{macrocode} -% \end{macro} -% -% \subsection{Checking new definitions} +% \end{macro} % +% We need these two to make |\chk_new_cs:N| bulletproof. +% \begin{macrocode} +\def_long:Npn \use_none:n #1{} +\def_long:Npn \use_arg_i:n #1{#1} +% \end{macrocode} % \begin{macro}{\chk_new_cs:N} -% This command is called by |\def_new:Npn| and |\let_new:NN| etc.\ -% to make sure that the argument sequence is not already in use. If -% it is, an error is signalled. -% It checks if \m{csname} is undefined or -% |\scan_stop:|. Otherwise an error message is issued. +% This command is called by |\def_new:Npn| and |\let_new:NN| etc.\ +% to make sure that the argument sequence is not already in use. If +% it is, an error is signalled. It checks if \m{csname} is +% undefined or |\scan_stop:|. Otherwise an error message is +% issued. We have to make sure we don't put the argument into the +% conditional processing since it may be an |\if...| type function! % \begin {macrocode} \def:Npn \chk_new_cs:N #1{ - \if_meaning:NN #1\c_undefined - \else: - \if_meaning:NN #1\scan_stop: - \else: - \err_latex_bug:n {Command~name~`\token_to_string:N #1'~ - already~defined!~ - Current~meaning:~\token_to_meaning:N #1 - } - \fi: - \fi: + \if:w \cs_if_free_p:N #1 + \exp_after:NN \use_none:n + \else: + \exp_after:NN \use_arg_i:n + \fi: + { + \err_latex_bug:x {Command~name~`\token_to_string:N #1'~ + already~defined!~ + Current~meaning:~\token_to_meaning:N #1 + } + } %<*trace> - \cs_record_meaning:N#1 -% \io_put_term:x{Defining~\token_to_string:N #1~on~ - \io_put_log:x{Defining~\token_to_string:N #1~on~ - line~\tex_the:D \tex_inputlineno:D} + \cs_record_meaning:N#1 +% \io_put_term:x{Defining~\token_to_string:N #1~on~%} + \io_put_log:x{Defining~\token_to_string:N #1~on~ + line~\tex_the:D \tex_inputlineno:D} %</trace> - } +} % \end{macrocode} -% \end {macro} +% \end{macro} % -% \begin{macro}{\cs_exist_p:N} -% Expands into |\c_true| if the control sequence given as its -% argument {\em is} in use. +% On 2005/11/20 Morten said: I think names for testing if a certain +% condition is true or false should always contain |if| to avoid +% confusion. This is what we do for lots of other types of test +% functions. For now I have defined both names for the functions +% checking names of control sequences. % +% \begin{macro}{\cs_if_exist_p:N} +% Expands into |\c_true| if the control sequence given as its +% argument \emph{is} in use. % \begin{macrocode} -\def:Npn \cs_exist_p:N #1{ - \if:w \cs_free_p:N #1 +\def:Npn \cs_if_exist_p:N #1{ + \if:w \cs_if_free_p:N #1 \c_false \else: \c_true \fi:} % \end{macrocode} % \end{macro} % -% \begin{macro}{\chk_exist_cs:N } -% This function issues a warning message when the control sequence +% \begin{macro}{\chk_if_exist_cs:N } +% \begin{macro}{\chk_if_exist_cs:c } +% This function issues a warning message when the control sequence % in its argument does not exist. % \begin{macrocode} -\def:Npn \chk_exist_cs:N #1 { - \if:w \cs_exist_p:N #1 +\def:Npn \chk_if_exist_cs:N #1 { + \if:w \cs_if_exist_p:N #1 \else: - \err_latex_bug:n{Command~ `\token_to_string:N #1'~ + \err_latex_bug:x{Command~ `\token_to_string:N #1'~ not~ yet~ defined!} \fi:} +\def:Npn \chk_if_exist_cs:c #1 { + \exp_after:NN \chk_if_exist_cs:N \cs:w #1\cs_end: } % \end{macrocode} % \end{macro} +% \end{macro} % -% \begin{macro}{\cs_free_p:N} +% \begin{macro}{\cs_if_free_p:N} % Expands into |\c_true| if the control sequence given as its % argument is not yet in use. Note that we make sure to expand -% into |\c_false | if the control sequence is textually +% into |\c_false| if the control sequence is textually % |\c_undefined| or |\scan_stop:|, so that we don't end up % (re)defining them. % \begin{macrocode} -\def:Npn \cs_free_p:N #1{ - \if_meaning:NN#1\c_undefined - \if:w\cs_eq_p:NN #1\c_undefined \c_false - \else: \c_true \fi: - \else: +\def:Npn \cs_if_free_p:N #1{ + \if_cs_exist:N #1 \if_meaning:NN#1\scan_stop: - \if:w\cs_eq_p:NN #1\scan_stop: \c_false - \else: \c_true \fi: - \else: - \c_false \fi:\fi:} + \if:w\cs_if_eq_name_p:NN #1\scan_stop: + \c_false \else: \c_true \fi: + \else: + \c_false + \fi: + \else: + \if:w \cs_if_eq_name_p:NN #1\c_undefined + \c_false \else: \c_true \fi: + \fi: +} +\let:NwN \cs_free_p:N \cs_if_free_p:N % \end{macrocode} % \end{macro} % -% \subsection{More new definitions} % -% \begin{macro}{\let:NN} -% \begin{macro}{\let:cN} -% \begin{macro}{\let:Nc} -% \begin{macro}{\let:cc} -% These macros allow us to copy the definition of a control sequence -% to another control sequence. Maybe we should implement a few more -% of these. +% \begin{macro}{\str_if_eq_p:nn} +% \begin{macro}{\str_if_eq_p_aux:w} +% Takes 2 lists of characters as arguments and expands into +% |\c_true| if they are equal, and |\c_false| otherwise. Note that +% in the current implementation spaces in these strings are +% ignored.\footnote{This is a function which could use +% \cs{tlist_compare:xx}.} +% \begin{macrocode} +\def:Npn \str_if_eq_p:nn #1#2{ + \str_if_eq_p_aux:w #1\scan_stop:\\#2\scan_stop:\\ +} +\def:Npn \str_if_eq_p_aux:w #1#2\\#3#4\\{ + \if_meaning:NN#1#3 + \if_meaning:NN#1\scan_stop:\c_true \else: + \if_meaning:NN#3\scan_stop:\c_false \else: + \str_if_eq_p_aux:w #2\\#4\\\fi:\fi: + \else:\c_false \fi:} +% \end{macrocode} +% \end{macro} +% \end{macro} % +% \begin{macro}{\cs_if_eq_name_p:NN} +% An application of the above function, already streamlined for +% speed, so I put it in here. It takes two control sequences as +% arguments and expands into true iff they have the same name. +% We make it long in case one of them is |\par|! % \begin{macrocode} -\tex_long:D\def:Npn \let:NN #1{ +\def_long:Npn \cs_if_eq_name_p:NN #1#2{ + \exp_after:NN\exp_after:NN + \exp_after:NN\str_if_eq_p_aux:w + \exp_after:NN\token_to_string:N + \exp_after:NN#1 + \exp_after:NN\scan_stop: + \exp_after:NN\\ + \token_to_string:N#2\scan_stop:\\} % \end{macrocode} -% The |=| sign allows us to define funny char tokens like .|=| -% itself or \verb*= = with this function. For the definition of -% |\c_space_chartok{~}| to work we need the |~| after the |=| +% \end{macro} +% % +% \begin{macro}{\str_if_eq_var_p:nf} +% \begin{macro}{\str_if_eq_var_start:nnN} +% \begin{macro}{\str_if_eq_var_stop:w} +% A variant of |\str_if_eq_p:nn| which has the advantage of obeying +% spaces in at least the second argument. See \textsf{l3quark} for +% an application. From the hand of David Kastrup with slight +% modifications to make it fit with the remainder of the expl3 +% language. +% +% The macro builds a string of |\if:w \fi:| pairs from the first +% argument. The idea is to turn the comparison of |ab| and |cde| +% into +% \begin{verbatim} +% \tex_number:D +% \if:w \scan_stop: \if:w b\if:w a cde\scan_stop: '\fi: \fi: \fi: +% 13 +% \end{verbatim} +% The |'| is important here. If all tests are true, the |'| is read +% as part of the number in which case the returned number is |13| in +% octal notation so |\tex_number:D| returns |11|. If one test +% returns false the |'| is never seen and then we get just |13|. We +% wrap the whole process in an external |\if:w| in order to make it +% return either |\c_true| or |\c_false| since some parts of +% \textsf{l3prg} expect a predicate to return one of these two +% tokens. % \begin{macrocode} - \let:NwN #1=~} -\def:Npn\let:cN #1 {\exp_after:NN\let:NwN\cs:w#1\cs_end:=~} -\def:Npn\let:Nc{\exp_args:NNc\let:NN} -\def:Npn\let:cc{\exp_args:Ncc\let:NN} -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% -% -% \begin {macro}{\def_new:Npn} -% \begin {macro}{\def_new:Npx} -% \begin {macro}{\let_new:NN} -% These are like |\def:Npn| and |\let:NN|, but they first check that -% the argument command is not already in use. You may use -% |\tex_global:D|, |\tex_long:D|, and |\tex_outer:D| as -% prefixes. +\def:Npn \str_if_eq_var_p:nf#1{ + \if:w \tex_number:D\str_if_eq_var_start:nnN{}{}#1\scan_stop: +} +\def:Npn\str_if_eq_var_start:nnN#1#2#3{ + \if:w#3\scan_stop:\exp_after:NN\str_if_eq_var_stop:w\fi: + \str_if_eq_var_start:nnN{\if:w#3#1}{#2\fi:} +} +\def:Npn\str_if_eq_var_stop:w\str_if_eq_var_start:nnN#1#2#3{ + #1#3\scan_stop:'#213~\c_true\else:\c_false\fi: +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% +% +% \subsubsection{More new definitions} +% +% +% +% \begin{macro}{\def_new:Npn} +% \begin{macro}{\def_new:Npx} +% \begin{macro}{\def_long_new:Npn} +% \begin{macro}{\def_long_new:Npx} +% \begin{macro}{\def_protected_new:Npn} +% \begin{macro}{\def_protected_new:Npx} +% \begin{macro}{\def_protected_long_new:Npn} +% \begin{macro}{\def_protected_long_new:Npx} +% These are like |\def:Npn| and |\let:NN|, but they first check that +% the argument command is not already in use. You may use +% |\pref_global:D|, |\pref_long:D|, |\pref_protected:D|, and +% |\tex_outer:D| as prefixes. % \begin {macrocode} -\def:Npn \def_new:Npn #1{\chk_new_cs:N #1 +\def_protected:Npn \def_new:Npn #1{\chk_new_cs:N #1 \def:Npn #1} -\def:Npn \def_new:Npx #1{\chk_new_cs:N #1 +\def_protected:Npn \def_new:Npx #1{\chk_new_cs:N #1 \def:Npx #1} -\def_new:Npn \let_new:NN #1{\chk_new_cs:N #1 - \let:NN #1} +\def_protected:Npn \def_long_new:Npn #1{\chk_new_cs:N #1 + \def_long:Npn #1} +\def_protected:Npn \def_long_new:Npx #1{\chk_new_cs:N #1 + \def_long:Npx #1} +\def_protected:Npn \def_protected_new:Npn #1{\chk_new_cs:N #1 + \def_protected:Npn #1} +\def_protected:Npn \def_protected_new:Npx #1{\chk_new_cs:N #1 + \def_protected:Npx #1} +\def_protected:Npn \def_protected_long_new:Npn #1{\chk_new_cs:N #1 + \def_protected_long:Npn #1} +\def_protected:Npn \def_protected_long_new:Npx #1{\chk_new_cs:N #1 + \def_protected_long:Npx #1} % \end{macrocode} -% \end {macro} -% \end {macro} -% \end {macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\gdef_new:Npn} +% \begin{macro}{\gdef_new:Npx} +% \begin{macro}{\gdef_long_new:Npn} +% \begin{macro}{\gdef_long_new:Npx} +% \begin{macro}{\gdef_protected_new:Npn} +% \begin{macro}{\gdef_protected_new:Npx} +% \begin{macro}{\gdef_protected_long_new:Npn} +% \begin{macro}{\gdef_protected_long_new:Npx} +% Global versions of the above functions. +% \begin {macrocode} +\def_protected_new:Npn \gdef_new:Npn #1{\chk_new_cs:N #1 + \gdef:Npn #1} +\def_protected_new:Npn \gdef_new:Npx #1{\chk_new_cs:N #1 + \gdef:Npx #1} +\def_protected_new:Npn \gdef_long_new:Npn #1{\chk_new_cs:N #1 + \gdef_long:Npn #1} +\def_protected_new:Npn \gdef_long_new:Npx #1{\chk_new_cs:N #1 + \gdef_long:Npx #1} +\def_protected_new:Npn \gdef_protected_new:Npn #1{\chk_new_cs:N #1 + \gdef_protected:Npn #1} +\def_protected_new:Npn \gdef_protected_new:Npx #1{\chk_new_cs:N #1 + \gdef_protected:Npx #1} +\def_protected_new:Npn \gdef_protected_long_new:Npn #1{\chk_new_cs:N #1 + \gdef_protected_long:Npn #1} +\def_protected_new:Npn \gdef_protected_long_new:Npx #1{\chk_new_cs:N #1 + \gdef_protected_long:Npx #1} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} % -% \begin {macro}{\def:cpn} -% \begin {macro}{\def:cpx} -% \begin {macro}{\def_new:cpn} -% \begin {macro}{\def_new:cpx} -% Like |\def:Npn| and |\def_new:Npn|, except that the first -% argument consists of the sequence of characters that should be -% used to form the name of the desired control sequence ( the |c| -% stands for csname argument, see the expansion module.). +% +% \begin{macro}{\def:cpn} +% \begin{macro}{\def:cpx} +% \begin{macro}{\gdef:cpn} +% \begin{macro}{\gdef:cpx} +% \begin{macro}{\def_new:cpn} +% \begin{macro}{\def_new:cpx} +% \begin{macro}{\gdef_new:cpn} +% \begin{macro}{\gdef_new:cpx} +% Like |\def:Npn| and |\def_new:Npn|, except that the first argument +% consists of the sequence of characters that should be used to form +% the name of the desired control sequence (the |c| stands for +% csname argument, see the expansion module.). Global versions are +% also provided. % % |\def:cpn|\m{string}\m{rep-text} will turn \m{string} into a % csname and then assign \m {rep-text} to it by using |\def:Npn|. % This means that there might be a parameter string between the two % arguments. -% \begin {macrocode} -\def_new:Npn \def:cpn #1{\exp_after:NN - \def:Npn - \cs:w #1\cs_end:} -\def_new:Npn \def:cpx #1{\exp_after:NN - \def:Npx - \cs:w #1\cs_end:} -\def_new:Npn \def_new:cpn #1{\exp_after:NN - \def_new:Npn - \cs:w #1\cs_end:} -\def_new:Npn \def_new:cpx #1{\exp_after:NN - \def_new:Npx - \cs:w #1\cs_end:} -% \end{macrocode} -% \end {macro} -% \end {macro} -% \end {macro} -% \end {macro} -% -% -% \begin{macro}{\def:No} -% |\def:No| expands its second argument one time before making -% the definition. % \begin{macrocode} -\def_new:Npn \def:No{\exp_args:NNo\def:Npn} +\def_new:Npn \def:cpn #1{\exp_after:NN \def:Npn \cs:w #1\cs_end:} +\def_new:Npn \def:cpx #1{\exp_after:NN \def:Npx \cs:w #1\cs_end:} +\def_new:Npn \gdef:cpn #1{\exp_after:NN \gdef:Npn \cs:w #1\cs_end:} +\def_new:Npn \gdef:cpx #1{\exp_after:NN \gdef:Npx \cs:w #1\cs_end:} +\def_new:Npn \def_new:cpn #1{\exp_after:NN \def_new:Npn \cs:w #1\cs_end:} +\def_new:Npn \def_new:cpx #1{\exp_after:NN \def_new:Npx \cs:w #1\cs_end:} +\def_new:Npn \gdef_new:cpn #1{\exp_after:NN \gdef_new:Npn \cs:w #1\cs_end:} +\def_new:Npn \gdef_new:cpx #1{\exp_after:NN \gdef_new:Npx \cs:w #1\cs_end:} % \end{macrocode} -% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} % -% \begin {macro}{\def_long:Npn} -% \begin {macro}{\def_long_new:Npn} -% \begin {macro}{\def_long:cpn} -% \begin {macro}{\def_long:Npx} -% |\def_long:Npn| stands for |\tex_long:D| |\def:Npn|. -% |\def_long:Npx| expands its second argument. -% \begin {macrocode} -\def_new:Npn \def_long:Npn {\tex_long:D\def:Npn} -\def_new:Npn \def_long_new:Npn #1{\chk_new_cs:N #1 - \def_long:Npn #1} -\def_new:Npn \def_long:cpn #1{\exp_after:NN - \def_long:Npn - \cs:w #1\cs_end:} -\def_new:Npn \def_long:Npx {\tex_long:D\def:Npx} -% \end{macrocode} -% \end {macro} -% \end {macro} -% \end {macro} -% \end {macro} -% -% \begin {macro}{\glet:NN} -% \begin {macro}{\glet_new:NN} -% \begin {macro}{\gdef_new:Npn} -% \begin {macro}{\gdef:cpn} -% \begin {macro}{\gdef:cpx} -% \begin {macro}{\gdef:No} -% These are global versions of some of the previosly defined functions. -% \begin {macrocode} -\def_new:Npn \glet:NN {\tex_global:D \let:NN} +% +% +% \begin{macro}{\def_long:cpn} +% \begin{macro}{\def_long:cpx} +% \begin{macro}{\gdef_long:cpn} +% \begin{macro}{\gdef_long:cpx} +% \begin{macro}{\def_long_new:cpn} +% \begin{macro}{\def_long_new:cpx} +% \begin{macro}{\gdef_long_new:cpn} +% \begin{macro}{\gdef_long_new:cpx} +% Variants of the |\def_long:Npn| versions which make a csname out +% of the first arguments. We may also do this globally. +% \begin{macrocode} +\def_new:Npn \def_long:cpn #1{\exp_after:NN \def_long:Npn \cs:w #1\cs_end:} +\def_new:Npn \def_long:cpx #1{ + \exp_after:NN\def_long:Npx\cs:w #1\cs_end:} +\def_new:Npn \gdef_long:cpn #1{ + \exp_after:NN \gdef_long:Npn \cs:w #1\cs_end:} +\def_new:Npn \gdef_long:cpx #1{ + \exp_after:NN\gdef_long:Npx\cs:w #1\cs_end:} +\def_new:Npn \def_long_new:cpn #1{ + \exp_after:NN \def_long_new:Npn \cs:w #1\cs_end:} +\def_new:Npn \def_long_new:cpx #1{ + \exp_after:NN \def_long_new:Npx \cs:w #1\cs_end:} +\def_new:Npn \gdef_long_new:cpn #1{ + \exp_after:NN \gdef_long_new:Npn \cs:w #1\cs_end:} +\def_new:Npn \gdef_long_new:cpx #1{ + \exp_after:NN \gdef_long_new:Npx \cs:w #1\cs_end:} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\def_protected:cpn} +% \begin{macro}{\def_protected:cpx} +% \begin{macro}{\gdef_protected:cpn} +% \begin{macro}{\gdef_protected:cpx} +% \begin{macro}{\def_protected_new:cpn} +% \begin{macro}{\def_protected_new:cpx} +% \begin{macro}{\gdef_protected_new:cpn} +% \begin{macro}{\gdef_protected_new:cpx} +% Variants of the |\def_protected:Npn| versions which make a csname +% out of the first arguments. We may also do this globally. +% \begin{macrocode} +\def_new:Npn \def_protected:cpn #1{ + \exp_after:NN \def_protected:Npn \cs:w #1\cs_end:} +\def_new:Npn \def_protected:cpx #1{ + \exp_after:NN\def_protected:Npx\cs:w #1\cs_end:} +\def_new:Npn \gdef_protected:cpn #1{ + \exp_after:NN \gdef_protected:Npn \cs:w #1\cs_end:} +\def_new:Npn \gdef_protected:cpx #1{ + \exp_after:NN\gdef_protected:Npx\cs:w #1\cs_end:} +\def_new:Npn \def_protected_new:cpn #1{ + \exp_after:NN \def_protected_new:Npn \cs:w #1\cs_end:} +\def_new:Npn \def_protected_new:cpx #1{ + \exp_after:NN \def_protected_new:Npx \cs:w #1\cs_end:} +\def_new:Npn \gdef_protected_new:cpn #1{ + \exp_after:NN \gdef_protected_new:Npn \cs:w #1\cs_end:} +\def_new:Npn \gdef_protected_new:cpx #1{ + \exp_after:NN \gdef_protected_new:Npx \cs:w #1\cs_end:} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\def_protected_long:cpn} +% \begin{macro}{\def_protected_long:cpx} +% \begin{macro}{\gdef_protected_long:cpn} +% \begin{macro}{\gdef_protected_long:cpx} +% \begin{macro}{\def_protected_long_new:cpn} +% \begin{macro}{\def_protected_long_new:cpx} +% \begin{macro}{\gdef_protected_long_new:cpn} +% \begin{macro}{\gdef_protected_long_new:cpx} +% Variants of the |\def_protected_long:Npn| versions which make a csname +% out of the first arguments. We may also do this globally. +% \begin{macrocode} +\def_new:Npn \def_protected_long:cpn #1{ + \exp_after:NN \def_protected_long:Npn \cs:w #1\cs_end:} +\def_new:Npn \def_protected_long:cpx #1{ + \exp_after:NN\def_protected_long:Npx\cs:w #1\cs_end:} +\def_new:Npn \gdef_protected_long:cpn #1{ + \exp_after:NN \gdef_protected_long:Npn \cs:w #1\cs_end:} +\def_new:Npn \gdef_protected_long:cpx #1{ + \exp_after:NN\gdef_protected_long:Npx\cs:w #1\cs_end:} +\def_new:Npn \def_protected_long_new:cpn #1{ + \exp_after:NN \def_protected_long_new:Npn \cs:w #1\cs_end:} +\def_new:Npn \def_protected_long_new:cpx #1{ + \exp_after:NN \def_protected_long_new:Npx \cs:w #1\cs_end:} +\def_new:Npn \gdef_protected_long_new:cpn #1{ + \exp_after:NN \gdef_protected_long_new:Npn \cs:w #1\cs_end:} +\def_new:Npn \gdef_protected_long_new:cpx #1{ + \exp_after:NN \gdef_protected_long_new:Npx \cs:w #1\cs_end:} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\def_aux_0:NNn} +% \begin{macro}{\def_aux_1:NNn} +% \begin{macro}{\def_aux_2:NNn} +% \begin{macro}{\def_aux_3:NNn} +% \begin{macro}{\def_aux_4:NNn} +% \begin{macro}{\def_aux_5:NNn} +% \begin{macro}{\def_aux_6:NNn} +% \begin{macro}{\def_aux_7:NNn} +% \begin{macro}{\def_aux_8:NNn} +% \begin{macro}{\def_aux_9:NNn} +% \begin{macro}{\def_aux:NNnn} +% \begin{macro}{\def_aux:Ncnn} +% \begin{macro}{\def_arg_number_error_msg:Nn} +% Defining a function with $n$ arguments. First some helper functions. +% \begin{macrocode} +\def_new:cpn {def_aux_0:NNn} #1#2 {#1 #2 } +\def_new:cpn {def_aux_1:NNn} #1#2 {#1 #2 ##1 } +\def_new:cpn {def_aux_2:NNn} #1#2 {#1 #2 ##1##2 } +\def_new:cpn {def_aux_3:NNn} #1#2 {#1 #2 ##1##2##3 } +\def_new:cpn {def_aux_4:NNn} #1#2 {#1 #2 ##1##2##3##4 } +\def_new:cpn {def_aux_5:NNn} #1#2 {#1 #2 ##1##2##3##4##5 } +\def_new:cpn {def_aux_6:NNn} #1#2 {#1 #2 ##1##2##3##4##5##6 } +\def_new:cpn {def_aux_7:NNn} #1#2 {#1 #2 ##1##2##3##4##5##6##7 } +\def_new:cpn {def_aux_8:NNn} #1#2 {#1 #2 ##1##2##3##4##5##6##7##8 } +\def_new:cpn {def_aux_9:NNn} #1#2 {#1 #2 ##1##2##3##4##5##6##7##8##9 } +% \end{macrocode} +% Then the function itself which checks for the existance of such a +% helper function. If it doesn't exist, return an error. Otherwise +% call it to define \verb|#2| with the correct number of arguments. +% \begin{macrocode} +\def_protected_long_new:Npn \def_aux:NNnn #1#2#3#4 { + \cs_if_really_exist:cTF {def_aux_\tex_the:D\etex_numexpr:D #3 :NNn} + { + \cs_use:c {def_aux_\tex_the:D\etex_numexpr:D #3 :NNn} #1 #2 {#4} + } + { \def_arg_number_error_msg:Nn #2{#3} } +} +\def_new:Npn \def_aux:Ncnn #1#2{ + \exp_after:NN \def_aux:NNnn \exp_after:NN #1 \cs:w #2\cs_end:} +% \end{macrocode} +% The error message. +% \begin{macrocode} +\def_new:Npn \def_arg_number_error_msg:Nn #1#2 { + \err_latex_bug:x{ + You're~ trying~ to~ define~ the~ command~ `\token_to_string:N #1'~ + with~ \use_arg_i:n{\tex_the:D\etex_numexpr:D #2\scan_stop:} ~ + arguments~ but~ I~ only~ allow~ 0-9~ arguments.~ I~ can~ probably~ + not~ help~ you~ here + } +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\def_aux_use_0_parameter:} +% \begin{macro}{\def_aux_use_1_parameter:} +% \begin{macro}{\def_aux_use_2_parameter:} +% \begin{macro}{\def_aux_use_3_parameter:} +% \begin{macro}{\def_aux_use_4_parameter:} +% \begin{macro}{\def_aux_use_5_parameter:} +% \begin{macro}{\def_aux_use_6_parameter:} +% \begin{macro}{\def_aux_use_7_parameter:} +% \begin{macro}{\def_aux_use_8_parameter:} +% \begin{macro}{\def_aux_use_9_parameter:} +% Something similar to |\def_aux_9:NNn| but for using the +% parameters. +% \begin{macrocode} +\def:cpn{def_aux_use_0_parameter:}{} +\def:cpn{def_aux_use_1_parameter:}{{##1}} +\def:cpn{def_aux_use_2_parameter:}{{##1}{##2}} +\def:cpn{def_aux_use_3_parameter:}{{##1}{##2}{##3}} +\def:cpn{def_aux_use_4_parameter:}{{##1}{##2}{##3}{##4}} +\def:cpn{def_aux_use_5_parameter:}{{##1}{##2}{##3}{##4}{##5}} +\def:cpn{def_aux_use_6_parameter:}{{##1}{##2}{##3}{##4}{##5}{##6}} +\def:cpn{def_aux_use_7_parameter:}{{##1}{##2}{##3}{##4}{##5}{##6}{##7}} +\def:cpn{def_aux_use_8_parameter:}{ + {##1}{##2}{##3}{##4}{##5}{##6}{##7}{##8}} +\def:cpn{def_aux_use_9_parameter:}{ + {##1}{##2}{##3}{##4}{##5}{##6}{##7}{##8}{##9}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\def:NNn} +% \begin{macro}{\def:NNx} +% \begin{macro}{\def:cNn} +% \begin{macro}{\def:cNx} +% \begin{macro}{\gdef:NNn} +% \begin{macro}{\gdef:NNx} +% \begin{macro}{\gdef:cNn} +% \begin{macro}{\gdef:cNx} +% \begin{macro}{\def_new:NNn} +% \begin{macro}{\def_new:NNx} +% \begin{macro}{\def_new:cNn} +% \begin{macro}{\def_new:cNx} +% \begin{macro}{\gdef_new:NNn} +% \begin{macro}{\gdef_new:NNx} +% \begin{macro}{\gdef_new:cNn} +% \begin{macro}{\gdef_new:cNx} +% Defining macros without delimited arguments is now relatively +% easy. First local and global versions of the usual |\def:Npn| +% operation. +% \begin{macrocode} +\def_new:Npn \def:NNn { \def_aux:NNnn \def:Npn } +\def_new:Npn \def:NNx { \def_aux:NNnn \def:Npx } +\def_new:Npn \def:cNn { \def_aux:Ncnn \def:Npn } +\def_new:Npn \def:cNx { \def_aux:Ncnn \def:Npx } +\def_new:Npn \gdef:NNn { \def_aux:NNnn \gdef:Npn } +\def_new:Npn \gdef:NNx { \def_aux:NNnn \gdef:Npx } +\def_new:Npn \gdef:cNn { \def_aux:Ncnn \gdef:Npn } +\def_new:Npn \gdef:cNx { \def_aux:Ncnn \gdef:Npx } +\def_new:Npn \def_new:NNn { \def_aux:NNnn \def_new:Npn } +\def_new:Npn \def_new:NNx { \def_aux:NNnn \def_new:Npx } +\def_new:Npn \def_new:cNn { \def_aux:Ncnn \def_new:Npn } +\def_new:Npn \def_new:cNx { \def_aux:Ncnn \def_new:Npx } +\def_new:Npn \gdef_new:NNn { \def_aux:NNnn \gdef_new:Npn } +\def_new:Npn \gdef_new:NNx { \def_aux:NNnn \gdef_new:Npx } +\def_new:Npn \gdef_new:cNn { \def_aux:Ncnn \gdef_new:Npn } +\def_new:Npn \gdef_new:cNx { \def_aux:Ncnn \gdef_new:Npx } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\def_long:NNn} +% \begin{macro}{\def_long:NNx} +% \begin{macro}{\def_long:cNn} +% \begin{macro}{\def_long:cNx} +% \begin{macro}{\gdef_long:NNn} +% \begin{macro}{\gdef_long:NNx} +% \begin{macro}{\gdef_long:cNn} +% \begin{macro}{\gdef_long:cNx} +% \begin{macro}{\def_long_new:NNn} +% \begin{macro}{\def_long_new:NNx} +% \begin{macro}{\def_long_new:cNn} +% \begin{macro}{\def_long_new:cNx} +% \begin{macro}{\gdef_long_new:NNn} +% \begin{macro}{\gdef_long_new:NNx} +% \begin{macro}{\gdef_long_new:cNn} +% \begin{macro}{\gdef_long_new:cNx} +% Long versions of the above. +% \begin{macrocode} +\def_new:Npn \def_long:NNn { \def_aux:NNnn \def_long:Npn } +\def_new:Npn \def_long:NNx { \def_aux:NNnn \def_long:Npx } +\def_new:Npn \def_long:cNn { \def_aux:Ncnn \def_long:Npn } +\def_new:Npn \def_long:cNx { \def_aux:Ncnn \def_long:Npx } +\def_new:Npn \gdef_long:NNn { \def_aux:NNnn \gdef_long:Npn } +\def_new:Npn \gdef_long:NNx { \def_aux:NNnn \gdef_long:Npx } +\def_new:Npn \gdef_long:cNn { \def_aux:Ncnn \gdef_long:Npn } +\def_new:Npn \gdef_long:cNx { \def_aux:Ncnn \gdef_long:Npx } +\def_new:Npn \def_long_new:NNn { \def_aux:NNnn \def_long_new:Npn } +\def_new:Npn \def_long_new:NNx { \def_aux:NNnn \def_long_new:Npx } +\def_new:Npn \def_long_new:cNn { \def_aux:Ncnn \def_long_new:Npn } +\def_new:Npn \def_long_new:cNx { \def_aux:Ncnn \def_long_new:Npx } +\def_new:Npn \gdef_long_new:NNn { \def_aux:NNnn \gdef_long_new:Npn } +\def_new:Npn \gdef_long_new:NNx { \def_aux:NNnn \gdef_long_new:Npx } +\def_new:Npn \gdef_long_new:cNn { \def_aux:Ncnn \gdef_long_new:Npn } +\def_new:Npn \gdef_long_new:cNx { \def_aux:Ncnn \gdef_long_new:Npx } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\def_protected:NNn} +% \begin{macro}{\def_protected:NNx} +% \begin{macro}{\def_protected:cNn} +% \begin{macro}{\def_protected:cNx} +% \begin{macro}{\gdef_protected:NNn} +% \begin{macro}{\gdef_protected:NNx} +% \begin{macro}{\gdef_protected:cNn} +% \begin{macro}{\gdef_protected:cNx} +% \begin{macro}{\def_protected_new:NNn} +% \begin{macro}{\def_protected_new:NNx} +% \begin{macro}{\def_protected_new:cNn} +% \begin{macro}{\def_protected_new:cNx} +% \begin{macro}{\gdef_protected_new:NNn} +% \begin{macro}{\gdef_protected_new:NNx} +% \begin{macro}{\gdef_protected_new:cNn} +% \begin{macro}{\gdef_protected_new:cNx} +% Protected versions of the above. +% \begin{macrocode} +\def_new:Npn \def_protected:NNn { \def_aux:NNnn \def_protected:Npn } +\def_new:Npn \def_protected:NNx { \def_aux:NNnn \def_protected:Npx } +\def_new:Npn \def_protected:cNn { \def_aux:Ncnn \def_protected:Npn } +\def_new:Npn \def_protected:cNx { \def_aux:Ncnn \def_protected:Npx } +\def_new:Npn \gdef_protected:NNn { \def_aux:NNnn \gdef_protected:Npn } +\def_new:Npn \gdef_protected:NNx { \def_aux:NNnn \gdef_protected:Npx } +\def_new:Npn \gdef_protected:cNn { \def_aux:Ncnn \gdef_protected:Npn } +\def_new:Npn \gdef_protected:cNx { \def_aux:Ncnn \gdef_protected:Npx } +\def_new:Npn \def_protected_new:NNn { \def_aux:NNnn \def_protected_new:Npn } +\def_new:Npn \def_protected_new:NNx { \def_aux:NNnn \def_protected_new:Npx } +\def_new:Npn \def_protected_new:cNn { \def_aux:Ncnn \def_protected_new:Npn } +\def_new:Npn \def_protected_new:cNx { \def_aux:Ncnn \def_protected_new:Npx } +\def_new:Npn \gdef_protected_new:NNn { \def_aux:NNnn \gdef_protected_new:Npn } +\def_new:Npn \gdef_protected_new:NNx { \def_aux:NNnn \gdef_protected_new:Npx } +\def_new:Npn \gdef_protected_new:cNn { \def_aux:Ncnn \gdef_protected_new:Npn } +\def_new:Npn \gdef_protected_new:cNx { \def_aux:Ncnn \gdef_protected_new:Npx } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\def_protected_long:NNn} +% \begin{macro}{\def_protected_long:NNx} +% \begin{macro}{\def_protected_long:cNn} +% \begin{macro}{\def_protected_long:cNx} +% \begin{macro}{\gdef_protected_long:NNn} +% \begin{macro}{\gdef_protected_long:NNx} +% \begin{macro}{\gdef_protected_long:cNn} +% \begin{macro}{\gdef_protected_long:cNx} +% \begin{macro}{\def_protected_long_new:NNn} +% \begin{macro}{\def_protected_long_new:NNx} +% \begin{macro}{\def_protected_long_new:cNn} +% \begin{macro}{\def_protected_long_new:cNx} +% \begin{macro}{\gdef_protected_long_new:NNn} +% \begin{macro}{\gdef_protected_long_new:NNx} +% \begin{macro}{\gdef_protected_long_new:cNn} +% \begin{macro}{\gdef_protected_long_new:cNx} +% And finally both long and protected. +% \begin{macrocode} +\def_new:Npn \def_protected_long:NNn { \def_aux:NNnn \def_protected_long:Npn } +\def_new:Npn \def_protected_long:NNx { \def_aux:NNnn \def_protected_long:Npx } +\def_new:Npn \def_protected_long:cNn { \def_aux:Ncnn \def_protected_long:Npn } +\def_new:Npn \def_protected_long:cNx { \def_aux:Ncnn \def_protected_long:Npx } +\def_new:Npn \gdef_protected_long:NNn { \def_aux:NNnn \gdef_protected_long:Npn } +\def_new:Npn \gdef_protected_long:NNx { \def_aux:NNnn \gdef_protected_long:Npx } +\def_new:Npn \gdef_protected_long:cNn { \def_aux:Ncnn \gdef_protected_long:Npn } +\def_new:Npn \gdef_protected_long:cNx { \def_aux:Ncnn \gdef_protected_long:Npx } +\def_new:Npn \def_protected_long_new:NNn { + \def_aux:NNnn \def_protected_long_new:Npn } +\def_new:Npn \def_protected_long_new:NNx { + \def_aux:NNnn \def_protected_long_new:Npx } +\def_new:Npn \def_protected_long_new:cNn { + \def_aux:Ncnn \def_protected_long_new:Npn } +\def_new:Npn \def_protected_long_new:cNx { + \def_aux:Ncnn \def_protected_long_new:Npx } +\def_new:Npn \gdef_protected_long_new:NNn { + \def_aux:NNnn \gdef_protected_long_new:Npn } +\def_new:Npn \gdef_protected_long_new:NNx { + \def_aux:NNnn \gdef_protected_long_new:Npx } +\def_new:Npn \gdef_protected_long_new:cNn { + \def_aux:Ncnn \gdef_protected_long_new:Npn } +\def_new:Npn \gdef_protected_long_new:cNx { + \def_aux:Ncnn \gdef_protected_long_new:Npx } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\let:NN} +% \begin{macro}{\let:cN} +% \begin{macro}{\let:Nc} +% \begin{macro}{\let:cc} +% \begin{macro}{\let_new:NN} +% \begin{macro}{\let_new:cN} +% \begin{macro}{\let_new:Nc} +% \begin{macro}{\let_new:cc} +% These macros allow us to copy the definition of a control sequence +% to another control sequence. +% \begin{macrocode} +\def_protected_long_new:Npn \let:NN #1{ +% \end{macrocode} +% The |=| sign allows us to define funny char tokens like .|=| +% itself or \verb*= = with this function. For the definition of +% |\c_space_chartok{~}| to work we need the |~| after the |=| +% \begin{macrocode} + \let:NwN #1=~} +\def_new:Npn\let:cN #1 {\exp_after:NN\let:NN\cs:w#1\cs_end:} +\def_new:Npn\let:Nc{\exp_args:NNc\let:NN} +\def_new:Npn\let:cc{\exp_args:Ncc\let:NN} +\def_new:Npn \let_new:NN #1{\chk_new_cs:N #1 + \let:NN #1} +\def_new:Npn \let_new:cN {\exp_args:Nc \let_new:NN} +\def_new:Npn \let_new:Nc {\exp_args:NNc \let_new:NN} +\def_new:Npn \let_new:cc {\exp_args:Ncc \let_new:NN} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\glet:NN} +% \begin{macro}{\glet:cN} +% \begin{macro}{\glet:Nc} +% \begin{macro}{\glet:cc} +% \begin{macro}{\glet_new:NN} +% \begin{macro}{\glet_new:cN} +% \begin{macro}{\glet_new:Nc} +% \begin{macro}{\glet_new:cc} +% These are global versions of some of the previously defined functions. +% \begin{macrocode} +\def_protected_new:Npn \glet:NN {\pref_global:D \let:NN} +\def_protected_new:Npn \glet:Nc {\exp_args:NNc \glet:NN} +\def_protected_new:Npn \glet:cN {\exp_args:Nc \glet:NN} +\def_new:Npn \glet:cc {\exp_args:Ncc \glet:NN} \def_new:Npn \glet_new:NN #1{\chk_new_cs:N #1 \tex_global:D\let:NN #1} -\def_new:Npn \gdef_new:Npn #1{\chk_new_cs:N #1 - \gdef:Npn #1} -\def_new:Npn \gdef:cpn {\tex_global:D \def:cpn} -\def_new:Npn \gdef:cpx {\tex_global:D \def:cpx} -\def_new:Npn \gdef:No {\exp_args:NNo\gdef:Npn} +\def_new:Npn \glet_new:cN {\exp_args:Nc \glet_new:NN} +\def_new:Npn \glet_new:Nc {\exp_args:NNc \glet_new:NN} +\def_new:Npn \glet_new:cc {\exp_args:Ncc \glet_new:NN} % \end{macrocode} -% \end {macro} -% \end {macro} -% \end {macro} -% \end {macro} -% \end {macro} -% \end {macro} - -% \begin {macro}{\gdef_long:Npn} -% \begin {macro}{\gdef_long:Npx} -% |\gdef_long:Npn| stands for |\tex_long:D| |\tex_global:D| |\def:Npn|. -% |\gdef_long:Npx| expands its second argument. -% \begin {macrocode} -\def_new:Npn \gdef_long:Npn {\tex_long:D\gdef:Npn} -\def_new:Npn \gdef_long:Npx {\tex_long:D\gdef:Npx} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\def:No} +% \begin{macro}{\gdef:No} +% |\def:No| expands its second argument one time before making +% the definition. +% \begin{macrocode} +\def_new:Npn \def:No{\exp_args:NNo\def:Npn} +\def_new:Npn \gdef:No {\exp_args:NNo\gdef:Npn} % \end{macrocode} -% \end {macro} -% \end {macro} +% \end{macro} +% \end{macro} % -% \begin {macro}{\gfuturelet:NNN} -% This is a global version of |\let_peek_after:NNN| -% \begin {macrocode} -\def_new:Npn \gfuturelet:NNN{\tex_global:D \let_peek_after:NNN} +% \begin{macro}{\def_test_function_aux:Nnnn} +% \begin{macro}{\def_test_function_aux:Nnnx} +% \begin{macro}{\def_test_function:npn} +% \begin{macro}{\def_test_function:npx} +% \begin{macro}{\def_long_test_function:npn} +% \begin{macro}{\def_long_test_function:npx} +% \begin{macro}{\def_test_function_new:npn} +% \begin{macro}{\def_test_function_new:npx} +% \begin{macro}{\def_long_test_function_new:npn} +% \begin{macro}{\def_long_test_function_new:npx} +% We will often be defining several almost identical TF, T and F +% type functions so it makes sense for us to define a small function +% that will do this for us so that we are less likely to introduce +% typos (it does tend to happen). By doing it in two steps as below +% we can still retain a simple interface where you write the \TeX\ +% parameters as usual. Just don't do it when you're already within a +% conditional! +% +% I think the ways of exiting conditionals below are as fast as they +% get. Using |\reverse_if:N| instead of |\else:| didn't give any +% difference I could measure. +% \begin{macrocode} +\def_long_new:Npn \def_test_function_aux:Nnnn #1#2#3#4{ + #1 {#2TF} #3 {#4 + \exp_after:NN\use_arg_i:nn\else:\exp_after:NN\use_arg_ii:nn\fi:} + #1 {#2T} #3 {#4 + \else:\exp_after:NN\use_none:nn\fi:\use_arg_i:n} + #1 {#2F} #3 {#4 + \exp_after:NN\use_none:nn\fi:\use_arg_i:n}} +\def_long_new:Npn \def_test_function_aux:Nnnx #1#2#3#4{ + #1 {#2TF} #3 {#4 + \exp_not:n{\exp_after:NN\use_arg_i:nn\else:\exp_after:NN\use_arg_ii:nn\fi:}} + #1 {#2T} #3 {#4 + \exp_not:n{\else:\exp_after:NN\use_none:nn\fi:\use_arg_i:n}} + #1 {#2F} #3 {#4 + \exp_not:n{\exp_after:NN\use_none:nn\fi:\use_arg_i:n}}} +\def_long_new:Npn \def_test_function:npn #1#2#{ + \def_test_function_aux:Nnnn \def:cpn {#1}{#2} +} +\def_long_new:Npn \def_test_function:npx #1#2#{ + \def_test_function_aux:Nnnx \def:cpx {#1}{#2} +} +\def_long_new:Npn \def_long_test_function:npn #1#2#{ + \def_test_function_aux:Nnnn \def_long:cpn {#1}{#2} +} +\def_long_new:Npn \def_long_test_function:npx #1#2#{ + \def_test_function_aux:Nnnx \def_long:cpx {#1}{#2} +} +\def_long_new:Npn \def_test_function_new:npn #1#2#{ + \def_test_function_aux:Nnnn \def_new:cpn {#1}{#2} +} +\def_long_new:Npn \def_long_test_function_new:npn #1#2#{ + \def_test_function_aux:Nnnn \def_long_new:cpn {#1}{#2} +} +\def_long_new:Npn \def_test_function_new:npx #1#2#{ + \def_test_function_aux:Nnnx \def_new:cpx {#1}{#2} +} +\def_long_new:Npn \def_long_test_function_new:npx #1#2#{ + \def_test_function_aux:Nnnx \def_long_new:cpx {#1}{#2} +} % \end{macrocode} -% \end {macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% % -% \subsection{Further checking} -% -% \begin{macro}{\cs_free:NTF} -% \begin{macro}{\cs_free:NT} -% \begin{macro}{\cs_free:NF} -% The old |\@ifundefined| of \LaTeX{} 2.09 is reimplemented in the +% \subsubsection{Further checking} +% +% \begin{macro}{\cs_if_free:NTF} +% \begin{macro}{\cs_if_free:NT} +% \begin{macro}{\cs_if_free:NF} +% The old |\@ifundefined| of \LaTeX{} 2.09 is re-implemented in the % function |\cs_free:cTF|, again in a way that |\else:| and |\fi:| % are removed. In this implementation this is absolutely % necessary because functions inside the conditional parts expect @@ -739,141 +2326,260 @@ % \m{csnames} directly and therefore allows both |\scan_stop:| and % |\c_undefined|. % \begin{macrocode} -\def_long_new:Npn \cs_free:NTF #1{\if:w\cs_free_p:N #1 - \exp_after:NN \use_choice_i:nn \else: - \exp_after:NN \use_choice_ii:nn \fi:} -\def_long_new:Npn \cs_free:NT #1{\if:w\cs_free_p:N #1 - \exp_after:NN \use:n \else: - \exp_after:NN \use_none:n \fi:} -\def_long_new:Npn \cs_free:NF #1{\if:w\cs_free_p:N #1 - \exp_after:NN \use_none:n \else: - \exp_after:NN \use:n \fi:} +\def_long_test_function_new:npn {cs_if_free:N}#1{\if:w\cs_if_free_p:N #1} +\let:NN \cs_free:NTF \cs_if_free:NTF +\let:NN \cs_free:NT \cs_if_free:NT +\let:NN \cs_free:NF \cs_if_free:NF % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % -% \begin{macro}{\cs_free:cTF} -% \begin{macro}{\cs_free:cT} -% \begin{macro}{\cs_free:cF} +% \begin{macro}{\cs_if_free:cTF} +% \begin{macro}{\cs_if_free:cT} +% \begin{macro}{\cs_if_free:cF} % We have to implement the |c| variants `by hand' because a different % test is necessary and I don't want the overhead for the test with % |\if:w|. What a mistake Don made by making this a % feature of |\cs:w|. If I'm not totally mistaken this % feature alone has cost him more than 600\$ for bug-checks. % \begin{macrocode} -\def_long_new:Npn \cs_free:cTF #1{ - \exp_after:NN - \if_meaning:NN - \cs:w#1\cs_end: - \scan_stop: - \exp_after:NN \use_choice_i:nn - \else: - \exp_after:NN \use_choice_ii:nn - \fi:} -\def_long_new:Npn \cs_free:cF #1{\exp_after:NN - \if_meaning:NN \cs:w#1\cs_end: \scan_stop: - \exp_after:NN \use_none:nn \fi: \use:n} -\def_long_new:Npn \cs_free:cT #1{\exp_after:NN - \if_meaning:NN \cs:w#1\cs_end: \scan_stop: - \else: - \exp_after:NN \use_none:nn \fi: \use:n} +\def_long_test_function_new:npn {cs_if_free:c}#1{ + \exp_after:NN \if_meaning:NN \cs:w#1\cs_end: \scan_stop:} +\let:NN \cs_free:cTF \cs_if_free:cTF +\let:NN \cs_free:cT \cs_if_free:cT +\let:NN \cs_free:cF \cs_if_free:cF % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % +% \begin{macro}{\cs_if_really_free:cTF} +% \begin{macro}{\cs_if_really_free:cT} +% \begin{macro}{\cs_if_really_free:cF} +% These versions are for special control sequences that can only be +% formed through |\cs:w ... \cs_end:|. They do not turn the control +% sequence formed into |\scan_stop:|. +% \begin{macrocode} +\def_long_test_function_new:npn {cs_if_really_free:c}#1{ + \reverse_if:N\if_cs_exist:w #1\cs_end:} +\let:NN \cs_really_free:cTF \cs_if_really_free:cTF +\let:NN \cs_really_free:cT \cs_if_really_free:cT +\let:NN \cs_really_free:cF \cs_if_really_free:cF +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\cs_if_exist:NTF} +% \begin{macro}{\cs_if_exist:NT} +% \begin{macro}{\cs_if_exist:NF} +% \begin{macro}{\cs_if_exist:cTF} +% \begin{macro}{\cs_if_exist:cT} +% \begin{macro}{\cs_if_exist:cF} +% \begin{macro}{\cs_if_really_exist:cTF} +% \begin{macro}{\cs_if_really_exist:cT} +% \begin{macro}{\cs_if_really_exist:cF} +% Now the same functions but with reverse logic: test if the control +% sequence exists. +% \begin{macrocode} +\def_long_test_function_new:npn {cs_if_exist:N}#1{\if:w\cs_if_exist_p:N #1} +\def_long_test_function_new:npn {cs_if_exist:c}#1{ + \exp_after:NN\reverse_if:N + \exp_after:NN \if_meaning:NN \cs:w#1\cs_end: \scan_stop:} +\def_long_test_function_new:npn {cs_if_really_exist:c}#1{ + \if_cs_exist:w #1\cs_end:} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} % -% \subsection{Freeing memory} % -% \begin{macro}{\gundefine:N } +% \subsubsection{Freeing memory} +% +% \begin{macro}{\cs_gundefine:N } % The following function is used to free the main memory from the % definition of some function that isn't in use any longer. % \begin{macrocode} -\def_new:Npn \gundefine:N #1{\glet:NN #1\c_undefined} +\def_new:Npn \cs_gundefine:N #1{\glet:NN #1\c_undefined} % \end{macrocode} % \end{macro} % -% \subsection{Gobbling tokens from input} % -% \begin{macro}{\use_none:n} -% \begin{macro}{\use_none:nn} -% \begin{macro}{\use_none:nnn} -% \begin{macro}{\use_none:nnnn} -% To gobble tokens from the input we use a standard naming -% convention: the number of tokens gobbled is given by the number -% of |n|'s following the |:| in the name. +% \subsubsection{Engine specific definitions} +% +% \begin{macro}{\engine_aleph:TF} +% In some cases it will be useful to know which engine we're running. % \begin{macrocode} -\def_long_new:Npn \use_none:n #1{} -\def_long_new:Npn \use_none:nn #1#2{} -\def_long_new:Npn \use_none:nnn #1{\use_none:nn} -\def_long_new:Npn \use_none:nnnn - {\exp_after:NN\use_none:nn \use_none:nn} +\def_test_function_new:npn {engine_aleph:}{\if_cs_exist:N \aleph_textdir:D} % \end{macrocode} % \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} % % -% \subsection{Selecting tokens} % -% \begin{macro}{\use:n} +% \subsubsection{Selecting tokens} +% +% \begin{macro}{\use_arg_i:n} % This macro grabs its argument and returns it back to the input % (with outer braces removed). % \begin{macrocode} -\def_long_new:Npn \use:n #1{#1} +%\def_long_new:Npn \use_arg_i:n #1{#1}% moved earlier % \end{macrocode} % \end{macro} % % \begin{macro}{\use:c} +% \begin{macro}{\cs_use:c} % \begin{macro}{\use:cc} % This macro grabs its argument and returns a csname from it. % \begin{macrocode} \def_new:Npn \use:c #1{\cs:w #1\cs_end:} - +\def_new:Npn \cs_use:c #1 { \cs:w#1\cs_end: } % \end{macrocode} -% THE NAME IS COMPLETELY WRONG!!!!! +% THE NAME IS COMPLETELY WRONG!!!!! +% Morten says: Perhaps this is really |\exp_args:cc| instead? % \begin{macrocode} \def_new:Npn \use:cc #1#2 {\cs:w #1\exp_after:NN\cs_end:\cs:w #2\cs_end:} % \end{macrocode} % \end{macro} % \end{macro} +% \end{macro} % -% \begin{macro}{\use_choice_i:nn} -% \begin{macro}{\use_choice_ii:nn} +% \begin{macro}{\use_arg_i:nn} +% \begin{macro}{\use_arg_ii:nn} % These macros are needed to provide functions with true and false % cases, as introduced by Michael some time ago. By using -% |\exp_after:NN| |\use_choice_i:nn | |\else:| constructions it +% |\exp_after:NN| |\use_arg_i:nn | |\else:| constructions it % is possible to write code where the true or false case is able to % access the following tokens from the input stream, which is not % possible if the |\c_true| syntax is used. % \begin{macrocode} -\def_long_new:Npn \use_choice_i:nn #1#2{#1} -\def_long_new:Npn \use_choice_ii:nn #1#2{#2} +\def_long_new:Npn \use_arg_i:nn #1#2{#1} +\def_long_new:Npn \use_arg_ii:nn #1#2{#2} % \end{macrocode} % \end{macro} % \end{macro} % % % -% \begin{macro}{\use_choice_i:nnn} -% \begin{macro}{\use_choice_ii:nnn} -% \begin{macro}{\use_choice_iii:nnn} +% \begin{macro}{\use_arg_i:nnn} +% \begin{macro}{\use_arg_ii:nnn} +% \begin{macro}{\use_arg_iii:nnn} +% \begin{macro}{\use_arg_i:nnnn} +% \begin{macro}{\use_arg_ii:nnnn} +% \begin{macro}{\use_arg_iii:nnnn} +% \begin{macro}{\use_arg_iv:nnnn} % We also need something for picking up arguments from a longer -% list. +% list. % \begin{macrocode} -\def_long_new:Npn\use_choice_i:nnn#1#2#3{#1} -\def_long_new:Npn\use_choice_ii:nnn#1#2#3{#2} -\def_long_new:Npn\use_choice_iii:nnn#1#2#3{#3} +\def_long_new:NNn \use_arg_i:nnn 3{#1} +\def_long_new:NNn \use_arg_ii:nnn 3{#2} +\def_long_new:NNn \use_arg_iii:nnn 3{#3} +\def_long_new:NNn \use_arg_i:nnnn 4{#1} +\def_long_new:NNn \use_arg_ii:nnnn 4{#2} +\def_long_new:NNn \use_arg_iii:nnnn 4{#3} +\def_long_new:NNn \use_arg_iv:nnnn 4{#4} % \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\use_arg_i_ii:nn} +% And a function for grabbing two arguments and returning them +% again. +% \begin{macrocode} +\def_long_new:NNn\use_arg_i_ii:nn 2{#1#2} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\use_none_delimit_by_q_nil:w} +% \begin{macro}{\use_none_delimit_by_q_stop:w} +% Functions that gobble everything until they see either |\q_nil| or +% |\q_stop| resp. +% \begin{macrocode} +\def_long_new:Npn \use_none_delimit_by_q_nil:w #1\q_nil{} +\def_long_new:Npn \use_none_delimit_by_q_stop:w #1\q_stop{} +% \end{macrocode} +% \end{macro} +% \end{macro} % +% \begin{macro}{\use_arg_i_delimit_by_q_nil:nw} +% \begin{macro}{\use_arg_i_delimit_by_q_stop:nw} +% Same as above but execute first argument after gobbling. Very +% useful when you need to skip the rest of a mapping sequence but +% want an easy way to control what should be expanded next. +% \begin{macrocode} +\def_long_new:Npn \use_arg_i_delimit_by_q_nil:nw #1#2\q_nil{#1} +\def_long_new:Npn \use_arg_i_delimit_by_q_stop:nw #1#2\q_stop{#1} +% \end{macrocode} +% \end{macro} +% \end{macro} % -% \subsection{Scratch functions} +% +% \begin{macro}{\use_arg_i_after_fi:nw} +% \begin{macro}{\use_arg_i_after_else:nw} +% \begin{macro}{\use_arg_i_after_or:nw} +% Returns the first argument after ending the conditional. +% \begin{macrocode} +\def_long_new:Npn \use_arg_i_after_fi:nw #1\fi:{\fi: #1} +\def_long_new:Npn \use_arg_i_after_else:nw #1\else:#2\fi:{\fi: #1} +\def_long_new:Npn \use_arg_i_after_or:nw #1\or: #2\fi: {\or:\fi:#1} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \subsubsection{Gobbling tokens from input} +% +% \begin{macro}{\use_none:n} +% \begin{macro}{\use_none:nn} +% \begin{macro}{\use_none:nnn} +% \begin{macro}{\use_none:nnnn} +% \begin{macro}{\use_none:nnnnn} +% \begin{macro}{\use_none:nnnnnn} +% \begin{macro}{\use_none:nnnnnnn} +% \begin{macro}{\use_none:nnnnnnnn} +% \begin{macro}{\use_none:nnnnnnnnn} +% To gobble tokens from the input we use a standard naming +% convention: the number of tokens gobbled is given by the number of +% |n|'s following the |:| in the name. Although defining +% |\use_none:nnn| and above as separate calls of |\use_none:n| and +% |\use_none:nn| is slightly faster, this is very non-intuitive to +% the programmer who will assume that expanding such a function once +% will take care of gobbling all the tokens in one go. +% \begin{macrocode} +%\def_long_new:NNn \use_none:n 1{}% moved earlier +\def_long_new:NNn \use_none:nn 2{} +\def_long_new:NNn \use_none:nnn 3{} +\def_long_new:NNn \use_none:nnnn 4{} +\def_long_new:NNn \use_none:nnnnn 5{} +\def_long_new:NNn \use_none:nnnnnn 6{} +\def_long_new:NNn \use_none:nnnnnnn 7{} +\def_long_new:NNn \use_none:nnnnnnnn 8{} +\def_long_new:NNn \use_none:nnnnnnnnn 9{} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \subsubsection{Scratch functions} % % \begin{macro}{\gtmp:w} % This function is for global scratch definitions that are used @@ -902,92 +2608,68 @@ % \end{macrocode} % \end{macro} % -% \section{Strings and input stream token lists} +% \subsubsection{Strings and input stream token lists} % % \begin{macro}{\cs_to_str:N} -% This converts a control sequence into the character string of its +% This converts a control sequence into the character string of its % name, removing the leading escape character. % \begin{macrocode} \def_new:Npn \cs_to_str:N {\exp_after:NN\use_none:n \token_to_string:N} % \end{macrocode} % \end{macro} % -% \begin{macro}{\tlist_eq:nnTF} -% \begin{macro}{\tlist_eq:onTF} -% |\tlist_eq:nnTF| tests whether the first two arguments are equal and -% executes either its third or fourth argument. -% |\tlist_eq:onTF| expands its first argument once. -% \begin{macrocode} -\def_new:Npn \tlist_eq:nnTF #1#2{ - \tlp_gset:Nn \g_testa_tlp {#1} - \tlp_gset:Nn \g_testb_tlp {#2} - \if_meaning:NN\g_testa_tlp \g_testb_tlp - \exp_after:NN\use_choice_i:nn \else: - \exp_after:NN\use_choice_ii:nn \fi:} -\def_new:Npn \tlist_eq:onTF {\exp_args:No \tlist_eq:nnTF} -% \end{macrocode} -% \end{macro} -% \end{macro} % % -% \begin{macro}{\tlist_empty:nTF} -% \begin{macro}{\tlist_empty:nF} -% These test whether a token list is empty and act accordingly. -% \begin{macrocode} -\def_new:Npn \tlist_empty:nTF #1{\tlp_gset:Nn \g_testa_tlp {#1} - \if_meaning:NN\g_testa_tlp \c_empty_tlp - \exp_after:NN \use_choice_i:nn \else: - \exp_after:NN \use_choice_ii:nn \fi:} -\def_new:Npn \tlist_empty:nF #1{\tlp_gset:Nn \g_testa_tlp {#1} - \if_meaning:NN\g_testa_tlp \c_empty_tlp - \exp_after:NN \use_none:nn \fi: \use:n} -% \end{macrocode} -% \end{macro} -% \end{macro} % % -% \begin{macro}{\str_eq_p:nn} -% Takes 2 lists of characters as arguments and expands into -% |\c_true| if they are equal, and |\c_false| otherwise. I'm -% pretty sure that the non expandable version above is faster, but -% it's not expandable so we also include this one. +% \begin{macro}{\cs_if_eq:NNTF} +% \begin{macro}{\cs_if_eq:NNT} +% \begin{macro}{\cs_if_eq:NNF} +% \begin{macro}{\cs_if_eq:cNTF} +% \begin{macro}{\cs_if_eq:cNT} +% \begin{macro}{\cs_if_eq:cNF} +% \begin{macro}{\cs_if_eq:NcTF} +% \begin{macro}{\cs_if_eq:NcT} +% \begin{macro}{\cs_if_eq:NcF} +% \begin{macro}{\cs_if_eq:ccTF} +% \begin{macro}{\cs_if_eq:ccT} +% \begin{macro}{\cs_if_eq:ccF} +% Check if two control sequences are identical. % \begin{macrocode} -\def_new:Npn \str_eq_p:nn #1#2{\str_eq_p_aux:w #1\scan_stop:\\#2\scan_stop:\\} -\def_new:Npn \str_eq_p_aux:w #1#2\\#3#4\\{ - \if_meaning:NN#1#3 - \if_meaning:NN#1\scan_stop:\c_true \else: - \if_meaning:NN#3\scan_stop:\c_false \else: - \str_eq_p_aux:w #2\\#4\\\fi:\fi: - \else:\c_false \fi:} +\def_test_function_new:npn {cs_if_eq:NN} #1#2{\if_meaning:NN #1#2} +\def_new:Npn \cs_if_eq:cNTF {\exp_args:Nc \cs_if_eq:NNTF} +\def_new:Npn \cs_if_eq:cNT {\exp_args:Nc \cs_if_eq:NNT} +\def_new:Npn \cs_if_eq:cNF {\exp_args:Nc \cs_if_eq:NNF} +\def_new:Npn \cs_if_eq:NcTF {\exp_args:NNc \cs_if_eq:NNTF} +\def_new:Npn \cs_if_eq:NcT {\exp_args:NNc \cs_if_eq:NNT} +\def_new:Npn \cs_if_eq:NcF {\exp_args:NNc \cs_if_eq:NNF} +\def_new:Npn \cs_if_eq:ccTF {\exp_args:Ncc \cs_if_eq:NNTF} +\def_new:Npn \cs_if_eq:ccT {\exp_args:Ncc \cs_if_eq:NNT} +\def_new:Npn \cs_if_eq:ccF {\exp_args:Ncc \cs_if_eq:NNF} % \end{macrocode} % \end{macro} -% -% \begin{macro}{\cs_eq_p:NN} -% An application of the above function, already streamlined for -% speed, so I put it in here. It takes two control sequences as -% arguments and expands into true iff they have the same name. -% \begin{macrocode} -\def:Npn \cs_eq_p:NN #1#2{ - \exp_after:NN\exp_after:NN - \exp_after:NN\str_eq_p_aux:w - \exp_after:NN\token_to_string:N - \exp_after:NN#1 - \exp_after:NN\scan_stop: - \exp_after:NN\\ - \token_to_string:N#2\scan_stop:\\} -% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} % \end{macro} % -% Finally some code that is needed as we -% do not distribute the file module at the moment (so we simply define -% the needed function via an existing \LaTeX{} command) and some other -% stuff which was set up elsewhere, in undistributed modules. +% Finally some code that is needed as we do not distribute the file +% module at the moment (so we simply define the needed function via an +% existing \LaTeX{} command) and some other stuff which was set up +% elsewhere, in undistributed modules. % \begin{macrocode} \def_new:Npn\file_not_found:nTF #1#2#3{\IfFileExists{#1}{#3}{#2}} % \end{macrocode} % -% -% \section{Predicates and conditionals} +% +% \subsubsection{Predicates and conditionals} % \label{sec:predicates} % % \LaTeX3 has three concepts for conditional flow processing: @@ -995,8 +2677,8 @@ % % \item % Functions that carry out a test an then execute, depending on its -% result, either the code supplied in the <true arg> or the <false -% arg>. These arguments are denoted with "T" and "F" repectively. An +% result, either the code supplied in the \m{true arg} or the \m{false +% arg}. These arguments are denoted with "T" and "F" repectively. An % example would be % \begin{quote} % "\cs_free:cTF{abc}{...}{...}" @@ -1027,52 +2709,108 @@ % thoughts. % \end{enumerate} % -% Important to note is that conditionals with <true code> and/or <false -% code> are always defined in a way that the code of the chosen +% Important to note is that conditionals with \m{true code} and/or +% \m{false code} are always defined in a way that the code of the chosen % alternative can operate on following tokens in the input stream while % the predicate implementations always have an "\else:" or "\fi:" % interfering. This can be important in scanner implementations. % -% \subsection{Variables} % -% \begin{variable}{% -% \c_true | \c_false | -% } -% Constants that represend `true' or `false', respectively. Used to -% implement predicates. -% \end{variable} +% \begin{macrocode} +%</initex|package> +%<*showmemory> +\showMemUsage +%</showmemory> +% \end{macrocode} % -% \begin{variable}{\l_testa_tlp | -% \l_testb_tlp | -% \g_testa_tlp | -% \g_testb_tlp | -% } -% All conditionals and predicates never use tmp variables. Instead they -% use the following reserved variables. -% \end{variable} +% \endinput % -% \subsection{Predicate implementation} +% $Log$ +% Revision 1.38 2006/08/06 17:05:25 morten +% Make \chk_new_cs:N bulletproof % -% I think Michael originated the idea of expandable boolean tests. -% They must expand into either \texttt{TT} or \texttt{TF} and are -% tested using |\if:w|. +% Revision 1.37 2006/07/30 14:37:47 morten +% Added \str_if_eq_var_p:nf % +% Revision 1.36 2006/07/23 13:43:21 morten +% Removed extra occurrence of \str_if_eq_p:nn % -% \begin{macro}{\c_true} -% \begin{macro}{\c_false} -% Here are the canonical boolean values. -% \begin{macrocode} -\def_new:Npn \c_true {TT} -\def_new:Npn \c_false {TF} -% \end{macrocode} -% \end{macro} -% \end{macro} +% Revision 1.35 2006/07/17 22:25:31 morten +% Fix logic of \chk_new_cs:N and rename \cs_if_eq_p:NN to +% \cs_if_eq_name_p:NN because it is not their meaning but their names +% which are compared. +% +% Revision 1.34 2006/07/08 22:46:17 morten +% Rearranged some code and added complete set of \use_none:<args> +% functions. +% +% Revision 1.33 2006/07/06 14:53:56 morten +% Added \def:NNn functions, reorganized code and much much more. +% +% Revision 1.32 2006/06/03 17:14:43 morten +% Added more \use_arg_... functions. +% +% Revision 1.31 2006/03/20 18:26:33 braams +% Updated the copyright notice (2006) and demoted all implementation +% sections to subsections and so on to clean up the toc for source3.tex +% +% Revision 1.30 2006/01/22 19:35:46 morten +% Changed \use_none:nnn to gobble all tokens in one go and added +% \use_arg_i_ii:nn for l3keyval. +% +% Revision 1.29 2006/01/16 09:47:49 morten +% Fixed deleted brace +% +% Revision 1.28 2006/01/15 19:08:28 morten +% Fixed typos in some \if names +% +% Revision 1.27 2006/01/04 01:29:36 morten +% Changed "robust" to "protected". +% +% Revision 1.26 2005/12/27 09:53:55 morten +% Fixed some names, added a few more \use_... functions, changed RCS +% information retrieval +% +% Revision 1.25 2005/12/23 11:16:15 morten +% *** empty log message *** +% +% Revision 1.24 2005/12/02 15:21:55 morten +% Fixed minor typo +% +% Revision 1.23 2005/11/20 07:10:03 morten +% Added a few missing functions. New function type +% \def_test_function:npn to help define TF-type functions. +% +% Revision 1.22 2005/11/08 04:16:17 morten +% Fixed typo. +% +% Revision 1.21 2005/10/27 22:35:13 morten +% Cleaned up a bit and moved some code to l3num. +% +% Revision 1.20 2005/07/12 16:10:24 morten +% Allow \cs_if_eq_p:NN to accept \par. (Yes, real life experience) +% +% Revision 1.19 2005/04/06 21:34:55 morten +% Added more functions. Moved \engine_aleph:TF from l3prg +% +% Revision 1.18 2005/03/25 23:52:24 braams +% The definition of \next needs to be seen at initex time, +% not at typesetting time +% +% Revision 1.17 2005/03/22 23:28:46 morten +% Moved some code to l3prg, removed obsolete code, cleaned up documentation. +% +% Revision 1.16 2005/03/16 22:31:44 braams +% Changed definition of \c_zero and \c_minus_one +% +% Revision 1.15 2005/03/15 23:16:27 braams +% Some tweaking with the docstrip guards to get the documentation to +% come out right. +% +% Revision 1.14 2005/03/15 22:50:00 braams +% Made loadable by initex as the second file +% +% Revision 1.13 2005/03/11 21:32:21 braams +% Fixed the use of RCS information; +% moved \RequirePackage after \StopEventually % -% \begin{macrocode} -%</package> -%<*showmemory> -\showMemUsage -%</showmemory> -% \end{macrocode} -% - |