diff options
author | Karl Berry <karl@freefriends.org> | 2009-07-19 18:13:59 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2009-07-19 18:13:59 +0000 |
commit | 97ea53ff09cc961846648bbba9f2acc716cf8015 (patch) | |
tree | 5526f85cb061b27e8b31dad6fc45889cddb6ec70 /Master/texmf-dist/source/latex/etextools | |
parent | a242529bcf517df9bcf227f4636fd56c5072ecf7 (diff) |
new package etextools (16jul09)
git-svn-id: svn://tug.org/texlive/trunk@14320 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex/etextools')
-rw-r--r-- | Master/texmf-dist/source/latex/etextools/etextools.dtx | 836 | ||||
-rw-r--r-- | Master/texmf-dist/source/latex/etextools/etextools.ins | 77 |
2 files changed, 913 insertions, 0 deletions
diff --git a/Master/texmf-dist/source/latex/etextools/etextools.dtx b/Master/texmf-dist/source/latex/etextools/etextools.dtx new file mode 100644 index 00000000000..921614fbe9a --- /dev/null +++ b/Master/texmf-dist/source/latex/etextools/etextools.dtx @@ -0,0 +1,836 @@ +% \iffalse meta-comment +%%% etextools : more e-TeX useful tools for LaTeX package writers +%%% Florent CHERVET +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either +% version 1.3 of this license or (at your option) any later +% version. The latest version of this license is in +% http://www.latex-project.org/lppl.txt +% +% This work consists of the main source file etextools.dtx +% and the derived files +% etextools.sty, etextools.pdf, etextools.ins, +% Unpacking: +% (a) If etextools.ins is present: +% etex etextools.ins +% (b) Without etextools.ins: +% etex etextools.dtx +% (c) If you insist on using LaTeX +% latex \let\install=y\input{etextools.dtx} +% (quote the arguments according to the demands of your shell) +% +% Documentation: +% (pdf)latex etextools.dtx; ... +% +%<*ignore> +\begingroup + \def\x{LaTeX2e}% +\expandafter\endgroup +\ifcase 0\ifx\install y1\fi\expandafter + \ifx\csname processbatchFile\endcsname\relax\else1\fi + \ifx\fmtname\x\else 1\fi\relax +\else\csname fi\endcsname +%</ignore> +%<*install> +\input docstrip.tex +\Msg{************************************************************************} +\Msg{* Installation} +\Msg{* Package: etextools 2009/07/14 v2e e-TeX more useful tools for LaTeX package writers} +\Msg{************************************************************************} + +\keepsilent +\askforoverwritefalse + +\let\MetaPrefix\relax +\preamble + +This is a generated file. + +Copyright (C) 2009 by Florent Chervet <florent.chervet@free.fr> + +This work may be distributed and/or modified under the +conditions of the LaTeX Project Public License, either +version 1.3 of this license or (at your option) any later +version. The latest version of this license is in + http://www.latex-project.org/lppl.txt + +This work consists of the main source file etextools.dtx +and the derived files + etextools.sty, etextools.pdf, etextools.ins, + +\endpreamble +\let\MetaPrefix\DoubleperCent + +\generate{% + \file{etextools.ins}{\from{etextools.dtx}{install}}% + \file{etextools.sty}{\from{etextools.dtx}{package}}% +} + +\obeyspaces +\Msg{************************************************************************} +\Msg{*} +\Msg{* To finish the installation you have to move the following} +\Msg{* file into a directory searched by TeX:} +\Msg{*} +\Msg{* etextools.sty} +\Msg{*} +\Msg{* To produce the documentation run the file `etextools.drv'} +\Msg{* through LaTeX.} +\Msg{*} +\Msg{* Happy TeXing!} +\Msg{*} +\Msg{************************************************************************} + +\endbatchfile +%</install> +%<*ignore> +\fi +%</ignore> +%<*driver> +\documentclass[a4paper,oneside]{ltxdockit} +\usepackage[latin9]{inputenc} +\usepackage[american]{babel} +\usepackage{doc,stmaryrd,amsmath,graphics,geometry,fancyhdr,framed,bbding,trace}\CodelineNumbered +\lastlinefit999 +\font\ding=dingbat scaled 800 +\geometry{totalheight=26cm,marginparwidth=14pt} +\fancyhf{}\fancyhead[L]{The \sty{etextools} package -- an \eTeX\, package for \LaTeX\,} +\fancyfoot[L]{\color[gray]{.35}\scriptsize\sty{etextools}\quad\copyright\,\lower.3ex\hbox{\NibRight}\,Florent Chervet} +\fancyfoot[R]{\oldstylenums{\thepage} / \oldstylenums{\pageref{LastPage}}} +\pagestyle{fancy} +\definecolor{spot}{rgb}{.7,0.1,0.2} +\newcommand\fecccolor{\color{fecc}}\definecolor{fecc}{rgb}{.2,.6,.2} +\newcommand\macrocodecolor{\color{macrocode}}\definecolor{macrocode}{rgb}{0.18,0.00,0.45} +\newcommand\reflinkcolor{\color{reflink}}\definecolor{reflink}{rgb}{.3,0,0} +\newcommand\rmklinkcolor{\color{rmklink}}\definecolor{rmklink}{rgb}{.2,.2,.2} +\newcommand\rmkcolor{\color{rmk}\let\reflinkcolor\rmklinkcolor}\definecolor{rmk}{gray}{.35} +\newcommand\rmk{\par\nobreak\footnotesize\rmkcolor} +\definecolor{shadecolor}{rgb}{0.93,0.94,0.81} +\renewcommand\ltxsyntaxlabelfont{\spotcolor \displayverbfont\bfseries} +\newcommand\eol{\textcolor[gray]{.5}{$\hookleftarrow$}} +\MakeShortVerb{\|} +\catcode`\§\active\def§{\par\nobreak\vskip-\parskip} +\renewcommand\partformat{}\let\thepart\partformat\renewcommand\raggedpart{\centering} +\newcommand\cmdref[1]{\hyperref[#1]{\underline{\sty{\reflinkcolor\textbackslash #1}}}} +\newcommand\cmdlabel[1]{\label{#1}} +\makeatletter +\AtBeginDocument{\g@addto@macro\macro@font{\macrocodecolor\let\AltMacroFont\macro@font}} +\def\FE{\setbox8\hbox{$\m@th\bindnasrepma$}% + \marginpar{\fecccolor\scalebox{2}{$\copy8\mkern-13.5mu\copy8\mkern-13.5mu\copy8$}}\space} +\def\smex{\leavevmode\hb@xt@2em{\hfil\spotcolor$\longrightarrow$\hfil}} +\parindent\z@\topsep\z@\partopsep\z@\parskip.3\baselineskip +\makeatother +\font\manual=manfnt\def\dbend{\marginpar{\manual\char127}\space} +\titlepage{% + title={The \sty{etextools} package}, + subtitle={An \etex package providing useful tools for LaTeX Users \\ and package Writers}, + url={http://www.ctan.org/tex-archive/macros/latex/contrib/etextools/}, + author={Florent CHERVET}, + email={florent.chervet@free.fr}, + revision={2\:$\boldsymbol{\varepsilon}$}, + date={14 July 2009}} +\hypersetup{% + pdftitle={The etextools package}, + pdfsubject={An e-TeX package for more useful tools for LaTeX package writers}, + pdfauthor={Florent CHERVET}, + colorlinks,linkcolor=reflink, + pdfkeywords={tex, e-tex, latex, package, programming}, + bookmarksopen=true,bookmarksopenlevel=2} +\begin{document} + \DocInput{etextools.dtx} +\end{document} +%</driver> +% \fi +% +% \thispagestyle{plain}\printtitlepage +% \fontfamily{ua1}\selectfont +% \tableofcontents\vfil +% +% \begin{shaded}\parindent0pt\noindent\large +% +% {\bfseries\catcode`\ \active\let =\,\hfil \* A b s t r a c t \*\hfil}\par +% +% The \sty{etextools} package is based on the \sty{etex} and \sty{etoolbox} +% packages and defines more tools for \LaTeX\ Users or package Writers. +% Before using this package, it is highly recommended to read the +% documentation (of this package and...) of the \sty{etoolbox} package. +% +% This package requires the \sty{etex} package from David Carlisle +% and the \sty{etoolbox} package from Philipp Lehman. Both of them +% are available on CTAN under the \sty{/latex/contrib/} directory \footnotemark. +% +% The main contributions of this package are : +% \begin{itemize} +% \item the \cmdref{expandnext} macro; +% \item the ability to define fully expandable macros with parameter and/or star version (with a small restriction) +% -- see \cmdref{FE@testopt}, \cmdref{FE@ifstar}; +% \item a Command-List Parser constructor that fully uses this new feature : command-list parser are fully expandable +% -- see \cmdref{csvloop} and \cmdref{listloop}; +% \item three macros that are lacking from the \sty{etoolbox} package for removing elements from lists : +% \cmdref{listdel} and \cmdref{listgdel}, \cmdref{listxdel}. +% \end{itemize} +% +% \end{shaded} +% +% \footnotetext{This documentation is produced with the \sty{ltxdockit} +% classe and package by Philipp Lehman using the |DocStrip| utility. +% \begin{tabbing} +% \qquad\=\smex\=To get the documentation, \= run (twice):\quad\= \sty{pdflatex etextools.dtx} \\ +% \>\smex\>To get the package, \> run:\> \sty{etex etextools.dtx} +% \end{tabbing}} +% +% \vfil\eject +% +% \section{Introduction} +% +% \subsection{Identification} +% +% \begin{macrocode} +%<*package> +\NeedsTeXFormat{LaTeX2e}[1996/12/01] +\ProvidesPackage{etextools} + [2009/07/14 v2e e-TeX more useful tools for LaTeX package writers] +\csname ettl@onlyonce\endcsname\let\ettl@onlyonce\endinput +% \end{macrocode} +% +% \subsection{Requirements} +% +% This package requires both the \sty{etex} package by David Carlisle and +% the \sty{etoolbox} package by Philipp Lehman. +% +% \begin{macrocode} +\RequirePackage{etex,etoolbox} +% \end{macrocode} +% +% Furthermore, the space token must have its natural catcode (10) all along this package. +% +% \begin{macrocode} +\edef\ettl@restore@space@catcode{\catcode`\ =\the\catcode`\ } +\AtEndOfPackage{\ettl@restore@space@catcode + \let\ettl@restore@space@catcode\ettl@undefined} +\catcode`\ =10 +% \end{macrocode} +% +% \subsection{Acknowledgements -- Thank You !} +% +% Thanks to Philipp Lehman for the \sty{etoolbox} package (and also for this nice class of documentation). +% Much of my work on lists are based on his work and package. +% +% Thank to Heiko Oberdiek who has done so much for the \TeX\ and \LaTeX\ community, and allows me to +% produce a package in one only \sty{.dtx} file. +% +% \subsection{Hint for the reader} +% +% Every command provided in this \sty{etextools} package are fully expandable +% unless explicitly specified. As it appears to be the philosophy of \sty{etoolbox} +% to make the most of its commands fully expandable (and this is very useful for package +% writing and/or document-style programming) the \FE fully expandable commands +% have a special sign in the margin (displayed here for information). +% +% Remain what a control sequence, a control word and a control character are... +% +% \iffalse The commands have been (extensively, more or less) tested.\fi +% +% +% \part*{User commands} +% \addtocontents{toc}{\protect\contentsline{part}{\large User commands}{}{}} +% +% \section{A few (\oldstylenums{7}) ``helper'' macros} +% +% \begin{ltxsyntax} +% +% \cmditem{ettl@afterelse} \cmdlabel{ettl@afterelse} +% \cmditem*{ettl@afterfi} \cmdlabel{ettl@afterfi}\hfil\par +% +% Those two commands\FE are the copies of |\bbl@afterelse| and |\bbl@afterfi| from the \sty{babel} package. +% They allow to get out of |\if|...|\fi| conditionals. +% +% \begin{macrocode} +\long\def\ettl@afterelse#1\else#2\fi{\fi#1} +\long\def\ettl@afterfi#1\fi{\fi#1} +% \end{macrocode} +% +% {\rmk Those commands are used in \cmdref{iffirstchar} and \cmdref{expandnext} } +% +% \cmditem*{@gobblescape}\hfil\par +% +% This sequence\FE of command is very often used, even in \sty{latex.ltx}. So +% it appears to be better to put it in a macro. It's aim is to reverse the +% mechanism of |\csname|...|\endcsname|: +% \begin{macrocode} +\newcommand*\@gobblescape{\expandafter\@gobble\string} +% \end{macrocode} +% +% \cmditem{str@gobblescape}{string}\hfil\par +% +% With \FE \eTeX\space |\detokenize| it is now possible to invoke a |\string| on an arbitrary +% sequence of tokens. Unfortunately, |\detokenize| adds a +% space tokens at the very end of the sequence. |\str@gobblescape| acts exactly +% the same way as |@gobblescape| \ie it removes the first character from a string, but removes +% the trailing spaces as well: +% +% \begin{macrocode} +\newcommand\str@gobblescape[1]{\expandafter\deblank\expandafter{% + \expandafter\@gobble\detokenize{#1}}} +% \end{macrocode} +% +% The \cmdref{deblank} command will be desbribed later. +% +% \end{ltxsyntax} +% +% \section{Expansion control} +% +% NOTA BENE: Pay attention\dbend that the expansion control macros are not \emph{primitives}! +% Therefore: +% \begin{tabbing} +% \qquad\= |\expandafter\controlsequence\noexpandcs{|\prm{csname}|}|\\ +% \> |\expandafter\controlsequence\expandonce{|\prm{command}|}| +% \end{tabbing} +% etc. etc. may not lead to the result you expected. +% The |\expandonce| macro from \sty{etoolbox} worth the same warning. +% +% For expansion control, it's better to use primitives, unless you clearly knows what +% you do and what will happen... \textbf{In particular,\dbend you'd very better avoid to use +% expansion control macros at the very beginning of the definition of a command, for if this command +% is preceded (in the user's code) by \sty{\textbackslash expandafter}, you will be lead +% to undesirable result and most probably to an error !} + +% \begin{ltxsyntax} +% +% \cmditem{noexpandcs}{csname} +% +% In an \FE expansion context (|\edef|) we often want a control sequence whose name results +% from the expansion of some macros and/or other tokens to be created, but not expanded at that point. +% Roughly:§ +% \qquad |\edef{\noexpandcs{<balanced text to be expanded as a cs-name>}}|§ +% will expand to: |\"cs-name"| but this (new) control sequence itself will not be expanded. +% A typical use is shown in the following code:§ +% \smex |\edef\abc{\noexpandcs{abc@\@gobblescape\controlword}}|§ +% \smex if equivalent to:\quad|\def\abc{\abc@controlword}|. +% +% \begin{macrocode} +\newcommand*\noexpandcs[1]{\expandafter\noexpand\csname #1\endcsname} +% \end{macrocode} +% +% {\rmk|\noexpandcs| is used in the definition of \cmdref{DeclareListCmdParser}.} +% +% \cmditem{noexpandafter}\hfil\par +% +% |\noexpandafter|\FE only means |\noexpand\expandafter| and is shorter to type. +% +% \begin{macrocode} +\newcommand\noexpandafter{\noexpand\expandafter} +% \end{macrocode} +% +% {\rmk This command is used in the definition of \cmdref{DeclareListCmdParser}.} +% \iffalse +% \cmditem{afterexpandafter} +% +% |\afterexpandafter|\FE means to delay the expansion twice :§ +% \qquad |\afterexpandafter\a\expandafter\b\c|\quad will replace |\c| by its \prm{replacement text}, then +% expand place |\b| before and replace it by its \prm{replacement text} as well, eventually consuming its +% parameters, and after that, place |\a| before the whole thing; then expansion goes further. +% +% \begin{macrocode} +% \newcommand\afterexpandafter{\expandafter\expandafter\expandafter} +% \end{macrocode} +% \fi +% +% \cmditem{expandnext}{cstoken}{first parameter of cstoken} \cmdlabel{expandnext} +% +% We\FE often want a control sequence to be expanded after its first argument. For example, if we want to test if a command +% |\foo| has a blank replacement text we will type : +% +% \qquad |\expandafter\ifblank\expandafter{\foo}| +% +% Now suppose you wish to define a macro |\detokenizecs{|\prm{csname}|}| that expands to the detokenized content +% of |\csname |\prm{csname}|\endcsname|. Without |\expandnext| you will have to say: +% \begin{tabbing} +% \qquad\= |\expandafter\expandafter\expandafter\detokenize| \\ +% \> |\expandafter\expandafter\expandafter{\csname |\prm{csname}|\endcsname}| +% \end{tabbing} +% \textbf{six} \cmd{expandafter}(s). With |\expandnext| you will just have to say:§ +% \qquad|\expandnext\expandnext\detokenize{\csname #1\endcsname}| +% +% Now observe the following game : +% \begin{tabbing} +% \qquad\= |\def\foo{foo}| \qquad \= \smex \qquad \= |\def\Foo{\foo}| \quad \= \eol \\ +% \> |\def\\FOo{\Foo}| \> \smex \> |\def\FOO{\FOo}| \> \eol \\ +% \> |\def\FOOL{\FOO}| +% \end{tabbing} +% And {\bfseries guess how many \cmd{expandafter} you will need in order to test ``|\ifblank{foo}|'' directly from |\FOOL| ??? } +% +% |\expandnext| solves this problem : |\FOOL| has 5 degrees of expansion until it expands to ``foo'', so one require exactly 5 +% |\expandnext| : the solution is : +% +% \qquad |\expandnext\expandnext\expandnext\expandnext\expandnext\ifblank{\FOOL}| +% +% And now : if you define, say : |\csdef{bloody fool}{\FOO}| you just require 2 more |\expandnext| in order +% to test ``foo'' from ``|\csname bloody fool\endcsname|'' ! \emph{just test it!} +% +% \begin{macrocode} +\newcommand\expandnext[2]{% + \ifx#1\expandnext + \ettl@afterelse\expandafter\expandafter\expandafter + \expandafter\@expandnext{#2}{\expandafter\expandafter\expandafter} + \else\ettl@afterfi\expandafter#1\expandafter{#2} + \fi} +\long\def\@expandnext#1#2#3{% + \ifx#1\expandnext + \expandafter\ettl@afterelse\expandafter\expandafter\expandafter + \expandafter\@expandnext{#3}{\expandafter#2#2} + \else + \expandafter\ettl@afterfi#2#1#2{#3} + \fi} +% \end{macrocode} +% +% This code is not very tricky but difficult to explain. The better is to watch at the log if the reader is eager +% to understand the job of each \cmd{expandafter}. +% +% Note that the first argument of |\expandnext| must be a single \prm{cstoken} (for \cmd{expandnext} acts +% only on the first following token). +% +% \end{ltxsyntax} +% +% \section{String manipulation} +% +% \subsection{String trimming} +% +% \begin{ltxsyntax} +% +% \cmditem{deblank}{string} \cmdlabel{deblank} +% +% The macro \FE |\deblank| will remove the extra blank space inserted by |\detokenize| at the +% very end of the \prm{string}. Actually, it removes all trailing spaces (charcode 32, catcode 10) +% from its argument: +% +% \begin{macrocode} +\newcommand\deblank{} +\begingroup\catcode`\&=3% a & as a math shift +\long\gdef\deblank#1{\@deblank#1 &} +\long\gdef\@deblank#1 #2&{\ifblank{#2}{#1}{#1\@deblank#2 &}} +\endgroup +% \end{macrocode} +% +% Note, by the way, that the leading spaces are also removed by \TeX's mastication mechanism. +% \goodbreak +% +% \subsection{Expanded string comparison} +% +% \cmditem{xifblank}{string}{true}{false} +% +% |\xifblank| is similar to |\ifblank| except that the \prm{string} is first expanded +% with |\protected@edef|: +% \begin{macrocode} +\newrobustcmd\xifblank[1]{\begingroup + \protected@edef\@xifblank{\endgroup + \noexpand\ifblank{#1}% + }\@xifblank} +% \end{macrocode} +% +% \cmditem{xifstrequal}{string1}{string2}{true}{false} +% +% In the same way, |\xifstrequal| is similar to |\ifstrequal| but both \prm{string} arguments +% are expanded with |\protected@edef| before comparison: +% \begin{macrocode} +\newrobustcmd\xifstrequal[2]{% + \begingroup\protected@edef\@tempa{#1}\protected@edef\@tempb{#2}% + \ifx\@tempa\@tempb \aftergroup\@firstoftwo + \else \aftergroup\@secondoftwo + \fi\endgroup} +% \end{macrocode} +% +% \subsection{Testing characters} +% +% \cmditem{iffirstchar}{string1}{string2}{true}{false} +% \cmditem*{iffirstchar}{}{string}{true}{false} +% +% |\iffirstchar| will\FE compare the character codes of the \textbf{first} characters of each \prm{string}. The +% comparison is \emph{catcode agnostic} and the macro is fully expandable. Neither \prm{string1} not \prm{string2} +% is expanded before comparison. +% +% There is a ``special'' use of this command when the user want to test if a \prm{string} begins +% with an \emph{escape} character (\,\textbackslash\,) one may say: +% \begin{tabbing} +%\qquad\= |\iffirstchar \@backslashchar{|\prm{string}|}|\qquad\= or even easier:\\ +% \>|\iffirstchar {}{|\prm{string}|}| +% \end{tabbing} +% Please note that the tests: +% \begin{tabbing} +% \qquad\qquad\=|\iffirstchar |\=|{|\prm{whatever string1 is}|}{}|\\ +% and:\>|\iffirstchar |\>|{}{}| +% \end{tabbing} +% are \textbf{always expanded into \underline{\prm{false}}} +% (for consistency with the shortcut-test for |\@backslashchar|): +% +% \begin{macrocode} +\newcommand\iffirstchar[2]{% + \if \expandafter\@car\string#2\relax\@nil\expandafter\@car#1\string\\\@nil + \ettl@afterelse\ifblank{#2}\@secondoftwo\@firstoftwo + \else \expandafter\@secondoftwo + \fi} +% \end{macrocode} +% +% +% \cmditem{ifsinglechar}{string1}{string2}{true}{false} +% +% |\ifsinglechar|\FE will perform the test |\iffirstchar| but will also check that \prm{string2} has only one character. +% +% \begin{macrocode} +\newcommand\ifsinglechar[2]{% +% \end{macrocode} +% Remember that neither \prm{string1} nor \prm{string2} is expanded.§ +% First: test if |#2| is a single character: +% \begin{macrocode} + \expandnext\expandnext\ifblank{\expandafter\@cdr\string#2 \@nil} +% \expandafter\expandafter\expandafter\ifblank +% \expandafter\expandafter\expandafter{% +% \expandafter\@cdr\string#2 \@nil} +% \end{macrocode} +% The test returned \prm{true}: therefore test further the character codes of |#2| and |#1|, and +% switch to \prm{true} only in case of equality: +% \begin{macrocode} + {\iffirstchar{#1}{#2}} +% \end{macrocode} +% Otherwise, switch to \prm{false} +% \begin{macrocode} + \@secondoftwo} +% \end{macrocode} +% +% Now with the macro |\ifsinglechar| it becomes possible to write fully expandable macros with an option, \textbf{provided +% that this macro has at least one non-optional argument}, as far as we don't use |\futurelet| nor any assignation. +% The ``trick'' is the following: +% \begin{tabbing} +% \qquad\= |\def\MacroWithOption#1{\ifsing|\=|lechar|\=|[{#1}| \\ +% \>\>|{\MacroHasOption[}| \\ +% \>\>|{\MacroNoOption{#1}}}}|\\ +% \> |\def\MacroHasOption[#1]#2|... \>\textit{definition} \\ +% \> |\def\MacroNoOption#1|...\>\textit{definition} +% \end{tabbing} +% +% Moreover (in the style of |\@testopt|): +% \begin{tabbing} +% \qquad\= |\def\MacroWithOption#1{\ifsing|\=|lechar|\=|[{#1}|\\ +% \>\>|{\MacroHasOption#1}|\\ +% \>\>|{\MacroHasOption[default]{#1}}}| +% \end{tabbing} +% +% Therefore, the following macro is defined: +% +% \subsection{Fully expandable macros with options} +% +% \cmditem{FE@testopt}{argument to be tested}{commands}{default option} \cmdlabel{FE@testopt} +% +% |\FE@testopt| mimics the behaviour of |\@testopt| but is Fully Expandable (\sty{FE})\FE and can be used as follow:§ +% \qquad |\def\MacroWithOption#1{\FE@testopt{#1}\MacroHasOption{default}}|\par +% +% Remember that |\MacroWithOption| \textbf{must have at least one mandatory argument.} +% +% \begin{macrocode} +\newcommand\FE@testopt[3]{\ifsinglechar [{#1}{#2#1}{#2[{#3}]{#1}}} +% \end{macrocode} +% +% \textbf{Limitation :}\dbend if you call such an option command without option and with |{[}| as mandatory +% argument, it will be considered that the command has an option, whose end will be at the next `\,]\,' found in the input string. +% +% {\rmk |\FE@testopt| is used in the definition of \cmdref{DeclareListCmdParser}.} +% +% \cmditem{FE@ifstar}{argument to be tested}{star-commands}{non-star commands} \cmdlabel{FE@ifstar} +% +% Similarly,\FE it becomes possible to mimic the behaviour of |\@ifstar| but in a fully expandable(\sty{FE}) way. +% |\FE@ifstar| can be used as follow :§ +% \begin{tabbing} +% \qquad\= |\def\StarOrNotCommand#1{\FE@|\=|ifstar|\=|{#1}|\\ +% \>\>|{\StarredCommand}|\\ +% \>\>|{\NotStarredCommand}}| +% \end{tabbing} +% +% Remember that |\StarredCommand| and |\NotStarredCommand| \textbf{must have at least one mandatory argument.} +% +% \begin{macrocode} +\newcommand\FE@ifstar[3]{\ifsinglechar *{#1}{#2}{#3{#1}}} +% \end{macrocode} +% +% \textbf{Limitation :}\dbend if you call such a command with |{*}| as mandatory argument, +% it will be considered that the command is starred, and the mandatory argument will be found next inside the input string. +% +% \textbf{This ``limitation'' is in fact a benediction:} thank to it we can have +% {\it\catcode`\ \active\let =-Fully Expandable starred macros with option\/}!\nobreak +% {\rmk |\FE@ifstar| is used in the definitions of \cmdref{DeclareListCmdParser}, \cmdref{csvloop}, \cmdref{listloop} +% and \cmdref{csvtolist}.} +% \goodbreak +% \end{ltxsyntax} +% +% \section{List management} +% +% \subsection{The Command-List Parser} +% +% The \sty{etoolbox} package provides a way to define list parsers a fully expandable macros: +% the list parser is able to expand the auxiliary command |\do| on each item of a list. +% \iffalse +% Declaration of a list parser is done via the |\DeclareListParser| macro\footnotemark. +% \footnotetext{besides, \sty{etoolbox} defines the \sty{\textbackslash docsvlist} and the +% \sty{\textbackslash dolistloop} macros: the choice of this name is not very friendly +% and we expected to have a \sty{\textbackslash docsvloop} macro instead...}. +% \fi +% +% Here we provide a |\DeclareCmdListParser| macro that is compatible and slightly different, because the auxiliary +% command is not necessarily |\do|. Such a command-list-parser is fully expandable. +% +% The idea is that if |\csvloop| has been defined as a command-parser then, thank to the fully expandable macro |\FE@testopt| +% we can call for expansion: +% \begin{tabbing} +% \qquad\= |\csvloop*{item,item,...}|\,\= as a shortcut for\,\= |\csvloop*[\do]{item,...}|\\ +% or:\> |\csvloop*[\listadd\mylist]{item,item,...}|\quad +% \end{tabbing} +% for example to convert the csv-list into internal \sty{etoolbox} list. +% +% {\rmk The star-form of \cmdref{csvloop} will be explained below.} +% +% \begin{ltxsyntax} +% +% \cmditem{DeclareCmdListParser}{command}{separator} +% +% |\DeclareCmdListParser| acts in the same way as \sty{etoolbox}-|\DeclareListParser| and the command-list-parser +% are sensitive to the category code of the \prm{separator} +% {\catcode`\ =13\let =-\it(which is not necessarily a single character and shall not be a {\tt\&} with a catcode of 3)}. +% +% The command-list-parser will be defined only if it is definable: +% +% \begin{macrocode} +\newrobustcmd*\DeclareCmdListParser[2]{% + \@ifdefinable#1 + {\expandafter\etextools@defcmdparser\expandafter{#1}{#2}}} +% \end{macrocode} +% +% Then the job is done by |\etextools@defcmdparser|: we need the `\,\&\,' to have a catcode of 3 +% and globally define the macro inside a purposeful group: +% +% \begin{macrocode} +\begingroup\catcode`\&=3 +\gdef\etextools@defcmdparser#1#2{% + \begingroup +% \end{macrocode} +% Now the parser definition is made inside an protected-|\edef| in order to expand control sequences names: +% \begin{macrocode} + \protected@edef\defineparser{\endgroup +% \end{macrocode} +% Here we define the entry-point: we first test if the command was starred. +% This is possible because the list-parser has always a mandatory argument (the \prm{list} itself or the \prm{listmacro}) : +% \begin{macrocode} + \long\def#1####1{\noexpand\FE@ifstar{####1} + {\noexpandcs{ettl@lst@star\string#1}} + {\noexpandcs{ettl@lst@nost\string#1}}}% +% \end{macrocode} +% Both starred and not-starred versions have an optional argument which is the auxiliary command, whose name is |\do| if not specified. +% It is possible to test the option for the same reason: +% \begin{macrocode} + \long\csdef{ettl@lst@star\string#1}####1{\noexpand\FE@testopt{####1} + {\noexpandcs{ettl@lst@star@pt\string#1}}{\noexpand\do}}% + \long\csdef{ettl@lst@nost\string#1}####1{\noexpand\FE@testopt{####1} + {\noexpandcs{ettl@lst@nost@pt\string#1}}{\noexpand\do}}% +% \end{macrocode} +% Definition of the parser with its arguments :\quad |[optional command]{list or listmacro}|. If the starred version +% was used, then we do not have to expand the (mandatory) \prm{list}: +% \begin{macrocode} + \long\csdef{ettl@lst@star@pt\string#1}[####1]####2{% + \noexpandcs{ettl@lst\string#1}{####2}{####1}}% +% \end{macrocode} +% On the other hand, if the parser was not starred, the (mandatory) \prm{listmacro} is expanded once: +% \begin{macrocode} + \long\csdef{ettl@lst@nost@pt\string#1}[####1]####2{% + \noexpandafter\noexpandcs{ettl@lst\string#1}\noexpandafter{% + ####2}{####1}}% +% \end{macrocode} +% ListParser is defined and leads to |\"ettl@lst\string\ListParser"| in all cases; here the \prm{list} is in first position, +% the auxiliary commands come after, so we reverse the order and add a \prm{separator} in case the \prm{list} is empty: +% \begin{macrocode} + \long\csdef{ettl@lst\string#1}####1####2{% + \noexpandcs{ettl@lst@\string#1}{####2}####1\noexpand#2&}% +% \end{macrocode} +% In the following macro, we extract the first item from the list (before the \prm{separator} |#2|), for treatment: +% \begin{macrocode} + \long\csdef{ettl@lst@\string#1}####1####2\noexpand#2####3&{% +% \end{macrocode} +% Proceed with the first item, if not empty: +% \begin{macrocode} + \noexpand\ifblank{####2} + {} + {\noexpand\ettl@lst@doitem{####1}{####2}}% +% \end{macrocode} +% If the remainder of the list is empty then break loop, otherwise restart extracting the next, first item for treatment: +% \begin{macrocode} + \noexpand\ifblank{####3} + {\noexpand\ettl@listbreak} + {\noexpandcs{ettl@lst@\string#1}{####1}####3}&}% +% \end{macrocode} +% Now the definitions are ready, execute them: +% \begin{macrocode} + }\defineparser}% +% \end{macrocode} +% |\ettl@lst@doitem| apply the auxiliary command(s) (in |#1|) to the item (|#2|): +% |\ettl@listbreak| breaks the loop, removing the extra \sty{\&}: +% \begin{macrocode} + \long\gdef\ettl@lst@doitem#1#2{#1{#2}}% + \long\gdef\ettl@listbreak#1&{}% +% \end{macrocode} +% Leave ``catcode-group'': +% \begin{macrocode} +\endgroup +% \end{macrocode} +% +% \subsection{Loops into lists} +% +% Now we have to declare two command-list-parsers : |\listloop| for \sty{etoolbox} lists +% and |\csvloop| for comma-separated lists. +% +% \cmditem{csvloop}[auxiliary commands]{csvlistmacro} \cmdlabel{csvloop} +% \cmditem*{csvloop*}[auxiliary commands]{item,item,item,...} +% \cmditem*{listloop}[auxiliary commands]{listmacro} \cmdlabel{listloop} +% \cmditem*{listloop*}[auxiliary commands]{expanded list} +% +% |\listloop| acts exactly as \sty{etoolbox}-|\dolistloop| with an optional argument to change +% the default auxiliary command |\do| to apply to each item of the list : +% \begin{tabbing} +% \qquad\=|\listloop\mylist|\;\=\textit{is}\;\= |\listloop[\do]\mylist|\;\=\textit{and is also}\;\= |\dolistloop\mylist|\\ +% \> |\csvloop\csvlist|\> \textit{is}\> |\csvloop[\do]\csvlist|\> \textit{and is also}: \eol \\ +% \>\>\> |\expandafter\docsvlist\expandafter{\csvlist}| +% \end{tabbing} +% Definition of |\csvloop| : +% \begin{macrocode} +\DeclareCmdListParser\csvloop{,} +% \end{macrocode} +% +% Definition of |\listloop| (with a `\,\textbar\,' of catcode 3 -- cf.\sty{etoolbox}): +% \begin{macrocode} +\begingroup\catcode`\|=3 + \gdef\do{\DeclareCmdListParser\listloop{|}\undef\do}\aftergroup\do +\endgroup +% \end{macrocode} +% +% \subsection{Converting csv lists to \sty{etoolbox}-lists} +% +% \cmditem{csvtolist}{listmacro}{csvlistmacro} \cmdlabel{csvtolist} +% \cmditem*{csvtolist*}{listmacro}{item,item,item...} +% +% |\csvtolist| converts a comma separated list into an internal \sty{etoolbox} list. It is useful to insert more than one item +% at a time in a list. It's also the first application of the |\csvloop| macro just defined : +% +% \begin{macrocode} +\newcommand\csvtolist[1]{\FE@ifstar{#1}\star@csvtolist\nost@csvtolist} +\def\star@csvtolist#1{\csvloop*[{\unexpanded{\listadd#1}}]} +\def\nost@csvtolist#1{\csvloop[{\unexpanded{\listadd#1}}]} +% \end{macrocode} +% +% \end{ltxsyntax} +% +% \subsection{Removing elements from \sty{etoolbox}-lists} +% +% The \sty{etoolbox} package provides |\listadd|, |\listgadd| and |\listxadd| commands +% to add items to a list. However, no command is designed to remove an element from a +% list. +% +% \begin{ltxsyntax} +% +% \cmditem{listdel}{listmacro}{item} \cmdlabel{listdel} +% \cmditem*{listgdel}{listmacro}{item} \cmdlabel{listgdel} +% \cmditem*{listxdel}{listmacro}{item} \cmditem{listxdel} +% +% The |\listdel| command removes the element \prm{item} from the list \prm{listmacro}. Note that the +% \prm{listmacro} is redefined after deletion: +% +% \begin{macrocode} +\newrobustcmd\listdel[2]{\@listdel\def{#1}{#2}} +% \end{macrocode} +% +% Commands |\listgdel| and |\listxdel| are similar, except that the assignment (\ie the redefinition +% of the list) is global; for the latter, the \prm{item} is first expanded using |\protected@edef|: +% +% \begin{macrocode} +\newrobustcmd\listgdel[2]{\@listdel\gdef{#2}{#2}} +\newrobustcmd\listxdel[2]{\begingroup + \protected@edef\@listxdel{\endgroup + \unexpanded{\@listdel\def#1}{#2}% + }\@listxdel} +% \end{macrocode} +% +% Now you noticed the job is delayed to a general macro |\@listdel| which is relatively tricky ! +% We need first to be placed in an environment where the `\,\textbar\,' delimiter has a category code of 3 +% (cf \sty{etoolbox}-lists definitions): +% \begin{macrocode} + \begingroup\catcode`\|=3\catcode`\&=3 +% \end{macrocode} +% Inside this ``catcode-group'' the definition of |\@listdel| ought to be global: +% \begin{macrocode} + \long\gdef\@listdel#1#2#3{% +% \end{macrocode} +% \qquad |#1|=|\def| or |\gdef|, |#2|=\prm{listmacro}, |#3|=\prm{item} to remove.\par +% In order to preserve the hash-table from temporary definitions, a group is opened: +% \begin{macrocode} + \begingroup + \def\@tempa##1|#3|##2&{##1|##2\@tempb}% +% \end{macrocode} +% |\@tempa| is a delimited macro whose aim is to remove the first \prm{item} found in the list +% and it adds |\@tempb| after the result. If the \prm{item} was not in the list, then |##2| +% will be empty. Note that |\@tempa| is the only macro whose definition depends on the \prm{item} +% (and then leads |\@listdel| not to be fully-expandable). +% +% The result of |\@tempa| expansion is then given to |\@tempb| whose purpose is to cancel out +% whatever is found between the two delimiters: \textbar|\@tempb|...\textbar|\@tempb|: +% \begin{macrocode} + \def\@tempb|##1|\@tempb##2|\@tempb{% + \ifblank{##2}{\unexpanded{##1}} +% \end{macrocode} +% If the \prm{item} \textsc{was not} is the list, then |##2| will be empty, and§ +% \qquad |\@tempb|\textbar...\textbar\@tempb...\textbar|\@tempb|§ +% is replaced by the \emph{original-}list (\ie |##1| -- that we shall not expand), then the loop is broken; +% otherwise the \prm{item} was in the list and |##1| is the \emph{shortened-}list without the \prm{item}. We have to loop +% to remove all the \prm{item{\tt s}} of the list, except in the case where the \emph{shortened-}list +% is empty after having removing \prm{item} (|##1| empty): +% \begin{macrocode} + {\ifblank{##1}{}{\@tempx##1&}}}% +% \end{macrocode} +% Now we just have to (define and) expand |\@tempx| in an |\edef| which is going to redefine +% the \prm{listmacro}. |\@tempx| expands first |\@tempa| and then |\@tempb| on the result of +% the expansion of |\@tempa|. The macro |\@tempx| itself has an argument: it is (at first stage) the +% replacement text of \prm{listmacro}: +% \begin{macrocode} + \def\@tempx##1&{\expandafter\@tempb\@tempa|##1|\@tempb|#3|&}% + \edef\@redef{\endgroup + \unexpanded{#1#2}{% ie: \def or \gdef \listmacro +% \end{macrocode} +% |\@redef| redefines the list using (|\def| or |\gdef|), the replacement text is the result +% of the expansion of |\@tempx| on the \prm{listmacro} which is expanded once (to see its items...): +% \begin{macrocode} + \expandafter\@tempx\unexpanded\expandafter{#2}&}% +% \end{macrocode} +% Then just expand |\@redef| (fully expandable): +% \begin{macrocode} + }\@redef}% end of \@listdel +% \end{macrocode} +% And ends the ``catcode-group'': +% \begin{macrocode} +\endgroup +% \end{macrocode} +% +% \end{ltxsyntax} +% +% +% +% +% + +% +% +% +% +% +% +% +% +% \begin{macrocode} +%</package> +% \end{macrocode} +% \label{LastPage} +% \Finale diff --git a/Master/texmf-dist/source/latex/etextools/etextools.ins b/Master/texmf-dist/source/latex/etextools/etextools.ins new file mode 100644 index 00000000000..9a94c04a435 --- /dev/null +++ b/Master/texmf-dist/source/latex/etextools/etextools.ins @@ -0,0 +1,77 @@ +%% +%% This is file `etextools.ins', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% etextools.dtx (with options: `install') +%% +%% This is a generated file. +%% +%% Copyright (C) 2009 by Florent Chervet <florent.chervet@free.fr> +%% +%% This work may be distributed and/or modified under the +%% conditions of the LaTeX Project Public License, either +%% version 1.3 of this license or (at your option) any later +%% version. The latest version of this license is in +%% http://www.latex-project.org/lppl.txt +%% +%% This work consists of the main source file etextools.dtx +%% and the derived files +%% etextools.sty, etextools.pdf, etextools.ins, +%% +%%% etextools : more e-TeX useful tools for LaTeX package writers +%%% Florent CHERVET +\input docstrip.tex +\Msg{************************************************************************} +\Msg{* Installation} +\Msg{* Package: etextools 2009/07/14 v2e e-TeX more useful tools for LaTeX package writers} +\Msg{************************************************************************} + +\keepsilent +\askforoverwritefalse + +\let\MetaPrefix\relax +\preamble + +This is a generated file. + +Copyright (C) 2009 by Florent Chervet <florent.chervet@free.fr> + +This work may be distributed and/or modified under the +conditions of the LaTeX Project Public License, either +version 1.3 of this license or (at your option) any later +version. The latest version of this license is in + http://www.latex-project.org/lppl.txt + +This work consists of the main source file etextools.dtx +and the derived files + etextools.sty, etextools.pdf, etextools.ins, + +\endpreamble +\let\MetaPrefix\DoubleperCent + +\generate{% + \file{etextools.ins}{\from{etextools.dtx}{install}}% + \file{etextools.sty}{\from{etextools.dtx}{package}}% +} + +\obeyspaces +\Msg{************************************************************************} +\Msg{*} +\Msg{* To finish the installation you have to move the following} +\Msg{* file into a directory searched by TeX:} +\Msg{*} +\Msg{* etextools.sty} +\Msg{*} +\Msg{* To produce the documentation run the file `etextools.drv'} +\Msg{* through LaTeX.} +\Msg{*} +\Msg{* Happy TeXing!} +\Msg{*} +\Msg{************************************************************************} + +\endbatchfile +\endinput +%% +%% End of file `etextools.ins'. |