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
\text
? I think it's some sort of\hbox
inside\mathchoice
. – Manuel Oct 5 '16 at 16:27amstext.sty
. (kpsewhich amstext.sty
will tell you where it is.) – Torbjørn T. Oct 5 '16 at 16:29\hbox{...}
for text, which can be used inside math. And\mathchoice
helps, when you want to have different font sizes depending on the current math style. – Heiko Oberdiek Oct 5 '16 at 16:36\hbox
and the interesting control sequence\mathchoice
. :) – awllower Oct 5 '16 at 16:42