Erhalten Sie die gesetzte Ausgabe eines Makros als Ersatztext für ein anderes Makro zurück.

Erhalten Sie die gesetzte Ausgabe eines Makros als Ersatztext für ein anderes Makro zurück.

Angenommen, Sie haben ein rekursives TeX-Makro \formula(mit inneren Steuersequenzen, die lokale Zähler erhöhen), das nach der Erweiterung und dem Setzen einen Ausdruck ausgibt, der alle Ihre Anforderungen erfüllt: beispielsweise einen Ausdruck wie f(x) (in einer DVI-Ausgabe).

Wie erhalten Sie diese gesetzte Formel als Rückgabezeichenfolge zurück, die Sie als Ersatz für den „wörtlichen“ Text eines anderen Makros verwenden können, z. B. \def\secondformula{f(x)}?

Hier ist als MWE eine Definition einer Formel, die durch Rekursion eine Bessel-Funktion der ersten Art beliebiger Ordnung definiert

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

Antwort1

% 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

Bildbeschreibung hier eingeben

verwandte Informationen