From bfb16a7c8d3c77987590435854c647b54bc6450b Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Sun, 6 Sep 2009 23:20:42 +0000 Subject: xpackages (5sep09) git-svn-id: svn://tug.org/texlive/trunk@15164 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/doc/latex/xpackages/README | 91 - Master/texmf-dist/doc/latex/xpackages/ldcsetup.pdf | Bin 100772 -> 0 bytes Master/texmf-dist/doc/latex/xpackages/readme-ctan | 91 + Master/texmf-dist/doc/latex/xpackages/template.pdf | Bin 226030 -> 0 bytes .../doc/latex/xpackages/xbase/ldcsetup.pdf | Bin 0 -> 207075 bytes .../doc/latex/xpackages/xbase/template.pdf | Bin 0 -> 361353 bytes .../doc/latex/xpackages/xbase/xparse.pdf | Bin 0 -> 764909 bytes Master/texmf-dist/doc/latex/xpackages/xparse.pdf | Bin 468168 -> 0 bytes .../doc/latex/xpackages/xtras/l3keys2e.pdf | Bin 0 -> 419801 bytes .../texmf-dist/source/latex/xpackages/ldcsetup.dtx | 331 --- .../source/latex/xpackages/template-test.tex | 77 - .../source/latex/xpackages/template-test2.tex | 110 - .../texmf-dist/source/latex/xpackages/template.dtx | 2456 -------------------- .../source/latex/xpackages/tprestrict-test.tex | 80 - Master/texmf-dist/source/latex/xpackages/xbase.ins | 73 - .../source/latex/xpackages/xbase/ldcsetup.dtx | 331 +++ .../source/latex/xpackages/xbase/template-test.tex | 77 + .../latex/xpackages/xbase/template-test2.tex | 110 + .../source/latex/xpackages/xbase/template.dtx | 2452 +++++++++++++++++++ .../latex/xpackages/xbase/tprestrict-test.tex | 80 + .../source/latex/xpackages/xbase/xbase.ins | 73 + .../source/latex/xpackages/xbase/xparse-test.tex | 296 +++ .../source/latex/xpackages/xbase/xparse.dtx | 2443 +++++++++++++++++++ .../source/latex/xpackages/xparse-test.tex | 311 --- .../texmf-dist/source/latex/xpackages/xparse.dtx | 2151 ----------------- .../source/latex/xpackages/xtras/l3keys2e-demo.tex | 46 + .../source/latex/xpackages/xtras/l3keys2e.dtx | 322 +++ .../source/latex/xpackages/xtras/l3keys2e.ins | 19 + Master/texmf-dist/tex/latex/xpackages/ldcsetup.sty | 193 -- Master/texmf-dist/tex/latex/xpackages/template.sty | 567 ----- .../tex/latex/xpackages/xbase/ldcsetup.sty | 193 ++ .../tex/latex/xpackages/xbase/template.sty | 566 +++++ .../tex/latex/xpackages/xbase/xparse.sty | 899 +++++++ Master/texmf-dist/tex/latex/xpackages/xparse.sty | 563 ----- .../tex/latex/xpackages/xtras/l3keys2e.sty | 117 + 35 files changed, 8115 insertions(+), 7003 deletions(-) delete mode 100644 Master/texmf-dist/doc/latex/xpackages/README delete mode 100644 Master/texmf-dist/doc/latex/xpackages/ldcsetup.pdf create mode 100644 Master/texmf-dist/doc/latex/xpackages/readme-ctan delete mode 100644 Master/texmf-dist/doc/latex/xpackages/template.pdf create mode 100644 Master/texmf-dist/doc/latex/xpackages/xbase/ldcsetup.pdf create mode 100644 Master/texmf-dist/doc/latex/xpackages/xbase/template.pdf create mode 100644 Master/texmf-dist/doc/latex/xpackages/xbase/xparse.pdf delete mode 100644 Master/texmf-dist/doc/latex/xpackages/xparse.pdf create mode 100644 Master/texmf-dist/doc/latex/xpackages/xtras/l3keys2e.pdf delete mode 100644 Master/texmf-dist/source/latex/xpackages/ldcsetup.dtx delete mode 100644 Master/texmf-dist/source/latex/xpackages/template-test.tex delete mode 100644 Master/texmf-dist/source/latex/xpackages/template-test2.tex delete mode 100644 Master/texmf-dist/source/latex/xpackages/template.dtx delete mode 100644 Master/texmf-dist/source/latex/xpackages/tprestrict-test.tex delete mode 100644 Master/texmf-dist/source/latex/xpackages/xbase.ins create mode 100644 Master/texmf-dist/source/latex/xpackages/xbase/ldcsetup.dtx create mode 100644 Master/texmf-dist/source/latex/xpackages/xbase/template-test.tex create mode 100644 Master/texmf-dist/source/latex/xpackages/xbase/template-test2.tex create mode 100644 Master/texmf-dist/source/latex/xpackages/xbase/template.dtx create mode 100644 Master/texmf-dist/source/latex/xpackages/xbase/tprestrict-test.tex create mode 100644 Master/texmf-dist/source/latex/xpackages/xbase/xbase.ins create mode 100644 Master/texmf-dist/source/latex/xpackages/xbase/xparse-test.tex create mode 100644 Master/texmf-dist/source/latex/xpackages/xbase/xparse.dtx delete mode 100644 Master/texmf-dist/source/latex/xpackages/xparse-test.tex delete mode 100644 Master/texmf-dist/source/latex/xpackages/xparse.dtx create mode 100644 Master/texmf-dist/source/latex/xpackages/xtras/l3keys2e-demo.tex create mode 100644 Master/texmf-dist/source/latex/xpackages/xtras/l3keys2e.dtx create mode 100644 Master/texmf-dist/source/latex/xpackages/xtras/l3keys2e.ins delete mode 100644 Master/texmf-dist/tex/latex/xpackages/ldcsetup.sty delete mode 100644 Master/texmf-dist/tex/latex/xpackages/template.sty create mode 100644 Master/texmf-dist/tex/latex/xpackages/xbase/ldcsetup.sty create mode 100644 Master/texmf-dist/tex/latex/xpackages/xbase/template.sty create mode 100644 Master/texmf-dist/tex/latex/xpackages/xbase/xparse.sty delete mode 100644 Master/texmf-dist/tex/latex/xpackages/xparse.sty create mode 100644 Master/texmf-dist/tex/latex/xpackages/xtras/l3keys2e.sty (limited to 'Master') diff --git a/Master/texmf-dist/doc/latex/xpackages/README b/Master/texmf-dist/doc/latex/xpackages/README deleted file mode 100644 index ccef2cc6007..00000000000 --- a/Master/texmf-dist/doc/latex/xpackages/README +++ /dev/null @@ -1,91 +0,0 @@ - - Experimental Packages Demonstrating - Possible LaTeX3 High-Level Concepts - ==================================== - - 2009/06/09 - - -WHERE TO GET IT ---------------- - -The files in this distribution represent a snapshot of selected files -from the Subversion (SVN) repository of the LaTeX3 Project. - -To obtain current versions of the files, visit - which contains further -instructions. - -OVERVIEW --------- - -The `xpackages' term is a designation used for proto-type -implementations of new concepts for a LaTeX Designer Interface. Some -work as standalone packages providing new functionality, such as the -packages in xbase; others go deeper and redefine LaTeX internals in -order to provide newer and better methods for managing certain -constructs. - -All xpackages require expl3 and, in addition to this, many require -functionality provided by the packages within the xbase bundle. - -Currently included in the CTAN release of xpackages are the following -bundles: - xbase - -xbase ------ - -The xbase bundle provides the packages xparse and template, and the -support package ldcsetup. - -The xparse package provides a high-level interface for declaring -document commands, e.g., a uniform way to define commands taking -optional arguments, optional stars (and others), mandatory arguments -and more. - -The template package provides an interface for defining generic -functions using a key=val syntax. - -The ldcsetup package used to establish prototype LaTeX3 coding conventions, -needed by xparse and xbase, but is now slowly being stripped in favor -of functionality added to expl3. - -Files included: - source: xbase.ins, xparse.dtx, template.dtx, ldcsetup.dtx - test: template-test.tex, template-test2.tex, tprestrict-test.tex, - xparse-test.tex - - - -DISCUSSION ----------- - -Discussion concerning the approach, suggestions for improvements, changes, -additions, etc. should be addressed to the list LATEX-L. - -You can subscribe to this list by sending mail to - - listserv@urz.uni-heidelberg.de - -with the body containing - - subscribe LATEX-L - - -BUGS ----- - -If you find a real bug that makes a package stop working you can -report it via the standard LaTeX bug reporting mechanism of the LaTeX -distribution (see bugs.txt there) using the category "Experimental -LaTeX kernel". However please do *not* use this method for -suggestions / comments / improvements / etc. For this the list LATEX-L -should be used instead. - -Also please don't expect these package to work with *any* code that -floats around in the LaTeX2e world. :-) - - ---- Copyright 1998 -- 2009 - The LaTeX3 Project. All rights reserved --- diff --git a/Master/texmf-dist/doc/latex/xpackages/ldcsetup.pdf b/Master/texmf-dist/doc/latex/xpackages/ldcsetup.pdf deleted file mode 100644 index 1db38a85a57..00000000000 Binary files a/Master/texmf-dist/doc/latex/xpackages/ldcsetup.pdf and /dev/null differ diff --git a/Master/texmf-dist/doc/latex/xpackages/readme-ctan b/Master/texmf-dist/doc/latex/xpackages/readme-ctan new file mode 100644 index 00000000000..ccef2cc6007 --- /dev/null +++ b/Master/texmf-dist/doc/latex/xpackages/readme-ctan @@ -0,0 +1,91 @@ + + Experimental Packages Demonstrating + Possible LaTeX3 High-Level Concepts + ==================================== + + 2009/06/09 + + +WHERE TO GET IT +--------------- + +The files in this distribution represent a snapshot of selected files +from the Subversion (SVN) repository of the LaTeX3 Project. + +To obtain current versions of the files, visit + which contains further +instructions. + +OVERVIEW +-------- + +The `xpackages' term is a designation used for proto-type +implementations of new concepts for a LaTeX Designer Interface. Some +work as standalone packages providing new functionality, such as the +packages in xbase; others go deeper and redefine LaTeX internals in +order to provide newer and better methods for managing certain +constructs. + +All xpackages require expl3 and, in addition to this, many require +functionality provided by the packages within the xbase bundle. + +Currently included in the CTAN release of xpackages are the following +bundles: + xbase + +xbase +----- + +The xbase bundle provides the packages xparse and template, and the +support package ldcsetup. + +The xparse package provides a high-level interface for declaring +document commands, e.g., a uniform way to define commands taking +optional arguments, optional stars (and others), mandatory arguments +and more. + +The template package provides an interface for defining generic +functions using a key=val syntax. + +The ldcsetup package used to establish prototype LaTeX3 coding conventions, +needed by xparse and xbase, but is now slowly being stripped in favor +of functionality added to expl3. + +Files included: + source: xbase.ins, xparse.dtx, template.dtx, ldcsetup.dtx + test: template-test.tex, template-test2.tex, tprestrict-test.tex, + xparse-test.tex + + + +DISCUSSION +---------- + +Discussion concerning the approach, suggestions for improvements, changes, +additions, etc. should be addressed to the list LATEX-L. + +You can subscribe to this list by sending mail to + + listserv@urz.uni-heidelberg.de + +with the body containing + + subscribe LATEX-L + + +BUGS +---- + +If you find a real bug that makes a package stop working you can +report it via the standard LaTeX bug reporting mechanism of the LaTeX +distribution (see bugs.txt there) using the category "Experimental +LaTeX kernel". However please do *not* use this method for +suggestions / comments / improvements / etc. For this the list LATEX-L +should be used instead. + +Also please don't expect these package to work with *any* code that +floats around in the LaTeX2e world. :-) + + +--- Copyright 1998 -- 2009 + The LaTeX3 Project. All rights reserved --- diff --git a/Master/texmf-dist/doc/latex/xpackages/template.pdf b/Master/texmf-dist/doc/latex/xpackages/template.pdf deleted file mode 100644 index c9b199bbda7..00000000000 Binary files a/Master/texmf-dist/doc/latex/xpackages/template.pdf and /dev/null differ diff --git a/Master/texmf-dist/doc/latex/xpackages/xbase/ldcsetup.pdf b/Master/texmf-dist/doc/latex/xpackages/xbase/ldcsetup.pdf new file mode 100644 index 00000000000..07615093cbe Binary files /dev/null and b/Master/texmf-dist/doc/latex/xpackages/xbase/ldcsetup.pdf differ diff --git a/Master/texmf-dist/doc/latex/xpackages/xbase/template.pdf b/Master/texmf-dist/doc/latex/xpackages/xbase/template.pdf new file mode 100644 index 00000000000..4d67cb17a13 Binary files /dev/null and b/Master/texmf-dist/doc/latex/xpackages/xbase/template.pdf differ diff --git a/Master/texmf-dist/doc/latex/xpackages/xbase/xparse.pdf b/Master/texmf-dist/doc/latex/xpackages/xbase/xparse.pdf new file mode 100644 index 00000000000..8dd55866da1 Binary files /dev/null and b/Master/texmf-dist/doc/latex/xpackages/xbase/xparse.pdf differ diff --git a/Master/texmf-dist/doc/latex/xpackages/xparse.pdf b/Master/texmf-dist/doc/latex/xpackages/xparse.pdf deleted file mode 100644 index bf63758c4aa..00000000000 Binary files a/Master/texmf-dist/doc/latex/xpackages/xparse.pdf and /dev/null differ diff --git a/Master/texmf-dist/doc/latex/xpackages/xtras/l3keys2e.pdf b/Master/texmf-dist/doc/latex/xpackages/xtras/l3keys2e.pdf new file mode 100644 index 00000000000..75583163f48 Binary files /dev/null and b/Master/texmf-dist/doc/latex/xpackages/xtras/l3keys2e.pdf differ diff --git a/Master/texmf-dist/source/latex/xpackages/ldcsetup.dtx b/Master/texmf-dist/source/latex/xpackages/ldcsetup.dtx deleted file mode 100644 index 09e37c55cb3..00000000000 --- a/Master/texmf-dist/source/latex/xpackages/ldcsetup.dtx +++ /dev/null @@ -1,331 +0,0 @@ -% \iffalse -%% File: ldcsetup.dtx (C) Copyright 1999 Frank Mittelbach, Chris Rowley, David Carlisle -%% (C) Copyright 2004-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 -%% 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 ``xbase 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{expl3} -% -%\fi -\GetIdInfo$Id: ldcsetup.dtx 1295 2009-05-06 08:32:25Z will $ - {coding conventions and stuff} -%\iffalse -%<*driver> -%\fi -\ProvidesFile{\filename.\filenameext} - [\filedate\space v\fileversion\space\filedescription] -%\iffalse -\documentclass{ltxdoc} -\begin{document} -\DocInput{ldcsetup.dtx} -\end{document} -% -% \fi -% -% \CheckSum{0} -% -% \title{The \textsf{ldcsetup} package\thanks{This file -% has version number \fileversion, last -% revised \filedate.}} -% \author{DPC, FMi} -% \date{\filedate} -% \maketitle -% -% \begin{abstract} -% Basic code shared by several other packages currently under development. -% \end{abstract} -% -% \StopEventually{} -% -% \begin{macrocode} -%<*package> -\ProvidesExplPackage - {\filename}{\filedate}{\fileversion}{\filedescription} -% \end{macrocode} -% \begin{macrocode} -\RequirePackage{keyval} -\RequirePackage{expl3} -\ExplSyntaxOff -% \end{macrocode} -% -% \section{Ignoring White Space} -% Within a package, or in a document preamble, you can use -% |\IgnoreWhiteSpace| this makes white space ignored, and |@| -% a letter, and |~| a space character. It lasts until the end of the -% current package or preamble. -% -%% Puts an ignored space at the end of the line, so `|\ |' does the right -% thing. (Perhaps should instead just change catcode of |^^M|) -% \begin{macrocode} -\def\IgnoreWhiteSpace{% - \edef\@tempa{% - \catcode`\noexpand\~=\the\catcode`\~\relax - \catcode`\noexpand\ =\the\catcode`\ \relax - \catcode`\noexpand\^^I=\the\catcode`\^^I\relax - \catcode`\noexpand\@=\the\catcode`\@\relax - \endlinechar=\the\endlinechar\relax - }% - \ifx\@currname\@empty - \expandafter\AtBeginDocument\expandafter{\@tempa}% - \else - \expandafter\AtEndOfPackage\expandafter{\@tempa}% - \fi - \catcode`\~=10\relax - \catcode`\ =9\relax - \catcode`\^^I=9\relax - \makeatletter - \endlinechar=` % - \relax -} -% \end{macrocode} -% The new syntax requires |:| and |_| to be letters; instead of -% putting that into |\IgnoreWhiteSpace| we make a new command which -% helps to gradually change packages from old to new syntax. -% \begin{macrocode} -\def\InternalSyntaxOn{% - \edef\@tempa{% - \catcode`\noexpand\~=\the\catcode`\~\relax - \catcode`\noexpand\ =\the\catcode`\ \relax - \catcode`\noexpand\^^I=\the\catcode`\^^I\relax - \catcode`\noexpand\@=\the\catcode`\@\relax - \catcode`\noexpand\:=\the\catcode`\:\relax - \catcode`\noexpand\_=\the\catcode`\_\relax - \endlinechar=\the\endlinechar\relax -%FMi fix is not properly reset - \endlinechar=13\relax - }% -%%% ???? -% this needs further work, don't think it is working - \ifx\InternalSyntaxOff\relax - \expandafter\def\expandafter\InternalSyntaxOff\expandafter - {\@tempa\let\InternalSyntaxOff\relax}% - \fi - \ifx\@currname\@empty - \expandafter\AtBeginDocument\expandafter{\@tempa}% - \else - \expandafter\AtEndOfPackage\expandafter{\@tempa}% - \fi - \catcode`\~=10\relax - \catcode`\ =9\relax - \catcode`\^^I=9\relax - \makeatletter - \catcode`\_=11\relax - \catcode`\:=11\relax - \endlinechar=` % - \relax -} -\let\InternalSyntaxOff\relax -% \end{macrocode} -% -% Do it for this package. -% \begin{macrocode} -%\InternalSyntaxOn -\ExplSyntaxOn -% \end{macrocode} -% -% \section{KV fixes} -% Allow\footnote{Not needed now?} key names to start with |\|. -% \begin{macrocode} -\cs_set_nopar:Npn \define@key#1#2{% - \@ifnextchar[ - {\KV@def{#1}{\string#2}} - {\@namedef{KV@#1@\string#2}####1}} -\cs_set_nopar:Npn \setkeys#1#2{% - \cs_set_nopar:Npn \KV@prefix{KV@#1@\expandafter\string}% - \KV@do#2,\relax,} -% \end{macrocode} -% -% Make KV |#| safe. -% \begin{macrocode} -% \end{macrocode} -% -% \begin{macrocode} -\newtoks\KV@toks -% \end{macrocode} -% -% \begin{macrocode} -\cs_set_nopar:Npn \KV@@sp@c#1\@nil#2\relax#3{\KV@toks{#1}\cs_set_nopar:Npx #3{\the\KV@toks}} -% \end{macrocode} -% -% Generate error messages on missing `,'. -% -% More exactly if two `=' appear after a key generate an error. -% The current KV just silently ignores everything after the second `='. -% \begin{macrocode} -\cs_set_nopar:Npn \KV@equal{=} -% \end{macrocode} -% -% \begin{macrocode} -\cs_set_nopar:Npn \KV@split#1=#2=#3\relax{% - \KV@@sp@def\@tempa{#1}% - \cs_set_nopar:Npn \@tempd{#3}% - \ifx\@tempa\@empty\else - \expandafter\cs_set_eq:NN \expandafter\@tempc - \csname\KV@prefix\@tempa\endcsname - \ifx\@tempc\relax - \KV@error{\@tempa\space \expandafter\@gobbletwo\string\@undefined}\@eha - \else - \ifx\@tempd\@empty - \KV@default - \else - \KV@@sp@def\@tempb{#2}% - \ifx\@tempd\KV@equal - \expandafter\@tempc\expandafter{\@tempb}\relax - \else - \KV@error{Extra~=~ sign~ after~ `#1'}\KV@erry - \fi - \fi - \fi - \fi} -% \end{macrocode} -% -% \begin{macrocode} -\cs_set_nopar:Npn \KV@erry{\expandafter\KV@errx\meaning\@tempd\relax ignored\MessageBreak - missing~comma~in~`\expandafter\strip@prefix\meaning\@tempb'~?} -% \end{macrocode} -% -% \begin{macrocode} -\cs_set_nopar:Npn \KV@errx#1>#2==\relax{% - `#2' } -% \end{macrocode} -% -% \begin{macrocode} -\cs_set_nopar:Npn \KV@default{% - \expandafter\cs_set_eq:NN \expandafter\@tempb - \csname\KV@prefix\@tempa @default\endcsname - \ifx\@tempb\relax - \KV@error{No value specified for \@tempa}\@eha - \else - \@tempb\relax - \fi} -% \end{macrocode} -% -% \LaTeX\ style error message. -% \begin{macrocode} -\cs_set_nopar:Npn \KV@error#1#2{\PackageError{keyval}{#1}{#2}} -% \end{macrocode} -% -% Instead of doing a full KV parse, and evaluating all the keys, -% you might want to parse a parameter list, even for undefined keys, -% removing spaces, splitting up the `,` and `=' and resolving cases -% where no value is supplied. This is used in |\DeclareGenericFunction| -% which \emph{defines} a set of keys via such a KV parse. -% -% A setting of |, key = value ,| will result in |\KV@elt{key}{value}| -% being added to the list, a seting of |, key ,| will result in -% |\KV@default@elt{key}| being added. At the end of the parse the list -% is executed. No keys are checked at this stage (so no csnames are used -% up) the two |\KV|\ldots|@elt| commands must be defined as appropriate. -% -% \begin{macrocode} -\cs_set_nopar:Npn \KV@parse#1{ - \begingroup -% \end{macrocode} -% -% Locally fudge |\KV@@def| to just add to a token register -% rather than make a definition. -% \begin{macrocode} -\cs_set_nopar:Npn \KV@@sp@c##1\@nil##2\relax##3{\addto@hook##3{{##1}}} -% \end{macrocode} -% -% Locally fudge |\KV@split| to just add to a token register -% rather than execute the code for the found keys. -% \begin{macrocode} -\cs_set_nopar:Npn \KV@split##1=##2=##3\relax{% - \cs_set_nopar:Npn \@tempd{##3}% - \expandafter\ifx\expandafter=\@firstofone##1=\else - \ifx\@tempd\@empty - \addto@hook\KV@toks\KV@default@elt - \KV@@sp@def\KV@toks{##1}% - \else - \ifx\@tempd\KV@equal - \addto@hook\KV@toks\KV@elt - \KV@@sp@def\KV@toks{##1}% - \KV@@sp@def\KV@toks{##2}% - \else - \KV@err{Extra `=' after `##1'}\@ehd - \fi - \fi - \fi} -% \end{macrocode} -% -% Initialise -% \begin{macrocode} - \KV@toks{} -% \end{macrocode} -% Do the parse -% \begin{macrocode} - \KV@do#1,\relax, -% \end{macrocode} -% Evaluate the token register outside the group. -% \begin{macrocode} - \expandafter - \endgroup - \the\KV@toks} -% \end{macrocode} -% -% \section{Calc fixes} -% -% Count Register assignments via calc. Here we also provide some -% global versions since a normal global prefix won't have any effect. -% \begin{macrocode} -\cs_set_eq:NN \SetInternalCounter \calc_int_set:Nn -\cs_set_eq:NN \GSetInternalCounter\calc_int_gset:Nn -% \end{macrocode} -% -% -% \section{Misc code that is best collected in one place} -% -% This section will receive odd code that would be of potential use to -% other packages and should eventually made it to the kernel -% (perhaps). -% -% \begin{macro}{\UndeclareRobustCommand} -% Remove a robust command from memory if it isn't used any -% longer. Of course this doesn't free the hash table but at least -% the space gets reclaimed. -% \begin{macrocode} -\cs_set_nopar:Npn \UndeclareRobustCommand#1{% - \cs_gundefine:N #1 - \exp_args:Nc \cs_gundefine:N {\cs_to_str:N #1~} -} -% \end{macrocode} -% \end{macro} -% -% -% \begin{macrocode} -% -% \end{macrocode} -% -% \Finale -% diff --git a/Master/texmf-dist/source/latex/xpackages/template-test.tex b/Master/texmf-dist/source/latex/xpackages/template-test.tex deleted file mode 100644 index f8c47c82d59..00000000000 --- a/Master/texmf-dist/source/latex/xpackages/template-test.tex +++ /dev/null @@ -1,77 +0,0 @@ -% \iffalse -%% (C) Copyright 2000-2004 LaTeX3 Project -%% -%% It may be distributed and/or modified under the conditions of the -%% LaTeX Project Public License (LPPL), either version 1.3a 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 ``xbase 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. -%% -%% ----------------------------------------------------------------------- -%% -%% $Id: template-test.tex 251 2004-11-11 19:01:16Z mittelba $ -%% -% \fi -% -\RequirePackage{template} - -\DeclareTemplateType{xxx}{0} - -\DeclareTemplate{xxx}{test}{0} - { - xkey=n \xkey, - key =i {yyy} \value - } - { - \DoParameterAssignments - \show\xkey - \show\value - \value - } - -\DeclareTemplateType{yyy}{0} - -\DeclareTemplate{yyy}{foo}{0} - { - keya =L \foo - } - { - \DoParameterAssignments - \show\foo - } - - -\DeclareInstance{xxx}{bar}{test} - { - xkey = \UseTemplate{yyy}{foo}{ keya = 20pt }, - key = \UseTemplate{yyy}{foo}{ keya = 10pt } - } - -\ShowInstance{xxx}{bar} - -\UseInstance{xxx}{bar} - -\stop diff --git a/Master/texmf-dist/source/latex/xpackages/template-test2.tex b/Master/texmf-dist/source/latex/xpackages/template-test2.tex deleted file mode 100644 index 489e9f2304a..00000000000 --- a/Master/texmf-dist/source/latex/xpackages/template-test2.tex +++ /dev/null @@ -1,110 +0,0 @@ -% \iffalse -%% (C) Copyright 2000-2004 LaTeX3 Project -%% -%% It may be distributed and/or modified under the conditions of the -%% LaTeX Project Public License (LPPL), either version 1.3a 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 ``xbase 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. -%% -%% ----------------------------------------------------------------------- -%% -%% $Id: template-test2.tex 585 2006-12-12 17:31:48Z morten $ -%% -% \fi -% - - -\RequirePackage{template} -\RequirePackage{trace} - -\DeclareTemplateType{xxx}{0} - -\def\MultiSelection{\MultiSelectionError} -%\def\foo{bar} - -%\traceon - -\DeclareTemplate{xxx}{test}{0} - { - xkey=n [\foo] \xkey, - ykey=n [\DelayEvaluation\foo] \ykey, - zkey=n \zkey, - last=n [last] \lastkey, - set =i {xxx} \xxx - } - { - \DoParameterAssignments - \typeout{abc} - } -\ShowTemplate{xxx}{test} - - -\DeclareInstance{xxx}{bar}{test} - { - zkey = foo, - xkey = baz, - } - -\DeclareInstance{xxx}{baz}{test} - { - last = first, - set = \UseTemplate{xxx}{test}{zkey=rrr}, - zkey = foo - } - - -\ShowInstance{xxx}{bar} -\ShowInstance{xxx}{baz} - -\DeclareTemplateType{yyy}{0} - -\DeclareTemplate{yyy}{foo}{0} - { - keya =L \foo - } - { - \DoParameterAssignments - \show\foo - } - - -\DeclareInstance{xxx}{bar}{test} - { - xkey = \UseTemplate{yyy}{foo}{ keya = 20pt }, - key = \UseTemplate{yyy}{foo}{ keya = 10pt } - } - -\ShowInstance{xxx}{bar} - -\UseInstance{xxx}{bar} - -\stop - -%%% Local Variables: -%%% mode: plain-tex -%%% TeX-master: t -%%% End: diff --git a/Master/texmf-dist/source/latex/xpackages/template.dtx b/Master/texmf-dist/source/latex/xpackages/template.dtx deleted file mode 100644 index 6c5fd2a686a..00000000000 --- a/Master/texmf-dist/source/latex/xpackages/template.dtx +++ /dev/null @@ -1,2456 +0,0 @@ -% \iffalse -%% File: template.dtx (C) Copyright 1999-2001 David Carlisle, Frank Mittelbach -%% (C) Copyright 2004-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 -%% 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 ``xbase 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{expl3} -% -%\fi -\GetIdInfo$Id: template.dtx 1295 2009-05-06 08:32:25Z will $ - {template} -%\iffalse -%<*driver> -%\fi -\ProvidesFile{\filename.\filenameext} - [\filedate\space v\fileversion\space\filedescription] -%\iffalse -\documentclass{ltxdoc} -\makeatletter - \newenvironment{decl}[1][]% - {\par\small\addvspace{4.5ex plus 1ex}% - \vskip -\parskip - \ifx\relax#1\relax - \def\@decl@date{}% - \else - \def\@decl@date{\NEWfeature{#1}}% - \fi - \noindent\hspace{-\leftmargini}% - \begin{tabular}{|l|}\hline\ignorespaces}% - {\\\hline\end{tabular}\nobreak\@decl@date\par\nobreak - \vspace{2.3ex}\vskip -\parskip\@afterheading} -\makeatother - - \begin{document} - \catcode`\_=11 - \catcode`\:=11 - \DocInput{template.dtx} - \end{document} -% -% -% -% \fi -% -% -% \CheckSum{0} -% -% \title{The \textsf{template} package\thanks{This file -% has version number \fileversion, last -% revised \filedate.}} -% \author{DPC, FMi} -% \date{\filedate} -% \maketitle -% -% \changes{0.06}{1998/12/17}{generic functions reborn as templates} -% -% \tableofcontents -% -% \section{Introduction} -% A \emph{Template} is a named `function' that has a fixed number -% of \emph{mandatory arguments} and an additional set of \emph{keys} -% or `named attributes' that are set in a `key value list'. That is, -% a comma separated set of assignments of the form:\\ -% \meta{key$_1$} |=| \meta{value$_1$} |,| -% \meta{key$_2$} |=| \meta{value$_2$} \ldots -% -% More specific instances of the template may be declared by -% specifying settings of the parameters. The key value list is parsed -% at the time the instance is declared, and an `internal' set of -% parameter assignments is passed to the template code. It is normally -% not parsed at run-time, though it is possible to enforce this -% behaviour. -% -% Templates have a \emph{type} and a \emph{name}. Templates -% of the same type have the same argument and parameter -% structure. That is, templates of the same type are expected to be -% exchangeable semantically. (However, except for checking that -% templates of the same type always have the same number of arguments -% this is not enforced by the code.) -% -% A template type is declared via the |\DeclareTemplateType| -% declaration which takes two arguments: the name for the type and the -% number of arguments a template of this type requires. -% -% Templates are declared via the |\DeclareTemplate| -% command which takes five arguments -% \begin{itemize} -% \item The \emph{type} of the template (no |\|). -% \item The \emph{name} of the template (no |\|). -% \item The number of arguments for the template (same as on type -% declaration). -% \item A list declaring the keys accepted by the template, -% with information about the action to take when the key is specified -% with a value. -% \item The code for the template. This may be arbitrary \TeX\ -% code. At some point it should execute |\DoParameterAssignments| -% to run the parameter assigments. -% -% The mandatory arguments are accessed via |#1|, |#2|, \ldots -% \end{itemize} -% -% -% Each element of the key specification list is of the form: -% \begin{flushleft} -% \meta{key name} |=| -% \meta{key type} \meta{optional default} \meta{internal code} -% \end{flushleft} -% -% The \meta{key types} are essentially specified by giving a symbolic -% representation of the assignment function to be used by \TeX. -% -% Currently the possibilities are -% -% \begin{center}\catcode`|=12 -% \begin{tabular}{l|ll|l} -% key type& letter& internal code& argument form\\\hline -% Command & f\emph{n}&command name & command definition\\ -% name & n & command name & command definition\\ -% length & l & length register& calc length syntax\\ -% fake length & L & command name & calc length syntax\\ -% count & c & count register& calc count syntax\\ -% fake count & C & command name & calc count syntax\\ -% boolean & b & name of \verb|\newif| switch& true or false\\ -% switch & s & \marg{true code}\marg{false code}& true or false\\ -% instance& i\marg{type}& command name& instance of this \emph{type}\\ -% direct & x & Internal code& any\\ -% general & g & general code & any -% \end{tabular} -% \end{center} -% -% In addition, any of these types may be prefixed by |+| to -% denote a global assignment (described below). -% |f| takes a digit from 0--9 to denote the number of arguments. -% |n| is in fact the same as |f0|. When an instance is declared -% The value assigned to the key should be the definition of -% the command, using |#1|\ldots|#9| to denote the specified arguments. -% -% |c| takes an internal form a count register, -% not a \LaTeX\ counter name. -% -% For |f|, |n|, |l|, and |c|, the assignment is done twice, once -% at the time an instance is \emph{declared}. (This may involve -% using \textsf{calc} expresions. Then the `primitive assignment' -% of the value (not using calc) is copied to the internal parameter -% list, to be executed when an instance is run. Sometimes you need the -% expression to be evaluated at the time an instance is run rather -% than the time it is declared. For example it may be an expression -% involving some values that are not fixed throughout a document. -% In this case the instance declaration may give a value in the -% form |\DelayedEvaluation|\marg{calc expression}. In this case -% the value is not evaluated when the instance is declared, and -% instead the entire expression is copied to the `internal parameter -% list' and is evaluated whenever the instance is used. -% -% |L| and |C| take the same value types as |l| and |c| but the internal -% assignments are to macros not registers. -% -% Keys declared with |b| and |s| each take values either \emph{true} or -% \emph{false}. if the key zzz is declared with |b| then specifying -% |zzz=true| will essentially pass |\zzztrue| to the internal parameter -% list (although in fact |\zzztrue| need not be defined) . If instead -% zzz had been declared via |s|, then |zzz=true| would pass the tokens -% of the \marg{true code} to the internal parameter list. -% -% If a key is specified as |x|, then when used the \emph{internal code} -% will be copied to the internal parameter lists. This code may use |#1| -% to denote the value supplied to the key in the instance declaration. -% Note that this code is \emph{only} copied at the time the instance is -% declared. It is not executed at this time. It is executed when the -% instance is executed.\footnote{Despite the question of whether or -% not x and g are still necessary these days, they have the wrong -% `names' since x is the one that is not executed during delcaration -% while g is.} -% -% If a key is declared with |g| then the code is run at the time the -% instance is declared. By default \emph{nothing} is passed to the -% internal parameter list. This code may use |#1| to denote the -% value that will be supplied when an instance is declared. -% Any code that should be run when an instance is executed should -% be explicitly passed to the internal parameter list using -% |\toks_add_right:Nn\l_TP_KV_assignments_toks{|\ldots|}| -% -% A key declared with |i|\marg{type} takes as value the name of a -% declared instance of that type. The command token associated with -% the key will store a command essentially equivalent to a call -% to |\UseInstance|\marg{type}\marg{name}, but in a slightly optimised -% internal form. -% As an exception to this rule the replacement code may be of the form -% |\UseTemplate| followed by the key settings for the template -% but without the mandatory arguments. In this case the `inner' -% instance declaration is `pre compiled' and the token assigned to -% the store the value assigned to this key will execute an instance -% of the template directly, it will not re-parse the keyword settings -% each time the instance is used. -% -% \section{Commands} -% -% -% \subsection{Template declaration commands} -% -% \begin{decl} -% |\DeclareTemplateType| \marg{type}\marg{num} -% \end{decl} -% Declare a template type. -% -% \begin{decl} -% |\DeclareTemplate| -% \marg{type}\marg{tname}\marg{num}\marg{keyspec}\marg{code} -% \end{decl} -% Declare a template \meta{tname} of type \meta{type} with the set of -% keys as defined by \meta{keyspec}. From this template instances can -% be declared using |\DeclareInstance| At runtime such instances will run -% \meta{code} and expect \meta{num} mandatory arguments (same number -% for all templates of one type).\footnote{The \meta{num} argument is -% redundent as it can be deduced from the type. However, for practical -% reasons it seems better to keep that information with each -% individual template declaration.} -% -% \begin{decl} -% |\DeclareRestrictedTemplate| -% \marg{type}\marg{new-tname}\marg{old-tname}\marg{keyvals} -% \end{decl} -% Declare as new template \meta{new-tname} for type \meta{type} by -% taking template \meta{old-tname} as the basis and setting one or -% more of its keys to specific values. -% -% \begin{decl} -% |\DoParameterAssignments| -% \end{decl} -% The list of key value assignments made (and saved) during template -% declaration is evaluated at this point in the template code. -% -% -% \subsection{Instance declaration commands} -% -% \begin{decl} -% |\DeclareInstance| \marg{type}\marg{iname}\marg{tname}\marg{keyvals} -% \end{decl} -% Declare an instance of type \meta{type} named \meta{iname} build -% from using template \meta{tname} with key settings as given by -% \meta{keyvals}. -% -% \begin{decl} -% |\DeclareCollectionInstance| -% \marg{collection}\marg{type}\marg{iname}\marg{tname}\marg{keyvals} -% \end{decl} -% Same as |\DeclareInstance| except that this instance is only active -% when for the type \meta{type} the collection \meta{collection} was -% selected via |\UseCollection|. E.g., within the frontmatter one -% could make all headings behave differently by defining collection -% instances for template type `head'. -% -% \subsection{Key value commands} -% -% \begin{decl} -% |\DelayEvaluation|\marg{code} -% \end{decl} -% Used in the value spec for an instance to declare that the value -% \meta{code} should not be evaluated at declaration time but at -% run-time. Can also be used in the defaults for keys (given in square -% brackets) in the declaration of templates. -% -% \begin{decl} -% |\MultiSelection| \meta{counter} \marg{cases} \marg{else} -% \end{decl} -% Used in the value spec for an instance key to declare that the value of -% this key depends on the current setting of \meta{counter} at run-time. -% The \meta{cases} argument is a comma-separated list of ``values'', -% the \meta{else} argument a single ``value''. If at run-time -% \meta{counter} has the value $i$ then the $i$-th element of the -% \meta{cases} list is selected. If that does not exist the -% \meta{else} case is returned. -% -% -% \subsection{Processing commands} -% -% \begin{decl} -% |\UseTemplate| \marg{type}\marg{tname}\marg{keyval} -% \end{decl} -% Execute a template \meta{tname} of type \meta{type} at run-time -% using \meta{keyvals} as the value assignments for its keys. In this -% case the keys are evaluated at run-time thus this method is far -% slower than using a predeclared instance of this template (see -% below). This command can also appear as the value for a key of type -% `i' in which case the evaluation happens at declaration time of the -% template that contains this key! -% -% -% \begin{decl} -% |\UseInstance| \marg{type}\marg{iname} -% \end{decl} -% Run the instance \meta{iname} of template type \meta{type}. If a -% collection is in force see if there is a collection instance of name -% \meta{iname} and if so run that instead. -% -% \begin{decl} -% |\UseCollection| \marg{type}\marg{collection} -% \end{decl} -% Declare that from now on (normal scoping rules) the collection -% \meta{collection} for template type \meta{type} is in force. This -% means that a call to |\UseInstance| will first check if there is a -% collection instance defined, and if so use that instance, otherwise -% use the normal instance. -% -% -% \subsection{Test commands} -% -% \begin{decl} -% |\IfExistsInstanceTF| \marg{type}\marg{iname}\marg{true}\marg{false} -% \end{decl} -% Test if for template type \meta{type} an instance with name -% \meta{iname} exists. Select \meta{true} or \meta{false} code -% accordingly. -% -% -% -% \section{Examples of template key types} -% -% The general syntax for key specification in templates (fourth argument -% of the command |\DeclareTemplate|) is: -%\begin{flushleft} -%| {| \\ -%| | \meta{key-name$_1$} |=|\meta{key-type$_1$} -% \meta{optional-default$_1$} \meta{storage-bin$_1$}|,|\\ -%| | \meta{key-name$_2$} |=|\meta{key-type$_2$} -% \meta{optional-default$_2$} \meta{storage-bin$_2$}|,|\\ -%| ...|\\ -%| }| -%\end{flushleft} -% In this section we look at all possible key types and give examples -% for them. -% -% -% \subsection{Attributes that receive names as values} -% -% The type |n| expects to receive a \LaTeX{} name as a value. Used, -% for example, to specify the name of a \LaTeX{} counter to use. -%\begin{verbatim} -% heading-id =n \heading@id, -% counter-id =n [\DelayEvaluation{\heading@id}] \heading@counter, -%\end{verbatim} -% Notice the use of |\DelayEvaluation| in the default of -% |counter-id|. It is necessary to make the default the token -% |\heading@id| if we want to inherit the value from the |heading-id| -% key. Otherwise it gets value of |\heading@id| at the time the -% instance is declared. -% -% -% \subsection{Attributes that receive functions as values} -% -% -% The type |f|\meta{num} expects a function with \meta{num} arguments -% as a value. The arguments are denoted by |#1|, |#2|, etc. In most -% cases either |f0| (for declarations) or |f1| (to format one argument) are -% needed. -%\begin{verbatim} -% initial-font =f0 \initial@font, -% initial-format =f1 [#1] \initial@boxhandling, -%\end{verbatim} -% -% \subsection{Attributes that receive dimensions as values} -% -% As far as specifying instances the |l| and |L| type behave -% identically. They differ only in the type of internal storage-bin -% they need: |l| expects a length register while |L| expects an -% ordinary macro name and assigns its value via |\cs_set_nopar:Npn |. -%\begin{verbatim} -% pre-sep =l \topsep, -% post-sep =L \botsep, -%\end{verbatim} -% -% -% -% \subsection{Attributes that receive integers as values} -% -% The |c| and |C| type receive integers as values. Again either of -% them can be transparently used. In case of |c| the -% \meta{storage-bin} has to be a \TeX{} count register not a \LaTeX{} -% counter name, i.e., set up via |\newcount|. (\LaTeX{} counters can -% be used as well if they are accessed via their internal name, i.e., -% via |\c@|\meta{\LaTeX-counter}) -%\begin{verbatim} -% pre-penalty =c \@beginparpenalty, -% penalty =C \hmaterial@penalty, -%\end{verbatim} -% -% -% -% \subsection{Attributes that receive template instances as values} -% -% The type |i|\marg{type} takes as value the name of a declared -% instance of that type. The \meta{storage-bin} associated with the -% key will store a command essentially equivalent to a call to -% |\UseInstance|\marg{type}\marg{name}, but in a slightly optimised -% internal form. -% -% As an exception to this rule the replacement code may be of the form -% |\UseTemplate| followed by the key settings for the template but -% without the mandatory arguments. In this case the `inner' instance -% declaration is `pre compiled' and the token assigned to the store -% the value assigned to this key will execute an instance of the -% template directly, it will not re-parse the keyword settings each -% time the instance is used. -%\begin{verbatim} -% justification-setup =i{justification} \list@justification, -%\end{verbatim} -% -% Usage within an instance declaration is either -%\begin{verbatim} -% justification-setup = raggedright, -%\end{verbatim} -% i.e., name of a declared instance or a call to |\UseTemplate| -%\begin{verbatim} -% justification-setup = \UseTemplate{justification}{TeX} -% { startskip = 0pt, ... }, -%\end{verbatim} -% -% -% -% \subsection{Attributes that receive true or false values} -% -% The type |s| expects the strings |true| or |false| as values. In -% this case the declaration has no \meta{storage-bin}. Instead the -% declaration consists of two brace groups containing code. Depending -% on the value one of the groups gets copied verbatim into the -% internal parameter list of the instance and gets executed at -% run-time at the point where |\DoParameterAssignments| is seen. -%\begin{verbatim} -% item-implicit-boolean =s -% { \cs_set_nopar:Npn \item@implicit@code{\item\relax} }{}, -% numbered-boolean =b [true] @heading@nums, -%\end{verbatim} -% -% -% \subsection{Attributes that accept any value} -% -% The type |g| is a low-level specification which contains arbitrary -% code in place of the \meta{storage-bin}. This code is evaluated at -% declaration time of the instance and by default \emph{nothing} is -% passed to the internal parameter list (this has to happen explicitly -% from within the code). |#1| may be used to access the value -% specified. -% -% The main purpose for this type is of historical nature (originally -% most of the other types have been implemented internally using |g|). -% -% The type |x| also requires code in place of the \meta{storage-bin}. -% However with this type all of the code is copied unevaluated to the -% internal parameter list. There are some applications for this type -% when implementing customisable defaults. However, it is likely that -% it will not survive a final release. -%\begin{verbatim} -% generic-key =g \typeout{#1}, -% extra-assigns =x \typeout{#1}, -%\end{verbatim} -% -% -% -% -% -% -% \section{A complete example} -% -% The following example shows a sketch of a template for typesetting -% captions to be used as part of a larger mechanism setting whole -% floats.\footnote{I made it up while I went along so if you spot the -% ``missing brace'' or some other blunder tell me, FMi.} -% -% We declare a template type \texttt{caption} then define an example -% template for that type and finally produce some instances from that. -% -% \subsection{Declaring the template type} -% -% To define the template type we first have to ask ourselves what -% information would be varying each time such a template is used? A -% potential answer could be the following: -% \begin{itemize} -% \item -% The float name, e.g., `Table' or `Fig.' etc. -% \item -% The float -% number e.g., `10' or `3--c' etc. -% \item -% The actual caption text as specified in the document. -% \end{itemize} -% Since the above items would be differed in each instantiation of -% such a template we would pass them as mandatory argument to the -% template. -% -% Are there others? Possibly. Here are two more that seem to be -% useful, at least in a number of cases: -% \begin{itemize} -% \item -% The text of the legend in document classes that distinguish -% between caption text (heading to the figure/table) and legend -% (explanatory material) -% \item -% Measure to which the caption should be typeset. -% \end{itemize} -% The last one of these might need some extra explanation. Suppose a -% design requires that the caption width is decided depending on the -% width of the table of figure, e.g., the caption is supposed to -% typeset below some illustration and should not be wider than that -% illustration, or the caption is typeset aside to the illustration -% using the remaining space. In that case the process that formats the -% whole float needs to communicate with the current template to pass -% that (varying) information along. Of course, that could happen by -% using global variables, e.g., the outer process sets the measure as -% desired before calling the caption formatting template. What makes -% more sense is likely to be a matter of taste but it also has to do -% with the precise semantics of the template type. Staying with our -% example: if the the semantics of the template type \texttt{caption} -% is supposed to produce a formatted box (in \TeX{} terms) then we -% should pass the measure as an argument if we ever intend to allow -% for variations. If on the other hand the semantics are to format a -% certain set of text into the current galley (which has measure of -% its own) then a measure argument would not belong to this template -% type. -% -% Are there other variations sensible? Yes, for example, instead of -% passing a fixed string like ``Fig.'' as the first argument one could -% pass an abstract float type identifier and let the template worry to -% deduce from that information what fixed string to produce. -% -% Another question: why should we pass the fixed text (or an abstract -% identifier from which it can be deduced) and the number as separate -% arguments to the template instead of passing a combined string (like -% it is done in the |\@makecaption| command of \LaTeXe{})? Answer: -% because this allows to build templates that can individually -% manipulate both bits of information, e.g., to format the number in a -% different font, etc. -% -% So what are the conclusions of this discussion? Defining the -% semantics of a template type is difficult and often needs several -% trials to come up with something that is covering the anticipated -% use. There is clearly not a cardinal way for defining template -% types; how the overall separation into smaller units is done is -% partly a matter of taste and partly a matter of the major layout -% characteristics that one tries to support. -% -% Returning to our example: let's assume we settle for the first four -% arguments, i.e., the calling template is responsible for setting the -% measure for the caption text if necessary. -% -% What we also have to do is to define (at least for ourselves) what -% data the arguments accept and what their semantics are. An informal -% summary of that could be the following: -% \begin{center} -% \begin{tabular}{rrl} -% \textit{Arg} & \textit{Data Type} & \textit{Description} \\[3pt] -% 1 & text & fixed float description -% \\ -% 2 & text/|\NoValue| & float number -% \\ -% 3 & text & caption text -% \\ -% 4 & text/|\NoValue| & legend text -% \\ -% \end{tabular} -% \end{center} -% The second and the fourth argument are allowed to be missing (i.e., -% can get |\NoValue| passed as a value). Note that the empty string in -% case of a text argument is different from |\NoValue|. -% -% We further declare that it is permissible for a template of this -% type to ignore the information provided by all arguments except 3, -% i.e., the caption text. -% -% Finally the result of the template formatting should is to typeset -% text into a current galley (paragraph mode in \LaTeX{} lingua). -% -% All the above is semantic information that (at least right now) is -% not being enforced by declaring a template type (except for the -% number of arguments) but each template of a certain type is supposed -% to conform to this specification nonetheless.\footnote{To make this -% even clearer we are thinking of extending the template type -% declaration with another argument in which one has to formally or -% informally (?) specifies information like the one in the table -% above.} -% -% This finally leads to the following declaration: -%\begin{verbatim} -%\DeclareTemplateType{caption}{4} -%\end{verbatim} -% -% \subsection{Defining a first template} -% -% We start by defining a simple template of type \texttt{caption} -% which roughly formats a caption like those being presented in -% \LaTeXe{}'s article class, i.e., the caption is typeset as a -% paragraph if it is longer than a single line, otherwise it is -% centered. The legend even if present is ignored. Above and below we -% give the designer the possibility to add some space. -% -% In fact the examples is more or less identical in code to -% |\@makecaption| except that if the second argument (i.e., the -% number) is |\NoValue| it and its preceding space\footnote{For those -% who wonder: spaces are by default ignored within definitions when -% the new packages are used due to a command \texttt{\textbackslash -% InternalSyntaxOn}, do get a normal space one has to use -% \texttt{\textasciitilde} and to obtain an unbreakable space -% \texttt{\textbackslash nobreakspace}.} gets ignored. -% -% We start by declaring the template \texttt{toosimple} of type -% \texttt{caption} having four mandatory arguments (as described in -% the discussion of the template type). -%\begin{verbatim} -%\DeclareTemplate{caption}{toosimple}{4} -%\end{verbatim} -% The next argument of |\DeclareTemplate| lists all keys for the -% template. In this case we have keys for the vertical spaces above -% and below. We make them type |L| to save on registers but with a bit -% of care we could also have used scratch registers like |\@tempskipa| -% etc. Their default values are both zero. -%\begin{verbatim} -% { -% above-skip =L [0pt] \caption@above@skip , -% below-skip =L [0pt] \caption@below@skip , -% } -%\end{verbatim} -% The final argument of |\DeclareTemplate| contains the actual -% processing code. We start with looking at the second mandatory -% argument (caption number) to find out if it is |\NoValue| and -% depending on the result define a helper command |\caption@start|. -%\begin{verbatim} -% { -% \IfNoValueTF{#2} -% { \cs_set_nopar:Npn \caption@start{#1:~} } -% { \cs_set_nopar:Npn \caption@start{#1~#2:~} } -%\end{verbatim} -% Having dealt with the prelims we now run |\DoParameterAssigments| at -% which point the keys of the template are made available, e.g., at -% this point all those right hand containers such as -% |\caption@above@skip| get assigned the value specified in an -% instantiation of the template. (That scheme allows to do preliminary -% processing up front, e.g., defaults for the keys could be assigned -% prior to that point in which case they are overwritten if the -% template instance specifies a different value. the use of specifying -% defaults via the |[..]| syntax as done above is slightly faster at -% run-time but needs more memory.) -%\begin{verbatim} -% \DoParameterAssigments -%\end{verbatim} -% The rest of the code should look familiar to anybody who ever looked -% at \texttt{article.cls}. The only point worth mentioning are the -% |\relax| commands after |\caption@above@skip| and -% |\caption@below@skip|. Since we have decided to use |L| as key type -% these commands are macros and not registers containing the -% dimensions as strings. This means that we have to be careful to -% ensure that \TeX{} knows where the dimension ends. In certain cases -% text following such a command might be mistaken as being part of the -% dimension (e.g., if followed by the word \texttt{plus}, etc.). In -% the code below this could only happen for the second |\vskip| but it -% is good practice to always add a terminating |\relax| to avoid such -% hidden traps. -%\begin{verbatim} -% \vskip \caption@above@skip \relax -% \sbox \@tempboxa {\caption@start #3} -% \ifdim \wd\@tempboxa >\hsize -% \caption@start #3\par -% \else -% \global \@minipagefalse -% \hb@xt@\hsize{\hfil\box\@tempboxa\hfil} -% \fi -% \vskip \caption@below@skip \relax -% } -%\end{verbatim} -% -% Why is the above template of not much use? Simply because it doesn't -% offer any flexibility to declare different designs. The only -% alteration offered to the designer is to modify the space above and -% below the caption, e.g., the following declaration would mimic the -% definition within the \texttt{article.cls} class of \LaTeXe : -%\begin{verbatim} -%\DeclareInstance{caption}{article}{toosimple} -% { -% above-skip = 0pt, -% below-skip = 10pt, -% } -%\end{verbatim} -% And that's all that can be manipulated. All items that people asking -% to change, e.g., not having a colon after the number, using -% different fonts and font sizes, etc.\ are still hard-wired and thus -% inaccessible. So we have to do better if we want to make use of the -% power the template mechanism offers. -% -% -% -% \subsection{Defining a better template} -% -% First step in defining better templates is to ask ourselves a couple -% of questions: -% \begin{itemize} -% \item What are the main characteristics of the layout the template -% is supposed to support? -% \item What are the elements that we want to allow (or can allow) the -% designer to modify? -% \end{itemize} -% -% Take the first question first: the layout supported by the template -% of the previous section had as its main characteristics that it -% would center the caption if it would fit in a single line in the -% current measure. We could consider this being an unchangable -% characteristic of the layout this template produces (and a designer -% would need to use a different template of type \texttt{caption} if a -% design compatible with this restriction is desired) or we could try -% to make our template smarter by adding bells and wistles that allow -% the designer to say stuff like: -%\begin{verbatim} -% one-line-format = \hfil #1 \hfil, -%\end{verbatim} -% or -%\begin{verbatim} -% one-line-action = center, -%\end{verbatim} -% depending on how we intend to offer changing the behavior of the -% template. Like when trying to define sensible template types we have -% no single road to heaven (and probably as many to hell) --- it has a -% lot to do with how we think about design. -% -% My advice, after having tried to work with these concepts for a -% while, is to keep templates simple in so far as that most of not all -% attribute for a template should be relevant for the design. In other -% words, if you have attributes that, depending on their setting, make -% half of the other attributes not applicable then it may be -% appropriate to think about providing several templates instead. To -% give an example from \LaTeXe : instead of having |\@startsection| -% deal with both vertical heads and run-in heads provide individual -% templates. (|\@startsection| is this famous command where design -% switches are build in by making dimensions negative to signal -% something and afterwards use the absolute value.) -% Another way to look at this is to say that a template should -% normally not contain large amounts of code which is only selected in -% a subset of attribute settings. -% -% As said before there are no golden rules, it is perfectly possible -% to make hugely complicated templates that solve every possible -% aspect of layout one could think of in one go --- it is just that -% with keeping it more simple one can get the same functionality with -% less headaches for the template writer as well as the template user -% later on. -% -% Returning to our example: allowing to handle the case of a single -% line caption specially could well be considered part of the -% template. In contrast: layouts that would put the caption number -% sideways, i.e., which would need totally different internal coding -% should probably be coded as a separate template of type -% \texttt{caption}. -% -% So for our next example template we settle for the fixed caption -% text plus number (if any) being at the beginning of the variable -% caption text (coming from the document) and being together formatted -% as some sort of a pargraph. In case of the whole caption being a -% single line we allow the designer to specify how to lay it out -% (e.g., centered, flush left, etc.). If there is a legend it will get -% formatted by a vertical space followed by the legend formatted as -% another paragraph. -% -% More precisely we allow for the following bells and wistles: -%\begin{verbatim} -%\DeclareTemplate{caption}{lesssimple}{4} -% { -%\end{verbatim} -% The designer can specify the space above and below the caption like -% we did in our first example. -%\begin{verbatim} -% above-skip =L [0pt] \caption@above@skip , -% below-skip =L [0pt] \caption@below@skip , -%\end{verbatim} -% Regarding the caption number we support the case where no number is -% present (the value being |\NoValue|) as well as the number being -% present. For both cases the designer has to specify what formatting -% should be attached. By default all is being typeset in the font the -% whole caption is presented but if there is a need for it the -% designer can use the following keys to attach special formatting -% devices to each particular item beside specifying special spacing -% information or replacing the default colon after the number with -% something else. -%\begin{verbatim} -% number-format =f2 [#1~#2:~] \caption@number@format, -% nonumber-format =f1 [#1:~] \caption@nonumber@format, -%\end{verbatim} -% If the caption is fitting onto a single line we make it possible -% for the designer to specify how this single line should be -% positioned (the default is to center the line). -%\begin{verbatim} -% single-line-format =f1 [\hfil#1\hfil] \caption@single@line@format, -%\end{verbatim} -% The font for the caption (including the fixed text and the number -% unless specified differently above) is going to be the one decided -% by the next key. -%\begin{verbatim} -% caption-font =f0 [\normalfont] \caption@font, -%\end{verbatim} -% The next attribute deserves some extra explanation: here we make use -% of an interface which is explained in more detail when we reveil the -% support for galley formatting.\footnote{Guess I have to apologize -% for the fact that i partly make use of that interface in this -% example while on other occasions (like the use of vertical spacing) -% within the example I do not---consistency around midnight is not my -% strength I fear (FMi).} In a nutshell the template type \texttt{hj} -% (hyphenation \& justification) allows one to define a) the -% justification concepts applied to the upcoming paragraphs, e.g., -% whether they should be set flush left, adjusted, first line -% centered, etc.\ b) the linebreaking strategy used and c) the -% hyphenation rules which should apply. All this is done by selecting -% an appropriate (predefined) instance of this type as will hopefully -% become somewhat clearer in the example instances shown below. -%\begin{verbatim} -% caption-hj-setup =i {hj} [default] \caption@hj@instance, -%\end{verbatim} -% In case there is a legend to format we give the designer the -% possibility to specify by how much vertical space it should be -% separated from the preceding paragraph (i.e., the caption text). The -% attributes for font and hj setup are comparable to those for the -% caption text itself (except that they will only apply to the -% legend). The only addition is the key \texttt{legend-text} which is -% allowed to take a fixed text (plus any formating and spacing for it) -% which will be added to the front of the legend in case it is -% provided at all (by default it is empty). -%\begin{verbatim} -% legend-sep =L [0pt] \caption@legend@sep , -% legend-text =f0 [] \caption@legend@text, -% legend-font =f0 [\normalfont] \caption@legend@font, -% legend-hj-setup =i {hj} [default] \caption@legend@hj@instance, -% } -%\end{verbatim} -% The actual code for the template should hold few if any -% surprises. In fact it is more or less identical to the one of the -% first template example, except that now we have now taken out some -% of the hardwired decisions and placed them into attributes. -%\begin{verbatim} -% { -% \IfNoValueTF{#2} -% { \cs_set_nopar:Npn \caption@start{\caption@number@format{#1}{#2}} } -% { \cs_set_nopar:Npn \caption@start{\caption@nonumber@format{#1}} } -% \DoParameterAssigments -% \vskip \caption@above@skip \relax -%\end{verbatim} -% To properly measure the caption to determine if it fits a single -% line we have to set it in the right font, so here as well as below -% we have to apply |\caption@font|. -%\begin{verbatim} -% \sbox \@tempboxa {\caption@font \caption@start #3} -% \ifdim \wd\@tempboxa >\hsize -% \begingroup -% \caption@font \caption@hj@instance -% \caption@start #3\par -% \endgroup -% \else -% \global \@minipagefalse -% \hb@xt@\hsize{\caption@single@line@format{\box\@tempboxa}} -% \fi -%\end{verbatim} -% To decide whether or not we have to set any legend we have to test -% |#4| for being |\NoValue|. This part of the code was not present in -% the previous example but otherwise should be straight forward. -%\begin{verbatim} -% \IfNoValueF{#4} -% { -% \vskip \caption@legend@sep \relax -% \begingroup -% \caption@legend@font \caption@legend@hj@instance -% \caption@legend@text -% #4\par -% \endgroup -% } -% \vskip \caption@below@skip \relax -% } -%\end{verbatim} -% -% I wouldn't claim the the above template is good or contains -% everything that would be desired and I'm sure that in the end we -% will have several such template for typesetting the caption part and -% perhaps decide on a different template type in the first place. So -% this is only to give a glimpse of how the template interface could -% be applied and I hope that reading it can see a) how they can apply -% it to other areas as well as see what is wrong with the example -% itself. -% -% To just note one point that i thought of being wrong after writing -% the above paragraphs: the key \texttt{single-line-format} was -% declared to be a function with one argument with the idea that -% besides specifying the single line should be centered (|\hfil|) on -% both sides, or flush left, or flush right (|\hfil| on one side) one -% could also specify something like -%\begin{verbatim} -% single-line-format = \hspace{10pt}#1\hfil, -%\end{verbatim} -% that is a fixed indentation on the left in case where the caption is -% a single line. However, of course one can't. Or at least it is not -% safe to do so since our test in the code tests the width of the line -% without taking into account such a finite fixed space and guess what -% might happen? So in summary, flexibility needs some thought and -% often some afterthoughts as well --- happy thinking :-) -% -% -% -% \subsection{Defining a few instances} -% -% So let us conclude this example with a few sample instances. We -% start with one that repeats what current \LaTeXe{} provides in the -% article class. It shows all keys with values. However in fact only -% the first key is actually needed since all others are the same as -% the default values in the template (and of course a legend is not -% specifiable in standard \LaTeX{} coding so those settings simply do -% not apply anyway). -%\begin{verbatim} -%\DeclareInstance{caption}{article}{lesssimple} -% { -% above-skip = 10pt, -% below-skip = 0pt, -% number-format = #1~#2:~, -% nonumber-format = #1:~, -% single-line-format = \hfil#1\hfil, -% caption-font = \normalfont, -% caption-hj-setup = default, -% legend-sep = 0pt, -% legend-text = , -% legend-font = \normalfont, -% legend-hj-setup = default, -% } -%\end{verbatim} -% -% The next examples are taken from books on the shelf essentially a -% random selection I fear. This one is from \emph{Introduction to -% Database Design} by C.~J.~Date and it uses Helvetica for the caption -% text with the caption flush left, with the figure and the fixed -% string (e.g., `Fig.' in bold face) separated by a quad of space. No -% legend either so this is not set up. The \texttt{hj} instance -% \texttt{noindentflushleft} is supposed to produce a ragged right paragraph -% without any indentation. It would have to be set up elsewhere -% (instance to the template of type \texttt{hj}). -%\begin{verbatim} -%\DeclareInstance{caption}{DATE}{lesssimple} -% { -% above-skip = 10pt, -% below-skip = 0pt, -% number-format = \textbf{#1~#2}\quad, -% nonumber-format = \textbf{#1}\quad, -% single-line-format = #1\hfil, -% caption-font = \fontfamily{phv} \normalfont, -% caption-hj-setup = noindentflushleft, -% } -%\end{verbatim} -% -% The final example is from the book ``Methods of Book Design'' by -% H.~Williamson which sets the caption centered if it fits a single -% line but adjusted as a paragraph without any indentation if longer -% than a single line. It uses old style numerals followed by a period -% for the number (though the example isn't quite right as i guess the -% text font used already has oldstyle numerals as default, so -% |\oldstylenums| is in fact not necessary). -%\begin{verbatim} -%\DeclareInstance{caption}{WILLIAMSON}{lesssimple} -% { -% above-skip = 10pt, -% below-skip = 0pt, -% number-format = #1~\oldstylenums{#2}.~, -% nonumber-format = #1~, -% single-line-format = \hfil#1\hfil, -% caption-font = \normalfont, -% caption-hj-setup = noindentadjusted, -% } -%\end{verbatim} -% -% -% -% \section{Notes} -% -% \subsection{Note on multi-valued parameters} -% -% -% The following code\footnote{docu taken from trial implementation in -% xlists.dtx, FMi} implements for registers (ie L,l,C,c keys) and -% for names (ie n key) a multi-selection mechanism of the following -% form: -% \begin{verbatim} -% key = \MultiSelection \ListDepth { -% \DelayEvaluation {2.5em}, -% 20pt + 34pt } -% { \DelayEvaluation {1em} }, -% \end{verbatim} -% where the first argument to |\MultiSelection| is a counter, the -% second argument is a comma separated list of values denoting the -% values for the cases 1, 2,\ldots, and the third argument contains -% the value for all other cases. -% -% The values are evaluated at declaration time in case of registers -% and therefore can contain calc expressions as well as -% |\DelayEvaluation|. -% -% Due to the implementation the case list is not allowed to have a -% trailing comma! And of course no checks are made whatsoever :-( -% -% A probably much nicer syntax would be something like this: -% \begin{verbatim} -% key = \MultiSelection { -% selector = \ListDepth, -% 1 = \DelayEvaluation {2.5em}, -% 2 = 20pt + 34pt, -% else = \DelayEvaluation {1em} -% }, -% \end{verbatim} -% but i found that too difficult to implement right now. -% -% I think it should also be considered if this kind of thing should be -% a generally available feature on all key types especially on the -% f\meta{number} ones. -% -% Anyway it is what i need for lists right now and as such it is -% sufficient. -% -% -% \subsection{Notes on template restriction} -% -% Possible semantics: -% -% a: just:-) changes the defaults ie the new template has as -% defaults those of its source as modified by the supplied -% keyvals; -% -% b: similar to a: but also removes some keywords ie the new template -% will not accept the keywods whose values are set by the suppied -% keyvals; -% -% c: plan C. -% -% -% Towards an implementation of b: but without a restriction on what -% keys appear where. -% -% -% -% -% \subsection{Open issues} -% -% In this section unresolved issues or ideas to think about and -% perhaps implement are collected. There is no particular order to -% them. -% -% \begin{itemize} -% \item The order of arguments in |\UseCollection| is illogical in my -% eyes! A collection typically modifies the behavior of several -% types and thus should perhaps be first (as it is in the -% |\DeclareCollectionInstance| case). Or not, or what? -% -% \item How should |\IfExistsInstanceTF| behave for Collection -% instances? Do we need a special check for those or a default -% action? Or do we need an additional test for the existence of -% collection instances? -% -% \item It was suggested that the template type declaration should get -% another argument in which (in?)formally the semantics for the -% template types are described, e.g., data type of arguments, -% resulting output, \ldots{} (somewhat like the description arguments -% for functions and variables in Emacs-Lisp). The advantage being -% that this helps employing the templates better as well as perhaps -% guiding context sensitive editors to support the work with such -% templates (e.g., providing help texts). -% -% \item The same might be of interest for the keys of individual -% templates though here syntax support is already available to some -% extend by the declaration of key types. -% -% \item There might be a need to distinguish between \TeX's dimen and -% skip registers. Right now this is not done and both |l| and |L| -% accepts what \LaTeX{} calls ``rubber length'' specifications. -% -% \item The type |b| can probably vanish. It is equivalent to -% specifying the mutators of a |\newif| command in the brace groups, -% e.g. -%\begin{verbatim} -% numbered-boolean =b [true] @heading@nums, -% numbered-boolean =s [true] {\@heading@numstrue} -% {\@heading@numsfalse}, -%\end{verbatim} -% -% \item See issue raised about syntax (and semantics) for -% |\Multiselection|. -% -% \item |f0| keys should perhaps support |\UseTemplate| by replacing -% it with its internal form. or perhaps this is a rubbish idea? -% -% \item Marcin Wolinski suggested to use |\EvalOnUse| instead or in -% addition to |\DelayEvalutation|. -% -% \end{itemize} -% -% \StopEventually{} -% -% \section{Implementation} -% \begin{macrocode} -%<*package> -\ProvidesExplPackage - {\filename}{\filedate}{\fileversion}{\filedescription} -% \end{macrocode} -% -% \begin{macrocode} -\RequirePackage{expl3} -\RequirePackage{ldcsetup,xparse} -% \end{macrocode} -% -% -% Declare a private token register for building parameter lists. -% Having the number saves a few expandafters -% (probably not needed in the end). -% \begin{macrocode} -\toks_new:N\l_TP_KV_assignments_toks -\toks_new:N\l_TP_default_assignments_toks -% \end{macrocode} -% -% -% -% \begin{macro}{\TP_declare_instance:Nnn} -% \begin{macro}{\TP_declare_instance:cnn} -% Declare a command name to be an instance of a template -% ie with a particular setting of the parameters.\\ -% |#1| internal command name for instance to be (globally) declared\\ -% |#2| template type/template name\\ -% |#3| key value assignments for parameters of |#2| -% \begin{macrocode} -\cs_new_nopar:Nn \TP_declare_instance:Nnn { - \group_begin: - \TP_instdecl_generate_assignments:nn {#2}{#3} - \cs_gset_nopar:Npx #1 { - \tl_if_eq:cNTF { TP>/#2 } \c_TP_doparameterassignments_tl -% \end{macrocode} -% If the body of the template consists only of the token -% |\DoParameterAssignments|, then we insert the list of parameter -% assignments directly. Otherwise we have push them onto the stack -% and prepare to execute the body code (which in turn will pop them -% again when it reaches |\DoParameterAssignments| inside). -% \begin{macrocode} - { \toks_use:N \l_TP_KV_assignments_toks } - { - \exp_not:N \TP_push_assignments:n - {\toks_use:N\l_TP_KV_assignments_toks} - \exp_not:c {TP>/#2} - } - } - \group_end:} -\cs_generate_variant:Nn \TP_declare_instance:Nnn {cnn} -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\c_TP_doparameterassignments_tl} -% \begin{macrocode} -\tl_set:Nn \c_TP_doparameterassignments_tl {\DoParameterAssignments} -% \end{macrocode} -% \end{macro} -% -% -% \begin{macro}{\UseTemplate} -% |{type}{templatename}{keyval}| -% Directly use a template with a particular parameter setting. -% This is also picked up if used in a nested fashion inside a parameter -% list.\\ -% |#1| type of a template.\\ -% |#2| name of a template.\\ -% |#3| key value assignments for parameters of |#1|. -% \begin{macrocode} -\cs_new_nopar:Npn \UseTemplate #1#2#3{ - \TP_instdecl_generate_assignments:nn {#1/#2}{#3} - \TP_push_assignments: - \use:c { TP>/#1/#2 } -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\DoParameterAssignments} -% Access the parameter assignment list that was once stored in -% |\l_TP_KV_assignments_toks| and then moved onto the -% |\g_TP_assignments_stack_toks|. -% \begin{macrocode} -\cs_new_nopar:Npn \DoParameterAssignments{ - \exp_after:wN - \TP_pop_and_execute_assignments:nw - \toks_use:N \g_TP_assignments_stack_toks \q_stop -} -% \end{macrocode} -% -% \end{macro} -% -% \begin{macro}{\TP_pop_and_execute_assignments:nw} -% \begin{macrocode} -\cs_new_nopar:Npn \TP_pop_and_execute_assignments:nw#1#2\q_stop{ - \toks_gset:Nn \g_TP_assignments_stack_toks {#2} - #1} -% \end{macrocode} -% \end{macro} -% -% -% \begin{macro}{\g_TP_assignments_stack_toks} -% \begin{macrocode} -\toks_new:N \g_TP_assignments_stack_toks -\toks_gset:Nn \g_TP_assignments_stack_toks {\scan_stop:}% avoid brace loss -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\TP_push_assignments:n} -% \begin{macro}{\TP_push_assignments:} -% Push a list of parameter assignments onto the -% |\g_TP_assignments_stack_toks|. As it all happens in token -% registers |#|s need no doubling. |\TP_push_assignments:| expects -% it to be |\l_TP_KV_assignments_toks| (needs fixing). -% \begin{macrocode} -\cs_new:Npn \TP_push_assignments:n#1{ - \toks_gput_left:Nn\g_TP_assignments_stack_toks{{#1}} -} -\cs_new_nopar:Npn \TP_push_assignments:{ - \toks_gset:No \g_TP_assignments_stack_toks - {\exp_after:wN - {\toks_use:N\exp_after:wN\l_TP_KV_assignments_toks\exp_after:wN} - \toks_use:N\g_TP_assignments_stack_toks} -} -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% -% \begin{macro}{\DeclareTemplateType} -% |{type}{nofarg}| -% \begin{macrocode} -\cs_new_nopar:Npn \DeclareTemplateType #1#2{ - \tl_set:cn {TP@<#1>} {{}#2}} -% \end{macrocode} -% \end{macro} -% -% -% \begin{macro}{\TP_get_csname_prefix:n} -% |{type}| returns prefix for csnames for template type, -% based on current collection. -% \begin{macrocode} -\cs_new_nopar:Nn \TP_get_csname_prefix:n { - <\exp_after:wN\exp_after:wN\exp_after:wN - \use_i:nn - \cs:w TP@<#1>\cs_end:>#1/ -} -% \end{macrocode} -% -% \end{macro} -% -% \begin{macro}{\TP_get_arg_count:n} -% |{type}| returns arg count for the template type. -% \begin{macrocode} -\cs_new_nopar:Nn \TP_get_arg_count:n { - \exp_after:wN\exp_after:wN\exp_after:wN - \use_ii:nn - \cs:w TP@<#1>\cs_end: -} -% \end{macrocode} -% \end{macro} -% -% -% \begin{macro}{\DeclareTemplate} -% |{type}{templatename}{nofarg}{keywordspec}{code}| -% \begin{macrocode} -\cs_new:Npn\DeclareTemplate #1#2#3#4#5{ - \cs_if_free:cTF{TP@<#1>} - {\undefinedtype\DeclareTemplateType{#1}#3} - { - \intexpr_compare:nNnF{#3}={\TP_get_arg_count:n{#1}} - { \BadArgCount } - } -% \end{macrocode} -% Parse the key declaration, and execute the list with a suitable -% definition of |\KV@elt|. -% \begin{macrocode} - \cs_set_eq:NN \KV_elt:nn \TP_templdecl_process_KV:nn - \cs_set_nopar:Npn \KV_default_elt:n##1{ - \PackageError{template}{Missing~ =~ after~ ##1}\@ehd} - \cs_set_eq:NN\KV@elt\KV_elt:nn - \cs_set_eq:NN\KV@default@elt\KV_default_elt:n - \tl_set:Nn \l_TP_curr_name_tl {#1/#2} - \toks_clear:N\l_TP_default_assignments_toks -% \end{macrocode} -% At this point there should be a test for which catcode regime we are -% in. We just test if spaces are ignored. -% \begin{macrocode} - %\intexpr_compare:nNnTF{\char_value_catcode:n{`\ }}=\c_nine - %\KV_parse_picky_no_space_removal_no_sanitize:n - %\KV_parse_picky_space_removal_no_sanitize:n - \KV@parse{#4} -% \end{macrocode} -% -% Define the defaults: the setting for |TPD>/\l_TP_curr_name_tl| is a -% tricky since |\l_TP_default_assignments_toks| may contain |#|. We -% have to use an |x| expansion rather than -% |o| since that will hide those during the assignment. -% FIX THIS (see below)! -% \begin{macrocode} - \cs_set_nopar:cpx { TPD>/\l_TP_curr_name_tl } - {\toks_use:N\l_TP_default_assignments_toks} - - \tl_clear:c {TPR>/\l_TP_curr_name_tl} - - \tl_set_eq:cN {TPO>/\l_TP_curr_name_tl}\l_TP_curr_name_tl -% \end{macrocode} -% -% Define the template (using |\cs_new_nopar:Npn| means that one can't -% redefine a template easily). -% \begin{macrocode} - \cs_generate_from_arg_count:cNnn {TP>/\l_TP_curr_name_tl} - \cs_set:Npn {#3}{#5} -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\tl_set:cx} -% FIX this: The code above only works because in the past |\tl_set:cx| was -% defined as follows: -% \begin{macrocode} -\cs_set:Npn \tl_set:cx {\exp_args:Nc \tl_set:Nx} -% \end{macrocode} -% i.e., expanding the second arg at the very end. -% This is no longer the case but for the moment I revert to the old -% definition until the template code is fixed to not rely on |\tl_set:cx| -% expanding the second arg at the very last minute. -% \end{macro} -% -% \begin{macro}{\TP_templdecl_process_KV:nn} -% The list of undefined keys and values is put in the list of the form\\ -% |\KV_elt:nn|\marg{key1}\marg{val1}%^^A -% |\KV_elt:nn|\marg{key2}\marg{val2}\ldots\\ -% So just need to give this macro a suitable definition. We just need -% to look at the first token of the value, to see what sort of key -% it is, so call a helper function to split that off. -% \begin{macrocode} -\cs_new_nopar:Nn \TP_templdecl_process_KV:nn {% - \cs_set_eq:NN \TP_templdecl_add_global_or_nothing: \prg_do_nothing: - \bool_set_false:N\l_TP_global_assignment_bool - \tl_set:Nn\l_TP_currkey_tl{#1} - \TP_templdecl_parse_KV:N#2\q_stop} -% \end{macrocode} -% \end{macro} -% -% -% -% \begin{macro}{\TP_templdecl_parse_KV:N} -% Case switch on the possible key types. -% \begin{macrocode} -\cs_new_nopar:Nn \TP_templdecl_parse_KV:N { -% \end{macrocode} -% In |#1| we have key, in |#2| the first character after the equal -% sign and in |#3| the remainder of the line. We now have to parse -% that remainder to find out if it contains a default value (in -% brackets) and then set up the key declaration needed to parse -% instance declarations. The method is similar in most cases: we call -% |\TP_parse_optional_key_default:nw| which parses for the default -% and pass it already found key name as first argument, what to do in -% the end as second argument, and the remainder delimited by |\q_stop| -% so that it becomes parseable. -% -% Note that the code in the second argument to -% |\TP_parse_optional_key_default:nw| normally calls on a macro with -% one more argument than actually provided: the reason being that the -% missing argument will be the remainder of the line (added by -% |\TP_parse_optional_key_default:nw| after the default has be -% removed (if present)). -% \begin{macrocode} - \cs_if_free:cTF{TP_use_arg_type_#1:w} - {\PackageError{template}{Unknown~key~type~ (#1)~for~\l_TP_currkey_tl}\@eha} - {\use:c{TP_use_arg_type_#1:w}} -% \end{macrocode} -% The |f| and |i| keys are somewhat different since there we first -% have to parse for an additional argument (a digit in case of |f| -% or an template type name in case of |i|): -% \begin{macrocode} -% \end{macrocode} -% One more alternative: a |+| after the equal sign signals global -% so we change |\TP_templdecl_add_global_or_nothing:| to append a -% |\pref_global:D| to the assignment toks and then reparse the rest. -% \begin{macrocode} -% \cs_set_nopar:Npn \TP_templdecl_add_global_or_nothing: -% {\toks_put_right:Nn \l_TP_KV_assignments_toks {\pref_global:D} } -% \TP_templdecl_parse_KV:nw{#1}#3\TP_templdecl_parse_KV:nnw -} -% \end{macrocode} -% \end{macro} -% -% -% \begin{macro}{\l_TP_global_assignment_bool} -% For keeping track of the assignments. -% \begin{macrocode} -\bool_new:N \l_TP_global_assignment_bool -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\TP_use_arg_type_+:w} -% The |+| does two things: Sets a boolean true to be used by the -% types that can't simply be prefixed with |\pref_global:D| and -% defines |\TP_templdecl_add_global_or_nothing:| to put the prefix -% onto the list. After that we simply call the big switch -% again.\footnote{It should probably all be changed to not rely on -% the prefix working}. -% \begin{macrocode} -\cs_new_nopar:cpn{TP_use_arg_type_+:w} { - \bool_set_true:N\l_TP_global_assignment_bool - \cs_set_nopar:Npn \TP_templdecl_add_global_or_nothing: - {\toks_put_right:Nn \l_TP_KV_assignments_toks {\pref_global:D} } - \TP_templdecl_parse_KV:N -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\TP_use_arg_type_l:w} -% The |l| sets a length register. We disable the prefix and insert -% either |\gsetlength| or |\setlength| depending on whether a |+| -% was seen or not. -% \begin{macrocode} -\cs_new_nopar:Npn\TP_use_arg_type_l:w { - \TP_parse_optional_key_default:nw - { - \cs_set_eq:NN \TP_templdecl_add_global_or_nothing: \prg_do_nothing: - \bool_if:NTF \l_TP_global_assignment_bool - {\TP_templdecl_setup_register_key:Nn\gsetlength} - {\TP_templdecl_setup_register_key:Nn\setlength} - } -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\TP_use_arg_type_L:w} -% The |L| sets a fake length register. -% \begin{macrocode} -\cs_new_nopar:Npn\TP_use_arg_type_L:w { - \TP_parse_optional_key_default:nw - {\TP_templdecl_setup_fakeregister_key:NNn\setlength\l_tmpa_skip} -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\TP_use_arg_type_c:w} -% The |c| sets a count register. -% \begin{macrocode} -\cs_new_nopar:Npn\TP_use_arg_type_c:w { - \TP_parse_optional_key_default:nw - { - \cs_set_eq:NN\TP_templdecl_add_global_or_nothing:\prg_do_nothing: - \bool_if:NTF \l_TP_global_assignment_bool - {\TP_templdecl_setup_register_key:Nn\GSetInternalCounter} - {\TP_templdecl_setup_register_key:Nn\SetInternalCounter} - } -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\TP_use_arg_type_C:w} -% The |C| sets a fake count register. -% \begin{macrocode} -\cs_new_nopar:Npn\TP_use_arg_type_C:w { - \TP_parse_optional_key_default:nw - {\TP_templdecl_setup_fakeregister_key:NNn - \SetInternalCounter\l_tmpa_int} -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\TP_use_arg_type_n:w} -% The |n| sets a token list variable. -% \begin{macrocode} -\cs_new_nopar:Npn\TP_use_arg_type_n:w { - \TP_parse_optional_key_default:nw - {\TP_templdecl_setup_n_key:N} -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\TP_use_arg_type_f:w} -% \begin{macro}{\TP_templdecl_parse_f_arg:nw} -% The |f| defines a command with between 0 and 9 arguments. -% \begin{macrocode} -\cs_new_nopar:Npn\TP_use_arg_type_f:w #1{ - %\TP_templdecl_parse_f_arg:nw {#1} - \TP_parse_optional_key_default:nw{\TP_templdecl_setup_f_key:Nn{#1}} -} -% \end{macrocode} -% Helper for |\TP_templdecl_parse_KV:nnw|. -% \begin{macrocode} -\cs_new_nopar:Npn \TP_templdecl_parse_f_arg:nw#1#2{ -% \end{macrocode} -% The third argument of |\TP_templdecl_setup_f_key:Nn|, i.e., the -% macro name, is the remaining data up to |\q_stop| which is picked up -% by |\TP_parse_optional_key_default:nw|. -% \begin{macrocode} - \TP_parse_optional_key_default:nw{\TP_templdecl_setup_f_key:Nn{#1}{#2}} -} -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% -% \begin{macro}{\TP_use_arg_type_b:w} -% \begin{macro}{\TP_templdecl_setup_b_key:nn} -% The |b| uses access to the |\if_true:| and |\if_false:| -% primitives. Needed? -% \begin{macrocode} -\cs_new_nopar:Npn\TP_use_arg_type_b:w { - \TP_parse_optional_key_default:nw - {\TP_templdecl_setup_b_key:n} -} -% \end{macrocode} -% -% \begin{macrocode} -\cs_new_nopar:Npn \TP_templdecl_setup_b_key:n#1{ - \cs_set_eq:cN { if#1 } \if_true: - \TP_templdecl_define_key:n - { \TP_templdecl_eval_b_key_value:nn {#1}{##1} } -} -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\TP_templdecl_eval_b_key_value:nn} -% Modify so the boolean does not need to have been -% declared with |\newif| -% \begin{macrocode} -\cs_new_nopar:Npn \TP_templdecl_eval_b_key_value:nn#1#2{ - \cs_if_free:cTF {if#2} - { \PackageError{template}{Bad~boolean~setting~#1=#2}\@eha } - { \tl_set_eq:cc {if_#1:}{if_#2:} - \toks_put_right:Nf \l_TP_KV_assignments_toks - { \tl_set_eq:cc {if_#1:}{if_#2:} } - } -} -% \end{macrocode} -% -% \end{macro} -% -% \begin{macro}{\TP_use_arg_type_s:w} -% \begin{macro}{\TP_templdecl_setup_s_key:n} -% The |s| chooses between true and false. -% \begin{macrocode} -\cs_new_nopar:Npn\TP_use_arg_type_s:w { - \TP_parse_optional_key_default:nw - {\TP_templdecl_setup_s_key:n} -} -% \end{macrocode} -% \begin{macrocode} -\cs_new_nopar:Npn \TP_templdecl_setup_s_key:n #1 { - \TP_templdecl_define_key:n - { \TP_templdecl_eval_s_key_value:nnn{##1}#1 } -} -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% -% -% -% -% -% -% \begin{macro}{\TP_use_arg_type_i:w} -% The |i| expects an instance. -% \begin{macrocode} -\cs_new_nopar:Npn\TP_use_arg_type_i:w #1{ - \TP_parse_optional_key_default:nw{\TP_templdecl_setup_i_key:nnn{#1}} -} -% \end{macrocode} -% -% declaration |hd =i{head} \fooo| \\ -% use |hd = mine|\\ -% makes |\fooo| shorthand for |\UseInstance{head}{mine}| -% -% also allowed: |hd = \UseTemplate{head}{...}{...}|\\ -% in case you want to use an unnamed instance of type |head| -% in this place. -% \end{macro} -% -% \begin{macro}{\TP_templdecl_setup_i_key:nnn} -% MH change: do either local or global. -% \begin{macrocode} -\cs_new_nopar:Npn \TP_templdecl_setup_i_key:nnn#1#2{ - \TP_templdecl_define_key:n - { - \TP_templdecl_eval_i_key_value:Nnn #2 {#1}{##1} - } -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\TP_templdecl_eval_i_key_value:Nnn} -% MH change: Add extra argument for local or global. -% \begin{macrocode} -\cs_new_nopar:Npn \TP_templdecl_eval_i_key_value:Nnn #1#2#3 { - \tl_if_head_eq_meaning:nNTF {#3.}\UseTemplate - { - \iow_term:x{\token_to_str:N\UseTemplate\space seen} -% \end{macrocode} -% -% Code below from |\TP_templdecl_setup_f_key:Nn| (should be -% combined and cleaned up) -% at this point one should also check if first arg of |\UseTemplate| -% corresponds to |#2| and if not complain (not done) -% -% \begin{macrocode} - {\TP_templdecl_declare_tmp_instance:nnnn #3 } - \toks_put_right:No \l_TP_KV_assignments_toks - { \exp_after:wN \KV@toks \exp_after:wN {\g_tmpa_tl} } - %\TP_templdecl_add_global_or_nothing: - %\toks_put_right:Nn \l_TP_KV_assignments_toks - % { \cs_set_nopar:Npx #1{ \toks_use:N \KV@toks} } - \bool_if:NTF \l_TP_global_assignment_bool - {\toks_put_right:Nn \l_TP_KV_assignments_toks - {\cs_gset_nopar:Npx #1 { \toks_use:N \KV@toks}} - } - {\toks_put_right:Nn \l_TP_KV_assignments_toks - {\cs_set_nopar:Npx #1 { \toks_use:N \KV@toks}} - } - } - { - \TP_let_instance:Nnn#1{#2}{#3} -% \end{macrocode} -% We want the |\cs_set_eq:Nc| hiding in |\TP_let_instance:Nnn| to expand -% fully to two csnames so we put a |\tex_romannumeral:D 0| (which in -% itself expands to nothing) in front. This expands the |\cs_set_eq:Nc| fully -% before finding out that |\cs_set_eq:NwN| is not expandable. -% \begin{macrocode} - \toks_put_right:Nf \l_TP_KV_assignments_toks - { \TP_let_instance:Nnn#1{#2}{#3} } - } -} -% \end{macrocode} -% \end{macro} -% -% -% -% -% -% -% -% -% \begin{macro}{\TP_use_arg_type_x:w} -% \begin{macro}{\TP_templdecl_setup_x_key:nn} -% The |x| runs internal code. -% \begin{macrocode} -\cs_new_nopar:Npn\TP_use_arg_type_x:w { - \TP_parse_optional_key_default:nw - {\TP_templdecl_setup_x_key:n} -} -% \end{macrocode} -% -% \begin{macrocode} -\cs_new_nopar:Npn \TP_templdecl_setup_x_key:n#1{ - \TP_templdecl_define_key:n - { \toks_put_right:Nn\l_TP_KV_assignments_toks{#1} } -} -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% -% -% -% -% \begin{macro}{\TP_use_arg_type_g:w} -% \begin{macro}{\TP_templdecl_setup_g_key:nn} -% The |g| runs any code. -% \begin{macrocode} -\cs_new_nopar:Npn\TP_use_arg_type_g:w { - \TP_parse_optional_key_default:nw - {\TP_templdecl_setup_g_key:n} -} -% \end{macrocode} -% -% \begin{macrocode} -\cs_new_nopar:Npn \TP_templdecl_setup_g_key:n #1 { - \TP_templdecl_define_key:n{#1}} -% \end{macrocode} -% -% \end{macro} -% \end{macro} -% -% -% -% -% \begin{macro}{\TP_templdecl_define_key:n} -% Here we define the key in the current template. Original code from -% r522 is essentially unreadable but we keep it here until the -% internal structure is finally sorted out. -% \begin{macrocode} -\cs_new_nopar:Npn \TP_templdecl_define_key:n#1{ - \exp_after:wN \cs_set:Npn \cs:w - KV@\l_TP_curr_name_tl @\l_TP_currkey_tl - \exp_after:wN\cs_end: - \exp_after:wN##\exp_after:wN1\exp_after:wN{ - \exp_after:wN\TP_templdecl_remove_from_default_assignments:N - \cs:w KV@\l_TP_curr_name_tl @\l_TP_currkey_tl - \exp_after:wN \cs_end: - \TP_templdecl_add_global_or_nothing: - #1 - } -} -% \end{macrocode} -% \end{macro} -% -% -% -% -% -% -% -% -% -% -% \begin{macro}{\TP_parse_optional_key_default:nw} -% Look for default value. The |t| argument type here is one we -% define for template so we can change it easily. Currently I just -% set it to be a regular optional argument in brackets. |#1| is what -% we are carrying over, |#2| the optional argument. -% \begin{macrocode} -\cs_set:Npn \TP_ignore_leading_space_in_arg_ii:nn#1#2{ - \exp_args:Nf\TP_ignore_leading_space_in_arg_ii_aux:nn - {\exp_not:N #2}{#1} -} -\cs_set:Npn \TP_ignore_leading_space_in_arg_ii_aux:nn#1#2{#2{#1}} - - -\DeclareArgumentType t[{meaning}{}{\NoValue}{#1[#2]}{#2} -\DeclareDocumentCommand\TP_parse_optional_key_default:nw{mt}{ - \IfNoValueTF{#2} - {\TP_templdecl_finish_key_setup:nw{#1}} - {\TP_templdecl_finish_key_setup_with_default:nnw{#1}{#2}} -} -%\show\TP_parse_optional_key_default:nw -%\exp_args:Nc\show{\string\TP_parse_optional_key_default:nw} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\TP_templdecl_finish_key_setup:nw} -% After having parsed the line and not found any default value it -% remains to actually define the key for the instance parsing by -% executing the setup code (in |#1|) giving it |#2| (i.e., the -% remainder of the line) as an argument. -% \begin{macrocode} -\cs_new_nopar:Npn \TP_templdecl_finish_key_setup:nw#1#2\q_stop{ - \TP_ignore_leading_space_in_arg_ii:nn{#1}{#2} - %%%#1{#2} -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\TP_templdecl_finish_key_setup_with_default:nnw} -% If there is a default the situation is more complicated since we -% not only have to set up the key for the instance but also have to -% add the default value to |\l_TP_default_assignments_toks| in an -% appropriate way. -% -% First set up the the key itself: -% \begin{macrocode} -\cs_new_nopar:Npn \TP_templdecl_finish_key_setup_with_default:nnw#1#2#3\q_stop{ - \TP_ignore_leading_space_in_arg_ii:nn{#1}{#3} - %%% #1 {#3} -% \end{macrocode} -% Now we run the new key code (which is stored in |\KV@...| hopefully) -% and give it the default found. By doing this in a group and by -% locally emptying |\l_TP_KV_assignments_toks| we will get the -% resulting assignment code into that register. -% -% (We set |\TP_templdecl_remove_from_default_assignments:N| to -% |\use_none:n| since this is a temporary operation and we don't want -% to change the default really.) -% \begin{macrocode} - \group_begin: - \toks_clear:N \l_TP_KV_assignments_toks - \cs_set_eq:NN \TP_templdecl_remove_from_default_assignments:N \use_none:n - \use:c{KV@\l_TP_curr_name_tl @\l_TP_currkey_tl}{#2} -% \end{macrocode} -% And now for a final trick: before closing the group again and losing -% our local changes we run |\exp_after:wN| several times to get the -% value of |\l_TP_KV_assignments_toks| into -% |\l_TP_default_assignments_toks| outside that group! -% \begin{macrocode} - \exp_after:wN - \group_end: - \exp_after:wN - \toks_set:Nn - \exp_after:wN - \l_TP_default_assignments_toks - \exp_after:wN - { \cs:w KV@\l_TP_curr_name_tl @\l_TP_currkey_tl \exp_after:wN \cs_end: - \exp_after:wN - { \toks_use:N \exp_after:wN \l_TP_KV_assignments_toks - \exp_after:wN - } - \toks_use:N\l_TP_default_assignments_toks - } -} -% \end{macrocode} -% \end{macro} -% -% -% -% \begin{macro}{\c_TP_true_tl} -% \begin{macrocode} -\tl_new:Nn \c_TP_true_tl {true} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\TP_templdecl_eval_s_key_value:nnn} -% \begin{macrocode} -\cs_new_nopar:Npn \TP_templdecl_eval_s_key_value:nnn#1#2#3 { -% no error check on this yet. - \tl_set:Nn \l_tmpa_tl {#1} - \tl_if_eq:NNTF \l_tmpa_tl \c_TP_true_tl - { \toks_put_right:Nn \l_TP_KV_assignments_toks {#2} } - { \toks_put_right:Nn \l_TP_KV_assignments_toks {#3} } -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\TP_templdecl_setup_register_key:Nnn} -% This is normally called automatically by |\DeclareTemplate|. -% -% Command for setting a template attribute whose name -% corresponds directly to a \TeX{} count or length register\\ -% |#1| the function to set the value eg \cs{setlength}.\\ -% |#2| key name.\\ -% |#3| the register to set. -% -% This command \emph{fully evaluates} the argument at declare time, -% and assigns the value to the register. It also passes an assignment -% of the register to the final value into the parameter list for the -% template. -% -% If the value is a call to |\DelayEvaluation|, don't evaluate it now, -% just pass the whole assignment to the template. Remember to remove -% the |\DelayEvaluation|. -% \begin{macrocode} -\cs_new_nopar:Npn \TP_templdecl_setup_register_key:Nn #1#2{ - \TP_templdecl_define_key:n{ - \tl_if_head_eq_meaning:nNTF{##1}\DelayEvaluation - { -% \end{macrocode} -% Old line commented out. Remove |\DelayEvaluation| and also remove -% the braces surrounding its argument. -% \begin{macrocode} - \toks_put_right:Nn \l_TP_KV_assignments_toks {#1#2{##1}} - %\toks_set:No\l_tmpa_toks{\use_ii:nn ##1} - %\toks_put_right:Nx \l_TP_KV_assignments_toks - % {\exp_not:n{#1#2}{\toks_use:N \l_tmpa_toks}} - } -% \end{macrocode} -% -% -% check for |\MultiSelection| creeping up and if so add something like -% -% \begin{verbatim} -% \setlength\register{\ifcase\selector \or value1 \or value2 -% ... \else valueotherwise \fi} -% \end{verbatim} -% to |\l_TP_KV_assignments_toks|. -% -% \begin{macrocode} - { - \tl_if_head_eq_meaning:nNTF{##1..}\MultiSelection - { - \group_begin: - \TP_multiselection_add:nnnnnn #1#2##1 - \group_end: -% \end{macrocode} -% -% -% there are probably better ways to do this (:-) -% -% \begin{macrocode} - \tl_if_in:onTF{\toks_use:N\g_TP_multiselection_toks}\DelayEvaluation - { - \toks_put_right:No\l_TP_KV_assignments_toks - { - \exp_after:wN#1\exp_after:wN#2\exp_after:wN - {\toks_use:N\g_TP_multiselection_toks} - } - } - { - \toks_put_right:No\l_TP_KV_assignments_toks - { - \exp_after:wN #2 - \exp_after:wN= \toks_use:N\g_TP_multiselection_toks\scan_stop: - } - } -% \end{macrocode} -% -% -% otherwise do as before -% -% \begin{macrocode} - } - { - #1#2{##1} - \toks_put_right:No\l_TP_KV_assignments_toks { - \exp_after:wN #2 \exp_after:wN = \tex_the:D #2\scan_stop: - } - } - } - } -} -% \end{macrocode} -% \end{macro} -% -% -% -% -% -% -% \begin{macro}{\DelayEvaluation} -% \begin{macro}{\MultiSelection} -% Since we are testing explicitly for |\DelayEvaluation| and -% |\MultiSelection| a few places we better give them unique -% meanings! -% \begin{macrocode} -\cs_new_nopar:Npn\DelayEvaluation #1{\use_none:n{\DelayEvaluation}#1} -\cs_new_nopar:Npn\MultiSelection #1{\use_none:n{\MultiSelection}#1} -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\TP_templdecl_remove_from_default_assignments:N} -% Note: the toks register is more or less a plists and should -% perhaps be implemented as such as this would make far more -% readable code. -% \begin{macrocode} -\cs_new_nopar:Npn \TP_templdecl_remove_from_default_assignments:N#1{ - \cs_set_nopar:Npn \TP_tmp:w ##1#1##2##3#1##4\q_stop{ - \l_TP_default_assignments_toks{##1##3} - } - \exp_after:wN \TP_tmp:w - \toks_use:N\l_TP_default_assignments_toks #1\scan_stop:#1\q_stop} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\TP_templdecl_setup_f_key:Nn} -% Same for macro names. Again usually called automatically when -% declaring a new template.\\ -% |#1| Determines how many arguments the function should have.\\ -% |#2| The macro to be defined. -% -% If the `|##1|`, the value passed as the argument of the key -% to the macro |#2| is invoked starts with |\FunctionInstance|, then a -% special procedure is taken. Instead of defining a macro with the -% specified number of arguments, the paramater list of the nested -% function instance is parsed, and |#2| is defined to be a macro -% expanding to that instance. In this case the specified template -% is responsible for picking up the requested number of -% arguments. (This is \emph{not} checked.) -% \begin{macrocode} -\cs_new_nopar:Npn \TP_templdecl_setup_f_key:Nn#1#2{ -% \end{macrocode} -% -% |##1| can either be arbitrary inline code, in which case it will be -% defined with something similar to |\newcommand[val]| so it needs to -% use |#1| -- |#val|. -% -% define it locally here (why this, David???) -% \begin{macrocode} - \TP_templdecl_define_key:n - { \TP_templdecl_define_function:NNn#1#2{##1} } -} -% \end{macrocode} -% \end{macro} -% -% -% \begin{macro}{\TP_templdecl_define_function:NNn} -% Use number of arguments to define function. -% \begin{macrocode} -\cs_new_nopar:Npn \TP_templdecl_define_function:NNn#1#2#3{ - \cs_generate_from_arg_count:NNnn #2 \cs_set:Npn {#1}{#3} - \toks_put_right:Nf \l_TP_KV_assignments_toks { - \cs_generate_from_arg_count:NNnn #2 \cs_set:Npn {#1}{#3} - } -} -% \end{macrocode} -% \end{macro} -% -% -% -% \begin{macro}{\TP_templdecl_setup_n_key:N} -% Here is the extended version that tries to deal with -% |\MultiSelection|. -% -% In case of `n' keys there is no evaluation at declaration time so it -% is not sensible to look for |\DelayEvaluation|. For this reason as -% well as for the fact that |\TP_multiselection_add:nnnnnn| above -% assumes that it deals -% with registers that can be accessed via |\toks_use:N| we have to use a -% different command to handle the |\MultiSelection| args but -% it is essentially doing the same. -% -% \begin{macrocode} -\cs_new_nopar:Npn \TP_templdecl_setup_n_key:N#1{ - \TP_templdecl_define_key:n{ - \tl_if_head_eq_meaning:nNTF{##1..}\MultiSelection - { - \group_begin: - \TP_templdecl_multiselection:nnnn ##1 - \group_end: -% \end{macrocode} -% Extracting the correct item from the |\if_case:w| we are building -% requires a bit of care. Firstly we want to expand the appropirate -% number of times to get to the item but we also want to ensure we do -% not have any unwanted leftover |\fi:|s or other junk which is bound -% to cause errors later on. Therefore we start an |f| expansion (so we -% don't have to count |\exp_after:wN|s and then stop it again when we -% want to. -% \begin{macrocode} - \toks_put_right:Nx\l_TP_KV_assignments_toks { - \exp_not:n{\tl_set:Nf #1} { \toks_use:N \g_TP_multiselection_toks} - } - } - { - \cs_set_nopar:Npn #1{##1} % setting it? - \toks_put_right:Nn \l_TP_KV_assignments_toks - { \tl_set:Nn #1{##1} } - } - } -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\TP_templdecl_multiselection:nnnn} -% Start the |\if_case:w|. When the item is retrieved using an |f| -% type expansion we better stop it at the right place once we have -% emerged on the other side of the conditional. -% \begin{macrocode} -\cs_new_nopar:Npn \TP_templdecl_multiselection:nnnn #1#2#3#4{ - \toks_gset:Nn \g_TP_multiselection_toks {\if_case:w #2} - \clist_map_inline:nn {#3}{ - \TP_multiselection_add_or_case:n {\exp_stop_f:##1} - } - \toks_gput_right:Nn\g_TP_multiselection_toks { - \else: \use_i_after_fi:nw { \exp_stop_f: #4} \fi: - } -} -% \end{macrocode} -% \end{macro} -% -% -% -% -% -% -% -% -% \begin{macro}{\DeclareInstance} -% |{type}{instname}{templatename}{keyval}| -% \begin{macrocode} -\cs_new_nopar:Npn \DeclareInstance { \DeclareCollectionInstance{} } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\DeclareCollectionInstance} -% |{collection}{type}{instname}{templatename}{keyval}| -% The fifth argument is picked up implicitly. -% \begin{macrocode} -\cs_new:Npn \DeclareCollectionInstance#1#2#3#4{ - \TP_declare_instance:cnn { <#1>#2/#3 }{ #2/#4 } -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\UseCollection} -% |{type}{collection}| -% \begin{macrocode} -\cs_new_nopar:Npn \UseCollection#1#2{ - \tl_set:cx { TP@<#1> } - { {#2} \TP_get_arg_count:n{#1} } -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\TP_let_instance:Nnn} -% |\internalcommand{type}{instname}| -% -% The way this macro is used, it must result in |\cs_set_eq:NwN| || -% || after exactly two expansions as it is used this way -% in |\TP_templdecl_eval_i_key_value:nnn|! -% \begin{macrocode} -\cs_new_nopar:Npn \TP_let_instance:Nnn#1#2#3{ - \cs_set_eq:Nc #1 - { - \cs_if_free:cTF { \TP_get_csname_prefix:n{#2} #3 } - { <>#2/ } - { \TP_get_csname_prefix:n{#2} } - #3 - } -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\UseInstance} -% |{type}{instname}| -% \begin{macrocode} -\cs_new_nopar:Npn \UseInstance#1#2{ - \TP_let_instance:Nnn \l_tmpa_tl {#1}{#2} - \tl_if_eq:NNTF \l_tmpa_tl \scan_stop: - \INSTANCEundefined - \l_tmpa_tl -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\TP_templdecl_declare_tmp_instance:nnnn} -% This macro is called when we have seen a |\UseTemplate| -% declaration as part of an |i| key value. Therefore the -% first argument will be dropped (it contains the token -% |\UseTemplate|) the second and third will be combined to refer to -% the template and the fourth argument will be implictly picked up -% by |\TP_declare_instance:Nnn|. -% \begin{macrocode} -\cs_new:Npn \TP_templdecl_declare_tmp_instance:nnnn#1#2#3{% - \TP_declare_instance:Nnn \g_tmpa_tl {#2/#3} } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\ShowTemplate} -% Some extension to |\ShowTemplate| so that we also get to see the -% restrictions if any -% \begin{macrocode} -\cs_new_nopar:Npn \ShowTemplate#1#2{ - \iow_term:x{*******~ Template:~ #1/#2~ *******} - \iow_term:x{*} - \iow_term:x{*~ Defaults:} - \iow_term:x{*} - \iow_term:x{\token_to_str:N\TPD>/#1/#2= - \cs_meaning:c{TPD>/#1/#2}} - \iow_term:x{*} - \iow_term:x{*~ Restrictions:} - \iow_term:x{*} - \iow_term:x{\token_to_str:N\TPR>/#1/#2= - \cs_meaning:c{TPR>/#1/#2}} - \iow_term:x{*} - \iow_term:x{*~ Body:} - \iow_term:x{*} - \cs_show:c {TP>/#1/#2}} -% \end{macrocode} -% \end{macro} -% -% -% \begin{macro}{\ShowCollectionInstance} -% \begin{macrocode} -\cs_new_nopar:Npn \ShowCollectionInstance#1#2#3{ - \iow_term:x{*******~ Instance:~ <#1>#2/#3~ *******} - \iow_term:x{*} - \cs_show:c {<#1>#2/#3}} -\cs_new_nopar:Npn \ShowInstance{\ShowCollectionInstance{}} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\TP_templdecl_setup_fakeregister_key:NNn} -% |{setcomand}{privateregister}{key}{internalcode}| -% \begin{macrocode} -\cs_new_nopar:Npn \TP_templdecl_setup_fakeregister_key:NNn#1#2#3{ - \TP_templdecl_define_key:n{ - \tl_if_head_eq_meaning:nNTF{##1..}\DelayEvaluation - { -% \end{macrocode} -% In the v0.08 version of \texttt{template.dtx} a -% |\DelayEvaluation| for a faked register would simply be equiv to -% a |\cs_set_nopar:Npn | (code is below commented out). The negative side effect -% of this is that something like |=L| used with |\DelayEvaluation| -% would not allow for calc syntax since it would end up as -% |\cs_set_nopar:Npn |\allowbreak|\foo|\allowbreak|{a+b}|. The code below changes -% this to first assign to a scratch register (at runtime) and then -% do an |\edef|. Could be coded differently to save space (at cost -% of time) -% \begin{macrocode} -% \toks_put_right:Nn \l_TP_KV_assignments_toks {\cs_set_nopar:Npn #3{##1}} -% \toks_put_right:Nn \l_TP_KV_assignments_toks -% {#1#2{##1}\cs_set_nopar:Npx #3{\toks_use:N#2}} - \toks_set:No \l_tmpa_toks {\use_ii:nn ##1} - \toks_put_right:Nx \l_TP_KV_assignments_toks { - \exp_not:n{#1#2}{\toks_use:N \l_tmpa_toks} - \exp_not:n{ \cs_set_nopar:Npx #3{\toks_use:N#2} } - - } - } -% \end{macrocode} -% -% -% Otherwise same game for fake registers except that instead of -% passing the register to |\TP_multiselection_add:nnnnnn| we pass a -% temp fake one and -% doing a def instead of using |\setlength| or |\setcounter| -% -% and i haven't done the |\DelayEvaluation| bit for that case! as -% i'm not sure what the best approach is for those -% things\footnote{we might disallow it for that case in general --- -% not a nice rule but an explainable one} -% -% \begin{macrocode} - { - \tl_if_head_eq_meaning:nNTF{##1..}\MultiSelection - { - \group_begin: - \TP_multiselection_add:nnnnnn#1#2##1 - \group_end: - \toks_put_right:Nx\l_TP_KV_assignments_toks - {\exp_not:n{\cs_set_nopar:Npn #3} {\toks_use:N\g_TP_multiselection_toks}} - } - { - #1#2{##1} - \toks_put_right:Nx\l_TP_KV_assignments_toks - {\exp_not:n{\cs_set_nopar:Npn#3} {\toks_use:N#2}} - } - } - } -} -% \end{macrocode} -% \end{macro} -% -% -% \begin{macro}{\g_TP_multiselection_toks} -% \begin{macrocode} -\toks_new:N \g_TP_multiselection_toks -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\TP_multiselection_add:nnnnnn} -% \marg{operation} \marg{register} |\MultiSelection| -% \marg{selector} \marg{case-list} \marg{else-case} -% -% This command builds up the |\if_case:w| code from the three -% arguments of |\MultiSelection| and stores it in -% |\g_TP_multiselection_toks|. This code is supposed to be run in a -% group so a) we don't have to initialise |\g_TP_multiselection_toks| -% and b) all changes to the used registers not affecting the -% outside. -% -% \begin{macrocode} -\cs_new_nopar:Npn \TP_multiselection_add:nnnnnn #1#2#3#4#5#6{ - \toks_gset:Nn \g_TP_multiselection_toks {\if_case:w #4} - \clist_map_inline:nn {#5}{ - \tl_if_head_eq_meaning:nNTF{##1..}\DelayEvaluation - { - \TP_multiselection_add_or_case:n {##1} - } - { - #1#2{##1} - \TP_multiselection_add_or_case:o { \toks_use:N #2 } - } - } - \toks_gput_right:Nn \g_TP_multiselection_toks { - \else: \use_i_after_fi:nw{#6}\fi: - } -} -% \end{macrocode} -% -% \end{macro} -% -% \begin{macro}{\TP_multiselection_add_or_case:o} -% No need to worry about where |\or:| is allowed to be added since -% all loops in \LaTeX3 process the item outside conditionals. -% \begin{macrocode} -\cs_new_nopar:Npn \TP_multiselection_add_or_case:n #1 { - \toks_gput_right:Nn \g_TP_multiselection_toks { - \or: \use_i_after_orelse:nw{#1} - } -} -\cs_generate_variant:Nn \TP_multiselection_add_or_case:n {o} -% \end{macrocode} -% \end{macro} -% -% Since i like to set things like |item-label-text| using this -% mechanism i need to handle the `n' key specially. -% -% Actually i could have probably extended -% |\TP_templdecl_setup_f_key:nnN| thus making -% this generally available to all f\meta{number} keys but was too lazy -% (or too stupid) to get it right first time so settled for the simple -% solution. -% -% So |\TP_templdecl_parse_KV:nnw| now calls -% |\TP_templdecl_setup_n_key:nN| for the `n' key. looks like -% this thus be fixed some time soon -% -% -% -% -% -% -% -% \begin{macro}{\IfExistsInstanceTF} -% tests that there is a \emph{default} definition -% taken from xinitials.dtx: -% \begin{macrocode} -\cs_new_nopar:Npn \IfExistsInstanceTF#1#2{ - \cs_if_exist:cTF{<>#1/#2} -} -% \end{macrocode} -% -% FMi: what happens if we are in collection FOO and there exists an -% instance I for type T within this collection but there doesn't exist -% an instance in the empty collection? -% -% What would happen if \ldots\ --- not clear to me what the sematics -% really should be. The code below is not better only different( and -% slower).\footnote{fix semantics} -% \begin{macrocode} -\cs_set_nopar:Npn \IfExistsInstanceTF#1#2{ - \TP_let_instance:Nnn \l_tmpa_tl {#1}{#2} -% next is not \tl_if_eq:NNTF but ...FT so done manually - \if_meaning:w\l_tmpa_tl\scan_stop: - \exp_after:wN\use_ii:nn - \else: - \exp_after:wN\use_i:nn - \fi:} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\DeclareRestrictedTemplate} -% Setting it up: -% -%| \DeclareRestrictedTemplate|\\ -% |{T-type} {new-T-name} {source-T-name} {keyvals}| -% -% This uses the same code as {T-type} {source-T-name} but adds -% settings from {keyvals} -% \begin{macrocode} -\cs_new_nopar:Npn \DeclareRestrictedTemplate#1#2#3#4{ - % CCC do we need a group here?? - \tl_set_eq:cc { TPD>/#1/#2 } { TPD>/#1/#3 } - \tl_set_eq:cc { TP>/#1/#2 } { TP>/#1/#3 } - \toks_set:Nv \l_TP_KV_assignments_toks { TPR>/ #1 / #3 } -% adds stuff to \l_TP_KV_assignments_toks - \setkeys {\cs:w TPO>/#1/#3\cs_end:}{#4} - - \tl_set:cx { TPR>/#1/#2 } - { \toks_use:N \l_TP_KV_assignments_toks } - \cs_if_free:cTF { TPO>/#1/#3 } - { \tl_set:cn {TPO>/#1/#2}{#1/#3} } - { \tl_set_eq:cc {TPO>/#1/#2}{TPO>/#1/#3} } -} -% \end{macrocode} -% \end{macro} -% -% -% Internals: -% -% \begin{macro}{\TP_instdecl_generate_assignments:nn} -% These could probably be inlined, even when they do something! -% -% Assumption: setkeys fully expands its first argument. -% -% \begin{macrocode} -\cs_new_nopar:Npn \TP_instdecl_generate_assignments:nn#1#2 { - % Returns to \l_TP_KV_assignments_toks - % the restrictions - % stored in the TP-structure (at present - % in YAM) of the template #1 - \exp_args:NNo \toks_set:No \l_TP_default_assignments_toks - {\cs:w TPD>/#1\cs_end:\scan_stop:\scan_stop:} - \toks_set:Nv \l_TP_KV_assignments_toks { TPR>/ #1 } - \setkeys { \cs:w TPO>/#1 \cs_end: } - { #2 } % adds stuff to \l_TP_KV_assignments_toks - -% prepends stuff to \l_TP_KV_assignments_toks : - \exp_after:wN\TP_instdecl_add_default_recurse:nn - \toks_use:N\l_TP_default_assignments_toks - -} -% \end{macrocode} -% \end{macro} -% -% -% \begin{macro}{\TP_instdecl_add_default_recurse:nn} -% [ 2001/06/10 Think about doing this properly with explicit plists! --- but -% this means that one has to think about whether or not plists should be -% implemented as token registers and not as tl vars as they are now. ] -% \begin{macrocode} -\cs_new_nopar:Npn \TP_instdecl_add_default_recurse:nn#1#2{ - \token_if_eq_meaning:NNF #1\scan_stop: - { - \l_tmpa_toks{#2} - \tl_set:Nx \l_tmpa_tl { - {\toks_use:N \l_tmpa_toks \toks_use:N \l_TP_KV_assignments_toks} - } - \l_TP_KV_assignments_toks \l_tmpa_tl - \TP_instdecl_add_default_recurse:nn - } -} -% \end{macrocode} -% \end{macro} -% -% -% -% |TPD>/type/name| stores the default parameter assignments. -% -% |TPR>/type/name| stores the parameter assignments that have been -% made for a restricted template otherwise it is undefined (or |\scan_stop:|). -% -% -% |TPO>/type/name| stores the full name (i.e. as |type/name|) -% of the template a restricted -% template is coming from originally. -% -% -% -% -% \begin{macro}{\TP_split_finite_skip_value:nnNN} -% This macro is for use in error checking template values like -% "text-float-sep" that can't contain infinite glue and needs the -% shrink and/or stretch components. First argument is the skip -% register (which is likely to be user input), second is a template -% key name, and the last two are the \meta{dimen} registers that -% stores the stretch and shrink components. Assignments are global. -% \begin{macrocode} -\cs_new_nopar:Npn \TP_split_finite_skip_value:nnNN #1#2{ - \skip_split_finite_else_action:nnNN {#1} { - \PackageError{template}{Value~ for~ key~ #2~ contains~ `fil(ll)'} - {Only~ finite~ minus~ or~ plus~ parts~ are~ allowed~ for~ this~ key.} - } -} -% \end{macrocode} -% \end{macro} -% -% -% -% -% \begin{macrocode} -% -% \end{macrocode} -% -% \Finale -% diff --git a/Master/texmf-dist/source/latex/xpackages/tprestrict-test.tex b/Master/texmf-dist/source/latex/xpackages/tprestrict-test.tex deleted file mode 100644 index a787694abff..00000000000 --- a/Master/texmf-dist/source/latex/xpackages/tprestrict-test.tex +++ /dev/null @@ -1,80 +0,0 @@ -% \iffalse -%% (C) Copyright 2000-2004 LaTeX3 Project -%% -%% It may be distributed and/or modified under the conditions of the -%% LaTeX Project Public License (LPPL), either version 1.3a 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 ``xbase 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. -%% -%% ----------------------------------------------------------------------- -%% -%% $Id: tprestrict-test.tex 251 2004-11-11 19:01:16Z mittelba $ -%% -% \fi -% - -\makeatletter -\RequirePackage{template} -\IgnoreWhiteSpace - -\newcount\ca -\newdimen\da - - -\DeclareTemplateType{type}{0} - -\DeclareTemplate{type}{Ta}{0}{ - one =l [2in] \da, - two =c [5] \ca} - {\DoParameterAssignments\typeout{\da=\the\da,\@spaces \ca=\the\ca}} - -\ShowTemplate{type}{Ta} - -\typeout{1^^J==} -\UseTemplate{type}{Ta}{} - -\typeout{2^^J==} -\UseTemplate{type}{Ta}{one=44pt, two=7} - - -\DeclareRestrictedTemplate{type}{Tb}{Ta}{one=33pt} - -\ShowTemplate{type}{Tb} - -\typeout{RESTRICT^^J3^^J==} - -\DeclareInstance{type}{foo}{Tb}{two=9} - -\ShowInstance{type}{foo} - -\UseInstance{type}{foo} - -\typeout{4^^J==} -\UseTemplate{type}{Tb}{two=7} - -\stop - diff --git a/Master/texmf-dist/source/latex/xpackages/xbase.ins b/Master/texmf-dist/source/latex/xpackages/xbase.ins deleted file mode 100644 index 9f6213a3fb2..00000000000 --- a/Master/texmf-dist/source/latex/xpackages/xbase.ins +++ /dev/null @@ -1,73 +0,0 @@ -% \iffalse -%% -%% This file will generate fast loadable files and documentation -%% driver files from the dtx files in this package when run through -%% LaTeX or TeX. -%% -%% (C) Copyright 2000-2005 LaTeX3 Project -%% -%% It may be distributed and/or modified under the conditions of the -%% LaTeX Project Public License (LPPL), either version 1.3a 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 ``xbase 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. -%% -%% ----------------------------------------------------------------------- -%% -%% $Id: xbase.ins 302 2005-03-01 22:49:14Z morten $ -%% -% \fi -% - -\input docstrip -\keepsilent -\askforoverwritefalse - -\preamble - -(C) Copyright The LaTeX3 Project and any individual authors -listed elsewhere in this file. - -This is a generated file. - -This file was generated from file(s) of the xbase bundle. ---------------------------------------------------------- - -This file may only be distributed together with a copy of this bundle. -You may however distribute the bundle without such generated files. - -====================================================================== - -\endpreamble - - -\generate{% - \file{ldcsetup.sty}{\from{ldcsetup.dtx}{package}} - \file{template.sty}{\from{template.dtx}{package,trace}} - \file{xparse.sty}{\from{xparse.dtx}{package}} -} - -\endbatchfile diff --git a/Master/texmf-dist/source/latex/xpackages/xbase/ldcsetup.dtx b/Master/texmf-dist/source/latex/xpackages/xbase/ldcsetup.dtx new file mode 100644 index 00000000000..09e37c55cb3 --- /dev/null +++ b/Master/texmf-dist/source/latex/xpackages/xbase/ldcsetup.dtx @@ -0,0 +1,331 @@ +% \iffalse +%% File: ldcsetup.dtx (C) Copyright 1999 Frank Mittelbach, Chris Rowley, David Carlisle +%% (C) Copyright 2004-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 +%% 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 ``xbase 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{expl3} +% +%\fi +\GetIdInfo$Id: ldcsetup.dtx 1295 2009-05-06 08:32:25Z will $ + {coding conventions and stuff} +%\iffalse +%<*driver> +%\fi +\ProvidesFile{\filename.\filenameext} + [\filedate\space v\fileversion\space\filedescription] +%\iffalse +\documentclass{ltxdoc} +\begin{document} +\DocInput{ldcsetup.dtx} +\end{document} +% +% \fi +% +% \CheckSum{0} +% +% \title{The \textsf{ldcsetup} package\thanks{This file +% has version number \fileversion, last +% revised \filedate.}} +% \author{DPC, FMi} +% \date{\filedate} +% \maketitle +% +% \begin{abstract} +% Basic code shared by several other packages currently under development. +% \end{abstract} +% +% \StopEventually{} +% +% \begin{macrocode} +%<*package> +\ProvidesExplPackage + {\filename}{\filedate}{\fileversion}{\filedescription} +% \end{macrocode} +% \begin{macrocode} +\RequirePackage{keyval} +\RequirePackage{expl3} +\ExplSyntaxOff +% \end{macrocode} +% +% \section{Ignoring White Space} +% Within a package, or in a document preamble, you can use +% |\IgnoreWhiteSpace| this makes white space ignored, and |@| +% a letter, and |~| a space character. It lasts until the end of the +% current package or preamble. +% +%% Puts an ignored space at the end of the line, so `|\ |' does the right +% thing. (Perhaps should instead just change catcode of |^^M|) +% \begin{macrocode} +\def\IgnoreWhiteSpace{% + \edef\@tempa{% + \catcode`\noexpand\~=\the\catcode`\~\relax + \catcode`\noexpand\ =\the\catcode`\ \relax + \catcode`\noexpand\^^I=\the\catcode`\^^I\relax + \catcode`\noexpand\@=\the\catcode`\@\relax + \endlinechar=\the\endlinechar\relax + }% + \ifx\@currname\@empty + \expandafter\AtBeginDocument\expandafter{\@tempa}% + \else + \expandafter\AtEndOfPackage\expandafter{\@tempa}% + \fi + \catcode`\~=10\relax + \catcode`\ =9\relax + \catcode`\^^I=9\relax + \makeatletter + \endlinechar=` % + \relax +} +% \end{macrocode} +% The new syntax requires |:| and |_| to be letters; instead of +% putting that into |\IgnoreWhiteSpace| we make a new command which +% helps to gradually change packages from old to new syntax. +% \begin{macrocode} +\def\InternalSyntaxOn{% + \edef\@tempa{% + \catcode`\noexpand\~=\the\catcode`\~\relax + \catcode`\noexpand\ =\the\catcode`\ \relax + \catcode`\noexpand\^^I=\the\catcode`\^^I\relax + \catcode`\noexpand\@=\the\catcode`\@\relax + \catcode`\noexpand\:=\the\catcode`\:\relax + \catcode`\noexpand\_=\the\catcode`\_\relax + \endlinechar=\the\endlinechar\relax +%FMi fix is not properly reset + \endlinechar=13\relax + }% +%%% ???? +% this needs further work, don't think it is working + \ifx\InternalSyntaxOff\relax + \expandafter\def\expandafter\InternalSyntaxOff\expandafter + {\@tempa\let\InternalSyntaxOff\relax}% + \fi + \ifx\@currname\@empty + \expandafter\AtBeginDocument\expandafter{\@tempa}% + \else + \expandafter\AtEndOfPackage\expandafter{\@tempa}% + \fi + \catcode`\~=10\relax + \catcode`\ =9\relax + \catcode`\^^I=9\relax + \makeatletter + \catcode`\_=11\relax + \catcode`\:=11\relax + \endlinechar=` % + \relax +} +\let\InternalSyntaxOff\relax +% \end{macrocode} +% +% Do it for this package. +% \begin{macrocode} +%\InternalSyntaxOn +\ExplSyntaxOn +% \end{macrocode} +% +% \section{KV fixes} +% Allow\footnote{Not needed now?} key names to start with |\|. +% \begin{macrocode} +\cs_set_nopar:Npn \define@key#1#2{% + \@ifnextchar[ + {\KV@def{#1}{\string#2}} + {\@namedef{KV@#1@\string#2}####1}} +\cs_set_nopar:Npn \setkeys#1#2{% + \cs_set_nopar:Npn \KV@prefix{KV@#1@\expandafter\string}% + \KV@do#2,\relax,} +% \end{macrocode} +% +% Make KV |#| safe. +% \begin{macrocode} +% \end{macrocode} +% +% \begin{macrocode} +\newtoks\KV@toks +% \end{macrocode} +% +% \begin{macrocode} +\cs_set_nopar:Npn \KV@@sp@c#1\@nil#2\relax#3{\KV@toks{#1}\cs_set_nopar:Npx #3{\the\KV@toks}} +% \end{macrocode} +% +% Generate error messages on missing `,'. +% +% More exactly if two `=' appear after a key generate an error. +% The current KV just silently ignores everything after the second `='. +% \begin{macrocode} +\cs_set_nopar:Npn \KV@equal{=} +% \end{macrocode} +% +% \begin{macrocode} +\cs_set_nopar:Npn \KV@split#1=#2=#3\relax{% + \KV@@sp@def\@tempa{#1}% + \cs_set_nopar:Npn \@tempd{#3}% + \ifx\@tempa\@empty\else + \expandafter\cs_set_eq:NN \expandafter\@tempc + \csname\KV@prefix\@tempa\endcsname + \ifx\@tempc\relax + \KV@error{\@tempa\space \expandafter\@gobbletwo\string\@undefined}\@eha + \else + \ifx\@tempd\@empty + \KV@default + \else + \KV@@sp@def\@tempb{#2}% + \ifx\@tempd\KV@equal + \expandafter\@tempc\expandafter{\@tempb}\relax + \else + \KV@error{Extra~=~ sign~ after~ `#1'}\KV@erry + \fi + \fi + \fi + \fi} +% \end{macrocode} +% +% \begin{macrocode} +\cs_set_nopar:Npn \KV@erry{\expandafter\KV@errx\meaning\@tempd\relax ignored\MessageBreak + missing~comma~in~`\expandafter\strip@prefix\meaning\@tempb'~?} +% \end{macrocode} +% +% \begin{macrocode} +\cs_set_nopar:Npn \KV@errx#1>#2==\relax{% + `#2' } +% \end{macrocode} +% +% \begin{macrocode} +\cs_set_nopar:Npn \KV@default{% + \expandafter\cs_set_eq:NN \expandafter\@tempb + \csname\KV@prefix\@tempa @default\endcsname + \ifx\@tempb\relax + \KV@error{No value specified for \@tempa}\@eha + \else + \@tempb\relax + \fi} +% \end{macrocode} +% +% \LaTeX\ style error message. +% \begin{macrocode} +\cs_set_nopar:Npn \KV@error#1#2{\PackageError{keyval}{#1}{#2}} +% \end{macrocode} +% +% Instead of doing a full KV parse, and evaluating all the keys, +% you might want to parse a parameter list, even for undefined keys, +% removing spaces, splitting up the `,` and `=' and resolving cases +% where no value is supplied. This is used in |\DeclareGenericFunction| +% which \emph{defines} a set of keys via such a KV parse. +% +% A setting of |, key = value ,| will result in |\KV@elt{key}{value}| +% being added to the list, a seting of |, key ,| will result in +% |\KV@default@elt{key}| being added. At the end of the parse the list +% is executed. No keys are checked at this stage (so no csnames are used +% up) the two |\KV|\ldots|@elt| commands must be defined as appropriate. +% +% \begin{macrocode} +\cs_set_nopar:Npn \KV@parse#1{ + \begingroup +% \end{macrocode} +% +% Locally fudge |\KV@@def| to just add to a token register +% rather than make a definition. +% \begin{macrocode} +\cs_set_nopar:Npn \KV@@sp@c##1\@nil##2\relax##3{\addto@hook##3{{##1}}} +% \end{macrocode} +% +% Locally fudge |\KV@split| to just add to a token register +% rather than execute the code for the found keys. +% \begin{macrocode} +\cs_set_nopar:Npn \KV@split##1=##2=##3\relax{% + \cs_set_nopar:Npn \@tempd{##3}% + \expandafter\ifx\expandafter=\@firstofone##1=\else + \ifx\@tempd\@empty + \addto@hook\KV@toks\KV@default@elt + \KV@@sp@def\KV@toks{##1}% + \else + \ifx\@tempd\KV@equal + \addto@hook\KV@toks\KV@elt + \KV@@sp@def\KV@toks{##1}% + \KV@@sp@def\KV@toks{##2}% + \else + \KV@err{Extra `=' after `##1'}\@ehd + \fi + \fi + \fi} +% \end{macrocode} +% +% Initialise +% \begin{macrocode} + \KV@toks{} +% \end{macrocode} +% Do the parse +% \begin{macrocode} + \KV@do#1,\relax, +% \end{macrocode} +% Evaluate the token register outside the group. +% \begin{macrocode} + \expandafter + \endgroup + \the\KV@toks} +% \end{macrocode} +% +% \section{Calc fixes} +% +% Count Register assignments via calc. Here we also provide some +% global versions since a normal global prefix won't have any effect. +% \begin{macrocode} +\cs_set_eq:NN \SetInternalCounter \calc_int_set:Nn +\cs_set_eq:NN \GSetInternalCounter\calc_int_gset:Nn +% \end{macrocode} +% +% +% \section{Misc code that is best collected in one place} +% +% This section will receive odd code that would be of potential use to +% other packages and should eventually made it to the kernel +% (perhaps). +% +% \begin{macro}{\UndeclareRobustCommand} +% Remove a robust command from memory if it isn't used any +% longer. Of course this doesn't free the hash table but at least +% the space gets reclaimed. +% \begin{macrocode} +\cs_set_nopar:Npn \UndeclareRobustCommand#1{% + \cs_gundefine:N #1 + \exp_args:Nc \cs_gundefine:N {\cs_to_str:N #1~} +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macrocode} +% +% \end{macrocode} +% +% \Finale +% diff --git a/Master/texmf-dist/source/latex/xpackages/xbase/template-test.tex b/Master/texmf-dist/source/latex/xpackages/xbase/template-test.tex new file mode 100644 index 00000000000..f8c47c82d59 --- /dev/null +++ b/Master/texmf-dist/source/latex/xpackages/xbase/template-test.tex @@ -0,0 +1,77 @@ +% \iffalse +%% (C) Copyright 2000-2004 LaTeX3 Project +%% +%% It may be distributed and/or modified under the conditions of the +%% LaTeX Project Public License (LPPL), either version 1.3a 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 ``xbase 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. +%% +%% ----------------------------------------------------------------------- +%% +%% $Id: template-test.tex 251 2004-11-11 19:01:16Z mittelba $ +%% +% \fi +% +\RequirePackage{template} + +\DeclareTemplateType{xxx}{0} + +\DeclareTemplate{xxx}{test}{0} + { + xkey=n \xkey, + key =i {yyy} \value + } + { + \DoParameterAssignments + \show\xkey + \show\value + \value + } + +\DeclareTemplateType{yyy}{0} + +\DeclareTemplate{yyy}{foo}{0} + { + keya =L \foo + } + { + \DoParameterAssignments + \show\foo + } + + +\DeclareInstance{xxx}{bar}{test} + { + xkey = \UseTemplate{yyy}{foo}{ keya = 20pt }, + key = \UseTemplate{yyy}{foo}{ keya = 10pt } + } + +\ShowInstance{xxx}{bar} + +\UseInstance{xxx}{bar} + +\stop diff --git a/Master/texmf-dist/source/latex/xpackages/xbase/template-test2.tex b/Master/texmf-dist/source/latex/xpackages/xbase/template-test2.tex new file mode 100644 index 00000000000..489e9f2304a --- /dev/null +++ b/Master/texmf-dist/source/latex/xpackages/xbase/template-test2.tex @@ -0,0 +1,110 @@ +% \iffalse +%% (C) Copyright 2000-2004 LaTeX3 Project +%% +%% It may be distributed and/or modified under the conditions of the +%% LaTeX Project Public License (LPPL), either version 1.3a 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 ``xbase 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. +%% +%% ----------------------------------------------------------------------- +%% +%% $Id: template-test2.tex 585 2006-12-12 17:31:48Z morten $ +%% +% \fi +% + + +\RequirePackage{template} +\RequirePackage{trace} + +\DeclareTemplateType{xxx}{0} + +\def\MultiSelection{\MultiSelectionError} +%\def\foo{bar} + +%\traceon + +\DeclareTemplate{xxx}{test}{0} + { + xkey=n [\foo] \xkey, + ykey=n [\DelayEvaluation\foo] \ykey, + zkey=n \zkey, + last=n [last] \lastkey, + set =i {xxx} \xxx + } + { + \DoParameterAssignments + \typeout{abc} + } +\ShowTemplate{xxx}{test} + + +\DeclareInstance{xxx}{bar}{test} + { + zkey = foo, + xkey = baz, + } + +\DeclareInstance{xxx}{baz}{test} + { + last = first, + set = \UseTemplate{xxx}{test}{zkey=rrr}, + zkey = foo + } + + +\ShowInstance{xxx}{bar} +\ShowInstance{xxx}{baz} + +\DeclareTemplateType{yyy}{0} + +\DeclareTemplate{yyy}{foo}{0} + { + keya =L \foo + } + { + \DoParameterAssignments + \show\foo + } + + +\DeclareInstance{xxx}{bar}{test} + { + xkey = \UseTemplate{yyy}{foo}{ keya = 20pt }, + key = \UseTemplate{yyy}{foo}{ keya = 10pt } + } + +\ShowInstance{xxx}{bar} + +\UseInstance{xxx}{bar} + +\stop + +%%% Local Variables: +%%% mode: plain-tex +%%% TeX-master: t +%%% End: diff --git a/Master/texmf-dist/source/latex/xpackages/xbase/template.dtx b/Master/texmf-dist/source/latex/xpackages/xbase/template.dtx new file mode 100644 index 00000000000..8b38f6d216c --- /dev/null +++ b/Master/texmf-dist/source/latex/xpackages/xbase/template.dtx @@ -0,0 +1,2452 @@ +% \iffalse +%% File: template.dtx (C) Copyright 1999-2001 David Carlisle, Frank Mittelbach +%% (C) Copyright 2004-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 +%% 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 ``xbase 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{expl3} +% +%\fi +\GetIdInfo$Id: template.dtx 1461 2009-08-15 08:38:12Z joseph $ + {template} +%\iffalse +%<*driver> +%\fi +\ProvidesFile{\filename.\filenameext} + [\filedate\space v\fileversion\space\filedescription] +%\iffalse +\documentclass{ltxdoc} +\makeatletter + \newenvironment{decl}[1][]% + {\par\small\addvspace{4.5ex plus 1ex}% + \vskip -\parskip + \ifx\relax#1\relax + \def\@decl@date{}% + \else + \def\@decl@date{\NEWfeature{#1}}% + \fi + \noindent\hspace{-\leftmargini}% + \begin{tabular}{|l|}\hline\ignorespaces}% + {\\\hline\end{tabular}\nobreak\@decl@date\par\nobreak + \vspace{2.3ex}\vskip -\parskip\@afterheading} +\makeatother + + \begin{document} + \catcode`\_=11 + \catcode`\:=11 + \DocInput{template.dtx} + \end{document} +% +% +% +% \fi +% +% +% \CheckSum{0} +% +% \title{The \textsf{template} package\thanks{This file +% has version number \fileversion, last +% revised \filedate.}} +% \author{DPC, FMi} +% \date{\filedate} +% \maketitle +% +% \changes{0.06}{1998/12/17}{generic functions reborn as templates} +% +% \tableofcontents +% +% \section{Introduction} +% A \emph{Template} is a named `function' that has a fixed number +% of \emph{mandatory arguments} and an additional set of \emph{keys} +% or `named attributes' that are set in a `key value list'. That is, +% a comma separated set of assignments of the form:\\ +% \meta{key$_1$} |=| \meta{value$_1$} |,| +% \meta{key$_2$} |=| \meta{value$_2$} \ldots +% +% More specific instances of the template may be declared by +% specifying settings of the parameters. The key value list is parsed +% at the time the instance is declared, and an `internal' set of +% parameter assignments is passed to the template code. It is normally +% not parsed at run-time, though it is possible to enforce this +% behaviour. +% +% Templates have a \emph{type} and a \emph{name}. Templates +% of the same type have the same argument and parameter +% structure. That is, templates of the same type are expected to be +% exchangeable semantically. (However, except for checking that +% templates of the same type always have the same number of arguments +% this is not enforced by the code.) +% +% A template type is declared via the |\DeclareTemplateType| +% declaration which takes two arguments: the name for the type and the +% number of arguments a template of this type requires. +% +% Templates are declared via the |\DeclareTemplate| +% command which takes five arguments +% \begin{itemize} +% \item The \emph{type} of the template (no |\|). +% \item The \emph{name} of the template (no |\|). +% \item The number of arguments for the template (same as on type +% declaration). +% \item A list declaring the keys accepted by the template, +% with information about the action to take when the key is specified +% with a value. +% \item The code for the template. This may be arbitrary \TeX\ +% code. At some point it should execute |\DoParameterAssignments| +% to run the parameter assigments. +% +% The mandatory arguments are accessed via |#1|, |#2|, \ldots +% \end{itemize} +% +% +% Each element of the key specification list is of the form: +% \begin{flushleft} +% \meta{key name} |=| +% \meta{key type} \meta{optional default} \meta{internal code} +% \end{flushleft} +% +% The \meta{key types} are essentially specified by giving a symbolic +% representation of the assignment function to be used by \TeX. +% +% Currently the possibilities are +% +% \begin{center}\catcode`|=12 +% \begin{tabular}{l|ll|l} +% key type& letter& internal code& argument form\\\hline +% Command & f\emph{n}&command name & command definition\\ +% name & n & command name & command definition\\ +% length & l & length register& calc length syntax\\ +% fake length & L & command name & calc length syntax\\ +% count & c & count register& calc count syntax\\ +% fake count & C & command name & calc count syntax\\ +% boolean & b & name of \verb|\newif| switch& true or false\\ +% switch & s & \marg{true code}\marg{false code}& true or false\\ +% instance& i\marg{type}& command name& instance of this \emph{type}\\ +% direct & x & Internal code& any\\ +% general & g & general code & any +% \end{tabular} +% \end{center} +% +% In addition, any of these types may be prefixed by |+| to +% denote a global assignment (described below). +% |f| takes a digit from 0--9 to denote the number of arguments. +% |n| is in fact the same as |f0|. When an instance is declared +% The value assigned to the key should be the definition of +% the command, using |#1|\ldots|#9| to denote the specified arguments. +% +% |c| takes an internal form a count register, +% not a \LaTeX\ counter name. +% +% For |f|, |n|, |l|, and |c|, the assignment is done twice, once +% at the time an instance is \emph{declared}. (This may involve +% using \textsf{calc} expresions. Then the `primitive assignment' +% of the value (not using calc) is copied to the internal parameter +% list, to be executed when an instance is run. Sometimes you need the +% expression to be evaluated at the time an instance is run rather +% than the time it is declared. For example it may be an expression +% involving some values that are not fixed throughout a document. +% In this case the instance declaration may give a value in the +% form |\DelayedEvaluation|\marg{calc expression}. In this case +% the value is not evaluated when the instance is declared, and +% instead the entire expression is copied to the `internal parameter +% list' and is evaluated whenever the instance is used. +% +% |L| and |C| take the same value types as |l| and |c| but the internal +% assignments are to macros not registers. +% +% Keys declared with |b| and |s| each take values either \emph{true} or +% \emph{false}. if the key zzz is declared with |b| then specifying +% |zzz=true| will essentially pass |\zzztrue| to the internal parameter +% list (although in fact |\zzztrue| need not be defined) . If instead +% zzz had been declared via |s|, then |zzz=true| would pass the tokens +% of the \marg{true code} to the internal parameter list. +% +% If a key is specified as |x|, then when used the \emph{internal code} +% will be copied to the internal parameter lists. This code may use |#1| +% to denote the value supplied to the key in the instance declaration. +% Note that this code is \emph{only} copied at the time the instance is +% declared. It is not executed at this time. It is executed when the +% instance is executed.\footnote{Despite the question of whether or +% not x and g are still necessary these days, they have the wrong +% `names' since x is the one that is not executed during delcaration +% while g is.} +% +% If a key is declared with |g| then the code is run at the time the +% instance is declared. By default \emph{nothing} is passed to the +% internal parameter list. This code may use |#1| to denote the +% value that will be supplied when an instance is declared. +% Any code that should be run when an instance is executed should +% be explicitly passed to the internal parameter list using +% |\toks_add_right:Nn\l_TP_KV_assignments_toks{|\ldots|}| +% +% A key declared with |i|\marg{type} takes as value the name of a +% declared instance of that type. The command token associated with +% the key will store a command essentially equivalent to a call +% to |\UseInstance|\marg{type}\marg{name}, but in a slightly optimised +% internal form. +% As an exception to this rule the replacement code may be of the form +% |\UseTemplate| followed by the key settings for the template +% but without the mandatory arguments. In this case the `inner' +% instance declaration is `pre compiled' and the token assigned to +% the store the value assigned to this key will execute an instance +% of the template directly, it will not re-parse the keyword settings +% each time the instance is used. +% +% \section{Commands} +% +% +% \subsection{Template declaration commands} +% +% \begin{decl} +% |\DeclareTemplateType| \marg{type}\marg{num} +% \end{decl} +% Declare a template type. +% +% \begin{decl} +% |\DeclareTemplate| +% \marg{type}\marg{tname}\marg{num}\marg{keyspec}\marg{code} +% \end{decl} +% Declare a template \meta{tname} of type \meta{type} with the set of +% keys as defined by \meta{keyspec}. From this template instances can +% be declared using |\DeclareInstance| At runtime such instances will run +% \meta{code} and expect \meta{num} mandatory arguments (same number +% for all templates of one type).\footnote{The \meta{num} argument is +% redundent as it can be deduced from the type. However, for practical +% reasons it seems better to keep that information with each +% individual template declaration.} +% +% \begin{decl} +% |\DeclareRestrictedTemplate| +% \marg{type}\marg{new-tname}\marg{old-tname}\marg{keyvals} +% \end{decl} +% Declare as new template \meta{new-tname} for type \meta{type} by +% taking template \meta{old-tname} as the basis and setting one or +% more of its keys to specific values. +% +% \begin{decl} +% |\DoParameterAssignments| +% \end{decl} +% The list of key value assignments made (and saved) during template +% declaration is evaluated at this point in the template code. +% +% +% \subsection{Instance declaration commands} +% +% \begin{decl} +% |\DeclareInstance| \marg{type}\marg{iname}\marg{tname}\marg{keyvals} +% \end{decl} +% Declare an instance of type \meta{type} named \meta{iname} build +% from using template \meta{tname} with key settings as given by +% \meta{keyvals}. +% +% \begin{decl} +% |\DeclareCollectionInstance| +% \marg{collection}\marg{type}\marg{iname}\marg{tname}\marg{keyvals} +% \end{decl} +% Same as |\DeclareInstance| except that this instance is only active +% when for the type \meta{type} the collection \meta{collection} was +% selected via |\UseCollection|. E.g., within the frontmatter one +% could make all headings behave differently by defining collection +% instances for template type `head'. +% +% \subsection{Key value commands} +% +% \begin{decl} +% |\DelayEvaluation|\marg{code} +% \end{decl} +% Used in the value spec for an instance to declare that the value +% \meta{code} should not be evaluated at declaration time but at +% run-time. Can also be used in the defaults for keys (given in square +% brackets) in the declaration of templates. +% +% \begin{decl} +% |\MultiSelection| \meta{counter} \marg{cases} \marg{else} +% \end{decl} +% Used in the value spec for an instance key to declare that the value of +% this key depends on the current setting of \meta{counter} at run-time. +% The \meta{cases} argument is a comma-separated list of ``values'', +% the \meta{else} argument a single ``value''. If at run-time +% \meta{counter} has the value $i$ then the $i$-th element of the +% \meta{cases} list is selected. If that does not exist the +% \meta{else} case is returned. +% +% +% \subsection{Processing commands} +% +% \begin{decl} +% |\UseTemplate| \marg{type}\marg{tname}\marg{keyval} +% \end{decl} +% Execute a template \meta{tname} of type \meta{type} at run-time +% using \meta{keyvals} as the value assignments for its keys. In this +% case the keys are evaluated at run-time thus this method is far +% slower than using a predeclared instance of this template (see +% below). This command can also appear as the value for a key of type +% `i' in which case the evaluation happens at declaration time of the +% template that contains this key! +% +% +% \begin{decl} +% |\UseInstance| \marg{type}\marg{iname} +% \end{decl} +% Run the instance \meta{iname} of template type \meta{type}. If a +% collection is in force see if there is a collection instance of name +% \meta{iname} and if so run that instead. +% +% \begin{decl} +% |\UseCollection| \marg{type}\marg{collection} +% \end{decl} +% Declare that from now on (normal scoping rules) the collection +% \meta{collection} for template type \meta{type} is in force. This +% means that a call to |\UseInstance| will first check if there is a +% collection instance defined, and if so use that instance, otherwise +% use the normal instance. +% +% +% \subsection{Test commands} +% +% \begin{decl} +% |\IfExistsInstanceTF| \marg{type}\marg{iname}\marg{true}\marg{false} +% \end{decl} +% Test if for template type \meta{type} an instance with name +% \meta{iname} exists. Select \meta{true} or \meta{false} code +% accordingly. +% +% +% +% \section{Examples of template key types} +% +% The general syntax for key specification in templates (fourth argument +% of the command |\DeclareTemplate|) is: +%\begin{flushleft} +%| {| \\ +%| | \meta{key-name$_1$} |=|\meta{key-type$_1$} +% \meta{optional-default$_1$} \meta{storage-bin$_1$}|,|\\ +%| | \meta{key-name$_2$} |=|\meta{key-type$_2$} +% \meta{optional-default$_2$} \meta{storage-bin$_2$}|,|\\ +%| ...|\\ +%| }| +%\end{flushleft} +% In this section we look at all possible key types and give examples +% for them. +% +% +% \subsection{Attributes that receive names as values} +% +% The type |n| expects to receive a \LaTeX{} name as a value. Used, +% for example, to specify the name of a \LaTeX{} counter to use. +%\begin{verbatim} +% heading-id =n \heading@id, +% counter-id =n [\DelayEvaluation{\heading@id}] \heading@counter, +%\end{verbatim} +% Notice the use of |\DelayEvaluation| in the default of +% |counter-id|. It is necessary to make the default the token +% |\heading@id| if we want to inherit the value from the |heading-id| +% key. Otherwise it gets value of |\heading@id| at the time the +% instance is declared. +% +% +% \subsection{Attributes that receive functions as values} +% +% +% The type |f|\meta{num} expects a function with \meta{num} arguments +% as a value. The arguments are denoted by |#1|, |#2|, etc. In most +% cases either |f0| (for declarations) or |f1| (to format one argument) are +% needed. +%\begin{verbatim} +% initial-font =f0 \initial@font, +% initial-format =f1 [#1] \initial@boxhandling, +%\end{verbatim} +% +% \subsection{Attributes that receive dimensions as values} +% +% As far as specifying instances the |l| and |L| type behave +% identically. They differ only in the type of internal storage-bin +% they need: |l| expects a length register while |L| expects an +% ordinary macro name and assigns its value via |\cs_set_nopar:Npn |. +%\begin{verbatim} +% pre-sep =l \topsep, +% post-sep =L \botsep, +%\end{verbatim} +% +% +% +% \subsection{Attributes that receive integers as values} +% +% The |c| and |C| type receive integers as values. Again either of +% them can be transparently used. In case of |c| the +% \meta{storage-bin} has to be a \TeX{} count register not a \LaTeX{} +% counter name, i.e., set up via |\newcount|. (\LaTeX{} counters can +% be used as well if they are accessed via their internal name, i.e., +% via |\c@|\meta{\LaTeX-counter}) +%\begin{verbatim} +% pre-penalty =c \@beginparpenalty, +% penalty =C \hmaterial@penalty, +%\end{verbatim} +% +% +% +% \subsection{Attributes that receive template instances as values} +% +% The type |i|\marg{type} takes as value the name of a declared +% instance of that type. The \meta{storage-bin} associated with the +% key will store a command essentially equivalent to a call to +% |\UseInstance|\marg{type}\marg{name}, but in a slightly optimised +% internal form. +% +% As an exception to this rule the replacement code may be of the form +% |\UseTemplate| followed by the key settings for the template but +% without the mandatory arguments. In this case the `inner' instance +% declaration is `pre compiled' and the token assigned to the store +% the value assigned to this key will execute an instance of the +% template directly, it will not re-parse the keyword settings each +% time the instance is used. +%\begin{verbatim} +% justification-setup =i{justification} \list@justification, +%\end{verbatim} +% +% Usage within an instance declaration is either +%\begin{verbatim} +% justification-setup = raggedright, +%\end{verbatim} +% i.e., name of a declared instance or a call to |\UseTemplate| +%\begin{verbatim} +% justification-setup = \UseTemplate{justification}{TeX} +% { startskip = 0pt, ... }, +%\end{verbatim} +% +% +% +% \subsection{Attributes that receive true or false values} +% +% The type |s| expects the strings |true| or |false| as values. In +% this case the declaration has no \meta{storage-bin}. Instead the +% declaration consists of two brace groups containing code. Depending +% on the value one of the groups gets copied verbatim into the +% internal parameter list of the instance and gets executed at +% run-time at the point where |\DoParameterAssignments| is seen. +%\begin{verbatim} +% item-implicit-boolean =s +% { \cs_set_nopar:Npn \item@implicit@code{\item\relax} }{}, +% numbered-boolean =b [true] @heading@nums, +%\end{verbatim} +% +% +% \subsection{Attributes that accept any value} +% +% The type |g| is a low-level specification which contains arbitrary +% code in place of the \meta{storage-bin}. This code is evaluated at +% declaration time of the instance and by default \emph{nothing} is +% passed to the internal parameter list (this has to happen explicitly +% from within the code). |#1| may be used to access the value +% specified. +% +% The main purpose for this type is of historical nature (originally +% most of the other types have been implemented internally using |g|). +% +% The type |x| also requires code in place of the \meta{storage-bin}. +% However with this type all of the code is copied unevaluated to the +% internal parameter list. There are some applications for this type +% when implementing customisable defaults. However, it is likely that +% it will not survive a final release. +%\begin{verbatim} +% generic-key =g \typeout{#1}, +% extra-assigns =x \typeout{#1}, +%\end{verbatim} +% +% +% +% +% +% +% \section{A complete example} +% +% The following example shows a sketch of a template for typesetting +% captions to be used as part of a larger mechanism setting whole +% floats.\footnote{I made it up while I went along so if you spot the +% ``missing brace'' or some other blunder tell me, FMi.} +% +% We declare a template type \texttt{caption} then define an example +% template for that type and finally produce some instances from that. +% +% \subsection{Declaring the template type} +% +% To define the template type we first have to ask ourselves what +% information would be varying each time such a template is used? A +% potential answer could be the following: +% \begin{itemize} +% \item +% The float name, e.g., `Table' or `Fig.' etc. +% \item +% The float +% number e.g., `10' or `3--c' etc. +% \item +% The actual caption text as specified in the document. +% \end{itemize} +% Since the above items would be differed in each instantiation of +% such a template we would pass them as mandatory argument to the +% template. +% +% Are there others? Possibly. Here are two more that seem to be +% useful, at least in a number of cases: +% \begin{itemize} +% \item +% The text of the legend in document classes that distinguish +% between caption text (heading to the figure/table) and legend +% (explanatory material) +% \item +% Measure to which the caption should be typeset. +% \end{itemize} +% The last one of these might need some extra explanation. Suppose a +% design requires that the caption width is decided depending on the +% width of the table of figure, e.g., the caption is supposed to +% typeset below some illustration and should not be wider than that +% illustration, or the caption is typeset aside to the illustration +% using the remaining space. In that case the process that formats the +% whole float needs to communicate with the current template to pass +% that (varying) information along. Of course, that could happen by +% using global variables, e.g., the outer process sets the measure as +% desired before calling the caption formatting template. What makes +% more sense is likely to be a matter of taste but it also has to do +% with the precise semantics of the template type. Staying with our +% example: if the the semantics of the template type \texttt{caption} +% is supposed to produce a formatted box (in \TeX{} terms) then we +% should pass the measure as an argument if we ever intend to allow +% for variations. If on the other hand the semantics are to format a +% certain set of text into the current galley (which has measure of +% its own) then a measure argument would not belong to this template +% type. +% +% Are there other variations sensible? Yes, for example, instead of +% passing a fixed string like ``Fig.'' as the first argument one could +% pass an abstract float type identifier and let the template worry to +% deduce from that information what fixed string to produce. +% +% Another question: why should we pass the fixed text (or an abstract +% identifier from which it can be deduced) and the number as separate +% arguments to the template instead of passing a combined string (like +% it is done in the |\@makecaption| command of \LaTeXe{})? Answer: +% because this allows to build templates that can individually +% manipulate both bits of information, e.g., to format the number in a +% different font, etc. +% +% So what are the conclusions of this discussion? Defining the +% semantics of a template type is difficult and often needs several +% trials to come up with something that is covering the anticipated +% use. There is clearly not a cardinal way for defining template +% types; how the overall separation into smaller units is done is +% partly a matter of taste and partly a matter of the major layout +% characteristics that one tries to support. +% +% Returning to our example: let's assume we settle for the first four +% arguments, i.e., the calling template is responsible for setting the +% measure for the caption text if necessary. +% +% What we also have to do is to define (at least for ourselves) what +% data the arguments accept and what their semantics are. An informal +% summary of that could be the following: +% \begin{center} +% \begin{tabular}{rrl} +% \textit{Arg} & \textit{Data Type} & \textit{Description} \\[3pt] +% 1 & text & fixed float description +% \\ +% 2 & text/|\NoValue| & float number +% \\ +% 3 & text & caption text +% \\ +% 4 & text/|\NoValue| & legend text +% \\ +% \end{tabular} +% \end{center} +% The second and the fourth argument are allowed to be missing (i.e., +% can get |\NoValue| passed as a value). Note that the empty string in +% case of a text argument is different from |\NoValue|. +% +% We further declare that it is permissible for a template of this +% type to ignore the information provided by all arguments except 3, +% i.e., the caption text. +% +% Finally the result of the template formatting should is to typeset +% text into a current galley (paragraph mode in \LaTeX{} lingua). +% +% All the above is semantic information that (at least right now) is +% not being enforced by declaring a template type (except for the +% number of arguments) but each template of a certain type is supposed +% to conform to this specification nonetheless.\footnote{To make this +% even clearer we are thinking of extending the template type +% declaration with another argument in which one has to formally or +% informally (?) specifies information like the one in the table +% above.} +% +% This finally leads to the following declaration: +%\begin{verbatim} +%\DeclareTemplateType{caption}{4} +%\end{verbatim} +% +% \subsection{Defining a first template} +% +% We start by defining a simple template of type \texttt{caption} +% which roughly formats a caption like those being presented in +% \LaTeXe{}'s article class, i.e., the caption is typeset as a +% paragraph if it is longer than a single line, otherwise it is +% centered. The legend even if present is ignored. Above and below we +% give the designer the possibility to add some space. +% +% In fact the examples is more or less identical in code to +% |\@makecaption| except that if the second argument (i.e., the +% number) is |\NoValue| it and its preceding space\footnote{For those +% who wonder: spaces are by default ignored within definitions when +% the new packages are used due to a command \texttt{\textbackslash +% InternalSyntaxOn}, do get a normal space one has to use +% \texttt{\textasciitilde} and to obtain an unbreakable space +% \texttt{\textbackslash nobreakspace}.} gets ignored. +% +% We start by declaring the template \texttt{toosimple} of type +% \texttt{caption} having four mandatory arguments (as described in +% the discussion of the template type). +%\begin{verbatim} +%\DeclareTemplate{caption}{toosimple}{4} +%\end{verbatim} +% The next argument of |\DeclareTemplate| lists all keys for the +% template. In this case we have keys for the vertical spaces above +% and below. We make them type |L| to save on registers but with a bit +% of care we could also have used scratch registers like |\@tempskipa| +% etc. Their default values are both zero. +%\begin{verbatim} +% { +% above-skip =L [0pt] \caption@above@skip , +% below-skip =L [0pt] \caption@below@skip , +% } +%\end{verbatim} +% The final argument of |\DeclareTemplate| contains the actual +% processing code. We start with looking at the second mandatory +% argument (caption number) to find out if it is |\NoValue| and +% depending on the result define a helper command |\caption@start|. +%\begin{verbatim} +% { +% \IfNoValueTF{#2} +% { \cs_set_nopar:Npn \caption@start{#1:~} } +% { \cs_set_nopar:Npn \caption@start{#1~#2:~} } +%\end{verbatim} +% Having dealt with the prelims we now run |\DoParameterAssigments| at +% which point the keys of the template are made available, e.g., at +% this point all those right hand containers such as +% |\caption@above@skip| get assigned the value specified in an +% instantiation of the template. (That scheme allows to do preliminary +% processing up front, e.g., defaults for the keys could be assigned +% prior to that point in which case they are overwritten if the +% template instance specifies a different value. the use of specifying +% defaults via the |[..]| syntax as done above is slightly faster at +% run-time but needs more memory.) +%\begin{verbatim} +% \DoParameterAssigments +%\end{verbatim} +% The rest of the code should look familiar to anybody who ever looked +% at \texttt{article.cls}. The only point worth mentioning are the +% |\relax| commands after |\caption@above@skip| and +% |\caption@below@skip|. Since we have decided to use |L| as key type +% these commands are macros and not registers containing the +% dimensions as strings. This means that we have to be careful to +% ensure that \TeX{} knows where the dimension ends. In certain cases +% text following such a command might be mistaken as being part of the +% dimension (e.g., if followed by the word \texttt{plus}, etc.). In +% the code below this could only happen for the second |\vskip| but it +% is good practice to always add a terminating |\relax| to avoid such +% hidden traps. +%\begin{verbatim} +% \vskip \caption@above@skip \relax +% \sbox \@tempboxa {\caption@start #3} +% \ifdim \wd\@tempboxa >\hsize +% \caption@start #3\par +% \else +% \global \@minipagefalse +% \hb@xt@\hsize{\hfil\box\@tempboxa\hfil} +% \fi +% \vskip \caption@below@skip \relax +% } +%\end{verbatim} +% +% Why is the above template of not much use? Simply because it doesn't +% offer any flexibility to declare different designs. The only +% alteration offered to the designer is to modify the space above and +% below the caption, e.g., the following declaration would mimic the +% definition within the \texttt{article.cls} class of \LaTeXe : +%\begin{verbatim} +%\DeclareInstance{caption}{article}{toosimple} +% { +% above-skip = 0pt, +% below-skip = 10pt, +% } +%\end{verbatim} +% And that's all that can be manipulated. All items that people asking +% to change, e.g., not having a colon after the number, using +% different fonts and font sizes, etc.\ are still hard-wired and thus +% inaccessible. So we have to do better if we want to make use of the +% power the template mechanism offers. +% +% +% +% \subsection{Defining a better template} +% +% First step in defining better templates is to ask ourselves a couple +% of questions: +% \begin{itemize} +% \item What are the main characteristics of the layout the template +% is supposed to support? +% \item What are the elements that we want to allow (or can allow) the +% designer to modify? +% \end{itemize} +% +% Take the first question first: the layout supported by the template +% of the previous section had as its main characteristics that it +% would center the caption if it would fit in a single line in the +% current measure. We could consider this being an unchangable +% characteristic of the layout this template produces (and a designer +% would need to use a different template of type \texttt{caption} if a +% design compatible with this restriction is desired) or we could try +% to make our template smarter by adding bells and wistles that allow +% the designer to say stuff like: +%\begin{verbatim} +% one-line-format = \hfil #1 \hfil, +%\end{verbatim} +% or +%\begin{verbatim} +% one-line-action = center, +%\end{verbatim} +% depending on how we intend to offer changing the behavior of the +% template. Like when trying to define sensible template types we have +% no single road to heaven (and probably as many to hell) --- it has a +% lot to do with how we think about design. +% +% My advice, after having tried to work with these concepts for a +% while, is to keep templates simple in so far as that most of not all +% attribute for a template should be relevant for the design. In other +% words, if you have attributes that, depending on their setting, make +% half of the other attributes not applicable then it may be +% appropriate to think about providing several templates instead. To +% give an example from \LaTeXe : instead of having |\@startsection| +% deal with both vertical heads and run-in heads provide individual +% templates. (|\@startsection| is this famous command where design +% switches are build in by making dimensions negative to signal +% something and afterwards use the absolute value.) +% Another way to look at this is to say that a template should +% normally not contain large amounts of code which is only selected in +% a subset of attribute settings. +% +% As said before there are no golden rules, it is perfectly possible +% to make hugely complicated templates that solve every possible +% aspect of layout one could think of in one go --- it is just that +% with keeping it more simple one can get the same functionality with +% less headaches for the template writer as well as the template user +% later on. +% +% Returning to our example: allowing to handle the case of a single +% line caption specially could well be considered part of the +% template. In contrast: layouts that would put the caption number +% sideways, i.e., which would need totally different internal coding +% should probably be coded as a separate template of type +% \texttt{caption}. +% +% So for our next example template we settle for the fixed caption +% text plus number (if any) being at the beginning of the variable +% caption text (coming from the document) and being together formatted +% as some sort of a pargraph. In case of the whole caption being a +% single line we allow the designer to specify how to lay it out +% (e.g., centered, flush left, etc.). If there is a legend it will get +% formatted by a vertical space followed by the legend formatted as +% another paragraph. +% +% More precisely we allow for the following bells and wistles: +%\begin{verbatim} +%\DeclareTemplate{caption}{lesssimple}{4} +% { +%\end{verbatim} +% The designer can specify the space above and below the caption like +% we did in our first example. +%\begin{verbatim} +% above-skip =L [0pt] \caption@above@skip , +% below-skip =L [0pt] \caption@below@skip , +%\end{verbatim} +% Regarding the caption number we support the case where no number is +% present (the value being |\NoValue|) as well as the number being +% present. For both cases the designer has to specify what formatting +% should be attached. By default all is being typeset in the font the +% whole caption is presented but if there is a need for it the +% designer can use the following keys to attach special formatting +% devices to each particular item beside specifying special spacing +% information or replacing the default colon after the number with +% something else. +%\begin{verbatim} +% number-format =f2 [#1~#2:~] \caption@number@format, +% nonumber-format =f1 [#1:~] \caption@nonumber@format, +%\end{verbatim} +% If the caption is fitting onto a single line we make it possible +% for the designer to specify how this single line should be +% positioned (the default is to center the line). +%\begin{verbatim} +% single-line-format =f1 [\hfil#1\hfil] \caption@single@line@format, +%\end{verbatim} +% The font for the caption (including the fixed text and the number +% unless specified differently above) is going to be the one decided +% by the next key. +%\begin{verbatim} +% caption-font =f0 [\normalfont] \caption@font, +%\end{verbatim} +% The next attribute deserves some extra explanation: here we make use +% of an interface which is explained in more detail when we reveil the +% support for galley formatting.\footnote{Guess I have to apologize +% for the fact that i partly make use of that interface in this +% example while on other occasions (like the use of vertical spacing) +% within the example I do not---consistency around midnight is not my +% strength I fear (FMi).} In a nutshell the template type \texttt{hj} +% (hyphenation \& justification) allows one to define a) the +% justification concepts applied to the upcoming paragraphs, e.g., +% whether they should be set flush left, adjusted, first line +% centered, etc.\ b) the linebreaking strategy used and c) the +% hyphenation rules which should apply. All this is done by selecting +% an appropriate (predefined) instance of this type as will hopefully +% become somewhat clearer in the example instances shown below. +%\begin{verbatim} +% caption-hj-setup =i {hj} [default] \caption@hj@instance, +%\end{verbatim} +% In case there is a legend to format we give the designer the +% possibility to specify by how much vertical space it should be +% separated from the preceding paragraph (i.e., the caption text). The +% attributes for font and hj setup are comparable to those for the +% caption text itself (except that they will only apply to the +% legend). The only addition is the key \texttt{legend-text} which is +% allowed to take a fixed text (plus any formating and spacing for it) +% which will be added to the front of the legend in case it is +% provided at all (by default it is empty). +%\begin{verbatim} +% legend-sep =L [0pt] \caption@legend@sep , +% legend-text =f0 [] \caption@legend@text, +% legend-font =f0 [\normalfont] \caption@legend@font, +% legend-hj-setup =i {hj} [default] \caption@legend@hj@instance, +% } +%\end{verbatim} +% The actual code for the template should hold few if any +% surprises. In fact it is more or less identical to the one of the +% first template example, except that now we have now taken out some +% of the hardwired decisions and placed them into attributes. +%\begin{verbatim} +% { +% \IfNoValueTF{#2} +% { \cs_set_nopar:Npn \caption@start{\caption@number@format{#1}{#2}} } +% { \cs_set_nopar:Npn \caption@start{\caption@nonumber@format{#1}} } +% \DoParameterAssigments +% \vskip \caption@above@skip \relax +%\end{verbatim} +% To properly measure the caption to determine if it fits a single +% line we have to set it in the right font, so here as well as below +% we have to apply |\caption@font|. +%\begin{verbatim} +% \sbox \@tempboxa {\caption@font \caption@start #3} +% \ifdim \wd\@tempboxa >\hsize +% \begingroup +% \caption@font \caption@hj@instance +% \caption@start #3\par +% \endgroup +% \else +% \global \@minipagefalse +% \hb@xt@\hsize{\caption@single@line@format{\box\@tempboxa}} +% \fi +%\end{verbatim} +% To decide whether or not we have to set any legend we have to test +% |#4| for being |\NoValue|. This part of the code was not present in +% the previous example but otherwise should be straight forward. +%\begin{verbatim} +% \IfNoValueF{#4} +% { +% \vskip \caption@legend@sep \relax +% \begingroup +% \caption@legend@font \caption@legend@hj@instance +% \caption@legend@text +% #4\par +% \endgroup +% } +% \vskip \caption@below@skip \relax +% } +%\end{verbatim} +% +% I wouldn't claim the the above template is good or contains +% everything that would be desired and I'm sure that in the end we +% will have several such template for typesetting the caption part and +% perhaps decide on a different template type in the first place. So +% this is only to give a glimpse of how the template interface could +% be applied and I hope that reading it can see a) how they can apply +% it to other areas as well as see what is wrong with the example +% itself. +% +% To just note one point that i thought of being wrong after writing +% the above paragraphs: the key \texttt{single-line-format} was +% declared to be a function with one argument with the idea that +% besides specifying the single line should be centered (|\hfil|) on +% both sides, or flush left, or flush right (|\hfil| on one side) one +% could also specify something like +%\begin{verbatim} +% single-line-format = \hspace{10pt}#1\hfil, +%\end{verbatim} +% that is a fixed indentation on the left in case where the caption is +% a single line. However, of course one can't. Or at least it is not +% safe to do so since our test in the code tests the width of the line +% without taking into account such a finite fixed space and guess what +% might happen? So in summary, flexibility needs some thought and +% often some afterthoughts as well --- happy thinking :-) +% +% +% +% \subsection{Defining a few instances} +% +% So let us conclude this example with a few sample instances. We +% start with one that repeats what current \LaTeXe{} provides in the +% article class. It shows all keys with values. However in fact only +% the first key is actually needed since all others are the same as +% the default values in the template (and of course a legend is not +% specifiable in standard \LaTeX{} coding so those settings simply do +% not apply anyway). +%\begin{verbatim} +%\DeclareInstance{caption}{article}{lesssimple} +% { +% above-skip = 10pt, +% below-skip = 0pt, +% number-format = #1~#2:~, +% nonumber-format = #1:~, +% single-line-format = \hfil#1\hfil, +% caption-font = \normalfont, +% caption-hj-setup = default, +% legend-sep = 0pt, +% legend-text = , +% legend-font = \normalfont, +% legend-hj-setup = default, +% } +%\end{verbatim} +% +% The next examples are taken from books on the shelf essentially a +% random selection I fear. This one is from \emph{Introduction to +% Database Design} by C.~J.~Date and it uses Helvetica for the caption +% text with the caption flush left, with the figure and the fixed +% string (e.g., `Fig.' in bold face) separated by a quad of space. No +% legend either so this is not set up. The \texttt{hj} instance +% \texttt{noindentflushleft} is supposed to produce a ragged right paragraph +% without any indentation. It would have to be set up elsewhere +% (instance to the template of type \texttt{hj}). +%\begin{verbatim} +%\DeclareInstance{caption}{DATE}{lesssimple} +% { +% above-skip = 10pt, +% below-skip = 0pt, +% number-format = \textbf{#1~#2}\quad, +% nonumber-format = \textbf{#1}\quad, +% single-line-format = #1\hfil, +% caption-font = \fontfamily{phv} \normalfont, +% caption-hj-setup = noindentflushleft, +% } +%\end{verbatim} +% +% The final example is from the book ``Methods of Book Design'' by +% H.~Williamson which sets the caption centered if it fits a single +% line but adjusted as a paragraph without any indentation if longer +% than a single line. It uses old style numerals followed by a period +% for the number (though the example isn't quite right as i guess the +% text font used already has oldstyle numerals as default, so +% |\oldstylenums| is in fact not necessary). +%\begin{verbatim} +%\DeclareInstance{caption}{WILLIAMSON}{lesssimple} +% { +% above-skip = 10pt, +% below-skip = 0pt, +% number-format = #1~\oldstylenums{#2}.~, +% nonumber-format = #1~, +% single-line-format = \hfil#1\hfil, +% caption-font = \normalfont, +% caption-hj-setup = noindentadjusted, +% } +%\end{verbatim} +% +% +% +% \section{Notes} +% +% \subsection{Note on multi-valued parameters} +% +% +% The following code\footnote{docu taken from trial implementation in +% xlists.dtx, FMi} implements for registers (ie L,l,C,c keys) and +% for names (ie n key) a multi-selection mechanism of the following +% form: +% \begin{verbatim} +% key = \MultiSelection \ListDepth { +% \DelayEvaluation {2.5em}, +% 20pt + 34pt } +% { \DelayEvaluation {1em} }, +% \end{verbatim} +% where the first argument to |\MultiSelection| is a counter, the +% second argument is a comma separated list of values denoting the +% values for the cases 1, 2,\ldots, and the third argument contains +% the value for all other cases. +% +% The values are evaluated at declaration time in case of registers +% and therefore can contain calc expressions as well as +% |\DelayEvaluation|. +% +% Due to the implementation the case list is not allowed to have a +% trailing comma! And of course no checks are made whatsoever :-( +% +% A probably much nicer syntax would be something like this: +% \begin{verbatim} +% key = \MultiSelection { +% selector = \ListDepth, +% 1 = \DelayEvaluation {2.5em}, +% 2 = 20pt + 34pt, +% else = \DelayEvaluation {1em} +% }, +% \end{verbatim} +% but i found that too difficult to implement right now. +% +% I think it should also be considered if this kind of thing should be +% a generally available feature on all key types especially on the +% f\meta{number} ones. +% +% Anyway it is what i need for lists right now and as such it is +% sufficient. +% +% +% \subsection{Notes on template restriction} +% +% Possible semantics: +% +% a: just:-) changes the defaults ie the new template has as +% defaults those of its source as modified by the supplied +% keyvals; +% +% b: similar to a: but also removes some keywords ie the new template +% will not accept the keywods whose values are set by the suppied +% keyvals; +% +% c: plan C. +% +% +% Towards an implementation of b: but without a restriction on what +% keys appear where. +% +% +% +% +% \subsection{Open issues} +% +% In this section unresolved issues or ideas to think about and +% perhaps implement are collected. There is no particular order to +% them. +% +% \begin{itemize} +% \item The order of arguments in |\UseCollection| is illogical in my +% eyes! A collection typically modifies the behavior of several +% types and thus should perhaps be first (as it is in the +% |\DeclareCollectionInstance| case). Or not, or what? +% +% \item How should |\IfExistsInstanceTF| behave for Collection +% instances? Do we need a special check for those or a default +% action? Or do we need an additional test for the existence of +% collection instances? +% +% \item It was suggested that the template type declaration should get +% another argument in which (in?)formally the semantics for the +% template types are described, e.g., data type of arguments, +% resulting output, \ldots{} (somewhat like the description arguments +% for functions and variables in Emacs-Lisp). The advantage being +% that this helps employing the templates better as well as perhaps +% guiding context sensitive editors to support the work with such +% templates (e.g., providing help texts). +% +% \item The same might be of interest for the keys of individual +% templates though here syntax support is already available to some +% extend by the declaration of key types. +% +% \item There might be a need to distinguish between \TeX's dimen and +% skip registers. Right now this is not done and both |l| and |L| +% accepts what \LaTeX{} calls ``rubber length'' specifications. +% +% \item The type |b| can probably vanish. It is equivalent to +% specifying the mutators of a |\newif| command in the brace groups, +% e.g. +%\begin{verbatim} +% numbered-boolean =b [true] @heading@nums, +% numbered-boolean =s [true] {\@heading@numstrue} +% {\@heading@numsfalse}, +%\end{verbatim} +% +% \item See issue raised about syntax (and semantics) for +% |\Multiselection|. +% +% \item |f0| keys should perhaps support |\UseTemplate| by replacing +% it with its internal form. or perhaps this is a rubbish idea? +% +% \item Marcin Wolinski suggested to use |\EvalOnUse| instead or in +% addition to |\DelayEvalutation|. +% +% \end{itemize} +% +% \StopEventually{} +% +% \section{Implementation} +% \begin{macrocode} +%<*package> +\ProvidesExplPackage + {\filename}{\filedate}{\fileversion}{\filedescription} +% \end{macrocode} +% +% \begin{macrocode} +\RequirePackage{expl3} +\RequirePackage{ldcsetup,xparse} +% \end{macrocode} +% +% +% Declare a private token register for building parameter lists. +% Having the number saves a few expandafters +% (probably not needed in the end). +% \begin{macrocode} +\toks_new:N\l_TP_KV_assignments_toks +\toks_new:N\l_TP_default_assignments_toks +% \end{macrocode} +% +% +% +% \begin{macro}{\TP_declare_instance:Nnn} +% \begin{macro}{\TP_declare_instance:cnn} +% Declare a command name to be an instance of a template +% ie with a particular setting of the parameters.\\ +% |#1| internal command name for instance to be (globally) declared\\ +% |#2| template type/template name\\ +% |#3| key value assignments for parameters of |#2| +% \begin{macrocode} +\cs_new_nopar:Nn \TP_declare_instance:Nnn { + \group_begin: + \TP_instdecl_generate_assignments:nn {#2}{#3} + \cs_gset_nopar:Npx #1 { + \tl_if_eq:cNTF { TP>/#2 } \c_TP_doparameterassignments_tl +% \end{macrocode} +% If the body of the template consists only of the token +% |\DoParameterAssignments|, then we insert the list of parameter +% assignments directly. Otherwise we have push them onto the stack +% and prepare to execute the body code (which in turn will pop them +% again when it reaches |\DoParameterAssignments| inside). +% \begin{macrocode} + { \toks_use:N \l_TP_KV_assignments_toks } + { + \exp_not:N \TP_push_assignments:n + {\toks_use:N\l_TP_KV_assignments_toks} + \exp_not:c {TP>/#2} + } + } + \group_end:} +\cs_generate_variant:Nn \TP_declare_instance:Nnn {cnn} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\c_TP_doparameterassignments_tl} +% \begin{macrocode} +\tl_set:Nn \c_TP_doparameterassignments_tl {\DoParameterAssignments} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\UseTemplate} +% |{type}{templatename}{keyval}| +% Directly use a template with a particular parameter setting. +% This is also picked up if used in a nested fashion inside a parameter +% list.\\ +% |#1| type of a template.\\ +% |#2| name of a template.\\ +% |#3| key value assignments for parameters of |#1|. +% \begin{macrocode} +\cs_new_nopar:Npn \UseTemplate #1#2#3{ + \TP_instdecl_generate_assignments:nn {#1/#2}{#3} + \TP_push_assignments: + \use:c { TP>/#1/#2 } +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\DoParameterAssignments} +% Access the parameter assignment list that was once stored in +% |\l_TP_KV_assignments_toks| and then moved onto the +% |\g_TP_assignments_stack_toks|. +% \begin{macrocode} +\cs_new_nopar:Npn \DoParameterAssignments{ + \exp_after:wN + \TP_pop_and_execute_assignments:nw + \toks_use:N \g_TP_assignments_stack_toks \q_stop +} +% \end{macrocode} +% +% \end{macro} +% +% \begin{macro}{\TP_pop_and_execute_assignments:nw} +% \begin{macrocode} +\cs_new_nopar:Npn \TP_pop_and_execute_assignments:nw#1#2\q_stop{ + \toks_gset:Nn \g_TP_assignments_stack_toks {#2} + #1} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\g_TP_assignments_stack_toks} +% \begin{macrocode} +\toks_new:N \g_TP_assignments_stack_toks +\toks_gset:Nn \g_TP_assignments_stack_toks {\scan_stop:}% avoid brace loss +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TP_push_assignments:n} +% \begin{macro}{\TP_push_assignments:} +% Push a list of parameter assignments onto the +% |\g_TP_assignments_stack_toks|. As it all happens in token +% registers |#|s need no doubling. |\TP_push_assignments:| expects +% it to be |\l_TP_KV_assignments_toks| (needs fixing). +% \begin{macrocode} +\cs_new:Npn \TP_push_assignments:n#1{ + \toks_gput_left:Nn\g_TP_assignments_stack_toks{{#1}} +} +\cs_new_nopar:Npn \TP_push_assignments:{ + \toks_gset:No \g_TP_assignments_stack_toks + {\exp_after:wN + {\toks_use:N\exp_after:wN\l_TP_KV_assignments_toks\exp_after:wN} + \toks_use:N\g_TP_assignments_stack_toks} +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\DeclareTemplateType} +% |{type}{nofarg}| +% \begin{macrocode} +\cs_new_nopar:Npn \DeclareTemplateType #1#2{ + \tl_set:cn {TP@<#1>} {{}#2}} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\TP_get_csname_prefix:n} +% |{type}| returns prefix for csnames for template type, +% based on current collection. +% \begin{macrocode} +\cs_new_nopar:Nn \TP_get_csname_prefix:n { + <\exp_after:wN\exp_after:wN\exp_after:wN + \use_i:nn + \cs:w TP@<#1>\cs_end:>#1/ +} +% \end{macrocode} +% +% \end{macro} +% +% \begin{macro}{\TP_get_arg_count:n} +% |{type}| returns arg count for the template type. +% \begin{macrocode} +\cs_new_nopar:Nn \TP_get_arg_count:n { + \exp_after:wN\exp_after:wN\exp_after:wN + \use_ii:nn + \cs:w TP@<#1>\cs_end: +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\DeclareTemplate} +% |{type}{templatename}{nofarg}{keywordspec}{code}| +% \begin{macrocode} +\cs_new:Npn\DeclareTemplate #1#2#3#4#5{ + \cs_if_free:cTF{TP@<#1>} + {\undefinedtype\DeclareTemplateType{#1}#3} + { + \intexpr_compare:nNnF{#3}={\TP_get_arg_count:n{#1}} + { \BadArgCount } + } +% \end{macrocode} +% Parse the key declaration, and execute the list with a suitable +% definition of |\KV@elt|. +% \begin{macrocode} + \cs_set_eq:NN \KV_elt:nn \TP_templdecl_process_KV:nn + \cs_set_nopar:Npn \KV_default_elt:n##1{ + \PackageError{template}{Missing~ =~ after~ ##1}\@ehd} + \cs_set_eq:NN\KV@elt\KV_elt:nn + \cs_set_eq:NN\KV@default@elt\KV_default_elt:n + \tl_set:Nn \l_TP_curr_name_tl {#1/#2} + \toks_clear:N\l_TP_default_assignments_toks +% \end{macrocode} +% At this point there should be a test for which catcode regime we are +% in. We just test if spaces are ignored. +% \begin{macrocode} + %\intexpr_compare:nNnTF{\char_value_catcode:n{`\ }}=\c_nine + %\KV_parse_picky_no_space_removal_no_sanitize:n + %\KV_parse_picky_space_removal_no_sanitize:n + \KV@parse{#4} +% \end{macrocode} +% +% Define the defaults: the setting for |TPD>/\l_TP_curr_name_tl| is a +% tricky since |\l_TP_default_assignments_toks| may contain |#|. We +% have to use an |x| expansion rather than +% |o| since that will hide those during the assignment. +% FIX THIS (see below)! +% \begin{macrocode} + \cs_set_nopar:cpx { TPD>/\l_TP_curr_name_tl } + {\toks_use:N\l_TP_default_assignments_toks} + + \tl_clear:c {TPR>/\l_TP_curr_name_tl} + + \tl_set_eq:cN {TPO>/\l_TP_curr_name_tl}\l_TP_curr_name_tl +% \end{macrocode} +% +% Define the template (using |\cs_new_nopar:Npn| means that one can't +% redefine a template easily). +% \begin{macrocode} + \cs_generate_from_arg_count:cNnn {TP>/\l_TP_curr_name_tl} + \cs_set:Npn {#3}{#5} +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tl_set:cx} +% FIX this: The code above only works because in the past |\tl_set:cx| was +% defined as follows: +% \begin{macrocode} +\cs_set:Npn \tl_set:cx {\exp_args:Nc \tl_set:Nx} +% \end{macrocode} +% i.e., expanding the second arg at the very end. +% This is no longer the case but for the moment I revert to the old +% definition until the template code is fixed to not rely on |\tl_set:cx| +% expanding the second arg at the very last minute. +% \end{macro} +% +% \begin{macro}{\TP_templdecl_process_KV:nn} +% The list of undefined keys and values is put in the list of the form\\ +% |\KV_elt:nn|\marg{key1}\marg{val1}%^^A +% |\KV_elt:nn|\marg{key2}\marg{val2}\ldots\\ +% So just need to give this macro a suitable definition. We just need +% to look at the first token of the value, to see what sort of key +% it is, so call a helper function to split that off. +% \begin{macrocode} +\cs_new_nopar:Nn \TP_templdecl_process_KV:nn {% + \cs_set_eq:NN \TP_templdecl_add_global_or_nothing: \prg_do_nothing: + \bool_set_false:N\l_TP_global_assignment_bool + \tl_set:Nn\l_TP_currkey_tl{#1} + \TP_templdecl_parse_KV:N#2\q_stop} +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\TP_templdecl_parse_KV:N} +% Case switch on the possible key types. +% \begin{macrocode} +\cs_new_nopar:Nn \TP_templdecl_parse_KV:N { +% \end{macrocode} +% In |#1| we have key, in |#2| the first character after the equal +% sign and in |#3| the remainder of the line. We now have to parse +% that remainder to find out if it contains a default value (in +% brackets) and then set up the key declaration needed to parse +% instance declarations. The method is similar in most cases: we call +% |\TP_parse_optional_key_default:nw| which parses for the default +% and pass it already found key name as first argument, what to do in +% the end as second argument, and the remainder delimited by |\q_stop| +% so that it becomes parseable. +% +% Note that the code in the second argument to +% |\TP_parse_optional_key_default:nw| normally calls on a macro with +% one more argument than actually provided: the reason being that the +% missing argument will be the remainder of the line (added by +% |\TP_parse_optional_key_default:nw| after the default has be +% removed (if present)). +% \begin{macrocode} + \cs_if_free:cTF{TP_use_arg_type_#1:w} + {\PackageError{template}{Unknown~key~type~ (#1)~for~\l_TP_currkey_tl}\@eha} + {\use:c{TP_use_arg_type_#1:w}} +% \end{macrocode} +% The |f| and |i| keys are somewhat different since there we first +% have to parse for an additional argument (a digit in case of |f| +% or an template type name in case of |i|): +% \begin{macrocode} +% \end{macrocode} +% One more alternative: a |+| after the equal sign signals global +% so we change |\TP_templdecl_add_global_or_nothing:| to append a +% |\pref_global:D| to the assignment toks and then reparse the rest. +% \begin{macrocode} +% \cs_set_nopar:Npn \TP_templdecl_add_global_or_nothing: +% {\toks_put_right:Nn \l_TP_KV_assignments_toks {\pref_global:D} } +% \TP_templdecl_parse_KV:nw{#1}#3\TP_templdecl_parse_KV:nnw +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\l_TP_global_assignment_bool} +% For keeping track of the assignments. +% \begin{macrocode} +\bool_new:N \l_TP_global_assignment_bool +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TP_use_arg_type_+:w} +% The |+| does two things: Sets a boolean true to be used by the +% types that can't simply be prefixed with |\pref_global:D| and +% defines |\TP_templdecl_add_global_or_nothing:| to put the prefix +% onto the list. After that we simply call the big switch +% again.\footnote{It should probably all be changed to not rely on +% the prefix working}. +% \begin{macrocode} +\cs_new_nopar:cpn{TP_use_arg_type_+:w} { + \bool_set_true:N\l_TP_global_assignment_bool + \cs_set_nopar:Npn \TP_templdecl_add_global_or_nothing: + {\toks_put_right:Nn \l_TP_KV_assignments_toks {\pref_global:D} } + \TP_templdecl_parse_KV:N +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TP_use_arg_type_l:w} +% The |l| sets a length register. We disable the prefix and insert +% either |\gsetlength| or |\setlength| depending on whether a |+| +% was seen or not. +% \begin{macrocode} +\cs_new_nopar:Npn\TP_use_arg_type_l:w { + \TP_parse_optional_key_default:nw + { + \cs_set_eq:NN \TP_templdecl_add_global_or_nothing: \prg_do_nothing: + \bool_if:NTF \l_TP_global_assignment_bool + {\TP_templdecl_setup_register_key:Nn\gsetlength} + {\TP_templdecl_setup_register_key:Nn\setlength} + } +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TP_use_arg_type_L:w} +% The |L| sets a fake length register. +% \begin{macrocode} +\cs_new_nopar:Npn\TP_use_arg_type_L:w { + \TP_parse_optional_key_default:nw + {\TP_templdecl_setup_fakeregister_key:NNn\setlength\l_tmpa_skip} +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TP_use_arg_type_c:w} +% The |c| sets a count register. +% \begin{macrocode} +\cs_new_nopar:Npn\TP_use_arg_type_c:w { + \TP_parse_optional_key_default:nw + { + \cs_set_eq:NN\TP_templdecl_add_global_or_nothing:\prg_do_nothing: + \bool_if:NTF \l_TP_global_assignment_bool + {\TP_templdecl_setup_register_key:Nn\GSetInternalCounter} + {\TP_templdecl_setup_register_key:Nn\SetInternalCounter} + } +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TP_use_arg_type_C:w} +% The |C| sets a fake count register. +% \begin{macrocode} +\cs_new_nopar:Npn\TP_use_arg_type_C:w { + \TP_parse_optional_key_default:nw + {\TP_templdecl_setup_fakeregister_key:NNn + \SetInternalCounter\l_tmpa_int} +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TP_use_arg_type_n:w} +% The |n| sets a token list variable. +% \begin{macrocode} +\cs_new_nopar:Npn\TP_use_arg_type_n:w { + \TP_parse_optional_key_default:nw + {\TP_templdecl_setup_n_key:N} +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TP_use_arg_type_f:w} +% \begin{macro}{\TP_templdecl_parse_f_arg:nw} +% The |f| defines a command with between 0 and 9 arguments. +% \begin{macrocode} +\cs_new_nopar:Npn\TP_use_arg_type_f:w #1{ + %\TP_templdecl_parse_f_arg:nw {#1} + \TP_parse_optional_key_default:nw{\TP_templdecl_setup_f_key:Nn{#1}} +} +% \end{macrocode} +% Helper for |\TP_templdecl_parse_KV:nnw|. +% \begin{macrocode} +\cs_new_nopar:Npn \TP_templdecl_parse_f_arg:nw#1#2{ +% \end{macrocode} +% The third argument of |\TP_templdecl_setup_f_key:Nn|, i.e., the +% macro name, is the remaining data up to |\q_stop| which is picked up +% by |\TP_parse_optional_key_default:nw|. +% \begin{macrocode} + \TP_parse_optional_key_default:nw{\TP_templdecl_setup_f_key:Nn{#1}{#2}} +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\TP_use_arg_type_b:w} +% \begin{macro}{\TP_templdecl_setup_b_key:nn} +% The |b| uses access to the |\if_true:| and |\if_false:| +% primitives. Needed? +% \begin{macrocode} +\cs_new_nopar:Npn\TP_use_arg_type_b:w { + \TP_parse_optional_key_default:nw + {\TP_templdecl_setup_b_key:n} +} +% \end{macrocode} +% +% \begin{macrocode} +\cs_new_nopar:Npn \TP_templdecl_setup_b_key:n#1{ + \cs_set_eq:cN { if#1 } \if_true: + \TP_templdecl_define_key:n + { \TP_templdecl_eval_b_key_value:nn {#1}{##1} } +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\TP_templdecl_eval_b_key_value:nn} +% Modify so the boolean does not need to have been +% declared with |\newif| +% \begin{macrocode} +\cs_new_nopar:Npn \TP_templdecl_eval_b_key_value:nn#1#2{ + \cs_if_free:cTF {if#2} + { \PackageError{template}{Bad~boolean~setting~#1=#2}\@eha } + { \tl_set_eq:cc {if_#1:}{if_#2:} + \toks_put_right:Nf \l_TP_KV_assignments_toks + { \tl_set_eq:cc {if_#1:}{if_#2:} } + } +} +% \end{macrocode} +% +% \end{macro} +% +% \begin{macro}{\TP_use_arg_type_s:w} +% \begin{macro}{\TP_templdecl_setup_s_key:n} +% The |s| chooses between true and false. +% \begin{macrocode} +\cs_new_nopar:Npn\TP_use_arg_type_s:w { + \TP_parse_optional_key_default:nw + {\TP_templdecl_setup_s_key:n} +} +% \end{macrocode} +% \begin{macrocode} +\cs_new_nopar:Npn \TP_templdecl_setup_s_key:n #1 { + \TP_templdecl_define_key:n + { \TP_templdecl_eval_s_key_value:nnn{##1}#1 } +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% +% +% +% +% +% \begin{macro}{\TP_use_arg_type_i:w} +% The |i| expects an instance. +% \begin{macrocode} +\cs_new_nopar:Npn\TP_use_arg_type_i:w #1{ + \TP_parse_optional_key_default:nw{\TP_templdecl_setup_i_key:nnn{#1}} +} +% \end{macrocode} +% +% declaration |hd =i{head} \fooo| \\ +% use |hd = mine|\\ +% makes |\fooo| shorthand for |\UseInstance{head}{mine}| +% +% also allowed: |hd = \UseTemplate{head}{...}{...}|\\ +% in case you want to use an unnamed instance of type |head| +% in this place. +% \end{macro} +% +% \begin{macro}{\TP_templdecl_setup_i_key:nnn} +% MH change: do either local or global. +% \begin{macrocode} +\cs_new_nopar:Npn \TP_templdecl_setup_i_key:nnn#1#2{ + \TP_templdecl_define_key:n + { + \TP_templdecl_eval_i_key_value:Nnn #2 {#1}{##1} + } +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TP_templdecl_eval_i_key_value:Nnn} +% MH change: Add extra argument for local or global. +% \begin{macrocode} +\cs_new_nopar:Npn \TP_templdecl_eval_i_key_value:Nnn #1#2#3 { + \tl_if_head_eq_meaning:nNTF {#3.}\UseTemplate + { + \iow_term:x{\token_to_str:N\UseTemplate\space seen} +% \end{macrocode} +% +% Code below from |\TP_templdecl_setup_f_key:Nn| (should be +% combined and cleaned up) +% at this point one should also check if first arg of |\UseTemplate| +% corresponds to |#2| and if not complain (not done) +% +% \begin{macrocode} + {\TP_templdecl_declare_tmp_instance:nnnn #3 } + \toks_put_right:No \l_TP_KV_assignments_toks + { \exp_after:wN \KV@toks \exp_after:wN {\g_tmpa_tl} } + %\TP_templdecl_add_global_or_nothing: + %\toks_put_right:Nn \l_TP_KV_assignments_toks + % { \cs_set_nopar:Npx #1{ \toks_use:N \KV@toks} } + \bool_if:NTF \l_TP_global_assignment_bool + {\toks_put_right:Nn \l_TP_KV_assignments_toks + {\cs_gset_nopar:Npx #1 { \toks_use:N \KV@toks}} + } + {\toks_put_right:Nn \l_TP_KV_assignments_toks + {\cs_set_nopar:Npx #1 { \toks_use:N \KV@toks}} + } + } + { + \TP_let_instance:Nnn#1{#2}{#3} +% \end{macrocode} +% We want the |\cs_set_eq:Nc| hiding in |\TP_let_instance:Nnn| to expand +% fully to two csnames so we put a |\tex_romannumeral:D 0| (which in +% itself expands to nothing) in front. This expands the |\cs_set_eq:Nc| fully +% before finding out that |\cs_set_eq:NwN| is not expandable. +% \begin{macrocode} + \toks_put_right:Nf \l_TP_KV_assignments_toks + { \TP_let_instance:Nnn#1{#2}{#3} } + } +} +% \end{macrocode} +% \end{macro} +% +% +% +% +% +% +% +% +% \begin{macro}{\TP_use_arg_type_x:w} +% \begin{macro}{\TP_templdecl_setup_x_key:nn} +% The |x| runs internal code. +% \begin{macrocode} +\cs_new_nopar:Npn\TP_use_arg_type_x:w { + \TP_parse_optional_key_default:nw + {\TP_templdecl_setup_x_key:n} +} +% \end{macrocode} +% +% \begin{macrocode} +\cs_new_nopar:Npn \TP_templdecl_setup_x_key:n#1{ + \TP_templdecl_define_key:n + { \toks_put_right:Nn\l_TP_KV_assignments_toks{#1} } +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% +% +% +% \begin{macro}{\TP_use_arg_type_g:w} +% \begin{macro}{\TP_templdecl_setup_g_key:nn} +% The |g| runs any code. +% \begin{macrocode} +\cs_new_nopar:Npn\TP_use_arg_type_g:w { + \TP_parse_optional_key_default:nw + {\TP_templdecl_setup_g_key:n} +} +% \end{macrocode} +% +% \begin{macrocode} +\cs_new_nopar:Npn \TP_templdecl_setup_g_key:n #1 { + \TP_templdecl_define_key:n{#1}} +% \end{macrocode} +% +% \end{macro} +% \end{macro} +% +% +% +% +% \begin{macro}{\TP_templdecl_define_key:n} +% Here we define the key in the current template. Original code from +% r522 is essentially unreadable but we keep it here until the +% internal structure is finally sorted out. +% \begin{macrocode} +\cs_new_nopar:Npn \TP_templdecl_define_key:n#1{ + \exp_after:wN \cs_set:Npn \cs:w + KV@\l_TP_curr_name_tl @\l_TP_currkey_tl + \exp_after:wN\cs_end: + \exp_after:wN##\exp_after:wN1\exp_after:wN{ + \exp_after:wN\TP_templdecl_remove_from_default_assignments:N + \cs:w KV@\l_TP_curr_name_tl @\l_TP_currkey_tl + \exp_after:wN \cs_end: + \TP_templdecl_add_global_or_nothing: + #1 + } +} +% \end{macrocode} +% \end{macro} +% +% +% +% +% +% +% +% +% +% +% \begin{macro}{\TP_parse_optional_key_default:nw} +% Look for default value. +% \begin{macrocode} +\cs_set:Npn \TP_ignore_leading_space_in_arg_ii:nn#1#2{ + \exp_args:Nf\TP_ignore_leading_space_in_arg_ii_aux:nn + {\exp_not:N #2}{#1} +} +\cs_set:Npn \TP_ignore_leading_space_in_arg_ii_aux:nn#1#2{#2{#1}} + + +\DeclareDocumentCommand\TP_parse_optional_key_default:nw{mo}{ + \IfNoValueTF{#2} + {\TP_templdecl_finish_key_setup:nw{#1}} + {\TP_templdecl_finish_key_setup_with_default:nnw{#1}{#2}} +} +%\show\TP_parse_optional_key_default:nw +%\exp_args:Nc\show{\string\TP_parse_optional_key_default:nw} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TP_templdecl_finish_key_setup:nw} +% After having parsed the line and not found any default value it +% remains to actually define the key for the instance parsing by +% executing the setup code (in |#1|) giving it |#2| (i.e., the +% remainder of the line) as an argument. +% \begin{macrocode} +\cs_new_nopar:Npn \TP_templdecl_finish_key_setup:nw#1#2\q_stop{ + \TP_ignore_leading_space_in_arg_ii:nn{#1}{#2} + %%%#1{#2} +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TP_templdecl_finish_key_setup_with_default:nnw} +% If there is a default the situation is more complicated since we +% not only have to set up the key for the instance but also have to +% add the default value to |\l_TP_default_assignments_toks| in an +% appropriate way. +% +% First set up the the key itself: +% \begin{macrocode} +\cs_new_nopar:Npn \TP_templdecl_finish_key_setup_with_default:nnw#1#2#3\q_stop{ + \TP_ignore_leading_space_in_arg_ii:nn{#1}{#3} + %%% #1 {#3} +% \end{macrocode} +% Now we run the new key code (which is stored in |\KV@...| hopefully) +% and give it the default found. By doing this in a group and by +% locally emptying |\l_TP_KV_assignments_toks| we will get the +% resulting assignment code into that register. +% +% (We set |\TP_templdecl_remove_from_default_assignments:N| to +% |\use_none:n| since this is a temporary operation and we don't want +% to change the default really.) +% \begin{macrocode} + \group_begin: + \toks_clear:N \l_TP_KV_assignments_toks + \cs_set_eq:NN \TP_templdecl_remove_from_default_assignments:N \use_none:n + \use:c{KV@\l_TP_curr_name_tl @\l_TP_currkey_tl}{#2} +% \end{macrocode} +% And now for a final trick: before closing the group again and losing +% our local changes we run |\exp_after:wN| several times to get the +% value of |\l_TP_KV_assignments_toks| into +% |\l_TP_default_assignments_toks| outside that group! +% \begin{macrocode} + \exp_after:wN + \group_end: + \exp_after:wN + \toks_set:Nn + \exp_after:wN + \l_TP_default_assignments_toks + \exp_after:wN + { \cs:w KV@\l_TP_curr_name_tl @\l_TP_currkey_tl \exp_after:wN \cs_end: + \exp_after:wN + { \toks_use:N \exp_after:wN \l_TP_KV_assignments_toks + \exp_after:wN + } + \toks_use:N\l_TP_default_assignments_toks + } +} +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\c_TP_true_tl} +% \begin{macrocode} +\tl_new:Nn \c_TP_true_tl {true} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TP_templdecl_eval_s_key_value:nnn} +% \begin{macrocode} +\cs_new_nopar:Npn \TP_templdecl_eval_s_key_value:nnn#1#2#3 { +% no error check on this yet. + \tl_set:Nn \l_tmpa_tl {#1} + \tl_if_eq:NNTF \l_tmpa_tl \c_TP_true_tl + { \toks_put_right:Nn \l_TP_KV_assignments_toks {#2} } + { \toks_put_right:Nn \l_TP_KV_assignments_toks {#3} } +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TP_templdecl_setup_register_key:Nnn} +% This is normally called automatically by |\DeclareTemplate|. +% +% Command for setting a template attribute whose name +% corresponds directly to a \TeX{} count or length register\\ +% |#1| the function to set the value eg \cs{setlength}.\\ +% |#2| key name.\\ +% |#3| the register to set. +% +% This command \emph{fully evaluates} the argument at declare time, +% and assigns the value to the register. It also passes an assignment +% of the register to the final value into the parameter list for the +% template. +% +% If the value is a call to |\DelayEvaluation|, don't evaluate it now, +% just pass the whole assignment to the template. Remember to remove +% the |\DelayEvaluation|. +% \begin{macrocode} +\cs_new_nopar:Npn \TP_templdecl_setup_register_key:Nn #1#2{ + \TP_templdecl_define_key:n{ + \tl_if_head_eq_meaning:nNTF{##1}\DelayEvaluation + { +% \end{macrocode} +% Old line commented out. Remove |\DelayEvaluation| and also remove +% the braces surrounding its argument. +% \begin{macrocode} + \toks_put_right:Nn \l_TP_KV_assignments_toks {#1#2{##1}} + %\toks_set:No\l_tmpa_toks{\use_ii:nn ##1} + %\toks_put_right:Nx \l_TP_KV_assignments_toks + % {\exp_not:n{#1#2}{\toks_use:N \l_tmpa_toks}} + } +% \end{macrocode} +% +% +% check for |\MultiSelection| creeping up and if so add something like +% +% \begin{verbatim} +% \setlength\register{\ifcase\selector \or value1 \or value2 +% ... \else valueotherwise \fi} +% \end{verbatim} +% to |\l_TP_KV_assignments_toks|. +% +% \begin{macrocode} + { + \tl_if_head_eq_meaning:nNTF{##1..}\MultiSelection + { + \group_begin: + \TP_multiselection_add:nnnnnn #1#2##1 + \group_end: +% \end{macrocode} +% +% +% there are probably better ways to do this (:-) +% +% \begin{macrocode} + \tl_if_in:onTF{\toks_use:N\g_TP_multiselection_toks}\DelayEvaluation + { + \toks_put_right:No\l_TP_KV_assignments_toks + { + \exp_after:wN#1\exp_after:wN#2\exp_after:wN + {\toks_use:N\g_TP_multiselection_toks} + } + } + { + \toks_put_right:No\l_TP_KV_assignments_toks + { + \exp_after:wN #2 + \exp_after:wN= \toks_use:N\g_TP_multiselection_toks\scan_stop: + } + } +% \end{macrocode} +% +% +% otherwise do as before +% +% \begin{macrocode} + } + { + #1#2{##1} + \toks_put_right:No\l_TP_KV_assignments_toks { + \exp_after:wN #2 \exp_after:wN = \tex_the:D #2\scan_stop: + } + } + } + } +} +% \end{macrocode} +% \end{macro} +% +% +% +% +% +% +% \begin{macro}{\DelayEvaluation} +% \begin{macro}{\MultiSelection} +% Since we are testing explicitly for |\DelayEvaluation| and +% |\MultiSelection| a few places we better give them unique +% meanings! +% \begin{macrocode} +\cs_new_nopar:Npn\DelayEvaluation #1{\use_none:n{\DelayEvaluation}#1} +\cs_new_nopar:Npn\MultiSelection #1{\use_none:n{\MultiSelection}#1} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\TP_templdecl_remove_from_default_assignments:N} +% Note: the toks register is more or less a plists and should +% perhaps be implemented as such as this would make far more +% readable code. +% \begin{macrocode} +\cs_new_nopar:Npn \TP_templdecl_remove_from_default_assignments:N#1{ + \cs_set_nopar:Npn \TP_tmp:w ##1#1##2##3#1##4\q_stop{ + \l_TP_default_assignments_toks{##1##3} + } + \exp_after:wN \TP_tmp:w + \toks_use:N\l_TP_default_assignments_toks #1\scan_stop:#1\q_stop} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TP_templdecl_setup_f_key:Nn} +% Same for macro names. Again usually called automatically when +% declaring a new template.\\ +% |#1| Determines how many arguments the function should have.\\ +% |#2| The macro to be defined. +% +% If the `|##1|`, the value passed as the argument of the key +% to the macro |#2| is invoked starts with |\FunctionInstance|, then a +% special procedure is taken. Instead of defining a macro with the +% specified number of arguments, the paramater list of the nested +% function instance is parsed, and |#2| is defined to be a macro +% expanding to that instance. In this case the specified template +% is responsible for picking up the requested number of +% arguments. (This is \emph{not} checked.) +% \begin{macrocode} +\cs_new_nopar:Npn \TP_templdecl_setup_f_key:Nn#1#2{ +% \end{macrocode} +% +% |##1| can either be arbitrary inline code, in which case it will be +% defined with something similar to |\newcommand[val]| so it needs to +% use |#1| -- |#val|. +% +% define it locally here (why this, David???) +% \begin{macrocode} + \TP_templdecl_define_key:n + { \TP_templdecl_define_function:NNn#1#2{##1} } +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\TP_templdecl_define_function:NNn} +% Use number of arguments to define function. +% \begin{macrocode} +\cs_new_nopar:Npn \TP_templdecl_define_function:NNn#1#2#3{ + \cs_generate_from_arg_count:NNnn #2 \cs_set:Npn {#1}{#3} + \toks_put_right:Nf \l_TP_KV_assignments_toks { + \cs_generate_from_arg_count:NNnn #2 \cs_set:Npn {#1}{#3} + } +} +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\TP_templdecl_setup_n_key:N} +% Here is the extended version that tries to deal with +% |\MultiSelection|. +% +% In case of `n' keys there is no evaluation at declaration time so it +% is not sensible to look for |\DelayEvaluation|. For this reason as +% well as for the fact that |\TP_multiselection_add:nnnnnn| above +% assumes that it deals +% with registers that can be accessed via |\toks_use:N| we have to use a +% different command to handle the |\MultiSelection| args but +% it is essentially doing the same. +% +% \begin{macrocode} +\cs_new_nopar:Npn \TP_templdecl_setup_n_key:N#1{ + \TP_templdecl_define_key:n{ + \tl_if_head_eq_meaning:nNTF{##1..}\MultiSelection + { + \group_begin: + \TP_templdecl_multiselection:nnnn ##1 + \group_end: +% \end{macrocode} +% Extracting the correct item from the |\if_case:w| we are building +% requires a bit of care. Firstly we want to expand the appropirate +% number of times to get to the item but we also want to ensure we do +% not have any unwanted leftover |\fi:|s or other junk which is bound +% to cause errors later on. Therefore we start an |f| expansion (so we +% don't have to count |\exp_after:wN|s and then stop it again when we +% want to. +% \begin{macrocode} + \toks_put_right:Nx\l_TP_KV_assignments_toks { + \exp_not:n{\tl_set:Nf #1} { \toks_use:N \g_TP_multiselection_toks} + } + } + { + \cs_set_nopar:Npn #1{##1} % setting it? + \toks_put_right:Nn \l_TP_KV_assignments_toks + { \tl_set:Nn #1{##1} } + } + } +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TP_templdecl_multiselection:nnnn} +% Start the |\if_case:w|. When the item is retrieved using an |f| +% type expansion we better stop it at the right place once we have +% emerged on the other side of the conditional. +% \begin{macrocode} +\cs_new_nopar:Npn \TP_templdecl_multiselection:nnnn #1#2#3#4{ + \toks_gset:Nn \g_TP_multiselection_toks {\if_case:w #2} + \clist_map_inline:nn {#3}{ + \TP_multiselection_add_or_case:n {\exp_stop_f:##1} + } + \toks_gput_right:Nn\g_TP_multiselection_toks { + \else: \use_i_after_fi:nw { \exp_stop_f: #4} \fi: + } +} +% \end{macrocode} +% \end{macro} +% +% +% +% +% +% +% +% +% \begin{macro}{\DeclareInstance} +% |{type}{instname}{templatename}{keyval}| +% \begin{macrocode} +\cs_new_nopar:Npn \DeclareInstance { \DeclareCollectionInstance{} } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\DeclareCollectionInstance} +% |{collection}{type}{instname}{templatename}{keyval}| +% The fifth argument is picked up implicitly. +% \begin{macrocode} +\cs_new:Npn \DeclareCollectionInstance#1#2#3#4{ + \TP_declare_instance:cnn { <#1>#2/#3 }{ #2/#4 } +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\UseCollection} +% |{type}{collection}| +% \begin{macrocode} +\cs_new_nopar:Npn \UseCollection#1#2{ + \tl_set:cx { TP@<#1> } + { {#2} \TP_get_arg_count:n{#1} } +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TP_let_instance:Nnn} +% |\internalcommand{type}{instname}| +% +% The way this macro is used, it must result in |\cs_set_eq:NwN| || +% || after exactly two expansions as it is used this way +% in |\TP_templdecl_eval_i_key_value:nnn|! +% \begin{macrocode} +\cs_new_nopar:Npn \TP_let_instance:Nnn#1#2#3{ + \cs_set_eq:Nc #1 + { + \cs_if_free:cTF { \TP_get_csname_prefix:n{#2} #3 } + { <>#2/ } + { \TP_get_csname_prefix:n{#2} } + #3 + } +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\UseInstance} +% |{type}{instname}| +% \begin{macrocode} +\cs_new_nopar:Npn \UseInstance#1#2{ + \TP_let_instance:Nnn \l_tmpa_tl {#1}{#2} + \tl_if_eq:NNTF \l_tmpa_tl \scan_stop: + \INSTANCEundefined + \l_tmpa_tl +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TP_templdecl_declare_tmp_instance:nnnn} +% This macro is called when we have seen a |\UseTemplate| +% declaration as part of an |i| key value. Therefore the +% first argument will be dropped (it contains the token +% |\UseTemplate|) the second and third will be combined to refer to +% the template and the fourth argument will be implictly picked up +% by |\TP_declare_instance:Nnn|. +% \begin{macrocode} +\cs_new:Npn \TP_templdecl_declare_tmp_instance:nnnn#1#2#3{% + \TP_declare_instance:Nnn \g_tmpa_tl {#2/#3} } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\ShowTemplate} +% Some extension to |\ShowTemplate| so that we also get to see the +% restrictions if any +% \begin{macrocode} +\cs_new_nopar:Npn \ShowTemplate#1#2{ + \iow_term:x{*******~ Template:~ #1/#2~ *******} + \iow_term:x{*} + \iow_term:x{*~ Defaults:} + \iow_term:x{*} + \iow_term:x{\token_to_str:N\TPD>/#1/#2= + \cs_meaning:c{TPD>/#1/#2}} + \iow_term:x{*} + \iow_term:x{*~ Restrictions:} + \iow_term:x{*} + \iow_term:x{\token_to_str:N\TPR>/#1/#2= + \cs_meaning:c{TPR>/#1/#2}} + \iow_term:x{*} + \iow_term:x{*~ Body:} + \iow_term:x{*} + \cs_show:c {TP>/#1/#2}} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\ShowCollectionInstance} +% \begin{macrocode} +\cs_new_nopar:Npn \ShowCollectionInstance#1#2#3{ + \iow_term:x{*******~ Instance:~ <#1>#2/#3~ *******} + \iow_term:x{*} + \cs_show:c {<#1>#2/#3}} +\cs_new_nopar:Npn \ShowInstance{\ShowCollectionInstance{}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TP_templdecl_setup_fakeregister_key:NNn} +% |{setcomand}{privateregister}{key}{internalcode}| +% \begin{macrocode} +\cs_new_nopar:Npn \TP_templdecl_setup_fakeregister_key:NNn#1#2#3{ + \TP_templdecl_define_key:n{ + \tl_if_head_eq_meaning:nNTF{##1..}\DelayEvaluation + { +% \end{macrocode} +% In the v0.08 version of \texttt{template.dtx} a +% |\DelayEvaluation| for a faked register would simply be equiv to +% a |\cs_set_nopar:Npn | (code is below commented out). The negative side effect +% of this is that something like |=L| used with |\DelayEvaluation| +% would not allow for calc syntax since it would end up as +% |\cs_set_nopar:Npn |\allowbreak|\foo|\allowbreak|{a+b}|. The code below changes +% this to first assign to a scratch register (at runtime) and then +% do an |\edef|. Could be coded differently to save space (at cost +% of time) +% \begin{macrocode} +% \toks_put_right:Nn \l_TP_KV_assignments_toks {\cs_set_nopar:Npn #3{##1}} +% \toks_put_right:Nn \l_TP_KV_assignments_toks +% {#1#2{##1}\cs_set_nopar:Npx #3{\toks_use:N#2}} + \toks_set:No \l_tmpa_toks {\use_ii:nn ##1} + \toks_put_right:Nx \l_TP_KV_assignments_toks { + \exp_not:n{#1#2}{\toks_use:N \l_tmpa_toks} + \exp_not:n{ \cs_set_nopar:Npx #3{\toks_use:N#2} } + + } + } +% \end{macrocode} +% +% +% Otherwise same game for fake registers except that instead of +% passing the register to |\TP_multiselection_add:nnnnnn| we pass a +% temp fake one and +% doing a def instead of using |\setlength| or |\setcounter| +% +% and i haven't done the |\DelayEvaluation| bit for that case! as +% i'm not sure what the best approach is for those +% things\footnote{we might disallow it for that case in general --- +% not a nice rule but an explainable one} +% +% \begin{macrocode} + { + \tl_if_head_eq_meaning:nNTF{##1..}\MultiSelection + { + \group_begin: + \TP_multiselection_add:nnnnnn#1#2##1 + \group_end: + \toks_put_right:Nx\l_TP_KV_assignments_toks + {\exp_not:n{\cs_set_nopar:Npn #3} {\toks_use:N\g_TP_multiselection_toks}} + } + { + #1#2{##1} + \toks_put_right:Nx\l_TP_KV_assignments_toks + {\exp_not:n{\cs_set_nopar:Npn#3} {\toks_use:N#2}} + } + } + } +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\g_TP_multiselection_toks} +% \begin{macrocode} +\toks_new:N \g_TP_multiselection_toks +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TP_multiselection_add:nnnnnn} +% \marg{operation} \marg{register} |\MultiSelection| +% \marg{selector} \marg{case-list} \marg{else-case} +% +% This command builds up the |\if_case:w| code from the three +% arguments of |\MultiSelection| and stores it in +% |\g_TP_multiselection_toks|. This code is supposed to be run in a +% group so a) we don't have to initialise |\g_TP_multiselection_toks| +% and b) all changes to the used registers not affecting the +% outside. +% +% \begin{macrocode} +\cs_new_nopar:Npn \TP_multiselection_add:nnnnnn #1#2#3#4#5#6{ + \toks_gset:Nn \g_TP_multiselection_toks {\if_case:w #4} + \clist_map_inline:nn {#5}{ + \tl_if_head_eq_meaning:nNTF{##1..}\DelayEvaluation + { + \TP_multiselection_add_or_case:n {##1} + } + { + #1#2{##1} + \TP_multiselection_add_or_case:o { \toks_use:N #2 } + } + } + \toks_gput_right:Nn \g_TP_multiselection_toks { + \else: \use_i_after_fi:nw{#6}\fi: + } +} +% \end{macrocode} +% +% \end{macro} +% +% \begin{macro}{\TP_multiselection_add_or_case:o} +% No need to worry about where |\or:| is allowed to be added since +% all loops in \LaTeX3 process the item outside conditionals. +% \begin{macrocode} +\cs_new_nopar:Npn \TP_multiselection_add_or_case:n #1 { + \toks_gput_right:Nn \g_TP_multiselection_toks { + \or: \use_i_after_orelse:nw{#1} + } +} +\cs_generate_variant:Nn \TP_multiselection_add_or_case:n {o} +% \end{macrocode} +% \end{macro} +% +% Since i like to set things like |item-label-text| using this +% mechanism i need to handle the `n' key specially. +% +% Actually i could have probably extended +% |\TP_templdecl_setup_f_key:nnN| thus making +% this generally available to all f\meta{number} keys but was too lazy +% (or too stupid) to get it right first time so settled for the simple +% solution. +% +% So |\TP_templdecl_parse_KV:nnw| now calls +% |\TP_templdecl_setup_n_key:nN| for the `n' key. looks like +% this thus be fixed some time soon +% +% +% +% +% +% +% +% \begin{macro}{\IfExistsInstanceTF} +% tests that there is a \emph{default} definition +% taken from xinitials.dtx: +% \begin{macrocode} +\cs_new_nopar:Npn \IfExistsInstanceTF#1#2{ + \cs_if_exist:cTF{<>#1/#2} +} +% \end{macrocode} +% +% FMi: what happens if we are in collection FOO and there exists an +% instance I for type T within this collection but there doesn't exist +% an instance in the empty collection? +% +% What would happen if \ldots\ --- not clear to me what the sematics +% really should be. The code below is not better only different( and +% slower).\footnote{fix semantics} +% \begin{macrocode} +\cs_set_nopar:Npn \IfExistsInstanceTF#1#2{ + \TP_let_instance:Nnn \l_tmpa_tl {#1}{#2} +% next is not \tl_if_eq:NNTF but ...FT so done manually + \if_meaning:w\l_tmpa_tl\scan_stop: + \exp_after:wN\use_ii:nn + \else: + \exp_after:wN\use_i:nn + \fi:} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\DeclareRestrictedTemplate} +% Setting it up: +% +%| \DeclareRestrictedTemplate|\\ +% |{T-type} {new-T-name} {source-T-name} {keyvals}| +% +% This uses the same code as {T-type} {source-T-name} but adds +% settings from {keyvals} +% \begin{macrocode} +\cs_new_nopar:Npn \DeclareRestrictedTemplate#1#2#3#4{ + % CCC do we need a group here?? + \tl_set_eq:cc { TPD>/#1/#2 } { TPD>/#1/#3 } + \tl_set_eq:cc { TP>/#1/#2 } { TP>/#1/#3 } + \toks_set:Nv \l_TP_KV_assignments_toks { TPR>/ #1 / #3 } +% adds stuff to \l_TP_KV_assignments_toks + \setkeys {\cs:w TPO>/#1/#3\cs_end:}{#4} + + \tl_set:cx { TPR>/#1/#2 } + { \toks_use:N \l_TP_KV_assignments_toks } + \cs_if_free:cTF { TPO>/#1/#3 } + { \tl_set:cn {TPO>/#1/#2}{#1/#3} } + { \tl_set_eq:cc {TPO>/#1/#2}{TPO>/#1/#3} } +} +% \end{macrocode} +% \end{macro} +% +% +% Internals: +% +% \begin{macro}{\TP_instdecl_generate_assignments:nn} +% These could probably be inlined, even when they do something! +% +% Assumption: setkeys fully expands its first argument. +% +% \begin{macrocode} +\cs_new_nopar:Npn \TP_instdecl_generate_assignments:nn#1#2 { + % Returns to \l_TP_KV_assignments_toks + % the restrictions + % stored in the TP-structure (at present + % in YAM) of the template #1 + \exp_args:NNo \toks_set:No \l_TP_default_assignments_toks + {\cs:w TPD>/#1\cs_end:\scan_stop:\scan_stop:} + \toks_set:Nv \l_TP_KV_assignments_toks { TPR>/ #1 } + \setkeys { \cs:w TPO>/#1 \cs_end: } + { #2 } % adds stuff to \l_TP_KV_assignments_toks + +% prepends stuff to \l_TP_KV_assignments_toks : + \exp_after:wN\TP_instdecl_add_default_recurse:nn + \toks_use:N\l_TP_default_assignments_toks + +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\TP_instdecl_add_default_recurse:nn} +% [ 2001/06/10 Think about doing this properly with explicit plists! --- but +% this means that one has to think about whether or not plists should be +% implemented as token registers and not as tl vars as they are now. ] +% \begin{macrocode} +\cs_new_nopar:Npn \TP_instdecl_add_default_recurse:nn#1#2{ + \token_if_eq_meaning:NNF #1\scan_stop: + { + \l_tmpa_toks{#2} + \tl_set:Nx \l_tmpa_tl { + {\toks_use:N \l_tmpa_toks \toks_use:N \l_TP_KV_assignments_toks} + } + \l_TP_KV_assignments_toks \l_tmpa_tl + \TP_instdecl_add_default_recurse:nn + } +} +% \end{macrocode} +% \end{macro} +% +% +% +% |TPD>/type/name| stores the default parameter assignments. +% +% |TPR>/type/name| stores the parameter assignments that have been +% made for a restricted template otherwise it is undefined (or |\scan_stop:|). +% +% +% |TPO>/type/name| stores the full name (i.e. as |type/name|) +% of the template a restricted +% template is coming from originally. +% +% +% +% +% \begin{macro}{\TP_split_finite_skip_value:nnNN} +% This macro is for use in error checking template values like +% "text-float-sep" that can't contain infinite glue and needs the +% shrink and/or stretch components. First argument is the skip +% register (which is likely to be user input), second is a template +% key name, and the last two are the \meta{dimen} registers that +% stores the stretch and shrink components. Assignments are global. +% \begin{macrocode} +\cs_new_nopar:Npn \TP_split_finite_skip_value:nnNN #1#2{ + \skip_split_finite_else_action:nnNN {#1} { + \PackageError{template}{Value~ for~ key~ #2~ contains~ `fil(ll)'} + {Only~ finite~ minus~ or~ plus~ parts~ are~ allowed~ for~ this~ key.} + } +} +% \end{macrocode} +% \end{macro} +% +% +% +% +% \begin{macrocode} +% +% \end{macrocode} +% +% \Finale +% diff --git a/Master/texmf-dist/source/latex/xpackages/xbase/tprestrict-test.tex b/Master/texmf-dist/source/latex/xpackages/xbase/tprestrict-test.tex new file mode 100644 index 00000000000..a787694abff --- /dev/null +++ b/Master/texmf-dist/source/latex/xpackages/xbase/tprestrict-test.tex @@ -0,0 +1,80 @@ +% \iffalse +%% (C) Copyright 2000-2004 LaTeX3 Project +%% +%% It may be distributed and/or modified under the conditions of the +%% LaTeX Project Public License (LPPL), either version 1.3a 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 ``xbase 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. +%% +%% ----------------------------------------------------------------------- +%% +%% $Id: tprestrict-test.tex 251 2004-11-11 19:01:16Z mittelba $ +%% +% \fi +% + +\makeatletter +\RequirePackage{template} +\IgnoreWhiteSpace + +\newcount\ca +\newdimen\da + + +\DeclareTemplateType{type}{0} + +\DeclareTemplate{type}{Ta}{0}{ + one =l [2in] \da, + two =c [5] \ca} + {\DoParameterAssignments\typeout{\da=\the\da,\@spaces \ca=\the\ca}} + +\ShowTemplate{type}{Ta} + +\typeout{1^^J==} +\UseTemplate{type}{Ta}{} + +\typeout{2^^J==} +\UseTemplate{type}{Ta}{one=44pt, two=7} + + +\DeclareRestrictedTemplate{type}{Tb}{Ta}{one=33pt} + +\ShowTemplate{type}{Tb} + +\typeout{RESTRICT^^J3^^J==} + +\DeclareInstance{type}{foo}{Tb}{two=9} + +\ShowInstance{type}{foo} + +\UseInstance{type}{foo} + +\typeout{4^^J==} +\UseTemplate{type}{Tb}{two=7} + +\stop + diff --git a/Master/texmf-dist/source/latex/xpackages/xbase/xbase.ins b/Master/texmf-dist/source/latex/xpackages/xbase/xbase.ins new file mode 100644 index 00000000000..742a1aa8dc3 --- /dev/null +++ b/Master/texmf-dist/source/latex/xpackages/xbase/xbase.ins @@ -0,0 +1,73 @@ +% \iffalse +%% +%% This file will generate fast loadable files and documentation +%% driver files from the dtx files in this package when run through +%% LaTeX or TeX. +%% +%% (C) Copyright 2000-2005 LaTeX3 Project +%% +%% It may be distributed and/or modified under the conditions of the +%% LaTeX Project Public License (LPPL), either version 1.3a 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 ``xbase 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. +%% +%% ----------------------------------------------------------------------- +%% +%% $Id: xbase.ins 302 2005-03-01 22:49:14Z morten $ +%% +% \fi +% + +\input docstrip +\keepsilent +\askforoverwritefalse + +\preamble + +(C) Copyright The LaTeX3 Project and any individual authors +listed elsewhere in this file. + +This is a generated file. + +This file was generated from file(s) of the xbase bundle. +--------------------------------------------------------- + +This file may only be distributed together with a copy of this bundle. +You may however distribute the bundle without such generated files. + +====================================================================== + +\endpreamble + + +\generate{% + \file{ldcsetup.sty}{\from{ldcsetup.dtx}{package}} + \file{template.sty}{\from{template.dtx}{package,trace}} + \file{xparse.sty}{\from{xparse.dtx}{package}} +} + +\endbatchfile diff --git a/Master/texmf-dist/source/latex/xpackages/xbase/xparse-test.tex b/Master/texmf-dist/source/latex/xpackages/xbase/xparse-test.tex new file mode 100644 index 00000000000..9e681adf520 --- /dev/null +++ b/Master/texmf-dist/source/latex/xpackages/xbase/xparse-test.tex @@ -0,0 +1,296 @@ +% \iffalse +%% (C) Copyright 2000-2009 LaTeX3 Project +%% +%% It may be distributed and/or modified under the conditions of the +%% LaTeX Project Public License (LPPL), either version 1.3a 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 ``xbase 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. +%% +%% ----------------------------------------------------------------------- +%% +%% $Id: xparse-test.tex 1487 2009-08-22 15:55:24Z joseph $ +%% +% \fi +% + +\documentclass{minimal} + +\usepackage{xparse,l3box} + + +\typeout{Testing the complicated makebox setup} +\typeout{*****************************} +\typeout{* look at dvi output for this part} +\typeout{*****************************} + +\ExplSyntaxOn +\makeatletter +% Let's just take the error messages for a ride: +\cs_set_nopar:Npn \makebox{} +% Here should be an error because it is defined +\NewDocumentCommand \makebox {m}{Gobbledygook} +\cs_gundefine:N \makebox +% And now one for being undefined +\RenewDocumentCommand \makebox {m}{More~gobbledygook} +\cs_set_eq:NN \makebox \scan_stop: +% Another one for being undefined +\RenewDocumentCommand \makebox {m}{Even~more~gobbledygook} +% Now it should work +\DeclareDocumentCommand \makebox + { >{\xparse_process_comma_split:n}d() o O{c} m} + {\IfNoValueTF{#1} + { \ltx@maketextbox{#2}{#3}{#4}\mbox } + { \ltx@makepicbox #1 {#2}{#4}\@firstofone } + } + +\DeclareDocumentCommand \framebox + { >{\xparse_process_comma_split:n} d() o O{c} m} + { + \IfNoValueTF{#1} + { \ltx@maketextbox{#2}{#3}{#4}\fbox } + { \ltx@makepicbox #1 {#2}{#4}\frame } + } + +\def\ltx@maketextbox#1#2#3#4{ + \IfNoValueTF{#1} + {#4{#3}} + { + \leavevmode + \@begin@tempboxa\hbox{#3} + \setlength\@tempdima{#1} + \if_meaning:w #4\fbox + \setbox\@tempboxa\hb@xt@\@tempdima{ + \kern\fboxsep + \use:c{bm@#2} + \kern\fboxsep + } + \@frameb@x{\kern-\fboxrule} + \else: + \hb@xt@\@tempdima{\use:c{bm@#2}} + \fi: + \@end@tempboxa + } +} + +\def\ltx@makepicbox#1#2#3#4#5{ + #5 + { + \vbox to#2\unitlength { + \cs_set_eq:NN \mb@b\vss \cs_set_eq:NN \mb@l\hss + \cs_set_eq:NN \mb@r\hss \cs_set_eq:NN \mb@t\vss + \IfNoValueF{#3}{ + \tl_map_variable:nNn {#3}\l_tmpa_tl { + \if:w s\l_tmpa_tl + \cs_set_eq:NN \mb@l \scan_stop: + \cs_set_eq:NN \mb@r \scan_stop: + \else: + \cs_set_eq:cN {mb@\l_tmpa_tl}\scan_stop: + \fi: + } + } + \mb@t + \hb@xt@ #1\unitlength{\mb@l #4\mb@r} + \mb@b + \kern\z@ + } + } +} + +\makeatother +\ExplSyntaxOff + +\begin{document} + + +\thicklines + +\makebox{A} +\makebox(1,2){B} +\makebox(0,0)[lt]{C} +\makebox[20pt]{D} +\makebox[30pt][r]{E} + +\vspace{1cm} + + +\framebox{A} +\framebox(1,2){B} +\framebox(0,0)[lt]{C} +\framebox[20pt]{D} +\framebox[30pt][r]{E} + + +\typeout{Testing optional coordinates} + +\DeclareDocumentCommand \foo { mmo } +{ \typeout{1:#1} + \typeout{2:#2} +} + +\show\foo + +\ExplSyntaxOn +\DeclareDocumentCommand \foo + { m >{\xparse_process_comma_split:n} D(){0,0} m } +{ \typeout{1:#1} + \typeout{2:#2} + \typeout{3:#3} +} +\ExplSyntaxOff + +\show\foo + +\foo A(1,2)B + +\foo A B + +\typeout{Testing mandatory coordinates (gives error on second examples)} + +\ExplSyntaxOn +\DeclareDocumentCommand \foo { m >{\xparse_process_comma_split:n} d() m } +{ \IfNoValueTF {#2} { + \ERROR + }{ + \typeout{1:#1} + \typeout{2:#2} + \typeout{3:#3} + } +} +\ExplSyntaxOff + +\show\foo + +\foo A(1,2)B + +\foo A B + +\typeout{Testing normal optional arguments} + + +\DeclareDocumentCommand \foo { mmmm o mm o } +{ \typeout{1:#1} + \typeout{2:#2} + \typeout{3:#3} + \typeout{4:#4} + \typeout{5:#5} + \typeout{6:#6} + \typeout{7:#7} + \typeout{8:#8} +} + +\foo 1234 [5]67[8] +\foo 1234 [5]67 [8] % 8 should not be picked up here +\foo 123467 + +\show\foo +\expandafter\show\csname\string\foo\endcsname + + +\typeout{Testing optional arguments with default} + +\DeclareDocumentCommand \baz { O{?}mmm o mm m } +{ \typeout{1:#1} + \typeout{2:#2} + \typeout{3:#3} + \typeout{4:#4} + \typeout{5:#5} + \typeout{6:#6} + \typeout{7:#7} + \typeout{8:#8} +} + +\show\baz +\expandafter\show\csname\string\baz\endcsname + +\baz [1]234[5]678 +\baz 234678 + +%\tracingall\tracingassigns=1 +\DeclareDocumentCommand \bar { mmmm mmmm m} +{ \typeout{1:#1} + \typeout{2:#2} + \typeout{3:#3} + \typeout{4:#4} + \typeout{5:#5} + \typeout{6:#6} + \typeout{7:#7} + \typeout{8:#8} + \typeout{9:#9} +} + +\show\bar +\expandafter\show\csname\string\bar\endcsname + +\bar 123456789 + +\DeclareDocumentCommand\chapter{soom} +{\typeout{a{#1}^^Jb{#2}^^Jc{#3}^^Jd{#4}^^Je}} + +\show\chapter +\expandafter\show\csname\string\chapter\endcsname + +\typeout{1:} +\chapter*[xxx][yyy]{zzz} + +\typeout{2:} +\chapter[xxx][yyy]{zzz} + +\typeout{3:} +\chapter*[xxx]{zzz} + +\typeout{4:} +\typeout{\chapter*[xxx][yyy]{zzz}} + + + + +\DeclareDocumentCommand\chapter{soom} +{\typeout{a{#1}^^Jb{#2}^^Jc{#3}^^Jd{#4}^^Je}} + +\DeclareDocumentEnvironment{hello}{ooo} + {\typeout{B1(#1)^^JB2(#2)^^JB3(#3)^^J}} + {\typeout{E1(#1)^^JE2(#2)^^JE3(#3)^^J}} + + +\show\hello +\expandafter\show\csname\string\hello\endcsname + +\show\endhello +\expandafter\show\csname end\string\\hello\endcsname + +\begin{hello}[abc][aabbcc] +\typeout{body} +\typeout{5:} +\chapter[xxx][yyy]{zzz} +\end{hello} + +\begin{hello}[1] +\typeout{outer body} +\hello[2]\typeout{inner body}\endhello +\end{hello} + +\stop diff --git a/Master/texmf-dist/source/latex/xpackages/xbase/xparse.dtx b/Master/texmf-dist/source/latex/xpackages/xbase/xparse.dtx new file mode 100644 index 00000000000..c227c4612f3 --- /dev/null +++ b/Master/texmf-dist/source/latex/xpackages/xbase/xparse.dtx @@ -0,0 +1,2443 @@ +% \iffalse +%% File: xparse.dtx (C) Copyright 1999 Frank Mittelbach, Chris Rowley, +%% David Carlisle +%% (C) Copyright 2004-2008 Frank Mittelbach, +%% LaTeX3 Project +%% (C) Copyright 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 ``xbase 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} +% +%\fi +\GetIdInfo$Id: xparse.dtx 1497 2009-08-31 19:17:53Z joseph $ + {Generic document command parser} +%\iffalse +%<*driver> +%\fi +\ProvidesFile{\filename.\filenameext} + [\filedate\space v\fileversion\space\filedescription] +%\iffalse +\documentclass{l3doc} +\begin{document} + \DocInput{xparse.dtx} +\end{document} +% +% \fi +% +% \title{The \textsf{xparse} package\thanks{This file +% has version number \fileversion, last +% revised \filedate.}\\ +% Generic document command parser} +% \author{\Team} +% \date{\filedate} +% \maketitle +% +%\begin{documentation} +% +%\section{Creating document commands} +% +% The \pkg{xparse} package provides a high-level interface for +% producing document-level commands. In that way, it is intended as +% a replacement for the \LaTeXe\ \cs{newcommand} macro. However, +% \pkg{xparse} works so that the interface to a function (optional +% arguments, stars and mandatory arguments, for example) is separate +% from the internal implementation. \pkg{xparse} provides a normalised +% input for the internal form of a function, independent of the +% document-level argument arrangement. +% +% At present, the functions in \pkg{xparse} which are regarded as +% `stable' are: +%\begin{itemize} +% \item \cs{DeclareDocumentCommand} +% \item \cs{NewDocumentCommand} +% \item \cs{RenewDocumentCommand} +% \item \cs{ProvideDocumentCommand} +% \item \cs{DeclareDocumentEnvironment} +% \item \cs{NewDocumentEnvironment} +% \item \cs{RenewDocumentEnvironment} +% \item \cs{ProvideDocumentEnvironment} +% \item \cs{IfNoValue(TF)} (the need for \cs{IfValue(TF)} is currently +% an item of active discussion) +% \item \cs{IfBoolean(TF)} +%\end{itemize} +% with the other functions currently regarded as `experimental'. Please +% try all of the commands provided here, but be aware that the +% experimental ones may change or disappear. +% +%\subsection{Specifying arguments} +% +% Before introducing the functions used to create document commands, +% the method for specifiying arguments with \pkg{xparse} will be +% illustrated. In order to allow each argument to be defined +% independently, \pkg{xparse} does not simply need to know the +% number of arguments for a function, but also the nature of each +% one. This is done by constructing an \emph{argument specification}, +% which defines the number of arguments, the type of each argument +% and any additional information needed for \pkg{xparse} to read the +% user input and properly pass it thorugh to internal functions. +% +% The basic form of the argument specifier is a list of letters, where +% each letter defines a type of argument. As will be described below, +% some of the types need additional information, such as default values. +% The argument types can be divided into two, those which define +% arguments that are mandatory (potentially raising an error if not +% found) and those which define optional arguments. The mandatory types +% are: +%\begin{itemize}[font=\ttfamily] +% \item[m] A standard mandatory argument, which can either be a single +% token alone or multiple tokens surrounded by curly braces. +% Regardless of the input, the argument will be passed to the +% internal code surrounded by a brace pair. This is the \pkg{xparse} +% type specifier for a normal \TeX\ argument. +% \item[l] An argument which reads everything up to the first +% open group token: in standard \LaTeX\ this is a left brace. +% \item[u] Reads an argument `until' \meta{tokens} are encountered, +% where the desired \meta{tokens} are given as an argument to the +% specifier: \texttt{u}\marg{tokens}. +%\end{itemize} +% The types which define optional arguments are: +%\begin{itemize}[font=\ttfamily] +% \item[o] A standard \LaTeX\ optional argument, surrounded with square +% brackets, which will supply +% the special \cs{NoValue} token if not given (as described later). +% \item[d] An optional argument which is delimited by \meta{token1} +% and \meta{token2}, which are given as arguments: +% \texttt{d}\meta{token1}\meta{token2}. As with \texttt{o}, if no +% value is given the special token \cs{NoValue} is returned. +% \item[O] As for \texttt{o}, but returns \meta{default} if no +% value is given. Should be given as \texttt{O}\marg{default}. +% \item[D] As for \texttt{d}, but returns \meta{default} if no +% value is given: \texttt{D}\meta{token1}\meta{token2}\marg{default}. +% Internally, the \texttt{o}, \texttt{d} and \texttt{O} types are +% shortcuts to an appropriated-constructed \texttt{D} type argument. +% \item[s] An optional star, which will result in a value +% \cs{BooleanTrue} if a star is present and \cs{BooleanFalse} +% otherwise (as described later). +% \item[t] An optional \meta{token}, which will result in a value +% \cs{BooleanTrue} if \meta{token} is present and \cs{BooleanFalse} +% otherwise. Given as \texttt{t}\meta{token}. +% \item[g] An optional argument given inside a pair of \TeX\ group +% tokens (in standard \LaTeX, |{| \ldots |}|). +%\end{itemize} +% +% Using these specifiers, it is possible to create complex input syntax +% very easily. For example, given the argument definition +% `|s o o m O{default}|', the input `|*[Foo]{Bar}|' would be parsed as: +%\begin{itemize}[nolistsep] +% \item |#1| = |\BooleanTrue| +% \item |#2| = |{Foo}| +% \item |#3| = |\NoValue| +% \item |#4| = |{Bar}| +% \item |#5| = |{default}| +%\end{itemize} +% whereas `|[One][Two]{}[three]|' would be parsed as: +%\begin{itemize}[nolistsep] +% \item |#1| = |\BooleanFalse| +% \item |#2| = |{One}| +% \item |#3| = |{Two}| +% \item |#4| = |{}| +% \item |#5| = |{Three}| +%\end{itemize} +% Note that after parsing the input there will be always exactly the +% same number of brace groups or tokens as the number of letters in the +% argument specifier. +% +% Two more tokens have a special meaning when creating an argument +% specifier. First, \texttt{+} is used to make an argument long (to +% accept paragraph tokens). In contrast to \LaTeXe's \cs{newcommand}, +% this applies on an argument-by-argument basis. So modifying the +% example to `|s o o +m O{default}|' means that the mandatory argument +% is now \cs{long}, whereas the optional arguments are not. +% +% Secondly, the token \texttt{>} is used to declare so-called +% `argument processors', which can be used to modify the contents of an +% argument before it is passed to the macro definition. The use of +% argument processors is a somewhat advanced topic, (or at least a less +% commonly used feature) and is covered in Section~\ref{sec:processors}. +% +%\subsection{Declaring commands and environments} +% +% With the concept of an argument specifier defined, it is now +% possible to describe the methods available for creating both +% functions and environments using \pkg{xparse}. +% +% The interface-building commands are the preferred method for +% creating document-level functions in \LaTeX3. All of the functions +% generated in this way are naturally robust (using the \eTeX\ +% \cs{protected} mechanism). +% +%\begin{function}{ +% \DeclareDocumentCommand| +% \NewDocumentCommand| +% \RenewDocumentCommand| +% \ProvideDocumentCommand +%} +% \begin{syntax} +% "\DeclareDocumentCommand" \Arg{arg spec} \Arg{code} +% \end{syntax} +% This family of commands are used to create a document-level +% . The argument specification for the function is +% given by , and the function will execute . +% +% As an example: +% \begin{verbatim} +% \DeclareDocumentCommand \chapter { s o m } { +% \IfBooleanTF {#1} { +% \typesetnormalchapter {#2} {#3} +% }{ +% \typesetstarchapter {#3} +% } +% } +% \end{verbatim} +% would be a way to define a \cs{chapter} command which would +% essentially behave like the current \LaTeXe\ command (except that it +% would accept an optional argument even when a \texttt{*} was parsed). +% The \cs{typesetnormalchapter} could test its first argument for being +% \cs{NoValue} to see if an optional argument was present. +% +% The difference between the \cs{Declare\ldots}, \cs{New\ldots} +% \cs{Renew\ldots} and \cs{Provide\ldots} versions is the behaviour +% if is already defined. +% \begin{itemize} +% \item \cs{DeclareDocumentCommand} will always create the new +% definition, irrespective of any existing with the +% same name. +% \item \cs{NewDocumentCommand} will issue an error if +% has already been defined. +% \item \cs{RenewDocumentCommand} will issue an error if +% has not previously been defined. +% \item \cs{ProvideDocumentCommand} creates a new definition for +% only if one has not already been given. +% \end{itemize} +% +% \begin{texnote} +% Unlike \LaTeXe's \cs{newcommand} and relatives, the +% \cs{DeclareDocumentCommand} function do not prevent creation of +% functions with names starting \cs{end\ldots}. +% \end{texnote} +%\end{function} +% +%\begin{function}{% +% \DeclareDocumentEnvironment| +% \NewDocumentEnvironment| +% \RenewDocumentEnvironment| +% \ProvideDocumentEnvironment +%} +% \begin{syntax} +% "\DeclareDocumentEnvironment" \Arg{environment} \Arg{arg spec} +% ~~~~\Arg{start code} \Arg{end code} +% \end{syntax} +% These commands work in the same way as \cs{DeclareDocumentCommand}, +% etc., but create environments (\cs{begin}|{||}| \ldots +% \cs{end}|{||}|). Both the and +% may access the arguments as defined by . +% +% \begin{texnote} +% When loaded as part of a \LaTeX3 format, these, these commands do +% not create a pair of macros \cs{} and +% \cs{end}. Thus \LaTeX3 environments have to be +% accessed using the \cs{begin} \ldots \cs{end} mechanism. When +% \pkg{xparse} is loaded as a \LaTeXe\ package, \cs{} +% and \cs{end} are defined, as this is necessary to +% allow the new environment to work! +% \end{texnote} +%\end{function} +% +%\subsection{Testing special values} +% +% Optional arguments created using \pkg{xparse} make use of dedicated +% variables to return information about the nature of the argument +% received. +% +%\begin{variable}{\NoValue} +% \cs{NoValue} is a special marker returned by \pkg{xparse} if no +% value is given for an optional argument. If typeset (which should +% not happen), it will print the value \texttt{-NoValue-}. +%\end{variable} +% +%\begin{function}{\IfNoValue / (TF) (EXP)} +% \begin{syntax} +% "\IfNoValueTF" \Arg{argument} \Arg{true code} \Arg{false code} +% \end{syntax} +% The \cs{IfNoValue} tests are used to check if (|#1|, +% |#2|, etc.) is the special \cs{NoValue} token. For example +% \begin{verbatim} +% \DeclareDocumentCommand \foo { o m } { +% \IfNoValueTF {#1} { +% \DoSomethingJustWithMandatoryArgument {#2} +% }{ +% \DoSomethingBothArguments {#1} {#2} +% } +% } +% \end{verbatim} +% will use a different internal function if the optional argument +% is given than if it is not present. +% +% As the \cs{IfNoValue} tests are expandable, it is possible to test +% these values later, for example at the point of typesetting or in +% an expansion context. +%\end{function} +% +%\begin{function}{\IfValue / (TF) (EXP)} +% \begin{syntax} +% "\IfValueTF" \Arg{argument} \Arg{true code} \Arg{false code} +% \end{syntax} +% The reverse form of the \cs{IfNoValue(TF)} tests are also available +% as \cs{IfValue(TF)}. The context will determine which logical +% form makes the most sense for a given code senario. +%\end{function} +% +%\begin{variable}{ +% \BooleanFalse| +% \BooleanTrue +%} +% The \texttt{true} and \texttt{false} flags set when searching for +% an optional token (using \texttt{s} or \texttt{t}) have +% names which are accessible outside of code blocks. +%\end{variable} +% +%\begin{function}{\IfBoolean / (TF) (EXP)} +% \begin{syntax} +% "\IfBooleanTF" \Arg{true code} \Arg{false code} +% \end{syntax} +% Used to test if (|#1|, |#2|, etc.) is \cs{BooleanTrue} +% or \cs{BooleanFalse}. For example +% \begin{verbatim} +% \DeclareDocumentCommand \foo { s m } { +% \IfBooleanTF #1 { +% \DoSomethingWithStar {#2} +% }{ +% \DoSomethingWithoutStar {#2} +% } +% } +% \end{verbatim} +% checks for a star as the first argument, then chooses the action to +% take based on this information. +%\end{function} +% +%\subsection{Argument processors} +%\label{sec:processors} +% +% \pkg{xparse} introduces the idea of an argument processor, which is +% applied to an argument \emph{after} it has been grabbed by the +% underlying system but before it is passed to \meta{code}. An argument +% processor can therefore be used to regularise input at an early stage, +% allowing the internal functions to be completely independent of input +% form. Processors are applied to user input and to default values for +% optional arguments, but \emph{not} to the special \cs{NoValue} marker. +% +% Each argument processor is specified by the syntax +% \texttt{>}\marg{processor} in the argument specification. Processors +% are applied from right to left, so that +%\begin{verbatim} +% >{\ProcessorB} >{\ProcessorA} m +%\end{verbatim} +% would apply \cs{ProcessorA} +% followed by \cs{ProcessorB} to the tokens grabbed by the \texttt{m} +% argument. +% +%\begin{variable}{\l_xparse_arg_toks} +% \pkg{xparse} defines a very small set of processor functions. In the +% main, it is anticipated that code writers will want to create their +% own processors. These need to accept one argument, which is the +% tokens as grabbed (or as returned by a previous processor function). +% Processor functions should return the processed argument in the +% variable \cs{l_xparse_arg_toks}. This will always be empty when the +% processor function is called by \pkg{xparse}, even if more than one +% argument processor is applied. +%\end{variable} +% +%\begin{function}{\xparse_process_to_str:n} +% \begin{syntax} +% "\xparse_process_to_str:n" \Arg{grabbed argument} +% \end{syntax} +% The \cs{xparse_process_to_str:n} processor applies the \LaTeX3 +% \cs{tl_to_str:n} function to the . For example +% \begin{verbatim} +% \DeclareDocumentCommand \foo { >{\xparse_arg_to_str:n} m } { +% #1 % Which is now detokenized +% } +% \end{verbatim} +%\end{function} +% +%\begin{function}{\xparse_process_comma_split:n} +% \begin{syntax} +% "\xparse_process_comma_split:n" +% ~~~~\Arg{grabbed argument} +% \end{syntax} +% The \cs{xparse_process_comma_split:n} processor splits the +% grabbed argument at the first comma, returning the two +% parts of the result in braces. If no comma is found, the second +% part of the returned value \cs{NoValue}. This function is intended to +% aid the processing of co-ordinate pairs. For example, to create +% a co-ordinate argument which raises an error if not given: +% \begin{verbatim} +% \DeclareDocumentCommand \foo +% { >{\xparse_process_comma_split:n} d() } { +% \IfNoValueTF #1 { +% \ERROR +% }{ +% \foo_internal:nn #1 +% } +% } +% \end{verbatim} +% For the input |\foo(1.1,2.2)|, |#1| here would equal |{1.1}{2.2}|, +% and so \cs{foo_internal:nn} receives exactly the correct number of +% arguments. A similar function which takes an optional co-ordinate +% pair, could be created as: +% \begin{verbatim} +% \DeclareDocumentCommand \foo +% { >{\xparse_process_comma_split:n} D(){0,0} } { +% \foo_internal:nn #1 +% } +% \end{verbatim} +% This illustrates that the processor function will be applied to the +% default value, which therefore includes a comma. +%\end{function} +% +%\subsection{Separating interface and implementation} +% +% One \emph{experimental} idea implemented in \pkg{xparse} is to +% separate out document command intefaces (the argument specification) +% from the implementation (code). This is carried out using a +% pair of functions, \cs{DeclareDocumentCommandInterface} and +% \cs{DeclareDocumentCommandImplementation} +% +%\begin{function}{\DeclareDocumentCommandInterface} +% \begin{syntax} +% "\DeclareDocumentCommandInterface" +% ~~~~\Arg{implementation} \Arg{arg.~spec} +% \end{syntax} +% This declares a , which will take arguments as detailed +% in the . When executed, the will look for +% code stored as an . +%\end{function} +% +%\begin{function}{\DeclareDocumentCommandImplementation} +% \begin{syntax} +% "\DeclareDocumentCommandImplementation" +% ~~~~\Arg{implementation} \Arg{code} +% \end{syntax} +% Declares the for a function to accept +% arguments and expand to . An implementation must take the +% same number of arguments as a linked interface, although this is not +% enforced by the code. +%\end{function} +% +%\subsection{Fully-expandable document commands} +% +% There are \emph{very rare} occasion when it may be useful to create +% functions using a fully-expandable argument grabber. To support this, +% \pkg{xparse} can create expandable functions as well as the usual +% robust ones. This imposes a number of restrictions on the nature of +% the arguments accepted by a function, and the code it implements. +% This facility should only be used when \emph{absolutely necessary}; +% if you do not understand when this might be, \emph{do not use these +% functions}! +% +%\begin{function}{\DeclareExpandableDocumentCommand} +% \begin{syntax} +% "\DeclareExpandableDocumentCommand" +% ~~~~ \Arg{arg spec} \Arg{code} +% \end{syntax} +% This command is used to create a document-level , +% which will grab its arguments in a fully-expandable manner. The +% argument specification for the function is given by , +% and the function will execute . In general, will +% also be fully expandable, although it is possible that this will +% not be the case (for example, a function for use in a table might +% expand so that \cs{omit} is the first non-expandable token). +% +% Parsing arguments expandably imposes a number of restrictions on +% both the type of arguments that can be read and the error checking +% available: +% \begin{itemize} +% \item The function must have at least one mandatory argument, and +% in particular the last argument must be one of the mandatory +% types (\texttt{l}, \texttt{m} or \texttt{u}). +% \item All arguments are either short or long: it is not possible +% to mix short and long argument types. +% \item The `optional group' argument types \texttt{g} and +% \texttt{G} are not available. +% \item It is not possible to differentiate between, for example +% |\foo[| and |\foo{[}|: in both cases the \texttt{[} will be +% interpretted as the start of an optional argument. As a result +% result, checking for optional arguments is less robust than +% in the standard version. +% \end{itemize} +% \pkg{xparse} will issue an error if an argument specifier is given +% which does not conform to the first three requirements. The last +% item is an issue when the function is used, and so is beyond the +% scope of \pkg{xparse} itself. +%\end{function} +% +%\subsection{Variables and constants} +% +%\begin{variable}{\c_xparse_shorthands_prop} +% Shorthands and replacement text: set up at the start of the package, +% and not be be altered later! +%\end{variable} +% +%\begin{variable}{\l_xparse_args_toks} +% Token register for arguments as they are picked up for passing on to +% user functions. +%\end{variable} +% +%\begin{variable}{\l_xparse_environment_args_toks} +% Token register to pass arguments to the end of an environment from +% the beginning. +%\end{variable} +% +%\begin{variable}{\l_xparse_error_bool} +% For flagging up errors when making expandable commands. +%\end{variable} +% +%\begin{variable}{\l_xparse_function_tl} +% Needed to pass along the function name when creating in an expandable +% manner. This is needed as a series of functions have to be created +% when making expandable functions. (In contrast, standard robust +% functions need at most two functions.) +%\end{variable} +% +%\begin{variable}{\l_xparse_last_arg_tl} +% The last argument type added. As this must be mandatory when creating +% expandable commands, this variable is needed to enforce this +% behaviour. +%\end{variable} +% +%\begin{variable}{\l_xparse_long_bool} +% Flag used to indicate creation of \cs{long} arguments. +%\end{variable} +% +%\begin{variable}{\l_xparse_m_args_int} +% Used to enumerate the \texttt{m} arguments with no modifications +% (i.e., neither long nor processed after grabbing). +%\end{variable} +% +%\begin{variable}{\l_xparse_m_only_bool} +% Flag used to indicate that all arguments are of type \texttt{m}, +% with no no modificiations. +%\end{variable} +% +%\begin{variable}{\l_xparse_mandatory_args_int} +% For counting up all mandatory arguments so that the code can tell +% when optional arguments come after the last mandatory one. Counts +% down again as mandatory arguments are added to the signature, so will +% be zero for any trailing optional arguments. +%\end{variable} +% +%\begin{variable}{\l_xparse_processor_bool} +% When converting an argument specification into a signature there is +% a need to know if there are any argument processors set up. This is +% used to tell if \texttt{m} arguments can simply be counted up or need +% handling on a one-off basis. +%\end{variable} +% +%\begin{variable}{\l_xparse_processor_int} +% Each time a processor is set up in the grabber routine, it is stored +% and the total number of processors is recorded here. Later, the +% variable is counted back down to use the processors in reverse order +% to the collection order. +%\end{variable} +% +%\begin{variable}{\l_xparse_signature_toks} +% For constucting the signature of the function defined. As +% \pkg{xparse} works thorugh an argument specification, grabber +% functions are added to this toks for each argument. +%\end{variable} +% +%\begin{variable}{\l_xparse_tmp_tl} +% Scratch space, used for example to convert shorthand argument types +% into the full versions. +%\end{variable} +% +%\begin{variable}{\l_xparse_total_args_int} +% Used to enumerate the total number of arguments (i.e., the number of +% ingroup letters in the argument specification). +%\end{variable} +% +%\begin{variable}{\q_xparse_stop} +% A private delimiting quark: needed by the expandable function system. +%\end{variable} +% +%\subsection{Internal functions} +% +%\begin{function}{\xparse_add_arg:n} +% \begin{syntax} +% "\xparse_add_arg:n" +% \end{syntax} +% Adds to the output \pkg{xparse} supplies to the +% defined , applying any post-processing that is needed. +%\end{function} +% +%\begin{function}{ +% \xparse_add_grabber_mandatory:N| +% \xparse_add_grabber_optional:N +%} +% \begin{syntax} +% "\xparse_add_grabber_mandatory:N" +% \end{syntax} +% Adds appropriate grabber for to the signature +% being constructed, making it long if necessary. The +% \texttt{optional} version includes a second check to see if space +% skipping should be on or off. +%\end{function} +% +%\begin{function}{ +% \xparse_add_type_+:w| +% \xparse_add_type_>:w| +% \xparse_add_type_d:w| +% \xparse_add_type_D:w| +% \xparse_add_type_g:w| +% \xparse_add_type_G:w| +% \xparse_add_type_l:w| +% \xparse_add_type_m:w| +% \xparse_add_type_t:w| +% \xparse_add_type_u:w +%} +% \begin{syntax} +% "\xparse_add_type_u:w" +% \end{syntax} +% Carry out necessary processes to add given of argument to +% the signature being constructed. Depending on the argument type +% being added, one or more arguments will be absorbed. +%\end{function} +% +%\begin{function}{\xparse_check_and_add:N} +% \begin{syntax} +% "\xparse_check_and_add:N" +% \end{syntax} +% Ensures that is valid, and if so adds it to the signature +% being constructed. +%\end{function} +% +%\begin{function}{ +% \xparse_count_mandatory:n| +% \xparse_count_mandatory:N +%} +% \begin{syntax} +% "\xparse_count_mandatory:N" +% \end{syntax} +% Used to count how many mandatory arguments an argument specification +% contains. The \texttt{n} function carries out the set up, before +% handing of to the \texttt{N} function. This reads one token, and +% calls the approriate counter function. +%\end{function} +% +%\begin{function}{ +% \xparse_count_type_>:w| +% \xparse_count_type_+:w| +% \xparse_count_type_d:w| +% \xparse_count_type_D:w| +% \xparse_count_type_g:w| +% \xparse_count_type_G:w| +% \xparse_count_type_l:w| +% \xparse_count_type_m:w| +% \xparse_count_type_t:w| +% \xparse_count_type_u:w| +%} +% \begin{syntax} +% "\xparse_count_type_D:w" +% \end{syntax} +% Used to count up mandatory arguments: one function for each argument +% type so that a simple loop can be used. Only the functions for +% mandatory arguments do any more than call the loop again. +%\end{function} +% +%\begin{function}{ +% \xparse_declare_cmd:Nnn| +% \xparse_declare_cmd:cnn +%} +% \begin{syntax} +% "\xparse_declare_cmd:Nnn" \Arg{signature} +% ~~~~\Arg{code} +% \end{syntax} +% Declares using for argument definition and +% as expansion. +% \begin{texnote} +% This is the internal name for \cs{DeclareDocumentCommand}. +% \end{texnote} +%\end{function} +% +%\begin{function}{\xparse_declare_cmd_interface:Nnn} +% \begin{syntax} +% "\xparse_declare_cmd_interface:Nnn" +% ~~~~\Arg{implementation} \Arg{signature} +% \end{syntax} +% Declares using , which should have code stored +% as . +% \begin{texnote} +% This is the internal name for \cs{DeclareDocumentCommandInterface}. +% \end{texnote} +%\end{function} +% +%\begin{function}{\xparse_declare_cmd_implementation:nNn} +% \begin{syntax} +% "\xparse_declare_cmd_implementation:nNn" +% ~~~~\Arg{implementation} \Arg{code} +% \end{syntax} +% Declares taking arguments as an , +% to be accessed using an interface defined elsewhere. +% \begin{texnote} +% This is the internal name for +% \cs{DeclareDocumentCommandImplementation}. +% \end{texnote} +%\end{function} +% +%\begin{function}{\xparse_declare_env:nnnn} +% \begin{syntax} +% "\xparse_declare_env:nnnn" \Arg{env} \Arg{arg spec} +% ~~~~\Arg{start code} \Arg{end code} +% \end{syntax} +% Declares as an environment taking arguments +% at \cs{begin}\{\}. The is eceutre at the beginning +% of the environment, and the at the end. Both parts may +% use the arguments defined by . +% \begin{texnote} +% This is the internal name for \cs{DeclareDocumentEnvironment}. +% \end{texnote} +%\end{function} +% +%\begin{function}{\xparse_flush_m_args:} +% \begin{syntax} +% "\xparse_flush_m_args:" +% \end{syntax} +% Adds an outstanding \texttt{m} arguments to the signature. +%\end{function} +% +%\begin{function}{\xparse_grab_arg:w} +% \begin{syntax} +% "\xparse_grab_arg:w" +% \end{syntax} +% Function re-defined each time an argument is grabbed to actually +% do the grabbing. It is this function which will raise an error if +% an argument runs away. +%\end{function} +% +%\begin{function}{ +% \xparse_grab_D:w | +% \xparse_grab_D_long:w | +% \xparse_grab_D_trailing:w | +% \xparse_grab_D_long_trailing:w| +% \xparse_grab_G:w | +% \xparse_grab_G_long:w | +% \xparse_grab_G_trailing:w | +% \xparse_grab_G_long_trailing:w| +% \xparse_grab_l:w | +% \xparse_grab_l_long:w | +% \xparse_grab_m:w | +% \xparse_grab_m_long:w | +% \xparse_grab_m_1:w | +% \xparse_grab_m_2:w | +% \xparse_grab_m_3:w | +% \xparse_grab_m_4:w | +% \xparse_grab_m_5:w | +% \xparse_grab_m_6:w | +% \xparse_grab_m_7:w | +% \xparse_grab_m_8:w | +% \xparse_grab_t:w | +% \xparse_grab_t_long:w | +% \xparse_grab_t_trailing:w | +% \xparse_grab_t_long_trailing:w| +% \xparse_grab_u:w | +% \xparse_grab_u_long:w | +%} +% \begin{syntax} +% "\xparse_grab_D:w" "\l_xparse_args_toks" +% \end{syntax} +% Argument grabbing functions, which re-arrange other +% so that the argument is read correctly. The \texttt{trailing} +% versions do not skip spaces when searching for optional arguments. +% For each argument type, the various versions feed the approriate +% information to a common auxiliary function which then sets up +% \cs{xparse_grab_arg:w} to actually carry out the argument absorption. +%\end{function} +% +%\begin{function}{\xparse_if_no_value:n / (TF) (EXP)} +% \begin{syntax} +% "\xparse_if_no_value:nTF" \Arg{arg} +% ~~~~\Arg{true code} \Arg{false code} +% \end{syntax} +% Executes if is equal to the special +% \cs{NoValue} marker and otherwise. Provided that +% the primitive \cs{(pdf)strcmp} is available, this function is +% expandable. +%\end{function} +% +%\begin{function}{ +% \xparse_prepare_signature:n| +% \xparse_prepare_signature:N +%} +% \begin{syntax} +% "\xparse_prepare_signature:n" \Arg{arg specs} +% \end{syntax} +% Parse one or more and convert to an output . +%\end{function} +% +%\begin{function}{\xparse_process_arg:n} +% \begin{syntax} +% "\xparse_process_arg:n" \Arg{processor} +% \end{syntax} +% Sets up code to apply to next grabbed argument. +%\end{function} +% +%\subsection{Creating expandable commands} +% +%\begin{function}{ +% \xparse_exp_add_type_d:w| +% \xparse_exp_add_type_D:w| +% \xparse_exp_add_type_l:w| +% \xparse_exp_add_type_m:w| +% \xparse_exp_add_type_t:w| +% \xparse_exp_add_type_u:w +%} +% \begin{syntax} +% "\xparse_exp_add_type_u:w" \Arg{delimiter} +% \end{syntax} +% Carry out necessary processes to add given of argument for +% an expandable command. Depending on the argument type being added, +% one or more arguments will be absorbed. +%\end{function} +% +%\begin{function}{\xparse_exp_check_and_add:N} +% \begin{syntax} +% "\xparse_exp_check_and_add:N" +% \end{syntax} +% Ensures that is valid, and if so adds it to expandable +% function being constructed. +%\end{function} +% +%\begin{function}{\xparse_exp_declare_cmd:Nnn} +% \begin{syntax} +% "\xparse_exp_declare_cmd:Nnn" \Arg{signature} +% ~~~~\Arg{code} +% \end{syntax} +% Declares using for argument definition and +% as expansion, and creating an expandable command. +% \begin{texnote} +% This is the internal name for +% \cs{DeclareExpandableDocumentCommand}. +% \end{texnote} +%\end{function} +% +%\begin{function}{ +% \xparse_exp_prepare_function:n| +% \xparse_exp_prepare_function:N +%} +% \begin{syntax} +% "\xparse_exp_prepare_function:n" \Arg{arg specs} +% \end{syntax} +% Parse one or more and convert to an expandable +% function. +%\end{function} +% +%\begin{function}{\xparse_exp_set:cpx} +% \begin{syntax} +% "\xparse_exp_set:cpx" \Arg{code} +% \end{syntax} +% An alias for either \cs{cs_set:cpx} or \cs{cs_set_nopar:cpx}, +% depending on the \cs{long} status of the expandable function. +%\end{function} +% +%\end{documentation} +% +%\begin{implementation} +% +%\section{\pkg{xparse} implementation} +% +% The usual lead-off: only needed for the package, of course (one day we +% may have a \LaTeX3 kernel). +% \begin{macrocode} +%<*package> +\ProvidesExplPackage + {\filename}{\filedate}{\fileversion}{\filedescription} +\RequirePackage{expl3} +% +%<*initex|package> +% \end{macrocode} +% +%\subsection{Variables and constants} +% +%\begin{macro}{\c_xparse_shorthands_prop} +% Shorthands are stored as a property list: this is set up here as it +% is a constant. +% \begin{macrocode} +\prop_new:N \c_xparse_shorthands_prop +\prop_put:Nnn \c_xparse_shorthands_prop { o } { d[] } +\prop_put:Nnn \c_xparse_shorthands_prop { O } { D[] } +\prop_put:Nnn \c_xparse_shorthands_prop { s } { t* } +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\l_xparse_arg_toks} +% Token registers for single grabbed argument when post-processing. +% \begin{macrocode} +\toks_new:N \l_xparse_arg_toks +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\l_xparse_args_toks} +% Token registers for grabbed arguments. +% \begin{macrocode} +\toks_new:N \l_xparse_args_toks +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\l_xparse_environment_args_toks} +% Used to pass arguments to the end of an environment. +% \begin{macrocode} +\toks_new:N \l_xparse_environment_args_toks +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\l_xparse_error_bool} +% Used to signal an error when creating expandable functions. +% \begin{macrocode} +\bool_new:N \l_xparse_error_bool +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\l_xparse_function_tl} +% When creating expandable functions, the current function name needs +% to be passed along. +% \begin{macrocode} +\tl_new:N \l_xparse_function_tl +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\l_xparse_last_arg_tl} +% Used when creating expandable arguments. +% \begin{macrocode} +\toks_new:N \l_xparse_last_arg_tl +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\l_xparse_long_bool} +% A flag for \cs{long} arguments. +% \begin{macrocode} +\bool_new:N \l_xparse_long_bool +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\l_xparse_m_args_int} +% The number of simple \texttt{m} arguments is tracked so they can be +% dumped \emph{en masse}. +% \begin{macrocode} +\int_new:N \l_xparse_m_args_int +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\l_xparse_m_only_bool} +% A flag to indicate that only \texttt{m} arguments have been found. +% \begin{macrocode} +\bool_new:N \l_xparse_m_only_bool +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\l_xparse_mandatory_args_int} +% So that trailing optional arguments can be picked up, a count has to +% be taken of all mandatory arguments. This is then decreased as +% mandatory arguments are added to the signature, so will be zero +% only if there are no more mandatory arguments to add. +% \begin{macrocode} +\int_new:N \l_xparse_mandatory_args_int +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\l_xparse_processor_bool} +% When reading through the argument specifier, a flag is needed to +% show that a processor has been found for the current argument. This +% is used when checking how to handle \texttt{m} arguments. +% \begin{macrocode} +\bool_new:N \l_xparse_processor_bool +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\l_xparse_processor_int} +% In the grabber routine, each processor is saved with a number +% recording the order it was found in. The total is then used to work +% back through the grabbers so they apply to the argument right to left. +% \begin{macrocode} +\int_new:N \l_xparse_processor_int +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\l_xparse_signature_toks} +% Token registers for constructing signatures. +% \begin{macrocode} +\toks_new:N \l_xparse_signature_toks +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\l_xparse_tmp_tl} +% A general purpose token list variable. +% \begin{macrocode} +\tl_new:N \l_xparse_tmp_tl +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\l_xparse_total_args_int} +% Thje total number of arguments is used to create the internal function +% which has a fixed number of arguments. +% \begin{macrocode} +\int_new:N \l_xparse_total_args_int +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\q_xparse_stop} +% A private quark, used for delimiting arguments when making +% expandable functions. +% \begin{macrocode} +\quark_new:N \q_xparse_stop +% \end{macrocode} +%\end{macro} +% +%\subsection{Turning the argument specifier into grabbers} +% +%\begin{macro}{\xparse_add_grabber_mandatory:N} +%\begin{macro}{\xparse_add_grabber_optional:N} +% To keep the various checks needed in one place, adding the grabber to +% the signature is done here. For mandatory arguments, the only question +% is whether to add a long grabber. For optional arguments, there is +% also a check to see if any mandatory arguments are still to be added. +% This is used to determine whether to skip spaces or not where +% searching for the argument. +% \begin{macrocode} +\cs_new_nopar:Nn \xparse_add_grabber_mandatory:N { + \toks_put_right:Nx \l_xparse_signature_toks { + \exp_not:c { + xparse_grab_ #1 \bool_if:NT \l_xparse_long_bool { _long } :w + } + } + \bool_set_false:N \l_xparse_long_bool + \int_decr:N \l_xparse_mandatory_args_int +} +\cs_new_nopar:Nn \xparse_add_grabber_optional:N { + \toks_put_right:Nx \l_xparse_signature_toks { + \exp_not:c { + xparse_grab_ #1 + \bool_if:NT \l_xparse_long_bool { _long } + \intexpr_compare:nF { + \l_xparse_mandatory_args_int > \c_zero + } { _trailing } + :w + } + } + \bool_set_false:N \l_xparse_long_bool +} +% \end{macrocode} +%\end{macro} +%\end{macro} +% +% All of the argument-adding functions work in essentially the same +% way, except the one for \texttt{m} arguments. Any collected \texttt{m} +% arguments are added to the signature, then the appropriate grabber +% is added to the signature. Some of the adding functions also pick up +% one or more arguments, and are also added to the signature. All of the +% functions then call the loop function \cs{xparse_prepare_signature:N}. +% +%\begin{macro}{\xparse_add_type_+:w} +% Making the next argument \cs{long} means setting the flag and +% knocking one back off the totatl argument count. The \texttt{m} +% arguments are recorded here as this has to be done for every case +% where there is then a \cs{long} argument. +% \begin{macrocode} +\cs_new_nopar:cpn { xparse_add_type_+:w } { + \xparse_flush_m_args: + \bool_set_true:N \l_xparse_long_bool + \bool_set_false:N \l_xparse_m_only_bool + \int_decr:N \l_xparse_total_args_int + \xparse_prepare_signature:N +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\xparse_add_type_>:w} +% When a processor is found, the function \cs{xparse_process_arg:n} +% is added to the signature along with the processor code itself. When +% the signature is used, the code will be added to an excution list by +% \cs{xparse_process_arg:n}. Here, the loop calls +% \cs{xparse_prepare_signature_aux:N} rather than +% \cs{xparse_prepare_signature:N} so that the flag is not reset. +% \begin{macrocode} +\cs_new:cpn { xparse_add_type_>:w } #1 { + \bool_set_true:N \l_xparse_processor_bool + \xparse_flush_m_args: + \int_decr:N \l_xparse_total_args_int + \toks_put_right:Nn \l_xparse_signature_toks { + \xparse_process_arg:n {#1} + } + \xparse_prepare_signature_aux:N +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\xparse_add_type_d:w} +% To save on repeated code, \texttt{d} is actually turned into +% the same grabber as is used by \texttt{D}, by putting the +% \cs{NoValue} default in the correct place. So there is some +% simple argument re-arrangement to do. Remember that |#1| and |#2| +% shoudl be single tokens. +% \begin{macrocode} +\cs_new:Npn \xparse_add_type_d:w #1#2 { + \xparse_add_type_D:w #1 #2 { \NoValue } +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\xparse_add_type_D:w} +% All of the optional delimited arguments are handled internally by +% the \texttt{D} type. At this stage, the two delimiters are stored +% along with the default value. +% \begin{macrocode} +\cs_new:Npn \xparse_add_type_D:w #1#2#3 { + \xparse_flush_m_args: + \xparse_add_grabber_optional:N D + \toks_put_right:Nn \l_xparse_signature_toks { #1 #2 {#3} } + \xparse_prepare_signature:N +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\xparse_add_type_g:w} +% The \texttt{g} type is simply an alias for \texttt{G} with the +% correct default built-in. +% \begin{macrocode} +\cs_new_nopar:Npn \xparse_add_type_g:w { + \xparse_add_type_G:w { \NoValue } +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\xparse_add_type_G:w} +% For the \texttt{G} type, the grabber and the default are added to +% the signature. +% \begin{macrocode} +\cs_new:Npn \xparse_add_type_G:w #1 { + \xparse_flush_m_args: + \xparse_add_grabber_optional:N G + \toks_put_right:Nn \l_xparse_signature_toks { {#1} } + \xparse_prepare_signature:N +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\xparse_add_type_l:w} +% Finding \texttt{l} arguments is very simple: there is nothing to do +% other than add the grabber. +% \begin{macrocode} +\cs_new_nopar:Npn \xparse_add_type_l:w { + \xparse_flush_m_args: + \xparse_add_grabber_mandatory:N l + \xparse_prepare_signature:N +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\xparse_add_type_m:w} +% The \texttt{m} type is special as short arguments which are not +% post-processed are simply counted at this stage. Thus there is a check +% to see if either of these cases apply. If so, a one-argument grabber +% is added to the signature. On the other hand, if a standard short +% argument is required it is simply counted at this stage, to be +% added later using \cs{xparse_flush_m_args:}. +% \begin{macrocode} +\cs_new_nopar:Npn \xparse_add_type_m:w { + \bool_if:nTF { + \l_xparse_long_bool || \l_xparse_processor_bool + } { + \xparse_flush_m_args: + \xparse_add_grabber_mandatory:N m + }{ + \int_incr:N \l_xparse_m_args_int + } + \xparse_prepare_signature:N +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\xparse_add_type_t:w} +% Setting up a \texttt{t} argument means collecting one token for the +% test, and adding it along with the grabber to the signature. +% \begin{macrocode} +\cs_new:Npn \xparse_add_type_t:w #1 { + \xparse_flush_m_args: + \xparse_add_grabber_optional:N t + \toks_put_right:Nn \l_xparse_signature_toks { #1 } + \xparse_prepare_signature:N +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\xparse_add_type_u:w} +% At the set up stage, the \texttt{u} type argument is identical to the +% \texttt{G} type except for the name of the grabber function. +% \begin{macrocode} +\cs_new:Npn \xparse_add_type_u:w #1 { + \xparse_flush_m_args: + \xparse_add_grabber_mandatory:N u + \toks_put_right:Nn \l_xparse_signature_toks { {#1} } + \xparse_prepare_signature:N +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\xparse_check_and_add:N} +% This function checks if the argument type actually exists and gives +% an error if it doesn't. +% \begin{macrocode} +\cs_new_nopar:Nn \xparse_check_and_add:N { + \cs_if_free:cTF { xparse_add_type_ #1 :w } { + \msg_error:nnx { xparse } { unknown-argument-type } {#1} + \xparse_add_type_m:w + }{ + \use:c { xparse_add_type_ #1 :w } + } +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\xparse_count_mandatory:n} +%\begin{macro}{\xparse_count_mandatory:N} +%\begin{macro}[aux]{\xparse_count_mandatory_aux:N} +% To count up mandatory arguments before the main parsing run, the +% same approach is used. First, check if the current token is a +% shrot-cut for another argument type. If it is, expand it and loop +% again. If not, then look for a `counting' function to check the +% argument type. No error is raised here if one is not found as one +% will be raised by later code. +% \begin{macrocode} +\cs_new:Nn \xparse_count_mandatory:n { + \int_zero:N \l_xparse_mandatory_args_int + \xparse_count_mandatory:N #1 \q_nil +} +\cs_new:Nn \xparse_count_mandatory:N { + \quark_if_nil:NF #1 { + \prop_if_in:NnTF \c_xparse_shorthands_prop {#1} { + \prop_get:NnN \c_xparse_shorthands_prop {#1} \l_xparse_tmp_tl + \exp_last_unbraced:NV \xparse_count_mandatory:N \l_xparse_tmp_tl + }{ + \xparse_count_mandatory_aux:N #1 + } + } +} +\cs_new:Nn \xparse_count_mandatory_aux:N { + \cs_if_free:cTF { xparse_count_type_ #1 :w } { + \xparse_count_type_m:w + }{ + \use:c { xparse_count_type_ #1 :w } + } +} +% \end{macrocode} +%\end{macro} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\xparse_count_type_>:w} +%\begin{macro}{\xparse_count_type_+:w} +%\begin{macro}{\xparse_count_type_d:w} +%\begin{macro}{\xparse_count_type_D:w} +%\begin{macro}{\xparse_count_type_g:w} +%\begin{macro}{\xparse_count_type_G:w} +%\begin{macro}{\xparse_count_type_l:w} +%\begin{macro}{\xparse_count_type_m:w} +%\begin{macro}{\xparse_count_type_t:w} +%\begin{macro}{\xparse_count_type_u:w} +% For counting the mandatory arguments, a function is provided for +% each argument type that will mop any extra arguments and call the +% loop function. Only the counting functions for mandatory arguments +% actually do anything: the rest are simply there to ensure the loop +% continues correctly. +% \begin{macrocode} +\cs_new:cpn { xparse_count_type_>:w } #1 { + \xparse_count_mandatory:N +} +\cs_new_nopar:cpn { xparse_count_type_+:w } { + \xparse_count_mandatory:N +} +\cs_new:Npn \xparse_count_type_d:w #1#2 { + \xparse_count_mandatory:N +} +\cs_new:Npn \xparse_count_type_D:w #1#2#3 { + \xparse_count_mandatory:N +} +\cs_new_nopar:Npn \xparse_count_type_g:w { + \xparse_count_mandatory:N +} +\cs_new:Npn \xparse_count_type_G:w #1 { + \xparse_count_mandatory:N +} +\cs_new_nopar:Npn \xparse_count_type_l:w { + \int_incr:N \l_xparse_mandatory_args_int + \xparse_count_mandatory:N +} +\cs_new_nopar:Npn \xparse_count_type_m:w { + \int_incr:N \l_xparse_mandatory_args_int + \xparse_count_mandatory:N +} +\cs_new:Npn \xparse_count_type_t:w #1 { + \xparse_count_mandatory:N +} +\cs_new:Npn \xparse_count_type_u:w #1 { + \int_incr:N \l_xparse_mandatory_args_int + \xparse_count_mandatory:N +} +% \end{macrocode} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\xparse_declare_cmd:Nnn} +%\begin{macro}{\xparse_declare_cmd:cnn} +%\begin{macro}[aux]{\xparse_declare_cmd_all_m:Nn} +%\begin{macro}[aux]{\xparse_declare_cmd_mixed:Nn} +% First, the signature is set up from the argument specification. There +% is then a check: if only \texttt{m} arguments are needed (which +% includes functions with no arguments at all) then the definition is +% simple. On the other hand, if the signature is more complex then an +% internal function actually contains the code with the user function +% as a simple wrapper. +% \begin{macrocode} +\cs_new:Nn \xparse_declare_cmd:Nnn { + \xparse_count_mandatory:n {#2} + \xparse_prepare_signature:n {#2} + \bool_if:NTF \l_xparse_m_only_bool { + \xparse_declare_cmd_all_m:Nn #1 {#3} + }{ + \xparse_declare_cmd_mixed:Nn #1 {#3} + } +} +\cs_generate_variant:Nn \xparse_declare_cmd:Nnn { cnn } +\cs_new:Nn \xparse_declare_cmd_all_m:Nn { + \cs_generate_from_arg_count:NNnn + #1 \cs_set_protected_nopar:Npn \l_xparse_total_args_int {#2} +} +\cs_new:Nn \xparse_declare_cmd_mixed:Nn { + \cs_set_protected_nopar:Npx #1 { + \exp_not:n { + \int_zero:N \l_xparse_processor_int + \toks_set:Nn \l_xparse_args_toks + } { \exp_not:c { \token_to_str:N #1 } } + \toks_use:N \l_xparse_signature_toks + \exp_not:n{ \toks_use:N \l_xparse_args_toks } + } + \cs_generate_from_arg_count:cNnn + { \token_to_str:N #1 } \cs_set:Npn \l_xparse_total_args_int {#2} +} +% \end{macrocode} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\xparse_declare_cmd_implementation:nNn} +% Creating a stand-alone implementation uisn the `two-part' mechanism +% is quite easy as this is just a wrapper for +% \cs{cs_generate_from_arg_count:cNnn}. +% \begin{macrocode} +\cs_new:Nn \xparse_declare_cmd_implementation:nNn { + \cs_generate_from_arg_count:cNnn { implementation_ #1 :w } + \cs_set:Npn {#2} {#3} +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\xparse_declare_cmd_interface:Nnn} +%\begin{macro}[aux]{\xparse_declare_cmd_interface_all_m:Nn} +%\begin{macro}[aux]{\xparse_declare_cmd_interface_mixed:Nn} +% As with the basic function \cs{xparse_declare_cmd:Nnn}, there are +% three things to do here. First, generate a signature from the +% argument specification. Then use that to create a function which +% will call the implementation part. Finally, a holder implementation +% is created. As before, there is a short-cut for functions which only +% have \texttt{m} type arguments. +% \begin{macrocode} +\cs_new:Nn \xparse_declare_cmd_interface:Nnn { + \xparse_prepare_signature:n {#3} + \bool_if:NTF \l_xparse_m_only_bool { + \xparse_declare_cmd_interface_all_m:Nn #1 {#2} + }{ + \xparse_declare_cmd_interface_mixed:Nn #1 {#2} + } + \cs_generate_from_arg_count:cNnn { implementation_ #2 :w } + \cs_set:Npn \l_xparse_total_args_int { ``#2'' } +} +\cs_new:Nn \xparse_declare_cmd_interface_all_m:Nn { + \cs_generate_from_arg_count:NNnn + #1 \cs_set_protected_nopar:Npn \l_xparse_total_args_int + { \use:c { implementation_ #2 :w } } +} +\cs_new:Nn \xparse_declare_cmd_interface_mixed:Nn { + \cs_set_protected_nopar:Npx #1 { + \exp_not:n { + \int_zero:N \l_xparse_processor_int + \toks_set:Nn \l_xparse_args_toks + } { \exp_not:c { \token_to_str:N #1 } } + \toks_use:N \l_xparse_signature_toks + \exp_not:n{ \toks_use:N \l_xparse_args_toks } + } + \cs_generate_from_arg_count:cNnn + { \token_to_str:N #1 } \cs_set:Npn \l_xparse_total_args_int + { \use:c { implementation_ #2 :w } } +} +% \end{macrocode} +%\end{macro} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\xparse_declare_env:nnnn} +% The idea here is to make sure that the end of the environment has the +% same arguments available as the beginning. +% \begin{macrocode} +\cs_new:Nn \xparse_declare_env:nnnn { + \xparse_declare_cmd:cnn { environment_begin_ #1 :w } {#2} { + \group_begin: + \toks_set_eq:NN \l_xparse_environment_args_toks + \l_xparse_args_toks + #3 + } + \cs_set_nopar:cpx { environment_end_ #1 :w } { + \exp_not:N \exp_last_unbraced:NV + \exp_not:c { environment_end_ #1 _aux:N } + \exp_not:N \l_xparse_environment_args_toks + \exp_not:N \group_end: + } + \cs_set_nopar:cx { environment_end_ #1 _aux:N } { + \exp_not:c { environment_end_ #1 _aux :w } + } + \cs_generate_from_arg_count:cNnn + { environment_end_ #1 _aux :w } \cs_set:Npn + \l_xparse_total_args_int {#4} +% +%<*package> + \cs_set_eq:cc {#1} { environment_begin_ #1 :w } + \cs_set_eq:cc { end #1 } { environment_end_ #1 :w } +% +%<*initex|package> +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\xparse_flush_m_args:} +% As \texttt{m} arguments are simply counted, there is a need to add +% them to the token register in a block. As this function can only +% be called if something other than \texttt{m} turns up, the flag can +% be switched here. The total number of mandatory arguments added to +% the signature is also decreased by the appropriate amount. +% \begin{macrocode} +\cs_new_nopar:Nn \xparse_flush_m_args: { + \cs_if_exist:cT { + xparse_grab_m_ \int_use:N \l_xparse_m_args_int :w + } { + \toks_put_right:Nx \l_xparse_signature_toks { + \exp_not:c { xparse_grab_m_ \int_use:N \l_xparse_m_args_int :w } + } + \int_set:Nn \l_xparse_mandatory_args_int { + \l_xparse_mandatory_args_int - \l_xparse_m_args_int + } + } + \int_zero:N \l_xparse_m_args_int + \bool_set_false:N \l_xparse_m_only_bool +} +% \end{macrocode} +%\end{macro} +% +% +%\begin{macro}[TF]{\xparse_if_no_value:n} +% Tests for \cs{NoValue}. +% \begin{macrocode} +\prg_new_conditional:Nnn \xparse_if_no_value:n { TF,T,F } { + \tl_if_eq:nnTF {#1} { \NoValue } { + \prg_return_true: + }{ + \prg_return_false: + } +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\xparse_prepare_signature:n} +% Creating the signature is a case of working through the input and +% turning into the output in \cs{l_xparse_signature_toks}. A track is +% also kept of the total number of arguments. This function sets +% everything up then hands off to the parser. +% \begin{macrocode} +\cs_new:Nn \xparse_prepare_signature:n { + \bool_set_false:N \l_xparse_long_bool + \int_zero:N \l_xparse_m_args_int + \bool_set_true:N \l_xparse_m_only_bool + \bool_set_false:N \l_xparse_processor_bool + \toks_clear:N \l_xparse_signature_toks + \int_zero:N \l_xparse_total_args_int + \xparse_prepare_signature:N #1 \q_nil +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\xparse_prepare_signature:N} +%\begin{macro}[aux]{\xparse_prepare_signature_aux:N} +% The main signature-preparation loop is in two parts, to keep the code +% a little clearer. Most of the checks here is pretty clear, with a key +% point to watch what is next on the stack so that the loop continues +% correctly. +% \begin{macrocode} +\cs_new:Nn \xparse_prepare_signature:N { + \bool_set_false:N \l_xparse_processor_bool + \xparse_prepare_signature_aux:N #1 +} +\cs_new:Nn \xparse_prepare_signature_aux:N { + \quark_if_nil:NTF #1 { + \bool_if:NF \l_xparse_m_only_bool { + \xparse_flush_m_args: + } + }{ + \prop_if_in:NnTF \c_xparse_shorthands_prop {#1} { + \prop_get:NnN \c_xparse_shorthands_prop {#1} \l_xparse_tmp_tl + \exp_last_unbraced:NV \xparse_prepare_signature:N \l_xparse_tmp_tl + }{ + \int_incr:N \l_xparse_total_args_int + \xparse_check_and_add:N #1 + } + } +} +% \end{macrocode} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\xparse_process_arg:n} +% Processors are saved for use later during the grabbbing process. +% \begin{macrocode} +\cs_new:Nn \xparse_process_arg:n { + \int_incr:N \l_xparse_processor_int + \cs_set:cn { + xparse_processor_ \int_use:N \l_xparse_processor_int :n + } + { #1 {##1} } +} +% \end{macrocode} +%\end{macro} +% +%\subsection{Grabbing arguments} +% +%\begin{macro}{\xparse_add_arg:n} +%\begin{macro}[aux]{\xparse_add_arg_aux:n} +%\begin{macro}[aux]{\xparse_add_arg_aux:V} +% The argument-storing system provides a single point for interfacing +% with processors. They are done in a loop, couning downward. In this +% way, the processor which was found last is executed first. The result +% is that processors apply from right to left, as intended. Notice that +% a set of braces are added back around the result of processing so that +% the internal function will correctly pick up one argument for each +% input argument. +% \begin{macrocode} +\cs_new:Nn \xparse_add_arg:n { + \intexpr_compare:nTF { \l_xparse_processor_int = \c_zero } { + \toks_put_right:Nn \l_xparse_args_toks { {#1} } + }{ + \xparse_if_no_value:nTF {#1} { + \int_zero:N \l_xparse_processor_int + \toks_put_right:Nn \l_xparse_args_toks { {#1} } + }{ + \xparse_add_arg_aux:n {#1} + } + } +} +\cs_new:Nn \xparse_add_arg_aux:n { + \use:c { xparse_processor_ \int_use:N \l_xparse_processor_int :n } + {#1} + \int_decr:N \l_xparse_processor_int + \intexpr_compare:nTF { \l_xparse_processor_int = \c_zero } { + \toks_put_right:No \l_xparse_args_toks { + \exp_after:wN { \toks_use:N \l_xparse_arg_toks } + } + }{ + \xparse_add_arg_aux:V \l_xparse_arg_toks + } +} +\cs_generate_variant:Nn \xparse_add_arg_aux:n { V } +% \end{macrocode} +%\end{macro} +%\end{macro} +%\end{macro} +% +% All of the grabbers follow the same basic pattern. The intial function +% sets u the appropriate information to define \cs{parse_grab_arg:w} to +% grab the argument. This means determining whether to use +% \cs{cs_set:Npn} or \cs{cs_set_nopar:Npn}, and for optional arguments +% whether to skip spaces. In all cases, \cs{xparse_grab_arg:w} is then +% called to actually do the grabbing. +% +%\begin{macro}{\xparse_grab_arg:w} +% Each time an argument is actually grabbed, \pkg{xparse} defines a +% function to do it. In that way, long arguments from previous functions +% can be included in the definition of the grabber function, so that +% it does not raise an error if not long. The generic function used +% for this is reserved here. +% \begin{macrocode} +\cs_new:Npn \xparse_grab_aux:w { } +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\xparse_grab_D:w} +%\begin{macro}{\xparse_grab_D_long:w} +%\begin{macro}{\xparse_grab_D_trailing:w} +%\begin{macro}{\xparse_grab_D_long_trailing:w} +%\begin{macro}[aux]{\xparse_grab_D_aux:NNnnNn} +% The generic delimited argument grabber. The auxiliary function does +% a peek test before calling \cs{xparse_grab_arg:w}, so that the +% optional nature of the argument works as expected. +% \begin{macrocode} +\cs_new:Npn \xparse_grab_D:w #1#2#3#4 \l_xparse_args_toks { + \xparse_grab_D_aux:NNnnNn #1 #2 {#3} {#4} \cs_set_nopar:Npn + { _ignore_spaces } +} +\cs_new:Npn \xparse_grab_D_long:w #1#2#3#4 \l_xparse_args_toks { + \xparse_grab_D_aux:NNnnNn #1 #2 {#3} {#4} \cs_set:Npn + { _ignore_spaces } +} +\cs_new:Npn \xparse_grab_D_trailing:w #1#2#3#4 \l_xparse_args_toks { + \xparse_grab_D_aux:NNnnNn #1 #2 {#3} {#4} \cs_set_nopar:Npn { } +} +\cs_new:Npn \xparse_grab_D_long_trailing:w #1#2#3#4 + \l_xparse_args_toks { + \xparse_grab_D_aux:NNnnNn #1 #2 {#3} {#4} \cs_set:Npn { } +} +\cs_set:Nn \xparse_grab_D_aux:NNnnNn { + #5 \xparse_grab_arg:w #1 ##1 #2 { + \xparse_add_arg:n {##1} + #4 \l_xparse_args_toks + } + \use:c { peek_charcode #6 :NTF } #1 { + \xparse_grab_arg:w + }{ + \xparse_add_arg:n {#3} + #4 \l_xparse_args_toks + } +} +% \end{macrocode} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\xparse_grab_G:w} +%\begin{macro}{\xparse_grab_G_long:w} +%\begin{macro}{\xparse_grab_G_trailing:w} +%\begin{macro}{\xparse_grab_G_long_trailing:w} +%\begin{macro}[aux]{\xparse_grab_G_aux:nnNn} +% Optional groups are checed by meaning, so that the same code will +% work with, for example, Con\TeX{}t-like input. +% \begin{macrocode} +\cs_new:Npn \xparse_grab_G:w #1#2 \l_xparse_args_toks { + \xparse_grab_G_aux:nnNn {#1} {#2} \cs_set_nopar:Npn { _ignore_spaces } +} +\cs_new:Npn \xparse_grab_G_long:w #1#2 \l_xparse_args_toks { + \xparse_grab_G_aux:nnNn {#1} {#2} \cs_set:Npn { _ignore_spaces } +} +\cs_new:Npn \xparse_grab_G_trailing:w #1#2 \l_xparse_args_toks { + \xparse_grab_G_aux:nnNn {#1} {#2} \cs_set_nopar:Npn { } +} +\cs_new:Npn \xparse_grab_G_long_trailing:w #1#2 \l_xparse_args_toks { + \xparse_grab_G_aux:nnNn {#1} {#2} \cs_set:Npn { } +} +\cs_set:Nn \xparse_grab_G_aux:nnNn { + #3 \xparse_grab_arg:w ##1 { + \xparse_add_arg:n {##1} + #2 \l_xparse_args_toks + } + \use:c { peek_meaning #4 :NTF } \c_group_begin_token { + \xparse_grab_arg:w + }{ + \xparse_add_arg:n {#1} + #2 \l_xparse_args_toks + } +} +% \end{macrocode} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\xparse_grab_l:w} +%\begin{macro}{\xparse_grab_l_long:w} +%\begin{macro}[aux]{\xparse_grab_l_aux:nN} +% Argument grabbers for mandatory \TeX\ arguments are pretty simple. +% \begin{macrocode} +\cs_new:Npn \xparse_grab_l:w #1 \l_xparse_args_toks { + \xparse_grab_l_aux:nN {#1} \cs_set_nopar:Npn +} +\cs_new:Npn \xparse_grab_l_long:w #1 \l_xparse_args_toks { + \xparse_grab_l_aux:nN {#1} \cs_set:Npn +} +\cs_new:Nn \xparse_grab_l_aux:nN { + #2 \xparse_grab_arg:w ##1## { + \xparse_add_arg:n \l_xparse_args_toks {##1} + #1 \l_xparse_args_toks + } + \xparse_grab_arg:w +} +% \end{macrocode} +%\end{macro} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\xparse_grab_m:w} +%\begin{macro}{\xparse_grab_m_long:w} +% Collecting a single mandatory argument is quite easy. +% \begin{macrocode} +\cs_new:Npn \xparse_grab_m:w #1 \l_xparse_args_toks { + \cs_set_nopar:Npn \xparse_grab_arg:w ##1 { + \xparse_add_arg:n {##1} + #1 \l_xparse_args_toks + } + \xparse_grab_arg:w +} +\cs_new:Npn \xparse_grab_m_long:w #1 \l_xparse_args_toks { + \cs_set:Npn \xparse_grab_arg:w ##1 { + \xparse_add_arg:n {##1} + #1 \l_xparse_args_toks + } + \xparse_grab_arg:w +} +% \end{macrocode} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\xparse_grab_m_1:w} +%\begin{macro}{\xparse_grab_m_2:w} +%\begin{macro}{\xparse_grab_m_3:w} +%\begin{macro}{\xparse_grab_m_4:w} +%\begin{macro}{\xparse_grab_m_5:w} +%\begin{macro}{\xparse_grab_m_6:w} +%\begin{macro}{\xparse_grab_m_7:w} +%\begin{macro}{\xparse_grab_m_8:w} +% Grabbing 1--8 mandatory arguments. We don't need to worry about +% nine arguments as this is only possible if everything is +% mandatory. Each function has an auxiliary so that \cs{par} tokens +% from other arguments still work. +% \begin{macrocode} +\cs_new:cpn { xparse_grab_m_1:w } #1 \l_xparse_args_toks { + \cs_set_nopar:Npn \xparse_grab_arg:w ##1 { + \toks_put_right:Nn \l_xparse_args_toks { {##1} } + #1 \l_xparse_args_toks + } + \xparse_grab_arg:w +} +\cs_new:cpn { xparse_grab_m_2:w } #1 \l_xparse_args_toks { + \cs_set_nopar:Npn \xparse_grab_arg:w ##1##2 { + \toks_put_right:Nn \l_xparse_args_toks { {##1} {##2} } + #1 \l_xparse_args_toks + } + \xparse_grab_arg:w +} +\cs_new:cpn { xparse_grab_m_3:w } #1 \l_xparse_args_toks { + \cs_set_nopar:Npn \xparse_grab_arg:w ##1##2##3 { + \toks_put_right:Nn \l_xparse_args_toks { {##1} {##2} {##3} } + #1 \l_xparse_args_toks + } + \xparse_grab_arg:w +} +\cs_new:cpn { xparse_grab_m_4:w } #1 \l_xparse_args_toks { + \cs_set_nopar:Npn \xparse_grab_arg:w ##1##2##3##4 { + \toks_put_right:Nn \l_xparse_args_toks { {##1} {##2} {##3} {##4} } + #1 \l_xparse_args_toks + } + \xparse_grab_arg:w +} +\cs_new:cpn { xparse_grab_m_5:w } #1 \l_xparse_args_toks { + \cs_set_nopar:Npn \xparse_grab_arg:w ##1##2##3##4##5 { + \toks_put_right:Nn \l_xparse_args_toks { + {##1} {##2} {##3} {##4} {##5} + } + #1 \l_xparse_args_toks + } + \xparse_grab_arg:w +} +\cs_new:cpn { xparse_grab_m_6:w } #1 \l_xparse_args_toks { + \cs_set_nopar:Npn \xparse_grab_arg:w ##1##2##3##4##5##6 { + \toks_put_right:Nn \l_xparse_args_toks { + {##1} {##2} {##3} {##4} {##5} {##6} + } + #1 \l_xparse_args_toks + } + \xparse_grab_arg:w +} +\cs_new:cpn { xparse_grab_m_7:w } #1 \l_xparse_args_toks { + \cs_set_nopar:Npn \xparse_grab_arg:w ##1##2##3##4##5##6##7 { + \toks_put_right:Nn \l_xparse_args_toks { + {##1} {##2} {##3} {##4} {##5} {##6} {##7} + } + #1 \l_xparse_args_toks + } + \xparse_grab_arg:w +} +\cs_new:cpn { xparse_grab_m_8:w } #1 \l_xparse_args_toks { + \cs_set_nopar:Npn \xparse_grab_arg:w ##1##2##3##4##5##6##7##8 { + \toks_put_right:Nn \l_xparse_args_toks { + {##1} {##2} {##3} {##4} {##5} {##6} {##7} {##8} + } + #1 \l_xparse_args_toks + } + \xparse_grab_arg:w +} +% \end{macrocode} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\xparse_grab_t:w} +%\begin{macro}{\xparse_grab_t_long:w} +%\begin{macro}{\xparse_grab_t_trailing:w} +%\begin{macro}{\xparse_grab_t_long_trailing:w} +%\begin{macro}[aux]{\xparse_grab_t_aux:NnNn} +% Dealing with a token is quite easy. Check the match, remove the +% token if needed and add a flag to the output. +% \begin{macrocode} +\cs_new:Npn \xparse_grab_t:w #1#2 \l_xparse_args_toks { + \xparse_grab_t_aux:NnNn #1 {#2} \cs_set_nopar:Npn { _ignore_spaces } +} +\cs_new:Npn \xparse_grab_t_long:w #1#2 \l_xparse_args_toks { + \xparse_grab_t_aux:NnNn #1 {#2} \cs_set:Npn { _ignore_spaces } +} +\cs_new:Npn \xparse_grab_t_trailing:w #1#2 \l_xparse_args_toks { + \xparse_grab_t_aux:NnNn #1 {#2} \cs_set_nopar:Npn { } +} +\cs_new:Npn \xparse_grab_t_long_trailing:w #1#2 \l_xparse_args_toks { + \xparse_grab_t_aux:NnNn #1 {#2} \cs_set:Npn { } +} +\cs_new:Nn \xparse_grab_t_aux:NnNn { + #3 \xparse_grab_arg:w { + \use:c { peek_charcode_remove #4 :NTF } #1 { + \xparse_add_arg:n { \BooleanTrue } + #2 \l_xparse_args_toks + }{ + \xparse_add_arg:n { \BooleanFalse } + #2 \l_xparse_args_toks + } + } + \xparse_grab_arg:w +} +% \end{macrocode} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\xparse_grab_u:w} +%\begin{macro}{\xparse_grab_u_long:w} +%\begin{macro}[aux]{\xparse_grab_u_aux:NnN} +% Grabbing up to a list of tokens is quite easy: define the grabber, +% and then collect. +% \begin{macrocode} +\cs_new:Npn \xparse_grab_u:w #1#2 \l_xparse_args_toks { + \xparse_grab_u_aux:NnN {#1} {#2} \cs_set_nopar:Npn +} +\cs_new:Npn \xparse_grab_u_long:w #1#2 \l_xparse_args_toks { + \xparse_grab_u_aux:NnN {#1} {#2} \cs_set:Npn +} +\cs_new:Nn \xparse_grab_u_aux:NnN { + #3 \xparse_grab_arg:w ##1 #1 { + \xparse_add_arg:n {##1} + #2 \l_xparse_args_toks + } + \xparse_grab_arg:w +} +% \end{macrocode} +%\end{macro} +%\end{macro} +%\end{macro} +% +%\subsection{Argument processors} +% +%\begin{macro}{\xparse_process_to_str:n} +% A basic argument processor: as much an example as anything else. +% \begin{macrocode} +\cs_new:Nn \xparse_process_to_str:n { + \toks_set:Nx \l_xparse_arg_toks { + \tl_to_str:n {#1} + } +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\xparse_process_comma_split:n} +%\begin{macro}[aux]{\xparse_process_comma_split_aux:w} +% Turns a co-ordinate pair into two separate values. +% \begin{macrocode} +\cs_new:Nn \xparse_process_comma_split:n { + \tl_if_in:nnTF {#1} { , } { + \xparse_process_comma_split_aux:w #1 \q_stop + }{ + \toks_set:Nn \l_xparse_arg_toks { {#1} { \NoValue } } + } +} +\cs_new:Npn \xparse_process_comma_split_aux:w #1 , #2 \q_stop { + \toks_set:Nn \l_xparse_arg_toks { {#1} {#2} } +} +% \end{macrocode} +%\end{macro} +%\end{macro} +% +%\subsection{Creating expandable functions} +% +% The trick here is to pass each grabbed argument along a chain of +% auxiliary functions. Each one ultimately calls the next in the chain, +% so that all of the arguments are passed along delimited using +% \cs{q_xparse_stop}. At the end of the chain, the marker is removed +% so that the user-supplied code can be passed the correct number +% of arguments. All of this is done by expansion! +% +%\begin{macro}{\xparse_exp_add_type_d:w} +% As in the standard case, the trick here is to slot in the default +% and treat as type \texttt{D}. +% \begin{macrocode} +\cs_new:Npn \xparse_exp_add_type_d:w #1#2 { + \xparse_exp_add_type_D:w #1 #2 { \NoValue } +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\xparse_exp_add_type_D:w} +% The most complex argument to grab in an expandable manner is the +% general delimited one. First, a shortcut is set up in +% \cs{l_xparse_tmpa_tl} for the name of the current grabber function. +% This is then created to grab one argument and test if it is equal +% to the opening delimiter. If the test fails, the code adds the default +% value and closing delimiter before `recycling' the argument. In either +% case, the second auxiliary function is called. It finds the closing +% delimiter and so the optional argument (if any). The function then +% calls the next one in the chain, passing along the argument(s) +% grabbed thus-far using \cs{q_xparse_stop} as a marker. +% \begin{macrocode} +\cs_new:Npn \xparse_exp_add_type_D:w #1#2#3 { + \tl_set:Nx \l_xparse_tmpa_tl { + \exp_after:wN \token_to_str:N \l_xparse_function_tl + \int_use:N \l_xparse_total_args_int + } + \xparse_exp_set:cpx { \l_xparse_tmpa_tl } ##1 \q_xparse_stop ##2 { + \exp_not:N \tl_if_head_eq_charcode:nNTF {##2} #1 { + \exp_not:c { \l_xparse_tmpa_tl aux } + ##1 \exp_not:N \q_xparse_stop + }{ + \exp_not:c { \l_xparse_tmpa_tl aux } + ##1 \exp_not:N \q_xparse_stop #3 #2 {##2} + } + } + \xparse_exp_set:cpx { \l_xparse_tmpa_tl aux} + ##1 \q_xparse_stop ##2 #2 { + \exp_not:c { + \exp_after:wN \token_to_str:N \l_xparse_function_tl + \intexpr_eval:n { \l_xparse_total_args_int + 1 } + } ##1 {##2} \exp_not:N \q_xparse_stop + } + \xparse_exp_prepare_function:N +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\xparse_exp_add_type_l:w} +%\begin{macro}{\xparse_exp_add_type_m:w} +% Gathering \texttt{l} and \texttt{m} arguments is almost the same. +% The grabber for the current argument is created to simply get the +% necessary argument and pass it along with any others through to the +% next function in the chain. +% \begin{macrocode} +\cs_new_nopar:Npn \xparse_exp_add_type_l:w { + \xparse_exp_set:cpx { + \exp_after:wN \token_to_str:N \l_xparse_function_tl + \int_use:N \l_xparse_total_args_int + } ##1 \q_xparse_stop ##2## { + \exp_not:c { + \exp_after:wN \token_to_str:N \l_xparse_function_tl + \intexpr_eval:n { \l_xparse_total_args_int + 1 } + } + ##1 {##2} \exp_not:N \q_xparse_stop + } + \xparse_exp_prepare_function:N +} +\cs_new_nopar:Npn \xparse_exp_add_type_m:w { + \int_incr:N \l_xparse_m_args_int + \xparse_exp_set:cpx { + \exp_after:wN \token_to_str:N \l_xparse_function_tl + \int_use:N \l_xparse_total_args_int + } ##1 \q_xparse_stop ##2 { + \exp_not:c { + \exp_after:wN \token_to_str:N \l_xparse_function_tl + \intexpr_eval:n { \l_xparse_total_args_int + 1 } + } + ##1 {##2} \exp_not:N \q_xparse_stop + } + \xparse_exp_prepare_function:N +} +% \end{macrocode} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\xparse_exp_add_type_t:w} +% Looking for a single token is a simpler version of the \texttt{D} +% code. The same idea of picking up one argument is used, but there is +% no need for a second function as there is no closing token to find. So +% either \cs{BooleanTrue} or \cs{BooleanFalse} are added to the list of +% arguments. In the later case, the grabber argument must be `recycled'. +% \begin{macrocode} +\cs_new:Npn \xparse_exp_add_type_t:w #1 { + \tl_set:Nx \l_xparse_tmpa_tl { + \exp_after:wN \token_to_str:N \l_xparse_function_tl + \intexpr_eval:n { \l_xparse_total_args_int + 1 } + } + \xparse_exp_set:cpx { + \exp_after:wN \token_to_str:N \l_xparse_function_tl + \int_use:N \l_xparse_total_args_int + } ##1 \q_xparse_stop ##2 { + \exp_not:N \tl_if_head_eq_charcode:nNTF {##2} #1 { + \exp_not:c { \l_xparse_tmpa_tl } + ##1 \exp_not:n { { \BooleanTrue } \q_xparse_stop } + }{ + \exp_not:c { \l_xparse_tmpa_tl } + ##1 \exp_not:n { { \BooleanFalse } \q_xparse_stop {##2} } + } + } + \xparse_exp_prepare_function:N +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\xparse_exp_add_type_u:w} +% Setting up for a \texttt{u} argument is a case of defining the +% grabber for the current argument in a delimited fashion. The rest of +% the process is as the other grabbers: add to the chain and call the +% next function. +% \begin{macrocode} +\cs_new:Npn \xparse_exp_add_type_u:w #1 { + \xparse_exp_set:cpx { + \exp_after:wN \token_to_str:N \l_xparse_function_tl + \int_use:N \l_xparse_total_args_int + } ##1 \q_xparse_stop ##2 #1 { + \exp_not:c { + \exp_after:wN \token_to_str:N \l_xparse_function_tl + \intexpr_eval:n { \l_xparse_total_args_int + 1 } + } + ##1 {##2} \exp_not:N \q_xparse_stop + } + \xparse_exp_prepare_function:N +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\xparse_exp_check_and_add:N} +% Virtually identical to the normal version, except calling the +% expandable \texttt{add} functions rather than the standard versions. +% \begin{macrocode} +\cs_new_nopar:Nn \xparse_exp_check_and_add:N { + \cs_if_free:cTF { xparse_exp_add_type_ #1 :w } { + \msg_error:nnx { xparse } { unknown-argument-type } {#1} + \tl_set:Nn \l_xparse_last_arg_tl { m } + \xparse_exp_add_type_m:w + }{ + \tl_set:Nn \l_xparse_last_arg_tl {#1} + \use:c { xparse_exp_add_type_ #1 :w } + } +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\xparse_exp_declare_cmd:Nnn} +%\begin{macro}[aux]{\xparse_exp_declare_cmd_all_m:Nn} +%\begin{macro}[aux]{\xparse_exp_declare_cmd_mixed:Nn} +%\begin{macro}[aux]{\xparse_exp_declare_cmd_mixed_aux:Nn} +% The overall scheme here is very different from the standard method. +% For each argument, an internal fucntion is created to grab an argument +% and pass along prevous ones. Each `daisy chains' to call the next +% one in the sequence. Thus at the end of the chain, an extra `argument' +% function is included to unwind the chain and pass data to the the +% internal function containing the actual code. If all of the arguments +% are type \texttt{m}, then the same tick is used as in the standard +% version. The \texttt{x} in the lead-off and mop-up functions makes +% sure that the braces around the first argument are not lost. +% \begin{macrocode} +\cs_new:Nn \xparse_exp_declare_cmd:Nnn { + \tl_set:Nn \l_xparse_function_tl {#1} + \xparse_exp_prepare_function:n {#2} + \intexpr_compare:nTF { + \l_xparse_total_args_int = \l_xparse_m_args_int + } { + \xparse_exp_declare_cmd_all_m:Nn #1 {#3} + }{ + \xparse_exp_declare_cmd_mixed:Nn #1 {#3} + } +} +\cs_new:Nn \xparse_exp_declare_cmd_all_m:Nn { + \bool_if:NTF \l_xparse_long_bool { + \cs_generate_from_arg_count:NNnn + #1 \cs_set:Npn \l_xparse_total_args_int {#2} + }{ + \cs_generate_from_arg_count:NNnn + #1 \cs_set_nopar:Npn \l_xparse_total_args_int {#2} + } +} +\cs_new:Nn \xparse_exp_declare_cmd_mixed:Nn { + \exp_args:NnV \tl_if_in:nnTF { l m u } \l_xparse_last_arg_tl { + \xparse_exp_declare_cmd_mixed_aux:Nn #1 {#2} + }{ + \msg_error:nn { xparse } { expandable-ending-optional } + } +} +\cs_new:Nn \xparse_exp_declare_cmd_mixed_aux:Nn { + \cs_set_nopar:Npx #1 { + \exp_not:c { \token_to_str:N #1 1 } x \exp_not:N \q_xparse_stop + } + \cs_set_nopar:cpx { + \token_to_str:N #1 \intexpr_eval:n { \l_xparse_total_args_int + 1 } + } x ##1 \q_xparse_stop { + \exp_not:c { \token_to_str:N #1 } ##1 + } + \cs_generate_from_arg_count:cNnn + { \token_to_str:N #1 } \cs_set:Npn \l_xparse_total_args_int {#2} +} +% \end{macrocode} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\xparse_exp_prepare_function:n} +%\begin{macro}[aux]{\xparse_exp_prepare_function_aux:n} +% A couple of early validation tests. Processors are forbidden, as are +% \texttt{g}, \texttt{l} and \texttt{u} arguments (the later more for +% ease than any technical reason). +% \begin{macrocode} +\cs_new:Nn \xparse_exp_prepare_function:n { + \bool_set_false:N \l_xparse_error_bool + \tl_if_in:nnT {#1} { > } { + \msg_error:nnx { xparse } { processor-in-expandable } {#1} + \bool_set_true:N \l_xparse_error_bool + } + \tl_if_in:nnT {#1} { g } { + \msg_error:nnx { xparse } { grouped-in-expandable } {#1} + \bool_set_true:N \l_xparse_error_bool + } + \tl_if_in:nnT {#1} { G } { + \msg_error:nnx { xparse } { grouped-in-expandable } {#1} + \bool_set_true:N \l_xparse_error_bool + } + \bool_if:NF \l_xparse_error_bool { + \xparse_exp_prepare_function_aux:n {#1} + } +} +\cs_new:Nn \xparse_exp_prepare_function_aux:n { + \cs_set_eq:NN \xparse_prepare_next:w \xparse_exp_prepare_function:N + \cs_set_eq:NN \xparse_exp_set:cpx \cs_set_nopar:cpx + \bool_set_false:N \l_xparse_long_bool + \int_zero:N \l_xparse_m_args_int + \int_zero:N \l_xparse_total_args_int + \tl_if_in:nnT {#1} { + } { + \bool_set_true:N \l_xparse_long_bool + \cs_set_eq:NN \xparse_exp_set:cpx \cs_set:cpx + } + \xparse_exp_prepare_function:N #1 \q_nil +} +% \end{macrocode} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\xparse_exp_prepare_function:N} +%\begin{macro}[aux]{\xparse_exp_prepare_function_long:N} +%\begin{macro}[aux]{\xparse_exp_prepare_function_short:N} +% Preparing functions is a case of +% \begin{macrocode} +\cs_new:Nn \xparse_exp_prepare_function:N { + \bool_if:NTF \l_xparse_long_bool { + \xparse_exp_prepare_function_long:N #1 + }{ + \xparse_exp_prepare_function_short:N #1 + } +} +\cs_new:Nn \xparse_exp_prepare_function_long:N { + \quark_if_nil:NF #1 { + \tl_if_eq:nnTF {#1} { + } { + \xparse_exp_prepare_function_short:N + }{ + \msg_error:nn { xparse } { inconsistent-long } + \xparse_exp_prepare_function_short:N #1 + } + + } +} +\cs_new:Nn \xparse_exp_prepare_function_short:N { + \quark_if_nil:NF #1 { + \prop_if_in:NnTF \c_xparse_shorthands_prop {#1} { + \prop_get:NnN \c_xparse_shorthands_prop {#1} \l_xparse_tmp_tl + \bool_if:NT \l_xparse_long_bool { + \tl_put_left:Nn \l_xparse_tmp_tl { + } + } + \exp_last_unbraced:NV \xparse_exp_prepare_function:N + \l_xparse_tmp_tl + }{ + \int_incr:N \l_xparse_total_args_int + \xparse_exp_check_and_add:N #1 + } + } +} +% \end{macrocode} +%\end{macro} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\xparse_exp_set:cpx} +% A shortcut to save constantly re-testing \cs{l_xparse_long_bool}. +% \begin{macrocode} +\cs_new_eq:NN \xparse_exp_set:cpx \cs_set_nopar:cpx +% \end{macrocode} +%\end{macro} +% +%\subsection{Messages} +% +% Some error messages. +% \begin{macrocode} +\msg_new:nnnn { xparse } { command-already-defined } {% + Command name `\token_to_str:N #1' already defined!% +}{% + You have used \token_to_str:N \NewDocumentCommand\\% + with a command that already has a definition.\\% + Perhaps you meant \token_to_str:N \RenewDocumentCommand.% +} +\msg_new:nnnn { xparse } { command-not-yet-defined } {% + Command `\token_to_str:N #1' not yet defined!% +}{% + You have used \token_to_str:N \RenewDocumentCommand\\% + with a command that was never defined.\\% + Perhaps you meant \token_to_str:N \NewDocumentCommand.% +} +\msg_new:nnn { xparse } { environment-already-defined } {% + Environment `#1' already defined!% +} +\msg_new:nnn { xparse } { environment-not-yet-defined } {% + Environment `#1' not yet defined!% +} +\msg_new:nnnn { xparse } { expandable-ending-optional } {% + Expandable command signature ends in optional argument.% +}{% + Expandable functions must have a final mandatory argument.% +} +\msg_new:nnnn { xparse } { grouped-in-expandable } {% + Optional grouped arguments cannot be used with expandable functions.% +}{% + Argument specification `#1' contains an optional grouped argument:\\% + this is only supported for standard robust functions.% +} +\msg_new:nnnn { xparse } { inconsistent-long } {% + Inconsistent long arguments.% +}{% + Expandable commands must have all arguments long if any at all.% +} +\msg_new:nnnn { xparse } { processor-in-expandable } {% + Argument processors cannot be used with expandable functions.% +}{% + Argument specification `#1' contains a processor function:\\% + this is only supported for standard robust functions.% +} +\msg_new:nnn { xparse } { unknown-argument-type } {% + Unknown argument type `#1' replaced by `m'. Fingers crossed ...% +} +% \end{macrocode} +% +%\subsection{User functions} +% +% The user functions are more or less just the internal functions +% renamed. +% +%\begin{macro}{\BooleanFalse} +%\begin{macro}{\BooleanTrue} +% Design-space names for the Boolean values. +% \begin{macrocode} +\cs_new_eq:NN \BooleanFalse \c_false_bool +\cs_new_eq:NN \BooleanTrue \c_true_bool +% \end{macrocode} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\DeclareDocumentCommand} +%\begin{macro}{\NewDocumentCommand} +%\begin{macro}{\RenewDocumentCommand} +%\begin{macro}{\ProvideDocumentCommand} +% The user macros are pretty simple wrappers around the internal ones. +% \begin{macrocode} +\xparse_declare_cmd:Nnn \DeclareDocumentCommand { +m +m +m } { + \xparse_declare_cmd:Nnn #1 {#2} {#3} +} +\DeclareDocumentCommand \NewDocumentCommand { +m +m +m } { + \cs_if_exist:NTF #1 { + \msg_error:nnx { xparse } { command-already-defined } {#1} + }{ + \xparse_declare_cmd:Nnn #1 {#2} {#3} + } +} +\NewDocumentCommand \RenewDocumentCommand { +m +m +m } { + \cs_if_exist:NTF #1 { + \xparse_declare_cmd:Nnn #1 {#2} {#3} + }{ + \msg_error:nnx { xparse } { command-not-yet-defined } {#1} + } +} +\NewDocumentCommand \ProvideDocumentCommand { +m +m +m } { + \cs_if_exist:NF #1 { + \xparse_declare_cmd:Nnn #1 {#2} {#3} + } +} +% \end{macrocode} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\DeclareDocumentCommandImplementation} +%\begin{macro}{\DeclareDocumentCommandInterface} +% The separate implementation/interface system is again pretty simple +% to create at the outer layer. +% \begin{macrocode} +\NewDocumentCommand \DeclareDocumentCommandImplementation { m m +m } { + \xparse_declare_cmd_implementation:nNn {#1} #2 {#3} +} +\NewDocumentCommand \DeclareDocumentCommandInterface { m m +m } { + \xparse_declare_cmd_interface:Nnn #1 {#2} {#3} +} +% \end{macrocode} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\DeclareDocumentEnvironment} +%\begin{macro}{\NewDocumentEnvironment} +%\begin{macro}{\RenewDocumentEnvironment} +%\begin{macro}{\ProvideDocumentEnvironment} +% Very similar for environments. +% \begin{macrocode} +\NewDocumentCommand \DeclareDocumentEnvironment { m +m +m +m } { + \xparse_declare_env:nnnn {#1} {#2} {#3} {#4} +} +\NewDocumentCommand \NewDocumentEnvironment { m +m +m +m } { + \cs_if_exist:cTF { environment_begin_ #1 :w } { + \msg_error:nnx { xparse } { environment-already-defined } {#1} + }{ + \xparse_declare_env:nnnn {#1} {#2} {#3} {#4} + } +} +\NewDocumentCommand \RenewDocumentEnvironment { m +m +m +m } { + \cs_if_exist:cTF { environment_begin_ #1 :w } { + \xparse_declare_env:nnnn {#1} {#2} {#3} {#4} + }{ + \msg_error:nnx { xparse } { environment-not-yet-defined } {#1} + } +} +\NewDocumentCommand \ProvideDocumentEnvironment { m +m +m +m } { + \cs_if_exist:cF { environment_begin_ #1 :w } { + \xparse_declare_env:nnnn {#1} {#2} {#3} {#4} + } +} +% \end{macrocode} +%\end{macro} +%\end{macro} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\DeclareExpandableDocumentCommand} +% The expanable version of the basic function is essentially the same. +% \begin{macrocode} +\NewDocumentCommand \DeclareExpandableDocumentCommand { +m +m +m } { + \xparse_exp_declare_cmd:Nnn #1 {#2} {#3} +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}[TF]{\IfBoolean} +% The logical \meta{true} and \meta{false} statements are just the +% normal \cs{c_true_bool} and \cs{c_false_bool}, so testing for them is +% done with the \cs{bool_if:NTF} functions from \textsf{l3prg}. +% \begin{macrocode} +\cs_new_eq:NN \IfBooleanTF \bool_if:NTF +\cs_new_eq:NN \IfBooleanT \bool_if:NT +\cs_new_eq:NN \IfBooleanF \bool_if:NF +% \end{macrocode} +%\end{macro} +% +%\begin{macro}[TF]{\IfNoValue} +% Simple re-naming. +% \begin{macrocode} +\cs_new_eq:NN \IfNoValueF \xparse_if_no_value:nF +\cs_new_eq:NN \IfNoValueT \xparse_if_no_value:nT +\cs_new_eq:NN \IfNoValueTF \xparse_if_no_value:nTF +% \end{macrocode} +%\end{macro} +%\begin{macro}[TF]{\IfValue} +% Inverted logic. +% \begin{macrocode} +\cs_set:Npn \IfValueF { \xparse_if_no_value:nT } +\cs_set:Npn \IfValueT { \xparse_if_no_value:nF } +\cs_set:Npn \IfValueTF #1#2#3 { + \xparse_if_no_value:nTF {#1} {#3} {#2} +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\NoValue} +% The marker for no value being give: this can be typeset safely. +% This is coded by hand as making it \cs{protected} ensures that it +% will not turn into anything else by accident. +% \begin{macrocode} +\NewDocumentCommand \NoValue { } { -NoValue- } +% \end{macrocode} +%\end{macro} +% +% \begin{macrocode} +% +% \end{macrocode} +% +% \end{implementation} +% +% \PrintIndex diff --git a/Master/texmf-dist/source/latex/xpackages/xparse-test.tex b/Master/texmf-dist/source/latex/xpackages/xparse-test.tex deleted file mode 100644 index f0071b021ab..00000000000 --- a/Master/texmf-dist/source/latex/xpackages/xparse-test.tex +++ /dev/null @@ -1,311 +0,0 @@ -% \iffalse -%% (C) Copyright 2000-2009 LaTeX3 Project -%% -%% It may be distributed and/or modified under the conditions of the -%% LaTeX Project Public License (LPPL), either version 1.3a 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 ``xbase 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. -%% -%% ----------------------------------------------------------------------- -%% -%% $Id: xparse-test.tex 1194 2009-04-19 15:07:07Z will $ -%% -% \fi -% - -\documentclass{minimal} - -\usepackage{xparse,l3box} - - -\typeout{Testing the complicated makebox setup} -\typeout{*****************************} -\typeout{* look at dvi output for this part} -\typeout{*****************************} - -\ExplSyntaxOn -\makeatletter -% Let's just take the error messages for a ride: -\cs_set_nopar:Npn \makebox{} -% Here should be an error because it is defined -\NewDocumentCommand \makebox {m}{Gobbledygook} -\cs_gundefine:N \makebox -% And now one for being undefined -\RenewDocumentCommand \makebox {m}{More~gobbledygook} -\cs_set_eq:NN \makebox \scan_stop: -% Another one for being undefined -\RenewDocumentCommand \makebox {m}{Even~more~gobbledygook} -% Now it should work -\DeclareDocumentCommand \makebox { C{\NoValue} o O{c} m} - { - \IfNoValueTF{#1} - { \ltx@maketextbox{#2}{#3}{#4}\mbox } - { \ltx@makepicbox #1 {#2}{#4}\@firstofone } - } - -\DeclareDocumentCommand \framebox { C{\NoValue} o O{c} m} - { - \IfNoValueTF{#1} - { \ltx@maketextbox{#2}{#3}{#4}\fbox } - { \ltx@makepicbox #1 {#2}{#4}\frame } - } - -\def\ltx@maketextbox#1#2#3#4{ - \IfNoValueTF{#1} - {#4{#3}} - { - \leavevmode - \@begin@tempboxa\hbox{#3} - \setlength\@tempdima{#1} - \if_meaning:w #4\fbox - \setbox\@tempboxa\hb@xt@\@tempdima{ - \kern\fboxsep - \use:c{bm@#2} - \kern\fboxsep - } - \@frameb@x{\kern-\fboxrule} - \else: - \hb@xt@\@tempdima{\use:c{bm@#2}} - \fi: - \@end@tempboxa - } -} - -\def\ltx@makepicbox#1#2#3#4#5{ - #5 - { - \vbox to#2\unitlength { - \cs_set_eq:NN \mb@b\vss \cs_set_eq:NN \mb@l\hss - \cs_set_eq:NN \mb@r\hss \cs_set_eq:NN \mb@t\vss - \IfNoValueF{#3}{ - \tl_map_variable:nNn {#3}\l_tmpa_tl { - \if:w s\l_tmpa_tl - \cs_set_eq:NN \mb@l \scan_stop: - \cs_set_eq:NN \mb@r \scan_stop: - \else: - \cs_set_eq:cN {mb@\l_tmpa_tl}\scan_stop: - \fi: - } - } - \mb@t - \hb@xt@ #1\unitlength{\mb@l #4\mb@r} - \mb@b - \kern\z@ - } - } -} - -\DeclarePseudoArgument{boxtest}{1} -{Before:~`#1',\hbox_set_inline_begin:N \l_tmpa_box } -{\hbox_set_inline_end: \space the~ box:~ - \hbox_unpack_clear:N\l_tmpa_box ,~ - After:~`#1'} -\DeclareDocumentCommand\sillyboxtest{m}{ - Testing~#1:~\UsePseudoArgument{boxtest}{#1} -} - - -\cs_set_nopar:Npn \showgrabbedargs{\showthe\l_xparse_grabbed_args_toks} -\makeatother -\ExplSyntaxOff - -\begin{document} - - -\thicklines - -\makebox{A} -\makebox(1,2){B} -\makebox(0,0)[lt]{C} -\makebox[20pt]{D} -\makebox[30pt][r]{E} - -\vspace{1cm} - - -\framebox{A} -\framebox(1,2){B} -\framebox(0,0)[lt]{C} -\framebox[20pt]{D} -\framebox[30pt][r]{E} - - -\typeout{Testing optional coordinates} - -\DeclareDocumentCommand \foo { mmo } -{ \typeout{1:#1} - \typeout{2:#2} -} - -\show\foo - -\DeclareDocumentCommand \foo { m C{{0}{0}} m } -{ \typeout{1:#1} - \typeout{2:#2} - \typeout{3:#3} -} - -\show\foo - -\foo A (1,2) B - -\foo A B - -\typeout{Testing mandatory coordinates (gives error on second examples)} - -\DeclareDocumentCommand \foo { m c m } -{ \typeout{1:#1} - \typeout{2:#2} - \typeout{3:#3} -} - -\show\foo - -\foo A (1,2) B - -\foo A B - -\typeout{Testing normal optional arguments} - - -\DeclareDocumentCommand \foo { mmmm o mm o } -{ \typeout{1:#1} - \typeout{2:#2} - \typeout{3:#3} - \typeout{4:#4} - \typeout{5:#5} - \typeout{6:#6} - \typeout{7:#7} - \typeout{8:#8} -} - -\foo 1234[5]67[8] -\foo 123467 - -\show\foo -\expandafter\show\csname\string\foo\endcsname - - -\typeout{Testing optional arguments with default} - -\DeclareDocumentCommand \baz { O{?}mmm o mm m } -{ \typeout{1:#1} - \typeout{2:#2} - \typeout{3:#3} - \typeout{4:#4} - \typeout{5:#5} - \typeout{6:#6} - \typeout{7:#7} - \typeout{8:#8} -} - -\show\baz -\expandafter\show\csname\string\baz\endcsname - -\baz [1]234[5]678 -\showgrabbedargs -\baz 234678 -\showgrabbedargs - -%\tracingall\tracingassigns=1 -\DeclareDocumentCommand \bar { mmmm mmmm m} -{ \typeout{1:#1} - \typeout{2:#2} - \typeout{3:#3} - \typeout{4:#4} - \typeout{5:#5} - \typeout{6:#6} - \typeout{7:#7} - \typeout{8:#8} - \typeout{9:#9} -} - -\show\bar -\expandafter\show\csname\string\bar\endcsname - -\bar 123456789 -\showgrabbedargs - -\DeclareDocumentCommand\chapter{soom} -{\typeout{a{#1}^^Jb{#2}^^Jc{#3}^^Jd{#4}^^Je}} - -\show\chapter -\expandafter\show\csname\string\chapter\endcsname - -\typeout{1:} -\chapter*[xxx][yyy]{zzz} - -\typeout{2:} -\chapter[xxx][yyy]{zzz} - -\typeout{3:} -\chapter*[xxx]{zzz} - -\typeout{4:} -\typeout{\chapter*[xxx][yyy]{zzz}} - - - -\typeout{Using pseudo arguments:} - -\sillyboxtest{AB}{a\verb*+% $%&\+b} - -\typeout{Testing environments with args passed to end env} -\typeout{****************} -\typeout{* This works only if xparse is compiled with `perhaps' - docstrip guard} -\typeout{* This part of the code is not activated by default!} -\typeout{****************} - - - -\DeclareDocumentCommand\chapter{soom} -{\typeout{a{#1}^^Jb{#2}^^Jc{#3}^^Jd{#4}^^Je}} - -\DeclareDocumentEnvironment{hello}{ooo} - {\typeout{B1(#1)^^JB2(#2)^^JB3(#3)^^J}} - {\typeout{E1(#1)^^JE2(#2)^^JE3(#3)^^J}} - - -\show\hello -\expandafter\show\csname\string\hello\endcsname - -\show\endhello -\expandafter\show\csname end\string\\hello\endcsname - -\begin{hello}[abc][aabbcc] -\typeout{body} -\typeout{5:} -\chapter[xxx][yyy]{zzz} -\end{hello} - -\begin{hello}[1] -\typeout{outer body} -\hello [2] \typeout{inner body} \endhello -\end{hello} - -\stop diff --git a/Master/texmf-dist/source/latex/xpackages/xparse.dtx b/Master/texmf-dist/source/latex/xpackages/xparse.dtx deleted file mode 100644 index 8b63e346a6a..00000000000 --- a/Master/texmf-dist/source/latex/xpackages/xparse.dtx +++ /dev/null @@ -1,2151 +0,0 @@ -% \iffalse -%% File: xparse.dtx (C) Copyright 1999 Frank Mittelbach, Chris Rowley, David Carlisle -%% (C) Copyright 2004-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 -%% 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 ``xbase 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{expl3} -% -%\fi -\GetIdInfo$Id: xparse.dtx 1365 2009-05-31 17:26:17Z mittelba $ - {generic document command parser} -%\iffalse -%<*driver> -%\fi -\ProvidesFile{\filename.\filenameext} - [\filedate\space v\fileversion\space\filedescription] -%\iffalse - \documentclass{ltxdoc} - \usepackage[T1]{fontenc} - \usepackage{textcomp} - \makeatletter - \providecommand*\eTeX{% - \if b\expandafter\@car\f@series\@nil\boldmath\fi - $\m@th\varepsilon$-\TeX} - \makeatother -% \usepackage{ldcdoc} - \begin{document} - \catcode`\_=11 - \catcode`\:=11 - \DocInput{xparse.dtx} - \end{document} -% -% \fi -% -% \CheckSum{632} -% -% -% \title{The \textsf{xparse} package\thanks{This file -% has version number \fileversion, last -% revised \filedate.}} -% \author{FMi, CAR, DPC, MH} -% \date{\copyright~\filedate} -% \maketitle -% -% \begin{abstract} -% The interfaces described in this document are not meant to be final -% but only as a basis for discussion. Building productive applications -% using the current code is discouraged. -% \end{abstract} -% -% \section{Interface} -% -% This package implements high-level interface commands for class file -% writers which allows the separation of formatting commands -% (typically instances of so-called `templates') and their arguments -% from the signature of document-level commands. -% -% This works by declaration commands that provide a general -% specification method for the typical \LaTeX{} syntax, e.g., -% star-form, optional arguments, and mandatory arguments. A command -% (or environment) declared in this way parses the input according to -% its spec and presents its findings in a normalized way for further -% processing. -% -% \subsection{Argument spec} -% -% -% An argument specification is a list of letters each representing a -% type of argument, i.e., |m| is a mandatory argument (surrounded by -% braces), |o| an optional argument (surrounded by brackets if -% present), and |s| represents a star (which might be present or not). -% Thus the argument spec for headings as implemented by -% |\@startsection| in standard \LaTeX{} would be represented by the -% three letters |som|. Other argument types are available and can be -% added at will. For a complete list of built-in argument types see -% the next section. -% -% There is one important argument specifier worth taking note of. The -% |P| does not behave as a normal argument specifier but allows the -% next argument to take an argument containing the |\par| token which -% is not allowed by default. -% -% -% \subsection{Parsing results} -% -% To normalise the result of parsing the input according to an -% argument specification it is important to uniquely identify all -% arguments found. For this reason each parsing operation initiated by -% one of the argument spec letters will result in an identifiable -% output as follows: -% \begin{description} -% \item[m] will return the parsed argument surrounded by a brace -% pair, i.e., will normally be the identity; -% \item[o] will return the parsed argument surrounded by a brace pair -% if present. Otherwise it will return the token |\NoValue|; -% \item[O\{default\}] will return the parsed argument surrounded by a -% brace pair if present. Otherwise it will return the |{default}| -% as specified above. -% \item[S\{\meta{symbol}\}] will return either the token |\c_true_bool| or -% |\c_false_bool| depending on whether or not the next token is -% \meta{symbol}. -% \item[s] will return either the token |\c_true_bool| or |\c_false_bool| -% depending on whether or not a star was parsed. This is just a -% shorthand for |S{*}|. -% \item[c] will parse the syntax |(|\meta{x}|,|\meta{y}|)|, i.e., a -% coordinate pair and will return |{{|\meta{x}|}{|\meta{y}|}}| as -% the result. If no open parentheses is scanned an error is -% signalled. -% \item[C\{\{x-default\}\{y-default\}\}] behaves like |c|, i.e., -% parses a coordinate pair if present. If the coordinate pair is -% missing it returns the default values instead. -% \item[l] Reads everything up to the first left brace as the -% argument. -% \end{description} -% For example, given the spec |soomO{default}| the input -% |*[Foo]{Bar}| would be parsed as -% |\c_true_bool{Foo}\NoValue{Bar}{default}|. In other words there will be -% always exactly the same number of brace groups or tokens as the -% number of letters in the argument spec. -% -% There are a few exceptions to this rule as the r\^ole of following -% letters is to affect how the next argument is read. -% \begin{description} -% \item[>] takes a mandatory argument like |{P}| or |{PW}| and -% inserts these extra argument specifiers so that they act on the -% next regular argument type. See below. -% \item[P] will cause the next argument to allow |\par| in it's -% argument. Thus the specification |m>{P}mm| will cause the command to -% read three mandatory arguments but only the second can contain the -% |\par| token. -% \item[W] will cause the next argument to \emph{not} ignore a space -% when trying to scan ahead for a special symbol such as a |*| or an -% optional argument. This is mostly useful when the last argument(s) -% of a document command are optional (see example later on). -% \end{description} -% -% -% \subsection{Applying the parsing results} -% -% Since the result of the parsing is a well defined number of tokens or -% brace groups it is easy to pass them on in any order to any -% processing function. To this end the tokens or brace groups are -% associated with the standard argument specifiers in \TeX{} macros, -% i.e., |#1|, |#2|, and so forth. This limits the argument -% specification to a maximum number of 9 letters, but for practical -% applications this should be sufficient. -% -% \subsection{The class designer interface} -% -% This package provides commands for declaring commands -% and environments to be used within the document body. -% -% \DescribeMacro\DeclareDocumentCommand -% The |\DeclareDocumentCommand| declaration takes three arguments. The -% first argument is the name of the command to be declared, the second -% is the argument specification in the syntax described above, and the -% third is the action to be carried out once the arguments are -% parsed. Within the third argument |#1|, |#2|, etc.\ denote the -% result of the parsing, e.g., -% \begin{verbatim} -% \DeclareDocumentCommand{\chapter}{som} -% { \IfBooleanTF {#1} -% { \typesetnormalchapter {#2}{#3} } -% { \typesetstarchapter {#3} } -% } -% \end{verbatim} -% would be a way to define a |\chapter| command which would -% essentially behave like the current \LaTeX{} command (except that it -% would accept an optional argument even when a |*| was parsed). The -% |\typesetnormalchapter| could test its first argument for being -% |\NoValue| to see if an optional argument was present. -% -% Of course something like the |\IfNoValueTF| test could also be -% placed inside a function that would process all three arguments, thus -% using the templates and their instances as provided by the -% \texttt{template} package such a declaration would probably look -% more like the following example: -% \begin{verbatim} -% \DeclareDocumentCommand{\chapter}{som} -% { \UseInstance {head} {A-head-main} {#1} {#2} {#3} } -% \end{verbatim} -% -% Using the |\DeclareDocumentCommand| interface it is easy to modify -% the document-level syntax while still applying the same -% layout-generating functions, e.g., a class that would not support -% optional arguments or star forms for the heading commands could -% define |\chapter| like this: -% \begin{verbatim} -% \DeclareDocumentCommand{\chapter}{m} -% { \UseInstance {head} {A-head-main} \BooleanFalse \NoValue {#1} } -% \end{verbatim} -% while a class that would allow for an additional optional argument -% (for whatever reason) could define it like that: -% \begin{verbatim} -% \DeclareDocumentCommand{\chapter}{somo} -% { \doSomethingWithTheExtraOptionalArg {#4} -% \UseInstance {head} {A-head-main} {#1} {#2} {#3} } -% \end{verbatim} -% \DescribeMacro\NewDocumentCommand -% \DescribeMacro\RenewDocumentCommand -% \DescribeMacro\ProvideDocumentCommand If |\DeclareDocumentCommand| -% is used on an already defined command, it'll overwrite it. The -% commands |\NewDocumentCommand|, |\RenewDocumentCommand| and -% |\ProvideDocumentCommand| have identical syntax to that of -% |\DeclareDocumentCommand| with the exception that |\New...| will -% only define the command if it is undefined, |\Renew...| will only -% redefine an existing command and |\Provide...| will only define the -% command if it is already undefined. -% -% -% \DescribeMacro\DeclareDocumentEnvironment -% \DescribeMacro\NewDocumentEnvironment -% \DescribeMacro\RenewDocumentEnvironment -% \DescribeMacro\ProvideDocumentEnvironment The -% |\DeclareDocumentEnvironment| declaration is similar to -% |\DeclareDocumentCommand| except that it takes four arguments: the -% first being the environment name (without a backslash), the second -% again the argument-spec, and the third and forth are the actions -% taken at start aqnd end of the environment. The parsed arguments are -% available to both the start and the finish as |#1|, |#2|, etc. -% -% All commands and environments defined with the above commands are -% automatically robust. -% -% -% -% \subsection{A different interface (for class design?)} -% -% Combining signature and top-level definition of a command |\foo| as -% in -% \begin{verbatim} -% \DeclareDocumentCommand \foo { m c m } -% { \typeout{1:#1} -% \typeout{2:#2} -% \typeout{3:#3} -% } -% \end{verbatim} -% is fine in certain cases, e.g., if the user wants to declare a few -% commands this way in the preamble of a document. However in a class -% file it probably better to completely separate signature (i.e., -% argument \#1 and \#2) from top-level implementation (i.e., argument -% \#3). -% -% -% \begin{verbatim} -% \DeclareDocumentCommandInterface \foo {bar} { m c m } -% \end{verbatim} -% The above now declare only the signature of the command |\foo| and -% states that the implementation is to be found under the label |bar|. -% -% A bunch of such statements would then for the first time clearly -% define a document class (i.e., what a document class instance needs -% to define to be compliant). -% -% An instance would then consist of a lot of declarations of the type -% \begin{verbatim} -% \DeclareDocumentCommandImplementation {bar} {3} -% { \typeout{1:#1} -% \typeout{2:#2} -% \typeout{3:#3} -% } -% \end{verbatim} -% i.e., defining how to format things being referenced as part of the -% signature. -% -% The functions |\DeclareDocumentCommandInterface| and -% |\DeclareDocumentCommandImplementation| are implemented for now but -% it is not sure if they will stay. If a document command is defined -% with |\DeclareDocumentCommandInterface| but there is no matching -% interface it prints the label in quotes as |``bar''|. -% -% -% -% -% \subsection{Checking for a value or boolean} -% -% It would make perfect sense to make |\NoValue| a \LaTeX3 quark but -% as there is a real danger of it getting executed by accident it is -% best not to as it would result in an infinite loop. -% -% \DescribeMacro\NoValue -% For this reason |\NoValue| is defined to expand to the string -% |-NoValue-| which would get typeset if ever executed thus clearly -% indicating the type of error the writer made. -% -% However this makes testing for this token slightly complicated as in -% that case the test -% \begin{verbatim} -% \tl_set:Nn \l_seen_tl {#1} -% \tl_set:Nn \l_hidden_novalue_tl {\NoValue} -% \tl_if_eq:NNTF \l_seen_tl \l_hidden_novalue_tl -% \end{verbatim} -% will be true if |#1| was |\NoValue| but false if |#1| itself -% contains a macro which contains |\NoValue|; a case that happens -% unfortunately very often in practice. Using an unguarded |x| type -% expansion to define |\l_seen_tl| is out of the question as |#1| is -% typically either |\NoValue| or arbitrary user input for which we -% can't properly guard it unless we are sure people only use robust -% commands. When running a pure \LaTeX3 format where all document -% commands are robust this is perhaps something to be looked at again -% but when running on top of \LaTeXe{} we have to be careful. -% -% Therefore we use a somewhat different procedure here, which goes -% like this: -% \begin{enumerate} -% \item Store |#1| in a temporary variable and check if it equals a -% variable containing |\NoValue|. If true, execute the \meta{true} -% code, otherwise go to~2. -% \item Peek at the first token in |#1|. If this is a macro taking no -% arguments expand |#1| once and go to~1. Otherwise execute the -% \meta{false} code. -% \end{enumerate} -% The reason for the careful peeking ahead is that |#1| may very well -% be a macro taking arguments and it is not certain that these -% arguments are present! Hence this could lead to the well-known -% \begin{verbatim} -% Argument of \XXX has an extra } -% \end{verbatim} -% and we wouldn't want that\dots{} Goes without saying that this -% procedure is quite tedious but usually it will exit after the first -% time |#1| has been inspected. One additional test could be added, -% namely that |#1| should also contain exactly one token but I don't -% think that is going to matter much. -% -% \DescribeMacro\IfNoValueTF -% \DescribeMacro\IfNoValueT -% \DescribeMacro\IfNoValueF -% \DescribeMacro\IfValueTF -% \DescribeMacro\IfValueT -% \DescribeMacro\IfValueF -% These macros are used for checking if an optional argument was -% present as in the example below. -% \begin{verbatim} -% \DeclareDocumentCommand\testcmd{om}{ -% \IfNoValueTF{#1}{``#2''}{#1,#2} -% } -% \end{verbatim} -% -% -% -% \DescribeMacro\IfBooleanTF -% \DescribeMacro\IfBooleanT -% \DescribeMacro\IfBooleanF -% As mentioned earlier, the parsing result for a symbol argument like -% |s| or |S{+}| is represented as the one of the tokens |\c_true_bool| or -% |\c_false_bool| respectively. To test for these values the macro -% |\IfBooleanTF| can be used. It expects as its first argument either -% |\c_true_bool| or |\c_false_bool| and executes its second or third argument -% depending on this value. |\IfBooleanT| and |\IfBooleanF| are -% obvious shortcuts. -% -% At one point in time I thought that one can represent everything -% using |\NoValue|, e.g., for the star case either return |*| or -% |\NoValue|. However, this slows down processing of commands like -% |\\*| considerably since they would then have to use a slower -% internal test instead of a fast two-way switch. -% -% -% \subsection{New argument types and shorthands} -% -% New argument types can be added at in a fairly straight forward -% manner with the command -% |\DeclareArgumentType|\DescribeMacro\DeclareArgumentType. This -% command takes seven arguments: |#1| is a symbol denoting the -% argument type, |#2| is the token the scanner should look for, |#3| -% is one of the words |meaning|, |charcode| or |catcode| which is -% handed down to the underlying |\peek_meaning:NTF| or -% |\peek_charcode:NTF| etc. functions. For instance you can use the -% |charcode| version if you want to pick up a literal |*| and not -% just something that has the same \emph{meaning} as a regular -% |*|. |#4| is for executing a special action (like an error message) -% if no argument is found, |#5| is the default value in case of a -% missing argument, |#6| is what the scanner will encounter, and -% finally |#7| is what the scanner grabs from the argument type. This -% is perhaps clearer with an example\dots{} This is how the |o| type -% is implemented: -% \begin{verbatim} -% \DeclareArgumentType o [ {meaning} {} {\NoValue} {#1[#2]} {#2} -% \end{verbatim} -% In a similar fashion a |b| type expecting its argument inside |<| -% and |>| would be defined as -% \begin{verbatim} -% \DeclareArgumentType b < {meaning} {} {\NoValue} {#1<#2>} {#2} -% \end{verbatim} -% -% \DescribeMacro\DeclareArgumentTypeWithDefault -% |\DeclareArgumentTypeWithDefault| is even simpler as this type -% expects the default value to be input at the time of argument -% specification. Thus arguments |#3| and |#4| from above are -% unnecessary and are simply absent. Thus the |O| type is -% implemented\footnote{I would say it is at best wishful thinking -% that the interface could be something like -% \texttt{\cs{DeclareArgumentTypeWithDefault} -% C\{2\}\{meaning\}\{(\#1,\#2)\}\{\{\#1\}\{\#2\}\}} as it would -% be quite troublesome implementation-wise and the current syntax -% isn't that difficult to use.} as -% \begin{verbatim} -% \DeclareArgumentTypeWithDefault O [ {meaning}{#1[#2]} {#2} -% \end{verbatim} -% and again a similar |B| type could be implemented as -% \begin{verbatim} -% \DeclareArgumentTypeWithDefault B < {meaning}{#1<#2>} {#2} -% \end{verbatim} -% -% -% There is also a possibility to define a shorthand for a specific -% sequence of arguments with the command -% \DescribeMacro\DeclareArgumentTypeShorthand -% |\DeclareArgumentTypeShorthand|. As an example the |s| argument -% type is just a different way of saying |S{*}| so it's simply -% implemented as -% \begin{verbatim} -% \DeclareArgumentTypeShorthand s {S{*}} -% \end{verbatim} -% Similarly one could add a shorthand |M| for inserting five -% mandatory arguments where the latter is allowed to take |\par| in -% its argument: -% \begin{verbatim} -% \DeclareArgumentTypeShorthand M {mmmm>{P}m} -% \end{verbatim} -% -% Finally there is also the command -% \DescribeMacro\DeclareSymbolArgument|\DeclareSymbolArgument| which -% defines the low level interface to looking ahead for specific -% symbols and removing them. For instance the |S| type argument is -% declared as -% \begin{verbatim} -% \DeclareSymbolArgument S{meaning} -% \end{verbatim} -% So symbols picked up by this type will compare the meaning of the -% tokens. One could do a -% \begin{verbatim} -% \DeclareSymbolArgument A{charcode} -% \end{verbatim} -% and then the |A| type would compare character codes instead. For -% instance a command which expects a |+| symbol would return -% \meta{true} if a |+| of any catcode is detected, not just catcode -% 12 as is usual. -% -% \subsection{Some comments on the need for the \texttt{O} specifier} -% -% With |\newcommand| there is the possibility of specifying a default -% for an optional argument which is stored away in a more or less -% efficient manner. For example below is the old definition of -% |\linebreak| as can be found in the \LaTeX2e kernel: -%\begin{verbatim} -%\def\linebreak{\@testopt{\@no@lnbk-}4} -%\def\@no@lnbk #1[#2]{% -% \ifvmode -% \@nolnerr -% \else -% \@tempskipa\lastskip -% \unskip -% \penalty #1\@getpen{#2}% -% \ifdim\@tempskipa>\z@ -% \hskip\@tempskipa -% \ignorespaces -% \fi -% \fi} -%\end{verbatim} -% Ignoring for the moment that the above is slightly optimised an -% expansion of this code under |\tracingall| will result in about 90 -% lines of tracing output. If we reimplement this using -% |\DeclarDocumentCommand\linebreak{o}| we have to use |\IfNoValueTF| -% to find out if an argument was present which (because of the careful -% expansion we do internally) results in about twice as much of -% tracing lines. In contrast using |O{4}| as below we end up with 110 -% lines, which seems roughly the price we have to pay for the extra -% generality available (though this could perhaps even be reduced by a -% better implementation of the parsing machine as originally done by -% David, before i talked him into adding support for arguments in the -% end code of an environment).\footnote{These comments were made -% before the extensive changes in expl3 and xparse in 2005.} -% -%\begin{verbatim} -%\DeclareDocumentCommand\linebreak { O{4} } -% { -% \ifvmode -% \@nolnerr -% \else -% \@tempskipa\lastskip -% \unskip -% % \IfNoValueTF{#1} -% % {\break} -% % {\penalty -\@getpen{#1}} -% \penalty -\@getpen{#1} -% \ifdim\@tempskipa>\z@ -% \hskip\@tempskipa -% \ignorespaces -% \fi -% \fi -% } -%\end{verbatim} -% -% -% \subsection{A somewhat complicated example} -% -% This example reimplements the |\makebox| and |\framebox| interface -% of \LaTeX{} both of which are unfortunately quite overloaded -% syntactically. For this reason the example isn't meant to show good -% coding practice but to show the power of the interface even though -% applied in a somewhat bad way. -% -% |\makebox| and |\framebox| support the following different document -% syntax forms: -% \begin{itemize} -% \item -% |\makebox{A}|: only a single mandatory argument. -% -% \item -% |\makebox[20pt]{B}|: one optional argument specify the box width. -% -% -% \item -% |\makebox[30pt][r]{C}|: two optional arguments the second specifying -% the text position within the box being made (l,c,r being allowed -% with c being the default). -% -% \item -% |\makebox(20,30){D}|: within picture mode the width is specified not -% as an optional argument in brackets but as a coordinate pair. -% -% \item -% |\makebox(0,0)[lt]{E}|: in that case an optional argument following -% coordinate pair denotes the placement within the box which can have -% different values compared to case C above. -% \end{itemize} -% -% To cater for this overloaded structure we can define |\makebox| to -% be something like the following: -%\begin{verbatim} -%\DeclareDocumentCommand \makebox { C{\NoValue} o O{c} m} -% { \IfNoValueTF{#1} -% { \ltx@maketextbox{#2}{#3}{#4} } -% { \ltx@makepicbox #1 {#2}{#4} } } -%\end{verbatim} -% In other words: if we do not see a coordinate pair first (i.e., -% first argument is |\NoValue| then we expect up to two optional -% arguments (the width of the box or |\NoValue| if not given and the -% placement specifier with a default of |c| if not given) and one -% mandatory one which is the text. In that case we pass argument 2 to -% 4 to an internal function |\ltx@maketextbox| which builds the text -% box. -% -% Otherwise, if the first argument is a coordinate pair we parse an -% optional argument denoting the placement specifier. Since -% \texttt{xparse} doesn't support variant syntax we actually parse for -% another optional argument (which has no meaning in that case and is -% in fact ignored if present) followed by a mandatory one containing -% the box text. In that case we pass the coordinate pair (|#1|), the -% specifier (|#2|), and the text (|#4|) to the function -% |\ltx@makepicbox| which builds the picture box. Note the special -% handling of the coordinatesD: which are passed without surrounding -% braces to |\ltx@makepicbox|: since the coordinate argument looks -% like |{x-val}{y-val}| the receiving function |\ltx@makepicbox| gets -% the |x-val| as argument one and the |y-val| as argument two. -% -% A definition for |\framebox| would look more or less identical -% except that we would need to pass the arguments to slightly -% different internal functions. The alternative is to give the -% internal functions an extra argument that controls whether or not a -% frame is bying built. -% -% \begin{macro}{\ltx@makepicbox} -% So here is a possible implementation of |\ltx@makepicbox| that -% builds a picture box with or without frame. It takes the following -% mandatory arguments: -% \begin{enumerate} -% \item x-part of coordinate -% \item y-part of coordinate -% \item placement specifier, e.g., |lt| or |\NoValue| -% \item text of box -% \item the token |\frame| (if a frame should surround the box) or the -% token |\@firstofone| --- not pretty i agree -% \end{enumerate} -%\begin{verbatim} -%\def\ltx@makepicbox#1#2#3#4#5 -% { -% #5{ -% \vbox to#2\unitlength -% {\let\mb@b\vss \let\mb@l\hss\let\mb@r\hss -% \let\mb@t\vss -% \IfNoValueF{#3} -% { -% \@tfor\reserved@a :=#3\do{ -% \if s\reserved@a -% \let\mb@l\relax\let\mb@r\relax -% \else -% \expandafter\let\csname mb@\reserved@a\endcsname\relax -% \fi}% -% } -% \mb@t -% \hb@xt@ #1\unitlength{\mb@l #4\mb@r} -% \mb@b -% \kern\z@} -% } -% } -%\end{verbatim} -% \end{macro} -% -% -% -% \begin{macro}{\ltx@maketextbox} -% For the text case the internal function could take the following -% mandatory arguments: -% \begin{enumerate} -% \item width of the box or |\NoValue| (denoting to build the box at -% natural width) -% \item placement specifier, e.g., |l|. (No test for |\NoValue| being undertaken) -% \item text of box -% \item the token |\fbox| (if a frame should surround the box) or the -% token |\mbox| -% \end{enumerate} -% The actual code is taken straight from the current \LaTeX{} kernel -% and looks kind of scary. -%\begin{verbatim} -%\def\ltx@maketextbox#1#2#3#4 -% { -% \IfNoValueTF{#1} -% {#4{#3}} -% { -% \leavevmode -% \@begin@tempboxa\hbox{#3} -% \setlength\@tempdima{#1} -% \ifx#4\fbox -% \setbox\@tempboxa\hb@xt@\@tempdima -% {\kern\fboxsep\csname bm@#2\endcsname\kern\fboxsep} -% \@frameb@x{\kern-\fboxrule} -% \else -% \hb@xt@\@tempdima{\csname bm@#2\endcsname} -% \fi -% \@end@tempboxa -% } -% } -%\end{verbatim} -% \end{macro} -% -% \begin{macro}{\makebox} -% \begin{macro}{\framebox} -% Given the above internal functions the declarations of |\makebox| -% and |\framebox| would then look like this: -%\begin{verbatim} -%\DeclareDocumentCommand \makebox { C{\NoValue} o O{c} m} -% { \IfNoValueTF{#1} -% { \ltx@maketextbox{#2}{#3}{#4}\mbox } -% { \ltx@makepicbox #1 {#2}{#4}\@firstofone } } -% -%\DeclareDocumentCommand \framebox { C{\NoValue} o O{c} m} -% { \IfNoValueTF{#1} -% { \ltx@maketextbox{#2}{#3}{#4}\fbox } -% { \ltx@makepicbox #1 {#2}{#4}\frame } } -%\end{verbatim} -% \end{macro} -% \end{macro} -% -% -% -% Here's another example which shows how one can use the |W| specifier. -% The \textsf{amsmath} environments use their own definition of |\\| -% which goes under the name |\math@cr|. As there is a good chance the -% next line of math begins with either an asterisk or something in -% square brackets this often leads to errors. The following example -% definition works (I \emph{did} try it). -% \begin{verbatim} -% \ExplSyntaxOn -% \makeatletter -% \DeclareDocumentCommand\math@cr{>{W}s >{W}O{\z@}}{ -% \IfBooleanTF{#1} -% { \global\@eqpen\@M }{ -% \global\@eqpen -% \ifnum\dspbrk@lvl <\z@ -% \interdisplaylinepenalty -% \else -% -\@getpen\dspbrk@lvl -% \fi -% } -% \math@cr@@@ -% \noalign{\vskip#2\relax} -% } -% \makeatother -% \ExplSyntaxOff -% \end{verbatim} -% Note that this definition automatically avoids problems within the -% alignments even if it is called as |\\&|. -% -% -% -% -% \subsection{Open issues} -% -% In this section unresolved issues or ideas to think about and -% perhaps implement are collected. There is no particular order to -% them. -% -% \begin{itemize} -% \item -% Support for parsing verbatim type of arguments was considered (and -% actually implemented at one stage. E.g., -% |g{|\meta{prepare-parsing}|}| where |g| first run -% \meta{prepare-parsing} (which might involve |catcode| -% changes)\footnote{urg horror!}, then look at the next token: if -% that would be a |{| it would scan a brace delimited argument -% (reverting catcodes of |{| and |}| if needed) otherwise would scan -% for an argument delimited by that token so that something like -% |\verb+%\+| would scan |%\| as its argument assuming that the -% \meta{prepare-parsing} turned |%| and |\| into non-letters. -% -% All kind of nasty problems lurking especially no proper error -% checks possible and of course as we all know such commands would -% then not work inside arguments of other commands. At least they -% would have some restrictions. -% -% Also no way to make the parsing smart by not accepting newlines as -% part of the code (|\verb| does this right now and this is really -% helpful as it catches runaways nicely). -% -% -% \item -% \textsf{xparse} should probably go into the \LaTeX3 kernel in which -% case it should also provide the definitions of |\begin| and |\end| -% and this raises a few questions: Will environments be defined as -% control sequences |\foo| and |\endfoo|? If they are do we then want -% to include support for a separate command |\foo| and if so what -% about using the environment forms in special scanner mechanisms -% where we \emph{can't} use |\begin{foo}|? In those cases one could -% use a special command like what the \textsf{fancyvrb} package -% provides with the command |\VerbatimEnvironment| and all packages -% that define such special arguments should then also make sure that -% the |\foo| command issued on its own should cause an error. -% Another solution would be to simply define environments as -% |\beginfoo| and |\endfoo| and then let |\begin| check if it was -% used to call an environment or a command. If the latter is the -% case then insert grouping as that could be handled by |\beginfoo| -% itself. When |\end| is reached check if |\endfoo| exists. If it -% does then use that, otherwise we were probably using a normal -% command which should just close the group. -% \end{itemize} -% -% -% \subsection{Rejected ideas---and why} -% -% Let's say the document command |\testmo| has signature |mo|. If we -% call it as |\testmo{arg} [opt]| a following space will be obeyed. -% However calling it with the mandatory argument only as in -% |\testmo{arg}| will gobble a following space because the peek ahead -% in the |o| type ignores spaces. We can record that a space has been -% gobbled when peeking ahead and we can also put it back in if needed -% but I have only ever seen one request for this and in that case the -% better solution was to use a signature |mWo| so that no spaces are -% allowed between the mandatory and the optional argument. One could -% even argue that this is the most appropriate thing to do if the user -% is really that sensitive to spaces! In any case it is not -% implemented here as it creates an unnecessary overhead for something -% that is never used and a simple solution exists. -% -% \subsection{Experimental features} -% -% Experimental features in an experimental packages\dots{} Needless to -% say that you can't rely on them staying! -% -% -% One new feature is what I decided to call ``pseudo -% arguments''. Strictly speaking these aren't real arguments but -% instead read by removing a begin group token and then using -% |\tex_aftergroup:D| to regain control. The definition of |\footnote| -% in plain \TeX\ uses this so that people can use -% |\verb| and the like inside the footnotes. The command -% |\DeclarePseudoArgument|\DescribeMacro{\DeclarePseudoArgument} takes -% four arguments: |#1| is a name for the pseudo argument, |#2| is the -% number of arguments it takes, |#3| is the action to be taken right -% before the left brace is removed and |#4| is what to be done when -% the right brace has been read and we regain control. Note that both -% |#3| and |#4| may use arguments! Here is a silly example: -% \begin{verbatim} -% \DeclarePseudoArgument{boxtest}{1} -% {Before:~`#1',\hbox_set_inline_begin:N \l_tmpa_box } -% {\hbox_set_inline_end: \iow_space: the~ box:~ -% \hbox_unpack_and_clear:N\l_tmpa_box ,~ -% After:~`#1'} -% \end{verbatim} -% Now when you want to use it, you simply call it with the macro -% |\UsePseudoArgument|\DescribeMacro{\UsePseudoArgument}, which as its -% first argument takes a name and the remaining depend on how many -% arguments the pseudo argument was defined to have. Hence we could -% use our |boxtest| definition like this: -% \begin{verbatim} -% \DeclareDocumentCommand\sillyboxtest{m}{ -% Testing~#1:~\UsePseudoArgument{boxtest}{#1} -% } -% \end{verbatim} -% Then calling |\sillyboxtest{AB}{a\verb*+% $%&\+b}| produces -% \begin{quote} -% Testing AB: Before: `AB', the box: -% a\verb*+% $%&\+b, After: `AB' -% \end{quote} -% |\UsePseudoArgument| should always come last in the document -% command definition. -% -% \StopEventually{} -% -% \section{Implementation} -% -% Versions prior to and including 1.19 contained several different -% implementations. These are gone now but can be looked at by -% getting an older version of the package from the CVS repository. -% -% First the required packages. -% \begin{macrocode} -%<*package> -\ProvidesExplPackage - {\filename}{\filedate}{\fileversion}{\filedescription} -\RequirePackage{expl3} -% \end{macrocode} -% -% -% -% \subsection{Error and warning messages} -% -% Here we define the error message we're going to use in this package. -% -% \begin{macro}{\xparse_already_defined_error_msg:N} -% \begin{macro}{\xparse_not_yet_defined_error_msg:N} -% \begin{macro}{\xparse_begins_with_end_error_msg:N} -% \begin{macro}{\xparse_unknown_arg_type_error_msg:N} -% \begin{macro}{\xparse_number_of_arguments_error_msg:Nn} -% \begin{macro}{\xparse_no_command_implementation_warning:n} -% The names should give the function's purpose away. -% \begin{macrocode} -\cs_new_nopar:Nn \xparse_already_defined_error_msg:N { - \xparse_error:x { - Command~name~`\token_to_str:N #1'~ already~defined! - } -} -\cs_new_nopar:Nn \xparse_not_yet_defined_error_msg:N { - \xparse_error:x { - Command~`\token_to_str:N #1'~ not~ yet~defined! - } -} -\cs_new_nopar:Nn \xparse_begins_with_end_error_msg:N { - \xparse_error:x { - Command~`\token_to_str:N #1'~begins~with~ - `\token_to_str:N \end'! - } -} -% \end{macrocode} -% This one is for when we've encountered an unknown argument type in -% the argument specification. We can try to recover by putting in an -% |m| type instead and hope for the best. -% \begin{macrocode} -\cs_new_nopar:Nn \xparse_unknown_arg_type_error_msg:N { - \xparse_error:x { - Unknown~ argument~ type~ `#1'~ - I'll~ substitute~ it~ with~ `m'~ for~ now.~ Fingers~ crossed... - } -} -% \end{macrocode} -% A message for people using the wrong number of arguments. -% \begin{macrocode} -\cs_new_nopar:Nn \xparse_no_command_implementation_warning:n { - \xparse_warning:x {No~ implementation~ for~ `#1'~ defined} -} -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\xparse_error:x} -% \begin{macro}{\xparse_warning:x} -% Here's how we produce the error messages and warnings currently. -% This awaits a proper error message module! -% \begin{macrocode} -\cs_new_nopar:Nn \xparse_error:x {\tex_errmessage:D {xparse~error:~#1}} -\cs_new_nopar:Nn \xparse_warning:x {\iow_term:x{xparse~warning:~#1}} -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% -% -% \subsection{Checking for valid command names} -% -% -% \begin{macro}{\xparse_if_definable:NT} -% \begin{macro}{\xparse_if_definable:cT} -% An undefinable command is either |\c_undefined| or |\scan_stop:| and -% furthermore we won't allow it to start with |\end|. -% If the command is definable we do what was asked for otherwise -% we give an appropriate error message. -% \begin{macrocode} -\cs_new_nopar:Npn \xparse_if_definable:NTF #1 { -% \end{macrocode} -% First check if the control sequence is free. -% \begin{macrocode} - \cs_if_free:NTF #1 -% \end{macrocode} -% If free check if it begins with |\end|. -% \begin{macrocode} - { - \xparse_begins_with_end:NTF #1 - { \xparse_begins_with_end_error_msg:N #1 \use_ii:nn } - \use_i:nn - } -% \end{macrocode} -% If not free give an error message. -% \begin{macrocode} - { \xparse_already_defined_error_msg:N #1 \use_ii:nn } -} -\cs_generate_variant:Nn \xparse_if_definable:NTF {c} -% \end{macrocode} -% \end{macro} -% \end{macro} -% \begin{macro}{\xparse_if_redefinable:NTF} -% \begin{macro}{\xparse_if_redefinable:cTF} -% A re-definable command is almost the same as above but here we -% demand that it already exists. -% \begin{macrocode} -\cs_new_nopar:Npn \xparse_if_redefinable:NTF #1 { - \cs_if_free:NTF #1 - { \xparse_not_yet_defined_error_msg:N #1 \use_ii:nn } - { - \xparse_begins_with_end:NTF #1 - { \xparse_begins_with_end_error_msg:N #1 \use_ii:nn } - \use_i:nn - } -} -\cs_generate_variant:Nn \xparse_if_redefinable:NTF {c} -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% -% \begin{macro}{\xparse_begins_with_end:NTF} -% \begin{macro}{\xparse_begins_with_end_aux:N} -% Finally we need the magic function for checking if the control -% sequence begins with |\end|. -% We wish to determine if the control sequence in question begins with -% |\end| which is forbidden. The end goal is to get a control sequence -% consisting of the first three letters to test against |\end| with -% |\cs_if_eq_name_p:NN|. The function |\cs_to_str:N| will remove the |\| -% from a command name and return the rest of the characters with -% category code 12. Thus using an |f| type expansion to get the first -% three characters is perfectly safe as it'll stop right there. Then -% we turn these three letters into a control sequence with a simple -% expansion which is then tested with |\xparse_begins_with_end_aux:N|. -% \begin{macrocode} -\cs_new_nopar:Npn \xparse_begins_with_end:NTF #1 { -% \end{macrocode} -% We do it all in a group as there is no need to fill up the hash -% table with weird three letter control sequences. -% \begin{macrocode} - \group_begin: - \exp_args:Nc \xparse_begins_with_end_aux:N { - \tl_head_iii:f { \cs_to_str:N #1 ??} - } -} -% \end{macrocode} -% After the above expansion tricks we now have a real control sequence -% to test against |\end|. We end the group again. -% \begin{macrocode} -\cs_new_nopar:Nn \xparse_begins_with_end_aux:N { - \if_predicate:w \cs_if_eq_name_p:NN #1 \end - \group_end: - \exp_after:wN \use_i:nn - \else: - \group_end: - \exp_after:wN \use_ii:nn - \fi: -} -% \end{macrocode} -% Note that these definitions make no use of temporary variables. -% \end{macro} -% \end{macro} -% -% -% -% -% -% \subsection{The low level definitions} -% -% -% First some helper functions -% \begin{macro}{\l_xparse_grabbed_args_toks} -% \begin{macro}{\l_xparse_end_environment_args_toks} -% \begin{macro}{\l_xparse_mandatory_args_int} -% \begin{macro}{\l_xparse_total_args_int} -% We need some \meta{token} registers to keep track of things. We also -% allocate an \meta{int} register to keep track of the number of -% arguments. -% \begin{macrocode} -\toks_new:N \l_xparse_grabbed_args_toks -\toks_new:N \l_xparse_end_environment_args_toks -\int_new:N \l_xparse_mandatory_args_int -\int_new:N \l_xparse_total_args_int -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% -% -% \begin{macro}{\xparse_declare_document_command:Nnn} -% \begin{macro}{\xparse_declare_document_command:cnn} -% |\xparse_declare_document_command:Nnn| is a two step procedure. The -% user level command |\|\meta{cmd} contains the argument grabbers -% while the internal command |\\|\meta{cmd} holds the actual -% definition of what to do with the arguments. Naturally this calls -% for every such user level command to be robust which is done using -% the \eTeX{} protection feature. -% \begin{macrocode} -\cs_set:Nn \xparse_declare_document_command:Nnn { -% \end{macrocode} -% First we prepare the signature. -% \begin{macrocode} - \xparse_prepare_signature:n {#2} -% \end{macrocode} -% Now for the document command. Make it robust and make sure it starts -% with |\toks_set:Nn \l_xparse_grabbed_args_toks {\\|\meta{cmd}|}|. -% \begin{macrocode} - \cs_set_protected_nopar:Npx #1 { - \exp_not:n { \toks_set:Nn \l_xparse_grabbed_args_toks } - {\exp_not:c {\token_to_str:N #1}} -% \end{macrocode} -% Then add the argument grabbers which contain code gathered when -% preparing the signature. -% \begin{macrocode} - \toks_use:N \l_xparse_grabbed_args_toks -% \end{macrocode} -% Finally execute |\toks_use:N \l_xparse_grabbed_args_toks| which now -% holds the grabbed arguments enclosed in braces and starts with the -% internal command |\\|\meta{cmd}. -% \begin{macrocode} - \exp_not:n{ \toks_use:N \l_xparse_grabbed_args_toks} - } -% \end{macrocode} -% Define the internal command by making it a |\long| macro with number -% of arguments equal to |\l_xparse_total_args_int| and definition as -% given by |#3|. Even though this internal macro allows |\par| in its -% argument the decision is left to the individual argument grabbers. -% \begin{macrocode} - \cs_generate_from_arg_count:cNnn {\token_to_str:N #1}\cs_set:Npn - \l_xparse_total_args_int{#3} -} -\cs_generate_variant:Nn \xparse_declare_document_command:Nnn {cnn} -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\xparse_declare_document_environment:nnnn} -% |\xparse_declare_document_environment:nnnn| is almost the same. In -% order to use the grabbed arguments we take them from -% |\l_xparse_grabbed_args_toks| just before they are executed. We -% also insert a |\group_begin:| as it will otherwise fail miserably -% in case a user tries to use it without |\begin ... \end|. -% \begin{macrocode} -\cs_new:Nn \xparse_declare_document_environment:nnnn { - \xparse_declare_document_command:cnn {#1}{#2} - { \group_begin: - \toks_set_eq:NN \l_xparse_end_environment_args_toks - \l_xparse_grabbed_args_toks - #3 - } -% \end{macrocode} -% We let |\end|\meta{envir} equal to a standard version which will do -% all the work. -% \begin{macrocode} - \cs_set_eq:cN {end #1} \xparse_parsed_end_environment: -% \end{macrocode} -% Now define |\end\\|\meta{envir}. -% \begin{macrocode} - \cs_generate_from_arg_count:cNnn {end \token_to_str:N \\ #1}\cs_set:Npn - \l_xparse_total_args_int{#4} -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\xparse_parsed_end_environment:} -% \begin{macro}{\xparse_parsed_end_environment_aux:N} -% |\end|\meta{envir} is set equal to |\xparse_parsed_end_environment:| -% which then executes |\end\\|\meta{envir}. The |\\|\meta{envir} comes -% from the argument grabbing. The remainder of the token list is the -% grabbed arguments. We better make this robust as well. -% \begin{macrocode} -\cs_new_protected_nopar:Nn \xparse_parsed_end_environment: { - \exp_after:wN \xparse_parsed_end_environment_aux:N - \toks_use:N \l_xparse_end_environment_args_toks - \group_end: -} -\cs_new_nopar:Nn \xparse_parsed_end_environment_aux:N { - \use:c {end \token_to_str:N #1 } -} -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% -% \subsection{The high level commands} -% -% -% Here we set up the functions for defining and redefining document -% commands and environments. It's all rather straight forward here so -% I've saved on the comments. -% -% \begin{macro}{\DeclareDocumentCommand} -% \begin{macro}{\NewDocumentCommand} -% \begin{macro}{\RenewDocumentCommand} -% In case we can't do what the user wanted we gobble the next -% arguments from the input stream. For commands there are two -% arguments waiting. -% \begin{macrocode} -\cs_new_eq:NN \DeclareDocumentCommand \xparse_declare_document_command:Nnn -\cs_new_nopar:Npn \NewDocumentCommand #1 { - \xparse_if_definable:NTF #1 - { \xparse_declare_document_command:Nnn #1 } - \use_none:nn -} -\cs_new_nopar:Npn \RenewDocumentCommand #1 { - \xparse_if_redefinable:NTF #1 - { \xparse_declare_document_command:Nnn #1 } - \use_none:nn -} -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\DeclareDocumentEnvironment} -% \begin{macro}{\NewDocumentEnvironment} -% \begin{macro}{\RenewDocumentEnvironment} -% Three arguments for environments. -% \begin{macrocode} -\cs_new_eq:NN \DeclareDocumentEnvironment - \xparse_declare_document_environment:nnnn -\cs_new_nopar:Npn \NewDocumentEnvironment #1 { - \xparse_if_definable:cTF {#1} - { \xparse_declare_document_environment:nnnn {#1} } - \use_none:nnn -} -\cs_new_nopar:Npn \RenewDocumentEnvironment #1 { - \xparse_if_redefinable:cTF {#1} - { \xparse_declare_document_environment:nnnn {#1} } - \use_none:nnn -} -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\ProvideDocumentCommand} -% \begin{macro}{\ProvideDocumentEnvironment} -% When providing a command we just check if the control sequence is -% free. If it is let |\DeclareDocument...| do the rest, otherwise -% gobble the next arguments. -% \begin{macrocode} -\cs_new_nopar:Npn \ProvideDocumentCommand #1{ - \cs_if_free:NTF #1 - { \DeclareDocumentCommand #1} - \use_none:nn -} -\cs_new_nopar:Npn \ProvideDocumentEnvironment #1{ - \cs_if_free:cTF {#1} - { \DeclareDocumentEnvironment {#1} } - \use_none:nnn -} -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% -% \subsubsection{A class designer interface} -% -% Below is the implementation of |\DeclareDocumentCommandInterface| -% and the close cousin |\DeclareDocumentCommandImplementation|. -% It is an open issue whether this concept should be supported. -% -% \begin{macro}{\DeclareDocumentCommandInterface} -% With this macro we define the document command |#1| to have -% signature |#3| which does the argument grabbing. The arguments are -% passed on to the internal command |\impl-#2|. -% \begin{macrocode} -\cs_new:Npn \DeclareDocumentCommandInterface #1#2#3{ - \xparse_prepare_signature:n {#3} - \cs_set_protected_nopar:Npx #1 { - \exp_not:n { \toks_set:Nn \l_xparse_grabbed_args_toks } - {\exp_not:c {impl-#2}} - \toks_use:N\l_xparse_grabbed_args_toks - \exp_not:n{ \toks_use:N \l_xparse_grabbed_args_toks} - } -% \end{macrocode} -% Define the internal command by making it a |\long| macro as we did -% for |\DeclareDocumentCommand| but give it just a default definition -% instead (usually an error message). -% \begin{macrocode} - \cs_generate_from_arg_count:cNnn {impl-#2} \cs_set:Npn - \l_xparse_total_args_int - {\xparse_undefined_command_implementation:n{#2}} -} -% \end{macrocode} -% \end{macro} -% \begin{macro}{\xparse_undefined_command_implementation:n} -% What to do if no implementation is made and the command is -% called. Let's just typeset the name in quotes indicating that -% something is wrong. -% \begin{macrocode} -\cs_new_nopar:Nn \xparse_undefined_command_implementation:n { - ``#1'' -% \ensuremath{\langle\textit{#1}\rangle} - \xparse_no_command_implementation_warning:n {#1} -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\DeclareDocumentCommandImplementation} -% Defines the internal command |\impl-#1| with |#2| arguments -% and definition |#3|. -% \begin{macrocode} -\cs_new:Npn \DeclareDocumentCommandImplementation #1#2#3{ - \cs_generate_from_arg_count:cNnn {impl-#1}\cs_set:Npn {#2}{#3} -} -% \end{macrocode} -% \end{macro} -% -% -% \subsection{Creating the signature} -% -% -% \begin{macro}{\xparse_prepare_signature:n} -% The actual preparation of the signature is always the same but we -% have different ways of handling it afterwards, so we make it a -% separate function. -% \begin{macrocode} -\cs_new_nopar:Nn \xparse_prepare_signature:n { -% \end{macrocode} -% Initialize the counter taking care of the number of arguments. In -% case we reach more than nine we will give an error message later on. -% \begin{macrocode} - \int_zero:N \l_xparse_total_args_int -% \end{macrocode} -% Clear the token register we use when building the signature and the -% number of ``normal'' mandatory arguments. Also clear out the special -% markers and initialize the two booleans to \meta{false}. -% \begin{macrocode} - \toks_clear:N \l_xparse_grabbed_args_toks - \int_zero:N \l_xparse_mandatory_args_int - \bool_gset_false:N \g_xparse_insert_marker_bool - \bool_gset_false:N \g_xparse_allow_par_bool - \tl_gset_eq:NN \g_xparse_ignore_marker_tl - \g_xparse_ignore_spaces_marker_tl -% \end{macrocode} -% Then call |\xparse_parse_signature:n|. -% \begin{macrocode} - \xparse_parse_signature:n #1 \q_nil -} -% \end{macrocode} -% \end{macro} -% -% -% \subsection{The argument types} -% -% -% -% All argument types must be denoted by single letters.\footnote{You -% can use a multi-letter sequence to denote a shorthand but it -% requires you to put two brace groups around it in the signature and -% it's not officially supported.} We have three categories of letters: -% Special markers, basic argument types, and shorthands. -% -% For certain argument types where we peek ahead in the token stream -% we have a multitude of choices for how the macro should work: -% Should it ignore spaces or other tokens? Which test should it use -% for comparing tokens: meaning, catcode or charcode? Because of -% these difficulties every argument that require peeking ahead must -% be declared as one of the three test types. -% -% \subsubsection{Special markers} -% -% Since there are different markers that may be used at the same -% time, we use the a special ``insert'' marker |>| to do this. -% -% \begin{macro}{\g_xparse_ignore_marker_tl} -% The current ignore marker is contained in this string. -% \begin{macrocode} -\tl_new:Nn \g_xparse_ignore_marker_tl {} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\g_xparse_ignore_marker_seq} -% We start out by declaring a new sequence to contain all the -% different types of ignore functions. Each element should be the -% missing part of a |\peek_meaning|\meta{text}|:NTF| function. -% \begin{macrocode} -\seq_new:N \g_xparse_ignore_marker_seq -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\g_xparse_insert_marker_bool} -% A boolean to check if we just saw an insert marker. -% \begin{macrocode} -\bool_new:N \g_xparse_insert_marker_bool -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\xparse_add_arg_type_>:} -% The insert marker is called when this is seen. Is has a funny -% definition but it works. |#1| is some test in the loop function -% and |#2| is the list of markers. -% \begin{macrocode} -\cs_new_nopar:cpn {xparse_add_arg_type_>:} #1 - \xparse_read_arg_type_or_grab_default:n #2{ -% \end{macrocode} -% Insert pending |m| args first. -% \begin{macrocode} - \xparse_add_remaining_m_args: -% \end{macrocode} -% Then we set the boolean true and subtract one from the argument -% count. -% \begin{macrocode} - \bool_gset_true:N \g_xparse_insert_marker_bool - \int_decr:N \l_xparse_total_args_int -% \end{macrocode} -% Then go through the list and call each subtype if it exists. -% \begin{macrocode} - \tl_map_inline:nn{#2}{ - \xparse_check_and_add_argument_type:N ##1 - } -% \end{macrocode} -% Finally call the loop again. -% \begin{macrocode} - \xparse_parse_signature:n -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\xparse_add_ignore_marker:Nnn} -% A small function for adding a new ignore type marker. -% \begin{macrocode} -\cs_new_nopar:Nn \xparse_add_ignore_marker:Nnn { - \tl_new:cn {g_xparse #2 _marker_tl}{#3} - \seq_gpush:Nv \g_xparse_ignore_marker_seq {g_xparse #2 _marker_tl} - \cs_new_nopar:cpn {xparse_add_arg_type_#1:}{ - \tl_gset_eq:Nc \g_xparse_ignore_marker_tl {g_xparse #2 _marker_tl} - } -} -% \end{macrocode} -% \end{macro} -% Here we add some ignore markers. -% \begin{macrocode} -\xparse_add_ignore_marker:Nnn W{_ignore_nothing}{} -\xparse_add_ignore_marker:Nnn i{_ignore_spaces}{_ignore_spaces} -\xparse_add_ignore_marker:Nnn I{_ignore_pars}{_ignore_pars} -% \end{macrocode} -% -% \begin{macro}{\xparse_add_arg_type_P:} -% This is simple, just set a boolean. -% \begin{macrocode} -\cs_new_nopar:Nn \xparse_add_arg_type_P: { - \bool_gset_true:N \g_xparse_allow_par_bool -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\g_xparse_allow_par_bool} -% The boolean for allowing the |\par| token. -% \begin{macrocode} -\bool_new:N \g_xparse_allow_par_bool -% \end{macrocode} -% \end{macro} -% -% -% \begin{macro}{\xparse_parse_signature:n} -% |\xparse_parse_signature:n| reads the signature one token/brace -% group at a time and builds a list of argument grabbers which is -% stored in |\l_xparse_grabbed_args_toks|. The function is recursive -% which is why we use a quark to delimit it. -% \begin{macrocode} -\cs_new_nopar:Nn \xparse_parse_signature:n { -% \end{macrocode} -% Check if we reached the end of the signature. -% \begin{macrocode} - \quark_if_nil:NTF #1 -% \end{macrocode} -% If we did we may have pending |m| type arguments so we clear them -% out here. Also check if the insert marker is true because if it is, -% something is wrong. Otherwise we just continue. -% \begin{macrocode} - { - \xparse_add_remaining_m_args: - } -% \end{macrocode} -% Then proceed with adding arguments. -% \begin{macrocode} - { - \int_incr:N \l_xparse_total_args_int - \xparse_check_and_add_argument_type:N #1 -% \end{macrocode} -% If the insert marker is true at this point we reset it again and -% also disallow |\par| in arguments and make all |\peek| functions use -% the |_ignore_spaces| versions. -% \begin{macrocode} - \bool_if:NT \g_xparse_insert_marker_bool - { - \bool_gset_false:N \g_xparse_insert_marker_bool - \bool_gset_false:N \g_xparse_allow_par_bool - \tl_gset_eq:NN \g_xparse_ignore_marker_tl - \g_xparse_ignore_spaces_marker_tl - } -% \end{macrocode} -% After adding arguments we better set the boolean false in case we -% don't have an insert marker. -% \begin{macrocode} -% \end{macrocode} -% First we add the remaining |m| arguments. -% \begin{macrocode} -% \end{macrocode} -% Then we run the loop again. -% \begin{macrocode} - \xparse_read_arg_type_or_grab_default:n - } -} -% \end{macrocode} -% \end{macro} -% -% -% \begin{macro}{\xparse_check_and_add_argument_type:N} -% This function checks if the argument type actually exists and gives -% an error if it doesn't. -% \begin{macrocode} -\cs_new_nopar:Nn \xparse_check_and_add_argument_type:N { - \cs_if_free:cTF {xparse_add_arg_type_#1:} - { \xparse_unknown_arg_type_error_msg:N #1 - \int_incr:N \l_xparse_mandatory_args_int - } -% \end{macrocode} -% Otherwise we just add it with its dedicated function. -% \begin{macrocode} - { \use:c {xparse_add_arg_type_#1:} } -} -% \end{macrocode} -% \end{macro} -% -% -% -% \begin{macro}{\xparse_read_arg_type_or_grab_default:n} -% \begin{macro}{\xparse_grab_default_arg:n} -% \begin{macro}{\xparse_grab_default_arg_allow_par:n} -% The function for grabbing a default value. The default setting is -% just to tun the loop again. However, some argument types need to -% add a default argument so we add these as well. -% \begin{macrocode} -\cs_new_eq:NN \xparse_read_arg_type_or_grab_default:n - \xparse_parse_signature:n -\cs_new_nopar:Nn \xparse_grab_default_arg:n { - \toks_put_right:Nn \l_xparse_grabbed_args_toks {{#1}} - \cs_set_eq:NN \xparse_read_arg_type_or_grab_default:n - \xparse_parse_signature:n - \xparse_parse_signature:n -} -\cs_new:Nn \xparse_grab_default_arg_allow_par:n { - \toks_put_right:Nn \l_xparse_grabbed_args_toks {{#1}} - \cs_set_eq:NN \xparse_read_arg_type_or_grab_default:n - \xparse_parse_signature:n - \xparse_parse_signature:n -} -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% -% -% -% -% -% -% \subsubsection{The default argument types} -% -% -% -% When scanning the signature we need to add the argument type which -% is done by a function |\xparse_add_arg_type_|\meta{X}|:|, where -% \meta{X} is the letter denoting the argument type. If not found an -% error message is issued ny |\xparse_unknown_arg_type_error_msg:N|. -% -% By default the package implements the argument types |m|, |S|, |c|, -% |C|, |o|, and |O| argument types as low level ones. The |s| type is -% a shorthand as we shall see later. -% -% As we don't make every single |m| argument a separate grabber all -% other types must clear out any pending |m|s. -% -% \paragraph{Mandatory arguments} -% -% Below follows the implementation of mandatory arguments. -% -% \begin{macro}{\xparse_add_arg_type_m:} -% Check if the user asked for an |m| argument allowing |\par| -% tokens and insert it. Otherwise increment the number of -% non-|\long| argument grabbers. -% \begin{macrocode} -\cs_new_nopar:Nn \xparse_add_arg_type_m: { - \bool_if:NTF \g_xparse_allow_par_bool - { - \toks_put_right:Nn \l_xparse_grabbed_args_toks {\xparse_allow_par_m:w} - } - { \int_incr:N \l_xparse_mandatory_args_int } -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\xparse_add_remaining_m_args:} -% And here is the function for clearing out normal pending |m| -% arguments. There is little point in adding any arguments if none -% are required. -% \begin{macrocode} -\cs_new_nopar:Nn \xparse_add_remaining_m_args: { - \intexpr_compare:nNnF \l_xparse_mandatory_args_int = \c_zero - { - \toks_put_right:Nx \l_xparse_grabbed_args_toks { - \exp_not:c{xparse_m - \int_use:N \l_xparse_mandatory_args_int - :w } - } - \int_zero:N \l_xparse_mandatory_args_int - } -} -% \end{macrocode} -% \end{macro} -% -% -% \begin{macro}{\xparse_m1:w} -% \begin{macro}{\xparse_m2:w} -% \begin{macro}{\xparse_m3:w} -% \begin{macro}{\xparse_m4:w} -% \begin{macro}{\xparse_m5:w} -% \begin{macro}{\xparse_m6:w} -% \begin{macro}{\xparse_m7:w} -% \begin{macro}{\xparse_m8:w} -% \begin{macro}{\xparse_m9:w} -% Grabbing 1--9 mandatory arguments. The one grabbing nine arguments -% will automatically end with -% |\toks_use:N \l_xparse_grabbed_args_toks| anyway so we avoid -% problems with that one. -% \begin{macrocode} -\cs_new_nopar:cpn {xparse_m1:w} #1 \l_xparse_grabbed_args_toks#2{ - \toks_put_right:Nn \l_xparse_grabbed_args_toks{{#2}} - #1 \l_xparse_grabbed_args_toks -} -\cs_new_nopar:cpn {xparse_m2:w} #1 \l_xparse_grabbed_args_toks #2#3{ - \toks_put_right:Nn \l_xparse_grabbed_args_toks{{#2}{#3}} - #1 \l_xparse_grabbed_args_toks -} -\cs_new_nopar:cpn {xparse_m3:w} #1 \l_xparse_grabbed_args_toks #2#3#4{ - \toks_put_right:Nn \l_xparse_grabbed_args_toks{{#2}{#3}{#4}} - #1 \l_xparse_grabbed_args_toks -} -\cs_new_nopar:cpn {xparse_m4:w} #1 \l_xparse_grabbed_args_toks #2#3#4#5{ - \toks_put_right:Nn \l_xparse_grabbed_args_toks{{#2}{#3}{#4}{#5}} - #1 \l_xparse_grabbed_args_toks -} -\cs_new_nopar:cpn {xparse_m5:w} #1 \l_xparse_grabbed_args_toks #2#3#4#5#6{ - \toks_put_right:Nn \l_xparse_grabbed_args_toks{{#2}{#3}{#4}{#5}{#6}} - #1 \l_xparse_grabbed_args_toks -} -\cs_new_nopar:cpn {xparse_m6:w} #1 \l_xparse_grabbed_args_toks #2#3#4#5#6#7{ - \toks_put_right:Nn \l_xparse_grabbed_args_toks - {{#2}{#3}{#4}{#5}{#6}{#7}} - #1 \l_xparse_grabbed_args_toks -} -\cs_new_nopar:cpn {xparse_m7:w} #1 \l_xparse_grabbed_args_toks#2#3#4#5#6#7#8{ - \toks_put_right:Nn \l_xparse_grabbed_args_toks - {{#2}{#3}{#4}{#5}{#6}{#7}{#8}} - #1 \l_xparse_grabbed_args_toks -} -\cs_new_nopar:cpn {xparse_m8:w} #1\l_xparse_grabbed_args_toks - #2#3#4#5#6#7#8#9{ - \toks_put_right:Nn \l_xparse_grabbed_args_toks - {{#2}{#3}{#4}{#5}{#6}{#7}{#8}{#9}} - #1 \l_xparse_grabbed_args_toks -} -\cs_new_nopar:cpn {xparse_m9:w} \toks_use:N \l_xparse_grabbed_args_toks - #1#2#3#4#5#6#7#8#9{ - \toks_put_right:Nn \l_xparse_grabbed_args_toks - {{#1}{#2}{#3}{#4}{#5}{#6}{#7}{#8}{#9}} - \toks_use:N \l_xparse_grabbed_args_toks -} -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\xparse_allow_par_m:w} -% The |m| type allowing |\par| tokens. We only define one of them as -% two in a row would be quite rare. -% \begin{macrocode} -\cs_new:Npn \xparse_allow_par_m:w #1 \l_xparse_grabbed_args_toks#2{ - \toks_put_right:Nn \l_xparse_grabbed_args_toks{{#2}} - #1 \l_xparse_grabbed_args_toks -} -% \end{macrocode} -% \end{macro} -% -% \paragraph{Arguments delimited by a left brace} -% -% \begin{macro}{\xparse_add_arg_type_l:} -% \begin{macro}{\xparse_l:w} -% \begin{macro}{\xparse_allow_par_l:w} -% This is almost exactly the same as the |m| type except we read -% everything up to the first left brace. -% \begin{macrocode} -\cs_new_nopar:Nn \xparse_add_arg_type_l: { - \xparse_add_remaining_m_args: - \bool_if:NTF \g_xparse_allow_par_bool - { - \toks_put_right:Nn \l_xparse_grabbed_args_toks {\xparse_allow_par_l:w} - } - { \toks_put_right:Nn \l_xparse_grabbed_args_toks {\xparse_l:w} } -} -\cs_new_nopar:Npn \xparse_l:w #1 \l_xparse_grabbed_args_toks#2#{ - \toks_put_right:Nn \l_xparse_grabbed_args_toks{{#2}} - #1 \l_xparse_grabbed_args_toks -} -\cs_new:Npn \xparse_allow_par_l:w #1 \l_xparse_grabbed_args_toks#2#{ - \toks_put_right:Nn \l_xparse_grabbed_args_toks{{#2}} - #1 \l_xparse_grabbed_args_toks -} -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \paragraph{Adding a symbol argument type} -% -% -% \begin{macro}{\DeclareSymbolArgument} -% The actual grabber functions just issue a |\peek_meaning_remove:NTF| -% or similar on the symbol chosen. If found, we put a |\c_true_bool| on the -% argument stack and |\c_false_bool| otherwise. -% \begin{macrocode} -\cs_new_nopar:Npn \DeclareSymbolArgument #1#2{ - \seq_map_variable:NNn \g_xparse_ignore_marker_seq \l_tmpa_tl { - \cs_set_nopar:cpx {xparse \l_tmpa_tl _#1:w}##1##2 - \l_xparse_grabbed_args_toks{ - \exp_not:c{peek_ #2 _remove \l_tmpa_tl :NTF} ##1 - { - \exp_not:N \toks_put_right:Nn \exp_not:N - \l_xparse_grabbed_args_toks \exp_not:N \c_true_bool - ##2 \exp_not:N\l_xparse_grabbed_args_toks - } - { - \exp_not:N \toks_put_right:Nn \exp_not:N - \l_xparse_grabbed_args_toks \exp_not:N \c_false_bool - ##2 \exp_not:N\l_xparse_grabbed_args_toks - } - } - } -% \end{macrocode} -% Implementing a symbol type is fairly straight forward. It needs to -% grab a default argument. First we must clear out any pending |m| -% arguments. -% \begin{macrocode} - \cs_set_nopar:cpn {xparse_add_arg_type_#1:} { - \xparse_add_remaining_m_args: - \toks_put_right:Nx \l_xparse_grabbed_args_toks - { \exp_not:c {xparse \g_xparse_ignore_marker_tl _#1:w } } -% \end{macrocode} -% Nothing special when building the signature: We always grab a single -% default argument. -% \begin{macrocode} - \cs_set_eq:NN \xparse_read_arg_type_or_grab_default:n - \xparse_grab_default_arg:n - } -} -% \end{macrocode} -% It is this easy now: -% \begin{macrocode} -\DeclareSymbolArgument S{meaning} -% \end{macrocode} -% \end{macro} -% -% -% \paragraph{Adding delimited arguments} -% -% -% \begin{macro}{\DeclareArgumentType} -% Argument types that read their argument delimited as the |o| type -% can be defined with this function. |#1| is the letter associated -% with the type, |#3| is the test type we should use, i.e., -% meaning, charcode or catcode. |#2| is the left delimiter \LaTeX{} -% will look for, |#4| can be used for an error message or such in -% case of a missing value, and |#5| the value inserted in case the -% optional argument is missing. The last two arguments control how -% the arguments are picked up and parsed on to the inner parsing. -% \begin{macrocode} -\cs_new_nopar:Npn \DeclareArgumentType #1#2#3#4#5#6#7{ -% \end{macrocode} -% For instance, we want |\DeclareArgumentType a{charcode}[...| to -% define the function |\xparse_ignore_spaces_a:w| with meaning -% |\peek_charcode_ignore_spaces:NTF [{...}{...}|. We want to define a -% series of functions for each of these delimited argument types. One -% for each of the |ignore| types plus an identical version of each of -% these allowing the |\par| token in the argument. All the different -% ignore types are stored in the sequence -% |\g_xparse_ignore_marker_seq| so we go through that when doing the -% definitions. -% \begin{macrocode} - \seq_map_variable:NNn \g_xparse_ignore_marker_seq \l_tmpa_tl { - \cs_set_nopar:cpx {xparse \l_tmpa_tl _#1:w}##1\l_xparse_grabbed_args_toks{ - \exp_not:c{peek_#3 \l_tmpa_tl :NTF} \exp_not:N #2 - { \exp_not:c{xparse_#1_#3_help:nw}{##1} } - { - \exp_not:n { - #4 \toks_put_right:Nn \l_xparse_grabbed_args_toks {#5} - } - ##1 \exp_not:N\l_xparse_grabbed_args_toks - } - } -% \end{macrocode} -% And now an almost identical version which allows the |\par| token. -% \begin{macrocode} - \cs_set:cpx {xparse_allow_par \l_tmpa_tl _#1:w}##1 - \l_xparse_grabbed_args_toks{ - \exp_not:c{peek_#3 \l_tmpa_tl :NTF} \exp_not:N #2 - { \exp_not:c{xparse_allow_par_#1_#3_help:nw}{##1} } - { - \exp_not:n { - #4 \toks_put_right:Nn \l_xparse_grabbed_args_toks {#5} - } - ##1 \exp_not:N\l_xparse_grabbed_args_toks - } - } - } -% \end{macrocode} -% Here is the function for building the argument grabbing. We clear -% out the remaining |m| arguments first. -% \begin{macrocode} - \cs_set_nopar:cpn {xparse_add_arg_type_#1:} { - \xparse_add_remaining_m_args: - \toks_put_right:Nx \l_xparse_grabbed_args_toks { - \exp_not:c {xparse -% \end{macrocode} -% Insert |_allow_par| in the csname if needed. This also applies to -% the argument grabber (although this should probably just be the -% default). -% \begin{macrocode} - \bool_if:NT \g_xparse_allow_par_bool {_allow_par} - \g_xparse_ignore_marker_tl - _#1:w - } - } - \cs_set_eq:NN \xparse_read_arg_type_or_grab_default:n \xparse_parse_signature:n - } -% \end{macrocode} -% Now all we need to do is to define the helper functions. -% \begin{macrocode} - \xparse_define_helper:Nnnn #1{#3}{#6}{#7} -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\DeclareArgumentTypeDefaultValue} -% The same as above but expects a default value in the signature. -% Therefore it doesn't have the arguments of the default value and -% what to do if it is missing like the above. -% \begin{macrocode} -\cs_new_nopar:Npn \DeclareArgumentTypeDefaultValue #1#2#3#4#5{ - \seq_map_variable:NNn \g_xparse_ignore_marker_seq \l_tmpa_tl { - \cs_set_nopar:cpx {xparse \l_tmpa_tl _#1:w}##1##2\l_xparse_grabbed_args_toks{ - \exp_not:c{peek_#3 \l_tmpa_tl :NTF} \exp_not:N #2 - { \exp_not:c{xparse_#1_#3_help:nw}{##2} } - { - \exp_not:N \toks_put_right:Nn - \exp_not:N \l_xparse_grabbed_args_toks {{##1}} - ##2 \exp_not:N \l_xparse_grabbed_args_toks - } - } -% \end{macrocode} -% And now an almost identical version which allows the |\par| token. -% \begin{macrocode} - \cs_set:cpx {xparse_allow_par \l_tmpa_tl _#1:w}##1##2 - \l_xparse_grabbed_args_toks{ - \exp_not:c{peek_#3 \l_tmpa_tl :NTF} \exp_not:N #2 - { \exp_not:c{xparse_allow_par_#1_#3_help:nw}{##2} } - { - \exp_not:N \toks_put_right:Nn - \exp_not:N \l_xparse_grabbed_args_toks {{##1}} - ##2 \exp_not:N \l_xparse_grabbed_args_toks - } - } - } -% \end{macrocode} -% Here is the function for building the argument grabbing. We clear -% out the remaining |m| arguments first. -% \begin{macrocode} - \cs_set_nopar:cpn {xparse_add_arg_type_#1:} { - \xparse_add_remaining_m_args: - \toks_put_right:Nx \l_xparse_grabbed_args_toks { - \exp_not:c {xparse -% \end{macrocode} -% Insert |_allow_par| in the csname if needed. This also applies to -% the argument grabber (although this should probably just be the -% default). -% \begin{macrocode} - \bool_if:NT \g_xparse_allow_par_bool {_allow_par} - \g_xparse_ignore_marker_tl - _#1:w - } - } - \cs_set_eq:Nc \xparse_read_arg_type_or_grab_default:n - {xparse_grab_default_arg - \bool_if:NT \g_xparse_allow_par_bool {_allow_par} - :n - } - } -% \end{macrocode} -% Now all we need to do is to define the helper functions. -% \begin{macrocode} - \xparse_define_helper:Nnnn #1{#3}{#4}{#5} -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\xparse_define_helper:Nnnn} -% All we need now is the helper functions. We define a generic -% interface that should be fairly easy to use. -% \begin{macrocode} -\cs_new_nopar:Nn \xparse_define_helper:Nnnn { - \toks_set:Nn \l_tmpa_toks - { - #3 - { -% \end{macrocode} -% Remember to add an extra set of braces here. -% \begin{macrocode} - \toks_put_right:Nn \l_xparse_grabbed_args_toks {{#4}} - ##1 \l_xparse_grabbed_args_toks - } - } -% \end{macrocode} -% The next bit looks a little ugly but that's life. -% \begin{macrocode} - \toks_set:Nx \l_tmpa_toks { - \exp_not:n {\cs_set_nopar:cpn{xparse_#1_#2_help:nw}} - \toks_use:N \l_tmpa_toks - \exp_not:n {\cs_set_nopar:cpn{xparse_allow_par_#1_#2_help:nw}} - \toks_use:N\l_tmpa_toks - } - \toks_use:N \l_tmpa_toks -} -% \end{macrocode} -% \end{macro} -% -% All the above may seem like an awful lot of trouble but it is -% general and it allows the following simple definitions: -% \begin{macrocode} -\DeclareArgumentType o[{meaning}{}{\NoValue}{#1[#2]}{#2} -% \end{macrocode} -% For the |c| type we add give an error message. -% \begin{macrocode} -\DeclareArgumentType c({meaning}{ - \xparse_error:x{ - Missing~ coordinate~ argument.~ A~ value~ of~ (0,0)~ is~ assumed} - } - {{00}} - {#1(#2,#3)}{{#2}{#3}} -\DeclareArgumentTypeDefaultValue O[{meaning}{#1[#2]}{#2} -\DeclareArgumentTypeDefaultValue C({meaning}{#1(#2,#3)}{{#2}{#3}} -% \end{macrocode} -% One could also do -% \begin{verbatim} -% \DeclareArgumentTypeDefaultValue O[{charcode}{#1#2#3]}{#3} -% \end{verbatim} -% where argument |#2| is the bracket but not requiring it to have -% catcode~12. However we can't use the same trick for reading the end -% of the argument. -% -% Another interesting one could be -% \begin{verbatim} -% \DeclareArgumentType a\c_group_begin_token{catcode}{}{\NoValue}{#1#2}{#2} -% \end{verbatim} -% which would basically be an optional argument in braces. -% -% -% -% \subsubsection{Argument shorthands} -% -% -% \begin{macro}{\DeclareArgumentTypeShorthand} -% Letting a letter or symbol be a shorthand for a more complicated -% structure is rather easy actually. All we need to do is to gobble -% the remainder of the main loop in the signature creation until -% |\xparse_parse_signature:n|, decrement the argument counter, put -% in the replacement argument specifiers and start the loop -% again. The disadvantage of this scheme is that we have to cheat -% and give it the wrong name as it should have a |w| argument -% specification but I hope you can forgive this little white lie. -% \begin{macrocode} -\cs_new_nopar:Npn \DeclareArgumentTypeShorthand #1#2{ - \cs_new_nopar:cpn {xparse_add_arg_type_#1:} - ##1 \xparse_read_arg_type_or_grab_default:n { - \int_decr:N \l_xparse_total_args_int - \xparse_read_arg_type_or_grab_default:n #2 - } -} -% \end{macrocode} -% \end{macro} -% \begin{macro}{\xparse_add_arg_type_s:} -% Defining the |s| type is easy now since it really means |S{*}|. -% \begin{macrocode} -\DeclareArgumentTypeShorthand s {S{*}} -% \end{macrocode} -% \end{macro} -% -% -% \subsection{Checking for optional values} -% -% -% \begin{macro}{\IfBooleanTF} -% \begin{macro}{\IfBooleanT} -% \begin{macro}{\IfBooleanF} -% The logical \meta{true} and \meta{false} statements are just our -% normal |\c_true_bool| and |\c_false_bool| so testing for them is done with -% our usual |\bool_if:NTF| functions from \textsf{l3prg}. -% \begin{macrocode} -\cs_new_eq:NN \IfBooleanTF \bool_if:NTF -\cs_new_eq:NN \IfBooleanT \bool_if:NT -\cs_new_eq:NN \IfBooleanF \bool_if:NF -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\NoValue} -% \begin{macro}{\c_xparse_hidden_no_value_tl} -% |\NoValue| is just a text string and we define it as a token list -% variable. However we will actually test for token list variables -% with \emph{meaning} |\NoValue|. Hence if an argument is really -% |-NoValue-| it will not be detected but that shouldn't happen. -% \begin{macrocode} -\tl_new:Nn \NoValue {-NoValue-} -\tl_new:Nn \c_xparse_hidden_no_value_tl {\NoValue} -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\xparse_if_no_value:nTF} -% The test start by making a token list variable out of the first -% argument and then check if it is equal to -% |\c_xparse_hidden_no_value_tl| which contains |\NoValue|. -% \begin{macrocode} -\cs_new:Npn \xparse_if_no_value:nTF #1{ - \tl_set:Nx \l_tmpa_tl{\exp_not:n{#1}} - \tl_if_eq:NNTF \l_tmpa_tl \c_xparse_hidden_no_value_tl -% \end{macrocode} -% If they are equal we just exit and execute the \meta{true} code. -% \begin{macrocode} - { \use_i:nn } -% \end{macrocode} -% If not, take a closer look at |#1|. Peek ahead at the first token in -% |#1| and then call the function |\xparse_if_no_value_aux:| but only -% if |#1| is not empty or a blank space: in that case we can execute -% the \meta{false} code immediately. We must use this test at some -% point otherwise the macros for checking tokens will break since the -% argument may be empty. -% \begin{macrocode} - { \tl_if_blank:nTF {#1} - { \use_ii:nn } - {\peek_after:NN \xparse_if_no_value_aux: #1 \q_nil {#1} } - } -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\xparse_if_no_value_aux:} -% Now we simply check the argument specification of the token. If -% it is not a macro the function |\token_get_arg_spec:N| returns -% |\scan_stop:|. -% \begin{macrocode} -\cs_new:Nn \xparse_if_no_value_aux: { - \tl_set:Nx \l_tmpa_tl{\token_get_arg_spec:N \l_peek_token } -% \end{macrocode} -% Then check if |\l_tmpa_tl| is empty, because this means we have a -% macro taking zero arguments and we can expand it once -% safely. Otherwise we just exit and execute the false code. Remember -% that we have the sequence |{#1}| waiting after the |\q_nil| in -% |\xparse_if_no_value:nTF| above. -% \begin{macrocode} - \tl_if_empty:NTF \l_tmpa_tl - {\use_i_delimit_by_q_nil:nw {\exp_args:No\xparse_if_no_value:nTF}} - {\use_i_delimit_by_q_nil:nw {\use_iii:nnn}} -} -% \end{macrocode} -% \end{macro} -% -% -% \begin{macro}{\IfNoValueTF} -% \begin{macro}{\IfNoValueT} -% \begin{macro}{\IfNoValueF} -% \begin{macro}{\IfValueTF} -% \begin{macro}{\IfValueT} -% \begin{macro}{\IfValueF} -% |\IfNoValueTF| and its varieties are implemented as subcases of -% |\xparse_if_no_value:nTF|. -% \begin{macrocode} -\cs_new_eq:NN \IfNoValueTF \xparse_if_no_value:nTF -\cs_new:Npn \IfNoValueT #1#2 {\xparse_if_no_value:nTF{#1}{#2}{}} -\cs_new:Npn \IfNoValueF #1 {\xparse_if_no_value:nTF {#1}{}} -% \end{macrocode} -% For |\IfValueTF| we just reverse the arguments. -% \begin{macrocode} -\cs_new:Npn \IfValueTF #1#2#3{\xparse_if_no_value:nTF {#1}{#3}{#2}} -\cs_new_eq:NN \IfValueT \IfNoValueF -\cs_new_eq:NN \IfValueF \IfNoValueT -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% -% -% \subsection{Pseudo arguments} -% -% \begin{macro}{\l_xparse_pseudo_post_arg_tl} -% A temporary token list variable to store the post-arguments. -% \begin{macrocode} -\tl_new:Nn \l_xparse_pseudo_post_arg_tl {} -% \end{macrocode} -% \end{macro} -% \begin{macro}{\DeclarePseudoArgument} -% Must be called at the end of the replacement text. Can use the -% parameters picked up so far. |#1| is a name for it, |#2| is the -% number of arguments, |#3| is the pre-argument definition, |#4| is -% the post-argument definition. The idea here is to define two -% functions: One to execute before the special pseudo argument is -% found and one to to it afterwards. Hence we define such two -% functions with |#2| arguments and definitions |#3| and |#4| -% respectively. -% \begin{macrocode} -\cs_new:Npn \DeclarePseudoArgument #1#2#3#4{ - \cs_set:cn {xparse_pseudo_pre_arg_#1:\prg_replicate:nn{#2}{n}} {#3} - \cs_set:cn {xparse_pseudo_post_arg_#1:\prg_replicate:nn{#2}{n}} {#4} -% \end{macrocode} -% In case the user doesn't put the argument in braces, it must be a -% single token which we just grab and then execute the -% post-argument. Surely it won't be a |\par| token! -% \begin{macrocode} - \cs_set_nopar:cn {xparse_pseudo_nobrace_arg_#1:N} { - ##1 \l_xparse_pseudo_post_arg_tl - } -% \end{macrocode} -% The regular version of the command is then this: -% \begin{enumerate} -% \item Execute the pre-code at level $n$. -% \item Store the post-code in a token list variable at level $n$. -% \item Look for a begin-group token. -% \item[4a] If found, remove it, start a group (level $n+1$) and make -% sure the token list variable from 2) is executed after the group -% has ended (at level $n$). -% \item[4b] If not found, call the |nobrace_arg| version which also -% executes the token list variable from 2) at level $n$. -% \end{enumerate} -% This scheme enables these commands to be nested since they all -% appear at different grouping levels. -% -% Next we define the function. Also make sure that it gets all the -% arguments carried over to the post-argument. -% \begin{macrocode} - \cs_generate_from_arg_count:cNnn {xparse_pseudo_arg_#1:w} - \cs_set:Npx {#2} - { - \exp_not:c { - xparse_pseudo_pre_arg_#1: \prg_replicate:nn{#2}{n} - } - \use:c{use_ \intexpr_eval:n{#2} _parameter:} - \exp_not:n {\tl_set:Nn \l_xparse_pseudo_post_arg_tl} - { - \exp_not:c {xparse_pseudo_post_arg_#1:\prg_replicate:nn{#2}{n}} - \use:c{use_ \intexpr_eval:n{#2}_parameter:} - } - \exp_not:n{ \peek_catcode_remove_ignore_spaces:NTF \c_group_begin_token } - { -% \end{macrocode} -% Here we insert the left brace token which was removed removed. -% In case you're wondering then yes, I know that |\c_group_begin_token| -% and |\group_execute_after:N| are unexpandable but I prefer this method -% because I don't want to remember which commands are expandable and -% which are not. -% \begin{macrocode} - \exp_not:n { - \c_group_begin_token - \group_execute_after:N \l_xparse_pseudo_post_arg_tl - } - } - { - \exp_not:c{xparse_pseudo_nobrace_arg_#1:N} - } - } -} -% \end{macrocode} -% \end{macro} -% \begin{macro}{\UsePseudoArgument} -% Just a nice wrapper for calling such an argument. -% \begin{macrocode} -\cs_new_nopar:Npn \UsePseudoArgument #1{\use:c{xparse_pseudo_arg_#1:w}} -% \end{macrocode} -% \end{macro} -% -% -% -% -% \Finale -% -\endinput diff --git a/Master/texmf-dist/source/latex/xpackages/xtras/l3keys2e-demo.tex b/Master/texmf-dist/source/latex/xpackages/xtras/l3keys2e-demo.tex new file mode 100644 index 00000000000..a00531e0741 --- /dev/null +++ b/Master/texmf-dist/source/latex/xpackages/xtras/l3keys2e-demo.tex @@ -0,0 +1,46 @@ +% !TEX encoding = ISO-8859-1 +% !TEX program = pdflatex +% +% This file demonstrates the use of the l3keys2e module to allow +% LaTeX3 keyvals (created using l3keys) to be used as LaTeX2e +% package or class options. +% + +% First, create a class +\begin{filecontents}{l3keys2e-class.cls} + \LoadClass{article} + \RequirePackage{l3keys2e} + \ProvidesExplClass{l3keys2e-class}{0000/00/00}{0.0}{test} + \keys_define:nn { test1 } { + option1 .code:n = {\wlog{You~gave~`#1'~for~option1}} + } + \ProcessKeysOptions { test1 } +\end{filecontents} + +% Load the class with some options. +% The class itself recognises `option1', leaving `option2' and +% `option3' as global optons which are not yet used. +\documentclass[option1=check,option2=more stuff,option3=unused] + {l3keys2e-class} + +%Now create a package +\begin{filecontents}{l3keys2e-package.sty} + \RequirePackage{l3keys2e} + \ProvidesExplPackage{l3keys2e-package}{0000/00/00}{0.0}{test} + \keys_define:nn { test2 } { + option1 .code:n = {\wlog{You~gave~`#1'~for~option1~(again)}}, + option2 .code:n = {\wlog{You~gave~`#1'~for~option2}}, + option4 .code:n = {\wlog{You~gave~`#1'~for~option4}}, + } + \ProcessKeysOptions { test2 } +\end{filecontents} + +% Load the package. +\usepackage[option4={extra stuff},option5=undefined!] + {l3keys2e-package} + +\begin{document} +% The log should show that option3 is an unused global option, and that +% option5 is not known by the l3keys2e-demo package. Everything else +% should simply be listed in the log. +\end{document} diff --git a/Master/texmf-dist/source/latex/xpackages/xtras/l3keys2e.dtx b/Master/texmf-dist/source/latex/xpackages/xtras/l3keys2e.dtx new file mode 100644 index 00000000000..9595206ee53 --- /dev/null +++ b/Master/texmf-dist/source/latex/xpackages/xtras/l3keys2e.dtx @@ -0,0 +1,322 @@ +% \iffalse +%% File: l3keys2e.dtx (C) Copyright 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 ``l3keys2e'' (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} +% +%\fi +\GetIdInfo$Id: l3keys2e.dtx 1494 2009-08-24 11:05:44Z joseph $ + {Parsing LaTeX3 keyvals as LaTeX2e package options} +%\iffalse +%<*driver> +%\fi +\ProvidesFile{\filename.\filenameext} + [\filedate\space v\fileversion\space\filedescription] +%\iffalse +\documentclass{l3doc} +\begin{document} + \DocInput{l3keys2e.dtx} +\end{document} +% +% \fi +% +% \title{The \textsf{l3keys2e} package\thanks{This file +% has version number \fileversion, last +% revised \filedate.}\\ +% Parsing \LaTeX3 keyvals as \LaTeXe\ package options} +% \author{\Team} +% \date{\filedate} +% \maketitle +% +%\begin{documentation} +% +%\section{Key--value arguments as \LaTeXe\ class and package options} +% +% The key--value method for optional arguments is very popular, as it +% allows the class or package author to define a large number of +% options with a simple interface. The \pkg{expl3} bundle of \LaTeX3 +% base code includes the module \pkg{l3keys} for defining keys, but +% to use these when loading \LaTeXe\ packages and classes requires +% extra support. That support is provided by this small package, which +% is intended to enable \LaTeXe\ packages to benefit from the power of +% the \LaTeX3 key--value system. +% +%\subsection{Creating and using keyval options} +% +% As with any key--value input, using key--value pairs as package or +% class options has two parts. The first stage is to define one or +% more keys. This should be done using the \LaTeX3 module \pkg{l3keys}. +% For example, an option which simply stores a value would be created +% using: +%\begin{verbatim} +% \keys_define:nn { module } { +% option .set:N = \l_module_variable_tl +% } +%\end{verbatim} +% On its own, this will not make the key an option for the package or +% class containing the definition. The second stage is therefore to +% process the current options, searching for applicable keys. +% +%\begin{function}{\ProcessKeysOptions} +% \begin{syntax} +% "\ProcessKeysOptions" \Arg{module} +% \end{syntax} +% The \cs{ProcessKeysOptions} function is used to check the current +% option list against the keys defined for . Global (class) +% options and local (package) options are checked when this function +% is called in a package. Each option which does match a key name is +% then used to attempt to set the appropriate key using +% \cs{keys_set:nn}. For example, the option defined earlier would be +% processed by the line +% \begin{verbatim} +% \ProcessKeysOptions { module } +% \end{verbatim} +%\end{function} +% +%\subsection{Internal functions and variables} +% +%\begin{variable}{\keys_latexe_options_clist} +% Local options and applicable global (class) options are collected up +% here prior to processing using \cs{keys_set:nn}. +%\end{variable} +% +%\begin{function}{\keys_latexe_options:n} +% \begin{syntax} +% "\keys_latexe_options:n" \Arg{module} +% \end{syntax} +% Examines current global and local options, comparing them to the +% keys defined for . Option names which match defined keys are +% then executed by passing the appropriate data to \cs{keys_set:nn}. +%\end{function} +% +%\begin{function}{\keys_latexe_options_global:n} +% \begin{syntax} +% "\keys_latexe_options_global:n" \Arg{module} +% \end{syntax} +% Makes appropriate checks on global (class) options, then searches for +% key matches for . +%\end{function} +% +%\begin{function}{\keys_latexe_options_class:n} +% \begin{syntax} +% "\keys_latexe_options_class:n" \Arg{module} +% \end{syntax} +% Processes global options when the current file is itself a class, +% checking the options against keys defined for . +%\end{function} +% +%\begin{function}{\keys_latexe_options_package:n} +% \begin{syntax} +% "\keys_latexe_options_package:n" \Arg{module} +% \end{syntax} +% Processes global options when the current file is a \LaTeXe\ package, +% checking the options against keys defined for . +%\end{function} +% +%\begin{function}{\keys_latexe_options_local:} +% \begin{syntax} +% "\keys_latexe_options_local:" +% \end{syntax} +% Finds local (package) options and adds them to the list to be +% parsed by \cs{keys_set:nn}. +%\end{function} +% +%\begin{function}{ +% \keys_latexe_remove_equals:n / (EXP) | +% \keys_latexe_remove_equals:w / (EXP) +%} +% \begin{syntax} +% "\keys_latexe_remove_equals:n" \Arg{option} +% "\keys_latexe_remove_equals:w" = "\q_stop" +% \end{syntax} +% Returns only the key part of a key--value option by removing +% everything after the first equals sign. It is assumed that, as this +% will apply in the preamble, equals signs have category code 12. +%\end{function} +% +%\end{documentation} +% +%\begin{implementation} +% +%\subsection{Implementation} +% +% The usual lead-off, using \pkg{xparse} at the interface level. +% \begin{macrocode} +%<*package> +\ProvidesExplPackage + {\filename}{\filedate}{\fileversion}{\filedescription} +\RequirePackage{xparse} +% \end{macrocode} +% +%\begin{macro}{\keys_latexe_options_clist} +% The module collects all applicable global and local options into a +% single list before processing them. +% \begin{macrocode} +\clist_new:N \keys_latexe_options_clist +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\keys_latexe_options:n} +% The main function calls functions to collect up the global and local +% options into \cs{keys_latexe_options_clist} before calling the main +% \pkg{l3keys} module to actually do the processing. So that a suitable +% message is produced if the option is unknown, the special +% \texttt{unknown} key is set if it does not already exist for the +% current module. +% \begin{macrocode} +\cs_new:Nn \keys_latexe_options:n { + \clist_clear:N \keys_latexe_options_clist + \keys_latexe_options_global:n {#1} + \keys_latexe_options_local: + \keys_if_exist:nnF {#1} { unknown } { + \keys_define:nn {#1} { + unknown .code:n = { + \msg_warning:nnxx { Option~Processing } { unknown-option } + { \l_keys_key_tl } { \@currname } + } + } + } + \keys_set:nV {#1} \keys_latexe_options_clist + \AtEndOfPackage { \cs_set_eq:NN \@unprocessedoptions \scan_stop: } +} +\msg_new:nnn { Option~Processing } { unknown-option } {% + Unknown~option~`#1'\\% + for~module~#2.% +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\keys_latexe_options_global:n} +% Global (class) options are handled differently for \LaTeXe\ packages +% and classes. Hence this function is essentially a check on the current +% file type. The initial test is needed as \LaTeXe\ allows variables to +% be equal to \cs{scan_stop:}, which is forbidden in \LaTeX3 code. +% \begin{macrocode} +\cs_new:Nn \keys_latexe_options_global:n { + \cs_if_eq:NNF \@classoptionslist \scan_stop: { + \cs_if_eq:NNTF \@currext \@clsextension { + \keys_latexe_options_class:n {#1} + }{ + \keys_latexe_options_package:n {#1} + } + } +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\keys_latexe_options_class:n} +% For classes, each option (stripped of any content after `\texttt{=}') +% is checked for existence as a key. If found, the option is added to +% the combined list for processing. On the other hand, unused options +% are stored up in \cs{@unusedoptionlist}. +% \begin{macrocode} +\cs_new:Nn \keys_latexe_options_class:n { + \clist_map_inline:Nn \@classoptionslist { + \keys_if_exist:nnTF {#1} { \keys_latexe_remove_equals:n {##1} } { + \clist_put_right:Nn \keys_latexe_options_clist {##1} + }{ + \clist_put_right:Nn \@unusedoptionlist {##1} + } + } +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\keys_latexe_options_package:n} +% For global options when processing a package, the tasks are slightly +% different from those for a class. The check is the same, but here +% there is nothing to do if the option is not applicable. Each valid +% option also needs to be removed from \cs{@unusedoptionlist}. +% \begin{macrocode} +\cs_new:Nn \keys_latexe_options_package:n { + \clist_map_inline:Nn \@classoptionslist { + \keys_if_exist:nnT {#1} { \keys_latexe_remove_equals:n {##1} } { + \clist_put_right:Nn \keys_latexe_options_clist {##1} + \clist_remove_element:Nn \@unusedoptionlist {##1} + } + } +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\keys_latexe_options_local:} +% If local options are found, the are added to the processing list. +% \LaTeXe\ stores options for each file in a macro which may or may not +% exist, hence the need to use \cs{cs_if_exist:c}. +% \begin{macrocode} +\cs_new_nopar:Nn \keys_latexe_options_local: { + \cs_if_eq:NNF \@currext \@clsextension { + \cs_if_exist:cT { opt@ \@currname . \@currext } { + \exp_args:NNc \clist_put_right:NV \keys_latexe_options_clist + { opt@ \@currname . \@currext } + } + } +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\keys_latexe_remove_equals:n} +%\begin{macro}{\keys_latexe_remove_equals:w} +% As the name suggests, this is a simple function to remove an equals +% sign from the input. This is all wrapped up in an \texttt{n} function +% so that there will always be a sign available. +% \begin{macrocode} +\cs_new:Nn \keys_latexe_remove_equals:n { + \keys_latexe_remove_equals:w #1 = \q_stop +} +\cs_new:Npn \keys_latexe_remove_equals:w #1 = #2 \q_stop {#1} +% \end{macrocode} +%\end{macro} +%\end{macro} +% +%\begin{macro}{\ProcessKeysOptions} +% The user macro is simply a wrapper around the internal process. In +% contrast to other similar packages, the module name is always required +% here. +% \begin{macrocode} +\NewDocumentCommand \ProcessKeysOptions { m } { + \keys_latexe_options:n {#1} +} +\@onlypreamble \ProcessKeysOptions +% \end{macrocode} +%\end{macro} +% +% \begin{macrocode} +% +% \end{macrocode} +% +% \end{implementation} +% +% \PrintIndex diff --git a/Master/texmf-dist/source/latex/xpackages/xtras/l3keys2e.ins b/Master/texmf-dist/source/latex/xpackages/xtras/l3keys2e.ins new file mode 100644 index 00000000000..75c72b058d4 --- /dev/null +++ b/Master/texmf-dist/source/latex/xpackages/xtras/l3keys2e.ins @@ -0,0 +1,19 @@ +\input docstrip +\keepsilent +\askforoverwritefalse + +\preamble +---------------------------------------------------------------- +l3keys2e --- Parsing LaTeX3 keyvals as LaTeX2e package options +Copyright 2009 The LaTeX3 Project +Released under the LaTeX Project Public License v1.3c or later +See http://www.latex-project.org/lppl.txt +---------------------------------------------------------------- +\endpreamble + + +\generate{% + \file{l3keys2e.sty}{\from{l3keys2e.dtx}{package}} +} + +\endbatchfile diff --git a/Master/texmf-dist/tex/latex/xpackages/ldcsetup.sty b/Master/texmf-dist/tex/latex/xpackages/ldcsetup.sty deleted file mode 100644 index 7f26ce16cbb..00000000000 --- a/Master/texmf-dist/tex/latex/xpackages/ldcsetup.sty +++ /dev/null @@ -1,193 +0,0 @@ -%% -%% This is file `ldcsetup.sty', -%% generated with the docstrip utility. -%% -%% The original source files were: -%% -%% ldcsetup.dtx (with options: `package') -%% -%% (C) Copyright The LaTeX3 Project and any individual authors -%% listed elsewhere in this file. -%% -%% This is a generated file. -%% -%% This file was generated from file(s) of the xbase bundle. -%% --------------------------------------------------------- -%% -%% This file may only be distributed together with a copy of this bundle. -%% You may however distribute the bundle without such generated files. -%% -%% ====================================================================== -%% -%% File: ldcsetup.dtx (C) Copyright 1999 Frank Mittelbach, Chris Rowley, David Carlisle -%% (C) Copyright 2004-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 -%% 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 ``xbase 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{expl3} -\GetIdInfo$Id: ldcsetup.dtx 1295 2009-05-06 08:32:25Z will $ - {coding conventions and stuff} -\ProvidesExplPackage - {\filename}{\filedate}{\fileversion}{\filedescription} -\RequirePackage{keyval} -\RequirePackage{expl3} -\ExplSyntaxOff -%% Puts an ignored space at the end of the line, so `|\ |' does the right -\def\IgnoreWhiteSpace{% - \edef\@tempa{% - \catcode`\noexpand\~=\the\catcode`\~\relax - \catcode`\noexpand\ =\the\catcode`\ \relax - \catcode`\noexpand\^^I=\the\catcode`\^^I\relax - \catcode`\noexpand\@=\the\catcode`\@\relax - \endlinechar=\the\endlinechar\relax - }% - \ifx\@currname\@empty - \expandafter\AtBeginDocument\expandafter{\@tempa}% - \else - \expandafter\AtEndOfPackage\expandafter{\@tempa}% - \fi - \catcode`\~=10\relax - \catcode`\ =9\relax - \catcode`\^^I=9\relax - \makeatletter - \endlinechar=` % - \relax -} -\def\InternalSyntaxOn{% - \edef\@tempa{% - \catcode`\noexpand\~=\the\catcode`\~\relax - \catcode`\noexpand\ =\the\catcode`\ \relax - \catcode`\noexpand\^^I=\the\catcode`\^^I\relax - \catcode`\noexpand\@=\the\catcode`\@\relax - \catcode`\noexpand\:=\the\catcode`\:\relax - \catcode`\noexpand\_=\the\catcode`\_\relax - \endlinechar=\the\endlinechar\relax - \endlinechar=13\relax - }% -%%% ???? - \ifx\InternalSyntaxOff\relax - \expandafter\def\expandafter\InternalSyntaxOff\expandafter - {\@tempa\let\InternalSyntaxOff\relax}% - \fi - \ifx\@currname\@empty - \expandafter\AtBeginDocument\expandafter{\@tempa}% - \else - \expandafter\AtEndOfPackage\expandafter{\@tempa}% - \fi - \catcode`\~=10\relax - \catcode`\ =9\relax - \catcode`\^^I=9\relax - \makeatletter - \catcode`\_=11\relax - \catcode`\:=11\relax - \endlinechar=` % - \relax -} -\let\InternalSyntaxOff\relax -\ExplSyntaxOn -\cs_set_nopar:Npn \define@key#1#2{% - \@ifnextchar[ - {\KV@def{#1}{\string#2}} - {\@namedef{KV@#1@\string#2}####1}} -\cs_set_nopar:Npn \setkeys#1#2{% - \cs_set_nopar:Npn \KV@prefix{KV@#1@\expandafter\string}% - \KV@do#2,\relax,} -\newtoks\KV@toks -\cs_set_nopar:Npn \KV@@sp@c#1\@nil#2\relax#3{\KV@toks{#1}\cs_set_nopar:Npx #3{\the\KV@toks}} -\cs_set_nopar:Npn \KV@equal{=} -\cs_set_nopar:Npn \KV@split#1=#2=#3\relax{% - \KV@@sp@def\@tempa{#1}% - \cs_set_nopar:Npn \@tempd{#3}% - \ifx\@tempa\@empty\else - \expandafter\cs_set_eq:NN \expandafter\@tempc - \csname\KV@prefix\@tempa\endcsname - \ifx\@tempc\relax - \KV@error{\@tempa\space \expandafter\@gobbletwo\string\@undefined}\@eha - \else - \ifx\@tempd\@empty - \KV@default - \else - \KV@@sp@def\@tempb{#2}% - \ifx\@tempd\KV@equal - \expandafter\@tempc\expandafter{\@tempb}\relax - \else - \KV@error{Extra~=~ sign~ after~ `#1'}\KV@erry - \fi - \fi - \fi - \fi} -\cs_set_nopar:Npn \KV@erry{\expandafter\KV@errx\meaning\@tempd\relax ignored\MessageBreak - missing~comma~in~`\expandafter\strip@prefix\meaning\@tempb'~?} -\cs_set_nopar:Npn \KV@errx#1>#2==\relax{% - `#2' } -\cs_set_nopar:Npn \KV@default{% - \expandafter\cs_set_eq:NN \expandafter\@tempb - \csname\KV@prefix\@tempa @default\endcsname - \ifx\@tempb\relax - \KV@error{No value specified for \@tempa}\@eha - \else - \@tempb\relax - \fi} -\cs_set_nopar:Npn \KV@error#1#2{\PackageError{keyval}{#1}{#2}} -\cs_set_nopar:Npn \KV@parse#1{ - \begingroup -\cs_set_nopar:Npn \KV@@sp@c##1\@nil##2\relax##3{\addto@hook##3{{##1}}} -\cs_set_nopar:Npn \KV@split##1=##2=##3\relax{% - \cs_set_nopar:Npn \@tempd{##3}% - \expandafter\ifx\expandafter=\@firstofone##1=\else - \ifx\@tempd\@empty - \addto@hook\KV@toks\KV@default@elt - \KV@@sp@def\KV@toks{##1}% - \else - \ifx\@tempd\KV@equal - \addto@hook\KV@toks\KV@elt - \KV@@sp@def\KV@toks{##1}% - \KV@@sp@def\KV@toks{##2}% - \else - \KV@err{Extra `=' after `##1'}\@ehd - \fi - \fi - \fi} - \KV@toks{} - \KV@do#1,\relax, - \expandafter - \endgroup - \the\KV@toks} -\cs_set_eq:NN \SetInternalCounter \calc_int_set:Nn -\cs_set_eq:NN \GSetInternalCounter\calc_int_gset:Nn -\cs_set_nopar:Npn \UndeclareRobustCommand#1{% - \cs_gundefine:N #1 - \exp_args:Nc \cs_gundefine:N {\cs_to_str:N #1~} -} -\endinput -%% -%% End of file `ldcsetup.sty'. diff --git a/Master/texmf-dist/tex/latex/xpackages/template.sty b/Master/texmf-dist/tex/latex/xpackages/template.sty deleted file mode 100644 index a64a9cf4cc9..00000000000 --- a/Master/texmf-dist/tex/latex/xpackages/template.sty +++ /dev/null @@ -1,567 +0,0 @@ -%% -%% This is file `template.sty', -%% generated with the docstrip utility. -%% -%% The original source files were: -%% -%% template.dtx (with options: `package,trace') -%% -%% (C) Copyright The LaTeX3 Project and any individual authors -%% listed elsewhere in this file. -%% -%% This is a generated file. -%% -%% This file was generated from file(s) of the xbase bundle. -%% --------------------------------------------------------- -%% -%% This file may only be distributed together with a copy of this bundle. -%% You may however distribute the bundle without such generated files. -%% -%% ====================================================================== -%% -%% File: template.dtx (C) Copyright 1999-2001 David Carlisle, Frank Mittelbach -%% (C) Copyright 2004-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 -%% 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 ``xbase 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{expl3} -\GetIdInfo$Id: template.dtx 1295 2009-05-06 08:32:25Z will $ - {template} -\ProvidesExplPackage - {\filename}{\filedate}{\fileversion}{\filedescription} -\RequirePackage{expl3} -\RequirePackage{ldcsetup,xparse} -\toks_new:N\l_TP_KV_assignments_toks -\toks_new:N\l_TP_default_assignments_toks -\cs_new_nopar:Nn \TP_declare_instance:Nnn { - \group_begin: - \TP_instdecl_generate_assignments:nn {#2}{#3} - \cs_gset_nopar:Npx #1 { - \tl_if_eq:cNTF { TP>/#2 } \c_TP_doparameterassignments_tl - { \toks_use:N \l_TP_KV_assignments_toks } - { - \exp_not:N \TP_push_assignments:n - {\toks_use:N\l_TP_KV_assignments_toks} - \exp_not:c {TP>/#2} - } - } - \group_end:} -\cs_generate_variant:Nn \TP_declare_instance:Nnn {cnn} -\tl_set:Nn \c_TP_doparameterassignments_tl {\DoParameterAssignments} -\cs_new_nopar:Npn \UseTemplate #1#2#3{ - \TP_instdecl_generate_assignments:nn {#1/#2}{#3} - \TP_push_assignments: - \use:c { TP>/#1/#2 } -} -\cs_new_nopar:Npn \DoParameterAssignments{ - \exp_after:wN - \TP_pop_and_execute_assignments:nw - \toks_use:N \g_TP_assignments_stack_toks \q_stop -} -\cs_new_nopar:Npn \TP_pop_and_execute_assignments:nw#1#2\q_stop{ - \toks_gset:Nn \g_TP_assignments_stack_toks {#2} - #1} -\toks_new:N \g_TP_assignments_stack_toks -\toks_gset:Nn \g_TP_assignments_stack_toks {\scan_stop:}% avoid brace loss -\cs_new:Npn \TP_push_assignments:n#1{ - \toks_gput_left:Nn\g_TP_assignments_stack_toks{{#1}} -} -\cs_new_nopar:Npn \TP_push_assignments:{ - \toks_gset:No \g_TP_assignments_stack_toks - {\exp_after:wN - {\toks_use:N\exp_after:wN\l_TP_KV_assignments_toks\exp_after:wN} - \toks_use:N\g_TP_assignments_stack_toks} -} -\cs_new_nopar:Npn \DeclareTemplateType #1#2{ - \tl_set:cn {TP@<#1>} {{}#2}} -\cs_new_nopar:Nn \TP_get_csname_prefix:n { - <\exp_after:wN\exp_after:wN\exp_after:wN - \use_i:nn - \cs:w TP@<#1>\cs_end:>#1/ -} -\cs_new_nopar:Nn \TP_get_arg_count:n { - \exp_after:wN\exp_after:wN\exp_after:wN - \use_ii:nn - \cs:w TP@<#1>\cs_end: -} -\cs_new:Npn\DeclareTemplate #1#2#3#4#5{ - \cs_if_free:cTF{TP@<#1>} - {\undefinedtype\DeclareTemplateType{#1}#3} - { - \intexpr_compare:nNnF{#3}={\TP_get_arg_count:n{#1}} - { \BadArgCount } - } - \cs_set_eq:NN \KV_elt:nn \TP_templdecl_process_KV:nn - \cs_set_nopar:Npn \KV_default_elt:n##1{ - \PackageError{template}{Missing~ =~ after~ ##1}\@ehd} - \cs_set_eq:NN\KV@elt\KV_elt:nn - \cs_set_eq:NN\KV@default@elt\KV_default_elt:n - \tl_set:Nn \l_TP_curr_name_tl {#1/#2} - \toks_clear:N\l_TP_default_assignments_toks - %\intexpr_compare:nNnTF{\char_value_catcode:n{`\ }}=\c_nine - %\KV_parse_picky_no_space_removal_no_sanitize:n - %\KV_parse_picky_space_removal_no_sanitize:n - \KV@parse{#4} - \cs_set_nopar:cpx { TPD>/\l_TP_curr_name_tl } - {\toks_use:N\l_TP_default_assignments_toks} - - \tl_clear:c {TPR>/\l_TP_curr_name_tl} - - \tl_set_eq:cN {TPO>/\l_TP_curr_name_tl}\l_TP_curr_name_tl - \cs_generate_from_arg_count:cNnn {TP>/\l_TP_curr_name_tl} - \cs_set:Npn {#3}{#5} -} -\cs_set:Npn \tl_set:cx {\exp_args:Nc \tl_set:Nx} -\cs_new_nopar:Nn \TP_templdecl_process_KV:nn {% - \cs_set_eq:NN \TP_templdecl_add_global_or_nothing: \prg_do_nothing: - \bool_set_false:N\l_TP_global_assignment_bool - \tl_set:Nn\l_TP_currkey_tl{#1} - \TP_templdecl_parse_KV:N#2\q_stop} -\cs_new_nopar:Nn \TP_templdecl_parse_KV:N { - \cs_if_free:cTF{TP_use_arg_type_#1:w} - {\PackageError{template}{Unknown~key~type~ (#1)~for~\l_TP_currkey_tl}\@eha} - {\use:c{TP_use_arg_type_#1:w}} -} -\bool_new:N \l_TP_global_assignment_bool -\cs_new_nopar:cpn{TP_use_arg_type_+:w} { - \bool_set_true:N\l_TP_global_assignment_bool - \cs_set_nopar:Npn \TP_templdecl_add_global_or_nothing: - {\toks_put_right:Nn \l_TP_KV_assignments_toks {\pref_global:D} } - \TP_templdecl_parse_KV:N -} -\cs_new_nopar:Npn\TP_use_arg_type_l:w { - \TP_parse_optional_key_default:nw - { - \cs_set_eq:NN \TP_templdecl_add_global_or_nothing: \prg_do_nothing: - \bool_if:NTF \l_TP_global_assignment_bool - {\TP_templdecl_setup_register_key:Nn\gsetlength} - {\TP_templdecl_setup_register_key:Nn\setlength} - } -} -\cs_new_nopar:Npn\TP_use_arg_type_L:w { - \TP_parse_optional_key_default:nw - {\TP_templdecl_setup_fakeregister_key:NNn\setlength\l_tmpa_skip} -} -\cs_new_nopar:Npn\TP_use_arg_type_c:w { - \TP_parse_optional_key_default:nw - { - \cs_set_eq:NN\TP_templdecl_add_global_or_nothing:\prg_do_nothing: - \bool_if:NTF \l_TP_global_assignment_bool - {\TP_templdecl_setup_register_key:Nn\GSetInternalCounter} - {\TP_templdecl_setup_register_key:Nn\SetInternalCounter} - } -} -\cs_new_nopar:Npn\TP_use_arg_type_C:w { - \TP_parse_optional_key_default:nw - {\TP_templdecl_setup_fakeregister_key:NNn - \SetInternalCounter\l_tmpa_int} -} -\cs_new_nopar:Npn\TP_use_arg_type_n:w { - \TP_parse_optional_key_default:nw - {\TP_templdecl_setup_n_key:N} -} -\cs_new_nopar:Npn\TP_use_arg_type_f:w #1{ - %\TP_templdecl_parse_f_arg:nw {#1} - \TP_parse_optional_key_default:nw{\TP_templdecl_setup_f_key:Nn{#1}} -} -\cs_new_nopar:Npn \TP_templdecl_parse_f_arg:nw#1#2{ - \TP_parse_optional_key_default:nw{\TP_templdecl_setup_f_key:Nn{#1}{#2}} -} -\cs_new_nopar:Npn\TP_use_arg_type_b:w { - \TP_parse_optional_key_default:nw - {\TP_templdecl_setup_b_key:n} -} -\cs_new_nopar:Npn \TP_templdecl_setup_b_key:n#1{ - \cs_set_eq:cN { if#1 } \if_true: - \TP_templdecl_define_key:n - { \TP_templdecl_eval_b_key_value:nn {#1}{##1} } -} -\cs_new_nopar:Npn \TP_templdecl_eval_b_key_value:nn#1#2{ - \cs_if_free:cTF {if#2} - { \PackageError{template}{Bad~boolean~setting~#1=#2}\@eha } - { \tl_set_eq:cc {if_#1:}{if_#2:} - \toks_put_right:Nf \l_TP_KV_assignments_toks - { \tl_set_eq:cc {if_#1:}{if_#2:} } - } -} -\cs_new_nopar:Npn\TP_use_arg_type_s:w { - \TP_parse_optional_key_default:nw - {\TP_templdecl_setup_s_key:n} -} -\cs_new_nopar:Npn \TP_templdecl_setup_s_key:n #1 { - \TP_templdecl_define_key:n - { \TP_templdecl_eval_s_key_value:nnn{##1}#1 } -} -\cs_new_nopar:Npn\TP_use_arg_type_i:w #1{ - \TP_parse_optional_key_default:nw{\TP_templdecl_setup_i_key:nnn{#1}} -} -\cs_new_nopar:Npn \TP_templdecl_setup_i_key:nnn#1#2{ - \TP_templdecl_define_key:n - { - \TP_templdecl_eval_i_key_value:Nnn #2 {#1}{##1} - } -} -\cs_new_nopar:Npn \TP_templdecl_eval_i_key_value:Nnn #1#2#3 { - \tl_if_head_eq_meaning:nNTF {#3.}\UseTemplate - { - \iow_term:x{\token_to_str:N\UseTemplate\space seen} - {\TP_templdecl_declare_tmp_instance:nnnn #3 } - \toks_put_right:No \l_TP_KV_assignments_toks - { \exp_after:wN \KV@toks \exp_after:wN {\g_tmpa_tl} } - %\TP_templdecl_add_global_or_nothing: - %\toks_put_right:Nn \l_TP_KV_assignments_toks - % { \cs_set_nopar:Npx #1{ \toks_use:N \KV@toks} } - \bool_if:NTF \l_TP_global_assignment_bool - {\toks_put_right:Nn \l_TP_KV_assignments_toks - {\cs_gset_nopar:Npx #1 { \toks_use:N \KV@toks}} - } - {\toks_put_right:Nn \l_TP_KV_assignments_toks - {\cs_set_nopar:Npx #1 { \toks_use:N \KV@toks}} - } - } - { - \TP_let_instance:Nnn#1{#2}{#3} - \toks_put_right:Nf \l_TP_KV_assignments_toks - { \TP_let_instance:Nnn#1{#2}{#3} } - } -} -\cs_new_nopar:Npn\TP_use_arg_type_x:w { - \TP_parse_optional_key_default:nw - {\TP_templdecl_setup_x_key:n} -} -\cs_new_nopar:Npn \TP_templdecl_setup_x_key:n#1{ - \TP_templdecl_define_key:n - { \toks_put_right:Nn\l_TP_KV_assignments_toks{#1} } -} -\cs_new_nopar:Npn\TP_use_arg_type_g:w { - \TP_parse_optional_key_default:nw - {\TP_templdecl_setup_g_key:n} -} -\cs_new_nopar:Npn \TP_templdecl_setup_g_key:n #1 { - \TP_templdecl_define_key:n{#1}} -\cs_new_nopar:Npn \TP_templdecl_define_key:n#1{ - \exp_after:wN \cs_set:Npn \cs:w - KV@\l_TP_curr_name_tl @\l_TP_currkey_tl - \exp_after:wN\cs_end: - \exp_after:wN##\exp_after:wN1\exp_after:wN{ - \exp_after:wN\TP_templdecl_remove_from_default_assignments:N - \cs:w KV@\l_TP_curr_name_tl @\l_TP_currkey_tl - \exp_after:wN \cs_end: - \TP_templdecl_add_global_or_nothing: - #1 - } -} -\cs_set:Npn \TP_ignore_leading_space_in_arg_ii:nn#1#2{ - \exp_args:Nf\TP_ignore_leading_space_in_arg_ii_aux:nn - {\exp_not:N #2}{#1} -} -\cs_set:Npn \TP_ignore_leading_space_in_arg_ii_aux:nn#1#2{#2{#1}} - -\DeclareArgumentType t[{meaning}{}{\NoValue}{#1[#2]}{#2} -\DeclareDocumentCommand\TP_parse_optional_key_default:nw{mt}{ - \IfNoValueTF{#2} - {\TP_templdecl_finish_key_setup:nw{#1}} - {\TP_templdecl_finish_key_setup_with_default:nnw{#1}{#2}} -} -\cs_new_nopar:Npn \TP_templdecl_finish_key_setup:nw#1#2\q_stop{ - \TP_ignore_leading_space_in_arg_ii:nn{#1}{#2} - %%%#1{#2} -} -\cs_new_nopar:Npn \TP_templdecl_finish_key_setup_with_default:nnw#1#2#3\q_stop{ - \TP_ignore_leading_space_in_arg_ii:nn{#1}{#3} - %%% #1 {#3} - \group_begin: - \toks_clear:N \l_TP_KV_assignments_toks - \cs_set_eq:NN \TP_templdecl_remove_from_default_assignments:N \use_none:n - \use:c{KV@\l_TP_curr_name_tl @\l_TP_currkey_tl}{#2} - \exp_after:wN - \group_end: - \exp_after:wN - \toks_set:Nn - \exp_after:wN - \l_TP_default_assignments_toks - \exp_after:wN - { \cs:w KV@\l_TP_curr_name_tl @\l_TP_currkey_tl \exp_after:wN \cs_end: - \exp_after:wN - { \toks_use:N \exp_after:wN \l_TP_KV_assignments_toks - \exp_after:wN - } - \toks_use:N\l_TP_default_assignments_toks - } -} -\tl_new:Nn \c_TP_true_tl {true} -\cs_new_nopar:Npn \TP_templdecl_eval_s_key_value:nnn#1#2#3 { - \tl_set:Nn \l_tmpa_tl {#1} - \tl_if_eq:NNTF \l_tmpa_tl \c_TP_true_tl - { \toks_put_right:Nn \l_TP_KV_assignments_toks {#2} } - { \toks_put_right:Nn \l_TP_KV_assignments_toks {#3} } -} -\cs_new_nopar:Npn \TP_templdecl_setup_register_key:Nn #1#2{ - \TP_templdecl_define_key:n{ - \tl_if_head_eq_meaning:nNTF{##1}\DelayEvaluation - { - \toks_put_right:Nn \l_TP_KV_assignments_toks {#1#2{##1}} - %\toks_set:No\l_tmpa_toks{\use_ii:nn ##1} - %\toks_put_right:Nx \l_TP_KV_assignments_toks - % {\exp_not:n{#1#2}{\toks_use:N \l_tmpa_toks}} - } - { - \tl_if_head_eq_meaning:nNTF{##1..}\MultiSelection - { - \group_begin: - \TP_multiselection_add:nnnnnn #1#2##1 - \group_end: - \tl_if_in:onTF{\toks_use:N\g_TP_multiselection_toks}\DelayEvaluation - { - \toks_put_right:No\l_TP_KV_assignments_toks - { - \exp_after:wN#1\exp_after:wN#2\exp_after:wN - {\toks_use:N\g_TP_multiselection_toks} - } - } - { - \toks_put_right:No\l_TP_KV_assignments_toks - { - \exp_after:wN #2 - \exp_after:wN= \toks_use:N\g_TP_multiselection_toks\scan_stop: - } - } - } - { - #1#2{##1} - \toks_put_right:No\l_TP_KV_assignments_toks { - \exp_after:wN #2 \exp_after:wN = \tex_the:D #2\scan_stop: - } - } - } - } -} -\cs_new_nopar:Npn\DelayEvaluation #1{\use_none:n{\DelayEvaluation}#1} -\cs_new_nopar:Npn\MultiSelection #1{\use_none:n{\MultiSelection}#1} -\cs_new_nopar:Npn \TP_templdecl_remove_from_default_assignments:N#1{ - \cs_set_nopar:Npn \TP_tmp:w ##1#1##2##3#1##4\q_stop{ - \l_TP_default_assignments_toks{##1##3} - } - \exp_after:wN \TP_tmp:w - \toks_use:N\l_TP_default_assignments_toks #1\scan_stop:#1\q_stop} -\cs_new_nopar:Npn \TP_templdecl_setup_f_key:Nn#1#2{ - \TP_templdecl_define_key:n - { \TP_templdecl_define_function:NNn#1#2{##1} } -} -\cs_new_nopar:Npn \TP_templdecl_define_function:NNn#1#2#3{ - \cs_generate_from_arg_count:NNnn #2 \cs_set:Npn {#1}{#3} - \toks_put_right:Nf \l_TP_KV_assignments_toks { - \cs_generate_from_arg_count:NNnn #2 \cs_set:Npn {#1}{#3} - } -} -\cs_new_nopar:Npn \TP_templdecl_setup_n_key:N#1{ - \TP_templdecl_define_key:n{ - \tl_if_head_eq_meaning:nNTF{##1..}\MultiSelection - { - \group_begin: - \TP_templdecl_multiselection:nnnn ##1 - \group_end: - \toks_put_right:Nx\l_TP_KV_assignments_toks { - \exp_not:n{\tl_set:Nf #1} { \toks_use:N \g_TP_multiselection_toks} - } - } - { - \cs_set_nopar:Npn #1{##1} % setting it? - \toks_put_right:Nn \l_TP_KV_assignments_toks - { \tl_set:Nn #1{##1} } - } - } -} -\cs_new_nopar:Npn \TP_templdecl_multiselection:nnnn #1#2#3#4{ - \toks_gset:Nn \g_TP_multiselection_toks {\if_case:w #2} - \clist_map_inline:nn {#3}{ - \TP_multiselection_add_or_case:n {\exp_stop_f:##1} - } - \toks_gput_right:Nn\g_TP_multiselection_toks { - \else: \use_i_after_fi:nw { \exp_stop_f: #4} \fi: - } -} -\cs_new_nopar:Npn \DeclareInstance { \DeclareCollectionInstance{} } -\cs_new:Npn \DeclareCollectionInstance#1#2#3#4{ - \TP_declare_instance:cnn { <#1>#2/#3 }{ #2/#4 } -} -\cs_new_nopar:Npn \UseCollection#1#2{ - \tl_set:cx { TP@<#1> } - { {#2} \TP_get_arg_count:n{#1} } -} -\cs_new_nopar:Npn \TP_let_instance:Nnn#1#2#3{ - \cs_set_eq:Nc #1 - { - \cs_if_free:cTF { \TP_get_csname_prefix:n{#2} #3 } - { <>#2/ } - { \TP_get_csname_prefix:n{#2} } - #3 - } -} -\cs_new_nopar:Npn \UseInstance#1#2{ - \TP_let_instance:Nnn \l_tmpa_tl {#1}{#2} - \tl_if_eq:NNTF \l_tmpa_tl \scan_stop: - \INSTANCEundefined - \l_tmpa_tl -} -\cs_new:Npn \TP_templdecl_declare_tmp_instance:nnnn#1#2#3{% - \TP_declare_instance:Nnn \g_tmpa_tl {#2/#3} } -\cs_new_nopar:Npn \ShowTemplate#1#2{ - \iow_term:x{*******~ Template:~ #1/#2~ *******} - \iow_term:x{*} - \iow_term:x{*~ Defaults:} - \iow_term:x{*} - \iow_term:x{\token_to_str:N\TPD>/#1/#2= - \cs_meaning:c{TPD>/#1/#2}} - \iow_term:x{*} - \iow_term:x{*~ Restrictions:} - \iow_term:x{*} - \iow_term:x{\token_to_str:N\TPR>/#1/#2= - \cs_meaning:c{TPR>/#1/#2}} - \iow_term:x{*} - \iow_term:x{*~ Body:} - \iow_term:x{*} - \cs_show:c {TP>/#1/#2}} -\cs_new_nopar:Npn \ShowCollectionInstance#1#2#3{ - \iow_term:x{*******~ Instance:~ <#1>#2/#3~ *******} - \iow_term:x{*} - \cs_show:c {<#1>#2/#3}} -\cs_new_nopar:Npn \ShowInstance{\ShowCollectionInstance{}} -\cs_new_nopar:Npn \TP_templdecl_setup_fakeregister_key:NNn#1#2#3{ - \TP_templdecl_define_key:n{ - \tl_if_head_eq_meaning:nNTF{##1..}\DelayEvaluation - { - \toks_set:No \l_tmpa_toks {\use_ii:nn ##1} - \toks_put_right:Nx \l_TP_KV_assignments_toks { - \exp_not:n{#1#2}{\toks_use:N \l_tmpa_toks} - \exp_not:n{ \cs_set_nopar:Npx #3{\toks_use:N#2} } - - } - } - { - \tl_if_head_eq_meaning:nNTF{##1..}\MultiSelection - { - \group_begin: - \TP_multiselection_add:nnnnnn#1#2##1 - \group_end: - \toks_put_right:Nx\l_TP_KV_assignments_toks - {\exp_not:n{\cs_set_nopar:Npn #3} {\toks_use:N\g_TP_multiselection_toks}} - } - { - #1#2{##1} - \toks_put_right:Nx\l_TP_KV_assignments_toks - {\exp_not:n{\cs_set_nopar:Npn#3} {\toks_use:N#2}} - } - } - } -} -\toks_new:N \g_TP_multiselection_toks -\cs_new_nopar:Npn \TP_multiselection_add:nnnnnn #1#2#3#4#5#6{ - \toks_gset:Nn \g_TP_multiselection_toks {\if_case:w #4} - \clist_map_inline:nn {#5}{ - \tl_if_head_eq_meaning:nNTF{##1..}\DelayEvaluation - { - \TP_multiselection_add_or_case:n {##1} - } - { - #1#2{##1} - \TP_multiselection_add_or_case:o { \toks_use:N #2 } - } - } - \toks_gput_right:Nn \g_TP_multiselection_toks { - \else: \use_i_after_fi:nw{#6}\fi: - } -} -\cs_new_nopar:Npn \TP_multiselection_add_or_case:n #1 { - \toks_gput_right:Nn \g_TP_multiselection_toks { - \or: \use_i_after_orelse:nw{#1} - } -} -\cs_generate_variant:Nn \TP_multiselection_add_or_case:n {o} -\cs_new_nopar:Npn \IfExistsInstanceTF#1#2{ - \cs_if_exist:cTF{<>#1/#2} -} -\cs_set_nopar:Npn \IfExistsInstanceTF#1#2{ - \TP_let_instance:Nnn \l_tmpa_tl {#1}{#2} - \if_meaning:w\l_tmpa_tl\scan_stop: - \exp_after:wN\use_ii:nn - \else: - \exp_after:wN\use_i:nn - \fi:} -\cs_new_nopar:Npn \DeclareRestrictedTemplate#1#2#3#4{ - % CCC do we need a group here?? - \tl_set_eq:cc { TPD>/#1/#2 } { TPD>/#1/#3 } - \tl_set_eq:cc { TP>/#1/#2 } { TP>/#1/#3 } - \toks_set:Nv \l_TP_KV_assignments_toks { TPR>/ #1 / #3 } - \setkeys {\cs:w TPO>/#1/#3\cs_end:}{#4} - - \tl_set:cx { TPR>/#1/#2 } - { \toks_use:N \l_TP_KV_assignments_toks } - \cs_if_free:cTF { TPO>/#1/#3 } - { \tl_set:cn {TPO>/#1/#2}{#1/#3} } - { \tl_set_eq:cc {TPO>/#1/#2}{TPO>/#1/#3} } -} -\cs_new_nopar:Npn \TP_instdecl_generate_assignments:nn#1#2 { - % Returns to \l_TP_KV_assignments_toks - % the restrictions - % stored in the TP-structure (at present - % in YAM) of the template #1 - \exp_args:NNo \toks_set:No \l_TP_default_assignments_toks - {\cs:w TPD>/#1\cs_end:\scan_stop:\scan_stop:} - \toks_set:Nv \l_TP_KV_assignments_toks { TPR>/ #1 } - \setkeys { \cs:w TPO>/#1 \cs_end: } - { #2 } % adds stuff to \l_TP_KV_assignments_toks - - \exp_after:wN\TP_instdecl_add_default_recurse:nn - \toks_use:N\l_TP_default_assignments_toks - -} -\cs_new_nopar:Npn \TP_instdecl_add_default_recurse:nn#1#2{ - \token_if_eq_meaning:NNF #1\scan_stop: - { - \l_tmpa_toks{#2} - \tl_set:Nx \l_tmpa_tl { - {\toks_use:N \l_tmpa_toks \toks_use:N \l_TP_KV_assignments_toks} - } - \l_TP_KV_assignments_toks \l_tmpa_tl - \TP_instdecl_add_default_recurse:nn - } -} -\cs_new_nopar:Npn \TP_split_finite_skip_value:nnNN #1#2{ - \skip_split_finite_else_action:nnNN {#1} { - \PackageError{template}{Value~ for~ key~ #2~ contains~ `fil(ll)'} - {Only~ finite~ minus~ or~ plus~ parts~ are~ allowed~ for~ this~ key.} - } -} -\endinput -%% -%% End of file `template.sty'. diff --git a/Master/texmf-dist/tex/latex/xpackages/xbase/ldcsetup.sty b/Master/texmf-dist/tex/latex/xpackages/xbase/ldcsetup.sty new file mode 100644 index 00000000000..7f26ce16cbb --- /dev/null +++ b/Master/texmf-dist/tex/latex/xpackages/xbase/ldcsetup.sty @@ -0,0 +1,193 @@ +%% +%% This is file `ldcsetup.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% ldcsetup.dtx (with options: `package') +%% +%% (C) Copyright The LaTeX3 Project and any individual authors +%% listed elsewhere in this file. +%% +%% This is a generated file. +%% +%% This file was generated from file(s) of the xbase bundle. +%% --------------------------------------------------------- +%% +%% This file may only be distributed together with a copy of this bundle. +%% You may however distribute the bundle without such generated files. +%% +%% ====================================================================== +%% +%% File: ldcsetup.dtx (C) Copyright 1999 Frank Mittelbach, Chris Rowley, David Carlisle +%% (C) Copyright 2004-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 +%% 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 ``xbase 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{expl3} +\GetIdInfo$Id: ldcsetup.dtx 1295 2009-05-06 08:32:25Z will $ + {coding conventions and stuff} +\ProvidesExplPackage + {\filename}{\filedate}{\fileversion}{\filedescription} +\RequirePackage{keyval} +\RequirePackage{expl3} +\ExplSyntaxOff +%% Puts an ignored space at the end of the line, so `|\ |' does the right +\def\IgnoreWhiteSpace{% + \edef\@tempa{% + \catcode`\noexpand\~=\the\catcode`\~\relax + \catcode`\noexpand\ =\the\catcode`\ \relax + \catcode`\noexpand\^^I=\the\catcode`\^^I\relax + \catcode`\noexpand\@=\the\catcode`\@\relax + \endlinechar=\the\endlinechar\relax + }% + \ifx\@currname\@empty + \expandafter\AtBeginDocument\expandafter{\@tempa}% + \else + \expandafter\AtEndOfPackage\expandafter{\@tempa}% + \fi + \catcode`\~=10\relax + \catcode`\ =9\relax + \catcode`\^^I=9\relax + \makeatletter + \endlinechar=` % + \relax +} +\def\InternalSyntaxOn{% + \edef\@tempa{% + \catcode`\noexpand\~=\the\catcode`\~\relax + \catcode`\noexpand\ =\the\catcode`\ \relax + \catcode`\noexpand\^^I=\the\catcode`\^^I\relax + \catcode`\noexpand\@=\the\catcode`\@\relax + \catcode`\noexpand\:=\the\catcode`\:\relax + \catcode`\noexpand\_=\the\catcode`\_\relax + \endlinechar=\the\endlinechar\relax + \endlinechar=13\relax + }% +%%% ???? + \ifx\InternalSyntaxOff\relax + \expandafter\def\expandafter\InternalSyntaxOff\expandafter + {\@tempa\let\InternalSyntaxOff\relax}% + \fi + \ifx\@currname\@empty + \expandafter\AtBeginDocument\expandafter{\@tempa}% + \else + \expandafter\AtEndOfPackage\expandafter{\@tempa}% + \fi + \catcode`\~=10\relax + \catcode`\ =9\relax + \catcode`\^^I=9\relax + \makeatletter + \catcode`\_=11\relax + \catcode`\:=11\relax + \endlinechar=` % + \relax +} +\let\InternalSyntaxOff\relax +\ExplSyntaxOn +\cs_set_nopar:Npn \define@key#1#2{% + \@ifnextchar[ + {\KV@def{#1}{\string#2}} + {\@namedef{KV@#1@\string#2}####1}} +\cs_set_nopar:Npn \setkeys#1#2{% + \cs_set_nopar:Npn \KV@prefix{KV@#1@\expandafter\string}% + \KV@do#2,\relax,} +\newtoks\KV@toks +\cs_set_nopar:Npn \KV@@sp@c#1\@nil#2\relax#3{\KV@toks{#1}\cs_set_nopar:Npx #3{\the\KV@toks}} +\cs_set_nopar:Npn \KV@equal{=} +\cs_set_nopar:Npn \KV@split#1=#2=#3\relax{% + \KV@@sp@def\@tempa{#1}% + \cs_set_nopar:Npn \@tempd{#3}% + \ifx\@tempa\@empty\else + \expandafter\cs_set_eq:NN \expandafter\@tempc + \csname\KV@prefix\@tempa\endcsname + \ifx\@tempc\relax + \KV@error{\@tempa\space \expandafter\@gobbletwo\string\@undefined}\@eha + \else + \ifx\@tempd\@empty + \KV@default + \else + \KV@@sp@def\@tempb{#2}% + \ifx\@tempd\KV@equal + \expandafter\@tempc\expandafter{\@tempb}\relax + \else + \KV@error{Extra~=~ sign~ after~ `#1'}\KV@erry + \fi + \fi + \fi + \fi} +\cs_set_nopar:Npn \KV@erry{\expandafter\KV@errx\meaning\@tempd\relax ignored\MessageBreak + missing~comma~in~`\expandafter\strip@prefix\meaning\@tempb'~?} +\cs_set_nopar:Npn \KV@errx#1>#2==\relax{% + `#2' } +\cs_set_nopar:Npn \KV@default{% + \expandafter\cs_set_eq:NN \expandafter\@tempb + \csname\KV@prefix\@tempa @default\endcsname + \ifx\@tempb\relax + \KV@error{No value specified for \@tempa}\@eha + \else + \@tempb\relax + \fi} +\cs_set_nopar:Npn \KV@error#1#2{\PackageError{keyval}{#1}{#2}} +\cs_set_nopar:Npn \KV@parse#1{ + \begingroup +\cs_set_nopar:Npn \KV@@sp@c##1\@nil##2\relax##3{\addto@hook##3{{##1}}} +\cs_set_nopar:Npn \KV@split##1=##2=##3\relax{% + \cs_set_nopar:Npn \@tempd{##3}% + \expandafter\ifx\expandafter=\@firstofone##1=\else + \ifx\@tempd\@empty + \addto@hook\KV@toks\KV@default@elt + \KV@@sp@def\KV@toks{##1}% + \else + \ifx\@tempd\KV@equal + \addto@hook\KV@toks\KV@elt + \KV@@sp@def\KV@toks{##1}% + \KV@@sp@def\KV@toks{##2}% + \else + \KV@err{Extra `=' after `##1'}\@ehd + \fi + \fi + \fi} + \KV@toks{} + \KV@do#1,\relax, + \expandafter + \endgroup + \the\KV@toks} +\cs_set_eq:NN \SetInternalCounter \calc_int_set:Nn +\cs_set_eq:NN \GSetInternalCounter\calc_int_gset:Nn +\cs_set_nopar:Npn \UndeclareRobustCommand#1{% + \cs_gundefine:N #1 + \exp_args:Nc \cs_gundefine:N {\cs_to_str:N #1~} +} +\endinput +%% +%% End of file `ldcsetup.sty'. diff --git a/Master/texmf-dist/tex/latex/xpackages/xbase/template.sty b/Master/texmf-dist/tex/latex/xpackages/xbase/template.sty new file mode 100644 index 00000000000..b91b2d6715e --- /dev/null +++ b/Master/texmf-dist/tex/latex/xpackages/xbase/template.sty @@ -0,0 +1,566 @@ +%% +%% This is file `template.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% template.dtx (with options: `package,trace') +%% +%% (C) Copyright The LaTeX3 Project and any individual authors +%% listed elsewhere in this file. +%% +%% This is a generated file. +%% +%% This file was generated from file(s) of the xbase bundle. +%% --------------------------------------------------------- +%% +%% This file may only be distributed together with a copy of this bundle. +%% You may however distribute the bundle without such generated files. +%% +%% ====================================================================== +%% +%% File: template.dtx (C) Copyright 1999-2001 David Carlisle, Frank Mittelbach +%% (C) Copyright 2004-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 +%% 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 ``xbase 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{expl3} +\GetIdInfo$Id: template.dtx 1461 2009-08-15 08:38:12Z joseph $ + {template} +\ProvidesExplPackage + {\filename}{\filedate}{\fileversion}{\filedescription} +\RequirePackage{expl3} +\RequirePackage{ldcsetup,xparse} +\toks_new:N\l_TP_KV_assignments_toks +\toks_new:N\l_TP_default_assignments_toks +\cs_new_nopar:Nn \TP_declare_instance:Nnn { + \group_begin: + \TP_instdecl_generate_assignments:nn {#2}{#3} + \cs_gset_nopar:Npx #1 { + \tl_if_eq:cNTF { TP>/#2 } \c_TP_doparameterassignments_tl + { \toks_use:N \l_TP_KV_assignments_toks } + { + \exp_not:N \TP_push_assignments:n + {\toks_use:N\l_TP_KV_assignments_toks} + \exp_not:c {TP>/#2} + } + } + \group_end:} +\cs_generate_variant:Nn \TP_declare_instance:Nnn {cnn} +\tl_set:Nn \c_TP_doparameterassignments_tl {\DoParameterAssignments} +\cs_new_nopar:Npn \UseTemplate #1#2#3{ + \TP_instdecl_generate_assignments:nn {#1/#2}{#3} + \TP_push_assignments: + \use:c { TP>/#1/#2 } +} +\cs_new_nopar:Npn \DoParameterAssignments{ + \exp_after:wN + \TP_pop_and_execute_assignments:nw + \toks_use:N \g_TP_assignments_stack_toks \q_stop +} +\cs_new_nopar:Npn \TP_pop_and_execute_assignments:nw#1#2\q_stop{ + \toks_gset:Nn \g_TP_assignments_stack_toks {#2} + #1} +\toks_new:N \g_TP_assignments_stack_toks +\toks_gset:Nn \g_TP_assignments_stack_toks {\scan_stop:}% avoid brace loss +\cs_new:Npn \TP_push_assignments:n#1{ + \toks_gput_left:Nn\g_TP_assignments_stack_toks{{#1}} +} +\cs_new_nopar:Npn \TP_push_assignments:{ + \toks_gset:No \g_TP_assignments_stack_toks + {\exp_after:wN + {\toks_use:N\exp_after:wN\l_TP_KV_assignments_toks\exp_after:wN} + \toks_use:N\g_TP_assignments_stack_toks} +} +\cs_new_nopar:Npn \DeclareTemplateType #1#2{ + \tl_set:cn {TP@<#1>} {{}#2}} +\cs_new_nopar:Nn \TP_get_csname_prefix:n { + <\exp_after:wN\exp_after:wN\exp_after:wN + \use_i:nn + \cs:w TP@<#1>\cs_end:>#1/ +} +\cs_new_nopar:Nn \TP_get_arg_count:n { + \exp_after:wN\exp_after:wN\exp_after:wN + \use_ii:nn + \cs:w TP@<#1>\cs_end: +} +\cs_new:Npn\DeclareTemplate #1#2#3#4#5{ + \cs_if_free:cTF{TP@<#1>} + {\undefinedtype\DeclareTemplateType{#1}#3} + { + \intexpr_compare:nNnF{#3}={\TP_get_arg_count:n{#1}} + { \BadArgCount } + } + \cs_set_eq:NN \KV_elt:nn \TP_templdecl_process_KV:nn + \cs_set_nopar:Npn \KV_default_elt:n##1{ + \PackageError{template}{Missing~ =~ after~ ##1}\@ehd} + \cs_set_eq:NN\KV@elt\KV_elt:nn + \cs_set_eq:NN\KV@default@elt\KV_default_elt:n + \tl_set:Nn \l_TP_curr_name_tl {#1/#2} + \toks_clear:N\l_TP_default_assignments_toks + %\intexpr_compare:nNnTF{\char_value_catcode:n{`\ }}=\c_nine + %\KV_parse_picky_no_space_removal_no_sanitize:n + %\KV_parse_picky_space_removal_no_sanitize:n + \KV@parse{#4} + \cs_set_nopar:cpx { TPD>/\l_TP_curr_name_tl } + {\toks_use:N\l_TP_default_assignments_toks} + + \tl_clear:c {TPR>/\l_TP_curr_name_tl} + + \tl_set_eq:cN {TPO>/\l_TP_curr_name_tl}\l_TP_curr_name_tl + \cs_generate_from_arg_count:cNnn {TP>/\l_TP_curr_name_tl} + \cs_set:Npn {#3}{#5} +} +\cs_set:Npn \tl_set:cx {\exp_args:Nc \tl_set:Nx} +\cs_new_nopar:Nn \TP_templdecl_process_KV:nn {% + \cs_set_eq:NN \TP_templdecl_add_global_or_nothing: \prg_do_nothing: + \bool_set_false:N\l_TP_global_assignment_bool + \tl_set:Nn\l_TP_currkey_tl{#1} + \TP_templdecl_parse_KV:N#2\q_stop} +\cs_new_nopar:Nn \TP_templdecl_parse_KV:N { + \cs_if_free:cTF{TP_use_arg_type_#1:w} + {\PackageError{template}{Unknown~key~type~ (#1)~for~\l_TP_currkey_tl}\@eha} + {\use:c{TP_use_arg_type_#1:w}} +} +\bool_new:N \l_TP_global_assignment_bool +\cs_new_nopar:cpn{TP_use_arg_type_+:w} { + \bool_set_true:N\l_TP_global_assignment_bool + \cs_set_nopar:Npn \TP_templdecl_add_global_or_nothing: + {\toks_put_right:Nn \l_TP_KV_assignments_toks {\pref_global:D} } + \TP_templdecl_parse_KV:N +} +\cs_new_nopar:Npn\TP_use_arg_type_l:w { + \TP_parse_optional_key_default:nw + { + \cs_set_eq:NN \TP_templdecl_add_global_or_nothing: \prg_do_nothing: + \bool_if:NTF \l_TP_global_assignment_bool + {\TP_templdecl_setup_register_key:Nn\gsetlength} + {\TP_templdecl_setup_register_key:Nn\setlength} + } +} +\cs_new_nopar:Npn\TP_use_arg_type_L:w { + \TP_parse_optional_key_default:nw + {\TP_templdecl_setup_fakeregister_key:NNn\setlength\l_tmpa_skip} +} +\cs_new_nopar:Npn\TP_use_arg_type_c:w { + \TP_parse_optional_key_default:nw + { + \cs_set_eq:NN\TP_templdecl_add_global_or_nothing:\prg_do_nothing: + \bool_if:NTF \l_TP_global_assignment_bool + {\TP_templdecl_setup_register_key:Nn\GSetInternalCounter} + {\TP_templdecl_setup_register_key:Nn\SetInternalCounter} + } +} +\cs_new_nopar:Npn\TP_use_arg_type_C:w { + \TP_parse_optional_key_default:nw + {\TP_templdecl_setup_fakeregister_key:NNn + \SetInternalCounter\l_tmpa_int} +} +\cs_new_nopar:Npn\TP_use_arg_type_n:w { + \TP_parse_optional_key_default:nw + {\TP_templdecl_setup_n_key:N} +} +\cs_new_nopar:Npn\TP_use_arg_type_f:w #1{ + %\TP_templdecl_parse_f_arg:nw {#1} + \TP_parse_optional_key_default:nw{\TP_templdecl_setup_f_key:Nn{#1}} +} +\cs_new_nopar:Npn \TP_templdecl_parse_f_arg:nw#1#2{ + \TP_parse_optional_key_default:nw{\TP_templdecl_setup_f_key:Nn{#1}{#2}} +} +\cs_new_nopar:Npn\TP_use_arg_type_b:w { + \TP_parse_optional_key_default:nw + {\TP_templdecl_setup_b_key:n} +} +\cs_new_nopar:Npn \TP_templdecl_setup_b_key:n#1{ + \cs_set_eq:cN { if#1 } \if_true: + \TP_templdecl_define_key:n + { \TP_templdecl_eval_b_key_value:nn {#1}{##1} } +} +\cs_new_nopar:Npn \TP_templdecl_eval_b_key_value:nn#1#2{ + \cs_if_free:cTF {if#2} + { \PackageError{template}{Bad~boolean~setting~#1=#2}\@eha } + { \tl_set_eq:cc {if_#1:}{if_#2:} + \toks_put_right:Nf \l_TP_KV_assignments_toks + { \tl_set_eq:cc {if_#1:}{if_#2:} } + } +} +\cs_new_nopar:Npn\TP_use_arg_type_s:w { + \TP_parse_optional_key_default:nw + {\TP_templdecl_setup_s_key:n} +} +\cs_new_nopar:Npn \TP_templdecl_setup_s_key:n #1 { + \TP_templdecl_define_key:n + { \TP_templdecl_eval_s_key_value:nnn{##1}#1 } +} +\cs_new_nopar:Npn\TP_use_arg_type_i:w #1{ + \TP_parse_optional_key_default:nw{\TP_templdecl_setup_i_key:nnn{#1}} +} +\cs_new_nopar:Npn \TP_templdecl_setup_i_key:nnn#1#2{ + \TP_templdecl_define_key:n + { + \TP_templdecl_eval_i_key_value:Nnn #2 {#1}{##1} + } +} +\cs_new_nopar:Npn \TP_templdecl_eval_i_key_value:Nnn #1#2#3 { + \tl_if_head_eq_meaning:nNTF {#3.}\UseTemplate + { + \iow_term:x{\token_to_str:N\UseTemplate\space seen} + {\TP_templdecl_declare_tmp_instance:nnnn #3 } + \toks_put_right:No \l_TP_KV_assignments_toks + { \exp_after:wN \KV@toks \exp_after:wN {\g_tmpa_tl} } + %\TP_templdecl_add_global_or_nothing: + %\toks_put_right:Nn \l_TP_KV_assignments_toks + % { \cs_set_nopar:Npx #1{ \toks_use:N \KV@toks} } + \bool_if:NTF \l_TP_global_assignment_bool + {\toks_put_right:Nn \l_TP_KV_assignments_toks + {\cs_gset_nopar:Npx #1 { \toks_use:N \KV@toks}} + } + {\toks_put_right:Nn \l_TP_KV_assignments_toks + {\cs_set_nopar:Npx #1 { \toks_use:N \KV@toks}} + } + } + { + \TP_let_instance:Nnn#1{#2}{#3} + \toks_put_right:Nf \l_TP_KV_assignments_toks + { \TP_let_instance:Nnn#1{#2}{#3} } + } +} +\cs_new_nopar:Npn\TP_use_arg_type_x:w { + \TP_parse_optional_key_default:nw + {\TP_templdecl_setup_x_key:n} +} +\cs_new_nopar:Npn \TP_templdecl_setup_x_key:n#1{ + \TP_templdecl_define_key:n + { \toks_put_right:Nn\l_TP_KV_assignments_toks{#1} } +} +\cs_new_nopar:Npn\TP_use_arg_type_g:w { + \TP_parse_optional_key_default:nw + {\TP_templdecl_setup_g_key:n} +} +\cs_new_nopar:Npn \TP_templdecl_setup_g_key:n #1 { + \TP_templdecl_define_key:n{#1}} +\cs_new_nopar:Npn \TP_templdecl_define_key:n#1{ + \exp_after:wN \cs_set:Npn \cs:w + KV@\l_TP_curr_name_tl @\l_TP_currkey_tl + \exp_after:wN\cs_end: + \exp_after:wN##\exp_after:wN1\exp_after:wN{ + \exp_after:wN\TP_templdecl_remove_from_default_assignments:N + \cs:w KV@\l_TP_curr_name_tl @\l_TP_currkey_tl + \exp_after:wN \cs_end: + \TP_templdecl_add_global_or_nothing: + #1 + } +} +\cs_set:Npn \TP_ignore_leading_space_in_arg_ii:nn#1#2{ + \exp_args:Nf\TP_ignore_leading_space_in_arg_ii_aux:nn + {\exp_not:N #2}{#1} +} +\cs_set:Npn \TP_ignore_leading_space_in_arg_ii_aux:nn#1#2{#2{#1}} + +\DeclareDocumentCommand\TP_parse_optional_key_default:nw{mo}{ + \IfNoValueTF{#2} + {\TP_templdecl_finish_key_setup:nw{#1}} + {\TP_templdecl_finish_key_setup_with_default:nnw{#1}{#2}} +} +\cs_new_nopar:Npn \TP_templdecl_finish_key_setup:nw#1#2\q_stop{ + \TP_ignore_leading_space_in_arg_ii:nn{#1}{#2} + %%%#1{#2} +} +\cs_new_nopar:Npn \TP_templdecl_finish_key_setup_with_default:nnw#1#2#3\q_stop{ + \TP_ignore_leading_space_in_arg_ii:nn{#1}{#3} + %%% #1 {#3} + \group_begin: + \toks_clear:N \l_TP_KV_assignments_toks + \cs_set_eq:NN \TP_templdecl_remove_from_default_assignments:N \use_none:n + \use:c{KV@\l_TP_curr_name_tl @\l_TP_currkey_tl}{#2} + \exp_after:wN + \group_end: + \exp_after:wN + \toks_set:Nn + \exp_after:wN + \l_TP_default_assignments_toks + \exp_after:wN + { \cs:w KV@\l_TP_curr_name_tl @\l_TP_currkey_tl \exp_after:wN \cs_end: + \exp_after:wN + { \toks_use:N \exp_after:wN \l_TP_KV_assignments_toks + \exp_after:wN + } + \toks_use:N\l_TP_default_assignments_toks + } +} +\tl_new:Nn \c_TP_true_tl {true} +\cs_new_nopar:Npn \TP_templdecl_eval_s_key_value:nnn#1#2#3 { + \tl_set:Nn \l_tmpa_tl {#1} + \tl_if_eq:NNTF \l_tmpa_tl \c_TP_true_tl + { \toks_put_right:Nn \l_TP_KV_assignments_toks {#2} } + { \toks_put_right:Nn \l_TP_KV_assignments_toks {#3} } +} +\cs_new_nopar:Npn \TP_templdecl_setup_register_key:Nn #1#2{ + \TP_templdecl_define_key:n{ + \tl_if_head_eq_meaning:nNTF{##1}\DelayEvaluation + { + \toks_put_right:Nn \l_TP_KV_assignments_toks {#1#2{##1}} + %\toks_set:No\l_tmpa_toks{\use_ii:nn ##1} + %\toks_put_right:Nx \l_TP_KV_assignments_toks + % {\exp_not:n{#1#2}{\toks_use:N \l_tmpa_toks}} + } + { + \tl_if_head_eq_meaning:nNTF{##1..}\MultiSelection + { + \group_begin: + \TP_multiselection_add:nnnnnn #1#2##1 + \group_end: + \tl_if_in:onTF{\toks_use:N\g_TP_multiselection_toks}\DelayEvaluation + { + \toks_put_right:No\l_TP_KV_assignments_toks + { + \exp_after:wN#1\exp_after:wN#2\exp_after:wN + {\toks_use:N\g_TP_multiselection_toks} + } + } + { + \toks_put_right:No\l_TP_KV_assignments_toks + { + \exp_after:wN #2 + \exp_after:wN= \toks_use:N\g_TP_multiselection_toks\scan_stop: + } + } + } + { + #1#2{##1} + \toks_put_right:No\l_TP_KV_assignments_toks { + \exp_after:wN #2 \exp_after:wN = \tex_the:D #2\scan_stop: + } + } + } + } +} +\cs_new_nopar:Npn\DelayEvaluation #1{\use_none:n{\DelayEvaluation}#1} +\cs_new_nopar:Npn\MultiSelection #1{\use_none:n{\MultiSelection}#1} +\cs_new_nopar:Npn \TP_templdecl_remove_from_default_assignments:N#1{ + \cs_set_nopar:Npn \TP_tmp:w ##1#1##2##3#1##4\q_stop{ + \l_TP_default_assignments_toks{##1##3} + } + \exp_after:wN \TP_tmp:w + \toks_use:N\l_TP_default_assignments_toks #1\scan_stop:#1\q_stop} +\cs_new_nopar:Npn \TP_templdecl_setup_f_key:Nn#1#2{ + \TP_templdecl_define_key:n + { \TP_templdecl_define_function:NNn#1#2{##1} } +} +\cs_new_nopar:Npn \TP_templdecl_define_function:NNn#1#2#3{ + \cs_generate_from_arg_count:NNnn #2 \cs_set:Npn {#1}{#3} + \toks_put_right:Nf \l_TP_KV_assignments_toks { + \cs_generate_from_arg_count:NNnn #2 \cs_set:Npn {#1}{#3} + } +} +\cs_new_nopar:Npn \TP_templdecl_setup_n_key:N#1{ + \TP_templdecl_define_key:n{ + \tl_if_head_eq_meaning:nNTF{##1..}\MultiSelection + { + \group_begin: + \TP_templdecl_multiselection:nnnn ##1 + \group_end: + \toks_put_right:Nx\l_TP_KV_assignments_toks { + \exp_not:n{\tl_set:Nf #1} { \toks_use:N \g_TP_multiselection_toks} + } + } + { + \cs_set_nopar:Npn #1{##1} % setting it? + \toks_put_right:Nn \l_TP_KV_assignments_toks + { \tl_set:Nn #1{##1} } + } + } +} +\cs_new_nopar:Npn \TP_templdecl_multiselection:nnnn #1#2#3#4{ + \toks_gset:Nn \g_TP_multiselection_toks {\if_case:w #2} + \clist_map_inline:nn {#3}{ + \TP_multiselection_add_or_case:n {\exp_stop_f:##1} + } + \toks_gput_right:Nn\g_TP_multiselection_toks { + \else: \use_i_after_fi:nw { \exp_stop_f: #4} \fi: + } +} +\cs_new_nopar:Npn \DeclareInstance { \DeclareCollectionInstance{} } +\cs_new:Npn \DeclareCollectionInstance#1#2#3#4{ + \TP_declare_instance:cnn { <#1>#2/#3 }{ #2/#4 } +} +\cs_new_nopar:Npn \UseCollection#1#2{ + \tl_set:cx { TP@<#1> } + { {#2} \TP_get_arg_count:n{#1} } +} +\cs_new_nopar:Npn \TP_let_instance:Nnn#1#2#3{ + \cs_set_eq:Nc #1 + { + \cs_if_free:cTF { \TP_get_csname_prefix:n{#2} #3 } + { <>#2/ } + { \TP_get_csname_prefix:n{#2} } + #3 + } +} +\cs_new_nopar:Npn \UseInstance#1#2{ + \TP_let_instance:Nnn \l_tmpa_tl {#1}{#2} + \tl_if_eq:NNTF \l_tmpa_tl \scan_stop: + \INSTANCEundefined + \l_tmpa_tl +} +\cs_new:Npn \TP_templdecl_declare_tmp_instance:nnnn#1#2#3{% + \TP_declare_instance:Nnn \g_tmpa_tl {#2/#3} } +\cs_new_nopar:Npn \ShowTemplate#1#2{ + \iow_term:x{*******~ Template:~ #1/#2~ *******} + \iow_term:x{*} + \iow_term:x{*~ Defaults:} + \iow_term:x{*} + \iow_term:x{\token_to_str:N\TPD>/#1/#2= + \cs_meaning:c{TPD>/#1/#2}} + \iow_term:x{*} + \iow_term:x{*~ Restrictions:} + \iow_term:x{*} + \iow_term:x{\token_to_str:N\TPR>/#1/#2= + \cs_meaning:c{TPR>/#1/#2}} + \iow_term:x{*} + \iow_term:x{*~ Body:} + \iow_term:x{*} + \cs_show:c {TP>/#1/#2}} +\cs_new_nopar:Npn \ShowCollectionInstance#1#2#3{ + \iow_term:x{*******~ Instance:~ <#1>#2/#3~ *******} + \iow_term:x{*} + \cs_show:c {<#1>#2/#3}} +\cs_new_nopar:Npn \ShowInstance{\ShowCollectionInstance{}} +\cs_new_nopar:Npn \TP_templdecl_setup_fakeregister_key:NNn#1#2#3{ + \TP_templdecl_define_key:n{ + \tl_if_head_eq_meaning:nNTF{##1..}\DelayEvaluation + { + \toks_set:No \l_tmpa_toks {\use_ii:nn ##1} + \toks_put_right:Nx \l_TP_KV_assignments_toks { + \exp_not:n{#1#2}{\toks_use:N \l_tmpa_toks} + \exp_not:n{ \cs_set_nopar:Npx #3{\toks_use:N#2} } + + } + } + { + \tl_if_head_eq_meaning:nNTF{##1..}\MultiSelection + { + \group_begin: + \TP_multiselection_add:nnnnnn#1#2##1 + \group_end: + \toks_put_right:Nx\l_TP_KV_assignments_toks + {\exp_not:n{\cs_set_nopar:Npn #3} {\toks_use:N\g_TP_multiselection_toks}} + } + { + #1#2{##1} + \toks_put_right:Nx\l_TP_KV_assignments_toks + {\exp_not:n{\cs_set_nopar:Npn#3} {\toks_use:N#2}} + } + } + } +} +\toks_new:N \g_TP_multiselection_toks +\cs_new_nopar:Npn \TP_multiselection_add:nnnnnn #1#2#3#4#5#6{ + \toks_gset:Nn \g_TP_multiselection_toks {\if_case:w #4} + \clist_map_inline:nn {#5}{ + \tl_if_head_eq_meaning:nNTF{##1..}\DelayEvaluation + { + \TP_multiselection_add_or_case:n {##1} + } + { + #1#2{##1} + \TP_multiselection_add_or_case:o { \toks_use:N #2 } + } + } + \toks_gput_right:Nn \g_TP_multiselection_toks { + \else: \use_i_after_fi:nw{#6}\fi: + } +} +\cs_new_nopar:Npn \TP_multiselection_add_or_case:n #1 { + \toks_gput_right:Nn \g_TP_multiselection_toks { + \or: \use_i_after_orelse:nw{#1} + } +} +\cs_generate_variant:Nn \TP_multiselection_add_or_case:n {o} +\cs_new_nopar:Npn \IfExistsInstanceTF#1#2{ + \cs_if_exist:cTF{<>#1/#2} +} +\cs_set_nopar:Npn \IfExistsInstanceTF#1#2{ + \TP_let_instance:Nnn \l_tmpa_tl {#1}{#2} + \if_meaning:w\l_tmpa_tl\scan_stop: + \exp_after:wN\use_ii:nn + \else: + \exp_after:wN\use_i:nn + \fi:} +\cs_new_nopar:Npn \DeclareRestrictedTemplate#1#2#3#4{ + % CCC do we need a group here?? + \tl_set_eq:cc { TPD>/#1/#2 } { TPD>/#1/#3 } + \tl_set_eq:cc { TP>/#1/#2 } { TP>/#1/#3 } + \toks_set:Nv \l_TP_KV_assignments_toks { TPR>/ #1 / #3 } + \setkeys {\cs:w TPO>/#1/#3\cs_end:}{#4} + + \tl_set:cx { TPR>/#1/#2 } + { \toks_use:N \l_TP_KV_assignments_toks } + \cs_if_free:cTF { TPO>/#1/#3 } + { \tl_set:cn {TPO>/#1/#2}{#1/#3} } + { \tl_set_eq:cc {TPO>/#1/#2}{TPO>/#1/#3} } +} +\cs_new_nopar:Npn \TP_instdecl_generate_assignments:nn#1#2 { + % Returns to \l_TP_KV_assignments_toks + % the restrictions + % stored in the TP-structure (at present + % in YAM) of the template #1 + \exp_args:NNo \toks_set:No \l_TP_default_assignments_toks + {\cs:w TPD>/#1\cs_end:\scan_stop:\scan_stop:} + \toks_set:Nv \l_TP_KV_assignments_toks { TPR>/ #1 } + \setkeys { \cs:w TPO>/#1 \cs_end: } + { #2 } % adds stuff to \l_TP_KV_assignments_toks + + \exp_after:wN\TP_instdecl_add_default_recurse:nn + \toks_use:N\l_TP_default_assignments_toks + +} +\cs_new_nopar:Npn \TP_instdecl_add_default_recurse:nn#1#2{ + \token_if_eq_meaning:NNF #1\scan_stop: + { + \l_tmpa_toks{#2} + \tl_set:Nx \l_tmpa_tl { + {\toks_use:N \l_tmpa_toks \toks_use:N \l_TP_KV_assignments_toks} + } + \l_TP_KV_assignments_toks \l_tmpa_tl + \TP_instdecl_add_default_recurse:nn + } +} +\cs_new_nopar:Npn \TP_split_finite_skip_value:nnNN #1#2{ + \skip_split_finite_else_action:nnNN {#1} { + \PackageError{template}{Value~ for~ key~ #2~ contains~ `fil(ll)'} + {Only~ finite~ minus~ or~ plus~ parts~ are~ allowed~ for~ this~ key.} + } +} +\endinput +%% +%% End of file `template.sty'. diff --git a/Master/texmf-dist/tex/latex/xpackages/xbase/xparse.sty b/Master/texmf-dist/tex/latex/xpackages/xbase/xparse.sty new file mode 100644 index 00000000000..9bc5164a748 --- /dev/null +++ b/Master/texmf-dist/tex/latex/xpackages/xbase/xparse.sty @@ -0,0 +1,899 @@ +%% +%% This is file `xparse.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% xparse.dtx (with options: `package') +%% +%% (C) Copyright The LaTeX3 Project and any individual authors +%% listed elsewhere in this file. +%% +%% This is a generated file. +%% +%% This file was generated from file(s) of the xbase bundle. +%% --------------------------------------------------------- +%% +%% This file may only be distributed together with a copy of this bundle. +%% You may however distribute the bundle without such generated files. +%% +%% ====================================================================== +%% +%% File: xparse.dtx (C) Copyright 1999 Frank Mittelbach, Chris Rowley, +%% David Carlisle +%% (C) Copyright 2004-2008 Frank Mittelbach, +%% LaTeX3 Project +%% (C) Copyright 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 ``xbase 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: xparse.dtx 1497 2009-08-31 19:17:53Z joseph $ + {Generic document command parser} +\ProvidesExplPackage + {\filename}{\filedate}{\fileversion}{\filedescription} +\RequirePackage{expl3} +\prop_new:N \c_xparse_shorthands_prop +\prop_put:Nnn \c_xparse_shorthands_prop { o } { d[] } +\prop_put:Nnn \c_xparse_shorthands_prop { O } { D[] } +\prop_put:Nnn \c_xparse_shorthands_prop { s } { t* } +\toks_new:N \l_xparse_arg_toks +\toks_new:N \l_xparse_args_toks +\toks_new:N \l_xparse_environment_args_toks +\bool_new:N \l_xparse_error_bool +\tl_new:N \l_xparse_function_tl +\toks_new:N \l_xparse_last_arg_tl +\bool_new:N \l_xparse_long_bool +\int_new:N \l_xparse_m_args_int +\bool_new:N \l_xparse_m_only_bool +\int_new:N \l_xparse_mandatory_args_int +\bool_new:N \l_xparse_processor_bool +\int_new:N \l_xparse_processor_int +\toks_new:N \l_xparse_signature_toks +\tl_new:N \l_xparse_tmp_tl +\int_new:N \l_xparse_total_args_int +\quark_new:N \q_xparse_stop +\cs_new_nopar:Nn \xparse_add_grabber_mandatory:N { + \toks_put_right:Nx \l_xparse_signature_toks { + \exp_not:c { + xparse_grab_ #1 \bool_if:NT \l_xparse_long_bool { _long } :w + } + } + \bool_set_false:N \l_xparse_long_bool + \int_decr:N \l_xparse_mandatory_args_int +} +\cs_new_nopar:Nn \xparse_add_grabber_optional:N { + \toks_put_right:Nx \l_xparse_signature_toks { + \exp_not:c { + xparse_grab_ #1 + \bool_if:NT \l_xparse_long_bool { _long } + \intexpr_compare:nF { + \l_xparse_mandatory_args_int > \c_zero + } { _trailing } + :w + } + } + \bool_set_false:N \l_xparse_long_bool +} +\cs_new_nopar:cpn { xparse_add_type_+:w } { + \xparse_flush_m_args: + \bool_set_true:N \l_xparse_long_bool + \bool_set_false:N \l_xparse_m_only_bool + \int_decr:N \l_xparse_total_args_int + \xparse_prepare_signature:N +} +\cs_new:cpn { xparse_add_type_>:w } #1 { + \bool_set_true:N \l_xparse_processor_bool + \xparse_flush_m_args: + \int_decr:N \l_xparse_total_args_int + \toks_put_right:Nn \l_xparse_signature_toks { + \xparse_process_arg:n {#1} + } + \xparse_prepare_signature_aux:N +} +\cs_new:Npn \xparse_add_type_d:w #1#2 { + \xparse_add_type_D:w #1 #2 { \NoValue } +} +\cs_new:Npn \xparse_add_type_D:w #1#2#3 { + \xparse_flush_m_args: + \xparse_add_grabber_optional:N D + \toks_put_right:Nn \l_xparse_signature_toks { #1 #2 {#3} } + \xparse_prepare_signature:N +} +\cs_new_nopar:Npn \xparse_add_type_g:w { + \xparse_add_type_G:w { \NoValue } +} +\cs_new:Npn \xparse_add_type_G:w #1 { + \xparse_flush_m_args: + \xparse_add_grabber_optional:N G + \toks_put_right:Nn \l_xparse_signature_toks { {#1} } + \xparse_prepare_signature:N +} +\cs_new_nopar:Npn \xparse_add_type_l:w { + \xparse_flush_m_args: + \xparse_add_grabber_mandatory:N l + \xparse_prepare_signature:N +} +\cs_new_nopar:Npn \xparse_add_type_m:w { + \bool_if:nTF { + \l_xparse_long_bool || \l_xparse_processor_bool + } { + \xparse_flush_m_args: + \xparse_add_grabber_mandatory:N m + }{ + \int_incr:N \l_xparse_m_args_int + } + \xparse_prepare_signature:N +} +\cs_new:Npn \xparse_add_type_t:w #1 { + \xparse_flush_m_args: + \xparse_add_grabber_optional:N t + \toks_put_right:Nn \l_xparse_signature_toks { #1 } + \xparse_prepare_signature:N +} +\cs_new:Npn \xparse_add_type_u:w #1 { + \xparse_flush_m_args: + \xparse_add_grabber_mandatory:N u + \toks_put_right:Nn \l_xparse_signature_toks { {#1} } + \xparse_prepare_signature:N +} +\cs_new_nopar:Nn \xparse_check_and_add:N { + \cs_if_free:cTF { xparse_add_type_ #1 :w } { + \msg_error:nnx { xparse } { unknown-argument-type } {#1} + \xparse_add_type_m:w + }{ + \use:c { xparse_add_type_ #1 :w } + } +} +\cs_new:Nn \xparse_count_mandatory:n { + \int_zero:N \l_xparse_mandatory_args_int + \xparse_count_mandatory:N #1 \q_nil +} +\cs_new:Nn \xparse_count_mandatory:N { + \quark_if_nil:NF #1 { + \prop_if_in:NnTF \c_xparse_shorthands_prop {#1} { + \prop_get:NnN \c_xparse_shorthands_prop {#1} \l_xparse_tmp_tl + \exp_last_unbraced:NV \xparse_count_mandatory:N \l_xparse_tmp_tl + }{ + \xparse_count_mandatory_aux:N #1 + } + } +} +\cs_new:Nn \xparse_count_mandatory_aux:N { + \cs_if_free:cTF { xparse_count_type_ #1 :w } { + \xparse_count_type_m:w + }{ + \use:c { xparse_count_type_ #1 :w } + } +} +\cs_new:cpn { xparse_count_type_>:w } #1 { + \xparse_count_mandatory:N +} +\cs_new_nopar:cpn { xparse_count_type_+:w } { + \xparse_count_mandatory:N +} +\cs_new:Npn \xparse_count_type_d:w #1#2 { + \xparse_count_mandatory:N +} +\cs_new:Npn \xparse_count_type_D:w #1#2#3 { + \xparse_count_mandatory:N +} +\cs_new_nopar:Npn \xparse_count_type_g:w { + \xparse_count_mandatory:N +} +\cs_new:Npn \xparse_count_type_G:w #1 { + \xparse_count_mandatory:N +} +\cs_new_nopar:Npn \xparse_count_type_l:w { + \int_incr:N \l_xparse_mandatory_args_int + \xparse_count_mandatory:N +} +\cs_new_nopar:Npn \xparse_count_type_m:w { + \int_incr:N \l_xparse_mandatory_args_int + \xparse_count_mandatory:N +} +\cs_new:Npn \xparse_count_type_t:w #1 { + \xparse_count_mandatory:N +} +\cs_new:Npn \xparse_count_type_u:w #1 { + \int_incr:N \l_xparse_mandatory_args_int + \xparse_count_mandatory:N +} +\cs_new:Nn \xparse_declare_cmd:Nnn { + \xparse_count_mandatory:n {#2} + \xparse_prepare_signature:n {#2} + \bool_if:NTF \l_xparse_m_only_bool { + \xparse_declare_cmd_all_m:Nn #1 {#3} + }{ + \xparse_declare_cmd_mixed:Nn #1 {#3} + } +} +\cs_generate_variant:Nn \xparse_declare_cmd:Nnn { cnn } +\cs_new:Nn \xparse_declare_cmd_all_m:Nn { + \cs_generate_from_arg_count:NNnn + #1 \cs_set_protected_nopar:Npn \l_xparse_total_args_int {#2} +} +\cs_new:Nn \xparse_declare_cmd_mixed:Nn { + \cs_set_protected_nopar:Npx #1 { + \exp_not:n { + \int_zero:N \l_xparse_processor_int + \toks_set:Nn \l_xparse_args_toks + } { \exp_not:c { \token_to_str:N #1 } } + \toks_use:N \l_xparse_signature_toks + \exp_not:n{ \toks_use:N \l_xparse_args_toks } + } + \cs_generate_from_arg_count:cNnn + { \token_to_str:N #1 } \cs_set:Npn \l_xparse_total_args_int {#2} +} +\cs_new:Nn \xparse_declare_cmd_implementation:nNn { + \cs_generate_from_arg_count:cNnn { implementation_ #1 :w } + \cs_set:Npn {#2} {#3} +} +\cs_new:Nn \xparse_declare_cmd_interface:Nnn { + \xparse_prepare_signature:n {#3} + \bool_if:NTF \l_xparse_m_only_bool { + \xparse_declare_cmd_interface_all_m:Nn #1 {#2} + }{ + \xparse_declare_cmd_interface_mixed:Nn #1 {#2} + } + \cs_generate_from_arg_count:cNnn { implementation_ #2 :w } + \cs_set:Npn \l_xparse_total_args_int { ``#2'' } +} +\cs_new:Nn \xparse_declare_cmd_interface_all_m:Nn { + \cs_generate_from_arg_count:NNnn + #1 \cs_set_protected_nopar:Npn \l_xparse_total_args_int + { \use:c { implementation_ #2 :w } } +} +\cs_new:Nn \xparse_declare_cmd_interface_mixed:Nn { + \cs_set_protected_nopar:Npx #1 { + \exp_not:n { + \int_zero:N \l_xparse_processor_int + \toks_set:Nn \l_xparse_args_toks + } { \exp_not:c { \token_to_str:N #1 } } + \toks_use:N \l_xparse_signature_toks + \exp_not:n{ \toks_use:N \l_xparse_args_toks } + } + \cs_generate_from_arg_count:cNnn + { \token_to_str:N #1 } \cs_set:Npn \l_xparse_total_args_int + { \use:c { implementation_ #2 :w } } +} +\cs_new:Nn \xparse_declare_env:nnnn { + \xparse_declare_cmd:cnn { environment_begin_ #1 :w } {#2} { + \group_begin: + \toks_set_eq:NN \l_xparse_environment_args_toks + \l_xparse_args_toks + #3 + } + \cs_set_nopar:cpx { environment_end_ #1 :w } { + \exp_not:N \exp_last_unbraced:NV + \exp_not:c { environment_end_ #1 _aux:N } + \exp_not:N \l_xparse_environment_args_toks + \exp_not:N \group_end: + } + \cs_set_nopar:cx { environment_end_ #1 _aux:N } { + \exp_not:c { environment_end_ #1 _aux :w } + } + \cs_generate_from_arg_count:cNnn + { environment_end_ #1 _aux :w } \cs_set:Npn + \l_xparse_total_args_int {#4} + \cs_set_eq:cc {#1} { environment_begin_ #1 :w } + \cs_set_eq:cc { end #1 } { environment_end_ #1 :w } +} +\cs_new_nopar:Nn \xparse_flush_m_args: { + \cs_if_exist:cT { + xparse_grab_m_ \int_use:N \l_xparse_m_args_int :w + } { + \toks_put_right:Nx \l_xparse_signature_toks { + \exp_not:c { xparse_grab_m_ \int_use:N \l_xparse_m_args_int :w } + } + \int_set:Nn \l_xparse_mandatory_args_int { + \l_xparse_mandatory_args_int - \l_xparse_m_args_int + } + } + \int_zero:N \l_xparse_m_args_int + \bool_set_false:N \l_xparse_m_only_bool +} +\prg_new_conditional:Nnn \xparse_if_no_value:n { TF,T,F } { + \tl_if_eq:nnTF {#1} { \NoValue } { + \prg_return_true: + }{ + \prg_return_false: + } +} +\cs_new:Nn \xparse_prepare_signature:n { + \bool_set_false:N \l_xparse_long_bool + \int_zero:N \l_xparse_m_args_int + \bool_set_true:N \l_xparse_m_only_bool + \bool_set_false:N \l_xparse_processor_bool + \toks_clear:N \l_xparse_signature_toks + \int_zero:N \l_xparse_total_args_int + \xparse_prepare_signature:N #1 \q_nil +} +\cs_new:Nn \xparse_prepare_signature:N { + \bool_set_false:N \l_xparse_processor_bool + \xparse_prepare_signature_aux:N #1 +} +\cs_new:Nn \xparse_prepare_signature_aux:N { + \quark_if_nil:NTF #1 { + \bool_if:NF \l_xparse_m_only_bool { + \xparse_flush_m_args: + } + }{ + \prop_if_in:NnTF \c_xparse_shorthands_prop {#1} { + \prop_get:NnN \c_xparse_shorthands_prop {#1} \l_xparse_tmp_tl + \exp_last_unbraced:NV \xparse_prepare_signature:N \l_xparse_tmp_tl + }{ + \int_incr:N \l_xparse_total_args_int + \xparse_check_and_add:N #1 + } + } +} +\cs_new:Nn \xparse_process_arg:n { + \int_incr:N \l_xparse_processor_int + \cs_set:cn { + xparse_processor_ \int_use:N \l_xparse_processor_int :n + } + { #1 {##1} } +} +\cs_new:Nn \xparse_add_arg:n { + \intexpr_compare:nTF { \l_xparse_processor_int = \c_zero } { + \toks_put_right:Nn \l_xparse_args_toks { {#1} } + }{ + \xparse_if_no_value:nTF {#1} { + \int_zero:N \l_xparse_processor_int + \toks_put_right:Nn \l_xparse_args_toks { {#1} } + }{ + \xparse_add_arg_aux:n {#1} + } + } +} +\cs_new:Nn \xparse_add_arg_aux:n { + \use:c { xparse_processor_ \int_use:N \l_xparse_processor_int :n } + {#1} + \int_decr:N \l_xparse_processor_int + \intexpr_compare:nTF { \l_xparse_processor_int = \c_zero } { + \toks_put_right:No \l_xparse_args_toks { + \exp_after:wN { \toks_use:N \l_xparse_arg_toks } + } + }{ + \xparse_add_arg_aux:V \l_xparse_arg_toks + } +} +\cs_generate_variant:Nn \xparse_add_arg_aux:n { V } +\cs_new:Npn \xparse_grab_aux:w { } +\cs_new:Npn \xparse_grab_D:w #1#2#3#4 \l_xparse_args_toks { + \xparse_grab_D_aux:NNnnNn #1 #2 {#3} {#4} \cs_set_nopar:Npn + { _ignore_spaces } +} +\cs_new:Npn \xparse_grab_D_long:w #1#2#3#4 \l_xparse_args_toks { + \xparse_grab_D_aux:NNnnNn #1 #2 {#3} {#4} \cs_set:Npn + { _ignore_spaces } +} +\cs_new:Npn \xparse_grab_D_trailing:w #1#2#3#4 \l_xparse_args_toks { + \xparse_grab_D_aux:NNnnNn #1 #2 {#3} {#4} \cs_set_nopar:Npn { } +} +\cs_new:Npn \xparse_grab_D_long_trailing:w #1#2#3#4 + \l_xparse_args_toks { + \xparse_grab_D_aux:NNnnNn #1 #2 {#3} {#4} \cs_set:Npn { } +} +\cs_set:Nn \xparse_grab_D_aux:NNnnNn { + #5 \xparse_grab_arg:w #1 ##1 #2 { + \xparse_add_arg:n {##1} + #4 \l_xparse_args_toks + } + \use:c { peek_charcode #6 :NTF } #1 { + \xparse_grab_arg:w + }{ + \xparse_add_arg:n {#3} + #4 \l_xparse_args_toks + } +} +\cs_new:Npn \xparse_grab_G:w #1#2 \l_xparse_args_toks { + \xparse_grab_G_aux:nnNn {#1} {#2} \cs_set_nopar:Npn { _ignore_spaces } +} +\cs_new:Npn \xparse_grab_G_long:w #1#2 \l_xparse_args_toks { + \xparse_grab_G_aux:nnNn {#1} {#2} \cs_set:Npn { _ignore_spaces } +} +\cs_new:Npn \xparse_grab_G_trailing:w #1#2 \l_xparse_args_toks { + \xparse_grab_G_aux:nnNn {#1} {#2} \cs_set_nopar:Npn { } +} +\cs_new:Npn \xparse_grab_G_long_trailing:w #1#2 \l_xparse_args_toks { + \xparse_grab_G_aux:nnNn {#1} {#2} \cs_set:Npn { } +} +\cs_set:Nn \xparse_grab_G_aux:nnNn { + #3 \xparse_grab_arg:w ##1 { + \xparse_add_arg:n {##1} + #2 \l_xparse_args_toks + } + \use:c { peek_meaning #4 :NTF } \c_group_begin_token { + \xparse_grab_arg:w + }{ + \xparse_add_arg:n {#1} + #2 \l_xparse_args_toks + } +} +\cs_new:Npn \xparse_grab_l:w #1 \l_xparse_args_toks { + \xparse_grab_l_aux:nN {#1} \cs_set_nopar:Npn +} +\cs_new:Npn \xparse_grab_l_long:w #1 \l_xparse_args_toks { + \xparse_grab_l_aux:nN {#1} \cs_set:Npn +} +\cs_new:Nn \xparse_grab_l_aux:nN { + #2 \xparse_grab_arg:w ##1## { + \xparse_add_arg:n \l_xparse_args_toks {##1} + #1 \l_xparse_args_toks + } + \xparse_grab_arg:w +} +\cs_new:Npn \xparse_grab_m:w #1 \l_xparse_args_toks { + \cs_set_nopar:Npn \xparse_grab_arg:w ##1 { + \xparse_add_arg:n {##1} + #1 \l_xparse_args_toks + } + \xparse_grab_arg:w +} +\cs_new:Npn \xparse_grab_m_long:w #1 \l_xparse_args_toks { + \cs_set:Npn \xparse_grab_arg:w ##1 { + \xparse_add_arg:n {##1} + #1 \l_xparse_args_toks + } + \xparse_grab_arg:w +} +\cs_new:cpn { xparse_grab_m_1:w } #1 \l_xparse_args_toks { + \cs_set_nopar:Npn \xparse_grab_arg:w ##1 { + \toks_put_right:Nn \l_xparse_args_toks { {##1} } + #1 \l_xparse_args_toks + } + \xparse_grab_arg:w +} +\cs_new:cpn { xparse_grab_m_2:w } #1 \l_xparse_args_toks { + \cs_set_nopar:Npn \xparse_grab_arg:w ##1##2 { + \toks_put_right:Nn \l_xparse_args_toks { {##1} {##2} } + #1 \l_xparse_args_toks + } + \xparse_grab_arg:w +} +\cs_new:cpn { xparse_grab_m_3:w } #1 \l_xparse_args_toks { + \cs_set_nopar:Npn \xparse_grab_arg:w ##1##2##3 { + \toks_put_right:Nn \l_xparse_args_toks { {##1} {##2} {##3} } + #1 \l_xparse_args_toks + } + \xparse_grab_arg:w +} +\cs_new:cpn { xparse_grab_m_4:w } #1 \l_xparse_args_toks { + \cs_set_nopar:Npn \xparse_grab_arg:w ##1##2##3##4 { + \toks_put_right:Nn \l_xparse_args_toks { {##1} {##2} {##3} {##4} } + #1 \l_xparse_args_toks + } + \xparse_grab_arg:w +} +\cs_new:cpn { xparse_grab_m_5:w } #1 \l_xparse_args_toks { + \cs_set_nopar:Npn \xparse_grab_arg:w ##1##2##3##4##5 { + \toks_put_right:Nn \l_xparse_args_toks { + {##1} {##2} {##3} {##4} {##5} + } + #1 \l_xparse_args_toks + } + \xparse_grab_arg:w +} +\cs_new:cpn { xparse_grab_m_6:w } #1 \l_xparse_args_toks { + \cs_set_nopar:Npn \xparse_grab_arg:w ##1##2##3##4##5##6 { + \toks_put_right:Nn \l_xparse_args_toks { + {##1} {##2} {##3} {##4} {##5} {##6} + } + #1 \l_xparse_args_toks + } + \xparse_grab_arg:w +} +\cs_new:cpn { xparse_grab_m_7:w } #1 \l_xparse_args_toks { + \cs_set_nopar:Npn \xparse_grab_arg:w ##1##2##3##4##5##6##7 { + \toks_put_right:Nn \l_xparse_args_toks { + {##1} {##2} {##3} {##4} {##5} {##6} {##7} + } + #1 \l_xparse_args_toks + } + \xparse_grab_arg:w +} +\cs_new:cpn { xparse_grab_m_8:w } #1 \l_xparse_args_toks { + \cs_set_nopar:Npn \xparse_grab_arg:w ##1##2##3##4##5##6##7##8 { + \toks_put_right:Nn \l_xparse_args_toks { + {##1} {##2} {##3} {##4} {##5} {##6} {##7} {##8} + } + #1 \l_xparse_args_toks + } + \xparse_grab_arg:w +} +\cs_new:Npn \xparse_grab_t:w #1#2 \l_xparse_args_toks { + \xparse_grab_t_aux:NnNn #1 {#2} \cs_set_nopar:Npn { _ignore_spaces } +} +\cs_new:Npn \xparse_grab_t_long:w #1#2 \l_xparse_args_toks { + \xparse_grab_t_aux:NnNn #1 {#2} \cs_set:Npn { _ignore_spaces } +} +\cs_new:Npn \xparse_grab_t_trailing:w #1#2 \l_xparse_args_toks { + \xparse_grab_t_aux:NnNn #1 {#2} \cs_set_nopar:Npn { } +} +\cs_new:Npn \xparse_grab_t_long_trailing:w #1#2 \l_xparse_args_toks { + \xparse_grab_t_aux:NnNn #1 {#2} \cs_set:Npn { } +} +\cs_new:Nn \xparse_grab_t_aux:NnNn { + #3 \xparse_grab_arg:w { + \use:c { peek_charcode_remove #4 :NTF } #1 { + \xparse_add_arg:n { \BooleanTrue } + #2 \l_xparse_args_toks + }{ + \xparse_add_arg:n { \BooleanFalse } + #2 \l_xparse_args_toks + } + } + \xparse_grab_arg:w +} +\cs_new:Npn \xparse_grab_u:w #1#2 \l_xparse_args_toks { + \xparse_grab_u_aux:NnN {#1} {#2} \cs_set_nopar:Npn +} +\cs_new:Npn \xparse_grab_u_long:w #1#2 \l_xparse_args_toks { + \xparse_grab_u_aux:NnN {#1} {#2} \cs_set:Npn +} +\cs_new:Nn \xparse_grab_u_aux:NnN { + #3 \xparse_grab_arg:w ##1 #1 { + \xparse_add_arg:n {##1} + #2 \l_xparse_args_toks + } + \xparse_grab_arg:w +} +\cs_new:Nn \xparse_process_to_str:n { + \toks_set:Nx \l_xparse_arg_toks { + \tl_to_str:n {#1} + } +} +\cs_new:Nn \xparse_process_comma_split:n { + \tl_if_in:nnTF {#1} { , } { + \xparse_process_comma_split_aux:w #1 \q_stop + }{ + \toks_set:Nn \l_xparse_arg_toks { {#1} { \NoValue } } + } +} +\cs_new:Npn \xparse_process_comma_split_aux:w #1 , #2 \q_stop { + \toks_set:Nn \l_xparse_arg_toks { {#1} {#2} } +} +\cs_new:Npn \xparse_exp_add_type_d:w #1#2 { + \xparse_exp_add_type_D:w #1 #2 { \NoValue } +} +\cs_new:Npn \xparse_exp_add_type_D:w #1#2#3 { + \tl_set:Nx \l_xparse_tmpa_tl { + \exp_after:wN \token_to_str:N \l_xparse_function_tl + \int_use:N \l_xparse_total_args_int + } + \xparse_exp_set:cpx { \l_xparse_tmpa_tl } ##1 \q_xparse_stop ##2 { + \exp_not:N \tl_if_head_eq_charcode:nNTF {##2} #1 { + \exp_not:c { \l_xparse_tmpa_tl aux } + ##1 \exp_not:N \q_xparse_stop + }{ + \exp_not:c { \l_xparse_tmpa_tl aux } + ##1 \exp_not:N \q_xparse_stop #3 #2 {##2} + } + } + \xparse_exp_set:cpx { \l_xparse_tmpa_tl aux} + ##1 \q_xparse_stop ##2 #2 { + \exp_not:c { + \exp_after:wN \token_to_str:N \l_xparse_function_tl + \intexpr_eval:n { \l_xparse_total_args_int + 1 } + } ##1 {##2} \exp_not:N \q_xparse_stop + } + \xparse_exp_prepare_function:N +} +\cs_new_nopar:Npn \xparse_exp_add_type_l:w { + \xparse_exp_set:cpx { + \exp_after:wN \token_to_str:N \l_xparse_function_tl + \int_use:N \l_xparse_total_args_int + } ##1 \q_xparse_stop ##2## { + \exp_not:c { + \exp_after:wN \token_to_str:N \l_xparse_function_tl + \intexpr_eval:n { \l_xparse_total_args_int + 1 } + } + ##1 {##2} \exp_not:N \q_xparse_stop + } + \xparse_exp_prepare_function:N +} +\cs_new_nopar:Npn \xparse_exp_add_type_m:w { + \int_incr:N \l_xparse_m_args_int + \xparse_exp_set:cpx { + \exp_after:wN \token_to_str:N \l_xparse_function_tl + \int_use:N \l_xparse_total_args_int + } ##1 \q_xparse_stop ##2 { + \exp_not:c { + \exp_after:wN \token_to_str:N \l_xparse_function_tl + \intexpr_eval:n { \l_xparse_total_args_int + 1 } + } + ##1 {##2} \exp_not:N \q_xparse_stop + } + \xparse_exp_prepare_function:N +} +\cs_new:Npn \xparse_exp_add_type_t:w #1 { + \tl_set:Nx \l_xparse_tmpa_tl { + \exp_after:wN \token_to_str:N \l_xparse_function_tl + \intexpr_eval:n { \l_xparse_total_args_int + 1 } + } + \xparse_exp_set:cpx { + \exp_after:wN \token_to_str:N \l_xparse_function_tl + \int_use:N \l_xparse_total_args_int + } ##1 \q_xparse_stop ##2 { + \exp_not:N \tl_if_head_eq_charcode:nNTF {##2} #1 { + \exp_not:c { \l_xparse_tmpa_tl } + ##1 \exp_not:n { { \BooleanTrue } \q_xparse_stop } + }{ + \exp_not:c { \l_xparse_tmpa_tl } + ##1 \exp_not:n { { \BooleanFalse } \q_xparse_stop {##2} } + } + } + \xparse_exp_prepare_function:N +} +\cs_new:Npn \xparse_exp_add_type_u:w #1 { + \xparse_exp_set:cpx { + \exp_after:wN \token_to_str:N \l_xparse_function_tl + \int_use:N \l_xparse_total_args_int + } ##1 \q_xparse_stop ##2 #1 { + \exp_not:c { + \exp_after:wN \token_to_str:N \l_xparse_function_tl + \intexpr_eval:n { \l_xparse_total_args_int + 1 } + } + ##1 {##2} \exp_not:N \q_xparse_stop + } + \xparse_exp_prepare_function:N +} +\cs_new_nopar:Nn \xparse_exp_check_and_add:N { + \cs_if_free:cTF { xparse_exp_add_type_ #1 :w } { + \msg_error:nnx { xparse } { unknown-argument-type } {#1} + \tl_set:Nn \l_xparse_last_arg_tl { m } + \xparse_exp_add_type_m:w + }{ + \tl_set:Nn \l_xparse_last_arg_tl {#1} + \use:c { xparse_exp_add_type_ #1 :w } + } +} +\cs_new:Nn \xparse_exp_declare_cmd:Nnn { + \tl_set:Nn \l_xparse_function_tl {#1} + \xparse_exp_prepare_function:n {#2} + \intexpr_compare:nTF { + \l_xparse_total_args_int = \l_xparse_m_args_int + } { + \xparse_exp_declare_cmd_all_m:Nn #1 {#3} + }{ + \xparse_exp_declare_cmd_mixed:Nn #1 {#3} + } +} +\cs_new:Nn \xparse_exp_declare_cmd_all_m:Nn { + \bool_if:NTF \l_xparse_long_bool { + \cs_generate_from_arg_count:NNnn + #1 \cs_set:Npn \l_xparse_total_args_int {#2} + }{ + \cs_generate_from_arg_count:NNnn + #1 \cs_set_nopar:Npn \l_xparse_total_args_int {#2} + } +} +\cs_new:Nn \xparse_exp_declare_cmd_mixed:Nn { + \exp_args:NnV \tl_if_in:nnTF { l m u } \l_xparse_last_arg_tl { + \xparse_exp_declare_cmd_mixed_aux:Nn #1 {#2} + }{ + \msg_error:nn { xparse } { expandable-ending-optional } + } +} +\cs_new:Nn \xparse_exp_declare_cmd_mixed_aux:Nn { + \cs_set_nopar:Npx #1 { + \exp_not:c { \token_to_str:N #1 1 } x \exp_not:N \q_xparse_stop + } + \cs_set_nopar:cpx { + \token_to_str:N #1 \intexpr_eval:n { \l_xparse_total_args_int + 1 } + } x ##1 \q_xparse_stop { + \exp_not:c { \token_to_str:N #1 } ##1 + } + \cs_generate_from_arg_count:cNnn + { \token_to_str:N #1 } \cs_set:Npn \l_xparse_total_args_int {#2} +} +\cs_new:Nn \xparse_exp_prepare_function:n { + \bool_set_false:N \l_xparse_error_bool + \tl_if_in:nnT {#1} { > } { + \msg_error:nnx { xparse } { processor-in-expandable } {#1} + \bool_set_true:N \l_xparse_error_bool + } + \tl_if_in:nnT {#1} { g } { + \msg_error:nnx { xparse } { grouped-in-expandable } {#1} + \bool_set_true:N \l_xparse_error_bool + } + \tl_if_in:nnT {#1} { G } { + \msg_error:nnx { xparse } { grouped-in-expandable } {#1} + \bool_set_true:N \l_xparse_error_bool + } + \bool_if:NF \l_xparse_error_bool { + \xparse_exp_prepare_function_aux:n {#1} + } +} +\cs_new:Nn \xparse_exp_prepare_function_aux:n { + \cs_set_eq:NN \xparse_prepare_next:w \xparse_exp_prepare_function:N + \cs_set_eq:NN \xparse_exp_set:cpx \cs_set_nopar:cpx + \bool_set_false:N \l_xparse_long_bool + \int_zero:N \l_xparse_m_args_int + \int_zero:N \l_xparse_total_args_int + \tl_if_in:nnT {#1} { + } { + \bool_set_true:N \l_xparse_long_bool + \cs_set_eq:NN \xparse_exp_set:cpx \cs_set:cpx + } + \xparse_exp_prepare_function:N #1 \q_nil +} +\cs_new:Nn \xparse_exp_prepare_function:N { + \bool_if:NTF \l_xparse_long_bool { + \xparse_exp_prepare_function_long:N #1 + }{ + \xparse_exp_prepare_function_short:N #1 + } +} +\cs_new:Nn \xparse_exp_prepare_function_long:N { + \quark_if_nil:NF #1 { + \tl_if_eq:nnTF {#1} { + } { + \xparse_exp_prepare_function_short:N + }{ + \msg_error:nn { xparse } { inconsistent-long } + \xparse_exp_prepare_function_short:N #1 + } + + } +} +\cs_new:Nn \xparse_exp_prepare_function_short:N { + \quark_if_nil:NF #1 { + \prop_if_in:NnTF \c_xparse_shorthands_prop {#1} { + \prop_get:NnN \c_xparse_shorthands_prop {#1} \l_xparse_tmp_tl + \bool_if:NT \l_xparse_long_bool { + \tl_put_left:Nn \l_xparse_tmp_tl { + } + } + \exp_last_unbraced:NV \xparse_exp_prepare_function:N + \l_xparse_tmp_tl + }{ + \int_incr:N \l_xparse_total_args_int + \xparse_exp_check_and_add:N #1 + } + } +} +\cs_new_eq:NN \xparse_exp_set:cpx \cs_set_nopar:cpx +\msg_new:nnnn { xparse } { command-already-defined } {% + Command name `\token_to_str:N #1' already defined!% +}{% + You have used \token_to_str:N \NewDocumentCommand\\% + with a command that already has a definition.\\% + Perhaps you meant \token_to_str:N \RenewDocumentCommand.% +} +\msg_new:nnnn { xparse } { command-not-yet-defined } {% + Command `\token_to_str:N #1' not yet defined!% +}{% + You have used \token_to_str:N \RenewDocumentCommand\\% + with a command that was never defined.\\% + Perhaps you meant \token_to_str:N \NewDocumentCommand.% +} +\msg_new:nnn { xparse } { environment-already-defined } {% + Environment `#1' already defined!% +} +\msg_new:nnn { xparse } { environment-not-yet-defined } {% + Environment `#1' not yet defined!% +} +\msg_new:nnnn { xparse } { expandable-ending-optional } {% + Expandable command signature ends in optional argument.% +}{% + Expandable functions must have a final mandatory argument.% +} +\msg_new:nnnn { xparse } { grouped-in-expandable } {% + Optional grouped arguments cannot be used with expandable functions.% +}{% + Argument specification `#1' contains an optional grouped argument:\\% + this is only supported for standard robust functions.% +} +\msg_new:nnnn { xparse } { inconsistent-long } {% + Inconsistent long arguments.% +}{% + Expandable commands must have all arguments long if any at all.% +} +\msg_new:nnnn { xparse } { processor-in-expandable } {% + Argument processors cannot be used with expandable functions.% +}{% + Argument specification `#1' contains a processor function:\\% + this is only supported for standard robust functions.% +} +\msg_new:nnn { xparse } { unknown-argument-type } {% + Unknown argument type `#1' replaced by `m'. Fingers crossed ...% +} +\cs_new_eq:NN \BooleanFalse \c_false_bool +\cs_new_eq:NN \BooleanTrue \c_true_bool +\xparse_declare_cmd:Nnn \DeclareDocumentCommand { +m +m +m } { + \xparse_declare_cmd:Nnn #1 {#2} {#3} +} +\DeclareDocumentCommand \NewDocumentCommand { +m +m +m } { + \cs_if_exist:NTF #1 { + \msg_error:nnx { xparse } { command-already-defined } {#1} + }{ + \xparse_declare_cmd:Nnn #1 {#2} {#3} + } +} +\NewDocumentCommand \RenewDocumentCommand { +m +m +m } { + \cs_if_exist:NTF #1 { + \xparse_declare_cmd:Nnn #1 {#2} {#3} + }{ + \msg_error:nnx { xparse } { command-not-yet-defined } {#1} + } +} +\NewDocumentCommand \ProvideDocumentCommand { +m +m +m } { + \cs_if_exist:NF #1 { + \xparse_declare_cmd:Nnn #1 {#2} {#3} + } +} +\NewDocumentCommand \DeclareDocumentCommandImplementation { m m +m } { + \xparse_declare_cmd_implementation:nNn {#1} #2 {#3} +} +\NewDocumentCommand \DeclareDocumentCommandInterface { m m +m } { + \xparse_declare_cmd_interface:Nnn #1 {#2} {#3} +} +\NewDocumentCommand \DeclareDocumentEnvironment { m +m +m +m } { + \xparse_declare_env:nnnn {#1} {#2} {#3} {#4} +} +\NewDocumentCommand \NewDocumentEnvironment { m +m +m +m } { + \cs_if_exist:cTF { environment_begin_ #1 :w } { + \msg_error:nnx { xparse } { environment-already-defined } {#1} + }{ + \xparse_declare_env:nnnn {#1} {#2} {#3} {#4} + } +} +\NewDocumentCommand \RenewDocumentEnvironment { m +m +m +m } { + \cs_if_exist:cTF { environment_begin_ #1 :w } { + \xparse_declare_env:nnnn {#1} {#2} {#3} {#4} + }{ + \msg_error:nnx { xparse } { environment-not-yet-defined } {#1} + } +} +\NewDocumentCommand \ProvideDocumentEnvironment { m +m +m +m } { + \cs_if_exist:cF { environment_begin_ #1 :w } { + \xparse_declare_env:nnnn {#1} {#2} {#3} {#4} + } +} +\NewDocumentCommand \DeclareExpandableDocumentCommand { +m +m +m } { + \xparse_exp_declare_cmd:Nnn #1 {#2} {#3} +} +\cs_new_eq:NN \IfBooleanTF \bool_if:NTF +\cs_new_eq:NN \IfBooleanT \bool_if:NT +\cs_new_eq:NN \IfBooleanF \bool_if:NF +\cs_new_eq:NN \IfNoValueF \xparse_if_no_value:nF +\cs_new_eq:NN \IfNoValueT \xparse_if_no_value:nT +\cs_new_eq:NN \IfNoValueTF \xparse_if_no_value:nTF +\cs_set:Npn \IfValueF { \xparse_if_no_value:nT } +\cs_set:Npn \IfValueT { \xparse_if_no_value:nF } +\cs_set:Npn \IfValueTF #1#2#3 { + \xparse_if_no_value:nTF {#1} {#3} {#2} +} +\NewDocumentCommand \NoValue { } { -NoValue- } +\endinput +%% +%% End of file `xparse.sty'. diff --git a/Master/texmf-dist/tex/latex/xpackages/xparse.sty b/Master/texmf-dist/tex/latex/xpackages/xparse.sty deleted file mode 100644 index b268d7b0957..00000000000 --- a/Master/texmf-dist/tex/latex/xpackages/xparse.sty +++ /dev/null @@ -1,563 +0,0 @@ -%% -%% This is file `xparse.sty', -%% generated with the docstrip utility. -%% -%% The original source files were: -%% -%% xparse.dtx (with options: `package') -%% -%% (C) Copyright The LaTeX3 Project and any individual authors -%% listed elsewhere in this file. -%% -%% This is a generated file. -%% -%% This file was generated from file(s) of the xbase bundle. -%% --------------------------------------------------------- -%% -%% This file may only be distributed together with a copy of this bundle. -%% You may however distribute the bundle without such generated files. -%% -%% ====================================================================== -%% -%% File: xparse.dtx (C) Copyright 1999 Frank Mittelbach, Chris Rowley, David Carlisle -%% (C) Copyright 2004-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 -%% 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 ``xbase 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{expl3} -\GetIdInfo$Id: xparse.dtx 1365 2009-05-31 17:26:17Z mittelba $ - {generic document command parser} -\ProvidesExplPackage - {\filename}{\filedate}{\fileversion}{\filedescription} -\RequirePackage{expl3} -\cs_new_nopar:Nn \xparse_already_defined_error_msg:N { - \xparse_error:x { - Command~name~`\token_to_str:N #1'~ already~defined! - } -} -\cs_new_nopar:Nn \xparse_not_yet_defined_error_msg:N { - \xparse_error:x { - Command~`\token_to_str:N #1'~ not~ yet~defined! - } -} -\cs_new_nopar:Nn \xparse_begins_with_end_error_msg:N { - \xparse_error:x { - Command~`\token_to_str:N #1'~begins~with~ - `\token_to_str:N \end'! - } -} -\cs_new_nopar:Nn \xparse_unknown_arg_type_error_msg:N { - \xparse_error:x { - Unknown~ argument~ type~ `#1'~ - I'll~ substitute~ it~ with~ `m'~ for~ now.~ Fingers~ crossed... - } -} -\cs_new_nopar:Nn \xparse_no_command_implementation_warning:n { - \xparse_warning:x {No~ implementation~ for~ `#1'~ defined} -} -\cs_new_nopar:Nn \xparse_error:x {\tex_errmessage:D {xparse~error:~#1}} -\cs_new_nopar:Nn \xparse_warning:x {\iow_term:x{xparse~warning:~#1}} -\cs_new_nopar:Npn \xparse_if_definable:NTF #1 { - \cs_if_free:NTF #1 - { - \xparse_begins_with_end:NTF #1 - { \xparse_begins_with_end_error_msg:N #1 \use_ii:nn } - \use_i:nn - } - { \xparse_already_defined_error_msg:N #1 \use_ii:nn } -} -\cs_generate_variant:Nn \xparse_if_definable:NTF {c} -\cs_new_nopar:Npn \xparse_if_redefinable:NTF #1 { - \cs_if_free:NTF #1 - { \xparse_not_yet_defined_error_msg:N #1 \use_ii:nn } - { - \xparse_begins_with_end:NTF #1 - { \xparse_begins_with_end_error_msg:N #1 \use_ii:nn } - \use_i:nn - } -} -\cs_generate_variant:Nn \xparse_if_redefinable:NTF {c} -\cs_new_nopar:Npn \xparse_begins_with_end:NTF #1 { - \group_begin: - \exp_args:Nc \xparse_begins_with_end_aux:N { - \tl_head_iii:f { \cs_to_str:N #1 ??} - } -} -\cs_new_nopar:Nn \xparse_begins_with_end_aux:N { - \if_predicate:w \cs_if_eq_name_p:NN #1 \end - \group_end: - \exp_after:wN \use_i:nn - \else: - \group_end: - \exp_after:wN \use_ii:nn - \fi: -} -\toks_new:N \l_xparse_grabbed_args_toks -\toks_new:N \l_xparse_end_environment_args_toks -\int_new:N \l_xparse_mandatory_args_int -\int_new:N \l_xparse_total_args_int -\cs_set:Nn \xparse_declare_document_command:Nnn { - \xparse_prepare_signature:n {#2} - \cs_set_protected_nopar:Npx #1 { - \exp_not:n { \toks_set:Nn \l_xparse_grabbed_args_toks } - {\exp_not:c {\token_to_str:N #1}} - \toks_use:N \l_xparse_grabbed_args_toks - \exp_not:n{ \toks_use:N \l_xparse_grabbed_args_toks} - } - \cs_generate_from_arg_count:cNnn {\token_to_str:N #1}\cs_set:Npn - \l_xparse_total_args_int{#3} -} -\cs_generate_variant:Nn \xparse_declare_document_command:Nnn {cnn} -\cs_new:Nn \xparse_declare_document_environment:nnnn { - \xparse_declare_document_command:cnn {#1}{#2} - { \group_begin: - \toks_set_eq:NN \l_xparse_end_environment_args_toks - \l_xparse_grabbed_args_toks - #3 - } - \cs_set_eq:cN {end #1} \xparse_parsed_end_environment: - \cs_generate_from_arg_count:cNnn {end \token_to_str:N \\ #1}\cs_set:Npn - \l_xparse_total_args_int{#4} -} -\cs_new_protected_nopar:Nn \xparse_parsed_end_environment: { - \exp_after:wN \xparse_parsed_end_environment_aux:N - \toks_use:N \l_xparse_end_environment_args_toks - \group_end: -} -\cs_new_nopar:Nn \xparse_parsed_end_environment_aux:N { - \use:c {end \token_to_str:N #1 } -} -\cs_new_eq:NN \DeclareDocumentCommand \xparse_declare_document_command:Nnn -\cs_new_nopar:Npn \NewDocumentCommand #1 { - \xparse_if_definable:NTF #1 - { \xparse_declare_document_command:Nnn #1 } - \use_none:nn -} -\cs_new_nopar:Npn \RenewDocumentCommand #1 { - \xparse_if_redefinable:NTF #1 - { \xparse_declare_document_command:Nnn #1 } - \use_none:nn -} -\cs_new_eq:NN \DeclareDocumentEnvironment - \xparse_declare_document_environment:nnnn -\cs_new_nopar:Npn \NewDocumentEnvironment #1 { - \xparse_if_definable:cTF {#1} - { \xparse_declare_document_environment:nnnn {#1} } - \use_none:nnn -} -\cs_new_nopar:Npn \RenewDocumentEnvironment #1 { - \xparse_if_redefinable:cTF {#1} - { \xparse_declare_document_environment:nnnn {#1} } - \use_none:nnn -} -\cs_new_nopar:Npn \ProvideDocumentCommand #1{ - \cs_if_free:NTF #1 - { \DeclareDocumentCommand #1} - \use_none:nn -} -\cs_new_nopar:Npn \ProvideDocumentEnvironment #1{ - \cs_if_free:cTF {#1} - { \DeclareDocumentEnvironment {#1} } - \use_none:nnn -} -\cs_new:Npn \DeclareDocumentCommandInterface #1#2#3{ - \xparse_prepare_signature:n {#3} - \cs_set_protected_nopar:Npx #1 { - \exp_not:n { \toks_set:Nn \l_xparse_grabbed_args_toks } - {\exp_not:c {impl-#2}} - \toks_use:N\l_xparse_grabbed_args_toks - \exp_not:n{ \toks_use:N \l_xparse_grabbed_args_toks} - } - \cs_generate_from_arg_count:cNnn {impl-#2} \cs_set:Npn - \l_xparse_total_args_int - {\xparse_undefined_command_implementation:n{#2}} -} -\cs_new_nopar:Nn \xparse_undefined_command_implementation:n { - ``#1'' - \xparse_no_command_implementation_warning:n {#1} -} -\cs_new:Npn \DeclareDocumentCommandImplementation #1#2#3{ - \cs_generate_from_arg_count:cNnn {impl-#1}\cs_set:Npn {#2}{#3} -} -\cs_new_nopar:Nn \xparse_prepare_signature:n { - \int_zero:N \l_xparse_total_args_int - \toks_clear:N \l_xparse_grabbed_args_toks - \int_zero:N \l_xparse_mandatory_args_int - \bool_gset_false:N \g_xparse_insert_marker_bool - \bool_gset_false:N \g_xparse_allow_par_bool - \tl_gset_eq:NN \g_xparse_ignore_marker_tl - \g_xparse_ignore_spaces_marker_tl - \xparse_parse_signature:n #1 \q_nil -} -\tl_new:Nn \g_xparse_ignore_marker_tl {} -\seq_new:N \g_xparse_ignore_marker_seq -\bool_new:N \g_xparse_insert_marker_bool -\cs_new_nopar:cpn {xparse_add_arg_type_>:} #1 - \xparse_read_arg_type_or_grab_default:n #2{ - \xparse_add_remaining_m_args: - \bool_gset_true:N \g_xparse_insert_marker_bool - \int_decr:N \l_xparse_total_args_int - \tl_map_inline:nn{#2}{ - \xparse_check_and_add_argument_type:N ##1 - } - \xparse_parse_signature:n -} -\cs_new_nopar:Nn \xparse_add_ignore_marker:Nnn { - \tl_new:cn {g_xparse #2 _marker_tl}{#3} - \seq_gpush:Nv \g_xparse_ignore_marker_seq {g_xparse #2 _marker_tl} - \cs_new_nopar:cpn {xparse_add_arg_type_#1:}{ - \tl_gset_eq:Nc \g_xparse_ignore_marker_tl {g_xparse #2 _marker_tl} - } -} -\xparse_add_ignore_marker:Nnn W{_ignore_nothing}{} -\xparse_add_ignore_marker:Nnn i{_ignore_spaces}{_ignore_spaces} -\xparse_add_ignore_marker:Nnn I{_ignore_pars}{_ignore_pars} -\cs_new_nopar:Nn \xparse_add_arg_type_P: { - \bool_gset_true:N \g_xparse_allow_par_bool -} -\bool_new:N \g_xparse_allow_par_bool -\cs_new_nopar:Nn \xparse_parse_signature:n { - \quark_if_nil:NTF #1 - { - \xparse_add_remaining_m_args: - } - { - \int_incr:N \l_xparse_total_args_int - \xparse_check_and_add_argument_type:N #1 - \bool_if:NT \g_xparse_insert_marker_bool - { - \bool_gset_false:N \g_xparse_insert_marker_bool - \bool_gset_false:N \g_xparse_allow_par_bool - \tl_gset_eq:NN \g_xparse_ignore_marker_tl - \g_xparse_ignore_spaces_marker_tl - } - \xparse_read_arg_type_or_grab_default:n - } -} -\cs_new_nopar:Nn \xparse_check_and_add_argument_type:N { - \cs_if_free:cTF {xparse_add_arg_type_#1:} - { \xparse_unknown_arg_type_error_msg:N #1 - \int_incr:N \l_xparse_mandatory_args_int - } - { \use:c {xparse_add_arg_type_#1:} } -} -\cs_new_eq:NN \xparse_read_arg_type_or_grab_default:n - \xparse_parse_signature:n -\cs_new_nopar:Nn \xparse_grab_default_arg:n { - \toks_put_right:Nn \l_xparse_grabbed_args_toks {{#1}} - \cs_set_eq:NN \xparse_read_arg_type_or_grab_default:n - \xparse_parse_signature:n - \xparse_parse_signature:n -} -\cs_new:Nn \xparse_grab_default_arg_allow_par:n { - \toks_put_right:Nn \l_xparse_grabbed_args_toks {{#1}} - \cs_set_eq:NN \xparse_read_arg_type_or_grab_default:n - \xparse_parse_signature:n - \xparse_parse_signature:n -} -\cs_new_nopar:Nn \xparse_add_arg_type_m: { - \bool_if:NTF \g_xparse_allow_par_bool - { - \toks_put_right:Nn \l_xparse_grabbed_args_toks {\xparse_allow_par_m:w} - } - { \int_incr:N \l_xparse_mandatory_args_int } -} -\cs_new_nopar:Nn \xparse_add_remaining_m_args: { - \intexpr_compare:nNnF \l_xparse_mandatory_args_int = \c_zero - { - \toks_put_right:Nx \l_xparse_grabbed_args_toks { - \exp_not:c{xparse_m - \int_use:N \l_xparse_mandatory_args_int - :w } - } - \int_zero:N \l_xparse_mandatory_args_int - } -} -\cs_new_nopar:cpn {xparse_m1:w} #1 \l_xparse_grabbed_args_toks#2{ - \toks_put_right:Nn \l_xparse_grabbed_args_toks{{#2}} - #1 \l_xparse_grabbed_args_toks -} -\cs_new_nopar:cpn {xparse_m2:w} #1 \l_xparse_grabbed_args_toks #2#3{ - \toks_put_right:Nn \l_xparse_grabbed_args_toks{{#2}{#3}} - #1 \l_xparse_grabbed_args_toks -} -\cs_new_nopar:cpn {xparse_m3:w} #1 \l_xparse_grabbed_args_toks #2#3#4{ - \toks_put_right:Nn \l_xparse_grabbed_args_toks{{#2}{#3}{#4}} - #1 \l_xparse_grabbed_args_toks -} -\cs_new_nopar:cpn {xparse_m4:w} #1 \l_xparse_grabbed_args_toks #2#3#4#5{ - \toks_put_right:Nn \l_xparse_grabbed_args_toks{{#2}{#3}{#4}{#5}} - #1 \l_xparse_grabbed_args_toks -} -\cs_new_nopar:cpn {xparse_m5:w} #1 \l_xparse_grabbed_args_toks #2#3#4#5#6{ - \toks_put_right:Nn \l_xparse_grabbed_args_toks{{#2}{#3}{#4}{#5}{#6}} - #1 \l_xparse_grabbed_args_toks -} -\cs_new_nopar:cpn {xparse_m6:w} #1 \l_xparse_grabbed_args_toks #2#3#4#5#6#7{ - \toks_put_right:Nn \l_xparse_grabbed_args_toks - {{#2}{#3}{#4}{#5}{#6}{#7}} - #1 \l_xparse_grabbed_args_toks -} -\cs_new_nopar:cpn {xparse_m7:w} #1 \l_xparse_grabbed_args_toks#2#3#4#5#6#7#8{ - \toks_put_right:Nn \l_xparse_grabbed_args_toks - {{#2}{#3}{#4}{#5}{#6}{#7}{#8}} - #1 \l_xparse_grabbed_args_toks -} -\cs_new_nopar:cpn {xparse_m8:w} #1\l_xparse_grabbed_args_toks - #2#3#4#5#6#7#8#9{ - \toks_put_right:Nn \l_xparse_grabbed_args_toks - {{#2}{#3}{#4}{#5}{#6}{#7}{#8}{#9}} - #1 \l_xparse_grabbed_args_toks -} -\cs_new_nopar:cpn {xparse_m9:w} \toks_use:N \l_xparse_grabbed_args_toks - #1#2#3#4#5#6#7#8#9{ - \toks_put_right:Nn \l_xparse_grabbed_args_toks - {{#1}{#2}{#3}{#4}{#5}{#6}{#7}{#8}{#9}} - \toks_use:N \l_xparse_grabbed_args_toks -} -\cs_new:Npn \xparse_allow_par_m:w #1 \l_xparse_grabbed_args_toks#2{ - \toks_put_right:Nn \l_xparse_grabbed_args_toks{{#2}} - #1 \l_xparse_grabbed_args_toks -} -\cs_new_nopar:Nn \xparse_add_arg_type_l: { - \xparse_add_remaining_m_args: - \bool_if:NTF \g_xparse_allow_par_bool - { - \toks_put_right:Nn \l_xparse_grabbed_args_toks {\xparse_allow_par_l:w} - } - { \toks_put_right:Nn \l_xparse_grabbed_args_toks {\xparse_l:w} } -} -\cs_new_nopar:Npn \xparse_l:w #1 \l_xparse_grabbed_args_toks#2#{ - \toks_put_right:Nn \l_xparse_grabbed_args_toks{{#2}} - #1 \l_xparse_grabbed_args_toks -} -\cs_new:Npn \xparse_allow_par_l:w #1 \l_xparse_grabbed_args_toks#2#{ - \toks_put_right:Nn \l_xparse_grabbed_args_toks{{#2}} - #1 \l_xparse_grabbed_args_toks -} -\cs_new_nopar:Npn \DeclareSymbolArgument #1#2{ - \seq_map_variable:NNn \g_xparse_ignore_marker_seq \l_tmpa_tl { - \cs_set_nopar:cpx {xparse \l_tmpa_tl _#1:w}##1##2 - \l_xparse_grabbed_args_toks{ - \exp_not:c{peek_ #2 _remove \l_tmpa_tl :NTF} ##1 - { - \exp_not:N \toks_put_right:Nn \exp_not:N - \l_xparse_grabbed_args_toks \exp_not:N \c_true_bool - ##2 \exp_not:N\l_xparse_grabbed_args_toks - } - { - \exp_not:N \toks_put_right:Nn \exp_not:N - \l_xparse_grabbed_args_toks \exp_not:N \c_false_bool - ##2 \exp_not:N\l_xparse_grabbed_args_toks - } - } - } - \cs_set_nopar:cpn {xparse_add_arg_type_#1:} { - \xparse_add_remaining_m_args: - \toks_put_right:Nx \l_xparse_grabbed_args_toks - { \exp_not:c {xparse \g_xparse_ignore_marker_tl _#1:w } } - \cs_set_eq:NN \xparse_read_arg_type_or_grab_default:n - \xparse_grab_default_arg:n - } -} -\DeclareSymbolArgument S{meaning} -\cs_new_nopar:Npn \DeclareArgumentType #1#2#3#4#5#6#7{ - \seq_map_variable:NNn \g_xparse_ignore_marker_seq \l_tmpa_tl { - \cs_set_nopar:cpx {xparse \l_tmpa_tl _#1:w}##1\l_xparse_grabbed_args_toks{ - \exp_not:c{peek_#3 \l_tmpa_tl :NTF} \exp_not:N #2 - { \exp_not:c{xparse_#1_#3_help:nw}{##1} } - { - \exp_not:n { - #4 \toks_put_right:Nn \l_xparse_grabbed_args_toks {#5} - } - ##1 \exp_not:N\l_xparse_grabbed_args_toks - } - } - \cs_set:cpx {xparse_allow_par \l_tmpa_tl _#1:w}##1 - \l_xparse_grabbed_args_toks{ - \exp_not:c{peek_#3 \l_tmpa_tl :NTF} \exp_not:N #2 - { \exp_not:c{xparse_allow_par_#1_#3_help:nw}{##1} } - { - \exp_not:n { - #4 \toks_put_right:Nn \l_xparse_grabbed_args_toks {#5} - } - ##1 \exp_not:N\l_xparse_grabbed_args_toks - } - } - } - \cs_set_nopar:cpn {xparse_add_arg_type_#1:} { - \xparse_add_remaining_m_args: - \toks_put_right:Nx \l_xparse_grabbed_args_toks { - \exp_not:c {xparse - \bool_if:NT \g_xparse_allow_par_bool {_allow_par} - \g_xparse_ignore_marker_tl - _#1:w - } - } - \cs_set_eq:NN \xparse_read_arg_type_or_grab_default:n \xparse_parse_signature:n - } - \xparse_define_helper:Nnnn #1{#3}{#6}{#7} -} -\cs_new_nopar:Npn \DeclareArgumentTypeDefaultValue #1#2#3#4#5{ - \seq_map_variable:NNn \g_xparse_ignore_marker_seq \l_tmpa_tl { - \cs_set_nopar:cpx {xparse \l_tmpa_tl _#1:w}##1##2\l_xparse_grabbed_args_toks{ - \exp_not:c{peek_#3 \l_tmpa_tl :NTF} \exp_not:N #2 - { \exp_not:c{xparse_#1_#3_help:nw}{##2} } - { - \exp_not:N \toks_put_right:Nn - \exp_not:N \l_xparse_grabbed_args_toks {{##1}} - ##2 \exp_not:N \l_xparse_grabbed_args_toks - } - } - \cs_set:cpx {xparse_allow_par \l_tmpa_tl _#1:w}##1##2 - \l_xparse_grabbed_args_toks{ - \exp_not:c{peek_#3 \l_tmpa_tl :NTF} \exp_not:N #2 - { \exp_not:c{xparse_allow_par_#1_#3_help:nw}{##2} } - { - \exp_not:N \toks_put_right:Nn - \exp_not:N \l_xparse_grabbed_args_toks {{##1}} - ##2 \exp_not:N \l_xparse_grabbed_args_toks - } - } - } - \cs_set_nopar:cpn {xparse_add_arg_type_#1:} { - \xparse_add_remaining_m_args: - \toks_put_right:Nx \l_xparse_grabbed_args_toks { - \exp_not:c {xparse - \bool_if:NT \g_xparse_allow_par_bool {_allow_par} - \g_xparse_ignore_marker_tl - _#1:w - } - } - \cs_set_eq:Nc \xparse_read_arg_type_or_grab_default:n - {xparse_grab_default_arg - \bool_if:NT \g_xparse_allow_par_bool {_allow_par} - :n - } - } - \xparse_define_helper:Nnnn #1{#3}{#4}{#5} -} -\cs_new_nopar:Nn \xparse_define_helper:Nnnn { - \toks_set:Nn \l_tmpa_toks - { - #3 - { - \toks_put_right:Nn \l_xparse_grabbed_args_toks {{#4}} - ##1 \l_xparse_grabbed_args_toks - } - } - \toks_set:Nx \l_tmpa_toks { - \exp_not:n {\cs_set_nopar:cpn{xparse_#1_#2_help:nw}} - \toks_use:N \l_tmpa_toks - \exp_not:n {\cs_set_nopar:cpn{xparse_allow_par_#1_#2_help:nw}} - \toks_use:N\l_tmpa_toks - } - \toks_use:N \l_tmpa_toks -} -\DeclareArgumentType o[{meaning}{}{\NoValue}{#1[#2]}{#2} -\DeclareArgumentType c({meaning}{ - \xparse_error:x{ - Missing~ coordinate~ argument.~ A~ value~ of~ (0,0)~ is~ assumed} - } - {{00}} - {#1(#2,#3)}{{#2}{#3}} -\DeclareArgumentTypeDefaultValue O[{meaning}{#1[#2]}{#2} -\DeclareArgumentTypeDefaultValue C({meaning}{#1(#2,#3)}{{#2}{#3}} -\cs_new_nopar:Npn \DeclareArgumentTypeShorthand #1#2{ - \cs_new_nopar:cpn {xparse_add_arg_type_#1:} - ##1 \xparse_read_arg_type_or_grab_default:n { - \int_decr:N \l_xparse_total_args_int - \xparse_read_arg_type_or_grab_default:n #2 - } -} -\DeclareArgumentTypeShorthand s {S{*}} -\cs_new_eq:NN \IfBooleanTF \bool_if:NTF -\cs_new_eq:NN \IfBooleanT \bool_if:NT -\cs_new_eq:NN \IfBooleanF \bool_if:NF -\tl_new:Nn \NoValue {-NoValue-} -\tl_new:Nn \c_xparse_hidden_no_value_tl {\NoValue} -\cs_new:Npn \xparse_if_no_value:nTF #1{ - \tl_set:Nx \l_tmpa_tl{\exp_not:n{#1}} - \tl_if_eq:NNTF \l_tmpa_tl \c_xparse_hidden_no_value_tl - { \use_i:nn } - { \tl_if_blank:nTF {#1} - { \use_ii:nn } - {\peek_after:NN \xparse_if_no_value_aux: #1 \q_nil {#1} } - } -} -\cs_new:Nn \xparse_if_no_value_aux: { - \tl_set:Nx \l_tmpa_tl{\token_get_arg_spec:N \l_peek_token } - \tl_if_empty:NTF \l_tmpa_tl - {\use_i_delimit_by_q_nil:nw {\exp_args:No\xparse_if_no_value:nTF}} - {\use_i_delimit_by_q_nil:nw {\use_iii:nnn}} -} -\cs_new_eq:NN \IfNoValueTF \xparse_if_no_value:nTF -\cs_new:Npn \IfNoValueT #1#2 {\xparse_if_no_value:nTF{#1}{#2}{}} -\cs_new:Npn \IfNoValueF #1 {\xparse_if_no_value:nTF {#1}{}} -\cs_new:Npn \IfValueTF #1#2#3{\xparse_if_no_value:nTF {#1}{#3}{#2}} -\cs_new_eq:NN \IfValueT \IfNoValueF -\cs_new_eq:NN \IfValueF \IfNoValueT -\tl_new:Nn \l_xparse_pseudo_post_arg_tl {} -\cs_new:Npn \DeclarePseudoArgument #1#2#3#4{ - \cs_set:cn {xparse_pseudo_pre_arg_#1:\prg_replicate:nn{#2}{n}} {#3} - \cs_set:cn {xparse_pseudo_post_arg_#1:\prg_replicate:nn{#2}{n}} {#4} - \cs_set_nopar:cn {xparse_pseudo_nobrace_arg_#1:N} { - ##1 \l_xparse_pseudo_post_arg_tl - } - \cs_generate_from_arg_count:cNnn {xparse_pseudo_arg_#1:w} - \cs_set:Npx {#2} - { - \exp_not:c { - xparse_pseudo_pre_arg_#1: \prg_replicate:nn{#2}{n} - } - \use:c{use_ \intexpr_eval:n{#2} _parameter:} - \exp_not:n {\tl_set:Nn \l_xparse_pseudo_post_arg_tl} - { - \exp_not:c {xparse_pseudo_post_arg_#1:\prg_replicate:nn{#2}{n}} - \use:c{use_ \intexpr_eval:n{#2}_parameter:} - } - \exp_not:n{ \peek_catcode_remove_ignore_spaces:NTF \c_group_begin_token } - { - \exp_not:n { - \c_group_begin_token - \group_execute_after:N \l_xparse_pseudo_post_arg_tl - } - } - { - \exp_not:c{xparse_pseudo_nobrace_arg_#1:N} - } - } -} -\cs_new_nopar:Npn \UsePseudoArgument #1{\use:c{xparse_pseudo_arg_#1:w}} -\endinput -%% -%% End of file `xparse.sty'. diff --git a/Master/texmf-dist/tex/latex/xpackages/xtras/l3keys2e.sty b/Master/texmf-dist/tex/latex/xpackages/xtras/l3keys2e.sty new file mode 100644 index 00000000000..67e67fe285a --- /dev/null +++ b/Master/texmf-dist/tex/latex/xpackages/xtras/l3keys2e.sty @@ -0,0 +1,117 @@ +%% +%% This is file `l3keys2e.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% l3keys2e.dtx (with options: `package') +%% ---------------------------------------------------------------- +%% l3keys2e --- Parsing LaTeX3 keyvals as LaTeX2e package options +%% Copyright 2009 The LaTeX3 Project +%% Released under the LaTeX Project Public License v1.3c or later +%% See http://www.latex-project.org/lppl.txt +%% ---------------------------------------------------------------- +%% File: l3keys2e.dtx (C) Copyright 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 ``l3keys2e'' (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: l3keys2e.dtx 1494 2009-08-24 11:05:44Z joseph $ + {Parsing LaTeX3 keyvals as LaTeX2e package options} +\ProvidesExplPackage + {\filename}{\filedate}{\fileversion}{\filedescription} +\RequirePackage{xparse} +\clist_new:N \keys_latexe_options_clist +\cs_new:Nn \keys_latexe_options:n { + \clist_clear:N \keys_latexe_options_clist + \keys_latexe_options_global:n {#1} + \keys_latexe_options_local: + \keys_if_exist:nnF {#1} { unknown } { + \keys_define:nn {#1} { + unknown .code:n = { + \msg_warning:nnxx { Option~Processing } { unknown-option } + { \l_keys_key_tl } { \@currname } + } + } + } + \keys_set:nV {#1} \keys_latexe_options_clist + \AtEndOfPackage { \cs_set_eq:NN \@unprocessedoptions \scan_stop: } +} +\msg_new:nnn { Option~Processing } { unknown-option } {% + Unknown~option~`#1'\\% + for~module~#2.% +} +\cs_new:Nn \keys_latexe_options_global:n { + \cs_if_eq:NNF \@classoptionslist \scan_stop: { + \cs_if_eq:NNTF \@currext \@clsextension { + \keys_latexe_options_class:n {#1} + }{ + \keys_latexe_options_package:n {#1} + } + } +} +\cs_new:Nn \keys_latexe_options_class:n { + \clist_map_inline:Nn \@classoptionslist { + \keys_if_exist:nnTF {#1} { \keys_latexe_remove_equals:n {##1} } { + \clist_put_right:Nn \keys_latexe_options_clist {##1} + }{ + \clist_put_right:Nn \@unusedoptionlist {##1} + } + } +} +\cs_new:Nn \keys_latexe_options_package:n { + \clist_map_inline:Nn \@classoptionslist { + \keys_if_exist:nnT {#1} { \keys_latexe_remove_equals:n {##1} } { + \clist_put_right:Nn \keys_latexe_options_clist {##1} + \clist_remove_element:Nn \@unusedoptionlist {##1} + } + } +} +\cs_new_nopar:Nn \keys_latexe_options_local: { + \cs_if_eq:NNF \@currext \@clsextension { + \cs_if_exist:cT { opt@ \@currname . \@currext } { + \exp_args:NNc \clist_put_right:NV \keys_latexe_options_clist + { opt@ \@currname . \@currext } + } + } +} +\cs_new:Nn \keys_latexe_remove_equals:n { + \keys_latexe_remove_equals:w #1 = \q_stop +} +\cs_new:Npn \keys_latexe_remove_equals:w #1 = #2 \q_stop {#1} +\NewDocumentCommand \ProcessKeysOptions { m } { + \keys_latexe_options:n {#1} +} +\@onlypreamble \ProcessKeysOptions +\endinput +%% +%% End of file `l3keys2e.sty'. -- cgit v1.2.3