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