How to implement \text in plain tex?
Really in plain you just have to use
\hbox{hello world}
in amsmath
(or more exactly amstext
) \text
is defined to use \mathchoice
and use different size text is subscripts etc, however plain tex has no real font size changing commands so there is, by default, nothing comparable you can do.
If you restrict to \rm
then that font is set up at different sizes in \fam0
so you could do
\def\textrm#1{\mathchoice
{\hbox{\the\textfont0 #1}}
{\hbox{\the\textfont0 #1}}
{\hbox{\the\scriptfont0 #1}}
{\hbox{\the\scriptscriptfont0 #1}}}
$$\textrm{one two} x^{\textrm{one two}^{\textrm{one two}}}$$
\bye
You can use opmac
(which I recommend anyway if you insist in using plain TeX):
\input opmac
\def\text#1{%
\relax
\ifmmode
\mathchoice
{\hbox{#1}}
{\hbox{#1}}
{\hbox{\typoscale[700/]\relax#1}}
{\hbox{\typoscale[500/]\relax#1}}%
\else
\hbox{#1}%
\fi
}
$$
a\text{a}_{a\text{a}_{a\text{a}}}
$$
$$
a+b=b+a\text{ is a {\it nice\/} property}
$$
$$
\scriptstyle a+b=b+a\text{ is a {\it nice\/} property}
$$
$$
\scriptscriptstyle a+b=b+a\text{ is a {\it nice\/} property}
$$
\bye
Just for the fun of it, let me try describing what your macros do.
\def\text#1{\begingroup\rm\testing#1\endtest}
{\escapechar=-1\xdef\endtest{\string\\endtest}}
\def\testing#1#2{\ifx#2\endtest\let\next=\endgroup\else\let\next=\testing\fi%
{\catcode`\|=10\ifcat#1|\hskip.5em\else#1\fi}\next #2}
First \text
is defined to absorb its argument and return the token list
\begingroup\rm\testing<argument>\endtesting
The macro \testing
is defined to have two arguments. If the second argument is \endtest
, the control sequence \next
is defined to be \endgroup
else it is defined to be \testing
, which starts up a recursion. Then
{\catcode`\|=10\ifcat#1|\hskip.5em\else#1\fi}
is done, where #1
stands for the first token (or contents of braced group) following \testing
. The test \ifcat#1|
will not succeed if #1
is a space for two reasons: spaces are ignored when TeX is looking for an undelimited argument, so #1
will never be a space token; second reason, the test will succeed when #1
is a single token of category code 12, which is the category code of |
at definition's time.
Thus you get a space when a character such as .
(catcode 12) follows (and the character is ignored), or the character otherwise, if it is a letter. If #1
is the contents of a braced group, then, well, anything can happen. Finally \next
is executed, and #2
is reinserted. This is the reason for “endtest” to appear at the end.
Recall that when an argument is absorbed, category codes are frozen, so the setting \catcode`\|=10
does nothing at all.
A recursion without the “termination” problem is obtained by adding two terminators.
% generic terminators
\def\TerminatorA{\TerminatorA}
\def\TerminatorB{\TerminatorB}
\def\boldenas#1{\boldenasRecurse#1\TerminatorA\TerminatorB}
\def\boldenasRecurse#1#2#3\TerminatorB{%
\boldenasDo{#1}%
\ifx#2\TerminatorA
\let\next\boldenasEnd
\else
\let\next\boldenasRecurse
\fi
\next#2#3\TerminatorB
}
\def\boldenasDo#1{%
\ifx #1a%
{\bf a}%
\else
#1%
\fi
}
\def\boldenasEnd#1\TerminatorB{}
\boldenas{abracadabra}
\bye
This is not safe against #1
being empty (we're tough plain TeX users, after all). Spaces will be gobbled for the reason I explained earlier and braced groups will produce chaos. But, hey, we're doing theory!
Note that the \let
instructions can be avoided:
% generic terminators
\def\TerminatorA{\TerminatorA}
\def\TerminatorB{\TerminatorB}
% syntactic sugar
\long\def\firstoftwo#1#2{#1}
\long\def\secondoftwo#1#2{#2}
\def\boldenas#1{\boldenasRecurse#1\TerminatorA\TerminatorB}
\def\boldenasRecurse#1#2#3\TerminatorB{%
\boldenasDo{#1}%
\ifx#2\TerminatorA
\expandafter\firstoftwo
\else
\expandafter\secondoftwo
\fi
\boldenasEnd\boldenasRecurse#2#3\TerminatorB
}
\def\boldenasDo#1{%
\ifx #1a%
{\bf a}%
\else
#1%
\fi
}
\def\boldenasEnd#1\TerminatorB{}
\boldenas{abracadabra}
\bye