foreach を使用して同義マクロを作成するにはどうすればよいでしょうか?

foreach を使用して同義マクロを作成するにはどうすればよいでしょうか?

重要な図参照を持つ多くのマクロの同義語が必要ですか? \foreach トークンを \newcommand 名として使用するにはどうすればよいでしょうか? 同義語はすべて同じ図番号を参照するため、マクロ \hello、\hola、\bonjour (すべて添え字 1) と \world、\mundo、\monde (すべて添え字 2) を生成して使用し、実際の出力を MOCKUP 出力に置き換えようと考えています。 もっと簡単な方法があれば、教えてください。 コピーして編集してすべてスペルアウトするのは非常に面倒です。

コンパイル:

bash$ for i in 1 2 3 4; do pdflatex MWE.tex ; done

ソース:

% filename: MWE.tex

\documentclass[10pt,twoside]{book}

\usepackage{tikz}
\begin{document}

\begin{center}{\bf\LARGE MWE}\end{center}

\begin{figure}\tikz{\node at (0,0) {hello};}\caption{hello}\label{hello}\end{figure}
\begin{figure}\tikz{\node at (0,0) {world};}\caption{world}\label{world}\end{figure}

GOAL: produce synonymous variant macros referencing a key figure.\\\\

EXPECT:\\
{\bf key:} $hello_1$ {\bf variants:} $hola_1$ $bonjour_1$\\
{\bf key:} $world_2$ {\bf variants:} $mundo_2$ $monde_2$\\

MOCKUP:\\
% NOTICE: this exercises the loops needed, but how do I generate named macros?
% PROBLEM: \foreach defines \key and \variant so \newcommand can't reuse them.
% FAILURE: \expandafter\newcommand\csname\variant\endcsname{$\variant~\ref{\key}}
\foreach\key/\variants in {hello/{hola,bonjour},world/{mundo,monde}}{
    {\bf key:} $\key_{\ref{\key}}$ {\bf variants:}
    \foreach\variant in \variants{$\variant_{\ref{\key}}$\;} \\
}

ACTUAL:\\
TODO
% TODO uncomment these next two lines when the \newcommands work correctly.
%key: \hello variants: \hola \bonjour
%key: \world variants: \mundo \monde
\end{document}

答え1

TNX user202729。Python ソリューションは完璧に機能しました。

まず IDEAS.py のソースコード:

#!/usr/bin/env python3

(BS, OB, CB) = ("\\", "{", "}")
IDEAS = {
    "hello": {"hola", "bonjour"},
    "world": {"mundo", "monde"}
}

def newcommand(num, key, syn):
    print(
        BS      + "newcommand" +
        BS      + syn +
        OB + BS + "large " + syn +
        BS      + "raisebox{-2pt}" +
        OB + BS + "footnotesize" +
        BS      + "ref{" + key + "}" +
        CB + CB
    )

def synonyms(num, key):
    newcommand(num + 1, key, key)
    for syn in IDEAS[key]:
        newcommand(num + 1, key, syn)

for num, key in enumerate(IDEAS):
    synonyms(num, key)

次にコマンドライン:

bash$ IDEAS.py > IDEAS.tex

次にラテックス:

\input{IDEAS}

答え2

1 つの問題は、各\foreach-iteration が独自のローカル スコープ内で実行されることです。
したがって、 で実行される定義は\newcommand、 -iteration の開始時に開かれ 、その定義の実行が行われる -iteration\foreachの終了時に閉じられるローカル スコープに制限されます。割り当てがグローバルに実行されるスクラッチ トークン レジスタ内に -directives を蓄積し、反復の完了時にそのレジスタの内容が配信されるようにすることをお勧めします。 -"variable"-マクロを適切に展開するには、いくつかの -tricks が必要です。\foreach
\newcommand\expandafter\foreach

おそらく次のコードがあなたの望みどおりに機能します:

% filename: MWE.tex

\documentclass[10pt,twoside]{book}

\newtoks\scratchtoks

\usepackage{tikz}
\begin{document}

\begin{center}{\bf\LARGE MWE}\end{center}

\begin{figure}\tikz{\node at (0,0) {hello};}\caption{hello}\label{hello}\end{figure}
\begin{figure}\tikz{\node at (0,0) {world};}\caption{world}\label{world}\end{figure}

GOAL: produce synonymous variant macros referencing a key figure.\\\\

EXPECT:\\
{\bf key:} $hello_1$ {\bf variants:} $hola_1$ $bonjour_1$\\
{\bf key:} $world_2$ {\bf variants:} $mundo_2$ $monde_2$\\

MOCKUP:\\
% NOTICE: this exercises the loops needed, but how do I generate named macros?
% PROBLEM: \foreach defines \key and \variant so \newcommand can't reuse them.
% FAILURE: \expandafter\newcommand\csname\variant\endcsname{$\variant~\ref{\key}}
\global\scratchtoks{\global\scratchtoks{}}%
\foreach\key/\variants in {hello/{hola,bonjour},world/{mundo,monde}}{%
    %---------------------------------------------------------------------------
    \global\scratchtoks\expandafter{%
      \the\expandafter\scratchtoks
          \expandafter\newcommand
          \csname\key\expandafter\expandafter\expandafter\endcsname
                     \expandafter\expandafter\expandafter{%
                     \expandafter\expandafter\expandafter$%
                     \expandafter\key
                     \expandafter_%
                     \expandafter{%
                     \expandafter\ref
                     \expandafter{\key}}$}%
    }%
    %---------------------------------------------------------------------------
    {\bf key:} $\key_{\ref{\key}}$ {\bf variants:}
    \foreach\variant in \variants{%
      %-------------------------------------------------------------------------
      \global\scratchtoks\expandafter{%
        \the\expandafter\scratchtoks
            \expandafter\newcommand
            \csname\variant\expandafter\expandafter\expandafter\endcsname
                       \expandafter\expandafter\expandafter{%
                       \expandafter\expandafter\expandafter$%
                       \expandafter\variant
                       \expandafter_%
                       \expandafter{%
                       \expandafter\ref
                       \expandafter{\key}}$}%
      }%
      %-------------------------------------------------------------------------
      $\variant_{\ref{\key}}$\;%
    }\\
}%
\the\scratchtoks

ACTUAL:\\
% TODO uncomment these next two lines when the \newcommands work correctly.
{\bf key:} \hello { \bf variants:} \hola\; \bonjour\;\\
{\bf key:} \world { \bf variants:} \mundo\; \monde\;\\
%\show\hello
%\show\hola
%\show\bonjour
%\show\world
%\show\mundo
%\show\monde
\end{document}

ここに画像の説明を入力してください


あるいは、トークン レジスタ内で蓄積する代わりに、expl3 を使用して\cs_new:cpxグローバルに定義することもできます。

% filename: MWE.tex

\documentclass[10pt,twoside]{book}
\usepackage{tikz}
\begin{document}

\begin{center}{\bf\LARGE MWE}\end{center}

\begin{figure}\tikz{\node at (0,0) {hello};}\caption{hello}\label{hello}\end{figure}
\begin{figure}\tikz{\node at (0,0) {world};}\caption{world}\label{world}\end{figure}

GOAL: produce synonymous variant macros referencing a key figure.\\\\

EXPECT:\\
{\bf key:} $hello_1$ {\bf variants:} $hola_1$ $bonjour_1$\\
{\bf key:} $world_2$ {\bf variants:} $mundo_2$ $monde_2$\\

MOCKUP:\\
% NOTICE: this exercises the loops needed, but how do I generate named macros?
% PROBLEM: \foreach defines \key and \variant so \newcommand can't reuse them.
% FAILURE: \expandafter\newcommand\csname\variant\endcsname{$\variant~\ref{\key}}
\ExplSyntaxOn
\foreach\key/\variants in {hello/{hola,bonjour},world/{mundo,monde}}{
    %---------------------------------------------------------------------------
    \cs_new:cpx{\key}
               {\c_math_toggle_token\exp_not:o {\key}\c_math_subscript_token{\exp_not:N\ref{\exp_not:o {\key}}}\c_math_toggle_token}
    %---------------------------------------------------------------------------
    {\bf key:}~\c_math_toggle_token\key\c_math_subscript_token{\ref{\key}}\c_math_toggle_token~{\bf variants:}~
    \foreach\variant in \variants{
      %-------------------------------------------------------------------------
      \cs_new:cpx{\variant}
                 {\c_math_toggle_token\exp_not:o {\variant}\c_math_subscript_token{\exp_not:N\ref{\exp_not:o {\key}}}\c_math_toggle_token}
      %-------------------------------------------------------------------------
      \c_math_toggle_token\variant\c_math_subscript_token{\ref{\key}}\c_math_toggle_token\;
    }\\
}
\ExplSyntaxOff

ACTUAL:\\
% TODO uncomment these next two lines when the \newcommands work correctly.
{\bf key:} \hello { \bf variants:} \hola\; \bonjour\;\\
{\bf key:} \world { \bf variants:} \mundo\; \monde\;\\
%\show\hello
%\show\hola
%\show\bonjour
%\show\world
%\show\mundo
%\show\monde
\end{document}

ここに画像の説明を入力してください

関連情報