From e0c6872cf40896c7be36b11dcc744620f10adf1d Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Mon, 2 Sep 2019 13:46:59 +0900 Subject: Initial commit --- macros/latex/contrib/ted/README | 51 ++ macros/latex/contrib/ted/ted-fr.pdf | Bin 0 -> 61561 bytes macros/latex/contrib/ted/ted.dtx | 1416 +++++++++++++++++++++++++++++++++++ macros/latex/contrib/ted/ted.pdf | Bin 0 -> 143368 bytes macros/latex/contrib/ted/ted.sty | 360 +++++++++ 5 files changed, 1827 insertions(+) create mode 100644 macros/latex/contrib/ted/README create mode 100644 macros/latex/contrib/ted/ted-fr.pdf create mode 100644 macros/latex/contrib/ted/ted.dtx create mode 100644 macros/latex/contrib/ted/ted.pdf create mode 100644 macros/latex/contrib/ted/ted.sty (limited to 'macros/latex/contrib/ted') diff --git a/macros/latex/contrib/ted/README b/macros/latex/contrib/ted/README new file mode 100644 index 0000000000..71f7c3598a --- /dev/null +++ b/macros/latex/contrib/ted/README @@ -0,0 +1,51 @@ + + The ted package + + A (primitive) token list editor + + Manuel P\'egouri\'e-Gonnard + +Presentation +------------ + +Just like sed is a stream editor, ted is a token list editor. Actually, it is +not as powerful as sed, but its main feature is that it really works with +tokens, not only characters. + +The ted package provides two user macros: \Substitute and \ShowTokens. The first +one is maybe the most useful: it performs substitutions in token lists (even +inside braces). The second displays each token of the list (one per line) with +its catcode (in the list, not just the current one), and can be useful for +debugging or for TeX learners. + +The ted package is designed to work well even if strange tokens (that is, +unusual (charcode, catcode) pairs or tokens with a confusing meaning) occur in +the list. + +Contents +-------- + +ted.sty: the package itself +ted.pdf: the (English) documentation and commented code +ted-fr.pdf: the French documentation + +ted.dtx: single source for both documentations and package + +Version info +------------ + +2007-12-09 v1.0 First release. +2007-12-12 v1.01 Fixed a stupid bug. +2008-03-02 v1.05 - Fixed a bug when trying to substitute AA in a + string ending with A. Also removed a spurious space. + - Added an occurrence counter. +2008-03-07 v1.06 - Fixed a bug in \ShowTokens with active spaces. + - Slightly expanded the doc (examples). + +License +------- + +This material is subject to the LaTeX Project Public License. See +http://www.ctan.org/tex-archive/help/Catalogue/licenses.lppl.html for the +details of that license. + diff --git a/macros/latex/contrib/ted/ted-fr.pdf b/macros/latex/contrib/ted/ted-fr.pdf new file mode 100644 index 0000000000..d49e62c6ef Binary files /dev/null and b/macros/latex/contrib/ted/ted-fr.pdf differ diff --git a/macros/latex/contrib/ted/ted.dtx b/macros/latex/contrib/ted/ted.dtx new file mode 100644 index 0000000000..4916436ade --- /dev/null +++ b/macros/latex/contrib/ted/ted.dtx @@ -0,0 +1,1416 @@ +% +% \iffalse /!\ this file contains non-ascii -- encoding is utf-8 /!\ +% +% ted package by Manuel P\'egouri\'e-Gonnard +% ----------------------------------------------------------- +% +% 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} +% +%\NeedsTeXFormat{LaTeX2e} +%\ProvidesPackage{ted} +%<*package> +% \fi +% \ProvidesFile{ted.dtx} + [2008/03/07 v1.06 \space a token list editor \space (mpg)] +% \iffalse +% +% \fi +% \CheckSum{816} +% \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 +% +%<*batchfile> +\input docstrip +\keepsilent +\preamble + +ted package by Manuel P\string\'egouri\string\'e-Gonnard % + +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}}} +% +%<*gobble> +\endgroup +% +%<*driver|pilote> +\documentclass[oneside, a4paper]{ltxdoc} +\usepackage[utf8]{inputenc} +\usepackage[T1]{fontenc} +\usepackage{lmodern} +\usepackage[babel=true, expansion=false]{microtype} +\usepackage{fixltx2e} +\expandafter\newif\csname iffrenchdoc\endcsname % cachez ce if... +%\frenchdoctrue +% +%<*gobble> +\iffrenchdoc +% +%<*pilote> +\usepackage[lmargin=4.5cm, rmargin=3cm]{geometry} +\OnlyDescription +\usepackage[english, french]{babel} +\FrenchFootnotes \AddThinSpaceBeforeFootnotes +\newcommand*\eng[1]{\emph{\foreignlanguage{english}{#1}}} +\usepackage[bookmarks=false]{hyperref} +\hypersetup{% + pdftitle=L'extension ted + pdfsubject=Un éditeur de liste de lexèmes pour LaTeX2e} +% +%<*gobble> +\else +% +%<*driver> +\AlsoImplementation +\usepackage[english]{babel} +\usepackage[bookmarks=true, bookmarksnumbered=true, bookmarksopen=true, + bookmarksopenlevel=2]{hyperref} +\hypersetup{% + pdftitle=The ted package, + pdfsubject=A token list editor for LaTex2e} +\settowidth\MacroIndent{\rmfamily\scriptsize 000\ } +\setlength\MacroTopsep{0pt} +\setcounter{tocdepth}{1} +\usepackage[nohints, english]{minitoc} +\mtcsetpagenumbers{secttoc}{off} +\mtcsetrules{secttoc}{off} +\mtcsetdepth{secttoc}{3} +\setlength{\stcindent}{0pt} +\mtcsetfont{secttoc}{subsection}{\normalfont} +\newcommand\tocwithmini{% + \dosecttoc[n] + \setcounter{tocdepth}{1}\tableofcontents + \setcounter{tocdepth}{3}\faketableofcontents + } +% +%<*gobble> +\fi +% +%<*driver|pilote> +\hypersetup{% + colorlinks=true, linkcolor=black, urlcolor=black, + pdfauthor=Manuel Pégourié-Gonnard} +\newcommand\pf{\textsf} +\newcommand\optstar{\meta{$*$}} +\newcommand\topcs[1]{\texorpdfstring{\cs{#1}}{#1}} +\begin{document} + \DocInput{ted.dtx} +\end{document} +% +%<*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@elzevir.fr}{mpg@elzevir.fr}} +% \date{\fileversion\ (\filedate)} +% +% \maketitle +% \iffrenchdoc\else \tocwithmini \fi +% +% \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 powerful 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 occurrence 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. +% +% \subsection{\topcs{Substitute}} +% +% \DescribeMacro{\Substitute} +% La syntaxe de \cs{Substitute} est la suivante. +% \begin{quote} +% \cs{Substitute}\optstar\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 occurrence +% 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 optionnel 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 optionnel. 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. Exemples : +% +% \begin{quote} +% |\Substitute{a#b#c}{a}{A}|\\ +% |\newtoks\vostoks \Substitute[\vostoks]{a#b#c}{a}{A}|\\ +% |\Substitute[\def\votremacro]{a#b#c}{#}{##}| +% \end{quote} +% +% 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 premier argument obligatoire +% avant de commencer à travailler dessus. Ceci vous évite d'avoir à +% placer vous-même des \cs{expandafter}, surtout dans le cas ou vous +% souhaitez utiliser l'argument optionnel. Cette fois, l'usage est +% inversé par rapport à l'argument optionnel : 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. Par exemple : +% +% \begin{quote} +% |\def\abc{abccdef} \newtoks\abctoks \abctoks{abc}|\\ +% |\Substitute{\abc}{cc}{C} %| donne |\abc|\\ +% |\Substitute*{\abc}{cc}{C} %| donne |abCdef|\\ +% |\Substitute*{\the\abctoks}{cc}{C} %| aussi +% \end{quote} +% +% 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 plupart du +% temps. Seul un cas particulier mérite sans doute une petite 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}. +% +% Enfin, il peut être utile de savoir qu'une fois que \cs{Substitute} a +% fini son travail, le nombre de substitutions effectuées est accessible +% dans le registre \cs{ted@count}. On peut ainsi s'en servir pour +% compter, par exemple, le nombre d'espaces (donc approximativement de +% mots) dans un texte, en faisant semblant d'opérer une substitution +% dessus. +% +% \subsection{\topcs{ShowTokens}} +% +% \DescribeMacro{\ShowTokens} +% La syntaxe de \cs{ShowTokens} est la suivante. +% \begin{quote} +% \cs{ShowTokens}\optstar\marg{liste} +% \end{quote} +% Dans sa forme simple, \cs{ShowTokens} se contente d'afficher la liste +% de lexèmes, un par ligne. Pour les lexèmes de type caractère, +% l'affichage comporte le caractère lui-même, suivi de l'indication de +% son code de catégorie sous la forme utilisée par \cs{show}. Je +% rappelle ci-dessous (table~\ref{cc}) pour la commodité du lecteur les +% différents \cs{catcode}s possibles dans une liste de lexème, ainsi +% qu'un exemple et la façon dont ils sont affichés par \cs{ShowTokens}. +% +% \begin{table} +% \begin{tabular}{rcl} +% 1 & |{| & |(begin-group character {)|\\ +% 2 & |}| & |(end-group character })|\\ +% 3 & |$| & |(math shift character $)|\\ +% 4 & |&| & |(alignment tab character &)|\\ +% 6 & |#| & |(macro parameter character #)|\\ +% 7 & |^| & |(superscript character ^)|\\ +% 8 & |_| & |(subscript character _)|\\ +% 10 & | | & |(blank space )|\\ +% 11 & |a| & |(the letter a)|\\ +% 12 & |0| & |(the character 0)|\\ +% 13 & |~| & |(active character=macro:->\nobreakspace {})|\\ +% \end{tabular} +% \caption{Les \cs{catcode} : code, exemple, et description.}\label{cc} +% \end{table} +% +% Pour les séquence de contrôles et les caractè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. Il s'agit bien +% sûr du sens courant au moment de l'appel à \cs{ShowTokens}. +% +% \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. Imaginons par +% exemple que vous vouliez vérifier, après la définition d'une macro, +% que vous avez bien les bons \cs{catcode}s : +% +% \begin{quote} +% |\begingroup \uccode`\~=32 \uppercase{\endgroup|\\ +% | \def\macro{1~2}}|\\ +% |\ShowTokens*{\macro} %| donne à l'écran : [...]\\ +% |1 (the character 1)|\\ +% | (active character=macro:-> )|\\ +% |2 (the character 2)| +% \end{quote} +% +% \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 à) des macros intimes de \pf{ted}, +% c'est-à-dire celles 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 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. +% +% \subsection{\topcs{Substitute}} +% +% \DescribeMacro{\Substitute} +% The syntax of \cs{Substitute} is as follows. +% \begin{quote} +% \cs{Substitute}\optstar\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 occurrence 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 +% improperly placed hash signs (that is, macro parameter tokens). +% +% \begin{quote} +% |\Substitute{a#b#c}{a}{A}|\\ +% |\newtoks\yourtoks \Substitute[\yourtoks]{a#b#c}{a}{A}|\\ +% |\Substitute[\def\yourmacro]{a#b#c}{#}{##}| +% \end{quote} +% +% 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. +% +% \begin{quote} +% |\def\abc{abccdef} \newtoks\abctoks \abctoks{abc}|\\ +% |\Substitute{\abc}{cc}{C} %| gives |\abc|\\ +% |\Substitute*{\abc}{cc}{C} %| gives |abCdef|\\ +% |\Substitute*{\the\abctoks}{cc}{C} %| too +% \end{quote} +% +% The two-starred form is also meant to avoid you trouble with +% development. It expands its three mandatory arguments once before +% executing. 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}. +% +% Finally, it may be useful to know that, after \cs{Subsitute} finished +% its job, it leaves the number of replaced occurrences in the count +% register \cs{ted@count}. This can be used, for example, to count +% spaces (hence words) in a text, by making a fake substitution on it. +% +% \subsection{\topcs{ShowTokens}} +% +% \DescribeMacro{\ShowTokens} +% The syntax of \cs{ShowTokens} is as follows. +% \begin{quote} +% \cs{ShowTokens}\optstar\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-friendly form. For the sake of readability, +% here is (table~\ref{cc}) a reminder of the possible \cs{catcode}s, +% with an exemple and the way \cs{ShowTokens} displays them. +% +% \begin{table} +% \begin{tabular}{rcl} +% 1 & |{| & |(begin-group character {)|\\ +% 2 & |}| & |(end-group character })|\\ +% 3 & |$| & |(math shift character $)|\\ +% 4 & |&| & |(alignment tab character &)|\\ +% 6 & |#| & |(macro parameter character #)|\\ +% 7 & |^| & |(superscript character ^)|\\ +% 8 & |_| & |(subscript character _)|\\ +% 10 & | | & |(blank space )|\\ +% 11 & |a| & |(the letter a)|\\ +% 12 & |0| & |(the character 0)|\\ +% 13 & |~| & |(active character=macro:->\nobreakspace {})|\\ +% \end{tabular} +% \caption{Possible \cs{catcode}s: code, example, and description.}\label{cc} +% \end{table} +% +% For control sequences and active characters, it +% also prints their current \cs{meaning} as a bonus, or only the +% beginning of it (ending with \cs{ETC.}) if it is more than one line +% ($80$ columns) long. +% +% \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. +% +% \begin{quote} +% |\begingroup \uccode`\~=32 \uppercase{\endgroup|\\ +% | \def\macro{1~2}}|\\ +% |\ShowTokens*{\macro} %| prints on screen: [...]\\ +% |1 (the character 1)|\\ +% | (active character=macro:-> )|\\ +% |2 (the character 2)| +% \end{quote} +% +% \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 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 they 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.} cannot +% be grabbed as the non-delimited 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 proceeds 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 +% non-delimited 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 proceeds in two passes: in the first, we try and detect the +% special tokens, storing their character codes for later use, then do +% the actual encoding in the last pass. +% +% Decoding also processes the tokens one by one, and is simpler, since +% special cases are already detected. There is, however, a trick with +% groups since, when we encounter 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$ characters. Finally, +% the substitution part uses a macro with delimited argument, defined on +% the fly. +% +% The code is divided as follows. +% \par\vspace{-0.5\baselineskip} +% \secttoc +% \par\vspace{-0.5\baselineskip} +% +% \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@} +\@ifdefinable\ted@count{\newcount\ted@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 almost 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 which 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 order to detect them easily later, for +% example 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 steps 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 whether 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 already \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 whether 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 following 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 already 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 following 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 +% always: 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 proceeds 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 corresponding 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, which 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-characters 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 following +% 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\@firstoftwo + \else + \expandafter\@secondoftwo + \fi{% + \expandafter\ted@remove@nil\the\ted@toks + }{% + \global\advance\ted@count\@ne + \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{% + \global\ted@count\z@ + \ted@toks\expandafter{\expandafter}% + \expandafter\ted@subsmac@loop\the\ted@toks\ted@@nil#1\ted@@end}} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\ted@remove@nil} +% You probably noticed the \cs{ted@@nil} after \cs{ted@toks} in the +% above definition. This is to avoid problems while trying to +% substitute something like ``AA'' in a list ending with ``A'' (new in +% v1.05). We need to remove it when finished. +% \begin{macrocode} +\@ifdefinable\ted@remove@nil{% + \long\def\ted@remove@nil#1\ted@@nil{% + \ted@toks{#1}}} +% \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 decomposition 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, almost like decoding, iteratively, processing the +% encoded tokens one by one. We detect control sequences the same way as +% in pre-scanning. For our tests (and also for use in +% \cs{ted@show@toks@}) we embed |#1| into \cs{ted@toks} in order to +% nest the \cs{if}s without fear. There are four cases that need to be +% typeset in different ways : active character, CS that represent a +% special token, normal CS, normal character token. However, we need to +% do one more test to detect the character tokens whose charcode is +% $32$, before we apply \cs{string} to it in order to check if it was a +% control sequence. +% \begin{macrocode} +\count@\catcode\z@ \catcode\z@ 12 +\newcommand\ted@show@toks[1]{% + \ted@toks{#1}\expandafter + \ifx\the\ted@toks\ted@@end \else\expandafter + \ifx\the\ted@toks\ted@@active +% \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@active + \expandafter\aftergroup\the\ted@toks + \else + \if\expandafter\noexpand\the\ted@toks\@sptoken + \aftergroup\ted@type@normal + \expandafter\aftergroup\the\ted@toks + \else + \begingroup + \escapechar\if\noexpand#1^^00 \@ne \else \z@ \fi + \expandafter\expandafter\expandafter\ted@show@toks@ + \expandafter\string\the\ted@toks\@nil + \fi + \fi + \expandafter\ted@show@toks + \fi} +\catcode\z@\count@ +% \end{macrocode} +% \end{macro} +% \begin{macro}{\ted@show@toks@} +% Now test the remaining cases : special CS, normal CS, or normal +% character. +% \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 + \aftergroup\ted@type@cs + \expandafter\aftergroup\the\ted@toks + \fi + \else + \aftergroup\ted@type@normal + \expandafter\aftergroup\the\ted@toks + \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 parameter 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, counting 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 almost 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 +% +%<*batchfile> +% \fi +% \begingroup\obeyspaces +% \typeout{*****************************************************} +% \typeout{* *} +% \typeout{* To finish the installation you have to move the *} +% \typeout{* following file into a directory searched by TeX: *} +% \typeout{* *} +% \typeout{* ted.sty *} +% \typeout{* *} +% \typeout{* Documentation is in ted.dvi or ted.pdf *} +% \typeout{* *} +% \typeout{* To produce the french documentation, run *} +% \typeout{* (pdf)latex ted-fr.drv *} +% \typeout{* *} +% \typeout{* Happy TeXing! *} +% \typeout{* *} +% \typeout{*****************************************************} +% \endgroup +% \iffalse +% +% \fi +\endinput diff --git a/macros/latex/contrib/ted/ted.pdf b/macros/latex/contrib/ted/ted.pdf new file mode 100644 index 0000000000..247e70e9e8 Binary files /dev/null and b/macros/latex/contrib/ted/ted.pdf differ diff --git a/macros/latex/contrib/ted/ted.sty b/macros/latex/contrib/ted/ted.sty new file mode 100644 index 0000000000..3ef652ff82 --- /dev/null +++ b/macros/latex/contrib/ted/ted.sty @@ -0,0 +1,360 @@ +%% +%% This is file `ted.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% ted.dtx (with options: `package') +%% +%% ted package by Manuel P\'egouri\'e-Gonnard +%% This is a generated file. See ted.dtx for license information. +%% +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{ted} + [2008/03/07 v1.06 \space a token list editor \space (mpg)] +\@ifdefinable\ted@toks{\newtoks\ted@toks} +\@ifdefinable\ted@list{\let\ted@list\toks@} +\@ifdefinable\ted@code{\let\ted@code\count@} +\@ifdefinable\ted@count{\newcount\ted@count} +\newcommand\ted@encloop{% + \futurelet\@let@token + \ted@encloop@} +\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} +\newcommand\ted@@end{\ted@@end@} +\@ifdefinable\ted@gobble@end{% + \def\ted@gobble@end\ted@@end{}} +\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@ +\newcommand\ted@@active{\ted@@active@} +\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} +\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} +\newcommand\ted@gobble@encloop{% + \afterassignment\ted@encloop + \let\@let@token= } +\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@ +\newcommand\ted@check@space{% + \futurelet\@let@token + \ted@check@space@} +\newcommand\ted@check@space@{% + \ifcat\@let@token\@sptoken + \endgroup + \ted@addlist{32}% + \expandafter\ted@gobble@encloop + \else + \expandafter\ted@list@special + \fi} +\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} +\newcommand*\ted@addlist[1]{% + \ted@list\expandafter{\the\ted@list#1 }} +\newcommand\ted@addtoks@encloop[1]{% + \ted@toks\expandafter{\the\ted@toks#1}% + \ted@encloop} +\newcommand\ted@special@out{% + \ifnum\ted@list@read=\m@ne + \ted@list@advance + \expandafter\ted@cs@clean + \else + \expandafter\ted@special@encode + \fi} +\newcommand\ted@cs@clean[1]{% + \expandafter\ted@add@toks{#1}% + \expandafter\ted@cscl@loop\string#1 \@nil} +\@ifdefinable\ted@cscl@loop{% + \def\ted@cscl@loop#1 {% + \futurelet\@let@token + \ted@cscl@loop@}} +\newcommand\ted@cscl@loop@{% + \ifx\@let@token\@nil + \expandafter\ted@gobble@encloop + \else + \ted@list@advance + \expandafter\ted@cscl@loop + \fi} +\newcommand\ted@special@encode{% + \afterassignment\ted@special@encode@ + \let\@let@token= } +\newcommand\ted@special@encode@{% + \expandafter\ted@special@encode@@\expandafter{% + \csname ted@@\the\ted@code\ted@list@read\endcsname}} +\newcommand*\ted@special@encode@@[1]{% + \ted@list@advance + \let#1\ted@@special + \ted@addtoks@encloop{#1}} +\newcommand\ted@@special{\ted@@special@} +\newcommand\ted@list@read{% + \expandafter\ted@list@read@\the\ted@list\@nil} +\@ifdefinable\ted@list@read@{% + \def\ted@list@read@#1 #2\@nil{% + #1}} +\newcommand\ted@list@advance{% + \expandafter\ted@list@advance@\the\ted@list\@nil} +\@ifdefinable\ted@list@advance@{ + \def\ted@list@advance@#1 #2\@nil{% + \ted@list{#2}}} +\newcommand\ted@add@toks[1]{% + \ted@toks\expandafter{\the\ted@toks#1}} +\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}} +\@ifdefinable\ted@decode@special{% + \begingroup\escapechar\m@ne \expandafter\endgroup\expandafter + \def\expandafter\ted@decode@special\string\ted@@#1#2\@nil{% + \ifcase#1 + \begingroup \uccode`##=#2 \uppercase{\endgroup + \ted@add@toks{##}}% + \or + \begingroup \uccode32=#2 \uppercase{\endgroup + \ted@add@toks{ }}% + \or + \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}} +\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}} +\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\@firstoftwo + \else + \expandafter\@secondoftwo + \fi{% + \expandafter\ted@remove@nil\the\ted@toks + }{% + \global\advance\ted@count\@ne + \ted@add@toks{#1}\ted@subsmac@loop##2}}% + \expandafter\ted@def@subsmac@\expandafter{\the\ted@toks}} +\newcommand\ted@def@subsmac@[1]{% + \def\ted@subsmac{% + \global\ted@count\z@ + \ted@toks\expandafter{\expandafter}% + \expandafter\ted@subsmac@loop\the\ted@toks\ted@@nil#1\ted@@end}} +\@ifdefinable\ted@remove@nil{% + \long\def\ted@remove@nil#1\ted@@nil{% + \ted@toks{#1}}} +\newcommand\ted@ShowTokens[1]{% + \begingroup \ted@sanitize + \ted@toks{#1}% + \ted@typeout{--- Begin token decomposition 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.}} +\count@\catcode\z@ \catcode\z@ 12 +\newcommand\ted@show@toks[1]{% + \ted@toks{#1}\expandafter + \ifx\the\ted@toks\ted@@end \else\expandafter + \ifx\the\ted@toks\ted@@active + \aftergroup\ted@type@active + \expandafter\aftergroup\the\ted@toks + \else + \if\expandafter\noexpand\the\ted@toks\@sptoken + \aftergroup\ted@type@normal + \expandafter\aftergroup\the\ted@toks + \else + \begingroup + \escapechar\if\noexpand#1^^00 \@ne \else \z@ \fi + \expandafter\expandafter\expandafter\ted@show@toks@ + \expandafter\string\the\ted@toks\@nil + \fi + \fi + \expandafter\ted@show@toks + \fi} +\catcode\z@\count@ +\@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 + \aftergroup\ted@type@cs + \expandafter\aftergroup\the\ted@toks + \fi + \else + \aftergroup\ted@type@normal + \expandafter\aftergroup\the\ted@toks + \fi}} +\@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}}} +\newcommand\ted@type@hash[1]{% + \ted@typeout{#1 (macro parameter character #1)}} +\newcommand\ted@type@blank[1]{% + \ted@typeout{#1 (blank space #1)}} +\newcommand\ted@type@bgroup[1]{% + \ted@typeout{#1 (begin-group character #1)}} +\newcommand\ted@type@egroup[1]{% + \ted@typeout{#1 (end-group character #1)}} +\newcommand\ted@type@normal[1]{% + \ted@typeout{#1 (\meaning#1)}} +\newcommand\ted@type@cs[1]{% + \ted@type@long{\string#1 (control sequence=\meaning#1}}% +\newcommand\ted@type@active[1]{% + \ted@type@long{\string#1 (active character=\meaning#1}}% +\newcommand\ted@type@long[1]{% + \ted@toks{}% + \ted@code72 + \edef\next{#1}% + \expandafter\ted@tl@loop\next\@nil} +\newcommand\ted@tl@loop{% + \futurelet\@let@token + \ted@tl@loop@} +\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} +\newcommand*\ted@tl@add[1]{% + \ted@toks\expandafter{\the\ted@toks #1}% + \ted@tl@loop} +\@ifdefinable\ted@tl@space{% + \expandafter\def\expandafter\ted@tl@space\space{% + \ted@tl@add{ }}} +\@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}} +\newcommand\ted@typeout{% + \immediate\write\ted@outfile} +\newcommand\ShowTokensOnline{% + \let\ted@outfile\@unused} +\newcommand\ShowTokensLogonly{% + \let\ted@outfile\m@ne} +\ShowTokensOnline +\newcommand\ShowTokens{% + \@ifstar{\ted@ShowTokens@exp}{\ted@ShowTokens}} +\newcommand\ted@ShowTokens@exp[1]{% + \expandafter\ted@ShowTokens\expandafter{#1}} +\newcommand\Substitute{% + \@ifstar + {\ted@Subs@star} + {\let\ted@Subs@cmd\ted@Substitute \ted@Subs}} +\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}} +\newcommand\ted@Subs@exp@i{% + \expandafter\ted@Substitute\expandafter} +\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} +\newcommand\ted@Subs[1][\ted@toks]{% + \def\ted@output{#1}% + \ted@Subs@cmd} +\let\ted@output\ted@toks +\endinput +%% +%% End of file `ted.sty'. -- cgit v1.2.3