diff options
author | Karl Berry <karl@freefriends.org> | 2009-06-09 23:31:15 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2009-06-09 23:31:15 +0000 |
commit | 215b9a864d5829070bdc66ba736986eb72e5143e (patch) | |
tree | fe0882c81fc4ec945cee4b512f72eaa21ea5f791 /Master/texmf-dist | |
parent | df90ec06321940c2f066b05e12f1b5ab099105da (diff) |
expl3 1407 (9jun09)
git-svn-id: svn://tug.org/texlive/trunk@13686 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist')
74 files changed, 22934 insertions, 17721 deletions
diff --git a/Master/texmf-dist/doc/latex/expl3/readme.txt b/Master/texmf-dist/doc/latex/expl3/README index 81202555eaa..67059036d41 100644 --- a/Master/texmf-dist/doc/latex/expl3/readme.txt +++ b/Master/texmf-dist/doc/latex/expl3/README @@ -1,9 +1,8 @@ - Experimental Packages Demonstrating - A Possible LaTeX3 Programming Convention - ======================================== + An Experimental LaTeX3 Programming Convention + ============================================= - 2008/08/05 + 2009/06/02 WHERE TO GET IT @@ -29,13 +28,10 @@ This API provides the foundation on which the LaTeX3 kernel and other advanced extensions are built. Special care has been taken so that they can be used within a LaTeX2e context as regular packages. -While the existing code is approaching a stable state, we cannot -guarantee that names of packages or commands they define will not -change. This is also related to the history of the code: It has been -developed over time and has been used in previous versions for -prototypes implementations, experiments, etc. It may therefore -occasionally contain references to parts that are at present not -distributed. +While expl3 is still experimental, the bundle is now regarded as +broadly stable. The syntax conventions and functions provided are now +ready for wider use. There may still be changes to some functions, but +these will be minor when compared to the scope of expl3. THE GUILTY PERSONS @@ -43,7 +39,8 @@ THE GUILTY PERSONS Frank Mittelbach, Denys Duchier, Johannes Braams, Michael Downes, David Carlisle, Alan Jeffrey, Chris Rowley, Rainer Schoepf - Javier Bezos, Morten Hoegholm, Thomas Lotze + Javier Bezos, Morten Hoegholm, Thomas Lotze, Will Robertson, + Joseph Wright DISCUSSION @@ -117,11 +114,11 @@ l3toks TeX's token registers. (Can be compiled with checking enabled) -l3tlp +l3tl ===== -Token List Pointers. A basic LaTeX3 datatype for storing token lists. -(These are essentially macros with no arguments.) The module also +Token Lists and Token List variables, a basic LaTeX3 datatype for storing +token lists. (These are essentially macros with no arguments.) The module also provides functions for arbitrary token lists. (Package can be compiled with checking enabled.) @@ -208,11 +205,10 @@ Module providing the low-level interface for cross references. This module also contains a test file which is generated along with the package. -l3messages +l3msg ===== -Module providing a new mechanism to provide longer warning and error -messages based on storing the messages in external files. +Module providing a new mechanism to provide user messages. l3calc ===== @@ -253,11 +249,21 @@ l3final.dtx This file is reserved for the last minute coding for producing a format (such as the dump instruction). +l3format.ins +============ + +Process with plain TeX or LaTeX2e to generate the experimental +format file lbase.ltx and its companion lbase.ini. +The run pdfetex --ini "*lbase.ini" to produce the experimental +format. + +===================================================================== + source3.tex =========== -Run this file with pdfLaTeX in extended mode: -pdflatex "*source3.tex" to produce the documentation. +Run this file with pdfLaTeX: +pdflatex source3 to produce the documentation. Doing this will produce three extra files (source3.ist, l3doc.cfg and l3full.cfg). The first of these is a style file for makeindex; the others or configuration files for the documentation class. @@ -269,47 +275,15 @@ After that run makeindex to produce the index, like so: makeindex -s source3.ist source3 and rerun LaTeX. -l3format.ins -============ - -Process with plain TeX or LaTeX2e to generate the experimental -format file lbase.ltx and its companion lbase.ini. -The run pdfetex --ini "*lbase.ini" to produce the experimental -format. - -===================================================================== - -Test Files -========== - -Two test files show the expansion module at work. - -test1.tex +expl3.dtx ========= -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. - -The option removeoldnames has been disabled temporarily and so this -test file is of limited use. - -test3.tex -========= - -This tests the io and precomp modules. - +This provides a single "load point" for the entire expl3 bundle. +Running pdflatex expl3.dtx will produce a general overview document +explaining the basics of expl3 programming. ===================================================================== ---- Copyright 1998 -- 2008 +--- Copyright 1998 -- 2009 The LaTeX3 Project. All rights reserved --- diff --git a/Master/texmf-dist/doc/latex/expl3/expl3.pdf b/Master/texmf-dist/doc/latex/expl3/expl3.pdf Binary files differindex 189b52ee082..0343e931674 100644 --- a/Master/texmf-dist/doc/latex/expl3/expl3.pdf +++ b/Master/texmf-dist/doc/latex/expl3/expl3.pdf diff --git a/Master/texmf-dist/doc/latex/expl3/l32eproc.pdf b/Master/texmf-dist/doc/latex/expl3/l32eproc.pdf Binary files differdeleted file mode 100644 index 2ccd85c6f1b..00000000000 --- a/Master/texmf-dist/doc/latex/expl3/l32eproc.pdf +++ /dev/null diff --git a/Master/texmf-dist/doc/latex/expl3/l3obsolete.txt b/Master/texmf-dist/doc/latex/expl3/l3obsolete.txt new file mode 100644 index 00000000000..5c1073fe333 --- /dev/null +++ b/Master/texmf-dist/doc/latex/expl3/l3obsolete.txt @@ -0,0 +1,9 @@ +l3obsolete +========== + +This file lists expl3 commands that have been removed or +replaced with respect to the version on the TeX Live 2009 disk. + +========== + +Nothing yet!
\ No newline at end of file diff --git a/Master/texmf-dist/doc/latex/expl3/l3obsolete2008.txt b/Master/texmf-dist/doc/latex/expl3/l3obsolete2008.txt new file mode 100644 index 00000000000..20b83ff0bcb --- /dev/null +++ b/Master/texmf-dist/doc/latex/expl3/l3obsolete2008.txt @@ -0,0 +1,296 @@ +l3obsolete2008 +============== + +This file lists expl3 commands that have been removed or +replaced with respect to the version on the TeX Live 2008 disk. + +========== + +\CodeStart -> \ExplSyntaxOn +\CodeStop -> \ExplSyntaxOff +\NamesStart -> \ExplSyntaxNamesOn +\NamesStop -> \ExplSyntaxNamesOff + +\cs_use:c -> \use:c +\use:cc -> \exp_args:cc + +\use_arg_i:n -> \use:n +\use_arg_i:nn -> \use_i:nn +\use_arg_i:nnn -> \use_i:nnn +\use_arg_i:nnnn -> \use_i:nnnn +\use_arg_i_ii:nn -> \use:nn + +\use_arg_i_after_else:nw -> \use_i_after_else:nw +\use_arg_i_after_fi:nw -> \use_i_after_fi:nw +\use_arg_i_after_or:nw -> \use_i_after_or:nw +\use_arg_i_after_orelse:nw -> \use_i_after_orelse:nw +\use_arg_i_delimit_by_q_nil:nw -> \use_i_delimit_by_q_nil:nw +\use_arg_i_delimit_by_q_stop:nw -> \use_i_delimit_by_q_stop:nw +\use_arg_i_delimit_by_q_recursion_stop:nw -> + \use_i_delimit_by_q_recursion_stop:nw + +\use_arg_ii:nn -> \use_ii:nn +\use_arg_ii:nnn -> \use_ii:nnn +\use_arg_ii:nnnn -> \use_ii:nnnn +\use_arg_iii:nnn -> \use_iii:nnn +\use_arg_iii:nnnn -> \use_iii:nnnn +\use_arg_iv:nnnn -> \use_iv:nnnn + +\cs_free:NTF -> \cs_if_free:NTF +\cs_free:NT -> \cs_if_free:NT +\cs_free:NF -> \cs_if_free:NF +\cs_free:cTF -> \cs_if_free:cTF +\cs_free:cT -> \cs_if_free:cT +\cs_free:cF -> \cs_if_free:cF + +\cs_really_free:cTF -> \cs_if_really_free:cTF +\cs_really_free:cT -> \cs_if_really_free:cT +\cs_really_free:cF -> \cs_if_really_free:cF + +\cs_if_eq_p:NN -> \cs_if_eq_name_p:NN +\chk_new_cs:N -> \chk_if_new_cs:N +\chk_exist_cs:N -> \chk_if_exist_cs:N +\chk_exist_cs:c -> \chk_if_exist_cs:c + +\cmd_declare:Nnn -> Undefined. Use \def:NNn instead. +\cmd_arg_list_build -> Undefined (auxiliary function used for the above). + +\tl_put_left:cx -> Undefined. Define your own, if you need it. +\tl_gput_left:cx -> Undefined. Ditto. +\tl_put_right:cc -> Undefined. Ditto. +\seq_gput_right:cc -> Undefined. Ditto. +\clist_gput_right:cc -> Undefined. Ditto. + +\token_to_string:N -> \token_to_str:N + + + + + + + +\let:NwN -> \cs_set_eq:NwN + +\def:No -> -> \cs_set_nopar:No +\gdef:No -> \cs_gset_nopar:No + + +\def:Npn -> \cs_set_nopar:Npn +\def:Npx -> \cs_set_nopar:Npx +\def:cpn -> \cs_set_nopar:cpn +\def:cpx -> \cs_set_nopar:cpx + +\def:NNn -> \cs_set_nopar:NNn +\def:NNx -> \cs_set_nopar:NNx +\def:cNn -> \cs_set_nopar:cNn +\def:cNx -> \cs_set_nopar:cNx + +\def_protected:Npn -> \cs_set_protected_nopar:Npn +\def_protected:Npx -> \cs_set_protected_nopar:Npx +\def_protected:cpn -> \cs_set_protected_nopar:cpn +\def_protected:cpx -> \cs_set_protected_nopar:cpx + +\def_protected:NNn -> \cs_set_protected_nopar:NNn +\def_protected:NNx -> \cs_set_protected_nopar:NNx +\def_protected:cNn -> \cs_set_protected_nopar:cNn +\def_protected:cNx -> \cs_set_protected_nopar:cNx + +\def_protected_long:Npn -> \cs_set_protected:Npn +\def_protected_long:Npx -> \cs_set_protected:Npx +\def_protected_long:cpn -> \cs_set_protected:cpn +\def_protected_long:cpx -> \cs_set_protected:cpx + +\def_protected_long:NNn -> \cs_set_protected:NNn +\def_protected_long:NNx -> \cs_set_protected:NNx +\def_protected_long:cNn -> \cs_set_protected:cNn +\def_protected_long:cNx -> \cs_set_protected:cNx + +\def_new:Npn -> \cs_new_nopar:Npn +\def_new:Npx -> \cs_new_nopar:Npx +\def_new:cpn -> \cs_new_nopar:cpn +\def_new:cpx -> \cs_new_nopar:cpx + +\def_new:NNn -> \cs_new_nopar:NNn +\def_new:NNx -> \cs_new_nopar:NNx +\def_new:cNn -> \cs_new_nopar:cNn +\def_new:cNx -> \cs_new_nopar:cNx + +\def_protected_new:Npn -> \cs_new_protected_nopar:Npn +\def_protected_new:Npx -> \cs_new_protected_nopar:Npx +\def_protected_new:cpn -> \cs_new_protected_nopar:cpn +\def_protected_new:cpx -> \cs_new_protected_nopar:cpx + +\def_protected_new:NNn -> \cs_new_protected_nopar:NNn +\def_protected_new:NNx -> \cs_new_protected_nopar:NNx +\def_protected_new:cNn -> \cs_new_protected_nopar:cNn +\def_protected_new:cNx -> \cs_new_protected_nopar:cNx + +\def_protected_long_new:Npn -> \cs_new_protected:Npn +\def_protected_long_new:Npx -> \cs_new_protected:Npx +\def_protected_long_new:cpn -> \cs_new_protected:cpn +\def_protected_long_new:cpx -> \cs_new_protected:cpx + +\def_protected_long_new:NNn -> \cs_new_protected:NNn +\def_protected_long_new:NNx -> \cs_new_protected:NNx +\def_protected_long_new:cNn -> \cs_new_protected:cNn +\def_protected_long_new:cNx -> \cs_new_protected:cNx + +\def_long:Npn -> \cs_set:Npn +\def_long:Npx -> \cs_set:Npx +\def_long:cpn -> \cs_set:cpn +\def_long:cpx -> \cs_set:cpx + +\def_long:NNn -> \cs_set:NNn +\def_long:NNx -> \cs_set:NNx +\def_long:cNn -> \cs_set:cNn +\def_long:cNx -> \cs_set:cNx + +\def_long_new:Npn -> \cs_new:Npn +\def_long_new:Npx -> \cs_new:Npx +\def_long_new:cpn -> \cs_new:cpn +\def_long_new:cpx -> \cs_new:cpx + +\def_long_new:NNn -> \cs_new:NNn +\def_long_new:NNx -> \cs_new:NNx +\def_long_new:cNn -> \cs_new:cNn +\def_long_new:cNx -> \cs_new:cNx + + +\gdef:Npn -> \cs_gset_nopar:Npn +\gdef:Npx -> \cs_gset_nopar:Npx +\gdef:cpn -> \cs_gset_nopar:cpn +\gdef:cpx -> \cs_gset_nopar:cpx + +\gdef:NNn -> \cs_gset_nopar:NNn +\gdef:NNx -> \cs_gset_nopar:NNx +\gdef:cNn -> \cs_gset_nopar:cNn +\gdef:cNx -> \cs_gset_nopar:cNx + +\gdef_protected:Npn -> \cs_gset_protected_nopar:Npn +\gdef_protected:Npx -> \cs_gset_protected_nopar:Npx +\gdef_protected:cpn -> \cs_gset_protected_nopar:cpn +\gdef_protected:cpx -> \cs_gset_protected_nopar:cpx + +\gdef_protected:NNn -> \cs_gset_protected_nopar:NNn +\gdef_protected:NNx -> \cs_gset_protected_nopar:NNx +\gdef_protected:cNn -> \cs_gset_protected_nopar:cNn +\gdef_protected:cNx -> \cs_gset_protected_nopar:cNx + +\gdef_protected_long:Npn -> \cs_gset_protected:Npn +\gdef_protected_long:Npx -> \cs_gset_protected:Npx +\gdef_protected_long:cpn -> \cs_gset_protected:cpn +\gdef_protected_long:cpx -> \cs_gset_protected:cpx + +\gdef_protected_long:NNn -> \cs_gset_protected:NNn +\gdef_protected_long:NNx -> \cs_gset_protected:NNx +\gdef_protected_long:cNn -> \cs_gset_protected:cNn +\gdef_protected_long:cNx -> \cs_gset_protected:cNx + +\gdef_protected_long_new:Npn -> \cs_gnew_protected:Npn +\gdef_protected_long_new:Npx -> \cs_gnew_protected:Npx +\gdef_protected_long_new:cpn -> \cs_gnew_protected:cpn +\gdef_protected_long_new:cpx -> \cs_gnew_protected:cpx + +\gdef_protected_long_new:NNn -> \cs_gnew_protected:NNn +\gdef_protected_long_new:NNx -> \cs_gnew_protected:NNx +\gdef_protected_long_new:cNn -> \cs_gnew_protected:cNn +\gdef_protected_long_new:cNx -> \cs_gnew_protected:cNx + +\gdef_long:Npn -> \cs_gset:Npn +\gdef_long:Npx -> \cs_gset:Npx +\gdef_long:cpn -> \cs_gset:cpn +\gdef_long:cpx -> \cs_gset:cpx + +\gdef_long:NNn -> \cs_gset:NNn +\gdef_long:NNx -> \cs_gset:NNx +\gdef_long:cNn -> \cs_gset:cNn +\gdef_long:cNx -> \cs_gset:cNx + +\gdef_new:Npn -> \cs_gnew_nopar:Npn +\gdef_new:Npx -> \cs_gnew_nopar:Npx +\gdef_new:cpn -> \cs_gnew_nopar:cpn +\gdef_new:cpx -> \cs_gnew_nopar:cpx + +\gdef_new:NNn -> \cs_gnew_nopar:NNn +\gdef_new:NNx -> \cs_gnew_nopar:NNx +\gdef_new:cNn -> \cs_gnew_nopar:cNn +\gdef_new:cNx -> \cs_gnew_nopar:cNx + +\gdef_protected_new:Npn -> \cs_gnew_protected_nopar:Npn +\gdef_protected_new:Npx -> \cs_gnew_protected_nopar:Npx +\gdef_protected_new:cpn -> \cs_gnew_protected_nopar:cpn +\gdef_protected_new:cpx -> \cs_gnew_protected_nopar:cpx + +\gdef_protected_new:NNn -> \cs_gnew_protected_nopar:NNn +\gdef_protected_new:NNx -> \cs_gnew_protected_nopar:NNx +\gdef_protected_new:cNn -> \cs_gnew_protected_nopar:cNn +\gdef_protected_new:cNx -> \cs_gnew_protected_nopar:cNx + +\gdef_long_new:Npn -> \cs_gnew:Npn +\gdef_long_new:Npx -> \cs_gnew:Npx +\gdef_long_new:cpn -> \cs_gnew:cpn +\gdef_long_new:cpx -> \cs_gnew:cpx + +\gdef_long_new:NNn -> \cs_gnew:NNn +\gdef_long_new:NNx -> \cs_gnew:NNx +\gdef_long_new:cNn -> \cs_gnew:cNn +\gdef_long_new:cNx -> \cs_gnew:cNx + +\let:NN -> \cs_set_eq:NN +\let:Nc -> \cs_set_eq:Nc +\let:cN -> \cs_set_eq:cN +\let:cc -> \cs_set_eq:cc + +\glet:NN -> \cs_gset_eq:NN +\glet:Nc -> \cs_gset_eq:Nc +\glet:cN -> \cs_gset_eq:cN +\glet:cc -> \cs_gset_eq:cc + +\let_new:NN -> \cs_new_eq:NN +\let_new:Nc -> \cs_new_eq:Nc +\let_new:cN -> \cs_new_eq:cN +\let_new:cc -> \cs_new_eq:cc + +\glet_new:NN -> \cs_gnew_eq:NN +\glet_new:Nc -> \cs_gnew_eq:Nc +\glet_new:cN -> \cs_gnew_eq:cN +\glet_new:cc -> \cs_gnew_eq:cc + + + + + + + +%% Copyright (C) 1990-2009 LaTeX3 project +%% +%% It may be distributed and/or modified under the conditions of the +%% LaTeX Project Public License (LPPL), either version 1.3c of this +%% license or (at your option) any later version. The latest version +%% of this license is in the file +%% +%% http://www.latex-project.org/lppl.txt +%% +%% This file is part of the ``expl3 bundle'' (The Work in LPPL) +%% and all files in that bundle must be distributed together. +%% +%% The released version of this bundle is available from CTAN. +%% +%% ----------------------------------------------------------------------- +%% +%% The development version of the bundle can be found at +%% +%% http://www.latex-project.org/svnroot/experimental/trunk/ +%% +%% for those people who are interested. +%% +%%%%%%%%%%% +%% NOTE: %% +%%%%%%%%%%% +%% +%% Snapshots taken from the repository represent work in progress and may +%% not work or may contain conflicting material! We therefore ask +%% people _not_ to put them into distributions, archives, etc. without +%% prior consultation with the LaTeX Project Team. +%% +%% -----------------------------------------------------------------------
\ No newline at end of file diff --git a/Master/texmf-dist/doc/latex/expl3/readme-dev.txt b/Master/texmf-dist/doc/latex/expl3/readme-dev.txt new file mode 100644 index 00000000000..bae4259fe22 --- /dev/null +++ b/Master/texmf-dist/doc/latex/expl3/readme-dev.txt @@ -0,0 +1,120 @@ + + The EXPL3 bundle for LaTeX3 Programming + ======================================= + +GETTING STARTED for developers +------------------------------ + +Welcome! +This is a short guide to how the expl3 bundle is set up, +and how you can get started programming with and +contributing to it. + +First, some signposts: +Email discussion list <http://news.gmane.org/gmane.comp.tex.latex.latex3> +SVN repository <http://www.latex-project.org/svnroot/experimental/trunk/> +SVN repository RRS feed <http://www.latex-project.org/latex3svn.rss> + +Those interested in receiving emails containing the diff +of every commit to the repository should ask on the discussion list. + +For more information, please look in the official README +and in the documentation expl3.pdf. + + +INSTALLATION +------------ + +When you pull down the SVN repository, you'll generally +want two things: the actual packages files so you can +use the `expl3` bundle, and the documentation. + +## Obtaining the code in the SVN repository + +Execute something like this: + + mkdir l3svn + svn checkout http://www.latex-project.org/svnroot/experimental/trunk/ l3svn + +This will give you both the xpackages and the expl3 bundle +contained within the `l3in2e/` directory, plus a few extras. +This readme only concerns the expl3 bundle. + + +## Package files + +Install `expl3` in your local texmf directory with + + make localinstall + +The installation directory is detected automatically, +and in a normal TeXLive distribution will be used +in preference to any existing `expl3` code directory. +(I.e., after the above command your regular documents +will use the new versions of the modules.) + + +## Documentation + +For an individual module, generate the documentation with + + make doc F=<module> + +For example, `make doc F=l3quark`. This will produce +`l3quark.pdf`, which includes the documentation for that +module and its implementation source code. + +To generate the complete reference documentation for +the `expl3` bundle, source3.pdf: + + make sourcedoc + +Note that source3.pdf does not include the modules' +implementation source code; therefore, source3.pdf is a +rough subset (plus index) of the complete set of typeset +module PDFs. + +To generate `source3.pdf` and the documentation for +each module, run + + make alldoc + + +HACKING +------- + +There are two main things you need to know when making +changes to the expl3 bundle. + +1. We have a regression test suite +2. Don't break it + +To make sure things are working, run + + make check + +If you change something, run that again. All working? Great! +Please send your diffs to the discussion list and we can talk +about adding your code. + +You can find more information about the test suite in + + l3in2e/testfiles/README.txt + +On a less critical level, we also have a method to check +that our documentation is somewhat self-consistent. Run + + make checkdoc + +and each module will be compiled and verified that what +is defined in the module is also documented. + +Note that it only checks what we *claim* we are defining +in the documentation; it does not literally check the code. +It will also check that each module's documentation +still compiles without errors. + + +--- Copyright 1998 -- 2009 + The LaTeX3 Project. All rights reserved --- + diff --git a/Master/texmf-dist/doc/latex/expl3/source3.pdf b/Master/texmf-dist/doc/latex/expl3/source3.pdf Binary files differindex 29d7985fe97..6cfe59cae8f 100644 --- a/Master/texmf-dist/doc/latex/expl3/source3.pdf +++ b/Master/texmf-dist/doc/latex/expl3/source3.pdf diff --git a/Master/texmf-dist/source/latex/expl3/test1.tex b/Master/texmf-dist/makeindex/expl3/l3doc.ist index d40189e37dc..542cffda9ca 100644 --- a/Master/texmf-dist/source/latex/expl3/test1.tex +++ b/Master/texmf-dist/makeindex/expl3/l3doc.ist @@ -1,5 +1,21 @@ -% \iffalse -%% File: test1 Copyright (C) 1990-2006 LaTeX3 project +%% +%% This is file `l3doc.ist', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% l3doc.dtx (with options: `docist') +%% +%% +%% EXPERIMENTAL CODE +%% +%% Do not distribute this file without also distributing the +%% source files specified above. +%% +%% Do not distribute a modified version of this file. +%% +%% +%% File: l3doc.dtx Copyright (C) 1990-2009 LaTeX3 project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this @@ -17,12 +33,12 @@ %% %% The development version of the bundle can be found at %% -%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/ +%% http://www.latex-project.org/svnroot/experimental/trunk/ %% %% for those people who are interested. %% %%%%%%%%%%% -%% NOTE: %% +%% NOTE: %% %%%%%%%%%%% %% %% Snapshots taken from the repository represent work in progress and may @@ -31,59 +47,26 @@ %% prior consultation with the LaTeX Project Team. %% %% ----------------------------------------------------------------------- +actual '=' +quote '!' +level '>' +preamble +"\n \\begin{theindex} \n \\makeatletter\\scan@allowedfalse\n" +postamble +"\n\n \\end{theindex}\n" +item_x1 "\\efill \n \\subitem " +item_x2 "\\efill \n \\subsubitem " +delim_0 "\\pfill " +delim_1 "\\pfill " +delim_2 "\\pfill " +lethead_prefix "{\\bfseries\\hfil " +lethead_suffix "\\hfil}\\nopagebreak\n" +lethead_flag 1 +heading_prefix "{\\bfseries\\hfil " +heading_suffix "\\hfil}\\nopagebreak\n" +headings_flag 1 + +page_precedence "rnaA" +%% %% -\def\next$Id: #1.tex #2 #3-#4-#5 #6 #7$#8{% - \def\fileversion{#2}% - \def\filedate{#3/#4/#5}% - \ProvidesFile{#1.tex}[#3/#4/#5 v#2 #8]% -} -\next$Id: test1.tex 573 2006-08-21 20:59:37Z morten $ - {L3 Test 1} -% \fi - -\documentclass{article} - -\tracingmacros2 -\usepackage{l3expan,l3io} - -\begin{document} - -\CodeStart - - -\def_new:Npn\test_cmd:nn#1#2{ - \iow_unexpanded_term:n{} - \iow_unexpanded_term:n{Argument~1:~#1} - \iow_unexpanded_term:n{Argument~2:~#2}} - - - -\def:Npn\a{A} -\def:Npn\b{B} - -\def:Npn\aa{\a} -\def:Npn\bb{\b} - -\exp_def_form:nnn {test_cmd}{nn}{oo} -\exp_def_form:nnn {test_cmd}{nn}{xx} -\exp_def_form:nnn {test_cmd}{nn}{cc} -\exp_def_form:nnn {test_cmd}{nn}{nx} - -\test_cmd:nn{a}{b} - -\test_cmd:nn{\a}{\b} - -\test_cmd:oo\aa\bb - -\test_cmd:xx\aa\bb - -\test_cmd:cc{a}{b} - -\test_cmd:nx{a}{\b} - -\CodeStop - -\LaTeX\ still works! - -\end{document} - +%% End of file `l3doc.ist'. diff --git a/Master/texmf-dist/source/latex/expl3/expl3.dtx b/Master/texmf-dist/source/latex/expl3/expl3.dtx new file mode 100644 index 00000000000..a22e1b53417 --- /dev/null +++ b/Master/texmf-dist/source/latex/expl3/expl3.dtx @@ -0,0 +1,970 @@ +% \iffalse +%% File: expl3.dtx Copyright (C) 1990-2009 LaTeX3 project +%% +%% It may be distributed and/or modified under the conditions of the +%% LaTeX Project Public License (LPPL), either version 1.3c of this +%% license or (at your option) any later version. The latest version +%% of this license is in the file +%% +%% http://www.latex-project.org/lppl.txt +%% +%% This file is part of the ``expl3 bundle'' (The Work in LPPL) +%% and all files in that bundle must be distributed together. +%% +%% The released version of this bundle is available from CTAN. +%% +%% ----------------------------------------------------------------------- +%% +%% The development version of the bundle can be found at +%% +%% http://www.latex-project.org/svnroot/experimental/trunk/ + +%% +%% for those people who are interested. +%% +%%%%%%%%%%% +%% NOTE: %% +%%%%%%%%%%% +%% +%% Snapshots taken from the repository represent work in progress and may +%% not work or may contain conflicting material! We therefore ask +%% people _not_ to put them into distributions, archives, etc. without +%% prior consultation with the LaTeX Project Team. +%% +%% ----------------------------------------------------------------------- +% +%<*driver|package> +\RequirePackage{l3names} +%</driver|package> +%\fi +\GetIdInfo$Id: expl3.dtx 1381 2009-06-01 20:36:02Z joseph $ + {L3 Experimental code bundle wrapper}% +%\iffalse +%<*driver> +%\fi +\ProvidesFile{\filename.\filenameext} + [\filedate\space v\fileversion\space\filedescription] +%\iffalse +\documentclass{l3doc} +\usepackage{shortvrb,hypdoc} +\MakeShortVerb{\|} +\hyphenation{para-meters para-meter} +% I have found at least 3 other hyphenations of this in various refs, +% but I did also find this, which is my personal favourite ---chris +\hyphenation{ignore ignored ignores} +\begin{document} +\DocInput{\filename.\filenameext} +\end{document} +%</driver> +% \fi +% +% \providecommand\acro[1]{\textsc{\MakeLowercase{#1}}} +% \providecommand\ie{i.e.,~} +% \providecommand\eg{e.g.,~} +% \newenvironment{arg-description}{% +% \begin{itemize}\def\makelabel##1{\hss\llap{\bfseries##1}}}{\end{itemize}} +% +% \title{The \textsf{expl3} package and philosophy\thanks{This file +% has version number \fileversion, last +% revised \filedate.}} +% \author{\Team} +% \date{\filedate} +% +% \maketitle +% +% \begin{documentation} +% +% \begin{abstract} +% +% This paper gives a brief introduction to a new set of programming +% conventions that have been designed to meet the requirements of +% implementing large scale \TeX\ macro programming projects such as +% \LaTeX. +% +% The main features of the system described are: +% \begin{itemize} +% \item classification of the macros (or, in \LaTeX{} terminology, +% commands) into \LaTeX{} functions and \LaTeX{} parameters, and also +% into modules containing related commands; +% \item a systematic naming scheme based on these +% classifications; +% \item a simple mechanism for controlling the expansion of a function's +% arguments. +% \end{itemize} +% This system is being used as the basis for +% \TeX{} programming within the \LaTeX3 project. +% Note that the language is not intended for either +% document mark-up or style specification. +% +% An earlier description of the \LaTeX3 programming language is +% available from \url{http://www.latex-project.org/papers}. +% \end{abstract} +% +% +% \section{Introduction} +% +% This paper describes the conventions for a \TeX-based programming +% language which is intended to provide a more consistent and rational +% environment for the construction of large scale systems, such as +% \LaTeX, using \TeX{} macros. +% +% Variants of this language have been in use by The \LaTeX3 Project Team +% since around 1990 but the syntax specification to be outlined here +% should \emph{not} be considered final. This is an experimental +% language thus many aspects, such as the syntax conventions and naming +% schemes, may (and probably will) change as more experience is gained +% with using the language in practice. +% +% The next section shows where this language fits into a complete +% \TeX-based document processing system. We then describe the major +% features of the syntactic structure of command names, including the +% argument specification syntax used in function names. +% +% The practical ideas behind this argument syntax will be explained, +% together with the semantics of the expansion control mechanism and the +% interface used to define variant forms of functions. The paper also +% discusses some advantages of the syntax for parameter names. +% +% As we shall demonstrate, the use of a structured naming scheme and of +% variant forms for functions greatly improves the readability of the +% code and hence also its reliability. Moreover, experience has shown +% that the longer command names which result from the new syntax do not +% make the process of \emph{writing} code significantly harder +% (especially when using a reasonably intelligent editor). +% +% The final section gives some details of our plans to distribute parts +% of this system. Although the paper is now a little dated, more general +% information concerning the work of the \LaTeX3 Project can be found +% in Ref.~\cite{tub:MR97-1}. +% +% +% \section{Languages and interfaces} +% \label{sec:langs} +% +% It is possible to identify several distinct languages related to the +% various interfaces that are needed in a \TeX-based document processing +% system. This section looks at those we consider most important for +% the \LaTeX3 system. +% +% \begin{description} +% \item[Document mark-up] This comprises those commands (often called tags) +% that are to embedded in the document (the |.tex| file). +% +% It is generally accepted that such mark-up should be essentially +% \emph{declarative}. +% It may be traditional \TeX-based mark-up such as +% \LaTeXe, as described in~\cite{A-W:LLa94} and~\cite{A-W:GMS94}, +% or a mark-up language defined via \acro{SGML} or \acro{XML}. +% +% One problem with more traditional \TeX\ coding conventions (as +% described in~\cite{A-W:K-TB}) is that the names and syntax of \TeX's +% primitive formatting commands are ingeniously designed to be +% `natural' when used directly by the author as document mark-up or in +% macros. Ironically, the ubiquity (and widely recognised +% superiority) of logical mark-up has meant that such explicit +% formatting commands are almost never needed in documents or in +% author-defined macros. Thus they are used almost exclusively by +% \TeX{} programmers to define higher-level commands; and their +% idiosyncratic syntax is not at all popular with this community. +% Moreover, many of them have names that could be very useful as +% document mark-up tags were they not pre-empted as primitives (\eg +% |\box| or |\special|). +% +% \item[Designer interface] This relates a (human) typographic +% designer's specification for a document to a program that `formats +% the document'. It should ideally use a declarative language that +% facilitates expression of the relationship and spacing rules specified +% for the layout of the various document elements. +% +% This language is not embedded in document text and it will be very +% different in form to the document mark-up language. For +% \acro{SGML}-based systems the \acro{DSSSL} language may come to play +% this role. For \LaTeX, this level was almost completely missing +% from \LaTeX2.09; \LaTeXe\ made some improvements in this area but it +% is still the case that implementing a design specification in +% \LaTeX\ requires far more `low-level' coding than is acceptable. +% \item[Programmer interface] +% This language is the implementation +% language within which the basic typesetting functionality is +% implemented, building upon the primitives of \TeX\ (or a +% successor program). +% It may also be used to implement the previous +% two languages `within' \TeX, as in the current \LaTeX\ system. +% \end{description} +% +% Only the last of these three interfaces is covered by this paper, +% which describes a system aimed at providing a suitable basis for +% coding large scale projects in \TeX{} (but this should not preclude its +% use for smaller projects). Its main distinguishing features are +% summarised here. +% +% \begin{itemize} +% \item A consistent naming scheme for all commands, including \TeX\ +% primitives. +% \item The classification of commands as \LaTeX{} functions or \LaTeX{} +% parameters, and also their division into modules according to their +% functionality. +% \item A simple mechanism for controlling argument expansion. +% \item Provision of a set of core \LaTeX{} functions that is sufficient +% for handling programming constructs such as queues, sets, +% stacks, property lists. +% \item A \TeX{} programming environment in which, for example, all +% white space is ignored. +% \end{itemize} +% +% \section{The naming scheme} +% \label{sec:scheme} +% +% The naming conventions for this programming language distinguish +% between \textit{functions} and \textit{parameters}. Functions can have +% arguments and they are executed. Parameters can be assigned values +% and they are used in arguments to functions; they are not directly +% executed but are manipulated by mutator and accessor functions. +% Functions and parameters with a related functionality (for example +% accessing counters, or manipulating token-lists, etc.)\ are collected +% together into a +% \textit{module}. +% +% +% Note that all these terms are only \LaTeX{} terminology and are not, +% for example, intended to indicate that the commands have these +% properties when considered in the context of basic \TeX{} or in any +% more general programming context. +% +% +% \subsection{Examples} +% \label{sec:ex} +% +% Before giving the details of the naming scheme, here are a few typical +% examples to indicate the flavour of the scheme; first some parameter +% names. +% \begin{quote} +% |\l_tmpa_box| is a local parameter (hence the~|l_| prefix) +% corresponding to a box register.\\ +% |\g_tmpa_int| is a global parameter (hence the~|g_| prefix) +% corresponding to an integer register (\ie a \TeX{} count register).\\ +% |\c_empty_toks| +% is the constant~(|c_|) token register parameter that is for ever empty. +% \end{quote} +% Now here is an example of a typical function name. +% +% |\seq_push:Nn| is the function which puts the token list specified by +% its second argument onto the stack specified by its first argument. +% The different natures of the two arguments are indicated by the~|:Nn| +% suffix. The first argument must be a single token which `names' +% the stack parameter: such single-token arguments are denoted~|N|. +% The second argument is a normal \TeX\ `undelimited argument', which +% may either be a single token or a balanced, brace-delimited token +% list (which we shall here call a \textit{braced token list}): the~|n| +% denotes such a `normal' argument form. The name of the function +% indicates it belongs to the |seq| module. +% +%^^A |\seq_push:cn| would be similar to the above, but in this case the~|c| +%^^A means that the stack-name is specified in the first argument by a +%^^A token list that expands, using |\csname...|, to a control sequence that +%^^A is the \emph{name} of the stack parameter. +%^^A +%^^A \noindent +%^^A The names of these two functions also indicate that they are in the +%^^A module called |seq|. +% +% +% \subsection{Formal syntax of the conventions} +% \label{sec:namesyn} +% +% We shall now look in more detail at the syntax of these names.\\ +% The syntax of parameter names is as follows: +% \begin{quote} +% |\|\m{access}|_|\m{module}|_|\m{description}|_|\m{type} +% \end{quote} +% The syntax of function names is as follows: +% \begin{quote} +% |\|\m{module}|_|\m{description}|:|\m{arg-spec} +% \end{quote} +% +% +% \subsection{Modules and descriptions} +% \label{sec:modules} +% +% The syntax of all names contains +% \begin{quote} +% \m{module} and \m{description}: +% \end{quote} +% these both give information about the command. +% +% A \textit{module} is a collection of +% closely related functions and parameters. +% Typical module names include~|int| for integer parameters +% and related functions,~|seq| for sequences and~|box| for boxes. +% +% Packages providing new programming functionality will add new modules +% as needed; the programmer can choose any unused name, consisting +% of letters only, for a module. +% +% The \textit{description} gives more detailed information about the +% function or parameter, and provides a unique name for it. It should +% consist of letters and, possibly,~|_|~characters. +% +% As a semi-formalized concept the letter |g| is sometimes used to +% prefix certain parts of the \m{description} +% to mark the function as ``globally acting'', e.g., |\int_set:Nn| is +% a local operation while |\int_gset:Nn| is a global operation. This +% of course goes hand in hand with when to use |\l_| and |\g_| +% variable prefixes. +% +% \subsection{Parameters: access and type} +% \label{sec:parms} +% +% The \m{access} part of the name describes how the parameter can be +% accessed. Parameters are primarily classified as local, global or +% constant (there are further, more technical, classes). This +% \textit{access} type appears as a code at the beginning of the name; +% the codes used include: +% \begin{arg-description} +% \item[c] +% constants (global parameters whose value should not be changed); +% \item[g] +% parameters whose value should only be set globally; +% \item[l] +% parameters whose value should only be set locally. +% \end{arg-description} +% +% The \m{type} will normally (except when introducing a new data-type) +% be in the list of available \textit{data-types}; these include the +% primitive \TeX\ data-types, such as the various registers, but to +% these will be added data-types built within the \LaTeX{} programming +% system. +% +% Here are some typical data-type names: +% \begin{description} +% \item[int] integer-valued count register; +% \item[tl] token list variables: placeholders for token lists; +% \item[toks] token register; +% \item[box] box register; +% \item[skip] `rubber' lengths; +% \item[dim] `rigid' lengths; +% \item[num] A `fake' integer type using only macros. Useful for +% setting up allocation routines; +% \item[seq] `sequence': a data-type used to implement lists +% (with access at both ends) and stacks; +% \item[prop] property list; +% \item[clist] comma separated list; +% \item[stream] an input or output stream (for reading from or writing to, respectively); +% \item[bool] either true or false. +% \end{description} +% When the \m{type} and \m{module} are identical (as often happens in +% the more basic modules) the \m{module} part is often omitted for +% aesthetic reasons. +% +% +% \subsection{Functions: basic argument specifications} +% \label{sec:args} +% +% Function names end with an \m{arg-spec} after a colon. This +% gives an indication of the types of argument that a function takes, +% and provides a convenient method of naming similar functions that +% differ only in their argument forms (see the next section for +% examples). +% +% The \m{arg-spec} consists of a (possibly empty) list of characters, +% each denoting one argument of the function. It is important to +% understand that `argument' here refers to the effective argument of +% the \LaTeX{} function, not to an argument at the \TeX-level. Indeed, +% the top level \TeX\ macro that has this name typically has no +% arguments. This is an extension of the existing \LaTeX\ convention +% where one says that |\section| has an optional argument and a +% mandatory argument, whereas the \TeX\ macro |\section| actually has +% zero parameters at the \TeX\ level, it merely calls an internal \LaTeX\ +% command which in turn calls others that look ahead for star forms and +% optional arguments. +% +% All functions have a base form with arguments using one of the +% following argument specifiers. +% \begin{arg-description} +% \item[n] Unexpanded token or braced token list.\\ +% This is a standard \TeX\ undelimited macro argument. +% \item[N] Single token (unlike~|n|, the argument must \emph{not} be +% surrounded by braces).\\ +% A typical example of a command taking an~|N| +% argument is~|\cs_set|, in which the command being defined must be +% unbraced. +% \item[p] Primitive \TeX\ parameter specification.\\ +% This can be something simple like~|#1#2#3|, but may use arbitrary +% delimited argument syntax such as: |#1,#2\q_stop#3|. This is used +% when defining functions. +% \item[T,F] +% These are special cases of~|n| arguments, used for the +% true and false code in conditional commands. +% \end{arg-description} +% There are two other specifiers with more general meanings: +% \begin{arg-description} +% \item[D] This means: \textbf{Do not +% use}. This special case is used +% for \TeX\ primitives and other commands that are provided for use +% only while bootstrapping the \LaTeX\ kernel. If the \TeX\ primitive +% needs to be used in other contexts it will be given an alternative, +% more appropriate, name with a useful argument specification. The +% argument syntax of these is often weird, in the sense described next. +% \item[w] This means that the argument syntax is `weird' in that it +% does not follow any standard rule. It is used for functions with +% arguments that take non standard forms: examples are \TeX-level +% delimited arguments and the boolean tests needed after certain +% primitive |\if|\ldots\ commands. +% \end{arg-description} +% +% 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. +% +% +% +% +% \section{Expansion control} +% \label{sec:exp} +% +% Let's take a look at some typical operations one might want to +% perform. Suppose we maintain a stack of open files and we use the +% stack |\g_io_file_name_seq| to keep track of them (|io| is the +% input-output file module). The basic operation +% here is to push a name onto this stack which could be done by the +% operation +% \begin{quote} +% "\seq_gpush:Nn" \\ +% " \g_io_file_name_seq" \\ +% " {#1}" +% \end{quote} +% where |#1| is the filename. In other words, this operation would +% push the file name as is. +% +% However, we might face a situation where +% the filename is stored in a register of some sort, say +% |\l_io_curr_file_tl|. In this case we want to retrieve the value of +% the register. If we simply use +% \begin{quote} +% "\seq_gpush:Nn" \\ +% " \g_io_file_name_seq" \\ +% " \l_io_curr_file_tl " +% \end{quote} +% we will not get the value of the register pushed onto the stack, +% only the register name itself. Instead a suitable number of +% "\exp_after:wN" would be necessary (together with extra braces) to +% change the order of execution, i.e. +% \begin{quote} +% "\exp_after:wN" \\ +% " \seq_gpush:Nn" \\ +% "\exp_after:wN" \\ +% " \g_io_file_name_seq" \\ +% "\exp_after:wN" \\ +% " {\l_io_curr_file_tl}" +% \end{quote} +% +% The above example is probably the simplest case but already shows +% how the code changes to something difficult to +% understand. Furthermore there is an assumption in this: That the +% storage bin reveals its contents after exactly one +% expansion. Relying on this means that you cannot do proper checking +% plus you have to know exactly how a storage bin acts in order to get +% the correct number of expansions. 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:NV" \\ +% " \g_io_file_name_seq " \\ +% " \l_io_curr_file_tl " +% \end{quote} +% to achieve the desired effect. Here the "V" is for ``retrieve the +% value of the register'' (the second argument) before passing it to +% the base function. +% +% +% The following letters can be used to denote special treatment of +% arguments before passing it to the base function: +% \begin{description} +% \item[c] Character string used as a command name.\\ The argument (a +% token or braced token list) must, when fully expanded, produce a +% sequence of characters which is then used to construct a command +% name (via~|\csname|, |\endcsname|). This command name is the +% single token that is passed to the function as the argument. Hence +% \begin{quote} +% "\seq_gpush:cV {g_file_name_stack} \l_tmpa_tl" +% \end{quote} +% is equivalent to +% \begin{quote} +% "\seq_gpush:NV \g_file_name_stack \l_tmpa_tl". +% \end{quote} +% +% \item[V] Value of a register.\\ +% This means that the register in question is returned, be it an +% integer, a length type register, a macro storage register or +% similar. The value is returned to the function as a braced token list. +% +% \item[v] Value of a register, constructed from a character string +% used as a command name.\\ +% This is a combination of |c| and |V| which first constructs a +% control sequence from the argument and then returns the value. +% +% \item[x] Fully-expanded token or braced token list.\\ +% This means that the argument is expanded as in the replacement +% text of an~|\edef|, and the expansion is passed to the function as +% a braced token list. This means that expansion takes place until +% only unexpandable tokens are left. +% +% \item[o] One-level-expanded token or braced token list.\\ +% This means that the argument is expanded one level, as by +% |\expandafter|, and the expansion is passed to the function as a braced +% token list. Note that if the original argument is a braced +% token list then only the first token in that list is expanded. +% +% \item[f] Almost the same as the |x| type except here the token list +% is expanded fully until the first unexpandable token is found and +% the rest is left unchanged. Note that if this function finds a +% space at the beginning of the argument it will gobble it and not +% expand the next argument. +% \end{description} +% +% +% \subsection{Simpler means better} +% \label{sec;simpler} +% +% Anyone who programs in \TeX\ is frustratingly familiar with the +% problem of arranging that arguments to functions are suitably expanded +% before the function is called. To illustrate how expansion control +% can bring instant relief to this problem we shall consider two +% examples copied from \texttt{latex.ltx}. +% +% \begin{verbatim} +% \global\expandafter\let +% \csname\cf@encoding \string#1\expandafter\endcsname +% \csname ?\string#1\endcsname +% \end{verbatim} +% This first piece of code is in essence simply a global |\let| whose +% two arguments firstly have to be constructed before |\let| is +% executed. The |#1| is a control sequence name such as +% |\textcurrency|. The token to be defined is obtained by +% concatenating the characters of the current font encoding stored in +% |\cf@encoding|, which has to be fully expanded, and the name of the +% symbol. The second token is the same except it uses the default +% encoding |?|. The result is a mess of interwoven |\expandafter| +% and |\csname| beloved of all \TeX\ programmers, and the code is +% essentially unreadable. +% +% Using the conventions and functionality outlined here, the task would +% be achieved with code such as this: +% \begin{verbatim} +% \cs_gset_eq:cc {\cf@encoding \string #1} +% {?\string #1} +% \end{verbatim} +% The command |\cs_gset_eq:cc| is a global~|\let| that generates +% command names out of both of its arguments before making the +% definition. This produces code that is far more readable and more +% likely to be correct first time. +% +% Here is the second example. +% \begin{verbatim} +% \expandafter +% \in@ +% \csname sym#3% +% \expandafter +% \endcsname +% \expandafter +% {% +% \group@list}% +% \end{verbatim} +% This piece of code is part of the definition of another function. It +% first produces two things: a token list, by expanding |\group@list| once; +% and a token whose name comes from~`|sym#3|'. Then the function~|\in@| +% is called and this tests if its first argument occurs in the token list +% of its second argument. +% +% Again we can improve enormously on the code. First we shall rename +% the function~|\in@| according to our conventions. A function such as +% this but taking two normal `\texttt{n}' arguments might reasonably be +% named |\seq_test_in:Nn|; thus the variant function we need will be +% defined with the appropriate argument types and its name will be +% |\seq_test_in:cV|. Now this code fragment will be simply: +% \begin{verbatim} +% \seq_test_in:cV {sym#3} \l_group_seq +% \end{verbatim} +% Note that, in addition to the lack of |\expandafter|, the space after +% the~|}| will be silently ignored since all white space is ignored in +% this programming environment. +% +% +% \subsection{New functions from old} +% \label{sec:newfunc} +% +% For many common functions the \LaTeX3 kernel will provide variants +% with a range of argument forms, and similarly it is expected that +% extension packages providing new functions will make them available in +% the all the commonly needed forms. +% +% However, there will be occasions where it is necessary to construct a +% new such variant form; therefore the expansion module provides a +% straightforward mechanism for the creation of functions with any +% required argument type, starting from a function that takes `normal' +% \TeX\ undelimited arguments. +% +% To illustrate this let us suppose you have a `base function' +% |\demo_cmd:nnn| that takes three normal arguments, and that you need +% to construct the variant |\demo_cmd:cnx|, for which the first argument +% is used to construct the \emph{name} of a command, whilst the third +% argument must be fully expanded before being passed to +% |\demo_cmd:nnn|. +% To produce the variant form from the base form, simply use this: +% \begin{verbatim} +% \cs_generate_variant:Nn \demo_cmd:nnn {cnx} +% \end{verbatim} +% This defines the variant form so that you can then write, for example: +% \begin{verbatim} +% \demo_cmd:cnx {abc} {pq} {\rst \xyz } +% \end{verbatim} +% rather than \ldots\ well, something like this! +% \begin{verbatim} +% \def \tempa {{pq}}% +% \edef \tempb {\rst \xyz}% +% \expandafter +% \demo@cmd:nnn +% \csname abc% +% \expandafter +% \expandafter +% \expandafter +% \endcsname +% \expandafter +% \tempa +% \expandafter +% {% +% \tempb +% }% +% \end{verbatim} +% +% Another example: you may wish to declare a function +% |\demo_cmd_b:xcxcx|, a variant of an existing function +% |\demo_cmd_b:nnnnn|, that fully +% expands arguments 1,~3 and~5, and produces commands to pass as +% arguments 2 and~4 using~|\csname|. +% The definition you need is simply +% \begin{verbatim} +% \cs_generate_variant:Nn +% \demo_cmd_b:nnnnn {xcxcx} +% \end{verbatim} +% +% This extension mechanism is written so that if the same new form of +% some existing command is implemented by two extension packages then the +% two definitions will be identical and thus no conflict will occur. +% +% +% \section{Parameter assignments and accessor functions} +% \label{sec:access} +% +% \subsection{Checking assignments} +% \label{sec:check} +% +% One of the advantages of having a consistent scheme is that the system +% can provide more extensive error-checking and debugging facilities. +% For example, an accessor function that makes a \emph{global} +% assignment of a value to a parameter can check that it is not passed +% the name of a \emph{local} parameter as that argument: it does this by +% checking that the name starts with~|\g_|. +% +% Such checking is probably too slow for normal use, but the code can +% have hooks built in that allow a format to be made in which all +% functions perform this kind of check. +% +% A typical section of the source^^A +% \footnote{This code uses the \textsf{docstrip} +% system described in~\cite{A-W:GMS94}, Section~14.3.} +% for such code might look like this +% (recall that all white space is ignored): +% +% \begin{verbatim} +% %<*!check> +% \cs_new_eq:NN +% \toks_gset:Nn \tex_global:D +% %</!check> +% %<*check> +% \cs_new_nopar:Npn +% \toks_gset:Nn #1 +% { +% \chk_global:N #1 +% \tex_global:D #1 +% } +% %</check> +% \end{verbatim} +% In the above code the function |\toks_gset:Nn| takes a single +% token~(|N|) specifying a token register, and globally sets it to the +% value passed in the second argument. +% +% A typical use of it would be: +% \begin{verbatim} +% \toks_gset:Nn \g_xxx_toks {<some value>} +% \end{verbatim} +% In the normal definition, |\toks_gset:Nn| can be simply~|\let| +% to~|\global| because the primitive \TeX{} token register does not +% require any explicit assignment function: +% this is done by the |%<*!check>| code above. +% +% The alternative definition first checks that the argument +% passed as~|#1| is the name of a global parameter and raises an error +% if it is not. It does this by taking apart the command name passed +% as~|#1| and checking that it starts~|\g_|. +% +% \subsection{Consistency} +% \label{sec:cons} +% +% The primitive \TeX\ syntax for register assignments has a very minimal +% syntax and, apart from box functions, there are no explicit functions +% for assigning values to these registers. +% +% This makes it impossible to implement alternative data-types with a +% syntax that is both consistent and at all similar to the syntax for +% the primitives; moreover, it encourages a coding style that is very +% error prone. +% +% As in the |\toks_gset:Nn| example given above, all \LaTeX\ data-types +% are provided with explicit functions for assignment and for use, even +% when these have essentially empty definitions. This allows for better +% error-checking as described above; it also allows the construction of +% further data-types with a similar interface, even when the +% implementation of the associated functions is very complex. +% +% For example, the `fake-integer' (\texttt{num}) data-type mentioned +% above will appear at the \LaTeX{} programming level to be exactly like +% the data-type based on primitive count registers; however, internally +% it makes no use of count registers. Typical functions in this module +% are illustrated here. +% +% \begin{verbatim} +% \num_new:N \l_tmpa_num +% \end{verbatim} +% This declares the local parameter |\l_example_num| as a fake-counter. +% +% \begin{verbatim} +% \num_add:Nn \l_example_num \c_thirty_two +% \end{verbatim} +% This increments the value of this fake-counter by 32. +% +% +% \section{The experimental distribution} +% \label{sec:dist} +% +% The initial implementations of a \LaTeX\ programming language using +% this kind of syntax remain unreleased (and not completely functional); +% they partly pre-date \LaTeXe! The planned distribution will provide a +% subset of the functionality of those implementations, in the form of +% packages to be used on top of \LaTeXe. +% +% The intention is to allow experienced \TeX\ programmers to experiment +% with the system and to comment on the interface. This means that +% \textbf{\itshape the interface will change}. No part of this system, +% including the name of anything, should be relied upon as being +% available in a later release. Please do \emph{experiment} with these +% packages, but do \emph{not} use them for code that you expect to keep +% unchanged over a long period. +% +% In view of the intended experimental use for this distribution we +% shall, in the first instance, produce only a few modules for use with +% \LaTeXe. These will set up the conventions and the basic functionality +% of, for example, the expansion mechanism; they will also implement some +% of the basic programming constructs, such as token-lists and sequences. +% They are intended only to give a flavour of the code: the full \LaTeX3 +% kernel will provide a very rich set of programming constructs so that +% packages can efficiently share code, in contrast with the situation in +% the current \LaTeX\ where every large package must implement its own +% version of queues, stacks, etc., as necessary. +% +% At time of writing the \textsf{expl3} bundle consists of the +% following modules. +% +% This distribution will also contain the \LaTeX\ source for the latest +% version of this document, a docstrip install file and three small test +% files. +% +% \begin{description} +% \providecommand\explpkg[2]{\item[#1]#2} +% \explpkg{l3basics}{ +% This contains the basic definition modules used +% by the other packages. +% } +% \explpkg{l3box}{ +% Primitives for dealing with boxes. +% } +% \explpkg{l3calc}{ +% A re-implementation of the \LaTeXe\ package \pkg{calc} package in +% \pkg{expl3} that provides extended methods for numeric and dimensional +% calculations and assignments. +% } +% \explpkg{l3chk}{ +% A module that provides functionality comparable to +% \LaTeX's \cmd{\newcommand} and \cmd{\renewcommand}, and also the +% extra level of +% checking for ensure internal consistency in the code. +% } +% \explpkg{l3clist}{ +% Methods for manipulating comma-separated token lists. +% } +% \explpkg{l3expan}{ +% This is the argument expansion module discussed above. +% } +% \explpkg{l3int}{ +% This implements the integer data-type \texttt{int}. +% } +% \explpkg{l3io}{ +% A module providing low level input and output functions. +% } +% \explpkg{l3keyval}{ +% A re-implementation of the \LaTeXe\ package \pkg{keyval}; +% provides low-level macros for dealing with lists of the form +% \texttt{\{ key1=val1 , key2=val2 \}}. +% } +% \explpkg{l3messages/l3msg}{ +% Communicating with the user. +% } +% \explpkg{l3names}{ +% This sets up the basic naming scheme and renames all +% the \TeX\ primitives. If it is loaded with the option +% \texttt{[removeoldnames]} then the old primitive names such as~\cmd{\box} +% become \emph{undefined} and are thus available for user +% definition. Caution: use of this option will certainly break existing +% \TeX\ code! +% } +% \explpkg{l3num}{ +% This implements the `fake integer' datatype \texttt{num}. +% } +% \explpkg{l3precom}{ +% A `pre-compilation' module that provides functions dealing with pointer +% creation and handling, and using external files to record the state of the current +% definitions. +% } +% \explpkg{l3prg}{ +% Program control structures such as boolean data type |bool|, generic +% do-while loops, case-switches, sorting routines and stepwise loops. +% } +% \explpkg{l3prop}{ +% This implements the data-type for `property lists' that are used, in +% particular, for storing key/value pairs. +% } +% \explpkg{l3quark}{ +% A `quark' is a command that is defined to expand to +% itself! Therefore they must never be expanded as this will generate +% infinite recursion; they do however have many uses, \eg as +% special markers and delimiters within code. +% } +% \explpkg{l3seq}{ +% This implements data-types such as queues and stacks. +% } +% \explpkg{l3skip}{ +% Implements the `rubber length' datatype \texttt{skip} and the +% `rigid length' datatype |dim|. +% } +% \explpkg{l3tl}{ +% This implements a basic data-type, called a \textit{token-list +% variable} (|tl var.|), used for storing named token lists: these are +% essentially \TeX{} macros with no arguments. +% } +% \explpkg{l3token}{ +% Analysing token lists and token streams, including peeking ahead to +% see what's coming next and inspecting tokens to detect which kind +% they are. +% } +% \explpkg{l3toks}{ +% A data-type corresponding to \TeX's primitive token registers. +% } +% \explpkg{l3xref}{ +% Data structure for low-level document cross-referencing. This +% provided the foundation for Heiko Oberdiek's \pkg{zref} package. +% } +% \end{description} +% +% \begin{thebibliography}{1} +% +% \bibitem{A-W:K-TB} +% Donald E Knuth +% \newblock {\em The {\TeX}book}. +% \newblock Addison-Wesley, Reading, Massachusetts, 1984. +% +% \bibitem{A-W:GMS94} +% Goossens, Mittelbach and Samarin. +% \newblock {\em The {\LaTeX} Companion}. +% \newblock Addison-Wesley, Reading, Massachusetts, 1994. +% +% \bibitem{A-W:LLa94} +% Leslie Lamport. +% \newblock {\em {\LaTeX:} A Document Preparation System}. +% \newblock Addison-Wesley, Reading, Massachusetts, second edition, 1994. +% +% \bibitem{tub:MR97-1} +% Frank Mittelbach and Chris Rowley. +% \newblock `The {\LaTeX3} Project'. +% \newblock {\em {TUG}boat}, +% Vol.\,18, No.\,3, pp.\,195--198, 1997. +% +% \end{thebibliography} +% +% \end{documentation} +% +% \begin{implementation} +% +% \subsection{\pkg{expl3} implementation} +% +% Well, it's not complicated |:)| +% +%<*package> +% \begin{macrocode} +\ProvidesExplPackage + {\filename}{\filedate}{\fileversion}{\filedescription} +% \end{macrocode} +% +% We already loaded \pkg{l3names} at the beginning of the \acro{dtx} file. +% +% The \pkg{l3chk} package is omitted since it is only used for conditional +% processing with full error-checking turned on. Most users will generally +% not need to do this, and we haven't set it up yet, anyway. +% +% Fundamentals: +% \begin{macrocode} +\RequirePackage{ + l3basics, + l3expan, + l3tl, + l3num, + l3intexpr, + l3quark, + l3seq, + l3toks, + l3int, + l3prg, + l3clist, + l3token, + l3io, + l3prop, + l3msg, + l3skip, +} +% \end{macrocode} +% All the rest: +% \begin{macrocode} +\RequirePackage{ + l3box, + l3keyval, + l3precom, + l3calc, + l3xref, + l3file +} +% \end{macrocode} +%</package> +% +% \end{implementation} +% +% \endinput diff --git a/Master/texmf-dist/source/latex/expl3/expl3.tex b/Master/texmf-dist/source/latex/expl3/expl3.tex deleted file mode 100644 index 8d9e1880667..00000000000 --- a/Master/texmf-dist/source/latex/expl3/expl3.tex +++ /dev/null @@ -1,753 +0,0 @@ -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% based on version for the TUGboat proceedings -% Copyright 1997--98 David Carlisle, Chris Rowley, Frank Mittelbach -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% $Id: expl3.tex 246 2004-11-11 08:20:37Z mittelba $ -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\documentclass{article} - -\usepackage{shortvrb} -\MakeShortVerb{\|} - -% A couple of \provide.. so document runs with -% both ltugproc and ltxguide classes -% -\providecommand \m [1]{$\langle$\textit{#1}$\rangle$} -%\providecommand \netaddress {\date} -\providecommand \acro [1]{\textsc{\MakeLowercase{#1}}} -\providecommand \ie {i.e.,~} -\providecommand \eg {e.g.,~} - -\hyphenation{para-meters para-meter} -% I have found at least 3 other hyphenations of this in various refs, -% but I did also find this, which is my personal favourite ---chris - -\hyphenation{ignore ignored ignores} - -\begin{document} - -\title{The \LaTeX3 Programming Language---\\ -a proposed system for \TeX\ macro programming} - - -\author{\copyright~David Carlisle, Chris Rowley and\\ Frank Mittelbach\\ -\LaTeX3 project\\ -\texttt{latex-l@urz.uni-heidelberg.de}} - - -\maketitle - -\begin{abstract} - -This paper gives s brief introduction to a new set of programming -conventions that have been designed to meet the requirements of -implementing large scale \TeX\ macro programming projects such as -\LaTeX. - -The main features of the system described are: -\begin{itemize} -\item classification of the macros (or, in \LaTeX{} terminology, - commands) into \LaTeX{} functions and \LaTeX{} parameters, and also - into modules containing related commands; -\item a systematic naming scheme based on these - classifications; -\item a simple mechanism for controlling the expansion of a function's -arguments. -\end{itemize} -A system such as this is being used experimentally as the basis for -\TeX{} programming within the \LaTeX3 project. -Note that the language is not intended for either -document mark-up or style specification. - -This paper is based on a talk given by David Carlisle in San -Francisco, July 1997, but it describes the work of several people: -principally - Frank Mittelbach and - Denys Duchier, -together with - Johannes Braams, - David Carlisle, - Michael Downes, - Alan Jeffrey, - Chris Rowley and - Rainer Sch\"opf. -\end{abstract} - -\vspace{4pt} - - -\section{Introduction} - -This paper describes the conventions for a \TeX-based programming -language which is intended to provide a more consistent and rational -environment for the construction of large scale systems, such as -\LaTeX, using \TeX{} macros. - -Variants of this language have been in use by The \LaTeX3 Project Team -since around 1990 but the syntax specification to be outlined here -should \emph{not} be considered final. This is an experimental -language thus many aspects, such as the syntax conventions and naming -schemes, may (and probably will) change as more experience is gained -with using the language in practice. - -The next section shows where this language fits into a complete -\TeX-based document processing system. We then describe the major -features of the syntactic structure of command names, including the -argument specification syntax used in function names. - -The practical ideas behind this argument syntax will be explained, -together with the semantics of the expansion control mechanism and the -interface used to define variant forms of functions. The paper also -discusses some advantages of the syntax for parameter names. - -As we shall demonstrate, the use of a structured naming scheme and of -variant forms for functions greatly improves the readability of the -code and hence also its reliability. Moreover, experience has shown -that the longer command names which result from the new syntax do not -make the process of \emph{writing} code significantly harder -(especially when using a reasonably intelligent editor). - -The final section gives some details of our plans to distribute parts -of this system during the next year. -More general information concerning the work of the \LaTeX3 Project -can be found in~\cite{tub:MR98-1}. - - -\section{Languages and interfaces} -\label{sec:langs} - -It is possible to identify several distinct languages related to the -various interfaces that are needed in a \TeX-based document processing -system. This section looks at those we consider most important for -the \LaTeX3 system. - -\begin{description} -\item[Document mark-up] This comprises those commands (often called tags) - that are to embedded in the document (the |.tex| file). - - It is generally accepted that such mark-up should be essentially - \emph{declarative}. - It may be traditional \TeX-based mark-up such as - \LaTeXe, as described in~\cite{A-W:LLa94} and~\cite{A-W:GMS94}, - or a mark-up language defined via \acro{SGML} or \acro{XML}. - - One problem with more traditional \TeX\ coding conventions (as - described in~\cite{A-W:K-TB}) is that the names and syntax of \TeX's - primitive formatting commands are ingeniously designed to be - `natural' when used directly by the author as document mark-up or in - macros. Ironically, the ubiquity (and widely recognised - superiority) of logical mark-up has meant that such explicit - formatting commands are almost never needed in documents or in - author-defined macros. Thus they are used almost exclusively by - \TeX{} programmers to define higher-level commands; and their - idiosyncratic syntax is not at all popular with this community. - Moreover, many of them have names that could be very useful as - document mark-up tags were they not pre-empted as primitives (\eg - |\box| or |\special|). - -\item[Designer interface] This relates a (human) typographic - designer's specification for a document to a program that `formats - the document'. It should ideally use a declarative language that - facilitates expression of the relationship and spacing rules specified - for the layout of the various document elements. - - This language is not embedded in document text and it will be very - different in form to the document mark-up language. For - \acro{SGML}-based systems the \acro{DSSSL} language may come to play - this role. For \LaTeX, this level was almost completely missing - from \LaTeX2.09; \LaTeXe\ made some improvements in this area but it - is still the case that implementing a design specification in - \LaTeX\ requires far more `low-level' coding than is acceptable. -\item[Programmer interface] - This language is the implementation - language within which the basic typesetting functionality is - implemented, building upon the primitives of \TeX\ (or a - successor program). - It may also be used to implement the previous - two languages `within' \TeX, as in the current \LaTeX\ system. -\end{description} - -Only the last of these three interfaces is covered by this paper, -which describes a system aimed at providing a suitable basis for -coding large scale projects in \TeX{} (but this should not preclude its -use for smaller projects). Its main distinguishing features are -summarised here. - -\begin{itemize} -\item A consistent naming scheme for all commands, including \TeX\ - primitives. -\item The classification of commands as \LaTeX{} functions or \LaTeX{} - parameters, and also their division into modules according to their - functionality. -\item A simple mechanism for controlling argument expansion. -\item Provision of a set of core \LaTeX{} functions that is sufficient - for handling programming constructs such as queues, sets, - stacks, property lists. -\item A \TeX{} programming environment in which, for example, all - white space is ignored. -\end{itemize} - -\section{The naming scheme} -\label{sec:scheme} - -The naming conventions for this programming language distinguish -between \textit{functions} and \textit{parameters}. Functions can have -arguments and they are executed. Parameters can be assigned values -and they are used in arguments to functions; they are not directly -executed but are manipulated by mutator and accessor functions. -Functions and parameters with a related functionality (for example -accessing counters, or manipulating token-lists, etc.)\ are collected -together into a -\textit{module}. - - -Note that all these terms are only \LaTeX{} terminology and are not, -for example, intended to indicate that the commands have these -properties when considered in the context of basic \TeX{} or in any -more general programming context. - - -\subsection{Examples} -\label{sec:ex} - -Before giving the details of the naming scheme, here are a few typical -examples to indicate the flavour of the scheme; first some parameter -names. -\begin{quote} -|\l_tmpa_box| is a local parameter (hence the~|l_| prefix) -corresponding to a box register.\\ -|\g_tmpa_int| is a global parameter (hence the~|g_| prefix) -corresponding to an integer register (\ie a \TeX{} count register).\\ -|\c_empty_toks| -is the constant~(|c_|) token register parameter that is for ever empty. -\end{quote} -Now here is an example of a typical function name. - -|\seq_push:Nn| is the function which puts the token list specified by -its second argument onto the stack specified by its first argument. -The different natures of the two arguments are indicated by the~|:Nn| -suffix. The first argument must be a single token which `names' -the stack parameter: such single-token arguments are denoted~|N|. -The second argument is a normal \TeX\ `undelimited argument', which -may either be a single token or a balanced, brace-delimited token -list (which we shall here call a \textit{braced token list}): the~|n| -denotes such a `normal' argument form. - -|\seq_push:cn| would be similar to the above, but in this case the~|c| -means that the stack-name is specified in the first argument by a -token list that expands, using |\csname...|, to a control sequence that -is the \emph{name} of the stack parameter. - -\noindent -The names of these two functions also indicate that they are in the -module called |seq|. - - -\subsection{Formal syntax of the conventions} -\label{sec:namesyn} - -We shall now look in more detail at the syntax of these names.\\ -The syntax of parameter names is as follows: - \begin{quote} - |\|\m{access}|_|\m{module}|_|\m{description}|_|\m{type} - \end{quote} -The syntax of function names is as follows: - \begin{quote} - |\|\m{module}|_|\m{description}|:|\m{arg-spec} - \end{quote} - - -\subsection{Modules and descriptions} -\label{sec:modules} - -The syntax of all names contains -\begin{quote} - \m{module} and \m{description}: -\end{quote} -these both give information about the command. - -A \textit{module} is a collection of -closely related functions and parameters. -Typical module names include~|int| for integer parameters -and related functions,~|seq| for sequences and~|box| for boxes. - -Packages providing new programming functionality will add new modules -as needed; the programmer can choose any unused name, consisting -of letters only, for a module. - -The \textit{description} gives more detailed information about the -function or parameter, and provides a unique name for it. It should -consist of letters and, possibly,~|_|~characters. - -\subsection{Parameters: access and type} -\label{sec:parms} - -The \m{access} part of the name describes how the parameter can be -accessed. Parameters are primarily classified as local, global or -constant (there are further, more technical, classes). This -\textit{access} type appears as a code at the beginning of the name; -the codes used include: -\begin{itemize} -\item[\bf c] - constants (global parameters whose value should not be changed); -\item[\bf g] - parameters whose value should only be set globally; -\item[\bf l] - parameters whose value should only be set locally. -\end{itemize} - -The \m{type} will normally (except when introducing a new data-type) -be in the list of available \textit{data-types}; these include the -primitive \TeX\ data-types, such as the various registers, but to -these will be added data-types built within the \LaTeX{} programming -system. - -Here are some typical data-type names: -\begin{description} -\item[int] integer-valued count register; -\item[toks] token register; -\item[box] box register; -\item[fint] `Fake-integer': (or fake-counter) a data type created to - avoid problems with the limited number of available count registers - in (standard) \TeX; -\item[seq] `sequence': a data-type used to implement lists - (with access at both ends) and stacks; -\item[plist] property list -\end{description} -When the \m{type} and \m{module} are identical (as often happens in -the more basic modules) the \m{module} part is often omitted for -aesthetic reasons. - - -\subsection{Functions: argument specifications} -\label{sec:args} - - Function names end with an \m{arg-spec} after a colon. This - gives an indication of the types of argument that a function takes, - and provides a convenient method of naming similar functions that - differ only in their argument forms (see the next section for - examples). - - The \m{arg-spec} consists of a (possibly empty) list of characters, - each denoting one argument of the function. It is important to - understand that `argument' here refers to the effective argument of - the \LaTeX{} function, not to an argument at the \TeX-level. Indeed, - the top level \TeX\ macro that has this name typically has no - arguments. This is an extension of the existing \LaTeX\ convention - where one says that |\section| has an optional argument and a - mandatory argument, whereas the \TeX\ macro |\section| actually has - zero parameters at the \TeX\ level, it merely calls an internal \LaTeX\ - command which in turn calls others that look ahead for star forms and - optional arguments. - -The list of possible argument specifiers includes the following. -\begin{itemize} -\item[\bf n] Unexpanded token or braced token list.\\ - This is a standard \TeX\ undelimited macro argument. -\item[\bf o] One-level-expanded token or braced token list.\\ - This means that the argument is expanded one level, as by - |\expandafter|, and the expansion is passed to the function as a braced - token list. Note that if the original argument is a braced - token list then only the first token in that list is expanded. -\item[\bf x] Fully-expanded token or braced token list.\\ - This means that the argument is expanded as in the replacement text of - an~|\edef|, and the expansion is passed to the function as a - braced token list. -\item[\bf c] Character string used as a command name.\\ The argument (a - token or braced token list) must, when fully expanded, produce a - sequence of characters which is then used to construct a command - name (via~|\csname|, |\endcsname|). This command name is the single - token that is passed to the function as the argument. -\item[\bf N] Single token (unlike~|n|, the argument must \emph{not} be - surrounded by braces).\\ - A typical example of a command taking an~|N| - argument is~|\def|, in which the command being defined must be - unbraced. - \item[\bf O] One-level-expanded single token (unbraced).\\ - As for~|o|, the one-level expansion is passed (as a - braced token list) to the function. - \item[\bf X] Fully-expanded single token (unbraced).\\ - As for~|x|, the full expansion is passed (as a - braced token list) to the function. - \item[\bf C] Character string used as a command name - then one-level expanded.\\ - The form of the argument is exactly as for~|c|, but the - resulting token is then expanded one level (as for~|O|), and - the expansion is passed to the function as a braced token list. - \item[\bf p] Primitive \TeX\ parameter specification.\\ - This can be something simple like~|#1#2#3|, but may use arbitrary - delimited argument syntax such as: |#1,#2\q_stop#3|. - \item[\bf T,F\hspace{-10pt}] - \hspace{10pt}% - These are special cases of~|n| arguments, used for the - true and false code in conditional commands. -\end{itemize} -There are two other specifiers with more general meanings: -\begin{itemize} -\item[\bf D] This means: \textbf{Do not use}. This special case is used - for \TeX\ primitives and other commands that are provided for use - only while bootstrapping the \LaTeX\ kernel. If the \TeX\ primitive - needs to be used in other contexts it will be given an alternative, - more appropriate, name with a useful argument specification. The - argument syntax of these is often weird, in the sense described next. - \item[\bf w] This means that the argument syntax is `weird' in that it - does not follow any standard rule. It is used for functions with - arguments that take non standard forms: examples are \TeX-level - delimited arguments and the boolean tests needed after certain - primitive |\if|\ldots\ commands. -\end{itemize} - - -\section{Expansion control} -\label{sec:exp} - -\subsection{Simpler means better} -\label{sec;simpler} - -Anyone who programs in \TeX\ is frustratingly familiar with the -problem of arranging that arguments to functions are suitably expanded -before the function is called. To illustrate how expansion control -can bring instant relief to this problem we shall consider two -examples copied from \texttt{latex.ltx}. - -\begin{verbatim} - \global - \expandafter - \expandafter - \expandafter - \let - \expandafter - \reserved@a - \csname \curr@fontshape \endcsname -\end{verbatim} -This first piece of code is in essence simply a -global |\let|. However, the token to be defined is obtained by -expanding |\reserved@a| one level; and, worse, the token to which it -is to be let is obtained by fully expanding |\curr@fontshape| and then -using the characters produced by that expansion to construct a command -name. The result is a mess of interwoven |\expandafter| and~|\csname| -beloved of all \TeX\ programmers, and the code is essentially -unreadable. - -Using the conventions and functionality outlined here, the task would -be achieved with code such as this: -\begin{verbatim} - \glet:Oc \g_reserved_a_tlp - \l_current_font_shape_tlp -\end{verbatim} -The command |\glet:Oc| is a global~|\let| that expands its -first argument once, and generates a command name out of its second -argument, before making the definition. This produces code that -is far more readable and more likely to be correct first time. - -Here is the second example. -\begin{verbatim} - \expandafter - \in@ - \csname sym#3% - \expandafter - \endcsname - \expandafter - {% - \group@list}% -\end{verbatim} -This piece of code is part of the definition of another function. It -first produces two things: a token list, by expanding |\group@list| once; -and a token whose name comes from~`|sym#3|'. Then the function~|\in@| -is called and this tests if its first argument occurs in the token list -of its second argument. - -Again we can improve enormously on the code. First we shall rename -the function~|\in@| according to our conventions. A function such as -this but taking two normal `\texttt{n}' arguments might reasonably be -named |\seq_test_in:nn|; thus the variant function we need will be -defined with the appropriate argument types and its name will be -|\seq_test_in:cO|. Now this code fragment will be simply: -\begin{verbatim} - \seq_test_in:cO {sym#3} \l_group_seq -\end{verbatim} -Note that, in addition to the lack of |\expandafter|, the space after -the~|}| will be silently ignored since all white space is ignored in -this programming environment. - - -\subsection{New functions from old} -\label{sec:newfunc} - -For many common functions the \LaTeX3 kernel will provide variants -with a range of argument forms, and similarly it is expected that -extension packages providing new functions will make them available in -the all the commonly needed forms. - -However, there will be occasions where it is necessary to construct a -new such variant form; therefore the expansion module provides a -straightforward mechanism for the creation of functions with any -required argument type, starting from a function that takes `normal' -\TeX\ undelimited arguments. - -To illustrate this let us suppose you have a `base function' -|\demo_cmd:nnn| that takes three normal arguments, and that you need -to construct the variant |\demo_cmd:cnx|, for which the first argument -is used to construct the \emph{name} of a command, whilst the third -argument must be fully expanded before being passed to -|\demo_cmd:nnn|. -To produce the variant form from the base form, simply use this: -\begin{verbatim} - \exp_def_form:nnn {demo_cmd} {nnn} {cnx} -\end{verbatim} -This defines the variant form so that you can then write, for example: -\begin{verbatim} - \demo_cmd:cnx {abc} {pq} {\rst \xyz } -\end{verbatim} -rather than \ldots\ well, something like this! -\begin{verbatim} - \def \tempa {{pq}}% - \edef \tempb {\rst \xyz}% - \expandafter - \demo@cmd - \csname abc% - \expandafter - \expandafter - \expandafter - \endcsname - \expandafter - \tempa - \expandafter - {% - \tempb - }% -\end{verbatim} - -Another example: you may wish to declare a function -|\demo_cmd_b:xcxcx|, a variant of an existing function -|\demo_cmd_b:nnnnn|, that fully -expands arguments 1,~3 and~5, and produces commands to pass as -arguments 2 and~4 using~|\csname|. -The definition you need is simply -\begin{verbatim} - \exp_def_form:nnn - {demo_cmd_b} {nnnnn} {xcxcx} -\end{verbatim} - -This extension mechanism is written so that if the same new form of -some existing command is implemented by two extension packages then the -two definitions will be identical and thus no conflict will occur. - - -\section{Parameter assignments and accessor functions} -\label{sec:access} - -\subsection{Checking assignments} -\label{sec:check} - -One of the advantages of having a consistent scheme is that the system -can provide more extensive error-checking and debugging facilities. -For example, an accessor function that makes a \emph{global} -assignment of a value to a parameter can check that it is not passed -the name of a \emph{local} parameter as that argument: it does this by -checking that the name starts with~|\g_|. - -Such checking is probably too slow for normal use, but the code can -have hooks built in that allow a format to be made in which all -functions perform this kind of check. - -A typical section of the source% -\footnote{This code uses the \textsf{docstrip} -system described in~\cite{A-W:GMS94}, Section~14.3.} -for such code might look like this -(recall that all white space is ignored): - -\begin{verbatim} - %<*!check> - \let_new:NN - \toks_gset:Nn \tex_global:D - %</!check> - %<*check> - \def_new:Npn - \toks_gset:Nn #1 - { - \chk_global:N #1 - \tex_global:D #1 - } - %</check> -\end{verbatim} -In the above code the function |\toks_gset:Nn| takes a single -token~(|N|) specifying a token register, and globally sets it to the -value passed in the second argument. - -A typical use of it would be: -\begin{verbatim} - \toks_gset \g_xxx_toks {<some value>} -\end{verbatim} -In the normal definition, |\toks_gset| can be simply~|\let| -to~|\global| because the primitive \TeX{} token register does not -require any explicit assignment function: -this is done by the |%<*!check>| code above. - -The alternative definition first checks that the argument -passed as~|#1| is the name of a global parameter and raises an error -if it is not. It does this by taking apart the command name passed -as~|#1| and checking that it starts~|\g_|. - -\subsection{Consistency} -\label{sec:cons} - -The primitive \TeX\ syntax for register assignments has a very minimal -syntax and, apart from box functions, there are no explicit functions -for assigning values to these registers. - -This makes it impossible to implement alternative data-types with a -syntax that is both consistent and at all similar to the syntax for -the primitives; moreover, it encourages a coding style that is very -error prone. - -As in the |\toks_gset:Nn| example given above, all \LaTeX\ data-types -are provided with explicit functions for assignment and for use, even -when these have essentially empty definitions. This allows for better -error-checking as described above; it also allows the construction of -further data-types with a similar interface, even when the -implementation of the associated functions is very complex. - -For example, the `fake-counter' (\texttt{fint}) data-type mentioned -above will appear at the \LaTeX{} programming level to be exactly like -the data-type based on primitive count registers; however, internally -it makes no use of count registers. Typical functions in this module -are illustrated here. - -\begin{verbatim} -\fint_new:N \l_tmpa_fint -\end{verbatim} -This declares the local parameter |\l_example_fint| as a fake-counter. - -\begin{verbatim} -\fint_add:Nn \l_example_fint \c_thirty_two -\end{verbatim} -This increments the value of this fake-counter by 32. - - -\section{The experimental distribution} -\label{sec:dist} - -The initial implementations of a \LaTeX\ programming language using -this kind of syntax remain unreleased (and not completely functional); -they partly pre-date \LaTeXe! The planned distribution will provide a -subset of the functionality of those implementations, in the form of -packages to be used on top of \LaTeXe. - -The intention is to allow experienced \TeX\ programmers to experiment -with the system and to comment on the interface. This means that -\textbf{\itshape the interface will change}. No part of this system, -including the name of anything, should be relied upon as being -available in a later release. Please do \emph{experiment} with these -packages, but do \emph{not} use them for code that you expect to keep -unchanged over a long period. - -In view of the intended experimental use for this distribution we -shall, in the first instance, produce only a few modules for use with -\LaTeXe. These will set up the conventions and the basic functionality -of, for example, the expansion mechanism; they will also implement some -of the basic programming constructs, such as token-lists and sequences. -They are intended only to give a flavour of the code: the full \LaTeX3 -kernel will provide a very rich set of programming constructs so that -packages can efficiently share code, in contrast with the situation in -the current \LaTeX\ where every large package must implement its own -version of queues, stacks, etc., as necessary. - -In the first release of this experimental system at least the -following modules will be distributed. -\begin{description} -\item[l3names] This sets up the basic naming scheme and renames all -the \TeX\ primitives. If it is loaded with the option -\texttt{[removeoldnames]} then the old primitive names such as~|\box| -become \emph{undefined} and are thus available for user -definition. Caution: use of this option will certainly break existing -\TeX\ code! - -\item [l3basics] -This contains the basic definition modules used -by the other packages. - -\item[l3chk] A module that provides functionality comparable to -\LaTeX's |\newcommand| and |\renewcommand|, and also the extra level of -checking described above in section~\ref{sec:check}. - -\item[l3tlp] -This implements a basic data-type, called a \textit{token-list -pointer}, used for storing named token lists: these are essentially -\TeX{} macros with no arguments. - -\item[l3expan] This is the argument expansion module discussed above. - -\item[l3quark] A `quark' is a command that is defined to expand to -itself! Therefore they must never be expanded as this will generate -infinite recursion; they do however have many uses, \eg as -special markers and delimiters within code. - -\item[l3seq] -This implements data-types such as queues and stacks. - -\item[l3prop] -This implements the data-type for `property lists' that are used, in -particular, for storing key/value pairs. - -\item[l3int] -This implements the integer and `fake integer' data-types. - -\item[l3toks] -A data-type corresponding to \TeX's primitive token registers. - -\item[l3io] -A module providing low level input and output functions. - -\item[l3precom] -A `pre-compilation' module that provides functions dealing with pointer -creation and handling, and using external files to record the state of the current -definitions. -\end{description} -This distribution will also contain the \LaTeX\ source for the latest -version of this document, a docstrip install file and three small test -files. - - -In later releases we plan to add further modules and a full-fledged -example of the use of the new language: a proto-type implementation -for the ideas described in the article `Language Information in -Structured Documents: A Model for Mark-up and -Rendering'~\cite{tub:MR98-2}. - -\begin{thebibliography}{1} - -\bibitem{A-W:K-TB} -Donald E Knuth -\newblock {\em The {\TeX}book}. -\newblock Addison-Wesley, Reading, Massachusetts, 1984. - -\bibitem{A-W:GMS94} -Goossens, Mittelbach and Samarin. -\newblock {\em The {\LaTeX} Companion}. -\newblock Addison-Wesley, Reading, Massachusetts, 1994. - -\bibitem{A-W:LLa94} -Leslie Lamport. -\newblock {\em {\LaTeX:} A Document Preparation System}. -\newblock Addison-Wesley, Reading, Massachusetts, second edition, 1994. - -\bibitem{tub:MR98-1} -Frank Mittelbach and Chris Rowley. -\newblock The {\LaTeX3} Project. -\newblock {\em {TUG}boat}, ????? ??? 1998. - -\bibitem{tub:MR98-2} -Frank Mittelbach and Chris Rowley. -\newblock Language Information in -Structured Documents: A Model for Mark-up and Rendering. -\newblock {\em {TUG}boat}, ????? ??? 1998. - -\end{thebibliography} - -\end{document} - - - - - diff --git a/Master/texmf-dist/source/latex/expl3/l3.ins b/Master/texmf-dist/source/latex/expl3/l3.ins index 14ac72c8532..9280d68eac5 100644 --- a/Master/texmf-dist/source/latex/expl3/l3.ins +++ b/Master/texmf-dist/source/latex/expl3/l3.ins @@ -1,107 +1,118 @@ - -\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 clists. -\generate{\file{l3clist.sty}{\from{l3clist.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 fake integer macros. -\generate{\file{l3num.sty}{\from{l3num.dtx}{package,trace}}} - -%% LaTeX3 skip registers. -\generate{\file{l3skip.sty}{\from{l3skip.dtx}{package,trace}}} - - -%% LaTeX3 precompilation -\generate{\file{l3precom.sty}{\from{l3precom.dtx}{package,precompile,trace}}} - -%% LaTeX3 I/O module. -\generate{\file{l3io.sty}{\from{l3io.dtx}{package,trace}}} - -%% LaTeX3 program control structures (loops, booleans, ...) -\generate{\file{l3prg.sty}{\from{l3prg.dtx}{package}}} - -%% LaTeX3 box module -\generate{\file{l3box.sty}{\from{l3box.dtx}{package}}} - -%% LaTeX3 messages -\generate{\file{l3messages.sty}{\from{l3messages.dtx}{package}}} - -%% LaTeX3 tokens -\generate{\file{l3token.sty}{\from{l3token.dtx}{package}}} - -%% LaTeX3 cross references -\generate{\file{l3xref.sty}{\from{l3xref.dtx}{package}}} -\generate{\file{l3xref-test.tex}{\from{l3xref.dtx}{testfile}}} - -%% LaTeX3 calc module -\generate{\file{l3calc.sty}{\from{l3calc.dtx}{package}}} - -%% LaTeX3 keyval module -\generate{\file{l3keyval.sty}{\from{l3keyval.dtx}{package}}} - - -\endbatchfile +
+\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
+
+% wrapper package for the expl3 bundle
+\generate{\file{expl3.sty}{\from{expl3.dtx}{package}}}
+
+
+% 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}}}
+
+
+%% token lists
+\generate{\file{l3tl.sty}{\from{l3tl.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 clists.
+\generate{\file{l3clist.sty}{\from{l3clist.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 fake integer macros.
+\generate{\file{l3num.sty}{\from{l3num.dtx}{package,trace}}}
+
+%% LaTeX3 integer expressions.
+\generate{\file{l3intexpr.sty}{\from{l3intexpr.dtx}{package,trace}}}
+
+
+%% LaTeX3 skip registers.
+\generate{\file{l3skip.sty}{\from{l3skip.dtx}{package,trace}}}
+
+
+%% LaTeX3 precompilation
+\generate{\file{l3precom.sty}{\from{l3precom.dtx}{package,precompile,trace}}}
+
+%% LaTeX3 I/O module.
+\generate{\file{l3io.sty}{\from{l3io.dtx}{package,trace}}}
+
+%% LaTeX3 program control structures (loops, booleans, ...)
+\generate{\file{l3prg.sty}{\from{l3prg.dtx}{package}}}
+
+%% LaTeX3 box module
+\generate{\file{l3box.sty}{\from{l3box.dtx}{package}}}
+
+%% LaTeX3 messages
+\generate{\file{l3msg.sty}{\from{l3msg.dtx}{package}}}
+
+%% LaTeX3 tokens
+\generate{\file{l3token.sty}{\from{l3token.dtx}{package}}}
+
+%% LaTeX3 cross references
+\generate{\file{l3xref.sty}{\from{l3xref.dtx}{package}}}
+%%\generate{\file{l3xref-test.tex}{\from{l3xref.dtx}{testfile}}}
+
+%% LaTeX3 calc module
+\generate{\file{l3calc.sty}{\from{l3calc.dtx}{package}}}
+
+%% LaTeX3 keyval module
+\generate{\file{l3keyval.sty}{\from{l3keyval.dtx}{package}}}
+
+%% LaTeX3 file loading
+\generate{\file{l3file.sty}{\from{l3file.dtx}{package}}}
+
+
+\endbatchfile
diff --git a/Master/texmf-dist/source/latex/expl3/l32eproc.tex b/Master/texmf-dist/source/latex/expl3/l32eproc.tex deleted file mode 100644 index d560c0c2338..00000000000 --- a/Master/texmf-dist/source/latex/expl3/l32eproc.tex +++ /dev/null @@ -1,523 +0,0 @@ -\documentclass - {ltugproc} -% {ltxguide} - -\usepackage{shortvrb} -\MakeShortVerb{\|} -\setlength\hfuzz{10pt} - -% A couple of \provide.. so document runs with -% both ltugproc and ltxguide classes -% -\providecommand\m[1]{$\langle$\textit{#1}$\rangle$} -\providecommand\netaddress{\date} -\providecommand\acro[1]{\textsc{\MakeLowercase{#1}}} - -\begin{document} -\title{The \LaTeX3 Programming Language\\ -A syntax proposal for \TeX\ macro programming} - - -\author{The \LaTeX3 Project} -\netaddress{latex-l@urz.uni-heidelberg.de} - - - -\begin{abstract} -This paper proposes a new set of programming conventions suitable for -implementing large scale \TeX\ programming projects such as \LaTeX. -(This syntax is not suitable for either document -markup, or as a style specification language.) - -The main features include a systematic naming scheme for all commands, -and a systematic mechanism for controlling the expansion of arguments -to functions. - -The syntax is under consideration as a basis for programming within -the \LaTeX3 project. - -This paper is based on a talk given by David -Carlisle but describes the work of several people, principally: - Frank Mittelbach, - Denys Duchier, - Rainer Sch\"opf, - Chris Rowley, - Michael Downes, - Johannes Braams, - David Carlisle and - Alan Jeffrey. -\end{abstract} - -\maketitle - - -\section{Introduction} -This paper describes a \TeX\ based language which is intended to -provide a more consistent and rational programming environment for the -construction of large scale \TeX\ macro projects such as \LaTeX. - -Variants of this language have been in use within the \LaTeX3 project -since around 1990 but the syntax specification to be outlined here -should \emph{not} be considered final. This is an experimental -language, and the syntax and command names may (and probably will) -change as more experience is gained with using the language in -practice. - -\section{Programming Interface levels for \LaTeX} - -One may identify several distinct languages that one might want to see -in a \TeX\ based system. This paper will \emph{only} be concerned with -the last of these three. - -\begin{description} -\item[Document Markup] This language consists of the commands that are - to be embedded in the document instance. It is generally accepted - that such a language should be essentially \emph{declarative}. - One might consider a traditional \TeX\ based markup such as the - \LaTeX2 markup as described in \cite{A-W:LLa94}, or alternatively one - might consider an \acro{SGML} based markup. - - One problem with more traditional \TeX\ coding conventions is that - the command names and syntax of the \TeX\ primitives are designed to - have a `natural' syntax when used directly by the author as document - markup. In fact one almost never uses the primitives in this - way, rather they are just used to define higher level commands. - -\item[Designer's Interface] In order to easily translate a (human) - designer's design specification into a program that accepts the - document instance one would ideally like to have a declarative - language that allows the relationships and spacing rules of the - various document elements to be easily expressed. As this language - is not embedded within the document text, it may take a rather - different form to the markup language described above. For - \acro{SGML} based systems one may consider the \acro{DSSSL} language - as playing this role. For \LaTeX2, then this level was essentially - missing in \LaTeX2.09. \LaTeXe\ made some improvements in this area - but it is still the case that implementing a design specification in - \LaTeX\ requires more `low level' coding than would be desired. -\item[Programmer's Interface] - This language, the subject of this paper, is the implementation - language in which the basic typesetting functionality is - implemented, building upon the primitives supplied by \TeX\ (or a - successor program). It may also be used to implement the previous - two languages `within' \TeX, as in the current \LaTeX\ system. -\end{description} - - -\section{Programming language: Main Features} - -The language outlined in this paper aims to provide a suitable -base for coding large (and small) scale projects in \TeX. -Its main distinguishing features are the following. -\begin{itemize} -\item Consistent naming scheme for all functions, including \TeX\ - primitives. -\item Standard mechanisms for controlling argument expansion. -\item Provision of sufficiently rich set of core functions for - handling programming constructs such as: - sequences, sets, stacks, property lists, etc. -\item White space ignored. -\end{itemize} - -\section{Naming Scheme} - -The name space is divided between \emph{Functions} and -\emph{Parameters}. Functions (normally) take arguments and are -executed, Parameters are usually passed as arguments to functions. -They are not directly executed, but accessed though accessor functions. - -Functions and parameters associated with a similar function (for -example accessing counters, or manipulating lists, etc.) are arranged -into \emph{modules}. Before giving the details of the form of the -command names, we give a few examples. - -|\l_tmpa_box| is a local parameter (hence the |l_| prefix) -corresponding to a box register. - -|\g_tmpa_box| is a global parameter (hence the |g_| prefix) -corresponding to a box register. - -|\c_one| is the constant (|c_|) parameter with value one. - -|\cnt_add:Nn| is the function which adds the value specified by -its second argument to the count register specified by its first -argument. The different natures of the two arguments are indicated by -the |:Nn| suffix. The first argument must be a single token specifying -the name of the count parameter. Such single token arguments are -denoted |N|. The second argument is a normal \TeX\ `non-delimited -argument' which may either be a single token, or a brace delimited -token list containing an expression for the value to be added. -The |n| denotes such `normal' argument forms. - -|\cnt_add:cn| is similar to the above, but in this case the the -counter is specified in the first argument by a list of tokens that -expands to the \emph{name} of the count parameter. - -These examples should give the basic flavour of the scheme. Parameters -are classified into local, global or constant (there are further more -technical cases in addition to these three) and this access type is -shown by |\l_|, |\g_| or |\c_|. Functions are arranged by -\emph{module} (The |cnt| module in these cases) with a descriptive -name followed by an indication of the type of argument to be passed. - -In more detail the specification of the names is as follows. - -Functions have the following general syntax: - \begin{quote} - |\|\m{module}|_|\m{description}|:|\m{arg-spec} - \end{quote} - The programmer can chose an arbitrary \m{module} name (consisting - of letters only) a group of functions with related functionality are - then all given names prefixed by this module name. The \m{description} - is a description of the functionality of the function, and should - consist of letters, and possibly |_| characters. \m{arg-spec} - describes the type of arguments as will be described below. - -The syntax of parameters is as follows: - \begin{quote} - |\|\m{access}|_|\m{module}|_|\m{description}|_|\m{type} - \end{quote} - \m{access} describes how the parameter can be accessed. The - principal access types are \emph{constant}, \emph{local} or - \emph{global}. As described below, some special access types relate - to \TeX\ primitive parameters. The meanings of \m{module} and - \m{description} in the parameter syntax is the same as that for - functions. Finally \m{type} should denote the type of parameter, - such as |cnt| for count registers, etc. - - - -Typical \m{module} names in the kernel include |cnt| for integer count -related functions, |seq| for functions relating to sequences, |box|, -etc. Normally additional packages adding new functionality would add -new modules as needed. - -The \m{description} is an arbitrary name for the function or -parameter, consisting of letters, or the |_| character. - -Function names always end with an \m{arg-spec} after a final colon. -This gives an indication of the types of argument that a function -takes, and provides a convenient method of naming similar functions -that just differ by their argument forms, as will be explained below. - -The \m{arg-spec} consists of a (possibly empty) list of characters -each denoting one argument that the function takes. It is important to -note that `argument' here refers to the conceptual argument of the -function. -The top level \TeX\ macro that has this name typically has no -arguments. This is similar to the existing \LaTeX\ convention where one -says that |\section| has an optional argument and a mandatory -argument, whereas the \TeX\ macro |\section| actually takes no -parameters at the \TeX\ level, it merely calls some standard \LaTeX\ -internal functions which look ahead for star forms and optional -arguments. The list of possible argument specifiers includes: -\begin{description} -\item[n] Unexpanded token (or token-list if in braces). In other words - this is a standard \TeX\ undelimited macro argument. -\item[o] One time expanded token or token-list. In the case of a token - list then only the first token in the list is expanded. -\item[x] Fully expanded token or token-list. Typically this means that - the argument is expanded in the style of |\edef| (|\def:Npx|) before - being passed to the function. -\item[c] A character string used (after expansion) as a command name. - The argument (a token or braced token list) should expand to a - sequence of characters which is then used to construct a command - name (via |\csname|, |\cs:w|). This command token is passed as the - argument to the function. - \item[N] A single token. (Unlike |n|, this argument must not be - surrounded by braces). A typical example of a command taking an N - argument is |\def|, in which the command being defined must be - unbraced. - \item[O] Single unbraced token that is expanded once and passed (as a - braced token list) to the function. - \item[X] Single unbraced token that is fully expanded and passed (as a - braced token list) to the function. - \item[C] A character string used as for |c| arguments but the - resulting command token is then expanded (as for |O|) and the - result passed as a braced token list to the function. - \item[p] A primitive \TeX\ parameter specification. This can be - something simple like |#1#2#3| but may be arbitrary delimited - argument syntax, such as |#1,#2\q_stop#3|. - \item[T, F] These are special cases of |n| arguments, used as the - true and false cases in conditional tests. - \item[D] `Do not use'. This special case is used for \TeX\ primitives - that are only used while bootstrapping the \LaTeX\ kernel. If the - \TeX\ primitive needs to be used in other contexts it will be given - an alternative name with a more appropriate argument specification. - \item[w] `weird' syntax. Used for arguments that take non standard - forms, usually delimited arguments that are needed internally to - implement certain modules, and also the boolean tests of many of the - primitive |\if|\ldots\ tests. -\end{description} - - -For parameters, the \m{type} should be from the list of available -data types (which include the primitive \TeX\ registers, but also -data types built within the system). - -Possible values for \m{type} include: -\begin{description} -\item[cnt] Integer valued counter. -\item[toks] Token register. -\item[box] Box register. -\item[fcnt] `Fake' count register. A data type supplied by the kernel - to avoid problems with the limited number of available count - registers in (standard) \TeX. -\end{description} - -The \m{access} codes that are used in parameter names include -\begin{description} -\item[c] Constants. -\item[l] Parameters that should only be set locally. -\item[g] Parameters that should only be set globally. -\end{description} - -\section{Checking Parameter assignments} -One of the advantages of having a consistent scheme is that the system -can provide more extensive error checking and debugging facilities. -For example a function that makes a global assignment can check that -it is not passed a local parameter as argument by checking that the -name of the command to be assigned starts with |\g_|. Such checking is -probably too slow for production runs, but the kernel has hooks built -in to allow a format to be made in which all functions perform this -kind of check. A typical section of code might look like -\begin{verbatim} -%<*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 -%</!check> -\end{verbatim} -The function |\toks_gset:Nn| takes a single token (|N|) specifying a -token register, and globally sets it to the value passed in the second -argument. So typical use would be -\begin{verbatim} -\toks_gset \g_xxx_toks {some value} -\end{verbatim} -In the normal definition, |\toks_gset| can be defined just to be |\let| -to |\global|, as the primitive token register does not require any -explicit assignment function. This is the |%<*!check>| code above. -However the alternative definition first checks that the argument -passed as |#1| is a global parameter and raises an error if it is not. -It does this by taking apart the command name passed as |#1| and -checking that it starts |\g_|. - -\section{Consistent use of accessor functions} -The primitive \TeX\ syntax for register assignments has a very minimal -syntax, and apart from box functions there are no explicit functions -for assignment or use of the registers. This makes it very difficult -to implement alternative data types with a syntax that is at all -similar to the syntax for the primitives, and also encourages a coding -style that is very error prone. - -As noted in the example given above, The \LaTeX\ data types are -provided with explicit functions for setting and using the parameters -even when these have essentially empty definitions. This allows for -better error checking as described above, and also allows the -construction of alternative data types with a similar interface. -For example the `fake counter' data type mentioned previously works at -the user level just like the data type based on primitive count -registers, internally it does not use count registers though. -Typical functions in the |fcnt| module include: - - -\verb|\fcnt_new:N \l_tempa_fcnt|\\ -Declare the local parameter |\l_tempa_fcnt| as a fake counter. - -\verb|\fcnt_add:Nn \l_tempa_fcnt \c_thirty_two|\\ -Increment the counter by 32. - -\section{Expansion Control} -Anyone who programs in \TeX\ is used to the problem of arranging that -arguments to functions are suitably expanded before the function is -called. A couple of real examples copied from \texttt{latex.ltx}: -\begin{verbatim} -\global - \expandafter\expandafter\expandafter - \let - \expandafter - \reserved@a - \csname\curr@fontshape\endcsname - -\expandafter - \in@ - \csname sym#3\expandafter\endcsname - \expandafter{\group@list}% -\end{verbatim} -The first piece of code is a global |\let|. The token to be defined -is obtained by expanding \verb|\reserved@a| one level. The command -that it is to be let too is obtained by fully expanding -\verb|\curr@fontshape| and then using the tokens produced by that -expansion to construct a command name. This results in the mess -of interwoven \verb|\expandafter| and \verb|\csname| beloved of all -\TeX\ programmers, and code that is essentially unreadable. - -A similar construction using the conventions outlined here would be -\begin{verbatim} -\glet:Oc - \reserved_a: \l_current_font_shape_tlp -\end{verbatim} -The command \verb|\glet:Oc| is a global |\let| that expands its -argument once, and generates a command name out of its second -argument, before making the definition. This produces coe that -is far more readable. - -Similarly the second piece of code above produces a token list by -expanding \verb|\group@list| once, and then creates a command name out -of `\verb|sym#3|' (this is inside the definition of another fumction). -The function |\in@| is called which tests if its first argument occurs -in the token list of its second argument. - -Again it would be much clearer, if the above function \verb|\in@| was -called (say) \verb|\test_if_in:nn| (a function taking two normal -`\texttt{n}' arguments) and then a variant function was defined with -the appropriate argument types and simply called as follows: -\begin{verbatim} -\test_if_in:co {sym#3} \group_list: -\end{verbatim} -Note that apart from the lack of \verb|\expandafter| the space after -\verb|}| will be silently ignored. - - -For many common functions the kernel will provide functions with a -range of argument forms, and similarly it is expected that extension -packages providing new functions will make then available in the more -common forms. However There will be occasions where it is necessary -to construct such a variant form. - -A consistent mechanism is provided by the kernel to produce functions -with any argument type, starting from a function that takes `normal' -\TeX\ delimited arguments. Suppose you have a function \verb|\cmd:nnn| -that takes two arguments, and you need to construct \verb|\cmd:cnx| -a variant form in which the first argument is passed as a \emph{name} -of a command, and the third argument must be fully expanded before -being passed to \verb|\cmd:nnn|. - -One simply defines \verb|\cmd:cx| as follows: -\begin{verbatim} -\def:Nn \cmd:cnx {\exp_args:Ncnx \cmd:nnn} -\end{verbatim} -The function \verb|\exp_args:Ncnx| takes as its first (\texttt{N}) -argument the `base' function, and then grabs the next three arguments -from the token stream, acts on the first with \verb|\csname|, and the -last with \verb|\edef| and then constructs a call to the base function -with suitably transformed arguments. So -\begin{verbatim} -\cmd:cnx {abc}{pq}{\rst\xyz} -\end{verbatim} -is equivalent, but emminently more readable, to -\begin{verbatim} -\edef\temp{\rst\xyz} -\expandafter\cmd:nnn - \csname abc\expandafter\endcsname - \expandafter{% - \expandafter p\expandafter q% - \expandafter}% - \expandafter{\temp} -\end{verbatim} - -A large range of argument processing functions are provided in -addition to \verb|\exp_args:Ncnx|. If you need a particular argument -combination for which a function is not provided, one may be -constructed in a simple way. For example you need to construct -\verb|\exp_args:Nxcxcxc| a function that fully expands arguments -1,~3 and~5 of a given function, and produces commands to pass as -arguments 2,~4 and~6 using \verb|\csname|. The definition is simply -\begin{verbatim} -\def:Npn \exp_args:Nxcxcxc - {\::x\::c\::x\::c\::x\::c\:::} -\end{verbatim} -Similar functions, |::o| etc exist for all the other argument types, -and they may be strung together in any order, terminated by -\verb|\:::| to create a function which processes arguments in the -desired way. - -As hopefully demonstrated, the use of variant forms greatly improves -the readability of the code, and experience shows that the longer -command names which result from the new syntax do not realy make the -process of \emph{writing} the code any harder. - -\section{The Current Experimental Distribution} -The initial implementations of a \TeX\ format using this kind of -syntax were made with an unreleased (and non functional) format -(which pre-dates \LaTeXe!) The current distribution consists of a -subset of the functionality of that format, converted to run as -packages on top of \LaTeXe. - -The intention is to allow experienced \TeX\ programmers to experiment -on the system and to comment on the interface. This means that -\textbf{\itshape the interface will change}. No part of this system, -including the names of any commands should be relied upon as being -available in a later release. Please do \emph{experiment} with these -packages, but do not use them for documents that you expect to keep -unchanged over a long period. - -In view of the proposed experimental use for this distribution, we -currently have only converted a few modules for use with \LaTeXe. -These set up the basic conventions, and then implement a few basic -programming constructs such as lists and sequences. These are really -to give a flavour of the code, and to indicate that the intention is -that the kernel provide a sufficiently rich set of programming -constructs so that packages may use them and thus more efficiently -share code, unlike the situation in the current \LaTeX\ where every -large package implements its own version of lists, stacks etc. - -The current packages are: -\begin{description} -\item[l3names] -Sets up the basic naming scheme, including naming the \TeX\ -primitives. If used with the option \texttt{[removeoldnames]} -then the old primitive names such as \verb|\box| are \emph{undefined} -and thus made available for user definitions. Use of this option might -possibly break existing \TeX\ code! - -\item [l3basics] -Some basic definitions that are used by the other packages. - -\item[l3chk] -Functions to check (and make) definitions (comparable to the existing -\verb|\newcommand| or \verb|\renewcommand|). - -\item[l3tlp] -Token List Pointers. A basic \LaTeX3 data type for storing token lists. -(These are essentially macros with no arguments.) - - -\item[l3expan] -The argument expansion module discussed in the previous section. - - -\item[l3quarq] - -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. - - -\item[l3seq] -A module implementing the basic list and stack data types. - -\item[l3prop] -Property lists are the data type for handling key/value assignments. -\end{description} - -The distribution also contains the \TeX\ source for this document, a -docstrip install file and two small test files. - -\begin{thebibliography}{1} - -\bibitem{A-W:LLa94} -Leslie Lamport. -\newblock {\em {\LaTeX:} A Document Preparation System}. -\newblock Addison-Wesley, Reading, Massachusetts, second edition, 1994. - -\end{thebibliography} - -\end{document} - - diff --git a/Master/texmf-dist/source/latex/expl3/l3alloc.dtx b/Master/texmf-dist/source/latex/expl3/l3alloc.dtx index 76f141a25b0..a2031c45493 100644 --- a/Master/texmf-dist/source/latex/expl3/l3alloc.dtx +++ b/Master/texmf-dist/source/latex/expl3/l3alloc.dtx @@ -1,5 +1,5 @@ % \iffalse -%% File: l3alloc.dtx Copyright (C) 1990-2006 LaTeX3 project +%% File: l3alloc.dtx Copyright (C) 1990-2006,2009 LaTeX3 project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this @@ -17,7 +17,7 @@ %% %% The development version of the bundle can be found at %% -%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/ +%% http://www.latex-project.org/svnroot/experimental/trunk/ %% %% for those people who are interested. %% @@ -36,7 +36,7 @@ \RequirePackage{l3names} %</driver|package> %\fi -\GetIdInfo$Id: l3alloc.dtx 621 2007-09-01 20:14:19Z morten $ +\GetIdInfo$Id: l3alloc.dtx 1362 2009-05-28 20:19:21Z joseph $ {L3 Experimental register allocation}% %\iffalse %<*driver> @@ -44,7 +44,7 @@ \ProvidesFile{\filename.\filenameext} [\filedate\space v\fileversion\space\filedescription] %\iffalse -\documentclass{l3doc} +\documentclass[full]{l3doc} \begin{document} \DocInput{\filename.\filenameext} \end{document} @@ -60,6 +60,8 @@ % \date{\filedate} % \maketitle % +% \begin{documentation} +% % \section{Allocating registers and the like} % % This module provides the basic mechanism for allocating \TeX's @@ -77,9 +79,9 @@ % \item The other registers (|\tex_count:D|, |\tex_dimen:D|, % |\tex_skip:D|, |\tex_muskip:D|, |\tex_box:D|, and |\tex_toks:D| % range from 0 to 32768, but registers numbered above 255 are -% accessed somewhat less efficient. +% accessed somewhat less efficiently. % \item Registers could be allocated both globally and locally; the -% use of regsiters could also be globaly or locally. Here we +% use of registers could also be globaly or locally. Here we % provide support for globally allocated registers for both % gloabl and local use and for locally allocated registers for % local use only. @@ -88,60 +90,67 @@ % register was allocated last and which registers can not be % allocated by the standard mechanisms. % -% \subsection{Functions} +% \section{Functions} % % \begin{function}{\alloc_setup_type:nnn} % \begin{syntax} -% "\alloc_setup_type:nnn" <type> <g_start_num> <l_start_num> +% "\alloc_setup_type:nnn" \Arg{type} \Arg{g_start_num} \Arg{l_start_num} % \end{syntax} % Sets up the storage needed for the administration of registers of % type <type>.\\ % <type> should be a token list in braces, it can be one of % "int", "dimen", "skip", "muskip", "box", "toks", "ior", "iow", % "pattern", or "ins".\\ -% <g_start_num> is the number of the first not allocated global +% <g_start_num> is the number of the first non-allocated global % register, it will be incremented by 1 when the allocation is done. -% <l_start_num> is the number of the first not allocated local +% <l_start_num> is the number of the first non-allocated local % register, it will be decremented by 1 when the allocation is done. % \end{function} % % \begin{function}{\alloc_reg:NnNN} % \begin{syntax} -% "\alloc_reg:NnNN" <g-l> <type> <alloc_cmd> <cs> +% "\alloc_reg:NnNN" "g"$\big/$"l" <type> <alloc_cmd> <cs> % \end{syntax} -% Performs the allocation of a register of type <type> to copntrol +% Performs the allocation of a register of type <type> to control % sequence <cs>, using the command <alloc_cmd>. The "g" or "l" -% indicaties whether the allocation should be global or local. +% indicates whether the allocation should be global or local. % This macro is the basic building block for the definition of the % "\"<type>"_new:N" commands % \end{function} % -% \StopEventually{} +% \end{documentation} % -% \subsection{The Implementation} +% \begin{implementation} % -% We start by ensuring that the required packages are loaded when -% this file is loaded as a package on top of \LaTeXe. +% \section{\pkg{l3alloc} implementation} % -% \begin{macrocode} -%<package>\ProvidesExplPackage -%<package> {\filename}{\filedate}{\fileversion}{\filedescription} -%<package>\RequirePackage{l3expan} -%<package>\RequirePackage{l3num} -%<package>\RequirePackage{l3seq}\par -% \end{macrocode} +% \subsection{Internal functions} % +% \begin{function}{ \alloc_next_g:n | +% \alloc_next_l:n } +% \begin{syntax} +% "\alloc_next_g:n" \Arg{type} +% \end{syntax} +% These functions find the next free register for the specified type. +% \end{function} +% +% \subsection{Module code} % % \begin{macrocode} +%<*package> +\ProvidesExplPackage + {\filename}{\filedate}{\fileversion}{\filedescription} +\package_check_loaded_expl: +%</package> %<*initex|package> % \end{macrocode} % % \begin{macro}{\alloc_setup_type:nnn} % For each type of register we need to `counters' that hold the % last allocated global or local register. We also need a sequence -% to store the `excpetions'. +% to store the `exceptions'. % \begin{macrocode} -\def_new:Npn \alloc_setup_type:nnn #1 #2 #3{ +\cs_new_nopar:Npn \alloc_setup_type:nnn #1 #2 #3{ \num_new:c {g_ #1 _allocation_num} \num_new:c {l_ #1 _allocation_num} \seq_new:c {g_ #1 _allocation_seq} @@ -156,27 +165,28 @@ % These routines find the next free register. For globally allocated % registers we first increment the counter that keeps track of them. % \begin{macrocode} -\def_new:Npn \alloc_next_g:n #1 { +\cs_new_nopar:Npn \alloc_next_g:n #1 { \num_gincr:c {g_ #1 _allocation_num} % \end{macrocode} % Then we need to check whether we have run out of registers. % \begin{macrocode} - \num_compare:cNcTF {g_ #1 _allocation_num} = {l_ #1 _allocation_num} - {\io_put_term:x{We~ ran~ out~ of~ registers~ of~ type~ g_#1!}} - { + \intexpr_compare:nTF { + \num_use:c{g_ #1 _allocation_num} = \num_use:c{l_ #1 _allocation_num} + } + {\iow_term:x{We~ ran~ out~ of~ registers~ of~ type~ g_#1!}} + { % \end{macrocode} -% We also need to check wether the value of the counter already +% We also need to check whether the value of the counter already % occurs in the list of already allocated registers. % \begin{macrocode} - \seq_if_in:cxTF {g_ #1 _allocation_seq} - {\num_use:c{g_ #1 _allocation_num}} - {\io_put_term:x{\num_use:c{g_ #1 _allocation_num}~Already~ allocated!} + \seq_if_in:cxT {g_ #1 _allocation_seq} + {\num_use:c{g_ #1 _allocation_num}} % \end{macrocode} % If it does, we find the next value. % \begin{macrocode} + { \iow_term:x{\num_use:c{g_ #1 _allocation_num}~already~allocated!} \alloc_next_g:n {#1} } - {\use_noop:} - } + } % \end{macrocode} % By now the |.._allocation_num| counter will contain the number of % the register we will assign a control seuence for. @@ -185,42 +195,47 @@ % \end{macrocode} % For the locally allocated registers we have a similar function. % \begin{macrocode} -\def_new:Npn \alloc_next_l:n #1 { +\cs_new_nopar:Npn \alloc_next_l:n #1 { \num_gdecr:c {l_ #1 _allocation_num} - \num_compare:cNcTF {g_ #1 _allocation_num} = {l_ #1 _allocation_num} - {\io_put_term:x{We~ ran~ out~ of~ registers~ of~ type~ l_#1!}} +% \end{macrocode} +% (Will: should that be "\num_decr" (no "g") ?!) +% \begin{macrocode} + \intexpr_compare:nTF { + \num_use:c{g_ #1 _allocation_num} = \num_use:c{l_ #1 _allocation_num} + } + {\iow_term:x{We~ ran~ out~ of~ registers~ of~ type~ l_#1!}} { \seq_if_in:cxTF {g_ #1 _allocation_seq} {\num_use:c{l_ #1 _allocation_num}} - {\io_put_term:x{\num_use:c{l_ #1 _allocation_num}~Already~ allocated!} + { \iow_term:x{\num_use:c{l_ #1 _allocation_num}~already~allocated!} \alloc_next_l:n {#1} } - {\io_put_term:x{\num_use:c{l_ #1 _allocation_num}~Free!}} - } + { \iow_term:x{\num_use:c{l_ #1 _allocation_num}~free!} } + } } % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\alloc_reg:NnNN} -% This internal macro performs the actual allocation. It's first +% This internal macro performs the actual allocation. Its first % argument is either 'g' for a globally allocated register or `l' % for a locally allocated register. The second argument is the % type of register to allocate, the third argument is the command % to use and the fourth argument is the control sequence that is to % be defined to point to the register. % \begin{macrocode} -\def_new:Npn \alloc_reg:NnNN #1 #2 #3 #4{ +\cs_new_nopar:Npn \alloc_reg:NnNN #1 #2 #3 #4{ % \end{macrocode} % It first checks that the control sequence that is to denote the % register does not already exist. % \begin{macrocode} - \chk_new_cs:N #4 + \chk_if_free_cs:N #4 % \end{macrocode} % Next, it decides whether a prefix is needed for the allocation % command; % \begin{macrocode} - \if:w#1g - \exp_after:NN \pref_global:D + \if:w #1 g + \exp_after:wN \pref_global:D \fi: % \end{macrocode} % And finally the actual allocation takes place. @@ -230,45 +245,28 @@ % \end{macrocode} % All that's left to do is write a message in the log file. % \begin{macrocode} - \io_put_log:x{ - \token_to_string:N#4=#2~register~\num_use:c{#1_ #2 _allocation_num}} + \iow_log:x{ + \token_to_str:N#4=#2~register~\num_use:c{#1_ #2 _allocation_num}} % \end{macrocode} -% Finally, it calls |\alloc_next_<g/l>| to find the next free register +% Finally, it calls |\alloc_next_|\meta{\texttt{\textup g}/\texttt{\textup l}} to find the next free register % number. % \begin{macrocode} - \cs_use:c{alloc_next_#1:n} {#2} + \use:c{alloc_next_#1:n} {#2} } % \end{macrocode} % \end{macro} % +% \begin{macrocode} +%</initex|package> +% \end{macrocode} % % \begin{macrocode} %<*showmemory> \showMemUsage %</showmemory> -%</initex|package> % \end{macrocode} % -% \endinput -% -% $Log$ -% Revision 1.6 2006/03/20 18:26:32 braams -% Updated the copyright notice (2006) and demoted all implementation -% sections to subsections and so on to clean up the toc for source3.tex -% -% Revision 1.5 2006/01/15 14:02:58 braams -% Added a \SopEventually{} command -% -% Revision 1.4 2005/12/27 16:02:18 morten -% Changed RCS information retrieval -% -% Revision 1.3 2005/04/06 22:32:38 braams -% Removed the functins that belong in other modules; -% Fixed the naming conventions -% -% Revision 1.2 2005/04/05 22:12:44 braams -% First, working, version of the regsiter allocation support -% -% Revision 1.1 2005/03/16 22:50:02 braams -% Initial register allocation module +% \end{implementation} +% \PrintIndex % +% \endinput diff --git a/Master/texmf-dist/source/latex/expl3/l3basics.dtx b/Master/texmf-dist/source/latex/expl3/l3basics.dtx index e34e42f2732..ecbafc5d6b9 100644 --- a/Master/texmf-dist/source/latex/expl3/l3basics.dtx +++ b/Master/texmf-dist/source/latex/expl3/l3basics.dtx @@ -1,5 +1,5 @@ % \iffalse -%% File: l3basics.dtx Copyright (C) 1990-2006 LaTeX3 project +%% File: l3basics.dtx Copyright (C) 1990-2008 LaTeX3 project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this @@ -17,7 +17,7 @@ %% %% The development version of the bundle can be found at %% -%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/ +%% http://www.latex-project.org/svnroot/experimental/trunk/ %% %% for those people who are interested. %% @@ -35,7 +35,7 @@ \RequirePackage{l3names} %</driver|package> %\fi -\GetIdInfo$Id: l3basics.dtx 702 2007-11-27 14:21:49Z morten $ +\GetIdInfo$Id: l3basics.dtx 1365 2009-05-31 17:26:17Z mittelba $ {L3 Experimental basic definitions} %\iffalse %<*driver> @@ -43,9 +43,9 @@ \ProvidesFile{\filename.\filenameext} [\filedate\space v\fileversion\space\filedescription] %\iffalse -\documentclass{l3doc} +\documentclass[full]{l3doc} \begin{document} -\DocInput{\filename.\filenameext} +\DocInput{l3basics.dtx} \end{document} %</driver> % \fi @@ -59,41 +59,116 @@ % \date{\filedate} % \maketitle % +% \begin{documentation} % % 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. With +% Here we describe those functions that are used all over the place. With % that we mean functions dealing with the construction and testing of % control sequences. Furthermore the basic parts of conditional % processing are covered; conditional processing dealing with specific % data types is described in the modules specific for the respective % data types. % -% \subsection{Predicates and conditionals} +% \section{Predicates and conditionals} +% \label{sec:predicates} +% +% \LaTeX3 has three concepts for conditional flow processing: +% \begin{description} +% +% \item[Branching conditionals] +% Functions that carry out a test and then execute, depending on its +% result, either the code supplied in the \m{true arg} or the \m{false +% arg}. +% These arguments are denoted with "T" and "F" repectively. An +% example would be +% \begin{quote} +% "\cs_if_free:cTF{abc}" \Arg{true code} \Arg{false code} +% \end{quote} +% a function that will turn the first argument into a control sequence +% (since it's 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). +% +% These type of functions are known as `conditionals'; whenever a "TF" +% function is defined it will usually be accompanied by "T" and "F" +% functions as well. These are provided for convenience when the +% branch only needs to go a single way. Package writers are free to +% choose which types to define but the kernel definitions will always +% provide all three versions. +% +% Important to note is that these branching conditionals with \m{true +% code} and/or \m{false code} are always defined in a way that the +% code of the chosen alternative can operate on following tokens in +% the input stream. +% +% These conditional functions may or may not be fully expandable, but if they +% are expandable they will be accompanied by a `predicate' for the same test +% as described below. +% +% \item[Predicates] +% `Predicates' are functions that return a special type of boolean +% value which can be tested by the function "\if_predicate:w" +% or in the boolean expression parser. All functions of this type +% are expandable and have names that end with "_p" in the +% description part. For example, +% \begin{quote} +% "\cs_if_free_p:N" +% \end{quote} +% would be a predicate function for the same type of test as the +% conditional described 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_predicate:w \cs_if_free_p:N \l_tmpz_tl" \m{true code} "\else:" +% \m{false code} "\fi:" +% \end{quote} +% or in expressions utilizing the boolean logic parser: +% \begin{quote} +% "\bool_if:nTF {" \\ +% " \cs_if_free_p:N \l_tmpz_tl || \cs_if_free_p:N \g_tmpz_tl " \\ +% "}" +% \Arg{true code} \Arg{false code} +% \end{quote} % -% \subsubsection{Primitive conditionals} +% Like their branching cousins, predicate functions ensure that all +% underlying primitive "\else:" or "\fi:" have been removed before +% returning the boolean true or false values.\footnote{If defined +% using the interface provided.} +% +% For each predicate defined, a `predicate conditional' will also exist that +% behaves like a conditional described above. +% +% \item[Primitive conditionals] +% There is a third variety of conditional, which is the original concept used in +% plain \TeX{} and \LaTeX. Their use is discouraged in \pkg{expl3} (although +% still used in low-level definitions) because they are more fragile and +% in many cases require more expansion control (hence more code) than the two +% types of conditionals described above. +% \end{description} +% +% +% \subsection{Primitive conditionals} % % The \eTeX\ engine itself provides many different conditionals. Some % expand whatever comes after them and others don't. Hence the names % for these underlying functions will often contain a |:w| part but % higher level functions are often available. See for instance -% |\int_compare_p:nNn| which is a wrapper for |\if_num:w|. +% |\intexpr_compare_p:nNn| which is a wrapper for |\if_num:w|. % % Certain conditionals deal with specific data types like boxes and % fonts and are described there. The ones described below are either % the universal conditionals or deal with control sequences. We will % prefix primitive conditionals with |\if_|. % -% \begin{function}{% -% \if_true: | -% \if_false: | -% \else: | -% \fi: | -% \reverse_if:N | -% } +% \begin{function}{ \if_true: / (EXP) | +% \if_false: / (EXP) | +% \or: / (EXP) | +% \else: / (EXP) | +% \fi: / (EXP) | +% \reverse_if:N / (EXP) } % \begin{syntax} % "\if_true:" <true code> "\else:" <false code> "\fi:" \\ % "\if_false:" <true code> "\else:" <false code> "\fi:" \\ @@ -101,37 +176,31 @@ % \end{syntax} % "\if_true:" always executes <true code>, while "\if_false:" always % executes <false code>. "\reverse_if:N" reverses any two-way primitive -% conditional. "\else:" and "\fi:" delimit the branches of the conditional. +% conditional. "\else:" and "\fi:" delimit the branches of the +% conditional. "\or:" is used in case switches, see \pkg{l3intexpr} +% for more. +% \begin{texnote} +% These are equivalent to their corresponding \TeX\ primitive +% conditionals; |\reverse_if:N| is \eTeX's |\unless|. +% \end{texnote} % \end{function} % -% \begin{function}{% -% \if_meaning:NN | -% \if_cs_meaning_eq:NN | -% \if_token_eq:NN | -% } +% \begin{function}{ \if_meaning:w / (EXP) } % \begin{syntax} -% "\if_meaning:NN" <cs1> <cs2> <true code> "\else:" <false code> -% "\fi:" \\ -% "\if_cs_meaning_eq:NN" <cs1> <cs2> <true code> "\else:" -% <false code> "\fi:" \\ -% "\if_token_eq:NN" <token1> <token2> <true code> "\else:" <false -% code> "\fi:" +% "\if_meaning:w" <arg1> <arg2> <true code> "\else:" <false code> "\fi:" % \end{syntax} -% "\if_meaning:NN" executes <true code> when the replacement text, -% i.e., the expansion of <cs1> and <cs2> are the same, otherwise it -% executes <false code>. However this name isn't really that -% good. What the \TeX\ primitive does is compare two tokens to see if -% they are equal. Hence this is actually a "token" functions. A -% similar argument applies to the situation where it is used to -% compare control sequences, where it is the meaning being compared. -% Something to be cleaned up at some point. +% "\if_meaning:w" executes <true code> when <arg1> and <arg2> are the same, +% otherwise it executes <false code>. +% <arg1> and <arg2> could be functions, variables, tokens; in all cases the +% \emph{unexpanded} definitions are compared. +% \begin{texnote} +% This is \TeX's |\ifx|. +% \end{texnote} % \end{function} % -% \begin{function}{% -% \if:w | -% \if_charcode:w | -% \if_catcode:w -% } +% \begin{function}{ \if:w / (EXP) | +% \if_charcode:w / (EXP) | +% \if_catcode:w / (EXP) } % \begin{syntax} % "\if:w" <token1> <token2> <true code> "\else:" <false code> "\fi:" \\ % "\if_catcode:w" <token1> <token2> <true code> "\else:" <false @@ -145,10 +214,30 @@ % identical. "\if_charcode:w" is an alternative name for "\if:w". % \end{function} % -% \begin{function}{% -% \if_cs_exist:N | -% \if_cs_exist:w -% } +% +% \begin{function}{\if_predicate:w / (EXP)} +% \begin{syntax} +% "\if_predicate:w" <predicate> <true code> "\else:" <false code> "\fi:" +% \end{syntax} +% This function takes a predicate function and +% branches according to the result. (In practice this function would also +% accept a single boolean variable in place of the <predicate> but to make the +% coding clearer this should be done through "\if_bool:N".) +% \end{function} +% +% +% +% \begin{function}{\if_bool:N / (EXP)} +% \begin{syntax} +% "\if_bool:N" <boolean> <true code> "\else:" <false code> "\fi:" +% \end{syntax} +% This function takes a boolean variable and +% branches according to the result. +% \end{function} +% +% +% \begin{function}{ \if_cs_exist:N / (EXP) | +% \if_cs_exist:w / (EXP) } % \begin{syntax} % "\if_cs_exist:N" <cs> <true code> "\else:" <false code> "\fi:" \\ % "\if_cs_exist:w" <tokens> "\cs_end:" <true code> "\else:" <false @@ -162,357 +251,388 @@ % \end{function} % % \begin{function}{ -% \if_mode_horizontal: | -% \if_mode_vertical: | -% \if_mode_math: | -% \if_mode_inner: -% } +% \if_mode_horizontal: / (EXP) | +% \if_mode_vertical: / (EXP) | +% \if_mode_math: / (EXP) | +% \if_mode_inner: / (EXP) } % \begin{syntax} -% "\if_horizontal_mode:" <true code> "\else:" <false code> "\fi:" +% "\if_mode_horizontal:" <true code> "\else:" <false code> "\fi:" % \end{syntax} % Execute <true code> if currently in horizontal mode, otherwise % execute <false code>. Similar for the other functions. % \end{function} % -% \subsubsection{Non-primitive conditionals} +% \subsection{Non-primitive conditionals} % -% \begin{function}{% -% \cs_if_eq_p:NN -% } +% \begin{function}{ \cs_if_eq_name_p:NN } % \begin{syntax} -% "\cs_if_eq_p:NN" <cs1> <cs2> +% "\cs_if_eq_name_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_if_eq:NNTF | -% \cs_if_eq:NNT | -% \cs_if_eq:NNF | -% \cs_if_eq:cNTF | -% \cs_if_eq:cNT | -% \cs_if_eq:cNF | -% \cs_if_eq:NcTF | -% \cs_if_eq:NcT | -% \cs_if_eq:NcF | -% \cs_if_eq:ccTF | -% \cs_if_eq:ccT | -% \cs_if_eq:ccF -% } +% \begin{function}{ \cs_if_eq_p:NN / (EXP) | +% \cs_if_eq_p:cN / (EXP) | +% \cs_if_eq_p:Nc / (EXP) | +% \cs_if_eq_p:cc / (EXP) | +% \cs_if_eq:NN / (TF)(EXP) | +% \cs_if_eq:cN / (TF)(EXP) | +% \cs_if_eq:Nc / (TF)(EXP) | +% \cs_if_eq:cc / (TF)(EXP) } % \begin{syntax} -% "\cs_if_eq:NNTF" <cs1> <cs2> "{"<true code>"}{"<false code>"}" +% "\cs_if_eq_p:NNTF" <cs1> <cs2> +% "\cs_if_eq:NNTF" <cs1> <cs2> \Arg{true code} \Arg{false code} % \end{syntax} -% These functions check if <cs1> and <cs2> have same meaning and then -% execute either <true code> or <false code>. +% These functions check if <cs1> and <cs2> have same meaning. % \end{function} % % -% \begin{function}{% -% \cs_if_free_p:N -% } +% \begin{function}{ \cs_if_free_p:N / (EXP) | +% \cs_if_free_p:c / (EXP) | +% \cs_if_free:N / (TF)(EXP) | +% \cs_if_free:c / (TF)(EXP) } % \begin{syntax} % "\cs_if_free_p:N" <cs> +% "\cs_if_free:NTF" <cs> \Arg{true code} \Arg{false code} % \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:". +% Returns `true' if <cs> is either undefined or equal to +% "\tex_relax:D" (the function that is assigned to newly created +% control sequences by \TeX{} when "\cs:w" "..." "\cs_end:" is +% used). In addition to this, `true' is only returned if <cs> does not +% have a signature equal to "D", i.e., `do not use' functions are not +% free to be redefined. % \end{function} % -% \begin{function}{% -% \cs_if_free:NTF | -% \cs_if_free:NT | -% \cs_if_free:NF | -% \cs_if_free:cTF | -% \cs_if_free:cT | -% \cs_if_free:cF -% } +% \begin{function}{ \cs_if_exist_p:N / (EXP) | +% \cs_if_exist_p:c / (EXP) | +% \cs_if_exist:N / (TF)(EXP) | +% \cs_if_exist:c / (TF)(EXP) } % \begin{syntax} -% "\cs_if_free:NTF" <cs> "{"<true code>"}{"<false code>"}" +% "\cs_if_exist_p:N" <cs> +% "\cs_if_exist:NTF" <cs> \Arg{true code} \Arg{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_if_free:cTF" is the \LaTeX3 implementation of -% the \LaTeX2 function \tn{@ifundefined}. The other functions -% haven't been around before. -% \end{texnote} +% These functions check if <cs> exists, i.e., if <cs> is present in +% the hash table and is not the primitive "\tex_relax:D". % \end{function} % -% \begin{function}{% -% \cs_if_really_free:cTF | -% \cs_if_really_free:cF | -% \cs_if_really_free:cT -% } +% \begin{function}{ \cs_if_do_not_use_p:N / (EXP) } % \begin{syntax} -% "\cs_if_really_free:cTF" "{"<tokens>"}" "{"<true code>"} {"<false -% code>"}" +% "\cs_if_do_not_use_p:N" <cs> % \end{syntax} -% Similar to "\cs_if_free:cTF" but does not put anything previously -% undefined into the hash table. Useful for special control sequences -% like "\foo/bar" which cannot be entered as one token. +% These functions check if <cs> has the arg spec "D" for `\emph{do not use}'. +% There are no "TF"-type conditionals for this function as it is only used +% internally and not expected to be widely used. (For now, anyway.) % \end{function} % -% \begin{function}{% -% \cs_if_exist_p:N -% } +% \begin{function}{ \chk_if_free_cs:N } % \begin{syntax} -% "\cs_if_exist_p:N" <cs> +% "\chk_if_free_cs:N" <cs> % \end{syntax} -% This function does the opposite of "\cs_if_free_p:N". +% This function checks that <cs> is \m{free} according to the criteria +% for "\cs_if_free_p:N" above. If not, an error is generated. % \end{function} % -% \begin{function}{% -% \cs_if_exist:NTF | -% \cs_if_exist:NT | -% \cs_if_exist:NF | -% \cs_if_exist:cTF | -% \cs_if_exist:cT | -% \cs_if_exist:cF -% } +% \begin{function}{ \chk_if_exist_cs:N | +% \chk_if_exist_cs:c } % \begin{syntax} -% "\cs_if_exist:NTF" <cs> "{"<true code>"}{"<false code>"}" +% "\chk_if_exist_cs:N" <cs> % \end{syntax} -% These functions check if <cs> exists and then execute either <true -% code> or <false code>. Exactly the opposite of "\cs_if_free:NTF". +% This function checks that <cs> is defined. If it is not an error +% is generated. % \end{function} % -% \begin{function}{% -% \cs_if_really_exist:cTF | -% \cs_if_really_exist:cF | -% \cs_if_really_exist:cT -% } +% \begin{variable}{ \c_true_bool | \c_false_bool } % \begin{syntax} -% "\cs_if_really_exist:cTF" "{"<tokens>"}" "{"<true code>"} {"<false -% code>"}" % \end{syntax} -% The opposite of "\cs_if_really_free:cTF". -% \end{function} +% Constants that represent `true' or `false', respectively. Used to +% implement predicates. +% \end{variable} % +% \subsection{Applications} % -% \begin{function}{% -% \chk_new_cs:N | -% } +% \begin{function}{ \str_if_eq_p:nn / (EXP) } % \begin{syntax} -% "\chk_new_cs:N" <cs> +% "\str_if_eq_p:nn" \Arg{string1} \Arg{string2} % \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). +% Expands to `true' if <string1> is the same as <string2>, +% otherwise `false'. Ignores spaces within the strings. % \end{function} % -% \begin{function}{% -% \chk_exist_cs:N | -% \chk_exist_cs:c -% } +% \begin{function}{ \str_if_eq_var_p:nf / (EXP) } % \begin{syntax} -% "\chk_exist_cs:N" <cs> +% "\str_if_eq_var_p:nf" \Arg{string1} \Arg{string2} % \end{syntax} -% This function checks that <cs> is defined. If it is not an error -% is generated. +% A variant of "\str_if_eq_p:nn" which has the advantage of +% obeying spaces in at least the second argument. % \end{function} % % -% \begin{variable}{% -% \c_true | -% \c_false -% } +% \section{Control sequences} +% +% \begin{function}{ \cs:w / (EXP) | \cs_end: / (EXP) } % \begin{syntax} +% "\cs:w" <tokens> "\cs_end:" % \end{syntax} -% Constants that represent `true' or `false', respectively. Used to -% implement predicates. -% \end{variable} +% 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}{ \cs_show:N | +% \cs_show:c } +% \begin{syntax} +% "\cs_show:N" <cs> +% "\cs_show:c" \Arg{arg} +% \end{syntax} +% This function shows in the console output the \emph{meaning} of the control +% sequence <cs> or that created by <arg>. +% \begin{texnote} +% This is \TeX's |\show| and associated csname version of it. +% \end{texnote} +% \end{function} % +% \begin{function}{ \cs_meaning:N / (EXP) | +% \cs_meaning:c / (EXP) } +% \begin{syntax} +% "\cs_meaning:N" <cs> +% "\cs_meaning:c" \Arg{arg} +% \end{syntax} +% This function expands to the \emph{meaning} of the control sequence <cs> or +% that created by <arg>. +% \begin{texnote} +% This is \TeX's |\meaning| and associated csname version of it. +% \end{texnote} +% \end{function} % -% \subsection{Selecting and discarding tokens from the input stream} +% \section{Selecting and discarding tokens from the input stream} % -% The conditional processing could not have been implemented without +% The conditional processing cannot be implemented without % being able to gobble and select which tokens to use from the input % stream. +% % -% \begin{function}{% -% \use_none:n | -% \use_none:nn | -% \use_none:nnn | -% \use_none:nnnn | -% \use_none:nnnnn | -% \use_none:nnnnnn | -% \use_none:nnnnnnn | -% \use_none:nnnnnnnn | -% \use_none:nnnnnnnnn | -% } +% \begin{function}{ \use:n / (EXP) | +% \use:nn / (EXP) | +% \use:nnn / (EXP) | +% \use:nnnn / (EXP) } % \begin{syntax} -% "\use_none:n" "{"<arg1>"}"\\ -% "\use_none:nn" "{"<arg1>"}{"<arg2>"}" +% "\use:n" \Arg{arg} % \end{syntax} -% These functions gobble the tokens or brace groups from the input -% stream. +% Functions that returns all of their arguments to the input stream after +% removing the surrounding braces around each argument. +% \begin{texnote} +% "\use:n" is \LaTeXe's "\@firstofone"/"\@iden". +% \end{texnote} % \end{function} % +% \begin{function}{ \use:c / (EXP) } +% \begin{syntax} +% "\use:c" \Arg{cs} +% \end{syntax} +% Function that returns to the input stream the control sequence created from +% its argument. Requires two expansions before a control sequence is returned. +% \begin{texnote} +% "\use:c" is \LaTeXe's "\@nameuse". +% \end{texnote} +% \end{function} % -% \begin{function}{\use_arg_i:n} +% \begin{function}{ \use_none:n / (EXP) | +% \use_none:nn / (EXP) | +% \use_none:nnn / (EXP) | +% \use_none:nnnn / (EXP) | +% \use_none:nnnnn / (EXP) | +% \use_none:nnnnnn / (EXP) | +% \use_none:nnnnnnn / (EXP) | +% \use_none:nnnnnnnn / (EXP) | +% \use_none:nnnnnnnnn / (EXP) } % \begin{syntax} -% "\use_arg_i:n" "{" <code1> "}" +% "\use_none:n" \Arg{arg1}\\ +% "\use_none:nn" \Arg{arg1} \Arg{arg2} % \end{syntax} -% Function that executes the next argument after removing the -% surrounding braces. Used to implement conditionals. +% These functions gobble the tokens or brace groups from the input +% stream. +% \begin{texnote} +% "\use_none:n", "\use_none:nn", "\use_none:nnnn" are \LaTeXe's +% "\@gobble", "\@gobbletwo", and "\@gobblefour". +% \end{texnote} % \end{function} % -% \begin{function}{% -% \use_arg_i:nn | -% \use_arg_ii:nn | -% } +% \begin{function}{ \use_i:nn / (EXP) | +% \use_ii:nn / (EXP) } % \begin{syntax} -% "\use_arg_i:nn" "{" <code1> "}{" <code2> "}" +% "\use_i:nn" \Arg{code1} \Arg{code2} % \end{syntax} % Functions that execute the first or second argument respectively, % after removing the surrounding braces. Primarily used to implement % conditionals. +% \begin{texnote} +% These are \LaTeXe's "\@firstoftwo" and "\@secondoftwo", respectively. +% \end{texnote} % \end{function} % -% \begin{function}{% -% \use_arg_i:nnn | -% \use_arg_ii:nnn | -% \use_arg_iii:nnn | -% } +% \begin{function}{ \use_i:nnn / (EXP) | +% \use_ii:nnn / (EXP) | +% \use_iii:nnn / (EXP) } % \begin{syntax} -% "\use_arg_i:nnn" "{" <arg1> "}{" <arg2> "}{" <arg3> "}" +% "\use_i:nnn" \Arg{arg1} \Arg{arg2} \Arg{arg3} % \end{syntax} % Functions that pick up one of three arguments and execute them after -% removing the surrounding braces. Should be described somewhere else. +% removing the surrounding braces. +% \begin{texnote} +% \LaTeXe\ has only "\@thirdofthree". +% \end{texnote} % \end{function} % -% \begin{function}{% -% \use_arg_i:nnnn | -% \use_arg_ii:nnnn | -% \use_arg_iii:nnnn | -% \use_arg_iv:nnnn | -% } +% \begin{function}{ \use_i:nnnn / (EXP) | +% \use_ii:nnnn / (EXP) | +% \use_iii:nnnn / (EXP) | +% \use_iv:nnnn / (EXP) } % \begin{syntax} -% "\use_arg_i:nnnn" "{" <arg1> "}{" <arg2> "}{" <arg3> "}{" <arg4> "}" +% "\use_i:nnnn" \Arg{arg1} \Arg{arg2} \Arg{arg3} \Arg{arg4} % \end{syntax} % Functions that pick up one of four arguments and execute them after % removing the surrounding braces. % \end{function} % -% A different kind of functions for selecting tokens from the token -% stream are those that use delimited arguments. +% \subsection{Extending the interface} % -% \begin{function}{% -% \use_none_delimit_by_q_nil:w | -% \use_none_delimit_by_q_stop:w | -% } +% \begin{function}{ \use_i_ii:nnn / (EXP) } +% \begin{syntax} +% "\use_i_ii:nnn" \Arg{arg1} \Arg{arg2} \Arg{arg3} +% \end{syntax} +% This function used in the expansion module reads three arguments and +% returns (without braces) the first and second argument while +% discarding the third argument. +% +% If you wish to select multiple arguments while discarding others, +% use a syntax like this. Its definition is +% \begin{verbatim} +% \cs_set:Npn \use_i_ii:nnn #1#2#3 {#1#2} +% \end{verbatim} +% \end{function} +% +% \subsection{Selecting tokens from delimited arguments} +% +% A different kind of function for selecting tokens from the token +% stream are those that use delimited arguments. +% +% \begin{function}{ \use_none_delimit_by_q_nil:w / (EXP) | +% \use_none_delimit_by_q_stop:w / (EXP) | +% \use_none_delimit_by_q_recursion_stop:w / (EXP) } % \begin{syntax} % "\use_none_delimit_by_q_nil:w" <balanced text> "\q_nil" % \end{syntax} % Gobbles <balanced text>. Useful in gobbling the remainder in a list -% structure. +% structure or terminating recursion. % \end{function} % -% \begin{function}{% -% \use_arg_i_delimit_by_q_nil:nw | -% \use_arg_i_delimit_by_q_stop:nw | -% } +% \begin{function}{ \use_i_delimit_by_q_nil:nw / (EXP) | +% \use_i_delimit_by_q_stop:nw / (EXP) | +% \use_i_delimit_by_q_recursion_stop:nw / (EXP) } % \begin{syntax} -% "\use_arg_i_delimit_by_q_nil:nw" "{"<arg>"}" <balanced text> "\q_nil" +% "\use_i_delimit_by_q_nil:nw" \Arg{arg} <balanced text> "\q_nil" % \end{syntax} % Gobbles <balanced text> and executes <arg> afterwards. This can also % be used to get the first item in a token list. % \end{function} % % -% \begin{function}{% -% \use_arg_i_after_fi:nw | -% \use_arg_i_after_else:nw | -% \use_arg_i_after_or:nw | -% \use_arg_i_after_orelse:nw -% } +% \begin{function}{ \use_i_after_fi:nw / (EXP) | +% \use_i_after_else:nw / (EXP) | +% \use_i_after_or:nw / (EXP) | +% \use_i_after_orelse:nw / (EXP) } % \begin{syntax} -% "\use_arg_i_after_fi:nw" "{"<arg>"}" "\fi:" -% "\use_arg_i_after_else:nw" "{"<arg>"}" "\else:" <balanced text> "\fi:" -% "\use_arg_i_after_or:nw" "{"<arg>"}" "\or:" <balanced text> "\fi:" -% "\use_arg_i_after_orelse:nw" "{"<arg>"}" "\or:/\else:" <balanced text> "\fi:" +% "\use_i_after_fi:nw" \Arg{arg} "\fi:" +% "\use_i_after_else:nw" \Arg{arg} "\else:" <balanced text> "\fi:" +% "\use_i_after_or:nw" \Arg{arg} "\or:" <balanced text> "\fi:" +% "\use_i_after_orelse:nw" \Arg{arg} "\or:/\else:" <balanced text> "\fi:" % \end{syntax} % Executes <arg> after executing closing out -% "\fi:". "\use_arg_i_after_orelse:nw" can be used anywhere where -% "\use_arg_i_after_else:nw" or "\use_arg_i_after_or:nw" are used. +% "\fi:". "\use_i_after_orelse:nw" can be used anywhere where +% "\use_i_after_else:nw" or "\use_i_after_or:nw" are used. % \end{function} % -% \subsection{Internal functions} % -% \begin{function}{% -% \cs:w | -% \cs_end: -% } +% \section{That which belongs in other modules but needs to be defined earlier} +% +% \begin{function}{ \exp_after:wN / (EXP) } % \begin{syntax} -% "\cs:w" <tokens> "\cs_end:" +% "\exp_after:wN" <token1> <token2> % \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. +% Expands <token2> once and then continues processing from <token1>. % \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} +% This is \TeX's \tn{expandafter}. +% \end{texnote} % \end{function} % -% \begin{function}{\pref_global:D | -% \pref_long:D | -% \pref_protected:D | -% } +% \begin{function}{ \exp_not:N / (EXP) | \exp_not:n / (EXP) } % \begin{syntax} -% "\pref_global:D" "\def:Npn" +% "\exp_not:N" <token> +% "\exp_not:n" \Arg{tokens} % \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, -% and "\pref_protected:D" makes the definition robust in "\write"s etc. -% -% -% None of these internal functions should be used by a programmer since -% the necessary combinations are all available as separate function, -% e.g., "\def_long:Npn" is internally implemented as "\pref_long:D" -% "\def:Npn". +% In an expanding context, this function prevents <token> or <tokens> from +% expanding. % \begin{texnote} -% These prefixes are the primitives \tn{global}, \tn{long}, and -% \tn{protected}. The \tn{outer} isn't used at all within \LaTeX3 -% because \ldots +% These are \TeX's \tn{noexpand} and \eTeX's \tn{unexpanded}, respectively. % \end{texnote} % \end{function} % +% \begin{function}{ \prg_do_nothing: / (EXP) } +% This is as close as we get to a null operation or no-op. +% \begin{texnote} +% Definition as in \LaTeX's \tn{\@empty} but not used for the same thing. +% \end{texnote} +% \end{function} % -% -% \begin{function}{\io_put_log:x | -% \io_put_term:x | -% \io_put_deferred:Nx | -% } +% \begin{function}{ \iow_log:x | +% \iow_term:x | +% \iow_shipout_x:Nn } % \begin{syntax} -% "\io_put_log:x" "{"<message>"}" -% "\io_put_deferred:Nx" <write_stream> "{"<message>"}" +% "\iow_log:x" \Arg{message} +% "\iow_shipout_x:Nn" <write_stream> \Arg{message} % \end{syntax} % Writes <message> to either to log or the terminal. % \end{function} % -% \subsection{Defining functions} +% \begin{function}{ \msg_kernel_bug:x } +% \begin{syntax} +% "\msg_kernel_bug:x" \Arg{message} +% \end{syntax} +% Internal function for calling errors in our code. +% \end{function} +% +% \begin{function}{ \cs_record_meaning:N } +% Placeholder for a function to be defined by \file{l3chk}. +% \end{function} +% +% \begin{variable}{ \c_minus_one | \c_zero | \c_sixteen } +% Numeric constants. +% \end{variable} +% +% +% +% \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 +% simply make the definition. The latter are used for internal scratch % functions that get new meanings all over the place. % % For each type there is an additional choice to be made: Does the % function to be defined contain delimited arguments? The answer in -% 99\% of the cases is no, so in most cases the programmer just want -% to input the number of arguments, which is basically how -% \cs{newcommand} in \LaTeXe{} works. Therefore we provide functions -% that expect a number as the primary type and later on in this module -% you can find the ones with the more primitive syntax. +% 99\% of the cases is no. For this type the programmer will know the +% number of arguments and in most cases use the argument signature to +% signal this, e.g., "\foo_bar:nnn" presumably takes three +% arguments. We therefore also provide functions that automatically +% detect how many arguments are required and construct the parameter +% text on the fly. % % A definition of a new function can be done locally and globally. Currently % nearly all function definitions are done locally on top level, in @@ -528,104 +648,126 @@ % as individual functions. % \end{texnote} % -% -% \subsubsection{Defining new functions} -% -% Firstly comes to variants most used namely those taking a number to -% denote the number of arguments. -% -% \begin{function}{\def_new:NNn | -% \def_new:NNx | -% \def_new:cNn | -% \def_new:cNx +% A slew of functions are defined in the following sections for defining +% new functions. Here's a quick summary to get an idea of what's available: +% {\centering +% "\cs_"("g")("new"/"set")("_protected")("_nopar")":"("N"/"c")("p")("n"/"x") +% \par} +% That stands for, respectively, the following variations: +% \begin{description} +% \item[\texttt g] Global or local; +% \item[\texttt{new}/\texttt{set}] +% Define a new function or re-define an existing one; +% \item[\texttt{protected}] +% Prevent expansion of the function in "x" arguments; +% \item[\texttt{nopar}] Restrict the argument(s) from containing "\par"; +% \item[\texttt N/\texttt c] Either a control sequence or a `csname'; +% \item[\texttt p] +% Either the a primitive \TeX\ argument or the number of arguments +% is detected from the argument signature, i.e., |\foo:nnn| is +% assumed to have three arguments |#1#2#3|; +% \item[\texttt n/\texttt x] Either an unexpanded or an expanded definition. +% \end{description} +% That adds up to 128 variations (!). However, the system is very +% logical and only a handful will usually be required often. +% +% +% +% \subsection{Defining new functions using primitive parameter text} +% +% +% \begin{function}{\cs_new:Npn | +% \cs_new:Npx | +% \cs_new:cpn | +% \cs_new:cpx % } % \begin{syntax} -% "\def_new:NNn" <cs> <num> "{" <code> "}" +% "\cs_new:Npn" <cs> <parms> \Arg{code} % \end{syntax} -% Defines a new function, making sure that <cs> is unused so far. -% <num> is the number of arguments which is in the interval $[0,9]$ -% otherwise an error is raised. It is under the responsibility of the -% programmer to name the new function according to the rules laid out -% in the previous section. <code> is either passed literally or may -% be subject to expansion (under the "x" variants). +% Defines a function that may contain "\par" tokens in the argument(s) +% when called. This is not allowed for normal functions. % \end{function} % -% \begin{function}{\gdef_new:NNn | -% \gdef_new:cNn | -% \gdef_new:NNx | -% \gdef_new:cNx +% \begin{function}{\cs_gnew:Npn | +% \cs_gnew:Npx | +% \cs_gnew:cpn | +% \cs_gnew:cpx % } % \begin{syntax} -% "\gdef_new:NNn" <cs> <num> "{" <code> "}" +% "\cs_gnew:Npn" <cs> <parms> \Arg{code} % \end{syntax} -% Like "\def_new:NNn" but defines the new function globally. +% Global versions of the above functions. % \end{function} % -% \begin{function}{\def_long_new:NNn | -% \def_long_new:NNx | -% \def_long_new:cNn | -% \def_long_new:cNx +% \begin{function}{\cs_new_nopar:Npn | +% \cs_new_nopar:Npx | +% \cs_new_nopar:cpn | +% \cs_new_nopar:cpx % } % \begin{syntax} -% "\def_long_new:NNn" <cs> <num> "{" <code> "}" +% "\cs_new_nopar:Npn" <cs> <parms> \Arg{code} % \end{syntax} -% Defines a function that may contain "\par" tokens in the argument(s) -% when called. This is not allowed for normal functions. +% 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_long_new:NNn | -% \gdef_long_new:NNx | -% \gdef_long_new:cNn | -% \gdef_long_new:cNx +% \begin{function}{\cs_gnew_nopar:Npn | +% \cs_gnew_nopar:Npx | +% \cs_gnew_nopar:cpn | +% \cs_gnew_nopar:cpx % } % \begin{syntax} -% "\gdef_long_new:NNn" <cs> <num> "{" <code> "}" +% "\cs_gnew_nopar:Npn" <cs> <parms> \Arg{code} % \end{syntax} -% Global versions of the above functions. +% Like "\cs_new_nopar:Npn" but defines the new function globally. See +% comments above. % \end{function} % -% \begin{function}{\def_protected_new:NNn | -% \def_protected_new:NNx | -% \def_protected_new:cNn | -% \def_protected_new:cNx +% \begin{function}{\cs_new_protected:Npn | +% \cs_new_protected:Npx | +% \cs_new_protected:cpn | +% \cs_new_protected:cpx % } % \begin{syntax} -% "\def_protected_new:NNn" <cs> <num> "{" <code> "}" +% "\cs_new_protected:Npn" <cs> <parms> \Arg{code} % \end{syntax} -% Defines a function that does not expand when inside an |x| type -% expansion. +% Defines a function that is both robust and may contain "\par" tokens +% in the argument(s) when called. % \end{function} % -% \begin{function}{\gdef_protected_new:NNn | -% \gdef_protected_new:NNx | -% \gdef_protected_new:cNn | -% \gdef_protected_new:cNx -% } +% \begin{function}{ \cs_gnew_protected:Npn | +% \cs_gnew_protected:Npx | +% \cs_gnew_protected:cpn | +% \cs_gnew_protected:cpx } % \begin{syntax} -% "\gdef_protected_new:NNn" <cs> <num> "{" <code> "}" +% "\cs_gnew_protected:Npn" <cs> <parms> \Arg{code} % \end{syntax} % Global versions of the above functions. % \end{function} % -% \begin{function}{\def_protected_long_new:NNn | -% \def_protected_long_new:NNx | -% \def_protected_long_new:cNn | -% \def_protected_long_new:cNx +% \begin{function}{\cs_new_protected_nopar:Npn | +% \cs_new_protected_nopar:Npx | +% \cs_new_protected_nopar:cpn | +% \cs_new_protected_nopar:cpx % } % \begin{syntax} -% "\def_protected_long_new:NNn" <cs> <num> "{" <code> "}" +% "\cs_new_protected_nopar:Npn" <cs> <parms> \Arg{code} % \end{syntax} -% Defines a function that is both robust and may contain "\par" tokens -% in the argument(s) when called. +% Defines a function that does not expand when inside an |x| type +% expansion. % \end{function} % -% \begin{function}{\gdef_protected_long_new:NNn | -% \gdef_protected_long_new:NNx | -% \gdef_protected_long_new:cNn | -% \gdef_protected_long_new:cNx +% \begin{function}{\cs_gnew_protected_nopar:Npn | +% \cs_gnew_protected_nopar:Npx | +% \cs_gnew_protected_nopar:cpn | +% \cs_gnew_protected_nopar:cpx % } % \begin{syntax} -% "\gdef_protected_long_new:NNn" <cs> <num> "{" <code> "}" +% "\cs_gnew_protected_nopar:Npn" <cs> <parms> \Arg{code} % \end{syntax} % Global versions of the above functions. % \end{function} @@ -634,367 +776,385 @@ % % % -% Secondly comes the ones where the programmer can use delimited -% arguments. Rarely needed outside the kernel. % % -% \begin{function}{\def_new:Npn | -% \def_new:Npx | -% \def_new:cpn | -% \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 | -% \gdef_new:cpn | -% \gdef_new:Npx | -% \gdef_new:cpx -% } -% \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 | -% \def_long_new:Npx | -% \def_long_new:cpn | -% \def_long_new:cpx +% \subsection{Defining new functions using the signature} +% +% +% \begin{function}{\cs_new:Nn | +% \cs_new:Nx | +% \cs_new:cn | +% \cs_new:cx % } % \begin{syntax} -% "\def_long_new:Npn" <cs> <parms> "{" <code> "}" +% "\cs_new:Nn" <cs> \Arg{code} % \end{syntax} -% Defines a function that may contain "\par" tokens in the argument(s) -% when called. This is not allowed for normal functions. +% Defines a new function, making sure that <cs> is unused so far. The +% parameter text is automatically detected from the length of the +% function signature. If <cs> is missing a colon in its name, an error +% is raised. It is under the responsibility of the programmer to name +% the new function according to the rules laid out in the previous +% section. <code> is either passed literally or may be subject to +% expansion (under the "x" variants). +% \begin{texnote} +% Internally, these use \TeX's "\long". These forms are +% recommended for low-level definitions as experience has shown that "\par" +% tokens often turn up in programming situations that wouldn't have been +% expected. +% \end{texnote} % \end{function} % -% \begin{function}{\gdef_long_new:Npn | -% \gdef_long_new:Npx | -% \gdef_long_new:cpn | -% \gdef_long_new:cpx +% \begin{function}{\cs_gnew:Nn | +% \cs_gnew:Nx | +% \cs_gnew:cn | +% \cs_gnew:cx % } % \begin{syntax} -% "\gdef_long_new:Npn" <cs> <parms> "{" <code> "}" +% "\cs_gnew:Nn" <cs> \Arg{code} % \end{syntax} % Global versions of the above functions. % \end{function} % -% \begin{function}{\def_protected_new:Npn | -% \def_protected_new:Npx | -% \def_protected_new:cpn | -% \def_protected_new:cpx +% \begin{function}{\cs_new_nopar:Nn | +% \cs_new_nopar:Nx | +% \cs_new_nopar:cn | +% \cs_new_nopar:cx % } % \begin{syntax} -% "\def_protected_new:Npn" <cs> <parms> "{" <code> "}" +% "\cs_new_nopar:Nn" <cs> \Arg{code} % \end{syntax} -% Defines a function that does not expand when inside an |x| type -% expansion. +% Version of the above in which "\par" is not allowed to appear within the +% argument(s) of the defined functions. % \end{function} % -% \begin{function}{\gdef_protected_new:Npn | -% \gdef_protected_new:Npx | -% \gdef_protected_new:cpn | -% \gdef_protected_new:cpx +% \begin{function}{\cs_gnew_nopar:Nn | +% \cs_gnew_nopar:Nx | +% \cs_gnew_nopar:cn | +% \cs_gnew_nopar:cx % } % \begin{syntax} -% "\gdef_protected_new:Npn" <cs> <parms> "{" <code> "}" +% "\cs_gnew_nopar:Nn" <cs> \Arg{code} % \end{syntax} % Global versions of the above functions. % \end{function} % -% \begin{function}{\def_protected_long_new:Npn | -% \def_protected_long_new:Npx | -% \def_protected_long_new:cpn | -% \def_protected_long_new:cpx +% \begin{function}{\cs_new_protected:Nn | +% \cs_new_protected:Nx | +% \cs_new_protected:cn | +% \cs_new_protected:cx % } % \begin{syntax} -% "\def_protected_long_new:Npn" <cs> <parms> "{" <code> "}" +% "\cs_new_protected:Nn" <cs> \Arg{code} % \end{syntax} % Defines a function that is both robust and may contain "\par" tokens % in the argument(s) when called. % \end{function} % -% \begin{function}{\gdef_protected_long_new:Npn | -% \gdef_protected_long_new:Npx | -% \gdef_protected_long_new:cpn | -% \gdef_protected_long_new:cpx +% \begin{function}{\cs_gnew_protected:Nn | +% \cs_gnew_protected:Nx | +% \cs_gnew_protected:cn | +% \cs_gnew_protected:cx % } % \begin{syntax} -% "\gdef_protected_long_new:Npn" <cs> <parms> "{" <code> "}" +% "\cs_gnew_protected:Nn" <cs> \Arg{code} % \end{syntax} % Global versions of the above functions. % \end{function} % -% \begin{function}{\let_new:NN | -% \let_new:cN | -% \let_new:Nc | -% \let_new:cc | -% \glet_new:NN| -% \glet_new:cN| -% \glet_new:Nc| -% \glet_new:cc } +% \begin{function}{\cs_new_protected_nopar:Nn | +% \cs_new_protected_nopar:Nx | +% \cs_new_protected_nopar:cn | +% \cs_new_protected_nopar:cx +% } % \begin{syntax} -% "\let_new:NN" <cs1> <cs2> +% "\cs_new_protected_nopar:Nn" <cs> \Arg{code} % \end{syntax} -% Gives the function <cs1> the current meaning of <cs2>. Again, we may -% do this always globally. +% Defines a function that does not expand when inside an |x| type +% expansion. "\par" is not allowed in the argument(s) of the defined function. % \end{function} % -% -% -% \subsubsection{Undefining functions} -% -% \begin{function}{ \cs_gundefine:N +% \begin{function}{\cs_gnew_protected_nopar:Nn | +% \cs_gnew_protected_nopar:Nx | +% \cs_gnew_protected_nopar:cn | +% \cs_gnew_protected_nopar:cx % } % \begin{syntax} -% "\cs_gundefine:N" <cs> +% "\cs_gnew_protected_nopar:Nn" <cs> \Arg{code} % \end{syntax} -% Undefines the control sequence. +% Global versions of the above functions. % \end{function} % -% \subsubsection{Defining internal functions (no checks)} +% +% +% \subsection{Defining functions using primitive parameter text} +% % % Besides the function definitions that check whether or not their % argument is an unused function we need function definitions that % overwrite currently used definitions. The following functions are % provided for this purpose. % -% First comes the versions expecting a number to denote the number of -% arguments. -% -% \begin{function}{\def:NNn | -% \def:NNx | -% \def:cNn | -% \def:cNx | +% \begin{function}{\cs_set:Npn | +% \cs_set:Npx | +% \cs_set:cpn | +% \cs_set:cpx | % } % \begin{syntax} -% "\def:NNn" <cs> <num> "{" <code> "}" +% "\cs_set:Npn" <cs> <parms> \Arg{code} % \end{syntax} -% Like "\def_new:NNn" etc.\ but does not check the <cs> name. +% Like "\cs_set_nopar:Npn" but allows "\par" tokens in the arguments of the +% function being defined. +% \begin{texnote} +% These are equivalent to \TeX's "\long\def" and so on. These forms are +% recommended for low-level definitions as experience has shown that "\par" +% tokens often turn up in programming situations that wouldn't have been +% expected. +% \end{texnote} % \end{function} % -% \begin{function}{\gdef:NNn | -% \gdef:NNx | -% \gdef:cNn | -% \gdef:cNx | +% \begin{function}{\cs_gset:Npn | +% \cs_gset:Npx | +% \cs_gset:cpn | +% \cs_gset:cpx | % } % \begin{syntax} -% "\gdef:NNn" <cs> <num> "{" <code> "}" +% "\cs_gset:Npn" <cs> <parms> \Arg{code} % \end{syntax} -% Like "\def:NNn" but defines the <cs> globally. +% Global variant of "\cs_set:Npn". % \end{function} % -% -% \begin{function}{\def_long:NNn | -% \def_long:NNx | -% \def_long:cNn | -% \def_long:cNx | +% \begin{function}{\cs_set_nopar:Npn | +% \cs_set_nopar:Npx | +% \cs_set_nopar:cpn | +% \cs_set_nopar:cpx | % } % \begin{syntax} -% "\def_long:NNn" <cs> <num> "{" <code> "}" +% "\cs_set_nopar:Npn" <cs> <parms> \Arg{code} % \end{syntax} -% Like "\def:NNn" but allows "\par" tokens in the arguments of the -% function being defined. +% Like "\cs_new_nopar:Npn" etc.\ but does not check the <cs> name. +% \begin{texnote} +% "\cs_set_nopar:Npn" is the \LaTeX3 name for \TeX{}'s \tn{def} and +% "\cs_set_nopar:Npx" corresponds to the primitive \tn{edef}. The +% "\cs_set_nopar:cpn" function was known in \LaTeX2 as \tn{@namedef}. +% "\cs_set_nopar:cpx" has no equivalent. +% \end{texnote} % \end{function} % -% \begin{function}{\gdef_long:NNn | -% \gdef_long:NNx | -% \gdef_long:cNn | -% \gdef_long:cNx | +% \begin{function}{\cs_gset_nopar:Npn | +% \cs_gset_nopar:Npx | +% \cs_gset_nopar:cpn | +% \cs_gset_nopar:cpx | % } % \begin{syntax} -% "\gdef_long:NNn" <cs> <num> "{" <code> "}" +% "\cs_gset_nopar:Npn" <cs> <parms> \Arg{code} % \end{syntax} -% Global variant of "\def_long:NNn". +% Like "\cs_set_nopar:Npn" but defines the <cs> globally. +% \begin{texnote} +% "\cs_gset_nopar:Npn" and "\cs_gset_nopar:Npx" +% are \TeX's \tn{gdef} and \tn{xdef}. +% \end{texnote} % \end{function} % -% \begin{function}{\def_protected:NNn | -% \def_protected:cNn | -% \def_protected:NNx | -% \def_protected:cNx | +% +% \begin{function}{\cs_set_protected:Npn | +% \cs_set_protected:Npx | +% \cs_set_protected:cpn | +% \cs_set_protected:cpx | % } % \begin{syntax} -% "\def_protected:NNn" <cs> <num> "{" <code> "}" +% "\cs_set_protected:Npn" <cs> <parms> \Arg{code} % \end{syntax} % Naturally robust macro that won't expand in an |x| type argument. -% This also comes as a |long| version. If you for some reason want to -% expand it inside an |x| type expansion, prefix it with -% |\exp_after:NN \use_noop:|. +% These varieties allow |\par| tokens in the arguments of the +% function being defined. % \end{function} % -% \begin{function}{\gdef_protected:NNn | -% \gdef_protected:cNn | -% \gdef_protected:NNx | -% \gdef_protected:cNx | +% \begin{function}{\cs_gset_protected:Npn | +% \cs_gset_protected:Npx | +% \cs_gset_protected:cpn | +% \cs_gset_protected:cpx | % } % \begin{syntax} -% "\gdef_protected:NNn" <cs> <num> "{" <code> "}" +% "\cs_gset_protected:Npn" <cs> <parms> \Arg{code} % \end{syntax} % Global versions of the above functions. % \end{function} % -% \begin{function}{\def_protected_long:NNn | -% \def_protected_long:cNn | -% \def_protected_long:NNx | -% \def_protected_long:cNx | +% \begin{function}{\cs_set_protected_nopar:Npn | +% \cs_set_protected_nopar:Npx | +% \cs_set_protected_nopar:cpn | +% \cs_set_protected_nopar:cpx | % } % \begin{syntax} -% "\def_protected_long:NNn" <cs> <num> "{" <code> "}" +% "\cs_set_protected_nopar:Npn" <cs> <parms> \Arg{code} % \end{syntax} % Naturally robust macro that won't expand in an |x| type argument. -% These varieties also allow |\par| tokens in the arguments of the -% function being defined. +% If you want for some reason to expand it inside an |x| type expansion, +% prefix it with |\exp_after:wN \prg_do_nothing:|. % \end{function} % -% \begin{function}{\gdef_protected_long:NNn | -% \gdef_protected_long:cNn | -% \gdef_protected_long:NNx | -% \gdef_protected_long:cNx | +% \begin{function}{\cs_gset_protected_nopar:Npn | +% \cs_gset_protected_nopar:Npx | +% \cs_gset_protected_nopar:cpn | +% \cs_gset_protected_nopar:cpx | % } % \begin{syntax} -% "\gdef_protected_long:NNn" <cs> <num> "{" <code> "}" +% "\cs_gset_protected_nopar:Npn" <cs> <parms> \Arg{code} % \end{syntax} % Global versions of the above functions. % \end{function} % -% Secondly the ones that use the primitive parameter build-up: % -% \begin{function}{\def:Npn | -% \def:Npx | -% \def:cpn | -% \def:cpx | +% \subsection{Defining functions using the signature (no checks)} +% +% As above but now detecting the parameter text from inspecting the +% signature. +% +% \begin{function}{\cs_set:Nn | +% \cs_set:Nx | +% \cs_set:cn | +% \cs_set:cx | % } % \begin{syntax} -% "\def:Npn" <cs> <parms> "{" <code> "}" +% "\cs_set:Nn" <cs> \Arg{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} +% Like "\cs_set_nopar:Nn" but allows "\par" tokens in the arguments of the +% function being defined. % \end{function} % -% \begin{function}{\gdef:Npn | -% \gdef:Npx | -% \gdef:cpn | -% \gdef:cpx | +% \begin{function}{\cs_gset:Nn | +% \cs_gset:Nx | +% \cs_gset:cn | +% \cs_gset:cx | % } % \begin{syntax} -% "\gdef:Npn" <cs> <parms> "{" <code> "}" +% "\cs_gset:Nn" <cs> \Arg{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} +% Global variant of "\cs_set:Nn". % \end{function} % -% -% \begin{function}{\def_long:Npn | -% \def_long:Npx | -% \def_long:cpn | -% \def_long:cpx | +% \begin{function}{\cs_set_nopar:Nn | +% \cs_set_nopar:Nx | +% \cs_set_nopar:cn | +% \cs_set_nopar:cx | % } % \begin{syntax} -% "\def_long:Npn" <cs> <parms> "{" <code> "}" +% "\cs_set_nopar:Nn" <cs> \Arg{code} % \end{syntax} -% Like "\def:Npn" but allows "\par" tokens in the arguments of the -% function being defined. +% Like "\cs_new_nopar:Nn" etc.\ but does not check the <cs> name. % \end{function} % -% \begin{function}{\gdef_long:Npn | -% \gdef_long:Npx | -% \gdef_long:cpn | -% \gdef_long:cpx | +% \begin{function}{\cs_gset_nopar:Nn | +% \cs_gset_nopar:Nx | +% \cs_gset_nopar:cn | +% \cs_gset_nopar:cx | % } % \begin{syntax} -% "\gdef_long:Npn" <cs> <parms> "{" <code> "}" +% "\cs_gset_nopar:Nn" <cs> \Arg{code} % \end{syntax} -% Global variant of "\def_long:Npn". +% Like "\cs_set_nopar:Nn" but defines the <cs> globally. % \end{function} % -% \begin{function}{\def_protected:Npn | -% \def_protected:cpn | -% \def_protected:Npx | -% \def_protected:cpx | +% \begin{function}{\cs_set_protected:Nn | +% \cs_set_protected:cn | +% \cs_set_protected:Nx | +% \cs_set_protected:cx | % } % \begin{syntax} -% "\def_protected:Npn" <cs> <parms> "{" <code> "}" +% "\cs_set_protected:Nn" <cs> \Arg{code} % \end{syntax} % Naturally robust macro that won't expand in an |x| type argument. -% This also comes as a |long| version. If you for some reason want to -% expand it inside an |x| type expansion, prefix it with -% |\exp_after:NN \use_noop:|. +% These varieties also allow |\par| tokens in the arguments of the +% function being defined. % \end{function} % -% \begin{function}{\gdef_protected:Npn | -% \gdef_protected:cpn | -% \gdef_protected:Npx | -% \gdef_protected:cpx | +% \begin{function}{\cs_gset_protected:Nn | +% \cs_gset_protected:cn | +% \cs_gset_protected:Nx | +% \cs_gset_protected:cx | % } % \begin{syntax} -% "\gdef_protected:Npn" <cs> <parms> "{" <code> "}" +% "\cs_gset_protected:Nn" <cs> \Arg{code} % \end{syntax} % Global versions of the above functions. % \end{function} % -% \begin{function}{\def_protected_long:Npn | -% \def_protected_long:cpn | -% \def_protected_long:Npx | -% \def_protected_long:cpx | +% \begin{function}{\cs_set_protected_nopar:Nn | +% \cs_set_protected_nopar:cn | +% \cs_set_protected_nopar:Nx | +% \cs_set_protected_nopar:cx | % } % \begin{syntax} -% "\def_protected_long:Npn" <cs> <parms> "{" <code> "}" +% "\cs_set_protected_nopar:Nn" <cs> \Arg{code} % \end{syntax} % Naturally robust macro that won't expand in an |x| type argument. -% These varieties also allow |\par| tokens in the arguments of the -% function being defined. +% This also comes as a |long| version. If you for some reason want to +% expand it inside an |x| type expansion, prefix it with +% |\exp_after:wN \prg_do_nothing:|. % \end{function} % -% \begin{function}{\gdef_protected_long:Npn | -% \gdef_protected_long:cpn | -% \gdef_protected_long:Npx | -% \gdef_protected_long:cpx | +% \begin{function}{\cs_gset_protected_nopar:Nn | +% \cs_gset_protected_nopar:cn | +% \cs_gset_protected_nopar:Nx | +% \cs_gset_protected_nopar:cx | % } % \begin{syntax} -% "\gdef_protected_long:Npn" <cs> <parms> "{" <code> "}" +% "\cs_gset_protected_nopar:Nn" <cs> \Arg{code} % \end{syntax} % Global versions of the above functions. % \end{function} % % % -% \begin{function}{\let:NN | -% \let:cN | -% \let:Nc | -% \let:cc | -% \glet:NN | -% \glet:cN | -% \glet:Nc | -% \glet:cc -% } +% \subsection{Undefining functions} +% +% \begin{function}{ \cs_gundefine:N } +% \begin{syntax} +% "\cs_gundefine:N" <cs> +% \end{syntax} +% Undefines the control sequence globally. +% \end{function} +% +% +% \subsection{Copying function definitions} +% +% \begin{function}{ \cs_new_eq:NN | +% \cs_new_eq:cN | +% \cs_new_eq:Nc | +% \cs_new_eq:cc | +% \cs_gnew_eq:NN | +% \cs_gnew_eq:cN | +% \cs_gnew_eq:Nc | +% \cs_gnew_eq:cc } +% \begin{syntax} +% "\cs_new_eq:NN" <cs1> <cs2> +% \end{syntax} +% Gives the function <cs1> locally or globally the current meaning of <cs2>. +% If <cs1> already exists then an error is called. +% \end{function} +% +% +% \begin{function}{\cs_set_eq:NN | +% \cs_set_eq:cN | +% \cs_set_eq:Nc | +% \cs_set_eq:cc | +% \cs_gset_eq:NN | +% \cs_gset_eq:cN | +% \cs_gset_eq:Nc | +% \cs_gset_eq:cc } % \begin{syntax} -% "\let:cN" <cs1> <cs2> +% "\cs_set_eq: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{function}{\cs_set_eq:NwN} % \begin{syntax} -% "\let:NwN" <cs1> <cs2> -% "\let:NwN" <cs1> "=" <cs2> +% "\cs_set_eq:NwN" <cs1> <cs2> +% "\cs_set_eq: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 @@ -1002,67 +1162,109 @@ % <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}. +% "\cs_set_eq:NwN" is the \LaTeX3 name for \TeX{}'s \tn{let}. % \end{texnote} % \end{function} % +% \subsection{Internal functions} % -% \subsection{Defining test functions} % +% \begin{function}{ \pref_global:D | +% \pref_long:D | +% \pref_protected:D } +% \begin{syntax} +% "\pref_global:D" "\cs_set_nopar: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, +% and "\pref_protected:D" makes the definition robust in "\write"s etc. % -% \begin{function}{ -% \def_test_function:npn | -% \def_long_test_function:npn | -% \def_test_function_new:npn | -% \def_long_test_function_new:npn | -% } -% \begin{syntax} -% "\def_test_function_new:npn" "{"name"}" <parms> "{"<test>"}" -% \end{syntax} -% Define all the common test cases for a simple test to reduce the -% risk of typos. As an example here's how we defined the functions -% "\cs_free:cTF", "\cs_free:cT" and "\cs_free:cF". You just have to -% fill in the test. -% \begin{verbatim} -% \def_test_function:npn{cs_free:c} #1 { -% \exp_after:NN \if_meaning:NN \cs:w#1\cs_end: \scan_stop:} -% \end{verbatim} -% Be careful not to use this function inside some primitive -% conditional as \TeX\ will most likely get confused because of the -% unmatched conditionals. +% None of these internal functions should be used by a programmer since +% the necessary combinations are all available as separate function, +% e.g., "\cs_set:Npn" is internally implemented as "\pref_long:D" +% "\cs_set_nopar:Npn". +% \begin{texnote} +% These prefixes are the primitives \tn{global}, \tn{long}, and +% \tn{protected}. The \tn{outer} prefix isn't used at all within \LaTeX3 +% because \ldots (it causes more hassle than it's worth? It's nevery proved +% useful in any meaningful way?) +% \end{texnote} % \end{function} % +% \section{The innards of a function} % -% \subsection{The innards of a function} -% -% \begin{function}{\cs_to_str:N} +% \begin{function}{\cs_to_str:N / (EXP)} % \begin{syntax} % "\cs_to_str:N" <cs> % \end{syntax} -% This function return the name of <cs> as a sequence of letters with +% This function returns the name of <cs> as a sequence of letters with % the escape character removed. % \end{function} % -% \begin{function}{\token_to_string:N} +% \begin{function}{\token_to_str:N / (EXP) | \token_to_str:c / (EXP)} % \begin{syntax} -% "\token_to_string:N" <arg> +% "\token_to_str:N" <arg> % \end{syntax} % This function return the name of <arg> as a sequence of letters % including the escape character. +% \begin{texnote} +% This is \TeX's \tn{string}. +% \end{texnote} % \end{function} % -% \begin{function}{\token_to_meaning:N} +% \begin{function}{\token_to_meaning:N / (EXP)} % \begin{syntax} % "\token_to_meaning:N" <arg> % \end{syntax} % This function returns the type and definition of <arg> as a sequence % of letters. +% \begin{texnote} +% This is \TeX's \tn{meaning}. +% \end{texnote} +% \end{function} +% +% +% \begin{function}{\cs_get_function_name:N / (EXP) | +% \cs_get_function_signature:N / (EXP)} +% \begin{syntax} +% "\cs_get_function_name:N" "\"<fn>":"<args> +% \end{syntax} +% The "name" variant strips off the leading escape character and the +% trailing argument specification (including the colon) to return +% <fn>. The "signature" variants does the same but returns the +% signature <args> instead. % \end{function} % +% +% \begin{function}{\cs_split_function:NN / (EXP)} +% \begin{syntax} +% "\cs_split_function:NN" "\"<fn>":"<args> <post process> +% \end{syntax} +% Strips off the leading escape character, splits off the signature +% without the colon, informs whether or not a colon was present and +% then prefixes these results with <post process>, i.e., <post +% process>\Arg{name}\Arg{signature}\meta{true}/\meta{false}. For +% example, "\cs_get_function_name:N" is nothing more than +% "\cs_split_function:NN" "\"<fn>":"<args> "\use_i:nnn". +% \end{function} +% +% +% \begin{function}{\cs_get_arg_count_from_signature:N / (EXP)} +% \begin{syntax} +% "\cs_get_arg_count_from_signature:N" "\"<fn>":"<args> +% \end{syntax} +% Returns the number of chars in <args>, signifying the number of arguments +% that the function uses. +% \end{function} +% +% % Other functions regarding arbitrary tokens can be found in the % \textsf{l3token} module. % -% \subsection{Grouping and scanning} +% \section{Grouping and scanning} % % \begin{function}{\scan_stop:} % \begin{syntax} @@ -1087,32 +1289,52 @@ % \end{texnote} % \end{function} % +% \begin{function}{\group_execute_after:N} +% \begin{syntax} +% "\group_execute_after:N" <token> +% \end{syntax} +% Adds <token> to the list of tokens to be inserted after the +% current group ends (through an explicit or implicit "\group_end:"). +% \begin{texnote} +% This is \TeX's \tn{aftergroup}. +% \end{texnote} +% \end{function} +% % -% \subsection{Engine specific definitions} +% \section{Checking the engine} +% +% \begin{function}{\xetex_if_engine: / (TF)(EXP)} +% \begin{syntax} +% "\xetex_if_engine:TF" \Arg{true code} \Arg{false code} +% \end{syntax} +% This function detects if we're running a Xe\TeX-based format. +% \end{function} % -% \begin{function}{\engine_if_aleph:TF} +% \begin{function}{\luatex_if_engine: / (TF)(EXP)} % \begin{syntax} -% "\engine_if_aleph:TF" "{"<true code>"}" "{"<false code>"}" +% "\luatex_if_engine:TF" \Arg{true code} \Arg{false code} % \end{syntax} -% This function detects if we're running an Aleph based format. This -% is particularly useful when allocating registers. +% This function detects if we're running a Lua\TeX-based format. % \end{function} % +% \begin{variable}{\c_xetex_is_engine_bool|\c_luatex_is_engine_bool} +% Boolean variables used for the above functions. +% \end{variable} % +% \end{documentation} % -% \StopEventually{} +% \begin{implementation} % +% \section{\pkg{l3basics} implementation} % -% \subsection{The Implementation} -% We start by ensuring that the required packages are loaded. We need -% \textsf{l3names} to get things going but we actually need it very -% early on, so it is loaded at the very top of this file. Also, most -% of the code below won't run until \textsf{l3expan} has been +% We need \textsf{l3names} to get things going but we actually need it very +% early on, so it is loaded at the very top of the file \file{l3basics.dtx}. +% Also, most of the code below won't run until \textsf{l3expan} has been % loaded. % -% \subsubsection{Renaming some \TeX{} primitives (again)} +% \subsection{Renaming some \TeX{} primitives (again)} % -% \begin{macro}{\let:NwN} +% \begin{macro}{\cs_set_eq:NwN} % Having given all the tex primitives a consistent name, we need to % give sensible names to the ones we actually want to use. % These will be defined as needed in the appropriate modules, but @@ -1120,30 +1342,39 @@ % 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>\ProvidesExplPackage -%<package> {\filename}{\filedate}{\fileversion}{\filedescription} +%<*package> +\ProvidesExplPackage + {\filename}{\filedate}{\fileversion}{\filedescription} +\package_check_loaded_expl: +%</package> %<*initex|package> -\tex_let:D \let:NwN \tex_let:D +\tex_let:D \cs_set_eq:NwN \tex_let:D % \end{macrocode} % \end{macro} % \begin{macro}{\if_true:} % \begin{macro}{\if_false:} +% \begin{macro}{\or:} % \begin{macro}{\else:} % \begin{macro}{\fi:} % \begin{macro}{\reverse_if:N} % \begin{macro}{\if:w} +% \begin{macro}{\if_bool:N} +% \begin{macro}{\if_predicate:w} % \begin{macro}{\if_charcode:w} % \begin{macro}{\if_catcode:w} % Then some conditionals. % \begin{macrocode} -\let:NwN \if_true: \tex_iftrue:D -\let:NwN \if_false: \tex_iffalse:D -\let:NwN \else: \tex_else:D -\let:NwN \fi: \tex_fi:D -\let:NwN \reverse_if:N \etex_unless:D -\let:NwN \if:w \tex_if:D -\let:NwN \if_charcode:w \tex_if:D -\let:NwN \if_catcode:w \tex_ifcat:D +\cs_set_eq:NwN \if_true: \tex_iftrue:D +\cs_set_eq:NwN \if_false: \tex_iffalse:D +\cs_set_eq:NwN \or: \tex_or:D +\cs_set_eq:NwN \else: \tex_else:D +\cs_set_eq:NwN \fi: \tex_fi:D +\cs_set_eq:NwN \reverse_if:N \etex_unless:D +\cs_set_eq:NwN \if:w \tex_if:D +\cs_set_eq:NwN \if_bool:N \tex_ifodd:D +\cs_set_eq:NwN \if_predicate:w \tex_ifodd:D +\cs_set_eq:NwN \if_charcode:w \tex_if:D +\cs_set_eq:NwN \if_catcode:w \tex_ifcat:D % \end{macrocode} % \end{macro} % \end{macro} @@ -1153,28 +1384,26 @@ % \end{macro} % \end{macro} % \end{macro} -% \begin{macro}{\if_meaning:NN} -% \begin{macro}{\if_token_eq:NN} -% \begin{macro}{\if_cs_meaning_eq:NN} -% Some different names for |\ifx|.\footnote{MH: Clean up at some point} -% \begin{macrocode} -\let:NwN \if_meaning:NN \tex_ifx:D -\let:NwN \if_token_eq:NN \tex_ifx:D -\let:NwN \if_cs_meaning_eq:NN\tex_ifx:D -% \end{macrocode} % \end{macro} % \end{macro} % \end{macro} +% +% \begin{macro}{\if_meaning:w} +% \begin{macrocode} +\cs_set_eq:NwN \if_meaning:w \tex_ifx:D +% \end{macrocode} +% \end{macro} +% % \begin{macro}{\if_mode_math:} % \begin{macro}{\if_mode_horizontal:} % \begin{macro}{\if_mode_vertical:} % \begin{macro}{\if_mode_inner:} % \TeX{} lets us detect some if its modes. % \begin{macrocode} -\let:NwN \if_mode_math: \tex_ifmmode:D -\let:NwN \if_mode_horizontal:\tex_ifhmode:D -\let:NwN \if_mode_vertical: \tex_ifvmode:D -\let:NwN \if_mode_inner: \tex_ifinner:D +\cs_set_eq:NwN \if_mode_math: \tex_ifmmode:D +\cs_set_eq:NwN \if_mode_horizontal: \tex_ifhmode:D +\cs_set_eq:NwN \if_mode_vertical: \tex_ifvmode:D +\cs_set_eq:NwN \if_mode_inner: \tex_ifinner:D % \end{macrocode} % \end{macro} % \end{macro} @@ -1183,29 +1412,30 @@ % \begin{macro}{\if_cs_exist:N} % \begin{macro}{\if_cs_exist:w} % \begin{macrocode} -\let:NwN \if_cs_exist:N \etex_ifdefined:D -\let:NwN \if_cs_exist:w \etex_ifcsname:D +\cs_set_eq:NwN \if_cs_exist:N \etex_ifdefined:D +\cs_set_eq:NwN \if_cs_exist:w \etex_ifcsname:D % \end{macrocode} % \end{macro} % \end{macro} % -% \begin{macro}{\exp_after:NN} +% \begin{macro}{\exp_after:wN} % \begin{macro}{\exp_not:N} % \begin{macro}{\exp_not:n} % The three |\exp_| functions are used in the \textsf{l3expan} module % where they are described. % \begin{macrocode} -\let:NwN \exp_after:NN \tex_expandafter:D -\let:NwN \exp_not:N \tex_noexpand:D -\let:NwN \exp_not:n \etex_unexpanded:D +\cs_set_eq:NwN \exp_after:wN \tex_expandafter:D +\cs_set_eq:NwN \exp_not:N \tex_noexpand:D +\cs_set_eq:NwN \exp_not:n \etex_unexpanded:D % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % -% \begin{macro}{\io_put_deferred:Nx} +% \begin{macro}{\iow_shipout_x:Nn} % \begin{macro}{\token_to_meaning:N} -% \begin{macro}{\token_to_string:N} +% \begin{macro}{\token_to_str:N} +% \begin{macro}{\token_to_str:c} % \begin{macro}{\cs:w} % \begin{macro}{\cs_end:} % \begin{macro}{\cs_meaning:N} @@ -1213,15 +1443,16 @@ % \begin{macro}{\cs_show:N} % \begin{macro}{\cs_show:c} % \begin{macrocode} -\let:NwN \io_put_deferred:Nx \tex_write:D -\let:NwN \token_to_meaning:N \tex_meaning:D -\let:NwN \token_to_string:N \tex_string:D -\let:NwN \cs:w \tex_csname:D -\let:NwN \cs_end: \tex_endcsname:D -\let:NwN \cs_meaning:N \tex_meaning:D -\tex_def:D \cs_meaning:c #1{\exp_after:NN\cs_meaning:N\cs:w #1\cs_end:} -\let:NwN \cs_show:N \tex_show:D -\tex_def:D \cs_show:c #1{\exp_after:NN\cs_show:N\cs:w #1\cs_end:} +\cs_set_eq:NwN \iow_shipout_x:Nn \tex_write:D +\cs_set_eq:NwN \token_to_meaning:N \tex_meaning:D +\cs_set_eq:NwN \token_to_str:N \tex_string:D +\cs_set_eq:NwN \cs:w \tex_csname:D +\cs_set_eq:NwN \cs_end: \tex_endcsname:D +\cs_set_eq:NwN \cs_meaning:N \tex_meaning:D +\tex_def:D \cs_meaning:c {\exp_args:Nc\cs_meaning:N} +\cs_set_eq:NwN \cs_show:N \tex_show:D +\tex_def:D \cs_show:c {\exp_args:Nc\cs_show:N} +\tex_def:D \token_to_str:c {\exp_args:Nc\token_to_str:N} % \end{macrocode} % \end{macro} % \end{macro} @@ -1232,6 +1463,8 @@ % \end{macro} % \end{macro} % \end{macro} +% \end{macro} +% % \begin{macro}{\scan_stop:} % \begin{macro}{\group_begin:} % \begin{macro}{\group_end:} @@ -1239,70 +1472,69 @@ % versions that are safe inside alignments. These safe versions are % defined in the \textsf{l3prg} module. % \begin{macrocode} -\let:NwN \scan_stop: \tex_relax:D -\let:NwN \group_begin: \tex_begingroup:D -\let:NwN \group_end: \tex_endgroup:D +\cs_set_eq:NwN \scan_stop: \tex_relax:D +\cs_set_eq:NwN \group_begin: \tex_begingroup:D +\cs_set_eq:NwN \group_end: \tex_endgroup:D % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \begin{macro}{\group_execute_after:N} % \begin{macrocode} -\let:NwN \group_execute_after:N \tex_aftergroup:D +\cs_set_eq:NwN \group_execute_after:N \tex_aftergroup:D % \end{macrocode} % \end{macro} -% \begin{macro}{\the_internal:D} % \begin{macro}{\pref_global:D} % \begin{macro}{\pref_long:D} % \begin{macro}{\pref_protected:D} -% These following names are temporary and should be removed as soon -% as possible (April 1998). -% \begin{macrocode} -\let:NwN \the_internal:D \tex_the:D -\let:NwN \pref_global:D \tex_global:D -% \end{macrocode} -% "\pref_long:D" has been documented for years but didn't exist\dots{} -% Added it and the robustness prefix. % \begin{macrocode} -\let:NwN \pref_long:D \tex_long:D -\let:NwN \pref_protected:D \etex_protected:D +\cs_set_eq:NwN \pref_global:D \tex_global:D +\cs_set_eq:NwN \pref_long:D \tex_long:D +\cs_set_eq:NwN \pref_protected:D \etex_protected:D % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} -% \end{macro} % % % -% \subsubsection {Defining functions} +% \subsection {Defining functions} % % % We start by providing functions for the typical definition % functions. First the local ones. % -% \begin{macro}{\def:Npn} -% \begin{macro}{\def:Npx} -% \begin{macro}{\def_long:Npn} -% \begin{macro}{\def_long:Npx} -% \begin{macro}{\def_protected:Npn} -% \begin{macro}{\def_protected:Npx} -% \begin{macro}{\def_protected_long:Npn} -% \begin{macro}{\def_protected_long:Npx} +% \begin{macro}{\cs_set_nopar:Npn} +% \begin{macro}{\cs_set_nopar:Npx} +% \begin{macro}{\cs_set:Npn} +% \begin{macro}{\cs_set:Npx} +% \begin{macro}{\cs_set_protected_nopar:Npn} +% \begin{macro}{\cs_set_protected_nopar:Npx} +% \begin{macro}{\cs_set_protected:Npn} +% \begin{macro}{\cs_set_protected:Npx} % All assignment functions in \LaTeX3 should be naturally robust; % after all, the \TeX\ primitives for assignments are and it can be % a cause of problems if others aren't. % \begin{macrocode} -\let:NwN \def:Npn \tex_def:D -\let:NwN \def:Npx \tex_edef:D -\pref_protected:D \def:Npn \def_long:Npn {\pref_long:D \def:Npn} -\pref_protected:D \def:Npn \def_long:Npx {\pref_long:D \def:Npx} -\pref_protected:D \def:Npn \def_protected:Npn {\pref_protected:D \def:Npn} -\pref_protected:D \def:Npn \def_protected:Npx {\pref_protected:D \def:Npx} -\def_protected:Npn \def_protected_long:Npn { - \pref_protected:D \pref_long:D \def:Npn +\cs_set_eq:NwN \cs_set_nopar:Npn \tex_def:D +\cs_set_eq:NwN \cs_set_nopar:Npx \tex_edef:D +\pref_protected:D \cs_set_nopar:Npn \cs_set:Npn { + \pref_long:D \cs_set_nopar:Npn +} +\pref_protected:D \cs_set_nopar:Npn \cs_set:Npx { + \pref_long:D \cs_set_nopar:Npx +} +\pref_protected:D \cs_set_nopar:Npn \cs_set_protected_nopar:Npn { + \pref_protected:D \cs_set_nopar:Npn +} +\pref_protected:D \cs_set_nopar:Npn \cs_set_protected_nopar:Npx { + \pref_protected:D \cs_set_nopar:Npx +} +\cs_set_protected_nopar:Npn \cs_set_protected:Npn { + \pref_protected:D \pref_long:D \cs_set_nopar:Npn } -\def_protected:Npn \def_protected_long:Npx { - \pref_protected:D \pref_long:D \def:Npx +\cs_set_protected_nopar:Npn \cs_set_protected:Npx { + \pref_protected:D \pref_long:D \cs_set_nopar:Npx } % \end{macrocode} % \end{macro} @@ -1314,27 +1546,35 @@ % \end{macro} % \end{macro} % -% \begin{macro}{\gdef:Npn} -% \begin{macro}{\gdef:Npx} -% \begin{macro}{\gdef_long:Npn} -% \begin{macro}{\gdef_long:Npx} -% \begin{macro}{\gdef_protected:Npn} -% \begin{macro}{\gdef_protected:Npx} -% \begin{macro}{\gdef_protected_long:Npn} -% \begin{macro}{\gdef_protected_long:Npx} +% \begin{macro}{\cs_gset_nopar:Npn} +% \begin{macro}{\cs_gset_nopar:Npx} +% \begin{macro}{\cs_gset:Npn} +% \begin{macro}{\cs_gset:Npx} +% \begin{macro}{\cs_gset_protected_nopar:Npn} +% \begin{macro}{\cs_gset_protected_nopar:Npx} +% \begin{macro}{\cs_gset_protected:Npn} +% \begin{macro}{\cs_gset_protected:Npx} % Global versions of the above functions. % \begin{macrocode} -\let:NwN \gdef:Npn \tex_gdef:D -\let:NwN \gdef:Npx \tex_xdef:D -\def_protected:Npn \gdef_long:Npn {\pref_long:D \gdef:Npn} -\def_protected:Npn \gdef_long:Npx {\pref_long:D \gdef:Npx} -\def_protected:Npn \gdef_protected:Npn {\pref_protected:D \gdef:Npn} -\def_protected:Npn \gdef_protected:Npx {\pref_protected:D \gdef:Npx} -\def_protected:Npn \gdef_protected_long:Npn { - \pref_protected:D \pref_long:D \gdef:Npn +\cs_set_eq:NwN \cs_gset_nopar:Npn \tex_gdef:D +\cs_set_eq:NwN \cs_gset_nopar:Npx \tex_xdef:D +\cs_set_protected_nopar:Npn \cs_gset:Npn { + \pref_long:D \cs_gset_nopar:Npn } -\def_protected:Npn \gdef_protected_long:Npx { - \pref_protected:D \pref_long:D \gdef:Npx +\cs_set_protected_nopar:Npn \cs_gset:Npx { + \pref_long:D \cs_gset_nopar:Npx +} +\cs_set_protected_nopar:Npn \cs_gset_protected_nopar:Npn { + \pref_protected:D \cs_gset_nopar:Npn +} +\cs_set_protected_nopar:Npn \cs_gset_protected_nopar:Npx { + \pref_protected:D \cs_gset_nopar:Npx +} +\cs_set_protected_nopar:Npn \cs_gset_protected:Npn { + \pref_protected:D \pref_long:D \cs_gset_nopar:Npn +} +\cs_set_protected_nopar:Npn \cs_gset_protected:Npx { + \pref_protected:D \pref_long:D \cs_gset_nopar:Npx } % \end{macrocode} % \end{macro} @@ -1346,34 +1586,666 @@ % \end{macro} % \end{macro} % -% \subsubsection{Predicate implementation} % +% +% \subsection{Selecting tokens} +% +% \begin{macro}{\use:c} +% This macro grabs its argument and returns a csname from it. +% \begin{macrocode} +\cs_set:Npn \use:c #1 { \cs:w#1\cs_end: } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\use:n} +% \begin{macro}{\use:nn} +% \begin{macro}{\use:nnn} +% \begin{macro}{\use:nnnn} +% These macro grabs its arguments and returns it back to the input +% (with outer braces removed). "\use:n" is defined earlier for bootstrapping. +% \begin{macrocode} +\cs_set:Npn \use:n #1 {#1} +\cs_set:Npn \use:nn #1#2 {#1#2} +\cs_set:Npn \use:nnn #1#2#3 {#1#2#3} +\cs_set:Npn \use:nnnn #1#2#3#4 {#1#2#3#4} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\use_i:nn} +% \begin{macro}{\use_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:wN| |\use_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_bool| syntax is used. +% \begin{macrocode} +\cs_set:Npn \use_i:nn #1#2 {#1} +\cs_set:Npn \use_ii:nn #1#2 {#2} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% +% \begin{macro}{\use_i:nnn} +% \begin{macro}{\use_ii:nnn} +% \begin{macro}{\use_iii:nnn} +% \begin{macro}{\use_i:nnnn} +% \begin{macro}{\use_ii:nnnn} +% \begin{macro}{\use_iii:nnnn} +% \begin{macro}{\use_iv:nnnn} +% \begin{macro}{\use_i_ii:nnn} +% We also need something for picking up arguments from a longer +% list. +% \begin{macrocode} +\cs_set:Npn \use_i:nnn #1#2#3{#1} +\cs_set:Npn \use_ii:nnn #1#2#3{#2} +\cs_set:Npn \use_iii:nnn #1#2#3{#3} +\cs_set:Npn \use_i:nnnn #1#2#3#4{#1} +\cs_set:Npn \use_ii:nnnn #1#2#3#4{#2} +\cs_set:Npn \use_iii:nnnn #1#2#3#4{#3} +\cs_set:Npn \use_iv:nnnn #1#2#3#4{#4} +\cs_set:Npn \use_i_ii:nnn #1#2#3{#1#2} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\use_none_delimit_by_q_nil:w} +% \begin{macro}{\use_none_delimit_by_q_stop:w} +% \begin{macro}{\use_none_delimit_by_q_recursion_stop:w} +% Functions that gobble everything until they see either |\q_nil| or +% |\q_stop| resp. +% \begin{macrocode} +\cs_set:Npn \use_none_delimit_by_q_nil:w #1\q_nil{} +\cs_set:Npn \use_none_delimit_by_q_stop:w #1\q_stop{} +\cs_set:Npn \use_none_delimit_by_q_recursion_stop:w #1 \q_recursion_stop {} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\use_i_delimit_by_q_nil:nw} +% \begin{macro}{\use_i_delimit_by_q_stop:nw} +% \begin{macro}{\use_i_delimit_by_q_recursion_stop:nw} +% Same as above but execute first argument after gobbling. Very +% useful when you need to skip the rest of a mapping sequence but +% want an easy way to control what should be expanded next. +% \begin{macrocode} +\cs_set:Npn \use_i_delimit_by_q_nil:nw #1#2\q_nil{#1} +\cs_set:Npn \use_i_delimit_by_q_stop:nw #1#2\q_stop{#1} +\cs_set:Npn \use_i_delimit_by_q_recursion_stop:nw #1#2 \q_recursion_stop {#1} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\use_i_after_fi:nw} +% \begin{macro}{\use_i_after_else:nw} +% \begin{macro}{\use_i_after_or:nw} +% \begin{macro}{\use_i_after_orelse:nw} +% Returns the first argument after ending the conditional. +% \begin{macrocode} +\cs_set:Npn \use_i_after_fi:nw #1\fi:{\fi: #1} +\cs_set:Npn \use_i_after_else:nw #1\else:#2\fi:{\fi: #1} +\cs_set:Npn \use_i_after_or:nw #1\or: #2\fi: {\fi:#1} +\cs_set:Npn \use_i_after_orelse:nw #1 #2#3\fi: {\fi:#1} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \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} +% \begin{macro}{\use_none:nnnnn} +% \begin{macro}{\use_none:nnnnnn} +% \begin{macro}{\use_none:nnnnnnn} +% \begin{macro}{\use_none:nnnnnnnn} +% \begin{macro}{\use_none:nnnnnnnnn} +% To gobble tokens from the input we use a standard naming +% convention: the number of tokens gobbled is given by the number of +% |n|'s following the |:| in the name. Although defining +% |\use_none:nnn| and above as separate calls of |\use_none:n| and +% |\use_none:nn| is slightly faster, this is very non-intuitive to +% the programmer who will assume that expanding such a function once +% will take care of gobbling all the tokens in one go. +% \begin{macrocode} +\cs_set:Npn \use_none:n #1{} +\cs_set:Npn \use_none:nn #1#2{} +\cs_set:Npn \use_none:nnn #1#2#3{} +\cs_set:Npn \use_none:nnnn #1#2#3#4{} +\cs_set:Npn \use_none:nnnnn #1#2#3#4#5{} +\cs_set:Npn \use_none:nnnnnn #1#2#3#4#5#6{} +\cs_set:Npn \use_none:nnnnnnn #1#2#3#4#5#6#7{} +\cs_set:Npn \use_none:nnnnnnnn #1#2#3#4#5#6#7#8{} +\cs_set:Npn \use_none:nnnnnnnnn #1#2#3#4#5#6#7#8#9{} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \subsection{Expansion control from l3expan} +% +% \begin{macro}{\exp_args:Nc} +% Moved here for now as it is going to be used right away. +% \begin{macrocode} +\cs_set:Npn \exp_args:Nc #1#2{\exp_after:wN#1\cs:w#2\cs_end:} +% \end{macrocode} +% \end{macro} +% +% \subsection{Conditional processing and definitions} +% +% Underneath any predicate function (|_p|) or other conditional forms +% (|TF|, etc.) is a built-in logic saying that it after all of the +% testing and processing must return the \meta{state} this leaves +% \TeX\ in. Therefore, a simple user interface could be something like +% \begin{verbatim} +% \if_meaning:w #1#2 \prg_return_true: \else: +% \if_meaning:w #1#3 \prg_return_true: \else: +% \prg_return_false: +% \fi: \fi: +% \end{verbatim} +% Usually, a \TeX\ programmer would have to insert a number of +% |\exp_after:wN|s to ensure the state value is returned at exactly +% the point where the last conditional is finished. However, that +% obscures the code and forces the \TeX\ programmer to prove that +% he/she knows the $2^{n}-1$ table. We therefore provide the simpler +% interface. +% +% \begin{macro}{\prg_return_true:} +% \begin{macro}{\prg_return_false:} +% These break statements put \TeX\ in a \m{true} or \m{false} state. +% The idea is that the expansion of |\tex_romannumeral:D \c_zero| is +% \m{null} so we set off a |\tex_romannumeral:D|. It will on its +% way expand any |\else:| or |\fi:| that are waiting to be discarded +% anyway before finally arriving at the |\c_zero| we will place +% right after the conditional. After this expansion has terminated, +% we issue either |\if_true:| or |\if_false:| to put \TeX\ in the +% correct state. +% \begin{macrocode} +\cs_set:Npn \prg_return_true: { \exp_after:wN\if_true:\tex_romannumeral:D } +\cs_set:Npn \prg_return_false: {\exp_after:wN\if_false:\tex_romannumeral:D } +% \end{macrocode} +% An extended state space could instead utilize |\tex_ifcase:D|: +% \begin{verbatim} +% \cs_set:Npn \prg_return_true: { +% \exp_after:wN\tex_ifcase:D \exp_after:wN \c_zero \tex_romannumeral:D +% } +% \cs_set:Npn \prg_return_false: { +% \exp_after:wN\tex_ifcase:D \exp_after:wN \c_one \tex_romannumeral:D +% } +% \cs_set:Npn \prg_return_error: { +% \exp_after:wN\tex_ifcase:D \exp_after:wN \c_two \tex_romannumeral:D +% } +% \end{verbatim} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\prg_set_conditional:Npnn,\prg_new_conditional:Npnn, +% \prg_set_protected_conditional:Npnn,\prg_new_protected_conditional:Npnn} +% The user functions for the types using parameter text from the +% programmer. Call aux function to grab parameters, split the base +% function into name and signature and then use, e.g., |\cs_set:Npn| +% to define it with. +% \begin{macrocode} +\cs_set:Npn \prg_set_conditional:Npnn #1{ + \prg_get_parm_aux:nw{ + \cs_split_function:NN #1 \prg_generate_conditional_aux:nnNNnnnn + \cs_set:Npn {parm} + } +} +\cs_set:Npn \prg_new_conditional:Npnn #1{ + \prg_get_parm_aux:nw{ + \cs_split_function:NN #1 \prg_generate_conditional_aux:nnNNnnnn + \cs_new:Npn {parm} + } +} +\cs_set:Npn \prg_set_protected_conditional:Npnn #1{ + \prg_get_parm_aux:nw{ + \cs_split_function:NN #1 \prg_generate_conditional_aux:nnNNnnnn + \cs_set_protected:Npn {parm} + } +} +\cs_set:Npn \prg_new_protected_conditional:Npnn #1{ + \prg_get_parm_aux:nw{ + \cs_split_function:NN #1 \prg_generate_conditional_aux:nnNNnnnn + \cs_new_protected:Npn {parm} + } +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\prg_set_conditional:Nnn,\prg_new_conditional:Nnn, +% \prg_set_protected_conditional:Nnn,\prg_new_protected_conditional:Nnn} +% The user functions for the types automatically inserting the +% correct parameter text based on the signature. Call aux function +% after calculating number of arguments, split the base function +% into name and signature and then use, e.g., |\cs_set:Npn| to +% define it with. +% \begin{macrocode} +\cs_set:Npn \prg_set_conditional:Nnn #1{ + \exp_args:Nnf \prg_get_count_aux:nn{ + \cs_split_function:NN #1 \prg_generate_conditional_aux:nnNNnnnn + \cs_set:Npn {count} + }{\cs_get_arg_count_from_signature:N #1} +} +\cs_set:Npn \prg_new_conditional:Nnn #1{ + \exp_args:Nnf \prg_get_count_aux:nn{ + \cs_split_function:NN #1 \prg_generate_conditional_aux:nnNNnnnn + \cs_new:Npn {count} + }{\cs_get_arg_count_from_signature:N #1} +} + +\cs_set:Npn \prg_set_protected_conditional:Nnn #1{ + \exp_args:Nnf \prg_get_count_aux:nn{ + \cs_split_function:NN #1 \prg_generate_conditional_aux:nnNNnnnn + \cs_set_protected:Npn {count} + }{\cs_get_arg_count_from_signature:N #1} +} + +\cs_set:Npn \prg_new_protected_conditional:Nnn #1{ + \exp_args:Nnf \prg_get_count_aux:nn{ + \cs_split_function:NN #1 \prg_generate_conditional_aux:nnNNnnnn + \cs_new_protected:Npn {count} + }{\cs_get_arg_count_from_signature:N #1} +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[aux]{\prg_get_parm_aux:nw,\prg_get_count_aux:nn} +% For the "Npnn" type we must grab the parameter text before +% continuing. We make this a very generic function that takes one +% argument before reading everything up to a left brace. Something +% similar for the "Nnn" type. +% \begin{macrocode} +\cs_set:Npn \prg_get_count_aux:nn #1#2 {#1{#2}} +\cs_set:Npn \prg_get_parm_aux:nw #1#2#{#1{#2}} +% \end{macrocode} +% \end{macro} +% \begin{macro}[aux]{\prg_generate_conditional_parm_aux:nnNNnnnn, +% \prg_generate_conditional_parm_aux:nw} +% +% The workhorse here is going through a list of desired forms, i.e., +% p, TF, T and F. The first three arguments come from splitting up +% the base form of the conditional, which gives the name, signature +% and a boolean to signal whether or not there was a colon in the +% name. For the time being, we do not use this piece of information +% but could well throw an error. The fourth argument is how to +% define this function, the fifth is the text "parm" or "count" for +% which version to use to define the functions, the sixth is the +% parameters to use (possibly empty) or number of arguments, the +% seventh is the list of forms to define, the eight is the +% replacement text which we will augment when defining the forms. +% \begin{macrocode} +\cs_set:Npn \prg_generate_conditional_aux:nnNNnnnn #1#2#3#4#5#6#7#8{ + \prg_generate_conditional_aux:nnw{#5}{ + #4{#1}{#2}{#6}{#8} + }#7,?, \q_recursion_stop +} +% \end{macrocode} +% Looping through the list of desired forms. First is the text "parm" +% or "count", second is five arguments packed together and third is +% the form. Use text and form to call the correct type. +% \begin{macrocode} +\cs_set:Npn \prg_generate_conditional_aux:nnw #1#2#3,{ + \if:w ?#3 + \exp_after:wN \use_none_delimit_by_q_recursion_stop:w + \fi: + \use:c{prg_generate_#3_form_#1:Nnnnn} #2 + \prg_generate_conditional_aux:nnw{#1}{#2} +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[aux]{\prg_generate_p_form_parm:Nnnnn, +% \prg_generate_TF_form_parm:Nnnnn, +% \prg_generate_T_form_parm:Nnnnn, +% \prg_generate_F_form_parm:Nnnnn +% } +% How to generate the various forms. The "parm" types here takes the +% following arguments: 1: how to define (an N-type), 2: name, 3: +% signature, 4: parameter text (or empty), 5: replacement. +% \begin{macrocode} +\cs_set:Npn \prg_generate_p_form_parm:Nnnnn #1#2#3#4#5{ + \exp_args:Nc #1 {#2_p:#3}#4{#5 \c_zero + \exp_after:wN\c_true_bool\else:\exp_after:wN\c_false_bool\fi: + } +} +\cs_set:Npn \prg_generate_TF_form_parm:Nnnnn #1#2#3#4#5{ + \exp_args:Nc#1 {#2:#3TF}#4{#5 \c_zero + \exp_after:wN \use_i:nn \else: \exp_after:wN \use_ii:nn \fi: + } +} +\cs_set:Npn \prg_generate_T_form_parm:Nnnnn #1#2#3#4#5{ + \exp_args:Nc#1 {#2:#3T}#4{#5 \c_zero + \else:\exp_after:wN\use_none:nn\fi:\use:n + } +} +\cs_set:Npn \prg_generate_F_form_parm:Nnnnn #1#2#3#4#5{ + \exp_args:Nc#1 {#2:#3F}#4{#5 \c_zero + \exp_after:wN\use_none:nn\fi:\use:n + } +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[aux]{\prg_generate_p_form_count:Nnnnn, +% \prg_generate_TF_form_count:Nnnnn, +% \prg_generate_T_form_count:Nnnnn, +% \prg_generate_F_form_count:Nnnnn +% } +% How to generate the various forms. The "count" types here use a +% number to insert the correct parameter text, otherwise like the +% "parm" functions above. +% \begin{macrocode} +\cs_set:Npn \prg_generate_p_form_count:Nnnnn #1#2#3#4#5{ + \cs_generate_from_arg_count:cNnn {#2_p:#3} #1 {#4}{#5 \c_zero + \exp_after:wN\c_true_bool\else:\exp_after:wN\c_false_bool\fi: + } +} +\cs_set:Npn \prg_generate_TF_form_count:Nnnnn #1#2#3#4#5{ + \cs_generate_from_arg_count:cNnn {#2:#3TF} #1 {#4}{#5 \c_zero + \exp_after:wN\use_i:nn\else:\exp_after:wN\use_ii:nn\fi: + } +} +\cs_set:Npn \prg_generate_T_form_count:Nnnnn #1#2#3#4#5{ + \cs_generate_from_arg_count:cNnn {#2:#3T} #1 {#4}{#5 \c_zero + \else:\exp_after:wN\use_none:nn\fi:\use:n + } +} +\cs_set:Npn \prg_generate_F_form_count:Nnnnn #1#2#3#4#5{ + \cs_generate_from_arg_count:cNnn {#2:#3F} #1 {#4}{#5 \c_zero + \exp_after:wN\use_none:nn\fi:\use:n + } +} +% \end{macrocode} +% \end{macro} +% +% All that is left is to define the canonical boolean true and false. % I think Michael originated the idea of expandable boolean tests. At % first these were supposed to expand into either \texttt{TT} or % \texttt{TF} to be tested using |\if:w| but this was later changed to -% \texttt{00} and \texttt{01}, so they can be used in logical -% operations (see the \textsf{l3prg} module). We need this from the -% get-go. +% \texttt{00} and \texttt{01}, so they could be used in logical +% operations. Later again they were changed to being numerical +% constants with values of $1$ for true and $0$ for false. We need +% this from the get-go. % -% \begin{macro}{\c_true} -% \begin{macro}{\c_false} +% \begin{macro}{\c_true_bool} +% \begin{macro}{\c_false_bool} % Here are the canonical boolean values. % \begin{macrocode} -\def:Npn \c_true {00} -\def:Npn \c_false {01} +\tex_chardef:D \c_true_bool = 1~ +\tex_chardef:D \c_false_bool = 0~ % \end{macrocode} % \end{macro} % \end{macro} % -% \subsubsection {Defining and checking (new) functions} +% +% \subsection{Dissecting a control sequence} +% +% \begin{macro}{\cs_to_str:N} +% \begin{macro}[aux]{\cs_to_str_aux:w} +% This converts a control sequence into the character string of its +% name, removing the leading escape character. This turns out to be +% a non-trivial matter as there a different cases: +% \begin{itemize} +% \item The usual case of a printable escape character; +% \item the case of a non-printable escape characters, e.g., when +% the value of |\tex_escapechar:D| is negative; +% \item when the escape character is a space. +% \end{itemize} +% The route chosen is this: If |\token_to_str:N \a| produces a +% non-space escape char, then this will produce two tokens. If the +% escape char is non-printable, only one token is produced. If the +% escape char is a space, then a space token plus one token +% character token is produced. If we augment the result of this +% expansion with the letters |ax| we get the following three +% scenarios (with \meta{X} being a printable non-space escape +% character): +% \begin{itemize} +% \item \meta{X}"aax" +% \item "aax" +% \item " aax" +% \end{itemize} +% In the second and third case, putting an auxiliary function in front +% reading undelimited arguments will treat them the same, removing the +% space token for us automatically. Therefore, if we test the second +% and third argument of what such a function reads, in case 1 we will +% get true and in cases 2 and 3 we will get false. If we choose to +% optimize for the usual case of a printable escape char, we can do it +% like this (again getting TeX to remove the leading space for us): +% \begin{macrocode} +\cs_set_nopar:Npn \cs_to_str:N { + \if:w \exp_after:wN \cs_str_aux:w\token_to_str:N \a ax\q_nil + \else: + \exp_after:wN \exp_after:wN\exp_after:wN \use_ii:nn + \fi: + \exp_after:wN \use_none:n \token_to_str:N +} +\cs_set:Npn \cs_str_aux:w #1#2#3#4\q_nil{#2#3} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\cs_split_function:NN} +% \begin{macro}[aux]{\cs_split_function_aux:w} +% \begin{macro}[aux]{\cs_split_function_auxii:w} +% This function takes a function name and splits it into name with +% the escape char removed and argument specification. In addition to +% this, a third argument, a boolean \m{true} or \m{false} is +% returned with \m{true} for when there is a colon in the function +% and \m{false} if there is not. Lastly, the second argument of +% |\cs_split_function:NN| is supposed to be a function +% taking three variables, one for name, one for signature, and one +% for the boolean. For example, +% "\cs_split_function:NN\foo_bar:cnx\use_i:nnn" as input +% becomes "\use_i:nnn {foo_bar}{cnx}\c_true_bool". +% +% Can't use a literal ":" because it has the wrong catcode here, so +% it's transformed from "@" with "\tex_lowercase:D". +% \begin{macrocode} +\group_begin: + \tex_lccode:D `\@ = `\: \scan_stop: + \tex_catcode:D `\@ = 12~ +\tex_lowercase:D { + \group_end: +% \end{macrocode} +% First ensure that we actually get a properly evaluated str as we +% don't know how many expansions |\cs_to_str:N| requires. Insert +% extra colon to catch the error cases. +% \begin{macrocode} +\cs_set:Npn \cs_split_function:NN #1#2{ + \exp_after:wN \cs_split_function_aux:w + \tex_romannumeral:D -`\q \cs_to_str:N #1 @a \q_nil #2 +} +% \end{macrocode} +% If no colon in the name, |#2| is |a| with catcode 11 and |#3| is +% empty. If colon in the name, then either |#2| is a colon or the +% first letter of the signature. The letters here have catcode 12. +% If a colon was given we need to a) split off the colon and quark at +% the end and b) ensure we return the name, signature and boolean true +% We can't use |\quark_if_no_value:NTF| yet but this is very safe +% anyway as all tokens have catcode~12. +% \begin{macrocode} +\cs_set:Npn \cs_split_function_aux:w #1@#2#3\q_nil#4{ + \if_meaning:w a#2 + \exp_after:wN \use_i:nn + \else: + \exp_after:wN\use_ii:nn + \fi: + {#4{#1}{}\c_false_bool} + {\cs_split_function_auxii:w#2#3\q_nil #4{#1}} +} +\cs_set:Npn \cs_split_function_auxii:w #1@a\q_nil#2#3{ + #2{#3}{#1}\c_true_bool +} +% \end{macrocode} +% End of lowercase +% \begin{macrocode} +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\cs_get_function_name:N, \cs_get_function_signature:N } +% Now returning the name is trivial: just discard the last two +% arguments. Similar for signature. +% \begin{macrocode} +\cs_set:Npn \cs_get_function_name:N #1 { + \cs_split_function:NN #1\use_i:nnn +} +\cs_set:Npn \cs_get_function_signature:N #1 { + \cs_split_function:NN #1\use_ii:nnn +} +% \end{macrocode} +% \end{macro} +% +% \subsection{Exist or free} +% +% A control sequence is said to \emph{exist} (to be used) if has an entry in +% the hash table and its meaning is different from the primitive +% "\tex_relax:D" token. A control sequence is said to be \emph{free} +% (to be defined) if it does not already exist and also meets the +% requirement that it does not contain a "D" signature. The reasoning +% behind this is that most of the time, a check for a free control +% sequence is when we wish to make a new control sequence and we do +% not want to let the user define a new ``do not use'' control +% sequence. +% +% \begin{macro}{\cs_if_exist_p:N,\cs_if_exist_p:c} +% \begin{macro}[TF]{\cs_if_exist:N,\cs_if_exist:c} +% Two versions for checking existence. For the "N" form we firstly +% check for "\tex_relax:D" and then if it is in the hash +% table. There is no problem when inputting something like "\else:" +% or "\fi:" as \TeX\ will only ever skip input in case the token +% tested against is "\tex_relax:D". +% \begin{macrocode} +\prg_set_conditional:Npnn \cs_if_exist:N #1 {p,TF,T,F}{ + \if_meaning:w #1\tex_relax:D + \prg_return_false: + \else: + \if_cs_exist:N #1 + \prg_return_true: + \else: + \prg_return_false: + \fi: + \fi: +} +% \end{macrocode} +% For the "c" form we firstly check if it is in the hash table and +% then for "\tex_relax:D" so that we do not add it to the hash table +% unless it was already there. Here we have to be careful as the text +% to be skipped if the first test is false may contain tokens that +% disturb the scanner. Therefore, we ensure that the second test is +% performed after the first one has concluded completely. +% \begin{macrocode} +\prg_set_conditional:Npnn \cs_if_exist:c #1 {p,TF,T,F}{ + \if_cs_exist:w #1 \cs_end: + \exp_after:wN \use_i:nn + \else: + \exp_after:wN \use_ii:nn + \fi: + { + \exp_after:wN \if_meaning:w \cs:w #1\cs_end: \tex_relax:D + \prg_return_false: + \else: + \prg_return_true: + \fi: + } + \prg_return_false: +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\cs_if_do_not_use_p:N} +% \begin{macro}[aux]{\cs_if_do_not_use_aux:nnN} +% \begin{macrocode} +\cs_set:Npn \cs_if_do_not_use_p:N #1{ + \cs_split_function:NN #1 \cs_if_do_not_use_aux:nnN +} +\cs_set:Npn \cs_if_do_not_use_aux:nnN #1#2#3{ + \exp_after:wN\str_if_eq_p:nn \token_to_str:N D {#2} +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\cs_if_free_p:N,\cs_if_free_p:c} +% \begin{macro}[TF]{\cs_if_free:N,\cs_if_free:c} +% The simple implementation is one using the boolean expression +% parser: If it is exists or is do not use, then return false. +% \begin{verbatim} +% \prg_set_conditional:Npnn \cs_if_free:N #1{p,TF,T,F}{ +% \bool_if:nTF {\cs_if_exist_p:N #1 || \cs_if_do_not_use_p:N #1} +% {\prg_return_false:}{\prg_return_true:} +% } +% \end{verbatim} +% However, this functionality may not be available this early on. We +% do something similar: The numerical values of true and false is one +% and zero respectively, which we can use. The problem again here is +% that the token we are checking may in fact be something that can +% disturb the scanner, so we have to be careful. We would like to do +% minimal evaluation so we ensure this. +% \begin{macrocode} +\prg_set_conditional:Npnn \cs_if_free:N #1{p,TF,T,F}{ + \tex_ifnum:D \cs_if_exist_p:N #1 =\c_zero + \exp_after:wN \use_i:nn + \else: + \exp_after:wN \use_ii:nn + \fi: + { + \tex_ifnum:D \cs_if_do_not_use_p:N #1 =\c_zero + \prg_return_true: + \else: + \prg_return_false: + \fi: + } + \prg_return_false: +} +\cs_set_nopar:Npn \cs_if_free_p:c{\exp_args:Nc\cs_if_free_p:N} +\cs_set_nopar:Npn \cs_if_free:cTF{\exp_args:Nc\cs_if_free:NTF} +\cs_set_nopar:Npn \cs_if_free:cT{\exp_args:Nc\cs_if_free:NT} +\cs_set_nopar:Npn \cs_if_free:cF{\exp_args:Nc\cs_if_free:NF} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% \subsection{Defining and checking (new) functions} % % \begin{macro}{\c_minus_one} +% \begin{macro}{\c_zero} % \begin{macro}{\c_sixteen} % We need the constants |\c_minus_one| and |\c_sixteen| now for -% writing information to the log and the terminal but the -% rest are defined in the \textsf{l3num} module -- at least for the +% writing information to the log and the terminal and |\c_zero| +% which is used by some functions in the \textsf{l3num}module. The +% rest are defined in the \textsf{l3int} module -- at least for the % ones that can be defined with |\tex_chardef:D| or -% |\tex_mathchardef:D|. Otherwise the \textsf{l3int} module is +% |\tex_mathchardef:D|. For other constants the \textsf{l3int} module is % required but it can't be used until the allocation has been set % up properly! The actual allocation mechanism is in % \textsf{l3alloc} and as \TeX{} wants to reserve count registers @@ -1381,16 +2253,18 @@ % |\c_minus_one|. % \begin{macrocode} %<*!initex> -\let:NwN \c_minus_one\m@ne +\cs_set_eq:NwN \c_minus_one\m@ne %</!initex> %<*!package> -\tex_countdef:D \c_minus_one = 10 \scan_stop: -\c_minus_one = -1 \scan_stop: +\tex_countdef:D \c_minus_one = 10 ~ +\c_minus_one = -1 ~ %</!package> -\tex_chardef:D \c_sixteen = 16\scan_stop: +\tex_chardef:D \c_sixteen = 16~ +\tex_chardef:D \c_zero = 0~ % \end{macrocode} % \end{macro} % \end{macro} +% \end{macro} % % We provide two kinds of functions that can be used to define % control sequences. On the one hand we have functions that check @@ -1402,25 +2276,29 @@ % allow us to generate error messages. The definitions here are % only temporary, they will be redefined later on. % -% \begin{macro}{\io_put_log:x} -% \begin{macro}{\io_put_term:x} +% \begin{macro}{\iow_log:x} +% \begin{macro}{\iow_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 } +\cs_set_nopar:Npn \iow_log:x { + \tex_immediate:D \iow_shipout_x:Nn \c_minus_one +} +\cs_set_nopar:Npn \iow_term:x { + \tex_immediate:D \iow_shipout_x:Nn \c_sixteen +} % \end{macrocode} % \end{macro} % \end{macro} % -% \begin{macro}{\err_latex_bug:x} +% \begin{macro}{\msg_kernel_bug:x} % This will show internal errors. % \begin{macrocode} -\def:Npn\err_latex_bug:x#1{ - \io_put_term:x{This~is~a~LaTeX~bug!~Check~coding!}\tex_errmessage:D{#1}} +\cs_set_nopar:Npn \msg_kernel_bug:x #1 { + \iow_term:x { This~is~a~LaTeX~bug:~check~coding! } + \tex_errmessage:D {#1} +} % \end{macrocode} % \end{macro} % @@ -1430,123 +2308,72 @@ % definition here. % \begin{macrocode} %<*trace> -\def:Npn \cs_record_meaning:N#1{} +\cs_set:Npn \cs_record_meaning:N #1{} %</trace> % \end{macrocode} % \end{macro} % -% We need these two to make |\chk_new_cs:N| bulletproof. -% \begin{macrocode} -\def_long:Npn \use_none:n #1{} -\def_long:Npn \use_arg_i:n #1{#1} -% \end{macrocode} -% \begin{macro}{\chk_new_cs:N} -% This command is called by |\def_new:Npn| and |\let_new:NN| etc.\ +% \begin{macro}{\chk_if_free_cs:N} +% This command is called by |\cs_new_nopar:Npn| and |\cs_new_eq:NN| etc.\ % to make sure that the argument sequence is not already in use. If % it is, an error is signalled. It checks if \m{csname} is % undefined or |\scan_stop:|. Otherwise an error message is % issued. We have to make sure we don't put the argument into the % conditional processing since it may be an |\if...| type function! % \begin {macrocode} -\def:Npn \chk_new_cs:N #1{ - \if:w \cs_if_free_p:N #1 - \exp_after:NN \use_none:n - \else: - \exp_after:NN \use_arg_i:n - \fi: +\cs_set_nopar:Npn \chk_if_free_cs:N #1{ + \cs_if_free:NF #1 { - \err_latex_bug:x {Command~name~`\token_to_string:N #1'~ + \msg_kernel_bug:x {Command~name~`\token_to_str:N #1'~ already~defined!~ Current~meaning:~\token_to_meaning:N #1 } } %<*trace> \cs_record_meaning:N#1 -% \io_put_term:x{Defining~\token_to_string:N #1~on~%} - \io_put_log:x{Defining~\token_to_string:N #1~on~ +% \iow_term:x{Defining~\token_to_str:N #1~on~%} + \iow_log:x{Defining~\token_to_str:N #1~on~ line~\tex_the:D \tex_inputlineno:D} %</trace> } % \end{macrocode} % \end{macro} % -% On 2005/11/20 Morten said: I think names for testing if a certain -% condition is true or false should always contain |if| to avoid -% confusion. This is what we do for lots of other types of test -% functions. For now I have defined both names for the functions -% checking names of control sequences. -% -% \begin{macro}{\cs_if_exist_p:N} -% Expands into |\c_true| if the control sequence given as its -% argument \emph{is} in use. -% \begin{macrocode} -\def:Npn \cs_if_exist_p:N #1{ - \if:w \cs_if_free_p:N #1 - \c_false - \else: - \c_true \fi:} -% \end{macrocode} -% \end{macro} -% % \begin{macro}{\chk_if_exist_cs:N } % \begin{macro}{\chk_if_exist_cs:c } % This function issues a warning message when the control sequence % in its argument does not exist. % \begin{macrocode} -\def:Npn \chk_if_exist_cs:N #1 { - \if:w \cs_if_exist_p:N #1 - \else: - \err_latex_bug:x{Command~ `\token_to_string:N #1'~ +\cs_set_nopar:Npn \chk_if_exist_cs:N #1 { + \cs_if_exist:NF #1 + { + \msg_kernel_bug:x {Command~ `\token_to_str:N #1'~ not~ yet~ defined!} - \fi:} -\def:Npn \chk_if_exist_cs:c #1 { - \exp_after:NN \chk_if_exist_cs:N \cs:w #1\cs_end: } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\cs_if_free_p:N} -% Expands into |\c_true| if the control sequence given as its -% argument is not yet in use. Note that we make sure to expand -% into |\c_false| if the control sequence is textually -% |\c_undefined| or |\scan_stop:|, so that we don't end up -% (re)defining them. -% \begin{macrocode} -\def:Npn \cs_if_free_p:N #1{ - \if_cs_exist:N #1 - \if_meaning:NN#1\scan_stop: - \if:w\cs_if_eq_name_p:NN #1\scan_stop: - \c_false \else: \c_true \fi: - \else: - \c_false - \fi: - \else: - \if:w \cs_if_eq_name_p:NN #1\c_undefined - \c_false \else: \c_true \fi: - \fi: + } } -\let:NwN \cs_free_p:N \cs_if_free_p:N +\cs_set_nopar:Npn \chk_if_exist_cs:c {\exp_args:Nc \chk_if_exist_cs:N } % \end{macrocode} % \end{macro} +% \end{macro} % % % \begin{macro}{\str_if_eq_p:nn} -% \begin{macro}{\str_if_eq_p_aux:w} +% \begin{macro}[aux]{\str_if_eq_p_aux:w} % Takes 2 lists of characters as arguments and expands into -% |\c_true| if they are equal, and |\c_false| otherwise. Note that +% |\c_true_bool| if they are equal, and |\c_false_bool| otherwise. Note that % in the current implementation spaces in these strings are % ignored.\footnote{This is a function which could use % \cs{tlist_compare:xx}.} % \begin{macrocode} -\def:Npn \str_if_eq_p:nn #1#2{ +\prg_set_conditional:Npnn \str_if_eq:nn #1#2{p}{ \str_if_eq_p_aux:w #1\scan_stop:\\#2\scan_stop:\\ } -\def:Npn \str_if_eq_p_aux:w #1#2\\#3#4\\{ - \if_meaning:NN#1#3 - \if_meaning:NN#1\scan_stop:\c_true \else: - \if_meaning:NN#3\scan_stop:\c_false \else: +\cs_set_nopar:Npn \str_if_eq_p_aux:w #1#2\\#3#4\\{ + \if_meaning:w#1#3 + \if_meaning:w#1\scan_stop:\prg_return_true: \else: + \if_meaning:w#3\scan_stop:\prg_return_false: \else: \str_if_eq_p_aux:w #2\\#4\\\fi:\fi: - \else:\c_false \fi:} + \else:\prg_return_false: \fi:} % \end{macrocode} % \end{macro} % \end{macro} @@ -1557,21 +2384,21 @@ % arguments and expands into true iff they have the same name. % We make it long in case one of them is |\par|! % \begin{macrocode} -\def_long:Npn \cs_if_eq_name_p:NN #1#2{ - \exp_after:NN\exp_after:NN - \exp_after:NN\str_if_eq_p_aux:w - \exp_after:NN\token_to_string:N - \exp_after:NN#1 - \exp_after:NN\scan_stop: - \exp_after:NN\\ - \token_to_string:N#2\scan_stop:\\} +\prg_set_conditional:Npnn \cs_if_eq_name:NN #1#2{p}{ + \exp_after:wN\exp_after:wN + \exp_after:wN\str_if_eq_p_aux:w + \exp_after:wN\token_to_str:N + \exp_after:wN#1 + \exp_after:wN\scan_stop: + \exp_after:wN\\ + \token_to_str:N#2\scan_stop:\\} % \end{macrocode} % \end{macro} % % % \begin{macro}{\str_if_eq_var_p:nf} -% \begin{macro}{\str_if_eq_var_start:nnN} -% \begin{macro}{\str_if_eq_var_stop:w} +% \begin{macro}[aux]{\str_if_eq_var_start:nnN} +% \begin{macro}[aux]{\str_if_eq_var_stop:w} % A variant of |\str_if_eq_p:nn| which has the advantage of obeying % spaces in at least the second argument. See \textsf{l3quark} for % an application. From the hand of David Kastrup with slight @@ -1591,19 +2418,19 @@ % octal notation so |\tex_number:D| returns |11|. If one test % returns false the |'| is never seen and then we get just |13|. We % wrap the whole process in an external |\if:w| in order to make it -% return either |\c_true| or |\c_false| since some parts of +% return either |\c_true_bool| or |\c_false_bool| since some parts of % \textsf{l3prg} expect a predicate to return one of these two % tokens. % \begin{macrocode} -\def:Npn \str_if_eq_var_p:nf#1{ - \if:w \tex_number:D\str_if_eq_var_start:nnN{}{}#1\scan_stop: +\prg_set_conditional:Npnn \str_if_eq_var:nf #1#2 {p} { + \if:w \tex_number:D\str_if_eq_var_start:nnN{}{}#1\scan_stop:{#2} } -\def:Npn\str_if_eq_var_start:nnN#1#2#3{ - \if:w#3\scan_stop:\exp_after:NN\str_if_eq_var_stop:w\fi: +\cs_set_nopar:Npn\str_if_eq_var_start:nnN#1#2#3{ + \if:w#3\scan_stop:\exp_after:wN\str_if_eq_var_stop:w\fi: \str_if_eq_var_start:nnN{\if:w#3#1}{#2\fi:} } -\def:Npn\str_if_eq_var_stop:w\str_if_eq_var_start:nnN#1#2#3{ - #1#3\scan_stop:'#213~\c_true\else:\c_false\fi: +\cs_set:Npn\str_if_eq_var_stop:w\str_if_eq_var_start:nnN#1#2#3{ + #1#3\scan_stop:'#213~\prg_return_true:\else:\prg_return_false:\fi: } % \end{macrocode} % \end{macro} @@ -1613,39 +2440,37 @@ % % % -% \subsubsection{More new definitions} +% \subsection{More new definitions} % % % -% \begin{macro}{\def_new:Npn} -% \begin{macro}{\def_new:Npx} -% \begin{macro}{\def_long_new:Npn} -% \begin{macro}{\def_long_new:Npx} -% \begin{macro}{\def_protected_new:Npn} -% \begin{macro}{\def_protected_new:Npx} -% \begin{macro}{\def_protected_long_new:Npn} -% \begin{macro}{\def_protected_long_new:Npx} -% These are like |\def:Npn| and |\let:NN|, but they first check that -% the argument command is not already in use. You may use -% |\pref_global:D|, |\pref_long:D|, |\pref_protected:D|, and +% \begin{macro}{\cs_new_nopar:Npn} +% \begin{macro}{\cs_new_nopar:Npx} +% \begin{macro}{\cs_new:Npn} +% \begin{macro}{\cs_new:Npx} +% \begin{macro}{\cs_new_protected_nopar:Npn} +% \begin{macro}{\cs_new_protected_nopar:Npx} +% \begin{macro}{\cs_new_protected:Npn} +% \begin{macro}{\cs_new_protected:Npx} +% These are like |\cs_set_nopar:Npn| and |\cs_set_eq:NN|, but they +% first check that the argument command is not already in use. You +% may use |\pref_global:D|, |\pref_long:D|, |\pref_protected:D|, and % |\tex_outer:D| as prefixes. % \begin {macrocode} -\def_protected:Npn \def_new:Npn #1{\chk_new_cs:N #1 - \def:Npn #1} -\def_protected:Npn \def_new:Npx #1{\chk_new_cs:N #1 - \def:Npx #1} -\def_protected:Npn \def_long_new:Npn #1{\chk_new_cs:N #1 - \def_long:Npn #1} -\def_protected:Npn \def_long_new:Npx #1{\chk_new_cs:N #1 - \def_long:Npx #1} -\def_protected:Npn \def_protected_new:Npn #1{\chk_new_cs:N #1 - \def_protected:Npn #1} -\def_protected:Npn \def_protected_new:Npx #1{\chk_new_cs:N #1 - \def_protected:Npx #1} -\def_protected:Npn \def_protected_long_new:Npn #1{\chk_new_cs:N #1 - \def_protected_long:Npn #1} -\def_protected:Npn \def_protected_long_new:Npx #1{\chk_new_cs:N #1 - \def_protected_long:Npx #1} +\cs_set:Npn \cs_tmp:w #1#2{ + \cs_set_protected_nopar:Npn #1 ##1 { + \chk_if_free_cs:N ##1 + #2 ##1 + } +} +\cs_tmp:w \cs_new_nopar:Npn \cs_set_nopar:Npn +\cs_tmp:w \cs_new_nopar:Npx\cs_set_nopar:Npx +\cs_tmp:w \cs_new:Npn \cs_set:Npn +\cs_tmp:w \cs_new:Npx\cs_set:Npx +\cs_tmp:w \cs_new_protected_nopar:Npn \cs_set_protected_nopar:Npn +\cs_tmp:w \cs_new_protected_nopar:Npx\cs_set_protected_nopar:Npx +\cs_tmp:w \cs_new_protected:Npn \cs_set_protected:Npn +\cs_tmp:w \cs_new_protected:Npx\cs_set_protected:Npx % \end{macrocode} % \end{macro} % \end{macro} @@ -1656,32 +2481,24 @@ % \end{macro} % \end{macro} % -% \begin{macro}{\gdef_new:Npn} -% \begin{macro}{\gdef_new:Npx} -% \begin{macro}{\gdef_long_new:Npn} -% \begin{macro}{\gdef_long_new:Npx} -% \begin{macro}{\gdef_protected_new:Npn} -% \begin{macro}{\gdef_protected_new:Npx} -% \begin{macro}{\gdef_protected_long_new:Npn} -% \begin{macro}{\gdef_protected_long_new:Npx} +% \begin{macro}{\cs_gnew_nopar:Npn} +% \begin{macro}{\cs_gnew_nopar:Npx} +% \begin{macro}{\cs_gnew:Npn} +% \begin{macro}{\cs_gnew:Npx} +% \begin{macro}{\cs_gnew_protected_nopar:Npn} +% \begin{macro}{\cs_gnew_protected_nopar:Npx} +% \begin{macro}{\cs_gnew_protected:Npn} +% \begin{macro}{\cs_gnew_protected:Npx} % Global versions of the above functions. % \begin {macrocode} -\def_protected_new:Npn \gdef_new:Npn #1{\chk_new_cs:N #1 - \gdef:Npn #1} -\def_protected_new:Npn \gdef_new:Npx #1{\chk_new_cs:N #1 - \gdef:Npx #1} -\def_protected_new:Npn \gdef_long_new:Npn #1{\chk_new_cs:N #1 - \gdef_long:Npn #1} -\def_protected_new:Npn \gdef_long_new:Npx #1{\chk_new_cs:N #1 - \gdef_long:Npx #1} -\def_protected_new:Npn \gdef_protected_new:Npn #1{\chk_new_cs:N #1 - \gdef_protected:Npn #1} -\def_protected_new:Npn \gdef_protected_new:Npx #1{\chk_new_cs:N #1 - \gdef_protected:Npx #1} -\def_protected_new:Npn \gdef_protected_long_new:Npn #1{\chk_new_cs:N #1 - \gdef_protected_long:Npn #1} -\def_protected_new:Npn \gdef_protected_long_new:Npx #1{\chk_new_cs:N #1 - \gdef_protected_long:Npx #1} +\cs_tmp:w \cs_gnew_nopar:Npn \cs_gset_nopar:Npn +\cs_tmp:w \cs_gnew_nopar:Npx \cs_gset_nopar:Npx +\cs_tmp:w \cs_gnew:Npn \cs_gset:Npn +\cs_tmp:w \cs_gnew:Npx \cs_gset:Npx +\cs_tmp:w \cs_gnew_protected_nopar:Npn \cs_gset_protected_nopar:Npn +\cs_tmp:w \cs_gnew_protected_nopar:Npx \cs_gset_protected_nopar:Npx +\cs_tmp:w \cs_gnew_protected:Npn \cs_gset_protected:Npn +\cs_tmp:w \cs_gnew_protected:Npx \cs_gset_protected:Npx % \end{macrocode} % \end{macro} % \end{macro} @@ -1693,33 +2510,36 @@ % \end{macro} % % -% \begin{macro}{\def:cpn} -% \begin{macro}{\def:cpx} -% \begin{macro}{\gdef:cpn} -% \begin{macro}{\gdef:cpx} -% \begin{macro}{\def_new:cpn} -% \begin{macro}{\def_new:cpx} -% \begin{macro}{\gdef_new:cpn} -% \begin{macro}{\gdef_new:cpx} -% Like |\def:Npn| and |\def_new:Npn|, except that the first argument -% consists of the sequence of characters that should be used to form -% the name of the desired control sequence (the |c| stands for -% csname argument, see the expansion module.). Global versions are -% also provided. +% \begin{macro}{\cs_set_nopar:cpn} +% \begin{macro}{\cs_set_nopar:cpx} +% \begin{macro}{\cs_gset_nopar:cpn} +% \begin{macro}{\cs_gset_nopar:cpx} +% \begin{macro}{\cs_new_nopar:cpn} +% \begin{macro}{\cs_new_nopar:cpx} +% \begin{macro}{\cs_gnew_nopar:cpn} +% \begin{macro}{\cs_gnew_nopar:cpx} +% Like |\cs_set_nopar:Npn| and |\cs_new_nopar:Npn|, except that the +% first argument consists of the sequence of characters that should +% be used to form the name of the desired control sequence (the |c| +% stands for csname argument, see the expansion module). Global +% versions are also provided. % -% |\def:cpn|\m{string}\m{rep-text} will turn \m{string} into a -% csname and then assign \m {rep-text} to it by using |\def:Npn|. -% This means that there might be a parameter string between the two -% arguments. +% |\cs_set_nopar:cpn|\m{string}\m{rep-text} will turn \m{string} +% into a csname and then assign \m {rep-text} to it by using +% |\cs_set_nopar: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 \gdef:cpn #1{\exp_after:NN \gdef:Npn \cs:w #1\cs_end:} -\def_new:Npn \gdef:cpx #1{\exp_after:NN \gdef:Npx \cs:w #1\cs_end:} -\def_new:Npn \def_new:cpn #1{\exp_after:NN \def_new:Npn \cs:w #1\cs_end:} -\def_new:Npn \def_new:cpx #1{\exp_after:NN \def_new:Npx \cs:w #1\cs_end:} -\def_new:Npn \gdef_new:cpn #1{\exp_after:NN \gdef_new:Npn \cs:w #1\cs_end:} -\def_new:Npn \gdef_new:cpx #1{\exp_after:NN \gdef_new:Npx \cs:w #1\cs_end:} +\cs_set:Npn \cs_tmp:w #1#2{ + \cs_new_nopar:Npn #1 { \exp_args:Nc #2 } +} +\cs_tmp:w \cs_set_nopar:cpn \cs_set_nopar:Npn +\cs_tmp:w \cs_set_nopar:cpx \cs_set_nopar:Npx +\cs_tmp:w \cs_gset_nopar:cpn \cs_gset_nopar:Npn +\cs_tmp:w \cs_gset_nopar:cpx \cs_gset_nopar:Npx +\cs_tmp:w \cs_new_nopar:cpn \cs_new_nopar:Npn +\cs_tmp:w \cs_new_nopar:cpx \cs_new_nopar:Npx +\cs_tmp:w \cs_gnew_nopar:cpn \cs_gnew_nopar:Npn +\cs_tmp:w \cs_gnew_nopar:cpx \cs_gnew_nopar:Npx % \end{macrocode} % \end{macro} % \end{macro} @@ -1732,32 +2552,25 @@ % % % -% \begin{macro}{\def_long:cpn} -% \begin{macro}{\def_long:cpx} -% \begin{macro}{\gdef_long:cpn} -% \begin{macro}{\gdef_long:cpx} -% \begin{macro}{\def_long_new:cpn} -% \begin{macro}{\def_long_new:cpx} -% \begin{macro}{\gdef_long_new:cpn} -% \begin{macro}{\gdef_long_new:cpx} -% Variants of the |\def_long:Npn| versions which make a csname out +% \begin{macro}{\cs_set:cpn} +% \begin{macro}{\cs_set:cpx} +% \begin{macro}{\cs_gset:cpn} +% \begin{macro}{\cs_gset:cpx} +% \begin{macro}{\cs_new:cpn} +% \begin{macro}{\cs_new:cpx} +% \begin{macro}{\cs_gnew:cpn} +% \begin{macro}{\cs_gnew:cpx} +% Variants of the |\cs_set:Npn| versions which make a csname out % of the first arguments. We may also do this globally. % \begin{macrocode} -\def_new:Npn \def_long:cpn #1{\exp_after:NN \def_long:Npn \cs:w #1\cs_end:} -\def_new:Npn \def_long:cpx #1{ - \exp_after:NN\def_long:Npx\cs:w #1\cs_end:} -\def_new:Npn \gdef_long:cpn #1{ - \exp_after:NN \gdef_long:Npn \cs:w #1\cs_end:} -\def_new:Npn \gdef_long:cpx #1{ - \exp_after:NN\gdef_long:Npx\cs:w #1\cs_end:} -\def_new:Npn \def_long_new:cpn #1{ - \exp_after:NN \def_long_new:Npn \cs:w #1\cs_end:} -\def_new:Npn \def_long_new:cpx #1{ - \exp_after:NN \def_long_new:Npx \cs:w #1\cs_end:} -\def_new:Npn \gdef_long_new:cpn #1{ - \exp_after:NN \gdef_long_new:Npn \cs:w #1\cs_end:} -\def_new:Npn \gdef_long_new:cpx #1{ - \exp_after:NN \gdef_long_new:Npx \cs:w #1\cs_end:} +\cs_tmp:w \cs_set:cpn \cs_set:Npn +\cs_tmp:w \cs_set:cpx \cs_set:Npx +\cs_tmp:w \cs_gset:cpn \cs_gset:Npn +\cs_tmp:w \cs_gset:cpx \cs_gset:Npx +\cs_tmp:w \cs_new:cpn \cs_new:Npn +\cs_tmp:w \cs_new:cpx \cs_new:Npx +\cs_tmp:w \cs_gnew:cpn \cs_gnew:Npn +\cs_tmp:w \cs_gnew:cpx \cs_gnew:Npx % \end{macrocode} % \end{macro} % \end{macro} @@ -1768,33 +2581,25 @@ % \end{macro} % \end{macro} % -% \begin{macro}{\def_protected:cpn} -% \begin{macro}{\def_protected:cpx} -% \begin{macro}{\gdef_protected:cpn} -% \begin{macro}{\gdef_protected:cpx} -% \begin{macro}{\def_protected_new:cpn} -% \begin{macro}{\def_protected_new:cpx} -% \begin{macro}{\gdef_protected_new:cpn} -% \begin{macro}{\gdef_protected_new:cpx} -% Variants of the |\def_protected:Npn| versions which make a csname +% \begin{macro}{\cs_set_protected_nopar:cpn} +% \begin{macro}{\cs_set_protected_nopar:cpx} +% \begin{macro}{\cs_gset_protected_nopar:cpn} +% \begin{macro}{\cs_gset_protected_nopar:cpx} +% \begin{macro}{\cs_new_protected_nopar:cpn} +% \begin{macro}{\cs_new_protected_nopar:cpx} +% \begin{macro}{\cs_gnew_protected_nopar:cpn} +% \begin{macro}{\cs_gnew_protected_nopar:cpx} +% Variants of the |\cs_set_protected_nopar:Npn| versions which make a csname % out of the first arguments. We may also do this globally. % \begin{macrocode} -\def_new:Npn \def_protected:cpn #1{ - \exp_after:NN \def_protected:Npn \cs:w #1\cs_end:} -\def_new:Npn \def_protected:cpx #1{ - \exp_after:NN\def_protected:Npx\cs:w #1\cs_end:} -\def_new:Npn \gdef_protected:cpn #1{ - \exp_after:NN \gdef_protected:Npn \cs:w #1\cs_end:} -\def_new:Npn \gdef_protected:cpx #1{ - \exp_after:NN\gdef_protected:Npx\cs:w #1\cs_end:} -\def_new:Npn \def_protected_new:cpn #1{ - \exp_after:NN \def_protected_new:Npn \cs:w #1\cs_end:} -\def_new:Npn \def_protected_new:cpx #1{ - \exp_after:NN \def_protected_new:Npx \cs:w #1\cs_end:} -\def_new:Npn \gdef_protected_new:cpn #1{ - \exp_after:NN \gdef_protected_new:Npn \cs:w #1\cs_end:} -\def_new:Npn \gdef_protected_new:cpx #1{ - \exp_after:NN \gdef_protected_new:Npx \cs:w #1\cs_end:} +\cs_tmp:w \cs_set_protected_nopar:cpn \cs_set_protected_nopar:Npn +\cs_tmp:w \cs_set_protected_nopar:cpx \cs_set_protected_nopar:Npx +\cs_tmp:w \cs_gset_protected_nopar:cpn \cs_gset_protected_nopar:Npn +\cs_tmp:w \cs_gset_protected_nopar:cpx \cs_gset_protected_nopar:Npx +\cs_tmp:w \cs_new_protected_nopar:cpn \cs_new_protected_nopar:Npn +\cs_tmp:w \cs_new_protected_nopar:cpx \cs_new_protected_nopar:Npx +\cs_tmp:w \cs_gnew_protected_nopar:cpn \cs_gnew_protected_nopar:Npn +\cs_tmp:w \cs_gnew_protected_nopar:cpx \cs_gnew_protected_nopar:Npx % \end{macrocode} % \end{macro} % \end{macro} @@ -1805,33 +2610,25 @@ % \end{macro} % \end{macro} % -% \begin{macro}{\def_protected_long:cpn} -% \begin{macro}{\def_protected_long:cpx} -% \begin{macro}{\gdef_protected_long:cpn} -% \begin{macro}{\gdef_protected_long:cpx} -% \begin{macro}{\def_protected_long_new:cpn} -% \begin{macro}{\def_protected_long_new:cpx} -% \begin{macro}{\gdef_protected_long_new:cpn} -% \begin{macro}{\gdef_protected_long_new:cpx} -% Variants of the |\def_protected_long:Npn| versions which make a csname +% \begin{macro}{\cs_set_protected:cpn} +% \begin{macro}{\cs_set_protected:cpx} +% \begin{macro}{\cs_gset_protected:cpn} +% \begin{macro}{\cs_gset_protected:cpx} +% \begin{macro}{\cs_new_protected:cpn} +% \begin{macro}{\cs_new_protected:cpx} +% \begin{macro}{\cs_gnew_protected:cpn} +% \begin{macro}{\cs_gnew_protected:cpx} +% Variants of the |\cs_set_protected:Npn| versions which make a csname % out of the first arguments. We may also do this globally. % \begin{macrocode} -\def_new:Npn \def_protected_long:cpn #1{ - \exp_after:NN \def_protected_long:Npn \cs:w #1\cs_end:} -\def_new:Npn \def_protected_long:cpx #1{ - \exp_after:NN\def_protected_long:Npx\cs:w #1\cs_end:} -\def_new:Npn \gdef_protected_long:cpn #1{ - \exp_after:NN \gdef_protected_long:Npn \cs:w #1\cs_end:} -\def_new:Npn \gdef_protected_long:cpx #1{ - \exp_after:NN\gdef_protected_long:Npx\cs:w #1\cs_end:} -\def_new:Npn \def_protected_long_new:cpn #1{ - \exp_after:NN \def_protected_long_new:Npn \cs:w #1\cs_end:} -\def_new:Npn \def_protected_long_new:cpx #1{ - \exp_after:NN \def_protected_long_new:Npx \cs:w #1\cs_end:} -\def_new:Npn \gdef_protected_long_new:cpn #1{ - \exp_after:NN \gdef_protected_long_new:Npn \cs:w #1\cs_end:} -\def_new:Npn \gdef_protected_long_new:cpx #1{ - \exp_after:NN \gdef_protected_long_new:Npx \cs:w #1\cs_end:} +\cs_tmp:w \cs_set_protected:cpn \cs_set_protected:Npn +\cs_tmp:w \cs_set_protected:cpx \cs_set_protected:Npx +\cs_tmp:w \cs_gset_protected:cpn \cs_gset_protected:Npn +\cs_tmp:w \cs_gset_protected:cpx \cs_gset_protected:Npx +\cs_tmp:w \cs_new_protected:cpn \cs_new_protected:Npn +\cs_tmp:w \cs_new_protected:cpx \cs_new_protected:Npx +\cs_tmp:w \cs_gnew_protected:cpn \cs_gnew_protected:Npn +\cs_tmp:w \cs_gnew_protected:cpx \cs_gnew_protected:Npx % \end{macrocode} % \end{macro} % \end{macro} @@ -1843,56 +2640,31 @@ % \end{macro} % % -% \begin{macro}{\def_aux_0:NNn} -% \begin{macro}{\def_aux_1:NNn} -% \begin{macro}{\def_aux_2:NNn} -% \begin{macro}{\def_aux_3:NNn} -% \begin{macro}{\def_aux_4:NNn} -% \begin{macro}{\def_aux_5:NNn} -% \begin{macro}{\def_aux_6:NNn} -% \begin{macro}{\def_aux_7:NNn} -% \begin{macro}{\def_aux_8:NNn} -% \begin{macro}{\def_aux_9:NNn} -% \begin{macro}{\def_aux:NNnn} -% \begin{macro}{\def_aux:Ncnn} -% \begin{macro}{\def_arg_number_error_msg:Nn} -% Defining a function with $n$ arguments. First some helper functions. -% \begin{macrocode} -\def_new:cpn {def_aux_0:NNn} #1#2 {#1 #2 } -\def_new:cpn {def_aux_1:NNn} #1#2 {#1 #2 ##1 } -\def_new:cpn {def_aux_2:NNn} #1#2 {#1 #2 ##1##2 } -\def_new:cpn {def_aux_3:NNn} #1#2 {#1 #2 ##1##2##3 } -\def_new:cpn {def_aux_4:NNn} #1#2 {#1 #2 ##1##2##3##4 } -\def_new:cpn {def_aux_5:NNn} #1#2 {#1 #2 ##1##2##3##4##5 } -\def_new:cpn {def_aux_6:NNn} #1#2 {#1 #2 ##1##2##3##4##5##6 } -\def_new:cpn {def_aux_7:NNn} #1#2 {#1 #2 ##1##2##3##4##5##6##7 } -\def_new:cpn {def_aux_8:NNn} #1#2 {#1 #2 ##1##2##3##4##5##6##7##8 } -\def_new:cpn {def_aux_9:NNn} #1#2 {#1 #2 ##1##2##3##4##5##6##7##8##9 } -% \end{macrocode} -% Then the function itself which checks for the existance of such a -% helper function. If it doesn't exist, return an error. Otherwise -% call it to define \verb|#2| with the correct number of arguments. +% \begin{macro}[aux]{\use_0_parameter:} +% \begin{macro}[aux]{\use_1_parameter:} +% \begin{macro}[aux]{\use_2_parameter:} +% \begin{macro}[aux]{\use_3_parameter:} +% \begin{macro}[aux]{\use_4_parameter:} +% \begin{macro}[aux]{\use_5_parameter:} +% \begin{macro}[aux]{\use_6_parameter:} +% \begin{macro}[aux]{\use_7_parameter:} +% \begin{macro}[aux]{\use_8_parameter:} +% \begin{macro}[aux]{\use_9_parameter:} +% For using parameters, i.e., when you need to define a function to +% process three parameters. See \textsf{xparse} for an application. % \begin{macrocode} -\def_protected_long_new:Npn \def_aux:NNnn #1#2#3#4 { - \cs_if_really_exist:cTF {def_aux_\tex_the:D\etex_numexpr:D #3 :NNn} - { - \cs_use:c {def_aux_\tex_the:D\etex_numexpr:D #3 :NNn} #1 #2 {#4} - } - { \def_arg_number_error_msg:Nn #2{#3} } -} -\def_new:Npn \def_aux:Ncnn #1#2{ - \exp_after:NN \def_aux:NNnn \exp_after:NN #1 \cs:w #2\cs_end:} -% \end{macrocode} -% The error message. -% \begin{macrocode} -\def_new:Npn \def_arg_number_error_msg:Nn #1#2 { - \err_latex_bug:x{ - You're~ trying~ to~ define~ the~ command~ `\token_to_string:N #1'~ - with~ \use_arg_i:n{\tex_the:D\etex_numexpr:D #2\scan_stop:} ~ - arguments~ but~ I~ only~ allow~ 0-9~ arguments.~ I~ can~ probably~ - not~ help~ you~ here - } -} +\cs_set_nopar:cpn{use_0_parameter:}{} +\cs_set_nopar:cpn{use_1_parameter:}{{##1}} +\cs_set_nopar:cpn{use_2_parameter:}{{##1}{##2}} +\cs_set_nopar:cpn{use_3_parameter:}{{##1}{##2}{##3}} +\cs_set_nopar:cpn{use_4_parameter:}{{##1}{##2}{##3}{##4}} +\cs_set_nopar:cpn{use_5_parameter:}{{##1}{##2}{##3}{##4}{##5}} +\cs_set_nopar:cpn{use_6_parameter:}{{##1}{##2}{##3}{##4}{##5}{##6}} +\cs_set_nopar:cpn{use_7_parameter:}{{##1}{##2}{##3}{##4}{##5}{##6}{##7}} +\cs_set_nopar:cpn{use_8_parameter:}{ + {##1}{##2}{##3}{##4}{##5}{##6}{##7}{##8}} +\cs_set_nopar:cpn{use_9_parameter:}{ + {##1}{##2}{##3}{##4}{##5}{##6}{##7}{##8}{##9}} % \end{macrocode} % \end{macro} % \end{macro} @@ -1904,409 +2676,332 @@ % \end{macro} % \end{macro} % \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} % -% \begin{macro}{\def_aux_use_0_parameter:} -% \begin{macro}{\def_aux_use_1_parameter:} -% \begin{macro}{\def_aux_use_2_parameter:} -% \begin{macro}{\def_aux_use_3_parameter:} -% \begin{macro}{\def_aux_use_4_parameter:} -% \begin{macro}{\def_aux_use_5_parameter:} -% \begin{macro}{\def_aux_use_6_parameter:} -% \begin{macro}{\def_aux_use_7_parameter:} -% \begin{macro}{\def_aux_use_8_parameter:} -% \begin{macro}{\def_aux_use_9_parameter:} -% Something similar to |\def_aux_9:NNn| but for using the -% parameters. +% \subsection{Copying definitions} +% +% \begin{macro}{\cs_set_eq:NN} +% \begin{macro}{\cs_set_eq:cN} +% \begin{macro}{\cs_set_eq:Nc} +% \begin{macro}{\cs_set_eq:cc} +% These macros allow us to copy the definition of a control sequence +% to another control sequence. +% +% 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 |=|. +% +% |\cs_set_eq:NN| is long to avoid problems with a literal argument +% of |\par|. While |\cs_new_eq:NN| will probably never be correct +% with a first argument of |\par|, define it long in order to throw +% an `already defined' error rather than `runaway argument'. +% +% The |c| variants are not protected in order for their arguments to +% be constructed in the correct context. +% % \begin{macrocode} -\def:cpn{def_aux_use_0_parameter:}{} -\def:cpn{def_aux_use_1_parameter:}{{##1}} -\def:cpn{def_aux_use_2_parameter:}{{##1}{##2}} -\def:cpn{def_aux_use_3_parameter:}{{##1}{##2}{##3}} -\def:cpn{def_aux_use_4_parameter:}{{##1}{##2}{##3}{##4}} -\def:cpn{def_aux_use_5_parameter:}{{##1}{##2}{##3}{##4}{##5}} -\def:cpn{def_aux_use_6_parameter:}{{##1}{##2}{##3}{##4}{##5}{##6}} -\def:cpn{def_aux_use_7_parameter:}{{##1}{##2}{##3}{##4}{##5}{##6}{##7}} -\def:cpn{def_aux_use_8_parameter:}{ - {##1}{##2}{##3}{##4}{##5}{##6}{##7}{##8}} -\def:cpn{def_aux_use_9_parameter:}{ - {##1}{##2}{##3}{##4}{##5}{##6}{##7}{##8}{##9}} +\cs_set_protected:Npn \cs_set_eq:NN #1 { \cs_set_eq:NwN #1=~ } +\cs_set_nopar:Npn \cs_set_eq:cN { \exp_args:Nc \cs_set_eq:NN } +\cs_set_nopar:Npn \cs_set_eq:Nc { \exp_args:NNc \cs_set_eq:NN } +\cs_set_nopar:Npn \cs_set_eq:cc { \exp_args:Ncc \cs_set_eq:NN } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} % -% \begin{macro}{\def:NNn} -% \begin{macro}{\def:NNx} -% \begin{macro}{\def:cNn} -% \begin{macro}{\def:cNx} -% \begin{macro}{\gdef:NNn} -% \begin{macro}{\gdef:NNx} -% \begin{macro}{\gdef:cNn} -% \begin{macro}{\gdef:cNx} -% \begin{macro}{\def_new:NNn} -% \begin{macro}{\def_new:NNx} -% \begin{macro}{\def_new:cNn} -% \begin{macro}{\def_new:cNx} -% \begin{macro}{\gdef_new:NNn} -% \begin{macro}{\gdef_new:NNx} -% \begin{macro}{\gdef_new:cNn} -% \begin{macro}{\gdef_new:cNx} -% Defining macros without delimited arguments is now relatively -% easy. First local and global versions of the usual |\def:Npn| -% operation. +% \begin{macro}{\cs_new_eq:NN} +% \begin{macro}{\cs_new_eq:cN} +% \begin{macro}{\cs_new_eq:Nc} +% \begin{macro}{\cs_new_eq:cc} % \begin{macrocode} -\def_new:Npn \def:NNn { \def_aux:NNnn \def:Npn } -\def_new:Npn \def:NNx { \def_aux:NNnn \def:Npx } -\def_new:Npn \def:cNn { \def_aux:Ncnn \def:Npn } -\def_new:Npn \def:cNx { \def_aux:Ncnn \def:Npx } -\def_new:Npn \gdef:NNn { \def_aux:NNnn \gdef:Npn } -\def_new:Npn \gdef:NNx { \def_aux:NNnn \gdef:Npx } -\def_new:Npn \gdef:cNn { \def_aux:Ncnn \gdef:Npn } -\def_new:Npn \gdef:cNx { \def_aux:Ncnn \gdef:Npx } -\def_new:Npn \def_new:NNn { \def_aux:NNnn \def_new:Npn } -\def_new:Npn \def_new:NNx { \def_aux:NNnn \def_new:Npx } -\def_new:Npn \def_new:cNn { \def_aux:Ncnn \def_new:Npn } -\def_new:Npn \def_new:cNx { \def_aux:Ncnn \def_new:Npx } -\def_new:Npn \gdef_new:NNn { \def_aux:NNnn \gdef_new:Npn } -\def_new:Npn \gdef_new:NNx { \def_aux:NNnn \gdef_new:Npx } -\def_new:Npn \gdef_new:cNn { \def_aux:Ncnn \gdef_new:Npn } -\def_new:Npn \gdef_new:cNx { \def_aux:Ncnn \gdef_new:Npx } +\cs_new_protected:Npn \cs_new_eq:NN #1 { + \chk_if_free_cs:N #1 + \cs_set_eq:NN #1 +} +\cs_new_nopar:Npn \cs_new_eq:cN { \exp_args:Nc \cs_new_eq:NN } +\cs_new_nopar:Npn \cs_new_eq:Nc { \exp_args:NNc \cs_new_eq:NN } +\cs_new_nopar:Npn \cs_new_eq:cc { \exp_args:Ncc \cs_new_eq:NN } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} % -% \begin{macro}{\def_long:NNn} -% \begin{macro}{\def_long:NNx} -% \begin{macro}{\def_long:cNn} -% \begin{macro}{\def_long:cNx} -% \begin{macro}{\gdef_long:NNn} -% \begin{macro}{\gdef_long:NNx} -% \begin{macro}{\gdef_long:cNn} -% \begin{macro}{\gdef_long:cNx} -% \begin{macro}{\def_long_new:NNn} -% \begin{macro}{\def_long_new:NNx} -% \begin{macro}{\def_long_new:cNn} -% \begin{macro}{\def_long_new:cNx} -% \begin{macro}{\gdef_long_new:NNn} -% \begin{macro}{\gdef_long_new:NNx} -% \begin{macro}{\gdef_long_new:cNn} -% \begin{macro}{\gdef_long_new:cNx} -% Long versions of the above. +% \begin{macro}{\cs_gset_eq:NN} +% \begin{macro}{\cs_gset_eq:cN} +% \begin{macro}{\cs_gset_eq:Nc} +% \begin{macro}{\cs_gset_eq:cc} % \begin{macrocode} -\def_new:Npn \def_long:NNn { \def_aux:NNnn \def_long:Npn } -\def_new:Npn \def_long:NNx { \def_aux:NNnn \def_long:Npx } -\def_new:Npn \def_long:cNn { \def_aux:Ncnn \def_long:Npn } -\def_new:Npn \def_long:cNx { \def_aux:Ncnn \def_long:Npx } -\def_new:Npn \gdef_long:NNn { \def_aux:NNnn \gdef_long:Npn } -\def_new:Npn \gdef_long:NNx { \def_aux:NNnn \gdef_long:Npx } -\def_new:Npn \gdef_long:cNn { \def_aux:Ncnn \gdef_long:Npn } -\def_new:Npn \gdef_long:cNx { \def_aux:Ncnn \gdef_long:Npx } -\def_new:Npn \def_long_new:NNn { \def_aux:NNnn \def_long_new:Npn } -\def_new:Npn \def_long_new:NNx { \def_aux:NNnn \def_long_new:Npx } -\def_new:Npn \def_long_new:cNn { \def_aux:Ncnn \def_long_new:Npn } -\def_new:Npn \def_long_new:cNx { \def_aux:Ncnn \def_long_new:Npx } -\def_new:Npn \gdef_long_new:NNn { \def_aux:NNnn \gdef_long_new:Npn } -\def_new:Npn \gdef_long_new:NNx { \def_aux:NNnn \gdef_long_new:Npx } -\def_new:Npn \gdef_long_new:cNn { \def_aux:Ncnn \gdef_long_new:Npn } -\def_new:Npn \gdef_long_new:cNx { \def_aux:Ncnn \gdef_long_new:Npx } +\cs_new_protected:Npn \cs_gset_eq:NN { \pref_global:D \cs_set_eq:NN } +\cs_new_nopar:Npn \cs_gset_eq:Nc { \exp_args:NNc \cs_gset_eq:NN } +\cs_new_nopar:Npn \cs_gset_eq:cN { \exp_args:Nc \cs_gset_eq:NN } +\cs_new_nopar:Npn \cs_gset_eq:cc { \exp_args:Ncc \cs_gset_eq:NN } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% % -% \begin{macro}{\def_protected:NNn} -% \begin{macro}{\def_protected:NNx} -% \begin{macro}{\def_protected:cNn} -% \begin{macro}{\def_protected:cNx} -% \begin{macro}{\gdef_protected:NNn} -% \begin{macro}{\gdef_protected:NNx} -% \begin{macro}{\gdef_protected:cNn} -% \begin{macro}{\gdef_protected:cNx} -% \begin{macro}{\def_protected_new:NNn} -% \begin{macro}{\def_protected_new:NNx} -% \begin{macro}{\def_protected_new:cNn} -% \begin{macro}{\def_protected_new:cNx} -% \begin{macro}{\gdef_protected_new:NNn} -% \begin{macro}{\gdef_protected_new:NNx} -% \begin{macro}{\gdef_protected_new:cNn} -% \begin{macro}{\gdef_protected_new:cNx} -% Protected versions of the above. +% \begin{macro}{\cs_gnew_eq:NN} +% \begin{macro}{\cs_gnew_eq:cN} +% \begin{macro}{\cs_gnew_eq:Nc} +% \begin{macro}{\cs_gnew_eq:cc} % \begin{macrocode} -\def_new:Npn \def_protected:NNn { \def_aux:NNnn \def_protected:Npn } -\def_new:Npn \def_protected:NNx { \def_aux:NNnn \def_protected:Npx } -\def_new:Npn \def_protected:cNn { \def_aux:Ncnn \def_protected:Npn } -\def_new:Npn \def_protected:cNx { \def_aux:Ncnn \def_protected:Npx } -\def_new:Npn \gdef_protected:NNn { \def_aux:NNnn \gdef_protected:Npn } -\def_new:Npn \gdef_protected:NNx { \def_aux:NNnn \gdef_protected:Npx } -\def_new:Npn \gdef_protected:cNn { \def_aux:Ncnn \gdef_protected:Npn } -\def_new:Npn \gdef_protected:cNx { \def_aux:Ncnn \gdef_protected:Npx } -\def_new:Npn \def_protected_new:NNn { \def_aux:NNnn \def_protected_new:Npn } -\def_new:Npn \def_protected_new:NNx { \def_aux:NNnn \def_protected_new:Npx } -\def_new:Npn \def_protected_new:cNn { \def_aux:Ncnn \def_protected_new:Npn } -\def_new:Npn \def_protected_new:cNx { \def_aux:Ncnn \def_protected_new:Npx } -\def_new:Npn \gdef_protected_new:NNn { \def_aux:NNnn \gdef_protected_new:Npn } -\def_new:Npn \gdef_protected_new:NNx { \def_aux:NNnn \gdef_protected_new:Npx } -\def_new:Npn \gdef_protected_new:cNn { \def_aux:Ncnn \gdef_protected_new:Npn } -\def_new:Npn \gdef_protected_new:cNx { \def_aux:Ncnn \gdef_protected_new:Npx } +\cs_new_protected:Npn \cs_gnew_eq:NN #1 { + \chk_if_free_cs:N #1 + \pref_global:D \cs_set_eq:NN #1 +} +\cs_new_nopar:Npn \cs_gnew_eq:cN { \exp_args:Nc \cs_gnew_eq:NN } +\cs_new_nopar:Npn \cs_gnew_eq:Nc { \exp_args:NNc \cs_gnew_eq:NN } +\cs_new_nopar:Npn \cs_gnew_eq:cc { \exp_args:Ncc \cs_gnew_eq:NN } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} % -% \begin{macro}{\def_protected_long:NNn} -% \begin{macro}{\def_protected_long:NNx} -% \begin{macro}{\def_protected_long:cNn} -% \begin{macro}{\def_protected_long:cNx} -% \begin{macro}{\gdef_protected_long:NNn} -% \begin{macro}{\gdef_protected_long:NNx} -% \begin{macro}{\gdef_protected_long:cNn} -% \begin{macro}{\gdef_protected_long:cNx} -% \begin{macro}{\def_protected_long_new:NNn} -% \begin{macro}{\def_protected_long_new:NNx} -% \begin{macro}{\def_protected_long_new:cNn} -% \begin{macro}{\def_protected_long_new:cNx} -% \begin{macro}{\gdef_protected_long_new:NNn} -% \begin{macro}{\gdef_protected_long_new:NNx} -% \begin{macro}{\gdef_protected_long_new:cNn} -% \begin{macro}{\gdef_protected_long_new:cNx} -% And finally both long and protected. +% +% \subsection{Undefining functions} +% +% \begin{macro}{\cs_gundefine:N } +% The following function is used to free the main memory from the +% definition of some function that isn't in use any longer. % \begin{macrocode} -\def_new:Npn \def_protected_long:NNn { \def_aux:NNnn \def_protected_long:Npn } -\def_new:Npn \def_protected_long:NNx { \def_aux:NNnn \def_protected_long:Npx } -\def_new:Npn \def_protected_long:cNn { \def_aux:Ncnn \def_protected_long:Npn } -\def_new:Npn \def_protected_long:cNx { \def_aux:Ncnn \def_protected_long:Npx } -\def_new:Npn \gdef_protected_long:NNn { \def_aux:NNnn \gdef_protected_long:Npn } -\def_new:Npn \gdef_protected_long:NNx { \def_aux:NNnn \gdef_protected_long:Npx } -\def_new:Npn \gdef_protected_long:cNn { \def_aux:Ncnn \gdef_protected_long:Npn } -\def_new:Npn \gdef_protected_long:cNx { \def_aux:Ncnn \gdef_protected_long:Npx } -\def_new:Npn \def_protected_long_new:NNn { - \def_aux:NNnn \def_protected_long_new:Npn } -\def_new:Npn \def_protected_long_new:NNx { - \def_aux:NNnn \def_protected_long_new:Npx } -\def_new:Npn \def_protected_long_new:cNn { - \def_aux:Ncnn \def_protected_long_new:Npn } -\def_new:Npn \def_protected_long_new:cNx { - \def_aux:Ncnn \def_protected_long_new:Npx } -\def_new:Npn \gdef_protected_long_new:NNn { - \def_aux:NNnn \gdef_protected_long_new:Npn } -\def_new:Npn \gdef_protected_long_new:NNx { - \def_aux:NNnn \gdef_protected_long_new:Npx } -\def_new:Npn \gdef_protected_long_new:cNn { - \def_aux:Ncnn \gdef_protected_long_new:Npn } -\def_new:Npn \gdef_protected_long_new:cNx { - \def_aux:Ncnn \gdef_protected_long_new:Npx } +\cs_new_nopar:Npn \cs_gundefine:N #1{\cs_gset_eq:NN #1\c_undefined:D} % \end{macrocode} % \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} % % -% \begin{macro}{\let:NN} -% \begin{macro}{\let:cN} -% \begin{macro}{\let:Nc} -% \begin{macro}{\let:cc} -% \begin{macro}{\let_new:NN} -% \begin{macro}{\let_new:cN} -% \begin{macro}{\let_new:Nc} -% \begin{macro}{\let_new:cc} -% These macros allow us to copy the definition of a control sequence -% to another control sequence. -% \begin{macrocode} -\def_protected_long_new:Npn \let:NN #1{ +% \subsection{Engine specific definitions} +% +% \begin{macro}{\c_xetex_is_engine_bool,\c_luatex_is_engine_bool} +% \begin{macro}[TF]{\xetex_if_engine:,\luatex_if_engine:} +% In some cases it will be useful to know which engine we're running. +% Don't provide a "_p" predicate because the "_bool" is used for the +% same thing. +% \begin{macrocode} +\if_cs_exist:N \xetex_version:D + \cs_new_eq:NN \c_xetex_is_engine_bool \c_true_bool +\else: + \cs_new_eq:NN \c_xetex_is_engine_bool \c_false_bool +\fi: +\prg_new_conditional:Npnn \xetex_if_engine: {TF,T,F} { + \if_bool:N \c_xetex_is_engine_bool + \prg_return_true: \else: \prg_return_false: \fi: +} % \end{macrocode} -% The |=| sign allows us to define funny char tokens like .|=| -% itself or \verb*= = with this function. For the definition of -% |\c_space_chartok{~}| to work we need the |~| after the |=| +% % \begin{macrocode} - \let:NwN #1=~} -\def_new:Npn\let:cN #1 {\exp_after:NN\let:NN\cs:w#1\cs_end:} -\def_new:Npn\let:Nc{\exp_args:NNc\let:NN} -\def_new:Npn\let:cc{\exp_args:Ncc\let:NN} -\def_new:Npn \let_new:NN #1{\chk_new_cs:N #1 - \let:NN #1} -\def_new:Npn \let_new:cN {\exp_args:Nc \let_new:NN} -\def_new:Npn \let_new:Nc {\exp_args:NNc \let_new:NN} -\def_new:Npn \let_new:cc {\exp_args:Ncc \let_new:NN} +\if_cs_exist:N \luatex_directlua:D + \cs_new_eq:NN \c_luatex_is_engine_bool \c_true_bool +\else: + \cs_new_eq:NN \c_luatex_is_engine_bool \c_false_bool +\fi: +\prg_set_conditional:Npnn \xetex_if_engine: {TF,T,F}{ + \if_bool:N \c_xetex_is_engine_bool \prg_return_true: + \else: \prg_return_false: \fi: +} +\prg_set_conditional:Npnn \luatex_if_engine: {TF,T,F}{ + \if_bool:N \c_luatex_is_engine_bool \prg_return_true: + \else: \prg_return_false: \fi: +} % \end{macrocode} % \end{macro} % \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} % -% \begin{macro}{\glet:NN} -% \begin{macro}{\glet:cN} -% \begin{macro}{\glet:Nc} -% \begin{macro}{\glet:cc} -% \begin{macro}{\glet_new:NN} -% \begin{macro}{\glet_new:cN} -% \begin{macro}{\glet_new:Nc} -% \begin{macro}{\glet_new:cc} -% These are global versions of some of the previously defined functions. +% +% +% +% \subsection{Scratch functions} +% +% \begin{macro}{\prg_do_nothing:} +% 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'. It is for example used in templates where +% depending on the users settings we have to either select an function that +% does something, or one that does nothing. % \begin{macrocode} -\def_protected_new:Npn \glet:NN {\pref_global:D \let:NN} -\def_protected_new:Npn \glet:Nc {\exp_args:NNc \glet:NN} -\def_protected_new:Npn \glet:cN {\exp_args:Nc \glet:NN} -\def_new:Npn \glet:cc {\exp_args:Ncc \glet:NN} -\def_new:Npn \glet_new:NN #1{\chk_new_cs:N #1 - \tex_global:D\let:NN #1} -\def_new:Npn \glet_new:cN {\exp_args:Nc \glet_new:NN} -\def_new:Npn \glet_new:Nc {\exp_args:NNc \glet_new:NN} -\def_new:Npn \glet_new:cc {\exp_args:Ncc \glet_new:NN} +\cs_new_nopar:Npn \prg_do_nothing: {} % \end{macrocode} % \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} % % -% \begin{macro}{\def:No} -% \begin{macro}{\gdef:No} -% |\def:No| expands its second argument one time before making -% the definition. +% \subsection{Defining functions from a given number of arguments} +% +% \begin{macro}{\cs_get_arg_count_from_signature:N} +% \begin{macro}[aux]{\cs_get_arg_count_from_signature_aux:nnN} +% \begin{macro}[aux]{\cs_get_arg_count_from_signature_auxii:w} +% Counting the number of tokens in the signature, i.e., the number +% of arguments the function should take. If there is no signature, +% we return that there is $-1$ arguments to signal an error. +% Otherwise we insert the string |9876543210| after the signature. +% If the signature is empty, the number we want is $0$ so we remove +% the first nine tokens and return the tenth. Similarly, if the +% signature is |nnn| we want to remove the nine tokens |nnn987654| +% and return $3$. Therefore, we simply remove the first nine tokens +% and then return the tenth. +% \begin{macrocode} +\cs_set:Npn \cs_get_arg_count_from_signature:N #1{ + \cs_split_function:NN #1 \cs_get_arg_count_from_signature_aux:nnN +} +\cs_set:Npn \cs_get_arg_count_from_signature_aux:nnN #1#2#3{ + \if_predicate:w #3 % \bool_if:NTF here + \exp_after:wN \use_i:nn + \else: + \exp_after:wN\use_ii:nn + \fi: + { + \exp_after:wN \cs_get_arg_count_from_signature_auxii:w + \use_none:nnnnnnnnn #2 9876543210\q_nil + } + {-1} +} +\cs_set:Npn \cs_get_arg_count_from_signature_auxii:w #1#2\q_nil{#1} +% \end{macrocode} +% A variant form we need right away. % \begin{macrocode} -\def_new:Npn \def:No{\exp_args:NNo\def:Npn} -\def_new:Npn \gdef:No {\exp_args:NNo\gdef:Npn} +\cs_set_nopar:Npn \cs_get_arg_count_from_signature:c { + \exp_args:Nc \cs_get_arg_count_from_signature:N +} % \end{macrocode} % \end{macro} % \end{macro} +% \end{macro} % -% \begin{macro}{\def_test_function_aux:Nnnn} -% \begin{macro}{\def_test_function_aux:Nnnx} -% \begin{macro}{\def_test_function:npn} -% \begin{macro}{\def_test_function:npx} -% \begin{macro}{\def_long_test_function:npn} -% \begin{macro}{\def_long_test_function:npx} -% \begin{macro}{\def_test_function_new:npn} -% \begin{macro}{\def_test_function_new:npx} -% \begin{macro}{\def_long_test_function_new:npn} -% \begin{macro}{\def_long_test_function_new:npx} -% We will often be defining several almost identical TF, T and F -% type functions so it makes sense for us to define a small function -% that will do this for us so that we are less likely to introduce -% typos (it does tend to happen). By doing it in two steps as below -% we can still retain a simple interface where you write the \TeX\ -% parameters as usual. Just don't do it when you're already within a -% conditional! % -% I think the ways of exiting conditionals below are as fast as they -% get. Using |\reverse_if:N| instead of |\else:| didn't give any -% difference I could measure. +% +% +% \begin{macro}[aux]{\cs_generate_from_arg_count:NNnn} +% \begin{macro}[aux]{\cs_generate_from_arg_count_error_msg:Nn} +% We provide a constructor function for defining functions with a +% given number of arguments. For this we need to choose the correct +% parameter text and then use that when defining. Since \TeX\ +% supports from zero to nine arguments, we use a simple switch to +% choose the correct parameter text, ensuring the result is returned +% after finishing the conditional. If it is not between zero and +% nine, we throw an error. +% +% 1: function to define, 2: with what to define it, 3: the number of +% args it requires and 4: the replacement text % \begin{macrocode} -\def_long_new:Npn \def_test_function_aux:Nnnn #1#2#3#4{ - #1 {#2TF} #3 {#4 - \exp_after:NN\use_arg_i:nn\else:\exp_after:NN\use_arg_ii:nn\fi:} - #1 {#2FT} #3 {#4 - \exp_after:NN\use_arg_ii:nn\else:\exp_after:NN\use_arg_i:nn\fi:} - #1 {#2T} #3 {#4 - \else:\exp_after:NN\use_none:nn\fi:\use_arg_i:n} - #1 {#2F} #3 {#4 - \exp_after:NN\use_none:nn\fi:\use_arg_i:n}} -\def_long_new:Npn \def_test_function_aux:Nnnx #1#2#3#4{ - #1 {#2TF} #3 {#4 - \exp_not:n{\exp_after:NN\use_arg_i:nn\else:\exp_after:NN\use_arg_ii:nn\fi:}} - #1 {#2FT} #3 {#4 - \exp_not:n{\exp_after:NN\use_arg_ii:nn\else:\exp_after:NN\use_arg_i:nn\fi:}} - #1 {#2T} #3 {#4 - \exp_not:n{\else:\exp_after:NN\use_none:nn\fi:\use_arg_i:n}} - #1 {#2F} #3 {#4 - \exp_not:n{\exp_after:NN\use_none:nn\fi:\use_arg_i:n}}} -\def_long_new:Npn \def_test_function:npn #1#2#{ - \def_test_function_aux:Nnnn \def:cpn {#1}{#2} -} -\def_long_new:Npn \def_test_function:npx #1#2#{ - \def_test_function_aux:Nnnx \def:cpx {#1}{#2} -} -\def_long_new:Npn \def_long_test_function:npn #1#2#{ - \def_test_function_aux:Nnnn \def_long:cpn {#1}{#2} -} -\def_long_new:Npn \def_long_test_function:npx #1#2#{ - \def_test_function_aux:Nnnx \def_long:cpx {#1}{#2} -} -\def_long_new:Npn \def_test_function_new:npn #1#2#{ - \def_test_function_aux:Nnnn \def_new:cpn {#1}{#2} +\cs_set:Npn \cs_generate_from_arg_count:NNnn #1#2#3#4{ + \tex_ifcase:D \etex_numexpr:D #3\tex_relax:D + \use_i_after_orelse:nw{#2#1} + \or: + \use_i_after_orelse:nw{#2#1 ##1} + \or: + \use_i_after_orelse:nw{#2#1 ##1##2} + \or: + \use_i_after_orelse:nw{#2#1 ##1##2##3} + \or: + \use_i_after_orelse:nw{#2#1 ##1##2##3##4} + \or: + \use_i_after_orelse:nw{#2#1 ##1##2##3##4##5} + \or: + \use_i_after_orelse:nw{#2#1 ##1##2##3##4##5##6} + \or: + \use_i_after_orelse:nw{#2#1 ##1##2##3##4##5##6##7} + \or: + \use_i_after_orelse:nw{#2#1 ##1##2##3##4##5##6##7##8} + \or: + \use_i_after_orelse:nw{#2#1 ##1##2##3##4##5##6##7##8##9} + \else: + \use_i_after_fi:nw{ + \cs_generate_from_arg_count_error_msg:Nn#1{#3} + \use_none:n % to remove replacement text + } + \fi: + {#4} } -\def_long_new:Npn \def_long_test_function_new:npn #1#2#{ - \def_test_function_aux:Nnnn \def_long_new:cpn {#1}{#2} +% \end{macrocode} +% A variant form we need right away. +% \begin{macrocode} +\cs_set_nopar:Npn \cs_generate_from_arg_count:cNnn { + \exp_args:Nc \cs_generate_from_arg_count:NNnn } -\def_long_new:Npn \def_test_function_new:npx #1#2#{ - \def_test_function_aux:Nnnx \def_new:cpx {#1}{#2} +% \end{macrocode} +% The error message. Elsewhere we use the value of $-1$ to signal a +% missing colon in a function, so provide a hint for help on this. +% \begin{macrocode} +\cs_set:Npn \cs_generate_from_arg_count_error_msg:Nn #1#2 { + \msg_kernel_bug:x { + You're~ trying~ to~ define~ the~ command~ `\token_to_str:N #1'~ + with~ \use:n{\tex_the:D\etex_numexpr:D #2\tex_relax:D} ~ + arguments~ but~ I~ only~ allow~ 0-9~arguments.~Perhaps~you~ + forgot~to~use~a~colon~in~the~function~name?~ + I~ can~ probably~ not~ help~ you~ here + } } -\def_long_new:Npn \def_long_test_function_new:npx #1#2#{ - \def_test_function_aux:Nnnx \def_long_new:cpx {#1}{#2} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% +% +% \subsection{Using the signature to define functions} +% +% We can now combine some of the tools we have to provide a simple +% interface for defining functions. We define some simpler functions +% with user interface |\cs_set:Nn \foo_bar:nn {#1,#2}|, i.e., the +% number of arguments is read from the signature. +% +% +% \begin{macro}{\cs_set:Nn} +% \begin{macro}{\cs_set:Nx} +% \begin{macro}{\cs_set_nopar:Nn} +% \begin{macro}{\cs_set_nopar:Nx} +% \begin{macro}{\cs_set_protected:Nn} +% \begin{macro}{\cs_set_protected:Nx} +% \begin{macro}{\cs_set_protected_nopar:Nn} +% \begin{macro}{\cs_set_protected_nopar:Nx} +% \begin{macro}{\cs_gset:Nn} +% \begin{macro}{\cs_gset:Nx} +% \begin{macro}{\cs_gset_nopar:Nn} +% \begin{macro}{\cs_gset_nopar:Nx} +% \begin{macro}{\cs_gset_protected:Nn} +% \begin{macro}{\cs_gset_protected:Nx} +% \begin{macro}{\cs_gset_protected_nopar:Nn} +% \begin{macro}{\cs_gset_protected_nopar:Nx} +% We want to define |\cs_set:Nn| as +% \begin{verbatim} +% \cs_set_protected:Npn \cs_set:Nn #1#2{ +% \cs_generate_from_arg_count:NNnn #1\cs_set:Npn +% {\cs_get_arg_count_from_signature:N #1}{#2} +% } +% \end{verbatim} +% In short, to define |\cs_set:Nn| we need just use |\cs_set:Npn|, +% everything else is the same for each variant. Therefore, we can +% make it simpler by temporarily defining a function to do this for +% us. +% \begin{macrocode} +\cs_set:Npn \cs_tmp:w #1#2#3{ + \cs_set_protected:cpx {cs_#1:#2}##1##2{ + \exp_not:N \cs_generate_from_arg_count:NNnn ##1 + \exp_after:wN \exp_not:N \cs:w cs_#1:#3 \cs_end: + {\exp_not:N\cs_get_arg_count_from_signature:N ##1}{##2} + } } % \end{macrocode} +% Then we define the 32 variants beginning with |N|. +% \begin{macrocode} +\cs_tmp:w {set}{Nn}{Npn} +\cs_tmp:w {set}{Nx}{Npx} +\cs_tmp:w {set_nopar}{Nn}{Npn} +\cs_tmp:w {set_nopar}{Nx}{Npx} +\cs_tmp:w {set_protected}{Nn}{Npn} +\cs_tmp:w {set_protected}{Nx}{Npx} +\cs_tmp:w {set_protected_nopar}{Nn}{Npn} +\cs_tmp:w {set_protected_nopar}{Nx}{Npx} +\cs_tmp:w {gset}{Nn}{Npn} +\cs_tmp:w {gset}{Nx}{Npx} +\cs_tmp:w {gset_nopar}{Nn}{Npn} +\cs_tmp:w {gset_nopar}{Nx}{Npx} +\cs_tmp:w {gset_protected}{Nn}{Npn} +\cs_tmp:w {gset_protected}{Nx}{Npx} +\cs_tmp:w {gset_protected_nopar}{Nn}{Npn} +\cs_tmp:w {gset_protected_nopar}{Nx}{Npx} +% \end{macrocode} % \end{macro} % \end{macro} % \end{macro} @@ -2317,86 +3012,50 @@ % \end{macro} % \end{macro} % \end{macro} -% -% -% \subsubsection{Further checking} -% -% \begin{macro}{\cs_if_free:NTF} -% \begin{macro}{\cs_if_free:NT} -% \begin{macro}{\cs_if_free:NF} -% The old |\@ifundefined| of \LaTeX{} 2.09 is re-implemented in the -% function |\cs_free:cTF|, again in a way that |\else:| and |\fi:| -% are removed. In this implementation this is absolutely -% necessary because functions inside the conditional parts expect -% 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_test_function_new:npn {cs_if_free:N}#1{\if:w\cs_if_free_p:N #1} -\let:NN \cs_free:NTF \cs_if_free:NTF -\let:NN \cs_free:NT \cs_if_free:NT -\let:NN \cs_free:NF \cs_if_free:NF -% \end{macrocode} % \end{macro} % \end{macro} % \end{macro} -% -% \begin{macro}{\cs_if_free:cTF} -% \begin{macro}{\cs_if_free:cT} -% \begin{macro}{\cs_if_free:cF} -% We have to implement the |c| variants `by hand' because a different -% test is necessary and I don't want the overhead for the test with -% |\if:w|. What a mistake Don made by making this a -% feature of |\cs:w|. If I'm not totally mistaken this -% feature alone has cost him more than 600\$ for bug-checks. -% \begin{macrocode} -\def_long_test_function_new:npn {cs_if_free:c}#1{ - \exp_after:NN \if_meaning:NN \cs:w#1\cs_end: \scan_stop:} -\let:NN \cs_free:cTF \cs_if_free:cTF -\let:NN \cs_free:cT \cs_if_free:cT -\let:NN \cs_free:cF \cs_if_free:cF -% \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % -% \begin{macro}{\cs_if_really_free:cTF} -% \begin{macro}{\cs_if_really_free:cT} -% \begin{macro}{\cs_if_really_free:cF} -% These versions are for special control sequences that can only be -% formed through |\cs:w ... \cs_end:|. They do not turn the control -% sequence formed into |\scan_stop:|. +% \begin{macro}{\cs_new:Nn} +% \begin{macro}{\cs_new:Nx} +% \begin{macro}{\cs_new_nopar:Nn} +% \begin{macro}{\cs_new_nopar:Nx} +% \begin{macro}{\cs_new_protected:Nn} +% \begin{macro}{\cs_new_protected:Nx} +% \begin{macro}{\cs_new_protected_nopar:Nn} +% \begin{macro}{\cs_new_protected_nopar:Nx} +% \begin{macro}{\cs_gnew:Nn} +% \begin{macro}{\cs_gnew:Nx} +% \begin{macro}{\cs_gnew_nopar:Nn} +% \begin{macro}{\cs_gnew_nopar:Nx} +% \begin{macro}{\cs_gnew_protected:Nn} +% \begin{macro}{\cs_gnew_protected:Nx} +% \begin{macro}{\cs_gnew_protected_nopar:Nn} +% \begin{macro}{\cs_gnew_protected_nopar:Nx} % \begin{macrocode} -\def_long_test_function_new:npn {cs_if_really_free:c}#1{ - \reverse_if:N\if_cs_exist:w #1\cs_end:} -\let:NN \cs_really_free:cTF \cs_if_really_free:cTF -\let:NN \cs_really_free:cT \cs_if_really_free:cT -\let:NN \cs_really_free:cF \cs_if_really_free:cF +\cs_tmp:w {new}{Nn}{Npn} +\cs_tmp:w {new}{Nx}{Npx} +\cs_tmp:w {new_nopar}{Nn}{Npn} +\cs_tmp:w {new_nopar}{Nx}{Npx} +\cs_tmp:w {new_protected}{Nn}{Npn} +\cs_tmp:w {new_protected}{Nx}{Npx} +\cs_tmp:w {new_protected_nopar}{Nn}{Npn} +\cs_tmp:w {new_protected_nopar}{Nx}{Npx} +\cs_tmp:w {gnew}{Nn}{Npn} +\cs_tmp:w {gnew}{Nx}{Npx} +\cs_tmp:w {gnew_nopar}{Nn}{Npn} +\cs_tmp:w {gnew_nopar}{Nx}{Npx} +\cs_tmp:w {gnew_protected}{Nn}{Npn} +\cs_tmp:w {gnew_protected}{Nx}{Npx} +\cs_tmp:w {gnew_protected_nopar}{Nn}{Npn} +\cs_tmp:w {gnew_protected_nopar}{Nx}{Npx} % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} -% -% \begin{macro}{\cs_if_exist:NTF} -% \begin{macro}{\cs_if_exist:NT} -% \begin{macro}{\cs_if_exist:NF} -% \begin{macro}{\cs_if_exist:cTF} -% \begin{macro}{\cs_if_exist:cT} -% \begin{macro}{\cs_if_exist:cF} -% \begin{macro}{\cs_if_really_exist:cTF} -% \begin{macro}{\cs_if_really_exist:cT} -% \begin{macro}{\cs_if_really_exist:cF} -% Now the same functions but with reverse logic: test if the control -% sequence exists. -% \begin{macrocode} -\def_long_test_function_new:npn {cs_if_exist:N}#1{\if:w\cs_if_exist_p:N #1} -\def_long_test_function_new:npn {cs_if_exist:c}#1{ - \exp_after:NN\reverse_if:N - \exp_after:NN \if_meaning:NN \cs:w#1\cs_end: \scan_stop:} -\def_long_test_function_new:npn {cs_if_really_exist:c}#1{ - \if_cs_exist:w #1\cs_end:} -% \end{macrocode} % \end{macro} % \end{macro} % \end{macro} @@ -2406,93 +3065,67 @@ % \end{macro} % \end{macro} % \end{macro} -% -% -% \subsubsection{Freeing memory} -% -% \begin{macro}{\cs_gundefine:N } -% The following function is used to free the main memory from the -% definition of some function that isn't in use any longer. -% \begin{macrocode} -\def_new:Npn \cs_gundefine:N #1{\glet:NN #1\c_undefined} -% \end{macrocode} % \end{macro} -% -% -% \subsubsection{Engine specific definitions} -% -% \begin{macro}{\engine_if_aleph:TF} -% In some cases it will be useful to know which engine we're running. -% \begin{macrocode} -\def_test_function_new:npn {engine_if_aleph:}{\if_cs_exist:N \aleph_textdir:D} -% \end{macrocode} % \end{macro} -% -% -% -% \subsubsection{Selecting tokens} -% -% \begin{macro}{\use_arg_i:n} -% This macro grabs its argument and returns it back to the input -% (with outer braces removed). -% \begin{macrocode} -%\def_long_new:Npn \use_arg_i:n #1{#1}% moved earlier -% \end{macrocode} +% \end{macro} % \end{macro} % -% \begin{macro}{\use:c} -% \begin{macro}{\cs_use:c} -% \begin{macro}{\use:cc} -% This macro grabs its argument and returns a csname from it. +% Then something similar for the |c| variants. +% \begin{verbatim} +% \cs_set_protected:Npn \cs_set:cn #1#2{ +% \cs_generate_from_arg_count:cNnn {#1}\cs_set:Npn +% {\cs_get_arg_count_from_signature:c {#1}}{#2} +% } +% \end{verbatim} % \begin{macrocode} -\def_new:Npn \use:c #1{\cs:w #1\cs_end:} -\def_new:Npn \cs_use:c #1 { \cs:w#1\cs_end: } +\cs_set:Npn \cs_tmp:w #1#2#3{ + \cs_set_protected:cpx {cs_#1:#2}##1##2{ + \exp_not:N\cs_generate_from_arg_count:cNnn {##1} + \exp_after:wN \exp_not:N \cs:w cs_#1:#3 \cs_end: + {\exp_not:N\cs_get_arg_count_from_signature:c {##1}}{##2} + } +} % \end{macrocode} -% THE NAME IS COMPLETELY WRONG!!!!! -% Morten says: Perhaps this is really |\exp_args:cc| instead? +% \begin{macro}{\cs_set:cn} +% \begin{macro}{\cs_set:cx} +% \begin{macro}{\cs_set_nopar:cn} +% \begin{macro}{\cs_set_nopar:cx} +% \begin{macro}{\cs_set_protected:cn} +% \begin{macro}{\cs_set_protected:cx} +% \begin{macro}{\cs_set_protected_nopar:cn} +% \begin{macro}{\cs_set_protected_nopar:cx} +% \begin{macro}{\cs_gset:cn} +% \begin{macro}{\cs_gset:cx} +% \begin{macro}{\cs_gset_nopar:cn} +% \begin{macro}{\cs_gset_nopar:cx} +% \begin{macro}{\cs_gset_protected:cn} +% \begin{macro}{\cs_gset_protected:cx} +% \begin{macro}{\cs_gset_protected_nopar:cn} +% \begin{macro}{\cs_gset_protected_nopar:cx} +% The 32 |c| variants. % \begin{macrocode} -\def_new:Npn \use:cc #1#2 - {\cs:w #1\exp_after:NN\cs_end:\cs:w #2\cs_end:} +\cs_tmp:w {set}{cn}{Npn} +\cs_tmp:w {set}{cx}{Npx} +\cs_tmp:w {set_nopar}{cn}{Npn} +\cs_tmp:w {set_nopar}{cx}{Npx} +\cs_tmp:w {set_protected}{cn}{Npn} +\cs_tmp:w {set_protected}{cx}{Npx} +\cs_tmp:w {set_protected_nopar}{cn}{Npn} +\cs_tmp:w {set_protected_nopar}{cx}{Npx} +\cs_tmp:w {gset}{cn}{Npn} +\cs_tmp:w {gset}{cx}{Npx} +\cs_tmp:w {gset_nopar}{cn}{Npn} +\cs_tmp:w {gset_nopar}{cx}{Npx} +\cs_tmp:w {gset_protected}{cn}{Npn} +\cs_tmp:w {gset_protected}{cx}{Npx} +\cs_tmp:w {gset_protected_nopar}{cn}{Npn} +\cs_tmp:w {gset_protected_nopar}{cx}{Npx} % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} -% -% \begin{macro}{\use_arg_i:nn} -% \begin{macro}{\use_arg_ii:nn} -% These macros are needed to provide functions with true and false -% cases, as introduced by Michael some time ago. By using -% |\exp_after:NN| |\use_arg_i:nn | |\else:| constructions it -% is possible to write code where the true or false case is able to -% access the following tokens from the input stream, which is not -% possible if the |\c_true| syntax is used. -% \begin{macrocode} -\def_long_new:Npn \use_arg_i:nn #1#2{#1} -\def_long_new:Npn \use_arg_ii:nn #1#2{#2} -% \end{macrocode} % \end{macro} % \end{macro} -% -% -% -% \begin{macro}{\use_arg_i:nnn} -% \begin{macro}{\use_arg_ii:nnn} -% \begin{macro}{\use_arg_iii:nnn} -% \begin{macro}{\use_arg_i:nnnn} -% \begin{macro}{\use_arg_ii:nnnn} -% \begin{macro}{\use_arg_iii:nnnn} -% \begin{macro}{\use_arg_iv:nnnn} -% We also need something for picking up arguments from a longer -% list. -% \begin{macrocode} -\def_long_new:NNn \use_arg_i:nnn 3{#1} -\def_long_new:NNn \use_arg_ii:nnn 3{#2} -\def_long_new:NNn \use_arg_iii:nnn 3{#3} -\def_long_new:NNn \use_arg_i:nnnn 4{#1} -\def_long_new:NNn \use_arg_ii:nnnn 4{#2} -\def_long_new:NNn \use_arg_iii:nnnn 4{#3} -\def_long_new:NNn \use_arg_iv:nnnn 4{#4} -% \end{macrocode} % \end{macro} % \end{macro} % \end{macro} @@ -2500,84 +3133,49 @@ % \end{macro} % \end{macro} % \end{macro} -% -% \begin{macro}{\use_arg_i_ii:nn} -% And a function for grabbing two arguments and returning them -% again. -% \begin{macrocode} -\def_long_new:NNn\use_arg_i_ii:nn 2{#1#2} -% \end{macrocode} % \end{macro} -% -% \begin{macro}{\use_none_delimit_by_q_nil:w} -% \begin{macro}{\use_none_delimit_by_q_stop:w} -% Functions that gobble everything until they see either |\q_nil| or -% |\q_stop| resp. -% \begin{macrocode} -\def_long_new:Npn \use_none_delimit_by_q_nil:w #1\q_nil{} -\def_long_new:Npn \use_none_delimit_by_q_stop:w #1\q_stop{} -% \end{macrocode} % \end{macro} % \end{macro} -% -% \begin{macro}{\use_arg_i_delimit_by_q_nil:nw} -% \begin{macro}{\use_arg_i_delimit_by_q_stop:nw} -% Same as above but execute first argument after gobbling. Very -% useful when you need to skip the rest of a mapping sequence but -% want an easy way to control what should be expanded next. -% \begin{macrocode} -\def_long_new:Npn \use_arg_i_delimit_by_q_nil:nw #1#2\q_nil{#1} -\def_long_new:Npn \use_arg_i_delimit_by_q_stop:nw #1#2\q_stop{#1} -% \end{macrocode} -% \end{macro} % \end{macro} % -% -% \begin{macro}{\use_arg_i_after_fi:nw} -% \begin{macro}{\use_arg_i_after_else:nw} -% \begin{macro}{\use_arg_i_after_or:nw} -% \begin{macro}{\use_arg_i_after_or:nw} -% Returns the first argument after ending the conditional. +% \begin{macro}{\cs_new:cn} +% \begin{macro}{\cs_new:cx} +% \begin{macro}{\cs_new_nopar:cn} +% \begin{macro}{\cs_new_nopar:cx} +% \begin{macro}{\cs_new_protected:cn} +% \begin{macro}{\cs_new_protected:cx} +% \begin{macro}{\cs_new_protected_nopar:cn} +% \begin{macro}{\cs_new_protected_nopar:cx} +% \begin{macro}{\cs_gnew:cn} +% \begin{macro}{\cs_gnew:cx} +% \begin{macro}{\cs_gnew_nopar:cn} +% \begin{macro}{\cs_gnew_nopar:cx} +% \begin{macro}{\cs_gnew_protected:cn} +% \begin{macro}{\cs_gnew_protected:cx} +% \begin{macro}{\cs_gnew_protected_nopar:cn} +% \begin{macro}{\cs_gnew_protected_nopar:cx} % \begin{macrocode} -\def_long_new:Npn \use_arg_i_after_fi:nw #1\fi:{\fi: #1} -\def_long_new:Npn \use_arg_i_after_else:nw #1\else:#2\fi:{\fi: #1} -\def_long_new:Npn \use_arg_i_after_or:nw #1\or: #2\fi: {\fi:#1} -\def_long_new:Npn \use_arg_i_after_orelse:nw #1 #2#3\fi: {\fi:#1} +\cs_tmp:w {new}{cn}{Npn} +\cs_tmp:w {new}{cx}{Npx} +\cs_tmp:w {new_nopar}{cn}{Npn} +\cs_tmp:w {new_nopar}{cx}{Npx} +\cs_tmp:w {new_protected}{cn}{Npn} +\cs_tmp:w {new_protected}{cx}{Npx} +\cs_tmp:w {new_protected_nopar}{cn}{Npn} +\cs_tmp:w {new_protected_nopar}{cx}{Npx} +\cs_tmp:w {gnew}{cn}{Npn} +\cs_tmp:w {gnew}{cx}{Npx} +\cs_tmp:w {gnew_nopar}{cn}{Npn} +\cs_tmp:w {gnew_nopar}{cx}{Npx} +\cs_tmp:w {gnew_protected}{cn}{Npn} +\cs_tmp:w {gnew_protected}{cx}{Npx} +\cs_tmp:w {gnew_protected_nopar}{cn}{Npn} +\cs_tmp:w {gnew_protected_nopar}{cx}{Npx} % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} -% -% \subsubsection{Gobbling tokens from input} -% -% \begin{macro}{\use_none:n} -% \begin{macro}{\use_none:nn} -% \begin{macro}{\use_none:nnn} -% \begin{macro}{\use_none:nnnn} -% \begin{macro}{\use_none:nnnnn} -% \begin{macro}{\use_none:nnnnnn} -% \begin{macro}{\use_none:nnnnnnn} -% \begin{macro}{\use_none:nnnnnnnn} -% \begin{macro}{\use_none:nnnnnnnnn} -% To gobble tokens from the input we use a standard naming -% convention: the number of tokens gobbled is given by the number of -% |n|'s following the |:| in the name. Although defining -% |\use_none:nnn| and above as separate calls of |\use_none:n| and -% |\use_none:nn| is slightly faster, this is very non-intuitive to -% the programmer who will assume that expanding such a function once -% will take care of gobbling all the tokens in one go. -% \begin{macrocode} -%\def_long_new:NNn \use_none:n 1{}% moved earlier -\def_long_new:NNn \use_none:nn 2{} -\def_long_new:NNn \use_none:nnn 3{} -\def_long_new:NNn \use_none:nnnn 4{} -\def_long_new:NNn \use_none:nnnnn 5{} -\def_long_new:NNn \use_none:nnnnnn 6{} -\def_long_new:NNn \use_none:nnnnnnn 7{} -\def_long_new:NNn \use_none:nnnnnnnn 8{} -\def_long_new:NNn \use_none:nnnnnnnnn 9{} -% \end{macrocode} % \end{macro} % \end{macro} % \end{macro} @@ -2587,240 +3185,100 @@ % \end{macro} % \end{macro} % \end{macro} -% -% -% \subsubsection{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} % -% \subsubsection{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}{\cs_if_eq:NNTF} -% \begin{macro}{\cs_if_eq:NNT} -% \begin{macro}{\cs_if_eq:NNF} -% \begin{macro}{\cs_if_eq:cNTF} -% \begin{macro}{\cs_if_eq:cNT} -% \begin{macro}{\cs_if_eq:cNF} -% \begin{macro}{\cs_if_eq:NcTF} -% \begin{macro}{\cs_if_eq:NcT} -% \begin{macro}{\cs_if_eq:NcF} -% \begin{macro}{\cs_if_eq:ccTF} -% \begin{macro}{\cs_if_eq:ccT} -% \begin{macro}{\cs_if_eq:ccF} +% \begin{macro}{\cs_if_eq_p:NN,\cs_if_eq_p:cN,\cs_if_eq_p:Nc,\cs_if_eq_p:cc} +% \begin{macro}[TF]{\cs_if_eq:NN,\cs_if_eq:cN,\cs_if_eq:Nc,\cs_if_eq:cc} % Check if two control sequences are identical. % \begin{macrocode} -\def_test_function_new:npn {cs_if_eq:NN} #1#2{\if_meaning:NN #1#2} -\def_new:Npn \cs_if_eq:cNTF {\exp_args:Nc \cs_if_eq:NNTF} -\def_new:Npn \cs_if_eq:cNT {\exp_args:Nc \cs_if_eq:NNT} -\def_new:Npn \cs_if_eq:cNF {\exp_args:Nc \cs_if_eq:NNF} -\def_new:Npn \cs_if_eq:NcTF {\exp_args:NNc \cs_if_eq:NNTF} -\def_new:Npn \cs_if_eq:NcT {\exp_args:NNc \cs_if_eq:NNT} -\def_new:Npn \cs_if_eq:NcF {\exp_args:NNc \cs_if_eq:NNF} -\def_new:Npn \cs_if_eq:ccTF {\exp_args:Ncc \cs_if_eq:NNTF} -\def_new:Npn \cs_if_eq:ccT {\exp_args:Ncc \cs_if_eq:NNT} -\def_new:Npn \cs_if_eq:ccF {\exp_args:Ncc \cs_if_eq:NNF} +\prg_set_conditional:Npnn \cs_if_eq:NN #1#2{p,TF,T,F}{ + \if_meaning:w #1#2 + \prg_return_true: \else: \prg_return_false: \fi: +} +\cs_new_nopar:Npn \cs_if_eq_p:cN {\exp_args:Nc \cs_if_eq_p:NN} +\cs_new_nopar:Npn \cs_if_eq:cNTF {\exp_args:Nc \cs_if_eq:NNTF} +\cs_new_nopar:Npn \cs_if_eq:cNT {\exp_args:Nc \cs_if_eq:NNT} +\cs_new_nopar:Npn \cs_if_eq:cNF {\exp_args:Nc \cs_if_eq:NNF} +\cs_new_nopar:Npn \cs_if_eq_p:Nc {\exp_args:NNc \cs_if_eq_p:NN} +\cs_new_nopar:Npn \cs_if_eq:NcTF {\exp_args:NNc \cs_if_eq:NNTF} +\cs_new_nopar:Npn \cs_if_eq:NcT {\exp_args:NNc \cs_if_eq:NNT} +\cs_new_nopar:Npn \cs_if_eq:NcF {\exp_args:NNc \cs_if_eq:NNF} +\cs_new_nopar:Npn \cs_if_eq_p:cc {\exp_args:Ncc \cs_if_eq_p:NN} +\cs_new_nopar:Npn \cs_if_eq:ccTF {\exp_args:Ncc \cs_if_eq:NNTF} +\cs_new_nopar:Npn \cs_if_eq:ccT {\exp_args:Ncc \cs_if_eq:NNT} +\cs_new_nopar:Npn \cs_if_eq:ccF {\exp_args:Ncc \cs_if_eq:NNF} % \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} % % 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}} +\cs_new_nopar:Npn\file_not_found:nTF #1#2#3{\IfFileExists{#1}{#3}{#2}} % \end{macrocode} % % -% \subsubsection{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 \m{true arg} or the \m{false -% arg}. These arguments are denoted with "T" and "F" repectively. An -% example would be -% \begin{quote} -% "\cs_free:cTF{abc}{...}{...}" -% \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 \m{true code} and/or -% \m{false code} are always defined in a way that the code of the chosen -% alternative can operate on following tokens in the input stream while -% the predicate implementations always have an "\else:" or "\fi:" -% interfering. This can be important in scanner implementations. % +% \begin{macro}{\prg_set_eq_conditional:NNn,\prg_new_eq_conditional:NNn} +% \begin{macrocode} +\cs_set:Npn \prg_set_eq_conditional:NNn #1#2#3 { + \prg_set_eq_conditional_aux:NNNn \cs_set_eq:cc #1#2 {#3} +} +\cs_set:Npn \prg_new_eq_conditional:NNn #1#2#3 { + \prg_set_eq_conditional_aux:NNNn \cs_new_eq:cc #1#2 {#3} +} +% \end{macrocode} +% \begin{macro}[aux]{\prg_set_eq_conditional_aux:NNNn, +% \prg_set_eq_conditional_aux:NNNw} +% \begin{macrocode} +\cs_set:Npn \prg_set_eq_conditional_aux:NNNn #1#2#3#4 { + \prg_set_eq_conditional_aux:NNNw #1#2#3#4,?,\q_recursion_stop +} +% \end{macrocode} +% Manual clist loop over argument "#4". +% \begin{macrocode} +\cs_set:Npn \prg_set_eq_conditional_aux:NNNw #1#2#3#4, { + \if:w ? #4 \scan_stop: + \exp_after:wN \use_none_delimit_by_q_recursion_stop:w + \fi: + #1 { + \exp_args:NNc \cs_split_function:NN #2 {prg_conditional_form_#4:nnn} + }{ + \exp_args:NNc \cs_split_function:NN #3 {prg_conditional_form_#4:nnn} + } + \prg_set_eq_conditional_aux:NNNw #1{#2}{#3} +} +% \end{macrocode} +% \begin{macrocode} +\cs_set:Npn \prg_conditional_form_p:nnn #1#2#3 {#1_p:#2} +\cs_set:Npn \prg_conditional_form_TF:nnn #1#2#3 {#1:#2TF} +\cs_set:Npn \prg_conditional_form_T:nnn #1#2#3 {#1:#2T} +\cs_set:Npn \prg_conditional_form_F:nnn #1#2#3 {#1:#2F} +% \end{macrocode} +% \end{macro} +% \end{macro} % % \begin{macrocode} %</initex|package> +% \end{macrocode} +% +% \begin{macrocode} %<*showmemory> \showMemUsage %</showmemory> % \end{macrocode} % -% \endinput -% -% $Log$ -% Revision 1.38 2006/08/06 17:05:25 morten -% Make \chk_new_cs:N bulletproof -% -% Revision 1.37 2006/07/30 14:37:47 morten -% Added \str_if_eq_var_p:nf -% -% Revision 1.36 2006/07/23 13:43:21 morten -% Removed extra occurrence of \str_if_eq_p:nn -% -% Revision 1.35 2006/07/17 22:25:31 morten -% Fix logic of \chk_new_cs:N and rename \cs_if_eq_p:NN to -% \cs_if_eq_name_p:NN because it is not their meaning but their names -% which are compared. -% -% Revision 1.34 2006/07/08 22:46:17 morten -% Rearranged some code and added complete set of \use_none:<args> -% functions. -% -% Revision 1.33 2006/07/06 14:53:56 morten -% Added \def:NNn functions, reorganized code and much much more. -% -% Revision 1.32 2006/06/03 17:14:43 morten -% Added more \use_arg_... functions. -% -% Revision 1.31 2006/03/20 18:26:33 braams -% Updated the copyright notice (2006) and demoted all implementation -% sections to subsections and so on to clean up the toc for source3.tex -% -% Revision 1.30 2006/01/22 19:35:46 morten -% Changed \use_none:nnn to gobble all tokens in one go and added -% \use_arg_i_ii:nn for l3keyval. -% -% Revision 1.29 2006/01/16 09:47:49 morten -% Fixed deleted brace -% -% Revision 1.28 2006/01/15 19:08:28 morten -% Fixed typos in some \if names -% -% Revision 1.27 2006/01/04 01:29:36 morten -% Changed "robust" to "protected". +% \end{implementation} % -% Revision 1.26 2005/12/27 09:53:55 morten -% Fixed some names, added a few more \use_... functions, changed RCS -% information retrieval -% -% Revision 1.25 2005/12/23 11:16:15 morten -% *** empty log message *** -% -% Revision 1.24 2005/12/02 15:21:55 morten -% Fixed minor typo -% -% Revision 1.23 2005/11/20 07:10:03 morten -% Added a few missing functions. New function type -% \def_test_function:npn to help define TF-type functions. -% -% Revision 1.22 2005/11/08 04:16:17 morten -% Fixed typo. -% -% Revision 1.21 2005/10/27 22:35:13 morten -% Cleaned up a bit and moved some code to l3num. -% -% Revision 1.20 2005/07/12 16:10:24 morten -% Allow \cs_if_eq_p:NN to accept \par. (Yes, real life experience) -% -% Revision 1.19 2005/04/06 21:34:55 morten -% Added more functions. Moved \engine_aleph:TF from l3prg -% -% Revision 1.18 2005/03/25 23:52:24 braams -% The definition of \next needs to be seen at initex time, -% not at typesetting time -% -% Revision 1.17 2005/03/22 23:28:46 morten -% Moved some code to l3prg, removed obsolete code, cleaned up documentation. -% -% Revision 1.16 2005/03/16 22:31:44 braams -% Changed definition of \c_zero and \c_minus_one -% -% Revision 1.15 2005/03/15 23:16:27 braams -% Some tweaking with the docstrip guards to get the documentation to -% come out right. -% -% Revision 1.14 2005/03/15 22:50:00 braams -% Made loadable by initex as the second file -% -% Revision 1.13 2005/03/11 21:32:21 braams -% Fixed the use of RCS information; -% moved \RequirePackage after \StopEventually +% \PrintIndex % +% \endinput diff --git a/Master/texmf-dist/source/latex/expl3/l3box.dtx b/Master/texmf-dist/source/latex/expl3/l3box.dtx index c697225b8b3..bf619435d63 100644 --- a/Master/texmf-dist/source/latex/expl3/l3box.dtx +++ b/Master/texmf-dist/source/latex/expl3/l3box.dtx @@ -1,5 +1,5 @@ % \iffalse -%% File: l3box.dtx Copyright (C) 2005-2007 LaTeX3 project +%% File: l3box.dtx Copyright (C) 2005-2009 LaTeX3 project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this @@ -17,7 +17,7 @@ %% %% The development version of the bundle can be found at %% -%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/ +%% http://www.latex-project.org/svnroot/experimental/trunk/ %% %% for those people who are interested. %% @@ -36,7 +36,7 @@ \RequirePackage{l3names} %</driver|package> %\fi -\GetIdInfo$Id: l3box.dtx 718 2007-12-16 22:59:58Z morten $ +\GetIdInfo$Id: l3box.dtx 1375 2009-06-01 12:28:52Z joseph $ {L3 Experimental Box module} %\iffalse %<*driver> @@ -44,9 +44,9 @@ \ProvidesFile{\filename.\filenameext} [\filedate\space v\fileversion\space\filedescription] %\iffalse -\documentclass{l3doc} +\documentclass[full]{l3doc} \begin{document} -\DocInput{\filename.\filenameext} +\DocInput{l3box.dtx} \end{document} %</driver> % \fi @@ -60,20 +60,19 @@ % \date{\filedate} % \maketitle % -% \section{Boxes} -% +% \begin{documentation} % % There are three kinds of box operations: horizontal mode denoted % with prefix |\hbox_|, vertical mode with prefix |\vbox_|, and the % generic operations working in both modes with prefix |\box_|. % % -% \subsection{Generic functions} +% \section{Generic functions} % % \begin{function}{% % \box_new:N | % \box_new:c | -% \box_new_l:N +%^^A \box_new_l:N % } % \begin{syntax} % "\box_new:N" <box> @@ -103,18 +102,34 @@ % \end{texnote} % \end{function} % +% \begin{function}{\box_if_horizontal_p:N | +% \box_if_horizontal_p:c | +% \box_if_horizontal:N / (TF) | +% \box_if_horizontal:c / (TF) } +% \begin{syntax} +% "\box_if_horizontal:NTF" <box> \Arg{true code} \Arg{false code} +% \end{syntax} +% Tests if <box> is an horizontal box and executes <code> accordingly. +% \end{function} +% +% \begin{function}{\box_if_vertical_p:N | +% \box_if_vertical_p:c | +% \box_if_vertical:N / (TF) | +% \box_if_vertical:c / (TF) } +% \begin{syntax} +% "\box_if_vertical:NTF" <box> \Arg{true code} \Arg{false code} +% \end{syntax} +% Tests if <box> is a vertical box and executes <code> accordingly. +% \end{function} +% % \begin{function}{% % \box_if_empty_p:N | % \box_if_empty_p:c | -% \box_if_empty:NTF | -% \box_if_empty:cTF | -% \box_if_empty:NT | -% \box_if_empty:cT | -% \box_if_empty:NF | -% \box_if_empty:cF | +% \box_if_empty:N / (TF) | +% \box_if_empty:c / (TF) | % } % \begin{syntax} -% "\box_if_empty:NTF" <box> "{"\m{true code}"}" "{"\m{false code}"}" +% "\box_if_empty:NTF" <box> \Arg{true code} \Arg{false code} % \end{syntax} % Tests if <box> is empty (void) and executes "code" according to the % test outcome. @@ -160,8 +175,8 @@ % \begin{syntax} % "\box_set_to_last:N" <box> % \end{syntax} -% Sets <box> equal to the previous box |\R_last_box| and removes -% |\R_last_box| from the current list (unless in outer vertical +% Sets <box> equal to the previous box |\l_last_box| and removes +% |\l_last_box| from the current list (unless in outer vertical % or math mode). % \end{function} % @@ -172,7 +187,7 @@ % \box_move_down:nn | % } % \begin{syntax} -% "\box_move_left:nn" "{"<dimen>"}" "{"<box function>"}" +% "\box_move_left:nn" \Arg{dimen} \Arg{box function} % \end{syntax} % Moves <box function> <dimen> in the direction specified. <box % function> is either an operation on a box such as "\box_use:N" or a @@ -258,23 +273,25 @@ % % % \begin{variable}{% -% \R_last_box | +% \l_last_box | % } % \begin{syntax} % \end{syntax} -% "\R_last_box" is a read-only box register. You can set other -% boxes to this box, which will then be removed from the current -% list. +% "\l_last_box" is more or less a read-only box register managed by the +% engine. It denotes the last box on the current list if there is one, +% otherwise it is void. You can set other +% boxes to this box, with the result that the last box on the current list is +% removed at the same time (so it is with variable with side-effects). % \end{variable} % % -% \subsection{Horizontal mode} +% \section{Horizontal mode} % % \begin{function}{% % \hbox:n | % } % \begin{syntax} -% "\hbox:n" "{"<contents>"}" +% "\hbox:n" \Arg{contents} % \end{syntax} % Places a "hbox" of natural size. % \end{function} @@ -286,7 +303,7 @@ % \hbox_gset:cn | % } % \begin{syntax} -% "\hbox_set:Nn" <box> "{"\m{contents}"}" +% "\hbox_set:Nn" <box> \Arg{contents} % \end{syntax} % Sets <box> to be a vertical mode box containing \m{contents}. It has % it's natural size. "\hbox_gset:Nn" does it globally. @@ -300,7 +317,7 @@ % \hbox_gset_to_wd:cnn | % } % \begin{syntax} -% "\hbox_set_to_wd:Nnn" <box> "{"\m{dimen}"}" "{"\m{contents}"}" +% "\hbox_set_to_wd:Nnn" <box> \Arg{dimen} \Arg{contents} % \end{syntax} % Sets <box> to contain \m{contents} and have width <dimen>. % "\hbox_gset_to_wd:Nn" does it globally. @@ -309,11 +326,14 @@ % % \begin{function}{% % \hbox_to_wd:nn | +% \hbox_to_zero:n | % } % \begin{syntax} -% "\hbox_to_wd:nn" "{"<dimen>"}" <contents> +% "\hbox_to_wd:nn" \Arg{dimen} <contents> +% "\hbox_to_zero:n" <contents> % \end{syntax} -% Places a <box> of width <dimen> containing <contents>. +% Places a <box> of width <dimen> containing <contents>. "\hbox_to_zero:n" +% is a shorthand for a width of zero. % \end{function} % % @@ -336,7 +356,9 @@ % % \begin{function}{% % \hbox_unpack:N | +% \hbox_unpack:c | % \hbox_unpack_clear:N | +% \hbox_unpack_clear:c | % } % \begin{syntax} % "\hbox_unpack:N" <box> @@ -352,7 +374,17 @@ % % % -% \subsection{Vertical mode} +% \section{Vertical mode} +% +% \begin{function}{% +% \vbox:n | +% } +% \begin{syntax} +% "\vbox:n" \Arg{contents} +% \end{syntax} +% Places a "vbox" of natural size with baseline equal to the baseline +% of the last line in the box. +% \end{function} % % \begin{function}{% % \vbox_set:Nn | @@ -361,10 +393,10 @@ % \vbox_gset:cn | % } % \begin{syntax} -% "\vbox_set:Nn" <box> "{"\m{contents}"}" +% "\vbox_set:Nn" <box> \Arg{contents} % \end{syntax} % Sets <box> to be a vertical mode box containing \m{contents}. It has -% it's natural size. "\vbox_gset:Nn" does it globally. +% its natural size. "\vbox_gset:Nn" does it globally. % \end{function} % % @@ -376,7 +408,7 @@ % \vbox_gset_to_ht:ccn | % } % \begin{syntax} -% "\vbox_set_to_ht:Nnn" <box> "{"\m{dimen}"}" "{"\m{contents}"}" +% "\vbox_set_to_ht:Nnn" <box> \Arg{dimen} \Arg{contents} % \end{syntax} % Sets <box> to contain \m{contents} and have total height <dimen>. % "\vbox_gset_to_ht:Nn" does it globally. @@ -401,7 +433,7 @@ % \vbox_set_split_to_ht:NNn | % } % \begin{syntax} -% "\vbox_set_split_to_ht:NNn" <box1> <box2> "{"<dimen>"}" +% "\vbox_set_split_to_ht:NNn" <box1> <box2> \Arg{dimen} % \end{syntax} % Sets <box1> to contain the top <dimen> part of <box2>. % \begin{texnote} @@ -410,21 +442,11 @@ % \end{function} % % \begin{function}{% -% \vbox:n | -% } -% \begin{syntax} -% "\vbox:n" "{"<contents>"}" -% \end{syntax} -% Places a "vbox" of natural size with baseline equal to the baseline -% of the last line in the box. -% \end{function} -% -% \begin{function}{% % \vbox_to_ht:nn | % \vbox_to_zero:n | % } % \begin{syntax} -% "\vbox_to_ht:nn" "{"<dimen>"}" <contents> \\ +% "\vbox_to_ht:nn" \Arg{dimen} <contents> \\ % "\vbox_to_zero:n" <contents> % \end{syntax} % Places a <box> of size <dimen> containing <contents>. @@ -433,7 +455,9 @@ % % \begin{function}{% % \vbox_unpack:N | +% \vbox_unpack:c | % \vbox_unpack_clear:N | +% \vbox_unpack_clear:c | % } % \begin{syntax} % "\vbox_unpack:N" <box> @@ -446,19 +470,22 @@ % \end{function} % % -% \StopEventually{} +% \end{documentation} % +% \begin{implementation} % % -% \subsection{The Implementation} +% +% \section{\pkg{l3box} implementation} % % % Announce and ensure that the required packages are loaded. % \begin{macrocode} -%<package>\ProvidesExplPackage -%<package> {\filename}{\filedate}{\fileversion}{\filedescription} -%<package&!check>\RequirePackage{l3prg,l3token}\par -%<package&check>\RequirePackage{l3chk}\par +%<*package> +\ProvidesExplPackage + {\filename}{\filedate}{\fileversion}{\filedescription} +\package_check_loaded_expl: +%</package> %<*initex|package> % \end{macrocode} % @@ -466,11 +493,10 @@ % comment it very extensively. % % -% \subsubsection{Generic boxes} +% \subsection{Generic boxes} % -% \begin{macro}{\box_new:N} -% \begin{macro}{\box_new_l:N} -% \begin{macro}{\box_new:c} +% \begin{macro}{\box_new:N,\box_new:c} +%^^A \begin{macro}{\box_new_l:N} % Defining a new \m{box} register. % \begin{macrocode} %<*initex> @@ -480,19 +506,26 @@ % shouldn't be allocated\dots % \begin{macrocode} \seq_put_right:Nn \g_box_allocation_seq {255} -\def_new:Npn \box_new:N #1 {\alloc_reg:NnNN g {box} \tex_mathchardef:D #1} -\def_new:Npn \box_new_l:N #1 {\alloc_reg:NnNN l {box} \tex_mathchardef:D #1} +\cs_new_nopar:Npn \box_new:N #1 {\alloc_reg:NnNN g {box} \tex_mathchardef:D #1} +\cs_new_nopar:Npn \box_new_l:N #1 {\alloc_reg:NnNN l {box} \tex_mathchardef:D #1} %</initex> % \end{macrocode} % When we run on top of \LaTeX, we just use its allocation % mechanism. % \begin{macrocode} -%<package>\let_new:NN \box_new:N \newbox -\def_new:Npn \box_new:c {\exp_args:Nc \box_new:N} +%<*package> +\cs_new:Npn \box_new:N #1 { + \chk_if_free_cs:N #1 + \newbox #1 +} +%</package> +% \end{macrocode} +% +% \begin{macrocode} +\cs_generate_variant:Nn \box_new:N {c} % \end{macrocode} % \end{macro} -% \end{macro} -% \end{macro} +%^^A \end{macro} % % \begin{macro}{\if_hbox:N} % \begin{macro}{\if_vbox:N} @@ -500,97 +533,97 @@ % The primitives for testing if a \m{box} is empty/void or which % type of box it is. % \begin{macrocode} -\let_new:NN \if_hbox:N \tex_ifhbox:D -\let_new:NN \if_vbox:N \tex_ifvbox:D -\let_new:NN \if_box_empty:N \tex_ifvoid:D +\cs_new_eq:NN \if_hbox:N \tex_ifhbox:D +\cs_new_eq:NN \if_vbox:N \tex_ifvbox:D +\cs_new_eq:NN \if_box_empty:N \tex_ifvoid:D % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % +% +% \begin{macro}{\box_if_horizontal_p:N,\box_if_horizontal_p:c} +% \begin{macro}{\box_if_vertical_p:N,\box_if_vertical_p:c} +% \begin{macro}[TF]{\box_if_horizontal:N,\box_if_horizontal:c} +% \begin{macro}[TF]{\box_if_vertical:N,\box_if_vertical:c} +% \begin{macrocode} +\prg_new_conditional:Nnn \box_if_horizontal:N {p,TF,T,F} { + \tex_ifhbox:D #1 \prg_return_true: \else: \prg_return_false: \fi: +} +\prg_new_conditional:Nnn \box_if_vertical:N {p,TF,T,F} { + \tex_ifvbox:D #1 \prg_return_true: \else: \prg_return_false: \fi: +} +\cs_generate_variant:Nn \box_if_horizontal_p:N {c} +\cs_generate_variant:Nn \box_if_horizontal:NTF {c} +\cs_generate_variant:Nn \box_if_horizontal:NT {c} +\cs_generate_variant:Nn \box_if_horizontal:NF {c} +\cs_generate_variant:Nn \box_if_vertical_p:N {c} +\cs_generate_variant:Nn \box_if_vertical:NTF {c} +\cs_generate_variant:Nn \box_if_vertical:NT {c} +\cs_generate_variant:Nn \box_if_vertical:NF {c} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% % \begin{macro}{\box_if_empty_p:N} % \begin{macro}{\box_if_empty_p:c} -% \begin{macro}{\box_if_empty:NTF} -% \begin{macro}{\box_if_empty:cTF} -% \begin{macro}{\box_if_empty:NT} -% \begin{macro}{\box_if_empty:cT} -% \begin{macro}{\box_if_empty:NF} -% \begin{macro}{\box_if_empty:cF} +% \begin{macro}[TF]{\box_if_empty:N} +% \begin{macro}[TF]{\box_if_empty:c} % Testing if a \m{box} is empty/void. % \begin{macrocode} -\def_new:Npn \box_if_empty_p:N #1{ - \if_box_empty:N #1 \c_true \else: \c_false \fi:} -\def_new:Npn \box_if_empty_p:c {\exp_args:Nc \box_if_empty_p:N} -\def_test_function_new:npn {box_if_empty:N}#1{\if_box_empty:N #1} -\def_new:Npn \box_if_empty:cTF {\exp_args:Nc \box_if_empty:NTF} -\def_new:Npn \box_if_empty:cT {\exp_args:Nc \box_if_empty:NT} -\def_new:Npn \box_if_empty:cF {\exp_args:Nc \box_if_empty:NF} +\prg_new_conditional:Nnn \box_if_empty:N {p,TF,T,F} { + \tex_ifvoid:D #1 \prg_return_true: \else: \prg_return_false: \fi: +} +\cs_generate_variant:Nn \box_if_empty_p:N {c} +\cs_generate_variant:Nn \box_if_empty:NTF {c} +\cs_generate_variant:Nn \box_if_empty:NT {c} +\cs_generate_variant:Nn \box_if_empty:NF {c} % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} % % -% \begin{macro}{\box_set_eq:NN} -% \begin{macro}{\box_set_eq:cN} -% \begin{macro}{\box_set_eq:Nc} -% \begin{macro}{\box_set_eq:cc} +% \begin{macro}{\box_set_eq:NN,\box_set_eq:cN, +% \box_set_eq:Nc,\box_set_eq:cc} % Assigning the contents of a box to be another box. % This clears the second box globally (that's how \TeX{} does it). % \begin{macrocode} -\def_new:Npn \box_set_eq:NN #1#2 {\tex_setbox:D #1 \tex_box:D #2} -\def_new:Npn \box_set_eq:cN {\exp_args:Nc \box_set_eq:NN} -\def_new:Npn \box_set_eq:Nc {\exp_args:NNc \box_set_eq:NN} -\def_new:Npn \box_set_eq:cc {\exp_args:Ncc \box_set_eq:NN} +\cs_new_nopar:Npn \box_set_eq:NN #1#2 {\tex_setbox:D #1 \tex_box:D #2} +\cs_generate_variant:Nn \box_set_eq:NN {cN,Nc,cc} % \end{macrocode} % \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} % -% \begin{macro}{\box_gset_eq:NN} -% \begin{macro}{\box_gset_eq:cN} -% \begin{macro}{\box_gset_eq:Nc} -% \begin{macro}{\box_gset_eq:cc} +% \begin{macro}{\box_gset_eq:NN,\box_gset_eq:cN, +% \box_gset_eq:Nc,\box_gset_eq:cc} % Global version of the above. % \begin{macrocode} -\def_new:Npn \box_gset_eq:NN {\pref_global:D\box_set_eq:NN} -\def_new:Npn \box_gset_eq:cN {\exp_args:Nc \box_gset_eq:NN} -\def_new:Npn \box_gset_eq:Nc {\exp_args:NNc \box_gset_eq:NN} -\def_new:Npn \box_gset_eq:cc {\exp_args:Ncc \box_gset_eq:NN} +\cs_new_nopar:Npn \box_gset_eq:NN {\pref_global:D\box_set_eq:NN} +\cs_generate_variant:Nn \box_gset_eq:NN {cN,Nc,cc} % \end{macrocode} % \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} % -% \begin{macro}{\R_last_box} +% \begin{macro}{\l_last_box} % A different name for this read-only primitive. % \begin{macrocode} -\let_new:NN \R_last_box \tex_lastbox:D +\cs_new_eq:NN \l_last_box \tex_lastbox:D % \end{macrocode} % \end{macro} % -% \begin{macro}{\box_set_to_last:N} -% \begin{macro}{\box_set_to_last:c} -% \begin{macro}{\box_gset_to_last:N} -% \begin{macro}{\box_gset_to_last:c} +% \begin{macro}{\box_set_to_last:N,\box_set_to_last:c} +% \begin{macro}{\box_gset_to_last:N,\box_gset_to_last:c} % Set a box to the previous box. % \begin{macrocode} -\def_new:Npn \box_set_to_last:N #1{\tex_setbox:D#1\R_last_box} -\def_new:Npn \box_set_to_last:c {\exp_args:Nc \box_set_to_last:N} -\def_new:Npn \box_gset_to_last:N {\pref_global:D \box_set_to_last:N} -\def_new:Npn \box_gset_to_last:c {\exp_args:Nc \box_gset_to_last:N} +\cs_new_nopar:Npn \box_set_to_last:N #1{\tex_setbox:D#1\l_last_box} +\cs_generate_variant:Nn \box_set_to_last:N {c} +\cs_new_nopar:Npn \box_gset_to_last:N {\pref_global:D \box_set_to_last:N} +\cs_generate_variant:Nn \box_gset_to_last:N {c} % \end{macrocode} % \end{macro} % \end{macro} -% \end{macro} -% \end{macro} % % \begin{macro}{\box_move_left:nn} % \begin{macro}{\box_move_right:nn} @@ -598,89 +631,73 @@ % \begin{macro}{\box_move_down:nn} % Move box material in different directions. % \begin{macrocode} -\def_long_new:Npn \box_move_left:nn #1#2{\tex_moveleft:D\dim_eval:n{#1}{#2}} -\def_long_new:Npn \box_move_right:nn #1#2{\tex_moveright:D\dim_eval:n{#1}{#2}} -\def_long_new:Npn \box_move_up:nn #1#2{\tex_raise:D\dim_eval:n{#1}{#2}} -\def_long_new:Npn \box_move_down:nn #1#2{\tex_lower:D\dim_eval:n{#1}{#2}} +\cs_new:Npn \box_move_left:nn #1#2{\tex_moveleft:D\dim_eval:n{#1}{#2}} +\cs_new:Npn \box_move_right:nn #1#2{\tex_moveright:D\dim_eval:n{#1}{#2}} +\cs_new:Npn \box_move_up:nn #1#2{\tex_raise:D\dim_eval:n{#1}{#2}} +\cs_new:Npn \box_move_down:nn #1#2{\tex_lower:D\dim_eval:n{#1}{#2}} % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % -% \begin{macro}{\box_clear:N} -% \begin{macro}{\box_clear:c} -% \begin{macro}{\box_gclear:N} -% \begin{macro}{\box_gclear:c} +% \begin{macro}{\box_clear:N,\box_clear:c} +% \begin{macro}{\box_gclear:N,\box_gclear:c} % Clear a \m{box} register. % \begin{macrocode} -\def_new:Npn \box_clear:N #1{\box_set_eq:NN #1 \c_empty_box } -\def_new:Npn \box_clear:c {\exp_args:Nc \box_clear:N } -\def_new:Npn \box_gclear:N {\pref_global:D\box_clear:N} -\def_new:Npn \box_gclear:c {\exp_args:Nc \box_gclear:c } +\cs_new_nopar:Npn \box_clear:N #1{\box_set_eq:NN #1 \c_empty_box } +\cs_generate_variant:Nn \box_clear:N {c} +\cs_new_nopar:Npn \box_gclear:N {\pref_global:D\box_clear:N} +\cs_generate_variant:Nn \box_gclear:N {c} % \end{macrocode} % \end{macro} % \end{macro} -% \end{macro} -% \end{macro} % % -% \begin{macro}{\box_ht:N} -% \begin{macro}{\box_ht:c} -% \begin{macro}{\box_dp:N} -% \begin{macro}{\box_dp:c} -% \begin{macro}{\box_wd:n} -% \begin{macro}{\box_wd:c} +% \begin{macro}{\box_ht:N,\box_ht:c} +% \begin{macro}{\box_dp:N,\box_dp:c} +% \begin{macro}{\box_wd:N,\box_wd:c} % Accessing the height, depth, and width of a \m{box} register. % \begin{macrocode} -\let_new:NN \box_ht:N \tex_ht:D -\def_new:Npn \box_ht:c {\exp_args:Nc \box_ht:N} -\let_new:NN \box_dp:N \tex_dp:D -\def_new:Npn \box_dp:c {\exp_args:Nc \box_dp:N} -\let_new:NN \box_wd:N \tex_wd:D -\def_new:Npn \box_wd:c {\exp_args:Nc \box_wd:N} +\cs_new_eq:NN \box_ht:N \tex_ht:D +\cs_new_eq:NN \box_dp:N \tex_dp:D +\cs_new_eq:NN \box_wd:N \tex_wd:D +\cs_generate_variant:Nn \box_ht:N {c} +\cs_generate_variant:Nn \box_dp:N {c} +\cs_generate_variant:Nn \box_wd:N {c} % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} % -% \begin{macro}{\box_use_clear:N} -% \begin{macro}{\box_use_clear:c} -% \begin{macro}{\box_use:N} -% \begin{macro}{\box_use:c} -% Using a \m{box}. This is just \TeX{} primitives with meaningful +% \begin{macro}{\box_use_clear:N,\box_use_clear:c} +% \begin{macro}{\box_use:N,\box_use:c} +% Using a \m{box}. These are just \TeX{} primitives with meaningful % names. % \begin{macrocode} -\let_new:NN \box_use_clear:N \tex_box:D -\def_new:Npn \box_use_clear:c {\exp_args:Nc \box_use_clear:N} -\let_new:NN \box_use:N \tex_copy:D -\def_new:Npn \box_use:c {\exp_args:Nc \box_use:N} +\cs_new_eq:NN \box_use_clear:N \tex_box:D +\cs_generate_variant:Nn \box_use_clear:N {c} +\cs_new_eq:NN \box_use:N \tex_copy:D +\cs_generate_variant:Nn \box_use:N {c} % \end{macrocode} % \end{macro} % \end{macro} -% \end{macro} -% \end{macro} % -% \begin{macro}{\box_show:N} -% \begin{macro}{\box_show:c} +% \begin{macro}{\box_show:N,\box_show:c} % Show the contents of a box and write it into the log file. % \begin{macrocode} -\let:NN \box_show:N \tex_showbox:D -\def_new:Npn \box_show:c {\exp_args:Nc \box_show:N} +\cs_set_eq:NN \box_show:N \tex_showbox:D +\cs_generate_variant:Nn \box_show:N {c} % \end{macrocode} % \end{macro} -% \end{macro} % % \begin{macro}{\c_empty_box} % \begin{macro}{\l_tmpa_box} % \begin{macro}{\l_tmpb_box} % We allocate some \m{box} registers here (and borrow a few from \LaTeX). % \begin{macrocode} -%<package>\let:NN \c_empty_box \voidb@x -%<package>\let_new:NN \l_tmpa_box \@tempboxa +%<package>\cs_set_eq:NN \c_empty_box \voidb@x +%<package>\cs_new_eq:NN \l_tmpa_box \@tempboxa %<initex>\box_new:N \c_empty_box %<initex>\box_new:N \l_tmpa_box \box_new:N \l_tmpb_box @@ -690,66 +707,56 @@ % \end{macro} % % -% \subsubsection{Vertical boxes} +% \subsection{Vertical boxes} % % % \begin{macro}{\vbox:n} % Put a vertical box directly into the input stream. % \begin{macrocode} -\def_new:Npn \vbox:n {\tex_vbox:D \scan_stop:} +\cs_new_nopar:Npn \vbox:n {\tex_vbox:D \scan_stop:} % \end{macrocode} % \end{macro} % -% \begin{macro}{\vbox_set:Nn} -% \begin{macro}{\vbox_set:cn} -% \begin{macro}{\vbox_gset:Nn} -% \begin{macro}{\vbox_gset:cn} +% \begin{macro}{\vbox_set:Nn,\vbox_set:cn} +% \begin{macro}{\vbox_gset:Nn,\vbox_gset:cn} % Storing material in a vertical box with a natural height. % \begin{macrocode} -\def_long_new:Npn \vbox_set:Nn #1#2 {\tex_setbox:D #1 \tex_vbox:D {#2}} -\def_new:Npn \vbox_set:cn {\exp_args:Nc \vbox_set:Nn} -\def_new:Npn \vbox_gset:Nn {\pref_global:D \vbox_set:Nn} -\def_new:Npn \vbox_gset:cn {\exp_args:Nc \vbox_gset:Nn} +\cs_new:Npn \vbox_set:Nn #1#2 {\tex_setbox:D #1 \tex_vbox:D {#2}} +\cs_generate_variant:Nn \vbox_set:Nn {cn} +\cs_new_nopar:Npn \vbox_gset:Nn {\pref_global:D \vbox_set:Nn} +\cs_generate_variant:Nn \vbox_gset:Nn {cn} % \end{macrocode} % \end{macro} % \end{macro} -% \end{macro} -% \end{macro} % -% \begin{macro}{\vbox_set_to_ht:Nnn} -% \begin{macro}{\vbox_set_to_ht:cnn} -% \begin{macro}{\vbox_gset_to_ht:Nnn} -% \begin{macro}{\vbox_gset_to_ht:cnn} -% \begin{macro}{\vbox_gset_to_ht:ccn} +% \begin{macro}{\vbox_set_to_ht:Nnn,\vbox_set_to_ht:cnn} +% \begin{macro}{\vbox_gset_to_ht:Nnn,\vbox_gset_to_ht:cnn,\vbox_gset_to_ht:ccn} % Storing material in a vertical box with a specified height. % \begin{macrocode} -\def_long_new:Npn \vbox_set_to_ht:Nnn #1#2#3 { - \tex_setbox:D #1 \tex_vbox:D to #2 {#3}} -\def_new:Npn \vbox_set_to_ht:cnn{\exp_args:Nc \vbox_set_to_ht:Nnn } -\def_new:Npn \vbox_gset_to_ht:Nnn {\pref_global:D \vbox_set_to_ht:Nnn } -\def_new:Npn \vbox_gset_to_ht:cnn{\exp_args:Nc \vbox_gset_to_ht:Nnn } -\def_new:Npn \vbox_gset_to_ht:ccn {\exp_args:Ncc \vbox_gset_to_ht:Nnn} +\cs_new:Npn \vbox_set_to_ht:Nnn #1#2#3 { + \tex_setbox:D #1 \tex_vbox:D to #2 {#3} +} +\cs_generate_variant:Nn \vbox_set_to_ht:Nnn {cnn} +\cs_new_nopar:Npn \vbox_gset_to_ht:Nnn { \pref_global:D \vbox_set_to_ht:Nnn } +\cs_generate_variant:Nn \vbox_gset_to_ht:Nnn {cnn,ccn} % \end{macrocode} % \end{macro} % \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} % % % \begin{macro}{\vbox_set_inline_begin:N} % \begin{macro}{\vbox_set_inline_end:} % \begin{macro}{\vbox_gset_inline_begin:N} -% \begin{macro}{\vbox_set_inline_end:} +% \begin{macro}{\vbox_gset_inline_end:} % Storing material in a vertical box. This type is useful in % environment definitions. % \begin{macrocode} -\def_new:Npn \vbox_set_inline_begin:N #1 { +\cs_new_nopar:Npn \vbox_set_inline_begin:N #1 { \tex_setbox:D #1 \tex_vbox:D \c_group_begin_token } -\let_new:NN \vbox_set_inline_end: \c_group_end_token -\def_new:Npn \vbox_gset_inline_begin:N { +\cs_new_eq:NN \vbox_set_inline_end: \c_group_end_token +\cs_new_nopar:Npn \vbox_gset_inline_begin:N { \pref_global:D \vbox_set_inline_begin:N } -\let_new:NN \vbox_gset_inline_end: \c_group_end_token +\cs_new_eq:NN \vbox_gset_inline_end: \c_group_end_token % \end{macrocode} % \end{macro} % \end{macro} @@ -761,8 +768,8 @@ % \begin{macro}{\vbox_to_zero:n} % Put a vertical box directly into the input stream. % \begin{macrocode} -\def_long_new:Npn \vbox_to_ht:nn #1#2{\tex_vbox:D to \dim_eval:n{#1}{#2}} -\def_long_new:Npn \vbox_to_zero:n #1 {\tex_vbox:D to \c_zero_dim {#1}} +\cs_new:Npn \vbox_to_ht:nn #1#2{\tex_vbox:D to \dim_eval:n{#1}{#2}} +\cs_new:Npn \vbox_to_zero:n #1 {\tex_vbox:D to \c_zero_dim {#1}} % \end{macrocode} % \end{macro} % \end{macro} @@ -770,130 +777,111 @@ % \begin{macro}{\vbox_set_split_to_ht:NNn} % Splitting a vertical box in two. % \begin{macrocode} -\def_new:Npn \vbox_set_split_to_ht:NNn #1#2#3{ +\cs_new_nopar:Npn \vbox_set_split_to_ht:NNn #1#2#3{ \tex_setbox:D #1 \tex_vsplit:D #2 to #3 } % \end{macrocode} % \end{macro} % -% \begin{macro}{\vbox_unpack:N} -% \begin{macro}{\vbox_unpack:c} -% \begin{macro}{\vbox_unpack_clear:N} -% \begin{macro}{\vbox_unpack_clear:c} +% \begin{macro}{\vbox_unpack:N,\vbox_unpack:c} +% \begin{macro}{\vbox_unpack_clear:N,\vbox_unpack_clear:c} % Unpacking a box and if requested also clear it. % \begin{macrocode} -\let_new:NN \vbox_unpack:N \tex_unvcopy:D -\def_new:Npn \vbox_unpack:c {\exp_args:Nc \vbox_unpack:N} -\let_new:NN \vbox_unpack_clear:N \tex_unvbox:D -\def_new:Npn \vbox_unpack_clear:c {\exp_args:Nc \vbox_unpack_clear:N} +\cs_new_eq:NN \vbox_unpack:N \tex_unvcopy:D +\cs_generate_variant:Nn \vbox_unpack:N {c} +\cs_new_eq:NN \vbox_unpack_clear:N \tex_unvbox:D +\cs_generate_variant:Nn \vbox_unpack_clear:N {c} % \end{macrocode} % \end{macro} % \end{macro} -% \end{macro} -% \end{macro} % % % % % % -% \subsubsection{Horizontal boxes} +% \subsection{Horizontal boxes} % % % \begin{macro}{\hbox:n} % Put a horizontal box directly into the input stream. % \begin{macrocode} -\def_new:Npn \hbox:n {\tex_hbox:D \scan_stop:} +\cs_new_nopar:Npn \hbox:n {\tex_hbox:D \scan_stop:} % \end{macrocode} % \end{macro} % -% \begin{macro}{\hbox_set:Nn} -% \begin{macro}{\hbox_set:cn} -% \begin{macro}{\hbox_gset:Nn} -% \begin{macro}{\hbox_gset:cn} +% \begin{macro}{\hbox_set:Nn,\hbox_set:cn} +% \begin{macro}{\hbox_gset:Nn,\hbox_gset:cn} % Assigning the contents of a box to be another box. % This clears the second box globally (that's how \TeX{} does it). % \begin{macrocode} -\def_long_new:Npn \hbox_set:Nn #1#2 {\tex_setbox:D #1 \tex_hbox:D {#2}} -\def_new:Npn \hbox_set:cn {\exp_args:Nc \hbox_set:Nn} -\def_new:Npn \hbox_gset:Nn {\pref_global:D \hbox_set:Nn} -\def_new:Npn \hbox_gset:cn {\exp_args:Nc \hbox_gset:Nn} +\cs_new:Npn \hbox_set:Nn #1#2 {\tex_setbox:D #1 \tex_hbox:D {#2}} +\cs_generate_variant:Nn \hbox_set:Nn {cn} +\cs_new_nopar:Npn \hbox_gset:Nn {\pref_global:D \hbox_set:Nn} +\cs_generate_variant:Nn \hbox_gset:Nn {cn} % \end{macrocode} % \end{macro} % \end{macro} -% \end{macro} -% \end{macro} % -% \begin{macro}{\hbox_set_to_wd:Nnn} -% \begin{macro}{\hbox_set_to_wd:cnn} -% \begin{macro}{\hbox_gset_to_wd:Nnn} -% \begin{macro}{\hbox_gset_to_wd:cnn} +% \begin{macro}{\hbox_set_to_wd:Nnn,\hbox_set_to_wd:cnn} +% \begin{macro}{\hbox_gset_to_wd:Nnn,\hbox_gset_to_wd:cnn} % Storing material in a horizontal box with a specified width. % \begin{macrocode} -\def_long_new:Npn \hbox_set_to_wd:Nnn #1#2#3 { - \tex_setbox:D #1 \tex_hbox:D to \dim_eval:n{#2} {#3}} -\def_new:Npn \hbox_set_to_wd:cnn{\exp_args:Nc \hbox_set_to_wd:Nnn } -\def_new:Npn \hbox_gset_to_wd:Nnn {\pref_global:D \hbox_set_to_wd:Nnn } -\def_new:Npn \hbox_gset_to_wd:cnn{\exp_args:Nc \hbox_gset_to_wd:Nnn } +\cs_new:Npn \hbox_set_to_wd:Nnn #1#2#3 { + \tex_setbox:D #1 \tex_hbox:D to \dim_eval:n{#2} {#3} +} +\cs_generate_variant:Nn \hbox_set_to_wd:Nnn {cnn} +\cs_new_nopar:Npn \hbox_gset_to_wd:Nnn {\pref_global:D \hbox_set_to_wd:Nnn } +\cs_generate_variant:Nn \hbox_gset_to_wd:Nnn {cnn} % \end{macrocode} % \end{macro} % \end{macro} -% \end{macro} -% \end{macro} % % -% \begin{macro}{\hbox_set_inline_begin:N} -% \begin{macro}{\hbox_set_inline_begin:c} -% \begin{macro}{\hbox_set_inline_end:} -% \begin{macro}{\hbox_gset_inline_begin:N} -% \begin{macro}{\hbox_gset_inline_begin:c} +% \begin{macro}{\hbox_set_inline_begin:N,\hbox_set_inline_begin:c} % \begin{macro}{\hbox_set_inline_end:} +% \begin{macro}{\hbox_gset_inline_begin:N,\hbox_gset_inline_begin:c} +% \begin{macro}{\hbox_gset_inline_end:} % Storing material in a horizontal box. This type is useful in % environment definitions. % \begin{macrocode} -\def_new:Npn \hbox_set_inline_begin:N #1 { - \tex_setbox:D #1 \tex_hbox:D \c_group_begin_token } -\def:Npn \hbox_set_inline_begin:c {\exp_args:Nc - \hbox_set_inline_begin:N} -\let_new:NN \hbox_set_inline_end: \c_group_end_token -\def_new:Npn \hbox_gset_inline_begin:N { - \pref_global:D \hbox_set_inline_begin:N } -\def:Npn \hbox_gset_inline_begin:c {\exp_args:Nc - \hbox_gset_inline_begin:N } -\let_new:NN \hbox_gset_inline_end: \c_group_end_token +\cs_new_nopar:Npn \hbox_set_inline_begin:N #1 { + \tex_setbox:D #1 \tex_hbox:D \c_group_begin_token +} +\cs_generate_variant:Nn \hbox_set_inline_begin:N {c} +\cs_new_eq:NN \hbox_set_inline_end: \c_group_end_token +\cs_new_nopar:Npn \hbox_gset_inline_begin:N { + \pref_global:D \hbox_set_inline_begin:N +} +\cs_generate_variant:Nn \hbox_gset_inline_begin:N {c} +\cs_new_eq:NN \hbox_gset_inline_end: \c_group_end_token % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} -% \end{macro} -% \end{macro} % % \begin{macro}{\hbox_to_wd:nn} % \begin{macro}{\hbox_to_zero:n} % Put a horizontal box directly into the input stream. % \begin{macrocode} -\def_long_new:Npn \hbox_to_wd:nn #1#2 {\tex_hbox:D to #1 {#2}} -\def_long_new:Npn \hbox_to_zero:n #1 {\tex_hbox:D to \c_zero_skip {#1}} +\cs_new:Npn \hbox_to_wd:nn #1#2 {\tex_hbox:D to #1 {#2}} +\cs_new:Npn \hbox_to_zero:n #1 {\tex_hbox:D to \c_zero_skip {#1}} % \end{macrocode} % \end{macro} % \end{macro} % -% \begin{macro}{\hbox_unpack:N} -% \begin{macro}{\hbox_unpack:c} -% \begin{macro}{\hbox_unpack_clear:N} -% \begin{macro}{\hbox_unpack_clear:c} +% \begin{macro}{\hbox_unpack:N,\hbox_unpack:c} +% \begin{macro}{\hbox_unpack_clear:N,\hbox_unpack_clear:c} % Unpacking a box and if requested also clear it. % \begin{macrocode} -\let_new:NN \hbox_unpack:N \tex_unhcopy:D -\def_new:Npn \hbox_unpack:c {\exp_args:Nc \hbox_unpack:N} -\let_new:NN \hbox_unpack_clear:N \tex_unhbox:D -\def_new:Npn \hbox_unpack_clear:c {\exp_args:Nc \hbox_unpack_clear:N} +\cs_new_eq:NN \hbox_unpack:N \tex_unhcopy:D +\cs_generate_variant:Nn \hbox_unpack:N {c} +\cs_new_eq:NN \hbox_unpack_clear:N \tex_unhbox:D +\cs_generate_variant:Nn \hbox_unpack_clear:N {c} % \end{macrocode} % \end{macro} % \end{macro} -% \end{macro} -% \end{macro} % % % @@ -910,40 +898,15 @@ % % \begin{macrocode} %</initex|package> +% \end{macrocode} +% +% \begin{macrocode} %<*showmemory> \showMemUsage %</showmemory> % \end{macrocode} % -% \endinput -% -% $Log$ -% Revision 1.10 2006/03/20 18:26:34 braams -% Updated the copyright notice (2006) and demoted all implementation -% sections to subsections and so on to clean up the toc for source3.tex -% -% Revision 1.9 2006/01/19 22:30:30 morten -% Added functions for accessing \tex_lastbox:D and moving box material -% in the four directions. -% -% Revision 1.8 2005/12/27 16:04:12 morten -% Changed RCS information retrieval -% -% Revision 1.7 2005/10/27 23:11:12 morten -% Moved \if_hbox:N, \if_vbox:N and _if_box_empty:N here -% -% Revision 1.6 2005/04/25 16:15:17 morten -% Fixed \bgroup/\egroup and made it run under initex -% -% Revision 1.5 2005/04/06 22:35:33 braams -% Now we have register allocation fitted -% -% Revision 1.4 2005/03/26 21:08:12 morten -% Fix \c_zero -> \c_zero_skip -% -% Revision 1.3 2005/03/16 22:36:46 braams -% Added the tweaks necessary to be able to load with initex -% -% Revision 1.2 2005/03/11 21:31:07 braams -% Fixed the use of RCS information; added \StopEventually +% \end{implementation} +% \PrintIndex % +% \endinput diff --git a/Master/texmf-dist/source/latex/expl3/l3calc.dtx b/Master/texmf-dist/source/latex/expl3/l3calc.dtx index 842e68864c7..c9519f13ca4 100644 --- a/Master/texmf-dist/source/latex/expl3/l3calc.dtx +++ b/Master/texmf-dist/source/latex/expl3/l3calc.dtx @@ -1,5 +1,5 @@ % \iffalse -%% File: l3calc.dtx Copyright (C) 2006 LaTeX3 project +%% File: l3calc.dtx Copyright (C) 2006,2009 LaTeX3 project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this @@ -17,7 +17,7 @@ %% %% The development version of the bundle can be found at %% -%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/ +%% http://www.latex-project.org/svnroot/experimental/trunk/ %% %% for those people who are interested. %% @@ -35,7 +35,7 @@ \RequirePackage{l3names} %</driver|package> %\fi -\GetIdInfo$Id: l3calc.dtx 621 2007-09-01 20:14:19Z morten $ +\GetIdInfo$Id: l3calc.dtx 1362 2009-05-28 20:19:21Z joseph $ {L3 Experimental calc module} %\iffalse %<*driver> @@ -43,7 +43,7 @@ \ProvidesFile{\filename.\filenameext} [\filedate\space v\fileversion\space\filedescription] %\iffalse -\documentclass{l3doc} +\documentclass[full]{l3doc} \begin{document} \DocInput{\filename.\filenameext} \end{document} @@ -58,8 +58,8 @@ % \date{\filedate} % \maketitle % -% \section{Infix notation arithmetic} -% +% \begin{documentation} +% % This is pretty much a straight adaption of the \textsf{calc} package % and as such has same syntax for the \meta{calc expression}. However, % there are some noticeable differences. @@ -83,16 +83,51 @@ % the original \textsf{calc} package providing the same functionality % and will prevent the original \textsf{calc} package from loading. % +% \section{User functions} +% +% +% \begin{function}{ \maxof | +% \minof | +% \widthof | +% \heightof | +% \depthof | +% \totalheightof | +% \ratio | +% \real | +% \setlength | +% \gsetlength | +% \addtolength | +% \gaddtolength | +% \setcounter | +% \addtocounter | +% \stepcounter } +% See documentation for \LaTeXe\ package \pkg{calc}. +% \end{function} +% +% \begin{function}{ \calc_maxof:nn | +% \calc_minof:nn | +% \calc_widthof:n | +% \calc_heightof:n | +% \calc_depthof:n | +% \calc_totalheightof:n | +% \calc_ratio:nn | +% \calc_real:n | +% \calc_setcounter:nn | +% \calc_addtocounter:nn | +% \calc_stepcounter:n } +% Equivalent commands as the above in the \pkg{expl3} namespace. +% \end{function} +% % \begin{function}{ % \calc_int_set:Nn | % \calc_int_gset:Nn | % \calc_int_add:Nn | % \calc_int_gadd:Nn | % \calc_int_sub:Nn | -% \calc_int_gsub:Nn | +% \calc_int_gsub:Nn % } % \begin{syntax} -% "\calc_int_set:Nn" <int> "{"<calc expression>"}" +% "\calc_int_set:Nn" <int> \Arg{calc expression} % \end{syntax} % Evaluates <calc expression> and either adds or subtracts it from % <int> or sets <int> to it. These operations can also be global. @@ -108,7 +143,7 @@ % \calc_dim_gsub:Nn | % } % \begin{syntax} -% "\calc_dim_set:Nn" <dim> "{"<calc expression>"}" +% "\calc_dim_set:Nn" <dim> \Arg{calc expression} % \end{syntax} % Evaluates <calc expression> and either adds or subtracts it from % <dim> or sets <dim> to it. These operations can also be global. @@ -124,7 +159,7 @@ % \calc_skip_gsub:Nn | % } % \begin{syntax} -% "\calc_skip_set:Nn" <skip> "{"<calc expression>"}" +% "\calc_skip_set:Nn" <skip> \Arg{calc expression} % \end{syntax} % Evaluates <calc expression> and either adds or subtracts it from % <skip> or sets <skip> to it. These operations can also be global. @@ -140,7 +175,7 @@ % \calc_muskip_gsub:Nn | % } % \begin{syntax} -% "\calc_muskip_set:Nn" <muskip> "{"<calc expression>"}" +% "\calc_muskip_set:Nn" <muskip> \Arg{calc expression} % \end{syntax} % Evaluates <calc expression> and either adds or subtracts it from % <muskip> or sets <muskip> to it. These operations can also be @@ -152,8 +187,8 @@ % \calc_calculate_box_size:nnn | % } % \begin{syntax} -% "\calc_calculate_box_size:nnn" "{"<dim-set>"}" \\ -% "{"<item 1> <item 2> ... <item n>"}" "{"<contents>"}" +% "\calc_calculate_box_size:nnn" \Arg{dim-set} \\ +% "{"<item 1> <item 2> ... <item n>"}" \Arg{contents} % \end{syntax} % Sets <contents> in a temporary box "\l_tmpa_box". Then <dim-set> % is put in front of a loop that inserts "+"\meta{item$\sb{i}$} in @@ -172,9 +207,72 @@ % \end{verbatim} % \end{function} % -% \StopEventually{} +% \end{documentation} +% +% \begin{implementation} +% % -% \subsection{The Implementation} +% \section{\pkg{l3calc} implementation} +% +% \subsection{Variables} +% +% \begin{function}{ \l_calc_expression_tl | +% \g_calc_A_register | +% \l_calc_B_register | +% \l_calc_current_type_int | +% \g_calc_A_int | +% \l_calc_B_int | +% \l_calc_C_int | +% \g_calc_A_dim | +% \l_calc_B_dim | +% \l_calc_C_dim | +% \g_calc_A_skip | +% \l_calc_B_skip | +% \l_calc_C_skip | +% \g_calc_A_muskip | +% \l_calc_B_muskip | +% \l_calc_C_muskip } +% Internal registers. +% \end{function} +% +% \subsection{Internal functions} +% +% \begin{function}{ \calc_assign_generic:NNNNnn | +% \calc_pre_scan:N | +% \calc_open:w | +% \calc_init_B: | +% \calc_numeric: | +% \calc_close: | +% \calc_post_scan:N | +% \calc_multiply:N | +% \calc_divide:N | +% \calc_generic_add_or_subtract:N | +% \calc_add: | +% \calc_subtract: | +% \calc_add_A_to_B: | +% \calc_subtract_A_from_B: | +% \calc_generic_multiply_or_divide:N | +% \calc_multiply_B_by_A: | +% \calc_divide_B_by_A: | +% \calc_multiply: | +% \calc_divide: | +% \calc_textsize:Nn | +% \calc_ratio_multiply:nn | +% \calc_ratio_divide:nn | +% \calc_real_evaluate:nn | +% \calc_real_multiply:n | +% \calc_real_divide:n | +% \calc_maxmin_operation:Nnn | +% \calc_maxmin_generic:Nnn | +% \calc_maxmin_div_or_mul:NNnn | +% \calc_maxmin_multiply: | +% \calc_maxmin_multiply: | +% \calc_error:N | +% \calc_chk_document_counter:nn } +% Awaiting better documentation ":)" +% \end{function} +% +% \subsection{Module code} % % Since this is basically a re-worked version of the \textsf{calc} % package, I haven't bothered with too many comments except for in the @@ -186,23 +284,21 @@ %<*package> \ProvidesExplPackage {\filename}{\filedate}{\fileversion}{\filedescription} -\RequirePackage{l3int} -\RequirePackage{l3skip} -\RequirePackage{l3box} +\package_check_loaded_expl: %</package> %<*initex|package> % \end{macrocode} % % -% \begin{macro}{\l_calc_expression_tlp} +% \begin{macro}{\l_calc_expression_tl} % \begin{macro}{\g_calc_A_register} % \begin{macro}{\l_calc_B_register} % \begin{macro}{\l_calc_current_type_int} % Here we define some registers and pointers we will need. % \begin{macrocode} -\tlp_new:Nn\l_calc_expression_tlp{} -\def_new:Npn \g_calc_A_register{} -\def_new:Npn \l_calc_B_register{} +\tl_new:Nn\l_calc_expression_tl{} +\cs_new_nopar:Npn \g_calc_A_register{} +\cs_new_nopar:Npn \l_calc_B_register{} \int_new:N \l_calc_current_type_int % \end{macrocode} % \end{macro} @@ -261,17 +357,17 @@ % little extra work so that |\real| and |\ratio| can still be used % by the user. % \begin{macrocode} -\def_long_new:Npn \calc_assign_generic:NNNNnn#1#2#3#4#5#6{ - \let:NN\g_calc_A_register#2 - \let:NN\l_calc_B_register#3 +\cs_new:Npn \calc_assign_generic:NNNNnn#1#2#3#4#5#6{ + \cs_set_eq:NN\g_calc_A_register#2 + \cs_set_eq:NN\l_calc_B_register#3 \int_set:Nn \l_calc_current_type_int {#1} \group_begin: - \let:NN \real \calc_real:n - \let:NN \ratio\calc_ratio:nn - \tlp_set:Nx\l_calc_expression_tlp{#6} - \exp_after:NN + \cs_set_eq:NN \real \calc_real:n + \cs_set_eq:NN \ratio\calc_ratio:nn + \tl_set:Nx\l_calc_expression_tl{#6} + \exp_after:wN \group_end: - \exp_after:NN\calc_open:w\exp_after:NN(\l_calc_expression_tlp ! + \exp_after:wN\calc_open:w\exp_after:wN(\l_calc_expression_tl ! \pref_global:D\g_calc_A_register\l_calc_B_register \group_end: #4{#5}\l_calc_B_register @@ -280,11 +376,11 @@ % A simpler version relying on |\real| and |\ratio| having our % definition is % \begin{verbatim} -% \def_long_new:Npn \calc_assign_generic:NNNNnn#1#2#3#4#5#6{ -% \let:NN\g_calc_A_register#2\let:NN\l_calc_B_register#3 +% \cs_new:Npn \calc_assign_generic:NNNNnn#1#2#3#4#5#6{ +% \cs_set_eq:NN\g_calc_A_register#2\cs_set_eq:NN\l_calc_B_register#3 % \int_set:Nn \l_calc_current_type_int {#1} -% \tlp_set:Nx\l_calc_expression_tlp{#6} -% \exp_after:NN\calc_open:w\exp_after:NN(\l_calc_expression_tlp ! +% \tl_set:Nx\l_calc_expression_tl{#6} +% \exp_after:wN\calc_open:w\exp_after:wN(\l_calc_expression_tl ! % \pref_global:D\g_calc_A_register\l_calc_B_register % \group_end: % #4{#5}\l_calc_B_register @@ -303,22 +399,22 @@ % Here are the individual versions for the different register % types. First integer registers. % \begin{macrocode} -\def_new:Npn\calc_int_set:Nn{ +\cs_new_nopar:Npn\calc_int_set:Nn{ \calc_assign_generic:NNNNnn\c_zero\g_calc_A_int\l_calc_B_int\int_set:Nn } -\def_new:Npn\calc_int_gset:Nn{ +\cs_new_nopar:Npn\calc_int_gset:Nn{ \calc_assign_generic:NNNNnn\c_zero\g_calc_A_int\l_calc_B_int\int_gset:Nn } -\def_new:Npn\calc_int_add:Nn{ +\cs_new_nopar:Npn\calc_int_add:Nn{ \calc_assign_generic:NNNNnn\c_zero\g_calc_A_int\l_calc_B_int\int_add:Nn } -\def_new:Npn\calc_int_gadd:Nn{ +\cs_new_nopar:Npn\calc_int_gadd:Nn{ \calc_assign_generic:NNNNnn\c_zero\g_calc_A_int\l_calc_B_int\int_gadd:Nn } -\def_new:Npn\calc_int_sub:Nn{ +\cs_new_nopar:Npn\calc_int_sub:Nn{ \calc_assign_generic:NNNNnn\c_zero\g_calc_A_int\l_calc_B_int\int_sub:Nn } -\def_new:Npn\calc_int_gsub:Nn{ +\cs_new_nopar:Npn\calc_int_gsub:Nn{ \calc_assign_generic:NNNNnn\c_zero\g_calc_A_int\l_calc_B_int\int_gsub:Nn } % \end{macrocode} @@ -337,22 +433,22 @@ % \begin{macro}{\calc_dim_gsub:Nn} % Dimens. % \begin{macrocode} -\def_new:Npn\calc_dim_set:Nn{ +\cs_new_nopar:Npn\calc_dim_set:Nn{ \calc_assign_generic:NNNNnn\c_one\g_calc_A_dim\l_calc_B_dim\dim_set:Nn } -\def_new:Npn\calc_dim_gset:Nn{ +\cs_new_nopar:Npn\calc_dim_gset:Nn{ \calc_assign_generic:NNNNnn\c_one\g_calc_A_dim\l_calc_B_dim\dim_gset:Nn } -\def_new:Npn\calc_dim_add:Nn{ +\cs_new_nopar:Npn\calc_dim_add:Nn{ \calc_assign_generic:NNNNnn\c_one\g_calc_A_dim\l_calc_B_dim\dim_add:Nn } -\def_new:Npn\calc_dim_gadd:Nn{ +\cs_new_nopar:Npn\calc_dim_gadd:Nn{ \calc_assign_generic:NNNNnn\c_one\g_calc_A_dim\l_calc_B_dim\dim_gadd:Nn } -\def_new:Npn\calc_dim_sub:Nn{ +\cs_new_nopar:Npn\calc_dim_sub:Nn{ \calc_assign_generic:NNNNnn\c_one\g_calc_A_int\l_calc_B_int\dim_sub:Nn } -\def_new:Npn\calc_dim_gsub:Nn{ +\cs_new_nopar:Npn\calc_dim_gsub:Nn{ \calc_assign_generic:NNNNnn\c_one\g_calc_A_int\l_calc_B_int\dim_gsub:Nn } % \end{macrocode} @@ -371,22 +467,22 @@ % \begin{macro}{\calc_skip_gsub:Nn} % Skips. % \begin{macrocode} -\def_new:Npn\calc_skip_set:Nn{ +\cs_new_nopar:Npn\calc_skip_set:Nn{ \calc_assign_generic:NNNNnn\c_two\g_calc_A_skip\l_calc_B_skip\skip_set:Nn } -\def_new:Npn\calc_skip_gset:Nn{ +\cs_new_nopar:Npn\calc_skip_gset:Nn{ \calc_assign_generic:NNNNnn\c_two\g_calc_A_skip\l_calc_B_skip\skip_gset:Nn } -\def_new:Npn\calc_skip_add:Nn{ +\cs_new_nopar:Npn\calc_skip_add:Nn{ \calc_assign_generic:NNNNnn\c_two\g_calc_A_skip\l_calc_B_skip\skip_add:Nn } -\def_new:Npn\calc_skip_gadd:Nn{ +\cs_new_nopar:Npn\calc_skip_gadd:Nn{ \calc_assign_generic:NNNNnn\c_two\g_calc_A_skip\l_calc_B_skip\skip_gadd:Nn } -\def_new:Npn\calc_skip_sub:Nn{ +\cs_new_nopar:Npn\calc_skip_sub:Nn{ \calc_assign_generic:NNNNnn\c_two\g_calc_A_skip\l_calc_B_skip\skip_sub:Nn } -\def_new:Npn\calc_skip_gsub:Nn{ +\cs_new_nopar:Npn\calc_skip_gsub:Nn{ \calc_assign_generic:NNNNnn\c_two\g_calc_A_skip\l_calc_B_skip\skip_gsub:Nn } % \end{macrocode} @@ -405,27 +501,27 @@ % \begin{macro}{\calc_muskip_gsub:Nn} % Muskips. % \begin{macrocode} -\def_new:Npn\calc_muskip_set:Nn{ +\cs_new_nopar:Npn\calc_muskip_set:Nn{ \calc_assign_generic:NNNNnn\c_three\g_calc_A_muskip\l_calc_B_muskip \muskip_set:Nn } -\def_new:Npn\calc_muskip_gset:Nn{ +\cs_new_nopar:Npn\calc_muskip_gset:Nn{ \calc_assign_generic:NNNNnn\c_three\g_calc_A_muskip\l_calc_B_muskip \muskip_gset:Nn } -\def_new:Npn\calc_muskip_add:Nn{ +\cs_new_nopar:Npn\calc_muskip_add:Nn{ \calc_assign_generic:NNNNnn\c_three\g_calc_A_muskip\l_calc_B_muskip \muskip_add:Nn } -\def_new:Npn\calc_muskip_gadd:Nn{ +\cs_new_nopar:Npn\calc_muskip_gadd:Nn{ \calc_assign_generic:NNNNnn\c_three\g_calc_A_muskip\l_calc_B_muskip \muskip_gadd:Nn } -\def_new:Npn\calc_muskip_sub:Nn{ +\cs_new_nopar:Npn\calc_muskip_sub:Nn{ \calc_assign_generic:NNNNnn\c_three\g_calc_A_muskip\l_calc_B_muskip \muskip_add:Nn } -\def_new:Npn\calc_muskip_gsub:Nn{ +\cs_new_nopar:Npn\calc_muskip_gsub:Nn{ \calc_assign_generic:NNNNnn\c_three\g_calc_A_muskip\l_calc_B_muskip \muskip_gadd:Nn } @@ -442,13 +538,13 @@ % In case we found one of the special operations, this should just % be executed. % \begin{macrocode} -\def_new:Npn \calc_pre_scan:N #1{ - \if_meaning:NN(#1 - \exp_after:NN\calc_open:w +\cs_new_nopar:Npn \calc_pre_scan:N #1{ + \if_meaning:w(#1 + \exp_after:wN\calc_open:w \else: - \if_meaning:NN \calc_textsize:Nn #1 + \if_meaning:w \calc_textsize:Nn #1 \else: - \if_meaning:NN \calc_maxmin_operation:Nnn #1 + \if_meaning:w \calc_maxmin_operation:Nnn #1 \else: % \end{macrocode} % |\calc_numeric:| uses a primitive assignment so doesn't care about @@ -464,7 +560,7 @@ % % \begin{macro}{\calc_open:w} % \begin{macrocode} -\def_new:Npn \calc_open:w({ +\cs_new_nopar:Npn \calc_open:w({ \group_begin:\group_execute_after:N\calc_init_B: \group_begin:\group_execute_after:N\calc_init_B: \calc_pre_scan:N @@ -476,12 +572,12 @@ % \begin{macro}{\calc_numeric:} % \begin{macro}{\calc_close:} % \begin{macrocode} -\def_new:Npn\calc_init_B:{\l_calc_B_register\g_calc_A_register} -\def_new:Npn\calc_numeric:{ +\cs_new_nopar:Npn\calc_init_B:{\l_calc_B_register\g_calc_A_register} +\cs_new_nopar:Npn\calc_numeric:{ \tex_afterassignment:D\calc_post_scan:N \pref_global:D\g_calc_A_register } -\def_new:Npn\calc_close:{ +\cs_new_nopar:Npn\calc_close:{ \group_end:\pref_global:D\g_calc_A_register\l_calc_B_register \group_end:\pref_global:D\g_calc_A_register\l_calc_B_register \calc_post_scan:N} @@ -493,21 +589,21 @@ % \begin{macro}{\calc_post_scan:N} % Look at what token we have and decide where to go. % \begin{macrocode} -\def_new:Npn\calc_post_scan:N#1{ - \if_meaning:NN#1!\let:NN\calc_next:w\group_end: \else: - \if_meaning:NN#1+\let:NN\calc_next:w\calc_add: \else: - \if_meaning:NN#1-\let:NN\calc_next:w\calc_subtract: \else: - \if_meaning:NN#1*\let:NN\calc_next:w\calc_multiply:N \else: - \if_meaning:NN#1/\let:NN\calc_next:w\calc_divide:N \else: - \if_meaning:NN#1)\let:NN\calc_next:w\calc_close: \else: - \if_meaning:NN#1\scan_stop:\let:NN\calc_next:w\calc_post_scan:N +\cs_new_nopar:Npn\calc_post_scan:N#1{ + \if_meaning:w#1!\cs_set_eq:NN\calc_next:w\group_end: \else: + \if_meaning:w#1+\cs_set_eq:NN\calc_next:w\calc_add: \else: + \if_meaning:w#1-\cs_set_eq:NN\calc_next:w\calc_subtract: \else: + \if_meaning:w#1*\cs_set_eq:NN\calc_next:w\calc_multiply:N \else: + \if_meaning:w#1/\cs_set_eq:NN\calc_next:w\calc_divide:N \else: + \if_meaning:w#1)\cs_set_eq:NN\calc_next:w\calc_close: \else: + \if_meaning:w#1\scan_stop:\cs_set_eq:NN\calc_next:w\calc_post_scan:N \else: % \end{macrocode} % If we get here, there is an error but let's also disable % |\calc_next:w| since it is otherwise undefined. No need to give % extra errors just for that. % \begin{macrocode} - \let:NN \calc_next:w \use_noop: + \cs_set_eq:NN \calc_next:w \prg_do_nothing: \calc_error:N#1 \fi: \fi: @@ -524,33 +620,33 @@ % \begin{macro}{\calc_divide:N} % The switches for multiplication and division. % \begin{macrocode} -\def_new:Npn \calc_multiply:N #1{ - \if_meaning:NN \calc_maxmin_operation:Nnn #1 - \let:NN \calc_next:w \calc_maxmin_multiply: +\cs_new_nopar:Npn \calc_multiply:N #1{ + \if_meaning:w \calc_maxmin_operation:Nnn #1 + \cs_set_eq:NN \calc_next:w \calc_maxmin_multiply: \else: - \if_meaning:NN \calc_ratio_multiply:nn #1 - \let:NN \calc_next:w \calc_ratio_multiply:nn + \if_meaning:w \calc_ratio_multiply:nn #1 + \cs_set_eq:NN \calc_next:w \calc_ratio_multiply:nn \else: - \if_meaning:NN \calc_real_evaluate:nn #1 - \let:NN \calc_next:w \calc_real_multiply:n + \if_meaning:w \calc_real_evaluate:nn #1 + \cs_set_eq:NN \calc_next:w \calc_real_multiply:n \else: - \def:Npn \calc_next:w{\calc_multiply: #1} + \cs_set_nopar:Npn \calc_next:w{\calc_multiply: #1} \fi: \fi: \fi: \calc_next:w } -\def_new:Npn \calc_divide:N #1{ - \if_meaning:NN \calc_maxmin_operation:Nnn #1 - \let:NN \calc_next:w \calc_maxmin_divide: +\cs_new_nopar:Npn \calc_divide:N #1{ + \if_meaning:w \calc_maxmin_operation:Nnn #1 + \cs_set_eq:NN \calc_next:w \calc_maxmin_divide: \else: - \if_meaning:NN \calc_ratio_multiply:nn #1 - \let:NN \calc_next:w \calc_ratio_divide:nn + \if_meaning:w \calc_ratio_multiply:nn #1 + \cs_set_eq:NN \calc_next:w \calc_ratio_divide:nn \else: - \if_meaning:NN \calc_real_evaluate:nn #1 - \let:NN \calc_next:w \calc_real_divide:n + \if_meaning:w \calc_real_evaluate:nn #1 + \cs_set_eq:NN \calc_next:w \calc_real_divide:n \else: - \def:Npn \calc_next:w{\calc_divide: #1} + \cs_set_nopar:Npn \calc_next:w{\calc_divide: #1} \fi: \fi: \fi: @@ -560,26 +656,26 @@ % \end{macro} % \end{macro} % -% \begin{macro}{\calc_generic_add:N} +% \begin{macro}{\calc_generic_add_or_subtract:N} % \begin{macro}{\calc_add:} % \begin{macro}{\calc_subtract:} % \begin{macro}{\calc_add_A_to_B:} % \begin{macro}{\calc_subtract_A_from_B:} % Here is how we add and subtract. % \begin{macrocode} -\def_new:Npn\calc_generic_add_or_subtract:N#1{ +\cs_new_nopar:Npn\calc_generic_add_or_subtract:N#1{ \group_end: \pref_global:D\g_calc_A_register\l_calc_B_register\group_end: \group_begin:\group_execute_after:N#1\group_begin: \group_execute_after:N\calc_init_B: \calc_pre_scan:N} -\def_new:Npn\calc_add:{\calc_generic_add_or_subtract:N\calc_add_A_to_B:} -\def_new:Npn\calc_subtract:{ +\cs_new_nopar:Npn\calc_add:{\calc_generic_add_or_subtract:N\calc_add_A_to_B:} +\cs_new_nopar:Npn\calc_subtract:{ \calc_generic_add_or_subtract:N\calc_subtract_A_from_B:} % \end{macrocode} % Don't use |\tex_advance:D| since it allows overflows. % \begin{macrocode} -\def_new:Npn\calc_add_A_to_B:{ +\cs_new_nopar:Npn\calc_add_A_to_B:{ \l_calc_B_register \if_case:w\l_calc_current_type_int \etex_numexpr:D\or: @@ -588,7 +684,7 @@ \etex_muexpr:D\fi: \l_calc_B_register + \g_calc_A_register\scan_stop: } -\def_new:Npn\calc_subtract_A_from_B:{ +\cs_new_nopar:Npn\calc_subtract_A_from_B:{ \l_calc_B_register \if_case:w\l_calc_current_type_int \etex_numexpr:D\or: @@ -613,15 +709,15 @@ % primitive \TeX{} operations but the expandable operations provided % by \eTeX. This means that all results are rounded not truncated! % \begin{macrocode} -\def_new:Npn\calc_generic_multiply_or_divide:N#1{ +\cs_new_nopar:Npn\calc_generic_multiply_or_divide:N#1{ \group_end: \group_begin: - \let:NN\g_calc_A_register\g_calc_A_int - \let:NN\l_calc_B_register\l_calc_B_int + \cs_set_eq:NN\g_calc_A_register\g_calc_A_int + \cs_set_eq:NN\l_calc_B_register\l_calc_B_int \int_zero:N \l_calc_current_type_int \group_execute_after:N#1\calc_pre_scan:N } -\def_new:Npn\calc_multiply_B_by_A:{ +\cs_new_nopar:Npn\calc_multiply_B_by_A:{ \l_calc_B_register \if_case:w\l_calc_current_type_int \etex_numexpr:D\or: @@ -630,7 +726,7 @@ \etex_muexpr:D\fi: \l_calc_B_register*\g_calc_A_int\scan_stop: } -\def_new:Npn\calc_divide_B_by_A:{ +\cs_new_nopar:Npn\calc_divide_B_by_A:{ \l_calc_B_register \if_case:w\l_calc_current_type_int \etex_numexpr:D\or: @@ -639,9 +735,9 @@ \etex_muexpr:D\fi: \l_calc_B_register/\g_calc_A_int\scan_stop: } -\def_new:Npn\calc_multiply:{ +\cs_new_nopar:Npn\calc_multiply:{ \calc_generic_multiply_or_divide:N\calc_multiply_B_by_A:} -\def_new:Npn\calc_divide:{ +\cs_new_nopar:Npn\calc_divide:{ \calc_generic_multiply_or_divide:N\calc_divide_B_by_A:} % \end{macrocode} % \end{macro} @@ -651,19 +747,19 @@ % \end{macro} % % \begin{macro}{\calc_calculate_box_size:nnn} -% \begin{macro}{\calc_calculate_box_size_aux:n} +% \begin{macro}[aux]{\calc_calculate_box_size_aux:n} % Put something in a box and measure it. |#1| is a list of % |\box_ht:N| etc., |#2| should be |\dim_set:Nn|\meta{dim register} % or |\dim_gset:Nn|\meta{dim register} and |#3| is the contents. % \begin{macrocode} -\def_long_new:Npn \calc_calculate_box_size:nnn #1#2#3{ +\cs_new:Npn \calc_calculate_box_size:nnn #1#2#3{ \hbox_set:Nn \l_tmpa_box {{#3}} - #2{\c_zero_dim \tlist_map_function:nN{#1}\calc_calculate_box_size_aux:n} + #2{\c_zero_dim \tl_map_function:nN{#1}\calc_calculate_box_size_aux:n} } % \end{macrocode} % Helper for calculating the final dimension. % \begin{macrocode} -\def:Npn \calc_calculate_box_size_aux:n#1{ + #1\l_tmpa_box} +\cs_set_nopar:Npn \calc_calculate_box_size_aux:n#1{ + #1\l_tmpa_box} % \end{macrocode} % \end{macro} % \end{macro} @@ -672,12 +768,12 @@ % \begin{macro}{\calc_textsize:Nn} % Now we can define |\calc_textsize:Nn|. % \begin{macrocode} -\def_protected_long:Npn \calc_textsize:Nn#1#2{ +\cs_set_protected:Npn \calc_textsize:Nn#1#2{ \group_begin: - \let:NN\calc_widthof_aux:n\box_wd:N - \let:NN\calc_heightof_aux:n\box_ht:N - \let:NN\calc_depthof_aux:n\box_dp:N - \def:Npn\calc_totalheightof_aux:n{\box_ht:N\box_dp:N} + \cs_set_eq:NN\calc_widthof_aux:n\box_wd:N + \cs_set_eq:NN\calc_heightof_aux:n\box_ht:N + \cs_set_eq:NN\calc_depthof_aux:n\box_dp:N + \cs_set_nopar:Npn\calc_totalheightof_aux:n{\box_ht:N\box_dp:N} \exp_args:No\calc_calculate_box_size:nnn{#1} {\dim_gset:Nn\g_calc_A_register} % \end{macrocode} @@ -685,10 +781,10 @@ % call. % \begin{macrocode} { - \let:NN \calc_depthof_aux:n \calc_depthof_auxi:n - \let:NN \calc_widthof_aux:n \calc_widthof_auxi:n - \let:NN \calc_heightof_aux:n \calc_heightof_auxi:n - \let:NN \calc_totalheightof_aux:n \calc_totalheightof_auxi:n + \cs_set_eq:NN \calc_depthof_aux:n \calc_depthof_auxi:n + \cs_set_eq:NN \calc_widthof_aux:n \calc_widthof_auxi:n + \cs_set_eq:NN \calc_heightof_aux:n \calc_heightof_auxi:n + \cs_set_eq:NN \calc_totalheightof_aux:n \calc_totalheightof_auxi:n #2 } \group_end: @@ -703,7 +799,7 @@ % register, the ratio is probably also done with this type and we'll % have to convert them to regular points. % \begin{macrocode} -\def_protected_long:Npn\calc_ratio_multiply:nn#1#2{ +\cs_set_protected:Npn\calc_ratio_multiply:nn#1#2{ \group_end:\group_begin: \if_num:w\l_calc_current_type_int < \c_three \calc_dim_set:Nn\l_calc_B_int{#1} @@ -715,7 +811,7 @@ % \end{macrocode} % Then store the ratio as a fraction, which we just pass on. % \begin{macrocode} - \gdef:Npx\calc_calculated_ratio:{ + \cs_gset_nopar:Npx\calc_calculated_ratio:{ \int_use:N\l_calc_B_int/\int_use:N\l_calc_C_int } \group_end: @@ -738,7 +834,7 @@ % \end{macrocode} % Division is just flipping the arguments around. % \begin{macrocode} -\def_long_new:Npn \calc_ratio_divide:nn#1#2{\calc_ratio_multiply:nn{#2}{#1}} +\cs_new:Npn \calc_ratio_divide:nn#1#2{\calc_ratio_multiply:nn{#2}{#1}} % \end{macrocode} % \end{macro} % \end{macro} @@ -750,7 +846,7 @@ % |\ratio|, this is horribly inefficient since we just want to convert % the decimal to a fraction. % \begin{macrocode} -\def_protected_new:Npn\calc_real_evaluate:nn #1#2{ +\cs_new_protected_nopar:Npn\calc_real_evaluate:nn #1#2{ \group_end: \l_calc_B_register \if_case:w\l_calc_current_type_int @@ -764,8 +860,8 @@ \scan_stop: \group_begin: \calc_post_scan:N} -\def_new:Npn \calc_real_multiply:n #1{\calc_real_evaluate:nn{#1}{1}} -\def_new:Npn \calc_real_divide:n {\calc_real_evaluate:nn{1}} +\cs_new_nopar:Npn \calc_real_multiply:n #1{\calc_real_evaluate:nn{#1}{1}} +\cs_new_nopar:Npn \calc_real_divide:n {\calc_real_evaluate:nn{1}} % \end{macrocode} % \end{macro} % \end{macro} @@ -778,7 +874,7 @@ % \begin{macro}{\calc_maxmin_multiply:} % The max and min functions. % \begin{macrocode} -\def_protected_long:Npn\calc_maxmin_operation:Nnn#1#2#3{ +\cs_set_protected:Npn\calc_maxmin_operation:Nnn#1#2#3{ \group_begin: \calc_maxmin_generic:Nnn#1{#2}{#3} \group_end: @@ -787,7 +883,7 @@ % \end{macrocode} % |#1| is either |>| or |<| and was expanded into this initially. % \begin{macrocode} -\def_protected_long_new:Npn \calc_maxmin_generic:Nnn#1#2#3{ +\cs_new_protected:Npn \calc_maxmin_generic:Nnn#1#2#3{ \group_begin: \if_case:w\l_calc_current_type_int \calc_int_set:Nn\l_calc_C_int{#2}% @@ -816,7 +912,7 @@ \fi: \group_end: } -\def_long_new:Npn\calc_maxmin_div_or_mul:NNnn#1#2#3#4{ +\cs_new:Npn\calc_maxmin_div_or_mul:NNnn#1#2#3#4{ \group_end: \group_begin: \int_zero:N\l_calc_current_type_int @@ -826,9 +922,9 @@ \group_begin: \calc_post_scan:N } -\def_new:Npn\calc_maxmin_multiply:{ +\cs_new_nopar:Npn\calc_maxmin_multiply:{ \calc_maxmin_div_or_mul:NNnn\calc_multiply_B_by_A:} -\def_new:Npn\calc_maxmin_divide: { +\cs_new_nopar:Npn\calc_maxmin_divide: { \calc_maxmin_div_or_mul:NNnn\calc_divide_B_by_A:} % \end{macrocode} % \end{macro} @@ -840,9 +936,9 @@ % \begin{macro}{\calc_error:N} % The error message. % \begin{macrocode} -\def_new:Npn\calc_error:N#1{ +\cs_new_nopar:Npn\calc_error:N#1{ \PackageError{calc} - {`\token_to_string:N#1'~ invalid~ at~ this~ point} + {`\token_to_str:N#1'~ invalid~ at~ this~ point} {I~ expected~ to~ see~ one~ of:~ +~ -~ *~ /~ )} } % \end{macrocode} @@ -858,14 +954,14 @@ % \begin{macro}{\minof} % Max and min operations % \begin{macrocode} -\def_long_new:Npn \calc_maxof:nn#1#2{ +\cs_new:Npn \calc_maxof:nn#1#2{ \calc_maxmin_operation:Nnn > \exp_not:n{{#1}{#2}} } -\def_long_new:Npn \calc_minof:nn#1#2{ +\cs_new:Npn \calc_minof:nn#1#2{ \calc_maxmin_operation:Nnn < \exp_not:n{{#1}{#2}} } -\let:NN \maxof \calc_maxof:nn -\let:NN \minof \calc_minof:nn +\cs_set_eq:NN \maxof \calc_maxof:nn +\cs_set_eq:NN \minof \calc_minof:nn % \end{macrocode} % \end{macro} % \end{macro} @@ -873,47 +969,47 @@ % \end{macro} % % \begin{macro}{\calc_widthof:n} -% \begin{macro}{\calc_widthof_aux:n} -% \begin{macro}{\calc_widthof_auxi:n} +% \begin{macro}[aux]{\calc_widthof_aux:n} +% \begin{macro}[aux]{\calc_widthof_auxi:n} % \begin{macro}{\calc_heightof:n} -% \begin{macro}{\calc_heightof_aux:n} -% \begin{macro}{\calc_heightof_auxi:n} +% \begin{macro}[aux]{\calc_heightof_aux:n} +% \begin{macro}[aux]{\calc_heightof_auxi:n} % \begin{macro}{\calc_depthof:n} -% \begin{macro}{\calc_depthof_aux:n} -% \begin{macro}{\calc_depthof_auxi:n} +% \begin{macro}[aux]{\calc_depthof_aux:n} +% \begin{macro}[aux]{\calc_depthof_auxi:n} % \begin{macro}{\calc_totalheightof:n} -% \begin{macro}{\calc_totalheightof_aux:n} -% \begin{macro}{\calc_totalheightof_auxi:n} +% \begin{macro}[aux]{\calc_totalheightof_aux:n} +% \begin{macro}[aux]{\calc_totalheightof_auxi:n} % Text dimension commands. % \begin{macrocode} -\def_long_new:Npn \calc_widthof:n#1{ +\cs_new:Npn \calc_widthof:n#1{ \calc_textsize:Nn \exp_not:N\calc_widthof_aux:n\exp_not:n{{#1}} } -\def_long_new:Npn \calc_heightof:n#1{ +\cs_new:Npn \calc_heightof:n#1{ \calc_textsize:Nn \exp_not:N\calc_heightof_aux:n\exp_not:n{{#1}} } -\def_long_new:Npn \calc_depthof:n#1{ +\cs_new:Npn \calc_depthof:n#1{ \calc_textsize:Nn \exp_not:N\calc_depthof_aux:n\exp_not:n{{#1}} } -\def_long_new:Npn \calc_totalheightof:n#1{ +\cs_new:Npn \calc_totalheightof:n#1{ \calc_textsize:Nn \exp_not:N\calc_totalheightof_aux:n \exp_not:n{{#1}} } -\def_long_new:Npn \calc_widthof_aux:n #1{ +\cs_new:Npn \calc_widthof_aux:n #1{ \exp_not:N\calc_widthof_aux:n\exp_not:n{{#1}} } -\let_new:NN \calc_widthof_auxi:n \calc_widthof_aux:n -\def_long_new:Npn \calc_depthof_aux:n #1{ +\cs_new_eq:NN \calc_widthof_auxi:n \calc_widthof_aux:n +\cs_new:Npn \calc_depthof_aux:n #1{ \exp_not:N\calc_depthof_aux:n\exp_not:n{{#1}} } -\let_new:NN \calc_depthof_auxi:n \calc_depthof_aux:n -\def_long_new:Npn \calc_heightof_aux:n #1{ +\cs_new_eq:NN \calc_depthof_auxi:n \calc_depthof_aux:n +\cs_new:Npn \calc_heightof_aux:n #1{ \exp_not:N\calc_heightof_aux:n\exp_not:n{{#1}} } -\let_new:NN \calc_heightof_auxi:n \calc_heightof_aux:n -\def_long_new:Npn \calc_totalheightof_aux:n #1{ +\cs_new_eq:NN \calc_heightof_auxi:n \calc_heightof_aux:n +\cs_new:Npn \calc_totalheightof_aux:n #1{ \exp_not:N\calc_totalheightof_aux:n\exp_not:n{{#1}} } -\let_new:NN \calc_totalheightof_auxi:n \calc_totalheightof_aux:n +\cs_new_eq:NN \calc_totalheightof_auxi:n \calc_totalheightof_aux:n % \end{macrocode} % \end{macro} % \end{macro} @@ -932,9 +1028,9 @@ % \begin{macro}{\calc_real:n} % Ratio and real. % \begin{macrocode} -\def_long_new:Npn \calc_ratio:nn#1#2{ +\cs_new:Npn \calc_ratio:nn#1#2{ \calc_ratio_multiply:nn\exp_not:n{{#1}{#2}}} -\def_new:Npn \calc_real:n {\calc_real_evaluate:nn} +\cs_new_nopar:Npn \calc_real:n {\calc_real_evaluate:nn} % \end{macrocode} % We can implement real and ratio without actually using these % names. We'll see. @@ -951,12 +1047,12 @@ % \begin{macro}{\real} % User commands. % \begin{macrocode} -\let:NN \depthof\calc_depthof:n -\let:NN \widthof\calc_widthof:n -\let:NN \heightof\calc_heightof:n -\let:NN \totalheightof\calc_totalheightof:n -%%\let:NN \ratio\calc_ratio:nn -%%\let:NN \real\calc_real:n +\cs_set_eq:NN \depthof\calc_depthof:n +\cs_set_eq:NN \widthof\calc_widthof:n +\cs_set_eq:NN \heightof\calc_heightof:n +\cs_set_eq:NN \totalheightof\calc_totalheightof:n +%%\cs_set_eq:NN \ratio\calc_ratio:nn +%%\cs_set_eq:NN \real\calc_real:n % \end{macrocode} % \end{macro} % \end{macro} @@ -970,10 +1066,10 @@ % \begin{macro}{\addtolength} % \begin{macro}{\gaddtolength} % \begin{macrocode} -\def_protected:Npn \setlength{\calc_skip_set:Nn} -\def_protected:Npn \gsetlength{\calc_skip_gset:Nn} -\def_protected:Npn \addtolength{\calc_skip_add:Nn} -\def_protected:Npn \gaddtolength{\calc_skip_gadd:Nn} +\cs_set_protected_nopar:Npn \setlength{\calc_skip_set:Nn} +\cs_set_protected_nopar:Npn \gsetlength{\calc_skip_gset:Nn} +\cs_set_protected_nopar:Npn \addtolength{\calc_skip_add:Nn} +\cs_set_protected_nopar:Npn \gaddtolength{\calc_skip_gadd:Nn} % \end{macrocode} % \end{macro} % \end{macro} @@ -992,44 +1088,67 @@ % |\mathchoice| will no longer need this switch as the argument is % only executed once. % \begin{macrocode} +%</initex|package> +%<*package> \newif\iffirstchoice@ \firstchoice@true -\def_protected:Npn \calc_setcounter:nn#1#2{ +%</package> +%<*initex|package> +\cs_set_protected_nopar:Npn \calc_setcounter:nn#1#2{ \calc_chk_document_counter:nn{#1}{ \exp_args:Nc\calc_int_gset:Nn {c@#1}{#2} } } -\def_protected:Npn \calc_addtocounter:nn#1#2{ +\cs_set_protected_nopar:Npn \calc_addtocounter:nn#1#2{ +%</initex|package> +%<*package> \iffirstchoice@ +%</package> +%<*initex|package> \calc_chk_document_counter:nn{#1}{ \exp_args:Nc\calc_int_gadd:Nn {c@#1}{#2} } +%</initex|package> +%<*package> \fi: +%</package> +%<*initex|package> } -\def_protected:Npn \calc_stepcounter:n#1{ +\cs_set_protected_nopar:Npn \calc_stepcounter:n#1{ +%</initex|package> +%<*package> \iffirstchoice@ +%</package> +%<*initex|package> \calc_chk_document_counter:nn{#1}{ \int_gincr:c {c@#1} \group_begin: - \let:NN \@elt\@stpelt \cs_use:c{cl@#1} + \cs_set_eq:NN \@elt\@stpelt \use:c{cl@#1} \group_end: } +%</initex|package> +%<*package> \fi: +%</package> +%<*initex|package> } -\def_new:Npn \calc_chk_document_counter:nn#1{ +\cs_new_nopar:Npn \calc_chk_document_counter:nn#1{ \cs_if_free:cTF{c@#1}{\@nocounterr {#1}} } -\let:NN \setcounter \calc_setcounter:nn -\let:NN \addtocounter \calc_addtocounter:nn -\let:NN \stepcounter \calc_stepcounter:n +\cs_set_eq:NN \setcounter \calc_setcounter:nn +\cs_set_eq:NN \addtocounter \calc_addtocounter:nn +\cs_set_eq:NN \stepcounter \calc_stepcounter:n +%</initex|package> +%<*package> \AtBeginDocument{ - \let:NN \setcounter \calc_setcounter:nn - \let:NN \addtocounter \calc_addtocounter:nn - \let:NN \stepcounter \calc_stepcounter:n + \cs_set_eq:NN \setcounter \calc_setcounter:nn + \cs_set_eq:NN \addtocounter \calc_addtocounter:nn + \cs_set_eq:NN \stepcounter \calc_stepcounter:n } % \end{macrocode} % Prevent the usual \textsf{calc} from loading. % \begin{macrocode} -%<package>\def:cpn{ver@calc.sty}{2005/08/06} +\cs_set_nopar:cpn{ver@calc.sty}{2005/08/06} +%</package> % \end{macrocode} % \end{macro} % \end{macro} @@ -1038,22 +1157,14 @@ % \end{macro} % \end{macro} % \end{macro} -% -% +% % \begin{macrocode} -%</initex|package> %<*showmemory> \showMemUsage %</showmemory> % \end{macrocode} % -% \endinput -% -% $Log$ -% Revision 1.2 2006/01/27 23:11:47 morten -% Fixed bug in \calc_pre_scan:N and avoid using \advance in order to -% catch overflows. -% -% Revision 1.1 2006/01/27 07:51:13 morten -% Initial version of a calc module +% \end{implementation} +% \PrintIndex % +% \endinput diff --git a/Master/texmf-dist/source/latex/expl3/l3chk.dtx b/Master/texmf-dist/source/latex/expl3/l3chk.dtx index 281ba7bc1cc..ad016f91c91 100644 --- a/Master/texmf-dist/source/latex/expl3/l3chk.dtx +++ b/Master/texmf-dist/source/latex/expl3/l3chk.dtx @@ -1,5 +1,5 @@ % \iffalse -%% File: l3chk.dtx Copyright (C) 1990-2006 LaTeX3 project +%% File: l3chk.dtx Copyright (C) 1990-2006,2009 LaTeX3 project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this @@ -17,7 +17,7 @@ %% %% The development version of the bundle can be found at %% -%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/ +%% http://www.latex-project.org/svnroot/experimental/trunk/ %% %% for those people who are interested. %% @@ -36,7 +36,7 @@ \RequirePackage{l3names} %</driver|package> %\fi -\GetIdInfo$Id: l3chk.dtx 621 2007-09-01 20:14:19Z morten $ +\GetIdInfo$Id: l3chk.dtx 1362 2009-05-28 20:19:21Z joseph $ {L3 Experimental check module} %\iffalse %<*driver> @@ -44,7 +44,7 @@ \ProvidesFile{\filename.\filenameext} [\filedate\space v\fileversion\space\filedescription] %\iffalse -\documentclass{l3doc} +\documentclass[full]{l3doc} \begin{document} \DocInput{\filename.\filenameext} \end{document} @@ -59,17 +59,27 @@ % \date{\filedate} % \maketitle % -% \section{The chk module} +% \begin{documentation} % % 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} +% \section{Tracing} +% +% \begin{function}{\tracingall | +% \absolutelytracingall | +% \donotcheck | +% \tracingoff | +% \traceon | +% \traceoff } +% Commands to control the level of verbosity in the tracing output. +% \end{function} +% +% \section{Functions} % % \begin{function}{% % \chk_var_or_const:N | -% \chk_var_or_const:c | % } % \begin{syntax} % "\chk_var_or_const:N" <cs> @@ -80,9 +90,7 @@ % % \begin{function}{% % \chk_local:N | -% \chk_local:c | % \chk_global:N | -% \chk_global:c | % } % \begin{syntax} % "\chk_local:N" <cs> @@ -108,40 +116,26 @@ % "\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 }" +% "\cs_new_nopar: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} +% \end{documentation} % -% \StopEventually{} +% \begin{implementation} % -% \subsection{The Implementation} +% \section{\pkg{l3chk} implementation} % % We start by ensuring that the required packages are loaded. % \begin{macrocode} -%<package>\ProvidesExplPackage -%<package> {\filename}{\filedate}{\fileversion}{\filedescription} -%<package>\RequirePackage{l3basics} -%<package>\RequirePackage{l3int,l3prg} +%<*package> +\ProvidesExplPackage + {\filename}{\filedate}{\fileversion}{\filedescription} +\package_check_loaded_expl: +%</package> %<*initex|package> % \end{macrocode} % @@ -150,10 +144,10 @@ % too badly. All these functions are of type `{\tt e}' since they % issue error messages if certain conditions are violated. % -% \subsubsection{Checking variable assignments} +% \subsection{Checking variable assignments} % % \begin{macro}{\chk_local:N} -% \begin{macro}{\chk_local_aux:w} +% \begin{macro}[aux]{\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|, @@ -166,18 +160,18 @@ % 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} +\cs_new_nopar:Npn \chk_local:N #1{ + \exp_after:wN \chk_local_aux:w \token_to_str:N#1\q_stop} -\def_new:Npn \chk_local_aux:w #1#2#3\q_stop{ +\cs_new_nopar:Npn \chk_local_aux:w #1#2#3\q_stop{ \if_num:w\tex_uccode:D`#2=`G\scan_stop: - \err_latex_bug:x{Local~mismatch:~local~function~called~with~ + \msg_kernel_bug:x {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:x{Variable~mismatch:~function~not~called~with~ + \msg_kernel_bug:x {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:} @@ -191,21 +185,21 @@ % \end{macro} % % \begin{macro}{\chk_global:N} -% \begin{macro}{\chk_global_aux:w} +% \begin{macro}[aux]{\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{ +\cs_new_nopar:Npn \chk_global:N #1{\exp_after:wN + \chk_global_aux:w \token_to_str:N#1\q_stop} +\cs_new_nopar:Npn \chk_global_aux:w #1#2#3\q_stop{ \if_num:w\tex_uccode:D`#2=`L\scan_stop: - \err_latex_bug:x{Global~mismatch:~global~function~called~with~ + \msg_kernel_bug:x {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:x{Variable~mismatch:~function~not~called~with~ + \msg_kernel_bug:x {Variable~mismatch:~function~not~called~with~ proper~variable:~#1#2#3~ on~line~\tex_the:D\tex_inputlineno:D}\fi:\fi:} % \end{macrocode} @@ -218,7 +212,7 @@ % |\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 which is usually |\cs_set_eq: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 @@ -228,7 +222,7 @@ % 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 } +% \cs_new_nopar: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 @@ -237,25 +231,25 @@ % |\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{ +\cs_new_nopar:Npn \pref_global_chk: { + \cs_gset_nopar:Npn \chk_local_or_pref_global:N ##1{ \chk_global:N ##1 - \glet:NN \chk_local_or_pref_global:N \chk_local:N} + \cs_gset_eq: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 +\cs_new_eq: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} +% \begin{macro}[aux]{\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 { +\cs_new_nopar:Npn \chk_var_or_const:N #1{\exp_after:wN + \chk_var_or_const_aux:w \token_to_str:N#1\q_stop } +\cs_new_nopar: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: @@ -273,7 +267,7 @@ % could check this by testing that there is no |_|, but this is not % implemented so far. % \begin{macrocode} - \err_latex_bug:x{Variable~mismatch:~function~not~called~with~ + \msg_kernel_bug:x {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:} @@ -282,7 +276,7 @@ % \end{macro} % % -% \subsubsection{Doing some tracing} +% \subsection{Doing some tracing} % % \begin{macro}{\tracingall} % \begin{macro}{\absolutelytracingall} @@ -292,20 +286,20 @@ % 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 +\cs_new_nopar:Npn\donotcheck{ + \cs_set_eq:NN \chk_global:N \use_none:n + \cs_set_eq:NN \chk_local:N \use_none:n + \cs_set_eq:NN \chk_local_or_pref_global:N \use_none:n + \cs_set_eq:NN \pref_global_chk: \pref_global:D + \cs_set_eq:NN \chk_if_free_cs:N \use_none:n + \cs_set_eq:NN \chk_exist_cs:N \use_none:n + \cs_set_eq:NN \chk_var_or_const:N \use_none:n + \cs_set_eq:NN \cs_record_name:N \use_none:n + \cs_set_eq:NN \cs_record_name:c \use_none:n + \cs_set_eq:NN \cs_record_meaning:N \use_none:n + \cs_set_eq:NN \register_record_name:N \use_none:n } -\def_new:Npn\absolutelytracingall{ +\cs_new_nopar:Npn\absolutelytracingall{ % \end{macrocode} % \end{macro} % @@ -326,7 +320,7 @@ \tex_errorstopmode:D} % % Use LaTeX2e definition for now. -%\def_new:Npn\tracingall{ +%\cs_new_nopar:Npn\tracingall{ % \donotcheck % \absolutelytracingall %} @@ -337,7 +331,7 @@ % \begin{macro}{\tracingoff} % This macro turns off all tracing. % \begin{macrocode} -\def_new:Npn\tracingoff{ +\cs_new_nopar: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 @@ -358,28 +352,28 @@ % \end{macrocode} % \end{macro} % -% \subsubsection{Tracing modules} +% \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{ +\cs_new_nopar:Npn\traceon#1{ \clist_map_inline:nn {#1}{ - \cs_free:cF{g_trace_ ##1 _status} + \cs_if_free:cF{g_trace_ ##1 _status} {\int_gincr:c{g_trace_ ##1 _status}} } } -\def_new:Npn\traceoff#1{ +\cs_new_nopar:Npn\traceoff#1{ \clist_map_inline:nn {#1}{ - \cs_free:cF{g_trace_ ##1 _status} + \cs_if_free:cF{g_trace_ ##1 _status} {\int_gdecr:c{g_trace_ ##1 _status}} } } %</trace> -%<-trace>\let_new:NN\traceon\use_none:n -%<-trace>\let_new:NN\traceoff\use_none:n +%<-trace>\cs_new_eq:NN\traceon\use_none:n +%<-trace>\cs_new_eq:NN\traceoff\use_none:n %</initex|package> % \end{macrocode} % \end{macro} @@ -393,22 +387,7 @@ %</showmemory> % \end{macrocode} % -% \endinput -% -% $Log$ -% Revision 1.14 2006/03/20 18:26:34 braams -% Updated the copyright notice (2006) and demoted all implementation -% sections to subsections and so on to clean up the toc for source3.tex -% -% Revision 1.13 2005/12/27 09:58:01 morten -% Minor changes plus changed RCS information retrieval -% -% Revision 1.12 2005/04/12 12:07:53 morten -% Removed unnecessary functions -% -% Revision 1.11 2005/03/15 23:31:54 braams -% Some fiddling with docstrip guards for initex use -% -% Revision 1.10 2005/03/11 21:33:31 braams -% Fixed the use of RCS information +% \end{implementation} +% \PrintIndex % +% \endinput diff --git a/Master/texmf-dist/source/latex/expl3/l3clist.dtx b/Master/texmf-dist/source/latex/expl3/l3clist.dtx index 0155c64f394..f875b7e0cbc 100644 --- a/Master/texmf-dist/source/latex/expl3/l3clist.dtx +++ b/Master/texmf-dist/source/latex/expl3/l3clist.dtx @@ -1,5 +1,5 @@ % \iffalse -%% File: l3clist.dtx Copyright (C) 2005-2006 Frank Mittelbach, LaTeX3 project +%% File: l3clist.dtx Copyright (C) 2005-2008 Frank Mittelbach, LaTeX3 project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this @@ -17,7 +17,7 @@ %% %% The development version of the bundle can be found at %% -%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/ +%% http://www.latex-project.org/svnroot/experimental/trunk/ %% %% for those people who are interested. %% @@ -36,7 +36,7 @@ \RequirePackage{l3names} %</driver|package> %\fi -\GetIdInfo$Id: l3clist.dtx 745 2008-08-03 18:50:46Z morten $ +\GetIdInfo$Id: l3clist.dtx 1362 2009-05-28 20:19:21Z joseph $ {L3 Experimental comma separated lists} %\iffalse %<*driver> @@ -44,7 +44,7 @@ \ProvidesFile{\filename.\filenameext} [\filedate\space v\fileversion\space\filedescription] %\iffalse -\documentclass{l3doc} +\documentclass[full]{l3doc} \begin{document} \DocInput{\filename.\filenameext} \end{document} @@ -61,9 +61,7 @@ % \date{\filedate} % \maketitle % -% -% -% \section{Comma lists} +% \begin{documentation} % % \LaTeX3 implements a data type called `clist (comma-lists)'. These % are special @@ -75,8 +73,8 @@ % part of the value). It is also possible to map functions on such % comma-lists so that they are executed for every item of the comma-list. % -% All functions that return items from a comma-list in some \m{tlp} assume -% that the \m{tlp} is local. See remarks below if you need a global +% All functions that return items from a comma-list in some \m{tl var.}~assume +% that the \m{tl var.}~is local. See remarks below if you need a global % returned value. % % The defined functions are not orthogonal in the sense that every @@ -89,7 +87,7 @@ % like "\clist_push:Nn" which has the same effect. Maybe one should % therefore remove the ``left'' functions totally. % -% \subsection{Functions} +% \section{Functions for creating/initialising comma-lists} % % \begin{function}{% % \clist_new:N | @@ -113,117 +111,153 @@ % These functions locally or globally clear <comma-list>. % \end{function} % +% \begin{function}{ \clist_clear_new:N | +% \clist_clear_new:c | +% \clist_gclear_new:N | +% \clist_gclear_new:c } +% \begin{syntax} +% "\clist_clear_new:N" <comma-list> +% \end{syntax} +% These functions locally or globally clear <comma-list> if it exists or +% otherwise allocates it. +% \end{function} +% +% \begin{function}{ \clist_set_eq:NN | +% \clist_set_eq:cN | +% \clist_set_eq:Nc | +% \clist_set_eq:cc } +% \begin{syntax} +% "\clist_set_eq:NN" <clist1> <clist2> +% \end{syntax} +% Function that locally makes <clist1> identical to <clist2>. +% \end{function} +% +% +% \begin{function}{ \clist_gset_eq:NN | +% \clist_gset_eq:cN | +% \clist_gset_eq:Nc | +% \clist_gset_eq:cc } +% \begin{syntax} +% "\clist_gset_eq:NN" <clist1> <clist2> +% \end{syntax} +% Function that globally makes <clist1> identical to <clist2>. +% \end{function} +% +% \section{Putting data in} +% % \begin{function}{% % \clist_put_left:Nn | +% \clist_put_left:NV | % \clist_put_left:No | % \clist_put_left:Nx | % \clist_put_left:cn | -% \clist_put_right:Nn | -% \clist_put_right:No | -% \clist_put_right:Nx | +% \clist_put_left:co | +% \clist_put_left:cV | % } % \begin{syntax} % "\clist_put_left:Nn" <comma-list> <token list> % \end{syntax} % Locally appends <token list> as a single item to the left -% or right of <comma-list>. <token list> might get expanded before -% appending. +% of <comma-list>. <token list> might get expanded before +% appending according to the variant used. % \end{function} % % \begin{function}{% -% \clist_gput_left:Nn | -% \clist_gput_right:Nn | -% \clist_gput_right:No | -% \clist_gput_right:cn | -% \clist_gput_right:co | -% \clist_gput_right:cc | +% \clist_put_right:Nn | +% \clist_put_right:No | +% \clist_put_right:NV | +% \clist_put_right:Nx | +% \clist_put_right:cn | +% \clist_put_right:co | +% \clist_put_right:cV | % } % \begin{syntax} -% "\clist_gput_left:Nn" <comma-list> <token list> +% "\clist_put_right:Nn" <comma-list> <token list> % \end{syntax} -% Globally appends <token list> as a single item to the left -% or right of <comma-list>. +% Locally appends <token list> as a single item to the right +% of <comma-list>. <token list> might get expanded before +% appending according to the variant used. % \end{function} % % \begin{function}{% -% \clist_get:NN | -% \clist_get:cN | +% \clist_gput_left:Nn | +% \clist_gput_left:NV | +% \clist_gput_left:No | +% \clist_gput_left:Nx | +% \clist_gput_left:cn | +% \clist_gput_left:cV | +% \clist_gput_left:co | % } % \begin{syntax} -% "\clist_get:NN" <comma-list> <tlp> +% "\clist_gput_left:Nn" <comma-list> <token list> % \end{syntax} -% Functions that locally assign the left-most item of <comma-list> to the -% token list pointer <tlp>. Item is not removed from <comma-list>! If you -% need a global return value you need to code something like this: -% \begin{quote} -% "\clist_get:NN" <comma-list> "\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. +% Globally appends <token list> as a single item to the +% right of <comma-list>. % \end{function} % % \begin{function}{% -% \clist_set_eq:NN +% \clist_gput_right:Nn | +% \clist_gput_right:NV | +% \clist_gput_right:No | +% \clist_gput_right:Nx | +% \clist_gput_right:cn | +% \clist_gput_right:cV | +% \clist_gput_right:co | % } % \begin{syntax} -% "\clist_set_eq:NN" <clist1> <clist2> +% "\clist_gput_right:Nn" <comma-list> <token list> % \end{syntax} -% Function that locally makes <clist1> identical to <clist2>. +% Globally appends <token list> as a single item to the +% right of <comma-list>. % \end{function} % +% \section{Getting data out} % -% \begin{function}{% -% \clist_gset_eq:NN | -% \clist_gset_eq:cN | -% \clist_gset_eq:Nc | -% \clist_gset_eq:cc -% } +% \begin{function}{ \clist_use:N | +% \clist_use:c } % \begin{syntax} -% "\clist_gset_eq:NN" <clist1> <clist2> +% "\clist_use:N" <clist> % \end{syntax} -% Function that globally makes <clist1> identical to <clist2>. +% Function that inserts the <clist> into the processing stream. Mainly +% useful if one knows what the <clist> contains, e.g., for displaying +% the content of template parameters. % \end{function} % -% -% \begin{function}{% -% \clist_concat:NNN | -% \clist_gconcat:NNN | -% \clist_gconcat:NNc | -% \clist_gconcat:ccc | -% } +% \begin{function}{ \clist_show:N | +% \clist_show:c } % \begin{syntax} -% "\clist_gconcat:NNN" <clist1> <clist2> <clist3> +% "\clist_show:N" <clist> % \end{syntax} -% Function that concatenates <clist2> and <clist3> and globally assigns the -% result to <clist1>. +% Function that pauses the compilation and displays <clist> in the terminal +% output and in the log file. (Usually used for diagnostic purposes.) % \end{function} % -% -% \begin{function}{% -% \clist_remove_duplicates:N | -% \clist_gremove_duplicates:N | -% } +% \begin{function}{ \clist_display:N | +% \clist_display:c } % \begin{syntax} -% "\clist_gremove_duplicates:N" <clist> +% "\clist_display:N" <clist> % \end{syntax} -% Function that removes any duplicate entries in <clist>. +% As with "\clist_show:N" but pretty prints the output one line per element. % \end{function} % -% \begin{function}{% -% \clist_use:N | -% \clist_use:c -% } +% \begin{function}{ \clist_get:NN | +% \clist_get:cN } % \begin{syntax} -% "\clist_use:N" <clist> +% "\clist_get:NN" <comma-list> <tl var.> % \end{syntax} -% Function that inserts the <clist> into the processing stream. Mainly -% useful if one knows what the <clist> contains, e.g., for displaying -% the content of template parameters. +% Functions that locally assign the left-most item of <comma-list> to the +% token list variable <tl var.>. Item is not removed from <comma-list>! If you +% need a global return value you need to code something like this: +% \begin{quote} +% "\clist_get:NN" <comma-list> "\l_tmpa_tl" \\ +% "\tl_gset_eq:NN" <global tl var.> "\l_tmpa_tl" +% \end{quote} +% But if this kind of construction is used often enough a separate +% function should be provided. % \end{function} % % -% \subsection{Mapping functions} +% \section{Mapping functions} % % % We provide three types of mapping functions, each with their own @@ -253,7 +287,7 @@ % \clist_map_inline:nn | % } % \begin{syntax} -% "\clist_map_inline:Nn" <comma-list> "{" <inline function> "}" +% "\clist_map_inline:Nn" <comma-list> \Arg{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 placeholder for @@ -269,7 +303,7 @@ % \clist_map_variable:nNn | % } % \begin{syntax} -% "\clist_map_variable:NNn" <comma-list> <temp-var> "{" <action> "}" +% "\clist_map_variable:NNn" <comma-list> <temp-var> \Arg{action} % \end{syntax} % Assigns <temp-var> to each element in <clist> and then executes % <action> which should contain <temp-var>. As the @@ -281,16 +315,16 @@ % \end{function} % % \begin{function}{% -% \clist_map_break:w | +% \clist_map_break: | % } % \begin{syntax} -% "\clist_map_break:w" +% "\clist_map_break:" % \end{syntax} % For breaking out of a loop. To be used inside "TF" type functions as % in the example below. % \begin{verbatim} -% \def_new:Npn \test_function:n #1 { -% \int_compare:nNnTF {#1}> 3 {\clist_map_break:w}{``#1''} +% \cs_new_nopar:Npn \test_function:n #1 { +% \intexpr_compare:nTF {#1 > 3} {\clist_map_break:}{``#1''} % } % \clist_map_function:nN {1,2,3,4,5,6,7,8}\test_function:n % \end{verbatim} @@ -298,9 +332,10 @@ % \end{function} % % -% \subsection{Predicates and conditionals} +% \section{Predicates and conditionals} % -% \begin{function}{\clist_if_empty_p:N} +% \begin{function}{ \clist_if_empty_p:N | +% \clist_if_empty_p:c } % \begin{syntax} % "\clist_if_empty_p:N" <comma-list> % \end{syntax} @@ -308,99 +343,87 @@ % contain any tokens. % \end{function} % -% \begin{function}{% -% \clist_if_empty:NTF | -% \clist_if_empty:cTF | -% \clist_if_empty:NF | -% \clist_if_empty:cF | -% } +% \begin{function}{ \clist_if_empty:N / (TF)(EXP) | +% \clist_if_empty:c / (TF)(EXP)} % \begin{syntax} -% "\clist_if_empty:NTF" <comma-list> "{" <true code> "}{" <false code> "}" +% "\clist_if_empty:NTF" <comma-list> \Arg{true code} \Arg{false code} % \end{syntax} % Set of conditionals that test whether or not a particular <comma-list> % is empty and if so executes either <true code> or <false code>. % \end{function} % -% \begin{function}{% -% \clist_if_eq:NNTF | -% } +% \begin{function}{ \clist_if_eq_p:NN / (EXP) | +% \clist_if_eq_p:cN / (EXP) | +% \clist_if_eq_p:Nc / (EXP) | +% \clist_if_eq_p:cc / (EXP) } % \begin{syntax} -% "\clist_if_eq:NNTF" <comma-list1> <comma-list2> "{" <true code> -% "}{" <false code> "}" +% "\clist_if_eq_p:N" <comma-list1> <comma-list2> +% \end{syntax} +% This predicate returns `true' if the two comma lists are identical. +% \end{function} +% +% \begin{function}{ \clist_if_eq:NN / (TF)(EXP) | +% \clist_if_eq:cN / (TF)(EXP) | +% \clist_if_eq:Nc / (TF)(EXP) | +% \clist_if_eq:cc / (TF)(EXP) } +% \begin{syntax} +% "\clist_if_eq:NNTF" <comma-list1> <comma-list2> \Arg{true code} \Arg{false code} % \end{syntax} % Check if <comma-list1> and <comma-list2> are equal and execute % either <true code> or <false code> accordingly. % \end{function} % -% \begin{function}{% -% \clist_if_in:NnTF | -% \clist_if_in:NoTF | -% \clist_if_in:cnTF | -% \clist_if_in:coTF | -% } +% \begin{function}{ \clist_if_in:Nn / (TF) | +% \clist_if_in:NV / (TF) | +% \clist_if_in:No / (TF) | +% \clist_if_in:cn / (TF) | +% \clist_if_in:cV / (TF) | +% \clist_if_in:co / (TF) } % \begin{syntax} -% "\clist_if_in:NnTF" <comma-list> "{" <item> "}{" <true code> "}{" -% <false code> "}" +% "\clist_if_in:NnTF" <comma-list> \Arg{item} \Arg{true code} \Arg{false code} % \end{syntax} % Function that tests if <item> is in <comma-list>. Depending on the result % either <true code> or <false code> is executed. % \end{function} % -% \subsection{Internal functions} +% \section{Higher level functions} % -% \begin{function}{\clist_if_empty_err:N} +% \begin{function}{ \clist_concat:NNN | +% \clist_concat:ccc | +% \clist_gconcat:NNN | +% \clist_gconcat:ccc } % \begin{syntax} -% "\clist_if_empty_err:N" <comma-list> +% "\clist_gconcat:NNN" <clist1> <clist2> <clist3> % \end{syntax} -% Signals an \LaTeX3 error if <comma-list> is empty. +% Function that concatenates <clist2> and <clist3> and locally or globally +% assigns the result to <clist1>. % \end{function} % -% \begin{function}{\clist_pop_aux:nnNN} +% +% \begin{function}{ \clist_remove_duplicates:N | +% \clist_gremove_duplicates:N } % \begin{syntax} -% "\clist_pop_aux:nnNN" <assign1> <assign2> <comma-list> <tlp> +% "\clist_gremove_duplicates:N" <clist> % \end{syntax} -% Function that assigns the left-most item of <comma-list> to <tlp> using -% <assign1> and assigns the tail to <comma-list> using <assign2>. This -% function could be used to implement a global return function. +% Function that removes any duplicate entries in <clist>. % \end{function} -% -% \begin{function}{% -% \clist_get_aux:w | -% \clist_pop_aux:w | -% \clist_pop_auxi:w | -% \clist_put_aux:NNnnNn | -% } -% \begin{syntax}\end{syntax} -% Functions used to implement put and get operations. They are not for -% meant for direct use. +% +% \begin{function}{ +% \clist_remove_element:Nn | +% \clist_gremove_element:Nn +%} +% \begin{syntax} +% "\clist_gremove_element:Nn" <clist> <element> +% \end{syntax} +% Function that removes <element> from <clist>, if present. +% \begin{texnote} +% This is similar in concept to \cs{@removeelement}, except that the +% syntax is clearer and the initial and final lists have the same +% name automatically. +% \end{texnote} % \end{function} % -% -% -% \begin{function}{% -% \clist_map_function_aux:Nw | -% \clist_map_inline_aux:Nw | -% \clist_map_variable_aux:Nnw | -% } -% \begin{syntax}\end{syntax} -% Internal helper functions for the <clist> mapping functions. -% \end{function} -% -% -% \begin{function}{% -% \clist_concat_aux:NNNN | -% \clist_remove_duplicates_aux:NN | -% \clist_remove_duplicates_aux:n | -% \l_clist_remove_duplicates_clist | -% } -% \begin{syntax}\end{syntax} -% Functions that help concatenate <clist>s and remove duplicate -% elements from a <clist>. -% \end{function} -% -% -% -% \subsection{Comma list Stacks} +% \section{Functions for `comma-list stacks'} % % Special comma-lists in \LaTeX3 are `stacks' with their usual operations % of `push', `pop', and `top'. They are internally implemented as @@ -409,14 +432,16 @@ % % \begin{function}{% % \clist_push:Nn | +% \clist_push:NV | % \clist_push:No | % \clist_push:cn | % \clist_gpush:Nn | +% \clist_gpush:NV | % \clist_gpush:No | % \clist_gpush:cn | % } % \begin{syntax} -% "\clist_push:Nn" <stack> "{" <token list> "}" +% "\clist_push:Nn" <stack> \Arg{token list} % \end{syntax} % Locally or globally pushes <token list> as a single item onto the % <stack>. <token list> might get expanded before the operation. @@ -429,10 +454,10 @@ % \clist_gpop:cN | % } % \begin{syntax} -% "\clist_pop:NN" <stack> <tlp> +% "\clist_pop:NN" <stack> <tl var.> % \end{syntax} % Functions that assign the top item of <stack> to the token -% list pointer <tlp> and removes it from <stack>! +% list variable <tl var.> and removes it from <stack>! % \end{function} % % \begin{function}{% @@ -440,38 +465,65 @@ % \clist_top:cN | % } % \begin{syntax} -% "\clist_top:NN" <stack> <tlp> +% "\clist_top:NN" <stack> <tl var.> % \end{syntax} % Functions that locally assign the top item of <stack> to the token -% list pointer <tlp>. Item is not removed from <stack>! +% list variable <tl var.>. Item is not removed from <stack>! % \end{function} % -% \StopEventually{} +% \section{Internal functions} % -% Use "clist" functions. +% \begin{function}{\clist_if_empty_err:N} +% \begin{syntax} +% "\clist_if_empty_err:N" <comma-list> +% \end{syntax} +% Signals an \LaTeX3 error if <comma-list> is empty. +% \end{function} % +% \begin{function}{\clist_pop_aux:nnNN} +% \begin{syntax} +% "\clist_pop_aux:nnNN" <assign1> <assign2> <comma-list> <tl var.> +% \end{syntax} +% Function that assigns the left-most item of <comma-list> to <tl var.> using +% <assign1> and assigns the tail to <comma-list> using <assign2>. This +% function could be used to implement a global return function. +% \end{function} % -% \subsection {The Implementation} +% \begin{function}{% +% \clist_get_aux:w | +% \clist_pop_aux:w | +% \clist_pop_auxi:w | +% \clist_put_aux:NNnnNn | +% } +% \begin{syntax}\end{syntax} +% Functions used to implement put and get operations. They are not for +% meant for direct use. +% \end{function} +% +% \end{documentation} +% +% \begin{implementation} +% +% \section{\pkg{l3clist} implementation} % % We start by ensuring that the required packages are loaded. % \begin{macrocode} -%<package>\ProvidesExplPackage -%<package> {\filename}{\filedate}{\fileversion}{\filedescription} %<*package> -\NeedsTeXFormat{LaTeX2e} -%<!check>\RequirePackage{l3prg,l3quark} -%<check>\RequirePackage{l3chk} +\ProvidesExplPackage + {\filename}{\filedate}{\fileversion}{\filedescription} +\package_check_loaded_expl: %</package> %<*initex|package> % \end{macrocode} % +% \subsection{Allocation and initialisation} % % \begin{macro}{\clist_new:N} % \begin{macro}{\clist_new:c} % Comma-Lists are implemented using token lists. % \begin{macrocode} -\def_new:Npn \clist_new:N #1{\tlp_new:Nn #1{}} -\def_new:Npn \clist_new:c {\exp_args:Nc \clist_new:N} +\cs_new_eq:NN \clist_new:N \tl_new:N +\cs_generate_variant:Nn \clist_new:N {c} % \end{macrocode} % \end{macro} % \end{macro} @@ -482,10 +534,10 @@ % \begin{macro}{\clist_gclear:c} % Clearing a comma-list is the same as clearing a token list. % \begin{macrocode} -\let_new:NN \clist_clear:N \tlp_clear:N -\let_new:NN \clist_clear:c \tlp_clear:c -\let_new:NN \clist_gclear:N \tlp_gclear:N -\let_new:NN \clist_gclear:c \tlp_gclear:c +\cs_new_eq:NN \clist_clear:N \tl_clear:N +\cs_generate_variant:Nn \clist_clear:N {c} +\cs_new_eq:NN \clist_gclear:N \tl_gclear:N +\cs_generate_variant:Nn \clist_gclear:N {c} % \end{macrocode} % \end{macro} % \end{macro} @@ -493,24 +545,32 @@ % \end{macro} % % -% \begin{macro}{\clist_set_eq:NN} -% We can set one \meta{clist} equal to another. +% \begin{macro}{\clist_clear_new:N} +% \begin{macro}{\clist_clear_new:c} +% \begin{macro}{\clist_gclear_new:N} +% \begin{macro}{\clist_gclear_new:c} +% Clearing a comma-list is the same as clearing a token list. % \begin{macrocode} -\let_new:NN \clist_set_eq:NN \let:NN +\cs_new_eq:NN \clist_clear_new:N \tl_clear_new:N +\cs_generate_variant:Nn \clist_clear_new:N {c} +\cs_new_eq:NN \clist_gclear_new:N \tl_gclear_new:N +\cs_generate_variant:Nn \clist_gclear_new:N {c} % \end{macrocode} % \end{macro} -% +% \end{macro} +% \end{macro} +% \end{macro} % % \begin{macro}{\clist_set_eq:NN} % \begin{macro}{\clist_set_eq:cN} % \begin{macro}{\clist_set_eq:Nc} % \begin{macro}{\clist_set_eq:cc} -% An of course globally which seems to be needed far more often. +% We can set one \meta{clist} equal to another. % \begin{macrocode} -\let_new:NN \clist_gset_eq:NN \glet:NN -\def_new:Npn \clist_gset_eq:cN {\exp_args:Nc \clist_gset_eq:NN} -\def_new:Npn \clist_gset_eq:Nc {\exp_args:NNc \clist_gset_eq:NN} -\def_new:Npn \clist_gset_eq:cc {\exp_args:Ncc \clist_gset_eq:NN} +\cs_new_eq:NN \clist_set_eq:NN \cs_set_eq:NN +\cs_new_eq:NN \clist_set_eq:cN \cs_set_eq:cN +\cs_new_eq:NN \clist_set_eq:Nc \cs_set_eq:Nc +\cs_new_eq:NN \clist_set_eq:cc \cs_set_eq:cc % \end{macrocode} % \end{macro} % \end{macro} @@ -518,33 +578,30 @@ % \end{macro} % % -% \begin{macro}{\clist_if_empty_p:N} -% A predicate which evaluates to |\c_true| iff the comma-list is empty. -% \begin{macrocode} -\let_new:NN \clist_if_empty_p:N \tlp_if_empty_p:N -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\clist_if_empty:NTF} -% \begin{macro}{\clist_if_empty:NT} -% \begin{macro}{\clist_if_empty:NF} -% \begin{macro}{\clist_if_empty:cTF} -% \begin{macro}{\clist_if_empty:cT} -% \begin{macro}{\clist_if_empty:cF} -% |\clist_if_empty:NTF|\m{clist}\m{true~case}\m{false~case} will check -% whether the \m{clist} is empty and then select one of the other -% arguments. |\clist_if_empty:cTF| turns its first argument into a -% control comma-list to get the name of the comma-list. +% \begin{macro}{\clist_gset_eq:NN} +% \begin{macro}{\clist_gset_eq:cN} +% \begin{macro}{\clist_gset_eq:Nc} +% \begin{macro}{\clist_gset_eq:cc} +% An of course globally which seems to be needed far more often. % \begin{macrocode} -\def_test_function_new:npn {clist_if_empty:N}#1{\if_meaning:NN#1\c_empty_tlp} -\def_new:Npn \clist_if_empty:cTF {\exp_args:Nc\clist_if_empty:NTF} -\def_new:Npn \clist_if_empty:cT {\exp_args:Nc\clist_if_empty:NT} -\def_new:Npn \clist_if_empty:cF {\exp_args:Nc\clist_if_empty:NF} +\cs_new_eq:NN \clist_gset_eq:NN \cs_gset_eq:NN +\cs_new_eq:NN \clist_gset_eq:cN \cs_gset_eq:cN +\cs_new_eq:NN \clist_gset_eq:Nc \cs_gset_eq:Nc +\cs_new_eq:NN \clist_gset_eq:cc \cs_gset_eq:cc % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} +% +% \subsection{Predicates and conditionals} +% +% \begin{macro}{\clist_if_empty_p:N,\clist_if_empty_p:c} +% \begin{macro}[TF]{\clist_if_empty:N,\clist_if_empty:c} +% \begin{macrocode} +\prg_new_eq_conditional:NNn \clist_if_empty:N \tl_if_empty:N {p,TF,T,F} +\prg_new_eq_conditional:NNn \clist_if_empty:c \tl_if_empty:c {p,TF,T,F} +% \end{macrocode} % \end{macro} % \end{macro} % @@ -552,154 +609,257 @@ % \begin{macro}{\clist_if_empty_err:N} % Signals an error if the comma-list is empty. % \begin{macrocode} -\def_new:Npn \clist_if_empty_err:N #1{ - \if_meaning:NN#1\c_empty_tlp - \tlp_clear:N \l_testa_tlp % catch prefixes - \err_latex_bug:x{Empty~comma-list~`\token_to_string:N#1'} - \fi:} +\cs_new_nopar:Npn \clist_if_empty_err:N #1 { + \if_meaning:w #1 \c_empty_tl + \tl_clear:N \l_testa_tl % catch prefixes + \msg_kernel_bug:x {Empty~comma-list~`\token_to_str:N #1'} + \fi: +} % \end{macrocode} % \end{macro} % -% \begin{macro}{\clist_if_eq:NNTF} -% As comma lists are token list pointers internally this is just an -% alias. +% \begin{macro}{\clist_if_eq_p:NN,\clist_if_eq_p:Nc, +% \clist_if_eq_p:cN,\clist_if_eq_p:cc} +% \begin{macro}[TF]{\clist_if_eq:NN,\clist_if_eq:cN, +% \clist_if_eq:Nc,\clist_if_eq:cc} +% Returns |\c_true| iff the two comma-lists are equal. % \begin{macrocode} -\let_new:NN \clist_if_eq:NNTF \tlp_if_eq:NNTF +\prg_new_eq_conditional:NNn \clist_if_eq:NN \tl_if_eq:NN {p,TF,T,F} +\prg_new_eq_conditional:NNn \clist_if_eq:cN \tl_if_eq:cN {p,TF,T,F} +\prg_new_eq_conditional:NNn \clist_if_eq:Nc \tl_if_eq:Nc {p,TF,T,F} +\prg_new_eq_conditional:NNn \clist_if_eq:cc \tl_if_eq:cc {p,TF,T,F} % \end{macrocode} -% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}[TF]{\clist_if_in:Nn} +% \begin{macro}[TF]{\clist_if_in:NV,\clist_if_in:No,\clist_if_in:cn, +% \clist_if_in:cV,\clist_if_in:co} +% |\clist_if_in:NnTF| \m{clist}\m{item} \m{true~case} \m{false~case} +% will check whether \m{item} is in \m{clist} and then either execute +% the \m{true~case} or the \m{false~case}. \m{true~case} and +% \m{false~case} may contain incomplete |\if_charcode:w| +% statements. +% \begin{macrocode} +\prg_new_conditional:Nnn \clist_if_in:Nn {TF,T,F} { + \cs_set:Npn \clist_tmp:w ##1,#2,##2##3 \q_stop { + \if_meaning:w \q_no_value ##2 + \prg_return_false: \else: \prg_return_true: \fi: + } + \exp_last_unbraced:NNo \clist_tmp:w , #1 , #2 , \q_no_value \q_stop +} +% \end{macrocode} +% \begin{macrocode} +\cs_generate_variant:Nn \clist_if_in:NnTF {NV,No,cn,cV,co} +\cs_generate_variant:Nn \clist_if_in:NnT {NV,No,cn,cV,co} +\cs_generate_variant:Nn \clist_if_in:NnF {NV,No,cn,cV,co} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% \subsection{Retrieving data} +% +% \begin{macro}{\clist_use:N} +% \begin{macro}{\clist_use:c} +% Using a \meta{clist} is just executing it but +% if \m{clist} equals |\scan_stop:| it is probably stemming +% from a |\cs:w ... \cs_end:| that was created by mistake somewhere. +% \begin{macrocode} +\cs_new_nopar:Npn \clist_use:N #1 { + \if_meaning:w #1 \scan_stop: + \msg_kernel_bug:x { + Comma~list~ `\token_to_str:N #1'~ has~ an~ erroneous~ structure!} + \else: + \exp_after:wN #1 + \fi: +} +\cs_generate_variant:Nn \clist_use:N {c} +% \end{macrocode} +% \end{macro} +% \end{macro} % % \begin{macro}{\clist_get:NN} % \begin{macro}{\clist_get:cN} -% |\clist_get:NN |\zz{comma-list}\zz{cmd} defines \zz{cmd} to be the -% left-most element of \zz{comma-list}. +% \begin{macro}{\clist_get_aux:w} +% |\clist_get:NN |\meta{comma-list}\meta{cmd} defines \meta{cmd} to be the +% left-most element of \meta{comma-list}. % \begin{macrocode} -\def_new:Npn \clist_get:NN #1{ +\cs_new_nopar:Npn \clist_get:NN #1 { \clist_if_empty_err:N #1 - \exp_after:NN\clist_get_aux:w #1,\q_stop} + \exp_after:wN \clist_get_aux:w #1,\q_stop +} % \end{macrocode} % \begin{macrocode} -\def_new:Npn \clist_get_aux:w #1,#2\q_stop #3{\tlp_set:Nn #3{#1}} +\cs_new:Npn \clist_get_aux:w #1,#2\q_stop #3 { \tl_set:Nn #3{#1} } % \end{macrocode} % \begin{macrocode} -\def_new:Npn \clist_get:cN {\exp_args:Nc \clist_get:NN} +\cs_generate_variant:Nn \clist_get:NN {cN} % \end{macrocode} % \end{macro} % \end{macro} +% \end{macro} % % \begin{macro}{\clist_pop_aux:nnNN} % \begin{macro}{\clist_pop_aux:w} % \begin{macro}{\clist_pop_auxi:w} -% |\clist_pop_aux:nnNN| \zz{def$\sb1$} \zz{def$\sb2$} \zz{comma-list} -% \zz{cmd} assigns the left-most element of \zz{comma-list} to -% \zz{cmd} using \zz{def$\sb2$}, and assigns the tail of -% \zz{comma-list} to \zz{comma-list} using \zz{def$\sb1$}. +% |\clist_pop_aux:nnNN| \meta{def$\sb1$} \meta{def$\sb2$} \meta{comma-list} +% \meta{cmd} assigns the left-most element of \meta{comma-list} to +% \meta{cmd} using \meta{def$\sb2$}, and assigns the tail of +% \meta{comma-list} to \meta{comma-list} using \meta{def$\sb1$}. % \begin{macrocode} -\def_new:Npn \clist_pop_aux:nnNN #1#2#3{ +\cs_new:Npn \clist_pop_aux:nnNN #1#2#3 { \clist_if_empty_err:N #3 - \exp_after:NN\clist_pop_aux:w #3,\q_nil\q_stop #1#2#3} + \exp_after:wN \clist_pop_aux:w #3,\q_nil\q_stop #1#2#3 +} % \end{macrocode} +% After the assignmnets below, if there was only one element in the original +% clist, it now contains only |\q_nil|. % \begin{macrocode} -\def_new:Npn \clist_pop_aux:w #1,#2\q_stop #3#4#5#6{ - #4#6{#1} - #3#5{#2} +\cs_new:Npn \clist_pop_aux:w #1,#2\q_stop #3#4#5#6 { + #4 #6 {#1} + #3 #5 {#2} + \quark_if_nil:NTF #5 { #3 #5 {} }{ \clist_pop_auxi:w #2 #3#5 } +} % \end{macrocode} -% If there was only one element in the original clist, it now contains -% only |\q_nil|. % \begin{macrocode} - \quark_if_nil:NTF #5 - { #3#5{} } - { \clist_pop_auxi:w #2 #3#5 } -} +\cs_new:Npn \clist_pop_auxi:w #1,\q_nil #2#3 { #2#3{#1} } % \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\clist_show:N} +% \begin{macro}{\clist_show:c} % \begin{macrocode} -\def_new:Npn\clist_pop_auxi:w #1,\q_nil #2#3 {#2#3{#1}} +\cs_new_eq:NN \clist_show:N \tl_show:N +\cs_new_eq:NN \clist_show:c \tl_show:c % \end{macrocode} % \end{macro} % \end{macro} +% +% \begin{macro}{\clist_display:N} +% \begin{macro}{\clist_display:c} +% \begin{macrocode} +\cs_new_nopar:Npn \clist_display:N #1 { + \iow_term:x { Comma-list~\token_to_str:N #1~contains~ + the~elements~(without~outer~braces): } + \toks_clear:N \l_tmpa_toks + \clist_map_inline:Nn #1 { + \toks_if_empty:NF \l_tmpa_toks { + \toks_put_right:Nx \l_tmpa_toks {^^J>~} + } + \toks_put_right:Nx \l_tmpa_toks { + \iow_space: \iow_char:N \{ \exp_not:n {##1} \iow_char:N \} + } + } + \toks_show:N \l_tmpa_toks +} +\cs_generate_variant:Nn \clist_display:N {c} +% \end{macrocode} +% \end{macro} % \end{macro} % +% \subsection{Storing data} +% % \begin{macro}{\clist_put_aux:NNnnNn} % The generic put function. -% \begin{macrocode} -\def_new:Npn \clist_put_aux:NNnnNn #1#2#3#4#5#6{ -% \end{macrocode} % When adding we have to distinguish between an empty \meta{clist} % and one that contains at least one item (otherwise we accumulate % commas). -% \begin{macrocode} - \clist_if_empty:NTF#5 {#1 #5{#6}} -% \end{macrocode} +% % MH says: Perhaps we should make sure that empty arguments don't get % on the stack as that is probably a mistake. That's what I've -% implemented here. Since |\tlist_if_empty:nF| is expandable prefixes +% implemented here. Since |\tl_if_empty:nF| is expandable prefixes % are still allowed. % \begin{macrocode} - { \tlist_if_empty:nF {#6}{ #2 #5{#3#6#4} } } +\cs_new:Npn \clist_put_aux:NNnnNn #1#2#3#4#5#6 { + \clist_if_empty:NTF #5 { #1 #5 {#6} } { + \tl_if_empty:nF {#6} { #2 #5{#3#6#4} } + } } % \end{macrocode} % \end{macro} +% % \begin{macro}{\clist_put_left:Nn} +% \begin{macro}{\clist_put_left:NV} % \begin{macro}{\clist_put_left:No} % \begin{macro}{\clist_put_left:Nx} % \begin{macro}{\clist_put_left:cn} +% \begin{macro}{\clist_put_left:cV} +% \begin{macro}{\clist_put_left:co} % The operations for adding to the left. % \begin{macrocode} -\def_new:Npn \clist_put_left:Nn { - \clist_put_aux:NNnnNn \tlp_set:Nn \tlp_put_left:Nn {} , +\cs_new_nopar:Npn \clist_put_left:Nn { + \clist_put_aux:NNnnNn \tl_set:Nn \tl_put_left:Nn {} , } -\def_new:Npn \clist_put_left:cn {\exp_args:Nc \clist_put_left:Nn} -\def_new:Npn \clist_put_left:No {\exp_args:NNo\clist_put_left:Nn} -\def_new:Npn \clist_put_left:Nx {\exp_args:Nnx\clist_put_left:Nn} +\cs_generate_variant:Nn \clist_put_left:Nn {NV,No,Nx,cn,cV,co} % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% % \begin{macro}{\clist_gput_left:Nn} +% \begin{macro}{\clist_gput_left:NV} +% \begin{macro}{\clist_gput_left:No} +% \begin{macro}{\clist_gput_left:Nx} +% \begin{macro}{\clist_gput_left:cn} +% \begin{macro}{\clist_gput_left:cV} +% \begin{macro}{\clist_gput_left:co} % Global versions. % \begin{macrocode} -\def_new:Npn \clist_gput_left:Nn { - \clist_put_aux:NNnnNn \tlp_gset:Nn \tlp_gput_left:Nn {} , +\cs_new_nopar:Npn \clist_gput_left:Nn { + \clist_put_aux:NNnnNn \tl_gset:Nn \tl_gput_left:Nn {} , } +\cs_generate_variant:Nn \clist_gput_left:Nn {NV,No,Nx,cn,cV,co} % \end{macrocode} % \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} % % \begin{macro}{\clist_put_right:Nn} -% \begin{macro}{\clist_put_right:cn} +% \begin{macro}{\clist_put_right:NV} % \begin{macro}{\clist_put_right:No} % \begin{macro}{\clist_put_right:Nx} +% \begin{macro}{\clist_put_right:cn} +% \begin{macro}{\clist_put_right:cV} +% \begin{macro}{\clist_put_right:co} % Adding something to the right side is almost the same. % \begin{macrocode} -\def_new:Npn \clist_put_right:Nn { - \clist_put_aux:NNnnNn \tlp_set:Nn \tlp_put_right:Nn , {} +\cs_new_nopar:Npn \clist_put_right:Nn { + \clist_put_aux:NNnnNn \tl_set:Nn \tl_put_right:Nn , {} } -\def_new:Npn \clist_put_right:cn {\exp_args:Nc \clist_put_right:Nn} -\def_new:Npn \clist_put_right:No {\exp_args:Nno\clist_put_right:Nn} -\def_new:Npn \clist_put_right:Nx {\exp_args:Nnx\clist_put_right:Nn} +\cs_generate_variant:Nn \clist_put_right:Nn {NV,No,Nx,cn,cV,co} % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} % % \begin{macro}{\clist_gput_right:Nn} +% \begin{macro}{\clist_gput_right:NV} % \begin{macro}{\clist_gput_right:No} +% \begin{macro}{\clist_gput_right:Nx} % \begin{macro}{\clist_gput_right:cn} +% \begin{macro}{\clist_gput_right:cV} % \begin{macro}{\clist_gput_right:co} -% \begin{macro}{\clist_gput_right:cc} -% \begin{macro}{\clist_gput_right:NC} -% An here the global variants. +% And here the global variants. % \begin{macrocode} -\def_new:Npn \clist_gput_right:Nn { - \clist_put_aux:NNnnNn \tlp_gset:Nn \tlp_gput_right:Nn , {} +\cs_new_nopar:Npn \clist_gput_right:Nn { + \clist_put_aux:NNnnNn \tl_gset:Nn \tl_gput_right:Nn , {} } -\def_new:Npn \clist_gput_right:No {\exp_args:NNo \clist_gput_right:Nn} -\def_new:Npn \clist_gput_right:cn {\exp_args:Nc \clist_gput_right:Nn} -\def_new:Npn \clist_gput_right:co {\exp_args:Nco \clist_gput_right:Nn} -\def_new:Npn \clist_gput_right:cc {\exp_args:Ncc \clist_gput_right:Nn} -% \end{macrocode} -% \begin{macrocode} -\def_new:Npn \clist_gput_right:NC {\exp_args:NNC \clist_gput_right:Nn} +\cs_generate_variant:Nn \clist_gput_right:Nn {NV,No,Nx,cn,cV,co} % \end{macrocode} % \end{macro} % \end{macro} @@ -707,36 +867,42 @@ % \end{macro} % \end{macro} % \end{macro} +% \end{macro} +% +% +% \subsection{Mapping} % -% \begin{macro}{\clist_map_function:nN} -% \begin{macro}{\clist_map_function:cN} % \begin{macro}{\clist_map_function:NN} -% |\clist_map_function:NN| \zz{comma-list} \zz{cmd} applies \zz{cmd} to each -% element of \zz{comma-list}, from left to right. +% \begin{macro}{\clist_map_function:cN} +% \begin{macro}{\clist_map_function:nN} +% |\clist_map_function:NN| \meta{comma-list} \meta{cmd} applies \meta{cmd} to each +% element of \meta{comma-list}, from left to right. % \begin{macrocode} -\def_new:Npn \clist_map_function:NN #1#2{ - \clist_if_empty:NF #1 - { - \exp_after:NN \clist_map_function_aux:Nw - \exp_after:NN #2 #1 , \q_recursion_tail , \q_recursion_stop +\cs_new_nopar:Npn \clist_map_function:NN #1#2 { + \clist_if_empty:NF #1 { + \exp_after:wN \clist_map_function_aux:Nw + \exp_after:wN #2 #1 , \q_recursion_tail , \q_recursion_stop } } -\def_new:Npn \clist_map_function:cN{\exp_args:Nc\clist_map_function:NN} -\def_new:Npn \clist_map_function:nN #1#2{ - \tlist_if_blank:nF {#1} - { \clist_map_function_aux:Nw #2 #1 , \q_recursion_tail , \q_recursion_stop } +\cs_generate_variant:Nn \clist_map_function:NN {cN} +% \end{macrocode} +% \begin{macrocode} +\cs_new:Npn \clist_map_function:nN #1#2 { + \tl_if_blank:nF {#1} { + \clist_map_function_aux:Nw #2 #1 , \q_recursion_tail , \q_recursion_stop + } } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % -% \begin{macro}{\clist_map_function_aux:Nw} +% \begin{macro}[aux]{\clist_map_function_aux:Nw} % The general loop. Tests if we hit the first stop marker and exits if % we did. If we didn't, place the function "#1" in front of the % element "#2", which is surrounded by braces. % \begin{macrocode} -\def_long_new:Npn \clist_map_function_aux:Nw #1#2,{ +\cs_new:Npn \clist_map_function_aux:Nw #1#2,{ \quark_if_recursion_tail_stop:n{#2} #1{#2} \clist_map_function_aux:Nw #1 @@ -744,11 +910,11 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}{\clist_map_break:w} +% \begin{macro}{\clist_map_break:} % The break statement is easy. Same as in other modules, gobble % everything up to the special recursion stop marker. % \begin{macrocode} -\let_new:NN \clist_map_break:w \use_none_delimit_by_q_recursion_stop:w +\cs_new_eq:NN \clist_map_break: \use_none_delimit_by_q_recursion_stop:w % \end{macrocode} % \end{macro} % @@ -769,31 +935,28 @@ % every operation globally. % \begin{macrocode} \int_new:N \g_clist_inline_level_int -\def_long_new:Npn \clist_map_inline:Nn #1#2{ - \clist_if_empty:NF #1 - { +\cs_new:Npn \clist_map_inline:Nn #1#2 { + \clist_if_empty:NF #1 { \int_gincr:N \g_clist_inline_level_int - \gdef_long:cpn {clist_map_inline_ \int_use:N \g_clist_inline_level_int :n} + \cs_gset:cpn {clist_map_inline_ \int_use:N \g_clist_inline_level_int :n} ##1{#2} % \end{macrocode} -% Recall that the |E| in |\exp_args:NcE| means `single token expanded -% once and no braces added'. It is a lot more efficient to carry over +% It is a lot more efficient to carry over % the special function rather than constructing the same csname over % and over again, so we just do it once. We reuse % |\clist_map_function_aux:Nw| for the actual loop. % \begin{macrocode} - \exp_args:NcE \clist_map_function_aux:Nw + \exp_last_unbraced:NcV \clist_map_function_aux:Nw {clist_map_inline_ \int_use:N \g_clist_inline_level_int :n} #1 , \q_recursion_tail , \q_recursion_stop \int_gdecr:N \g_clist_inline_level_int } } -\def_new:Npn \clist_map_inline:cn{\exp_args:Nc\clist_map_inline:Nn} -\def_long_new:Npn \clist_map_inline:nn #1#2{ - \tlist_if_empty:nF {#1} - { +\cs_generate_variant:Nn \clist_map_inline:Nn {c} +\cs_new:Npn \clist_map_inline:nn #1#2 { + \tl_if_empty:nF {#1} { \int_gincr:N \g_clist_inline_level_int - \gdef_long:cpn {clist_map_inline_ \int_use:N \g_clist_inline_level_int :n} + \cs_gset:cpn {clist_map_inline_ \int_use:N \g_clist_inline_level_int :n} ##1{#2} \exp_args:Nc \clist_map_function_aux:Nw {clist_map_inline_ \int_use:N \g_clist_inline_level_int :n} @@ -810,76 +973,78 @@ % \begin{macro}{\clist_map_variable:nNn} % \begin{macro}{\clist_map_variable:NNn} % \begin{macro}{\clist_map_variable:cNn} -% |\clist_map:NNn| \zz{comma-list} \zz{temp} \zz{action} assigns -% \zz{temp} to each element and executes \zz{action}. +% |\clist_map_variable:NNn| \meta{comma-list} \meta{temp} \meta{action} assigns +% \meta{temp} to each element and executes \meta{action}. % \begin{macrocode} -\def_new:Npn \clist_map_variable:nNn #1#2#3{ - \tlist_if_empty:nF{#1} - { +\cs_new:Npn \clist_map_variable:nNn #1#2#3 { + \tl_if_empty:nF {#1} { \clist_map_variable_aux:Nnw #2 {#3} #1 , \q_recursion_tail , \q_recursion_stop } } -\def_new:Npn \clist_map_variable:NNn {\exp_args:No \clist_map_variable:nNn} -\def_new:Npn \clist_map_variable:cNn {\exp_args:Nc \clist_map_variable:NNn} +% \end{macrocode} +% Something for v/V +% \begin{macrocode} +\cs_new_nopar:Npn \clist_map_variable:NNn {\exp_args:No \clist_map_variable:nNn} +\cs_generate_variant:Nn\clist_map_variable:NNn {cNn} % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % -% \begin{macro}{\clist_map_variable_aux:Nnw} +% \begin{macro}[aux]{\clist_map_variable_aux:Nnw} % The general loop. Assign the temp variable |#1| to the current item % |#3| and then check if that's the stop marker. If it is, break the % loop. If not, execute the action |#2| and continue. % \begin{macrocode} -\def_new:Npn \clist_map_variable_aux:Nnw #1#2#3,{ - \def:Npn #1{#3} +\cs_new:Npn \clist_map_variable_aux:Nnw #1#2#3,{ + \cs_set_nopar:Npn #1{#3} \quark_if_recursion_tail_stop:N #1 #2 \clist_map_variable_aux:Nnw #1{#2} } % \end{macrocode} % \end{macro} % -% \begin{macro}{\clist_concat_aux:NNNN} -% \begin{macro}{\clist_concat:NNN} -% \begin{macro}{\clist_gconcat:NNN} -% \begin{macro}{\clist_gconcat:NNc} -% \begin{macro}{\clist_gconcat:ccc} +% \subsection{Higher level functions} +% +% \begin{macro}[aux]{\clist_concat_aux:NNNN} +% \begin{macro}{\clist_concat:NNN,\clist_concat:ccc} +% \begin{macro}{\clist_gconcat:NNN,\clist_gconcat:ccc} % |\clist_gconcat:NNN| \m{clist~1} \m{clist~2} \m{clist~3} will globally % assign \m{clist~1} the concatenation of \m{clist~2} and % \m{clist~3}. +% +% Again the situation is a bit more complicated because of the use +% of commas between items, so if either list is empty we have to avoid +% adding a comma. % \begin{macrocode} -\def_new:Npn \clist_concat_aux:NNNN #1#2#3#4{ +\cs_new_nopar:Npn \clist_concat_aux:NNNN #1#2#3#4 { \toks_set:No \l_tmpa_toks {#3} \toks_set:No \l_tmpb_toks {#4} #1 #2 { \toks_use:N \l_tmpa_toks -% \end{macrocode} -% Again the situation is a bit more complicated because of the use -% of commas between items, so if either list is empty we have to avoid -% adding a comma. -% \begin{macrocode} - \toks_if_empty:NF \l_tmpa_toks {\toks_if_empty:NF \l_tmpb_toks ,} + \toks_if_empty:NF \l_tmpa_toks { \toks_if_empty:NF \l_tmpb_toks , } \toks_use:N \l_tmpb_toks } } -\def_new:Npn \clist_concat:NNN {\clist_concat_aux:NNNN \tlp_set:Nx} -\def_new:Npn \clist_gconcat:NNN {\clist_concat_aux:NNNN \tlp_gset:Nx} +\cs_new_nopar:Npn \clist_concat:NNN { \clist_concat_aux:NNNN \tl_set:Nx } +\cs_new_nopar:Npn \clist_gconcat:NNN { \clist_concat_aux:NNNN \tl_gset:Nx } +\cs_generate_variant:Nn \clist_concat:NNN {ccc} +\cs_generate_variant:Nn \clist_gconcat:NNN {ccc} % \end{macrocode} -% And the usual versions. -% \begin{macrocode} -\def_new:Npn \clist_gconcat:NNc{\exp_args:Nnnc\clist_gconcat:NNN} -\def_new:Npn \clist_gconcat:ccc{\exp_args:Nccc\clist_gconcat:NNN} -% \end{macrocode} -% \end{macro} % \end{macro} % \end{macro} % \end{macro} -% \end{macro} -% +% +% \begin{macro}[aux]{\l_clist_remove_clist} +% A common scratch space for the removal routines. +% \begin{macrocode} +\clist_new:N \l_clist_remove_clist +% \end{macrocode} +% \end{macro} % -% \begin{macro}{\clist_remove_duplicates_aux:NN} -% \begin{macro}{\clist_remove_duplicates_aux:n} +% \begin{macro}[aux]{\clist_remove_duplicates_aux:NN} +% \begin{macro}[aux]{\clist_remove_duplicates_aux:n} % \begin{macro}{\clist_remove_duplicates:N} % \begin{macro}{\clist_gremove_duplicates:N} % Removing duplicate entries in a \meta{clist} is fairly straight @@ -887,23 +1052,24 @@ % from left to right. For each element check if the element is % already present in the list. % \begin{macrocode} -\def:Npn \clist_remove_duplicates_aux:NN #1#2 { - \clist_clear:N \l_clist_remove_duplicates_clist +\cs_new:Nn \clist_remove_duplicates_aux:NN { + \clist_clear:N \l_clist_remove_clist \clist_map_function:NN #2 \clist_remove_duplicates_aux:n - #1 #2 \l_clist_remove_duplicates_clist + #1 #2 \l_clist_remove_clist } -\def:Npn \clist_remove_duplicates_aux:n #1 { - \clist_if_in:NnTF \l_clist_remove_duplicates_clist {#1} {} - {\clist_put_right:Nn \l_clist_remove_duplicates_clist {#1}} +\cs_new:Nn \clist_remove_duplicates_aux:n { + \clist_if_in:NnF \l_clist_remove_clist {#1} { + \clist_put_right:Nn \l_clist_remove_clist {#1} + } } % \end{macrocode} % The high level functions are just for telling if it should be a % local or global setting. % \begin{macrocode} -\def_new:Npn \clist_remove_duplicates:N { +\cs_new_nopar:Npn \clist_remove_duplicates:N { \clist_remove_duplicates_aux:NN \clist_set_eq:NN } -\def_new:Npn \clist_gremove_duplicates:N { +\cs_new_nopar:Npn \clist_gremove_duplicates:N { \clist_remove_duplicates_aux:NN \clist_gset_eq:NN } % \end{macrocode} @@ -911,67 +1077,38 @@ % \end{macro} % \end{macro} % \end{macro} -% -% \begin{macro}{\l_clist_remove_duplicates_clist} -% \begin{macrocode} -\clist_new:N \l_clist_remove_duplicates_clist -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\clist_use:N} -% \begin{macro}{\clist_use:c} -% Using a \meta{clist} is just executing it but\dots -% \begin{macrocode} -\def_new:Npn \clist_use:N #1 { - \if_meaning:NN #1 \scan_stop: -% \end{macrocode} -% \dots\ if \m{clist} equals |\scan_stop:| it is probably stemming -% from a |\cs:w ... \cs_end:| that was created by mistake somewhere. +% +%\begin{macro}{\clist_remove_element:Nn} +%\begin{macro}{\clist_gremove_element:Nn} +%\begin{macro}[aux]{\clist_remove_element_aux:NNn} +%\begin{macro}[aux]{\clist_remove_element_aux:n} +% The same general idea is used for removing elements: the parent +% functions just set things up for the internal ones. % \begin{macrocode} - \err_latex_bug:x {Comma~list~ `\token_to_string:N #1'~ - has~ an~ erroneous~ structure!} - \else: - \exp_after:NN #1 - \fi: +\cs_new_nopar:Npn \clist_remove_element:Nn { + \clist_remove_element_aux:NNn \clist_set_eq:NN } -\def_new:Npn \clist_use:c {\exp_args:Nc \clist_use:N} -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\clist_if_in:NnTF} -% \begin{macro}{\clist_if_in:NoTF} -% \begin{macro}{\clist_if_in:cnTF} -% \begin{macro}{\clist_if_in:coTF} -% |\clist_if_in:NnTF| \m{clist}\m{item} \m{true~case} \m{false~case} -% will check whether \m{item} is in \m{clist} and then either execute -% the \m{true~case} or the \m{false~case}. \m{true~case} and -% \m{false~case} may contain incomplete |\if_charcode:w| -% statements. -% \begin{macrocode} -\def_new:Npn \clist_if_in:NnTF #1#2{ - \def:Npn \tmp:w ##1 ,#2, ##2##3\q_stop{ - \if_meaning:NN\q_no_value##2 - \exp_after:NN\use_arg_ii:nn - \else: - \exp_after:NN\use_arg_i:nn - \fi: +\cs_new_nopar:Npn \clist_gremove_element:Nn { + \clist_remove_element_aux:NNn \clist_gset_eq:NN +} +\cs_new:Nn \clist_remove_element_aux:NNn { + \clist_clear:N \l_clist_remove_clist + \cs_set:Nn \clist_remove_element_aux:n { + \tl_if_eq:nnF {#3} {##1} { + \clist_put_right:Nn \l_clist_remove_clist {##1} + } } - \exp_after:NN \tmp:w - \exp_after:NN , #1, #2, \q_no_value \q_stop + \clist_map_function:NN #2 \clist_remove_element_aux:n + #1 #2 \l_clist_remove_clist } -\def_new:Npn \clist_if_in:NoTF {\exp_args:NNo \clist_if_in:NnTF} -\def_new:Npn \clist_if_in:coTF {\exp_args:Nco \clist_if_in:NnTF} -\def_new:Npn \clist_if_in:cnTF {\exp_args:Nc \clist_if_in:NnTF} +\cs_new:Nn \clist_remove_element_aux:n { } % \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} % -% -% \subsubsection{Stack operations} +% \subsection{Stack operations} % % We build stacks from comma-lists, but here we put the % specific functions together. @@ -979,6 +1116,7 @@ % % \begin{macro}{\clist_push:Nn} % \begin{macro}{\clist_push:No} +% \begin{macro}{\clist_push:NV} % \begin{macro}{\clist_push:cn} % \begin{macro}{\clist_pop:NN} % \begin{macro}{\clist_pop:cN} @@ -986,22 +1124,25 @@ % `push' and `pop'. In most cases they are nothing more then new % names for old functions. % \begin{macrocode} -\let_new:NN \clist_push:Nn \clist_put_left:Nn -\let_new:NN \clist_push:No \clist_put_left:No -\let_new:NN \clist_push:cn \clist_put_left:cn -\def_new:Npn \clist_pop:NN {\clist_pop_aux:nnNN \tlp_set:Nn \tlp_set:Nn} -\def_new:Npn \clist_pop:cN {\exp_args:Nc \clist_pop:NN} +\cs_new_eq:NN \clist_push:Nn \clist_put_left:Nn +\cs_new_eq:NN \clist_push:NV \clist_put_left:NV +\cs_new_eq:NN \clist_push:No \clist_put_left:No +\cs_new_eq:NN \clist_push:cn \clist_put_left:cn +\cs_new_nopar:Npn \clist_pop:NN {\clist_pop_aux:nnNN \tl_set:Nn \tl_set:Nn} +\cs_generate_variant:Nn \clist_pop:NN {cN} % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} +% \end{macro} % % % % \begin{macro}{\clist_gpush:Nn} % \begin{macro}{\clist_gpush:No} +% \begin{macro}{\clist_gpush:NV} % \begin{macro}{\clist_gpush:cn} % \begin{macro}{\clist_gpop:NN} % \begin{macro}{\clist_gpop:cN} @@ -1010,12 +1151,17 @@ % here more often. In case of |\clist_gpop:NN| the value is % nevertheless returned locally. % \begin{macrocode} -\let_new:NN \clist_gpush:Nn \clist_gput_left:Nn -\def_new:Npn \clist_gpush:No {\exp_args:NNo \clist_gpush:Nn} -\def_new:Npn \clist_gpush:cn {\exp_args:Nc \clist_gpush:Nn} -\def_new:Npn \clist_gpop:NN {\clist_pop_aux:nnNN \tlp_gset:Nn \tlp_set:Nn} -\def_new:Npn \clist_gpop:cN {\exp_args:Nc \clist_gpop:NN} +\cs_new_eq:NN \clist_gpush:Nn \clist_gput_left:Nn +\cs_new_eq:NN \clist_gpush:NV \clist_gput_left:NV +\cs_new_eq:NN \clist_gpush:No \clist_gput_left:No +\cs_generate_variant:Nn \clist_gpush:Nn {cn} % \end{macrocode} +% +% \begin{macrocode} +\cs_new_nopar:Npn \clist_gpop:NN {\clist_pop_aux:nnNN \tl_gset:Nn \tl_set:Nn} +\cs_generate_variant:Nn \clist_gpop:NN {cN} +% \end{macrocode} +% \end{macro} % \end{macro} % \end{macro} % \end{macro} @@ -1028,58 +1174,26 @@ % Looking at the top element of the stack without removing it is % done with this operation. % \begin{macrocode} -\let_new:NN \clist_top:NN \clist_get:NN -\let_new:NN \clist_top:cN \clist_get:cN +\cs_new_eq:NN \clist_top:NN \clist_get:NN +\cs_new_eq:NN \clist_top:cN \clist_get:cN % \end{macrocode} % \end{macro} % \end{macro} % -% -% Show token usage: % \begin{macrocode} %</initex|package> +% \end{macrocode} +% +% Show token usage: +% \begin{macrocode} %<*showmemory> %\showMemUsage %</showmemory> % \end{macrocode} % +% \end{implementation} +% \PrintIndex % % -% \endinput -% -% $Log$ -% Revision 1.16 2006/07/30 15:45:46 morten -% Made \clist_map_inline:Nn and variants nestable plus a little cleanup. -% -% Revision 1.15 2006/03/20 18:26:34 braams -% Updated the copyright notice (2006) and demoted all implementation -% sections to subsections and so on to clean up the toc for source3.tex -% -% Revision 1.14 2006/01/04 01:32:09 morten -% Minor changes to code to reflect changes in l3tlp. -% -% Revision 1.13 2005/12/27 09:52:51 morten -% Minor changes plus changed RCS information retrieval -% -% Revision 1.12 2005/10/27 23:14:49 morten -% Improved loops. -% -% Revision 1.11 2005/04/12 16:45:22 morten -% Enabled put operations. Added function that removes duplicate entries (mostly for -% use after concatenating to clists) -% -% Revision 1.10 2005/04/12 13:22:13 morten -% Mostly cosmetic changes. \clist_gconcat:NNN reprogrammed using "proper" methods, \clist_put_right:Nn likewise. -% -% Revision 1.9 2005/03/22 23:26:54 morten -% Fix error message -% -% Revision 1.8 2005/03/16 22:36:43 braams -% Added the tweaks necessary to be able to load with initex -% -% Revision 1.7 2005/03/11 21:36:36 braams -% Fixed the use of RCS information; -% Fixed a few documentation typos; added \StopEventually -% Replaced \ifx by \if_meaning:NN, \c_if_empty_toks became \c_empty_toks -% but needs further work according to Morten % +% \endinput diff --git a/Master/texmf-dist/source/latex/expl3/l3doc.dtx b/Master/texmf-dist/source/latex/expl3/l3doc.dtx new file mode 100644 index 00000000000..d9674ee724e --- /dev/null +++ b/Master/texmf-dist/source/latex/expl3/l3doc.dtx @@ -0,0 +1,1674 @@ +% \iffalse +%% File: l3doc.dtx Copyright (C) 1990-2009 LaTeX3 project +%% +%% It may be distributed and/or modified under the conditions of the +%% LaTeX Project Public License (LPPL), either version 1.3c of this +%% license or (at your option) any later version. The latest version +%% of this license is in the file +%% +%% http://www.latex-project.org/lppl.txt +%% +%% This file is part of the ``expl3 bundle'' (The Work in LPPL) +%% and all files in that bundle must be distributed together. +%% +%% The released version of this bundle is available from CTAN. +%% +%% ----------------------------------------------------------------------- +%% +%% The development version of the bundle can be found at +%% +%% http://www.latex-project.org/svnroot/experimental/trunk/ +%% +%% for those people who are interested. +%% +%%%%%%%%%%% +%% NOTE: %% +%%%%%%%%%%% +%% +%% Snapshots taken from the repository represent work in progress and may +%% not work or may contain conflicting material! We therefore ask +%% people _not_ to put them into distributions, archives, etc. without +%% prior consultation with the LaTeX Project Team. +%% +%% ----------------------------------------------------------------------- +%<*driver> +\def\nameofplainTeX{plain} +\ifx\fmtname\nameofplainTeX\else + \expandafter\begingroup +\fi +\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 +\generate{\file{l3doc.cls}{\from{l3doc.dtx}{class}}} +\generate{\file{l3doc.ist}{\from{l3doc.dtx}{docist}}} +\ifx\fmtname\nameofplainTeX + \expandafter\endbatchfile +\else + \expandafter\endgroup +\fi +%</driver> +% +%<*driver|class> +\RequirePackage{l3names} +%</driver|class> +% +% Need to protect the file metadata for any modules that load l3doc. +% This is restored after "\ProvideExplClass" below. +% \begin{macrocode} +%<class>\let \filenameOld \filename +%<class>\let \filenameextOld \filenameext +%<class>\let \filedateOld \filedate +%<class>\let \fileversionOld \fileversion +%<class>\let \filedescriptionOld \filedescription +% \end{macrocode} +% +%<*driver|class> +\GetIdInfo$Id: l3doc.dtx 1398 2009-06-08 15:53:26Z joseph $ + {L3 Experimental documentation class} +%</driver|class> +% +%<*driver> +\ProvidesFile{\filename.\filenameext} + [\filedate\space v\fileversion\space\filedescription] +\documentclass{l3doc} +\begin{document} +\DocInput{l3doc.dtx} +\end{document} +%</driver> +% +% This isn't included in the typeset documentation because it's a bit ugly: +%<*class> +\ProvidesExplClass + {\filename}{\filedate}{\fileversion}{\filedescription} +\RequirePackage{expl3} +\let \filename \filenameOld +\let \filenameext \filenameextOld +\let \filedate \filedateOld +\let \fileversion \fileversionOld +\let \filedescription \filedescriptionOld +%</class> +% \fi +% +% \title{The \pkg{l3doc} class\thanks{This file +% has version number \fileversion, last +% revised \filedate.}} +% \author{\Team} +% \date{\filedate} +% \maketitle +% \tableofcontents +% +% \begin{documentation} +% +% \section{Introduction} +% +% This is an ad-hoc class for documenting the \pkg{expl3} bundle, +% a collection of modules or packages that make up \LaTeX3's programming +% environment. Eventually it will replace the "ltxdoc" class for \LaTeX3, +% but not before the good ideas in \pkg{hypdoc}, \cls{xdoc2}, \pkg{docmfp}, and +% \cls{gmdoc} are incorporated. +% +% \textbf{It is even less stable than the main \pkg{expl3} packages. Use at own risk!} +% +% It is written as a `self-contained' docstrip file: executing +% "latex l3doc.dtx" +% will generate the "l3doc.cls" file and typeset this +% documentation; execute "tex l3doc.dtx" to only generate the ".cls" file. +% +% \section{Features of other packages} +% +% This class builds on the \pkg{ltxdoc} class and the \pkg{doc} package, but +% in the time since they were originally written some +% improvements and replacements have appeared that we would like to use as +% inspiration. +% +% These packages or classes are \pkg{hypdoc}, \pkg{docmfp}, \pkg{gmdoc}, +% and \pkg{xdoc}. I have summarised them below in order to work out what +% sort of features we should aim at a minimum for \pkg{l3doc}. +% +% \subsection{The \pkg{hypdoc} package} +% +% This package provides hyperlink support for the \pkg{doc} package. I have +% included it in this list to remind me that cross-referencing between +% documentation and implementation of methods is not very good. (E.g., it +% would be nice to be able to automatically hyperlink the documentation for +% a function from its implementation and vice-versa.) +% +% \subsection{The \pkg{docmfp} package} +% +% \begin{itemize} +% \item Provides "\DescribeRoutine" and the "routine" environment (etc.) +% for MetaFont and MetaPost code. +% \item Provides "\DescribeVariable" and the "variable" environment (etc.) +% for more general code. +% \item Provides "\Describe" and the "Code" environment (etc.) as a +% generalisation of the above two instantiations. +% \item Small tweaks to the DocStrip system to aid non-\LaTeX\ use. +% \end{itemize} +% +% \subsection{The \pkg{xdoc2} package} +% +% \begin{itemize} +% \item Two-sided printing. +% \item "\NewMacroEnvironment", "\NewDescribeEnvironment"; similar idea +% to \pkg{docmfp} but more comprehensive. +% \item Tons of small improvements. +% \end{itemize} +% +% \subsection{The \pkg{gmdoc} package} +% +% Radical re-implementation of \pkg{doc} as a package or class. +% \begin{itemize} +% \item Requires no "\begin{macrocode}" blocks! +% \item Automatically inserts "\begin{macro}" blocks! +% \item And a whole bunch of other little things. +% \end{itemize} +% +% \section{Problems \& Todo} +% +% Problems at the moment: (1)~not flexible in the types of things that can be documented; (2)~very nonstandard markup (using `"|"' as a delimiter and the odd `"/ (...)"' tags; (3)~no obvious link to the "\begin{macro}" function that's used analogously in the implementation. +% +% The environments "function" and "macro" should probably +% be renamed to something like \env{funcdoc} and \env{funcimpl}, +% respectively. +% +% Furthermore, we need another `layer' of documentation commands to +% account for `user-macro' as opposed to `code-functions'; the \pkg{expl3} +% functions should be documented differently, probably, to the \pkg{xparse} +% user macros (at least in terms of indexing). +% +% In no particular order, a list of things to do: +% \begin{itemize} +% \item Rename \env{function}/\env{macro} environments to better describe +% their use. +% \item Generalise \env{function}/\env{macro} for documenting `other things', +% such as environment names, package options, even keyval options. +% \item Use \pkg{xparse}. +% \item New function like "\part" but for files (remove awkward `File' as "\partname"). +% \item Something better to replace "\StopEventually"; I'm thinking two +% environments \env{documentation} and \env{implementation} that can +% conditionally typeset/ignore their material. +% \item Hyperlink documentation and implementation of macros (also see +% the \textsc{dtx} file of \pkg{svn-multi} v2). +% \end{itemize} +% +% \section{Bugs} +% +% \begin{itemize} +% \item Spaces are ignored entirely within \env{function} and \env{macro} +% arguments. This is just waiting for a convenient space-trimming +% macro in \pkg{expl3}. +% \end{itemize} +% +% \section{Documentation} +% +% \subsection{Partitioning documentation and implementation} +% +% \pkg{doc} uses the "\OnlyDocumentation"/"\AlsoImplementation" macros +% to guide the use of "\StopEventually{}", which is intended to be placed +% to partition the documentation and implementation within a single DTX file. +% +% This isn't very flexible, since it assumes that we \emph{always} want +% to print the documentation. For the \pkg{expl3} sources, I wanted to be +% be able to input DTX files in two modes: only displaying the documentation, +% and only displaying the implementation. For example: +% +% \begin{verbatim} +% \DisableImplementation +% \DocInput{l3basics,l3prg,...} +% \EnableImplementation +% \DisableDocumentation +% \DocInputAgain +% \end{verbatim} +% +% The idea being that the entire \pkg{expl3} bundle can be documented, +% with the implementation included at the back. Now, this isn't perfect, +% but it's a start. +% +% Use "\begin{documentation}...\end{documentation}" around the documentation, +% and "\begin{implementation}...\end{implementation}" around the implementation. +% The "\EnableDocumentation"/"\EnableImplementation" will cause them to be typeset +% when the DTX file is "\DocInput"; use "\DisableDocumentation"/"\DisableImplementation" +% to omit the contents of those environments. +% +% Note that \cmd\DocInput\ now takes comma-separated arguments, and \cmd\DocInputAgain\ +% can be used to re-input all DTX files previously input in this way. +% +% \subsection{Describing functions in the documentation} +% +% \DescribeEnv{function} +% \DescribeEnv{syntax} +% Two heavily-used environments are defined to describe the syntax +% of \textsf{expl3} functions and variables. +% \begin{verbatim} +% \begin{function}{ list_of | functions } +% \begin{syntax} +% "\foo_bar:" \Arg{meta} <test1> +% \end{syntax} +% <description> +% \end{function} +% \end{verbatim} +% +% \begin{function}{ list_of | functions } +% \begin{syntax} +% "\foo_bar:" \Arg{meta} <test1> +% \end{syntax} +% <description> +% \end{function} +% +% Note that the list of functions use "|" as a separator. +% +% \bigskip +% \textbf{MAJOR PROPOSED CHANGE}\qquad +% I think we should probably discourage this sort of free-form markup in +% \LaTeX3 and change this to a plain ol' comma-separated list instead. +% +% Alternatively, we could provide programmatic means of looping through +% lists with arbitary separators and promote this kind of thing. +% +% \subsection{Describing functions in the implementation} +% +% \DescribeEnv{macro} +% The well-used environment from \LaTeXe\ for marking up the implementation +% of macros/functions remains the \env{macro} environment. +% One major change in \pkg{l3doc}: it now accepts comma-separated lists +% of functions, to avoid a very large number of consecutive "\end{macro}" +% statements. +% \begin{verbatim} +% % \begin{macro}{\foo:N,\foo:c} +% % \begin{macrocode} +% ... code for \foo:N and \foo:c ... +% % \end{macrocode} +% % \end{macro} +% \end{verbatim} +% +% \DescribeEnv{arguments} +% Within a \env{macro} environment, you may use the \env{arguments} environment +% to describe the arguments taken by the function(s). It behaves exactly +% like a list environment. +% \begin{verbatim} +% % \begin{macro}{\foo:nn,\foo:VV} +% % \begin{arguments} +% % \item Name of froozle to be frazzled +% % \item Name of muble to be jubled +% % \end{arguments} +% % \begin{macrocode} +% ... code for \foo:nn and \foo:VV ... +% % \end{macrocode} +% % \end{macro} +% \end{verbatim} +% +% \bigskip +% \textbf{OPTIONS FOR THE FUTURE}\qquad Any improvements to the markup +% for the \env{function} environment would be good to mirror in \env{macro}. +% +% Perhaps this would be a better syntax for describing arguments? +% \begin{verbatim} +% \begin{macro}{\foo:nn,foo:VV} +% \dArg{Name of froozle to be frazzled} +% \dArg{Name of mumble to be jumbled} +% ... +% \end{verbatim} +% I.e., get rid of the environment and do things like in, say, \pkg{fontspec}. +% +% \subsection{Keeping things consistent} +% +% Whenever a function is either documented or defined with \env{function} +% and \env{macro} respectively, its name is stored in a sequence for later +% processing. +% +% At the end of the document (i.e., after the \textsc{dtx} file has finished +% processing), the list of names is analysed to check whether all defined +% functions have been documented and vice versa. The results are printed +% in the console output. +% +% If you need to do more serious work with these lists of names, take a +% look at the implementation for the data structures and methods used to +% store and access them directly. +% +% \subsection{Documenting templates} +% +% The following macros are provided for documenting templates; might +% end up being something completely different but who knows. +% \begin{quote}\parskip=0pt\obeylines +% "\begin{TemplateInterfaceDescription}" \Arg{template type name} +% " \TemplateArgument{none}{---}" +% \textsc{or one or more of these:} +% " \TemplateArgument" \Arg{arg no} \Arg{meaning} +% \textsc{and} +% "\TemplateSemantics" +% " " \meta{text describing the template type semantics} +% "\end{TemplateInterfaceDescription}" +% \end{quote} +% +% \begin{quote}\parskip=0pt\obeylines +% "\begin{TemplateDescription}" \Arg{template type name} \Arg{name} +% \textsc{one or more of these:} +% " \TemplateKey" \marg{key name} \marg{type of key} +% " "\marg{textual description of meaning} +% " "\marg{default value if any} +% \textsc{and} +% "\TemplateSemantics" +% " " \meta{text describing special additional semantics of the template} +% "\end{TemplateDescription}" +% \end{quote} +% +% \begin{quote}\parskip=0pt\obeylines +% "\begin{InstanceDescription}" \oarg{text to specify key column width (optional)} +% \hfill\marg{template type name}\marg{instance name}\marg{template name} +% \textsc{one or more of these:} +% " \InstanceKey" \marg{key name} \marg{value} +% \textsc{and} +% "\InstanceSemantics" +% " " \meta{text describing the result of this instance} +% "\end{InstanceDescription}" +% \end{quote} +% +% \end{documentation} +% +% \begin{implementation} +% +% \section{\pkg{l3doc} implementation} +% +% \begin{macrocode} +%<*class> +% \end{macrocode} +% +% The Guilty Parties. +% \begin{macrocode} +\cs_new_nopar:Npn\Team{% + The~\LaTeX3~Project\thanks{% + Frank~Mittelbach,~Denys~Duchier,~Chris~Rowley,~ + Rainer~Sch\"opf,~Johannes~Braams,~Michael~Downes,~ + David~Carlisle,~Alan~Jeffrey,~Morten~H\o{}gholm,~Thomas~Lotze,~ + Javier~Bezos,~Will~Robertson,~Joseph~Wright}} +% \end{macrocode} +% +% \subsection{Options} +% +% \begin{macrocode} +\DeclareOption{a5paper}{\@latexerr{Option not supported}{}} +% \end{macrocode} +% +% \begin{macrocode} +\bool_new:N \g_doc_full_bool +\bool_set_false:N \g_doc_full_bool +\DeclareOption{full}{ \bool_set_true:N \g_doc_full_bool } +\DeclareOption{onlydoc}{ \bool_set_false:N \g_doc_full_bool } +% \end{macrocode} +% +% \begin{macrocode} +\bool_new:N \g_doc_checkfunc_bool +\bool_set_true:N \g_doc_checkfunc_bool +\DeclareOption{check}{ \bool_set_true:N \g_doc_checkfunc_bool } +\DeclareOption{nocheck}{ \bool_set_false:N \g_doc_checkfunc_bool } +% \end{macrocode} +% +% \begin{macrocode} +\DeclareOption*{\PassOptionsToClass{\CurrentOption}{article}} +\ExecuteOptions{full} +\ProcessOptions +% \end{macrocode} +% +% +% \subsection{Class and package loading} +% +% \begin{macrocode} +\LoadClass[a4paper]{article} +\RequirePackage{doc} +\RequirePackage{array,alphalph,color,fixltx2e,enumitem,trace,underscore} +% \end{macrocode} +% +% \begin{macrocode} +\RequirePackage[T1]{fontenc} +\RequirePackage{lmodern,textcomp} +\RequirePackage{hypdoc} +% \end{macrocode} +% Just want the "comment" environment from \pkg{verbatim}: +% \begin{macrocode} +\let\doc@verbatim\verbatim +\let\enddoc@verbatim\endverbatim +\let\doc@@verbatim\@verbatim +\usepackage{verbatim} +\AtBeginDocument{% + \let\verbatim\doc@verbatim + \let\endverbatim\enddoc@verbatim + \let\@verbatim\doc@@verbatim +} +% \end{macrocode} +% +% \subsection{Configuration} +% +% \begin{macro}{\MakePrivateLetters} +% \begin{macrocode} +\cs_set_nopar:Npn \MakePrivateLetters { + \char_make_letter:N \@ + \char_make_letter:N \_ + \char_make_letter:N \: +} +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +\setcounter{StandardModuleDepth}{1} +\@addtoreset{CodelineNo}{part} +\cs_set_nopar:Npn \theCodelineNo { + \textcolor[gray]{0.5}{ \sffamily\tiny\arabic{CodelineNo} } +} +% \end{macrocode} +% +% +% +% \subsection{Design} +% +% Increase the text width slightly so that width the standard fonts +% 72 columns of code may appear in a |macrocode| environment. +% Increase the marginpar width slightly, for long command names. +% And increase the left margin by a similar amount. +% \begin{macrocode} +\setlength \textwidth { 385pt } +\addtolength \marginparwidth { 30pt } +\addtolength \oddsidemargin { 20pt } +\addtolength \evensidemargin { 20pt } +% \end{macrocode} +% (These were introduced when "article" was the documentclass, but +% I've left them here for now to remind me to do something about them +% later; we still have the problem of \emph{very long} command names.) +% +% Customise lists: +% \begin{macrocode} +\cs_set_eq:NN \@@oldlist\list +\cs_set_nopar:Npn \list#1#2{\@@oldlist{#1}{#2\listparindent\z@}} +\setlength \parindent { 0pt } +\setlength \itemindent { 0pt } +\setlength \parskip { \medskipamount } +% \end{macrocode} +% +% \subsection{Text markup} +% +% Make "|" and |"| be `short verb' characters, but not in +% the document preamble, where an active character may interfere +% with packages that are loaded. +% \begin{macrocode} +\AtBeginDocument { + \MakeShortVerb \" + \MakeShortVerb \| +} +% \end{macrocode} +% +% \begin{macrocode} +\providecommand*\eTeX{ + \if b\expandafter\@car\f@series\@nil\boldmath\fi + $\m@th\varepsilon$-\TeX +} +% \end{macrocode} +% +% \begin{macro}{\cmd,\cs} +% |\cmd{\foo}| Prints |\foo| verbatim. It may be used inside moving +% arguments. |\cs{foo}| also prints |\foo|, for those who prefer that +% syntax. +% \begin{macrocode} +\cs_set_nopar:Npn \cmd #1 { \cs{\expandafter\cmd@to@cs\string#1} } +\cs_set_nopar:Npn \cmd@to@cs #1#2 { \char\number`#2\relax } +\DeclareRobustCommand \cs [1] { \texttt { \char`\\ #1 } } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\marg,\oarg,\parg} +% |\marg{text}| prints \marg{text}, `mandatory argument'.\\ +% |\oarg{text}| prints \oarg{text}, `optional argument'.\\ +% |\parg{te,xt}| prints \parg{te,xt}, `picture mode argument'. +% \begin{macrocode} +\providecommand\marg[1]{ \texttt{\char`\{} \meta{#1} \texttt{\char`\}} } +\providecommand\oarg[1]{ \texttt[ \meta{#1} \texttt] } +\providecommand\parg[1]{ \texttt( \meta{#1} \texttt) } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\m,\file,\env,\pkg,\cls} +% This list may change\dots this is just my preference for markup. +% \begin{macrocode} +\cs_set_eq:NN \m \meta +\cs_set_eq:NN \file \nolinkurl +\DeclareRobustCommand \env {\texttt} +\DeclareRobustCommand \pkg {\textsf} +\DeclareRobustCommand \cls {\textsf} +% \end{macrocode} +% \end{macro} +% +% \begin{environment}{texnote} +% \begin{macrocode} +\newenvironment{texnote}{ + \endgraf + \vspace{3mm} + \small\textbf{\TeX~hackers~note:} +}{ + \vspace{3mm} +} +% \end{macrocode} +% \end{environment} +% +% \begin{macro}{\tn} +% \begin{macrocode} +\newcommand\tn[1]{ + \texttt{\bslash #1} + \index{TeX~and~LaTeX2e~commands\actualchar + \string\TeX{}~and~\string\LaTeXe{}~commands:\levelchar + #1\actualchar{\string\ttfamily\string\bslash{}#1}}} +% \end{macrocode} +% \end{macro} +% +% \begin{environment}{documentation} +% \begin{environment}{implementation} +% \begin{macro}{\EnableDocumentation,\EnableImplementation} +% \begin{macro}{\DisableDocumentation,\DisableImplementation} +% \begin{macrocode} +\newenvironment{documentation}{}{} +\newenvironment{implementation}{}{} +\newcommand\EnableDocumentation{% + \renewenvironment{documentation}{}{}% +} +\newcommand\EnableImplementation{% + \renewenvironment{implementation}{}{}% +} +\newcommand\DisableDocumentation{% + \cs_set_eq:NN \documentation \comment + \cs_set_eq:NN \enddocumentation \endcomment +} +\newcommand\DisableImplementation{% + \cs_set_eq:NN \implementation \comment + \cs_set_eq:NN \endimplementation \endcomment +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{environment} +% \end{environment} +% +% \begin{environment}{arguments} +% This environment is designed to be used within a \env{macro} environment +% to describe the arguments of the macro/function. +% \begin{macrocode} +\newenvironment{arguments}{ + \enumerate[ + nolistsep, + label=\texttt{\#\arabic*}~:, + labelsep=*, + ] +}{ + \endenumerate +} +% \end{macrocode} +% \end{environment} +% +% \begin{environment}{function} +% \begin{environment}{variable} +% Environment for documenting function(s). +% Stick the function names in a box. Use a "|" as delimiter and +% allow |<...>| to be used as markup for |\meta{...}|. +% Ignore spaces and sanitize with catcodes before reading argument. +% \begin{macrocode} +\group_begin: +\char_make_active:N \< +\cs_gnew_nopar:Npn \function { + \char_make_active:N \< + \cs_set_eq:NN < \doc_open_meta:n + \group_begin: + \MakePrivateLetters + \char_make_other:N \| + \char_make_other:N \^ + \char_make_other:N \\ + \char_make_space:N \~ + \char_make_ignore:N \ % space + \char_make_ignore:N \^^M + \char_make_ignore:N \^^I + \function_aux:n +} +\group_end: +% \end{macrocode} +% And the "variable" function is exactly the same for now: +% \begin{macrocode} +\cs_set_eq:NN \variable \function +% \end{macrocode} +% +% \begin{macro}{\function_aux:n} +% \begin{arguments} +% \item Vertical bar--separated list of functions with optional metadata; +% input has already been sanitised by catcode changes before reading +% the argument. +% \end{arguments} +% \begin{macrocode} +\cs_set_nopar:Npn \function_aux:n #1 { + \cs_set_nopar:Npn \nextnewline{\cs_gset_nopar:Npn\nextnewline{\\}} + \tl_gset_eq:NN \g_doc_macro_tl \c_empty_tl + \bigskip\endgraf\noindent\ttfamily + \tabular[b]{ | l @{} c | } + \hline + \doc_showmacro:w #1 | \q_stop \\ + \hline + \endtabular + \group_end: +} +% \end{macrocode} +% \end{macro} +% \end{environment} +% \end{environment} +% +% \begin{macro}{\doc_showmacro:w} +% This function reads in a "|"-separated list, passing each item to +% the auxiliary function "\doc_showmacro_aux:w". +% \begin{macrocode} +\cs_set_nopar:Npn \doc_showmacro:w #1 | { + \tl_if_blank:nTF {#1} { + \use_none:n + }{ + \doc_showmacro_aux:w #1 / \q_stop + \peek_meaning:NTF \q_stop { \use_none:n } { \doc_showmacro:w } + } +} +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +\bool_new:N \l_doc_meta_TF_bool +\bool_new:N \l_doc_meta_EXP_bool +% \end{macrocode} +% +% \begin{macro}{\doc_showmacro_aux:w} +% This macro is passed one of: +% \begin{quote} +% "\abc:cnx / (EXP) / \q_stop" \\ +% "\abc:cnx / \q_stop" \\ +% \end{quote} +% We also have some code here to print out every documented macro at the end +% of the document. +% \begin{arguments} +% \item Function/macro/variable name \item Metadata tags (if any) +% \end{arguments} +% \begin{macrocode} +\cs_new_nopar:Npn \doc_showmacro_aux:w #1 / #2 \q_stop { + + \tl_if_in:nnTF {#2} { (TF) } { + \bool_gset_true:N \l_doc_meta_TF_bool + }{ + \bool_gset_false:N \l_doc_meta_TF_bool + } + \tl_if_in:nnTF {#2} { (EXP) } { + \bool_gset_true:N \l_doc_meta_EXP_bool + }{ + \bool_gset_false:N \l_doc_meta_EXP_bool + } + + \bool_if:NTF \l_doc_meta_TF_bool { + \doc_special_main_index:o { #1 TF } + \seq_gput_right:Nx \g_doc_functions_seq { \tl_to_str:n { #1 TF } } + \seq_gput_right:Nx \g_doc_functions_seq { \tl_to_str:n { #1 T } } + \seq_gput_right:Nx \g_doc_functions_seq { \tl_to_str:n { #1 F } } + }{ + \doc_special_main_index:o { #1 } + \seq_gput_right:Nx \g_doc_functions_seq { \tl_to_str:n { #1 } } + } + + \doc_showmacro_aux_ii:w #1::\q_stop +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\doc_showmacro_aux_ii:w} +% This macro is passed one of: +% \begin{quote} +% "\showexplmacro "^^A +% \makebox[\widthof{\texttt{123456}}]{\meta{name}}^^A +% " ::\q_stop" \\ +% "\showexplmacro \foo ::\q_stop" \\ +% "\showexplmacro \foo: ::\q_stop" \\ +% "\showexplmacro \foo:Z ::\q_stop" \\ +% \end{quote} +% Notice that for "\foo", "#2" and "#3" are empty,\\ +% for "\foo:", "#2" is empty,\\ +% and for both "\foo:" and "\foo:Z", "#3" is `":"' . +% \begin{arguments} +% \item Function name \item Possible arg.\ spec. \item Possible colon +% \end{arguments} +% \begin{macrocode} +\cs_set_nopar:Npn \doc_showmacro_aux_ii:w #1:#2:#3 \q_stop { + \nextnewline + + \tl_if_eq:xxTF {#1} {\g_doc_macro_tl} { + \doc_typeset_aux:n + }{ + \tl_gset:Nn \g_doc_macro_tl {#1} + \use:n + } + { \g_doc_macro_tl } + #3 + #2 + \bool_if:NT \l_doc_meta_TF_bool { \doc_typeset_TF: } + & + \bool_if:NT \l_doc_meta_EXP_bool { + \hspace{\tabcolsep} + $\star$ + } +} +% \end{macrocode} +% \end{macro} +% +% \begin{environment}{syntax} +% Syntax block placed next to the list of functions to illustrate their use. +% \begin{macrocode} +\newenvironment{syntax}{% + \minipage[b]{.7\textwidth}% + \cs_set_nopar:Npn \meta@font@select{\rmfamily\itshape} % (Will: I HATE italic cmtt!) + \small\ttfamily\raggedright + \obeyspaces\obeylines +}{% + \endminipage + \hfil\break + \global\@ignoretrue +} +% \end{macrocode} +% \end{environment} +% +% Perhaps these belong in \file{l3token}? +% \begin{macrocode} +\tl_map_inline:nn {0123456789} { \cs_gset_eq:cN {char_other_#1} #1 } +% \end{macrocode} +% +% \begin{macro}{\doc_open_meta:n,\doc_close_meta:n} +% This code turns all numbers within "<...>" markup to be set as subscripts. +% You can use escaped numbers to get the real thing (e.g., "\1" = `1'). +% \begin{macrocode} +\group_begin: + \tl_map_inline:nn {0123456789} { \char_make_active:N #1 } + \cs_gnew:Npn \doc_open_meta:n { + \group_begin: + \tl_map_function:nN {0123456789} \doc_assign_num:n + \doc_close_meta:w + } + \cs_gnew:Npn \Arg { + \texttt{ \char`\{ } + \group_begin: + \tl_map_function:nN {0123456789} \doc_assign_num:n + \doc_close_Arg:n + } +\group_end: +\cs_new_nopar:Npn \doc_close_meta:w #1> { \meta {#1} \group_end: } +\cs_new_nopar:Npn \doc_close_Arg:n #1 { + \meta {#1} + \group_end: + \texttt{ \char`\} } +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\doc_assign_num:n} +% This function takes a numeral (`0'), defines its escaped self to be equal +% to itself ("\0" $\to$ `0'), makes it active, and turns itself into a subscript +% instead (`0' $\to$ `${}_0$'). +% \begin{macrocode} +\cs_new_nopar:Npn \doc_assign_num:n #1 { + \cs_set_eq:cc { \string #1 } { char_other_\string #1 } + \char_make_active:N #1 + \cs_set_nopar:Npn #1 { \unskip \, $ {} \sb { \use:c { char_other_\string #1 } } $ } +} +% \end{macrocode} +% \end{macro} +% +% \begin{environment}{macro} +% We want to extend the old definition to allow comma-separated lists of +% macros, rather than one at a time. keyval processing is very rudimentary; +% awaiting a more robust solution. +% \begin{macrocode} +\renewcommand \macro [1][] { + \bool_set_false:N \l_doc_macro_aux_bool + \bool_set_false:N \l_doc_macro_TF_bool + \cs_set_eq:NN \doc_macroname_prefix:n \use:n + \cs_set_eq:NN \doc_macroname_suffix: \c_empty_tl + + \cs_set_nopar:Npn \KV_key_no_value_elt:n ##1 { \use:c {doc_macro_opt_##1:} } + \KV_parse_space_removal_sanitize:n {#1} + + \group_begin: + \MakePrivateLetters + \char_make_letter:N \\ + \char_make_ignore:N \ % space + \char_make_ignore:N \^^M + \char_make_ignore:N \^^I + \doc_macro_aux:n +} +% \end{macrocode} +% After changing the catcodes, parse the arguments: +% \begin{macrocode} +\cs_new_nopar:Npn \doc_macro_aux:n #1 { + \group_end: + \clist_map_inline:nn {#1} { \doc_macro_single {##1} } +} +% \end{macrocode} +% +% \begin{macrocode} +\bool_new:N \l_doc_macro_aux_bool +\bool_new:N \l_doc_macro_TF_bool +\cs_set_nopar:Npn \doc_macro_opt_aux: { \bool_set_true:N \l_doc_macro_aux_bool } +\cs_set_nopar:Npn \doc_macro_opt_TF: { \bool_set_true:N \l_doc_macro_TF_bool } +% \end{macrocode} +% \end{environment} +% +% \begin{environment}{doc_macro_single} +% Let's start to mess around with "doc"'s "macro" environment. See \file{doc.dtx} +% for a full explanation of the original environment. It's +% rather \emph{enthusiastically} commented. +% \begin{arguments} +% \item Macro/function/whatever name; input has already been sanitised. +% \end{arguments} +% \begin{macrocode} +\cs_set_nopar:Npn \doc_macro_single #1 { + + \topsep\MacroTopsep + \trivlist + \cs_set_nopar:Npn \makelabel ##1 { \llap{##1} } + \if@inlabel + \cs_set_eq:NN \@tempa \@empty + \count@ \macro@cnt + \loop \ifnum\count@>\z@ + \cs_set_nopar:Npx \@tempa{\@tempa\hbox{\strut}} + \advance\count@\m@ne + \repeat + \cs_set_nopar:Npx \makelabel ##1 { + \llap{\vtop to\baselineskip {\@tempa\hbox{##1}\vss}} + } + \advance \macro@cnt \@ne + \else + \macro@cnt \@ne + \fi + + \bool_if:NT \l_doc_macro_aux_bool { + \cs_set_eq:NN \doc_macroname_prefix:n \doc_typeset_aux:n + } + \bool_if:NT \l_doc_macro_TF_bool { + \cs_set_eq:NN \doc_macroname_suffix: \doc_typeset_TF: + } + + \cs_set_nopar:Npx \@tempa { + \exp_not:N \item [ \exp_not:N \doc_print_macroname:n { + \tl_to_str:n {#1} + }] + } \@tempa + \global\advance \c@CodelineNo \@ne + + \bool_if:NF \l_doc_macro_aux_bool { + \bool_if:NTF \l_doc_macro_TF_bool { + \seq_gput_right:Nx \g_doc_macros_seq { \tl_to_str:n { #1 TF } } + \seq_gput_right:Nx \g_doc_macros_seq { \tl_to_str:n { #1 T } } + \seq_gput_right:Nx \g_doc_macros_seq { \tl_to_str:n { #1 F } } + }{ + \seq_gput_right:Nx \g_doc_macros_seq { \tl_to_str:n {#1} } + } + } + \bool_if:NTF \l_doc_macro_TF_bool { + \SpecialMainIndex{#1 TF}\nobreak + \DoNotIndex{#1 TF} + }{ + \SpecialMainIndex{#1}\nobreak + \DoNotIndex{#1} + } + + \global\advance \c@CodelineNo \m@ne + \ignorespaces +} +% \end{macrocode} +% +% \begin{macro}{\doc_print_macroname:n} +% \begin{macrocode} +\cs_set_nopar:Npn \doc_print_macroname:n #1 { + \strut \MacroFont + \doc_macroname_prefix:n {#1} \doc_macroname_suffix: \ % space! +} +% \end{macrocode} +% \end{macro} +% \end{environment} +% +% \begin{macro}{\doc_typeset_TF:,\doc_typeset_aux:n} +% Used by \cs{doc_macro_single} and \cs{doc_showmacro_aux_ii:w} to typeset +% conditionals and auxiliary functions. +% \begin{macrocode} +\cs_set_nopar:Npn \doc_typeset_TF: { + \color[gray]{0.5} + \underline { \color{black} \itshape TF \kern-0.1em } +} +\cs_set_nopar:Npn \doc_typeset_aux:n #1 { + {\color[gray]{0.5} #1} +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\DescribeOption} +% For describing package options. Due to Joseph Wright. +% Name/usage might change soon. +% \begin{macrocode} +\newcommand*{\DescribeOption}{ + \leavevmode + \@bsphack + \begingroup + \MakePrivateLetters + \Describe@Option +} +\newcommand*{\Describe@Option}[1]{ + \endgroup + \marginpar{ + \raggedleft + \PrintDescribeEnv{#1} + } + \SpecialOptionIndex{#1} + \@esphack + \ignorespaces +} +\newcommand*{\SpecialOptionIndex}[1]{ + \@bsphack + \begingroup + \HD@target + \let\HDorg@encapchar\encapchar + \edef\encapchar usage{ + \HDorg@encapchar hdclindex{\the\c@HD@hypercount}{usage} + } + \index{ + #1\actualchar{\protect\ttfamily#1} (option) + \encapchar usage + } + \index{ + options:\levelchar#1\actualchar{\protect\ttfamily#1} + \encapchar usage + } + \endgroup + \@esphack +} +% \end{macrocode} +% \end{macro} +% +% Here are some definitions for additional markup that will help to +% structure your documentation. +% +% \begin{environment}{danger} +% \begin{environment}{ddanger} +% \begin{syntax} +% |\begin{[d]danger}|\\ +% dangerous code\\ +% |\end{[d]danger}| +% \end{syntax} +% +% \begin{danger} +% Provides a danger bend, as known from the \TeX{}book. +% \end{danger} +% The actual character from the font |manfnt|: +% \begin{macrocode} +\font\manual=manfnt +\cs_set_nopar:Npn \dbend { {\manual\char127} } +% \end{macrocode} +% +% Defines the single danger bend. Use it whenever there is a feature in your +% package that might be tricky to use. +% FIXME: Has to be fixed when in combination with a macro-definition. +% \begin{macrocode} +\newenvironment {danger} { + \begin{trivlist}\item[]\noindent + \begingroup\hangindent=2pc\hangafter=-2 + \cs_set_nopar:Npn \par{\endgraf\endgroup} + \hbox to0pt{\hskip-\hangindent\dbend\hfill}\ignorespaces +}{ + \par\end{trivlist} +} +% \end{macrocode} +% +% \begin{ddanger} +% Use the double danger bend if there is something which could cause serious +% problems when used in a wrong way. Better the normal user does not know +% about such things. +% \end{ddanger} +% \begin{macrocode} +\newenvironment {ddanger} { + \begin{trivlist}\item[]\noindent + \begingroup\hangindent=3.5pc\hangafter=-2 + \cs_set_nopar:Npn \par{\endgraf\endgroup} + \hbox to0pt{\hskip-\hangindent\dbend\kern2pt\dbend\hfill}\ignorespaces +}{ + \par\end{trivlist} +} +% \end{macrocode} +% \end{environment} +% \end{environment} +% +% \subsection{Documenting templates} +% +% \begin{macrocode} +\newenvironment{TemplateInterfaceDescription}[1] + {\subsection{The template type `#1'}% + \begingroup + \@beginparpenalty\@M + \description + \def\TemplateArgument##1##2{\item[Arg: ##1]##2\par}% + \def\TemplateSemantics{\enddescription\endgroup + \subsubsection*{Semantics:}}% + } + {\par\bigskip} +% \end{macrocode} +% +% \begin{macrocode} +\newenvironment{TemplateDescription}[2] + {\subsection{The template `#2' (type #1)}% + \subsubsection*{Attributes:}% + \begingroup + \@beginparpenalty\@M + \description + \def\TemplateKey##1##2##3##4{\item[##1 (##2)]##3% + \ifx\TemplateKey##4\TemplateKey\else +% \hskip0ptplus3em\penalty-500\hskip 0pt plus 1filll Default:~##4% + \hfill\penalty500\hbox{}\hfill Default:~##4% + \nobreak\hskip-\parfillskip\hskip0pt\relax + \fi + \par}% + \def\TemplateSemantics{\enddescription\endgroup + \subsubsection*{Semantics \& Comments:}}% + } + {\par\bigskip} +% \end{macrocode} +% +% \begin{macrocode} +\newenvironment{InstanceDescription}[4][xxxxxxxxxxxxxxx] + {\subsubsection{The instance `#3' (template #2/#4)}% + \subsubsection*{Attribute values:}% + \begingroup + \@beginparpenalty\@M + \def\InstanceKey##1##2{\>\textbf{##1}\>##2\\}% + \def\InstanceSemantics{\endtabbing\endgroup + \vskip-30pt\vskip0pt + \subsubsection*{Layout description \& Comments:}}% + \tabbing + xxxx\=#1\=\kill + } + {\par\bigskip} +% \end{macrocode} +% +% \subsection{Inheriting doc} +% +% Code here is taken from \pkg{doc}, stripped of comments and translated +% into \pkg{expl3} syntax. New features are added in various places. +% +% \begin{macro}{\StopEventually,\Finale,\AlsoImplementation,\OnlyDescription} +% \begin{macrocode} +\bool_new:N \g_doc_implementation_bool +\cs_set_nopar:Npn \AlsoImplementation { + \bool_set_true:N \g_doc_implementation_bool + \cs_set:Npn \StopEventually ##1 { + \@bsphack + \cs_gset_nopar:Npn \Finale { ##1 \check@checksum } + \init@checksum + \@esphack + } +} +\AlsoImplementation +\cs_set_nopar:Npn \OnlyDescription { + \@bsphack + \bool_set_false:N \g_doc_implementation_bool + \cs_set:Npn \StopEventually ##1 { ##1 \endinput } + \@esphack +} +\cs_set_eq:NN \Finale \relax +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +\cs_set_nopar:Npn \partname{File} +% \end{macrocode} +% +% \begin{macro}{\DocInput} +% From \pkg{doc}. Now accepts comma-list input (who has commas in filenames?). +% \begin{macrocode} +\clist_new:N \g_docinput_clist +\cs_set:Npn \DocInput #1 { + \clist_map_inline:nn {#1} { + \clist_put_right:Nn \g_docinput_clist {##1} + \MakePercentIgnore + \input{##1} + \MakePercentComment + } +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\DocInputAgain} +% Uses "\g_docinput_clist" to re-input whatever's already been "\DocInput"-ed until now. +% May be used multiple times. +% \begin{macrocode} +\cs_set:Npn \DocInputAgain { + \clist_map_inline:Nn \g_docinput_clist { + \MakePercentIgnore + \input{##1} + \MakePercentComment + } +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\DocInclude} +% More or less exactly the same as |\include|, but uses |\DocInput| +% on a |dtx| file, not |\input| on a |tex| file. +% \begin{macrocode} +\cs_set_nopar:Npn \partname{File} +% \end{macrocode} +% +% \begin{macrocode} +\newcommand*{\DocInclude}[1]{% + \relax\clearpage + \docincludeaux + \IfFileExists{#1.fdd}{ + \cs_set_nopar:Npn \currentfile{#1.fdd} + }{ + \cs_set_nopar:Npn \currentfile{#1.dtx} + } + \ifnum\@auxout=\@partaux + \@latexerr{\string\include\space cannot~be~nested}\@eha + \else + \@docinclude #1 + \fi +} +% \end{macrocode} +% +% \begin{macrocode} +\cs_set_nopar:Npn \@docinclude #1 { + \clearpage + \immediate\write\@mainaux{\string\@input{#1.aux}} + \@tempswatrue + \if@partsw + \@tempswafalse + \cs_set_nopar:Npx \@tempb{#1} + \@for\@tempa:=\@partlist\do{ + \ifx\@tempa\@tempb\@tempswatrue\fi + } + \fi + \if@tempswa + \cs_set_eq:NN \@auxout\@partaux + \immediate\openout\@partaux #1.aux + \immediate\write\@partaux{\relax} + \cs_set_eq:NN \@ltxdoc@PrintIndex\PrintIndex + \cs_set_eq:NN \PrintIndex\relax + \cs_set_eq:NN \@ltxdoc@PrintChanges\PrintChanges + \cs_set_eq:NN \PrintChanges\relax + \cs_set_eq:NN \@ltxdoc@theglossary\theglossary + \cs_set_eq:NN \@ltxdoc@endtheglossary\endtheglossary + \part{\currentfile} + { + \cs_set_eq:NN \ttfamily\relax + \cs_gset_nopar:Npx \filekey{\filekey, \thepart={\ttfamily\currentfile}} + } + \DocInput{\currentfile} + \cs_set_eq:NN \PrintIndex\@ltxdoc@PrintIndex + \cs_set_eq:NN \PrintChanges\@ltxdoc@PrintChanges + \cs_set_eq:NN \theglossary\@ltxdoc@theglossary + \cs_set_eq:NN \endtheglossary\@ltxdoc@endtheglossary + \clearpage + \@writeckpt{#1} + \immediate\closeout\@partaux + \else + \@nameuse{cp@#1} + \fi + \cs_set_eq:NN \@auxout\@mainaux +} +% \end{macrocode} +% +% \begin{macrocode} +\cs_gset_nopar:Npn \codeline@wrindex #1 { + \immediate\write\@indexfile { + \string\indexentry{#1} + {\filesep\number\c@CodelineNo} + } +} +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +\cs_set_eq:NN \filesep \@empty +% \end{macrocode} +% +% \begin{macro}{\docincludeaux} +% \begin{macrocode} +\cs_set_nopar:Npn \docincludeaux { + \cs_set_nopar:Npn \thepart {\alphalph{part}} + \cs_set_nopar:Npn \filesep {\thepart-} + \cs_set_eq:NN \filekey\@gobble + \g@addto@macro\index@prologue{ + \cs_gset_nopar:Npn\@oddfoot{ + \parbox{\textwidth}{ + \strut\footnotesize + \raggedright{\bfseries File~Key:}~\filekey + } + } + \cs_set_eq:NN \@evenfoot\@oddfoot + } + \cs_gset_eq:NN \docincludeaux\relax + \cs_gset_nopar:Npn\@oddfoot{ + \expandafter\ifx\csname ver@\currentfile\endcsname\relax + File~\thepart :~{\ttfamily\currentfile}~ + \else + \GetFileInfo{\currentfile} + File~\thepart :~{\ttfamily\filename}~ + Date:~\filedate\ % space + Version~\fileversion + \fi + \hfill\thepage + } + \cs_set_eq:NN \@evenfoot \@oddfoot +} +% \end{macrocode} +% \end{macro} +% +% \subsection{At end document} +% +% Print all defined and documented macros/functions. +% +% \begin{macrocode} +\seq_new:N \g_doc_functions_seq +\seq_new:N \g_doc_macros_seq +% \end{macrocode} +% +% \begin{macrocode} +\iow_new:N \g_write_func_stream +\iow_open:Nn \g_write_func_stream { \jobname.cmds } +% \end{macrocode} +% +% \begin{macrocode} +\cs_new_nopar:Npn \doc_show_functions_defined: { + \bool_if:nT { \g_doc_implementation_bool && \g_doc_checkfunc_bool } { + \typeout{ ======================================== ^^J } + + \tl_clear:N \l_tmpa_tl + \seq_map_inline:Nn \g_doc_functions_seq { + \seq_if_in:NnT \g_doc_macros_seq {##1} { + \tl_put_right:Nn \l_tmpa_tl { ##1 ^^J } + \iow_now:Nn \g_write_func_stream { ##1 } + } + } + \iow_close:N \g_write_func_stream + \doc_functions_typeout:n { + Functions~both~documented~and~defined:^^J (In~order~of~being~documented) + } + + \seq_map_inline:Nn \g_doc_functions_seq { + \seq_if_in:NnF \g_doc_macros_seq {##1} { + \tl_put_right:Nn \l_tmpa_tl { ##1 ^^J } + } + } + \doc_functions_typeout:n { Functions~documented~but~not~defined: } + + \seq_map_inline:Nn \g_doc_macros_seq { + \seq_if_in:NnF \g_doc_functions_seq {##1} { + \tl_put_right:Nn \l_tmpa_tl { ##1 ^^J } + } + } + \doc_functions_typeout:n { Functions~defined~but~not~documented: } + + \typeout{ ======================================== } + } +} +\AtEndDocument{ \doc_show_functions_defined: } +% \end{macrocode} +% +% \begin{macrocode} +\cs_set_nopar:Npn \doc_functions_typeout:n #1 { + \tl_if_empty:NF \l_tmpa_tl { + \typeout{ + -------------------------------------- ^^J #1 ^^J + -------------------------------------- ^^J \l_tmpa_tl + } + \tl_clear:N \l_tmpa_tl + } +} +% \end{macrocode} +% +% \subsection{Indexing} +% +% Fix index (for now): +% \begin{macrocode} +\g@addto@macro\theindex{\MakePrivateLetters} +% \end{macrocode} +% +% \begin{macrocode} +\setcounter{IndexColumns}{2} +% \end{macrocode} +% +% Set up the Index to use "\part" +% \begin{macrocode} +\IndexPrologue{ + \part*{Index} + \markboth{Index}{Index} + \addcontentsline{toc}{part}{Index} + The~italic~numbers~denote~the~pages~where~the~ + corresponding~entry~is~described,~ + numbers~underlined~point~to~the~definition,~ + all~others~indicate~the~places~where~it~is~used. +} +% \end{macrocode} +% +% +% \begin{macro}{\doc_special_main_index:n,\doc_special_main_index:o,\hdpgindex} +% Heiko's replacement to play nicely with |hypdoc|: +% \begin{macrocode} +\cs_set_nopar:Npn \doc_special_main_index:n #1 { + \index{ + \@gobble#1 + \actualchar + \string\verb\quotechar*\verbatimchar#1\verbatimchar + \encapchar + hdpgindex{\thepage}{usage} + } +} +\cs_set_nopar:Npn \doc_special_main_index:o { \exp_args:No \doc_special_main_index:n } +% \end{macrocode} +% \begin{macrocode} +\cs_set_nopar:Npn \hdpgindex #1#2#3 { + \csname\ifx\\#2\\relax\else#2\fi\endcsname{ + \hyperlink{page.#1}{#3} + } +} +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +\g@addto@macro \PrintIndex { \AtEndDocument{ \typeout{^^J + ========================================^^J + Generate~the~index~by~executing^^J + \msg_four_spaces: makeindex~-s~l3doc.ist~-o~\jobname.ind~\jobname.idx^^J + ========================================^^J + }} +} +% \end{macrocode} +% +% \subsection{Change history} +% +% Set the change history to use "\part". +% Allow control names to be hyphenated in here... +% \begin{macrocode} +\GlossaryPrologue{ + \part*{Change~History} + {\GlossaryParms\ttfamily\hyphenchar\font=`\-} + \markboth{Change~History}{Change~History} + \addcontentsline{toc}{part}{Change~History} +} +% \end{macrocode} +% +% \begin{macrocode} +\g@addto@macro \PrintChanges { \AtEndDocument{ \typeout{^^J + ========================================^^J + Generate~the~change~list~by~executing^^J + \msg_four_spaces: makeindex~-s~gglo.ist~~-o~\jobname.gls~\jobname.glo^^J + ========================================^^J + }} +} +% \end{macrocode} +% +%^^A The standard \changes command modified slightly to better cope with +%^^A this multiple file document. +%^^A\def\changes@#1#2#3{% +%^^A \let\protect\@unexpandable@protect +%^^A \edef\@tempa{\noexpand\glossary{#2\space\currentfile\space#1\levelchar +%^^A \ifx\saved@macroname\@empty +%^^A \space +%^^A \actualchar +%^^A \generalname +%^^A \else +%^^A \expandafter\@gobble +%^^A \saved@macroname +%^^A \actualchar +%^^A \string\verb\quotechar*% +%^^A \verbatimchar\saved@macroname +%^^A \verbatimchar +%^^A \fi +%^^A :\levelchar #3}}% +%^^A \@tempa\endgroup\@esphack} +% +% \subsection{Patch file} +% +% Will: Do we still need this? +% +% \begin{macro}{\includeltpatch} +% This command will be used to input the patch file +% if that file exists. +% \begin{macrocode} +\cs_new_nopar:Npn \includeltpatch { + \cs_set_nopar:Npn \currentfile {l3patch.ltx} + \part{l3patch} + {\cs_set_eq:NN \ttfamily\relax + \cs_gset_nopar:Npx \filekey{\filekey, \thepart={\ttfamily\currentfile}}} + Things~we~did~wrong\ldots + \IndexInput{l3patch.ltx}} +% \end{macrocode} +% Get the date from ltvers.dtx +% \begin{macrocode} +\cs_set_nopar:Npn \patchdate{0} +\begingroup + %%\cs_set_nopar:Npn \ProvidesFile#1\fmtversion#2{\date{#2}\endinput} + \cs_set_nopar:Npn \ProvidesFile#1[#2#3]{\date{#2}\endinput} + \input{l3vers.dtx} + \cs_gset_nopar:Npx \@date{\@date} + \cs_gset_eq:NN \X@date \@date +% Add the patch version if available. + \cs_set:Npn \Xdef#1#2#3\def#4#5 { + \cs_gset_nopar:Npx \X@date{#2} + \cs_gset_nopar:Npx \patchdate{#5} + \endinput + } + \InputIfFileExists{l3patch.ltx}{ + \cs_set_eq:NN \cs_set_nopar:Npn \Xdef + }{ + \cs_gset_eq:NN \includeltpatch \relax + } +\endgroup +\ifx\@date\X@date + \cs_set_nopar:Npn \Xpatch{0} + \ifx\patchdate\Xpatch\else + \cs_set_nopar:Npx \@date {\@date\space Patch level \patchdate} + \fi +\else + \@warning{l3patch.ltx does not match l3vers.dtx!} + \cs_set_eq:NN \includeltpatch \relax +\fi +% \end{macrocode} +% \end{macro} +% +% \subsection{cfg} +% +% \begin{macrocode} +\bool_if:NTF \g_doc_full_bool { + \RecordChanges + \CodelineIndex + \EnableCrossrefs + \AlsoImplementation +}{ + \CodelineNumbered + \DisableCrossrefs + \OnlyDescription +} +% \end{macrocode} +% +% Input a local configuration file, if it exists. +% \begin{macrocode} +\InputIfFileExists{l3doc.cfg}{ + \typeout{*************************************^^J + *~Local~config~file~l3doc.cfg~used ^^J + *************************************} +}{} +% \end{macrocode} +% +% \begin{macrocode} +%</class> +% \end{macrocode} +% +% +% \subsection{Makeindex configuration} +% +% The makeindex style "l3doc.ist" is used in place of the usual +% "gind.ist" to ensure that I is used in the sequence I J K +% not I II II, which would be the default makeindex behaviour. +% +% Will: Do we need this? +% +% \begin{macrocode} +%<*docist> +actual '=' +quote '!' +level '>' +preamble +"\n \\begin{theindex} \n \\makeatletter\\scan@allowedfalse\n" +postamble +"\n\n \\end{theindex}\n" +item_x1 "\\efill \n \\subitem " +item_x2 "\\efill \n \\subsubitem " +delim_0 "\\pfill " +delim_1 "\\pfill " +delim_2 "\\pfill " +% The next lines will produce some warnings when +% running Makeindex as they try to cover two different +% versions of the program: +lethead_prefix "{\\bfseries\\hfil " +lethead_suffix "\\hfil}\\nopagebreak\n" +lethead_flag 1 +heading_prefix "{\\bfseries\\hfil " +heading_suffix "\\hfil}\\nopagebreak\n" +headings_flag 1 + +% and just for source3: +% Remove R so I is treated in sequence I J K not I II III +page_precedence "rnaA" +%</docist> +% \end{macrocode} +% +% \section{Testing} +%\ExplSyntaxOn +%\cs_set_eq:NN\g_saved_doc_functions_seq\g_doc_functions_seq +%\cs_set_eq:NN\g_saved_doc_macros_seq\g_doc_macros_seq +%\ExplSyntaxOff +% +% \begin{function}{\example_foo:N|\example_foo:c} +% \begin{syntax} +% "\example_foo:N" <arg1> +% \end{syntax} +% <0123456789> <\0\1\2\3\4\5\6\7\8\9> \Arg{arg1} ":(" +% \end{function} +% +% \begin{function}{ \foo | \foo: | \foo:x | \barrz: } +% \begin{syntax} +% "\example_foo:N" <arg1> +% \end{syntax} +% <0123456789> <\0\1\2\3\4\5\6\7\8\9> +% \end{function} +% +% \begin{function}{\foo:N / (TF) | \foo_if:c / (TF) (EXP)} +% Test. +% \end{function} +% +% \begin{function}{ \bar / (EXP) | \bar: / (EXP) | \bar:x / (EXP) | } +% \begin{syntax} +% "\example_foo:N" <arg1> +% \end{syntax} +% <0123456789> <\0\1\2\3\4\5\6\7\8\9> +% \end{function} +% +% \begin{macro}{ \foo , \foo: , \foo:x } +% Testing. +% \end{macro} +% +% \bigskip\bigskip +% +% \begin{macro}[aux]{ \foo_aux: } +% Testing. +% \end{macro} +% +% \bigskip\bigskip +% +% \begin{macro}[TF]{ \foo_if:c } +% Testing. +% \end{macro} +% +%\ExplSyntaxOn +%\cs_set_eq:NN\g_doc_functions_seq\g_saved_doc_functions_seq +%\cs_set_eq:NN\g_doc_macros_seq\g_saved_doc_macros_seq +%\ExplSyntaxOff +% +% \bigskip\bigskip +% +% \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_five} +% \begin{macro}{\c_six} +% \begin{macro}{\c_seven} +% \begin{macro}{\c_eight} +% \begin{macro}{\c_nine} +% \begin{macro}{\c_ten} +% \begin{macro}{\c_eleven} +% \begin{macro}{\c_sixteen} +% \begin{macro}{\c_thirty_two} +% \begin{macro}{\c_hundred_one} +% \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{arguments} +% \item name +% \item parameters +% \end{arguments} +% Another test. +% \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} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \subsection{Macros} +% \raggedright +% \ExplSyntaxOn +% \seq_map_inline:Nn \g_doc_macros_seq { `\texttt{#1}' \quad } +% \ExplSyntaxOff +% +% \subsection{Functions} +% \ExplSyntaxOn +% \seq_map_inline:Nn \g_doc_functions_seq { `\texttt{#1}' \quad } +% \ExplSyntaxOff +% +% \end{implementation} +% +% \PrintIndex +% +% \endinput diff --git a/Master/texmf-dist/source/latex/expl3/l3expan.dtx b/Master/texmf-dist/source/latex/expl3/l3expan.dtx index 1efadb1dab3..7f2323b2e0c 100644 --- a/Master/texmf-dist/source/latex/expl3/l3expan.dtx +++ b/Master/texmf-dist/source/latex/expl3/l3expan.dtx @@ -1,5 +1,5 @@ % \iffalse -%% File: l3expan.dtx Copyright (C) 1990-2006 LaTeX3 project +%% File: l3expan.dtx Copyright (C) 1990-2009 LaTeX3 project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this @@ -17,7 +17,7 @@ %% %% The development version of the bundle can be found at %% -%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/ +%% http://www.latex-project.org/svnroot/experimental/trunk/ %% %% for those people who are interested. %% @@ -36,7 +36,7 @@ \RequirePackage{l3names} %</driver|package> %\fi -\GetIdInfo$Id: l3expan.dtx 735 2008-01-14 22:31:02Z morten $ +\GetIdInfo$Id: l3expan.dtx 1376 2009-06-01 17:01:30Z morten $ {L3 Experimental Argument Expansion module} %\iffalse %<*driver> @@ -44,153 +44,37 @@ \ProvidesFile{\filename.\filenameext} [\filedate\space v\fileversion\space\filedescription] %\iffalse -\documentclass{l3doc} +\documentclass[full]{l3doc} \begin{document} -\DocInput{\filename.\filenameext} +\DocInput{l3expan.dtx} \end{document} %</driver> % \fi % % -% \title{The \textsf{l3expan} package\thanks{This file +% \title{The \pkg{l3expan} package\thanks{This file % has version number \fileversion, last % revised \filedate.}\\ -% Controlling Expansion of Command Arguments} +% Controlling Expansion of Function Arguments} % \author{\Team} % \date{\filedate} % \maketitle % +% \begin{documentation} % -% \section{\LaTeX3 functions} +% \section{Brief overview} % -% 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. +% The functions in this module all have prefix |exp|. % -% 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[f] Almost the same as the |x| type except here the token list -% is expanded fully until the first unexpandable token is found and -% the rest is left unchanged. Note that if this function finds a -% space at the beginning of the argument it will gobble it and not -% expand the next argument. -% -% \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} -% -% Here are three new expansion types that may be useful but I'm not -% sure yet. Only time will tell\dots{} Proper documentation of these -% functions is postponed until later. -% \begin{description} -% \item[d] This is pretty much like the |o| type except the token list -% get's expanded twice before being passed on. (|d| is for double.) -% It is often useful in conjunction with a forced expansion. -% -% \item[E] Sometimes you need to unpack a token list or something else -% but you don't want it to add the braces that the |o| type -% does. This is where you usually wind up with a lot of -% |\exp_after:NN|s and we would like to avoid that. This type works -% quite well with the other syntax but it won't work in certain -% circumstances: Since the generic expansion functions read their -% arguments when the expanded code is shuffled around, this type -% will have a problem if the last token you want to expand once is -% |\token_to_str:N| \emph{and} you're in an argument expansion -% process involving arguments in braces such as the |n| and |o| type -% arguments. If you stick to functions invloving only |N| and |E| -% everything will work just fine. (|E| is for expanded, single -% token.) -% -% \item[e] Same as above but the argument must be given in braces. -% \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 to be of general interest are -% implemented. +% Not all possible variations are implemented for every base +% function. Instead only those that are used within the \LaTeX3 kernel +% or otherwise seem to be 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} +% \section{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 @@ -202,11 +86,11 @@ % 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} +% \begin{verbatim} +% \exp_args:NNo\seq_gpush:Nn +% \g_file_name_stack +% \l_tmpa_tl +% \end{verbatim} % 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 @@ -215,85 +99,132 @@ % 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}" +% "\cs_new_nopar: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 +% "\cs_new_nopar: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 |f| type is so special that it deserves an example. -% Let's pretend we want to set "\aaa" equal to the control sequence -% stemming from turning "b \l_tmpa_tlp b" into a control -% sequence. Furthermore we want to store the execution of it in a -% \m{toks} register. In this example we assume "\l_tmpa_tlp" contains -% the text string "lur". The straight forward approach is -% \begin{quote} -% "\toks_set:No \l_tmpa_toks {\let:Nc \aaa {b \l_tmpa_tlp b}}" -% \end{quote} -% Unfortunately this only puts -% "\exp_args:NNc \let:NN \aaa {b \l_tmpa_tlp b}" into "\l_tmpa_toks" -% and not "\let:NwN \aaa = \blurb" as we probably wanted. Using -% "\toks_set:Nx" is not an option as that will die horribly. Instead -% we can do a -% \begin{quote} -% "\toks_set:Nf \l_tmpa_toks {\let:Nc \aaa {b \l_tmpa_tlp b}}" -% \end{quote} -% which puts the desired result in "\l_tmpa_toks". It requires -% "\toks_set:Nf" to be defined as -% \begin{quote} -% "\def:Npn \toks_set:Nf {\exp_args:NNf \toks_set:Nn}" -% \end{quote} -% If you use this type of expansion in conditional processing then -% you should stick to using "TF" type functions only as it does not -% try to finish any "\if... \fi:" itself! -% -% -% -% -% -% The available internal functions for argument expansion come in to +% The steps above may be automated by using the function +% "\cs_generate_variant:Nn", described next. +% +% \subsection{Methods for defining variants} +% +% \begin{function}{\cs_generate_variant:Nn} +% \begin{syntax} +% "\cs_generate_variant:Nn" <function> <variant argument> +% "\cs_generate_variant:Nn " "\foo:Nn" "{c}" +% "\cs_generate_variant:Nn" "\foo:Nn" "{c,Nx,cx}" +% \end{syntax} +% This function greatly simplify the task of defining +% variantions on a base function with differing expansion control. +% The first example is equivalent to writing +% \begin{verbatim} +% \cs_set_nopar:Npn \foo:cn { \exp_args:Nc \foo:Nn } +% \end{verbatim} +% If used with a comma-separated list of variants, it does so for each +% variant form, i.e., the second example is equivalent to +% \begin{verbatim} +% \cs_set_nopar:Npn \foo:cn { \exp_args:Nc \foo:Nn } +% \cs_set_nopar:Npn \foo:Nx { \exp_args:NNx \foo:Nn } +% \cs_set_nopar:Npn \foo:cx { \exp_args:Ncx \foo:Nn } +% \end{verbatim} +% \end{function} +% +% \paragraph{Internal functions} \mbox{} +% +% \begin{function}{\cs_generate_internal_variant:n} +% \begin{syntax} +% "\cs_generate_internal_variant:n" \Arg{args} +% \end{syntax} +% Defines the appropriate "\exp_args:N"<args> function, if necessary, +% to perform the expansion control specified by <args>. +% \end{function} +% +% \section{Introducing the variants} +% +% The available internal functions for argument expansion come in two % 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. +% 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. +% 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", "o" or "f" in the last position) whenever possible. +% "c", "N", "o" or "f" in the last position) whenever possible. % \end{itemize} % +% The |V| type returns the value of a register, which can be one of +% |tl|, |num|, |int|, |skip|, |dim|, |toks|, or built-in \TeX\ +% registers. The |v| type is the same except it first creates a +% control sequence out of its argument before returning the +% value. This recent addition to the argument specifiers may shake +% things up a bit as most places where |o| is used will be replaced by +% |V|. The documentation you are currently reading will therefore +% require a fair bit of re-writing. +% +% In general, the programmer should not need to be concerned with +% expansion control. When simply using the content of a variable, +% functions with a "V" specifier should be used. For those referred to by +% (cs)name, the "v" specifier is available for the same purpose. Only when +% specific expansion steps are needed, such as when using delimited +% arguments, should the lower-level functions with "o" specifiers be employed. +% +% The |f| type is so special that it deserves an example. +% Let's pretend we want to set "\aaa" equal to the control sequence +% stemming from turning "b \l_tmpa_tl b" into a control +% sequence. Furthermore we want to store the execution of it in a +% \m{toks} register. In this example we assume "\l_tmpa_tl" contains +% the text string "lur". The straight forward approach is +% \begin{quote} +% "\toks_set:No \l_tmpa_toks {\cs_set_eq:Nc \aaa {b \l_tmpa_tl b}}" +% \end{quote} +% Unfortunately this only puts +% "\exp_args:NNc \cs_set_eq:NN \aaa {b \l_tmpa_tl b}" into "\l_tmpa_toks" +% and not "\cs_set_eq:NwN \aaa = \blurb" as we probably wanted. Using +% "\toks_set:Nx" is not an option as that will die horribly. Instead +% we can do a +% \begin{quote} +% "\toks_set:Nf \l_tmpa_toks {\cs_set_eq:Nc \aaa {b \l_tmpa_tl b}}" +% \end{quote} +% which puts the desired result in "\l_tmpa_toks". It requires +% "\toks_set:Nf" to be defined as +% \begin{quote} +% "\cs_set_nopar:Npn \toks_set:Nf {\exp_args:NNf \toks_set:Nn}" +% \end{quote} +% If you use this type of expansion in conditional processing then +% you should stick to using "TF" type functions only as it does not +% try to finish any "\if... \fi:" itself! +% % % When pdf\TeX\ 1.50 arrives, it will contain a primitive for % performing the equivalent of an "x" expansion after only one % expansion and most importantly: as an expandable operation. -% \begin{function}{% -% \exp_arg:x -% } +% \begin{function}{\exp_arg:x} % \begin{syntax} -% " \exp_arg:x" "{" <arg> "}" +% "\exp_arg:x" \Arg{arg} % \end{syntax} % <arg> is expanded fully using an "x" expansion. % \end{function} % % -% \subsection{Manipulating the first argument} % -% \begin{function}{% -% \exp_args:No -% } +% \section{Manipulating the first argument} +% +% \begin{function}{ \exp_args:No / (EXP) } % \begin{syntax} % " \exp_args:No" <funct> <arg1> <arg2> "..." % \end{syntax} @@ -302,9 +233,16 @@ % more than one argument---all others are passed unchanged. % \end{function} % -% \begin{function}{% -% \exp_args:Nc -% } +% \begin{function}{ \exp_args:Nd / (EXP) } +% \begin{syntax} +% " \exp_args:Nd" <funct> <arg1> <arg2> "..." +% \end{syntax} +% The first argument of <funct> (i.e., <arg1>) is expanded twice, 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 / (EXP) | \exp_args:cc / (EXP) } % \begin{syntax} % " \exp_args:Nc" <funct> <arg1> <arg2> "..." % \end{syntax} @@ -313,25 +251,32 @@ % 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. +% +% In the ":cc" variant, the <funct> control sequence itself is constructed +% (with the same process as described above) before <arg1> is turned into a +% control sequence and passed as its argument. % \end{function} % -% \begin{function}{% -% \exp_args:NC -% } +% \begin{function}{ \exp_args:NV / (EXP) } % \begin{syntax} -% " \exp_args:Nc" <funct> <arg1> <arg2> "..." +% " \exp_args:NV" <funct> <register> % \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. +% The first argument of <funct> (i.e., <register>) is expanded to its +% value. By value we mean a number stored in an |int| or |num| +% register, the length value of a |dim|, |skip| or |muskip| register, the +% contents of a |toks| register or the unexpanded contents of a |tl var.| +% register. The value is passed onto <funct> in braces. % \end{function} % -% \begin{function}{% -% \exp_args:Nx -% } +% \begin{function}{ \exp_args:Nv / (EXP) } +% \begin{syntax} +% " \exp_args:Nv" <funct> \Arg{register} +% \end{syntax} +% Like the |V| type except the register is given by a list of +% characters from which a control sequence name is generated. +% \end{function} +% +% \begin{function}{ \exp_args:Nx } % \begin{syntax} % " \exp_args:Nx" <funct> <arg1> <arg2> "..." % \end{syntax} @@ -342,9 +287,7 @@ % As mentioned before, this type of function is relatively slow. % \end{function} % -% \begin{function}{% -% \exp_args:Nf -% } +% \begin{function}{ \exp_args:Nf / (EXP) } % \begin{syntax} % " \exp_args:Nf" <funct> <arg1> <arg2> "..." % \end{syntax} @@ -355,8 +298,7 @@ % Beware of its special behavior as explained above. % \end{function} % -% -% \subsection{Manipulating two arguments} +% \section{Manipulating two arguments} % % \begin{function}{% % \exp_args:NNx | @@ -374,16 +316,22 @@ % \end{function} % % \begin{function}{% -% \exp_args:NNo | -% \exp_args:NNf | -% \exp_args:Nno | -% \exp_args:NNc | -% \exp_args:Noo | -% \exp_args:NOo | -% \exp_args:NOc | -% \exp_args:Nco | -% \exp_args:Ncc | -% \exp_args:NNC | +% \exp_args:NNo / (EXP) | +% \exp_args:NNc / (EXP) | +% \exp_args:NNv / (EXP) | +% \exp_args:NNV / (EXP) | +% \exp_args:NNd / (EXP) | +% \exp_args:NNf / (EXP) | +% \exp_args:Nno / (EXP) | +% \exp_args:Nnf / (EXP) | +% \exp_args:Noo / (EXP) | +% \exp_args:Noc / (EXP) | +% \exp_args:Nco / (EXP) | +% \exp_args:Ncf / (EXP) | +% \exp_args:Ncc / (EXP) | +% \exp_args:Nff / (EXP) | +% \exp_args:Nfo / (EXP) | +% \exp_args:NVV / (EXP) | % } % \begin{syntax} % "\exp_args:NNo" <funct> <arg1> <arg2> "..." @@ -391,17 +339,20 @@ % These are the fast and expandable functions for the first two arguments. % \end{function} % -% \subsection{Manipulating three arguments} +% \section{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:NNnx | +% \exp_args:NNox | % \exp_args:Nnnx | -% \exp_args:Noox | % \exp_args:Nnox | +% \exp_args:Noox | % \exp_args:Ncnx | +% \exp_args:Nccx | % } % \begin{syntax} % "\exp_args:Nnnx" <funct> <arg1> <arg2> <arg3> "..." @@ -410,44 +361,32 @@ % \end{function} % % \begin{function}{% -% \exp_args:NnnN | -% \exp_args:Nnno | -% \exp_args:NNOo | -% \exp_args:NOOo | -% \exp_args:Nccc | -% \exp_args:NcNc | -% \exp_args:Nnnc | -% \exp_args:NcNo | -% \exp_args:Ncco | +% \exp_args:NNNo / (EXP) | +% \exp_args:NNoo / (EXP) | +% \exp_args:NNno / (EXP) | +% \exp_args:Nnno / (EXP) | +% \exp_args:Nnnc / (EXP) | +% \exp_args:Nooo / (EXP) | +% \exp_args:Nccc / (EXP) | +% \exp_args:NcNc / (EXP) | +% \exp_args:NcNo / (EXP) | +% \exp_args:Ncco / (EXP) | % } % \begin{syntax} -% "\exp_args:NNOo" <funct> <arg1> <arg2> <arg3> "..." +% "\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} +% \section{Preventing expansion} % % \begin{function}{\exp_not:N | % \exp_not:c | % \exp_not:n } % \begin{syntax} % "\exp_not:N" <token> -% "\exp_not:n" "{" <token list> "}" +% "\exp_not:n" \Arg{token list} % \end{syntax} % This function will prohibit the expansion of <token> in situation % where <token> would otherwise be replaced by it definition, e.g., @@ -458,45 +397,40 @@ % \end{texnote} % \end{function} % -% % \begin{function}{\exp_not:o | % \exp_not:d | -% \exp_not:f} +% \exp_not:f } % \begin{syntax} -% "\exp_not:o" "{"<token list>"}" +% "\exp_not:o" \Arg{token list} % \end{syntax} % Same as "\exp_not:n" except <token list> is expanded once for the % "o" type and twice for the "d" type and the result of this expansion -% is then prohibited from being expanded further. +% is then prohibited from being expanded further. % \end{function} -% -% \begin{function}{\exp_not:E} +% +% \begin{function}{\exp_not:V | +% \exp_not:v } % \begin{syntax} -% "\exp_not:E" <token> +% "\exp_not:V" <register> +% "\exp_not:v" \Arg{token list} % \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. -% \begin{texnote} -% This command has no equivalent. -% \end{texnote} +% The value of <register> is retrieved and then passed on to +% "\exp_not:n" which will prohibit further expansion. The |v| type +% first creates a control sequence from <token list> but is otherwise +% identical to |V|. % \end{function} -% % -% \begin{function}{\exp_stop_f: } +% \begin{function}{\exp_stop_f:} % \begin{syntax} % <f expansion> ... "\exp_stop_f:" % \end{syntax} % This function stops an "f" type expansion. An example use is one such as % \begin{verbatim} -% \tlp_set:Nf \l_tmpa_tlp { +% \tl_set:Nf \l_tmpa_tl { % \if_case:w \l_tmpa_int -% \or: \use_arg_i_after_orelse:nw{\exp_stop_f: \textbullet} -% \or: \use_arg_i_after_orelse:nw{\exp_stop_f: \textendash} -% \else: \use_arg_i_after_orelse:nw{\exp_stop_f: else-item} +% \or: \use_i_after_orelse:nw {\exp_stop_f: \textbullet} +% \or: \use_i_after_orelse:nw {\exp_stop_f: \textendash} +% \else: \use_i_after_fi:nw {\exp_stop_f: else-item} % \fi: % } % \end{verbatim} @@ -508,46 +442,122 @@ % writing code. % \end{texnote} % \end{function} +% +% \section{Unbraced expansion} +% +% \begin{function}{ +% \exp_last_unbraced:Nf| +% \exp_last_unbraced:NV| +% \exp_last_unbraced:Nv| +% \exp_last_unbraced:NcV| +% \exp_last_unbraced:NNo| +% \exp_last_unbraced:NNV| +% \exp_last_unbraced:NNNo| +% } +% \begin{syntax} +% "\exp_last_unbraced:NV" <token> <variable name> +% \end{syntax} +% There are a small number of occasions where the last argument +% in an expansion run must be expanded unbraced. These functions +% should only be used inside functions, \emph{not} for creating +% variants. +% \end{function} +% +% \end{documentation} +% +% \begin{implementation} % +% \section{\pkg{l3expan} implementation} % -% \begin{variable}{\l_exp_tlp | } +% \subsection{Internal functions and variables} +% +% \begin{function}{\exp_after:wN} +% \begin{syntax} +% "\exp_after:wN" <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{variable}{\l_exp_tl} % \begin{syntax}\end{syntax} % 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{} +% \begin{function}{ \exp_eval_register:N / (EXP) | +% \exp_eval_register:c / (EXP) } +% \begin{syntax} +% "\exp_eval_register:N" <register> +% \end{syntax} +% These functions evaluates a register as part of a "V" or "v" expansion +% (respectively). A register might exist as +% one of two things: A parameter-less non-long, non-protected macro +% or a built-in \TeX\ register such as |\count|. +% \end{function} +% +% \begin{function}{\::n|\::N|\::c|\::o|\::f|\::x|\::v|\::V|\::d|\:::} +% \begin{syntax} +% "\cs_set_nopar:Npn \exp_args:Ncof {\::c\::o\::f\:::}" +% \end{syntax} +% Internal forms for the base expansion types. +% \end{function} % -% \subsection {The Implementation} +% \subsection{Module code} % % We start by ensuring that the required packages are loaded. % \begin{macrocode} -%<package>\ProvidesExplPackage -%<package> {\filename}{\filedate}{\fileversion}{\filedescription} -%<package>\RequirePackage{l3tlp} +%<*package> +\ProvidesExplPackage + {\filename}{\filedate}{\fileversion}{\filedescription} +\package_check_loaded_expl: +%</package> %<*initex|package> % \end{macrocode} % -% \subsubsection{General expansion} +% \begin{macro}{\exp_after:wN} +% \begin{macro}{\exp_not:N} +% \begin{macro}{\exp_not:n} +% These are defined in \pkg{l3basics}. +% \begin{macrocode} +%<*bootstrap> +\cs_set_eq:NwN \exp_after:wN \tex_expandafter:D +\cs_set_eq:NwN \exp_not:N \tex_noexpand:D +\cs_set_eq:NwN \exp_not:n \etex_unexpanded:D +%</bootstrap> +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \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 +% to use one of the \LaTeX3\ names for |\cs_set_nopar:Npx| at some point, and % so is never going to be expandable.\footnote{However, some % primitives have certain characteristics that means that their % arguments undergo an \texttt{x} type expansion but the primitive % is in fact still expandable. We shall make it very clear when such % a function is expandable.}) % -% In a later section some common cases are coded by a more direct -% method, typically using calls to |\exp_after:NN|. +% The definition of expansion functions with this technique happens +% in section~\ref{sec:gendef}. +% In section~\ref{sec:handtune} some common cases are coded by a more direct +% method for efficiency, typically using calls to |\exp_after:wN|. % -% \begin{macro}{\l_exp_tlp} -% We need a scratch token list pointer. +% \begin{macro}{\l_exp_tl} +% We need a scratch token list variable. +% We don't use "tl" methods so that \pkg{l3expan} can be loaded earlier. % \begin{macrocode} -\tlp_new:Nn\l_exp_tlp{} +\cs_new_nopar:Npn \l_exp_tl {} % \end{macrocode} % \end{macro} % @@ -555,20 +565,47 @@ % to perform the expansions. All macros are |long| as this turned out % to be desirable since the tokens undergoing expansion may be % arbitrary user input. -% \begin{macro}{\exp_arg_next:nnn} -% This is basically the same function as |\Dexp_arg_next:nnn|. +% +% An argument manipulator |\::|\meta{Z} always has signature |#1\:::#2#3| +% where |#1| holds the remaining argument manipulations to be performed, +% |\:::| serves as an end marker for the list of manipulations, |#2| +% is the carried over result of the previous expansion steps and |#3| is +% the argument about to be processed. +% +% \begin{macro}[aux]{\exp_arg_next:nnn} +% \begin{macro}[aux]{\exp_arg_next_nobrace:nnn} +% |#1| is the result of an expansion step, |#2| is the remaining +% argument manipulations and |#3| is the current result of the +% expansion chain. This auxilliary function moves |#1| back after +% |#3| in the input stream and checks if any expansion is left to +% be done by calling |#2|. In by far the most cases we will require +% to add a set of braces to the result of an argument manipulation +% so it is more effective to do it directly here. Actually, so far +% only the |c| of the final argument manipulation variants does not +% require a set of braces. % \begin{macrocode} -\def_long_new:Npn\exp_arg_next:nnn#1#2#3{ +\cs_new:Npn\exp_arg_next:nnn#1#2#3{ + #2\:::{#3{#1}} +} +\cs_new:Npn\exp_arg_next_nobrace:nnn#1#2#3{ #2\:::{#3#1} } % \end{macrocode} % \end{macro} +% \end{macro} +% +% \begin{macro}{\:::} +% The end marker is just another name for the identity function. +% \begin{macrocode} +\cs_new:Npn\:::#1{#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_long_new:Npn\::n#1\:::#2#3{ +\cs_new:Npn\::n#1\:::#2#3{ #1\:::{#2{#3}} } % \end{macrocode} @@ -577,9 +614,8 @@ % \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_long_new:Npn\::N#1\:::#2#3{ +\cs_new:Npn\::N#1\:::#2#3{ #1\:::{#2#3} } % \end{macrocode} @@ -589,8 +625,8 @@ % This function is used to skip an argument that is turned into % as control sequence without expansion. % \begin{macrocode} -\def_long_new:Npn\::c#1\:::#2#3{ - \exp_after:NN\exp_arg_next:nnn\cs:w #3\cs_end:{#1}{#2} +\cs_new:Npn\::c#1\:::#2#3{ + \exp_after:wN\exp_arg_next_nobrace:nnn\cs:w #3\cs_end:{#1}{#2} } % \end{macrocode} % \end{macro} @@ -598,8 +634,8 @@ % \begin{macro}{\::o} % This function is used to expand an argument once. % \begin{macrocode} -\def_long_new:Npn\::o#1\:::#2#3{ - \exp_after:NN\exp_arg_next:nnn\exp_after:NN{\exp_after:NN{#3}}{#1}{#2} +\cs_new:Npn\::o#1\:::#2#3{ + \exp_after:wN\exp_arg_next:nnn\exp_after:wN{#3}{#1}{#2} } % \end{macrocode} % \end{macro} @@ -608,7 +644,7 @@ % \begin{macro}{\::f} % \begin{macro}{\exp_stop_f:} % This function is used to expand a token list until the first -% unexpandable token is found. The underlying "\int_to_roman:w -`0" +% unexpandable token is found. The underlying "\tex_romannumeral:D -`0" % expands everything in its way to find something terminating the % number and thereby expands the function in front of it. This % scanning procedure is terminated once the expansion hits @@ -616,459 +652,541 @@ % to mark such an end of expansion marker; in case the scanner hits % a number, this number also terminates the scanning and is left % untouched. In the example shown earlier the scanning was stopped -% once \TeX{} had fully expanded "\let:Nc \aaa {b \l_tmpa_tlp b}" -% into "\let:NwN \aaa = \blurb" which then turned out to contain -% the non-expandable token "\let:NwN". Since the expansion of -% "\int_to_roman:w -`0" is \m{null}, we wind up with a fully +% once \TeX{} had fully expanded "\cs_set_eq:Nc \aaa {b \l_tmpa_tl b}" +% into "\cs_set_eq:NwN \aaa = \blurb" which then turned out to contain +% the non-expandable token "\cs_set_eq:NwN". Since the expansion of +% "\tex_romannumeral:D -`0" is \m{null}, we wind up with a fully % expanded list, only \TeX{} has not tried to execute any of the % non-expandable tokens. This is what differentiates this function % from the "x" argument type. % \begin{macrocode} -\def_long_new:Npn\::f#1\:::#2#3{ - \exp_after:NN\exp_arg_next:nnn - \exp_after:NN{\exp_after:NN{\int_to_roman:w -`0 #3}} +\cs_new:Npn\::f#1\:::#2#3{ + \exp_after:wN\exp_arg_next:nnn + \exp_after:wN{\tex_romannumeral:D -`0 #3} {#1}{#2} } -\def_new:Npn \exp_stop_f: {~} +\cs_new_nopar:Npn \exp_stop_f: {~} % \end{macrocode} % \end{macro} % \end{macro} % -% \begin{macro}{\::x} +% \begin{macro}{\::x,\exp_arg:x} % This function is used to expand an argument fully. If the % pdf\TeX\ primitive "\expanded" is present, we use it. % \begin{macrocode} -\let_new:NN \exp_arg:x \expanded % Move eventually. +\cs_new_eq:NN \exp_arg:x \expanded % Move eventually. \cs_if_free:NTF\exp_arg:x{ - \def_long_new:Npn\::x#1\:::#2#3{ - % \tlp_set:Nx\l_exp_tlp{{{#3}}} - \def:Npx \l_exp_tlp{{{#3}}} - \exp_after:NN\exp_arg_next:nnn\l_exp_tlp{#1}{#2}} + \cs_new:Npn\::x#1\:::#2#3{ + \cs_set_nopar:Npx \l_exp_tl{{#3}} + \exp_after:wN\exp_arg_next:nnn\l_exp_tl{#1}{#2}} } { - \def_long_new:Npn\::x#1\:::#2#3{ - \exp_after:NN\exp_arg_next:nnn - \exp_after:NN{\exp_arg:x{{#3}}}{#1}{#2} + \cs_new:Npn\::x#1\:::#2#3{ + \exp_after:wN\exp_arg_next:nnn + \exp_after:wN{\exp_arg:x{{#3}}}{#1}{#2} } } % \end{macrocode} % \end{macro} % -% \begin{macro}{\:::} -% Just another name for the identity function. +% +% \begin{macro}{\::v} +% \begin{macro}{\::V} +% These functions return the value of a register, i.e., one of +% |tl|, |num|, |int|, |skip|, |dim| and |muskip|. The |V| version +% expects a single token whereas |v| like |c| creates a csname from +% its argument given in braces and then evaluates it as if it was a +% |V|. The sequence |\tex_romannumeral:D -`0| sets off an |f| type +% expansion. The argument is returned in braces. % \begin{macrocode} -\def_long_new:Npn\:::#1{#1} +\cs_new:Npn \::V#1\:::#2#3{ + \exp_after:wN\exp_arg_next:nnn + \exp_after:wN{ + \tex_romannumeral:D -`0 + \exp_eval_register:N #3 + } + {#1}{#2} +} +\cs_new:Npn \::v#1\:::#2#3{ + \exp_after:wN\exp_arg_next:nnn + \exp_after:wN{ + \tex_romannumeral:D -`0 + \exp_eval_register:c {#3} + } + {#1}{#2} +} % \end{macrocode} % \end{macro} +% \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{macro}{\exp_eval_register:N,\exp_eval_register:c} +% \begin{macro}{\exp_eval_error_msg:w} +% This function evaluates a register. Now a register might exist as +% one of two things: A parameter-less macro or a built-in \TeX\ +% register such as |\count|. For the \TeX\ registers we have to +% utilize a |\tex_the:D| whereas for the macros we merely have to +% expand them once. The trick is to find out when to use +% |\tex_the:D| and when not to. What we do here is try to find out +% whether the token will expand to something else when hit with +% |\exp_after:wN|. The technique is to compare the meaning of the +% register in question when it has been prefixed with |\exp_not:N| +% and the register itself. If it is a macro, the prefixed +% |\exp_not:N| will temporarily turn it into the primitive +% |\tex_relax:D|. % \begin{macrocode} -\def_long_new:Npn\::C#1\:::#2#3{ - \exp_after:NN\exp_C_aux:nnn\cs:w #3\cs_end:{#1}{#2}} +\cs_set_nopar:Npn \exp_eval_register:N #1{ + \exp_after:wN \if_meaning:w \exp_not:N #1#1 % \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|. +% If the token was not a macro it may be a malformed variable from a +% |c| expansion in which case it is equal to the primitive +% |\tex_relax:D|. In that case we throw an error. We could let \TeX\ +% do it for us but that would result in the rather obscure +% \begin{quote} +% |! You can't use `\relax' after \the.| +% \end{quote} +% which while quite true doesn't give many hints as to what actually +% went wrong. We provide something more sensible. +% \begin{macrocode} + \if_meaning:w \tex_relax:D #1 + \exp_eval_error_msg:w + \fi: +% \end{macrocode} +% The next bit requires some explanation. The function must be +% initiated by the sequence |\tex_romannumeral:D -`0| and we want to +% terminate this expansion chain by inserting an |\exp_stop_f:| +% token. However, we have to expand the register |#1| before we do +% that. If it is a \TeX\ register, we need to execute the sequence +% |\exp_after:wN\exp_stop_f:\tex_the:D #1| and if it is a macro we +% need to execute |\exp_after:wN\exp_stop_f: #1|. We therefore issue +% the longer of the two sequences and if the register is a macro, we +% remove the |\tex_the:D|. % \begin{macrocode} -\def_long_new:Npn\exp_C_aux:nnn #1{ - \exp_after:NN - \exp_arg_next:nnn - \exp_after:NN - { - \exp_after:NN - {#1} - } + \else: + \exp_after:wN \use_i_ii:nnn + \fi: + \exp_after:wN \exp_stop_f: \tex_the:D #1 +} +\cs_set_nopar:Npn \exp_eval_register:c #1{ + \exp_after:wN\exp_eval_register:N\cs:w #1\cs_end: } % \end{macrocode} -% \end{macro} +% Clean up nicely, then call the undefined control sequence. The +% result is an error message looking like this: +% \begin{verbatim} +% ! Undefined control sequence. +% \exp_eval_error_msg:w ...erroneous variable used! +% +% l.55 \tl_set:Nv \l_tmpa_tl {undefined_tl} +% \end{verbatim} +% \begin{macrocode} +\group_begin:% +\tex_catcode:D`\!=11\tex_relax:D% +\tex_catcode:D`\ =11\tex_relax:D% +\cs_gset:Npn\exp_eval_error_msg:w#1\tex_the:D#2{% +\fi:\fi:\erroneous variable used!}% +\group_end:% +% \end{macrocode} +% \end{macro} +% \end{macro} +% % % Here are some that might not stay but let's see. -% \begin{macro}{\::E} -% This function is used to expand an argument once and return it -% \emph{without} braces. Use this only when you feel pretty -% comfortable about your input! Actually this is pretty much just -% generic wrapper for |\exp_after:NN|. +% +% \begin{macro}{\::d} +% This function is used to expand an argument twice. Mostly useful +% for |toks| type things. This is likely to vanish with |V| around. % \begin{macrocode} -\def_long_new:Npn\::E#1\:::#2#3{ - \exp_after:NN\exp_arg_next:nnn \exp_after:NN{#3}{#1}{#2} +\cs_new:Npn\::d#1\:::#2#3{ + \exp_after:wN\exp_after:wN\exp_after:wN\exp_arg_next:nnn + \exp_after:wN\exp_after:wN\exp_after:wN{#3}{#1}{#2} } % \end{macrocode} % \end{macro} % -% \begin{macro}{\::e} -% Same as |\::E| really but conceptually they are different. +% \subsection{Hand-tuned definitions} +% \label{sec:handtune} +% +% 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 +% `general' concept above is slower 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:NNo} +% \begin{macro}{\exp_args:NNNo} % \begin{macrocode} -\def_long_new:Npn\::e#1\:::#2#3{ - \exp_after:NN\exp_arg_next:nnn \exp_after:NN{#3}{#1}{#2} -} +\cs_new:Npn \exp_args:No #1#2{\exp_after:wN#1\exp_after:wN{#2}} +\cs_new:Npn \exp_args:NNo #1#2#3{\exp_after:wN#1\exp_after:wN#2 + \exp_after:wN{#3}} +\cs_new:Npn \exp_args:NNNo #1#2#3#4{\exp_after:wN#1\exp_after:wN#2 + \exp_after:wN#3\exp_after:wN{#4}} % \end{macrocode} % \end{macro} +% \end{macro} +% \end{macro} % -% \begin{macro}{\::d} -% This function is used to expand an argument twice. Mostly useful -% for |toks| type things. +% +% \begin{macro}{\exp_args:Nc,\exp_args:cc,\exp_args:NNc,\exp_args:Ncc,\exp_args:Nccc} +% Here are the functions that turn their argument into csnames but +% are expandable. % \begin{macrocode} -\def_long_new:Npn\::d#1\:::#2#3{ - \exp_after:NN\exp_after:NN\exp_after:NN\exp_arg_next:nnn - \exp_after:NN\exp_after:NN\exp_after:NN{ - \exp_after:NN\exp_after:NN\exp_after:NN{#3}}{#1}{#2} -} +\cs_set:Npn \exp_args:Nc #1#2{\exp_after:wN#1\cs:w#2\cs_end:} +\cs_new:Npn \exp_args:cc #1#2{\cs:w #1\exp_after:wN\cs_end:\cs:w #2\cs_end:} +\cs_new:Npn \exp_args:NNc #1#2#3{\exp_after:wN#1\exp_after:wN#2 + \cs:w#3\cs_end:} +\cs_new:Npn \exp_args:Ncc #1#2#3{\exp_after:wN#1 + \cs:w#2\exp_after:wN\cs_end:\cs:w#3\cs_end:} +\cs_new:Npn \exp_args:Nccc #1#2#3#4{\exp_after:wN#1 + \cs:w#2\exp_after:wN\cs_end:\cs:w#3\exp_after:wN + \cs_end:\cs:w #4\cs_end:} % \end{macrocode} % \end{macro} % -% We do most of them by hand here. This also means that we get a name -% for |\exp_after:NN| that fits with the rest of the code. +% \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} -\let:NN \exp_args:NE \exp_after:NN -\def:Npn \exp_args:NNE #1{\exp_args:NE#1\exp_args:NE} -\def:Npn \exp_args:NNNE #1#2{\exp_args:NE#1\exp_args:NE#2\exp_args:NE} -\def:Npn \exp_args:NEE #1{\exp_args:NE\exp_args:NE\exp_args:NE#1\exp_args:NE} -\def:Npn \exp_args:NcE #1#2{\exp_after:NN #1\cs:w #2\exp_after:NN\cs_end:} -\def:Npn \exp_args:Nd {\::d\:::} -\def:Npn \exp_args:NNd {\::N\::d\:::} +\cs_new:Npn \exp_args:Nco #1#2#3{\exp_after:wN#1\cs:w#2\exp_after:wN + \cs_end:\exp_after:wN{#3}} % \end{macrocode} +% \end{macro} +% +% \subsection{Definitions with the `general' technique} +% \label{sec:gendef} +% +% \begin{macro}{\exp_args:Nd,\exp_args:Nf,\exp_args:NV,\exp_args:Nv,\exp_args:Nx} +% \begin{macrocode} +\cs_set_nopar:Npn \exp_args:Nd {\::d\:::} +\cs_set_nopar:Npn \exp_args:Nf {\::f\:::} +\cs_set_nopar:Npn \exp_args:Nv {\::v\:::} +\cs_set_nopar:Npn \exp_args:NV {\::V\:::} +\cs_set_nopar:Npn \exp_args:Nx {\::x\:::} +% \end{macrocode} +% \end{macro} % -% \begin{macro}{\exp_args:NC} -% \begin{macro}{\exp_args:Ncx} -% \begin{macro}{\exp_args:Ncco} -% \begin{macro}{\exp_args:Nccx} -% \begin{macro}{\exp_args:Ncnx} -% \begin{macro}{\exp_args:NcNc} -% \begin{macro}{\exp_args:Nf} -% \begin{macro}{\exp_args:NNf} -% \begin{macro}{\exp_args:Nfo} -% \begin{macro}{\exp_args:Nnf} -% \begin{macro}{\exp_args:NNno} -% \begin{macro}{\exp_args:NnnN} -% \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} -% \begin{macro}{\exp_args:NNC} -% \begin{macro}{\exp_args:Nnnc} -% \begin{macro}{\exp_args:NNnx} -% \begin{macro}{\exp_args:NNoo} -% \begin{macro}{\exp_args:NNox} +% \begin{macro}{\exp_args:NNV,\exp_args:NNv,\exp_args:NNd,\exp_args:NNf,\exp_args:NNx, +% \exp_args:NVV, +% \exp_args:Ncx, +% \exp_args:Nfo,\exp_args:Nff, +% \exp_args:Ncf,\exp_args:Nco, +% \exp_args:Nnf,\exp_args:Nno,\exp_args:Nnx, +% \exp_args:Noo,\exp_args:Noc,\exp_args:Nox, +% \exp_args:Nxo,\exp_args:Nxx} % Here are the actual function definitions, using the helper functions % above. % \begin{macrocode} -%\def:Npn \exp_args:NNNo {\::N\::N\::o\:::} -%\def:Npn \exp_args:NNOo {\::N\::O\::o\:::} -%\def:Npn \exp_args:NNc {\::N\::c\:::} -%\def:Npn \exp_args:NNo {\::N\::o\::\:::} -%\def:Npn \exp_args:NOOo {\::O\::O\::o\:::} -%\def:Npn \exp_args:NOc {\::O\::c\:::} -%\def:Npn \exp_args:NOo {\::O\::o\:::} -%\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:Nco {\::c\::o\:::} -%\def:Npn \exp_args:No {\::o\:::} +\cs_set_nopar:Npn \exp_args:NNd {\::N\::d\:::} +\cs_set_nopar:Npn \exp_args:NNf {\::N\::f\:::} +\cs_set_nopar:Npn \exp_args:NNv {\::N\::v\:::} +\cs_set_nopar:Npn \exp_args:NNV {\::N\::V\:::} +\cs_set_nopar:Npn \exp_args:NNx {\::N\::x\:::} + +\cs_set_nopar:Npn \exp_args:Ncx {\::c\::x\:::} +\cs_set_nopar:Npn \exp_args:Nfo {\::f\::o\:::} +\cs_set_nopar:Npn \exp_args:Nff {\::f\::f\:::} +\cs_set_nopar:Npn \exp_args:Ncf {\::c\::f\:::} +\cs_set_nopar:Npn \exp_args:Nnf {\::n\::f\:::} +\cs_set_nopar:Npn \exp_args:Nno {\::n\::o\:::} +\cs_set_nopar:Npn \exp_args:Nnx {\::n\::x\:::} + +\cs_set_nopar:Npn \exp_args:Noc {\::o\::c\:::} +\cs_set_nopar:Npn \exp_args:Noo {\::o\::o\:::} +\cs_set_nopar:Npn \exp_args:Nox {\::o\::x\:::} -\def:Npn \exp_args:NC {\::C\:::} -\def:Npn \exp_args:NNC {\::N\::C\:::} -\def:Npn \exp_args:NNf {\::N\::f\:::} -\def:Npn \exp_args:NNno {\::N\::n\::o\:::} -\def:Npn \exp_args:NNnx {\::N\::n\::x\:::} % new -\def:Npn \exp_args:NNoo {\::N\::o\::o\:::} % new -\def:Npn \exp_args:NNox {\::N\::o\::x\:::} % new -\def:Npn \exp_args:NNx {\::N\::x\:::} -\def:Npn \exp_args:NcNc {\::c\::N\::c\:::} -\def:Npn \exp_args:NcNo {\::c\::N\::o\:::} -\def:Npn \exp_args:Ncco {\::c\::c\::o\:::} -\def:Npn \exp_args:Ncco {\::c\::c\::o\:::} -\def:Npn \exp_args:Nccx {\::c\::c\::x\:::} -\def:Npn \exp_args:Ncnx {\::c\::n\::x\:::} -\def:Npn \exp_args:Ncx {\::c\::x\:::} -\def:Npn \exp_args:Nf {\::f\:::} -\def:Npn \exp_args:Nfo{\::f\::o\:::} -\def:Npn \exp_args:Nnf {\::n\::f\:::} -\def:Npn \exp_args:NnnN {\::n\::n\::N\:::} %% Strange one this one... -\def:Npn \exp_args:Nnnc {\::n\::n\::c\:::} -\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:Nnox {\::n\::o\::x\:::} -\def:Npn \exp_args:Nnx {\::n\::x\:::} -\def:Npn \exp_args:Noo {\::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\:::} +\cs_set_nopar:Npn \exp_args:NVV {\::V\::V\:::} + +\cs_set_nopar:Npn \exp_args:Nxo {\::x\::o\:::} +\cs_set_nopar: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} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} +% +% \begin{macro}{\exp_args:Ncco, +% \exp_args:Nccx, +% \exp_args:Ncnx, +% \exp_args:NcNc, +% \exp_args:NcNo, +% \exp_args:NNno, +% \exp_args:Nnno, +% \exp_args:Nnnx, +% \exp_args:Nnox, +% \exp_args:Nooo, +% \exp_args:Noox, +% \exp_args:Nnnc, +% \exp_args:NNnx, +% \exp_args:NNoo, +% \exp_args:NNox} +% \begin{macrocode} +\cs_set_nopar:Npn \exp_args:NNno {\::N\::n\::o\:::} +\cs_set_nopar:Npn \exp_args:NNnx {\::N\::n\::x\:::} +\cs_set_nopar:Npn \exp_args:NNoo {\::N\::o\::o\:::} +\cs_set_nopar:Npn \exp_args:NNox {\::N\::o\::x\:::} + +\cs_set_nopar:Npn \exp_args:Nnnc {\::n\::n\::c\:::} +\cs_set_nopar:Npn \exp_args:Nnno {\::n\::n\::o\:::} +\cs_set_nopar:Npn \exp_args:Nnnx {\::n\::n\::x\:::} +\cs_set_nopar:Npn \exp_args:Nnox {\::n\::o\::x\:::} + +\cs_set_nopar:Npn \exp_args:NcNc {\::c\::N\::c\:::} +\cs_set_nopar:Npn \exp_args:NcNo {\::c\::N\::o\:::} +\cs_set_nopar:Npn \exp_args:Ncco {\::c\::c\::o\:::} +\cs_set_nopar:Npn \exp_args:Ncco {\::c\::c\::o\:::} +\cs_set_nopar:Npn \exp_args:Nccx {\::c\::c\::x\:::} +\cs_set_nopar:Npn \exp_args:Ncnx {\::c\::n\::x\:::} + +\cs_set_nopar:Npn \exp_args:Noox {\::o\::o\::x\:::} +\cs_set_nopar:Npn \exp_args:Nooo {\::o\::o\::o\:::} +% \end{macrocode} % \end{macro} % % -% \subsubsection{Preventing expansion} +% \subsection{Preventing expansion} % % % \begin{macro}{\exp_not:o} % \begin{macro}{\exp_not:d} % \begin{macro}{\exp_not:f} +% \begin{macro}{\exp_not:v} +% \begin{macro}{\exp_not:V} % \begin{macrocode} -\def_long_new:Npn\exp_not:o#1{\exp_not:n\exp_after:NN{#1}} -\def_long_new:Npn\exp_not:d#1{ - \exp_not:n\exp_after:NN\exp_after:NN\exp_after:NN{#1} +\cs_new:Npn\exp_not:o#1{\exp_not:n\exp_after:wN{#1}} +\cs_new:Npn\exp_not:d#1{ + \exp_not:n\exp_after:wN\exp_after:wN\exp_after:wN{#1} +} +\cs_new:Npn\exp_not:f#1{ + \exp_not:n\exp_after:wN{\tex_romannumeral:D -`0 #1} +} +\cs_new:Npn\exp_not:v#1{ + \exp_not:n\exp_after:wN{\tex_romannumeral:D -`0 \exp_eval_register:c {#1}} } -\def_long_new:Npn\exp_not:f#1{ - \exp_not:n\exp_after:NN{\int_to_roman:w -`0 #1} +\cs_new:Npn\exp_not:V#1{ + \exp_not:n\exp_after:wN{\tex_romannumeral:D -`0 \exp_eval_register:N #1} } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} +% \end{macro} +% \end{macro} % -% \begin{macro}{\exp_not:E} % \begin{macro}{\exp_not:c} -% Two helper functions, which we can probably live without it. +% A helper function. % \begin{macrocode} -\def_new:Npn\exp_not:E{\exp_after:NN\exp_not:N} -\def_long_new:Npn\exp_not:c#1{\exp_after:NN\exp_not:N\cs:w#1\cs_end:} +\cs_new:Npn\exp_not:c#1{\exp_after:wN\exp_not:N\cs:w#1\cs_end:} % \end{macrocode} % \end{macro} -% \end{macro} -% -% -% \subsubsection{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: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. +% \subsection{Defining function variants} +% +% +% \begin{macro}{\cs_generate_variant:Nn} +% \begin{macro}[aux]{\cs_generate_variant_aux:nnNn} +% \begin{macro}[aux]{\cs_generate_variant_aux:nnw} +% \begin{macro}[aux]{\cs_generate_variant_aux:N} +% \begin{arguments} +% \item Base form of a function; e.g., "\tl_set:Nn" +% \item One or more variant argument specifiers; e.g., "{Nx,c,cx}" +% \end{arguments} +% Split up the original base function to grab its name and signature +% consisting of $k$ letters. Then we wish to iterate through the list +% of variant argument specifiers, and for each one construct a new +% function name using the original base name, the variant signature +% consisting of $l$ letters and the last $k-l$ letters of the base +% signature. For example, for a base function "\tl_set:Nn" which +% needs a "c" variant form, we want the new signature to be "cn". % \begin{macrocode} -\def_long_new:Npn \exp_args:No #1#2{\exp_after:NN#1\exp_after:NN{#2}} -\def_long_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_long_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_long_new:Npn \exp_args:NNo #1#2#3{\exp_after:NN#1\exp_after:NN#2 - \exp_after:NN{#3}} -\def_long_new:Npn \exp_args:NNO #1#2#3 {\exp_after:NN#1 - \exp_after:NN#2 #3} -\def_long_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_long_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}} +\cs_new:Npn \cs_generate_variant:Nn #1 { + \chk_if_exist_cs:N #1 + \cs_split_function:NN #1 \cs_generate_variant_aux:nnNn +} % \end{macrocode} -% \end{macro} -% \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. +% We discard the boolean and then set off a loop through the desired +% variant forms. % \begin{macrocode} -\def_long_new:Npn \exp_args:Nc #1#2{\exp_after:NN#1\cs:w#2\cs_end:} -\def_long_new:Npn \exp_args:NNc #1#2#3{\exp_after:NN#1\exp_after:NN#2 - \cs:w#3\cs_end:} -\def_long_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_long_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_long_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:} +\cs_set:Npn \cs_generate_variant_aux:nnNn #1#2#3#4{ + \cs_generate_variant_aux:nnw {#1}{#2} #4,?,\q_recursion_stop +} +% \end{macrocode} +% Next is the real work to be done. We now have 1: base name, 2: base +% signature, 3: beginning of variant signature. To construct the new +% csname and the "\exp_args:Ncc" form, we need the variant signature. +% In our example, we wanted to discard the first two letters of the +% base signature because the variant form started with "cc". This is +% the same as putting first "cc" in the signature and then +% "\use_none:nn" followed by the base signature "NNn". We therefore +% call a small loop that outputs an "n" for each letter in the variant +% signature and use this to call the correct "\use_none:" variant. +% Firstly though, we check whether to terminate the loop. +% \begin{macrocode} +\cs_set:Npn \cs_generate_variant_aux:nnw #1 #2 #3, { + \if:w ? #3 + \exp_after:wN \use_none_delimit_by_q_recursion_stop:w + \fi: +% \end{macrocode} +% Then check if the variant form has already been defined. +% \begin{macrocode} + \cs_if_free:cTF { + #1:#3\use:c {use_none:\cs_generate_variant_aux:N #3 ?}#2 + } + { +% \end{macrocode} +% If not, then define it and then additionally check if +% the |\exp_args:N| form needed is defined. +% \begin{macrocode} + \cs_new_nopar:cpx { + #1:#3 \use:c{use_none:\cs_generate_variant_aux:N #3 ?}#2 + } + { + \exp_not:c { exp_args:N #3} \exp_not:c {#1:#2} + } + \cs_generate_internal_variant:n {#3} + } +% \end{macrocode} +% Otherwise tell that it was already defined. +% \begin{macrocode} + { + \iow_log:x{ + Variant~\token_to_str:c { + #1:#3\use:c {use_none:\cs_generate_variant_aux:N #3 ?}#2 + }~already~defined;~ not~ changing~ it~on~line~ + \tex_the:D \tex_inputlineno:D + } + } +% \end{macrocode} +% Recurse. +% \begin{macrocode} + \cs_generate_variant_aux:nnw{#1}{#2} +} +% \end{macrocode} +% The small loop for defining the required number of "n"s. Break when +% seeing a "?". +% \begin{macrocode} +\cs_set:Npn \cs_generate_variant_aux:N #1{ + \if:w ?#1 \exp_after:wN\use_none:nn \fi: n \cs_generate_variant_aux:N +} % \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_long_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{macro}{\cs_generate_internal_variant:n} +% Test if |exp_args:N #1| is already defined +% and if not define it via the +% |\::| commands using the chars in |#1| % \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: - } +\cs_new:Npn \cs_generate_internal_variant:n #1 { + \cs_if_free:cT { exp_args:N #1 }{ % \end{macrocode} -% We also have to test if |exp_args:N#3| is already defined -% and if not define it via the -% |\::| commands using the chars in |#3| +% We use "new" to log the definition if we have to make one. % \begin{macrocode} - \cs_if_free:cT - {exp_args:N#3} - {\def:cpx {exp_args:N#3} - {\exp_args_form_x:w #3 :} - } + \cs_new:cpx { exp_args:N #1 } + { \cs_generate_internal_variant_aux:n #1 : } + } } % \end{macrocode} % \end{macro} % -% -% \begin{macro}{\exp_args_form_x:w} +% \begin{macro}[aux]{\cs_generate_internal_variant_aux:n} % This command grabs 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 { +\cs_new:Npn \cs_generate_internal_variant_aux:n #1 { \exp_not:c{::#1} - \if_meaning:NN #1 : - \else: - \exp_after:NN\exp_args_form_x:w - \fi:} + \if_meaning:w #1 : + \exp_after:wN \use_none:n + \fi: + \cs_generate_internal_variant_aux:n +} % \end{macrocode} % \end{macro} % -% Show token usage: +% \subsection{Last-unbraced versions} +% +%\begin{macro}[aux]{\exp_arg_last_unbraced:nn} +%\begin{macro}[aux]{\::f_unbraced} +%\begin{macro}[aux]{\::o_unbraced} +%\begin{macro}[aux]{\::V_unbraced} +%\begin{macro}[aux]{\::v_unbraced} +% There are a few places where the last argument needs to be available +% unbraced. First some helper macros. +% \begin{macrocode} +\cs_new:Npn \exp_arg_last_unbraced:nn #1#2 { #2#1 } +\cs_new:Npn \::f_unbraced \:::#1#2 { + \exp_after:wN \exp_arg_last_unbraced:nn + \exp_after:wN { \tex_romannumeral:D -`0 #2 } {#1} +} +\cs_new:Npn \::o_unbraced \:::#1#2 { + \exp_after:wN \exp_arg_last_unbraced:nn \exp_after:wN {#2 }{#1} +} +\cs_new:Npn \::V_unbraced \:::#1#2 { + \exp_after:wN \exp_arg_last_unbraced:nn + \exp_after:wN { \tex_romannumeral:D -`0 \exp_eval_register:N #2 } {#1} +} +\cs_new:Npn \::v_unbraced \:::#1#2 { + \exp_after:wN \exp_arg_last_unbraced:nn + \exp_after:wN { + \tex_romannumeral:D -`0 \exp_eval_register:c {#2} + } {#1} +} +% \end{macrocode} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\exp_last_unbraced:NV} +%\begin{macro}{\exp_last_unbraced:Nv} +%\begin{macro}{\exp_last_unbraced:Nf} +%\begin{macro}{\exp_last_unbraced:NcV} +%\begin{macro}{\exp_last_unbraced:NNo} +%\begin{macro}{\exp_last_unbraced:NNV} +%\begin{macro}{\exp_last_unbraced:NNNo} +% Now the business end. +% \begin{macrocode} +\cs_new_nopar:Npn \exp_last_unbraced:Nf { \::f_unbraced \::: } +\cs_new_nopar:Npn \exp_last_unbraced:NV { \::V_unbraced \::: } +\cs_new_nopar:Npn \exp_last_unbraced:Nv { \::v_unbraced \::: } +\cs_new_nopar:Npn \exp_last_unbraced:NcV { + \::c \::V_unbraced \::: +} +\cs_new:Npn \exp_last_unbraced:NNo #1#2#3 { + \exp_after:wN #1 \exp_after:wN #2 #3 +} +\cs_new_nopar:Npn \exp_last_unbraced:NNV { + \::N \::V_unbraced \::: +} +\cs_new:Npn \exp_last_unbraced:NNNo #1#2#3#4 { + \exp_after:wN #1 \exp_after:wN #2 \exp_after:wN #3 #4 +} +% \end{macrocode} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +% % \begin{macrocode} %</initex|package> +% \end{macrocode} +% +% Show token usage: +% \begin{macrocode} %<*showmemory> \showMemUsage %</showmemory> % \end{macrocode} % -% \endinput -% -% $Log$ -% Revision 1.29 2006/07/30 15:43:38 morten -% Minor touch-up plus added functions needed by clist module -% -% Revision 1.28 2006/06/03 18:56:31 morten -% A few more functions -% -% Revision 1.27 2006/03/20 18:26:35 braams -% Updated the copyright notice (2006) and demoted all implementation -% sections to subsections and so on to clean up the toc for source3.tex -% -% Revision 1.26 2006/02/17 23:01:47 braams -% Imported \exp_args:NNO from l3messages -% -% Revision 1.25 2005/12/27 10:00:45 morten -% Changed RCS information retrieval -% -% Revision 1.24 2005/12/22 13:56:03 morten -% Fixed error in \exp_args:NNd -% -% Revision 1.23 2005/12/21 20:44:30 morten -% Corrected typo. -% -% Revision 1.22 2005/12/06 15:34:46 morten -% Made \exp_not:o do what you'd expect -% -% Revision 1.21 2005/11/23 07:37:29 morten -% A few new expansion types, we shall see if they will be useful. -% -% Revision 1.20 2005/04/12 16:44:06 morten -% Fix to make it run as a package -% -% Revision 1.19 2005/04/12 13:24:07 morten -% Minor updates -% -% Revision 1.18 2005/04/09 21:06:46 morten -% Added yet another function. -% -% Revision 1.17 2005/04/06 21:38:10 morten -% Added more functions. -% -% Revision 1.16 2005/03/26 21:09:44 morten -% Added f argument type for "force expansion" -% -% Revision 1.15 2005/03/22 23:24:40 morten -% Fixed documentation error. -% -% Revision 1.14 2005/03/16 22:36:37 braams -% Added the tweaks necessary to be able to load with initex -% -% Revision 1.13 2005/03/11 21:37:37 braams -% Fixed the use of RCS information +% \end{implementation} +% \PrintIndex % +% \endinput diff --git a/Master/texmf-dist/source/latex/expl3/l3file.dtx b/Master/texmf-dist/source/latex/expl3/l3file.dtx new file mode 100644 index 00000000000..e5e3a5e159c --- /dev/null +++ b/Master/texmf-dist/source/latex/expl3/l3file.dtx @@ -0,0 +1,412 @@ +% \iffalse +%% File: l3file.dtx Copyright (C) 2009 LaTeX3 project +%% +%% It may be distributed and/or modified under the conditions of the +%% LaTeX Project Public License (LPPL), either version 1.3c of this +%% license or (at your option) any later version. The latest version +%% of this license is in the file +%% +%% http://www.latex-project.org/lppl.txt +%% +%% This file is part of the ``expl3 bundle'' (The Work in LPPL) +%% and all files in that bundle must be distributed together. +%% +%% The released version of this bundle is available from CTAN. +%% +%% ----------------------------------------------------------------------- +%% +%% The development version of the bundle can be found at +%% +%% http://www.latex-project.org/svnroot/experimental/trunk/ +%% +%% for those people who are interested. +%% +%%%%%%%%%%% +%% NOTE: %% +%%%%%%%%%%% +%% +%% Snapshots taken from the repository represent work in progress and may +%% not work or may contain conflicting material! We therefore ask +%% people _not_ to put them into distributions, archives, etc. without +%% prior consultation with the LaTeX Project Team. +%% +%% ----------------------------------------------------------------------- +%% +% +%<*driver|package> +\RequirePackage{l3names} +%</driver|package> +%\fi +\GetIdInfo$Id: l3file.dtx 1352 2009-05-28 11:50:39Z morten $ + {L3 Experimental file loading} +%\iffalse +%<*driver> +%\fi +\ProvidesFile{\filename.\filenameext} + [\filedate\space v\fileversion\space\filedescription] +%\iffalse +\documentclass[full]{l3doc} +\begin{document} + \DocInput{l3file.dtx} +\end{document} +%</driver> +% \fi +% +% \title{The \textsf{l3file} package\thanks{This file +% has version number \fileversion, last +% revised \filedate.}\\ +% File Loading} +% \author{\Team} +% \date{\filedate} +% \maketitle +% +% \begin{documentation} +% +%\section{Loading files} +% +% The need to test if a file is available and to load a file if found is +% covered at a low level here. +% +%\begin{function}{ +% \file_if_exist_p:n| +% \file_if_exist:n / (TF) +%} +% \begin{syntax} +% "\file_if_exist:nTF" <file> <true code> <false code> +% \end{syntax} +% Tests if <file> exists. +% \begin{texnote} +% This is \LaTeXe's \cs{IfFileExists}, although it does not return +% name of the file (\emph{cf.}~\cs{@filef@und}). +% \end{texnote} +%\end{function} +% +%\begin{function}{\file_add_path:nN} +% \begin{syntax} +% "\file_add_path:nN" <file> <tl~var.> +% \end{syntax} +% Searches for <file> on the \TeX\ path and using +% \cs{l_file_search_path_clist}. If <file> is found, <tl~var.> is set +% to the file name plus any path information needed. If <file> is not +% found, <tl~var.> will be blank. +% \begin{texnote} +% This is similar to obtaining \cs{@filef@und} from \LaTeXe's +% \cs{IfFileExists}. +% \end{texnote} +%\end{function} +% +%\begin{function}{\file_input:n} +% \begin{syntax} +% "\file_input:n" <file> +% \end{syntax} +% Inputs <file> if it found (according to the same rule as for +% \cs{file_if_exist:n}. +% \begin{texnote} +% This acts in a similar way to \LaTeXe's \cs{input}, as it will not +% lead to a \TeX\ loop if the file is not found. +% \end{texnote} +%\end{function} +% +%\begin{function}{\file_input_no_record:n} +% \begin{syntax} +% "\file_input_no_record:n" <file> +% \end{syntax} +% Inputs <file> if it found (according to the same rule as for +% \cs{file_if_exist:n}, but does not add it to +% \cs{g_file_record_clist}. The file is still added to +% \cs{g_file_record_full_clist}. +% \begin{texnote} +% This is similar to \LaTeXe's \cs{@input@}. +% \end{texnote} +%\end{function} +% +%\begin{function}{ +% \file_input_no_check:n| +% \file_input_no_check_no_record:n| +%} +% \begin{syntax} +% "\file_input_no_check:n" <file> +% \end{syntax} +% Inputs <file> directly without checking if it exists. The +% \texttt{no_record} version does not record the input in +% \begin{texnote}\cs{g_file_record_clist}. +% These are simple wrappers around the \TeX\ \cs{input} primitive +% \end{texnote} +%\end{function} +% +%\begin{function}{ +% \file_list:| +% \file_list_full:| +%} +% \begin{syntax} +% "\file_list:" <file> +% \end{syntax} +% Lists files loaded in current \LaTeX\ run: the \texttt{full} version +% lists all files. +%\end{function} +% +%\section{Variables and constants} +% +%\begin{variable}{ +% \g_file_record_clist| +% \g_file_record_full_clist +%} +% Used to track the files that have been loaded. +%\end{variable} +% +%\begin{variable}{\l_file_search_path_clist} +% List of paths to search for a file in addition to those searched by +% \TeX. +% \begin{texnote} +% This is \cs{input@path} in \LaTeXe. +% \end{texnote} +%\end{variable} +% +%\begin{variable}{\l_file_test_read_stream} +% Input stream used to carry out file tests. +%\end{variable} +% +%\begin{variable}{\l_file_tmp_bool} +% Internal scratch switch. +%\end{variable} +% +%\begin{variable}{\l_file_tmp_tl} +% Internal scratch token list variable. +%\end{variable} +% +% \end{documentation} +% +% \begin{implementation} +% +% \section{\pkg{l3file} implementation} +% +% The usual lead-off. +% \begin{macrocode} +%<*package> +\ProvidesExplPackage + {\filename}{\filedate}{\fileversion}{\filedescription} +\package_check_loaded_expl: +%</package> +%<*initex|package> +% \end{macrocode} +% +%\begin{macro}{\g_file_record_clist} +%\begin{macro}{\g_file_record_full_clist} +% When files are read with logging, the names are added here. There are +% two lists, one for everything and one for only those items which might +% later be listed (as in \LaTeXe's \cs{listfiles}). +% \begin{macrocode} +\clist_new:N \g_file_record_clist +\clist_new:N \g_file_record_full_clist +% \end{macrocode} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\l_file_search_path_clist} +% Checking input needs a stream to work with +% \begin{macrocode} +\clist_new:N \l_file_search_path_clist +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\l_file_test_read_stream} +% Checking input needs a stream to work with +% \begin{macrocode} +\ior_new:N \l_file_test_read_stream +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\l_file_tmp_bool} +% A flag is needed for internal purposes. +% \begin{macrocode} +\bool_new:N \l_file_tmp_bool +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\l_file_tmp_tl} +% A scratch token list variable. +% \begin{macrocode} +\tl_new:N \l_file_tmp_tl +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\file_if_exist_p:n} +%\begin{macro}[TF]{\file_if_exist:n} +%\begin{macro}[aux]{\file_if_exist_path:n} +%\begin{macro}[aux]{\file_if_exist_aux:n} +% Checking if a file exists takes place in two parts. First, there is +% a simple check ``here''. If that fails, then there is a loop over +% the current search path. +% \begin{macrocode} +\prg_new_conditional:Nnn \file_if_exist:n {p,TF,T,F} { + \ior_open:Nn \l_file_test_read_stream {#1} + \ior_if_eof:NTF \l_file_test_read_stream { + \file_if_exist_path:n {#1} + }{ + \ior_close:N \l_file_test_read_stream + \prg_return_true: + } +} +\cs_new_nopar:Nn \file_if_exist_path:n { + \bool_set_false:N \l_file_tmp_bool + \cs_set_nopar:Nn \file_if_exist_aux:n { + \ior_open:Nn \l_file_test_read_stream { #1 ##1 } + \ior_if_eof:NF \l_file_test_read_stream { + \bool_set_true:N \l_file_tmp_bool + \clist_map_break: + } + } +%</initex|package> +%<*package> + \cs_if_exist:NT \input@path { + \cs_set_eq:NN \l_file_search_path_clist \input@path + } +%</package> +%<*initex|package> + \clist_map_function:NN \l_file_search_path_clist \file_if_exist_aux:n + \ior_close:N \l_file_test_read_stream + \bool_if:NTF \l_file_tmp_bool { + \prg_return_true: + }{ + \prg_return_false: + } +} +\cs_new_nopar:Nn \file_if_exist_aux:n { } +% \end{macrocode} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\file_add_path:nN} +%\begin{macro}[aux]{\file_add_path_search:n} +%\begin{macro}[aux]{\file_add_path_aux:n} +% Checking if a file exists takes place in two parts. First, there is +% a simple check ``here''. If that fails, then there is a loop over +% the current search path. +% \begin{macrocode} +\cs_new_nopar:Nn \file_add_path:nN { + \tl_clear:N #2 + \ior_open:Nn \l_file_test_read_stream {#1} + \ior_if_eof:NTF \l_file_test_read_stream { + \file_add_path_search:nN {#1} #2 + }{ + \tl_set:Nn #2 {#1} + } + \ior_close:N \l_file_test_read_stream +} +\cs_new_nopar:Nn \file_add_path_search:nN { + \cs_set_nopar:Nn \file_add_path_aux:n { + \ior_open:Nn \l_file_test_read_stream { ##1 #1 } + \ior_if_eof:NF \l_file_test_read_stream { + \tl_set:Nn #2 { ##1 #1 } + \clist_map_break: + } + } +%</initex|package> +%<*package> + \cs_if_exist:NT \input@path { + \cs_set_eq:NN \l_file_search_path_clist \input@path + } +%</package> +%<*initex|package> + \clist_map_function:NN \l_file_search_path_clist \file_add_path_aux:n +} +\cs_new_nopar:Nn \file_add_path_aux:n { } +% \end{macrocode} +%\end{macro} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\file_input:n} +%\begin{macro}{\file_input_no_record:n} +% \cs{file_add_path:nN} will return an empty token list variable if the +% file is not found. This is used rather than \cs{file_if_exist:nT} here +% as it saves running the same loop twice. +% \begin{macrocode} +\cs_new:Nn \file_input:n { + \file_add_path:nN {#1} \l_file_tmp_tl + \tl_if_empty:NF \l_file_tmp_tl { + \file_input_no_check:n \l_file_tmp_tl + } +} +\cs_new:Nn \file_input_no_record:n { + \file_add_path:nN {#1} \l_file_tmp_tl + \tl_if_empty:NF \l_file_tmp_tl { + \file_input_no_check_no_record:n \l_file_tmp_tl + } +} +% \end{macrocode} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\file_input_no_check:n} +% File input records what is going on before setting to work. +% \begin{macrocode} +\cs_new_nopar:Nn \file_input_no_check:n { + \clist_gput_right:Nx \g_file_record_clist {#1} + \wlog{ADDING: #1} +%</initex|package> +%<*package> + \@addtofilelist {#1} +%</package> +%<*initex|package> + \clist_gput_right:Nx \g_file_record_full_clist {#1} + \tex_input:D #1 ~ +} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\file_input_no_check_no_record:n} +% Inputting a file without adding to the main record is basically the +% same: even in this case the file goes on the full log. +% \begin{macrocode} +\cs_new_nopar:Nn \file_input_no_check_no_record:n { + \clist_gput_right:Nx \g_file_record_full_clist {#1} + \tex_input:D #1 ~ +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\file_list:} +%\begin{macro}{\file_list_full:} +%\begin{macro}[aux]{\file_list:N} +% Two functions to list all files used to the log: the \texttt{full} +% version includes everything whereas the standard version uses the +% shorter record. +% \begin{macrocode} +\cs_new_nopar:Nn \file_list: { + \file_list:N \g_file_record_clist +} +\cs_new_nopar:Nn \file_list_full: { + \file_list:N \g_file_record_full_clist +} +\cs_new_nopar:Nn \file_list:N { + \clist_remove_duplicates:N #1 + \iow_log:x { *~File~List~* } + \clist_map_function:NN #1 \file_list_aux:n + \iow_log:x { ************* } +} +\cs_new_nopar:Nn \file_list_aux:n { + \iow_log:x { #1 } +} +% \end{macrocode} +%\end{macro} +%\end{macro} +%\end{macro} +% +% When used as a package, there is a need to hold onto the standard +% file list as well as the new one here. +% \begin{macrocode} +%</initex|package> +%<*package> +% \begin{macrocode} +\AtBeginDocument{ + \clist_put_right:NV \g_file_record_clist \@filelist + \clist_put_right:NV \g_file_record_full_clist \@filelist +} +%</package> +% \end{macrocode} +% +% \end{implementation} +% +% \PrintIndex diff --git a/Master/texmf-dist/source/latex/expl3/l3final.dtx b/Master/texmf-dist/source/latex/expl3/l3final.dtx index f23db756876..65da64c7f7f 100644 --- a/Master/texmf-dist/source/latex/expl3/l3final.dtx +++ b/Master/texmf-dist/source/latex/expl3/l3final.dtx @@ -17,7 +17,7 @@ %% %% The development version of the bundle can be found at %% -%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/ +%% http://www.latex-project.org/svnroot/experimental/trunk/ %% %% for those people who are interested. %% @@ -37,7 +37,7 @@ %</driver|package> %<*-ini> %\fi -\GetIdInfo$Id: l3final.dtx 621 2007-09-01 20:14:19Z morten $ +\GetIdInfo$Id: l3final.dtx 1362 2009-05-28 20:19:21Z joseph $ {L3 Experimental final module} %\iffalse %</-ini> @@ -46,7 +46,7 @@ \ProvidesFile{\filename.\filenameext} [\filedate\space v\fileversion\space\filedescription] %\iffalse -\documentclass{l3doc} +\documentclass[full]{l3doc} \begin{document} \DocInput{\filename.\filenameext} \end{document} @@ -63,15 +63,9 @@ % Some of the macros needed in creating the format are no longer % needed and will either be removed are modified to generate error % messages. -%<*initex> -% -% \subsection{Closing the error file} % -% Earlier on in the format a file was opened to collect all the -% error messages. This file needs to be closed before the format is -% dumped. % \begin{macrocode} -\err_file_close:N\c_kernel_err_tlp +%<*initex> % \end{macrocode} % % \subsection{Dumping the format} @@ -80,45 +74,7 @@ % \begin{macrocode} \tex_dump:D % \end{macrocode} -%</initex> -% \subsection{Creating the format} % -% There is one more thing needed for creating the format; a file -% called \file{lbase.ini}. For now this is included here. -%<*ini> % \begin{macrocode} -%% Derived from a file by Thomas Esser - -\ifx\pdfoutput\undefined \else - \ifx\pdfoutput\relax \else - % We're building the latex format with the pdfetex engine (started 2004). - % See this file for details. - \input pdftex-dvi.tex - \fi -\fi - -%% the usual format initialization. -%%\scrollmode -\input lbase.ltx -\endinput +%</initex> % \end{macrocode} -%</ini> -% \endinput -% -% $Log$ -% Revision 1.5 2006/03/19 15:03:22 braams -% Added code to close the kernel error file -% -% Revision 1.4 2006/01/13 23:20:07 braams -% Added lbase.ini to be generated from this file -% -% Revision 1.3 2005/12/27 16:01:48 morten -% Changed RCS information retrieval -% -% Revision 1.2 2005/04/12 22:48:24 braams -% Corrected a slight mistake -% -% Revision 1.1 2005/04/12 22:41:38 braams -% This file will contain al the last minute things needed in the format. -% For starters it just dumps the format. -% diff --git a/Master/texmf-dist/source/latex/expl3/l3format.ins b/Master/texmf-dist/source/latex/expl3/l3format.ins index cc3d0d984b8..f42ea71724d 100644 --- a/Master/texmf-dist/source/latex/expl3/l3format.ins +++ b/Master/texmf-dist/source/latex/expl3/l3format.ins @@ -1,72 +1,75 @@ - -\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 - -% generate the format file -\generate{% - \file{lbase.ltx}{% - \from{l3names.dtx}{initex} % The naming conventions - \from{l3basics.dtx}{initex} % Initialisations - \from{l3chk.dtx}{initex} % Checking functions - \from{l3tlp.dtx}{initex} % token list pointers - \from{l3expan.dtx}{initex} % Controlling expansion of arguments - \from{l3quark.dtx}{initex} % quarks - \from{l3num.dtx}{initex} % Storing integers in macros - \from{l3seq.dtx}{initex} % Sequences and Stacks - \from{l3alloc.dtx}{initex} % Register allocations - \from{l3io.dtx}{initex} % dealing with I/O - \from{l3int.dtx}{initex} % dealing with integer registers - \from{l3clist.dtx}{initex} % Comma separated lists - \from{l3prop.dtx}{initex} % property lists - \from{l3token.dtx}{initex} % token investigation -% - \from{l3vers.dtx}{initex} % Version information -% - \from{l3skip.dtx}{initex} % dealing with skip registers - \from{l3toks.dtx}{initex} % dealing with token registers - \from{l3messages.dtx}{initex} % seting up for user communication - \from{l3box.dtx}{initex} % dealing with box registers - \from{l3precom.dtx}{initex,precompile} % - \from{l3prg.dtx}{initex} % Program control structures - \from{l3xref.dtx}{initex} % Cross references -% - \from{l3final.dtx}{initex} % Final wrap-up - } -} -% generate the format initialisation file -\generate{% - \file{lbase.ini}{% - \from{l3final.dtx}{ini} - } -} - -\Msg{} -\Msg{*************************************} -\Msg{*} -\Msg{* Now run (PDF)EINITEX on *lbase.ini} -\Msg{*} -\Msg{* On an up to date system, run } -\Msg{* pdfetex -ini "*lbase.ini" } -\Msg{*} -\Msg{*************************************} -\Msg{} - -\endbatchfile +
+\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
+
+% generate the format file
+\generate{%
+ \file{lbase.ltx}{%
+ \from{l3names.dtx}{initex} % The naming conventions
+ \from{l3basics.dtx}{initex} % Initialisations
+ \from{l3expan.dtx}{initex} % Controlling expansion of arguments
+ \from{l3tl.dtx}{initex} % token list variables
+ \from{l3num.dtx}{initex} % Storing integers in macros
+ \from{l3intexpr.dtx}{initex} %
+ \from{l3quark.dtx}{initex} % quarks
+ \from{l3seq.dtx}{initex} % Sequences and stacks
+%
+ \from{l3alloc.dtx}{initex} % Register allocations
+%
+ \from{l3toks.dtx}{initex} % dealing with token registers
+ \from{l3int.dtx}{initex} % dealing with integer registers
+ \from{l3prg.dtx}{initex} % Program control structures
+ \from{l3clist.dtx}{initex} % Comma separated lists
+ \from{l3token.dtx}{initex} % token investigation
+ \from{l3io.dtx}{initex} % dealing with I/O
+ \from{l3prop.dtx}{initex} % property lists
+ \from{l3msg.dtx}{initex} % setting up for user communication
+ \from{l3skip.dtx}{initex} % dealing with skip registers
+ \from{l3box.dtx}{initex} % dealing with box registers
+ \from{l3keyval.dtx}{initex} %
+%
+% \from{l3precom.dtx}{initex,precompile} %
+%
+ \from{l3calc.dtx}{initex} %
+ \from{l3xref.dtx}{initex} % Cross references
+ \from{l3file.dtx}{initex} % file loading
+%
+ \from{l3vers.dtx}{initex} % Version information
+%
+%
+% \from{l3chk.dtx}{initex} % Checking functions
+%
+ \from{l3final.dtx}{initex} % Final wrap-up
+ }
+}
+
+\Msg{}
+\Msg{*************************************}
+\Msg{*}
+\Msg{* Now run (PDF)INITEX on lbase.ltx}
+\Msg{*}
+\Msg{* On an up to date system, run }
+\Msg{* pdftex -ini *lbase.ltx }
+\Msg{*}
+\Msg{*************************************}
+\Msg{}
+
+\endbatchfile
diff --git a/Master/texmf-dist/source/latex/expl3/l3int.dtx b/Master/texmf-dist/source/latex/expl3/l3int.dtx index 5b13df9cec4..815f7610e9c 100644 --- a/Master/texmf-dist/source/latex/expl3/l3int.dtx +++ b/Master/texmf-dist/source/latex/expl3/l3int.dtx @@ -1,5 +1,5 @@ % \iffalse -%% File: l3int.dtx Copyright (C) 1990-2008 LaTeX3 project +%% File: l3int.dtx Copyright (C) 1990-2009 LaTeX3 project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this @@ -17,7 +17,7 @@ %% %% The development version of the bundle can be found at %% -%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/ +%% http://www.latex-project.org/svnroot/experimental/trunk/ %% %% for those people who are interested. %% @@ -36,7 +36,7 @@ \RequirePackage{l3names} %</driver|package> %\fi -\GetIdInfo$Id: l3int.dtx 738 2008-08-01 13:21:42Z morten $ +\GetIdInfo$Id: l3int.dtx 1362 2009-05-28 20:19:21Z joseph $ {L3 Experimental Integer module} %\iffalse %<*driver> @@ -44,9 +44,9 @@ \ProvidesFile{\filename.\filenameext} [\filedate\space v\fileversion\space\filedescription] %\iffalse -\documentclass{l3doc} +\documentclass[full]{l3doc} \begin{document} -\DocInput{\filename.\filenameext} +\DocInput{l3int.dtx} \end{document} %</driver> % \fi @@ -55,12 +55,12 @@ % \title{The \textsf{l3int} package\thanks{This file % has version number \fileversion, last % revised \filedate.}\\ -% Counters} +% Integers/counters} % \author{\Team} % \date{\filedate} % \maketitle % -% \section{Integers} +% \begin{documentation} % % \LaTeX3 maintains two type of integer registers for internal use. % One (associated with the name "num") for low level uses in the @@ -72,12 +72,12 @@ % preferred in all cases as there is little chance we should ever run % out of registers when being based on at least \eTeX. % -% \subsection{Functions} +% \section{Functions} % % \begin{function}{% % \int_new:N | % \int_new:c | -% \int_new_l:N | +%^^A \int_new_l:N | % } % \begin{syntax} % "\int_new:N" <int> @@ -85,7 +85,7 @@ % Globally defines <int> to be a new variable of type "int" although % you can still choose if it should be a an "\l_" or "\g_" type. % There is no way to define constant counters with these functions. -% The function "\int_new_l:N" defines <int> locally only. +%^^A The function "\int_new_l:N" defines <int> locally only. % \begin{texnote} % "\int_new:N" is the equivalent to plain \TeX{}'s \tn{newcount}. % However, the internal register allocation is done differently. @@ -125,7 +125,7 @@ % \int_gset:cn | % } % \begin{syntax} -% "\int_set:Nn" <int> "{" <integer expr> "}" +% "\int_set:Nn" <int> \Arg{integer expr} % \end{syntax} % These functions will set the <int> register to the <integer expr> % value. This value can contain simple calc-like expressions as @@ -154,7 +154,7 @@ % \int_gadd:cn | % } % \begin{syntax} -% "\int_add:Nn" <int> "{" <integer expr> "}" +% "\int_add:Nn" <int> \Arg{integer expr} % \end{syntax} % These functions will add to the <int> register the value <integer % expr>. If the second argument is a <int> register too, the @@ -168,7 +168,7 @@ % \int_gsub:cn | % } % \begin{syntax} -% "\int_gsub:Nn" <int> "{" <integer expr> "}" +% "\int_gsub:Nn" <int> \Arg{integer expr} % \end{syntax} % These functions will subtract from the <int> register the value % <integer expr>. If the second argument is a <int> register too, the @@ -193,18 +193,34 @@ % \end{texnote} % \end{function} % -% \subsection{Formatting a counter value} +% \begin{function}{ \int_show:N | +% \int_show:c } +% \begin{syntax} +% "\int_show:N" <int> +% \end{syntax} +% This function pauses the compilation and displays the integer value kept +% in <int> in the console output and log file. +% \begin{texnote} +% The function "\int_show:N" could be implemented directly as the \TeX{} +% primitive "\tex_showthe:D" which is also responsible to produce the values for +% other internal quantities. We have chosen to use individual functions +% for counters, dimensions etc.\ to allow checks and to make the code +% more self-explaining. +% \end{texnote} +% \end{function} +% +% \section{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 | +% \int_to_arabic:n / (EXP) | +% \int_to_alph:n / (EXP) | +% \int_to_Alph:n / (EXP) | +% \int_to_roman:n / (EXP) | +% \int_to_Roman:n / (EXP) | +% \int_to_symbol:n / (EXP) | % } % \begin{syntax} -% "\int_to_alph:n" "{" <integer> "}" +% "\int_to_alph:n" \Arg{integer} % "\int_to_alph:n" <int> % \end{syntax} % If some <integer> or the the current value of a <int> should be @@ -228,9 +244,9 @@ % \end{texnote} % \end{function} % -% \subsubsection{Internal functions} +% \subsection{Internal functions} % -% \begin{function}{\int_to_roman:w} +% \begin{function}{\int_to_roman:w / (EXP)} % \begin{syntax} % "\int_to_roman:w" <integer> <space> \textit{or} <non-expandable token> % \end{syntax} @@ -240,12 +256,24 @@ % This is the \TeX{} primitive \tn{romannumeral} renamed. % \end{texnote} % \end{function} +% +% \begin{function}{\int_to_number:w / (EXP)} +% \begin{syntax} +% "\int_to_number:w" <integer> <space> +% \end{syntax} +% Converts <integer> to its numerical string. Note that +% it produces a string of letters with catcode 12. +% \begin{texnote} +% This is the \TeX{} primitive \tn{number} renamed. +% \end{texnote} +% \end{function} +% % \begin{function}{ % \int_roman_lcuc_mapping:Nnn | % \int_to_roman_lcuc:NN | % } % \begin{syntax} -% "\int_roman_lcuc_mapping:Nnn" <roman_char> "{"<licr>"}" "{"<LICR>"}" +% "\int_roman_lcuc_mapping:Nnn" <roman_char> \Arg{licr} \Arg{LICR} % "\int_to_roman_lcuc:NN" <roman_char> <char> % \end{syntax} % "\int_roman_lcuc_mapping:Nnn" specifies how the roman @@ -264,8 +292,8 @@ % \int_symbol_text_conversion_rule:n | % } % \begin{syntax} -% "\int_convert_number_with_rule:nnN" "{"<int1>"}" "{"<int2>"}" <function> -% "\int_alph_default_conversion_rule:n" "{"<int>"}" +% "\int_convert_number_with_rule:nnN" \Arg{int1} \Arg{int2} <function> +% "\int_alph_default_conversion_rule:n" \Arg{int} % \end{syntax} % "\int_convert_number_with_rule:nnN" converts <int1> into letters, % symbols, whatever as defined by <function>. <int2> denotes the base @@ -277,7 +305,34 @@ % % % -% \subsection{Variable and constants} +% \section{Variable and constants} +% +% \begin{function}{% +% \int_const:Nn | +% } +% \begin{syntax} +% "\int_const:Nn" "\c_"<value> \Arg{value} +% \end{syntax} +% Defines an integer constant of a certain <value>. If the constant is negative +% or very large it internally uses an <int> register. +% \end{function} +% +% \begin{variable}{ \c_minus_one | \c_zero | \c_one | \c_two | \c_three | +% \c_four | \c_five | \c_six | \c_seven | \c_eight | +% \c_nine | \c_ten | \c_eleven | \c_twelve | \c_thirteen | +% \c_fourteen | \c_fifteen | \c_sixteen | \c_thirty_two | +% \c_hundred_one | +% \c_twohundred_fifty_five | \c_twohundred_fifty_six | +% \c_thousand | +% \c_ten_thousand | \c_ten_thousand_one | +% \c_ten_thousand_two | \c_ten_thousand_three | +% \c_ten_thousand_four | \c_twenty_thousand } +% Set of constants denoting useful values. +% \begin{texnote} +% Some of these constants have been available under \LaTeX2 under names +% like \tn{m@ne}, \tn{z@}, \tn{@ne},\tn{tw@}, \tn{thr@@}, etc. +% \end{texnote} +% \end{variable} % % \begin{variable}{% % \c_max_int | @@ -299,149 +354,87 @@ % \end{variable} % % -% \subsection{Testing and evaluating integer expressions} % -% \begin{function}{% -% \int_eval:n | -% \int_div_truncate:nn | -% \int_div_round:nn | -% \int_mod:nn | -% } -% \begin{syntax} -% "\int_eval:n" "{"<int~expr>"}" \\ -% "\int_div_truncate:n" "{"<int~expr>"}" "{"<int~expr>"}" \\ -% "\int_mod:nn" "{"<int~expr>"}" "{"<int~expr>"}" -% \end{syntax} -% Evaluates the value of a integer expression so that -% "\int_eval:n {3*5/4}" puts "4" back into the input stream. Note that -% the results of divisions are rounded by the primitive operations. If -% you want the result of a division to be truncated use -% "\int_div_truncate:nn". "\int_div_round:nn" is added for -% completeness. "\int_mod:nn" returns the remainder of a division. All -% of these functions are expandable. -% \begin{texnote} -% "\int_eval:n" is the \eTeX primitive \tn{numexpr} turned into a function -% taking an argument. -% \end{texnote} -% \end{function} % -% \begin{function}{% -% \int_compare:nNnTF | -% \int_compare:nNnT | -% \int_compare:nNnF | -% } -% \begin{syntax} -% "\int_compare:nNnTF" "{"<int~expr>"}" <rel> "{"<int~expr>"}" -% "{"<true>"}" "{"<false>"}" -% \end{syntax} -% These functions test two integer expressions against each other. They -% are both evaluated by "\int_eval:n". Note that if both expressions -% are normal integer variables as in -% \begin{quote} -% "\int_compare:nNnTF \l_temp_int < \c_zero {negative}{non-negative}" -% \end{quote} -% you can safely omit the braces. -% \begin{texnote} -% This is the \TeX{} primitive \tn{ifnum} turned into a function. -% \end{texnote} -% \end{function} +% \section{Conversion} % % \begin{function}{% -% \int_compare_p:nNn | +% \int_convert_from_base_ten:nn | % } % \begin{syntax} -% "\int_compare_p:nNn" "{"<int~expr>"}" <rel> "{"<int~expr>"}" +% "\int_convert_from_base_ten:nn" \Arg{number} \Arg{base} % \end{syntax} -% A predicate version of the above mentioned functions. +% Converts the base~10 number <number> into its equivalent +% representation written in base~<base>. Expandable. % \end{function} % -% \begin{function}{% -% \int_max_of:nn | -% \int_min_of:nn | -% } -% \begin{syntax} -% "\int_max_of:nn" "{"<int~expr>"}" "{"<int~expr>"}" -% \end{syntax} -% Return the largest or smallest of two integer expressions. -% \end{function} % % \begin{function}{% -% \int_abs:n | +% \int_convert_to_base_ten:nn | % } % \begin{syntax} -% "\int_abs:n" "{"<int~expr>"}" +% "\int_convert_to_base_ten:nn" \Arg{number} \Arg{base} % \end{syntax} -% Return the numerical value of an integer expression. +% Converts the base~<base> number <number> into its equivalent +% representation written in base~10. <number> can consist of digits +% and ascii letters. Expandable. % \end{function} % -% \begin{function}{% -% \int_if_odd:nTF | -% \int_if_odd_p:n | -% } +% +% \end{documentation} +% +% \begin{implementation} +% +% \section{\pkg{l3int} implementation} +% +% \subsection{Internal functions and variables} +% +% \begin{function}{\int_advance:w} % \begin{syntax} -% "\int_if_odd:nTF" "{"<int~expr>"}" "{"<true>"}" "{"<false>"}" +% "\int_advance:w" <int register> <optional `\texttt{by}'> <number> <space> % \end{syntax} -% These functions test if an integer expression is even or odd. We -% also define a predicate version of it. +% Increments the count register by the specified amount. % \begin{texnote} -% This is the \TeX{} primitive \tn{ifodd} turned into a function. +% This is \TeX's \tn{advance}. % \end{texnote} % \end{function} % -% \begin{function}{% -% \int_whiledo:nNnT | -% \int_whiledo:nNnF | -% \int_dowhile:nNnT | -% \int_dowhile:nNnF | -% } +% +% \begin{function}{\int_convert_number_to_letter:n / (EXP)} % \begin{syntax} -% "\int_whiledo:nNnT" <int expr> <rel> <int~expr> "{"<true>"}" +% "\int_convert_number_to_letter:n" \Arg{integer expression} % \end{syntax} -% "\int_whiledo:nNnT" tests the integer expressions and if true performs -% the body "T" until the test fails. "\int_dowhile:nNnT" is similar -% but executes the body first and then performs the check, thus -% ensuring that the body is executed at least once. The "F" versions -% are similar but continue the loop as long as the test is false. They -% could be omitted as it is just a matter of switching the arguments -% in the test. +% Internal function for turning a number for a different base into a letter or digit. % \end{function} % - -% \subsection{Conversion} -% -% \begin{function}{% -% \int_convert_from_base_ten:nn | -% } +% \begin{function}{\int_pre_eval_one_arg:Nn | \int_pre_eval_two_args:Nnn} % \begin{syntax} -% "\int_convert_from_base_ten:nn" "{"<number>"}""{"<base>"}" +% "\int_pre_eval_one_arg:Nn" <function> \Arg{integer expression} +% "\int_pre_eval_one_arg:Nnn" <function> \Arg{int~expr~1} \Arg{int~expr~2} % \end{syntax} -% Converts the base~10 number <number> into its equivalent -% representation written in base~<base>. Expandable. +% These are expansion helpers; they evaluate their integer expressions +% before handing them off to the specified <function>. % \end{function} % -% -% \begin{function}{% -% \int_convert_to_base_ten:nn | -% } +% \begin{function}{ \int_get_sign_and_digits:n / (EXP) | +% \int_get_sign:n / (EXP ) | +% \int_get_digits:n / (EXP) } % \begin{syntax} -% "\int_convert_to_base_ten:nn" "{"<number>"}""{"<base>"}" +% "\int_get_sign_and_digits:n" \Arg{number} % \end{syntax} -% Converts the base~<base> number <number> into its equivalent -% representation written in base~10. <number> can consist of digits -% and ascii letters. Expandable. +% From an argument that may or may not include a "+" or "-" sign, these +% functions expand to the respective components of the number. % \end{function} % -% -% \StopEventually{} -% \subsection{The Implementation} -% +% \subsection{Module loading and primitives definitions} % % We start by ensuring that the required packages are loaded. % \begin{macrocode} -%<package>\ProvidesExplPackage -%<package> {\filename}{\filedate}{\fileversion}{\filedescription} -%<package&!check>\RequirePackage{l3num} -%<package&check>\RequirePackage{l3chk} +%<*package> +\ProvidesExplPackage + {\filename}{\filedate}{\fileversion}{\filedescription} +\package_check_loaded_expl: +%</package> %<*initex|package> % \end{macrocode} % @@ -450,9 +443,9 @@ % \begin{macro}{\int_advance:w} % A new name for the primitives. % \begin{macrocode} -\let_new:NN \int_to_roman:w \tex_romannumeral:D -\let_new:NN \int_to_number:w \tex_number:D -\let_new:NN \int_advance:w \tex_advance:D +\cs_new_eq:NN \int_to_roman:w \tex_romannumeral:D +\cs_new_eq:NN \int_to_number:w \tex_number:D +\cs_new_eq:NN \int_advance:w \tex_advance:D % \end{macrocode} % \end{macro} % \end{macro} @@ -460,6 +453,63 @@ % Functions that support \LaTeX's user accessible counters should be % added here, too. But first the internal counters. % +% \subsection{Allocation and setting} +% +% \begin{macro}{\int_new:N,\int_new:c} +%^^A \begin{macro}{\int_new_l:N} +% Allocation of a new internal counter is already done above. Here we define +% the next likely variant. +% +% For the \LaTeX3 format: +% \begin{macrocode} +%<*initex> +\alloc_setup_type:nnn {int} {11} \c_max_register_num +\cs_new_nopar:Npn \int_new:N #1 {\alloc_reg:NnNN g {int} \tex_countdef:D#1} +\cs_new_nopar:Npn \int_new_l:N #1 {\alloc_reg:NnNN l {int} \tex_countdef:D#1} +%</initex> +% \end{macrocode} +% For `l3in2e': +% \begin{macrocode} +%<*package> +\cs_new_nopar:Npn \int_new:N #1 { + \chk_if_free_cs:N #1 + \newcount #1 +} +%</package> +% \end{macrocode} +% \begin{macrocode} +\cs_generate_variant:Nn \int_new:N {c} +% \end{macrocode} +% \end{macro} +%^^A \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} +\cs_new_nopar:Npn \int_set:Nn #1#2{#1 \intexpr_eval:w #2\intexpr_eval_end: +%<*check> +\chk_local_or_pref_global:N #1 +%</check> +} +\cs_new_nopar:Npn \int_gset:Nn { +%<*check> + \pref_global_chk: +%</check> +%<-check> \pref_global:D + \int_set:Nn } +\cs_generate_variant:Nn\int_set:Nn {cn} +\cs_generate_variant:Nn\int_gset:Nn {cn} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% % \begin{macro}{\int_incr:N} % \begin{macro}{\int_decr:N} % \begin{macro}{\int_gincr:N} @@ -471,17 +521,17 @@ % Incrementing and decrementing of integer registers is done with % the following functions. % \begin{macrocode} -\def_new:Npn \int_incr:N #1{\int_advance:w#1\c_one +\cs_new_nopar:Npn \int_incr:N #1{\int_advance:w#1\c_one %<*check> \chk_local_or_pref_global:N #1 %</check> } -\def_new:Npn \int_decr:N #1{\int_advance:w#1\c_minus_one +\cs_new_nopar:Npn \int_decr:N #1{\int_advance:w#1\c_minus_one %<*check> \chk_local_or_pref_global:N #1 %</check> } -\def_new:Npn \int_gincr:N { +\cs_new_nopar: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 @@ -496,7 +546,7 @@ %</check> %<-check> \pref_global:D \int_incr:N} -\def_new:Npn \int_gdecr:N { +\cs_new_nopar:Npn \int_gdecr:N { %<*check> \pref_global_chk: %</check> @@ -506,80 +556,41 @@ % 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} -\def:Npn \int_incr:c {\exp_args:Nc\int_incr:N} -\def:Npn \int_decr:c {\exp_args:Nc\int_decr:N} -\def:Npn \int_gincr:c {\exp_args:Nc\int_gincr:N} -\def:Npn \int_gdecr:c {\exp_args:Nc\int_gdecr:N} +\cs_set_nopar:Npn \int_incr:N #1{\int_add:Nn#1\c_one} +\cs_set_nopar:Npn \int_decr:N #1{\int_add:Nn#1\c_minus_one} +\cs_set_nopar:Npn \int_gincr:N #1{\int_gadd:Nn#1\c_one} +\cs_set_nopar:Npn \int_gdecr:N #1{\int_gadd:Nn#1\c_minus_one} % \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% -% -% \begin{macro}{\int_new:N} -% \begin{macro}{\int_new_l: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} -%<*initex> -\alloc_setup_type:nnn {int} \c_eleven \c_max_register_num -\def_new:Npn \int_new:N #1 {\alloc_reg:NnNN g {int} \tex_countdef:D#1} -\def_new:Npn \int_new_l:N #1 {\alloc_reg:NnNN l {int} \tex_countdef:D#1} -%</initex> -%<package>\let:NN \int_new:N \newcount% allocation better nick the LaTeX one... -\def_new:Npn \int_new:c {\exp_args:Nc \int_new:N} +\cs_generate_variant:Nn \int_incr:N {c} +\cs_generate_variant:Nn \int_decr:N {c} +\cs_generate_variant:Nn \int_gincr:N {c} +\cs_generate_variant:Nn \int_gdecr:N {c} % \end{macrocode} % \end{macro} % \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 \int_eval:w #2\int_eval_end: -%<*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} % \end{macro} % +% % \begin{macro}{\int_zero:N} % \begin{macro}{\int_zero:c} % \begin{macro}{\int_gzero:N} % \begin{macro}{\int_gzero:c} % Functions that reset an \m{int} register to zero. % \begin{macrocode} -\def_new:Npn \int_zero:N #1 {#1=\c_zero} -\def_new:Npn \int_zero:c #1 {\exp_args:Nc \int_zero:N} -\def_new:Npn \int_gzero:N #1 {\pref_global:D #1=\c_zero} -\def_new:Npn \int_gzero:c {\exp_args:Nc \int_gzero:N} +\cs_new_nopar:Npn \int_zero:N #1 {#1=\c_zero} +\cs_generate_variant:Nn \int_zero:N {c} +% \end{macrocode} +% +% \begin{macrocode} +\cs_new_nopar:Npn \int_gzero:N #1 {\pref_global:D #1=\c_zero} +\cs_generate_variant:Nn \int_gzero:N {c} % \end{macrocode} % \end{macro} % \end{macro} @@ -597,39 +608,39 @@ % 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{ +\cs_new_nopar:Npn \int_add:Nn #1#2{ % \end{macrocode} % We need to say |by| in case the first argument is a register % accessed by its number, e.g., |\count23|. Not that it should % ever happen but\dots % \begin{macrocode} - \int_advance:w #1 by \int_eval:w #2\int_eval_end: + \int_advance:w #1 by \intexpr_eval:w #2\intexpr_eval_end: %<*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{ - \int_advance:w #1-\int_eval:w #2\int_eval_end: +\cs_new_nopar:Npn \int_sub:Nn #1#2{ + \int_advance:w #1-\intexpr_eval:w #2\intexpr_eval_end: %<*check> \chk_local_or_pref_global:N #1 %</check> } -\def_new:Npn \int_gadd:Nn { +\cs_new_nopar:Npn \int_gadd:Nn { %<*check> \pref_global_chk: %</check> %<-check> \pref_global:D \int_add:Nn } -\def_new:Npn \int_gsub:Nn { +\cs_new_nopar:Npn \int_gsub:Nn { %<*check> \pref_global_chk: %</check> %<-check> \pref_global:D \int_sub:Nn } -\def_new:Npn \int_gadd:cn{\exp_args:Nc\int_gadd:Nn} -\def_new:Npn \int_sub:cn{\exp_args:Nc\int_sub:Nn} -\def_new:Npn \int_gsub:cn{\exp_args:Nc\int_gsub:Nn} +\cs_generate_variant:Nn \int_add:Nn {cn} +\cs_generate_variant:Nn \int_gadd:Nn {cn} +\cs_generate_variant:Nn \int_sub:Nn {cn} +\cs_generate_variant:Nn \int_gsub:Nn {cn} % \end{macrocode} % \end{macro} % \end{macro} @@ -645,8 +656,18 @@ % \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:} +\cs_new_eq:NN \int_use:N \tex_the:D +\cs_new_nopar:Npn \int_use:c #1{\int_use:N \cs:w#1\cs_end:} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\int_show:N} +% \begin{macro}{\int_show:c} +% Diagnostics. +% \begin{macrocode} +\cs_new_eq:NN \int_show:N \tex_showthe:D +\cs_new_nopar:Npn \int_show:c {\exp_args:Nc \int_show:N } % \end{macrocode} % \end{macro} % \end{macro} @@ -657,7 +678,7 @@ % \begin{macro}{\int_to_arabic:n} % Nothing exciting here. % \begin{macrocode} -\def_new:Npn \int_to_arabic:n #1{\int_to_number:w \int_eval:n{#1}} +\cs_new_nopar:Npn \int_to_arabic:n #1{ \intexpr_eval:n{#1}} % \end{macrocode} % \end{macro} % @@ -671,9 +692,9 @@ % character \TeX{} produces to the character we actually want which % will give us letters with category code~11.% % \begin{macrocode} -\def_new:Npn \int_roman_lcuc_mapping:Nnn #1#2#3{ - \def:cpn {int_to_lc_roman_#1:}{#2} - \def:cpn {int_to_uc_roman_#1:}{#3} +\cs_new_nopar:Npn \int_roman_lcuc_mapping:Nnn #1#2#3{ + \cs_set_nopar:cpn {int_to_lc_roman_#1:}{#2} + \cs_set_nopar:cpn {int_to_uc_roman_#1:}{#3} } % \end{macrocode} % \end{macro} @@ -701,18 +722,18 @@ % The commands for producing the lower and upper case roman numerals % run a loop on one character at a time and also carries some % information for upper or lower case with it. We put it through -% |\int_eval:n| first which is safer and more flexible. +% |\intexpr_eval:n| first which is safer and more flexible. % \begin{macrocode} -\def_new:Npn \int_to_roman:n #1 { - \exp_after:NN \int_to_roman_lcuc:NN \exp_after:NN l - \int_to_roman:w \int_eval:n {#1} Q +\cs_new_nopar:Npn \int_to_roman:n #1 { + \exp_after:wN \int_to_roman_lcuc:NN \exp_after:wN l + \int_to_roman:w \intexpr_eval:n {#1} Q } -\def_new:Npn \int_to_Roman:n #1 { - \exp_after:NN \int_to_roman_lcuc:NN \exp_after:NN u - \int_to_roman:w \int_eval:n {#1} Q +\cs_new_nopar:Npn \int_to_Roman:n #1 { + \exp_after:wN \int_to_roman_lcuc:NN \exp_after:wN u + \int_to_roman:w \intexpr_eval:n {#1} Q } -\def_new:Npn \int_to_roman_lcuc:NN #1#2{ - \cs_use:c {int_to_#1c_roman_#2:} +\cs_new_nopar:Npn \int_to_roman_lcuc:NN #1#2{ + \use:c {int_to_#1c_roman_#2:} \int_to_roman_lcuc:NN #1 } % \end{macrocode} @@ -743,20 +764,20 @@ % We do a little pre-expansion of the arguments below as they % otherwise have a tendency to grow quite large. % \begin{macrocode} -\def:Npn \int_convert_number_with_rule:nnN #1#2#3{ - \int_compare:nNnTF {#1}>{#2} +\cs_set_nopar:Npn \int_convert_number_with_rule:nnN #1#2#3{ + \intexpr_compare:nNnTF {#1}>{#2} { - \exp_args:No \int_convert_number_with_rule:nnN - { \int_use:N\int_div_truncate:nn {#1-1}{#2} }{#2} + \exp_args:Nf \int_convert_number_with_rule:nnN + { \intexpr_div_truncate:nn {#1-1}{#2} }{#2} #3 % \end{macrocode} % Note that we have to nudge our modulus function so it won't % return~$0$ as that wouldn't work with |\if_case:w| when that % expects a positive number to produce a letter. % \begin{macrocode} - \exp_args:No #3 { \int_use:N\int_eval:n{1+\int_mod:nn {#1-1}{#2}} } + \exp_args:Nf #3 { \intexpr_eval:n{1+\intexpr_mod:nn {#1-1}{#2}} } } - { \exp_args:No #3{ \int_use:N\int_eval:n{#1} } } + { \exp_args:Nf #3{ \intexpr_eval:n{#1} } } } % \end{macrocode} % As can be seen it is even simpler to convert to number systems @@ -770,7 +791,7 @@ % should have one such rule, as say in Danish there are 29 letters in % the alphabet. % \begin{macrocode} -\def_new:Npn \int_alph_default_conversion_rule:n #1{ +\cs_new_nopar:Npn \int_alph_default_conversion_rule:n #1{ \if_case:w #1 \or: a\or: b\or: c\or: d\or: e\or: f \or: g\or: h\or: i\or: j\or: k\or: l @@ -779,7 +800,7 @@ \or: y\or: z \fi: } -\def_new:Npn \int_Alph_default_conversion_rule:n #1{ +\cs_new_nopar:Npn \int_Alph_default_conversion_rule:n #1{ \if_case:w #1 \or: A\or: B\or: C\or: D\or: E\or: F \or: G\or: H\or: I\or: J\or: K\or: L @@ -799,11 +820,11 @@ % second argument of |\int_convert_number_with_rule:nnN| should of % course match the number of |\or:|s in the conversion rule. % \begin{macrocode} -\def_new:Npn \int_to_alph:n #1{ +\cs_new_nopar:Npn \int_to_alph:n #1{ \int_convert_number_with_rule:nnN {#1}{26} \int_alph_default_conversion_rule:n } -\def_new:Npn \int_to_Alph:n #1{ +\cs_new_nopar:Npn \int_to_Alph:n #1{ \int_convert_number_with_rule:nnN {#1}{26} \int_Alph_default_conversion_rule:n } @@ -814,7 +835,7 @@ % \begin{macro}{\int_to_symbol:n} % Turning a number into a symbol is also easy enough. % \begin{macrocode} -\def_new:Npn \int_to_symbol:n #1{ +\cs_new_nopar:Npn \int_to_symbol:n #1{ \mode_if_math:TF { \int_convert_number_with_rule:nnN {#1}{9} @@ -831,7 +852,7 @@ % \begin{macro}{\int_symbol_text_conversion_rule:n} % Nothing spectacular here. % \begin{macrocode} -\def_new:Npn \int_symbol_math_conversion_rule:n #1 { +\cs_new_nopar:Npn \int_symbol_math_conversion_rule:n #1 { \if_case:w #1 \or: * \or: \dagger @@ -844,7 +865,7 @@ \or: \ddagger\ddagger \fi: } -\def_new:Npn \int_symbol_text_conversion_rule:n #1 { +\cs_new_nopar:Npn \int_symbol_text_conversion_rule:n #1 { \if_case:w #1 \or: \textasteriskcentered \or: \textdagger @@ -866,7 +887,6 @@ % \begin{macro}{\l_tmpc_int} % \begin{macro}{\g_tmpa_int} % \begin{macro}{\g_tmpb_int} -% \begin{macro}{\l_loop_int} % We provide four local and two global scratch counters, maybe we % need more or less. % \begin{macrocode} @@ -875,202 +895,116 @@ \int_new:N \l_tmpc_int \int_new:N \g_tmpa_int \int_new:N \g_tmpb_int -\int_new:N \l_loop_int % a variable for use in loops (whilenum etc) % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} -% \end{macro} % % -% \begin{macro}{\int_eval:n} -% \begin{macro}{\int_eval:w} -% \begin{macro}{\int_eval_end:} -% Evaluating a calc expression using normal operators. Many of these -% are exactly the same as the ones in the \textsf{num} module so we -% just use them. -% \begin{macrocode} -\let_new:NN \int_eval:n \num_eval:n -\let_new:NN \int_eval:w \num_eval:w -\let_new:NN \int_eval_end: \num_eval_end: -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} % -% \begin{macro}{\c_max_int} -% The largest number allowed is $2^{31}-1$ -% \begin{macrocode} -\const_new:Nn \c_max_int {2147483647} -% \end{macrocode} -% \end{macro} % % \begin{macro}{\int_pre_eval_one_arg:Nn} % \begin{macro}{\int_pre_eval_two_args:Nnn} -% These might be handy when handing down values to other +% These are handy when handing down values to other % functions. All they do is evaluate the number in advance. % \begin{macrocode} -\def:Npn \int_pre_eval_one_arg:Nnn #1#2{\exp_args:No#1{\int_eval:w#2}} -\def:Npn \int_pre_eval_two_args:Nnn #1#2#3{ - \exp_args:Noo#1{\int_use:N\int_eval:w#2}{\int_use:N\int_eval:w#3} +\cs_set_nopar:Npn \int_pre_eval_one_arg:Nn #1#2{ + \exp_args:Nf#1{\intexpr_eval:n{#2}}} +\cs_set_nopar:Npn \int_pre_eval_two_args:Nnn #1#2#3{ + \exp_args:Nff#1{\intexpr_eval:n{#2}}{\intexpr_eval:n{#3}} } % \end{macrocode} % \end{macro} % \end{macro} % -% \begin{macro}{\int_div_truncate:nn} -% \begin{macro}{\int_div_round:nn} -% \begin{macro}{\int_mod:nn} -% \begin{macro}{\int_div_truncate_raw:nn} -% \begin{macro}{\int_div_round_raw:nn} -% \begin{macro}{\int_mod_raw:nn} -% As "\num_eval:w" rounds the result of a division we also -% provide a version that truncates the result. -% \begin{macrocode} -\def_new:Npn \int_div_truncate:nn { - \int_pre_eval_two_args:Nnn\int_div_truncate_raw:nn -} -% \end{macrocode} -% Initial version didn't work correctly with e\TeX's implementation. -% \begin{macrocode} -%\def_new:Npn \int_div_truncate_raw:nn #1#2 { -% \int_eval:n{ (2*#1 - #2) / (2* #2) } -%} -% \end{macrocode} -% New version by Heiko: -% \begin{macrocode} -\def_new:Npn \int_div_truncate_raw:nn #1#2 { - \int_eval:w - \if_num:w \int_eval:w#1 = \c_zero - 0 - \else: - (#1 - \if_num:w \int_eval:w #1 < \c_zero - \if_num:w \int_eval:w#2 < \c_zero - -( #2 + - \else: - +( #2 - - \fi: - \else: - \if_num:w \int_eval:w #2 < \c_zero - +( #2 + - \else: - -( #2 - - \fi: - \fi: - 1)/2) - \fi: - /(#2) - \int_eval_end: -} -% \end{macrocode} -% For the sake of completeness: -% \begin{macrocode} -\def_new:Npn \int_div_round:nn { - \int_pre_eval_two_args:Nnn\int_div_round_raw:nn -} -\def_new:Npn \int_div_round_raw:nn #1#2 {\int_eval:n{#1/#2}} -% \end{macrocode} -% Finally there's the modulus operation. -% \begin{macrocode} -\def_new:Npn \int_mod:nn {\int_pre_eval_two_args:Nnn\int_mod_raw:nn} -\def_new:Npn \int_mod_raw:nn #1#2 { - \int_eval:n{ #1 - \int_div_truncate_raw:nn {#1}{#2} * #2 } -} -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} % % -% \begin{macro}{\int_compare:nNnTF} -% \begin{macro}{\int_compare:nNnT} -% \begin{macro}{\int_compare:nNnF} -% Simple comparison tests. -% \begin{macrocode} -\let_new:NN \int_compare:nNnTF \num_compare:nNnTF -\let_new:NN \int_compare:nNnT \num_compare:nNnT -\let_new:NN \int_compare:nNnF \num_compare:nNnF -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} % -% \begin{macro}{\int_max_of:nn} -% \begin{macro}{\int_min_of:nn} -% \begin{macro}{\int_abs:n} -% Simple comparison tests. +% \subsection{Defining constants} +% \begin{macro}{\int_const:Nn} +% As stated, most constants can be defined as |\tex_chardef:D| or +% |\tex_mathchardef:D| but that's engine dependent. % \begin{macrocode} -\let_new:NN \int_max_of:nn \num_max_of:nn -\let_new:NN \int_min_of:nn \num_min_of:nn -\let_new:NN \int_abs:nn \num_abs:nn +\cs_new_nopar:Npn \int_const:Nn #1#2 { + \intexpr_compare:nNnTF {#2} > \c_minus_one { + \intexpr_compare:nNnTF {#2} > \c_max_register_num { + \int_new:N #1 \int_set:Nn #1{#2} + } { + \chk_if_free_cs:N #1 \tex_mathchardef:D #1 = \intexpr_eval:n{#2} + } + } { + \int_new:N #1 \int_set:Nn #1{#2} + } +} % \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% +% \end{macro} % -% \begin{macro}{\int_compare_p:nNn} -% A predicate function. +% \begin{macro}{\c_minus_one, +% \c_zero, \c_one, \c_two, \c_three, \c_four, \c_five, \c_six, +% \c_seven, \c_eight, \c_nine, \c_ten, +% \c_eleven, \c_twelve, \c_thirteen, \c_fourteen, \c_fifteen, +% \c_sixteen, \c_thirty_two, +% \c_hundred_one, +% \c_twohundred_fifty_five, \c_twohundred_fifty_six, +% \c_thousand, +% \c_ten_thousand, +% \c_ten_thousand_one, \c_ten_thousand_two, +% \c_ten_thousand_three, \c_ten_thousand_four, +% \c_twenty_thousand} +% 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} -\let_new:NN \int_compare_p:nNn \num_compare_p:nNn + %% \tex_countdef:D \c_minus_one = 10 \scan_stop: + %% \c_minus_one = -1 \scan_stop: %% in l3basics +%\int_const:Nn \c_zero {0} +\int_const:Nn \c_one {1} +\int_const:Nn \c_two {2} +\int_const:Nn \c_three {3} +\int_const:Nn \c_four {4} +\int_const:Nn \c_five {5} +\int_const:Nn \c_six {6} +\int_const:Nn \c_seven {7} +\int_const:Nn \c_eight {8} +\int_const:Nn \c_nine {9} +\int_const:Nn \c_ten {10} +\int_const:Nn \c_eleven {11} +\int_const:Nn \c_twelve {12} +\int_const:Nn \c_thirteen {13} +\int_const:Nn \c_fourteen {14} +\int_const:Nn \c_fifteen {15} + %% \tex_chardef:D \c_sixteen = 16\scan_stop: %% in l3basics +\int_const:Nn \c_thirty_two {32} % \end{macrocode} -% \end{macro} -% -% \begin{macro}{\int_if_odd_p:n} -% \begin{macro}{\int_if_odd:nTF} -% \begin{macro}{\int_if_odd:nT} -% \begin{macro}{\int_if_odd:nF} -% A predicate function. +% The next one may seem a little odd (obviously!) but is useful when +% dealing with logical operators. % \begin{macrocode} -\def_new:Npn \int_if_odd_p:n #1 { - \if_num_odd:w \int_eval:n{#1} - \c_true - \else: - \c_false - \fi: -} -\def_test_function_new:npn {int_if_odd:n}#1{\if_num_odd:w \int_eval:n{#1}} +\int_const:Nn \c_hundred_one {101} +\int_const:Nn \c_twohundred_fifty_five{255} +\int_const:Nn \c_twohundred_fifty_six {256} +\int_const:Nn \c_thousand {1000} +\int_const:Nn \c_ten_thousand {10000} +\int_const:Nn \c_ten_thousand_one {10001} +\int_const:Nn \c_ten_thousand_two {10002} +\int_const:Nn \c_ten_thousand_three {10003} +\int_const:Nn \c_ten_thousand_four {10004} +\int_const:Nn \c_twenty_thousand {20000} % \end{macrocode} % \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} % -% \begin{macro}{\int_whiledo:nNnT} -% \begin{macro}{\int_whiledo:nNnF} -% \begin{macro}{\int_dowhile:nNnT} -% \begin{macro}{\int_dowhile:nNnF} -% These are quite easy given the above functions. The "while" versions -% test first and then execute the body. The "dowhile" does it the -% other way round. The have to be defined as ``long'' since the "T" argument -% might contain "\par" tokens. +% \begin{macro}{\c_max_int} +% The largest number allowed is $2^{31}-1$ % \begin{macrocode} -\def_long_new:Npn \int_whiledo:nNnT #1#2#3#4{ - \int_compare:nNnT {#1}#2{#3}{#4 \int_whiledo:nNnT {#1}#2{#3}{#4}} -} -\def_long_new:Npn \int_whiledo:nNnF #1#2#3#4{ - \int_compare:nNnF {#1}#2{#3}{#4 \int_whiledo:nNnF {#1}#2{#3}{#4}} -} -\def_long_new:Npn \int_dowhile:nNnT #1#2#3#4{ - #4 \int_compare:nNnT {#1}#2{#3}{\int_dowhile:nNnT {#1}#2{#3}{#4}} -} -\def_long_new:Npn \int_dowhile:nNnF #1#2#3#4{ - #4 \int_compare:nNnF {#1}#2{#3}{\int_dowhile:nNnF {#1}#2{#3}{#4}} -} +\int_const:Nn \c_max_int {2147483647} % \end{macrocode} % \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} % % -% \subsubsection{Scanning and conversion} +% +% \subsection{Scanning and conversion} % % % Conversion between different numbering schemes requires meticulous @@ -1081,54 +1015,50 @@ % \begin{macro}{\int_get_sign_and_digits:n} % \begin{macro}{\int_get_sign:n} % \begin{macro}{\int_get_digits:n} -% \begin{macro}{\int_get_sign_and_digits_aux:nNNN} -% \begin{macro}{\int_get_sign_and_digits_aux:oNNN} +% \begin{macro}[aux]{\int_get_sign_and_digits_aux:nNNN} +% \begin{macro}[aux]{\int_get_sign_and_digits_aux:oNNN} % A number may be preceeded by any number of |+|s and |-|s. Start out % by assuming we have a positive number. % \begin{macrocode} -\def_new:Npn \int_get_sign_and_digits:n #1{ - \int_get_sign_and_digits_aux:nNNN {#1} \c_true \c_true \c_true +\cs_new_nopar:Npn \int_get_sign_and_digits:n #1{ + \int_get_sign_and_digits_aux:nNNN {#1} \c_true_bool \c_true_bool \c_true_bool } -\def_new:Npn \int_get_sign:n #1{ - \int_get_sign_and_digits_aux:nNNN {#1} \c_true \c_true \c_false +\cs_new_nopar:Npn \int_get_sign:n #1{ + \int_get_sign_and_digits_aux:nNNN {#1} \c_true_bool \c_true_bool \c_false_bool } -\def_new:Npn \int_get_digits:n #1{ - \int_get_sign_and_digits_aux:nNNN {#1} \c_true \c_false \c_true +\cs_new_nopar:Npn \int_get_digits:n #1{ + \int_get_sign_and_digits_aux:nNNN {#1} \c_true_bool \c_false_bool \c_true_bool } % \end{macrocode} % Now check the first character in the string. Only a |-| can change % if a number is positive or negative, hence we reverse the boolean % governing this. Then gobble the |-| and start over. % \begin{macrocode} -\def_new:Npn \int_get_sign_and_digits_aux:nNNN #1#2#3#4{ - \tlist_if_head_eq_charcode:fNTF {#1} - +\cs_new_nopar:Npn \int_get_sign_and_digits_aux:nNNN #1#2#3#4{ + \tl_if_head_eq_charcode:fNTF {#1} - { \bool_if:NTF #2 - { \int_get_sign_and_digits_aux:oNNN {\use_none:n #1} \c_false #3#4 } - { \int_get_sign_and_digits_aux:oNNN {\use_none:n #1} \c_true #3#4 } + { \int_get_sign_and_digits_aux:oNNN {\use_none:n #1} \c_false_bool #3#4 } + { \int_get_sign_and_digits_aux:oNNN {\use_none:n #1} \c_true_bool #3#4 } } % \end{macrocode} % The other cases are much simpler since we either just have to gobble % the |+| or exit immediately and insert the correct sign. % \begin{macrocode} { - \tlist_if_head_eq_charcode:fNTF {#1} + + \tl_if_head_eq_charcode:fNTF {#1} + { \int_get_sign_and_digits_aux:oNNN {\use_none:n #1} #2#3#4} { % \end{macrocode} % The boolean |#3| is for printing the sign while |#4| is for printing % the digits. % \begin{macrocode} - \bool_double_if:NNnnnn #3#4 - { \bool_if:NF #2 - #1 } - { \bool_if:NF #2 - } - { #1 } { } + \bool_if:NT #3 { \bool_if:NF #2 - } + \bool_if:NT #4 {#1} } } } -\def_new:Npn \int_get_sign_and_digits_aux:oNNN{ - \exp_args:No\int_get_sign_and_digits_aux:nNNN -} +\cs_generate_variant:Nn \int_get_sign_and_digits_aux:nNNN {oNNN} % \end{macrocode} % \end{macro} % \end{macro} @@ -1138,23 +1068,23 @@ % % % \begin{macro}{\int_convert_from_base_ten:nn} -% \begin{macro}{\int_convert_from_base_ten_aux:nnn} -% \begin{macro}{\int_convert_from_base_ten_aux:non} -% \begin{macro}{\int_convert_from_base_ten_aux:fon} +% \begin{macro}[aux]{\int_convert_from_base_ten_aux:nnn} +% \begin{macro}[aux]{\int_convert_from_base_ten_aux:non} +% \begin{macro}[aux]{\int_convert_from_base_ten_aux:fon} % |#1| is the base 10 number to be converted to base |#2|. We split % off the sign first, print if if there and then convert only the % number. Since this is supposedly a base~10 number we can let \TeX\ % do the reading of |+| and |-|. % \begin{macrocode} -\def:Npn \int_convert_from_base_ten:nn#1#2{ - \num_compare:nNnTF {#1}<\c_zero +\cs_set_nopar:Npn \int_convert_from_base_ten:nn#1#2{ + \intexpr_compare:nNnTF {#1}<\c_zero { - - \int_convert_from_base_ten_aux:non {} - { \int_use:N \int_eval:n {-#1} } + - \int_convert_from_base_ten_aux:nfn {} + { \intexpr_eval:n {-#1} } } { - \int_convert_from_base_ten_aux:non {} - { \int_use:N \int_eval:n {#1} } + \int_convert_from_base_ten_aux:nfn {} + { \intexpr_eval:n {#1} } } {#2} } @@ -1173,44 +1103,42 @@ % |#1| is the carried over result, |#2| the remainder and |#3| the % base number. % \begin{macrocode} -\def_new:Npn \int_convert_from_base_ten_aux:nnn#1#2#3{ - \num_compare:nNnTF {#2}<{#3} +\cs_new_nopar:Npn \int_convert_from_base_ten_aux:nnn#1#2#3{ + \intexpr_compare:nNnTF {#2}<{#3} { \int_convert_number_to_letter:n{#2} #1 } { - \int_convert_from_base_ten_aux:fon + \int_convert_from_base_ten_aux:ffn { - \int_convert_number_to_letter:n {\int_use:N\int_mod_raw:nn {#2}{#3}} + \int_convert_number_to_letter:n {\intexpr_mod:nn {#2}{#3}} #1 } - {\int_use:N \int_div_truncate_raw:nn{#2}{#3}} + { \intexpr_div_truncate:nn{#2}{#3}} {#3} } } -\def:Npn \int_convert_from_base_ten_aux:non{ - \exp_args:Nno\int_convert_from_base_ten_aux:nnn -} -\def:Npn \int_convert_from_base_ten_aux:fon{ - \exp_args:Nfo\int_convert_from_base_ten_aux:nnn -} +\cs_generate_variant:Nn \int_convert_from_base_ten_aux:nnn {nfn} +\cs_generate_variant:Nn \int_convert_from_base_ten_aux:nnn {ffn} % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} +% % \begin{macro}{\int_convert_number_to_letter:n} % Turning a number for a different base into a letter or digit. % \begin{macrocode} -\def:Npn \int_convert_number_to_letter:n #1{ \if_case:w \int_eval:w - #1-10\scan_stop: \exp_after:NN A \or: \exp_after:NN B \or: - \exp_after:NN C \or: \exp_after:NN D \or: \exp_after:NN E \or: - \exp_after:NN F \or: \exp_after:NN G \or: \exp_after:NN H \or: - \exp_after:NN I \or: \exp_after:NN J \or: \exp_after:NN K \or: - \exp_after:NN L \or: \exp_after:NN M \or: \exp_after:NN N \or: - \exp_after:NN O \or: \exp_after:NN P \or: \exp_after:NN Q \or: - \exp_after:NN R \or: \exp_after:NN S \or: \exp_after:NN T \or: - \exp_after:NN U \or: \exp_after:NN V \or: \exp_after:NN W \or: - \exp_after:NN X \or: \exp_after:NN Y \or: \exp_after:NN Z \else: - \use_arg_i_after_fi:nw{ #1 }\fi: } +\cs_set_nopar:Npn \int_convert_number_to_letter:n #1{ + \if_case:w \intexpr_eval:w #1-10\intexpr_eval_end: + \exp_after:wN A \or: \exp_after:wN B \or: + \exp_after:wN C \or: \exp_after:wN D \or: \exp_after:wN E \or: + \exp_after:wN F \or: \exp_after:wN G \or: \exp_after:wN H \or: + \exp_after:wN I \or: \exp_after:wN J \or: \exp_after:wN K \or: + \exp_after:wN L \or: \exp_after:wN M \or: \exp_after:wN N \or: + \exp_after:wN O \or: \exp_after:wN P \or: \exp_after:wN Q \or: + \exp_after:wN R \or: \exp_after:wN S \or: \exp_after:wN T \or: + \exp_after:wN U \or: \exp_after:wN V \or: \exp_after:wN W \or: + \exp_after:wN X \or: \exp_after:wN Y \or: \exp_after:wN Z \else: + \use_i_after_fi:nw{ #1 }\fi: } % \end{macrocode} % \end{macro} % @@ -1219,8 +1147,8 @@ % use only the digits/letters from it and pass that onto a new % function. % \begin{macrocode} -\def:Npn \int_convert_to_base_ten:nn #1#2 { - \int_use:N\int_eval:n{ +\cs_set_nopar:Npn \int_convert_to_base_ten:nn #1#2 { + \intexpr_eval:n{ \int_get_sign:n{#1} \exp_args:Nf\int_convert_to_base_ten_aux:nn {\int_get_digits:n{#1}}{#2} } @@ -1228,7 +1156,7 @@ % \end{macrocode} % This is an intermediate function to get things started. % \begin{macrocode} -\def_new:Npn \int_convert_to_base_ten_aux:nn #1#2{ +\cs_new_nopar:Npn \int_convert_to_base_ten_aux:nn #1#2{ \int_convert_to_base_ten_auxi:nnN {0}{#2} #1 \q_nil } % \end{macrocode} @@ -1236,11 +1164,11 @@ % is the previously calculated result (to be multiplied by the base), % |#2| is the base and |#3| is the next letter/digit to be added. % \begin{macrocode} -\def_new:Npn \int_convert_to_base_ten_auxi:nnN#1#2#3{ +\cs_new_nopar:Npn \int_convert_to_base_ten_auxi:nnN#1#2#3{ \quark_if_nil:NTF #3 {#1} - {\exp_args:No\int_convert_to_base_ten_auxi:nnN - {\int_use:N \int_eval:n{ #1*#2+\int_convert_letter_to_number:N #3} } + {\exp_args:Nf\int_convert_to_base_ten_auxi:nnN + {\intexpr_eval:n{ #1*#2+\int_convert_letter_to_number:N #3} } {#2} } } @@ -1249,80 +1177,30 @@ % also takes care of handling lowercase and uppercase letters. Hence % |a| is turned into |11| and so is |A|. % \begin{macrocode} -\def:Npn \int_convert_letter_to_number:N #1{ - \int_compare:nNnTF{`#1}<{58}{#1} +\cs_set_nopar:Npn \int_convert_letter_to_number:N #1{ + \intexpr_compare:nNnTF{`#1}<{58}{#1} { - \int_eval:n{ `#1 - - \if:w\int_compare_p:nNn{`#1}<{91} - 55 - \else: - 87 - \fi: + \intexpr_eval:n{ `#1 - + \intexpr_compare:nNnTF{`#1}<{91}{ 55 }{ 87 } } } } % \end{macrocode} % \end{macro} % -% -% -% -% -% +% \begin{macrocode} +%</initex|package> +% \end{macrocode} % % Show token usage: % \begin{macrocode} -%</initex|package> %<*showmemory> \showMemUsage %</showmemory> % \end{macrocode} % +% \end{implementation} +% \PrintIndex % -% \endinput -% -% $Log$ -% Revision 1.26 2006/06/03 17:17:08 morten -% Functions for converting between number bases -% -% Revision 1.25 2006/03/20 18:26:35 braams -% Updated the copyright notice (2006) and demoted all implementation -% sections to subsections and so on to clean up the toc for source3.tex -% -% Revision 1.24 2006/01/17 22:47:43 morten -% Changed \int_while:nNnT to \int_whiledo:nNnT to avoid confusion with -% the dowhile versions. -% -% Revision 1.23 2005/12/27 10:02:37 morten -% Minor changes plus changed RCS information retrieval -% -% Revision 1.22 2005/12/21 20:43:32 morten -% Fixed silly bugs! -% -% Revision 1.21 2005/12/06 17:31:23 morten -% fixed \int_convert_number_with_rule:nnN -% -% Revision 1.20 2005/12/06 14:49:36 morten -% Fixed primitive names plus a few minor touch-ups -% -% Revision 1.19 2005/04/25 15:02:47 morten -% Added ifodd functions -% -% Revision 1.18 2005/04/09 21:07:39 morten -% Added (extensible) implementations of \int_to_roman:n etc. -% -% Revision 1.17 2005/04/06 22:35:43 braams -% Now we have register allocation fitted -% -% Revision 1.16 2005/03/25 23:48:47 braams -% Added a missing \end{macro} -% -% Revision 1.15 2005/03/22 23:22:09 morten -% Moved definitions of constants to l3num -% -% Revision 1.14 2005/03/16 22:36:30 braams -% Added the tweaks necessary to be able to load with initex -% -% Revision 1.13 2005/03/11 21:38:31 braams -% Fixed the use of RCS information; added \StopEventually % +% \endinput diff --git a/Master/texmf-dist/source/latex/expl3/l3intexpr.dtx b/Master/texmf-dist/source/latex/expl3/l3intexpr.dtx new file mode 100644 index 00000000000..6b454a8ab80 --- /dev/null +++ b/Master/texmf-dist/source/latex/expl3/l3intexpr.dtx @@ -0,0 +1,642 @@ +% \iffalse +%% File: l3intexpr.dtx Copyright (C) 2009 LaTeX3 project +%% +%% It may be distributed and/or modified under the conditions of the +%% LaTeX Project Public License (LPPL), either version 1.3c of this +%% license or (at your option) any later version. The latest version +%% of this license is in the file +%% +%% http://www.latex-project.org/lppl.txt +%% +%% This file is part of the ``expl3 bundle'' (The Work in LPPL) +%% and all files in that bundle must be distributed together. +%% +%% The released version of this bundle is available from CTAN. +%% +%% ----------------------------------------------------------------------- +%% +%% The development version of the bundle can be found at +%% +%% http://www.latex-project.org/svnroot/experimental/trunk/ +%% +%% for those people who are interested. +%% +%%%%%%%%%%% +%% NOTE: %% +%%%%%%%%%%% +%% +%% Snapshots taken from the repository represent work in progress and may +%% not work or may contain conflicting material! We therefore ask +%% people _not_ to put them into distributions, archives, etc. without +%% prior consultation with the LaTeX Project Team. +%% +%% ----------------------------------------------------------------------- +% +%<*driver|package> +\RequirePackage{l3names} +%</driver|package> +%\fi +\GetIdInfo$Id: l3intexpr.dtx 1086 2009-03-20 19:29:35Z morten $ + {L3 Integer Expressions} +%\iffalse +%<*driver> +%\fi +\ProvidesFile{\filename.\filenameext} + [\filedate\space v\fileversion\space\filedescription] +%\iffalse +\documentclass[full]{l3doc} +\begin{document} +\DocInput{\filename.\filenameext} +\end{document} +%</driver> +% \fi +% +% +% \title{The \textsf{l3intexpr} package\thanks{This file +% has version number \fileversion, last +% revised \filedate.}\\ +% Integer expressions} +% \author{\Team} +% \date{\filedate} +% \maketitle +% +% \begin{documentation} +% +% This module sets up evaluation of integer expressions and allows +% mixing |int| and |num| registers. +% +% An integer expression is one that contains integers in the form of +% numbers, registers containg numbers, i.e., |int| and |num| registers +% plus constants like |\c_one|, standard operators "+", "-", "/" and +% "*" and parentheses to group sub-expressions. +% +% \section{Functions} +% +% \begin{function}{% +% \intexpr_eval:n / (EXP) +% } +% \begin{syntax} +% "\intexpr_eval:n" \Arg{int~expr} +% \end{syntax} +% The result of this expansion is a properly terminated <number>, +% i.e., one that can be used with "\if_case:w" and others. For example, +% \begin{quote} +% |\intexpr_eval:n{ 5 + 4*3 - (3+4*5) }| +% \end{quote} +% evaluates to $-6$. The result is returned after two expansions so +% if you find that you need to pass on the result to another function +% using the expansion engine, the recommendation is to use an "f" type +% expansion if in an expandable context or "x" otherwise. +% \end{function} +% +% +% \begin{function}{% +% \intexpr_compare_p:n / (EXP) | +% \intexpr_compare:n / (TF)(EXP) +% } +% \begin{syntax} +% "\intexpr_compare_p:n" \Arg{<int~expr1> <rel> <int~expr2>} +% \end{syntax} +% Compares <int~expr1> with <int~expr2> using C-like relational +% operators, i.e. +% \begin{center} +% \begin{tabular}{ll@{\hspace{2cm}}ll} +% Less than & "<" & Less than or equal & "<=" \\ +% Greater than & "<" & Greater than or equal & ">=" \\ +% Equal & "==" or "=" & Not equal & "!=" +% \end{tabular} +% \end{center} +% Both integer expressions are evaluated fully in the process. Note +% the syntax, which allows natural input in the style of +% \begin{quote} +% |\intexpr_compare_p:n {5+3 != \l_tmpb_int}| +% \end{quote} +% "=" is added for the sake of \TeX\ users accustomed to using a +% single equal sign. +% \end{function} +% +% +% \begin{function}{% +% \intexpr_compare_p:nNn / (EXP) | +% \intexpr_compare:nNn / (TF)(EXP) +% } +% \begin{syntax} +% "\intexpr_compare_p:nNn" \Arg{int~expr1}<rel>\Arg{int~expr2} +% \end{syntax} +% Compares <int~expr1> with <int~expr2> using one of the relations +% "=", ">" or "<". This is faster than the variant above but at the +% cost of requiring a little more typing and not supporting the +% extended set of relational operators. Note that if both expressions +% are normal integer variables as in +% \begin{quote} +% "\intexpr_compare:nNnTF \l_temp_int < \c_zero {negative}{non-negative}" +% \end{quote} +% you can safely omit the braces. +% \end{function} +% +% +% \begin{function}{% +% \intexpr_max:nn / (EXP)| +% \intexpr_min:nn / (EXP)| +% } +% \begin{syntax} +% "\intexpr_max:nn" \Arg{int~expr1} \Arg{int~expr2} +% \end{syntax} +% Return the largest or smallest of two integer expressions. +% \end{function} +% +% \begin{function}{% +% \intexpr_abs:n / (EXP)| +% } +% \begin{syntax} +% "\intexpr_abs:n" \Arg{int~expr} +% \end{syntax} +% Return the numerical value of an integer expression. +% \end{function} +% +% \begin{function}{% +% \intexpr_if_odd:n / (EXP)(TF) | +% \intexpr_if_odd_p:n / (EXP) | +% \intexpr_if_even:n / (EXP)(TF) | +% \intexpr_if_even_p:n / (EXP) | +% } +% \begin{syntax} +% "\intexpr_if_odd:nTF" \Arg{int~expr} \Arg{true} \Arg{false} +% \end{syntax} +% These functions test if an integer expression is even or odd. +% \end{function} +% +% +% +% +% +% +% \begin{function}{% +% \intexpr_div_truncate:nn / (EXP) | +% \intexpr_div_round:nn / (EXP) | +% \intexpr_mod:nn / (EXP) | +% } +% \begin{syntax} +% "\intexpr_div_truncate:n" \Arg{int~expr} \Arg{int~expr} \\ +% "\intexpr_mod:nn" \Arg{int~expr} \Arg{int~expr} +% \end{syntax} +% If +% you want the result of a division to be truncated use +% "\intexpr_div_truncate:nn". "\intexpr_div_round:nn" is added for +% completeness. "\intexpr_mod:nn" returns the remainder of a division. +% \end{function} +% +% +% +% +% +% +% +% +% +% +% +% \section{Primitive functions} +% +% +% \begin{function}{% +% \intexpr_value:w | +% } +% \begin{syntax} +% "\intexpr_value:w" <integer> \\ +% "\intexpr_value:w" <tokens> <optional space> +% \end{syntax} +% Expands <tokens> until an <integer> is formed. One space may be +% gobbled in the process. +% \begin{texnote} +% This is the \TeX{} primitive \tn{number}. +% \end{texnote} +% \end{function} +% +% \begin{function}{% +% \intexpr_eval:w | +% \intexpr_eval_end: | +% } +% \begin{syntax} +% "\intexpr_eval:w" <int expr> "\intexpr_eval_end:" +% \end{syntax} +% Evaluates <int expr>. The evaluation stops when an +% unexpandable token of catcode other than 12 is reached or +% "\intexpr_end:" is read. The latter is gobbled by the scanner +% mechanism. +% \begin{texnote} +% This is the \eTeX{} primitive \tn{numexpr}. +% \end{texnote} +% \end{function} +% +% \begin{function}{% +% \if_intexpr_compare:w | +% } +% \begin{syntax} +% "\if_intexpr_compare:w" <number1> <rel> <number2> <true> "\else:" <false> "\fi:" +% \end{syntax} +% Compare two numbers. It is recommended to use "\intexpr_eval:n" to +% correctly evaluate and terminate these numbers. <rel> is one of +% "<", "=" or ">" with catcode 12. +% \begin{texnote} +% This is the \TeX{} primitive \tn{ifnum}. +% \end{texnote} +% \end{function} +% +% \begin{function}{% +% \if_intexpr_odd:w | +% } +% \begin{syntax} +% "\if_intexpr_odd:w" <number> <true> "\else:" <false> "\fi:" +% \end{syntax} +% Execute <true> if <number> is odd, <false> otherwise. +% \begin{texnote} +% This is the \TeX{} primitive \tn{ifodd}. +% \end{texnote} +% \end{function} +% +% \begin{function}{% +% \if_intexpr_case:w | +% \or: | +% } +% \begin{syntax} +% "\if_intexpr_case:w" <number> <case0> "\or:" <case1> "\or:" "..." "\else:" +% <default> "\fi:" +% \end{syntax} +% Chooses case <number>. If you wish to use negative numbers as well, +% you can offset them with "\intexpr_eval:n". +% \begin{texnote} +% These are the \TeX{} primitives \tn{ifcase} and \tn{or}. +% \end{texnote} +% \end{function} +% +% +% +% \begin{function}{% +% \intexpr_while_do:nn | +% \intexpr_until_do:nn | +% \intexpr_do_while:nn | +% \intexpr_do_until:nn | +% } +% \begin{syntax} +% "\intexpr_while_do:nn" \Arg{<int~expr1> <rel> <int~expr2>} \Arg{code} +% \end{syntax} +% "\intexpr_while_do:nn" tests the integer expressions against each +% other using a C-like <rel> as in "\intexpr_compare_p:n" and if true +% performs the <code> until the test fails. "\intexpr_do_while:nn" is +% similar but executes the <code> first and then performs the check, +% thus ensuring that the body is executed at least once. The `until' +% versions are similar but continue the loop as long as the test is +% false. They could be omitted as it is just a matter of switching the +% arguments in the test. +% \end{function} +% +% \begin{function}{% +% \intexpr_while_do:nNnn | +% \intexpr_until_do:nNnn | +% \intexpr_do_while:nNnn | +% \intexpr_do_until:nNnn | +% } +% \begin{syntax} +% "\intexpr_while_do:nNnn" <int expr> <rel> <int~expr> \Arg{code} +% \end{syntax} +% Exactly as above but instead using the syntax of +% "\intexpr_compare_p:nNn". +% \end{function} +% +% +% +% +% +% \end{documentation} +% +% \begin{implementation} +% +% \section{\pkg{l3intexpr} implementation} +% +% +% We start by ensuring that the required packages are loaded. +% \begin{macrocode} +%<*package> +\ProvidesExplPackage + {\filename}{\filedate}{\fileversion}{\filedescription} +\package_check_loaded_expl: +%</package> +%<*initex|package> +% \end{macrocode} +% +% \begin{macro}{\intexpr_value:w} +% \begin{macro}{\intexpr_eval:n,\intexpr_eval:w,\intexpr_eval_end:} +% \begin{macro}{\if_intexpr_compare:w} +% \begin{macro}{\if_intexpr_odd:w} +% \begin{macro}{\if_intexpr_case:w} +% Here are the remaining primitives for number comparisons and +% expressions. +% \begin{macrocode} +\cs_set_eq:NN \intexpr_value:w \tex_number:D +\cs_set_eq:NN \intexpr_eval:w \etex_numexpr:D +\cs_set_protected:Npn \intexpr_eval_end: {\tex_relax:D} +\cs_set_eq:NN \if_intexpr_compare:w \tex_ifnum:D +\cs_set_eq:NN \if_intexpr_odd:w \tex_ifodd:D +\cs_set_eq:NN \if_intexpr_case:w \tex_ifcase:D +\cs_set:Npn \intexpr_eval:n #1{ + \intexpr_value:w \intexpr_eval:w #1\intexpr_eval_end: +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% +% +% +% +% \begin{macro}{\intexpr_compare_p:n} +% \begin{macro}[TF]{\intexpr_compare:n} +% Comparison tests using a simple syntax where only one set of braces +% is required and additional operators such as "!=" and ">=" are +% supported. First some notes on the idea behind this. We wish to +% support writing code like +% \begin{verbatim} +% \intexpr_compare_p:n { 5 + \l_tmpa_int != 4 - \l_tmpb_int } +% \end{verbatim} +% In other words, we want to somehow add the missing "\intexpr_eval:w" +% where required. We can start evaluating from the left using +% "\intexpr:w", and we know that since the relation symbols "<", ">", +% "=" and "!" are not allowed in such expressions, they will terminate +% the expression. Therefore, we first let \TeX\ evaluate this left +% hand side of the (in)equality. +% \begin{macrocode} +\prg_set_conditional:Npnn \intexpr_compare:n #1{p,TF,T,F}{ + \exp_after:wN \intexpr_compare_auxi:w \intexpr_value:w + \intexpr_eval:w #1\q_stop +} +% \end{macrocode} +% Then the next step is to figure out which relation we should use, so +% we have to somehow get rid of the first evaluation so that we can +% see what stopped it. "\tex_romannumeral:D" is handy here since its +% expansion given a non-positive number is \m{null}. We therefore +% simply check if the first token of the left hand side evaluation is +% a minus. If not, we insert it and issue "\tex_romannumeral:D", +% thereby ridding us of the left hand side evaluation. We do however +% save it for later. +% \begin{macrocode} +\cs_set:Npn \intexpr_compare_auxi:w #1#2\q_stop{ + \exp_after:wN \intexpr_compare_auxii:w \tex_romannumeral:D + \if:w #1- \else: -\fi: #1#2 \q_stop #1#2 \q_nil +} +% \end{macrocode} +% This leaves the first relation symbol in front and assuming the +% right hand side has been input, at least one other token as well. We +% support the following forms: |=|, |<|, |>| and the extended |!=|, +% |==|, |<=| and |>=|. All the extended forms have an extra |=| so we +% check if that is present as well. Then use specific function to +% perform the test. +% \begin{macrocode} +\cs_set:Npn \intexpr_compare_auxii:w #1#2#3\q_stop{ + \use:c{ + intexpr_compare_ + #1 \if_meaning:w =#2 = \fi: + :w} +} +% \end{macrocode} +% The actual comparisons are then simple function calls, using the +% relation as delimiter for a delimited argument. +% Equality is easy: +% \begin{macrocode} +\cs_set:cpn {intexpr_compare_=:w} #1=#2\q_nil{ + \if_intexpr_compare:w #1=\intexpr_eval:w #2 \intexpr_eval_end: + \prg_return_true: \else: \prg_return_false: \fi: +} +% \end{macrocode} +% So is the one using |==| -- we just have to use |==| in the +% parameter text. +% \begin{macrocode} +\cs_set:cpn {intexpr_compare_==:w} #1==#2\q_nil{ + \if_intexpr_compare:w #1=\intexpr_eval:w #2 \intexpr_eval_end: + \prg_return_true: \else: \prg_return_false: \fi: +} +% \end{macrocode} +% Not equal is just about reversing the truth value. +% \begin{macrocode} +\cs_set:cpn {intexpr_compare_!=:w} #1!=#2\q_nil{ + \if_intexpr_compare:w #1=\intexpr_eval:w #2 \intexpr_eval_end: + \prg_return_false: \else: \prg_return_true: \fi: +} +% \end{macrocode} +% Less than and greater than are also straight forward. +% \begin{macrocode} +\cs_set:cpn {intexpr_compare_<:w} #1<#2\q_nil{ + \if_intexpr_compare:w #1<\intexpr_eval:w #2 \intexpr_eval_end: + \prg_return_true: \else: \prg_return_false: \fi: +} +\cs_set:cpn {intexpr_compare_>:w} #1>#2\q_nil{ + \if_intexpr_compare:w #1>\intexpr_eval:w #2 \intexpr_eval_end: + \prg_return_true: \else: \prg_return_false: \fi: +} +% \end{macrocode} +% For the less than or equal operation, we simply add $1$ to the right +% hand side and then use a less than test. A similar trick for the +% greater than or equal test except there we subtract $1$. +% \begin{macrocode} +\cs_set:cpn {intexpr_compare_<=:w} #1<=#2\q_nil{ + \if_intexpr_compare:w #1<\intexpr_eval:w #2 +\c_one \intexpr_eval_end: + \prg_return_true: \else: \prg_return_false: \fi: +} +\cs_set:cpn {intexpr_compare_>=:w} #1>=#2\q_nil{ + \if_intexpr_compare:w #1>\intexpr_eval:w #2 - \c_one \intexpr_eval_end: + \prg_return_true: \else: \prg_return_false: \fi: +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\intexpr_compare_p:nNn} +% \begin{macro}[TF]{\intexpr_compare:nNn} +% More efficient but less natural in typing. +% \begin{macrocode} +\prg_set_conditional:Npnn \intexpr_compare:nNn #1#2#3{p,TF,T,F}{ + \if_intexpr_compare:w \intexpr_eval:w #1 #2 \intexpr_eval:w #3 \intexpr_eval_end: + \prg_return_true: \else: \prg_return_false: \fi: +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\intexpr_max:nn} +% \begin{macro}{\intexpr_min:nn} +% \begin{macro}{\intexpr_abs:n} +% Functions for $\min$, $\max$, and absolute value. +% \begin{macrocode} +\cs_set:Npn \intexpr_abs:n #1{ + \intexpr_value:w + \if_intexpr_compare:w \intexpr_eval:w #1<\c_zero + - + \fi: + \intexpr_eval:w #1\intexpr_eval_end: +} +\cs_set:Npn \intexpr_max:nn #1#2{ + \intexpr_value:w \intexpr_eval:w + \if_intexpr_compare:w + \intexpr_eval:w #1>\intexpr_eval:w #2\intexpr_eval_end: + #1 + \else: + #2 + \fi: + \intexpr_eval_end: +} +\cs_set:Npn \intexpr_min:nn #1#2{ + \intexpr_value:w \intexpr_eval:w + \if_intexpr_compare:w + \intexpr_eval:w #1<\intexpr_eval:w #2\intexpr_eval_end: + #1 + \else: + #2 + \fi: + \intexpr_eval_end: +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\intexpr_div_truncate:nn} +% \begin{macro}{\intexpr_div_round:nn} +% \begin{macro}{\intexpr_mod:nn} +% As "\intexpr_eval:w" rounds the result of a division we also +% provide a version that truncates the result. +% \begin{macrocode} +% \end{macrocode} +% Initial version didn't work correctly with e\TeX's implementation. +% \begin{macrocode} +%\cs_set:Npn \intexpr_div_truncate_raw:nn #1#2 { +% \intexpr_eval:n{ (2*#1 - #2) / (2* #2) } +%} +% \end{macrocode} +% New version by Heiko: +% \begin{macrocode} +\cs_set:Npn \intexpr_div_truncate:nn #1#2 { + \intexpr_value:w \intexpr_eval:w + \if_intexpr_compare:w \intexpr_eval:w #1 = \c_zero + 0 + \else: + (#1 + \if_intexpr_compare:w \intexpr_eval:w #1 < \c_zero + \if_intexpr_compare:w \intexpr_eval:w #2 < \c_zero + -( #2 + + \else: + +( #2 - + \fi: + \else: + \if_intexpr_compare:w \intexpr_eval:w #2 < \c_zero + +( #2 + + \else: + -( #2 - + \fi: + \fi: + 1)/2) + \fi: + /(#2) + \intexpr_eval_end: +} +% \end{macrocode} +% For the sake of completeness: +% \begin{macrocode} +\cs_set:Npn \intexpr_div_round:nn #1#2 {\intexpr_eval:n{(#1)/(#2)}} +% \end{macrocode} +% Finally there's the modulus operation. +% \begin{macrocode} +\cs_set:Npn \intexpr_mod:nn #1#2 { + \intexpr_value:w + \intexpr_eval:w + #1 - \intexpr_div_truncate:nn {#1}{#2} * (#2) + \intexpr_eval_end: +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\intexpr_if_odd_p:n} +% \begin{macro}[TF]{\intexpr_if_odd:n} +% \begin{macro}{\intexpr_if_even_p:n} +% \begin{macro}[TF]{\intexpr_if_even:n} +% A predicate function. +% \begin{macrocode} +\prg_set_conditional:Npnn \intexpr_if_odd:n #1 {p,TF,T,F} { + \if_intexpr_odd:w \intexpr_eval:w #1\intexpr_eval_end: + \prg_return_true: \else: \prg_return_false: \fi: +} +\prg_set_conditional:Npnn \intexpr_if_even:n #1 {p,TF,T,F} { + \if_intexpr_odd:w \intexpr_eval:w #1\intexpr_eval_end: + \prg_return_false: \else: \prg_return_true: \fi: +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\intexpr_while_do:nn} +% \begin{macro}{\intexpr_until_do:nn} +% \begin{macro}{\intexpr_do_while:nn} +% \begin{macro}{\intexpr_do_until:nn} +% These are quite easy given the above functions. The "while" versions +% test first and then execute the body. The "do_while" does it the +% other way round. +% \begin{macrocode} +\cs_set:Npn \intexpr_while_do:nn #1#2{ + \intexpr_compare:nT {#1}{#2 \intexpr_while_do:nn {#1}{#2}} +} +\cs_set:Npn \intexpr_until_do:nn #1#2{ + \intexpr_compare:nF {#1}{#2 \intexpr_until_do:nn {#1}{#2}} +} +\cs_set:Npn \intexpr_do_while:nn #1#2{ + #2 \intexpr_compare:nT {#1}{\intexpr_do_while:nNnn {#1}{#2}} +} +\cs_set:Npn \intexpr_do_until:nn #1#2{ + #2 \intexpr_compare:nF {#1}{\intexpr_do_until:nn {#1}{#2}} +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\intexpr_while_do:nNnn} +% \begin{macro}{\intexpr_until_do:nNnn} +% \begin{macro}{\intexpr_do_while:nNnn} +% \begin{macro}{\intexpr_do_until:nNnn} +% As above but not using the more natural syntax. +% \begin{macrocode} +\cs_set:Npn \intexpr_while_do:nNnn #1#2#3#4{ + \intexpr_compare:nNnT {#1}#2{#3}{#4 \intexpr_while_do:nNnn {#1}#2{#3}{#4}} +} +\cs_set:Npn \intexpr_until_do:nNnn #1#2#3#4{ + \intexpr_compare:nNnF {#1}#2{#3}{#4 \intexpr_until_do:nNnn {#1}#2{#3}{#4}} +} +\cs_set:Npn \intexpr_do_while:nNnn #1#2#3#4{ + #4 \intexpr_compare:nNnT {#1}#2{#3}{\intexpr_do_while:nNnn {#1}#2{#3}{#4}} +} +\cs_set:Npn \intexpr_do_until:nNnn #1#2#3#4{ + #4 \intexpr_compare:nNnF {#1}#2{#3}{\intexpr_do_until:nNnn {#1}#2{#3}{#4}} +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macrocode} +%</initex|package> +% \end{macrocode} +% +% \end{implementation} +% \PrintIndex +% +% \endinput diff --git a/Master/texmf-dist/source/latex/expl3/l3io.dtx b/Master/texmf-dist/source/latex/expl3/l3io.dtx index b382744776b..6473c2dca8b 100644 --- a/Master/texmf-dist/source/latex/expl3/l3io.dtx +++ b/Master/texmf-dist/source/latex/expl3/l3io.dtx @@ -1,5 +1,5 @@ % \iffalse -%% File: l3io.dtx Copyright (C) 1990-2006 LaTeX3 project +%% File: l3io.dtx Copyright (C) 1990-2009 LaTeX3 project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this @@ -17,7 +17,7 @@ %% %% The development version of the bundle can be found at %% -%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/ +%% http://www.latex-project.org/svnroot/experimental/trunk/ %% %% for those people who are interested. %% @@ -36,7 +36,7 @@ \RequirePackage{l3names} %</driver|package> %\fi -\GetIdInfo$Id: l3io.dtx 621 2007-09-01 20:14:19Z morten $ +\GetIdInfo$Id: l3io.dtx 1369 2009-05-31 21:36:35Z joseph $ {L3 Experimental i/o module} %\iffalse %<*driver> @@ -44,14 +44,22 @@ \ProvidesFile{\filename.\filenameext} [\filedate\space v\fileversion\space\filedescription] %\iffalse -\documentclass{l3doc} +\documentclass[full]{l3doc} \begin{document} -\DocInput{\filename.\filenameext} +\DocInput{l3io.dtx} \end{document} %</driver> % \fi % -% \section{Low-level file i/o} +% \title{The \textsf{l3io} package\thanks{This file +% has version number \fileversion, last +% revised \filedate.}\\ +% Low-level file i/o} +% \author{\Team} +% \date{\filedate} +% \maketitle +% +% \begin{documentation} % % \TeX{} is capable of reading from and writing up to 16 individual % streams. These i/o operations are accessable in \LaTeX3 with functions @@ -60,25 +68,24 @@ % 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 +% Sometimes it is not known 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'' +% direct write operations like "\iow_now:Nx" 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", +% Beside the functions that immediately act (e.g., "\iow_now:Nx", % 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} +% \section{Functions for output streams} % -% \begin{function}{\iow_new:N | -% \iow_new:c -% } +% \begin{function}{ \iow_new:N | +% \iow_new:c } % \begin{syntax} % "\iow_new:N" <stream> % \end{syntax} @@ -90,11 +97,10 @@ % \end{texnote} % \end{function} % -% \begin{function}{\iow_open:Nn | -% \iow_open:cn -% } +% \begin{function}{ \iow_open:Nn | +% \iow_open:cn } % \begin{syntax} -% "\iow_open:Nn" <stream> "{" <file name> "}" +% "\iow_open:Nn" <stream> \Arg{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 @@ -105,65 +111,93 @@ % still open at the end of the \TeX{} run will be automatically closed. % \end{function} % -% \begin{function}{\iow_expanded:Nn | -% \iow_unexpanded:Nn -% } +% \begin{function}{ \iow_close:N } +% \begin{syntax} +% "\iow_open:Nn" <stream> +% \end{syntax} +% Closes output stream <stream>. +% \end{function} +% +% \subsection{Immediate writing} +% +% \begin{function}{ \iow_now:Nx | +% \iow_now:Nn } % \begin{syntax} -% "\iow_expanded:Nn" <stream> "{" <tokens> "}" +% "\iow_now:Nx" <stream> \Arg{tokens} % \end{syntax} -% This function immediately writes the expansion of <tokens> to the +% "\iow_now:Nx" 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). +% terminal. The variant "\iow_now:Nn" writes out <tokens> without any +% further expansion. +% \begin{texnote} +% These are the equivalent of \TeX's "\immediate\write" with and without +% expansion control. +% \end{texnote} +% \end{function} +% +% \begin{function}{ \iow_log:n | \iow_log:x | +% \iow_term:x | \iow_term:n } +% \begin{syntax} +% "\iow_log:x" \Arg{tokens} +% \end{syntax} +% These functions write to the log file (also known as the transcript file) or +% to the terminal respectively. They are equivalent to "\iow_now:Nx" where +% <stream> is the transcript file ("\c_iow_log_stream") or the terminal +% ("\c_iow_term_stream"). % \end{function} % -% \begin{function}{\iow_expanded_log:n | -% \iow_expanded_term:n | -% \iow_unexpanded_term:n -% } +% \begin{function}{ \iow_now_buffer_safe:Nn | +% \iow_now_buffer_safe:Nx } % \begin{syntax} -% "\iow_expanded_log:n" "{" <tokens> "}" +% "\iow_now_buffer_safe:Nn" <stream> \Arg{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"). +% Like "\iow_now:Nx" but splits <tokens> at every blank into separate +% lines. When potentially (very) long token lists are being written, this +% avoids the problem of +% buffer overflow when reading back the file. % \end{function} % -% \begin{function}{\iow_long_expanded:Nx | -% \iow_long_unexpanded:Nn -% } +% \begin{function}{ \iow_now_when_avail:Nn | +% \iow_now_when_avail:cn } % \begin{syntax} -% "\iow_long_expanded:Nn" <stream> "{" <tokens> "}" +% "\iow_now_when_avail:Nn" <stream> \Arg{tokens} % \end{syntax} -% Like "\iow_expanded:Nn" but splits <tokens> at every blank into separate -% lines. +% This special function first checks if the <stream> is open for writing. +% If not it does nothing otherwise it behaves like "\iow_now:Nn". % \end{function} % -% \begin{function}{\iow_unexpanded_if_avail:Nn| -% \iow_unexpanded_if_avail:cn|} +% \subsection{Deferred writing} +% +% \begin{function}{ \iow_shipout:Nn | \iow_shipout:Nx } % \begin{syntax} -% "\iow_unexpanded_if_avail:Nn" <stream> "{" <tokens> "}" +% "\iow_shipout_x:Nn" <stream> \Arg{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". +% These functions write <tokens> to the specified <stream>, but unlike with +% "\iow_now:Nn" which write the material immediately, "\iow_shipout:Nn" waits +% until the processing of the current page has finished. % \end{function} % -% \begin{function}{\iow_deferred_expanded:Nn | -% \iow_deferred_unexpanded:Nn} +% \begin{function}{ \iow_shipout_x:Nn | \iow_shipout_x:Nx } % \begin{syntax} -% "\iow_deferred_expanded:Nn" <stream> "{" <tokens> "}" +% "\iow_shipout_x:Nn" <stream> \Arg{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. +% More useful than the "\iow_shipout:Nn" functions, these functions also write +% <tokens> to <stream> at the end of the processing of the current page; +% however, before <tokens> are written they are subjected to a further +% "x" expansion stage. +% +% This is useful for writing messages that depend +% on counters (such as the page number) that are not known until the page has +% been completed. +% +% "\iow_shipout_x:Nn" always needs "{}" around the second argument. % \begin{texnote} -% "\iow_deferred_expanded:Nn" was known as \tn{write}. +% "\iow_shipout_x:Nn" is equivalent to \TeX's \tn{write}. % \end{texnote} % \end{function} % +% \subsection{Special characters for writing} +% % \begin{function}{\iow_newline:} % \begin{syntax} % "\iow_newline:" @@ -172,10 +206,26 @@ % that gets written some output stream in non-verbatim mode. % \end{function} % -% \subsection{Functions for input streams} +% \begin{function}{\iow_space:} +% \begin{syntax} +% "\iow_space:" +% \end{syntax} +% Function that produces a space when used within the <token list> +% that gets written to some output stream in an expanding mode. +% \end{function} +% +% \begin{function}{\iow_char:N} +% \begin{syntax} +% "\iow_space:N" "\"<char> +% "\iow_space:N" "\%" +% \end{syntax} +% Inserts <char> into the output stream. Useful when trying to write difficult +% characters such as "%", "{", "}", etc., in messages. +% \end{function} +% +% \section{Functions for input streams} % -% \begin{function}{\ior_new:N -% } +% \begin{function}{\ior_new:N} % \begin{syntax} % "\ior_new:N" <stream> % \end{syntax} @@ -188,12 +238,12 @@ % % \begin{function}{\ior_open:Nn} % \begin{syntax} -% "\ior_open:Nn" <stream> "{" <file name> "}" +% "\ior_open:Nn" <stream> \Arg{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 +% with "\ior_if_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} @@ -209,10 +259,9 @@ % \end{texnote} % \end{function} % -% \begin{function}{\ior_eof:NTF | -% \ior_eof:NF} +% \begin{function}{ \ior_if_eof_p:N / (EXP) | \ior_if_eof:N / (TF)(EXP) } % \begin{syntax} -% "\ior_eof:NTF" <stream> "{" <true code> "}{" <false code> "}" +% "\ior_if_eof:NTF" <stream> \Arg{true code} \Arg{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. @@ -228,18 +277,18 @@ % \end{texnote} % \end{function} % -% \begin{function}{\ior_to:NN | -% \ior_gto:NN} +% \begin{function}{ \ior_to:NN | +% \ior_gto:NN } % \begin{syntax} -% "\ior_to:NN" <stream> <tlp> +% "\ior_to:NN" <stream> <tl var.> % \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. +% the result locally or globally into the token list variable. +% If <stream> is not open, input is requested from the terminal. % \end{function} % -% \subsection{Constants} +% \section{Constants} % % \begin{variable}{\c_iow_comment_char | % \c_iow_lbrace_char | @@ -248,55 +297,36 @@ % right brace in token lists that should be written to a file. % \end{variable} % -% \begin{variable}{\c_io_term_stream} +% \begin{variable}{ \c_iow_term_stream | \c_ior_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 +% stream the user is prompted with the name of the token list variable +% (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} +% \begin{variable}{ \c_iow_log_stream | \c_ior_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 +% ".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} % % -% \subsection{Internal functions} +% \end{documentation} % -% \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} -% -% \StopEventually{} +% \begin{implementation} % -% \subsection{The Implementation} +% \section{\pkg{l3io} implementation} % % We start by ensuring that the required packages are loaded. % \begin{macrocode} -%<package>\ProvidesExplPackage -%<package> {\filename}{\filedate}{\fileversion}{\filedescription} -%<package&check>\RequirePackage{l3chk}\par -%<package>\RequirePackage{l3toks}\par +%<*package> +\ProvidesExplPackage + {\filename}{\filedate}{\fileversion}{\filedescription} +\package_check_loaded_expl: +%</package> %<*initex|package> % \end{macrocode} % @@ -305,27 +335,25 @@ % (for write) as module names. e.g.\ |\c_ior_test_stream| is an input stream % variable called `test'. % -% \subsubsection{Output streams} +% \subsection{Output streams} % -% \begin{macro}{\iow_new:N} -% \begin{macro}{\iow_new:c} +% \begin{macro}{\iow_new:N,\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} %<*initex> \alloc_setup_type:nnn {iow} \c_zero \c_sixteen -\def_new:Npn \iow_new:N #1 {\alloc_reg:NnNN g {iow} \tex_chardef:D #1} +\cs_new_nopar:Npn \iow_new:N #1 {\alloc_reg:NnNN g {iow} \tex_chardef:D #1} %</initex> -%<package>\let:NN \iow_new:N \newwrite -\def_new:Npn \iow_new:c {\exp_args:Nc \iow_new:N} +%<*package> +\cs_set_eq:NN \iow_new:N \newwrite +%</package> +\cs_generate_variant:Nn \iow_new:N {c} % \end{macrocode} % \end{macro} -% \end{macro} -% % -% \begin{macro}{\iow_open:Nn} -% \begin{macro}{\iow_open:cn} +% \begin{macro}{\iow_open:Nn,\iow_open:cn} % To open streams for reading or writing the following two functions % are provided. The streams are opened immediately. % @@ -334,110 +362,99 @@ % 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} +\cs_new_nopar:Npn \iow_open:Nn #1#2 { + \iow_close:N #1 + \tex_immediate:D \tex_openout:D #1#2 \scan_stop: +} +\cs_generate_variant:Nn \iow_open:Nn {c} % \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. +% and then read in the same pass from a stream. % \begin{macrocode} -\def_new:Npn \iow_close:N {\tex_immediate:D\tex_closeout:D} +\cs_new_nopar: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} +% \begin{macro}{\c_iow_term_stream,\c_ior_term_stream} +% \begin{macro}{\c_iow_log_stream,\c_ior_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_..|. +% file (|\c_iow_term_stream|). Both can be used to read from and have +% equivalent "\c_ior" versions. % \begin{macrocode} -\let_new:NN \c_io_term_stream \c_sixteen -\let_new:NN \c_iow_log_stream \c_minus_one +\cs_new_eq:NN \c_iow_term_stream \c_sixteen +\cs_new_eq:NN \c_ior_term_stream \c_sixteen +\cs_new_eq:NN \c_iow_log_stream \c_minus_one +\cs_new_eq:NN \c_ior_log_stream \c_minus_one % \end{macrocode} % \end{macro} % \end{macro} % % \paragraph{Immediate writing} % -% \begin{macro}{\iow_expanded:Nn} +% \begin{macro}{\iow_now:Nx} % An abbreviation for an often used operation, which immediately -% writes its second argument to the output stream. +% writes its second argument expanded to the output stream. % \begin{macrocode} -\def_new:Npn \iow_expanded:Nn {\tex_immediate:D\iow_deferred_expanded:Nn} +\cs_new_nopar:Npn \iow_now:Nx { \tex_immediate:D \iow_shipout_x: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. +% \begin{macro}{\iow_now:Nn} +% This routine writes the second argument onto the output +% stream without expansion. If this stream isn't open, the output goes to +% the terminal instead. % 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{ - \iow_expanded:Nn #1{\exp_not:n{#2}}} +\cs_new_nopar:Npn \iow_now:Nn #1#2 { + \iow_now:Nx #1 { \exp_not:n {#2} } +} % \end{macrocode} % \end{macro} % % -% \begin{macro}{\iow_expanded_log:n} -% \begin{macro}{\iow_expanded_term:n} +% \begin{macro}{\iow_log:n,\iow_log:x,\iow_term:n,\iow_term:x} % 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. +% very early on. % \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} +\cs_set_nopar:Npn \iow_log:x { \iow_now:Nx \c_iow_log_stream } +\cs_new_nopar:Npn \iow_log:n { \iow_now:Nn \c_iow_log_stream } +\cs_set_nopar:Npn \iow_term:x { \iow_now:Nx \c_iow_term_stream } +\cs_new_nopar:Npn \iow_term:n { \iow_now:Nn \c_iow_term_stream } % \end{macrocode} -% The second one isn't exactly equivalent to the old |\typeout| since +% "\iow_term:x" 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 +% \begin{macro}{\iow_now_when_avail:Nn,\iow_now_when_avail:cn} +% |\iow_now_when_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 } +\cs_new_nopar:Npn \iow_now_when_avail:Nn #1 { + \cs_if_free:NTF #1 {\use_none:n} {\iow_now:Nn #1} +} +\cs_generate_variant:Nn \iow_now_when_avail:Nn {c} % \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} +% \begin{macro}{\iow_now_buffer_safe:Nn,\iow_now_buffer_safe:Nx} +% \begin{macro}[aux]{\iow_now_buffer_safe_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 @@ -448,61 +465,42 @@ % 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:\tex_newlinechar:D`\ #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} +\cs_new_nopar:Npn \iow_now_buffer_safe_aux:w #1#2#3 { + \group_begin: \tex_newlinechar:D`\ #1#2{#3} \group_end: +} +\cs_new_nopar:Npn \iow_now_buffer_safe:Nx { + \iow_now_buffer_safe_aux:w \iow_now:Nx +} +\cs_new_nopar:Npn \iow_now_buffer_safe:Nn { + \iow_now_buffer_safe_aux:w \iow_now:Nn +} % \end{macrocode} % \end{macro} % \end{macro} -% \end{macro} % % % \paragraph{Deferred writing} -% -% With \eTeX\ available deferred writing is easy. The comments below -% are old. % -% 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{macro}{\iow_shipout_x:Nn,\iow_shipout_x:Nx} +% First the easy part, this is the primitive. % \begin{macrocode} -\let:NN \iow_deferred_expanded:Nn \tex_write:D +\cs_set_eq:NN \iow_shipout_x:Nn \tex_write:D +\cs_generate_variant:Nn \iow_shipout_x:Nn {Nx} % \end{macrocode} % \end{macro} % -% -% \begin{macro}{\iow_deferred_unexpanded:Nn} -% Now the harder part: +% \begin{macro}{\iow_shipout:Nn,\iow_shipout:Nx} +% With \eTeX\ available deferred writing is easy. % \begin{macrocode} -\def_new:Npn \iow_deferred_unexpanded:Nn #1#2{ - \iow_deferred_expanded:Nn{\exp_not:n{#2}} +\cs_new_nopar:Npn \iow_shipout:Nn #1#2{ + \iow_shipout_x:Nn #1 { \exp_not:n {#2} } } -%% Old implementation: -%\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} +\cs_generate_variant:Nn \iow_shipout:Nn {Nx} % \end{macrocode} % \end{macro} % -% Long forms of these functions are not possible since the deferred +% `Buffer safe' forms of these functions are not possible since the deferred % writing will restore the value of |\tex_newlinechar:D| 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 |\tex_newlinechar:D| @@ -515,33 +513,52 @@ % % \begin{macro}{\iow_newline:} % Global variable holding the character that forces a new line when -% something is written to an output stream. +% something is written to an output stream. +% \begin{macrocode} +\cs_new_nopar:Npn \iow_newline: {^^J} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\iow_space:} +% Global variable holding the character that inserts a space char when +% writing to an output stream. +% \begin{macrocode} +\cs_new_nopar:Npn \iow_space: {~} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\iow_char:N} +% Function to write any escaped char to an output stream. % \begin{macrocode} -\def_new:Npn \iow_newline: {^^J} +\cs_new:Nn \iow_char:N { \cs_to_str:N #1 } % \end{macrocode} % \end{macro} % +% % \begin{macro}{\c_iow_comment_char} % \begin{macro}{\c_iow_lbrace_char} % \begin{macro}{\c_iow_rbrace_char} +% TODO: remove these in favour of "\iow_char:N" (Will, Apr 2009) +% % 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} -\tlp_new:Nx \c_iow_comment_char {\cs_to_str:N\%} +\tl_new:Nx \c_iow_comment_char {\cs_to_str:N\%} % \end{macrocode} % To avoid another allocation function which is probably only -% necessary here we use the |\def:Npx| command directly. +% necessary here we use the |\cs_set_nopar:Npx| command directly. % \begin{macrocode} -\tlp_new:Nx \c_iow_lbrace_char{\cs_to_str:N\{} -\tlp_new:Nx \c_iow_rbrace_char{\cs_to_str:N\}} +\tl_new:Nx \c_iow_lbrace_char{\cs_to_str:N\{} +\tl_new:Nx \c_iow_rbrace_char{\cs_to_str:N\}} % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % % -% \subsubsection{Input streams} +% \subsection{Input streams} % % \begin{macro}{\ior_new:N} % Allocation of new input streams is done by this function. @@ -550,100 +567,79 @@ % \begin{macrocode} %<*initex> \alloc_setup_type:nnn {ior} \c_zero \c_sixteen -\def_new:Npn \ior_new:N #1 {\alloc_reg:NnNN g {ior} \tex_chardef:D #1} +\cs_new_nopar:Npn \ior_new:N #1 {\alloc_reg:NnNN g {ior} \tex_chardef:D #1} %</initex> -%<package>\let:NN \ior_new:N \newread +%<package>\cs_set_eq:NN \ior_new:N \newread % \end{macrocode} % \end{macro} % % \begin{macro}{\ior_open:Nn} -% \begin{macro}{\ior_close:Nn} +% \begin{macro}{\ior_close:N} % 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} -\let:NN \ior_close:N \tex_closein:D -\def_new:Npn \ior_open:Nn #1#2{\ior_close:N #1\scan_stop: - \tex_openin:D#1#2\scan_stop:} +\cs_set_eq:NN \ior_close:N \tex_closein:D +\cs_new_nopar:Npn \ior_open:Nn #1#2 { + \ior_close:N #1 \scan_stop: + \tex_openin:D #1#2 \scan_stop: +} % \end{macrocode} % \end{macro} % \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{macro}{\if_eof:w} % \begin{macrocode} -\def_new:Npn \ior_eof:NTF #1{\if_eof:w#1 - \exp_after:NN\use_arg_i:nn \else: - \exp_after:NN\use_arg_ii:nn \fi:} +\cs_new_eq:NN \if_eof:w \tex_ifeof:D % \end{macrocode} % \end{macro} % -% \begin{macro}{\ior_eof:NF} -% \begin{macro}{\if_eof:w} -% |\ior_eof:NF | \m{stream} \m{false case}. Do something if -% if there is still something to read from this file: +% +% \begin{macro}{\ior_if_eof_p:N} +% \begin{macro}[TF]{\ior_if_eof:N} +% |\ior_if_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} -\let:NN \if_eof:w \tex_ifeof:D -\def_new:Npn \ior_eof:NF #1{\if_eof:w#1 - \exp_after:NN \use_none:nn \fi: \use_arg_i:n} +\prg_new_conditional:Nnn \ior_if_eof:N {p,TF,T,F} { + \tex_ifeof:D #1 \prg_return_true: \else: \prg_return_false: \fi: +} % \end{macrocode} % \end{macro} % \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} +\cs_new_nopar:Npn \ior_to:NN #1#2 { + \tex_read:D #1 to #2 +%<check> \chk_local_or_pref_global:N #2 +} +\cs_new_nopar:Npn \ior_gto:NN { +%<+check> \pref_global_chk: +%<-check> \pref_global:D + \ior_to:NN +} % \end{macrocode} % \end{macro} % \end{macro} % +% \begin{macrocode} +%</initex|package> +% \end{macrocode} % % Show token usage: % \begin{macrocode} -%</initex|package> %<*showmemory> \showMemUsage %</showmemory> % \end{macrocode} % -% \endinput -% -% $Log$ -% Revision 1.16 2006/03/20 18:26:36 braams -% Updated the copyright notice (2006) and demoted all implementation -% sections to subsections and so on to clean up the toc for source3.tex -% -% Revision 1.15 2005/12/27 09:51:27 morten -% Changed the use of RCS information -% -% Revision 1.14 2005/11/07 17:59:48 morten -% Fixed definition of \iow_newline: (moved it to the right place) -% -% Revision 1.13 2005/04/29 22:29:23 braams -% Replaced the undefined \g_iow_newline_code with \tex_newlinechar:D -% and added the definition for \iow_newline: -% -% Revision 1.12 2005/04/06 22:35:37 braams -% Now we have register allocation fitted -% -% Revision 1.11 2005/03/16 22:36:24 braams -% Added the tweaks necessary to be able to load with initex -% -% Revision 1.10 2005/03/11 21:39:10 braams -% Fixed the use of RCS information; added \StopEventually +% \end{implementation} +% \PrintIndex % +% \endinput diff --git a/Master/texmf-dist/source/latex/expl3/l3keyval.dtx b/Master/texmf-dist/source/latex/expl3/l3keyval.dtx index 4134b0fef51..8ac747e5d0a 100644 --- a/Master/texmf-dist/source/latex/expl3/l3keyval.dtx +++ b/Master/texmf-dist/source/latex/expl3/l3keyval.dtx @@ -1,5 +1,5 @@ % \iffalse -%% File: l3keyval.dtx Copyright (C) 2006 LaTeX3 project +%% File: l3keyval.dtx Copyright (C) 2006-2009 LaTeX3 project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this @@ -17,7 +17,7 @@ %% %% The development version of the bundle can be found at %% -%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/ +%% http://www.latex-project.org/svnroot/experimental/trunk/ %% %% for those people who are interested. %% @@ -35,7 +35,7 @@ \RequirePackage{l3names} %</driver|package> %\fi -\GetIdInfo$Id: l3keyval.dtx 621 2007-09-01 20:14:19Z morten $ +\GetIdInfo$Id: l3keyval.dtx 1362 2009-05-28 20:19:21Z joseph $ {L3 Experimental keyval processing} %\iffalse %<*driver> @@ -43,9 +43,9 @@ \ProvidesFile{\filename.\filenameext} [\filedate\space v\fileversion\space\filedescription] %\iffalse -\documentclass{l3doc} +\documentclass[full]{l3doc} \begin{document} -\DocInput{\filename.\filenameext} +\DocInput{l3keyval.dtx} \end{document} %</driver> % \fi @@ -59,6 +59,8 @@ % \date{\filedate} % \maketitle % +% \begin{documentation} +% % \section{Introduction} % % Currently, this module only provides functions for extracting keys @@ -109,16 +111,13 @@ % two functions before starting the parsing process. % % -% \subsection{Functions} -% -% -% +% \section{Functions} % % \begin{function}{ % \KV_parse_no_space_removal_no_sanitize:n | % } % \begin{syntax} -% "\KV_parse_no_space_removal_no_sanitize:n" "{"<keyval list>"}" +% "\KV_parse_no_space_removal_no_sanitize:n" \Arg{keyval list} % \end{syntax} % Parses the keys and values literally. For use when spaces are % ignored and |=| and |,| have normal catcodes. @@ -128,7 +127,7 @@ % \KV_parse_space_removal_no_sanitize:n | % } % \begin{syntax} -% "\KV_parse_space_removal_no_sanitize:n" "{"<keyval list>"}" +% "\KV_parse_space_removal_no_sanitize:n" \Arg{keyval list} % \end{syntax} % As above but also removes spaces around keys and values. For use % when spaces are not ignored. @@ -138,7 +137,7 @@ % \KV_parse_space_removal_sanitize:n | % } % \begin{syntax} -% "\KV_parse_space_removal_sanitize:n" "{"<keyval list>"}" +% "\KV_parse_space_removal_sanitize:n" \Arg{keyval list} % \end{syntax} % As above but additionally also replaces top-level active |=| and % |,| with harmless versions. @@ -166,43 +165,91 @@ % \KV_key_value_elt:nn | % } % \begin{syntax} -% "\KV_key_no_value_elt:n" "{"<key>"}" \\ -% "\KV_key_value_elt:n" "{"<key>"}" "{"<value>"}" +% "\KV_key_no_value_elt:n" \Arg{key} \\ +% "\KV_key_value_elt:n" \Arg{key} \Arg{value} % \end{syntax} % Functions returned by the |\KV_parse_| functions. The default % definition of these two functions is an error message! % \end{function} % +% \end{documentation} +% +% \begin{implementation} +% +% \section{\pkg{l3keyval} implementation} +% +% \subsection{Internal functions and variables} +% +% \begin{variable}{ \l_KV_tmpa_tl | \l_KV_tmpb_tl | +% \c_KV_single_equal_sign_tl | +% \l_KV_parse_toks | \l_KV_currkey_toks | +% \l_KV_currval_toks } +% Token list variables and token registers used internally. +% \end{variable} +% +% \begin{function}{ \KV_sanitize_outerlevel_active_equals:N | +% \KV_sanitize_outerlevel_active_commas:N } +% \begin{syntax} +% "\KV_sanitize_outerlevel_active_equals:N" <tl var.> +% \end{syntax} +% Replaces catcode other "=" and "," within a <tl var.> with active characters. +% \end{function} +% +% \begin{function}{ \KV_remove_surrounding_spaces:nw | +% \KV_remove_surrounding_spaces_auxi:w / (EXP) } +% \begin{syntax} +% +% "\KV_remove_surrounding_spaces:nw" <toks> <token list> "\q_nil" +% "\KV_remove_surrounding_spaces_auxi:w" <token list> \verb*" Q"$\sb3$ +% \end{syntax} +% Removes a possible +% leading space plus a possible ending space from a <token list>. +% The first version (which is not used in the code) stores it in <toks>. +% \end{function} % -% \StopEventually{} +% \begin{function}{ \KV_add_value_element:w | \KV_set_key_element:w } +% \begin{syntax} +% "\KV_set_key_element:w" <token list> "\q_nil" +% "\KV_add_value_element:w" "\q_stop" <token list> "\q_nil" +% \end{syntax} +% Specialised functions to strip spaces from their input and set the +% token registers "\l_KV_currkey_toks" or "\l_KV_currval_toks" +% respectively. +% \end{function} % -% \section{Implementation} +% \begin{function}{ \KV_split_key_value_current:w | +% \KV_split_key_value_space_removal:w | +% \KV_split_key_value_space_removal_detect_error:wTF | +% \KV_split_key_value_no_space_removal:w } +% \begin{syntax} +% "\KV_split_key_value_current:w" \dots +% \end{syntax} +% These functions split keyval lists into chunks depending which +% sanitising method is being used. "\KV_split_key_value_current:w" is "\cs_set_eq:NN" +% to whichever is appropriate. +% \end{function} % +% \subsection{Module code} % % We start by ensuring that the required packages are loaded. % \begin{macrocode} %<*package> \ProvidesExplPackage {\filename}{\filedate}{\fileversion}{\filedescription} -\RequirePackage{l3quark} -\RequirePackage{l3toks} -\RequirePackage{l3int} -\RequirePackage{l3token} +\package_check_loaded_expl: %</package> %<*initex|package> % \end{macrocode} % % -% -% -% \begin{macro}{\l_KV_tmpa_tlp} -% \begin{macro}{\l_KV_tmpb_tlp} -% \begin{macro}{\c_KV_single_equal_sign_tlp} +% \begin{macro}{\l_KV_tmpa_tl} +% \begin{macro}{\l_KV_tmpb_tl} +% \begin{macro}{\c_KV_single_equal_sign_tl} % Various useful things. % \begin{macrocode} -\tlp_new:Nn\l_KV_tmpa_tlp{} -\tlp_new:Nn\l_KV_tmpb_tlp{} -\tlp_new:Nn \c_KV_single_equal_sign_tlp{=} +\tl_new:N \l_KV_tmpa_tl +\tl_new:N \l_KV_tmpb_tl +\tl_new:Nn \c_KV_single_equal_sign_tl{=} % \end{macrocode} % \end{macro} % \end{macro} @@ -240,12 +287,12 @@ \char_set_catcode:nn{`\,}{13} \char_set_lccode:nn{`\8}{`\=} \char_set_lccode:nn{`\9}{`\,} -\tlist_to_lowercase:n{\group_end: -\def_new:Npn \KV_sanitize_outerlevel_active_equals:N #1{ - \tlp_replace_all_in:Nnn #1 = 8 +\tl_to_lowercase:n{\group_end: +\cs_new_nopar:Npn \KV_sanitize_outerlevel_active_equals:N #1{ + \tl_replace_all_in:Nnn #1 = 8 } -\def_new:Npn \KV_sanitize_outerlevel_active_commas:N #1{ - \tlp_replace_all_in:Nnn #1 , 9 +\cs_new_nopar:Npn \KV_sanitize_outerlevel_active_commas:N #1{ + \tl_replace_all_in:Nnn #1 , 9 } } % \end{macrocode} @@ -258,10 +305,10 @@ % % \begin{macro}{\KV_remove_surrounding_spaces:nw} % \begin{macro}{\KV_remove_surrounding_spaces_auxi:w} -% \begin{macro}{\KV_remove_surrounding_spaces_auxii:w} +% \begin{macro}[aux]{\KV_remove_surrounding_spaces_auxii:w} % \begin{macro}{\KV_set_key_element:w} -% \begin{macro}{\KV_set_value_element:w} -% The macro |\KV_remove_surrounding_spaces:Nw| removes a possible +% \begin{macro}{\KV_add_value_element:w} +% The macro |\KV_remove_surrounding_spaces:nw| removes a possible % leading space plus a possible ending space from its second % argument and stores it in the token register |#1|. % @@ -274,7 +321,7 @@ \char_set_catcode:nn{`\Q}{3} % \end{macrocode} % \begin{macrocode} -\gdef_long_new:Npn\KV_remove_surrounding_spaces:nw#1#2\q_nil{ +\cs_gnew:Npn\KV_remove_surrounding_spaces:nw#1#2\q_nil{ % \end{macrocode} % The idea in this processing is to use a Q with strange catcode to % remove a trailing space. But first, how to get this expansion going? @@ -312,7 +359,7 @@ % |\KV_remove_surrounding_spaces_auxii:w| to work properly we need to % put back a Q first. % \begin{macrocode} -\gdef_long_new:Npn\KV_remove_surrounding_spaces_auxi:w#1~Q{ +\cs_gnew:Npn\KV_remove_surrounding_spaces_auxi:w#1~Q{ \KV_remove_surrounding_spaces_auxii:w #1 Q } % \end{macrocode} @@ -320,39 +367,41 @@ % taken care of by the function used to initiate the expansion. Simply % return the argument before the funny Q. % \begin{macrocode} -\gdef_long_new:Npn\KV_remove_surrounding_spaces_auxii:w#1Q#2{#1} +\cs_gnew:Npn\KV_remove_surrounding_spaces_auxii:w#1Q#2{#1} % \end{macrocode} +% % Here are some specialized versions of the above. They do exactly % what we want in one go. First trim spaces from the value and then % put the result surrounded in braces onto |\l_KV_parse_toks|. % \begin{macrocode} -\gdef_long_new:Npn\KV_add_value_element:w\q_stop#1\q_nil{ +\cs_gnew:Npn\KV_add_value_element:w\q_stop#1\q_nil{ \toks_set:Nf\l_KV_currval_toks { \KV_remove_surrounding_spaces_auxi:w \exp_not:N#1Q~Q } \toks_put_right:No\l_KV_parse_toks{ - \exp_after:NN {\toks_use:N \l_KV_currval_toks} + \exp_after:wN {\toks_use:N \l_KV_currval_toks} } } % \end{macrocode} % When storing the key we firstly remove spaces plus the prepended % |\q_no_value|. % \begin{macrocode} -\gdef_long_new:Npn\KV_set_key_element:w#1\q_nil{ +\cs_gnew:Npn\KV_set_key_element:w#1\q_nil{ \toks_set:Nf\l_KV_currkey_toks { - \exp_after:NN\KV_remove_surrounding_spaces_auxi:w - \exp_after:NN\exp_not:N\use_none:n #1Q~Q + \exp_last_unbraced:NNo \KV_remove_surrounding_spaces_auxi:w + \exp_not:N \use_none:n #1Q~Q } % \end{macrocode} % Afterwards we gobble an extra level of braces if that's what we are -% asked to do. +% asked to do. The next part can be done using \cs{toks_set:Nd}, but +% this might not be around for long. % \begin{macrocode} \bool_if:NT \l_KV_remove_one_level_of_braces_bool { - \toks_set:Nd \l_KV_currkey_toks{ - \exp_after:NN \KV_add_element_aux:w - \toks_use:N \l_KV_currkey_toks \q_nil + \exp_args:NNo \toks_set:No \l_KV_currkey_toks { + \exp_after:wN \KV_add_element_aux:w + \toks_use:N \l_KV_currkey_toks \q_nil } } } @@ -364,10 +413,10 @@ % \end{macro} % \end{macro} % -% \begin{macro}{\KV_add_element_aux:w} +% \begin{macro}[aux]{\KV_add_element_aux:w} % A helper function for fixing braces around keys and values. % \begin{macrocode} -\def_long_new:Npn \KV_add_element_aux:w#1\q_nil{#1} +\cs_new:Npn \KV_add_element_aux:w#1\q_nil{#1} % \end{macrocode} % \end{macro} % @@ -375,57 +424,58 @@ % Parse a list of keyvals, put them into list form with entries like % |\KV_key_no_value_elt:n{key1}| and |\KV_key_value_elt:nn{key2}{val2}|. % -% \begin{macro}{\KV_parse_sanitize_aux:n} +% \begin{macro}[aux]{\KV_parse_sanitize_aux:n} % The slow parsing algorithm sanitizes active commas and equal signs % at the top level first. Then uses |#1| as inspector of each % element in the comma list. % \begin{macrocode} -\def_long_new:Npn \KV_parse_sanitize_aux:n #1{ +\cs_new:Npn \KV_parse_sanitize_aux:n #1 { \group_begin: - \toks_clear:N \l_KV_parse_toks - \tlp_set:Nx\l_KV_tmpa_tlp{\exp_not:n{#1}} - \KV_sanitize_outerlevel_active_equals:N\l_KV_tmpa_tlp - \KV_sanitize_outerlevel_active_commas:N\l_KV_tmpa_tlp - \exp_after:NN \KV_parse_elt:w \exp_after:NN\q_no_value \l_KV_tmpa_tlp,\q_nil, + \toks_clear:N \l_KV_parse_toks + \tl_set:Nx \l_KV_tmpa_tl { \exp_not:n {#1} } + \KV_sanitize_outerlevel_active_equals:N \l_KV_tmpa_tl + \KV_sanitize_outerlevel_active_commas:N \l_KV_tmpa_tl + \exp_last_unbraced:NNV \KV_parse_elt:w \q_no_value + \l_KV_tmpa_tl , \q_nil , % \end{macrocode} % We evaluate the parsed keys and values outside the group so the % token register is restored to its previous value. % \begin{macrocode} - \exp_after:NN\group_end: - \toks_use:N \l_KV_parse_toks + \exp_last_unbraced:NV \group_end: + \l_KV_parse_toks } % \end{macrocode} % \end{macro} % % -% \begin{macro}{\KV_parse_no_sanitize_aux:n} +% \begin{macro}[aux]{\KV_parse_no_sanitize_aux:n} % Like above but we don't waste time sanitizing. This is probably % the one we will use for preamble parsing where catcodes of |=| and % |,| are as expected! % \begin{macrocode} -\def_long_new:Npn \KV_parse_no_sanitize_aux:n #1{ +\cs_new:Npn \KV_parse_no_sanitize_aux:n #1{ \group_begin: - \toks_clear:N \l_KV_parse_toks - \KV_parse_elt:w \q_no_value #1,\q_nil, - \exp_after:NN\group_end: - \toks_use:N \l_KV_parse_toks + \toks_clear:N \l_KV_parse_toks + \KV_parse_elt:w \q_no_value #1 , \q_nil , + \exp_last_unbraced:NV \group_end: + \l_KV_parse_toks } % \end{macrocode} % \end{macro} % % -% \begin{macro}{\KV_parse_elt:w} +% \begin{macro}[aux]{\KV_parse_elt:w} % This function will always have a |\q_no_value| stuffed in as the % rightmost token in |#1|. In case there was a blank entry in the % comma separated list we just run it again. The |\use_none:n| makes % sure to gobble the quark |\q_no_value|. A similar test is made to % check if we hit the end of the recursion. % \begin{macrocode} -\def_long:Npn \KV_parse_elt:w #1,{ - \tlist_if_blank:oTF{\use_none:n #1} +\cs_set:Npn \KV_parse_elt:w #1,{ + \tl_if_blank:oTF{\use_none:n #1} { \KV_parse_elt:w \q_no_value } { - \quark_if_nil:oF {\use_arg_ii:nn #1 } + \quark_if_nil:oF {\use_ii:nn #1 } % \end{macrocode} % If we made it to here we can start parsing the key and value. When % done try, try again. @@ -443,7 +493,7 @@ % \begin{macro}{\KV_split_key_value_current:w} % The function called to split the keys and values. % \begin{macrocode} -\let_new:NN \KV_split_key_value_current:w \ERROR +\cs_new:Npn \KV_split_key_value_current:w {\ERROR} % \end{macrocode} % \end{macro} % @@ -462,7 +512,7 @@ % % \begin{macro}{\KV_split_key_value_space_removal:w} % \begin{macro}{\KV_split_key_value_space_removal_detect_error:wTF} -% \begin{macro}{\KV_split_key_value_space_removal_aux:w} +% \begin{macro}[aux]{\KV_split_key_value_space_removal_aux:w} % The code below removes extraneous spaces around the keys and % values plus one set of braces around the entire value. % @@ -474,7 +524,7 @@ % this is slightly more tedious (but only slightly) but at least it % always removes only one level of braces. % \begin{macrocode} -\def_long_new:Npn \KV_split_key_value_space_removal:w #1 = #2\q_nil{ +\cs_new:Npn \KV_split_key_value_space_removal:w #1 = #2\q_nil{ % \end{macrocode} % First grab the key. % \begin{macrocode} @@ -483,15 +533,15 @@ % Then we start checking. If only a key was entered, |#2| contains % |=| and nothing else, so we test for that first. % \begin{macrocode} - \tlp_set:Nx\l_KV_tmpa_tlp{\exp_not:n{#2}} - \tlp_if_eq:NNTF\l_KV_tmpa_tlp\c_KV_single_equal_sign_tlp + \tl_set:Nx\l_KV_tmpa_tl{\exp_not:n{#2}} + \tl_if_eq:NNTF\l_KV_tmpa_tl\c_KV_single_equal_sign_tl % \end{macrocode} % Then we just insert the default key. % \begin{macrocode} { \toks_put_right:No\l_KV_parse_toks{ - \exp_after:NN \KV_key_no_value_elt:n - \exp_after:NN {\toks_use:N\l_KV_currkey_toks} + \exp_after:wN \KV_key_no_value_elt:n + \exp_after:wN {\toks_use:N\l_KV_currkey_toks} } } % \end{macrocode} @@ -510,9 +560,9 @@ % \end{macrocode} % The error test. % \begin{macrocode} -\def_long_new:Npn +\cs_new:Npn \KV_split_key_value_space_removal_detect_error:wTF#1=#2#3\q_nil{ - \tlist_if_head_eq_meaning:nNTF{#3}\q_no_value + \tl_if_head_eq_meaning:nNTF{#3}\q_no_value } % \end{macrocode} % Now we can start extracting the value. Recall that |#1| here starts @@ -521,18 +571,18 @@ % is empty or blank, all three quarks are gobbled. If |#1| consists of % exactly one token or brace group, only the latter quark is left. % \begin{macrocode} -\def_long_new:Npn \KV_val_preserve_braces:NnN #1#2#3{{#2}} -\def_long_new:Npn\KV_split_key_value_space_removal_aux:w #1=={ - \tlp_set:Nx\l_KV_tmpa_tlp{\exp_not:o{\use_none:nnn#1\q_nil\q_nil}} +\cs_new:Npn \KV_val_preserve_braces:NnN #1#2#3{{#2}} +\cs_new:Npn\KV_split_key_value_space_removal_aux:w #1=={ + \tl_set:Nx\l_KV_tmpa_tl{\exp_not:o{\use_none:nnn#1\q_nil\q_nil}} \toks_put_right:No\l_KV_parse_toks{ - \exp_after:NN \KV_key_value_elt:nn - \exp_after:NN {\toks_use:N\l_KV_currkey_toks} + \exp_after:wN \KV_key_value_elt:nn + \exp_after:wN {\toks_use:N\l_KV_currkey_toks} } % \end{macrocode} -% If there a blank space or nothing at all, |\l_KV_tmpa_tlp| is now +% If there a blank space or nothing at all, |\l_KV_tmpa_tl| is now % completely empty. % \begin{macrocode} - \tlp_if_empty:NTF\l_KV_tmpa_tlp + \tl_if_empty:NTF\l_KV_tmpa_tl % \end{macrocode} % We just put an empty value on the stack. % \begin{macrocode} @@ -540,21 +590,21 @@ { % \end{macrocode} % If there was exactly one brace group or token in |#1|, -% |\l_KV_tmpa_tlp| is now equal to |\q_nil|. Then we can just pick it +% |\l_KV_tmpa_tl| is now equal to |\q_nil|. Then we can just pick it % up as the second argument of |#1|. This will also take care of any % spaces which might surround it. % \begin{macrocode} - \quark_if_nil:NTF\l_KV_tmpa_tlp + \quark_if_nil:NTF\l_KV_tmpa_tl { \bool_if:NTF \l_KV_remove_one_level_of_braces_bool { \toks_put_right:No\l_KV_parse_toks{ - \exp_after:NN{\use_arg_ii:nnn #1\q_nil} + \exp_after:wN{\use_ii:nnn #1\q_nil} } } { \toks_put_right:No\l_KV_parse_toks{ - \exp_after:NN{\KV_val_preserve_braces:NnN #1\q_nil} + \exp_after:wN{\KV_val_preserve_braces:NnN #1\q_nil} } } } @@ -575,14 +625,14 @@ % however fun they may be. Since there are no spaces, a set of % braces around a value is automatically stripped by \TeX. % \begin{macrocode} -\def_long_new:Npn \KV_split_key_value_no_space_removal:w #1#2=#3=#4\q_nil{ - \tlp_set:Nn\l_KV_tmpa_tlp{#4} - \tlp_if_empty:NTF \l_KV_tmpa_tlp +\cs_new:Npn \KV_split_key_value_no_space_removal:w #1#2=#3=#4\q_nil{ + \tl_set:Nn\l_KV_tmpa_tl{#4} + \tl_if_empty:NTF \l_KV_tmpa_tl { \toks_put_right:Nn\l_KV_parse_toks{\KV_key_no_value_elt:n{#2}} } { - \tlp_if_eq:NNTF\c_KV_single_equal_sign_tlp\l_KV_tmpa_tlp + \tl_if_eq:NNTF\c_KV_single_equal_sign_tl\l_KV_tmpa_tl { \toks_put_right:Nn\l_KV_parse_toks{\KV_key_value_elt:nn{#2}{#3}} } @@ -597,8 +647,8 @@ % \begin{macro}{\KV_key_no_value_elt:n} % \begin{macro}{\KV_key_value_elt:nn} % \begin{macrocode} -\def_long_new:Npn \KV_key_no_value_elt:n #1{\ERROR} -\def_long_new:Npn \KV_key_value_elt:nn #1#2{\ERROR} +\cs_new:Npn \KV_key_no_value_elt:n #1{\ERROR} +\cs_new:Npn \KV_key_value_elt:nn #1#2{\ERROR} % \end{macrocode} % \end{macro} % \end{macro} @@ -612,8 +662,8 @@ % version that disallows unmatched conditional and does no space % removal. % \begin{macrocode} -\def_new:Npn \KV_parse_no_space_removal_no_sanitize:n { - \let:NN \KV_split_key_value_current:w \KV_split_key_value_no_space_removal:w +\cs_new_nopar:Npn \KV_parse_no_space_removal_no_sanitize:n { + \cs_set_eq:NN \KV_split_key_value_current:w \KV_split_key_value_no_space_removal:w \KV_parse_no_sanitize_aux:n } % \end{macrocode} @@ -624,15 +674,15 @@ % The other varieties can be defined in a similar manner. For the % version needed at the document level, we can use this one. % \begin{macrocode} -\def_new:Npn \KV_parse_space_removal_sanitize:n { - \let:NN \KV_split_key_value_current:w \KV_split_key_value_space_removal:w +\cs_new_nopar:Npn \KV_parse_space_removal_sanitize:n { + \cs_set_eq:NN \KV_split_key_value_current:w \KV_split_key_value_space_removal:w \KV_parse_sanitize_aux:n } % \end{macrocode} % For preamble use by the non-programmer this is probably best. % \begin{macrocode} -\def_new:Npn \KV_parse_space_removal_no_sanitize:n { - \let:NN \KV_split_key_value_current:w \KV_split_key_value_space_removal:w +\cs_new_nopar:Npn \KV_parse_space_removal_no_sanitize:n { + \cs_set_eq:NN \KV_split_key_value_current:w \KV_split_key_value_space_removal:w \KV_parse_no_sanitize_aux:n } % \end{macrocode} @@ -642,24 +692,15 @@ % % \begin{macrocode} %</initex|package> +% \end{macrocode} +% +% \begin{macrocode} %<*showmemory> \showMemUsage %</showmemory> % \end{macrocode} % -% \endinput -% -% $Log$ -% Revision 1.4 2006/07/25 22:38:58 morten -% Removed spurious \exp_after:NN in \KV_add_value_element:w. Sigh. -% -% Revision 1.3 2006/07/25 22:34:03 morten -% Fixed silly bug in \KV_set_key_element:w plus clean-up of code -% -% Revision 1.2 2006/07/25 16:21:30 morten -% Allow values to contain unmatched conditionals such as `val -% \fi:'. Provide option to not strip any braces at all. -% -% Revision 1.1 2006/01/27 10:14:24 morten -% Initial version of keyval parser +% \end{implementation} +% \PrintIndex % +% \endinput diff --git a/Master/texmf-dist/source/latex/expl3/l3messages.dtx b/Master/texmf-dist/source/latex/expl3/l3messages.dtx deleted file mode 100644 index b5ae9e6025f..00000000000 --- a/Master/texmf-dist/source/latex/expl3/l3messages.dtx +++ /dev/null @@ -1,966 +0,0 @@ -% \iffalse -%% File: l3messages.dtx Copyright (C) 1990-2007 LaTeX3 project -%% -%% It may be distributed and/or modified under the conditions of the -%% LaTeX Project Public License (LPPL), either version 1.3c of this -%% license or (at your option) any later version. The latest version -%% of this license is in the file -%% -%% http://www.latex-project.org/lppl.txt -%% -%% This file is part of the ``expl3 bundle'' (The Work in LPPL) -%% and all files in that bundle must be distributed together. -%% -%% The released version of this bundle is available from CTAN. -%% -%% ----------------------------------------------------------------------- -%% -%% The development version of the bundle can be found at -%% -%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/ -%% -%% for those people who are interested. -%% -%%%%%%%%%%% -%% NOTE: %% -%%%%%%%%%%% -%% -%% Snapshots taken from the repository represent work in progress and may -%% not work or may contain conflicting material! We therefore ask -%% people _not_ to put them into distributions, archives, etc. without -%% prior consultation with the LaTeX Project Team. -%% -%% ----------------------------------------------------------------------- -% -%<*driver|package> -\RequirePackage{l3names} -%</driver|package> -%\fi -\GetIdInfo$Id: l3messages.dtx 673 2007-09-28 20:50:33Z mittelba $ - {L3 Experimental LaTeX Messages module} -%\iffalse -%<*driver> -%\fi -\ProvidesFile{\filename.\filenameext} - [\filedate\space v\fileversion\space\filedescription] -%\iffalse -\documentclass{l3doc} -\begin{document} -\DocInput{\filename.\filenameext} -\end{document} -%</driver> -% \fi -% -% -% \section{Communicating with the user} -% -% Sometimes it is necesary to pass information back to the user -% about what is going on. The information can be just that, -% information, or it can be a warning that something might not -% happen to his expectation. It could also be that something has -% gone awry and that processing can't reliably continue without -% some help from the user. In such a case an error is signalled. -% When things are really bad, processing may have to stop as there -% is no way to enter additional commands that put things right -% again. In such a case we have a fatal error and the \LaTeX\ run -% will be aborted. -% -% \subsection{Displaying the information} -% -% First of all we need a couple of fairly low level functions that -% deal with the job of passing the information to the user. -% -% Real information is usually only written to the log file, while -% warnings are displayed on the screen as well. -% \begin{function}{% -% \err_info:nn | -% \err_warn:nn -% } -% \begin{syntax} -% "\err_info:nn" "{" <message> "}" "{"<continuation>"}" -% \end{syntax} -% The <message> will be written to the log file. When it contains -% the command "\err_newline:" a line break will occur and the new -% line will start with the <continuation>. The function -% "\err_warn:nn" writes the message to the terminal as well. -% \end{function} -% When an erroneous situation is encountered, a message is -% displayed and the user is given the opportunity to enter some -% additional code in an attempt to put things right. He may first -% ask for some help, in which case some extra text will be -% displayed to him. -% \begin{function}{\err_interrupt:NNw} -% \begin{syntax} -% "\err_interrupt:NNw" <err id> <label> <more args> -% \end{syntax} -% This function signals a user error by searching the error file -% denoted by <err id> for an error message associated with <label>, -% i.e., specified by a corresponding "\err_interrupt_new:NNNnnn" -% command. Depending on the number of arguments specified as -% <argno> when the error message was defined, further arguments are -% read. Then the error message is displayed as explained in -% "\err_interrupt_new:NNNnnn". -% \end{function} -% -% Finally, when something really serious occurs, \LaTeX\ will tell -% the user about it and abort the run. -% \begin{function}{\err_fatal:nn} -% \begin{syntax} -% "\err_fatal:nn" "{" <message> "}" "{"<continuation>"}" -% \end{syntax} -% Just displays the <message> and then aborts the \LaTeX\ run. -% \end{function} -% -% \begin{function}{\err_newline:} -% \begin{syntax} -% "\err_newline:" -% \end{syntax} -% Is used to break an informational, warning or error message up -% into multiple lines. May be defined in such a way that the new -% line starts with a standard <continuation>. A normal line break in such -% messages can be achieved with "\iow_newline:" from the l3iow module. -% \end{function} -% -% \subsection{Storing the information} -% -% The informational and warning messages are usually short and can -% be stored as part of a macro; but error messages need to be more -% verbose. Therefor error messages are stored in external files -% which are read and searched for the correct error message at the -% time of the error. In this way it is possible to write extensive -% help texts without cluttering \TeX{}'s main memory. -% -% \subsubsection{Dealing with the error file} -% -% \begin{function}{\err_file_new:Nn} -% \begin{syntax} -% "\err_file_new:Nn" <err id> "{"<err file name>"}" -% \end{syntax} -% Opens a new error file to write errors to. <err id> is a unique -% identifier for the external <err file name>. By convention <err -% id> is declared as a constant (i.e., starts with "\c_") und ends -% with "_tlp". If this command is issued while some other error -% file is open we get an internal error message. -% \end{function} -% -% \begin{function}{\err_file_close:N} -% \begin{syntax} -% "\err_file_close:N" <err id> -% \end{syntax} -% Closes the currently open error file and checks that it matches -% <err id>, i.e., that everything is alright in the code. -% \end{function} -% -% \subsubsection{Declaring an error message in the error file} -% \begin{function}{\err_interrupt_new:NNNnnn} -% \begin{syntax} -% "\err_interrupt_new:NNNnnn" <err id> <label> <argno> -% "{" <short msg> "}" -% "{" <long msg> "}" -% "{" <recovery code> "}" -% \end{syntax} -% This function declares an new error message which can be -% addressed via "\err_interrupt:NNw". The pair (<err id>, <label>) -% has to be unique where <label> can be some otherwise arbitrary -% token (usually the function name in which the error routine is -% called. Actually, the pair (<err id>, expansion of <label>) has -% to be unique since for reasons of speed, tests are carried out -% using "\if_meaning:NN". -% -% <argno> specifies the number of extra arguments that will be -% supplied to the error routine when "\err_interrupt:NNw" is -% called. These arguments can be used within <short msg>, <long -% msg>, and/or <recovery code> to provide further information to -% the user. They are denoted with "#1", "#2", etc.\ within these -% arguments. -% -% The <short msg> is displayed directly on the terminal if the -% error occurs, <long msg> is displayed when the user types "h" in -% response to the error prompt of \TeX{}, and <recovery code> is -% executed afterwards. This means that <recovery code> is inserted -% after any deletions or insertions given by the user. All three -% arguments are expanded while they are written to the error file, -% therefore one has to prevent expansion of tokens with -% "\token_to_string:N" that should be expanded when the error is -% triggered. -% \end{function} -% -% \subsection{Internal functions} -% -% \begin{function}{\err_display_aux:w} -% This function is constructed on the fly while reading the error file. -% It grabs following arguments from the code (if any) and then displays -% the error message and inserts the <recovery code>. -% \end{function} -% -% \begin{function}{\err_interrupt_new_aux:w} -% Helper function used to write the error message info onto the error -% file. -% \end{function} -% -% \begin{function}{\err_msgline_aux:NNnnn} -% \begin{syntax} -% "\err_msgline_aux:NNnnn" <argno> <label> "{"<short>"}" -% "{"<long msg>"}{"<recovery code>"}" -% \end{syntax} -% Function written in front of every error message on the error file. It -% will be executed when the error file is read back in comparing <label> -% to "\l_err_label_token". If they are the same, "\err_display_aux:w" -% will be defined and the reading process will stop. -% \end{function} -% -% \begin{function}{\err_message:x} -% \begin{syntax} -% "\err_message:x" "{"<error message>"}" -% \end{syntax} -% Function that directly triggers \TeX{}'s error handler. It should -% not be used directly. -% \begin{texnote} -% This is the \LaTeX3 name for the \tn{errormessage} primitive. -% \end{texnote} -% \end{function} -% -% \subsection{Kernel specific functions} -% -% For a number of the functions described above specific variants -% are provided that are used in the kernel of \LaTeX3. -% -% \begin{function}{% -% \err_kernel_info:n | -% \err_kernel_warn:n | -% \err_kernel_fatal:n -% } -% \begin{syntax} -% "\err_kernel_info:n" "{"<message>"}" -% \end{syntax} -% \end{function} -% \begin{function}{% -% \err_kernel_interrupt:Nw | -% \err_kernel_interrupt_new:NNnnn | -% } -% Abbrivations for writing and accessing kernel error messages that -% go to the error file "\c_kernel_err_tlp". -% \end{function} -% -% \begin{function}{\err_latex_bug:x} -% \begin{syntax} -% "\err_latex_bug:x" "{"<error message>"}" -% \end{syntax} -% Creates an internal error message. This is intended to be used in -% places that should not be reached in normal operation. Something is -% wrong with the code. -% \end{function} -% -% \subsection{Variables and constants} -% -% \begin{variable}{\c_iow_err_stream} -% Output stream used to access the error files during their -% generation. -% \end{variable} -% -% \begin{variable}{\c_kernel_err_tlp} -% Identifier denoting the kernel error file. (Its contents is the -% name of the external file.) -% \end{variable} -% -% \begin{variable}{\g_err_curr_fname} -% Global variable containing the name of the currently open error -% file. Empty when no such file is open for writing. -% \end{variable} -% -% \begin{variable}{\tex_errorcontextlines:D} -% Variable determining the amount of macro expansion contents shown -% to the user when an error is triggered. \LaTeX3 sets this to -1 -% since to the average user this contents is of no interest. -% \begin{texnote} -% This is the \LaTeX3 name for the \TeX3 primitive -% \tn{errorcontextlines}. -% \end{texnote} -% \end{variable} -% -% \begin{variable}{\g_err_help_toks} -% Token register that holds the message that will be shown if the -% user types "h" in response to an error message that was produced -% by "\err_message:x". -% \begin{texnote} -% This is the \LaTeX3 name for the \TeX\ primitive \tn{errhelp}. -% \end{texnote} -% \end{variable} -% -% \begin{variable}{\l_err_label_token} -% Variable holding the <label> to look up in an error file. -% \end{variable} -% -% \StopEventually{} -% -% \subsection{The implementation} -% -% \begin{macrocode} -%<package>\ProvidesExplPackage -%<package> {\filename}{\filedate}{\fileversion}{\filedescription} -%<package>\RequirePackage{l3basics} -%<package>\RequirePackage{l3tlp} -%<package>\RequirePackage{l3expan} -%<package>\RequirePackage{l3num} -%<package>\RequirePackage{l3io} -%<package>\RequirePackage{l3int} -%<package>\RequirePackage{l3toks} -%<package>\RequirePackage{l3token} -%<*initex|package> -% \end{macrocode} -% -% \subsubsection{Code to be moved to other modules} -% -% \begin{macro}{\g_file_curr_name_tlp} -% This variable is used to store the name of the file currently -% being processed. It should be part of the code that defines the -% higher level I/O commands. -% \begin{macrocode} -\tlp_new:Nn \g_file_curr_name_tlp {no~file} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\err_message:x} -% The \LaTeX3 name for a \TeX\ primitive. This should perhaps move -% to \texttt{l3names.dtx}. -% \begin{macrocode} -\let_new:NN \err_message:x \tex_errmessage:D -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\text_put_sp:} -% \begin{macro}{\text_put_four_sp:} -% We need these functions for certain error and warning messages -% right away. They put one and four spaces into the message stream. -% \begin{macrocode} -\def_new:Npn \text_put_sp: {~} -\def_new:Npn \text_put_four_sp: {\text_put_sp: \text_put_sp: - \text_put_sp: \text_put_sp: } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\cmd_arg_list_build} -% This macro takes a digit as its argument and creates a string of -% |#| characters and argument numbers, such as |##1##2##3|. This -% list can then later be used in defining a new macro. -% To do this it locally uses a count register and a token -% register. -% -% \begin{macrocode} -\def:Npn\cmd_arg_list_build#1{ -% \end{macrocode} -% First we need to make sure that the token register we will be -% using for temporary storage is empty. -% \begin{macrocode} - \toks_clear:N\l_tmpb_toks -% \end{macrocode} -% Then we can store the argument in a count register that will be -% decremented untill it's value is zero. Beacuse of the use of the -% result of this macro, the argument needs to be between 1 and 9; -% this could be tested, but such a test is not (yet) added. -% \begin{macrocode} - \int_set:Nn \l_tmpa_int {#1} - \int_while:nNnT \l_tmpa_int > \c_zero { -% \end{macrocode} -% In the loop we first add the value of our counter to the contents -% of the token register; -% \begin{macrocode} - \toks_put_left:No \l_tmpb_toks {\the_internal:D\l_tmpa_int} -% \end{macrocode} -% and precede it with two hash marks. -% \begin{macrocode} - \toks_put_left:Nn \l_tmpb_toks {##} -% \end{macrocode} -% Now the count register is decremented and another iteration will -% follow so long as zero isn't reached. -% \begin{macrocode} - \int_decr:N\l_tmpa_int - } -% \end{macrocode} -% Finally the contents of the token register needs to be copied as -% the expansion of a local variable. -% \begin{macrocode} - \def:Npx\l_cmd_arg_list{\the_internal:D\l_tmpb_toks} -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\cmd_declare:Nnn} -% This macro is a first replacement for \LaTeXe's |\newcommand|. It -% takes the name of a new macro as its first argument, the number -% of arguments for the new macro is taken as the second argument. -% \begin{macrocode} -\def:Npn\cmd_declare:Nnn#1[#2]{ - \cmd_arg_list_build{#2} - \exp_args:NNO\def:Npn#1\l_cmd_arg_list -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\io_show_file_lineno:} -% A function to add the number of the line and the name of the file -% to a message as an indication of where the message was triggered. -% \begin{macrocode} -\def_new:Npn \io_show_file_lineno:{ - on~line~\the_internal:D\tex_inputlineno:D\text_put_sp:~of~ - file~\g_file_curr_name_tlp} -% \end{macrocode} -% \end{macro} -% -% \subsubsection{Variables and constants} -% -% \begin{macro}{\g_err_help_toks} -% A token register to store the help text for an error message in. -% \begin{macrocode} -\let:NwN \g_err_help_toks \tex_errhelp:D -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\l_err_label_token} -% This will hold the current error label. -% \begin{macrocode} -\def_new:Npn \l_err_label_token {} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\tex_errorcontextlines:D} -% Since we are producing our own error and help messages we can -% turn off the nasty stack information coming from \TeX{}'s -% stomach. -% \begin{macrocode} -\int_set:Nn\tex_errorcontextlines:D\c_minus_one -% \end{macrocode} -% \end{macro} -% -% \subsubsection{Displaying the information} -% -% Here we define the fairly low level commands needed to -% communicate with the user. -% -% \begin{macro}{\err_info:nn} -% \begin{macro}{\err_warn:nn} -% Write a message to the log file ("\err_info:nn") or to both the -% log file and the terminal ("\err_warn:nn"). -% \begin{macrocode} -\def_new:Npn \err_info:nn #1#2{ -% \end{macrocode} -% Make sure that the \emph{continuation} is part of "\err_newline:". -% \begin{macrocode} - \def:Npn\err_newline:{\iow_newline:#2} -% \end{macrocode} -% Then write the message. -% \begin{macrocode} - \io_put_log:x {#1~\io_show_file_lineno:}} -\def_new:Npn \err_warn:nn #1#2{ - \def:Npn\err_newline:{\iow_newline:#2} - \io_put_term:x {#1~\io_show_file_lineno:}} -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\err_info_noline:nn} -% \begin{macro}{\err_warn_noline:nn} -% These variants of the above two functions don't add the -% linenumber to the message. -% \begin{macrocode} -\def_new:Npn \err_info_noline:nn #1#2{ - \def:Npn\err_newline:{\iow_newline:#2} - \io_put_log:x {#1}} -\def_new:Npn \err_warn_noline:nn #1#2{ - \def:Npn\err_newline:{\iow_newline:#2} - \io_put_term:x {#1}} -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\err_interrupt:NNw} -% |\err_interrupt:NNw| is the function that is called when some error -% occurs in the code. It takes at least two arguments, the -% \m{errfile} which is a token list that holds the name of the file -% where the error message should be fetched from, and the label to -% identify the error message in the error file. However, it may -% have additional arguments that are picked up by the error handler -% extracted from the error file. This is specified in the third -% argument to |\err_interrupt_new:NNNnnn|. -% \begin{macrocode} -\def_new:Npn \err_interrupt:NNw #1#2{\let:NwN \l_err_label_token #2 - \group_begin: -% \end{macrocode} -% For some reason we get some |\par|s into the file if we use the -% current definition of |\iow_long_unxepanded:N| to write the messages. -% This is probably a consequence of using token registers to -% prohibit the expansion of code. -% \begin{macrocode} - \let:NwN \par\use_noop: -% \end{macrocode} -% We want to ensure that we are not in programmer's mode (no spaces) -% but we want to switch on internal naming conventions. -% \begin{macrocode} - \CodeStop - \NamesStart: -% \end{macrocode} -% We better clear all short references that are active, otherwise -% we may get surprising results. -% \begin{macrocode} - %\clearshortrefmaps - \tex_input:D #1~\err_display_aux:w} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\err_fatal:nn} -% \begin{macro}{\err_fatal_noline:nn} -% Write a message to the log file and to the terminal. -% \begin{macrocode} -\def_new:Npn \err_fatal:nn #1#2{ -% \end{macrocode} -% Make sure that the \emph{continuation} is part of "\err_newline". -% \begin{macrocode} - \def:Npn\err_newline:{\iow_newline:#2} -% \end{macrocode} -% Then write the message. -% \begin{macrocode} - \io_put_term:x {#1~\io_show_file_lineno:} -% \end{macrocode} -% Finally abort the \LaTeX{} run. -% \begin{macrocode} - \tex_end:D - } -% \end{macrocode} -% A variant that doesn't include the line number where the error -% occured. -% \begin{macrocode} -\def_new:Npn \err_fatal_noline:nn #1#2{ - \def:Npn\err_newline:{\iow_newline:#2} - \io_put_term:x {#1} - \tex_end:D - } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\err_newline:} -% |\err_newline:| is used to introduce a new line in an error -% message. I would like to use |\\| but this would mean -% redefinition which should be avoided to make the error message -% the last action before control is given to the user (otherwise -% something like |\group_end:| would interfere with -% insertions/deletions by the user). "\err_newline:" will be -% redefined by the various functions displaying messages to include -% the correct \emph{continuation}. -% \begin{macrocode} -\def_new:Npn \err_newline: {^^J} -% \end{macrocode} -% \end{macro} -% -% \subsubsection{Dealing with the error file} -% -% This section contains code that combines Michaels original thoughts -% on the the subject with Denys' further ideas. -% -% \begin{macro}{\c_iow_err_stream} -% Error messages are logged using the output stream -% |\c_iow_err_stream|. -% \begin{macrocode} -\iow_new:N \c_iow_err_stream -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\g_err_curr_fname} -% A nick name for the currently open error file. It is empty -% if no error file is currently open. -% \begin{macrocode} -\tlp_new:Nn \g_err_curr_fname{} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\err_file_new:Nn} -% This function defines a new error file. The first argument is a -% token list which should hold the name of the error file, the second -% argument is the name of the error file. The token list should be -% a constant defined by this function. -% \begin{macrocode} -\def_new:Npn \err_file_new:Nn #1#2{ - \tlp_if_empty:NF\g_err_curr_fname - {\err_latex_bug:x{Unclosed~error~file~`\g_err_curr_fname'}} - \iow_open:Nn \c_iow_err_stream {#2} - \err_kernel_info:n{Errorfile~`#2'~opened~for~output} - \tlp_gset:Nn \g_err_curr_fname{#2} - \tlp_new:Nn #1{#2}} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\err_file_close:N} -% This function closes the current error file. -% \begin{macrocode} -\def_new:Npn \err_file_close:N#1{ -% \end{macrocode} -% Before we close the stream, we write out a final error handler -% that catches mismatch within error message labels and their -% calls. Actually this should be integrated into -% |\err_file_new:Nn|, too. -% \begin{macrocode} - \tlp_if_eq:NNF#1\g_err_curr_fname - {\err_latex_bug:x{You~closed~the~wrong~error~file~`#1'.~ - Open~is~`\g_err_curr_fname'.}} - \iow_long_unexpanded:Nn \c_iow_err_stream {\err_latex_bug:x{Didn't~find~the~ - correct~error~message~to~show.\iow_newline: - Was~searching~for~a~function~ - with~the~following~meaning:\iow_newline: - \token_to_string:N\token_to_meaning:N - \token_to_string:N\l_err_label_token} -% \end{macrocode} -% The |\group_end:| here matches the one from |\err_interrupt:NNw| that -% is used to hide changes to |\par| etc. -% \begin{macrocode} - \group_end:} - \iow_close:N \c_iow_err_stream - \err_kernel_info:n{Errorfile~`\g_err_curr_fname'~closed} - \tlp_gset_eq:NN\g_err_curr_fname\c_empty_tlp -} -% \end{macrocode} -% \end{macro} -% -% \subsubsection{Declaring an error message in the error file} -% -% \begin{macro}{\err_interrupt_new:NNNnnn} -% This function declares a new error message. -% |\err_interrupt_new:NNNnnn| \m{errfile} \m{errlabel} \m{argno} -% \m{errmsg} \m{helpmsg} \m{code}. That error message is fetched -% from the error file \m{errfile}. The label to search for is -% \m{errlabel}, the error handler has \m{argno} number of arguments -% (actually \m{argno} + 3 since the \m{errmsg}, \m{helpmsg} and -% \m{code} are also arguments), and \m{errmsg} is the message to -% display, \m{helpmsg} is the message that is displayed when the -% user enters |h|, while \m{code} is extra code to perform when the -% error occurs. \m{code} is perhaps not necessary, we will see. -% -% We have to check that the label associated with the error message -% is unique. This means that its replacement text (labels are -% simply arbitrary functions) is different from the replacement -% text of any other label in the same error set. -% \begin{macrocode} -\def_new:Npn \err_interrupt_new:NNNnnn #1{ -% \end{macrocode} -% Both \m{errmsg} and \m{code} might contain hashmarks denoting -% arguments to the error handler. -% \begin{macrocode} - \group_begin: \char_set_catcode:nn{`\#}{12} -% \end{macrocode} -% We also have to check that output goes to the correct error file. -% \begin{macrocode} - \if_meaning:NN#1\g_err_curr_fname - \else: - \err_latex_bug:x{Error~text~goes~to~wrong~err~file:~ - `\g_err_curr_fname'~is~open~but~you~requested~ - `#1'} - \fi: - \err_interrupt_new_aux:w} -\def_long_new:Npn \err_interrupt_new_aux:w #1#2#3#4#5{ - \iow_long_unexpanded:Nn \c_iow_err_stream - {\err_msgline_aux:NNnnn #1#2{#3}{#4}{#5}\use_noop:} - \group_end:} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\err_msgline_aux:NNnnn} -% This function is executed when an error file is read back by -% |\err_interrupt:NNw|. It compares its first argument against -% |\l_err_label_token| using |\if_meaning:NN| and if this fails the -% function does nothing; otherwise it defines |\err_display_aux:w| in -% a way that it will pick up the arguments (if any) from the code and -% generates a suitable error message. -% \begin{macrocode} -\def_new:Npn \err_msgline_aux:NNnnn #1#2#3#4#5{ - \if_meaning:NN#1\l_err_label_token -% \end{macrocode} -% At the moment we simply use the old \LaTeX{} error code and -% |\renewcommand| to generate the error handler. After displaying -% the error message we insert error code this can be manipulated by -% the user with the deletion/insertion facility of \TeX{}'s error -% mechanism. -% -% The |\group_end:| at the very beginning matches the -% |\group_begin:| when the file starts. -% \begin{macrocode} - \cmd_declare:Nnn\err_display_aux:w [#2]{ - \group_end: - \toks_gset:Nx\g_err_help_toks{#4} - \io_put_term:x{LaTeX~error~\io_show_file_lineno:.\iow_newline: - \text_put_sp:\text_put_four_sp: \text_put_sp: - See~LaTeX~manual~for~explanation.\iow_newline: - \text_put_sp:\text_put_four_sp: \text_put_sp: - Type~\text_put_sp: H~<return>~\text_put_sp: for~ - immediate~help.} - \err_message:x{#3} - #5} - \tex_endinput:D - \fi:} -% \end{macrocode} -% \end{macro} -% -% -% \begin{macro}{\err_display_aux:w} -% We should make sure that this function is definable. -% \begin{macrocode} -\def_new:Npn \err_display_aux:w {} -% \end{macrocode} -% \end{macro} -% -% \subsubsection{Kernel specific functions} -% -% \begin{macro}{\err_kernel_interrupt:Nw} -% |\err_kernel_interrupt:Nw | is just the abbreviation to read from -% the standard system error file. -% \begin{macrocode} -\def_new:Npn \err_kernel_interrupt:Nw {\err_interrupt:NNw \c_kernel_err_tlp} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\err_kernel_interrupt_new:NNnnn} -% To ease the coding in case of system messages that should all go -% to one and the same error file (if!) we also have the following -% function. -% \begin{macrocode} -\def_new:Npn \err_kernel_interrupt_new:NNnnn { - \err_interrupt_new:NNNnnn \c_kernel_err_tlp} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\err_kernel_info:n} -% \begin{macro}{\err_kernel_warn:n} -% \begin{macro}{\err_kernel_fatal:n} -% \begin{macro}{\err_kernel_info_noline:n} -% \begin{macro}{\err_kernel_warn_noline:n} -% \begin{macro}{\err_kernel_fatal_noline:n} -% These variants are specific for the \LaTeX\ kernel. -% \begin{macrocode} -\def_new:Npn \err_kernel_info:n #1 { - \err_info:nn {LaTeX~Info:~#1} - {\text_put_four_sp:\text_put_four_sp:\text_put_four_sp:} - } -\def_new:Npn \err_kernel_warn:n #1 { - \err_warn:nn {LaTeX~Warning:~#1} - {\text_put_sp:\text_put_sp:\text_put_sp: - \text_put_four_sp:\text_put_four_sp:\text_put_four_sp:} - } -\def_new:Npn \err_kernel_fatal:n #1 { - \err_fatal:nn {LaTeX~Fatal:~#1} - {\text_put_sp: - \text_put_four_sp:\text_put_four_sp:\text_put_four_sp:} - } -\def_new:Npn \err_kernel_info_noline:n #1 { - \err_info_noline:nn {LaTeX~Info:~#1} - {\text_put_four_sp:\text_put_four_sp:\text_put_four_sp:} - } -\def_new:Npn \err_kernel_warn_noline:n #1 { - \err_warn_noline:nn {LaTeX~Warning:~#1} - {\text_put_sp:\text_put_sp:\text_put_sp: - \text_put_four_sp:\text_put_four_sp:\text_put_four_sp:} - } -\def_new:Npn \err_kernel_fatal_noline:n #1 { - \err_fatal_noline:nn {LaTeX~Fatal:~#1} - {\text_put_sp: - \text_put_four_sp:\text_put_four_sp:\text_put_four_sp:} - } -%</initex|package> -% \end{macrocode} -% At a later stage variants may be provided for what in \LaTeXe{} -% used to be called document classes and packages. -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\c_kernel_err_tlp} -% Most error messages will go to the system error file; it's name is -% stored in |\c_kernel_err_tlp|. -% \begin{macrocode} -%<initex>\err_file_new:Nn \c_kernel_err_tlp {ltxkernel.err} -%<package>\err_file_new:Nn \c_kernel_err_tlp {l3in2e.err} -% \end{macrocode} -% \end{macro} -% -% The code below is a temporary implementation of a few of -% \LaTeX209 error messages with the new syntax. They are only -% included in the package as the \LaTeX3 kernel will certainly have -% it's own error message definitions that differ from \LaTeXe's way -% of signalling errors. These primarily serve as an example on how -% to use this concept of dealing with errors. -% -% First we declare a couple of helper macros that contain texts -% that are used frequently throughout \LaTeX. -% \begin{macrocode} -%<*package> -\def:Npn\err_help_ignored: { - Your~command~was~ignored.\iow_newline: - Type \text_put_sp: I~<command>~<return> - \text_put_sp: to~replace~it~with~another~command,\iow_newline: - or~\text_put_sp: <return> \text_put_sp: to~continue~without~it.} - -\def:Npn\err_help_textlost: { - You've~lost~some~text.\text_put_sp: \err_help_return_or_X:} - -\def:Npn\err_help_return_or_X: { - Try~typing\text_put_sp: <return> - \text_put_sp: to~proceed.\iow_newline: - If~that~doesn't~work,~type - \text_put_sp: X~<return>\text_put_sp: to~quit.} - -\def:Npn\err_help_trouble: { - You're~ in~ trouble~ here. - \text_put_sp:\err_help_return_or_X:} -% \end{macrocode} -% -% Below are the definitions of the complete messages -% \begin{macrocode} - -\err_kernel_interrupt_new:NNnnn\cs_free_p:N{1} - {Command~name~`\tex_string:D#1'~already~used} - {You~tried~to~define~a~command~which~already~has~ - a~meaning.\iow_newline: - If~you~really~want~to~redefine~it~try~ - \token_to_string:N\cmd_declare:Nnn\text_put_sp: - next~time.\iow_newline: - For~this~run~I~will~ignore~your~definition.} - {} - -\err_kernel_interrupt_new:NNnnn\newline{0} - {There's~no~line~here~to~end} - {You~tried~to~end~a~line~at~a~place~where~I~thought~ - we~were~already~between~paragraphs.} - {} - -\err_kernel_interrupt_new:NNnnn\newcnt{0} - {No~such~counter} - {The~counter~name~mentioned~in~the~operation~is~not~ - known~to~me.\iow_newline: - Check~the~spelling.} - {} - -\err_kernel_interrupt_new:NNnnn\nodocument{0} - {Missing~\token_to_string:N\begin{document}} - {\err_help_trouble:} - {} - -\err_kernel_interrupt_new:NNnnn\badmath{0} - {Bad~math~environment~delimiter} - {\err_help_ignored:} - {} - -\err_kernel_interrupt_new:NNnnn\toodeep{0} - {Too~deeply~nested} - {\err_help_trouble:} - {} - -\err_kernel_interrupt_new:NNnnn\badpoptabs{0} - {\token_to_string:N\pushtabs \text_put_sp: - and~\token_to_string:N\poptabs - \text_put_sp: don't~match} - {\err_help_trouble:} - {} - -\err_kernel_interrupt_new:NNnnn\badtab{0} - {Undefined~tab~position} - {\err_help_trouble:} - {} - -\err_kernel_interrupt_new:NNnnn\preamerr{} - {\if_case:w #1~Illegal~character\or: - Missing~@-exp\or: Missing~p-arg\fi:\text_put_sp: - in~array~arg} - {\err_help_trouble:} - {} - -\err_kernel_interrupt_new:NNnnn\badlinearg{} - {Bad~\token_to_string:N\line - \text_put_sp: or~\token_to_string:N\vector - \text_put_sp: argument} - {\err_help_textlost:} - {} - -\err_kernel_interrupt_new:NNnnn\parmoderr{0} - {Not~in~outer~par~mode} - {\err_help_textlost:} - {} - -\err_kernel_interrupt_new:NNnnn\fltovf{0} - {Too~many~unprocessed~floats} - {\err_help_textlost:} - {} - -\err_kernel_interrupt_new:NNnnn\badcrerr{0} - {Bad~use~of~\token_to_string:N\\} - {\err_help_return_or_X:} - {} - -\err_kernel_interrupt_new:NNnnn\noitemerr{0} - {Something's~wrong--perhaps~a~missing~ - \token_to_string:N\item} - {\err_help_return_or_X:} - {} - -\err_kernel_interrupt_new:NNnnn\notprerr{0} - {Can~be~used~only~in~preamble} - {\err_help_ignored:} - {} - -\err_file_close:N\c_kernel_err_tlp -%<package> -% \end{macrocode} -% -% -% Show token usage: -% \begin{macrocode} -%<*showmemory> -\showMemUsage -%</showmemory> -% \end{macrocode} -% -% \endinput -% -% $Log$ -% Revision 1.9 2006/03/19 15:07:47 braams -% Moved some code to other modules, where it belongs; -% reverted \c_io_newline to \iow_newline (it'scontents might need to be -% modified sometine) -% Example messages are not part of the kernel, only for the package. -% -% Revision 1.8 2006/02/15 23:45:46 braams -% Rearranged the file; -% implemented \err_fatal:nn and \err_fatal_noline:nn -% Recode the remaining error definitions for testing purposes -% -% Revision 1.7 2006/01/15 09:48:54 braams -% Mostly textual changes -% -% Revision 1.6 2005/12/27 16:01:27 morten -% Changed RCS information retrieval plus a few minor changes -% -% Revision 1.5 2005/05/05 23:45:49 braams -% Worked on the documentation; -% added commands \err_info:nn, \err_warn:nn and kernel specific versions -% of these. -% Changed \iow_newline: into \c_io_newline; introduced \err_newline: to -% be used in messages with multiple lines to provide a continuation -% string. -% Renamed \style_names_start and \style_names_stop: into \NamesStart: -% and \NamesStop:. -% -% Revision 1.4 2005/05/03 23:34:52 braams -% Added code that performs the basic function of the old \renewcommand -% Added a couple of new functions that need to live in other modules -% Documentation still needs to be corrected -% The module now basically works -% -% Revision 1.3 2005/04/29 22:39:47 braams -% Another one -% -% Revision 1.2 2005/04/29 22:34:39 braams -% Small typo in the RCS tags -% -% Revision 1.1 2005/04/29 22:30:44 braams -% first version that can be loaded without producing errors. -% Just a translation from the old stuff, haven't looked at the docu yet diff --git a/Master/texmf-dist/source/latex/expl3/l3msg.dtx b/Master/texmf-dist/source/latex/expl3/l3msg.dtx new file mode 100644 index 00000000000..4eb211be1a6 --- /dev/null +++ b/Master/texmf-dist/source/latex/expl3/l3msg.dtx @@ -0,0 +1,1336 @@ +% \iffalse +%% File: l3msg.dtx Copyright (C) 2009 LaTeX3 project +%% +%% It may be distributed and/or modified under the conditions of the +%% LaTeX Project Public License (LPPL), either version 1.3c of this +%% license or (at your option) any later version. The latest version +%% of this license is in the file +%% +%% http://www.latex-project.org/lppl.txt +%% +%% This file is part of the ``expl3 bundle'' (The Work in LPPL) +%% and all files in that bundle must be distributed together. +%% +%% The released version of this bundle is available from CTAN. +%% +%% ----------------------------------------------------------------------- +%% +%% The development version of the bundle can be found at +%% +%% http://www.latex-project.org/svnroot/experimental/trunk/ +%% +%% for those people who are interested. +%% +%%%%%%%%%%% +%% NOTE: %% +%%%%%%%%%%% +%% +%% Snapshots taken from the repository represent work in progress and may +%% not work or may contain conflicting material! We therefore ask +%% people _not_ to put them into distributions, archives, etc. without +%% prior consultation with the LaTeX Project Team. +%% +%% ----------------------------------------------------------------------- +%% +% +%<*driver|package> +\RequirePackage{l3names} +%</driver|package> +%\fi +\GetIdInfo$Id: l3msg.dtx 1362 2009-05-28 20:19:21Z joseph $ + {L3 Experimental LaTeX Messages module} +%\iffalse +%<*driver> +%\fi +\ProvidesFile{\filename.\filenameext} + [\filedate\space v\fileversion\space\filedescription] +%\iffalse +\documentclass[full]{l3doc} +\begin{document} +\DocInput{l3msg.dtx} +\end{document} +%</driver> +% \fi +% +% \title{The \textsf{l3msg} package\thanks{This file +% has version number \fileversion, last +% revised \filedate.}\\ +% Communicating with the user} +% \author{\Team} +% \date{\filedate} +% \maketitle +% +% \begin{documentation} +% +% Messages need to be passed to the user by modules, either when errors +% occur or to indicate how the code is proceeding. The \pkg{l3msg} +% module provides a consistent method for doing this (as opposed to +% writing directly to the terminal or log). +% +% The system used by \pkg{l3msg} to create messages divides the process +% into two distinct parts. Named messages are created in the first part +% of the process; at this stage, no decision is made about the type +% output that the message will produce. The second part of the process +% is actually producing a message. At this stage a choice of message +% \emph{class} has to be made, for example \texttt{error}, +% \texttt{warning} or \texttt{info}. +% +% By separating out the creation and use of messages, several benefits +% are available. First, the messages can be altered later without +% needing details of where they are used in the code. This makes it +% possible to alter the language used, the detail level and so on. +% Secondly, the output which results from a given message can be +% altered. This can be done on a message class, module or message name +% basis. In this way, message behaviour can be altered and messages can +% be entirely suppressed. +% +% \section{Creating new messages} +% +% All messages have to be created before they can be used. Inside the +% message text, spaces are \emph{not} ignored. A space where \TeX\ +% would normally gobble one can be created using |\ |, and a new line +% with |\\|. New lines may have ``continuation'' text added by the +% output system. +% +%\begin{function}{ +% \msg_new:nnnnn| +% \msg_new:nnnn| +% \msg_new:nnn| +% \msg_set:nnnnn| +% \msg_set:nnnn| +% \msg_set:nnn +%} +% \begin{syntax} +% "\msg_new:nnnn" <module> <name> <text> <more text> <code> +% \end{syntax} +% Creates new message <name> for <module> to produce <text> initially, +% <more text> if requested by the user and to insert <code> after the +% message when used as an error. <text> and <more text> can use up to +% two macro parameters (|#1| and |#2|), which are supplied by the +% message system. Inside <text> and <more text> spaces are not ignored. +%\end{function} +% +% \section{Message classes} +% +% Creating message output requires the message to be given a class. +% +%\begin{function}{ +% \msg_class_new:nn| +% \msg_class_set:nn +%} +% \begin{syntax} +% "\msg_class_new:nn" <class> <code> +% \end{syntax} +% Creates new <class> to output a message, using <code> to process +% the message text. +%\end{function} +% +% The module defines several common message classes. The following +% describes the standard behaviour of each class if no redirection of +% the class or message is active. +% +%\begin{function}{ +% \msg_fatal:nnxx| +% \msg_fatal:nnx| +% \msg_fatal:nn +%} +% \begin{syntax} +% "\msg_fatal:nnxx" <module> <name> <arg one> <arg two> +% \end{syntax} +% Issues <module> error message <name>, passing <arg one> and +% <arg two> to the text-creating functions. The \TeX\ run then halts. +%\end{function} +% +%\begin{function}{ +% \msg_error:nnxx| +% \msg_error:nnx| +% \msg_error:nn +%} +% \begin{syntax} +% "\msg_error:nnxx" <module> <name> <arg one> <arg two> +% \end{syntax} +% Issues <module> error message <name>, passing <arg one> and +% <arg two> to the text-creating functions. +% \begin{texnote} +% The standard output here is similar to \cs{PackageError}. +% \end{texnote} +%\end{function} +% +%\begin{function}{ +% \msg_warning:nnxx| +% \msg_warning:nnx| +% \msg_warning:nn +%} +% \begin{syntax} +% "\msg_warning:nnxx" <module> <name> <arg one> <arg two> +% \end{syntax} +% Prints <module> message <name> to the terminal, passing <arg one> and +% <arg two> to the text-creating functions. +% \begin{texnote} +% The standard output here is similar to \cs{PackageWarningNoLine}. +% \end{texnote} +%\end{function} +% +%\begin{function}{ +% \msg_info:nnxx| +% \msg_info:nnx| +% \msg_info:nn +%} +% \begin{syntax} +% "\msg_info:nnxx" <module> <name> <arg one> <arg two> +% \end{syntax} +% Prints <module> message <name> to the log, passing <arg one> and +% <arg two> to the text-creating functions. +% \begin{texnote} +% The standard output here is similar to \cs{PackageInfoNoLine}. +% \end{texnote} +%\end{function} +% +%\begin{function}{ +% \msg_log:nnxx| +% \msg_log:nnx| +% \msg_log:nn +%} +% \begin{syntax} +% "\msg_info:nnxx" <module> <name> <arg one> <arg two> +% \end{syntax} +% Prints <module> message <name> to the log, passing <arg one> and +% <arg two> to the text-creating functions. No continuation text is +% added. +%\end{function} +% +%\begin{function}{ +% \msg_trace:nnxx| +% \msg_trace:nnx| +% \msg_trace:nn +%} +% \begin{syntax} +% "\msg_info:nnxx" <module> <name> <arg one> <arg two> +% \end{syntax} +% Prints <module> message <name> to the log, passing <arg one> and +% <arg two> to the text-creating functions. No continuation text is +% added. +%\end{function} +% +%\begin{function}{ +% \msg_none:nnxx| +% \msg_none:nnx| +% \msg_none:nn +%} +% \begin{syntax} +% "\msg_none:nnxx" <module> <name> <arg one> <arg two> +% \end{syntax} +% Does nothing: used for redirecting other message classes. +%\end{function} +% +% \section{Redirecting messages} +% +%\begin{function}{\msg_redirect_class:nn} +% \begin{syntax} +% "\msg_redirect_class:nn" <class one> <class two> +% \end{syntax} +% Redirect all messages of <class one> to appear as those of +% <class two>. +%\end{function} +% +%\begin{function}{\msg_redirect_module:nnn} +% \begin{syntax} +% "\msg_redirect_module:nnn" <class one> <module> <class two> +% \end{syntax} +% Redirect <module> messages of <class one> to appear in <class two>. +% \begin{texnote} +% This function can be used to make some messages ``silent'' by +% default. For example, all of the \texttt{trace} messages of +% <module> could be turned off with: +% \begin{verbatim} +% \msg_redirect_module:nnn { trace } { module } { none } +% \end{verbatim} +% \end{texnote} +%\end{function} +% +%\begin{function}{\msg_redirect_name:nnn} +% \begin{syntax} +% "\msg_redirect_name:nnn" <module> <message> <class> +% \end{syntax} +% Redirect <module> <message> to appear using <class>. +%\end{function} +% +% \section{Support functions for output} +% +%\begin{function}{\msg_line_context:} +% \begin{syntax} +% "\msg_line_context:" +% \end{syntax} +% Prints the current line number preceded by \cs{c_msg_on_line_tl}. +%\end{function} +% +%\begin{function}{\msg_line_number:} +% \begin{syntax} +% "\msg_line_number:" +% \end{syntax} +% Prints the current line number. +%\end{function} +% +%\begin{function}{ +% \msg_newline:| +% \msg_two_newlines: +%} +% \begin{syntax} +% "\msg_newline:" +% \end{syntax} +% Print one or two newlines with no continuation information. +%\end{function} +% +%\begin{function}{ +% \msg_space:| +% \msg_two_spaces:| +% \msg_four_spaces: +%} +% \begin{syntax} +% "\msg_space:" +% \end{syntax} +% Print one, two or four spaces: needed where a literal space would +% otherwise be gobbled by \TeX. +%\end{function} +% +% \section{Low-level functions} +% +% The low-level functions do not make assumptions about module names. +% The output functions here produce messages directly, and do not +% respond to redirection. +% +%\begin{function}{ +% \msg_generic_new:nnnn| +% \msg_generic_new:nnn| +% \msg_generic_new:nn| +% \msg_generic_set:nnnn| +% \msg_generic_set:nnn| +% \msg_generic_set:nn +%} +% \begin{syntax} +% "\msg_generic_new:nnnn" <name> <text> <more text> <code> +% \end{syntax} +% Creates new message <name> to produce <text> initially, <more text> +% if requested by the user and to insert <code> after the message when +% used as an error. <text> and <more text> can use up to two macro +% parameters (|#1| and |#2|), which are supplied by the message system. +% Inside <text> and <more text> spaces are not ignored. +%\end{function} +% +%\begin{function}{\msg_direct_interrupt:xxxxn} +% \begin{syntax} +% "\msg_direct_interrupt:xxxxn" <first line> <text> +% ~~~~<continuation> <more text> <code> +% \end{syntax} +% Executes a \TeX\ error, interrupting compilation. The <first line> +% is displayed followed by <text> and the input prompt. <more text> is +% displays if requested by the user, and <code> is inserted after the +% message. If <more text> is blank a default is supplied. Each line of +% <text> (broken with |\\|) begins with <continuation>. +%\end{function} +% +%\begin{function}{ +% \msg_direct_log:xx| +% \msg_direct_term:xx +%} +% \begin{syntax} +% "\msg_direct_log:xx" <text> <continuation> +% \end{syntax} +% Prints <text> to either the log or terminal. New lines (broken +% with |\\|) start with <continuation>. +%\end{function} +% +% \section{Kernel-specific functions} +% +%\begin{function}{ +% \msg_kernel_new:nnnn| +% \msg_kernel_new:nnn| +% \msg_kernel_new:nn| +% \msg_kernel_set:nnnn| +% \msg_kernel_set:nnn| +% \msg_kernel_set:nn +%} +% \begin{syntax} +% "\msg_kernel_new:nnn" <name> <text> <more text> <code> +% \end{syntax} +% Creates new kernel message <name> to produce <text> initially, +% <more text> if requested by the user and to insert <code> after the +% message when used as an error. <text> and <more text> can use up to +% two macro parameters (|#1| and |#2|), which are supplied by the +% message system. +%\end{function} +% +%\begin{function}{ +% \msg_kernel_fatal:nxx| +% \msg_kernel_fatal:nx| +% \msg_kernel_fatal:n +%} +% \begin{syntax} +% "\msg_kernel_fatal:nxx" <name> <arg one> <arg two> +% \end{syntax} +% Issues kernel error message <name>, passing <arg one> and +% <arg two> to the text-creating functions. The \TeX\ run then halts. +% Cannot be redirected. +%\end{function} +% +%\begin{function}{ +% \msg_kernel_error:nxx| +% \msg_kernel_error:nx| +% \msg_kernel_error:n +%} +% \begin{syntax} +% "\msg_kernel_error:nxx" <name> <arg one> <arg two> +% \end{syntax} +% Issues kernel error message <name>, passing <arg one> and +% <arg two> to the text-creating functions. Cannot be redirected. +%\end{function} +% +%\begin{function}{ +% \msg_kernel_warning:nxx| +% \msg_kernel_warning:nx| +% \msg_kernel_warning:n +%} +% \begin{syntax} +% "\msg_kernel_warning:nxx" <name> <arg one> <arg two> +% \end{syntax} +% Prints kernel message <name> to the terminal, passing <arg one> and +% <arg two> to the text-creating functions. +%\end{function} +% +%\begin{function}{ +% \msg_kernel_info:nxx| +% \msg_kernel_info:nx| +% \msg_kernel_info:n +%} +% \begin{syntax} +% "\msg_kernel_info:nxx" <name> <arg one> <arg two> +% \end{syntax} +% Prints kernel message <name> to the log, passing <arg one> and +% <arg two> to the text-creating functions. +%\end{function} +% +%\begin{function}{\msg_kernel_bug:x} +% \begin{syntax} +% "\msg_kernel_bug:x" <text> +% \end{syntax} +% Short-cut for ``This is a LaTeX bug: check coding'' errors. +%\end{function} +% +% \section{Variables and constants} +% +%\begin{variable}{ +% \c_msg_fatal_tl| +% \c_msg_error_tl| +% \c_msg_warning_tl| +% \c_msg_info_tl +%} +% Simple headers for errors. +%\end{variable} +% +%\begin{variable}{ +% \c_msg_fatal_text_tl| +% \c_msg_help_text_tl| +% \c_msg_kernel_bug_text_tl| +% \c_msg_kernel_bug_more_text_tl| +% \c_msg_no_info_text_tl| +% \c_msg_return_text_tl +%} +% Various pieces of text for use in messages, which are not changed by +% the code here although they could be to alter the language. +%\end{variable} +% +%\begin{variable}{\c_msg_on_line_tl} +% The ``on line'' phrase for line numbers. +%\end{variable} +% +%\begin{variable}{ +% \c_msg_text_prefix_tl| +% \c_msg_more_text_prefix_tl| +% \c_msg_code_prefix_tl +%} +% Header information for storing the ``paths'' to parts of a message. +%\end{variable} +% +%\begin{variable}{ +% \l_msg_class_tl| +% \l_msg_current_class_tl +%} +% Information about message method, used for filtering. +%\end{variable} +% +%\begin{variable}{\l_msg_names_clist} +% List of all of the message names defined. +%\end{variable} +% +%\begin{variable}{ +% \l_msg_redirect_classes_prop| +% \l_msg_redirect_names_prop +%} +% Re-direction lists containing the class of message to convert an +% different one. +%\end{variable} +% +%\begin{variable}{\l_msg_redirect_classes_clist} +% List so that filtering does not loop. +%\end{variable} +% +% \end{documentation} +% +% \begin{implementation} +% +% \section{\pkg{l3msg} implementation} +% +% The usual lead-off. +% \begin{macrocode} +%<*package> +\ProvidesExplPackage + {\filename}{\filedate}{\fileversion}{\filedescription} +\package_check_loaded_expl: +%</package> +%<*initex|package> +% \end{macrocode} +% +% \LaTeX\ is handling context, so the \TeX\ ``noise'' is turned down. +% \begin{macrocode} +\int_set:Nn \tex_errorcontextlines:D { \c_minus_one } +% \end{macrocode} +% +% \subsection{Variables and constants} +% +%\begin{macro}{\c_msg_fatal_tl} +%\begin{macro}{\c_msg_error_tl} +%\begin{macro}{\c_msg_warning_tl} +%\begin{macro}{\c_msg_info_tl} +% Header information. +% \begin{macrocode} +\tl_new:Nn \c_msg_fatal_tl { Fatal~Error } +\tl_new:Nn \c_msg_error_tl { Error } +\tl_new:Nn \c_msg_warning_tl { Warning } +\tl_new:Nn \c_msg_info_tl { Info } +% \end{macrocode} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\c_msg_fatal_text_tl} +%\begin{macro}{\c_msg_help_text_tl} +%\begin{macro}{\c_msg_kernel_bug_text_tl} +%\begin{macro}{\c_msg_kernel_bug_more_text_tl} +%\begin{macro}{\c_msg_no_info_text_tl} +%\begin{macro}{\c_msg_return_text_tl} +% Simple pieces of text for messages. +% \begin{macrocode} +\tl_new:Nn \c_msg_fatal_text_tl { + This~is~a~fatal~error:~LaTeX~will~abort +} +\tl_new:Nn \c_msg_help_text_tl { + For~immediate~help~type~H~<return> +} +\tl_new:Nn \c_msg_kernel_bug_text_tl { + This~is~a~LaTeX~bug:~check~coding! +} +\tl_new:Nn \c_msg_kernel_bug_more_text_tl { + There~is~a~coding~bug~somewhere~around~here. + \msg_newline: + This~probably~needs~examining~by~an~expert. + \c_msg_return_text_tl +} +\tl_new:Nn \c_msg_no_info_text_tl { + LaTeX~does~not~know~anything~more~about~this~error,~sorry. + \c_msg_return_text_tl +} +\tl_new:Nn \c_msg_return_text_tl { + \msg_two_newlines: + Try~typing~<return>~to~proceed. + \msg_newline: + If~that~doesn't~work,~type~X~<return>~to~quit +} +% \end{macrocode} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +% +%\begin{macro}[aux]{\c_msg_hide_tl<spaces>} +% An empty variable with a number of (category code 11) spaces at the +% end of its name. This is used to push the \TeX\ part of an error +% message ``off the screen''. +% +% No indentation here as \verb*| | is a letter! +% \begin{macrocode} +\group_begin: +\char_make_letter:N\ % +\tl_to_lowercase:n{% +\group_end:% +\tl_new:Nn% +\c_msg_hide_tl % +{}% +}% +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\c_msg_on_line_tl} +% ``On line''. +% \begin{macrocode} +\tl_new:Nn \c_msg_on_line_tl { on~line } +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\c_msg_text_prefix_tl} +%\begin{macro}{\c_msg_more_text_prefix_tl} +%\begin{macro}{\c_msg_code_prefix_tl} +% Prefixes for storage areas. +% \begin{macrocode} +\tl_new:Nn \c_msg_text_prefix_tl { msg_text // } +\tl_new:Nn \c_msg_more_text_prefix_tl { msg_text_more // } +\tl_new:Nn \c_msg_code_prefix_tl { msg_code // } +% \end{macrocode} +%\end{macro} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\l_msg_class_tl} +%\begin{macro}{\l_msg_current_class_tl} +% For holding the current message method and that for redirection. +% \begin{macrocode} +\tl_new:N \l_msg_class_tl +\tl_new:N \l_msg_current_class_tl +% \end{macrocode} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\l_msg_names_clist} +% Lists used for filtering. +% \begin{macrocode} +\clist_new:N \l_msg_names_clist +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\l_msg_redirect_classes_prop} +%\begin{macro}{\l_msg_redirect_names_prop} +% For filtering messages, a list of all messages and of those which have +% to be modified is required. +% \begin{macrocode} +\prop_new:N \l_msg_redirect_classes_prop +\prop_new:N \l_msg_redirect_names_prop +% \end{macrocode} +%\end{macro} +%\end{macro} +%\begin{macro}{\l_msg_redirect_classes_clist} +% To prevent an infinite loop. +% \begin{macrocode} +\clist_new:N \l_msg_redirect_classes_clist +% \end{macrocode} +%\end{macro} +% +% \subsection{Output helper functions} +% +%\begin{macro}{\msg_line_number:} +%\begin{macro}{\msg_line_context:} +% For writing the line number nicely. +% \begin{macrocode} +\cs_new_nopar:Nn { \msg_line_number: } { + \toks_use:N \tex_inputlineno:D +} +\cs_new_nopar:Nn { \msg_line_context: } { + \msg_space: + \c_msg_on_line_tl + \msg_space: + \msg_line_number: +} +% \end{macrocode} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\msg_newline:} +%\begin{macro}{\msg_two_newlines:} +% Always forces a new line. +% \begin{macrocode} +\cs_new_nopar:Nn \msg_newline: { ^^J } +\cs_new_nopar:Nn \msg_two_newlines: { ^^J ^^J } +% \end{macrocode} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\msg_space:} +%\begin{macro}{\msg_two_spaces:} +%\begin{macro}{\msg_four_spaces:} +% For printing spaces, some very simple functions. +% \begin{macrocode} +\cs_new_nopar:Nn \msg_space: { ~ } +\cs_new_nopar:Nn \msg_two_spaces: { \msg_space: \msg_space: } +\cs_new_nopar:Nn \msg_four_spaces: { \msg_two_spaces: \msg_two_spaces: } +% \end{macrocode} +%\end{macro} +%\end{macro} +%\end{macro} +% +%\subsection{Generic functions} +% +% The lowest level functions make no assumptions about modules, +% \emph{etc.} +% +%\begin{macro}{\msg_generic_new:nnnn} +%\begin{macro}{\msg_generic_new:nnn} +%\begin{macro}{\msg_generic_new:nn} +% Creating a new message is basically the same as the non-checking +% version, and so after a check everything hands over. +% \begin{macrocode} +\cs_new_nopar:Npn \msg_generic_new:nnnn #1 { + \exp_args:Nc \chk_if_free_cs:N { \c_msg_text_prefix_tl #1 :nn } + \msg_generic_set:nnnn {#1} +} +\cs_new_nopar:Npn \msg_generic_new:nnn #1 { + \exp_args:Nc \chk_if_free_cs:N { \c_msg_text_prefix_tl #1 :nn } + \msg_generic_set:nnn {#1} +} +\cs_new_nopar:Npn \msg_generic_new:nn #1 { + \exp_args:Nc \chk_if_free_cs:N { \c_msg_text_prefix_tl #1 :nn } + \msg_generic_set:nn {#1} +} +% \end{macrocode} +%\end{macro} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\msg_generic_set:nnnn} +%\begin{macro}{\msg_generic_set:nnn} +%\begin{macro}{\msg_generic_set:nn} +%\begin{macro}[aux]{\msg_generic_set_clist:n} +%\begin{macro}[aux]{\msg_generic_set_text:n} +%\begin{macro}[aux]{\msg_generic_set_more_text:n} +%\begin{macro}[aux]{\msg_generic_set_code:n} +% Creating a message is quite simple. There must be a short text part, +% while the other parts may not exist. To avoid filling up the hash +% table with empty functions,only non-empty arguments are stored. +% The various auxiliary functions are used to allow spaces in the +% text arguments. +% \begin{macrocode} +\cs_new_nopar:Npn \msg_generic_set:nnnn #1 { + \msg_generic_set_clist:n {#1} + \char_make_space:N \ % + \msg_generic_set_code:nnnn{#1}% +} +\cs_new_nopar:Npn \msg_generic_set:nnn #1 { + \msg_generic_set_clist:n {#1} + \char_make_space:N \ % + \msg_generic_set_more_text:nnn{#1}% +} +\cs_new_nopar:Npn \msg_generic_set:nn #1 { + \msg_generic_set_clist:n {#1} + \char_make_space:N \ % + \msg_generic_set_text:nn{#1}% +} +\cs_new_nopar:Npn \msg_generic_set_clist:n #1 { + \clist_if_in:NnF \l_msg_names_clist { // #1 / } { + \clist_put_right:Nn \l_msg_names_clist { // #1 / } + } +} +\cs_new:Nn \msg_generic_set_text:nn { + \cs_set:cn { \c_msg_text_prefix_tl #1 :nn } {#2} + \char_make_ignore:N \ +} +\cs_new:Nn \msg_generic_set_more_text:nnn { + \cs_set:cn { \c_msg_text_prefix_tl #1 :nn } {#2} + \tl_if_empty:nTF {#3} { + \cs_set_eq:cN { \c_msg_more_text_prefix_tl #1 } \c_undefined + }{ + \cs_set:cn { \c_msg_more_text_prefix_tl #1 :nn } {#3} + } + \char_make_ignore:N \ +} +\cs_new:Npn \msg_generic_set_code:nnnn #1#2#3 { + \cs_set:cn { \c_msg_text_prefix_tl #1 :nn } {#2} + \tl_if_empty:nTF {#3} { + \cs_set_eq:cN { \c_msg_more_text_prefix_tl #1 } \c_undefined + }{ + \cs_set:cn { \c_msg_more_text_prefix_tl #1 :nn } {#3} + } + \char_make_ignore:N \ + \msg_generic_set_code:nn {#1} +} +\cs_new:Nn \msg_generic_set_code:nn { + \tl_if_empty:nTF {#2} { + \cs_set_eq:cN { \c_msg_code_prefix_tl #1 : } \c_undefined + }{ + \cs_set:cn { \c_msg_code_prefix_tl #1 : } {#2} + } +} +% \end{macrocode} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\msg_direct_interrupt:xxxxn} +%\begin{macro}[aux]{\msg_direct_interrupt:n} +% The low-level interruption macro is rather opaque, unfortunately. The +% idea here is to create a a message which hides all of \TeX's own +% information by filling the output up with spaces. To achieve this, +% spaces have to be letters: hence no indentation. The odd +% \cs{c_msg_hide_tl} actually does the hiding: it is the large run of +% spaces in the name that is important here. The meaning of |\\| +% is altered so that the explanation text is a simple run whilst the +% initial error has line-continuation shown. +% \begin{macrocode} +\group_begin: + \char_set_lccode:nn {`\&} {`\ } % { + \char_set_lccode:w `\} = `\ \scan_stop: + \char_make_active:N \& + \char_make_letter:N\ % +\tl_to_lowercase:n{% +\group_end:% +\cs_new_protected:Nn\msg_direct_interrupt:xxxxn{% +\group_begin:% +\cs_set_eq:NN\\\msg_newline:% +\cs_set_eq:NN\ \msg_space:% +\msg_direct_interrupt_aux:n{#4}% +\cs_set_nopar:Npn\\{\msg_newline:#3}% +\tex_errhelp:D\l_msg_tmp_tl% +\cs_set:Npn&{% +\tex_errmessage:D{% +#1\msg_newline:% +#2\msg_two_newlines:% +\c_msg_help_text_tl% +\c_msg_hide_tl % +}% +}% +&% +\group_end:% +#5% +}% +}% +\cs_new:Nn \msg_direct_interrupt_aux:n { + \tl_if_empty:nTF {#1} { + \tl_set:Nx \l_msg_tmp_tl { { \c_msg_no_info_text_tl } } + }{ + \tl_set:Nx \l_msg_tmp_tl { {#1 } } + } +} +% \end{macrocode} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\msg_direct_log:xx} +%\begin{macro}{\msg_direct_term:xx} +% Printing to the log or terminal without a stop is rather easier. +% \begin{macrocode} +\cs_new_protected:Nn \msg_direct_log:xx { + \group_begin: + \cs_set:Npn \\ { \msg_newline: #2 } + \cs_set_eq:NN \ \msg_space: + \iow_log:x { #1 \msg_newline: } + \group_end: +} +\cs_new_protected:Nn \msg_direct_term:xx { + \group_begin: + \cs_set:Npn \\ { \msg_newline: #2 } + \cs_set_eq:NN \ \msg_space: + \iow_term:x { #1 \msg_newline: } + \group_end: +} +% \end{macrocode} +%\end{macro} +%\end{macro} +% +%\subsection{General functions} +% +% The main functions for messaging are built around the separation of +% module from the message name. These have short names as they will be +% widely used. +% +%\begin{macro}{\msg_new:nnnnn} +%\begin{macro}{\msg_new:nnnn} +%\begin{macro}{\msg_new:nnn} +%\begin{macro}{\msg_set:nnnnn} +%\begin{macro}{\msg_set:nnnn} +%\begin{macro}{\msg_set:nnn} +% For making messages. +% \begin{macrocode} +\cs_new_nopar:Npn \msg_new:nnnnn #1#2 { + \msg_generic_new:nnnn { #1 / #2 } +} +\cs_new_nopar:Npn \msg_new:nnnn #1#2 { + \msg_generic_new:nnn { #1 / #2 } +} +\cs_new_nopar:Npn \msg_new:nnn #1#2 { + \msg_generic_new:nn { #1 / #2 } +} +\cs_new_nopar:Npn \msg_set:nnnnn #1#2 { + \msg_generic_set:nnnn { #1 / #2 } +} +\cs_new_nopar:Npn \msg_set:nnnn #1#2 { + \msg_generic_set:nnn { #1 / #2 } +} +\cs_new_nopar:Npn \msg_set:nnn #1#2 { + \msg_generic_set:nn { #1 / #2 } +} +% \end{macrocode} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\msg_class_new:nn} +%\begin{macro}{\msg_class_set:nn} +% Creating a new class produces three new functions, with varying +% numbers of arguments. The \cs{msg_class_loop:n} function is set up +% so that redirection will work as desired. +% \begin{macrocode} +\cs_new_nopar:Npn \msg_class_new:nn #1 { + \exp_args:Nc \chk_if_free_cs:N { msg_ #1 :nnxx } + \prop_new:c { l_msg_redirect_ #1 _prop } + \msg_class_set:nn {#1} +} +\cs_new_nopar:Nn \msg_class_set:nn { + \prop_clear:c { l_msg_redirect_ #1 _prop } + \cs_set_protected:cn { msg_ #1 :nnxx } { + \msg_use:nnnnxx {#1} {#2} {##1} {##2} {##3} {##4} + } + \cs_set_protected:cn { msg_ #1 :nnx } { + \use:c { msg_ #1 :nnxx } {##1} {##2} {##3} { } + } + \cs_set_protected:cn { msg_ #1 :nn } { + \use:c { msg_ #1 :nnxx } {##1} {##2} { } { } + } +} +% \end{macrocode} +%\end{macro} +%\end{macro} +% +%\begin{macro}[aux]{\msg_use:nnnnxx} +% The main message-using macro creates two auxiliary functions: one +% containing the code for the message, and the second a loop function. +% There is then a hand-off to the system for checking if redirection is +% needed. +% \begin{macrocode} +\cs_new:Nn \msg_use:nnnnxx { + \cs_set:Nn \msg_use_code: { + \clist_clear:N \l_msg_redirect_classes_clist + #2 + } + \cs_set:Nn \msg_use_loop:n { + \clist_if_in:NnTF \l_msg_redirect_classes_clist {#1} { + \msg_kernel_error:n { message~loop } + }{ + \clist_put_right:Nn \l_msg_redirect_classes_clist {#1} + \cs_if_exist:cTF { msg_ ##1 :nnxx } { + \use:c { msg_ ##1 :nnxx } {#3} {#4} {#5} {#6} + }{ + \msg_kernel_error:nx { message~class~unknown } { ##1 } + } + } + } + \cs_if_exist:cTF { \c_msg_text_prefix_tl #3 / #4 :nn } { + \msg_use_aux:nnn {#1} {#3} {#4} + }{ + \msg_kernel_error:nxx { message~unknown } { #3 } { #4 } + } +} +% \end{macrocode} +%\end{macro} +%\begin{macro}[aux]{\msg_use_code:} +%\begin{macro}[aux]{\msg_use_loop:} +% Blank definitions are initially created for these functions. +% \begin{macrocode} +\cs_new_nopar:Nn \msg_use_code: { } +\cs_new_nopar:Nn \msg_use_loop:n { } +% \end{macrocode} +%\end{macro} +%\end{macro} +% +%\begin{macro}[aux]{\msg_use_aux:nnn} +% The first auxiliary macro looks for a match by name: the most +% restrictive check. +% \begin{macrocode} +\cs_new_nopar:Nn \msg_use_aux:nnn { + \tl_set:Nn \l_msg_current_class_tl {#1} + \tl_set:Nn \l_msg_current_module_tl {#2} + \prop_if_in:NnTF \l_msg_redirect_names_prop { // #2 / #3 / } { + \msg_use_loop_check:nn { names } { // #2 / #3 / } + }{ + \msg_use_aux:nn {#1} {#2} + } +} +% \end{macrocode} +%\end{macro} +%\begin{macro}[aux]{\msg_use_aux:nn} +% The second function checks for general matches by module or for +% all modules. +% \begin{macrocode} +\cs_new_nopar:Nn \msg_use_aux:nn { + \prop_if_in:cnTF { l_msg_redirect_ #1 _prop } {#2} { + \msg_use_loop_check:nn {#1} {#2} + }{ + \prop_if_in:cnTF { l_msg_redirect_ #1 _prop } {*} { + \msg_use_loop_check:nn {#1} {*} + }{ + \msg_use_code: + } + } +} +% \end{macrocode} +%\end{macro} +%\begin{macro}[aux]{\msg_use_loop_check:nn} +% When checking whether to loop, the same code is needed in a few +% places. +% \begin{macrocode} +\cs_new:Nn \msg_use_loop_check:nn { + \prop_get:cnN { l_msg_redirect_ #1 _prop } {#2} \l_msg_class_tl + \tl_if_eq:NNTF \l_msg_current_class_tl \l_msg_class_tl { + \msg_use_code: + }{ + \msg_use_loop:n { \l_msg_class_tl } + } +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\msg_fatal:nnxx} +%\begin{macro}{\msg_fatal:nnx} +%\begin{macro}{\msg_fatal:nn} +% For fatal errors, after the error message \TeX\ bails out. +% \begin{macrocode} +\msg_class_new:nn { fatal } { + \msg_direct_interrupt:xxxxn + { \c_msg_fatal_tl \msg_two_newlines: } + { + ( \c_msg_fatal_tl ) \msg_space: + \use:c { \c_msg_text_prefix_tl #1 / #2 :nn } {#3} {#4} + } + { ( \c_msg_fatal_tl ) \msg_space: } + { \c_msg_fatal_text_tl } + { \tex_end:D } +} +% \end{macrocode} +%\end{macro} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\msg_error:nnxx} +%\begin{macro}{\msg_error:nnx} +%\begin{macro}{\msg_error:nn} +% For an error, the interrupt routine is called, then any recovery code +% is tried. +% \begin{macrocode} +\msg_class_new:nn { error } { + \msg_direct_interrupt:xxxxn + { #1~\c_msg_error_tl \msg_newline: } + { + ( #1 ) \msg_space: + \use:c { \c_msg_text_prefix_tl #1 / #2 :nn } {#3} {#4} + } + { ( #1 ) \msg_space: } + { + \cs_if_exist:cTF { \c_msg_more_text_prefix_tl #1 / #2 :nn } { + \use:c { \c_msg_more_text_prefix_tl #1 / #2 :nn } {#3} {#4} + }{ + \c_msg_no_info_text_tl + } + } + { + \cs_if_exist:cT { \c_msg_code_prefix_tl #1 /#2 :nn } { + \use:c { \c_msg_code_prefix_tl #1 / #2 :nn} {#3} {#4} + } + } +} +% \end{macrocode} +%\end{macro} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\msg_warning:nnxx} +%\begin{macro}{\msg_warning:nnx} +%\begin{macro}{\msg_warning:nn} +% Warnings are printed to the terminal. +% \begin{macrocode} +\msg_class_new:nn { warning } { + \msg_direct_term:xx { + \msg_space: #1~\c_msg_warning_tl :~ + \use:c { \c_msg_text_prefix_tl #1 / #2 :nn } {#3} {#4} + } + { ( #1 ) \msg_two_spaces: } +} +% \end{macrocode} +%\end{macro} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\msg_info:nnxx} +%\begin{macro}{\msg_info:nnx} +%\begin{macro}{\msg_info:nn} +% Information only goes into the log. +% \begin{macrocode} +\msg_class_new:nn { info } { + \msg_direct_log:xx { + \msg_space: #1~\c_msg_info_tl :~ + \use:c { \c_msg_text_prefix_tl #1 / #2 :nn } {#3} {#4} + } + { ( #1 ) \msg_two_spaces: } +} +% \end{macrocode} +%\end{macro} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\msg_log:nnxx} +%\begin{macro}{\msg_log:nnx} +%\begin{macro}{\msg_log:nn} +% ``Log'' data is very similar to information, but with no extras +% added. +% \begin{macrocode} +\msg_class_new:nn { log } { + \msg_direct_log:xx { + \use:c { \c_msg_text_prefix_tl #1 / #2 :nn } {#3} {#4} + } + { } +} +% \end{macrocode} +%\end{macro} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\msg_trace:nnxx} +%\begin{macro}{\msg_trace:nnx} +%\begin{macro}{\msg_trace:nn} +% Trace data is the same as log data, more or less +% \begin{macrocode} +\msg_class_new:nn { trace } { + \msg_direct_log:xx { + \use:c { \c_msg_text_prefix_tl #1 / #2 :nn } {#3} {#4} + } + { } +} +% \end{macrocode} +%\end{macro} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\msg_none:nnxx} +%\begin{macro}{\msg_none:nnx} +%\begin{macro}{\msg_none:nn} +% The \texttt{none} message type is needed so that input can be gobbled. +% \begin{macrocode} +\msg_class_new:nn { none } { } +% \end{macrocode} +%\end{macro} +%\end{macro} +%\end{macro} +% +%\subsection{Redirection functions} +% +%\begin{macro}{\msg_redirect_class:nn} +% Converts class one into class two. +% \begin{macrocode} +\cs_new_nopar:Nn \msg_redirect_class:nn { + \prop_put:cnn { l_msg_redirect_ #1 _prop } {*} {#2} +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\msg_redirect_module:nnn} +% For when all messages of a class should be altered for a given module. +% \begin{macrocode} +\cs_new_nopar:Nn \msg_redirect_module:nnn { + \prop_put:cnn { l_msg_redirect_ #2 _prop } {#1} {#3} +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\msg_redirect_name:nnn} +% Named message will always use the given class. +% \begin{macrocode} +\cs_new_nopar:Nn \msg_redirect_name:nnn { + \prop_put:Nnn \l_msg_redirect_names_prop { // #1 / #2 / } {#3} +} +% \end{macrocode} +%\end{macro} +% +%\subsection{Kernel-specific functions} +% +%\begin{macro}{\msg_kernel_new:nnnn} +%\begin{macro}{\msg_kernel_new:nnn} +%\begin{macro}{\msg_kernel_new:nn} +%\begin{macro}{\msg_kernel_set:nnnn} +%\begin{macro}{\msg_kernel_set:nnn} +%\begin{macro}{\msg_kernel_set:nn} +% The kernel needs some messages of its own. These are created using +% pre-built functions. Two functions are provided: one more general +% and one which only has the short text part. +% \begin{macrocode} +\cs_new_nopar:Npn \msg_kernel_new:nnnn #1 { + \msg_new:nnnnn { LaTeX } {#1} +} +\cs_new_nopar:Npn \msg_kernel_new:nnn #1 { + \msg_new:nnnn { LaTeX } {#1} +} +\cs_new_nopar:Npn \msg_kernel_new:nn #1 { + \msg_new:nnn { LaTeX } {#1} +} +\cs_new_nopar:Npn \msg_kernel_set:nnnn #1 { + \msg_set:nnnnn { LaTeX } {#1} +} +\cs_new_nopar:Npn \msg_kernel_set:nnn #1 { + \msg_set:nnnn { LaTeX } {#1} +} +\cs_new_nopar:Npn \msg_kernel_set:nn #1 { + \msg_set:nnn { LaTeX } {#1} +} +% \end{macrocode} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +% +%\begin{macro}[aux]{\msg_kernel_classes_new:n} +% Quickly make the fewer-arguments versions. +% \begin{macrocode} +\cs_new_nopar:Nn \msg_kernel_classes_new:n { + \cs_new_protected:cn { msg_kernel_ #1 :nx } { + \use:c { msg_kernel_ #1 :nxx } {##1} {##2} { } + } + \cs_new_protected:cn { msg_kernel_ #1 :n } { + \use:c { msg_kernel_ #1 :nxx } {##1} { } { } + } +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\msg_kernel_fatal:nxx} +%\begin{macro}{\msg_kernel_fatal:nx} +%\begin{macro}{\msg_kernel_fatal:n} +% Fatal kernel errors cannot be re-defined. +% \begin{macrocode} +\cs_new_protected:Nn \msg_kernel_fatal:nxx { + \msg_direct_interrupt:xxxxn + { \c_msg_fatal_tl \msg_two_newlines: } + { + ( LaTeX ) \msg_space: + \use:c { \c_msg_text_prefix_tl LaTeX / #1 :nn } {#2} {#3} + } + { ( LaTeX ) \msg_space: } + { \c_msg_fatal_text_tl } + { \tex_end:D } +} +\msg_kernel_classes_new:n { fatal } +% \end{macrocode} +%\end{macro} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\msg_kernel_error:nxx} +%\begin{macro}{\msg_kernel_error:nx} +%\begin{macro}{\msg_kernel_error:n} +% Neither can kernel errors. +% \begin{macrocode} +\cs_new_protected:Nn \msg_kernel_error:nxx { + \msg_direct_interrupt:xxxxn + { LaTeX~\c_msg_error_tl \msg_newline: } + { + ( LaTeX ) \msg_space: + \use:c { \c_msg_text_prefix_tl LaTeX / #1 :nn } {#2} {#3} + } + { ( LaTeX ) \msg_space: } + { + \cs_if_exist:cTF { \c_msg_more_text_prefix_tl LaTeX / #1 :nn } { + \use:c { \c_msg_more_text_prefix_tl LaTeX / #1 :nn } {#2} {#3} + }{ + \c_msg_no_info_text_tl + } + } + { + \cs_if_exist:cT { \c_msg_code_prefix_tl LaTeX /#1 :nn } { + \use:c { \c_msg_code_prefix_tl LaTeX / #1 :nn} {#2} {#3} + } + } +} +\msg_kernel_classes_new:n { error } +% \end{macrocode} +%\end{macro} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\msg_kernel_warning:nxx} +%\begin{macro}{\msg_kernel_warning:nx} +%\begin{macro}{\msg_kernel_warning:n} +%\begin{macro}{\msg_kernel_info:nxx} +%\begin{macro}{\msg_kernel_info:nx} +%\begin{macro}{\msg_kernel_info:n} +% Life is much more simple for warnings and information messages, as +% these are just short-cuts to the standard classes. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \msg_kernel_warning:nxx { + \msg_warning:nnxx { LaTeX } +} +\msg_kernel_classes_new:n { warning } +\cs_new_protected_nopar:Npn \msg_kernel_info:nxx { + \msg_info:nnxx { LaTeX } +} +\msg_kernel_classes_new:n { info } +% \end{macrocode} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +% +% Some very basic error messages. +% \begin{macrocode} +\msg_kernel_new:nnn + { coding~bug } + {This is a LaTeX bug: check coding!\\#1} + {#2} +\msg_kernel_new:nnn + { message~unknown } + {Unknown message `#2' for module `#1'.} + {LaTeX was asked to display a message by the `#1' module.\\ + The message was supposed to be called `#2', but I can't\\ + find a message with that name. + \c_msg_return_text_tl} +\msg_kernel_new:nnn + { message~class~unknown } + {Unknown message class `#1'.} + {You have asked for a message to be redirected to class `#1'\\ + but this class is unknown. + \c_msg_return_text_tl} +\msg_kernel_new:nnn + { message~loop } + {Message redirection loop.} + {You have asked for a message to be redirected,\\ + but the redirection instructions form a loop:\\ + you've lost the message. + \c_msg_return_text_tl} +% \end{macrocode} +% +%\begin{macro}{\msg_kernel_bug:x} +% The \LaTeX\ coding bug error gets re-visited here. +% \begin{macrocode} +\cs_set_protected:Nn \msg_kernel_bug:x { + \msg_direct_interrupt:xxxxn + { \c_msg_kernel_bug_text_tl } + { !~#1 } + { ! } + { \c_msg_kernel_bug_more_text_tl } + { } +} +% \end{macrocode} +%\end{macro} +% +% \begin{macrocode} +%</initex|package> +% \end{macrocode} +% +% \end{implementation} +% +% \PrintIndex diff --git a/Master/texmf-dist/source/latex/expl3/l3names.dtx b/Master/texmf-dist/source/latex/expl3/l3names.dtx index 3bd4dbf2612..26148a4e7a2 100644 --- a/Master/texmf-dist/source/latex/expl3/l3names.dtx +++ b/Master/texmf-dist/source/latex/expl3/l3names.dtx @@ -1,5 +1,5 @@ % \iffalse -%% File: l3names.dtx Copyright (C) 1990-2006 LaTeX3 project +%% File: l3names.dtx Copyright (C) 1990-2006,2009 LaTeX3 project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this @@ -17,7 +17,7 @@ %% %% The development version of the bundle can be found at %% -%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/ +%% http://www.latex-project.org/svnroot/experimental/trunk/ %% %% for those people who are interested. %% @@ -42,7 +42,18 @@ %</initex> %<package>\begingroup %<*initex|package> -\def\GetIdInfo$#1 #2.#3 #4 #5 #6 #7${% +\def\GetIdInfo$#1${% + \begingroup + \def\GetIdInfoString{#1}% + \def\IdInfoStringUnexp{Id}% + \ifx \GetIdInfoString \IdInfoStringUnexp + \def\next{\endgroup\GetIdInfoMissing} + \else + \def\next{\endgroup\GetIdInfoFull$#1$} + \fi + \next +} +\def\GetIdInfoFull$#1 #2.#3 #4 #5 #6 #7${% \GetIdInfoAux #5\relax{#2}#5\relax{#4}% } \def\GetIdInfoAux #1#2#3#4#5#6\relax{% @@ -60,6 +71,12 @@ \def\GetIdInfoAuxSVN #1#2-#3-#4\relax#5#6{% \immediate\write-1{#1; #2/#3/#4 v#5 #6}% } +\def\GetIdInfoMissing#1{% + \gdef\fileversion{000}% + \gdef\filedate{0000/00/00}% + \gdef\filedescription{#1}% + \immediate\write-1{[Loading unknown package: #1]}% +} %</initex> %<*package> \def\GetIdInfoAuxCVS #1#2\relax#3#4{% @@ -74,12 +91,18 @@ \gdef\filedescription{#6}% \ProvidesPackage{#1}[#2/#3/#4 v#5 #6] } +\def\GetIdInfoMissing#1{% + \gdef\fileversion{000}% + \gdef\filedate{0000/00/00}% + \gdef\filedescription{#1}% + \ProvidesPackage{[unknown package]}[0000/00/00 v0.0 #1] +} %</package> %<*driver> \RequirePackage{l3names} %</driver> %\fi -\GetIdInfo$Id: l3names.dtx 621 2007-09-01 20:14:19Z morten $ +\GetIdInfo$Id: l3names.dtx 1362 2009-05-28 20:19:21Z joseph $ {L3 Experimental Naming Scheme for TeX Primitives} % % @@ -90,7 +113,7 @@ \ProvidesFile{l3names.dtx} [\filedate\space v\fileversion\space\filedescription] %\iffalse -\documentclass{l3doc} +\documentclass[full]{l3doc} \begin{document} \DocInput{l3names.dtx} \end{document} @@ -105,215 +128,30 @@ % \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 heart 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 -% letters to denote the various primitive argument types available in -% \TeX, however it seems that this just complicates the system -% without adding 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} +% \begin{documentation} % -% Parameter names have the following general syntax: -% \begin{quote} -% |\|\m{access}|_|\m{module}|_|\m{description}|_|\m{type} -% \end{quote} +% \section{Setting up the \LaTeX3 programming language} % -% \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} +% This module is at the core of the \LaTeX3 programming language. It +% performs the following tasks: +% \begin{itemize} +% \item defines new names for all \TeX{} primitives; +% \item defines catcode regimes for programming; +% \item provides settings for when the code is used in a format; +% \item provides tools for when the code is used as a package within a +% \LaTeXe\ context. +% \end{itemize} % -% \item[int] Integer valued. +% \section{Using the modules} % -% \item[factor] Another integer value type. Used for things where the -% parameter is used as a factor for something else. +% The modules documented in \file{source3} are designed to be used on top of +% \LaTeXe\ and are loaded all as one with the usual "\usepackage{expl3}" or +% "\RequirePackage{expl3}" instructions. These modules will also form the +% basis of the \LaTeX3 format, but work in this area is incomplete and not +% included in this documentation. % -% \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. -% -% \subsection{Using the modules} -% -% Most of the modules can be used on top of \LaTeX\ and are loaded -% with the usual "\usepackage" or "\RequirePackage" instructions. As -% the packages use a coding syntax different from standard \LaTeX\ it -% provides a few functions for setting it up. +% As the modules use a coding syntax different from standard +% \LaTeX\ it provides a few functions for setting it up. % % \begin{function}{ % \ExplSyntaxOn | @@ -323,18 +161,28 @@ % "\ExplSyntaxOn" <code> "\ExplSyntaxOff" % \end{syntax} % Issues a catcode regime where spaces are ignored and colon and -% underscore are letters. +% underscore are letters. A space character may by input with "~" instead. +% \end{function} +% +% \begin{function}{ +% \ExplSyntaxNamesOn | +% \ExplSyntaxNamesOff +% } +% \begin{syntax} +% "\ExplSyntaxNamesOn" <code> "\ExplSyntaxNamesOff" +% \end{syntax} +% Issues a catcode regime where colon and underscore are letters, but +% spaces remain the same. % \end{function} % % \begin{function}{ -% l3names | % \ProvidesExplPackage | % \ProvidesExplClass % } % \begin{syntax} -% "\RequirePackage{l3names}" \\ -% "\ProvidesExplPackage" "{"<package>"}" -% "{"<date>"}" "{"<version>"}" "{"<description>"}" +% "\RequirePackage{expl3}" \\ +% "\ProvidesExplPackage" \Arg{package} +% \Arg{date} \Arg{version} \Arg{description} % \end{syntax} % The package "l3names" (this module) provides % "\ProvidesExplPackage" which is a wrapper for "\ProvidesPackage" @@ -351,13 +199,14 @@ % \filedate | % \fileversion | % \filetimestamp | -% \fileauthor +% \fileauthor | +% \filedescription % } % \begin{syntax} % "\RequirePackage{l3names}" \\ -% "\GetIdInfo" "$Id:" <cvs or svn info field> "$" "{"<description>"}" +% "\GetIdInfo" "$Id:" <cvs or svn info field> "$" \Arg{description} % \end{syntax} -% Extracts all information from a cvs or svn field. Spaces are not +% Extracts all information from a CVS or SVN field. Spaces are not % ignored in these fields. The information pieces are stored in % separate control sequences with "\filename" for the part of the % file name leading up to the period, "\filenameext" for the @@ -377,33 +226,79 @@ % \end{verbatim} % % +% \end{documentation} % +% \begin{implementation} % -% \StopEventually{} -% -% \section{Starters} +% \section{\pkg{l3names} implementation} % % This is the base part of \LaTeX3 defining things like |catcode|s -% and redefining the \TeX{} primitives. +% and redefining the \TeX{} primitives, as well as setting up the code +% to load \pkg{expl3} modules in \LaTeXe. +% +% \subsection{Internal functions} % -% 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{function}{ \ExplSyntaxStatus | \ExplSyntaxPopStack | \ExplSyntaxStack } +% Functions used to track the state of the catcode regime. +% \end{function} +% +% \begin{function}{\@pushfilename | \@popfilename} +% Re-definitions of \LaTeX's file-loading functions to support "\ExplSyntax". +% \end{function} +% +% \subsection{Package loading} +% +% Before anything else, check that we're using \eTeX; +% no point continuing otherwise. % \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> +%<*initex|package> +\begingroup +\def\firstoftwo#1#2{#1} +\def\secondoftwo#1#2{#2} +\def\etexmissingerror{Not running under e-TeX} +\def\etexmissinghelp{% + This package requires e-TeX.^^J% + Try compiling the document with `elatex' instead of `latex'.^^J% + When using pdfTeX, try `pdfelatex' instead of `pdflatex'% +}% +\expandafter\ifx\csname eTeXversion\endcsname\relax + \expandafter\secondoftwo\else\expandafter\firstoftwo\fi + {\endgroup}{% +%<initex> \expandafter\errhelp\expandafter{\etexmissinghelp}% +%<initex> \expandafter\errmessage\expandafter{\etexmissingerror}% +%<package> \PackageError{l3names}{\etexmissingerror}{\etexmissinghelp}% + \endgroup + \endinput + } +%</initex|package> % \end{macrocode} +% +% \subsection{Catcode assignments} +% +% Catcodes for begingroup, endgroup, macro parameter, superscript, and tab, +% are all assigned before the start of the documented code. (See the beginning +% of \file{l3names.dtx}.) +% % Reason for |\endlinechar=32| is that a line ending with a backslash % will be interpreted as the token \verb*|\ | which seems most natural % and since spaces are ignored it works as we intend elsewhere. +% +% Before we do this we must however record the settings for the +% catcode regime as it was when we start changing it. % \begin{macrocode} %<*initex|package> +\edef\ExplSyntaxOff{ + \unexpanded{\ifodd \ExplSyntaxStatus\relax + \def\ExplSyntaxStatus{0} + } + \catcode 126=\the \catcode 126 \relax + \catcode 32=\the \catcode 32 \relax + \catcode 9=\the \catcode 9 \relax + \endlinechar =\the \endlinechar \relax + \catcode 95=\the \catcode 95 \relax + \catcode 58=\the \catcode 58 \relax + \noexpand\fi +} \catcode126=10\relax % tilde is a space char. \catcode32=9\relax % space is ignored \catcode9=9\relax % tab also ignored @@ -412,8 +307,7 @@ \catcode58=11\relax % colon letter % \end{macrocode} % -% -% \section{Setting up primitive names} +% \subsection{Setting up primitive names} % % Here is the function that renames \TeX{}'s primitives. % @@ -477,7 +371,7 @@ } % \end{macrocode} % -% \subsection{Assignments} +% \subsection{Reassignment of primitives} % % In the current incarnation of this package, all \TeX\ primitives % are given a new name of the form |\tex_|\emph{oldname}|:D|. @@ -819,7 +713,7 @@ % % % -% Since \LaTeX3 will require at least the \eTeX{} extensions, +% Since \LaTeX3 requires at least the \eTeX{} extensions, % we also rename the additional primitives. These are all % given the prefix |\etex_|. % \begin{macrocode} @@ -892,8 +786,7 @@ % \end{macrocode} % % -% All major distributions\footnote{At the time of writing MiK\TeX\ -% does not but I have a gut feeling that will change.} use +% All major distributions use % pdf\eTeX{} as engine so we add these names as well. Since the % pdf\TeX{} team has been very good at prefixing most primitives % with |pdf| (so far only five do not start with |pdf|) we do not @@ -1003,14 +896,29 @@ \name_primitive:NN \pdfnoligatures \pdf_noligatures:D % \end{macrocode} % -% What about Omega and Aleph? The status of both are unclear but let's -% start by adding a single primitive which we can use for testing if -% we have one of these engines. +% We're ignoring XeTeX and LuaTeX right +% now except for a check whether they're in use: +% \begin{macrocode} +\name_primitive:NN \XeTeXversion \xetex_version:D +\name_primitive:NN \directlua \luatex_directlua:D +% \end{macrocode} +% +% XeTeX adds \cs{strcmp} to the set of primitives, with the same +% implementation as \cs{pdfstrcmp} but a different name. To avoid +% having to worry about this later, the same internal name is used. % \begin{macrocode} -\name_primitive:NN \textdir \aleph_textdir:D +\etex_ifdefined:D \strcmp + \etex_ifdefined:D \xetex_version:D + \name_primitive:NN \strcmp \pdf_strcmp:D + \tex_fi:D +\tex_fi:D % \end{macrocode} -% \begin{macro}{\CodeStart} -% \begin{macro}{\CodeStop} +% +% \subsection{\pkg{expl3} code switches} +% +% \begin{macro}{\ExplSyntaxOn} +% \begin{macro}{\ExplSyntaxOff} +% \begin{macro}{\ExplSyntaxStatus} % Here we define functions that are used to turn on and off the % special conventions used in the kernel of \LaTeX3. % @@ -1019,48 +927,63 @@ % to a space instead. When space characters are needed in \LaTeX3 % code the |~| character will be used for that purpose. % +% Specification of the desired behavior: +% \begin{itemize} +% \item ExplSyntax can be either On or Off. +% \item The On switch is \meta{null} if ExplSyntax is on. +% \item The Off switch is \meta{null} if ExplSyntax is off. +% \item If the On switch is issued and not \meta{null}, it records +% the current catcode scheme just prior to it being issued. +% \item An Off switch restores the catcode scheme to what it was just +% prior to the previous On switch. +% \end{itemize} +% % \begin{macrocode} \tex_def:D\ExplSyntaxOn{ - \tex_def:D\ExplSyntaxStatus{00} - \tex_catcode:D 126=10 \tex_relax:D % tilde is a space char. - \tex_catcode:D 32=9 \tex_relax:D % space is ignored - \tex_catcode:D 9=9 \tex_relax:D % tab also ignored - \tex_endlinechar:D =32 \tex_relax:D % endline is space - \tex_catcode:D 95=11 \tex_relax:D % underscore letter - \tex_catcode:D 58=11 \tex_relax:D % colon letter -} -% \end{macrocode} -% -% \begin{macrocode} -\tex_def:D\ExplSyntaxOff{ - \tex_def:D\ExplSyntaxStatus{01} - \tex_catcode:D 126=13 \tex_relax:D - \tex_catcode:D 32=10 \tex_relax:D - \tex_catcode:D 9=10 \tex_relax:D - \tex_endlinechar:D =13 \tex_relax:D - \tex_catcode:D 95=8 \tex_relax:D - \tex_catcode:D 58=12 \tex_relax:D + \tex_ifodd:D \ExplSyntaxStatus \tex_relax:D + \tex_else:D + \tex_edef:D\ExplSyntaxOff{ + \etex_unexpanded:D{ + \tex_ifodd:D \ExplSyntaxStatus \tex_relax:D + \tex_def:D \ExplSyntaxStatus{0} + } + \tex_catcode:D 126=\tex_the:D \tex_catcode:D 126 \tex_relax:D + \tex_catcode:D 32=\tex_the:D \tex_catcode:D 32 \tex_relax:D + \tex_catcode:D 9=\tex_the:D \tex_catcode:D 9 \tex_relax:D + \tex_endlinechar:D =\tex_the:D \tex_endlinechar:D \tex_relax:D + \tex_catcode:D 95=\tex_the:D \tex_catcode:D 95 \tex_relax:D + \tex_catcode:D 58=\tex_the:D \tex_catcode:D 58 \tex_relax:D + \tex_noexpand:D \tex_fi:D + } + \tex_def:D\ExplSyntaxStatus{1} + \tex_catcode:D 126=10 \tex_relax:D % tilde is a space char. + \tex_catcode:D 32=9 \tex_relax:D % space is ignored + \tex_catcode:D 9=9 \tex_relax:D % tab also ignored + \tex_endlinechar:D =32 \tex_relax:D % endline is space + \tex_catcode:D 95=11 \tex_relax:D % underscore letter + \tex_catcode:D 58=11 \tex_relax:D % colon letter + \tex_fi:D } % \end{macrocode} -% Temporary while names change. +% At this point we better set the status. % \begin{macrocode} -\tex_let:D \CodeStart \ExplSyntaxOn -\tex_let:D \CodeStop \ExplSyntaxOff +\tex_def:D\ExplSyntaxStatus{1} % \end{macrocode} % \end{macro} % \end{macro} +% \end{macro} % -% \begin{macro}{\NamesStart} -% \begin{macro}{\NamesStop} +% \begin{macro}{\ExplSyntaxNamesOn} +% \begin{macro}{\ExplSyntaxNamesOff} % Sometimes we need to be able to use names from the kernel of % \LaTeX3 without adhering it's conventions according to space % characters. These macros provide the necessary settings. % \begin{macrocode} -\tex_def:D \NamesStart{ +\tex_def:D \ExplSyntaxNamesOn{ \tex_catcode:D `\_=11\tex_relax:D \tex_catcode:D `\:=11\tex_relax:D } -\tex_def:D \NamesStop{ +\tex_def:D \ExplSyntaxNamesOff{ \tex_catcode:D `\_=8\tex_relax:D \tex_catcode:D `\:=12\tex_relax:D } @@ -1068,11 +991,21 @@ % \end{macro} % \end{macro} % +% \subsection{Package loading} +% +% % \begin{macro}{\GetIdInfo} -% \begin{macro}{\GetIdInfoAuxi:w} -% \begin{macro}{\GetIdInfoAuxii:w} -% \begin{macro}{\GetIdInfoAuxCVS:w} -% \begin{macro}{\GetIdInfoAuxSVN:w} +% \begin{macro}{ \filedescription , +% \filename , +% \fileversion , +% \fileauthor , +% \filedate , +% \filenameext , +% \filetimestamp } +% \begin{macro}[aux]{\GetIdInfoAuxi:w} +% \begin{macro}[aux]{\GetIdInfoAuxii:w} +% \begin{macro}[aux]{\GetIdInfoAuxCVS:w} +% \begin{macro}[aux]{\GetIdInfoAuxSVN:w} % Extract all information from a cvs or svn field. The % formats are slightly different but at least the information is in % the same positions so we check in the date format so see if it @@ -1083,8 +1016,33 @@ \tex_def:D\GetIdInfo{ \tex_begingroup:D \tex_catcode:D 32=10 \tex_relax:D % needed? Probably for now. - \GetIdInfoAuxi:w + \GetIdInfoMaybeMissing:w } +% \end{macrocode} +% +% \begin{macrocode} +\tex_def:D\GetIdInfoMaybeMissing:w$#1$#2{ + \tex_def:D \l_tmpa_tl {#1} + \tex_def:D \l_tmpb_tl {Id} + \tex_ifx:D \l_tmpa_tl \l_tmpb_tl + \tex_def:D \l_tmpa_tl { + \tex_endgroup:D + \tex_def:D\filedescription{#2} + \tex_def:D\filename {[unknown~name]} + \tex_def:D\fileversion {000} + \tex_def:D\fileauthor {[unknown~author]} + \tex_def:D\filedate {0000/00/00} + \tex_def:D\filenameext {[unknown~ext]} + \tex_def:D\filetimestamp {[unknown~timestamp]} + } + \tex_else:D + \tex_def:D \l_tmpa_tl {\GetIdInfoAuxi:w$#1${#2}} + \tex_fi:D + \l_tmpa_tl +} +% \end{macrocode} +% +% \begin{macrocode} \tex_def:D\GetIdInfoAuxi:w$#1~#2.#3~#4~#5~#6~#7~#8$#9{ \tex_endgroup:D \tex_def:D\filename{#2} @@ -1094,6 +1052,9 @@ \GetIdInfoAuxii:w #5\tex_relax:D #3\tex_relax:D#5\tex_relax:D#6\tex_relax:D } +% \end{macrocode} +% +% \begin{macrocode} \tex_def:D\GetIdInfoAuxii:w #1#2#3#4#5#6\tex_relax:D{ \tex_ifx:D#5/ \tex_expandafter:D\GetIdInfoAuxCVS:w @@ -1101,6 +1062,9 @@ \tex_expandafter:D\GetIdInfoAuxSVN:w \tex_fi:D } +% \end{macrocode} +% +% \begin{macrocode} \tex_def:D\GetIdInfoAuxCVS:w #1,v\tex_relax:D #2\tex_relax:D#3\tex_relax:D{ \tex_def:D\filedate{#2} @@ -1128,11 +1092,10 @@ % \end{macro} % \end{macro} % \end{macro} +% \end{macro} % % Finally some corrections in the case we are running over \LaTeXe. % -% -% % We want to set things up so that experimental packages and regular % packages can coexist with the former using the \LaTeX3 programming % catcode settings. Since it cannot be the task of the end user to @@ -1147,7 +1110,7 @@ % as the packages in this distribution do like this: % \begin{verbatim} % \RequirePackage{l3names} -% \GetIdInfo$Id: l3names.dtx 621 2007-09-01 20:14:19Z morten $ +% \GetIdInfo$Id: l3names.dtx 1362 2009-05-28 20:19:21Z joseph $ % {L3 Experimental Box module} % \ProvidesExplPackage % {\filename}{\filedate}{\fileversion}{\filedescription} @@ -1156,7 +1119,8 @@ % % \begin{macro}{\ProvidesExplPackage} % \begin{macro}{\ProvidesExplClass} -% First up is the identification. Rather trivial +% First up is the identification. Rather trivial as we don't allow for +% options just yet. % \begin{macrocode} %<*package> \tex_def:D \ProvidesExplPackage#1#2#3#4{ @@ -1172,58 +1136,106 @@ % \end{macro} % % -% \begin{macro}{\org@onefilewithoptions} -% \begin{macro}{\@onefilewithoptions} +% \begin{macro}{\@pushfilename} % \begin{macro}{\@popfilename} % The idea behind the code is to record whether or not the \LaTeX3 % syntax is on or off when about to load a file with class or % package extension. This status stored in the parameter % |\ExplSyntaxStatus| and set by |\ExplSyntaxOn| and -% |\ExplSyntaxOff| to |00| and |01| respectively is puched onto the +% |\ExplSyntaxOff| to |1| and |0| respectively is pushed onto the % stack |\ExplSyntaxStack|. Then the catcodes are set back to % normal, the file loaded with its options and finally the stack is -% popped again. -% -% |\@popfilename| is appended with a preamble check. If the catcode -% of "@" is being reset it is a fair assumption that we are back in -% the usual preamble and so we switch off our syntax as well. +% popped again. The whole thing is a bit problematical. So let's +% take a look at what the desired behavior is: A package or class +% which declares itself of Expl type by using |\ProvidesExplClass| +% or |\ProvidesExplPackage| should automatically ensure the correct +% catcode scheme as soon as the identification part is +% over. Similarly, a package or class which uses the traditional +% |\ProvidesClass| or |\ProvidesPackage| commands should go back to +% the traditional catcode scheme. An example: +% \begin{verbatim} +% \RequirePackage{l3names} +% \ProvidesExplPackage{foobar}{2009/05/07}{0.1}{Foobar package} +% \cs_new:Nn \foo_bar:nn {#1,#2} +% ... +% \RequirePackage{array} +% ... +% \cs_new:Nn \foo_bar:nnn {#3,#2,#1} +% \end{verbatim} +% Inside the \pkg{array} package, everything should behave as normal +% under traditional \LaTeX\ but as soon as we are back at the top +% level, we should use the new catcode regime. +% +% +% Whenever \LaTeX\ inputs a package file or similar, it calls upon +% |\@pushfilename| to push the name, the extension and the catcode +% of @ of the file it was currently processing onto a file name +% stack. Similarly, after inputting such a file, this file name +% stack is popped again and the catcode of @ is set to what it was +% before. If it is a package within package, @ maintains catcode 11 +% whereas if it is package within document preamble @ is reset to +% what it was in the preamble (which is usually catcode 12). We wish +% to adopt a similar technique. Every time an Expl package or class +% is declared, they will issue an ExplSyntaxOn. Then whenever we are +% about to load another file, we will first push this status onto a +% stack and then turn it off again. Then when done loading a file, +% we pop the stack and if ExplSyntax was On right before, so should +% it be now. The only problem with this is that we cannot guarantee +% that we get to the file name stack very early on. Therefore, if +% the ExplSyntaxStack is empty when trying to pop it, we ensure to +% turn ExplSyntax off again. +% +% |\@pushfilename| is prepended with a small function pushing the +% current ExplSyntaxStatus (true/false) onto a stack. Then the +% current catcode regime is recorded and ExplSyntax is switched off. +% +% |\@popfilename| is appended with a function for popping the +% ExplSyntax stack. However, chances are we didn't get to hook into +% the file stack early enough so \LaTeX\ might try to pop the file +% name stack while the ExplSyntaxStack is empty. If the latter is +% empty, we just switch off ExplSyntax. % \begin{macrocode} -\tex_let:D \org@onefilewithoptions\@onefilewithoptions -\tex_def:D \@onefilewithoptions#1[#2][#3]#4{ - \tex_edef:D \ExplSyntaxStack{ \ExplSyntaxStatus\ExplSyntaxStack } - \ExplSyntaxOff - \org@onefilewithoptions{#1}[{#2}][{#3}]{#4} - \tex_expandafter:D\ExplSyntaxPopStack\ExplSyntaxStack\tex_relax:D -} -\g@addto@macro\@popfilename{% - \tex_ifnum:D\tex_the:D\tex_catcode:D`\@=12\tex_relax:D +\tex_edef:D \@pushfilename{ + \etex_unexpanded:D{ + \tex_edef:D \ExplSyntaxStack{ \ExplSyntaxStatus \ExplSyntaxStack } \ExplSyntaxOff - \tex_fi:D + } + \etex_unexpanded:D\tex_expandafter:D{\@pushfilename } +} +\tex_edef:D \@popfilename{ + \etex_unexpanded:D\tex_expandafter:D{\@popfilename + \tex_if:D 2\ExplSyntaxStack 2 + \ExplSyntaxOff + \tex_else:D + \tex_expandafter:D\ExplSyntaxPopStack\ExplSyntaxStack\q_nil + \tex_fi:D + } } % \end{macrocode} % \end{macro} % \end{macro} -% \end{macro} % % \begin{macro}{\ExplSyntaxPopStack} % \begin{macro}{\ExplSyntaxStack} -% Popping the stack is simple: Take the first two tokens which are -% either the sequence "00" or "01" and use them in an if test. The -% stack is initially empty. +% Popping the stack is simple: Take the first token which is either +% 0 (false) or 1 (true) and test if it is odd. Save the rest. The +% stack is initially empty set to 0 signalling that before +% \pkg{l3names} was loaded, the ExplSyntax was off. % \begin{macrocode} -\tex_def:D\ExplSyntaxPopStack#1#2#3\tex_relax:D{ - \tex_def:D\ExplSyntaxStack{#3} - \tex_if:D#1#2 +\tex_def:D\ExplSyntaxPopStack#1#2\q_nil{ + \tex_def:D\ExplSyntaxStack{#2} + \tex_ifodd:D#1\tex_relax:D \ExplSyntaxOn \tex_else:D \ExplSyntaxOff \tex_fi:D } -\tex_def:D\ExplSyntaxStack{} +\tex_def:D \ExplSyntaxStack{0} % \end{macrocode} % \end{macro} % \end{macro} % +% \subsection{Finishing up} % % A few of the `primitives' assigned above have already been stolen % by \LaTeX, so assign them by hand to the saved real primitive. @@ -1243,18 +1255,11 @@ \tex_let:D\par \tex_par:D % \end{macrocode} % -% +% This is the end for \file{l3names} when used on top of \LaTeXe: % % \begin{macrocode} \tex_ifx:D\name_undefine:N\@gobble -% \end{macrocode} -% -% \begin{macrocode} - \AtEndOfPackage{\ExplSyntaxOff} \tex_def:D\name_pop_stack:w{} -% \end{macrocode} -% -% \begin{macrocode} \tex_else:D % \end{macrocode} % @@ -1282,8 +1287,8 @@ % \end{macrocode} % % 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 explicitly with |\CodeStop| (although as currently +% |\ExplSyntaxOn| conventions stay in force once on. You'll need +% to turn then off explicitly with |\ExplSyntaxOff| (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. @@ -1322,39 +1327,55 @@ % token is in fact |\let| and that may be undefined.) % \begin{macrocode} \tex_futurelet:D\name_tmp:\name_pop_stack:w -%</package> % \end{macrocode} % -% \endinput -% -% $Log$ -% Revision 1.17 2006/01/15 07:55:48 morten -% Fixed minor typo -% -% Revision 1.16 2006/01/15 07:17:43 morten -% Imported \NamesStart and \NamesStop from l3messages. -% -% Revision 1.15 2005/12/27 10:00:03 morten -% Changed RCS information retrieval, code to run as package under 2e -% changed slightly to not set special catcodes directly. +% \paragraph{\pkg{expl3} dependency checks} +% We want the \pkg{expl3} bundle to be loaded `as one'; this command is +% used to ensure that one of the "l3" packages isn't loaded on its own. +% \begin{macrocode} +%<*!initex> +\tex_def:D \package_check_loaded_expl: { + \@ifpackageloaded{expl3}{}{ + \PackageError{expl3}{Cannot~load~the~expl3~modules~separately}{ + The~expl3~modules~cannot~be~loaded~separately;\MessageBreak + please~\protect\usepackage{expl3}~instead. + } + } +} +%</!initex> +% \end{macrocode} % -% Revision 1.14 2005/12/01 22:58:16 morten -% Added pdfTeX primitives +% \begin{macrocode} +%</package> +% \end{macrocode} % -% Revision 1.13 2005/03/26 21:04:19 morten -% Fix typo. +% \subsection{Showing memory usage} % -% Revision 1.12 2005/03/22 23:23:57 morten -% Added an Aleph primitive +% This section is from some old code from 1993; it'd be good to work out +% how it should be used in our code today. % -% Revision 1.11 2005/03/15 23:16:21 braams -% Some tweaking with the docstrip guards to get the documentation to -% come out right. +% During the development of the \LaTeX3 kernel we need to be able +% to keep track of the memory usage. Therefore we generate empty +% pages while loading the kernel code, just to be able to check the +% memory usage. % -% Revision 1.10 2005/03/15 22:48:31 braams -% Made it possible to load this as the very first file with initex +% \begin{macrocode} +%<*showmemory> +\g_trace_statistics_status=2\scan_stop: +\cs_set_nopar:Npn\showMemUsage{ + \if_horizontal_mode: + \tex_errmessage:D{Wrong~ mode~ H:~ something~ triggered~ + hmode~ above} + \else: + \tex_message:D{Mode ~ okay} + \fi: + \tex_shipout:D\hbox:w{} +} +\showMemUsage +%</showmemory> +% \end{macrocode} % -% Revision 1.9 2005/03/11 21:29:56 braams -% Fixed the use of RCS information; moved definition of \eTeX -% to l3doc.cls +% \end{implementation} +% \PrintIndex % +% \endinput diff --git a/Master/texmf-dist/source/latex/expl3/l3num.dtx b/Master/texmf-dist/source/latex/expl3/l3num.dtx index 325eef2e131..51281eaf7ac 100644 --- a/Master/texmf-dist/source/latex/expl3/l3num.dtx +++ b/Master/texmf-dist/source/latex/expl3/l3num.dtx @@ -1,5 +1,5 @@ % \iffalse -%% File: l3num.dtx Copyright (C) 2005-2008 Frank Mittelbach, LaTeX3 project +%% File: l3num.dtx Copyright (C) 2005-2009 Frank Mittelbach, LaTeX3 project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this @@ -17,7 +17,7 @@ %% %% The development version of the bundle can be found at %% -%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/ +%% http://www.latex-project.org/svnroot/experimental/trunk/ %% %% for those people who are interested. %% @@ -36,7 +36,7 @@ \RequirePackage{l3names} %</driver|package> %\fi -\GetIdInfo$Id: l3num.dtx 741 2008-08-01 13:37:16Z morten $ +\GetIdInfo$Id: l3num.dtx 1362 2009-05-28 20:19:21Z joseph $ {L3 Experimental token numbers} %\iffalse %<*driver> @@ -44,9 +44,9 @@ \ProvidesFile{\filename.\filenameext} [\filedate\space v\fileversion\space\filedescription] %\iffalse -\documentclass{l3doc} +\documentclass[full]{l3doc} \begin{document} -\DocInput{\filename.\filenameext} +\DocInput{l3num.dtx} \end{document} %</driver> % \fi @@ -55,12 +55,12 @@ % \title{The \textsf{l3num} package\thanks{This file % has version number \fileversion, last % revised \filedate.}\\ -% Integer in macros} +% Integers in macros} % \author{\Team} % \date{\filedate} % \maketitle % -% \section{Macro Counters} +% \begin{documentation} % % Instead of using counter registers for manipulation of % integer values it is sometimes useful to keep such values in @@ -75,7 +75,7 @@ % allocation module can do its bookkeeping without the aid of % \meta{int} registers. % -% \subsection{Functions} +% \section{Functions} % % \begin{function}{% % \num_new:N | @@ -135,12 +135,24 @@ % \num_gset:cn | % } % \begin{syntax} -% "\num_set:Nn" <num> "{" <integer> "}" +% "\num_set:Nn" <num> \Arg{integer} % \end{syntax} % These functions will set the <num> register to the <integer> value. % \end{function} % % \begin{function}{% +% \num_set_eq:NN | +% \num_set_eq:cN | +% \num_set_eq:Nc | +% \num_set_eq:cc | +% } +% \begin{syntax} +% "\num_gset_eq:NN" <num1> <num2> +% \end{syntax} +% These functions will set the <num1> register equal to <num2>. +% \end{function} +% +% \begin{function}{% % \num_gset_eq:NN | % \num_gset_eq:cN | % \num_gset_eq:Nc | @@ -149,7 +161,7 @@ % \begin{syntax} % "\num_gset_eq:NN" <num1> <num2> % \end{syntax} -% These functions will set the <num1> register equal to <num2>. +% These functions will globally set the <num1> register equal to <num2>. % \end{function} % % \begin{function}{% @@ -159,7 +171,7 @@ % \num_gadd:cn | % } % \begin{syntax} -% "\num_add:Nn" <num> "{" <integer> "}" +% "\num_add:Nn" <num> \Arg{integer} % \end{syntax} % These functions will add to the <num> register the value <integer>. If % the second argument is a <num> register too, the surrounding braces @@ -184,112 +196,37 @@ % \end{texnote} % \end{function} % -% -% \begin{function}{% -% \num_eval:n | -% } -% \begin{syntax} -% "\num_eval:n" "{" <integer-expr> "}" -% \end{syntax} -% Evaluates the integer expression allowing normal mathematical -% operators like |+-/*|. -% \end{function} -% -% -% \begin{function}{% -% \num_compare:nNnTF | -% \num_compare:cNcTF | -% \num_compare:nNnT | -% \num_compare:nNnF | -% } -% \begin{syntax} -% "\num_compare:nNnTF" "{"<num~expr>"}" <rel> "{"<num~expr>"}" -% "{"<true>"}" "{"<false>"}" -% \end{syntax} -% These functions test two \m{num} expressions against each other. They -% are both evaluated by "\num_eval:n". -% \end{function} -% -% \begin{function}{% -% \num_compare_p:nNn | -% } +% \begin{function}{ \num_show:N | +% \num_show:c } % \begin{syntax} -% "\num_compare_p:nNn" "{"<num~expr>"}" <rel> "{"<num~expr>"}" +% "\num_show:N" <num> % \end{syntax} -% A predicate version of the above functions. +% This function pauses the compilation and displays the integer value kept +% in <num> on the console output. % \end{function} % -% \begin{function}{% -% \num_max_of:nn | -% \num_min_of:nn | -% } -% \begin{syntax} -% "\num_max_of:nn" "{"<num~expr>"}" "{"<num~expr>"}" -% \end{syntax} -% Return the largest or smallest of two \m{num} expressions. -% \end{function} % -% \begin{function}{% -% \num_abs:n | -% } -% \begin{syntax} -% "\num_abs:n" "{"<num~expr>"}" -% \end{syntax} -% Return the numerical value of a \m{num} expression. -% \end{function} % % \begin{function}{% % \num_elt_count:n | +% \num_elt_count_prop:Nn | % } % \begin{syntax} -% "\num_elt_count:n" "{"<balanced text>"}" +% "\num_elt_count:n" \Arg{balanced text} +% "\num_elt_count_prop:Nn" <prop> \Arg{balanced text} % \end{syntax} -% Discards \m{balanced text} and puts a "+1" in the input stream. Used +% Discards their arguments and puts a "+1" in the input stream. Used % to count elements in a token list. % \end{function} % -% \subsection{Formatting a counter value} +% \section{Formatting a counter value} % % See the \textsf{l3int} module for ways of doing this. % -% \subsection{Variable and constants} +% \section{Variable and constants} % -% \begin{function}{% -% \const_new:Nn | -% } -% \begin{syntax} -% "\const_new:Nn" "\c_"<value> "{" <value> "}" -% \end{syntax} -% Defines a constant with <value>. If the constant is negative -% or very large it requires an <int> register. -% \end{function} -% -% \begin{variable}{% -% \c_minus_one | -% \c_zero | -% \c_one | -% \c_two | -% \c_three | -% \c_four | -% \c_six | -% \c_seven | -% \c_nine | -% \c_ten | -% \c_eleven | -% \c_sixteen | -% \c_hundred_one | -% \c_twohundred_fifty_five | -% \c_twohundred_fifty_six | -% \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} +% \begin{variable}{ \c_max_register_num } +% Maximum number of registers; possibly engine-specific. % \end{variable} % % \begin{variable}{% @@ -299,50 +236,20 @@ % \g_tmpa_num | % \g_tmpb_num | % } -% \\ % Scratch register for immediate use. They are not used by conditionals % or predicate functions. % \end{variable} % -% \subsection{Primitive functions} +% \section{Primitive functions} % % % \begin{function}{% -% \num_value:w | -% } -% \begin{syntax} -% "\num_value:w" <integer> \\ -% "\num_value:w" <tokens> <optional space> -% \end{syntax} -% Expands <tokens> until an <integer> is formed. One space may be -% gobbled in the process. Preferably use with "\num_eval:n". -% \begin{texnote} -% This is the \TeX{} primitive \tn{number}. -% \end{texnote} -% \end{function} -% -% \begin{function}{% -% \num_eval:w | -% } -% \begin{syntax} -% "\num_eval:w" <integer expression> "\num_eval_end:" -% \end{syntax} -% Evaluates <integer expression>. The evaluation stops when an -% unexpandable token of catcode other than 12 is reached or -% "\num_eval_end:" is read. The latter is gobbled by the scanner -% mechanism. -% \begin{texnote} -% This is the \eTeX{} primitive \tn{numexpr}. -% \end{texnote} -% \end{function} -% -% \begin{function}{% % \if_num:w | % } % \begin{syntax} % "\if_num:w" <number1> <rel> <number2> <true> "\else:" <false> "\fi:" % \end{syntax} -% Compare two numbers. It is recommended to use "\num_eval:n" to +% Compare two numbers. It is recommended to use "\intexpr_eval:n" to % correctly evaluate and terminate these numbers. <rel> is one of % "<", "=" or ">" with catcode 12. % \begin{texnote} @@ -351,18 +258,6 @@ % \end{function} % % \begin{function}{% -% \if_num_odd:w | -% } -% \begin{syntax} -% "\if_num_odd:w" <number> <true> "\else:" <false> "\fi:" -% \end{syntax} -% Execute <true> if <number> is odd, <false> otherwise. -% \begin{texnote} -% This is the \TeX{} primitive \tn{ifodd}. -% \end{texnote} -% \end{function} -% -% \begin{function}{% % \if_case:w | % \or: | % } @@ -370,52 +265,40 @@ % "\if_case:w" <number> <case0> "\or:" <case1> "\or:" "..." "\else:" % <default> "\fi:" % \end{syntax} -% Chooses case<number>. If you wish to use negative numbers as well, -% you can offset them with "\num_eval:n". +% Chooses case <number>. If you wish to use negative numbers as well, +% you can offset them with "\intexpr_eval:n". % \begin{texnote} % These are the \TeX{} primitives \tn{ifcase} and \tn{or}. % \end{texnote} % \end{function} % -% \StopEventually{} +% \end{documentation} % -% \subsection{The Implementation} +% \begin{implementation} +% +% \section{\pkg{l3num} implementation} % % % We start by ensuring that the required packages are loaded. % \begin{macrocode} -%<package>\ProvidesExplPackage -%<package> {\filename}{\filedate}{\fileversion}{\filedescription} -%<package&!check>\RequirePackage{l3expan}\par -%<package&check>\RequirePackage{l3chk}\par +%<*package> +\ProvidesExplPackage + {\filename}{\filedate}{\fileversion}{\filedescription} +\package_check_loaded_expl: +%</package> %<*initex|package> % \end{macrocode} % -% \begin{macro}{\num_value:w} -% \begin{macro}{\num_eval:w} -% \begin{macro}{\num_eval_end:} % \begin{macro}{\if_num:w} -% \begin{macro}{\if_num_odd:w} % \begin{macro}{\if_case:w} -% \begin{macro}{\or:} % Here are the remaining primitives for number comparisons and % expressions. % \begin{macrocode} -\let_new:NN \num_value:w \tex_number:D -\let_new:NN \num_eval:w \etex_numexpr:D -\let_new:NN \num_eval_end: \scan_stop: -\let_new:NN \if_num:w \tex_ifnum:D -\let_new:NN \if_num_odd:w \tex_ifodd:D -\let_new:NN \if_case:w \tex_ifcase:D -\let_new:NN \or: \tex_or:D +\cs_new_eq:NN \if_num:w \tex_ifnum:D +\cs_new_eq:NN \if_case:w \tex_ifcase:D % \end{macrocode} % \end{macro} % \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} % % Functions that support \LaTeX's user accessible counters should be % added here, too. But first the internal counters. @@ -427,10 +310,10 @@ % Incrementing and decrementing of integer registers is done with % the following functions. % \begin{macrocode} -\def:Npn \num_incr:N #1{\num_add:Nn#1 1} -\def:Npn \num_decr:N #1{\num_add:Nn#1 \c_minus_one} -\def:Npn \num_gincr:N #1{\num_gadd:Nn#1 1} -\def:Npn \num_gdecr:N #1{\num_gadd:Nn#1 \c_minus_one} +\cs_set_nopar:Npn \num_incr:N #1{\num_add:Nn#1 1} +\cs_set_nopar:Npn \num_decr:N #1{\num_add:Nn#1 \c_minus_one} +\cs_set_nopar:Npn \num_gincr:N #1{\num_gadd:Nn#1 1} +\cs_set_nopar:Npn \num_gdecr:N #1{\num_gadd:Nn#1 \c_minus_one} % \end{macrocode} % \end{macro} % \end{macro} @@ -443,10 +326,10 @@ % \begin{macro}{\num_gdecr:c} % We also need \ldots % \begin{macrocode} -\def_new:Npn \num_incr:c {\exp_args:Nc \num_incr:N} -\def_new:Npn \num_decr:c {\exp_args:Nc \num_decr:N} -\def_new:Npn \num_gincr:c {\exp_args:Nc \num_gincr:N} -\def_new:Npn \num_gdecr:c {\exp_args:Nc \num_gdecr:N} +\cs_generate_variant:Nn \num_incr:N {c} +\cs_generate_variant:Nn \num_decr:N {c} +\cs_generate_variant:Nn \num_gincr:N {c} +\cs_generate_variant:Nn \num_gdecr:N {c} % \end{macrocode} % \end{macro} % \end{macro} @@ -459,10 +342,13 @@ % \begin{macro}{\num_gzero:c} % We also need \ldots % \begin{macrocode} -\def_new:Npn \num_zero:N #1 {\num_set:Nn #1 0} -\def_new:Npn \num_gzero:N #1 {\num_gset:Nn #1 0} -\def_new:Npn \num_zero:c {\exp_args:Nc \num_zero:N} -\def_new:Npn \num_gzero:c {\exp_args:Nc \num_gzero:N} +\cs_new_nopar:Npn \num_zero:N #1 {\num_set:Nn #1 0} +\cs_new_nopar:Npn \num_gzero:N #1 {\num_gset:Nn #1 0} +% \end{macrocode} +% +% \begin{macrocode} +\cs_generate_variant:Nn \num_zero:N {c} +\cs_generate_variant:Nn \num_gzero:N {c} % \end{macrocode} % \end{macro} % \end{macro} @@ -475,33 +361,27 @@ % \begin{macro}{\num_new:c} % Allocate a new \m{num} variable and initialize it with zero. % \begin{macrocode} -\def_new:Npn \num_new:N #1{\tlp_new:Nn #1{0}} -\def_new:Npn \num_new:c {\exp_args:Nc \num_new:N} +\cs_new_nopar:Npn \num_new:N #1{\tl_new:Nn #1{0}} +\cs_generate_variant:Nn \num_new:N {c} % \end{macrocode} % \end{macro} % \end{macro} % -% -% \begin{macro}{\num_eval:n} -% This function enables us to do all the operations without the aid of -% an \m{int} register. -% \begin{macrocode} -\def_new:Npn \num_eval:n #1{\num_eval:w #1\num_eval_end:} -% \end{macrocode} -% \end{macro} -% % \begin{macro}{\num_set:Nn} % \begin{macro}{\num_set:cn} % \begin{macro}{\num_gset:Nn} % \begin{macro}{\num_gset:cn} % Assigning values to \m{num} registers. % \begin{macrocode} -\def_new:Npn \num_set:Nn #1#2{ - \tlp_set:No #1{ \tex_number:D \num_eval:n {#2} } +\cs_new_nopar:Npn \num_set:Nn #1#2{ + \tl_set:No #1{ \tex_number:D \intexpr_eval:n {#2} } } -\def_new:Npn \num_gset:Nn {\pref_global:D \num_set:Nn} -\def_new:Npn \num_set:cn {\exp_args:Nc \num_set:Nn } -\def_new:Npn \num_gset:cn {\exp_args:Nc \num_gset:Nn } +\cs_generate_variant:Nn\num_set:Nn {c} +% \end{macrocode} +% +% \begin{macrocode} +\cs_new_nopar:Npn \num_gset:Nn {\pref_global:D \num_set:Nn} +\cs_generate_variant:Nn\num_gset:Nn {c} % \end{macrocode} % \end{macro} % \end{macro} @@ -514,10 +394,8 @@ % \begin{macro}{\num_set_eq:cc} % Setting \m{num} registers equal to each other. % \begin{macrocode} -\let_new:NN \num_set_eq:NN \tlp_set_eq:NN -\def_new:Npn \num_set_eq:cN {\exp_args:Nc \num_set_eq:NN} -\def_new:Npn \num_set_eq:Nc {\exp_args:NNc \num_set_eq:NN} -\def_new:Npn \num_set_eq:cc {\exp_args:Ncc \num_set_eq:NN} +\cs_new_eq:NN \num_set_eq:NN \tl_set_eq:NN +\cs_generate_variant:Nn\num_set_eq:NN {c,Nc,cc} % \end{macrocode} % \end{macro} % \end{macro} @@ -530,10 +408,8 @@ % \begin{macro}{\num_gset_eq:cc} % Setting \m{num} registers equal to each other. % \begin{macrocode} -\let_new:NN \num_gset_eq:NN \tlp_gset_eq:NN -\def_new:Npn \num_gset_eq:cN {\exp_args:Nc \num_gset_eq:NN} -\def_new:Npn \num_gset_eq:Nc {\exp_args:NNc \num_gset_eq:NN} -\def_new:Npn \num_gset_eq:cc {\exp_args:Ncc \num_gset_eq:NN} +\cs_new_eq:NN \num_gset_eq:NN \tl_gset_eq:NN +\cs_generate_variant:Nn\num_gset_eq:NN {c,Nc,cc} % \end{macrocode} % \end{macro} % \end{macro} @@ -545,12 +421,15 @@ % \begin{macro}{\num_gadd:Nn} % \begin{macro}{\num_gadd:cn} % Adding is easily done as the second argument goes through -% |\num_eval:n|. +% |\intexpr_eval:n|. % \begin{macrocode} -\def_new:Npn \num_add:Nn #1#2 {\num_set:Nn #1{#1+#2}} -\def_new:Npn \num_add:cn {\exp_args:Nc\num_add:Nn} -\def_new:Npn \num_gadd:Nn {\pref_global:D \num_add:Nn} -\def_new:Npn \num_gadd:cn {\exp_args:Nc\num_gadd:Nn} +\cs_new_nopar:Npn \num_add:Nn #1#2 {\num_set:Nn #1{#1+#2}} +\cs_generate_variant:Nn\num_add:Nn {c} +% \end{macrocode} +% +% \begin{macrocode} +\cs_new_nopar:Npn \num_gadd:Nn {\pref_global:D \num_add:Nn} +\cs_generate_variant:Nn\num_gadd:Nn {c} % \end{macrocode} % \end{macro} % \end{macro} @@ -562,61 +441,30 @@ % \begin{macro}{\num_use:c} % Here is how num macros are accessed: % \begin{macrocode} -\let_new:NN\num_use:N \use_arg_i:n -\let_new:NN\num_use:c \cs_use:c +\cs_new_eq:NN\num_use:N \use:n +\cs_new_eq:NN\num_use:c \use:c % \end{macrocode} % \end{macro} % \end{macro} % -% -% \begin{macro}{\num_compare:nNnTF} -% \begin{macro}{\num_compare:nNnT} -% \begin{macro}{\num_compare:nNnF} -% Simple comparison tests. +% \begin{macro}{\num_show:N} +% \begin{macro}{\num_show:c} +% Here is how num macros are diagnosed: % \begin{macrocode} -\def_test_function_new:npn {num_compare:nNn}#1#2#3{ - \if_num:w \num_eval:n {#1}#2\num_eval:n {#3} -} -\def_new:Npn \num_compare:cNcTF { \exp_args:NcNc\num_compare:nNnTF } +\cs_new_eq:NN\num_show:N \cs_show:N +\cs_new_eq:NN\num_show:c \cs_show:c % \end{macrocode} % \end{macro} % \end{macro} -% \end{macro} % -% \begin{macro}{\num_compare_p:nNn} -% A predicate function. -% \begin{macrocode} -\def_new:Npn \num_compare_p:nNn #1#2#3{ - \if_num:w \num_eval:n {#1}#2\num_eval:n {#3} - \c_true - \else: - \c_false - \fi: -} -% \end{macrocode} -% \end{macro} % -% \begin{macro}{\num_max_of:nn} -% \begin{macro}{\num_min_of:nn} -% \begin{macro}{\num_abs:n} -% Functions for $\min$, $\max$, and absolute value. -% \begin{macrocode} -\def_new:Npn \num_abs:n#1{ - \if_num:w \num_eval:n{#1}<\c_zero \exp_after:NN -\fi: #1 -} -\def_new:Npn \num_max_of:nn#1#2{\num_compare:nNnTF {#1}>{#2}{#1}{#2}} -\def_new:Npn \num_min_of:nn#1#2{\num_compare:nNnTF {#1}<{#2}{#1}{#2}} -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} % % \begin{macro}{\num_elt_count:n} % \begin{macro}{\num_elt_count_prop:Nn} % Helper function for counting elements in a list. % \begin{macrocode} -\def_long_new:Npn \num_elt_count:n #1 { + 1 } -\def_long_new:Npn \num_elt_count_prop:Nn #1#2 { + 1 } +\cs_new:Npn \num_elt_count:n #1 { + 1 } +\cs_new:Npn \num_elt_count_prop:Nn #1#2 { + 1 } % \end{macrocode} % \end{macro} % \end{macro} @@ -641,167 +489,17 @@ % \end{macro} % \end{macro} % -% \subsubsection{Defining constants} -% As stated, most constants can be defined as |\tex_chardef:D| or -% |\tex_mathchardef:D| but that's engine dependent. Omega/Aleph -% allows |\tex_chardef:D|s up to 65535 which is also the maximum -% number of registers of all types. -% \begin{macro}{\const_new:Nn} % \begin{macro}{\c_max_register_num} -% \begin{macro}{\const_new_aux:Nw} -% \begin{macrocode} % \begin{macrocode} -\engine_if_aleph:TF -{ - \let_new:NN \const_new_aux:Nw \tex_chardef:D - \const_new_aux:Nw \c_max_register_num = 65535 \scan_stop: -} -{ - \let_new:NN \const_new_aux:Nw \tex_mathchardef:D - \const_new_aux:Nw \c_max_register_num = 32767 \scan_stop: -} -\def_new:Npn \const_new:Nn #1#2 { - \num_compare:nNnTF {#2} > \c_minus_one - { - \num_compare:nNnTF {#2} > \c_max_register_num - {\int_new:N #1 \int_set:Nn #1{#2}} - {\chk_new_cs:N #1 \const_new_aux:Nw #1 = #2 \scan_stop: } - } - {\int_new:N #1 \int_set:Nn #1{#2}} -} +\tex_mathchardef:D \c_max_register_num = 32767 \scan_stop: % \end{macrocode} % \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_six} -% \begin{macro}{\c_seven} -% \begin{macro}{\c_nine} -% \begin{macro}{\c_ten} -% \begin{macro}{\c_eleven} -% \begin{macro}{\c_sixteen} -% \begin{macro}{\c_thirty_two} -% \begin{macro}{\c_hundred_one} -% \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} -% 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_countdef:D \c_minus_one = 10 \scan_stop: - %% \c_minus_one = -1 \scan_stop: %% in l3basics - %% \tex_chardef:D \c_sixteen = 16\scan_stop: %% in l3basics -\const_new:Nn \c_zero {0} -\const_new:Nn \c_one {1} -\const_new:Nn \c_two {2} -\const_new:Nn \c_three {3} -\const_new:Nn \c_four {4} -\const_new:Nn \c_six {6} -\const_new:Nn \c_seven {7} -\const_new:Nn \c_nine {9} -\const_new:Nn \c_ten {10} -\const_new:Nn \c_eleven {11} -\const_new:Nn \c_thirty_two {32} -% \end{macrocode} -% The next one may seem a little odd (obviously!) but is useful when -% dealing with logical operators. -% \begin{macrocode} -\const_new:Nn \c_hundred_one {101} -\const_new:Nn \c_twohundred_fifty_five {255} -\const_new:Nn \c_twohundred_fifty_six {256} -\const_new:Nn \c_thousand {1000} -\const_new:Nn \c_ten_thousand {10000} -\const_new:Nn \c_ten_thousand_one {10001} -\const_new:Nn \c_ten_thousand_two {10002} -\const_new:Nn \c_ten_thousand_three {10003} -\const_new:Nn \c_ten_thousand_four {10004} -\const_new:Nn \c_twenty_thousand {20000} -% \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} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% % % \begin{macrocode} %</initex|package> % \end{macrocode} % -% \endinput -% -% $Log$ -% Revision 1.17 2006/03/20 18:26:37 braams -% Updated the copyright notice (2006) and demoted all implementation -% sections to subsections and so on to clean up the toc for source3.tex -% -% Revision 1.16 2005/12/27 10:03:01 morten -% Changed RCS information retrieval -% -% Revision 1.15 2005/12/06 13:41:02 morten -% Added a few functions to ease processing with \if_case:w -% -% Revision 1.14 2005/12/03 12:57:36 morten -% Minor touch-ups. -% -% Revision 1.13 2005/10/27 22:39:02 morten -% Forgot to add \if_num_odd:w -% -% Revision 1.12 2005/10/27 22:34:26 morten -% Added \if_num:w, \if_case:w and \or: as they really belong here. -% -% Revision 1.11 2005/04/06 22:36:53 braams -% Missed one occurence of \c_max_register_int -% -% Revision 1.10 2005/04/06 21:38:46 morten -% Removed dependency on l3prg and added a missing function. -% -% Revision 1.9 2005/04/05 22:05:38 braams -% Renamed \c_max_regsiter_int to \c_max_register_num, -% Fixed const_new to allow 32767 as a value for \tex_mathchardef:D -% Added \c_ten and \c_eleven as constants -% -% Revision 1.8 2005/03/26 21:06:35 morten -% Update documentation -% -% Revision 1.7 2005/03/22 23:21:32 morten -% Now independent of l3int and can be used as a very primitive module. -% -% Revision 1.6 2005/03/16 22:36:20 braams -% Added the tweaks necessary to be able to load with initex -% -% Revision 1.5 2005/03/11 21:39:47 braams -% Fixed the use of RCS information; added \StopEventually +% \end{implementation} +% \PrintIndex % +% \endinput diff --git a/Master/texmf-dist/source/latex/expl3/l3precom.dtx b/Master/texmf-dist/source/latex/expl3/l3precom.dtx index 786181d93b5..6b681f1610e 100644 --- a/Master/texmf-dist/source/latex/expl3/l3precom.dtx +++ b/Master/texmf-dist/source/latex/expl3/l3precom.dtx @@ -1,5 +1,5 @@ % \iffalse -%% File: l3precom.dtx Copyright (C) 1990-2006 Frank Mittelbach, LaTeX3 project +%% File: l3precom.dtx Copyright (C) 1990-2006,2009 Frank Mittelbach, LaTeX3 project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this @@ -17,7 +17,7 @@ %% %% The development version of the bundle can be found at %% -%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/ +%% http://www.latex-project.org/svnroot/experimental/trunk/ %% %% for those people who are interested. %% @@ -36,7 +36,7 @@ \RequirePackage{l3names} %</driver|package> %\fi -\GetIdInfo$Id: l3precom.dtx 621 2007-09-01 20:14:19Z morten $ +\GetIdInfo$Id: l3precom.dtx 1362 2009-05-28 20:19:21Z joseph $ {L3 Experimental precompilation module} %\iffalse %<*driver> @@ -44,41 +44,74 @@ \ProvidesFile{\filename.\filenameext} [\filedate\space v\fileversion\space\filedescription] %\iffalse -\documentclass{l3doc} +\documentclass[full]{l3doc} \begin{document} \DocInput{\filename.\filenameext} \end{document} %</driver> % \fi % +% \title{The \textsf{l3precom} package\thanks{This file +% has version number \fileversion, last +% revised \filedate.}\\ +% Precompilation of complex data} +% \author{\Team} +% \date{\filedate} +% \maketitle +% +% \begin{documentation} +% +% \section{Introduction} +% +% It is possible speed up the processing of documents when complex parts +% of the document style file are `precompiled' and stored in a +% separate file. +% % \section{Control sequence functions extended \ldots} % % \begin{function}{\cs_gen_sym:N | % \cs_ggen_sym:N} % \begin{syntax} -% "\cs_gen_sym:N" <tlp> +% "\cs_gen_sym:N" <tl var.> % \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 +% is returned locally in <tl var.> 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{function}{\cs_record_name:N|\cs_record_name:c} % \begin{syntax} % "\cs_record_name:N" <cs> % \end{syntax} -% Takes the <cs> and saves it in a special places for pre-compiling +% Takes the <cs> and saves it in a special place 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_record_meaning:N} +% \begin{syntax} +% "\cs_record_meaning:N" <cs> +% \end{syntax} +% Takes the <cs> and saves its meaning in a special place for pre-compiling +% purposes on a file later on. Used for tracing purposes. +% \end{function} +% +% \begin{function}{\register_record_name:N} +% \begin{syntax} +% "\register_record_name:N" <register> +% \end{syntax} +% Takes the <register> 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:". +% \end{function} +% % \begin{function}{\cs_load_dump:n} % \begin{syntax} -% "\cs_load_dump:n" "{" <file name> "}" +% "\cs_load_dump:n" \Arg{file name} % \end{syntax} % Loads and executes the file <file name> if found. Then scans % further ignoring everything until finding "\cs_dump:" where normal @@ -93,14 +126,22 @@ % 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> "}" +% "\cs_set_nopar:Npn" <cs> \Arg{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} % +% \begin{function}{\dumpLaTeXstate} +% \begin{syntax} +% "\dumpLaTeXstate" \Arg{file} +% \end{syntax} +% This function is used to write control sequences +% and registers, together with their meaning or value in the <file>|.dmp| +% file. +% \end{function} % -% \subsection{Internal variables} +% \section{Internal variables} % % \begin{variable}{\g_gen_sym_num | % \g_ggen_sym_num} Holds the number of the last @@ -113,12 +154,28 @@ % % \begin{variable}{\c_cs_dump_stream} % Output stream used for writing out the definitions of the -% recorded <tlp>. +% recorded <tl var.>. % \end{variable} % -% \StopEventually{} +% \begin{variable}{\g_cs_dump_name_tl} +% Used to store the name of the file to dump to. +% \end{variable} % -% \subsection{The Implementation} +% \begin{variable}{\g_cs_trace_seq} +% Sequence which holds the control sequence names that are to +% be dumped with their corresponding meanings. Used for tracing purposes. +% \end{variable} +% +% \begin{variable}{\g_register_trace_seq} +% Sequence holding the register names to be dumped with their +% corresponding values. Used for tracing purposes. +% \end{variable} +% +% \end{documentation} +% +% \begin{implementation} +% +% \section{\pkg{l3precom} implementation} % % We start by ensuring that the required packages are loaded. % \begin{macrocode} @@ -130,10 +187,6 @@ %<package>\RequirePackage{l3int} % \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. @@ -147,11 +200,11 @@ % \end{macro} % % -% \begin{macro}{\g_cs_dump_name_tlp} -% This \m{tlp} is used to store the name of the file. +% \begin{macro}{\g_cs_dump_name_tl} +% This \m{tl var.}~is used to store the name of the file. % % \begin{macrocode} -\tlp_new:Nn\g_cs_dump_name_tlp{} +\tl_new:Nn\g_cs_dump_name_tl{} % \end{macrocode} % \end{macro} % @@ -165,25 +218,23 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}{\cs_record_name:N} -% \begin{macro}{\cs_record_name:c} +% \begin{macro}{\cs_record_name:N,\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{ +\cs_new_nopar: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} +\cs_generate_variant:Nn \cs_record_name:N {c} % \end{macrocode} % \end{macro} -% \end{macro} % % % \begin{macro}{\cs_dump:} @@ -195,42 +246,42 @@ % 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} +\cs_new_nopar:Npn\cs_dump:{ +\iow_term:x{Precompiling~style~into~(\g_cs_dump_name_tl)} +\iow_open:Nn\c_cs_dump_stream{\g_cs_dump_name_tl} % \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 +\iow_now:Nx\c_cs_dump_stream {\group_begin: -\tex_catcode:D`\token_to_string:N\*=11\scan_stop: -\token_to_string:N\CodeStart +\tex_catcode:D`\token_to_str:N\*=11\scan_stop: +\token_to_str:N\ExplSyntaxOn } \seq_map_inline:Nn \g_cs_dump_seq {\tex_message:D{.} -\iow_expanded:Nn\c_cs_dump_stream +\iow_now:Nx\c_cs_dump_stream % \end{macrocode} -% We use a direct |\gdef:Npn| to disable any type of local/global +% We use a direct |\cs_gset_nopar:Npn| to disable any type of local/global % check on the pointers. % \begin{macrocode} - {\exp_not:n{\gdef:Npn ##1} - {\tlp_to_str:N##1}} + {\exp_not:n{\cs_gset_nopar:Npn ##1} + {\tl_to_str:N##1}} } % \end{macrocode} % We also need to remember the current values of the % |\g_gen_sym_num| and |\g_ggen_sym_num| counters to allow % further updates after a database was dumped. % \begin{macrocode} -\iow_expanded:Nn \c_cs_dump_stream {\exp_not:n{\num_gset:Nn +\iow_now:Nx \c_cs_dump_stream {\exp_not:n{\num_gset:Nn \g_gen_sym_num} {\num_use:N\g_gen_sym_num}^^J \exp_not:n{\num_gset:Nn \g_ggen_sym_num} {\num_use:N\g_ggen_sym_num}} -\iow_expanded:Nn +\iow_now:Nx \c_cs_dump_stream {\group_end:} \iow_close:N\c_cs_dump_stream @@ -246,14 +297,14 @@ % continues and a subsequent |\cs_dump:| command will then create the % dump file. % \begin{macrocode} -\def_new:Npn\cs_load_dump:n#1{ +\cs_new_nopar:Npn\cs_load_dump:n#1{ \file_not_found:nTF{#1.cmp} %<*precompile> -{\tlp_gset:Nn\g_cs_dump_name_tlp{#1.cmp}} +{\tl_gset:Nn\g_cs_dump_name_tl{#1.cmp}} %</precompile> %<-precompile> {\tex_errmessage:D{Cannot~ dump~ with~ this~ format}} {\input{#1.cmp} -\let:NN\cs_dump:\fi: +\cs_set_eq:NN\cs_dump:\fi: \if_false:}} % \end{macrocode} % \end{macro} @@ -279,28 +330,28 @@ % is locally stored in the token that was passed in |#1|. % % \begin{macrocode} -\def_new:Npn\cs_gen_sym:N#1{ +\cs_new_nopar:Npn\cs_gen_sym:N#1{ \num_gincr:N\g_gen_sym_num -\tlp_set:Nc#1{l*\tex_romannumeral:D\num_use:N\g_gen_sym_num} +\tl_set:Nc#1{l*\tex_romannumeral:D\num_use:N\g_gen_sym_num} %<*precompile> -\exp_after:NN\cs_record_name:N#1 +\exp_after:wN\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} +\exp_after:wN\tl_clear_new:N#1} % \end{macrocode} % The global variant % \begin{macrocode} -\def_new:Npn\cs_ggen_sym:N#1{ +\cs_new_nopar:Npn\cs_ggen_sym:N#1{ \num_gincr:N\g_ggen_sym_num -\tlp_set:Nc#1{g*\tex_romannumeral:D\num_use:N\g_ggen_sym_num} +\tl_set:Nc#1{g*\tex_romannumeral:D\num_use:N\g_ggen_sym_num} %<*precompile> -\exp_after:NN\cs_record_name:N#1 +\exp_after:wN\cs_record_name:N#1 %</precompile> -\exp_after:NN\tlp_clear_new:N#1} +\exp_after:wN\tl_clear_new:N#1} % \end{macrocode} % \end{macro} % \end{macro} @@ -332,7 +383,7 @@ % \begin{macro}{\cs_record_meaning:N} % Function marking a control sequence for dumping with meaning. % \begin{macrocode} -\def:Npn\cs_record_meaning:N#1{ +\cs_set_nopar:Npn\cs_record_meaning:N#1{ \seq_gput_left:Nn \g_cs_trace_seq#1} % \end{macrocode} @@ -341,7 +392,7 @@ % \begin{macro}{\register_record_name:N} % Function marking a register for dumping with value. % \begin{macrocode} -\def:Npn\register_record_name:N#1{ +\cs_set_nopar:Npn\register_record_name:N#1{ \seq_gput_left:Nn \g_register_trace_seq#1} % \end{macrocode} @@ -358,23 +409,23 @@ % 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)} +\cs_new_nopar:Npn\dumpLaTeXstate#1{ + \iow_term:x{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~ + \iow_now:Nx\c_cs_dump_stream + {\token_to_str: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} + \iow_now:Nx\c_cs_dump_stream + {\token_to_str:N##1 + \toks_use:N##1} } \tex_message:D{~finished} } @@ -391,26 +442,7 @@ %</showmemory> % \end{macrocode} % -% \endinput -% -% $Log$ -% Revision 1.7 2006/03/20 18:26:37 braams -% Updated the copyright notice (2006) and demoted all implementation -% sections to subsections and so on to clean up the toc for source3.tex -% -% Revision 1.6 2005/12/27 16:03:21 morten -% Changed RCS information retrieval plus a few name changes -% -% Revision 1.5 2005/04/12 12:06:30 morten -% Fixed the use of fake integers (now known as "num") -% -% Revision 1.4 2005/03/16 22:36:14 braams -% Added the tweaks necessary to be able to load with initex -% -% Revision 1.3 2005/03/11 21:51:50 braams -% Just another small mistake to be corrected -% -% Revision 1.2 2005/03/11 21:21:01 braams -% Added the header for CVS public read access and fixed the -% use of RCS data +% \end{implementation} +% \PrintIndex % +% \endinput diff --git a/Master/texmf-dist/source/latex/expl3/l3prg.dtx b/Master/texmf-dist/source/latex/expl3/l3prg.dtx index b99caf822d7..ca50697fd0f 100644 --- a/Master/texmf-dist/source/latex/expl3/l3prg.dtx +++ b/Master/texmf-dist/source/latex/expl3/l3prg.dtx @@ -1,5 +1,5 @@ % \iffalse -%% File: l3prg.dtx Copyright (C) 2005-2006 LaTeX3 project +%% File: l3prg.dtx Copyright (C) 2005-2009 LaTeX3 project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this @@ -17,7 +17,7 @@ %% %% The development version of the bundle can be found at %% -%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/ +%% http://www.latex-project.org/svnroot/experimental/trunk/ %% %% for those people who are interested. %% @@ -36,7 +36,7 @@ \RequirePackage{l3names} %</driver|package> %\fi -\GetIdInfo$Id: l3prg.dtx 768 2008-08-05 19:45:06Z morten $ +\GetIdInfo$Id: l3prg.dtx 1365 2009-05-31 17:26:17Z mittelba $ {L3 Experimental control structures} %\iffalse %<*driver> @@ -44,9 +44,9 @@ \ProvidesFile{\filename.\filenameext} [\filedate\space v\fileversion\space\filedescription] %\iffalse -\documentclass{l3doc} +\documentclass[full]{l3doc} \begin{document} -\DocInput{\filename.\filenameext} +\DocInput{l3prg.dtx} \end{document} %</driver> % \fi @@ -60,167 +60,121 @@ % \date{\filedate} % \maketitle % +% \begin{documentation} % -% \section{Control structures} +% \section{Conditionals and logical operations} % -% \subsection{Choosing modes} +% Conditional processing in \LaTeX3 is defined as something that +% performs a series of tests, possibly involving assignments and +% calling other functions that do not read further ahead in the input +% stream. After processing the input, a \emph{state} is returned. The +% typical states returned are \meta{true} and \meta{false} but other +% states are possible, say an \meta{error} state for erroneous +% input, e.g., text as input in a function comparing integers. % -% \begin{function}{\mode_if_vertical_p:| -% \mode_if_vertical:TF | -% \mode_if_vertical:T | -% \mode_if_vertical:F -% } -% \begin{syntax} -% "\mode_if_vertical:TF" "{"<true code>"}" "{"<false code>"}" -% \end{syntax} -% Determines if \TeX{} is in vertical mode or not and executes either -% <true code> or <false code> accordingly. -% \end{function} -% -% \begin{function}{\mode_if_horizontal_p:| -% \mode_if_horizontal:TF | -% \mode_if_horizontal:T | -% \mode_if_horizontal:F -% } -% \begin{syntax} -% "\mode_if_horizontal:TF" "{"<true code>"}" "{"<false code>"}" -% \end{syntax} -% Determines if \TeX{} is in horizontal mode or not and executes either -% <true code> or <false code> accordingly. -% \end{function} -% -% -% \begin{function}{ -% \mode_if_inner_p:| -% \mode_if_inner:TF| -% \mode_if_inner:T| -% \mode_if_inner:F -% } -% \begin{syntax} -% "\mode_if_inner:TF" "{"<true code>"}" "{"<false code>"}" -% \end{syntax} -% Determines if \TeX{} is in inner mode or not and executes either -% <true code> or <false code> accordingly. -% \end{function} -% -% \begin{function}{ -% \mode_if_math:TF| -% \mode_if_math:T| -% \mode_if_math:F| -% } -% \begin{syntax} -% "\mode_if_math:TF" "{"<true code>"}" "{"<false code>"}" -% \end{syntax} -% Determines if \TeX{} is in math mode or not and executes either -% <true code> or <false code> accordingly. -% \begin{texnote} -% This version will choose the right branch even at the beginning of -% an alignment cell. -% \end{texnote} -% \end{function} -% -% -% \subsubsection{Alignment safe grouping and scanning} -% -% \begin{function}{\scan_align_safe_stop:} -% \begin{syntax} -% "\scan_align_safe_stop:" -% \end{syntax} -% This function gets \TeX{} on the right track inside an alignment -% cell but without destroying any kerning. -% \end{function} +% % +% \LaTeX3 has two primary forms of conditional flow processing based +% on these states. One type is predicate functions that turn the +% returned state into a boolean \meta{true} or \meta{false}. For +% example, the function "\cs_if_free_p:N" checks whether the control +% sequence given as its argument is free and then returns the boolean +% \meta{true} or \meta{false} values to be used in testing with +% "\if_predicate:w" or in functions to be described below. The other type +% is the kind of functions choosing a particular argument from the +% input stream based on the result of the testing as in +% "\cs_if_free:NTF" which also takes one argument (the "N") and then +% executes either \meta{true} or \meta{false} depending on the +% result. Important to note here is that the arguments are executed +% after exiting the underlying "\if...\fi:" structure % -% \begin{function}{\group_align_safe_begin:| -% \group_align_safe_end:} -% \begin{syntax} -% "\group_align_safe_begin:" <...> "\group_align_safe_end:" -% \end{syntax} -% Encloses <...> inside a group but is safe inside an alignment cell. -% See the implementation of |\peek_token_generic:NNTF| for an -% application. -% \end{function} % % -% \subsection{Producing $n$ copies} -% -% There are often several different requirements for producing -% multiple copies of something. Sometimes one might want to produce a -% number of identical copies of a sequence of tokens whereas at other -% times the goal is to simulate a for loop as known from most real -% programming languages. % -% \begin{function}{\prg_replicate:nn } -% \begin{syntax} -% "\prg_replicate:nn" "{" <number> "}" "{" <arg> "}" -% \end{syntax} -% Creates <number> copies of <arg>. Expandable. -% \end{function} % % -% \begin{function}{\prg_stepwise_function:nnnN} -% \begin{syntax} -% "\prg_stepwise_function:nnnN" "{"<start>"}" "{"<step>"}" -% "{"<end>"}" <function> -% \end{syntax} -% This function performs <action> once for each step starting at -% <start> and ending once <end> is passed. <function> is placed -% directly in front of a brace group holding the current number so it -% should usually be a function taking one argument. The -% |\prg_stepwise_function:nnnN| function is expandable. -% \end{function} % -% \begin{function}{\prg_stepwise_inline:nnnn} -% \begin{syntax} -% "\prg_stepwise_inline:nnnn" "{"<start>"}" "{"<step>"}" "{"<end>"}" -% "{"<action>"}" -% \end{syntax} -% Same as |\prg_stepwise_function:nnnN| except here <action> is -% performed each time with |##1| as a placeholder for the number -% currently being tested. This function is not expandable and it is -% nestable. -% \end{function} +% \section{Defining a set of conditional functions} % -% \begin{function}{\prg_stepwise_variable:nnnNn} -% \begin{syntax} -% "\prg_stepwise_variable:nnnn" "{"<start>"}" "{"<step>"}" "{"<end>"}" -% <temp-var> "{"<action>"}" -% \end{syntax} -% Same as |\prg_stepwise_inline:nnnn| except here the current value is -% stored in <temp-var> and the programmer can use it in <action>. This -% function is not expandable. +% \begin{function}{ \prg_return_true: | +% \prg_return_false: } +% These functions exit conditional processing when used in +% conjunction with the generating functions listed below. % \end{function} % +% \begin{function}{% +% \prg_set_conditional:Nnn | +% \prg_set_conditional:Npnn | +% \prg_new_conditional:Nnn | +% \prg_new_conditional:Npnn | +% \prg_set_protected_conditional:Nnn | +% \prg_set_protected_conditional:Npnn | +% \prg_new_protected_conditional:Nnn | +% \prg_new_protected_conditional:Npnn | +% } +% \begin{syntax} +% "\prg_set_conditional:Nnn" <test> <conds> <code> +% "\prg_set_conditional:Npnn" <test> <param> <conds> <code> +% \end{syntax} +% This defines a conditional \meta{base function} which upon +% evaluation using |\prg_return_true:| and |\prg_return_false:| to +% finish branches, +% returns a state. Currently the states are either \meta{true} or +% \meta{false} although this can change as more states may be +% introduced, say an \meta{error} state. \meta{conds} is a comma +% separated list possibly consisting of |p| for denoting a predicate function +% returning the boolean \meta{true} or \meta{false} values and |TF|, +% |T| and |F| for the functions that act on the tokens following in +% the input stream. The |:Nnn| form implicitly determines the number +% of arguments from the function being defined whereas the |:Npnn| +% form expects a primitive parameter text. +% +% An example can easily clarify matters here: +% \begin{verbatim} +% \prg_set_conditional:Nnn \foo_if_bar:NN {p,TF,T} { +% \if_meaning:w \l_tmpa_tl #1 +% \prg_return_true: +% \else: +% \if_meaning:w \l_tmpa_tl #2 +% \prg_return_true: +% \else: +% \prg_return_false: +% \fi: +% \fi: +% } +% \end{verbatim} +% This defines the function |\foo_if_bar_p:NN|, |\foo_if_bar:NNTF|, +% |\foo_if_bar:NNT| but not |\foo_if_bar:NNF| (because "F" is missing from +% the \meta{conds} list). The return statements +% take care of resolving the remaining |\else:| and |\fi:| before +% returning the state. There must be a return statement for each +% branch, failing to do so will result in an error if that branch is +% executed. +% \end{function} % % -% \subsection{Conditionals and logical operations} % % -% \LaTeX3 has two primary forms of conditional flow processing. The -% one type deals with the truth value of a test directly as in -% "\cs_free:NTF" where you test if a control sequence was undefined -% and then execute either the \m{true} or \m{false} part depending on -% the result and after exiting the underlying "\if...\fi:" structure. -% The second type has to do with predicate functions like -% "\cs_free_p:N" which return either "\c_true" or "\c_false" to be -% used in testing with "\if:w". % +% \section{The boolean data type} % % This section describes a boolean data type which is closely -% connected to both parts as sometimes you want to execute some code -% depending on the value of a switch (e.g.,~draft/final) and other -% times you perhaps want to use it as a predicate function in an -% "\if:w" test. Parsing "\iffalse" -% and "\iftrue" tokens can be quite tricky at times so the easiest is to -% simply let a boolean either be "\c_true" or "\c_false". This -% also means we get the logical operations And, Or, and Not which can -% then be used on both the boolean type and predicate functions. All -% functions by the name |\predicate| are expandable and expect the -% input to also be fully expandable. More generic constructs do not -% contain |predicate| in their names. -% -% -% \subsubsection{The boolean data type} +% connected to conditional processing as sometimes you want to +% execute some code depending on the value of a switch +% (e.g.,~draft/final) and other times you perhaps want to use it as a +% predicate function in an "\if_predicate:w" test. The problem of the +% primitive "\if_false:" and "\if_true:" tokens is that it is not +% always safe to pass them around as they may interfere with scanning +% for termination of primitive conditional processing. Therefore, we +% employ two canonical booleans: "\c_true_bool" or +% "\c_false_bool". Besides preventing problems as described above, it +% also allows us to implement a simple boolean parser supporting the +% logical operations And, Or, Not, etc.\ which can then be used on +% both the boolean type and predicate functions. +% +% All conditonal "\bool_" functions are expandable and expect the +% input to also be fully expandable (which will generally mean being +% constructed from predicate functions, possibly nested). % % \begin{function}{% % \bool_new:N | @@ -230,7 +184,7 @@ % "\bool_new:N" <bool> % \end{syntax} % Define a new boolean variable. The initial value is <false>. A -% boolean is actually just either "\c_true" or "\c_false". +% boolean is actually just either "\c_true_bool" or "\c_false_bool". % \end{function} % % \begin{function}{% @@ -246,7 +200,7 @@ % \begin{syntax} % "\bool_gset_false:N" <bool> % \end{syntax} -% Set <bool> either true or false. We can also do this globally. +% Set <bool> either <true> or <false>. We can also do this globally. % \end{function} % % @@ -268,120 +222,145 @@ % \end{function} % % \begin{function}{% -% \bool_if:NTF | -% \bool_if:NT | -% \bool_if:NF | -% \bool_if_p:N | +% \bool_if_p:N / (EXP) | +% \bool_if:N / (TF)(EXP) | +% \bool_if_p:c / (EXP) | +% \bool_if:c / (TF)(EXP) | % % } % \begin{syntax} -% "\bool_if:NTF" <bool> "{"\m{true}"}" "{"\m{false}"}" \\ +% "\bool_if:NTF" <bool> \Arg{true} \Arg{false} \\ % "\bool_if_p:N" <bool> % \end{syntax} -% Test the truth value of the boolean and execute the \m{true} or +% Test the truth value of <bool> and execute the \m{true} or % \m{false} code. "\bool_if_p:N" is a predicate function for use in -% "\if:w" tests. +% "\if_predicate:w" tests or "\bool_if:nTF"-type functions described below. % \end{function} % % \begin{function}{% -% \bool_whiledo:NT | -% \bool_whiledo:NF | -% \bool_dowhile:NT | -% \bool_dowhile:NF | +% \bool_while_do:Nn | +% \bool_while_do:cn | +% \bool_until_do:Nn | +% \bool_until_do:cn | +% \bool_do_while:Nn | +% \bool_do_while:cn | +% \bool_do_until:Nn | +% \bool_do_until:cn | % % } % \begin{syntax} -% "\bool_whiledo:NT" <bool> "{"\m{true}"}" \\ -% "\bool_whiledo:NF" <bool> "{"\m{false}"}" \\ +% "\bool_while_do:Nn" <bool> \Arg{code} \\ +% "\bool_until_do:Nn" <bool> \Arg{code} \\ % \end{syntax} -% The "T" versions execute the \m{true} code as long as the boolean is -% true and the "F" versions execute the \m{false} code as long as the -% boolean is false. The "whiledo" functions execute the body after -% testing the boolean and the "dowhile" functions executes the body +% The `while' versions execute <code> as long as the boolean is +% true and the `until' versions execute <code> as long as the +% boolean is false. The "while_do" functions execute the body after +% testing the boolean and the "do_while" functions executes the body % first and then tests the boolean. % \end{function} % % -% \begin{function}{% -% \l_tmpa_bool | -% \g_tmpa_bool | -% -% } -% \begin{syntax} -% \end{syntax} -% Reserved booleans. -% \end{function} % -% \subsubsection{Logical operations} +% \section{Boolean expressions} % -% Somewhat related to the subject of conditional flow processing is -% logical operators as these deal with \m{true} and \m{false} -% statements which is precisely what the predicate functions return. +% As we have a boolean datatype and predicate functions returning +% boolean \meta{true} or \meta{false} values, it seems only fitting +% that we also provide a parser for \meta{boolean expressions}. % +% A boolean expression is an expression which given input in the form +% of predicate functions and boolean variables, return boolean +% \meta{true} or \meta{false}. It supports the logical operations And, +% Or and Not as the well-known infix operators "&&", "||" and "!". In +% addition to this, parentheses can be used to isolate +% sub-expressions. For example, +% \begin{verbatim} +% \intexpr_compare_p:n {1=1} && +% ( +% \intexpr_compare_p:n {2=3} || +% \intexpr_compare_p:n {4=4} || +% \intexpr_compare_p:n {1=\error} % is skipped +% ) && +% !(\intexpr_compare_p:n {2=4}) +% \end{verbatim} +% is a valid boolean expression. Note that minimal evaluation is +% carried out whenever possible so that whenever a truth value cannot +% be changed anymore, the remainding tests within the current group +% are skipped. % % \begin{function}{% -% \predicate_p:n | -% \predicate:nTF | -% \predicate:nT | -% \predicate:nF | +% \bool_if_p:n / (EXP) | +% \bool_if:n / (TF)(EXP) | % } % \begin{syntax} -% "\predicate:nTF" "{"<list of predicates>"}" "{"<true>"}" -% "{"<false>"}" +% "\bool_if:nTF" \Arg{boolean expression} \Arg{true} +% \Arg{false} % \end{syntax} -% The functions evaluate the truth value of \m{list of predicates} +% The functions evaluate the truth value of \m{boolean expression} % where each predicate is separated by \verb+&&+ or \verb+||+ -% denoting logical And and Or functions. Minimal evaluation is -% carried out so that whenever a truth value cannot be changed -% anymore, the remainding tests are not carried out. Hence +% denoting logical `And' and `Or' functions. "(" and ")" denote +% grouping of sub-expressions while "!" is used to as a prefix to +% either negate a single expression or a group. Hence % \begin{verbatim} -% \predicate_p:n{ -% \int_compare_p:nNn 1=1 && -% \predicate_p:n { -% \int_compare_p:nNn 2=3 || -% \int_compare_p:nNn 4=4 || -% \int_compare_p:nNn 1=\error % is skipped -% } && -% \int_compare_p:nNn 2=2 +% \bool_if_p:n{ +% \intexpr_compare_p:n {1=1} && +% ( +% \intexpr_compare_p:n {2=3} || +% \intexpr_compare_p:n {4=4} || +% \intexpr_compare_p:n {1=\error} % is skipped +% ) && +% !(\intexpr_compare_p:n {2=4}) % } % \end{verbatim} -% returns \meta{true}. +% from above returns \meta{true}. +% +% Logical operators take higher precedence the later in the predicate they +% appear. ``<x> "||" <y> "&&" <z>'' is interpreted as the equivalent of +% ``<x> \textsc{or} [~<y> \textsc{and} <z>~]'' (but now we have grouping +% you shouldn't write this sort of thing, anyway). % \end{function} % % % +% \begin{function}{ \bool_not_p:n / (EXP) } +% \begin{syntax} +% "\bool_not_p:n" \Arg{boolean expression} +% \end{syntax} +% Longhand for writing "!("\meta{boolean expression}")" within a boolean +% expression. Might not stick around. +% \end{function} % -% \begin{function}{% -% \predicate_not_p:n | -% } +% \begin{function}{ \bool_xor_p:nn / (EXP) } % \begin{syntax} -% "\predicate_not_p:n" "{"<list of predicates>"}" +% "\bool_xor_p:nn" \Arg{boolean expression} \Arg{boolean expression} % \end{syntax} -% "\predicate_not_p:n" -% reverses the truth value of its argument. Thus -% \begin{quote} -% "\prg_if_predicate_not_p:n {\prg_if_predicate_not_p:n {\c_true}}" -% \end{quote} -% ultimately returns \m{true}. +% Implements an `exclusive or' operation between two boolean +% expressions. There is no infix operation for this. % \end{function} % -% \subsubsection{Case switches} +% \begin{function}{\bool_set:Nn |\bool_set:cn |\bool_gset:Nn |\bool_gset:cn} +% \begin{syntax} +% "\bool_set:Nn" <bool> \Arg{boolean expression} +% \end{syntax} +% Sets <bool> to the logical outcome of evaluating <boolean expression>. +% \end{function} % % -% \begin{function}{ -% \prg_case_int:nnn | +% \section{Case switches} % -% } +% +% \begin{function}{ \prg_case_int:nnn / (EXP) } % \begin{syntax} -% "\prg_case_int:nnn" "{"<integer expr>"}" "{" -% " {"\m{integer expr$\sb 1$}"}""{"\m{code$\sb 1$}"}""{"\m{integer expr$\sb 2$}"}""{"\m{code$\sb 2$}"}"\\ -% " ...""{"\m{integer expr$\sb n$}"}""{"\m{code$\sb n$}"}"\\ -% "}" "{"\m{else case}"}" +% "\prg_case_int:nnn" \Arg{integer expr} "{" +% ~~\Arg{integer expr 1} \Arg{code 1}\\ +% ~~\Arg{integer expr 2} \Arg{code 2}\\ +% ~~\dots\\ +% ~~\Arg{integer expr\,$\sb n$} \Arg{code\,$\sb n$}\\ +% "}" \Arg{else case} % \end{syntax} % This function evaluates the first \meta{integer expr} and then compares it % to the values found in the list. Thus the expression % \begin{verbatim} -% \prg_case:nnn{2*5}{ +% \prg_case_int:nnn{2*5}{ % {5}{Small} {4+6}{Medium} {-2*10}{Negative} % }{Other} % \end{verbatim} @@ -396,29 +375,27 @@ % from within the function are left over. % \end{function} % -% \begin{function}{ -% \prg_case_dim:nnn | -% -% } +% \begin{function}{ \prg_case_dim:nnn / (EXP) } % \begin{syntax} -% "\prg_case_int:nnn" "{"<dim expr>"}" "{" -% " {"\m{dim expr$\sb 1$}"}""{"\m{code$\sb 1$}"}""{"\m{dim expr$\sb 2$}"}""{"\m{code$\sb 2$}"}"\\ -% " ...""{"\m{dim expr$\sb n$}"}""{"\m{code$\sb n$}"}"\\ -% "}" "{"\m{else case}"}" +% "\prg_case_int:nnn" \Arg{dim expr} "{"\\ +% ~~\Arg{dim expr 1} \Arg{code 1}\\ +% ~~\Arg{dim expr 2} \Arg{code 2}\\ +% ~~"..."\\ +% ~~\Arg{dim expr\,$\sb n$} \Arg{code\,$\sb n$}\\ +% "}" \Arg{else case} % \end{syntax} % This function works just like |\prg_case_int:nnn| except it works % for \meta{dim} registers. % \end{function} % -% \begin{function}{ -% \prg_case_str:nnn | -% -% } +% \begin{function}{ \prg_case_str:nnn / (EXP) } % \begin{syntax} -% "\prg_case_str:nnn" "{"<string>"}" "{" -% " {"\m{string$\sb 1$}"}""{"\m{code$\sb 1$}"}""{"\m{string$\sb 2$}"}""{"\m{code$\sb 2$}"}"\\ -% " ...""{"\m{string$\sb n$}"}""{"\m{code$\sb n$}"}"\\ -% "}" "{"\m{else case}"}" +% "\prg_case_str:nnn" \Arg{string} "{" \\ +% ~~\Arg{string 1} \Arg{code 1}\\ +% ~~\Arg{string 2} \Arg{code 2}\\ +% ~~"..."\\ +% ~~\Arg{string\,$\sb n$} \Arg{code,$\sb n$}\\ +% "}" \Arg{else case} % \end{syntax} % This function works just like |\prg_case_int:nnn| except it % compares strings. Each string is evaluated fully using \texttt{x} @@ -429,45 +406,169 @@ % \texttt{f} style expansion can take place cleanly, i.e., no tokens % from within the function are left over. % \end{function} -% -% \subsubsection{Generic loops} % +% \begin{function}{ \prg_case_tl:Nnn / (EXP) } +% \begin{syntax} +% "\prg_case_tl:Nnn" <tl var.> "{" +% ~~<tl var.\ 1> \Arg{code 1} <tl var.\ 2> \Arg{code 2} "..." <tl var.\,$\sb n$> \Arg{code\,$\sb n$}\\ +% "}" \Arg{else case} +% \end{syntax} +% This function works just like |\prg_case_int:nnn| except it +% compares token list variables. % -% \begin{function}{ -% \prg_whiledo:nT | -% \prg_whiledo:nF | -% \prg_dowhile:nT | -% \prg_dowhile:nF | +% The function is expandable\footnote{Provided you use pdfTeX v1.30 or +% later} and is written in such a way that +% \texttt{f} style expansion can take place cleanly, i.e., no tokens +% from within the function are left over. +% \end{function} +% +% \section{Generic loops} % -% } +% +% \begin{function}{ \bool_while_do:nn | +% \bool_until_do:nn | +% \bool_do_while:nn | +% \bool_do_until:nn } % \begin{syntax} -% "\prg_whiledo:nT" "{"<test>"}" "{"\m{true}"}" \\ -% "\prg_whiledo:nF" "{"<test>"}" "{"\m{false}"}" +% "\bool_while_do:nn" \Arg{boolean expression} \Arg{code} \\ +% "\bool_until_do:nn" \Arg{boolean expression} \Arg{code} % \end{syntax} -% The "T" versions execute the \m{true} code as long as <test> is -% true and the "F" versions execute the \m{false} code as long as -% <test> is false. The "whiledo" functions execute the body after -% testing the boolean and the "dowhile" functions executes the body -% first and then tests the boolean. For the "T" versions, <test> -% should end with a function executing only the \meta{true} code for -% some test such as |\tlp_if_eq:NNT|. Similarly the "F" types should -% end with |\tlp_if_eq:NNF|. +% The `while' versions execute the code as long as <boolean +% expression> is true and the `until' versions execute <code> as long +% as <boolean expression> is false. The "while_do" functions execute +% the body after testing the boolean and the "do_while" functions +% executes the body first and then tests the boolean. % \end{function} % -% \subsection{Sorting} +% \section{Choosing modes} +% +% \begin{function}{ \mode_if_vertical_p: / (EXP)| +% \mode_if_vertical: / (TF)(EXP) } +% \begin{syntax} +% "\mode_if_vertical:TF" \Arg{true code} \Arg{false code} +% \end{syntax} +% Determines if \TeX{} is in vertical mode or not and executes either +% <true code> or <false code> accordingly. +% \end{function} +% +% \begin{function}{ \mode_if_horizontal_p: / (EXP)| +% \mode_if_horizontal: / (TF)(EXP) } +% \begin{syntax} +% "\mode_if_horizontal:TF" \Arg{true code} \Arg{false code} +% \end{syntax} +% Determines if \TeX{} is in horizontal mode or not and executes either +% <true code> or <false code> accordingly. +% \end{function} +% +% +% \begin{function}{ +% \mode_if_inner_p: / (EXP)| +% \mode_if_inner: / (TF)(EXP) } +% \begin{syntax} +% "\mode_if_inner:TF" \Arg{true code} \Arg{false code} +% \end{syntax} +% Determines if \TeX{} is in inner mode or not and executes either +% <true code> or <false code> accordingly. +% \end{function} +% +% \begin{function}{ +% \mode_if_math_p: /(EXP) | +% \mode_if_math: / (TF)(EXP) } +% \begin{syntax} +% "\mode_if_math:TF" \Arg{true code} \Arg{false code} +% \end{syntax} +% Determines if \TeX{} is in math mode or not and executes either +% <true code> or <false code> accordingly. +% \begin{texnote} +% This version will choose the right branch even at the beginning of +% an alignment cell. +% \end{texnote} +% \end{function} +% +% +% \section{Alignment safe grouping and scanning} +% +% \begin{function}{\scan_align_safe_stop:} +% \begin{syntax} +% "\scan_align_safe_stop:" +% \end{syntax} +% This function gets \TeX{} on the right track inside an alignment +% cell but without destroying any kerning. +% \end{function} +% +% +% \begin{function}{\group_align_safe_begin:| +% \group_align_safe_end:} +% \begin{syntax} +% "\group_align_safe_begin:" <...> "\group_align_safe_end:" +% \end{syntax} +% Encloses <...> inside a group but is safe inside an alignment cell. +% See the implementation of |\peek_token_generic:NNTF| for an +% application. +% \end{function} +% +% +% \section{Producing $n$ copies} +% +% There are often several different requirements for producing +% multiple copies of something. Sometimes one might want to produce a +% number of identical copies of a sequence of tokens whereas at other +% times the goal is to simulate a for loop as known from most real +% programming languages. +% +% \begin{function}{\prg_replicate:nn / (EXP) } +% \begin{syntax} +% "\prg_replicate:nn" \Arg{number} \Arg{arg} +% \end{syntax} +% Creates <number> copies of <arg>. Note that it is expandable. +% \end{function} +% +% +% \begin{function}{\prg_stepwise_function:nnnN / (EXP) } +% \begin{syntax} +% "\prg_stepwise_function:nnnN" \Arg{start} \Arg{step} +% \Arg{end} <function> +% \end{syntax} +% This function performs <action> once for each step starting at +% <start> and ending once <end> is passed. <function> is placed +% directly in front of a brace group holding the current number so it +% should usually be a function taking one argument. +% \end{function} +% +% \begin{function}{\prg_stepwise_inline:nnnn} +% \begin{syntax} +% "\prg_stepwise_inline:nnnn" \Arg{start} \Arg{step} \Arg{end} +% \Arg{action} +% \end{syntax} +% Same as |\prg_stepwise_function:nnnN| except here <action> is +% performed each time with |##1| as a placeholder for the number +% currently being tested. This function is not expandable and it is +% nestable. +% \end{function} +% +% \begin{function}{\prg_stepwise_variable:nnnNn} +% \begin{syntax} +% "\prg_stepwise_variable:nnnn" \Arg{start} \Arg{step} \Arg{end} +% <temp-var> \Arg{action} +% \end{syntax} +% Same as |\prg_stepwise_inline:nnnn| except here the current value is +% stored in <temp-var> and the programmer can use it in <action>. This +% function is not expandable. +% \end{function} +% +% \section{Sorting} % % % \begin{function}{ % \prg_quicksort:n | % } % \begin{syntax} -% "\prg_quicksort:n" "{" "{"<element~1>"}" "{"<element~2>"}" -% \dots\space "{"<element~n>"}" "}" +% "\prg_quicksort:n" "{" \Arg{item~1} \Arg{item~2} \dots \Arg{item~n} "}" % \end{syntax} % Performs a Quicksort on the token list. The comparisons are % performed by the function |\prg_quicksort_compare:nnTF| which is up % to the programmer to define. When the sorting process is over, all -% elements are given as argument to the function +% items are given as argument to the function % |\prg_quicksort_function:n| which the programmer also controls. % \end{function} % @@ -476,14 +577,14 @@ % \prg_quicksort_compare:nnTF % } % \begin{syntax} -% "\prg_quicksort_function:n" "{"<element>"}" \\ -% "\prg_quicksort_compare:nnTF" "{"<element 1>"}" "{"<element 2>"}"\\ +% "\prg_quicksort_function:n" \Arg{element} \\ +% "\prg_quicksort_compare:nnTF" \Arg{element 1} \Arg{element 2}\\ % \end{syntax} % The two functions the programmer must define before calling % |\prg_quicksort:n|. As an example we could define % \begin{quote} -% |\def:NNn\prg_quicksort_function:n 1{{#1}}|\\ -% |\def:NNn\prg_quicksort_compare:nnTF 2{\num_compare:nNnTF{#1}>{#2}}| +% |\cs_set_nopar:Nn\prg_quicksort_function:n {{#1}}|\\ +% |\cs_set_nopar:Nn\prg_quicksort_compare:nnTF {\intexpr_compare:nNnTF{#1}>{#2}}| % \end{quote} % Then the function call % \begin{quote} @@ -493,89 +594,94 @@ % where one sorts a list of words, |\prg_quicksort_compare:nnTF| could % be defined as % \begin{quote} -% |\def:NNn\prg_quicksort_compare:nnTF 2{|\\ -% | \num_compare:nNnTF{\tlist_compare:nn{#1}{#2}}>\c_zero }| +% |\cs_set_nopar:Nn\prg_quicksort_compare:nnTF {|\\ +% | \intexpr_compare:nNnTF{\tl_compare:nn{#1}{#2}}>\c_zero }| % \end{quote} % % \end{function} % +% \end{documentation} +% +% \begin{implementation} +% +% \section{\pkg{l3prg} implementation} +% +% \subsection{Variables} % -% \StopEventually{} +% \begin{function}{ \l_tmpa_bool | \g_tmpa_bool } +% Reserved booleans. +% \end{function} % -% \subsection{The Implementation} +% \begin{variable}{\g_prg_inline_level_int} +% Global variable to track the nesting of the stepwise inline loop. +% \end{variable} % +% \subsection{Module code} % % We start by ensuring that the required packages are loaded. % \begin{macrocode} %<*package> \ProvidesExplPackage {\filename}{\filedate}{\fileversion}{\filedescription} -\RequirePackage{l3quark} -\RequirePackage{l3toks} -\RequirePackage{l3int} +\package_check_loaded_expl: %</package> %<*initex|package> % \end{macrocode} % -% -% \subsubsection{Choosing modes} +% \subsection{Choosing modes} % % \begin{macro}{\mode_if_vertical_p:} -% \begin{macro}{\mode_if_vertical:TF} -% \begin{macro}{\mode_if_vertical:T} -% \begin{macro}{\mode_if_vertical:F} -% For testing vertical mode. +% \begin{macro}[TF]{\mode_if_vertical:} +% For testing vertical mode. Strikes me here on the bus with David, +% that as long as we are just talking about returning true and +% false states, we can just use the primitive conditionals for this +% and gobbling the |\c_zero| in the input stream. However this +% requires knowledge of the implementation so we keep things nice +% and clean and use the return statements. % \begin{macrocode} -\def_new:Npn \mode_if_vertical_p: { - \if_mode_vertical: \c_true \else: \c_false\fi:} -\def_test_function_new:npn{mode_if_vertical:}{\if_mode_vertical:} +\prg_set_conditional:Npnn \mode_if_vertical: {p,TF,T,F}{ + \if_mode_vertical: + \prg_return_true: \else: \prg_return_false: \fi: +} % \end{macrocode} % \end{macro} % \end{macro} -% \end{macro} -% \end{macro} % % \begin{macro}{\mode_if_horizontal_p:} -% \begin{macro}{\mode_if_horizontal:TF} -% \begin{macro}{\mode_if_horizontal:T} -% \begin{macro}{\mode_if_horizontal:F} +% \begin{macro}[TF]{\mode_if_horizontal:} % For testing horizontal mode. % \begin{macrocode} -\def_new:Npn \mode_if_horizontal_p: { - \if_mode_horizontal: \c_true \else: \c_false\fi:} -\def_test_function_new:npn{mode_if_horizontal:}{\if_mode_horizontal:} +\prg_set_conditional:Npnn \mode_if_horizontal: {p,TF,T,F}{ + \if_mode_horizontal: + \prg_return_true: \else: \prg_return_false: \fi: +} % \end{macrocode} % \end{macro} % \end{macro} -% \end{macro} -% \end{macro} % % \begin{macro}{\mode_if_inner_p:} -% \begin{macro}{\mode_if_inner:TF} -% \begin{macro}{\mode_if_inner:T} -% \begin{macro}{\mode_if_inner:F} +% \begin{macro}[TF]{\mode_if_inner:} % For testing inner mode. % \begin{macrocode} -\def_new:Npn \mode_if_inner_p: { - \if_mode_inner: \c_true \else: \c_false\fi:} -\def_test_function_new:npn{mode_if_inner:}{\if_mode_inner:} +\prg_set_conditional:Npnn \mode_if_inner: {p,TF,T,F}{ + \if_mode_inner: + \prg_return_true: \else: \prg_return_false: \fi: +} % \end{macrocode} % \end{macro} % \end{macro} -% \end{macro} -% \end{macro} % -% \begin{macro}{\mode_if_math:TF} -% \begin{macro}{\mode_if_math:T} -% \begin{macro}{\mode_if_math:F} +% \begin{macro}{\mode_if_math_p:} +% \begin{macro}[TF]{\mode_if_math:} % For testing math mode. Uses the kern-save |\scan_align_safe_stop:|. % \begin{macrocode} -\def_test_function_new:npn{mode_if_math:} { - \scan_align_safe_stop: \if_mode_math: } +\prg_set_conditional:Npnn \mode_if_math: {p,TF,T,F}{ + \scan_align_safe_stop: \if_mode_math: + \prg_return_true: \else: \prg_return_false: \fi: +} % \end{macrocode} % \end{macro} % \end{macro} -% \end{macro} % % \paragraph{Alignment safe grouping and scanning} % @@ -583,7 +689,7 @@ % \begin{macro}{\group_align_safe_begin:} % \begin{macro}{\group_align_safe_end:} % \TeX's alignment structures present many problems. As Knuth says -% himself in \emph{\TeX: The Program}: ``It's sort of a miracle +% himself in \emph{\TeX : The Program}: ``It's sort of a miracle % whenever |\halign| or |\valign| work, [\ldots]'' One problem relates % to commands that internally issues a |\cr| but also peek ahead for % the next character for use in, say, an optional argument. If the @@ -599,9 +705,9 @@ % by using code documented only in Appendix~D of % \emph{The \TeX book}\dots % \begin{macrocode} -\def_new:Npn \group_align_safe_begin: { +\cs_new_nopar:Npn \group_align_safe_begin: { \if_false:{\fi:\if_num:w`}=\c_zero\fi:} -\def_new:Npn \group_align_safe_end: {\if_num:w`{=\c_zero}\fi:} +\cs_new_nopar:Npn \group_align_safe_end: {\if_num:w`{=\c_zero}\fi:} % \end{macrocode} % \end{macro} % \end{macro} @@ -625,12 +731,12 @@ % outer part of an alignment cell and b)~the last node \emph{wasn't} a % char node or a ligature node. % \begin{macrocode} -\def_new:Npn \scan_align_safe_stop: { - \num_compare:nNnT \etex_currentgrouptype:D = \c_six +\cs_new_nopar:Npn \scan_align_safe_stop: { + \intexpr_compare:nNnT \etex_currentgrouptype:D = \c_six { - \num_compare:nNnF \etex_lastnodetype:D = \c_zero + \intexpr_compare:nNnF \etex_lastnodetype:D = \c_zero { - \num_compare:nNnF \etex_lastnodetype:D = \c_seven + \intexpr_compare:nNnF \etex_lastnodetype:D = \c_seven \scan_stop: } } @@ -638,11 +744,10 @@ % \end{macrocode} % \end{macro} % -% \subsubsection{Making $n$ copies} +% \subsection{Producing $n$ copies} % % \begin{macro}{\prg_replicate:nn} -% \begin{macro}{\prg_replicate_aux:N} -% \begin{macro}{\prg_replicate_first_aux:N} +% \begin{macro}[aux]{\prg_replicate_aux:N,\prg_replicate_first_aux:N} % This function uses a cascading csname technique by David Kastrup % (who else :-) % @@ -660,7 +765,7 @@ % argument just to gobble them again we define separate functions to % be inserted first. Finally we must ensure that the cascade comes to % a peaceful end so we make it so that the original csname \TeX{} is -% creating is simply "\use_noop:" expanding to nothing. +% creating is simply "\prg_do_nothing:" expanding to nothing. % % This function has one flaw though: Since it constantly passes down % ten copies of its previous argument it will severely affect the main @@ -672,104 +777,102 @@ % pool. Also, it is considerably slower than what we use here so the % few extra csnames are well spent I would say. % \begin{macrocode} -\def_new:Npn \prg_replicate:nn #1{ - \cs:w use_noop: - \exp_after:NN\prg_replicate_first_aux:N - \int_use:N \int_eval:n{#1} \cs_end: +\cs_new_nopar:Npn \prg_replicate:nn #1{ + \cs:w prg_do_nothing: + \exp_after:wN\prg_replicate_first_aux:N + \tex_romannumeral:D -`\q \intexpr_eval:n{#1} \cs_end: \cs_end: } -\def_new:Npn \prg_replicate_aux:N#1{ +\cs_new_nopar:Npn \prg_replicate_aux:N#1{ \cs:w prg_replicate_#1:n\prg_replicate_aux:N } -\def_new:Npn \prg_replicate_first_aux:N#1{ +\cs_new_nopar:Npn \prg_replicate_first_aux:N#1{ \cs:w prg_replicate_first_#1:n\prg_replicate_aux:N } % \end{macrocode} % \end{macro} % \end{macro} -% \end{macro} % Then comes all the functions that do the hard work of inserting all % the copies. % \begin{macrocode} -\def_new:Npn \prg_replicate_ :n #1{}% no, this is not a typo! -\def_long_new:cpn {prg_replicate_0:n}#1{\cs_end:{#1#1#1#1#1#1#1#1#1#1}} -\def_long_new:cpn {prg_replicate_1:n}#1{\cs_end:{#1#1#1#1#1#1#1#1#1#1}#1} -\def_long_new:cpn {prg_replicate_2:n}#1{\cs_end:{#1#1#1#1#1#1#1#1#1#1}#1#1} -\def_long_new:cpn {prg_replicate_3:n}#1{ +\cs_new_nopar:Npn \prg_replicate_ :n #1{}% no, this is not a typo! +\cs_new:cpn {prg_replicate_0:n}#1{\cs_end:{#1#1#1#1#1#1#1#1#1#1}} +\cs_new:cpn {prg_replicate_1:n}#1{\cs_end:{#1#1#1#1#1#1#1#1#1#1}#1} +\cs_new:cpn {prg_replicate_2:n}#1{\cs_end:{#1#1#1#1#1#1#1#1#1#1}#1#1} +\cs_new:cpn {prg_replicate_3:n}#1{ \cs_end:{#1#1#1#1#1#1#1#1#1#1}#1#1#1} -\def_long_new:cpn {prg_replicate_4:n}#1{ +\cs_new:cpn {prg_replicate_4:n}#1{ \cs_end:{#1#1#1#1#1#1#1#1#1#1}#1#1#1#1} -\def_long_new:cpn {prg_replicate_5:n}#1{ +\cs_new:cpn {prg_replicate_5:n}#1{ \cs_end:{#1#1#1#1#1#1#1#1#1#1}#1#1#1#1#1} -\def_long_new:cpn {prg_replicate_6:n}#1{ +\cs_new:cpn {prg_replicate_6:n}#1{ \cs_end:{#1#1#1#1#1#1#1#1#1#1}#1#1#1#1#1#1} -\def_long_new:cpn {prg_replicate_7:n}#1{ +\cs_new:cpn {prg_replicate_7:n}#1{ \cs_end:{#1#1#1#1#1#1#1#1#1#1}#1#1#1#1#1#1#1} -\def_long_new:cpn {prg_replicate_8:n}#1{ +\cs_new:cpn {prg_replicate_8:n}#1{ \cs_end:{#1#1#1#1#1#1#1#1#1#1}#1#1#1#1#1#1#1#1} -\def_long_new:cpn {prg_replicate_9:n}#1{ +\cs_new:cpn {prg_replicate_9:n}#1{ \cs_end:{#1#1#1#1#1#1#1#1#1#1}#1#1#1#1#1#1#1#1#1} % \end{macrocode} % Users shouldn't ask for something to be replicated once or even % not at all but\dots % \begin{macrocode} -\def_long_new:cpn {prg_replicate_first_0:n}#1{\cs_end: } -\def_long_new:cpn {prg_replicate_first_1:n}#1{\cs_end: #1} -\def_long_new:cpn {prg_replicate_first_2:n}#1{\cs_end: #1#1} -\def_long_new:cpn {prg_replicate_first_3:n}#1{\cs_end: #1#1#1} -\def_long_new:cpn {prg_replicate_first_4:n}#1{\cs_end: #1#1#1#1} -\def_long_new:cpn {prg_replicate_first_5:n}#1{\cs_end: #1#1#1#1#1} -\def_long_new:cpn {prg_replicate_first_6:n}#1{\cs_end: #1#1#1#1#1#1} -\def_long_new:cpn {prg_replicate_first_7:n}#1{\cs_end: #1#1#1#1#1#1#1} -\def_long_new:cpn {prg_replicate_first_8:n}#1{\cs_end: #1#1#1#1#1#1#1#1} -\def_long_new:cpn {prg_replicate_first_9:n}#1{\cs_end: #1#1#1#1#1#1#1#1#1} +\cs_new:cpn {prg_replicate_first_0:n}#1{\cs_end: } +\cs_new:cpn {prg_replicate_first_1:n}#1{\cs_end: #1} +\cs_new:cpn {prg_replicate_first_2:n}#1{\cs_end: #1#1} +\cs_new:cpn {prg_replicate_first_3:n}#1{\cs_end: #1#1#1} +\cs_new:cpn {prg_replicate_first_4:n}#1{\cs_end: #1#1#1#1} +\cs_new:cpn {prg_replicate_first_5:n}#1{\cs_end: #1#1#1#1#1} +\cs_new:cpn {prg_replicate_first_6:n}#1{\cs_end: #1#1#1#1#1#1} +\cs_new:cpn {prg_replicate_first_7:n}#1{\cs_end: #1#1#1#1#1#1#1} +\cs_new:cpn {prg_replicate_first_8:n}#1{\cs_end: #1#1#1#1#1#1#1#1} +\cs_new:cpn {prg_replicate_first_9:n}#1{\cs_end: #1#1#1#1#1#1#1#1#1} % \end{macrocode} % % % % % \begin{macro}{\prg_stepwise_function:nnnN} -% \begin{macro}{\prg_stepwise_function_incr:nnnN} -% \begin{macro}{\prg_stepwise_function_decr:nnnN} +% \begin{macro}[aux]{\prg_stepwise_function_incr:nnnN, +% \prg_stepwise_function_decr:nnnN} % A stepwise function. Firstly we check the direction of the steps % |#2| since that will depend on which test we should use. If the % step is positive we use a greater than test, otherwise a less than % test. If the test comes out true exit, otherwise perform |#4|, % add the step to |#1| and try again with this new value of |#1|. % \begin{macrocode} -\def_long_new:NNn \prg_stepwise_function:nnnN 2{ - \num_compare:nNnTF{#2}<\c_zero - {\exp_args:No\prg_stepwise_function_decr:nnnN } - {\exp_args:No\prg_stepwise_function_incr:nnnN } - {\int_use:N\int_eval:n{#1}}{#2} +\cs_new:Npn \prg_stepwise_function:nnnN #1#2{ + \intexpr_compare:nNnTF{#2}<\c_zero + {\exp_args:Nf\prg_stepwise_function_decr:nnnN } + {\exp_args:Nf\prg_stepwise_function_incr:nnnN } + {\intexpr_eval:n{#1}}{#2} } -\def_long_new:NNn \prg_stepwise_function_incr:nnnN 4{ - \num_compare:nNnF {#1}>{#3} +\cs_new:Npn \prg_stepwise_function_incr:nnnN #1#2#3#4{ + \intexpr_compare:nNnF {#1}>{#3} { #4{#1} - \exp_args:No \prg_stepwise_function_incr:nnnN - {\int_use:N\int_eval:n{#1 + #2}} + \exp_args:Nf \prg_stepwise_function_incr:nnnN + {\intexpr_eval:n{#1 + #2}} {#2}{#3}{#4} } } -\def_long_new:NNn \prg_stepwise_function_decr:nnnN 4{ - \num_compare:nNnF {#1}<{#3} +\cs_new:Npn \prg_stepwise_function_decr:nnnN #1#2#3#4{ + \intexpr_compare:nNnF {#1}<{#3} { #4{#1} - \exp_args:No \prg_stepwise_function_decr:nnnN - {\int_use:N\int_eval:n{#1 + #2}} + \exp_args:Nf \prg_stepwise_function_decr:nnnN + {\intexpr_eval:n{#1 + #2}} {#2}{#3}{#4} } } % \end{macrocode} % \end{macro} % \end{macro} -% \end{macro} % % \begin{macro}{\g_prg_inline_level_int} % \begin{macro}{\prg_stepwise_inline:nnnn} -% \begin{macro}{\prg_stepwise_inline_decr:nnnn} -% \begin{macro}{\prg_stepwise_inline_incr:nnnn} +% \begin{macro}[aux]{\prg_stepwise_inline_decr:nnnn, +% \prg_stepwise_inline_incr:nnnn} % This function uses the same approach as for instance % |\clist_map_inline:Nn| to allow arbitrary nesting. First construct % the special function and then call an auxiliary one which just @@ -777,76 +880,74 @@ % when we maintain our own stack. % \begin{macrocode} \int_new:N\g_prg_inline_level_int -\def_long_new:NNn\prg_stepwise_inline:nnnn 4{ +\cs_new:Npn\prg_stepwise_inline:nnnn #1#2#3#4{ \int_gincr:N \g_prg_inline_level_int - \gdef:cpn{prg_stepwise_inline_\int_use:N\g_prg_inline_level_int :n}##1{#4} - \num_compare:nNnTF {#2}<\c_zero - {\exp_args:Nco \prg_stepwise_inline_decr:Nnnn } - {\exp_args:Nco \prg_stepwise_inline_incr:Nnnn } + \cs_gset_nopar:cpn{prg_stepwise_inline_\int_use:N\g_prg_inline_level_int :n}##1{#4} + \intexpr_compare:nNnTF {#2}<\c_zero + {\exp_args:Ncf \prg_stepwise_inline_decr:Nnnn } + {\exp_args:Ncf \prg_stepwise_inline_incr:Nnnn } {prg_stepwise_inline_\int_use:N\g_prg_inline_level_int :n} - {\int_use:N\int_eval:n{#1}} {#2} {#3} + {\intexpr_eval:n{#1}} {#2} {#3} \int_gdecr:N \g_prg_inline_level_int } -\def_long_new:NNn \prg_stepwise_inline_incr:Nnnn 4{ - \num_compare:nNnF {#2}>{#4} +\cs_new:Npn \prg_stepwise_inline_incr:Nnnn #1#2#3#4{ + \intexpr_compare:nNnF {#2}>{#4} { #1{#2} - \exp_args:NNo \prg_stepwise_inline_incr:Nnnn #1 - {\int_use:N\int_eval:n{#2 + #3}} {#3}{#4} + \exp_args:NNf \prg_stepwise_inline_incr:Nnnn #1 + {\intexpr_eval:n{#2 + #3}} {#3}{#4} } } -\def_long_new:NNn \prg_stepwise_inline_decr:Nnnn 4{ - \num_compare:nNnF {#2}<{#4} +\cs_new:Npn \prg_stepwise_inline_decr:Nnnn #1#2#3#4{ + \intexpr_compare:nNnF {#2}<{#4} { #1{#2} - \exp_args:NNo \prg_stepwise_inline_decr:Nnnn #1 - {\int_use:N\int_eval:n{#2 + #3}} {#3}{#4} + \exp_args:NNf \prg_stepwise_inline_decr:Nnnn #1 + {\intexpr_eval:n{#2 + #3}} {#3}{#4} } } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} -% \end{macro} % % \begin{macro}{\prg_stepwise_variable:nnnNn} -% \begin{macro}{\prg_stepwise_variable_decr:nnnNn} -% \begin{macro}{\prg_stepwise_variable_incr:nnnNn} +% \begin{macro}[aux]{\prg_stepwise_variable_decr:nnnNn, +% \prg_stepwise_variable_incr:nnnNn} % Almost the same as above. Just store the value in |#4| and execute % |#5|. % \begin{macrocode} -\def_long_new:NNn \prg_stepwise_variable:nnnNn 2 { - \num_compare:nNnTF {#2}<\c_zero - {\exp_args:No\prg_stepwise_variable_decr:nnnNn} - {\exp_args:No\prg_stepwise_variable_incr:nnnNn} - {\int_use:N\int_eval:n{#1}}{#2} +\cs_new:Npn \prg_stepwise_variable:nnnNn #1#2 { + \intexpr_compare:nNnTF {#2}<\c_zero + {\exp_args:Nf\prg_stepwise_variable_decr:nnnNn} + {\exp_args:Nf\prg_stepwise_variable_incr:nnnNn} + {\intexpr_eval:n{#1}}{#2} } -\def_long_new:NNn \prg_stepwise_variable_incr:nnnNn 5 { - \num_compare:nNnF {#1}>{#3} +\cs_new:Npn \prg_stepwise_variable_incr:nnnNn #1#2#3#4#5 { + \intexpr_compare:nNnF {#1}>{#3} { - \def:Npn #4{#1} #5 - \exp_args:No \prg_stepwise_variable_incr:nnnNn - {\int_use:N\int_eval:n{#1 + #2}}{#2}{#3}#4{#5} + \cs_set_nopar:Npn #4{#1} #5 + \exp_args:Nf \prg_stepwise_variable_incr:nnnNn + {\intexpr_eval:n{#1 + #2}}{#2}{#3}#4{#5} } } -\def_long_new:NNn \prg_stepwise_variable_decr:nnnNn 5 { - \num_compare:nNnF {#1}<{#3} +\cs_new:Npn \prg_stepwise_variable_decr:nnnNn #1#2#3#4#5 { + \intexpr_compare:nNnF {#1}<{#3} { - \def:Npn #4{#1} #5 - \exp_args:No \prg_stepwise_variable_decr:nnnNn - {\int_use:N\int_eval:n{#1 + #2}}{#2}{#3}#4{#5} + \cs_set_nopar:Npn #4{#1} #5 + \exp_args:Nf \prg_stepwise_variable_decr:nnnNn + {\intexpr_eval:n{#1 + #2}}{#2}{#3}#4{#5} } } % \end{macrocode} % \end{macro} % \end{macro} -% \end{macro} % % -% \subsubsection{Booleans} -% For normal booleans we set them to either "\c_true" or "\c_false" -% and then use "\if:w" to choose the right branch. The functions -% return either the TF, T, or F case \emph{after} ending the |\if:w|. +% \subsection{Booleans} +% For normal booleans we set them to either "\c_true_bool" or "\c_false_bool" +% and then use "\if_bool:N" to choose the right branch. The functions +% return either the TF, T, or F case \emph{after} ending the |\if_bool:N|. % We only define the |N| versions here as the |c| versions can easily % be constructed with the expansion module. % @@ -862,16 +963,16 @@ % \begin{macro}{\bool_gset_false:c} % Defining and setting a boolean is easy. % \begin{macrocode} -\def_new:Npn \bool_new:N #1 { \let_new:NN #1 \c_false } -\def_new:Npn \bool_new:c #1 { \let_new:cN {#1} \c_false } -\def_new:Npn \bool_set_true:N #1 { \let:NN #1 \c_true } -\def_new:Npn \bool_set_true:c #1 { \let:cN {#1} \c_true } -\def_new:Npn \bool_set_false:N #1 { \let:NN #1 \c_false } -\def_new:Npn \bool_set_false:c #1 { \let:cN {#1} \c_false } -\def_new:Npn \bool_gset_true:N #1 { \glet:NN #1 \c_true } -\def_new:Npn \bool_gset_true:c #1 { \glet:cN {#1} \c_true } -\def_new:Npn \bool_gset_false:N #1 { \glet:NN #1 \c_false } -\def_new:Npn \bool_gset_false:c #1 { \glet:cN {#1} \c_false } +\cs_new_nopar:Npn \bool_new:N #1 { \cs_new_eq:NN #1 \c_false_bool } +\cs_new_nopar:Npn \bool_new:c #1 { \cs_new_eq:cN {#1} \c_false_bool } +\cs_new_nopar:Npn \bool_set_true:N #1 { \cs_set_eq:NN #1 \c_true_bool } +\cs_new_nopar:Npn \bool_set_true:c #1 { \cs_set_eq:cN {#1} \c_true_bool } +\cs_new_nopar:Npn \bool_set_false:N #1 { \cs_set_eq:NN #1 \c_false_bool } +\cs_new_nopar:Npn \bool_set_false:c #1 { \cs_set_eq:cN {#1} \c_false_bool } +\cs_new_nopar:Npn \bool_gset_true:N #1 { \cs_gset_eq:NN #1 \c_true_bool } +\cs_new_nopar:Npn \bool_gset_true:c #1 { \cs_gset_eq:cN {#1} \c_true_bool } +\cs_new_nopar:Npn \bool_gset_false:N #1 { \cs_gset_eq:NN #1 \c_false_bool } +\cs_new_nopar:Npn \bool_gset_false:c #1 { \cs_gset_eq:cN {#1} \c_false_bool } % \end{macrocode} % \end{macro} % \end{macro} @@ -894,14 +995,14 @@ % \begin{macro}{\bool_gset_eq:cc} % Setting a boolean to another is also pretty easy. % \begin{macrocode} -\let_new:NN \bool_set_eq:NN \let:NN -\let_new:NN \bool_set_eq:Nc \let:Nc -\let_new:NN \bool_set_eq:cN \let:cN -\let_new:NN \bool_set_eq:cc \let:cc -\let_new:NN \bool_gset_eq:NN \glet:NN -\let_new:NN \bool_gset_eq:Nc \glet:Nc -\let_new:NN \bool_gset_eq:cN \glet:cN -\let_new:NN \bool_gset_eq:cc \glet:cc +\cs_new_eq:NN \bool_set_eq:NN \cs_set_eq:NN +\cs_new_eq:NN \bool_set_eq:Nc \cs_set_eq:Nc +\cs_new_eq:NN \bool_set_eq:cN \cs_set_eq:cN +\cs_new_eq:NN \bool_set_eq:cc \cs_set_eq:cc +\cs_new_eq:NN \bool_gset_eq:NN \cs_gset_eq:NN +\cs_new_eq:NN \bool_gset_eq:Nc \cs_gset_eq:Nc +\cs_new_eq:NN \bool_gset_eq:cN \cs_gset_eq:cN +\cs_new_eq:NN \bool_gset_eq:cc \cs_gset_eq:cc % \end{macrocode} % \end{macro} % \end{macro} @@ -922,217 +1023,225 @@ % \end{macro} % \end{macro} % -% \begin{macro}{\bool_if:NTF} -% \begin{macro}{\bool_if:NT} -% \begin{macro}{\bool_if:NF} -% \begin{macro}{\bool_if:cTF} -% \begin{macro}{\bool_if:cT} -% \begin{macro}{\bool_if:cF} -% Straight forward here. +% \begin{macro}{\bool_if_p:N,\bool_if_p:c} +% \begin{macro}[TF]{\bool_if:N,\bool_if:c} +% Straight forward here. We could optimize here if we wanted to as +% the boolean can just be input directly. % \begin{macrocode} -\def_test_function_new:npn{bool_if:N}#1{\if:w #1} -\def_new:Npn \bool_if:cTF{\exp_args:Nc\bool_if:NTF} -\def_new:Npn \bool_if:cT{\exp_args:Nc\bool_if:NT} -\def_new:Npn \bool_if:cF{\exp_args:Nc\bool_if:NF} +\prg_set_conditional:Npnn \bool_if:N #1 {p,TF,T,F}{ + \if_bool:N #1 \prg_return_true: \else: \prg_return_false: \fi: +} +\cs_generate_variant:Nn \bool_if_p:N {c} +\cs_generate_variant:Nn \bool_if:NTF {c} +\cs_generate_variant:Nn \bool_if:NT {c} +\cs_generate_variant:Nn \bool_if:NF {c} % \end{macrocode} % \end{macro} % \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} % -% \begin{macro}{\bool_if_p:N} -% \begin{macro}{\bool_if_p:c} -% We also make a predicate function for the "bool" data type but since -% we use "\c_true" and "\c_false" it's rather simple\dots{} -% Not that there's anything wrong in simplicity -- on the contrary! -% \begin{macrocode} -\def_new:Npn \bool_if_p:N #1 { #1 } -\let_new:NN \bool_if_p:c \cs_use:c -% \end{macrocode} -% \end{macro} -% \end{macro} % % -% \begin{macro}{\bool_whiledo:NT} -% \begin{macro}{\bool_whiledo:cT} -% \begin{macro}{\bool_whiledo:NF} -% \begin{macro}{\bool_whiledo:cF} +% \begin{macro}{\bool_while_do:Nn} +% \begin{macro}{\bool_while_do:cn} +% \begin{macro}{\bool_until_do:Nn} +% \begin{macro}{\bool_until_do:cn} % A "while" loop where the boolean is tested before executing the -% statement. The "NT" version executes the "T" part as long as the -% boolean is true while the "NF" version executes the "F" part as +% statement. The `while' version executes the code as long as the +% boolean is true; the `until' version executes the code as % long as the boolean is false. % \begin{macrocode} -\def_long_new:Npn \bool_whiledo:NT #1 #2 { - \bool_if:NT #1 {#2 \bool_whiledo:NT #1 {#2}} +\cs_new:Npn \bool_while_do:Nn #1 #2 { + \bool_if:NT #1 {#2 \bool_while_do:Nn #1 {#2}} } -\def_new:Npn \bool_whiledo:cT{\exp_args:Nc\bool_whiledo:NT} -\def_long_new:Npn \bool_whiledo:NF #1 #2 { - \bool_if:NF #1 {#2 \bool_whiledo:NF #1 {#2}} +\cs_generate_variant:Nn \bool_while_do:Nn {c} +% \end{macrocode} +% +% \begin{macrocode} +\cs_new:Npn \bool_until_do:Nn #1 #2 { + \bool_if:NF #1 {#2 \bool_until_do:Nn #1 {#2}} } -\def_new:Npn \bool_whiledo:cF{\exp_args:Nc\bool_whiledo:NF} +\cs_generate_variant:Nn \bool_until_do:Nn {c} % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % -% \begin{macro}{\bool_dowhile:NT} -% \begin{macro}{\bool_dowhile:cT} -% \begin{macro}{\bool_dowhile:NF} -% \begin{macro}{\bool_dowhile:cF} +% \begin{macro}{\bool_do_while:Nn} +% \begin{macro}{\bool_do_while:cn} +% \begin{macro}{\bool_do_until:Nn} +% \begin{macro}{\bool_do_until:cn} % A "do-while" loop where the body is performed at least once and the % boolean is tested after executing the body. Otherwise identical to % the above functions. % \begin{macrocode} -\def_long_new:Npn \bool_dowhile:NT #1 #2 { - #2 \bool_if:NT #1 {\bool_dowhile:NT #1 {#2}} +\cs_new:Npn \bool_do_while:Nn #1 #2 { + #2 \bool_if:NT #1 {\bool_do_while:Nn #1 {#2}} } -\def_new:Npn \bool_dowhile:cT{\exp_args:Nc\bool_dowhile:NT} -\def_long_new:Npn \bool_dowhile:NF #1 #2 { - #2 \bool_if:NF #1 {\bool_dowhile:NF #1 {#2}} -} -\def_new:Npn \bool_dowhiledo:cF{\exp_args:Nc\bool_dowhile:cF} +\cs_generate_variant:Nn \bool_do_while:Nn {c} % \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\bool_double_if:NNnnnn} -% \begin{macro}{\bool_double_if:cNnnnn} -% \begin{macro}{\bool_double_if:Ncnnnn} -% \begin{macro}{\bool_double_if:ccnnnn} -% Execute |#3| iff TT, |#4| iff TF, |#5| iff FT and |#6| iff -% FF. The name isn't that great but I'll have to think about -% that. Ideally it should be something with |TF| since only one of -% the cases is executed but we haven't got any naming scheme for -% this kind of thing so for now I'll just stick to simple |nnnn|. +% % \begin{macrocode} -\def_new:Npn \bool_double_if:NNnnnn#1#2{ - \if_case:w \num_eval:w #1\scan_stop: - \if_case:w \num_eval:w #2\scan_stop: - \exp_after:NN\exp_after:NN\exp_after:NN \use_arg_i:nnnn - \else: - \exp_after:NN\exp_after:NN\exp_after:NN \use_arg_ii:nnnn - \fi: - \else: - \if_case:w \num_eval:w #2\scan_stop: - \exp_after:NN\exp_after:NN\exp_after:NN \use_arg_iii:nnnn - \else: - \exp_after:NN\exp_after:NN\exp_after:NN \use_arg_iv:nnnn - \fi: - \fi: +\cs_new:Npn \bool_do_until:Nn #1 #2 { + #2 \bool_if:NF #1 {\bool_do_until:Nn #1 {#2}} } -\def_new:Npn \bool_double_if:cNnnnn{\exp_args:Nc\bool_double_if:NNnnnn} -\def_new:Npn \bool_double_if:Ncnnnn{\exp_args:NNc\bool_double_if:NNnnnn} -\def_new:Npn \bool_double_if:ccnnnn{\exp_args:Ncc\bool_double_if:NNnnnn} +\cs_generate_variant:Nn \bool_do_until:Nn {c} % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} -% \subsubsection{Generic testing} -% -% \begin{macro}{\prg_whiledo:nT} -% \begin{macro}{\prg_whiledo:nF} -% \begin{macro}{\prg_dowhile:nT} -% \begin{macro}{\prg_dowhile:nF} -% We provide these four generic while loops. |#1| is a test function -% and for the |T| functions it should be a test function ending with -% just the true case. Similar for the |F| types. -% \begin{macrocode} -\def_long_new:Npn \prg_whiledo:nT #1#2{ - #1 {#2 \prg_whiledo:nT {#1}{#2}} -} -\def_long_new:Npn \prg_whiledo:nF #1#2{ - #1 {#2 \prg_whiledo:nF {#1}{#2}} -} -\def_long_new:Npn \prg_dowhile:nT #1#2{ - #2 #1 {\prg_dowhile:nT {#1}{#2}} -} -\def_long_new:Npn \prg_dowhile:nF #1#2{ - #2 #1 {\prg_dowhile:nF {#1}{#2}} -} -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} % -% \begin{macro}{\predicate_p:n} -% \begin{macro}{\predicate:nTF} -% \begin{macro}{\predicate:nT} -% \begin{macro}{\predicate:nF} -% \begin{macro}{\predicate_auxi:NN} -% \begin{macro}{\predicate_auxii:NNN} -% \begin{macro}{\predicate_88_0:w}^^A% fix! -% \begin{macro}{\predicate_88_1:w}^^A% fix! -% \begin{macro}{\predicate_II_0:w}^^A% fix! -% \begin{macro}{\predicate_II_1:w}^^A fix! -% \begin{macro}{\predicate_02_0:w} -% \begin{macro}{\predicate_02_1:w} -% +% +% +% \subsection{Parsing boolean expressions} +% +% \begin{macro}{\bool_if_p:n} +% \begin{macro}[TF]{\bool_if:n} +% \begin{macro}[aux]{\bool_get_next:N, \bool_cleanup:N, \bool_choose:NN} +% \begin{macro}[aux]{\bool_!:w} +% \begin{macro}[aux]{\bool_(:w} +% \begin{macro}[aux]{\bool_p:w} +% \begin{macro}[aux]{\bool_8_1:w} +% \begin{macro}[aux]{\bool_I_1:w} +% \begin{macro}[aux]{\bool_8_0:w} +% \begin{macro}[aux]{\bool_I_0:w} +% \begin{macro}[aux]{\bool_)_0:w} +% \begin{macro}[aux]{\bool_)_1:w} +% \begin{macro}[aux]{\bool_S_0:w} +% \begin{macro}[aux]{\bool_S_1:w} +% % Evaluating the truth value of a list of predicates is done using % an input syntax somewhat similar to the one found in other -% programming languages. The function evaluates predicates from -% left to right, expanding them to 00 and 01 resp., which leads to -% six different situations of tokens in the input stream: -% \begin{itemize} -% \item[\texttt{00\&\&}] Current truth value is true, logical And -% seen, continue to see if next is also true. -% \item[\texttt{01\&\&}] Current truth value is false, logical And -% seen, break the scanning and return \meta{false}. -% \item[\texttt{00\char`\|\char`\|}] Current truth value is true, -% logical Or seen, break the scanning and return \meta{true}. -% \item[\texttt{01\char`\|\char`\|}] Current truth value is false, -% logical Or seen, continue to see if a later predicate is true. -% \item[\texttt{0002}] Current truth value is true, end marker +% programming languages with "(" and ")" for grouping, "!" for +% logical `Not', "&&" for logical `And' and "||" for logical +% "Or". We shall use the terms Not, And, Or, Open and Close for +% these operations. +% +% Any expression is terminated by a Close operation. Evaluation +% happens from left to right in the following manner using a GetNext +% function: +% \begin{itemize} +% \item If an Open is seen, start evaluating a new expression using +% the Eval function and +% call GetNext again. +% \item If a Not is seen, insert a negating function (if-even in +% this case) and call GetNext. +% \item If none of the above, start evaluating a new expression by +% reinserting the token found (this is supposed to be a predicate +% function) in front of Eval. +% \end{itemize} +% The Eval function then contains a post-processing operation which +% grabs the instruction following the predicate. This is either And, +% Or or Close. In each case the truth value is used to determine +% where to go next. The following situations can arise: +% \begin{description} +% \item[\meta{true}And] Current truth value is true, logical And +% seen, continue with GetNext to examine truth value of next +% boolean (sub-)expression. +% \item[\meta{false}And] Current truth value is false, logical And +% seen, stop evaluating the predicates within this sub-expression +% and break to the nearest Close. Then return \meta{false}. +% \item[\meta{true}Or] Current truth value is true, logical Or +% seen, stop evaluating the predicates within this sub-expression +% and break to the nearest Close. Then return \meta{true}. +% \item[\meta{false}Or] Current truth value is false, logical Or +% seen, continue with GetNext to examine truth value of next +% boolean (sub-)expression. +% \item[\meta{true}Close] Current truth value is true, Close % seen, return \meta{true}. -% \item[\texttt{0102}] Current truth value is false, end marker +% \item[\meta{false}Close] Current truth value is false, Close % seen, return \meta{false}. -% \end{itemize} -% To accomplish this we pre-expand the predicate list using |f| -% type expansion which leads to |00| or |01|, possibly with a -% sequence of unfinished |\else: \c_false \fi:| or similar after -% it, which we remove using the same trick. We also carry over the -% truth value of the evaluated predicate. The expansion stops when -% it sees the end marker or \verb+&&+ or \verb+||+ (assuming these -% are not active characters at the programming level). +% \end{description} +% We introduce an additional Stop operation with the following +% semantics: +% \begin{description} +% \item[\meta{true}Stop] Current truth value is true, return +% \meta{true}. +% \item[\meta{false}Stop] Current truth value is false, return +% \meta{false}. +% \end{description} +% The reasons for this follow below. +% +% Now for how these works in practice. The canonical true and false +% values have numerical values 1 and 0 respectively. We evaluate +% this using the primitive "\tex_number:D" operation. First we +% issue a "\group_align_safe_begin:" as we are using "&&" as syntax +% shorthand for the And operation and we need to hide it for \TeX. +% We also need to finish this special group before finally +% returning a "\c_true_bool" or "\c_false_bool" as there might +% otherwise be something left in front in the input stream. For +% this we call the Stop operation, denoted simply by a "S" +% following the last Close operation. % \begin{macrocode} -\def_long_new:Npn \predicate_p:n #1{ - \group_align_safe_begin: - \exp_after:NN \predicate_auxi:NN - \int_to_roman:w-`\q #1 02\scan_stop: +\cs_set:Npn \bool_if_p:n #1{ + \group_align_safe_begin: + \bool_get_next:N ( #1 )S } -\def_long_test_function_new:npn {predicate:n}#1{ - \group_align_safe_begin: - \if:w \exp_after:NN \predicate_auxi:NN - \int_to_roman:w-`\q #1 02\scan_stop: +% \end{macrocode} +% The GetNext operation. We make it a switch: If not a "!" or "(", we +% assume it is a predicate. +% \begin{macrocode} +\cs_set:Npn \bool_get_next:N #1{ + \use:c { + bool_ + \if_meaning:w !#1 ! \else: \if_meaning:w (#1 ( \else: p \fi: \fi: + :w + } #1 } -\def_new:Npn \predicate_auxi:NN 0 #1{ - \exp_after:NN \predicate_auxii:NNN \exp_after:NN #1 - \int_to_roman:w-`\q +% \end{macrocode} +% The Not operation. Discard the token read and reverse the truth +% value of the next expression using "\intexpr_if_even_p:n". +% \begin{macrocode} +\cs_set:cpn {bool_!:w}#1{ + \exp_after:wN \intexpr_if_even_p:n \tex_number:D \bool_get_next:N } % \end{macrocode} -% After removing trailing conditionals we call a macro for the case we -% are in (see list above). +% The Open operation. Discard the token read and start a +% sub-expression. % \begin{macrocode} -\def_new:Npn \predicate_auxii:NNN #1#2#3{ - \cs_use:c{predicate_#2#3_#1:w} } -\def_new:cpn{predicate_&&_0:w}{ - \exp_after:NN \predicate_auxi:NN\int_to_roman:w-`\q +\cs_set:cpn {bool_(:w}#1{ + \exp_after:wN \bool_cleanup:N \tex_number:D \bool_get_next:N } -\def_long_new:cpn{predicate_&&_1:w} #1 02\scan_stop:{ - \group_align_safe_end: 01} -\def_long_new:cpn{predicate_||_0:w} #1 02\scan_stop:{ - \group_align_safe_end: 00} -\def_new:cpn{predicate_||_1:w}{ - \exp_after:NN \predicate_auxi:NN\int_to_roman:w-`\q +% \end{macrocode} +% Otherwise just evaluate the predicate and look for And, Or or Close +% afterward. +% \begin{macrocode} +\cs_set:cpn {bool_p:w}{\exp_after:wN \bool_cleanup:N \tex_number:D } +% \end{macrocode} +% This cleanup function can be omitted once predicates return their +% true/false booleans outside the conditionals. +% \begin{macrocode} +\cs_new_nopar:Npn \bool_cleanup:N #1{ + \exp_after:wN \bool_choose:NN \exp_after:wN #1 + \int_to_roman:w-`\q } -\def_new:cpn{predicate_02_0:w}\scan_stop:{ \group_align_safe_end: 00 } -\def_new:cpn{predicate_02_1:w}\scan_stop:{ \group_align_safe_end: 01 } +% \end{macrocode} +% Branching the six way switch. +% \begin{macrocode} +\cs_new_nopar:Npn \bool_choose:NN #1#2{ \use:c{bool_#2_#1:w} } +% \end{macrocode} +% Continues scanning. Must remove the second "&" or "|". +% \begin{macrocode} +\cs_new_nopar:cpn{bool_&_1:w}&{\bool_get_next:N} +\cs_new_nopar:cpn{bool_|_0:w}|{\bool_get_next:N} +% \end{macrocode} +% Closing a group is just about returning the result. The Stop +% operation is similar except it closes the special alignment group +% before returning the boolean. +% \begin{macrocode} +\cs_new_nopar:cpn{bool_)_0:w}{ \c_false_bool } +\cs_new_nopar:cpn{bool_)_1:w}{ \c_true_bool } +\cs_new_nopar:cpn{bool_S_0:w}{\group_align_safe_end: \c_false_bool } +\cs_new_nopar:cpn{bool_S_1:w}{\group_align_safe_end: \c_true_bool } +% \end{macrocode} +% When the truth value has already been decided, we have to throw away +% the remainder of the current group as we are doing minimal +% evaluation. This is slightly tricky as there are no braces so we +% have to play match the "()" manually. +% \begin{macrocode} +\cs_set:cpn{bool_&_0:w}&{\bool_eval_skip_to_end:Nw \c_false_bool} +\cs_set:cpn{bool_|_1:w}|{\bool_eval_skip_to_end:Nw \c_true_bool} % \end{macrocode} % \end{macro} % \end{macro} @@ -1146,61 +1255,197 @@ % \end{macro} % \end{macro} % \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}[aux]{\bool_eval_skip_to_end:Nw, +% \bool_eval_skip_to_end_aux:Nw,\bool_eval_skip_to_end_auxii:Nw} +% There is always at least one ")" waiting, namely the outer +% one. However, we are facing the problem that there may be more than +% one that need to be finished off and we have to detect the correct +% number of them. Here is a complicated example showing how this is +% done. After evaluating the following, we realize we must skip +% everything after the first And. Note the extra Close at the end. +% \begin{quote} +% |\c_false_bool && ((abc) && xyz) && ((xyz) && (def)))| +% \end{quote} +% First read up to the first Close. This gives us the list we first +% read up until the first right parenthesis so we are looking at the +% token list +% \begin{quote} +% |((abc| +% \end{quote} +% This contains two Open markers so we must remove two groups. Since +% no evaluation of the contents is to be carried out, it doesn't +% matter how we remove the groups as long as we wind up with the +% correct result. We therefore first remove a "()" pair and what +% preceded the Open -- but leave the contents as it may contain Open +% tokens itself -- leaving +% \begin{quote} +% |(abc && xyz) && ((xyz) && (def)))| +% \end{quote} +% Another round of this gives us +% \begin{quote} +% |(abc && xyz| +% \end{quote} +% which still contains an Open so we remove another "()" pair, giving us +% \begin{quote} +% |abc && xyz && ((xyz) && (def)))| +% \end{quote} +% Again we read up to a Close and again find Open tokens: +% \begin{quote} +% |abc && xyz && ((xyz| +% \end{quote} +% Further reduction gives us +% \begin{quote} +% |(xyz && (def)))| +% \end{quote} +% and then +% \begin{quote} +% |(xyz && (def| +% \end{quote} +% with reduction to +% \begin{quote} +% |xyz && (def))| +% \end{quote} +% and ultimately we arrive at no Open tokens being skipped and we can +% finally close the group nicely. % +% This whole operation could be made a lot simpler if we were allowed +% to do simple pattern matching. With a new enough pdf\TeX\ one can do +% that sort of thing to test for existence of particular tokens. +% \begin{macrocode} +\cs_set:Npn \bool_eval_skip_to_end:Nw #1#2){ + \bool_eval_skip_to_end_aux:Nw #1 #2(\q_no_value\q_nil{#2} +} +% \end{macrocode} +% If no right parenthesis, then |#3| is no_value and we are done, return +% the boolean |#1|. If there is, we need to grab a () pair and then +% recurse +% \begin{macrocode} +\cs_set:Npn \bool_eval_skip_to_end_aux:Nw #1#2(#3#4\q_nil#5{ + \quark_if_no_value:NTF #3 + { #1 } + { \bool_eval_skip_to_end_auxii:Nw #1 #5 } +} +% \end{macrocode} +% keep the boolean, throw away anything up to the ( as it is +% irrelevant, remove a () pair but remember to reinsert |#3| as it may +% contain ( tokens! +% \begin{macrocode} +\cs_set:Npn \bool_eval_skip_to_end_auxii:Nw #1#2(#3){ + \bool_eval_skip_to_end:Nw #1#3 ) +} +% \end{macrocode} +% \end{macro} % -% \begin{macro}{\predicate_not_p:n} -% The "not" variant just reverses the outcome of |\predicate_p:n|. +% \begin{macro}{\bool_set:Nn,\bool_set:cn,\bool_gset:Nn,\bool_gset:cn} +% This function evaluates a boolean expression and assigns the first +% argument the meaning "\c_true_bool" or "\c_false_bool". % \begin{macrocode} -\def_long_new:Npn \predicate_not_p:n #1{ - \if:w \predicate_p:n{#1} \c_false \else: \c_true \fi: +\cs_new:Npn \bool_set:Nn #1#2 {\tex_chardef:D #1 = \bool_if_p:n {#2}} +\cs_new:Npn \bool_gset:Nn #1#2 { + \tex_global:D \tex_chardef:D #1 = \bool_if_p:n {#2} } +\cs_generate_variant:Nn \bool_set:Nn {c} +\cs_generate_variant:Nn \bool_gset:Nn {c} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\bool_not_p:n} +% The "not" variant just reverses the outcome of |\bool_if_p:n|. Can +% be optimized but this is nice and simple and according to the +% implementation plan. Not even particularly useful to have it when +% the infix notation is easier to use. +% \begin{macrocode} +\cs_new:Npn \bool_not_p:n #1{ \bool_if_p:n{!(#1)} } % \end{macrocode} % \end{macro} % -% \subsubsection{Case switch} +% \begin{macro}{\bool_xor_p:nn} +% Exclusive or. If the boolean expressions have same truth value, +% return false, otherwise return true. +% \begin{macrocode} +\cs_new:Npn \bool_xor_p:nn #1#2 { + \intexpr_compare:nNnTF {\bool_if_p:n { #1 }} = {\bool_if_p:n { #2 }} + {\c_false_bool}{\c_true_bool} +} +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +\prg_set_conditional:Npnn \bool_if:n #1 {TF,T,F}{ + \if_predicate:w \bool_if_p:n{#1} + \prg_return_true: \else: \prg_return_false: \fi: +} +% \end{macrocode} +% +% \begin{macro}{\bool_while_do:nn,\bool_until_do:nn} +% \begin{macro}{\bool_do_while:nn,\bool_do_until:nn} +% \begin{arguments} +% \item Predicate test +% \item Code to execute +% \end{arguments} +% \begin{macrocode} +\cs_new:Npn \bool_while_do:nn #1#2 { + \bool_if:nT {#1} { #2 \bool_while_do:nn {#1}{#2} } +} +\cs_new:Npn \bool_until_do:nn #1#2 { + \bool_if:nF {#1} { #2 \bool_until_do:nn {#1}{#2} } +} +\cs_new:Npn \bool_do_while:nn #1#2 { + #2 \bool_if:nT {#1} { \bool_do_while:nn {#1}{#2} } +} +\cs_new:Npn \bool_do_until:nn #1#2 { + #2 \bool_if:nF {#1} { \bool_do_until:nn {#1}{#2} } +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \subsection{Case switch} % % \begin{macro}{\prg_case_int:nnn} -% \begin{macro}{\prg_case_int_aux:nnn} +% \begin{macro}[aux]{\prg_case_int_aux:nnn} % This case switch is in reality quite simple. It takes three arguments: % \begin{enumerate} % \item An integer expression you wish to find. -% \item A list of pairs of "{"\meta{integer -% expr}"}""{"\meta{code}"}". The list can be as long as is desired +% \item A list of pairs of \Arg{integer expr} \Arg{code}. +% The list can be as long as is desired % and \meta{integer expr} can be negative. % \item The code to be executed if the value wasn't found. % \end{enumerate} % We don't need the else case here yet, so leave it dangling in the % input stream. % \begin{macrocode} -\def_long:Npn \prg_case_int:nnn #1 #2 { +\cs_new:Npn \prg_case_int:nnn #1 #2 { % \end{macrocode} % We will be parsing on |#1| for each step so we might as well % evaluate it first in case it is complicated. % \begin{macrocode} - \exp_args:No \prg_case_int_aux:nnn {\num_value:w \int_eval:n{#1}} #2 + \exp_args:Nf \prg_case_int_aux:nnn { \intexpr_eval:n{#1}} #2 % \end{macrocode} % The \texttt{?} below is just so there are enough arguments when we % reach the end. And it made you look.~\texttt{;-)} % \begin{macrocode} \q_recursion_tail ? \q_recursion_stop } -\def_long_new:Npn \prg_case_int_aux:nnn #1#2#3{ +\cs_new:Npn \prg_case_int_aux:nnn #1#2#3{ % \end{macrocode} % If we reach the end, return the else case. We just remove braces. % \begin{macrocode} - \quark_if_recursion_tail_stop_do:nn{#2}{\use_arg_i:n} + \quark_if_recursion_tail_stop_do:nn{#2}{\use:n} % \end{macrocode} % Otherwise we compare (which evaluates |#2| for us) % \begin{macrocode} - \num_compare:nNnTF{#1}={#2} + \intexpr_compare:nNnTF{#1}={#2} % \end{macrocode} % If true, we want to remove the remainder of the list, the else case -% and then execute the code specified. Why not use |#3\use_none:n|? -% Because if we are doing |f| style expansion, we will get -% leftovers. If the test was false, we try the next pair, carrying the -% |#1|. +% and then execute the code specified. |\prg_end_case:nw {#3}| does +% just that in one go. This means |f| style expansion works the way +% one wants it to work. % \begin{macrocode} - { \use_arg_i_delimit_by_q_recursion_stop:nw {\use_arg_i:nn{#3}} } + { \prg_end_case:nw {#3} } { \prg_case_int_aux:nnn {#1}} } % \end{macrocode} @@ -1208,17 +1453,17 @@ % \end{macro} % % \begin{macro}{\prg_case_dim:nnn} -% \begin{macro}{\prg_case_dim_aux:nnn} +% \begin{macro}[aux]{\prg_case_dim_aux:nnn} % Same as |\prg_case_dim:nnn| except it is for \meta{dim} registers. % \begin{macrocode} -\def_long:Npn \prg_case_dim:nnn #1 #2 { +\cs_new:Npn \prg_case_dim:nnn #1 #2 { \exp_args:No \prg_case_dim_aux:nnn {\dim_use:N \dim_eval:n{#1}} #2 \q_recursion_tail ? \q_recursion_stop } -\def_long_new:Npn \prg_case_dim_aux:nnn #1#2#3{ - \quark_if_recursion_tail_stop_do:nn{#2}{\use_arg_i:n} +\cs_new:Npn \prg_case_dim_aux:nnn #1#2#3{ + \quark_if_recursion_tail_stop_do:nn{#2}{\use:n} \dim_compare:nNnTF{#1}={#2} - { \use_arg_i_delimit_by_q_recursion_stop:nw {\use_arg_i:nn{#3}} } + { \prg_end_case:nw {#3} } { \prg_case_dim_aux:nnn {#1}} } % \end{macrocode} @@ -1226,27 +1471,56 @@ % \end{macro} % % \begin{macro}{\prg_case_str:nnn} -% \begin{macro}{\prg_case_str_aux:nnn} +% \begin{macro}[aux]{\prg_case_str_aux:nnn} % Same as |\prg_case_dim:nnn| except it is for strings. % \begin{macrocode} -\def_long:Npn \prg_case_str:nnn #1 #2 { +\cs_new:Npn \prg_case_str:nnn #1 #2 { \prg_case_str_aux:nnn {#1} #2 \q_recursion_tail ? \q_recursion_stop } -\def_long_new:Npn \prg_case_str_aux:nnn #1#2#3{ - \quark_if_recursion_tail_stop_do:nn{#2}{\use_arg_i:n} - \tlist_if_eq:xxTF{#1}{#2} - { \use_arg_i_delimit_by_q_recursion_stop:nw {\use_arg_i:nn{#3}} } +\cs_new:Npn \prg_case_str_aux:nnn #1#2#3{ + \quark_if_recursion_tail_stop_do:nn{#2}{\use:n} + \tl_if_eq:xxTF{#1}{#2} + { \prg_end_case:nw {#3} } { \prg_case_str_aux:nnn {#1}} } % \end{macrocode} % \end{macro} % \end{macro} % -% \subsubsection{Sorting} +% \begin{macro}{\prg_case_tl:Nnn} +% \begin{macro}[aux]{\prg_case_tl_aux:NNn} +% Same as |\prg_case_dim:nnn| except it is for token list variables. +% \begin{macrocode} +\cs_new:Npn \prg_case_tl:Nnn #1 #2 { + \prg_case_tl_aux:NNn #1 #2 + \q_recursion_tail ? \q_recursion_stop +} +\cs_new:Npn \prg_case_tl_aux:NNn #1#2#3{ + \quark_if_recursion_tail_stop_do:Nn #2{\use:n} + \tl_if_eq:NNTF #1 #2 + { \prg_end_case:nw {#3} } + { \prg_case_tl_aux:NNn #1} +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}[aux]{\prg_end_case:nw} +% Ending a case switch is always performed the same way so we +% optimize for this. |#1| is the code to execute, |#2| the +% remainder, and |#3| the dangling else case. +% \begin{macrocode} +\cs_new:Npn \prg_end_case:nw #1#2\q_recursion_stop#3{#1} +% \end{macrocode} +% \end{macro} + % +% \subsection{Sorting} % -% \begin{macro}{\prg_define_quicksort:nnn} +% +% \begin{macro}[aux]{\prg_define_quicksort:nnn} % |#1| is the name, |#2| and |#3| are the tokens enclosing the % argument. For the somewhat strange \meta{clist} type which doesn't % enclose the items but uses a separator we define it by hand @@ -1263,37 +1537,37 @@ % which compares the items and |\seq_quicksort_function:n| which is % placed before each sorted item. It is up to the programmer to % define these functions when needed. For the |seq| type a sequence -% is a token list pointer, so one additionally has to define +% is a token list variable, so one additionally has to define % \begin{quote} -% |\def:Npn \seq_quicksort:N{\exp_args:No\seq_quicksort:n}| +% |\cs_set_nopar:Npn \seq_quicksort:N{\exp_args:No\seq_quicksort:n}| % \end{quote} % % % For details on the implementation see ``Sorting in \TeX's Mouth'' % by Bernd Raichle. Firstly we define the function for parsing the -% ininital list and then the braced list afterwards. +% initial list and then the braced list afterwards. % \begin{macrocode} -\def_new:NNn \prg_define_quicksort:nnn 3 { - \def_long:cNx{#1_quicksort:n}1{ +\cs_new_nopar:Npn \prg_define_quicksort:nnn #1#2#3 { + \cs_set:cpx{#1_quicksort:n}##1{ \exp_not:c{#1_quicksort_start_partition:w} ##1 \exp_not:n{#2\q_nil#3\q_stop} } - \def_long:cNx{#1_quicksort_braced:n}1{ + \cs_set:cpx{#1_quicksort_braced:n}##1{ \exp_not:c{#1_quicksort_start_partition_braced:n} ##1 \exp_not:N\q_nil\exp_not:N\q_stop } - \def_long:cpx {#1_quicksort_start_partition:w} #2 ##1 #3{ + \cs_set:cpx {#1_quicksort_start_partition:w} #2 ##1 #3{ \exp_not:N \quark_if_nil:nT {##1}\exp_not:N \use_none_delimit_by_q_stop:w \exp_not:c{#1_quicksort_do_partition_i:nnnw} {##1}{}{} } - \def_long:cNx {#1_quicksort_start_partition_braced:n} 1 { + \cs_set:cpx {#1_quicksort_start_partition_braced:n} ##1 { \exp_not:N \quark_if_nil:nT {##1}\exp_not:N \use_none_delimit_by_q_stop:w \exp_not:c{#1_quicksort_do_partition_i_braced:nnnn} {##1}{}{} } % \end{macrocode} % Now for doing the partitions. % \begin{macrocode} - \def_long:cpx {#1_quicksort_do_partition_i:nnnw} ##1##2##3 #2 ##4 #3 { + \cs_set:cpx {#1_quicksort_do_partition_i:nnnw} ##1##2##3 #2 ##4 #3 { \exp_not:N \quark_if_nil:nTF {##4} \exp_not:c {#1_do_quicksort_braced:nnnnw} { \exp_not:c{#1_quicksort_compare:nnTF}{##1}{##4} @@ -1302,7 +1576,7 @@ } {##1}{##2}{##3}{##4} } - \def_long:cNx {#1_quicksort_do_partition_i_braced:nnnn} 4 { + \cs_set:cpx {#1_quicksort_do_partition_i_braced:nnnn} ##1##2##3##4 { \exp_not:N \quark_if_nil:nTF {##4} \exp_not:c {#1_do_quicksort_braced:nnnnw} { \exp_not:c{#1_quicksort_compare:nnTF}{##1}{##4} @@ -1311,7 +1585,7 @@ } {##1}{##2}{##3}{##4} } - \def_long:cpx {#1_quicksort_do_partition_ii:nnnw} ##1##2##3 #2 ##4 #3 { + \cs_set:cpx {#1_quicksort_do_partition_ii:nnnw} ##1##2##3 #2 ##4 #3 { \exp_not:N \quark_if_nil:nTF {##4} \exp_not:c {#1_do_quicksort_braced:nnnnw} { \exp_not:c{#1_quicksort_compare:nnTF}{##4}{##1} @@ -1320,7 +1594,7 @@ } {##1}{##2}{##3}{##4} } - \def_long:cNx {#1_quicksort_do_partition_ii_braced:nnnn} 4 { + \cs_set:cpx {#1_quicksort_do_partition_ii_braced:nnnn} ##1##2##3##4 { \exp_not:N \quark_if_nil:nTF {##4} \exp_not:c {#1_do_quicksort_braced:nnnnw} { \exp_not:c{#1_quicksort_compare:nnTF}{##4}{##1} @@ -1333,26 +1607,26 @@ % This part of the code handles the two branches in each % sorting. Again we will also have to do it braced. % \begin{macrocode} - \def_long:cNx {#1_quicksort_partition_less_i:nnnn} 4{ + \cs_set:cpx {#1_quicksort_partition_less_i:nnnn} ##1##2##3##4{ \exp_not:c{#1_quicksort_do_partition_i:nnnw}{##1}{##2}{{##4}##3}} - \def_long:cNx {#1_quicksort_partition_less_ii:nnnn} 4{ + \cs_set:cpx {#1_quicksort_partition_less_ii:nnnn} ##1##2##3##4{ \exp_not:c{#1_quicksort_do_partition_ii:nnnw}{##1}{##2}{##3{##4}}} - \def_long:cNx {#1_quicksort_partition_greater_i:nnnn} 4{ + \cs_set:cpx {#1_quicksort_partition_greater_i:nnnn} ##1##2##3##4{ \exp_not:c{#1_quicksort_do_partition_i:nnnw}{##1}{{##4}##2}{##3}} - \def_long:cNx {#1_quicksort_partition_greater_ii:nnnn} 4{ + \cs_set:cpx {#1_quicksort_partition_greater_ii:nnnn} ##1##2##3##4{ \exp_not:c{#1_quicksort_do_partition_ii:nnnw}{##1}{##2{##4}}{##3}} - \def_long:cNx {#1_quicksort_partition_less_i_braced:nnnn} 4{ + \cs_set:cpx {#1_quicksort_partition_less_i_braced:nnnn} ##1##2##3##4{ \exp_not:c{#1_quicksort_do_partition_i_braced:nnnn}{##1}{##2}{{##4}##3}} - \def_long:cNx {#1_quicksort_partition_less_ii_braced:nnnn} 4{ + \cs_set:cpx {#1_quicksort_partition_less_ii_braced:nnnn} ##1##2##3##4{ \exp_not:c{#1_quicksort_do_partition_ii_braced:nnnn}{##1}{##2}{##3{##4}}} - \def_long:cNx {#1_quicksort_partition_greater_i_braced:nnnn} 4{ + \cs_set:cpx {#1_quicksort_partition_greater_i_braced:nnnn} ##1##2##3##4{ \exp_not:c{#1_quicksort_do_partition_i_braced:nnnn}{##1}{{##4}##2}{##3}} - \def_long:cNx {#1_quicksort_partition_greater_ii_braced:nnnn} 4{ + \cs_set:cpx {#1_quicksort_partition_greater_ii_braced:nnnn} ##1##2##3##4{ \exp_not:c{#1_quicksort_do_partition_ii_braced:nnnn}{##1}{##2{##4}}{##3}} % \end{macrocode} % Finally, the big kahuna! This is where the sub-lists are sorted. % \begin{macrocode} - \def_long:cpx {#1_do_quicksort_braced:nnnnw} ##1##2##3##4\q_stop { + \cs_set:cpx {#1_do_quicksort_braced:nnnnw} ##1##2##3##4\q_stop { \exp_not:c{#1_quicksort_braced:n}{##2} \exp_not:c{#1_quicksort_function:n}{##1} \exp_not:c{#1_quicksort_braced:n}{##3} @@ -1374,77 +1648,24 @@ % \begin{macro}{\prg_quicksort_function:n} % \begin{macro}{\prg_quicksort_compare:nnTF} % \begin{macrocode} -\let:NN \prg_quicksort_function:n \ERROR -\let:NN \prg_quicksort_compare:nnTF \ERROR +\cs_set:Npn \prg_quicksort_function:n {\ERROR} +\cs_set:Npn \prg_quicksort_compare:nnTF {\ERROR} % \end{macrocode} % \end{macro} % \end{macro} % -% % That's it (for now). % \begin{macrocode} %</initex|package> +% \end{macrocode} +% +% \begin{macrocode} %<*showmemory> \showMemUsage %</showmemory> % \end{macrocode} % -% \endinput -% -% $Log$ -% Revision 1.19 2006/08/08 10:26:09 morten -% Fixed bugs in stepwise functions -% -% Revision 1.18 2006/07/30 14:41:28 morten -% Added stepwise functions (loops going from i to k with step of j) plus quicksort. -% -% Revision 1.17 2006/07/06 14:57:13 morten -% Moved code in the `miscellaneus' section to l3basics. -% -% Revision 1.16 2006/06/03 18:55:12 morten -% Added special double boolean switches. -% -% Revision 1.15 2006/03/20 18:26:38 braams -% Updated the copyright notice (2006) and demoted all implementation -% sections to subsections and so on to clean up the toc for source3.tex -% -% Revision 1.14 2006/01/19 22:31:56 morten -% Added \bool_set_eq:NN functions plus made function collection -% complete. -% -% Revision 1.13 2006/01/04 00:58:17 morten -% Added generic loops. Changed some names plus syntax for some of the -% logical operations. Added code for defining functions with specified -% number of arguments. -% -% Revision 1.12 2005/12/27 10:01:55 morten -% Changed RCS information retrieval. Moved tlist code to l3tlp. Added -% code for inserting n copies of something. Changed \bool_while to -% \bool_whiledo. -% -% Revision 1.11 2005/04/25 15:01:59 morten -% Fixed some names. Improved \peek_char_generic:NNTF to not use token registers. -% -% Revision 1.10 2005/04/23 14:36:12 morten -% Changed \c_left|right_brace_token to \c_group_begin_token and -% \c_group_end_token. Fixed definitions of \tlist_if_head_XXX functions. -% Added example for PR/3080. -% -% Revision 1.9 2005/04/09 21:08:43 morten -% Documentation blunders fixed -% -% Revision 1.8 2005/04/06 21:27:15 morten -% More tlist functions, Moved \engine_aleph:TF to l3basics, new peek-ahead functions, definitions of implicit characters. -% -% Revision 1.7 2005/03/26 21:11:14 morten -% Fix typo in \scan_align_safe_stop: -% -% Revision 1.6 2005/03/22 23:23:30 morten -% Moved \tlist_ functions from l3basics. Added align-safe versions of important functions. Reorganized documentation slightly. -% -% Revision 1.5 2005/03/16 22:36:10 braams -% Added the tweaks necessary to be able to load with initex -% -% Revision 1.4 2005/03/11 21:28:20 braams -% Fixed the use of RCS information; added \StopEventually +% \end{implementation} +% \PrintIndex % +% \endinput diff --git a/Master/texmf-dist/source/latex/expl3/l3prop.dtx b/Master/texmf-dist/source/latex/expl3/l3prop.dtx index d9c9e1271cc..ec76aa7fa6b 100644 --- a/Master/texmf-dist/source/latex/expl3/l3prop.dtx +++ b/Master/texmf-dist/source/latex/expl3/l3prop.dtx @@ -1,5 +1,5 @@ % \iffalse -%% File: l3prop.dtx Copyright (C) 1990-2008 LaTeX3 project +%% File: l3prop.dtx Copyright (C) 1990-2009 LaTeX3 project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this @@ -17,7 +17,7 @@ %% %% The development version of the bundle can be found at %% -%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/ +%% http://www.latex-project.org/svnroot/experimental/trunk/ %% %% for those people who are interested. %% @@ -36,7 +36,7 @@ \RequirePackage{l3names} %</driver|package> %\fi -\GetIdInfo$Id: l3prop.dtx 745 2008-08-03 18:50:46Z morten $ +\GetIdInfo$Id: l3prop.dtx 1365 2009-05-31 17:26:17Z mittelba $ {L3 Experimental Property Lists} %\iffalse %<*driver> @@ -44,7 +44,7 @@ \ProvidesFile{\filename.\filenameext} [\filedate\space v\fileversion\space\filedescription] %\iffalse -\documentclass{l3doc} +\documentclass[full]{l3doc} \begin{document} \DocInput{\filename.\filenameext} \end{document} @@ -60,105 +60,112 @@ % \date{\filedate} % \maketitle % +% \def\propkey{key} +% \def\propval{info} +% \def\proplist{prop} % +% \begin{documentation} % -% \section{Property lists} +% \LaTeX3 implements a data structure called a `property list' which allows +% arbitrary information to be stored and accessed using keywords rather than +% numerical indexing. % -% \LaTeX3 implements a data structure which allows to store information -% associated with individual tokens. +% A property list might contain a set of keys such as "name", "age", and "ID", +% which each have individual values that can be saved and retrieved. % -% \subsection{Functions} +% \section{Functions} % % \begin{function}{% % \prop_new:N | % \prop_new:c | % } % \begin{syntax} -% "\prop_new:N" <plist> +% "\prop_new:N" <\proplist> % \end{syntax} -% Defines <plist> to be a variable of type p-list. +% Defines <\proplist> to be a variable of type \meta{\proplist}. % \end{function} % % \begin{function}{% % \prop_clear:N | +% \prop_clear:c | % \prop_gclear:N | +% \prop_gclear:c | % } % \begin{syntax} -% "\prop_clear:N" <plist> +% "\prop_clear:N" <\proplist> % \end{syntax} -% These functions locally or globally clear <plist>. +% These functions locally or globally clear <\proplist>. % \end{function} % % \begin{function}{% % \prop_put:Nnn | -% \prop_put:ccn | +% \prop_put:cnn | % \prop_gput:Nnn | % \prop_gput:Nno | -% \prop_gput:Noo | -% \prop_gput:Ncn | -% \prop_gput:Ooo | -% \prop_gput:Nox | +% \prop_gput:NnV | +% \prop_gput:Nnx | % \prop_gput:cnn | -% \prop_gput:ccn | -% \prop_gput:cco | % \prop_gput:ccx | % } % \begin{syntax} -% "\prop_put:Nnn" <plist> "{"<key>"}" "{"<token list>"}" +% "\prop_put:Nnn" <\proplist> \Arg{\propkey} \Arg{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 +% Locally or globally associates <token list> with <\propkey> in the <\proplist> +% <\proplist>. If <\propkey> has already a meaning within <\proplist> this value is % overwritten. +% +% The <\propkey> must not contain unescaped "#" tokens but the <token list> may. % \end{function} % % \begin{function}{% % \prop_gput_if_new:Nnn | % } % \begin{syntax} -% "\prop_gput_if_new:Nnn" <plist> "{"<key>"}" "{"<token list>"}" +% "\prop_gput_if_new:Nnn" <\proplist> \Arg{\propkey} \Arg{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. +% Globally associates <token list> with <\propkey> in the <\proplist> +% <\proplist> but only if <\propkey> has so far no meaning within <\proplist>. +% Silently ignored if <\propkey> is already set in the <\proplist>. % \end{function} % % \begin{function}{% % \prop_get:NnN | % \prop_get:cnN | % \prop_gget:NnN | -% \prop_gget:NcN | % \prop_gget:cnN | % } % \begin{syntax} -% "\prop_get:NnN" <plist> "{"<key>"}" <tlp> +% "\prop_get:NnN" <\proplist> \Arg{\propkey} <tl var.> % \end{syntax} -% If <info> is the information associated with <key> in the p-list -% <plist> then the token list pointer <tlp> gets <info> assigned. +% If <\propval> is the information associated with <\propkey> in the <\proplist> +% <\proplist> then the token list variable <tl var.> gets <\propval> 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 | -% \prop_set_eq:cc | -% \prop_gset_eq:NN | -% \prop_gset_eq:cc -% } +% \begin{function}{ \prop_set_eq:NN | +% \prop_set_eq:cN | +% \prop_set_eq:Nc | +% \prop_set_eq:cc | +% \prop_gset_eq:NN | +% \prop_gset_eq:cN | +% \prop_gset_eq:Nc | +% \prop_gset_eq:cc } % \begin{syntax} -% "\prop_set_eq:NN" <plist 1> <plist 2> +% "\prop_set_eq:NN" <\proplist 1> <\proplist 2> % \end{syntax} -% A fast assignment of <plist>s. +% A fast assignment of <\proplist>s. % \end{function} % % \begin{function}{% % \prop_get_gdel:NnN | % } % \begin{syntax} -% "\prop_get_gdel:NnN" <plist> "{"<key>"}" <tlp> +% "\prop_get_gdel:NnN" <\proplist> \Arg{\propkey} <tl var.> % \end{syntax} -% Like "\prop_get:NnN" but additionally removes <key> (and its <info>) -% from <plist>. +% Like "\prop_get:NnN" but additionally removes <\propkey> (and its <\propval>) +% from <\proplist>. % \end{function} % % \begin{function}{% @@ -166,82 +173,121 @@ % \prop_gdel:Nn | % } % \begin{syntax} -% "\prop_del:Nn" <plist> "{"<key>"}" +% "\prop_del:Nn" <\proplist> \Arg{\propkey} % \end{syntax} -% Locally or globally deletes <key> and its <info> from <plist> if +% Locally or globally deletes <\propkey> and its <\propval> from <\proplist> if % found. Otherwise does nothing. % \end{function} % % -% \begin{function}{\prop_map_function:NN | -% \prop_map_function:cN | -% \prop_map_function:Nc | -% \prop_map_function:cc | -% } +% \begin{function}{ \prop_map_function:NN / (EXP) | +% \prop_map_function:cN / (EXP) | +% \prop_map_function:Nc / (EXP) | +% \prop_map_function:cc / (EXP) } % \begin{syntax} -% "\prop_map_function:NN" <plist> <function> +% "\prop_map_function:NN" <\proplist> <function> % \end{syntax} -% Maps <function> which should be a function with two arguments (<key> -% and <info>) over every <key> <info> pair of <plist>. Expandable. +% Maps <function> which should be a function with two arguments (<\propkey> +% and <\propval>) over every <\propkey> <\propval> pair of <\proplist>. Expandable. % \end{function} % % \begin{function}{\prop_map_inline:Nn | % \prop_map_inline:cn % } % \begin{syntax} -% "\prop_map_inline:Nn" <plist> "{" <inline function> "}" +% "\prop_map_inline:Nn" <\proplist> \Arg{inline function} % \end{syntax} % Just like "\prop_map_function: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>). Nestable. +% arguments via "#1" (<\propkey>) and "#2" (<\propval>). Nestable. +% \end{function} +% +% +% \begin{function}{% +% \prop_map_break: | +% } +% \begin{syntax} +% "\prop_map_inline:Nn" \meta{\proplist} "{"\\ +% " ... \"\meta{break test}":T {\prop_map_break:} }" +% \end{syntax} +% For breaking out of a loop. To be used inside "TF"-type functions as shown +% in the example above. % \end{function} % +% \begin{function}{ \prop_show:N | +% \prop_show:c } +% \begin{syntax} +% "\prop_show:N" <\proplist> +% \end{syntax} +% Pauses the compilation and shows <\proplist> on the terminal output and +% in the log file. +% \end{function} % -% \begin{function}{% -% \prop_map_break:w | -% } -% \begin{syntax} -% "\prop_map_break:w" -% \end{syntax} -% For breaking out of a loop. To be used inside "TF" type functions. -% \end{function} +% \begin{function}{ \prop_display:N | +% \prop_display:c } +% \begin{syntax} +% "\prop_display:N" <prop> +% \end{syntax} +% As with "\prop_show:N" but pretty prints the output one line per property pair. +% \end{function} % % +% \section{Predicates and conditionals} % -% \subsection{Predicates and conditionals} +% \begin{function}{ \prop_if_empty_p:N | +% \prop_if_empty_p:c } +% \begin{syntax} +% "\prop_if_empty_p:N" <\proplist> \Arg{true code} \Arg{false code} +% \end{syntax} +% Predicates to test whether or not a particular <\proplist> is empty. +% \end{function} % -% \begin{function}{\prop_if_empty:NTF} +% \begin{function}{ \prop_if_empty:N / (TF)(EXP) | +% \prop_if_empty:c / (TF)(EXP) } % \begin{syntax} -% "\prop_if_empty:NTF" <plist> "{"<true code>"}{"<false code>"}" +% "\prop_if_empty:NTF" <\proplist> \Arg{true code} \Arg{false code} % \end{syntax} -% Set of conditionals that test whether or not a particular <plist> +% Set of conditionals that test whether or not a particular <\proplist> % is empty. % \end{function} % -% \begin{function}{\prop_if_eq:NNF | -% \prop_if_eq:ccF +% \begin{function}{ +% \prop_if_eq_p:NN / (EXP) | +% \prop_if_eq_p:cN / (EXP) | +% \prop_if_eq_p:Nc / (EXP) | +% \prop_if_eq_p:cc / (EXP) | +% \prop_if_eq:NN / (EXP)(TF) | +% \prop_if_eq:cN / (EXP)(TF) | +% \prop_if_eq:Nc / (EXP)(TF) | +% \prop_if_eq:cc / (EXP)(TF) | % } % \begin{syntax} -% "\prop_if_eq:NNF" <plist1> <plist2> "{"<false code>"}" +% "\prop_if_eq:NNF" <\proplist 1> <\proplist 2> \Arg{false code} % \end{syntax} -% Execute <false code> if <plist1> doesn't hold the same token list as -% <plist2>. +% Execute <false code> if <\proplist 1> doesn't hold the same token list as +% <\proplist 2>. Only expandable for new versions of pdf\TeX. % \end{function} % % % \begin{function}{% -% \prop_if_in:NnTF | -% \prop_if_in:NoTF | -% \prop_if_in:ccTF | +% \prop_if_in:Nn / (TF) | +% \prop_if_in:NV / (TF) | +% \prop_if_in:No / (TF) | +% \prop_if_in:cn / (TF) | +% \prop_if_in:cc / (TF) | % } % \begin{syntax} -% "\prop_if_in:NnTF" <plist>"{"<key>"}{"<true code>"}{"<false code>"}" +% "\prop_if_in:NnTF" <\proplist> \Arg{\propkey} \Arg{true code} \Arg{false code} % \end{syntax} -% Tests if <key> is used in <plist> and then either executes <true code> +% Tests if <\propkey> is used in <\proplist> and then either executes <true code> % or <false code>. % \end{function} % -% \subsection{Internal functions} +% \section{Internal functions} +% +% \begin{function}{\q_prop} +% Quark used to delimit property lists internally. +% \end{function} % % \begin{function}{% % \prop_put_aux:w | @@ -252,6 +298,7 @@ % % \begin{function}{% % \prop_get_aux:w | +% \prop_gget_aux:w | % \prop_get_del_aux:w | % \prop_del_aux:w | % } @@ -265,10 +312,9 @@ % \end{function} % % \begin{function}{% -% \prop_map_function_aux:NNn | -% \prop_map_inline_aux:Nn | +% \prop_map_function_aux:w | % } -% Internal functions implementing the map operations. +% Internal function implementing the map operations. % \end{function} % % \begin{function}{% @@ -280,53 +326,60 @@ % % \begin{function}{\prop_split_aux:Nnn} % \begin{syntax} -% "\prop_split_aux:Nnn" <plist> <key> <cmd> +% "\prop_split_aux:Nnn" <\proplist> <\propkey> <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> +% beginning of <\proplist> before <\propkey>, 2nd is the value associated with +% <\propkey>, 3rd is the rest of <\proplist> after <\propkey>. If there is no key +% <\propkey> in <\proplist>, then the 2 arg is "\q_no_value" and the 3rd arg is +% empty; otherwise the 3rd argument has the two extra tokens <\propkey> % "\q_no_value" at the end. % % This function is used to implement various get operations. % \end{function} % -% \StopEventually{} +% \end{documentation} % -% \subsection {The Implementation} +% \begin{implementation} +% +% \section{\pkg{l3prop} implementation} +% +% A property list is a token register whose contents is +% of the form\par +% {\centering|\q_prop| \meta{\propkey$\sb1$} |\q_prop| \marg{\propval$\sb1$} \ldots{} +% |\q_prop| \meta{\propkey$\sb n$} |\q_prop| \marg{\propval$\sb n$}\par} +% +% The property \m{\propkey}s and \m{\propval}s might be arbitrary token lists; each +% \m{\propval} is surrounded by braces. % % We start by ensuring that the required packages are loaded. % \begin{macrocode} -%<package>\ProvidesExplPackage -%<package> {\filename}{\filedate}{\fileversion}{\filedescription} -%<package>\RequirePackage{l3toks}\par -%<package>\RequirePackage{l3quark}\par +%<*package> +\ProvidesExplPackage + {\filename}{\filedate}{\fileversion}{\filedescription} +\package_check_loaded_expl: +%</package> %<*initex|package> % \end{macrocode} % -% A property list is a token register whose contents is -% of the form `\zz{q_prop}key$\sb1$\zz{q_prop}\zv{val$\sb1$} \ldots{} -% \zz{q_prop}key$\sb n$\zz{q_prop}\zv{val$\sb{}n$}'. -% The properties have to be single -% token, the values might be arbitrary token lists they get surrounded -% by braces. -% % \begin{macro}{\q_prop} +% The separator between \m{\propkey}s and \m{\propval}s and \m{\propkey}s. % \begin{macrocode} \quark_new:N\q_prop % \end{macrocode} % \end{macro} - +% % To get values from property-lists, token lists should be passed to % the appropriate functions. % +% \subsection{Functions} +% % \begin{macro}{\prop_new:N} % \begin{macro}{\prop_new:c} -% Property lists are implemented as token lists. +% Property lists are implemented as token registers. % \begin{macrocode} -\def_new:Npn \prop_new:N #1{\toks_new:N #1} -\def_new:Npn \prop_new:c {\exp_args:Nc \prop_new:N} +\cs_new_eq:NN \prop_new:N \toks_new:N +\cs_new_eq:NN \prop_new:c \toks_new:c % \end{macrocode} % \end{macro} % \end{macro} @@ -338,30 +391,94 @@ % The same goes for clearing a property list, either % locally or globally. % \begin{macrocode} -\let_new:NN \prop_clear:N \toks_clear:N -\def_new:Npn \prop_clear:c {\exp_args:Nc\prop_clear:N} -\let_new:NN \prop_gclear:N \toks_gclear:N -\def_new:Npn \prop_gclear:c {\exp_args:Nc\prop_gclear:N} +\cs_new_eq:NN \prop_clear:N \toks_clear:N +\cs_new_eq:NN \prop_clear:c \toks_clear:c +\cs_new_eq:NN \prop_gclear:N \toks_gclear:N +\cs_new_eq:NN \prop_gclear:c \toks_gclear:c % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % +% \begin{macro}{\prop_set_eq:NN} +% \begin{macro}{\prop_set_eq:Nc} +% \begin{macro}{\prop_set_eq:cN} +% \begin{macro}{\prop_set_eq:cc} +% \begin{macro}{\prop_gset_eq:NN} +% \begin{macro}{\prop_gset_eq:Nc} +% \begin{macro}{\prop_gset_eq:cN} +% \begin{macro}{\prop_gset_eq:cc} +% This makes two \m{\proplist}s have the same contents. +% \begin{macrocode} +\cs_new_eq:NN \prop_set_eq:NN \toks_set_eq:NN +\cs_new_eq:NN \prop_set_eq:Nc \toks_set_eq:Nc +\cs_new_eq:NN \prop_set_eq:cN \toks_set_eq:cN +\cs_new_eq:NN \prop_set_eq:cc \toks_set_eq:cc +\cs_new_eq:NN \prop_gset_eq:NN \toks_gset_eq:NN +\cs_new_eq:NN \prop_gset_eq:Nc \toks_gset_eq:Nc +\cs_new_eq:NN \prop_gset_eq:cN \toks_gset_eq:cN +\cs_new_eq:NN \prop_gset_eq:cc \toks_gset_eq:cc +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\prop_show:N} +% \begin{macro}{\prop_show:c} +% Show on the console the raw contents of a property list's token register. +% \begin{macrocode} +\cs_new_eq:NN \prop_show:N \toks_show:N +\cs_new_eq:NN \prop_show:c \toks_show:c +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\prop_display:N} +% \begin{macro}{\prop_display:c} +% Pretty print the contents of a property list on the console. +% \begin{macrocode} +\cs_new_nopar:Npn \prop_display:N #1 { + \iow_term:x { Property-list~\token_to_str:N #1~contains~ + the~pairs~(without~outer~braces): } + \toks_clear:N \l_tmpa_toks + \prop_map_inline:Nn #1 { + \toks_if_empty:NF \l_tmpa_toks { + \toks_put_right:Nx \l_tmpa_toks {^^J>~} + } + \toks_put_right:Nx \l_tmpa_toks { + \iow_space: \iow_char:N \{ \exp_not:n {##1} \iow_char:N \} \iow_space: + \iow_space: => \iow_space: + \iow_space: \iow_char:N \{ \exp_not:n {##2} \iow_char:N \} + } + } + \toks_show:N \l_tmpa_toks +} +\cs_generate_variant:Nn \prop_display:N {c} +% \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| +% |\prop_split_aux:Nnn|\meta{\proplist}\meta{\propkey}\meta{cmd} invokes \meta{cmd} +% with 3 arguments: 1st is the beginning of \meta{\proplist} before +% \meta{\propkey}, 2nd is the value associated with \meta{\propkey}, 3rd is the +% rest of \meta{\proplist} after \meta{\propkey}. If there is no property +% \meta{\propkey} in \meta{\proplist}, then the 2nd argument will be |\q_no_value| % and the 3rd argument is empty; otherwise the 3rd argument has the -% extra tokens |\q_prop| \zz{prop} |\q_prop| |\q_no_value| at the end. +% extra tokens |\q_prop| \meta{\propkey} |\q_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\q_prop#2\q_prop##2##3\q_stop {#3{##1}{##2}{##3}} - \exp_after:NN\tmp:w \toks_use:N#1\q_prop#2\q_prop\q_no_value \q_stop +\cs_new:Npn \prop_split_aux:Nnn #1#2#3{ + \cs_set:Npn \prop_tmp:w ##1 \q_prop #2 \q_prop ##2##3 \q_stop { + #3 {##1}{##2}{##3} + } + \exp_after:wN \prop_tmp:w \toks_use:N #1 \q_prop #2 \q_prop \q_no_value \q_stop } % \end{macrocode} % \end{macro} @@ -369,109 +486,106 @@ % \begin{macro}{\prop_get:NnN} % \begin{macro}{\prop_get:cnN} % \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}, +% |\prop_get:NnN |\meta{\proplist}\meta{\propkey}\meta{tl var.}~defines +% \meta{tl var.}~to be the value associated with \meta{\propkey} in \meta{\proplist}, % |\q_no_value| if not found. % \begin{macrocode} -\def_long_new:NNn \prop_get:NnN 2{ - \prop_split_aux:Nnn #1{#2}\prop_get_aux:w} -\def_long_new:NNn \prop_get_aux:w 4{\tlp_set:Nx#4{\exp_not:n{#2}}} -\def_new:Npn \prop_get:cnN { \exp_args:Nc \prop_get:NnN } +\cs_new:Npn \prop_get:NnN #1#2 { + \prop_split_aux:Nnn #1{#2}\prop_get_aux:w +} +\cs_new:Npn \prop_get_aux:w #1#2#3#4 { \tl_set:Nx #4 {\exp_not:n{#2}} } +% \end{macrocode} +% +% \begin{macrocode} +\cs_generate_variant:Nn \prop_get:NnN {cnN} % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % % \begin{macro}{\prop_gget:NnN} -% \begin{macro}{\prop_gget:NcN} % \begin{macro}{\prop_gget:cnN} % \begin{macro}{\prop_gget_aux:w} % The global version of the previous function. % \begin{macrocode} -\def_long_new:NNn \prop_gget:NnN 2{ +\cs_new:Npn \prop_gget:NnN #1#2{ \prop_split_aux:Nnn #1{#2}\prop_gget_aux:w} -\def_new:Npn \prop_gget:NcN {\exp_args:NNc \prop_gget:NnN} -\def_new:Npn \prop_gget:cnN {\exp_args:Nc \prop_gget:NnN} -\def_long_new:NNn \prop_gget_aux:w 4{\tlp_gset:Nx#4{\exp_not:n{#2}}} +\cs_new:Npn \prop_gget_aux:w #1#2#3#4{\tl_gset:Nx#4{\exp_not:n{#2}}} +% \end{macrocode} +% +% \begin{macrocode} +\cs_generate_variant:Nn \prop_gget:NnN {cnN} % \end{macrocode} -% \end{macro} % \end{macro} % \end{macro} % \end{macro} % -% \begin{macro}{\prop_get_gdel:NNN} +% \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 +% |\prop_get_gdel:NnN| is the same as |\prop_get:NnN| but the +% \m{\propkey} 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:NNn \prop_get_gdel:NnN 3{ +\cs_new:Npn \prop_get_gdel:NnN #1#2#3{ \prop_split_aux:Nnn #1{#2}{\prop_get_del_aux:w #3{\toks_gset:Nn #1}{#2}}} -\def_long_new:NNn \prop_get_del_aux:w 6{ - \tlp_set:Nx #1{\exp_not:n{#5}} +\cs_new:Npn \prop_get_del_aux:w #1#2#3#4#5#6{ + \tl_set:Nx #1{\exp_not:n{#5}} \quark_if_no_value:NF #1 { - \def:Npn \tmp:w ##1\q_prop#3\q_prop\q_no_value {#2{#4##1}} - \tmp:w #6} + \cs_set_nopar:Npn \prop_tmp:w ##1\q_prop#3\q_prop\q_no_value {#2{#4##1}} + \prop_tmp:w #6} } % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\prop_put:Nnn} -% \begin{macro}{\prop_put:ccn} +% \begin{macro}{\prop_put:cnn} % \begin{macro}{\prop_gput:Nnn} +% \begin{macro}{\prop_gput:NnV} % \begin{macro}{\prop_gput:Nno} % \begin{macro}{\prop_gput:Nnx} -% \begin{macro}{\prop_gput:Nox} -% \begin{macro}{\prop_gput:Noo} -% \begin{macro}{\prop_gput:Ncn} -% \begin{macro}{\prop_gput:Ooo} -% \begin{macro}{\prop_gput:cNn} -% \begin{macro}{\prop_gput:ccn} -% \begin{macro}{\prop_gput:cco} +% \begin{macro}{\prop_gput:cnn} % \begin{macro}{\prop_gput:ccx} % \begin{macro}{\prop_put_aux:w} -% |\prop_put:Nnn |\zz{plist}\zz{prop}\zv{val} adds/changes the -% value associated with \zz{prop} in \zz{plist} to \zv{val}. +% |\prop_put:Nnn| \marg{\proplist} \marg{\propkey} \marg{\propval} adds/changes the +% value associated with \meta{\propkey} in \meta{\proplist} to \meta{\propval}. % \begin{macrocode} -\def_long_new:NNn \prop_put:Nnn 2{ +\cs_new:Npn \prop_put:Nnn #1#2{ \prop_split_aux:Nnn #1{#2}{ \prop_clear:N #1 - \prop_put_aux:w {\toks_put_right:Nn #1}{#2}} + \prop_put_aux:w {\toks_put_right:Nn #1}{#2} + } } -\def_new:Npn \prop_put:ccn {\exp_args:Ncc \prop_put:Nnn } - -\def_long_new:NNn \prop_gput:Nnn 2{ +% \end{macrocode} +% +% \begin{macrocode} +\cs_new:Npn \prop_gput:Nnn #1#2{ \prop_split_aux:Nnn #1{#2}{ \prop_gclear:N #1 - \prop_put_aux:w {\toks_gput_right:Nn #1}{#2}} + \prop_put_aux:w {\toks_gput_right:Nn #1}{#2} + } } - -\def_long_new:NNn \prop_put_aux:w 6{ +% \end{macrocode} +% +% \begin{macrocode} +\cs_new:Npn \prop_put_aux:w #1#2#3#4#5#6{ #1{\q_prop#2\q_prop{#6}#3} - \tlist_if_empty:nF{#5} + \tl_if_empty:nF{#5} { - \def:Npn \tmp:w ##1\q_prop#2\q_prop\q_no_value {#1{##1}} - \tmp:w #5 + \cs_set_nopar:Npn \prop_tmp:w ##1\q_prop#2\q_prop\q_no_value {#1{##1}} + \prop_tmp:w #5 } } -\def_new:Npn \prop_gput:Nno {\exp_args:NNno \prop_gput:Nnn} -\def_new:Npn \prop_gput:Nnx {\exp_args:NNnx \prop_gput:Nnn} -\def_new:Npn \prop_gput:Nox {\exp_args:NNox \prop_gput:Nnn} -\def_new:Npn \prop_gput:Noo {\exp_args:NNoo \prop_gput:Nnn} -\def_new:Npn \prop_gput:Ncn {\exp_args:NNc \prop_gput:Nnn} -\def_new:Npn \prop_gput:Ooo {\exp_args:NOoo \prop_gput:Nnn} -\def_new:Npn \prop_gput:cnn {\exp_args:Nc \prop_gput:Nnn} -\def_new:Npn \prop_gput:ccn {\exp_args:Ncc \prop_gput:Nnn} -\def_new:Npn \prop_gput:cco {\exp_args:Ncco \prop_gput:Nnn} -\def_new:Npn \prop_gput:ccx {\exp_args:Nccx \prop_gput:Nnn} % \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} +% +% \begin{macrocode} +\cs_generate_variant:Nn \prop_put:Nnn {cnn} +% \end{macrocode} +% +% \begin{macrocode} +\cs_generate_variant:Nn \prop_gput:Nnn {NnV,Nno,Nnx,Nox,cnn,ccx} +% \end{macrocode} % \end{macro} % \end{macro} % \end{macro} @@ -485,169 +599,105 @@ % \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. +% |\prop_del:Nn |\meta{\proplist}\meta{\propkey} deletes the entry for +% \meta{\propkey} in \meta{\proplist}, if any. % \begin{macrocode} -\def_long_new:NNn \prop_del:Nn 2{ +\cs_new:Npn \prop_del:Nn #1#2{ \prop_split_aux:Nnn #1{#2}{\prop_del_aux:w {\toks_set:Nn #1}{#2}}} -\def_long_new:NNn \prop_gdel:Nn 2{ +\cs_new:Npn \prop_gdel:Nn #1#2{ \prop_split_aux:Nnn #1{#2}{\prop_del_aux:w {\toks_gset:Nn #1}{#2}}} -\def_long_new:NNn \prop_del_aux:w 5{ - \def:Npn \tmp:w {#4} - \quark_if_no_value:NF \tmp:w - {\def:Npn \tmp:w ##1\q_prop#2\q_prop\q_no_value {#1{#3##1}} - \tmp:w #5}} +\cs_new:Npn \prop_del_aux:w #1#2#3#4#5{ + \cs_set_nopar:Npn \prop_tmp:w {#4} + \quark_if_no_value:NF \prop_tmp:w { + \cs_set_nopar:Npn \prop_tmp:w ##1\q_prop#2\q_prop\q_no_value {#1{#3##1}} + \prop_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:ccTF} -% \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:NNn \prop_if_in:NnTF 2{ - \prop_split_aux:Nnn #1{#2}\prop_if_in_aux:w} -\def_new:NNn \prop_if_in_aux:w 3{\quark_if_no_value:nFT {#2}} - -\def_new:Npn \prop_if_in:NoTF {\exp_args:NNo \prop_if_in:NnTF} -\def_new:Npn \prop_if_in:ccTF {\exp_args:Ncc \prop_if_in:NnTF} -% \end{macrocode} -% \end{macro} -% \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{macro}{\prop_put_if_new_aux:w} +% |\prop_gput_if_new:Nnn| \m{\proplist} \m{\propkey} +% \m{\propval} is equivalent to % \begin{tabbing} % xxxxx\=xxxxx\= \kill -% |\prop_if_in:NNTF |\m{property}\m{property_key} \\ +% |\prop_if_in:NnTF |\m{\proplist}\m{\propkey} \\ % \> |{}%| \\ % \> |{\prop_gput:Nnn| \\ % \>\> \m{property_list} \\ -% \>\> \m{property_key} \\ -% \>\> \m{property_value}|}| +% \>\> \m{\propkey} \\ +% \>\> \m{\propval}|}| % \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:NNn \prop_gput_if_new:Nnn 2{ +\cs_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:NNn \prop_put_if_new_aux:w 6{ - \tlist_if_empty:nT {#5}{#1{\q_prop#2\q_prop{#6}#3}}} +\cs_new:Npn \prop_put_if_new_aux:w #1#2#3#4#5#6{ + \tl_if_empty:nT {#5}{#1{\q_prop#2\q_prop{#6}#3}}} % \end{macrocode} % \end{macro} +% \end{macro} % % -% \begin{macro}{\prop_set_eq:NN} -% \begin{macro}{\prop_set_eq:Nc} -% \begin{macro}{\prop_set_eq:cN} -% \begin{macro}{\prop_set_eq:cc} -% \begin{macro}{\prop_gset_eq:NN} -% \begin{macro}{\prop_gset_eq:Nc} -% \begin{macro}{\prop_gset_eq:cN} -% \begin{macro}{\prop_gset_eq:cc} -% This makes two \m{plist}s have the same contents. +% \subsection{Predicates and conditionals} +% +% \begin{macro}{\prop_if_empty_p:N,\prop_if_empty_p:c} +% \begin{macro}[TF]{\prop_if_empty:N,\prop_if_empty:c} +% This conditional takes a \m{\proplist} as its argument and evaluates +% either the true or the false case, depending on whether or not +% \m{\proplist} contains any properties. % \begin{macrocode} -\let_new:NN \prop_set_eq:NN \toks_set_eq:NN -\let_new:NN \prop_set_eq:Nc \toks_set_eq:Nc -\let_new:NN \prop_set_eq:cN \toks_set_eq:cN -\let_new:NN \prop_set_eq:cc \toks_set_eq:cc -\let_new:NN \prop_gset_eq:NN \toks_gset_eq:NN -\let_new:NN \prop_gset_eq:Nc \toks_gset_eq:Nc -\let_new:NN \prop_gset_eq:cN \toks_gset_eq:cN -\let_new:NN \prop_gset_eq:cc \toks_gset_eq:cc +\prg_new_eq_conditional:NNn \prop_if_empty:N \toks_if_empty:N {p,TF,T,F} +\prg_new_eq_conditional:NNn \prop_if_empty:c \toks_if_empty:c {p,TF,T,F} % \end{macrocode} % \end{macro} % \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} % -% \begin{macro}{\prop_if_empty_p:N} -% \begin{macro}{\prop_if_empty_p:c} -% \begin{macro}{\prop_if_empty:NTF} -% \begin{macro}{\prop_if_empty:NT} -% \begin{macro}{\prop_if_empty:NF} -% \begin{macro}{\prop_if_empty:cTF} -% \begin{macro}{\prop_if_empty:cT} -% \begin{macro}{\prop_if_empty:cF} -% 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{macro}{\prop_if_eq_p:NN,\prop_if_eq_p:cN, +% \prop_if_eq_p:Nc,\prop_if_eq_p:cc} +% \begin{macro}[TF]{\prop_if_eq:NN,\prop_if_eq:Nc, +% \prop_if_eq:cN,\prop_if_eq:cc} +% These functions test whether two property lists are equal. % \begin{macrocode} -\let_new:NN \prop_if_empty_p:N \toks_if_empty_p:N -\let_new:NN \prop_if_empty_p:c \toks_if_empty_p:c -\let_new:NN \prop_if_empty:NTF \toks_if_empty:NTF -\let_new:NN \prop_if_empty:NT \toks_if_empty:NT -\let_new:NN \prop_if_empty:NF \toks_if_empty:NF -\let_new:NN \prop_if_empty:cTF \toks_if_empty:cTF -\let_new:NN \prop_if_empty:cT \toks_if_empty:cTF -\let_new:NN \prop_if_empty:cF \toks_if_empty:cF +\prg_new_eq_conditional:NNn \prop_if_eq:NN \toks_if_eq:NN {p,TF,T,F} +\prg_new_eq_conditional:NNn \prop_if_eq:cN \toks_if_eq:cN {p,TF,T,F} +\prg_new_eq_conditional:NNn \prop_if_eq:Nc \toks_if_eq:Nc {p,TF,T,F} +\prg_new_eq_conditional:NNn \prop_if_eq:cc \toks_if_eq:cc {p,TF,T,F} % \end{macrocode} % \end{macro} % \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% % -% \begin{macro}{\prop_if_eq:NNTF} -% \begin{macro}{\prop_if_eq:NNT} -% \begin{macro}{\prop_if_eq:NNF} -% \begin{macro}{\prop_if_eq:NcTF} -% \begin{macro}{\prop_if_eq:NcT} -% \begin{macro}{\prop_if_eq:NcF} -% \begin{macro}{\prop_if_eq:cNTF} -% \begin{macro}{\prop_if_eq:cNT} -% \begin{macro}{\prop_if_eq:cNF} -% \begin{macro}{\prop_if_eq:ccTF} -% \begin{macro}{\prop_if_eq:ccT} -% \begin{macro}{\prop_if_eq:ccF} -% This function test whether the property lists that are in its first -% two arguments are equal; if they are not |#3| is executed. +% \begin{macro}[TF]{\prop_if_in:Nn} +% \begin{macro}[TF]{\prop_if_in:NV} +% \begin{macro}[TF]{\prop_if_in:No} +% \begin{macro}[TF]{\prop_if_in:cn} +% \begin{macro}[TF]{\prop_if_in:cc} +% \begin{macro}{\prop_if_in_aux:w} +% |\prop_if_in:NnTF| \m{property_list} \m{\propkey} +% \m{true_case} \m{false_case} will check whether or not +% \m{\propkey} is on the \m{property_list} and then select +% either the true or false case. % \begin{macrocode} -\def_new:NNn \prop_if_eq:NNTF 2 { - \tlist_if_eq:xxTF{\toks_use:N #1}{\toks_use:N #2} -} -\def_new:NNn \prop_if_eq:NNT 2 { - \tlist_if_eq:xxT{\toks_use:N #1}{\toks_use:N #2} +\prg_new_conditional:Nnn \prop_if_in:Nn {TF,T,F} { + \prop_split_aux:Nnn #1 {#2} {\prop_if_in_aux:w} } -\def_new:NNn \prop_if_eq:NNF 2 { - \tlist_if_eq:xxF{\toks_use:N #1}{\toks_use:N #2} +\cs_new_nopar:Npn \prop_if_in_aux:w #1#2#3 { + \quark_if_no_value:nTF {#2} {\prg_return_false:} {\prg_return_true:} } -\def_new:Npn \prop_if_eq:NcTF {\exp_args:NNc \prop_if_eq:NNTF} -\def_new:Npn \prop_if_eq:NcT {\exp_args:NNc \prop_if_eq:NNT} -\def_new:Npn \prop_if_eq:NcF {\exp_args:NNc \prop_if_eq:NNF} -\def_new:Npn \prop_if_eq:cNTF {\exp_args:Nc \prop_if_eq:NNTF} -\def_new:Npn \prop_if_eq:cNT {\exp_args:Nc \prop_if_eq:NNT} -\def_new:Npn \prop_if_eq:cNF {\exp_args:Nc \prop_if_eq:NNF} -\def_new:Npn \prop_if_eq:ccTF {\exp_args:Ncc \prop_if_eq:NNTF} -\def_new:Npn \prop_if_eq:ccT {\exp_args:Ncc \prop_if_eq:NNT} -\def_new:Npn \prop_if_eq:ccF {\exp_args:Ncc \prop_if_eq:NNF} % \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} +% +% \begin{macrocode} +\cs_generate_variant:Nn \prop_if_in:NnTF {NV,No,cn,cc} +\cs_generate_variant:Nn \prop_if_in:NnT {NV,No,cn,cc} +\cs_generate_variant:Nn \prop_if_in:NnF {NV,No,cn,cc} +% \end{macrocode} % \end{macro} % \end{macro} % \end{macro} @@ -655,6 +705,8 @@ % \end{macro} % \end{macro} % +% \subsection{Mapping functions} +% % \begin{macro}{\prop_map_function:NN} % \begin{macro}{\prop_map_function:cN} % \begin{macro}{\prop_map_function:Nc} @@ -662,55 +714,59 @@ % \begin{macro}{\prop_map_function_aux:w} % Maps a function on every entry in the property list. The % function must take 2 arguments: a key and a value. -% \begin{macrocode} -\def_new:Npn \prop_map_function:NN #1#2{ - \exp_after:NN \prop_map_function_aux:w - \exp_after:NN #2 \toks_use:N #1 \q_prop{}\q_prop \q_no_value \q_stop -} -\def_new:Npn \prop_map_function_aux:w #1\q_prop#2\q_prop#3{ - \if:w \tlist_if_empty_p:n{#2} - \exp_after:NN \prop_map_break:w - \fi: - #1{#2}{#3} - \prop_map_function_aux:w #1 -} -% problem with the above impl, is that an empty key stops the mapping but all +% +% First, some failed attempts: +% \begin{verbatim} +% \cs_new_nopar:Npn \prop_map_function:NN #1#2{ +% \exp_after:wN \prop_map_function_aux:w +% \exp_after:wN #2 \toks_use:N #1 \q_prop{}\q_prop \q_no_value \q_stop +% } +% \cs_new_nopar:Npn \prop_map_function_aux:w #1\q_prop#2\q_prop#3{ +% \if_predicate:w \tl_if_empty_p:n{#2} +% \exp_after:wN \prop_map_break: +% \fi: +% #1{#2}{#3} +% \prop_map_function_aux:w #1 +% } +% \end{verbatim} +% problem with the above implementation is that an empty key stops the mapping but all % other functions in the module allow the use of empty keys (as one value) - -\def:Npn \prop_map_function:NN #1#2{ - \exp_after:NN \prop_map_function_aux:w - \exp_after:NN #2 \toks_use:N #1 \q_prop \q_no_value \q_prop \q_no_value -} -\def:Npn \prop_map_function_aux:w #1\q_prop#2\q_prop#3{ - \quark_if_no_value:nF{#2} - { - #1{#2}{#3} - \prop_map_function_aux:w #1 - } -} -% problem with the above impl is that \quark_if_no_value:nF is fairly slow and -% if \quark_if_no_value:NF is used instead we have to do an assignment thus +% \begin{verbatim} +% \cs_set_nopar:Npn \prop_map_function:NN #1#2{ +% \exp_after:wN \prop_map_function_aux:w +% \exp_after:wN #2 \toks_use:N #1 \q_prop \q_no_value \q_prop \q_no_value +% } +% \cs_set_nopar:Npn \prop_map_function_aux:w #1\q_prop#2\q_prop#3{ +% \quark_if_no_value:nF{#2} +% { +% #1{#2}{#3} +% \prop_map_function_aux:w #1 +% } +% } +% \end{verbatim} +% problem with the above implementation is that |\quark_if_no_value:nF| is fairly slow and +% if |\quark_if_no_value:NF| is used instead we have to do an assignment thus % making the mapping not expandable (is that important?) - -\def:Npn \prop_map_function:NN #1#2{ - \exp_after:NN \prop_map_function_aux:w - \exp_after:NN #2 \toks_use:N #1 \q_prop \q_nil \q_prop \q_no_value \q_stop +% +% Here's the current version of the code: +% \begin{macrocode} +\cs_set_nopar:Npn \prop_map_function:NN #1#2 { + \exp_after:wN \prop_map_function_aux:w + \exp_after:wN #2 \toks_use:N #1 \q_prop \q_nil \q_prop \q_no_value \q_stop } -\def:Npn \prop_map_function_aux:w #1\q_prop#2\q_prop#3{ - \if_meaning:NN \q_nil #2 - \exp_after:NN \prop_map_break:w +\cs_set:Npn \prop_map_function_aux:w #1 \q_prop #2 \q_prop #3 { + \if_meaning:w \q_nil #2 + \exp_after:wN \prop_map_break: \fi: #1{#2}{#3} \prop_map_function_aux:w #1 } - -% (potential) problem with the above impl is that it will returns true is #2 -% contains more than just \q_nil thus executing whatever follows. Claim: this -% can't happen :-) so we should be ok - -\def_new:Npn \prop_map_function:cN {\exp_args:Nc \prop_map_function:NN } -\def_new:Npn \prop_map_function:Nc {\exp_args:NNc \prop_map_function:NN } -\def_new:Npn \prop_map_function:cc {\exp_args:Ncc \prop_map_function:NN} +% \end{macrocode} +% (potential) problem with the above implementation is that it will +% return true if |#2| contains more than just |\q_nil| thus executing +% whatever follows. Claim: this can't happen |:-)| so we should be ok +% \begin{macrocode} +\cs_generate_variant:Nn \prop_map_function:NN {c,Nc,cc} % \end{macrocode} % \end{macro} % \end{macro} @@ -726,76 +782,42 @@ % we don't waste time doing that. % \begin{macrocode} \num_new:N \g_prop_inline_level_num -\def_new:Npn \prop_map_inline:Nn #1#2 { +\cs_new_nopar:Npn \prop_map_inline:Nn #1#2 { \num_gincr:N \g_prop_inline_level_num - \gdef_long:cpn {prop_map_inline_ \num_use:N \g_prop_inline_level_num :n} + \cs_gset:cpn {prop_map_inline_ \num_use:N \g_prop_inline_level_num :n} ##1##2{#2} \prop_map_function:Nc #1 {prop_map_inline_ \num_use:N \g_prop_inline_level_num :n} \num_gdecr:N \g_prop_inline_level_num } -\def_new:Npn \prop_map_inline:cN { \exp_args:Nc \prop_map_inline:NN } +% \end{macrocode} +% +% \begin{macrocode} +\cs_generate_variant:Nn\prop_map_inline:Nn {cn} % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % -% \begin{macro}{\prop_map_break:w} +% \begin{macro}{\prop_map_break:} % The break statement. % \begin{macrocode} -\let_new:NN \prop_map_break:w \use_none_delimit_by_q_stop:w +\cs_new_eq:NN \prop_map_break: \use_none_delimit_by_q_stop:w % \end{macrocode} % \end{macro} % -% Finally a bunch of compatibility commands with the old syntax: they will -% vanish soon! % \begin{macrocode} -\def:Npn \prop_put:NNn {\typeout{Warning:~name~ - changed~ to~ \string\prop_put:Nnn}\prop_put:Nnn} -\def:Npn \prop_gput:NNn {\typeout{Warning:~name~ - changed~ to~ \string\prop_gput:Nnn }\prop_gput:Nnn } -\def:Npn \prop_gput:NNo {\typeout{Warning:~name~ - changed~ to~ \string\prop_gput:Nno }\prop_gput:Nno } -\def:Npn \prop_gput:cNn {\typeout{Warning:~name~ - changed~ to~ \string\prop_gput:cnn }\prop_gput:cnn } -\def:Npn \prop_gput_if_new:NNn {\typeout{Warning:~name~ - changed~ to~ \string\prop_gput_if_new:Nnn }\prop_gput_if_new:Nnn } -\def:Npn \prop_get:NNN {\typeout{Warning:~name~ - changed~ to~ \string\prop_get:NnN }\prop_get:NnN } -\def:Npn \prop_get:cNN {\typeout{Warning:~name~ - changed~ to~ \string\prop_get:cnN }\prop_get:cnN } -\def:Npn \prop_gget:NNN {\typeout{Warning:~name~ - changed~ to~ \string\prop_gget:NnN }\prop_gget:NnN } -\def:Npn \prop_gget:cNN {\typeout{Warning:~name~ - changed~ to~ \string\prop_gget:cnN }\prop_gget:cnN } -\def:Npn \prop_get_gdel:NNN {\typeout{Warning:~name~ - changed~ to~ \string\prop_get_gdel:NnN }\prop_get_gdel:NnN } -\def:Npn \prop_del:NN {\typeout{Warning:~name~ - changed~ to~ \string\prop_del:Nn }\prop_del:Nn } -\def:Npn \prop_gdel:NN {\typeout{Warning:~name~ - changed~ to~ \string\prop_gdel:Nn }\prop_gdel:Nn } -\def:Npn \prop_if_in:NNTF {\typeout{Warning:~name~ - changed~ to~ \string\prop_if_in:NnTF }\prop_if_in:NnTF } +%</initex|package> % \end{macrocode} -% +% % Show token usage: % \begin{macrocode} -%</initex|package> %<*showmemory> %\showMemUsage %</showmemory> % \end{macrocode} % -% -% -% \begin{macrocode} -%<*unused> -\file_input_stop: -% \end{macrocode} -% -% \begin{macrocode} -%</unused> -% \end{macrocode} +% \end{implementation} +% \PrintIndex % % \endinput -% diff --git a/Master/texmf-dist/source/latex/expl3/l3quark.dtx b/Master/texmf-dist/source/latex/expl3/l3quark.dtx index 80328f6a768..c5c5a22c00c 100644 --- a/Master/texmf-dist/source/latex/expl3/l3quark.dtx +++ b/Master/texmf-dist/source/latex/expl3/l3quark.dtx @@ -1,5 +1,5 @@ % \iffalse -%% File: l3quark.dtx Copyright (C) 1990-2006 LaTeX3 project +%% File: l3quark.dtx Copyright (C) 1990-2009 LaTeX3 project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this @@ -17,7 +17,7 @@ %% %% The development version of the bundle can be found at %% -%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/ +%% http://www.latex-project.org/svnroot/experimental/trunk/ %% %% for those people who are interested. %% @@ -36,7 +36,7 @@ \RequirePackage{l3names} %</driver|package> %\fi -\GetIdInfo$Id: l3quark.dtx 761 2008-08-04 21:35:13Z morten $ +\GetIdInfo$Id: l3quark.dtx 1365 2009-05-31 17:26:17Z mittelba $ {L3 Experimental Quark Commands} %\iffalse %<*driver> @@ -44,7 +44,7 @@ \ProvidesFile{\filename.\filenameext} [\filedate\space v\fileversion\space\filedescription] %\iffalse -\documentclass{l3doc} +\documentclass[full]{l3doc} \begin{document} \DocInput{\filename.\filenameext} \end{document} @@ -60,10 +60,7 @@ % \date{\filedate} % \maketitle % -% -% \section{Quarks} -%^^A \label{sec:quarks} -% +% \begin{documentation} % % A special type of constants in \LaTeX3 are `quarks'. These are control % sequences that expand to themselves and should therefore NEVER be @@ -74,7 +71,7 @@ % 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 +% "\if_meaning:w". A set of special quark testing functions is set up % below. All the quark testing functions are expandable although the % ones testing only single tokens are much faster. % @@ -83,45 +80,37 @@ % The documentation needs some updating. % % -% \subsection{Functions} +% \section{Functions} % -% \begin{function}{% -% \quark_new:N | -% } +% \begin{function}{ \quark_new:N } % \begin{syntax} -% "\quark_new:N" <quark> +% "\quark_new:N" <quark> % \end{syntax} % Defines <quark> to be a new constant of type "quark". % \end{function} % % \begin{function}{% -% \quark_if_no_value_p:n | -% \quark_if_no_value:nTF | -% \quark_if_no_value:nF | -% \quark_if_no_value:nT | -% \quark_if_no_value_p:N | -% \quark_if_no_value:NTF | -% \quark_if_no_value:NT | -% \quark_if_no_value:NF | +% \quark_if_no_value_p:n / (EXP) | +% \quark_if_no_value:n / (TF)(EXP) | +% \quark_if_no_value_p:N / (EXP) | +% \quark_if_no_value:N / (TF)(EXP) | % } % \begin{syntax} -% "\quark_if_no_value:nTF" "{"<token list>"}" -% " {"<true code>"}{"<false code>"}" -% "\quark_if_no_value:NTF" <tlp> -% " {"<true code>"}{"<false code>"}" +% "\quark_if_no_value:nTF" \Arg{token list} \Arg{true code} \Arg{false code} +% "\quark_if_no_value:NTF" <tl var.> \Arg{true code} \Arg{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 +% If <token list> to be tested is stored in a token list variable 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 +% value directly with "\if_meaning:w". All those cases are faster then % "\quark_if_no_value:nTF" so should be preferred.\footnote{Clarify % semantic of the ``n'' case \ldots{} i think it is not implement % according to what we originally intended /FMi} % % \begin{texnote} -% But be aware of the fact that "\if_meaning:NN" can result in an +% But be aware of the fact that "\if_meaning:w" 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 @@ -131,14 +120,11 @@ % \end{function} % % \begin{function}{% -% \quark_if_nil_p:N | -% \quark_if_nil:NTF | -% \quark_if_nil:NT | -% \quark_if_nil:NF | +% \quark_if_nil_p:N / (EXP) | +% \quark_if_nil:N / (TF)(EXP) | % } % \begin{syntax} -% "\quark_if_nil:NTF" <token> -% " {"<true code>"}{"<false code>"}" +% "\quark_if_nil:NTF" <token> \Arg{true code} \Arg{false code} % \end{syntax} % This tests whether or not <token> is equal to the quark % "\q_nil". @@ -149,18 +135,15 @@ % % % \begin{function}{% -% \quark_if_nil_p:n | -% \quark_if_nil:nTF | -% \quark_if_nil:nT | -% \quark_if_nil:nF | -% \quark_if_nil_p:o | -% \quark_if_nil:oTF | -% \quark_if_nil:oT | -% \quark_if_nil:oF | +% \quark_if_nil_p:n / (EXP) | +% \quark_if_nil_p:V / (EXP) | +% \quark_if_nil_p:o / (EXP) | +% \quark_if_nil:n / (TF)(EXP) | +% \quark_if_nil:V / (TF)(EXP) | +% \quark_if_nil:o / (TF)(EXP) | % } % \begin{syntax} -% "\quark_if_nil:nTF" "{"<tokens>"}" -% "{"<true code>"}{"<false code>"}" +% "\quark_if_nil:nTF" \Arg{tokens} \Arg{true code} \Arg{false code} % \end{syntax} % This tests whether or not <tokens> is equal to the quark % "\q_nil". @@ -169,7 +152,7 @@ % "\q_nil" as an end marker. % \end{function} % -% \subsection{Recursion} +% \section{Recursion} % % This module provides a uniform interface to intercepting and % terminating loops as when one is doing tail recursion. The building @@ -188,12 +171,12 @@ % \end{variable} % % \begin{function}{% -% \quark_if_recursion_tail_stop:N | -% \quark_if_recursion_tail_stop:n | -% \quark_if_recursion_tail_stop:o | +% \quark_if_recursion_tail_stop:N / (EXP) | +% \quark_if_recursion_tail_stop:n / (EXP) | +% \quark_if_recursion_tail_stop:o / (EXP) | % } % \begin{syntax} -% "\quark_if_recursion_tail_stop:n" "{"<list element>"}" \\ +% "\quark_if_recursion_tail_stop:n" \Arg{list element} \\ % "\quark_if_recursion_tail_stop:N" <list element> % \end{syntax} % This tests whether or not <list element> is equal to @@ -205,26 +188,26 @@ % to use the "n". If you wish to use the "N" form you \emph{must} % ensure it is really a single token such as if you have % \begin{quote} -% "\tlp_set:Nn \l_tmpa_tlp {" <list element> "}" +% "\tl_set:Nn \l_tmpa_tl {" <list element> "}" % \end{quote} % \end{function} % % \begin{function}{% -% \quark_if_recursion_tail_stop_do:Nn | -% \quark_if_recursion_tail_stop_do:nn | -% \quark_if_recursion_tail_stop_do:on | +% \quark_if_recursion_tail_stop_do:Nn / (EXP) | +% \quark_if_recursion_tail_stop_do:nn / (EXP) | +% \quark_if_recursion_tail_stop_do:on / (EXP) | % } % \begin{syntax} -% "\quark_if_recursion_tail_stop_do:nn"\\ -% "{"<list element>"}" "{" <post action> "}" +% "\quark_if_recursion_tail_stop_do:nn" +% ~~~~\Arg{list element} \Arg{post action} % "\quark_if_recursion_tail_stop_do:Nn" -% <list element> "{" <post action> "}" +% ~~~~<list element> \Arg{post action} % \end{syntax} % Same as "\quark_if_recursion_tail_stop:N" except here the second % argument is executed after the recursion has been terminated. % \end{function} % -% \subsection{Constants} +% \section{Constants} % % \begin{variable}{\q_no_value} The canonical `missing value quark' % that is returned by certain functions to denote that a requested value @@ -240,30 +223,42 @@ % This constant represent the nil pointer in pointer structures. % \end{variable} % -% \StopEventually{} +% \begin{variable}{\q_error} +% Delimits the end of +% the computation for purposes of error recovery. +% \end{variable} +% +% \begin{variable}{\q_mark} +% Used in parameter text when we need a scanning boundary that is +% distinct from |\q_stop|. +% \end{variable} % -% \subsection{The Implementation} +% \end{documentation} +% +% \begin{implementation} +% +% \section{\pkg{l3quark} 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>\ProvidesExplPackage -%<package> {\filename}{\filedate}{\fileversion}{\filedescription} -%<package>\RequirePackage{l3expan}\par +%<*package> +\ProvidesExplPackage + {\filename}{\filedate}{\fileversion}{\filedescription} +\package_check_loaded_expl: +%</package> %<*initex|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}} +\cs_new_nopar:Npn \quark_new:N #1{\tl_new:Nn #1{#1}} % \end{macrocode} % \end{macro} % -% \begin{macro}{\q_stop} -% \begin{macro}{\q_no_value} -% \begin{macro}{\q_nil} +% \begin{macro}{\q_stop,\q_no_value,\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. @@ -273,11 +268,8 @@ \quark_new:N \q_nil % \end{macrocode} % \end{macro} -% \end{macro} -% \end{macro} % -% \begin{macro}{\q_error} -% \begin{macro}{\q_mark} +% \begin{macro}{\q_error,\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 @@ -287,11 +279,9 @@ \quark_new:N\q_mark % \end{macrocode} % \end{macro} -% \end{macro} % % -% \begin{macro}{\q_recursion_tail} -% \begin{macro}{\q_recursion_stop} +% \begin{macro}{\q_recursion_tail,\q_recursion_stop} % Quarks for ending recursions. Only ever used there! % |\q_recursion_tail| is appended to whatever list structure we are % doing recursion on, meaning it is added as a proper list item with @@ -302,7 +292,6 @@ \quark_new:N\q_recursion_stop % \end{macrocode} % \end{macro} -% \end{macro} % % \begin{macro}{\quark_if_recursion_tail_stop:n} % \begin{macro}{\quark_if_recursion_tail_stop:N} @@ -312,20 +301,18 @@ % marker every time we do this kind of task. Also, if the recursion % end marker is found, we wrap things up and finish. % \begin{macrocode} -\def_long_new:Npn \quark_if_recursion_tail_stop:n #1 { - \exp_after:NN\if_meaning:NN +\cs_new:Npn \quark_if_recursion_tail_stop:n #1 { + \exp_after:wN\if_meaning:w \quark_if_recursion_tail_aux:w #1?\q_nil\q_recursion_tail\q_recursion_tail - \exp_after:NN \use_none_delimit_by_q_recursion_stop:w + \exp_after:wN \use_none_delimit_by_q_recursion_stop:w \fi: } -\def_long_new:Npn \quark_if_recursion_tail_stop:N #1 { - \if_meaning:NN#1\q_recursion_tail - \exp_after:NN \use_none_delimit_by_q_recursion_stop:w +\cs_new:Npn \quark_if_recursion_tail_stop:N #1 { + \if_meaning:w#1\q_recursion_tail + \exp_after:wN \use_none_delimit_by_q_recursion_stop:w \fi: } -\def_new:Npn \quark_if_recursion_tail_stop:o{ - \exp_args:No\quark_if_recursion_tail_stop:n -} +\cs_generate_variant:Nn \quark_if_recursion_tail_stop:n {o} % \end{macrocode} % \end{macro} % \end{macro} @@ -335,77 +322,52 @@ % \begin{macro}{\quark_if_recursion_tail_stop_do:Nn} % \begin{macro}{\quark_if_recursion_tail_stop_do:on} % \begin{macrocode} -\def_long_new:Npn \quark_if_recursion_tail_stop_do:nn #1#2 { - \exp_after:NN\if_meaning:NN +\cs_new:Npn \quark_if_recursion_tail_stop_do:nn #1#2 { + \exp_after:wN\if_meaning:w \quark_if_recursion_tail_aux:w #1?\q_nil\q_recursion_tail\q_recursion_tail - \exp_after:NN \use_arg_i_delimit_by_q_recursion_stop:nw + \exp_after:wN \use_i_delimit_by_q_recursion_stop:nw \else: - \exp_after:NN\use_none:n + \exp_after:wN\use_none:n \fi: {#2} } -\def_long_new:Npn \quark_if_recursion_tail_stop_do:Nn #1#2 { - \if_meaning:NN #1\q_recursion_tail - \exp_after:NN \use_arg_i_delimit_by_q_recursion_stop:nw +\cs_new:Npn \quark_if_recursion_tail_stop_do:Nn #1#2 { + \if_meaning:w #1\q_recursion_tail + \exp_after:wN \use_i_delimit_by_q_recursion_stop:nw \else: - \exp_after:NN\use_none:n + \exp_after:wN\use_none:n \fi: {#2} } -\def_new:Npn \quark_if_recursion_tail_stop_do:on{ - \exp_args:No\quark_if_recursion_tail_stop_do:nn -} +\cs_generate_variant:Nn \quark_if_recursion_tail_stop_do:nn {on} % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % -% \begin{macro}{\quark_if_recursion_tail_aux:w} -% \begin{macro}{\use_none_delimit_by_q_recursion_stop:w} -% \begin{macro}{\use_arg_i_delimit_by_q_recursion_stop:nw} -% Helper macros for picking up the first token of a list to see if -% it is "\q_recursion_tail" and to stop the recursion. +% \begin{macro}[aux]{\quark_if_recursion_tail_aux:w} % \begin{macrocode} -\def_long_new:Npn \quark_if_recursion_tail_aux:w - #1#2\q_nil\q_recursion_tail{#1} -\def_long_new:Npn\use_none_delimit_by_q_recursion_stop:w - #1\q_recursion_stop {} -\def_long_new:Npn\use_arg_i_delimit_by_q_recursion_stop:nw - #1#2\q_recursion_stop {#1} +\cs_new:Npn \quark_if_recursion_tail_aux:w #1#2 \q_nil \q_recursion_tail {#1} % \end{macrocode} % \end{macro} -% \end{macro} -% \end{macro} -% % -% \begin{macro}{\quark_if_no_value_p:N} -% \begin{macro}{\quark_if_no_value:NTF} -% \begin{macro}{\quark_if_no_value:NT} -% \begin{macro}{\quark_if_no_value:NF} -% \begin{macro}{\quark_if_no_value_p:n} -% \begin{macro}{\quark_if_no_value:nTF} -% \begin{macro}{\quark_if_no_value:nT} -% \begin{macro}{\quark_if_no_value:nF} -% \begin{macro}{\quark_if_no_value:nFT} +% \begin{macro}{\quark_if_no_value_p:N,\quark_if_no_value_p:n} +% \begin{macro}[TF]{\quark_if_no_value:N,\quark_if_no_value:n} % Here we test if we found a special quark as the first argument. -% \begin{macrocode} -\def_long_test_function_new:npn {quark_if_no_value:N} #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} -\def_long_new:Npn \quark_if_no_value_p:N #1{ - \if_meaning:NN \q_no_value #1 \c_true - \else: \c_false \fi: +\prg_new_conditional:Nnn \quark_if_no_value:N {p,TF,T,F} { + \if_meaning:w \q_no_value #1 + \prg_return_true: \else: \prg_return_false: \fi: } % \end{macrocode} % We also provide an |n| type. If run under a sufficiently new % pdf\eTeX, it uses a built-in primitive for string comparisons, % otherwise it uses the slower |\str_if_eq_var_p:nf| function. In the -% latter case it would be faster to use a temporary token list pointer +% latter case it would be faster to use a temporary token list variable % but it would render the function non-expandable. Using the pdf\eTeX\ % primitive is the preferred approach. Note that we have to add a % manual space token in the first part of the comparison, otherwise it @@ -415,156 +377,87 @@ % latter test function and unfortunately this example turned up in one % application. % \begin{macrocode} -\cs_if_really_free:cTF{pdf_strcmp:D}{ - \def_long_new:Npn \quark_if_no_value_p:n #1{ - \if:w \exp_args:No \str_if_eq_var_p:nf -%<package> {\token_to_string:N\q_no_value\space} -%<initex> {\token_to_string:N\q_no_value\text_put_sp:} - {\tlist_to_str:n{#1}} - \c_true - \else: - \c_false +\cs_if_exist:cTF {pdf_strcmp:D} +{ + \prg_new_conditional:Nnn \quark_if_no_value:n {p,TF,T,F} { + \if_num:w \pdf_strcmp:D + {\exp_not:N \q_no_value} + {\exp_not:n{#1}} = \c_zero + \prg_return_true: \else: \prg_return_false: \fi: } } { - \def_long_new:Npn \quark_if_no_value_p:n #1{ - \if_num:w - \pdf_strcmp:D {\exp_not:N \q_no_value}{\exp_not:n{#1}}=\c_zero - \c_true \else: \c_false \fi: - } -} -\def_long_test_function_new:npn {quark_if_no_value:n} #1 { - \if:w \quark_if_no_value_p:n{#1}} -% \end{macrocode} -% We also define a version where the true and false code is ordered -% differently. -% \begin{macrocode} -\def_long:Npn \quark_if_no_value:nFT #1{ - \if:w \quark_if_no_value_p:n{#1} - \exp_after:NN\use_arg_ii:nn - \else: - \exp_after:NN\use_arg_i:nn + \prg_new_conditional:Nnn \quark_if_no_value:n {p,TF,T,F} { + \exp_args:NNo + \if_predicate:w \str_if_eq_var_p:nf + {\token_to_str:N\q_no_value\iow_space:} + {\tl_to_str:n{#1}} + \prg_return_true: \else: \prg_return_false: \fi: + } } % \end{macrocode} % \end{macro} % \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} % % \begin{macro}{\quark_if_nil_p:N} -% \begin{macro}{\quark_if_nil:NTF} -% \begin{macro}{\quark_if_nil:NT} -% \begin{macro}{\quark_if_nil:NF} +% \begin{macro}[TF]{\quark_if_nil:N} % A function to check for the presence of |\q_nil|. % \begin{macrocode} -\def_long_new:Npn \quark_if_nil_p:N #1{ - \if_meaning:NN \q_nil #1 \c_true - \else: \c_false \fi: +\prg_new_conditional:Nnn \quark_if_nil:N {p,TF,T,F} { + \if_meaning:w \q_nil #1 \prg_return_true: \else: \prg_return_false: \fi: } -\def_long_test_function_new:npn {quark_if_nil:N}#1{ - \if_meaning:NN\q_nil#1} % \end{macrocode} % \end{macro} % \end{macro} -% \end{macro} -% \end{macro} % -% \begin{macro}{\quark_if_nil_p:n} -% \begin{macro}{\quark_if_nil:nTF} -% \begin{macro}{\quark_if_nil:nT} -% \begin{macro}{\quark_if_nil:nF} -% \begin{macro}{\quark_if_nil_p:o} -% \begin{macro}{\quark_if_nil:oTF} -% \begin{macro}{\quark_if_nil:oT} -% \begin{macro}{\quark_if_nil:oF} +% \begin{macro}{\quark_if_nil_p:n,\quark_if_nil_p:V,\quark_if_nil_p:o} +% \begin{macro}[TF]{\quark_if_nil:n,\quark_if_nil:V,\quark_if_nil:o} % A function to check for the presence of |\q_nil|. % \begin{macrocode} -\cs_if_really_free:cTF{pdf_strcmp:D}{ - \def_long_new:Npn \quark_if_nil_p:n #1{ - \if:w \exp_args:No \str_if_eq_var_p:nf -%<package> {\token_to_string:N\q_nil\space} -%<initex> {\token_to_string:N\q_nil\text_put_sp:} - {\tlist_to_str:n{#1}} - \c_true - \else: - \c_false +\cs_if_exist:cTF {pdf_strcmp:D} { + \prg_new_conditional:Nnn \quark_if_nil:n {p,TF,T,F} { + \if_num:w \pdf_strcmp:D + {\exp_not:N \q_nil} + {\exp_not:n{#1}} = \c_zero + \prg_return_true: \else: \prg_return_false: \fi: } } { - \def_long_new:Npn \quark_if_nil_p:n #1{ - \if_num:w - \pdf_strcmp:D {\exp_not:N \q_nil}{\exp_not:n{#1}}=\c_zero - \c_true \else: \c_false \fi: + \prg_new_conditional:Nnn \quark_if_nil:n {p,TF,T,F} { + \exp_args:NNo + \if_predicate:w \str_if_eq_var_p:nf + {\token_to_str:N\q_nil\iow_space:} + {\tl_to_str:n{#1}} + \prg_return_true: \else: \prg_return_false: + \fi: } } -\def_long_test_function_new:npn {quark_if_nil:n} #1 { - \if:w \quark_if_nil_p:n{#1}} -\def_new:Npn \quark_if_nil_p:o{\exp_args:No\quark_if_nil_p:n} -\def_new:Npn \quark_if_nil:oTF{\exp_args:No\quark_if_nil:nTF} -\def_new:Npn \quark_if_nil:oT {\exp_args:No\quark_if_nil:nT} -\def_new:Npn \quark_if_nil:oF {\exp_args:No\quark_if_nil:nF} +\cs_generate_variant:Nn \quark_if_nil_p:n {V} +\cs_generate_variant:Nn \quark_if_nil:nTF {V} +\cs_generate_variant:Nn \quark_if_nil:nT {V} +\cs_generate_variant:Nn \quark_if_nil:nF {V} +\cs_generate_variant:Nn \quark_if_nil_p:n {o} +\cs_generate_variant:Nn \quark_if_nil:nTF {o} +\cs_generate_variant:Nn \quark_if_nil:nT {o} +\cs_generate_variant:Nn \quark_if_nil:nF {o} % \end{macrocode} % \end{macro} % \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} +% +% % % Show token usage: % \begin{macrocode} -%</initex|package> + %<*showmemory> \showMemUsage %</showmemory> % \end{macrocode} % -% \endinput -% -% $Log$ -% Revision 1.22 2006/07/30 14:39:02 morten -% Changed all quark functions to be expandable regardless of whether -% \pdfstrcmp is available. -% -% Revision 1.21 2006/07/25 15:34:21 morten -% Added the non-expandable \quark_if_nil:nTF plus variants. -% -% Revision 1.20 2006/07/23 13:43:47 morten -% Fixed minor bug in \quark_if_no_value_p:n -% -% Revision 1.19 2006/03/20 18:26:38 braams -% Updated the copyright notice (2006) and demoted all implementation -% sections to subsections and so on to clean up the toc for source3.tex -% -% Revision 1.18 2006/01/04 01:18:31 morten -% Changed \quark_if_no_value:nTF to be expandable. Added a few predicate -% functions and updated documentation. -% -% Revision 1.17 2005/12/27 10:04:41 morten -% Minor changes plus changed RCS information retrieval -% -% Revision 1.16 2005/10/27 14:12:28 morten -% Added gobble-until-quark functions. -% -% Revision 1.15 2005/07/14 18:50:31 morten -% Added \quark_if_nil:NF -% -% Revision 1.14 2005/04/06 13:55:57 morten -% Fixed \quark_if_nil:NTF -% -% Revision 1.13 2005/03/16 22:35:57 braams -% Added the tweaks necessary to be able to load with initex -% -% Revision 1.12 2005/03/11 21:41:27 braams -% Fixed the use of RCS information; added \StopEventually +% \end{implementation} +% \PrintIndex % +% \endinput diff --git a/Master/texmf-dist/source/latex/expl3/l3seq.dtx b/Master/texmf-dist/source/latex/expl3/l3seq.dtx index 259d5630c43..139e5038579 100644 --- a/Master/texmf-dist/source/latex/expl3/l3seq.dtx +++ b/Master/texmf-dist/source/latex/expl3/l3seq.dtx @@ -1,5 +1,5 @@ % \iffalse -%% File: l3seq.dtx Copyright (C) 1990-2006 LaTeX3 project +%% File: l3seq.dtx Copyright (C) 1990-2009 LaTeX3 project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this @@ -17,7 +17,7 @@ %% %% The development version of the bundle can be found at %% -%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/ +%% http://www.latex-project.org/svnroot/experimental/trunk/ %% %% for those people who are interested. %% @@ -36,7 +36,7 @@ \RequirePackage{l3names} %</driver|package> %\fi -\GetIdInfo$Id: l3seq.dtx 621 2007-09-01 20:14:19Z morten $ +\GetIdInfo$Id: l3seq.dtx 1362 2009-05-28 20:19:21Z joseph $ {L3 Experimental sequences and stacks} %\iffalse %<*driver> @@ -44,7 +44,7 @@ \ProvidesFile{\filename.\filenameext} [\filedate\space v\fileversion\space\filedescription] %\iffalse -\documentclass{l3doc} +\documentclass[full]{l3doc} \begin{document} \DocInput{\filename.\filenameext} \end{document} @@ -60,9 +60,7 @@ % \date{\filedate} % \maketitle % -% -% -% \section{Sequences} +% \begin{documentation} % % \LaTeX3 implements a data type called `sequences'. These are special % token lists that can be accessed via special function on the `left'. @@ -73,8 +71,8 @@ % 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 \m{tlp} assume -% that the \m{tlp} is local. See remarks below if you need a global +% All functions that return items from a sequence in some \m{tl var.}~assume +% that the \m{tl var.}~is local. See remarks below if you need a global % returned value. % % The defined functions are not orthogonal in the sense that every @@ -87,130 +85,180 @@ % like "\seq_push:Nn" which has the same effect. Maybe one should % therefore remove the ``left'' functions totally. % -% \subsection{Functions} +% \section{Functions for creating/initialising sequences} % -% \begin{function}{% -% \seq_new:N | -% \seq_new:c | -% } +% \begin{function}{ \seq_new:N | +% \seq_new:c } % \begin{syntax} % "\seq_new:N" <sequence> % \end{syntax} -% Defines <sequence> to be a variable of type sequences. +% Defines <sequence> to be a variable of type "seq". % \end{function} % -% \begin{function}{% -% \seq_clear:N | -% \seq_clear:c | +% \begin{function}{ \seq_clear:N | +% \seq_clear:c | % \seq_gclear:N | -% \seq_gclear:c | -% } +% \seq_gclear:c } % \begin{syntax} % "\seq_clear:N" <sequence> % \end{syntax} % These functions locally or globally clear <sequence>. % \end{function} % +% \begin{function}{ \seq_clear_new:N | +% \seq_clear_new:c | +% \seq_gclear_new:N | +% \seq_gclear_new:c } +% \begin{syntax} +% "\seq_clear_new:N" <sequence> +% \end{syntax} +% These functions locally or globally clear <sequence> if it exists or +% otherwise allocates it. +% \end{function} +% +% \begin{function}{ \seq_set_eq:NN | +% \seq_set_eq:cN | +% \seq_set_eq:Nc | +% \seq_set_eq:cc } +% \begin{syntax} +% "\seq_set_eq:NN" <seq1> <seq2> +% \end{syntax} +% Function that locally makes <seq1> identical to <seq2>. +% \end{function} +% +% \begin{function}{ \seq_gset_eq:NN | +% \seq_gset_eq:cN | +% \seq_gset_eq:Nc | +% \seq_gset_eq:cc } +% \begin{syntax} +% "\seq_gset_eq:NN" <seq1> <seq2> +% \end{syntax} +% Function that globally makes <seq1> identical to <seq2>. +% \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} +% +% \section{Adding data to sequences} +% % \begin{function}{% % \seq_put_left:Nn | +% \seq_put_left:NV | % \seq_put_left:No | % \seq_put_left:Nx | % \seq_put_left:cn | -% \seq_put_right:Nn | -% \seq_put_right:No | -% \seq_put_right:Nx | +% \seq_put_left:cV | +% \seq_put_left:co | % } % \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. +% of <sequence>. <token list> might get expanded before +% appending according to the variant. % \end{function} % % \begin{function}{% -% \seq_gput_left:Nn | -% \seq_gput_right:Nn | -% \seq_gput_right:Nc | -% \seq_gput_right:No | -% \seq_gput_right:cn | -% \seq_gput_right:co | -% \seq_gput_right:cc | +% \seq_put_right:Nn | +% \seq_put_right:NV | +% \seq_put_right:No | +% \seq_put_right:Nx | +% \seq_put_right:cn | +% \seq_put_right:cV | +% \seq_put_right:co | % } % \begin{syntax} -% "\seq_gput_left:Nn" <sequence> <token list> +% "\seq_put_right:Nn" <sequence> <token list> % \end{syntax} -% Globally appends <token list> as a single item to the left -% or right of <sequence>. +% Locally appends <token list> as a single item to the right +% of <sequence>. <token list> might get expanded before +% appending according to the variant. % \end{function} % % \begin{function}{% -% \seq_get:NN | -% \seq_get:cN | +% \seq_gput_left:Nn | +% \seq_gput_left:NV | +% \seq_gput_left:No | +% \seq_gput_left:Nx | +% \seq_gput_left:cn | +% \seq_gput_left:cV | +% \seq_gput_left:co | % } % \begin{syntax} -% "\seq_get:NN" <sequence> <tlp> +% "\seq_gput_left:Nn" <sequence> <token list> % \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. +% Globally appends <token list> as a single item to the left +% of <sequence>. % \end{function} % % \begin{function}{% -% \seq_set_eq:NN +% \seq_gput_right:Nn | +% \seq_gput_right:NV | +% \seq_gput_right:No | +% \seq_gput_right:Nx | +% \seq_gput_right:cn | +% \seq_gput_right:cV | +% \seq_gput_right:co | % } % \begin{syntax} -% "\seq_set_eq:NN" <seq1> <seq2> +% "\seq_gput_right:Nn" <sequence> <token list> % \end{syntax} -% Function that locally makes <seq1> identical to <seq2>. +% Globally appends <token list> as a single item to the right +% of <sequence>. % \end{function} % -% -% % \begin{function}{% -% \seq_gset_eq:NN | -% \seq_gset_eq:cN | -% \seq_gset_eq:Nc | -% \seq_gset_eq:cc +% \seq_gput_right:Nc | % } -% \begin{syntax} -% "\seq_gset_eq:NN" <seq1> <seq2> -% \end{syntax} -% Function that globally makes <seq1> identical to <seq2>. +% Variant of the above used in the |xor| package. +% Will probably be moved soon to that package. (Sep 2008) % \end{function} % +% \section{Working with sequences} +% % \begin{function}{% -% \seq_gconcat:NNN | -% \seq_gconcat:ccc | +% \seq_get:NN | +% \seq_get:cN | % } % \begin{syntax} -% "\seq_gconcat:NNN" <seq1> <seq2> <seq3> +% "\seq_get:NN" <sequence> <tl var.> % \end{syntax} -% Function that conatenates <seq2> and <seq3> and globally assigns the -% result to <seq1>. +% Functions that locally assign the left-most item of <sequence> to the +% token list variable <tl var.>. 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_tl" \\ +% "\tl_gset_eq:NN" <global tl var.> "\l_tmpa_tl" +% \end{quote} +% But if this kind of construction is used often enough a separate +% function should be provided. % \end{function} % +% % \begin{function}{\seq_map_variable:NNn | % \seq_map_variable:cNn % } % \begin{syntax} -% "\seq_map_variable:NNn" <sequence> <tlp> "{" <code using tlp> "}" +% "\seq_map_variable:NNn" <sequence> <tl var.> \Arg{code using tl var.} % \end{syntax} -% Every element in <sequence> is assigned to <tlp> and then <code -% using tlp> is executed. The operation is not expandable which means +% Every element in <sequence> is assigned to <tl var.> and then <code +% using tl var.> is executed. The operation is not expandable which means % that it can't be used within write operations etc. However, this % function can be nested which the others can't. % \end{function} % -% \begin{function}{\seq_map:NN} +% \begin{function}{ \seq_map_function:NN | +% \seq_map_function:cN } % \begin{syntax} -% "\seq_map:NN" <sequences> <function> +% "\seq_map_function:NN" <sequence> <function> % \end{syntax} % This function applies <function> (which must be a function with one % argument) to every item of <sequence>. <function> is not executed @@ -226,55 +274,67 @@ % \seq_map_inline:cn % } % \begin{syntax} -% "\seq_map_inline:Nn" <sequence> "{" <inline function> "}" +% "\seq_map_inline:Nn" <sequence> \Arg{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 +% 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_show:N | +% \seq_show:c } +% \begin{syntax} +% "\seq_show:N" <sequence> +% \end{syntax} +% Function that pauses the compilation and displays <seq> in the terminal +% output and in the log file. (Usually used for diagnostic purposes.) +% \end{function} +% +% \begin{function}{ \seq_display:N | +% \seq_display:c } +% \begin{syntax} +% "\seq_display:N" <sequence> +% \end{syntax} +% As with "\seq_show:N" but pretty prints the output one line per element. +% \end{function} +% +% \section{Predicates and conditionals} % -% \begin{function}{\seq_if_empty_p:N} +% \begin{function}{ \seq_if_empty_p:N / (EXP) | +% \seq_if_empty_p:c / (EXP) } % \begin{syntax} % "\seq_if_empty_p:N" <sequence> % \end{syntax} % This predicate returns `true' if <sequence> is `empty' i.e., doesn't -% contain any tokens. +% contain any items. Note that this is `false' even if the <sequence> only +% contains a single empty item. % \end{function} % -% \begin{function}{% -% \seq_if_empty:NTF | -% \seq_if_empty:cTF | -% \seq_if_empty:NF | -% \seq_if_empty:cF | -% } +% \begin{function}{ \seq_if_empty:N / (TF) | +% \seq_if_empty:c / (TF) } % \begin{syntax} -% "\seq_if_empty:NTF" <sequence> "{" <true code> "}{" <false code> "}" +% "\seq_if_empty:NTF" <sequence> \Arg{true code} \Arg{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 | -% \seq_if_in:cxTF | -% \seq_if_in:NnF | -% \seq_if_in:cnF | -% } +% \begin{function}{ \seq_if_in:Nn / (TF) | +% \seq_if_in:cn / (TF) | +% \seq_if_in:cV / (TF) | +% \seq_if_in:co / (TF) | +% \seq_if_in:cx / (TF) } % \begin{syntax} -% "\seq_if_in:NnTF" <sequ> "{" <item> "}{" <true code> "}{" <false code> "}" +% "\seq_if_in:NnTF" <sequence> \Arg{item} \Arg{true code} \Arg{false code} % \end{syntax} -% Function that tests if <item> is in <sequ>. Depending on the result +% Functions that test if <item> is in <sequence>. Depending on the result % either <true code> or <false code> is executed. % \end{function} % -% \subsection{Internal functions} +% \section{Internal functions} % % \begin{function}{\seq_if_empty_err:N} % \begin{syntax} @@ -285,9 +345,9 @@ % % \begin{function}{\seq_pop_aux:nnNN} % \begin{syntax} -% "\seq_pop_aux:nnNN" <assign1> <assign2> <sequence> <tlp> +% "\seq_pop_aux:nnNN" <assign1> <assign2> <sequence> <tl var.> % \end{syntax} -% Function that assigns the left-most item of <sequence> to <tlp> using +% Function that assigns the left-most item of <sequence> to <tl var.> using % <assign1> and assigns the tail to <sequence> using <assign2>. This % function could be used to implement a global return function. % \end{function} @@ -302,8 +362,12 @@ % meant for direct use. % \end{function} % -% \begin{function}{% -% \seq_elt:w | +% \begin{function}{ \seq_map_break: | \seq_map_break:n } +% Functions used to implement mapping 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 @@ -311,27 +375,28 @@ % sequence. % \end{function} % -% \section{Sequence Stacks} +% \section{Functions for `Sequence Stacks'} % % Special sequences in \LaTeX3 are `stacks' with their usual operations -% of`push', `pop', and `top'. They are internally implemented as +% of `push', `pop', and `top'. They are internally implemented as % sequences and share some of the functions (like "\seq_new:N" etc.) % -% \subsection{Functions} -% % \begin{function}{% % \seq_push:Nn | +% \seq_push:NV | % \seq_push:No | % \seq_push:cn | % \seq_gpush:Nn | +% \seq_gpush:NV | % \seq_gpush:No | +% \seq_gpush:Nv | % \seq_gpush:cn | % } % \begin{syntax} -% "\seq_push:Nn" <stack> "{" <token list> "}" +% "\seq_push:Nn" <stack> \Arg{token list} % \end{syntax} % Locally or globally pushes <token list> as a single item onto the -% <stack>. <token list> might get expanded before the operation. +% <stack>. % \end{function} % % \begin{function}{% @@ -341,10 +406,10 @@ % \seq_gpop:cN | % } % \begin{syntax} -% "\seq_pop:NN" <stack> <tlp> +% "\seq_pop:NN" <stack> <tl var.> % \end{syntax} -% Functions that assign the top item of <stack> to the token -% list pointer <tlp> and removes it from <stack>! +% Functions that assign the top item of <stack> to <tl var.> +% and removes it from <stack>! % \end{function} % % \begin{function}{% @@ -352,34 +417,29 @@ % \seq_top:cN | % } % \begin{syntax} -% "\seq_top:NN" <stack> <tlp> +% "\seq_top:NN" <stack> <tl var.> % \end{syntax} -% Functions that locally assign the top item of <stack> to the token -% list pointer <tlp>. Item is not removed from <stack>! +% Functions that locally assign the top item of <stack> to the <tl var.>. +% Item is \emph{not} removed from <stack>! % \end{function} % -% \subsection{Predicates and conditionals} -% -% Use "seq" functions. +% \end{documentation} % -% \StopEventually{} +% \begin{implementation} % -% \subsection {Implementation} +% \section{\pkg{l3seq} implementation} % -% -% We start by ensuring that the required packages are loaded. % \begin{macrocode} -%<package>\ProvidesExplPackage -%<package> {\filename}{\filedate}{\fileversion}{\filedescription} -%<package&!check>\RequirePackage{l3quark} -%<package&!check>\RequirePackage{l3tlp} -%<package&check>\RequirePackage{l3chk} -%<package>\RequirePackage{l3expan} +%<*package> +\ProvidesExplPackage + {\filename}{\filedate}{\fileversion}{\filedescription} +\package_check_loaded_expl: +%</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 +% |\seq_elt:w| \meta{text$\sb{n}$} \ldots'. We use explicit delimiters % instead of braces around \m{text} to allow efficient searching for % an item in the sequence. % @@ -388,19 +448,20 @@ % We allocate the delimiters and make them errors if executed. % \begin{macrocode} %<*initex|package> -\let_new:NN \seq_elt:w \ERROR -\let_new:NN \seq_elt_end: \ERROR +\cs_new:Npn \seq_elt:w {\ERROR} +\cs_new:Npn \seq_elt_end: {\ERROR} % \end{macrocode} % \end{macro} % \end{macro} % +% \subsection{Allocating and initialisation} % % \begin{macro}{\seq_new:N} % \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} +\cs_new_eq:NN \seq_new:N \tl_new:N +\cs_new_eq:NN \seq_new:c \tl_new:c % \end{macrocode} % \end{macro} % \end{macro} @@ -411,10 +472,10 @@ % \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 +\cs_new_eq:NN \seq_clear:N \tl_clear:N +\cs_new_eq:NN \seq_clear:c \tl_clear:c +\cs_new_eq:NN \seq_gclear:N \tl_gclear:N +\cs_new_eq:NN \seq_gclear:c \tl_gclear:c % \end{macrocode} % \end{macro} % \end{macro} @@ -427,128 +488,248 @@ % \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 +\cs_new_eq:NN \seq_clear_new:N \tl_clear_new:N +\cs_new_eq:NN \seq_clear_new:c \tl_clear_new:c +\cs_new_eq:NN \seq_gclear_new:N \tl_gclear_new:N +\cs_new_eq:NN \seq_gclear_new:c \tl_gclear_new:c +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\seq_set_eq:NN} +% \begin{macro}{\seq_set_eq:Nc} +% \begin{macro}{\seq_set_eq:cN} +% \begin{macro}{\seq_set_eq:cc} +% We can set one "seq" equal to another. +% \begin{macrocode} +\cs_new_eq:NN \seq_set_eq:NN \cs_set_eq:NN +\cs_new_eq:NN \seq_set_eq:cN \cs_set_eq:cN +\cs_new_eq:NN \seq_set_eq:Nc \cs_set_eq:Nc +\cs_new_eq:NN \seq_set_eq:cc \cs_set_eq:cc % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % -% \begin{macro}{\seq_if_empty_p:N} -% A predicate which evaluates to |\c_true| iff the sequence is empty. +% \begin{macro}{\seq_gset_eq:NN} +% \begin{macro}{\seq_gset_eq:cN} +% \begin{macro}{\seq_gset_eq:Nc} +% \begin{macro}{\seq_gset_eq:cc} +% And of course globally which seems to be needed far more +% often.\footnote{To save a bit of space these functions could be made +% identical to those from the tl or clist module.} % \begin{macrocode} -\let_new:NN \seq_if_empty_p:N \tlp_if_empty_p:N +\cs_new_eq:NN \seq_gset_eq:NN \cs_gset_eq:NN +\cs_new_eq:NN \seq_gset_eq:cN \cs_gset_eq:cN +\cs_new_eq:NN \seq_gset_eq:Nc \cs_gset_eq:Nc +\cs_new_eq:NN \seq_gset_eq:cc \cs_gset_eq:cc % \end{macrocode} % \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} % -% \begin{macro}{\seq_if_empty:NTF} -% \begin{macro}{\seq_if_empty:cTF} -% \begin{macro}{\seq_if_empty:NF} -% \begin{macro}{\seq_if_empty:cF} -% |\seq_if_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_if_empty:cTF| turns its first argument into a -% control sequence to get the name of the sequence. +% \begin{macro}{\seq_gconcat:NNN,\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} -\let_new:NN \seq_if_empty:NTF \tlp_if_empty:NTF -\def_new:Npn \seq_if_empty:cTF {\exp_args:Nc\seq_if_empty:NTF} +\cs_new_nopar:Npn \seq_gconcat:NNN #1#2#3 { + \tl_gset:Nx #1 { \exp_not:V #2 \exp_not:V #3 } +} +\cs_generate_variant:Nn \seq_gconcat:NNN {ccc} % \end{macrocode} -% A variant of this, is only to do something if the sequence is -% \emph{not} empty. +% \end{macro} +% +% \subsection{Predicates and conditionals} +% +% \begin{macro}{\seq_if_empty_p:N,\seq_if_empty_p:c} +% \begin{macro}[TF]{\seq_if_empty:N,\seq_if_empty:c} +% A predicate which evaluates to |\c_true_bool| iff the sequence is empty. % \begin{macrocode} -\let_new:NN \seq_if_empty:NF \tlp_if_empty:NF -\def_new:Npn \seq_if_empty:cF {\exp_args:Nc\seq_if_empty:NF} +\prg_new_eq_conditional:NNn \seq_if_empty:N \tl_if_empty:N {p,TF,T,F} +\prg_new_eq_conditional:NNn \seq_if_empty:c \tl_if_empty:c {p,TF,T,F} % \end{macrocode} % \end{macro} % \end{macro} -% \end{macro} -% \end{macro} % % % \begin{macro}{\seq_if_empty_err:N} % Signals an error if the sequence is empty. % \begin{macrocode} -\def_new:Npn \seq_if_empty_err:N #1{\if_meaning:NN#1\c_empty_tlp +\cs_new_nopar:Npn \seq_if_empty_err:N #1 { + \if_meaning:w #1 \c_empty_tl % \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. +% (Will: I have no idea what this comment means.) % \begin{macrocode} - \tlp_clear:N \l_testa_tlp % catch prefixes - \err_latex_bug:x{Empty~sequence~`\token_to_string:N#1'}\fi:} + \tl_clear:N \l_testa_tl % catch prefixes + \msg_kernel_bug:x {Empty~sequence~`\token_to_str:N#1'} + \fi: +} % \end{macrocode} % \end{macro} % +% \begin{macro}[TF]{\seq_if_in:Nn,\seq_if_in:cn, +% \seq_if_in:cV,\seq_if_in:co,\seq_if_in:cx} +% |\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_charcode:w| +% statements. +% +% Note that |##2| in the definition below for "\seq_tmp:w" contains +% exactly one token which we can compare with |\q_no_value|. +% \begin{macrocode} +\prg_new_conditional:Nnn \seq_if_in:Nn {TF,T,F} { + \cs_set:Npn \seq_tmp:w ##1 \seq_elt:w #2 \seq_elt_end: ##2##3 \q_stop { + \if_meaning:w \q_no_value ##2 + \prg_return_false: \else: \prg_return_true: \fi: + } + \exp_after:wN \seq_tmp:w #1 \seq_elt:w #2 \seq_elt_end: \q_no_value \q_stop +} +% \end{macrocode} +% \begin{macrocode} +\cs_generate_variant:Nn \seq_if_in:NnTF {cV,co,c,cx} +\cs_generate_variant:Nn \seq_if_in:NnT {cV,co,c,cx} +\cs_generate_variant:Nn \seq_if_in:NnF {cV,co,c,cx} +% \end{macrocode} +% \end{macro} +% +% \subsection{Getting data out} +% % \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{macro}{\seq_get_aux:w} +% |\seq_get:NN |\meta{sequence}\meta{cmd} defines \meta{cmd} to be the +% left-most element of \meta{sequence}. % \begin{macrocode} -\def_new:Npn \seq_get:NN #1{ +\cs_new_nopar:Npn \seq_get:NN #1 { \seq_if_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} + \exp_after:wN \seq_get_aux:w #1 \q_stop +} +\cs_new:Npn \seq_get_aux:w \seq_elt:w #1 \seq_elt_end: #2 \q_stop #3 { + \tl_set:Nn #3 {#1} +} +\cs_generate_variant:Nn \seq_get:NN {c} % \end{macrocode} % \end{macro} % \end{macro} +% \end{macro} % % \begin{macro}{\seq_pop_aux:nnNN} % \begin{macro}{\seq_pop_aux:w} -% |\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$}. +% |\seq_pop_aux:nnNN| \meta{def$\sb1$} \meta{def$\sb2$} \meta{sequence} +% \meta{cmd} assigns the left_most element of \meta{sequence} to +% \meta{cmd} using \meta{def$\sb2$}, and assigns the tail of +% \meta{sequence} to \meta{sequence} using \meta{def$\sb1$}. % \begin{macrocode} -\def_new:Npn \seq_pop_aux:nnNN #1#2#3{ +\cs_new:Npn \seq_pop_aux:nnNN #1#2#3 { \seq_if_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}} + \exp_after:wN \seq_pop_aux:w #3 \q_stop #1#2#3 +} +\cs_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} +% \end{macro} +% +% \begin{macro}{\seq_show:N} +% \begin{macro}{\seq_show:c} +% \begin{macrocode} +\cs_new_eq:NN \seq_show:N \tl_show:N +\cs_new_eq:NN \seq_show:c \tl_show:c % \end{macrocode} % \end{macro} % \end{macro} % +% \begin{macro}{\seq_display:N} +% \begin{macro}{\seq_display:c} +% \begin{macrocode} +\cs_new_nopar:Npn \seq_display:N #1 { + \iow_term:x { Sequence~\token_to_str:N #1~contains~ + the~elements~(without~outer~braces): } + \toks_clear:N \l_tmpa_toks + \seq_map_inline:Nn #1 { + \toks_if_empty:NF \l_tmpa_toks { + \toks_put_right:Nx \l_tmpa_toks {^^J>~} + } + \toks_put_right:Nx \l_tmpa_toks { + \iow_space: \iow_char:N \{ \exp_not:n {##1} \iow_char:N \} + } + } + \toks_show:N \l_tmpa_toks +} +\cs_generate_variant:Nn \seq_display:N {c} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% \subsection{Putting data in} +% % \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{macro}{\seq_put_aux:w} +% |\seq_put_aux:Nnn| \meta{sequence} \meta{left} \meta{right} adds the +% elements specified by \meta{left} to the left of \meta{sequence}, and +% those specified by \meta{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}} +\cs_new:Npn \seq_put_aux:Nnn #1 { + \exp_after:wN \seq_put_aux:w #1 \q_stop #1 +} +\cs_new:Npn \seq_put_aux:w #1\q_stop #2#3#4 { \tl_set:Nn #2 {#3#1#4} } % \end{macrocode} % \end{macro} +% \end{macro} % % \begin{macro}{\seq_put_left:Nn} +% \begin{macro}{\seq_put_left:NV} % \begin{macro}{\seq_put_left:No} % \begin{macro}{\seq_put_left:Nx} % \begin{macro}{\seq_put_left:cn} +% \begin{macro}{\seq_put_left:cV} +% \begin{macro}{\seq_put_left:co} % \begin{macro}{\seq_put_right:Nn} % \begin{macro}{\seq_put_right:No} +% \begin{macro}{\seq_put_right:NV} % \begin{macro}{\seq_put_right:Nx} +% \begin{macro}{\seq_put_right:cn} +% \begin{macro}{\seq_put_right:cV} +% \begin{macro}{\seq_put_right:co} % Here are the usual operations for adding to the left and right. % \begin{macrocode} -\def_new:Npn \seq_put_left:Nn #1#2{ +\cs_new:Npn \seq_put_left:Nn #1#2 { + \seq_put_aux:Nnn #1 {\seq_elt:w #2\seq_elt_end:} {} +} +% \end{macrocode} +% We can't put in a |\prg_do_nothing:| instead of |{}| above since this argument +% is passed literally (and we would end up with many |\prg_do_nothing:|s inside +% the sequences). +% \begin{macrocode} +\cs_generate_variant:Nn \seq_put_left:Nn {NV,No,Nx,c,cV,co} % \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{ +\cs_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} +% \begin{macrocode} +\cs_generate_variant:Nn \seq_put_right:Nn {NV,No,Nx,c,cV,co} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} % \end{macro} % \end{macro} % \end{macro} @@ -558,31 +739,46 @@ % \end{macro} % % \begin{macro}{\seq_gput_left:Nn} +% \begin{macro}{\seq_gput_left:NV} +% \begin{macro}{\seq_gput_left:No} +% \begin{macro}{\seq_gput_left:Nx} +% \begin{macro}{\seq_gput_left:cn} +% \begin{macro}{\seq_gput_left:cV} +% \begin{macro}{\seq_gput_left:co} % \begin{macro}{\seq_gput_right:Nn} -% \begin{macro}{\seq_gput_right:Nc} +% \begin{macro}{\seq_gput_right:NV} % \begin{macro}{\seq_gput_right:No} +% \begin{macro}{\seq_gput_right:Nx} % \begin{macro}{\seq_gput_right:cn} +% \begin{macro}{\seq_gput_right:cV} % \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 { +\cs_new:Npn \seq_gput_left:Nn { %<*check> - \pref_global_chk: + \pref_global_chk: %</check> -%<-check> \pref_global:D - \seq_put_left:Nn} -\def_new:Npn \seq_gput_right:Nn { +%<*!check> + \pref_global:D +%</!check> + \seq_put_left:Nn +} +% \end{macrocode} +% \begin{macrocode} +\cs_new:Npn \seq_gput_right:Nn { %<*check> - \pref_global_chk: + \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:Nc {\exp_args:NNc \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} +%<*!check> + \pref_global:D +%</!check> + \seq_put_right:Nn +} +% \end{macrocode} +% \begin{macrocode} +\cs_generate_variant:Nn \seq_gput_left:Nn {NV,No,Nx,c,cV,co} +% \end{macrocode} +% \begin{macrocode} +\cs_generate_variant:Nn \seq_gput_right:Nn {NV,No,Nx,c,cV,co} % \end{macrocode} % \end{macro} % \end{macro} @@ -591,156 +787,88 @@ % \end{macro} % \end{macro} % \end{macro} -% -% \begin{macro}{\seq_map_variable:NNn} -% \begin{macro}{\seq_map_variable:cNn} -% \begin{macro}{\seq_map_variable_aux:nw} -% \begin{macro}{\seq_map_break:w} -% Nothing spectacular here. The shuffling of the arguments in -% |\seq_map_variable:NNn| below could also be done with -% |\exp_args:NNnE|. -% \begin{macrocode} -\def_new:Npn \seq_map_variable_aux:Nnw #1#2\seq_elt:w#3\seq_elt_end:{ - \tlp_set:Nn #1{#3} - \quark_if_nil:NT #1 \seq_map_break:w - #2 - \seq_map_variable_aux:Nnw #1{#2} -} -\def_new:Npn \seq_map_variable:NNn #1#2#3{ - \tlp_set:Nx #2 {\exp_not:n{\seq_map_variable_aux:Nnw #2{#3}}} - \exp_after:NN #2 #1 \seq_elt:w \q_nil\seq_elt_end: \q_stop -} -\def_new:Npn \seq_map_variable:cNn{\exp_args:Nc\seq_map_variable:Nn} -\let_new:NN \seq_map_break:w \use_none_delimit_by_q_stop:w -% \end{macrocode} % \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 - \let:NN \seq_elt:w \ERROR -} -% \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{ - \def:Npn \seq_elt:w ##1\seq_elt_end: {#2}#1 - \let:NN \seq_elt:w \ERROR -} -\def_new:Npn \seq_map_inline:cn{\exp_args:Nc\seq_map_inline:Nn} -% \end{macrocode} % \end{macro} % \end{macro} % -% \begin{macro}{\seq_set_eq:NN} -% \begin{macro}{\seq_set_eq:Nc} -% We can set one seq equal to another. +% \begin{macro}{\seq_gput_right:Nc} +% TODO: move to |xor| (Sep 2008) % \begin{macrocode} -\let_new:NN \seq_set_eq:NN \let:NN -\def_new:Npn \seq_set_eq:Nc {\exp_args:NNc \seq_set_eq:NN} +\cs_generate_variant:Nn \seq_gput_right:Nn {Nc} % \end{macrocode} % \end{macro} -% \end{macro} % +% \subsection{Mapping} % -% \begin{macro}{\seq_gset_eq:NN} -% \begin{macro}{\seq_gset_eq:cN} -% \begin{macro}{\seq_gset_eq:Nc} -% \begin{macro}{\seq_gset_eq:cc} -% An of course globally which seems to be needed far more -% often.\footnote{To save a bit of space these functions could be made -% identical to those from the tlp or clist module.} +% \begin{macro}{\seq_map_variable:NNn} +% \begin{macro}{\seq_map_variable:cNn} +% \begin{macro}[aux]{\seq_map_variable_aux:Nnw} +% \begin{macro}{\seq_map_break:} +% \begin{macro}{\seq_map_break:n} +% Nothing spectacular here. % \begin{macrocode} -\let_new:NN \seq_gset_eq:NN \glet:NN -\def_new:Npn \seq_gset_eq:cN {\exp_args:Nc \seq_gset_eq:NN} -\def_new:Npn \seq_gset_eq:Nc {\exp_args:NNc \seq_gset_eq:NN} -\def_new:Npn \seq_gset_eq:cc {\exp_args:Ncc \seq_gset_eq:NN} +\cs_new:Npn \seq_map_variable_aux:Nnw #1#2 \seq_elt:w #3 \seq_elt_end: { + \tl_set:Nx #1{\exp_not:n{#3}} + \quark_if_nil:NT #1 \seq_map_break: + #2 + \seq_map_variable_aux:Nnw #1{#2} +} +\cs_new:Npn \seq_map_variable:NNn #1#2#3 { + \tl_set:Nx #2 {\exp_not:n{\seq_map_variable_aux:Nnw #2{#3}}} + \exp_after:wN #2 #1 \seq_elt:w \q_nil\seq_elt_end: \q_stop +} +\cs_generate_variant:Nn \seq_map_variable:NNn {c} + +\cs_new_eq:NN \seq_map_break: \use_none_delimit_by_q_stop:w +\cs_new_eq:NN \seq_map_break:n \use_i_delimit_by_q_stop:nw % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \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{macro}{\seq_map_function:NN} +% \begin{macro}{\seq_map_function:cN} +% |\seq_map_function:NN| \meta{sequence} \meta{cmd} applies \meta{cmd} to each +% element of \meta{sequence}, from left to right. Since we don't have +% braces, this implementation is not very efficient. It might be +% better to say that \meta{cmd} must be a function with one argument +% that is delimited by |\seq_elt_end:|. % \begin{macrocode} -\def_new:Npn \seq_gconcat:NNN #1#2#3{ - \tlp_gset:Nx #1 {\exp_not:o{#2}\exp_not:o{#3}} +\cs_new_nopar:Npn \seq_map_function:NN #1#2 { + \cs_set:Npn \seq_elt:w ##1 \seq_elt_end: {#2{##1}} + #1 + \cs_set_eq:NN \seq_elt:w \ERROR } -\def_new:Npn \seq_gconcat:ccc{\exp_args:Nccc\seq_gconcat:NNN} +\cs_generate_variant:Nn \seq_map_function:NN {c} % \end{macrocode} % \end{macro} % \end{macro} % -% \begin{macro}{\seq_if_in:NnTF} -% \begin{macro}{\seq_if_in:cnTF} -% \begin{macro}{\seq_if_in:coTF} -% \begin{macro}{\seq_if_in:cxTF} -% \begin{macro}{\seq_if_in:NnF} -% \begin{macro}{\seq_if_in:cnF} -% |\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_charcode: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_arg_ii:nn - \else: - \exp_after:NN\use_arg_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} -\def_new:Npn \seq_if_in:cxTF {\exp_args:Ncx \seq_if_in:NnTF} -% \end{macrocode} -% +% \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_if_in:NnF #1#2 { \seq_if_in:NnTF #1{#2}\use_noop: } -\def_new:Npn \seq_if_in:cnF {\exp_args:Nc \seq_if_in:NnF} +\cs_new_nopar:Npn \seq_map_inline:Nn #1#2 { + \cs_set:Npn \seq_elt:w ##1 \seq_elt_end: {#2} + #1 + \cs_set_eq:NN \seq_elt:w \ERROR +} +\cs_generate_variant:Nn \seq_map_inline:Nn {c} % \end{macrocode} % \end{macro} % \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% -% -% -% \subsubsection{Stack operations} -% -% We build stacks from sequences, but here we put the -% specific functions together. % +% \subsection{Sequence stacks} % % \begin{macro}{\seq_push:Nn} +% \begin{macro}{\seq_push:NV} % \begin{macro}{\seq_push:No} % \begin{macro}{\seq_push:cn} % \begin{macro}{\seq_pop:NN} @@ -749,24 +877,25 @@ % `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} +\cs_new_eq:NN \seq_push:Nn \seq_put_left:Nn +\cs_new_eq:NN \seq_push:NV \seq_put_left:NV +\cs_new_eq:NN \seq_push:No \seq_put_left:No +\cs_new_eq:NN \seq_push:cn \seq_put_left:cn +\cs_new_nopar:Npn \seq_pop:NN { \seq_pop_aux:nnNN \tl_set:Nn \tl_set:Nn } +\cs_generate_variant:Nn \seq_pop:NN {c} % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} -% -% +% \end{macro} % % \begin{macro}{\seq_gpush:Nn} +% \begin{macro}{\seq_gpush:NV} % \begin{macro}{\seq_gpush:No} % \begin{macro}{\seq_gpush:cn} -% \begin{macro}{\seq_gpush:NC} +% \begin{macro}{\seq_gpush:Nv} % \begin{macro}{\seq_gpop:NN} % \begin{macro}{\seq_gpop:cN} % I don't agree with Denys that one needs only local stacks, @@ -774,12 +903,10 @@ % 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_gpush:NC {\exp_args:NNC \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} +\cs_new_eq:NN \seq_gpush:Nn \seq_gput_left:Nn +\cs_new_nopar:Npn \seq_gpop:NN { \seq_pop_aux:nnNN \tl_gset:Nn \tl_set:Nn } +\cs_generate_variant:Nn \seq_gpush:Nn {NV,No,c,Nv} +\cs_generate_variant:Nn \seq_gpop:NN {c} % \end{macrocode} % \end{macro} % \end{macro} @@ -787,54 +914,32 @@ % \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 +\cs_new_eq:NN \seq_top:NN \seq_get:NN +\cs_new_eq:NN \seq_top:cN \seq_get:cN % \end{macrocode} % \end{macro} % \end{macro} % % -% Show token usage: % \begin{macrocode} %</initex|package> +% \end{macrocode} +% +% Show token usage: +% \begin{macrocode} %<*showmemory> %\showMemUsage %</showmemory> % \end{macrocode} % -% \endinput -% -% $Log$ -% Revision 1.23 2006/08/09 21:12:50 morten -% Minor change in \seq_gconcat:NNN -% -% Revision 1.22 2006/03/20 18:26:39 braams -% Updated the copyright notice (2006) and demoted all implementation -% sections to subsections and so on to clean up the toc for source3.tex -% -% Revision 1.21 2005/12/29 01:28:29 morten -% Added a new mapping function (needed in xparse) -% -% Revision 1.20 2005/12/27 10:06:10 morten -% Minor changes plus changed RCS information retrieval -% -% Revision 1.19 2005/04/06 21:36:08 morten -% Removed dependency on l3toks and added an if_in variant -% -% Revision 1.18 2005/03/22 23:28:05 morten -% Fix coding as Benjamin pointed out -% -% Revision 1.17 2005/03/16 22:35:51 braams -% Added the tweaks necessary to be able to load with initex -% -% Revision 1.16 2005/03/11 21:42:10 braams -% Fixed the use of RCS information; added \StopEventually -% Fixed a few documentation typos +% \end{implementation} +% \PrintIndex % +% \endinput diff --git a/Master/texmf-dist/source/latex/expl3/l3skip.dtx b/Master/texmf-dist/source/latex/expl3/l3skip.dtx index 11545f09d82..1853812248e 100644 --- a/Master/texmf-dist/source/latex/expl3/l3skip.dtx +++ b/Master/texmf-dist/source/latex/expl3/l3skip.dtx @@ -1,5 +1,5 @@ % \iffalse -%% File: l3skip.dtx Copyright (C) 2005-2007 Frank Mittelbach, LaTeX3 project +%% File: l3skip.dtx Copyright (C) 2005-2008 Frank Mittelbach, LaTeX3 project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this @@ -17,7 +17,7 @@ %% %% The development version of the bundle can be found at %% -%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/ +%% http://www.latex-project.org/svnroot/experimental/trunk/ %% %% for those people who are interested. %% @@ -36,7 +36,7 @@ \RequirePackage{l3names} %</driver|package> %\fi -\GetIdInfo$Id: l3skip.dtx 666 2007-09-27 15:53:26Z mittelba $ +\GetIdInfo$Id: l3skip.dtx 1362 2009-05-28 20:19:21Z joseph $ {L3 Experimental skip registers} %\iffalse %<*driver> @@ -44,9 +44,9 @@ \ProvidesFile{\filename.\filenameext} [\filedate\space v\fileversion\space\filedescription] %\iffalse -\documentclass{l3doc} +\documentclass[full]{l3doc} \begin{document} -\DocInput{\filename.\filenameext} +\DocInput{l3skip.dtx} \end{document} %</driver> % \fi @@ -60,23 +60,21 @@ % \date{\filedate} % \maketitle % -% -% \section{Length registers} -% +% \begin{documentation} % % \LaTeX3 knows about two types of length registers for internal use: % rubber lengths ("skip"s) and rigid lengths ("dim"s). % -% \subsection{Skip registers} +% \section{Skip registers} % % % -% \subsubsection{Functions} +% \subsection{Functions} % % \begin{function}{% % \skip_new:N | % \skip_new:c | -% \skip_new_l:N +%^^A \skip_new_l:N % } % \begin{syntax} % "\skip_new:N" <skip> @@ -110,7 +108,7 @@ % \skip_gset:cn | % } % \begin{syntax} -% "\skip_set:Nn" <skip> "{" <skip value> "}" +% "\skip_set:Nn" <skip> \Arg{skip value} % \end{syntax} % These functions will set the <skip> register to the <length> value. % \end{function} @@ -123,7 +121,7 @@ % \skip_gadd:cn | % } % \begin{syntax} -% "\skip_add:Nn" <skip> "{" <length> "}" +% "\skip_add:Nn" <skip> \Arg{length} % \end{syntax} % These functions will add to the <skip> register the value <length>. If % the second argument is a <skip> register too, the surrounding braces @@ -135,7 +133,7 @@ % \skip_gsub:Nn | % } % \begin{syntax} -% "\skip_gsub:Nn" <skip> "{" <length> "}" +% "\skip_gsub:Nn" <skip> \Arg{length} % \end{syntax} % These functions will subtract from the <skip> register the value % <length>. If the second argument is a <skip> register too, the @@ -160,6 +158,21 @@ % \end{texnote} % \end{function} % +% \begin{function}{ \skip_show:N | +% \skip_show:c } +% \begin{syntax} +% "\skip_show:N" <skip> +% \end{syntax} +% This function pauses the compilation and displays the length value kept +% in <skip> in the console output and log file. +% \begin{texnote} +% The function "\skip_show:N" could be implemented directly as the \TeX{} +% primitive "\tex_showthe:D" which is also responsible to produce the values for +% other internal quantities. We have chosen to use individual functions +% for counters, dimensions etc.\ to allow checks and to make the code +% more self-explaining. +% \end{texnote} +% \end{function} % % \begin{function}{% % \skip_horizontal:N | @@ -171,7 +184,7 @@ % } % \begin{syntax} % "\skip_horizontal:N" <skip> \\ -% "\skip_horizontal:n" "{" <length> "}" +% "\skip_horizontal:n" \Arg{length} % \end{syntax} % The "hor" functions insert <skip> or <length> with the \TeX\ % primitive \tn{hskip}. The "vertical" variants do the same with @@ -179,11 +192,10 @@ % \end{function} % % -% \begin{function}{% -% \skip_infinite_glue:nTF | -% } +% \begin{function}{ \skip_if_infinite_glue_p:n | +% \skip_if_infinite_glue:n / (TF) } % \begin{syntax} -% "\skip_infinite_glue:nTF" "{"<skip>"}" "{"<true>"}" "{"<false>"}" +% "\skip_if_infinite_glue:nTF" \Arg{skip} \Arg{true} \Arg{false} % \end{syntax} % Checks if <skip> contains infinite stretch or shrink components % and executes either <true> or <false>. Also works on input like @@ -196,7 +208,7 @@ % \skip_split_finite_else_action:nnNN | % } % \begin{syntax} -% "\skip_split_finite_else_action:nnNN" "{"<skip>"}" "{"<action>"}" +% "\skip_split_finite_else_action:nnNN" \Arg{skip} \Arg{action} % <dimen1> <dimen2> % \end{syntax} % Checks if <skip> contains finite glue. If it does then it assigns @@ -208,10 +220,10 @@ % % % \begin{function}{% -% \skip_eval:n | +% \skip_eval:n / (EXP) | % } % \begin{syntax} -% "\skip_eval:n" "{"<skip expr>"}" +% "\skip_eval:n" \Arg{skip expr} % \end{syntax} % Evaluates the value of <skip expr> so that % "\skip_eval:n {5pt plus 3fil + 3pt minus 1fil}" puts @@ -224,10 +236,10 @@ % \end{function} % % -% \subsubsection{Formatting a skip register value} +% \subsection{Formatting a skip register value} % % -% \subsubsection{Variable and constants} +% \subsection{Variable and constants} % % \begin{variable}{% % \c_max_skip | @@ -256,10 +268,10 @@ % % % -% \subsection{Dim registers} +% \section{Dim registers} % % -% \subsubsection{Functions} +% \subsection{Functions} % % % @@ -267,7 +279,7 @@ % \begin{function}{% % \dim_new:N | % \dim_new:c | -% \dim_new_l:N +%^^A \dim_new_l:N % } % \begin{syntax} % "\dim_new:N" <dim> @@ -296,12 +308,15 @@ % % \begin{function}{% % \dim_set:Nn | +% \dim_set:Nc | % \dim_set:cn | % \dim_gset:Nn | +% \dim_gset:Nc | % \dim_gset:cn | +% \dim_gset:cc | % } % \begin{syntax} -% "\dim_set:Nn" <dim> "{" <dim value> "}" +% "\dim_set:Nn" <dim> \Arg{dim value} % \end{syntax} % These functions will set the <dim> register to the <dim value> value. % \end{function} @@ -309,12 +324,13 @@ % % \begin{function}{% % \dim_add:Nn | +% \dim_add:Nc | % \dim_add:cn | % \dim_gadd:Nn | % \dim_gadd:cn | % } % \begin{syntax} -% "\dim_add:Nn" <dim> "{" <length> "}" +% "\dim_add:Nn" <dim> \Arg{length} % \end{syntax} % These functions will add to the <dim> register the value <length>. If % the second argument is a <dim> register too, the surrounding braces @@ -323,10 +339,13 @@ % % \begin{function}{% % \dim_sub:Nn | +% \dim_sub:Nc | +% \dim_sub:cn | % \dim_gsub:Nn | +% \dim_gsub:cn | % } % \begin{syntax} -% "\dim_gsub:Nn" <dim> "{" <length> "}" +% "\dim_gsub:Nn" <dim> \Arg{length} % \end{syntax} % These functions will subtract from the <dim> register the value % <length>. If the second argument is a <dim> register too, the @@ -351,13 +370,28 @@ % \end{texnote} % \end{function} % +% \begin{function}{ \dim_show:N | +% \dim_show:c } +% \begin{syntax} +% "\dim_show:N" <skip> +% \end{syntax} +% This function pauses the compilation and displays the length value kept +% in <skip> in the console output and log file. +% \begin{texnote} +% The function "\dim_show:N" could be implemented directly as the \TeX{} +% primitive "\tex_showthe:D" which is also responsible to produce the values for +% other internal quantities. We have chosen to use individual functions +% for counters, dimensions etc.\ to allow checks and to make the code +% more self-explaining. +% \end{texnote} +% \end{function} % % % \begin{function}{% % \dim_eval:n | % } % \begin{syntax} -% "\dim_eval:n" "{"<dim expr>"}" +% "\dim_eval:n" \Arg{dim expr} % \end{syntax} % Evaluates the value of a dimension expression so that % "\dim_eval:n {5pt+3pt}" puts "8pt" back into the input stream. @@ -382,14 +416,10 @@ % \end{texnote} % \end{function} % -% \begin{function}{% -% \dim_compare:nNnTF | -% \dim_compare:nNnT | -% \dim_compare:nNnF | -% } +% \begin{function}{ \dim_compare:nNn / (TF)(EXP) | \dim_compare_p:nNn / (EXP)} % \begin{syntax} -% "\dim_compare:nNnTF" "{"<dim~expr>"}" <rel> "{"<dim~expr>"}" -% "{"<true>"}" "{"<false>"}" +% "\dim_compare:nNnTF" \Arg{dim~expr} <rel> \Arg{dim~expr} +% \Arg{true} \Arg{false} % \end{syntax} % These functions test two dimension expressions against each other. They % are both evaluated by "\dim_eval:n". Note that if both expressions @@ -403,34 +433,26 @@ % \end{texnote} % \end{function} % -% \begin{function}{% -% \dim_compare_p:nNn | -% } -% \begin{syntax} -% "\dim_compare_p:nNn" "{"<dim~expr>"}" <rel> "{"<dim~expr>"}" -% \end{syntax} -% Predicate version of the above functions. -% \end{function} % % \begin{function}{% -% \dim_while:nNnT | -% \dim_while:nNnF | -% \dim_dowhile:nNnT | -% \dim_dowhile:nNnF | +% \dim_while_do:nNnn | +% \dim_until_do:nNnn | +% \dim_do_while:nNnn | +% \dim_do_until:nNnn | % } % \begin{syntax} -% "\dim_while:nNnT" <dim expr> <rel> <dim~expr> <true> +% "\dim_while_do:nNnn" <dim expr> <rel> <dim~expr> <code> % \end{syntax} -% "\dim_while:nNnT" tests the dimension expressions and if true performs -% the body "T" until the test fails. "\dim_dowhile:nNnT" is similar +% "\dim_while_do:nNnn" tests the dimension expressions and if true performs +% <code> repeatedly while the test remains true. "\dim_do_while:nNnn" is similar % but executes the body first and then performs the check, thus -% ensuring that the body is executed at least once. The "F" versions +% ensuring that the body is executed at least once. The `until' versions % are similar but continue the loop as long as the test is false. % \end{function} % % % -% \subsubsection{Variable and constants} +% \subsection{Variable and constants} % % \begin{variable}{% % \c_max_dim | @@ -456,11 +478,11 @@ % Scratch register for immediate use. % \end{variable} % -% \subsection{Muskips} +% \section{Muskips} % % \begin{function}{% % \muskip_new:N | -% \muskip_new_l:N +%^^A \muskip_new_l:N % } % \begin{syntax} % "\muskip_new:N" <muskip> @@ -477,7 +499,7 @@ % \muskip_gset:Nn | % } % \begin{syntax} -% "\muskip_set:Nn" <muskip> "{" <muskip value> "}" +% "\muskip_set:Nn" <muskip> \Arg{muskip value} % \end{syntax} % These functions will set the <muskip> register to the <length> % value. @@ -489,7 +511,7 @@ % \muskip_gadd:Nn | % } % \begin{syntax} -% "\muskip_add:Nn" <muskip> "{" <length> "}" +% "\muskip_add:Nn" <muskip> \Arg{length} % \end{syntax} % These functions will add to the <muskip> register the value % <length>. If the second argument is a <muskip> register too, the @@ -501,47 +523,62 @@ % \muskip_gsub:Nn | % } % \begin{syntax} -% "\muskip_gsub:Nn" <muskip> "{" <length> "}" +% "\muskip_gsub:Nn" <muskip> \Arg{length} % \end{syntax} % These functions will subtract from the <muskip> register the value % <length>. If the second argument is a <muskip> register too, the % surrounding braces can be left out. % \end{function} % +% \begin{function}{ \muskip_use:N } +% \begin{syntax} +% "\muskip_use:N" <muskip> +% \end{syntax} +% This function returns the length value kept in <muskip> in a way +% suitable for further processing. +% \begin{texnote} +% See note for "\dim_use:N". +% \end{texnote} +% \end{function} % -% \StopEventually{} +% \end{documentation} % -% \subsection{The Implementation} +% \begin{implementation} +% +% \section{\pkg{l3skip} implementation} % % % We start by ensuring that the required packages are loaded. % \begin{macrocode} -%<package>\ProvidesExplPackage -%<package> {\filename}{\filedate}{\fileversion}{\filedescription} -%<package&!check>\RequirePackage{l3int} -%<package&!check>\RequirePackage{l3prg} -%<package&check>\RequirePackage{l3chk} +%<*package> +\ProvidesExplPackage + {\filename}{\filedate}{\fileversion}{\filedescription} +\package_check_loaded_expl: +%</package> %<*initex|package> % \end{macrocode} % -% \subsubsection{Skip registers} +% \subsection{Skip registers} % -% \begin{macro}{\skip_new:N} -% \begin{macro}{\skip_new:c} -% \begin{macro}{\skip_new_l:N} +% \begin{macro}{\skip_new:N,\skip_new:c} +%^^A \begin{macro}{\skip_new_l:N} % Allocation of a new internal registers. % \begin{macrocode} %<*initex> \alloc_setup_type:nnn {skip} \c_zero \c_max_register_num -\def_new:Npn\skip_new:N #1 {\alloc_reg:NnNN g {skip} \tex_skipdef:D #1 } -\def_new:Npn\skip_new_l:N #1 {\alloc_reg:NnNN l {skip} \tex_skipdef:D #1 } +\cs_new_nopar:Npn\skip_new:N #1 { \alloc_reg:NnNN g {skip} \tex_skipdef:D #1 } +\cs_new_nopar:Npn\skip_new_l:N #1 { \alloc_reg:NnNN l {skip} \tex_skipdef:D #1 } %</initex> -%<package>\let:NN \skip_new:N \newskip -\def_new:Npn \skip_new:c {\exp_args:Nc \skip_new:N} +%<*package> +\cs_new_nopar:Npn \skip_new:N #1 { + \chk_if_free_cs:N #1 + \newskip #1 +} +%</package> +\cs_generate_variant:Nn \skip_new:N {c} % \end{macrocode} % \end{macro} -% \end{macro} -% \end{macro} +%^^A \end{macro} % % % \begin{macro}{\skip_set:Nn} @@ -551,19 +588,21 @@ % Setting skips is again something that I would like to make % uniform at the moment to get a better overview. % \begin{macrocode} -\def_new:Npn \skip_set:Nn #1#2{#1\skip_eval:n{#2} +\cs_new_nopar:Npn \skip_set:Nn #1#2 { + #1\skip_eval:n{#2} %<*check> \chk_local_or_pref_global:N #1 %</check> } -\def_new:Npn \skip_gset:Nn { +\cs_new_nopar:Npn \skip_gset:Nn { %<*check> - \pref_global_chk: + \pref_global_chk: %</check> %<-check> \pref_global:D - \skip_set:Nn } -\def_new:Npn \skip_set:cn {\exp_args:Nc \skip_set:Nn } -\def_new:Npn \skip_gset:cn {\exp_args:Nc \skip_gset:Nn } + \skip_set:Nn +} +\cs_generate_variant:Nn \skip_set:Nn {cn} +\cs_generate_variant:Nn \skip_gset:Nn {cn} % \end{macrocode} % \end{macro} % \end{macro} @@ -576,12 +615,13 @@ % \begin{macro}{\skip_gzero:c} % Reset the register to zero. % \begin{macrocode} -\def_new:Npn \skip_zero:N #1{#1\c_zero_skip \scan_stop: +\cs_new_nopar:Npn \skip_zero:N #1{ + #1\c_zero_skip \scan_stop: %<*check> - \chk_local_or_pref_global:N #1 + \chk_local_or_pref_global:N #1 %</check> } -\def_new:Npn \skip_gzero:N { +\cs_new_nopar:Npn \skip_gzero: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 @@ -592,12 +632,13 @@ % production versions. % \begin{macrocode} %<*check> - \pref_global_chk: + \pref_global_chk: %</check> %<-check> \pref_global:D - \skip_zero:N} -\def_new:Npn \skip_zero:c {\exp_args:Nc \skip_zero:N} -\def_new:Npn \skip_gzero:c {\exp_args:Nc \skip_gzero:N} + \skip_zero:N +} +\cs_generate_variant:Nn \skip_zero:N {c} +\cs_generate_variant:Nn \skip_gzero:N {c} % \end{macrocode} % \end{macro} % \end{macro} @@ -608,45 +649,59 @@ % \begin{macro}{\skip_add:Nn} % \begin{macro}{\skip_add:cn} % \begin{macro}{\skip_gadd:Nn} +% \begin{macro}{\skip_gadd:cn} % \begin{macro}{\skip_sub:Nn} % \begin{macro}{\skip_gsub:Nn} % Adding and subtracting to and from <skip>s % \begin{macrocode} -\def_new:Npn \skip_add:Nn #1#2{ +\cs_new_nopar:Npn \skip_add:Nn #1#2 { % \end{macrocode} % We need to say |by| in case the first argment is a register % accessed by its number, e.g., |\skip23|. % \begin{macrocode} - \tex_advance:D#1 by \skip_eval:n{#2} + \tex_advance:D#1 by \skip_eval:n{#2} %<*check> - \chk_local_or_pref_global:N #1 + \chk_local_or_pref_global:N #1 %</check> } -\def_new:Npn\skip_add:cn{\exp_args:Nc\skip_add:Nn} -\def_new:Npn \skip_sub:Nn #1#2{ - \tex_advance:D#1-\skip_eval:n{#2} +\cs_generate_variant:Nn \skip_add:Nn {cn} +% \end{macrocode} +% +% \begin{macrocode} +\cs_new_nopar:Npn \skip_sub:Nn #1#2{ + \tex_advance:D#1-\skip_eval:n{#2} %<*check> -\chk_local_or_pref_global:N #1 + \chk_local_or_pref_global:N #1 %</check> } -\def_new:Npn \skip_gadd:Nn { +% \end{macrocode} +% +% \begin{macrocode} +\cs_new_nopar:Npn \skip_gadd:Nn { %<*check> - \pref_global_chk: + \pref_global_chk: %</check> %<-check> \pref_global:D - \skip_add:Nn } -\def_new:Npn \skip_gsub:Nn { + \skip_add:Nn +} +\cs_generate_variant:Nn \skip_gadd:Nn {cn} +% \end{macrocode} +% +% \begin{macrocode} +\cs_new_nopar:Npn \skip_gsub:Nn { %<*check> - \pref_global_chk: + \pref_global_chk: %</check> %<-check> \pref_global:D - \skip_sub:Nn } + \skip_sub:Nn +} % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} +% \end{macro} % % % \begin{macro}{\skip_horizontal:N} @@ -657,12 +712,15 @@ % \begin{macro}{\skip_vertical:n} % Inserting skips. % \begin{macrocode} -\let_new:NN \skip_horizontal:N \tex_hskip:D -\def_new:Npn \skip_horizontal:c {\exp_args:Nc\skip_horizontal:N} -\def_new:Npn \skip_horizontal:n #1{\skip_horizontal:N \skip_eval:n{#1}} -\let_new:NN \skip_vertical:N \tex_vskip:D -\def_new:Npn \skip_vertital:c {\exp_args:Nc\skip_vertical:N} -\def_new:Npn \skip_vertical:n #1{\skip_vertical:N \skip_eval:n{#1}} +\cs_new_eq:NN \skip_horizontal:N \tex_hskip:D +\cs_generate_variant:Nn \skip_horizontal:N {c} +% \end{macrocode} +% +% \begin{macrocode} +\cs_new_nopar:Npn \skip_horizontal:n #1 { \skip_horizontal:N \skip_eval:n{#1} } +\cs_new_eq:NN \skip_vertical:N \tex_vskip:D +\cs_generate_variant:Nn \skip_vertical:N {c} +\cs_new_nopar:Npn \skip_vertical:n #1 { \skip_vertical:N \skip_eval:n{#1} } % \end{macrocode} % \end{macro} % \end{macro} @@ -675,16 +733,26 @@ % \begin{macro}{\skip_use:c} % Here is how skip registers are accessed: % \begin{macrocode} -\let_new:NN \skip_use:N \tex_the:D -\def_new:Npn \skip_use:c #1{\exp_args:Nc\skip_use:N} +\cs_new_eq:NN \skip_use:N \tex_the:D +\cs_generate_variant:Nn \skip_use:N {c} % \end{macrocode} % \end{macro} % \end{macro} % +% \begin{macro}{\skip_show:N} +% \begin{macro}{\skip_show:c} +% Diagnostics. +% \begin{macrocode} +\cs_new_eq:NN \skip_show:N \tex_showthe:D +\cs_new_nopar:Npn \skip_show:c #1 { \skip_show:N \cs:w #1 \cs_end: } +% \end{macrocode} +% \end{macro} +% \end{macro} +% % \begin{macro}{\skip_eval:n} % Evaluating a calc expression. % \begin{macrocode} -\def_new:Npn \skip_eval:n #1 {\etex_glueexpr:D #1 \scan_stop:} +\cs_new_nopar:Npn \skip_eval:n #1 { \etex_glueexpr:D #1 \scan_stop: } % \end{macrocode} % \end{macro} % @@ -696,7 +764,7 @@ % We provide three local and two global scratch registers, maybe we % need more or less. % \begin{macrocode} -%%\chk_new_cs:N \l_tmpa_skip +%%\chk_if_free_cs:N \l_tmpa_skip %%\tex_skipdef:D\l_tmpa_skip 255 %currently taken up by \skip@ \skip_new:N \l_tmpa_skip \skip_new:N \l_tmpb_skip @@ -720,8 +788,8 @@ \skip_set:Nn \c_max_skip {16383.99999pt} %</!package> %<*!initex> -\let:NN \c_zero_skip \z@ -\let:NN \c_max_skip \maxdimen +\cs_set_eq:NN \c_zero_skip \z@ +\cs_set_eq:NN \c_max_skip \maxdimen %</!initex> % \end{macrocode} % \end{macro} @@ -729,26 +797,28 @@ % % % -% \begin{macro}{\skip_infinite_glue:nTF} +% \begin{macro}{\skip_if_infinite_glue_p:n} +% \begin{macro}[TF]{\skip_if_infinite_glue:n} % With \eTeX{} we all of a sudden get access to a lot information we % should otherwise consider ourselves lucky to get. One is % the stretch and shrink components of a skip register and the order -% or those components. "\skip_infinite_glue:nTF" tests it directly by +% or those components. "\skip_if_infinite_glue:nTF" tests it directly by % looking at the stretch and shrink order. If either of the predicate -% functions return \m{true} "\prg_logic_or_p:nn" will return \m{true} +% functions return \m{true} "\bool_if:nTF" will return \m{true} % and the logic test will take the true branch. % \begin{macrocode} -\def_new:Npn \skip_infinite_glue:nTF #1{ - \predicate:nTF { - \int_compare_p:nNn {\etex_gluestretchorder:D #1 } > \c_zero || - \int_compare_p:nNn {\etex_glueshrinkorder:D #1 } > \c_zero - } +\prg_new_conditional:Nnn \skip_if_infinite_glue:n {p,TF,T,F} { + \bool_if:nTF { + \intexpr_compare_p:nNn {\etex_gluestretchorder:D #1 } > \c_zero || + \intexpr_compare_p:nNn {\etex_glueshrinkorder:D #1 } > \c_zero + } {\prg_return_true:} {\prg_return_false:} } % \end{macrocode} % \end{macro} +% \end{macro} % % -% \begin{macro}{\skip_split_finite_else_action:nnNN} +% \begin{macro}{\skip_split_finite_else_action:nnNN} % This macro is useful when performing error checking in certain % circumstances. If the \m{skip} register holds finite glue it sets % "#3" and "#4" to the stretch and shrink component resp. If it holds @@ -756,8 +826,8 @@ % "#2" which is probably an error message. % Assignments are global. % \begin{macrocode} -\def_new:Npn \skip_split_finite_else_action:nnNN #1#2#3#4{ - \skip_infinite_glue:nTF {#1} +\cs_new_nopar:Npn \skip_split_finite_else_action:nnNN #1#2#3#4{ + \skip_if_infinite_glue:nTF {#1} { #3 = \c_zero_skip #4 = \c_zero_skip @@ -773,61 +843,62 @@ % % % -% \subsubsection{Dimen registers} +% \subsection{Dimen registers} % -% \begin{macro}{\dim_new:N} -% \begin{macro}{\dim_new:c} -% \begin{macro}{\dim_new_l:N} +% \begin{macro}{\dim_new:N,\dim_new:c} +%^^A \begin{macro}{\dim_new_l:N} % Allocating \meta{dim} registers... % \begin{macrocode} %<*initex> \alloc_setup_type:nnn {dimen} \c_zero \c_max_register_num -\def_new:Npn \dim_new:N #1 {\alloc_reg:NnNN g {dimen} \tex_dimendef:D #1 } -\def_new:Npn \dim_new_l:N #1 {\alloc_reg:NnNN l {dimen} \tex_dimendef:D #1 } +\cs_new_nopar:Npn \dim_new:N #1 {\alloc_reg:NnNN g {dimen} \tex_dimendef:D #1 } +\cs_new_nopar:Npn \dim_new_l:N #1 {\alloc_reg:NnNN l {dimen} \tex_dimendef:D #1 } %</initex> -%<package>\let:NN \dim_new:N \newdimen -\def_new:Npn \dim_new:c {\exp_args:Nc \dim_new:N} +%<*package> +\cs_new_nopar:Npn \dim_new:N #1 { + \chk_if_free_cs:N #1 + \newdimen #1 +} +%</package> +\cs_generate_variant:Nn \dim_new:N {c} % \end{macrocode} % \end{macro} -% \end{macro} -% \end{macro} +%^^A \end{macro} % % \begin{macro}{\dim_set:Nn} -% \begin{macro}{\dim_gset:Nn} % \begin{macro}{\dim_set:cn} % \begin{macro}{\dim_set:Nc} +% \begin{macro}{\dim_gset:Nn} % \begin{macro}{\dim_gset:cn} % \begin{macro}{\dim_gset:Nc} % \begin{macro}{\dim_gset:cc} % We add |\dim_eval:n| in order to allow simple arithmetic % and a space just for those using |\dimen1| or alike. See OR! % \begin{macrocode} -\def_new:Npn \dim_set:Nn #1#2{#1~ \dim_eval:n{#2}} -\def_new:Npn \dim_gset:Nn {\pref_global:D \dim_set:Nn } -\def_new:Npn \dim_set:cn {\exp_args:Nc \dim_set:Nn } -\def_new:Npn \dim_set:Nc {\exp_args:NNc \dim_set:Nn } -\def_new:Npn \dim_gset:cn {\exp_args:Nc \dim_gset:Nn } -\def_new:Npn \dim_gset:Nc {\exp_args:NNc \dim_gset:Nn } -\def_new:Npn \dim_gset:cc {\exp_args:Ncc \dim_gset:Nn } +\cs_new_nopar:Npn \dim_set:Nn #1#2 { #1~ \dim_eval:n{#2} } +\cs_generate_variant:Nn \dim_set:Nn {cn,Nc} % \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} +% +% \begin{macrocode} +\cs_new_nopar:Npn \dim_gset:Nn { \pref_global:D \dim_set:Nn } +\cs_generate_variant:Nn \dim_gset:Nn {cn,Nc,cc} +% \end{macrocode} +% \end{macro}\end{macro}\end{macro}\end{macro} +% \end{macro}\end{macro}\end{macro} % % \begin{macro}{\dim_zero:N} % \begin{macro}{\dim_gzero:N} % \begin{macro}{\dim_zero:c} -% \begin{macro}{\dim_gzero:N} +% \begin{macro}{\dim_gzero:c} % Resetting. % \begin{macrocode} -\def_new:Npn \dim_zero:N #1{#1\c_zero_skip} -\def_new:Npn \dim_gzero:N {\pref_global:D \dim_zero:N} -\def_new:Npn \dim_zero:c {\exp_args:Nc \dim_zero:N} -\def_new:Npn \dim_gzero:c {\exp_args:Nc \dim_gzero:N} +\cs_new_nopar:Npn \dim_zero:N #1 { #1\c_zero_skip } +\cs_generate_variant:Nn \dim_zero:N {c} +% \end{macrocode} +% +% \begin{macrocode} +\cs_new_nopar:Npn \dim_gzero:N { \pref_global:D \dim_zero:N } +\cs_generate_variant:Nn \dim_gzero:N {c} % \end{macrocode} % \end{macro} % \end{macro} @@ -841,17 +912,19 @@ % \begin{macro}{\dim_gadd:cn} % Addition. % \begin{macrocode} -\def_new:Npn \dim_add:Nn #1#2{ +\cs_new_nopar:Npn \dim_add:Nn #1#2{ % \end{macrocode} % We need to say |by| in case the first argment is a register % accessed by its number, e.g., |\dimen23|. % \begin{macrocode} \tex_advance:D#1 by \dim_eval:n{#2}\scan_stop: } -\def_new:Npn\dim_add:cn{\exp_args:Nc\dim_add:Nn} -\def_new:Npn\dim_add:Nc{\exp_args:NNc\dim_add:Nn} -\def_new:Npn \dim_gadd:Nn { \pref_global:D \dim_add:Nn } -\def_new:Npn\dim_gadd:cn{\exp_args:Nc\dim_gadd:Nn} +\cs_generate_variant:Nn \dim_add:Nn {cn,Nc} +% \end{macrocode} +% +% \begin{macrocode} +\cs_new_nopar:Npn \dim_gadd:Nn { \pref_global:D \dim_add:Nn } +\cs_generate_variant:Nn \dim_gadd:Nn {cn} % \end{macrocode} % \end{macro} % \end{macro} @@ -866,11 +939,13 @@ % \begin{macro}{\dim_gsub:cn} % Subtracting. % \begin{macrocode} -\def_new:Npn \dim_sub:Nn #1#2{\tex_advance:D#1-#2\scan_stop:} -\def_new:Npn\dim_sub:cn{\exp_args:Nc\dim_sub:Nn} -\def_new:Npn\dim_sub:Nc{\exp_args:NNc\dim_sub:Nn} -\def_new:Npn \dim_gsub:Nn {\pref_global:D \dim_sub:Nn } -\def_new:Npn\dim_gsub:cn{\exp_args:Nc\dim_gsub:Nn} +\cs_new_nopar:Npn \dim_sub:Nn #1#2 { \tex_advance:D#1-#2\scan_stop: } +\cs_generate_variant:Nn \dim_sub:Nn {cn,Nc} +% \end{macrocode} +% +% \begin{macrocode} +\cs_new_nopar:Npn \dim_gsub:Nn { \pref_global:D \dim_sub:Nn } +\cs_generate_variant:Nn \dim_gsub:Nn {cn} % \end{macrocode} % \end{macro} % \end{macro} @@ -882,12 +957,22 @@ % \begin{macro}{\dim_use:c} % Accessing a \meta{dim}. % \begin{macrocode} -\let_new:NN \dim_use:N \tex_the:D -\def_new:Npn \dim_use:c {\exp_args:Nc\dim_use:N} +\cs_new_eq:NN \dim_use:N \tex_the:D +\cs_generate_variant:Nn \dim_use:N {c} % \end{macrocode} % \end{macro} % \end{macro} % +% \begin{macro}{\dim_show:N} +% \begin{macro}{\dim_show:c} +% Diagnostics. +% \begin{macrocode} +\cs_new_eq:NN \dim_show:N \tex_showthe:D +\cs_new_nopar:Npn \dim_show:c #1 { \dim_show:N \cs:w #1 \cs_end: } +% \end{macrocode} +% \end{macro} +% \end{macro} +% % \begin{macro}{\l_tmpa_dim} % \begin{macro}{\l_tmpb_dim} % \begin{macro}{\l_tmpc_dim} @@ -914,8 +999,8 @@ % \begin{macro}{\c_max_dim} % Just aliases. % \begin{macrocode} -\let_new:NN \c_zero_dim \c_zero_skip -\let_new:NN \c_max_dim \c_max_skip +\cs_new_eq:NN \c_zero_dim \c_zero_skip +\cs_new_eq:NN \c_max_dim \c_max_skip % \end{macrocode} % \end{macro} % \end{macro} @@ -923,78 +1008,47 @@ % \begin{macro}{\dim_eval:n} % Evaluating a calc expression. % \begin{macrocode} -\def_new:Npn \dim_eval:n #1 {\etex_dimexpr:D #1 \scan_stop:} +\cs_new_nopar:Npn \dim_eval:n #1 { \etex_dimexpr:D #1 \scan_stop: } % \end{macrocode} % \end{macro} % % \begin{macro}{\if_dim:w} % The comparison primitive. % \begin{macrocode} -\let_new:NN \if_dim:w \tex_ifdim:D +\cs_new_eq:NN \if_dim:w \tex_ifdim:D % \end{macrocode} % \end{macro} % -% \begin{macro}{\dim_compare:nNnTF} -% \begin{macro}{\dim_compare:nNnT} -% \begin{macro}{\dim_compare:nNnF} -% Check the expression and choose branch. -% \begin{macrocode} -\def_new:Npn \dim_compare:nNnTF #1#2#3{ - \if_dim:w \dim_eval:n {#1} #2 \dim_eval:n {#3} - \exp_after:NN \use_arg_i:nn - \else: - \exp_after:NN \use_arg_ii:nn - \fi: -} -\def_new:Npn \dim_compare:nNnT #1#2#3{ - \if_dim:w \dim_eval:n {#1} #2 \dim_eval:n {#3} - \exp_after:NN \use_arg_ii:nn - \fi: - \use_none:n -} -\def_new:Npn \dim_compare:nNnF #1#2#3{ - \if_dim:w \dim_eval:n {#1} #2 \dim_eval:n {#3} - \exp_after:NN \use_none:n - \else: - \exp_after:NN \use_arg_i:n - \fi: -} -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} % % \begin{macro}{\dim_compare_p:nNn} -% A predicate function. +% \begin{macro}[TF]{\dim_compare:nNn} % \begin{macrocode} -\def_new:Npn \dim_compare_p:nNn #1#2#3{ +\prg_new_conditional:Nnn \dim_compare:nNn {p,TF,T,F} { \if_dim:w \dim_eval:n {#1} #2 \dim_eval:n {#3} - \c_true - \else: - \c_false - \fi: + \prg_return_true: \else: \prg_return_false: \fi: } % \end{macrocode} % \end{macro} +% \end{macro} % -% \begin{macro}{\dim_while:nNnT} -% \begin{macro}{\dim_while:nNnF} -% \begin{macro}{\dim_dowhile:nNnT} -% \begin{macro}{\dim_dowhile:nNnF} -% "while" and "do-while" functions for dimensions. Same as for the +% \begin{macro}{\dim_while_do:nNnn} +% \begin{macro}{\dim_until_do:nNnn} +% \begin{macro}{\dim_do_while:nNnn} +% \begin{macro}{\dim_do_until:nNnn} +% "while_do" and "do_while" functions for dimensions. Same as for the % "int" type only the names have changed. % \begin{macrocode} -\def_new:Npn \dim_while:nNnT #1#2#3#4{ - \dim_compare:nNnT {#1}#2{#3}{#4 \dim_while:nNnT {#1}#2{#3}{#4}} +\cs_new_nopar:Npn \dim_while_do:nNnn #1#2#3#4{ + \dim_compare:nNnT {#1}#2{#3}{#4 \dim_while_do:nNnn {#1}#2{#3}{#4}} } -\def_new:Npn \dim_while:nNnF #1#2#3#4{ - \dim_compare:nNnF {#1}#2{#3}{#4 \dim_while:nNnF {#1}#2{#3}{#4}} +\cs_new_nopar:Npn \dim_until_do:nNnn #1#2#3#4{ + \dim_compare:nNnF {#1}#2{#3}{#4 \dim_until_do:nNnn {#1}#2{#3}{#4}} } -\def_new:Npn \dim_dowhile:nNnT #1#2#3#4{ - #4 \dim_compare:nNnT {#1}#2{#3}{\dim_dowhile:nNnT {#1}#2{#3}{#4}} +\cs_new_nopar:Npn \dim_do_while:nNnn #1#2#3#4{ + #4 \dim_compare:nNnT {#1}#2{#3}{\dim_do_while:nNnn {#1}#2{#3}{#4}} } -\def_new:Npn \dim_dowhile:nNnF #1#2#3#4{ - #4 \dim_compare:nNnF {#1}#2{#3}{\dim_dowhile:nNnF {#1}#2{#3}{#4}} +\cs_new_nopar:Npn \dim_do_until:nNnn #1#2#3#4{ + #4 \dim_compare:nNnF {#1}#2{#3}{\dim_do_until:nNnn {#1}#2{#3}{#4}} } % \end{macrocode} % \end{macro} @@ -1003,20 +1057,25 @@ % \end{macro} % % -% \subsubsection{Muskips} +% \subsection{Muskips} % % \begin{macro}{\muskip_new:N} -% \begin{macro}{\muskip_new_l:N} +%^^A \begin{macro}{\muskip_new_l:N} % And then we add muskips. % \begin{macrocode} %<*initex> \alloc_setup_type:nnn {muskip} \c_zero \c_max_register_num -\def_new:Npn \muskip_new:N #1{\alloc_reg:NnNN g {muskip} \tex_muskipdef:D #1} -\def_new:Npn \muskip_new_l:N #1{\alloc_reg:NnNN l {muskip} \tex_muskipdef:D #1} +\cs_new_nopar:Npn \muskip_new:N #1{\alloc_reg:NnNN g {muskip} \tex_muskipdef:D #1} +\cs_new_nopar:Npn \muskip_new_l:N #1{\alloc_reg:NnNN l {muskip} \tex_muskipdef:D #1} %</initex> -%<package>\let_new:NN \muskip_new:N \newmuskip % nicked from LaTeX +%<*package> +\cs_new_nopar:Npn \muskip_new:N #1 { + \chk_if_free_cs:N #1 + \newmuskip #1 +} +%</package> % \end{macrocode} -% \end{macro} +%^^A \end{macro} % \end{macro} % % \begin{macro}{\muskip_set:Nn} @@ -1027,12 +1086,12 @@ % \begin{macro}{\muskip_gsub:Nn} % Simple functions for muskips. % \begin{macrocode} -\def_new:Npn \muskip_set:Nn#1#2{#1\etex_muexpr:D#2\scan_stop:} -\def_new:Npn \muskip_gset:Nn{\pref_global:D\muskip_set:Nn} -\def_new:Npn \muskip_add:Nn#1#2{\tex_advance:D#1\etex_muexpr:D#2\scan_stop:} -\def_new:Npn \muskip_gadd:Nn{\pref_global:D\muskip_add:Nn} -\def_new:Npn \muskip_sub:Nn#1#2{\tex_advance:D#1-\etex_muexpr:D#2\scan_stop:} -\def_new:Npn \muskip_gsub:Nn{\pref_global:D\muskip_sub:Nn} +\cs_new_nopar:Npn \muskip_set:Nn#1#2{#1\etex_muexpr:D#2\scan_stop:} +\cs_new_nopar:Npn \muskip_gset:Nn{\pref_global:D\muskip_set:Nn} +\cs_new_nopar:Npn \muskip_add:Nn#1#2{\tex_advance:D#1\etex_muexpr:D#2\scan_stop:} +\cs_new_nopar:Npn \muskip_gadd:Nn{\pref_global:D\muskip_add:Nn} +\cs_new_nopar:Npn \muskip_sub:Nn#1#2{\tex_advance:D#1-\etex_muexpr:D#2\scan_stop:} +\cs_new_nopar:Npn \muskip_gsub:Nn{\pref_global:D\muskip_sub:Nn} % \end{macrocode} % \end{macro} % \end{macro} @@ -1041,50 +1100,18 @@ % \end{macro} % \end{macro} % +% \begin{macro}{\muskip_use:N} +% Accessing a \meta{muskip}. % \begin{macrocode} -%</initex|package> +\cs_new_eq:NN \muskip_use:N \tex_the:D % \end{macrocode} +% \end{macro} % -% \endinput -% -% $Log$ -% Revision 1.18 2006/03/20 18:26:40 braams -% Updated the copyright notice (2006) and demoted all implementation -% sections to subsections and so on to clean up the toc for source3.tex -% -% Revision 1.17 2006/01/27 11:22:38 morten -% Added \muskip_set:Nn and friends (since l3calc uses them). -% -% Revision 1.16 2006/01/17 22:46:37 morten -% Moved \skip_eval:n earlier to avoid error. -% -% Revision 1.15 2006/01/17 22:05:35 morten -% Minor updates -% -% Revision 1.14 2006/01/14 19:13:16 morten -% Added operations for \vskip and \hskip -% -% Revision 1.13 2005/12/27 15:54:44 morten -% Changed RCS information retrieval -% -% Revision 1.12 2005/10/27 22:56:15 morten -% Moved \if_dim:w to this module. -% -% Revision 1.11 2005/04/12 12:07:10 morten -% Added muskips -% -% Revision 1.10 2005/04/09 21:09:48 morten -% Both documentation and implementation cleaned up. -% -% Revision 1.9 2005/04/06 22:35:57 braams -% Now we have register allocation fitted -% -% Revision 1.8 2005/03/26 21:05:42 morten -% Make \c_zero_skip different from \c_zero -% -% Revision 1.7 2005/03/16 22:35:47 braams -% Added the tweaks necessary to be able to load with initex +% \begin{macrocode} +%</initex|package> +% \end{macrocode} % -% Revision 1.6 2005/03/11 21:42:48 braams -% Fixed the use of RCS information; added \StopEventually +% \end{implementation} +% \PrintIndex % +% \endinput diff --git a/Master/texmf-dist/source/latex/expl3/l3tl.dtx b/Master/texmf-dist/source/latex/expl3/l3tl.dtx new file mode 100644 index 00000000000..e63646016e8 --- /dev/null +++ b/Master/texmf-dist/source/latex/expl3/l3tl.dtx @@ -0,0 +1,2269 @@ +% \iffalse +%% File: l3tl.dtx Copyright (C) 1990-2009 LaTeX3 project +%% +%% It may be distributed and/or modified under the conditions of the +%% LaTeX Project Public License (LPPL), either version 1.3c of this +%% license or (at your option) any later version. The latest version +%% of this license is in the file +%% +%% http://www.latex-project.org/lppl.txt +%% +%% This file is part of the ``expl3 bundle'' (The Work in LPPL) +%% and all files in that bundle must be distributed together. +%% +%% The released version of this bundle is available from CTAN. +%% +%% ----------------------------------------------------------------------- +%% +%% The development version of the bundle can be found at +%% +%% http://www.latex-project.org/svnroot/experimental/trunk/ +%% +%% for those people who are interested. +%% +%%%%%%%%%%% +%% NOTE: %% +%%%%%%%%%%% +%% +%% Snapshots taken from the repository represent work in progress and may +%% not work or may contain conflicting material! We therefore ask +%% people _not_ to put them into distributions, archives, etc. without +%% prior consultation with the LaTeX Project Team. +%% +%% ----------------------------------------------------------------------- +% +%<*driver|package> +\RequirePackage{l3names} +%</driver|package> +%\fi +\GetIdInfo$Id: l3tl.dtx 1365 2009-05-31 17:26:17Z mittelba $ + {L3 Experimental Token Lists} +%\iffalse +%<*driver> +%\fi +\ProvidesFile{\filename.\filenameext} + [\filedate\space v\fileversion\space\filedescription] +%\iffalse +\documentclass[full]{l3doc} +\begin{document} +\DocInput{l3tl.dtx} +\end{document} +%</driver> +% \fi +% +% +% \title{The \textsf{l3tl} package\thanks{This file +% has version number \fileversion, last +% revised \filedate.}\\ +% Token Lists} +% \author{\Team} +% \date{\filedate} +% \maketitle +% +% \def\tlvar{tl var.} +% \def\tlist{token list} +% +% \begin{documentation} +% +% \LaTeX3 stores token lists in variables also called `token lists'. +% Variables of this type get the suffix "tl" and functions of this type +% have the prefix "tl". To use a token list variable you simply call +% the corresponding variable. +% +% Often you find yourself with not a token list variable but an +% arbitrary token list which has to undergo certain tests. We will \emph{also} +% prefix these functions with "tl". While token list variables are +% always single tokens, token lists are always surrounded by +% braces. +% +% \section{Functions} +% +% \begin{function}{\tl_new:N | +% \tl_new:c | +% \tl_new:Nn | +% \tl_new:cn | +% \tl_new:Nx } +% \begin{syntax} +% "\tl_new:Nn" <\tlvar> \Arg{initial token list} +% \end{syntax} +% Defines <\tlvar> to be a new variable to store a token list. +% <initial token list> is the initial value of <\tlvar>. This +% makes it possible to assign values to a constant token list variable. +% +% The form "\tl_new:N" initializes the token list variable with an empty value. +% \end{function} +% +% \begin{function}{% +% \tl_use:N | +% \tl_use:c +% } +% \begin{syntax} +% "\tl_use:N" <\tlvar> +% \end{syntax} +% Function that inserts the <\tlvar> into the processing stream. Instead of +% |\tl_use:N| simply placing the <\tlvar> into the input stream is also +% supported. |\tl_use:c| will complain if the <\tlvar> hasn't been declared +% previously! +% \end{function} +% +% \begin{function}{\tl_show:N | +% \tl_show:c | +% \tl_show:n } +% \begin{syntax} +% "\tl_show:N" <\tlvar> +% "\tl_show:n" \Arg{\tlist} +% \end{syntax} +% Function that pauses the compilation and displays the <\tlvar> +% or <\tlist> on the console output and in the log file. +% \end{function} +% +% \begin{function}{% +% \tl_set:Nn | +% \tl_set:Nc | +% \tl_set:NV | +% \tl_set:No | +% \tl_set:Nv | +% \tl_set:Nd | +% \tl_set:Nf | +% \tl_set:Nx | +% \tl_set:cn | +% \tl_set:co | +% \tl_set:cV | +% \tl_set:cx | +% \tl_gset:Nn | +% \tl_gset:Nc | +% \tl_gset:No | +% \tl_gset:NV | +% \tl_gset:Nd | +% \tl_gset:Nv | +% \tl_gset:Nx | +% \tl_gset:cn | +% \tl_gset:cx } +% \begin{syntax} +% "\tl_set:Nn" <\tlvar> \Arg{\tlist} +% \end{syntax} +% Defines <\tlvar> to hold the token list <\tlist>. Global +% variants of this command assign the value globally the other variants +% expand the <\tlist> up to a certain level before the assignment +% or interpret the <\tlist> as a character list and form a control +% sequence out of it. +% \end{function} +% +% \begin{function}{% +% \tl_clear:N | +% \tl_clear:c | +% \tl_gclear:N | +% \tl_gclear:c +% } +% \begin{syntax} +% "\tl_clear:N" <\tlvar> +% \end{syntax} +% The <\tlvar> is locally or globally cleared. The "c" variants will +% generate a control sequence name which is then interpreted as +% <\tlvar> before clearing. +% \end{function} +% +% \begin{function}{% +% \tl_clear_new:N | +% \tl_clear_new:c | +% \tl_gclear_new:N | +% \tl_gclear_new:c | +% } +% \begin{syntax} +% "\tl_clear_new:N" <\tlvar> +% \end{syntax} +% These functions check if <\tlvar> exists. If it does it will be cleared; +% if it doesn't it will be allocated. +% \end{function} +% +% \begin{function}{% +% \tl_put_left:Nn | +% \tl_put_left:NV | +% \tl_put_left:No | +% \tl_put_left:Nx | +% \tl_put_left:cn | +% \tl_put_left:cV | +% \tl_put_left:co | +% } +% \begin{syntax} +% "\tl_put_left:Nn" <\tlvar> \Arg{\tlist} +% \end{syntax} +% These functions will append <\tlist> to the left of +% <\tlvar>. <\tlist> might be subject to expansion before assignment. +% \end{function} +% +% \begin{function}{% +% \tl_put_right:Nn | +% \tl_put_right:NV | +% \tl_put_right:No | +% \tl_put_right:Nx | +% \tl_put_right:cn | +% \tl_put_right:cV | +% \tl_put_right:co | +% } +% \begin{syntax} +% "\tl_put_right:Nn" <\tlvar> \Arg{\tlist} +% \end{syntax} +% These functions append <\tlist> to the right of +% <\tlvar>. +% \end{function} +% +% \begin{function}{% +% \tl_gput_left:Nn | +% \tl_gput_left:No | +% \tl_gput_left:NV | +% \tl_gput_left:Nx | +% \tl_gput_left:cn | +% \tl_gput_left:co | +% \tl_gput_left:cV | +% } +% \begin{syntax} +% "\tl_gput_left:Nn" <\tlvar> \Arg{\tlist} +% \end{syntax} +% These functions will append <\tlist> globally to the left of +% <\tlvar>. +% \end{function} +% +% \begin{function}{% +% \tl_gput_right:Nn| +% \tl_gput_right:No| +% \tl_gput_right:NV| +% \tl_gput_right:Nx| +% \tl_gput_right:cn| +% \tl_gput_right:co| +% \tl_gput_right:cV| +% } +% \begin{syntax} +% "\tl_gput_right:Nn" <\tlvar> \Arg{\tlist} +% \end{syntax} +% These functions will globally append <\tlist> to the right of +% <\tlvar>. +% \end{function} +% +% A word of warning is appropriate here: Token list variables are +% implemented as macros and as such currently inherit some of the +% peculiarities of how \TeX\ handles "#"s in the argument of +% macros. In particular, the following actions are legal +% \begin{verbatim} +% \tl_set:Nn \l_tmpa_tl{##1} +% \tl_put_right:Nn \l_tmpa_tl{##2} +% \tl_set:No \l_tmpb_tl{\l_tmpa_tl ##3} +% \end{verbatim} +% |x| type expansions where macros being expanded contain |#|s do not +% work and will not work until there is an |\expanded| primitive in +% the engine. If you want them to work you must double |#|s another +% level. +% +% +% \begin{function}{% +% \tl_set_eq:NN | +% \tl_set_eq:Nc | +% \tl_set_eq:cN | +% \tl_set_eq:cc | +% \tl_gset_eq:NN | +% \tl_gset_eq:Nc | +% \tl_gset_eq:cN | +% \tl_gset_eq:cc | +% } +% \begin{syntax} +% "\tl_set_eq:NN" <\tlvar1> <\tlvar2> +% \end{syntax} +% Fast form for +% \begin{syntax} +% "\tl_set:No" <\tlvar1> \Arg{\tlvar2} +% \end{syntax} +% when <\tlvar2> is known to be a variable of type "tl". +% \end{function} +% +% \begin{function}{\tl_to_str:N | +% \tl_to_str:c +% } +% \begin{syntax} +% "\tl_to_str:N" <\tlvar> +% \end{syntax} +% This function returns the token list kept in <\tlvar> as a string list +% with all characters catcoded to `other'. +% \end{function} +% +% \begin{function}{ \tl_to_str:n } +% \begin{syntax} +% "\tl_to_str:n" \Arg{\tlist} +% \end{syntax} +% This function turns its argument into a string where all characters +% have catcode `other'. +% \begin{texnote} +% This is the \eTeX\ primitive \tn{detokenize}. +% \end{texnote} +% \end{function} +% +% +% \begin{function}{ \tl_rescan:nn } +% \begin{syntax} +% "\tl_rescan:nn" \Arg{catcode setup} \Arg{\tlist} +% \end{syntax} +% Returns the result of re-tokenising <\tlist> with the catcode setup +% (and whatever other redefinitions) specified. This is useful because +% the catcodes of characters are `frozen' when first tokenised; this allows +% their meaning to be changed even after they've been read as an argument. +% Also see "\tl_set_rescan:Nnn" below. +% \begin{texnote} +% This is a wrapper around \eTeX's "\scantokens". +% \end{texnote} +% \end{function} +% +% \begin{function}{ \tl_set_rescan:Nnn | \tl_set_rescan:Nnx | +% \tl_gset_rescan:Nnn | \tl_gset_rescan:Nnx } +% \begin{syntax} +% "\tl_set_rescan:Nnn" <\tlvar> \Arg{catcode setup} \Arg{\tlist} +% \end{syntax} +% Sets <\tlvar> to the result of re-tokenising <\tlist> with the catcode setup +% (and whatever other redefinitions) specified. +% \begin{texnote} +% This is a wrapper around \eTeX's "\scantokens". +% \end{texnote} +% \end{function} +% +% +% +% \section{Predicates and conditionals} +% +% \begin{function}{\tl_if_empty_p:N / (EXP) | +% \tl_if_empty_p:c / (EXP) +% } +% \begin{syntax} +% "\tl_if_empty_p:N" <\tlvar> +% \end{syntax} +% This predicate returns `true' if <\tlvar> is `empty' i.e., doesn't +% contain any tokens. +% \end{function} +% +% \begin{function}{\tl_if_empty:N / (TF)(EXP) | +% \tl_if_empty:c / (TF)(EXP) | +% } +% \begin{syntax} +% "\tl_if_empty:NTF" <\tlvar> \Arg{true code} \Arg{false code} +% \end{syntax} +% Execute <true code> if <\tlvar> is empty and <false code> if it +% contains any tokens. +% \end{function} +% +% \begin{function}{\tl_if_eq_p:NN / (EXP) | +% \tl_if_eq_p:cN / (EXP) | +% \tl_if_eq_p:Nc / (EXP) | +% \tl_if_eq_p:cc / (EXP) | +% } +% \begin{syntax} +% "\tl_if_eq_p:NN" <\tlvar1> <\tlvar2> +% \end{syntax} +% Predicate function which returns `true' if the two token list +% variables are identical and `false' otherwise. +% \end{function} +% +% \begin{function}{ +% \tl_if_eq:NN / (TF)(EXP) | +% \tl_if_eq:cN / (TF)(EXP) | +% \tl_if_eq:Nc / (TF)(EXP) | +% \tl_if_eq:cc / (TF)(EXP) | +% } +% \begin{syntax} +% "\tl_if_eq:NNTF" <\tlvar1> <\tlvar2> \Arg{true code} \Arg{false code} +% \end{syntax} +% Execute <true code> if <\tlvar1> holds the same token list as <\tlvar2> +% and <false code> otherwise. +% \end{function} +% +% +% \begin{function}{\tl_if_eq:nn / (TF)(EXP) | +% \tl_if_eq:nV / (TF)(EXP) | +% \tl_if_eq:no / (TF)(EXP) | +% \tl_if_eq:Vn / (TF)(EXP) | +% \tl_if_eq:on / (TF)(EXP) | +% \tl_if_eq:VV / (TF)(EXP) | +% \tl_if_eq:oo / (TF)(EXP) | +% \tl_if_eq:xx / (TF)(EXP) | +% \tl_if_eq:xn / (TF)(EXP) | +% \tl_if_eq:nx / (TF)(EXP) | +% \tl_if_eq:xV / (TF)(EXP) | +% \tl_if_eq:xo / (TF)(EXP) | +% \tl_if_eq:Vx / (TF)(EXP) | +% \tl_if_eq:ox / (TF)(EXP) } +% \begin{syntax} +% "\tl_if_eq:nnTF" \Arg{tlist1} \Arg{tlist2} \Arg{true code} \Arg{false code} +% \end{syntax} +% Execute <true code> if the two token lists <tlist1> and <tlist2> are +% identical. These functions are expandable if a new enough version of +% pdf\TeX\ is being used. +% \end{function}% +% +% \begin{function}{\tl_if_eq_p:nn / (EXP) | +% \tl_if_eq_p:nV / (EXP) | +% \tl_if_eq_p:no / (EXP) | +% \tl_if_eq_p:Vn / (EXP) | +% \tl_if_eq_p:on / (EXP) | +% \tl_if_eq_p:VV / (EXP) | +% \tl_if_eq_p:oo / (EXP) | +% \tl_if_eq_p:xx / (EXP) | +% \tl_if_eq_p:xn / (EXP) | +% \tl_if_eq_p:nx / (EXP) | +% \tl_if_eq_p:xV / (EXP) | +% \tl_if_eq_p:xo / (EXP) | +% \tl_if_eq_p:Vx / (EXP) | +% \tl_if_eq_p:ox / (EXP) } +% \begin{syntax} +% "\tl_if_eq_p:nn" \Arg{tlist1} \Arg{tlist2} +% \end{syntax} +% Predicates function which returns `true' if the two token list +% are identical and `false' otherwise. These are only defined if a new enough version +% of pdf\TeX\ is in use. +% \end{function} +% +% +% \begin{function}{\tl_if_empty_p:n / (EXP) | +% \tl_if_empty_p:V / (EXP) | +% \tl_if_empty_p:o / (EXP) | +% \tl_if_empty:n / (TF) | +% \tl_if_empty:V / (TF) | +% \tl_if_empty:o / (TF) | +% } +% \begin{syntax} +% "\tl_if_empty:nTF" \Arg{\tlist} \Arg{true code} \Arg{false code} +% \end{syntax} +% Execute <true code> if <\tlist> doesn't contain any tokens and <false +% code> otherwise. +% \end{function} +% +% \begin{function}{\tl_if_blank_p:n / (EXP)| +% \tl_if_blank:n / (TF)(EXP)| +% \tl_if_blank_p:V / (EXP)| +% \tl_if_blank_p:o / (EXP)| +% \tl_if_blank:V / (TF)(EXP)| +% \tl_if_blank:o / (TF)(EXP)| +% } +% \begin{syntax} +% "\tl_if_blank:nTF" \Arg{\tlist} \Arg{true code} \Arg{false code} +% \end{syntax} +% Execute <true code> if <\tlist> is blank meaning that it is either +% empty or contains only blank spaces. +% \end{function} +% +% \begin{function}{\tl_to_lowercase:n | +% \tl_to_uppercase:n +% } +% \begin{syntax} +% "\tl_to_lowercase:n" \Arg{\tlist} +% \end{syntax} +% "\tl_to_lowercase:n" converts all tokens in <\tlist> to their +% lower case representation. Similar for "\tl_to_uppercase:n". +% \begin{texnote} +% These are the \TeX\ primitives \tn{lowercase} and \tn{uppercase} +% renamed. +% \end{texnote} +% \end{function} +% +% \section{Working with the contents of token lists} +% +% \begin{function}{% +% \tl_map_function:nN / (EXP) | +% \tl_map_function:NN | +% \tl_map_function:cN | +% } +% \begin{syntax} +% "\tl_map_function:nN" \Arg{\tlist} <function> \\ +% "\tl_map_function:NN" <\tlvar> <function> +% \end{syntax} +% Runs through all elements in a <\tlist> from left to right and places +% <function> in front of each element. As this function will also pick +% up elements in brace groups, the element is returned with braces and +% hence <function> should be a function with a |:n| suffix even though +% it may very well only deal with a single token. +% +% This function uses a +% purely expandable loop function and will stay so as long as +% <function> is expandable too. +% \end{function} +% +% \begin{function}{% +% \tl_map_inline:nn | +% \tl_map_inline:Nn | +% \tl_map_inline:cn | +% } +% \begin{syntax} +% "\tl_map_inline:nn" \Arg{\tlist} \Arg{inline~function} \\ +% "\tl_map_inline:Nn" <\tlvar> \Arg{inline~function} +% \end{syntax} +% Allows a syntax like "\tl_map_inline:nn" \Arg{\tlist} +% "{\token_to_str:N ##1}". This renders it non-expandable though. +% Remember to double the "#"s for each level. +% \end{function} +% +% +% \begin{function}{% +% \tl_map_variable:nNn | +% \tl_map_variable:NNn | +% \tl_map_variable:cNn | +% } +% \begin{syntax} +% "\tl_map_variable:nNn" \Arg{\tlist} <temp> \Arg{action} \\ +% "\tl_map_variable:NNn" <\tlvar> <temp> \Arg{action} +% \end{syntax} +% Assigns <temp> to each element on <\tlist> and executes <action>. +% As there is an assignment in this process it is not expandable. +% \begin{texnote} +% This is the \LaTeX2{} function \tn{@tfor} but with a more sane syntax. +% Also it works by tail recursion and so is faster as lists grow longer. +% \end{texnote} +% \end{function} +% +% \begin{function}{% +% \tl_map_break: | +% } +% \begin{syntax} +% "\tl_map_break:" +% \end{syntax} +% For breaking out of a loop. Must not be nested inside a primitive +% "\if" structure. +% \end{function} +% +% +% \begin{function}{ \tl_reverse:n | +% \tl_reverse:V | +% \tl_reverse:o | +% \tl_reverse:N } +% \begin{syntax} +% "\tl_reverse:n" "{"<token1><token2>...<token$\sb n$>"}"\\ +% "\tl_reverse:N" <\tlvar> +% \end{syntax} +% Reverse the token list (or the token list in the <\tlvar>) to result in +% <token$\sb n$>\dots<token2><token1>. +% Note that spaces in this +% token list are gobbled in the process. +% +% Note also that braces are lost in the process of reversing a <\tlvar>. +% That is,\\ +% "\tl_set:Nn \l_tmpa_tl {a{bcd}e} \tl_reverse:N \l_tmpa_tl"\\ +% will result in "ebcda". This behaviour is probably more of a bug than +% a feature. +% \end{function} +% +% \begin{function}{% +% \tl_elt_count:n / (EXP) | +% \tl_elt_count:V / (EXP) | +% \tl_elt_count:o / (EXP) | +% \tl_elt_count:N / (EXP) | +% } +% \begin{syntax} +% "\tl_elt_count:n" \Arg{\tlist} \\ +% "\tl_elt_count:N" <\tlvar> +% \end{syntax} +% Returns the number of elements in the token list. Brace groups +% encountered count as one element. Note that spaces in this +% token list are gobbled in the process. +% \end{function} +% +% +% \section{Variables and constants} +% +% \begin{variable}{\c_job_name_tl} +% 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 is set by \TeX{} and should not be overwritten by the package. +% \end{texnote} +% \end{variable} +% +% \begin{variable}{\c_empty_tl} +% 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}{% +% \l_tmpa_tl | +% \l_tmpb_tl | +% \g_tmpa_tl | +% \g_tmpb_tl +% } +% Scratch register for immediate use. They are not used by conditionals +% or predicate functions. +% \end{variable} +% +% \begin{variable}{% +% \l_tl_replace_toks | +% } +% Internal register used in the replace functions. +% \end{variable} +% +% \begin{variable}{% +% \l_testa_tl | +% \l_testb_tl | +% \g_testa_tl | +% \g_testb_tl | +% } +% Registers used for conditional processing if the engine doesn't +% support arbitrary string comparison. +% \end{variable} +% +% \begin{variable}{% +% \g_tl_inline_level_num | +% } +% Internal register used in the inline map functions. +% \end{variable}% +% +% \section{Searching for and replacing tokens} +% +% \begin{function}{ +% \tl_if_in:Nn / (TF) | +% \tl_if_in:cn / (TF) | +% \tl_if_in:nn / (TF) | +% \tl_if_in:Vn / (TF) | +% \tl_if_in:on / (TF) | +% } +% \begin{syntax} +% "\tl_if_in:NnTF" <\tlvar> \Arg{item} \Arg{true code} \Arg{false code} +% \end{syntax} +% Function that tests if <item> is in <\tlvar>. Depending on the result +% either <true code> or <false code> is executed. Note that <item> +% cannot contain brace groups nor "#"$_6$ tokens. +% \end{function} +% +% \begin{function}{ +% \tl_replace_in:Nnn | +% \tl_replace_in:cnn | +% \tl_greplace_in:Nnn | +% \tl_greplace_in:cnn | +% } +% \begin{syntax} +% "\tl_replace_in:Nnn" <\tlvar> \Arg{item1} \Arg{item2} +% \end{syntax} +% Replaces the leftmost occurrence of <item1> in <\tlvar> with +% <item2> if present, otherwise the <\tlvar> is left untouched. +% Note that <item1> +% cannot contain brace groups nor "#"$_6$ tokens, and <item2> +% cannot contain "#"$_6$ tokens. +% \end{function} +% +% \begin{function}{ +% \tl_replace_all_in:Nnn | +% \tl_replace_all_in:cnn | +% \tl_greplace_all_in:Nnn | +% \tl_greplace_all_in:cnn | +% } +% \begin{syntax} +% "\tl_replace_all_in:Nnn" <\tlvar> \Arg{item1} \Arg{item2} +% \end{syntax} +% Replaces \emph{all} occurrences of <item1> in <\tlvar> with +% <item2>. +% Note that <item1> +% cannot contain brace groups nor "#"$_6$ tokens, and <item2> +% cannot contain "#"$_6$ tokens. +% \end{function} +% +% +% \begin{function}{ +% \tl_remove_in:Nn | +% \tl_remove_in:cn | +% \tl_gremove_in:Nn | +% \tl_gremove_in:cn | +% } +% \begin{syntax} +% "\tl_remove_in:Nn" <\tlvar> \Arg{item} +% \end{syntax} +% Removes the leftmost occurrence of <item> from <\tlvar> if present. +% Note that <item> +% cannot contain brace groups nor "#"$_6$ tokens. +% \end{function} +% +% +% \begin{function}{ +% \tl_remove_all_in:Nn | +% \tl_remove_all_in:cn | +% \tl_gremove_all_in:Nn | +% \tl_gremove_all_in:cn | +% } +% \begin{syntax} +% "\tl_remove_all_in:Nn" <\tlvar> \Arg{item} +% \end{syntax} +% Removes \emph{all} occurrences of <item> from <\tlvar>. Note that <item> +% cannot contain brace groups nor "#"$_6$ tokens. +% \end{function} +% +% +% \section{Heads or tails?} +% +% Here are some functions for grabbing either the head or tail of a +% list and perform some tests on it. +% +% \begin{function}{% +% \tl_head:n | +% \tl_tail:n | +% \tl_tail:f | +% \tl_head_i:n | +% \tl_head_iii:n | +% \tl_head_iii:f | +% \tl_head:w | +% \tl_tail:w | +% \tl_head_i:w | +% \tl_head_iii:w +% } +% \begin{syntax} +% "\tl_head:n" "{" <token1><token2>...<token\,$\sb n$> "}" \\ +% "\tl_tail:n" "{" <token1><token2>...<token\,$\sb n$> "}" \\ +% "\tl_head:w" <token1><token2>...<token\,$\sb n$> "\q_nil" +% \end{syntax} +% These functions return either the head or the tail of a list, thus in +% the above example "\tl_head:n" would return <token1> and "\tl_tail:n" +% would return <token2>\dots<token\,$\sb n$>. "\tl_head_iii:n" returns the first +% three tokens. The ":w" versions require some care as they use a +% delimited argument internally. +% \begin{texnote} +% These are the Lisp functions "car" and "cdr" but with \LaTeX3 names. +% \end{texnote} +% \end{function} +% +% +% +% +% \begin{function}{% +% \tl_if_head_eq_meaning_p:nN / (EXP) | +% \tl_if_head_eq_meaning:nN / (TF)(EXP) | +% } +% \begin{syntax} +% "\tl_if_head_eq_meaning:nNTF" \Arg{\tlist} <token> +% \Arg{true} \Arg{false} +% \end{syntax} +% Returns <true> if the first token in <\tlist> is equal to +% <token> and <false> otherwise. The |meaning| version compares the +% two tokens with |\if_meaning:w|. +% \end{function} +% +% \begin{function}{% +% \tl_if_head_eq_charcode_p:nN / (EXP) | +% \tl_if_head_eq_charcode_p:fN / (EXP) | +% \tl_if_head_eq_charcode:nN / (TF)(EXP) | +% \tl_if_head_eq_charcode:fN / (TF)(EXP) | +% } +% \begin{syntax} +% "\tl_if_head_eq_charcode:nNTF" \Arg{\tlist} <token> +% \Arg{true} \Arg{false} +% \end{syntax} +% Returns <true> if the first token in <\tlist> is equal to +% <token> and <false> otherwise. The |meaning| version compares the +% two tokens with |\if_charcode:w| but it prevents expansion of +% them. If you want them to expand, you can use an |f| type expansion +% first (define |\tl_if_head_eq_charcode:fNTF| or similar). +% \end{function} +% +% \begin{function}{% +% \tl_if_head_eq_catcode_p:nN / (EXP) | +% \tl_if_head_eq_catcode:nN / (TF)(EXP) | +% } +% \begin{syntax} +% "\tl_if_head_eq_catcode:nNTF" \Arg{\tlist} <token> +% \Arg{true} \Arg{false} +% \end{syntax} +% Returns <true> if the first token in <\tlist> is equal to +% <token> and <false> otherwise. This version uses |\if_catcode:w| for +% the test but is otherwise identical to the |charcode| version. +% \end{function} +% +% +% \end{documentation} +% +% \begin{implementation} +% +% \section{\pkg{l3tl} implementation} +% +% We start by ensuring that the required packages are loaded. +% \begin{macrocode} +%<*package> +\ProvidesExplPackage + {\filename}{\filedate}{\fileversion}{\filedescription} +\package_check_loaded_expl: +%</package> +% \end{macrocode} +% \begin{macrocode} +%<*initex|package> +% \end{macrocode} +% +% A token list variable is a control sequence that holds tokens. The +% interface is similar to that for token registers, but beware that +% the behavior vis \'a vis |\cs_set_nopar:Npx| etc. \ldots{} is different. (You +% see this comes from Denys' implementation.) +% +% +% \subsection{Functions} +% +% \begin{macro}{\tl_new:N} +% \begin{macro}{\tl_new:c} +% \begin{macro}{\tl_new:Nn} +% \begin{macro}{\tl_new:cn} +% \begin{macro}{\tl_new:Nx} +% 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} +\cs_new:Npn \tl_new:Nn #1#2{ + \chk_if_free_cs:N #1 +% \end{macrocode} +% If checking we don't allow constants to be defined. +% \begin{macrocode} +%<*check> + \chk_var_or_const:N #1 +%</check> +% \end{macrocode} +% Otherwise any variable type is allowed. +% \begin{macrocode} + \cs_gset_nopar:Npn #1{#2} +} +\cs_generate_variant:Nn \tl_new:Nn {cn} +\cs_new:Npn \tl_new:Nx #1#2{ + \chk_if_free_cs:N #1 +%<check> \chk_var_or_const:N #1 + \cs_gset_nopar:Npx #1{#2} +} +\cs_new_nopar:Npn \tl_new:N #1{\tl_new:Nn #1{}} +\cs_new_nopar:Npn \tl_new:c #1{\tl_new:cn {#1}{}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\tl_use:N} +% \begin{macro}{\tl_use:c} +% Perhaps this should just be enabled when checking? +% \begin{macrocode} +\cs_new_nopar:Npn \tl_use:N #1 { + \if_meaning:w #1 \tex_relax:D +% \end{macrocode} +% If \m{\tlvar} equals |\tex_relax:D| it is probably stemming from a +% |\cs:w|\dots|\cs_end:| that was created by mistake somewhere. +% \begin{macrocode} + \msg_kernel_bug:x {Token~list~variable~ `\token_to_str:N #1'~ + has~ an~ erroneous~ structure!} + \else: + \exp_after:wN #1 + \fi: +} +\cs_generate_variant:Nn \tl_use:N {c} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\tl_show:N,\tl_show:c,\tl_show:n} +% Showing a \meta{\tlvar} is just "\show"ing it and I don't really care +% about checking that it's malformed at this stage. +% \begin{macrocode} +\cs_new_nopar:Npn \tl_show:N #1 { \cs_show:N #1 } +\cs_generate_variant:Nn \tl_show:N {c} +\cs_set_eq:NN \tl_show:n \etex_showtokens:D +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\tl_set:Nn} +% \begin{macro}{\tl_set:NV} +% \begin{macro}{\tl_set:No} +% \begin{macro}{\tl_set:Nv} +% \begin{macro}{\tl_set:Nd} +% \begin{macro}{\tl_set:Nf} +% \begin{macro}{\tl_set:Nx} +% \begin{macro}{\tl_set:cn} +% \begin{macro}{\tl_set:cV} +% \begin{macro}{\tl_set:co} +% \begin{macro}{\tl_set:cx} +% \begin{macro}{\tl_gset:Nn} +% \begin{macro}{\tl_gset:NV} +% \begin{macro}{\tl_gset:No} +% \begin{macro}{\tl_gset:Nv} +% \begin{macro}{\tl_gset:Nd} +% \begin{macro}{\tl_gset:Nx} +% \begin{macro}{\tl_gset:cn} +% \begin{macro}{\tl_gset:cx} +% To set token lists to a specific value to type of functions are +% available: |\tl_set_eq:NN| takes two token-lists as its +% arguments assign the first the contents of the second; +% |\tl_set:Nn| has as its second argument a `real' list of tokens. +% One can view |\tl_set_eq:NN| as a special form of |\tl_set:No|. +% 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> +\cs_new:Npn \tl_set:Nn #1#2{ + \chk_exist_cs:N #1 \cs_set_nopar: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 built-in. +% \begin{macrocode} + \chk_local_or_pref_global:N #1 +} +\cs_new:Npn \tl_set:Nx #1#2{ + \chk_exist_cs:N #1 \cs_set_nopar:Npx #1{#2} \chk_local:N #1 +} +% \end{macrocode} +% The the global versions. +% \begin{macrocode} +\cs_new:Npn \tl_gset:Nn #1#2{ + \chk_exist_cs:N #1 \cs_gset_nopar:Npn #1{#2} \chk_global:N #1 +} +\cs_new:Npn \tl_gset:Nx #1#2{ + \chk_exist_cs:N #1 \cs_gset_nopar:Npx #1{#2} \chk_global:N #1 +} +%</check> +% \end{macrocode} +% For some functions like |\tl_set:Nn| we need to define the +% `non-check' version with arguments since we want to allow +% constructions like |\tl_set:Nn\l_tmpa_tl\foo| and so we can't +% use the primitive \TeX{} command. +% \begin{macrocode} +%<*!check> +\cs_new:Npn\tl_set:Nn#1#2{\cs_set_nopar:Npn#1{#2}} +\cs_new:Npn\tl_set:Nx#1#2{\cs_set_nopar:Npx#1{#2}} +\cs_new:Npn\tl_gset:Nn#1#2{\cs_gset_nopar:Npn#1{#2}} +\cs_new:Npn\tl_gset:Nx#1#2{\cs_gset_nopar:Npx#1{#2}} +%</!check> +% \end{macrocode} +% The remaining functions can just be defined with help from the +% expansion module. +% \begin{macrocode} +\cs_generate_variant:Nn \tl_set:Nn {NV,No,Nv,Nd,Nf,cn,cV,co,cx} +\cs_generate_variant:Nn \tl_gset:Nn {NV,No,Nv,Nd,cn,cx} +% \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} +% \end{macro} +% +% \begin{macro}{\tl_set_eq:NN} +% \begin{macro}{\tl_set_eq:Nc} +% \begin{macro}{\tl_set_eq:cN} +% \begin{macro}{\tl_set_eq:cc} +% \begin{macro}{\tl_gset_eq:NN} +% \begin{macro}{\tl_gset_eq:Nc} +% \begin{macro}{\tl_gset_eq:cN} +% \begin{macro}{\tl_gset_eq:cc} +% For setting token list variables equal to each other. First checking: +% \begin{macrocode} +%<*check> +\cs_new_nopar:Npn \tl_set_eq:NN #1#2{ + \chk_exist_cs:N #1 \cs_set_eq:NN #1#2 + \chk_local_or_pref_global:N #1 \chk_var_or_const:N #2 +} +\cs_new_nopar:Npn \tl_gset_eq:NN #1#2{ + \chk_exist_cs:N #1 \cs_gset_eq:NN #1#2 + \chk_global:N #1 \chk_var_or_const:N #2 +} +%</check> +% \end{macrocode} +% Non-checking versions are easy. +% \begin{macrocode} +%<*!check> +\cs_new_eq:NN \tl_set_eq:NN \cs_set_eq:NN +\cs_new_eq:NN \tl_gset_eq:NN \cs_gset_eq:NN +%</!check> +% \end{macrocode} +% The rest again with the expansion module. +% \begin{macrocode} +\cs_generate_variant:Nn \tl_set_eq:NN {Nc,c,cc} +\cs_generate_variant:Nn \tl_gset_eq:NN {Nc,c,cc} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% +% \begin{macro}{\tl_clear:N} +% \begin{macro}{\tl_clear:c} +% \begin{macro}{\tl_gclear:N} +% \begin{macro}{\tl_gclear:c} +% Clearing a token list variable. +% \begin{macrocode} +\cs_new_nopar:Npn \tl_clear:N #1{\tl_set_eq:NN #1\c_empty_tl} +\cs_generate_variant:Nn \tl_clear:N {c} +\cs_new_nopar:Npn \tl_gclear:N #1{\tl_gset_eq:NN #1\c_empty_tl} +\cs_generate_variant:Nn \tl_gclear:N {c} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\tl_clear_new:N} +% \begin{macro}{\tl_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> +\cs_new_nopar:Npn \tl_clear_new:N #1{ + \chk_var_or_const:N #1 + \if_predicate:w \cs_if_exist_p:N #1 + \tl_clear:N #1 + \else: + \tl_new:Nn #1{} + \fi: +} +%</check> +%<-check>\cs_new_eq:NN \tl_clear_new:N \tl_clear:N +\cs_generate_variant:Nn \tl_clear_new:N {c} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\tl_gclear_new:N} +% \begin{macro}{\tl_gclear_new:c} +% These are the global versions of the above. +% \begin{macrocode} +%<*check> +\cs_new_nopar:Npn \tl_gclear_new:N #1{ + \chk_var_or_const:N #1 + \if_predicate:w \cs_if_exist_p:N #1 + \tl_gclear:N #1 + \else: + \tl_new:Nn #1{} + \fi:} +%</check> +%<-check>\cs_new_eq:NN \tl_gclear_new:N \tl_gclear:N +\cs_generate_variant:Nn \tl_gclear_new:N {c} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\tl_put_left:Nn} +% \begin{macro}{\tl_put_left:NV} +% \begin{macro}{\tl_put_left:No} +% \begin{macro}{\tl_put_left:Nx} +% \begin{macro}{\tl_put_left:cn} +% \begin{macro}{\tl_put_left:cV} +% \begin{macro}{\tl_put_left:co} +% \begin{macro}{\tl_gput_left:Nn} +% \begin{macro}{\tl_gput_left:NV} +% \begin{macro}{\tl_gput_left:No} +% \begin{macro}{\tl_gput_left:Nx} +% \begin{macro}{\tl_gput_left:cn} +% \begin{macro}{\tl_gput_left:cV} +% \begin{macro}{\tl_gput_left:co} +% We can add tokens to the left (either globally or locally). It is +% not quite as easy as we would like because we have to ensure the +% assignments +% \begin{verbatim} +% \tl_set:Nn \l_tmpa_tl{##1abc##2def} +% \tl_set:Nn \l_tmpb_tl{##1abc} +% \tl_put_right:Nn \l_tmpb_tl {##2def} +% \end{verbatim} +% cause |\l_tmpa_tl| and |\l_tmpb_tl| to be identical. The old +% code did not succeed in doing this (it gave an error) and so we +% use a different technique where the item(s) to be added are first +% stored in a temporary variable and then added using an |x| type +% expansion combined with the appropriate level of +% non-expansion. Putting the tokens directly into one assignment +% does not work unless we want full expansion. Note (according to +% the warning earlier) \TeX\ does not allow us to treat |#|s the +% same in all cases. Tough. +% \begin{macrocode} +\cs_new:Npn \tl_put_left:Nn #1#2 { + \tl_set:Nn \l_exp_tl {#2} + \tl_set:Nx #1 { \exp_not:V \l_exp_tl \exp_not:V #1 } +%<check> \chk_local_or_pref_global:N #1 +} +\cs_new:Npn \tl_put_left:NV #1#2 { + \tl_set:Nx #1 { \exp_not:V #2 \exp_not:V #1 } +} +\cs_new:Npn \tl_put_left:No #1#2{ + \tl_set:No \l_exp_tl {#2} + \tl_set:Nx #1 { \exp_not:V \l_exp_tl \exp_not:V #1 } +%<check> \chk_local_or_pref_global:N #1 +} +\cs_new:Npn \tl_put_left:Nx #1#2{ + \tl_set:Nx #1 { #2 \exp_not:V #1 } +%<check> \chk_local_or_pref_global:N #1 +} +\cs_new:Npn \tl_gput_left:Nn #1#2{ + \tl_set:Nn \l_exp_tl{#2} + \tl_gset:Nx #1 { \exp_not:V \l_exp_tl \exp_not:V #1 } +%<check> \chk_local_or_pref_global:N #1 +} +\cs_new:Npn \tl_gput_left:NV #1#2 { + \tl_gset:Nx #1 { \exp_not:V #2 \exp_not:V #1 } +} +\cs_new:Npn \tl_gput_left:No #1#2{ + \tl_set:No \l_exp_tl {#2} + \tl_gset:Nx #1 { \exp_not:V \l_exp_tl \exp_not:V #1 } +%<check> \chk_local_or_pref_global:N #1 +} +\cs_new:Npn \tl_gput_left:Nx #1#2{ + \tl_gset:Nx #1 { #2 \exp_not:V #1 } +%<check> \chk_local_or_pref_global:N #1 +} +\cs_generate_variant:Nn \tl_put_left:Nn {cn,co} +\cs_generate_variant:Nn \tl_put_left:NV {cV} +% \end{macrocode} +% +% \begin{macrocode} +\cs_generate_variant:Nn \tl_gput_left:Nn {cn,co} +\cs_generate_variant:Nn \tl_gput_left:NV {cV} +% \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} +% +% \begin{macro}{\tl_put_right:Nn} +% \begin{macro}{\tl_put_right:NV} +% \begin{macro}{\tl_put_right:No} +% \begin{macro}{\tl_put_right:Nx} +% \begin{macro}{\tl_put_right:cn} +% \begin{macro}{\tl_put_right:cV} +% \begin{macro}{\tl_put_right:co} +% \begin{macro}{\tl_gput_right:Nn} +% \begin{macro}{\tl_gput_right:NV} +% \begin{macro}{\tl_gput_right:No} +% \begin{macro}{\tl_gput_right:Nx} +% \begin{macro}{\tl_gput_right:cn} +% \begin{macro}{\tl_gput_right:cV} +% \begin{macro}{\tl_gput_right:co} +% These are variants of the functions above, but for adding tokens +% to the right. +% \begin{macrocode} +\cs_new:Npn \tl_put_right:Nn #1#2 { + \tl_set:Nn \l_exp_tl {#2} + \tl_set:Nx #1 { \exp_not:V #1 \exp_not:V \l_exp_tl } +%<check> \chk_local_or_pref_global:N #1 +} +\cs_new:Npn \tl_gput_right:Nn #1#2{ + \tl_set:Nn \l_exp_tl {#2} + \tl_gset:Nx #1 { \exp_not:V #1 \exp_not:V \l_exp_tl } +%<check> \chk_local_or_pref_global:N #1 +} +\cs_new:Npn \tl_put_right:NV #1#2 { + \tl_set:Nx #1 { \exp_not:V #1 \exp_not:V #2 } +} +\cs_new:Npn \tl_put_right:No #1#2 { + \tl_set:No \l_exp_tl {#2} + \tl_set:Nx #1 { \exp_not:V #1 \exp_not:V \l_exp_tl } +%<check> \chk_local_or_pref_global:N #1 +} +\cs_new:Npn \tl_gput_right:NV #1#2 { + \tl_gset:Nx #1 { \exp_not:V #1 \exp_not:V #2 } +} +\cs_new:Npn \tl_gput_right:No #1#2 { + \tl_set:No \l_exp_tl {#2} + \tl_gset:Nx #1 { \exp_not:V #1 \exp_not:V \l_exp_tl } +%<check> \chk_local_or_pref_global:N #1 +} +\cs_set:Npn \tl_put_right:Nx #1#2 { + \tl_set:Nx #1 { \exp_not:V #1 #2 } +%<check> \chk_local_or_pref_global:N #1 +} +\cs_set:Npn \tl_gput_right:Nx #1#2 { + \tl_gset:Nx #1 { \exp_not:V #1 #2 } +%<check> \chk_local_or_pref_global:N #1 +} +\cs_generate_variant:Nn \tl_put_right:Nn {cn,co} +\cs_generate_variant:Nn \tl_put_right:NV {cV} +% \end{macrocode} +% +% \begin{macrocode} +\cs_generate_variant:Nn \tl_gput_right:Nn {cn,co} +\cs_generate_variant:Nn \tl_gput_right:NV {cV} +% \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} +% +% +% +% \begin{macro}{\tl_gset:Nc} +% \begin{macro}{\tl_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} +\cs_new_nopar:Npn \tl_gset:Nc { +%<*check> + \pref_global_chk: +%</check> +%<-check> \pref_global:D + \tl_set:Nc} +% \end{macrocode} +% |\pref_global_chk:| will turn the variable check in |\tl_set:No| +% into a global check. +% \begin{macrocode} +\cs_new_nopar:Npn \tl_set:Nc #1#2{\tl_set:No #1{\cs:w#2\cs_end:}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \subsection{Variables and constants} +% +% \begin{macro}{\c_job_name_tl} +% Inherited from the expl3 name for the primitive. +% \begin{macrocode} +\tl_new:Nn \c_job_name_tl {\tex_jobname:D} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\c_empty_tl} +% Two constants which are often used. +% \begin{macrocode} +\tl_new:Nn \c_empty_tl {} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\g_tmpa_tl} +% \begin{macro}{\g_tmpb_tl} +% Global temporary token list variables. +% 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} +\tl_new:Nn \g_tmpa_tl{} +\tl_new:Nn \g_tmpb_tl{} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\l_testa_tl} +% \begin{macro}{\l_testb_tl} +% \begin{macro}{\g_testa_tl} +% \begin{macro}{\g_testb_tl} +% 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} +\tl_new:Nn \l_testa_tl {} +\tl_new:Nn \l_testb_tl {} +\tl_new:Nn \g_testa_tl {} +\tl_new:Nn \g_testb_tl {} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\l_tmpa_tl} +% \begin{macro}{\l_tmpb_tl} +% These are local temporary token list variables. +% \begin{macrocode} +\tl_new:Nn \l_tmpa_tl{} +\tl_new:Nn \l_tmpb_tl{} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% \subsection{Predicates and conditionals} +% +% We also provide a few conditionals, both in expandable form (with +% |\c_true_bool|) and in `brace-form', the latter are denoted by |TF| at the +% end, as explained elsewhere. +% +% +% \begin{macro}{\tl_if_empty_p:N,\tl_if_empty_p:c} +% \begin{macro}[TF]{\tl_if_empty:N,\tl_if_empty:c} +% These functions check whether the token list in the argument is +% empty and execute the proper code from their argument(s). +% \begin{macrocode} +\prg_set_conditional:Npnn \tl_if_empty:N #1 {p,TF,T,F} { + \if_meaning:w #1 \c_empty_tl + \prg_return_true: \else: \prg_return_false: \fi: +} +\cs_generate_variant:Nn \tl_if_empty_p:N {c} +\cs_generate_variant:Nn \tl_if_empty:NTF {c} +\cs_generate_variant:Nn \tl_if_empty:NT {c} +\cs_generate_variant:Nn \tl_if_empty:NF {c} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\tl_if_eq_p:NN,\tl_if_eq_p:Nc,\tl_if_eq_p:cN,\tl_if_eq_p:cc} +% \begin{macro}[TF]{\tl_if_eq:NN,\tl_if_eq:Nc,\tl_if_eq:cN,\tl_if_eq:cc} +% Returns |\c_true_bool| iff the two token list variables are equal. +% \begin{macrocode} +\prg_new_conditional:Npnn \tl_if_eq:NN #1#2 {p,TF,T,F} { + \if_meaning:w #1 #2 \prg_return_true: \else: \prg_return_false: \fi: +} +\cs_generate_variant:Nn \tl_if_eq_p:NN {Nc,c,cc} +\cs_generate_variant:Nn \tl_if_eq:NNTF {Nc,c,cc} +\cs_generate_variant:Nn \tl_if_eq:NNT {Nc,c,cc} +\cs_generate_variant:Nn \tl_if_eq:NNF {Nc,c,cc} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\tl_if_empty_p:n,\tl_if_empty_p:V,\tl_if_empty_p:o} +% \begin{macro}[TF]{\tl_if_empty:n,\tl_if_empty:V,\tl_if_empty:o} +% It would be tempting to just use "\if_meaning:w\q_nil#1\q_nil" as +% a test since this works really well. However it fails on a token +% list starting with "\q_nil" of course but more troubling is the +% case where argument is a complete conditional such as "\if_true:" +% a "\else:" b "\fi:" because then "\if_true:" is used by +% "\if_meaning:w", the test turns out false, the "\else:" executes +% the false branch, the "\fi:" ends it and the "\q_nil" at the end +% starts executing\dots{} A safer route is to convert the entire +% token list into harmless characters first and then compare +% that. This way the test will even accept "\q_nil" as the first +% token. +% \begin{macrocode} +\prg_new_conditional:Npnn \tl_if_empty:n #1 {p,TF,T,F} { + \exp_after:wN \if_meaning:w \exp_after:wN \q_nil \tl_to_str:n {#1} \q_nil + \prg_return_true: \else: \prg_return_false: \fi: +} +\cs_generate_variant:Nn \tl_if_empty_p:n {V} +\cs_generate_variant:Nn \tl_if_empty:nTF {V} +\cs_generate_variant:Nn \tl_if_empty:nT {V} +\cs_generate_variant:Nn \tl_if_empty:nF {V} +\cs_generate_variant:Nn \tl_if_empty_p:n {o} +\cs_generate_variant:Nn \tl_if_empty:nTF {o} +\cs_generate_variant:Nn \tl_if_empty:nT {o} +\cs_generate_variant:Nn \tl_if_empty:nF {o} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\tl_if_blank_p:n,\tl_if_blank_p:V,\tl_if_blank_p:o} +% \begin{macro}[TF]{\tl_if_blank:n,\tl_if_blank:V,\tl_if_blank:o} +% \begin{macro}[aux]{\tl_if_blank_p_aux:w} +% This is based on the answers in ``Around the Bend No~2'' but is +% safer as the tests listed there all have one small flaw: If the +% input in the test is two tokens with the same meaning as the +% internal delimiter, they will fail since one of them is mistaken +% for the actual delimiter. In our version below we make sure to +% pass the input through |\tl_to_str:n| which ensures that all +% the tokens are converted to catcode 12. However we use an |a| with +% catcode 11 as delimiter so we can \emph{never} get into the same +% problem as the solutions in ``Around the Bend No~2''. +% \begin{macrocode} +\prg_new_conditional:Npnn \tl_if_blank:n #1 {p,TF,T,F} { + \exp_after:wN \tl_if_blank_p_aux:w \tl_to_str:n {#1} aa..\q_nil +} +\cs_new:Npn \tl_if_blank_p_aux:w #1#2 a #3#4 \q_nil { + \if_meaning:w #3 #4 \prg_return_true: \else: \prg_return_false: \fi: +} +\cs_generate_variant:Nn \tl_if_blank_p:n {V} +\cs_generate_variant:Nn \tl_if_blank:nTF {V} +\cs_generate_variant:Nn \tl_if_blank:nT {V} +\cs_generate_variant:Nn \tl_if_blank:nF {V} +\cs_generate_variant:Nn \tl_if_blank_p:n {o} +\cs_generate_variant:Nn \tl_if_blank:nTF {o} +\cs_generate_variant:Nn \tl_if_blank:nT {o} +\cs_generate_variant:Nn \tl_if_blank:nF {o} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}[TF]{\tl_if_eq:xx,\tl_if_eq:nn,\tl_if_eq:VV,\tl_if_eq:oo, +% \tl_if_eq:xn,\tl_if_eq:nx,\tl_if_eq:on,\tl_if_eq:no, +% \tl_if_eq:Vn,\tl_if_eq:nV, +% \tl_if_eq:xV,\tl_if_eq:xo,\tl_if_eq:Vx,\tl_if_eq:ox} +% \begin{macro}{\tl_if_eq_p:xx,\tl_if_eq_p:nn,\tl_if_eq_p:VV,\tl_if_eq_p:oo, +% \tl_if_eq_p:xn,\tl_if_eq_p:nx,\tl_if_eq_p:Vn,\tl_if_eq_p:on, +% \tl_if_eq_p:nV,\tl_if_eq_p:no,\tl_if_eq_p:xV,\tl_if_eq_p:Vx, +% \tl_if_eq_p:xo,\tl_if_eq_p:ox} +% Test if two token lists are identical. pdf\TeX\ contains a most +% interesting primitive for expandable string comparison so we make +% use of it if available. Presumable it will be in the final +% version. +% +% Firstly we give it an appropriate name. Note that this primitive +% actually performs an \texttt{x} type expansion but it is still +% expandable! Hence we must program these functions backwards to add +% \verb|\exp_not:n|. We provide the combinations for the types +% \texttt{n}, \texttt{o} and \texttt{x}. +% \begin{macrocode} +\cs_new_eq:NN \tl_compare:xx \pdf_strcmp:D +\cs_new:Npn \tl_compare:nn #1#2{ + \tl_compare:xx{\exp_not:n{#1}}{\exp_not:n{#2}} +} +\cs_new:Npn \tl_compare:nx #1{ + \tl_compare:xx{\exp_not:n{#1}} +} +\cs_new:Npn \tl_compare:xn #1#2{ + \tl_compare:xx{#1}{\exp_not:n{#2}} +} +\cs_new:Npn \tl_compare:nV #1#2 { + \tl_compare:xx { \exp_not:n {#1} } { \exp_not:V #2 } +} +\cs_new:Npn \tl_compare:no #1#2{ + \tl_compare:xx{\exp_not:n{#1}}{\exp_not:n\exp_after:wN{#2}} +} +\cs_new:Npn \tl_compare:Vn #1#2 { + \tl_compare:xx { \exp_not:V #1 } { \exp_not:n {#2} } +} +\cs_new:Npn \tl_compare:on #1#2{ + \tl_compare:xx{\exp_not:n\exp_after:wN{#1}}{\exp_not:n{#2}} +} +\cs_new:Npn \tl_compare:VV #1#2 { + \tl_compare:xx { \exp_not:V #1 } { \exp_not:V #2 } +} +\cs_new:Npn \tl_compare:oo #1#2{ + \tl_compare:xx{\exp_not:n\exp_after:wN{#1}}{\exp_not:n\exp_after:wN{#2}} +} +\cs_new:Npn \tl_compare:xV #1#2 { + \tl_compare:xx {#1} { \exp_not:V #2 } +} +\cs_new:Npn \tl_compare:xo #1#2{ + \tl_compare:xx{#1}{\exp_not:n\exp_after:wN{#2}} +} +\cs_new:Npn \tl_compare:Vx #1#2 { + \tl_compare:xx { \exp_not:V #1 } {#2} +} +\cs_new:Npn \tl_compare:ox #1#2{ + \tl_compare:xx{\exp_not:n\exp_after:wN{#1}}{#2} +} +% \end{macrocode} +% Since we have a lot of basically identical functions to define we +% define one to define the rest. Unfortunately we aren't quite set up +% to use the new \verb|\tl_map_inline:nn| function yet. +% \begin{macrocode} +\cs_set_nopar:Npn \tl_tmp:w #1 { + \tl_set:Nx \l_tmpa_tl { + \exp_not:N \prg_new_conditional:Npnn \exp_not:c {tl_if_eq:#1} + ####1 ####2 {p,TF,T,F} { + \exp_not:N \tex_ifnum:D + \exp_not:c {tl_compare:#1} {####1}{####2} + \exp_not:n{ =\c_zero \prg_return_true: \else: \prg_return_false: \fi: } + } + } + \l_tmpa_tl +} +\tl_tmp:w{xx} \tl_tmp:w{nx} \tl_tmp:w{ox} \tl_tmp:w{Vx} +\tl_tmp:w{xn} \tl_tmp:w{nn} \tl_tmp:w{on} \tl_tmp:w{Vn} +\tl_tmp:w{xo} \tl_tmp:w{no} \tl_tmp:w{oo} +\tl_tmp:w{xV} \tl_tmp:w{nV} \tl_tmp:w{VV} +% \end{macrocode} +% However all of this only makes sense if we actually have that +% primitive. Therefore we disable it again if it is not there and +% define \verb|\tl_if_eq:nn| the old fashioned (and unexpandable) +% way. +% +% In some cases below, since arbitrary token lists could be being used in +% this function, you can't assume (as token list variables usually do) that there won't be +% any |#| tokens. Therefore, "\tl_set:Nx" and "\exp_not:n" is used instead +% of plain "\tl_set:Nn". +% +% \begin{macrocode} +\cs_if_exist:cF{pdf_strcmp:D}{ + \prg_set_protected_conditional:Npnn \tl_if_eq:nn #1#2 {TF,T,F} { + \tl_set:Nx \l_testa_tl {\exp_not:n{#1}} + \tl_set:Nx \l_testb_tl {\exp_not:n{#2}} + \if_meaning:w\l_testa_tl \l_testb_tl + \prg_return_true: \else: \prg_return_false: + \fi: + } + \prg_set_protected_conditional:Npnn \tl_if_eq:nV #1#2 {TF,T,F} { + \tl_set:Nx \l_testa_tl { \exp_not:n {#1} } + \tl_set:Nx \l_testb_tl { \exp_not:V #2 } + \if_meaning:w \l_testa_tl \l_testb_tl + \prg_return_true: \else: \prg_return_false: + \fi: + } + \prg_set_protected_conditional:Npnn \tl_if_eq:no #1#2 {TF,T,F} { + \tl_set:Nx \l_testa_tl {\exp_not:n{#1}} + \tl_set:Nx \l_testb_tl {\exp_not:o{#2}} + \if_meaning:w\l_testa_tl \l_testb_tl + \prg_return_true: \else: \prg_return_false: + \fi: + } + \prg_set_protected_conditional:Npnn \tl_if_eq:nx #1#2 {TF,T,F} { + \tl_set:Nx \l_testa_tl {\exp_not:n{#1}} + \tl_set:Nx \l_testb_tl {#2} + \if_meaning:w\l_testa_tl \l_testb_tl + \prg_return_true: \else: \prg_return_false: + \fi: + } + \prg_set_protected_conditional:Npnn \tl_if_eq:Vn #1#2 {TF,T,F} { + \tl_set:Nx \l_testa_tl { \exp_not:V #1 } + \tl_set:Nx \l_testb_tl { \exp_not:n{#2} } + \if_meaning:w \l_testa_tl \l_testb_tl + \prg_return_true: \else: \prg_return_false: + \fi: + } + \prg_set_protected_conditional:Npnn \tl_if_eq:on #1#2 {TF,T,F} { + \tl_set:Nx \l_testa_tl {\exp_not:o{#1}} + \tl_set:Nx \l_testb_tl {\exp_not:n{#2}} + \if_meaning:w\l_testa_tl \l_testb_tl + \prg_return_true: \else: \prg_return_false: + \fi: + } + \prg_set_protected_conditional:Npnn \tl_if_eq:VV #1#2 {TF,T,F} { + \tl_set:Nx \l_testa_tl { \exp_not:V #1 } + \tl_set:Nx \l_testb_tl { \exp_not:V #2 } + \if_meaning:w \l_testa_tl \l_testb_tl + \prg_return_true: \else: \prg_return_false: + \fi: + } + \prg_set_protected_conditional:Npnn \tl_if_eq:oo #1#2 {TF,T,F} { + \tl_set:Nx \l_testa_tl {\exp_not:o{#1}} + \tl_set:Nx \l_testb_tl {\exp_not:o{#2}} + \if_meaning:w\l_testa_tl \l_testb_tl + \prg_return_true: \else: \prg_return_false: + \fi: + } + \prg_set_protected_conditional:Npnn \tl_if_eq:Vx #1#2 {TF,T,F} { + \tl_set:Nx \l_testa_tl { \exp_not:V #1 } + \tl_set:Nx \l_testb_tl {#2} + \if_meaning:w \l_testa_tl \l_testb_tl + \prg_return_true: \else: \prg_return_false: + \fi: + } + \prg_set_protected_conditional:Npnn \tl_if_eq:ox #1#2 {TF,T,F} { + \tl_set:Nx \l_testa_tl {\exp_not:o{#1}} + \tl_set:Nx \l_testb_tl {#2} + \if_meaning:w\l_testa_tl \l_testb_tl + \prg_return_true: \else: \prg_return_false: + \fi: + } + \prg_set_protected_conditional:Npnn \tl_if_eq:xn #1#2 {TF,T,F} { + \tl_set:Nx \l_testa_tl {#1} + \tl_set:Nx \l_testb_tl {\exp_not:n{#2}} + \if_meaning:w\l_testa_tl \l_testb_tl + \prg_return_true: \else: \prg_return_false: + \fi: + } + \prg_set_protected_conditional:Npnn \tl_if_eq:xV #1#2 {TF,T,F} { + \tl_set:Nx \l_testa_tl {#1} + \tl_set:Nx \l_testb_tl { \exp_not:V #2 } + \if_meaning:w \l_testa_tl \l_testb_tl + \prg_return_true: \else: \prg_return_false: + \fi: + } + \prg_set_protected_conditional:Npnn \tl_if_eq:xo #1#2 {TF,T,F} { + \tl_set:Nx \l_testa_tl {#1} + \tl_set:Nx \l_testb_tl {\exp_not:o{#2}} + \if_meaning:w\l_testa_tl \l_testb_tl + \prg_return_true: \else: \prg_return_false: + \fi: + } + \prg_set_protected_conditional:Npnn \tl_if_eq:xx #1#2 {TF,T,F} { + \tl_set:Nx \l_testa_tl {#1} + \tl_set:Nx \l_testb_tl {#2} + \if_meaning:w\l_testa_tl \l_testb_tl + \prg_return_true: \else: \prg_return_false: + \fi: + } +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% \subsection{Working with the contents of token lists} +% +% +% \begin{macro}{\tl_to_lowercase:n} +% \begin{macro}{\tl_to_uppercase:n} +% Just some names for a few primitives. +% \begin{macrocode} +\cs_new_eq:NN \tl_to_lowercase:n \tex_lowercase:D +\cs_new_eq:NN \tl_to_uppercase:n \tex_uppercase:D +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\tl_to_str:n} +% Another name for a primitive. +% \begin{macrocode} +\cs_new_eq:NN \tl_to_str:n \etex_detokenize:D +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tl_to_str:N} +% \begin{macro}{\tl_to_str:c} +% \begin{macro}[aux]{\tl_to_str_aux:w} +% These functions return the replacement text of a token list as a +% string list with all characters catcoded to `other'. +% \begin{macrocode} +\cs_new_nopar:Npn \tl_to_str:N {\exp_after:wN\tl_to_str_aux:w + \token_to_meaning:N} +\cs_new_nopar:Npn \tl_to_str_aux:w #1>{} +\cs_generate_variant:Nn \tl_to_str:N {c} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\tl_map_function:nN} +% \begin{macro}{\tl_map_function:NN} +% \begin{macro}{\tl_map_function:cN} +% \begin{macro}[aux]{\tl_map_function_aux:NN} +% Expandable loop macro for token lists. These have the advantage of not +% needing to test if the argument is empty, because if it is, the stop +% marker will be read immediately and the loop terminated. +% \begin{macrocode} +\cs_new:Npn \tl_map_function:nN #1#2{ + \tl_map_function_aux:Nn #2 #1 \q_recursion_tail \q_recursion_stop +} +\cs_new_nopar:Npn \tl_map_function:NN #1#2{ + \exp_after:wN \tl_map_function_aux:Nn + \exp_after:wN #2 #1 \q_recursion_tail \q_recursion_stop +} +\cs_new:Npn \tl_map_function_aux:Nn #1#2{ + \quark_if_recursion_tail_stop:n{#2} + #1{#2} \tl_map_function_aux:Nn #1 +} +\cs_generate_variant:Nn \tl_map_function:NN {cN} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\tl_map_inline:nn} +% \begin{macro}{\tl_map_inline:Nn} +% \begin{macro}{\tl_map_inline:cn} +% \begin{macro}[aux]{\tl_map_inline_aux:n} +% \begin{macro}{\g_tl_inline_level_num} +% The inline functions are straight forward by now. We use a little +% trick with the fake counter |\g_tl_inline_level_num| to make +% them nestable.\footnote{This should be a proper integer, but I +% don't want to mess with the dependencies right now\dots} We can +% also make use of |\tl_map_function:Nn| from before. +% \begin{macrocode} +\cs_new:Npn \tl_map_inline:nn #1#2{ + \num_gincr:N \g_tl_inline_level_num + \cs_gset:cpn {tl_map_inline_ \num_use:N \g_tl_inline_level_num :n} + ##1{#2} + \exp_args:Nc \tl_map_function_aux:Nn + {tl_map_inline_ \num_use:N \g_tl_inline_level_num :n} + #1 \q_recursion_tail\q_recursion_stop + \num_gdecr:N \g_tl_inline_level_num +} +\cs_new:Npn \tl_map_inline:Nn #1#2{ + \num_gincr:N \g_tl_inline_level_num + \cs_gset:cpn {tl_map_inline_ \num_use:N \g_tl_inline_level_num :n} + ##1{#2} + \exp_last_unbraced:NcV \tl_map_function_aux:Nn + {tl_map_inline_ \num_use:N \g_tl_inline_level_num :n} + #1 \q_recursion_tail\q_recursion_stop + \num_gdecr:N \g_tl_inline_level_num +} +\cs_generate_variant:Nn \tl_map_inline:Nn {c} +\tl_new:Nn \g_tl_inline_level_num{0} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\tl_map_variable:nNn} +% \begin{macro}{\tl_map_variable:NNn} +% \begin{macro}{\tl_map_variable:cNn} +% |\tl_map_variable:nNn| \meta{\tlist} \meta{temp} \meta{action} assigns +% \meta{temp} to each element and executes \meta{action}. +% \begin{macrocode} +\cs_new:Npn \tl_map_variable:nNn #1#2#3{ + \tl_map_variable_aux:Nnn #2 {#3} #1 \q_recursion_tail \q_recursion_stop +} +% \end{macrocode} +% Next really has to be v/V args +% \begin{macrocode} +\cs_new_nopar:Npn \tl_map_variable:NNn {\exp_args:No \tl_map_variable:nNn} +\cs_generate_variant:Nn \tl_map_variable:NNn {c} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}[aux]{\tl_map_variable_aux:NnN} +% The general loop. Assign the temp variable |#1| to the current item +% |#3| and then check if that's the stop marker. If it is, break the +% loop. If not, execute the action |#2| and continue. +% \begin{macrocode} +\cs_new:Npn \tl_map_variable_aux:Nnn #1#2#3{ + \tl_set:Nn #1{#3} + \quark_if_recursion_tail_stop:N #1 + #2 \tl_map_variable_aux:Nnn #1{#2} +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tl_map_break:} +% The break statement. +% \begin{macrocode} +\cs_new_eq:NN \tl_map_break: \use_none_delimit_by_q_recursion_stop:w +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tl_reverse:n} +% \begin{macro}{\tl_reverse:V} +% \begin{macro}{\tl_reverse:o} +% \begin{macro}[aux]{\tl_reverse_aux:nN} +% Reversal of a token list is done by taking one token at a time +% and putting it in front of the ones before it. +% \begin{macrocode} +\cs_new:Npn \tl_reverse:n #1{ + \tl_reverse_aux:nN {} #1 \q_recursion_tail\q_recursion_stop +} +\cs_new:Npn \tl_reverse_aux:nN #1#2{ + \quark_if_recursion_tail_stop_do:nn {#2}{ #1 } + \tl_reverse_aux:nN {#2#1} +} +\cs_generate_variant:Nn \tl_reverse:n {V,o} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\tl_reverse:N} +% This reverses the list, leaving "\exp_stop_f:" in front, which in turn +% is removed by the "f" expansion which comes to a halt. +% \begin{macrocode} +\cs_new_nopar:Npn \tl_reverse:N #1 { + \tl_set:Nf #1 { \tl_reverse:o { #1 \exp_stop_f: } } +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tl_elt_count:n} +% \begin{macro}{\tl_elt_count:V} +% \begin{macro}{\tl_elt_count:o} +% \begin{macro}{\tl_elt_count:N} +% Count number of elements within a token list or token list +% variable. Brace groups within the list are read as a single +% element. +% "\num_elt_count:n" grabs the element and replaces it by "+1". The +% "0" to ensure it works on an empty list. +% \begin{macrocode} +\cs_new:Npn \tl_elt_count:n #1{ + \intexpr_eval:n { + \tl_map_function:nN {#1}\num_elt_count:n + } +} +\cs_generate_variant:Nn \tl_elt_count:n {V,o} +\cs_new_nopar:Npn \tl_elt_count:N #1{ + \intexpr_eval:n { + \tl_map_function:NN #1 \num_elt_count:n + } +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\tl_set_rescan:Nnn, \tl_gset_rescan:Nnn} +% These functions store the \marg{\tlist} in \meta{\tlvar} after +% redefining catcodes, etc., in argument "#2". +% \begin{arguments} +% \item \meta{\tlvar} +% \item \marg{catcode setup, etc.} +% \item \marg{\tlist} +% \end{arguments} +% \begin{macrocode} +\cs_new:Npn \tl_set_rescan:Nnn { \tl_set_rescan_aux:NNnn \tl_set:Nn } +\cs_new:Npn \tl_gset_rescan:Nnn { \tl_set_rescan_aux:NNnn \tl_gset:Nn } +% \end{macrocode} +% +% \begin{macro}[aux]{\tl_set_rescan_aux:NNnn} +% This macro uses a trick to extract an unexpanded token list after it's +% rescanned with "\etex_scantokens:D". This technique was first used (as far as I +% know) by Heiko Oberdiek in his \pkg{catchfile} package, albeit for real +% files rather than the `fake' "\scantokens" one. +% +% The basic problem arises because "\etex_scantokens:D" emulates a file read, which +% inserts an EOF marker into the expansion; the simplistic\\ +% "\exp_args:NNo \cs_set:Npn \tmp:w { \etex_scantokens:D {some text} }"\\ +% unfortunately doesn't work, calling the error:\\ +% "! File ended while scanning definition of \tmp:w."\\ +% (Lua\TeX\ works around this +% problem with its "\scantextokens" primitive.) +% +% Usually, we'd define "\etex_everyeof:D" to be "\exp_not:N" to gobble the EOF +% marker, but since we're not expanding the token list, it gets left in there +% and we have the same basic problem. +% +% Instead, we define "\etex_everyeof:D" to contain a marker that's impossible +% to occur within the scanned text; that is, the same char twice with +% different catcodes. (For some reason, we \emph{don't} need to insert +% a "\exp_not:N" token after it to prevent the EOF marker to expand. Anyone +% know why?) +% +% A helper function is can be used to save the token list delimited by the +% special marker, keeping the catcode redefinitions hidden away in a group. +% +% \begin{macro}[aux]{\c_two_ats_with_two_catcodes_tl} +% A tl with two "@" characters with two different catcodes. +% Used as a special marker for delimited text. +% \begin{macrocode} +\group_begin: + \tex_lccode:D `\A = `\@ \scan_stop: + \tex_lccode:D `\B = `\@ \scan_stop: + \tex_catcode:D `\A = 8 \scan_stop: + \tex_catcode:D `\B = 3 \scan_stop: +\tl_to_lowercase:n { + \group_end: + \tl_new:Nn \c_two_ats_with_two_catcodes_tl {AB} +} +% \end{macrocode} +% \end{macro} +% +% \begin{arguments} +% \item "\tl_set" function +% \item \meta{\tlvar} +% \item \marg{catcode setup, etc.} +% \item \marg{\tlist} +% \end{arguments} +% Note that if you change "\etex_everyeof:D" in "#3" +% then you'd better do it correctly! +% \begin{macrocode} +\cs_new:Npn \tl_set_rescan_aux:NNnn #1#2#3#4 { + \group_begin: + \toks_set:No \etex_everyeof:D { \c_two_ats_with_two_catcodes_tl } + \tex_endlinechar:D = \c_minus_one + #3 + \exp_after:wN \tl_rescan_aux:w \etex_scantokens:D {#4} + \exp_args:NNNo + \group_end: + #1 #2 { \l_tmpa_tl } +} +% \end{macrocode} +% +% \begin{macro}[aux]{\tl_rescan_aux:w} +% \begin{macrocode} +\exp_after:wN \cs_set:Npn +\exp_after:wN \tl_rescan_aux:w +\exp_after:wN # +\exp_after:wN 1 \c_two_ats_with_two_catcodes_tl { + \tl_set:Nn \l_tmpa_tl {#1} +} +% \end{macrocode} +% +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\tl_set_rescan:Nnx,\tl_gset_rescan:Nnx} +% These functions store the full expansion of \marg{\tlist} in +% \meta{\tlvar} after redefining catcodes, etc., in argument "#2". +% \begin{arguments} +% \item \meta{\tlvar} +% \item \marg{catcode setup, etc.} +% \item \marg{\tlist} +% \end{arguments} +% The expanded versions are much simpler because the "\etex_scantokens:D" +% can occur within the expansion. +% \begin{macrocode} +\cs_new:Npn \tl_set_rescan:Nnx #1#2#3 { + \group_begin: + \etex_everyeof:D { \exp_not:N } + \tex_endlinechar:D = \c_minus_one + #2 + \tl_set:Nx \l_tmpa_tl { \etex_scantokens:D {#3} } + \exp_args:NNNo + \group_end: + \tl_set:Nn #1 { \l_tmpa_tl } +} +% \end{macrocode} +% Globally is easier again: +% \begin{macrocode} +\cs_new:Npn \tl_gset_rescan:Nnx #1#2#3 { + \group_begin: + \etex_everyeof:D { \exp_not:N } + \tex_endlinechar:D = \c_minus_one + #2 + \tl_gset:Nx #1 { \etex_scantokens:D {#3} } + \group_end: +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tl_rescan:nn} +% The inline wrapper for "\etex_scantokens:D". +% \begin{arguments} +% \item Catcode changes (etc.) +% \item Token list to re-tokenise +% \end{arguments} +% \begin{macrocode} +\cs_new:Npn \tl_rescan:nn #1#2 { + \group_begin: + \etex_everyeof:D { \exp_not:N } + \tex_endlinechar:D = \c_minus_one + #1 + \toks_set:Nx \l_tmpa_toks { \etex_scantokens:D {#2} } + \exp_args:NV \group_end: \l_tmpa_toks +} +% \end{macrocode} +% \end{macro} +% +% \subsection{Checking for and replacing tokens} +% +% \begin{macro}[TF]{\tl_if_in:Nn,\tl_if_in:cn} +% See the replace functions for further comments. In this part we +% don't care too much about brace stripping since we are not +% interested in passing on the tokens which are split off in the +% process. +% \begin{macrocode} +\prg_new_protected_conditional:Npnn \tl_if_in:Nn #1#2 {TF,T,F} { + \cs_set:Npn \tl_tmp:w ##1 #2 ##2 \q_stop { + \quark_if_no_value:nTF {##2} {\prg_return_false:} {\prg_return_true:} + } + \exp_after:wN \tl_tmp:w #1 #2 \q_no_value \q_stop +} +\cs_generate_variant:Nn \tl_if_in:NnTF {c} +\cs_generate_variant:Nn \tl_if_in:NnT {c} +\cs_generate_variant:Nn \tl_if_in:NnF {c} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[TF]{\tl_if_in:nn,\tl_if_in:Vn,\tl_if_in:on} +% \begin{macrocode} +\prg_new_protected_conditional:Npnn \tl_if_in:nn #1#2 {TF,T,F} { + \cs_set:Npn \tl_tmp:w ##1 #2 ##2 \q_stop { + \quark_if_no_value:nTF {##2} {\prg_return_false:} {\prg_return_true:} + } + \tl_tmp:w #1 #2 \q_no_value \q_stop +} +\cs_generate_variant:Nn \tl_if_in:nnTF {V} +\cs_generate_variant:Nn \tl_if_in:nnT {V} +\cs_generate_variant:Nn \tl_if_in:nnF {V} +\cs_generate_variant:Nn \tl_if_in:nnTF {o} +\cs_generate_variant:Nn \tl_if_in:nnT {o} +\cs_generate_variant:Nn \tl_if_in:nnF {o} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\l_tl_replace_toks} +% A temp variable for the replace operations. +% \begin{macrocode} +%%\l_tl_replace_toks % moved to l3token as alloc not set up yet. +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tl_replace_in:Nnn} +% \begin{macro}{\tl_replace_in:cnn} +% \begin{macro}{\tl_greplace_in:Nnn} +% \begin{macro}{\tl_greplace_in:cnn} +% Replacing the first item in a token list variable goes like this: +% Define a temporary function with delimited arguments containing +% the search term and take a closer look at what is left. We append +% the expansion of the token list with the search term plus the quark +% |\q_no_value|. If the search term isn't present this last one is +% found and the following token is the quark, so we test for +% that. If the search term is present we will have to split off the +% |#3\q_no_value| we had, so we define yet another function with +% delimited arguments to do this. The advantage here is that now we +% have a special end sequence so there is no problem if the search +% term appears more than once. Only problem left is to prevent brace +% stripping in both ends, so we prepend the expansion of the token list +% with |\prg_do_nothing:| later to be expanded and also prepend the +% remainder of the first split operation with |\prg_do_nothing:| also to +% be expanded again later on. +% +% \begin{macro}[aux]{\tl_replace_in_aux:NNnn} +% \begin{arguments} +% \item "\tl_set:Nx" or "\tl_gset:Nx" +% \item \meta{\tlvar} +% \item item to find +% \item replacement text +% \end{arguments} +% \begin{macrocode} +\cs_new:Npn \tl_replace_in_aux:NNnn #1#2#3#4{ + \cs_set:Npn \tl_tmp:w ##1#3##2\q_stop{ + \quark_if_no_value:nF{##2} + { +% \end{macrocode} +% At this point |##1| starts with a |\prg_do_nothing:| so we expand it to +% remove it. +% \begin{macrocode} + \toks_set:No\l_tl_replace_toks{##1#4} + \cs_set:Npn \tl_tmp:w ####1#3\q_no_value{ + \toks_put_right:No \l_tl_replace_toks { ####1 } + } + \tl_tmp:w \prg_do_nothing: ##2 +% \end{macrocode} +% Now all that is done is setting the token list variable equal to the +% expansion of the token register. +% \begin{macrocode} + #1#2{\toks_use:N\l_tl_replace_toks} + } + } +% \end{macrocode} +% Here is where we start the process. Note that the token list might start +% with a space token so we use this little trick with |\use:n| +% to prevent it from being removed. +% \begin{macrocode} + \use:n{\exp_after:wN \tl_tmp:w\exp_after:wN\prg_do_nothing:} + #2#3 \q_no_value\q_stop +} +% \end{macrocode} +% Now the various versions doing the replacement either globally or +% locally. +% \begin{macrocode} +\cs_new_nopar:Npn \tl_replace_in:Nnn {\tl_replace_in_aux:NNnn \tl_set:Nx} +\cs_generate_variant:Nn\tl_replace_in:Nnn {cnn} +% \end{macrocode} +% +% \begin{macrocode} +\cs_new_nopar:Npn \tl_greplace_in:Nnn {\tl_replace_in_aux:NNnn \tl_gset:Nx} +\cs_generate_variant:Nn\tl_greplace_in:Nnn {cnn} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\tl_replace_all_in:Nnn} +% \begin{macro}{\tl_replace_all_in:cnn} +% \begin{macro}{\tl_greplace_all_in:Nnn} +% \begin{macro}{\tl_greplace_all_in:cnn} +% \begin{macro}[aux]{\tl_replace_all_in_aux:NNnn} +% The version for replacing \emph{all} occurrences of the search +% term is fairly easy since we just have to keep doing the +% replacement on the split-off part until all are +% replaced. Otherwise it is pretty much the same as above. +% \begin{macrocode} +\cs_set:Npn \tl_replace_all_in_aux:NNnn #1#2#3#4{ + \toks_clear:N \l_tl_replace_toks + \cs_set:Npn \tl_tmp:w ##1#3##2\q_stop{ + \quark_if_no_value:nTF{##2} + { + \toks_put_right:No \l_tl_replace_toks {##1} + } + { + \toks_put_right:No \l_tl_replace_toks {##1 #4} + \tl_tmp:w \prg_do_nothing: ##2 \q_stop + } + } + \use:n{\exp_after:wN \tl_tmp:w \exp_after:wN \prg_do_nothing:} + #2#3 \q_no_value\q_stop + #1#2{\toks_use:N\l_tl_replace_toks} +} +% \end{macrocode} +% Now the various forms. +% \begin{macrocode} +\cs_new_nopar:Npn \tl_replace_all_in:Nnn { + \tl_replace_all_in_aux:NNnn \tl_set:Nx} +\cs_generate_variant:Nn \tl_replace_all_in:Nnn {cnn} +% \end{macrocode} +% +% \begin{macrocode} +\cs_new_nopar:Npn \tl_greplace_all_in:Nnn { + \tl_replace_all_in_aux:NNnn \tl_gset:Nx} +\cs_generate_variant:Nn \tl_greplace_all_in:Nnn {cnn} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% +% \begin{macro}{\tl_remove_in:Nn} +% \begin{macro}{\tl_remove_in:cn} +% \begin{macro}{\tl_gremove_in:Nn} +% \begin{macro}{\tl_gremove_in:cn} +% Next comes a series of removal functions. I have just implemented +% them as subcases of the replace functions for now (I'm lazy). +% \begin{macrocode} +\cs_new:Npn \tl_remove_in:Nn #1#2{\tl_replace_in:Nnn #1{#2}{}} +\cs_new:Npn \tl_gremove_in:Nn #1#2{\tl_greplace_in:Nnn #1{#2}{}} +\cs_generate_variant:Nn \tl_remove_in:Nn {cn} +\cs_generate_variant:Nn \tl_gremove_in:Nn {cn} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\tl_remove_all_in:Nn} +% \begin{macro}{\tl_remove_all_in:cn} +% \begin{macro}{\tl_gremove_all_in:Nn} +% \begin{macro}{\tl_gremove_all_in:cn} +% Same old, same old. +% \begin{macrocode} +\cs_new:Npn \tl_remove_all_in:Nn #1#2{ + \tl_replace_all_in:Nnn #1{#2}{} +} +\cs_new:Npn \tl_gremove_all_in:Nn #1#2{ + \tl_greplace_all_in:Nnn #1{#2}{} +} +\cs_generate_variant:Nn \tl_remove_all_in:Nn {cn} +\cs_generate_variant:Nn \tl_gremove_all_in:Nn {cn} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \subsection{Heads or tails?} +% +% \begin{macro}{\tl_head:n} +% \begin{macro}{\tl_head_i:n} +% \begin{macro}{\tl_tail:n} +% \begin{macro}{\tl_tail:f} +% \begin{macro}{\tl_head_iii:n} +% \begin{macro}{\tl_head_iii:f} +% \begin{macro}{\tl_head:w} +% \begin{macro}{\tl_head_i:w} +% \begin{macro}{\tl_tail:w} +% \begin{macro}{\tl_head_iii:w} +% These functions pick up either the head or the tail of a list. +% "\tl_head_iii:n" returns the first three items on a list. +% \begin{macrocode} +\cs_new:Npn \tl_head:n #1{\tl_head:w #1\q_nil} +\cs_new_eq:NN \tl_head_i:n \tl_head:n +\cs_new:Npn \tl_tail:n #1{\tl_tail:w #1\q_nil} +\cs_generate_variant:Nn \tl_tail:n {f} +\cs_new:Npn \tl_head_iii:n #1{\tl_head_iii:w #1\q_nil} +\cs_generate_variant:Nn \tl_head_iii:n {f} +\cs_new_eq:NN \tl_head:w \use_i_delimit_by_q_nil:nw +\cs_new_eq:NN \tl_head_i:w \tl_head:w +\cs_new:Npn \tl_tail:w #1#2\q_nil{#2} +\cs_new:Npn \tl_head_iii:w #1#2#3#4\q_nil{#1#2#3} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\tl_if_head_eq_meaning_p:nN} +% \begin{macro}[TF]{\tl_if_head_eq_meaning:nN} +% \begin{macro}{\tl_if_head_eq_charcode_p:nN} +% \begin{macro}{\tl_if_head_eq_charcode_p:fN} +% \begin{macro}[TF]{\tl_if_head_eq_charcode:nN} +% \begin{macro}[TF]{\tl_if_head_eq_charcode:fN} +% \begin{macro}{\tl_if_head_eq_catcode_p:nN} +% \begin{macro}[TF]{\tl_if_head_eq_catcode:nN} +% When we want to check if the first token of a list equals something +% specific it is usually either to see if it is a control sequence or +% a character. Hence we make two different functions as the internal +% test is different. +% |\tl_if_head_meaning_eq:nNTF| uses |\if_meaning:w| and will +% consider the tokens |b|$\sb{11}$ and |b|$\sb{12}$ different. +% |\tl_if_head_char_eq:nNTF| on the other hand only compares +% character codes so would regard |b|$\sb{11}$ and |b|$\sb{12}$ as +% equal but would also regard two primitives as equal. +% \begin{macrocode} +\prg_new_conditional:Npnn \tl_if_head_eq_meaning:nN #1#2 {p,TF,T,F} { + \exp_after:wN \if_meaning:w \tl_head:w #1 \q_nil #2 + \prg_return_true: \else: \prg_return_false: \fi: +} +% \end{macrocode} +% For the charcode and catcode versions we insert |\exp_not:N| in +% front of both tokens. If you need them to expand fully as \TeX{} +% does itself with these you can use an |f| type expansion. +% \begin{macrocode} +\prg_new_conditional:Npnn \tl_if_head_eq_charcode:nN #1#2 {p,TF,T,F} { + \exp_after:wN \if:w \exp_after:wN \exp_not:N + \tl_head:w #1 \q_nil \exp_not:N #2 + \prg_return_true: \else: \prg_return_false: \fi: +} +% \end{macrocode} +% Actually the default is already an |f| type expansion. +% \begin{macrocode} +%% \cs_new:Npn \tl_if_head_eq_charcode_p:fN #1#2{ +%% \exp_after:wN\if_charcode:w \tl_head:w #1\q_nil\exp_not:N#2 +%% \c_true_bool +%% \else: +%% \c_false_bool +%% \fi: +%% } +%% \def_long_test_function_new:npn {tl_if_head_eq_charcode:fN}#1#2{ +%% \if_predicate:w \tl_if_head_eq_charcode_p:fN {#1}#2} +% \end{macrocode} +% These ":fN" variants are broken; temporary patch: +% \begin{macrocode} +\cs_generate_variant:Nn \tl_if_head_eq_charcode_p:nN {f} +\cs_generate_variant:Nn \tl_if_head_eq_charcode:nNTF {f} +\cs_generate_variant:Nn \tl_if_head_eq_charcode:nNT {f} +\cs_generate_variant:Nn \tl_if_head_eq_charcode:nNF {f} +% \end{macrocode} +% And now catcodes: +% \begin{macrocode} +\prg_new_conditional:Npnn \tl_if_head_eq_catcode:nN #1#2 {p,TF,T,F} { + \exp_after:wN \if_catcode:w \exp_after:wN \exp_not:N + \tl_head:w #1 \q_nil \exp_not:N #2 + \prg_return_true: \else: \prg_return_false: \fi: +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% Show token usage: +% \begin{macrocode} +%<*showmemory> +\showMemUsage +%</showmemory> +% \end{macrocode} +% +% \end{implementation} +% \PrintIndex +% +% \endinput diff --git a/Master/texmf-dist/source/latex/expl3/l3tlp.dtx b/Master/texmf-dist/source/latex/expl3/l3tlp.dtx deleted file mode 100644 index 2d722a77624..00000000000 --- a/Master/texmf-dist/source/latex/expl3/l3tlp.dtx +++ /dev/null @@ -1,2054 +0,0 @@ -% \iffalse -%% File: l3tlp.dtx Copyright (C) 1990-2008 LaTeX3 project -%% -%% It may be distributed and/or modified under the conditions of the -%% LaTeX Project Public License (LPPL), either version 1.3c of this -%% license or (at your option) any later version. The latest version -%% of this license is in the file -%% -%% http://www.latex-project.org/lppl.txt -%% -%% This file is part of the ``expl3 bundle'' (The Work in LPPL) -%% and all files in that bundle must be distributed together. -%% -%% The released version of this bundle is available from CTAN. -%% -%% ----------------------------------------------------------------------- -%% -%% The development version of the bundle can be found at -%% -%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/ -%% -%% for those people who are interested. -%% -%%%%%%%%%%% -%% NOTE: %% -%%%%%%%%%%% -%% -%% Snapshots taken from the repository represent work in progress and may -%% not work or may contain conflicting material! We therefore ask -%% people _not_ to put them into distributions, archives, etc. without -%% prior consultation with the LaTeX Project Team. -%% -%% ----------------------------------------------------------------------- -% -%<*driver|package> -\RequirePackage{l3names} -%</driver|package> -%\fi -\GetIdInfo$Id: l3tlp.dtx 767 2008-08-05 19:44:21Z morten $ - {L3 Experimental Token List Pointers} -%\iffalse -%<*driver> -%\fi -\ProvidesFile{\filename.\filenameext} - [\filedate\space v\fileversion\space\filedescription] -%\iffalse -\documentclass{l3doc} -\begin{document} -\DocInput{\filename.\filenameext} -\end{document} -%</driver> -% \fi -% -% -% \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. -% -% Often you find yourself with not a token list pointer but an -% arbitrary token list which has to undergo certain tests. We will -% prefix these functions with "tlist". While token list pointers are -% always single tokens, token lists are always surrounded by -% braces. Perhaps these token lists should have their own module but -% for now I decided to put them here because there is quite a bit of -% overlap with token list pointers. -% -% \subsection{Functions} -% -% \begin{function}{\tlp_new:N | -% \tlp_new:c | -% \tlp_new:Nn | -% \tlp_new:cn | -% \tlp_new:Nx } -% \begin{syntax} -% "\tlp_new:Nn" <tlp> "{" <initial token list> "}" -% \end{syntax} -% Defines <tlp> 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. -% -% The form "\tlp_new:N" initializes the token list pointer with an empty value. -% \end{function} -% -% \begin{function}{% -% \tlp_use:N | -% \tlp_use:c -% } -% \begin{syntax} -% "\tlp_use:N" <tlp> -% \end{syntax} -% Function that inserts the <tlp> into the processing stream. Instead of -% |\tlp_use:N| simply placing the <tlp> into the input stream is also -% supported.|\tlp_use:c| will complain is the <tlp> hasn't been declared -% previously! -% \end{function} -% -% \begin{function}{% -% \tlp_set:Nn | -% \tlp_set:Nc | -% \tlp_set:No | -% \tlp_set:Nd | -% \tlp_set:Nf | -% \tlp_set:Nx | -% \tlp_gset:Nn | -% \tlp_gset:Nc | -% \tlp_gset:No | -% \tlp_gset:Nd | -% \tlp_gset:Nx | -% \tlp_gset:cn | -% \tlp_gset:cx } -% \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 <token list> 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 | -% \tlp_gclear_new:N | -% \tlp_gclear_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_put_left:Nx | -% \tlp_gput_left:Nn | -% \tlp_gput_left:No | -% \tlp_gput_left:Nx | -% \tlp_put_right:Nn | -% \tlp_put_right:No | -% \tlp_put_right:Nx | -% \tlp_put_right:cc | -% \tlp_gput_right:Nn | -% \tlp_gput_right:No| -% \tlp_gput_right:Nx| -% \tlp_gput_right:cn| -% \tlp_gput_right:co| -% } -% \begin{syntax} -% "\tlp_put_left:Nn" <tlp> "{" <token list> "}" -% \end{syntax} -% These functions will append <token list> to the left or right of -% <tlp>. Assignment is done either locally or globally and <token -% list> might be subject to expansion before assignment. -% \end{function} -% -% A word of warning is appropriate here: Token list pointers are -% implemented as macros and as such currently inherit some of the -% peculiarities of how \TeX\ handles "#"s in the argument of -% macros. In particular, the following actions are legal -% \begin{verbatim} -% \tlp_set:Nn \l_tmpa_tlp{##1} -% \tlp_put_right:Nn \l_tmpa_tlp{##2} -% \tlp_set:No \l_tmpb_tlp{\l_tmpa_tlp ##3} -% \end{verbatim} -% |x| type expansions where macros being expanded contain |#|s do not -% work and will not work until there is an |\expanded| primitive in -% the engine. If you want them to work you must double |#|s another -% level. -% -% -% \begin{function}{% -% \tlp_set_eq:NN | -% \tlp_set_eq:Nc | -% \tlp_set_eq:cN | -% \tlp_set_eq:cc | -% \tlp_gset_eq:NN | -% \tlp_gset_eq:Nc | -% \tlp_gset_eq:cN | -% \tlp_gset_eq:cc | -% } -% \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_if_empty_p:N| -% \tlp_if_empty_p:c -% } -% \begin{syntax} -% "\tlp_if_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_if_empty:NTF| -% \tlp_if_empty:NT| -% \tlp_if_empty:NF| -% \tlp_if_empty:cTF | -% \tlp_if_empty:cT | -% \tlp_if_empty:cF -% } -% \begin{syntax} -% "\tlp_if_empty:NTF" <tlp> "{"<true code>"}""{"<false code>"}" -% \end{syntax} -% Execute <true code> if <tlp> is empty and <false code> if it -% contains any tokens. -% \end{function} -% -% \begin{function}{\tlp_if_eq_p:NN | -% \tlp_if_eq_p:cN | -% \tlp_if_eq_p:Nc | -% \tlp_if_eq_p:cc | -% } -% \begin{syntax} -% "\tlp_if_eq_p:NN" <tlp1> <tlp2> -% \end{syntax} -% Predicate function which returns `true' if the two token list -% pointers are identical and `false' otherwise. -% \end{function} -% -% \begin{function}{ -% \tlp_if_eq:NNTF | -% \tlp_if_eq:NNT | -% \tlp_if_eq:NNF | -% \tlp_if_eq:cNTF | -% \tlp_if_eq:cNT | -% \tlp_if_eq:cNF | -% \tlp_if_eq:NcTF | -% \tlp_if_eq:NcT | -% \tlp_if_eq:NcF | -% \tlp_if_eq:ccTF | -% \tlp_if_eq:ccT | -% \tlp_if_eq:ccF | -% } -% \begin{syntax} -% "\tlp_if_eq:NNTF" <tlp1> <tlp2> "{"<true code>"}""{"<false code>"}" -% \end{syntax} -% Execute <true code> if <tlp1> holds the same token list as <tlp2> -% and <false code> otherwise. -% \end{function} -% -% -% \subsection{Token lists} -% -% \begin{function}{\tlist_if_eq:nnTF | -% \tlist_if_eq:nnT | -% \tlist_if_eq:nnF | -% \tlist_if_eq:noTF | -% \tlist_if_eq:noT | -% \tlist_if_eq:noF | -% } -% \begin{syntax} -% "\tlist_if_eq:nnTF" "{"<tlist1>"}" "{"<tlist2>"}" "{"<true -% code>"}" "{"<false code>"}" -% \end{syntax} -% Execute <true code> if the two token lists <tlist1> and <tlist2> are -% identical. -% \end{function} -% -% -% \begin{function}{\tlist_if_empty_p:n | -% \tlist_if_empty_p:o | -% \tlist_if_empty:nTF | -% \tlist_if_empty:nT | -% \tlist_if_empty:nF | -% \tlist_if_empty:oTF | -% \tlist_if_empty:oT | -% \tlist_if_empty:oF | -% } -% \begin{syntax} -% "\tlist_if_empty:nTF" "{"<tlist>"}" "{"<true code>"}" "{"<false code>"}" -% \end{syntax} -% Execute <true code> if <tlist> doesn't contain any tokens and <false -% code> otherwise. -% \end{function} -% -% \begin{function}{\tlist_if_blank_p:n | -% \tlist_if_blank:nTF | -% \tlist_if_blank:nT | -% \tlist_if_blank:nF | -% \tlist_if_blank_p:o | -% \tlist_if_blank:oTF | -% \tlist_if_blank:oT | -% \tlist_if_blank:oF | -% } -% \begin{syntax} -% "\tlist_if_blank:nTF" "{"<tlist>"}" "{"<true code>"}" "{"<false code>"}" -% \end{syntax} -% Execute <true code> if <tlist> is blank meaning that it is either -% empty or contains only blank spaces. -% \end{function} -% -% \begin{function}{\tlist_to_lowercase:n | -% \tlist_to_uppercase:n -% } -% \begin{syntax} -% "\tlist_to_lowercase:n" "{"<tlist>"}" -% \end{syntax} -% "\tlist_to_lowercase:n" converts all tokens in <tlist> to their -% lower case representation. Similar for "\tlist_to_uppercase:n". -% \begin{texnote} -% These are the \TeX\ primitives \tn{lowercase} and \tn{uppercase} -% renamed. -% \end{texnote} -% \end{function} -% -% \begin{function}{\tlist_to_str:n -% } -% \begin{syntax} -% "\tlist_to_str:n" "{"<tlist>"}" -% \end{syntax} -% This function turns its argument into a string where all characters -% have catcode `other'. -% \begin{texnote} -% This is the \eTeX\ primitive \tn{detokenize}. -% \end{texnote} -% \end{function} -% -% \begin{function}{% -% \tlist_map_function:nN | -% \tlp_map_function:NN | -% \tlp_map_function:cN | -% } -% \begin{syntax} -% "\tlist_map_function:nN" "{"<tlist>"}" <function> \\ -% "\tlp_map_function:NN" <tlp> <function> -% \end{syntax} -% Runs through all elements in a |tlist| from left to right and places -% <function> in front of each element. As this function will also pick -% up elements in brace groups, the element is returned with braces and -% hence <function> should be a function with a |:n| suffix even though -% it may very well only deal with a single token. This function uses a -% purely expandable loop function and will stay so as long as -% <function> is expandable too. -% \end{function} -% -% \begin{function}{% -% \tlist_map_inline:nn | -% \tlp_map_inline:Nn | -% \tlp_map_inline:cn | -% } -% \begin{syntax} -% "\tlist_map_inline:nn" "{"<tlist>"}" "{"<inline~function>"}" \\ -% "\tlp_map_inline:Nn" <tlp> "{"<inline~function>"}" -% \end{syntax} -% Allows a syntax like "\tlist_map_inline:nn" "{"<tlist>"}" -% "{\token_to_string:N ##1}". This renders it non-expandable though. -% Remember to double the "#"s for each level. -% \end{function} -% -% -% \begin{function}{% -% \tlist_map_variable:nNn | -% \tlp_map_variable:NNn | -% \tlp_map_variable:cNn | -% } -% \begin{syntax} -% "\tlist_map_variable:nNn" "{"<tlist>"}" <temp> "{"<action>"}" \\ -% "\tlp_map_variable:NNn" <tlp> <temp> "{"<action>"}" -% \end{syntax} -% Assigns <temp> to each element on <tlist> and executes <action>. -% As there is an assignment in this process it is not expandable. -% \begin{texnote} -% This is the \LaTeX2{} function \tn{@tfor} but with a more sane syntax. -% Also it works by tail recursion and so is faster as lists grow longer. -% \end{texnote} -% \end{function} -% -% \begin{function}{% -% \tlist_map_break:w | -% \tlp_map_break:w | -% } -% \begin{syntax} -% "\tlist_map_break:w" -% \end{syntax} -% For breaking out of a loop. You should take note of the ":w" as -% its usage must be precise! -% \end{function} -% -% -% \begin{function}{% -% \tlist_reverse:n | -% } -% \begin{syntax} -% "\tlist_reverse:n" "{"<token$\sb1$><token$\sb2$>...<token$\sb n$>"}" -% \end{syntax} -% Reverse the token list to result in -% <token$\sb n$>\dots<token$\sb2$><token$\sb1$>. Note that spaces in this -% token list are gobbled in the process. -% \end{function} -% -% \begin{function}{% -% \tlist_elt_count:n | -% \tlist_elt_count:o | -% \tlp_elt_count:N | -% } -% \begin{syntax} -% "\tlist_elt_count:n" "{"<token list>"}" \\ -% "\tlp_elt_count:N" <tlp> -% \end{syntax} -% Returns the number of elements in the token list. Brace groups -% encountered count as one element. Note that spaces in this -% token list are gobbled in the process. -% \end{function} -% -% -% \subsubsection{Internal functions} -% -% -% \begin{function}{% -% \tlist_map_function_aux:Nn | -% \tlist_map_inline_aux:Nn | -% \tlist_map_variable_aux:Nnn | -% } -% \begin{syntax}\end{syntax} -% Internal helper functions for the <tlist> loops. -% \end{function} -% -% -% -% \begin{function}{\tlist_if_blank_p_aux:w -% } -% \end{function} -% -% -% -% \subsection{Variables 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{variable}{% -% \l_replace_tlp | -% } -% Internal register used in the replace functions. -% \end{variable} -% -% \begin{variable}{% -% \l_testa_tlp | -% \l_testb_tlp | -% \g_testa_tlp | -% \g_testb_tlp | -% } -% Registers used for conditional processing if the engine doesn't -% support arbitrary string comparison. -% \end{variable} -% -% -% \begin{function}{\tlp_to_str_aux:w} -% Function used to implement "\tlp_to_str:N". -% \end{function} -% -% -% \subsection{Search and replace} -% -% -% \begin{function}{ -% \tlp_if_in:NnTF | -% \tlp_if_in:cnTF | -% \tlp_if_in:NnT | -% \tlp_if_in:cnT | -% \tlp_if_in:NnF | -% \tlp_if_in:cnF | -% \tlist_if_in:nnTF | -% \tlist_if_in:onTF | -% } -% \begin{syntax} -% "\tlp_if_in:NnTF" <tlp> "{" <item> "}{" <true code> "}{" -% <false code> "}" -% \end{syntax} -% Function that tests if <item> is in <tlp>. Depending on the result -% either <true code> or <false code> is executed. Note that <item> -% cannot contain brace groups. -% \end{function} -% -% \begin{function}{ -% \tlp_replace_in:Nnn | -% \tlp_replace_in:cnn | -% \tlp_greplace_in:Nnn | -% \tlp_greplace_in:cnn | -% } -% \begin{syntax} -% "\tlp_replace_in:Nnn" <tlp> "{" <item1> "}{" <item2> "}" -% \end{syntax} -% Replaces the leftmost occurrence of <item1> in <tlp> with -% <item2> if present, otherwise the <tlp> is left untouched. -% \end{function} -% -% \begin{function}{ -% \tlp_replace_all_in:Nnn | -% \tlp_replace_all_in:cnn | -% \tlp_greplace_all_in:Nnn | -% \tlp_greplace_all_in:cnn | -% } -% \begin{syntax} -% "\tlp_replace_all_in:Nnn" <tlp> "{" <item1> "}{" <item2> "}" -% \end{syntax} -% Replaces \emph{all} occurrences of <item1> in <tlp> with -% <item2>. -% \end{function} -% -% -% \begin{function}{ -% \tlp_remove_in:Nn | -% \tlp_remove_in:cn | -% \tlp_gremove_in:Nn | -% \tlp_gremove_in:cn | -% } -% \begin{syntax} -% "\tlp_remove_in:Nn" <tlp> "{" <item> "}" -% \end{syntax} -% Removes the leftmost occurrence of <item> from <tlp> if present. -% \end{function} -% -% -% \begin{function}{ -% \tlp_remove_all_in:Nn | -% \tlp_remove_all_in:cn | -% \tlp_gremove_all_in:Nn | -% \tlp_gremove_all_in:cn | -% } -% \begin{syntax} -% "\tlp_remove_all_in:Nn" <tlp> "{" <item> "}" -% \end{syntax} -% Removes \emph{all} occurrences of <item> from <tlp>. -% \end{function} -% -% -% \subsection{Heads or tails?} -% -% Here are some functions for grabbing either the head or tail of a -% list and perform some tests on it. -% -% \begin{function}{% -% \tlist_head:n | -% \tlist_tail:n | -% \tlist_head_iii:n | -% \tlist_head_iii:f | -% \tlist_head:w | -% \tlist_tail:w | -% \tlist_head_iii:w -% } -% \begin{syntax} -% "\tlist_head:n" "{" <token1><token2>...<token-n> "}" \\ -% "\tlist_tail:n" "{" <token1><token2>...<token-n> "}" -% \end{syntax} -% These functions return either the head or the tail of a list, thus in -% the above example "\tlist_head:n" would return <token1> and "\tlist_tail:n" -% would return <token2>\dots<token-n>. "\tlist_head_iii:n" returns the first -% three tokens. The ":w" versions require some care as they use a -% delimited argument internally. -% \begin{texnote} -% These are the Lisp functions "car" and "cdr" but with \LaTeX3 names. -% \end{texnote} -% \end{function} -% -% -% -% -% \begin{function}{% -% \tlist_if_head_eq_meaning_p:nN | -% \tlist_if_head_eq_meaning:nNTF | -% \tlist_if_head_eq_meaning:nNTF | -% \tlist_if_head_eq_meaning:nNTF | -% } -% \begin{syntax} -% "\tlist_if_head_eq_meaning:nNTF" "{" <token list> "}" <token> -% "{"<true>"}""{"<false>"}" -% \end{syntax} -% Returns <true> if the first token in <token list> is equal to -% <token> and <false> otherwise. The |meaning| version compares the -% two tokens with |\if_meaning:NN|. -% \end{function} -% -% \begin{function}{% -% \tlist_if_head_eq_charcode_p:nN | -% \tlist_if_head_eq_charcode:nNTF | -% \tlist_if_head_eq_charcode:nNTF | -% \tlist_if_head_eq_charcode:nNTF | -% } -% \begin{syntax} -% "\tlist_if_head_eq_charcode:nNTF" "{" <token list> "}" <token> -% "{"<true>"}""{"<false>"}" -% \end{syntax} -% Returns <true> if the first token in <token list> is equal to -% <token> and <false> otherwise. The |meaning| version compares the -% two tokens with |\if_charcode:w| but it prevents expansion of -% them. If you want them to expand, you can use an |f| type expansion -% first (define |\tlist_if_head_eq_charcode:fNTF| or similar). -% \end{function} -% -% \begin{function}{% -% \tlist_if_head_eq_catcode_p:nN | -% \tlist_if_head_eq_catcode:nNTF | -% \tlist_if_head_eq_catcode:nNTF | -% \tlist_if_head_eq_catcode:nNTF | -% } -% \begin{syntax} -% "\tlist_if_head_eq_catcode:nNTF" "{" <token list> "}" <token> -% "{"<true>"}""{"<false>"}" -% \end{syntax} -% Returns <true> if the first token in <token list> is equal to -% <token> and <false> otherwise. This version uses |\if_catcode:w| for -% the test but is otherwise identical to the |charcode| version. -% \end{function} -% -% -% \StopEventually{} -% -% \subsection{The Implementation} -% -% We start by ensuring that the required packages are loaded. -% \begin{macrocode} -%<package>\ProvidesExplPackage -%<package> {\filename}{\filedate}{\fileversion}{\filedescription} -%<package&!check>\RequirePackage{l3basics} -%<package&check>\RequirePackage{l3chk} -% \end{macrocode} -% \begin{macrocode} -%<*initex|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.) -% -% -% -% \begin{macro}{\tlp_new:N} -% \begin{macro}{\tlp_new:c} -% \begin{macro}{\tlp_new:Nn} -% \begin{macro}{\tlp_new:cn} -% \begin{macro}{\tlp_new:Nx} -% 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} -\def_long_new:Npn \tlp_new:Nn #1#2{ - \chk_new_cs:N #1 -% \end{macrocode} -% If checking we don't allow constants to be defined. -% \begin{macrocode} -%<*check> - \chk_var_or_const:N #1 -%</check> -% \end{macrocode} -% Otherwise any variable type is allowed. -% \begin{macrocode} - \gdef:Npn #1{#2} -} -\def_new:Npn \tlp_new:cn {\exp_args:Nc \tlp_new:Nn } -\def_long_new:Npn \tlp_new:Nx #1#2{ - \chk_new_cs:N #1 -%<check> \chk_var_or_const:N #1 - \gdef:Npx #1{#2} -} -\def_new:Npn \tlp_new:N #1{\tlp_new:Nn #1{}} -\def_new:Npn \tlp_new:c #1{\tlp_new:cn {#1}{}} -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% -% -% \begin{macro}{\tlp_use:N} -% \begin{macro}{\tlp_use:c} -% Perhaps this should just be enabled when checking? -% \begin{macrocode} -\def_new:Npn \tlp_use:N #1 { - \if_meaning:NN #1 \scan_stop: -% \end{macrocode} -% If \m{tlp} equals |\scan_stop:| it is probably stemming from a -% |\cs:w ... \cd_end:| that was created by mistake somewhere. -% \begin{macrocode} - \err_latex_bug:x {Token~list~pointer~ `\token_to_string:N #1'~ - has~ an~ erroneous~ structure!} - \else: - \exp_after:NN #1 - \fi: -} -\def_new:Npn \tlp_use:c {\exp_args:Nc \tlp_use:N} -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% -% \begin{macro}{\tlp_set:Nn} -% \begin{macro}{\tlp_set:No} -% \begin{macro}{\tlp_set:Nd} -% \begin{macro}{\tlp_set:Nf} -% \begin{macro}{\tlp_set:Nx} -% \begin{macro}{\tlp_set:cn} -% \begin{macro}{\tlp_set:co} -% \begin{macro}{\tlp_set:cx} -% \begin{macro}{\tlp_gset:Nn} -% \begin{macro}{\tlp_gset:No} -% \begin{macro}{\tlp_gset:Nd} -% \begin{macro}{\tlp_gset:Nx} -% \begin{macro}{\tlp_gset:cn} -% \begin{macro}{\tlp_gset:cx} -% 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|. -% 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 built-in. -% \begin{macrocode} - \chk_local_or_pref_global:N #1 -} -\def_long_new:Npn \tlp_set:Nx #1#2{ - \chk_exist_cs:N #1 \def:Npx #1{#2} \chk_local:N #1 -} -% \end{macrocode} -% The the global versions. -% \begin{macrocode} -\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:Nx #1#2{ - \chk_exist_cs:N #1 \gdef:Npx #1{#2} \chk_global:N #1 -} -%</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_long_new:Npn\tlp_set:Nn#1#2{\def:Npn#1{#2}} -\def_long_new:Npn\tlp_set:Nx#1#2{\def:Npx#1{#2}} -\def_long_new:Npn\tlp_gset:Nn#1#2{\gdef:Npn#1{#2}} -\def_long_new:Npn\tlp_gset:Nx#1#2{\gdef:Npx#1{#2}} -%</!check> -% \end{macrocode} -% The remaining functions can just be defined with help from the -% expansion module. -% \begin{macrocode} -\def_new:Npn \tlp_set:No {\exp_args:NNo \tlp_set:Nn} -\def_new:Npn \tlp_set:Nd {\exp_args:NNd \tlp_set:Nn} -\def_new:Npn \tlp_set:Nf {\exp_args:NNf \tlp_set:Nn} -\def_new:Npn \tlp_set:cn {\exp_args:Nc \tlp_set:Nn} -\def_new:Npn \tlp_set:co {\exp_args:Nco \tlp_set:Nn} -\def_new:Npn \tlp_set:cx {\exp_args:Nc \tlp_set:Nx} -\def_new:Npn \tlp_gset:No {\exp_args:NNo \tlp_gset:Nn} -\def_new:Npn \tlp_gset:Nd {\exp_args:NNd \tlp_gset:Nn} -\def_new:Npn \tlp_gset:cn {\exp_args:Nc \tlp_gset:Nn} -\def_new:Npn \tlp_gset:cx {\exp_args:Nc \tlp_gset:Nx} -% \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} -% -% \begin{macro}{\tlp_set_eq:NN} -% \begin{macro}{\tlp_set_eq:Nc} -% \begin{macro}{\tlp_set_eq:cN} -% \begin{macro}{\tlp_set_eq:cc} -% \begin{macro}{\tlp_gset_eq:NN} -% \begin{macro}{\tlp_gset_eq:Nc} -% \begin{macro}{\tlp_gset_eq:cN} -% \begin{macro}{\tlp_gset_eq:cc} -% For setting token list pointers equal to each other. First checking: -% \begin{macrocode} -%<*check> -\def_new:Npn \tlp_set_eq:NN #1#2{ - \chk_exist_cs:N #1 \let:NN #1#2 - \chk_local_or_pref_global:N #1 \chk_var_or_const:N #2 -} -\def_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} -% Non-checking versions are easy. -% \begin{macrocode} -%<*!check> -\let_new:NN \tlp_set_eq:NN \let:NN -\let_new:NN \tlp_gset_eq:NN \glet:NN -%</!check> -% \end{macrocode} -% The rest again with the expansion module. -% \begin{macrocode} -\def_new:Npn \tlp_set_eq:Nc {\exp_args:NNc \tlp_set_eq:NN} -\def_new:Npn \tlp_set_eq:cN {\exp_args:Nc \tlp_set_eq:NN} -\def_new:Npn \tlp_set_eq:cc {\exp_args:Ncc \tlp_set_eq:NN} -\def_new:Npn \tlp_gset_eq:Nc {\exp_args:NNc \tlp_gset_eq:NN} -\def_new:Npn \tlp_gset_eq:cN {\exp_args:Nc \tlp_gset_eq:NN} -\def_new:Npn \tlp_gset_eq:cc {\exp_args:Ncc \tlp_gset_eq:NN} -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% -% -% -% \begin{macro}{\tlp_clear:N} -% \begin{macro}{\tlp_clear:c} -% \begin{macro}{\tlp_gclear:N} -% \begin{macro}{\tlp_gclear:c} -% Clearing a token list pointer. -% \begin{macrocode} -\def_new:Npn \tlp_clear:N #1{\tlp_set_eq:NN #1\c_empty_tlp} -\def_new:Npn \tlp_clear:c {\exp_args:Nc \tlp_clear:N} -\def_new:Npn \tlp_gclear:N #1{\tlp_gset_eq:NN #1\c_empty_tlp} -\def_new:Npn \tlp_gclear:c {\exp_args:Nc \tlp_gclear:N} -% \end{macrocode} -% \end{macro} -% \end{macro} -% \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_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_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_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_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_put_left:Nx} -% \begin{macro}{\tlp_gput_left:Nn} -% \begin{macro}{\tlp_gput_left:No} -% \begin{macro}{\tlp_gput_left:Nx} -% We can add tokens to the left (either globally or locally). It is -% not quite as easy as we would like because we have to ensure the -% assignments -% \begin{verbatim} -% \tlp_set:Nn \l_tmpa_tlp{##1abc##2def} -% \tlp_set:Nn \l_tmpb_tlp{##1abc} -% \tlp_put_right:Nn \l_tmpb_tlp {##2def} -% \end{verbatim} -% cause |\l_tmpa_tlp| and |\l_tmpb_tlp| to be identical. The old -% code did not succeed in doing this (it gave an error) and so we -% use a different technique where the item(s) to be added are first -% stored in a temporary pointer and then added using an |x| type -% expansion combined with the appropriate level of -% non-expansion. Putting the tokens directly into one assignment -% does not work unless we want full expansion. Note (according to -% the warning earlier) \TeX\ does not allow us to treat |#|s the -% same in all cases. Tough. -% \begin{macrocode} -\def_long_new:Npn \tlp_put_left:Nn #1#2{ - \tlp_set:Nn \l_exp_tlp{#2} - \tlp_set:Nx #1{\exp_not:o{\l_exp_tlp}\exp_not:o{#1}} -%<check> \chk_local_or_pref_global:N #1 -} -\def_long_new:Npn \tlp_put_left:No #1#2{ - \tlp_set:Nn \l_exp_tlp{#2} - \tlp_set:Nx #1{\exp_not:d{\l_exp_tlp}\exp_not:o{#1}} -%<check> \chk_local_or_pref_global:N #1 -} -\def_long_new:Npn \tlp_put_left:Nx #1#2{ - \tlp_set:Nx #1{#2\exp_not:o{#1}} -%<check> \chk_local_or_pref_global:N #1 -} -\def_long_new:Npn \tlp_gput_left:Nn #1#2{ - \tlp_set:Nn \l_exp_tlp{#2} - \tlp_gset:Nx #1{\exp_not:o{\l_exp_tlp}\exp_not:o{#1}} -%<check> \chk_local_or_pref_global:N #1 -} -\def_long_new:Npn \tlp_gput_left:No #1#2{ - \tlp_set:Nn \l_exp_tlp{#2} - \tlp_gset:Nx #1{\exp_not:d{\l_exp_tlp}\exp_not:o{#1}} -%<check> \chk_local_or_pref_global:N #1 -} -\def_long_new:Npn \tlp_gput_left:Nx #1#2{ - \tlp_gset:Nx #1{#2\exp_not:o{#1}} -%<check> \chk_local_or_pref_global:N #1 -} -\def_long_new:Npn \tlp_put_left:cn{\exp_args:Nc\tlp_put_left:Nn} -\def_long_new:Npn \tlp_put_left:co{\exp_args:Nc\tlp_put_left:No} -\def_long_new:Npn \tlp_put_left:cx{\exp_args:Nc\tlp_put_left:Nx} -\def_long_new:Npn \tlp_gput_left:cn{\exp_args:Nc\tlp_gput_left:Nn} -\def_long_new:Npn \tlp_gput_left:co{\exp_args:Nc\tlp_gput_left:No} -\def_long_new:Npn \tlp_gput_left:cx{\exp_args:Nc\tlp_gput_left:Nx} -% \end{macrocode} -% \end{macro} -% \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:cn} -% \begin{macro}{\tlp_gput_right:co} -% \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:Nn \l_exp_tlp{#2} - \tlp_set:Nx #1{\exp_not:o{#1}\exp_not:o{\l_exp_tlp}} -%<check> \chk_local_or_pref_global:N #1 -} -\def_long_new:Npn \tlp_gput_right:Nn #1#2{ - \tlp_set:Nn \l_exp_tlp{#2} - \tlp_gset:Nx #1{\exp_not:o{#1}\exp_not:o{\l_exp_tlp}} -%<check> \chk_local_or_pref_global:N #1 -} -\def_long_new:Npn \tlp_put_right:No #1#2{ - \tlp_set:Nn \l_exp_tlp{#2} - \tlp_set:Nx #1{\exp_not:o{#1}\exp_not:d{\l_exp_tlp}} -%<check> \chk_local_or_pref_global:N #1 -} -\def_long_new:Npn \tlp_gput_right:No #1#2{ - \tlp_set:Nn \l_exp_tlp{#2} - \tlp_gset:Nx #1{\exp_not:o{#1}\exp_not:d{\l_exp_tlp}} -%<check> \chk_local_or_pref_global:N #1 -} -\def_long:Npn \tlp_put_right:Nx #1#2{ - \tlp_set:Nx #1{\exp_not:o{#1}#2} -%<check> \chk_local_or_pref_global:N #1 -} -\def_long:Npn \tlp_gput_right:Nx #1#2{ - \tlp_gset:Nx #1{\exp_not:o{#1}#2} -%<check> \chk_local_or_pref_global:N #1 -} -\def_new:Npn \tlp_gput_right:cn {\exp_args:Nc \tlp_gput_right:Nn} -\def_new:Npn \tlp_gput_right:co {\exp_args:Nc \tlp_gput_right:No} -\def_new:Npn \tlp_put_right:cc {\exp_args:Ncc \tlp_put_right:Nn} -% \end{macrocode} -% \end{macro} -% \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_if_empty_p:N} -% \begin{macro}{\tlp_if_empty_p:c} -% Returns |\c_true| iff the token list in the argument is empty. -% \begin{macrocode} -\def_new:Npn \tlp_if_empty_p:N #1{ - \if_meaning:NN#1\c_empty_tlp \c_true \else: \c_false \fi:} -\def_new:Npn \tlp_if_empty_p:c {\exp_args:Nc\tlp_if_empty_p:N} -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% -% \begin{macro}{\tlp_if_empty:NTF} -% \begin{macro}{\tlp_if_empty:NT} -% \begin{macro}{\tlp_if_empty:NF} -% \begin{macro}{\tlp_if_empty:cTF} -% \begin{macro}{\tlp_if_empty:cT} -% \begin{macro}{\tlp_if_empty:cF} -% These functions check whether the token list in the argument is -% empty and execute the proper code from their argument(s). -% \begin{macrocode} -\def_test_function_new:npn {tlp_if_empty:N} #1{ - \if_meaning:NN#1\c_empty_tlp} -\def_new:Npn \tlp_if_empty:cTF {\exp_args:Nc \tlp_if_empty:NTF} -\def_new:Npn \tlp_if_empty:cT {\exp_args:Nc \tlp_if_empty:NT} -\def_new:Npn \tlp_if_empty:cF {\exp_args:Nc \tlp_if_empty:NF} -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\tlp_if_eq_p:NN} -% \begin{macro}{\tlp_if_eq_p:Nc} -% \begin{macro}{\tlp_if_eq_p:cN} -% \begin{macro}{\tlp_if_eq_p:cc} -% Returns |\c_true| iff the two token list pointers are equal. -% \begin{macrocode} -\def_new:Npn \tlp_if_eq_p:NN #1#2{ - \if_meaning:NN#1#2 \c_true \else: \c_false \fi:} -\def_new:Npn \tlp_if_eq_p:Nc {\exp_args:NNc\tlp_if_empty_p:NN} -\def_new:Npn \tlp_if_eq_p:cN {\exp_args:Nc\tlp_if_empty_p:NN} -\def_new:Npn \tlp_if_eq_p:cc {\exp_args:Ncc\tlp_if_empty_p:NN} -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\tlp_if_eq:NNTF} -% \begin{macro}{\tlp_if_eq:NNT} -% \begin{macro}{\tlp_if_eq:NNF} -% \begin{macro}{\tlp_if_eq:NcTF} -% \begin{macro}{\tlp_if_eq:NcT} -% \begin{macro}{\tlp_if_eq:NcF} -% \begin{macro}{\tlp_if_eq:cNTF} -% \begin{macro}{\tlp_if_eq:cNT} -% \begin{macro}{\tlp_if_eq:cNF} -% \begin{macro}{\tlp_if_eq:ccTF} -% \begin{macro}{\tlp_if_eq:ccT} -% \begin{macro}{\tlp_if_eq:ccF} -% These function tests whether the token list pointers that are in its -% first two arguments are equal. -% \begin{macrocode} -\def_test_function_new:npn {tlp_if_eq:NN} #1#2{\if_meaning:NN#1#2} -\def_new:Npn \tlp_if_eq:cNTF{\exp_args:Nc \tlp_if_eq:NNTF} -\def_new:Npn \tlp_if_eq:cNT {\exp_args:Nc \tlp_if_eq:NNT} -\def_new:Npn \tlp_if_eq:cNF {\exp_args:Nc \tlp_if_eq:NNF} -\def_new:Npn \tlp_if_eq:NcTF{\exp_args:NNc \tlp_if_eq:NNTF} -\def_new:Npn \tlp_if_eq:NcT {\exp_args:NNc \tlp_if_eq:NNT} -\def_new:Npn \tlp_if_eq:NcF {\exp_args:NNc \tlp_if_eq:NNF} -\def_new:Npn \tlp_if_eq:ccTF{\exp_args:Ncc \tlp_if_eq:NNTF} -\def_new:Npn \tlp_if_eq:ccT {\exp_args:Ncc \tlp_if_eq:NNT} -\def_new:Npn \tlp_if_eq:ccF {\exp_args:Ncc \tlp_if_eq:NNF} -% \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} -% -% -% -% \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:w} -% 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:w - \token_to_meaning:N} -\def_new:Npn \tlp_to_str_aux:w #1>{} -\def_new:Npn\tlp_to_str:c{\exp_args:Nc\tlp_to_str:N} -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% -% -% -% -% \begin{macro}{\tlist_if_empty_p:n} -% It would be tempting to just use "\if_meaning:NN\q_nil#1\q_nil" as -% a test since this works really well. However it fails on a token -% list starting with "\q_nil" of course but more troubling is the -% case where argument is a complete conditional such as "\if_true:" -% a "\else:" b "\fi:" because then "\if_true:" is used by -% "\if_meaning:NN", the test turns out false, the "\else:" executes -% the false branch, the "\fi:" ends it and the "\q_nil" at the end -% starts executing\dots{} A safer route is to convert the entire -% token list into harmless characters first and then compare -% that. This way the test will even accept "\q_nil" as the first -% token. -% \begin{macrocode} -\def_long_new:Npn \tlist_if_empty_p:n #1{ - \exp_after:NN\if_meaning:NN\exp_after:NN\q_nil\tlist_to_str:n{#1}\q_nil - \c_true - \else: - \c_false - \fi: -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\tlist_if_empty_p:o} -% \begin{macro}{\tlist_if_empty:nTF} -% \begin{macro}{\tlist_if_empty:nT} -% \begin{macro}{\tlist_if_empty:nF} -% \begin{macro}{\tlist_if_empty:oTF} -% \begin{macro}{\tlist_if_empty:oT} -% \begin{macro}{\tlist_if_empty:oF} -% \begin{macrocode} -\def_new:Npn \tlist_if_empty_p:o {\exp_args:No\tlist_if_empty_p:n} -\def_long_test_function_new:npn{tlist_if_empty:n}#1{ - \if:w\tlist_if_empty_p:n{#1}} -\def_long_test_function_new:npn{tlist_if_empty:o}#1{ - \if:w\tlist_if_empty_p:o{#1}} -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\tlist_if_blank_p:n} -% \begin{macro}{\tlist_if_blank_p_aux:w} -% This is based on the answers in ``Around the Bend No~2'' but is -% safer as the tests listed there all have one small flaw: If the -% input in the test is two tokens with the same meaning as the -% internal delimiter, they will fail since one of them is mistaken -% for the actual delimiter. In our version below we make sure to -% pass the input through |\tlist_to_str:n| which ensures that all -% the tokens are converted to catcode 12. However we use an |a| with -% catcode 11 as delimiter so we can \emph{never} get into the same -% problem as the solutions in ``Around the Bend No~2''. -% \begin{macrocode} -\def_long_new:Npn \tlist_if_blank_p:n #1{ - \exp_after:NN\tlist_if_blank_p_aux:w\tlist_to_str:n{#1}aa..\q_nil -} -\def_new:Npn \tlist_if_blank_p_aux:w #1#2a#3#4\q_nil{ - \if_meaning:NN #3#4\c_true\else:\c_false\fi:} -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\tlist_if_blank:nTF} -% \begin{macro}{\tlist_if_blank:nT} -% \begin{macro}{\tlist_if_blank:nF} -% \begin{macro}{\tlist_if_blank_p:o} -% \begin{macro}{\tlist_if_blank:oTF} -% \begin{macro}{\tlist_if_blank:oT} -% \begin{macro}{\tlist_if_blank:oF} -% Variations on the original function above. -% \begin{macrocode} -\def_long_test_function_new:npn{tlist_if_blank:n}#1{ - \if:w\tlist_if_blank_p:n{#1}} -\def:Npn \tlist_if_blank_p:o{\exp_args:No\tlist_if_blank_p:n} -\def_long_test_function_new:npn{tlist_if_blank:o}#1{ - \if:w\tlist_if_blank_p:o{#1}} -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\tlist_to_lowercase:n} -% \begin{macro}{\tlist_to_uppercase:n} -% Just some names for a few primitives. -% \begin{macrocode} -\let_new:NN \tlist_to_lowercase:n \tex_lowercase:D -\let_new:NN \tlist_to_uppercase:n \tex_uppercase:D -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\tlist_to_str:n} -% Another name for a primitive. -% \begin{macrocode} -\let_new:NN \tlist_to_str:n \etex_detokenize:D -% \end{macrocode} -% \end{macro} -% -% -% \begin{macro}{\tlist_map_function:nN} -% \begin{macro}{\tlp_map_function:NN} -% \begin{macro}{\tlp_map_function:cN} -% \begin{macro}{\tlist_map_function_aux:NN} -% Expandable loop macro for |tlist|s. These have the advantage of not -% needing to test if the argument is empty, because if it is, the stop -% marker will be read immediately and the loop terminated. -% \begin{macrocode} -\def_long_new:Npn \tlist_map_function:nN #1#2{ - \tlist_map_function_aux:Nn #2 #1 \q_recursion_tail \q_recursion_stop -} -\def_new:Npn \tlp_map_function:NN #1#2{ - \exp_after:NN \tlist_map_function_aux:Nn - \exp_after:NN #2 #1 \q_recursion_tail \q_recursion_stop -} -\def_long_new:Npn \tlist_map_function_aux:Nn #1#2{ - \quark_if_recursion_tail_stop:n{#2} - #1{#2} \tlist_map_function_aux:Nn #1 -} -\def_new:Npn\tlp_map_function:cN{\exp_args:Nc\tlp_map_function:NN} -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% -% -% \begin{macro}{\tlist_map_inline:nn} -% \begin{macro}{\tlp_map_inline:Nn} -% \begin{macro}{\tlp_map_inline:cn} -% \begin{macro}{\tlist_map_inline_aux:n} -% \begin{macro}{\g_tlp_inline_level_num} -% The inline functions are straight forward by now. We use a little -% a trick with the fake counter |\g_tlp_inline_level_num| to make -% them nestable.\footnote{This should be a proper integer, but I -% don't want to mess with the dependencies right now\dots} We can -% also make use of |\tlist_map_function:Nn| from before. -% \begin{macrocode} -\def_long_new:Npn \tlist_map_inline:nn #1#2{ - \num_gincr:N \g_tlp_inline_level_num - \gdef_long:cpn {tlist_map_inline_ \num_use:N \g_tlp_inline_level_num :n} - ##1{#2} - \exp_args:Nc \tlist_map_function_aux:Nn - {tlist_map_inline_ \num_use:N \g_tlp_inline_level_num :n} - #1 \q_recursion_tail\q_recursion_stop - \num_gdecr:N \g_tlp_inline_level_num -} -\def_long_new:Npn \tlp_map_inline:Nn #1#2{ - \num_gincr:N \g_tlp_inline_level_num - \gdef_long:cpn {tlist_map_inline_ \num_use:N \g_tlp_inline_level_num :n} - ##1{#2} - \exp_args:NcE \tlist_map_function_aux:Nn - {tlist_map_inline_ \num_use:N \g_tlp_inline_level_num :n} - #1 \q_recursion_tail\q_recursion_stop - \num_gdecr:N \g_tlp_inline_level_num -} -\def_new:Npn\tlp_map_inline:cN{\exp_args:Nc\tlp_map_inline:NN} -\tlp_new:Nn \g_tlp_inline_level_num{0} -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% -% -% \begin{macro}{\tlist_map_variable:nNn} -% \begin{macro}{\tlp_map_variable:NNn} -% \begin{macro}{\tlp_map_variable:cNn} -% |\tlist_map:nNn| \zz{tlist} \zz{temp} \zz{action} assigns -% \zz{temp} to each element and executes \zz{action}. -% \begin{macrocode} -\def_long_new:Npn \tlist_map_variable:nNn #1#2#3{ - \tlist_map_variable_aux:Nnn #2 {#3} #1 \q_recursion_tail \q_recursion_stop -} -\def_new:Npn \tlp_map_variable:NNn {\exp_args:No \tlist_map_variable:nNn} -\def_new:Npn \tlp_map_variable:cNn {\exp_args:Nc \tlp_map_variable:NNn} -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\tlist_map_variable_aux:NnN} -% The general loop. Assign the temp variable |#1| to the current item -% |#3| and then check if that's the stop marker. If it is, break the -% loop. If not, execute the action |#2| and continue. -% \begin{macrocode} -\def_long_new:Npn \tlist_map_variable_aux:Nnn #1#2#3{ - \tlp_set:Nn #1{#3} - \quark_if_recursion_tail_stop:N #1 - #2 \tlist_map_variable_aux:Nnn #1{#2} -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\tlist_map_break:w} -% \begin{macro}{\tlp_map_break:w} -% The break statement. -% \begin{macrocode} -\let_new:NN \tlist_map_break:w \use_none_delimit_by_q_recursion_stop:w -\let_new:NN \tlp_map_break:w \tlist_map_break:w -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% -% \begin{macro}{\tlist_elt_count:n} -% \begin{macro}{\tlist_elt_count:o} -% \begin{macro}{\tlp_elt_count:n} -% Count number of elements within a token list or token list -% pointer. Brace groups within the list are read as a single -% element. -% "\num_elt_count:n" grabs the element and replaces it by "+1". The -% "0" to ensure it works on an empty list. -% \begin{macrocode} -\def_long_new:Npn \tlist_elt_count:n #1{ - \num_value:w \num_eval:w 0 - \tlist_map_function:nN {#1}\num_elt_count:n - \num_eval_end: -} -\def_new:Npn \tlist_elt_count:o {\exp_args:No\tlist_elt_count:n} -\def_new:Npn \tlp_elt_count:N #1{ - \num_value:w \num_eval:w 0 - \tlp_map_function:NN #1 \num_elt_count:n - \num_eval_end: -} -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% -% -% -% -% \begin{macro}{\tlist_if_eq:nnTF} -% \begin{macro}{\tlist_if_eq:nnT} -% \begin{macro}{\tlist_if_eq:nnF} -% Test if two token lists are identical. pdf\TeX\ contains a most -% interesting primitive for expandable string comparison so we make -% use of it if available. Presumable it will be in the final -% version. -% -% Firstly we give it an appropriate name. Note that this primitive -% actually performs an \texttt{x} type expansion but it is still -% expandable! Hence we must program these functions backwards to add -% \verb|\exp_not:n|. We provide the combinations for the types -% \texttt{n}, \texttt{o} and \texttt{x}. -% \begin{macrocode} -\let_new:NN \tlist_compare:xx \pdfstrcmp -\def_long_new:NNn \tlist_compare:nn 2{ - \tlist_compare:xx{\exp_not:n{#1}}{\exp_not:n{#2}} -} -\def_long_new:NNn \tlist_compare:nx 1{ - \tlist_compare:xx{\exp_not:n{#1}} -} -\def_long_new:NNn \tlist_compare:xn 2{ - \tlist_compare:xx{#1}{\exp_not:n{#2}} -} -\def_long_new:NNn \tlist_compare:no 2{ - \tlist_compare:xx{\exp_not:n{#1}}{\exp_not:n\exp_after:NN{#2}} -} -\def_long_new:NNn \tlist_compare:on 2{ - \tlist_compare:xx{\exp_not:n\exp_after:NN{#1}}{\exp_not:n{#2}} -} -\def_long_new:NNn \tlist_compare:oo 2{ - \tlist_compare:xx{\exp_not:n\exp_after:NN{#1}}{\exp_not:n\exp_after:NN{#2}} -} -\def_long_new:NNn \tlist_compare:xo 2{ - \tlist_compare:xx{#1}{\exp_not:n\exp_after:NN{#2}} -} -\def_long_new:NNn \tlist_compare:ox 2{ - \tlist_compare:xx{\exp_not:n\exp_after:NN{#1}}{\exp_not:n{#2}} -} -% \end{macrocode} -% Since we have a lot of basically identical functions to define we -% define one to define the rest. Unfortunately we aren't quite set up -% to use the new \verb|\tlist_map_inline:nn| function yet. -% \begin{macrocode} -\def:Npn \tmp:w #1{ - \def_long_new:cNx {tlist_if_eq_p:#1} 2{ - \exp_not:N \if_num:w - \exp_after:NN \exp_not:N \cs:w tlist_compare:#1\cs_end:{##1}{##2} - \exp_not:n{ =\c_zero \c_true \else: \c_false \fi: } - } - \def_long_test_function_new:npx{tlist_if_eq:#1}##1##2{ - \exp_not:N \if_num:w - \exp_after:NN \exp_not:N \cs:w tlist_compare:#1\cs_end:{##1}{##2} - \exp_not:n{ =\c_zero } - } -} -\tmp:w{xx} \tmp:w{nn} \tmp:w{oo} \tmp:w{xn} \tmp:w{nx} -\tmp:w{on} \tmp:w{no} \tmp:w{xo} \tmp:w{ox} -% \end{macrocode} -% However all of this only makes sense if we actually have that -% primitive. Therefore we disable it again if it is not there and -% define \verb|\tlist_if_eq:nn| the old fashioned (and unexpandable) -% way. -% \begin{macrocode} -\cs_if_really_free:cT{pdf_strcmp:D}{ - \def_long_test_function:npn{tlist_if_eq:nn}#1#2{ - \tlp_set:Nx \l_testa_tlp {\exp_not:n{#1}} - \tlp_set:Nx \l_testb_tlp {\exp_not:n{#2}} - \if_meaning:NN\l_testa_tlp \l_testb_tlp - } - \def_long_test_function:npn{tlist_if_eq:no}#1#2{ - \tlp_set:Nx \l_testa_tlp {\exp_not:n{#1}} - \tlp_set:Nx \l_testb_tlp {\exp_not:o{#2}} - \if_meaning:NN\l_testa_tlp \l_testb_tlp - } - \def_long_test_function:npn{tlist_if_eq:nx}#1#2{ - \tlp_set:Nx \l_testa_tlp {\exp_not:n{#1}} - \tlp_set:Nx \l_testb_tlp {#2} - \if_meaning:NN\l_testa_tlp \l_testb_tlp - } - \def_long_test_function:npn{tlist_if_eq:on}#1#2{ - \tlp_set:Nx \l_testa_tlp {\exp_not:o{#1}} - \tlp_set:Nx \l_testb_tlp {\exp_not:n{#2}} - \if_meaning:NN\l_testa_tlp \l_testb_tlp - } - \def_long_test_function:npn{tlist_if_eq:oo}#1#2{ - \tlp_set:Nx \l_testa_tlp {\exp_not:o{#1}} - \tlp_set:Nx \l_testb_tlp {\exp_not:o{#2}} - \if_meaning:NN\l_testa_tlp \l_testb_tlp - } - \def_long_test_function:npn{tlist_if_eq:ox}#1#2{ - \tlp_set:Nx \l_testa_tlp {\exp_not:o{#1}} - \tlp_set:Nx \l_testb_tlp {#2} - \if_meaning:NN\l_testa_tlp \l_testb_tlp - } - \def_long_test_function:npn{tlist_if_eq:xn}#1#2{ - \tlp_set:Nx \l_testa_tlp {#1} - \tlp_set:Nx \l_testb_tlp {\exp_not:n{#2}} - \if_meaning:NN\l_testa_tlp \l_testb_tlp - } - \def_long_test_function:npn{tlist_if_eq:xo}#1#2{ - \tlp_set:Nx \l_testa_tlp {#1} - \tlp_set:Nx \l_testb_tlp {\exp_not:o{#2}} - \if_meaning:NN\l_testa_tlp \l_testb_tlp - } - \def_long_test_function:npn{tlist_if_eq:xx}#1#2{ - \tlp_set:Nx \l_testa_tlp {#1} - \tlp_set:Nx \l_testb_tlp {#2} - \if_meaning:NN\l_testa_tlp \l_testb_tlp - } -} -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% -% -% -% -% \subsubsection{Checking for and replacing tokens} -% -% \begin{macro}{\tlp_if_in:NnTF} -% \begin{macro}{\tlp_if_in:cnTF} -% \begin{macro}{\tlp_if_in:NnT} -% \begin{macro}{\tlp_if_in:cnT} -% \begin{macro}{\tlp_if_in:NnF} -% \begin{macro}{\tlp_if_in:cnF} -% \begin{macro}{\tlist_if_in:nnTF} -% \begin{macro}{\tlist_if_in:onTF} -% See the replace functions for further comments. In this part we -% don't care too much about brace stripping since we are not -% interested in passing on the tokens which are split off in the -% process. -% \begin{macrocode} -\def_long:Npn \tlp_if_in:NnTF #1#2{ - \def_long:Npn\tmp:w ##1 #2 ##2\q_stop{ - \quark_if_no_value:nFT{##2} - } - \exp_after:NN \tmp:w #1 #2 \q_no_value \q_stop -} -\def_new:Npn \tlp_if_in:cnTF {\exp_args:Nc\tlp_if_in:NnTF} -\def_long:Npn \tlp_if_in:NnT #1#2{ - \def_long:Npn\tmp:w ##1 #2 ##2\q_stop{ - \quark_if_no_value:nF{##2} - } - \exp_after:NN \tmp:w #1 #2 \q_no_value \q_stop -} -\def_new:Npn \tlp_if_in:cnT {\exp_args:Nc\tlp_if_in:NnT} -\def_long:Npn \tlp_if_in:NnF #1#2{ - \def_long:Npn\tmp:w ##1 #2 ##2\q_stop{ - \quark_if_no_value:nT{##2} - } - \exp_after:NN \tmp:w #1 #2 \q_no_value \q_stop -} -\def_new:Npn \tlp_if_in:cnF {\exp_args:Nc\tlp_if_in:NnF} -\def_long_new:Npn \tlist_if_in:nnTF #1#2{ - \def_long:Npn\tmp:w ##1 #2 ##2\q_stop{ - \quark_if_no_value:nFT{##2} - } - \tmp:w #1 #2 \q_no_value \q_stop -} -\def_new:Npn \tlist_if_in:onTF {\exp_args:No\tlist_if_in:nnTF} -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\l_tlp_replace_tlp} -% A temp variable for the replace operations. -% \begin{macrocode} -\tlp_new:Nn\l_tlp_replace_tlp{} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\tlp_replace_in:Nnn} -% \begin{macro}{\tlp_replace_in:cnn} -% \begin{macro}{\tlp_greplace_in:Nnn} -% \begin{macro}{\tlp_greplace_in:cnn} -% \begin{macro}{\tlp_replace_in_aux:NNnn} -% Replacing the first item in a token list pointer goes like this: -% Define a temporary function with delimited arguments containing -% the search term and take a closer look at what is left. We append -% the expansion of the tlp with the search term plus the quark -% |\q_no_value|. If the search term isn't present this last one is -% found and the following token is the quark, so we test for -% that. If the search term is present we will have to split off the -% |#3\q_no_value| we had, so we define yet another function with -% delimited arguments to do this. The advantage here is that now we -% have a special end sequence so there is no problem if the search -% term appears more than once. Only problem left is to prevent brace -% stripping in both ends, so we prepend the expansion of the tlp -% with |\q_mark| later to be gobbled and also prepend the remainder -% of the first split operation with |\q_mark| also to be gobbled -% again later on. -% \begin{macrocode} -\def_long_new:NNn \tlp_replace_in_aux:NNnn 4{ - \def_long:Npn \tmp:w ##1#3##2\q_stop{ - \quark_if_no_value:nF{##2} - { -% \end{macrocode} -% At this point |##1| starts with a |\q_mark| so remove it. -% \begin{macrocode} - \tlp_set:Nx\l_tlp_replace_tlp{\exp_not:o{\use_none:n##1#4}} - \def_long:Npn \tmp:w ####1#3\q_no_value{ - \tlp_put_right:Nx \l_tlp_replace_tlp {\exp_not:o{\use_none:n ####1}} - } - \tmp:w \q_mark ##2 - } -% \end{macrocode} -% Now all that is done is setting the token list pointer equal to the -% expansion of the token register. -% \begin{macrocode} - #1#2\l_tlp_replace_tlp - } -% \end{macrocode} -% Here is where we start the process. Note that the tlp might start -% with a space token so we use this little trick with |\use_arg_i:n| -% to prevent it from being removed. -% \begin{macrocode} - \use_arg_i:n{\exp_after:NN \tmp:w\exp_after:NN\q_mark} - #2#3 \q_no_value\q_stop -} -% \end{macrocode} -% Now the various versions doing the replacement either globally or -% locally. -% \begin{macrocode} -\def_new:Npn \tlp_replace_in:Nnn {\tlp_replace_in_aux:NNnn \tlp_set_eq:NN} -\def_new:Npn \tlp_replace_in:cnn{\exp_args:Nc\tlp_replace_in:Nnn} -\def_new:Npn \tlp_greplace_in:Nnn {\tlp_replace_in_aux:NNnn \tlp_gset_eq:NN} -\def_new:Npn \tlp_greplace_in:cnn{\exp_args:Nc\tlp_greplace_in:Nnn} -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\tlp_replace_all_in:Nnn} -% \begin{macro}{\tlp_greplace_all_in:cnn} -% \begin{macro}{\tlp_replace_all_in:Nnn} -% \begin{macro}{\tlp_greplace_all_in:cnn} -% \begin{macro}{\tlp_replace_all_in_aux:NNnn} -% The version for replacing \emph{all} occurrences of the search -% term is fairly easy since we just have to keep doing the -% replacement on the split-off part until all are -% replaced. Otherwise it is pretty much the same as above. -% \begin{macrocode} -\def_long:NNn \tlp_replace_all_in_aux:NNnn 4{ - \tlp_clear:N \l_tlp_replace_tlp - \def_long:Npn \tmp:w ##1#3##2\q_stop{ - \quark_if_no_value:nTF{##2} - { - \tlp_put_right:Nx \l_tlp_replace_tlp {\exp_not:o{\use_none:n##1}} - } - { - \tlp_put_right:Nx \l_tlp_replace_tlp {\exp_not:o{\use_none:n##1 #4}} - \tmp:w \q_mark##2 \q_stop - } - } - \use_arg_i:n{\exp_after:NN \tmp:w\exp_after:NN\q_mark} - #2#3 \q_no_value\q_stop - #1#2\l_tlp_replace_tlp -} -% \end{macrocode} -% Now the various forms. -% \begin{macrocode} -\def_new:Npn \tlp_replace_all_in:Nnn { - \tlp_replace_all_in_aux:NNnn \tlp_set_eq:NN} -\def_new:Npn \tlp_replace_all_in:cnn{\exp_args:Nc\tlp_replace_all_in:Nnn} -\def_new:Npn \tlp_greplace_all_in:Nnn { - \tlp_replace_all_in_aux:NNnn \tlp_gset_eq:NN} -\def_new:Npn \tlp_greplace_all_in:cnn{\exp_args:Nc\tlp_greplace_all_in:Nnn} -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% -% -% -% \begin{macro}{\tlp_remove_in:Nn} -% \begin{macro}{\tlp_remove_in:cn} -% \begin{macro}{\tlp_gremove_in:Nn} -% \begin{macro}{\tlp_gremove_in:cn} -% Next comes a series of removal functions. I have just implemented -% them as subcases of the replace functions for now (I'm lazy). -% \begin{macrocode} -\def_long_new:NNn \tlp_remove_in:Nn 2{\tlp_replace_in:Nnn #1{#2}{}} -\def_long_new:NNn \tlp_gremove_in:Nn 2{\tlp_greplace_in:Nnn #1{#2}{}} -\def_new:Npn \tlp_remove_in:cn{\exp_args:Nc\tlp_remove_in:Nn} -\def_new:Npn \tlp_gremove_in:cn{\exp_args:Nc\tlp_gremove_in:Nn} -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% -% -% \begin{macro}{\tlp_remove_all_in:Nn} -% \begin{macro}{\tlp_remove_all_in:Nn} -% \begin{macro}{\tlp_gremove_all_in:Nn} -% \begin{macro}{\tlp_gremove_all_in:Nn} -% Same old, same old. -% \begin{macrocode} -\def_long_new:Npn \tlp_remove_all_in:Nn #1#2{ - \tlp_replace_all_in:Nnn #1{#2}{} -} -\def_long_new:Npn \tlp_gremove_all_in:Nn #1#2{ - \tlp_greplace_all_in:Nnn #1{#2}{} -} -\def_new:Npn \tlp_remove_all_in:cn{\exp_args:Nc\tlp_remove_all_in:Nn} -\def_new:Npn \tlp_gremove_all_in:cn{\exp_args:Nc\tlp_gremove_all_in:Nn} -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% -% -% \subsubsection{Heads or tails?} -% -% \begin{macro}{\tlist_head:n} -% \begin{macro}{\tlist_head_i:n} -% \begin{macro}{\tlist_tail:n} -% \begin{macro}{\tlist_tail:f} -% \begin{macro}{\tlist_head_iii:n} -% \begin{macro}{\tlist_head_iii:f} -% \begin{macro}{\tlist_head:w} -% \begin{macro}{\tlist_tail:w} -% \begin{macro}{\tlist_head_iii:w} -% These functions pick up either the head or the tail of a list. -% "\tlist_head_iii:n" returns the first three items on a list. -% \begin{macrocode} -\def_long_new:Npn \tlist_head:n #1{\tlist_head:w #1\q_nil} -\let_new:NN \tlist_head_i:n \tlist_head:n -\def_long_new:Npn \tlist_tail:n #1{\tlist_tail:w #1\q_nil} -\def_new:Npn \tlist_tail:f {\exp_args:Nf \tlist_tail:n} -\def_long_new:Npn \tlist_head_iii:n #1{\tlist_head_iii:w #1\q_nil} -\def_new:Npn \tlist_head_iii:f {\exp_args:Nf \tlist_head_iii:n} -\let_new:NN \tlist_head:w \use_arg_i_delimit_by_q_nil:nw -\def_long_new:Npn \tlist_tail:w #1#2\q_nil{#2} -\def_long_new:Npn \tlist_head_iii:w #1#2#3#4\q_nil{#1#2#3} -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\tlist_if_head_eq_meaning_p:nN} -% \begin{macro}{\tlist_if_head_eq_meaning:nNTF} -% \begin{macro}{\tlist_if_head_eq_meaning:nNT} -% \begin{macro}{\tlist_if_head_eq_meaning:nNF} -% \begin{macro}{\tlist_if_head_eq_charcode_p:nNTF} -% \begin{macro}{\tlist_if_head_eq_charcode:nNTF} -% \begin{macro}{\tlist_if_head_eq_charcode:nNT} -% \begin{macro}{\tlist_if_head_eq_charcode:nNF} -% \begin{macro}{\tlist_if_head_eq_catcode_p:nNTF} -% \begin{macro}{\tlist_if_head_eq_catcode:nNTF} -% \begin{macro}{\tlist_if_head_eq_catcode:nNT} -% \begin{macro}{\tlist_if_head_eq_catcode:nNF} -% When we want to check if the first token of a list equals something -% specific it is usually either to see if it is a control sequence or -% a character. Hence we make two different functions as the internal -% test is different. -% |\tlist_if_head_meaning_eq:nNTF| uses |\if_meaning:NN| and will -% consider the tokens |b|$\sb{11}$ and |b|$\sb{12}$ different. -% |\tlist_if_head_char_eq:nNTF| on the other hand only compares -% character codes so would regard |b|$\sb{11}$ and |b|$\sb{12}$ as -% equal but would also regard two primitives as equal. -% \begin{macrocode} -\def_long_new:Npn \tlist_if_head_eq_meaning_p:nN #1#2{ - \exp_after:NN \if_meaning:NN \tlist_head:w #1\q_nil#2 - \c_true - \else: - \c_false - \fi: -} -\def_long_test_function_new:npn {tlist_if_head_eq_meaning:nN}#1#2{ - \if:w \tlist_if_head_eq_meaning_p:nN{#1}#2} -% \end{macrocode} -% For the charcode and catcode versions we insert |\exp_not:N| in -% front of both tokens. If you need them to expand fully as \TeX{} -% does itself with these you can use an |f| type expansion. -% \begin{macrocode} -\def_long_new:Npn \tlist_if_head_eq_charcode_p:nN #1#2{ - \exp_after:NN\if_charcode:w \exp_after:NN\exp_not:N - \tlist_head:w #1\q_nil\exp_not:N#2 - \c_true - \else: - \c_false - \fi: -} -\def_long_test_function_new:npn {tlist_if_head_eq_charcode:nN}#1#2{ - \if:w\tlist_if_head_eq_charcode_p:nN{#1}#2} -% \end{macrocode} -% Actually the default is already an |f| type expansion. -% \begin{macrocode} -\def_long_new:Npn \tlist_if_head_eq_charcode_p:fN #1#2{ - \exp_after:NN\if_charcode:w \tlist_head:w #1\q_nil\exp_not:N#2 - \c_true - \else: - \c_false - \fi: -} -\def_long_test_function_new:npn {tlist_if_head_eq_charcode:fN}#1#2{ - \if:w\tlist_if_head_eq_charcode_p:fN{#1}#2} -\def_long_new:Npn \tlist_if_head_eq_catcode_p:nN #1#2{ - \exp_after:NN\if_charcode:w \exp_after:NN\exp_not:N - \tlist_head:w #1\q_nil\exp_not:N#2 - \c_true - \else: - \c_false - \fi: -} -\def_long_test_function_new:npn {tlist_if_head_eq_catcode:nN}#1#2{ - \if:w\tlist_if_head_eq_catcode_p:nN{#1}#2} -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% -% -% \begin{macro}{\tlist_reverse:n} -% \begin{macro}{\tlist_reverse_aux:nN} -% Reversal of a token list is done by taking one token at a time -% and putting it in front of the ones before it. -% \begin{macrocode} -\def_long_new:Npn \tlist_reverse:n #1{ - \tlist_reverse_aux:nN {} #1 \q_recursion_tail\q_recursion_stop -} -\def_long_new:Npn \tlist_reverse_aux:nN #1#2{ - \quark_if_recursion_tail_stop_do:nn {#2}{ #1 } - \tlist_reverse_aux:nN {#2#1} -} -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% -% -% As this package relies heavily on a lot of the expansion tricks used -% in \textsf{l3expan} we make sure to load it automatically at the end -% when used as a package. Probably not needed but I'm just such a nice -% guy\dots -% \begin{macrocode} -%<package>\RequirePackage{l3expan} -%<package>\RequirePackage{l3num}\par -% \end{macrocode} -% Show token usage: -% \begin{macrocode} -%</initex|package> -%<*showmemory> -\showMemUsage -%</showmemory> -% \end{macrocode} -% -% \endinput -% -% $Log$ -% Revision 1.28 2006/07/30 15:51:53 morten -% Made \tlist_map_inline:nn and variants nestable. Reimplemented -% \tlp_if_in:..., \tlp_replace_in:..., \tlp_replace_all_in:... -% -% Revision 1.27 2006/07/25 15:32:48 morten -% More \tlist_if_blank functions -% -% Revision 1.26 2006/07/06 14:58:50 morten -% Documentation touch-ups. Added more functions plus some new comparison -% functions which are dependent on a reasonably new pdfTeX. -% -% Revision 1.25 2006/06/05 14:55:14 morten -% Function for reversing a list of tokens. -% -% Revision 1.24 2006/06/03 16:31:19 morten -% Another version of \tlist_head... -% -% Revision 1.23 2006/03/20 18:26:41 braams -% Updated the copyright notice (2006) and demoted all implementation -% sections to subsections and so on to clean up the toc for source3.tex -% -% Revision 1.22 2006/01/26 14:00:42 morten -% Added a few missing functions (that were documented to be there!) -% -% Revision 1.21 2006/01/19 22:27:08 morten -% Added \tlp_replace_ and \tlp_remove_if_in functions. -% -% Revision 1.20 2006/01/17 23:07:06 morten -% Added "if_in" functions. -% -% Revision 1.19 2005/12/27 10:09:07 morten -% Changed RCS information retrieval, imported all tlist functions since -% half of them dealt with token list pointers anyway -% -% Revision 1.18 2005/07/25 19:50:40 morten -% Fixed the \long-ness aspects. -% -% Revision 1.17 2005/04/12 16:43:03 morten -% Minor updates -% -% Revision 1.16 2005/04/12 12:10:28 morten -% Rearranged and cleaned up code to avoid much doubling. -% -% Revision 1.15 2005/04/06 21:34:07 morten -% Fixed all tlp_set:XX so that they're \long. Added \tlp_set:Nf -% -% Revision 1.14 2005/03/22 23:20:43 morten -% Fixed \long versions according to Benjamin's suggestions. Slightly reorganized. -% -% Revision 1.13 2005/03/16 22:35:41 braams -% Added the tweaks necessary to be able to load with initex -% -% Revision 1.12 2005/03/11 21:43:58 braams -% Fixed the use of RCS information; -% Fixed a documentation typo -% diff --git a/Master/texmf-dist/source/latex/expl3/l3token.dtx b/Master/texmf-dist/source/latex/expl3/l3token.dtx index 1df1e08240d..7d0e3110d60 100644 --- a/Master/texmf-dist/source/latex/expl3/l3token.dtx +++ b/Master/texmf-dist/source/latex/expl3/l3token.dtx @@ -1,5 +1,5 @@ % \iffalse -%% File: l3token.dtx Copyright (C) 2005-2006 LaTeX3 project +%% File: l3token.dtx Copyright (C) 2005-2009 LaTeX3 project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this @@ -17,7 +17,7 @@ %% %% The development version of the bundle can be found at %% -%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/ +%% http://www.latex-project.org/svnroot/experimental/trunk/ %% %% for those people who are interested. %% @@ -35,7 +35,7 @@ \RequirePackage{l3names} %</driver|package> %\fi -\GetIdInfo$Id: l3token.dtx 701 2007-11-27 14:21:05Z morten $ +\GetIdInfo$Id: l3token.dtx 1365 2009-05-31 17:26:17Z mittelba $ {L3 Experimental token investigation and manipulation} %\iffalse %<*driver> @@ -43,7 +43,7 @@ \ProvidesFile{\filename.\filenameext} [\filedate\space v\fileversion\space\filedescription] %\iffalse -\documentclass{l3doc} +\documentclass[full]{l3doc} \begin{document} \DocInput{\filename.\filenameext} \end{document} @@ -53,13 +53,12 @@ % \title{The \textsf{l3token} package\thanks{This file % has version number \fileversion, last % revised \filedate.}\\ -% Basic Definitions} +% A token of my appreciation\dots} % \author{\Team} % \date{\filedate} % \maketitle % -% -% \section{A token of my appreciation\dots} +% \begin{documentation} % % This module deals with tokens. Now this is perhaps not the most % precise description so let's try with a better description: When @@ -79,16 +78,12 @@ % time the function we're describing can equally well by used on a % control sequence as such one is one token as well. % -% % We shall refer to list of tokens as |tlist|s and such lists -% represented py a single control sequence is a `token list pointer' -% |tlp|. Functions for these two types are found in the \textsf{l3tlp} +% represented by a single control sequence is a `token list variable' +% |tl var|. Functions for these two types are found in the \textsf{l3tl} % module. % -% \subsection{Character tokens} -% -% Setting category codes of characters. -% +% \section{Character tokens} % % \begin{function}{ % \char_set_catcode:nn | @@ -99,22 +94,78 @@ % \char_show_value_catcode:w % } % \begin{syntax} -% "\char_set_catcode:nn" "{"<char>"}" "{"<number>"}"\\ +% "\char_set_catcode:nn" \Arg{char number} \Arg{number}\\ % "\char_set_catcode:w" <char> = <number> \\ -% "\char_value_catcode:n" "{"<char>"}" \\ -% "\char_show_value_catcode:n" "{"<char>"}" +% "\char_value_catcode:n" \Arg{char number} \\ +% "\char_show_value_catcode:n" \Arg{char number} % \end{syntax} % "\char_set_catcode:nn" sets the category code of a character, % "\char_value_catcode:n" returns its value for use in integer tests -% and "\char_show_value_catcode:n" prints the value on the terminal -% and in the log file. The ":w" should be avoided unless you have to -% fiddle with the catcode of "{" or "}". +% and "\char_show_value_catcode:n" pausing the typesetting and prints +% the value on the terminal and in the log file. +% The ":w" form should be avoided. +% (Will: should we then just not mention it?) +% +% "\char_set_catcode" is more usefully abstracted below. % \begin{texnote} % "\char_set_catcode:w" is the \TeX\ primitive \tn{catcode} renamed. % \end{texnote} % \end{function} % % \begin{function}{ +% \char_make_escape:n | +% \char_make_begin_group:n | +% \char_make_end_group:n | +% \char_make_math_shift:n | +% \char_make_alignment:n | +% \char_make_end_line:n | +% \char_make_parameter:n | +% \char_make_math_superscript:n | +% \char_make_math_subscript:n | +% \char_make_ignore:n | +% \char_make_space:n | +% \char_make_letter:n | +% \char_make_other:n | +% \char_make_active:n | +% \char_make_comment:n | +% \char_make_invalid:n } +% \begin{syntax} +% "\char_make_letter:n" \Arg{character number} +% "\char_make_letter:n {64}" +% "\char_make_letter:n {`\@}" +% \end{syntax} +% Sets the catcode of the character referred to by its <character number>. +% \end{function} +% +% \begin{function}{ +% \char_make_escape:N | +% \char_make_begin_group:N | +% \char_make_end_group:N | +% \char_make_math_shift:N | +% \char_make_alignment:N | +% \char_make_end_line:N | +% \char_make_parameter:N | +% \char_make_math_superscript:N | +% \char_make_math_subscript:N | +% \char_make_ignore:N | +% \char_make_space:N | +% \char_make_letter:N | +% \char_make_other:N | +% \char_make_active:N | +% \char_make_comment:N | +% \char_make_invalid:N } +% \begin{syntax} +% "\char_make_letter:N" \Arg{character} +% "\char_make_letter:N" "@" +% "\char_make_letter:N" "\%" +% \end{syntax} +% Sets the catcode of the <character>, which may have to be escaped. +% \begin{texnote} +% "\char_make_other:N" is \LaTeXe's "\@makeother". +% \end{texnote} +% \end{function} +% +% \begin{function}{ % \char_set_lccode:nn | % \char_set_lccode:w | % \char_value_lccode:n | @@ -123,13 +174,13 @@ % \char_show_value_lccode:w % } % \begin{syntax} -% "\char_set_lccode:nn" "{"<char>"}" "{"<number>"}" \\ +% "\char_set_lccode:nn" \Arg{char} \Arg{number} \\ % "\char_set_lccode:w" <char> = <number> \\ -% "\char_value_lccode:n" "{"<char>"}"\\ -% "\char_show_value_lccode:n" "{"<char>"}" +% "\char_value_lccode:n" \Arg{char}\\ +% "\char_show_value_lccode:n" \Arg{char} % \end{syntax} % Set the lower caser representation of <char> for when <char> is -% being converted in "\tlist_to_lowercase:n". As above, the +% being converted in "\tl_to_lowercase:n". As above, the % ":w" form is only for people who really, really know what they are % doing. % \begin{texnote} @@ -146,13 +197,13 @@ % \char_show_value_uccode:w % } % \begin{syntax} -% "\char_set_uccode:nn" "{"<char>"}" "{"<number>"}"\\ +% "\char_set_uccode:nn" \Arg{char} \Arg{number}\\ % "\char_set_uccode:w" <char> = <number> \\ -% "\char_value_uccode:n" "{"<char>"}"\\ -% "\char_show_value_uccode:n" "{"<char>"}" +% "\char_value_uccode:n" \Arg{char}\\ +% "\char_show_value_uccode:n" \Arg{char} % \end{syntax} % Set the uppercase representation of <char> for when <char> is being -% converted in "\tlist_to_uppercase:n". As above, the ":w" +% converted in "\tl_to_uppercase:n". As above, the ":w" % form is only for people who really, really know what they are % doing. % \begin{texnote} @@ -169,10 +220,10 @@ % \char_show_value_sfcode:w % } % \begin{syntax} -% "\char_set_sfcode:nn" "{"<char>"}" "{"<number>"}"\\ +% "\char_set_sfcode:nn" \Arg{char} \Arg{number}\\ % "\char_set_sfcode:w" <char> = <number> \\ -% "\char_value_sfcode:n" "{"<char>"}"\\ -% "\char_show_value_sfcode:n" "{"<char>"}" +% "\char_value_sfcode:n" \Arg{char}\\ +% "\char_show_value_sfcode:n" \Arg{char} % \end{syntax} % Set the space factor for <char>. % \begin{texnote} @@ -191,10 +242,10 @@ % \char_show_value_mathcode:w % } % \begin{syntax} -% "\char_set_mathcode:nn" "{"<char>"}" "{"<number>"}"\\ +% "\char_set_mathcode:nn" \Arg{char} \Arg{number}\\ % "\char_set_mathcode:w" <char> = <number> \\ -% "\char_value_mathcode:n" "{"<char>"}"\\ -% "\char_show_value_mathcode:n" "{"<char>"}" +% "\char_value_mathcode:n" \Arg{char}\\ +% "\char_show_value_mathcode:n" \Arg{char} % \end{syntax} % Set the math code for <char>. % \begin{texnote} @@ -203,13 +254,13 @@ % \end{function} % % -% \subsection{Generic tokens} +% \section{Generic tokens} % % \begin{function}{% % \token_new:Nn | % } % \begin{syntax} -% "\token_new:Nn" <token 1> "{"<token 2>"}" +% "\token_new:Nn" <token 1> \Arg{token 2} % \end{syntax} % Defines <token 1> to globally be a snapshot of <token 2>. This will % be an implicit representation of <token 2>. @@ -235,217 +286,178 @@ % \end{variable} % % \begin{function}{ -% \token_if_group_begin_p:N | -% \token_if_group_begin:NTF | -% \token_if_group_begin:NT | -% \token_if_group_begin:NF | +% \token_if_group_begin_p:N / (EXP) | +% \token_if_group_begin:N / (TF) (EXP) | % } % \begin{syntax} -% "\token_if_group_begin:NTF" <token> "{"<true>"}" "{"<false>"}" +% "\token_if_group_begin:NTF" <token> \Arg{true} \Arg{false} % \end{syntax} % Check if <token> is a begin group token. % \end{function} % % \begin{function}{ -% \token_if_group_end_p:N | -% \token_if_group_end:NTF | -% \token_if_group_end:NT | -% \token_if_group_end:NF | +% \token_if_group_end_p:N / (EXP) | +% \token_if_group_end:N / (TF) (EXP) | % } % \begin{syntax} -% "\token_if_group_end:NTF" <token> "{"<true>"}" "{"<false>"}" +% "\token_if_group_end:NTF" <token> \Arg{true} \Arg{false} % \end{syntax} % Check if <token> is an end group token. % \end{function} % % \begin{function}{ -% \token_if_math_shift_p:N | -% \token_if_math_shift:NTF | -% \token_if_math_shift:NT | -% \token_if_math_shift:NF | +% \token_if_math_shift_p:N / (EXP) | +% \token_if_math_shift:N / (TF) (EXP) | % } % \begin{syntax} -% "\token_if_math_shift:NTF" <token> "{"<true>"}" "{"<false>"}" +% "\token_if_math_shift:NTF" <token> \Arg{true} \Arg{false} % \end{syntax} % Check if <token> is a math shift token. % \end{function} % % % \begin{function}{ -% \token_if_aligment_tab_p:N | -% \token_if_aligment_tab:NTF | -% \token_if_aligment_tab:NT | -% \token_if_aligment_tab:NF | +% \token_if_alignment_tab_p:N / (EXP) | +% \token_if_alignment_tab:N / (TF) (EXP) | % } % \begin{syntax} -% "\token_if_aligment_tab:NTF" <token> "{"<true>"}" "{"<false>"}" +% "\token_if_aligment_tab:NTF" <token> \Arg{true} \Arg{false} % \end{syntax} % Check if <token> is an aligment tab token. % \end{function} % % \begin{function}{ -% \token_if_parameter_p:N | -% \token_if_parameter:NTF | -% \token_if_parameter:NT | -% \token_if_parameter:NF | +% \token_if_parameter_p:N / (EXP) | +% \token_if_parameter:N / (TF) (EXP) | % } % \begin{syntax} -% "\token_if_parameter:NTF" <token> "{"<true>"}" "{"<false>"}" +% "\token_if_parameter:NTF" <token> \Arg{true} \Arg{false} % \end{syntax} % Check if <token> is a parameter token. % \end{function} % % \begin{function}{ -% \token_if_math_superscript_p:N | -% \token_if_math_superscript:NTF | -% \token_if_math_superscript:NT | -% \token_if_math_superscript:NF | +% \token_if_math_superscript_p:N / (EXP) | +% \token_if_math_superscript:N / (TF) (EXP) | % } % \begin{syntax} -% "\token_if_math_superscript:NTF" <token> "{"<true>"}" "{"<false>"}" +% "\token_if_math_superscript:NTF" <token> \Arg{true} \Arg{false} % \end{syntax} % Check if <token> is a math superscript token. % \end{function} % % \begin{function}{ -% \token_if_math_subscript_p:N | -% \token_if_math_subscript:NTF | -% \token_if_math_subscript:NT | -% \token_if_math_subscript:NF | +% \token_if_math_subscript_p:N / (EXP) | +% \token_if_math_subscript:N / (TF) (EXP) | % } % \begin{syntax} -% "\token_if_math_subscript:NTF" <token> "{"<true>"}" "{"<false>"}" +% "\token_if_math_subscript:NTF" <token> \Arg{true} \Arg{false} % \end{syntax} % Check if <token> is a math subscript token. % \end{function} % % \begin{function}{ -% \token_if_space_p:N | -% \token_if_space:NTF | -% \token_if_space:NT | -% \token_if_space:NF | +% \token_if_space_p:N / (EXP) | +% \token_if_space:N / (TF) (EXP) | % } % \begin{syntax} -% "\token_if_space:NTF" <token> "{"<true>"}" "{"<false>"}" +% "\token_if_space:NTF" <token> \Arg{true} \Arg{false} % \end{syntax} % Check if <token> is a space token. % \end{function} % % % \begin{function}{ -% \token_if_letter_p:N | -% \token_if_letter:NTF | -% \token_if_letter:NT | -% \token_if_letter:NF | +% \token_if_letter_p:N / (EXP) | +% \token_if_letter:N / (TF) (EXP) | % } % \begin{syntax} -% "\token_if_letter:NTF" <token> "{"<true>"}" "{"<false>"}" +% "\token_if_letter:NTF" <token> \Arg{true} \Arg{false} % \end{syntax} % Check if <token> is a letter token. % \end{function} % % % \begin{function}{ -% \token_if_other_char_p:N | -% \token_if_other_char:NTF | -% \token_if_other_char:NT | -% \token_if_other_char:NF | +% \token_if_other_char_p:N / (EXP) | +% \token_if_other_char:N / (TF) (EXP) | % } % \begin{syntax} -% "\token_if_other_char:NTF" <token> "{"<true>"}" "{"<false>"}" +% "\token_if_other_char:NTF" <token> \Arg{true} \Arg{false} % \end{syntax} % Check if <token> is an other char token. % \end{function} % % \begin{function}{ -% \token_if_active_char_p:N | -% \token_if_active_char:NTF | -% \token_if_active_char:NT | -% \token_if_active_char:NF | +% \token_if_active_char_p:N / (EXP) | +% \token_if_active_char:N / (TF) (EXP) | % } % \begin{syntax} -% "\token_if_active_char:NTF" <token> "{"<true>"}" "{"<false>"}" +% "\token_if_active_char:NTF" <token> \Arg{true} \Arg{false} % \end{syntax} % Check if <token> is an active char token. % \end{function} % -% % \begin{function}{% -% \token_if_eq_meaning_p:NN | -% \token_if_eq_meaning:NNTF | -% \token_if_eq_meaning:NNT | -% \token_if_eq_meaning:NNF +% \token_if_eq_meaning_p:NN / (EXP) | +% \token_if_eq_meaning:NN / (TF) (EXP) % } % \begin{syntax} -% "\token_if_eq_meaning:NNTF" <token1> <token2>"{"<true>"}""{"<false>"}" +% "\token_if_eq_meaning:NNTF" <token1> <token2>\Arg{true} \Arg{false} % \end{syntax} % Check if the meaning of two tokens are identical. % \end{function} % % \begin{function}{% -% \token_if_eq_catcode_p:NN | -% \token_if_eq_catcode:NNTF | -% \token_if_eq_catcode:NNT | -% \token_if_eq_catcode:NNF +% \token_if_eq_catcode_p:NN / (EXP) | +% \token_if_eq_catcode:NN / (TF) (EXP) % } % \begin{syntax} -% "\token_if_eq_catcode:NNTF" <token1> <token2>"{"<true>"}""{"<false>"}" +% "\token_if_eq_catcode:NNTF" <token1> <token2>\Arg{true} \Arg{false} % \end{syntax} % Check if the category codes of two tokens are equal. If both tokens % are control sequences the test will be true. % \end{function} % % \begin{function}{% -% \token_if_eq_charcode_p:NN | -% \token_if_eq_catcode:NNTF | -% \token_if_eq_catcode:NNT | -% \token_if_eq_catcode:NNF +% \token_if_eq_charcode_p:NN / (EXP) | +% \token_if_eq_charcode:NN / (TF) (EXP) % } % \begin{syntax} -% "\token_if_eq_catcode:NNTF" <token1> <token2>"{"<true>"}""{"<false>"}" +% "\token_if_eq_catcode:NNTF" <token1> <token2>\Arg{true} \Arg{false} % \end{syntax} % Check if the character codes of two tokens are equal. If both tokens % are control sequences the test will be true. % \end{function} % % \begin{function}{ -% \token_if_macro_p:N | -% \token_if_macro:NTF | -% \token_if_macro:NT | -% \token_if_macro:NF | +% \token_if_macro_p:N / (EXP) | +% \token_if_macro:N / (TF) (EXP) | % } % \begin{syntax} -% "\token_if_macro:NTF" <token> "{"<true>"}" "{"<false>"}" +% "\token_if_macro:NTF" <token> \Arg{true} \Arg{false} % \end{syntax} % Check if <token> is a macro. % \end{function} % -% % \begin{function}{ -% \token_if_cs_p:N | -% \token_if_cs:NTF | -% \token_if_cs:NT | -% \token_if_cs:NF | +% \token_if_cs_p:N / (EXP) | +% \token_if_cs:N / (TF) (EXP) | % } % \begin{syntax} -% "\token_if_cs:NTF" <token> "{"<true>"}" "{"<false>"}" +% "\token_if_cs:NTF" <token> \Arg{true} \Arg{false} % \end{syntax} % Check if <token> is a control sequence or not. This can be useful % for situations where the next token in the input stream is being % looked at and you want to determine what should be done to it. % \end{function} % -% -% -% % \begin{function}{ -% \token_if_expandable_p:N | -% \token_if_expandable:NTF | -% \token_if_expandable:NT | -% \token_if_expandable:NF +% \token_if_expandable_p:N / (EXP) | +% \token_if_expandable:N / (TF) (EXP) % } % \begin{syntax} -% "\token_if_expandable:NTF" <token> "{"<true>"}" "{"<false>"}" +% "\token_if_expandable:NTF" <token> \Arg{true} \Arg{false} % \end{syntax} % Check if <token> is expandable or not. Note that <token> can very % well be an active character. @@ -460,151 +472,130 @@ % \m{toks} register at all? % % \begin{function}{ -% \token_if_long_macro_p:N | -% \token_if_long_macro:NTF | -% \token_if_long_macro:NT | -% \token_if_long_macro:NF | +% \token_if_long_macro_p:N / (EXP) | +% \token_if_long_macro:N / (TF) (EXP) | % } % \begin{syntax} -% "\token_if_long_macro:NTF" <token> "{"<true>"}" "{"<false>"}" +% "\token_if_long_macro:NTF" <token> \Arg{true} \Arg{false} % \end{syntax} % Check if <token> is a ``long'' macro. % \end{function} % % % \begin{function}{ -% \token_if_protected_macro_p:N | -% \token_if_protected_macro:NTF | -% \token_if_protected_macro:NT | -% \token_if_protected_macro:NF | +% \token_if_protected_macro_p:N / (EXP) | +% \token_if_protected_macro:N / (TF) (EXP) | % } % \begin{syntax} -% "\token_if_long_macro:NTF" <token> "{"<true>"}" "{"<false>"}" +% "\token_if_long_macro:NTF" <token> \Arg{true} \Arg{false} % \end{syntax} % Check if <token> is a ``protected'' macro. This test does \emph{not} % return <true> if the macro is also ``long'', see below. % \end{function} % % \begin{function}{ -% \token_if_protected_long_macro_p:N | -% \token_if_protected_long_macro:NTF | -% \token_if_protected_long_macro:NT | -% \token_if_protected_long_macro:NF | +% \token_if_protected_long_macro_p:N / (EXP) | +% \token_if_protected_long_macro:N / (TF) (EXP) | % } % \begin{syntax} -% "\token_if_protected_long_macro:NTF" <token> "{"<true>"}" "{"<false>"}" +% "\token_if_protected_long_macro:NTF" <token> \Arg{true} \Arg{false} % \end{syntax} % Check if <token> is a ``protected long'' macro. % \end{function} % % \begin{function}{ -% \token_if_chardef_p:N | -% \token_if_chardef:NTF | -% \token_if_chardef:NT | -% \token_if_chardef:NF | +% \token_if_chardef_p:N / (EXP) | +% \token_if_chardef:N / (TF) (EXP) | % } % \begin{syntax} -% "\token_if_chardef:NTF" <token> "{"<true>"}" "{"<false>"}" +% "\token_if_chardef:NTF" <token> \Arg{true} \Arg{false} % \end{syntax} % Check if <token> is defined to be a chardef. % \end{function} % % \begin{function}{ -% \token_if_mathchardef_p:N | -% \token_if_mathchardef:NTF | -% \token_if_mathchardef:NT | -% \token_if_mathchardef:NF | +% \token_if_mathchardef_p:N / (EXP) | +% \token_if_mathchardef:N / (TF) (EXP) | % } % \begin{syntax} -% "\token_if_mathchardef:NTF" <token> "{"<true>"}" "{"<false>"}" +% "\token_if_mathchardef:NTF" <token> \Arg{true} \Arg{false} % \end{syntax} % Check if <token> is defined to be a mathchardef. % \end{function} % % \begin{function}{ -% \token_if_int_register_p:N | -% \token_if_int_register:NTF | -% \token_if_int_register:NT | -% \token_if_int_register:NF | +% \token_if_int_register_p:N / (EXP) | +% \token_if_int_register:N / (TF) (EXP) | % } % \begin{syntax} -% "\token_if_int_register:NTF" <token> "{"<true>"}" "{"<false>"}" +% "\token_if_int_register:NTF" <token> \Arg{true} \Arg{false} % \end{syntax} % Check if <token> is defined to be an integer register. % \end{function} % % \begin{function}{ -% \token_if_dim_register_p:N | -% \token_if_dim_register:NTF | -% \token_if_dim_register:NT | -% \token_if_dim_register:NF | +% \token_if_dim_register_p:N / (EXP) | +% \token_if_dim_register:N / (TF) (EXP) | % } % \begin{syntax} -% "\token_if_dim_register:NTF" <token> "{"<true>"}" "{"<false>"}" +% "\token_if_dim_register:NTF" <token> \Arg{true} \Arg{false} % \end{syntax} % Check if <token> is defined to be a dimension register. % \end{function} % % \begin{function}{ -% \token_if_skip_register_p:N | -% \token_if_skip_register:NTF | -% \token_if_skip_register:NT | -% \token_ifskip_register:NF | +% \token_if_skip_register_p:N / (EXP) | +% \token_if_skip_register:N / (TF) (EXP) | % } % \begin{syntax} -% "\token_if_skip_register:NTF" <token> "{"<true>"}" "{"<false>"}" +% "\token_if_skip_register:NTF" <token> \Arg{true} \Arg{false} % \end{syntax} % Check if <token> is defined to be a skip register. % \end{function} % % \begin{function}{ -% \token_if_toks_register_p:N | -% \token_if_toks_register:NTF | -% \token_if_toks_register:NT | -% \token_if_toks_register:NF | +% \token_if_toks_register_p:N / (EXP) | +% \token_if_toks_register:N / (TF) (EXP) | % } % \begin{syntax} -% "\token_if_toks_register:NTF" <token> "{"<true>"}" "{"<false>"}" +% "\token_if_toks_register:NTF" <token> \Arg{true} \Arg{false} % \end{syntax} % Check if <token> is defined to be a toks register. % \end{function} % % % \begin{function}{ -% \token_get_prefix_spec:N | -% \token_get_arg_spec:N | -% \token_get_replacement_spec:N +% \token_get_prefix_spec:N / (EXP) | +% \token_get_arg_spec:N / (EXP) | +% \token_get_replacement_spec:N / (EXP) % } % \begin{syntax} % "\token_get_arg_spec:N" <token> % \end{syntax} -% If token is a macro with definition |\def_long:Npn||\next| +% If token is a macro with definition |\cs_set:Npn||\next| % |#1#2{x`#1--#2'y}|, the |prefix| function will return the string % |\long|, the |arg| function returns the string |#1#2| and the % |replacement| function returns the string |x`#1--#2'y|. If <token> % isn't a macro, these functions return the |\scan_stop:| token. +% +% If the |arg_spec| contains the string |->|, then the |spec| function +% will produce incorrect results. % \end{function} % -% \subsubsection{Useless code: because we can!} +% \subsection{Useless code: because we can!} % % \begin{function}{ -% \token_if_primitive_p:N | -% \token_if_primitive:NTF | -% \token_if_primitive:NT | -% \token_if_primitive:NF | +% \token_if_primitive_p:N / (EXP) | +% \token_if_primitive:N / (TF) (EXP) | % } % \begin{syntax} -% "\token_if_primitive:NTF" <token> "{"<true>"}" "{"<false>"}" +% "\token_if_primitive:NTF" <token> \Arg{true} \Arg{false} % \end{syntax} % Check if <token> is a primitive. Probably not a very useful function. % \end{function} % % -% \subsection{Peeking ahead at the next token} -% -% -% -% +% \section{Peeking ahead at the next token} % % \begin{variable}{% % \l_peek_token | @@ -634,43 +625,46 @@ % \end{function} % % \begin{function}{% -% \peek_meaning:NTF | -% \peek_meaning_ignore_spaces:NTF | -% \peek_meaning_remove:NTF | -% \peek_meaning_remove_ignore_spaces:NTF +% \peek_meaning:N / (TF) | +% \peek_meaning_ignore_spaces:N / (TF) | +% \peek_meaning_remove:N / (TF) | +% \peek_meaning_remove_ignore_spaces:N / (TF) % } % \begin{syntax} -% "\peek_meaning:NTF" <token> "{"<true>"}""{"<false>"}" +% "\peek_meaning:NTF" <token> \Arg{true} \Arg{false} % \end{syntax} -% "\peek_meaning:NTF" checks (by using "\if_meaning:NN") if <token> +% "\peek_meaning:NTF" checks (by using "\if_meaning:w") if <token> % equals the next token in the input stream and executes either <true % code> or <false code> accordingly. "\peek_meaning_remove:NTF" does % the same but additionally removes the token if found. The % "ignore_spaces" versions skips blank spaces before making the % decision. +% \begin{texnote} +% This is equivalent to \LaTeXe's \tn{@ifnextchar}. +% \end{texnote} % \end{function} % % \begin{function}{% -% \peek_charcode:NTF | -% \peek_charcode_ignore_spaces:NTF | -% \peek_charcode_remove:NTF | -% \peek_charcode_remove_ignore_spaces:NTF +% \peek_charcode:N / (TF) | +% \peek_charcode_ignore_spaces:N / (TF) | +% \peek_charcode_remove:N / (TF) | +% \peek_charcode_remove_ignore_spaces:N / (TF) % } % \begin{syntax} -% "\peek_charcode:NTF" <token> "{"<true>"}""{"<false>"}" +% "\peek_charcode:NTF" <token> \Arg{true} \Arg{false} % \end{syntax} % Same as for the "\peek_meaning:NTF" functions above but these use % "\if_charcode:w" to compare the tokens. % \end{function} % % \begin{function}{% -% \peek_catcode:NTF | -% \peek_catcode_ignore_spaces:NTF | -% \peek_catcode_remove:NTF | -% \peek_catcode_remove_ignore_spaces:NTF +% \peek_catcode:N / (TF) | +% \peek_catcode_ignore_spaces:N / (TF) | +% \peek_catcode_remove:N / (TF) | +% \peek_catcode_remove_ignore_spaces:N / (TF) % } % \begin{syntax} -% "\peek_catcode:NTF" <token> "{"<true>"}""{"<false>"}" +% "\peek_catcode:NTF" <token> \Arg{true} \Arg{false} % \end{syntax} % Same as for the "\peek_meaning:NTF" functions above but these use % "\if_catcode:w" to compare the tokens. @@ -678,11 +672,11 @@ % % % \begin{function}{% -% \peek_token_generic:NNTF | -% \peek_token_remove_generic:NNTF +% \peek_token_generic:NN / (TF) | +% \peek_token_remove_generic:NN / (TF) % } % \begin{syntax} -% "\peek_token_generic:NNTF" <token><function> "{"<true>"}""{"<false>"}" +% "\peek_token_generic:NNTF" <token><function> \Arg{true} \Arg{false} % \end{syntax} % "\peek_token_generic:NNTF" looks ahead and checks if the next token % in the input stream is equal to <token>. It uses <function> to make @@ -706,219 +700,259 @@ % meaning, character code, and category code. % \end{function} % +% \end{documentation} % +% \begin{implementation} % +% \section{\pkg{l3token} implementation} % -% \subsubsection{Internal functions} -% -% \begin{variable}{% -% \l_peek_true_tlp | -% \l_peek_false_tlp | -% } -% \begin{syntax} -% \end{syntax} -% These token list pointers are used internally when choosing either -% the true or false branches of a test. -% \end{variable} -% -% \begin{function}{% -% \peek_tmp:w | -% } -% \begin{syntax} -% \end{syntax} -% Scratch function used to gobble tokens from the input stream. -% \end{function} -% -% \begin{variable}{% -% \l_peek_true_aux_tlp | -% \l_peek_true_remove_next_tlp | -% } -% \begin{syntax} -% \end{syntax} -% These token list pointers are used internally when choosing either -% the true or false branches of a test. -% \end{variable} -% -% \begin{function}{% -% \peek_ignore_spaces_execute_branches: | -% \peek_ignore_spaces_aux: | -% } -% \begin{syntax} -% \end{syntax} -% Functions used to ignore space tokens in the input stream. -% \end{function} -% -% +% \subsection{Documentation of internal functions} % -% \StopEventually{} +% \begin{variable}{% +% \l_peek_true_tl | +% \l_peek_false_tl | +% } +% \begin{syntax} +% \end{syntax} +% These token list variables are used internally when choosing either +% the true or false branches of a test. +% \end{variable} +% +% \begin{variable}{ \l_peek_search_tl } +% \begin{syntax} +% \end{syntax} +% Used to store "\l_peek_search_token". +% \end{variable} +% +% \begin{function}{% +% \peek_tmp:w | +% } +% \begin{syntax} +% \end{syntax} +% Scratch function used to gobble tokens from the input stream. +% \end{function} +% +% \begin{variable}{% +% \l_peek_true_aux_tl | +% \c_peek_true_remove_next_tl | +% } +% \begin{syntax} +% \end{syntax} +% These token list variables are used internally when choosing either +% the true or false branches of a test. +% \end{variable} +% +% \begin{function}{% +% \peek_ignore_spaces_execute_branches: | +% \peek_ignore_spaces_aux: | +% } +% \begin{syntax} +% \end{syntax} +% Functions used to ignore space tokens in the input stream. +% \end{function} % +% \subsection{Module code} % -% \subsection{Implementation} % First a few required packages to get this going. % \begin{macrocode} -%<package>\ProvidesExplPackage -%<package> {\filename}{\filedate}{\fileversion}{\filedescription} -%<package>\RequirePackage{l3prg} -%<package>\RequirePackage{l3int} +%<*package> +\ProvidesExplPackage + {\filename}{\filedate}{\fileversion}{\filedescription} +\package_check_loaded_expl: +%</package> %<*initex|package> % \end{macrocode} % -% \subsubsection{Character tokens} +% \subsection{Character tokens} % -% \begin{macro}{\char_set_catcode:w} -% \begin{macro}{\char_set_catcode:nn} -% \begin{macro}{\char_value_catcode:w} -% \begin{macro}{\char_value_catcode:n} -% \begin{macro}{\char_show_value_catcode:w} -% \begin{macro}{\char_show_value_catcode:n} +% \begin{macro}{ \char_set_catcode:w , +% \char_set_catcode:nn , +% \char_value_catcode:w , +% \char_value_catcode:n , +% \char_show_value_catcode:w , +% \char_show_value_catcode:n } % \begin{macrocode} -\let_new:NN \char_set_catcode:w \tex_catcode:D -\def_new:Npn \char_set_catcode:nn #1#2{ - \char_set_catcode:w #1 = \int_eval:n{#2} +\cs_new_eq:NN \char_set_catcode:w \tex_catcode:D +\cs_new_nopar:Npn \char_set_catcode:nn #1#2 { + \char_set_catcode:w #1 = \intexpr_eval:w #2\intexpr_eval_end: +} +\cs_new_nopar:Npn \char_value_catcode:w { \int_use:N \tex_catcode:D } +\cs_new_nopar:Npn \char_value_catcode:n #1 { + \char_value_catcode:w \intexpr_eval:w #1\intexpr_eval_end: +} +\cs_new_nopar:Npn \char_show_value_catcode:w { + \tex_showthe:D \tex_catcode:D +} +\cs_new_nopar:Npn \char_show_value_catcode:n #1 { + \char_show_value_catcode:w \intexpr_eval:w #1\intexpr_eval_end: } -\def_new:Npn \char_value_catcode:w {\int_use:N\tex_catcode:D} -\def_new:Npn \char_value_catcode:n #1{\char_value_catcode:w \int_eval:n{#1}} -\def_new:Npn \char_show_value_catcode:w {\tex_showthe:D\tex_catcode:D} -\def_new:Npn \char_show_value_catcode:n #1{ - \char_show_value_catcode:w \int_eval:n{#1}} % \end{macrocode} % \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} % -% \begin{macro}{\char_set_mathcode:w} -% \begin{macro}{\char_set_mathcode:nn} -% \begin{macro}{\char_gset_mathcode:w} -% \begin{macro}{\char_gset_mathcode:nn} -% \begin{macro}{\char_value_mathcode:w} -% \begin{macro}{\char_value_mathcode:n} -% \begin{macro}{\char_show_value_mathcode:w} -% \begin{macro}{\char_show_value_mathcode:n} +% \begin{macro}{ \char_make_escape:N , \char_make_begin_group:N , +% \char_make_end_group:N , \char_make_math_shift:N , +% \char_make_alignment:N , \char_make_end_line:N , +% \char_make_parameter:N , \char_make_math_superscript:N , +% \char_make_math_subscript:N , \char_make_ignore:N , +% \char_make_space:N , \char_make_letter:N , +% \char_make_other:N , \char_make_active:N , +% \char_make_comment:N , \char_make_invalid:N } +% \begin{macrocode} +\cs_new_nopar:Npn \char_make_escape:N #1 { \char_set_catcode:nn {`#1} {\c_zero} } +\cs_new_nopar:Npn \char_make_begin_group:N #1 { \char_set_catcode:nn {`#1} {\c_one} } +\cs_new_nopar:Npn \char_make_end_group:N #1 { \char_set_catcode:nn {`#1} {\c_two} } +\cs_new_nopar:Npn \char_make_math_shift:N #1 { \char_set_catcode:nn {`#1} {\c_three} } +\cs_new_nopar:Npn \char_make_alignment:N #1 { \char_set_catcode:nn {`#1} {\c_four} } +\cs_new_nopar:Npn \char_make_end_line:N #1 { \char_set_catcode:nn {`#1} {\c_five} } +\cs_new_nopar:Npn \char_make_parameter:N #1 { \char_set_catcode:nn {`#1} {\c_six} } +\cs_new_nopar:Npn \char_make_math_superscript:N #1 { \char_set_catcode:nn {`#1} {\c_seven} } +\cs_new_nopar:Npn \char_make_math_subscript:N #1 { \char_set_catcode:nn {`#1} {\c_eight} } +\cs_new_nopar:Npn \char_make_ignore:N #1 { \char_set_catcode:nn {`#1} {\c_nine} } +\cs_new_nopar:Npn \char_make_space:N #1 { \char_set_catcode:nn {`#1} {\c_ten} } +\cs_new_nopar:Npn \char_make_letter:N #1 { \char_set_catcode:nn {`#1} {\c_eleven} } +\cs_new_nopar:Npn \char_make_other:N #1 { \char_set_catcode:nn {`#1} {\c_twelve} } +\cs_new_nopar:Npn \char_make_active:N #1 { \char_set_catcode:nn {`#1} {\c_thirteen} } +\cs_new_nopar:Npn \char_make_comment:N #1 { \char_set_catcode:nn {`#1} {\c_fourteen} } +\cs_new_nopar:Npn \char_make_invalid:N #1 { \char_set_catcode:nn {`#1} {\c_fifteen} } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{ \char_make_escape:n , \char_make_begin_group:n , +% \char_make_end_group:n , \char_make_math_shift:n , +% \char_make_alignment:n , \char_make_end_line:n , +% \char_make_parameter:n , \char_make_math_superscript:n , +% \char_make_math_subscript:n , \char_make_ignore:n , +% \char_make_space:n , \char_make_letter:n , +% \char_make_other:n , \char_make_active:n , +% \char_make_comment:n , \char_make_invalid:n } +% \begin{macrocode} +\cs_new_nopar:Npn \char_make_escape:n #1 { \char_set_catcode:nn {#1} {\c_zero} } +\cs_new_nopar:Npn \char_make_begin_group:n #1 { \char_set_catcode:nn {#1} {\c_one} } +\cs_new_nopar:Npn \char_make_end_group:n #1 { \char_set_catcode:nn {#1} {\c_two} } +\cs_new_nopar:Npn \char_make_math_shift:n #1 { \char_set_catcode:nn {#1} {\c_three} } +\cs_new_nopar:Npn \char_make_alignment:n #1 { \char_set_catcode:nn {#1} {\c_four} } +\cs_new_nopar:Npn \char_make_end_line:n #1 { \char_set_catcode:nn {#1} {\c_five} } +\cs_new_nopar:Npn \char_make_parameter:n #1 { \char_set_catcode:nn {#1} {\c_six} } +\cs_new_nopar:Npn \char_make_math_superscript:n #1 { \char_set_catcode:nn {#1} {\c_seven} } +\cs_new_nopar:Npn \char_make_math_subscript:n #1 { \char_set_catcode:nn {#1} {\c_eight} } +\cs_new_nopar:Npn \char_make_ignore:n #1 { \char_set_catcode:nn {#1} {\c_nine} } +\cs_new_nopar:Npn \char_make_space:n #1 { \char_set_catcode:nn {#1} {\c_ten} } +\cs_new_nopar:Npn \char_make_letter:n #1 { \char_set_catcode:nn {#1} {\c_eleven} } +\cs_new_nopar:Npn \char_make_other:n #1 { \char_set_catcode:nn {#1} {\c_twelve} } +\cs_new_nopar:Npn \char_make_active:n #1 { \char_set_catcode:nn {#1} {\c_thirteen} } +\cs_new_nopar:Npn \char_make_comment:n #1 { \char_set_catcode:nn {#1} {\c_fourteen} } +\cs_new_nopar:Npn \char_make_invalid:n #1 { \char_set_catcode:nn {#1} {\c_fifteen} } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\char_set_mathcode:w, +% \char_set_mathcode:nn, +% \char_gset_mathcode:w, +% \char_gset_mathcode:nn, +% \char_value_mathcode:w, +% \char_value_mathcode:n, +% \char_show_value_mathcode:w, +% \char_show_value_mathcode:n} % Math codes. % \begin{macrocode} -\let_new:NN \char_set_mathcode:w \tex_mathcode:D -\def_new:Npn \char_set_mathcode:nn #1#2{ - \char_set_mathcode:w #1 = \int_eval:n{#2} +\cs_new_eq:NN \char_set_mathcode:w \tex_mathcode:D +\cs_new_nopar:Npn \char_set_mathcode:nn #1#2 { + \char_set_mathcode:w #1 = \intexpr_eval:w #2\intexpr_eval_end: +} +\cs_new_protected_nopar:Npn \char_gset_mathcode:w { \pref_global:D \tex_mathcode:D } +\cs_new_nopar:Npn \char_gset_mathcode:nn #1#2 { + \char_gset_mathcode:w #1 = \intexpr_eval:w #2\intexpr_eval_end: } -\def_protected_new:Npn \char_gset_mathcode:w {\pref_global:D\tex_mathcode:D} -\def_new:Npn \char_gset_mathcode:nn #1#2{ - \char_gset_mathcode:w #1 = \int_eval:n{#2} +\cs_new_nopar:Npn \char_value_mathcode:w { \int_use:N \tex_mathcode:D } +\cs_new_nopar:Npn \char_value_mathcode:n #1 { + \char_value_mathcode:w \intexpr_eval:w #1\intexpr_eval_end: +} +\cs_new_nopar:Npn \char_show_value_mathcode:w { \tex_showthe:D \tex_mathcode:D } +\cs_new_nopar:Npn \char_show_value_mathcode:n #1 { + \char_show_value_mathcode:w \intexpr_eval:w #1\intexpr_eval_end: } -\def_new:Npn \char_value_mathcode:w {\int_use:N\tex_mathcode:D} -\def_new:Npn \char_value_mathcode:n #1{\char_value_mathcode:w \int_eval:n{#1}} -\def_new:Npn \char_show_value_mathcode:w {\tex_showthe:D\tex_mathcode:D} -\def_new:Npn \char_show_value_mathcode:n #1{ - \char_show_value_mathcode:w \int_eval:n{#1}} % \end{macrocode} % \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} % -% \begin{macro}{\char_set_lccode:w} -% \begin{macro}{\char_set_lccode:nn} -% \begin{macro}{\char_value_lccode:w} -% \begin{macro}{\char_value_lccode:n} -% \begin{macro}{\char_show_value_lccode:w} -% \begin{macro}{\char_show_value_lccode:n} +% \begin{macro}{\char_set_lccode:w, \char_set_lccode:nn, +% \char_value_lccode:w, \char_value_lccode:n, +% \char_show_value_lccode:w, \char_show_value_lccode:n} % \begin{macrocode} -\let_new:NN \char_set_lccode:w \tex_lccode:D -\def_new:Npn \char_set_lccode:nn #1#2{ - \char_set_lccode:w #1 = \int_eval:n{#2} +\cs_new_eq:NN \char_set_lccode:w \tex_lccode:D +\cs_new_nopar:Npn \char_set_lccode:nn #1#2{ + \char_set_lccode:w #1 = \intexpr_eval:w #2\intexpr_eval_end: } -\def_new:Npn \char_value_lccode:w {\int_use:N\tex_lccode:D} -\def_new:Npn \char_value_lccode:n #1{\char_value_lccode:w \int_eval:n{#1}} -\def_new:Npn \char_show_value_lccode:w {\tex_showthe:D\tex_lccode:D} -\def_new:Npn \char_show_value_lccode:n #1{ - \char_show_value_lccode:w \int_eval:n{#1}} +\cs_new_nopar:Npn \char_value_lccode:w {\int_use:N\tex_lccode:D} +\cs_new_nopar:Npn \char_value_lccode:n #1{\char_value_lccode:w + \intexpr_eval:w #1\intexpr_eval_end:} +\cs_new_nopar:Npn \char_show_value_lccode:w {\tex_showthe:D\tex_lccode:D} +\cs_new_nopar:Npn \char_show_value_lccode:n #1{ + \char_show_value_lccode:w \intexpr_eval:w #1\intexpr_eval_end:} % \end{macrocode} % \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} % -% \begin{macro}{\char_set_uccode:w} -% \begin{macro}{\char_set_uccode:nn} -% \begin{macro}{\char_value_uccode:w} -% \begin{macro}{\char_value_uccode:n} -% \begin{macro}{\char_show_value_uccode:w} -% \begin{macro}{\char_show_value_uccode:n} +% \begin{macro}{\char_set_uccode:w, \char_set_uccode:nn, +% \char_value_uccode:w, \char_value_uccode:n, +% \char_show_value_uccode:w, \char_show_value_uccode:n } % \begin{macrocode} -\let_new:NN \char_set_uccode:w \tex_uccode:D -\def_new:Npn \char_set_uccode:nn #1#2{ - \char_set_uccode:w #1 = \int_eval:n{#2} +\cs_new_eq:NN \char_set_uccode:w \tex_uccode:D +\cs_new_nopar:Npn \char_set_uccode:nn #1#2{ + \char_set_uccode:w #1 = \intexpr_eval:w #2\intexpr_eval_end: } -\def_new:Npn \char_value_uccode:w {\int_use:N\tex_uccode:D} -\def_new:Npn \char_value_uccode:n #1{\char_value_uccode:w \int_eval:n{#1}} -\def_new:Npn \char_show_value_uccode:w {\tex_showthe:D\tex_uccode:D} -\def_new:Npn \char_show_value_uccode:n #1{ - \char_show_value_uccode:w \int_eval:n{#1}} +\cs_new_nopar:Npn \char_value_uccode:w {\int_use:N\tex_uccode:D} +\cs_new_nopar:Npn \char_value_uccode:n #1{\char_value_uccode:w + \intexpr_eval:w #1\intexpr_eval_end:} +\cs_new_nopar:Npn \char_show_value_uccode:w {\tex_showthe:D\tex_uccode:D} +\cs_new_nopar:Npn \char_show_value_uccode:n #1{ + \char_show_value_uccode:w \intexpr_eval:w #1\intexpr_eval_end:} % \end{macrocode} % \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} % -% \begin{macro}{\char_set_sfcode:w} -% \begin{macro}{\char_set_sfcode:nn} -% \begin{macro}{\char_value_sfcode:w} -% \begin{macro}{\char_value_sfcode:n} -% \begin{macro}{\char_show_value_sfcode:w} -% \begin{macro}{\char_show_value_sfcode:n} +% \begin{macro}{\char_set_sfcode:w, \char_set_sfcode:nn, +% \char_value_sfcode:w, \char_value_sfcode:n, +% \char_show_value_sfcode:w, \char_show_value_sfcode:n} % \begin{macrocode} -\let_new:NN \char_set_sfcode:w \tex_sfcode:D -\def_new:Npn \char_set_sfcode:nn #1#2{ - \char_set_sfcode:w #1 = \int_eval:n{#2} +\cs_new_eq:NN \char_set_sfcode:w \tex_sfcode:D +\cs_new_nopar:Npn \char_set_sfcode:nn #1#2 { + \char_set_sfcode:w #1 = \intexpr_eval:w #2\intexpr_eval_end: +} +\cs_new_nopar:Npn \char_value_sfcode:w { \int_use:N \tex_sfcode:D } +\cs_new_nopar:Npn \char_value_sfcode:n #1 { + \char_value_sfcode:w \intexpr_eval:w #1\intexpr_eval_end: +} +\cs_new_nopar:Npn \char_show_value_sfcode:w { \tex_showthe:D \tex_sfcode:D } +\cs_new_nopar:Npn \char_show_value_sfcode:n #1 { + \char_show_value_sfcode:w \intexpr_eval:w #1\intexpr_eval_end: } -\def_new:Npn \char_value_sfcode:w {\int_use:N\tex_uccode:D} -\def_new:Npn \char_value_sfcode:n #1{\char_value_sfcode:w \int_eval:n{#1}} -\def_new:Npn \char_show_value_sfcode:w {\tex_showthe:D\tex_sfcode:D} -\def_new:Npn \char_show_value_sfcode:n #1{ - \char_show_value_sfcode:w \int_eval:n{#1}} % \end{macrocode} % \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \subsubsection{Generic tokens} % +% \subsection{Generic tokens} % % \begin{macro}{\token_new:Nn} -% Creates a new token. +% Creates a new token. (Will: why can't this just be +% "\cs_new_eq:NN \token_new:Nn \cs_gnew_eq:NN"? Seriously, that doesn't work!) % \begin{macrocode} -\def_new:Npn \token_new:Nn #1#2{\glet_new:NN #1#2} +\cs_new_nopar:Npn \token_new:Nn #1#2 {\cs_gnew_eq:NN #1#2} % \end{macrocode} % \end{macro} -% \begin{macro}{\c_group_begin_token} -% \begin{macro}{\c_group_end_token} -% \begin{macro}{\c_math_shift_token} -% \begin{macro}{\c_alignment_tab_token} -% \begin{macro}{\c_parameter_token} -% \begin{macro}{\c_math_superscript_token} -% \begin{macro}{\c_math_subscript_token} -% \begin{macro}{\c_space_token} -% \begin{macro}{\c_letter_token} -% \begin{macro}{\c_other_char_token} -% \begin{macro}{\c_active_char_token} +% +% \begin{macro}{\c_group_begin_token, +% \c_group_end_token, +% \c_math_shift_token, +% \c_alignment_tab_token, +% \c_parameter_token, +% \c_math_superscript_token, +% \c_math_subscript_token, +% \c_space_token, +% \c_letter_token, +% \c_other_char_token, +% \c_active_char_token } % We define these useful tokens. We have to do it by hand with the % brace tokens for obvious reasons. % \begin{macrocode} -\let_new:NN \c_group_begin_token { -\let_new:NN \c_group_end_token } +\cs_new_eq:NN \c_group_begin_token { +\cs_new_eq:NN \c_group_end_token } \group_begin: \char_set_catcode:nn{`\*}{3} \token_new:Nn \c_math_shift_token {*} @@ -932,328 +966,196 @@ \token_new:Nn \c_letter_token {a} \token_new:Nn \c_other_char_token {1} \char_set_catcode:nn{`\*}{13} -\token_new:Nn \c_active_char_token {*} +\cs_gset_nopar:Npn \c_active_char_token {\exp_not:N*} \group_end: % \end{macrocode} % \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} % % \begin{macro}{\token_if_group_begin_p:N} -% \begin{macro}{\token_if_group_begin:NTF} -% \begin{macro}{\token_if_group_begin:NT} -% \begin{macro}{\token_if_group_begin:NF} +% \begin{macro}[TF]{\token_if_group_begin:N} % Check if token is a begin group token. We use the constant % "\c_group_begin_token" for this. % \begin{macrocode} -\def_new:Npn \token_if_group_begin_p:N #1{ +\prg_new_conditional:Nnn \token_if_group_begin:N {p,TF,T,F} { \if_catcode:w \exp_not:N #1\c_group_begin_token - \c_true - \else: - \c_false - \fi: + \prg_return_true: \else: \prg_return_false: \fi: } -\def_test_function_new:npn {token_if_group_begin:N} #1{ - \if:w\token_if_group_begin_p:N #1} % \end{macrocode} % \end{macro} % \end{macro} -% \end{macro} -% \end{macro} % -% \begin{macro}{\token_if_group_end_p:N} -% \begin{macro}{\token_if_group_end:NTF} -% \begin{macro}{\token_if_group_end:NT} -% \begin{macro}{\token_if_group_end:NF} +% \begin{macro}{ \token_if_group_end_p:N } +% \begin{macro}[TF]{ \token_if_group_end:N } % Check if token is a end group token. We use the constant % "\c_group_end_token" for this. % \begin{macrocode} -\def_new:Npn \token_if_group_end_p:N #1{ +\prg_new_conditional:Nnn \token_if_group_end:N {p,TF,T,F} { \if_catcode:w \exp_not:N #1\c_group_end_token - \c_true - \else: - \c_false - \fi: + \prg_return_true: \else: \prg_return_false: \fi: } -\def_test_function_new:npn {token_if_group_end:N} #1{ - \if:w\token_if_group_end_p:N #1} % \end{macrocode} % \end{macro} % \end{macro} -% \end{macro} -% \end{macro} +% % \begin{macro}{\token_if_math_shift_p:N} -% \begin{macro}{\token_if_math_shift:NTF} -% \begin{macro}{\token_if_math_shift:NT} -% \begin{macro}{\token_if_math_shift:NF} +% \begin{macro}[TF]{\token_if_math_shift:N} % Check if token is a math shift token. We use the constant % "\c_math_shift_token" for this. % \begin{macrocode} -\def_new:Npn \token_if_math_shift_p:N #1{ +\prg_new_conditional:Nnn \token_if_math_shift:N {p,TF,T,F} { \if_catcode:w \exp_not:N #1\c_math_shift_token - \c_true - \else: - \c_false - \fi: + \prg_return_true: \else: \prg_return_false: \fi: } -\def_test_function_new:npn {token_if_math_shift:N} #1{ - \if:w\token_if_math_shift_p:N#1} % \end{macrocode} % \end{macro} % \end{macro} -% \end{macro} -% \end{macro} +% % \begin{macro}{\token_if_alignment_tab_p:N} -% \begin{macro}{\token_if_alignment_tab:NTF} -% \begin{macro}{\token_if_alignment_tab:NT} -% \begin{macro}{\token_if_alignment_tab:NF} +% \begin{macro}[TF]{\token_if_alignment_tab:N} % Check if token is an alignment tab token. We use the constant % "\c_alignment_tab_token" for this. % \begin{macrocode} -\def_new:Npn \token_if_alignment_tab_p:N #1{ +\prg_new_conditional:Nnn \token_if_alignment_tab:N {p,TF,T,F} { \if_catcode:w \exp_not:N #1\c_alignment_tab_token - \c_true - \else: - \c_false - \fi: + \prg_return_true: \else: \prg_return_false: \fi: } -\def_test_function_new:npn {token_if_alignment_tab:N} #1{ - \if:w\token_if_alignment_tab_p:N#1} % \end{macrocode} % \end{macro} % \end{macro} -% \end{macro} -% \end{macro} +% % \begin{macro}{\token_if_parameter_p:N} -% \begin{macro}{\token_if_parameter:NTF} -% \begin{macro}{\token_if_parameter:NT} -% \begin{macro}{\token_if_parameter:NF} +% \begin{macro}[TF]{\token_if_parameter:N} % Check if token is a parameter token. We use the constant % "\c_parameter_token" for this. We have to trick \TeX{} a bit to % avoid an error message. % \begin{macrocode} -\def_new:Npn \token_if_parameter_p:N #1{ - \exp_after:NN\if_catcode:w \cs:w c_parameter_token\cs_end:\exp_not:N #1 - \c_true - \else: - \c_false - \fi: +\prg_new_conditional:Nnn \token_if_parameter:N {p,TF,T,F} { + \exp_after:wN\if_catcode:w \cs:w c_parameter_token\cs_end:\exp_not:N #1 + \prg_return_true: \else: \prg_return_false: \fi: } -\def_test_function_new:npn {token_if_parameter:N} #1{ - \if:w\token_if_parameter_p:N#1} % \end{macrocode} % \end{macro} % \end{macro} -% \end{macro} -% \end{macro} +% % \begin{macro}{\token_if_math_superscript_p:N} -% \begin{macro}{\token_if_math_superscript:NTF} -% \begin{macro}{\token_if_math_superscript:NT} -% \begin{macro}{\token_if_math_superscript:NF} +% \begin{macro}[TF]{\token_if_math_superscript:N} % Check if token is a math superscript token. We use the constant % "\c_math_superscript_token" for this. % \begin{macrocode} -\def_new:Npn \token_if_math_superscript_p:N #1{ +\prg_new_conditional:Nnn \token_if_math_superscript:N {p,TF,T,F} { \if_catcode:w \exp_not:N #1\c_math_superscript_token - \c_true - \else: - \c_false - \fi: + \prg_return_true: \else: \prg_return_false: \fi: } -\def_test_function_new:npn {token_if_math_superscript:N} #1{ - \if:w\token_if_math_superscript_p:N #1} % \end{macrocode} % \end{macro} % \end{macro} -% \end{macro} -% \end{macro} +% % \begin{macro}{\token_if_math_subscript_p:N} -% \begin{macro}{\token_if_math_subscript:NTF} -% \begin{macro}{\token_if_math_subscript:NT} -% \begin{macro}{\token_if_math_subscript:NF} +% \begin{macro}[TF]{\token_if_math_subscript:N} % Check if token is a math subscript token. We use the constant % "\c_math_subscript_token" for this. % \begin{macrocode} -\def_new:Npn \token_if_math_subscript_p:N #1{ +\prg_new_conditional:Nnn \token_if_math_subscript:N {p,TF,T,F} { \if_catcode:w \exp_not:N #1\c_math_subscript_token - \c_true - \else: - \c_false - \fi: + \prg_return_true: \else: \prg_return_false: \fi: } -\def_test_function_new:npn {token_if_math_subscript:N} #1{ - \if:w\token_if_math_subscript_p:N #1} % \end{macrocode} % \end{macro} % \end{macro} -% \end{macro} -% \end{macro} % % \begin{macro}{\token_if_space_p:N} -% \begin{macro}{\token_if_space:NTF} -% \begin{macro}{\token_if_space:NT} -% \begin{macro}{\token_if_space:NF} +% \begin{macro}[TF]{\token_if_space:N} % Check if token is a space token. We use the constant % "\c_space_token" for this. % \begin{macrocode} -\def_new:Npn \token_if_space_p:N #1{ +\prg_new_conditional:Nnn \token_if_space:N {p,TF,T,F} { \if_catcode:w \exp_not:N #1\c_space_token - \c_true - \else: - \c_false - \fi: + \prg_return_true: \else: \prg_return_false: \fi: } -\def_test_function_new:npn {token_if_space:N} #1{ - \if:w\token_if_space_p:N #1} % \end{macrocode} % \end{macro} % \end{macro} -% \end{macro} -% \end{macro} +% % \begin{macro}{\token_if_letter_p:N} -% \begin{macro}{\token_if_letter:NTF} -% \begin{macro}{\token_if_letter:NT} -% \begin{macro}{\token_if_letter:NF} +% \begin{macro}[TF]{\token_if_letter:N} % Check if token is a letter token. We use the constant % "\c_letter_token" for this. % \begin{macrocode} -\def_new:Npn \token_if_letter_p:N #1{ +\prg_new_conditional:Nnn \token_if_letter:N {p,TF,T,F} { \if_catcode:w \exp_not:N #1\c_letter_token - \c_true - \else: - \c_false - \fi: + \prg_return_true: \else: \prg_return_false: \fi: } -\def_test_function_new:npn {token_if_letter:N} #1{ - \if:w\token_if_letter_p:N #1} % \end{macrocode} % \end{macro} % \end{macro} -% \end{macro} -% \end{macro} % % \begin{macro}{\token_if_other_char_p:N} -% \begin{macro}{\token_if_other_char:NTF} -% \begin{macro}{\token_if_other_char:NT} -% \begin{macro}{\token_if_other_char:NF} +% \begin{macro}[TF]{\token_if_other_char:N} % Check if token is an other char token. We use the constant % "\c_other_char_token" for this. % \begin{macrocode} -\def_new:Npn \token_if_other_char_p:N #1{ +\prg_new_conditional:Nnn \token_if_other_char:N {p,TF,T,F} { \if_catcode:w \exp_not:N #1\c_other_char_token - \c_true - \else: - \c_false - \fi: + \prg_return_true: \else: \prg_return_false: \fi: } -\def_test_function_new:npn {token_if_other_char:N} #1{ - \if:w\token_if_other_char_p:N #1} % \end{macrocode} % \end{macro} % \end{macro} -% \end{macro} -% \end{macro} % % \begin{macro}{\token_if_active_char_p:N} -% \begin{macro}{\token_if_active_char:NTF} -% \begin{macro}{\token_if_active_char:NT} -% \begin{macro}{\token_if_active_char:NF} +% \begin{macro}[TF]{\token_if_active_char:N} % Check if token is an active char token. We use the constant % "\c_active_char_token" for this. % \begin{macrocode} -\def_new:Npn \token_if_active_char_p:N #1{ +\prg_new_conditional:Nnn \token_if_active_char:N {p,TF,T,F} { \if_catcode:w \exp_not:N #1\c_active_char_token - \c_true - \else: - \c_false - \fi: + \prg_return_true: \else: \prg_return_false: \fi: } -\def_test_function_new:npn {token_if_active_char:N} #1{ - \if:w\token_if_active_char_p:N #1} % \end{macrocode} % \end{macro} % \end{macro} -% \end{macro} -% \end{macro} % % \begin{macro}{\token_if_eq_meaning_p:NN} -% \begin{macro}{\token_if_eq_meaning:NNTF} -% \begin{macro}{\token_if_eq_meaning:NNT} -% \begin{macro}{\token_if_eq_meaning:NNF} +% \begin{macro}[TF]{\token_if_eq_meaning:NN} % Check if the tokens |#1| and |#2| have same meaning. % \begin{macrocode} -\def_new:Npn \token_if_eq_meaning_p:NN #1#2 { - \if_meaning:NN #1 #2 - \c_true - \else: - \c_false - \fi: +\prg_new_conditional:Nnn \token_if_eq_meaning:NN {p,TF,T,F} { + \if_meaning:w #1 #2 + \prg_return_true: \else: \prg_return_false: \fi: } -\def_test_function_new:npn {token_if_eq_meaning:NN}#1#2{ - \if_meaning:NN #1 #2} % \end{macrocode} % \end{macro} % \end{macro} -% \end{macro} -% \end{macro} % -% \begin{macro}{\token_if_eq_catcode_p:NN} -% \begin{macro}{\token_if_eq_catcode:NNTF} -% \begin{macro}{\token_if_eq_catcode:NNT} -% \begin{macro}{\token_if_eq_catcode:NNF} +% \begin{macro}{\token_if_eq_catcode_p:NN} +% \begin{macro}[TF]{\token_if_eq_catcode:NN} % Check if the tokens |#1| and |#2| have same category code. % \begin{macrocode} -\def_new:Npn \token_if_eq_catcode_p:NN #1#2 { +\prg_new_conditional:Nnn \token_if_eq_catcode:NN {p,TF,T,F} { \if_catcode:w \exp_not:N #1 \exp_not:N #2 - \c_true - \else: - \c_false - \fi: + \prg_return_true: \else: \prg_return_false: \fi: } -\def_test_function_new:npn {token_if_eq_catcode:NN}#1#2{ - \if:w\token_if_eq_catcode_p:NN#1#2} % \end{macrocode} -% \end{macro} -% \end{macro} % \end{macro} % \end{macro} % % % -% \begin{macro}{\token_if_eq_charcode_p:NN} -% \begin{macro}{\token_if_eq_charcode:NNTF} -% \begin{macro}{\token_if_eq_charcode:NNT} -% \begin{macro}{\token_if_eq_charcode:NNF} +% \begin{macro}{\token_if_eq_charcode_p:NN} +% \begin{macro}[TF]{\token_if_eq_charcode:NN} % Check if the tokens |#1| and |#2| have same character code. % \begin{macrocode} -\def_new:Npn \token_if_charcode_eq_p:NN #1#2 { +\prg_new_conditional:Nnn \token_if_eq_charcode:NN {p,TF,T,F} { \if_charcode:w \exp_not:N #1 \exp_not:N #2 - \c_true - \else: - \c_false - \fi: + \prg_return_true: \else: \prg_return_false: \fi: } -\def_test_function_new:npn {token_if_eq_charcode:NN}#1#2{ - \if:w\token_if_eq_charcode_p:NN#1#2} % \end{macrocode} % \end{macro} % \end{macro} -% \end{macro} -% \end{macro} % % \begin{macro}{\token_if_macro_p:N} -% \begin{macro}{\token_if_macro_p_aux:w} -% \begin{macro}{\token_if_macro:NTF} -% \begin{macro}{\token_if_macro:NT} -% \begin{macro}{\token_if_macro:NF} +% \begin{macro}[TF]{\token_if_macro:N} +% \begin{macro}[aux]{\token_if_macro_p_aux:w} % When a token is a macro, "\token_to_meaning:N" will always output % something like "\long macro:#1->#1" so we simply check to see if % the meaning contains "->". Argument "#2" in the code below will be @@ -1263,78 +1165,73 @@ % other private functions as well) but that should certainly never % be a problem! % \begin{macrocode} -\def_new:Npn \token_if_macro_p:N #1 { - \exp_after:NN \token_if_macro_p_aux:w \token_to_meaning:N #1 -> \q_nil +\prg_new_conditional:Nnn \token_if_macro:N {p,TF,T,F} { + \exp_after:wN \token_if_macro_p_aux:w \token_to_meaning:N #1 -> \q_nil } -\def_new:Npn \token_if_macro_p_aux:w #1 -> #2 \q_nil{ - \if:w \tlist_if_empty_p:n{#2} \c_false \else: \c_true \fi: +\cs_new_nopar:Npn \token_if_macro_p_aux:w #1 -> #2 \q_nil{ + \if_predicate:w \tl_if_empty_p:n{#2} + \prg_return_false: \else: \prg_return_true: \fi: } -\def_test_function_new:npn {token_if_macro:N} #1{\if:w\token_if_macro_p:N#1} % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} -% \end{macro} -% \end{macro} % % \begin{macro}{\token_if_cs_p:N} -% \begin{macro}{\token_if_cs:NTF} -% \begin{macro}{\token_if_cs:NT} -% \begin{macro}{\token_if_cs:NF} +% \begin{macro}[TF]{\token_if_cs:N} % Check if token has same catcode as a control sequence. We use % "\scan_stop:" for this. % \begin{macrocode} -\def_new:Npn \token_if_cs_p:N {\token_if_eq_catcode_p:NN \scan_stop:} -\def_test_function_new:npn {token_if_cs:N} #1{ - \if:w \token_if_eq_catcode_p:NN \scan_stop: #1} +\prg_new_conditional:Nnn \token_if_cs:N {p,TF,T,F} { + \if_predicate:w \token_if_eq_catcode_p:NN \scan_stop: #1 + \prg_return_true: \else: \prg_return_false: \fi:} % \end{macrocode} % \end{macro} % \end{macro} -% \end{macro} -% \end{macro} % % % \begin{macro}{\token_if_expandable_p:N} -% \begin{macro}{\token_if_expandable:NTF} -% \begin{macro}{\token_if_expandable:NT} -% \begin{macro}{\token_if_expandable:NF} +% \begin{macro}[TF]{\token_if_expandable:N} % Check if token is expandable. We use the fact that \TeX\ will % temporarily convert "\exp_not:N" \m{token} into "\scan_stop:" if % \m{token} is expandable. % \begin{macrocode} -\def_new:Npn \token_if_expandable_p:N #1{ - \exp_after:NN \if_token_eq:NN \exp_not:N #1 \scan_stop: - \c_true - \else: - \c_false - \fi: +\prg_new_conditional:Nnn \token_if_expandable:N {p,TF,T,F} { + \cs_if_exist:NTF #1 { + \exp_after:wN \if_meaning:w \exp_not:N #1 #1 + \prg_return_false: \else: \prg_return_true: \fi: + } { + \prg_return_false: + } } -\def_test_function_new:npn {token_if_expandable:N} #1{ - \if:w\token_if_expandable_p:N#1} % \end{macrocode} % \end{macro} % \end{macro} -% \end{macro} -% \end{macro} % -% \begin{macro}{\token_if_chardef_p:N} -% \begin{macro}{\token_if_chardef_p_aux:w} -% \begin{macro}{\token_if_mathchardef_p:N} -% \begin{macro}{\token_if_mathchardef_p_aux:w} -% \begin{macro}{\token_if_int_register_p:N} -% \begin{macro}{\token_if_int_register_p_aux:w} -% \begin{macro}{\token_if_skip_register_p:N} -% \begin{macro}{\token_if_skip_register_p_aux:w} -% \begin{macro}{\token_if_dim_register_p:N} -% \begin{macro}{\token_if_dim_register_p_aux:w} -% \begin{macro}{\token_if_toks_register_p:N} -% \begin{macro}{\token_if_toks_register_p_aux:w} -% \begin{macro}{\token_if_protected_macro_p:N} -% \begin{macro}{\token_if_protected_macro_p_aux:w} -% \begin{macro}{\token_if_long_macro_p:N} -% \begin{macro}{\token_if_long_macro_p_aux:w} -% \begin{macro}{\token_if_protected_long_macro_p:N} -% \begin{macro}{\token_if_protected_long_macro_p_aux:w} +% \begin{macro}{\token_if_chardef_p:N, +% \token_if_mathchardef_p:N, +% \token_if_int_register_p:N, +% \token_if_skip_register_p:N, +% \token_if_dim_register_p:N, +% \token_if_toks_register_p:N, +% \token_if_protected_macro_p:N, +% \token_if_long_macro_p:N, +% \token_if_protected_long_macro_p:N} +% \begin{macro}[TF]{\token_if_chardef:N,\token_if_mathchardef:N, +% \token_if_long_macro:N, \token_if_protected_macro:N, +% \token_if_protected_long_macro:N, \token_if_dim_register:N, +% \token_if_skip_register:N, \token_if_int_register:N, +% \token_if_toks_register:N} +% \begin{macro}[aux]{ +% \token_if_chardef_p_aux:w, +% \token_if_mathchardef_p_aux:w, +% \token_if_int_register_p_aux:w, +% \token_if_skip_register_p_aux:w, +% \token_if_dim_register_p_aux:w, +% \token_if_toks_register_p_aux:w, +% \token_if_protected_macro_p_aux:w, +% \token_if_long_macro_p_aux:w, +% \token_if_protected_long_macro_p_aux:w} % Most of these functions have to check the meaning of the token in % question so we need to do some checkups on which characters are % output by |\token_to_meaning:N|. As usual, these characters have @@ -1342,17 +1239,19 @@ % below\dots % \begin{macrocode} \group_begin: - \char_set_lccode:nn {`\X}{`\n} + \char_set_lccode:nn {`\T}{`\T} + \char_set_lccode:nn {`\F}{`\F} + \char_set_lccode:nn {`\X}{`\n} \char_set_lccode:nn {`\Y}{`\t} \char_set_lccode:nn {`\Z}{`\d} \char_set_lccode:nn {`\?}{`\\} - \tlist_map_inline:nn{\X\Y\Z\M\T\C\H\A\R\O\U\S\K\I\P\L\G\P\E} + \tl_map_inline:nn{\X\Y\Z\M\C\H\A\R\O\U\S\K\I\P\L\G\P\E} {\char_set_catcode:nn {`#1}{12}} % \end{macrocode} % We convert the token list to lowercase and restore the catcode and % lowercase code changes. % \begin{macrocode} -\tlist_to_lowercase:n{ +\tl_to_lowercase:n{ \group_end: % \end{macrocode} % First up is checking if something has been defined with @@ -1360,239 +1259,126 @@ % thinks of such tokens as hexadecimal so it stores them as % |\char"|\meta{hex~number} or |\mathchar"|\meta{hex~number}. % \begin{macrocode} -\def_new:Npn \token_if_chardef_p:N #1 { - \exp_after:NN \token_if_chardef_p_aux:w +\prg_new_conditional:Nnn \token_if_chardef:N {p,TF,T,F} { + \exp_after:wN \token_if_chardef_aux:w \token_to_meaning:N #1?CHAR"\q_nil } -\def_new:Npn \token_if_chardef_p_aux:w #1?CHAR"#2\q_nil{ - \tlist_if_empty_p:n{#1} +\cs_new_nopar:Npn \token_if_chardef_aux:w #1?CHAR"#2\q_nil{ + \tl_if_empty:nTF {#1} {\prg_return_true:} {\prg_return_false:} } -\def_new:Npn \token_if_mathchardef_p:N #1 { - \exp_after:NN \token_if_mathchardef_p_aux:w +% \end{macrocode} +% +% \begin{macrocode} +\prg_new_conditional:Nnn \token_if_mathchardef:N {p,TF,T,F} { + \exp_after:wN \token_if_mathchardef_aux:w \token_to_meaning:N #1?MAYHCHAR"\q_nil } -\def_new:Npn \token_if_mathchardef_p_aux:w #1?MAYHCHAR"#2\q_nil{ - \tlist_if_empty_p:n{#1} +\cs_new_nopar:Npn \token_if_mathchardef_aux:w #1?MAYHCHAR"#2\q_nil{ + \tl_if_empty:nTF {#1} {\prg_return_true:} {\prg_return_false:} } % \end{macrocode} % Integer registers are a little more difficult since they expand to % |\count|\meta{number} and there is also a primitive |\countdef|. So % we have to check for that primitive as well. % \begin{macrocode} -\def:Npn \token_if_int_register_p:N #1{ - \if_meaning:NN \tex_countdef:D #1 - \c_false +\prg_new_conditional:Nnn \token_if_int_register:N {p,TF,T,F} { + \if_meaning:w \tex_countdef:D #1 + \prg_return_false: \else: - \exp_after:NN \token_if_int_register_p_aux:w + \exp_after:wN \token_if_int_register_aux:w \token_to_meaning:N #1?COUXY\q_nil \fi: } -\def_new:Npn \token_if_int_register_p_aux:w #1?COUXY#2\q_nil{ - \tlist_if_empty_p:n{#1} +\cs_new_nopar:Npn \token_if_int_register_aux:w #1?COUXY#2\q_nil{ + \tl_if_empty:nTF {#1} {\prg_return_true:} {\prg_return_false:} } % \end{macrocode} % Skip registers are done the same way as the integer registers. % \begin{macrocode} -\def:Npn \token_if_skip_register_p:N #1{ - \if_meaning:NN \tex_skipdef:D #1 - \c_false +\prg_new_conditional:Nnn \token_if_skip_register:N {p,TF,T,F} { + \if_meaning:w \tex_skipdef:D #1 + \prg_return_false: \else: - \exp_after:NN \token_if_skip_register_p_aux:w - \token_to_meaning:N #1?SKIP\q_nil + \exp_after:wN \token_if_skip_register_aux:w + \token_to_meaning:N #1?SKIP\q_nil \fi: } -\def_new:Npn \token_if_skip_register_p_aux:w #1?SKIP#2\q_nil{ - \tlist_if_empty_p:n{#1} +\cs_new_nopar:Npn \token_if_skip_register_aux:w #1?SKIP#2\q_nil{ + \tl_if_empty:nTF {#1} {\prg_return_true:} {\prg_return_false:} } % \end{macrocode} % Dim registers. No news here % \begin{macrocode} -\def:Npn \token_if_dim_register_p:N #1{ - \if_meaning:NN \tex_dimendef:D #1 - \c_false +\prg_new_conditional:Nnn \token_if_dim_register:N {p,TF,T,F} { + \if_meaning:w \tex_dimendef:D #1 + \c_false_bool \else: - \exp_after:NN \token_if_dim_register_p_aux:w - \token_to_meaning:N #1?ZIMEX\q_nil + \exp_after:wN \token_if_dim_register_aux:w + \token_to_meaning:N #1?ZIMEX\q_nil \fi: } -\def_new:Npn \token_if_dim_register_p_aux:w #1?ZIMEX#2\q_nil{ - \tlist_if_empty_p:n{#1} +\cs_new_nopar:Npn \token_if_dim_register_aux:w #1?ZIMEX#2\q_nil{ + \tl_if_empty:nTF {#1} {\prg_return_true:} {\prg_return_false:} } % \end{macrocode} -% Toks registers. Ho-hum. +% Toks registers. % \begin{macrocode} -\def:Npn \token_if_toks_register_p:N #1{ - \if_meaning:NN \tex_toksdef:D #1 - \c_false +\prg_new_conditional:Nnn \token_if_toks_register:N {p,TF,T,F} { + \if_meaning:w \tex_toksdef:D #1 + \prg_return_false: \else: - \exp_after:NN \token_if_toks_register_p_aux:w + \exp_after:wN \token_if_toks_register_aux:w \token_to_meaning:N #1?YOKS\q_nil \fi: } -\def_new:Npn \token_if_toks_register_p_aux:w #1?YOKS#2\q_nil{ - \tlist_if_empty_p:n{#1} +\cs_new_nopar:Npn \token_if_toks_register_aux:w #1?YOKS#2\q_nil{ + \tl_if_empty:nTF {#1} {\prg_return_true:} {\prg_return_false:} } % \end{macrocode} % Protected macros. % \begin{macrocode} -\def_new:Npn \token_if_protected_macro_p:N #1 { - \exp_after:NN \token_if_protected_macro_p_aux:w +\prg_new_conditional:Nnn \token_if_protected_macro:N {p,TF,T,F} { + \exp_after:wN \token_if_protected_macro_aux:w \token_to_meaning:N #1?PROYECYEZ~MACRO\q_nil } -\def_new:Npn \token_if_protected_macro_p_aux:w #1?PROYECYEZ~MACRO#2\q_nil{ - \tlist_if_empty_p:n{#1} +\cs_new_nopar:Npn \token_if_protected_macro_aux:w #1?PROYECYEZ~MACRO#2\q_nil{ + \tl_if_empty:nTF {#1} {\prg_return_true:} {\prg_return_false:} } % \end{macrocode} % Long macros. % \begin{macrocode} -\def_new:Npn \token_if_long_macro_p:N #1 { - \exp_after:NN \token_if_long_macro_p_aux:w +\prg_new_conditional:Nnn \token_if_long_macro:N {p,TF,T,F} { + \exp_after:wN \token_if_long_macro_aux:w \token_to_meaning:N #1?LOXG~MACRO\q_nil } -\def_new:Npn \token_if_long_macro_p_aux:w #1?LOXG~MACRO#2\q_nil{ - \tlist_if_empty_p:n{#1} +\cs_new_nopar:Npn \token_if_long_macro_aux:w #1?LOXG~MACRO#2\q_nil{ + \tl_if_empty:nTF {#1} {\prg_return_true:} {\prg_return_false:} } % \end{macrocode} % Finally protected long macros where we for once don't have to add an % extra test since there is no primitive for the combined prefixes. % \begin{macrocode} -\def_new:Npn \token_if_protected_long_macro_p:N #1 { - \exp_after:NN \token_if_protected_long_macro_p_aux:w - \token_to_meaning:N #1?PROYECYEZ~?LOXG~MACRO\q_nil +\prg_new_conditional:Nnn \token_if_protected_long_macro:N {p,TF,T,F} { + \exp_after:wN \token_if_protected_long_macro_aux:w + \token_to_meaning:N #1?PROYECYEZ?LOXG~MACRO\q_nil } -\def_new:Npn \token_if_protected_long_macro_p_aux:w #1 - ?PROYECYEZ~?LOXG~MACRO#2\q_nil{ - \tlist_if_empty_p:n{#1} +\cs_new_nopar:Npn \token_if_protected_long_macro_aux:w #1 + ?PROYECYEZ?LOXG~MACRO#2\q_nil{ + \tl_if_empty:nTF {#1} {\prg_return_true:} {\prg_return_false:} } % \end{macrocode} -% Finally the |\tlist_to_lowercase:n| ends! +% Finally the |\tl_to_lowercase:n| ends! % \begin{macrocode} } % \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} -% -% \begin{macro}{\token_if_chardef:NTF} -% \begin{macro}{\token_if_chardef:NT} -% \begin{macro}{\token_if_chardef:NF} -% \begin{macrocode} -\def_test_function_new:npn {token_if_chardef:N} {\if:w \token_if_chardef_p:N} -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\token_if_mathchardef:NTF} -% \begin{macro}{\token_if_mathchardef:NT} -% \begin{macro}{\token_if_mathchardef:NF} -% \begin{macrocode} -\def_test_function_new:npn {token_if_mathchardef:N} { - \if:w \token_if_mathchardef_p:N} -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\token_if_long_macro:NTF} -% \begin{macro}{\token_if_long_macro:NT} -% \begin{macro}{\token_if_long_macro:NF} -% \begin{macrocode} -\def_test_function_new:npn {token_if_long_macro:N} { - \if:w \token_if_long_macro_p:N} -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\token_if_protected_macro:NTF} -% \begin{macro}{\token_if_protected_macro:NT} -% \begin{macro}{\token_if_protected_macro:NF} -% \begin{macrocode} -\def_test_function_new:npn {token_if_protected_macro:N} { - \if:w \token_if_protected_macro_p:N} -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\token_if_protected_long_macro:NTF} -% \begin{macro}{\token_if_protected_long_macro:NT} -% \begin{macro}{\token_if_protected_long_macro:NF} -% \begin{macrocode} -\def_test_function_new:npn {token_if_protected_long_macro:N} { - \if:w \token_if_protected_long_macro_p:N} -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\token_if_dim_register:NTF} -% \begin{macro}{\token_if_dim_register:NT} -% \begin{macro}{\token_if_dim_register:NF} -% \begin{macrocode} -\def_test_function_new:npn {token_if_dim_register:N} { - \if:w \token_if_dim_register_p:N} -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\token_if_skip_register:NTF} -% \begin{macro}{\token_if_skip_register:NT} -% \begin{macro}{\token_if_skip_register:NF} -% \begin{macrocode} -\def_test_function_new:npn {token_if_skip_register:N} { - \if:w \token_if_skip_register_p:N} -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\token_if_int_register:NTF} -% \begin{macro}{\token_if_int_register:NT} -% \begin{macro}{\token_if_int_register:NF} -% \begin{macrocode} -\def_test_function_new:npn {token_if_int_register:N} { - \if:w \token_if_int_register_p:N} -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\token_if_toks_register:NTF} -% \begin{macro}{\token_if_toks_register:NT} -% \begin{macro}{\token_if_toks_register:NF} -% \begin{macrocode} -\def_test_function_new:npn {token_if_toks_register:N} { - \if:w \token_if_toks_register_p:N} -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% -% -% % % We do not provide a function for testing if a control sequence is % ``outer'' since we don't use that in \LaTeX3. % -% \begin{macro}{\token_get_prefix_arg_replacement_aux:w} +% \begin{macro}[aux]{\token_get_prefix_arg_replacement_aux:w} % \begin{macro}{\token_get_prefix_spec:N} % \begin{macro}{\token_get_arg_spec:N} % \begin{macro}{\token_get_replacement_spec:N} @@ -1613,27 +1399,27 @@ \char_set_catcode:nn{`\C}{12} \char_set_catcode:nn{`\R}{12} \char_set_catcode:nn{`\O}{12} -\tlist_to_lowercase:n{ +\tl_to_lowercase:n{ \group_end: - \def_new:Npn \token_get_prefix_arg_replacement_aux:w #1MACRO?#2->#3\q_nil#4{ + \cs_new_nopar:Npn \token_get_prefix_arg_replacement_aux:w #1MACRO?#2->#3\q_nil#4{ #4{#1}{#2}{#3} } - \def_new:Npn\token_get_prefix_spec:N #1{ + \cs_new_nopar:Npn\token_get_prefix_spec:N #1{ \token_if_macro:NTF #1{ - \exp_after:NN \token_get_prefix_arg_replacement_aux:w - \token_to_meaning:N #1\q_nil\use_arg_i:nnn + \exp_after:wN \token_get_prefix_arg_replacement_aux:w + \token_to_meaning:N #1\q_nil\use_i:nnn }{\scan_stop:} } - \def_new:Npn\token_get_arg_spec:N #1{ + \cs_new_nopar:Npn\token_get_arg_spec:N #1{ \token_if_macro:NTF #1{ - \exp_after:NN \token_get_prefix_arg_replacement_aux:w - \token_to_meaning:N #1\q_nil\use_arg_ii:nnn + \exp_after:wN \token_get_prefix_arg_replacement_aux:w + \token_to_meaning:N #1\q_nil\use_ii:nnn }{\scan_stop:} } - \def_new:Npn\token_get_replacement_spec:N #1{ + \cs_new_nopar:Npn\token_get_replacement_spec:N #1{ \token_if_macro:NTF #1{ - \exp_after:NN \token_get_prefix_arg_replacement_aux:w - \token_to_meaning:N #1\q_nil\use_arg_iii:nnn + \exp_after:wN \token_get_prefix_arg_replacement_aux:w + \token_to_meaning:N #1\q_nil\use_iii:nnn }{\scan_stop:} } } @@ -1646,52 +1432,50 @@ % \paragraph{Useless code: because we can!} % % \begin{macro}{\token_if_primitive_p:N} -% \begin{macro}{\token_if_primitive_p_aux:N} -% \begin{macro}{\token_if_primitive:NTF} -% \begin{macro}{\token_if_primitive:NT} -% \begin{macro}{\token_if_primitive:NF} +% \begin{macro}[aux]{\token_if_primitive_p_aux:N} +% \begin{macro}[TF]{\token_if_primitive:N} % It is rather hard to determine if a token is a primitive. First we % can check if it is a control sequence or active character. If % either, we check if it is a macro. Then we can go through a % tedious process of testing for different register types\dots{} I % don't actually think this function is useful but you never know. % \begin{macrocode} -\def_new:Npn \token_if_primitive_p:N #1{ - \if:w \token_if_cs_p:N #1\scan_stop: - \if:w \token_if_macro_p:N #1 - \c_false +\prg_new_conditional:Nnn \token_if_primitive:N {p,TF,T,F} { + \if_predicate:w \token_if_cs_p:N #1 + \if_predicate:w \token_if_macro_p:N #1 + \prg_return_false: \else: \token_if_primitive_p_aux:N #1 \fi: \else: - \if:w \token_if_active_p:N #1 - \if:w \token_if_macro_p:N #1 - \c_false + \if_predicate:w \token_if_active_char_p:N #1 + \if_predicate:w \token_if_macro_p:N #1 + \prg_return_false: \else: \token_if_primitive_p_aux:N #1 \fi: \else: - \c_false + \prg_return_false: \fi: \fi: } -\def_new:Npn \token_if_primitive_p_aux:N #1{ - \if:w \token_if_chardef_p:N #1 \c_false +\cs_new_nopar:Npn \token_if_primitive_p_aux:N #1{ + \if_predicate:w \token_if_chardef_p:N #1 \c_false_bool \else: - \if:w \token_if_mathchardef_p:N #1 \c_false + \if_predicate:w \token_if_mathchardef_p:N #1 \prg_return_false: \else: - \if:w \token_if_int_register_p:N #1 \c_false + \if_predicate:w \token_if_int_register_p:N #1 \prg_return_false: \else: - \if:w \token_if_skip_register_p:N #1 \c_false + \if_predicate:w \token_if_skip_register_p:N #1 \prg_return_false: \else: - \if:w \token_if_dim_register_p:N #1 \c_false + \if_predicate:w \token_if_dim_register_p:N #1 \prg_return_false: \else: - \if:w \token_if_toks_register_p:N #1 \c_false + \if_predicate:w \token_if_toks_register_p:N #1 \prg_return_false: \else: % \end{macrocode} % We made it! % \begin{macrocode} - \c_true + \prg_return_true: \fi: \fi: \fi: @@ -1699,24 +1483,13 @@ \fi: \fi: } -\def_test_function_new:npn {token_if_primitive:N} #1{ - \if:w\token_if_primitive_p:N#1} % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} -% \end{macro} -% \end{macro} -% -% -% -% -% \subsubsection{Peeking ahead at the next token} -% -% -% % % +% \subsection{Peeking ahead at the next token} % % \begin{macro}{\l_peek_token} % \begin{macro}{\g_peek_token} @@ -1740,8 +1513,8 @@ % input stream which |\l_peek_token| is set equal to. % |\peek_gafter:NN| does the same globally to |\g_peek_token|. % \begin{macrocode} -\def_new:Npn \peek_after:NN {\tex_futurelet:D \l_peek_token } -\def_new:Npn \peek_gafter:NN { +\cs_new_nopar:Npn \peek_after:NN {\tex_futurelet:D \l_peek_token } +\cs_new_nopar:Npn \peek_gafter:NN { \pref_global:D \tex_futurelet:D \g_peek_token } % \end{macrocode} @@ -1776,13 +1549,13 @@ % in the input stream. % \end{enumerate} % -% \begin{macro}{\l_peek_true_tlp} -% \begin{macro}{\l_peek_false_tlp} -% Two dedicated token list pointers that store the true and false +% \begin{macro}{\l_peek_true_tl} +% \begin{macro}{\l_peek_false_tl} +% Two dedicated token list variables that store the true and false % cases. % \begin{macrocode} -\tlp_new:Nn \l_peek_true_tlp {} -\tlp_new:Nn \l_peek_false_tlp {} +\tl_new:Nn \l_peek_true_tl {} +\tl_new:Nn \l_peek_false_tl {} % \end{macrocode} % \end{macro} % \end{macro} @@ -1791,82 +1564,97 @@ % Scratch function used for storing the token to be removed if % found. % \begin{macrocode} -\def_new:Npn \peek_tmp:w{} +\cs_new_nopar:Npn \peek_tmp:w {} % \end{macrocode} % \end{macro} % -% \begin{macro}{\l_peek_search_tlp} -% We also use this token list pointer for storing the token we want +% \begin{macro}{\l_peek_search_tl} +% We also use this token list variable for storing the token we want % to compare. This turns out to be useful. % \begin{macrocode} -\tlp_new:Nn \l_peek_search_tlp{} +\tl_new:Nn \l_peek_search_tl {} % \end{macrocode} % \end{macro} % -% \begin{macro}{\peek_token_generic:NNTF} -% |#1| is the function to execute (obey or ignore spaces, etc.), -% |#2| is the special token we're looking for, and |#3| and |#4| -% are the \meta{true} and \meta{false} branches. -% \begin{macrocode} -\def_long_new:Npn \peek_token_generic:NNTF #1#2#3#4{ - \let:NN \l_peek_search_token #2 - \tlp_set:Nn \l_peek_search_tlp {#2} - \tlp_set:Nx \l_peek_true_tlp {\exp_not:n{\group_align_safe_end: #3}} - \tlp_set:Nx \l_peek_false_tlp {\exp_not:n{\group_align_safe_end: #4}} +% \begin{macro}[TF]{\peek_token_generic:NN} +% \begin{arguments} +% \item the function to execute (obey or ignore spaces, etc.), +% \item the special token we're looking for. +% \end{arguments} +% \begin{macrocode} +\cs_new:Npn \peek_token_generic:NNTF #1#2#3#4 { + \cs_set_eq:NN \l_peek_search_token #2 + \tl_set:Nn \l_peek_search_tl {#2} + \tl_set:Nx \l_peek_true_tl {\exp_not:n{\group_align_safe_end: #3}} + \tl_set:Nx \l_peek_false_tl {\exp_not:n{\group_align_safe_end: #4}} \group_align_safe_begin: \peek_after:NN #1 } +\cs_new:Npn \peek_token_generic:NNT #1#2#3 { + \peek_token_generic:NNTF #1#2 {#3} {} +} +\cs_new:Npn \peek_token_generic:NNF #1#2#3 { + \peek_token_generic:NNTF #1#2 {} {#3} +} % \end{macrocode} % \end{macro} -% \begin{macro}{\peek_token_remove_generic:NNTF} +% +% \begin{macro}[TF]{\peek_token_remove_generic:NN} % If we want to be able to remove any character from the input % stream we might as well do it the same way for all characters so % we define this as little differently from above. % \begin{macrocode} -\def_long_new:Npn \peek_token_remove_generic:NNTF #1#2#3#4{ - \let:NN \l_peek_search_token #2 - \tlp_set:Nn \l_peek_search_tlp {#2} - \tlp_set:Nx \l_peek_true_aux_tlp { \exp_not:n{ #3 } } - \tlp_set_eq:NN \l_peek_true_tlp \c_peek_true_remove_next_tlp - \tlp_set:Nx \l_peek_false_tlp {\exp_not:n{\group_align_safe_end: #4}} +\cs_new:Npn \peek_token_remove_generic:NNTF #1#2#3#4 { + \cs_set_eq:NN \l_peek_search_token #2 + \tl_set:Nn \l_peek_search_tl {#2} + \tl_set:Nx \l_peek_true_aux_tl { \exp_not:n{ #3 } } + \tl_set_eq:NN \l_peek_true_tl \c_peek_true_remove_next_tl + \tl_set:Nx \l_peek_false_tl {\exp_not:n{\group_align_safe_end: #4}} \group_align_safe_begin: \peek_after:NN #1 } +\cs_new:Npn \peek_token_remove_generic:NNT #1#2#3 { + \peek_token_remove_generic:NNTF #1#2 {#3} {} +} +\cs_new:Npn \peek_token_remove_generic:NNF #1#2#3 { + \peek_token_remove_generic:NNTF #1#2 {} {#3} +} % \end{macrocode} % \end{macro} -% \begin{macro}{\l_peek_true_aux_tlp} -% \begin{macro}{\l_peek_true_remove_next_tlp} -% Two token list pointers to help with removing the character from +% +% \begin{macro}{\l_peek_true_aux_tl} +% \begin{macro}{\c_peek_true_remove_next_tl} +% Two token list variables to help with removing the character from % the input stream. % \begin{macrocode} -\tlp_new:Nn \l_peek_true_aux_tlp {} -\tlp_new:Nn \c_peek_true_remove_next_tlp {\group_align_safe_end: - \tex_afterassignment:D \l_peek_true_aux_tlp \let:NN \peek_tmp:w +\tl_new:Nn \l_peek_true_aux_tl {} +\tl_new:Nn \c_peek_true_remove_next_tl {\group_align_safe_end: + \tex_afterassignment:D \l_peek_true_aux_tl \cs_set_eq:NN \peek_tmp:w } % \end{macrocode} % \end{macro} % \end{macro} % -% \begin{macro}{\peek_execute_braches_meaning:} -% \begin{macro}{\peek_execute_braches_catcode:} -% \begin{macro}{\peek_execute_braches_charcode:} -% \begin{macro}{\peek_execute_branches_charcode_aux:NN} +% \begin{macro}{\peek_execute_branches_meaning:} +% \begin{macro}{\peek_execute_branches_catcode:} +% \begin{macro}{\peek_execute_branches_charcode:} +% \begin{macro}[aux]{\peek_execute_branches_charcode_aux:NN} % There are three major tests between tokens in \TeX: meaning, % catcode and charcode. Hence we define three basic test functions % that set in after the ignoring phase is over and done with. % \begin{macrocode} -\def_new:Npn \peek_execute_branches_meaning: { - \if_meaning:NN \l_peek_token \l_peek_search_token - \exp_after:NN \l_peek_true_tlp +\cs_new_nopar:Npn \peek_execute_branches_meaning: { + \if_meaning:w \l_peek_token \l_peek_search_token + \exp_after:wN \l_peek_true_tl \else: - \exp_after:NN \l_peek_false_tlp + \exp_after:wN \l_peek_false_tl \fi: } -\def_new:Npn \peek_execute_branches_catcode: { +\cs_new_nopar:Npn \peek_execute_branches_catcode: { \if_catcode:w \exp_not:N\l_peek_token \exp_not:N\l_peek_search_token - \exp_after:NN \l_peek_true_tlp + \exp_after:wN \l_peek_true_tl \else: - \exp_after:NN \l_peek_false_tlp + \exp_after:wN \l_peek_false_tl \fi: } % \end{macrocode} @@ -1880,31 +1668,31 @@ % |charcode| function for searching for |\c_group_begin_token| or % |\c_space_token|. % \begin{macrocode} -\def_new:Npn \peek_execute_branches_charcode: { - \predicate:nTF { +\cs_new_nopar:Npn \peek_execute_branches_charcode: { + \bool_if:nTF { \token_if_eq_catcode_p:NN \l_peek_token \c_group_begin_token || \token_if_eq_meaning_p:NN \l_peek_token \c_space_token } - { \l_peek_false_tlp } + { \l_peek_false_tl } % \end{macrocode} % Otherwise we call a small auxiliary function that just grabs the % next token. We can do that because it really is a single token; we % just have insert it again afterwards. Also we stored the token we -% were looking for in the token list pointer |\l_peek_search_tlp| so +% were looking for in the token list variable |\l_peek_search_tl| so % we unpack it again for this function. % \begin{macrocode} - { \exp_after:NN \peek_execute_branches_charcode_aux:NN \l_peek_search_tlp } + { \exp_after:wN \peek_execute_branches_charcode_aux:NN \l_peek_search_tl } } % \end{macrocode} % Then we just do the usual |\if_charcode:w| comparison. We also % remember to insert |#2| again after executing the true or false % branches. % \begin{macrocode} -\def_long_new:Npn \peek_execute_branches_charcode_aux:NN #1#2{ +\cs_new:Npn \peek_execute_branches_charcode_aux:NN #1#2{ \if_charcode:w \exp_not:N #1\exp_not:N#2 - \exp_after:NN \l_peek_true_tlp + \exp_after:wN \l_peek_true_tl \else: - \exp_after:NN \l_peek_false_tlp + \exp_after:wN \l_peek_false_tl \fi: #2 } @@ -1914,87 +1702,152 @@ % \end{macro} % \end{macro} % -% \begin{macro}{\peek_meaning:NTF} -% \begin{macro}{\peek_meaning_ignore_spaces:NTF} -% \begin{macro}{\peek_meaning_remove:NTF} -% \begin{macro}{\peek_meaning_remove_ignore_spaces:NTF} -% Here we use meaning comparison with |\if_meaning:NN|. -% \begin{macrocode} -\def_new:Npn \peek_meaning:NTF { - \peek_token_generic:NNTF \peek_execute_branches_meaning: -} -\def_new:Npn \peek_meaning_ignore_spaces:NTF { - \let:NN \peek_execute_branches: \peek_execute_branches_meaning: - \peek_token_generic:NNTF \peek_ignore_spaces_execute_branches: -} -\def_new:Npn \peek_meaning_remove:NTF { - \peek_token_remove_generic:NNTF \peek_execute_branches_meaning: -} -\def_new:Npn \peek_meaning_remove_ignore_spaces:NTF { - \let:NN \peek_execute_branches: \peek_execute_branches_meaning: - \peek_token_remove_generic:NNTF \peek_ignore_spaces_execute_branches: +% \begin{macro}[aux]{\peek_def_aux:nnnn,\peek_def_aux_ii:nnnnn} +% This function aids defining conditional variants without too much +% repeated code. I hope that it doesn't detract too much from the readability. +% \begin{macrocode} +\cs_new_nopar:Npn \peek_def_aux:nnnn #1#2#3#4 { + \peek_def_aux_ii:nnnnn {#1} {#2} {#3} {#4} { TF } + \peek_def_aux_ii:nnnnn {#1} {#2} {#3} {#4} { T } + \peek_def_aux_ii:nnnnn {#1} {#2} {#3} {#4} { F } +} +\cs_new_nopar:Npn \peek_def_aux_ii:nnnnn #1#2#3#4#5 { + \cs_new_nopar:cpx { #1 #5 } { + \tl_if_empty:nF {#2} { + \exp_not:n { \cs_set_eq:NN \peek_execute_branches: #2 } + } + \exp_not:c { #3 #5 } + \exp_not:n { #4 } + } } % \end{macrocode} % \end{macro} +% +% \begin{macro}[TF]{\peek_meaning:N} +% Here we use meaning comparison with |\if_meaning:w|. +% \begin{macrocode} +\peek_def_aux:nnnn + { peek_meaning:N } + {} + { peek_token_generic:NN } + { \peek_execute_branches_meaning: } +% \end{macrocode} % \end{macro} +% +% \begin{macro}[TF]{\peek_meaning_ignore_spaces:N} +% \begin{macrocode} +\peek_def_aux:nnnn + { peek_meaning_ignore_spaces:N } + { \peek_execute_branches_meaning: } + { peek_token_generic:NN } + { \peek_ignore_spaces_execute_branches: } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[TF]{\peek_meaning_remove:N} +% \begin{macrocode} +\peek_def_aux:nnnn + { peek_meaning_remove:N } + {} + { peek_token_remove_generic:NN } + { \peek_execute_branches_meaning: } +% \end{macrocode} % \end{macro} +% +% \begin{macro}[TF]{\peek_meaning_remove_ignore_spaces:N} +% \begin{macrocode} +\peek_def_aux:nnnn + { peek_meaning_remove_ignore_spaces:N } + { \peek_execute_branches_meaning: } + { peek_token_remove_generic:NN } + { \peek_ignore_spaces_execute_branches: } +% \end{macrocode} % \end{macro} % -% \begin{macro}{\peek_catcode:NTF} -% \begin{macro}{\peek_catcode_ignore_spaces:NTF} -% \begin{macro}{\peek_catcode_remove:NTF} -% \begin{macro}{\peek_catcode_remove_ignore_spaces:NTF} +% \begin{macro}[TF]{\peek_catcode:N} % Here we use catcode comparison with |\if_catcode:w|. % \begin{macrocode} -\def_new:Npn \peek_catcode:NTF { - \peek_token_generic:NNTF \peek_execute_branches_catcode: -} -\def_new:Npn \peek_catcode_ignore_spaces:NTF { - \let:NN \peek_execute_branches: \peek_execute_branches_catcode: - \peek_token_generic:NNTF \peek_ignore_spaces_execute_branches: -} -\def_new:Npn \peek_catcode_remove:NTF { - \peek_token_remove_generic:NNTF \peek_execute_branches_catcode: -} -\def_new:Npn \peek_catcode_remove_ignore_spaces:NTF { - \let:NN \peek_execute_branches: \peek_execute_branches_catcode: - \peek_token_remove_generic:NNTF \peek_ignore_spaces_execute_branches: -} +\peek_def_aux:nnnn + { peek_catcode:N } + {} + { peek_token_generic:NN } + { \peek_execute_branches_catcode: } % \end{macrocode} % \end{macro} +% +% \begin{macro}[TF]{\peek_catcode_ignore_spaces:N} +% \begin{macrocode} +\peek_def_aux:nnnn + { peek_catcode_ignore_spaces:N } + { \peek_execute_branches_catcode: } + { peek_token_generic:NN } + { \peek_ignore_spaces_execute_branches: } +% \end{macrocode} % \end{macro} +% +% \begin{macro}[TF]{\peek_catcode_remove:N} +% \begin{macrocode} +\peek_def_aux:nnnn + { peek_catcode_remove:N } + {} + { peek_token_remove_generic:NN } + { \peek_execute_branches_catcode: } +% \end{macrocode} % \end{macro} +% +% \begin{macro}[TF]{\peek_catcode_remove_ignore_spaces:N} +% \begin{macrocode} +\peek_def_aux:nnnn + { peek_catcode_remove_ignore_spaces:N } + { \peek_execute_branches_catcode: } + { peek_token_remove_generic:NN } + { \peek_ignore_spaces_execute_branches: } +% \end{macrocode} % \end{macro} % -% \begin{macro}{\peek_charcode:NTF} -% \begin{macro}{\peek_charcode_ignore_spaces:NTF} -% \begin{macro}{\peek_charcode_remove:NTF} -% \begin{macro}{\peek_charcode_remove_ignore_spaces:NTF} +% \begin{macro}[TF]{\peek_charcode:N} % Here we use charcode comparison with |\if_charcode:w|. % \begin{macrocode} -\def_new:Npn \peek_charcode:NTF { - \peek_token_generic:NNTF \peek_execute_branches_charcode: -} -\def_new:Npn \peek_charcode_ignore_spaces:NTF { - \let:NN \peek_execute_branches: \peek_execute_branches_charcode: - \peek_token_generic:NNTF \peek_ignore_spaces_execute_branches: -} -\def_new:Npn \peek_charcode_remove:NTF { - \peek_token_remove_generic:NNTF \peek_execute_branches_charcode: -} - -\def_new:Npn \peek_charcode_remove_ignore_spaces:NTF { - \let:NN \peek_execute_branches: \peek_execute_branches_charcode: - \peek_token_remove_generic:NNTF \peek_ignore_spaces_execute_branches: -} +\peek_def_aux:nnnn + { peek_charcode:N } + {} + { peek_token_generic:NN } + { \peek_execute_branches_charcode: } % \end{macrocode} % \end{macro} +% +% \begin{macro}[TF]{\peek_charcode_ignore_spaces:N} +% \begin{macrocode} +\peek_def_aux:nnnn + { peek_charcode_ignore_spaces:N } + { \peek_execute_branches_charcode: } + { peek_token_generic:NN } + { \peek_ignore_spaces_execute_branches: } +% \end{macrocode} % \end{macro} +% +% \begin{macro}[TF]{\peek_charcode_remove:N} +% \begin{macrocode} +\peek_def_aux:nnnn + { peek_charcode_remove:N } + {} + { peek_token_remove_generic:NN } + { \peek_execute_branches_charcode: } +% \end{macrocode} % \end{macro} +% +% \begin{macro}[TF]{\peek_charcode_remove_ignore_spaces:N} +% \begin{macrocode} +\peek_def_aux:nnnn + { peek_charcode_remove_ignore_spaces:N } + { \peek_execute_branches_charcode: } + { peek_token_remove_generic:NN } + { \peek_ignore_spaces_execute_branches:} +% \end{macrocode} % \end{macro} % -% \begin{macro}{\peek_ignore_spaces_aux:} -% \begin{macro}{\peek_ignore_spaces_execute_branches:} +% \begin{macro}{\peek_ignore_spaces_aux:, +% \peek_ignore_spaces_execute_branches:} % Throw away a space token and search again. We could define this in % a more devious way where the auxiliary function gobbles the space % token but then what do we do if we decide that a certain function @@ -2003,53 +1856,33 @@ % ignores |a|'s and |b|'s! Or maybe different kinds of ``funny % spaces''\dots{} Therefore I have decided to use this version which % uses |\tex_afterassignment:D| to call the auxiliary function after -% the next token has been removed by |\let:NN|. That way it is +% the next token has been removed by |\cs_set_eq:NN|. That way it is % easily extensible. % \begin{macrocode} -\def_new:Npn \peek_ignore_spaces_aux: { +\cs_new_nopar:Npn \peek_ignore_spaces_aux: { \peek_after:NN \peek_ignore_spaces_execute_branches: } -\def_new:Npn \peek_ignore_spaces_execute_branches: { +\cs_new_nopar:Npn \peek_ignore_spaces_execute_branches: { \token_if_eq_meaning:NNTF \l_peek_token \c_space_token { \tex_afterassignment:D \peek_ignore_spaces_aux: - \let:NN \peek_tmp:w + \cs_set_eq:NN \peek_tmp:w } \peek_execute_branches: } % \end{macrocode} % \end{macro} -% \end{macro} -% -% -% % % \begin{macrocode} %</initex|package> +% \end{macrocode} +% +% \begin{macrocode} %<*showmemory> \showMemUsage %</showmemory> % \end{macrocode} % -% \endinput -% -% $Log$ -% Revision 1.6 2006/03/20 18:26:40 braams -% Updated the copyright notice (2006) and demoted all implementation -% sections to subsections and so on to clean up the toc for source3.tex -% -% Revision 1.5 2006/01/19 22:33:53 morten -% Minor changes in \char_set_XXXcode:nn functions. -% -% Revision 1.4 2006/01/04 01:28:06 morten -% Fixed \peek_execute_branches_charcode: properly. -% -% Revision 1.3 2005/12/29 12:17:32 morten -% Fixed \peek_execute_branches_charcode: plus minor bugs elsewhere -% -% Revision 1.2 2005/12/27 15:48:41 morten -% Fixing initial boo-boos. Updated documentation to reflect current code -% included -% -% Revision 1.1 2005/12/27 09:54:58 morten -% New module +% \end{implementation} +% \PrintIndex % +% \endinput diff --git a/Master/texmf-dist/source/latex/expl3/l3toks.dtx b/Master/texmf-dist/source/latex/expl3/l3toks.dtx index a5d78d7386c..e5575678f27 100644 --- a/Master/texmf-dist/source/latex/expl3/l3toks.dtx +++ b/Master/texmf-dist/source/latex/expl3/l3toks.dtx @@ -1,5 +1,5 @@ % \iffalse -%% File: l3toks.dtx Copyright (C) 1990-2006 LaTeX3 project +%% File: l3toks.dtx Copyright (C) 1990-2009 LaTeX3 project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this @@ -17,7 +17,7 @@ %% %% The development version of the bundle can be found at %% -%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/ +%% http://www.latex-project.org/svnroot/experimental/trunk/ %% %% for those people who are interested. %% @@ -36,7 +36,7 @@ \RequirePackage{l3names} %</driver|package> %\fi -\GetIdInfo$Id: l3toks.dtx 728 2008-01-01 16:11:58Z morten $ +\GetIdInfo$Id: l3toks.dtx 1362 2009-05-28 20:19:21Z joseph $ {L3 Experimental Token Registers} %\iffalse %<*driver> @@ -44,9 +44,9 @@ \ProvidesFile{\filename.\filenameext} [\filedate\space v\fileversion\space\filedescription] %\iffalse -\documentclass{l3doc} +\documentclass[full]{l3doc} \begin{document} -\DocInput{\filename.\filenameext} +\DocInput{l3toks.dtx} \end{document} %</driver> % \fi @@ -60,70 +60,124 @@ % \date{\filedate} % \maketitle % -% \section {Token Registers} +% \begin{documentation} % -% There is a second form beside token list pointers in which \LaTeX3 +% There is a second form beside token list variables 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 +% token list variables we have an accessing function as one can see % below. % -% The main difference between \m{toks} (token registers) and \m{tlp} (token -% list pointers) is their behavior regarding expansion. While \m{tlp}'s +% The main difference between \m{toks} (token registers) and \m{tl var.}~(token +% list variable) is their behavior regarding expansion. While \m{tl vars} % expand fully (i.e., until only unexpandable tokens are left) inside -% an argument that is subject to expansion (i.e., denote by |x|) +% an argument that is subject to expansion (i.e., denoted by |x|) % \m{toks}'s expand always only up to one level, i.e., passing their % contents without further expansion. % -% \subsection{Functions} -% -% \begin{function}{% -% \toks_new:N | -% \toks_new:c | -% \toks_new_l:N} +% There are fewer restrictions on the contents of a token register over +% a token list variable. So while \meta{token list} is used to describe +% the contents of both of these, bear in mind that slightly different lists +% of tokens are allowed in each case. The best (only?) example is that a +% \meta{toks} can contain the "#" character (i.e., characters of catcode 6), +% whereas a \meta{tl var.}~will require its input to be sanitised before that is +% possible. +% +% If you're not sure which to use between a \meta{tl var.}~or a \meta{toks}, +% consider what data you're trying to hold. If you're dealing with function +% parameters involving "#", or building some sort of data structure +% then you probably want a \meta{toks} (e.g., \file{l3prop} uses \meta{toks} +% to store its property lists). +% +% If you're storing ad-hoc data for later use (possibly from direct user +% input) then usually a \meta{tl var.}~will be what you want. +% +% \section{Allocation and use} +% +% \begin{function}{ \toks_new:N | +% \toks_new:c | +%^^A \toks_new_l:N | +% } % \begin{syntax} % "\toks_new:N" <toks> % \end{syntax} % Defines <toks> to be a new token list register. +%^^A "\toks_new_l:N" is only defined in the \LaTeX3 kernel. % \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:Nd | -% \toks_set:Nf | -% \toks_set:Nx | -% \toks_set:cn | -% \toks_set:co | -% \toks_set:cf | -% \toks_set:cx | -% \toks_gset:Nn | -% \toks_gset:No | -% \toks_gset:Nx} +% \begin{function}{ \toks_use:N | \toks_use:c } +% \begin{syntax} +% "\toks_use:N" <toks> +% \end{syntax} +% Accesses the contents of <toks>. Contrary to token list variables +% <toks> can't be access simply by calling them directly. +% \begin{texnote} +% Something like "\the" <toks>. +% \end{texnote} +% \end{function} +% +% \begin{function}{ \toks_set:Nn | +% \toks_set:NV | +% \toks_set:Nv | +% \toks_set:No | +% \toks_set:Nx | +% \toks_set:Nd | +% \toks_set:Nf | +% \toks_set:cn | +% \toks_set:co | +% \toks_set:cV | +% \toks_set:cv | +% \toks_set:cx | +% \toks_set:cd | +% \toks_set:cf } % \begin{syntax} -% "\toks_set:Nn" <toks> "{"<token list>"}" +% "\toks_set:Nn" <toks> \Arg{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. +% Defines <toks> to hold the token list <token list>. % \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 +% \Arg{token list} but all other functions have no counterpart in +% plain \TeX. Additionally the functions above the global variants described +% below 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{function}{ \toks_gset:Nn | +% \toks_gset:NV | +% \toks_gset:No | +% \toks_gset:Nx | +% \toks_gset:cn | +% \toks_gset:cV | +% \toks_gset:co | +% \toks_gset:cx } +% \begin{syntax} +% "\toks_gset:Nn" <toks> \Arg{token list} +% \end{syntax} +% Defines <toks> to globally hold the token list <token list>. +% \end{function} +% +% \begin{function}{ \toks_set_eq:NN | +% \toks_set_eq:cN | +% \toks_set_eq:Nc | +% \toks_set_eq:cc } +% \begin{syntax} +% "\toks_set_eq:NN" <toks1> <toks2> +% \end{syntax} +% Set <toks1> to the value of <toks2>. Don't try to use +% "\toks_set:Nn" for this purpose if the second argument is also a +% token register. +% \end{function} +% +% \begin{function}{ \toks_gset_eq:NN | +% \toks_gset_eq:cN | +% \toks_gset_eq:Nc | +% \toks_gset_eq:cc } % \begin{syntax} % "\toks_gset_eq:NN" <toks1> <toks2> % \end{syntax} @@ -132,325 +186,251 @@ % token register. % \end{function} % -% \begin{function}{% -% \toks_clear:N | -% \toks_gclear:N | -% } +% \begin{function}{ \toks_clear:N | +% \toks_clear:c | +% \toks_gclear:N | +% \toks_gclear:c } % \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_put_right:No | -% \toks_put_right:Nx | -% \toks_gput_right:Nn | -% \toks_gput_right:No | -% \toks_gput_right:Nx | -% } +% \begin{function}{ \toks_use_clear:N | +% \toks_use_clear:c | +% \toks_use_gclear:N | +% \toks_use_gclear:c } % \begin{syntax} -% "\toks_put_left:Nn" <toks> "{"<token list>"}" +% "\toks_use_clear:N" <toks> % \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. +% 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} % -% \begin{function}{\toks_use:N} +% \begin{function}{ \toks_show:N | \toks_show:c} % \begin{syntax} -% "\toks_use:N" <toks> +% "\toks_show:N" <toks> % \end{syntax} -% Accesses the contents of <toks>. Contrary to token list pointers -% <toks> can't be access simply by calling them directly. +% Displays the contents of <toks> in the terminal output and log file. +% "#" signs in the <toks> will be shown doubled. % \begin{texnote} -% Something like \tn{the} <toks>. +% Something like "\showthe" <toks>. % \end{texnote} % \end{function} % -% \begin{function}{\toks_use_clear:N | -% \toks_use_gclear:N} +% \section{Adding to the contents of token registers} +% +% \begin{function}{ \toks_put_left:Nn | +% \toks_put_left:NV | +% \toks_put_left:No | +% \toks_put_left:Nx | +% \toks_put_left:cn | +% \toks_put_left:cV | +% \toks_put_left:co } % \begin{syntax} -% "\toks_use_clear:N" <toks> +% "\toks_put_left:Nn" <toks> \Arg{token list} % \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. +% These functions will append <token list> to the left of +% <toks>. Assignment is done locally. If possible +% append to the right since this operation is faster. % \end{function} % -% \subsection{Predicates and conditionals} +% \begin{function}{ \toks_gput_left:Nn | +% \toks_gput_left:NV | +% \toks_gput_left:No | +% \toks_gput_left:Nx | +% \toks_gput_left:cn | +% \toks_gput_left:cV | +% \toks_gput_left:co } +% \begin{syntax} +% "\toks_gput_left:Nn" <toks> \Arg{token list} +% \end{syntax} +% These functions will append <token list> to the left of +% <toks>. Assignment is done globally. If possible +% append to the right since this operation is faster. +% \end{function} % -% \begin{function}{ -% \toks_if_empty_p:N| -% \toks_if_empty:NTF| -% \toks_if_empty:NT | -% \toks_if_empty:NF| -% \toks_if_empty_p:c| -% \toks_if_empty:cTF | -% \toks_if_empty:cT | -% \toks_if_empty:cF -% } +% \begin{function}{ \toks_put_right:Nn | +% \toks_put_right:NV | +% \toks_put_right:No | +% \toks_put_right:Nx | +% \toks_put_right:cV | +% \toks_put_right:cn | +% \toks_put_right:co } +% \begin{syntax} +% "\toks_put_right:Nn" <toks> \Arg{token list} +% \end{syntax} +% These functions will append <token list> to the right of +% <toks>. Assignment is done locally. +% \end{function} +% +% \begin{function}{ \toks_put_right:Nf } +% \begin{syntax} +% "\toks_put_right:Nf" <toks> \Arg{token list} +% \end{syntax} +% Variant of the above. |:Nf| is used by |template.dtx| and will +% perhaps be moved to that package. +% \end{function} +% +% \begin{function}{ \toks_gput_right:Nn | +% \toks_gput_right:NV | +% \toks_gput_right:No | +% \toks_gput_right:Nx | +% \toks_gput_right:cn | +% \toks_gput_right:cV | +% \toks_gput_right:co } % \begin{syntax} -% "\toks_if_empty:NTF" <toks> "{"<true code>"}{"<false code>"}" +% "\toks_gput_right:Nn" <toks> \Arg{token list} % \end{syntax} -% Tests if <toks> is empty. +% These functions will append <token list> to the right of +% <toks>. Assignment is done globally. % \end{function} % -% \subsection{Variable and constants} +% +% \section{Predicates and conditionals} +% +% \begin{function}{ \toks_if_empty_p:N / (EXP) | +% \toks_if_empty:N / (EXP)(TF) | +% \toks_if_empty_p:c / (EXP) | +% \toks_if_empty:c / (EXP)(TF) } +% \begin{syntax} +% "\toks_if_empty:NTF" <toks> \Arg{true code} \Arg{false code} +% \end{syntax} +% Expandable test for whether <toks> is empty. +% \end{function} +% +% \begin{function}{ \toks_if_eq:NN / (TF)(EXP) | +% \toks_if_eq:Nc / (TF)(EXP) | +% \toks_if_eq:cN / (TF)(EXP) | +% \toks_if_eq:cc / (TF)(EXP) | +% \toks_if_eq_p:NN / (EXP) | +% \toks_if_eq_p:cN / (EXP) | +% \toks_if_eq_p:Nc / (EXP) | +% \toks_if_eq_p:cc / (EXP) } +% \begin{syntax} +% "\toks_if_eq:NNTF" <toks1> <toks2> \Arg{true code} \Arg{false code} +% \end{syntax} +% Expandably tests if <toks1> and <toks2> are equal. +% \end{function} +% +% \section{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 -% } +% \begin{variable}{ \l_tmpa_toks | +% \l_tmpb_toks | +% \l_tmpc_toks | +% \g_tmpa_toks | +% \g_tmpb_toks | +% \g_tmpc_toks } % Scratch register for immediate use. They are not used by conditionals % or predicate functions. % \end{variable} % -% \subsubsection{Internal functions} +% \begin{variable}{ \l_tl_replace_toks } +% A placeholder for contents of functions replacing contents of strings. +% \end{variable} % -% \begin{function}{\toks_put_left_aux:w} -% Used by "\toks_put_left:Nn" and its variants. -% \end{function} +% \end{documentation} % -% \begin{function}{\tex_toksdef: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{} +% \begin{implementation} % -% \subsection{The Implementation} +% \section{\pkg{l3toks} 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>\ProvidesExplPackage -%<package> {\filename}{\filedate}{\fileversion}{\filedescription} -%<package&check>\RequirePackage{l3chk}\par -%<package>\RequirePackage{l3expan}\par +%<*package> +\ProvidesExplPackage + {\filename}{\filedate}{\fileversion}{\filedescription} +\package_check_loaded_expl: +%</package> %<*initex|package> % \end{macrocode} % -% \begin{macro}{\toks_new:N} -% \begin{macro}{\toks_new_l:N} -% \begin{macro}{\toks_new:c} -% Allocates a new token register. This function is already defined above. +% \subsection{Allocation and use} +% +% \begin{macro}{\toks_new:N,\toks_new:c} +%^^A \begin{macro}{\toks_new_l:N} +% Allocates a new token register. % \begin{macrocode} %<*initex> \alloc_setup_type:nnn {toks} \c_zero \c_max_register_num -\def_new:Npn \toks_new:N #1{\alloc_reg:NnNN g {toks} \tex_toksdef:D #1} -\def_new:Npn \toks_new_l:N #1{\alloc_reg:NnNN l {toks} \tex_toksdef:D #1} +\cs_new_nopar:Npn \toks_new:N #1 { \alloc_reg:NnNN g {toks} \tex_toksdef:D #1 } +\cs_new_nopar:Npn \toks_new_l:N #1 { \alloc_reg:NnNN l {toks} \tex_toksdef:D #1 } %</initex> -%<package>\let:NN \toks_new:N \newtoks % nick from LaTeX for the moment -\def_new:Npn \toks_new:c {\exp_args:Nc\toks_new:N} +%<package>\cs_set_eq:NN \toks_new:N \newtoks % nick from LaTeX for the moment +\cs_generate_variant:Nn \toks_new:N {c} % \end{macrocode} % \end{macro} -% \end{macro} -% \end{macro} +%^^A \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} % \begin{macro}{\toks_use:c} -% This function just returns the contents of a token register. +% This function returns the contents of a token register. % \begin{macrocode} -\let_new:NN \toks_use:N \the_internal:D -\def_new:Npn \toks_use:c {\exp_args:Nc\toks_use:N} -% \end{macrocode} -% \end{macro} -% \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} +\cs_new_eq:NN \toks_use:N \tex_the:D +\cs_generate_variant:Nn \toks_use:N {c} % \end{macrocode} % \end{macro} % \end{macro} % -% \begin{macro}{\toks_put_left:Nn} -% \begin{macro}{\toks_put_left:No} -% \begin{macro}{\toks_gput_left:Nn} -% \begin{macro}{\toks_gput_left:Nx} -% \begin{macro}{\toks_put_left_aux:w} -% |\toks_put_left:Nn |\zz{toks}\zv{stuff\/} adds the tokens of -% \textsl{stuff} on the `left-side' of the token register -% \m{toks}. |\toks_put_left:No| does the same, but expands the -% tokens once. We need to look out for brace stripping so we add a -% token, which is then later removed. -% \begin{macrocode} -\def_new:Npn \toks_put_left:Nn #1{ - \exp_after:NN\toks_put_left_aux:w\exp_after:NN\q_mark - \toks_use:N #1\q_stop #1} -\def_new:Npn \toks_put_left:No {\exp_args:NNo \toks_put_left:Nn} -\def_new:Npn \toks_gput_left:Nn { -%<*check> - \pref_global_chk: -%</check> -%<-check> \pref_global:D - \toks_put_left:Nn} -\def_new:Npn \toks_gput_left:Nx {\exp_args:NNx \toks_gput_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}. We make sure to -% remove the token we inserted earlier. -% \begin{macrocode} -\def_long_new:Npn \toks_put_left_aux:w #1\q_stop #2#3{ - #2\exp_after:NN{\use_arg_i:nn{#3}#1} -%<*check> - \chk_local_or_pref_global:N #2 -%</check> -} -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\toks_put_right:Nn} -% \begin{macro}{\toks_gput_right:Nn} -% \begin{macro}{\toks_put_right:No} -% \begin{macro}{\toks_put_right:Nd} -% \begin{macro}{\toks_put_right:Nf} -% \begin{macro}{\toks_put_right:Nx} -% \begin{macro}{\toks_gput_right:No} -% \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} -%<check>\def_new:Npn \toks_put_right:No {\exp_args:NNo \toks_put_right:Nn } -%<-check>\def_long_new:Npn\toks_put_right:No#1#2{#1\exp_after:NN\exp_after:NN -%<-check>\exp_after:NN{\exp_after:NN\toks_use:N\exp_after:NN #1#2}} -%<check>\def_new:Npn \toks_put_right:Nd {\exp_args:NNd \toks_put_right:Nn } -%<-check>\def_long_new:Npn\toks_put_right:Nd#1#2{ -%<-check> \exp_after:NN\toks_put_right:No\exp_after:NN#1\exp_after:NN{#2}} -% \end{macrocode} -% We implement |\toks_put_right:Nf| by hand because I think I might -% use it in the \textsf{l3keyval} module in which case it is going to -% be used a lot. -% \begin{macrocode} -%<check>\def_new:Npn \toks_put_right:Nf {\exp_args:NNf \toks_put_right:Nn } -%<-check>\def_long_new:Npn \toks_put_right:Nf #1#2{ -%<-check> #1\exp_after:NN\exp_after:NN\exp_after:NN{ -%<-check> \exp_after:NN\toks_use:N\exp_after:NN #1\int_to_roman:w -`0#2}} -\def_new:Npn \toks_put_right:Nx {\exp_args:NNx \toks_put_right:Nn } -\def_new:Npn \toks_gput_right:No {\exp_args:NNo\toks_gput_right:Nn} -\def_new:Npn \toks_gput_right:Nx {\exp_args:NNx\toks_gput_right:Nn} -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% % \begin{macro}{\toks_set:Nn} +% \begin{macro}{\toks_set:NV} +% \begin{macro}{\toks_set:Nv} % \begin{macro}{\toks_set:No} +% \begin{macro}{\toks_set:Nx} % \begin{macro}{\toks_set:Nd} % \begin{macro}{\toks_set:Nf} -% \begin{macro}{\toks_set:Nx} % \begin{macro}{\toks_set:cn} % \begin{macro}{\toks_set:co} -% \begin{macro}{\toks_set:cf} +% \begin{macro}{\toks_set:cV} +% \begin{macro}{\toks_set:cv} % \begin{macro}{\toks_set:cx} +% \begin{macro}{\toks_set:cd} +% \begin{macro}{\toks_set:cf} % |\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} +\cs_new_nopar:Npn \toks_set:Nn #1 { \chk_local:N #1 #1 } +\cs_generate_variant:Nn \toks_set:Nn {No,Nd,Nf} %</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. +% We implement |\toks_set:No|/|d|/|f| by hand when not checking because this +% is going to be used \emph{extensively} in keyval processing! +% TODO: (Will) Can we get some numbers published on how necessary this is? +% On the other hand I'm happy to believe Morten |:)| % \begin{macrocode} -%<-check> \let_new:NN \toks_set:Nn\use_noop: -%<-check> \def_long_new:Npn \toks_set:No#1#2{#1\exp_after:NN{#2}} -%<-check> \def_long_new:Npn \toks_set:Nd#1#2{ -%<-check> #1\exp_after:NN\exp_after:NN\exp_after:NN{#2}} -%<check> \def_new:Npn \toks_set:No {\exp_args:NNo \toks_set:Nn} -%<check> \def_new:Npn \toks_set:Nd {\exp_args:NNd \toks_set:Nn} -\def_new:Npn \toks_set:Nx {\exp_args:NNx \toks_set:Nn} +%<*!check> +\cs_new_eq:NN \toks_set:Nn \prg_do_nothing: +\cs_new:Npn \toks_set:NV #1#2 { + #1 \exp_after:wN { \int_to_roman:w -`0 \exp_eval_register:N #2 } +} +\cs_new:Npn \toks_set:Nv #1#2 { + #1 \exp_after:wN { \int_to_roman:w -`0 \exp_eval_register:c {#2} } +} +\cs_new:Npn \toks_set:No #1#2 { #1 \exp_after:wN {#2} } +\cs_new:Npn \toks_set:Nd #1#2 { + #1 \exp_after:wN \exp_after:wN \exp_after:wN {#2} +} +\cs_new:Npn \toks_set:Nf #1#2 { + #1 \exp_after:wN { \int_to_roman:w -`0#2 } +} +%</!check> % \end{macrocode} -% We implement |\toks_set:Nf| by hand when not checking because this -% is going to be used \emph{extensively} in keyval processing! +% % \begin{macrocode} -%<check>\def_new:Npn \toks_set:Nf {\exp_args:NNf \toks_set:Nn} -%<-check>\def_long_new:Npn\toks_set:Nf #1#2{ -%<-check> #1\exp_after:NN{\int_to_roman:w -`0#2}} -\def_new:Npn \toks_set:cf {\exp_args:Nc\toks_set:Nf} -\def_new:Npn \toks_set:cn {\exp_args:Nc\toks_set:Nn} -\def_new:Npn \toks_set:co {\exp_args:Nc\toks_set:No} -\def_new:Npn \toks_set:cx {\exp_args:Nc\toks_set:Nx} +\cs_generate_variant:Nn \toks_set:Nn {Nx,cn,cV,cv,co,cx,cd,cf} % \end{macrocode} % \end{macro} % \end{macro} @@ -461,24 +441,25 @@ % \end{macro} % \end{macro} % \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} % % \begin{macro}{\toks_gset:Nn} +% \begin{macro}{\toks_gset:NV} % \begin{macro}{\toks_gset:No} % \begin{macro}{\toks_gset:Nx} % \begin{macro}{\toks_gset:cn} +% \begin{macro}{\toks_gset:cV} % \begin{macro}{\toks_gset:co} % \begin{macro}{\toks_gset:cx} % 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} -\def_new:Npn \toks_gset:cn {\exp_args:Nc \toks_gset:Nn} -\def_new:Npn \toks_gset:co {\exp_args:Nc \toks_gset:No} -\def_new:Npn \toks_gset:cx {\exp_args:Nc \toks_gset:Nx} +%<check>\cs_new_nopar:Npn \toks_gset:Nn #1 { \chk_global:N #1 \pref_global:D #1 } +%<!check>\cs_new_eq:NN \toks_gset:Nn \pref_global:D +\cs_generate_variant:Nn \toks_gset:Nn {NV,No,Nx,cn,cV,co,cx} % \end{macrocode} % \end{macro} % \end{macro} @@ -486,6 +467,8 @@ % \end{macro} % \end{macro} % \end{macro} +% \end{macro} +% \end{macro} % % \begin{macro}{\toks_set_eq:NN} % \begin{macro}{\toks_set_eq:Nc} @@ -499,23 +482,23 @@ % 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} +\cs_new_nopar:Npn\toks_set_eq:NN #1#2 { + \chk_local:N #1 + \chk_var_or_const:N #2 + #1 #2 +} +\cs_new_nopar: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 -\def_new:Npn \toks_set_eq:Nc {\exp_args:NNc\toks_set_eq:NN} -\def_new:Npn \toks_set_eq:cN {\exp_args:Nc\toks_set_eq:NN} -\def_new:Npn \toks_set_eq:cc {\exp_args:Ncc\toks_set_eq:NN} -\def_new:Npn \toks_gset_eq:Nc {\exp_args:NNc\toks_gset_eq:NN} -\def_new:Npn \toks_gset_eq:cN {\exp_args:Nc\toks_gset_eq:NN} -\def_new:Npn \toks_gset_eq:cc {\exp_args:Ncc\toks_gset_eq:NN} +%<*!check> +\cs_new_eq:NN \toks_set_eq:NN \prg_do_nothing: +\cs_new_eq:NN \toks_gset_eq:NN \pref_global:D +%</!check> +\cs_generate_variant:Nn \toks_set_eq:NN {Nc,cN,cc} +\cs_generate_variant:Nn \toks_gset_eq:NN {Nc,cN,cc} % \end{macrocode} % \end{macro} % \end{macro} @@ -526,31 +509,126 @@ % \end{macro} % \end{macro} % -% \begin{macro}{\toks_if_empty_p:N} -% \begin{macro}{\toks_if_empty_p:c} -% \begin{macro}{\toks_if_empty:NTF} -% \begin{macro}{\toks_if_empty:cTF} -% \begin{macro}{\toks_if_empty:NT} -% \begin{macro}{\toks_if_empty:cT} -% \begin{macro}{\toks_if_empty:NF} -% \begin{macro}{\toks_if_empty:cF} -% |\toks_if_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}. This test had the advantage of being -% expandable. Otherwise one has to do an |x| type expansion in order -% to prevent problems with parameter tokens. +% \begin{macro}{\toks_clear:N,\toks_gclear:N,\toks_clear:c,\toks_gclear:c} +% These functions clear a token register, either locally or globally. +% \begin{macrocode} +\cs_new_nopar:Npn \toks_clear:N #1 { + #1\c_empty_toks +%<check>\chk_local_or_pref_global:N #1 +} +% \end{macrocode} +% +% \begin{macrocode} +\cs_new_nopar:Npn \toks_gclear:N { +%<check> \pref_global_chk: +%<!check> \pref_global:D + \toks_clear:N +} +% \end{macrocode} +% +% \begin{macrocode} +\cs_generate_variant:Nn \toks_clear:N {c} +\cs_generate_variant:Nn \toks_gclear:N {c} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\toks_use_clear:N} +% \begin{macro}{\toks_use_clear:c} +% \begin{macro}{\toks_use_gclear:N} +% \begin{macro}{\toks_use_gclear:c} +% 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. +% \begin{macrocode} +\cs_new_nopar:Npn \toks_use_clear:N #1 { + \exp_last_unbraced:NNV \toks_clear:N #1 #1 +} +% \end{macrocode} +% +% \begin{macrocode} +\cs_new_nopar:Npn \toks_use_gclear:N { +%<check> \pref_global_chk: +%<!check> \pref_global:D + \toks_use_clear:N +} +% \end{macrocode} +% +% \begin{macrocode} +\cs_generate_variant:Nn \toks_use_clear:N {c} +\cs_generate_variant:Nn \toks_use_gclear:N {c} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\toks_show:N} +% \begin{macro}{\toks_show:c} +% This function shows the contents of a token register on the terminal. +% TODO: this is not pretty when the argument is a control sequence that doesn't exist! +% \begin{macrocode} +\cs_new_eq:NN \toks_show:N \tex_showthe:D +\cs_generate_variant:Nn \toks_show:N {c} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \subsection{Adding to token registers' contents} +% +% \begin{macro}{\toks_put_left:Nn} +% \begin{macro}{\toks_put_left:NV} +% \begin{macro}{\toks_put_left:No} +% \begin{macro}{\toks_put_left:Nx} +% \begin{macro}{\toks_put_left:cn} +% \begin{macro}{\toks_put_left:cV} +% \begin{macro}{\toks_put_left:co} +% \begin{macro}{\toks_gput_left:Nn} +% \begin{macro}{\toks_gput_left:NV} +% \begin{macro}{\toks_gput_left:No} +% \begin{macro}{\toks_gput_left:Nx} +% \begin{macro}{\toks_gput_left:cn} +% \begin{macro}{\toks_gput_left:cV} +% \begin{macro}{\toks_gput_left:co} +% \begin{macro}[aux]{\toks_put_left_aux:w} +% |\toks_put_left:Nn |\meta{toks}\meta{stuff\/} adds the tokens of +% \textsl{stuff} on the `left-side' of the token register +% \m{toks}. |\toks_put_left:No| does the same, but expands the +% tokens once. We need to look out for brace stripping so we add a +% token, which is then later removed. +% \begin{macrocode} +\cs_new_nopar:Npn \toks_put_left:Nn #1 { + \exp_after:wN \toks_put_left_aux:w \exp_after:wN \q_mark + \toks_use:N #1 \q_stop #1 +} +% \end{macrocode} +% +% \begin{macrocode} +\cs_generate_variant:Nn \toks_put_left:Nn {NV,No,Nx,cn,co,cV} +% \end{macrocode} +% +% \begin{macrocode} +\cs_new_nopar:Npn \toks_gput_left:Nn { +%<check> \pref_global_chk: +%<!check> \pref_global:D + \toks_put_left:Nn +} +% \end{macrocode} +% +% \begin{macrocode} +\cs_generate_variant:Nn \toks_gput_left:Nn {NV,No,Nx,cn,cV,co} +% \end{macrocode} +% A helper function for |\toks_put_left:Nn|. Its arguments are +% subsequently the tokens of \meta{stuff\/}, the token register +% \meta{toks} and the current contents of \meta{toks}. We make sure to +% remove the token we inserted earlier. % \begin{macrocode} -\def_new:Npn\toks_if_empty_p:N#1{ - \if:w \tlist_if_empty_p:o{\toks_use:N #1} - \c_true - \else: - \c_false - \fi: +\cs_new:Npn \toks_put_left_aux:w #1\q_stop #2#3 { + #2 \exp_after:wN { \use_i:nn {#3} #1 } +%<check> \chk_local_or_pref_global:N #2 } -\def_test_function_new:npn{toks_if_empty:N}#1{\if:w \toks_if_empty_p:N #1} -\def_new:Npn\toks_if_empty:cTF{\exp_args:Nc\toks_if_empty:NTF} -\def_new:Npn\toks_if_empty:cT{\exp_args:Nc\toks_if_empty:NT} -\def_new:Npn\toks_if_empty:cF{\exp_args:Nc\toks_if_empty:NF} % \end{macrocode} % \end{macro} % \end{macro} @@ -560,49 +638,61 @@ % \end{macro} % \end{macro} % \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} % -% \begin{macro}{\toks_if_eq:NNTF} -% \begin{macro}{\toks_if_eq:NNT} -% \begin{macro}{\toks_if_eq:NNF} -% \begin{macro}{\toks_if_eq:NcTF} -% \begin{macro}{\toks_if_eq:NcT} -% \begin{macro}{\toks_if_eq:NcF} -% \begin{macro}{\toks_if_eq:cNTF} -% \begin{macro}{\toks_if_eq:cNT} -% \begin{macro}{\toks_if_eq:cNF} -% \begin{macro}{\toks_if_eq:ccTF} -% \begin{macro}{\toks_if_eq:ccT} -% \begin{macro}{\toks_if_eq:ccF} -% \begin{macro}{\toks_if_eq_p:NN} -% \begin{macro}{\toks_if_eq_p:cN} -% \begin{macro}{\toks_if_eq_p:Nc} -% \begin{macro}{\toks_if_eq_p:cc} -% This function test whether two token registers contain the same. +% \begin{macro}{\toks_put_right:Nn} +% \begin{macro}{\toks_put_right:NV} +% \begin{macro}{\toks_put_right:No} +% \begin{macro}{\toks_put_right:Nx} +% \begin{macro}{\toks_put_right:cn} +% \begin{macro}{\toks_put_right:cV} +% \begin{macro}{\toks_put_right:co} +% \begin{macro}{\toks_gput_right:Nn} +% \begin{macro}{\toks_gput_right:NV} +% \begin{macro}{\toks_gput_right:No} +% \begin{macro}{\toks_gput_right:Nx} +% \begin{macro}{\toks_gput_right:cn} +% \begin{macro}{\toks_gput_right:cV} +% \begin{macro}{\toks_gput_right:co} +% These macros add a list of tokens to the right of a token register. % \begin{macrocode} -\def_new:NNn \toks_if_eq:NNTF 2 { - \tlist_if_eq:xxTF{\toks_use:N #1}{\toks_use:N #2} +\cs_new:Npn \toks_put_right:Nn #1#2 { + #1 \exp_after:wN { \toks_use:N #1 #2 } +%<check> \chk_local_or_pref_global:N #1 } -\def_new:NNn \toks_if_eq:NNT 2 { - \tlist_if_eq:xxT{\toks_use:N #1}{\toks_use:N #2} +% \end{macrocode} +% +% \begin{macrocode} +\cs_new_nopar:Npn \toks_gput_right:Nn { +%<check> \pref_global_chk: +%<!check> \pref_global:D + \toks_put_right:Nn } -\def_new:NNn \toks_if_eq:NNF 2 { - \tlist_if_eq:xxF{\toks_use:N #1}{\toks_use:N #2} +% \end{macrocode} +% A couple done by hand for speed. +% \begin{macrocode} +%<check>\cs_generate_variant:Nn \toks_put_right:Nn {No} +%<*!check> +\cs_new:Npn \toks_put_right:NV #1#2 { + #1 \exp_after:wN \exp_after:wN \exp_after:wN { + \exp_after:wN \toks_use:N \exp_after:wN #1 + \int_to_roman:w -`0 \exp_eval_register:N #2 + } } -\def_new:Npn \toks_if_eq:NcTF {\exp_args:NNc \toks_if_eq:NNTF} -\def_new:Npn \toks_if_eq:NcT {\exp_args:NNc \toks_if_eq:NNT} -\def_new:Npn \toks_if_eq:NcF {\exp_args:NNc \toks_if_eq:NNF} -\def_new:Npn \toks_if_eq:cNTF {\exp_args:Nc \toks_if_eq:NNTF} -\def_new:Npn \toks_if_eq:cNT {\exp_args:Nc \toks_if_eq:NNT} -\def_new:Npn \toks_if_eq:cNF {\exp_args:Nc \toks_if_eq:NNF} -\def_new:Npn \toks_if_eq:ccTF {\exp_args:Ncc \toks_if_eq:NNTF} -\def_new:Npn \toks_if_eq:ccT {\exp_args:Ncc \toks_if_eq:NNT} -\def_new:Npn \toks_if_eq:ccF {\exp_args:Ncc \toks_if_eq:NNF} -\def_new:NNn \toks_if_eq_p:NN 2 { - \tlist_if_eq_p:xx {\toks_use:N #1} {\toks_use:N #2} +\cs_new:Npn \toks_put_right:No #1#2 { + #1 \exp_after:wN \exp_after:wN \exp_after:wN { + \exp_after:wN \toks_use:N \exp_after:wN #1 #2 + } } -\def_new:Npn \toks_if_eq_p:cN {\exp_args:Nc \toks_if_eq_p:NN} -\def_new:Npn \toks_if_eq_p:Nc {\exp_args:NNc \toks_if_eq_p:NN} -\def_new:Npn \toks_if_eq_p:cc {\exp_args:Ncc \toks_if_eq_p:NN} +%</!check> +\cs_generate_variant:Nn \toks_put_right:Nn {Nx,cn,cV,co} +\cs_generate_variant:Nn \toks_gput_right:Nn {NV,No,Nx,cn,cV,co} % \end{macrocode} % \end{macro} % \end{macro} @@ -618,18 +708,73 @@ % \end{macro} % \end{macro} % \end{macro} +% +% \begin{macro}{\toks_put_right:Nf} +% We implement |\toks_put_right:Nf| by hand because I think I might +% use it in the \textsf{l3keyval} module in which case it is going to +% be used a lot. +% \begin{macrocode} +%<check>\cs_generate_variant:Nn \toks_put_right:Nn {Nf} +%<*!check> +\cs_new:Npn \toks_put_right:Nf #1#2 { + #1 \exp_after:wN \exp_after:wN \exp_after:wN { + \exp_after:wN \toks_use:N \exp_after:wN #1 \int_to_roman:w -`0#2 + } +} +%</!check> +% \end{macrocode} +% \end{macro} +% +% \subsection{Predicates and conditionals} +% +% \begin{macro}{\toks_if_empty_p:N,\toks_if_empty_p:c} +% \begin{macro}[TF]{\toks_if_empty:N,\toks_if_empty:c} +% |\toks_if_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}. This test had the advantage of being +% expandable. Otherwise one has to do an |x| type expansion in order +% to prevent problems with parameter tokens. +% \begin{macrocode} +\prg_new_conditional:Nnn \toks_if_empty:N {p,TF,T,F} { + \tl_if_empty:VTF #1 {\prg_return_true:} {\prg_return_false:} +} +% \end{macrocode} +% \begin{macrocode} +\cs_generate_variant:Nn \toks_if_empty_p:N {c} +\cs_generate_variant:Nn \toks_if_empty:NTF {c} +\cs_generate_variant:Nn \toks_if_empty:NT {c} +\cs_generate_variant:Nn \toks_if_empty:NF {c} +% \end{macrocode} % \end{macro} % \end{macro} % +% \begin{macro}{\toks_if_eq_p:NN,\toks_if_eq_p:cN,\toks_if_eq_p:Nc,\toks_if_eq_p:cc} +% \begin{macro}[TF]{\toks_if_eq:NN,\toks_if_eq:Nc,\toks_if_eq:cN,\toks_if_eq:cc} +% This function test whether two token registers have the same contents. +% \begin{macrocode} +\prg_new_conditional:Nnn \toks_if_eq:NN {p,TF,T,F} { + \tl_if_eq:xxTF {\toks_use:N #1} {\toks_use:N #2} + {\prg_return_true:} {\prg_return_false:} +} +\cs_generate_variant:Nn \toks_if_eq_p:NN {Nc,c,cc} +\cs_generate_variant:Nn \toks_if_eq:NNTF {Nc,c,cc} +\cs_generate_variant:Nn \toks_if_eq:NNT {Nc,c,cc} +\cs_generate_variant:Nn \toks_if_eq:NNF {Nc,c,cc} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \subsection{Variables and constants} +% % \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 +% Some scratch registers \ldots % \begin{macrocode} -\tex_toksdef:D \l_tmpa_toks = 255 +\tex_toksdef:D \l_tmpa_toks = 255\scan_stop: %<initex>\seq_put_right:Nn \g_toks_allocation_seq {255} \toks_new:N \l_tmpb_toks \toks_new:N \l_tmpc_toks @@ -651,81 +796,27 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}{\toks_remove_extra_brace_group:N} -% \begin{macro}{\toks_remove_extra_brace_group_aux:NNw} -% Small function for removing an extra brace group if present. Hmm, -% not really needed anymore. +% \begin{macro}{\l_tl_replace_toks} +% And here is one for tl vars. Can't define it there as the allocation +% isn't set up at that point. % \begin{macrocode} -\def_new:Npn \toks_remove_extra_brace_group:N #1{ - \exp_after:NN \toks_remove_extra_brace_group_aux:NNw - \exp_after:NN \toks_set:Nn \exp_after:NN #1 - \toks_use:N#1\q_nil -} -\def_long_new:Npn\toks_remove_extra_brace_group_aux:NNw #1#2#3\q_nil{#1#2{#3}} +\toks_new:N \l_tl_replace_toks % \end{macrocode} % \end{macro} -% \end{macro} % -% Show token usage: % \begin{macrocode} %</initex|package> +% \end{macrocode} +% +% Show token usage: +% \begin{macrocode} %<*showmemory> \showMemUsage %</showmemory> % \end{macrocode} % -% \endinput -% -% $Log$ -% Revision 1.25 2006/08/01 01:54:12 morten -% Prevent brace stripping in \toks_put_left:Nn and friends. -% -% Revision 1.24 2006/03/20 18:26:40 braams -% Updated the copyright notice (2006) and demoted all implementation -% sections to subsections and so on to clean up the toc for source3.tex -% -% Revision 1.23 2006/02/16 23:32:49 braams -% Imported \toks_put_left:No from l3messages -% -% Revision 1.22 2006/01/21 11:43:20 morten -% Tuned some of the \toks_set and \toks_put_right functions since they -% are going to be used intensively in the l3keyval module which is again -% going to be heavily used. -% -% Revision 1.21 2006/01/20 12:22:44 morten -% Minor changes plus added \toks_remove_extra_brace_group:N for l3keyval -% module -% -% Revision 1.20 2005/12/27 10:03:39 morten -% Changed RCS information retrieval -% -% Revision 1.19 2005/12/23 13:24:39 morten -% Added a few functions from template -% -% Revision 1.18 2005/12/21 20:44:04 morten -% Corrected typo. -% -% Revision 1.17 2005/12/02 15:56:48 morten -% Added some more functions and improved test for emptiness. -% -% Revision 1.16 2005/04/12 13:22:37 morten -% More functions added -% -% Revision 1.15 2005/04/07 08:18:17 morten -% Only put 255 in the toks stack when running initex -% -% Revision 1.14 2005/04/06 22:35:50 braams -% Now we have register allocation fitted -% -% Revision 1.13 2005/04/06 21:37:50 morten -% Added some more functions -% -% Revision 1.12 2005/03/15 23:39:21 braams -% Some fiddling to get it loaded by initex; needs a way to allocate -% token registers for it to work. -% -% Revision 1.11 2005/03/11 21:25:06 braams -% Changed copyright year, fixed use of RCS values; -% fixed a few typos in the documentation; -% \c_if_empty_toks had to be \c_empty_toks +% \end{implementation} +% \PrintIndex % +% \endinput + diff --git a/Master/texmf-dist/source/latex/expl3/l3vers.dtx b/Master/texmf-dist/source/latex/expl3/l3vers.dtx index b3cbde577bd..c61d07ce94c 100644 --- a/Master/texmf-dist/source/latex/expl3/l3vers.dtx +++ b/Master/texmf-dist/source/latex/expl3/l3vers.dtx @@ -1,5 +1,5 @@ % \iffalse -%% File: l3vers.dtx Copyright (C) 1990-2008 LaTeX3 project +%% File: l3vers.dtx Copyright (C) 1990-2009 LaTeX3 project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this @@ -17,7 +17,7 @@ %% %% The development version of the bundle can be found at %% -%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/ +%% http://www.latex-project.org/svnroot/experimental/trunk/ %% %% for those people who are interested. %% @@ -35,7 +35,7 @@ \RequirePackage{l3names} %</driver|package> %\fi -\GetIdInfo$Id: l3vers.dtx 769 2008-08-05 19:48:40Z morten $ +\GetIdInfo$Id: l3vers.dtx 1378 2009-06-01 19:15:56Z joseph $ {L3 Experimental LaTeX format version} %\iffalse %<*driver> @@ -43,28 +43,45 @@ \ProvidesFile{\filename.\filenameext} [\filedate\space v\fileversion\space\filedescription] %\iffalse -\documentclass{l3doc} +\documentclass[full]{l3doc} \begin{document} \DocInput{\filename.\filenameext} \end{document} %</driver> % \fi % +% \begin{documentation} +% % \section{Version Identification} % Here we identify the date and version number of this release of % \LaTeX3, and set |\tex_everyjob:D| so that it is printed at the start of % every \LaTeX3 run. % -% \StopEventually{} +% \begin{variable}{\c_format_name|\c_format_date} +% Name and date. +% \end{variable} +% +% \begin{variable}{\c_fmt_too_old} +% Age in months past "\c_format_date" after which an error is called +% during format generation. +% \end{variable} +% +% \begin{function}{\chk_format_age:w} +% Function that calculates the age of the format and calls an error if it +% is too old. +% \end{function} % +% \end{documentation} +% +% \begin{implementation} % % \begin{macro}{\c_format_name} % \begin{macro}{\c_format_date} % \begin{macrocode} %<*initex> -\def:Npn\c_format_name{Experimental~ LaTeX3} -\def:Npn\c_format_date{2008/08/05} -%^^A\def:Npx\c_format_version{--release--date--goes--here--} +\cs_set_nopar:Npn\c_format_name{Experimental~ LaTeX3} +\cs_set_nopar:Npn\c_format_date{2009/06/01} +%^^A\cs_set_nopar:Npx\c_format_version{--release--date--goes--here--} % \end{macrocode} % \end{macro} % \end{macro} @@ -74,18 +91,18 @@ % Check that the format being made is not too old. While in development % it should be a rather small number. % \begin{macrocode} -\const_new:Nn \c_fmt_too_old{12} -\def:Npn\chk_format_age:w #1/#2/#3\q_stop{ +\int_const:Nn \c_fmt_too_old{12} +\cs_set_nopar:Npn\chk_format_age:w #1/#2/#3\q_stop{ % \end{macrocode} % We just calculate the age of this file in months and give a warning % if deemed too old. % \begin{macrocode} - \num_compare:nNnT{(\tex_year:D-#1)*12+\tex_month:D-#2}>\c_fmt_too_old - {\iow_expanded_term:n{^^J + \intexpr_compare:nNnT{(\tex_year:D-#1)*12+\tex_month:D-#2}>\c_fmt_too_old + {\iow_term:x{^^J !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!^^J !~~You~are~attempting~to~make~an~experimental~LaTeX3~format~from^^J !~~source~files~that~are~more~than~ - \num_value:w\num_eval:n{\c_fmt_too_old}~months~old.^^J + \intexpr_eval:n{\c_fmt_too_old}~months~old.^^J !^^J !~~If~you~enter~<return>~to~scroll~past~this~message~then~the~format^^J !~~will~be~built,~but~please~consider~obtaining~newer~source~files^^J @@ -96,7 +113,7 @@ To~avoid~this~error~message,~obtain~new~Experimental~LaTeX3~sources.} \tex_errmessage:D{ Experimental~LaTeX3~source~files~are~more~than~ - \num_use:N\num_eval:n{\c_fmt_too_old}~months~old!} + \intexpr_eval:n{\c_fmt_too_old}~months~old!} } } % \end{macrocode} @@ -104,7 +121,7 @@ % \end{macro} % Then we execute it. % \begin{macrocode} -\exp_after:NN\chk_format_age:w\c_format_date\q_stop +\exp_after:wN\chk_format_age:w\c_format_date\q_stop % \end{macrocode} % And since it's no longer needed we remove it again. % \begin{macrocode} @@ -114,27 +131,12 @@ % This startup banner may be further modified by the code in % |ltfinal.dtx| if a patch file is present. % \begin{macrocode} -\tex_everyjob:D{\io_put_term:x{\c_format_name,~<\c_format_date>}} -\io_put_term:x{\c_format_name,~<\c_format_date>} +\tex_everyjob:D{\iow_term:x{\c_format_name,~<\c_format_date>}} +\iow_term:x{\c_format_name,~<\c_format_date>} %</initex> % \end{macrocode} % -% \endinput -% -% $Log$ -% Revision 1.5 2005/12/27 15:54:15 morten -% Changed RCS information retrieval -% -% Revision 1.4 2005/04/13 09:52:47 morten -% Fix spaces in messages, make fast calculation of format age, fixed \DocInput, added \endinput -% -% Revision 1.3 2005/04/12 22:42:22 braams -% Removed a few redundant lines with docstrip instructions -% -% Revision 1.2 2005/04/11 22:46:47 braams -% Translated this file into the ltx3 lingo -% This file may need further cleanup at a later stage -% -% Revision 1.1 2005/03/11 21:26:31 braams -% File copied from 2e for now, to hold the format version identification +% \end{implementation} +% \PrintIndex % +% \endinput diff --git a/Master/texmf-dist/source/latex/expl3/l3xref.dtx b/Master/texmf-dist/source/latex/expl3/l3xref.dtx index 742def4b143..c0f0fa791ac 100644 --- a/Master/texmf-dist/source/latex/expl3/l3xref.dtx +++ b/Master/texmf-dist/source/latex/expl3/l3xref.dtx @@ -1,5 +1,5 @@ % \iffalse -%% File: l3xref.dtx Copyright (C) 2006 LaTeX3 project +%% File: l3xref.dtx Copyright (C) 2006,2009 LaTeX3 project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this @@ -17,7 +17,7 @@ %% %% The development version of the bundle can be found at %% -%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/ +%% http://www.latex-project.org/svnroot/experimental/trunk/ %% %% for those people who are interested. %% @@ -36,7 +36,7 @@ \RequirePackage{l3names} %</driver|package|testfile> %\fi -\GetIdInfo$Id: l3xref.dtx 621 2007-09-01 20:14:19Z morten $ +\GetIdInfo$Id: l3xref.dtx 1362 2009-05-28 20:19:21Z joseph $ {L3 Experimental cross referencing} %\iffalse %<*testfile> @@ -48,7 +48,7 @@ \ProvidesFile{\filename.\filenameext} [\filedate\space v\fileversion\space\filedescription] %\iffalse -\documentclass{l3doc} +\documentclass[full]{l3doc} \begin{document} \DocInput{\filename.\filenameext} \end{document} @@ -64,12 +64,11 @@ % \date{\filedate} % \maketitle % -% -% \section{Cross references} +% \begin{documentation} % % \begin{function}{\xref_set_label:n} % \begin{syntax} -% "\xref_set_label:n" "{"<name>"}" +% "\xref_set_label:n" \Arg{name} % \end{syntax} % Sets a label in the text. Note that this function does not do % anything else than setting the correct labels. In particular, it @@ -79,10 +78,10 @@ % % \begin{function}{\xref_new:nn} % \begin{syntax} -% "\xref_new:nn" "{"<type>"}" "{"<value>"}" +% "\xref_new:nn" \Arg{type} \Arg{value} % \end{syntax} % Defines a new cross reference type <type>. This defines the token -% list pointer |\l_xref_curr_|<type>|_tlp| with default value +% list variable |\l_xref_curr_|<type>|_tl| with default value % <value> which gets written fully expanded when |\xref_set_label:n| % is called. % \end{function} @@ -90,57 +89,73 @@ % % \begin{function}{\xref_deferred_new:nn} % \begin{syntax} -% "\xref_deferred_new:nn" "{"<type>"}" "{"<value>"}" +% "\xref_deferred_new:nn" \Arg{type} \Arg{value} % \end{syntax} % Same as |\xref_new:n| except for this one, the value written % happens when \TeX\ ships out the page. Page numbers use this one % obviously. % \end{function} % -% \begin{function}{\xref_get_value:nn} +% \begin{function}{\xref_get_value:nn / (EXP)} % \begin{syntax} -% "\xref_get_value:nn" "{"<type>"}" "{"<name>"}" +% "\xref_get_value:nn" \Arg{type} \Arg{name} % \end{syntax} % Extracts the cross reference information of type <type> for the % label <name>. This operation is expandable. % \end{function} % % -% \StopEventually{} +% \end{documentation} +% +% \begin{implementation} +% +% \section{\pkg{l3xref} implementation} % -% \subsection{Implementation} +% \subsection{Internal functions and variables} % +% \begin{variable}{ \g_xref_all_curr_immediate_fields_prop | +% \g_xref_all_curr_deferred_fields_prop } +% What they say they are ":)" +% \end{variable} +% +% \begin{variable}{ \xref_write } +% A stream for writing cross references, although they are not required +% to be in a separate file. +% \end{variable} +% +% \begin{function}{\xref_define_label:nn} +% \begin{syntax} +% "\xref_define_label:nn" \Arg{name} \Arg{plist contents} +% \end{syntax} +% Define the property list for each label; used internally by +% "\xref_set_label:n". +% \end{function} +% +% \subsection{Module code} % % We start by ensuring that the required packages are loaded. % \begin{macrocode} %<*package> \ProvidesExplPackage {\filename}{\filedate}{\fileversion}{\filedescription} -\RequirePackage{l3quark} -\RequirePackage{l3toks} -\RequirePackage{l3io} -\RequirePackage{l3prop} -\RequirePackage{l3int} -\RequirePackage{l3token} +\package_check_loaded_expl: %</package> %<*initex|package> % \end{macrocode} % -% -% % There are two kinds of information, namely information which is % \emph{immediate} like a section title and then there's \emph{deferred} % information like page numbers. Each reference type belong to one of % these categories, which we save internally as the property lists -% |\g_xref_all_curr_immediate_fields_plist| and -% |\g_xref_all_curr_deferred_fields_plist| and the reference type +% |\g_xref_all_curr_immediate_fields_prop| and +% |\g_xref_all_curr_deferred_fields_prop| and the reference type % \meta{xyz} exists as the key-info pair |\xref_|\meta{xyz}|_key| -% |{\l_xref_curr_|\meta{xyz}|_tlp}| on one of these lists. This way each +% |{\l_xref_curr_|\meta{xyz}|_tl}| on one of these lists. This way each % new entry type is just added as another key-info pair. % % When the cross references are generated at the beginning of the % document each will turn into a control sequence. Thus |\label{mylab}| -% will internally refer to the property list |\g_xref_mylab_plist|. +% will internally refer to the property list |\g_xref_mylab_prop|. % % The extraction of values from this property list can be done in % several different ways but we want to keep the operation @@ -156,52 +171,54 @@ % argument is the type and the second the label name so here it would % be |\xref_get_value:nn| |{xyz}| |{mylab}|. % -% \begin{macro}{\g_xref_all_curr_immediate_fields_plist} -% \begin{macro}{\g_xref_all_curr_deferred_fields_plist} +% \begin{macro}{\g_xref_all_curr_immediate_fields_prop} +% \begin{macro}{\g_xref_all_curr_deferred_fields_prop} % The two main property lists for storing information. They contain % key-info pairs for all known types. % \begin{macrocode} -\prop_new:N \g_xref_all_curr_immediate_fields_plist -\prop_new:N \g_xref_all_curr_deferred_fields_plist +\prop_new:N \g_xref_all_curr_immediate_fields_prop +\prop_new:N \g_xref_all_curr_deferred_fields_prop % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\xref_new:nn} % \begin{macro}{\xref_deferred_new:nn} -% \begin{macro}{\xref_new_aux:nnn} +% \begin{macro}[aux]{\xref_new_aux:nnn} % Setting up a new cross reference type is fairly straight forward % when we follow the game plan mentioned earlier. % \begin{macrocode} -\def_new:Npn \xref_new:nn {\xref_new_aux:nnn{immediate}} -\def_new:Npn \xref_deferred_new:nn {\xref_new_aux:nnn{deferred}} -\def_new:Npn \xref_new_aux:nnn #1#2#3{ +\cs_new_nopar:Npn \xref_new:nn {\xref_new_aux:nnn{immediate}} +\cs_new_nopar:Npn \xref_deferred_new:nn {\xref_new_aux:nnn{deferred}} +\cs_new_nopar:Npn \xref_new_aux:nnn #1#2#3{ % \end{macrocode} % First put the new type in the relevant property list. % \begin{macrocode} - \prop_gput:ccx {g_xref_all_curr_ #1 _fields_plist} + \prop_gput:ccx {g_xref_all_curr_ #1 _fields_prop} { xref_ #2 _key } - { \exp_not:c {l_xref_curr_#2_tlp }} + { \exp_not:c {l_xref_curr_#2_tl }} % \end{macrocode} % Then define the key to be a protected macro.\footnote{We could also % set it equal to \cs{scan_stop:} but this just feels ``cleaner''.} % \begin{macrocode} - \def_protected:cpn { xref_#2_key }{} - \tlp_new:cn{l_xref_curr_#2_tlp}{#3} + \cs_set_protected_nopar:cpn { xref_#2_key }{} + \tl_new:cn{l_xref_curr_#2_tl}{#3} % \end{macrocode} % Now for the function extracting the value of a reference. We could % do this with a simple |\prop_if_in| thing put since we want to do % things in an expandable way we make a separate grabber for each % type---this is also faster. The grabber function can be defined by -% using an intricate construction of |\exp_after:NN| and other goodies +% using an intricate construction of |\exp_after:wN| and other goodies % but I prefer readable code. The end result for the input |xyz| is % \begin{verbatim} -% \def:Npn\xref_get_value_xyz_aux:w #1\xref_xyz_key #2#3\q_nil{#2} +% \cs_set_nopar:Npn\xref_get_value_xyz_aux:w #1\xref_xyz_key #2#3\q_nil{#2} % \end{verbatim} % \begin{macrocode} \toks_set:Nx \l_tmpa_toks { - \exp_not:n { \def:cpn {xref_get_value_#2_aux:w} ##1 } + \exp_not:n { \cs_set_nopar:cpn {xref_get_value_#2_aux:w} ##1 } + \exp_not:N \q_prop \exp_not:c { xref_#2_key } + \exp_not:N \q_prop } \toks_use:N \l_tmpa_toks ##2 ##3\q_nil {##2} } @@ -215,31 +232,36 @@ % Getting the correct value for a given label-type pair is a matter % of connecting the correct grabber functions and property list. % \begin{macrocode} -\def_new:Npn \xref_get_value:nn #1#2 { - \cs_if_really_free:cTF{g_xref_#2_plist} - {??} +\cs_new_nopar:Npn \xref_get_value:nn #1#2 { + \cs_if_exist:cTF{g_xref_#2_prop} { % \end{macrocode} % This next expansion may look a little weird but it isn't if you % think about it! % \begin{macrocode} - \exp_args:NcNc \exp_after:NN {xref_get_value_#1_aux:w} - \prop_use:N {g_xref_#2_plist} + \exp_args:NcNc \exp_after:wN {xref_get_value_#1_aux:w} + \toks_use:N {g_xref_#2_prop} % \end{macrocode} % Better put in the stop marker. % \begin{macrocode} \q_nil } + {??} } -\def:NNn \exp_after:cc 2 { - \exp_after:NN \exp_after:NN - \cs:w #1\exp_after:NN\cs_end: \cs:w #2\cs_end: +% \end{macrocode} +% Temporary! We expand the property list and so we can't have the +% |\q_prop| marker just expand! +% \begin{macrocode} +\cs_set_nopar:Npn \exp_after:cc #1#2 { + \exp_after:wN \exp_after:wN + \cs:w #1\exp_after:wN\cs_end: \cs:w #2\cs_end: } +\cs_set_protected:Npn \q_prop {\q_prop} % \end{macrocode} % \end{macro} % % \begin{macro}{\xref_define_label:nn} -% \begin{macro}{\xref_define_label_aux:nn} +% \begin{macro}[aux]{\xref_define_label_aux:nn} % Define the property list for each label. We better do this in two % steps because the special catcode regime is in effect and since % some of the info fields are very likely to contain actual text, @@ -248,7 +270,7 @@ % containing catcode instructions which can then be activated with % |\etex_scantokens:D|. % \begin{macrocode} -\def_protected_new:Npn \xref_define_label:nn { +\cs_new_protected_nopar:Npn \xref_define_label:nn { \group_begin: \char_set_catcode:nn {`\ }\c_ten \xref_define_label_aux:nn @@ -258,10 +280,10 @@ % we should do something about it. For now we don't do anything % spectacular. % \begin{macrocode} -\def_new:Npn \xref_define_label_aux:nn #1#2 { - \cs_if_really_free:cTF{g_xref_#1_plist} - {\prop_new:c{g_xref_#1_plist}}{\WARNING} - \toks_gset:cn{g_xref_#1_plist}{#2} +\cs_new_nopar:Npn \xref_define_label_aux:nn #1#2 { + \cs_if_free:cTF{g_xref_#1_prop} + {\prop_new:c{g_xref_#1_prop}}{\WARNING} + \toks_gset:cn{g_xref_#1_prop}{#2} \group_end: } % \end{macrocode} @@ -276,12 +298,12 @@ % lists being implemented as token list registers we must expand the % `immediate' fields twice. % \begin{macrocode} -\def:Npn \xref_set_label:n #1{ - \def:Npx \tmp:w{\prop_use:N\g_xref_all_curr_immediate_fields_plist} - \exp_args:NNx\iow_deferred_expanded:Nn \xref_write{ +\cs_set_nopar:Npn \xref_set_label:n #1{ + \cs_set_nopar:Npx \xref_tmp:w{\toks_use:N\g_xref_all_curr_immediate_fields_prop} + \exp_args:NNx\iow_shipout_x:Nn \xref_write{ \xref_define_label:nn {#1} { - \tmp:w - \prop_use:N \g_xref_all_curr_deferred_fields_plist + \xref_tmp:w + \toks_use:N \g_xref_all_curr_deferred_fields_prop } } } @@ -299,37 +321,41 @@ % That's it (for now). % \begin{macrocode} %</initex|package> +% \end{macrocode} +% +% \begin{macrocode} %<*showmemory> \showMemUsage %</showmemory> % \end{macrocode} % +% \section{\pkg{l3xref} test file} % % \begin{macrocode} %<*testfile> \documentclass{article} \usepackage{l3xref} \ExplSyntaxOn -\def:Npn \startrecording {\iow_open:Nn \xref_write {\jobname.xref}} -\def:Npn \DefineCrossReferences { +\cs_set_nopar:Npn \startrecording {\iow_open:Nn \xref_write {\jobname.xref}} +\cs_set_nopar:Npn \DefineCrossReferences { \group_begin: - \NamesStart + \ExplSyntaxNamesOn \InputIfFileExists{\jobname.xref}{}{} \group_end: } \AtBeginDocument{\DefineCrossReferences\startrecording} \xref_new:nn {name}{} -\def:Npn \setname{\tlp_set:Nn\l_xref_curr_name_tlp} -\def:Npn \getname{\xref_get_value:nn{name}} +\cs_set_nopar:Npn \setname{\tl_set:Nn\l_xref_curr_name_tl} +\cs_set_nopar:Npn \getname{\xref_get_value:nn{name}} \xref_deferred_new:nn {page}{\thepage} -\def:Npn \getpage{\xref_get_value:nn{page}} +\cs_set_nopar:Npn \getpage{\xref_get_value:nn{page}} \xref_deferred_new:nn {valuepage}{\number\value{page}} -\def:Npn \getvaluepage{\xref_get_value:nn{valuepage}} +\cs_set_nopar:Npn \getvaluepage{\xref_get_value:nn{valuepage}} -\let:NN \setlabel \xref_set_label:n +\cs_set_eq:NN \setlabel \xref_set_label:n \ExplSyntaxOff \begin{document} @@ -358,21 +384,7 @@ Now let's extract some values. \getname{testlabel 7} on page %</testfile> % \end{macrocode} % +% \end{implementation} +% \PrintIndex % % \endinput -% -% $Log$ -% Revision 1.4 2006/03/20 18:26:42 braams -% Updated the copyright notice (2006) and demoted all implementation -% sections to subsections and so on to clean up the toc for source3.tex -% -% Revision 1.3 2006/01/16 11:26:57 morten -% Minor changes -% -% Revision 1.2 2006/01/15 14:07:31 braams -% Activated \StopEventually{} -% -% Revision 1.1 2006/01/15 07:55:06 morten -% New cross reference module including test file. -% -%
\ No newline at end of file diff --git a/Master/texmf-dist/source/latex/expl3/source3.tex b/Master/texmf-dist/source/latex/expl3/source3.tex index 1199dbf3209..837260437b1 100644 --- a/Master/texmf-dist/source/latex/expl3/source3.tex +++ b/Master/texmf-dist/source/latex/expl3/source3.tex @@ -1,5 +1,5 @@ % \iffalse -%% File: source3.dtx Copyright (C) 1990-2006 LaTeX3 project +%% File: source3.dtx Copyright (C) 1990-2009 LaTeX3 project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this @@ -17,7 +17,7 @@ %% %% The development version of the bundle can be found at %% -%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/ +%% http://www.latex-project.org/svnroot/experimental/trunk/ %% %% for those people who are interested. %% @@ -35,184 +35,343 @@ % This document will typeset the LaTeX3 sources as a single document. % This will produce quite a large file (roughly ??? pages) and may -% take a long time. -% -% Some notes on processing this document are contained at the end -% of this document, after \end{document} -% -% DPC 1997/11/17 -% JLB 2005/03/09 copied from source2e.tex for l3in2e sources -% First a special index style for makeindex -% - -\begin{filecontents}{source3.ist} -actual '=' -quote '!' -level '>' -preamble -"\n \\begin{theindex} \n \\makeatletter\\scan@allowedfalse\n" -postamble -"\n\n \\end{theindex}\n" -item_x1 "\\efill \n \\subitem " -item_x2 "\\efill \n \\subsubitem " -delim_0 "\\pfill " -delim_1 "\\pfill " -delim_2 "\\pfill " -% The next lines will produce some warnings when -% running Makeindex as they try to cover two different -% versions of the program: -lethead_prefix "{\\bfseries\\hfil " -lethead_suffix "\\hfil}\\nopagebreak\n" -lethead_flag 1 -heading_prefix "{\\bfseries\\hfil " -heading_suffix "\\hfil}\\nopagebreak\n" -headings_flag 1 - -% and just for source3: -% Remove R so I is treated in sequence I J K not I II III -page_precedence "rnaA" -\end{filecontents} - -\begin{filecontents}{l3doc.cfg} - \DisableCrossrefs - \AtEndOfClass{\OnlyDescription} -\end{filecontents} - -\begin{filecontents}{l3full.cfg} - -% Set up the Index and Change History to use \part - \IndexPrologue{\part*{Index}% - \markboth{Index}{Index}% - \addcontentsline{toc}{part}{Index}% - The italic numbers denote the pages where the - corresponding entry is described, - numbers underlined point to the definition, - all others indicate the places where it is used.} - - \GlossaryPrologue{\part*{Change History}% -% Allow control names to be hyphenated here... - {\GlossaryParms\ttfamily\hyphenchar\font=`\-}% - \markboth{Change History}{Change History}% - \addcontentsline{toc}{part}{Change History}} - - \RecordChanges - \CodelineIndex - \EnableCrossrefs - \AlsoImplementation - \setcounter{IndexColumns}{2} -\end{filecontents} - +% take a long time on a slow machine. \documentclass{l3doc} - \listfiles -% Do not index some TeX primitives, and some common plain TeX commands. - -%% to be filled in later\DoNotIndex{...} -% The standard \changes command modified slightly to better cope with -% this multiple file document. -%\makeatletter -%\def\changes@#1#2#3{% -% \let\protect\@unexpandable@protect -% \edef\@tempa{\noexpand\glossary{#2\space\currentfile\space#1\levelchar -% \ifx\saved@macroname\@empty -% \space -% \actualchar -% \generalname -% \else -% \expandafter\@gobble -% \saved@macroname -% \actualchar -% \string\verb\quotechar*% -% \verbatimchar\saved@macroname -% \verbatimchar -% \fi -% :\levelchar #3}}% -% \@tempa\endgroup\@esphack} -%\makeatother - -% Needed for documentation in ltoutenc.dtx -\usepackage{textcomp} - \begin{document} - \title{The \LaTeX3 Sources} - \author{\Team} - - \pagenumbering{roman} - \maketitle - \renewcommand\maketitle{} - - \tableofcontents - - \clearpage - \pagenumbering{arabic} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -% Each of the following \DocInput lines includes a file with extension -% .dtx. Each of these files may be typeset separately. For instance -% latex l3boxes.dtx -% will typeset the source of the LaTeX3 box commands. -% -% If this file is processed, each of these separate dtx files will be -% contained as a part of a single document. Using ltxdoc.cfg you can -% then optionally produce a combined index and/or change history for -% the entire source of the format file. Note that such a document will -% be quite large (about ??? pages). -% +\title{The \LaTeX3 Sources} +\author{\Team} - \DocInput{l3names.dtx} % System dependant initialisation - \DocInput{l3basics.dtx} % +\pagenumbering{roman} +\maketitle - \DocInput{l3chk.dtx} % Checking assignments +\begin{abstract} - \DocInput{l3tlp.dtx} % +\parindent=0pt +\parskip=\baselineskip - \DocInput{l3expan.dtx} % +\noindent This is the reference documentation for the \pkg{expl3} +programming environment. The \pkg{expl3} modules set up an experimental +naming scheme for \LaTeX\ commands, which allow the \LaTeX\ programmer +to systematically name functions and variables, and specify the argument +types of functions. - \DocInput{l3num.dtx} % +The \TeX\ and \eTeX\ primitives are all given a new name according to +these conventions. However, in the main direct use of the primitives is +not required or encouraged: the \pkg{expl3} modules define an +independent low-level \LaTeX3 programming language. - \DocInput{l3seq.dtx} % +At present, the \pkg{expl3} modules are designed to be loaded on top of +\LaTeXe. In time, a \LaTeX3 format will be produced based on this code. +This allows the code to be used in \LaTeXe\ packages \emph{now} while a +stand-alone \LaTeX3 is developed. - \DocInput{l3alloc.dtx} % +\begin{bfseries} + While \pkg{expl3} is still experimental, the bundle is now regarded as + broadly stable. The syntax conventions and functions provided are now + ready for wider use. There may still be changes to some functions, but + these will be minor when compared to the scope of \pkg{expl3}. - \DocInput{l3io.dtx} % + New modules will be added to the distributed version of \pkg{expl3} as + they reach maturity. +\end{bfseries} - \DocInput{l3clist.dtx} % +\end{abstract} - \DocInput{l3prop.dtx} % - - \DocInput{l3int.dtx} % - - \DocInput{l3skip.dtx} % - - \DocInput{l3toks.dtx} % - - \DocInput{l3messages.dtx} % - - \DocInput{l3box.dtx} % - - \DocInput{l3precom.dtx} % - - \DocInput{l3quark.dtx} % +\clearpage - \DocInput{l3prg.dtx} % +{\def\\{:}% fix "newlines" in the ToC +\tableofcontents} - \DocInput{l3token.dtx} % +\clearpage +\pagenumbering{arabic} - \DocInput{l3xref.dtx} % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - \DocInput{l3calc.dtx} % +% Each of the following \DocInput lines includes a file with extension +% .dtx. Each of these files may be typeset separately. For instance +% pdflatex l3box.dtx +% will typeset the source of the LaTeX3 box commands. If you use the +% Makefile, the index will be generated automatically; e.g., +% make doc F=l3box +% +% If this file is processed, each of these separate dtx files will be +% contained as a part of a single document. + +\makeatletter +\def\partname{Part} +\def\maketitle{\part{\@title}} +\let\thanks\@gobble +\let\DelayPrintIndex\PrintIndex +\let\PrintIndex\@empty +\makeatother + +\part{Introduction to \pkg{expl3} and this document} + +This document is intended to act as a comprehensive reference manual +for the \pkg{expl3} language. A general guide to the \LaTeX3 +programming language is found in \href{expl3.pdf}{expl3.pdf}. + +\section{Naming functions and variables} + +\LaTeX3 does not use \texttt{@} as a ``letter'' for defining +internal macros. Instead, the symbols |_| and \texttt{:} +are used in internal macro names to provide structure. The name of +each \emph{function} is divided into logical units using \texttt{_}, +while \texttt{:} separates the \emph{name} of the function from the +\emph{argument specifier} (``arg-spec''). This describes the arguments +expected by the function. In most cases, each argument is represented +by a single letter. The complete list of arg-spec letters for a function +is referred to as the \emph{signature} of the function. + +Each function name starts with the \emph{module} to which it belongs. +Thus apart from a small number of very basic functions, all \pkg{expl3} +function names contain at least one underscore to divide the module +name from the descriptive name of the function. For example, all +functions concerned with comma lists are in module \texttt{clist} and +begin \cs{clist_}. + +Every function must include an argument specifier. For functions which +take no arguments, this will be blank and the function name will end +\texttt{:}. Most functions take one or more arguments, and use the +following argument specifiers: +\begin{description} + \item[\texttt{D}] The \texttt{D} specifier means \emph{do not use}. + All of the \TeX\ primitives are initially \cs{let} to a \texttt{D} + name, and some are then given a second name. Only the kernel + team should use anything with a \texttt{D} specifier! + \item[\texttt{N} and \texttt{n}] These mean \emph{no manipulation}, + of a single token for \texttt{N} and of a set of tokens given in + braces for \texttt{n}. Both pass the argument though exactly as + given. Usually, if you use a single token for an \texttt{n} argument, + all will be well. + \item[\texttt{c}] This means \emph{csname}, and indicates that the + argument will be turned into a csname before being used. So + So \cs{foo:c} |{ArgumentOne}| will act in the same way as \cs{foo:N} + \cs{ArgumentOne}. + \item[\texttt{V} and \texttt{v}] These mean \emph{value + of variable}. The \texttt{V} and \texttt{v} specifiers are used to + get the content of a variable without needing to worry about the + underlying \TeX\ structure containing the data. A \texttt{V} + argument will be a single token (similar to \texttt{N}), for example + \cs{foo:V} \cs{MyVariable}; on the other hand, using \texttt{v} a + csname is constructed first, and then the value is recovered, for + example \cs{foo:v} |{MyVariable}|. + \item[\texttt{o}] This means \emph{expansion once}. In general, the + \texttt{V} and \texttt{v} specifiers are favoured over \texttt{o} + for recovering stored information. However, \texttt{o} is useful + for correctly processing information with delimited arguments. + \item[\texttt{x}] The \texttt{x} specifier stands for \emph{exhaustive + expansion}: the plain \TeX\ \cs{edef}. + \item[\texttt{f}] The \texttt{f} specifier stands for \emph{full + expansion}, and in contrast to \emph{x} stops at the first + non-expandable item without trying to execute it. + \item[\texttt{T} and \texttt{F}] For logic tests, there are the branch + specifiers \texttt{T} (\emph{true}) and \texttt{F} (\emph{false}). + Both specifiers treat the input in the same way as \texttt{n} (no + change), but make the logic much easier to see. + \item[\texttt{p}] The letter \texttt{p} indicates \TeX\ + \emph{parameters}. Normally this will be used for delimited + functions as \pkg{expl3} provides better methods for creating simple + sequential arguments. + \item[\texttt{w}] Finally, there is the \texttt{w} specifier for + \emph{weird} arguments. This covers everything else, but mainly + applies to delimited values (where the argument must be terminated + by some arbitrary string). +\end{description} +Notice that the argument specifier describes how the argument is +processed prior to being passed to the underlying function. For example, +\cs{foo:c} will take its argument, convert it to a control sequence and +pass it to \cs{foo:N}. + +Variables are named in a similar manner to functions, but begin with +a single letter to define the type of variable: +\begin{description} + \item[\texttt{c}] Constant: global parameters whose value should not + be changed. + \item[\texttt{g}] Parameters whose value should only be set globally. + \item[\texttt{l}] Parameters whose value should only be set locally. +\end{description} +Each variable name is then build up in a similar way to that of a +function, typically starting with the module\footnote{The module names are + not used in case of generic scratch registers defined in the data + type modules, e.g., the + \texttt{int} module contains some scratch variables called \cs{l_tmpa_int}, + \cs{l_tmpb_int}, and so on. In such a case adding the module name up front + to denote the module + and in the back to indicate the type, as in + \cs{l_int_tmpa_int} would be very unreadable.} name +and then a descriptive part. +Variables end with a short identifier to show the variable type: +\begin{description} + \item[\texttt{bool}] Either true or false. + \item[\texttt{box}] Box register. + \item[\texttt{clist}] Comma separated list. + \item[\texttt{dim}] `Rigid' lengths. + \item[\texttt{int}] Integer-valued count register. + \item[\texttt{num}] A `fake' integer type using only macros. Useful for + setting up allocation routines. + \item[\texttt{prop}] Property list. + \item[\texttt{skip}] `Rubber' lengths. + \item[\texttt{seq}] `Sequence': a data-type used to implement lists + (with access at both ends) and stacks. + \item[\texttt{stream}] An input or output stream (for reading from or + writing to, respectively). + \item[\texttt{tl}] Token list variables: placeholder for a token list. + \item[\texttt{toks}] Token register. +\end{description} + +\section{Documentation conventions} + +This document is typeset with the experimental \pkg{l3doc} class; +several conventions are used to help describe the features of the code. +A number of conventions are used here to make the documentation clearer. + +Each group of related functions is given in a box. For a function with +a ``user'' name, this might read: +\begin{function}{ + \ExplSyntaxOn | + \ExplSyntaxOff + } + \begin{syntax} + "\ExplSyntaxOn" + \end{syntax} + The textual description of how the function works would appear here. The + syntax of the function is shown in mono-spaced text to the right of + the box. In this example, the function takes no arguments and so the + name of the function is simply reprinted. +\end{function} + +For programming functions, which use \texttt{_} and \texttt{:} in their +name there are a few additional conventions: If two related functions are given with identical names but +different argument specifiers, these are termed \emph{variants} of each +other, and the latter functions are printed in grey to show this more +clearly. They will carry out the same function but will take different +types of argument: +\begin{function}{ + \seq_new:N | + \seq_new:c + } + \begin{syntax} + "\seq_new:N" <sequence> + \end{syntax} + When a number of variants are described, the arguments are usually + illustrated only for the base function. Here, <sequence> indicates + that \cs{seq_new:N} expects the name of a sequence. From the argument + specifier, \cs{seq_new:c} also expects a sequence name, but as a + name rather than as a control sequence. Each argument given in the + illustration should be described in the following text. +\end{function} + +Some functions are fully expandable, which allows it to be used within +an \texttt{x}-type argument (in plain \TeX\ terms, inside an \cs{edef}). +These fully expandable functions are indicated in the documentation by +a star: +\begin{function}{ + \cs_to_str:N / (EXP) + } + \begin{syntax} + "\cs_to_str:N" <cs> + \end{syntax} + As with other functions, some text should follow which explains how + the function works. Usually, only the star will indicate that the + function is expandable. In this case, the function expects a <cs>, + shorthand for a <control sequence>. +\end{function} + +Conditional (\texttt{if}) functions are normally defined in three variants, with +\texttt{T}, \texttt{F} and \texttt{TF} argument specifiers. This allows +them to be used for different `true'/`false' branches, depending on +which outcome the conditional is being used to test. To indicate this +without repetition, this information is given in a shortened form: +\begin{function}{ + \xetex_if_engine: / (TF) (EXP) + } + \begin{syntax} + "\xetex_if_engine:TF" <true code> <false code> + \end{syntax} + The underlining and italic of \texttt{TF} indicates that + \cs{xetex_if_engine:T}, \cs{xetex_if_engine:F} and + \cs{xetex_if_engine:TF} are all available. Usually, the illustration + will use the \texttt{TF} variant, and so both <true code> + and <false code> will be shown. The two variant forms \texttt{T} and + \texttt{F} take only <true code> and <false code>, respectively. + Here, the star also shows that this function is expandable. + With some minor exceptions, \emph{all} conditional functions in the + \pkg{expl3} modules should be defined in this way. +\end{function} + +Variables, constants and so on are described in a similar manner: +\begin{variable}{ + \l_tmpa_tl + } + A short piece of text will describe the variable: there is no + syntax illustration in this case. +\end{variable} + +In some cases, the function is similar to one in \LaTeXe\ or plain \TeX. +In these cases, the text will include an extra `\textbf{\TeX{}hackers +note}' section: +\begin{function}{ + \token_to_str:N / (EXP) + } + \begin{syntax} + "\token_to_str:N" <token> + \end{syntax} + The normal description text. + \begin{texnote} + Detail for the experienced \TeX\ or \LaTeXe\ programmer. In this + case, it would point out that this function is the \TeX\ primitive + \cs{string}. + \end{texnote} +\end{function} + +\DisableImplementation + +\DocInput{l3names.dtx} + +\DocInput{l3basics.dtx} +\DocInput{l3expan.dtx} +\DocInput{l3prg.dtx} +\DocInput{l3quark.dtx} +\DocInput{l3token.dtx} + +\DocInput{l3int.dtx} +\DocInput{l3num.dtx} +\DocInput{l3intexpr.dtx} +\DocInput{l3skip.dtx} + +\DocInput{l3tl.dtx} +\DocInput{l3toks.dtx} +\DocInput{l3seq.dtx} +\DocInput{l3clist.dtx} +\DocInput{l3prop.dtx} + +\DocInput{l3io.dtx} +\DocInput{l3msg.dtx} +\DocInput{l3box.dtx} +\DocInput{l3xref.dtx} +\DocInput{l3keyval.dtx} +\DocInput{l3calc.dtx} +\DocInput{l3file.dtx} + +% \DocInput{l3precom.dtx} +% \DocInput{l3alloc.dtx} +% \DocInput{l3chk.dtx} + +\part{Implementation} +\def\maketitle{} +\EnableImplementation +\DisableDocumentation +\DocInputAgain %% \DocInput{l3vers.dtx} % Current version date - \includeltpatch % Corrections distributed after the full release - -% Stop here if ltxdoc.cfg says \AtEndOfClass{\OnlyDescription} -\StopEventually{\PrintIndex\end{document}} +\includeltpatch % Corrections distributed after the full release \clearpage \pagestyle{headings} @@ -222,178 +381,18 @@ page_precedence "rnaA" \newcount\hbadness \hfuzz=\maxdimen -\typeout{% - \string # Produce change log with^^J% - makeindex -s gglo.ist -o source3.gls source3.glo} - - \PrintChanges - \clearpage -% makeindex needs a symbol between the parts of composite page numbers -% but we dont want one, so: -\typeout{% - \string # Produce index with^^J% - makeindex -s source3.ist source3.idx} - \begingroup \def\endash{--} \catcode`\-\active \def-{\futurelet\temp\indexdash} \def\indexdash{\ifx\temp-\endash\fi} -\PrintIndex +\DelayPrintIndex \endgroup -% Make sure that the index is not printed twice -% (ltxdoc.cfg might have a second \PrintIndex command) -\let\PrintChanges\relax -\let\PrintIndex\relax - \end{document} -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -To use this file to produce a fully indexed source code -you need to execute the following (or equivalent) commands: - - latex source3.tex - - makeindex -s source3.ist source3.idx - makeindex -s gglo.ist -o source3.gls source3.glo - - latex source3.tex - latex source3.tex - - -The makeindex style source3.ist is used in place of the usual -doc gind.ist to ensure that I is used in the sequence I J K -not I II II, which would be the default makeindex behaviour. - -The third run with latex is only required to get the table of -contents entries for the change log and index. You may speed things up -by using the \includeonly mechanism so as not to typeset the source -files on the second run. This involves changing the file -ltxdoc.cfg -between the latex runs. - -The following unix script automates this. - (It could easily be ported to scripts for DOS or VMS, - rm is ReMove a file, and echo "..." > file writes ... to "file".) - - -After this script (after the second ==============) is a similar script -that will produce the documentation for all the files in the base -distribution that are *not* included in source3.dvi. This second script -was requested, but before using it, beware it will take a long time! -It may however be modified as required, eg to not typeset the fdd files -or whatever... - -============== -#!/bin/sh - -rm -f source3.gls source3.ind source3.toc - -# First run: -# Create new standard ltxdoc.cfg file -# Pass the (possibly empty) list of arguments supplied on the -# command line to article class. -# -# If you use A4 paper, running this script with argument -# a4paper -# may save about 30 pages. -# -echo "\PassOptionsToClass{$*}{article}" > ltxdoc.cfg - - -# Now LaTeX the file with this cfg file. -# -latex source3.tex - - -# Make the Change log and Glossary. -# -makeindex -s source3.ist source3.idx -makeindex -s gglo.ist -o source3.gls source3.glo - - -# Second run: append \includeonly{} to ltxdoc.cfg to speed up things -# (this run needed only to get changes and index listed in .toc file) -# -# Note that the index will not be made incorrect by the insertion -# of the table of contents as the front matter uses a diferent page -# numbering scheme. -# -echo "\includeonly{}" >> ltxdoc.cfg - -latex source3.tex - - -# Third and final run, to put everything together. -# First restore the cfg file: -# -echo "\PassOptionsToClass{$*}{article}" > ltxdoc.cfg -latex source3.tex - - -============== -#!/bin/sh - -# Running this script will process all the dtx fdd and *guide.tex -# and ltnews*.tex files in the LaTeX distribution, except the dtx -# files included in source3.tex. -# (The shell first script in the comments of source3.tex will -# process those.) - -# Any command line arguments (eg a4paper) are taken as options to the -# article class. - -# This script is likely to take ages! - -echo "\PassOptionsToClass{$*}{article}" > ltxdoc.cfg -echo "\batchmode" >> ltxdoc.cfg - -# The next four lines produce full indexes and change logs -# you may not want those. -echo "\AtBeginDocument{\RecordChanges}" >> ltxdoc.cfg -echo "\AtEndDocument{\PrintChanges}" >> ltxdoc.cfg -echo "\AtBeginDocument{\CodelineIndex\EnableCrossrefs}" >> ltxdoc.cfg -echo "\AtEndDocument{\PrintIndex}" >> ltxdoc.cfg - -# If you do not want any code listings, just documentation, then instead -# of the above four lines, uncomment the following: -# echo "\AtBeginDocument{\OnlyDescription}" >> ltxdoc.cfg - -echo "\PassOptionsToClass{$*}{article}" > ltxguide.cfg -echo "\batchmode" >> ltxguide.cfg - -cp ltxguide.cfg ltnews.cfg - - -for i in *dtx *fdd *guide.tex ltnews*.tex -do -B=`basename $i .dtx` - -if (grep "Include{$B}" source3.tex >/dev/null ; ) -then -echo In source3: $i -else -echo latex $i - if (latex $i > /dev/null) - then - echo latex $i - latex $i > /dev/null - echo makeindex -s gind.ist $B.idx - makeindex -s gind.ist $B.idx > /dev/null 2> /dev/null - echo makeindex -s gglo.ist -o $B.gls $B.glo - makeindex -s gglo.ist -o $B.gls $B.glo > /dev/null 2> /dev/null - echo latex $i - latex $i > /dev/null - else - echo "!!! LaTeX ERROR: $i. (See $B.log.)" - fi -fi - -done diff --git a/Master/texmf-dist/source/latex/expl3/test3.tex b/Master/texmf-dist/source/latex/expl3/test3.tex deleted file mode 100644 index 3dd5f714d35..00000000000 --- a/Master/texmf-dist/source/latex/expl3/test3.tex +++ /dev/null @@ -1,135 +0,0 @@ -% \iffalse -%% File: test2 Copyright (C) 1990-2006 LaTeX3 project -%% -%% It may be distributed and/or modified under the conditions of the -%% LaTeX Project Public License (LPPL), either version 1.3c of this -%% license or (at your option) any later version. The latest version -%% of this license is in the file -%% -%% http://www.latex-project.org/lppl.txt -%% -%% This file is part of the ``expl3 bundle'' (The Work in LPPL) -%% and all files in that bundle must be distributed together. -%% -%% The released version of this bundle is available from CTAN. -%% -%% ----------------------------------------------------------------------- -%% -%% The development version of the bundle can be found at -%% -%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/ -%% -%% for those people who are interested. -%% -%%%%%%%%%%% -%% NOTE: %% -%%%%%%%%%%% -%% -%% Snapshots taken from the repository represent work in progress and may -%% not work or may contain conflicting material! We therefore ask -%% people _not_ to put them into distributions, archives, etc. without -%% prior consultation with the LaTeX Project Team. -%% -%% ----------------------------------------------------------------------- -%% -% \fi -\documentclass{article} - -\usepackage{l3precom} - -% let's dump what is known about the LaTeX internals so far. -% this will not be much as the very basic stuff doesn't get -% dumped and we haven't got anything else. -% -\dumpLaTeXstate{test1} - -\CodeStart - -% we need some variants of tlp_set which are not yet -% defined for use in the code below. -% -\exp_def_form:nnn{tlp_set}{Nn}{on} -\exp_def_form:nnn{tlp_gset}{Nn}{on} - -% okay, here we either load a dump file (testdump.cmp) -% and then jump tp \cs_dump: or we compile one for next time. -% don't forget that if you change code below it will only have any -% affect if a new dump file is written so you may have to remove -% the existing one. -% -\cs_load_dump:n{testdump} - -% two test definitions -% -\def_new:Npn\foo{some foo} -\def_new:Npn\baz{some baz} - -% we say that \foo should be dumped in the compiled style. -% this is pretty useless as it is certainly not faster than defining -% it in the first place. but this is only done for showing that it -% works. just assume that \foo is actually a pretty difficult -% definition which does need a lot of static compilation due to -% parsing, comparing values, etc., so that it is much faster load the -% final version rather than do the compilation each time again. -% -% btw note that \baz is not dumped and will not be available in the -% production run (ie the one using the cmp file) -% -\cs_record_name:N\foo - -% get our self a scratch register (again this will not be available in -% the production run) -% -\tlp_new:Nn\l_scratch_tlp{} - -% now we generate a unique cs name and assign it the string "foo". -% again pretty useless example. but with this mechansim you can build -% complex graph structures etc using these names as pointers, etc. and -% in such a case you need to dump the state of your graph at some -% point to be able to load it very fast in production. -% -\cs_gen_sym:N\l_scratch_tlp{} -\tlp_set:on \l_scratch_tlp {foo} - -% ditto for a global unique name -% -\cs_ggen_sym:N\l_scratch_tlp{} -\tlp_gset:on \l_scratch_tlp {bar} - -% and now we dump the whole rubbish. In the current implementation -% only csnames can be precompiled, perhaps registers should be handled -% similarly. -% -\cs_dump: - -% and some int register to show something in the second LaTeX state -% dump. -% -\int_new:N\l_my_int -\int_set:Nn\l_my_int{42} -% -% as the allocation routines are not distributed we have to do this -% manually. -% -\register_record_name:N\l_my_int - -\dumpLaTeXstate{test2} - -% and changing something ... what happens with the LaTeX state? -% -\int_set:Nn\l_my_int{0} -\def:Npn\file_not_found:nTF#1#2#3{} - -\dumpLaTeXstate{test3} - -\CodeStop - -\begin{document} - -\LaTeX\ still works! - -\end{document} - - - - diff --git a/Master/texmf-dist/source/latex/expl3/test2.tex b/Master/texmf-dist/tex/latex/expl3/expl3.sty index 764ad74fc39..db6b998e867 100644 --- a/Master/texmf-dist/source/latex/expl3/test2.tex +++ b/Master/texmf-dist/tex/latex/expl3/expl3.sty @@ -1,5 +1,21 @@ -% \iffalse -%% File: test2 Copyright (C) 1990-2006 LaTeX3 project +%% +%% This is file `expl3.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% expl3.dtx (with options: `package') +%% +%% +%% EXPERIMENTAL CODE +%% +%% Do not distribute this file without also distributing the +%% source files specified above. +%% +%% Do not distribute a modified version of this file. +%% +%% +%% File: expl3.dtx Copyright (C) 1990-2009 LaTeX3 project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this @@ -17,12 +33,13 @@ %% %% The development version of the bundle can be found at %% -%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/ +%% http://www.latex-project.org/svnroot/experimental/trunk/ + %% %% for those people who are interested. %% %%%%%%%%%%% -%% NOTE: %% +%% NOTE: %% %%%%%%%%%%% %% %% Snapshots taken from the repository represent work in progress and may @@ -31,43 +48,37 @@ %% prior consultation with the LaTeX Project Team. %% %% ----------------------------------------------------------------------- -%% -\def\next$Id: #1.tex #2 #3-#4-#5 #6 #7$#8{% - \def\fileversion{#2}% - \def\filedate{#3/#4/#5}% - \ProvidesFile{#1.tex}[#3/#4/#5 v#2 #8]% +\RequirePackage{l3names} +\GetIdInfo$Id: expl3.dtx 1381 2009-06-01 20:36:02Z joseph $ + {L3 Experimental code bundle wrapper}% +\ProvidesExplPackage + {\filename}{\filedate}{\fileversion}{\filedescription} +\RequirePackage{ + l3basics, + l3expan, + l3tl, + l3num, + l3intexpr, + l3quark, + l3seq, + l3toks, + l3int, + l3prg, + l3clist, + l3token, + l3io, + l3prop, + l3msg, + l3skip, } -\next$Id: test2.tex 573 2006-08-21 20:59:37Z morten $ - {L3 Test 2} -% \fi - - -\RequirePackage[removeoldnames]{l3names} -\RequirePackage{l3expan} - -\CodeStart - - -\def_new:Npn\foo:nn#1#2{\def:Npn\xxx{(#1)(#2)}\tex_show:D\xxx} - -\def:Npn\a{A}\def:Npn\b{B} -\def:Npn\aa{\a}\def:Npn\bb{\b} - -\def:Npn\foo:oo{\exp_args:Noo\foo:nn} -\def:Npn\foo:xx{\exp_args:Nxx\foo:nn} -\def:Npn\foo:cc{\exp_args:Ncc\foo:nn} -\def:Npn\foo:nx{\exp_args:Nnx\foo:nn} - -\foo:nn{a}{b} - -\foo:nn{\a}{\b} - -\foo:oo\aa\bb - -\foo:xx\aa\bb - -\foo:cc{a}{b} - -\foo:nx{a}{\b} - -\tex_end:D +\RequirePackage{ + l3box, + l3keyval, + l3precom, + l3calc, + l3xref, + l3file +} +%% +%% +%% End of file `expl3.sty'. diff --git a/Master/texmf-dist/tex/latex/expl3/l3basics.sty b/Master/texmf-dist/tex/latex/expl3/l3basics.sty index d4e9c2abe9e..4d9e49664c5 100644 --- a/Master/texmf-dist/tex/latex/expl3/l3basics.sty +++ b/Master/texmf-dist/tex/latex/expl3/l3basics.sty @@ -15,7 +15,7 @@ %% Do not distribute a modified version of this file. %% %% -%% File: l3basics.dtx Copyright (C) 1990-2006 LaTeX3 project +%% File: l3basics.dtx Copyright (C) 1990-2008 LaTeX3 project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this @@ -33,7 +33,7 @@ %% %% The development version of the bundle can be found at %% -%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/ +%% http://www.latex-project.org/svnroot/experimental/trunk/ %% %% for those people who are interested. %% @@ -48,483 +48,675 @@ %% %% ----------------------------------------------------------------------- \RequirePackage{l3names} -\GetIdInfo$Id: l3basics.dtx 702 2007-11-27 14:21:49Z morten $ +\GetIdInfo$Id: l3basics.dtx 1365 2009-05-31 17:26:17Z mittelba $ {L3 Experimental basic definitions} \ProvidesExplPackage {\filename}{\filedate}{\fileversion}{\filedescription} -\tex_let:D \let:NwN \tex_let:D -\let:NwN \if_true: \tex_iftrue:D -\let:NwN \if_false: \tex_iffalse:D -\let:NwN \else: \tex_else:D -\let:NwN \fi: \tex_fi:D -\let:NwN \reverse_if:N \etex_unless:D -\let:NwN \if:w \tex_if:D -\let:NwN \if_charcode:w \tex_if:D -\let:NwN \if_catcode:w \tex_ifcat:D -\let:NwN \if_meaning:NN \tex_ifx:D -\let:NwN \if_token_eq:NN \tex_ifx:D -\let:NwN \if_cs_meaning_eq:NN\tex_ifx:D -\let:NwN \if_mode_math: \tex_ifmmode:D -\let:NwN \if_mode_horizontal:\tex_ifhmode:D -\let:NwN \if_mode_vertical: \tex_ifvmode:D -\let:NwN \if_mode_inner: \tex_ifinner:D -\let:NwN \if_cs_exist:N \etex_ifdefined:D -\let:NwN \if_cs_exist:w \etex_ifcsname:D -\let:NwN \exp_after:NN \tex_expandafter:D -\let:NwN \exp_not:N \tex_noexpand:D -\let:NwN \exp_not:n \etex_unexpanded: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 \cs_meaning:N \tex_meaning:D -\tex_def:D \cs_meaning:c #1{\exp_after:NN\cs_meaning:N\cs:w #1\cs_end:} -\let:NwN \cs_show:N \tex_show:D -\tex_def:D \cs_show:c #1{\exp_after:NN\cs_show:N\cs:w #1\cs_end:} -\let:NwN \scan_stop: \tex_relax:D -\let:NwN \group_begin: \tex_begingroup:D -\let:NwN \group_end: \tex_endgroup:D -\let:NwN \group_execute_after:N \tex_aftergroup:D -\let:NwN \the_internal:D \tex_the:D -\let:NwN \pref_global:D \tex_global:D -\let:NwN \pref_long:D \tex_long:D -\let:NwN \pref_protected:D \etex_protected:D -\let:NwN \def:Npn \tex_def:D -\let:NwN \def:Npx \tex_edef:D -\pref_protected:D \def:Npn \def_long:Npn {\pref_long:D \def:Npn} -\pref_protected:D \def:Npn \def_long:Npx {\pref_long:D \def:Npx} -\pref_protected:D \def:Npn \def_protected:Npn {\pref_protected:D \def:Npn} -\pref_protected:D \def:Npn \def_protected:Npx {\pref_protected:D \def:Npx} -\def_protected:Npn \def_protected_long:Npn { - \pref_protected:D \pref_long:D \def:Npn -} -\def_protected:Npn \def_protected_long:Npx { - \pref_protected:D \pref_long:D \def:Npx -} -\let:NwN \gdef:Npn \tex_gdef:D -\let:NwN \gdef:Npx \tex_xdef:D -\def_protected:Npn \gdef_long:Npn {\pref_long:D \gdef:Npn} -\def_protected:Npn \gdef_long:Npx {\pref_long:D \gdef:Npx} -\def_protected:Npn \gdef_protected:Npn {\pref_protected:D \gdef:Npn} -\def_protected:Npn \gdef_protected:Npx {\pref_protected:D \gdef:Npx} -\def_protected:Npn \gdef_protected_long:Npn { - \pref_protected:D \pref_long:D \gdef:Npn -} -\def_protected:Npn \gdef_protected_long:Npx { - \pref_protected:D \pref_long:D \gdef:Npx -} -\def:Npn \c_true {00} -\def:Npn \c_false {01} -\let:NwN \c_minus_one\m@ne -\tex_chardef:D \c_sixteen = 16\scan_stop: -\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 } -\def:Npn\err_latex_bug:x#1{ - \io_put_term:x{This~is~a~LaTeX~bug!~Check~coding!}\tex_errmessage:D{#1}} -\def:Npn \cs_record_meaning:N#1{} -\def_long:Npn \use_none:n #1{} -\def_long:Npn \use_arg_i:n #1{#1} -\def:Npn \chk_new_cs:N #1{ - \if:w \cs_if_free_p:N #1 - \exp_after:NN \use_none:n +\package_check_loaded_expl: +\tex_let:D \cs_set_eq:NwN \tex_let:D +\cs_set_eq:NwN \if_true: \tex_iftrue:D +\cs_set_eq:NwN \if_false: \tex_iffalse:D +\cs_set_eq:NwN \or: \tex_or:D +\cs_set_eq:NwN \else: \tex_else:D +\cs_set_eq:NwN \fi: \tex_fi:D +\cs_set_eq:NwN \reverse_if:N \etex_unless:D +\cs_set_eq:NwN \if:w \tex_if:D +\cs_set_eq:NwN \if_bool:N \tex_ifodd:D +\cs_set_eq:NwN \if_predicate:w \tex_ifodd:D +\cs_set_eq:NwN \if_charcode:w \tex_if:D +\cs_set_eq:NwN \if_catcode:w \tex_ifcat:D +\cs_set_eq:NwN \if_meaning:w \tex_ifx:D +\cs_set_eq:NwN \if_mode_math: \tex_ifmmode:D +\cs_set_eq:NwN \if_mode_horizontal: \tex_ifhmode:D +\cs_set_eq:NwN \if_mode_vertical: \tex_ifvmode:D +\cs_set_eq:NwN \if_mode_inner: \tex_ifinner:D +\cs_set_eq:NwN \if_cs_exist:N \etex_ifdefined:D +\cs_set_eq:NwN \if_cs_exist:w \etex_ifcsname:D +\cs_set_eq:NwN \exp_after:wN \tex_expandafter:D +\cs_set_eq:NwN \exp_not:N \tex_noexpand:D +\cs_set_eq:NwN \exp_not:n \etex_unexpanded:D +\cs_set_eq:NwN \iow_shipout_x:Nn \tex_write:D +\cs_set_eq:NwN \token_to_meaning:N \tex_meaning:D +\cs_set_eq:NwN \token_to_str:N \tex_string:D +\cs_set_eq:NwN \cs:w \tex_csname:D +\cs_set_eq:NwN \cs_end: \tex_endcsname:D +\cs_set_eq:NwN \cs_meaning:N \tex_meaning:D +\tex_def:D \cs_meaning:c {\exp_args:Nc\cs_meaning:N} +\cs_set_eq:NwN \cs_show:N \tex_show:D +\tex_def:D \cs_show:c {\exp_args:Nc\cs_show:N} +\tex_def:D \token_to_str:c {\exp_args:Nc\token_to_str:N} +\cs_set_eq:NwN \scan_stop: \tex_relax:D +\cs_set_eq:NwN \group_begin: \tex_begingroup:D +\cs_set_eq:NwN \group_end: \tex_endgroup:D +\cs_set_eq:NwN \group_execute_after:N \tex_aftergroup:D +\cs_set_eq:NwN \pref_global:D \tex_global:D +\cs_set_eq:NwN \pref_long:D \tex_long:D +\cs_set_eq:NwN \pref_protected:D \etex_protected:D +\cs_set_eq:NwN \cs_set_nopar:Npn \tex_def:D +\cs_set_eq:NwN \cs_set_nopar:Npx \tex_edef:D +\pref_protected:D \cs_set_nopar:Npn \cs_set:Npn { + \pref_long:D \cs_set_nopar:Npn +} +\pref_protected:D \cs_set_nopar:Npn \cs_set:Npx { + \pref_long:D \cs_set_nopar:Npx +} +\pref_protected:D \cs_set_nopar:Npn \cs_set_protected_nopar:Npn { + \pref_protected:D \cs_set_nopar:Npn +} +\pref_protected:D \cs_set_nopar:Npn \cs_set_protected_nopar:Npx { + \pref_protected:D \cs_set_nopar:Npx +} +\cs_set_protected_nopar:Npn \cs_set_protected:Npn { + \pref_protected:D \pref_long:D \cs_set_nopar:Npn +} +\cs_set_protected_nopar:Npn \cs_set_protected:Npx { + \pref_protected:D \pref_long:D \cs_set_nopar:Npx +} +\cs_set_eq:NwN \cs_gset_nopar:Npn \tex_gdef:D +\cs_set_eq:NwN \cs_gset_nopar:Npx \tex_xdef:D +\cs_set_protected_nopar:Npn \cs_gset:Npn { + \pref_long:D \cs_gset_nopar:Npn +} +\cs_set_protected_nopar:Npn \cs_gset:Npx { + \pref_long:D \cs_gset_nopar:Npx +} +\cs_set_protected_nopar:Npn \cs_gset_protected_nopar:Npn { + \pref_protected:D \cs_gset_nopar:Npn +} +\cs_set_protected_nopar:Npn \cs_gset_protected_nopar:Npx { + \pref_protected:D \cs_gset_nopar:Npx +} +\cs_set_protected_nopar:Npn \cs_gset_protected:Npn { + \pref_protected:D \pref_long:D \cs_gset_nopar:Npn +} +\cs_set_protected_nopar:Npn \cs_gset_protected:Npx { + \pref_protected:D \pref_long:D \cs_gset_nopar:Npx +} +\cs_set:Npn \use:c #1 { \cs:w#1\cs_end: } +\cs_set:Npn \use:n #1 {#1} +\cs_set:Npn \use:nn #1#2 {#1#2} +\cs_set:Npn \use:nnn #1#2#3 {#1#2#3} +\cs_set:Npn \use:nnnn #1#2#3#4 {#1#2#3#4} +\cs_set:Npn \use_i:nn #1#2 {#1} +\cs_set:Npn \use_ii:nn #1#2 {#2} +\cs_set:Npn \use_i:nnn #1#2#3{#1} +\cs_set:Npn \use_ii:nnn #1#2#3{#2} +\cs_set:Npn \use_iii:nnn #1#2#3{#3} +\cs_set:Npn \use_i:nnnn #1#2#3#4{#1} +\cs_set:Npn \use_ii:nnnn #1#2#3#4{#2} +\cs_set:Npn \use_iii:nnnn #1#2#3#4{#3} +\cs_set:Npn \use_iv:nnnn #1#2#3#4{#4} +\cs_set:Npn \use_i_ii:nnn #1#2#3{#1#2} +\cs_set:Npn \use_none_delimit_by_q_nil:w #1\q_nil{} +\cs_set:Npn \use_none_delimit_by_q_stop:w #1\q_stop{} +\cs_set:Npn \use_none_delimit_by_q_recursion_stop:w #1 \q_recursion_stop {} +\cs_set:Npn \use_i_delimit_by_q_nil:nw #1#2\q_nil{#1} +\cs_set:Npn \use_i_delimit_by_q_stop:nw #1#2\q_stop{#1} +\cs_set:Npn \use_i_delimit_by_q_recursion_stop:nw #1#2 \q_recursion_stop {#1} +\cs_set:Npn \use_i_after_fi:nw #1\fi:{\fi: #1} +\cs_set:Npn \use_i_after_else:nw #1\else:#2\fi:{\fi: #1} +\cs_set:Npn \use_i_after_or:nw #1\or: #2\fi: {\fi:#1} +\cs_set:Npn \use_i_after_orelse:nw #1 #2#3\fi: {\fi:#1} +\cs_set:Npn \use_none:n #1{} +\cs_set:Npn \use_none:nn #1#2{} +\cs_set:Npn \use_none:nnn #1#2#3{} +\cs_set:Npn \use_none:nnnn #1#2#3#4{} +\cs_set:Npn \use_none:nnnnn #1#2#3#4#5{} +\cs_set:Npn \use_none:nnnnnn #1#2#3#4#5#6{} +\cs_set:Npn \use_none:nnnnnnn #1#2#3#4#5#6#7{} +\cs_set:Npn \use_none:nnnnnnnn #1#2#3#4#5#6#7#8{} +\cs_set:Npn \use_none:nnnnnnnnn #1#2#3#4#5#6#7#8#9{} +\cs_set:Npn \exp_args:Nc #1#2{\exp_after:wN#1\cs:w#2\cs_end:} +\cs_set:Npn \prg_return_true: { \exp_after:wN\if_true:\tex_romannumeral:D } +\cs_set:Npn \prg_return_false: {\exp_after:wN\if_false:\tex_romannumeral:D } +\cs_set:Npn \prg_set_conditional:Npnn #1{ + \prg_get_parm_aux:nw{ + \cs_split_function:NN #1 \prg_generate_conditional_aux:nnNNnnnn + \cs_set:Npn {parm} + } +} +\cs_set:Npn \prg_new_conditional:Npnn #1{ + \prg_get_parm_aux:nw{ + \cs_split_function:NN #1 \prg_generate_conditional_aux:nnNNnnnn + \cs_new:Npn {parm} + } +} +\cs_set:Npn \prg_set_protected_conditional:Npnn #1{ + \prg_get_parm_aux:nw{ + \cs_split_function:NN #1 \prg_generate_conditional_aux:nnNNnnnn + \cs_set_protected:Npn {parm} + } +} +\cs_set:Npn \prg_new_protected_conditional:Npnn #1{ + \prg_get_parm_aux:nw{ + \cs_split_function:NN #1 \prg_generate_conditional_aux:nnNNnnnn + \cs_new_protected:Npn {parm} + } +} +\cs_set:Npn \prg_set_conditional:Nnn #1{ + \exp_args:Nnf \prg_get_count_aux:nn{ + \cs_split_function:NN #1 \prg_generate_conditional_aux:nnNNnnnn + \cs_set:Npn {count} + }{\cs_get_arg_count_from_signature:N #1} +} +\cs_set:Npn \prg_new_conditional:Nnn #1{ + \exp_args:Nnf \prg_get_count_aux:nn{ + \cs_split_function:NN #1 \prg_generate_conditional_aux:nnNNnnnn + \cs_new:Npn {count} + }{\cs_get_arg_count_from_signature:N #1} +} + +\cs_set:Npn \prg_set_protected_conditional:Nnn #1{ + \exp_args:Nnf \prg_get_count_aux:nn{ + \cs_split_function:NN #1 \prg_generate_conditional_aux:nnNNnnnn + \cs_set_protected:Npn {count} + }{\cs_get_arg_count_from_signature:N #1} +} + +\cs_set:Npn \prg_new_protected_conditional:Nnn #1{ + \exp_args:Nnf \prg_get_count_aux:nn{ + \cs_split_function:NN #1 \prg_generate_conditional_aux:nnNNnnnn + \cs_new_protected:Npn {count} + }{\cs_get_arg_count_from_signature:N #1} +} +\cs_set:Npn \prg_get_count_aux:nn #1#2 {#1{#2}} +\cs_set:Npn \prg_get_parm_aux:nw #1#2#{#1{#2}} +\cs_set:Npn \prg_generate_conditional_aux:nnNNnnnn #1#2#3#4#5#6#7#8{ + \prg_generate_conditional_aux:nnw{#5}{ + #4{#1}{#2}{#6}{#8} + }#7,?, \q_recursion_stop +} +\cs_set:Npn \prg_generate_conditional_aux:nnw #1#2#3,{ + \if:w ?#3 + \exp_after:wN \use_none_delimit_by_q_recursion_stop:w + \fi: + \use:c{prg_generate_#3_form_#1:Nnnnn} #2 + \prg_generate_conditional_aux:nnw{#1}{#2} +} +\cs_set:Npn \prg_generate_p_form_parm:Nnnnn #1#2#3#4#5{ + \exp_args:Nc #1 {#2_p:#3}#4{#5 \c_zero + \exp_after:wN\c_true_bool\else:\exp_after:wN\c_false_bool\fi: + } +} +\cs_set:Npn \prg_generate_TF_form_parm:Nnnnn #1#2#3#4#5{ + \exp_args:Nc#1 {#2:#3TF}#4{#5 \c_zero + \exp_after:wN \use_i:nn \else: \exp_after:wN \use_ii:nn \fi: + } +} +\cs_set:Npn \prg_generate_T_form_parm:Nnnnn #1#2#3#4#5{ + \exp_args:Nc#1 {#2:#3T}#4{#5 \c_zero + \else:\exp_after:wN\use_none:nn\fi:\use:n + } +} +\cs_set:Npn \prg_generate_F_form_parm:Nnnnn #1#2#3#4#5{ + \exp_args:Nc#1 {#2:#3F}#4{#5 \c_zero + \exp_after:wN\use_none:nn\fi:\use:n + } +} +\cs_set:Npn \prg_generate_p_form_count:Nnnnn #1#2#3#4#5{ + \cs_generate_from_arg_count:cNnn {#2_p:#3} #1 {#4}{#5 \c_zero + \exp_after:wN\c_true_bool\else:\exp_after:wN\c_false_bool\fi: + } +} +\cs_set:Npn \prg_generate_TF_form_count:Nnnnn #1#2#3#4#5{ + \cs_generate_from_arg_count:cNnn {#2:#3TF} #1 {#4}{#5 \c_zero + \exp_after:wN\use_i:nn\else:\exp_after:wN\use_ii:nn\fi: + } +} +\cs_set:Npn \prg_generate_T_form_count:Nnnnn #1#2#3#4#5{ + \cs_generate_from_arg_count:cNnn {#2:#3T} #1 {#4}{#5 \c_zero + \else:\exp_after:wN\use_none:nn\fi:\use:n + } +} +\cs_set:Npn \prg_generate_F_form_count:Nnnnn #1#2#3#4#5{ + \cs_generate_from_arg_count:cNnn {#2:#3F} #1 {#4}{#5 \c_zero + \exp_after:wN\use_none:nn\fi:\use:n + } +} +\tex_chardef:D \c_true_bool = 1~ +\tex_chardef:D \c_false_bool = 0~ +\cs_set_nopar:Npn \cs_to_str:N { + \if:w \exp_after:wN \cs_str_aux:w\token_to_str:N \a ax\q_nil + \else: + \exp_after:wN \exp_after:wN\exp_after:wN \use_ii:nn + \fi: + \exp_after:wN \use_none:n \token_to_str:N +} +\cs_set:Npn \cs_str_aux:w #1#2#3#4\q_nil{#2#3} +\group_begin: + \tex_lccode:D `\@ = `\: \scan_stop: + \tex_catcode:D `\@ = 12~ +\tex_lowercase:D { + \group_end: +\cs_set:Npn \cs_split_function:NN #1#2{ + \exp_after:wN \cs_split_function_aux:w + \tex_romannumeral:D -`\q \cs_to_str:N #1 @a \q_nil #2 +} +\cs_set:Npn \cs_split_function_aux:w #1@#2#3\q_nil#4{ + \if_meaning:w a#2 + \exp_after:wN \use_i:nn + \else: + \exp_after:wN\use_ii:nn + \fi: + {#4{#1}{}\c_false_bool} + {\cs_split_function_auxii:w#2#3\q_nil #4{#1}} +} +\cs_set:Npn \cs_split_function_auxii:w #1@a\q_nil#2#3{ + #2{#3}{#1}\c_true_bool +} +} +\cs_set:Npn \cs_get_function_name:N #1 { + \cs_split_function:NN #1\use_i:nnn +} +\cs_set:Npn \cs_get_function_signature:N #1 { + \cs_split_function:NN #1\use_ii:nnn +} +\prg_set_conditional:Npnn \cs_if_exist:N #1 {p,TF,T,F}{ + \if_meaning:w #1\tex_relax:D + \prg_return_false: + \else: + \if_cs_exist:N #1 + \prg_return_true: + \else: + \prg_return_false: + \fi: + \fi: +} +\prg_set_conditional:Npnn \cs_if_exist:c #1 {p,TF,T,F}{ + \if_cs_exist:w #1 \cs_end: + \exp_after:wN \use_i:nn \else: - \exp_after:NN \use_arg_i:n + \exp_after:wN \use_ii:nn \fi: { - \err_latex_bug:x {Command~name~`\token_to_string:N #1'~ + \exp_after:wN \if_meaning:w \cs:w #1\cs_end: \tex_relax:D + \prg_return_false: + \else: + \prg_return_true: + \fi: + } + \prg_return_false: +} +\cs_set:Npn \cs_if_do_not_use_p:N #1{ + \cs_split_function:NN #1 \cs_if_do_not_use_aux:nnN +} +\cs_set:Npn \cs_if_do_not_use_aux:nnN #1#2#3{ + \exp_after:wN\str_if_eq_p:nn \token_to_str:N D {#2} +} +\prg_set_conditional:Npnn \cs_if_free:N #1{p,TF,T,F}{ + \tex_ifnum:D \cs_if_exist_p:N #1 =\c_zero + \exp_after:wN \use_i:nn + \else: + \exp_after:wN \use_ii:nn + \fi: + { + \tex_ifnum:D \cs_if_do_not_use_p:N #1 =\c_zero + \prg_return_true: + \else: + \prg_return_false: + \fi: + } + \prg_return_false: +} +\cs_set_nopar:Npn \cs_if_free_p:c{\exp_args:Nc\cs_if_free_p:N} +\cs_set_nopar:Npn \cs_if_free:cTF{\exp_args:Nc\cs_if_free:NTF} +\cs_set_nopar:Npn \cs_if_free:cT{\exp_args:Nc\cs_if_free:NT} +\cs_set_nopar:Npn \cs_if_free:cF{\exp_args:Nc\cs_if_free:NF} +\cs_set_eq:NwN \c_minus_one\m@ne +\tex_chardef:D \c_sixteen = 16~ +\tex_chardef:D \c_zero = 0~ +\cs_set_nopar:Npn \iow_log:x { + \tex_immediate:D \iow_shipout_x:Nn \c_minus_one +} +\cs_set_nopar:Npn \iow_term:x { + \tex_immediate:D \iow_shipout_x:Nn \c_sixteen +} +\cs_set_nopar:Npn \msg_kernel_bug:x #1 { + \iow_term:x { This~is~a~LaTeX~bug:~check~coding! } + \tex_errmessage:D {#1} +} +\cs_set:Npn \cs_record_meaning:N #1{} +\cs_set_nopar:Npn \chk_if_free_cs:N #1{ + \cs_if_free:NF #1 + { + \msg_kernel_bug:x {Command~name~`\token_to_str:N #1'~ already~defined!~ Current~meaning:~\token_to_meaning:N #1 } } \cs_record_meaning:N#1 - \io_put_log:x{Defining~\token_to_string:N #1~on~ + \iow_log:x{Defining~\token_to_str:N #1~on~ line~\tex_the:D \tex_inputlineno:D} } -\def:Npn \cs_if_exist_p:N #1{ - \if:w \cs_if_free_p:N #1 - \c_false - \else: - \c_true \fi:} -\def:Npn \chk_if_exist_cs:N #1 { - \if:w \cs_if_exist_p:N #1 - \else: - \err_latex_bug:x{Command~ `\token_to_string:N #1'~ +\cs_set_nopar:Npn \chk_if_exist_cs:N #1 { + \cs_if_exist:NF #1 + { + \msg_kernel_bug:x {Command~ `\token_to_str:N #1'~ not~ yet~ defined!} - \fi:} -\def:Npn \chk_if_exist_cs:c #1 { - \exp_after:NN \chk_if_exist_cs:N \cs:w #1\cs_end: } -\def:Npn \cs_if_free_p:N #1{ - \if_cs_exist:N #1 - \if_meaning:NN#1\scan_stop: - \if:w\cs_if_eq_name_p:NN #1\scan_stop: - \c_false \else: \c_true \fi: - \else: - \c_false - \fi: - \else: - \if:w \cs_if_eq_name_p:NN #1\c_undefined - \c_false \else: \c_true \fi: - \fi: + } } -\let:NwN \cs_free_p:N \cs_if_free_p:N -\def:Npn \str_if_eq_p:nn #1#2{ +\cs_set_nopar:Npn \chk_if_exist_cs:c {\exp_args:Nc \chk_if_exist_cs:N } +\prg_set_conditional:Npnn \str_if_eq:nn #1#2{p}{ \str_if_eq_p_aux:w #1\scan_stop:\\#2\scan_stop:\\ } -\def:Npn \str_if_eq_p_aux:w #1#2\\#3#4\\{ - \if_meaning:NN#1#3 - \if_meaning:NN#1\scan_stop:\c_true \else: - \if_meaning:NN#3\scan_stop:\c_false \else: +\cs_set_nopar:Npn \str_if_eq_p_aux:w #1#2\\#3#4\\{ + \if_meaning:w#1#3 + \if_meaning:w#1\scan_stop:\prg_return_true: \else: + \if_meaning:w#3\scan_stop:\prg_return_false: \else: \str_if_eq_p_aux:w #2\\#4\\\fi:\fi: - \else:\c_false \fi:} -\def_long:Npn \cs_if_eq_name_p:NN #1#2{ - \exp_after:NN\exp_after:NN - \exp_after:NN\str_if_eq_p_aux:w - \exp_after:NN\token_to_string:N - \exp_after:NN#1 - \exp_after:NN\scan_stop: - \exp_after:NN\\ - \token_to_string:N#2\scan_stop:\\} -\def:Npn \str_if_eq_var_p:nf#1{ - \if:w \tex_number:D\str_if_eq_var_start:nnN{}{}#1\scan_stop: -} -\def:Npn\str_if_eq_var_start:nnN#1#2#3{ - \if:w#3\scan_stop:\exp_after:NN\str_if_eq_var_stop:w\fi: + \else:\prg_return_false: \fi:} +\prg_set_conditional:Npnn \cs_if_eq_name:NN #1#2{p}{ + \exp_after:wN\exp_after:wN + \exp_after:wN\str_if_eq_p_aux:w + \exp_after:wN\token_to_str:N + \exp_after:wN#1 + \exp_after:wN\scan_stop: + \exp_after:wN\\ + \token_to_str:N#2\scan_stop:\\} +\prg_set_conditional:Npnn \str_if_eq_var:nf #1#2 {p} { + \if:w \tex_number:D\str_if_eq_var_start:nnN{}{}#1\scan_stop:{#2} +} +\cs_set_nopar:Npn\str_if_eq_var_start:nnN#1#2#3{ + \if:w#3\scan_stop:\exp_after:wN\str_if_eq_var_stop:w\fi: \str_if_eq_var_start:nnN{\if:w#3#1}{#2\fi:} } -\def:Npn\str_if_eq_var_stop:w\str_if_eq_var_start:nnN#1#2#3{ - #1#3\scan_stop:'#213~\c_true\else:\c_false\fi: -} -\def_protected:Npn \def_new:Npn #1{\chk_new_cs:N #1 - \def:Npn #1} -\def_protected:Npn \def_new:Npx #1{\chk_new_cs:N #1 - \def:Npx #1} -\def_protected:Npn \def_long_new:Npn #1{\chk_new_cs:N #1 - \def_long:Npn #1} -\def_protected:Npn \def_long_new:Npx #1{\chk_new_cs:N #1 - \def_long:Npx #1} -\def_protected:Npn \def_protected_new:Npn #1{\chk_new_cs:N #1 - \def_protected:Npn #1} -\def_protected:Npn \def_protected_new:Npx #1{\chk_new_cs:N #1 - \def_protected:Npx #1} -\def_protected:Npn \def_protected_long_new:Npn #1{\chk_new_cs:N #1 - \def_protected_long:Npn #1} -\def_protected:Npn \def_protected_long_new:Npx #1{\chk_new_cs:N #1 - \def_protected_long:Npx #1} -\def_protected_new:Npn \gdef_new:Npn #1{\chk_new_cs:N #1 - \gdef:Npn #1} -\def_protected_new:Npn \gdef_new:Npx #1{\chk_new_cs:N #1 - \gdef:Npx #1} -\def_protected_new:Npn \gdef_long_new:Npn #1{\chk_new_cs:N #1 - \gdef_long:Npn #1} -\def_protected_new:Npn \gdef_long_new:Npx #1{\chk_new_cs:N #1 - \gdef_long:Npx #1} -\def_protected_new:Npn \gdef_protected_new:Npn #1{\chk_new_cs:N #1 - \gdef_protected:Npn #1} -\def_protected_new:Npn \gdef_protected_new:Npx #1{\chk_new_cs:N #1 - \gdef_protected:Npx #1} -\def_protected_new:Npn \gdef_protected_long_new:Npn #1{\chk_new_cs:N #1 - \gdef_protected_long:Npn #1} -\def_protected_new:Npn \gdef_protected_long_new:Npx #1{\chk_new_cs:N #1 - \gdef_protected_long:Npx #1} -\def_new:Npn \def:cpn #1{\exp_after:NN \def:Npn \cs:w #1\cs_end:} -\def_new:Npn \def:cpx #1{\exp_after:NN \def:Npx \cs:w #1\cs_end:} -\def_new:Npn \gdef:cpn #1{\exp_after:NN \gdef:Npn \cs:w #1\cs_end:} -\def_new:Npn \gdef:cpx #1{\exp_after:NN \gdef:Npx \cs:w #1\cs_end:} -\def_new:Npn \def_new:cpn #1{\exp_after:NN \def_new:Npn \cs:w #1\cs_end:} -\def_new:Npn \def_new:cpx #1{\exp_after:NN \def_new:Npx \cs:w #1\cs_end:} -\def_new:Npn \gdef_new:cpn #1{\exp_after:NN \gdef_new:Npn \cs:w #1\cs_end:} -\def_new:Npn \gdef_new:cpx #1{\exp_after:NN \gdef_new:Npx \cs:w #1\cs_end:} -\def_new:Npn \def_long:cpn #1{\exp_after:NN \def_long:Npn \cs:w #1\cs_end:} -\def_new:Npn \def_long:cpx #1{ - \exp_after:NN\def_long:Npx\cs:w #1\cs_end:} -\def_new:Npn \gdef_long:cpn #1{ - \exp_after:NN \gdef_long:Npn \cs:w #1\cs_end:} -\def_new:Npn \gdef_long:cpx #1{ - \exp_after:NN\gdef_long:Npx\cs:w #1\cs_end:} -\def_new:Npn \def_long_new:cpn #1{ - \exp_after:NN \def_long_new:Npn \cs:w #1\cs_end:} -\def_new:Npn \def_long_new:cpx #1{ - \exp_after:NN \def_long_new:Npx \cs:w #1\cs_end:} -\def_new:Npn \gdef_long_new:cpn #1{ - \exp_after:NN \gdef_long_new:Npn \cs:w #1\cs_end:} -\def_new:Npn \gdef_long_new:cpx #1{ - \exp_after:NN \gdef_long_new:Npx \cs:w #1\cs_end:} -\def_new:Npn \def_protected:cpn #1{ - \exp_after:NN \def_protected:Npn \cs:w #1\cs_end:} -\def_new:Npn \def_protected:cpx #1{ - \exp_after:NN\def_protected:Npx\cs:w #1\cs_end:} -\def_new:Npn \gdef_protected:cpn #1{ - \exp_after:NN \gdef_protected:Npn \cs:w #1\cs_end:} -\def_new:Npn \gdef_protected:cpx #1{ - \exp_after:NN\gdef_protected:Npx\cs:w #1\cs_end:} -\def_new:Npn \def_protected_new:cpn #1{ - \exp_after:NN \def_protected_new:Npn \cs:w #1\cs_end:} -\def_new:Npn \def_protected_new:cpx #1{ - \exp_after:NN \def_protected_new:Npx \cs:w #1\cs_end:} -\def_new:Npn \gdef_protected_new:cpn #1{ - \exp_after:NN \gdef_protected_new:Npn \cs:w #1\cs_end:} -\def_new:Npn \gdef_protected_new:cpx #1{ - \exp_after:NN \gdef_protected_new:Npx \cs:w #1\cs_end:} -\def_new:Npn \def_protected_long:cpn #1{ - \exp_after:NN \def_protected_long:Npn \cs:w #1\cs_end:} -\def_new:Npn \def_protected_long:cpx #1{ - \exp_after:NN\def_protected_long:Npx\cs:w #1\cs_end:} -\def_new:Npn \gdef_protected_long:cpn #1{ - \exp_after:NN \gdef_protected_long:Npn \cs:w #1\cs_end:} -\def_new:Npn \gdef_protected_long:cpx #1{ - \exp_after:NN\gdef_protected_long:Npx\cs:w #1\cs_end:} -\def_new:Npn \def_protected_long_new:cpn #1{ - \exp_after:NN \def_protected_long_new:Npn \cs:w #1\cs_end:} -\def_new:Npn \def_protected_long_new:cpx #1{ - \exp_after:NN \def_protected_long_new:Npx \cs:w #1\cs_end:} -\def_new:Npn \gdef_protected_long_new:cpn #1{ - \exp_after:NN \gdef_protected_long_new:Npn \cs:w #1\cs_end:} -\def_new:Npn \gdef_protected_long_new:cpx #1{ - \exp_after:NN \gdef_protected_long_new:Npx \cs:w #1\cs_end:} -\def_new:cpn {def_aux_0:NNn} #1#2 {#1 #2 } -\def_new:cpn {def_aux_1:NNn} #1#2 {#1 #2 ##1 } -\def_new:cpn {def_aux_2:NNn} #1#2 {#1 #2 ##1##2 } -\def_new:cpn {def_aux_3:NNn} #1#2 {#1 #2 ##1##2##3 } -\def_new:cpn {def_aux_4:NNn} #1#2 {#1 #2 ##1##2##3##4 } -\def_new:cpn {def_aux_5:NNn} #1#2 {#1 #2 ##1##2##3##4##5 } -\def_new:cpn {def_aux_6:NNn} #1#2 {#1 #2 ##1##2##3##4##5##6 } -\def_new:cpn {def_aux_7:NNn} #1#2 {#1 #2 ##1##2##3##4##5##6##7 } -\def_new:cpn {def_aux_8:NNn} #1#2 {#1 #2 ##1##2##3##4##5##6##7##8 } -\def_new:cpn {def_aux_9:NNn} #1#2 {#1 #2 ##1##2##3##4##5##6##7##8##9 } -\def_protected_long_new:Npn \def_aux:NNnn #1#2#3#4 { - \cs_if_really_exist:cTF {def_aux_\tex_the:D\etex_numexpr:D #3 :NNn} +\cs_set:Npn\str_if_eq_var_stop:w\str_if_eq_var_start:nnN#1#2#3{ + #1#3\scan_stop:'#213~\prg_return_true:\else:\prg_return_false:\fi: +} +\cs_set:Npn \cs_tmp:w #1#2{ + \cs_set_protected_nopar:Npn #1 ##1 { + \chk_if_free_cs:N ##1 + #2 ##1 + } +} +\cs_tmp:w \cs_new_nopar:Npn \cs_set_nopar:Npn +\cs_tmp:w \cs_new_nopar:Npx\cs_set_nopar:Npx +\cs_tmp:w \cs_new:Npn \cs_set:Npn +\cs_tmp:w \cs_new:Npx\cs_set:Npx +\cs_tmp:w \cs_new_protected_nopar:Npn \cs_set_protected_nopar:Npn +\cs_tmp:w \cs_new_protected_nopar:Npx\cs_set_protected_nopar:Npx +\cs_tmp:w \cs_new_protected:Npn \cs_set_protected:Npn +\cs_tmp:w \cs_new_protected:Npx\cs_set_protected:Npx +\cs_tmp:w \cs_gnew_nopar:Npn \cs_gset_nopar:Npn +\cs_tmp:w \cs_gnew_nopar:Npx \cs_gset_nopar:Npx +\cs_tmp:w \cs_gnew:Npn \cs_gset:Npn +\cs_tmp:w \cs_gnew:Npx \cs_gset:Npx +\cs_tmp:w \cs_gnew_protected_nopar:Npn \cs_gset_protected_nopar:Npn +\cs_tmp:w \cs_gnew_protected_nopar:Npx \cs_gset_protected_nopar:Npx +\cs_tmp:w \cs_gnew_protected:Npn \cs_gset_protected:Npn +\cs_tmp:w \cs_gnew_protected:Npx \cs_gset_protected:Npx +\cs_set:Npn \cs_tmp:w #1#2{ + \cs_new_nopar:Npn #1 { \exp_args:Nc #2 } +} +\cs_tmp:w \cs_set_nopar:cpn \cs_set_nopar:Npn +\cs_tmp:w \cs_set_nopar:cpx \cs_set_nopar:Npx +\cs_tmp:w \cs_gset_nopar:cpn \cs_gset_nopar:Npn +\cs_tmp:w \cs_gset_nopar:cpx \cs_gset_nopar:Npx +\cs_tmp:w \cs_new_nopar:cpn \cs_new_nopar:Npn +\cs_tmp:w \cs_new_nopar:cpx \cs_new_nopar:Npx +\cs_tmp:w \cs_gnew_nopar:cpn \cs_gnew_nopar:Npn +\cs_tmp:w \cs_gnew_nopar:cpx \cs_gnew_nopar:Npx +\cs_tmp:w \cs_set:cpn \cs_set:Npn +\cs_tmp:w \cs_set:cpx \cs_set:Npx +\cs_tmp:w \cs_gset:cpn \cs_gset:Npn +\cs_tmp:w \cs_gset:cpx \cs_gset:Npx +\cs_tmp:w \cs_new:cpn \cs_new:Npn +\cs_tmp:w \cs_new:cpx \cs_new:Npx +\cs_tmp:w \cs_gnew:cpn \cs_gnew:Npn +\cs_tmp:w \cs_gnew:cpx \cs_gnew:Npx +\cs_tmp:w \cs_set_protected_nopar:cpn \cs_set_protected_nopar:Npn +\cs_tmp:w \cs_set_protected_nopar:cpx \cs_set_protected_nopar:Npx +\cs_tmp:w \cs_gset_protected_nopar:cpn \cs_gset_protected_nopar:Npn +\cs_tmp:w \cs_gset_protected_nopar:cpx \cs_gset_protected_nopar:Npx +\cs_tmp:w \cs_new_protected_nopar:cpn \cs_new_protected_nopar:Npn +\cs_tmp:w \cs_new_protected_nopar:cpx \cs_new_protected_nopar:Npx +\cs_tmp:w \cs_gnew_protected_nopar:cpn \cs_gnew_protected_nopar:Npn +\cs_tmp:w \cs_gnew_protected_nopar:cpx \cs_gnew_protected_nopar:Npx +\cs_tmp:w \cs_set_protected:cpn \cs_set_protected:Npn +\cs_tmp:w \cs_set_protected:cpx \cs_set_protected:Npx +\cs_tmp:w \cs_gset_protected:cpn \cs_gset_protected:Npn +\cs_tmp:w \cs_gset_protected:cpx \cs_gset_protected:Npx +\cs_tmp:w \cs_new_protected:cpn \cs_new_protected:Npn +\cs_tmp:w \cs_new_protected:cpx \cs_new_protected:Npx +\cs_tmp:w \cs_gnew_protected:cpn \cs_gnew_protected:Npn +\cs_tmp:w \cs_gnew_protected:cpx \cs_gnew_protected:Npx +\cs_set_nopar:cpn{use_0_parameter:}{} +\cs_set_nopar:cpn{use_1_parameter:}{{##1}} +\cs_set_nopar:cpn{use_2_parameter:}{{##1}{##2}} +\cs_set_nopar:cpn{use_3_parameter:}{{##1}{##2}{##3}} +\cs_set_nopar:cpn{use_4_parameter:}{{##1}{##2}{##3}{##4}} +\cs_set_nopar:cpn{use_5_parameter:}{{##1}{##2}{##3}{##4}{##5}} +\cs_set_nopar:cpn{use_6_parameter:}{{##1}{##2}{##3}{##4}{##5}{##6}} +\cs_set_nopar:cpn{use_7_parameter:}{{##1}{##2}{##3}{##4}{##5}{##6}{##7}} +\cs_set_nopar:cpn{use_8_parameter:}{ + {##1}{##2}{##3}{##4}{##5}{##6}{##7}{##8}} +\cs_set_nopar:cpn{use_9_parameter:}{ + {##1}{##2}{##3}{##4}{##5}{##6}{##7}{##8}{##9}} +\cs_set_protected:Npn \cs_set_eq:NN #1 { \cs_set_eq:NwN #1=~ } +\cs_set_nopar:Npn \cs_set_eq:cN { \exp_args:Nc \cs_set_eq:NN } +\cs_set_nopar:Npn \cs_set_eq:Nc { \exp_args:NNc \cs_set_eq:NN } +\cs_set_nopar:Npn \cs_set_eq:cc { \exp_args:Ncc \cs_set_eq:NN } +\cs_new_protected:Npn \cs_new_eq:NN #1 { + \chk_if_free_cs:N #1 + \cs_set_eq:NN #1 +} +\cs_new_nopar:Npn \cs_new_eq:cN { \exp_args:Nc \cs_new_eq:NN } +\cs_new_nopar:Npn \cs_new_eq:Nc { \exp_args:NNc \cs_new_eq:NN } +\cs_new_nopar:Npn \cs_new_eq:cc { \exp_args:Ncc \cs_new_eq:NN } +\cs_new_protected:Npn \cs_gset_eq:NN { \pref_global:D \cs_set_eq:NN } +\cs_new_nopar:Npn \cs_gset_eq:Nc { \exp_args:NNc \cs_gset_eq:NN } +\cs_new_nopar:Npn \cs_gset_eq:cN { \exp_args:Nc \cs_gset_eq:NN } +\cs_new_nopar:Npn \cs_gset_eq:cc { \exp_args:Ncc \cs_gset_eq:NN } +\cs_new_protected:Npn \cs_gnew_eq:NN #1 { + \chk_if_free_cs:N #1 + \pref_global:D \cs_set_eq:NN #1 +} +\cs_new_nopar:Npn \cs_gnew_eq:cN { \exp_args:Nc \cs_gnew_eq:NN } +\cs_new_nopar:Npn \cs_gnew_eq:Nc { \exp_args:NNc \cs_gnew_eq:NN } +\cs_new_nopar:Npn \cs_gnew_eq:cc { \exp_args:Ncc \cs_gnew_eq:NN } +\cs_new_nopar:Npn \cs_gundefine:N #1{\cs_gset_eq:NN #1\c_undefined:D} +\if_cs_exist:N \xetex_version:D + \cs_new_eq:NN \c_xetex_is_engine_bool \c_true_bool +\else: + \cs_new_eq:NN \c_xetex_is_engine_bool \c_false_bool +\fi: +\prg_new_conditional:Npnn \xetex_if_engine: {TF,T,F} { + \if_bool:N \c_xetex_is_engine_bool + \prg_return_true: \else: \prg_return_false: \fi: +} +\if_cs_exist:N \luatex_directlua:D + \cs_new_eq:NN \c_luatex_is_engine_bool \c_true_bool +\else: + \cs_new_eq:NN \c_luatex_is_engine_bool \c_false_bool +\fi: +\prg_set_conditional:Npnn \xetex_if_engine: {TF,T,F}{ + \if_bool:N \c_xetex_is_engine_bool \prg_return_true: + \else: \prg_return_false: \fi: +} +\prg_set_conditional:Npnn \luatex_if_engine: {TF,T,F}{ + \if_bool:N \c_luatex_is_engine_bool \prg_return_true: + \else: \prg_return_false: \fi: +} +\cs_new_nopar:Npn \prg_do_nothing: {} +\cs_set:Npn \cs_get_arg_count_from_signature:N #1{ + \cs_split_function:NN #1 \cs_get_arg_count_from_signature_aux:nnN +} +\cs_set:Npn \cs_get_arg_count_from_signature_aux:nnN #1#2#3{ + \if_predicate:w #3 % \bool_if:NTF here + \exp_after:wN \use_i:nn + \else: + \exp_after:wN\use_ii:nn + \fi: { - \cs_use:c {def_aux_\tex_the:D\etex_numexpr:D #3 :NNn} #1 #2 {#4} + \exp_after:wN \cs_get_arg_count_from_signature_auxii:w + \use_none:nnnnnnnnn #2 9876543210\q_nil } - { \def_arg_number_error_msg:Nn #2{#3} } -} -\def_new:Npn \def_aux:Ncnn #1#2{ - \exp_after:NN \def_aux:NNnn \exp_after:NN #1 \cs:w #2\cs_end:} -\def_new:Npn \def_arg_number_error_msg:Nn #1#2 { - \err_latex_bug:x{ - You're~ trying~ to~ define~ the~ command~ `\token_to_string:N #1'~ - with~ \use_arg_i:n{\tex_the:D\etex_numexpr:D #2\scan_stop:} ~ - arguments~ but~ I~ only~ allow~ 0-9~ arguments.~ I~ can~ probably~ - not~ help~ you~ here + {-1} +} +\cs_set:Npn \cs_get_arg_count_from_signature_auxii:w #1#2\q_nil{#1} +\cs_set_nopar:Npn \cs_get_arg_count_from_signature:c { + \exp_args:Nc \cs_get_arg_count_from_signature:N +} +\cs_set:Npn \cs_generate_from_arg_count:NNnn #1#2#3#4{ + \tex_ifcase:D \etex_numexpr:D #3\tex_relax:D + \use_i_after_orelse:nw{#2#1} + \or: + \use_i_after_orelse:nw{#2#1 ##1} + \or: + \use_i_after_orelse:nw{#2#1 ##1##2} + \or: + \use_i_after_orelse:nw{#2#1 ##1##2##3} + \or: + \use_i_after_orelse:nw{#2#1 ##1##2##3##4} + \or: + \use_i_after_orelse:nw{#2#1 ##1##2##3##4##5} + \or: + \use_i_after_orelse:nw{#2#1 ##1##2##3##4##5##6} + \or: + \use_i_after_orelse:nw{#2#1 ##1##2##3##4##5##6##7} + \or: + \use_i_after_orelse:nw{#2#1 ##1##2##3##4##5##6##7##8} + \or: + \use_i_after_orelse:nw{#2#1 ##1##2##3##4##5##6##7##8##9} + \else: + \use_i_after_fi:nw{ + \cs_generate_from_arg_count_error_msg:Nn#1{#3} + \use_none:n % to remove replacement text + } + \fi: + {#4} +} +\cs_set_nopar:Npn \cs_generate_from_arg_count:cNnn { + \exp_args:Nc \cs_generate_from_arg_count:NNnn +} +\cs_set:Npn \cs_generate_from_arg_count_error_msg:Nn #1#2 { + \msg_kernel_bug:x { + You're~ trying~ to~ define~ the~ command~ `\token_to_str:N #1'~ + with~ \use:n{\tex_the:D\etex_numexpr:D #2\tex_relax:D} ~ + arguments~ but~ I~ only~ allow~ 0-9~arguments.~Perhaps~you~ + forgot~to~use~a~colon~in~the~function~name?~ + I~ can~ probably~ not~ help~ you~ here } } -\def:cpn{def_aux_use_0_parameter:}{} -\def:cpn{def_aux_use_1_parameter:}{{##1}} -\def:cpn{def_aux_use_2_parameter:}{{##1}{##2}} -\def:cpn{def_aux_use_3_parameter:}{{##1}{##2}{##3}} -\def:cpn{def_aux_use_4_parameter:}{{##1}{##2}{##3}{##4}} -\def:cpn{def_aux_use_5_parameter:}{{##1}{##2}{##3}{##4}{##5}} -\def:cpn{def_aux_use_6_parameter:}{{##1}{##2}{##3}{##4}{##5}{##6}} -\def:cpn{def_aux_use_7_parameter:}{{##1}{##2}{##3}{##4}{##5}{##6}{##7}} -\def:cpn{def_aux_use_8_parameter:}{ - {##1}{##2}{##3}{##4}{##5}{##6}{##7}{##8}} -\def:cpn{def_aux_use_9_parameter:}{ - {##1}{##2}{##3}{##4}{##5}{##6}{##7}{##8}{##9}} -\def_new:Npn \def:NNn { \def_aux:NNnn \def:Npn } -\def_new:Npn \def:NNx { \def_aux:NNnn \def:Npx } -\def_new:Npn \def:cNn { \def_aux:Ncnn \def:Npn } -\def_new:Npn \def:cNx { \def_aux:Ncnn \def:Npx } -\def_new:Npn \gdef:NNn { \def_aux:NNnn \gdef:Npn } -\def_new:Npn \gdef:NNx { \def_aux:NNnn \gdef:Npx } -\def_new:Npn \gdef:cNn { \def_aux:Ncnn \gdef:Npn } -\def_new:Npn \gdef:cNx { \def_aux:Ncnn \gdef:Npx } -\def_new:Npn \def_new:NNn { \def_aux:NNnn \def_new:Npn } -\def_new:Npn \def_new:NNx { \def_aux:NNnn \def_new:Npx } -\def_new:Npn \def_new:cNn { \def_aux:Ncnn \def_new:Npn } -\def_new:Npn \def_new:cNx { \def_aux:Ncnn \def_new:Npx } -\def_new:Npn \gdef_new:NNn { \def_aux:NNnn \gdef_new:Npn } -\def_new:Npn \gdef_new:NNx { \def_aux:NNnn \gdef_new:Npx } -\def_new:Npn \gdef_new:cNn { \def_aux:Ncnn \gdef_new:Npn } -\def_new:Npn \gdef_new:cNx { \def_aux:Ncnn \gdef_new:Npx } -\def_new:Npn \def_long:NNn { \def_aux:NNnn \def_long:Npn } -\def_new:Npn \def_long:NNx { \def_aux:NNnn \def_long:Npx } -\def_new:Npn \def_long:cNn { \def_aux:Ncnn \def_long:Npn } -\def_new:Npn \def_long:cNx { \def_aux:Ncnn \def_long:Npx } -\def_new:Npn \gdef_long:NNn { \def_aux:NNnn \gdef_long:Npn } -\def_new:Npn \gdef_long:NNx { \def_aux:NNnn \gdef_long:Npx } -\def_new:Npn \gdef_long:cNn { \def_aux:Ncnn \gdef_long:Npn } -\def_new:Npn \gdef_long:cNx { \def_aux:Ncnn \gdef_long:Npx } -\def_new:Npn \def_long_new:NNn { \def_aux:NNnn \def_long_new:Npn } -\def_new:Npn \def_long_new:NNx { \def_aux:NNnn \def_long_new:Npx } -\def_new:Npn \def_long_new:cNn { \def_aux:Ncnn \def_long_new:Npn } -\def_new:Npn \def_long_new:cNx { \def_aux:Ncnn \def_long_new:Npx } -\def_new:Npn \gdef_long_new:NNn { \def_aux:NNnn \gdef_long_new:Npn } -\def_new:Npn \gdef_long_new:NNx { \def_aux:NNnn \gdef_long_new:Npx } -\def_new:Npn \gdef_long_new:cNn { \def_aux:Ncnn \gdef_long_new:Npn } -\def_new:Npn \gdef_long_new:cNx { \def_aux:Ncnn \gdef_long_new:Npx } -\def_new:Npn \def_protected:NNn { \def_aux:NNnn \def_protected:Npn } -\def_new:Npn \def_protected:NNx { \def_aux:NNnn \def_protected:Npx } -\def_new:Npn \def_protected:cNn { \def_aux:Ncnn \def_protected:Npn } -\def_new:Npn \def_protected:cNx { \def_aux:Ncnn \def_protected:Npx } -\def_new:Npn \gdef_protected:NNn { \def_aux:NNnn \gdef_protected:Npn } -\def_new:Npn \gdef_protected:NNx { \def_aux:NNnn \gdef_protected:Npx } -\def_new:Npn \gdef_protected:cNn { \def_aux:Ncnn \gdef_protected:Npn } -\def_new:Npn \gdef_protected:cNx { \def_aux:Ncnn \gdef_protected:Npx } -\def_new:Npn \def_protected_new:NNn { \def_aux:NNnn \def_protected_new:Npn } -\def_new:Npn \def_protected_new:NNx { \def_aux:NNnn \def_protected_new:Npx } -\def_new:Npn \def_protected_new:cNn { \def_aux:Ncnn \def_protected_new:Npn } -\def_new:Npn \def_protected_new:cNx { \def_aux:Ncnn \def_protected_new:Npx } -\def_new:Npn \gdef_protected_new:NNn { \def_aux:NNnn \gdef_protected_new:Npn } -\def_new:Npn \gdef_protected_new:NNx { \def_aux:NNnn \gdef_protected_new:Npx } -\def_new:Npn \gdef_protected_new:cNn { \def_aux:Ncnn \gdef_protected_new:Npn } -\def_new:Npn \gdef_protected_new:cNx { \def_aux:Ncnn \gdef_protected_new:Npx } -\def_new:Npn \def_protected_long:NNn { \def_aux:NNnn \def_protected_long:Npn } -\def_new:Npn \def_protected_long:NNx { \def_aux:NNnn \def_protected_long:Npx } -\def_new:Npn \def_protected_long:cNn { \def_aux:Ncnn \def_protected_long:Npn } -\def_new:Npn \def_protected_long:cNx { \def_aux:Ncnn \def_protected_long:Npx } -\def_new:Npn \gdef_protected_long:NNn { \def_aux:NNnn \gdef_protected_long:Npn } -\def_new:Npn \gdef_protected_long:NNx { \def_aux:NNnn \gdef_protected_long:Npx } -\def_new:Npn \gdef_protected_long:cNn { \def_aux:Ncnn \gdef_protected_long:Npn } -\def_new:Npn \gdef_protected_long:cNx { \def_aux:Ncnn \gdef_protected_long:Npx } -\def_new:Npn \def_protected_long_new:NNn { - \def_aux:NNnn \def_protected_long_new:Npn } -\def_new:Npn \def_protected_long_new:NNx { - \def_aux:NNnn \def_protected_long_new:Npx } -\def_new:Npn \def_protected_long_new:cNn { - \def_aux:Ncnn \def_protected_long_new:Npn } -\def_new:Npn \def_protected_long_new:cNx { - \def_aux:Ncnn \def_protected_long_new:Npx } -\def_new:Npn \gdef_protected_long_new:NNn { - \def_aux:NNnn \gdef_protected_long_new:Npn } -\def_new:Npn \gdef_protected_long_new:NNx { - \def_aux:NNnn \gdef_protected_long_new:Npx } -\def_new:Npn \gdef_protected_long_new:cNn { - \def_aux:Ncnn \gdef_protected_long_new:Npn } -\def_new:Npn \gdef_protected_long_new:cNx { - \def_aux:Ncnn \gdef_protected_long_new:Npx } -\def_protected_long_new:Npn \let:NN #1{ - \let:NwN #1=~} -\def_new:Npn\let:cN #1 {\exp_after:NN\let:NN\cs:w#1\cs_end:} -\def_new:Npn\let:Nc{\exp_args:NNc\let:NN} -\def_new:Npn\let:cc{\exp_args:Ncc\let:NN} -\def_new:Npn \let_new:NN #1{\chk_new_cs:N #1 - \let:NN #1} -\def_new:Npn \let_new:cN {\exp_args:Nc \let_new:NN} -\def_new:Npn \let_new:Nc {\exp_args:NNc \let_new:NN} -\def_new:Npn \let_new:cc {\exp_args:Ncc \let_new:NN} -\def_protected_new:Npn \glet:NN {\pref_global:D \let:NN} -\def_protected_new:Npn \glet:Nc {\exp_args:NNc \glet:NN} -\def_protected_new:Npn \glet:cN {\exp_args:Nc \glet:NN} -\def_new:Npn \glet:cc {\exp_args:Ncc \glet:NN} -\def_new:Npn \glet_new:NN #1{\chk_new_cs:N #1 - \tex_global:D\let:NN #1} -\def_new:Npn \glet_new:cN {\exp_args:Nc \glet_new:NN} -\def_new:Npn \glet_new:Nc {\exp_args:NNc \glet_new:NN} -\def_new:Npn \glet_new:cc {\exp_args:Ncc \glet_new:NN} -\def_new:Npn \def:No{\exp_args:NNo\def:Npn} -\def_new:Npn \gdef:No {\exp_args:NNo\gdef:Npn} -\def_long_new:Npn \def_test_function_aux:Nnnn #1#2#3#4{ - #1 {#2TF} #3 {#4 - \exp_after:NN\use_arg_i:nn\else:\exp_after:NN\use_arg_ii:nn\fi:} - #1 {#2FT} #3 {#4 - \exp_after:NN\use_arg_ii:nn\else:\exp_after:NN\use_arg_i:nn\fi:} - #1 {#2T} #3 {#4 - \else:\exp_after:NN\use_none:nn\fi:\use_arg_i:n} - #1 {#2F} #3 {#4 - \exp_after:NN\use_none:nn\fi:\use_arg_i:n}} -\def_long_new:Npn \def_test_function_aux:Nnnx #1#2#3#4{ - #1 {#2TF} #3 {#4 - \exp_not:n{\exp_after:NN\use_arg_i:nn\else:\exp_after:NN\use_arg_ii:nn\fi:}} - #1 {#2FT} #3 {#4 - \exp_not:n{\exp_after:NN\use_arg_ii:nn\else:\exp_after:NN\use_arg_i:nn\fi:}} - #1 {#2T} #3 {#4 - \exp_not:n{\else:\exp_after:NN\use_none:nn\fi:\use_arg_i:n}} - #1 {#2F} #3 {#4 - \exp_not:n{\exp_after:NN\use_none:nn\fi:\use_arg_i:n}}} -\def_long_new:Npn \def_test_function:npn #1#2#{ - \def_test_function_aux:Nnnn \def:cpn {#1}{#2} -} -\def_long_new:Npn \def_test_function:npx #1#2#{ - \def_test_function_aux:Nnnx \def:cpx {#1}{#2} -} -\def_long_new:Npn \def_long_test_function:npn #1#2#{ - \def_test_function_aux:Nnnn \def_long:cpn {#1}{#2} -} -\def_long_new:Npn \def_long_test_function:npx #1#2#{ - \def_test_function_aux:Nnnx \def_long:cpx {#1}{#2} -} -\def_long_new:Npn \def_test_function_new:npn #1#2#{ - \def_test_function_aux:Nnnn \def_new:cpn {#1}{#2} -} -\def_long_new:Npn \def_long_test_function_new:npn #1#2#{ - \def_test_function_aux:Nnnn \def_long_new:cpn {#1}{#2} -} -\def_long_new:Npn \def_test_function_new:npx #1#2#{ - \def_test_function_aux:Nnnx \def_new:cpx {#1}{#2} -} -\def_long_new:Npn \def_long_test_function_new:npx #1#2#{ - \def_test_function_aux:Nnnx \def_long_new:cpx {#1}{#2} -} -\def_long_test_function_new:npn {cs_if_free:N}#1{\if:w\cs_if_free_p:N #1} -\let:NN \cs_free:NTF \cs_if_free:NTF -\let:NN \cs_free:NT \cs_if_free:NT -\let:NN \cs_free:NF \cs_if_free:NF -\def_long_test_function_new:npn {cs_if_free:c}#1{ - \exp_after:NN \if_meaning:NN \cs:w#1\cs_end: \scan_stop:} -\let:NN \cs_free:cTF \cs_if_free:cTF -\let:NN \cs_free:cT \cs_if_free:cT -\let:NN \cs_free:cF \cs_if_free:cF -\def_long_test_function_new:npn {cs_if_really_free:c}#1{ - \reverse_if:N\if_cs_exist:w #1\cs_end:} -\let:NN \cs_really_free:cTF \cs_if_really_free:cTF -\let:NN \cs_really_free:cT \cs_if_really_free:cT -\let:NN \cs_really_free:cF \cs_if_really_free:cF -\def_long_test_function_new:npn {cs_if_exist:N}#1{\if:w\cs_if_exist_p:N #1} -\def_long_test_function_new:npn {cs_if_exist:c}#1{ - \exp_after:NN\reverse_if:N - \exp_after:NN \if_meaning:NN \cs:w#1\cs_end: \scan_stop:} -\def_long_test_function_new:npn {cs_if_really_exist:c}#1{ - \if_cs_exist:w #1\cs_end:} -\def_new:Npn \cs_gundefine:N #1{\glet:NN #1\c_undefined} -\def_test_function_new:npn {engine_if_aleph:}{\if_cs_exist:N \aleph_textdir:D} -\def_new:Npn \use:c #1{\cs:w #1\cs_end:} -\def_new:Npn \cs_use:c #1 { \cs:w#1\cs_end: } -\def_new:Npn \use:cc #1#2 - {\cs:w #1\exp_after:NN\cs_end:\cs:w #2\cs_end:} -\def_long_new:Npn \use_arg_i:nn #1#2{#1} -\def_long_new:Npn \use_arg_ii:nn #1#2{#2} -\def_long_new:NNn \use_arg_i:nnn 3{#1} -\def_long_new:NNn \use_arg_ii:nnn 3{#2} -\def_long_new:NNn \use_arg_iii:nnn 3{#3} -\def_long_new:NNn \use_arg_i:nnnn 4{#1} -\def_long_new:NNn \use_arg_ii:nnnn 4{#2} -\def_long_new:NNn \use_arg_iii:nnnn 4{#3} -\def_long_new:NNn \use_arg_iv:nnnn 4{#4} -\def_long_new:NNn\use_arg_i_ii:nn 2{#1#2} -\def_long_new:Npn \use_none_delimit_by_q_nil:w #1\q_nil{} -\def_long_new:Npn \use_none_delimit_by_q_stop:w #1\q_stop{} -\def_long_new:Npn \use_arg_i_delimit_by_q_nil:nw #1#2\q_nil{#1} -\def_long_new:Npn \use_arg_i_delimit_by_q_stop:nw #1#2\q_stop{#1} -\def_long_new:Npn \use_arg_i_after_fi:nw #1\fi:{\fi: #1} -\def_long_new:Npn \use_arg_i_after_else:nw #1\else:#2\fi:{\fi: #1} -\def_long_new:Npn \use_arg_i_after_or:nw #1\or: #2\fi: {\fi:#1} -\def_long_new:Npn \use_arg_i_after_orelse:nw #1 #2#3\fi: {\fi:#1} -\def_long_new:NNn \use_none:nn 2{} -\def_long_new:NNn \use_none:nnn 3{} -\def_long_new:NNn \use_none:nnnn 4{} -\def_long_new:NNn \use_none:nnnnn 5{} -\def_long_new:NNn \use_none:nnnnnn 6{} -\def_long_new:NNn \use_none:nnnnnnn 7{} -\def_long_new:NNn \use_none:nnnnnnnn 8{} -\def_long_new:NNn \use_none:nnnnnnnnn 9{} -\def_new:Npn \gtmp:w {} -\def_new:Npn \tmp:w {} -\def_new:Npn \use_noop: {} -\def_new:Npn \cs_to_str:N {\exp_after:NN\use_none:n \token_to_string:N} -\def_test_function_new:npn {cs_if_eq:NN} #1#2{\if_meaning:NN #1#2} -\def_new:Npn \cs_if_eq:cNTF {\exp_args:Nc \cs_if_eq:NNTF} -\def_new:Npn \cs_if_eq:cNT {\exp_args:Nc \cs_if_eq:NNT} -\def_new:Npn \cs_if_eq:cNF {\exp_args:Nc \cs_if_eq:NNF} -\def_new:Npn \cs_if_eq:NcTF {\exp_args:NNc \cs_if_eq:NNTF} -\def_new:Npn \cs_if_eq:NcT {\exp_args:NNc \cs_if_eq:NNT} -\def_new:Npn \cs_if_eq:NcF {\exp_args:NNc \cs_if_eq:NNF} -\def_new:Npn \cs_if_eq:ccTF {\exp_args:Ncc \cs_if_eq:NNTF} -\def_new:Npn \cs_if_eq:ccT {\exp_args:Ncc \cs_if_eq:NNT} -\def_new:Npn \cs_if_eq:ccF {\exp_args:Ncc \cs_if_eq:NNF} -\def_new:Npn\file_not_found:nTF #1#2#3{\IfFileExists{#1}{#3}{#2}} +\cs_set:Npn \cs_tmp:w #1#2#3{ + \cs_set_protected:cpx {cs_#1:#2}##1##2{ + \exp_not:N \cs_generate_from_arg_count:NNnn ##1 + \exp_after:wN \exp_not:N \cs:w cs_#1:#3 \cs_end: + {\exp_not:N\cs_get_arg_count_from_signature:N ##1}{##2} + } +} +\cs_tmp:w {set}{Nn}{Npn} +\cs_tmp:w {set}{Nx}{Npx} +\cs_tmp:w {set_nopar}{Nn}{Npn} +\cs_tmp:w {set_nopar}{Nx}{Npx} +\cs_tmp:w {set_protected}{Nn}{Npn} +\cs_tmp:w {set_protected}{Nx}{Npx} +\cs_tmp:w {set_protected_nopar}{Nn}{Npn} +\cs_tmp:w {set_protected_nopar}{Nx}{Npx} +\cs_tmp:w {gset}{Nn}{Npn} +\cs_tmp:w {gset}{Nx}{Npx} +\cs_tmp:w {gset_nopar}{Nn}{Npn} +\cs_tmp:w {gset_nopar}{Nx}{Npx} +\cs_tmp:w {gset_protected}{Nn}{Npn} +\cs_tmp:w {gset_protected}{Nx}{Npx} +\cs_tmp:w {gset_protected_nopar}{Nn}{Npn} +\cs_tmp:w {gset_protected_nopar}{Nx}{Npx} +\cs_tmp:w {new}{Nn}{Npn} +\cs_tmp:w {new}{Nx}{Npx} +\cs_tmp:w {new_nopar}{Nn}{Npn} +\cs_tmp:w {new_nopar}{Nx}{Npx} +\cs_tmp:w {new_protected}{Nn}{Npn} +\cs_tmp:w {new_protected}{Nx}{Npx} +\cs_tmp:w {new_protected_nopar}{Nn}{Npn} +\cs_tmp:w {new_protected_nopar}{Nx}{Npx} +\cs_tmp:w {gnew}{Nn}{Npn} +\cs_tmp:w {gnew}{Nx}{Npx} +\cs_tmp:w {gnew_nopar}{Nn}{Npn} +\cs_tmp:w {gnew_nopar}{Nx}{Npx} +\cs_tmp:w {gnew_protected}{Nn}{Npn} +\cs_tmp:w {gnew_protected}{Nx}{Npx} +\cs_tmp:w {gnew_protected_nopar}{Nn}{Npn} +\cs_tmp:w {gnew_protected_nopar}{Nx}{Npx} +\cs_set:Npn \cs_tmp:w #1#2#3{ + \cs_set_protected:cpx {cs_#1:#2}##1##2{ + \exp_not:N\cs_generate_from_arg_count:cNnn {##1} + \exp_after:wN \exp_not:N \cs:w cs_#1:#3 \cs_end: + {\exp_not:N\cs_get_arg_count_from_signature:c {##1}}{##2} + } +} +\cs_tmp:w {set}{cn}{Npn} +\cs_tmp:w {set}{cx}{Npx} +\cs_tmp:w {set_nopar}{cn}{Npn} +\cs_tmp:w {set_nopar}{cx}{Npx} +\cs_tmp:w {set_protected}{cn}{Npn} +\cs_tmp:w {set_protected}{cx}{Npx} +\cs_tmp:w {set_protected_nopar}{cn}{Npn} +\cs_tmp:w {set_protected_nopar}{cx}{Npx} +\cs_tmp:w {gset}{cn}{Npn} +\cs_tmp:w {gset}{cx}{Npx} +\cs_tmp:w {gset_nopar}{cn}{Npn} +\cs_tmp:w {gset_nopar}{cx}{Npx} +\cs_tmp:w {gset_protected}{cn}{Npn} +\cs_tmp:w {gset_protected}{cx}{Npx} +\cs_tmp:w {gset_protected_nopar}{cn}{Npn} +\cs_tmp:w {gset_protected_nopar}{cx}{Npx} +\cs_tmp:w {new}{cn}{Npn} +\cs_tmp:w {new}{cx}{Npx} +\cs_tmp:w {new_nopar}{cn}{Npn} +\cs_tmp:w {new_nopar}{cx}{Npx} +\cs_tmp:w {new_protected}{cn}{Npn} +\cs_tmp:w {new_protected}{cx}{Npx} +\cs_tmp:w {new_protected_nopar}{cn}{Npn} +\cs_tmp:w {new_protected_nopar}{cx}{Npx} +\cs_tmp:w {gnew}{cn}{Npn} +\cs_tmp:w {gnew}{cx}{Npx} +\cs_tmp:w {gnew_nopar}{cn}{Npn} +\cs_tmp:w {gnew_nopar}{cx}{Npx} +\cs_tmp:w {gnew_protected}{cn}{Npn} +\cs_tmp:w {gnew_protected}{cx}{Npx} +\cs_tmp:w {gnew_protected_nopar}{cn}{Npn} +\cs_tmp:w {gnew_protected_nopar}{cx}{Npx} +\prg_set_conditional:Npnn \cs_if_eq:NN #1#2{p,TF,T,F}{ + \if_meaning:w #1#2 + \prg_return_true: \else: \prg_return_false: \fi: +} +\cs_new_nopar:Npn \cs_if_eq_p:cN {\exp_args:Nc \cs_if_eq_p:NN} +\cs_new_nopar:Npn \cs_if_eq:cNTF {\exp_args:Nc \cs_if_eq:NNTF} +\cs_new_nopar:Npn \cs_if_eq:cNT {\exp_args:Nc \cs_if_eq:NNT} +\cs_new_nopar:Npn \cs_if_eq:cNF {\exp_args:Nc \cs_if_eq:NNF} +\cs_new_nopar:Npn \cs_if_eq_p:Nc {\exp_args:NNc \cs_if_eq_p:NN} +\cs_new_nopar:Npn \cs_if_eq:NcTF {\exp_args:NNc \cs_if_eq:NNTF} +\cs_new_nopar:Npn \cs_if_eq:NcT {\exp_args:NNc \cs_if_eq:NNT} +\cs_new_nopar:Npn \cs_if_eq:NcF {\exp_args:NNc \cs_if_eq:NNF} +\cs_new_nopar:Npn \cs_if_eq_p:cc {\exp_args:Ncc \cs_if_eq_p:NN} +\cs_new_nopar:Npn \cs_if_eq:ccTF {\exp_args:Ncc \cs_if_eq:NNTF} +\cs_new_nopar:Npn \cs_if_eq:ccT {\exp_args:Ncc \cs_if_eq:NNT} +\cs_new_nopar:Npn \cs_if_eq:ccF {\exp_args:Ncc \cs_if_eq:NNF} +\cs_new_nopar:Npn\file_not_found:nTF #1#2#3{\IfFileExists{#1}{#3}{#2}} +\cs_set:Npn \prg_set_eq_conditional:NNn #1#2#3 { + \prg_set_eq_conditional_aux:NNNn \cs_set_eq:cc #1#2 {#3} +} +\cs_set:Npn \prg_new_eq_conditional:NNn #1#2#3 { + \prg_set_eq_conditional_aux:NNNn \cs_new_eq:cc #1#2 {#3} +} +\cs_set:Npn \prg_set_eq_conditional_aux:NNNn #1#2#3#4 { + \prg_set_eq_conditional_aux:NNNw #1#2#3#4,?,\q_recursion_stop +} +\cs_set:Npn \prg_set_eq_conditional_aux:NNNw #1#2#3#4, { + \if:w ? #4 \scan_stop: + \exp_after:wN \use_none_delimit_by_q_recursion_stop:w + \fi: + #1 { + \exp_args:NNc \cs_split_function:NN #2 {prg_conditional_form_#4:nnn} + }{ + \exp_args:NNc \cs_split_function:NN #3 {prg_conditional_form_#4:nnn} + } + \prg_set_eq_conditional_aux:NNNw #1{#2}{#3} +} +\cs_set:Npn \prg_conditional_form_p:nnn #1#2#3 {#1_p:#2} +\cs_set:Npn \prg_conditional_form_TF:nnn #1#2#3 {#1:#2TF} +\cs_set:Npn \prg_conditional_form_T:nnn #1#2#3 {#1:#2T} +\cs_set:Npn \prg_conditional_form_F:nnn #1#2#3 {#1:#2F} %% %% %% End of file `l3basics.sty'. diff --git a/Master/texmf-dist/tex/latex/expl3/l3box.sty b/Master/texmf-dist/tex/latex/expl3/l3box.sty index be463eacf81..7f790646251 100644 --- a/Master/texmf-dist/tex/latex/expl3/l3box.sty +++ b/Master/texmf-dist/tex/latex/expl3/l3box.sty @@ -15,7 +15,7 @@ %% Do not distribute a modified version of this file. %% %% -%% File: l3box.dtx Copyright (C) 2005-2007 LaTeX3 project +%% File: l3box.dtx Copyright (C) 2005-2009 LaTeX3 project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this @@ -33,7 +33,7 @@ %% %% The development version of the bundle can be found at %% -%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/ +%% http://www.latex-project.org/svnroot/experimental/trunk/ %% %% for those people who are interested. %% @@ -48,111 +48,125 @@ %% %% ----------------------------------------------------------------------- \RequirePackage{l3names} -\GetIdInfo$Id: l3box.dtx 718 2007-12-16 22:59:58Z morten $ +\GetIdInfo$Id: l3box.dtx 1375 2009-06-01 12:28:52Z joseph $ {L3 Experimental Box module} \ProvidesExplPackage {\filename}{\filedate}{\fileversion}{\filedescription} -\RequirePackage{l3prg,l3token}\par -\let_new:NN \box_new:N \newbox -\def_new:Npn \box_new:c {\exp_args:Nc \box_new:N} -\let_new:NN \if_hbox:N \tex_ifhbox:D -\let_new:NN \if_vbox:N \tex_ifvbox:D -\let_new:NN \if_box_empty:N \tex_ifvoid:D -\def_new:Npn \box_if_empty_p:N #1{ - \if_box_empty:N #1 \c_true \else: \c_false \fi:} -\def_new:Npn \box_if_empty_p:c {\exp_args:Nc \box_if_empty_p:N} -\def_test_function_new:npn {box_if_empty:N}#1{\if_box_empty:N #1} -\def_new:Npn \box_if_empty:cTF {\exp_args:Nc \box_if_empty:NTF} -\def_new:Npn \box_if_empty:cT {\exp_args:Nc \box_if_empty:NT} -\def_new:Npn \box_if_empty:cF {\exp_args:Nc \box_if_empty:NF} -\def_new:Npn \box_set_eq:NN #1#2 {\tex_setbox:D #1 \tex_box:D #2} -\def_new:Npn \box_set_eq:cN {\exp_args:Nc \box_set_eq:NN} -\def_new:Npn \box_set_eq:Nc {\exp_args:NNc \box_set_eq:NN} -\def_new:Npn \box_set_eq:cc {\exp_args:Ncc \box_set_eq:NN} -\def_new:Npn \box_gset_eq:NN {\pref_global:D\box_set_eq:NN} -\def_new:Npn \box_gset_eq:cN {\exp_args:Nc \box_gset_eq:NN} -\def_new:Npn \box_gset_eq:Nc {\exp_args:NNc \box_gset_eq:NN} -\def_new:Npn \box_gset_eq:cc {\exp_args:Ncc \box_gset_eq:NN} -\let_new:NN \R_last_box \tex_lastbox:D -\def_new:Npn \box_set_to_last:N #1{\tex_setbox:D#1\R_last_box} -\def_new:Npn \box_set_to_last:c {\exp_args:Nc \box_set_to_last:N} -\def_new:Npn \box_gset_to_last:N {\pref_global:D \box_set_to_last:N} -\def_new:Npn \box_gset_to_last:c {\exp_args:Nc \box_gset_to_last:N} -\def_long_new:Npn \box_move_left:nn #1#2{\tex_moveleft:D\dim_eval:n{#1}{#2}} -\def_long_new:Npn \box_move_right:nn #1#2{\tex_moveright:D\dim_eval:n{#1}{#2}} -\def_long_new:Npn \box_move_up:nn #1#2{\tex_raise:D\dim_eval:n{#1}{#2}} -\def_long_new:Npn \box_move_down:nn #1#2{\tex_lower:D\dim_eval:n{#1}{#2}} -\def_new:Npn \box_clear:N #1{\box_set_eq:NN #1 \c_empty_box } -\def_new:Npn \box_clear:c {\exp_args:Nc \box_clear:N } -\def_new:Npn \box_gclear:N {\pref_global:D\box_clear:N} -\def_new:Npn \box_gclear:c {\exp_args:Nc \box_gclear:c } -\let_new:NN \box_ht:N \tex_ht:D -\def_new:Npn \box_ht:c {\exp_args:Nc \box_ht:N} -\let_new:NN \box_dp:N \tex_dp:D -\def_new:Npn \box_dp:c {\exp_args:Nc \box_dp:N} -\let_new:NN \box_wd:N \tex_wd:D -\def_new:Npn \box_wd:c {\exp_args:Nc \box_wd:N} -\let_new:NN \box_use_clear:N \tex_box:D -\def_new:Npn \box_use_clear:c {\exp_args:Nc \box_use_clear:N} -\let_new:NN \box_use:N \tex_copy:D -\def_new:Npn \box_use:c {\exp_args:Nc \box_use:N} -\let:NN \box_show:N \tex_showbox:D -\def_new:Npn \box_show:c {\exp_args:Nc \box_show:N} -\let:NN \c_empty_box \voidb@x -\let_new:NN \l_tmpa_box \@tempboxa +\package_check_loaded_expl: +\cs_new:Npn \box_new:N #1 { + \chk_if_free_cs:N #1 + \newbox #1 +} +\cs_generate_variant:Nn \box_new:N {c} +\cs_new_eq:NN \if_hbox:N \tex_ifhbox:D +\cs_new_eq:NN \if_vbox:N \tex_ifvbox:D +\cs_new_eq:NN \if_box_empty:N \tex_ifvoid:D +\prg_new_conditional:Nnn \box_if_horizontal:N {p,TF,T,F} { + \tex_ifhbox:D #1 \prg_return_true: \else: \prg_return_false: \fi: +} +\prg_new_conditional:Nnn \box_if_vertical:N {p,TF,T,F} { + \tex_ifvbox:D #1 \prg_return_true: \else: \prg_return_false: \fi: +} +\cs_generate_variant:Nn \box_if_horizontal_p:N {c} +\cs_generate_variant:Nn \box_if_horizontal:NTF {c} +\cs_generate_variant:Nn \box_if_horizontal:NT {c} +\cs_generate_variant:Nn \box_if_horizontal:NF {c} +\cs_generate_variant:Nn \box_if_vertical_p:N {c} +\cs_generate_variant:Nn \box_if_vertical:NTF {c} +\cs_generate_variant:Nn \box_if_vertical:NT {c} +\cs_generate_variant:Nn \box_if_vertical:NF {c} +\prg_new_conditional:Nnn \box_if_empty:N {p,TF,T,F} { + \tex_ifvoid:D #1 \prg_return_true: \else: \prg_return_false: \fi: +} +\cs_generate_variant:Nn \box_if_empty_p:N {c} +\cs_generate_variant:Nn \box_if_empty:NTF {c} +\cs_generate_variant:Nn \box_if_empty:NT {c} +\cs_generate_variant:Nn \box_if_empty:NF {c} +\cs_new_nopar:Npn \box_set_eq:NN #1#2 {\tex_setbox:D #1 \tex_box:D #2} +\cs_generate_variant:Nn \box_set_eq:NN {cN,Nc,cc} +\cs_new_nopar:Npn \box_gset_eq:NN {\pref_global:D\box_set_eq:NN} +\cs_generate_variant:Nn \box_gset_eq:NN {cN,Nc,cc} +\cs_new_eq:NN \l_last_box \tex_lastbox:D +\cs_new_nopar:Npn \box_set_to_last:N #1{\tex_setbox:D#1\l_last_box} +\cs_generate_variant:Nn \box_set_to_last:N {c} +\cs_new_nopar:Npn \box_gset_to_last:N {\pref_global:D \box_set_to_last:N} +\cs_generate_variant:Nn \box_gset_to_last:N {c} +\cs_new:Npn \box_move_left:nn #1#2{\tex_moveleft:D\dim_eval:n{#1}{#2}} +\cs_new:Npn \box_move_right:nn #1#2{\tex_moveright:D\dim_eval:n{#1}{#2}} +\cs_new:Npn \box_move_up:nn #1#2{\tex_raise:D\dim_eval:n{#1}{#2}} +\cs_new:Npn \box_move_down:nn #1#2{\tex_lower:D\dim_eval:n{#1}{#2}} +\cs_new_nopar:Npn \box_clear:N #1{\box_set_eq:NN #1 \c_empty_box } +\cs_generate_variant:Nn \box_clear:N {c} +\cs_new_nopar:Npn \box_gclear:N {\pref_global:D\box_clear:N} +\cs_generate_variant:Nn \box_gclear:N {c} +\cs_new_eq:NN \box_ht:N \tex_ht:D +\cs_new_eq:NN \box_dp:N \tex_dp:D +\cs_new_eq:NN \box_wd:N \tex_wd:D +\cs_generate_variant:Nn \box_ht:N {c} +\cs_generate_variant:Nn \box_dp:N {c} +\cs_generate_variant:Nn \box_wd:N {c} +\cs_new_eq:NN \box_use_clear:N \tex_box:D +\cs_generate_variant:Nn \box_use_clear:N {c} +\cs_new_eq:NN \box_use:N \tex_copy:D +\cs_generate_variant:Nn \box_use:N {c} +\cs_set_eq:NN \box_show:N \tex_showbox:D +\cs_generate_variant:Nn \box_show:N {c} +\cs_set_eq:NN \c_empty_box \voidb@x +\cs_new_eq:NN \l_tmpa_box \@tempboxa \box_new:N \l_tmpb_box -\def_new:Npn \vbox:n {\tex_vbox:D \scan_stop:} -\def_long_new:Npn \vbox_set:Nn #1#2 {\tex_setbox:D #1 \tex_vbox:D {#2}} -\def_new:Npn \vbox_set:cn {\exp_args:Nc \vbox_set:Nn} -\def_new:Npn \vbox_gset:Nn {\pref_global:D \vbox_set:Nn} -\def_new:Npn \vbox_gset:cn {\exp_args:Nc \vbox_gset:Nn} -\def_long_new:Npn \vbox_set_to_ht:Nnn #1#2#3 { - \tex_setbox:D #1 \tex_vbox:D to #2 {#3}} -\def_new:Npn \vbox_set_to_ht:cnn{\exp_args:Nc \vbox_set_to_ht:Nnn } -\def_new:Npn \vbox_gset_to_ht:Nnn {\pref_global:D \vbox_set_to_ht:Nnn } -\def_new:Npn \vbox_gset_to_ht:cnn{\exp_args:Nc \vbox_gset_to_ht:Nnn } -\def_new:Npn \vbox_gset_to_ht:ccn {\exp_args:Ncc \vbox_gset_to_ht:Nnn} -\def_new:Npn \vbox_set_inline_begin:N #1 { +\cs_new_nopar:Npn \vbox:n {\tex_vbox:D \scan_stop:} +\cs_new:Npn \vbox_set:Nn #1#2 {\tex_setbox:D #1 \tex_vbox:D {#2}} +\cs_generate_variant:Nn \vbox_set:Nn {cn} +\cs_new_nopar:Npn \vbox_gset:Nn {\pref_global:D \vbox_set:Nn} +\cs_generate_variant:Nn \vbox_gset:Nn {cn} +\cs_new:Npn \vbox_set_to_ht:Nnn #1#2#3 { + \tex_setbox:D #1 \tex_vbox:D to #2 {#3} +} +\cs_generate_variant:Nn \vbox_set_to_ht:Nnn {cnn} +\cs_new_nopar:Npn \vbox_gset_to_ht:Nnn { \pref_global:D \vbox_set_to_ht:Nnn } +\cs_generate_variant:Nn \vbox_gset_to_ht:Nnn {cnn,ccn} +\cs_new_nopar:Npn \vbox_set_inline_begin:N #1 { \tex_setbox:D #1 \tex_vbox:D \c_group_begin_token } -\let_new:NN \vbox_set_inline_end: \c_group_end_token -\def_new:Npn \vbox_gset_inline_begin:N { +\cs_new_eq:NN \vbox_set_inline_end: \c_group_end_token +\cs_new_nopar:Npn \vbox_gset_inline_begin:N { \pref_global:D \vbox_set_inline_begin:N } -\let_new:NN \vbox_gset_inline_end: \c_group_end_token -\def_long_new:Npn \vbox_to_ht:nn #1#2{\tex_vbox:D to \dim_eval:n{#1}{#2}} -\def_long_new:Npn \vbox_to_zero:n #1 {\tex_vbox:D to \c_zero_dim {#1}} -\def_new:Npn \vbox_set_split_to_ht:NNn #1#2#3{ +\cs_new_eq:NN \vbox_gset_inline_end: \c_group_end_token +\cs_new:Npn \vbox_to_ht:nn #1#2{\tex_vbox:D to \dim_eval:n{#1}{#2}} +\cs_new:Npn \vbox_to_zero:n #1 {\tex_vbox:D to \c_zero_dim {#1}} +\cs_new_nopar:Npn \vbox_set_split_to_ht:NNn #1#2#3{ \tex_setbox:D #1 \tex_vsplit:D #2 to #3 } -\let_new:NN \vbox_unpack:N \tex_unvcopy:D -\def_new:Npn \vbox_unpack:c {\exp_args:Nc \vbox_unpack:N} -\let_new:NN \vbox_unpack_clear:N \tex_unvbox:D -\def_new:Npn \vbox_unpack_clear:c {\exp_args:Nc \vbox_unpack_clear:N} -\def_new:Npn \hbox:n {\tex_hbox:D \scan_stop:} -\def_long_new:Npn \hbox_set:Nn #1#2 {\tex_setbox:D #1 \tex_hbox:D {#2}} -\def_new:Npn \hbox_set:cn {\exp_args:Nc \hbox_set:Nn} -\def_new:Npn \hbox_gset:Nn {\pref_global:D \hbox_set:Nn} -\def_new:Npn \hbox_gset:cn {\exp_args:Nc \hbox_gset:Nn} -\def_long_new:Npn \hbox_set_to_wd:Nnn #1#2#3 { - \tex_setbox:D #1 \tex_hbox:D to \dim_eval:n{#2} {#3}} -\def_new:Npn \hbox_set_to_wd:cnn{\exp_args:Nc \hbox_set_to_wd:Nnn } -\def_new:Npn \hbox_gset_to_wd:Nnn {\pref_global:D \hbox_set_to_wd:Nnn } -\def_new:Npn \hbox_gset_to_wd:cnn{\exp_args:Nc \hbox_gset_to_wd:Nnn } -\def_new:Npn \hbox_set_inline_begin:N #1 { - \tex_setbox:D #1 \tex_hbox:D \c_group_begin_token } -\def:Npn \hbox_set_inline_begin:c {\exp_args:Nc - \hbox_set_inline_begin:N} -\let_new:NN \hbox_set_inline_end: \c_group_end_token -\def_new:Npn \hbox_gset_inline_begin:N { - \pref_global:D \hbox_set_inline_begin:N } -\def:Npn \hbox_gset_inline_begin:c {\exp_args:Nc - \hbox_gset_inline_begin:N } -\let_new:NN \hbox_gset_inline_end: \c_group_end_token -\def_long_new:Npn \hbox_to_wd:nn #1#2 {\tex_hbox:D to #1 {#2}} -\def_long_new:Npn \hbox_to_zero:n #1 {\tex_hbox:D to \c_zero_skip {#1}} -\let_new:NN \hbox_unpack:N \tex_unhcopy:D -\def_new:Npn \hbox_unpack:c {\exp_args:Nc \hbox_unpack:N} -\let_new:NN \hbox_unpack_clear:N \tex_unhbox:D -\def_new:Npn \hbox_unpack_clear:c {\exp_args:Nc \hbox_unpack_clear:N} +\cs_new_eq:NN \vbox_unpack:N \tex_unvcopy:D +\cs_generate_variant:Nn \vbox_unpack:N {c} +\cs_new_eq:NN \vbox_unpack_clear:N \tex_unvbox:D +\cs_generate_variant:Nn \vbox_unpack_clear:N {c} +\cs_new_nopar:Npn \hbox:n {\tex_hbox:D \scan_stop:} +\cs_new:Npn \hbox_set:Nn #1#2 {\tex_setbox:D #1 \tex_hbox:D {#2}} +\cs_generate_variant:Nn \hbox_set:Nn {cn} +\cs_new_nopar:Npn \hbox_gset:Nn {\pref_global:D \hbox_set:Nn} +\cs_generate_variant:Nn \hbox_gset:Nn {cn} +\cs_new:Npn \hbox_set_to_wd:Nnn #1#2#3 { + \tex_setbox:D #1 \tex_hbox:D to \dim_eval:n{#2} {#3} +} +\cs_generate_variant:Nn \hbox_set_to_wd:Nnn {cnn} +\cs_new_nopar:Npn \hbox_gset_to_wd:Nnn {\pref_global:D \hbox_set_to_wd:Nnn } +\cs_generate_variant:Nn \hbox_gset_to_wd:Nnn {cnn} +\cs_new_nopar:Npn \hbox_set_inline_begin:N #1 { + \tex_setbox:D #1 \tex_hbox:D \c_group_begin_token +} +\cs_generate_variant:Nn \hbox_set_inline_begin:N {c} +\cs_new_eq:NN \hbox_set_inline_end: \c_group_end_token +\cs_new_nopar:Npn \hbox_gset_inline_begin:N { + \pref_global:D \hbox_set_inline_begin:N +} +\cs_generate_variant:Nn \hbox_gset_inline_begin:N {c} +\cs_new_eq:NN \hbox_gset_inline_end: \c_group_end_token +\cs_new:Npn \hbox_to_wd:nn #1#2 {\tex_hbox:D to #1 {#2}} +\cs_new:Npn \hbox_to_zero:n #1 {\tex_hbox:D to \c_zero_skip {#1}} +\cs_new_eq:NN \hbox_unpack:N \tex_unhcopy:D +\cs_generate_variant:Nn \hbox_unpack:N {c} +\cs_new_eq:NN \hbox_unpack_clear:N \tex_unhbox:D +\cs_generate_variant:Nn \hbox_unpack_clear:N {c} %% %% %% End of file `l3box.sty'. diff --git a/Master/texmf-dist/tex/latex/expl3/l3calc.sty b/Master/texmf-dist/tex/latex/expl3/l3calc.sty index 6d6239ac0b6..6bdfdcef00c 100644 --- a/Master/texmf-dist/tex/latex/expl3/l3calc.sty +++ b/Master/texmf-dist/tex/latex/expl3/l3calc.sty @@ -15,7 +15,7 @@ %% Do not distribute a modified version of this file. %% %% -%% File: l3calc.dtx Copyright (C) 2006 LaTeX3 project +%% File: l3calc.dtx Copyright (C) 2006,2009 LaTeX3 project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this @@ -33,7 +33,7 @@ %% %% The development version of the bundle can be found at %% -%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/ +%% http://www.latex-project.org/svnroot/experimental/trunk/ %% %% for those people who are interested. %% @@ -48,16 +48,14 @@ %% %% ----------------------------------------------------------------------- \RequirePackage{l3names} -\GetIdInfo$Id: l3calc.dtx 621 2007-09-01 20:14:19Z morten $ +\GetIdInfo$Id: l3calc.dtx 1362 2009-05-28 20:19:21Z joseph $ {L3 Experimental calc module} \ProvidesExplPackage {\filename}{\filedate}{\fileversion}{\filedescription} -\RequirePackage{l3int} -\RequirePackage{l3skip} -\RequirePackage{l3box} -\tlp_new:Nn\l_calc_expression_tlp{} -\def_new:Npn \g_calc_A_register{} -\def_new:Npn \l_calc_B_register{} +\package_check_loaded_expl: +\tl_new:Nn\l_calc_expression_tl{} +\cs_new_nopar:Npn \g_calc_A_register{} +\cs_new_nopar:Npn \l_calc_B_register{} \int_new:N \l_calc_current_type_int \int_new:N \g_calc_A_int \int_new:N \l_calc_B_int @@ -71,136 +69,136 @@ \muskip_new:N \g_calc_A_muskip \muskip_new:N \l_calc_B_muskip \muskip_new:N \l_calc_C_muskip -\def_long_new:Npn \calc_assign_generic:NNNNnn#1#2#3#4#5#6{ - \let:NN\g_calc_A_register#2 - \let:NN\l_calc_B_register#3 +\cs_new:Npn \calc_assign_generic:NNNNnn#1#2#3#4#5#6{ + \cs_set_eq:NN\g_calc_A_register#2 + \cs_set_eq:NN\l_calc_B_register#3 \int_set:Nn \l_calc_current_type_int {#1} \group_begin: - \let:NN \real \calc_real:n - \let:NN \ratio\calc_ratio:nn - \tlp_set:Nx\l_calc_expression_tlp{#6} - \exp_after:NN + \cs_set_eq:NN \real \calc_real:n + \cs_set_eq:NN \ratio\calc_ratio:nn + \tl_set:Nx\l_calc_expression_tl{#6} + \exp_after:wN \group_end: - \exp_after:NN\calc_open:w\exp_after:NN(\l_calc_expression_tlp ! + \exp_after:wN\calc_open:w\exp_after:wN(\l_calc_expression_tl ! \pref_global:D\g_calc_A_register\l_calc_B_register \group_end: #4{#5}\l_calc_B_register } -\def_new:Npn\calc_int_set:Nn{ +\cs_new_nopar:Npn\calc_int_set:Nn{ \calc_assign_generic:NNNNnn\c_zero\g_calc_A_int\l_calc_B_int\int_set:Nn } -\def_new:Npn\calc_int_gset:Nn{ +\cs_new_nopar:Npn\calc_int_gset:Nn{ \calc_assign_generic:NNNNnn\c_zero\g_calc_A_int\l_calc_B_int\int_gset:Nn } -\def_new:Npn\calc_int_add:Nn{ +\cs_new_nopar:Npn\calc_int_add:Nn{ \calc_assign_generic:NNNNnn\c_zero\g_calc_A_int\l_calc_B_int\int_add:Nn } -\def_new:Npn\calc_int_gadd:Nn{ +\cs_new_nopar:Npn\calc_int_gadd:Nn{ \calc_assign_generic:NNNNnn\c_zero\g_calc_A_int\l_calc_B_int\int_gadd:Nn } -\def_new:Npn\calc_int_sub:Nn{ +\cs_new_nopar:Npn\calc_int_sub:Nn{ \calc_assign_generic:NNNNnn\c_zero\g_calc_A_int\l_calc_B_int\int_sub:Nn } -\def_new:Npn\calc_int_gsub:Nn{ +\cs_new_nopar:Npn\calc_int_gsub:Nn{ \calc_assign_generic:NNNNnn\c_zero\g_calc_A_int\l_calc_B_int\int_gsub:Nn } -\def_new:Npn\calc_dim_set:Nn{ +\cs_new_nopar:Npn\calc_dim_set:Nn{ \calc_assign_generic:NNNNnn\c_one\g_calc_A_dim\l_calc_B_dim\dim_set:Nn } -\def_new:Npn\calc_dim_gset:Nn{ +\cs_new_nopar:Npn\calc_dim_gset:Nn{ \calc_assign_generic:NNNNnn\c_one\g_calc_A_dim\l_calc_B_dim\dim_gset:Nn } -\def_new:Npn\calc_dim_add:Nn{ +\cs_new_nopar:Npn\calc_dim_add:Nn{ \calc_assign_generic:NNNNnn\c_one\g_calc_A_dim\l_calc_B_dim\dim_add:Nn } -\def_new:Npn\calc_dim_gadd:Nn{ +\cs_new_nopar:Npn\calc_dim_gadd:Nn{ \calc_assign_generic:NNNNnn\c_one\g_calc_A_dim\l_calc_B_dim\dim_gadd:Nn } -\def_new:Npn\calc_dim_sub:Nn{ +\cs_new_nopar:Npn\calc_dim_sub:Nn{ \calc_assign_generic:NNNNnn\c_one\g_calc_A_int\l_calc_B_int\dim_sub:Nn } -\def_new:Npn\calc_dim_gsub:Nn{ +\cs_new_nopar:Npn\calc_dim_gsub:Nn{ \calc_assign_generic:NNNNnn\c_one\g_calc_A_int\l_calc_B_int\dim_gsub:Nn } -\def_new:Npn\calc_skip_set:Nn{ +\cs_new_nopar:Npn\calc_skip_set:Nn{ \calc_assign_generic:NNNNnn\c_two\g_calc_A_skip\l_calc_B_skip\skip_set:Nn } -\def_new:Npn\calc_skip_gset:Nn{ +\cs_new_nopar:Npn\calc_skip_gset:Nn{ \calc_assign_generic:NNNNnn\c_two\g_calc_A_skip\l_calc_B_skip\skip_gset:Nn } -\def_new:Npn\calc_skip_add:Nn{ +\cs_new_nopar:Npn\calc_skip_add:Nn{ \calc_assign_generic:NNNNnn\c_two\g_calc_A_skip\l_calc_B_skip\skip_add:Nn } -\def_new:Npn\calc_skip_gadd:Nn{ +\cs_new_nopar:Npn\calc_skip_gadd:Nn{ \calc_assign_generic:NNNNnn\c_two\g_calc_A_skip\l_calc_B_skip\skip_gadd:Nn } -\def_new:Npn\calc_skip_sub:Nn{ +\cs_new_nopar:Npn\calc_skip_sub:Nn{ \calc_assign_generic:NNNNnn\c_two\g_calc_A_skip\l_calc_B_skip\skip_sub:Nn } -\def_new:Npn\calc_skip_gsub:Nn{ +\cs_new_nopar:Npn\calc_skip_gsub:Nn{ \calc_assign_generic:NNNNnn\c_two\g_calc_A_skip\l_calc_B_skip\skip_gsub:Nn } -\def_new:Npn\calc_muskip_set:Nn{ +\cs_new_nopar:Npn\calc_muskip_set:Nn{ \calc_assign_generic:NNNNnn\c_three\g_calc_A_muskip\l_calc_B_muskip \muskip_set:Nn } -\def_new:Npn\calc_muskip_gset:Nn{ +\cs_new_nopar:Npn\calc_muskip_gset:Nn{ \calc_assign_generic:NNNNnn\c_three\g_calc_A_muskip\l_calc_B_muskip \muskip_gset:Nn } -\def_new:Npn\calc_muskip_add:Nn{ +\cs_new_nopar:Npn\calc_muskip_add:Nn{ \calc_assign_generic:NNNNnn\c_three\g_calc_A_muskip\l_calc_B_muskip \muskip_add:Nn } -\def_new:Npn\calc_muskip_gadd:Nn{ +\cs_new_nopar:Npn\calc_muskip_gadd:Nn{ \calc_assign_generic:NNNNnn\c_three\g_calc_A_muskip\l_calc_B_muskip \muskip_gadd:Nn } -\def_new:Npn\calc_muskip_sub:Nn{ +\cs_new_nopar:Npn\calc_muskip_sub:Nn{ \calc_assign_generic:NNNNnn\c_three\g_calc_A_muskip\l_calc_B_muskip \muskip_add:Nn } -\def_new:Npn\calc_muskip_gsub:Nn{ +\cs_new_nopar:Npn\calc_muskip_gsub:Nn{ \calc_assign_generic:NNNNnn\c_three\g_calc_A_muskip\l_calc_B_muskip \muskip_gadd:Nn } -\def_new:Npn \calc_pre_scan:N #1{ - \if_meaning:NN(#1 - \exp_after:NN\calc_open:w +\cs_new_nopar:Npn \calc_pre_scan:N #1{ + \if_meaning:w(#1 + \exp_after:wN\calc_open:w \else: - \if_meaning:NN \calc_textsize:Nn #1 + \if_meaning:w \calc_textsize:Nn #1 \else: - \if_meaning:NN \calc_maxmin_operation:Nnn #1 + \if_meaning:w \calc_maxmin_operation:Nnn #1 \else: \calc_numeric: \fi: \fi: \fi: #1} -\def_new:Npn \calc_open:w({ +\cs_new_nopar:Npn \calc_open:w({ \group_begin:\group_execute_after:N\calc_init_B: \group_begin:\group_execute_after:N\calc_init_B: \calc_pre_scan:N } -\def_new:Npn\calc_init_B:{\l_calc_B_register\g_calc_A_register} -\def_new:Npn\calc_numeric:{ +\cs_new_nopar:Npn\calc_init_B:{\l_calc_B_register\g_calc_A_register} +\cs_new_nopar:Npn\calc_numeric:{ \tex_afterassignment:D\calc_post_scan:N \pref_global:D\g_calc_A_register } -\def_new:Npn\calc_close:{ +\cs_new_nopar:Npn\calc_close:{ \group_end:\pref_global:D\g_calc_A_register\l_calc_B_register \group_end:\pref_global:D\g_calc_A_register\l_calc_B_register \calc_post_scan:N} -\def_new:Npn\calc_post_scan:N#1{ - \if_meaning:NN#1!\let:NN\calc_next:w\group_end: \else: - \if_meaning:NN#1+\let:NN\calc_next:w\calc_add: \else: - \if_meaning:NN#1-\let:NN\calc_next:w\calc_subtract: \else: - \if_meaning:NN#1*\let:NN\calc_next:w\calc_multiply:N \else: - \if_meaning:NN#1/\let:NN\calc_next:w\calc_divide:N \else: - \if_meaning:NN#1)\let:NN\calc_next:w\calc_close: \else: - \if_meaning:NN#1\scan_stop:\let:NN\calc_next:w\calc_post_scan:N +\cs_new_nopar:Npn\calc_post_scan:N#1{ + \if_meaning:w#1!\cs_set_eq:NN\calc_next:w\group_end: \else: + \if_meaning:w#1+\cs_set_eq:NN\calc_next:w\calc_add: \else: + \if_meaning:w#1-\cs_set_eq:NN\calc_next:w\calc_subtract: \else: + \if_meaning:w#1*\cs_set_eq:NN\calc_next:w\calc_multiply:N \else: + \if_meaning:w#1/\cs_set_eq:NN\calc_next:w\calc_divide:N \else: + \if_meaning:w#1)\cs_set_eq:NN\calc_next:w\calc_close: \else: + \if_meaning:w#1\scan_stop:\cs_set_eq:NN\calc_next:w\calc_post_scan:N \else: - \let:NN \calc_next:w \use_noop: + \cs_set_eq:NN \calc_next:w \prg_do_nothing: \calc_error:N#1 \fi: \fi: @@ -210,48 +208,48 @@ \fi: \fi: \calc_next:w} -\def_new:Npn \calc_multiply:N #1{ - \if_meaning:NN \calc_maxmin_operation:Nnn #1 - \let:NN \calc_next:w \calc_maxmin_multiply: +\cs_new_nopar:Npn \calc_multiply:N #1{ + \if_meaning:w \calc_maxmin_operation:Nnn #1 + \cs_set_eq:NN \calc_next:w \calc_maxmin_multiply: \else: - \if_meaning:NN \calc_ratio_multiply:nn #1 - \let:NN \calc_next:w \calc_ratio_multiply:nn + \if_meaning:w \calc_ratio_multiply:nn #1 + \cs_set_eq:NN \calc_next:w \calc_ratio_multiply:nn \else: - \if_meaning:NN \calc_real_evaluate:nn #1 - \let:NN \calc_next:w \calc_real_multiply:n + \if_meaning:w \calc_real_evaluate:nn #1 + \cs_set_eq:NN \calc_next:w \calc_real_multiply:n \else: - \def:Npn \calc_next:w{\calc_multiply: #1} + \cs_set_nopar:Npn \calc_next:w{\calc_multiply: #1} \fi: \fi: \fi: \calc_next:w } -\def_new:Npn \calc_divide:N #1{ - \if_meaning:NN \calc_maxmin_operation:Nnn #1 - \let:NN \calc_next:w \calc_maxmin_divide: +\cs_new_nopar:Npn \calc_divide:N #1{ + \if_meaning:w \calc_maxmin_operation:Nnn #1 + \cs_set_eq:NN \calc_next:w \calc_maxmin_divide: \else: - \if_meaning:NN \calc_ratio_multiply:nn #1 - \let:NN \calc_next:w \calc_ratio_divide:nn + \if_meaning:w \calc_ratio_multiply:nn #1 + \cs_set_eq:NN \calc_next:w \calc_ratio_divide:nn \else: - \if_meaning:NN \calc_real_evaluate:nn #1 - \let:NN \calc_next:w \calc_real_divide:n + \if_meaning:w \calc_real_evaluate:nn #1 + \cs_set_eq:NN \calc_next:w \calc_real_divide:n \else: - \def:Npn \calc_next:w{\calc_divide: #1} + \cs_set_nopar:Npn \calc_next:w{\calc_divide: #1} \fi: \fi: \fi: \calc_next:w } -\def_new:Npn\calc_generic_add_or_subtract:N#1{ +\cs_new_nopar:Npn\calc_generic_add_or_subtract:N#1{ \group_end: \pref_global:D\g_calc_A_register\l_calc_B_register\group_end: \group_begin:\group_execute_after:N#1\group_begin: \group_execute_after:N\calc_init_B: \calc_pre_scan:N} -\def_new:Npn\calc_add:{\calc_generic_add_or_subtract:N\calc_add_A_to_B:} -\def_new:Npn\calc_subtract:{ +\cs_new_nopar:Npn\calc_add:{\calc_generic_add_or_subtract:N\calc_add_A_to_B:} +\cs_new_nopar:Npn\calc_subtract:{ \calc_generic_add_or_subtract:N\calc_subtract_A_from_B:} -\def_new:Npn\calc_add_A_to_B:{ +\cs_new_nopar:Npn\calc_add_A_to_B:{ \l_calc_B_register \if_case:w\l_calc_current_type_int \etex_numexpr:D\or: @@ -260,7 +258,7 @@ \etex_muexpr:D\fi: \l_calc_B_register + \g_calc_A_register\scan_stop: } -\def_new:Npn\calc_subtract_A_from_B:{ +\cs_new_nopar:Npn\calc_subtract_A_from_B:{ \l_calc_B_register \if_case:w\l_calc_current_type_int \etex_numexpr:D\or: @@ -269,15 +267,15 @@ \etex_muexpr:D\fi: \l_calc_B_register - \g_calc_A_register\scan_stop: } -\def_new:Npn\calc_generic_multiply_or_divide:N#1{ +\cs_new_nopar:Npn\calc_generic_multiply_or_divide:N#1{ \group_end: \group_begin: - \let:NN\g_calc_A_register\g_calc_A_int - \let:NN\l_calc_B_register\l_calc_B_int + \cs_set_eq:NN\g_calc_A_register\g_calc_A_int + \cs_set_eq:NN\l_calc_B_register\l_calc_B_int \int_zero:N \l_calc_current_type_int \group_execute_after:N#1\calc_pre_scan:N } -\def_new:Npn\calc_multiply_B_by_A:{ +\cs_new_nopar:Npn\calc_multiply_B_by_A:{ \l_calc_B_register \if_case:w\l_calc_current_type_int \etex_numexpr:D\or: @@ -286,7 +284,7 @@ \etex_muexpr:D\fi: \l_calc_B_register*\g_calc_A_int\scan_stop: } -\def_new:Npn\calc_divide_B_by_A:{ +\cs_new_nopar:Npn\calc_divide_B_by_A:{ \l_calc_B_register \if_case:w\l_calc_current_type_int \etex_numexpr:D\or: @@ -295,34 +293,34 @@ \etex_muexpr:D\fi: \l_calc_B_register/\g_calc_A_int\scan_stop: } -\def_new:Npn\calc_multiply:{ +\cs_new_nopar:Npn\calc_multiply:{ \calc_generic_multiply_or_divide:N\calc_multiply_B_by_A:} -\def_new:Npn\calc_divide:{ +\cs_new_nopar:Npn\calc_divide:{ \calc_generic_multiply_or_divide:N\calc_divide_B_by_A:} -\def_long_new:Npn \calc_calculate_box_size:nnn #1#2#3{ +\cs_new:Npn \calc_calculate_box_size:nnn #1#2#3{ \hbox_set:Nn \l_tmpa_box {{#3}} - #2{\c_zero_dim \tlist_map_function:nN{#1}\calc_calculate_box_size_aux:n} + #2{\c_zero_dim \tl_map_function:nN{#1}\calc_calculate_box_size_aux:n} } -\def:Npn \calc_calculate_box_size_aux:n#1{ + #1\l_tmpa_box} -\def_protected_long:Npn \calc_textsize:Nn#1#2{ +\cs_set_nopar:Npn \calc_calculate_box_size_aux:n#1{ + #1\l_tmpa_box} +\cs_set_protected:Npn \calc_textsize:Nn#1#2{ \group_begin: - \let:NN\calc_widthof_aux:n\box_wd:N - \let:NN\calc_heightof_aux:n\box_ht:N - \let:NN\calc_depthof_aux:n\box_dp:N - \def:Npn\calc_totalheightof_aux:n{\box_ht:N\box_dp:N} + \cs_set_eq:NN\calc_widthof_aux:n\box_wd:N + \cs_set_eq:NN\calc_heightof_aux:n\box_ht:N + \cs_set_eq:NN\calc_depthof_aux:n\box_dp:N + \cs_set_nopar:Npn\calc_totalheightof_aux:n{\box_ht:N\box_dp:N} \exp_args:No\calc_calculate_box_size:nnn{#1} {\dim_gset:Nn\g_calc_A_register} { - \let:NN \calc_depthof_aux:n \calc_depthof_auxi:n - \let:NN \calc_widthof_aux:n \calc_widthof_auxi:n - \let:NN \calc_heightof_aux:n \calc_heightof_auxi:n - \let:NN \calc_totalheightof_aux:n \calc_totalheightof_auxi:n + \cs_set_eq:NN \calc_depthof_aux:n \calc_depthof_auxi:n + \cs_set_eq:NN \calc_widthof_aux:n \calc_widthof_auxi:n + \cs_set_eq:NN \calc_heightof_aux:n \calc_heightof_auxi:n + \cs_set_eq:NN \calc_totalheightof_aux:n \calc_totalheightof_auxi:n #2 } \group_end: \calc_post_scan:N } -\def_protected_long:Npn\calc_ratio_multiply:nn#1#2{ +\cs_set_protected:Npn\calc_ratio_multiply:nn#1#2{ \group_end:\group_begin: \if_num:w\l_calc_current_type_int < \c_three \calc_dim_set:Nn\l_calc_B_int{#1} @@ -331,7 +329,7 @@ \calc_dim_muskip:Nn{\l_calc_B_int\etex_mutoglue:D}{#1} \calc_dim_muskip:Nn{\l_calc_C_int\etex_mutoglue:D}{#2} \fi: - \gdef:Npx\calc_calculated_ratio:{ + \cs_gset_nopar:Npx\calc_calculated_ratio:{ \int_use:N\l_calc_B_int/\int_use:N\l_calc_C_int } \group_end: @@ -344,8 +342,8 @@ \l_calc_B_register*\calc_calculated_ratio:\scan_stop: \group_begin: \calc_post_scan:N} -\def_long_new:Npn \calc_ratio_divide:nn#1#2{\calc_ratio_multiply:nn{#2}{#1}} -\def_protected_new:Npn\calc_real_evaluate:nn #1#2{ +\cs_new:Npn \calc_ratio_divide:nn#1#2{\calc_ratio_multiply:nn{#2}{#1}} +\cs_new_protected_nopar:Npn\calc_real_evaluate:nn #1#2{ \group_end: \l_calc_B_register \if_case:w\l_calc_current_type_int @@ -359,15 +357,15 @@ \scan_stop: \group_begin: \calc_post_scan:N} -\def_new:Npn \calc_real_multiply:n #1{\calc_real_evaluate:nn{#1}{1}} -\def_new:Npn \calc_real_divide:n {\calc_real_evaluate:nn{1}} -\def_protected_long:Npn\calc_maxmin_operation:Nnn#1#2#3{ +\cs_new_nopar:Npn \calc_real_multiply:n #1{\calc_real_evaluate:nn{#1}{1}} +\cs_new_nopar:Npn \calc_real_divide:n {\calc_real_evaluate:nn{1}} +\cs_set_protected:Npn\calc_maxmin_operation:Nnn#1#2#3{ \group_begin: \calc_maxmin_generic:Nnn#1{#2}{#3} \group_end: \calc_post_scan:N } -\def_protected_long_new:Npn \calc_maxmin_generic:Nnn#1#2#3{ +\cs_new_protected:Npn \calc_maxmin_generic:Nnn#1#2#3{ \group_begin: \if_case:w\l_calc_current_type_int \calc_int_set:Nn\l_calc_C_int{#2}% @@ -396,7 +394,7 @@ \fi: \group_end: } -\def_long_new:Npn\calc_maxmin_div_or_mul:NNnn#1#2#3#4{ +\cs_new:Npn\calc_maxmin_div_or_mul:NNnn#1#2#3#4{ \group_end: \group_begin: \int_zero:N\l_calc_current_type_int @@ -406,99 +404,99 @@ \group_begin: \calc_post_scan:N } -\def_new:Npn\calc_maxmin_multiply:{ +\cs_new_nopar:Npn\calc_maxmin_multiply:{ \calc_maxmin_div_or_mul:NNnn\calc_multiply_B_by_A:} -\def_new:Npn\calc_maxmin_divide: { +\cs_new_nopar:Npn\calc_maxmin_divide: { \calc_maxmin_div_or_mul:NNnn\calc_divide_B_by_A:} -\def_new:Npn\calc_error:N#1{ +\cs_new_nopar:Npn\calc_error:N#1{ \PackageError{calc} - {`\token_to_string:N#1'~ invalid~ at~ this~ point} + {`\token_to_str:N#1'~ invalid~ at~ this~ point} {I~ expected~ to~ see~ one~ of:~ +~ -~ *~ /~ )} } -\def_long_new:Npn \calc_maxof:nn#1#2{ +\cs_new:Npn \calc_maxof:nn#1#2{ \calc_maxmin_operation:Nnn > \exp_not:n{{#1}{#2}} } -\def_long_new:Npn \calc_minof:nn#1#2{ +\cs_new:Npn \calc_minof:nn#1#2{ \calc_maxmin_operation:Nnn < \exp_not:n{{#1}{#2}} } -\let:NN \maxof \calc_maxof:nn -\let:NN \minof \calc_minof:nn -\def_long_new:Npn \calc_widthof:n#1{ +\cs_set_eq:NN \maxof \calc_maxof:nn +\cs_set_eq:NN \minof \calc_minof:nn +\cs_new:Npn \calc_widthof:n#1{ \calc_textsize:Nn \exp_not:N\calc_widthof_aux:n\exp_not:n{{#1}} } -\def_long_new:Npn \calc_heightof:n#1{ +\cs_new:Npn \calc_heightof:n#1{ \calc_textsize:Nn \exp_not:N\calc_heightof_aux:n\exp_not:n{{#1}} } -\def_long_new:Npn \calc_depthof:n#1{ +\cs_new:Npn \calc_depthof:n#1{ \calc_textsize:Nn \exp_not:N\calc_depthof_aux:n\exp_not:n{{#1}} } -\def_long_new:Npn \calc_totalheightof:n#1{ +\cs_new:Npn \calc_totalheightof:n#1{ \calc_textsize:Nn \exp_not:N\calc_totalheightof_aux:n \exp_not:n{{#1}} } -\def_long_new:Npn \calc_widthof_aux:n #1{ +\cs_new:Npn \calc_widthof_aux:n #1{ \exp_not:N\calc_widthof_aux:n\exp_not:n{{#1}} } -\let_new:NN \calc_widthof_auxi:n \calc_widthof_aux:n -\def_long_new:Npn \calc_depthof_aux:n #1{ +\cs_new_eq:NN \calc_widthof_auxi:n \calc_widthof_aux:n +\cs_new:Npn \calc_depthof_aux:n #1{ \exp_not:N\calc_depthof_aux:n\exp_not:n{{#1}} } -\let_new:NN \calc_depthof_auxi:n \calc_depthof_aux:n -\def_long_new:Npn \calc_heightof_aux:n #1{ +\cs_new_eq:NN \calc_depthof_auxi:n \calc_depthof_aux:n +\cs_new:Npn \calc_heightof_aux:n #1{ \exp_not:N\calc_heightof_aux:n\exp_not:n{{#1}} } -\let_new:NN \calc_heightof_auxi:n \calc_heightof_aux:n -\def_long_new:Npn \calc_totalheightof_aux:n #1{ +\cs_new_eq:NN \calc_heightof_auxi:n \calc_heightof_aux:n +\cs_new:Npn \calc_totalheightof_aux:n #1{ \exp_not:N\calc_totalheightof_aux:n\exp_not:n{{#1}} } -\let_new:NN \calc_totalheightof_auxi:n \calc_totalheightof_aux:n -\def_long_new:Npn \calc_ratio:nn#1#2{ +\cs_new_eq:NN \calc_totalheightof_auxi:n \calc_totalheightof_aux:n +\cs_new:Npn \calc_ratio:nn#1#2{ \calc_ratio_multiply:nn\exp_not:n{{#1}{#2}}} -\def_new:Npn \calc_real:n {\calc_real_evaluate:nn} -\let:NN \depthof\calc_depthof:n -\let:NN \widthof\calc_widthof:n -\let:NN \heightof\calc_heightof:n -\let:NN \totalheightof\calc_totalheightof:n -%%\let:NN \ratio\calc_ratio:nn -%%\let:NN \real\calc_real:n -\def_protected:Npn \setlength{\calc_skip_set:Nn} -\def_protected:Npn \gsetlength{\calc_skip_gset:Nn} -\def_protected:Npn \addtolength{\calc_skip_add:Nn} -\def_protected:Npn \gaddtolength{\calc_skip_gadd:Nn} +\cs_new_nopar:Npn \calc_real:n {\calc_real_evaluate:nn} +\cs_set_eq:NN \depthof\calc_depthof:n +\cs_set_eq:NN \widthof\calc_widthof:n +\cs_set_eq:NN \heightof\calc_heightof:n +\cs_set_eq:NN \totalheightof\calc_totalheightof:n +%%\cs_set_eq:NN \ratio\calc_ratio:nn +%%\cs_set_eq:NN \real\calc_real:n +\cs_set_protected_nopar:Npn \setlength{\calc_skip_set:Nn} +\cs_set_protected_nopar:Npn \gsetlength{\calc_skip_gset:Nn} +\cs_set_protected_nopar:Npn \addtolength{\calc_skip_add:Nn} +\cs_set_protected_nopar:Npn \gaddtolength{\calc_skip_gadd:Nn} \newif\iffirstchoice@ \firstchoice@true -\def_protected:Npn \calc_setcounter:nn#1#2{ +\cs_set_protected_nopar:Npn \calc_setcounter:nn#1#2{ \calc_chk_document_counter:nn{#1}{ \exp_args:Nc\calc_int_gset:Nn {c@#1}{#2} } } -\def_protected:Npn \calc_addtocounter:nn#1#2{ +\cs_set_protected_nopar:Npn \calc_addtocounter:nn#1#2{ \iffirstchoice@ \calc_chk_document_counter:nn{#1}{ \exp_args:Nc\calc_int_gadd:Nn {c@#1}{#2} } \fi: } -\def_protected:Npn \calc_stepcounter:n#1{ +\cs_set_protected_nopar:Npn \calc_stepcounter:n#1{ \iffirstchoice@ \calc_chk_document_counter:nn{#1}{ \int_gincr:c {c@#1} \group_begin: - \let:NN \@elt\@stpelt \cs_use:c{cl@#1} + \cs_set_eq:NN \@elt\@stpelt \use:c{cl@#1} \group_end: } \fi: } -\def_new:Npn \calc_chk_document_counter:nn#1{ +\cs_new_nopar:Npn \calc_chk_document_counter:nn#1{ \cs_if_free:cTF{c@#1}{\@nocounterr {#1}} } -\let:NN \setcounter \calc_setcounter:nn -\let:NN \addtocounter \calc_addtocounter:nn -\let:NN \stepcounter \calc_stepcounter:n +\cs_set_eq:NN \setcounter \calc_setcounter:nn +\cs_set_eq:NN \addtocounter \calc_addtocounter:nn +\cs_set_eq:NN \stepcounter \calc_stepcounter:n \AtBeginDocument{ - \let:NN \setcounter \calc_setcounter:nn - \let:NN \addtocounter \calc_addtocounter:nn - \let:NN \stepcounter \calc_stepcounter:n + \cs_set_eq:NN \setcounter \calc_setcounter:nn + \cs_set_eq:NN \addtocounter \calc_addtocounter:nn + \cs_set_eq:NN \stepcounter \calc_stepcounter:n } -\def:cpn{ver@calc.sty}{2005/08/06} +\cs_set_nopar:cpn{ver@calc.sty}{2005/08/06} %% %% %% End of file `l3calc.sty'. diff --git a/Master/texmf-dist/tex/latex/expl3/l3chk.sty b/Master/texmf-dist/tex/latex/expl3/l3chk.sty index 7900e8409d0..b059aa3167e 100644 --- a/Master/texmf-dist/tex/latex/expl3/l3chk.sty +++ b/Master/texmf-dist/tex/latex/expl3/l3chk.sty @@ -15,7 +15,7 @@ %% Do not distribute a modified version of this file. %% %% -%% File: l3chk.dtx Copyright (C) 1990-2006 LaTeX3 project +%% File: l3chk.dtx Copyright (C) 1990-2006,2009 LaTeX3 project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this @@ -33,7 +33,7 @@ %% %% The development version of the bundle can be found at %% -%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/ +%% http://www.latex-project.org/svnroot/experimental/trunk/ %% %% for those people who are interested. %% @@ -49,50 +49,49 @@ %% ----------------------------------------------------------------------- %% \RequirePackage{l3names} -\GetIdInfo$Id: l3chk.dtx 621 2007-09-01 20:14:19Z morten $ +\GetIdInfo$Id: l3chk.dtx 1362 2009-05-28 20:19:21Z joseph $ {L3 Experimental check module} \ProvidesExplPackage {\filename}{\filedate}{\fileversion}{\filedescription} -\RequirePackage{l3basics} -\RequirePackage{l3int,l3prg} -\def_new:Npn \chk_local:N #1{ - \exp_after:NN \chk_local_aux:w \token_to_string:N#1\q_stop} +\package_check_loaded_expl: +\cs_new_nopar:Npn \chk_local:N #1{ + \exp_after:wN \chk_local_aux:w \token_to_str:N#1\q_stop} -\def_new:Npn \chk_local_aux:w #1#2#3\q_stop{ +\cs_new_nopar:Npn \chk_local_aux:w #1#2#3\q_stop{ \if_num:w\tex_uccode:D`#2=`G\scan_stop: - \err_latex_bug:x{Local~mismatch:~local~function~called~with~ + \msg_kernel_bug:x {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:x{Variable~mismatch:~function~not~called~with~ + \msg_kernel_bug:x {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:} \tex_newlinechar:D=`\^^J -\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{ +\cs_new_nopar:Npn \chk_global:N #1{\exp_after:wN + \chk_global_aux:w \token_to_str:N#1\q_stop} +\cs_new_nopar:Npn \chk_global_aux:w #1#2#3\q_stop{ \if_num:w\tex_uccode:D`#2=`L\scan_stop: - \err_latex_bug:x{Global~mismatch:~global~function~called~with~ + \msg_kernel_bug:x {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:x{Variable~mismatch:~function~not~called~with~ + \msg_kernel_bug:x {Variable~mismatch:~function~not~called~with~ proper~variable:~#1#2#3~ on~line~\tex_the:D\tex_inputlineno:D}\fi:\fi:} -\def_new:Npn \pref_global_chk: { - \gdef:Npn \chk_local_or_pref_global:N ##1{ +\cs_new_nopar:Npn \pref_global_chk: { + \cs_gset_nopar:Npn \chk_local_or_pref_global:N ##1{ \chk_global:N ##1 - \glet:NN \chk_local_or_pref_global:N \chk_local:N} + \cs_gset_eq: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 -\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 { +\cs_new_eq:NN \chk_local_or_pref_global:N \chk_local:N +\cs_new_nopar:Npn \chk_var_or_const:N #1{\exp_after:wN + \chk_var_or_const_aux:w \token_to_str:N#1\q_stop } +\cs_new_nopar: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: @@ -101,24 +100,24 @@ \else: \if_charcode:w#2q\scan_stop: \else: - \err_latex_bug:x{Variable~mismatch:~function~not~called~with~ + \msg_kernel_bug:x {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:} -\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 +\cs_new_nopar:Npn\donotcheck{ + \cs_set_eq:NN \chk_global:N \use_none:n + \cs_set_eq:NN \chk_local:N \use_none:n + \cs_set_eq:NN \chk_local_or_pref_global:N \use_none:n + \cs_set_eq:NN \pref_global_chk: \pref_global:D + \cs_set_eq:NN \chk_if_free_cs:N \use_none:n + \cs_set_eq:NN \chk_exist_cs:N \use_none:n + \cs_set_eq:NN \chk_var_or_const:N \use_none:n + \cs_set_eq:NN \cs_record_name:N \use_none:n + \cs_set_eq:NN \cs_record_name:c \use_none:n + \cs_set_eq:NN \cs_record_meaning:N \use_none:n + \cs_set_eq:NN \register_record_name:N \use_none:n } -\def_new:Npn\absolutelytracingall{ +\cs_new_nopar:Npn\absolutelytracingall{ \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 @@ -131,7 +130,7 @@ \pref_global:D\g_trace_box_depth_int\c_ten_thousand \pref_global:D\g_trace_online_status\c_one \tex_errorstopmode:D} -\def_new:Npn\tracingoff{ +\cs_new_nopar:Npn\tracingoff{ \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 @@ -144,15 +143,15 @@ \pref_global:D\g_trace_box_breadth_int\c_zero \pref_global:D\g_trace_box_depth_int\c_zero } -\def_new:Npn\traceon#1{ +\cs_new_nopar:Npn\traceon#1{ \clist_map_inline:nn {#1}{ - \cs_free:cF{g_trace_ ##1 _status} + \cs_if_free:cF{g_trace_ ##1 _status} {\int_gincr:c{g_trace_ ##1 _status}} } } -\def_new:Npn\traceoff#1{ +\cs_new_nopar:Npn\traceoff#1{ \clist_map_inline:nn {#1}{ - \cs_free:cF{g_trace_ ##1 _status} + \cs_if_free:cF{g_trace_ ##1 _status} {\int_gdecr:c{g_trace_ ##1 _status}} } } diff --git a/Master/texmf-dist/tex/latex/expl3/l3clist.sty b/Master/texmf-dist/tex/latex/expl3/l3clist.sty index ac82ec646f0..33051453762 100644 --- a/Master/texmf-dist/tex/latex/expl3/l3clist.sty +++ b/Master/texmf-dist/tex/latex/expl3/l3clist.sty @@ -15,7 +15,7 @@ %% Do not distribute a modified version of this file. %% %% -%% File: l3clist.dtx Copyright (C) 2005-2006 Frank Mittelbach, LaTeX3 project +%% File: l3clist.dtx Copyright (C) 2005-2008 Frank Mittelbach, LaTeX3 project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this @@ -33,7 +33,7 @@ %% %% The development version of the bundle can be found at %% -%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/ +%% http://www.latex-project.org/svnroot/experimental/trunk/ %% %% for those people who are interested. %% @@ -48,114 +48,149 @@ %% %% ----------------------------------------------------------------------- \RequirePackage{l3names} -\GetIdInfo$Id: l3clist.dtx 745 2008-08-03 18:50:46Z morten $ +\GetIdInfo$Id: l3clist.dtx 1362 2009-05-28 20:19:21Z joseph $ {L3 Experimental comma separated lists} \ProvidesExplPackage {\filename}{\filedate}{\fileversion}{\filedescription} -\NeedsTeXFormat{LaTeX2e} -\RequirePackage{l3prg,l3quark} -\def_new:Npn \clist_new:N #1{\tlp_new:Nn #1{}} -\def_new:Npn \clist_new:c {\exp_args:Nc \clist_new:N} -\let_new:NN \clist_clear:N \tlp_clear:N -\let_new:NN \clist_clear:c \tlp_clear:c -\let_new:NN \clist_gclear:N \tlp_gclear:N -\let_new:NN \clist_gclear:c \tlp_gclear:c -\let_new:NN \clist_set_eq:NN \let:NN -\let_new:NN \clist_gset_eq:NN \glet:NN -\def_new:Npn \clist_gset_eq:cN {\exp_args:Nc \clist_gset_eq:NN} -\def_new:Npn \clist_gset_eq:Nc {\exp_args:NNc \clist_gset_eq:NN} -\def_new:Npn \clist_gset_eq:cc {\exp_args:Ncc \clist_gset_eq:NN} -\let_new:NN \clist_if_empty_p:N \tlp_if_empty_p:N -\def_test_function_new:npn {clist_if_empty:N}#1{\if_meaning:NN#1\c_empty_tlp} -\def_new:Npn \clist_if_empty:cTF {\exp_args:Nc\clist_if_empty:NTF} -\def_new:Npn \clist_if_empty:cT {\exp_args:Nc\clist_if_empty:NT} -\def_new:Npn \clist_if_empty:cF {\exp_args:Nc\clist_if_empty:NF} -\def_new:Npn \clist_if_empty_err:N #1{ - \if_meaning:NN#1\c_empty_tlp - \tlp_clear:N \l_testa_tlp % catch prefixes - \err_latex_bug:x{Empty~comma-list~`\token_to_string:N#1'} - \fi:} -\let_new:NN \clist_if_eq:NNTF \tlp_if_eq:NNTF -\def_new:Npn \clist_get:NN #1{ +\package_check_loaded_expl: +\cs_new_eq:NN \clist_new:N \tl_new:N +\cs_generate_variant:Nn \clist_new:N {c} +\cs_new_eq:NN \clist_clear:N \tl_clear:N +\cs_generate_variant:Nn \clist_clear:N {c} +\cs_new_eq:NN \clist_gclear:N \tl_gclear:N +\cs_generate_variant:Nn \clist_gclear:N {c} +\cs_new_eq:NN \clist_clear_new:N \tl_clear_new:N +\cs_generate_variant:Nn \clist_clear_new:N {c} +\cs_new_eq:NN \clist_gclear_new:N \tl_gclear_new:N +\cs_generate_variant:Nn \clist_gclear_new:N {c} +\cs_new_eq:NN \clist_set_eq:NN \cs_set_eq:NN +\cs_new_eq:NN \clist_set_eq:cN \cs_set_eq:cN +\cs_new_eq:NN \clist_set_eq:Nc \cs_set_eq:Nc +\cs_new_eq:NN \clist_set_eq:cc \cs_set_eq:cc +\cs_new_eq:NN \clist_gset_eq:NN \cs_gset_eq:NN +\cs_new_eq:NN \clist_gset_eq:cN \cs_gset_eq:cN +\cs_new_eq:NN \clist_gset_eq:Nc \cs_gset_eq:Nc +\cs_new_eq:NN \clist_gset_eq:cc \cs_gset_eq:cc +\prg_new_eq_conditional:NNn \clist_if_empty:N \tl_if_empty:N {p,TF,T,F} +\prg_new_eq_conditional:NNn \clist_if_empty:c \tl_if_empty:c {p,TF,T,F} +\cs_new_nopar:Npn \clist_if_empty_err:N #1 { + \if_meaning:w #1 \c_empty_tl + \tl_clear:N \l_testa_tl % catch prefixes + \msg_kernel_bug:x {Empty~comma-list~`\token_to_str:N #1'} + \fi: +} +\prg_new_eq_conditional:NNn \clist_if_eq:NN \tl_if_eq:NN {p,TF,T,F} +\prg_new_eq_conditional:NNn \clist_if_eq:cN \tl_if_eq:cN {p,TF,T,F} +\prg_new_eq_conditional:NNn \clist_if_eq:Nc \tl_if_eq:Nc {p,TF,T,F} +\prg_new_eq_conditional:NNn \clist_if_eq:cc \tl_if_eq:cc {p,TF,T,F} +\prg_new_conditional:Nnn \clist_if_in:Nn {TF,T,F} { + \cs_set:Npn \clist_tmp:w ##1,#2,##2##3 \q_stop { + \if_meaning:w \q_no_value ##2 + \prg_return_false: \else: \prg_return_true: \fi: + } + \exp_last_unbraced:NNo \clist_tmp:w , #1 , #2 , \q_no_value \q_stop +} +\cs_generate_variant:Nn \clist_if_in:NnTF {NV,No,cn,cV,co} +\cs_generate_variant:Nn \clist_if_in:NnT {NV,No,cn,cV,co} +\cs_generate_variant:Nn \clist_if_in:NnF {NV,No,cn,cV,co} +\cs_new_nopar:Npn \clist_use:N #1 { + \if_meaning:w #1 \scan_stop: + \msg_kernel_bug:x { + Comma~list~ `\token_to_str:N #1'~ has~ an~ erroneous~ structure!} + \else: + \exp_after:wN #1 + \fi: +} +\cs_generate_variant:Nn \clist_use:N {c} +\cs_new_nopar:Npn \clist_get:NN #1 { \clist_if_empty_err:N #1 - \exp_after:NN\clist_get_aux:w #1,\q_stop} -\def_new:Npn \clist_get_aux:w #1,#2\q_stop #3{\tlp_set:Nn #3{#1}} -\def_new:Npn \clist_get:cN {\exp_args:Nc \clist_get:NN} -\def_new:Npn \clist_pop_aux:nnNN #1#2#3{ + \exp_after:wN \clist_get_aux:w #1,\q_stop +} +\cs_new:Npn \clist_get_aux:w #1,#2\q_stop #3 { \tl_set:Nn #3{#1} } +\cs_generate_variant:Nn \clist_get:NN {cN} +\cs_new:Npn \clist_pop_aux:nnNN #1#2#3 { \clist_if_empty_err:N #3 - \exp_after:NN\clist_pop_aux:w #3,\q_nil\q_stop #1#2#3} -\def_new:Npn \clist_pop_aux:w #1,#2\q_stop #3#4#5#6{ - #4#6{#1} - #3#5{#2} - \quark_if_nil:NTF #5 - { #3#5{} } - { \clist_pop_auxi:w #2 #3#5 } -} -\def_new:Npn\clist_pop_auxi:w #1,\q_nil #2#3 {#2#3{#1}} -\def_new:Npn \clist_put_aux:NNnnNn #1#2#3#4#5#6{ - \clist_if_empty:NTF#5 {#1 #5{#6}} - { \tlist_if_empty:nF {#6}{ #2 #5{#3#6#4} } } -} -\def_new:Npn \clist_put_left:Nn { - \clist_put_aux:NNnnNn \tlp_set:Nn \tlp_put_left:Nn {} , -} -\def_new:Npn \clist_put_left:cn {\exp_args:Nc \clist_put_left:Nn} -\def_new:Npn \clist_put_left:No {\exp_args:NNo\clist_put_left:Nn} -\def_new:Npn \clist_put_left:Nx {\exp_args:Nnx\clist_put_left:Nn} -\def_new:Npn \clist_gput_left:Nn { - \clist_put_aux:NNnnNn \tlp_gset:Nn \tlp_gput_left:Nn {} , -} -\def_new:Npn \clist_put_right:Nn { - \clist_put_aux:NNnnNn \tlp_set:Nn \tlp_put_right:Nn , {} -} -\def_new:Npn \clist_put_right:cn {\exp_args:Nc \clist_put_right:Nn} -\def_new:Npn \clist_put_right:No {\exp_args:Nno\clist_put_right:Nn} -\def_new:Npn \clist_put_right:Nx {\exp_args:Nnx\clist_put_right:Nn} -\def_new:Npn \clist_gput_right:Nn { - \clist_put_aux:NNnnNn \tlp_gset:Nn \tlp_gput_right:Nn , {} -} -\def_new:Npn \clist_gput_right:No {\exp_args:NNo \clist_gput_right:Nn} -\def_new:Npn \clist_gput_right:cn {\exp_args:Nc \clist_gput_right:Nn} -\def_new:Npn \clist_gput_right:co {\exp_args:Nco \clist_gput_right:Nn} -\def_new:Npn \clist_gput_right:cc {\exp_args:Ncc \clist_gput_right:Nn} -\def_new:Npn \clist_gput_right:NC {\exp_args:NNC \clist_gput_right:Nn} -\def_new:Npn \clist_map_function:NN #1#2{ - \clist_if_empty:NF #1 - { - \exp_after:NN \clist_map_function_aux:Nw - \exp_after:NN #2 #1 , \q_recursion_tail , \q_recursion_stop + \exp_after:wN \clist_pop_aux:w #3,\q_nil\q_stop #1#2#3 +} +\cs_new:Npn \clist_pop_aux:w #1,#2\q_stop #3#4#5#6 { + #4 #6 {#1} + #3 #5 {#2} + \quark_if_nil:NTF #5 { #3 #5 {} }{ \clist_pop_auxi:w #2 #3#5 } +} +\cs_new:Npn \clist_pop_auxi:w #1,\q_nil #2#3 { #2#3{#1} } +\cs_new_eq:NN \clist_show:N \tl_show:N +\cs_new_eq:NN \clist_show:c \tl_show:c +\cs_new_nopar:Npn \clist_display:N #1 { + \iow_term:x { Comma-list~\token_to_str:N #1~contains~ + the~elements~(without~outer~braces): } + \toks_clear:N \l_tmpa_toks + \clist_map_inline:Nn #1 { + \toks_if_empty:NF \l_tmpa_toks { + \toks_put_right:Nx \l_tmpa_toks {^^J>~} + } + \toks_put_right:Nx \l_tmpa_toks { + \iow_space: \iow_char:N \{ \exp_not:n {##1} \iow_char:N \} + } + } + \toks_show:N \l_tmpa_toks +} +\cs_generate_variant:Nn \clist_display:N {c} +\cs_new:Npn \clist_put_aux:NNnnNn #1#2#3#4#5#6 { + \clist_if_empty:NTF #5 { #1 #5 {#6} } { + \tl_if_empty:nF {#6} { #2 #5{#3#6#4} } } } -\def_new:Npn \clist_map_function:cN{\exp_args:Nc\clist_map_function:NN} -\def_new:Npn \clist_map_function:nN #1#2{ - \tlist_if_blank:nF {#1} - { \clist_map_function_aux:Nw #2 #1 , \q_recursion_tail , \q_recursion_stop } +\cs_new_nopar:Npn \clist_put_left:Nn { + \clist_put_aux:NNnnNn \tl_set:Nn \tl_put_left:Nn {} , } -\def_long_new:Npn \clist_map_function_aux:Nw #1#2,{ +\cs_generate_variant:Nn \clist_put_left:Nn {NV,No,Nx,cn,cV,co} +\cs_new_nopar:Npn \clist_gput_left:Nn { + \clist_put_aux:NNnnNn \tl_gset:Nn \tl_gput_left:Nn {} , +} +\cs_generate_variant:Nn \clist_gput_left:Nn {NV,No,Nx,cn,cV,co} +\cs_new_nopar:Npn \clist_put_right:Nn { + \clist_put_aux:NNnnNn \tl_set:Nn \tl_put_right:Nn , {} +} +\cs_generate_variant:Nn \clist_put_right:Nn {NV,No,Nx,cn,cV,co} +\cs_new_nopar:Npn \clist_gput_right:Nn { + \clist_put_aux:NNnnNn \tl_gset:Nn \tl_gput_right:Nn , {} +} +\cs_generate_variant:Nn \clist_gput_right:Nn {NV,No,Nx,cn,cV,co} +\cs_new_nopar:Npn \clist_map_function:NN #1#2 { + \clist_if_empty:NF #1 { + \exp_after:wN \clist_map_function_aux:Nw + \exp_after:wN #2 #1 , \q_recursion_tail , \q_recursion_stop + } +} +\cs_generate_variant:Nn \clist_map_function:NN {cN} +\cs_new:Npn \clist_map_function:nN #1#2 { + \tl_if_blank:nF {#1} { + \clist_map_function_aux:Nw #2 #1 , \q_recursion_tail , \q_recursion_stop + } +} +\cs_new:Npn \clist_map_function_aux:Nw #1#2,{ \quark_if_recursion_tail_stop:n{#2} #1{#2} \clist_map_function_aux:Nw #1 } -\let_new:NN \clist_map_break:w \use_none_delimit_by_q_recursion_stop:w +\cs_new_eq:NN \clist_map_break: \use_none_delimit_by_q_recursion_stop:w \int_new:N \g_clist_inline_level_int -\def_long_new:Npn \clist_map_inline:Nn #1#2{ - \clist_if_empty:NF #1 - { +\cs_new:Npn \clist_map_inline:Nn #1#2 { + \clist_if_empty:NF #1 { \int_gincr:N \g_clist_inline_level_int - \gdef_long:cpn {clist_map_inline_ \int_use:N \g_clist_inline_level_int :n} + \cs_gset:cpn {clist_map_inline_ \int_use:N \g_clist_inline_level_int :n} ##1{#2} - \exp_args:NcE \clist_map_function_aux:Nw + \exp_last_unbraced:NcV \clist_map_function_aux:Nw {clist_map_inline_ \int_use:N \g_clist_inline_level_int :n} #1 , \q_recursion_tail , \q_recursion_stop \int_gdecr:N \g_clist_inline_level_int } } -\def_new:Npn \clist_map_inline:cn{\exp_args:Nc\clist_map_inline:Nn} -\def_long_new:Npn \clist_map_inline:nn #1#2{ - \tlist_if_empty:nF {#1} - { +\cs_generate_variant:Nn \clist_map_inline:Nn {c} +\cs_new:Npn \clist_map_inline:nn #1#2 { + \tl_if_empty:nF {#1} { \int_gincr:N \g_clist_inline_level_int - \gdef_long:cpn {clist_map_inline_ \int_use:N \g_clist_inline_level_int :n} + \cs_gset:cpn {clist_map_inline_ \int_use:N \g_clist_inline_level_int :n} ##1{#2} \exp_args:Nc \clist_map_function_aux:Nw {clist_map_inline_ \int_use:N \g_clist_inline_level_int :n} @@ -163,84 +198,80 @@ \int_gdecr:N \g_clist_inline_level_int } } -\def_new:Npn \clist_map_variable:nNn #1#2#3{ - \tlist_if_empty:nF{#1} - { +\cs_new:Npn \clist_map_variable:nNn #1#2#3 { + \tl_if_empty:nF {#1} { \clist_map_variable_aux:Nnw #2 {#3} #1 , \q_recursion_tail , \q_recursion_stop } } -\def_new:Npn \clist_map_variable:NNn {\exp_args:No \clist_map_variable:nNn} -\def_new:Npn \clist_map_variable:cNn {\exp_args:Nc \clist_map_variable:NNn} -\def_new:Npn \clist_map_variable_aux:Nnw #1#2#3,{ - \def:Npn #1{#3} +\cs_new_nopar:Npn \clist_map_variable:NNn {\exp_args:No \clist_map_variable:nNn} +\cs_generate_variant:Nn\clist_map_variable:NNn {cNn} +\cs_new:Npn \clist_map_variable_aux:Nnw #1#2#3,{ + \cs_set_nopar:Npn #1{#3} \quark_if_recursion_tail_stop:N #1 #2 \clist_map_variable_aux:Nnw #1{#2} } -\def_new:Npn \clist_concat_aux:NNNN #1#2#3#4{ +\cs_new_nopar:Npn \clist_concat_aux:NNNN #1#2#3#4 { \toks_set:No \l_tmpa_toks {#3} \toks_set:No \l_tmpb_toks {#4} #1 #2 { \toks_use:N \l_tmpa_toks - \toks_if_empty:NF \l_tmpa_toks {\toks_if_empty:NF \l_tmpb_toks ,} + \toks_if_empty:NF \l_tmpa_toks { \toks_if_empty:NF \l_tmpb_toks , } \toks_use:N \l_tmpb_toks } } -\def_new:Npn \clist_concat:NNN {\clist_concat_aux:NNNN \tlp_set:Nx} -\def_new:Npn \clist_gconcat:NNN {\clist_concat_aux:NNNN \tlp_gset:Nx} -\def_new:Npn \clist_gconcat:NNc{\exp_args:Nnnc\clist_gconcat:NNN} -\def_new:Npn \clist_gconcat:ccc{\exp_args:Nccc\clist_gconcat:NNN} -\def:Npn \clist_remove_duplicates_aux:NN #1#2 { - \clist_clear:N \l_clist_remove_duplicates_clist +\cs_new_nopar:Npn \clist_concat:NNN { \clist_concat_aux:NNNN \tl_set:Nx } +\cs_new_nopar:Npn \clist_gconcat:NNN { \clist_concat_aux:NNNN \tl_gset:Nx } +\cs_generate_variant:Nn \clist_concat:NNN {ccc} +\cs_generate_variant:Nn \clist_gconcat:NNN {ccc} +\clist_new:N \l_clist_remove_clist +\cs_new:Nn \clist_remove_duplicates_aux:NN { + \clist_clear:N \l_clist_remove_clist \clist_map_function:NN #2 \clist_remove_duplicates_aux:n - #1 #2 \l_clist_remove_duplicates_clist + #1 #2 \l_clist_remove_clist } -\def:Npn \clist_remove_duplicates_aux:n #1 { - \clist_if_in:NnTF \l_clist_remove_duplicates_clist {#1} {} - {\clist_put_right:Nn \l_clist_remove_duplicates_clist {#1}} +\cs_new:Nn \clist_remove_duplicates_aux:n { + \clist_if_in:NnF \l_clist_remove_clist {#1} { + \clist_put_right:Nn \l_clist_remove_clist {#1} + } } -\def_new:Npn \clist_remove_duplicates:N { +\cs_new_nopar:Npn \clist_remove_duplicates:N { \clist_remove_duplicates_aux:NN \clist_set_eq:NN } -\def_new:Npn \clist_gremove_duplicates:N { +\cs_new_nopar:Npn \clist_gremove_duplicates:N { \clist_remove_duplicates_aux:NN \clist_gset_eq:NN } -\clist_new:N \l_clist_remove_duplicates_clist -\def_new:Npn \clist_use:N #1 { - \if_meaning:NN #1 \scan_stop: - \err_latex_bug:x {Comma~list~ `\token_to_string:N #1'~ - has~ an~ erroneous~ structure!} - \else: - \exp_after:NN #1 - \fi: +\cs_new_nopar:Npn \clist_remove_element:Nn { + \clist_remove_element_aux:NNn \clist_set_eq:NN +} +\cs_new_nopar:Npn \clist_gremove_element:Nn { + \clist_remove_element_aux:NNn \clist_gset_eq:NN } -\def_new:Npn \clist_use:c {\exp_args:Nc \clist_use:N} -\def_new:Npn \clist_if_in:NnTF #1#2{ - \def:Npn \tmp:w ##1 ,#2, ##2##3\q_stop{ - \if_meaning:NN\q_no_value##2 - \exp_after:NN\use_arg_ii:nn - \else: - \exp_after:NN\use_arg_i:nn - \fi: +\cs_new:Nn \clist_remove_element_aux:NNn { + \clist_clear:N \l_clist_remove_clist + \cs_set:Nn \clist_remove_element_aux:n { + \tl_if_eq:nnF {#3} {##1} { + \clist_put_right:Nn \l_clist_remove_clist {##1} + } } - \exp_after:NN \tmp:w - \exp_after:NN , #1, #2, \q_no_value \q_stop -} -\def_new:Npn \clist_if_in:NoTF {\exp_args:NNo \clist_if_in:NnTF} -\def_new:Npn \clist_if_in:coTF {\exp_args:Nco \clist_if_in:NnTF} -\def_new:Npn \clist_if_in:cnTF {\exp_args:Nc \clist_if_in:NnTF} -\let_new:NN \clist_push:Nn \clist_put_left:Nn -\let_new:NN \clist_push:No \clist_put_left:No -\let_new:NN \clist_push:cn \clist_put_left:cn -\def_new:Npn \clist_pop:NN {\clist_pop_aux:nnNN \tlp_set:Nn \tlp_set:Nn} -\def_new:Npn \clist_pop:cN {\exp_args:Nc \clist_pop:NN} -\let_new:NN \clist_gpush:Nn \clist_gput_left:Nn -\def_new:Npn \clist_gpush:No {\exp_args:NNo \clist_gpush:Nn} -\def_new:Npn \clist_gpush:cn {\exp_args:Nc \clist_gpush:Nn} -\def_new:Npn \clist_gpop:NN {\clist_pop_aux:nnNN \tlp_gset:Nn \tlp_set:Nn} -\def_new:Npn \clist_gpop:cN {\exp_args:Nc \clist_gpop:NN} -\let_new:NN \clist_top:NN \clist_get:NN -\let_new:NN \clist_top:cN \clist_get:cN + \clist_map_function:NN #2 \clist_remove_element_aux:n + #1 #2 \l_clist_remove_clist +} +\cs_new:Nn \clist_remove_element_aux:n { } +\cs_new_eq:NN \clist_push:Nn \clist_put_left:Nn +\cs_new_eq:NN \clist_push:NV \clist_put_left:NV +\cs_new_eq:NN \clist_push:No \clist_put_left:No +\cs_new_eq:NN \clist_push:cn \clist_put_left:cn +\cs_new_nopar:Npn \clist_pop:NN {\clist_pop_aux:nnNN \tl_set:Nn \tl_set:Nn} +\cs_generate_variant:Nn \clist_pop:NN {cN} +\cs_new_eq:NN \clist_gpush:Nn \clist_gput_left:Nn +\cs_new_eq:NN \clist_gpush:NV \clist_gput_left:NV +\cs_new_eq:NN \clist_gpush:No \clist_gput_left:No +\cs_generate_variant:Nn \clist_gpush:Nn {cn} +\cs_new_nopar:Npn \clist_gpop:NN {\clist_pop_aux:nnNN \tl_gset:Nn \tl_set:Nn} +\cs_generate_variant:Nn \clist_gpop:NN {cN} +\cs_new_eq:NN \clist_top:NN \clist_get:NN +\cs_new_eq:NN \clist_top:cN \clist_get:cN %% %% %% End of file `l3clist.sty'. diff --git a/Master/texmf-dist/tex/latex/expl3/l3doc.cls b/Master/texmf-dist/tex/latex/expl3/l3doc.cls index da59bf174ef..09d6928412f 100644 --- a/Master/texmf-dist/tex/latex/expl3/l3doc.cls +++ b/Master/texmf-dist/tex/latex/expl3/l3doc.cls @@ -1,5 +1,21 @@ -% \iffalse -%% File: l3doc.dtx Copyright (C) 1990-2008 LaTeX3 project +%% +%% This is file `l3doc.cls', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% l3doc.dtx (with options: `class') +%% +%% +%% EXPERIMENTAL CODE +%% +%% Do not distribute this file without also distributing the +%% source files specified above. +%% +%% Do not distribute a modified version of this file. +%% +%% +%% File: l3doc.dtx Copyright (C) 1990-2009 LaTeX3 project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this @@ -17,7 +33,7 @@ %% %% The development version of the bundle can be found at %% -%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/ +%% http://www.latex-project.org/svnroot/experimental/trunk/ %% %% for those people who are interested. %% @@ -31,385 +47,697 @@ %% prior consultation with the LaTeX Project Team. %% %% ----------------------------------------------------------------------- -%% \fi -% \iffalse -% \begin{macrocode} -%<*class> -\NeedsTeXFormat{LaTeX2e} -\ProvidesClass{l3doc} - [2008/08/01 v0.0k class for documenting experimental stuff] -% -\NeedsTeXFormat{LaTeX2e} -%</class> -% \end{macrocode} -% -% \section{Options} -% -% \begin{macrocode} -%<*class> -\DeclareOption{a5paper}{\@latexerr{Option not supported}% - {}} -\DeclareOption{full}{\AtBeginDocument{\input{l3full.cfg}}} -% \end{macrocode} -% -% \begin{macrocode} +\RequirePackage{l3names} +\let \filenameOld \filename +\let \filenameextOld \filenameext +\let \filedateOld \filedate +\let \fileversionOld \fileversion +\let \filedescriptionOld \filedescription +\GetIdInfo$Id: l3doc.dtx 1398 2009-06-08 15:53:26Z joseph $ + {L3 Experimental documentation class} +\ProvidesExplClass + {\filename}{\filedate}{\fileversion}{\filedescription} +\RequirePackage{expl3} +\let \filename \filenameOld +\let \filenameext \filenameextOld +\let \filedate \filedateOld +\let \fileversion \fileversionOld +\let \filedescription \filedescriptionOld +\cs_new_nopar:Npn\Team{% + The~\LaTeX3~Project\thanks{% + Frank~Mittelbach,~Denys~Duchier,~Chris~Rowley,~ + Rainer~Sch\"opf,~Johannes~Braams,~Michael~Downes,~ + David~Carlisle,~Alan~Jeffrey,~Morten~H\o{}gholm,~Thomas~Lotze,~ + Javier~Bezos,~Will~Robertson,~Joseph~Wright}} +\DeclareOption{a5paper}{\@latexerr{Option not supported}{}} +\bool_new:N \g_doc_full_bool +\bool_set_false:N \g_doc_full_bool +\DeclareOption{full}{ \bool_set_true:N \g_doc_full_bool } +\DeclareOption{onlydoc}{ \bool_set_false:N \g_doc_full_bool } +\bool_new:N \g_doc_checkfunc_bool +\bool_set_true:N \g_doc_checkfunc_bool +\DeclareOption{check}{ \bool_set_true:N \g_doc_checkfunc_bool } +\DeclareOption{nocheck}{ \bool_set_false:N \g_doc_checkfunc_bool } \DeclareOption*{\PassOptionsToClass{\CurrentOption}{article}} -% \end{macrocode} -% -% \section{Option Processing} -% -% \begin{macrocode} +\ExecuteOptions{full} \ProcessOptions -% \end{macrocode} -% -% \section{Loading article and doc} -% -% \begin{macrocode} -\LoadClass{article} -% \end{macrocode} -% We need eTeX. Otherwise stop processing now. -% \begin{macrocode} -\@ifundefined{eTeXversion}{% - \ClassError{l3doc}{This document class requires eTeX extensions}% - {I'm going to stop now.}% - \endinput\stop -}{} -% \end{macrocode} -% -% \begin{macrocode} -\RequirePackage{l3names,trace} +\LoadClass[a4paper]{article} \RequirePackage{doc} -\renewcommand\MakePrivateLetters{\makeatletter - \catcode`\_=11\relax - \catcode`\:=11\relax} -% \end{macrocode} -% -% \section{Configuration} -% Input a local configuration file, if it exists. -% \begin{macrocode} -\InputIfFileExists{l3doc.cfg} - {\typeout{*************************************^^J% - * Local config file l3doc.cfg used^^J% - *************************************}} - {} -% \end{macrocode} -% -% taken out for the moment as my laptop doesn't have a full set of -% type 1 fonts installed right now --- fmi -%\RequirePackage[T1]{fontenc} - -%% The Guilty Parties -\def\Team{% - The \LaTeX3 Project\thanks{% - Frank Mittelbach, Denys Duchier, Chris Rowley, - Rainer Sch\"opf, Johannes Braams, Michael Downes, - David Carlisle, Alan Jeffrey, Morten H\o gholm, Thomas Lotze, - Javier Bezos}} - -%% You do not want to look at the mess below this line. -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - -\catcode`\_=11 -\AtBeginDocument{\catcode`\_=11\relax} -% \end{macrocode} -% -% Make \verb+|+ and \verb+"+ be `short verb' characters, but not in -% the document preamble, where an active character may interfere -% with packages that are loaded. -% \begin{macrocode} -\MakeShortVerb\" -\MakeShortVerb\| -% \end{macrocode} -% -% As `doc' documents tend to have a lot of monospaced material, -% Set up some |tt| substitutions to occur silently. -% \begin{macrocode} -\DeclareFontShape{OT1}{cmtt}{bx}{n}{<-> ssub * cmtt/m/n}{} -\DeclareFontFamily{OMS}{cmtt}{\skewchar\font 48} % '60 -\DeclareFontShape{OMS}{cmtt}{m}{n}{<-> ssub * cmsy/m/n}{} -\DeclareFontShape{OMS}{cmtt}{bx}{n}{<-> ssub * cmsy/b/n}{} -% \end{macrocode} -% This substitution is in the standard fd file, but not silent. -% \begin{macrocode} -\DeclareFontShape{OT1}{cmss}{m}{it}{<->ssub*cmss/m/sl}{} -% \begin{macrocode} -\CodelineNumbered -\DisableCrossrefs -% \end{macrocode} -% -% Increase the text width slightly so that width the standard fonts -% 72 columns of code may appear in a |macrocode| environment. -% \changes{v2.0c}{1994/03/15}{Set \cs{textwidth}.} -% \begin{macrocode} -\setlength{\textwidth}{355pt} -% \end{macrocode} -% -% Increase the marginpar width slightly, for long command names. -% And increase the left margin by a similar amount -% \changes{v2.0l} -% {1994/05/25}{Increase \cs{marginparwidth}} -% \changes{v2.0q}{1995/11/28} -% {Increase \cs{marginparwidth} and page margin.} -% \begin{macrocode} -\addtolength\marginparwidth{30pt} -\addtolength\oddsidemargin{20pt} -\addtolength\evensidemargin{20pt} -% \end{macrocode} -% -% -% \begin{macrocode} +\RequirePackage{array,alphalph,color,fixltx2e,enumitem,trace,underscore} +\RequirePackage[T1]{fontenc} +\RequirePackage{lmodern,textcomp} +\RequirePackage{hypdoc} +\let\doc@verbatim\verbatim +\let\enddoc@verbatim\endverbatim +\let\doc@@verbatim\@verbatim +\usepackage{verbatim} +\AtBeginDocument{% + \let\verbatim\doc@verbatim + \let\endverbatim\enddoc@verbatim + \let\@verbatim\doc@@verbatim +} +\cs_set_nopar:Npn \MakePrivateLetters { + \char_make_letter:N \@ + \char_make_letter:N \_ + \char_make_letter:N \: +} \setcounter{StandardModuleDepth}{1} -% \end{macrocode} -% -% \begin{macrocode} -\newcommand{\tn}[1]{{\ttfamily\bslash #1}% - \index{TeX and LaTeX2e commands\actualchar - \string\TeX{} and \string\LaTeXe{} commands:\levelchar - #1\actualchar{\string\ttfamily\string\bslash{}#1}}} -\DeclareRobustCommand\cs[1]{\texttt{\char`\\#1}} -% This command will be used to input the patch file -% if that file exists. -\newcommand{\includeltpatch}{% - \def\currentfile{l3patch.ltx} - \part{l3patch} - {\let\ttfamily\relax - \xdef\filekey{\filekey, \thepart={\ttfamily\currentfile}}}% - Things we did wrong\ldots - \IndexInput{l3patch.ltx}} - -% Get the date from ltvers.dtx -\def\patchdate{0} -\begingroup - %%\def\ProvidesFile#1\fmtversion#2{\date{#2}\endinput} - \def\ProvidesFile#1[#2#3]{\date{#2}\endinput} - \input{l3vers.dtx} - \xdef\@date{\@date} - \global\let\X@date=\@date -% Add the patch version if available. - \long\def\Xdef#1#2#3\def#4#5{% - \xdef\X@date{#2}% - \xdef\patchdate{#5}% - \endinput}% - \InputIfFileExists{l3patch.ltx} - {\let\def\Xdef}{\global\let\includeltpatch\relax} -\endgroup - -\ifx\@date\X@date - \def\Xpatch{0} - \ifx\patchdate\Xpatch\else - \edef\@date{\@date\space Patch level \patchdate} - \fi -\else - \@warning{l3patch.ltx does not match l3vers.dtx!} - \let\includeltpatch\relax -\fi - -\providecommand*\eTeX{% +\@addtoreset{CodelineNo}{part} +\cs_set_nopar:Npn \theCodelineNo { + \textcolor[gray]{0.5}{ \sffamily\tiny\arabic{CodelineNo} } +} +\setlength \textwidth { 385pt } +\addtolength \marginparwidth { 30pt } +\addtolength \oddsidemargin { 20pt } +\addtolength \evensidemargin { 20pt } +\cs_set_eq:NN \@@oldlist\list +\cs_set_nopar:Npn \list#1#2{\@@oldlist{#1}{#2\listparindent\z@}} +\setlength \parindent { 0pt } +\setlength \itemindent { 0pt } +\setlength \parskip { \medskipamount } +\AtBeginDocument { + \MakeShortVerb \" + \MakeShortVerb \| +} +\providecommand*\eTeX{ \if b\expandafter\@car\f@series\@nil\boldmath\fi - $\m@th\varepsilon$-\TeX} + $\m@th\varepsilon$-\TeX +} +\cs_set_nopar:Npn \cmd #1 { \cs{\expandafter\cmd@to@cs\string#1} } +\cs_set_nopar:Npn \cmd@to@cs #1#2 { \char\number`#2\relax } +\DeclareRobustCommand \cs [1] { \texttt { \char`\\ #1 } } +\providecommand\marg[1]{ \texttt{\char`\{} \meta{#1} \texttt{\char`\}} } +\providecommand\oarg[1]{ \texttt[ \meta{#1} \texttt] } +\providecommand\parg[1]{ \texttt( \meta{#1} \texttt) } +\cs_set_eq:NN \m \meta +\cs_set_eq:NN \file \nolinkurl +\DeclareRobustCommand \env {\texttt} +\DeclareRobustCommand \pkg {\textsf} +\DeclareRobustCommand \cls {\textsf} +\newenvironment{texnote}{ + \endgraf + \vspace{3mm} + \small\textbf{\TeX~hackers~note:} +}{ + \vspace{3mm} +} +\newcommand\tn[1]{ + \texttt{\bslash #1} + \index{TeX~and~LaTeX2e~commands\actualchar + \string\TeX{}~and~\string\LaTeXe{}~commands:\levelchar + #1\actualchar{\string\ttfamily\string\bslash{}#1}}} +\newenvironment{documentation}{}{} +\newenvironment{implementation}{}{} +\newcommand\EnableDocumentation{% + \renewenvironment{documentation}{}{}% +} +\newcommand\EnableImplementation{% + \renewenvironment{implementation}{}{}% +} +\newcommand\DisableDocumentation{% + \cs_set_eq:NN \documentation \comment + \cs_set_eq:NN \enddocumentation \endcomment +} +\newcommand\DisableImplementation{% + \cs_set_eq:NN \implementation \comment + \cs_set_eq:NN \endimplementation \endcomment +} +\newenvironment{arguments}{ + \enumerate[ + nolistsep, + label=\texttt{\#\arabic*}~:, + labelsep=*, + ] +}{ + \endenumerate +} +\group_begin: +\char_make_active:N \< +\cs_gnew_nopar:Npn \function { + \char_make_active:N \< + \cs_set_eq:NN < \doc_open_meta:n + \group_begin: + \MakePrivateLetters + \char_make_other:N \| + \char_make_other:N \^ + \char_make_other:N \\ + \char_make_space:N \~ + \char_make_ignore:N \ % space + \char_make_ignore:N \^^M + \char_make_ignore:N \^^I + \function_aux:n +} +\group_end: +\cs_set_eq:NN \variable \function +\cs_set_nopar:Npn \function_aux:n #1 { + \cs_set_nopar:Npn \nextnewline{\cs_gset_nopar:Npn\nextnewline{\\}} + \tl_gset_eq:NN \g_doc_macro_tl \c_empty_tl + \bigskip\endgraf\noindent\ttfamily + \tabular[b]{ | l @{} c | } + \hline + \doc_showmacro:w #1 | \q_stop \\ + \hline + \endtabular + \group_end: +} +\cs_set_nopar:Npn \doc_showmacro:w #1 | { + \tl_if_blank:nTF {#1} { + \use_none:n + }{ + \doc_showmacro_aux:w #1 / \q_stop + \peek_meaning:NTF \q_stop { \use_none:n } { \doc_showmacro:w } + } +} +\bool_new:N \l_doc_meta_TF_bool +\bool_new:N \l_doc_meta_EXP_bool +\cs_new_nopar:Npn \doc_showmacro_aux:w #1 / #2 \q_stop { -\providecommand*\file{\texttt} + \tl_if_in:nnTF {#2} { (TF) } { + \bool_gset_true:N \l_doc_meta_TF_bool + }{ + \bool_gset_false:N \l_doc_meta_TF_bool + } + \tl_if_in:nnTF {#2} { (EXP) } { + \bool_gset_true:N \l_doc_meta_EXP_bool + }{ + \bool_gset_false:N \l_doc_meta_EXP_bool + } + \bool_if:NTF \l_doc_meta_TF_bool { + \doc_special_main_index:o { #1 TF } + \seq_gput_right:Nx \g_doc_functions_seq { \tl_to_str:n { #1 TF } } + \seq_gput_right:Nx \g_doc_functions_seq { \tl_to_str:n { #1 T } } + \seq_gput_right:Nx \g_doc_functions_seq { \tl_to_str:n { #1 F } } + }{ + \doc_special_main_index:o { #1 } + \seq_gput_right:Nx \g_doc_functions_seq { \tl_to_str:n { #1 } } + } -\def\vindex#1>#2\@nil{% - \edef\temp{\foo#2<>\@nil}% - \ifx\temp\space\else - \expandafter\SpecialMainIndexB\expandafter{\temp}\fi} + \doc_showmacro_aux_ii:w #1::\q_stop +} +\cs_set_nopar:Npn \doc_showmacro_aux_ii:w #1:#2:#3 \q_stop { + \nextnewline -% remove <foo> from index (quick hack, could be better) -\def\foo#1<#2>#3\@nil{% - #1\ifx\foo#3\foo - \else#2\expandafter\foo\fi#3\@nil} -%\def\foo#1<#2>#3\@nil{#1<#2>#3} -\def\foo#1<#2>#3\@nil{#1} + \tl_if_eq:xxTF {#1} {\g_doc_macro_tl} { + \doc_typeset_aux:n + }{ + \tl_gset:Nn \g_doc_macro_tl {#1} + \use:n + } + { \g_doc_macro_tl } + #3 + #2 + \bool_if:NT \l_doc_meta_TF_bool { \doc_typeset_TF: } + & + \bool_if:NT \l_doc_meta_EXP_bool { + \hspace{\tabcolsep} + $\star$ + } +} +\newenvironment{syntax}{% + \minipage[b]{.7\textwidth}% + \cs_set_nopar:Npn \meta@font@select{\rmfamily\itshape} % (Will: I HATE italic cmtt!) + \small\ttfamily\raggedright + \obeyspaces\obeylines +}{% + \endminipage + \hfil\break + \global\@ignoretrue +} +\tl_map_inline:nn {0123456789} { \cs_gset_eq:cN {char_other_#1} #1 } +\group_begin: + \tl_map_inline:nn {0123456789} { \char_make_active:N #1 } + \cs_gnew:Npn \doc_open_meta:n { + \group_begin: + \tl_map_function:nN {0123456789} \doc_assign_num:n + \doc_close_meta:w + } + \cs_gnew:Npn \Arg { + \texttt{ \char`\{ } + \group_begin: + \tl_map_function:nN {0123456789} \doc_assign_num:n + \doc_close_Arg:n + } +\group_end: +\cs_new_nopar:Npn \doc_close_meta:w #1> { \meta {#1} \group_end: } +\cs_new_nopar:Npn \doc_close_Arg:n #1 { + \meta {#1} + \group_end: + \texttt{ \char`\} } +} +\cs_new_nopar:Npn \doc_assign_num:n #1 { + \cs_set_eq:cc { \string #1 } { char_other_\string #1 } + \char_make_active:N #1 + \cs_set_nopar:Npn #1 { \unskip \, $ {} \sb { \use:c { char_other_\string #1 } } $ } +} +\renewcommand \macro [1][] { + \bool_set_false:N \l_doc_macro_aux_bool + \bool_set_false:N \l_doc_macro_TF_bool + \cs_set_eq:NN \doc_macroname_prefix:n \use:n + \cs_set_eq:NN \doc_macroname_suffix: \c_empty_tl -% Cant remember why I switched from \SpecialMainIndexB -%%\gdef\SpecialMainIndexB#1{\index{\@gobble#1\space\actualchar{\string\verb+#1+}}} + \cs_set_nopar:Npn \KV_key_no_value_elt:n ##1 { \use:c {doc_macro_opt_##1:} } + \KV_parse_space_removal_sanitize:n {#1} -\gdef\SpecialMainIndexB#1{\index{\@gobble#1\actualchar\string\verb - \quotechar*\verbatimchar#1\verbatimchar\encapchar usage}} + \group_begin: + \MakePrivateLetters + \char_make_letter:N \\ + \char_make_ignore:N \ % space + \char_make_ignore:N \^^M + \char_make_ignore:N \^^I + \doc_macro_aux:n +} +\cs_new_nopar:Npn \doc_macro_aux:n #1 { + \group_end: + \clist_map_inline:nn {#1} { \doc_macro_single {##1} } +} +\bool_new:N \l_doc_macro_aux_bool +\bool_new:N \l_doc_macro_TF_bool +\cs_set_nopar:Npn \doc_macro_opt_aux: { \bool_set_true:N \l_doc_macro_aux_bool } +\cs_set_nopar:Npn \doc_macro_opt_TF: { \bool_set_true:N \l_doc_macro_TF_bool } +\cs_set_nopar:Npn \doc_macro_single #1 { -% A helper for later on. -\def\q@nil{\q@nil} -\long\def\tlist@if@blank@p@n #1{% - \expandafter\tlist@if@blank@p@aux@w\detokenize{#1}aa..\q@nil} -\def\tlist@if@blank@p@aux@w #1#2a#3#4\q@nil{% - \ifx #3#400\else01\fi} + \topsep\MacroTopsep + \trivlist + \cs_set_nopar:Npn \makelabel ##1 { \llap{##1} } + \if@inlabel + \cs_set_eq:NN \@tempa \@empty + \count@ \macro@cnt + \loop \ifnum\count@>\z@ + \cs_set_nopar:Npx \@tempa{\@tempa\hbox{\strut}} + \advance\count@\m@ne + \repeat + \cs_set_nopar:Npx \makelabel ##1 { + \llap{\vtop to\baselineskip {\@tempa\hbox{##1}\vss}} + } + \advance \macro@cnt \@ne + \else + \macro@cnt \@ne + \fi + \bool_if:NT \l_doc_macro_aux_bool { + \cs_set_eq:NN \doc_macroname_prefix:n \doc_typeset_aux:n + } + \bool_if:NT \l_doc_macro_TF_bool { + \cs_set_eq:NN \doc_macroname_suffix: \doc_typeset_TF: + } -\let\m\meta -\newenvironment{texnote}% - {\endgraf\vspace{3mm}\textbf{\TeX{}hackers~note:}\small} - {\vspace{3mm}} -% stick the function names in a box. -{\catcode`\|=\active\catcode`\<=\active + \cs_set_nopar:Npx \@tempa { + \exp_not:N \item [ \exp_not:N \doc_print_macroname:n { + \tl_to_str:n {#1} + }] + } \@tempa + \global\advance \c@CodelineNo \@ne + \bool_if:NF \l_doc_macro_aux_bool { + \bool_if:NTF \l_doc_macro_TF_bool { + \seq_gput_right:Nx \g_doc_macros_seq { \tl_to_str:n { #1 TF } } + \seq_gput_right:Nx \g_doc_macros_seq { \tl_to_str:n { #1 T } } + \seq_gput_right:Nx \g_doc_macros_seq { \tl_to_str:n { #1 F } } + }{ + \seq_gput_right:Nx \g_doc_macros_seq { \tl_to_str:n {#1} } + } + } + \bool_if:NTF \l_doc_macro_TF_bool { + \SpecialMainIndex{#1 TF}\nobreak + \DoNotIndex{#1 TF} + }{ + \SpecialMainIndex{#1}\nobreak + \DoNotIndex{#1} + } - -% index fuction lists (could be better...) -\gdef\funcindex#1|{% - \if\tlist@if@blank@p@n{#1}% - \expandafter\@firstoftwo + \global\advance \c@CodelineNo \m@ne + \ignorespaces +} +\cs_set_nopar:Npn \doc_print_macroname:n #1 { + \strut \MacroFont + \doc_macroname_prefix:n {#1} \doc_macroname_suffix: \ % space! +} +\cs_set_nopar:Npn \doc_typeset_TF: { + \color[gray]{0.5} + \underline { \color{black} \itshape TF \kern-0.1em } +} +\cs_set_nopar:Npn \doc_typeset_aux:n #1 { + {\color[gray]{0.5} #1} +} +\newcommand*{\DescribeOption}{ + \leavevmode + \@bsphack + \begingroup + \MakePrivateLetters + \Describe@Option +} +\newcommand*{\Describe@Option}[1]{ + \endgroup + \marginpar{ + \raggedleft + \PrintDescribeEnv{#1} + } + \SpecialOptionIndex{#1} + \@esphack + \ignorespaces +} +\newcommand*{\SpecialOptionIndex}[1]{ + \@bsphack + \begingroup + \HD@target + \let\HDorg@encapchar\encapchar + \edef\encapchar usage{ + \HDorg@encapchar hdclindex{\the\c@HD@hypercount}{usage} + } + \index{ + #1\actualchar{\protect\ttfamily#1} (option) + \encapchar usage + } + \index{ + options:\levelchar#1\actualchar{\protect\ttfamily#1} + \encapchar usage + } + \endgroup + \@esphack +} +\font\manual=manfnt +\cs_set_nopar:Npn \dbend { {\manual\char127} } +\newenvironment {danger} { + \begin{trivlist}\item[]\noindent + \begingroup\hangindent=2pc\hangafter=-2 + \cs_set_nopar:Npn \par{\endgraf\endgroup} + \hbox to0pt{\hskip-\hangindent\dbend\hfill}\ignorespaces +}{ + \par\end{trivlist} +} +\newenvironment {ddanger} { + \begin{trivlist}\item[]\noindent + \begingroup\hangindent=3.5pc\hangafter=-2 + \cs_set_nopar:Npn \par{\endgraf\endgroup} + \hbox to0pt{\hskip-\hangindent\dbend\kern2pt\dbend\hfill}\ignorespaces +}{ + \par\end{trivlist} +} +\newenvironment{TemplateInterfaceDescription}[1] + {\subsection{The template type `#1'}% + \begingroup + \@beginparpenalty\@M + \description + \def\TemplateArgument##1##2{\item[Arg: ##1]##2\par}% + \def\TemplateSemantics{\enddescription\endgroup + \subsubsection*{Semantics:}}% + } + {\par\bigskip} +\newenvironment{TemplateDescription}[2] + {\subsection{The template `#2' (type #1)}% + \subsubsection*{Attributes:}% + \begingroup + \@beginparpenalty\@M + \description + \def\TemplateKey##1##2##3##4{\item[##1 (##2)]##3% + \ifx\TemplateKey##4\TemplateKey\else + \hfill\penalty500\hbox{}\hfill Default:~##4% + \nobreak\hskip-\parfillskip\hskip0pt\relax + \fi + \par}% + \def\TemplateSemantics{\enddescription\endgroup + \subsubsection*{Semantics \& Comments:}}% + } + {\par\bigskip} +\newenvironment{InstanceDescription}[4][xxxxxxxxxxxxxxx] + {\subsubsection{The instance `#3' (template #2/#4)}% + \subsubsection*{Attribute values:}% + \begingroup + \@beginparpenalty\@M + \def\InstanceKey##1##2{\>\textbf{##1}\>##2\\}% + \def\InstanceSemantics{\endtabbing\endgroup + \vskip-30pt\vskip0pt + \subsubsection*{Layout description \& Comments:}}% + \tabbing + xxxx\=#1\=\kill + } + {\par\bigskip} +\bool_new:N \g_doc_implementation_bool +\cs_set_nopar:Npn \AlsoImplementation { + \bool_set_true:N \g_doc_implementation_bool + \cs_set:Npn \StopEventually ##1 { + \@bsphack + \cs_gset_nopar:Npn \Finale { ##1 \check@checksum } + \init@checksum + \@esphack + } +} +\AlsoImplementation +\cs_set_nopar:Npn \OnlyDescription { + \@bsphack + \bool_set_false:N \g_doc_implementation_bool + \cs_set:Npn \StopEventually ##1 { ##1 \endinput } + \@esphack +} +\cs_set_eq:NN \Finale \relax +\cs_set_nopar:Npn \partname{File} +\clist_new:N \g_docinput_clist +\cs_set:Npn \DocInput #1 { + \clist_map_inline:nn {#1} { + \clist_put_right:Nn \g_docinput_clist {##1} + \MakePercentIgnore + \input{##1} + \MakePercentComment + } +} +\cs_set:Npn \DocInputAgain { + \clist_map_inline:Nn \g_docinput_clist { + \MakePercentIgnore + \input{##1} + \MakePercentComment + } +} +\cs_set_nopar:Npn \partname{File} +\newcommand*{\DocInclude}[1]{% + \relax\clearpage + \docincludeaux + \IfFileExists{#1.fdd}{ + \cs_set_nopar:Npn \currentfile{#1.fdd} + }{ + \cs_set_nopar:Npn \currentfile{#1.dtx} + } + \ifnum\@auxout=\@partaux + \@latexerr{\string\include\space cannot~be~nested}\@eha \else - \expandafter\@secondoftwo + \@docinclude #1 \fi - {\@ifnextchar|{\@gobble}{}}% at the end, look for extra | and remove it - {\def\yyy{#1}\expandafter\vindex\meaning\yyy\@nil \funcindex}% } - -\gdef\function{% - \catcode`\<=\active\def<##1>{\meta{##1}}% - \bigskip - \bgroup - \@makeother\\ - \@makeother\_ - \catcode`\ =9 - \catcode`\^^M=9 - \catcode`\^^I=9 - \catcode`\|=\active\def|{\\}% - \@function} -\gdef\@function#1{% - \ifx\@function#1\@function\else - \funcindex#1| |% +\cs_set_nopar:Npn \@docinclude #1 { + \clearpage + \immediate\write\@mainaux{\string\@input{#1.aux}} + \@tempswatrue + \if@partsw + \@tempswafalse + \cs_set_nopar:Npx \@tempb{#1} + \@for\@tempa:=\@partlist\do{ + \ifx\@tempa\@tempb\@tempswatrue\fi + } \fi - \ttfamily - \endgraf - \noindent\hspace*{-2\parindent}% - \tabular[b]% - {@{\vline\hskip\tabcolsep}l@{\hskip\tabcolsep\vline}}% - \hline - #1\crcr - \hline - \noalign{\kern-2pt}% - \endtabular - \egroup}} - - -\let\variable\function - -% syntax for functions -\def\syntax{% - \@syntax} - -\def\@syntax{% - \minipage[b]{.7\textwidth}% - \small\ttfamily\raggedright - \obeyspaces\obeylines} -\def\endsyntax{\endminipage\hfil\break\global\@ignoretrue} - + \if@tempswa + \cs_set_eq:NN \@auxout\@partaux + \immediate\openout\@partaux #1.aux + \immediate\write\@partaux{\relax} + \cs_set_eq:NN \@ltxdoc@PrintIndex\PrintIndex + \cs_set_eq:NN \PrintIndex\relax + \cs_set_eq:NN \@ltxdoc@PrintChanges\PrintChanges + \cs_set_eq:NN \PrintChanges\relax + \cs_set_eq:NN \@ltxdoc@theglossary\theglossary + \cs_set_eq:NN \@ltxdoc@endtheglossary\endtheglossary + \part{\currentfile} + { + \cs_set_eq:NN \ttfamily\relax + \cs_gset_nopar:Npx \filekey{\filekey, \thepart={\ttfamily\currentfile}} + } + \DocInput{\currentfile} + \cs_set_eq:NN \PrintIndex\@ltxdoc@PrintIndex + \cs_set_eq:NN \PrintChanges\@ltxdoc@PrintChanges + \cs_set_eq:NN \theglossary\@ltxdoc@theglossary + \cs_set_eq:NN \endtheglossary\@ltxdoc@endtheglossary + \clearpage + \@writeckpt{#1} + \immediate\closeout\@partaux + \else + \@nameuse{cp@#1} + \fi + \cs_set_eq:NN \@auxout\@mainaux +} +\cs_gset_nopar:Npn \codeline@wrindex #1 { + \immediate\write\@indexfile { + \string\indexentry{#1} + {\filesep\number\c@CodelineNo} + } +} +\cs_set_eq:NN \filesep \@empty +\cs_set_nopar:Npn \docincludeaux { + \cs_set_nopar:Npn \thepart {\alphalph{part}} + \cs_set_nopar:Npn \filesep {\thepart-} + \cs_set_eq:NN \filekey\@gobble + \g@addto@macro\index@prologue{ + \cs_gset_nopar:Npn\@oddfoot{ + \parbox{\textwidth}{ + \strut\footnotesize + \raggedright{\bfseries File~Key:}~\filekey + } + } + \cs_set_eq:NN \@evenfoot\@oddfoot + } + \cs_gset_eq:NN \docincludeaux\relax + \cs_gset_nopar:Npn\@oddfoot{ + \expandafter\ifx\csname ver@\currentfile\endcsname\relax + File~\thepart :~{\ttfamily\currentfile}~ + \else + \GetFileInfo{\currentfile} + File~\thepart :~{\ttfamily\filename}~ + Date:~\filedate\ % space + Version~\fileversion + \fi + \hfill\thepage + } + \cs_set_eq:NN \@evenfoot \@oddfoot +} +\seq_new:N \g_doc_functions_seq +\seq_new:N \g_doc_macros_seq +\iow_new:N \g_write_func_stream +\iow_open:Nn \g_write_func_stream { \jobname.cmds } +\cs_new_nopar:Npn \doc_show_functions_defined: { + \bool_if:nT { \g_doc_implementation_bool && \g_doc_checkfunc_bool } { + \typeout{ ======================================== ^^J } -%The toks file uses these, Icould not see the original definition... -\let\zz\m -\let\zv\m + \tl_clear:N \l_tmpa_tl + \seq_map_inline:Nn \g_doc_functions_seq { + \seq_if_in:NnT \g_doc_macros_seq {##1} { + \tl_put_right:Nn \l_tmpa_tl { ##1 ^^J } + \iow_now:Nn \g_write_func_stream { ##1 } + } + } + \iow_close:N \g_write_func_stream + \doc_functions_typeout:n { + Functions~both~documented~and~defined:^^J (In~order~of~being~documented) + } -\setcounter{StandardModuleDepth}{1} -\addtolength{\textwidth}{30pt} + \seq_map_inline:Nn \g_doc_functions_seq { + \seq_if_in:NnF \g_doc_macros_seq {##1} { + \tl_put_right:Nn \l_tmpa_tl { ##1 ^^J } + } + } + \doc_functions_typeout:n { Functions~documented~but~not~defined: } -\let\@@oldlist\list -\def\list#1#2{\@@oldlist{#1}{#2\listparindent\z@}} + \seq_map_inline:Nn \g_doc_macros_seq { + \seq_if_in:NnF \g_doc_functions_seq {##1} { + \tl_put_right:Nn \l_tmpa_tl { ##1 ^^J } + } + } + \doc_functions_typeout:n { Functions~defined~but~not~documented: } -\setlength{\parindent}{0pt} -\setlength{\itemindent}{0pt} -\setlength{\parskip}{\medskipamount} - -% \section{DocInclude} -% -% \begin{macrocode} -\@addtoreset{CodelineNo}{part} -% \end{macrocode} -% -% \begin{macro}{\DocInclude} -% More or less exactly the same as |\include|, but uses |\DocInput| -% on a |dtx| file, not |\input| on a |tex| file. -% \changes{v2.0b}{1994/03/14}{Rename from \cs{docinclude}} -% \changes{v2.0f}{1994/03/25}{Use \cs{part}} -% \changes{v2.0u}{1999/08/08}{Also works for .fdd (M. Schroeder)} -% \begin{macrocode} -\def\partname{File} -% \end{macrocode} -% -% \begin{macrocode} -\newcommand*{\DocInclude}[1]{% - \relax - \clearpage - \docincludeaux - \IfFileExists{#1.fdd}{\def\currentfile{#1.fdd}}{\def\currentfile{#1.dtx}}% - \ifnum\@auxout=\@partaux - \@latexerr{\string\include\space cannot be nested}\@eha - \else \@docinclude#1 \fi} -\def\@docinclude#1 {\clearpage -\if@filesw \immediate\write\@mainaux{\string\@input{#1.aux}}\fi -\@tempswatrue\if@partsw \@tempswafalse\edef\@tempb{#1}\@for -\@tempa:=\@partlist\do{\ifx\@tempa\@tempb\@tempswatrue\fi}\fi -\if@tempswa \let\@auxout\@partaux \if@filesw -\immediate\openout\@partaux #1.aux -\immediate\write\@partaux{\relax}\fi -% \end{macrocode} -% We need to save (and later restore) various index-related -% commands which might be changed by the included file. -% \begin{macrocode} -\let\@ltxdoc@PrintIndex\PrintIndex -\let\PrintIndex\relax -\let\@ltxdoc@PrintChanges\PrintChanges -\let\PrintChanges\relax -\let\@ltxdoc@theglossary\theglossary -\let\@ltxdoc@endtheglossary\endtheglossary -\part{\currentfile}% - {\let\ttfamily\relax - \xdef\filekey{\filekey, \thepart={\ttfamily\currentfile}}}% -\DocInput{\currentfile}% -\let\PrintIndex\@ltxdoc@PrintIndex -\let\PrintChanges\@ltxdoc@PrintChanges -\let\theglossary\@ltxdoc@theglossary -\let\endtheglossary\@ltxdoc@endtheglossary -\clearpage -\@writeckpt{#1}\if@filesw \immediate\closeout\@partaux \fi -\else\@nameuse{cp@#1}\fi\let\@auxout\@mainaux} -% \end{macrocode} -% -% \begin{macrocode} -\gdef\codeline@wrindex#1{\if@filesw - \immediate\write\@indexfile - {\string\indexentry{#1}% - {\filesep\number\c@CodelineNo}}\fi}% -% \end{macrocode} -% \end{macro} -% -% \begin{macrocode} -\let\filesep\@empty -% \end{macrocode} -% -% \begin{macro}{\docincludeaux} -% \changes{v2.06}{1994/03/31}{Use \cs{footnotesize} in file key.} -% \changes{v2.0k}{1994/05/21}{Use \cs{aalph}} -% \begin{macrocode} -\def\docincludeaux{% - \def\thepart{\aalph{part}}\def\filesep{\thepart-}% - \let\filekey\@gobble - \g@addto@macro\index@prologue{% - \gdef\@oddfoot{\parbox{\textwidth}{\strut\footnotesize - \raggedright{\bfseries File Key:} \filekey}}% - \let\@evenfoot\@oddfoot}% - \global\let\docincludeaux\relax - \gdef\@oddfoot{% - \expandafter\ifx\csname ver@\currentfile\endcsname\relax - File \thepart: {\ttfamily\currentfile} % - \else - \GetFileInfo{\currentfile}% - File \thepart: {\ttfamily\filename} % - Date: \filedate\ % - Version \fileversion - \fi - \hfill\thepage}% - \let\@evenfoot\@oddfoot}% -% \end{macrocode} -% \end{macro} -% -% -% \begin{macrocode} -\def\task#1#2{} -%</class> -% \end{macrocode} -% \Finale -% + \typeout{ ======================================== } + } +} +\AtEndDocument{ \doc_show_functions_defined: } +\cs_set_nopar:Npn \doc_functions_typeout:n #1 { + \tl_if_empty:NF \l_tmpa_tl { + \typeout{ + -------------------------------------- ^^J #1 ^^J + -------------------------------------- ^^J \l_tmpa_tl + } + \tl_clear:N \l_tmpa_tl + } +} +\g@addto@macro\theindex{\MakePrivateLetters} +\setcounter{IndexColumns}{2} +\IndexPrologue{ + \part*{Index} + \markboth{Index}{Index} + \addcontentsline{toc}{part}{Index} + The~italic~numbers~denote~the~pages~where~the~ + corresponding~entry~is~described,~ + numbers~underlined~point~to~the~definition,~ + all~others~indicate~the~places~where~it~is~used. +} +\cs_set_nopar:Npn \doc_special_main_index:n #1 { + \index{ + \@gobble#1 + \actualchar + \string\verb\quotechar*\verbatimchar#1\verbatimchar + \encapchar + hdpgindex{\thepage}{usage} + } +} +\cs_set_nopar:Npn \doc_special_main_index:o { \exp_args:No \doc_special_main_index:n } +\cs_set_nopar:Npn \hdpgindex #1#2#3 { + \csname\ifx\\#2\\relax\else#2\fi\endcsname{ + \hyperlink{page.#1}{#3} + } +} +\g@addto@macro \PrintIndex { \AtEndDocument{ \typeout{^^J + ========================================^^J + Generate~the~index~by~executing^^J + \msg_four_spaces: makeindex~-s~l3doc.ist~-o~\jobname.ind~\jobname.idx^^J + ========================================^^J + }} +} +\GlossaryPrologue{ + \part*{Change~History} + {\GlossaryParms\ttfamily\hyphenchar\font=`\-} + \markboth{Change~History}{Change~History} + \addcontentsline{toc}{part}{Change~History} +} +\g@addto@macro \PrintChanges { \AtEndDocument{ \typeout{^^J + ========================================^^J + Generate~the~change~list~by~executing^^J + \msg_four_spaces: makeindex~-s~gglo.ist~~-o~\jobname.gls~\jobname.glo^^J + ========================================^^J + }} +} +\cs_new_nopar:Npn \includeltpatch { + \cs_set_nopar:Npn \currentfile {l3patch.ltx} + \part{l3patch} + {\cs_set_eq:NN \ttfamily\relax + \cs_gset_nopar:Npx \filekey{\filekey, \thepart={\ttfamily\currentfile}}} + Things~we~did~wrong\ldots + \IndexInput{l3patch.ltx}} +\cs_set_nopar:Npn \patchdate{0} +\begingroup + %%\cs_set_nopar:Npn \ProvidesFile#1\fmtversion#2{\date{#2}\endinput} + \cs_set_nopar:Npn \ProvidesFile#1[#2#3]{\date{#2}\endinput} + \input{l3vers.dtx} + \cs_gset_nopar:Npx \@date{\@date} + \cs_gset_eq:NN \X@date \@date + \cs_set:Npn \Xdef#1#2#3\def#4#5 { + \cs_gset_nopar:Npx \X@date{#2} + \cs_gset_nopar:Npx \patchdate{#5} + \endinput + } + \InputIfFileExists{l3patch.ltx}{ + \cs_set_eq:NN \cs_set_nopar:Npn \Xdef + }{ + \cs_gset_eq:NN \includeltpatch \relax + } +\endgroup +\ifx\@date\X@date + \cs_set_nopar:Npn \Xpatch{0} + \ifx\patchdate\Xpatch\else + \cs_set_nopar:Npx \@date {\@date\space Patch level \patchdate} + \fi +\else + \@warning{l3patch.ltx does not match l3vers.dtx!} + \cs_set_eq:NN \includeltpatch \relax +\fi +\bool_if:NTF \g_doc_full_bool { + \RecordChanges + \CodelineIndex + \EnableCrossrefs + \AlsoImplementation +}{ + \CodelineNumbered + \DisableCrossrefs + \OnlyDescription +} +\InputIfFileExists{l3doc.cfg}{ + \typeout{*************************************^^J + *~Local~config~file~l3doc.cfg~used ^^J + *************************************} +}{} +%% +%% +%% End of file `l3doc.cls'. diff --git a/Master/texmf-dist/tex/latex/expl3/l3expan.sty b/Master/texmf-dist/tex/latex/expl3/l3expan.sty index 4e8ee86603e..c4929513b38 100644 --- a/Master/texmf-dist/tex/latex/expl3/l3expan.sty +++ b/Master/texmf-dist/tex/latex/expl3/l3expan.sty @@ -15,7 +15,7 @@ %% Do not distribute a modified version of this file. %% %% -%% File: l3expan.dtx Copyright (C) 1990-2006 LaTeX3 project +%% File: l3expan.dtx Copyright (C) 1990-2009 LaTeX3 project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this @@ -33,7 +33,7 @@ %% %% The development version of the bundle can be found at %% -%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/ +%% http://www.latex-project.org/svnroot/experimental/trunk/ %% %% for those people who are interested. %% @@ -48,171 +48,246 @@ %% %% ----------------------------------------------------------------------- \RequirePackage{l3names} -\GetIdInfo$Id: l3expan.dtx 735 2008-01-14 22:31:02Z morten $ +\GetIdInfo$Id: l3expan.dtx 1376 2009-06-01 17:01:30Z morten $ {L3 Experimental Argument Expansion module} \ProvidesExplPackage {\filename}{\filedate}{\fileversion}{\filedescription} -\RequirePackage{l3tlp} -\tlp_new:Nn\l_exp_tlp{} -\def_long_new:Npn\exp_arg_next:nnn#1#2#3{ +\package_check_loaded_expl: +\cs_new_nopar:Npn \l_exp_tl {} +\cs_new:Npn\exp_arg_next:nnn#1#2#3{ + #2\:::{#3{#1}} +} +\cs_new:Npn\exp_arg_next_nobrace:nnn#1#2#3{ #2\:::{#3#1} } -\def_long_new:Npn\::n#1\:::#2#3{ +\cs_new:Npn\:::#1{#1} +\cs_new:Npn\::n#1\:::#2#3{ #1\:::{#2{#3}} } -\def_long_new:Npn\::N#1\:::#2#3{ +\cs_new:Npn\::N#1\:::#2#3{ #1\:::{#2#3} } -\def_long_new:Npn\::c#1\:::#2#3{ - \exp_after:NN\exp_arg_next:nnn\cs:w #3\cs_end:{#1}{#2} +\cs_new:Npn\::c#1\:::#2#3{ + \exp_after:wN\exp_arg_next_nobrace:nnn\cs:w #3\cs_end:{#1}{#2} } -\def_long_new:Npn\::o#1\:::#2#3{ - \exp_after:NN\exp_arg_next:nnn\exp_after:NN{\exp_after:NN{#3}}{#1}{#2} +\cs_new:Npn\::o#1\:::#2#3{ + \exp_after:wN\exp_arg_next:nnn\exp_after:wN{#3}{#1}{#2} } -\def_long_new:Npn\::f#1\:::#2#3{ - \exp_after:NN\exp_arg_next:nnn - \exp_after:NN{\exp_after:NN{\int_to_roman:w -`0 #3}} +\cs_new:Npn\::f#1\:::#2#3{ + \exp_after:wN\exp_arg_next:nnn + \exp_after:wN{\tex_romannumeral:D -`0 #3} {#1}{#2} } -\def_new:Npn \exp_stop_f: {~} -\let_new:NN \exp_arg:x \expanded % Move eventually. +\cs_new_nopar:Npn \exp_stop_f: {~} +\cs_new_eq:NN \exp_arg:x \expanded % Move eventually. \cs_if_free:NTF\exp_arg:x{ - \def_long_new:Npn\::x#1\:::#2#3{ - % \tlp_set:Nx\l_exp_tlp{{{#3}}} - \def:Npx \l_exp_tlp{{{#3}}} - \exp_after:NN\exp_arg_next:nnn\l_exp_tlp{#1}{#2}} + \cs_new:Npn\::x#1\:::#2#3{ + \cs_set_nopar:Npx \l_exp_tl{{#3}} + \exp_after:wN\exp_arg_next:nnn\l_exp_tl{#1}{#2}} } { - \def_long_new:Npn\::x#1\:::#2#3{ - \exp_after:NN\exp_arg_next:nnn - \exp_after:NN{\exp_arg:x{{#3}}}{#1}{#2} + \cs_new:Npn\::x#1\:::#2#3{ + \exp_after:wN\exp_arg_next:nnn + \exp_after:wN{\exp_arg:x{{#3}}}{#1}{#2} } } -\def_long_new:Npn\:::#1{#1} -\def_long_new:Npn\::C#1\:::#2#3{ - \exp_after:NN\exp_C_aux:nnn\cs:w #3\cs_end:{#1}{#2}} -\def_long_new:Npn\exp_C_aux:nnn #1{ - \exp_after:NN - \exp_arg_next:nnn - \exp_after:NN - { - \exp_after:NN - {#1} - } -} -\def_long_new:Npn\::E#1\:::#2#3{ - \exp_after:NN\exp_arg_next:nnn \exp_after:NN{#3}{#1}{#2} -} -\def_long_new:Npn\::e#1\:::#2#3{ - \exp_after:NN\exp_arg_next:nnn \exp_after:NN{#3}{#1}{#2} -} -\def_long_new:Npn\::d#1\:::#2#3{ - \exp_after:NN\exp_after:NN\exp_after:NN\exp_arg_next:nnn - \exp_after:NN\exp_after:NN\exp_after:NN{ - \exp_after:NN\exp_after:NN\exp_after:NN{#3}}{#1}{#2} -} -\let:NN \exp_args:NE \exp_after:NN -\def:Npn \exp_args:NNE #1{\exp_args:NE#1\exp_args:NE} -\def:Npn \exp_args:NNNE #1#2{\exp_args:NE#1\exp_args:NE#2\exp_args:NE} -\def:Npn \exp_args:NEE #1{\exp_args:NE\exp_args:NE\exp_args:NE#1\exp_args:NE} -\def:Npn \exp_args:NcE #1#2{\exp_after:NN #1\cs:w #2\exp_after:NN\cs_end:} -\def:Npn \exp_args:Nd {\::d\:::} -\def:Npn \exp_args:NNd {\::N\::d\:::} - -\def:Npn \exp_args:NC {\::C\:::} -\def:Npn \exp_args:NNC {\::N\::C\:::} -\def:Npn \exp_args:NNf {\::N\::f\:::} -\def:Npn \exp_args:NNno {\::N\::n\::o\:::} -\def:Npn \exp_args:NNnx {\::N\::n\::x\:::} % new -\def:Npn \exp_args:NNoo {\::N\::o\::o\:::} % new -\def:Npn \exp_args:NNox {\::N\::o\::x\:::} % new -\def:Npn \exp_args:NNx {\::N\::x\:::} -\def:Npn \exp_args:NcNc {\::c\::N\::c\:::} -\def:Npn \exp_args:NcNo {\::c\::N\::o\:::} -\def:Npn \exp_args:Ncco {\::c\::c\::o\:::} -\def:Npn \exp_args:Ncco {\::c\::c\::o\:::} -\def:Npn \exp_args:Nccx {\::c\::c\::x\:::} -\def:Npn \exp_args:Ncnx {\::c\::n\::x\:::} -\def:Npn \exp_args:Ncx {\::c\::x\:::} -\def:Npn \exp_args:Nf {\::f\:::} -\def:Npn \exp_args:Nfo{\::f\::o\:::} -\def:Npn \exp_args:Nnf {\::n\::f\:::} -\def:Npn \exp_args:NnnN {\::n\::n\::N\:::} %% Strange one this one... -\def:Npn \exp_args:Nnnc {\::n\::n\::c\:::} -\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:Nnox {\::n\::o\::x\:::} -\def:Npn \exp_args:Nnx {\::n\::x\:::} -\def:Npn \exp_args:Noo {\::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\:::} -\def_long_new:Npn\exp_not:o#1{\exp_not:n\exp_after:NN{#1}} -\def_long_new:Npn\exp_not:d#1{ - \exp_not:n\exp_after:NN\exp_after:NN\exp_after:NN{#1} -} -\def_long_new:Npn\exp_not:f#1{ - \exp_not:n\exp_after:NN{\int_to_roman:w -`0 #1} -} -\def_new:Npn\exp_not:E{\exp_after:NN\exp_not:N} -\def_long_new:Npn\exp_not:c#1{\exp_after:NN\exp_not:N\cs:w#1\cs_end:} -\def_long_new:Npn \exp_args:No #1#2{\exp_after:NN#1\exp_after:NN{#2}} -\def_long_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_long_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_long_new:Npn \exp_args:NNo #1#2#3{\exp_after:NN#1\exp_after:NN#2 - \exp_after:NN{#3}} -\def_long_new:Npn \exp_args:NNO #1#2#3 {\exp_after:NN#1 - \exp_after:NN#2 #3} -\def_long_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_long_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}} -\def_long_new:Npn \exp_args:Nc #1#2{\exp_after:NN#1\cs:w#2\cs_end:} -\def_long_new:Npn \exp_args:NNc #1#2#3{\exp_after:NN#1\exp_after:NN#2 +\cs_new:Npn \::V#1\:::#2#3{ + \exp_after:wN\exp_arg_next:nnn + \exp_after:wN{ + \tex_romannumeral:D -`0 + \exp_eval_register:N #3 + } + {#1}{#2} +} +\cs_new:Npn \::v#1\:::#2#3{ + \exp_after:wN\exp_arg_next:nnn + \exp_after:wN{ + \tex_romannumeral:D -`0 + \exp_eval_register:c {#3} + } + {#1}{#2} +} +\cs_set_nopar:Npn \exp_eval_register:N #1{ + \exp_after:wN \if_meaning:w \exp_not:N #1#1 + \if_meaning:w \tex_relax:D #1 + \exp_eval_error_msg:w + \fi: + \else: + \exp_after:wN \use_i_ii:nnn + \fi: + \exp_after:wN \exp_stop_f: \tex_the:D #1 +} +\cs_set_nopar:Npn \exp_eval_register:c #1{ + \exp_after:wN\exp_eval_register:N\cs:w #1\cs_end: +} +\group_begin:% +\tex_catcode:D`\!=11\tex_relax:D% +\tex_catcode:D`\ =11\tex_relax:D% +\cs_gset:Npn\exp_eval_error_msg:w#1\tex_the:D#2{% +\fi:\fi:\erroneous variable used!}% +\group_end:% +\cs_new:Npn\::d#1\:::#2#3{ + \exp_after:wN\exp_after:wN\exp_after:wN\exp_arg_next:nnn + \exp_after:wN\exp_after:wN\exp_after:wN{#3}{#1}{#2} +} +\cs_new:Npn \exp_args:No #1#2{\exp_after:wN#1\exp_after:wN{#2}} +\cs_new:Npn \exp_args:NNo #1#2#3{\exp_after:wN#1\exp_after:wN#2 + \exp_after:wN{#3}} +\cs_new:Npn \exp_args:NNNo #1#2#3#4{\exp_after:wN#1\exp_after:wN#2 + \exp_after:wN#3\exp_after:wN{#4}} +\cs_set:Npn \exp_args:Nc #1#2{\exp_after:wN#1\cs:w#2\cs_end:} +\cs_new:Npn \exp_args:cc #1#2{\cs:w #1\exp_after:wN\cs_end:\cs:w #2\cs_end:} +\cs_new:Npn \exp_args:NNc #1#2#3{\exp_after:wN#1\exp_after:wN#2 \cs:w#3\cs_end:} -\def_long_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_long_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_long_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_new:Npn \exp_args:Ncc #1#2#3{\exp_after:wN#1 + \cs:w#2\exp_after:wN\cs_end:\cs:w#3\cs_end:} +\cs_new:Npn \exp_args:Nccc #1#2#3#4{\exp_after:wN#1 + \cs:w#2\exp_after:wN\cs_end:\cs:w#3\exp_after:wN \cs_end:\cs:w #4\cs_end:} -\def_long_new:Npn \exp_args:Nco #1#2#3{\exp_after:NN#1\cs:w#2\exp_after:NN - \cs_end:\exp_after:NN{#3}} -\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: - } - \cs_if_free:cT - {exp_args:N#3} - {\def:cpx {exp_args:N#3} - {\exp_args_form_x:w #3 :} - } -} -\def_new:Npn\exp_args_form_x:w #1 { +\cs_new:Npn \exp_args:Nco #1#2#3{\exp_after:wN#1\cs:w#2\exp_after:wN + \cs_end:\exp_after:wN{#3}} +\cs_set_nopar:Npn \exp_args:Nd {\::d\:::} +\cs_set_nopar:Npn \exp_args:Nf {\::f\:::} +\cs_set_nopar:Npn \exp_args:Nv {\::v\:::} +\cs_set_nopar:Npn \exp_args:NV {\::V\:::} +\cs_set_nopar:Npn \exp_args:Nx {\::x\:::} +\cs_set_nopar:Npn \exp_args:NNd {\::N\::d\:::} +\cs_set_nopar:Npn \exp_args:NNf {\::N\::f\:::} +\cs_set_nopar:Npn \exp_args:NNv {\::N\::v\:::} +\cs_set_nopar:Npn \exp_args:NNV {\::N\::V\:::} +\cs_set_nopar:Npn \exp_args:NNx {\::N\::x\:::} + +\cs_set_nopar:Npn \exp_args:Ncx {\::c\::x\:::} +\cs_set_nopar:Npn \exp_args:Nfo {\::f\::o\:::} +\cs_set_nopar:Npn \exp_args:Nff {\::f\::f\:::} +\cs_set_nopar:Npn \exp_args:Ncf {\::c\::f\:::} +\cs_set_nopar:Npn \exp_args:Nnf {\::n\::f\:::} +\cs_set_nopar:Npn \exp_args:Nno {\::n\::o\:::} +\cs_set_nopar:Npn \exp_args:Nnx {\::n\::x\:::} + +\cs_set_nopar:Npn \exp_args:Noc {\::o\::c\:::} +\cs_set_nopar:Npn \exp_args:Noo {\::o\::o\:::} +\cs_set_nopar:Npn \exp_args:Nox {\::o\::x\:::} + +\cs_set_nopar:Npn \exp_args:NVV {\::V\::V\:::} + +\cs_set_nopar:Npn \exp_args:Nxo {\::x\::o\:::} +\cs_set_nopar:Npn \exp_args:Nxx {\::x\::x\:::} +\cs_set_nopar:Npn \exp_args:NNno {\::N\::n\::o\:::} +\cs_set_nopar:Npn \exp_args:NNnx {\::N\::n\::x\:::} +\cs_set_nopar:Npn \exp_args:NNoo {\::N\::o\::o\:::} +\cs_set_nopar:Npn \exp_args:NNox {\::N\::o\::x\:::} + +\cs_set_nopar:Npn \exp_args:Nnnc {\::n\::n\::c\:::} +\cs_set_nopar:Npn \exp_args:Nnno {\::n\::n\::o\:::} +\cs_set_nopar:Npn \exp_args:Nnnx {\::n\::n\::x\:::} +\cs_set_nopar:Npn \exp_args:Nnox {\::n\::o\::x\:::} + +\cs_set_nopar:Npn \exp_args:NcNc {\::c\::N\::c\:::} +\cs_set_nopar:Npn \exp_args:NcNo {\::c\::N\::o\:::} +\cs_set_nopar:Npn \exp_args:Ncco {\::c\::c\::o\:::} +\cs_set_nopar:Npn \exp_args:Ncco {\::c\::c\::o\:::} +\cs_set_nopar:Npn \exp_args:Nccx {\::c\::c\::x\:::} +\cs_set_nopar:Npn \exp_args:Ncnx {\::c\::n\::x\:::} + +\cs_set_nopar:Npn \exp_args:Noox {\::o\::o\::x\:::} +\cs_set_nopar:Npn \exp_args:Nooo {\::o\::o\::o\:::} +\cs_new:Npn\exp_not:o#1{\exp_not:n\exp_after:wN{#1}} +\cs_new:Npn\exp_not:d#1{ + \exp_not:n\exp_after:wN\exp_after:wN\exp_after:wN{#1} +} +\cs_new:Npn\exp_not:f#1{ + \exp_not:n\exp_after:wN{\tex_romannumeral:D -`0 #1} +} +\cs_new:Npn\exp_not:v#1{ + \exp_not:n\exp_after:wN{\tex_romannumeral:D -`0 \exp_eval_register:c {#1}} +} +\cs_new:Npn\exp_not:V#1{ + \exp_not:n\exp_after:wN{\tex_romannumeral:D -`0 \exp_eval_register:N #1} +} +\cs_new:Npn\exp_not:c#1{\exp_after:wN\exp_not:N\cs:w#1\cs_end:} +\cs_new:Npn \cs_generate_variant:Nn #1 { + \chk_if_exist_cs:N #1 + \cs_split_function:NN #1 \cs_generate_variant_aux:nnNn +} +\cs_set:Npn \cs_generate_variant_aux:nnNn #1#2#3#4{ + \cs_generate_variant_aux:nnw {#1}{#2} #4,?,\q_recursion_stop +} +\cs_set:Npn \cs_generate_variant_aux:nnw #1 #2 #3, { + \if:w ? #3 + \exp_after:wN \use_none_delimit_by_q_recursion_stop:w + \fi: + \cs_if_free:cTF { + #1:#3\use:c {use_none:\cs_generate_variant_aux:N #3 ?}#2 + } + { + \cs_new_nopar:cpx { + #1:#3 \use:c{use_none:\cs_generate_variant_aux:N #3 ?}#2 + } + { + \exp_not:c { exp_args:N #3} \exp_not:c {#1:#2} + } + \cs_generate_internal_variant:n {#3} + } + { + \iow_log:x{ + Variant~\token_to_str:c { + #1:#3\use:c {use_none:\cs_generate_variant_aux:N #3 ?}#2 + }~already~defined;~ not~ changing~ it~on~line~ + \tex_the:D \tex_inputlineno:D + } + } + \cs_generate_variant_aux:nnw{#1}{#2} +} +\cs_set:Npn \cs_generate_variant_aux:N #1{ + \if:w ?#1 \exp_after:wN\use_none:nn \fi: n \cs_generate_variant_aux:N +} +\cs_new:Npn \cs_generate_internal_variant:n #1 { + \cs_if_free:cT { exp_args:N #1 }{ + \cs_new:cpx { exp_args:N #1 } + { \cs_generate_internal_variant_aux:n #1 : } + } +} +\cs_new:Npn \cs_generate_internal_variant_aux:n #1 { \exp_not:c{::#1} - \if_meaning:NN #1 : - \else: - \exp_after:NN\exp_args_form_x:w - \fi:} + \if_meaning:w #1 : + \exp_after:wN \use_none:n + \fi: + \cs_generate_internal_variant_aux:n +} +\cs_new:Npn \exp_arg_last_unbraced:nn #1#2 { #2#1 } +\cs_new:Npn \::f_unbraced \:::#1#2 { + \exp_after:wN \exp_arg_last_unbraced:nn + \exp_after:wN { \tex_romannumeral:D -`0 #2 } {#1} +} +\cs_new:Npn \::o_unbraced \:::#1#2 { + \exp_after:wN \exp_arg_last_unbraced:nn \exp_after:wN {#2 }{#1} +} +\cs_new:Npn \::V_unbraced \:::#1#2 { + \exp_after:wN \exp_arg_last_unbraced:nn + \exp_after:wN { \tex_romannumeral:D -`0 \exp_eval_register:N #2 } {#1} +} +\cs_new:Npn \::v_unbraced \:::#1#2 { + \exp_after:wN \exp_arg_last_unbraced:nn + \exp_after:wN { + \tex_romannumeral:D -`0 \exp_eval_register:c {#2} + } {#1} +} +\cs_new_nopar:Npn \exp_last_unbraced:Nf { \::f_unbraced \::: } +\cs_new_nopar:Npn \exp_last_unbraced:NV { \::V_unbraced \::: } +\cs_new_nopar:Npn \exp_last_unbraced:Nv { \::v_unbraced \::: } +\cs_new_nopar:Npn \exp_last_unbraced:NcV { + \::c \::V_unbraced \::: +} +\cs_new:Npn \exp_last_unbraced:NNo #1#2#3 { + \exp_after:wN #1 \exp_after:wN #2 #3 +} +\cs_new_nopar:Npn \exp_last_unbraced:NNV { + \::N \::V_unbraced \::: +} +\cs_new:Npn \exp_last_unbraced:NNNo #1#2#3#4 { + \exp_after:wN #1 \exp_after:wN #2 \exp_after:wN #3 #4 +} %% %% %% End of file `l3expan.sty'. diff --git a/Master/texmf-dist/tex/latex/expl3/l3file.sty b/Master/texmf-dist/tex/latex/expl3/l3file.sty new file mode 100644 index 00000000000..4e576422173 --- /dev/null +++ b/Master/texmf-dist/tex/latex/expl3/l3file.sty @@ -0,0 +1,161 @@ +%% +%% This is file `l3file.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% l3file.dtx (with options: `package') +%% +%% +%% EXPERIMENTAL CODE +%% +%% Do not distribute this file without also distributing the +%% source files specified above. +%% +%% Do not distribute a modified version of this file. +%% +%% +%% File: l3file.dtx Copyright (C) 2009 LaTeX3 project +%% +%% It may be distributed and/or modified under the conditions of the +%% LaTeX Project Public License (LPPL), either version 1.3c of this +%% license or (at your option) any later version. The latest version +%% of this license is in the file +%% +%% http://www.latex-project.org/lppl.txt +%% +%% This file is part of the ``expl3 bundle'' (The Work in LPPL) +%% and all files in that bundle must be distributed together. +%% +%% The released version of this bundle is available from CTAN. +%% +%% ----------------------------------------------------------------------- +%% +%% The development version of the bundle can be found at +%% +%% http://www.latex-project.org/svnroot/experimental/trunk/ +%% +%% for those people who are interested. +%% +%%%%%%%%%%% +%% NOTE: %% +%%%%%%%%%%% +%% +%% Snapshots taken from the repository represent work in progress and may +%% not work or may contain conflicting material! We therefore ask +%% people _not_ to put them into distributions, archives, etc. without +%% prior consultation with the LaTeX Project Team. +%% +%% ----------------------------------------------------------------------- +%% +\RequirePackage{l3names} +\GetIdInfo$Id: l3file.dtx 1352 2009-05-28 11:50:39Z morten $ + {L3 Experimental file loading} +\ProvidesExplPackage + {\filename}{\filedate}{\fileversion}{\filedescription} +\package_check_loaded_expl: +\clist_new:N \g_file_record_clist +\clist_new:N \g_file_record_full_clist +\clist_new:N \l_file_search_path_clist +\ior_new:N \l_file_test_read_stream +\bool_new:N \l_file_tmp_bool +\tl_new:N \l_file_tmp_tl +\prg_new_conditional:Nnn \file_if_exist:n {p,TF,T,F} { + \ior_open:Nn \l_file_test_read_stream {#1} + \ior_if_eof:NTF \l_file_test_read_stream { + \file_if_exist_path:n {#1} + }{ + \ior_close:N \l_file_test_read_stream + \prg_return_true: + } +} +\cs_new_nopar:Nn \file_if_exist_path:n { + \bool_set_false:N \l_file_tmp_bool + \cs_set_nopar:Nn \file_if_exist_aux:n { + \ior_open:Nn \l_file_test_read_stream { #1 ##1 } + \ior_if_eof:NF \l_file_test_read_stream { + \bool_set_true:N \l_file_tmp_bool + \clist_map_break: + } + } + \cs_if_exist:NT \input@path { + \cs_set_eq:NN \l_file_search_path_clist \input@path + } + \clist_map_function:NN \l_file_search_path_clist \file_if_exist_aux:n + \ior_close:N \l_file_test_read_stream + \bool_if:NTF \l_file_tmp_bool { + \prg_return_true: + }{ + \prg_return_false: + } +} +\cs_new_nopar:Nn \file_if_exist_aux:n { } +\cs_new_nopar:Nn \file_add_path:nN { + \tl_clear:N #2 + \ior_open:Nn \l_file_test_read_stream {#1} + \ior_if_eof:NTF \l_file_test_read_stream { + \file_add_path_search:nN {#1} #2 + }{ + \tl_set:Nn #2 {#1} + } + \ior_close:N \l_file_test_read_stream +} +\cs_new_nopar:Nn \file_add_path_search:nN { + \cs_set_nopar:Nn \file_add_path_aux:n { + \ior_open:Nn \l_file_test_read_stream { ##1 #1 } + \ior_if_eof:NF \l_file_test_read_stream { + \tl_set:Nn #2 { ##1 #1 } + \clist_map_break: + } + } + \cs_if_exist:NT \input@path { + \cs_set_eq:NN \l_file_search_path_clist \input@path + } + \clist_map_function:NN \l_file_search_path_clist \file_add_path_aux:n +} +\cs_new_nopar:Nn \file_add_path_aux:n { } +\cs_new:Nn \file_input:n { + \file_add_path:nN {#1} \l_file_tmp_tl + \tl_if_empty:NF \l_file_tmp_tl { + \file_input_no_check:n \l_file_tmp_tl + } +} +\cs_new:Nn \file_input_no_record:n { + \file_add_path:nN {#1} \l_file_tmp_tl + \tl_if_empty:NF \l_file_tmp_tl { + \file_input_no_check_no_record:n \l_file_tmp_tl + } +} +\cs_new_nopar:Nn \file_input_no_check:n { + \clist_gput_right:Nx \g_file_record_clist {#1} + \wlog{ADDING: #1} + \@addtofilelist {#1} + \clist_gput_right:Nx \g_file_record_full_clist {#1} + \tex_input:D #1 ~ +} +\cs_new_nopar:Nn \file_input_no_check_no_record:n { + \clist_gput_right:Nx \g_file_record_full_clist {#1} + \tex_input:D #1 ~ +} +\cs_new_nopar:Nn \file_list: { + \file_list:N \g_file_record_clist +} +\cs_new_nopar:Nn \file_list_full: { + \file_list:N \g_file_record_full_clist +} +\cs_new_nopar:Nn \file_list:N { + \clist_remove_duplicates:N #1 + \iow_log:x { *~File~List~* } + \clist_map_function:NN #1 \file_list_aux:n + \iow_log:x { ************* } +} +\cs_new_nopar:Nn \file_list_aux:n { + \iow_log:x { #1 } +} +\AtBeginDocument{ + \clist_put_right:NV \g_file_record_clist \@filelist + \clist_put_right:NV \g_file_record_full_clist \@filelist +} +%% +%% +%% End of file `l3file.sty'. diff --git a/Master/texmf-dist/tex/latex/expl3/l3int.sty b/Master/texmf-dist/tex/latex/expl3/l3int.sty index 7c9ea287861..3ab5772e28a 100644 --- a/Master/texmf-dist/tex/latex/expl3/l3int.sty +++ b/Master/texmf-dist/tex/latex/expl3/l3int.sty @@ -15,7 +15,7 @@ %% Do not distribute a modified version of this file. %% %% -%% File: l3int.dtx Copyright (C) 1990-2008 LaTeX3 project +%% File: l3int.dtx Copyright (C) 1990-2009 LaTeX3 project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this @@ -33,7 +33,7 @@ %% %% The development version of the bundle can be found at %% -%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/ +%% http://www.latex-project.org/svnroot/experimental/trunk/ %% %% for those people who are interested. %% @@ -48,68 +48,72 @@ %% %% ----------------------------------------------------------------------- \RequirePackage{l3names} -\GetIdInfo$Id: l3int.dtx 738 2008-08-01 13:21:42Z morten $ +\GetIdInfo$Id: l3int.dtx 1362 2009-05-28 20:19:21Z joseph $ {L3 Experimental Integer module} - \ProvidesExplPackage {\filename}{\filedate}{\fileversion}{\filedescription} -\RequirePackage{l3num} -\let_new:NN \int_to_roman:w \tex_romannumeral:D -\let_new:NN \int_to_number:w \tex_number:D -\let_new:NN \int_advance:w \tex_advance:D -\def_new:Npn \int_incr:N #1{\int_advance:w#1\c_one +\package_check_loaded_expl: +\cs_new_eq:NN \int_to_roman:w \tex_romannumeral:D +\cs_new_eq:NN \int_to_number:w \tex_number:D +\cs_new_eq:NN \int_advance:w \tex_advance:D +\cs_new_nopar:Npn \int_new:N #1 { + \chk_if_free_cs:N #1 + \newcount #1 +} +\cs_generate_variant:Nn \int_new:N {c} +\cs_new_nopar:Npn \int_set:Nn #1#2{#1 \intexpr_eval:w #2\intexpr_eval_end: +} +\cs_new_nopar:Npn \int_gset:Nn { + \pref_global:D + \int_set:Nn } +\cs_generate_variant:Nn\int_set:Nn {cn} +\cs_generate_variant:Nn\int_gset:Nn {cn} +\cs_new_nopar:Npn \int_incr:N #1{\int_advance:w#1\c_one } -\def_new:Npn \int_decr:N #1{\int_advance:w#1\c_minus_one +\cs_new_nopar:Npn \int_decr:N #1{\int_advance:w#1\c_minus_one } -\def_new:Npn \int_gincr:N { +\cs_new_nopar:Npn \int_gincr:N { \pref_global:D \int_incr:N} -\def_new:Npn \int_gdecr:N { +\cs_new_nopar:Npn \int_gdecr:N { \pref_global:D \int_decr:N} -\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} -\def:Npn \int_incr:c {\exp_args:Nc\int_incr:N} -\def:Npn \int_decr:c {\exp_args:Nc\int_decr:N} -\def:Npn \int_gincr:c {\exp_args:Nc\int_gincr:N} -\def:Npn \int_gdecr:c {\exp_args:Nc\int_gdecr:N} -\let:NN \int_new:N \newcount% allocation better nick the LaTeX one... -\def_new:Npn \int_new:c {\exp_args:Nc \int_new:N} -\def_new:Npn \int_set:Nn #1#2{#1 \int_eval:w #2\int_eval_end: -} -\def_new:Npn \int_gset:Nn { - \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 } -\def_new:Npn \int_zero:N #1 {#1=\c_zero} -\def_new:Npn \int_zero:c #1 {\exp_args:Nc \int_zero:N} -\def_new:Npn \int_gzero:N #1 {\pref_global:D #1=\c_zero} -\def_new:Npn \int_gzero:c {\exp_args:Nc \int_gzero:N} -\def_new:Npn \int_add:Nn #1#2{ - \int_advance:w #1 by \int_eval:w #2\int_eval_end: -} -\def_new:Npn\int_add:cn{\exp_args:Nc\int_add:Nn} -\def_new:Npn \int_sub:Nn #1#2{ - \int_advance:w #1-\int_eval:w #2\int_eval_end: -} -\def_new:Npn \int_gadd:Nn { +\cs_set_nopar:Npn \int_incr:N #1{\int_add:Nn#1\c_one} +\cs_set_nopar:Npn \int_decr:N #1{\int_add:Nn#1\c_minus_one} +\cs_set_nopar:Npn \int_gincr:N #1{\int_gadd:Nn#1\c_one} +\cs_set_nopar:Npn \int_gdecr:N #1{\int_gadd:Nn#1\c_minus_one} +\cs_generate_variant:Nn \int_incr:N {c} +\cs_generate_variant:Nn \int_decr:N {c} +\cs_generate_variant:Nn \int_gincr:N {c} +\cs_generate_variant:Nn \int_gdecr:N {c} +\cs_new_nopar:Npn \int_zero:N #1 {#1=\c_zero} +\cs_generate_variant:Nn \int_zero:N {c} +\cs_new_nopar:Npn \int_gzero:N #1 {\pref_global:D #1=\c_zero} +\cs_generate_variant:Nn \int_gzero:N {c} +\cs_new_nopar:Npn \int_add:Nn #1#2{ + \int_advance:w #1 by \intexpr_eval:w #2\intexpr_eval_end: +} +\cs_new_nopar:Npn \int_sub:Nn #1#2{ + \int_advance:w #1-\intexpr_eval:w #2\intexpr_eval_end: +} +\cs_new_nopar:Npn \int_gadd:Nn { \pref_global:D \int_add:Nn } -\def_new:Npn \int_gsub:Nn { +\cs_new_nopar:Npn \int_gsub:Nn { \pref_global:D \int_sub:Nn } -\def_new:Npn \int_gadd:cn{\exp_args:Nc\int_gadd:Nn} -\def_new:Npn \int_sub:cn{\exp_args:Nc\int_sub:Nn} -\def_new:Npn \int_gsub:cn{\exp_args:Nc\int_gsub:Nn} -\let_new:NN \int_use:N \tex_the:D -\def_new:Npn \int_use:c #1{\int_use:N \cs:w#1\cs_end:} -\def_new:Npn \int_to_arabic:n #1{\int_to_number:w \int_eval:n{#1}} -\def_new:Npn \int_roman_lcuc_mapping:Nnn #1#2#3{ - \def:cpn {int_to_lc_roman_#1:}{#2} - \def:cpn {int_to_uc_roman_#1:}{#3} +\cs_generate_variant:Nn \int_add:Nn {cn} +\cs_generate_variant:Nn \int_gadd:Nn {cn} +\cs_generate_variant:Nn \int_sub:Nn {cn} +\cs_generate_variant:Nn \int_gsub:Nn {cn} +\cs_new_eq:NN \int_use:N \tex_the:D +\cs_new_nopar:Npn \int_use:c #1{\int_use:N \cs:w#1\cs_end:} +\cs_new_eq:NN \int_show:N \tex_showthe:D +\cs_new_nopar:Npn \int_show:c {\exp_args:Nc \int_show:N } +\cs_new_nopar:Npn \int_to_arabic:n #1{ \intexpr_eval:n{#1}} +\cs_new_nopar:Npn \int_roman_lcuc_mapping:Nnn #1#2#3{ + \cs_set_nopar:cpn {int_to_lc_roman_#1:}{#2} + \cs_set_nopar:cpn {int_to_uc_roman_#1:}{#3} } \int_roman_lcuc_mapping:Nnn i i I \int_roman_lcuc_mapping:Nnn v v V @@ -119,29 +123,29 @@ \int_roman_lcuc_mapping:Nnn d d D \int_roman_lcuc_mapping:Nnn m m M \int_roman_lcuc_mapping:Nnn Q \use_none:nn \use_none:nn -\def_new:Npn \int_to_roman:n #1 { - \exp_after:NN \int_to_roman_lcuc:NN \exp_after:NN l - \int_to_roman:w \int_eval:n {#1} Q +\cs_new_nopar:Npn \int_to_roman:n #1 { + \exp_after:wN \int_to_roman_lcuc:NN \exp_after:wN l + \int_to_roman:w \intexpr_eval:n {#1} Q } -\def_new:Npn \int_to_Roman:n #1 { - \exp_after:NN \int_to_roman_lcuc:NN \exp_after:NN u - \int_to_roman:w \int_eval:n {#1} Q +\cs_new_nopar:Npn \int_to_Roman:n #1 { + \exp_after:wN \int_to_roman_lcuc:NN \exp_after:wN u + \int_to_roman:w \intexpr_eval:n {#1} Q } -\def_new:Npn \int_to_roman_lcuc:NN #1#2{ - \cs_use:c {int_to_#1c_roman_#2:} +\cs_new_nopar:Npn \int_to_roman_lcuc:NN #1#2{ + \use:c {int_to_#1c_roman_#2:} \int_to_roman_lcuc:NN #1 } -\def:Npn \int_convert_number_with_rule:nnN #1#2#3{ - \int_compare:nNnTF {#1}>{#2} +\cs_set_nopar:Npn \int_convert_number_with_rule:nnN #1#2#3{ + \intexpr_compare:nNnTF {#1}>{#2} { - \exp_args:No \int_convert_number_with_rule:nnN - { \int_use:N\int_div_truncate:nn {#1-1}{#2} }{#2} + \exp_args:Nf \int_convert_number_with_rule:nnN + { \intexpr_div_truncate:nn {#1-1}{#2} }{#2} #3 - \exp_args:No #3 { \int_use:N\int_eval:n{1+\int_mod:nn {#1-1}{#2}} } + \exp_args:Nf #3 { \intexpr_eval:n{1+\intexpr_mod:nn {#1-1}{#2}} } } - { \exp_args:No #3{ \int_use:N\int_eval:n{#1} } } + { \exp_args:Nf #3{ \intexpr_eval:n{#1} } } } -\def_new:Npn \int_alph_default_conversion_rule:n #1{ +\cs_new_nopar:Npn \int_alph_default_conversion_rule:n #1{ \if_case:w #1 \or: a\or: b\or: c\or: d\or: e\or: f \or: g\or: h\or: i\or: j\or: k\or: l @@ -150,7 +154,7 @@ \or: y\or: z \fi: } -\def_new:Npn \int_Alph_default_conversion_rule:n #1{ +\cs_new_nopar:Npn \int_Alph_default_conversion_rule:n #1{ \if_case:w #1 \or: A\or: B\or: C\or: D\or: E\or: F \or: G\or: H\or: I\or: J\or: K\or: L @@ -159,15 +163,15 @@ \or: Y\or: Z \fi: } -\def_new:Npn \int_to_alph:n #1{ +\cs_new_nopar:Npn \int_to_alph:n #1{ \int_convert_number_with_rule:nnN {#1}{26} \int_alph_default_conversion_rule:n } -\def_new:Npn \int_to_Alph:n #1{ +\cs_new_nopar:Npn \int_to_Alph:n #1{ \int_convert_number_with_rule:nnN {#1}{26} \int_Alph_default_conversion_rule:n } -\def_new:Npn \int_to_symbol:n #1{ +\cs_new_nopar:Npn \int_to_symbol:n #1{ \mode_if_math:TF { \int_convert_number_with_rule:nnN {#1}{9} @@ -178,7 +182,7 @@ \int_symbol_text_conversion_rule:n } } -\def_new:Npn \int_symbol_math_conversion_rule:n #1 { +\cs_new_nopar:Npn \int_symbol_math_conversion_rule:n #1 { \if_case:w #1 \or: * \or: \dagger @@ -191,7 +195,7 @@ \or: \ddagger\ddagger \fi: } -\def_new:Npn \int_symbol_text_conversion_rule:n #1 { +\cs_new_nopar:Npn \int_symbol_text_conversion_rule:n #1 { \if_case:w #1 \or: \textasteriskcentered \or: \textdagger @@ -209,175 +213,139 @@ \int_new:N \l_tmpc_int \int_new:N \g_tmpa_int \int_new:N \g_tmpb_int -\int_new:N \l_loop_int % a variable for use in loops (whilenum etc) -\let_new:NN \int_eval:n \num_eval:n -\let_new:NN \int_eval:w \num_eval:w -\let_new:NN \int_eval_end: \num_eval_end: -\const_new:Nn \c_max_int {2147483647} -\def:Npn \int_pre_eval_one_arg:Nnn #1#2{\exp_args:No#1{\int_eval:w#2}} -\def:Npn \int_pre_eval_two_args:Nnn #1#2#3{ - \exp_args:Noo#1{\int_use:N\int_eval:w#2}{\int_use:N\int_eval:w#3} -} -\def_new:Npn \int_div_truncate:nn { - \int_pre_eval_two_args:Nnn\int_div_truncate_raw:nn -} -\def_new:Npn \int_div_truncate_raw:nn #1#2 { - \int_eval:w - \if_num:w \int_eval:w#1 = \c_zero - 0 - \else: - (#1 - \if_num:w \int_eval:w #1 < \c_zero - \if_num:w \int_eval:w#2 < \c_zero - -( #2 + - \else: - +( #2 - - \fi: - \else: - \if_num:w \int_eval:w #2 < \c_zero - +( #2 + - \else: - -( #2 - - \fi: - \fi: - 1)/2) - \fi: - /(#2) - \int_eval_end: -} -\def_new:Npn \int_div_round:nn { - \int_pre_eval_two_args:Nnn\int_div_round_raw:nn -} -\def_new:Npn \int_div_round_raw:nn #1#2 {\int_eval:n{#1/#2}} -\def_new:Npn \int_mod:nn {\int_pre_eval_two_args:Nnn\int_mod_raw:nn} -\def_new:Npn \int_mod_raw:nn #1#2 { - \int_eval:n{ #1 - \int_div_truncate_raw:nn {#1}{#2} * #2 } -} -\let_new:NN \int_compare:nNnTF \num_compare:nNnTF -\let_new:NN \int_compare:nNnT \num_compare:nNnT -\let_new:NN \int_compare:nNnF \num_compare:nNnF -\let_new:NN \int_max_of:nn \num_max_of:nn -\let_new:NN \int_min_of:nn \num_min_of:nn -\let_new:NN \int_abs:nn \num_abs:nn -\let_new:NN \int_compare_p:nNn \num_compare_p:nNn -\def_new:Npn \int_if_odd_p:n #1 { - \if_num_odd:w \int_eval:n{#1} - \c_true - \else: - \c_false - \fi: -} -\def_test_function_new:npn {int_if_odd:n}#1{\if_num_odd:w \int_eval:n{#1}} -\def_long_new:Npn \int_whiledo:nNnT #1#2#3#4{ - \int_compare:nNnT {#1}#2{#3}{#4 \int_whiledo:nNnT {#1}#2{#3}{#4}} -} -\def_long_new:Npn \int_whiledo:nNnF #1#2#3#4{ - \int_compare:nNnF {#1}#2{#3}{#4 \int_whiledo:nNnF {#1}#2{#3}{#4}} -} -\def_long_new:Npn \int_dowhile:nNnT #1#2#3#4{ - #4 \int_compare:nNnT {#1}#2{#3}{\int_dowhile:nNnT {#1}#2{#3}{#4}} -} -\def_long_new:Npn \int_dowhile:nNnF #1#2#3#4{ - #4 \int_compare:nNnF {#1}#2{#3}{\int_dowhile:nNnF {#1}#2{#3}{#4}} -} -\def_new:Npn \int_get_sign_and_digits:n #1{ - \int_get_sign_and_digits_aux:nNNN {#1} \c_true \c_true \c_true -} -\def_new:Npn \int_get_sign:n #1{ - \int_get_sign_and_digits_aux:nNNN {#1} \c_true \c_true \c_false -} -\def_new:Npn \int_get_digits:n #1{ - \int_get_sign_and_digits_aux:nNNN {#1} \c_true \c_false \c_true +\cs_set_nopar:Npn \int_pre_eval_one_arg:Nn #1#2{ + \exp_args:Nf#1{\intexpr_eval:n{#2}}} +\cs_set_nopar:Npn \int_pre_eval_two_args:Nnn #1#2#3{ + \exp_args:Nff#1{\intexpr_eval:n{#2}}{\intexpr_eval:n{#3}} +} +\cs_new_nopar:Npn \int_const:Nn #1#2 { + \intexpr_compare:nNnTF {#2} > \c_minus_one { + \intexpr_compare:nNnTF {#2} > \c_max_register_num { + \int_new:N #1 \int_set:Nn #1{#2} + } { + \chk_if_free_cs:N #1 \tex_mathchardef:D #1 = \intexpr_eval:n{#2} + } + } { + \int_new:N #1 \int_set:Nn #1{#2} + } } -\def_new:Npn \int_get_sign_and_digits_aux:nNNN #1#2#3#4{ - \tlist_if_head_eq_charcode:fNTF {#1} - + %% \tex_countdef:D \c_minus_one = 10 \scan_stop: + %% \c_minus_one = -1 \scan_stop: %% in l3basics +\int_const:Nn \c_one {1} +\int_const:Nn \c_two {2} +\int_const:Nn \c_three {3} +\int_const:Nn \c_four {4} +\int_const:Nn \c_five {5} +\int_const:Nn \c_six {6} +\int_const:Nn \c_seven {7} +\int_const:Nn \c_eight {8} +\int_const:Nn \c_nine {9} +\int_const:Nn \c_ten {10} +\int_const:Nn \c_eleven {11} +\int_const:Nn \c_twelve {12} +\int_const:Nn \c_thirteen {13} +\int_const:Nn \c_fourteen {14} +\int_const:Nn \c_fifteen {15} + %% \tex_chardef:D \c_sixteen = 16\scan_stop: %% in l3basics +\int_const:Nn \c_thirty_two {32} +\int_const:Nn \c_hundred_one {101} +\int_const:Nn \c_twohundred_fifty_five{255} +\int_const:Nn \c_twohundred_fifty_six {256} +\int_const:Nn \c_thousand {1000} +\int_const:Nn \c_ten_thousand {10000} +\int_const:Nn \c_ten_thousand_one {10001} +\int_const:Nn \c_ten_thousand_two {10002} +\int_const:Nn \c_ten_thousand_three {10003} +\int_const:Nn \c_ten_thousand_four {10004} +\int_const:Nn \c_twenty_thousand {20000} +\int_const:Nn \c_max_int {2147483647} +\cs_new_nopar:Npn \int_get_sign_and_digits:n #1{ + \int_get_sign_and_digits_aux:nNNN {#1} \c_true_bool \c_true_bool \c_true_bool +} +\cs_new_nopar:Npn \int_get_sign:n #1{ + \int_get_sign_and_digits_aux:nNNN {#1} \c_true_bool \c_true_bool \c_false_bool +} +\cs_new_nopar:Npn \int_get_digits:n #1{ + \int_get_sign_and_digits_aux:nNNN {#1} \c_true_bool \c_false_bool \c_true_bool +} +\cs_new_nopar:Npn \int_get_sign_and_digits_aux:nNNN #1#2#3#4{ + \tl_if_head_eq_charcode:fNTF {#1} - { \bool_if:NTF #2 - { \int_get_sign_and_digits_aux:oNNN {\use_none:n #1} \c_false #3#4 } - { \int_get_sign_and_digits_aux:oNNN {\use_none:n #1} \c_true #3#4 } + { \int_get_sign_and_digits_aux:oNNN {\use_none:n #1} \c_false_bool #3#4 } + { \int_get_sign_and_digits_aux:oNNN {\use_none:n #1} \c_true_bool #3#4 } } { - \tlist_if_head_eq_charcode:fNTF {#1} + + \tl_if_head_eq_charcode:fNTF {#1} + { \int_get_sign_and_digits_aux:oNNN {\use_none:n #1} #2#3#4} { - \bool_double_if:NNnnnn #3#4 - { \bool_if:NF #2 - #1 } - { \bool_if:NF #2 - } - { #1 } { } + \bool_if:NT #3 { \bool_if:NF #2 - } + \bool_if:NT #4 {#1} } } } -\def_new:Npn \int_get_sign_and_digits_aux:oNNN{ - \exp_args:No\int_get_sign_and_digits_aux:nNNN -} -\def:Npn \int_convert_from_base_ten:nn#1#2{ - \num_compare:nNnTF {#1}<\c_zero +\cs_generate_variant:Nn \int_get_sign_and_digits_aux:nNNN {oNNN} +\cs_set_nopar:Npn \int_convert_from_base_ten:nn#1#2{ + \intexpr_compare:nNnTF {#1}<\c_zero { - - \int_convert_from_base_ten_aux:non {} - { \int_use:N \int_eval:n {-#1} } + - \int_convert_from_base_ten_aux:nfn {} + { \intexpr_eval:n {-#1} } } { - \int_convert_from_base_ten_aux:non {} - { \int_use:N \int_eval:n {#1} } + \int_convert_from_base_ten_aux:nfn {} + { \intexpr_eval:n {#1} } } {#2} } -\def_new:Npn \int_convert_from_base_ten_aux:nnn#1#2#3{ - \num_compare:nNnTF {#2}<{#3} +\cs_new_nopar:Npn \int_convert_from_base_ten_aux:nnn#1#2#3{ + \intexpr_compare:nNnTF {#2}<{#3} { \int_convert_number_to_letter:n{#2} #1 } { - \int_convert_from_base_ten_aux:fon + \int_convert_from_base_ten_aux:ffn { - \int_convert_number_to_letter:n {\int_use:N\int_mod_raw:nn {#2}{#3}} + \int_convert_number_to_letter:n {\intexpr_mod:nn {#2}{#3}} #1 } - {\int_use:N \int_div_truncate_raw:nn{#2}{#3}} + { \intexpr_div_truncate:nn{#2}{#3}} {#3} } } -\def:Npn \int_convert_from_base_ten_aux:non{ - \exp_args:Nno\int_convert_from_base_ten_aux:nnn -} -\def:Npn \int_convert_from_base_ten_aux:fon{ - \exp_args:Nfo\int_convert_from_base_ten_aux:nnn -} -\def:Npn \int_convert_number_to_letter:n #1{ \if_case:w \int_eval:w - #1-10\scan_stop: \exp_after:NN A \or: \exp_after:NN B \or: - \exp_after:NN C \or: \exp_after:NN D \or: \exp_after:NN E \or: - \exp_after:NN F \or: \exp_after:NN G \or: \exp_after:NN H \or: - \exp_after:NN I \or: \exp_after:NN J \or: \exp_after:NN K \or: - \exp_after:NN L \or: \exp_after:NN M \or: \exp_after:NN N \or: - \exp_after:NN O \or: \exp_after:NN P \or: \exp_after:NN Q \or: - \exp_after:NN R \or: \exp_after:NN S \or: \exp_after:NN T \or: - \exp_after:NN U \or: \exp_after:NN V \or: \exp_after:NN W \or: - \exp_after:NN X \or: \exp_after:NN Y \or: \exp_after:NN Z \else: - \use_arg_i_after_fi:nw{ #1 }\fi: } -\def:Npn \int_convert_to_base_ten:nn #1#2 { - \int_use:N\int_eval:n{ +\cs_generate_variant:Nn \int_convert_from_base_ten_aux:nnn {nfn} +\cs_generate_variant:Nn \int_convert_from_base_ten_aux:nnn {ffn} +\cs_set_nopar:Npn \int_convert_number_to_letter:n #1{ + \if_case:w \intexpr_eval:w #1-10\intexpr_eval_end: + \exp_after:wN A \or: \exp_after:wN B \or: + \exp_after:wN C \or: \exp_after:wN D \or: \exp_after:wN E \or: + \exp_after:wN F \or: \exp_after:wN G \or: \exp_after:wN H \or: + \exp_after:wN I \or: \exp_after:wN J \or: \exp_after:wN K \or: + \exp_after:wN L \or: \exp_after:wN M \or: \exp_after:wN N \or: + \exp_after:wN O \or: \exp_after:wN P \or: \exp_after:wN Q \or: + \exp_after:wN R \or: \exp_after:wN S \or: \exp_after:wN T \or: + \exp_after:wN U \or: \exp_after:wN V \or: \exp_after:wN W \or: + \exp_after:wN X \or: \exp_after:wN Y \or: \exp_after:wN Z \else: + \use_i_after_fi:nw{ #1 }\fi: } +\cs_set_nopar:Npn \int_convert_to_base_ten:nn #1#2 { + \intexpr_eval:n{ \int_get_sign:n{#1} \exp_args:Nf\int_convert_to_base_ten_aux:nn {\int_get_digits:n{#1}}{#2} } } -\def_new:Npn \int_convert_to_base_ten_aux:nn #1#2{ +\cs_new_nopar:Npn \int_convert_to_base_ten_aux:nn #1#2{ \int_convert_to_base_ten_auxi:nnN {0}{#2} #1 \q_nil } -\def_new:Npn \int_convert_to_base_ten_auxi:nnN#1#2#3{ +\cs_new_nopar:Npn \int_convert_to_base_ten_auxi:nnN#1#2#3{ \quark_if_nil:NTF #3 {#1} - {\exp_args:No\int_convert_to_base_ten_auxi:nnN - {\int_use:N \int_eval:n{ #1*#2+\int_convert_letter_to_number:N #3} } + {\exp_args:Nf\int_convert_to_base_ten_auxi:nnN + {\intexpr_eval:n{ #1*#2+\int_convert_letter_to_number:N #3} } {#2} } } -\def:Npn \int_convert_letter_to_number:N #1{ - \int_compare:nNnTF{`#1}<{58}{#1} +\cs_set_nopar:Npn \int_convert_letter_to_number:N #1{ + \intexpr_compare:nNnTF{`#1}<{58}{#1} { - \int_eval:n{ `#1 - - \if:w\int_compare_p:nNn{`#1}<{91} - 55 - \else: - 87 - \fi: + \intexpr_eval:n{ `#1 - + \intexpr_compare:nNnTF{`#1}<{91}{ 55 }{ 87 } } } } diff --git a/Master/texmf-dist/tex/latex/expl3/l3intexpr.sty b/Master/texmf-dist/tex/latex/expl3/l3intexpr.sty new file mode 100644 index 00000000000..91d7d2daeb0 --- /dev/null +++ b/Master/texmf-dist/tex/latex/expl3/l3intexpr.sty @@ -0,0 +1,203 @@ +%% +%% This is file `l3intexpr.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% l3intexpr.dtx (with options: `package,trace') +%% +%% +%% EXPERIMENTAL CODE +%% +%% Do not distribute this file without also distributing the +%% source files specified above. +%% +%% Do not distribute a modified version of this file. +%% +%% +%% File: l3intexpr.dtx Copyright (C) 2009 LaTeX3 project +%% +%% It may be distributed and/or modified under the conditions of the +%% LaTeX Project Public License (LPPL), either version 1.3c of this +%% license or (at your option) any later version. The latest version +%% of this license is in the file +%% +%% http://www.latex-project.org/lppl.txt +%% +%% This file is part of the ``expl3 bundle'' (The Work in LPPL) +%% and all files in that bundle must be distributed together. +%% +%% The released version of this bundle is available from CTAN. +%% +%% ----------------------------------------------------------------------- +%% +%% The development version of the bundle can be found at +%% +%% http://www.latex-project.org/svnroot/experimental/trunk/ +%% +%% for those people who are interested. +%% +%%%%%%%%%%% +%% NOTE: %% +%%%%%%%%%%% +%% +%% Snapshots taken from the repository represent work in progress and may +%% not work or may contain conflicting material! We therefore ask +%% people _not_ to put them into distributions, archives, etc. without +%% prior consultation with the LaTeX Project Team. +%% +%% ----------------------------------------------------------------------- +\RequirePackage{l3names} +\GetIdInfo$Id: l3intexpr.dtx 1086 2009-03-20 19:29:35Z morten $ + {L3 Integer Expressions} +\ProvidesExplPackage + {\filename}{\filedate}{\fileversion}{\filedescription} +\package_check_loaded_expl: +\cs_set_eq:NN \intexpr_value:w \tex_number:D +\cs_set_eq:NN \intexpr_eval:w \etex_numexpr:D +\cs_set_protected:Npn \intexpr_eval_end: {\tex_relax:D} +\cs_set_eq:NN \if_intexpr_compare:w \tex_ifnum:D +\cs_set_eq:NN \if_intexpr_odd:w \tex_ifodd:D +\cs_set_eq:NN \if_intexpr_case:w \tex_ifcase:D +\cs_set:Npn \intexpr_eval:n #1{ + \intexpr_value:w \intexpr_eval:w #1\intexpr_eval_end: +} +\prg_set_conditional:Npnn \intexpr_compare:n #1{p,TF,T,F}{ + \exp_after:wN \intexpr_compare_auxi:w \intexpr_value:w + \intexpr_eval:w #1\q_stop +} +\cs_set:Npn \intexpr_compare_auxi:w #1#2\q_stop{ + \exp_after:wN \intexpr_compare_auxii:w \tex_romannumeral:D + \if:w #1- \else: -\fi: #1#2 \q_stop #1#2 \q_nil +} +\cs_set:Npn \intexpr_compare_auxii:w #1#2#3\q_stop{ + \use:c{ + intexpr_compare_ + #1 \if_meaning:w =#2 = \fi: + :w} +} +\cs_set:cpn {intexpr_compare_=:w} #1=#2\q_nil{ + \if_intexpr_compare:w #1=\intexpr_eval:w #2 \intexpr_eval_end: + \prg_return_true: \else: \prg_return_false: \fi: +} +\cs_set:cpn {intexpr_compare_==:w} #1==#2\q_nil{ + \if_intexpr_compare:w #1=\intexpr_eval:w #2 \intexpr_eval_end: + \prg_return_true: \else: \prg_return_false: \fi: +} +\cs_set:cpn {intexpr_compare_!=:w} #1!=#2\q_nil{ + \if_intexpr_compare:w #1=\intexpr_eval:w #2 \intexpr_eval_end: + \prg_return_false: \else: \prg_return_true: \fi: +} +\cs_set:cpn {intexpr_compare_<:w} #1<#2\q_nil{ + \if_intexpr_compare:w #1<\intexpr_eval:w #2 \intexpr_eval_end: + \prg_return_true: \else: \prg_return_false: \fi: +} +\cs_set:cpn {intexpr_compare_>:w} #1>#2\q_nil{ + \if_intexpr_compare:w #1>\intexpr_eval:w #2 \intexpr_eval_end: + \prg_return_true: \else: \prg_return_false: \fi: +} +\cs_set:cpn {intexpr_compare_<=:w} #1<=#2\q_nil{ + \if_intexpr_compare:w #1<\intexpr_eval:w #2 +\c_one \intexpr_eval_end: + \prg_return_true: \else: \prg_return_false: \fi: +} +\cs_set:cpn {intexpr_compare_>=:w} #1>=#2\q_nil{ + \if_intexpr_compare:w #1>\intexpr_eval:w #2 - \c_one \intexpr_eval_end: + \prg_return_true: \else: \prg_return_false: \fi: +} +\prg_set_conditional:Npnn \intexpr_compare:nNn #1#2#3{p,TF,T,F}{ + \if_intexpr_compare:w \intexpr_eval:w #1 #2 \intexpr_eval:w #3 \intexpr_eval_end: + \prg_return_true: \else: \prg_return_false: \fi: +} +\cs_set:Npn \intexpr_abs:n #1{ + \intexpr_value:w + \if_intexpr_compare:w \intexpr_eval:w #1<\c_zero + - + \fi: + \intexpr_eval:w #1\intexpr_eval_end: +} +\cs_set:Npn \intexpr_max:nn #1#2{ + \intexpr_value:w \intexpr_eval:w + \if_intexpr_compare:w + \intexpr_eval:w #1>\intexpr_eval:w #2\intexpr_eval_end: + #1 + \else: + #2 + \fi: + \intexpr_eval_end: +} +\cs_set:Npn \intexpr_min:nn #1#2{ + \intexpr_value:w \intexpr_eval:w + \if_intexpr_compare:w + \intexpr_eval:w #1<\intexpr_eval:w #2\intexpr_eval_end: + #1 + \else: + #2 + \fi: + \intexpr_eval_end: +} +\cs_set:Npn \intexpr_div_truncate:nn #1#2 { + \intexpr_value:w \intexpr_eval:w + \if_intexpr_compare:w \intexpr_eval:w #1 = \c_zero + 0 + \else: + (#1 + \if_intexpr_compare:w \intexpr_eval:w #1 < \c_zero + \if_intexpr_compare:w \intexpr_eval:w #2 < \c_zero + -( #2 + + \else: + +( #2 - + \fi: + \else: + \if_intexpr_compare:w \intexpr_eval:w #2 < \c_zero + +( #2 + + \else: + -( #2 - + \fi: + \fi: + 1)/2) + \fi: + /(#2) + \intexpr_eval_end: +} +\cs_set:Npn \intexpr_div_round:nn #1#2 {\intexpr_eval:n{(#1)/(#2)}} +\cs_set:Npn \intexpr_mod:nn #1#2 { + \intexpr_value:w + \intexpr_eval:w + #1 - \intexpr_div_truncate:nn {#1}{#2} * (#2) + \intexpr_eval_end: +} +\prg_set_conditional:Npnn \intexpr_if_odd:n #1 {p,TF,T,F} { + \if_intexpr_odd:w \intexpr_eval:w #1\intexpr_eval_end: + \prg_return_true: \else: \prg_return_false: \fi: +} +\prg_set_conditional:Npnn \intexpr_if_even:n #1 {p,TF,T,F} { + \if_intexpr_odd:w \intexpr_eval:w #1\intexpr_eval_end: + \prg_return_false: \else: \prg_return_true: \fi: +} +\cs_set:Npn \intexpr_while_do:nn #1#2{ + \intexpr_compare:nT {#1}{#2 \intexpr_while_do:nn {#1}{#2}} +} +\cs_set:Npn \intexpr_until_do:nn #1#2{ + \intexpr_compare:nF {#1}{#2 \intexpr_until_do:nn {#1}{#2}} +} +\cs_set:Npn \intexpr_do_while:nn #1#2{ + #2 \intexpr_compare:nT {#1}{\intexpr_do_while:nNnn {#1}{#2}} +} +\cs_set:Npn \intexpr_do_until:nn #1#2{ + #2 \intexpr_compare:nF {#1}{\intexpr_do_until:nn {#1}{#2}} +} +\cs_set:Npn \intexpr_while_do:nNnn #1#2#3#4{ + \intexpr_compare:nNnT {#1}#2{#3}{#4 \intexpr_while_do:nNnn {#1}#2{#3}{#4}} +} +\cs_set:Npn \intexpr_until_do:nNnn #1#2#3#4{ + \intexpr_compare:nNnF {#1}#2{#3}{#4 \intexpr_until_do:nNnn {#1}#2{#3}{#4}} +} +\cs_set:Npn \intexpr_do_while:nNnn #1#2#3#4{ + #4 \intexpr_compare:nNnT {#1}#2{#3}{\intexpr_do_while:nNnn {#1}#2{#3}{#4}} +} +\cs_set:Npn \intexpr_do_until:nNnn #1#2#3#4{ + #4 \intexpr_compare:nNnF {#1}#2{#3}{\intexpr_do_until:nNnn {#1}#2{#3}{#4}} +} +%% +%% +%% End of file `l3intexpr.sty'. diff --git a/Master/texmf-dist/tex/latex/expl3/l3io.sty b/Master/texmf-dist/tex/latex/expl3/l3io.sty index 608c6b7c624..5ea97d6b61a 100644 --- a/Master/texmf-dist/tex/latex/expl3/l3io.sty +++ b/Master/texmf-dist/tex/latex/expl3/l3io.sty @@ -15,7 +15,7 @@ %% Do not distribute a modified version of this file. %% %% -%% File: l3io.dtx Copyright (C) 1990-2006 LaTeX3 project +%% File: l3io.dtx Copyright (C) 1990-2009 LaTeX3 project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this @@ -33,7 +33,7 @@ %% %% The development version of the bundle can be found at %% -%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/ +%% http://www.latex-project.org/svnroot/experimental/trunk/ %% %% for those people who are interested. %% @@ -48,59 +48,73 @@ %% %% ----------------------------------------------------------------------- \RequirePackage{l3names} -\GetIdInfo$Id: l3io.dtx 621 2007-09-01 20:14:19Z morten $ +\GetIdInfo$Id: l3io.dtx 1369 2009-05-31 21:36:35Z joseph $ {L3 Experimental i/o module} \ProvidesExplPackage {\filename}{\filedate}{\fileversion}{\filedescription} -\RequirePackage{l3toks}\par -\let:NN \iow_new:N \newwrite -\def_new:Npn \iow_new:c {\exp_args:Nc \iow_new:N} -\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} -\def_new:Npn \iow_close:N {\tex_immediate:D\tex_closeout:D} -\let_new:NN \c_io_term_stream \c_sixteen -\let_new:NN \c_iow_log_stream \c_minus_one -\def_new:Npn \iow_expanded:Nn {\tex_immediate:D\iow_deferred_expanded:Nn} -\def_new:Npn \iow_unexpanded:Nn #1#2{ - \iow_expanded:Nn #1{\exp_not:n{#2}}} -\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} - -\def_new:Npn \iow_unexpanded_term:n {\iow_unexpanded:Nn \c_io_term_stream} -\def_new:Npn \iow_unexpanded_if_avail:Nn #1{ - \cs_free:NTF #1\use_none:n {\iow_unexpanded:Nn #1}} -\def_new:Npn \iow_unexpanded_if_avail:cn { - \exp_args:Nc \iow_unexpanded_if_avail:Nn } -\def_new:Npn \iow_long_expanded_aux:w #1#2#3{ - \group_begin:\tex_newlinechar:D`\ #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} -\let:NN \iow_deferred_expanded:Nn \tex_write:D -\def_new:Npn \iow_deferred_unexpanded:Nn #1#2{ - \iow_deferred_expanded:Nn{\exp_not:n{#2}} +\package_check_loaded_expl: +\cs_set_eq:NN \iow_new:N \newwrite +\cs_generate_variant:Nn \iow_new:N {c} +\cs_new_nopar:Npn \iow_open:Nn #1#2 { + \iow_close:N #1 + \tex_immediate:D \tex_openout:D #1#2 \scan_stop: +} +\cs_generate_variant:Nn \iow_open:Nn {c} +\cs_new_nopar:Npn \iow_close:N { \tex_immediate:D \tex_closeout:D } +\cs_new_eq:NN \c_iow_term_stream \c_sixteen +\cs_new_eq:NN \c_ior_term_stream \c_sixteen +\cs_new_eq:NN \c_iow_log_stream \c_minus_one +\cs_new_eq:NN \c_ior_log_stream \c_minus_one +\cs_new_nopar:Npn \iow_now:Nx { \tex_immediate:D \iow_shipout_x:Nn } +\cs_new_nopar:Npn \iow_now:Nn #1#2 { + \iow_now:Nx #1 { \exp_not:n {#2} } +} +\cs_set_nopar:Npn \iow_log:x { \iow_now:Nx \c_iow_log_stream } +\cs_new_nopar:Npn \iow_log:n { \iow_now:Nn \c_iow_log_stream } +\cs_set_nopar:Npn \iow_term:x { \iow_now:Nx \c_iow_term_stream } +\cs_new_nopar:Npn \iow_term:n { \iow_now:Nn \c_iow_term_stream } +\cs_new_nopar:Npn \iow_now_when_avail:Nn #1 { + \cs_if_free:NTF #1 {\use_none:n} {\iow_now:Nn #1} +} +\cs_generate_variant:Nn \iow_now_when_avail:Nn {c} +\cs_new_nopar:Npn \iow_now_buffer_safe_aux:w #1#2#3 { + \group_begin: \tex_newlinechar:D`\ #1#2{#3} \group_end: +} +\cs_new_nopar:Npn \iow_now_buffer_safe:Nx { + \iow_now_buffer_safe_aux:w \iow_now:Nx +} +\cs_new_nopar:Npn \iow_now_buffer_safe:Nn { + \iow_now_buffer_safe_aux:w \iow_now:Nn +} +\cs_set_eq:NN \iow_shipout_x:Nn \tex_write:D +\cs_generate_variant:Nn \iow_shipout_x:Nn {Nx} +\cs_new_nopar:Npn \iow_shipout:Nn #1#2{ + \iow_shipout_x:Nn #1 { \exp_not:n {#2} } +} +\cs_generate_variant:Nn \iow_shipout:Nn {Nx} +\cs_new_nopar:Npn \iow_newline: {^^J} +\cs_new_nopar:Npn \iow_space: {~} +\cs_new:Nn \iow_char:N { \cs_to_str:N #1 } +\tl_new:Nx \c_iow_comment_char {\cs_to_str:N\%} +\tl_new:Nx \c_iow_lbrace_char{\cs_to_str:N\{} +\tl_new:Nx \c_iow_rbrace_char{\cs_to_str:N\}} +\cs_set_eq:NN \ior_new:N \newread +\cs_set_eq:NN \ior_close:N \tex_closein:D +\cs_new_nopar:Npn \ior_open:Nn #1#2 { + \ior_close:N #1 \scan_stop: + \tex_openin:D #1#2 \scan_stop: +} +\cs_new_eq:NN \if_eof:w \tex_ifeof:D +\prg_new_conditional:Nnn \ior_if_eof:N {p,TF,T,F} { + \tex_ifeof:D #1 \prg_return_true: \else: \prg_return_false: \fi: +} +\cs_new_nopar:Npn \ior_to:NN #1#2 { + \tex_read:D #1 to #2 +} +\cs_new_nopar:Npn \ior_gto:NN { + \pref_global:D + \ior_to:NN } -%% Old implementation: -\def_new:Npn \iow_newline: {^^J} -\tlp_new:Nx \c_iow_comment_char {\cs_to_str:N\%} -\tlp_new:Nx \c_iow_lbrace_char{\cs_to_str:N\{} -\tlp_new:Nx \c_iow_rbrace_char{\cs_to_str:N\}} -\let:NN \ior_new:N \newread -\let:NN \ior_close:N \tex_closein:D -\def_new:Npn \ior_open:Nn #1#2{\ior_close:N #1\scan_stop: - \tex_openin:D#1#2\scan_stop:} -\def_new:Npn \ior_eof:NTF #1{\if_eof:w#1 - \exp_after:NN\use_arg_i:nn \else: - \exp_after:NN\use_arg_ii:nn \fi:} -\let:NN \if_eof:w \tex_ifeof:D -\def_new:Npn \ior_eof:NF #1{\if_eof:w#1 - \exp_after:NN \use_none:nn \fi: \use_arg_i:n} - \def_new:Npn \ior_to:NN #1{\tex_read:D#1to} -\def_new:Npn \ior_gto:NN { - \pref_global:D - \ior_to:NN} %% %% %% End of file `l3io.sty'. diff --git a/Master/texmf-dist/tex/latex/expl3/l3keyval.sty b/Master/texmf-dist/tex/latex/expl3/l3keyval.sty index 683d121e3aa..d74b9ef62be 100644 --- a/Master/texmf-dist/tex/latex/expl3/l3keyval.sty +++ b/Master/texmf-dist/tex/latex/expl3/l3keyval.sty @@ -15,7 +15,7 @@ %% Do not distribute a modified version of this file. %% %% -%% File: l3keyval.dtx Copyright (C) 2006 LaTeX3 project +%% File: l3keyval.dtx Copyright (C) 2006-2009 LaTeX3 project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this @@ -33,7 +33,7 @@ %% %% The development version of the bundle can be found at %% -%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/ +%% http://www.latex-project.org/svnroot/experimental/trunk/ %% %% for those people who are interested. %% @@ -48,17 +48,14 @@ %% %% ----------------------------------------------------------------------- \RequirePackage{l3names} -\GetIdInfo$Id: l3keyval.dtx 621 2007-09-01 20:14:19Z morten $ +\GetIdInfo$Id: l3keyval.dtx 1362 2009-05-28 20:19:21Z joseph $ {L3 Experimental keyval processing} \ProvidesExplPackage {\filename}{\filedate}{\fileversion}{\filedescription} -\RequirePackage{l3quark} -\RequirePackage{l3toks} -\RequirePackage{l3int} -\RequirePackage{l3token} -\tlp_new:Nn\l_KV_tmpa_tlp{} -\tlp_new:Nn\l_KV_tmpb_tlp{} -\tlp_new:Nn \c_KV_single_equal_sign_tlp{=} +\package_check_loaded_expl: +\tl_new:N \l_KV_tmpa_tl +\tl_new:N \l_KV_tmpb_tl +\tl_new:Nn \c_KV_single_equal_sign_tl{=} \toks_new:N \l_KV_parse_toks \toks_new:N \l_KV_currkey_toks \toks_new:N \l_KV_currval_toks @@ -69,84 +66,85 @@ \char_set_catcode:nn{`\,}{13} \char_set_lccode:nn{`\8}{`\=} \char_set_lccode:nn{`\9}{`\,} -\tlist_to_lowercase:n{\group_end: -\def_new:Npn \KV_sanitize_outerlevel_active_equals:N #1{ - \tlp_replace_all_in:Nnn #1 = 8 +\tl_to_lowercase:n{\group_end: +\cs_new_nopar:Npn \KV_sanitize_outerlevel_active_equals:N #1{ + \tl_replace_all_in:Nnn #1 = 8 } -\def_new:Npn \KV_sanitize_outerlevel_active_commas:N #1{ - \tlp_replace_all_in:Nnn #1 , 9 +\cs_new_nopar:Npn \KV_sanitize_outerlevel_active_commas:N #1{ + \tl_replace_all_in:Nnn #1 , 9 } } \group_begin: \char_set_catcode:nn{`\Q}{3} -\gdef_long_new:Npn\KV_remove_surrounding_spaces:nw#1#2\q_nil{ +\cs_gnew:Npn\KV_remove_surrounding_spaces:nw#1#2\q_nil{ #1{\KV_remove_surrounding_spaces_auxi:w \exp_not:N#2Q~Q} } -\gdef_long_new:Npn\KV_remove_surrounding_spaces_auxi:w#1~Q{ +\cs_gnew:Npn\KV_remove_surrounding_spaces_auxi:w#1~Q{ \KV_remove_surrounding_spaces_auxii:w #1 Q } -\gdef_long_new:Npn\KV_remove_surrounding_spaces_auxii:w#1Q#2{#1} -\gdef_long_new:Npn\KV_add_value_element:w\q_stop#1\q_nil{ +\cs_gnew:Npn\KV_remove_surrounding_spaces_auxii:w#1Q#2{#1} +\cs_gnew:Npn\KV_add_value_element:w\q_stop#1\q_nil{ \toks_set:Nf\l_KV_currval_toks { \KV_remove_surrounding_spaces_auxi:w \exp_not:N#1Q~Q } \toks_put_right:No\l_KV_parse_toks{ - \exp_after:NN {\toks_use:N \l_KV_currval_toks} + \exp_after:wN {\toks_use:N \l_KV_currval_toks} } } -\gdef_long_new:Npn\KV_set_key_element:w#1\q_nil{ +\cs_gnew:Npn\KV_set_key_element:w#1\q_nil{ \toks_set:Nf\l_KV_currkey_toks { - \exp_after:NN\KV_remove_surrounding_spaces_auxi:w - \exp_after:NN\exp_not:N\use_none:n #1Q~Q + \exp_last_unbraced:NNo \KV_remove_surrounding_spaces_auxi:w + \exp_not:N \use_none:n #1Q~Q } \bool_if:NT \l_KV_remove_one_level_of_braces_bool { - \toks_set:Nd \l_KV_currkey_toks{ - \exp_after:NN \KV_add_element_aux:w - \toks_use:N \l_KV_currkey_toks \q_nil + \exp_args:NNo \toks_set:No \l_KV_currkey_toks { + \exp_after:wN \KV_add_element_aux:w + \toks_use:N \l_KV_currkey_toks \q_nil } } } \group_end: -\def_long_new:Npn \KV_add_element_aux:w#1\q_nil{#1} -\def_long_new:Npn \KV_parse_sanitize_aux:n #1{ +\cs_new:Npn \KV_add_element_aux:w#1\q_nil{#1} +\cs_new:Npn \KV_parse_sanitize_aux:n #1 { \group_begin: - \toks_clear:N \l_KV_parse_toks - \tlp_set:Nx\l_KV_tmpa_tlp{\exp_not:n{#1}} - \KV_sanitize_outerlevel_active_equals:N\l_KV_tmpa_tlp - \KV_sanitize_outerlevel_active_commas:N\l_KV_tmpa_tlp - \exp_after:NN \KV_parse_elt:w \exp_after:NN\q_no_value \l_KV_tmpa_tlp,\q_nil, - \exp_after:NN\group_end: - \toks_use:N \l_KV_parse_toks -} -\def_long_new:Npn \KV_parse_no_sanitize_aux:n #1{ + \toks_clear:N \l_KV_parse_toks + \tl_set:Nx \l_KV_tmpa_tl { \exp_not:n {#1} } + \KV_sanitize_outerlevel_active_equals:N \l_KV_tmpa_tl + \KV_sanitize_outerlevel_active_commas:N \l_KV_tmpa_tl + \exp_last_unbraced:NNV \KV_parse_elt:w \q_no_value + \l_KV_tmpa_tl , \q_nil , + \exp_last_unbraced:NV \group_end: + \l_KV_parse_toks +} +\cs_new:Npn \KV_parse_no_sanitize_aux:n #1{ \group_begin: - \toks_clear:N \l_KV_parse_toks - \KV_parse_elt:w \q_no_value #1,\q_nil, - \exp_after:NN\group_end: - \toks_use:N \l_KV_parse_toks + \toks_clear:N \l_KV_parse_toks + \KV_parse_elt:w \q_no_value #1 , \q_nil , + \exp_last_unbraced:NV \group_end: + \l_KV_parse_toks } -\def_long:Npn \KV_parse_elt:w #1,{ - \tlist_if_blank:oTF{\use_none:n #1} +\cs_set:Npn \KV_parse_elt:w #1,{ + \tl_if_blank:oTF{\use_none:n #1} { \KV_parse_elt:w \q_no_value } { - \quark_if_nil:oF {\use_arg_ii:nn #1 } + \quark_if_nil:oF {\use_ii:nn #1 } { \KV_split_key_value_current:w #1==\q_nil \KV_parse_elt:w \q_no_value } } } -\let_new:NN \KV_split_key_value_current:w \ERROR -\def_long_new:Npn \KV_split_key_value_space_removal:w #1 = #2\q_nil{ +\cs_new:Npn \KV_split_key_value_current:w {\ERROR} +\cs_new:Npn \KV_split_key_value_space_removal:w #1 = #2\q_nil{ \KV_set_key_element:w#1\q_nil - \tlp_set:Nx\l_KV_tmpa_tlp{\exp_not:n{#2}} - \tlp_if_eq:NNTF\l_KV_tmpa_tlp\c_KV_single_equal_sign_tlp + \tl_set:Nx\l_KV_tmpa_tl{\exp_not:n{#2}} + \tl_if_eq:NNTF\l_KV_tmpa_tl\c_KV_single_equal_sign_tl { \toks_put_right:No\l_KV_parse_toks{ - \exp_after:NN \KV_key_no_value_elt:n - \exp_after:NN {\toks_use:N\l_KV_currkey_toks} + \exp_after:wN \KV_key_no_value_elt:n + \exp_after:wN {\toks_use:N\l_KV_currkey_toks} } } { @@ -155,63 +153,63 @@ {\ERROR} } } -\def_long_new:Npn +\cs_new:Npn \KV_split_key_value_space_removal_detect_error:wTF#1=#2#3\q_nil{ - \tlist_if_head_eq_meaning:nNTF{#3}\q_no_value + \tl_if_head_eq_meaning:nNTF{#3}\q_no_value } -\def_long_new:Npn \KV_val_preserve_braces:NnN #1#2#3{{#2}} -\def_long_new:Npn\KV_split_key_value_space_removal_aux:w #1=={ - \tlp_set:Nx\l_KV_tmpa_tlp{\exp_not:o{\use_none:nnn#1\q_nil\q_nil}} +\cs_new:Npn \KV_val_preserve_braces:NnN #1#2#3{{#2}} +\cs_new:Npn\KV_split_key_value_space_removal_aux:w #1=={ + \tl_set:Nx\l_KV_tmpa_tl{\exp_not:o{\use_none:nnn#1\q_nil\q_nil}} \toks_put_right:No\l_KV_parse_toks{ - \exp_after:NN \KV_key_value_elt:nn - \exp_after:NN {\toks_use:N\l_KV_currkey_toks} + \exp_after:wN \KV_key_value_elt:nn + \exp_after:wN {\toks_use:N\l_KV_currkey_toks} } - \tlp_if_empty:NTF\l_KV_tmpa_tlp + \tl_if_empty:NTF\l_KV_tmpa_tl { \toks_put_right:Nn\l_KV_parse_toks{{}} } { - \quark_if_nil:NTF\l_KV_tmpa_tlp + \quark_if_nil:NTF\l_KV_tmpa_tl { \bool_if:NTF \l_KV_remove_one_level_of_braces_bool { \toks_put_right:No\l_KV_parse_toks{ - \exp_after:NN{\use_arg_ii:nnn #1\q_nil} + \exp_after:wN{\use_ii:nnn #1\q_nil} } } { \toks_put_right:No\l_KV_parse_toks{ - \exp_after:NN{\KV_val_preserve_braces:NnN #1\q_nil} + \exp_after:wN{\KV_val_preserve_braces:NnN #1\q_nil} } } } { \KV_add_value_element:w #1\q_nil } } } -\def_long_new:Npn \KV_split_key_value_no_space_removal:w #1#2=#3=#4\q_nil{ - \tlp_set:Nn\l_KV_tmpa_tlp{#4} - \tlp_if_empty:NTF \l_KV_tmpa_tlp +\cs_new:Npn \KV_split_key_value_no_space_removal:w #1#2=#3=#4\q_nil{ + \tl_set:Nn\l_KV_tmpa_tl{#4} + \tl_if_empty:NTF \l_KV_tmpa_tl { \toks_put_right:Nn\l_KV_parse_toks{\KV_key_no_value_elt:n{#2}} } { - \tlp_if_eq:NNTF\c_KV_single_equal_sign_tlp\l_KV_tmpa_tlp + \tl_if_eq:NNTF\c_KV_single_equal_sign_tl\l_KV_tmpa_tl { \toks_put_right:Nn\l_KV_parse_toks{\KV_key_value_elt:nn{#2}{#3}} } {\ERROR} } } -\def_long_new:Npn \KV_key_no_value_elt:n #1{\ERROR} -\def_long_new:Npn \KV_key_value_elt:nn #1#2{\ERROR} -\def_new:Npn \KV_parse_no_space_removal_no_sanitize:n { - \let:NN \KV_split_key_value_current:w \KV_split_key_value_no_space_removal:w +\cs_new:Npn \KV_key_no_value_elt:n #1{\ERROR} +\cs_new:Npn \KV_key_value_elt:nn #1#2{\ERROR} +\cs_new_nopar:Npn \KV_parse_no_space_removal_no_sanitize:n { + \cs_set_eq:NN \KV_split_key_value_current:w \KV_split_key_value_no_space_removal:w \KV_parse_no_sanitize_aux:n } -\def_new:Npn \KV_parse_space_removal_sanitize:n { - \let:NN \KV_split_key_value_current:w \KV_split_key_value_space_removal:w +\cs_new_nopar:Npn \KV_parse_space_removal_sanitize:n { + \cs_set_eq:NN \KV_split_key_value_current:w \KV_split_key_value_space_removal:w \KV_parse_sanitize_aux:n } -\def_new:Npn \KV_parse_space_removal_no_sanitize:n { - \let:NN \KV_split_key_value_current:w \KV_split_key_value_space_removal:w +\cs_new_nopar:Npn \KV_parse_space_removal_no_sanitize:n { + \cs_set_eq:NN \KV_split_key_value_current:w \KV_split_key_value_space_removal:w \KV_parse_no_sanitize_aux:n } %% diff --git a/Master/texmf-dist/tex/latex/expl3/l3messages.sty b/Master/texmf-dist/tex/latex/expl3/l3messages.sty deleted file mode 100644 index eee8eab7c8b..00000000000 --- a/Master/texmf-dist/tex/latex/expl3/l3messages.sty +++ /dev/null @@ -1,316 +0,0 @@ -%% -%% This is file `l3messages.sty', -%% generated with the docstrip utility. -%% -%% The original source files were: -%% -%% l3messages.dtx (with options: `package') -%% -%% -%% EXPERIMENTAL CODE -%% -%% Do not distribute this file without also distributing the -%% source files specified above. -%% -%% Do not distribute a modified version of this file. -%% -%% -%% File: l3messages.dtx Copyright (C) 1990-2007 LaTeX3 project -%% -%% It may be distributed and/or modified under the conditions of the -%% LaTeX Project Public License (LPPL), either version 1.3c of this -%% license or (at your option) any later version. The latest version -%% of this license is in the file -%% -%% http://www.latex-project.org/lppl.txt -%% -%% This file is part of the ``expl3 bundle'' (The Work in LPPL) -%% and all files in that bundle must be distributed together. -%% -%% The released version of this bundle is available from CTAN. -%% -%% ----------------------------------------------------------------------- -%% -%% The development version of the bundle can be found at -%% -%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/ -%% -%% for those people who are interested. -%% -%%%%%%%%%%% -%% NOTE: %% -%%%%%%%%%%% -%% -%% Snapshots taken from the repository represent work in progress and may -%% not work or may contain conflicting material! We therefore ask -%% people _not_ to put them into distributions, archives, etc. without -%% prior consultation with the LaTeX Project Team. -%% -%% ----------------------------------------------------------------------- -\RequirePackage{l3names} -\GetIdInfo$Id: l3messages.dtx 673 2007-09-28 20:50:33Z mittelba $ - {L3 Experimental LaTeX Messages module} -\ProvidesExplPackage - {\filename}{\filedate}{\fileversion}{\filedescription} -\RequirePackage{l3basics} -\RequirePackage{l3tlp} -\RequirePackage{l3expan} -\RequirePackage{l3num} -\RequirePackage{l3io} -\RequirePackage{l3int} -\RequirePackage{l3toks} -\RequirePackage{l3token} -\tlp_new:Nn \g_file_curr_name_tlp {no~file} -\let_new:NN \err_message:x \tex_errmessage:D -\def_new:Npn \text_put_sp: {~} -\def_new:Npn \text_put_four_sp: {\text_put_sp: \text_put_sp: - \text_put_sp: \text_put_sp: } -\def:Npn\cmd_arg_list_build#1{ - \toks_clear:N\l_tmpb_toks - \int_set:Nn \l_tmpa_int {#1} - \int_while:nNnT \l_tmpa_int > \c_zero { - \toks_put_left:No \l_tmpb_toks {\the_internal:D\l_tmpa_int} - \toks_put_left:Nn \l_tmpb_toks {##} - \int_decr:N\l_tmpa_int - } - \def:Npx\l_cmd_arg_list{\the_internal:D\l_tmpb_toks} -} -\def:Npn\cmd_declare:Nnn#1[#2]{ - \cmd_arg_list_build{#2} - \exp_args:NNO\def:Npn#1\l_cmd_arg_list -} -\def_new:Npn \io_show_file_lineno:{ - on~line~\the_internal:D\tex_inputlineno:D\text_put_sp:~of~ - file~\g_file_curr_name_tlp} -\let:NwN \g_err_help_toks \tex_errhelp:D -\def_new:Npn \l_err_label_token {} -\int_set:Nn\tex_errorcontextlines:D\c_minus_one -\def_new:Npn \err_info:nn #1#2{ - \def:Npn\err_newline:{\iow_newline:#2} - \io_put_log:x {#1~\io_show_file_lineno:}} -\def_new:Npn \err_warn:nn #1#2{ - \def:Npn\err_newline:{\iow_newline:#2} - \io_put_term:x {#1~\io_show_file_lineno:}} -\def_new:Npn \err_info_noline:nn #1#2{ - \def:Npn\err_newline:{\iow_newline:#2} - \io_put_log:x {#1}} -\def_new:Npn \err_warn_noline:nn #1#2{ - \def:Npn\err_newline:{\iow_newline:#2} - \io_put_term:x {#1}} -\def_new:Npn \err_interrupt:NNw #1#2{\let:NwN \l_err_label_token #2 - \group_begin: - \let:NwN \par\use_noop: - \CodeStop - \NamesStart: - %\clearshortrefmaps - \tex_input:D #1~\err_display_aux:w} -\def_new:Npn \err_fatal:nn #1#2{ - \def:Npn\err_newline:{\iow_newline:#2} - \io_put_term:x {#1~\io_show_file_lineno:} - \tex_end:D - } -\def_new:Npn \err_fatal_noline:nn #1#2{ - \def:Npn\err_newline:{\iow_newline:#2} - \io_put_term:x {#1} - \tex_end:D - } -\def_new:Npn \err_newline: {^^J} -\iow_new:N \c_iow_err_stream -\tlp_new:Nn \g_err_curr_fname{} -\def_new:Npn \err_file_new:Nn #1#2{ - \tlp_if_empty:NF\g_err_curr_fname - {\err_latex_bug:x{Unclosed~error~file~`\g_err_curr_fname'}} - \iow_open:Nn \c_iow_err_stream {#2} - \err_kernel_info:n{Errorfile~`#2'~opened~for~output} - \tlp_gset:Nn \g_err_curr_fname{#2} - \tlp_new:Nn #1{#2}} -\def_new:Npn \err_file_close:N#1{ - \tlp_if_eq:NNF#1\g_err_curr_fname - {\err_latex_bug:x{You~closed~the~wrong~error~file~`#1'.~ - Open~is~`\g_err_curr_fname'.}} - \iow_long_unexpanded:Nn \c_iow_err_stream {\err_latex_bug:x{Didn't~find~the~ - correct~error~message~to~show.\iow_newline: - Was~searching~for~a~function~ - with~the~following~meaning:\iow_newline: - \token_to_string:N\token_to_meaning:N - \token_to_string:N\l_err_label_token} - \group_end:} - \iow_close:N \c_iow_err_stream - \err_kernel_info:n{Errorfile~`\g_err_curr_fname'~closed} - \tlp_gset_eq:NN\g_err_curr_fname\c_empty_tlp -} -\def_new:Npn \err_interrupt_new:NNNnnn #1{ - \group_begin: \char_set_catcode:nn{`\#}{12} - \if_meaning:NN#1\g_err_curr_fname - \else: - \err_latex_bug:x{Error~text~goes~to~wrong~err~file:~ - `\g_err_curr_fname'~is~open~but~you~requested~ - `#1'} - \fi: - \err_interrupt_new_aux:w} -\def_long_new:Npn \err_interrupt_new_aux:w #1#2#3#4#5{ - \iow_long_unexpanded:Nn \c_iow_err_stream - {\err_msgline_aux:NNnnn #1#2{#3}{#4}{#5}\use_noop:} - \group_end:} -\def_new:Npn \err_msgline_aux:NNnnn #1#2#3#4#5{ - \if_meaning:NN#1\l_err_label_token - \cmd_declare:Nnn\err_display_aux:w [#2]{ - \group_end: - \toks_gset:Nx\g_err_help_toks{#4} - \io_put_term:x{LaTeX~error~\io_show_file_lineno:.\iow_newline: - \text_put_sp:\text_put_four_sp: \text_put_sp: - See~LaTeX~manual~for~explanation.\iow_newline: - \text_put_sp:\text_put_four_sp: \text_put_sp: - Type~\text_put_sp: H~<return>~\text_put_sp: for~ - immediate~help.} - \err_message:x{#3} - #5} - \tex_endinput:D - \fi:} -\def_new:Npn \err_display_aux:w {} -\def_new:Npn \err_kernel_interrupt:Nw {\err_interrupt:NNw \c_kernel_err_tlp} -\def_new:Npn \err_kernel_interrupt_new:NNnnn { - \err_interrupt_new:NNNnnn \c_kernel_err_tlp} -\def_new:Npn \err_kernel_info:n #1 { - \err_info:nn {LaTeX~Info:~#1} - {\text_put_four_sp:\text_put_four_sp:\text_put_four_sp:} - } -\def_new:Npn \err_kernel_warn:n #1 { - \err_warn:nn {LaTeX~Warning:~#1} - {\text_put_sp:\text_put_sp:\text_put_sp: - \text_put_four_sp:\text_put_four_sp:\text_put_four_sp:} - } -\def_new:Npn \err_kernel_fatal:n #1 { - \err_fatal:nn {LaTeX~Fatal:~#1} - {\text_put_sp: - \text_put_four_sp:\text_put_four_sp:\text_put_four_sp:} - } -\def_new:Npn \err_kernel_info_noline:n #1 { - \err_info_noline:nn {LaTeX~Info:~#1} - {\text_put_four_sp:\text_put_four_sp:\text_put_four_sp:} - } -\def_new:Npn \err_kernel_warn_noline:n #1 { - \err_warn_noline:nn {LaTeX~Warning:~#1} - {\text_put_sp:\text_put_sp:\text_put_sp: - \text_put_four_sp:\text_put_four_sp:\text_put_four_sp:} - } -\def_new:Npn \err_kernel_fatal_noline:n #1 { - \err_fatal_noline:nn {LaTeX~Fatal:~#1} - {\text_put_sp: - \text_put_four_sp:\text_put_four_sp:\text_put_four_sp:} - } -\err_file_new:Nn \c_kernel_err_tlp {l3in2e.err} -\def:Npn\err_help_ignored: { - Your~command~was~ignored.\iow_newline: - Type \text_put_sp: I~<command>~<return> - \text_put_sp: to~replace~it~with~another~command,\iow_newline: - or~\text_put_sp: <return> \text_put_sp: to~continue~without~it.} - -\def:Npn\err_help_textlost: { - You've~lost~some~text.\text_put_sp: \err_help_return_or_X:} - -\def:Npn\err_help_return_or_X: { - Try~typing\text_put_sp: <return> - \text_put_sp: to~proceed.\iow_newline: - If~that~doesn't~work,~type - \text_put_sp: X~<return>\text_put_sp: to~quit.} - -\def:Npn\err_help_trouble: { - You're~ in~ trouble~ here. - \text_put_sp:\err_help_return_or_X:} - -\err_kernel_interrupt_new:NNnnn\cs_free_p:N{1} - {Command~name~`\tex_string:D#1'~already~used} - {You~tried~to~define~a~command~which~already~has~ - a~meaning.\iow_newline: - If~you~really~want~to~redefine~it~try~ - \token_to_string:N\cmd_declare:Nnn\text_put_sp: - next~time.\iow_newline: - For~this~run~I~will~ignore~your~definition.} - {} - -\err_kernel_interrupt_new:NNnnn\newline{0} - {There's~no~line~here~to~end} - {You~tried~to~end~a~line~at~a~place~where~I~thought~ - we~were~already~between~paragraphs.} - {} - -\err_kernel_interrupt_new:NNnnn\newcnt{0} - {No~such~counter} - {The~counter~name~mentioned~in~the~operation~is~not~ - known~to~me.\iow_newline: - Check~the~spelling.} - {} - -\err_kernel_interrupt_new:NNnnn\nodocument{0} - {Missing~\token_to_string:N\begin{document}} - {\err_help_trouble:} - {} - -\err_kernel_interrupt_new:NNnnn\badmath{0} - {Bad~math~environment~delimiter} - {\err_help_ignored:} - {} - -\err_kernel_interrupt_new:NNnnn\toodeep{0} - {Too~deeply~nested} - {\err_help_trouble:} - {} - -\err_kernel_interrupt_new:NNnnn\badpoptabs{0} - {\token_to_string:N\pushtabs \text_put_sp: - and~\token_to_string:N\poptabs - \text_put_sp: don't~match} - {\err_help_trouble:} - {} - -\err_kernel_interrupt_new:NNnnn\badtab{0} - {Undefined~tab~position} - {\err_help_trouble:} - {} - -\err_kernel_interrupt_new:NNnnn\preamerr{} - {\if_case:w #1~Illegal~character\or: - Missing~@-exp\or: Missing~p-arg\fi:\text_put_sp: - in~array~arg} - {\err_help_trouble:} - {} - -\err_kernel_interrupt_new:NNnnn\badlinearg{} - {Bad~\token_to_string:N\line - \text_put_sp: or~\token_to_string:N\vector - \text_put_sp: argument} - {\err_help_textlost:} - {} - -\err_kernel_interrupt_new:NNnnn\parmoderr{0} - {Not~in~outer~par~mode} - {\err_help_textlost:} - {} - -\err_kernel_interrupt_new:NNnnn\fltovf{0} - {Too~many~unprocessed~floats} - {\err_help_textlost:} - {} - -\err_kernel_interrupt_new:NNnnn\badcrerr{0} - {Bad~use~of~\token_to_string:N\\} - {\err_help_return_or_X:} - {} - -\err_kernel_interrupt_new:NNnnn\noitemerr{0} - {Something's~wrong--perhaps~a~missing~ - \token_to_string:N\item} - {\err_help_return_or_X:} - {} - -\err_kernel_interrupt_new:NNnnn\notprerr{0} - {Can~be~used~only~in~preamble} - {\err_help_ignored:} - {} - -\err_file_close:N\c_kernel_err_tlp - -%% -%% -%% End of file `l3messages.sty'. diff --git a/Master/texmf-dist/tex/latex/expl3/l3msg.sty b/Master/texmf-dist/tex/latex/expl3/l3msg.sty new file mode 100644 index 00000000000..6d7cee74366 --- /dev/null +++ b/Master/texmf-dist/tex/latex/expl3/l3msg.sty @@ -0,0 +1,487 @@ +%% +%% This is file `l3msg.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% l3msg.dtx (with options: `package') +%% +%% +%% EXPERIMENTAL CODE +%% +%% Do not distribute this file without also distributing the +%% source files specified above. +%% +%% Do not distribute a modified version of this file. +%% +%% +%% File: l3msg.dtx Copyright (C) 2009 LaTeX3 project +%% +%% It may be distributed and/or modified under the conditions of the +%% LaTeX Project Public License (LPPL), either version 1.3c of this +%% license or (at your option) any later version. The latest version +%% of this license is in the file +%% +%% http://www.latex-project.org/lppl.txt +%% +%% This file is part of the ``expl3 bundle'' (The Work in LPPL) +%% and all files in that bundle must be distributed together. +%% +%% The released version of this bundle is available from CTAN. +%% +%% ----------------------------------------------------------------------- +%% +%% The development version of the bundle can be found at +%% +%% http://www.latex-project.org/svnroot/experimental/trunk/ +%% +%% for those people who are interested. +%% +%%%%%%%%%%% +%% NOTE: %% +%%%%%%%%%%% +%% +%% Snapshots taken from the repository represent work in progress and may +%% not work or may contain conflicting material! We therefore ask +%% people _not_ to put them into distributions, archives, etc. without +%% prior consultation with the LaTeX Project Team. +%% +%% ----------------------------------------------------------------------- +%% +\RequirePackage{l3names} +\GetIdInfo$Id: l3msg.dtx 1362 2009-05-28 20:19:21Z joseph $ + {L3 Experimental LaTeX Messages module} +\ProvidesExplPackage + {\filename}{\filedate}{\fileversion}{\filedescription} +\package_check_loaded_expl: +\int_set:Nn \tex_errorcontextlines:D { \c_minus_one } +\tl_new:Nn \c_msg_fatal_tl { Fatal~Error } +\tl_new:Nn \c_msg_error_tl { Error } +\tl_new:Nn \c_msg_warning_tl { Warning } +\tl_new:Nn \c_msg_info_tl { Info } +\tl_new:Nn \c_msg_fatal_text_tl { + This~is~a~fatal~error:~LaTeX~will~abort +} +\tl_new:Nn \c_msg_help_text_tl { + For~immediate~help~type~H~<return> +} +\tl_new:Nn \c_msg_kernel_bug_text_tl { + This~is~a~LaTeX~bug:~check~coding! +} +\tl_new:Nn \c_msg_kernel_bug_more_text_tl { + There~is~a~coding~bug~somewhere~around~here. + \msg_newline: + This~probably~needs~examining~by~an~expert. + \c_msg_return_text_tl +} +\tl_new:Nn \c_msg_no_info_text_tl { + LaTeX~does~not~know~anything~more~about~this~error,~sorry. + \c_msg_return_text_tl +} +\tl_new:Nn \c_msg_return_text_tl { + \msg_two_newlines: + Try~typing~<return>~to~proceed. + \msg_newline: + If~that~doesn't~work,~type~X~<return>~to~quit +} +\group_begin: +\char_make_letter:N\ % +\tl_to_lowercase:n{% +\group_end:% +\tl_new:Nn% +\c_msg_hide_tl % +{}% +}% +\tl_new:Nn \c_msg_on_line_tl { on~line } +\tl_new:Nn \c_msg_text_prefix_tl { msg_text // } +\tl_new:Nn \c_msg_more_text_prefix_tl { msg_text_more // } +\tl_new:Nn \c_msg_code_prefix_tl { msg_code // } +\tl_new:N \l_msg_class_tl +\tl_new:N \l_msg_current_class_tl +\clist_new:N \l_msg_names_clist +\prop_new:N \l_msg_redirect_classes_prop +\prop_new:N \l_msg_redirect_names_prop +\clist_new:N \l_msg_redirect_classes_clist +\cs_new_nopar:Nn { \msg_line_number: } { + \toks_use:N \tex_inputlineno:D +} +\cs_new_nopar:Nn { \msg_line_context: } { + \msg_space: + \c_msg_on_line_tl + \msg_space: + \msg_line_number: +} +\cs_new_nopar:Nn \msg_newline: { ^^J } +\cs_new_nopar:Nn \msg_two_newlines: { ^^J ^^J } +\cs_new_nopar:Nn \msg_space: { ~ } +\cs_new_nopar:Nn \msg_two_spaces: { \msg_space: \msg_space: } +\cs_new_nopar:Nn \msg_four_spaces: { \msg_two_spaces: \msg_two_spaces: } +\cs_new_nopar:Npn \msg_generic_new:nnnn #1 { + \exp_args:Nc \chk_if_free_cs:N { \c_msg_text_prefix_tl #1 :nn } + \msg_generic_set:nnnn {#1} +} +\cs_new_nopar:Npn \msg_generic_new:nnn #1 { + \exp_args:Nc \chk_if_free_cs:N { \c_msg_text_prefix_tl #1 :nn } + \msg_generic_set:nnn {#1} +} +\cs_new_nopar:Npn \msg_generic_new:nn #1 { + \exp_args:Nc \chk_if_free_cs:N { \c_msg_text_prefix_tl #1 :nn } + \msg_generic_set:nn {#1} +} +\cs_new_nopar:Npn \msg_generic_set:nnnn #1 { + \msg_generic_set_clist:n {#1} + \char_make_space:N \ % + \msg_generic_set_code:nnnn{#1}% +} +\cs_new_nopar:Npn \msg_generic_set:nnn #1 { + \msg_generic_set_clist:n {#1} + \char_make_space:N \ % + \msg_generic_set_more_text:nnn{#1}% +} +\cs_new_nopar:Npn \msg_generic_set:nn #1 { + \msg_generic_set_clist:n {#1} + \char_make_space:N \ % + \msg_generic_set_text:nn{#1}% +} +\cs_new_nopar:Npn \msg_generic_set_clist:n #1 { + \clist_if_in:NnF \l_msg_names_clist { // #1 / } { + \clist_put_right:Nn \l_msg_names_clist { // #1 / } + } +} +\cs_new:Nn \msg_generic_set_text:nn { + \cs_set:cn { \c_msg_text_prefix_tl #1 :nn } {#2} + \char_make_ignore:N \ +} +\cs_new:Nn \msg_generic_set_more_text:nnn { + \cs_set:cn { \c_msg_text_prefix_tl #1 :nn } {#2} + \tl_if_empty:nTF {#3} { + \cs_set_eq:cN { \c_msg_more_text_prefix_tl #1 } \c_undefined + }{ + \cs_set:cn { \c_msg_more_text_prefix_tl #1 :nn } {#3} + } + \char_make_ignore:N \ +} +\cs_new:Npn \msg_generic_set_code:nnnn #1#2#3 { + \cs_set:cn { \c_msg_text_prefix_tl #1 :nn } {#2} + \tl_if_empty:nTF {#3} { + \cs_set_eq:cN { \c_msg_more_text_prefix_tl #1 } \c_undefined + }{ + \cs_set:cn { \c_msg_more_text_prefix_tl #1 :nn } {#3} + } + \char_make_ignore:N \ + \msg_generic_set_code:nn {#1} +} +\cs_new:Nn \msg_generic_set_code:nn { + \tl_if_empty:nTF {#2} { + \cs_set_eq:cN { \c_msg_code_prefix_tl #1 : } \c_undefined + }{ + \cs_set:cn { \c_msg_code_prefix_tl #1 : } {#2} + } +} +\group_begin: + \char_set_lccode:nn {`\&} {`\ } % { + \char_set_lccode:w `\} = `\ \scan_stop: + \char_make_active:N \& + \char_make_letter:N\ % +\tl_to_lowercase:n{% +\group_end:% +\cs_new_protected:Nn\msg_direct_interrupt:xxxxn{% +\group_begin:% +\cs_set_eq:NN\\\msg_newline:% +\cs_set_eq:NN\ \msg_space:% +\msg_direct_interrupt_aux:n{#4}% +\cs_set_nopar:Npn\\{\msg_newline:#3}% +\tex_errhelp:D\l_msg_tmp_tl% +\cs_set:Npn&{% +\tex_errmessage:D{% +#1\msg_newline:% +#2\msg_two_newlines:% +\c_msg_help_text_tl% +\c_msg_hide_tl % +}% +}% +&% +\group_end:% +#5% +}% +}% +\cs_new:Nn \msg_direct_interrupt_aux:n { + \tl_if_empty:nTF {#1} { + \tl_set:Nx \l_msg_tmp_tl { { \c_msg_no_info_text_tl } } + }{ + \tl_set:Nx \l_msg_tmp_tl { {#1 } } + } +} +\cs_new_protected:Nn \msg_direct_log:xx { + \group_begin: + \cs_set:Npn \\ { \msg_newline: #2 } + \cs_set_eq:NN \ \msg_space: + \iow_log:x { #1 \msg_newline: } + \group_end: +} +\cs_new_protected:Nn \msg_direct_term:xx { + \group_begin: + \cs_set:Npn \\ { \msg_newline: #2 } + \cs_set_eq:NN \ \msg_space: + \iow_term:x { #1 \msg_newline: } + \group_end: +} +\cs_new_nopar:Npn \msg_new:nnnnn #1#2 { + \msg_generic_new:nnnn { #1 / #2 } +} +\cs_new_nopar:Npn \msg_new:nnnn #1#2 { + \msg_generic_new:nnn { #1 / #2 } +} +\cs_new_nopar:Npn \msg_new:nnn #1#2 { + \msg_generic_new:nn { #1 / #2 } +} +\cs_new_nopar:Npn \msg_set:nnnnn #1#2 { + \msg_generic_set:nnnn { #1 / #2 } +} +\cs_new_nopar:Npn \msg_set:nnnn #1#2 { + \msg_generic_set:nnn { #1 / #2 } +} +\cs_new_nopar:Npn \msg_set:nnn #1#2 { + \msg_generic_set:nn { #1 / #2 } +} +\cs_new_nopar:Npn \msg_class_new:nn #1 { + \exp_args:Nc \chk_if_free_cs:N { msg_ #1 :nnxx } + \prop_new:c { l_msg_redirect_ #1 _prop } + \msg_class_set:nn {#1} +} +\cs_new_nopar:Nn \msg_class_set:nn { + \prop_clear:c { l_msg_redirect_ #1 _prop } + \cs_set_protected:cn { msg_ #1 :nnxx } { + \msg_use:nnnnxx {#1} {#2} {##1} {##2} {##3} {##4} + } + \cs_set_protected:cn { msg_ #1 :nnx } { + \use:c { msg_ #1 :nnxx } {##1} {##2} {##3} { } + } + \cs_set_protected:cn { msg_ #1 :nn } { + \use:c { msg_ #1 :nnxx } {##1} {##2} { } { } + } +} +\cs_new:Nn \msg_use:nnnnxx { + \cs_set:Nn \msg_use_code: { + \clist_clear:N \l_msg_redirect_classes_clist + #2 + } + \cs_set:Nn \msg_use_loop:n { + \clist_if_in:NnTF \l_msg_redirect_classes_clist {#1} { + \msg_kernel_error:n { message~loop } + }{ + \clist_put_right:Nn \l_msg_redirect_classes_clist {#1} + \cs_if_exist:cTF { msg_ ##1 :nnxx } { + \use:c { msg_ ##1 :nnxx } {#3} {#4} {#5} {#6} + }{ + \msg_kernel_error:nx { message~class~unknown } { ##1 } + } + } + } + \cs_if_exist:cTF { \c_msg_text_prefix_tl #3 / #4 :nn } { + \msg_use_aux:nnn {#1} {#3} {#4} + }{ + \msg_kernel_error:nxx { message~unknown } { #3 } { #4 } + } +} +\cs_new_nopar:Nn \msg_use_code: { } +\cs_new_nopar:Nn \msg_use_loop:n { } +\cs_new_nopar:Nn \msg_use_aux:nnn { + \tl_set:Nn \l_msg_current_class_tl {#1} + \tl_set:Nn \l_msg_current_module_tl {#2} + \prop_if_in:NnTF \l_msg_redirect_names_prop { // #2 / #3 / } { + \msg_use_loop_check:nn { names } { // #2 / #3 / } + }{ + \msg_use_aux:nn {#1} {#2} + } +} +\cs_new_nopar:Nn \msg_use_aux:nn { + \prop_if_in:cnTF { l_msg_redirect_ #1 _prop } {#2} { + \msg_use_loop_check:nn {#1} {#2} + }{ + \prop_if_in:cnTF { l_msg_redirect_ #1 _prop } {*} { + \msg_use_loop_check:nn {#1} {*} + }{ + \msg_use_code: + } + } +} +\cs_new:Nn \msg_use_loop_check:nn { + \prop_get:cnN { l_msg_redirect_ #1 _prop } {#2} \l_msg_class_tl + \tl_if_eq:NNTF \l_msg_current_class_tl \l_msg_class_tl { + \msg_use_code: + }{ + \msg_use_loop:n { \l_msg_class_tl } + } +} +\msg_class_new:nn { fatal } { + \msg_direct_interrupt:xxxxn + { \c_msg_fatal_tl \msg_two_newlines: } + { + ( \c_msg_fatal_tl ) \msg_space: + \use:c { \c_msg_text_prefix_tl #1 / #2 :nn } {#3} {#4} + } + { ( \c_msg_fatal_tl ) \msg_space: } + { \c_msg_fatal_text_tl } + { \tex_end:D } +} +\msg_class_new:nn { error } { + \msg_direct_interrupt:xxxxn + { #1~\c_msg_error_tl \msg_newline: } + { + ( #1 ) \msg_space: + \use:c { \c_msg_text_prefix_tl #1 / #2 :nn } {#3} {#4} + } + { ( #1 ) \msg_space: } + { + \cs_if_exist:cTF { \c_msg_more_text_prefix_tl #1 / #2 :nn } { + \use:c { \c_msg_more_text_prefix_tl #1 / #2 :nn } {#3} {#4} + }{ + \c_msg_no_info_text_tl + } + } + { + \cs_if_exist:cT { \c_msg_code_prefix_tl #1 /#2 :nn } { + \use:c { \c_msg_code_prefix_tl #1 / #2 :nn} {#3} {#4} + } + } +} +\msg_class_new:nn { warning } { + \msg_direct_term:xx { + \msg_space: #1~\c_msg_warning_tl :~ + \use:c { \c_msg_text_prefix_tl #1 / #2 :nn } {#3} {#4} + } + { ( #1 ) \msg_two_spaces: } +} +\msg_class_new:nn { info } { + \msg_direct_log:xx { + \msg_space: #1~\c_msg_info_tl :~ + \use:c { \c_msg_text_prefix_tl #1 / #2 :nn } {#3} {#4} + } + { ( #1 ) \msg_two_spaces: } +} +\msg_class_new:nn { log } { + \msg_direct_log:xx { + \use:c { \c_msg_text_prefix_tl #1 / #2 :nn } {#3} {#4} + } + { } +} +\msg_class_new:nn { trace } { + \msg_direct_log:xx { + \use:c { \c_msg_text_prefix_tl #1 / #2 :nn } {#3} {#4} + } + { } +} +\msg_class_new:nn { none } { } +\cs_new_nopar:Nn \msg_redirect_class:nn { + \prop_put:cnn { l_msg_redirect_ #1 _prop } {*} {#2} +} +\cs_new_nopar:Nn \msg_redirect_module:nnn { + \prop_put:cnn { l_msg_redirect_ #2 _prop } {#1} {#3} +} +\cs_new_nopar:Nn \msg_redirect_name:nnn { + \prop_put:Nnn \l_msg_redirect_names_prop { // #1 / #2 / } {#3} +} +\cs_new_nopar:Npn \msg_kernel_new:nnnn #1 { + \msg_new:nnnnn { LaTeX } {#1} +} +\cs_new_nopar:Npn \msg_kernel_new:nnn #1 { + \msg_new:nnnn { LaTeX } {#1} +} +\cs_new_nopar:Npn \msg_kernel_new:nn #1 { + \msg_new:nnn { LaTeX } {#1} +} +\cs_new_nopar:Npn \msg_kernel_set:nnnn #1 { + \msg_set:nnnnn { LaTeX } {#1} +} +\cs_new_nopar:Npn \msg_kernel_set:nnn #1 { + \msg_set:nnnn { LaTeX } {#1} +} +\cs_new_nopar:Npn \msg_kernel_set:nn #1 { + \msg_set:nnn { LaTeX } {#1} +} +\cs_new_nopar:Nn \msg_kernel_classes_new:n { + \cs_new_protected:cn { msg_kernel_ #1 :nx } { + \use:c { msg_kernel_ #1 :nxx } {##1} {##2} { } + } + \cs_new_protected:cn { msg_kernel_ #1 :n } { + \use:c { msg_kernel_ #1 :nxx } {##1} { } { } + } +} +\cs_new_protected:Nn \msg_kernel_fatal:nxx { + \msg_direct_interrupt:xxxxn + { \c_msg_fatal_tl \msg_two_newlines: } + { + ( LaTeX ) \msg_space: + \use:c { \c_msg_text_prefix_tl LaTeX / #1 :nn } {#2} {#3} + } + { ( LaTeX ) \msg_space: } + { \c_msg_fatal_text_tl } + { \tex_end:D } +} +\msg_kernel_classes_new:n { fatal } +\cs_new_protected:Nn \msg_kernel_error:nxx { + \msg_direct_interrupt:xxxxn + { LaTeX~\c_msg_error_tl \msg_newline: } + { + ( LaTeX ) \msg_space: + \use:c { \c_msg_text_prefix_tl LaTeX / #1 :nn } {#2} {#3} + } + { ( LaTeX ) \msg_space: } + { + \cs_if_exist:cTF { \c_msg_more_text_prefix_tl LaTeX / #1 :nn } { + \use:c { \c_msg_more_text_prefix_tl LaTeX / #1 :nn } {#2} {#3} + }{ + \c_msg_no_info_text_tl + } + } + { + \cs_if_exist:cT { \c_msg_code_prefix_tl LaTeX /#1 :nn } { + \use:c { \c_msg_code_prefix_tl LaTeX / #1 :nn} {#2} {#3} + } + } +} +\msg_kernel_classes_new:n { error } +\cs_new_protected_nopar:Npn \msg_kernel_warning:nxx { + \msg_warning:nnxx { LaTeX } +} +\msg_kernel_classes_new:n { warning } +\cs_new_protected_nopar:Npn \msg_kernel_info:nxx { + \msg_info:nnxx { LaTeX } +} +\msg_kernel_classes_new:n { info } +\msg_kernel_new:nnn + { coding~bug } + {This is a LaTeX bug: check coding!\\#1} + {#2} +\msg_kernel_new:nnn + { message~unknown } + {Unknown message `#2' for module `#1'.} + {LaTeX was asked to display a message by the `#1' module.\\ + The message was supposed to be called `#2', but I can't\\ + find a message with that name. + \c_msg_return_text_tl} +\msg_kernel_new:nnn + { message~class~unknown } + {Unknown message class `#1'.} + {You have asked for a message to be redirected to class `#1'\\ + but this class is unknown. + \c_msg_return_text_tl} +\msg_kernel_new:nnn + { message~loop } + {Message redirection loop.} + {You have asked for a message to be redirected,\\ + but the redirection instructions form a loop:\\ + you've lost the message. + \c_msg_return_text_tl} +\cs_set_protected:Nn \msg_kernel_bug:x { + \msg_direct_interrupt:xxxxn + { \c_msg_kernel_bug_text_tl } + { !~#1 } + { ! } + { \c_msg_kernel_bug_more_text_tl } + { } +} +%% +%% +%% End of file `l3msg.sty'. diff --git a/Master/texmf-dist/tex/latex/expl3/l3names.sty b/Master/texmf-dist/tex/latex/expl3/l3names.sty index 485ad03e134..28f36638615 100644 --- a/Master/texmf-dist/tex/latex/expl3/l3names.sty +++ b/Master/texmf-dist/tex/latex/expl3/l3names.sty @@ -15,7 +15,7 @@ %% Do not distribute a modified version of this file. %% %% -%% File: l3names.dtx Copyright (C) 1990-2006 LaTeX3 project +%% File: l3names.dtx Copyright (C) 1990-2006,2009 LaTeX3 project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this @@ -33,7 +33,7 @@ %% %% The development version of the bundle can be found at %% -%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/ +%% http://www.latex-project.org/svnroot/experimental/trunk/ %% %% for those people who are interested. %% @@ -48,7 +48,18 @@ %% %% ----------------------------------------------------------------------- \begingroup -\def\GetIdInfo$#1 #2.#3 #4 #5 #6 #7${% +\def\GetIdInfo$#1${% + \begingroup + \def\GetIdInfoString{#1}% + \def\IdInfoStringUnexp{Id}% + \ifx \GetIdInfoString \IdInfoStringUnexp + \def\next{\endgroup\GetIdInfoMissing} + \else + \def\next{\endgroup\GetIdInfoFull$#1$} + \fi + \next +} +\def\GetIdInfoFull$#1 #2.#3 #4 #5 #6 #7${% \GetIdInfoAux #5\relax{#2}#5\relax{#4}% } \def\GetIdInfoAux #1#2#3#4#5#6\relax{% @@ -70,9 +81,43 @@ \gdef\filedescription{#6}% \ProvidesPackage{#1}[#2/#3/#4 v#5 #6] } -\GetIdInfo$Id: l3names.dtx 621 2007-09-01 20:14:19Z morten $ +\def\GetIdInfoMissing#1{% + \gdef\fileversion{000}% + \gdef\filedate{0000/00/00}% + \gdef\filedescription{#1}% + \ProvidesPackage{[unknown package]}[0000/00/00 v0.0 #1] +} +\GetIdInfo$Id: l3names.dtx 1362 2009-05-28 20:19:21Z joseph $ {L3 Experimental Naming Scheme for TeX Primitives} \endgroup +\begingroup +\def\firstoftwo#1#2{#1} +\def\secondoftwo#1#2{#2} +\def\etexmissingerror{Not running under e-TeX} +\def\etexmissinghelp{% + This package requires e-TeX.^^J% + Try compiling the document with `elatex' instead of `latex'.^^J% + When using pdfTeX, try `pdfelatex' instead of `pdflatex'% +}% +\expandafter\ifx\csname eTeXversion\endcsname\relax + \expandafter\secondoftwo\else\expandafter\firstoftwo\fi + {\endgroup}{% + \PackageError{l3names}{\etexmissingerror}{\etexmissinghelp}% + \endgroup + \endinput + } +\edef\ExplSyntaxOff{ + \unexpanded{\ifodd \ExplSyntaxStatus\relax + \def\ExplSyntaxStatus{0} + } + \catcode 126=\the \catcode 126 \relax + \catcode 32=\the \catcode 32 \relax + \catcode 9=\the \catcode 9 \relax + \endlinechar =\the \endlinechar \relax + \catcode 95=\the \catcode 95 \relax + \catcode 58=\the \catcode 58 \relax + \noexpand\fi +} \catcode126=10\relax % tilde is a space char. \catcode32=9\relax % space is ignored \catcode9=9\relax % tab also ignored @@ -583,39 +628,70 @@ \name_primitive:NN \pdfresettimer \pdf_resettimer:D \name_primitive:NN \pdfsetrandomseed \pdf_setrandomseed:D \name_primitive:NN \pdfnoligatures \pdf_noligatures:D -\name_primitive:NN \textdir \aleph_textdir:D +\name_primitive:NN \XeTeXversion \xetex_version:D +\name_primitive:NN \directlua \luatex_directlua:D +\etex_ifdefined:D \strcmp + \etex_ifdefined:D \xetex_version:D + \name_primitive:NN \strcmp \pdf_strcmp:D + \tex_fi:D +\tex_fi:D \tex_def:D\ExplSyntaxOn{ - \tex_def:D\ExplSyntaxStatus{00} - \tex_catcode:D 126=10 \tex_relax:D % tilde is a space char. - \tex_catcode:D 32=9 \tex_relax:D % space is ignored - \tex_catcode:D 9=9 \tex_relax:D % tab also ignored - \tex_endlinechar:D =32 \tex_relax:D % endline is space - \tex_catcode:D 95=11 \tex_relax:D % underscore letter - \tex_catcode:D 58=11 \tex_relax:D % colon letter -} -\tex_def:D\ExplSyntaxOff{ - \tex_def:D\ExplSyntaxStatus{01} - \tex_catcode:D 126=13 \tex_relax:D - \tex_catcode:D 32=10 \tex_relax:D - \tex_catcode:D 9=10 \tex_relax:D - \tex_endlinechar:D =13 \tex_relax:D - \tex_catcode:D 95=8 \tex_relax:D - \tex_catcode:D 58=12 \tex_relax:D + \tex_ifodd:D \ExplSyntaxStatus \tex_relax:D + \tex_else:D + \tex_edef:D\ExplSyntaxOff{ + \etex_unexpanded:D{ + \tex_ifodd:D \ExplSyntaxStatus \tex_relax:D + \tex_def:D \ExplSyntaxStatus{0} + } + \tex_catcode:D 126=\tex_the:D \tex_catcode:D 126 \tex_relax:D + \tex_catcode:D 32=\tex_the:D \tex_catcode:D 32 \tex_relax:D + \tex_catcode:D 9=\tex_the:D \tex_catcode:D 9 \tex_relax:D + \tex_endlinechar:D =\tex_the:D \tex_endlinechar:D \tex_relax:D + \tex_catcode:D 95=\tex_the:D \tex_catcode:D 95 \tex_relax:D + \tex_catcode:D 58=\tex_the:D \tex_catcode:D 58 \tex_relax:D + \tex_noexpand:D \tex_fi:D + } + \tex_def:D\ExplSyntaxStatus{1} + \tex_catcode:D 126=10 \tex_relax:D % tilde is a space char. + \tex_catcode:D 32=9 \tex_relax:D % space is ignored + \tex_catcode:D 9=9 \tex_relax:D % tab also ignored + \tex_endlinechar:D =32 \tex_relax:D % endline is space + \tex_catcode:D 95=11 \tex_relax:D % underscore letter + \tex_catcode:D 58=11 \tex_relax:D % colon letter + \tex_fi:D } -\tex_let:D \CodeStart \ExplSyntaxOn -\tex_let:D \CodeStop \ExplSyntaxOff -\tex_def:D \NamesStart{ +\tex_def:D\ExplSyntaxStatus{1} +\tex_def:D \ExplSyntaxNamesOn{ \tex_catcode:D `\_=11\tex_relax:D \tex_catcode:D `\:=11\tex_relax:D } -\tex_def:D \NamesStop{ +\tex_def:D \ExplSyntaxNamesOff{ \tex_catcode:D `\_=8\tex_relax:D \tex_catcode:D `\:=12\tex_relax:D } \tex_def:D\GetIdInfo{ \tex_begingroup:D \tex_catcode:D 32=10 \tex_relax:D % needed? Probably for now. - \GetIdInfoAuxi:w + \GetIdInfoMaybeMissing:w +} +\tex_def:D\GetIdInfoMaybeMissing:w$#1$#2{ + \tex_def:D \l_tmpa_tl {#1} + \tex_def:D \l_tmpb_tl {Id} + \tex_ifx:D \l_tmpa_tl \l_tmpb_tl + \tex_def:D \l_tmpa_tl { + \tex_endgroup:D + \tex_def:D\filedescription{#2} + \tex_def:D\filename {[unknown~name]} + \tex_def:D\fileversion {000} + \tex_def:D\fileauthor {[unknown~author]} + \tex_def:D\filedate {0000/00/00} + \tex_def:D\filenameext {[unknown~ext]} + \tex_def:D\filetimestamp {[unknown~timestamp]} + } + \tex_else:D + \tex_def:D \l_tmpa_tl {\GetIdInfoAuxi:w$#1${#2}} + \tex_fi:D + \l_tmpa_tl } \tex_def:D\GetIdInfoAuxi:w$#1~#2.#3~#4~#5~#6~#7~#8$#9{ \tex_endgroup:D @@ -653,27 +729,31 @@ \ProvidesClass{#1}[#2~v#3~#4] \ExplSyntaxOn } -\tex_let:D \org@onefilewithoptions\@onefilewithoptions -\tex_def:D \@onefilewithoptions#1[#2][#3]#4{ - \tex_edef:D \ExplSyntaxStack{ \ExplSyntaxStatus\ExplSyntaxStack } - \ExplSyntaxOff - \org@onefilewithoptions{#1}[{#2}][{#3}]{#4} - \tex_expandafter:D\ExplSyntaxPopStack\ExplSyntaxStack\tex_relax:D -} -\g@addto@macro\@popfilename{% - \tex_ifnum:D\tex_the:D\tex_catcode:D`\@=12\tex_relax:D +\tex_edef:D \@pushfilename{ + \etex_unexpanded:D{ + \tex_edef:D \ExplSyntaxStack{ \ExplSyntaxStatus \ExplSyntaxStack } \ExplSyntaxOff - \tex_fi:D + } + \etex_unexpanded:D\tex_expandafter:D{\@pushfilename } } -\tex_def:D\ExplSyntaxPopStack#1#2#3\tex_relax:D{ - \tex_def:D\ExplSyntaxStack{#3} - \tex_if:D#1#2 +\tex_edef:D \@popfilename{ + \etex_unexpanded:D\tex_expandafter:D{\@popfilename + \tex_if:D 2\ExplSyntaxStack 2 + \ExplSyntaxOff + \tex_else:D + \tex_expandafter:D\ExplSyntaxPopStack\ExplSyntaxStack\q_nil + \tex_fi:D + } +} +\tex_def:D\ExplSyntaxPopStack#1#2\q_nil{ + \tex_def:D\ExplSyntaxStack{#2} + \tex_ifodd:D#1\tex_relax:D \ExplSyntaxOn \tex_else:D \ExplSyntaxOff \tex_fi:D } -\tex_def:D\ExplSyntaxStack{} +\tex_def:D \ExplSyntaxStack{0} \tex_let:D\tex_input:D \@@input \tex_let:D\tex_underline:D \@@underline \tex_let:D\tex_end:D \@@end @@ -683,7 +763,6 @@ \tex_let:D\tex_hyphen:D \@@hyph \tex_let:D\par \tex_par:D \tex_ifx:D\name_undefine:N\@gobble - \AtEndOfPackage{\ExplSyntaxOff} \tex_def:D\name_pop_stack:w{} \tex_else:D \tex_def:D\ProvidesPackage{ @@ -715,6 +794,14 @@ \tex_fi:D} \tex_fi:D \tex_futurelet:D\name_tmp:\name_pop_stack:w +\tex_def:D \package_check_loaded_expl: { + \@ifpackageloaded{expl3}{}{ + \PackageError{expl3}{Cannot~load~the~expl3~modules~separately}{ + The~expl3~modules~cannot~be~loaded~separately;\MessageBreak + please~\protect\usepackage{expl3}~instead. + } + } +} %% %% %% End of file `l3names.sty'. diff --git a/Master/texmf-dist/tex/latex/expl3/l3num.sty b/Master/texmf-dist/tex/latex/expl3/l3num.sty index e34d1f82280..f2a12228b84 100644 --- a/Master/texmf-dist/tex/latex/expl3/l3num.sty +++ b/Master/texmf-dist/tex/latex/expl3/l3num.sty @@ -15,7 +15,7 @@ %% Do not distribute a modified version of this file. %% %% -%% File: l3num.dtx Copyright (C) 2005-2008 Frank Mittelbach, LaTeX3 project +%% File: l3num.dtx Copyright (C) 2005-2009 Frank Mittelbach, LaTeX3 project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this @@ -33,7 +33,7 @@ %% %% The development version of the bundle can be found at %% -%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/ +%% http://www.latex-project.org/svnroot/experimental/trunk/ %% %% for those people who are interested. %% @@ -48,118 +48,53 @@ %% %% ----------------------------------------------------------------------- \RequirePackage{l3names} -\GetIdInfo$Id: l3num.dtx 741 2008-08-01 13:37:16Z morten $ +\GetIdInfo$Id: l3num.dtx 1362 2009-05-28 20:19:21Z joseph $ {L3 Experimental token numbers} \ProvidesExplPackage {\filename}{\filedate}{\fileversion}{\filedescription} -\RequirePackage{l3expan}\par -\let_new:NN \num_value:w \tex_number:D -\let_new:NN \num_eval:w \etex_numexpr:D -\let_new:NN \num_eval_end: \scan_stop: -\let_new:NN \if_num:w \tex_ifnum:D -\let_new:NN \if_num_odd:w \tex_ifodd:D -\let_new:NN \if_case:w \tex_ifcase:D -\let_new:NN \or: \tex_or:D -\def:Npn \num_incr:N #1{\num_add:Nn#1 1} -\def:Npn \num_decr:N #1{\num_add:Nn#1 \c_minus_one} -\def:Npn \num_gincr:N #1{\num_gadd:Nn#1 1} -\def:Npn \num_gdecr:N #1{\num_gadd:Nn#1 \c_minus_one} -\def_new:Npn \num_incr:c {\exp_args:Nc \num_incr:N} -\def_new:Npn \num_decr:c {\exp_args:Nc \num_decr:N} -\def_new:Npn \num_gincr:c {\exp_args:Nc \num_gincr:N} -\def_new:Npn \num_gdecr:c {\exp_args:Nc \num_gdecr:N} -\def_new:Npn \num_zero:N #1 {\num_set:Nn #1 0} -\def_new:Npn \num_gzero:N #1 {\num_gset:Nn #1 0} -\def_new:Npn \num_zero:c {\exp_args:Nc \num_zero:N} -\def_new:Npn \num_gzero:c {\exp_args:Nc \num_gzero:N} -\def_new:Npn \num_new:N #1{\tlp_new:Nn #1{0}} -\def_new:Npn \num_new:c {\exp_args:Nc \num_new:N} -\def_new:Npn \num_eval:n #1{\num_eval:w #1\num_eval_end:} -\def_new:Npn \num_set:Nn #1#2{ - \tlp_set:No #1{ \tex_number:D \num_eval:n {#2} } +\package_check_loaded_expl: +\cs_new_eq:NN \if_num:w \tex_ifnum:D +\cs_new_eq:NN \if_case:w \tex_ifcase:D +\cs_set_nopar:Npn \num_incr:N #1{\num_add:Nn#1 1} +\cs_set_nopar:Npn \num_decr:N #1{\num_add:Nn#1 \c_minus_one} +\cs_set_nopar:Npn \num_gincr:N #1{\num_gadd:Nn#1 1} +\cs_set_nopar:Npn \num_gdecr:N #1{\num_gadd:Nn#1 \c_minus_one} +\cs_generate_variant:Nn \num_incr:N {c} +\cs_generate_variant:Nn \num_decr:N {c} +\cs_generate_variant:Nn \num_gincr:N {c} +\cs_generate_variant:Nn \num_gdecr:N {c} +\cs_new_nopar:Npn \num_zero:N #1 {\num_set:Nn #1 0} +\cs_new_nopar:Npn \num_gzero:N #1 {\num_gset:Nn #1 0} +\cs_generate_variant:Nn \num_zero:N {c} +\cs_generate_variant:Nn \num_gzero:N {c} +\cs_new_nopar:Npn \num_new:N #1{\tl_new:Nn #1{0}} +\cs_generate_variant:Nn \num_new:N {c} +\cs_new_nopar:Npn \num_set:Nn #1#2{ + \tl_set:No #1{ \tex_number:D \intexpr_eval:n {#2} } } -\def_new:Npn \num_gset:Nn {\pref_global:D \num_set:Nn} -\def_new:Npn \num_set:cn {\exp_args:Nc \num_set:Nn } -\def_new:Npn \num_gset:cn {\exp_args:Nc \num_gset:Nn } -\let_new:NN \num_set_eq:NN \tlp_set_eq:NN -\def_new:Npn \num_set_eq:cN {\exp_args:Nc \num_set_eq:NN} -\def_new:Npn \num_set_eq:Nc {\exp_args:NNc \num_set_eq:NN} -\def_new:Npn \num_set_eq:cc {\exp_args:Ncc \num_set_eq:NN} -\let_new:NN \num_gset_eq:NN \tlp_gset_eq:NN -\def_new:Npn \num_gset_eq:cN {\exp_args:Nc \num_gset_eq:NN} -\def_new:Npn \num_gset_eq:Nc {\exp_args:NNc \num_gset_eq:NN} -\def_new:Npn \num_gset_eq:cc {\exp_args:Ncc \num_gset_eq:NN} -\def_new:Npn \num_add:Nn #1#2 {\num_set:Nn #1{#1+#2}} -\def_new:Npn \num_add:cn {\exp_args:Nc\num_add:Nn} -\def_new:Npn \num_gadd:Nn {\pref_global:D \num_add:Nn} -\def_new:Npn \num_gadd:cn {\exp_args:Nc\num_gadd:Nn} -\let_new:NN\num_use:N \use_arg_i:n -\let_new:NN\num_use:c \cs_use:c -\def_test_function_new:npn {num_compare:nNn}#1#2#3{ - \if_num:w \num_eval:n {#1}#2\num_eval:n {#3} -} -\def_new:Npn \num_compare:cNcTF { \exp_args:NcNc\num_compare:nNnTF } -\def_new:Npn \num_compare_p:nNn #1#2#3{ - \if_num:w \num_eval:n {#1}#2\num_eval:n {#3} - \c_true - \else: - \c_false - \fi: -} -\def_new:Npn \num_abs:n#1{ - \if_num:w \num_eval:n{#1}<\c_zero \exp_after:NN -\fi: #1 -} -\def_new:Npn \num_max_of:nn#1#2{\num_compare:nNnTF {#1}>{#2}{#1}{#2}} -\def_new:Npn \num_min_of:nn#1#2{\num_compare:nNnTF {#1}<{#2}{#1}{#2}} -\def_long_new:Npn \num_elt_count:n #1 { + 1 } -\def_long_new:Npn \num_elt_count_prop:Nn #1#2 { + 1 } +\cs_generate_variant:Nn\num_set:Nn {c} +\cs_new_nopar:Npn \num_gset:Nn {\pref_global:D \num_set:Nn} +\cs_generate_variant:Nn\num_gset:Nn {c} +\cs_new_eq:NN \num_set_eq:NN \tl_set_eq:NN +\cs_generate_variant:Nn\num_set_eq:NN {c,Nc,cc} +\cs_new_eq:NN \num_gset_eq:NN \tl_gset_eq:NN +\cs_generate_variant:Nn\num_gset_eq:NN {c,Nc,cc} +\cs_new_nopar:Npn \num_add:Nn #1#2 {\num_set:Nn #1{#1+#2}} +\cs_generate_variant:Nn\num_add:Nn {c} +\cs_new_nopar:Npn \num_gadd:Nn {\pref_global:D \num_add:Nn} +\cs_generate_variant:Nn\num_gadd:Nn {c} +\cs_new_eq:NN\num_use:N \use:n +\cs_new_eq:NN\num_use:c \use:c +\cs_new_eq:NN\num_show:N \cs_show:N +\cs_new_eq:NN\num_show:c \cs_show:c +\cs_new:Npn \num_elt_count:n #1 { + 1 } +\cs_new:Npn \num_elt_count_prop:Nn #1#2 { + 1 } \num_new:N \l_tmpa_num \num_new:N \l_tmpb_num \num_new:N \l_tmpc_num \num_new:N \g_tmpa_num \num_new:N \g_tmpb_num -\engine_if_aleph:TF -{ - \let_new:NN \const_new_aux:Nw \tex_chardef:D - \const_new_aux:Nw \c_max_register_num = 65535 \scan_stop: -} -{ - \let_new:NN \const_new_aux:Nw \tex_mathchardef:D - \const_new_aux:Nw \c_max_register_num = 32767 \scan_stop: -} -\def_new:Npn \const_new:Nn #1#2 { - \num_compare:nNnTF {#2} > \c_minus_one - { - \num_compare:nNnTF {#2} > \c_max_register_num - {\int_new:N #1 \int_set:Nn #1{#2}} - {\chk_new_cs:N #1 \const_new_aux:Nw #1 = #2 \scan_stop: } - } - {\int_new:N #1 \int_set:Nn #1{#2}} -} - %% \tex_countdef:D \c_minus_one = 10 \scan_stop: - %% \c_minus_one = -1 \scan_stop: %% in l3basics - %% \tex_chardef:D \c_sixteen = 16\scan_stop: %% in l3basics -\const_new:Nn \c_zero {0} -\const_new:Nn \c_one {1} -\const_new:Nn \c_two {2} -\const_new:Nn \c_three {3} -\const_new:Nn \c_four {4} -\const_new:Nn \c_six {6} -\const_new:Nn \c_seven {7} -\const_new:Nn \c_nine {9} -\const_new:Nn \c_ten {10} -\const_new:Nn \c_eleven {11} -\const_new:Nn \c_thirty_two {32} -\const_new:Nn \c_hundred_one {101} -\const_new:Nn \c_twohundred_fifty_five {255} -\const_new:Nn \c_twohundred_fifty_six {256} -\const_new:Nn \c_thousand {1000} -\const_new:Nn \c_ten_thousand {10000} -\const_new:Nn \c_ten_thousand_one {10001} -\const_new:Nn \c_ten_thousand_two {10002} -\const_new:Nn \c_ten_thousand_three {10003} -\const_new:Nn \c_ten_thousand_four {10004} -\const_new:Nn \c_twenty_thousand {20000} +\tex_mathchardef:D \c_max_register_num = 32767 \scan_stop: %% %% %% End of file `l3num.sty'. diff --git a/Master/texmf-dist/tex/latex/expl3/l3precom.sty b/Master/texmf-dist/tex/latex/expl3/l3precom.sty index 39bf566c3f8..c8a07a52680 100644 --- a/Master/texmf-dist/tex/latex/expl3/l3precom.sty +++ b/Master/texmf-dist/tex/latex/expl3/l3precom.sty @@ -15,7 +15,7 @@ %% Do not distribute a modified version of this file. %% %% -%% File: l3precom.dtx Copyright (C) 1990-2006 Frank Mittelbach, LaTeX3 project +%% File: l3precom.dtx Copyright (C) 1990-2006,2009 Frank Mittelbach, LaTeX3 project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this @@ -33,7 +33,7 @@ %% %% The development version of the bundle can be found at %% -%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/ +%% http://www.latex-project.org/svnroot/experimental/trunk/ %% %% for those people who are interested. %% @@ -48,7 +48,7 @@ %% %% ----------------------------------------------------------------------- \RequirePackage{l3names} -\GetIdInfo$Id: l3precom.dtx 621 2007-09-01 20:14:19Z morten $ +\GetIdInfo$Id: l3precom.dtx 1362 2009-05-28 20:19:21Z joseph $ {L3 Experimental precompilation module} \ProvidesExplPackage {\filename}{\filedate}{\fileversion}{\filedescription} @@ -57,83 +57,83 @@ \RequirePackage{l3seq} \RequirePackage{l3int} \iow_new:N\c_cs_dump_stream -\tlp_new:Nn\g_cs_dump_name_tlp{} +\tl_new:Nn\g_cs_dump_name_tl{} \seq_new:N\g_cs_dump_seq -\def_new:Npn\cs_record_name:N#1{ +\cs_new_nopar:Npn\cs_record_name:N#1{ \seq_gput_left:Nn \g_cs_trace_seq#1 \seq_gput_left:Nn \g_cs_dump_seq#1} -\def_new:Npn\cs_record_name:c{\exp_args:Nc\cs_record_name:N} -\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} -\iow_expanded:Nn\c_cs_dump_stream +\cs_generate_variant:Nn \cs_record_name:N {c} +\cs_new_nopar:Npn\cs_dump:{ +\iow_term:x{Precompiling~style~into~(\g_cs_dump_name_tl)} +\iow_open:Nn\c_cs_dump_stream{\g_cs_dump_name_tl} +\iow_now:Nx\c_cs_dump_stream {\group_begin: -\tex_catcode:D`\token_to_string:N\*=11\scan_stop: -\token_to_string:N\CodeStart +\tex_catcode:D`\token_to_str:N\*=11\scan_stop: +\token_to_str:N\ExplSyntaxOn } \seq_map_inline:Nn \g_cs_dump_seq {\tex_message:D{.} -\iow_expanded:Nn\c_cs_dump_stream - {\exp_not:n{\gdef:Npn ##1} - {\tlp_to_str:N##1}} +\iow_now:Nx\c_cs_dump_stream + {\exp_not:n{\cs_gset_nopar:Npn ##1} + {\tl_to_str:N##1}} } -\iow_expanded:Nn \c_cs_dump_stream {\exp_not:n{\num_gset:Nn +\iow_now:Nx \c_cs_dump_stream {\exp_not:n{\num_gset:Nn \g_gen_sym_num} {\num_use:N\g_gen_sym_num}^^J \exp_not:n{\num_gset:Nn \g_ggen_sym_num} {\num_use:N\g_ggen_sym_num}} -\iow_expanded:Nn +\iow_now:Nx \c_cs_dump_stream {\group_end:} \iow_close:N\c_cs_dump_stream \tex_message:D{~finished} } -\def_new:Npn\cs_load_dump:n#1{ +\cs_new_nopar:Npn\cs_load_dump:n#1{ \file_not_found:nTF{#1.cmp} -{\tlp_gset:Nn\g_cs_dump_name_tlp{#1.cmp}} +{\tl_gset:Nn\g_cs_dump_name_tl{#1.cmp}} {\input{#1.cmp} -\let:NN\cs_dump:\fi: +\cs_set_eq:NN\cs_dump:\fi: \if_false:}} \num_new:N\g_gen_sym_num \num_gset:Nn\g_gen_sym_num{0} \num_new:N\g_ggen_sym_num \num_gset:Nn\g_ggen_sym_num{0} -\def_new:Npn\cs_gen_sym:N#1{ +\cs_new_nopar:Npn\cs_gen_sym:N#1{ \num_gincr:N\g_gen_sym_num -\tlp_set:Nc#1{l*\tex_romannumeral:D\num_use:N\g_gen_sym_num} -\exp_after:NN\cs_record_name:N#1 -\exp_after:NN\tlp_clear_new:N#1} -\def_new:Npn\cs_ggen_sym:N#1{ +\tl_set:Nc#1{l*\tex_romannumeral:D\num_use:N\g_gen_sym_num} +\exp_after:wN\cs_record_name:N#1 +\exp_after:wN\tl_clear_new:N#1} +\cs_new_nopar:Npn\cs_ggen_sym:N#1{ \num_gincr:N\g_ggen_sym_num -\tlp_set:Nc#1{g*\tex_romannumeral:D\num_use:N\g_ggen_sym_num} -\exp_after:NN\cs_record_name:N#1 -\exp_after:NN\tlp_clear_new:N#1} +\tl_set:Nc#1{g*\tex_romannumeral:D\num_use:N\g_ggen_sym_num} +\exp_after:wN\cs_record_name:N#1 +\exp_after:wN\tl_clear_new:N#1} \seq_new:N\g_cs_trace_seq \seq_new:N\g_register_trace_seq -\def:Npn\cs_record_meaning:N#1{ +\cs_set_nopar:Npn\cs_record_meaning:N#1{ \seq_gput_left:Nn \g_cs_trace_seq#1} -\def:Npn\register_record_name:N#1{ +\cs_set_nopar:Npn\register_record_name:N#1{ \seq_gput_left:Nn \g_register_trace_seq#1} -\def_new:Npn\dumpLaTeXstate#1{ - \iow_expanded_term:n{Dumping~commands~into~(#1.dmp)} +\cs_new_nopar:Npn\dumpLaTeXstate#1{ + \iow_term:x{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~ + \iow_now:Nx\c_cs_dump_stream + {\token_to_str: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} + \iow_now:Nx\c_cs_dump_stream + {\token_to_str:N##1 + \toks_use:N##1} } \tex_message:D{~finished} } diff --git a/Master/texmf-dist/tex/latex/expl3/l3prg.sty b/Master/texmf-dist/tex/latex/expl3/l3prg.sty index 7cc170fef4f..d696e412e06 100644 --- a/Master/texmf-dist/tex/latex/expl3/l3prg.sty +++ b/Master/texmf-dist/tex/latex/expl3/l3prg.sty @@ -15,7 +15,7 @@ %% Do not distribute a modified version of this file. %% %% -%% File: l3prg.dtx Copyright (C) 2005-2006 LaTeX3 project +%% File: l3prg.dtx Copyright (C) 2005-2009 LaTeX3 project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this @@ -33,7 +33,7 @@ %% %% The development version of the bundle can be found at %% -%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/ +%% http://www.latex-project.org/svnroot/experimental/trunk/ %% %% for those people who are interested. %% @@ -48,301 +48,325 @@ %% %% ----------------------------------------------------------------------- \RequirePackage{l3names} -\GetIdInfo$Id: l3prg.dtx 768 2008-08-05 19:45:06Z morten $ +\GetIdInfo$Id: l3prg.dtx 1365 2009-05-31 17:26:17Z mittelba $ {L3 Experimental control structures} \ProvidesExplPackage {\filename}{\filedate}{\fileversion}{\filedescription} -\RequirePackage{l3quark} -\RequirePackage{l3toks} -\RequirePackage{l3int} -\def_new:Npn \mode_if_vertical_p: { - \if_mode_vertical: \c_true \else: \c_false\fi:} -\def_test_function_new:npn{mode_if_vertical:}{\if_mode_vertical:} -\def_new:Npn \mode_if_horizontal_p: { - \if_mode_horizontal: \c_true \else: \c_false\fi:} -\def_test_function_new:npn{mode_if_horizontal:}{\if_mode_horizontal:} -\def_new:Npn \mode_if_inner_p: { - \if_mode_inner: \c_true \else: \c_false\fi:} -\def_test_function_new:npn{mode_if_inner:}{\if_mode_inner:} -\def_test_function_new:npn{mode_if_math:} { - \scan_align_safe_stop: \if_mode_math: } -\def_new:Npn \group_align_safe_begin: { +\package_check_loaded_expl: +\prg_set_conditional:Npnn \mode_if_vertical: {p,TF,T,F}{ + \if_mode_vertical: + \prg_return_true: \else: \prg_return_false: \fi: +} +\prg_set_conditional:Npnn \mode_if_horizontal: {p,TF,T,F}{ + \if_mode_horizontal: + \prg_return_true: \else: \prg_return_false: \fi: +} +\prg_set_conditional:Npnn \mode_if_inner: {p,TF,T,F}{ + \if_mode_inner: + \prg_return_true: \else: \prg_return_false: \fi: +} +\prg_set_conditional:Npnn \mode_if_math: {p,TF,T,F}{ + \scan_align_safe_stop: \if_mode_math: + \prg_return_true: \else: \prg_return_false: \fi: +} +\cs_new_nopar:Npn \group_align_safe_begin: { \if_false:{\fi:\if_num:w`}=\c_zero\fi:} -\def_new:Npn \group_align_safe_end: {\if_num:w`{=\c_zero}\fi:} -\def_new:Npn \scan_align_safe_stop: { - \num_compare:nNnT \etex_currentgrouptype:D = \c_six +\cs_new_nopar:Npn \group_align_safe_end: {\if_num:w`{=\c_zero}\fi:} +\cs_new_nopar:Npn \scan_align_safe_stop: { + \intexpr_compare:nNnT \etex_currentgrouptype:D = \c_six { - \num_compare:nNnF \etex_lastnodetype:D = \c_zero + \intexpr_compare:nNnF \etex_lastnodetype:D = \c_zero { - \num_compare:nNnF \etex_lastnodetype:D = \c_seven + \intexpr_compare:nNnF \etex_lastnodetype:D = \c_seven \scan_stop: } } } -\def_new:Npn \prg_replicate:nn #1{ - \cs:w use_noop: - \exp_after:NN\prg_replicate_first_aux:N - \int_use:N \int_eval:n{#1} \cs_end: +\cs_new_nopar:Npn \prg_replicate:nn #1{ + \cs:w prg_do_nothing: + \exp_after:wN\prg_replicate_first_aux:N + \tex_romannumeral:D -`\q \intexpr_eval:n{#1} \cs_end: \cs_end: } -\def_new:Npn \prg_replicate_aux:N#1{ +\cs_new_nopar:Npn \prg_replicate_aux:N#1{ \cs:w prg_replicate_#1:n\prg_replicate_aux:N } -\def_new:Npn \prg_replicate_first_aux:N#1{ +\cs_new_nopar:Npn \prg_replicate_first_aux:N#1{ \cs:w prg_replicate_first_#1:n\prg_replicate_aux:N } -\def_new:Npn \prg_replicate_ :n #1{}% no, this is not a typo! -\def_long_new:cpn {prg_replicate_0:n}#1{\cs_end:{#1#1#1#1#1#1#1#1#1#1}} -\def_long_new:cpn {prg_replicate_1:n}#1{\cs_end:{#1#1#1#1#1#1#1#1#1#1}#1} -\def_long_new:cpn {prg_replicate_2:n}#1{\cs_end:{#1#1#1#1#1#1#1#1#1#1}#1#1} -\def_long_new:cpn {prg_replicate_3:n}#1{ +\cs_new_nopar:Npn \prg_replicate_ :n #1{}% no, this is not a typo! +\cs_new:cpn {prg_replicate_0:n}#1{\cs_end:{#1#1#1#1#1#1#1#1#1#1}} +\cs_new:cpn {prg_replicate_1:n}#1{\cs_end:{#1#1#1#1#1#1#1#1#1#1}#1} +\cs_new:cpn {prg_replicate_2:n}#1{\cs_end:{#1#1#1#1#1#1#1#1#1#1}#1#1} +\cs_new:cpn {prg_replicate_3:n}#1{ \cs_end:{#1#1#1#1#1#1#1#1#1#1}#1#1#1} -\def_long_new:cpn {prg_replicate_4:n}#1{ +\cs_new:cpn {prg_replicate_4:n}#1{ \cs_end:{#1#1#1#1#1#1#1#1#1#1}#1#1#1#1} -\def_long_new:cpn {prg_replicate_5:n}#1{ +\cs_new:cpn {prg_replicate_5:n}#1{ \cs_end:{#1#1#1#1#1#1#1#1#1#1}#1#1#1#1#1} -\def_long_new:cpn {prg_replicate_6:n}#1{ +\cs_new:cpn {prg_replicate_6:n}#1{ \cs_end:{#1#1#1#1#1#1#1#1#1#1}#1#1#1#1#1#1} -\def_long_new:cpn {prg_replicate_7:n}#1{ +\cs_new:cpn {prg_replicate_7:n}#1{ \cs_end:{#1#1#1#1#1#1#1#1#1#1}#1#1#1#1#1#1#1} -\def_long_new:cpn {prg_replicate_8:n}#1{ +\cs_new:cpn {prg_replicate_8:n}#1{ \cs_end:{#1#1#1#1#1#1#1#1#1#1}#1#1#1#1#1#1#1#1} -\def_long_new:cpn {prg_replicate_9:n}#1{ +\cs_new:cpn {prg_replicate_9:n}#1{ \cs_end:{#1#1#1#1#1#1#1#1#1#1}#1#1#1#1#1#1#1#1#1} -\def_long_new:cpn {prg_replicate_first_0:n}#1{\cs_end: } -\def_long_new:cpn {prg_replicate_first_1:n}#1{\cs_end: #1} -\def_long_new:cpn {prg_replicate_first_2:n}#1{\cs_end: #1#1} -\def_long_new:cpn {prg_replicate_first_3:n}#1{\cs_end: #1#1#1} -\def_long_new:cpn {prg_replicate_first_4:n}#1{\cs_end: #1#1#1#1} -\def_long_new:cpn {prg_replicate_first_5:n}#1{\cs_end: #1#1#1#1#1} -\def_long_new:cpn {prg_replicate_first_6:n}#1{\cs_end: #1#1#1#1#1#1} -\def_long_new:cpn {prg_replicate_first_7:n}#1{\cs_end: #1#1#1#1#1#1#1} -\def_long_new:cpn {prg_replicate_first_8:n}#1{\cs_end: #1#1#1#1#1#1#1#1} -\def_long_new:cpn {prg_replicate_first_9:n}#1{\cs_end: #1#1#1#1#1#1#1#1#1} -\def_long_new:NNn \prg_stepwise_function:nnnN 2{ - \num_compare:nNnTF{#2}<\c_zero - {\exp_args:No\prg_stepwise_function_decr:nnnN } - {\exp_args:No\prg_stepwise_function_incr:nnnN } - {\int_use:N\int_eval:n{#1}}{#2} -} -\def_long_new:NNn \prg_stepwise_function_incr:nnnN 4{ - \num_compare:nNnF {#1}>{#3} +\cs_new:cpn {prg_replicate_first_0:n}#1{\cs_end: } +\cs_new:cpn {prg_replicate_first_1:n}#1{\cs_end: #1} +\cs_new:cpn {prg_replicate_first_2:n}#1{\cs_end: #1#1} +\cs_new:cpn {prg_replicate_first_3:n}#1{\cs_end: #1#1#1} +\cs_new:cpn {prg_replicate_first_4:n}#1{\cs_end: #1#1#1#1} +\cs_new:cpn {prg_replicate_first_5:n}#1{\cs_end: #1#1#1#1#1} +\cs_new:cpn {prg_replicate_first_6:n}#1{\cs_end: #1#1#1#1#1#1} +\cs_new:cpn {prg_replicate_first_7:n}#1{\cs_end: #1#1#1#1#1#1#1} +\cs_new:cpn {prg_replicate_first_8:n}#1{\cs_end: #1#1#1#1#1#1#1#1} +\cs_new:cpn {prg_replicate_first_9:n}#1{\cs_end: #1#1#1#1#1#1#1#1#1} +\cs_new:Npn \prg_stepwise_function:nnnN #1#2{ + \intexpr_compare:nNnTF{#2}<\c_zero + {\exp_args:Nf\prg_stepwise_function_decr:nnnN } + {\exp_args:Nf\prg_stepwise_function_incr:nnnN } + {\intexpr_eval:n{#1}}{#2} +} +\cs_new:Npn \prg_stepwise_function_incr:nnnN #1#2#3#4{ + \intexpr_compare:nNnF {#1}>{#3} { #4{#1} - \exp_args:No \prg_stepwise_function_incr:nnnN - {\int_use:N\int_eval:n{#1 + #2}} + \exp_args:Nf \prg_stepwise_function_incr:nnnN + {\intexpr_eval:n{#1 + #2}} {#2}{#3}{#4} } } -\def_long_new:NNn \prg_stepwise_function_decr:nnnN 4{ - \num_compare:nNnF {#1}<{#3} +\cs_new:Npn \prg_stepwise_function_decr:nnnN #1#2#3#4{ + \intexpr_compare:nNnF {#1}<{#3} { #4{#1} - \exp_args:No \prg_stepwise_function_decr:nnnN - {\int_use:N\int_eval:n{#1 + #2}} + \exp_args:Nf \prg_stepwise_function_decr:nnnN + {\intexpr_eval:n{#1 + #2}} {#2}{#3}{#4} } } \int_new:N\g_prg_inline_level_int -\def_long_new:NNn\prg_stepwise_inline:nnnn 4{ +\cs_new:Npn\prg_stepwise_inline:nnnn #1#2#3#4{ \int_gincr:N \g_prg_inline_level_int - \gdef:cpn{prg_stepwise_inline_\int_use:N\g_prg_inline_level_int :n}##1{#4} - \num_compare:nNnTF {#2}<\c_zero - {\exp_args:Nco \prg_stepwise_inline_decr:Nnnn } - {\exp_args:Nco \prg_stepwise_inline_incr:Nnnn } + \cs_gset_nopar:cpn{prg_stepwise_inline_\int_use:N\g_prg_inline_level_int :n}##1{#4} + \intexpr_compare:nNnTF {#2}<\c_zero + {\exp_args:Ncf \prg_stepwise_inline_decr:Nnnn } + {\exp_args:Ncf \prg_stepwise_inline_incr:Nnnn } {prg_stepwise_inline_\int_use:N\g_prg_inline_level_int :n} - {\int_use:N\int_eval:n{#1}} {#2} {#3} + {\intexpr_eval:n{#1}} {#2} {#3} \int_gdecr:N \g_prg_inline_level_int } -\def_long_new:NNn \prg_stepwise_inline_incr:Nnnn 4{ - \num_compare:nNnF {#2}>{#4} +\cs_new:Npn \prg_stepwise_inline_incr:Nnnn #1#2#3#4{ + \intexpr_compare:nNnF {#2}>{#4} { #1{#2} - \exp_args:NNo \prg_stepwise_inline_incr:Nnnn #1 - {\int_use:N\int_eval:n{#2 + #3}} {#3}{#4} + \exp_args:NNf \prg_stepwise_inline_incr:Nnnn #1 + {\intexpr_eval:n{#2 + #3}} {#3}{#4} } } -\def_long_new:NNn \prg_stepwise_inline_decr:Nnnn 4{ - \num_compare:nNnF {#2}<{#4} +\cs_new:Npn \prg_stepwise_inline_decr:Nnnn #1#2#3#4{ + \intexpr_compare:nNnF {#2}<{#4} { #1{#2} - \exp_args:NNo \prg_stepwise_inline_decr:Nnnn #1 - {\int_use:N\int_eval:n{#2 + #3}} {#3}{#4} + \exp_args:NNf \prg_stepwise_inline_decr:Nnnn #1 + {\intexpr_eval:n{#2 + #3}} {#3}{#4} } } -\def_long_new:NNn \prg_stepwise_variable:nnnNn 2 { - \num_compare:nNnTF {#2}<\c_zero - {\exp_args:No\prg_stepwise_variable_decr:nnnNn} - {\exp_args:No\prg_stepwise_variable_incr:nnnNn} - {\int_use:N\int_eval:n{#1}}{#2} +\cs_new:Npn \prg_stepwise_variable:nnnNn #1#2 { + \intexpr_compare:nNnTF {#2}<\c_zero + {\exp_args:Nf\prg_stepwise_variable_decr:nnnNn} + {\exp_args:Nf\prg_stepwise_variable_incr:nnnNn} + {\intexpr_eval:n{#1}}{#2} } -\def_long_new:NNn \prg_stepwise_variable_incr:nnnNn 5 { - \num_compare:nNnF {#1}>{#3} +\cs_new:Npn \prg_stepwise_variable_incr:nnnNn #1#2#3#4#5 { + \intexpr_compare:nNnF {#1}>{#3} { - \def:Npn #4{#1} #5 - \exp_args:No \prg_stepwise_variable_incr:nnnNn - {\int_use:N\int_eval:n{#1 + #2}}{#2}{#3}#4{#5} + \cs_set_nopar:Npn #4{#1} #5 + \exp_args:Nf \prg_stepwise_variable_incr:nnnNn + {\intexpr_eval:n{#1 + #2}}{#2}{#3}#4{#5} } } -\def_long_new:NNn \prg_stepwise_variable_decr:nnnNn 5 { - \num_compare:nNnF {#1}<{#3} +\cs_new:Npn \prg_stepwise_variable_decr:nnnNn #1#2#3#4#5 { + \intexpr_compare:nNnF {#1}<{#3} { - \def:Npn #4{#1} #5 - \exp_args:No \prg_stepwise_variable_decr:nnnNn - {\int_use:N\int_eval:n{#1 + #2}}{#2}{#3}#4{#5} + \cs_set_nopar:Npn #4{#1} #5 + \exp_args:Nf \prg_stepwise_variable_decr:nnnNn + {\intexpr_eval:n{#1 + #2}}{#2}{#3}#4{#5} } } -\def_new:Npn \bool_new:N #1 { \let_new:NN #1 \c_false } -\def_new:Npn \bool_new:c #1 { \let_new:cN {#1} \c_false } -\def_new:Npn \bool_set_true:N #1 { \let:NN #1 \c_true } -\def_new:Npn \bool_set_true:c #1 { \let:cN {#1} \c_true } -\def_new:Npn \bool_set_false:N #1 { \let:NN #1 \c_false } -\def_new:Npn \bool_set_false:c #1 { \let:cN {#1} \c_false } -\def_new:Npn \bool_gset_true:N #1 { \glet:NN #1 \c_true } -\def_new:Npn \bool_gset_true:c #1 { \glet:cN {#1} \c_true } -\def_new:Npn \bool_gset_false:N #1 { \glet:NN #1 \c_false } -\def_new:Npn \bool_gset_false:c #1 { \glet:cN {#1} \c_false } -\let_new:NN \bool_set_eq:NN \let:NN -\let_new:NN \bool_set_eq:Nc \let:Nc -\let_new:NN \bool_set_eq:cN \let:cN -\let_new:NN \bool_set_eq:cc \let:cc -\let_new:NN \bool_gset_eq:NN \glet:NN -\let_new:NN \bool_gset_eq:Nc \glet:Nc -\let_new:NN \bool_gset_eq:cN \glet:cN -\let_new:NN \bool_gset_eq:cc \glet:cc +\cs_new_nopar:Npn \bool_new:N #1 { \cs_new_eq:NN #1 \c_false_bool } +\cs_new_nopar:Npn \bool_new:c #1 { \cs_new_eq:cN {#1} \c_false_bool } +\cs_new_nopar:Npn \bool_set_true:N #1 { \cs_set_eq:NN #1 \c_true_bool } +\cs_new_nopar:Npn \bool_set_true:c #1 { \cs_set_eq:cN {#1} \c_true_bool } +\cs_new_nopar:Npn \bool_set_false:N #1 { \cs_set_eq:NN #1 \c_false_bool } +\cs_new_nopar:Npn \bool_set_false:c #1 { \cs_set_eq:cN {#1} \c_false_bool } +\cs_new_nopar:Npn \bool_gset_true:N #1 { \cs_gset_eq:NN #1 \c_true_bool } +\cs_new_nopar:Npn \bool_gset_true:c #1 { \cs_gset_eq:cN {#1} \c_true_bool } +\cs_new_nopar:Npn \bool_gset_false:N #1 { \cs_gset_eq:NN #1 \c_false_bool } +\cs_new_nopar:Npn \bool_gset_false:c #1 { \cs_gset_eq:cN {#1} \c_false_bool } +\cs_new_eq:NN \bool_set_eq:NN \cs_set_eq:NN +\cs_new_eq:NN \bool_set_eq:Nc \cs_set_eq:Nc +\cs_new_eq:NN \bool_set_eq:cN \cs_set_eq:cN +\cs_new_eq:NN \bool_set_eq:cc \cs_set_eq:cc +\cs_new_eq:NN \bool_gset_eq:NN \cs_gset_eq:NN +\cs_new_eq:NN \bool_gset_eq:Nc \cs_gset_eq:Nc +\cs_new_eq:NN \bool_gset_eq:cN \cs_gset_eq:cN +\cs_new_eq:NN \bool_gset_eq:cc \cs_gset_eq:cc \bool_new:N \l_tmpa_bool \bool_new:N \g_tmpa_bool -\def_test_function_new:npn{bool_if:N}#1{\if:w #1} -\def_new:Npn \bool_if:cTF{\exp_args:Nc\bool_if:NTF} -\def_new:Npn \bool_if:cT{\exp_args:Nc\bool_if:NT} -\def_new:Npn \bool_if:cF{\exp_args:Nc\bool_if:NF} -\def_new:Npn \bool_if_p:N #1 { #1 } -\let_new:NN \bool_if_p:c \cs_use:c -\def_long_new:Npn \bool_whiledo:NT #1 #2 { - \bool_if:NT #1 {#2 \bool_whiledo:NT #1 {#2}} -} -\def_new:Npn \bool_whiledo:cT{\exp_args:Nc\bool_whiledo:NT} -\def_long_new:Npn \bool_whiledo:NF #1 #2 { - \bool_if:NF #1 {#2 \bool_whiledo:NF #1 {#2}} -} -\def_new:Npn \bool_whiledo:cF{\exp_args:Nc\bool_whiledo:NF} -\def_long_new:Npn \bool_dowhile:NT #1 #2 { - #2 \bool_if:NT #1 {\bool_dowhile:NT #1 {#2}} -} -\def_new:Npn \bool_dowhile:cT{\exp_args:Nc\bool_dowhile:NT} -\def_long_new:Npn \bool_dowhile:NF #1 #2 { - #2 \bool_if:NF #1 {\bool_dowhile:NF #1 {#2}} -} -\def_new:Npn \bool_dowhiledo:cF{\exp_args:Nc\bool_dowhile:cF} -\def_new:Npn \bool_double_if:NNnnnn#1#2{ - \if_case:w \num_eval:w #1\scan_stop: - \if_case:w \num_eval:w #2\scan_stop: - \exp_after:NN\exp_after:NN\exp_after:NN \use_arg_i:nnnn - \else: - \exp_after:NN\exp_after:NN\exp_after:NN \use_arg_ii:nnnn - \fi: - \else: - \if_case:w \num_eval:w #2\scan_stop: - \exp_after:NN\exp_after:NN\exp_after:NN \use_arg_iii:nnnn - \else: - \exp_after:NN\exp_after:NN\exp_after:NN \use_arg_iv:nnnn - \fi: - \fi: -} -\def_new:Npn \bool_double_if:cNnnnn{\exp_args:Nc\bool_double_if:NNnnnn} -\def_new:Npn \bool_double_if:Ncnnnn{\exp_args:NNc\bool_double_if:NNnnnn} -\def_new:Npn \bool_double_if:ccnnnn{\exp_args:Ncc\bool_double_if:NNnnnn} -\def_long_new:Npn \prg_whiledo:nT #1#2{ - #1 {#2 \prg_whiledo:nT {#1}{#2}} -} -\def_long_new:Npn \prg_whiledo:nF #1#2{ - #1 {#2 \prg_whiledo:nF {#1}{#2}} -} -\def_long_new:Npn \prg_dowhile:nT #1#2{ - #2 #1 {\prg_dowhile:nT {#1}{#2}} -} -\def_long_new:Npn \prg_dowhile:nF #1#2{ - #2 #1 {\prg_dowhile:nF {#1}{#2}} -} -\def_long_new:Npn \predicate_p:n #1{ +\prg_set_conditional:Npnn \bool_if:N #1 {p,TF,T,F}{ + \if_bool:N #1 \prg_return_true: \else: \prg_return_false: \fi: +} +\cs_generate_variant:Nn \bool_if_p:N {c} +\cs_generate_variant:Nn \bool_if:NTF {c} +\cs_generate_variant:Nn \bool_if:NT {c} +\cs_generate_variant:Nn \bool_if:NF {c} +\cs_new:Npn \bool_while_do:Nn #1 #2 { + \bool_if:NT #1 {#2 \bool_while_do:Nn #1 {#2}} +} +\cs_generate_variant:Nn \bool_while_do:Nn {c} +\cs_new:Npn \bool_until_do:Nn #1 #2 { + \bool_if:NF #1 {#2 \bool_until_do:Nn #1 {#2}} +} +\cs_generate_variant:Nn \bool_until_do:Nn {c} +\cs_new:Npn \bool_do_while:Nn #1 #2 { + #2 \bool_if:NT #1 {\bool_do_while:Nn #1 {#2}} +} +\cs_generate_variant:Nn \bool_do_while:Nn {c} +\cs_new:Npn \bool_do_until:Nn #1 #2 { + #2 \bool_if:NF #1 {\bool_do_until:Nn #1 {#2}} +} +\cs_generate_variant:Nn \bool_do_until:Nn {c} +\cs_set:Npn \bool_if_p:n #1{ \group_align_safe_begin: - \exp_after:NN \predicate_auxi:NN - \int_to_roman:w-`\q #1 02\scan_stop: + \bool_get_next:N ( #1 )S } -\def_long_test_function_new:npn {predicate:n}#1{ - \group_align_safe_begin: - \if:w \exp_after:NN \predicate_auxi:NN - \int_to_roman:w-`\q #1 02\scan_stop: +\cs_set:Npn \bool_get_next:N #1{ + \use:c { + bool_ + \if_meaning:w !#1 ! \else: \if_meaning:w (#1 ( \else: p \fi: \fi: + :w + } #1 } -\def_new:Npn \predicate_auxi:NN 0 #1{ - \exp_after:NN \predicate_auxii:NNN \exp_after:NN #1 +\cs_set:cpn {bool_!:w}#1{ + \exp_after:wN \intexpr_if_even_p:n \tex_number:D \bool_get_next:N +} +\cs_set:cpn {bool_(:w}#1{ + \exp_after:wN \bool_cleanup:N \tex_number:D \bool_get_next:N +} +\cs_set:cpn {bool_p:w}{\exp_after:wN \bool_cleanup:N \tex_number:D } +\cs_new_nopar:Npn \bool_cleanup:N #1{ + \exp_after:wN \bool_choose:NN \exp_after:wN #1 \int_to_roman:w-`\q } -\def_new:Npn \predicate_auxii:NNN #1#2#3{ - \cs_use:c{predicate_#2#3_#1:w} } -\def_new:cpn{predicate_&&_0:w}{ - \exp_after:NN \predicate_auxi:NN\int_to_roman:w-`\q -} -\def_long_new:cpn{predicate_&&_1:w} #1 02\scan_stop:{ - \group_align_safe_end: 01} -\def_long_new:cpn{predicate_||_0:w} #1 02\scan_stop:{ - \group_align_safe_end: 00} -\def_new:cpn{predicate_||_1:w}{ - \exp_after:NN \predicate_auxi:NN\int_to_roman:w-`\q -} -\def_new:cpn{predicate_02_0:w}\scan_stop:{ \group_align_safe_end: 00 } -\def_new:cpn{predicate_02_1:w}\scan_stop:{ \group_align_safe_end: 01 } -\def_long_new:Npn \predicate_not_p:n #1{ - \if:w \predicate_p:n{#1} \c_false \else: \c_true \fi: -} -\def_long:Npn \prg_case_int:nnn #1 #2 { - \exp_args:No \prg_case_int_aux:nnn {\num_value:w \int_eval:n{#1}} #2 +\cs_new_nopar:Npn \bool_choose:NN #1#2{ \use:c{bool_#2_#1:w} } +\cs_new_nopar:cpn{bool_&_1:w}&{\bool_get_next:N} +\cs_new_nopar:cpn{bool_|_0:w}|{\bool_get_next:N} +\cs_new_nopar:cpn{bool_)_0:w}{ \c_false_bool } +\cs_new_nopar:cpn{bool_)_1:w}{ \c_true_bool } +\cs_new_nopar:cpn{bool_S_0:w}{\group_align_safe_end: \c_false_bool } +\cs_new_nopar:cpn{bool_S_1:w}{\group_align_safe_end: \c_true_bool } +\cs_set:cpn{bool_&_0:w}&{\bool_eval_skip_to_end:Nw \c_false_bool} +\cs_set:cpn{bool_|_1:w}|{\bool_eval_skip_to_end:Nw \c_true_bool} +\cs_set:Npn \bool_eval_skip_to_end:Nw #1#2){ + \bool_eval_skip_to_end_aux:Nw #1 #2(\q_no_value\q_nil{#2} +} +\cs_set:Npn \bool_eval_skip_to_end_aux:Nw #1#2(#3#4\q_nil#5{ + \quark_if_no_value:NTF #3 + { #1 } + { \bool_eval_skip_to_end_auxii:Nw #1 #5 } +} +\cs_set:Npn \bool_eval_skip_to_end_auxii:Nw #1#2(#3){ + \bool_eval_skip_to_end:Nw #1#3 ) +} +\cs_new:Npn \bool_set:Nn #1#2 {\tex_chardef:D #1 = \bool_if_p:n {#2}} +\cs_new:Npn \bool_gset:Nn #1#2 { + \tex_global:D \tex_chardef:D #1 = \bool_if_p:n {#2} +} +\cs_generate_variant:Nn \bool_set:Nn {c} +\cs_generate_variant:Nn \bool_gset:Nn {c} +\cs_new:Npn \bool_not_p:n #1{ \bool_if_p:n{!(#1)} } +\cs_new:Npn \bool_xor_p:nn #1#2 { + \intexpr_compare:nNnTF {\bool_if_p:n { #1 }} = {\bool_if_p:n { #2 }} + {\c_false_bool}{\c_true_bool} +} +\prg_set_conditional:Npnn \bool_if:n #1 {TF,T,F}{ + \if_predicate:w \bool_if_p:n{#1} + \prg_return_true: \else: \prg_return_false: \fi: +} +\cs_new:Npn \bool_while_do:nn #1#2 { + \bool_if:nT {#1} { #2 \bool_while_do:nn {#1}{#2} } +} +\cs_new:Npn \bool_until_do:nn #1#2 { + \bool_if:nF {#1} { #2 \bool_until_do:nn {#1}{#2} } +} +\cs_new:Npn \bool_do_while:nn #1#2 { + #2 \bool_if:nT {#1} { \bool_do_while:nn {#1}{#2} } +} +\cs_new:Npn \bool_do_until:nn #1#2 { + #2 \bool_if:nF {#1} { \bool_do_until:nn {#1}{#2} } +} +\cs_new:Npn \prg_case_int:nnn #1 #2 { + \exp_args:Nf \prg_case_int_aux:nnn { \intexpr_eval:n{#1}} #2 \q_recursion_tail ? \q_recursion_stop } -\def_long_new:Npn \prg_case_int_aux:nnn #1#2#3{ - \quark_if_recursion_tail_stop_do:nn{#2}{\use_arg_i:n} - \num_compare:nNnTF{#1}={#2} - { \use_arg_i_delimit_by_q_recursion_stop:nw {\use_arg_i:nn{#3}} } +\cs_new:Npn \prg_case_int_aux:nnn #1#2#3{ + \quark_if_recursion_tail_stop_do:nn{#2}{\use:n} + \intexpr_compare:nNnTF{#1}={#2} + { \prg_end_case:nw {#3} } { \prg_case_int_aux:nnn {#1}} } -\def_long:Npn \prg_case_dim:nnn #1 #2 { +\cs_new:Npn \prg_case_dim:nnn #1 #2 { \exp_args:No \prg_case_dim_aux:nnn {\dim_use:N \dim_eval:n{#1}} #2 \q_recursion_tail ? \q_recursion_stop } -\def_long_new:Npn \prg_case_dim_aux:nnn #1#2#3{ - \quark_if_recursion_tail_stop_do:nn{#2}{\use_arg_i:n} +\cs_new:Npn \prg_case_dim_aux:nnn #1#2#3{ + \quark_if_recursion_tail_stop_do:nn{#2}{\use:n} \dim_compare:nNnTF{#1}={#2} - { \use_arg_i_delimit_by_q_recursion_stop:nw {\use_arg_i:nn{#3}} } + { \prg_end_case:nw {#3} } { \prg_case_dim_aux:nnn {#1}} } -\def_long:Npn \prg_case_str:nnn #1 #2 { +\cs_new:Npn \prg_case_str:nnn #1 #2 { \prg_case_str_aux:nnn {#1} #2 \q_recursion_tail ? \q_recursion_stop } -\def_long_new:Npn \prg_case_str_aux:nnn #1#2#3{ - \quark_if_recursion_tail_stop_do:nn{#2}{\use_arg_i:n} - \tlist_if_eq:xxTF{#1}{#2} - { \use_arg_i_delimit_by_q_recursion_stop:nw {\use_arg_i:nn{#3}} } +\cs_new:Npn \prg_case_str_aux:nnn #1#2#3{ + \quark_if_recursion_tail_stop_do:nn{#2}{\use:n} + \tl_if_eq:xxTF{#1}{#2} + { \prg_end_case:nw {#3} } { \prg_case_str_aux:nnn {#1}} } -\def_new:NNn \prg_define_quicksort:nnn 3 { - \def_long:cNx{#1_quicksort:n}1{ +\cs_new:Npn \prg_case_tl:Nnn #1 #2 { + \prg_case_tl_aux:NNn #1 #2 + \q_recursion_tail ? \q_recursion_stop +} +\cs_new:Npn \prg_case_tl_aux:NNn #1#2#3{ + \quark_if_recursion_tail_stop_do:Nn #2{\use:n} + \tl_if_eq:NNTF #1 #2 + { \prg_end_case:nw {#3} } + { \prg_case_tl_aux:NNn #1} +} +\cs_new:Npn \prg_end_case:nw #1#2\q_recursion_stop#3{#1} + +\cs_new_nopar:Npn \prg_define_quicksort:nnn #1#2#3 { + \cs_set:cpx{#1_quicksort:n}##1{ \exp_not:c{#1_quicksort_start_partition:w} ##1 \exp_not:n{#2\q_nil#3\q_stop} } - \def_long:cNx{#1_quicksort_braced:n}1{ + \cs_set:cpx{#1_quicksort_braced:n}##1{ \exp_not:c{#1_quicksort_start_partition_braced:n} ##1 \exp_not:N\q_nil\exp_not:N\q_stop } - \def_long:cpx {#1_quicksort_start_partition:w} #2 ##1 #3{ + \cs_set:cpx {#1_quicksort_start_partition:w} #2 ##1 #3{ \exp_not:N \quark_if_nil:nT {##1}\exp_not:N \use_none_delimit_by_q_stop:w \exp_not:c{#1_quicksort_do_partition_i:nnnw} {##1}{}{} } - \def_long:cNx {#1_quicksort_start_partition_braced:n} 1 { + \cs_set:cpx {#1_quicksort_start_partition_braced:n} ##1 { \exp_not:N \quark_if_nil:nT {##1}\exp_not:N \use_none_delimit_by_q_stop:w \exp_not:c{#1_quicksort_do_partition_i_braced:nnnn} {##1}{}{} } - \def_long:cpx {#1_quicksort_do_partition_i:nnnw} ##1##2##3 #2 ##4 #3 { + \cs_set:cpx {#1_quicksort_do_partition_i:nnnw} ##1##2##3 #2 ##4 #3 { \exp_not:N \quark_if_nil:nTF {##4} \exp_not:c {#1_do_quicksort_braced:nnnnw} { \exp_not:c{#1_quicksort_compare:nnTF}{##1}{##4} @@ -351,7 +375,7 @@ } {##1}{##2}{##3}{##4} } - \def_long:cNx {#1_quicksort_do_partition_i_braced:nnnn} 4 { + \cs_set:cpx {#1_quicksort_do_partition_i_braced:nnnn} ##1##2##3##4 { \exp_not:N \quark_if_nil:nTF {##4} \exp_not:c {#1_do_quicksort_braced:nnnnw} { \exp_not:c{#1_quicksort_compare:nnTF}{##1}{##4} @@ -360,7 +384,7 @@ } {##1}{##2}{##3}{##4} } - \def_long:cpx {#1_quicksort_do_partition_ii:nnnw} ##1##2##3 #2 ##4 #3 { + \cs_set:cpx {#1_quicksort_do_partition_ii:nnnw} ##1##2##3 #2 ##4 #3 { \exp_not:N \quark_if_nil:nTF {##4} \exp_not:c {#1_do_quicksort_braced:nnnnw} { \exp_not:c{#1_quicksort_compare:nnTF}{##4}{##1} @@ -369,7 +393,7 @@ } {##1}{##2}{##3}{##4} } - \def_long:cNx {#1_quicksort_do_partition_ii_braced:nnnn} 4 { + \cs_set:cpx {#1_quicksort_do_partition_ii_braced:nnnn} ##1##2##3##4 { \exp_not:N \quark_if_nil:nTF {##4} \exp_not:c {#1_do_quicksort_braced:nnnnw} { \exp_not:c{#1_quicksort_compare:nnTF}{##4}{##1} @@ -378,31 +402,31 @@ } {##1}{##2}{##3}{##4} } - \def_long:cNx {#1_quicksort_partition_less_i:nnnn} 4{ + \cs_set:cpx {#1_quicksort_partition_less_i:nnnn} ##1##2##3##4{ \exp_not:c{#1_quicksort_do_partition_i:nnnw}{##1}{##2}{{##4}##3}} - \def_long:cNx {#1_quicksort_partition_less_ii:nnnn} 4{ + \cs_set:cpx {#1_quicksort_partition_less_ii:nnnn} ##1##2##3##4{ \exp_not:c{#1_quicksort_do_partition_ii:nnnw}{##1}{##2}{##3{##4}}} - \def_long:cNx {#1_quicksort_partition_greater_i:nnnn} 4{ + \cs_set:cpx {#1_quicksort_partition_greater_i:nnnn} ##1##2##3##4{ \exp_not:c{#1_quicksort_do_partition_i:nnnw}{##1}{{##4}##2}{##3}} - \def_long:cNx {#1_quicksort_partition_greater_ii:nnnn} 4{ + \cs_set:cpx {#1_quicksort_partition_greater_ii:nnnn} ##1##2##3##4{ \exp_not:c{#1_quicksort_do_partition_ii:nnnw}{##1}{##2{##4}}{##3}} - \def_long:cNx {#1_quicksort_partition_less_i_braced:nnnn} 4{ + \cs_set:cpx {#1_quicksort_partition_less_i_braced:nnnn} ##1##2##3##4{ \exp_not:c{#1_quicksort_do_partition_i_braced:nnnn}{##1}{##2}{{##4}##3}} - \def_long:cNx {#1_quicksort_partition_less_ii_braced:nnnn} 4{ + \cs_set:cpx {#1_quicksort_partition_less_ii_braced:nnnn} ##1##2##3##4{ \exp_not:c{#1_quicksort_do_partition_ii_braced:nnnn}{##1}{##2}{##3{##4}}} - \def_long:cNx {#1_quicksort_partition_greater_i_braced:nnnn} 4{ + \cs_set:cpx {#1_quicksort_partition_greater_i_braced:nnnn} ##1##2##3##4{ \exp_not:c{#1_quicksort_do_partition_i_braced:nnnn}{##1}{{##4}##2}{##3}} - \def_long:cNx {#1_quicksort_partition_greater_ii_braced:nnnn} 4{ + \cs_set:cpx {#1_quicksort_partition_greater_ii_braced:nnnn} ##1##2##3##4{ \exp_not:c{#1_quicksort_do_partition_ii_braced:nnnn}{##1}{##2{##4}}{##3}} - \def_long:cpx {#1_do_quicksort_braced:nnnnw} ##1##2##3##4\q_stop { + \cs_set:cpx {#1_do_quicksort_braced:nnnnw} ##1##2##3##4\q_stop { \exp_not:c{#1_quicksort_braced:n}{##2} \exp_not:c{#1_quicksort_function:n}{##1} \exp_not:c{#1_quicksort_braced:n}{##3} } } \prg_define_quicksort:nnn {prg}{}{} -\let:NN \prg_quicksort_function:n \ERROR -\let:NN \prg_quicksort_compare:nnTF \ERROR +\cs_set:Npn \prg_quicksort_function:n {\ERROR} +\cs_set:Npn \prg_quicksort_compare:nnTF {\ERROR} %% %% %% End of file `l3prg.sty'. diff --git a/Master/texmf-dist/tex/latex/expl3/l3prop.sty b/Master/texmf-dist/tex/latex/expl3/l3prop.sty index 21ff956c0fd..e18fb8e2b7f 100644 --- a/Master/texmf-dist/tex/latex/expl3/l3prop.sty +++ b/Master/texmf-dist/tex/latex/expl3/l3prop.sty @@ -15,7 +15,7 @@ %% Do not distribute a modified version of this file. %% %% -%% File: l3prop.dtx Copyright (C) 1990-2008 LaTeX3 project +%% File: l3prop.dtx Copyright (C) 1990-2009 LaTeX3 project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this @@ -33,7 +33,7 @@ %% %% The development version of the bundle can be found at %% -%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/ +%% http://www.latex-project.org/svnroot/experimental/trunk/ %% %% for those people who are interested. %% @@ -48,202 +48,143 @@ %% %% ----------------------------------------------------------------------- \RequirePackage{l3names} -\GetIdInfo$Id: l3prop.dtx 745 2008-08-03 18:50:46Z morten $ +\GetIdInfo$Id: l3prop.dtx 1365 2009-05-31 17:26:17Z mittelba $ {L3 Experimental Property Lists} \ProvidesExplPackage {\filename}{\filedate}{\fileversion}{\filedescription} -\RequirePackage{l3toks}\par -\RequirePackage{l3quark}\par +\package_check_loaded_expl: \quark_new:N\q_prop - -\def_new:Npn \prop_new:N #1{\toks_new:N #1} -\def_new:Npn \prop_new:c {\exp_args:Nc \prop_new:N} -\let_new:NN \prop_clear:N \toks_clear:N -\def_new:Npn \prop_clear:c {\exp_args:Nc\prop_clear:N} -\let_new:NN \prop_gclear:N \toks_gclear:N -\def_new:Npn \prop_gclear:c {\exp_args:Nc\prop_gclear:N} -\def_long_new:Npn \prop_split_aux:Nnn #1#2#3{ - \def:Npn \tmp:w ##1\q_prop#2\q_prop##2##3\q_stop {#3{##1}{##2}{##3}} - \exp_after:NN\tmp:w \toks_use:N#1\q_prop#2\q_prop\q_no_value \q_stop +\cs_new_eq:NN \prop_new:N \toks_new:N +\cs_new_eq:NN \prop_new:c \toks_new:c +\cs_new_eq:NN \prop_clear:N \toks_clear:N +\cs_new_eq:NN \prop_clear:c \toks_clear:c +\cs_new_eq:NN \prop_gclear:N \toks_gclear:N +\cs_new_eq:NN \prop_gclear:c \toks_gclear:c +\cs_new_eq:NN \prop_set_eq:NN \toks_set_eq:NN +\cs_new_eq:NN \prop_set_eq:Nc \toks_set_eq:Nc +\cs_new_eq:NN \prop_set_eq:cN \toks_set_eq:cN +\cs_new_eq:NN \prop_set_eq:cc \toks_set_eq:cc +\cs_new_eq:NN \prop_gset_eq:NN \toks_gset_eq:NN +\cs_new_eq:NN \prop_gset_eq:Nc \toks_gset_eq:Nc +\cs_new_eq:NN \prop_gset_eq:cN \toks_gset_eq:cN +\cs_new_eq:NN \prop_gset_eq:cc \toks_gset_eq:cc +\cs_new_eq:NN \prop_show:N \toks_show:N +\cs_new_eq:NN \prop_show:c \toks_show:c +\cs_new_nopar:Npn \prop_display:N #1 { + \iow_term:x { Property-list~\token_to_str:N #1~contains~ + the~pairs~(without~outer~braces): } + \toks_clear:N \l_tmpa_toks + \prop_map_inline:Nn #1 { + \toks_if_empty:NF \l_tmpa_toks { + \toks_put_right:Nx \l_tmpa_toks {^^J>~} + } + \toks_put_right:Nx \l_tmpa_toks { + \iow_space: \iow_char:N \{ \exp_not:n {##1} \iow_char:N \} \iow_space: + \iow_space: => \iow_space: + \iow_space: \iow_char:N \{ \exp_not:n {##2} \iow_char:N \} + } + } + \toks_show:N \l_tmpa_toks +} +\cs_generate_variant:Nn \prop_display:N {c} +\cs_new:Npn \prop_split_aux:Nnn #1#2#3{ + \cs_set:Npn \prop_tmp:w ##1 \q_prop #2 \q_prop ##2##3 \q_stop { + #3 {##1}{##2}{##3} + } + \exp_after:wN \prop_tmp:w \toks_use:N #1 \q_prop #2 \q_prop \q_no_value \q_stop } -\def_long_new:NNn \prop_get:NnN 2{ - \prop_split_aux:Nnn #1{#2}\prop_get_aux:w} -\def_long_new:NNn \prop_get_aux:w 4{\tlp_set:Nx#4{\exp_not:n{#2}}} -\def_new:Npn \prop_get:cnN { \exp_args:Nc \prop_get:NnN } -\def_long_new:NNn \prop_gget:NnN 2{ +\cs_new:Npn \prop_get:NnN #1#2 { + \prop_split_aux:Nnn #1{#2}\prop_get_aux:w +} +\cs_new:Npn \prop_get_aux:w #1#2#3#4 { \tl_set:Nx #4 {\exp_not:n{#2}} } +\cs_generate_variant:Nn \prop_get:NnN {cnN} +\cs_new:Npn \prop_gget:NnN #1#2{ \prop_split_aux:Nnn #1{#2}\prop_gget_aux:w} -\def_new:Npn \prop_gget:NcN {\exp_args:NNc \prop_gget:NnN} -\def_new:Npn \prop_gget:cnN {\exp_args:Nc \prop_gget:NnN} -\def_long_new:NNn \prop_gget_aux:w 4{\tlp_gset:Nx#4{\exp_not:n{#2}}} -\def_long_new:NNn \prop_get_gdel:NnN 3{ +\cs_new:Npn \prop_gget_aux:w #1#2#3#4{\tl_gset:Nx#4{\exp_not:n{#2}}} +\cs_generate_variant:Nn \prop_gget:NnN {cnN} +\cs_new:Npn \prop_get_gdel:NnN #1#2#3{ \prop_split_aux:Nnn #1{#2}{\prop_get_del_aux:w #3{\toks_gset:Nn #1}{#2}}} -\def_long_new:NNn \prop_get_del_aux:w 6{ - \tlp_set:Nx #1{\exp_not:n{#5}} +\cs_new:Npn \prop_get_del_aux:w #1#2#3#4#5#6{ + \tl_set:Nx #1{\exp_not:n{#5}} \quark_if_no_value:NF #1 { - \def:Npn \tmp:w ##1\q_prop#3\q_prop\q_no_value {#2{#4##1}} - \tmp:w #6} + \cs_set_nopar:Npn \prop_tmp:w ##1\q_prop#3\q_prop\q_no_value {#2{#4##1}} + \prop_tmp:w #6} } -\def_long_new:NNn \prop_put:Nnn 2{ +\cs_new:Npn \prop_put:Nnn #1#2{ \prop_split_aux:Nnn #1{#2}{ \prop_clear:N #1 - \prop_put_aux:w {\toks_put_right:Nn #1}{#2}} + \prop_put_aux:w {\toks_put_right:Nn #1}{#2} + } } -\def_new:Npn \prop_put:ccn {\exp_args:Ncc \prop_put:Nnn } - -\def_long_new:NNn \prop_gput:Nnn 2{ +\cs_new:Npn \prop_gput:Nnn #1#2{ \prop_split_aux:Nnn #1{#2}{ \prop_gclear:N #1 - \prop_put_aux:w {\toks_gput_right:Nn #1}{#2}} + \prop_put_aux:w {\toks_gput_right:Nn #1}{#2} + } } - -\def_long_new:NNn \prop_put_aux:w 6{ +\cs_new:Npn \prop_put_aux:w #1#2#3#4#5#6{ #1{\q_prop#2\q_prop{#6}#3} - \tlist_if_empty:nF{#5} + \tl_if_empty:nF{#5} { - \def:Npn \tmp:w ##1\q_prop#2\q_prop\q_no_value {#1{##1}} - \tmp:w #5 + \cs_set_nopar:Npn \prop_tmp:w ##1\q_prop#2\q_prop\q_no_value {#1{##1}} + \prop_tmp:w #5 } } -\def_new:Npn \prop_gput:Nno {\exp_args:NNno \prop_gput:Nnn} -\def_new:Npn \prop_gput:Nnx {\exp_args:NNnx \prop_gput:Nnn} -\def_new:Npn \prop_gput:Nox {\exp_args:NNox \prop_gput:Nnn} -\def_new:Npn \prop_gput:Noo {\exp_args:NNoo \prop_gput:Nnn} -\def_new:Npn \prop_gput:Ncn {\exp_args:NNc \prop_gput:Nnn} -\def_new:Npn \prop_gput:Ooo {\exp_args:NOoo \prop_gput:Nnn} -\def_new:Npn \prop_gput:cnn {\exp_args:Nc \prop_gput:Nnn} -\def_new:Npn \prop_gput:ccn {\exp_args:Ncc \prop_gput:Nnn} -\def_new:Npn \prop_gput:cco {\exp_args:Ncco \prop_gput:Nnn} -\def_new:Npn \prop_gput:ccx {\exp_args:Nccx \prop_gput:Nnn} -\def_long_new:NNn \prop_del:Nn 2{ +\cs_generate_variant:Nn \prop_put:Nnn {cnn} +\cs_generate_variant:Nn \prop_gput:Nnn {NnV,Nno,Nnx,Nox,cnn,ccx} +\cs_new:Npn \prop_del:Nn #1#2{ \prop_split_aux:Nnn #1{#2}{\prop_del_aux:w {\toks_set:Nn #1}{#2}}} -\def_long_new:NNn \prop_gdel:Nn 2{ +\cs_new:Npn \prop_gdel:Nn #1#2{ \prop_split_aux:Nnn #1{#2}{\prop_del_aux:w {\toks_gset:Nn #1}{#2}}} -\def_long_new:NNn \prop_del_aux:w 5{ - \def:Npn \tmp:w {#4} - \quark_if_no_value:NF \tmp:w - {\def:Npn \tmp:w ##1\q_prop#2\q_prop\q_no_value {#1{#3##1}} - \tmp:w #5}} -\def_new:NNn \prop_if_in:NnTF 2{ - \prop_split_aux:Nnn #1{#2}\prop_if_in_aux:w} -\def_new:NNn \prop_if_in_aux:w 3{\quark_if_no_value:nFT {#2}} - -\def_new:Npn \prop_if_in:NoTF {\exp_args:NNo \prop_if_in:NnTF} -\def_new:Npn \prop_if_in:ccTF {\exp_args:Ncc \prop_if_in:NnTF} -\def_long_new:NNn \prop_gput_if_new:Nnn 2{ - \prop_split_aux:Nnn #1{#2}{\prop_put_if_new_aux:w #1{#2}}} -\def_long_new:NNn \prop_put_if_new_aux:w 6{ - \tlist_if_empty:nT {#5}{#1{\q_prop#2\q_prop{#6}#3}}} -\let_new:NN \prop_set_eq:NN \toks_set_eq:NN -\let_new:NN \prop_set_eq:Nc \toks_set_eq:Nc -\let_new:NN \prop_set_eq:cN \toks_set_eq:cN -\let_new:NN \prop_set_eq:cc \toks_set_eq:cc -\let_new:NN \prop_gset_eq:NN \toks_gset_eq:NN -\let_new:NN \prop_gset_eq:Nc \toks_gset_eq:Nc -\let_new:NN \prop_gset_eq:cN \toks_gset_eq:cN -\let_new:NN \prop_gset_eq:cc \toks_gset_eq:cc -\let_new:NN \prop_if_empty_p:N \toks_if_empty_p:N -\let_new:NN \prop_if_empty_p:c \toks_if_empty_p:c -\let_new:NN \prop_if_empty:NTF \toks_if_empty:NTF -\let_new:NN \prop_if_empty:NT \toks_if_empty:NT -\let_new:NN \prop_if_empty:NF \toks_if_empty:NF -\let_new:NN \prop_if_empty:cTF \toks_if_empty:cTF -\let_new:NN \prop_if_empty:cT \toks_if_empty:cTF -\let_new:NN \prop_if_empty:cF \toks_if_empty:cF -\def_new:NNn \prop_if_eq:NNTF 2 { - \tlist_if_eq:xxTF{\toks_use:N #1}{\toks_use:N #2} -} -\def_new:NNn \prop_if_eq:NNT 2 { - \tlist_if_eq:xxT{\toks_use:N #1}{\toks_use:N #2} -} -\def_new:NNn \prop_if_eq:NNF 2 { - \tlist_if_eq:xxF{\toks_use:N #1}{\toks_use:N #2} -} -\def_new:Npn \prop_if_eq:NcTF {\exp_args:NNc \prop_if_eq:NNTF} -\def_new:Npn \prop_if_eq:NcT {\exp_args:NNc \prop_if_eq:NNT} -\def_new:Npn \prop_if_eq:NcF {\exp_args:NNc \prop_if_eq:NNF} -\def_new:Npn \prop_if_eq:cNTF {\exp_args:Nc \prop_if_eq:NNTF} -\def_new:Npn \prop_if_eq:cNT {\exp_args:Nc \prop_if_eq:NNT} -\def_new:Npn \prop_if_eq:cNF {\exp_args:Nc \prop_if_eq:NNF} -\def_new:Npn \prop_if_eq:ccTF {\exp_args:Ncc \prop_if_eq:NNTF} -\def_new:Npn \prop_if_eq:ccT {\exp_args:Ncc \prop_if_eq:NNT} -\def_new:Npn \prop_if_eq:ccF {\exp_args:Ncc \prop_if_eq:NNF} -\def_new:Npn \prop_map_function:NN #1#2{ - \exp_after:NN \prop_map_function_aux:w - \exp_after:NN #2 \toks_use:N #1 \q_prop{}\q_prop \q_no_value \q_stop -} -\def_new:Npn \prop_map_function_aux:w #1\q_prop#2\q_prop#3{ - \if:w \tlist_if_empty_p:n{#2} - \exp_after:NN \prop_map_break:w - \fi: - #1{#2}{#3} - \prop_map_function_aux:w #1 +\cs_new:Npn \prop_del_aux:w #1#2#3#4#5{ + \cs_set_nopar:Npn \prop_tmp:w {#4} + \quark_if_no_value:NF \prop_tmp:w { + \cs_set_nopar:Npn \prop_tmp:w ##1\q_prop#2\q_prop\q_no_value {#1{#3##1}} + \prop_tmp:w #5 + } } - -\def:Npn \prop_map_function:NN #1#2{ - \exp_after:NN \prop_map_function_aux:w - \exp_after:NN #2 \toks_use:N #1 \q_prop \q_no_value \q_prop \q_no_value +\cs_new:Npn \prop_gput_if_new:Nnn #1#2{ + \prop_split_aux:Nnn #1{#2}{\prop_put_if_new_aux:w #1{#2}}} +\cs_new:Npn \prop_put_if_new_aux:w #1#2#3#4#5#6{ + \tl_if_empty:nT {#5}{#1{\q_prop#2\q_prop{#6}#3}}} +\prg_new_eq_conditional:NNn \prop_if_empty:N \toks_if_empty:N {p,TF,T,F} +\prg_new_eq_conditional:NNn \prop_if_empty:c \toks_if_empty:c {p,TF,T,F} +\prg_new_eq_conditional:NNn \prop_if_eq:NN \toks_if_eq:NN {p,TF,T,F} +\prg_new_eq_conditional:NNn \prop_if_eq:cN \toks_if_eq:cN {p,TF,T,F} +\prg_new_eq_conditional:NNn \prop_if_eq:Nc \toks_if_eq:Nc {p,TF,T,F} +\prg_new_eq_conditional:NNn \prop_if_eq:cc \toks_if_eq:cc {p,TF,T,F} +\prg_new_conditional:Nnn \prop_if_in:Nn {TF,T,F} { + \prop_split_aux:Nnn #1 {#2} {\prop_if_in_aux:w} } -\def:Npn \prop_map_function_aux:w #1\q_prop#2\q_prop#3{ - \quark_if_no_value:nF{#2} - { - #1{#2}{#3} - \prop_map_function_aux:w #1 - } +\cs_new_nopar:Npn \prop_if_in_aux:w #1#2#3 { + \quark_if_no_value:nTF {#2} {\prg_return_false:} {\prg_return_true:} } - -\def:Npn \prop_map_function:NN #1#2{ - \exp_after:NN \prop_map_function_aux:w - \exp_after:NN #2 \toks_use:N #1 \q_prop \q_nil \q_prop \q_no_value \q_stop +\cs_generate_variant:Nn \prop_if_in:NnTF {NV,No,cn,cc} +\cs_generate_variant:Nn \prop_if_in:NnT {NV,No,cn,cc} +\cs_generate_variant:Nn \prop_if_in:NnF {NV,No,cn,cc} +\cs_set_nopar:Npn \prop_map_function:NN #1#2 { + \exp_after:wN \prop_map_function_aux:w + \exp_after:wN #2 \toks_use:N #1 \q_prop \q_nil \q_prop \q_no_value \q_stop } -\def:Npn \prop_map_function_aux:w #1\q_prop#2\q_prop#3{ - \if_meaning:NN \q_nil #2 - \exp_after:NN \prop_map_break:w +\cs_set:Npn \prop_map_function_aux:w #1 \q_prop #2 \q_prop #3 { + \if_meaning:w \q_nil #2 + \exp_after:wN \prop_map_break: \fi: #1{#2}{#3} \prop_map_function_aux:w #1 } - - -\def_new:Npn \prop_map_function:cN {\exp_args:Nc \prop_map_function:NN } -\def_new:Npn \prop_map_function:Nc {\exp_args:NNc \prop_map_function:NN } -\def_new:Npn \prop_map_function:cc {\exp_args:Ncc \prop_map_function:NN} +\cs_generate_variant:Nn \prop_map_function:NN {c,Nc,cc} \num_new:N \g_prop_inline_level_num -\def_new:Npn \prop_map_inline:Nn #1#2 { +\cs_new_nopar:Npn \prop_map_inline:Nn #1#2 { \num_gincr:N \g_prop_inline_level_num - \gdef_long:cpn {prop_map_inline_ \num_use:N \g_prop_inline_level_num :n} + \cs_gset:cpn {prop_map_inline_ \num_use:N \g_prop_inline_level_num :n} ##1##2{#2} \prop_map_function:Nc #1 {prop_map_inline_ \num_use:N \g_prop_inline_level_num :n} \num_gdecr:N \g_prop_inline_level_num } -\def_new:Npn \prop_map_inline:cN { \exp_args:Nc \prop_map_inline:NN } -\let_new:NN \prop_map_break:w \use_none_delimit_by_q_stop:w -\def:Npn \prop_put:NNn {\typeout{Warning:~name~ - changed~ to~ \string\prop_put:Nnn}\prop_put:Nnn} -\def:Npn \prop_gput:NNn {\typeout{Warning:~name~ - changed~ to~ \string\prop_gput:Nnn }\prop_gput:Nnn } -\def:Npn \prop_gput:NNo {\typeout{Warning:~name~ - changed~ to~ \string\prop_gput:Nno }\prop_gput:Nno } -\def:Npn \prop_gput:cNn {\typeout{Warning:~name~ - changed~ to~ \string\prop_gput:cnn }\prop_gput:cnn } -\def:Npn \prop_gput_if_new:NNn {\typeout{Warning:~name~ - changed~ to~ \string\prop_gput_if_new:Nnn }\prop_gput_if_new:Nnn } -\def:Npn \prop_get:NNN {\typeout{Warning:~name~ - changed~ to~ \string\prop_get:NnN }\prop_get:NnN } -\def:Npn \prop_get:cNN {\typeout{Warning:~name~ - changed~ to~ \string\prop_get:cnN }\prop_get:cnN } -\def:Npn \prop_gget:NNN {\typeout{Warning:~name~ - changed~ to~ \string\prop_gget:NnN }\prop_gget:NnN } -\def:Npn \prop_gget:cNN {\typeout{Warning:~name~ - changed~ to~ \string\prop_gget:cnN }\prop_gget:cnN } -\def:Npn \prop_get_gdel:NNN {\typeout{Warning:~name~ - changed~ to~ \string\prop_get_gdel:NnN }\prop_get_gdel:NnN } -\def:Npn \prop_del:NN {\typeout{Warning:~name~ - changed~ to~ \string\prop_del:Nn }\prop_del:Nn } -\def:Npn \prop_gdel:NN {\typeout{Warning:~name~ - changed~ to~ \string\prop_gdel:Nn }\prop_gdel:Nn } -\def:Npn \prop_if_in:NNTF {\typeout{Warning:~name~ - changed~ to~ \string\prop_if_in:NnTF }\prop_if_in:NnTF } +\cs_generate_variant:Nn\prop_map_inline:Nn {cn} +\cs_new_eq:NN \prop_map_break: \use_none_delimit_by_q_stop:w %% %% %% End of file `l3prop.sty'. diff --git a/Master/texmf-dist/tex/latex/expl3/l3quark.sty b/Master/texmf-dist/tex/latex/expl3/l3quark.sty index 1b44ce2ab2d..8302f07306a 100644 --- a/Master/texmf-dist/tex/latex/expl3/l3quark.sty +++ b/Master/texmf-dist/tex/latex/expl3/l3quark.sty @@ -15,7 +15,7 @@ %% Do not distribute a modified version of this file. %% %% -%% File: l3quark.dtx Copyright (C) 1990-2006 LaTeX3 project +%% File: l3quark.dtx Copyright (C) 1990-2009 LaTeX3 project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this @@ -33,7 +33,7 @@ %% %% The development version of the bundle can be found at %% -%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/ +%% http://www.latex-project.org/svnroot/experimental/trunk/ %% %% for those people who are interested. %% @@ -48,12 +48,12 @@ %% %% ----------------------------------------------------------------------- \RequirePackage{l3names} -\GetIdInfo$Id: l3quark.dtx 761 2008-08-04 21:35:13Z morten $ +\GetIdInfo$Id: l3quark.dtx 1365 2009-05-31 17:26:17Z mittelba $ {L3 Experimental Quark Commands} \ProvidesExplPackage {\filename}{\filedate}{\fileversion}{\filedescription} -\RequirePackage{l3expan}\par -\def_new:Npn \quark_new:N #1{\tlp_new:Nn #1{#1}} +\package_check_loaded_expl: +\cs_new_nopar:Npn \quark_new:N #1{\tl_new:Nn #1{#1}} \quark_new:N \q_stop \quark_new:N \q_no_value \quark_new:N \q_nil @@ -61,109 +61,92 @@ \quark_new:N\q_mark \quark_new:N\q_recursion_tail \quark_new:N\q_recursion_stop -\def_long_new:Npn \quark_if_recursion_tail_stop:n #1 { - \exp_after:NN\if_meaning:NN +\cs_new:Npn \quark_if_recursion_tail_stop:n #1 { + \exp_after:wN\if_meaning:w \quark_if_recursion_tail_aux:w #1?\q_nil\q_recursion_tail\q_recursion_tail - \exp_after:NN \use_none_delimit_by_q_recursion_stop:w + \exp_after:wN \use_none_delimit_by_q_recursion_stop:w \fi: } -\def_long_new:Npn \quark_if_recursion_tail_stop:N #1 { - \if_meaning:NN#1\q_recursion_tail - \exp_after:NN \use_none_delimit_by_q_recursion_stop:w +\cs_new:Npn \quark_if_recursion_tail_stop:N #1 { + \if_meaning:w#1\q_recursion_tail + \exp_after:wN \use_none_delimit_by_q_recursion_stop:w \fi: } -\def_new:Npn \quark_if_recursion_tail_stop:o{ - \exp_args:No\quark_if_recursion_tail_stop:n -} -\def_long_new:Npn \quark_if_recursion_tail_stop_do:nn #1#2 { - \exp_after:NN\if_meaning:NN +\cs_generate_variant:Nn \quark_if_recursion_tail_stop:n {o} +\cs_new:Npn \quark_if_recursion_tail_stop_do:nn #1#2 { + \exp_after:wN\if_meaning:w \quark_if_recursion_tail_aux:w #1?\q_nil\q_recursion_tail\q_recursion_tail - \exp_after:NN \use_arg_i_delimit_by_q_recursion_stop:nw + \exp_after:wN \use_i_delimit_by_q_recursion_stop:nw \else: - \exp_after:NN\use_none:n + \exp_after:wN\use_none:n \fi: {#2} } -\def_long_new:Npn \quark_if_recursion_tail_stop_do:Nn #1#2 { - \if_meaning:NN #1\q_recursion_tail - \exp_after:NN \use_arg_i_delimit_by_q_recursion_stop:nw +\cs_new:Npn \quark_if_recursion_tail_stop_do:Nn #1#2 { + \if_meaning:w #1\q_recursion_tail + \exp_after:wN \use_i_delimit_by_q_recursion_stop:nw \else: - \exp_after:NN\use_none:n + \exp_after:wN\use_none:n \fi: {#2} } -\def_new:Npn \quark_if_recursion_tail_stop_do:on{ - \exp_args:No\quark_if_recursion_tail_stop_do:nn -} -\def_long_new:Npn \quark_if_recursion_tail_aux:w - #1#2\q_nil\q_recursion_tail{#1} -\def_long_new:Npn\use_none_delimit_by_q_recursion_stop:w - #1\q_recursion_stop {} -\def_long_new:Npn\use_arg_i_delimit_by_q_recursion_stop:nw - #1#2\q_recursion_stop {#1} -\def_long_test_function_new:npn {quark_if_no_value:N} #1 { - \if_meaning:NN\q_no_value#1} -\def_long_new:Npn \quark_if_no_value_p:N #1{ - \if_meaning:NN \q_no_value #1 \c_true - \else: \c_false \fi: +\cs_generate_variant:Nn \quark_if_recursion_tail_stop_do:nn {on} +\cs_new:Npn \quark_if_recursion_tail_aux:w #1#2 \q_nil \q_recursion_tail {#1} +\prg_new_conditional:Nnn \quark_if_no_value:N {p,TF,T,F} { + \if_meaning:w \q_no_value #1 + \prg_return_true: \else: \prg_return_false: \fi: } -\cs_if_really_free:cTF{pdf_strcmp:D}{ - \def_long_new:Npn \quark_if_no_value_p:n #1{ - \if:w \exp_args:No \str_if_eq_var_p:nf - {\token_to_string:N\q_no_value\space} - {\tlist_to_str:n{#1}} - \c_true - \else: - \c_false +\cs_if_exist:cTF {pdf_strcmp:D} +{ + \prg_new_conditional:Nnn \quark_if_no_value:n {p,TF,T,F} { + \if_num:w \pdf_strcmp:D + {\exp_not:N \q_no_value} + {\exp_not:n{#1}} = \c_zero + \prg_return_true: \else: \prg_return_false: \fi: } } { - \def_long_new:Npn \quark_if_no_value_p:n #1{ - \if_num:w - \pdf_strcmp:D {\exp_not:N \q_no_value}{\exp_not:n{#1}}=\c_zero - \c_true \else: \c_false \fi: - } -} -\def_long_test_function_new:npn {quark_if_no_value:n} #1 { - \if:w \quark_if_no_value_p:n{#1}} -\def_long:Npn \quark_if_no_value:nFT #1{ - \if:w \quark_if_no_value_p:n{#1} - \exp_after:NN\use_arg_ii:nn - \else: - \exp_after:NN\use_arg_i:nn + \prg_new_conditional:Nnn \quark_if_no_value:n {p,TF,T,F} { + \exp_args:NNo + \if_predicate:w \str_if_eq_var_p:nf + {\token_to_str:N\q_no_value\iow_space:} + {\tl_to_str:n{#1}} + \prg_return_true: \else: \prg_return_false: \fi: + } } -\def_long_new:Npn \quark_if_nil_p:N #1{ - \if_meaning:NN \q_nil #1 \c_true - \else: \c_false \fi: +\prg_new_conditional:Nnn \quark_if_nil:N {p,TF,T,F} { + \if_meaning:w \q_nil #1 \prg_return_true: \else: \prg_return_false: \fi: } -\def_long_test_function_new:npn {quark_if_nil:N}#1{ - \if_meaning:NN\q_nil#1} -\cs_if_really_free:cTF{pdf_strcmp:D}{ - \def_long_new:Npn \quark_if_nil_p:n #1{ - \if:w \exp_args:No \str_if_eq_var_p:nf - {\token_to_string:N\q_nil\space} - {\tlist_to_str:n{#1}} - \c_true - \else: - \c_false +\cs_if_exist:cTF {pdf_strcmp:D} { + \prg_new_conditional:Nnn \quark_if_nil:n {p,TF,T,F} { + \if_num:w \pdf_strcmp:D + {\exp_not:N \q_nil} + {\exp_not:n{#1}} = \c_zero + \prg_return_true: \else: \prg_return_false: \fi: } } { - \def_long_new:Npn \quark_if_nil_p:n #1{ - \if_num:w - \pdf_strcmp:D {\exp_not:N \q_nil}{\exp_not:n{#1}}=\c_zero - \c_true \else: \c_false \fi: + \prg_new_conditional:Nnn \quark_if_nil:n {p,TF,T,F} { + \exp_args:NNo + \if_predicate:w \str_if_eq_var_p:nf + {\token_to_str:N\q_nil\iow_space:} + {\tl_to_str:n{#1}} + \prg_return_true: \else: \prg_return_false: + \fi: } } -\def_long_test_function_new:npn {quark_if_nil:n} #1 { - \if:w \quark_if_nil_p:n{#1}} -\def_new:Npn \quark_if_nil_p:o{\exp_args:No\quark_if_nil_p:n} -\def_new:Npn \quark_if_nil:oTF{\exp_args:No\quark_if_nil:nTF} -\def_new:Npn \quark_if_nil:oT {\exp_args:No\quark_if_nil:nT} -\def_new:Npn \quark_if_nil:oF {\exp_args:No\quark_if_nil:nF} +\cs_generate_variant:Nn \quark_if_nil_p:n {V} +\cs_generate_variant:Nn \quark_if_nil:nTF {V} +\cs_generate_variant:Nn \quark_if_nil:nT {V} +\cs_generate_variant:Nn \quark_if_nil:nF {V} +\cs_generate_variant:Nn \quark_if_nil_p:n {o} +\cs_generate_variant:Nn \quark_if_nil:nTF {o} +\cs_generate_variant:Nn \quark_if_nil:nT {o} +\cs_generate_variant:Nn \quark_if_nil:nF {o} + %% %% %% End of file `l3quark.sty'. diff --git a/Master/texmf-dist/tex/latex/expl3/l3seq.sty b/Master/texmf-dist/tex/latex/expl3/l3seq.sty index c4ebb497c03..a28d9f64ad7 100644 --- a/Master/texmf-dist/tex/latex/expl3/l3seq.sty +++ b/Master/texmf-dist/tex/latex/expl3/l3seq.sty @@ -15,7 +15,7 @@ %% Do not distribute a modified version of this file. %% %% -%% File: l3seq.dtx Copyright (C) 1990-2006 LaTeX3 project +%% File: l3seq.dtx Copyright (C) 1990-2009 LaTeX3 project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this @@ -33,7 +33,7 @@ %% %% The development version of the bundle can be found at %% -%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/ +%% http://www.latex-project.org/svnroot/experimental/trunk/ %% %% for those people who are interested. %% @@ -48,128 +48,147 @@ %% %% ----------------------------------------------------------------------- \RequirePackage{l3names} -\GetIdInfo$Id: l3seq.dtx 621 2007-09-01 20:14:19Z morten $ +\GetIdInfo$Id: l3seq.dtx 1362 2009-05-28 20:19:21Z joseph $ {L3 Experimental sequences and stacks} \ProvidesExplPackage {\filename}{\filedate}{\fileversion}{\filedescription} -\RequirePackage{l3quark} -\RequirePackage{l3tlp} -\RequirePackage{l3expan} -\let_new:NN \seq_elt:w \ERROR -\let_new:NN \seq_elt_end: \ERROR -\def_new:Npn \seq_new:N #1{\tlp_new:Nn #1{}} -\def_new:Npn \seq_new:c {\exp_args:Nc \seq_new:N} -\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 -\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 -\let_new:NN \seq_if_empty_p:N \tlp_if_empty_p:N -\let_new:NN \seq_if_empty:NTF \tlp_if_empty:NTF -\def_new:Npn \seq_if_empty:cTF {\exp_args:Nc\seq_if_empty:NTF} -\let_new:NN \seq_if_empty:NF \tlp_if_empty:NF -\def_new:Npn \seq_if_empty:cF {\exp_args:Nc\seq_if_empty:NF} -\def_new:Npn \seq_if_empty_err:N #1{\if_meaning:NN#1\c_empty_tlp - \tlp_clear:N \l_testa_tlp % catch prefixes - \err_latex_bug:x{Empty~sequence~`\token_to_string:N#1'}\fi:} -\def_new:Npn \seq_get:NN #1{ +\package_check_loaded_expl: +\cs_new:Npn \seq_elt:w {\ERROR} +\cs_new:Npn \seq_elt_end: {\ERROR} +\cs_new_eq:NN \seq_new:N \tl_new:N +\cs_new_eq:NN \seq_new:c \tl_new:c +\cs_new_eq:NN \seq_clear:N \tl_clear:N +\cs_new_eq:NN \seq_clear:c \tl_clear:c +\cs_new_eq:NN \seq_gclear:N \tl_gclear:N +\cs_new_eq:NN \seq_gclear:c \tl_gclear:c +\cs_new_eq:NN \seq_clear_new:N \tl_clear_new:N +\cs_new_eq:NN \seq_clear_new:c \tl_clear_new:c +\cs_new_eq:NN \seq_gclear_new:N \tl_gclear_new:N +\cs_new_eq:NN \seq_gclear_new:c \tl_gclear_new:c +\cs_new_eq:NN \seq_set_eq:NN \cs_set_eq:NN +\cs_new_eq:NN \seq_set_eq:cN \cs_set_eq:cN +\cs_new_eq:NN \seq_set_eq:Nc \cs_set_eq:Nc +\cs_new_eq:NN \seq_set_eq:cc \cs_set_eq:cc +\cs_new_eq:NN \seq_gset_eq:NN \cs_gset_eq:NN +\cs_new_eq:NN \seq_gset_eq:cN \cs_gset_eq:cN +\cs_new_eq:NN \seq_gset_eq:Nc \cs_gset_eq:Nc +\cs_new_eq:NN \seq_gset_eq:cc \cs_gset_eq:cc +\cs_new_nopar:Npn \seq_gconcat:NNN #1#2#3 { + \tl_gset:Nx #1 { \exp_not:V #2 \exp_not:V #3 } +} +\cs_generate_variant:Nn \seq_gconcat:NNN {ccc} +\prg_new_eq_conditional:NNn \seq_if_empty:N \tl_if_empty:N {p,TF,T,F} +\prg_new_eq_conditional:NNn \seq_if_empty:c \tl_if_empty:c {p,TF,T,F} +\cs_new_nopar:Npn \seq_if_empty_err:N #1 { + \if_meaning:w #1 \c_empty_tl + \tl_clear:N \l_testa_tl % catch prefixes + \msg_kernel_bug:x {Empty~sequence~`\token_to_str:N#1'} + \fi: +} +\prg_new_conditional:Nnn \seq_if_in:Nn {TF,T,F} { + \cs_set:Npn \seq_tmp:w ##1 \seq_elt:w #2 \seq_elt_end: ##2##3 \q_stop { + \if_meaning:w \q_no_value ##2 + \prg_return_false: \else: \prg_return_true: \fi: + } + \exp_after:wN \seq_tmp:w #1 \seq_elt:w #2 \seq_elt_end: \q_no_value \q_stop +} +\cs_generate_variant:Nn \seq_if_in:NnTF {cV,co,c,cx} +\cs_generate_variant:Nn \seq_if_in:NnT {cV,co,c,cx} +\cs_generate_variant:Nn \seq_if_in:NnF {cV,co,c,cx} +\cs_new_nopar:Npn \seq_get:NN #1 { \seq_if_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} -\def_new:Npn \seq_pop_aux:nnNN #1#2#3{ + \exp_after:wN \seq_get_aux:w #1 \q_stop +} +\cs_new:Npn \seq_get_aux:w \seq_elt:w #1 \seq_elt_end: #2 \q_stop #3 { + \tl_set:Nn #3 {#1} +} +\cs_generate_variant:Nn \seq_get:NN {c} +\cs_new:Npn \seq_pop_aux:nnNN #1#2#3 { \seq_if_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}} -\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}} -\def_new:Npn \seq_put_left:Nn #1#2{ - \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{ + \exp_after:wN \seq_pop_aux:w #3 \q_stop #1#2#3 +} +\cs_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} +} +\cs_new_eq:NN \seq_show:N \tl_show:N +\cs_new_eq:NN \seq_show:c \tl_show:c +\cs_new_nopar:Npn \seq_display:N #1 { + \iow_term:x { Sequence~\token_to_str:N #1~contains~ + the~elements~(without~outer~braces): } + \toks_clear:N \l_tmpa_toks + \seq_map_inline:Nn #1 { + \toks_if_empty:NF \l_tmpa_toks { + \toks_put_right:Nx \l_tmpa_toks {^^J>~} + } + \toks_put_right:Nx \l_tmpa_toks { + \iow_space: \iow_char:N \{ \exp_not:n {##1} \iow_char:N \} + } + } + \toks_show:N \l_tmpa_toks +} +\cs_generate_variant:Nn \seq_display:N {c} +\cs_new:Npn \seq_put_aux:Nnn #1 { + \exp_after:wN \seq_put_aux:w #1 \q_stop #1 +} +\cs_new:Npn \seq_put_aux:w #1\q_stop #2#3#4 { \tl_set:Nn #2 {#3#1#4} } +\cs_new:Npn \seq_put_left:Nn #1#2 { + \seq_put_aux:Nnn #1 {\seq_elt:w #2\seq_elt_end:} {} +} +\cs_generate_variant:Nn \seq_put_left:Nn {NV,No,Nx,c,cV,co} +\cs_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} -\def_new:Npn \seq_gput_left:Nn { - \pref_global:D - \seq_put_left:Nn} -\def_new:Npn \seq_gput_right:Nn { - \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:Nc {\exp_args:NNc \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} -\def_new:Npn \seq_map_variable_aux:Nnw #1#2\seq_elt:w#3\seq_elt_end:{ - \tlp_set:Nn #1{#3} - \quark_if_nil:NT #1 \seq_map_break:w +\cs_generate_variant:Nn \seq_put_right:Nn {NV,No,Nx,c,cV,co} +\cs_new:Npn \seq_gput_left:Nn { + \pref_global:D + \seq_put_left:Nn +} +\cs_new:Npn \seq_gput_right:Nn { + \pref_global:D + \seq_put_right:Nn +} +\cs_generate_variant:Nn \seq_gput_left:Nn {NV,No,Nx,c,cV,co} +\cs_generate_variant:Nn \seq_gput_right:Nn {NV,No,Nx,c,cV,co} +\cs_generate_variant:Nn \seq_gput_right:Nn {Nc} +\cs_new:Npn \seq_map_variable_aux:Nnw #1#2 \seq_elt:w #3 \seq_elt_end: { + \tl_set:Nx #1{\exp_not:n{#3}} + \quark_if_nil:NT #1 \seq_map_break: #2 \seq_map_variable_aux:Nnw #1{#2} } -\def_new:Npn \seq_map_variable:NNn #1#2#3{ - \tlp_set:Nx #2 {\exp_not:n{\seq_map_variable_aux:Nnw #2{#3}}} - \exp_after:NN #2 #1 \seq_elt:w \q_nil\seq_elt_end: \q_stop -} -\def_new:Npn \seq_map_variable:cNn{\exp_args:Nc\seq_map_variable:Nn} -\let_new:NN \seq_map_break:w \use_none_delimit_by_q_stop:w -\def_new:Npn \seq_map:NN #1#2{ - \def:Npn \seq_elt:w ##1\seq_elt_end: {#2{##1}}#1 - \let:NN \seq_elt:w \ERROR -} -\def_new:Npn \seq_map_inline:Nn #1#2{ - \def:Npn \seq_elt:w ##1\seq_elt_end: {#2}#1 - \let:NN \seq_elt:w \ERROR -} -\def_new:Npn \seq_map_inline:cn{\exp_args:Nc\seq_map_inline:Nn} -\let_new:NN \seq_set_eq:NN \let:NN -\def_new:Npn \seq_set_eq:Nc {\exp_args:NNc \seq_set_eq:NN} -\let_new:NN \seq_gset_eq:NN \glet:NN -\def_new:Npn \seq_gset_eq:cN {\exp_args:Nc \seq_gset_eq:NN} -\def_new:Npn \seq_gset_eq:Nc {\exp_args:NNc \seq_gset_eq:NN} -\def_new:Npn \seq_gset_eq:cc {\exp_args:Ncc \seq_gset_eq:NN} -\def_new:Npn \seq_gconcat:NNN #1#2#3{ - \tlp_gset:Nx #1 {\exp_not:o{#2}\exp_not:o{#3}} -} -\def_new:Npn \seq_gconcat:ccc{\exp_args:Nccc\seq_gconcat:NNN} -\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{ - \if_meaning:NN\q_no_value##2 - \exp_after:NN\use_arg_ii:nn - \else: - \exp_after:NN\use_arg_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} -\def_new:Npn \seq_if_in:cxTF {\exp_args:Ncx \seq_if_in:NnTF} -\def_new:Npn \seq_if_in:NnF #1#2 { \seq_if_in:NnTF #1{#2}\use_noop: } -\def_new:Npn \seq_if_in:cnF {\exp_args:Nc \seq_if_in:NnF} -\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} -\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_gpush:NC {\exp_args:NNC \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} -\let_new:NN \seq_top:NN \seq_get:NN -\let_new:NN \seq_top:cN \seq_get:cN +\cs_new:Npn \seq_map_variable:NNn #1#2#3 { + \tl_set:Nx #2 {\exp_not:n{\seq_map_variable_aux:Nnw #2{#3}}} + \exp_after:wN #2 #1 \seq_elt:w \q_nil\seq_elt_end: \q_stop +} +\cs_generate_variant:Nn \seq_map_variable:NNn {c} + +\cs_new_eq:NN \seq_map_break: \use_none_delimit_by_q_stop:w +\cs_new_eq:NN \seq_map_break:n \use_i_delimit_by_q_stop:nw +\cs_new_nopar:Npn \seq_map_function:NN #1#2 { + \cs_set:Npn \seq_elt:w ##1 \seq_elt_end: {#2{##1}} + #1 + \cs_set_eq:NN \seq_elt:w \ERROR +} +\cs_generate_variant:Nn \seq_map_function:NN {c} +\cs_new_nopar:Npn \seq_map_inline:Nn #1#2 { + \cs_set:Npn \seq_elt:w ##1 \seq_elt_end: {#2} + #1 + \cs_set_eq:NN \seq_elt:w \ERROR +} +\cs_generate_variant:Nn \seq_map_inline:Nn {c} +\cs_new_eq:NN \seq_push:Nn \seq_put_left:Nn +\cs_new_eq:NN \seq_push:NV \seq_put_left:NV +\cs_new_eq:NN \seq_push:No \seq_put_left:No +\cs_new_eq:NN \seq_push:cn \seq_put_left:cn +\cs_new_nopar:Npn \seq_pop:NN { \seq_pop_aux:nnNN \tl_set:Nn \tl_set:Nn } +\cs_generate_variant:Nn \seq_pop:NN {c} +\cs_new_eq:NN \seq_gpush:Nn \seq_gput_left:Nn +\cs_new_nopar:Npn \seq_gpop:NN { \seq_pop_aux:nnNN \tl_gset:Nn \tl_set:Nn } +\cs_generate_variant:Nn \seq_gpush:Nn {NV,No,c,Nv} +\cs_generate_variant:Nn \seq_gpop:NN {c} +\cs_new_eq:NN \seq_top:NN \seq_get:NN +\cs_new_eq:NN \seq_top:cN \seq_get:cN %% %% %% End of file `l3seq.sty'. diff --git a/Master/texmf-dist/tex/latex/expl3/l3skip.sty b/Master/texmf-dist/tex/latex/expl3/l3skip.sty index 588bcb9f88b..53462fcaea7 100644 --- a/Master/texmf-dist/tex/latex/expl3/l3skip.sty +++ b/Master/texmf-dist/tex/latex/expl3/l3skip.sty @@ -15,7 +15,7 @@ %% Do not distribute a modified version of this file. %% %% -%% File: l3skip.dtx Copyright (C) 2005-2007 Frank Mittelbach, LaTeX3 project +%% File: l3skip.dtx Copyright (C) 2005-2008 Frank Mittelbach, LaTeX3 project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this @@ -33,7 +33,7 @@ %% %% The development version of the bundle can be found at %% -%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/ +%% http://www.latex-project.org/svnroot/experimental/trunk/ %% %% for those people who are interested. %% @@ -48,67 +48,78 @@ %% %% ----------------------------------------------------------------------- \RequirePackage{l3names} -\GetIdInfo$Id: l3skip.dtx 666 2007-09-27 15:53:26Z mittelba $ +\GetIdInfo$Id: l3skip.dtx 1362 2009-05-28 20:19:21Z joseph $ {L3 Experimental skip registers} \ProvidesExplPackage {\filename}{\filedate}{\fileversion}{\filedescription} -\RequirePackage{l3int} -\RequirePackage{l3prg} -\let:NN \skip_new:N \newskip -\def_new:Npn \skip_new:c {\exp_args:Nc \skip_new:N} -\def_new:Npn \skip_set:Nn #1#2{#1\skip_eval:n{#2} +\package_check_loaded_expl: +\cs_new_nopar:Npn \skip_new:N #1 { + \chk_if_free_cs:N #1 + \newskip #1 } -\def_new:Npn \skip_gset:Nn { +\cs_generate_variant:Nn \skip_new:N {c} +\cs_new_nopar:Npn \skip_set:Nn #1#2 { + #1\skip_eval:n{#2} +} +\cs_new_nopar:Npn \skip_gset:Nn { \pref_global:D - \skip_set:Nn } -\def_new:Npn \skip_set:cn {\exp_args:Nc \skip_set:Nn } -\def_new:Npn \skip_gset:cn {\exp_args:Nc \skip_gset:Nn } -\def_new:Npn \skip_zero:N #1{#1\c_zero_skip \scan_stop: + \skip_set:Nn +} +\cs_generate_variant:Nn \skip_set:Nn {cn} +\cs_generate_variant:Nn \skip_gset:Nn {cn} +\cs_new_nopar:Npn \skip_zero:N #1{ + #1\c_zero_skip \scan_stop: } -\def_new:Npn \skip_gzero:N { +\cs_new_nopar:Npn \skip_gzero:N { \pref_global:D - \skip_zero:N} -\def_new:Npn \skip_zero:c {\exp_args:Nc \skip_zero:N} -\def_new:Npn \skip_gzero:c {\exp_args:Nc \skip_gzero:N} -\def_new:Npn \skip_add:Nn #1#2{ - \tex_advance:D#1 by \skip_eval:n{#2} + \skip_zero:N } -\def_new:Npn\skip_add:cn{\exp_args:Nc\skip_add:Nn} -\def_new:Npn \skip_sub:Nn #1#2{ - \tex_advance:D#1-\skip_eval:n{#2} +\cs_generate_variant:Nn \skip_zero:N {c} +\cs_generate_variant:Nn \skip_gzero:N {c} +\cs_new_nopar:Npn \skip_add:Nn #1#2 { + \tex_advance:D#1 by \skip_eval:n{#2} } -\def_new:Npn \skip_gadd:Nn { +\cs_generate_variant:Nn \skip_add:Nn {cn} +\cs_new_nopar:Npn \skip_sub:Nn #1#2{ + \tex_advance:D#1-\skip_eval:n{#2} +} +\cs_new_nopar:Npn \skip_gadd:Nn { \pref_global:D - \skip_add:Nn } -\def_new:Npn \skip_gsub:Nn { + \skip_add:Nn +} +\cs_generate_variant:Nn \skip_gadd:Nn {cn} +\cs_new_nopar:Npn \skip_gsub:Nn { \pref_global:D - \skip_sub:Nn } -\let_new:NN \skip_horizontal:N \tex_hskip:D -\def_new:Npn \skip_horizontal:c {\exp_args:Nc\skip_horizontal:N} -\def_new:Npn \skip_horizontal:n #1{\skip_horizontal:N \skip_eval:n{#1}} -\let_new:NN \skip_vertical:N \tex_vskip:D -\def_new:Npn \skip_vertital:c {\exp_args:Nc\skip_vertical:N} -\def_new:Npn \skip_vertical:n #1{\skip_vertical:N \skip_eval:n{#1}} -\let_new:NN \skip_use:N \tex_the:D -\def_new:Npn \skip_use:c #1{\exp_args:Nc\skip_use:N} -\def_new:Npn \skip_eval:n #1 {\etex_glueexpr:D #1 \scan_stop:} -%%\chk_new_cs:N \l_tmpa_skip + \skip_sub:Nn +} +\cs_new_eq:NN \skip_horizontal:N \tex_hskip:D +\cs_generate_variant:Nn \skip_horizontal:N {c} +\cs_new_nopar:Npn \skip_horizontal:n #1 { \skip_horizontal:N \skip_eval:n{#1} } +\cs_new_eq:NN \skip_vertical:N \tex_vskip:D +\cs_generate_variant:Nn \skip_vertical:N {c} +\cs_new_nopar:Npn \skip_vertical:n #1 { \skip_vertical:N \skip_eval:n{#1} } +\cs_new_eq:NN \skip_use:N \tex_the:D +\cs_generate_variant:Nn \skip_use:N {c} +\cs_new_eq:NN \skip_show:N \tex_showthe:D +\cs_new_nopar:Npn \skip_show:c #1 { \skip_show:N \cs:w #1 \cs_end: } +\cs_new_nopar:Npn \skip_eval:n #1 { \etex_glueexpr:D #1 \scan_stop: } +%%\chk_if_free_cs:N \l_tmpa_skip %%\tex_skipdef:D\l_tmpa_skip 255 %currently taken up by \skip@ \skip_new:N \l_tmpa_skip \skip_new:N \l_tmpb_skip \skip_new:N \l_tmpc_skip \skip_new:N \g_tmpa_skip \skip_new:N \g_tmpb_skip -\let:NN \c_zero_skip \z@ -\let:NN \c_max_skip \maxdimen -\def_new:Npn \skip_infinite_glue:nTF #1{ - \predicate:nTF { - \int_compare_p:nNn {\etex_gluestretchorder:D #1 } > \c_zero || - \int_compare_p:nNn {\etex_glueshrinkorder:D #1 } > \c_zero - } +\cs_set_eq:NN \c_zero_skip \z@ +\cs_set_eq:NN \c_max_skip \maxdimen +\prg_new_conditional:Nnn \skip_if_infinite_glue:n {p,TF,T,F} { + \bool_if:nTF { + \intexpr_compare_p:nNn {\etex_gluestretchorder:D #1 } > \c_zero || + \intexpr_compare_p:nNn {\etex_glueshrinkorder:D #1 } > \c_zero + } {\prg_return_true:} {\prg_return_false:} } -\def_new:Npn \skip_split_finite_else_action:nnNN #1#2#3#4{ - \skip_infinite_glue:nTF {#1} +\cs_new_nopar:Npn \skip_split_finite_else_action:nnNN #1#2#3#4{ + \skip_if_infinite_glue:nTF {#1} { #3 = \c_zero_skip #4 = \c_zero_skip @@ -119,89 +130,70 @@ #4 = \etex_glueshrink:D #1 \scan_stop: } } -\let:NN \dim_new:N \newdimen -\def_new:Npn \dim_new:c {\exp_args:Nc \dim_new:N} -\def_new:Npn \dim_set:Nn #1#2{#1~ \dim_eval:n{#2}} -\def_new:Npn \dim_gset:Nn {\pref_global:D \dim_set:Nn } -\def_new:Npn \dim_set:cn {\exp_args:Nc \dim_set:Nn } -\def_new:Npn \dim_set:Nc {\exp_args:NNc \dim_set:Nn } -\def_new:Npn \dim_gset:cn {\exp_args:Nc \dim_gset:Nn } -\def_new:Npn \dim_gset:Nc {\exp_args:NNc \dim_gset:Nn } -\def_new:Npn \dim_gset:cc {\exp_args:Ncc \dim_gset:Nn } -\def_new:Npn \dim_zero:N #1{#1\c_zero_skip} -\def_new:Npn \dim_gzero:N {\pref_global:D \dim_zero:N} -\def_new:Npn \dim_zero:c {\exp_args:Nc \dim_zero:N} -\def_new:Npn \dim_gzero:c {\exp_args:Nc \dim_gzero:N} -\def_new:Npn \dim_add:Nn #1#2{ +\cs_new_nopar:Npn \dim_new:N #1 { + \chk_if_free_cs:N #1 + \newdimen #1 +} +\cs_generate_variant:Nn \dim_new:N {c} +\cs_new_nopar:Npn \dim_set:Nn #1#2 { #1~ \dim_eval:n{#2} } +\cs_generate_variant:Nn \dim_set:Nn {cn,Nc} +\cs_new_nopar:Npn \dim_gset:Nn { \pref_global:D \dim_set:Nn } +\cs_generate_variant:Nn \dim_gset:Nn {cn,Nc,cc} +\cs_new_nopar:Npn \dim_zero:N #1 { #1\c_zero_skip } +\cs_generate_variant:Nn \dim_zero:N {c} +\cs_new_nopar:Npn \dim_gzero:N { \pref_global:D \dim_zero:N } +\cs_generate_variant:Nn \dim_gzero:N {c} +\cs_new_nopar:Npn \dim_add:Nn #1#2{ \tex_advance:D#1 by \dim_eval:n{#2}\scan_stop: } -\def_new:Npn\dim_add:cn{\exp_args:Nc\dim_add:Nn} -\def_new:Npn\dim_add:Nc{\exp_args:NNc\dim_add:Nn} -\def_new:Npn \dim_gadd:Nn { \pref_global:D \dim_add:Nn } -\def_new:Npn\dim_gadd:cn{\exp_args:Nc\dim_gadd:Nn} -\def_new:Npn \dim_sub:Nn #1#2{\tex_advance:D#1-#2\scan_stop:} -\def_new:Npn\dim_sub:cn{\exp_args:Nc\dim_sub:Nn} -\def_new:Npn\dim_sub:Nc{\exp_args:NNc\dim_sub:Nn} -\def_new:Npn \dim_gsub:Nn {\pref_global:D \dim_sub:Nn } -\def_new:Npn\dim_gsub:cn{\exp_args:Nc\dim_gsub:Nn} -\let_new:NN \dim_use:N \tex_the:D -\def_new:Npn \dim_use:c {\exp_args:Nc\dim_use:N} +\cs_generate_variant:Nn \dim_add:Nn {cn,Nc} +\cs_new_nopar:Npn \dim_gadd:Nn { \pref_global:D \dim_add:Nn } +\cs_generate_variant:Nn \dim_gadd:Nn {cn} +\cs_new_nopar:Npn \dim_sub:Nn #1#2 { \tex_advance:D#1-#2\scan_stop: } +\cs_generate_variant:Nn \dim_sub:Nn {cn,Nc} +\cs_new_nopar:Npn \dim_gsub:Nn { \pref_global:D \dim_sub:Nn } +\cs_generate_variant:Nn \dim_gsub:Nn {cn} +\cs_new_eq:NN \dim_use:N \tex_the:D +\cs_generate_variant:Nn \dim_use:N {c} +\cs_new_eq:NN \dim_show:N \tex_showthe:D +\cs_new_nopar:Npn \dim_show:c #1 { \dim_show:N \cs:w #1 \cs_end: } \dim_new:N \l_tmpa_dim \dim_new:N \l_tmpb_dim \dim_new:N \l_tmpc_dim \dim_new:N \l_tmpd_dim \dim_new:N \g_tmpa_dim \dim_new:N \g_tmpb_dim -\let_new:NN \c_zero_dim \c_zero_skip -\let_new:NN \c_max_dim \c_max_skip -\def_new:Npn \dim_eval:n #1 {\etex_dimexpr:D #1 \scan_stop:} -\let_new:NN \if_dim:w \tex_ifdim:D -\def_new:Npn \dim_compare:nNnTF #1#2#3{ +\cs_new_eq:NN \c_zero_dim \c_zero_skip +\cs_new_eq:NN \c_max_dim \c_max_skip +\cs_new_nopar:Npn \dim_eval:n #1 { \etex_dimexpr:D #1 \scan_stop: } +\cs_new_eq:NN \if_dim:w \tex_ifdim:D +\prg_new_conditional:Nnn \dim_compare:nNn {p,TF,T,F} { \if_dim:w \dim_eval:n {#1} #2 \dim_eval:n {#3} - \exp_after:NN \use_arg_i:nn - \else: - \exp_after:NN \use_arg_ii:nn - \fi: + \prg_return_true: \else: \prg_return_false: \fi: } -\def_new:Npn \dim_compare:nNnT #1#2#3{ - \if_dim:w \dim_eval:n {#1} #2 \dim_eval:n {#3} - \exp_after:NN \use_arg_ii:nn - \fi: - \use_none:n +\cs_new_nopar:Npn \dim_while_do:nNnn #1#2#3#4{ + \dim_compare:nNnT {#1}#2{#3}{#4 \dim_while_do:nNnn {#1}#2{#3}{#4}} } -\def_new:Npn \dim_compare:nNnF #1#2#3{ - \if_dim:w \dim_eval:n {#1} #2 \dim_eval:n {#3} - \exp_after:NN \use_none:n - \else: - \exp_after:NN \use_arg_i:n - \fi: +\cs_new_nopar:Npn \dim_until_do:nNnn #1#2#3#4{ + \dim_compare:nNnF {#1}#2{#3}{#4 \dim_until_do:nNnn {#1}#2{#3}{#4}} } -\def_new:Npn \dim_compare_p:nNn #1#2#3{ - \if_dim:w \dim_eval:n {#1} #2 \dim_eval:n {#3} - \c_true - \else: - \c_false - \fi: -} -\def_new:Npn \dim_while:nNnT #1#2#3#4{ - \dim_compare:nNnT {#1}#2{#3}{#4 \dim_while:nNnT {#1}#2{#3}{#4}} -} -\def_new:Npn \dim_while:nNnF #1#2#3#4{ - \dim_compare:nNnF {#1}#2{#3}{#4 \dim_while:nNnF {#1}#2{#3}{#4}} -} -\def_new:Npn \dim_dowhile:nNnT #1#2#3#4{ - #4 \dim_compare:nNnT {#1}#2{#3}{\dim_dowhile:nNnT {#1}#2{#3}{#4}} -} -\def_new:Npn \dim_dowhile:nNnF #1#2#3#4{ - #4 \dim_compare:nNnF {#1}#2{#3}{\dim_dowhile:nNnF {#1}#2{#3}{#4}} -} -\let_new:NN \muskip_new:N \newmuskip % nicked from LaTeX -\def_new:Npn \muskip_set:Nn#1#2{#1\etex_muexpr:D#2\scan_stop:} -\def_new:Npn \muskip_gset:Nn{\pref_global:D\muskip_set:Nn} -\def_new:Npn \muskip_add:Nn#1#2{\tex_advance:D#1\etex_muexpr:D#2\scan_stop:} -\def_new:Npn \muskip_gadd:Nn{\pref_global:D\muskip_add:Nn} -\def_new:Npn \muskip_sub:Nn#1#2{\tex_advance:D#1-\etex_muexpr:D#2\scan_stop:} -\def_new:Npn \muskip_gsub:Nn{\pref_global:D\muskip_sub:Nn} +\cs_new_nopar:Npn \dim_do_while:nNnn #1#2#3#4{ + #4 \dim_compare:nNnT {#1}#2{#3}{\dim_do_while:nNnn {#1}#2{#3}{#4}} +} +\cs_new_nopar:Npn \dim_do_until:nNnn #1#2#3#4{ + #4 \dim_compare:nNnF {#1}#2{#3}{\dim_do_until:nNnn {#1}#2{#3}{#4}} +} +\cs_new_nopar:Npn \muskip_new:N #1 { + \chk_if_free_cs:N #1 + \newmuskip #1 +} +\cs_new_nopar:Npn \muskip_set:Nn#1#2{#1\etex_muexpr:D#2\scan_stop:} +\cs_new_nopar:Npn \muskip_gset:Nn{\pref_global:D\muskip_set:Nn} +\cs_new_nopar:Npn \muskip_add:Nn#1#2{\tex_advance:D#1\etex_muexpr:D#2\scan_stop:} +\cs_new_nopar:Npn \muskip_gadd:Nn{\pref_global:D\muskip_add:Nn} +\cs_new_nopar:Npn \muskip_sub:Nn#1#2{\tex_advance:D#1-\etex_muexpr:D#2\scan_stop:} +\cs_new_nopar:Npn \muskip_gsub:Nn{\pref_global:D\muskip_sub:Nn} +\cs_new_eq:NN \muskip_use:N \tex_the:D %% %% %% End of file `l3skip.sty'. diff --git a/Master/texmf-dist/tex/latex/expl3/l3tl.sty b/Master/texmf-dist/tex/latex/expl3/l3tl.sty new file mode 100644 index 00000000000..2e5c8294ac1 --- /dev/null +++ b/Master/texmf-dist/tex/latex/expl3/l3tl.sty @@ -0,0 +1,610 @@ +%% +%% This is file `l3tl.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% l3tl.dtx (with options: `package,trace') +%% +%% +%% EXPERIMENTAL CODE +%% +%% Do not distribute this file without also distributing the +%% source files specified above. +%% +%% Do not distribute a modified version of this file. +%% +%% +%% File: l3tl.dtx Copyright (C) 1990-2009 LaTeX3 project +%% +%% It may be distributed and/or modified under the conditions of the +%% LaTeX Project Public License (LPPL), either version 1.3c of this +%% license or (at your option) any later version. The latest version +%% of this license is in the file +%% +%% http://www.latex-project.org/lppl.txt +%% +%% This file is part of the ``expl3 bundle'' (The Work in LPPL) +%% and all files in that bundle must be distributed together. +%% +%% The released version of this bundle is available from CTAN. +%% +%% ----------------------------------------------------------------------- +%% +%% The development version of the bundle can be found at +%% +%% http://www.latex-project.org/svnroot/experimental/trunk/ +%% +%% for those people who are interested. +%% +%%%%%%%%%%% +%% NOTE: %% +%%%%%%%%%%% +%% +%% Snapshots taken from the repository represent work in progress and may +%% not work or may contain conflicting material! We therefore ask +%% people _not_ to put them into distributions, archives, etc. without +%% prior consultation with the LaTeX Project Team. +%% +%% ----------------------------------------------------------------------- +\RequirePackage{l3names} +\GetIdInfo$Id: l3tl.dtx 1365 2009-05-31 17:26:17Z mittelba $ + {L3 Experimental Token Lists} +\ProvidesExplPackage + {\filename}{\filedate}{\fileversion}{\filedescription} +\package_check_loaded_expl: +\cs_new:Npn \tl_new:Nn #1#2{ + \chk_if_free_cs:N #1 + \cs_gset_nopar:Npn #1{#2} +} +\cs_generate_variant:Nn \tl_new:Nn {cn} +\cs_new:Npn \tl_new:Nx #1#2{ + \chk_if_free_cs:N #1 + \cs_gset_nopar:Npx #1{#2} +} +\cs_new_nopar:Npn \tl_new:N #1{\tl_new:Nn #1{}} +\cs_new_nopar:Npn \tl_new:c #1{\tl_new:cn {#1}{}} +\cs_new_nopar:Npn \tl_use:N #1 { + \if_meaning:w #1 \tex_relax:D + \msg_kernel_bug:x {Token~list~variable~ `\token_to_str:N #1'~ + has~ an~ erroneous~ structure!} + \else: + \exp_after:wN #1 + \fi: +} +\cs_generate_variant:Nn \tl_use:N {c} +\cs_new_nopar:Npn \tl_show:N #1 { \cs_show:N #1 } +\cs_generate_variant:Nn \tl_show:N {c} +\cs_set_eq:NN \tl_show:n \etex_showtokens:D +\cs_new:Npn\tl_set:Nn#1#2{\cs_set_nopar:Npn#1{#2}} +\cs_new:Npn\tl_set:Nx#1#2{\cs_set_nopar:Npx#1{#2}} +\cs_new:Npn\tl_gset:Nn#1#2{\cs_gset_nopar:Npn#1{#2}} +\cs_new:Npn\tl_gset:Nx#1#2{\cs_gset_nopar:Npx#1{#2}} +\cs_generate_variant:Nn \tl_set:Nn {NV,No,Nv,Nd,Nf,cn,cV,co,cx} +\cs_generate_variant:Nn \tl_gset:Nn {NV,No,Nv,Nd,cn,cx} +\cs_new_eq:NN \tl_set_eq:NN \cs_set_eq:NN +\cs_new_eq:NN \tl_gset_eq:NN \cs_gset_eq:NN +\cs_generate_variant:Nn \tl_set_eq:NN {Nc,c,cc} +\cs_generate_variant:Nn \tl_gset_eq:NN {Nc,c,cc} +\cs_new_nopar:Npn \tl_clear:N #1{\tl_set_eq:NN #1\c_empty_tl} +\cs_generate_variant:Nn \tl_clear:N {c} +\cs_new_nopar:Npn \tl_gclear:N #1{\tl_gset_eq:NN #1\c_empty_tl} +\cs_generate_variant:Nn \tl_gclear:N {c} +\cs_new_eq:NN \tl_clear_new:N \tl_clear:N +\cs_generate_variant:Nn \tl_clear_new:N {c} +\cs_new_eq:NN \tl_gclear_new:N \tl_gclear:N +\cs_generate_variant:Nn \tl_gclear_new:N {c} +\cs_new:Npn \tl_put_left:Nn #1#2 { + \tl_set:Nn \l_exp_tl {#2} + \tl_set:Nx #1 { \exp_not:V \l_exp_tl \exp_not:V #1 } +} +\cs_new:Npn \tl_put_left:NV #1#2 { + \tl_set:Nx #1 { \exp_not:V #2 \exp_not:V #1 } +} +\cs_new:Npn \tl_put_left:No #1#2{ + \tl_set:No \l_exp_tl {#2} + \tl_set:Nx #1 { \exp_not:V \l_exp_tl \exp_not:V #1 } +} +\cs_new:Npn \tl_put_left:Nx #1#2{ + \tl_set:Nx #1 { #2 \exp_not:V #1 } +} +\cs_new:Npn \tl_gput_left:Nn #1#2{ + \tl_set:Nn \l_exp_tl{#2} + \tl_gset:Nx #1 { \exp_not:V \l_exp_tl \exp_not:V #1 } +} +\cs_new:Npn \tl_gput_left:NV #1#2 { + \tl_gset:Nx #1 { \exp_not:V #2 \exp_not:V #1 } +} +\cs_new:Npn \tl_gput_left:No #1#2{ + \tl_set:No \l_exp_tl {#2} + \tl_gset:Nx #1 { \exp_not:V \l_exp_tl \exp_not:V #1 } +} +\cs_new:Npn \tl_gput_left:Nx #1#2{ + \tl_gset:Nx #1 { #2 \exp_not:V #1 } +} +\cs_generate_variant:Nn \tl_put_left:Nn {cn,co} +\cs_generate_variant:Nn \tl_put_left:NV {cV} +\cs_generate_variant:Nn \tl_gput_left:Nn {cn,co} +\cs_generate_variant:Nn \tl_gput_left:NV {cV} +\cs_new:Npn \tl_put_right:Nn #1#2 { + \tl_set:Nn \l_exp_tl {#2} + \tl_set:Nx #1 { \exp_not:V #1 \exp_not:V \l_exp_tl } +} +\cs_new:Npn \tl_gput_right:Nn #1#2{ + \tl_set:Nn \l_exp_tl {#2} + \tl_gset:Nx #1 { \exp_not:V #1 \exp_not:V \l_exp_tl } +} +\cs_new:Npn \tl_put_right:NV #1#2 { + \tl_set:Nx #1 { \exp_not:V #1 \exp_not:V #2 } +} +\cs_new:Npn \tl_put_right:No #1#2 { + \tl_set:No \l_exp_tl {#2} + \tl_set:Nx #1 { \exp_not:V #1 \exp_not:V \l_exp_tl } +} +\cs_new:Npn \tl_gput_right:NV #1#2 { + \tl_gset:Nx #1 { \exp_not:V #1 \exp_not:V #2 } +} +\cs_new:Npn \tl_gput_right:No #1#2 { + \tl_set:No \l_exp_tl {#2} + \tl_gset:Nx #1 { \exp_not:V #1 \exp_not:V \l_exp_tl } +} +\cs_set:Npn \tl_put_right:Nx #1#2 { + \tl_set:Nx #1 { \exp_not:V #1 #2 } +} +\cs_set:Npn \tl_gput_right:Nx #1#2 { + \tl_gset:Nx #1 { \exp_not:V #1 #2 } +} +\cs_generate_variant:Nn \tl_put_right:Nn {cn,co} +\cs_generate_variant:Nn \tl_put_right:NV {cV} +\cs_generate_variant:Nn \tl_gput_right:Nn {cn,co} +\cs_generate_variant:Nn \tl_gput_right:NV {cV} +\cs_new_nopar:Npn \tl_gset:Nc { + \pref_global:D + \tl_set:Nc} +\cs_new_nopar:Npn \tl_set:Nc #1#2{\tl_set:No #1{\cs:w#2\cs_end:}} +\tl_new:Nn \c_job_name_tl {\tex_jobname:D} +\tl_new:Nn \c_empty_tl {} +\tl_new:Nn \g_tmpa_tl{} +\tl_new:Nn \g_tmpb_tl{} +\tl_new:Nn \l_testa_tl {} +\tl_new:Nn \l_testb_tl {} +\tl_new:Nn \g_testa_tl {} +\tl_new:Nn \g_testb_tl {} +\tl_new:Nn \l_tmpa_tl{} +\tl_new:Nn \l_tmpb_tl{} +\prg_set_conditional:Npnn \tl_if_empty:N #1 {p,TF,T,F} { + \if_meaning:w #1 \c_empty_tl + \prg_return_true: \else: \prg_return_false: \fi: +} +\cs_generate_variant:Nn \tl_if_empty_p:N {c} +\cs_generate_variant:Nn \tl_if_empty:NTF {c} +\cs_generate_variant:Nn \tl_if_empty:NT {c} +\cs_generate_variant:Nn \tl_if_empty:NF {c} +\prg_new_conditional:Npnn \tl_if_eq:NN #1#2 {p,TF,T,F} { + \if_meaning:w #1 #2 \prg_return_true: \else: \prg_return_false: \fi: +} +\cs_generate_variant:Nn \tl_if_eq_p:NN {Nc,c,cc} +\cs_generate_variant:Nn \tl_if_eq:NNTF {Nc,c,cc} +\cs_generate_variant:Nn \tl_if_eq:NNT {Nc,c,cc} +\cs_generate_variant:Nn \tl_if_eq:NNF {Nc,c,cc} +\prg_new_conditional:Npnn \tl_if_empty:n #1 {p,TF,T,F} { + \exp_after:wN \if_meaning:w \exp_after:wN \q_nil \tl_to_str:n {#1} \q_nil + \prg_return_true: \else: \prg_return_false: \fi: +} +\cs_generate_variant:Nn \tl_if_empty_p:n {V} +\cs_generate_variant:Nn \tl_if_empty:nTF {V} +\cs_generate_variant:Nn \tl_if_empty:nT {V} +\cs_generate_variant:Nn \tl_if_empty:nF {V} +\cs_generate_variant:Nn \tl_if_empty_p:n {o} +\cs_generate_variant:Nn \tl_if_empty:nTF {o} +\cs_generate_variant:Nn \tl_if_empty:nT {o} +\cs_generate_variant:Nn \tl_if_empty:nF {o} +\prg_new_conditional:Npnn \tl_if_blank:n #1 {p,TF,T,F} { + \exp_after:wN \tl_if_blank_p_aux:w \tl_to_str:n {#1} aa..\q_nil +} +\cs_new:Npn \tl_if_blank_p_aux:w #1#2 a #3#4 \q_nil { + \if_meaning:w #3 #4 \prg_return_true: \else: \prg_return_false: \fi: +} +\cs_generate_variant:Nn \tl_if_blank_p:n {V} +\cs_generate_variant:Nn \tl_if_blank:nTF {V} +\cs_generate_variant:Nn \tl_if_blank:nT {V} +\cs_generate_variant:Nn \tl_if_blank:nF {V} +\cs_generate_variant:Nn \tl_if_blank_p:n {o} +\cs_generate_variant:Nn \tl_if_blank:nTF {o} +\cs_generate_variant:Nn \tl_if_blank:nT {o} +\cs_generate_variant:Nn \tl_if_blank:nF {o} +\cs_new_eq:NN \tl_compare:xx \pdf_strcmp:D +\cs_new:Npn \tl_compare:nn #1#2{ + \tl_compare:xx{\exp_not:n{#1}}{\exp_not:n{#2}} +} +\cs_new:Npn \tl_compare:nx #1{ + \tl_compare:xx{\exp_not:n{#1}} +} +\cs_new:Npn \tl_compare:xn #1#2{ + \tl_compare:xx{#1}{\exp_not:n{#2}} +} +\cs_new:Npn \tl_compare:nV #1#2 { + \tl_compare:xx { \exp_not:n {#1} } { \exp_not:V #2 } +} +\cs_new:Npn \tl_compare:no #1#2{ + \tl_compare:xx{\exp_not:n{#1}}{\exp_not:n\exp_after:wN{#2}} +} +\cs_new:Npn \tl_compare:Vn #1#2 { + \tl_compare:xx { \exp_not:V #1 } { \exp_not:n {#2} } +} +\cs_new:Npn \tl_compare:on #1#2{ + \tl_compare:xx{\exp_not:n\exp_after:wN{#1}}{\exp_not:n{#2}} +} +\cs_new:Npn \tl_compare:VV #1#2 { + \tl_compare:xx { \exp_not:V #1 } { \exp_not:V #2 } +} +\cs_new:Npn \tl_compare:oo #1#2{ + \tl_compare:xx{\exp_not:n\exp_after:wN{#1}}{\exp_not:n\exp_after:wN{#2}} +} +\cs_new:Npn \tl_compare:xV #1#2 { + \tl_compare:xx {#1} { \exp_not:V #2 } +} +\cs_new:Npn \tl_compare:xo #1#2{ + \tl_compare:xx{#1}{\exp_not:n\exp_after:wN{#2}} +} +\cs_new:Npn \tl_compare:Vx #1#2 { + \tl_compare:xx { \exp_not:V #1 } {#2} +} +\cs_new:Npn \tl_compare:ox #1#2{ + \tl_compare:xx{\exp_not:n\exp_after:wN{#1}}{#2} +} +\cs_set_nopar:Npn \tl_tmp:w #1 { + \tl_set:Nx \l_tmpa_tl { + \exp_not:N \prg_new_conditional:Npnn \exp_not:c {tl_if_eq:#1} + ####1 ####2 {p,TF,T,F} { + \exp_not:N \tex_ifnum:D + \exp_not:c {tl_compare:#1} {####1}{####2} + \exp_not:n{ =\c_zero \prg_return_true: \else: \prg_return_false: \fi: } + } + } + \l_tmpa_tl +} +\tl_tmp:w{xx} \tl_tmp:w{nx} \tl_tmp:w{ox} \tl_tmp:w{Vx} +\tl_tmp:w{xn} \tl_tmp:w{nn} \tl_tmp:w{on} \tl_tmp:w{Vn} +\tl_tmp:w{xo} \tl_tmp:w{no} \tl_tmp:w{oo} +\tl_tmp:w{xV} \tl_tmp:w{nV} \tl_tmp:w{VV} +\cs_if_exist:cF{pdf_strcmp:D}{ + \prg_set_protected_conditional:Npnn \tl_if_eq:nn #1#2 {TF,T,F} { + \tl_set:Nx \l_testa_tl {\exp_not:n{#1}} + \tl_set:Nx \l_testb_tl {\exp_not:n{#2}} + \if_meaning:w\l_testa_tl \l_testb_tl + \prg_return_true: \else: \prg_return_false: + \fi: + } + \prg_set_protected_conditional:Npnn \tl_if_eq:nV #1#2 {TF,T,F} { + \tl_set:Nx \l_testa_tl { \exp_not:n {#1} } + \tl_set:Nx \l_testb_tl { \exp_not:V #2 } + \if_meaning:w \l_testa_tl \l_testb_tl + \prg_return_true: \else: \prg_return_false: + \fi: + } + \prg_set_protected_conditional:Npnn \tl_if_eq:no #1#2 {TF,T,F} { + \tl_set:Nx \l_testa_tl {\exp_not:n{#1}} + \tl_set:Nx \l_testb_tl {\exp_not:o{#2}} + \if_meaning:w\l_testa_tl \l_testb_tl + \prg_return_true: \else: \prg_return_false: + \fi: + } + \prg_set_protected_conditional:Npnn \tl_if_eq:nx #1#2 {TF,T,F} { + \tl_set:Nx \l_testa_tl {\exp_not:n{#1}} + \tl_set:Nx \l_testb_tl {#2} + \if_meaning:w\l_testa_tl \l_testb_tl + \prg_return_true: \else: \prg_return_false: + \fi: + } + \prg_set_protected_conditional:Npnn \tl_if_eq:Vn #1#2 {TF,T,F} { + \tl_set:Nx \l_testa_tl { \exp_not:V #1 } + \tl_set:Nx \l_testb_tl { \exp_not:n{#2} } + \if_meaning:w \l_testa_tl \l_testb_tl + \prg_return_true: \else: \prg_return_false: + \fi: + } + \prg_set_protected_conditional:Npnn \tl_if_eq:on #1#2 {TF,T,F} { + \tl_set:Nx \l_testa_tl {\exp_not:o{#1}} + \tl_set:Nx \l_testb_tl {\exp_not:n{#2}} + \if_meaning:w\l_testa_tl \l_testb_tl + \prg_return_true: \else: \prg_return_false: + \fi: + } + \prg_set_protected_conditional:Npnn \tl_if_eq:VV #1#2 {TF,T,F} { + \tl_set:Nx \l_testa_tl { \exp_not:V #1 } + \tl_set:Nx \l_testb_tl { \exp_not:V #2 } + \if_meaning:w \l_testa_tl \l_testb_tl + \prg_return_true: \else: \prg_return_false: + \fi: + } + \prg_set_protected_conditional:Npnn \tl_if_eq:oo #1#2 {TF,T,F} { + \tl_set:Nx \l_testa_tl {\exp_not:o{#1}} + \tl_set:Nx \l_testb_tl {\exp_not:o{#2}} + \if_meaning:w\l_testa_tl \l_testb_tl + \prg_return_true: \else: \prg_return_false: + \fi: + } + \prg_set_protected_conditional:Npnn \tl_if_eq:Vx #1#2 {TF,T,F} { + \tl_set:Nx \l_testa_tl { \exp_not:V #1 } + \tl_set:Nx \l_testb_tl {#2} + \if_meaning:w \l_testa_tl \l_testb_tl + \prg_return_true: \else: \prg_return_false: + \fi: + } + \prg_set_protected_conditional:Npnn \tl_if_eq:ox #1#2 {TF,T,F} { + \tl_set:Nx \l_testa_tl {\exp_not:o{#1}} + \tl_set:Nx \l_testb_tl {#2} + \if_meaning:w\l_testa_tl \l_testb_tl + \prg_return_true: \else: \prg_return_false: + \fi: + } + \prg_set_protected_conditional:Npnn \tl_if_eq:xn #1#2 {TF,T,F} { + \tl_set:Nx \l_testa_tl {#1} + \tl_set:Nx \l_testb_tl {\exp_not:n{#2}} + \if_meaning:w\l_testa_tl \l_testb_tl + \prg_return_true: \else: \prg_return_false: + \fi: + } + \prg_set_protected_conditional:Npnn \tl_if_eq:xV #1#2 {TF,T,F} { + \tl_set:Nx \l_testa_tl {#1} + \tl_set:Nx \l_testb_tl { \exp_not:V #2 } + \if_meaning:w \l_testa_tl \l_testb_tl + \prg_return_true: \else: \prg_return_false: + \fi: + } + \prg_set_protected_conditional:Npnn \tl_if_eq:xo #1#2 {TF,T,F} { + \tl_set:Nx \l_testa_tl {#1} + \tl_set:Nx \l_testb_tl {\exp_not:o{#2}} + \if_meaning:w\l_testa_tl \l_testb_tl + \prg_return_true: \else: \prg_return_false: + \fi: + } + \prg_set_protected_conditional:Npnn \tl_if_eq:xx #1#2 {TF,T,F} { + \tl_set:Nx \l_testa_tl {#1} + \tl_set:Nx \l_testb_tl {#2} + \if_meaning:w\l_testa_tl \l_testb_tl + \prg_return_true: \else: \prg_return_false: + \fi: + } +} +\cs_new_eq:NN \tl_to_lowercase:n \tex_lowercase:D +\cs_new_eq:NN \tl_to_uppercase:n \tex_uppercase:D +\cs_new_eq:NN \tl_to_str:n \etex_detokenize:D +\cs_new_nopar:Npn \tl_to_str:N {\exp_after:wN\tl_to_str_aux:w + \token_to_meaning:N} +\cs_new_nopar:Npn \tl_to_str_aux:w #1>{} +\cs_generate_variant:Nn \tl_to_str:N {c} +\cs_new:Npn \tl_map_function:nN #1#2{ + \tl_map_function_aux:Nn #2 #1 \q_recursion_tail \q_recursion_stop +} +\cs_new_nopar:Npn \tl_map_function:NN #1#2{ + \exp_after:wN \tl_map_function_aux:Nn + \exp_after:wN #2 #1 \q_recursion_tail \q_recursion_stop +} +\cs_new:Npn \tl_map_function_aux:Nn #1#2{ + \quark_if_recursion_tail_stop:n{#2} + #1{#2} \tl_map_function_aux:Nn #1 +} +\cs_generate_variant:Nn \tl_map_function:NN {cN} +\cs_new:Npn \tl_map_inline:nn #1#2{ + \num_gincr:N \g_tl_inline_level_num + \cs_gset:cpn {tl_map_inline_ \num_use:N \g_tl_inline_level_num :n} + ##1{#2} + \exp_args:Nc \tl_map_function_aux:Nn + {tl_map_inline_ \num_use:N \g_tl_inline_level_num :n} + #1 \q_recursion_tail\q_recursion_stop + \num_gdecr:N \g_tl_inline_level_num +} +\cs_new:Npn \tl_map_inline:Nn #1#2{ + \num_gincr:N \g_tl_inline_level_num + \cs_gset:cpn {tl_map_inline_ \num_use:N \g_tl_inline_level_num :n} + ##1{#2} + \exp_last_unbraced:NcV \tl_map_function_aux:Nn + {tl_map_inline_ \num_use:N \g_tl_inline_level_num :n} + #1 \q_recursion_tail\q_recursion_stop + \num_gdecr:N \g_tl_inline_level_num +} +\cs_generate_variant:Nn \tl_map_inline:Nn {c} +\tl_new:Nn \g_tl_inline_level_num{0} +\cs_new:Npn \tl_map_variable:nNn #1#2#3{ + \tl_map_variable_aux:Nnn #2 {#3} #1 \q_recursion_tail \q_recursion_stop +} +\cs_new_nopar:Npn \tl_map_variable:NNn {\exp_args:No \tl_map_variable:nNn} +\cs_generate_variant:Nn \tl_map_variable:NNn {c} +\cs_new:Npn \tl_map_variable_aux:Nnn #1#2#3{ + \tl_set:Nn #1{#3} + \quark_if_recursion_tail_stop:N #1 + #2 \tl_map_variable_aux:Nnn #1{#2} +} +\cs_new_eq:NN \tl_map_break: \use_none_delimit_by_q_recursion_stop:w +\cs_new:Npn \tl_reverse:n #1{ + \tl_reverse_aux:nN {} #1 \q_recursion_tail\q_recursion_stop +} +\cs_new:Npn \tl_reverse_aux:nN #1#2{ + \quark_if_recursion_tail_stop_do:nn {#2}{ #1 } + \tl_reverse_aux:nN {#2#1} +} +\cs_generate_variant:Nn \tl_reverse:n {V,o} +\cs_new_nopar:Npn \tl_reverse:N #1 { + \tl_set:Nf #1 { \tl_reverse:o { #1 \exp_stop_f: } } +} +\cs_new:Npn \tl_elt_count:n #1{ + \intexpr_eval:n { + \tl_map_function:nN {#1}\num_elt_count:n + } +} +\cs_generate_variant:Nn \tl_elt_count:n {V,o} +\cs_new_nopar:Npn \tl_elt_count:N #1{ + \intexpr_eval:n { + \tl_map_function:NN #1 \num_elt_count:n + } +} +\cs_new:Npn \tl_set_rescan:Nnn { \tl_set_rescan_aux:NNnn \tl_set:Nn } +\cs_new:Npn \tl_gset_rescan:Nnn { \tl_set_rescan_aux:NNnn \tl_gset:Nn } +\group_begin: + \tex_lccode:D `\A = `\@ \scan_stop: + \tex_lccode:D `\B = `\@ \scan_stop: + \tex_catcode:D `\A = 8 \scan_stop: + \tex_catcode:D `\B = 3 \scan_stop: +\tl_to_lowercase:n { + \group_end: + \tl_new:Nn \c_two_ats_with_two_catcodes_tl {AB} +} +\cs_new:Npn \tl_set_rescan_aux:NNnn #1#2#3#4 { + \group_begin: + \toks_set:No \etex_everyeof:D { \c_two_ats_with_two_catcodes_tl } + \tex_endlinechar:D = \c_minus_one + #3 + \exp_after:wN \tl_rescan_aux:w \etex_scantokens:D {#4} + \exp_args:NNNo + \group_end: + #1 #2 { \l_tmpa_tl } +} +\exp_after:wN \cs_set:Npn +\exp_after:wN \tl_rescan_aux:w +\exp_after:wN # +\exp_after:wN 1 \c_two_ats_with_two_catcodes_tl { + \tl_set:Nn \l_tmpa_tl {#1} +} +\cs_new:Npn \tl_set_rescan:Nnx #1#2#3 { + \group_begin: + \etex_everyeof:D { \exp_not:N } + \tex_endlinechar:D = \c_minus_one + #2 + \tl_set:Nx \l_tmpa_tl { \etex_scantokens:D {#3} } + \exp_args:NNNo + \group_end: + \tl_set:Nn #1 { \l_tmpa_tl } +} +\cs_new:Npn \tl_gset_rescan:Nnx #1#2#3 { + \group_begin: + \etex_everyeof:D { \exp_not:N } + \tex_endlinechar:D = \c_minus_one + #2 + \tl_gset:Nx #1 { \etex_scantokens:D {#3} } + \group_end: +} +\cs_new:Npn \tl_rescan:nn #1#2 { + \group_begin: + \etex_everyeof:D { \exp_not:N } + \tex_endlinechar:D = \c_minus_one + #1 + \toks_set:Nx \l_tmpa_toks { \etex_scantokens:D {#2} } + \exp_args:NV \group_end: \l_tmpa_toks +} +\prg_new_protected_conditional:Npnn \tl_if_in:Nn #1#2 {TF,T,F} { + \cs_set:Npn \tl_tmp:w ##1 #2 ##2 \q_stop { + \quark_if_no_value:nTF {##2} {\prg_return_false:} {\prg_return_true:} + } + \exp_after:wN \tl_tmp:w #1 #2 \q_no_value \q_stop +} +\cs_generate_variant:Nn \tl_if_in:NnTF {c} +\cs_generate_variant:Nn \tl_if_in:NnT {c} +\cs_generate_variant:Nn \tl_if_in:NnF {c} +\prg_new_protected_conditional:Npnn \tl_if_in:nn #1#2 {TF,T,F} { + \cs_set:Npn \tl_tmp:w ##1 #2 ##2 \q_stop { + \quark_if_no_value:nTF {##2} {\prg_return_false:} {\prg_return_true:} + } + \tl_tmp:w #1 #2 \q_no_value \q_stop +} +\cs_generate_variant:Nn \tl_if_in:nnTF {V} +\cs_generate_variant:Nn \tl_if_in:nnT {V} +\cs_generate_variant:Nn \tl_if_in:nnF {V} +\cs_generate_variant:Nn \tl_if_in:nnTF {o} +\cs_generate_variant:Nn \tl_if_in:nnT {o} +\cs_generate_variant:Nn \tl_if_in:nnF {o} +%%\l_tl_replace_toks % moved to l3token as alloc not set up yet. +\cs_new:Npn \tl_replace_in_aux:NNnn #1#2#3#4{ + \cs_set:Npn \tl_tmp:w ##1#3##2\q_stop{ + \quark_if_no_value:nF{##2} + { + \toks_set:No\l_tl_replace_toks{##1#4} + \cs_set:Npn \tl_tmp:w ####1#3\q_no_value{ + \toks_put_right:No \l_tl_replace_toks { ####1 } + } + \tl_tmp:w \prg_do_nothing: ##2 + #1#2{\toks_use:N\l_tl_replace_toks} + } + } + \use:n{\exp_after:wN \tl_tmp:w\exp_after:wN\prg_do_nothing:} + #2#3 \q_no_value\q_stop +} +\cs_new_nopar:Npn \tl_replace_in:Nnn {\tl_replace_in_aux:NNnn \tl_set:Nx} +\cs_generate_variant:Nn\tl_replace_in:Nnn {cnn} +\cs_new_nopar:Npn \tl_greplace_in:Nnn {\tl_replace_in_aux:NNnn \tl_gset:Nx} +\cs_generate_variant:Nn\tl_greplace_in:Nnn {cnn} +\cs_set:Npn \tl_replace_all_in_aux:NNnn #1#2#3#4{ + \toks_clear:N \l_tl_replace_toks + \cs_set:Npn \tl_tmp:w ##1#3##2\q_stop{ + \quark_if_no_value:nTF{##2} + { + \toks_put_right:No \l_tl_replace_toks {##1} + } + { + \toks_put_right:No \l_tl_replace_toks {##1 #4} + \tl_tmp:w \prg_do_nothing: ##2 \q_stop + } + } + \use:n{\exp_after:wN \tl_tmp:w \exp_after:wN \prg_do_nothing:} + #2#3 \q_no_value\q_stop + #1#2{\toks_use:N\l_tl_replace_toks} +} +\cs_new_nopar:Npn \tl_replace_all_in:Nnn { + \tl_replace_all_in_aux:NNnn \tl_set:Nx} +\cs_generate_variant:Nn \tl_replace_all_in:Nnn {cnn} +\cs_new_nopar:Npn \tl_greplace_all_in:Nnn { + \tl_replace_all_in_aux:NNnn \tl_gset:Nx} +\cs_generate_variant:Nn \tl_greplace_all_in:Nnn {cnn} +\cs_new:Npn \tl_remove_in:Nn #1#2{\tl_replace_in:Nnn #1{#2}{}} +\cs_new:Npn \tl_gremove_in:Nn #1#2{\tl_greplace_in:Nnn #1{#2}{}} +\cs_generate_variant:Nn \tl_remove_in:Nn {cn} +\cs_generate_variant:Nn \tl_gremove_in:Nn {cn} +\cs_new:Npn \tl_remove_all_in:Nn #1#2{ + \tl_replace_all_in:Nnn #1{#2}{} +} +\cs_new:Npn \tl_gremove_all_in:Nn #1#2{ + \tl_greplace_all_in:Nnn #1{#2}{} +} +\cs_generate_variant:Nn \tl_remove_all_in:Nn {cn} +\cs_generate_variant:Nn \tl_gremove_all_in:Nn {cn} +\cs_new:Npn \tl_head:n #1{\tl_head:w #1\q_nil} +\cs_new_eq:NN \tl_head_i:n \tl_head:n +\cs_new:Npn \tl_tail:n #1{\tl_tail:w #1\q_nil} +\cs_generate_variant:Nn \tl_tail:n {f} +\cs_new:Npn \tl_head_iii:n #1{\tl_head_iii:w #1\q_nil} +\cs_generate_variant:Nn \tl_head_iii:n {f} +\cs_new_eq:NN \tl_head:w \use_i_delimit_by_q_nil:nw +\cs_new_eq:NN \tl_head_i:w \tl_head:w +\cs_new:Npn \tl_tail:w #1#2\q_nil{#2} +\cs_new:Npn \tl_head_iii:w #1#2#3#4\q_nil{#1#2#3} +\prg_new_conditional:Npnn \tl_if_head_eq_meaning:nN #1#2 {p,TF,T,F} { + \exp_after:wN \if_meaning:w \tl_head:w #1 \q_nil #2 + \prg_return_true: \else: \prg_return_false: \fi: +} +\prg_new_conditional:Npnn \tl_if_head_eq_charcode:nN #1#2 {p,TF,T,F} { + \exp_after:wN \if:w \exp_after:wN \exp_not:N + \tl_head:w #1 \q_nil \exp_not:N #2 + \prg_return_true: \else: \prg_return_false: \fi: +} +%% \cs_new:Npn \tl_if_head_eq_charcode_p:fN #1#2{ +%% \exp_after:wN\if_charcode:w \tl_head:w #1\q_nil\exp_not:N#2 +%% \c_true_bool +%% \else: +%% \c_false_bool +%% \fi: +%% } +%% \def_long_test_function_new:npn {tl_if_head_eq_charcode:fN}#1#2{ +%% \if_predicate:w \tl_if_head_eq_charcode_p:fN {#1}#2} +\cs_generate_variant:Nn \tl_if_head_eq_charcode_p:nN {f} +\cs_generate_variant:Nn \tl_if_head_eq_charcode:nNTF {f} +\cs_generate_variant:Nn \tl_if_head_eq_charcode:nNT {f} +\cs_generate_variant:Nn \tl_if_head_eq_charcode:nNF {f} +\prg_new_conditional:Npnn \tl_if_head_eq_catcode:nN #1#2 {p,TF,T,F} { + \exp_after:wN \if_catcode:w \exp_after:wN \exp_not:N + \tl_head:w #1 \q_nil \exp_not:N #2 + \prg_return_true: \else: \prg_return_false: \fi: +} +%% +%% +%% End of file `l3tl.sty'. diff --git a/Master/texmf-dist/tex/latex/expl3/l3tlp.sty b/Master/texmf-dist/tex/latex/expl3/l3tlp.sty deleted file mode 100644 index 1867f9e2e0e..00000000000 --- a/Master/texmf-dist/tex/latex/expl3/l3tlp.sty +++ /dev/null @@ -1,506 +0,0 @@ -%% -%% This is file `l3tlp.sty', -%% generated with the docstrip utility. -%% -%% The original source files were: -%% -%% l3tlp.dtx (with options: `package,trace') -%% -%% -%% EXPERIMENTAL CODE -%% -%% Do not distribute this file without also distributing the -%% source files specified above. -%% -%% Do not distribute a modified version of this file. -%% -%% -%% File: l3tlp.dtx Copyright (C) 1990-2008 LaTeX3 project -%% -%% It may be distributed and/or modified under the conditions of the -%% LaTeX Project Public License (LPPL), either version 1.3c of this -%% license or (at your option) any later version. The latest version -%% of this license is in the file -%% -%% http://www.latex-project.org/lppl.txt -%% -%% This file is part of the ``expl3 bundle'' (The Work in LPPL) -%% and all files in that bundle must be distributed together. -%% -%% The released version of this bundle is available from CTAN. -%% -%% ----------------------------------------------------------------------- -%% -%% The development version of the bundle can be found at -%% -%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/ -%% -%% for those people who are interested. -%% -%%%%%%%%%%% -%% NOTE: %% -%%%%%%%%%%% -%% -%% Snapshots taken from the repository represent work in progress and may -%% not work or may contain conflicting material! We therefore ask -%% people _not_ to put them into distributions, archives, etc. without -%% prior consultation with the LaTeX Project Team. -%% -%% ----------------------------------------------------------------------- -\RequirePackage{l3names} -\GetIdInfo$Id: l3tlp.dtx 767 2008-08-05 19:44:21Z morten $ - {L3 Experimental Token List Pointers} -\ProvidesExplPackage - {\filename}{\filedate}{\fileversion}{\filedescription} -\RequirePackage{l3basics} -\def_long_new:Npn \tlp_new:Nn #1#2{ - \chk_new_cs:N #1 - \gdef:Npn #1{#2} -} -\def_new:Npn \tlp_new:cn {\exp_args:Nc \tlp_new:Nn } -\def_long_new:Npn \tlp_new:Nx #1#2{ - \chk_new_cs:N #1 - \gdef:Npx #1{#2} -} -\def_new:Npn \tlp_new:N #1{\tlp_new:Nn #1{}} -\def_new:Npn \tlp_new:c #1{\tlp_new:cn {#1}{}} -\def_new:Npn \tlp_use:N #1 { - \if_meaning:NN #1 \scan_stop: - \err_latex_bug:x {Token~list~pointer~ `\token_to_string:N #1'~ - has~ an~ erroneous~ structure!} - \else: - \exp_after:NN #1 - \fi: -} -\def_new:Npn \tlp_use:c {\exp_args:Nc \tlp_use:N} -\def_long_new:Npn\tlp_set:Nn#1#2{\def:Npn#1{#2}} -\def_long_new:Npn\tlp_set:Nx#1#2{\def:Npx#1{#2}} -\def_long_new:Npn\tlp_gset:Nn#1#2{\gdef:Npn#1{#2}} -\def_long_new:Npn\tlp_gset:Nx#1#2{\gdef:Npx#1{#2}} -\def_new:Npn \tlp_set:No {\exp_args:NNo \tlp_set:Nn} -\def_new:Npn \tlp_set:Nd {\exp_args:NNd \tlp_set:Nn} -\def_new:Npn \tlp_set:Nf {\exp_args:NNf \tlp_set:Nn} -\def_new:Npn \tlp_set:cn {\exp_args:Nc \tlp_set:Nn} -\def_new:Npn \tlp_set:co {\exp_args:Nco \tlp_set:Nn} -\def_new:Npn \tlp_set:cx {\exp_args:Nc \tlp_set:Nx} -\def_new:Npn \tlp_gset:No {\exp_args:NNo \tlp_gset:Nn} -\def_new:Npn \tlp_gset:Nd {\exp_args:NNd \tlp_gset:Nn} -\def_new:Npn \tlp_gset:cn {\exp_args:Nc \tlp_gset:Nn} -\def_new:Npn \tlp_gset:cx {\exp_args:Nc \tlp_gset:Nx} -\let_new:NN \tlp_set_eq:NN \let:NN -\let_new:NN \tlp_gset_eq:NN \glet:NN -\def_new:Npn \tlp_set_eq:Nc {\exp_args:NNc \tlp_set_eq:NN} -\def_new:Npn \tlp_set_eq:cN {\exp_args:Nc \tlp_set_eq:NN} -\def_new:Npn \tlp_set_eq:cc {\exp_args:Ncc \tlp_set_eq:NN} -\def_new:Npn \tlp_gset_eq:Nc {\exp_args:NNc \tlp_gset_eq:NN} -\def_new:Npn \tlp_gset_eq:cN {\exp_args:Nc \tlp_gset_eq:NN} -\def_new:Npn \tlp_gset_eq:cc {\exp_args:Ncc \tlp_gset_eq:NN} -\def_new:Npn \tlp_clear:N #1{\tlp_set_eq:NN #1\c_empty_tlp} -\def_new:Npn \tlp_clear:c {\exp_args:Nc \tlp_clear:N} -\def_new:Npn \tlp_gclear:N #1{\tlp_gset_eq:NN #1\c_empty_tlp} -\def_new:Npn \tlp_gclear:c {\exp_args:Nc \tlp_gclear:N} -\let_new:NN \tlp_clear_new:N \tlp_clear:N -\def_new:Npn \tlp_clear_new:c {\exp_args:Nc \tlp_clear_new:N} -\let_new:NN \tlp_gclear_new:N \tlp_gclear:N -\def_new:Npn \tlp_gclear_new:c {\exp_args:Nc \tlp_gclear_new:N} -\def_long_new:Npn \tlp_put_left:Nn #1#2{ - \tlp_set:Nn \l_exp_tlp{#2} - \tlp_set:Nx #1{\exp_not:o{\l_exp_tlp}\exp_not:o{#1}} -} -\def_long_new:Npn \tlp_put_left:No #1#2{ - \tlp_set:Nn \l_exp_tlp{#2} - \tlp_set:Nx #1{\exp_not:d{\l_exp_tlp}\exp_not:o{#1}} -} -\def_long_new:Npn \tlp_put_left:Nx #1#2{ - \tlp_set:Nx #1{#2\exp_not:o{#1}} -} -\def_long_new:Npn \tlp_gput_left:Nn #1#2{ - \tlp_set:Nn \l_exp_tlp{#2} - \tlp_gset:Nx #1{\exp_not:o{\l_exp_tlp}\exp_not:o{#1}} -} -\def_long_new:Npn \tlp_gput_left:No #1#2{ - \tlp_set:Nn \l_exp_tlp{#2} - \tlp_gset:Nx #1{\exp_not:d{\l_exp_tlp}\exp_not:o{#1}} -} -\def_long_new:Npn \tlp_gput_left:Nx #1#2{ - \tlp_gset:Nx #1{#2\exp_not:o{#1}} -} -\def_long_new:Npn \tlp_put_left:cn{\exp_args:Nc\tlp_put_left:Nn} -\def_long_new:Npn \tlp_put_left:co{\exp_args:Nc\tlp_put_left:No} -\def_long_new:Npn \tlp_put_left:cx{\exp_args:Nc\tlp_put_left:Nx} -\def_long_new:Npn \tlp_gput_left:cn{\exp_args:Nc\tlp_gput_left:Nn} -\def_long_new:Npn \tlp_gput_left:co{\exp_args:Nc\tlp_gput_left:No} -\def_long_new:Npn \tlp_gput_left:cx{\exp_args:Nc\tlp_gput_left:Nx} -\def_long_new:Npn \tlp_put_right:Nn #1#2{ - \tlp_set:Nn \l_exp_tlp{#2} - \tlp_set:Nx #1{\exp_not:o{#1}\exp_not:o{\l_exp_tlp}} -} -\def_long_new:Npn \tlp_gput_right:Nn #1#2{ - \tlp_set:Nn \l_exp_tlp{#2} - \tlp_gset:Nx #1{\exp_not:o{#1}\exp_not:o{\l_exp_tlp}} -} -\def_long_new:Npn \tlp_put_right:No #1#2{ - \tlp_set:Nn \l_exp_tlp{#2} - \tlp_set:Nx #1{\exp_not:o{#1}\exp_not:d{\l_exp_tlp}} -} -\def_long_new:Npn \tlp_gput_right:No #1#2{ - \tlp_set:Nn \l_exp_tlp{#2} - \tlp_gset:Nx #1{\exp_not:o{#1}\exp_not:d{\l_exp_tlp}} -} -\def_long:Npn \tlp_put_right:Nx #1#2{ - \tlp_set:Nx #1{\exp_not:o{#1}#2} -} -\def_long:Npn \tlp_gput_right:Nx #1#2{ - \tlp_gset:Nx #1{\exp_not:o{#1}#2} -} -\def_new:Npn \tlp_gput_right:cn {\exp_args:Nc \tlp_gput_right:Nn} -\def_new:Npn \tlp_gput_right:co {\exp_args:Nc \tlp_gput_right:No} -\def_new:Npn \tlp_put_right:cc {\exp_args:Ncc \tlp_put_right:Nn} -\def_new:Npn \tlp_gset:Nc { - \pref_global:D - \tlp_set:Nc} -\def_new:Npn \tlp_set:Nc #1#2{\tlp_set:No #1{\cs:w#2\cs_end:}} -\def_new:Npn \tlp_if_empty_p:N #1{ - \if_meaning:NN#1\c_empty_tlp \c_true \else: \c_false \fi:} -\def_new:Npn \tlp_if_empty_p:c {\exp_args:Nc\tlp_if_empty_p:N} -\def_test_function_new:npn {tlp_if_empty:N} #1{ - \if_meaning:NN#1\c_empty_tlp} -\def_new:Npn \tlp_if_empty:cTF {\exp_args:Nc \tlp_if_empty:NTF} -\def_new:Npn \tlp_if_empty:cT {\exp_args:Nc \tlp_if_empty:NT} -\def_new:Npn \tlp_if_empty:cF {\exp_args:Nc \tlp_if_empty:NF} -\def_new:Npn \tlp_if_eq_p:NN #1#2{ - \if_meaning:NN#1#2 \c_true \else: \c_false \fi:} -\def_new:Npn \tlp_if_eq_p:Nc {\exp_args:NNc\tlp_if_empty_p:NN} -\def_new:Npn \tlp_if_eq_p:cN {\exp_args:Nc\tlp_if_empty_p:NN} -\def_new:Npn \tlp_if_eq_p:cc {\exp_args:Ncc\tlp_if_empty_p:NN} -\def_test_function_new:npn {tlp_if_eq:NN} #1#2{\if_meaning:NN#1#2} -\def_new:Npn \tlp_if_eq:cNTF{\exp_args:Nc \tlp_if_eq:NNTF} -\def_new:Npn \tlp_if_eq:cNT {\exp_args:Nc \tlp_if_eq:NNT} -\def_new:Npn \tlp_if_eq:cNF {\exp_args:Nc \tlp_if_eq:NNF} -\def_new:Npn \tlp_if_eq:NcTF{\exp_args:NNc \tlp_if_eq:NNTF} -\def_new:Npn \tlp_if_eq:NcT {\exp_args:NNc \tlp_if_eq:NNT} -\def_new:Npn \tlp_if_eq:NcF {\exp_args:NNc \tlp_if_eq:NNF} -\def_new:Npn \tlp_if_eq:ccTF{\exp_args:Ncc \tlp_if_eq:NNTF} -\def_new:Npn \tlp_if_eq:ccT {\exp_args:Ncc \tlp_if_eq:NNT} -\def_new:Npn \tlp_if_eq:ccF {\exp_args:Ncc \tlp_if_eq:NNF} -\tlp_new:Nn \c_empty_tlp {} -\tlp_new:Nn \c_relax_tlp {\scan_stop:} -\tlp_new:Nn \g_tmpa_tlp{} -\tlp_new:Nn \g_tmpb_tlp{} -\tlp_new:Nn \l_testa_tlp {} -\tlp_new:Nn \l_testb_tlp {} -\tlp_new:Nn \g_testa_tlp {} -\tlp_new:Nn \g_testb_tlp {} -\tlp_new:Nn \l_tmpa_tlp{} -\tlp_new:Nn \l_tmpb_tlp{} -\def_new:Npn \tlp_to_str:N {\exp_after:NN\tlp_to_str_aux:w - \token_to_meaning:N} -\def_new:Npn \tlp_to_str_aux:w #1>{} -\def_new:Npn\tlp_to_str:c{\exp_args:Nc\tlp_to_str:N} -\def_long_new:Npn \tlist_if_empty_p:n #1{ - \exp_after:NN\if_meaning:NN\exp_after:NN\q_nil\tlist_to_str:n{#1}\q_nil - \c_true - \else: - \c_false - \fi: -} -\def_new:Npn \tlist_if_empty_p:o {\exp_args:No\tlist_if_empty_p:n} -\def_long_test_function_new:npn{tlist_if_empty:n}#1{ - \if:w\tlist_if_empty_p:n{#1}} -\def_long_test_function_new:npn{tlist_if_empty:o}#1{ - \if:w\tlist_if_empty_p:o{#1}} -\def_long_new:Npn \tlist_if_blank_p:n #1{ - \exp_after:NN\tlist_if_blank_p_aux:w\tlist_to_str:n{#1}aa..\q_nil -} -\def_new:Npn \tlist_if_blank_p_aux:w #1#2a#3#4\q_nil{ - \if_meaning:NN #3#4\c_true\else:\c_false\fi:} -\def_long_test_function_new:npn{tlist_if_blank:n}#1{ - \if:w\tlist_if_blank_p:n{#1}} -\def:Npn \tlist_if_blank_p:o{\exp_args:No\tlist_if_blank_p:n} -\def_long_test_function_new:npn{tlist_if_blank:o}#1{ - \if:w\tlist_if_blank_p:o{#1}} -\let_new:NN \tlist_to_lowercase:n \tex_lowercase:D -\let_new:NN \tlist_to_uppercase:n \tex_uppercase:D -\let_new:NN \tlist_to_str:n \etex_detokenize:D -\def_long_new:Npn \tlist_map_function:nN #1#2{ - \tlist_map_function_aux:Nn #2 #1 \q_recursion_tail \q_recursion_stop -} -\def_new:Npn \tlp_map_function:NN #1#2{ - \exp_after:NN \tlist_map_function_aux:Nn - \exp_after:NN #2 #1 \q_recursion_tail \q_recursion_stop -} -\def_long_new:Npn \tlist_map_function_aux:Nn #1#2{ - \quark_if_recursion_tail_stop:n{#2} - #1{#2} \tlist_map_function_aux:Nn #1 -} -\def_new:Npn\tlp_map_function:cN{\exp_args:Nc\tlp_map_function:NN} -\def_long_new:Npn \tlist_map_inline:nn #1#2{ - \num_gincr:N \g_tlp_inline_level_num - \gdef_long:cpn {tlist_map_inline_ \num_use:N \g_tlp_inline_level_num :n} - ##1{#2} - \exp_args:Nc \tlist_map_function_aux:Nn - {tlist_map_inline_ \num_use:N \g_tlp_inline_level_num :n} - #1 \q_recursion_tail\q_recursion_stop - \num_gdecr:N \g_tlp_inline_level_num -} -\def_long_new:Npn \tlp_map_inline:Nn #1#2{ - \num_gincr:N \g_tlp_inline_level_num - \gdef_long:cpn {tlist_map_inline_ \num_use:N \g_tlp_inline_level_num :n} - ##1{#2} - \exp_args:NcE \tlist_map_function_aux:Nn - {tlist_map_inline_ \num_use:N \g_tlp_inline_level_num :n} - #1 \q_recursion_tail\q_recursion_stop - \num_gdecr:N \g_tlp_inline_level_num -} -\def_new:Npn\tlp_map_inline:cN{\exp_args:Nc\tlp_map_inline:NN} -\tlp_new:Nn \g_tlp_inline_level_num{0} -\def_long_new:Npn \tlist_map_variable:nNn #1#2#3{ - \tlist_map_variable_aux:Nnn #2 {#3} #1 \q_recursion_tail \q_recursion_stop -} -\def_new:Npn \tlp_map_variable:NNn {\exp_args:No \tlist_map_variable:nNn} -\def_new:Npn \tlp_map_variable:cNn {\exp_args:Nc \tlp_map_variable:NNn} -\def_long_new:Npn \tlist_map_variable_aux:Nnn #1#2#3{ - \tlp_set:Nn #1{#3} - \quark_if_recursion_tail_stop:N #1 - #2 \tlist_map_variable_aux:Nnn #1{#2} -} -\let_new:NN \tlist_map_break:w \use_none_delimit_by_q_recursion_stop:w -\let_new:NN \tlp_map_break:w \tlist_map_break:w -\def_long_new:Npn \tlist_elt_count:n #1{ - \num_value:w \num_eval:w 0 - \tlist_map_function:nN {#1}\num_elt_count:n - \num_eval_end: -} -\def_new:Npn \tlist_elt_count:o {\exp_args:No\tlist_elt_count:n} -\def_new:Npn \tlp_elt_count:N #1{ - \num_value:w \num_eval:w 0 - \tlp_map_function:NN #1 \num_elt_count:n - \num_eval_end: -} -\let_new:NN \tlist_compare:xx \pdfstrcmp -\def_long_new:NNn \tlist_compare:nn 2{ - \tlist_compare:xx{\exp_not:n{#1}}{\exp_not:n{#2}} -} -\def_long_new:NNn \tlist_compare:nx 1{ - \tlist_compare:xx{\exp_not:n{#1}} -} -\def_long_new:NNn \tlist_compare:xn 2{ - \tlist_compare:xx{#1}{\exp_not:n{#2}} -} -\def_long_new:NNn \tlist_compare:no 2{ - \tlist_compare:xx{\exp_not:n{#1}}{\exp_not:n\exp_after:NN{#2}} -} -\def_long_new:NNn \tlist_compare:on 2{ - \tlist_compare:xx{\exp_not:n\exp_after:NN{#1}}{\exp_not:n{#2}} -} -\def_long_new:NNn \tlist_compare:oo 2{ - \tlist_compare:xx{\exp_not:n\exp_after:NN{#1}}{\exp_not:n\exp_after:NN{#2}} -} -\def_long_new:NNn \tlist_compare:xo 2{ - \tlist_compare:xx{#1}{\exp_not:n\exp_after:NN{#2}} -} -\def_long_new:NNn \tlist_compare:ox 2{ - \tlist_compare:xx{\exp_not:n\exp_after:NN{#1}}{\exp_not:n{#2}} -} -\def:Npn \tmp:w #1{ - \def_long_new:cNx {tlist_if_eq_p:#1} 2{ - \exp_not:N \if_num:w - \exp_after:NN \exp_not:N \cs:w tlist_compare:#1\cs_end:{##1}{##2} - \exp_not:n{ =\c_zero \c_true \else: \c_false \fi: } - } - \def_long_test_function_new:npx{tlist_if_eq:#1}##1##2{ - \exp_not:N \if_num:w - \exp_after:NN \exp_not:N \cs:w tlist_compare:#1\cs_end:{##1}{##2} - \exp_not:n{ =\c_zero } - } -} -\tmp:w{xx} \tmp:w{nn} \tmp:w{oo} \tmp:w{xn} \tmp:w{nx} -\tmp:w{on} \tmp:w{no} \tmp:w{xo} \tmp:w{ox} -\cs_if_really_free:cT{pdf_strcmp:D}{ - \def_long_test_function:npn{tlist_if_eq:nn}#1#2{ - \tlp_set:Nx \l_testa_tlp {\exp_not:n{#1}} - \tlp_set:Nx \l_testb_tlp {\exp_not:n{#2}} - \if_meaning:NN\l_testa_tlp \l_testb_tlp - } - \def_long_test_function:npn{tlist_if_eq:no}#1#2{ - \tlp_set:Nx \l_testa_tlp {\exp_not:n{#1}} - \tlp_set:Nx \l_testb_tlp {\exp_not:o{#2}} - \if_meaning:NN\l_testa_tlp \l_testb_tlp - } - \def_long_test_function:npn{tlist_if_eq:nx}#1#2{ - \tlp_set:Nx \l_testa_tlp {\exp_not:n{#1}} - \tlp_set:Nx \l_testb_tlp {#2} - \if_meaning:NN\l_testa_tlp \l_testb_tlp - } - \def_long_test_function:npn{tlist_if_eq:on}#1#2{ - \tlp_set:Nx \l_testa_tlp {\exp_not:o{#1}} - \tlp_set:Nx \l_testb_tlp {\exp_not:n{#2}} - \if_meaning:NN\l_testa_tlp \l_testb_tlp - } - \def_long_test_function:npn{tlist_if_eq:oo}#1#2{ - \tlp_set:Nx \l_testa_tlp {\exp_not:o{#1}} - \tlp_set:Nx \l_testb_tlp {\exp_not:o{#2}} - \if_meaning:NN\l_testa_tlp \l_testb_tlp - } - \def_long_test_function:npn{tlist_if_eq:ox}#1#2{ - \tlp_set:Nx \l_testa_tlp {\exp_not:o{#1}} - \tlp_set:Nx \l_testb_tlp {#2} - \if_meaning:NN\l_testa_tlp \l_testb_tlp - } - \def_long_test_function:npn{tlist_if_eq:xn}#1#2{ - \tlp_set:Nx \l_testa_tlp {#1} - \tlp_set:Nx \l_testb_tlp {\exp_not:n{#2}} - \if_meaning:NN\l_testa_tlp \l_testb_tlp - } - \def_long_test_function:npn{tlist_if_eq:xo}#1#2{ - \tlp_set:Nx \l_testa_tlp {#1} - \tlp_set:Nx \l_testb_tlp {\exp_not:o{#2}} - \if_meaning:NN\l_testa_tlp \l_testb_tlp - } - \def_long_test_function:npn{tlist_if_eq:xx}#1#2{ - \tlp_set:Nx \l_testa_tlp {#1} - \tlp_set:Nx \l_testb_tlp {#2} - \if_meaning:NN\l_testa_tlp \l_testb_tlp - } -} -\def_long:Npn \tlp_if_in:NnTF #1#2{ - \def_long:Npn\tmp:w ##1 #2 ##2\q_stop{ - \quark_if_no_value:nFT{##2} - } - \exp_after:NN \tmp:w #1 #2 \q_no_value \q_stop -} -\def_new:Npn \tlp_if_in:cnTF {\exp_args:Nc\tlp_if_in:NnTF} -\def_long:Npn \tlp_if_in:NnT #1#2{ - \def_long:Npn\tmp:w ##1 #2 ##2\q_stop{ - \quark_if_no_value:nF{##2} - } - \exp_after:NN \tmp:w #1 #2 \q_no_value \q_stop -} -\def_new:Npn \tlp_if_in:cnT {\exp_args:Nc\tlp_if_in:NnT} -\def_long:Npn \tlp_if_in:NnF #1#2{ - \def_long:Npn\tmp:w ##1 #2 ##2\q_stop{ - \quark_if_no_value:nT{##2} - } - \exp_after:NN \tmp:w #1 #2 \q_no_value \q_stop -} -\def_new:Npn \tlp_if_in:cnF {\exp_args:Nc\tlp_if_in:NnF} -\def_long_new:Npn \tlist_if_in:nnTF #1#2{ - \def_long:Npn\tmp:w ##1 #2 ##2\q_stop{ - \quark_if_no_value:nFT{##2} - } - \tmp:w #1 #2 \q_no_value \q_stop -} -\def_new:Npn \tlist_if_in:onTF {\exp_args:No\tlist_if_in:nnTF} -\tlp_new:Nn\l_tlp_replace_tlp{} -\def_long_new:NNn \tlp_replace_in_aux:NNnn 4{ - \def_long:Npn \tmp:w ##1#3##2\q_stop{ - \quark_if_no_value:nF{##2} - { - \tlp_set:Nx\l_tlp_replace_tlp{\exp_not:o{\use_none:n##1#4}} - \def_long:Npn \tmp:w ####1#3\q_no_value{ - \tlp_put_right:Nx \l_tlp_replace_tlp {\exp_not:o{\use_none:n ####1}} - } - \tmp:w \q_mark ##2 - } - #1#2\l_tlp_replace_tlp - } - \use_arg_i:n{\exp_after:NN \tmp:w\exp_after:NN\q_mark} - #2#3 \q_no_value\q_stop -} -\def_new:Npn \tlp_replace_in:Nnn {\tlp_replace_in_aux:NNnn \tlp_set_eq:NN} -\def_new:Npn \tlp_replace_in:cnn{\exp_args:Nc\tlp_replace_in:Nnn} -\def_new:Npn \tlp_greplace_in:Nnn {\tlp_replace_in_aux:NNnn \tlp_gset_eq:NN} -\def_new:Npn \tlp_greplace_in:cnn{\exp_args:Nc\tlp_greplace_in:Nnn} -\def_long:NNn \tlp_replace_all_in_aux:NNnn 4{ - \tlp_clear:N \l_tlp_replace_tlp - \def_long:Npn \tmp:w ##1#3##2\q_stop{ - \quark_if_no_value:nTF{##2} - { - \tlp_put_right:Nx \l_tlp_replace_tlp {\exp_not:o{\use_none:n##1}} - } - { - \tlp_put_right:Nx \l_tlp_replace_tlp {\exp_not:o{\use_none:n##1 #4}} - \tmp:w \q_mark##2 \q_stop - } - } - \use_arg_i:n{\exp_after:NN \tmp:w\exp_after:NN\q_mark} - #2#3 \q_no_value\q_stop - #1#2\l_tlp_replace_tlp -} -\def_new:Npn \tlp_replace_all_in:Nnn { - \tlp_replace_all_in_aux:NNnn \tlp_set_eq:NN} -\def_new:Npn \tlp_replace_all_in:cnn{\exp_args:Nc\tlp_replace_all_in:Nnn} -\def_new:Npn \tlp_greplace_all_in:Nnn { - \tlp_replace_all_in_aux:NNnn \tlp_gset_eq:NN} -\def_new:Npn \tlp_greplace_all_in:cnn{\exp_args:Nc\tlp_greplace_all_in:Nnn} -\def_long_new:NNn \tlp_remove_in:Nn 2{\tlp_replace_in:Nnn #1{#2}{}} -\def_long_new:NNn \tlp_gremove_in:Nn 2{\tlp_greplace_in:Nnn #1{#2}{}} -\def_new:Npn \tlp_remove_in:cn{\exp_args:Nc\tlp_remove_in:Nn} -\def_new:Npn \tlp_gremove_in:cn{\exp_args:Nc\tlp_gremove_in:Nn} -\def_long_new:Npn \tlp_remove_all_in:Nn #1#2{ - \tlp_replace_all_in:Nnn #1{#2}{} -} -\def_long_new:Npn \tlp_gremove_all_in:Nn #1#2{ - \tlp_greplace_all_in:Nnn #1{#2}{} -} -\def_new:Npn \tlp_remove_all_in:cn{\exp_args:Nc\tlp_remove_all_in:Nn} -\def_new:Npn \tlp_gremove_all_in:cn{\exp_args:Nc\tlp_gremove_all_in:Nn} -\def_long_new:Npn \tlist_head:n #1{\tlist_head:w #1\q_nil} -\let_new:NN \tlist_head_i:n \tlist_head:n -\def_long_new:Npn \tlist_tail:n #1{\tlist_tail:w #1\q_nil} -\def_new:Npn \tlist_tail:f {\exp_args:Nf \tlist_tail:n} -\def_long_new:Npn \tlist_head_iii:n #1{\tlist_head_iii:w #1\q_nil} -\def_new:Npn \tlist_head_iii:f {\exp_args:Nf \tlist_head_iii:n} -\let_new:NN \tlist_head:w \use_arg_i_delimit_by_q_nil:nw -\def_long_new:Npn \tlist_tail:w #1#2\q_nil{#2} -\def_long_new:Npn \tlist_head_iii:w #1#2#3#4\q_nil{#1#2#3} -\def_long_new:Npn \tlist_if_head_eq_meaning_p:nN #1#2{ - \exp_after:NN \if_meaning:NN \tlist_head:w #1\q_nil#2 - \c_true - \else: - \c_false - \fi: -} -\def_long_test_function_new:npn {tlist_if_head_eq_meaning:nN}#1#2{ - \if:w \tlist_if_head_eq_meaning_p:nN{#1}#2} -\def_long_new:Npn \tlist_if_head_eq_charcode_p:nN #1#2{ - \exp_after:NN\if_charcode:w \exp_after:NN\exp_not:N - \tlist_head:w #1\q_nil\exp_not:N#2 - \c_true - \else: - \c_false - \fi: -} -\def_long_test_function_new:npn {tlist_if_head_eq_charcode:nN}#1#2{ - \if:w\tlist_if_head_eq_charcode_p:nN{#1}#2} -\def_long_new:Npn \tlist_if_head_eq_charcode_p:fN #1#2{ - \exp_after:NN\if_charcode:w \tlist_head:w #1\q_nil\exp_not:N#2 - \c_true - \else: - \c_false - \fi: -} -\def_long_test_function_new:npn {tlist_if_head_eq_charcode:fN}#1#2{ - \if:w\tlist_if_head_eq_charcode_p:fN{#1}#2} -\def_long_new:Npn \tlist_if_head_eq_catcode_p:nN #1#2{ - \exp_after:NN\if_charcode:w \exp_after:NN\exp_not:N - \tlist_head:w #1\q_nil\exp_not:N#2 - \c_true - \else: - \c_false - \fi: -} -\def_long_test_function_new:npn {tlist_if_head_eq_catcode:nN}#1#2{ - \if:w\tlist_if_head_eq_catcode_p:nN{#1}#2} -\def_long_new:Npn \tlist_reverse:n #1{ - \tlist_reverse_aux:nN {} #1 \q_recursion_tail\q_recursion_stop -} -\def_long_new:Npn \tlist_reverse_aux:nN #1#2{ - \quark_if_recursion_tail_stop_do:nn {#2}{ #1 } - \tlist_reverse_aux:nN {#2#1} -} -\RequirePackage{l3expan} -\RequirePackage{l3num}\par -%% -%% -%% End of file `l3tlp.sty'. diff --git a/Master/texmf-dist/tex/latex/expl3/l3token.sty b/Master/texmf-dist/tex/latex/expl3/l3token.sty index b9f43418038..034312a4707 100644 --- a/Master/texmf-dist/tex/latex/expl3/l3token.sty +++ b/Master/texmf-dist/tex/latex/expl3/l3token.sty @@ -15,7 +15,7 @@ %% Do not distribute a modified version of this file. %% %% -%% File: l3token.dtx Copyright (C) 2005-2006 LaTeX3 project +%% File: l3token.dtx Copyright (C) 2005-2009 LaTeX3 project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this @@ -33,7 +33,7 @@ %% %% The development version of the bundle can be found at %% -%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/ +%% http://www.latex-project.org/svnroot/experimental/trunk/ %% %% for those people who are interested. %% @@ -48,64 +48,108 @@ %% %% ----------------------------------------------------------------------- \RequirePackage{l3names} -\GetIdInfo$Id: l3token.dtx 701 2007-11-27 14:21:05Z morten $ +\GetIdInfo$Id: l3token.dtx 1365 2009-05-31 17:26:17Z mittelba $ {L3 Experimental token investigation and manipulation} \ProvidesExplPackage {\filename}{\filedate}{\fileversion}{\filedescription} -\RequirePackage{l3prg} -\RequirePackage{l3int} -\let_new:NN \char_set_catcode:w \tex_catcode:D -\def_new:Npn \char_set_catcode:nn #1#2{ - \char_set_catcode:w #1 = \int_eval:n{#2} -} -\def_new:Npn \char_value_catcode:w {\int_use:N\tex_catcode:D} -\def_new:Npn \char_value_catcode:n #1{\char_value_catcode:w \int_eval:n{#1}} -\def_new:Npn \char_show_value_catcode:w {\tex_showthe:D\tex_catcode:D} -\def_new:Npn \char_show_value_catcode:n #1{ - \char_show_value_catcode:w \int_eval:n{#1}} -\let_new:NN \char_set_mathcode:w \tex_mathcode:D -\def_new:Npn \char_set_mathcode:nn #1#2{ - \char_set_mathcode:w #1 = \int_eval:n{#2} -} -\def_protected_new:Npn \char_gset_mathcode:w {\pref_global:D\tex_mathcode:D} -\def_new:Npn \char_gset_mathcode:nn #1#2{ - \char_gset_mathcode:w #1 = \int_eval:n{#2} -} -\def_new:Npn \char_value_mathcode:w {\int_use:N\tex_mathcode:D} -\def_new:Npn \char_value_mathcode:n #1{\char_value_mathcode:w \int_eval:n{#1}} -\def_new:Npn \char_show_value_mathcode:w {\tex_showthe:D\tex_mathcode:D} -\def_new:Npn \char_show_value_mathcode:n #1{ - \char_show_value_mathcode:w \int_eval:n{#1}} -\let_new:NN \char_set_lccode:w \tex_lccode:D -\def_new:Npn \char_set_lccode:nn #1#2{ - \char_set_lccode:w #1 = \int_eval:n{#2} -} -\def_new:Npn \char_value_lccode:w {\int_use:N\tex_lccode:D} -\def_new:Npn \char_value_lccode:n #1{\char_value_lccode:w \int_eval:n{#1}} -\def_new:Npn \char_show_value_lccode:w {\tex_showthe:D\tex_lccode:D} -\def_new:Npn \char_show_value_lccode:n #1{ - \char_show_value_lccode:w \int_eval:n{#1}} -\let_new:NN \char_set_uccode:w \tex_uccode:D -\def_new:Npn \char_set_uccode:nn #1#2{ - \char_set_uccode:w #1 = \int_eval:n{#2} -} -\def_new:Npn \char_value_uccode:w {\int_use:N\tex_uccode:D} -\def_new:Npn \char_value_uccode:n #1{\char_value_uccode:w \int_eval:n{#1}} -\def_new:Npn \char_show_value_uccode:w {\tex_showthe:D\tex_uccode:D} -\def_new:Npn \char_show_value_uccode:n #1{ - \char_show_value_uccode:w \int_eval:n{#1}} -\let_new:NN \char_set_sfcode:w \tex_sfcode:D -\def_new:Npn \char_set_sfcode:nn #1#2{ - \char_set_sfcode:w #1 = \int_eval:n{#2} -} -\def_new:Npn \char_value_sfcode:w {\int_use:N\tex_uccode:D} -\def_new:Npn \char_value_sfcode:n #1{\char_value_sfcode:w \int_eval:n{#1}} -\def_new:Npn \char_show_value_sfcode:w {\tex_showthe:D\tex_sfcode:D} -\def_new:Npn \char_show_value_sfcode:n #1{ - \char_show_value_sfcode:w \int_eval:n{#1}} -\def_new:Npn \token_new:Nn #1#2{\glet_new:NN #1#2} -\let_new:NN \c_group_begin_token { -\let_new:NN \c_group_end_token } +\package_check_loaded_expl: +\cs_new_eq:NN \char_set_catcode:w \tex_catcode:D +\cs_new_nopar:Npn \char_set_catcode:nn #1#2 { + \char_set_catcode:w #1 = \intexpr_eval:w #2\intexpr_eval_end: +} +\cs_new_nopar:Npn \char_value_catcode:w { \int_use:N \tex_catcode:D } +\cs_new_nopar:Npn \char_value_catcode:n #1 { + \char_value_catcode:w \intexpr_eval:w #1\intexpr_eval_end: +} +\cs_new_nopar:Npn \char_show_value_catcode:w { + \tex_showthe:D \tex_catcode:D +} +\cs_new_nopar:Npn \char_show_value_catcode:n #1 { + \char_show_value_catcode:w \intexpr_eval:w #1\intexpr_eval_end: +} +\cs_new_nopar:Npn \char_make_escape:N #1 { \char_set_catcode:nn {`#1} {\c_zero} } +\cs_new_nopar:Npn \char_make_begin_group:N #1 { \char_set_catcode:nn {`#1} {\c_one} } +\cs_new_nopar:Npn \char_make_end_group:N #1 { \char_set_catcode:nn {`#1} {\c_two} } +\cs_new_nopar:Npn \char_make_math_shift:N #1 { \char_set_catcode:nn {`#1} {\c_three} } +\cs_new_nopar:Npn \char_make_alignment:N #1 { \char_set_catcode:nn {`#1} {\c_four} } +\cs_new_nopar:Npn \char_make_end_line:N #1 { \char_set_catcode:nn {`#1} {\c_five} } +\cs_new_nopar:Npn \char_make_parameter:N #1 { \char_set_catcode:nn {`#1} {\c_six} } +\cs_new_nopar:Npn \char_make_math_superscript:N #1 { \char_set_catcode:nn {`#1} {\c_seven} } +\cs_new_nopar:Npn \char_make_math_subscript:N #1 { \char_set_catcode:nn {`#1} {\c_eight} } +\cs_new_nopar:Npn \char_make_ignore:N #1 { \char_set_catcode:nn {`#1} {\c_nine} } +\cs_new_nopar:Npn \char_make_space:N #1 { \char_set_catcode:nn {`#1} {\c_ten} } +\cs_new_nopar:Npn \char_make_letter:N #1 { \char_set_catcode:nn {`#1} {\c_eleven} } +\cs_new_nopar:Npn \char_make_other:N #1 { \char_set_catcode:nn {`#1} {\c_twelve} } +\cs_new_nopar:Npn \char_make_active:N #1 { \char_set_catcode:nn {`#1} {\c_thirteen} } +\cs_new_nopar:Npn \char_make_comment:N #1 { \char_set_catcode:nn {`#1} {\c_fourteen} } +\cs_new_nopar:Npn \char_make_invalid:N #1 { \char_set_catcode:nn {`#1} {\c_fifteen} } +\cs_new_nopar:Npn \char_make_escape:n #1 { \char_set_catcode:nn {#1} {\c_zero} } +\cs_new_nopar:Npn \char_make_begin_group:n #1 { \char_set_catcode:nn {#1} {\c_one} } +\cs_new_nopar:Npn \char_make_end_group:n #1 { \char_set_catcode:nn {#1} {\c_two} } +\cs_new_nopar:Npn \char_make_math_shift:n #1 { \char_set_catcode:nn {#1} {\c_three} } +\cs_new_nopar:Npn \char_make_alignment:n #1 { \char_set_catcode:nn {#1} {\c_four} } +\cs_new_nopar:Npn \char_make_end_line:n #1 { \char_set_catcode:nn {#1} {\c_five} } +\cs_new_nopar:Npn \char_make_parameter:n #1 { \char_set_catcode:nn {#1} {\c_six} } +\cs_new_nopar:Npn \char_make_math_superscript:n #1 { \char_set_catcode:nn {#1} {\c_seven} } +\cs_new_nopar:Npn \char_make_math_subscript:n #1 { \char_set_catcode:nn {#1} {\c_eight} } +\cs_new_nopar:Npn \char_make_ignore:n #1 { \char_set_catcode:nn {#1} {\c_nine} } +\cs_new_nopar:Npn \char_make_space:n #1 { \char_set_catcode:nn {#1} {\c_ten} } +\cs_new_nopar:Npn \char_make_letter:n #1 { \char_set_catcode:nn {#1} {\c_eleven} } +\cs_new_nopar:Npn \char_make_other:n #1 { \char_set_catcode:nn {#1} {\c_twelve} } +\cs_new_nopar:Npn \char_make_active:n #1 { \char_set_catcode:nn {#1} {\c_thirteen} } +\cs_new_nopar:Npn \char_make_comment:n #1 { \char_set_catcode:nn {#1} {\c_fourteen} } +\cs_new_nopar:Npn \char_make_invalid:n #1 { \char_set_catcode:nn {#1} {\c_fifteen} } +\cs_new_eq:NN \char_set_mathcode:w \tex_mathcode:D +\cs_new_nopar:Npn \char_set_mathcode:nn #1#2 { + \char_set_mathcode:w #1 = \intexpr_eval:w #2\intexpr_eval_end: +} +\cs_new_protected_nopar:Npn \char_gset_mathcode:w { \pref_global:D \tex_mathcode:D } +\cs_new_nopar:Npn \char_gset_mathcode:nn #1#2 { + \char_gset_mathcode:w #1 = \intexpr_eval:w #2\intexpr_eval_end: +} +\cs_new_nopar:Npn \char_value_mathcode:w { \int_use:N \tex_mathcode:D } +\cs_new_nopar:Npn \char_value_mathcode:n #1 { + \char_value_mathcode:w \intexpr_eval:w #1\intexpr_eval_end: +} +\cs_new_nopar:Npn \char_show_value_mathcode:w { \tex_showthe:D \tex_mathcode:D } +\cs_new_nopar:Npn \char_show_value_mathcode:n #1 { + \char_show_value_mathcode:w \intexpr_eval:w #1\intexpr_eval_end: +} +\cs_new_eq:NN \char_set_lccode:w \tex_lccode:D +\cs_new_nopar:Npn \char_set_lccode:nn #1#2{ + \char_set_lccode:w #1 = \intexpr_eval:w #2\intexpr_eval_end: +} +\cs_new_nopar:Npn \char_value_lccode:w {\int_use:N\tex_lccode:D} +\cs_new_nopar:Npn \char_value_lccode:n #1{\char_value_lccode:w + \intexpr_eval:w #1\intexpr_eval_end:} +\cs_new_nopar:Npn \char_show_value_lccode:w {\tex_showthe:D\tex_lccode:D} +\cs_new_nopar:Npn \char_show_value_lccode:n #1{ + \char_show_value_lccode:w \intexpr_eval:w #1\intexpr_eval_end:} +\cs_new_eq:NN \char_set_uccode:w \tex_uccode:D +\cs_new_nopar:Npn \char_set_uccode:nn #1#2{ + \char_set_uccode:w #1 = \intexpr_eval:w #2\intexpr_eval_end: +} +\cs_new_nopar:Npn \char_value_uccode:w {\int_use:N\tex_uccode:D} +\cs_new_nopar:Npn \char_value_uccode:n #1{\char_value_uccode:w + \intexpr_eval:w #1\intexpr_eval_end:} +\cs_new_nopar:Npn \char_show_value_uccode:w {\tex_showthe:D\tex_uccode:D} +\cs_new_nopar:Npn \char_show_value_uccode:n #1{ + \char_show_value_uccode:w \intexpr_eval:w #1\intexpr_eval_end:} +\cs_new_eq:NN \char_set_sfcode:w \tex_sfcode:D +\cs_new_nopar:Npn \char_set_sfcode:nn #1#2 { + \char_set_sfcode:w #1 = \intexpr_eval:w #2\intexpr_eval_end: +} +\cs_new_nopar:Npn \char_value_sfcode:w { \int_use:N \tex_sfcode:D } +\cs_new_nopar:Npn \char_value_sfcode:n #1 { + \char_value_sfcode:w \intexpr_eval:w #1\intexpr_eval_end: +} +\cs_new_nopar:Npn \char_show_value_sfcode:w { \tex_showthe:D \tex_sfcode:D } +\cs_new_nopar:Npn \char_show_value_sfcode:n #1 { + \char_show_value_sfcode:w \intexpr_eval:w #1\intexpr_eval_end: +} +\cs_new_nopar:Npn \token_new:Nn #1#2 {\cs_gnew_eq:NN #1#2} +\cs_new_eq:NN \c_group_begin_token { +\cs_new_eq:NN \c_group_end_token } \group_begin: \char_set_catcode:nn{`\*}{3} \token_new:Nn \c_math_shift_token {*} @@ -119,260 +163,174 @@ \token_new:Nn \c_letter_token {a} \token_new:Nn \c_other_char_token {1} \char_set_catcode:nn{`\*}{13} -\token_new:Nn \c_active_char_token {*} +\cs_gset_nopar:Npn \c_active_char_token {\exp_not:N*} \group_end: -\def_new:Npn \token_if_group_begin_p:N #1{ +\prg_new_conditional:Nnn \token_if_group_begin:N {p,TF,T,F} { \if_catcode:w \exp_not:N #1\c_group_begin_token - \c_true - \else: - \c_false - \fi: + \prg_return_true: \else: \prg_return_false: \fi: } -\def_test_function_new:npn {token_if_group_begin:N} #1{ - \if:w\token_if_group_begin_p:N #1} -\def_new:Npn \token_if_group_end_p:N #1{ +\prg_new_conditional:Nnn \token_if_group_end:N {p,TF,T,F} { \if_catcode:w \exp_not:N #1\c_group_end_token - \c_true - \else: - \c_false - \fi: + \prg_return_true: \else: \prg_return_false: \fi: } -\def_test_function_new:npn {token_if_group_end:N} #1{ - \if:w\token_if_group_end_p:N #1} -\def_new:Npn \token_if_math_shift_p:N #1{ +\prg_new_conditional:Nnn \token_if_math_shift:N {p,TF,T,F} { \if_catcode:w \exp_not:N #1\c_math_shift_token - \c_true - \else: - \c_false - \fi: + \prg_return_true: \else: \prg_return_false: \fi: } -\def_test_function_new:npn {token_if_math_shift:N} #1{ - \if:w\token_if_math_shift_p:N#1} -\def_new:Npn \token_if_alignment_tab_p:N #1{ +\prg_new_conditional:Nnn \token_if_alignment_tab:N {p,TF,T,F} { \if_catcode:w \exp_not:N #1\c_alignment_tab_token - \c_true - \else: - \c_false - \fi: + \prg_return_true: \else: \prg_return_false: \fi: } -\def_test_function_new:npn {token_if_alignment_tab:N} #1{ - \if:w\token_if_alignment_tab_p:N#1} -\def_new:Npn \token_if_parameter_p:N #1{ - \exp_after:NN\if_catcode:w \cs:w c_parameter_token\cs_end:\exp_not:N #1 - \c_true - \else: - \c_false - \fi: +\prg_new_conditional:Nnn \token_if_parameter:N {p,TF,T,F} { + \exp_after:wN\if_catcode:w \cs:w c_parameter_token\cs_end:\exp_not:N #1 + \prg_return_true: \else: \prg_return_false: \fi: } -\def_test_function_new:npn {token_if_parameter:N} #1{ - \if:w\token_if_parameter_p:N#1} -\def_new:Npn \token_if_math_superscript_p:N #1{ +\prg_new_conditional:Nnn \token_if_math_superscript:N {p,TF,T,F} { \if_catcode:w \exp_not:N #1\c_math_superscript_token - \c_true - \else: - \c_false - \fi: + \prg_return_true: \else: \prg_return_false: \fi: } -\def_test_function_new:npn {token_if_math_superscript:N} #1{ - \if:w\token_if_math_superscript_p:N #1} -\def_new:Npn \token_if_math_subscript_p:N #1{ +\prg_new_conditional:Nnn \token_if_math_subscript:N {p,TF,T,F} { \if_catcode:w \exp_not:N #1\c_math_subscript_token - \c_true - \else: - \c_false - \fi: + \prg_return_true: \else: \prg_return_false: \fi: } -\def_test_function_new:npn {token_if_math_subscript:N} #1{ - \if:w\token_if_math_subscript_p:N #1} -\def_new:Npn \token_if_space_p:N #1{ +\prg_new_conditional:Nnn \token_if_space:N {p,TF,T,F} { \if_catcode:w \exp_not:N #1\c_space_token - \c_true - \else: - \c_false - \fi: + \prg_return_true: \else: \prg_return_false: \fi: } -\def_test_function_new:npn {token_if_space:N} #1{ - \if:w\token_if_space_p:N #1} -\def_new:Npn \token_if_letter_p:N #1{ +\prg_new_conditional:Nnn \token_if_letter:N {p,TF,T,F} { \if_catcode:w \exp_not:N #1\c_letter_token - \c_true - \else: - \c_false - \fi: + \prg_return_true: \else: \prg_return_false: \fi: } -\def_test_function_new:npn {token_if_letter:N} #1{ - \if:w\token_if_letter_p:N #1} -\def_new:Npn \token_if_other_char_p:N #1{ +\prg_new_conditional:Nnn \token_if_other_char:N {p,TF,T,F} { \if_catcode:w \exp_not:N #1\c_other_char_token - \c_true - \else: - \c_false - \fi: + \prg_return_true: \else: \prg_return_false: \fi: } -\def_test_function_new:npn {token_if_other_char:N} #1{ - \if:w\token_if_other_char_p:N #1} -\def_new:Npn \token_if_active_char_p:N #1{ +\prg_new_conditional:Nnn \token_if_active_char:N {p,TF,T,F} { \if_catcode:w \exp_not:N #1\c_active_char_token - \c_true - \else: - \c_false - \fi: + \prg_return_true: \else: \prg_return_false: \fi: } -\def_test_function_new:npn {token_if_active_char:N} #1{ - \if:w\token_if_active_char_p:N #1} -\def_new:Npn \token_if_eq_meaning_p:NN #1#2 { - \if_meaning:NN #1 #2 - \c_true - \else: - \c_false - \fi: +\prg_new_conditional:Nnn \token_if_eq_meaning:NN {p,TF,T,F} { + \if_meaning:w #1 #2 + \prg_return_true: \else: \prg_return_false: \fi: } -\def_test_function_new:npn {token_if_eq_meaning:NN}#1#2{ - \if_meaning:NN #1 #2} -\def_new:Npn \token_if_eq_catcode_p:NN #1#2 { +\prg_new_conditional:Nnn \token_if_eq_catcode:NN {p,TF,T,F} { \if_catcode:w \exp_not:N #1 \exp_not:N #2 - \c_true - \else: - \c_false - \fi: + \prg_return_true: \else: \prg_return_false: \fi: } -\def_test_function_new:npn {token_if_eq_catcode:NN}#1#2{ - \if:w\token_if_eq_catcode_p:NN#1#2} -\def_new:Npn \token_if_charcode_eq_p:NN #1#2 { +\prg_new_conditional:Nnn \token_if_eq_charcode:NN {p,TF,T,F} { \if_charcode:w \exp_not:N #1 \exp_not:N #2 - \c_true - \else: - \c_false - \fi: -} -\def_test_function_new:npn {token_if_eq_charcode:NN}#1#2{ - \if:w\token_if_eq_charcode_p:NN#1#2} -\def_new:Npn \token_if_macro_p:N #1 { - \exp_after:NN \token_if_macro_p_aux:w \token_to_meaning:N #1 -> \q_nil -} -\def_new:Npn \token_if_macro_p_aux:w #1 -> #2 \q_nil{ - \if:w \tlist_if_empty_p:n{#2} \c_false \else: \c_true \fi: -} -\def_test_function_new:npn {token_if_macro:N} #1{\if:w\token_if_macro_p:N#1} -\def_new:Npn \token_if_cs_p:N {\token_if_eq_catcode_p:NN \scan_stop:} -\def_test_function_new:npn {token_if_cs:N} #1{ - \if:w \token_if_eq_catcode_p:NN \scan_stop: #1} -\def_new:Npn \token_if_expandable_p:N #1{ - \exp_after:NN \if_token_eq:NN \exp_not:N #1 \scan_stop: - \c_true - \else: - \c_false - \fi: + \prg_return_true: \else: \prg_return_false: \fi: +} +\prg_new_conditional:Nnn \token_if_macro:N {p,TF,T,F} { + \exp_after:wN \token_if_macro_p_aux:w \token_to_meaning:N #1 -> \q_nil +} +\cs_new_nopar:Npn \token_if_macro_p_aux:w #1 -> #2 \q_nil{ + \if_predicate:w \tl_if_empty_p:n{#2} + \prg_return_false: \else: \prg_return_true: \fi: +} +\prg_new_conditional:Nnn \token_if_cs:N {p,TF,T,F} { + \if_predicate:w \token_if_eq_catcode_p:NN \scan_stop: #1 + \prg_return_true: \else: \prg_return_false: \fi:} +\prg_new_conditional:Nnn \token_if_expandable:N {p,TF,T,F} { + \cs_if_exist:NTF #1 { + \exp_after:wN \if_meaning:w \exp_not:N #1 #1 + \prg_return_false: \else: \prg_return_true: \fi: + } { + \prg_return_false: + } } -\def_test_function_new:npn {token_if_expandable:N} #1{ - \if:w\token_if_expandable_p:N#1} \group_begin: + \char_set_lccode:nn {`\T}{`\T} + \char_set_lccode:nn {`\F}{`\F} \char_set_lccode:nn {`\X}{`\n} \char_set_lccode:nn {`\Y}{`\t} \char_set_lccode:nn {`\Z}{`\d} \char_set_lccode:nn {`\?}{`\\} - \tlist_map_inline:nn{\X\Y\Z\M\T\C\H\A\R\O\U\S\K\I\P\L\G\P\E} + \tl_map_inline:nn{\X\Y\Z\M\C\H\A\R\O\U\S\K\I\P\L\G\P\E} {\char_set_catcode:nn {`#1}{12}} -\tlist_to_lowercase:n{ +\tl_to_lowercase:n{ \group_end: -\def_new:Npn \token_if_chardef_p:N #1 { - \exp_after:NN \token_if_chardef_p_aux:w +\prg_new_conditional:Nnn \token_if_chardef:N {p,TF,T,F} { + \exp_after:wN \token_if_chardef_aux:w \token_to_meaning:N #1?CHAR"\q_nil } -\def_new:Npn \token_if_chardef_p_aux:w #1?CHAR"#2\q_nil{ - \tlist_if_empty_p:n{#1} +\cs_new_nopar:Npn \token_if_chardef_aux:w #1?CHAR"#2\q_nil{ + \tl_if_empty:nTF {#1} {\prg_return_true:} {\prg_return_false:} } -\def_new:Npn \token_if_mathchardef_p:N #1 { - \exp_after:NN \token_if_mathchardef_p_aux:w +\prg_new_conditional:Nnn \token_if_mathchardef:N {p,TF,T,F} { + \exp_after:wN \token_if_mathchardef_aux:w \token_to_meaning:N #1?MAYHCHAR"\q_nil } -\def_new:Npn \token_if_mathchardef_p_aux:w #1?MAYHCHAR"#2\q_nil{ - \tlist_if_empty_p:n{#1} +\cs_new_nopar:Npn \token_if_mathchardef_aux:w #1?MAYHCHAR"#2\q_nil{ + \tl_if_empty:nTF {#1} {\prg_return_true:} {\prg_return_false:} } -\def:Npn \token_if_int_register_p:N #1{ - \if_meaning:NN \tex_countdef:D #1 - \c_false +\prg_new_conditional:Nnn \token_if_int_register:N {p,TF,T,F} { + \if_meaning:w \tex_countdef:D #1 + \prg_return_false: \else: - \exp_after:NN \token_if_int_register_p_aux:w + \exp_after:wN \token_if_int_register_aux:w \token_to_meaning:N #1?COUXY\q_nil \fi: } -\def_new:Npn \token_if_int_register_p_aux:w #1?COUXY#2\q_nil{ - \tlist_if_empty_p:n{#1} +\cs_new_nopar:Npn \token_if_int_register_aux:w #1?COUXY#2\q_nil{ + \tl_if_empty:nTF {#1} {\prg_return_true:} {\prg_return_false:} } -\def:Npn \token_if_skip_register_p:N #1{ - \if_meaning:NN \tex_skipdef:D #1 - \c_false +\prg_new_conditional:Nnn \token_if_skip_register:N {p,TF,T,F} { + \if_meaning:w \tex_skipdef:D #1 + \prg_return_false: \else: - \exp_after:NN \token_if_skip_register_p_aux:w - \token_to_meaning:N #1?SKIP\q_nil + \exp_after:wN \token_if_skip_register_aux:w + \token_to_meaning:N #1?SKIP\q_nil \fi: } -\def_new:Npn \token_if_skip_register_p_aux:w #1?SKIP#2\q_nil{ - \tlist_if_empty_p:n{#1} +\cs_new_nopar:Npn \token_if_skip_register_aux:w #1?SKIP#2\q_nil{ + \tl_if_empty:nTF {#1} {\prg_return_true:} {\prg_return_false:} } -\def:Npn \token_if_dim_register_p:N #1{ - \if_meaning:NN \tex_dimendef:D #1 - \c_false +\prg_new_conditional:Nnn \token_if_dim_register:N {p,TF,T,F} { + \if_meaning:w \tex_dimendef:D #1 + \c_false_bool \else: - \exp_after:NN \token_if_dim_register_p_aux:w + \exp_after:wN \token_if_dim_register_aux:w \token_to_meaning:N #1?ZIMEX\q_nil \fi: } -\def_new:Npn \token_if_dim_register_p_aux:w #1?ZIMEX#2\q_nil{ - \tlist_if_empty_p:n{#1} +\cs_new_nopar:Npn \token_if_dim_register_aux:w #1?ZIMEX#2\q_nil{ + \tl_if_empty:nTF {#1} {\prg_return_true:} {\prg_return_false:} } -\def:Npn \token_if_toks_register_p:N #1{ - \if_meaning:NN \tex_toksdef:D #1 - \c_false +\prg_new_conditional:Nnn \token_if_toks_register:N {p,TF,T,F} { + \if_meaning:w \tex_toksdef:D #1 + \prg_return_false: \else: - \exp_after:NN \token_if_toks_register_p_aux:w + \exp_after:wN \token_if_toks_register_aux:w \token_to_meaning:N #1?YOKS\q_nil \fi: } -\def_new:Npn \token_if_toks_register_p_aux:w #1?YOKS#2\q_nil{ - \tlist_if_empty_p:n{#1} +\cs_new_nopar:Npn \token_if_toks_register_aux:w #1?YOKS#2\q_nil{ + \tl_if_empty:nTF {#1} {\prg_return_true:} {\prg_return_false:} } -\def_new:Npn \token_if_protected_macro_p:N #1 { - \exp_after:NN \token_if_protected_macro_p_aux:w +\prg_new_conditional:Nnn \token_if_protected_macro:N {p,TF,T,F} { + \exp_after:wN \token_if_protected_macro_aux:w \token_to_meaning:N #1?PROYECYEZ~MACRO\q_nil } -\def_new:Npn \token_if_protected_macro_p_aux:w #1?PROYECYEZ~MACRO#2\q_nil{ - \tlist_if_empty_p:n{#1} +\cs_new_nopar:Npn \token_if_protected_macro_aux:w #1?PROYECYEZ~MACRO#2\q_nil{ + \tl_if_empty:nTF {#1} {\prg_return_true:} {\prg_return_false:} } -\def_new:Npn \token_if_long_macro_p:N #1 { - \exp_after:NN \token_if_long_macro_p_aux:w +\prg_new_conditional:Nnn \token_if_long_macro:N {p,TF,T,F} { + \exp_after:wN \token_if_long_macro_aux:w \token_to_meaning:N #1?LOXG~MACRO\q_nil } -\def_new:Npn \token_if_long_macro_p_aux:w #1?LOXG~MACRO#2\q_nil{ - \tlist_if_empty_p:n{#1} -} -\def_new:Npn \token_if_protected_long_macro_p:N #1 { - \exp_after:NN \token_if_protected_long_macro_p_aux:w - \token_to_meaning:N #1?PROYECYEZ~?LOXG~MACRO\q_nil -} -\def_new:Npn \token_if_protected_long_macro_p_aux:w #1 - ?PROYECYEZ~?LOXG~MACRO#2\q_nil{ - \tlist_if_empty_p:n{#1} -} -} -\def_test_function_new:npn {token_if_chardef:N} {\if:w \token_if_chardef_p:N} -\def_test_function_new:npn {token_if_mathchardef:N} { - \if:w \token_if_mathchardef_p:N} -\def_test_function_new:npn {token_if_long_macro:N} { - \if:w \token_if_long_macro_p:N} -\def_test_function_new:npn {token_if_protected_macro:N} { - \if:w \token_if_protected_macro_p:N} -\def_test_function_new:npn {token_if_protected_long_macro:N} { - \if:w \token_if_protected_long_macro_p:N} -\def_test_function_new:npn {token_if_dim_register:N} { - \if:w \token_if_dim_register_p:N} -\def_test_function_new:npn {token_if_skip_register:N} { - \if:w \token_if_skip_register_p:N} -\def_test_function_new:npn {token_if_int_register:N} { - \if:w \token_if_int_register_p:N} -\def_test_function_new:npn {token_if_toks_register:N} { - \if:w \token_if_toks_register_p:N} +\cs_new_nopar:Npn \token_if_long_macro_aux:w #1?LOXG~MACRO#2\q_nil{ + \tl_if_empty:nTF {#1} {\prg_return_true:} {\prg_return_false:} +} +\prg_new_conditional:Nnn \token_if_protected_long_macro:N {p,TF,T,F} { + \exp_after:wN \token_if_protected_long_macro_aux:w + \token_to_meaning:N #1?PROYECYEZ?LOXG~MACRO\q_nil +} +\cs_new_nopar:Npn \token_if_protected_long_macro_aux:w #1 + ?PROYECYEZ?LOXG~MACRO#2\q_nil{ + \tl_if_empty:nTF {#1} {\prg_return_true:} {\prg_return_false:} +} +} \group_begin: \char_set_lccode:nn {`\?}{`\:} \char_set_catcode:nn{`\M}{12} @@ -380,63 +338,63 @@ \char_set_catcode:nn{`\C}{12} \char_set_catcode:nn{`\R}{12} \char_set_catcode:nn{`\O}{12} -\tlist_to_lowercase:n{ +\tl_to_lowercase:n{ \group_end: - \def_new:Npn \token_get_prefix_arg_replacement_aux:w #1MACRO?#2->#3\q_nil#4{ + \cs_new_nopar:Npn \token_get_prefix_arg_replacement_aux:w #1MACRO?#2->#3\q_nil#4{ #4{#1}{#2}{#3} } - \def_new:Npn\token_get_prefix_spec:N #1{ + \cs_new_nopar:Npn\token_get_prefix_spec:N #1{ \token_if_macro:NTF #1{ - \exp_after:NN \token_get_prefix_arg_replacement_aux:w - \token_to_meaning:N #1\q_nil\use_arg_i:nnn + \exp_after:wN \token_get_prefix_arg_replacement_aux:w + \token_to_meaning:N #1\q_nil\use_i:nnn }{\scan_stop:} } - \def_new:Npn\token_get_arg_spec:N #1{ + \cs_new_nopar:Npn\token_get_arg_spec:N #1{ \token_if_macro:NTF #1{ - \exp_after:NN \token_get_prefix_arg_replacement_aux:w - \token_to_meaning:N #1\q_nil\use_arg_ii:nnn + \exp_after:wN \token_get_prefix_arg_replacement_aux:w + \token_to_meaning:N #1\q_nil\use_ii:nnn }{\scan_stop:} } - \def_new:Npn\token_get_replacement_spec:N #1{ + \cs_new_nopar:Npn\token_get_replacement_spec:N #1{ \token_if_macro:NTF #1{ - \exp_after:NN \token_get_prefix_arg_replacement_aux:w - \token_to_meaning:N #1\q_nil\use_arg_iii:nnn + \exp_after:wN \token_get_prefix_arg_replacement_aux:w + \token_to_meaning:N #1\q_nil\use_iii:nnn }{\scan_stop:} } } -\def_new:Npn \token_if_primitive_p:N #1{ - \if:w \token_if_cs_p:N #1\scan_stop: - \if:w \token_if_macro_p:N #1 - \c_false +\prg_new_conditional:Nnn \token_if_primitive:N {p,TF,T,F} { + \if_predicate:w \token_if_cs_p:N #1 + \if_predicate:w \token_if_macro_p:N #1 + \prg_return_false: \else: \token_if_primitive_p_aux:N #1 \fi: \else: - \if:w \token_if_active_p:N #1 - \if:w \token_if_macro_p:N #1 - \c_false + \if_predicate:w \token_if_active_char_p:N #1 + \if_predicate:w \token_if_macro_p:N #1 + \prg_return_false: \else: \token_if_primitive_p_aux:N #1 \fi: \else: - \c_false + \prg_return_false: \fi: \fi: } -\def_new:Npn \token_if_primitive_p_aux:N #1{ - \if:w \token_if_chardef_p:N #1 \c_false +\cs_new_nopar:Npn \token_if_primitive_p_aux:N #1{ + \if_predicate:w \token_if_chardef_p:N #1 \c_false_bool \else: - \if:w \token_if_mathchardef_p:N #1 \c_false + \if_predicate:w \token_if_mathchardef_p:N #1 \prg_return_false: \else: - \if:w \token_if_int_register_p:N #1 \c_false + \if_predicate:w \token_if_int_register_p:N #1 \prg_return_false: \else: - \if:w \token_if_skip_register_p:N #1 \c_false + \if_predicate:w \token_if_skip_register_p:N #1 \prg_return_false: \else: - \if:w \token_if_dim_register_p:N #1 \c_false + \if_predicate:w \token_if_dim_register_p:N #1 \prg_return_false: \else: - \if:w \token_if_toks_register_p:N #1 \c_false + \if_predicate:w \token_if_toks_register_p:N #1 \prg_return_false: \else: - \c_true + \prg_return_true: \fi: \fi: \fi: @@ -444,120 +402,161 @@ \fi: \fi: } -\def_test_function_new:npn {token_if_primitive:N} #1{ - \if:w\token_if_primitive_p:N#1} \token_new:Nn \l_peek_token {?} \token_new:Nn \g_peek_token {?} \token_new:Nn \l_peek_search_token {?} -\def_new:Npn \peek_after:NN {\tex_futurelet:D \l_peek_token } -\def_new:Npn \peek_gafter:NN { +\cs_new_nopar:Npn \peek_after:NN {\tex_futurelet:D \l_peek_token } +\cs_new_nopar:Npn \peek_gafter:NN { \pref_global:D \tex_futurelet:D \g_peek_token } -\tlp_new:Nn \l_peek_true_tlp {} -\tlp_new:Nn \l_peek_false_tlp {} -\def_new:Npn \peek_tmp:w{} -\tlp_new:Nn \l_peek_search_tlp{} -\def_long_new:Npn \peek_token_generic:NNTF #1#2#3#4{ - \let:NN \l_peek_search_token #2 - \tlp_set:Nn \l_peek_search_tlp {#2} - \tlp_set:Nx \l_peek_true_tlp {\exp_not:n{\group_align_safe_end: #3}} - \tlp_set:Nx \l_peek_false_tlp {\exp_not:n{\group_align_safe_end: #4}} +\tl_new:Nn \l_peek_true_tl {} +\tl_new:Nn \l_peek_false_tl {} +\cs_new_nopar:Npn \peek_tmp:w {} +\tl_new:Nn \l_peek_search_tl {} +\cs_new:Npn \peek_token_generic:NNTF #1#2#3#4 { + \cs_set_eq:NN \l_peek_search_token #2 + \tl_set:Nn \l_peek_search_tl {#2} + \tl_set:Nx \l_peek_true_tl {\exp_not:n{\group_align_safe_end: #3}} + \tl_set:Nx \l_peek_false_tl {\exp_not:n{\group_align_safe_end: #4}} \group_align_safe_begin: \peek_after:NN #1 } -\def_long_new:Npn \peek_token_remove_generic:NNTF #1#2#3#4{ - \let:NN \l_peek_search_token #2 - \tlp_set:Nn \l_peek_search_tlp {#2} - \tlp_set:Nx \l_peek_true_aux_tlp { \exp_not:n{ #3 } } - \tlp_set_eq:NN \l_peek_true_tlp \c_peek_true_remove_next_tlp - \tlp_set:Nx \l_peek_false_tlp {\exp_not:n{\group_align_safe_end: #4}} +\cs_new:Npn \peek_token_generic:NNT #1#2#3 { + \peek_token_generic:NNTF #1#2 {#3} {} +} +\cs_new:Npn \peek_token_generic:NNF #1#2#3 { + \peek_token_generic:NNTF #1#2 {} {#3} +} +\cs_new:Npn \peek_token_remove_generic:NNTF #1#2#3#4 { + \cs_set_eq:NN \l_peek_search_token #2 + \tl_set:Nn \l_peek_search_tl {#2} + \tl_set:Nx \l_peek_true_aux_tl { \exp_not:n{ #3 } } + \tl_set_eq:NN \l_peek_true_tl \c_peek_true_remove_next_tl + \tl_set:Nx \l_peek_false_tl {\exp_not:n{\group_align_safe_end: #4}} \group_align_safe_begin: \peek_after:NN #1 } -\tlp_new:Nn \l_peek_true_aux_tlp {} -\tlp_new:Nn \c_peek_true_remove_next_tlp {\group_align_safe_end: - \tex_afterassignment:D \l_peek_true_aux_tlp \let:NN \peek_tmp:w +\cs_new:Npn \peek_token_remove_generic:NNT #1#2#3 { + \peek_token_remove_generic:NNTF #1#2 {#3} {} +} +\cs_new:Npn \peek_token_remove_generic:NNF #1#2#3 { + \peek_token_remove_generic:NNTF #1#2 {} {#3} } -\def_new:Npn \peek_execute_branches_meaning: { - \if_meaning:NN \l_peek_token \l_peek_search_token - \exp_after:NN \l_peek_true_tlp +\tl_new:Nn \l_peek_true_aux_tl {} +\tl_new:Nn \c_peek_true_remove_next_tl {\group_align_safe_end: + \tex_afterassignment:D \l_peek_true_aux_tl \cs_set_eq:NN \peek_tmp:w +} +\cs_new_nopar:Npn \peek_execute_branches_meaning: { + \if_meaning:w \l_peek_token \l_peek_search_token + \exp_after:wN \l_peek_true_tl \else: - \exp_after:NN \l_peek_false_tlp + \exp_after:wN \l_peek_false_tl \fi: } -\def_new:Npn \peek_execute_branches_catcode: { +\cs_new_nopar:Npn \peek_execute_branches_catcode: { \if_catcode:w \exp_not:N\l_peek_token \exp_not:N\l_peek_search_token - \exp_after:NN \l_peek_true_tlp + \exp_after:wN \l_peek_true_tl \else: - \exp_after:NN \l_peek_false_tlp + \exp_after:wN \l_peek_false_tl \fi: } -\def_new:Npn \peek_execute_branches_charcode: { - \predicate:nTF { +\cs_new_nopar:Npn \peek_execute_branches_charcode: { + \bool_if:nTF { \token_if_eq_catcode_p:NN \l_peek_token \c_group_begin_token || \token_if_eq_meaning_p:NN \l_peek_token \c_space_token } - { \l_peek_false_tlp } - { \exp_after:NN \peek_execute_branches_charcode_aux:NN \l_peek_search_tlp } + { \l_peek_false_tl } + { \exp_after:wN \peek_execute_branches_charcode_aux:NN \l_peek_search_tl } } -\def_long_new:Npn \peek_execute_branches_charcode_aux:NN #1#2{ +\cs_new:Npn \peek_execute_branches_charcode_aux:NN #1#2{ \if_charcode:w \exp_not:N #1\exp_not:N#2 - \exp_after:NN \l_peek_true_tlp + \exp_after:wN \l_peek_true_tl \else: - \exp_after:NN \l_peek_false_tlp + \exp_after:wN \l_peek_false_tl \fi: #2 } -\def_new:Npn \peek_meaning:NTF { - \peek_token_generic:NNTF \peek_execute_branches_meaning: -} -\def_new:Npn \peek_meaning_ignore_spaces:NTF { - \let:NN \peek_execute_branches: \peek_execute_branches_meaning: - \peek_token_generic:NNTF \peek_ignore_spaces_execute_branches: -} -\def_new:Npn \peek_meaning_remove:NTF { - \peek_token_remove_generic:NNTF \peek_execute_branches_meaning: -} -\def_new:Npn \peek_meaning_remove_ignore_spaces:NTF { - \let:NN \peek_execute_branches: \peek_execute_branches_meaning: - \peek_token_remove_generic:NNTF \peek_ignore_spaces_execute_branches: -} -\def_new:Npn \peek_catcode:NTF { - \peek_token_generic:NNTF \peek_execute_branches_catcode: -} -\def_new:Npn \peek_catcode_ignore_spaces:NTF { - \let:NN \peek_execute_branches: \peek_execute_branches_catcode: - \peek_token_generic:NNTF \peek_ignore_spaces_execute_branches: -} -\def_new:Npn \peek_catcode_remove:NTF { - \peek_token_remove_generic:NNTF \peek_execute_branches_catcode: -} -\def_new:Npn \peek_catcode_remove_ignore_spaces:NTF { - \let:NN \peek_execute_branches: \peek_execute_branches_catcode: - \peek_token_remove_generic:NNTF \peek_ignore_spaces_execute_branches: -} -\def_new:Npn \peek_charcode:NTF { - \peek_token_generic:NNTF \peek_execute_branches_charcode: -} -\def_new:Npn \peek_charcode_ignore_spaces:NTF { - \let:NN \peek_execute_branches: \peek_execute_branches_charcode: - \peek_token_generic:NNTF \peek_ignore_spaces_execute_branches: -} -\def_new:Npn \peek_charcode_remove:NTF { - \peek_token_remove_generic:NNTF \peek_execute_branches_charcode: -} - -\def_new:Npn \peek_charcode_remove_ignore_spaces:NTF { - \let:NN \peek_execute_branches: \peek_execute_branches_charcode: - \peek_token_remove_generic:NNTF \peek_ignore_spaces_execute_branches: +\cs_new_nopar:Npn \peek_def_aux:nnnn #1#2#3#4 { + \peek_def_aux_ii:nnnnn {#1} {#2} {#3} {#4} { TF } + \peek_def_aux_ii:nnnnn {#1} {#2} {#3} {#4} { T } + \peek_def_aux_ii:nnnnn {#1} {#2} {#3} {#4} { F } +} +\cs_new_nopar:Npn \peek_def_aux_ii:nnnnn #1#2#3#4#5 { + \cs_new_nopar:cpx { #1 #5 } { + \tl_if_empty:nF {#2} { + \exp_not:n { \cs_set_eq:NN \peek_execute_branches: #2 } + } + \exp_not:c { #3 #5 } + \exp_not:n { #4 } + } } -\def_new:Npn \peek_ignore_spaces_aux: { +\peek_def_aux:nnnn + { peek_meaning:N } + {} + { peek_token_generic:NN } + { \peek_execute_branches_meaning: } +\peek_def_aux:nnnn + { peek_meaning_ignore_spaces:N } + { \peek_execute_branches_meaning: } + { peek_token_generic:NN } + { \peek_ignore_spaces_execute_branches: } +\peek_def_aux:nnnn + { peek_meaning_remove:N } + {} + { peek_token_remove_generic:NN } + { \peek_execute_branches_meaning: } +\peek_def_aux:nnnn + { peek_meaning_remove_ignore_spaces:N } + { \peek_execute_branches_meaning: } + { peek_token_remove_generic:NN } + { \peek_ignore_spaces_execute_branches: } +\peek_def_aux:nnnn + { peek_catcode:N } + {} + { peek_token_generic:NN } + { \peek_execute_branches_catcode: } +\peek_def_aux:nnnn + { peek_catcode_ignore_spaces:N } + { \peek_execute_branches_catcode: } + { peek_token_generic:NN } + { \peek_ignore_spaces_execute_branches: } +\peek_def_aux:nnnn + { peek_catcode_remove:N } + {} + { peek_token_remove_generic:NN } + { \peek_execute_branches_catcode: } +\peek_def_aux:nnnn + { peek_catcode_remove_ignore_spaces:N } + { \peek_execute_branches_catcode: } + { peek_token_remove_generic:NN } + { \peek_ignore_spaces_execute_branches: } +\peek_def_aux:nnnn + { peek_charcode:N } + {} + { peek_token_generic:NN } + { \peek_execute_branches_charcode: } +\peek_def_aux:nnnn + { peek_charcode_ignore_spaces:N } + { \peek_execute_branches_charcode: } + { peek_token_generic:NN } + { \peek_ignore_spaces_execute_branches: } +\peek_def_aux:nnnn + { peek_charcode_remove:N } + {} + { peek_token_remove_generic:NN } + { \peek_execute_branches_charcode: } +\peek_def_aux:nnnn + { peek_charcode_remove_ignore_spaces:N } + { \peek_execute_branches_charcode: } + { peek_token_remove_generic:NN } + { \peek_ignore_spaces_execute_branches:} +\cs_new_nopar:Npn \peek_ignore_spaces_aux: { \peek_after:NN \peek_ignore_spaces_execute_branches: } -\def_new:Npn \peek_ignore_spaces_execute_branches: { +\cs_new_nopar:Npn \peek_ignore_spaces_execute_branches: { \token_if_eq_meaning:NNTF \l_peek_token \c_space_token { \tex_afterassignment:D \peek_ignore_spaces_aux: - \let:NN \peek_tmp:w + \cs_set_eq:NN \peek_tmp:w } \peek_execute_branches: } diff --git a/Master/texmf-dist/tex/latex/expl3/l3toks.sty b/Master/texmf-dist/tex/latex/expl3/l3toks.sty index ea18f851ee0..79de834fd71 100644 --- a/Master/texmf-dist/tex/latex/expl3/l3toks.sty +++ b/Master/texmf-dist/tex/latex/expl3/l3toks.sty @@ -15,7 +15,7 @@ %% Do not distribute a modified version of this file. %% %% -%% File: l3toks.dtx Copyright (C) 1990-2006 LaTeX3 project +%% File: l3toks.dtx Copyright (C) 1990-2009 LaTeX3 project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this @@ -33,7 +33,7 @@ %% %% The development version of the bundle can be found at %% -%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/ +%% http://www.latex-project.org/svnroot/experimental/trunk/ %% %% for those people who are interested. %% @@ -48,128 +48,118 @@ %% %% ----------------------------------------------------------------------- \RequirePackage{l3names} -\GetIdInfo$Id: l3toks.dtx 728 2008-01-01 16:11:58Z morten $ +\GetIdInfo$Id: l3toks.dtx 1362 2009-05-28 20:19:21Z joseph $ {L3 Experimental Token Registers} \ProvidesExplPackage {\filename}{\filedate}{\fileversion}{\filedescription} -\RequirePackage{l3expan}\par -\let:NN \toks_new:N \newtoks % nick from LaTeX for the moment -\def_new:Npn \toks_new:c {\exp_args:Nc\toks_new:N} -\def_new:Npn \toks_clear:N #1{#1\c_empty_toks -} -\def_new:Npn \toks_gclear:N { - \pref_global:D - \toks_clear:N} -\let_new:NN \toks_use:N \the_internal:D -\def_new:Npn \toks_use:c {\exp_args:Nc\toks_use:N} -\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{ - \pref_global:D - \toks_use_clear:N} -\def_new:Npn \toks_put_left:Nn #1{ - \exp_after:NN\toks_put_left_aux:w\exp_after:NN\q_mark - \toks_use:N #1\q_stop #1} -\def_new:Npn \toks_put_left:No {\exp_args:NNo \toks_put_left:Nn} -\def_new:Npn \toks_gput_left:Nn { - \pref_global:D - \toks_put_left:Nn} -\def_new:Npn \toks_gput_left:Nx {\exp_args:NNx \toks_gput_left:Nn} -\def_long_new:Npn \toks_put_left_aux:w #1\q_stop #2#3{ - #2\exp_after:NN{\use_arg_i:nn{#3}#1} -} -\def_long_new:Npn \toks_put_right:Nn #1#2{#1\exp_after:NN{\toks_use:N #1#2} -} -\def_new:Npn \toks_gput_right:Nn { - \pref_global:D - \toks_put_right:Nn} -\def_long_new:Npn\toks_put_right:No#1#2{#1\exp_after:NN\exp_after:NN -\exp_after:NN{\exp_after:NN\toks_use:N\exp_after:NN #1#2}} -\def_long_new:Npn\toks_put_right:Nd#1#2{ - \exp_after:NN\toks_put_right:No\exp_after:NN#1\exp_after:NN{#2}} -\def_long_new:Npn \toks_put_right:Nf #1#2{ - #1\exp_after:NN\exp_after:NN\exp_after:NN{ - \exp_after:NN\toks_use:N\exp_after:NN #1\int_to_roman:w -`0#2}} -\def_new:Npn \toks_put_right:Nx {\exp_args:NNx \toks_put_right:Nn } -\def_new:Npn \toks_gput_right:No {\exp_args:NNo\toks_gput_right:Nn} -\def_new:Npn \toks_gput_right:Nx {\exp_args:NNx\toks_gput_right:Nn} - \let_new:NN \toks_set:Nn\use_noop: - \def_long_new:Npn \toks_set:No#1#2{#1\exp_after:NN{#2}} - \def_long_new:Npn \toks_set:Nd#1#2{ - #1\exp_after:NN\exp_after:NN\exp_after:NN{#2}} -\def_new:Npn \toks_set:Nx {\exp_args:NNx \toks_set:Nn} -\def_long_new:Npn\toks_set:Nf #1#2{ - #1\exp_after:NN{\int_to_roman:w -`0#2}} -\def_new:Npn \toks_set:cf {\exp_args:Nc\toks_set:Nf} -\def_new:Npn \toks_set:cn {\exp_args:Nc\toks_set:Nn} -\def_new:Npn \toks_set:co {\exp_args:Nc\toks_set:No} -\def_new:Npn \toks_set:cx {\exp_args:Nc\toks_set:Nx} - \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} -\def_new:Npn \toks_gset:cn {\exp_args:Nc \toks_gset:Nn} -\def_new:Npn \toks_gset:co {\exp_args:Nc \toks_gset:No} -\def_new:Npn \toks_gset:cx {\exp_args:Nc \toks_gset:Nx} - \let_new:NN \toks_set_eq:NN \use_noop: - \let_new:NN \toks_gset_eq:NN \pref_global:D -\def_new:Npn \toks_set_eq:Nc {\exp_args:NNc\toks_set_eq:NN} -\def_new:Npn \toks_set_eq:cN {\exp_args:Nc\toks_set_eq:NN} -\def_new:Npn \toks_set_eq:cc {\exp_args:Ncc\toks_set_eq:NN} -\def_new:Npn \toks_gset_eq:Nc {\exp_args:NNc\toks_gset_eq:NN} -\def_new:Npn \toks_gset_eq:cN {\exp_args:Nc\toks_gset_eq:NN} -\def_new:Npn \toks_gset_eq:cc {\exp_args:Ncc\toks_gset_eq:NN} -\def_new:Npn\toks_if_empty_p:N#1{ - \if:w \tlist_if_empty_p:o{\toks_use:N #1} - \c_true - \else: - \c_false - \fi: -} -\def_test_function_new:npn{toks_if_empty:N}#1{\if:w \toks_if_empty_p:N #1} -\def_new:Npn\toks_if_empty:cTF{\exp_args:Nc\toks_if_empty:NTF} -\def_new:Npn\toks_if_empty:cT{\exp_args:Nc\toks_if_empty:NT} -\def_new:Npn\toks_if_empty:cF{\exp_args:Nc\toks_if_empty:NF} -\def_new:NNn \toks_if_eq:NNTF 2 { - \tlist_if_eq:xxTF{\toks_use:N #1}{\toks_use:N #2} -} -\def_new:NNn \toks_if_eq:NNT 2 { - \tlist_if_eq:xxT{\toks_use:N #1}{\toks_use:N #2} -} -\def_new:NNn \toks_if_eq:NNF 2 { - \tlist_if_eq:xxF{\toks_use:N #1}{\toks_use:N #2} -} -\def_new:Npn \toks_if_eq:NcTF {\exp_args:NNc \toks_if_eq:NNTF} -\def_new:Npn \toks_if_eq:NcT {\exp_args:NNc \toks_if_eq:NNT} -\def_new:Npn \toks_if_eq:NcF {\exp_args:NNc \toks_if_eq:NNF} -\def_new:Npn \toks_if_eq:cNTF {\exp_args:Nc \toks_if_eq:NNTF} -\def_new:Npn \toks_if_eq:cNT {\exp_args:Nc \toks_if_eq:NNT} -\def_new:Npn \toks_if_eq:cNF {\exp_args:Nc \toks_if_eq:NNF} -\def_new:Npn \toks_if_eq:ccTF {\exp_args:Ncc \toks_if_eq:NNTF} -\def_new:Npn \toks_if_eq:ccT {\exp_args:Ncc \toks_if_eq:NNT} -\def_new:Npn \toks_if_eq:ccF {\exp_args:Ncc \toks_if_eq:NNF} -\def_new:NNn \toks_if_eq_p:NN 2 { - \tlist_if_eq_p:xx {\toks_use:N #1} {\toks_use:N #2} -} -\def_new:Npn \toks_if_eq_p:cN {\exp_args:Nc \toks_if_eq_p:NN} -\def_new:Npn \toks_if_eq_p:Nc {\exp_args:NNc \toks_if_eq_p:NN} -\def_new:Npn \toks_if_eq_p:cc {\exp_args:Ncc \toks_if_eq_p:NN} -\tex_toksdef:D \l_tmpa_toks = 255 +\package_check_loaded_expl: +\cs_set_eq:NN \toks_new:N \newtoks % nick from LaTeX for the moment +\cs_generate_variant:Nn \toks_new:N {c} +\cs_new_eq:NN \toks_use:N \tex_the:D +\cs_generate_variant:Nn \toks_use:N {c} +\cs_new_eq:NN \toks_set:Nn \prg_do_nothing: +\cs_new:Npn \toks_set:NV #1#2 { + #1 \exp_after:wN { \int_to_roman:w -`0 \exp_eval_register:N #2 } +} +\cs_new:Npn \toks_set:Nv #1#2 { + #1 \exp_after:wN { \int_to_roman:w -`0 \exp_eval_register:c {#2} } +} +\cs_new:Npn \toks_set:No #1#2 { #1 \exp_after:wN {#2} } +\cs_new:Npn \toks_set:Nd #1#2 { + #1 \exp_after:wN \exp_after:wN \exp_after:wN {#2} +} +\cs_new:Npn \toks_set:Nf #1#2 { + #1 \exp_after:wN { \int_to_roman:w -`0#2 } +} +\cs_generate_variant:Nn \toks_set:Nn {Nx,cn,cV,cv,co,cx,cd,cf} +\cs_new_eq:NN \toks_gset:Nn \pref_global:D +\cs_generate_variant:Nn \toks_gset:Nn {NV,No,Nx,cn,cV,co,cx} +\cs_new_eq:NN \toks_set_eq:NN \prg_do_nothing: +\cs_new_eq:NN \toks_gset_eq:NN \pref_global:D +\cs_generate_variant:Nn \toks_set_eq:NN {Nc,cN,cc} +\cs_generate_variant:Nn \toks_gset_eq:NN {Nc,cN,cc} +\cs_new_nopar:Npn \toks_clear:N #1 { + #1\c_empty_toks +} +\cs_new_nopar:Npn \toks_gclear:N { + \pref_global:D + \toks_clear:N +} +\cs_generate_variant:Nn \toks_clear:N {c} +\cs_generate_variant:Nn \toks_gclear:N {c} +\cs_new_nopar:Npn \toks_use_clear:N #1 { + \exp_last_unbraced:NNV \toks_clear:N #1 #1 +} +\cs_new_nopar:Npn \toks_use_gclear:N { + \pref_global:D + \toks_use_clear:N +} +\cs_generate_variant:Nn \toks_use_clear:N {c} +\cs_generate_variant:Nn \toks_use_gclear:N {c} +\cs_new_eq:NN \toks_show:N \tex_showthe:D +\cs_generate_variant:Nn \toks_show:N {c} +\cs_new_nopar:Npn \toks_put_left:Nn #1 { + \exp_after:wN \toks_put_left_aux:w \exp_after:wN \q_mark + \toks_use:N #1 \q_stop #1 +} +\cs_generate_variant:Nn \toks_put_left:Nn {NV,No,Nx,cn,co,cV} +\cs_new_nopar:Npn \toks_gput_left:Nn { + \pref_global:D + \toks_put_left:Nn +} +\cs_generate_variant:Nn \toks_gput_left:Nn {NV,No,Nx,cn,cV,co} +\cs_new:Npn \toks_put_left_aux:w #1\q_stop #2#3 { + #2 \exp_after:wN { \use_i:nn {#3} #1 } +} +\cs_new:Npn \toks_put_right:Nn #1#2 { + #1 \exp_after:wN { \toks_use:N #1 #2 } +} +\cs_new_nopar:Npn \toks_gput_right:Nn { + \pref_global:D + \toks_put_right:Nn +} +\cs_new:Npn \toks_put_right:NV #1#2 { + #1 \exp_after:wN \exp_after:wN \exp_after:wN { + \exp_after:wN \toks_use:N \exp_after:wN #1 + \int_to_roman:w -`0 \exp_eval_register:N #2 + } +} +\cs_new:Npn \toks_put_right:No #1#2 { + #1 \exp_after:wN \exp_after:wN \exp_after:wN { + \exp_after:wN \toks_use:N \exp_after:wN #1 #2 + } +} +\cs_generate_variant:Nn \toks_put_right:Nn {Nx,cn,cV,co} +\cs_generate_variant:Nn \toks_gput_right:Nn {NV,No,Nx,cn,cV,co} +\cs_new:Npn \toks_put_right:Nf #1#2 { + #1 \exp_after:wN \exp_after:wN \exp_after:wN { + \exp_after:wN \toks_use:N \exp_after:wN #1 \int_to_roman:w -`0#2 + } +} +\prg_new_conditional:Nnn \toks_if_empty:N {p,TF,T,F} { + \tl_if_empty:VTF #1 {\prg_return_true:} {\prg_return_false:} +} +\cs_generate_variant:Nn \toks_if_empty_p:N {c} +\cs_generate_variant:Nn \toks_if_empty:NTF {c} +\cs_generate_variant:Nn \toks_if_empty:NT {c} +\cs_generate_variant:Nn \toks_if_empty:NF {c} +\prg_new_conditional:Nnn \toks_if_eq:NN {p,TF,T,F} { + \tl_if_eq:xxTF {\toks_use:N #1} {\toks_use:N #2} + {\prg_return_true:} {\prg_return_false:} +} +\cs_generate_variant:Nn \toks_if_eq_p:NN {Nc,c,cc} +\cs_generate_variant:Nn \toks_if_eq:NNTF {Nc,c,cc} +\cs_generate_variant:Nn \toks_if_eq:NNT {Nc,c,cc} +\cs_generate_variant:Nn \toks_if_eq:NNF {Nc,c,cc} +\tex_toksdef:D \l_tmpa_toks = 255\scan_stop: \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 \toks_new:N \c_empty_toks -\def_new:Npn \toks_remove_extra_brace_group:N #1{ - \exp_after:NN \toks_remove_extra_brace_group_aux:NNw - \exp_after:NN \toks_set:Nn \exp_after:NN #1 - \toks_use:N#1\q_nil -} -\def_long_new:Npn\toks_remove_extra_brace_group_aux:NNw #1#2#3\q_nil{#1#2{#3}} +\toks_new:N \l_tl_replace_toks + %% %% %% End of file `l3toks.sty'. diff --git a/Master/texmf-dist/tex/latex/expl3/l3vers.dtx b/Master/texmf-dist/tex/latex/expl3/l3vers.dtx new file mode 100644 index 00000000000..c61d07ce94c --- /dev/null +++ b/Master/texmf-dist/tex/latex/expl3/l3vers.dtx @@ -0,0 +1,142 @@ +% \iffalse +%% File: l3vers.dtx Copyright (C) 1990-2009 LaTeX3 project +%% +%% It may be distributed and/or modified under the conditions of the +%% LaTeX Project Public License (LPPL), either version 1.3c of this +%% license or (at your option) any later version. The latest version +%% of this license is in the file +%% +%% http://www.latex-project.org/lppl.txt +%% +%% This file is part of the ``expl3 bundle'' (The Work in LPPL) +%% and all files in that bundle must be distributed together. +%% +%% The released version of this bundle is available from CTAN. +%% +%% ----------------------------------------------------------------------- +%% +%% The development version of the bundle can be found at +%% +%% http://www.latex-project.org/svnroot/experimental/trunk/ +%% +%% for those people who are interested. +%% +%%%%%%%%%%% +%% NOTE: %% +%%%%%%%%%%% +%% +%% Snapshots taken from the repository represent work in progress and may +%% not work or may contain conflicting material! We therefore ask +%% people _not_ to put them into distributions, archives, etc. without +%% prior consultation with the LaTeX Project Team. +%% +%% ----------------------------------------------------------------------- +%<*driver|package> +\RequirePackage{l3names} +%</driver|package> +%\fi +\GetIdInfo$Id: l3vers.dtx 1378 2009-06-01 19:15:56Z joseph $ + {L3 Experimental LaTeX format version} +%\iffalse +%<*driver> +%\fi +\ProvidesFile{\filename.\filenameext} + [\filedate\space v\fileversion\space\filedescription] +%\iffalse +\documentclass[full]{l3doc} +\begin{document} +\DocInput{\filename.\filenameext} +\end{document} +%</driver> +% \fi +% +% \begin{documentation} +% +% \section{Version Identification} +% Here we identify the date and version number of this release of +% \LaTeX3, and set |\tex_everyjob:D| so that it is printed at the start of +% every \LaTeX3 run. +% +% \begin{variable}{\c_format_name|\c_format_date} +% Name and date. +% \end{variable} +% +% \begin{variable}{\c_fmt_too_old} +% Age in months past "\c_format_date" after which an error is called +% during format generation. +% \end{variable} +% +% \begin{function}{\chk_format_age:w} +% Function that calculates the age of the format and calls an error if it +% is too old. +% \end{function} +% +% \end{documentation} +% +% \begin{implementation} +% +% \begin{macro}{\c_format_name} +% \begin{macro}{\c_format_date} +% \begin{macrocode} +%<*initex> +\cs_set_nopar:Npn\c_format_name{Experimental~ LaTeX3} +\cs_set_nopar:Npn\c_format_date{2009/06/01} +%^^A\cs_set_nopar:Npx\c_format_version{--release--date--goes--here--} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\c_fmt_too_old} +% \begin{macro}{\chk_format_age:w} +% Check that the format being made is not too old. While in development +% it should be a rather small number. +% \begin{macrocode} +\int_const:Nn \c_fmt_too_old{12} +\cs_set_nopar:Npn\chk_format_age:w #1/#2/#3\q_stop{ +% \end{macrocode} +% We just calculate the age of this file in months and give a warning +% if deemed too old. +% \begin{macrocode} + \intexpr_compare:nNnT{(\tex_year:D-#1)*12+\tex_month:D-#2}>\c_fmt_too_old + {\iow_term:x{^^J + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!^^J + !~~You~are~attempting~to~make~an~experimental~LaTeX3~format~from^^J + !~~source~files~that~are~more~than~ + \intexpr_eval:n{\c_fmt_too_old}~months~old.^^J + !^^J + !~~If~you~enter~<return>~to~scroll~past~this~message~then~the~format^^J + !~~will~be~built,~but~please~consider~obtaining~newer~source~files^^J + !~~before~continuing~to~build~an~experimental~LaTeX3~format.^^J + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!^^J + } + \tex_errhelp:D{ + To~avoid~this~error~message,~obtain~new~Experimental~LaTeX3~sources.} + \tex_errmessage:D{ + Experimental~LaTeX3~source~files~are~more~than~ + \intexpr_eval:n{\c_fmt_too_old}~months~old!} + } +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% Then we execute it. +% \begin{macrocode} +\exp_after:wN\chk_format_age:w\c_format_date\q_stop +% \end{macrocode} +% And since it's no longer needed we remove it again. +% \begin{macrocode} +\cs_gundefine:N \chk_format_age:w +% \end{macrocode} +% +% This startup banner may be further modified by the code in +% |ltfinal.dtx| if a patch file is present. +% \begin{macrocode} +\tex_everyjob:D{\iow_term:x{\c_format_name,~<\c_format_date>}} +\iow_term:x{\c_format_name,~<\c_format_date>} +%</initex> +% \end{macrocode} +% +% \end{implementation} +% \PrintIndex +% +% \endinput diff --git a/Master/texmf-dist/tex/latex/expl3/l3xref.sty b/Master/texmf-dist/tex/latex/expl3/l3xref.sty index 4635b63f382..98a3ca09251 100644 --- a/Master/texmf-dist/tex/latex/expl3/l3xref.sty +++ b/Master/texmf-dist/tex/latex/expl3/l3xref.sty @@ -15,7 +15,7 @@ %% Do not distribute a modified version of this file. %% %% -%% File: l3xref.dtx Copyright (C) 2006 LaTeX3 project +%% File: l3xref.dtx Copyright (C) 2006,2009 LaTeX3 project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this @@ -33,7 +33,7 @@ %% %% The development version of the bundle can be found at %% -%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/ +%% http://www.latex-project.org/svnroot/experimental/trunk/ %% %% for those people who are interested. %% @@ -48,62 +48,60 @@ %% %% ----------------------------------------------------------------------- \RequirePackage{l3names} -\GetIdInfo$Id: l3xref.dtx 621 2007-09-01 20:14:19Z morten $ +\GetIdInfo$Id: l3xref.dtx 1362 2009-05-28 20:19:21Z joseph $ {L3 Experimental cross referencing} \ProvidesExplPackage {\filename}{\filedate}{\fileversion}{\filedescription} -\RequirePackage{l3quark} -\RequirePackage{l3toks} -\RequirePackage{l3io} -\RequirePackage{l3prop} -\RequirePackage{l3int} -\RequirePackage{l3token} -\prop_new:N \g_xref_all_curr_immediate_fields_plist -\prop_new:N \g_xref_all_curr_deferred_fields_plist -\def_new:Npn \xref_new:nn {\xref_new_aux:nnn{immediate}} -\def_new:Npn \xref_deferred_new:nn {\xref_new_aux:nnn{deferred}} -\def_new:Npn \xref_new_aux:nnn #1#2#3{ - \prop_gput:ccx {g_xref_all_curr_ #1 _fields_plist} +\package_check_loaded_expl: +\prop_new:N \g_xref_all_curr_immediate_fields_prop +\prop_new:N \g_xref_all_curr_deferred_fields_prop +\cs_new_nopar:Npn \xref_new:nn {\xref_new_aux:nnn{immediate}} +\cs_new_nopar:Npn \xref_deferred_new:nn {\xref_new_aux:nnn{deferred}} +\cs_new_nopar:Npn \xref_new_aux:nnn #1#2#3{ + \prop_gput:ccx {g_xref_all_curr_ #1 _fields_prop} { xref_ #2 _key } - { \exp_not:c {l_xref_curr_#2_tlp }} - \def_protected:cpn { xref_#2_key }{} - \tlp_new:cn{l_xref_curr_#2_tlp}{#3} + { \exp_not:c {l_xref_curr_#2_tl }} + \cs_set_protected_nopar:cpn { xref_#2_key }{} + \tl_new:cn{l_xref_curr_#2_tl}{#3} \toks_set:Nx \l_tmpa_toks { - \exp_not:n { \def:cpn {xref_get_value_#2_aux:w} ##1 } + \exp_not:n { \cs_set_nopar:cpn {xref_get_value_#2_aux:w} ##1 } + \exp_not:N \q_prop \exp_not:c { xref_#2_key } + \exp_not:N \q_prop } \toks_use:N \l_tmpa_toks ##2 ##3\q_nil {##2} } -\def_new:Npn \xref_get_value:nn #1#2 { - \cs_if_really_free:cTF{g_xref_#2_plist} - {??} +\cs_new_nopar:Npn \xref_get_value:nn #1#2 { + \cs_if_exist:cTF{g_xref_#2_prop} { - \exp_args:NcNc \exp_after:NN {xref_get_value_#1_aux:w} - \prop_use:N {g_xref_#2_plist} + \exp_args:NcNc \exp_after:wN {xref_get_value_#1_aux:w} + \toks_use:N {g_xref_#2_prop} \q_nil } + {??} } -\def:NNn \exp_after:cc 2 { - \exp_after:NN \exp_after:NN - \cs:w #1\exp_after:NN\cs_end: \cs:w #2\cs_end: +\cs_set_nopar:Npn \exp_after:cc #1#2 { + \exp_after:wN \exp_after:wN + \cs:w #1\exp_after:wN\cs_end: \cs:w #2\cs_end: } -\def_protected_new:Npn \xref_define_label:nn { +\cs_set_protected:Npn \q_prop {\q_prop} +\cs_new_protected_nopar:Npn \xref_define_label:nn { \group_begin: \char_set_catcode:nn {`\ }\c_ten \xref_define_label_aux:nn } -\def_new:Npn \xref_define_label_aux:nn #1#2 { - \cs_if_really_free:cTF{g_xref_#1_plist} - {\prop_new:c{g_xref_#1_plist}}{\WARNING} - \toks_gset:cn{g_xref_#1_plist}{#2} +\cs_new_nopar:Npn \xref_define_label_aux:nn #1#2 { + \cs_if_free:cTF{g_xref_#1_prop} + {\prop_new:c{g_xref_#1_prop}}{\WARNING} + \toks_gset:cn{g_xref_#1_prop}{#2} \group_end: } -\def:Npn \xref_set_label:n #1{ - \def:Npx \tmp:w{\prop_use:N\g_xref_all_curr_immediate_fields_plist} - \exp_args:NNx\iow_deferred_expanded:Nn \xref_write{ +\cs_set_nopar:Npn \xref_set_label:n #1{ + \cs_set_nopar:Npx \xref_tmp:w{\toks_use:N\g_xref_all_curr_immediate_fields_prop} + \exp_args:NNx\iow_shipout_x:Nn \xref_write{ \xref_define_label:nn {#1} { - \tmp:w - \prop_use:N \g_xref_all_curr_deferred_fields_plist + \xref_tmp:w + \toks_use:N \g_xref_all_curr_deferred_fields_prop } } } |