
Supongamos que tiene una macro TeX recursiva \formula
(con secuencias de control internas que hacen avanzar los contadores locales), que una vez expandida y escrita genera una expresión que satisface todas sus necesidades: por ejemplo, una expresión como f(x) (en una salida dvi).
¿Cómo recuperar esta fórmula tipográfica como una cadena de caracteres de retorno que puede utilizar como texto "textual" de reemplazo de otra macro, como por ejemplo \def\secondformula{f(x)}
?
Aquí hay como MWE una definición de fórmula que define mediante recursividad una función de Bessel del primer tipo de cualquier orden.
\newcount\BesselOrder
\newcount\BesselOrderMinusOne
\def\BesselZERO{besj0(x)}
\def\BesselONE{besj1(x)}
\def\Recursion{%
\advance\BesselOrder by -1
\advance\BesselOrderMinusOne by -1
((2 * \the\BesselOrder / x) * {\BesselJ{\the\BesselOrder}} - \BesselJ{\the\BesselOrderMinusOne})
}
\def\BesselJ#1{%
\BesselOrder=#1%
\BesselOrderMinusOne = \BesselOrder%
\advance\BesselOrderMinusOne by -1%
\ifnum\BesselOrder = 0
\let\next=\BesselZERO
\fi
\ifnum\BesselOrder = 1
\let\next = \BesselONE
\fi
\ifnum\BesselOrder > 1
\let\next = \Recursion
\fi
\next
}
Respuesta1
% This is to be compiled with e-TeX. (Not TeX and also not LaTeX.)
\overfullrule=0pt
\parindent=0ex
\parskip=\baselineskip
\begingroup\catcode`\%=12 \lowercase{\endgroup\def\percentchar{%}}%
% Pete's bessel-routine:
% ======================
\newcount\BesselOrder
\newcount\BesselOrderMinusOne
\def\BesselZERO{besj0(x)}
\def\BesselONE{besj1(x)}
\def\Recursion{%
\advance\BesselOrder by -1
\advance\BesselOrderMinusOne by -1
((2 * \the\BesselOrder/ x) * {\BesselJ{\the\BesselOrder}} - \BesselJ{\the\BesselOrderMinusOne})
}
\def\BesselJ#1{%
\BesselOrder=#1%
\BesselOrderMinusOne = \BesselOrder%
\advance\BesselOrderMinusOne by -1%
\ifnum\BesselOrder = 0
\let\next=\BesselZERO
\fi
\ifnum\BesselOrder = 1
\let\next = \BesselONE
\fi
\ifnum\BesselOrder > 1
\let\next = \Recursion
\fi
\next
}
% Ulrich's bessel-routine:
% ========================
%
% The routine doesn't need temporary assignments and the like and is based
% on expansion only.
%
% !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
% !!!! Due to the \numexpr-thingie e-TeX-extensions are required. !!!!
% !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
%
% The routine as a trick for triggering expansion uses \romannumeral-expansion:
% When due to \romannumeral (La)TeX does gather together a sequence of digits
% trailed by a space as the number which it has to convert, expandable tokens
% get expanded.
% When in the end a number is gathered together which is not positive, as the result
% of the conversion (La)TeX will not deliver any token at all.
% Thus one can nicely (ab)use \romannumeral for triggering a lot of
% expansion-work and flipping-arguments-around-work as long as one ensures
% that in the end \romannumeral will not find a positive number.
%
% Due to \romannumeral-expansion \UDBesselJ will deliver the result in
% two expansion-steps/after "being hit" by two \expandafter .
%
% !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
% !!! \UDBesselJ will take its toll at the semantic nest and at the input-stack. !!!
% !!! !!!
% !!! Don't use it with all too large values in the argument. !!!
% !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
\long\def\exchange#1#2{#2#1}%
\long\def\passfirsttosecond#1#2{#2{#1}}%
\long\def\firstoftwo#1#2{#1}%
\long\def\secondoftwo#1#2{#2}%
\def\romannumeralstop{ }%
\def\UDBesselJ#1{%
\romannumeral0%
\ifnum#1 = 0 \expandafter\firstoftwo\else\expandafter\secondoftwo\fi
{\romannumeralstop besj0(x)}{%
\ifnum#1 = 1 \expandafter\firstoftwo\else\expandafter\secondoftwo\fi
{\romannumeralstop besj1(x)}{%
\ifnum#1 > 1 \expandafter\firstoftwo\else\expandafter\secondoftwo\fi
{%
\expandafter\exchange\expandafter{%
\romannumeral0%
\exchange{ }{\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter}%
\expandafter\UDBesselJ\expandafter{\the\numexpr#1-2\relax}) %
}{%
\expandafter\passfirsttosecond\expandafter{%
\romannumeral0%
\exchange{ }{\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter}%
\expandafter\UDBesselJ\expandafter{\the\numexpr#1-1\relax}%
}%
{\expandafter\exchange\expandafter{\the\numexpr#1-1\relax}{\romannumeralstop((2 * }/ x) * } - %
}%
}{\romannumeralstop}%
}%
}%
}%
% Testing the routines:
% =====================
{\tt\string\BesselJ\string{4\string}} yields:\hfil\break
\BesselJ{4}
\hbox to\hsize{\null\hrulefill\null}\nointerlineskip
{\tt\string\UDBesselJ\string{4\string}} yields:\hfil\break
\UDBesselJ{4}
\hbox to\hsize{\null\hrulefill\null}\nointerlineskip
{\tt\string\expandafter\string\expandafter\string\expandafter\string\def\hfil\break
\string\expandafter\string\expandafter\string\expandafter\string\secondformula\hfil\break
\string\expandafter\string\expandafter\string\expandafter\string{\percentchar\hfil\break
\string\UDBesselJ\string{4\string}\string}}
yields the macro
\expandafter\expandafter\expandafter\def
\expandafter\expandafter\expandafter\secondformula
\expandafter\expandafter\expandafter{%
\UDBesselJ{4}}%
{\tt\string\secondformula:}
{\tt\meaning\secondformula}
\hbox to\hsize{\null\hrulefill\null}\nointerlineskip
{\tt\string\secondformula} yields:\hfil\break
\secondformula
\bye