summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2015-03-04 00:12:30 +0000
committerKarl Berry <karl@freefriends.org>2015-03-04 00:12:30 +0000
commit54e0055672245bb7a9d7875052b7c2b47038ba76 (patch)
treea16d0031f6073e6a485013223b01862ce9b0e702
parentd34e62f6c5fec68a9b3cb118a1d0bfcee6302726 (diff)
multiexpand (3mar15)
git-svn-id: svn://tug.org/texlive/trunk@36427 c570f23f-e606-0410-a88d-b1316a301751
-rw-r--r--Master/texmf-dist/doc/latex/multiexpand/README28
-rw-r--r--Master/texmf-dist/doc/latex/multiexpand/multiexpand.pdfbin284328 -> 375421 bytes
-rw-r--r--Master/texmf-dist/source/latex/multiexpand/multiexpand.dtx411
-rw-r--r--Master/texmf-dist/source/latex/multiexpand/multiexpand.ins71
-rw-r--r--Master/texmf-dist/tex/latex/multiexpand/multiexpand.sty76
5 files changed, 361 insertions, 225 deletions
diff --git a/Master/texmf-dist/doc/latex/multiexpand/README b/Master/texmf-dist/doc/latex/multiexpand/README
index 062ceda37ba..160664a37ee 100644
--- a/Master/texmf-dist/doc/latex/multiexpand/README
+++ b/Master/texmf-dist/doc/latex/multiexpand/README
@@ -5,35 +5,27 @@ Variations on the `\expandafter` TeX primitive
See http://www.latex-project.org/lppl.txt
Every TeX programmer knows `\expandafter`, and how messy it can become
-when trying to expand several times a very deeply hidden token. For
+when trying to expand several times a very deeply hidden token. For
example, say we want to expand `\C` four times before `\A` and `\B` in
`\A\B\C`. The traditional approach would be to insert 15 `\expandafter`
-before `\A` and the same number before `\B`. This package allows the two
-simpler codes
+before `\A` and the same number before `\B`. With this package one can
+do either of the following
\expandafter\A\expandafter\B\romannumeral\multiexpand{4}\C
-
-or
-
\expandafter\A\romannumeral\multiexpandafter{4}\B\C
-In one step of expansion (triggered by the `\expandafter`'s), the
-sequence `\romannumeral\multiexpand{4}` expands the following token 4
-times, whereas `\romannumeral\multiexpandafter{4}` expands the token
-after that 4 times.
-
-The code behaves with braces as `\expandafter` would. Another example is
+In one step of expansion (triggered by the `\expandafter`'s),
+`\romannumeral\multiexpand{4}` expands the following token 4 times,
+whereas `\romannumeral\multiexpandafter{4}` expands the token after
+that 4 times. For more complicated cases, use `\MultiExpandAfter`:
\MultiExpandAfter{2}\a\MultiExpandAfter{3}{%
- \MultiExpandAfter{10}\b\MultiExpandAfter{10}\c\d},
+ \MultiExpandAfter{10}\b\MultiExpandAfter{10}\c\d}
-which expands `\d` 10 times, then `\c` 8 times, then `\b` once.
-The whole process will only take two steps of expansion.
+expands `\d` 10 times, then `\c` 8 times, then `\b` once.
+The whole process only takes two steps of expansion.
The package can be built from the file `multiexpand.dtx' by running
pdflatex multiexpand.dtx
pdflatex multiexpand.dtx
- pdflatex multiexpand-example.tex
-
-The last step is optional: it runs a series of tests.
diff --git a/Master/texmf-dist/doc/latex/multiexpand/multiexpand.pdf b/Master/texmf-dist/doc/latex/multiexpand/multiexpand.pdf
index b6b2599f27a..9a87dcd6da0 100644
--- a/Master/texmf-dist/doc/latex/multiexpand/multiexpand.pdf
+++ b/Master/texmf-dist/doc/latex/multiexpand/multiexpand.pdf
Binary files differ
diff --git a/Master/texmf-dist/source/latex/multiexpand/multiexpand.dtx b/Master/texmf-dist/source/latex/multiexpand/multiexpand.dtx
index 02740fc75f3..11f36e608ec 100644
--- a/Master/texmf-dist/source/latex/multiexpand/multiexpand.dtx
+++ b/Master/texmf-dist/source/latex/multiexpand/multiexpand.dtx
@@ -10,93 +10,159 @@ Variations on the `\expandafter` TeX primitive
See http://www.latex-project.org/lppl.txt
Every TeX programmer knows `\expandafter`, and how messy it can become
-when trying to expand several times a very deeply hidden token. For
+when trying to expand several times a very deeply hidden token. For
example, say we want to expand `\C` four times before `\A` and `\B` in
`\A\B\C`. The traditional approach would be to insert 15 `\expandafter`
-before `\A` and the same number before `\B`. This package allows the two
-simpler codes
+before `\A` and the same number before `\B`. With this package one can
+do either of the following
\expandafter\A\expandafter\B\romannumeral\multiexpand{4}\C
-
-or
-
\expandafter\A\romannumeral\multiexpandafter{4}\B\C
-In one step of expansion (triggered by the `\expandafter`'s), the
-sequence `\romannumeral\multiexpand{4}` expands the following token 4
-times, whereas `\romannumeral\multiexpandafter{4}` expands the token
-after that 4 times.
-
-The code behaves with braces as `\expandafter` would. Another example is
+In one step of expansion (triggered by the `\expandafter`'s),
+`\romannumeral\multiexpand{4}` expands the following token 4 times,
+whereas `\romannumeral\multiexpandafter{4}` expands the token after
+that 4 times. For more complicated cases, use `\MultiExpandAfter`:
\MultiExpandAfter{2}\a\MultiExpandAfter{3}{%
- \MultiExpandAfter{10}\b\MultiExpandAfter{10}\c\d},
-
-which expands `\d` 10 times, then `\c` 8 times, then `\b` once.
-The whole process will only take two steps of expansion.
+ \MultiExpandAfter{10}\b\MultiExpandAfter{10}\c\d}
+expands `\d` 10 times, then `\c` 8 times, then `\b` once.
+The whole process only takes two steps of expansion.
The package can be built from the file `multiexpand.dtx' by running
pdflatex multiexpand.dtx
pdflatex multiexpand.dtx
- pdflatex multiexpand-example.tex
-The last step is optional: it runs a series of tests.
%</readme>
-%<*example>
+%<*lvt>
+ \input regression-test.tex\relax
+ \START
+ \AUTHOR{Bruno Le Floch}
+%<lvt002> \let\numexpr\relax
\input multiexpand.sty\relax
- % |\expandonce| redefines its argument |#1| as |#1| expanded once.
- \long\gdef\expandonce#1{%
- \long\edef#1{\unexpanded\expandafter\expandafter\expandafter{#1}}}
- % Commands that expand to each other, to count how many times things
- % were expanded.
- \def\0{\1} \def\1{\2} \def\2{\3} \def\3{\4} \def\4{\5}
- \def\5{\6} \def\6{\7} \def\7{\8} \def\8{\9} \def\9{\0x}
+
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ % Introduce commands that expand to each other, to count how many times
+ % things were expanded.
+ \OMIT
+ \def\i{}
+ \def\v{\i\i\i\i}
+ \def\x{\i\i\i\i\v}
+ \def\l{\i\i\i\i\v\x\x\x\x}
+ \def\c{\i\i\i\i\v\x\x\x\x\l}
+ \def\d{\i\i\i\i\v\x\x\x\x\l\c\c\c\c}
+ \def\m{\i\i\i\i\v\x\x\x\x\l\c\c\c\c\d}
+ \TIMO
+
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% We test |\MultiExpand|, which needs two expansions. In particular, we see
- % that the implementation is reasonably quick, and we get the $2011$-th
- % expansion of |\0|.
- \long\gdef\a{\MultiExpand{2011}\0} \expandonce\a \expandonce\a
- \long\gdef\b{\1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%
- xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%
- xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
- \ifx\a\b\message{Correct! }\else\show\WRONG\fi
- %
+ % that the implementation is reasonably quick, and we get the $2345$-th
+ % expansion of |\m\m\m\m|.
+ % 4000-2345 = 1655 = mdclv
+ \TEST{MultiExpand many times (vlcdm)}{%
+ \toks0\expandafter\expandafter\expandafter{\MultiExpand{2345}\m\m\m\m}%
+ \TYPE{\the\toks0.}%
+ }
+
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Test |\MultiExpandAfter|, two expansions to get the specified expansion.
- % The results also show that the expansion happens in the expected order.
- \long\gdef\a{%
- \MultiExpandAfter{27}\0% note that we get \5xx (25=27-2).
- \MultiExpandAfter{14}\0% note that we get \2x (12=14-2).
- \MultiExpandAfter{38}\0\0}% note that we get \8xxx... no "-2".
- \expandonce\a \expandonce\a
- \long\gdef\b{\0\5xx\2x\8xxx}
- \ifx\a\b\message{Correct! }\else\show\WRONG\fi
- %
- % For comparison, the "Hello World!" example
+ % The results indirectly show that expansions happen in the expected order.
+ % 100 = c
+ % 100-(27-2) = 75 = lxxv
+ % 100-(14-2) = 88 = lxxxviii
+ % 100-38 = 62 = lxii
+ \TEST{MultiExpandAfter chain (c vxxl iiivxxxl iixl)}{%
+ \toks0\expandafter\expandafter\expandafter{%
+ \MultiExpandAfter{27}\c
+ \MultiExpandAfter{14}\c
+ \MultiExpandAfter{38}\c\c}%
+ \TYPE{\the\toks0.}%
+ }
+
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ % Test the order of expansion. The example was given in the original
+ % question that led to writing this package. For the record, this
+ % package (at some point) used 32 |\expandafter| to do the expansion
+ % in the right order, which was better than other approaches; however
+ % this counting ignores the large overheads due to other primitives.
+ \OMIT
\def\a#1.{#1}
\def\b#1:{#1.}
\def\c#1,{#1:}
\def\d{Hello world!,}
- \edef\foo{\unexpanded\MultiExpandAfter{3}{%
+ \TIMO
+ %
+ \TEST{MultiExpandAfter order}{%
+ \toks0\MultiExpandAfter{3}{%
\MultiExpandAfter{3}\a
\MultiExpandAfter{3}\b
\MultiExpandAfter{1}\c
- \d}}
- \def\fooB{Hello world!}
- \ifx\foo\fooB\message{Correct! }\else\show\WRONG\fi
- % now uses 32 \expandafters, slightly better than Hendrik's solution (however, we should count the overhead with all the \csname and friends). The other example on which Hendrik was optimizing, namely, expanding seven tokens once each in the reverse order, takes 74 \expandafter:
- \def\a{a} \def\b{b} \def\c{c} \def\d{d}
- \def\e{e} \def\f{f} \def\g{g}
- \begingroup\tracingall\tracingonline=0\relax
- \xdef\foo{\unexpanded\MultiExpandAfter{2}{%
+ \d}%
+ \TYPE{\the\toks0}%
+ }
+
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ % The other example from the same question (expanding seven tokens once
+ % each in the reverse order) takes 74 \expandafter.
+ \OMIT
+ \def\b.{.b} \def\c.{.c} \def\d.{.d}
+ \def\e.{.e} \def\f.{.f} \def\g.{.g}
+ \TIMO
+ %
+ \TEST{MultiExpandAfter order (2)}{%
+ \toks0\MultiExpandAfter{2}{%
\MultiExpandAfter3\a \MultiExpandAfter3\b
\MultiExpandAfter3\c \MultiExpandAfter3\d
- \MultiExpandAfter3\e \MultiExpandAfter1\f\g}}
- \endgroup
- % Some experimentation tells me that the number of \expandafter is roughly 5 times the sum of the arguments of the various \MultiExpandAfter.
- \csname bye\endcsname
- \csname stop\endcsname
-%</example>
+ \MultiExpandAfter3\e \MultiExpandAfter1\f\g.}%
+ \TYPE{\the\toks0}%
+ }
+
+ \END
+%</lvt>
+%<*tlg>
+This is a generated file for the l3build validation system.
+Don't change this file in any respect.
+%% \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 \~}
+%%
+Author: Bruno Le Floch
+(multiexpand.sty)
+============================================================
+TEST 1: MultiExpand many times (vlcdm)
+============================================================
+\v \l \c \d \m .
+============================================================
+============================================================
+TEST 2: MultiExpandAfter chain (c vxxl iiivxxxl iixl)
+============================================================
+\c \v \x \x \l \i \i \i \v \x \x \x \l \i \i \x \l .
+============================================================
+============================================================
+TEST 3: MultiExpandAfter order
+============================================================
+Hello world!
+============================================================
+============================================================
+TEST 4: MultiExpandAfter order (2)
+============================================================
+\a .bcdefg
+============================================================
+%</tlg>
%<*internal>
\fi
\def\nameofplainTeX{plain}
@@ -119,7 +185,7 @@ See http://www.latex-project.org/lppl.txt
\endpreamble
\postamble
-Copyright (C) 2011-2013 by Bruno Le Floch <blflatex@gmail.com>
+Copyright (C) 2011-2015 by Bruno Le Floch <blflatex@gmail.com>
This work may be distributed and/or modified under the
conditions of the LaTeX Project Public License (LPPL), either
@@ -147,12 +213,14 @@ and the derived files multiexpand.ins,
\usedir{source/latex/multiexpand}
\generate{
\file{\jobname.ins}{\from{\jobname.dtx}{install}}
+ \file{\jobname 001.lvt}{\from{\jobname.dtx}{lvt}}
+ \file{\jobname 002.lvt}{\from{\jobname.dtx}{lvt,lvt002}}
}
-\usedir{source/latex/multiexpand}
+\nopreamble\nopostamble
\generate{
- \file{\jobname-example.tex}{\from{\jobname.dtx}{example}}
+ \file{\jobname 001.tlg}{\from{\jobname.dtx}{tlg}}
+ \file{\jobname 002.tlg}{\from{\jobname.dtx}{tlg}}
}
-\nopreamble\nopostamble
\usedir{doc/latex/multiexpand}
\generate{
\file{README.md}{\from{\jobname.dtx}{readme}}
@@ -167,6 +235,7 @@ and the derived files multiexpand.ins,
%<*driver>
\documentclass[12pt]{ltxdoc}
\usepackage[T1]{fontenc}
+\usepackage{hologo}
\usepackage{multiexpand}
\usepackage[margin=4cm]{geometry}
\usepackage{hyperref}
@@ -177,9 +246,9 @@ and the derived files multiexpand.ins,
%</driver>
% \fi
%
-% \CheckSum{60}
+% \CheckSum{127}
%
-% \def\fileversion{1.1} \def\filedate{2013/01/08}
+% \def\fileversion{v1.3} \def\filedate{2015/03/03}
%\title{\texttt{multiexpand}\\
% Trigger multiple expansions \\ in one expansion step\thanks{This file
% describes version \fileversion, last revised \filedate.}}
@@ -193,6 +262,8 @@ and the derived files multiexpand.ins,
% \tableofcontents
% \changes{v1.0}{2011/02/15}{First version with documentation}
% \changes{v1.1}{2013/01/08}{Version submitted to CTAN}
+% \changes{v1.2}{2013/01/09}{Use less expandafter for large arguments}
+% \changes{v1.2}{2013/01/09}{Change ME prefix to multiexpand}
%
% \section{Two user commands}
%
@@ -218,40 +289,22 @@ and the derived files multiexpand.ins,
% In some cases, one needs to achieve the same effect in \emph{one} step
% only. For this, we use the first expansion of |\MultiExpand|, which
% is |\romannumeral| |\multiexpand|, or of |\MultiExpandAfter|, which is
-% |\romannumeral| |\multiexpandafter|). Expanding |\romannumeral|
+% |\romannumeral| |\multiexpandafter|. In detail, expanding |\romannumeral|
% |\multiexpand{|$n$|}| once expands the following token $n$ times, and
% similarly for |\romannumeral| |\multiexpandafter{|$n$|}|.
%
% These are especially useful when we want to expand several times a
-% very specific token which is buried behind many others. Example:
-% expanding the following code twice,
+% very specific token which is buried behind many others. For instance,
+% expanding the following code once
% \begin{verbatim}
-% \MultiExpand{3}\expandafter\macroA\expandafter\macroB%
+% \expandafter\macroA\expandafter\macroB
% \romannumeral\multiexpandafter{4}\macroC\macroD
% \end{verbatim}
-% will expand |\macroD| $4$ times, then will expand |\macroA| $2=3-1$
-% additional times.
+% will expand |\macroD| $4$ times before the three other macros.
%
% Note: as we mentionned, this breaks for $n=0$. But in this case, consider
% using |\expandafter\empty|, or a variant thereof.
%
-% \section{How it works}
-%
-% The primitive |\romannumeral| expands what follows fully until it builds
-% a full number. It will remove exactly one trailing space if the first
-% non-digit token is a space. So if we expand the construction
-% |\romannumeral0\expandafter\space| once, then |\romannumeral| will see
-% the |0|, and expand |\expandafter|: it cannot yet be sure that it won't
-% find another digit afterwards. This expands the next token once. In other
-% words, |\romannumeral0\expandafter\space| behaves as if it was not there.
-%
-% This is how we end our loop. Namely, |\multiexpand|\marg{$n$} checks
-% if $n<2$, in which case it stops with |0\expandafter\space|. If $n\geq 2$,
-% then it simply expands to |\multiexpand|\marg{$n-1$}, plus the relevant
-% |\expandafter|s meant to expand the next token once.\footnote{Note
-% to self: Possible optimization: put three \cs{expandafter} rather than
-% one at the end, to to two expansions at once.}
-%
% \section{Implementation}
%\StopEventually{\PrintChanges\PrintIndex}
% \begin{macrocode}
@@ -259,47 +312,175 @@ and the derived files multiexpand.ins,
% \end{macrocode}
%
% We work inside a group, to change the catcode of |@|. So we will only
-% do |\gdef|s. We also define a macro |\ME@use|.
+% do |\gdef|s. Note that this code can be read several times with no
+% issue; no need to bother to check whether it was already read or not.
% \begin{macrocode}
\begingroup
-\catcode`\@=11\relax%
-\gdef\ME@use#1{#1}%
+\catcode `\@=11
+% \end{macrocode}
+%
+% \subsection{Common to the \hologo{eTeX} and non-\hologo{eTeX} cases}
+%
+% For the ``lazy'', who do not want to use |\romannumeral|, we provide
+% |\MultiExpand| and |\MultiExpandAfter|, simple shorthands. A drawback
+% is that they require two steps of expansion rather than only one.
+% \begin{macrocode}
+\gdef \MultiExpand {\romannumeral \multiexpand }
+\gdef \MultiExpandAfter {\romannumeral \multiexpandafter }
+% \end{macrocode}
+%
+% \subsection{Without \hologo{eTeX}'s \cs{numexpr}}
+% \changes{v1.3}{2015/03/03}{Support TeX with no numexpr}
+%
+% No need for the usual |\begingroup\expandafter\endgroup| to prevent
+% |\numexpr| from being set to |\relax|, because we are already in a
+% group.
+% \begin{macrocode}
+\expandafter\ifx\csname numexpr\endcsname\relax
% \end{macrocode}
%
-% |\MultiExpand| and |\MultiExpandAfter| are simply shorthands to avoid
-% typing |\romannumeral|. Drawback: they require two steps of expansion
-% rather than only one.
+% A helper.
% \begin{macrocode}
-\gdef\MultiExpand{\romannumeral\multiexpand}%
-\gdef\MultiExpandAfter{\romannumeral\multiexpandafter}%
+\long\gdef\multiexpand@gobble#1{}
% \end{macrocode}
%
-% The |\romannumeral| is stopped by |0\space|. We insert the relevant
-% |\expandafter| to do the work.
+% The user commands |\multiexpand| and |\multiexpandafter|, to be used
+% after |\romannumeral|. They only differ a little bit.
% \begin{macrocode}
-\xdef\ME@endroman#1{0\noexpand\expandafter\space}%
-\xdef\ME@endroman@after#1{0\noexpand\expandafter\space\noexpand\expandafter}%
+\gdef\multiexpand{\multiexpand@aux\multiexpand@}
+\gdef\multiexpandafter{\multiexpand@aux\multiexpand@after}
% \end{macrocode}
+% The user commands receives a number, and to accept various forms of
+% numbers we hit it with |\number|. If it is non-positive, stop the
+% |\romannumeral| expansion with |0| and a space. Otherwise, reverse
+% the number, to make it easy to subtract~$1$.
+% \begin{macrocode}
+\long \gdef \multiexpand@aux #1#2%
+ {\expandafter \multiexpand@test \number #2;#1}
+\long \gdef \multiexpand@test #1;#2%
+ {%
+ \ifnum #1>0
+ \multiexpand@reverse #1{?\multiexpand@reverse@end }?;;#2%
+ \fi
+ 0 %
+ }
+% \end{macrocode}
+% The macro |\multiexpand@reverse| puts characters from the number one
+% by one (as~|#1|) after the semicolon, to reverse the number. After
+% the last digit, |#1| is |{?\multiexpand@reverse@end}|. The question
+% mark is removed by |\multiexpand@gobble|, and the |reverse@end|
+% macro cleans up. In particular, one should not forget to close the
+% conditional using~|#5|, which is the trailing~|\fi|. At this stage,
+% |#4| is the function that distinguishes |\multiexpand| from
+% |\multiexpand@after|, and |#3| is the reversed
+% number. \begin{macrocode}
+\gdef \multiexpand@reverse #1#2;%
+ {\multiexpand@gobble #1\multiexpand@reverse #2;#1}
+\gdef \multiexpand@reverse@end #1;?#2#3;#4#50
+ {#5\multiexpand@iterate #41#3;}
+% \end{macrocode}
+% The macro |\multiexpand@iterate| applies a \meta{function} a certain
+% number of times to what follows in the input stream. It expects to
+% receive \meta{function} \meta{nines} |1|\meta{reversed number}|;|.
+% The argument \meta{nines}, made entirely of the digit~|9|, is used to
+% compute carries when subtracting~$1$, and is initally empty. As a
+% concrete example, after |\multiexpand{302}| the successive
+% calls to |\multiexpand@iterate| would go as follows.
+% \begin{verbatim}
+% \multiexpand@iterate \multiexpand@ 1203;
+% \multiexpand@iterate \multiexpand@ 1103;
+% \multiexpand@iterate \multiexpand@ 1003;
+% \multiexpand@iterate \multiexpand@ 9 103;
+% \multiexpand@iterate \multiexpand@ 99 13;
+% \multiexpand@iterate \multiexpand@ 1992;
+% \multiexpand@iterate \multiexpand@ 1892;
+% \multiexpand@iterate \multiexpand@ 1792;
+% \end{verbatim}
+% Note in particular how carries are done in several steps. The details
+% are left as an exercise to the reader. The most common case is when
+% |#2| is empty and |#3| is a non-zero digit. Then |\number| is
+% expanded, triggering |\ifcase| which shifts |#3| by one unit, and |#1|
+% takes care of expanding the tokens are required by |\multiexpand| or
+% |\multiexpandafter|. If |#3| is~$0$, then |\multiexpand@zero| is
+% called, closing the conditional with |#1|, and iterating, this time
+% with a non-empty \meta{nines}, which are the argument |#2| of a new
+% call to |\multiexpand@iterate|. Those \meta{nines} are put back into
+% the number by |\multiexpand@iterate|, unless the next significant
+% digit is also $0$, in which case |\multiexpand@zero| is called again,
+% until finding a non-zero digit; at each step, one more $9$ is added to
+% the \meta{nines}. If all digits are zero, we reach |;| this way, and
+% end, after cleaning up.
+% \begin{macrocode}
+\gdef \multiexpand@iterate #1#21#3%
+ {%
+ \ifx ;#3\multiexpand@end \fi
+ \ifx 0#3\multiexpand@zero \fi
+ \expandafter \multiexpand@iterate
+ \expandafter #1%
+ \number 1#2%
+ \ifcase #3 \or 0\or 1\or 2\or 3\or 4\or 5\or 6\or 7\or 8\fi
+ #1%
+ }
+\gdef\multiexpand@zero#1#2\number1#3\ifcase#4\fi#5%
+ {#1\multiexpand@iterate#59#31}
+\gdef\multiexpand@end#1#2\ifcase#3\fi#4{#10 }
+% \end{macrocode}
+% Finally, the two different expansion commands.
+% \begin{macrocode}
+\gdef\multiexpand@#1;{#1\expandafter;}
+\gdef\multiexpand@after#1;{#1\expandafter;\expandafter}
+% \end{macrocode}
+%
+% \subsection{With \hologo{eTeX}}
%
% \begin{macrocode}
-\long\gdef\multiexpand#1{%
- \ifnum#1<2 \expandafter \ME@endroman%
- \else \expandafter \ME@use%
- \fi%
- {\expandafter \multiexpand \expandafter {%
- \number\numexpr#1-1\expandafter}}%
-}%
+\else
+% \end{macrocode}
+%
+% With \hologo{eTeX}, everything is much easier, since the engine knows
+% how to subtract~$1$.
+%
+% The main looping macros expect their arguments as an integer followed
+% by a semicolon. As long as the argument is at least~$2$, decrement
+% it, and expand what follows. Once the argument is~$1$ (or less: the
+% macros are not meant to handle that case), call |\multiexpand@end| to clean up
+% and stop looping.
+% \begin{macrocode}
+\gdef \multiexpand@ #1;%
+ {%
+ \ifnum #1<2 \multiexpand@end \fi
+ \expandafter \multiexpand@
+ \the \numexpr #1-1\expandafter ;%
+ }
+\gdef \multiexpand@after #1;%
+ {%
+ \ifnum #1<2 \multiexpand@end \fi
+ \expandafter \multiexpand@after
+ \the \numexpr #1-1\expandafter ;\expandafter
+ }
+% \end{macrocode}
+% The looping macros are used within an overarching |\romannumeral|
+% expansion, which we end with a |0| and a space, as well as the
+% appropriate |\expandafter|. Here, |#1| is |\fi| which needs to remain
+% to close the conditional, |#2| is |\expandafter|, and there is a
+% trailing |\expandafter| in the case of |\multiexpand@after|.
+% \begin{macrocode}
+\gdef \multiexpand@end #1#2#3;{#10#2 }
+% \end{macrocode}
+% Finally, user commands, used as |\romannumeral| |\multiexpand(after)|.
+% Those evaluate their argument, and pass it to |\multiexpand@(after)|.
+% The argument might contain |\par| tokens (who knows)
+% \begin{macrocode}
+\long \gdef \multiexpand #1%
+ {\expandafter \multiexpand@ \the \numexpr #1;}
+\long \gdef \multiexpandafter #1%
+ {\expandafter \multiexpand@after \the \numexpr #1;}
% \end{macrocode}
-% Almost identical definitions for expanding after...
+%
% \begin{macrocode}
-\long\gdef\multiexpandafter#1{%
- \ifnum#1<2 \expandafter\ME@endroman@after%
- \else \expandafter \ME@use%
- \fi%
- {\expandafter \multiexpandafter \expandafter {%
- \number\numexpr#1-1\expandafter}\expandafter}%
-}%
+\fi
% \end{macrocode}
+%
% Close the group.
% \begin{macrocode}
\endgroup
diff --git a/Master/texmf-dist/source/latex/multiexpand/multiexpand.ins b/Master/texmf-dist/source/latex/multiexpand/multiexpand.ins
deleted file mode 100644
index a6d2341e1ee..00000000000
--- a/Master/texmf-dist/source/latex/multiexpand/multiexpand.ins
+++ /dev/null
@@ -1,71 +0,0 @@
-%%
-%% This is file `multiexpand.ins',
-%% generated with the docstrip utility.
-%%
-%% The original source files were:
-%%
-%% multiexpand.dtx (with options: `install')
-%% ----------------------------------------------------------------
-%% multiexpand --- trigger multiple expansions in one expansion step.
-%% E-mail: blflatex@gmail.com
-%% Released under the LaTeX Project Public License v1.3c or later
-%% See http://www.latex-project.org/lppl.txt
-%% ----------------------------------------------------------------
-%%
-\input docstrip.tex
-\keepsilent
-\askforoverwritefalse
-\preamble
-----------------------------------------------------------------
-multiexpand --- trigger multiple expansions in one expansion step.
-E-mail: blflatex@gmail.com
-Released under the LaTeX Project Public License v1.3c or later
-See http://www.latex-project.org/lppl.txt
-----------------------------------------------------------------
-
-\endpreamble
-\postamble
-
-Copyright (C) 2011-2013 by Bruno Le Floch <blflatex@gmail.com>
-
-This work may be distributed and/or modified under the
-conditions of the LaTeX Project Public License (LPPL), either
-version 1.3c of this license or (at your option) any later
-version. The latest version of this license is in the file:
-
-http://www.latex-project.org/lppl.txt
-
-This work is "maintained" (as per LPPL maintenance status) by
-Bruno Le Floch.
-
-This work consists of the file multiexpand.dtx
-and the derived files multiexpand.ins,
- multiexpand.pdf and
- multiexpand.sty.
-
-\endpostamble
-\usedir{tex/latex/multiexpand}
-\generate{
- \file{\jobname.sty}{\from{\jobname.dtx}{package}}
-}
-\endbatchfile
-%%
-%% Copyright (C) 2011-2013 by Bruno Le Floch <blflatex@gmail.com>
-%%
-%% This work may be distributed and/or modified under the
-%% conditions of the LaTeX Project Public License (LPPL), either
-%% version 1.3c of this license or (at your option) any later
-%% version. The latest version of this license is in the file:
-%%
-%% http://www.latex-project.org/lppl.txt
-%%
-%% This work is "maintained" (as per LPPL maintenance status) by
-%% Bruno Le Floch.
-%%
-%% This work consists of the file multiexpand.dtx
-%% and the derived files multiexpand.ins,
-%% multiexpand.pdf and
-%% multiexpand.sty.
-%%
-%%
-%% End of file `multiexpand.ins'.
diff --git a/Master/texmf-dist/tex/latex/multiexpand/multiexpand.sty b/Master/texmf-dist/tex/latex/multiexpand/multiexpand.sty
index e69945c3c9f..23ef936a250 100644
--- a/Master/texmf-dist/tex/latex/multiexpand/multiexpand.sty
+++ b/Master/texmf-dist/tex/latex/multiexpand/multiexpand.sty
@@ -13,29 +13,63 @@
%% ----------------------------------------------------------------
%%
\begingroup
-\catcode`\@=11\relax%
-\gdef\ME@use#1{#1}%
-\gdef\MultiExpand{\romannumeral\multiexpand}%
-\gdef\MultiExpandAfter{\romannumeral\multiexpandafter}%
-\xdef\ME@endroman#1{0\noexpand\expandafter\space}%
-\xdef\ME@endroman@after#1{0\noexpand\expandafter\space\noexpand\expandafter}%
-\long\gdef\multiexpand#1{%
- \ifnum#1<2 \expandafter \ME@endroman%
- \else \expandafter \ME@use%
- \fi%
- {\expandafter \multiexpand \expandafter {%
- \number\numexpr#1-1\expandafter}}%
-}%
-\long\gdef\multiexpandafter#1{%
- \ifnum#1<2 \expandafter\ME@endroman@after%
- \else \expandafter \ME@use%
- \fi%
- {\expandafter \multiexpandafter \expandafter {%
- \number\numexpr#1-1\expandafter}\expandafter}%
-}%
+\catcode `\@=11
+\gdef \MultiExpand {\romannumeral \multiexpand }
+\gdef \MultiExpandAfter {\romannumeral \multiexpandafter }
+\expandafter\ifx\csname numexpr\endcsname\relax
+\long\gdef\multiexpand@gobble#1{}
+\gdef\multiexpand{\multiexpand@aux\multiexpand@}
+\gdef\multiexpandafter{\multiexpand@aux\multiexpand@after}
+\long \gdef \multiexpand@aux #1#2%
+ {\expandafter \multiexpand@test \number #2;#1}
+\long \gdef \multiexpand@test #1;#2%
+ {%
+ \ifnum #1>0
+ \multiexpand@reverse #1{?\multiexpand@reverse@end }?;;#2%
+ \fi
+ 0 %
+ }
+\gdef \multiexpand@reverse #1#2;%
+ {\multiexpand@gobble #1\multiexpand@reverse #2;#1}
+\gdef \multiexpand@reverse@end #1;?#2#3;#4#50
+ {#5\multiexpand@iterate #41#3;}
+\gdef \multiexpand@iterate #1#21#3%
+ {%
+ \ifx ;#3\multiexpand@end \fi
+ \ifx 0#3\multiexpand@zero \fi
+ \expandafter \multiexpand@iterate
+ \expandafter #1%
+ \number 1#2%
+ \ifcase #3 \or 0\or 1\or 2\or 3\or 4\or 5\or 6\or 7\or 8\fi
+ #1%
+ }
+\gdef\multiexpand@zero#1#2\number1#3\ifcase#4\fi#5%
+ {#1\multiexpand@iterate#59#31}
+\gdef\multiexpand@end#1#2\ifcase#3\fi#4{#10 }
+\gdef\multiexpand@#1;{#1\expandafter;}
+\gdef\multiexpand@after#1;{#1\expandafter;\expandafter}
+\else
+\gdef \multiexpand@ #1;%
+ {%
+ \ifnum #1<2 \multiexpand@end \fi
+ \expandafter \multiexpand@
+ \the \numexpr #1-1\expandafter ;%
+ }
+\gdef \multiexpand@after #1;%
+ {%
+ \ifnum #1<2 \multiexpand@end \fi
+ \expandafter \multiexpand@after
+ \the \numexpr #1-1\expandafter ;\expandafter
+ }
+\gdef \multiexpand@end #1#2#3;{#10#2 }
+\long \gdef \multiexpand #1%
+ {\expandafter \multiexpand@ \the \numexpr #1;}
+\long \gdef \multiexpandafter #1%
+ {\expandafter \multiexpand@after \the \numexpr #1;}
+\fi
\endgroup
%%
-%% Copyright (C) 2011-2013 by Bruno Le Floch <blflatex@gmail.com>
+%% Copyright (C) 2011-2015 by Bruno Le Floch <blflatex@gmail.com>
%%
%% This work may be distributed and/or modified under the
%% conditions of the LaTeX Project Public License (LPPL), either