On avoiding the intended (but unwanted) effect of \outer
Jim Diamond
jim.diamond at acadiau.ca
Fri Oct 18 19:15:19 CEST 2019
On Fri, Oct 18, 2019 at 17:26 (+0100), David Carlisle wrote:
> On Fri, 18 Oct 2019 at 17:15, Taylor, P <P.Taylor at rhul.ac.uk> wrote:
>> David Carlisle wrote:
>>> You could save yourself some bytes, and some expansion steps.
>>> \edef \imagebox #1{\expandafter\noexpand\csname newbox\endcsname #1\setbox #1}
>>> David
>> Confused (as always), David. Your definition is 77 characters, mine is
>> 56. I assume that the "bytes saved" must therefore be in TeX's
>> internal memory, but we have for quite some time not been restricted to
>> 640kB,
> You got a new machine?
>> so are there any real-world situations in which saving those few
>> bytes (and some expansion steps) is more important that writing clear,
>> simple, didactic code ?
> I wouldn't say anything with `\csname` in it counts as clear simple
> or didactic,
I might agree. But I think anything with \expandafter\noexpand ups
the lack of clarity considerably.
<snip>
> By far the clearest and simplest version would be to repeat the
> one-line definition of \newbox without \outer, then just use \newbox
> directly or use a format that has done that for you already:-)
To that end, below is something I found wandering around the net a long
time ago. It gives and \unouter macro which, ummm, unouters a given
macro.
I'll let everyone decide just how unclear this is. Purely for amusement.
Jim
% unouter.tex - remove the concept of \outer from plain TeX
% By Eamonn McManus Nov 88. This file is not copyrighted.
% This macro removes the outerness of the control sequence \csname#1\endcsname
% by copying it to \csname un*#1\endcsname and then defining
% \csname#1\endcsname to be a macro that expands to that. For example,
% after \unouter{proclaim}, we have: \proclaim=macro:->\un*proclaim .
% and \un*proclaim=\outer macro:->[original definition of \proclaim] .
% It would be nice if we could avoid this extra level, but I know of no way
% of doing that short of writing the \meaning to a file and reading that in
% again (yeuch).
\def\unouter#1{\toks0=\expandafter{\csname un*#1\endcsname}%
\edef\next{\let\the\toks0=}\expandafter\next\csname#1\endcsname
\expandafter\edef\csname#1\endcsname{\the\toks0}}
% In the case where the macro has no parameter text, we can unouter it
% directly by putting its expansion into a token list and redefining it
% in terms of that expansion.
\def\simpunouter#1{%
\toks0=\expandafter\expandafter\expandafter{\csname#1\endcsname}%
\expandafter\edef\csname#1\endcsname{\the\toks0}}
% ^^L is defined as \outer\par
\let^^L=\par
% Change everything else defined as \outer.
\simpunouter{newcount} \simpunouter{newdimen} \simpunouter{newskip}
\simpunouter{newmuskip} \simpunouter{newbox} \simpunouter{newtoks}
\simpunouter{newread} \simpunouter{newwrite} \simpunouter{newfam}
\simpunouter{+} \simpunouter{bye}
\unouter{newhelp} \unouter{newif} \unouter{beginsection} \unouter{proclaim}
% \unouter no longer needed, and remove the offending primitive!
\let\unouter=\undefined \let\simpunouter=\undefined \let\outer=\relax
\endinput
More information about the texhax
mailing list