diff options
author | Karl Berry <karl@freefriends.org> | 2007-12-14 01:45:54 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2007-12-14 01:45:54 +0000 |
commit | fc77b8d3f3622ede43e4c3277b3fbab79fb8d19c (patch) | |
tree | 5b178626d2021fb7ecaead7949df9b86b5fa0591 /Master/texmf-dist/source/latex/ted | |
parent | eb1442008618eb247e459e968cfb19e013fa7d02 (diff) |
new latex package ted (12dec07)
git-svn-id: svn://tug.org/texlive/trunk@5772 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex/ted')
-rw-r--r-- | Master/texmf-dist/source/latex/ted/ted.dtx | 1246 |
1 files changed, 1246 insertions, 0 deletions
diff --git a/Master/texmf-dist/source/latex/ted/ted.dtx b/Master/texmf-dist/source/latex/ted/ted.dtx new file mode 100644 index 00000000000..310f37c967c --- /dev/null +++ b/Master/texmf-dist/source/latex/ted/ted.dtx @@ -0,0 +1,1246 @@ +% +% \iffalse /!\ utf-8 encoded file /!\ +% +% ted package by Manuel P\'egouri\'e-Gonnard <mpg@math.jussieu.fr> +% ---------------------------------------------------------------- +% +% This work may be distributed and/or modified under the conditions of the +% LaTeX Project Public License, either version 1.3c 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 +% +% and version 1.3c or later is part of all distributions of LaTeX version +% 2006/05/20 or later. +% +% This work has the LPPL maintenance status `maintained'. +% +% The current maintainer of this work is Manuel P\'egouri\'e-Gonnard. +% +% This work consists of the file ted.dtx and the derived files ted.sty, +% ted.pdf and ted-fr.pdf. +% +% +%<*gobble> +\ProvidesFile{ted.dtx} +%</gobble> +%<package>\NeedsTeXFormat{LaTeX2e} +%<package>\ProvidesPackage{ted} +%<*package> +% \fi +% \ProvidesFile{ted.dtx} + [2007/12/12 v1.01 \space token list editor \space (mpg)] +% \iffalse +%</package> +% \fi +% \CheckSum{774} +% \CharacterTable +% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z +% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z +% Digits \0\1\2\3\4\5\6\7\8\9 +% Exclamation \! Double quote \" Hash (number) \# +% Dollar \$ Percent \% Ampersand \& +% Acute accent \' Left paren \( Right paren \) +% Asterisk \* Plus \+ Comma \, +% Minus \- Point \. Solidus \/ +% Colon \: Semicolon \; Less than \< +% Equals \= Greater than \> Question mark \? +% Commercial at \@ Left bracket \[ Backslash \\ +% Right bracket \] Circumflex \^ Underscore \_ +% Grave accent \` Left brace \{ Vertical bar \| +% Right brace \} Tilde \~} +% \iffalse +%<*gobble> +\begingroup +%</gobble> +%<*batchfile> +\input docstrip +\keepsilent +\preamble + +ted package by Manuel P\string\'egouri\string\'e-Gonnard % +<mpg@math.jussieu.fr> +This is a generated file. See ted.dtx for license information. + +\endpreamble +\askforoverwritefalse +%\generate{\file{ted.ins}{\from{ted.dtx}{batchfile}}} +%\generate{\file{ted.drv}{\from{ted.dtx}{driver}}} +\generate{\file{ted.sty}{\from{ted.dtx}{package}}} +\generate{\file{ted-fr.drv}{\from{ted.dtx}{pilote}}} +%</batchfile> +%<*gobble> +\endgroup +%</gobble> +%<*driver|pilote> +\documentclass[oneside, a4paper]{ltxdoc} +\usepackage[utf8]{inputenc} +\usepackage[T1]{fontenc} +\usepackage{lmodern} +\usepackage[babel=true, expansion=false]{microtype} +\usepackage[bookmarks=false, colorlinks=true, + linkcolor=black, urlcolor=black]{hyperref} +\usepackage{fixltx2e} +\expandafter\newif\csname iffrenchdoc\endcsname % just hiding this if +%<pilote>\frenchdoctrue +%</driver|pilote> +%<*gobble> +\iffrenchdoc +%</gobble> +%<*pilote> +\usepackage[lmargin=4.5cm, rmargin=3cm]{geometry} +\OnlyDescription +\usepackage[english, french]{babel} +\FrenchFootnotes +\newcommand*\eng[1]{\emph{\foreignlanguage{english}{#1}}} +%</pilote> +%<*gobble> +\else +%</gobble> +%<*driver> +\AlsoImplementation +\usepackage[english]{babel} +%</driver> +%<*gobble> +\fi +%</gobble> +%<*driver|pilote> +\newcommand\pf{\textsf} +\setcounter{tocdepth}{1} +\renewcommand\thesubsubsection{\alph{subsubsection}} +\settowidth\MacroIndent{\rmfamily\scriptsize 000\ } +\setlength\MacroTopsep{0pt} +\begin{document} + \DocInput{ted.dtx} +\end{document} +%</driver|pilote> +%<*package> +% \fi +% +% \GetFileInfo{ted.dtx} +% +% \title{\iffrenchdoc L'extension \pf{ted}\else The \pf{ted} package\fi} +% \author{Manuel Pégourié-Gonnard\\ +% \href{mailto:mpg@math.jussieu.fr}{mpg@math.jussieu.fr}} +% \date{\fileversion\ (\filedate)} +% +% \maketitle +% \tracingmacros1 +% \iffrenchdoc\else \tableofcontents \fi +% \tracingmacros0 +% +% \section{Introduction} +% +% \iffrenchdoc +% +% Le nom de l'extension \pf{ted} signifie \eng{token list editor}, soit en +% français \og éditeur de listes de lexèmes \fg{}. Comparé à \texttt{sed} dont +% son nom s'inspire, il n'est pas très puissant : il ne sait faire +% actuellement que deux choses avec les listes de lexèmes, à savoir les +% afficher en détail, et y opérer des substitutions. Toutefois, sa +% caractéristique principale est de travailler vraiment au niveau des lexèmes, +% et non des simples caractères. +% +% L'extension \pf{ted} est capable de faire des substitutions même à +% l'intérieur d'une paire d'accolades, et n'a pas de problèmes avec des +% lexèmes particuliers. En fait, elle est conçue pour fonctionner même avec +% des listes comportant des lexèmes très exotiques. +% +% \else +% +% Just like \texttt{sed} is a stream editor, \pf{ted} is a token list editor. +% Actually, it is not as powerfull as \texttt{sed}, but its main feature is +% that it really works with tokens, not only characters. At the moment, it can +% do only two things with token lists: display it with full information on +% each token, and perform substitutions (that is, replacing every occurence of +% a sublist with another token list). +% +% The \pf{ted} package can perform substitutions inside groups, and don't +% forbid any token in the lists. Actually, \pf{ted} is designed to work well +% even if strange tokens (that is, unusual (charcode, \cs{catcode}) pairs or +% tokens with a confusing \cs{meaning}) occur in the list. +% +% \fi +% +% \section{Usage} +% +% \iffrenchdoc +% +% L'extension \pf{ted} définit essentiellement deux macros publiques : +% \cs{Substitute} et \cs{ShowTokens}. La première est la raison d'être de +% \pf{ted}, mais au cours du développement de l'extension, la partie la plus +% difficile et intéressante a été d'être capable d'écrire la deuxième. J'ai +% donc décidé de la proposer à l'utilisateur, car je pense qu'elle peut être +% utile, soit pour déboguer du code, soit pour apprendre \TeX. +% +% \medskip +% \DescribeMacro{\Substitute} +% La syntaxe de \cs{Substitute} est la suivante. +% \begin{quote} +% \cs{Substitute}\meta{*}\oarg{sortie}\marg{entrée}\marg{de}\marg{vers} +% \end{quote} +% Commençons par l'usage le plus simple : sans étoile ni argument optionel. +% Sous cette forme, \cs{Substitute} remplace chaque occurence de la sous-liste +% \meta{de} par \meta{vers} dans l'\meta{entrée}, et place le résultat dans le +% registre à lexèmes \cs{ted@toks}. Comme \cs{Substitute} est sans doute +% destiné à être utilisé par des auteurs de classe ou d'extensions, le |@| +% dans le nom de ce registre ne devrait pas poser de problèmes la plupart du +% temps. +% +% Quoi qu'il en soit, vous pouvez changer facilement le nom du registre +% utilisé pour la sortie avec l'argument optionel en spécifiant le nom d'un +% registre à lexèmes dans \meta{sortie}. En fait, vous voulez peut-être que la +% sortie soit placée dans une macro et non un registre : dans ce cas, vous +% pouvez spécifier par exemple \cs{def}\cs{macro} (ou +% \cs{long}\cs{def}\cs{macro} etc.) comme argument optionel. Dans tous les +% cas, \meta{sortie}|{trucs}| doit être une syntaxe légale d'affectation de +% |truc| dans la sortie. Bien sûr, si vous demandez à ce que la sortie soit +% placée dans une macro, vous devez veiller à ce qu'elle ne contienne pas de +% dièses (caractère de paramètre) mal placés. +% +% La version étoilée de \cs{Substitute} a pour but de vous simplifier la vie +% quand vous ne voulez pas spécifier explicitement une liste de lexèmes en +% entrée, mais plutôt utiliser le contenu d'une macro ou d'un registre, en +% développant une fois son premeir argument obligatoire avant de commancer à +% travailler dessus. Ceci vous évite d'avoir à placer vous-même des +% \cs{expandafter}, surtout dans le cas ou vous souhaitez utiliser l'argument +% optionel. Cette fois, l'usage est inversé par rapport à l'argument optionel +% : c'est la cas d'une macro qui est le plus naturel. Pour un registre de +% lexèmes, vous devez écrire le \cs{the} vous même : ainsi, votre \meta{entrée} +% pourra être de la forme \cs{macro}, ou \cs{the}\cs{toksreg}, ou toute autre +% chose dont le 1-développement donne ce que vous voulez. +% +% La version avec deux étoiles a aussi pour but de vous épargner la peine +% de contrôler vous-même le développement des arguments. Elle fonctionne comme +% la version étoilée simple, mais développe cette fois ses trois arguments +% obligatoires une fois avant de commencer à travailler. La même remarque que +% pour la version étoilée simple s'applique concernant les macros et les +% registres à lexèmes. J'espère que ces trois cas (de zéro à deux étoiles) +% couvriront la plupart des usage courants. Pour une gestion plus souple du +% développement des arguments, attendez \LaTeX$3$ ! +% +% Le comportement de \cs{Substitute} devrait être évident la pluart du temps. +% seul un cas particulier mérite sans doute une patite remarque : dans le cas +% ou la liste \meta{de} est vide, la liste \meta{vers} est insérée entre +% chaque paire de lexèmes de l'\meta{entrée} : en particulier elle n'est pas +% insérée au début ni à la fin. Par exemple, |\Substitute{abc}{}{1}| placera +% |a1b1c| dans \cs{ted@toks}. +% +% \medskip +% \DescribeMacro{\ShowTokens} +% La syntaxe de \cs{ShowTokens} est la suivante. +% \begin{quote} +% \cs{ShowTokens}\meta{*}\marg{liste} +% \end{quote} +% Dans sa forme simple, \cs{ShowTokens} se contente d'afficher la liste de +% lexème, un par ligne. Pour les lexèmes de type caractère, l'affichage +% comprte le caractère lui-même, suivi de l'indication de son code de +% catégorie sous forme parlante (comme |blank space|, |letter|, etc.). Pour +% les séquence de contrôles et les carctères actifs, le (début du) +% \cs{meaning} est également affiché, sans dépasser les 80 colonnes de large +% afin de ne pas perturber l'affichage par ligne. +% +% \DescribeMacro{\ShowTokensLogonly} +% \DescribeMacro{\ShowTokensOnline} +% Le comportement par défaut est d'afficher ces listes à la fois sur le +% terminal et dans le fichier log. Si vous préférez que l'affichage n'ait lieu +% que dans le fichier log, vous n'avez qu'à dire \cs{ShowTokensLogonly}. Si +% vous souhaitez ensuite revenir au comportement par défaut, dites seulement +% \cs{ShowTokensOnline}. +% +% La version étoilée de \cs{ShowTokens} fonctionne de la même façon que dans +% le cas de \cs{Substitute} en développant son argument une fois avant d'en +% commencer l'analyse. La même remarque que précédemment s'applique concernant +% les macros et les registres. +% +% \medskip +% J'aimerais conclure par la remarque suivante : au cours de la conception de +% \pf{ted}, j'ai vraiment essayé de ne faire aucune hypothèse sur les lexèmes +% présents dans la liste. Ainsi, vous pouvez utiliser librement des accolades, +% des dièses, des espaces, des \cs{par}, des \cs{if}s, des \cs{bgroup} ou +% \cs{egroup} dans toutes les listes de lexèmes. À ma connaissance à ce jour, +% la seule limitation est que les séquences de contrôle qui apparaissent ne +% doivent pas être (ou être \cs{let}-égales à) certaines des macros intimes de +% \pf{ted}, commençant par \cs{ted@@}. +% +% \begin{quote} +% Vous savez maintenant tout ce qu'il y a à savoir sur l'utilisation de +% \pf{ted}. Si vous souhaitez vous pencher sur son implémentation, il vous +% faudra lire les commentaires en anglais car je n'ai pas eu le courage de +% documenter mon code en deux langues. +% \end{quote} +% +% \begin{center}\large +% C'est tout pour cette fois ! \\ +% Amusez-vous bien avec \LaTeX{} ! +% \end{center} +% +% \else +% +% The \pf{ted} package provides two user macros: \cs{Substitute} and +% \cs{ShowTokens}. The first one is the primary goal of the package, but to be +% able to do the second was the more difficult and interesting part while +% writing the package. I made it into a user macro since I believe it can be +% useful for debugging things, or for learning \TeX. +% +% \medskip +% \DescribeMacro{\Substitute} +% The syntax of \cs{Substitute} is as follows. +% \begin{quote} +% \cs{Substitute}\meta{*}\oarg{output}\marg{input}\marg{from}\marg{to} +% \end{quote} +% Let's begin with the basics. Without star or optional argument, the +% \cs{Substitute} macro will replace each occurence of the \meta{from} token +% list with \marg{to} in the \meta{input}, and put the result in the +% \cs{toks} register \cs{ted@toks}. This macro has a |@| in its name, but +% since I think the \cs{Substitute} macro will be essentially be used by class +% or package writers, this should be ok. +% +% Anyway, if you don't like this name, you can specify another one as +% \meta{output} using the optional argument. Your \meta{output} should be the +% name of a \cs{toks} register. If you want the output to be put in a macro, +% use \cs{def}\cs{macro} (or \cs{long}\cs{def}\cs{macro} or\ldots) as the +% optional argument. Anyway, \meta{output}\marg{stuff} must be a legal syntax +% for an assignment: using \cs{macro} as optional argument will not work (and +% may actually result in chaos). Of course, if you want your output to be +% placed in a macro, it should not contain unproperly placed hash signs +% (that is, macro parameter tokens). +% +% The one-starred form of \cs{Substitute} is meant to help you when your +% \meta{input} is not an explicit token list, but the contents of either a +% macro or a \cs{toks} register, by expanding once its first mandatory +% argument before proceeding. It spares you the pain of +% using \cs{expandafter}s, especially in case you want to use the optional +% argument too. This time, things are reversed compared to the optional +% argument : using a macro instead of a toks register is easier. Actually, +% with the starred form, the first argument can be \cs{macro} or +% \cs{the}\cs{toksreg}, or anything whose one-time expansion is the token list +% you want \cs{Substitute} to act upon. +% +% The two-starred form is also meant to avoid you trouble with development. It +% expands its three mandatory arguments once before executiing. The remark +% about macros and \cs{toks} register still holds. I hope this three cases +% (from zero to two stars) will suffice for most purpose. For a better +% handling of arguments expansion, wait for \LaTeX$3$! +% +% The action of \cs{Substitute} is pretty obvious most of the time. Maybe a +% particular case needs some precision: when \meta{from} is empty, then the +% \meta{to} list gets inserted between each two tokens of the \cs{input}, but +% not before the first one. For example, \cs{Substitute}|{abc}{}{1}| puts +% |a1b1c| in \cs{ted@toks}. +% +% \medskip +% \DescribeMacro{\ShowTokens} +% The syntax of \cs{ShowTokens} is as follows. +% \begin{quote} +% \cs{ShowTokens}\meta{*}\marg{list} +% \end{quote} +% In its simple form, \cs{ShowTokens} just shows the list, one token per line. +% For characters tokens, its prints the character, and its category code in +% human-friedly form (such as ``blank space'', ``letter'', etc.). For control +% sequences and active characters, it also prints (the beginning of) their +% current \cs{meaning} as a bonus. +% +% \DescribeMacro{\ShowTokensLogonly} +% \DescribeMacro{\ShowTokensOnline} +% The default is to show this list both in the terminal and in the log file. +% If you don't want it to be printed on the terminal, just say +% \cs{ShowTokensLogonly}. If you change your mind latter, you can restore the +% default behaviour with \cs{ShowTokensOnline}. +% +% The starred form of \cs{ShowTokens} works the same as for \cs{Substitute}: +% it expands its argument once before analysing and displaying it. The same +% remarks hold: use \cs{macro} or \cs{the}\cs{toksreg} in the argument. +% +% \medskip +% I would like to conclude with the following remark: I have really tried to +% make sure \pf{ted}'s macros will work fine even with the wierdest token list. +% In particular, you can freely use begin-group and end-group characters, hash +% signs, spaces, \cs{bgroup} and \cs{egroup}, \cs{par}, \cs{if}s, as well as +% exotic charcode-\cs{catcode} pairs in every argument of the macros. As far +% as I am aware, the only restriction is you should not use +% some\footnote{Precisely, none of the control sequence in the token lists +% should be \cs{let}-equal to \cs{ted@@end}, \cs{ted@@special}, +% \cs{ted@@active} as defined below.} of the very private macros of \pf{ted} +% (those beginning with \cs{ted@@}) in your token lists. +% +% \fi +% +% \StopEventually{} +% +% \section{Implementation} +% +% A important problem, when trying to substitute things in token lists, is to +% handle begin-group and end-group tokens, since prevent us from to reading +% the tokens one by one, and tend to be difficult to handle individually. Two +% more kinds of tokens are special: the space tokens, since +% they\footnote{Actually, only tokens with charcode $32$ and \cs{catcode}~$10$ +% (i.e. $32_{10}$ tokens) are concerned. However, we will process all +% \cs{catcode}-$10$ tokens the same way.} cannot be grabbed as the undelimited +% argument of a macro, and the parameter tokens (hash signs), since they +% cannot be part of the delimiters in the parameter text of a macro. From now +% on, ``special tokens'' thus denotes tokens with \cs{catcode} $1$, $2$, $6$ +% or $10$. +% +% To get rid of these problems, the \cs{Substitute} command procedes in three +% steps. First, encode the input, replacing all special tokens with nice +% control sequences representing them, then do the actual substitution, and +% finally decode the output, replacing the special control sequences with the +% initial special tokens. +% +% Encoding is the hard part. The idea is to try reading the tokens one by one; +% for this we have two means: using a macro with one undelimited argument, or +% something like \cs{let}. The former doesn't work well with \cs{catcode}~$1$, +% $2$ or $10$ tokens, and the later do not see the name of the token (its +% character code, or its name for a CS). So we need to use both +% \cs{futurelet}, a ``grabbing'' macro with argument, and \cs{string} in order +% to scan the tokens. Actually, the encoding procedes in two passes: in the +% first, we try and detect the special tokens, storing their character codes +% for later use, then do the the actual encoding in the last pass. +% +% Decoding also processes the tokens one by one, and is simpler, since special +% cases are allready detected. There is, however, a trick with groups since, +% when we encouter a begin-group character, we have to wait for the +% corresponding end-group before adding the whole thing to the output. There +% is also a simpler version of decoding, for \cs{ShowTokens}, for screen/log +% output, with no need to use this trick, since it only outputs +% \cs{catcode}-$12$ charachters. Finally, the substitution part uses a macro +% with delimited argument, defined on the fly, using an idea of Jean-Côme +% Charpentier. +% +% The code is divided as follows. +% \begin{enumerate} \setlength\itemsep{0pt}% +% \item Encoding -- (a) pre-scan (b) encode +% \item Decoding +% \item Substitution +% \item Screen display for \cs{ShowTokens} +% \item Definition of the user commands +% \end{enumerate} +% +% \begin{macro}{\ted@toks} +% \begin{macro}{\ted@list} +% \begin{macro}{\ted@code} +% Before we begin, just allocate (or give a nice name to) a few registers. +% \begin{macrocode} +\@ifdefinable\ted@toks{\newtoks\ted@toks} +\@ifdefinable\ted@list{\let\ted@list\toks@} +\@ifdefinable\ted@code{\let\ted@code\count@} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \subsection{Encoding} +% +% \begin{macro}{\ted@encloop} +% \begin{macro}{\ted@encloop@} +% The two passes use the same loop for reading the input allmost token by +% token. This loop grabs the next token through a \cs{futurelet}\ldots +% \begin{macrocode} +\newcommand\ted@encloop{% + \futurelet\@let@token + \ted@encloop@} +% \end{macrocode} +% \ldots then looks at it with some \cs{ifx} and \cs{ifcat} (non nested, since +% the token could be an \cs{if} itself), in order to distinguish between +% three cases: normal token, end reached, or special token. In the later case, +% remember wich kind of special token it is, using a numeric code. +% \begin{macrocode} +\newcommand\ted@encloop@{% + \let\next\ted@do@normal + \ifx\@let@token\ted@@end + \let\next\ted@gobble@end + \fi + \ifcat\noexpand\@let@token##% + \ted@code0 + \let\next\ted@do@special + \fi + \ifcat\noexpand\@let@token\@sptoken + \ted@code1 + \let\next\ted@do@special + \fi + \ifcat\noexpand\@let@token\bgroup + \ted@code2 + \let\next\ted@do@special + \fi + \ifcat\noexpand\@let@token\egroup + \ted@code3 + \let\next\ted@do@special + \fi + \next} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \begin{macro}{\ted@@end} +% \begin{macro}{\ted@gobble@end} +% Here we used the following to detect the end, then gobble it when reached. +% \begin{macrocode} +\newcommand\ted@@end{\ted@@end@} +% \end{macrocode} +% \begin{macrocode} +\@ifdefinable\ted@gobble@end{% + \def\ted@gobble@end\ted@@end{}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\ted@sanitize} +% \begin{macro}{\ted@@active} +% Now, this detection method, with \cs{futurelet} and \cs{ifcat}, is unable to +% distinguish the following three cases for potential special tokens: (i) a +% ``true'' (explicit) special token, (ii) a CS \cs{let}-equal to a special +% token, (iii) an active character \cs{let}-equal to a special token. While +% this is pre-scanning's job to detect the (ii) case, the (iii) can be easily +% got rid of by redefining locally all active characters. +% \begin{macrocode} +\count@\catcode\z@ \catcode\z@\active +\newcommand\ted@sanitize{% + \count@\z@ \@whilenum\count@<\@cclvi \do{% + \uccode\z@\count@ + \uppercase{\let^^00\ted@@active}% + \advance\count@\@ne}} +\catcode\z@\count@ +% \end{macrocode} +% \begin{macrocode} +\newcommand\ted@@active{\ted@@active@} +% \end{macrocode} +% This sanitizing macro also mark active characters by \cs{let}-ing them equal +% to \cs{ted@@active} in ordrer to detect them easily later, for exemple while +% displaying on-screen token analysis. +% All operations (scanning, replacing, display and decoding) are going to +% happen inside a group where \cs{ted@sanitize} has been executed, so that +% active characters are no longer an issue. +% \end{macro} +% \end{macro} +% +% \begin{macro}{\ted@encode} +% \begin{macro}{\ted@do@normal} +% \begin{macro}{\ted@do@special} +% The \cs{ted@encode} macro is the master macro for encoding. It only +% initialise a few things and launches the two loops. We select one of the +% tree stpes by \cs{let}-ing \cs{ted@do@normal} and \cs{ted@do@special} to +% the appropriate action. +% \begin{macrocode} +\newcommand\ted@encode[1]{% + \ted@list{}% + \let\ted@do@normal\ted@gobble@encloop + \let\ted@do@special\ted@scan@special + \ted@encloop#1\ted@@end + \ted@toks{}% + \let\ted@do@normal\ted@addtoks@encloop + \let\ted@do@special\ted@special@out + \ted@encloop#1\ted@@end + \ted@assert@listempty} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \begin{macro}{\ted@assert@listempty} +% After the last loop, \cs{ted@list} should be empty. If it's not, it means +% something very weird happened during the encoding procedure. I hope the code +% below will never be executed :) +% \begin{macrocode} +\newcommand\ted@assert@listempty{% + \edef\next{\the\ted@list}% + \ifx\next\@empty \else + \PackageError{ted}{% + Assertion `\string\ted@list\space is empty' failed}{% + This should not happen. Please report this bug to the author. + \MessageBreak By the way, you're in trouble there... I'm sorry.}% + \fi} +% \end{macrocode} +% \end{macro} +% +% \subsubsection{Pre-scanning} +% +% \begin{macro}{\ted@gobble@encloop} +% For normal tokens, things are pretty easy: just gobble them! +% \begin{macrocode} +\newcommand\ted@gobble@encloop{% + \afterassignment\ted@encloop + \let\@let@token= } +% \end{macrocode} +% \end{macro} +% \begin{macro}{\ted@scan@special} +% For special tokens, it's harder. We must distinguish explicit +% character tokens from control sequences \cs{let}-equal to special tokens. +% For this, we use \cs{string}, then grab the next character to see wether its +% code is \cs{escapechar} or not. Actually, things are not this easy, for two +% reasons. First, we have to make sure the next character's code is not +% allready \cs{escapechar} before the \cs{string}, by accident. For this +% purpose, we set \cs{escapechar} to~$0$ except if next character's code is +% also~$0$, in which case we prefer~$1$. +% \begin{macrocode} +\count@\catcode\z@ \catcode\z@ 12 +\newcommand\ted@scan@special{% + \begingroup + \escapechar\if\@let@token^^00 \@ne \else \z@ \fi + \expandafter\ted@check@space\string} +\catcode\z@\count@ +% \end{macrocode} +% \end{macro} +% \begin{macro}{\ted@check@space} +% \begin{macro}{\ted@check@space@} +% Second, we have to handle carefully the case of the next token being the +% $32_{10}$ token, since we cannot grab this one with a macro. We are in this +% case if and only if the token we just \cs{string}ed was a character token +% with code $32$, and it is enough to check if next token's \cs{catcode} is +% $10$ in order to detect it, since it will be $12$ otherwise. In order to +% check this, we use \cs{futurelet} again for pre-scanning. +% \begin{macrocode} +\newcommand\ted@check@space{% + \futurelet\@let@token + \ted@check@space@} +% \end{macrocode} +% \begin{macrocode} +\newcommand\ted@check@space@{% + \ifcat\@let@token\@sptoken + \endgroup + \ted@addlist{32}% + \expandafter\ted@gobble@encloop + \else + \expandafter\ted@list@special + \fi} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \begin{macro}{\ted@list@special} +% Now that we got rid of this nasty space problem, we know for sure that the +% next token has \cs{catcode} $12$, so we can easily grab it as an argument, +% find its charcode, and decide wether the original token was a control +% sequence or not. Note the \cs{expandafter} over \cs{endgroup} trick, since +% we need to add the charcode to the list outside the group (opened for the +% modified \cs{escapechar}) though it was set inside. +% \begin{macrocode} +\newcommand*\ted@list@special[1]{% + \ted@code`#1\relax + \expandafter\expandafter\expandafter + \endgroup + \ifnum\ted@code=\escapechar + \ted@addlist{\m@ne}% + \else + \expandafter\ted@addlist\expandafter{\the\ted@code}% + \fi + \ted@encloop} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\ted@addlist} +% Here we used the following macro to add an element to the list, which is +% space-separated. +% \begin{macrocode} +\newcommand*\ted@addlist[1]{% + \ted@list\expandafter{\the\ted@list#1 }} +% \end{macrocode} +% \end{macro} +% +% \subsubsection{Actually encoding} +% +% Remember that, before this last encoding pass, \cs{ted@encode} did the +% following: +% \begin{quote} +% \cs{let}\cs{ted@do@normal}\cs{ted@addtoks@encloop}\\ +% \cs{let}\cs{ted@do@special}\cs{ted@special@out} +% \end{quote} +% \begin{macro}{\ted@addtoks@encloop} +% The first one is very easy : normal tokens are just grabbed as arguments and +% appended to the output, then the loop continues. +% \begin{macrocode} +\newcommand\ted@addtoks@encloop[1]{% + \ted@toks\expandafter{\the\ted@toks#1}% + \ted@encloop} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\ted@special@out} +% Special tokens need to be encoded, but before, just check if they are really +% special: they aren't if the corresponding code is $-1$. +% \begin{macrocode} +\newcommand\ted@special@out{% + \ifnum\ted@list@read=\m@ne + \ted@list@advance + \expandafter\ted@cs@clean + \else + \expandafter\ted@special@encode + \fi} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\ted@cs@clean} +% Even if the potentially special token was not a real one, we have work to +% do. Indeed, in the first pass we did break it using a \cs{string}, and thus +% we introduced some foreign tokens in the stream. Most of them are not +% important since they have \cs{catcode}~$12$. Anyway, some of them may be +% space tokens : in this case we have extra $32$'s in our list. So, we need to +% check this before going any further. +% \begin{macrocode} +\newcommand\ted@cs@clean[1]{% + \expandafter\ted@add@toks{#1}% + \expandafter\ted@cscl@loop\string#1 \@nil} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\ted@cscl@loop} +% We first add the CS to the output, then break it with a \cs{string} in order +% to look at its name with the folowing loop. It first grabs everything to the +% first space\ldots +% \begin{macrocode} +\@ifdefinable\ted@cscl@loop{% + \def\ted@cscl@loop#1 {% + \futurelet\@let@token + \ted@cscl@loop@}} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\ted@cscl@loop@} +% \ldots and carefully look at the next token in order to know if we are +% finished or not. +% \begin{macrocode} +\newcommand\ted@cscl@loop@{% + \ifx\@let@token\@nil + \expandafter\ted@gobble@encloop + \else + \ted@list@advance + \expandafter\ted@cscl@loop + \fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\ted@special@encode} +% Now, let's come back to the special tokens. As we don't need the token to +% encode it (we allready know its \cs{catcode} from \cs{ted@code}, and its +% charcode is stored in the list), we first gobble it in order to prepare for +% next iteration. +% \begin{macrocode} +\newcommand\ted@special@encode{% + \afterassignment\ted@special@encode@ + \let\@let@token= } +% \end{macrocode} +% \end{macro} +% \begin{macro}{\ted@special@encode@} +% Then we encode it in two steps : first, create a control sequence with name +% \cs{ted@@}\meta{code}\meta{charcode}, where code is a digit +% denoting\footnote{I don't store the \cs{catcode} for two reasons : first, +% having a single digit is easier; second, having the true catcode would be +% useless (though it could maybe make the code more readable).} the +% \cs{catcode} of the special token, \ldots +% \begin{macrocode} +\newcommand\ted@special@encode@{% + \expandafter\ted@special@encode@@\expandafter{% + \csname ted@@\the\ted@code\ted@list@read\endcsname}} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\ted@special@encode@@} +% \begin{macro}{\ted@@special} +% \ldots then, mark this CS as a special token encoding, in order to make it +% easier to detect later, add it to the output and loop again. +% \begin{macrocode} +\newcommand*\ted@special@encode@@[1]{% + \ted@list@advance + \let#1\ted@@special + \ted@addtoks@encloop{#1}} +% \end{macrocode} +% \begin{macrocode} +\newcommand\ted@@special{\ted@@special@} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\ted@list@read} +% \begin{macro}{\ted@list@read@} +% Here we used the folowing macros in order to manage our charcode list. The +% reading one is fully expandable. +% \begin{macrocode} +\newcommand\ted@list@read{% + \expandafter\ted@list@read@\the\ted@list\@nil} +% \end{macrocode} +% \begin{macrocode} +\@ifdefinable\ted@list@read@{% + \def\ted@list@read@#1 #2\@nil{% + #1}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \begin{macro}{\ted@list@advance} +% \begin{macro}{\ted@list@advance@} +% Since it's expandable, it cannot change the list, so we need a separate +% macro to remove the first element from the list, once read. +% \begin{macrocode} +\newcommand\ted@list@advance{% + \expandafter\ted@list@advance@\the\ted@list\@nil} +% \end{macrocode} +% \begin{macrocode} +\@ifdefinable\ted@list@advance@{ + \def\ted@list@advance@#1 #2\@nil{% + \ted@list{#2}}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \subsection{Decoding} +% +% \begin{macro}{\ted@add@toks} +% Main decoding macro is \cs{ted@decode}. It is again a loop, processing the +% token list one by one. For normal tokens, things are easy as allways: just +% add them to the output, via +% \begin{macrocode} +\newcommand\ted@add@toks[1]{% + \ted@toks\expandafter{\the\ted@toks#1}} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\ted@decode} +% Encoded special tokens are easily recognized, since they were \cs{let} equal +% to \cs{ted@@special}. In order to decode it, we use the name of the CS. The +% following macro uses \LaTeX-style \cs{if} in order to avoid potential +% nesting problems when \cs{ifs} are present in the token list being +% processed. +% \begin{macrocode} +\newcommand\ted@decode[1]{% + \ifx#1\ted@@end \expandafter\@gobble\else\expandafter\@firstofone\fi{% + \ifx#1\ted@@special + \expandafter\@firstoftwo + \else + \expandafter\@secondoftwo + \fi{% + \begingroup \escapechar\m@ne \expandafter\endgroup + \expandafter\ted@decode@special\string#1\@nil + }{% + \ted@add@toks{#1}}% + \ted@decode}} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\ted@decode@special} +% The next macro should then gobble the |ted@@| part of the CS name, and use +% the last part as two numeric codes (here we use the fact that the first one +% is only a digit). +% \begin{macrocode} +\@ifdefinable\ted@decode@special{% + \begingroup\escapechar\m@ne \expandafter\endgroup\expandafter + \def\expandafter\ted@decode@special\string\ted@@#1#2\@nil{% +% \end{macrocode} +% It then prodeces according to the first code, building back the original +% token and adding it to the output. The first two kinds of tokens (macro +% parameter characters and blank spaces) are easily dealt with. +% \begin{macrocode} + \ifcase#1 + \begingroup \uccode`##=#2 \uppercase{\endgroup + \ted@add@toks{##}}% + \or + \begingroup \uccode32=#2 \uppercase{\endgroup + \ted@add@toks{ }}% + \or +% \end{macrocode} +% For begin-group and end-group characters, we have a problem, since they are +% impossible to handle individually: we can only add a \meta{balanced text} to +% the output. So, when we find a begin-group character, we just open a group +% (a real one), and start decoding again inside the group, until we find the +% correponding end-group character. Then, we enclose the local decoded list +% of tokens into the correct begin-group/end-group pair, and then add it to +% the output one group level below, using the +% \cs{expandafter}-over-\cs{endgroup} trick (essential here). +% \begin{macrocode} + \begingroup \ted@toks{}% + \uccode`{=#2 + \or + \uccode`}=#2 + \uppercase{\ted@toks\expandafter{\expandafter{\the\ted@toks}}} + \expandafter\endgroup + \expandafter\ted@add@toks\expandafter{\the\ted@toks}% + \fi}} +% \end{macrocode} +% \end{macro} +% +% \subsection{Substitution} +% +% For this part, the idea\footnote{for which I am grateful to Jean-Côme +% Charpentier, who first taught me the clever use delimited arguments (and lots +% of other wonderful things) in \nolinkurl{fr.comp.text.tex}} is to use a macro +% whose first argument is delimited with the \meta{from} string, wich outputs +% the first argument followed by the \meta{to} string, and loops. Obviously +% this macro has to be defined on the fly. All tokens lists need to be encoded +% first, and the output decoded at end. Since all this needs to happens inside +% a group (for \cs{ted@sanitize} and the marking up of special-charaters +% control sequences), remember to ``export'' \cs{ted@toks} when done. +% +% \begin{macro}{\ted@Substitude} +% The main substitution macro is as follows. Arguments are \meta{input}, +% \meta{from}, \meta{to}. \cs{ted@output} will be discussed later. +% \begin{macrocode} +\newcommand\ted@Substitute[3]{% + \begingroup \ted@sanitize + \ted@encode{#3}% + \expandafter\ted@def@subsmac\expandafter{\the\ted@toks}{#2}% + \ted@encode{#1}% + \ted@subsmac + \ted@toks\expandafter{\expandafter}% + \expandafter\ted@decode\the\ted@toks\ted@@end + \expandafter\endgroup + \expandafter\ted@output\expandafter{\the\ted@toks}} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\ted@def@subsmac} +% The actual iterative substitution macro is defined by the folowing macro, +% whose arguments are the \meta{to} string, encoded, and the plain \meta{from} +% string. +% \begin{macrocode} +\newcommand\ted@def@subsmac[2]{% + \ted@encode{#2}% + \long\expandafter\def\expandafter\ted@subsmac@loop + \expandafter##\expandafter1\the\ted@toks##2{% + \ted@add@toks{##1}% + \ifx##2\ted@@end + \expandafter\@gobble + \else + \expandafter\@firstofone + \fi{% + \ted@add@toks{#1}\ted@subsmac@loop##2}}% + \expandafter\ted@def@subsmac@\expandafter{\the\ted@toks}} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\ted@def@subsmac@} +% While we have the encoded \meta{from} string at hand, define the start-loop +% macro. +% \begin{macrocode} +\newcommand\ted@def@subsmac@[1]{% + \def\ted@subsmac{% + \ted@toks\expandafter{\expandafter}% + \expandafter\ted@subsmac@loop\the\ted@toks#1\ted@@end}} +% \end{macrocode} +% \end{macro} +% +% \subsection{Display} +% +% \begin{macro}{\ted@ShowTokens} +% In order to display the tokens one by one, we first encode the string +% \begin{macrocode} +\newcommand\ted@ShowTokens[1]{% + \begingroup \ted@sanitize + \ted@toks{#1}% + \ted@typeout{--- Begin token decompositon of:}% + \ted@typeout{\@spaces \the\ted@toks}% + \ted@encode{#1}% + \expandafter\ted@show@toks\the\ted@toks\ted@@end + \endgroup + \ted@typeout{--- End token decomposition.}} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\ted@show@toks} +% Then we proceed, allmost like decoding, iteratively, processing the encoded +% tokens one by one. We detect control sequences the same way as in +% pre-scanning. +% \begin{macrocode} +\count@\catcode\z@ \catcode\z@ 12 +\newcommand\ted@show@toks[1]{% + \ifx#1\ted@@end \expandafter\@gobble\else\expandafter\@firstofone\fi{% + \ted@toks{#1}% + \begingroup + \escapechar\if\noexpand#1^^00 \@ne \else \z@ \fi + \expandafter\ted@show@toks@\string#1\@nil + \ted@show@toks}} +\catcode\z@\count@ +% \end{macrocode} +% \end{macro} +% \begin{macro}{\ted@show@toks@} +% We stored the current token so that it can be used in the next macro, though +% previously broken by the \cs{string}, and moreover we can nest the \cs{if}s +% freely since it is hidden in a register (in case it would be a \cs{if} +% itself). The four cases are : CS representing a special token, normal CS, +% active character (since we cannot show its category with \cs{meaning}), and +% finally normal character token. +% \begin{macrocode} +\@ifdefinable\ted@show@toks@{% + \long\def\ted@show@toks@#1#2\@nil{% + \expandafter\endgroup + \ifnum`#1=\escapechar + \expandafter\ifx\the\ted@toks\ted@@special + \ted@show@special#2\@nil + \else +% \end{macrocode} +% It's time to think about the following: we are inside a group where all +% active characters were redefined, but we nonetheless want to display their +% meaning. In order to do this, the display need to actually happen after the +% current group is finished. For this we use \cs{aftergroup} (with specialized +% macro for displaying each kind of token). +% \begin{macrocode} + \aftergroup\ted@type@cs + \expandafter\aftergroup\the\ted@toks + \fi + \else \expandafter + \ifx\the\ted@toks\ted@@active + \aftergroup\ted@type@active + \expandafter\aftergroup\the\ted@toks + \else + \aftergroup\ted@type@normal + \expandafter\aftergroup\the\ted@toks + \fi + \fi}} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\ted@show@special} +% Let's begin our tour of specialized display macro with the most important +% one: \cs{ted@show@special}. Displaying the special token goes mostly the +% same way as decoding them, but is far easier, since we don't need to care +% about groups: display is done with \cs{catcode}~$12$ characters. +% \begin{macrocode} +\@ifdefinable\ted@show@special{% + \begingroup\escapechar\m@ne \expandafter\endgroup + \expandafter\def\expandafter\ted@show@special\string\ted@@#1#2\@nil{% + \ifcase#1 + \aftergroup\ted@type@hash + \or + \aftergroup\ted@type@blank + \or + \aftergroup\ted@type@bgroup + \or + \aftergroup\ted@type@egroup + \fi + \begingroup \uccode`1#2 + \uppercase{\endgroup\aftergroup1}}} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\ted@type@hash} +% \begin{macro}{\ted@type@blank} +% \begin{macro}{\ted@type@bgroup} +% \begin{macro}{\ted@type@egroup} +% \begin{macro}{\ted@type@normal} +% The four macros for special tokens are obvious. So is the macro for normal +% tokens. By the way, \cs{ted@typeout} will be discussed in the next section. +% \begin{macrocode} +\newcommand\ted@type@hash[1]{% + \ted@typeout{#1 (macro paramater character #1)}} +% \end{macrocode} +% \begin{macrocode} +\newcommand\ted@type@blank[1]{% + \ted@typeout{#1 (blank space #1)}} +% \end{macrocode} +% \begin{macrocode} +\newcommand\ted@type@bgroup[1]{% + \ted@typeout{#1 (begin-group character #1)}} +% \end{macrocode} +% \begin{macrocode} +\newcommand\ted@type@egroup[1]{% + \ted@typeout{#1 (end-group character #1)}} +% \end{macrocode} +% \begin{macrocode} +\newcommand\ted@type@normal[1]{% + \ted@typeout{#1 (\meaning#1)}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \begin{macro}{\ted@type@cs} +% \begin{macro}{\ted@type@active} +% For control sequences and active characters, we use more sophisticated +% macros. Indeed, their \cs{meaning} can be quite long, and since it is not so +% important (\pf{ted}'s work is lexical analysis, displaying the \cs{meaning} +% is just an add-on), we cut it so that lines are shorter than $80$ colons, in +% order to save our one-token-a-line presentation. +% \begin{macrocode} +\newcommand\ted@type@cs[1]{% + \ted@type@long{\string#1 (control sequence=\meaning#1}}% +% \end{macrocode} +% \begin{macrocode} +\newcommand\ted@type@active[1]{% + \ted@type@long{\string#1 (active character=\meaning#1}}% +% \end{macrocode} +% \end{macro} +% \end{macro} +% \begin{macro}{\ted@type@long} +% Lines are cut and displayed by \cs{ted@type@long}. This macro uses a loop, +% conting down how many columns remain on the current line. The input need to +% be fully expanded first, and the output is stored in \cs{ted@toks}. +% \begin{macrocode} +\newcommand\ted@type@long[1]{% + \ted@toks{}% + \ted@code72 + \edef\next{#1}% + \expandafter\ted@tl@loop\next\@nil} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\ted@tl@loop} +% The only difficult thing in this loop is to take care of space tokens. For +% this we use again our \cs{futurelet} trick: +% \begin{macrocode} +\newcommand\ted@tl@loop{% + \futurelet\@let@token + \ted@tl@loop@} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\ted@tl@loop@} +% \ldots then check what to do. +% \begin{macrocode} +\newcommand\ted@tl@loop@{% + \ifx\@let@token\@nil + \let\next\ted@tl@finish + \else + \advance\ted@code\m@ne + \ifnum\ted@code<\z@ + \let\next\ted@tl@finish + \else + \ifx\@let@token\@sptoken + \let\next\ted@tl@space + \else + \let\next\ted@tl@add + \fi + \fi + \fi + \next} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\ted@tl@add} +% \begin{macro}{\ted@tl@space} +% Normal characters are just grabbed and added without care, and spaces are +% gobbled with a special macro which also add a space to the output. +% \begin{macrocode} +\newcommand*\ted@tl@add[1]{% + \ted@toks\expandafter{\the\ted@toks #1}% + \ted@tl@loop} +% \end{macrocode} +% \begin{macrocode} +\@ifdefinable\ted@tl@space{% + \expandafter\def\expandafter\ted@tl@space\space{% + \ted@tl@add{ }}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \begin{macro}{\ted@tl@finish} +% When the end has been reached (either because a \cs{@nil} was encountered or +% because the line is allmost full), it's time to actually display the result. +% We add \cs{ETC.} at the end when the full \cs{meaning} isn't displayed. +% \begin{macrocode} +\@ifdefinable\ted@tl@finish{% + \def\ted@tl@finish#1\@nil{% + \ifnum\ted@code<\z@ + \ted@typeout{\the\ted@toks\string\ETC.)} + \else + \ted@typeout{\the\ted@toks)} + \fi}} +% \end{macrocode} +% \end{macro} +% +% \subsection{User macros} +% +% \begin{macro}{\ted@typeout} +% Since we just discussed display, let's see the related user commands. Output +% is done with +% \begin{macrocode} +\newcommand\ted@typeout{% + \immediate\write\ted@outfile} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\ShowTokensOnline} +% \begin{macro}{\ShowTokensLogonly} +% allowing the user to choose between online display, or log output. Default +% is online. +% \begin{macrocode} +\newcommand\ShowTokensOnline{% + \let\ted@outfile\@unused} +% \end{macrocode} +% \begin{macrocode} +\newcommand\ShowTokensLogonly{% + \let\ted@outfile\m@ne} +% \end{macrocode} +% \begin{macrocode} +\ShowTokensOnline +% \end{macrocode} +% \end{macro} +% \end{macro} +% \begin{macro}{\ShowTokens} +% \begin{macro}{\ted@ShowTokens@exp} +% The user macro for showing tokens is a simple call to the internal macro, +% just expanding its argument once in its stared form. +% \begin{macrocode} +\newcommand\ShowTokens{% + \@ifstar{\ted@ShowTokens@exp}{\ted@ShowTokens}} +% \end{macrocode} +% \begin{macrocode} +\newcommand\ted@ShowTokens@exp[1]{% + \expandafter\ted@ShowTokens\expandafter{#1}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\Substitute} +% \begin{macro}{\ted@Subs@star} +% Now, the user macro for substitution. First, check how many stars there are, +% if any, and set \cs{ted@subs@cmd} accordingly. +% \begin{macrocode} +\newcommand\Substitute{% + \@ifstar + {\ted@Subs@star} + {\let\ted@Subs@cmd\ted@Substitute \ted@Subs}} +% \end{macrocode} +% \begin{macrocode} +\newcommand\ted@Subs@star{% + \@ifstar + {\let\ted@Subs@cmd\ted@Subs@exp@iii \ted@Subs} + {\let\ted@Subs@cmd\ted@Subs@exp@i \ted@Subs}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \begin{macro}{\ted@Subs@exp@i} +% \begin{macro}{\ted@Subs@exp@iii} +% Here are the intermediate macros that expand either the first or all three +% arguments before calling \cs{ted@Substitute}. +% \begin{macrocode} +\newcommand\ted@Subs@exp@i{% + \expandafter\ted@Substitute\expandafter} +% \end{macrocode} +% \begin{macrocode} +\newcommand\ted@Subs@exp@iii[3]{% + \begingroup + \toks0{\ted@Substitute}% + \toks2\expandafter{#1}% + \toks4\expandafter{#2}% + \toks6\expandafter{#3}% + \xdef\ted@Subs@cmd{\the\toks0{\the\toks2}{\the\toks4}{\the\toks6}}% + \endgroup + \ted@Subs@cmd} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \begin{macro}{\ted@Subs} +% Now, the last macro checks and process the optional argument. Here we set +% \cs{ted@output}, which will be used at the end of \cs{ted@Substitute}. +% \begin{macrocode} +\newcommand\ted@Subs[1][\ted@toks]{% + \def\ted@output{#1}% + \ted@Subs@cmd} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\ted@output} +% Finally set a default \cs{ted@output} for advanced users who may want +% to use \cs{ted@Substitute} directly. +% \begin{macrocode} +\let\ted@output\ted@toks +% \end{macrocode} +% \end{macro} +% +% \bigskip +% \begin{center}\Large +% That's all folks!\\ +% Happy \TeX ing! +% \end{center} +% +% \Finale +% +% \iffalse +%</package> +%<*batchfile> +% \fi +\typeout{**************************************************} +\typeout{*} +\typeout{* To finish the installation you have to move the} +\typeout{* following file into a directory searched by TeX:} +\typeout{*} +\typeout{* \space\space\space\space ted.sty} +\typeout{*} +\typeout{* Documentation is in ted.dvi or ted.pdf} +\typeout{*} +\typeout{* To produce french documentation, run} +\typeout{* \space\space \space\space (pdf)latex ted-fr.drv} +\typeout{*} +\typeout{* Happy TeXing!} +\typeout{*} +\typeout{**************************************************} +% \iffalse +%</batchfile> +% \fi +\endinput |