
Estoy haciendo una macro de fábrica (A) que produce otra macro (B). La macro B consiste en afectar lo que recibe como parámetros de las variables cuando se llama. Actualmente puedo hacer todo esto sin A, pero esto no es escalable porque requiere mucha reescritura.
Supongo que lo que me falta aquí es la referencia a un argumento que debe expandirse durante la llamada de B. Intenté usar varios #
porque parecen ser argumentos anidados, pero siento que esto no es lo que necesito.
El punto con el que estoy luchando es: " #1
(para señalar el primer argumento dentro de la función que llama a la función propia (es decir \variable1
))" debe reemplazarse por "Laetitia", porque es el primer argumento de la macro B.
Encontrarás en el MWE:
- prueba de automatización 1: lo intenté sin
xparse
- prueba de automatización 2: con
xparse
- el código hecho a mano de lo que quiero lograr.
Los 3 se pueden ejecutar, uno a la vez, cambiando la instrucción \iffalse
/ \iftrue
al principio.
¡Cualquier consejo sería útil!
\documentclass[twoside]{article}
% package pour utiliser une macro nested ac ses propres args
\usepackage{xparse}
\errorcontextlines32
\begin{document}
%==================================================================================
% Prerequisite : lines of code to define variableI to variableXVI
%==================================================================================
\newcommand{\DefinitVariable}[1]{%
\expandafter\newcommand\csname variable\Roman{#1}\endcsname{}%
}%
% Loop for defining all the variable
\newcounter{ctr}
\loop
\stepcounter{ctr}
\expandafter\DefinitVariable{ctr}%
\ifnum\thectr<16
\repeat
%==================================================================================
% Automation trial 1 :
%\iftrue
\iffalse
\newcommand\DeuxiemeAffecteVariable[1]{%%
\setcounter{ctr}{1}%
\expandafter\renewcommand\csname variable\Roman{ctr}\endcsname{\#1 (to point to the first argument within the function calling self function (ie \textbackslash variable1))}%
}
\newcommand\definecommand[1]{%%
\expandafter\def\csname#1\endcsname{%
\setcounter{ctr}{1}%
\expandafter\DeuxiemeAffecteVariable{\arabic{ctr}}%
}%%
}%
\definecommand{DefinitionVariablesN}%
\DefinitionVariablesN{Laetitia}%
La variable 1 est : \variableI \\ FIN\\
\fi
%==================================================================================
% Automation trial 2 with xparse :
\iftrue
%\iffalse
\newcounter{cpteurLocal}
\NewDocumentCommand{\AffecteVariable}{m}
{%
\setcounter{cpteurLocal}{#1}%
\expandafter\RenewDocumentCommand\csname variable\Roman{cpteurLocal}\endcsname {m}%
{\#1 (to point to the first argument within the function calling self function (ie \textbackslash variable1))}%
%{m}%
%{##1}%
%{########1}%
%{contenu vraiable}%
}%
% Macro factory (A)
\newcommand{\DefinitFonctionDeDefinition}[1]{%
\expandafter\newcommand\csname DefinitionVariablesN\endcsname{%
\expandafter\AffecteVariable{#1}%
%\expandafter\expandafter\AffecteVariable{#1}%
%\AffecteVariable{#1}%
}%
}
\setcounter{ctr}{1}%
\DefinitFonctionDeDefinition{\arabic{ctr}}%
\DefinitionVariablesN{Laetitia}
La variable 1 est : \variableI \\ FIN\\
\fi
%==================================================================================
% Goal to reach, but this is 'handmade' (not scalable) :
\iffalse
%\iftrue
\newcommand{\DefinitionVariablesI}[9]{
\renewcommand{\variableI}{#1}
\renewcommand{\variableII}{#2}
\renewcommand{\variableIII}{#3}
\renewcommand{\variableIV}{#4}
\renewcommand{\variableV}{#5}
\renewcommand{\variableVI}{#6}
\renewcommand{\variableVII}{#7}
\renewcommand{\variableVIII}{#8}
\renewcommand{\variableIX}{#9}
}
\newcommand{\DefinitionVariablesII}[7]{
\renewcommand{\variableX}{#1}
\renewcommand{\variableXI}{#2}
\renewcommand{\variableXII}{#3}
\renewcommand{\variableXIII}{#4}
\renewcommand{\variableXIV}{#5}
\renewcommand{\variableXV}{#6}
\renewcommand{\variableXVI}{#7}
}
\DefinitionVariablesI{Laetitia}{Patrick}{Marie}{Michel}{Dieter}{Sammy}{Barbara}{Donna}{Ivan}
\DefinitionVariablesII{Pierre}{Rene}{Frederic}{Ousmam}{Paul}{Virginie}{Gerard}
La variable 1 est : \variableI\\
La variable 2 est : \variableII\\
La variable 3 est : \variableIII\\
La variable 4 est : \variableIV\\
La variable 5 est : \variableV\\
La variable 10 est : \variableX\\
La variable 11 est : \variableXI\\
La variable 12 est : \variableXII\\
La variable 13 est : \variableXIII\\
La variable 14 est : \variableXIV\\
FIN
\fi
\end{document}
==================================================== ===================== Definitivamente estamos progresando gracias a la respuesta de @egreg.
Darle seguimiento aFábrica de macros y argumento pasado al llamar (parte 2)
Respuesta1
Puedes utilizar algunas expl3
herramientas más avanzadas:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\DefinitionVariables}{m}
{
\int_zero:N \l_tmpa_int
\clist_map_inline:nn { #1 }
{
\int_incr:N \l_tmpa_int
\tl_clear_new:c { variable \int_to_Roman:n { \l_tmpa_int } }
\tl_set:cn { variable \int_to_Roman:n { \l_tmpa_int } } { ##1 }
}
}
\ExplSyntaxOff
\begin{document}
\DefinitionVariables{
Laetitia,Patrick,Marie,Michel,Dieter,Sammy,Barbara,Donna,Ivan,
Pierre,Rene,Frederic,Ousmam,Paul,Virginie,Gerard
}
\noindent
La variable 1 est : \variableI\\
La variable 2 est : \variableII\\
La variable 3 est : \variableIII\\
La variable 4 est : \variableIV\\
La variable 5 est : \variableV\\
La variable 10 est : \variableX\\
La variable 11 est : \variableXI\\
La variable 12 est : \variableXII\\
La variable 13 est : \variableXIII\\
La variable 14 est : \variableXIV\\
FIN
\end{document}
Aquí hay una versión "clásica":
\documentclass{article}
\makeatletter
\newcommand{\DefinitionVariables}[1]{%
\count@=\z@
\@for\next:={#1}\do{%
\advance\count@\@ne
\expandafter\newcommand\csname variable\@Roman\count@\expandafter\endcsname\expandafter{\next}% !!
}%
}
\makeatother
\begin{document}
\DefinitionVariables{%
Laetitia,Patrick,Marie,Michel,Dieter,Sammy,Barbara,Donna,Ivan,%
Pierre,Rene,Frederic,Ousmam,Paul,Virginie,Gerard%
}
\noindent
La variable 1 est : \variableI\\
La variable 2 est : \variableII\\
La variable 3 est : \variableIII\\
La variable 4 est : \variableIV\\
La variable 5 est : \variableV\\
La variable 10 est : \variableX\\
La variable 11 est : \variableXI\\
La variable 12 est : \variableXII\\
La variable 13 est : \variableXIII\\
La variable 14 est : \variableXIV\\
FIN
\end{document}
Para estar seguro, sería mejor usar
\uppercase\expandafter{%
\expandafter\def\expandafter\df@temp\expandafter{%
\romannumeral\count@
}%
}%
\expandafter\newcommand\csname variable\df@temp\expandafter\endcsname
\expandafter{\next}%
en lugar de la línea marcada como !!
, porque algunos babel
módulos se redefinen \@Roman
de forma no expandible.
Sin embargo, tenga en cuenta que los finales de línea deben protegerse en el argumento de \DefineVariables
. Esto no es necesario en la expl3
versión porque \clist_map_inline:nn
ignora los espacios alrededor de los delimitadores de coma.
Respuesta2
Puede utilizar algunas herramientas primitivas TeX avanzadas:
\newcount\varnum
\def\DefinitionVariables#1{\varnum=0 \defvarA#1,\end,}
\def\defvarA#1#2,{%
\ifx\end#1\else
\advance\varnum by1
\uppercase\expandafter
{\expandafter\def\expandafter\tmp\expandafter{\romannumeral\varnum}}%
\expandafter\def\csname variable\tmp\endcsname{#1#2}%
\expandafter\defvarA\fi
}
\DefinitionVariables{
Laetitia,Patrick,Marie,Michel,Dieter,Sammy,Barbara,Donna,Ivan,
Pierre,Rene,Frederic,Ousmam,Paul,Virginie,Gerard
}
La variable 1 est : \variableI\\
La variable 2 est : \variableII\\
La variable 3 est : \variableIII\\
La variable 4 est : \variableIV\\
La variable 5 est : \variableV\\
La variable 10 est : \variableX\\
La variable 11 est : \variableXI\\
La variable 12 est : \variableXII\\
La variable 13 est : \variableXIII\\
La variable 14 est : \variableXIV\\