¿Cómo se puede utilizar foreach para crear macros sinónimas?

¿Cómo se puede utilizar foreach para crear macros sinónimas?

¿Necesito muchos sinónimos de muchas macros con referencias a cifras clave? ¿Cómo uso el token \foreach como nombre de \newcommand? Busco reemplazar la salida REAL con la salida MOCKUP generando y usando las macros \hello, \hola y \bonjour (todas con subíndice 1) y \world, \mundo y \monde (todas con subíndice 2), porque Todos los sinónimos se refieren al mismo número de figura. Si hay una forma más sencilla de hacer esto, muéstrela. Deletrearlos todos copiándolos y editándolos es muy tedioso.

COMPILAR:

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

FUENTE:

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

Respuesta1

Usuario de TNX202729. Una solución Python funcionó perfectamente.

Primero el código fuente de 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)

Luego línea de comando:

bash$ IDEAS.py > IDEAS.tex

Luego látex:

\input{IDEAS}

Respuesta2

Un problema es que cada \foreachiteración tiene lugar dentro de su propio ámbito local.
Por lo tanto, una definición realizada en términos de \newcommandestá restringida al ámbito local que se abre al comienzo de la \foreachiteración y se cierra al final de la \foreachiteración durante la cual se lleva a cabo esa definición.
Sugiero acumular \newcommanddirectivas dentro de un registro de token de scratch donde las asignaciones se realizan globalmente y entregar el contenido de ese registro cuando finaliza la iteración. Necesita algunos \expandaftertrucos para \foreachexpandir correctamente las macros "variables".

Probablemente el siguiente código haga lo que desea:

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

ingrese la descripción de la imagen aquí


Alternativamente, en lugar de acumular dentro de un registro de token, puede usar expl3 \cs_new:cpxpara definir cosas globalmente:

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

ingrese la descripción de la imagen aquí

información relacionada