diff options
author | Karl Berry <karl@freefriends.org> | 2006-01-11 23:53:06 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2006-01-11 23:53:06 +0000 |
commit | 1f4499ce04e16a3dae7c287b445576361cc20769 (patch) | |
tree | ad95653c87d8135183eddbd885d1645f9dc5b547 /Master | |
parent | 4206a1600d2e36ae7c46f99a3c58ae98112ee1ad (diff) |
trunk/Master/texmf-dist/source/latex/expl3
git-svn-id: svn://tug.org/texlive/trunk@270 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master')
18 files changed, 7415 insertions, 0 deletions
diff --git a/Master/texmf-dist/source/latex/expl3/l3.ins b/Master/texmf-dist/source/latex/expl3/l3.ins new file mode 100644 index 00000000000..786fcff9a9b --- /dev/null +++ b/Master/texmf-dist/source/latex/expl3/l3.ins @@ -0,0 +1,77 @@ + +\input docstrip.tex +\askforoverwritefalse + +\preamble + + +EXPERIMENTAL CODE + +Do not distribute this file without also distributing the +source files specified above. + +Do not distribute a modified version of this file. + + +\endpreamble +% stop docstrip adding \endinput +\postamble +\endpostamble + +\keepsilent + +% l3names.sty sets up the naming scheme for TeX primitives. +\generate{\file{l3names.sty}{\from{l3names.dtx}{package}}} + + + +% Define some basic commands to get us started with the new +% programming style. +\generate{\file{l3basics.sty}{\from{l3basics.dtx}{package,trace}}} + + +% Define some basic commands That check various conditions +% related to defining commands eg defined/undefined global/local +% Not sure how much of this really makes sense as a package, but... +\generate{\file{l3chk.sty}{\from{l3chk.dtx}{package,trace}}} + + +%% toks register handling (can be compiled with check module) +\generate{\file{l3toks.sty}{\from{l3toks.dtx}{package,trace}}} + + +%% tlp handling +\generate{\file{l3tlp.sty}{\from{l3tlp.dtx}{package,trace}}} + + +%% LaTeX3 expansion module +\generate{\file{l3expan.sty}{\from{l3expan.dtx}{package,trace}}} + + +%% LaTeX3 quarks. +\generate{\file{l3quark.sty}{\from{l3quark.dtx}{package,trace}}} + + +%% LaTeX3 sequences. +\generate{\file{l3seq.sty}{\from{l3seq.dtx}{package,trace}}} + + +%% LaTeX3 property lists. +\generate{\file{l3prop.sty}{\from{l3prop.dtx}{package,trace}}} + + +%% LaTeX3 integer registers. (can be compiled with check module) +\generate{\file{l3int.sty}{\from{l3int.dtx}{package,trace}}} + + +%% LaTeX3 precompilation +\generate{\file{l3precom.sty}{\from{l3precom.dtx}{package,precompile,trace}}} + + +%% LaTeX3 precompilation +\generate{\file{l3io.sty}{\from{l3io.dtx}{package,trace}}} + + +\endbatchfile + + diff --git a/Master/texmf-dist/source/latex/expl3/l3basics.dtx b/Master/texmf-dist/source/latex/expl3/l3basics.dtx new file mode 100644 index 00000000000..8a4170e79cf --- /dev/null +++ b/Master/texmf-dist/source/latex/expl3/l3basics.dtx @@ -0,0 +1,1078 @@ +% \iffalse +%% File: l3basics.dtx Copyright (C) 1990-1998 LaTeX3 project +% +%<*dtx> + \ProvidesFile{l3basics.dtx} +%</dtx> +%<package>\NeedsTeXFormat{LaTeX2e} +%<package>\ProvidesPackage{l3basics} +%<driver> \ProvidesFile{l3basics.drv} +% \fi +% \ProvidesFile{l3basics.dtx} + [1998/05/04 v1.0i L3 Experimental basic definitions] +% +% \iffalse +%<*driver> +\documentclass{l3doc} + +\begin{document} +\DocInput{l3basics.dtx} +\end{document} +%</driver> +% \fi +% +% \GetFileInfo{l3basics.dtx} +% \title{The \textsf{l3basics} package\thanks{This file +% has version number \fileversion, last +% revised \filedate.}\\ +% Basic Definitions} +% \author{\Team} +% \date{\filedate} +% \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. +% +% \subsection{Functions} +% +% \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}{\cs_gen_sym:N | +% \cs_ggen_sym:N} +% \begin{syntax} +% "\cs_gen_sym:N" <tlp> +% \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). +% \end{function} +% +% +% \subsection{Predicates and conditionals} +% +% \begin{function}{% +% \if_meaning:NN | +% } +% \begin{syntax} +% "\if_meaning:NN" <cs1> <cs2> <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} +% \end{function} +% \begin{function}{% +% \cs_eq_p:NN | +% } +% \begin{syntax} +% "\cs_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 | +% } +% \begin{syntax} +% "\cs_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 | +% } +% \begin{syntax} +% "\cs_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. +% \end{texnote} +% \end{function} +% +% \begin{function}{% +% \cs_exist_p:N | +% } +% \begin{syntax} +% "\cs_exist_p:N" <cs> +% \end{syntax} +% This function does the opposite of "\cs_free_p:N". +% \end{function} +% +% \begin{function}{% +% \chk_new_cs:N | +% } +% \begin{syntax} +% "\chk_new_cs:N" <cs> +% \end{syntax} +% This function checks that <cs> is so far either undefined or equals +% "\scan_stop:" (the function that is assigned to newly created +% control sequences by \TeX{} when "\cs:w" "..." "\cs_end:" is +% used). +% \end{function} +% +% \begin{function}{% +% \chk_exist_cs:N | +% } +% \begin{syntax} +% "\chk_exist_cs:N" <cs> +% \end{syntax} +% This function checks that <cs> is defined. If it is not an error +% is generated. +% \end{function} +% +% +% \subsection{Internal functions} +% +% \begin{function}{% +% \cs:w | +% \cs_end: | +% } +% \begin{syntax} +% "\cs:w" <tokens> "\cs_end:" +% \end{syntax} +% This is the \TeX{} internal way of generating a control sequence from +% some token list. <tokens> get expanded and must ultimately result in a +% sequence of characters. +% \begin{texnote} +% These functions are the primitives \tn{csname} and \tn{endcsname}. +% "\cs:w" is considered weird because it expands tokens until it reaches +% "\cs_end:". +% \end{texnote} +% \end{function} +% +% \begin{function}{\pref_global:D | +% \pref_long:D | +% } +% \begin{syntax} +% "\pref_global:D" "\def:Npn" +% \end{syntax} +% Prefix functions that can be used in front of some definition +% 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. +% +% 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". +% \begin{texnote} +% These prefixes are the primitives \tn{global}, \tn{long}. +% 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{syntax} +% "\use_choice_i:nnn" "{" <arg1> "}{" <arg2> "}{" <arg2> "}" +% \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: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} +% +% \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.) +% +% \begin{texnote} +% While \TeX{} makes all definition functions directly available to the +% user \LaTeX3 hides them very carefully to avoid the problems with +% definitions that are overwritten accidentally. Many functions that are in +% \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. +% +% \begin{function}{\def_new:Npn | +% \def_new:Npx | +% \def_new:cpn | +% \def_new:cpx +% } +% \begin{syntax} +% "\def_new:Npn" <cs> <parms> "{" <code> "}" +% \end{syntax} +% Defines a new function, making sure that <cs> is unused so far. +% <parms> may consist of arbitrary parameter specification in \TeX{} +% syntax. 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:Npn +% } +% \begin{syntax} +% "\gdef_new:Npn" <cs> <parms> "{" <code> "}" +% \end{syntax} +% Like "\def_new:Npn" but defines the new function globally. See +% comments above. +% \end{function} +% +% \begin{function}{\def_long_new:Npn | +% } +% \begin{syntax} +% "\def_long_new:Npn" <cs> <parms> "{" <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}{\let_new:NN | +% \glet_new:NN} +% \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. +% \end{function} +% +% \subsection{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. +% +% \begin{function}{\def:Npn | +% \def:Npx | +% \def:cpn | +% \def:cpx | +% } +% \begin{syntax} +% "\def:Npn" <cs> <parms> "{" <code> "}" +% \end{syntax} +% Like "\def_new:Npn" etc.\ but does not check the <cs> name. +% \begin{texnote} +% "\def:Npn" is the \LaTeX3 name for \TeX{}'s \tn{def} and "\def:Npx" +% corresponds to the primitive \tn{edef}. The "\def:cpn" function was +% known in \LaTeX2 as \tn{@namedef}. "\def:cpx" has no equivalent. +% \end{texnote} +% \end{function} +% +% \begin{function}{\gdef:Npn | +% \gdef:Npx | +% \gdef:cpn | +% \gdef:cpx | +% } +% \begin{syntax} +% "\gdef:Npn" <cs> <parms> "{" <code> "}" +% \end{syntax} +% Like "\def:Npn" but defines the <cs> globally. +% \begin{texnote} +% "\gdef:Npn" and "\gdef:Npx" are known to \TeX{}hackers as \tn{gdef} +% 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 | +% } +% \begin{syntax} +% "\def_long:Npn" <cs> <parms> "{" <code> "}" +% \end{syntax} +% 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 | +% } +% \begin{syntax} +% "\gdef_long:Npn" <cs> <parms> "{" <code> "}" +% \end{syntax} +% Global variant of "\def_long:Npn". +% \end{function} +% +% \begin{function}{\let:NN | +% \glet:NN | +% \let:cN | +% \let:Nc | +% \let:cc +% } +% \begin{syntax} +% "\let:cN" <cs1> <cs2> +% \end{syntax} +% 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> +% "\let:NwN" <cs1> "=" <cs2> +% \end{syntax} +% These functions assign the meaning of <cs2> locally or globally to the +% function <cs1>. Because the \TeX{} primitive operation is being used +% which may have an equal sign and (a certain number of) spaces between +% <cs1> and <cs2> the name contains a "w". (Not happy about this +% convention!). +% \begin{texnote} +% "\let:NwN" is the \LaTeX3 name for \TeX{}'s \tn{let}. +% \end{texnote} +% \end{function} +% +% +% \StopEventually{} +% +% \section{Renaming some \TeX{} primitives (again)} +% +% 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 +% 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> +\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 +\let:NwN \if_false: \tex_iffalse:D +\let:NwN \else: \tex_else:D +\let:NwN \fi: \tex_fi:D +\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 \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} +% +% 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} +% +% +% \section {Defining and checking (new) functions} +% +% 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. +% +% \begin{macrocode} +\let:NwN\c_minus_one\m@ne +\tex_chardef:D \c_one = 1\scan_stop: +\tex_chardef:D \c_sixteen = 16\scan_stop: +\tex_mathchardef:D \c_two_hundred_fifty_six = 256\scan_stop: +% \end{macrocode} +% +% We provide two kinds of functions that can be used to define +% control sequences. On the one hand we have functions that check +% if their argument doesn't already exist, they are called +% |\..._new|. The second type of defining functions doesn't check +% 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 +% only temporary, they will be redefined later on. +% +% \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. +% +% \begin{macrocode} +\def:Npn \io_put_log:x{ + \tex_immediate:D\io_put_deferred:Nx \c_minus_one } +\def:Npn \io_put_term:x{ + \tex_immediate:D\io_put_deferred:Nx \c_sixteen } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\err_latex_bug:n} +% This will show internal errors. +% \begin{macrocode} +\def:Npn\err_latex_bug:n#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} +% 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. +% \begin{macrocode} +%<*trace> +\def:Npn \cs_record_meaning:N#1{} +%</trace> +% \end{macrocode} +% \end{macro} +% +% \subsection{Checking new definitions} +% +% \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. +% \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: +%<*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} +%</trace> + } +% \end{macrocode} +% \end {macro} +% +% \begin{macro}{\cs_exist_p:N} +% Expands into |\c_true| if the control sequence given as its +% argument {\em is} in use. +% +% \begin{macrocode} +\def:Npn \cs_exist_p:N #1{ + \if:w \cs_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 +% in its argument does not exist. +% \begin{macrocode} +\def:Npn \chk_exist_cs:N #1 { + \if:w \cs_exist_p:N #1 + \else: + \err_latex_bug:n{Command~ `\token_to_string:N #1'~ + not~ yet~ defined!} + \fi:} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\cs_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 +% |\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: + \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:} +% \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{macrocode} +\tex_long:D\def: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: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. +% \begin {macrocode} +\def: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:Npx #1} +\def_new:Npn \let_new:NN #1{\chk_new_cs:N #1 + \let:NN #1} +% \end{macrocode} +% \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.). +% +% |\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} +% \end{macrocode} +% \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} +\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} +% \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{macrocode} +% \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} +% \end{macrocode} +% \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 +% 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 +% to read further input from outside the conditional. Actually, +% the first part of the code below is more general, since it checks +% \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:} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\cs_free:cTF} +% \begin{macro}{\cs_free:cT} +% \begin{macro}{\cs_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} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \subsection{Freeing memory} +% +% \begin{macro}{\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} +% \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. +% \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} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \subsection{Selecting tokens} +% +% \begin{macro}{\use: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} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\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:} + +% \end{macrocode} +% THE NAME IS COMPLETELY WRONG!!!!! +% \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} +% +% \begin{macro}{\use_choice_i:nn} +% \begin{macro}{\use_choice_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 +% 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} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% +% \begin{macro}{\use_choice_i:nnn} +% \begin{macro}{\use_choice_ii:nnn} +% \begin{macro}{\use_choice_iii:nnn} +% We also need something for picking up arguments from a longer +% 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} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \subsection{Scratch functions} +% +% \begin{macro}{\gtmp:w} +% This function is for global scratch definitions that are used +% immediately afterwards. It should be used when we need a function +% that operates on input, i.e.\ has arguments. If we want to save +% only some tokens for later use, token-list scratch variables +% should be used. +% \begin{macrocode} +\def_new:Npn \gtmp:w {} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tmp:w} +% This is a local version of the previous function. +% \begin{macrocode} +\def_new:Npn \tmp:w {} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\use_noop:} +% I don't think this function belongs here, but one place is as +% good as any other. I want to use this function when I want to +% express `no operation'. +% \begin{macrocode} +\def_new:Npn \use_noop: {} +% \end{macrocode} +% \end{macro} +% +% \section{Strings and input stream token lists} +% +% \begin{macro}{\cs_to_str:N} +% 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{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:} +% \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} +% +% 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} +% \label{sec:predicates} +% +% \LaTeX3 has three concepts for conditional flow processing: +% \begin{enumerate} +% +% \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 +% example would be +% \begin{quote} +% "\cs_free:cTF{abc}{...}{...}" +% \end{quote} +% a function that will turn the first argument into a control sequence +% (since its marked as "c") then checks whether this control sequence is +% still free and then depending on the result carry out the code in the +% second argument (true case) or in the third argument (false case). +% +% \item +% Functions that return a special type of boolean value which can be +% tested by the function "\if:w". All functions of this type +% have names that end with "_p" in the description part. For example +% \begin{quote} +% "\cs_free_p:N" +% \end{quote} +% would be a predicate function for the same type of test as the +% function above. It would return `true' if its argument (a single token +% denoted by "N") is still free for definition. It would be used in +% constructions like +% \begin{quote} +% "\if:w \cs_free_p:N \l_foo_bar ... \else: ... \fi:" +% \end{quote} +% +% \item +% Actually there is a third one, namely the original concept used in +% plain \TeX{}. This belongs to the second form but needs further +% 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 +% 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{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} +% +% \subsection{Predicate implementation} +% +% 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|. +% +% +% \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} +% +% \begin{macrocode} +%</package> +%<*showmemory> +\showMemUsage +%</showmemory> +% \end{macrocode} +% + diff --git a/Master/texmf-dist/source/latex/expl3/l3chk.dtx b/Master/texmf-dist/source/latex/expl3/l3chk.dtx new file mode 100644 index 00000000000..56b9cf5c34c --- /dev/null +++ b/Master/texmf-dist/source/latex/expl3/l3chk.dtx @@ -0,0 +1,358 @@ +% \iffalse +%% File: l3chk.dtx Copyright (C) 1990-1998 LaTeX3 project +% +%<*dtx> + \ProvidesFile{l3chk.dtx} +%</dtx> +%<package>\NeedsTeXFormat{LaTeX2e} +%<package>\ProvidesPackage{l3chk} +%<driver> \ProvidesFile{l3chk.drv} +% \fi +% \ProvidesFile{l3chk.dtx} + [1998/04/20 v1.0e L3 Experimental check module] +% +% \iffalse +%<*driver> +\documentclass{l3doc} + +\begin{document} +\DocInput{l3chk.dtx} +\end{document} +%</driver> +% \fi +% +% \GetFileInfo{l3chk.dtx} +% \title{The \textsf{l3chk} package\thanks{This file +% has version number \fileversion, last +% revised \filedate.}\\ +% Checking things\ldots} +% \author{\Team} +% \date{\filedate} +% \maketitle +% +% \section{The chk module} +% +% To ensure that functions and variables are properly used certain +% checking functions are implemented that may or may not be compiled +% into the final format. +% +% \subsection{Functions} +% +% \begin{function}{% +% \chk_var_or_const:N | +% } +% \begin{syntax} +% "\chk_var_or_const:N" <cs> +% \end{syntax} +% Checks that <cs> is a proper variable or constant which means that its +% name starts out with "\L", "\l", "\G", "\g", "\R", "\C", "\c", or "\q". +% \end{function} +% +% \begin{function}{% +% \chk_local:N | +% \chk_global:N | +% } +% \begin{syntax} +% "\chk_local:N" <cs> +% \end{syntax} +% Checks that <cs> is a proper local or global variable. This means that +% its name starts out with "\L", "\l", or "\G", "\g" respectively. +% \end{function} +% +% \begin{function}{% +% \chk_local_or_pref_global:N | +% \pref_global_chk: | +% } +% To allow implementations where we precede some function with +% "\pref_global:D" without loosing the possibility to check for the +% correct variable type the following helper functions can be used: +% "\chk_local_or_pref_global:N" <cs> is the variable check which is +% usually let to "\chk_local:N", i.e.\ it will check that its argument +% is a local variable. This behavior will be changed by +% "\pref_global_chk:". This function first changes +% "\chk_local_or_pref_global:N" to check for global variables then it +% issues a "\pref_global:D". After use "\chk_local_or_pref_global:N" +% will restore itself to "\chk_local:N". So, if we use +% "\chk_local_or_pref_global:N" inside some function "\foo_bar:n" we can +% implement a global version "\foo_gbar:n" by defining +% \begin{quote} +% "\def_new:Npn \foo_gbar:n {\pref_global_chk: \foo_bar:n }" +% \end{quote} +% provided that "\foo_bar:n" is built in a way that prefixing it with +% "\pref_global:D" turns its operation into a global one. See +% implementation for details. +% \end{function} +% +% \subsection{Constants} +% +% \begin{variable}{\c_undefined} +% This constant is always undefined and therefore can be used to check +% for free function names. +% \end{variable} +% +% \subsection{Internal functions} +% +% \begin{function}{% +% \chk_global_aux:w | +% \chk_local_aux:w | +% \chk_var_or_const_aux:w | +% } +% Helper functions that implement the checking. +% \end{function} +% +% \StopEventually{} +% +% \section{The code} +% +% We start by ensuring that the required packages are loaded. +% \begin{macrocode} +%<package>\RequirePackage{l3basics} +%<package>\RequirePackage{l3int} +%<*package> +% \end{macrocode} +% +% The |\chk| module contains those functions that are used primarily +% during the development of \LaTeX3 for checking that things are not mixed up +% too badly. All these functions are of type `{\tt e}' since they +% issue error messages if certain conditions are violated. +% +% \subsection{Checking variable assignments} +% +% \begin{macro}{\chk_local:N} +% \begin{macro}{\chk_local_aux:w} +% This function checks that its argument is a proper local +% variable, i.e.\ its name starts with |\l| or |\L|. +% It is not allowed that the name starts with |\g| or |\G|, +% which means that we do not allow to update global +% variables locally. But see |\pref_global_chk:| below for +% the encoding of functions that might accept global variables +% in certain situations. Not checked is the case that the +% argument isn't a variable at all, i.e.\ it doesn't have +% a |_| as second letter. Maybe we should add this for safety +% during the implementation since it will find certain errors +% involving wrong expansion in earlier stage. +% \begin{macrocode} +\def_new:Npn \chk_local:N #1{\exp_after:NN + \chk_local_aux:w \token_to_string:N#1\q_stop} +\def_new:Npn \chk_local_aux:w #1#2#3\q_stop{ + \if_num:w\tex_uccode:D`#2=`G\scan_stop: + \err_latex_bug:n{Local~mismatch:~local~function~called~with~ + global~variable:^^J\text_put_four_sp: #1#2#3~ + on~line~\tex_the:D\tex_inputlineno:D} + \else: + \if_num:w\tex_uccode:D`#2=`L\scan_stop: + \else: + \err_latex_bug:n{Variable~mismatch:~function~not~called~with~ + proper~variable:^^J\text_put_four_sp: #1#2#3~ + on~line~\tex_the:D\tex_inputlineno:D}\fi: + \fi:} +% \end{macrocode} +% We set the |\l_iow_new_line_code| at this point, just in case we +% run into errors. +% \begin{macrocode} +\tex_newlinechar:D=`\^^J +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\chk_global:N} +% \begin{macro}{\chk_global_aux:w} +% |\chk_global:N| is similar to |\chk_local:N| but looks only +% for global variables. +% \begin{macrocode} +\def_new:Npn \chk_global:N #1{\exp_after:NN + \chk_global_aux:w \token_to_string:N#1\q_stop} +\def_new:Npn \chk_global_aux:w #1#2#3\q_stop{ + \if_num:w\tex_uccode:D`#2=`L\scan_stop: + \err_latex_bug:n{Global~mismatch:~global~function~called~with~ + local~variable:~#1#2#3~ + on~line~\tex_the:D\tex_inputlineno:D} + \else: + \if_num:w\tex_uccode:D`#2=`G\scan_stop: + \else: + \err_latex_bug:n{Variable~mismatch:~function~not~called~with~ + proper~variable:~#1#2#3~ + on~line~\tex_the:D\tex_inputlineno:D}\fi:\fi:} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\pref_global_chk:} +% \begin{macro}{\chk_local_or_pref_global:N} +% To allow implementations where we precede some function with +% |\pref_global:D| without loosing the possibility to check for the +% correct type of a variable, the following helper functions can be +% used: |\chk_local_or_pref_global:N| \m{variable} is the variable +% check which is usually |\let:NN| to |\chk_local:N|, i.e.\ it will +% check for local variables. This behavior will be changed by +% |\pref_global_chk:|. This function first changes +% |\chk_local_or_pref_global:N| to check for global variables, then +% issues a |\pref_global:D|. After being used, +% |\chk_local_or_pref_global:N| will restore itself to +% |\chk_local:N|. So, if we use |\chk_local_or_pref_global:N| +% inside some function |\foo_bar:n| we can implement a global +% version |\foo_gbar:n| by defining +% \begin{verbatim} +% \def_new:Npn \foo_gbar:n {\pref_global_chk: \foo_bar:n } +%\end{verbatim} +% provided of course, that |\foo_bar:n| is defined in a way that a +% |\pref_global:D| does work. Such a scheme has to be used +% carefully, but its advantage is that the checking version has the +% same structure as a streamlined version, we only have to change +% |\pref_global_chk:| into |\pref_global:D| and omit the +% |\chk_local_or_pref_global:N| function in the body. +% \begin{macrocode} +\def_new:Npn \pref_global_chk: { + \gdef:Npn \chk_local_or_pref_global:N ##1{ + \chk_global:N ##1 + \glet:NN \chk_local_or_pref_global:N \chk_local:N} + \pref_global:D} +\let_new:NN \chk_local_or_pref_global:N \chk_local:N +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\chk_var_or_const:N} +% \begin{macro}{\chk_var_or_const_aux:w} +% |\chk_var_or_const:N| is used in situations where we want to check +% that we have a variable (or a constant) but do not care whether +% or not it is global (for example, in allocation routines). +% \begin{macrocode} +\def_new:Npn \chk_var_or_const:N #1{\exp_after:NN + \chk_var_or_const_aux:w \token_to_string:N#1\q_stop } +\def_new:Npn \chk_var_or_const_aux:w #1#2#3\q_stop { + \if_num:w\tex_uccode:D`#2=`L\scan_stop: + \else: + \if_num:w\tex_uccode:D`#2=`G\scan_stop: + \else: + \if_num:w\tex_uccode:D`#2=`C\scan_stop: + \else: +% \end{macrocode} +% We also allow the beast to be a quark, i.e.\ to start with |\q|. +% \begin{macrocode} + \if_char_code:w#2q\scan_stop: + \else: +% \end{macrocode} +% We might also want to allow that it is a user definable +% variable which means that its name consists of letters only. We +% could check this by testing that there is no |_|, but this is not +% implemented so far. +% \begin{macrocode} + \err_latex_bug:n{Variable~mismatch:~function~not~called~with~ + proper~variable:^^J\text_put_four_sp: #1#2#3~ + on~line~\tex_the:D\tex_inputlineno:D}\fi:\fi:\fi: + \fi:} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% \subsection{Doing some tracing} +% +% \begin{macro}{\tracingall} +% \begin{macro}{\absolutelytracingall} +% \begin{macro}{\donotcheck} +% During |\tracingall| we don't want to see all this code coming +% from the checking functions since something more substantial is +% probably wrong. Therefore this definition of it turns the +% functions of as far as possible. +% \begin{macrocode} +\def_new:Npn\donotcheck{ + \let:NN \chk_global:N \use_none:n + \let:NN \chk_local:N \use_none:n + \let:NN \chk_local_or_pref_global:N \use_none:n + \let:NN \pref_global_chk: \pref_global:D + \let:NN \chk_new_cs:N \use_none:n + \let:NN \chk_exist_cs:N \use_none:n + \let:NN \chk_var_or_const:N \use_none:n + \let:NN \cs_record_name:N \use_none:n + \let:NN \cs_record_name:c \use_none:n + \let:NN \cs_record_meaning:N \use_none:n + \let:NN \register_record_name:N \use_none:n +} +\def_new:Npn\absolutelytracingall{ +% \end{macrocode} +% \end{macro} +% +% We do the settings by hand to avoid uninteresting lines in the +% log file as much as possible. +% \begin{macrocode} + \pref_global:D\g_trace_commands_status\c_two + \pref_global:D\g_trace_statistics_status\c_two + \pref_global:D\g_trace_pages_status\c_one + \pref_global:D\g_trace_output_status\c_one + \pref_global:D\g_trace_chars_status\c_one + \pref_global:D\g_trace_macros_status\c_two + \pref_global:D\g_trace_paragraphs_status\c_one + \pref_global:D\g_trace_restores_status\c_one + \pref_global:D\g_trace_box_breadth_int\c_ten_thousand + \pref_global:D\g_trace_box_depth_int\c_ten_thousand + \pref_global:D\g_trace_online_status\c_one + \mode_errorstop:D} +% +% Use LaTeX2e definition for now. +%\def_new:Npn\tracingall{ +% \donotcheck +% \absolutelytracingall +%} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\tracingoff} +% This macro turns off all tracing. +% \begin{macrocode} +\def_new:Npn\tracingoff{ +% \end{macrocode} +% First we turn off |\g_trace_online_status| so that we get minimal +% rubbish on the terminal. Of course, in the log file all +% assignments are shown. +% \begin{macrocode} + \pref_global:D\g_trace_online_status\c_zero + \pref_global:D\g_trace_commands_status\c_zero + \pref_global:D\g_trace_statistics_status\c_zero + \pref_global:D\g_trace_pages_status\c_zero + \pref_global:D\g_trace_output_status\c_zero + \pref_global:D\g_trace_chars_status\c_zero + \pref_global:D\g_trace_macros_status\c_zero + \pref_global:D\g_trace_paragraphs_status\c_zero + \pref_global:D\g_trace_restores_status\c_zero + \pref_global:D\g_trace_box_breadth_int\c_zero + \pref_global:D\g_trace_box_depth_int\c_zero +} +% \end{macrocode} +% \end{macro} +% +% \subsection{Tracing modules} +% +% \begin{macro}{\traceon} +% \begin{macro}{\traceoff} +% Turning the tracing of modules on or off. (primitive version). +% \begin{macrocode} +%<*trace> +\def_new:Npn\traceon#1{\for_clist:Nnn\l_tmpa_tlp{#1} + { + \cs_free:cF{g_trace_\l_tmpa_tlp _status} + {\int_gincr:c{g_trace_\l_tmpa_tlp _status}} + }} +\def_new:Npn\traceoff#1{\for_clist:Nnn\l_tmpa_tlp{#1} + { + \cs_free:cF{g_trace_\l_tmpa_tlp _status} + {\int_gdecr:c{g_trace_\l_tmpa_tlp _status}} + }} +%</trace> +%<-trace>\let_new:NN\traceon\use_none:n +%<-trace>\let_new:NN\traceoff\use_none:n +%</package> +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% Show token usage: +% \begin{macrocode} +%<*showmemory> +\showMemUsage +%</showmemory> +% \end{macrocode} +% diff --git a/Master/texmf-dist/source/latex/expl3/l3expan.dtx b/Master/texmf-dist/source/latex/expl3/l3expan.dtx new file mode 100644 index 00000000000..7f634d74f77 --- /dev/null +++ b/Master/texmf-dist/source/latex/expl3/l3expan.dtx @@ -0,0 +1,705 @@ +% \iffalse +%% File: l3expan.dtx Copyright (C) 1990-1998 LaTeX3 project +% +%<*dtx> + \ProvidesFile{l3expan.dtx} +%</dtx> +%<package>\NeedsTeXFormat{LaTeX2e} +%<package>\ProvidesPackage{l3expan} +%<driver> \ProvidesFile{l3expan.drv} +% \fi +% \ProvidesFile{l3expan.dtx} + [1998/04/20 v1.0e L3 Experimental Argument Expansion module] +% +% \iffalse +%<*driver> +\documentclass{l3doc} + +\begin{document} +\DocInput{l3expan.dtx} +\end{document} +%</driver> +% \fi +% +% +% \GetFileInfo{l3expan.dtx} +% \title{The \textsf{l3expan} package\thanks{This file +% has version number \fileversion, last +% revised \filedate.}\\ +% Controlling Expansion of Command Arguments} +% \author{\Team} +% \date{\filedate} +% \maketitle +% +% +% \section{\LaTeX3 functions} +% +% All \LaTeX3 functions contain a colon in their +% name. Characters following the colon are used to denote the number and +% the ``type'' of arguments that the function takes. An uppercase "N" is +% used to denote an argument that consists of a single token and a +% lowercase "n" is used when the argument can consist of several tokens +% surrounded by braces. In case of "n" arguments that consist of a +% single token the surrounding braces can be omitted in nearly all +% situations---functions that force the use of braces even for single +% token arguments are explicitly mentioned. For example, "\seq_gpush:Nn" +% is a function that takes two arguments, the first is a single token +% (the sequence) and the second may consist of several tokens surrounded +% by braces. +% +% This concept of argument specification makes it easy to read the code +% and should be followed when defining new functions. +% +% \subsection{Expanding arguments of functions} +% +% Within code it is often necessary to expand or partially expand +% arguments before passing it on to some function. For example, if the +% token list pointer "\l_tmpa_tlp" contains the current file +% that should be pushed onto some stack, we can not write +% \begin{quote} +% "\seq_gpush:Nn" \\ +% " \g_file_name_stack" \\ +% " \l_tmpa_tlp" +% \end{quote} +% since this would put the token "\l_tmpa_tlp" and not its +% contents on the stack. Instead a suitable number of "\exp_after:NN" +% would be necessary (together with extra braces) to change the order of +% execution, i.e. +% \begin{quote} +% "\exp_after:NN" \\ +% " \seq_gpush:Nn" \\ +% "\exp_after:NN" \\ +% " \g_file_name_stack" \\ +% "\exp_after:NN" \\ +% " {\l_tmpa_tlp}" +% \end{quote} +% +% The above example is probably the simplest case but is already shows +% how the code changes to something difficult to understand. Therefore +% \LaTeX3 provides the programmer with a general scheme that keeps the +% code compact and easy to understand. +% To denote that some argument to a function needs special treatment one +% just uses different letters in the argument part of the function to +% mark the desired behavior. In the above example one would write +% \begin{quote} +% "\seq_gpush:No" \\ +% " \g_file_name_stack" \\ +% " \l_tmpa_tlp" +% \end{quote} +% to achieve the desired effect. Here the "o" stands for expand this +% (the second) argument once before passing it to the function. +% +% The following letters can be used to denote special treatment of +% arguments before passing it to the basic function: +% \begin{description} +% \item[o] One time expanded token or token-list. In the latter case, +% effectively only the first token in the list gets expanded. Since +% the expansion might result in more than one token, the result is +% surrounded for further processing with braces. +% +% \item[x] Fully expanded token or token-list. Like "o" but the +% argument is expanded using "\def:Npx" before it is passed on. This means +% that expansion takes place until only unexpandable tokens are left. +% +% \item[N,O,X] Like "n", "o", "x" but the argument must be a single +% token without any braces around it. +% +% \item[c] A character string or a token-list that ultimately expands +% to characters. This string (after expansion) is used to construct a +% command name that is eventually passed on. +% +% \item[C] A character string or a token-list that ultimately expands +% to characters. From this string (after expansion) a command name is +% constructed and then this command name is expanded once (like "o"). +% The result of this is eventually passed on. In other words +% \begin{quote} +% "\seq_gpush:NC" \\ +% " \g_file_name_stack" \\ +% " {l_tmpa_tlp}" +% \end{quote} +% Has the same effect as the example above. +% +% +% +% \end{description} +% +% Due to memory constraints not all possible variations are implemented +% for every base function. Instead only those that are used within the +% \LaTeX3 kernel or otherwise seem of general interest are implemented. +% Consult the module description to find out which functions are +% actually defined. The next section explains how to define missing +% variants. +% +% \subsection{Defining new variants} +% +% The definition of variant forms for base functions may be necessary +% when writing new functions or when applying a kernel function in a +% situation that we haven't thought of before. +% +% Internally preprocessing of arguments is done with functions from the +% "\exp_" module. They all look alike, an example would be +% "\exp_args:NNo". This function has three arguments, the first and the +% second are a single tokens the third argument gets +% expanded once. If "\seq_gpush:No" wouldn't be defined the example +% above could be coded in the following way: +% \begin{quote} +% "\exp_args:NNo\seq_gpush:Nn" \\ +% " \g_file_name_stack" \\ +% " \l_tmpa_tlp" +% \end{quote} +% In other words, the first argument to "\exp_args:NNo" is the base +% function and the other arguments are preprocessed and then passed to +% this base function. In the example the first argument to the base +% function should be a single token which is left unchanged while the +% second argument is expanded once. From this example we can also see +% how the variants are defined. They just expand into the appropriate +% "\exp_" function followed by the desired base function, e.g. +% \begin{quote} +% "\def_new:Npn\seq_gpush:No{\exp_args:NNo\seq_gpush:Nn}" +% \end{quote} +% Providing variants in this way in style files is uncritical as the +% "\def_new:Npn" function will silently accept definitions whenever the +% new definition is identical to an already given one. Therefore adding +% such definition to later releases of the kernel will not make such +% style files obsolete. +% +% The available internal functions for argument expansion come in to +% flavours, some of them are faster then others. Therefore it is usually +% best to follow the following guidelines when defining new functions +% that are supposed to come with variant forms: +% \begin{itemize} +% \item +% Arguments that might need expansion should come first in the list of +% arguments to make processing faster. +% \item +% Arguments that should consist of single tokens should come first. +% \item +% Arguments that need full expansion (i.e., are denoted with "x") +% should be avoided if possible as they can not be processed very fast. +% \item +% In general "n", "x", and "o" (if not in the last position) will +% need special processing which is not fast and not expandable, i.e., +% functions of this type may not work correctly in arguments that are +% itself subject to "x" expansion. Therefore it is best to use the +% ``expandable'' functions (i.e., those that contain only "c", "N", "O" +% or "o" in the last position) whenever possible. +% \end{itemize} +% +% \subsection{Manipulating the first argument} +% +% \begin{function}{% +% \exp_args:No +% } +% \begin{syntax} +% " \exp_args:No" <funct> <arg1> <arg2> "..." +% \end{syntax} +% The first argument of <funct> (i.e., <arg1>) is expanded once, the +% result is surrounded by braces and passed to <funct>. <funct> may have +% more than one argument---all others are passed unchanged. +% \end{function} +% +% \begin{function}{% +% \exp_args:Nc +% } +% \begin{syntax} +% " \exp_args:Nc" <funct> <arg1> <arg2> "..." +% \end{syntax} +% The first argument of <funct> (i.e., <arg1>) is expanded until only +% characters remain. (An internal error occurs if something else is the +% result of this expansion.) Then the result is turned into a control +% sequence and passed to <funct> as the first argument. <funct> may have +% more than one argument---all others are passed unchanged. +% \end{function} +% +% \begin{function}{% +% \exp_args:NC +% } +% \begin{syntax} +% " \exp_args:Nc" <funct> <arg1> <arg2> "..." +% \end{syntax} +% The first argument of <funct> (i.e., <arg1>) is expanded until only +% characters remain. (An internal error occurs if something else is the +% result of this expansion.) Then the result is turned into a control +% sequence which is then expanded once more. The result of this is then +% passed to <funct> as the first argument. <funct> may have more than +% one argument---all others are passed unchanged. +% \end{function} +% +% \begin{function}{% +% \exp_args:Nx +% } +% \begin{syntax} +% " \exp_args:Nx" <funct> <arg1> <arg2> "..." +% \end{syntax} +% The first argument of <funct> (i.e., <arg1>) is fully expanded until +% only unexpandable tokens remain, the result is surrounded by braces +% and passed to <funct>. <funct> may have more than one argument---all +% others are passed unchanged. +% As mentioned before, this type of function is relatively slow. +% \end{function} +% +% \subsection{Manipulating two arguments} +% +% \begin{function}{% +% \exp_args:Nno | +% \exp_args:NNx | +% \exp_args:Nnx | +% \exp_args:Noo | +% \exp_args:Nox | +% \exp_args:Nxo | +% \exp_args:Nxx | +% } +% \begin{syntax} +% "\exp_args:Nno" <funct> <arg1> <arg2> "..." +% \end{syntax} +% The above functions all manipulate the first two arguments of <funct>. +% They are all slow and non-expandable. +% \end{function} +% +% \begin{function}{% +% \exp_args:NNo | +% \exp_args:NNc | +% \exp_args:NOo | +% \exp_args:NOc | +% \exp_args:Nco | +% \exp_args:Ncc | +% } +% \begin{syntax} +% "\exp_args:NNo" <funct> <arg1> <arg2> "..." +% \end{syntax} +% These are the fast and expandable functions for the first two arguments. +% \end{function} +% +% \subsection{Manipulating three arguments} +% +% So far not all possible functions are provided and even the selection +% below may be reduced in the future as far as the non-expandable +% functions are concerned. +% +% \begin{function}{% +% \exp_args:Nnno | +% \exp_args:Nnnx | +% \exp_args:Noox | +% \exp_args:Nnox | +% \exp_args:Ncnx | +% } +% \begin{syntax} +% "\exp_args:Nnno" <funct> <arg1> <arg2> <arg3> "..." +% \end{syntax} +% All the above functions are non-expandable. +% \end{function} +% +% \begin{function}{% +% \exp_args:NNOo | +% \exp_args:NOOo | +% \exp_args:Nccc | +% } +% \begin{syntax} +% "\exp_args:NNOo" <funct> <arg1> <arg2> <arg3> "..." +% \end{syntax} +% These are the fast and expandable functions for the first three +% arguments. +% \end{function} +% +% \subsection{Internal functions and variables} +% +% \begin{function}{\exp_after:NN} +% \begin{syntax} +% "\exp_after:NN" <token1> <token2> +% \end{syntax} +% This will expand <token2> once before processing <token1>. This is +% similar to "\exp_args:No" except that no braces are put around the +% result of expanding <token2>. +% \begin{texnote} +% This is the primitive \tn{expandafter} which was renamed to fit into +% the naming conventions of \LaTeX3. +% \end{texnote} +% \end{function} +% +% \begin{function}{\exp_not:N | +% \exp_not:c } +% \begin{syntax} +% "\exp_not:N" <token> +% \end{syntax} +% This function will prohibit the expansion of <token> in situation +% where <token> would otherwise be replaced by it definition, e.g., +% inside an argument that is handled by the "x" convention. +% \begin{texnote} +% "\exp_not:N" is the primitive \tn{noexpand} renamed. +% \end{texnote} +% \end{function} +% +% +% \begin{function}{\exp_not:o} +% \begin{syntax} +% "\exp_not:o" <token> +% \end{syntax} +% +% The name of this command is a lie. Perhaps it should be called +% ``"exp_perhaps_once"''. What it actually does is, it expands <token> and +% then issues an "\exp_not:N" to prohibit further expansion of the +% first token in the replacement text of <token>. This means that if the +% replacement text of <token> consists of more than one token all +% further tokens are still subject to full expansion. The command is, for +% example, useful when generating a new cs name inside a "x" situation +% that shouldn't be expanded further, e.g., "\exp_not:o" "\cs:w" "foo" +% "\cs_end:". +% \begin{texnote} +% This command has no equivalent. +% \end{texnote} +% \end{function} +% +% \begin{variable}{\l_exp_tlp | \l_exp_toks} +% The "\exp_" module has its private variables to temporarily store +% results of the argument expansion. This is done to avoid interference +% with other functions using temporary variables. +% \end{variable} +% +% \StopEventually{} +% +% \section {Argument Expansion} +% +% We start by ensuring that the required packages are loaded. +% \begin{macrocode} +%<package>\RequirePackage{l3basics} +%<package>\RequirePackage{l3tlp} +%<*package> +% \end{macrocode} +% +% \subsection{General expansion} +% +% In this section a general mechanism for defining functions to handle +% argument handling is defined. +% These general expansion functions are expandable unless |x| is used. +% (Any version of |x| is going to have to use +% one of the \LaTeX3\ names for |\def:Npx| at some point, and so is never +% going to be expandable.) +% +% In a later section some common cases are coded by a more direct +% method, typically using calls to |\exp_after:NN|. +% +% \begin{macro}{\l_exp_tlp} +% We need a scratch token list pointer. +% \begin{macrocode} +\tlp_new:Nn\l_exp_tlp{} +% \end{macrocode} +% \end{macro} +% +% This code uses internal functions with names that start with |\::| +% to perform the expansions. +% \begin{macro}{\exp_arg_next:nnn} +% This is basically the same function as |\Dexp_arg_next:nnn|. +% \begin{macrocode} +\def_new:Npn\exp_arg_next:nnn#1#2#3{% + #2\:::{#3#1}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\::n} +% This function is used to skip an argument that doesn't need to +% be expanded. +% \begin{macrocode} +\def_new:Npn\::n#1\:::#2#3{% + #1\:::{#2{#3}}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\::N} +% This function is used to skip an argument that consists of a +% single token and doesn't need to be expanded. +%^^A was \let_new:NN\::N\::n (changed to match \;N above. +% \begin{macrocode} +\def_new:Npn\::N#1\:::#2#3{% + #1\:::{#2#3}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\::c} +% This function is used to skip an argument that is turned into +% as control sequence without expansion. +% \begin{macrocode} +\def_new:Npn\::c#1\:::#2#3{% + \exp_after:NN\exp_arg_next:nnn\cs:w #3\cs_end:{#1}{#2}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\::o} +% This function is used to expand an argument once. +% \begin{macrocode} +\def_new:Npn\::o#1\:::#2#3{% + \exp_after:NN\exp_arg_next:nnn\exp_after:NN{\exp_after:NN{#3}}{#1}{#2}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\::x} +% This function is used to expand an argument fully. +% +% \begin{macrocode} +\def_new:Npn\::x#1\:::#2#3{% + \tlp_set:Nx\l_exp_tlp{{{#3}}}% + \exp_after:NN\exp_arg_next:nnn\l_exp_tlp{#1}{#2}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\:::} +% Just another name for the identity function. +% \begin{macrocode} +\def_new:Npn\:::#1{#1} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\::C} +% This function creates a control sequence out of |#3| and expands +% that once before passing it on to |\exp_arg_next:nnn|. +% \begin{macrocode} +\def_new:Npn\::C#1\:::#2#3{% + \exp_after:NN\exp_C_aux:nnn\cs:w #3\cs_end:{#1}{#2}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\exp_C_aux:nnn} +% A helper function for |\::C| wich expands its argument before +% passing it on to |\exp_arg_next:nnn|. +% \begin{macrocode} +\def_new:Npn\exp_C_aux:nnn #1 + { + \exp_after:NN + \exp_arg_next:nnn + \exp_after:NN + { + \exp_after:NN + {#1} + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\exp_args:NC} +% \begin{macro}{\exp_args:Nccx} +% \begin{macro}{\exp_args:Ncnx} +% \begin{macro}{\exp_args:NNno} +% \begin{macro}{\exp_args:Nnno} +% \begin{macro}{\exp_args:Nnnx} +% \begin{macro}{\exp_args:Nno} +% \begin{macro}{\exp_args:Nnox} +% \begin{macro}{\exp_args:NNx} +% \begin{macro}{\exp_args:Nnx} +% \begin{macro}{\exp_args:Noo} +% \begin{macro}{\exp_args:Noox} +% \begin{macro}{\exp_args:Nox} +% \begin{macro}{\exp_args:Nx} +% \begin{macro}{\exp_args:Nxx} +% \begin{macro}{\exp_args:Nxx} +% Here are the actual function definitions, using the helper functions +% above. +% \begin{macrocode} +\def:Npn \exp_args:NC {\::C\:::} +%\def:Npn \exp_args:Nc {\::c\:::} +%\def:Npn \exp_args:Ncc {\::c\::c\:::} +%\def:Npn \exp_args:Nccc {\::c\::c\::c\:::} +\def:Npn \exp_args:Nccx {\::c\::c\::x\:::} +\def:Npn \exp_args:Ncnx {\::c\::n\::x\:::} +%\def:Npn \exp_args:Nco {\::c\::o\:::} +%\def:Npn \exp_args:NNc {\::N\::c\:::} +%\def:Npn \exp_args:NNNo {\::N\::N\::o\:::} +\def:Npn \exp_args:NNno {\::N\::n\::o\:::} +\def:Npn \exp_args:Nnno {\::n\::n\::o\:::} +\def:Npn \exp_args:Nnnx {\::n\::n\::x\:::} +%\def:Npn \exp_args:NNo {\::N\::o\::\:::} +\def:Npn \exp_args:Nno {\::n\::o\:::} +%\def:Npn \exp_args:NNOo {\::N\::O\::o\:::} +\def:Npn \exp_args:Nnox {\::n\::o\::x\:::} +\def:Npn \exp_args:NNx {\::N\::x\:::} +\def:Npn \exp_args:Nnx {\::n\::x\:::} +%\def:Npn \exp_args:No {\::o\:::} +%\def:Npn \exp_args:NOc {\::O\::c\:::} +%\def:Npn \exp_args:NOo {\::O\::o\:::} +\def:Npn \exp_args:Noo {\::o\::o\:::} +%\def:Npn \exp_args:NOOo {\::O\::O\::o\:::} +\def:Npn \exp_args:Noox {\::o\::o\::x\:::} +\def:Npn \exp_args:Nox {\::o\::x\:::} +\def:Npn \exp_args:Nx {\::x\:::} +\def:Npn \exp_args:Nxo {\::x\::o\:::} +\def:Npn \exp_args:Nxx {\::x\::x\:::} +% \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} +% +% +% \subsection{Preventing expansion} +% +% \begin{macro}{\exp_not:N} +% This is the \TeX\ primitive that was defined earlier. +% \end{macro} +% +% \begin{macro}{\exp_not:o} +% \begin{macro}{\exp_not:c} +% Two helper functions, which we can probably live without it. +% \begin{macrocode} +\def_new:Npn\exp_not:o{\exp_after:NN\exp_not:N} +\def_new:Npn\exp_not:c#1{\exp_after:NN\exp_not:N\cs:w#1\cs_end:} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \subsection{Single token expansion} +% +% Expansion for arguments that are single tokens is done with the +% functions below. I first thought of using a different module name +% but then I saw that this wouldn't do since I could then never +% determine for, say, |\seq_put:no| whether this means single, or +% general expansion. Therefore I decided to use uppercase `O' for +% single expansion. +% +% One of the most important features of these functions is that they +% are fully expandable and therefore allow to prefix them with +% |\pref_global:D| for example. This together with the fact that the +% above concept is much slower in general means that we should convert +% whenever possible and perhaps remove all remaining occurences by +% hand-encoding in the end. +% +% \begin{macro}{\exp_args:No} +% \begin{macro}{\exp_args:NOo} +% \begin{macro}{\exp_args:NNo} +% \begin{macro}{\exp_args:NOOo} +% \begin{macro}{\exp_args:NNOo} +% \begin{macro}{\exp_args:NNNo} +% This looks somewhat horrible but it runs well with the other +% syntax. It is important to see that these functions really need +% single tokens as arguments whenever capital letters are used. +% \begin{macrocode} +\def_new:Npn \exp_args:No #1#2{\exp_after:NN#1\exp_after:NN{#2}} +\def_new:Npn \exp_args:NOo #1#2#3{\exp_after:NN\exp_args:No \exp_after:NN#1 + \exp_after:NN#2\exp_after:NN{#3}} +\def_new:Npn \exp_args:NOOo #1#2#3#4{\exp_after:NN\exp_args:NOo + \exp_after:NN#1\exp_after:NN#2\exp_after:NN#3\exp_after:NN{#4}} +\def_new:Npn \exp_args:NNo #1#2#3{\exp_after:NN#1\exp_after:NN#2 + \exp_after:NN{#3}} +\def_new:Npn \exp_args:NNOo #1#2#3#4{\exp_after:NN\exp_args:NNo + \exp_after:NN#1\exp_after:NN#2\exp_after:NN#3\exp_after:NN{#4}} +\def_new:Npn \exp_args:NNNo #1#2#3#4{\exp_after:NN#1\exp_after:NN#2 + \exp_after:NN#3\exp_after:NN{#4}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\exp_args:Nc} +% \begin{macro}{\exp_args:NNc} +% \begin{macro}{\exp_args:NOc} +% \begin{macro}{\exp_args:Ncc} +% \begin{macro}{\exp_args:Nccc} +% Here are the functions that turn their argument into csnames but +% are expandable. +% \begin{macrocode} +\def_new:Npn \exp_args:Nc #1#2{\exp_after:NN#1\cs:w#2\cs_end:} +\def_new:Npn \exp_args:NNc #1#2#3{\exp_after:NN#1\exp_after:NN#2 + \cs:w#3\cs_end:} +\def_new:Npn \exp_args:NOc#1#2#3{\exp_after:NN\exp_args:No\exp_after:NN + #1\exp_after:NN#2\cs:w#3\cs_end:} +\def_new:Npn \exp_args:Ncc #1#2#3{\exp_after:NN#1 + \cs:w#2\exp_after:NN\cs_end:\cs:w#3\cs_end:} +\def_new:Npn \exp_args:Nccc #1#2#3#4{\exp_after:NN#1 + \cs:w#2\exp_after:NN\cs_end:\cs:w#3\exp_after:NN + \cs_end:\cs:w #4\cs_end:} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\exp_args:Nco} +% If we force that the third argument +% always has braces, we could implement this function +% with less tokens and only two arguments. +% \begin{macrocode} +\def_new:Npn \exp_args:Nco #1#2#3{\exp_after:NN#1\cs:w#2\exp_after:NN + \cs_end:\exp_after:NN{#3}} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\exp_def_form:nnn} +% This command is a recent addition which was actually added +% when we wrote the article for TUGboat (while most of the other +% code goes way back to 1993). +% \begin{macrocode} +\def:Npn\exp_def_form:nnn#1#2#3{ + \exp_after:NN + \def:Npn + \cs:w + #1:#3 + \exp_after:NN + \cs_end: + \exp_after:NN + { + \cs:w + exp_args:N#3 + \exp_after:NN + \cs_end: + \cs:w + #1:#2 + \cs_end: + } +% \end{macrocode} +% We also have to test if |exp_arg:N#3| is already defined +% and if not define it via the +% |\::| commands using the chars in |#3| +% \begin{macrocode} + \cs_free:cT + {exp_args:N#3} + {\def:cpx {exp_args:N#3} + {\exp_args_form_x:w #3 :} + } +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\exp_args_form_x:w} +% This command graps char by char outputting |\::#1| (not expanded +% further) until we see a |:|. That colon is in fact also turned into +% |\:::| so that the required structure for |\exp_args...| commands +% is correctly terminated. +% \begin{macrocode} +\def_new:Npn\exp_args_form_x:w #1 { + \exp_after:NN \exp_not:N \cs:w ::#1 \cs_end: + \if_meaning:NN #1 : + \else: + \exp_after:NN\exp_args_form_x:w + \fi:} +% \end{macrocode} +% \end{macro} + +% Show token usage: +% \begin{macrocode} +%</package> +%<*showmemory> +\showMemUsage +%</showmemory> +% \end{macrocode} +% +% + + + diff --git a/Master/texmf-dist/source/latex/expl3/l3int.dtx b/Master/texmf-dist/source/latex/expl3/l3int.dtx new file mode 100644 index 00000000000..d219a9d27bb --- /dev/null +++ b/Master/texmf-dist/source/latex/expl3/l3int.dtx @@ -0,0 +1,755 @@ +% \iffalse +%% File: l3int.dtx Copyright (C) 1990-1998 LaTeX3 project +% +%<*dtx> + \ProvidesFile{l3int.dtx} +%</dtx> +%<package>\NeedsTeXFormat{LaTeX2e} +%<package>\ProvidesPackage{l3int} +%<driver> \ProvidesFile{l3int.drv} +% \fi +% \ProvidesFile{l3int.dtx} + [1998/04/20 v1.0c L3 Experimental Integer module] +% +% \iffalse +%<*driver> +\documentclass{l3doc} + +\begin{document} +\DocInput{l3int.dtx} +\end{document} +%</driver> +% \fi +% +% +% \GetFileInfo{l3int.dtx} +% \title{The \textsf{l3int} package\thanks{This file +% has version number \fileversion, last +% revised \filedate.}\\ +% Counters} +% \author{\Team} +% \date{\filedate} +% \maketitle +% +% \section{Counters} +% +% \LaTeX3 maintains two type of integer registers for internal use. +% One (associated with the name "int") uses the builtin counter +% registers of \TeX{} and is therefore relatively fast and one +% (associated with the name "fint" for fake counter) that implements the +% operations within the \TeX{} macro language and is therefore much +% slower in processing. This type of counter is also far more restricted +% in its range. +% +% The fake counter should be used for variables that are not accessed +% very often since this saves the important fast internal registers +% (\TeX{} has only 255 of those). For example, all allocation routines +% in \LaTeX3 make use of fake counters to remember the values of recent +% allocated register numbers etc. +% +% Since all functions for both types are very similar (they usually +% differ only in the initial "f") we describe them together. But +% remember that you need to use "fint" variables when using "fint" +% functions. +% +% \subsection{Functions} +% +% \begin{function}{% +% \int_new:N | +% \int_new:c | +% \fint_new:N | +% } +% \begin{syntax} +% "\int_new:N" <int> +% "\fint_new:N" <fint> +% \end{syntax} +% Defines <int> to be a new variable of type "int". There is no way to +% define constant counters with these functions. +% \begin{texnote} +% "\int_new:N" is the equivalent to plain \TeX{}'s \tn{newcount}. +% However, the internal register allocation is done differently. +% \end{texnote} +% \end{function} +% +% \begin{function}{% +% \int_incr:N | +% \int_gincr:N | +% \int_gincr:c | +% \fint_incr:N | +% \fint_gincr:N | +% } +% \begin{syntax} +% "\int_incr:N" <int> +% "\fint_incr:N" <fint> +% \end{syntax} +% Increments <int> by one. For global variables the global versions +% should be used. +% \end{function} +% +% \begin{function}{% +% \int_decr:N | +% \int_gdecr:N | +% \int_gdecr:c | +% \fint_decr:N | +% \fint_gdecr:N | +% } +% \begin{syntax} +% "\int_decr:N" <int> +% "\fint_decr:N" <fint> +% \end{syntax} +% Decrements <int> by one. For global variables the global versions +% should be used. +% \end{function} +% +% \begin{function}{% +% \int_set:Nn | +% \int_set:cn | +% \int_gset:Nn | +% \int_gset:cn | +% \fint_set:Nn | +% \fint_gset:Nn | +% } +% \begin{syntax} +% "\int_set:Nn" <int> "{" <integer> "}" +% "\fint_set:Nn" <fint> "{" <integer> "}" +% \end{syntax} +% These functions will set the <int> register to the <integer> value. +% \end{function} +% +% \begin{function}{% +% \fint_set_eq:NN | +% \fint_gset_eq:NN | +% } +% \begin{syntax} +% "\fint_set_eq:NN" <fint1> <fint2> +% \end{syntax} +% Fast form for +% \begin{syntax} +% "\fint_set:No" <fint1> "{\fint_use:N" <fint2> "}" +% \end{syntax} +% when <fint2> is known to be a variable of fake counter. Note that a +% corresponding function for real counters is not implemented since the +% "\int_set:Nn" function does this operation sufficiently when then second +% argument is a <int> instead of "{"<integer>"}" value. +% \end{function} +% +% \begin{function}{% +% \int_add:Nn | +% \int_add:cn | +% \int_gadd:Nn | +% \fint_add:Nn | +% \fint_gadd:Nn | +% } +% \begin{syntax} +% "\int_add:Nn" <int> "{" <integer> "}" +% "\fint_add:Nn" <fint> "{" <integer> "}" +% \end{syntax} +% These functions will add to the <int> register the value <integer>. If +% the second argument is a <int> register too, the surrounding braces +% can be left out. +% +% It not allowed to use a <fint> instead of the <integer>. If a fake +% counter should be used as the second argument one needs to turn the +% <fint> first into an <integer> by applying "\fint_use:N". +% \end{function} +% +% \begin{function}{% +% \int_sub:Nn | +% \int_gsub:Nn | +% \fint_sub:Nn | +% \fint_gsub:Nn | +% } +% \begin{syntax} +% "\int_gsub:Nn" <int> "{" <integer> "}" +% "\fint_gsub:Nn" <fint> "{" <integer> "}" +% \end{syntax} +% These functions will subtract from the <int> register the value +% <integer>. If the second argument is a <int> register too, the +% surrounding braces can be left out. +% +% It is not allowed to use a <fint> instead of the <integer>. If a fake +% counter should be used as the second argument one needs to turn the +% <fint> first into an <integer> by applying "\fint_use:N". +% \end{function} +% +% \begin{function}{% +% \int_use:N | +% \int_use:c | +% \fint_use:N | +% } +% \begin{syntax} +% "\int_use:N" <int> +% "\fint_use:N" <fint> +% \end{syntax} +% This function returns the integer value kept in <int> in a way +% suitable for further processing. Be sure to use "\fint_use:N" if you +% are accessing the value of a fake counter because otherwise your +% result will be to some surprise to you (there is no check). +% \begin{texnote} +% The function "\int_use:N" could be implemented directly as the \TeX{} +% primitive "\tex_the:D" which is also responsible to produce the values for +% other internal quantities. We have chosen to use individual functions +% for counters, dimenions etc.\ to allow checks and to make the code +% more selfexplaining. +% \end{texnote} +% \end{function} +% +% \subsection{Formatting a counter value} +% +% \begin{function}{\int_to_arabic:n | +% \int_to_alph:n | +% \int_to_Alph:n | +% \int_to_roman:n | +% \int_to_Roman:n | +% \int_to_symbol:n | +% } +% \begin{syntax} +% "\int_to_alph:n" "{" <integer> "}" +% "\int_to_alph:n" <int> +% "\int_to_alph:n" "{" "\fint_use:N" <fint> "}" +% \end{syntax} +% If some <integer> or the the current value of a <int> should be +% displayed or typeset in a special ways (e.g., as uppercase roman +% numerals) these function can be used. We need braces if the argument +% is a simple <integer>, they can be omitted in case of a <int>. +% +% To format <fint>s with these functions it is necessary to turn the +% value of the <fint> first into an <integer> by applying "\fint_use:N" +% within the argument braces. +% +% All functions are fully expandable and will therefore produce the +% correct output when used inside of deferred writes, etc. +% \begin{texnote} +% These are more or less the internal \LaTeX2 functions \tn{@arabic}, +% \tn{@alph}, \tn{Alph}, \tn{@roman}, \tn{@Roman}, and \tn{@fnsymbol} +% except that "\int_to_symbol:n" is also allowed outside math mode. +% \end{texnote} +% \end{function} +% +% \subsection{Variable and constants} +% +% \begin{variable}{% +% \c_int_max | +% \c_fint_max | +% } +% Constant that denote the maximum value which can be stored in a <int> +% or <fint> register. +% \end{variable} +% +% \begin{variable}{% +% \c_minus_one | +% \c_zero | +% \c_one | +% \c_two | +% \c_three | +% \c_sixteen | +% \c_twohundred_fifty_five | +% \c_twohundredfiftysix | +% \c_thousand | +% \c_ten_thousand | +% \c_twenty_thousand | +% } +% Set of constants denoting useful values. +% \begin{texnote} +% Most of these constants have been available under \LaTeX2 under names +% like \tn{tw@}, \tn{thr@@} etc. +% \end{texnote} +% \end{variable} +% +% \begin{variable}{% +% \l_tmpa_int | +% \l_tmpb_int | +% \l_tmpc_int | +% \g_tmpa_int | +% \g_tmpb_int | +% } +% Scratch register for immediate use. They are not used by conditionals +% or predicate functions. +% \end{variable} +% +% +% \section{Integer registers} +% +% +% We start by ensuring that the required packages are loaded. +% \begin{macrocode} +%<package&!check>\RequirePackage{l3basics}\par +%<package&check>\RequirePackage{l3chk}\par +%<*package> +% \end{macrocode} +% +% Functions that support \LaTeX's user accessible counters should be +% added here, too. But first the internal counters. +% +% \begin{macro}{\int_incr:N} +% \begin{macro}{\int_decr:N} +% \begin{macro}{\int_gincr:N} +% \begin{macro}{\int_gdecr:N} +% Incrementing and decrementing of integer registers is done with +% the following functions. +% \begin{macrocode} +\def_new:Npn \int_incr:N #1{\tex_advance:D#1\c_one +%<*check> + \chk_local_or_pref_global:N #1 +%</check> +} +\def_new:Npn \int_decr:N #1{\tex_advance:D#1\c_minus_one +%<*check> + \chk_local_or_pref_global:N #1 +%</check> +} +\def_new:Npn \int_gincr:N { +% \end{macrocode} +% We make sure that a local variable is not updated globally by +% changing the internal test (i.e.\ |\chk_local_or_pref_global:N|) before +% making the assignment. This is done by |\pref_global_chk:| which also +% issues the necessary |\pref_global:D|. This is not very efficient, but +% this code will be only included for debugging purposes. Using +% |\pref_global:D| in front of the local function is better in the +% production versions. +% \begin{macrocode} +%<*check> + \pref_global_chk: +%</check> +%<-check> \pref_global:D + \int_incr:N} +\def_new:Npn \int_gdecr:N { +%<*check> + \pref_global_chk: +%</check> +%<-check> \pref_global:D + \int_decr:N} +% \end{macrocode} +% With the |\int_add:Nn| functions we can shorten the above code. +% If this makes it too slow \ldots +% \begin{macrocode} +\def:Npn \int_incr:N #1{\int_add:Nn#1\c_one} +\def:Npn \int_decr:N #1{\int_add:Nn#1\c_minus_one} +\def:Npn \int_gincr:N #1{\int_gadd:Nn#1\c_one} +\def:Npn \int_gdecr:N #1{\int_gadd:Nn#1\c_minus_one} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\int_new:N} +% \begin{macro}{\int_new:c} +% Allocation of a new internal counter is already done above. Here we define +% the next likely variant. +% \begin{macrocode} +\def_new:Npn \int_new:N {} % but since we don't distribute +\let:NN \int_new:N \newcount % allocation better nick the LaTeX one ... +\def_new:Npn \int_new:c {\exp_args:Nc \int_new:N} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\int_set:Nn} +% \begin{macro}{\int_set:cn} +% \begin{macro}{\int_gset:Nn} +% \begin{macro}{\int_gset:cn} +% Setting counters is again something that I would like to make +% uniform at the moment to get a better overview. +% \begin{macrocode} +\def_new:Npn \int_set:Nn #1#2{#1#2\scan_stop: +%<*check> +\chk_local_or_pref_global:N #1 +%</check> +} +\def_new:Npn \int_gset:Nn { +%<*check> + \pref_global_chk: +%</check> +%<-check> \pref_global:D + \int_set:Nn } +\def_new:Npn \int_set:cn {\exp_args:Nc \int_set:Nn } +\def_new:Npn \int_gset:cn {\exp_args:Nc \int_gset:Nn } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\int_add:Nn} +% \begin{macro}{\int_add:cn} +% \begin{macro}{\int_gadd:Nn} +% \begin{macro}{\int_sub:Nn} +% \begin{macro}{\int_gsub:Nn} +% Adding and substracting to and from a counter \ldots +% We should think of using these functions +% \begin{macrocode} +\def_new:Npn \int_add:Nn #1#2{ + \tex_advance:D#1#2\scan_stop: +%<*check> + \chk_local_or_pref_global:N #1 +%</check> +} +\def_new:Npn\int_add:cn{\exp_args:Nc\int_add:Nn} +\def_new:Npn \int_sub:Nn #1#2{ + \tex_advance:D#1-#2\scan_stop: +%<*check> +\chk_local_or_pref_global:N #1 +%</check> +} +\def_new:Npn \int_gadd:Nn { +%<*check> + \pref_global_chk: +%</check> +%<-check> \pref_global:D + \int_add:Nn } +\def_new:Npn \int_gsub:Nn { +%<*check> + \pref_global_chk: +%</check> +%<-check> \pref_global:D + \int_sub:Nn } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\int_use:N} +% \begin{macro}{\int_use:c} +% Here is how counters are accessed: +% \begin{macrocode} +\let_new:NN \int_use:N \tex_the:D +\def_new:Npn \int_use:c #1{\int_use:N \cs:w#1\cs_end:} +% \end{macrocode} +% \end{macro} +% \end{macro} + +% +% \begin{macro}{\int_gincr:c} +% \begin{macro}{\int_gdecr:c} +% We also need \ldots +% \begin{macrocode} +\def_new:Npn \int_gincr:c {\exp_args:Nc \int_gincr:N} +\def_new:Npn \int_gdecr:c {\exp_args:Nc \int_gdecr:N} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\l_tmpa_int} +% \begin{macro}{\l_tmpb_int} +% \begin{macro}{\l_tmpc_int} +% \begin{macro}{\g_tmpa_int} +% \begin{macro}{\g_tmpb_int} +% We provide two local and two global scratch counters, maybe we +% need more or less. Instead of using the allocation routines we +% partly allocate them by hand. +% \begin{macrocode} +\chk_new_cs:N \l_tmpa_int +% \end{macrocode} +% If it turns out that we don't need local counters then this +% register should be used for global counter. We might also think of +% using the |\l_last_alloc_fint| as a scratch register. +% \begin{macrocode} +\tex_countdef:D\l_tmpa_int 255 +\int_new:N \l_tmpb_int +\int_new:N \l_tmpc_int +\int_new:N \g_tmpa_int +\int_new:N \g_tmpb_int +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\c_minus_one} +% \begin{macro}{\c_zero} +% \begin{macro}{\c_one} +% \begin{macro}{\c_two} +% \begin{macro}{\c_three} +% \begin{macro}{\c_four} +% \begin{macro}{\c_sixteen} +% \begin{macro}{\c_thirty_two} +% \begin{macro}{\c_twohundred_fifty_five} +% \begin{macro}{\c_twohundred_fifty_six} +% \begin{macro}{\c_thousand} +% \begin{macro}{\c_ten_thousand} +% \begin{macro}{\c_ten_thousand_one} +% \begin{macro}{\c_ten_thousand_two} +% \begin{macro}{\c_ten_thousand_three} +% \begin{macro}{\c_ten_thousand_four} +% \begin{macro}{\c_twenty_thousand} +% \begin{macro}{\c_int_max} +% And the usual constants, others are still missing. Please, make +% every constant a real constant at least for the moment. We can +% easily convert things in the end when we have found what +% constants are used in critical places and what not. +% \begin{macrocode} +\tex_chardef:D \c_zero = 0 \scan_stop: +\tex_chardef:D \c_one = 1 \scan_stop: +\tex_chardef:D \c_two = 2 \scan_stop: +\tex_chardef:D \c_three = 3 \scan_stop: +\tex_chardef:D \c_four = 4 \scan_stop: +\tex_chardef:D \c_sixteen = 16 \scan_stop: +\tex_chardef:D \c_thirty_two = 32 \scan_stop: +\tex_chardef:D \c_twohundred_fifty_five = 255 \scan_stop: +\tex_mathchardef:D \c_twohundred_fifty_six = 256 \scan_stop: +\tex_mathchardef:D \c_thousand = 1000 \scan_stop: +\tex_mathchardef:D \c_ten_thousand = 10000 \scan_stop: +\tex_mathchardef:D \c_ten_thousand_one = 10001 \scan_stop: +\tex_mathchardef:D \c_ten_thousand_two = 10002 \scan_stop: +\tex_mathchardef:D \c_ten_thousand_three = 10003 \scan_stop: +\tex_mathchardef:D \c_ten_thousand_four = 10004 \scan_stop: +\tex_mathchardef:D \c_twenty_thousand = 20000 \scan_stop: +% already defined ... +%\int_new:N \c_minus_one +% \c_minus_one = -1 +% \end{macrocode} +% The |\c_int_max| will be defined internally as the largest +% dimen. +% \begin{macrocode} +%\int_new:N \c_int_max +% \c_int_max = 2147483647 +% \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} +% \end{macro} +% \end{macro} +% +% +% Show token usage: +% \begin{macrocode} +%</package> +%<*showmemory> +\showMemUsage +%</showmemory> +% \end{macrocode} +% +% +% \section{Fake registers} +% +% Fake registers are registers which implement \m{counter}s, +% \m{dimen}s, etc.\ which aren't used often and therefore don't need +% to run efficiently. One possible way of using them is to prepare certain +% registers this way, but |\let:NN| the mutator functions to real +% \m{counter}s as long as we have a sufficient number available. Now +% if we are making real large formats (by adding Pic\TeX, for example) +% we can turn them easily into fake registers and everything will work +% as before (only a bit slower). +% +% +% I haven't implemented anything besides counters so far, but \m{dimen} +% and \m{skip} present no principal problem and should probably be +% added. +% +% \subsection{Fake counters} +% +% \begin{macro}{\fint_new:N} +% A fake counter is internally a \m{muskip} register. A count value +% \m{x} is saved as \m{x}|mu| (more exactly as \m{x}|.0mu|) in this +% register. This means that fake counter values are far more +% restricted then usual counters, the largest value is 16383, +% i.e.\ the |pt| part of \TeX{}'s largest \m{dimen}. This could be +% changed by using more complicated conversion routines, but it +% might be all right in usual applications. +% +% Of course, we should make sure that we don't reach the borders, +% otherwise the user will be faced by the surprising message that +% some dimension got to large. (Not done yet). +% \begin{macrocode} +%<*package> +\let_new:NN \fint_new:N \newmuskip % nicked from LaTeX +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\fint_use:N} +% \begin{macro}{\fint_use_aux:w} +% To use the value of a fake counter we have to get rid of |.0mu| in +% an expandable way, since we want to allow constructions like +% \begin{verbatim} +% \if_num:w\fint_use:N \l_test_fint > 55\scan_stop: ... +%\end{verbatim} +% The simplest way I came up with (not much thinking behind) was +% using parameter matching. +% \begin{macrocode} +\def_new:Npn \fint_use:N {\exp_after:NN\fint_use_aux:w\the_internal:D} +% \end{macrocode} +% In the |\fint_use_aux:w| function we remove the |.0mu| and pass the +% the result back into the input stream. The only thing we +% have to think of, is that both |mu| have category code 12 when +% they are returned by |\the_internal:D|. +% \begin{macrocode} +\tex_lccode:D`\!=`\m \tex_lccode:D`\?=`\u +\tex_lowercase:D{\def_new:Npn \fint_use_aux:w #1.0!?{#1}} +\tex_lccode:D`\!=0\scan_stop: \tex_lccode:D`\?=0\scan_stop: +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\fint_set:Nn} +% \begin{macro}{\fint_gset:Nn} +% The way both routines are set up, the second argument might be +% either a \m{normal integer}, or an internal register. +% \begin{macrocode} +\def_new:Npn \fint_set:Nn #1#2{#1#2~mu\scan_stop: +%<*check> + \chk_local_or_pref_global:N #1 +%</check> +} +\def_new:Npn \fint_gset:Nn{ +%<*check> + \pref_global_chk: +%</check> +%<-check> \pref_global:D + \fint_set:Nn} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\fint_set_eq:NN} +% \begin{macro}{\fint_gset_eq:NN} +% We can easily set two fake counters equal to each other, but if +% fake counters and real counters are used, we have to use the +% slower |set| functions. +% \begin{macrocode} +\def_new:Npn \fint_set_eq:NN #1#2{#1#2 +%<*check> + \chk_local_or_pref_global:N #1\chk_var_or_const:N #2 +%</check> +} +\def_new:Npn \fint_gset_eq:NN { +%<*check> + \pref_global_chk: +%</check> +%<-check> \pref_global:D + \fint_set_eq:NN} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\fint_add:Nn} +% \begin{macro}{\fint_gadd:Nn} +% \begin{macro}{\fint_sub:Nn} +% \begin{macro}{\fint_gsub:Nn} +% Adding and substracting; we make use of the fact that internally +% \TeX{} always use the same primitives to advance a register. +% \begin{macrocode} +\def_new:Npn \fint_add:Nn #1#2{\int_add:Nn#1{#2mu}} +\def_new:Npn \fint_gadd:Nn { +%<*check> + \pref_global_chk: +%</check> +%<-check> \pref_global:D + \fint_add:Nn} +\def_new:Npn \fint_sub:Nn #1#2{\int_sub:Nn#1{#2mu}} +\def_new:Npn \fint_gsub:Nn { +%<*check> + \pref_global_chk: +%</check> +%<-check> \pref_global:D + \fint_sub:Nn} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\fint_incr:N} +% \begin{macro}{\fint_gincr:N} +% \begin{macro}{\fint_decr:N} +% \begin{macro}{\fint_gdecr:N} +% Incrementing and decrementing the fake counters: +% \begin{macrocode} +\def_new:Npn \fint_incr:N #1{\advance:D#1\c_one mu\scan_stop: +%<*check> + \chk_local_or_pref_global:N #1 +%</check> +} +\def_new:Npn \fint_decr:N #1{\advance:D#1\c_minus_one mu\scan_stop: +%<*check> + \chk_local_or_pref_global:N #1 +%</check> +} +\def_new:Npn \fint_gincr:N { +%<*check> + \pref_global_chk: +%</check> +%<-check> \pref_global:D + \fint_incr:N} +\def_new:Npn \fint_gdecr:N { +%<*check> + \pref_global_chk: +%</check> +%<-check> \pref_global:D + \fint_decr:N} +% \end{macrocode} +% This can be achieved with less tokens but extra expansions: +% \begin{macrocode} +\def:Npn \fint_incr:N #1{\fint_add:Nn#1\c_one} +\def:Npn \fint_decr:N #1{\fint_add:Nn#1\c_minus_one} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\c_fint_max} +% A constant, denoting the largest possible value for fake counters. +% \begin{macrocode} +\tex_mathchardef:D\c_fint_max=16383 \scan_stop: +% \end{macrocode} +% \end{macro} +% +% +% \subsection{Fake skip registers} +% +% One has to convert simply from the \m{x}|pt| |plus| \m{y}|pt| |minus| +% \m{z}|pt| representation produced by |\the_internal:D|, to the +% corresponding |mu| representation. Complications arise from the +% possibility that |plus| and/or |minus| is not present,\footnote{This +% can be catched by adding a suitable constant and removing the +% corresponding constant in the other representation.} and by the +% possibility that the stretch or shrink component is a |fil| unit. +% +% \subsection{Fake dimen registers} +% +% I suppose this could be viewed as a subcase of the skip registers. +% See later section for a fake fake version for the moment. +% +% +% \subsection{Allocation routines} +% +% Counters are rare goods in \TeX{} and we are near the limit, if +% for example \LaTeX{} and Pic\TeX{} are merged. Therefore we should +% be careful not to throw away counter registers unnecessarily. One +% place for instance, where we can save some of them are the +% allocation routines. Instead of using counters we maintain the +% number of the last allocated register in a fake counter. +% +% +% \begin{macrocode} +%</package> +%<*showmemory> +\showMemUsage +%</showmemory> +% \end{macrocode} + diff --git a/Master/texmf-dist/source/latex/expl3/l3io.dtx b/Master/texmf-dist/source/latex/expl3/l3io.dtx new file mode 100644 index 00000000000..ae155f4d2b3 --- /dev/null +++ b/Master/texmf-dist/source/latex/expl3/l3io.dtx @@ -0,0 +1,577 @@ +% \iffalse +%% File: l3io.dtx Copyright (C) 1990-1998 LaTeX3 project +% +%<*dtx> + \ProvidesFile{l3io.dtx} +%</dtx> +%<package>\NeedsTeXFormat{LaTeX2e} +%<package>\ProvidesPackage{l3io} +%<driver> \ProvidesFile{l3io.drv} +% \fi +% \ProvidesFile{l3io.dtx} + [1998/04/20 v1.0c L3 Experimental i/o module] +% +% \iffalse +%<*driver> +\documentclass{l3doc} + +\begin{document} +\DocInput{l3io.dtx} +\end{document} +%</driver> +% \fi +% +% \section{Low-level file i/o} +% +% \TeX{} is capable of reading from and writing up to 16 individual +% streams. These i/o operations are accessable in \LaTeX3 with functions +% from the "\io.." modules. In most cases it will be +% sufficiant for the programmer to use the functions provided by the +% auxiliary file module, but here are the necessary functions for +% manipulating private streams. +% +% Sometimes it is not know beforehand how much text is going to be +% written with a single call. As a result some internal \TeX{} buffer +% may overflow. To avoid this kind of problem, \LaTeX3 maintains beside +% direct write operations like "\iow_expanded:Nn" also so called ``long'' +% writes where the output is broken into individual lines on every blank +% in the text to be written. The resulting files are difficult to read +% for humans but since they usually serve only as internal storage this +% poses no problem. +% +% Beside the functions that immediately act (e.g., "\iow_expanded:Nn", +% etc.) we also have deferred operations that are saved away until the +% next page is finished. This allow to expand the <tokens> at the right +% time to get correct page numbers etc. +% +% \subsection{Functions for output streams} +% +% \begin{function}{\iow_new:N | +% \iow_new:c +% } +% \begin{syntax} +% "\iow_new:N" <stream> +% \end{syntax} +% Defines <stream> to be a new identifer denoting an output stream for +% use in subsequent functions. +% \begin{texnote} +% "\iow_new:N" corresponds to the plain \TeX{} \tn{newwrite} +% allocation routine. +% \end{texnote} +% \end{function} +% +% \begin{function}{\iow_open:Nn | +% \iow_open:cn +% } +% \begin{syntax} +% "\iow_open:Nn" <stream> "{" <file name> "}" +% \end{syntax} +% Opens output stream <stream> to write to <file name>. The output +% stream is immediately available for use. If the <stream> was already +% used as an output stream to some other file, this file gets closed +% first.\footnote{This is a precaution since on some OS it is possible +% to open the same file for output more than once which then results in +% some internal errors at the end of the run.} Also, all output streams +% still open at the end of the \TeX{} run will be automatically closed. +% \end{function} +% +% \begin{function}{\iow_expanded:Nn | +% \iow_unexpanded:Nn +% } +% \begin{syntax} +% "\iow_expanded:Nn" <stream> "{" <tokens> "}" +% \end{syntax} +% This function immediately writes the expansion of <tokens> to the +% output stream <stream>. If <stream> is not open output goes to the +% terminal. The variant "\iow_unexpanded:Nn" writes out <tokens> without any +% further expansion (verbatim). +% \end{function} +% +% \begin{function}{\iow_expanded_log:n | +% \iow_expanded_term:n | +% \iow_unexpanded_term:n +% } +% \begin{syntax} +% "\iow_expanded_log:n" "{" <tokens> "}" +% \end{syntax} +% These functions write to the transcript or to the terminal +% respectively. So they are equivalent to "\iow_expanded:Nn" where <stream> +% is the transcript file ("\c_iow_log_stream") or the terminal +% ("\c_io_term_stream"). +% \end{function} +% +% \begin{function}{\iow_long_expanded:Nx | +% \iow_long_unexpanded:Nn +% } +% \begin{syntax} +% "\iow_long_expanded:Nn" <stream> "{" <tokens> "}" +% \end{syntax} +% Like "\iow_expanded:Nn" but splits <tokens> at every blank into separate +% lines. +% \end{function} +% +% \begin{function}{\iow_unexpanded_if_avail:Nn| +% \iow_unexpanded_if_avail:cn|} +% \begin{syntax} +% "\iow_unexpanded_if_avail:Nn" <stream> "{" <tokens> "}" +% \end{syntax} +% This special function first checks if the <stream> is open of writing. +% If not it does nothing otherwise it behaves like "\iow_unexpanded:Nn". +% \end{function} +% +% \begin{function}{\iow_deferred_expanded:Nn | +% \iow_deferred_unexpanded:Nn} +% \begin{syntax} +% "\iow_deferred_expanded:Nn" <stream> "{" <tokens> "}" +% \end{syntax} +% These functions save away <tokens> until the next page is ready to be +% shipped out. Then, in case of "\iow_deferred_expanded:Nn" <tokens> get +% expanded and afterwards written to <stream>. "\iow_deferred_expanded:Nn" +% also always needs "{}" around the second argument. The use of +% "\iow_deferred_unexpanded:Nn" is probably seldom necessary. +% \begin{texnote} +% "\iow_deferred_expanded:Nn" was known as \tn{write}. +% \end{texnote} +% \end{function} +% +% \begin{function}{\iow_newline:} +% \begin{syntax} +% "\iow_newline:" +% \end{syntax} +% Function that produces a new line when used within the <token list> +% that gets written some output stream in non-verbatim mode. +% \end{function} +% +% \subsection{Functions for input streams} +% +% \begin{function}{\ior_new:N +% } +% \begin{syntax} +% "\ior_new:N" <stream> +% \end{syntax} +% This function defines <stream> to be a new input stream constant. +% \begin{texnote} +% This is the new name and new implementation for plain \TeX's +% \tn{newread}. +% \end{texnote} +% \end{function} +% +% \begin{function}{\ior_open:Nn} +% \begin{syntax} +% "\ior_open:Nn" <stream> "{" <file name> "}" +% \end{syntax} +% This function opens <stream> as an input stream for the external file +% <file name>. If <file name> doesn't exist or is an empty file the +% stream is considered to be fully read, a condition which can be tested +% with "\ior_eof:NTF" etc. If <stream> was already used to read from some +% other file this file will be closed first. The input stream is ready +% for immediate use. +% \end{function} +% +% \begin{function}{\ior_close:N} +% \begin{syntax} +% "\ior_close:N" <stream> +% \end{syntax} +% This function closes the read stream <stream>. +% \begin{texnote} +% This is a new name for \tn{closein} but it is considered bad practice +% to make use of this knowledge :-) +% \end{texnote} +% \end{function} +% +% \begin{function}{\ior_eof:NTF | +% \ior_eof:NF} +% \begin{syntax} +% "\ior_eof:NTF" <stream> "{" <true code> "}{" <false code> "}" +% \end{syntax} +% Conditional that tests if some input stream is fully read. The +% condition is also true if the input stream is not open. +% \end{function} +% +% \begin{function}{\if_eof:w} +% \begin{syntax} +% "\if_eof:w" <stream> <true code> "\else:" <false code> "\fi:" +% \end{syntax} +% \begin{texnote} +% This is the primitive \tn{ifeof} but we allow only a <stream> and not +% a plain number after it. +% \end{texnote} +% \end{function} +% +% \begin{function}{\ior_to:NN | +% \ior_gto:NN} +% \begin{syntax} +% "\ior_to:NN" <stream> <tlp> +% \end{syntax} +% Functions that reads one or more lines (until an equal number of left +% and right braces are found) from the input stream <stream> and places +% the result locally or globally into <tlp>. If <stream> is not open +% input is requested from the terminal. +% \end{function} +% +% \subsection{Constants} +% +% \begin{variable}{\c_iow_comment_char | +% \c_iow_lbrace_char | +% \c_iow_rbrace_char} +% Constants that can be used to represent comment character, left and +% right brace in token lists that should be written to a file. +% \end{variable} +% +% \begin{variable}{\c_io_term_stream} +% Input or output stream denoting the terminal. If used as an input +% stream the user is prompted with the name of the <tlp> (that is used +% in the call "\ior_to:NN" or "\ior_gto:NN") followed by an equal sign. +% If you don't want an automatic prompt of this sort ``misuse'' +% "\c_iow_log_stream" as an input stream. +% \end{variable} +% +% \begin{variable}{\c_iow_log_stream} +% Output stream that writes only to the transcript file (e.g., the +% {\tt.log} file on most systems). You may ``misuse'' this stream as an +% input stream. In this case it acts as a terminal stream without user +% prompting. +% \end{variable} +% +% \begin{variable}{\g_iow_newline_code} +% Global variable holding the character number of the character that +% denotes a new line when something is written to an output stream. +% \begin{texnote} +% A.k.a \tn{newlinechar}. +% \end{texnote} +% \end{variable} +% +% \subsection{Internal functions} +% +% \begin{function}{\iow_long_expanded_aux:w} +% Function used to implement immediate writing where a new line is +% started at every blank. +% \end{function} +% +% \begin{function}{% +% \tex_read:D | +% \tex_immediate:D | +% \tex_closeout:D | +% \tex_openin:D | +% \tex_openout:D | +% } +% These are the functions of the primitive interface to \TeX. +% \begin{texnote} +% The \TeX{} primitives \tn{read}, \tn{immediate}, \tn{closeout}, +% \tn{openin}, and \tn{openout} are all renamed and should not be used +% by a programmer since the functionality is covered by the \LaTeX3 +% functions above. +% \end{texnote} +% \end{function} +% +% +% \section{Lowlevel i/o-commands} +% +% We start by ensuring that the required packages are loaded. +% \begin{macrocode} +%<package&check>\RequirePackage{l3chk}\par +%<package>\RequirePackage{l3toks}\par +%<*package> +% \end{macrocode} +% +% This section is primarily concerned with input and output streams. +% The naming conventions for i/o streams is |ior| (for read) and |iow| +% (for write) as module names. e.g.\ |\c_ior_test_stream| is an input stream +% variable called `test'. +% +% \subsection{Output streams} +% +% \begin{macro}{\iow_new:N} +% \begin{macro}{\iow_new:c} +% Allocation of new output streams is done by these functions. +% As we currently do not distribute a new allocation module we nick +% the |\newwrite| function. +% \begin{macrocode} +\def_new:Npn \iow_new:N {} +\let:NN \iow_new:N \newwrite +\def_new:Npn \iow_new:c {\exp_args:Nc \iow_new:N} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\iow_open:Nn} +% \begin{macro}{\iow_open:cn} +% To open streams for reading or writing the following two functions +% are provided. The streams are opened immediately. +% +% From some bad experiences on the mainframe, I learned that it is +% better to force the close before opening a dataset for writing. +% We have to check whether this is also necessary in case of +% |\tex_openin:D|. +% \begin{macrocode} +\def_new:Npn \iow_open:Nn #1#2{\iow_close:N #1 + \tex_immediate:D\tex_openout:D#1#2\scan_stop:} +\def_new:Npn \iow_open:cn {\exp_args:Nc \iow_open:Nn} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\iow_close:N} +% Since we close output streams prior to opening, a separate closing +% operation is probably not necessary. But here it is, just in +% case\ldots. Actually you will need this if you intend to write +% and then read in the same pass from some stream. +% \begin{macrocode} +\def_new:Npn \iow_close:N {\tex_immediate:D\tex_closeout:D} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\c_io_term_stream} +% \begin{macro}{\c_iow_log_stream} +% Here we allocate two output streams for writing to the transcript +% file only (|\c_iow_log_stream|) and to both the terminal and transcript +% file (|\c_io_term_stream|). The latter can also be used to read +% from therefore it is called |..io_..|. +% \begin{macrocode} +\let_new:NN \c_io_term_stream \c_sixteen +\let_new:NN \c_iow_log_stream \c_minus_one +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \subsubsection{Immediate writing} +% +% \begin{macro}{\iow_expanded:Nn} +% An abbreviation for an often used operation, which immediately +% writes its second argument to the output stream. +% \begin{macrocode} +\def_new:Npn \iow_expanded:Nn {\tex_immediate:D\iow_deferred_expanded:Nn} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\iow_unexpanded:Nn} +% This routine writes the second argument verbatim onto the output +% stream. If this stream isn't open, the output goes to the terminal. +% If the first argument is no output stream at all, we get an +% internal error. +% \begin{macrocode} +\def_new:Npn \iow_unexpanded:Nn #1#2{\toks_gset:Nn \g_tmpa_toks {#2} + \iow_expanded:Nn #1{\toks_use:N \g_tmpa_toks}} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\iow_expanded_log:n} +% \begin{macro}{\iow_expanded_term:n} +% Now we redefine two functions for which we needed a definition +% very early on. They both write their second argument fully +% expanded to the output stream. +% \begin{macrocode} +\def:Npn \iow_expanded_log:n {\iow_expanded:Nn \c_iow_log_stream} +\def:Npn \iow_expanded_term:n{\iow_expanded:Nn \c_io_term_stream} +% \end{macrocode} +% The second one isn't exactly equivalent to the old |\typeout| since +% we need to control expansion in the function we provide for the user. +% \end{macro} +% \end{macro} + +% \begin{macro}{\iow_unexpanded_term:n} +% This function writes its argument verbatim to the the terminal. +% \begin{macrocode} +\def_new:Npn \iow_unexpanded_term:n {\iow_unexpanded:Nn \c_io_term_stream} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\iow_unexpanded_if_avail:Nn} +% \begin{macro}{\iow_unexpanded_if_avail:cn} +% |\iow_unexpanded_if_avail:Nn | \m{stream} \m{code}. This routine writes +% its second argument unexpanded to the stream given by the first +% argument, provided that this stream was opened for writing. Note, +% that |#| characters get doubled within \m{code}. +% \begin{macrocode} +\def_new:Npn \iow_unexpanded_if_avail:Nn #1{ +% \end{macrocode} +% In this routine we have to check whether or not the output stream +% that was requested is defined at all. +% So we check if the name is still free. +% \begin{macrocode} + \cs_free:NTF #1\use_none:n {\iow_unexpanded:Nn #1}} +% \end{macrocode} +% Note: the next function could be streamlined for speed if we use +% the faster |\cs_free:cTF|. (space viz time). +% \begin{macrocode} +\def_new:Npn \iow_unexpanded_if_avail:cn { + \exp_args:Nc \iow_unexpanded_if_avail:Nn } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\iow_long_expanded:Nn} +% \begin{macro}{\iow_long_unexpanded:Nn} +% \begin{macro}{\iow_long_expanded_aux:w} +% Another type of writing onto an output stream is used for +% potentially long token sequences. We break the output lines at +% every blank in the second argument. This avoids the problem of +% buffer overflow when reading back, or badly broken lines on +% systems with limited file records. The only thing we have to +% take care of, is the danger of two blanks in succession since +% these get converted into a |\par| when we read the stuff back. +% But this can happen only if things like +% two spaces find their way into the second argument. +% Usually, multiple spaces are removed by \TeX's scanner. +% +% \begin{macrocode} +\def_new:Npn \iow_long_expanded_aux:w #1#2#3{ + \group_begin:\g_iow_newline_code`\ #1#2{#3}\group_end:} +\def_new:Npn \iow_long_expanded:Nn {\iow_long_expanded_aux:w + \iow_expanded:Nn} +\def_new:Npn \iow_long_unexpanded:Nn {\iow_long_expanded_aux:w + \iow_unexpanded:Nn} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \subsubsection{Deferred writing} +% +% Deferred writing to output streams is a bit more complicated because +% there seems to be no nice hack for writing unexpanded. The only +% relatively sure bet is to use |\token_to_meaning:N| expansion of some token +% list. That's the way the following functions are implemented. +% +% Another possibility would be to reserve a certain number of scratch +% token registers that could be used to hold the tokens until after the +% next |\tex_shipout:D|. But such an approach would probably fail because of +% the limited number of available token registers that would need to +% be reserved for this special application. +% +% +% \begin{macro}{\iow_deferred_expanded:Nn} +% First the easy part, this is the primitive. +% \begin{macrocode} +\let:NN \iow_deferred_expanded:Nn \tex_write:D +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\iow_deferred_unexpanded:Nn} +% Now the harder part: +% \begin{macrocode} +\def_new:Npn \iow_deferred_unexpanded:Nn #1#2{ + \tlp_set:Nn \l_tmpa_tlp {#2} + \tlp_set:Nx \l_tmpb_tlp + {\iow_deferred_expanded:Nn #1{\tlp_to_str:N \l_tmpa_tlp}} + \l_tmpb_tlp} +% \end{macrocode} +% \end{macro} +% +% Long forms of these functions are not possible since the deferred +% writing will restore the value of |\g_iow_newline_code| before it will have +% a chance to act. But on the other hand it is nevertheless possible +% to make all deferred writes long by setting the |\g_iow_newline_code| +% inside the output routine just before the |\tex_shipout:D|. The only +% disadvantage of this method is the fact that messages to the +% terminal during this time will also then break at spaces. But we +% should consider this. +% +% \subsubsection{Special characters for writing} +% +% +% \begin{macro}{\c_iow_comment_char} +% \begin{macro}{\c_iow_lbrace_char} +% \begin{macro}{\c_iow_rbrace_char} +% We also need to be able to write braces and the comment character. We +% achieve this by defining global constants to expand into a version of +% these characters with |\tex_catcode:D|${}=12$. +% \begin{macrocode} +\tex_catcode:D `\%= 12 \scan_stop: +\tlp_new:Nn \c_iow_comment_char {%} +\tex_catcode:D `\%= 14 \scan_stop: +% \end{macrocode} +% To avoid another allocation function which is probably only +% necessary here we use the |\def:Npx| command directly. +% \begin{macrocode} +\tlp_new:Nn \c_iow_lbrace_char{} +\tlp_new:Nn \c_iow_rbrace_char{} +\def:Npx\c_iow_lbrace_char {\token_to_string:N{} +\def:Npx\c_iow_rbrace_char {\token_to_string:N}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \subsection{Input streams} +% +% \begin{macro}{\ior_new:N} +% Allocation of new input streams is done by this function. +% As we currently do not distribute a new allocation module we nick +% the |\newwread| function. +% \begin{macrocode} +\def_new:Npn \ior_new:N {} +\let:NN \ior_new:N \newread +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\ior_open:Nn} +% Processing of input-streams (via |\tex_openin:D| and |closein|) is +% always `immediate' as far as \TeX{} is concerned. An extra +% |\tex_immediate:D| is silently ignored. +% \begin{macrocode} +\def_new:Npn \ior_open:Nn #1#2{\ior_close:N #1\scan_stop: + \tex_openin:D#1#2\scan_stop:} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\ior_eof:NTF} +% |\ior_eof:NTF | \m{stream} \m{true case} \m{false case}. To +% test if some particular input stream is exhausted the following +% conditional is provided: +% \begin{macrocode} +\def_new:Npn \ior_eof:NTF #1{\if_eof:w#1 + \exp_after:NN\use_choice_i:nn \else: + \exp_after:NN\use_choice_ii:nn \fi:} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\ior_eof:NF} +% |\ior_eof:NF | \m{stream} \m{false case}. Do something if +% if there is still something to read from this file: +% \begin{macrocode} +\def_new:Npn \ior_eof:NF #1{\if_eof:w#1 + \exp_after:NN \use_none:nn \fi: \use:n} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\ior_to:NN} +% \begin{macro}{\ior_gto:NN} +% And here we read from files. +% \begin{macrocode} +%<*check> +\def_new:Npn \ior_to:NN #1#2{\tex_read:D#1to#2 + \chk_local_or_pref_global:N #2} +%</check> +%<-check> \def_new:Npn \ior_to:NN #1{\tex_read:D#1to} +\def_new:Npn \ior_gto:NN { +%<*check> + \pref_global_chk: +%</check> +%<-check> \pref_global:D + \ior_to:NN} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% Show token usage: +% \begin{macrocode} +%</package> +%<*showmemory> +\showMemUsage +%</showmemory> +% \end{macrocode} +% +% + diff --git a/Master/texmf-dist/source/latex/expl3/l3names.dtx b/Master/texmf-dist/source/latex/expl3/l3names.dtx new file mode 100644 index 00000000000..1f981eb2d45 --- /dev/null +++ b/Master/texmf-dist/source/latex/expl3/l3names.dtx @@ -0,0 +1,810 @@ +% \iffalse +%% File: l3names.dtx Copyright (C) 1990-1997 LaTeX3 project +% +%<*dtx> + \ProvidesFile{l3names.dtx} +%</dtx> +%<package>\NeedsTeXFormat{LaTeX2e} +%<package>\ProvidesPackage{l3names} +%<driver> \ProvidesFile{l3names.drv} +% \fi +% \ProvidesFile{l3names.dtx} + [1998/04/20 v2.0b L3 Experimental Naming Scheme for TeX Primitives] +% +% \iffalse +%<*driver> +\documentclass{l3doc} + +\begin{document} +\DocInput{l3names.dtx} +\end{document} +%</driver> +% \fi +% +% \GetFileInfo{l3names.dtx} +% \title{The \textsf{l3names} package\thanks{This file +% has version number \fileversion, last +% revised \filedate.}\\ +% A systematic naming scheme for \TeX} +% \author{\Team} +% \date{\filedate} +% \maketitle +% +% \changes{v2.0a}{1997/08/04} +% {new consistent tex module name for \TeX\ primitives} +% +% \begin{abstract} +% This package sets up an experimental naming scheme for +% \LaTeX\ commands. It allows the \LaTeX\ programmer to systematically +% name functions and variables, and specify the argument types of +% functions. +% +% The \TeX\ primitives are all given a new name according to these +% conventions. +% +% \begin{bfseries} +% Warning: This package, and all packages using it should be regarded as +% \emph{expermiental}! +% +% The names of these packages, and the names and syntax of any commands +% defined in them might change at any time. +% +% These conventions are being distributed in this form to encourage +% discussion and experimentation. It is \emph{not} intentended that +% these packages be used in `real' documents at this stage. +% \end{bfseries} +% \end{abstract} +% +% +% \section{Conventions} +% +% This section gives an overview of the syntax for \LaTeX\ commands +% that is set up for use in these `experimental' pacages. +% +% Commands in \LaTeX3 are either functions or parameters. All +% primitive commands of \TeX{} have private names. +% +% \subsection{Functions} +% +% Functions have the following general syntax: +% \begin{quote} +% |\|\m{module}|_|\m{description}|:|\m{arg-spec} +% \end{quote} +% where \m{module} is one of the (to be) chosen module names and +% \m{description} is a verbal description of the functionality. +% \m{arg-spec} finally describes the type of arguments that the +% function takes and is left empty if it is a function without +% arguments. +% +% All three parts consists of letters only \m{description} is allowed +% to take further |_| characters to separate words is necessary. +% +% Currently there exists some functions which don't have a proper +% \m{module} name. +% +% As a semi-formalized concept the letter |g| is sometimes used to +% prefix the \m{module} name and certain parts of the \m{description} +% to mark the function as ``globally acting''. +% +% The \m{arg-spec} currently supports the following types of +% arguments: +% \begin{description} +% +% \item[n] Unexpanded token (or token-list if in braces) braces. +% +% \item[o] One time expanded token or token-list. In the latter case, +% effectively only the first token in the list gets expanded. Since +% the expansion might result in more than one token, the result is +% surrounded for further processing with braces. +% +% \item[x] Fully expanded token or token-list. Like |o| but the +% argument is expanded using |\def:Npx| before it is passed on. +% +% \item[c] A character string or a token-list that expands to +% characters of catcode 11 or 12. This string (after expansion) is +% used to construct a command name that is eventually passed on. +% +% \item[N,O,X] Like |n|, |o|, |x| but the argument must be a single +% token without any braces around it. +% +% \item[w] One or more arguments with ``weird'' syntax that one has +% to know by hard or better leave it alone. +% +% \item[p] Denotes parameter text specification part, e.g.\^^M +% |#1#2\q_stop#3|. +% +% \item[T,F] denotes the ``true'' or the ``false'' case in a +% functional predicate. +% +% \end{description} +% +% Especially for the new names of \TeX{} primitives there are is one +% more character to denote arguments. It implies that these +% functions should not be used outside this bootstrapping file. +% \begin{description} +% +% \item[D] Zero or more arguments with ``weird'' syntax. Uppercase +% ``D'' means (DON'T USE IT), i.e., +% that this is a primitive \TeX{} command that should +% not show up in code except in the very basic functions of \LaTeX3 +% that provide a more sensible interface. +% +% \end{description} +% +% One could perhaps envisage an extended system which allocated +% lettters to denote the various primitive argument types available in +% \TeX, however it seems that this just complicates the system +% withoutadding any real benefit, as these primitives would never be +% used in production code, as higher level packages should offer a +% better interface. Thus the following letters, although they were +% considered have not been used. ``D'' is used in most cases in +% preference. +% \begin{description} +% \item[i] Denotes an integer in \TeX{} notation (which might be a +% register or \dots). +% +% \item[d] Denotes a dimension in \TeX{} notation. +% +% \item[g] Denotes a glue in \TeX{} notation. +% +% \item[m] Denotes an muglue or mukern in \TeX{} notation. +% +% \item[b] Denotes a box specification in \TeX{} notation (again +% something pretty arbitrary). +% +% \item[r] Denotes a rule specification in \TeX{} notation. +% +% \end{description} +% +% Some of the primitive functions below are flagged ``D'' even if +% they actually might be useful in average code. So certainly there +% are some adjustments necessary. It all depends whether or not we +% provide some safer interface or leave them alone. +% +% \subsection{Parameters} +% +% Parameter names have the following general syntax: +% \begin{quote} +% |\|\m{access}|_|\m{module}|_|\m{description}|_|\m{type} +% \end{quote} +% +% \m{module} and \m{description} is as above. \m{type} should denote +% the type of parameter if this helps in using it. The currently used +% types are: +% \begin{description} +% +% \item[int] Integer valued. +% +% \item[factor] Another integer value type. Used for things where the +% parameter is used as a factor for something else. +% +% \item[status] The sort of boolean stuff \TeX{} provides. Essentially +% an integer with the meaning |0| = `off' and other values may or may +% not have sensible meanings. +% +% \item[pen] Another integer describing penalties. +% +% \item[dem] The demerits. +% +% \item[dim] A dimension. +% +% \item[skip] A glue value. +% +% \item[toks] A toks register (sort of). +% +% \item[char] An integer denoting a character. +% +% \item[muskip] A math unit. +% +% \end{description} +% +% \m{access} describes how the parameter can be accessed. The +% following characters are possible: +% \begin{description} +% +% \item[c] A constant. Should not be set in the code except with +% special functions to define the value for the whole processing. +% +% \item[C] A constant according to \TeX's rules. Can not be changed at +% all. +% +% \item[l] A local variable which therefore should not be changed +% globally. +% +% \item[L] A local variable that is usually set (and/or reset) by +% \TeX{} itself. +% +% \item[g] A global variable. +% +% \item[G] A global variable that is usually set (and/or reset by \TeX. +% +% \item[R] A variable that is set (and changed) by \TeX{} and can not +% be changed by in the code (read-only). +% +% \end{description} +% +% +% +% \section{Modules} +% +% Nearly all operations of \LaTeX3 are carried out by calling control +% sequences. For better programming concepts many types of functions are +% identified and gathered in modules. Functions in such modules starts +% with special prefixes, for example "\tlp_" is the prefix for functions +% dealing with token list pointers. +% +% +% +% \StopEventually{} +% +% \section{Starters} +% +% This is the base part of \LaTeX3 defining things like |catcode|s +% and redefining the \TeX{} primitives. +% +% We start by setting up |\catcode|s that we need to define new +% commands. These are the ones for begin-group and end-group +% characters.\footnote{Well not needed while this file is running +% as a package on top of \LaTeXe, so omitted from the package code} +% \begin{macrocode} +%<*initex> +\catcode`\{=1 % left brace is begin-group character +\catcode`\}=2 % right brace is end-group character +\catcode`\#=6 % hash mark is macro parameter character +\catcode`\^=7 % +\catcode`\^^I=10 % ascii tab is a blank space +%</initex> +% \end{macrocode} +% +% \begin{macrocode} +%<*initex|package> +\catcode`\ =9\relax +\catcode`\^^I=9\relax +\catcode`\^^M=9\relax +\catcode`\~=10\relax +\catcode`\_=11\relax\catcode`\:=11\relax +\catcode`\@=11\relax % as long as we use old LaTeX stuff. +% \end{macrocode} +% +% +% \section{Setting up primitive names} +% +% Here is the function that renames \TeX{}'s primitives. +% +% Normally the old name is left untouched, but the possibility of +% undefining the original names is made available by docstrip and +% package options. +% If nothing else, this gives a way of checking what `old code' a +% package depends on\ldots\ +% +% If the package option `removeoldnames' is used then some trick code +% is run after the end of this file, to skip past the code which has +% been inserted by \LaTeXe\ to manage the file name stack, this code +% would break if run once the \TeX\ primitives have been undefined. +% (What a surprise!) +% +% To get things started, give a new name for |\let|. +% \begin{macrocode} +\let\tex_let:D\let +%</initex|package> +% \end{macrocode} +% +% and now an internal function to possibly +% remove the old name. +% +% \begin{macrocode} +%<*initex> +\long\def\name_undefine:N#1{ + \tex_let:D#1\tex_undefined:} +%</initex> +% \end{macrocode} +% +% \begin{macrocode} +%<*package> +\DeclareOption{removeoldnames}{ + \long\def\name_undefine:N#1{ + \tex_let:D#1\tex_undefined:}} +% \end{macrocode} +% +% \begin{macrocode} +\DeclareOption{keepoldnames}{ + \long\def\name_undefine:N#1{}} +% \end{macrocode} +% +% \begin{macrocode} +\ExecuteOptions{keepoldnames} +% \end{macrocode} +% +% \begin{macrocode} +\ProcessOptions +%</package> +% \end{macrocode} +% +% The internal function to give the new name and possibly undefine +% the old name. +% \begin{macrocode} +%<*initex|package> +\long\def\name_primitive:NN#1#2{ + \tex_let:D #2 #1 + \name_undefine:N #1 + } +% \end{macrocode} +% +% \subsection{Assignments} +% +% In the current incarnation of this package, all \TeX\ primitives +% are given a new name of the form |\tex_|\emph{oldname}|:D|. +% But first three special cases which have symbolic original names. +% These are given modified new names, so that they may be entered +% without catcode tricks. +% \begin{macrocode} +\name_primitive:NN \ \tex_space:D +\name_primitive:NN \/ \tex_italiccor:D +\name_primitive:NN \- \tex_hyphen:D +% \end{macrocode} +% +% Now all the other primitives. +% \begin{macrocode} +\name_primitive:NN \let \tex_let:D +\name_primitive:NN \def \tex_def:D +\name_primitive:NN \edef \tex_edef:D +\name_primitive:NN \gdef \tex_gdef:D +\name_primitive:NN \xdef \tex_xdef:D +\name_primitive:NN \chardef \tex_chardef:D +\name_primitive:NN \countdef \tex_countdef:D +\name_primitive:NN \dimendef \tex_dimendef:D +\name_primitive:NN \skipdef \tex_skipdef:D +\name_primitive:NN \muskipdef \tex_muskipdef:D +\name_primitive:NN \mathchardef \tex_mathchardef:D +\name_primitive:NN \toksdef \tex_toksdef:D +\name_primitive:NN \futurelet \tex_futurelet:D +\name_primitive:NN \advance \tex_advance:D +\name_primitive:NN \divide \tex_divide:D +\name_primitive:NN \multiply \tex_multiply:D +\name_primitive:NN \font \tex_font:D +\name_primitive:NN \fam \tex_fam:D +\name_primitive:NN \global \tex_global:D +\name_primitive:NN \long \tex_long:D +\name_primitive:NN \outer \tex_outer:D +\name_primitive:NN \setlanguage \tex_setlanguage:D +\name_primitive:NN \globaldefs \tex_globaldefs:D +\name_primitive:NN \afterassignment \tex_afterassignment:D +\name_primitive:NN \aftergroup \tex_aftergroup:D +\name_primitive:NN \expandafter \tex_expandafter:D +\name_primitive:NN \noexpand \tex_noexpand:D +\name_primitive:NN \begingroup \tex_begingroup:D +\name_primitive:NN \endgroup \tex_endgroup:D +\name_primitive:NN \halign \tex_halign:D +\name_primitive:NN \valign \tex_valign:D +\name_primitive:NN \cr \tex_cr:D +\name_primitive:NN \crcr \tex_crcr:D +\name_primitive:NN \noalign \tex_noalign:D +\name_primitive:NN \omit \tex_omit:D +\name_primitive:NN \span \tex_span:D +\name_primitive:NN \tabskip \tex_tabskip:D +\name_primitive:NN \everycr \tex_everycr:D +\name_primitive:NN \if \tex_if:D +\name_primitive:NN \ifcase \tex_ifcase:D +\name_primitive:NN \ifcat \tex_ifcat:D +\name_primitive:NN \ifnum \tex_ifnum:D +\name_primitive:NN \ifodd \tex_ifodd:D +\name_primitive:NN \ifdim \tex_ifdim:D +\name_primitive:NN \ifeof \tex_ifeof:D +\name_primitive:NN \ifhbox \tex_ifhbox:D +\name_primitive:NN \ifvbox \tex_ifvbox:D +\name_primitive:NN \ifvoid \tex_ifvoid:D +\name_primitive:NN \ifx \tex_ifx:D +\name_primitive:NN \iffalse \tex_iffalse:D +\name_primitive:NN \iftrue \tex_iftrue:D +\name_primitive:NN \ifhmode \tex_ifhmode:D +\name_primitive:NN \ifmmode \tex_ifmmode:D +\name_primitive:NN \ifvmode \tex_ifvmode:D +\name_primitive:NN \ifinner \tex_ifinner:D +\name_primitive:NN \else \tex_else:D +\name_primitive:NN \fi \tex_fi:D +\name_primitive:NN \or \tex_or:D +\name_primitive:NN \immediate \tex_immediate:D +\name_primitive:NN \closeout \tex_closeout:D +\name_primitive:NN \openin \tex_openin:D +\name_primitive:NN \openout \tex_openout:D +\name_primitive:NN \read \tex_read:D +\name_primitive:NN \write \tex_write:D +\name_primitive:NN \closein \tex_closein:D +\name_primitive:NN \newlinechar \tex_newlinechar:D +\name_primitive:NN \input \tex_input:D +\name_primitive:NN \endinput \tex_endinput:D +\name_primitive:NN \inputlineno \tex_inputlineno:D +\name_primitive:NN \errmessage \tex_errmessage:D +\name_primitive:NN \message \tex_message:D +\name_primitive:NN \show \tex_show:D +\name_primitive:NN \showthe \tex_showthe:D +\name_primitive:NN \showbox \tex_showbox:D +\name_primitive:NN \showlists \tex_showlists:D +\name_primitive:NN \errhelp \tex_errhelp:D +\name_primitive:NN \errorcontextlines \tex_errorcontextlines:D +\name_primitive:NN \tracingcommands \tex_tracingcommands:D +\name_primitive:NN \tracinglostchars \tex_tracinglostchars:D +\name_primitive:NN \tracingmacros \tex_tracingmacros:D +\name_primitive:NN \tracingonline \tex_tracingonline:D +\name_primitive:NN \tracingoutput \tex_tracingoutput:D +\name_primitive:NN \tracingpages \tex_tracingpages:D +\name_primitive:NN \tracingparagraphs \tex_tracingparagraphs:D +\name_primitive:NN \tracingrestores \tex_tracingrestores:D +\name_primitive:NN \tracingstats \tex_tracingstats:D +\name_primitive:NN \pausing \tex_pausing:D +\name_primitive:NN \showboxbreadth \tex_showboxbreadth:D +\name_primitive:NN \showboxdepth \tex_showboxdepth:D +\name_primitive:NN \batchmode \tex_batchmode:D +\name_primitive:NN \errorstopmode \tex_errorstopmode:D +\name_primitive:NN \nonstopmode \tex_nonstopmode:D +\name_primitive:NN \scrollmode \tex_scrollmode:D +\name_primitive:NN \end \tex_end:D +\name_primitive:NN \csname \tex_csname:D +\name_primitive:NN \endcsname \tex_endcsname:D +\name_primitive:NN \ignorespaces \tex_ignorespaces:D +\name_primitive:NN \relax \tex_relax:D +\name_primitive:NN \the \tex_the:D +\name_primitive:NN \mag \tex_mag:D +\name_primitive:NN \language \tex_language:D +\name_primitive:NN \mark \tex_mark:D +\name_primitive:NN \topmark \tex_topmark:D +\name_primitive:NN \firstmark \tex_firstmark:D +\name_primitive:NN \botmark \tex_botmark:D +\name_primitive:NN \splitfirstmark \tex_splitfirstmark:D +\name_primitive:NN \splitbotmark \tex_splitbotmark:D +\name_primitive:NN \fontname \tex_fontname:D +\name_primitive:NN \escapechar \tex_escapechar:D +\name_primitive:NN \endlinechar \tex_endlinechar:D +\name_primitive:NN \mathchoice \tex_mathchoice:D +\name_primitive:NN \delimiter \tex_delimiter:D +\name_primitive:NN \mathaccent \tex_mathaccent:D +\name_primitive:NN \mathchar \tex_mathchar:D +\name_primitive:NN \mskip \tex_mskip:D +\name_primitive:NN \radical \tex_radical:D +\name_primitive:NN \vcenter \tex_vcenter:D +\name_primitive:NN \mkern \tex_mkern:D +\name_primitive:NN \above \tex_above:D +\name_primitive:NN \abovewithdelims \tex_abovewithdelims:D +\name_primitive:NN \atop \tex_atop:D +\name_primitive:NN \atopwithdelims \tex_atopwithdelims:D +\name_primitive:NN \over \tex_over:D +\name_primitive:NN \overwithdelims \tex_overwithdelims:D +\name_primitive:NN \displaystyle \tex_displaystyle:D +\name_primitive:NN \textstyle \tex_textstyle:D +\name_primitive:NN \scriptstyle \tex_scriptstyle:D +\name_primitive:NN \scriptscriptstyle \tex_scriptscriptstyle:D +\name_primitive:NN \eqno \tex_eqno:D +\name_primitive:NN \leqno \tex_leqno:D +\name_primitive:NN \abovedisplayshortskip \tex_abovedisplayshortskip:D +\name_primitive:NN \abovedisplayskip \tex_abovedisplayskip:D +\name_primitive:NN \belowdisplayshortskip \tex_belowdisplayshortskip:D +\name_primitive:NN \belowdisplayskip \tex_belowdisplayskip:D +\name_primitive:NN \displaywidowpenalty \tex_displaywidowpenalty:D +\name_primitive:NN \displayindent \tex_displayindent:D +\name_primitive:NN \displaywidth \tex_displaywidth:D +\name_primitive:NN \everydisplay \tex_everydisplay:D +\name_primitive:NN \predisplaysize \tex_predisplaysize:D +\name_primitive:NN \predisplaypenalty \tex_predisplaypenalty:D +\name_primitive:NN \postdisplaypenalty \tex_postdisplaypenalty:D +\name_primitive:NN \mathbin \tex_mathbin:D +\name_primitive:NN \mathclose \tex_mathclose:D +\name_primitive:NN \mathinner \tex_mathinner:D +\name_primitive:NN \mathop \tex_mathop:D +\name_primitive:NN \displaylimits \tex_displaylimits:D +\name_primitive:NN \limits \tex_limits:D +\name_primitive:NN \nolimits \tex_nolimits:D +\name_primitive:NN \mathopen \tex_mathopen:D +\name_primitive:NN \mathord \tex_mathord:D +\name_primitive:NN \mathpunct \tex_mathpunct:D +\name_primitive:NN \mathrel \tex_mathrel:D +\name_primitive:NN \overline \tex_overline:D +\name_primitive:NN \underline \tex_underline:D +\name_primitive:NN \left \tex_left:D +\name_primitive:NN \right \tex_right:D +\name_primitive:NN \binoppenalty \tex_binoppenalty:D +\name_primitive:NN \relpenalty \tex_relpenalty:D +\name_primitive:NN \delimitershortfall \tex_delimitershortfall:D +\name_primitive:NN \delimiterfactor \tex_delimiterfactor:D +\name_primitive:NN \nulldelimiterspace \tex_nulldelimiterspace:D +\name_primitive:NN \everymath \tex_everymath:D +\name_primitive:NN \mathsurround \tex_mathsurround:D +\name_primitive:NN \medmuskip \tex_medmuskip:D +\name_primitive:NN \thinmuskip \tex_thinmuskip:D +\name_primitive:NN \thickmuskip \tex_thickmuskip:D +\name_primitive:NN \scriptspace \tex_scriptspace:D +\name_primitive:NN \noboundary \tex_noboundary:D +\name_primitive:NN \accent \tex_accent:D +\name_primitive:NN \char \tex_char:D +\name_primitive:NN \discretionary \tex_discretionary:D +\name_primitive:NN \hfil \tex_hfil:D +\name_primitive:NN \hfilneg \tex_hfilneg:D +\name_primitive:NN \hfill \tex_hfill:D +\name_primitive:NN \hskip \tex_hskip:D +\name_primitive:NN \hss \tex_hss:D +\name_primitive:NN \vfil \tex_vfil:D +\name_primitive:NN \vfilneg \tex_vfilneg:D +\name_primitive:NN \vfill \tex_vfill:D +\name_primitive:NN \vskip \tex_vskip:D +\name_primitive:NN \vss \tex_vss:D +\name_primitive:NN \unskip \tex_unskip:D +\name_primitive:NN \kern \tex_kern:D +\name_primitive:NN \unkern \tex_unkern:D +\name_primitive:NN \hrule \tex_hrule:D +\name_primitive:NN \vrule \tex_vrule:D +\name_primitive:NN \leaders \tex_leaders:D +\name_primitive:NN \cleaders \tex_cleaders:D +\name_primitive:NN \xleaders \tex_xleaders:D +\name_primitive:NN \lastkern \tex_lastkern:D +\name_primitive:NN \lastskip \tex_lastskip:D +\name_primitive:NN \indent \tex_indent:D +\name_primitive:NN \par \tex_par:D +\name_primitive:NN \noindent \tex_noindent:D +\name_primitive:NN \vadjust \tex_vadjust:D +\name_primitive:NN \baselineskip \tex_baselineskip:D +\name_primitive:NN \lineskip \tex_lineskip:D +\name_primitive:NN \lineskiplimit \tex_lineskiplimit:D +\name_primitive:NN \clubpenalty \tex_clubpenalty:D +\name_primitive:NN \widowpenalty \tex_widowpenalty:D +\name_primitive:NN \exhyphenpenalty \tex_exhyphenpenalty:D +\name_primitive:NN \hyphenpenalty \tex_hyphenpenalty:D +\name_primitive:NN \linepenalty \tex_linepenalty:D +\name_primitive:NN \doublehyphendemerits \tex_doublehyphendemerits:D +\name_primitive:NN \finalhyphendemerits \tex_finalhyphendemerits:D +\name_primitive:NN \adjdemerits \tex_adjdemerits:D +\name_primitive:NN \hangafter \tex_hangafter:D +\name_primitive:NN \hangindent \tex_hangindent:D +\name_primitive:NN \parshape \tex_parshape:D +\name_primitive:NN \hsize \tex_hsize:D +\name_primitive:NN \lefthyphenmin \tex_lefthyphenmin:D +\name_primitive:NN \righthyphenmin \tex_righthyphenmin:D +\name_primitive:NN \leftskip \tex_leftskip:D +\name_primitive:NN \rightskip \tex_rightskip:D +\name_primitive:NN \looseness \tex_looseness:D +\name_primitive:NN \parskip \tex_parskip:D +\name_primitive:NN \parindent \tex_parindent:D +\name_primitive:NN \uchyph \tex_uchyph:D +\name_primitive:NN \emergencystretch \tex_emergencystretch:D +\name_primitive:NN \pretolerance \tex_pretolerance:D +\name_primitive:NN \tolerance \tex_tolerance:D +\name_primitive:NN \spaceskip \tex_spaceskip:D +\name_primitive:NN \xspaceskip \tex_xspaceskip:D +\name_primitive:NN \everypar \tex_everypar:D +\name_primitive:NN \prevgraf \tex_prevgraf:D +\name_primitive:NN \spacefactor \tex_spacefactor:D +\name_primitive:NN \shipout \tex_shipout:D +\name_primitive:NN \vsize \tex_vsize:D +\name_primitive:NN \interlinepenalty \tex_interlinepenalty:D +\name_primitive:NN \brokenpenalty \tex_brokenpenalty:D +\name_primitive:NN \topskip \tex_topskip:D +\name_primitive:NN \maxdeadcycles \tex_maxdeadcycles:D +\name_primitive:NN \maxdepth \tex_maxdepth:D +\name_primitive:NN \output \tex_output:D +\name_primitive:NN \deadcycles \tex_deadcycles:D +\name_primitive:NN \pagedepth \tex_pagedepth:D +\name_primitive:NN \pagestretch \tex_pagestretch:D +\name_primitive:NN \pagefilstretch \tex_pagefilstretch:D +\name_primitive:NN \pagefillstretch \tex_pagefillstretch:D +\name_primitive:NN \pagefilllstretch \tex_pagefilllstretch:D +\name_primitive:NN \pageshrink \tex_pageshrink:D +\name_primitive:NN \pagegoal \tex_pagegoal:D +\name_primitive:NN \pagetotal \tex_pagetotal:D +\name_primitive:NN \outputpenalty \tex_outputpenalty:D +\name_primitive:NN \hoffset \tex_hoffset:D +\name_primitive:NN \voffset \tex_voffset:D +\name_primitive:NN \insert \tex_insert:D +\name_primitive:NN \holdinginserts \tex_holdinginserts:D +\name_primitive:NN \floatingpenalty \tex_floatingpenalty:D +\name_primitive:NN \insertpenalties \tex_insertpenalties:D +\name_primitive:NN \lower \tex_lower:D +\name_primitive:NN \moveleft \tex_moveleft:D +\name_primitive:NN \moveright \tex_moveright:D +\name_primitive:NN \raise \tex_raise:D +\name_primitive:NN \copy \tex_copy:D +\name_primitive:NN \lastbox \tex_lastbox:D +\name_primitive:NN \vsplit \tex_vsplit:D +\name_primitive:NN \unhbox \tex_unhbox:D +\name_primitive:NN \unhcopy \tex_unhcopy:D +\name_primitive:NN \unvbox \tex_unvbox:D +\name_primitive:NN \unvcopy \tex_unvcopy:D +\name_primitive:NN \setbox \tex_setbox:D +\name_primitive:NN \hbox \tex_hbox:D +\name_primitive:NN \vbox \tex_vbox:D +\name_primitive:NN \vtop \tex_vtop:D +\name_primitive:NN \prevdepth \tex_prevdepth:D +\name_primitive:NN \badness \tex_badness:D +\name_primitive:NN \hbadness \tex_hbadness:D +\name_primitive:NN \vbadness \tex_vbadness:D +\name_primitive:NN \hfuzz \tex_hfuzz:D +\name_primitive:NN \vfuzz \tex_vfuzz:D +\name_primitive:NN \overfullrule \tex_overfullrule:D +\name_primitive:NN \boxmaxdepth \tex_boxmaxdepth:D +\name_primitive:NN \splitmaxdepth \tex_splitmaxdepth:D +\name_primitive:NN \splittopskip \tex_splittopskip:D +\name_primitive:NN \everyhbox \tex_everyhbox:D +\name_primitive:NN \everyvbox \tex_everyvbox:D +\name_primitive:NN \nullfont \tex_nullfont:D +\name_primitive:NN \textfont \tex_textfont:D +\name_primitive:NN \scriptfont \tex_scriptfont:D +\name_primitive:NN \scriptscriptfont \tex_scriptscriptfont:D +\name_primitive:NN \fontdimen \tex_fontdimen:D +\name_primitive:NN \hyphenchar \tex_hyphenchar:D +\name_primitive:NN \skewchar \tex_skewchar:D +\name_primitive:NN \defaulthyphenchar \tex_defaulthyphenchar:D +\name_primitive:NN \defaultskewchar \tex_defaultskewchar:D +\name_primitive:NN \number \tex_number:D +\name_primitive:NN \romannumeral \tex_romannumeral:D +\name_primitive:NN \string \tex_string:D +\name_primitive:NN \lowercase \tex_lowercase:D +\name_primitive:NN \uppercase \tex_uppercase:D +\name_primitive:NN \meaning \tex_meaning:D +\name_primitive:NN \penalty \tex_penalty:D +\name_primitive:NN \unpenalty \tex_unpenalty:D +\name_primitive:NN \lastpenalty \tex_lastpenalty:D +\name_primitive:NN \special \tex_special:D +\name_primitive:NN \dump \tex_dump:D +\name_primitive:NN \patterns \tex_patterns:D +\name_primitive:NN \hyphenation \tex_hyphenation:D +\name_primitive:NN \time \tex_time:D +\name_primitive:NN \day \tex_day:D +\name_primitive:NN \month \tex_month:D +\name_primitive:NN \year \tex_year:D +\name_primitive:NN \jobname \tex_jobname:D +\name_primitive:NN \everyjob \tex_everyjob:D +\name_primitive:NN \count \tex_count:D +\name_primitive:NN \dimen \tex_dimen:D +\name_primitive:NN \skip \tex_skip:D +\name_primitive:NN \toks \tex_toks:D +\name_primitive:NN \muskip \tex_muskip:D +\name_primitive:NN \box \tex_box:D +\name_primitive:NN \wd \tex_wd:D +\name_primitive:NN \ht \tex_ht:D +\name_primitive:NN \dp \tex_dp:D +\name_primitive:NN \catcode \tex_catcode:D +\name_primitive:NN \delcode \tex_delcode:D +\name_primitive:NN \sfcode \tex_sfcode:D +\name_primitive:NN \lccode \tex_lccode:D +\name_primitive:NN \uccode \tex_uccode:D +\name_primitive:NN \mathcode \tex_mathcode:D +% \end{macrocode} +% +% \begin{macro}{\CodeStart} +% \begin{macro}{\CodeStop} +% Here we define functions that are used to turn on and off the +% special conventions used in the kernel of \LaTeX3. +% +% First of all, the space, tab and the return characters will all be +% ignored inside \LaTeX3 code. When space characters are needed in +% \LaTeX3 code the |~| character will be used for that purpose. +% +% \begin{macrocode} +\tex_def:D\CodeStart{% + \tex_catcode:D `\ =9\tex_relax:D + \tex_catcode:D `\^^M=9\tex_relax:D + \tex_catcode:D `\^^I=9\tex_relax:D + \tex_catcode:D `\~=10\tex_relax:D +%<!initex> \tex_catcode:D `\@=11\tex_relax:D % For LaTeX2e + \tex_catcode:D `\_=11\tex_relax:D + \tex_catcode:D `\:=11\tex_relax:D} +% \end{macrocode} +% +% \begin{macrocode} +\tex_def:D\CodeStop{ + \tex_catcode:D `\ =10\tex_relax:D + \tex_catcode:D `\^^M=5\tex_relax:D + \tex_catcode:D `\^^I=10\tex_relax:D + \tex_catcode:D `\~=13\tex_relax:D +%<!initex> \tex_catcode:D `\@=12\tex_relax:D % For LaTeX2e + \tex_catcode:D `\_=8\tex_relax:D + \tex_catcode:D `\:=12\tex_relax:D} +%</initex|package> +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% Finally some corrections in the case we are running over \LaTeXe. +% +% A few of the `primitives' assigned above have already been stolen +% by \LaTeX, so assign them by hand to the saved real primitive. +% \begin{macrocode} +%<*package> +\tex_let:D\tex_input:D \@@input +\tex_let:D\tex_underline:D \@@underline +\tex_let:D\tex_end:D \@@end +\tex_let:D\tex_everymath:D \frozen@everymath +\tex_let:D\tex_everydisplay:D \frozen@everydisplay +\tex_let:D\tex_italiccor:D \@@italiccorr +\tex_let:D\tex_hyphen:D \@@hyph +% \end{macrocode} +% +% \TeX\ has a nasty habit of inserting a command with the name |\par| +% so we had better make sure that that command at least has a definition. +% \begin{macrocode} +\tex_let:D\par \tex_par:D +% \end{macrocode} +% +% As mentioned above, The \LaTeXe\ package mechanism will insert some code +% to handle the filename stack, and reset the package options, this +% code will die if the \TeX\ primitives have gone, so skip past it +% and insert some equivalent code that will work. +% +% First a version of |\ProvidesPackage| that can cope. +% \begin{macrocode} +\tex_def:D\ProvidesPackage{ + \tex_begingroup:D + \CodeStop + \package_provides:w} +% \end{macrocode} +% +% \begin{macrocode} +\tex_def:D\package_provides:w#1#2[#3]{ + \tex_endgroup:D + \tex_immediate:D\tex_write:D-1{Package: #1#2 #3} + \tex_expandafter:D\tex_xdef:D + \tex_csname:D ver@#1.sty\tex_endcsname:D{}} +% \end{macrocode} +% +% \begin{macrocode} +\tex_ifx:D\name_undefine:N\@gobble +% \end{macrocode} +% +% Normally just set the catcodes, and let \LaTeXe\ handle the +% package stack. If \LaTeXe\ resets @ reset the white space as well. +% \begin{macrocode} + \tex_def:D\name_pop_stack:w{} + \g@addto@macro\@popfilename{% + \tex_ifnum:D12=\tex_the:D\tex_catcode:D`@ + \CodeStop + \tex_fi:D} + \g@addto@macro\@pushfilename{\CodeStart} +% \end{macrocode} +% +% \begin{macrocode} +\tex_else:D +% \end{macrocode} +% +% But if traditional \TeX\ code is disabled, do this\ldots +% +% In this case the catcode preserving stack is not maintained and +% |\CodeStart| conventions stay in force once on. You'll need +% to turn then off explicitky with |\CodeStop| (although as currently +% built on 2e, nothing except very experimental code will run in +% this mode!) Also note that |\RequirePackage| is a simple definition, just for +% one file, with no options. +% \begin{macrocode} +\tex_def:D\name_pop_stack:w#1\relax{% + \CodeStop + \tex_expandafter:D\@p@pfilename\@currnamestack\@nil + \tex_let:D\default@ds\@unknownoptionerror + \tex_global:D\tex_let:D\ds@\@empty + \tex_global:D\tex_let:D\@declaredoptions\@empty} +% \end{macrocode} +% +% \begin{macrocode} +\tex_def:D\@p@pfilename#1#2#3#4\@nil{% + \tex_gdef:D\@currname{#1}% + \tex_gdef:D\@currext{#2}% + \tex_catcode:D`\@#3% + \tex_gdef:D\@currnamestack{#4}} +% \end{macrocode} +% +% \begin{macrocode} + \tex_def:D\NeedsTeXFormat#1{} + \tex_def:D\RequirePackage#1{ + \tex_expandafter:D\tex_ifx:D + \tex_csname:D ver@#1.sty\tex_endcsname:D\tex_relax:D + \CodeStart + \tex_input:D#1.sty\tex_relax:D + \tex_fi:D} +\tex_fi:D +% \end{macrocode} +% +% The |\futurelet| just forces the special end of file marker to vanish, +% so the argument of |\name_pop_stack:w| does not cause an end-of-file +% error. (Normally I use |\expandafter| for this trick, but here the next +% token is in fact |\let| and that may be undefined.) +% \begin{macrocode} +\tex_futurelet:D\name_tmp:\name_pop_stack:w +%</package> +% \end{macrocode} +% diff --git a/Master/texmf-dist/source/latex/expl3/l3precom.dtx b/Master/texmf-dist/source/latex/expl3/l3precom.dtx new file mode 100644 index 00000000000..69c1bc4e7cd --- /dev/null +++ b/Master/texmf-dist/source/latex/expl3/l3precom.dtx @@ -0,0 +1,369 @@ +% \iffalse +%% File: l3precom.dtx Copyright (C) 1990-1998 LaTeX3 project +% +%<*dtx> + \ProvidesFile{l3precom.dtx} +%</dtx> +%<package>\NeedsTeXFormat{LaTeX2e} +%<package>\ProvidesPackage{l3precom} +%<driver> \ProvidesFile{l3precom.drv} +% \fi +% \ProvidesFile{l3precom.dtx} + [1998/04/20 v1.0b L3 Experimental precompilation module] +% +% \iffalse +%<*driver> +\documentclass{l3doc} + +\begin{document} +\DocInput{l3precom.dtx} +\end{document} +%</driver> +% \fi +% +% \section{Control sequence functions extended \ldots} +% +% \begin{function}{\cs_gen_sym:N | +% \cs_ggen_sym:N} +% \begin{syntax} +% "\cs_gen_sym:N" <tlp> +% \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). +% \end{function} +% +% \begin{function}{\cs_record_name:N} +% \begin{syntax} +% "\cs_record_name:N" <cs> +% \end{syntax} +% Takes the <cs> and saves it in a special places for pre-compiling +% purposes on a file later on. All control sequences that are recorded +% with this function will be dumped by "\cs_dump:". This function is +% internally automatically used to record all symbols generated by +% "\cs_gen_sym:N" and "\cs_ggen_sym:N". +% \end{function} +% +% \begin{function}{\cs_load_dump:n} +% \begin{syntax} +% "\cs_load_dump:n" "{" <file name> "}" +% \end{syntax} +% Loads and executes the file <file name> if found. Then scans +% further ignoring everything until finding "\cs_dump:" where normal +% execution continues. If <file name> is not found, the name is saved +% and normal execution of all following code is done until "\cs_dump:" is +% scanned. Then all symbols marked for dumping are dumped into <file +% name>. +% \end{function} +% +% \begin{function}{\cs_dump:} +% Dumps the symbols recorded by "\cs_record_name:N" in the file given +% by the argument in "\cs_load_dump:n". Dumping means that for every +% <cs> recorded by "\cs_record_name:N" a line +% \begin{quote} +% "\def:Npn" <cs> "{" <current meaning of cs> "}" +% \end{quote} +% is written to this file. This means that when loading the file the +% definitions of all these <cs>'s are directly available. +% \end{function} +% +% +% \subsection{Internal variables} +% +% \begin{variable}{\g_gen_sym_fint | +% \g_ggen_sym_fint} Holds the number of the last +% generated symbol by "\cs_gen_sym:N" or "\cs_ggen_sym:N". +% \end{variable} +% +% \begin{variable}{\g_cs_dump_seq} +% Sequence in which the symbols to be dumped are stored. +% \end{variable} +% +% \begin{variable}{\c_cs_dump_stream} +% Output stream used for writing out the definitions of the +% recorded <tlp>. +% \end{variable} +% +% +% +% \section{Precompiling some functions} +% +% We start by ensuring that the required packages are loaded. +% \begin{macrocode} +%<package>\RequirePackage{l3int} +%<package>\RequirePackage{l3io} +%<package>\RequirePackage{l3seq} +% \end{macrocode} +% +% It might speed up the processing of documents when certain parts +% of the document style file are `precompiled' and stored in a +% separate file. +% +% \begin{macro}{\c_cs_dump_stream} +% We need to allocate an output stream in order to be able to write +% the precompiled code out. +% Stream number for the dump. +% +% \begin{macrocode} +%<*package> +%<*precompile> +\iow_new:N\c_cs_dump_stream +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\g_cs_dump_name_tlp} +% This \m{tlp} is used to store the name of the file. +% +% \begin{macrocode} +\tlp_new:Nn\g_cs_dump_name_tlp{} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\g_cs_dump_seq} +% While processing the documentstyle we build up a list of +% control sequence names to be dumped. For this purpose +% we use the |\g_cs_dump_seq| sequence. +% +% \begin{macrocode} +\seq_new:N\g_cs_dump_seq +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\cs_record_name:N} +% \begin{macro}{\cs_record_name:c} +% These functions mark a control sequence for dumping into a +% precompiled style. +% +% When the {\sf trace} `module' is included in the code we also write +% information about the control sequence into a |.dmp| file. +% \begin{macrocode} +\def_new:Npn\cs_record_name:N#1{ +%<*trace> + \seq_gput_left:Nn + \g_cs_trace_seq#1 +%</trace> + \seq_gput_left:Nn + \g_cs_dump_seq#1} +\def_new:Npn\cs_record_name:c{\exp_args:Nc\cs_record_name:N} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\cs_dump:} +% When a document style\marginpar{\small As you can see from the +% wording this pre-dates \LaTeXe{} \quad \emph{Frank}} +% calls |\cs_dump:| it triggers this code +% to write all the precompilation information out to a file. +% +% Before dumping, we write a message to the terminal informing the +% `user' of this fact. +% \begin{macrocode} +\def_new:Npn\cs_dump:{ + \iow_expanded_term:n{Precompiling~style~into~(\g_cs_dump_name_tlp)} + \iow_open:Nn\c_cs_dump_stream{\g_cs_dump_name_tlp} +% \end{macrocode} +% The first thing we write on a `dump' file is a command that +% allows us to use |*| in control sequences. We also need to be +% able to write to (and read from) the file internal control +% sequences, containing |_| and |:|. +% \begin{macrocode} + \iow_expanded:Nn\c_cs_dump_stream + {\group_begin: + \tex_catcode:D`\token_to_string:N\*=11\scan_stop: + \token_to_string:N\CodeStart + } + \seq_map_inline:Nn + \g_cs_dump_seq + {\tex_message:D{.} + \iow_expanded:Nn\c_cs_dump_stream +% \end{macrocode} +% We use a direct |\gdef:Npn| to disable any type of local/global +% check on the pointers. +% \begin{macrocode} + {\token_to_string:N\gdef:Npn + \token_to_string:N##1 + {\tlp_to_str:N##1}} + } +% \end{macrocode} +% We also need to remember the current values of the +% |\g_gen_sym_fint| and |\g_ggen_sym_fint| counters to allow +% further updates after a database was dumped. +% \begin{macrocode} + \iow_expanded:Nn + \c_cs_dump_stream + {\token_to_string:N\fint_gset:Nn + \g_gen_sym_fint + {\fint_use:N\g_gen_sym_fint}^^J + \token_to_string:N\fint_gset:Nn + \g_ggen_sym_fint + {\fint_use:N\g_ggen_sym_fint}} + \iow_expanded:Nn + \c_cs_dump_stream + {\group_end:} + \iow_close:N\c_cs_dump_stream + \tex_message:D{~finished} +} +%</precompile> +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\cs_load_dump:n} +% A function to read a precompiled file into memory and skip until a +% |\cs_dump:| command is found. If no such file is found, processing +% continues and a subsequent |\cs_dump:| command will then create the +% dump file. +% \begin{macrocode} +\def_new:Npn\cs_load_dump:n#1{ + \file_not_found:nTF{#1.cmp} +%<*precompile> + {\tlp_gset:Nn\g_cs_dump_name_tlp{#1.cmp}} +%</precompile> +%<-precompile> {\tex_errmessage:D{Cannot~ dump~ with~ this~ format}} + {\input{#1.cmp} + \let:NN\cs_dump:\fi: + \if_false:}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\g_gen_sym_fint} +% \begin{macro}{\g_ggen_sym_fint} +% Two counters to make up new local or global {\sl short\/} names +% in pointer structures like the {\sc ldb}. +% We use a fake counters since operations with them are seldom. +% \begin{macrocode} +\fint_new:N\g_gen_sym_fint +\fint_gset:Nn\g_gen_sym_fint{0} +\fint_new:N\g_ggen_sym_fint +\fint_gset:Nn\g_ggen_sym_fint{0} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\cs_gen_sym:N} +% \begin{macro}{\cs_ggen_sym:N} +% We need to be able to generate control sequences on the fly. +% They will exist of a prefix, either |l*| or |g*|, followed +% by the value of the counter |\g_gen_sym_fint| (|\g_ggen_sym_fint|) +% in roman numeral representation. The generated control sequence +% is locally stored in the token that was passed in |#1|. +% +% \begin{macrocode} +\def_new:Npn\cs_gen_sym:N#1{ + \fint_gincr:N\g_gen_sym_fint + \tlp_set:Nc#1{l*\tex_romannumeral:D\fint_use:N\g_gen_sym_fint} +%<*precompile> + \exp_after:NN\cs_record_name:N#1 +%</precompile> +% \end{macrocode} +% We still want to define the initial value for the new symbol +% globally to make sure that during compilation something is +% written to the output file. +% \begin{macrocode} + \exp_after:NN\tlp_clear_new:N#1} +% \end{macrocode} +% The global variant +% \begin{macrocode} +\def_new:Npn\cs_ggen_sym:N#1{ + \fint_gincr:N\g_ggen_sym_fint + \tlp_set:Nc#1{g*\tex_romannumeral:D\fint_use:N\g_ggen_sym_fint} +%<*precompile> + \exp_after:NN\cs_record_name:N#1 +%</precompile> + \exp_after:NN\tlp_clear_new:N#1} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\g_cs_trace_seq} +% A sequence which holds the control sequence names that are to +% be dumped. They are stored together with their meaning. +% +% ATTENTION: as we currently don't distribute allocation routines +% for primitive registers this code will have no effect! +% \begin{macrocode} +%<*trace> +\seq_new:N\g_cs_trace_seq +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\g_register_trace_seq} +% Sequence holding the register names to be dumped with their +% corresponding values. +% +% ATTENTION: as we currently don't distribute allocation routines +% for primitive registers this code will have no effect! +% \begin{macrocode} +\seq_new:N\g_register_trace_seq +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\cs_record_meaning:N} +% Function marking a control sequence for dumping with meaning. +% \begin{macrocode} +\def:Npn\cs_record_meaning:N#1{ + \seq_gput_left:Nn + \g_cs_trace_seq#1} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\register_record_name:N} +% Function marking a register for dumping with value. +% \begin{macrocode} +\def:Npn\register_record_name:N#1{ + \seq_gput_left:Nn + \g_register_trace_seq#1} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\dumpLaTeXstate} +% The function |\dumpLaTeXstate| is used to write control sequences +% and registers, together with their meaning or value in the |.dmp| +% file. We write informational messages to the terminal during the +% dump. +% +% ATTENTION: as we currently don't distribute allocation routines +% for primitive registers this part of the code will dump nothing +% unless |\register_record_name:N| is explicitly used. +% \begin{macrocode} +\def_new:Npn\dumpLaTeXstate#1{ + \iow_expanded_term:n{Dumping~commands~into~(#1.dmp)} + \iow_open:Nn\c_cs_dump_stream{#1.dmp} + \seq_map_inline:Nn + \g_cs_trace_seq + {\tex_message:D{.} + \iow_expanded:Nn\c_cs_dump_stream + {\token_to_string:N##1~ + \token_to_meaning:N##1} + } + \tex_message:D{~registers} + \seq_map_inline:Nn + \g_register_trace_seq + {\tex_message:D{.} + \iow_expanded:Nn\c_cs_dump_stream + {\token_to_string:N##1 + \the_internal:D##1} + } + \tex_message:D{~finished} +} +%</trace> +%</package> +% \end{macrocode} +% \end{macro} +% +% +% Show token usage: +% \begin{macrocode} +%<*showmemory> +\showMemUsage +%</showmemory> +% \end{macrocode} +% +% + + diff --git a/Master/texmf-dist/source/latex/expl3/l3prop.dtx b/Master/texmf-dist/source/latex/expl3/l3prop.dtx new file mode 100644 index 00000000000..e430507aabf --- /dev/null +++ b/Master/texmf-dist/source/latex/expl3/l3prop.dtx @@ -0,0 +1,599 @@ +% \iffalse +%% File: l3prop.dtx Copyright (C) 1990-1998 LaTeX3 project +% +%<*dtx> + \ProvidesFile{l3prop.dtx} +%</dtx> +%<package>\NeedsTeXFormat{LaTeX2e} +%<package>\ProvidesPackage{l3prop} +%<driver> \ProvidesFile{l3prop.drv} +% \fi +% \ProvidesFile{l3prop.dtx} + [1998/05/04 v1.0e L3 Experimental Property Lists] +% +% \iffalse +%<*driver> +\documentclass{l3doc} + +\begin{document} +\DocInput{l3prop.dtx} +\end{document} +%</driver> +% \fi +% +% +% \GetFileInfo{l3prop.dtx} +% \title{The \textsf{l3prop} package\thanks{This file +% has version number \fileversion, last +% revised \filedate.}\\ +% Property Lists} +% \author{\Team} +% \date{\filedate} +% \maketitle +% +% +% +% \section{Property lists} +% +% \LaTeX3 implements a data structure which allows to store information +% associated with individual tokens. +% +% \subsection{Functions} +% +% \begin{function}{% +% \prop_new:N | +% \prop_new:O | +% } +% \begin{syntax} +% "\prop_new:N" <plist> +% \end{syntax} +% Defines <plist> to be a variable of type p-list. +% \end{function} +% +% \begin{function}{% +% \prop_clear:N | +% \prop_gclear:N | +% } +% \begin{syntax} +% "\prop_clear:N" <plist> +% \end{syntax} +% These functions locally or globally clear <plist>. +% \end{function} +% +% \begin{function}{% +% \prop_put:NNn | +% \prop_gput:NNn | +% \prop_gput:NNo | +% \prop_gput:NOo | +% \prop_gput:OOo | +% \prop_gput:NOx | +% \prop_gput:ccn | +% \prop_gput:ccx | +% } +% \begin{syntax} +% "\prop_put:NNn" <plist> <key> "{"<token list>"}" +% \end{syntax} +% Locally or globally associates <token list> with <key> in the p-list +% <plist>. If <key> has already a meaning within <plist> this value is +% overwritten. +% \end{function} +% +% \begin{function}{% +% \prop_gput_if_new:NNn | +% } +% \begin{syntax} +% "\prop_gput_if_new:NNn" <plist> <key> "{"<token list>"}" +% \end{syntax} +% Globally associates <token list> with <key> in the p-list +% <plist> but only if <key> has so far no meaning within <plist>. +% overwritten. +% \end{function} +% +% \begin{function}{% +% \prop_get:NNN | +% \prop_gget:NNN | +% } +% \begin{syntax} +% "\prop_get:NNN" <plist> <key> <tlp> +% \end{syntax} +% If <info> is the information associated with <key> in the p-list +% <plist> then the token list pointer <tlp> gets <info> assigned. +% Otherwise its value is the special quark "\q_no_value". +%^^A See section \ref{sec:quarks} to test this. +% The assignment is done either locally or globally. +% \end{function} +% +% \begin{function}{% +% \prop_set_eq:NN +% } +% \begin{syntax} +% "\prop_set_eq:NN" <plist 1> <plist 2> +% \end{syntax} +% A fast assignment of <plist>s. +% \end{function} +% +% \begin{function}{% +% \prop_get_gdel:NNN | +% } +% \begin{syntax} +% "\prop_get_gdel:NNN" <plist> <key> <tlp> +% \end{syntax} +% Like "\prop_get:NNN" but additionally removes <key> (and its <info>) +% from <plist>. +% \end{function} +% +% \begin{function}{% +% \prop_del:NN | +% \prop_gdel:NN | +% } +% \begin{syntax} +% "\prop_del:NN" <plist> <key> +% \end{syntax} +% Locally or globally deletes <key> and its <info> from <plist> if +% found. Otherwise does nothing. +% \end{function} +% +% \begin{function}{\prop_map:NN | +% \prop_map:cN +% } +% \begin{syntax} +% "\prop_map:NN" <plist> <function> +% \end{syntax} +% Maps <function> which should be a function with two arguments (<key> +% and <info>) over every <key> <info> pair of <plist>. +% \end{function} +% +% \begin{function}{\prop_map_inline:Nn | +% \prop_map_inline:cn +% } +% \begin{syntax} +% "\prop_map_inline:Nn" <plist> "{" <inline function> "}" +% \end{syntax} +% Just like "\prop_map:NN" but with the function of two arguments +% supplied as inline code. Within <inline function> refer to the +% arguments via "##1" (<key>) and "##2" (<info>). +% +% Not implemented so far! +% \end{function} +% +% \subsection{Predicates and conditionals} +% +% \begin{function}{\prop_empty:NTF} +% \begin{syntax} +% "\prop_empty:NTF" <plist> "{"<true code>"}{"<false code>"}" +% \end{syntax} +% Set of conditionals that test whether or not a particular <plist> +% is empty. +% \end{function} +% +% \begin{function}{% +% \prop_if_in:NNTF | +% \prop_if_in:NOTF | +% } +% \begin{syntax} +% "\prop_if_in:NNTF" <plist><key>"{"<true code>"}{"<false code>"}" +% \end{syntax} +% Tests if <key> is used in <plist> and then either executes <true code> +% or <false code>. +% \end{function} +% +% \subsection{Internal functions} +% +% \begin{function}{% +% \prop_put_aux:w | +% \prop_put_if_new_aux:w | +% } +% Internal functions implementing the put operations. +% \end{function} +% +% \begin{function}{% +% \prop_get_aux:w | +% \prop_get_del_aux:w | +% \prop_del_aux:w | +% } +% Internal functions implementing the get and delete operations. +% \end{function} +% +% \begin{function}{% +% \prop_if_in_aux:w | +% } +% Internal function implementing the key test operation. +% \end{function} +% +% \begin{function}{% +% \prop_map_aux:w | +% } +% Internal function implementing the map operation. +% \end{function} +% +% \begin{function}{% +% \prop_map_funct:Nn | +% } +% Internal name for the function that is mapped over p-list during +% execution of "\prop_map:NN". +% \end{function} +% +% \begin{function}{\prop_split_aux:NNn} +% \begin{syntax} +% "\prop_split_aux:NNn" <plist> <key> <cmd> +% \end{syntax} +% Internal function that invokes <cmd> with 3 arguments: 1st is the +% beginning of <plist> before <key>, 2nd is the value associated with +% <key>, 3rd is the rest of <plist> after <key>. If there is no key +% <key> in <plist>, then the 2 arg is "\q_no_value " and the 3rd arg is +% empty; otherwise the 3rd argument has the two extra tokens <prop> +% "\q_no_value" at the end. +% +% This function is used to implement various get operations. +% \end{function} +% +% +% \section {Implementation} +% +% We start by ensuring that the required packages are loaded. +% \begin{macrocode} +%<package>\RequirePackage{l3seq}\par +%<*package> +% \end{macrocode} +% +% A property list is a control sequence whose top-level expansion is +% of the form `\zz{tok$\sb1$}\zv{val$\sb1$} \ldots{} +% \zz{tok$\sb{}n$}\zv{val$\sb{}n$}'. The properties have to be single +% token, the values might be arbitrary token lists they get surrounded +% by braces. +% +% To get values from property-lists, token lists should be passed to +% the appropriate functions. +% +% \begin{macro}{\prop_new:N} +% \begin{macro}{\prop_new:O} +% \begin{macro}{\prop_new:c} +% Property lists are a special case of sequences, so allocating +% them is the same as allocating sequences. +% \begin{macrocode} +\let_new:NN \prop_new:N \seq_new:N +\let_new:NN \prop_new:O \seq_new:O +\let_new:NN \prop_new:c \seq_new:c +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\prop_clear:N} +% \begin{macro}{\prop_gclear:N} +% The same goes for clearing a property list, either +% locally or globally. +% \begin{macrocode} +\let_new:NN \prop_clear:N \seq_clear:N +\let_new:NN \prop_gclear:N \seq_gclear:N +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\prop_split_aux:NNn} +% |\prop_split_aux:NNn|\zz{plist}\zz{prop}\zz{cmd} invokes \zz{cmd} +% with 3 arguments: 1st is the beginning of \zz{plist} before +% \zz{prop}, 2nd is the value associated with \zz{prop}, 3rd is the +% rest of \zz{plist} after \zz{prop}. If there is no property +% \zz{prop} in \zz{plist}, then the 2nd argument will be |\q_no_value| +% and the 3rd argument is empty; otherwise the 3rd argument has the two +% extra tokens \zz{prop} |\q_no_value| at the end. +% \begin{macrocode} +\def_long_new:Npn \prop_split_aux:NNn #1#2#3{ + \def:Npn \tmp:w ##1#2##2##3\q_stop {#3{##1}{##2}{##3}} + \exp_after:NN\tmp:w #1#2\q_no_value \q_stop} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\prop_get:NNN} +% \begin{macro}{\prop_get_aux:w} +% |\prop_get:NNN |\zz{plist}\zz{prop}\zz{tlp} defines +% \zz{tlp} to be the value associated with \zz{prop} in \zz{plist}, +% |\q_no_value| if not found. +% \begin{macrocode} +\def_long_new:Npn \prop_get:NNN #1#2{\prop_split_aux:NNn + #1#2\prop_get_aux:w} +\def_long_new:Npn \prop_get_aux:w #1#2#3#4{\tlp_set:Nn#4{#2}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\prop_gget:NNN} +% \begin{macro}{\prop_gget_aux:w} +% The global version of the previous function. +% \begin{macrocode} +\def_long_new:Npn \prop_gget:NNN #1#2{\prop_split_aux:NNn + #1#2\prop_gget_aux:w} +\def_long_new:Npn \prop_gget_aux:w #1#2#3#4{\tlp_gset:Nn#4{#2}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\prop_get_gdel:NNN} +% \begin{macro}{\prop_get_del_aux:w} +% |\prop_get_gdel:NNN| is the same as |\prop_get:NNN| but the +% \m{property_key} and its value are afterwards globally removed +% from \m{property_list}. One probably also needs the local +% variants or only the local one, or\ldots\ We decide this later. +% \begin{macrocode} +\def_long_new:Npn \prop_get_gdel:NNN #1#2#3{\prop_split_aux:NNn + #1#2{\prop_get_del_aux:w #3{\tlp_gset:Nn #1}#2}} +\def_long_new:Npn \prop_get_del_aux:w #1#2#3#4#5#6{ + \tlp_set:Nn #1{#5} + \quark_if_no_value:NF#1 + {\def:Npn \tmp:w ##1#3\q_no_value {#2{#4##1}} + \tmp:w #6}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\prop_put:NNn} +% \begin{macro}{\prop_put_aux:w} +% \begin{macro}{\prop_gput:NNn} +% \begin{macro}{\prop_gput:NNx} +% \begin{macro}{\prop_gput:NNo} +% \begin{macro}{\prop_gput:NOx} +% \begin{macro}{\prop_gput:NOo} +% \begin{macro}{\prop_gput:OOo} +% \begin{macro}{\prop_gput:ccx} +% |\prop_put:NNn |\zz{plist}\zz{prop}\zv{val} adds/changes the +% value associated with \zz{prop} in \zz{plist} to \zv{val}. +% \begin{macrocode} +\def_long_new:Npn \prop_put:NNn #1#2{\prop_split_aux:NNn + #1#2{\prop_put_aux:w {\tlp_set:Nn #1}#2}} +\def_long_new:Npn \prop_gput:NNn #1#2{\prop_split_aux:NNn + #1#2{\prop_put_aux:w {\tlp_gset:Nn #1}#2}} +\def_new:Npn \prop_gput:NNo {\exp_args:NNNo \prop_gput:NNn} +\def_new:Npn \prop_gput:NOx {\exp_args:Nnox \prop_gput:NNn} +\def_new:Npn \prop_gput:NNx {\exp_args:Nnnx \prop_gput:NNn} +\def_new:Npn \prop_gput:NOo {\exp_args:NNOo \prop_gput:NNn} +\def_new:Npn \prop_gput:OOo {\exp_args:NOOo \prop_gput:NNn} +\def_new:Npn \prop_gput:ccn {\exp_args:Ncc \prop_gput:NNn} +\def_new:Npn \prop_gput:ccx {\exp_args:Nccx \prop_gput:NNn} +\def_long_new:Npn \prop_put_aux:w #1#2#3#4#5#6{ + \quark_if_no_value:nTF {#4} + {#1{#2{#6}#3}} + {\def:Npn \tmp:w ##1#2\q_no_value {#1{#3#2{#6}##1}} + \tmp:w #5}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\prop_del:NN} +% \begin{macro}{\prop_gdel:NN} +% \begin{macro}{\prop_del_aux:w} +% |\prop_del:NN |\zz{plist}\zz{prop} deletes the entry for +% \zz{prop} in \zz{plist}, if any. +% \begin{macrocode} +\def_long_new:Npn \prop_del:NN #1#2{\prop_split_aux:NNn + #1#2{\prop_del_aux:w {\tlp_set:Nn #1}#2}} +\def_long_new:Npn \prop_gdel:NN #1#2{\prop_split_aux:NNn + #1#2{\prop_del_aux:w {\tlp_gset:Nn #1}#2}} +\def_long_new:Npn \prop_del_aux:w #1#2#3#4#5{\quark_if_no_value:nF {#4} +% \end{macrocode} +% I see no reason for updating the property list if we don't find +% any entry. +% \begin{macrocode} +% {#1{#3}} + {\def:Npn \tmp:w ##1#2\q_no_value {#1{#3##1}}\tmp:w #5}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% +% \begin{macro}{\prop_if_in:NNTF} +% \begin{macro}{\prop_if_in:NOTF} +% \begin{macro}{\prop_if_in_aux:w} +% |\prop_if_in:NNTF| \m{property_list} \m{property_key} +% \m{true_case} \m{false_case} will check whether or not +% \m{property_key} is on the \m{property_list} and then select +% either the true or false case. +% \begin{macrocode} +\def_new:Npn \prop_if_in:NNTF #1#2{\prop_split_aux:NNn + #1#2\prop_if_in_aux:w} +\def_new:Npn \prop_if_in:NOTF {\exp_args:Nno \prop_if_in:NNTF} +\def_new:Npn \prop_if_in_aux:w #1#2#3{\quark_if_no_value:nTF {#2}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\prop_gput_if_new:NNn} +% |\prop_gput_if_new:NNn| \m{property_list} \m{property_key} +% \m{property_value} is equivalent to +% \begin{tabbing} +% xxxxx\=xxxxx\= \kill +% |\prop_if_in:NNTF |\m{property}\m{property_key} \\ +% \> |{}%| \\ +% \> |{\prop_gput:NNn| \\ +% \>\> \m{property_list} \\ +% \>\> \m{property_key} \\ +% \>\> \m{property_value}|}| +% \end{tabbing} +% Here we go (listening to Porgy \& Bess in a recording with Ella +% F. and Louis A. which makes writing macros sometimes difficult; I +% find myself humming instead of working): +% \begin{macrocode} +\def_long_new:Npn \prop_gput_if_new:NNn #1#2{\prop_split_aux:NNn #1#2 + {\prop_put_if_new_aux:w #1#2}} +\def_long_new:Npn \prop_put_if_new_aux:w #1#2#3#4#5#6{ + \quark_if_no_value:nT {#4}{#1{#2{#6}#3}}} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\prop_set_eq:NN} +% This makes two \m{plist}s have the same contents. +% \begin{macrocode} +\let_new:NN\prop_set_eq:NN\tlp_set_eq:NN +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\prop_empty:NTF} +% This conditional takes a \m{plist} as its argument and evaluates +% either the true or the false case, depending on whether or not +% \m{plist} contains any properties. +% \begin{macrocode} +\let_new:NN \prop_empty:NTF \tlp_empty:NTF +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\prop_map:NN} +% \begin{macro}{\prop_map:cN} +% \begin{macro}{\prop_map_funct:Nn} +% Maps a function on every entry in the property list. The +% function must take 2 arguments: a key and a value. +% \begin{macrocode} +\let_new:NN \prop_map_funct:Nn \use_none:nn +\def_new:Npn \prop_map:NN #1#2{ + \let:NN \prop_map_funct:Nn #2 + \exp_after:NN\prop_map_aux:w #1\q_stop \q_stop} +\def_new:Npn \prop_map_aux:w #1#2{ + \if_meaning:NN#1\q_stop \else: + \prop_map_funct:Nn #1{#2} + \exp_after:NN\prop_map_aux:w + \fi:} +\def_new:Npn \prop_map:cN { \exp_args:Nc \prop_map:NN } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\prop_map_inline:Nn} +% \begin{macro}{\prop_map_inline:cn} +% To be supplied. +% \begin{macrocode} +\let_new:NN \prop_map_inline:Nn \ERROR +\let_new:NN \prop_map_inline:cn \ERROR +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% Show token usage: +% \begin{macrocode} +%</package> +%<*showmemory> +%\showMemUsage +%</showmemory> +% \end{macrocode} +% +% +% +% \begin{macrocode} +%<*unused> +\file_input_stop: +% \end{macrocode} +% +% +% \section {Properties} +% +% +% This is the version that uses individual pointers to hold the values. +% maybe we need both? +% It is currently disabled because it does not work with the +% implementation of the mark mechanism. +% +% A property list is a control sequence whose top_level expansion is +% of the form `\zz{tok$\sb1$}\zv{val$\sb1$} \ldots{} +% \zz{tok$\sb{}n$}\zv{val$\sb{}n$}'. The properties have to be single token, +% the values might be arbitrary token lists they get surrounded by +% braces. +% +% To get values from property_lists token_lists should be passed to +% the appropriate functions. +% +% +% \begin{macro}{\prop_split_aux:NNn} +% |\prop_split_aux:NNn|\zz{plist}\zz{prop}\zz{cmd} invokes \zz{cmd} +% with 3 arguments: 1st is the beginning of \zz{plist} before +% \zz{prop}, 2nd is the value associated with \zz{prop}, 3rd is the +% rest of \zz{plist} after \zz{prop}. If there is no property +% \zz{prop} in \zz{plist}, then the 2 arg is |\q_no_value | and +% the 3rd arg is empty; otherwise the 3rd argument has the two +% extra tokens \zz{prop} |\q_no_value| at the end. +% \begin{macrocode} +\def_long:Npn \prop_split_aux:NNn #1#2#3{ + \def:Npn \tmp:w ##1#2##2##3\q_stop {#3{##1}##2{##3}} + \exp_after:NN\tmp:w #1#2\q_no_value \q_stop} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\prop_get:NNN} +% \begin{macro}{\prop_get_aux:w} +% |\prop_get:NNN |\zz{plist}\zz{prop}\zz{tlp} defines +% command to be the value associated with \zz{prop} in \zz{plist}, +% |\q_no_value| if not found. +% \begin{macrocode} +\def_long:Npn \prop_get:NNN #1#2{\prop_split_aux:NNn + #1#2\prop_get_aux:w} +\def_long:Npn \prop_get_aux:w #1#2#3#4{\tlp_set_eq:NN#4#2} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\prop_put:NNn} +% \begin{macro}{\prop_put_aux:w} +% \begin{macro}{\prop_gput:NNn} +% \begin{macro}{\prop_gput:NNx} +% \begin{macro}{\prop_gput:NNo} +% \begin{macro}{\prop_gput:NOx} +% \begin{macro}{\prop_gput:NOo} +% \begin{macro}{\prop_gput:OOo} +% \begin{macro}{\prop_gput:ccx} +% |\prop_put:NNn |\zz{plist}\zz{prop}\zv{val} adds/changes the +% value associated with \zz{prop} in \zz{plist} to \zv{val}. +% \begin{macrocode} +\def_long:Npn \prop_put:NNn #1#2{\prop_split_aux:NNn + #1#2{\prop_put_aux:w \tlp_set:Nn #1#2}} +\def_long:Npn \prop_gput:NNn #1#2{\prop_split_aux:NNn + #1#2{\prop_put_aux:w \tlp_gset:Nn #1#2}} +\def:Npn \prop_gput:NNo {\exp_args:Nnno \prop_gput:NNn} +\def:Npn \prop_gput:NOx {\exp_args:Nnox \prop_gput:NNn} +\def:Npn \prop_gput:NNx {\exp_args:Nnnx \prop_gput:NNn} +\def:Npn \prop_gput:NOo {\exp_args:NNOo \prop_gput:NNn} +\def:Npn \prop_gput:OOo {\exp_args:NOOo \prop_gput:NNn} +\def:Npn \prop_gput:ccn {\exp_args:Ncc \prop_gput:NNn} +\def:Npn \prop_gput:ccx {\exp_args:Nccx \prop_gput:NNn} +\def_long:Npn \prop_put_aux:w #1#2#3#4#5#6#7{ + \quark_if_no_value:nTF#5 + { + \cs_ggen_sym:N\l_testa_tlp + \exp_after:NN#1\exp_after:NN#2\exp_after:NN{\exp_after:NN#3\l_testa_tlp#4} + \exp_after:NN\tlp_gset:Nn\l_testa_tlp + } + {#1#5} + {#7}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% +% Show token usage: +% \begin{macrocode} +%<*showmemory> +%\showMemUsage +%</showmemory> +%</unused> +% \end{macrocode} +% + diff --git a/Master/texmf-dist/source/latex/expl3/l3quark.dtx b/Master/texmf-dist/source/latex/expl3/l3quark.dtx new file mode 100644 index 00000000000..1f95aa6fe71 --- /dev/null +++ b/Master/texmf-dist/source/latex/expl3/l3quark.dtx @@ -0,0 +1,212 @@ +% \iffalse +%% File: l3quark.dtx Copyright (C) 1990-1998 LaTeX3 project +% +%<*dtx> + \ProvidesFile{l3quark.dtx} +%</dtx> +%<package>\NeedsTeXFormat{LaTeX2e} +%<package>\ProvidesPackage{l3quark} +%<driver> \ProvidesFile{l3quark.drv} +% \fi +% \ProvidesFile{l3quark.dtx} + [1998/05/20 v1.0e L3 Experimental Quark Commands] +% +% \iffalse +%<*driver> +\documentclass{l3doc} + +\begin{document} +\DocInput{l3quark.dtx} +\end{document} +%</driver> +% \fi +% +% +% \GetFileInfo{l3quark.dtx} +% \title{The \textsf{l3quark} package\thanks{This file +% has version number \fileversion, last +% revised \filedate.}\\ +% ``Quarks''} +% \author{\Team} +% \date{\filedate} +% \maketitle +% +% +% \section{Quarks} +%^^A \label{sec:quarks} +% +% +% A special type of constants in \LaTeX3 are `quarks'. These are control +% sequences that expand to themselves and should therefore NEVER be +% executed directly in the code. This would result in an endless loop! +% +% They are meant to be used as delimiter is weird functions (for example +% as the stop token (i.e., "\q_stop"). They also permit the following +% ingenious trick: when you pick up a token in a temporary, and you want +% to know whether you have picked up a particular quark, all you have to +% do is compare the temporary to the quark using "\if_meaning:NN". A +% set of special quark testing functions is set up below. +% +% By convention all constants of type quark start out with "\q_". +% +% \subsection{Functions} +% +% \begin{function}{% +% \quark_new:N | +% } +% \begin{syntax} +% "\quark_new:N" <quark> +% \end{syntax} +% Defines <quark> to be a new constant of type "quark". +% \end{function} +% +% \begin{function}{% +% \quark_if_no_value:nTF | +% \quark_if_no_value:nF | +% \quark_if_no_value:nT | +% \quark_if_no_value:NTF | +% \quark_if_no_value:NF | +% } +% \begin{syntax} +% "\quark_if_no_value:nTF" "{" <token list> "}" +% " {"<true code>"}{"<false code>"}" +% "\quark_if_no_value:NTF" <tlp> +% " {"<true code>"}{"<false code>"}" +% \end{syntax} +% This tests whether or not <token list> contains only the quark +% "\q_no_value". +% +% If <token list> to be tested is stored in a token list pointer use +% "\quark_if_no_value:NTF", or "\quark_if_no_value:NF" or check the +% value directly with "\if_meaning:NN". All those cases are faster then +% "\quark_if_no_value:nTF" so should be preferred. +% +% \begin{texnote} +% But be aware of the fact that "\if_meaning:NN" can result in an +% overflow of \TeX{}'s parameter stack since it leaves the corresponding +% "\fi:" on the input until the whole replacement text is processed. It +% is therefore better in recursions to use "\quark_if_no_value:NTF" as +% it will remove the conditional prior to processing the "T" or "F" case +% and so allows tail-recursion. +% \end{texnote} +% \end{function} +% +% \subsection{Constants} +% +% \begin{variable}{\q_no_value} The canonical `missing value quark' +% that is returned by certain functions to denote that a requested value +% is not found in the data structure. +% \end{variable} +% +% \begin{variable}{\q_stop} +% This constant is used as a a marker in parameter text. This allows a +% scanning function to find the end of some input string. +% \end{variable} +% +% \begin{variable}{\q_nil} +% This constant represent the nil pointer in pointer structures. +% \end{variable} +% +% \section{Implementation} +% +% We start by ensuring that the required packages are loaded. +% We check for \texttt{l3expan} since this a basic package that is +% essential for use of any higher-level package. +% \begin{macrocode} +%<package>\RequirePackage{l3expan}\par +%<*package> +% \end{macrocode} +% +% \begin{macro}{\quark_new:N} +% Allocate a new quark. +% \begin{macrocode} +\def_new:Npn \quark_new:N #1{\tlp_new:Nn #1{#1}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\q_stop} +% \begin{macro}{\q_no_value} +% \begin{macro}{\q_nil} +% |\q_stop| is often used as a marker in parameter text, +% |\q_no_value| is the canonical missing value, and |\q_nil| +% represents a nil pointer in some data structures. +% \begin{macrocode} +\quark_new:N \q_stop +\quark_new:N \q_no_value +\quark_new:N \q_nil +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\q_error} +% \begin{macro}{\q_mark} +% We need two additional quarks. |\q_error| delimits the end of +% the computation for purposes of error recovery. |\q_mark| is +% used in parameter text when we need a scanning boundary that is +% distinct from |\q_stop|. +% \begin{macrocode} +\quark_new:N\q_error +\quark_new:N\q_mark +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\quark_if_no_value:NTF} +% \begin{macro}{\quark_if_no_value:NF} +% \begin{macro}{\quark_if_no_value:nTF} +% \begin{macro}{\quark_if_no_value:nT} +% \begin{macro}{\quark_if_no_value:nF} +% Here we test if we found a special quark as the first argument. +% The argument might contain an arbitrary list of tokens, therefore +% we have to wrap it up in a token list pointer. +% \begin{macrocode} +\def_new:Npn \quark_if_no_value:NTF #1{ +% \end{macrocode} +% We better start with |\q_no_value| as the first argument since +% the whole thing may otherwise loop if |#1| is wrongly given +% a string like |aabc| instead of a single token.\footnote{It may +% still loop in special circumstances however!} +% \begin{macrocode} + \if_meaning:NN\q_no_value#1 + \exp_after:NN\use_choice_i:nn + \else: \exp_after:NN\use_choice_ii:nn \fi:} +% \end{macrocode} +% It would be possible to speed up the following commands by +% providing individual implementations similar to the one above. +% Should perhaps be done if they are used often! +% \begin{macrocode} +\def_new:Npn \quark_if_no_value:NF #1{\quark_if_no_value:NTF {#1}\use_noop:} +\def_new:Npn \quark_if_no_value:nTF #1{\tlp_gset:Nn \g_testa_tlp {#1} + \quark_if_no_value:NTF\g_testa_tlp} +\def_new:Npn \quark_if_no_value:nF #1{\quark_if_no_value:nTF {#1}\use_noop:} +\def_new:Npn \quark_if_no_value:nT #1#2{\quark_if_no_value:nTF {#1} + {#2}\use_noop:} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\quark_if_nil:NTF} +% A function to check for the presence of |\q_nil|. +% \begin{macrocode} +\def_new:Npn\quark_if_nil:NTF#1{ + \if_meaning:NN#1\q_nil + \exp_after:NN\use_choice_i:nn + \else: + \exp_after:NN\use_choice_ii:nn\fi:} +% \end{macrocode} +% \end{macro} +% +% Show token usage: +% \begin{macrocode} +%</package> +%<*showmemory> +\showMemUsage +%</showmemory> +% \end{macrocode} +% +% diff --git a/Master/texmf-dist/source/latex/expl3/l3seq.dtx b/Master/texmf-dist/source/latex/expl3/l3seq.dtx new file mode 100644 index 00000000000..f3da69642ef --- /dev/null +++ b/Master/texmf-dist/source/latex/expl3/l3seq.dtx @@ -0,0 +1,622 @@ +% \iffalse +%% File: l3seq.dtx Copyright (C) 1990-1998 LaTeX3 project +% +%<*dtx> + \ProvidesFile{l3seq.dtx} +%</dtx> +%<package>\NeedsTeXFormat{LaTeX2e} +%<package>\ProvidesPackage{l3seq} +%<driver> \ProvidesFile{l3seq.drv} +% \fi +% \ProvidesFile{l3seq.dtx} + [1998/04/20 v1.0d L3 Experimental Token List Pointers] +% +% \iffalse +%<*driver> +\documentclass{l3doc} + +\begin{document} +\DocInput{l3seq.dtx} +\end{document} +%</driver> +% \fi +% +% +% \GetFileInfo{l3seq.dtx} +% \title{The \textsf{l3seq} package\thanks{This file +% has version number \fileversion, last +% revised \filedate.}\\ +% Sequences} +% \author{\Team} +% \date{\filedate} +% \maketitle +% +% +% +% \section{Sequence} +% +% \LaTeX3 implements a data type called `sequences'. These are special +% token lists that can be accessed via special function on the `left'. +% Appending tokens is possible at both ends. Appended token lists can be +% accessed only as a union. The token lists that form the individual +% items of a sequence might contain any tokens except two internal +% functions that are used to structure sequences (see section internal +% functions below). It is also possible to map functions on such +% sequences so that they are executed for every item on the sequence. +% +% All functions that return items from a sequence in some <tlp> assume +% that the <tlp> is local. See remarks below if you need a global +% returned value. +% +% The defined functions are not orthogonal in the sense that every +% possible variation possible is actually available. If you need a new +% variant use the expansion functions described in the package +% \texttt{l3expan} to build it. +% +% Adding items to the left of a sequence can currently be done with +% either something like "\seq_put_left:Nn" or with a ``stack'' function +% like "\seq_push:Nn" which has the same effect. Maybe one should +% therefore remove the ``left'' functions totally. +% +% \subsection{Functions} +% +% \begin{function}{% +% \seq_new:N | +% \seq_new:O | +% \seq_new:c | +% } +% \begin{syntax} +% "\seq_new:N" <sequence> +% \end{syntax} +% Defines <sequence> to be a variable of type sequences. +% \end{function} +% +% \begin{function}{% +% \seq_clear:N | +% \seq_clear:c | +% \seq_gclear:N | +% \seq_gclear:c | +% } +% \begin{syntax} +% "\seq_clear:N" <sequence> +% \end{syntax} +% These functions locally or globally clear <sequence>. +% \end{function} +% +% \begin{function}{% +% \seq_put_left:Nn | +% \seq_put_left:No | +% \seq_put_left:Nx | +% \seq_put_left:cn | +% \seq_put_right:Nn | +% \seq_put_right:No | +% \seq_put_right:Nx | +% } +% \begin{syntax} +% "\seq_put_left:Nn" <sequence> <token list> +% \end{syntax} +% Locally appends <token list> as a single item to the left +% or right of <sequence>. <token list> might get expanded before +% appending. +% \end{function} +% +% \begin{function}{% +% \seq_gput_left:Nn | +% \seq_gput_right:Nn | +% \seq_gput_right:No | +% \seq_gput_right:cn | +% \seq_gput_right:co | +% \seq_gput_right:cc | +% } +% \begin{syntax} +% "\seq_gput_left:Nn" <sequence> <token list> +% \end{syntax} +% Globally appends <token list> as a single item to the left +% or right of <sequence>. +% \end{function} +% +% \begin{function}{% +% \seq_get:NN | +% \seq_get:cN | +% } +% \begin{syntax} +% "\seq_get:NN" <sequence> <tlp> +% \end{syntax} +% Functions that locally assign the left-most item of <sequence> to the +% token list pointer <tlp>. Item is not removed from <sequence>! If you +% need a global return value you need to code something like this: +% \begin{quote} +% "\seq_get:NN" <sequence> "\l_tmpa_tlp" \\ +% "\tlp_gset_eq:NN" <global tlp> "\l_tmpa_tlp" +% \end{quote} +% But if this kind of construction is used often enough a separate +% function should be provided. +% \end{function} +% +% \begin{function}{% +% \seq_gconcat:NNN | +% \seq_gconcat:ccc | +% } +% \begin{syntax} +% "\seq_gconcat:NNN" <seq1> <seq2> <seq3> +% \end{syntax} +% Function that conatenates <seq2> and <seq3> and globally assigns the +% result to <seq1>. +% \end{function} +% +% \begin{function}{\seq_map:NN} +% \begin{syntax} +% "\seq_map:NN" <sequences> <function> +% \end{syntax} +% This function applies <function> (which must be a function with one +% argument) to every item of <sequence>. <function> is not executed +% within a sub-group so that side effects can be achieved locally. The +% operation is not expandable which means that it can't be used within +% write operations etc. +% +% In the current implementation the next functions are more efficient and +% should be preferred. +% \end{function} +% +% \begin{function}{\seq_map_inline:Nn | +% \seq_map_inline:cn +% } +% \begin{syntax} +% "\seq_map_inline:Nn" <sequence> "{" <inline function> "}" +% \end{syntax} +% Applies <inline function> (which should be the direct coding for a +% function with one argument (i.e.\ use "##1" as the place holder for +% this argument)) to every item of <sequence>. <inline function> is not +% executed within a sub-group so that side effects can be achieved locally. +% The operation is not expandable which means that it can't be used +% within write operations etc. +% \end{function} +% +% \subsection{Predicates and conditionals} +% +% \begin{function}{\seq_empty_p:N} +% \begin{syntax} +% "\seq_empty_p:N" <sequence> +% \end{syntax} +% This predicate returns `true' if <sequence> is `empty' i.e., doesn't +% contain any tokens. +% \end{function} +% +% \begin{function}{% +% \seq_empty:NTF | +% \seq_empty:cTF | +% \seq_empty:NF | +% \seq_empty:cF | +% } +% \begin{syntax} +% "\seq_empty:NTF" <sequence> "{" <true code> "}{" <false code> "}" +% \end{syntax} +% Set of conditionals that test whether or not a particular <sequence> +% is empty and if so executes either <true code> or <false code>. +% \end{function} +% +% \begin{function}{% +% \seq_if_in:NnTF | +% \seq_if_in:cnTF | +% \seq_if_in:coTF | +% } +% \begin{syntax} +% "\seq_if_in:NnTF" <sequ> "{" <item> "}{" <true code> "}{" <false code> "}" +% \end{syntax} +% Function that tests if <item> is in <sequ>. Depending on the result +% either <true code> or <false code> is executed. +% \end{function} +% +% \subsection{Internal functions} +% +% \begin{function}{\seq_empty_err:N} +% \begin{syntax} +% "\seq_empty_err:N" <sequence> +% \end{syntax} +% Signals an \LaTeX3 error if <sequence> is empty. +% \end{function} +% +% \begin{function}{\seq_pop_aux:nnNN} +% \begin{syntax} +% "\seq_pop_aux:nnNN" <assign1> <assign2> <sequence> <tlp> +% \end{syntax} +% Function that assigns the left-most item of <sequence> to <tlp> using +% <assign1> and assigns the tail to <sequence> using <assign2>. This +% function could be used to implement a global return function. +% \end{function} +% +% \begin{function}{% +% \seq_get_aux:w | +% \seq_pop_aux:w | +% \seq_put_aux:Nnn | +% \seq_put_aux:w | +% } +% Functions used to implement put and get operations. They are not for +% meant for direct use. +% \end{function} +% +% \begin{function}{% +% \seq_elt:w | +% \seq_elt_end: } +% Functions (usually used as constants) that separates items within a +% sequence. They might get special meaning during mapping operations and +% are not supposed to show up as tokens within an item appended to a +% sequence. +% \end{function} +% +% +% \section {Implementation} +% +% We start by ensuring that the required packages are loaded. +% \begin{macrocode} +%<package&!check>\RequirePackage{l3toks} +%<package&!check>\RequirePackage{l3quark} +%<package&check>\RequirePackage{l3chk} +%<package>\RequirePackage{l3expan} +%<*package> +% \end{macrocode} +% +% A sequence is a control sequence whose top-level expansion is of the +% form `|\seq_elt:w| \m{text$\sb1$} |\seq_elt_end:| \ldots{} +% |\seq_elt:w| \zv{text$\sb{n}$} \ldots'. We use explicit delimiters +% instead of braces around \m{text} to allow efficient searching for +% an item in the sequence. +% +% \begin{macro}{\seq_elt:w} +% \begin{macro}{\seq_elt_end:} +% We allocate the delimiters and make them noops as default. +% \begin{macrocode} +\let_new:NN \seq_elt:w \use_noop: +\let_new:NN \seq_elt_end: \use_noop: +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\seq_new:N} +% \begin{macro}{\seq_new:O} +% \begin{macro}{\seq_new:c} +% Sequences are implemented using token lists. +% \begin{macrocode} +\def_new:Npn \seq_new:N #1{\tlp_new:Nn #1{}} +\def_new:Npn \seq_new:c {\exp_args:Nc \seq_new:N} +\def_new:Npn \seq_new:O {\exp_args:No \seq_new:N} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\seq_clear:N} +% \begin{macro}{\seq_clear:c} +% \begin{macro}{\seq_gclear:N} +% \begin{macro}{\seq_gclear:c} +% Clearing a sequence is the same as clearing a token list. +% \begin{macrocode} +\let_new:NN \seq_clear:N \tlp_clear:N +\let_new:NN \seq_clear:c \tlp_clear:c +\let_new:NN \seq_gclear:N \tlp_gclear:N +\let_new:NN \seq_gclear:c \tlp_gclear:c +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\seq_clear_new:N} +% \begin{macro}{\seq_clear_new:c} +% \begin{macro}{\seq_gclear_new:N} +% \begin{macro}{\seq_gclear_new:c} +% Clearing a sequence is the same as clearing a token list. +% \begin{macrocode} +\let_new:NN \seq_clear_new:N \tlp_clear_new:N +\let_new:NN \seq_clear_new:c \tlp_clear_new:c +\let_new:NN \seq_gclear_new:N \tlp_gclear_new:N +\let_new:NN \seq_gclear_new:c \tlp_gclear_new:c +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\seq_empty_p:N} +% A predicate which evaluates to |\c_true| iff the sequence is empty. +% \begin{macrocode} +\let_new:NN \seq_empty_p:N \tlp_empty_p:N +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\seq_empty:NTF} +% \begin{macro}{\seq_empty:cTF} +% \begin{macro}{\seq_empty:NF} +% \begin{macro}{\seq_empty:cF} +% |\seq_empty:NTF|\m{seq}\m{true~case}\m{false~case} will check +% whether the \m{seq} is empty and then select one of the other +% arguments. |seq_empty:cTF| turns its first argument into a +% control sequence to get the name of the sequence. +% \begin{macrocode} +\def_new:Npn \seq_empty:NTF #1{ + \if_meaning:NN#1\c_empty_tlp + \exp_after:NN\use_choice_i:nn + \else: \exp_after:NN\use_choice_ii:nn \fi:} +\def_new:Npn \seq_empty:cTF {\exp_args:Nc\seq_empty:NTF} +% \end{macrocode} +% A variant of this, is only to do something if the sequence is +% {\em not} empty. +% \begin{macrocode} +\def_new:Npn \seq_empty:NF #1{ + \if_meaning:NN#1\c_empty_tlp \exp_after:NN\use_none:n + \else: \exp_after:NN\use:n \fi:} +\def_new:Npn \seq_empty:cF {\exp_args:Nc\seq_empty:NF} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\seq_empty_err:N} +% Signals an error if the sequence is empty. +% \begin{macrocode} +\def_new:Npn \seq_empty_err:N #1{\if_meaning:NN#1\c_empty_tlp +% \end{macrocode} +% As I said before, I don't think we need to provide checks for this +% kind of error, since it is a severe internal macro package error +% that can not be produced by the user directly. Can it? So the +% next line of code should be probably removed. +% \begin{macrocode} + \tlp_clear:N \l_testa_tlp % catch prefixes + \err_latex_bug:n{Empty~sequence~`\token_to_string:N#1'}\fi:} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\seq_get:NN} +% \begin{macro}{\seq_get:cN} +% |\seq_get:NN |\zz{sequence}\zz{cmd} defines \zz{cmd} to be the +% left_most element of \zz{sequence}. +% \begin{macrocode} +\def_new:Npn \seq_get:NN #1{ + \seq_empty_err:N #1 + \exp_after:NN\seq_get_aux:w #1\q_stop} +\def_new:Npn \seq_get_aux:w \seq_elt:w #1\seq_elt_end: + #2\q_stop #3{\tlp_set:Nn #3{#1}} +\def_new:Npn \seq_get:cN {\exp_args:Nc \seq_get:NN} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\seq_pop_aux:nnNN} +% |\seq_pop_aux:nnNN| \zz{def$\sb1$} \zz{def$\sb2$} \zz{sequence} +% \zz{cmd} assigns the left_most element of \zz{sequence} to +% \zz{cmd} using \zz{def$\sb2$}, and assigns the tail of +% \zz{sequence} to \zz{sequence} using \zz{def$\sb1$}. +% \begin{macrocode} +\def_new:Npn \seq_pop_aux:nnNN #1#2#3{ + \seq_empty_err:N #3 + \exp_after:NN\seq_pop_aux:w #3\q_stop #1#2#3} +\def_new:Npn \seq_pop_aux:w \seq_elt:w #1\seq_elt_end: + #2\q_stop #3#4#5#6{#3#5{#2}#4#6{#1}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\seq_put_aux:Nnn} +% |\seq_put_aux:Nnn| \zz{sequence} \zv{left} \zv{right} adds the +% elements specified by \zv{left} to the left of \zz{sequence}, and +% those specified by \zv{right} to the right. +% \begin{macrocode} +\def_new:Npn \seq_put_aux:Nnn #1{ + \exp_after:NN\seq_put_aux:w #1\q_stop #1} +\def_new:Npn \seq_put_aux:w #1\q_stop #2#3#4{\tlp_set:Nn #2{#3#1#4}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\seq_put_left:Nn} +% \begin{macro}{\seq_put_left:No} +% \begin{macro}{\seq_put_left:Nx} +% \begin{macro}{\seq_put_left:cn} +% \begin{macro}{\seq_put_right:Nn} +% \begin{macro}{\seq_put_right:No} +% \begin{macro}{\seq_put_right:Nx} +% Here are the usual operations for adding to the left and right. +% \begin{macrocode} +\def_new:Npn \seq_put_left:Nn #1#2{ +% \end{macrocode} +% We can't put in a |\use_noop:| instead of |{}| since this argument is +% passed literally (and we would end up with many |\use_noop:|s inside +% the sequences. +% \begin{macrocode} + \seq_put_aux:Nnn #1{\seq_elt:w #2\seq_elt_end:}{}} +\def_new:Npn \seq_put_left:cn {\exp_args:Nc\seq_put_left:Nn} +\def_new:Npn \seq_put_left:No {\exp_args:NNo\seq_put_left:Nn} +\def_new:Npn \seq_put_left:Nx {\exp_args:Nnx\seq_put_left:Nn} +\def_new:Npn \seq_put_right:Nn #1#2{ + \seq_put_aux:Nnn #1{}{\seq_elt:w #2\seq_elt_end:}} +\def_new:Npn \seq_put_right:No {\exp_args:Nno\seq_put_right:Nn} +\def_new:Npn \seq_put_right:Nx {\exp_args:Nnx\seq_put_right:Nn} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\seq_gput_left:Nn} +% \begin{macro}{\seq_gput_right:Nn} +% \begin{macro}{\seq_gput_right:No} +% \begin{macro}{\seq_gput_right:cn} +% \begin{macro}{\seq_gput_right:co} +% \begin{macro}{\seq_gput_right:cc} +% An here the global variants. +% \begin{macrocode} +\def_new:Npn \seq_gput_left:Nn { +%<*check> + \pref_global_chk: +%</check> +%<_check> \pref_global:D + \seq_put_left:Nn} +\def_new:Npn \seq_gput_right:Nn { +%<*check> + \pref_global_chk: +%</check> +%<_check> \pref_global:D + \seq_put_right:Nn} +\def_new:Npn \seq_gput_right:No {\exp_args:NNo \seq_gput_right:Nn} +\def_new:Npn \seq_gput_right:cn {\exp_args:Nc \seq_gput_right:Nn} +\def_new:Npn \seq_gput_right:co {\exp_args:Nco \seq_gput_right:Nn} +\def_new:Npn \seq_gput_right:cc {\exp_args:Ncc \seq_gput_right:Nn} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\seq_map:NN} +% |\seq_map:NN| \zz{sequence} \zz{cmd} applies \zz{cmd} to each +% element of \zz{sequence}, from left to right. Since we don't have +% braces, this implementation is not very efficient. It might be +% better to say that \zz{cmd} must be a function with one argument +% that is delimited by |\seq_elt_end:|. +% \begin{macrocode} +\def_new:Npn \seq_map:NN #1#2{ + \def:Npn \seq_elt:w ##1\seq_elt_end: {#2{##1}}#1} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\seq_map_inline:Nn} +% \begin{macro}{\seq_map_inline:cn} +% When no braces are used, this version of mapping seems more +% natural. +% \begin{macrocode} +\def_new:Npn \seq_map_inline:Nn #1#2{ + \gdef:Npn \seq_elt:w ##1\seq_elt_end: {#2}#1} +\def_new:Npn \seq_map_inline:cn{\exp_args:Nc\seq_map_inline:Nn} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\seq_gconcat:NNN} +% \begin{macro}{\seq_gconcat:ccc} +% |\seq_gconcat:NNN| \m{seq~1} \m{seq~2} \m{seq~3} will globally +% assign \m{seq~1} the concatenation of \m{seq~2} and \m{seq~3}. +% \begin{macrocode} +\def_new:Npn \seq_gconcat:NNN #1#2#3{ + \l_tmpa_toks \exp_after:NN{#2} + \l_tmpb_toks \exp_after:NN{#3} + \gdef:Npx #1{\toks_use:N \l_tmpa_toks \toks_use:N \l_tmpb_toks}} +\def_new:Npn \seq_gconcat:ccc{\exp_args:Nccc\seq_gconcat:NNN} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\seq_if_in:NnTF} +% \begin{macro}{\seq_if_in:cnTF} +% \begin{macro}{\seq_if_in:coTF} +% |\seq_if_in:NnTF| \m{seq}\m{item} \m{true~case} \m{false~case} +% will check whether \m{item} is in \m{seq} and then either execute +% the \m{true~case} or the \m{false~case}. \m{true~case} and +% \m{false~case} may contain incomplete |\if_char_code:w| +% statements. +% \begin{macrocode} +\def_new:Npn \seq_if_in:NnTF #1#2{ + \def:Npn\tmp:w + ##1\seq_elt:w #2\seq_elt_end: ##2##3\q_stop{ +% \end{macrocode} +% Note that |##2| contains exactly one token which we can compare +% with |\q_no_value|. +% \begin{macrocode} + \if_meaning:NN\q_no_value##2 + \exp_after:NN\use_choice_ii:nn + \else: + \exp_after:NN\use_choice_i:nn + \fi: + } + \exp_after:NN + \tmp:w #1\seq_elt:w + #2\seq_elt_end: \q_no_value \q_stop} +\def_new:Npn \seq_if_in:coTF {\exp_args:Nco \seq_if_in:NnTF} +\def_new:Npn \seq_if_in:cnTF {\exp_args:Nc \seq_if_in:NnTF} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% +% \subsection{Stack operations} +% +% We build stacks from sequences, but here we put the +% specific functions together. +% +% +% \begin{macro}{\seq_push:Nn} +% \begin{macro}{\seq_push:No} +% \begin{macro}{\seq_push:cn} +% \begin{macro}{\seq_pop:NN} +% \begin{macro}{\seq_pop:cN} +% Since sequences can be used as stacks, we ought to have both +% `push' and `pop'. In most cases they are nothing more then new +% names for old functions. +% \begin{macrocode} +\let_new:NN \seq_push:Nn \seq_put_left:Nn +\let_new:NN \seq_push:No \seq_put_left:No +\let_new:NN \seq_push:cn \seq_put_left:cn +\def_new:Npn \seq_pop:NN {\seq_pop_aux:nnNN \tlp_set:Nn \tlp_set:Nn} +\def_new:Npn \seq_pop:cN {\exp_args:Nc \seq_pop:NN} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% +% \begin{macro}{\seq_gpush:Nn} +% \begin{macro}{\seq_gpush:No} +% \begin{macro}{\seq_gpush:cn} +% \begin{macro}{\seq_gpop:NN} +% \begin{macro}{\seq_gpop:cN} +% I don't agree with Denys that one needs only local stacks, +% actually I believe that one will probably need the functions +% here more often. In case of |\seq_gpop:NN| the value is +% nevertheless returned locally. +% \begin{macrocode} +\let_new:NN \seq_gpush:Nn \seq_gput_left:Nn +\def_new:Npn \seq_gpush:No {\exp_args:NNo \seq_gpush:Nn} +\def_new:Npn \seq_gpush:cn {\exp_args:Nc \seq_gpush:Nn} +\def_new:Npn \seq_gpop:NN {\seq_pop_aux:nnNN \tlp_gset:Nn \tlp_set:Nn} +\def_new:Npn \seq_gpop:cN {\exp_args:Nc \seq_gpop:NN} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\seq_top:NN} +% \begin{macro}{\seq_top:cN} +% Looking at the top element of the stack without removing it is +% done with this operation. +% \begin{macrocode} +\let_new:NN \seq_top:NN \seq_get:NN +\let_new:NN \seq_top:cN \seq_get:cN +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% Show token usage: +% \begin{macrocode} +%</package> +%<*showmemory> +%\showMemUsage +%</showmemory> +% \end{macrocode} +% +% +% + diff --git a/Master/texmf-dist/source/latex/expl3/l3tlp.dtx b/Master/texmf-dist/source/latex/expl3/l3tlp.dtx new file mode 100644 index 00000000000..ecc51de9b20 --- /dev/null +++ b/Master/texmf-dist/source/latex/expl3/l3tlp.dtx @@ -0,0 +1,600 @@ +% \iffalse +%% File: l3tlp.dtx Copyright (C) 1990-1998 LaTeX3 project +% +%<*dtx> + \ProvidesFile{l3tlp.dtx} +%</dtx> +%<package>\NeedsTeXFormat{LaTeX2e} +%<package>\ProvidesPackage{l3tlp} +%<driver> \ProvidesFile{l3tlp.drv} +% \fi +% \ProvidesFile{l3tlp.dtx} + [1998/04/20 v1.0d L3 Experimental Token List Pointers] +% +% \iffalse +%<*driver> +\documentclass{l3doc} + +\begin{document} +\DocInput{l3tlp.dtx} +\end{document} +%</driver> +% \fi +% +% +% \GetFileInfo{l3tlp.dtx} +% \title{The \textsf{l3tlp} package\thanks{This file +% has version number \fileversion, last +% revised \filedate.}\\ +% Token List Pointers} +% \author{\Team} +% \date{\filedate} +% \maketitle +% +% +% +% \section {Token list pointers} +% +% \LaTeX3 stores token lists in so called `token list pointers'. +% Variables of this type get the suffix "tlp" and functions of this type +% have the prefix "tlp". To use a token list pointer you simply call +% the corresponding variable. +% +% \subsection{Functions} +% +% \begin{function}{\tlp_new:Nn} +% \begin{syntax} +% "\tlp_new:Nn" <tlp> "{" <initial token list> "}" +% \end{syntax} +% Defines <varible> to be a new variable (or constant) of type token +% list pointer. <initial token list> is the initial value of +% <tlp>. This makes it possible to assign values to a constant +% token list pointer. +% \end{function} +% +% \begin{function}{% +% \tlp_set:Nn | +% \tlp_set:Nc | +% \tlp_set:No | +% \tlp_set:Nx | +% \tlp_gset:Nn | +% \tlp_gset:Nc | +% \tlp_gset:No | +% \tlp_gset:Nx} +% \begin{syntax} +% "\tlp_set:Nn" <tlp> "{" <token list> "}" +% \end{syntax} +% Defines <tlp> to hold the token list <token list>. Global +% variants of this command assign the value globally the other variants +% expand the <token list> up to a certain level before the assignment +% or interpret the <tokenlist> as a character list and form a control +% sequence out of it. +% \end{function} +% +% \begin{function}{% +% \tlp_clear:N | +% \tlp_clear:c | +% \tlp_gclear:N | +% \tlp_gclear:c +% } +% \begin{syntax} +% "\tlp_clear:N" <tlp> +% \end{syntax} +% The <tlp> is locally or globally cleared. The "c" variants will +% generate a control sequence name which is then interpreted as +% <tlp> before clearing. +% \end{function} +% +% \begin{function}{% +% \tlp_clear_new:N | +% \tlp_clear_new:c | +% } +% \begin{syntax} +% "\tlp_clear_new:N" <tlp> +% \end{syntax} +% These functions check if <tlp> exists. If it does it will be cleared; +% if it doesn't it will be allocated. +% \end{function} +% +% \begin{function}{% +% \tlp_put_left:Nn | +% \tlp_put_left:No | +% \tlp_gput_left:Nn | +% \tlp_gput_left:No | +% \tlp_put_right:Nn | +% \tlp_put_right:cc | +% \tlp_gput_right:Nn | +% \tlp_gput_right:No +% } +% \begin{syntax} +% "\tlp_put_left:Nn" <tlp> "{" <token list> "}" +% \end{syntax} +% These functions will append <token list> to the left or right of +% <tlp>. Assigment is done either locally or globally and <token +% list> might be subject to expansion before assigment. +% \end{function} +% +% \begin{function}{% +% \tlp_set_eq:NN | +% \tlp_gset_eq:NN +% } +% \begin{syntax} +% "\tlp_set_eq:NN" <tlp1> <tlp2> +% \end{syntax} +% Fast form for +% \begin{syntax} +% "\tlp_set:No" <tlp1> "{" <tlp2> "}" +% \end{syntax} +% when <tlp2> is known to be a variable of type token list pointer. +% \end{function} +% +% \begin{function}{\tlp_to_str:N | +% \tlp_to_str:c +% } +% \begin{syntax} +% "\tlp_to_str:N" <tlp> +% \end{syntax} +% This function returns the token list kept in <tlp> as a string list +% with all characters catcoded to `other'. +% \end{function} +% +% \subsection{Predicates and conditionals} +% +% \begin{function}{\tlp_empty_p:N} +% \begin{syntax} +% "\tlp_empty_p:N" <tlp> +% \end{syntax} +% This predicate returns `true' if <tlp> is `empty' i.e., doesn't +% contain any tokens. +% \end{function} +% +% \begin{function}{\tlp_empty:NF| +% \tlp_empty:NTF} +% \begin{syntax} +% "\tlp_empty:NF" <tlp> "{"<false code>"}" +% \end{syntax} +% Execute <false code> if <tlp> is empty. +% contain any tokens. +% \end{function} +% +% \begin{function}{\tlp_eq:NNF} +% \begin{syntax} +% "\tlp_eq:NNF" <tlp1> <tlp2> "{"<false code>"}" +% \end{syntax} +% Execute <false code> if <tlp1> doesn't hold the same token list as +% <tlp2>. +% \end{function} +% +% \subsection{Variable and constants} +% +% \begin{variable}{\C_job_name_tlp} +% Constant that gets the `job name' assigned when \TeX{} starts. +% \begin{texnote} +% This is the new name for the primitive \tn{jobname}. It is a constant +% that will be set by \TeX{} and can not be overwritten by the package. +% Therefore the "C" +% \end{texnote} +% \end{variable} +% +% \begin{variable}{\c_empty_tlp} +% Constant that is always empty. +% \begin{texnote} +% This was named \tn{@empty} in \LaTeX2 and \tn{empty} in plain \TeX{}. +% \end{texnote} +% \end{variable} +% +% \begin{variable}{\c_relax_tlp} +% Constant holding the token that is assigned to a newly created control +% sequence by \TeX. +% \end{variable} +% +% \begin{variable}{% +% \l_tmpa_tlp | +% \l_tmpb_tlp | +% \g_tmpa_tlp | +% \g_tmpb_tlp +% } +% Scratch register for immediate use. They are not used by conditionals +% or predicate functions. +% \end{variable} +% +% \subsubsection{Internal functions} +% +% \begin{function}{\tlp_put_left:aux} +% Used by "\tlp_put_left:Nn" and its variants. +% \end{function} +% +% \begin{function}{\tlp_to_str:aux} +% Function used to implement "\tlp_to_str:N". +% \end{function} +% +% \StopEventually{} +% +% \section{The code} +% +% We start by ensuring that the required packages are loaded. +% \begin{macrocode} +%<package&!check>\RequirePackage{l3basics}\par +%<package&check>\RequirePackage{l3chk}\par +%<*package> +% \end{macrocode} +% +% A token list pointer is a control sequence that holds tokens. The +% interface is similar to that for token registers, but beware that +% the behavior vis \'a vis |\def:Npx| etc. \ldots{} is different. (You +% see this comes from Denys' implementation.) +% +% We don't implement a |\tlp_use:n| function. Execution is done by +% calling the list. +% +% +% \begin{macro}{\tlp_new:Nn} +% \begin{macro}{\tlp_clear:N} +% \begin{macro}{\tlp_gclear:N} +% We provide one allocation function (which checks that the name is +% not used) and two clear functions that locally or globally clear +% the token list. The allocation function has two arguments to +% specify an initial value. This is the only way to give values to +% constants. +% \begin{macrocode} +%<*check> +\def_long_new:Npn \tlp_new:Nn #1#2{ + \chk_new_cs:N #1 + \chk_var_or_const:N #1 +% \end{macrocode} +% The next line contains the token list assignments without any +% checking for variable types etc.\ since we want to allow to +% update constants here. +% \begin{macrocode} + \gdef:Npn #1{#2}} +%</check> +%<-check> \let_new:NN\tlp_new:Nn\gdef:Npn +\def_long_new:Npn \tlp_clear:N #1{\tlp_set_eq:NN #1\c_empty_tlp} +\def_long_new:Npn \tlp_gclear:N #1{\tlp_gset_eq:NN #1\c_empty_tlp} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\tlp_clear:c} +% \begin{macro}{\tlp_gclear:c} +% We also define the variants that construct the token list name +% from a string. +% \begin{macrocode} +\def_new:Npn \tlp_clear:c {\exp_args:Nc \tlp_clear:N} +\def_new:Npn \tlp_gclear:c {\exp_args:Nc \tlp_gclear:N} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\tlp_clear_new:N} +% \begin{macro}{\tlp_clear_new:c} +% These macros check whether a token list exists. If it does it +% is cleared, if it doesn't it is allocated. +% \begin{macrocode} +%<*check> +\def_long_new:Npn \tlp_clear_new:N #1{ + \chk_var_or_const:N #1 + \if:w \cs_exist_p:N #1 + \tlp_clear:N #1 + \else: + \tlp_new:Nn #1{} + \fi:} +%</check> +%<-check>\let_new:NN \tlp_clear_new:N \tlp_clear:N +\def_long_new:Npn \tlp_clear_new:c {\exp_args:Nc \tlp_clear_new:N} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\tlp_gclear_new:N} +% \begin{macro}{\tlp_gclear_new:c} +% These are the global versions of the above. +% \begin{macrocode} +%<*check> +\def_long_new:Npn \tlp_gclear_new:N #1{ + \chk_var_or_const:N #1 + \if:w \cs_exist_p:N #1 + \tlp_gclear:N #1 + \else: + \tlp_new:Nn #1{} + \fi:} +%</check> +%<-check>\let_new:NN \tlp_gclear_new:N \tlp_gclear:N +\def_long_new:Npn \tlp_gclear_new:c {\exp_args:Nc \tlp_gclear_new:N} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\tlp_put_left:Nn} +% \begin{macro}{\tlp_put_left:No} +% \begin{macro}{\tlp_gput_left:Nn} +% \begin{macro}{\tlp_gput_left:No} +% \begin{macro}{\tlp_put_left:aux} +% We can add tokens to the left (either globally or locally). +% \begin{macrocode} +\def_long_new:Npn \tlp_put_left:Nn #1{\exp_after:NN +% \end{macrocode} +% We need expanding over a brace to ensure that if |#1| contains +% just one token within braces the braces are preserved. +% \begin{macrocode} + \tlp_put_left:aux\exp_after:NN{#1}#1} +\def_new:Npn\tlp_put_left:No{\exp_args:NNo\tlp_put_left:Nn} +\def_long_new:Npn \tlp_gput_left:Nn { +%<*check> + \pref_global_chk: +%</check> +%<-check> \pref_global:D + \tlp_put_left:Nn} +\def_new:Npn\tlp_gput_left:No{\exp_args:NNo\tlp_gput_left:Nn} +\def_long_new:Npn \tlp_put_left:aux #1#2#3{\def:Npn #2{#3#1} +% \end{macrocode} +% We check the type afterwards to avoid conflicts with the use of +% |\pref_global:D|. +% \begin{macrocode} +%<*check> + \chk_local_or_pref_global:N #2 +%</check> +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\tlp_put_right:Nn} +% \begin{macro}{\tlp_put_right:No} +% \begin{macro}{\tlp_put_right:Nx} +% \begin{macro}{\tlp_put_right:cc} +% \begin{macro}{\tlp_gput_right:Nn} +% \begin{macro}{\tlp_gput_right:No} +% \begin{macro}{\tlp_gput_right:Nx} +% These are variants of the functions above, but for adding tokens +% to the right. +% \begin{macrocode} +\def_long_new:Npn \tlp_put_right:Nn #1#2{\tlp_set:No #1{#1#2}} +\def_long_new:Npn \tlp_gput_right:Nn #1#2{\tlp_gset:No #1{#1#2}} +\def_new:Npn \tlp_gput_right:No {\exp_args:NNo \tlp_gput_right:Nn} +\def_new:Npn \tlp_gput_right:Nx {\exp_args:NNx \tlp_gput_right:Nn} +\def_new:Npn \tlp_put_right:cc {\exp_args:Ncc \tlp_put_right:Nn} +\def_new:Npn \tlp_put_right:No {\exp_args:NNo \tlp_put_right:Nn} +\def_new:Npn \tlp_put_right:Nx {\exp_args:Nnx \tlp_put_right:Nn} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\tlp_set:Nn} +% \begin{macro}{\tlp_set:No} +% \begin{macro}{\tlp_set:Nx} +% \begin{macro}{\tlp_gset:Nn} +% \begin{macro}{\tlp_gset:No} +% \begin{macro}{\tlp_gset:Nx} +% \begin{macro}{\tlp_set_eq:NN} +% \begin{macro}{\tlp_gset_eq:NN} +% To set token lists to a specific value to type of functions are +% available: |\tlp_set_eq:NN| takes two token-lists as its +% arguments assign the first the contents of the second; +% |\tlp_set:Nn| has as its second argument a `real' list of tokens. +% One can view |\tlp_set_eq:NN| as a special form of |\tlp_set:No| +% (which is not implemented). Both functions have global +% counterparts. +% +% During development we check if the token list that is being +% assigned to exists. If not, a warning will be issued. +% \begin{macrocode} +%<*check> +\def_long_new:Npn \tlp_set:Nn #1#2{ + \chk_exist_cs:N #1 + \def:Npn #1{#2} +% \end{macrocode} +% We use |\chk_local_or_pref_global:N| after the assignment to +% allow constructs with |\pref_global_chk:|. But one should note +% that this is less efficient then using the real global variant +% since they are builtin. +% \begin{macrocode} + \chk_local_or_pref_global:N #1} +\def_long_new:Npn \tlp_set:No { + \exp_args:NNo \tlp_set:Nn} +\def_long_new:Npn \tlp_set:Nx #1#2{ + \chk_exist_cs:N #1 + \def:Npx #1{#2}\chk_local:N #1} +\def_long_new:Npn \tlp_gset:Nn #1#2{ + \chk_exist_cs:N #1 + \gdef:Npn #1{#2}\chk_global:N #1} +\def_long_new:Npn \tlp_gset:No { + \exp_args:NNo \tlp_gset:Nn} +\def_long_new:Npn \tlp_gset:Nx #1#2{ + \chk_exist_cs:N #1 + \gdef:Npx #1{#2}\chk_global:N #1} +\def_long_new:Npn \tlp_set_eq:NN #1#2{ + \chk_exist_cs:N #1 + \let:NwN #1#2 + \chk_local_or_pref_global:N #1\chk_var_or_const:N #2} +\def_long_new:Npn \tlp_gset_eq:NN #1#2{ + \chk_exist_cs:N #1 + \glet:NN #1#2 + \chk_global:N #1\chk_var_or_const:N #2} +%</check> +% \end{macrocode} +% For some functions like |\tlp_set:Nn| we need to define the +% `non-check' version with arguments since we want to allow +% constructions like |\tlp_set:Nn\l_tmpa_tlp\foo| and so we can't +% use the primitive \TeX{} command. +% \begin{macrocode} +%<-check> \def_new:Npn\tlp_set:Nn#1#2{\def:Npn#1{#2}} +%<-check> \def_new:Npn\tlp_set:Nx#1#2{\def:Npx#1{#2}} +%<-check> \def_new:Npn\tlp_gset:Nn#1#2{\gdef:Npn#1{#2}} +%<-check> \def_new:Npn\tlp_gset:Nx#1#2{\gdef:Npx#1{#2}} +%<-check> \let_new:NN\tlp_set:No\def:No +%<-check> \let_new:NN\tlp_gset:No\gdef:No +%<-check> \let_new:NN\tlp_set_eq:NN\let:NwN +%<-check> \let_new:NN\tlp_gset_eq:NN\glet:NN +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\tlp_gset:Nc} +% \begin{macro}{\tlp_set:Nc} +% These two functions are included because they are necessary in +% Denys' implementations. The |:Nc| convention (see the expansion +% module) is very unusual at first sight, but it works nicely +% over all modules, so we would like to keep it. +% +% Construct a control sequence on the fly from |#2| and save it in +% |#1|. +% \begin{macrocode} +\def_new:Npn \tlp_gset:Nc { +%<*check> + \pref_global_chk: +%</check> +%<-check> \pref_global:D + \tlp_set:Nc} +% \end{macrocode} +% |\pref_global_chk:| will turn the variable check in |\tlp_set:No| +% into a global check. +% \begin{macrocode} +\def_new:Npn \tlp_set:Nc #1#2{\tlp_set:No #1{\cs:w#2\cs_end:}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% We also provide a few conditionals, both in expandable form (with +% |\c_true|) and in `brace-form', the latter are denoted by |TF| at the +% end, as explained elsewhere. +% +% +% \begin{macro}{\tlp_empty_p:N} +% Returns |\c_true| iff the token list in the argument is empty. +% \begin{macrocode} +\def_new:Npn \tlp_empty_p:N #1{ + \if_meaning:NN#1\c_empty_tlp \c_true \else: \c_false \fi:} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\tlp_empty:NF} +% \begin{macro}{\tlp_empty:NTF} +% These functions check whether the token list in the argument is +% empty and execute the proper code from their argument(s). +% \begin{macrocode} +\def_new:Npn \tlp_empty:NF #1{ + \if_meaning:NN#1\c_empty_tlp + \exp_after:NN\use_none:nn + \fi: + \use:n} +\def_new:Npn \tlp_empty:NTF #1{ + \if_meaning:NN#1\c_empty_tlp + \exp_after:NN\use_choice_i:nn + \else: + \exp_after:NN\use_choice_ii:nn + \fi:} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\tlp_eq:NNF} +% This function test whether the token lists that are in its first +% two arguments are equal; if they are not |#3| is executed. +% \begin{macrocode} +\def_new:Npn \tlp_eq:NNF #1#2{ + \if_meaning:NN#1#2 + \exp_after:NN\use_none:nn + \fi: + \use:n} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\c_empty_tlp} +% \begin{macro}{\c_relax_tlp} +% Two constants which are often used. +% \begin{macrocode} +\tlp_new:Nn \c_empty_tlp {} +\tlp_new:Nn \c_relax_tlp {\scan_stop:} +% \end{macrocode} +% \end{macro} +% \end{macro} + +% \begin{macro}{\g_tmpa_tlp} +% \begin{macro}{\g_tmpb_tlp} +% Global temporary token list pointers. +% They are supposed to be set and used immediately, +% with no delay between the definition and the use because you +% can't count on other macros not to redefine them from under you. +% +% \begin{macrocode} +\tlp_new:Nn \g_tmpa_tlp{} +\tlp_new:Nn \g_tmpb_tlp{} +% \end{macrocode} +% \end{macro} +% \end{macro} +% + +% \begin{macro}{\l_testa_tlp} +% \begin{macro}{\l_testb_tlp} +% \begin{macro}{\g_testa_tlp} +% \begin{macro}{\g_testb_tlp} +% Global and local temporaries. These are the ones for test +% routines. This means that one can safely use other temporaries +% when calling test routines. +% \begin{macrocode} +\tlp_new:Nn \l_testa_tlp {} +\tlp_new:Nn \l_testb_tlp {} +\tlp_new:Nn \g_testa_tlp {} +\tlp_new:Nn \g_testb_tlp {} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% + +% \begin{macro}{\l_tmpa_tlp} +% \begin{macro}{\l_tmpb_tlp} +% These are local temporary token list pointers. +% \begin{macrocode} +\tlp_new:Nn \l_tmpa_tlp{} +\tlp_new:Nn \l_tmpb_tlp{} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\tlp_to_str:N} +% \begin{macro}{\tlp_to_str:c} +% \begin{macro}{\tlp_to_str:aux} +% These functions return the replacement text of a token list as a +% string list with all characters catcoded to `other'. +% \begin{macrocode} +\def_new:Npn \tlp_to_str:N {\exp_after:NN\tlp_to_str:aux + \token_to_meaning:N} +\def_new:Npn \tlp_to_str:aux #1>{} +\def_new:Npn\tlp_to_str:c{\exp_args:Nc\tlp_to_str:N} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% Show token usage: +% \begin{macrocode} +%</package> +%<*showmemory> +\showMemUsage +%</showmemory> +% \end{macrocode} +% diff --git a/Master/texmf-dist/source/latex/expl3/l3toks.dtx b/Master/texmf-dist/source/latex/expl3/l3toks.dtx new file mode 100644 index 00000000000..7e233e725fc --- /dev/null +++ b/Master/texmf-dist/source/latex/expl3/l3toks.dtx @@ -0,0 +1,417 @@ +% \iffalse +%% File: l3toks.dtx Copyright (C) 1990-1998 LaTeX3 project +% +%<*dtx> + \ProvidesFile{l3toks.dtx} +%</dtx> +%<package>\NeedsTeXFormat{LaTeX2e} +%<package>\ProvidesPackage{l3toks} +%<driver> \ProvidesFile{l3toks.drv} +% \fi +% \ProvidesFile{l3toks.dtx} + [1998/05/14 v1.0g L3 Experimental Token Registers] +% +% \iffalse +%<*driver> +\documentclass{l3doc} + +\begin{document} +\DocInput{l3toks.dtx} +\end{document} +%</driver> +% \fi +% +% +% \GetFileInfo{l3toks.dtx} +% \title{The \textsf{l3toks} package\thanks{This file +% has version number \fileversion, last +% revised \filedate.}\\ +% Token Registers} +% \author{\Team} +% \date{\filedate} +% \maketitle +% +% \section {Token Registers} +% +% There is a second form beside token list pointers in which \LaTeX3 +% stores token lists, namely the internal \TeX{} token registers. +% Functions dealing with these registers got the prefix "\toks_". Unlike +% token list pointers we have an accessing function as one can see +% below. +% +% The main difference between <toks> (token registers) and <tlp> (token +% list pointers) is their behavior regarding expansion. While <tlp>'s +% expand fully (i.e., until only unexpandable tokens are left) inside +% an argument that is subject to expansion (i.e., denote by |x|) +% <toks>'s expand always only up to one level, i.e., passing their +% contents without further expansion. +% +% \subsection{Functions} +% +% \begin{function}{\toks_new:N} +% \begin{syntax} +% "\toks_new:N" <toks> +% \end{syntax} +% Defines <toks> to be a new token list register. +% token list pointer. +% \begin{texnote} +% This is the \LaTeX3 allocation for what was called \tn{newtoks} in +% plain \TeX. +% \end{texnote} +% \end{function} +% +% \begin{function}{% +% \toks_set:Nn | +% \toks_set:No | +% \toks_set:Nx | +% \toks_gset:Nn | +% \toks_gset:No | +% \toks_gset:Nx} +% \begin{syntax} +% "\toks_set:Nn" <toks> "{"<token list>"}" +% \end{syntax} +% Defines <toks> to hold the token list <token list>. Global +% variants of this command assign the value globally the other variants +% expand the <token list> up to a certain level before the assignment +% or interpret the <token list> as a character list and form a control +% sequence out of it. +% \begin{texnote} +% "\toks_set:Nn" could have been specified in plain \TeX{} by <toks> "=" +% "{" <token list> "}" but all other functions have no counterpart in +% plain \TeX. Additionally the functions above will check for correct +% local and global assignments, something that isn't available in plain +% \TeX. +% \end{texnote} +% \end{function} +% +% \begin{function}{% +% \toks_gset_eq:NN | +% } +% \begin{syntax} +% "\toks_gset_eq:NN" <toks1> <toks2> +% \end{syntax} +% The <toks1> globally set to the value of <toks2>. Don't try to use +% "\toks_gset:Nn" for this purpose if the second argument is also a +% token register. +% \end{function} +% +% \begin{function}{% +% \toks_clear:N | +% \toks_gclear:N | +% } +% \begin{syntax} +% "\toks_clear:N" <toks> +% \end{syntax} +% The <toks> is locally or globally cleared. +% \end{function} +% +% \begin{function}{% +% \toks_put_left:Nn | +% \toks_gput_left:Nn | +% \toks_put_right:Nn | +% \toks_gput_right:Nn | +% \toks_gput_right:Nx | +% } +% \begin{syntax} +% "\toks_put_left:Nn" <toks> "{"<token list>"}" +% \end{syntax} +% These functions will append <token list> to the left or right of +% <toks>. Assignment is done either locally or globally. If possible +% append to the right since this operation is faster. +% \end{function} +% +% \begin{function}{\toks_use:N} +% \begin{syntax} +% "\toks_use:N" <toks> +% \end{syntax} +% Accesses the contents of <toks>. Contrary to token list pointers +% <toks> can't be access simply by calling them directly. +% \begin{texnote} +% Something like \tn{the} <toks>. +% \end{texnote} +% \end{function} +% +% \begin{function}{\toks_use_clear:N | +% \toks_use_gclear:N} +% \begin{syntax} +% "\toks_use_clear:N" <toks> +% \end{syntax} +% Accesses the contents of <toks> and clears (locally or globally) it +% afterwards. Actually the clearing operation is done in a way that does +% not prohibit the access of the following tokens in the input stream +% with functions stored in the token register. In other words this +% function is not exactly the same as calling "\toks_use:N" <toks> +% "\toks_clear:N" <toks> in sequence. +% \end{function} +% +% \subsection{Predicates} +% +% \begin{function}{\toks_empty:NTF} +% \begin{syntax} +% "\toks_empty:NTF" <toks> "{"<true code>"}{"<false code>"}" +% \end{syntax} +% Tests if <toks> is empty. +% \end{function} +% +% \subsection{Variable and constants} +% +% \begin{variable}{\c_empty_toks} +% Constant that is always empty. +% \end{variable} +% +% \begin{variable}{% +% \l_tmpa_toks | +% \l_tmpb_toks | +% \g_tmpa_toks | +% \g_tmpb_toks +% } +% Scratch register for immediate use. They are not used by conditionals +% or predicate functions. +% \end{variable} +% +% \subsubsection{Internal functions} +% +% \begin{function}{\toks_put_left_aux:w} +% Used by "\toks_put_left:Nn" and its variants. +% \end{function} +% +% \begin{function}{\def_toks:D} +% Primitive function for defining a <cs> to correspond to a token +% register should not be used by a programmer. +% \begin{texnote} +% This function was named \tn{toksdef}. +% \end{texnote} +% \end{function} +% +% \StopEventually{} +% +% \section{The code} +% +% We start by ensuring that the required packages are loaded. +% We check for \texttt{l3expan} since this a basic package that is +% essential for use of any higher-level package. +% \begin{macrocode} +%<package&check>\RequirePackage{l3chk}\par +%<package>\RequirePackage{l3expan}\par +%<*package> +% \end{macrocode} +% +% \begin{macro}{\toks_new:N} +% Allocates a new token register. This function is already defined above. +% \begin{macrocode} +\def_new:Npn \toks_new:N {} +\let:NN \toks_new:N \newtoks % nick from LaTeX for the moment +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\toks_clear:N} +% \begin{macro}{\toks_gclear:N} +% These functions clear a token register, either locally or globally. +% \begin{macrocode} +\def_new:Npn \toks_clear:N #1{#1\c_empty_toks +%<*check> + \chk_local_or_pref_global:N #1 +%</check> +} +\def_new:Npn \toks_gclear:N { +%<*check> + \pref_global_chk: +%</check> +%<-check> \pref_global:D + \toks_clear:N} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\toks_use:N} +% This function just returns the contents of a token register. +% \begin{macrocode} +\let_new:NN \toks_use:N \the_internal:D +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\toks_use_clear:N} +% \begin{macro}{\toks_use_gclear:N} +% These functions clear a token register (locally or globally) after +% returning the contents. +% +% They make sure that clearing the register does not +% interfere with following tokens. In other words, the contents of +% the register might operate on what follows in the input stream. +% A direct implementation will save one |\exp_after:NN| but for the +% sake of checking we do it this way now. +% \begin{macrocode} +\def_new:Npn \toks_use_clear:N#1{ + \exp_after:NN + \toks_clear:N + \exp_after:NN + #1 + \toks_use:N#1} +\def_new:Npn \toks_use_gclear:N{ +%<*check> + \pref_global_chk: +%</check> +%<-check> \pref_global:D + \toks_use_clear:N} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\toks_put_left:Nn} +% \begin{macro}{\toks_gput_left:Nn} +% |\toks_put_left:Nn |\zz{toks}\zv{stuff\/} adds the tokens of {\sl +% stuff\/} on the `left-side' of the token register \m{toks}. +% \begin{macrocode} +\def_new:Npn \toks_put_left:Nn #1{\exp_after:NN\toks_put_left_aux:w + \toks_use:N #1\q_stop #1} +\def_new:Npn \toks_gput_left:Nn { +%<*check> + \pref_global_chk: +%</check> +%<-check> \pref_global:D + \toks_put_left:Nn} +% \end{macrocode} +% A helper function for |\toks_put_left:Nn|. Its arguments are +% subsequently the tokens of \zv{stuff\/}, the token register +% \zz{toks} and the current contents of \zz{toks}. +% \begin{macrocode} +\def_long_new:Npn \toks_put_left_aux:w #1\q_stop #2#3{#2{#3#1} +%<*check> + \chk_local_or_pref_global:N #2 +%</check> +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\toks_put_right:Nn} +% \begin{macro}{\toks_gput_right:Nn} +% \begin{macro}{\toks_gput_right:Nx} +% These macros add a list of tokens to the right of a token register. +% \begin{macrocode} +\def_long_new:Npn \toks_put_right:Nn #1#2{#1\exp_after:NN{\toks_use:N #1#2} +%<*check> + \chk_local_or_pref_global:N #1 +%</check> +} +\def_new:Npn \toks_gput_right:Nn { +%<*check> + \pref_global_chk: +%</check> +%<-check> \pref_global:D + \toks_put_right:Nn} +% \end{macrocode} +% |\toks_gput_right:Nx| expands its (second) argument. +% \begin{macrocode} +\def_new:Npn \toks_gput_right:Nx {\exp_args:Nnx\toks_gput_right:Nn} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\toks_set:Nn} +% \begin{macro}{\toks_set:No} +% \begin{macro}{\toks_set:Nx} +% |\toks_set:Nn|\m{toks}\m{stuff} stores \m{stuff} without expansion +% in \m{toks}. |\toks_set:No| and |\toks_set:Nx| expand \m{stuff} once +% and fully. +% \begin{macrocode} +%<*check> +\def_new:Npn \toks_set:Nn #1{\chk_local:N #1#1} +%</check> +% \end{macrocode} +% If we don't check if \m{toks} is a local register then the +% |\toks_set:Nn| function has nothing to do. +% \begin{macrocode} +%<-check> \let_new:NN \toks_set:Nn\use_noop: +\def_new:Npn \toks_set:No {\exp_args:NNo \toks_set:Nn} +\def_new:Npn \toks_set:Nx {\exp_args:NNx \toks_set:Nn} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\toks_gset:Nn} +% \begin{macro}{\toks_gset:No} +% \begin{macro}{\toks_gset:Nx} +% These functions are the global variants of the above. +% \begin{macrocode} +%<*check> +\def_new:Npn \toks_gset:Nn #1{\chk_global:N #1\pref_global:D#1} +%</check> +%<-check> \let_new:NN \toks_gset:Nn\pref_global:D +\def_new:Npn \toks_gset:No {\exp_args:NNo \toks_gset:Nn} +\def_new:Npn \toks_gset:Nx {\exp_args:NNx \toks_gset:Nn} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\toks_set_eq:NN} +% \begin{macro}{\toks_gset_eq:NN} +% |\toks_set_eq:NN|\m{toks1}\m{toks2} copies the contents of \m{toks2} +% in \m{toks1}. +% \begin{macrocode} +%<*check> +\def_new:Npn\toks_set_eq:NN#1#2{ + \chk_local:N#1 + \chk_var_or_const:N#2 + #1#2} +\def_new:Npn\toks_gset_eq:NN#1#2{ + \chk_global:N#1 + \chk_var_or_const:N#2 + \pref_global:D#1#2} +%</check> +%<-check> \let_new:NN \toks_set_eq:NN \use_noop: +%<-check> \let_new:NN \toks_gset_eq:NN \pref_global:D +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\toks_empty:NTF} +% |\toks_empty:NTF|\m{toks}\m{true code}\m{false code} tests if +% a token register is empty and executes either \m{true code} or +% \m{false code}. +% \begin{macrocode} +\def_new:Npn\toks_empty:NTF#1{ + \tlp_set:No\l_testa_tlp{\toks_use:N#1} + \tlp_empty:NTF\l_testa_tlp} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\l_tmpa_toks} +% \begin{macro}{\l_tmpb_toks} +% \begin{macro}{\l_tmpc_toks} +% \begin{macro}{\g_tmpa_toks} +% \begin{macro}{\g_tmpb_toks} +% \begin{macro}{\g_tmpc_toks} +% Some scratch register \ldots +% \begin{macrocode} +\tex_toksdef:D \l_tmpa_toks = 255 +\toks_new:N \l_tmpb_toks +\toks_new:N \l_tmpc_toks +\toks_new:N \g_tmpa_toks +\toks_new:N \g_tmpb_toks +\toks_new:N \g_tmpc_toks +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\c_empty_toks} +% And here is a constant, which is a (permanently) empty token register. +% \begin{macrocode} +\toks_new:N \c_empty_toks +% \end{macrocode} +% \end{macro} +% +% Show token usage: +% \begin{macrocode} +%</package> +%<*showmemory> +\showMemUsage +%</showmemory> +% \end{macrocode} diff --git a/Master/texmf-dist/source/latex/expl3/readme.txt b/Master/texmf-dist/source/latex/expl3/readme.txt new file mode 100644 index 00000000000..ae888d040d9 --- /dev/null +++ b/Master/texmf-dist/source/latex/expl3/readme.txt @@ -0,0 +1,224 @@ + + Experimental Packages Demonstrating + A Possible LaTeX3 Programming Convention + ======================================== + + 1998/04/20 + + +OVERVIEW +-------- + +The packages in this directory implement a possible language for `low +level' programming in TeX. The syntax conventions described here are NOT +intended either for use in documents or for use in describing design +layouts in document class files. + +All aspects of these package are *experimental*. The names of the +packages, and the names of any commands that they define, may change +at any time. They are being released in this form to allow public +discussion and comment. + +Currently all the code is distributed in a format suitable for running +as LaTeX2e packages. Further documentation may be produced by processing +the .dtx files with LaTeX2e. The packages may be installed by processing +l3.ins with plain TeX or LaTeX. + +This code has be developed over time and has been used in previous +versions for prototype implementations, experiments, etc. Its internal +documentation (in the .dtx files) reflects the age of parts of it; it +often contains personal comments and it sometimes refers to parts that +not at present distributed. We kindly ask you to overlook its +deficiencies and inaccuracies --- if we had tried to clean this up it +would never have surfaced and, for the purpose of discussions and +comments, we hope its present form is adequate. + + +NOTE (docstrip version) +----------------------- + +If latex l3.ins +produces the `docstrip interactive mode' prompt: + + * First type the extension of your input file(s): * + \infileext= + +Then your version of docstrip is too old. +Quit (eg by hitting `enter' to all questions) and get a newer +docstrip.tex. It must be at least version 2.4. + +A suitable docstrip.tex may be found from `CTAN' archives such as +ftp.dante.de tex-archive/macros/latex/unpacked/docstrip.tex + +Docstrip is part of the base LaTeX distribution, so if you have +an old docstrip then your LaTeX is out of date and you may consider +getting the whole of that directory and re-installing LaTeX. +However you need to fetch only the file docstrip.tex to unpack +this expl3 distribution with your existing format. + + + +THE GUILTY PERSONS +------------------ + + Frank Mittelbach, Denys Duchier, Johannes Braams, Michael Downes, + David Carlisle, Alan Jeffrey, Chris Rowley, Rainer Schoepf + + +DISCUSSION +---------- + +Discussion concerning the approach, suggestions for improvements, changes, +additions, etc. should be addressed to the list LATEX-L. + +You can subscribe to this list by sending mail to + + listserv@urz.uni-heidelberg.de + +with the body containing + + subscribe LATEX-L <Your-First-Name> <Your-Second-Name> + + +BUGS +---- + +If you find a real bug that makes a package stop working you can +report it via the standard latexbug.tex mechanism of the LaTeX +distribution (see bugs.txt there) using the category "l3exp". +However please do *not* use this method for suggestions / comments / +improvements / etc. For this the list LATEX-L should be used instead. + +Also please don't expect these package to work with *any* code that +floats around in the LaTeX2e world. :-) + + + +MANIFEST +-------- + +The following packages are in this release: + + +l3names +======= + +Documents the general naming scheme, and gives new names to all the TeX +primitives. + +If this package is used with the option [removeoldnames] then the +original TeX primitive names (\hbox, \def, ...) are made *undefined* and +so free to be defined for other purposes if needed. Of course this +breaks almost all existing LaTeX2 code, but it may be used for testing +purposes, see test2.tex. + +l3basics +======== + +Some basic definitions that are used by the other packages. + +l3chk +===== + +Functions that check definitions. +(Comparable to LaTeX2's \newcommand/\renewcommand.) + +l3tlp +===== + +Token List Pointers. A basic LaTeX3 datatype for storing token lists. +(These are essentially macros with no arguments.) +(Package can be compiled with checking enabled.) + +l3expan +======= + +The argument expansion module. One of the main features of the language +proposed here is a systematic treatment of the handling of argument +expansion. The basic functions for preprocessing command arguments are +defined here. + +l3quark +======= + +A `quark' is a command that is defined to expand to itself. So it may +not be directly used (it would generate an infinite loop) but has many +uses as special markers within LaTeX code. + +l3seq +===== + +A module implementing the basic list and stack datatypes. + +l3prop +====== + +Property lists are the datatype for handling key/value assignments. + +l3int +===== + +Integer and fake integer registers. With eTeX/Omega becoming more and +more accessible this module is, at least in parts only of historical +significance. (Can be compiled with checking enabled) + +l3toks +====== + +TeX's token registers. (Can be compiled with checking enabled) + +l3io +==== + +Low-level input and ouput. + +l3precom +========= + +Low-level pointer-related code, with further checking and tracing. + + +===================================================================== + +Install file +============= + +l3.ins +====== + +Process with plain TeX or LaTeX2e to generate the experimental +packages. + +===================================================================== + +Test Files +========== + +Two test files show the expansion module at work. + +test1.tex +========= + +Test document showing the expansion module at work. + +test2.tex +========= + +The same test as the file test1, but this time the l3names package is +loaded with [removeoldnames]. This is useful for testing, but as it +breaks all LaTeX2 code, it is not so useful for documents. (For +example {document} would generate an error.) In this mode +\RequirePackage may be used to load further packages, as demonstrated +in this file, but any other LaTeX2 command is likely to fail. + +test3.tex +========= + +This tests the io and precomp modules. + + +===================================================================== + +--- Copyright 1998 + The LaTeX3 Project. All rights reserved --- + diff --git a/Master/texmf-dist/source/latex/expl3/test1.dmp b/Master/texmf-dist/source/latex/expl3/test1.dmp new file mode 100644 index 00000000000..ecb21f24572 --- /dev/null +++ b/Master/texmf-dist/source/latex/expl3/test1.dmp @@ -0,0 +1 @@ +\dumpLaTeXstate macro:#1->\iow_expanded_term:n {Dumping commands into (#1.dmp)}\iow_open:Nn \c_cs_dump_stream {#1.dmp}\seq_map_inline:Nn \g_cs_trace_seq {\tex_message:D {.}\iow_expanded:Nn \c_cs_dump_stream {\token_to_string:N ##1 \token_to_meaning:N ##1}}\tex_message:D { registers}\seq_map_inline:Nn \g_register_trace_seq {\tex_message:D {.}\iow_expanded:Nn \c_cs_dump_stream {\token_to_string:N ##1\the_internal:D ##1}}\tex_message:D { finished} diff --git a/Master/texmf-dist/source/latex/expl3/test2.dmp b/Master/texmf-dist/source/latex/expl3/test2.dmp new file mode 100644 index 00000000000..3a93bfcdb53 --- /dev/null +++ b/Master/texmf-dist/source/latex/expl3/test2.dmp @@ -0,0 +1,2 @@ +\dumpLaTeXstate macro:#1->\iow_expanded_term:n {Dumping commands into (#1.dmp)}\iow_open:Nn \c_cs_dump_stream {#1.dmp}\seq_map_inline:Nn \g_cs_trace_seq {\tex_message:D {.}\iow_expanded:Nn \c_cs_dump_stream {\token_to_string:N ##1 \token_to_meaning:N ##1}}\tex_message:D { registers}\seq_map_inline:Nn \g_register_trace_seq {\tex_message:D {.}\iow_expanded:Nn \c_cs_dump_stream {\token_to_string:N ##1\the_internal:D ##1}}\tex_message:D { finished} +\l_my_int42 diff --git a/Master/texmf-dist/source/latex/expl3/test3.dmp b/Master/texmf-dist/source/latex/expl3/test3.dmp new file mode 100644 index 00000000000..de4c6f395bc --- /dev/null +++ b/Master/texmf-dist/source/latex/expl3/test3.dmp @@ -0,0 +1,2 @@ +\dumpLaTeXstate macro:#1->\iow_expanded_term:n {Dumping commands into (#1.dmp)}\iow_open:Nn \c_cs_dump_stream {#1.dmp}\seq_map_inline:Nn \g_cs_trace_seq {\tex_message:D {.}\iow_expanded:Nn \c_cs_dump_stream {\token_to_string:N ##1 \token_to_meaning:N ##1}}\tex_message:D { registers}\seq_map_inline:Nn \g_register_trace_seq {\tex_message:D {.}\iow_expanded:Nn \c_cs_dump_stream {\token_to_string:N ##1\the_internal:D ##1}}\tex_message:D { finished} +\l_my_int0 diff --git a/Master/texmf-dist/source/latex/expl3/testdump.cmp b/Master/texmf-dist/source/latex/expl3/testdump.cmp new file mode 100644 index 00000000000..081751f9871 --- /dev/null +++ b/Master/texmf-dist/source/latex/expl3/testdump.cmp @@ -0,0 +1,7 @@ +\group_begin: \tex_catcode:D `\*=11\scan_stop: \CodeStart +\gdef:Npn\g*i{bar} +\gdef:Npn\l*i{foo} +\gdef:Npn\foo{somefoo} +\fint_gset:Nn\g_gen_sym_fint {1} +\fint_gset:Nn\g_ggen_sym_fint {1} +\group_end: |