Style name in tikz called from macro/variable
For \xaller
to be used here, it has to be expandable.
So it can use neither \def
nor \uppercase
.
To make an expandable version (which is also more readable IMO), you can use expl3:
\ExplSyntaxOn
\cs_new:Npn \xaller #1 #2 {
\use:c { #2 \int_to_Roman:n { #1 } }
}
\ExplSyntaxOff
The second problem is your usage of \let
:
The line
\let\monStyle\xaller{2}{variableStyle}
makes \monStyle
an alias for \xaller
, but \xaller
is not expanded and {2}{variableStyle}
are just output as regular text to the document.
Later, when \monStyle
is used, TeX tries to read the \xaller
arguments and misses the number. This can be fixed by expanding \xaller
three times (this needs a lot of \expandafter
s) or by by using \def
instead:
\def\monStyle{\xaller{2}{variableStyle}}
This results in the working version
\documentclass[10pt,twoside]{article}
\usepackage{xparse}
\usepackage{xstring}
\usepackage[nomessages]{fp}
% graphics and color
\usepackage[usenames]{color}
\usepackage{xcolor}
\usepackage{tikz}
\usetikzlibrary{matrix, shapes, patterns, fit, positioning}
\usepackage{etoolbox}
\begin{document}
%==================================================================================
%==================================================================================
%==================================================================================
% Define the xpl3 functions to attributes the variables
%\include{fonctionsMWE}
\ExplSyntaxOn
\cs_new:Npn \SetStyle #1
{
% clear new car si new seulement, se plaint que la variable existe deja
\tl_clear_new:N \l_my_tl
% convertit l argument en chiffre romain
\tl_set:Nn \l_my_tl { \int_to_Roman:n {#1} }
% concatene variableCouleurMatrice a ma var \l_my_tl par la gauche
\tl_put_left:Nn \l_my_tl { variableStyle }
%show la variable
%\tl_use:N \l_my_tl
% use permet d executer la variable
\use:c { \tl_use:N \l_my_tl }
\let\monStyle\use:c { \tl_use:N \l_my_tl }
%\let\monStyle\variableStyleII
}
\ExplSyntaxOff
% Automation trial 7 : utilise la syntaxe expl3
\ExplSyntaxOn
\NewDocumentCommand{\DefinitionVariablesEnIndividuel}{O{variable}}
{% pass control to an inner function
% #1 is the "name part", default "variable"
\aline_df:n { #1 }
}
% define an integer variable
\int_new:N \l_aline_df_int
\cs_new_protected:Nn \aline_df:n
{
% the integer variable assigns the trailing roman number
\int_zero:N \l_aline_df_int
% start the recursion
\__aline_df_peek:n { #1 }
}
\cs_new_protected:Nn \__aline_df_peek:n
{
% check whether the next token is { (ignoring spaces)
\peek_catcode_ignore_spaces:NT \c_group_begin_token
{
% if it is, increment the counter and call
% \__aline_df_next:nn { #1 } { #2 }, where
% { #2 } is the next braced group
\int_incr:N \l_aline_df_int
\__aline_df_next:nn { #1 }
}
}
\cs_new_protected:Nn \__aline_df_next:nn
{
% if the variable is already defined, clear it
% otherwise create it
\tl_clear_new:c { #1 \int_to_Roman:n { \l_aline_df_int } }
\tl_clear_new:c { #1 ConstanteLongueur }
% set the variable
\tl_set:cn { #1 \int_to_Roman:n { \l_aline_df_int }} { #2 }
\tl_set:cx { #1 ConstanteLongueur } { \int_eval:n { \l_aline_df_int } }
% restart the recursion
\__aline_df_peek:n { #1 }
}
\ExplSyntaxOff
%==================================================================================
%==================================================================================
%==================================================================================
%==================================================================================
%\include{stylesMWE}
\tikzstyle{teteColonneNegatif} = [
text centered,
text=white, font=\bfseries,
minimum height=1em,
text depth=0.5em, text height=1em,
text width = 3cm,
rectangle, fill=none, draw=none, rounded corners,
fill=black!100
]
\tikzset{
teteColonne/.style={
text centered,
text=white, font=\bfseries,
minimum height=1em,
text depth=0.5em, text height=1em,
text width = 5cm,
rectangle, fill=none, draw=none, rounded corners,
fill=red!100
},
teteColonne/.default=white
}
\ExplSyntaxOn
\cs_new:Npn \xaller #1 #2 {
\use:c { #2 \int_to_Roman:n { #1 } }
}
\ExplSyntaxOff
%==================================================================================
%==================================================================================
%==================================================================================
% Define all the variables variableStyleN
\DefinitionVariablesEnIndividuel[variableStyle]{teteColonne}{teteColonneNegatif}{teteColonneNegatif}{teteColonne}{teteColonne}{teteColonne}{teteColonneNegatif}{teteColonne}
%==================================================================================
%==================================================================================
%==================================================================================
Wether the code is called from the variable or via the call of xaller, it is the same result :
xaller call : \xaller{1}{variableStyle}
direct variable : \variableStyleI
=======================================================
% Code to switch between what works (Generalization at false) and what doesn't (Generalization at true)
\newif\ifGeneralization
\Generalizationtrue
%\Generalizationfalse
% Use monStyle as a tmp variable for the node
\ifGeneralization
\def\monStyle{\xaller{1}{variableStyle}}
%\SetStyle{1}
\else
\let\monStyle\variableStyleI
\fi
Style used : \monStyle
\newline
\begin{tikzpicture}%
%\node[\variableStyleI](nom) at (1,10){\variableStyleI};
\node[\monStyle](nom) at (1,10){\monStyle};
\end{tikzpicture}
% Use monStyle as a tmp variable for the node
\ifGeneralization
\def\monStyle{\xaller{2}{variableStyle}}
\else
\let\monStyle\variableStyleII
\fi
\let\monStyle\variableStyleII
Style used : \monStyle
\newline
\begin{tikzpicture}%
%\node[\variableStyleII](nom) at (1,10){\variableStyleII};
\node[\monStyle](nom) at (1,10){\monStyle};
\end{tikzpicture}
\end{document}
Your mix of old and new style programming is the problem, plus the misunderstanding of how \let
works.
\documentclass[10pt,twoside]{article}
\usepackage{xparse}
\usepackage[usenames]{xcolor}
\usepackage{tikz}
\usetikzlibrary{matrix, shapes, patterns, fit, positioning}
\begin{document}
\ExplSyntaxOn
\NewExpandableDocumentCommand{\xaller}{mm}
{
\use:c { #2 \int_to_Roman:n { #1 } }
}
\NewDocumentCommand \SetStyle { m }
{
\cs_set:Npx \monStyle { \xaller{#1}{variableStyle} }
}
\NewDocumentCommand{\DefinitionVariablesEnIndividuel}{O{variable}}
{% pass control to an inner function
% #1 is the "name part", default "variable"
\aline_df:n { #1 }
}
% define an integer variable
\int_new:N \l_aline_df_int
\cs_new_protected:Nn \aline_df:n
{
% the integer variable assigns the trailing roman number
\int_zero:N \l_aline_df_int
% start the recursion
\__aline_df_peek:n { #1 }
}
\cs_new_protected:Nn \__aline_df_peek:n
{
% check whether the next token is { (ignoring spaces)
\peek_catcode_ignore_spaces:NT \c_group_begin_token
{
% if it is, increment the counter and call
% \__aline_df_next:nn { #1 } { #2 }, where
% { #2 } is the next braced group
\int_incr:N \l_aline_df_int
\__aline_df_next:nn { #1 }
}
}
\cs_new_protected:Nn \__aline_df_next:nn
{
% if the variable is already defined, clear it
% otherwise create it
\tl_clear_new:c { #1 \int_to_Roman:n { \l_aline_df_int } }
\tl_clear_new:c { #1 ConstanteLongueur }
% set the variable
\tl_set:cn { #1 \int_to_Roman:n { \l_aline_df_int }} { #2 }
\tl_set:cx { #1 ConstanteLongueur } { \int_eval:n { \l_aline_df_int } }
% restart the recursion
\__aline_df_peek:n { #1 }
}
\ExplSyntaxOff
\tikzset{
teteColonneNegatif/.style = {
text centered,
text=white, font=\bfseries,
minimum height=1em,
text depth=0.5em, text height=1em,
text width = 3cm,
rectangle, fill=none, draw=none, rounded corners,
fill=black!100
},
teteColonne/.style={
text centered,
text=white, font=\bfseries,
minimum height=1em,
text depth=0.5em, text height=1em,
text width = 5cm,
rectangle, fill=none, draw=none, rounded corners,
fill=red!100
},
teteColonne/.default=white,
}
% Define all the variables variableStyleN
\DefinitionVariablesEnIndividuel[variableStyle]
{teteColonne}
{teteColonneNegatif}
{teteColonneNegatif}
{teteColonne}
{teteColonne}
{teteColonne}
{teteColonneNegatif}
{teteColonne}
\SetStyle{1}
Style used : \verb|\monStyle|
\begin{tikzpicture}
\node[\monStyle](nom) at (1,10){\monStyle};
\end{tikzpicture}
\bigskip
\begin{tikzpicture}
\foreach \i in {1,...,8} {
\node[\xaller{\i}{variableStyle},text width=9cm](nom) at (1,10+\i){\xaller{\i}{variableStyle}};
}
\end{tikzpicture}
\end{document}