Ist es möglich, einen als Text in einer Variablen gespeicherten Befehl auszuführen?

Ist es möglich, einen als Text in einer Variablen gespeicherten Befehl auszuführen?

Ich habe einige komplizierte Ausdrücke mit vielen verschachtelten Befehlen, mit denen es schwierig ist, zu arbeiten. Um das zu lösen, habe ich einen Parser mit pgfparser geschrieben, der die Ausdrücke für mich erstellt. Ich kann die Ausgabe dann wieder in LaTeX kopieren und es gibt aus, was ich brauche.

Ich habe mich gefragt, ob ich das automatisieren könnte. Ich kann den Text (eine Folge von Befehlen) in einer Variablen speichern, aber dann finde ich keine Möglichkeit, die Befehle in der Variablen auszuführen

Der Parser selbst ist nicht besonders interessant, aber als MWE ist dies eine vereinfachte Version dessen, was ich habe:

\documentclass{standalone}
\usepackage[T1]{fontenc}
\usepackage{pgf}
\usepgfmodule{parser}

\pgfparserdef{mweparser}{initial}{\meaning [}{\textbackslash overline\{}
\pgfparserdef{mweparser}{initial}{\meaning ]}{\}}
\pgfparserdef{mweparser}{initial}{\meaning A}{A}
\pgfparserdef{mweparser}{initial}{subscript character _}{\_\{\pgfparserswitch{subscript}}
\pgfparserdef{mweparser}{subscript}{\meaning +}{\textbackslash hat\{\pgfparserswitch{edgename}}
\pgfparserdef{mweparser}{subscript}{\meaning -}{\textbackslash check\{\pgfparserswitch{edgename}}
\pgfparserdef{mweparser}{edgename}{\meaning a}{a\}\pgfparserswitch{subscript}}
\pgfparserdef{mweparser}{edgename}{\meaning b}{b\}\pgfparserswitch{subscript}}
\pgfparserdef{mweparser}{subscript}{subscript character _}{\}\pgfparserswitch{initial}}
\pgfparserdef{mweparser}{all}{the character ;}{\pgfparserswitch{final}}

\begin{document}
    \pgfparserparse{mweparser}[A_+a-b-a_[A_+a+b-a_]];%
\end{document}

Das Ergebnis ist:

\overline{A_{\hat{a}\check{b}\check{a}}\overline{A_{\hat{a}\hat{b}\check{a}}}}

Das ist es, was ich ausführen möchte (im Mathematikmodus). Ich kann diesen Text in einer Variablen speichern, weiß aber nicht, wie ich ihn ausführen kann.

Ich bin neu in diesem Bereich, also entschuldige ich mich, wenn ich etwas falsch gemacht habe.

Antwort1

Ich weiß nicht genau, wie der PGF-Parser funktioniert, aber was Sie mit Ihrem Code erhalten, ist eine Zeichenfolge, die nicht das ist, was Sie wollen: \textbackslashEs handelt sich nicht um einen Backslash, sondern um einen Befehl zum Drucken eines solchen.

Hier ist eine Implementierung mit l3regex, dem regulären Ausdrucksparser von LaTeX3; das gewünschte Ergebnis wurde hinzugefügt, um zu prüfen, was die Makros tun.

\documentclass[border=3,varwidth]{standalone}
\usepackage[T1]{fontenc}
\usepackage{xparse,l3regex}

\ExplSyntaxOn
\NewDocumentCommand{\term}{m}
 {
  \dquick_term:n { #1 }
 }

\tl_new:N \l__dquick_input_tl

\cs_new_protected:Npn \dquick_term:n #1
 {
  \tl_set:Nn \l__dquick_input_tl { #1 }
  %% subscripts (works so long you don't have nested subscripts)
  \regex_replace_all:nnN { \_(.*?)\_ } { \cD\_\cB\{\1\cE\} } \l__dquick_input_tl
  %% [ becomes \overline\bgroup (nesting is allowed)
  \regex_replace_all:nnN { \[ } { \c{overline}\c{bgroup} } \l__dquick_input_tl
  %% ] becomes \egroup
  \regex_replace_all:nnN { \] } { \c{egroup} } \l__dquick_input_tl
  %% +<char> becomes \hat{<char>}
  \regex_replace_all:nnN { \+(.) } { \c{hat}\cB\{\1\cE\} } \l__dquick_input_tl
  %% -<char> becomes \check{<char>}
  \regex_replace_all:nnN { \-(.) } { \c{check}\cB\{\1\cE\} } \l__dquick_input_tl
  $\tl_use:N \l__dquick_input_tl$
 }
\ExplSyntaxOff

\begin{document}
\term{[G_+a-b-c_[H_+a+a-c_]]}

$\overline{G_{\hat{a}\check{b}\check{c}}\overline{H_{\hat{a}\hat{a}\check{c}}}}$
\end{document}

Bildbeschreibung hier eingeben


Eine leicht andere Version, die die Angabe von Trennzeichen (sie müssen unterschiedlich sein) für verschachtelte Makros ermöglicht, hier mit dargestellt \overline.

\documentclass[border=3,varwidth]{standalone}
\usepackage[T1]{fontenc}
\usepackage{xparse,l3regex}

\ExplSyntaxOn
\NewDocumentCommand{\term}{m}
 {
  \dquick_term:n { #1 }
 }

\tl_new:N \l__dquick_input_tl

\cs_new_protected:Npn \dquick_term:n #1
 {
  \tl_set:Nn \l__dquick_input_tl { #1 }
  %% subscripts (works so long you don't have nested subscripts)
  \regex_replace_all:nnN { \_(.*?)\_ } { \cD\_\cB\{\1\cE\} } \l__dquick_input_tl
  %% brackets can be nested, this requires a slower routine
  \dquick_replace_nested:nnn { \[ } { \] } { overline }
  %% +<char> becomes \hat{<char>}
  \regex_replace_all:nnN { \+(.) } { \c{hat}\cB\{\1\cE\} } \l__dquick_input_tl
  %% -<char> becomes \check{<char>}
  \regex_replace_all:nnN { \-(.) } { \c{check}\cB\{\1\cE\} } \l__dquick_input_tl
  \tl_use:N \l__dquick_input_tl
 }

\cs_new_protected:Npn \dquick_replace_nested:nnn #1 #2 #3
 {% #1 is the left delimiter
  % #2 is the right delimiter
  % #3 is the macro name for replacement
  \regex_match:nVT { #1 ( [^#1#2]*? ) #2 } \l__dquick_input_tl
   {
    \regex_replace_all:nnN { #1 ( [^#1#2]*? ) #2 } { \c{#3}\cB\{\1\cE\} } \l__dquick_input_tl
    \dquick_replace_nested:nnn { #1 } { #2 } { #3 }
   }
 }
\cs_generate_variant:Nn \regex_match:nnT { nV }

\ExplSyntaxOff

\begin{document}
$\term{[G_+a-b-c_[H_+a+a-c_]]}$

$\overline{G_{\hat{a}\check{b}\check{c}}\overline{H_{\hat{a}\hat{a}\check{c}}}}$
\end{document}

verwandte Informationen