An answer which does not rely on colors and allows verbatim text.
\catcode 64 11
\newif\if@inSO@
\def\ShowOff{\afterassignment\ShowOff@\setbox\z@\hbox}
\def\ShowOff@{\@inSO@true\aftergroup\ShowOff@@}
\def\ShowOff@@{\hskip\wd\z@}
\def\ShowOn{\if@inSO@\expandafter\ShowOn@\fi}
\def\ShowOn@#{\egroup\bgroup\aftergroup\ShowOn@@\let\next= }
\def\ShowOn@@{\ShowOff\bgroup}
\catcode 64 12
abcdefghijklmnop
coffin
abc\ShowOff{defg\ShowOn{hi\ShowOff{jk}lm}n}op
\ShowOn{co\ShowOff{f\ShowOn{f}i}n}
\end
How does \phantom
work? It stores the text in a box, then creates an empty box with the same width, height and depth. In a similar way, I'll collect the text that should be hidden in box 0, and produce a horizontal space of the same width as that box. All text that is to be displayed is typeset directly.
Let us analyse for example \ShowOff{abc}
First, it becomes
\afterassignment\ShowOff@ \setbox\z@\hbox{abc}
TeX remembers \ShowOff@
for use after the next assignment, namely \setbox
. The placement of the "after assignment" token in the case of \setbox
is a little bit tricky; in our case it ends up after the opening brace following \hbox
. Ignore \@inSO@true
for the moment. \aftergroup\ShowOff@@
will place \ShowOff@@
as soon as the box that is being build ends. This macro, in turn, inserts a horizontal skip of the size of the box.
Now, \ShowOn
cancels this hiding by ending the box of \ShowOff
early, namely with the \egroup
in \ShowOn@
. The horizontal skip is then inserted there. We can then typeset the argument of \ShowOn
, and resume hiding afterwards. I could have defined \def\ShowOn@#1{\egroup#1\ShowOff\bgroup}
, but this grabs the argument early, forbidding verbatim. Instead, I used \aftergroup
again: the argument of \ShowOn
comes as a group, {...}
. Somehow, we want to insert \aftergroup\ShowOn@@
after the opening brace. Open a brace (\bgroup
), and remove the one that the user put (\let\next=
).
I still have to explain the @inSO@
switch. If \ShowOn
appears outside any \ShowOff
command, it should just do nothing to its argument. Otherwise, it acts as described in the previous paragraph.
EDIT: I tried to add support for math mode below (didn't incorporate it above because the macros become ugly).
\catcode`@=11
\def\ShowOff
{%
\v@true\h@true
\ifmmode
\expandafter\mathpalette\expandafter\ShowOff@math
\else
\afterassignment\ShowOff@\setbox\z@\hbox
\fi
}
\def\ShowOff@{\let\ShowOn\ShowOn@\aftergroup\finph@nt}
\long\def\ShowOff@math#1{%
\setbox\z@\hbox\bgroup$\m@th #1%
\bgroup
\aftergroup\ShowOff@math@
\long\def\ShowOn##1{\egroup##1\ShowOff@math#1\bgroup}%
\let\next= }
\def\ShowOff@math@{$\egroup\finph@nt}
\let\ShowOn\relax
\def\ShowOn@#{\egroup\bgroup\aftergroup\ShowOn@@\let\next= }
\def\ShowOn@@{\ShowOff\bgroup}
\catcode`@=12
% Tests.
$abcdefg^h_{ijkl}mnop$ $co^{ffi}n$
$abc\ShowOff{defg\ShowOn{^h_{i\ShowOff{jk}l}m}n}op$
$\ShowOn{co^{\ShowOff{f\ShowOn{f}i}}n}$
abcdefghijklmnop coffin
abc\ShowOff{defg\ShowOn{hi\ShowOff{jk}lm}n}op
\ShowOn{co\ShowOff{f\ShowOn{f}i}n}
\bye
\documentclass
and the appropriate packages so that those trying to help don't have to recreate it.\def\showOff{} \def\showOn{}
and\bye
. Not everyone uses plain TeX so it takes time to get to this point (well at least for me).