Obtenha uma saída tipografada de uma macro como um texto de substituição para outra macro

Obtenha uma saída tipografada de uma macro como um texto de substituição para outra macro

Suponhamos que você tenha uma macro TeX recursiva \formula(com sequências de controle internas avançando contadores locais), que uma vez expandida e digitada produz uma expressão que atende a todas as suas necessidades: por exemplo, uma expressão como f(x) (em uma saída dvi).

Como recuperar essa fórmula digitada de volta como uma sequência de caracteres de retorno que você pode usar como substituto do texto "literal" de outra macro, como \def\secondformula{f(x)}?

Aqui está, como MWE, uma definição de fórmula que define por meio de recursão uma função de Bessel do primeiro tipo de qualquer ordem

\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
}

Responder1

% 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

insira a descrição da imagem aqui

informação relacionada