从宏/变量调用的 tikz 中的样式名称

从宏/变量调用的 tikz 中的样式名称

这是我的问题:我正在尝试编写一些代码,以给定的样式绘制节点。样式在单独的文件中定义。样式的名称由一个函数定义,该函数将创建多个具有相同根名称和罗马数字的变量以区分它们。这是设计,无法更改。

我想通过名为 xaller 的函数访问样式的名称,该函数检索变量“root+roman number”的内容:当内容用于显示时,它工作正常,但当内容应该用作样式的名称时,它就不行了。我想我需要指出检索到的内容指定了 tikz 的样式,但我不知道该怎么做。

在 MWE 中,您将找到当前正在运行和不运行的开关:我可以访问变量的内容,并在直接访问变量时将其用作样式名称,但通过 xaller 函数访问时无法使用它。我尝试使用函数 SetStyle 来解决此问题,该函数应该将样式的名称归因于 \monStyle ,但它也不起作用。

任何指示都会有所帮助。抱歉,如果代码看起来有点过分,我已尽我所能将其最小化。

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


\newcommand{\xaller}[2]{%
      \uppercase\expandafter
     {\expandafter\def\expandafter\tmp\expandafter{\romannumeral #1}}%
      \csname #2\tmp\endcsname%
      %\csname variableStyle\tmp\endcsname%
}


%==================================================================================
%==================================================================================
%==================================================================================
% 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
    \let\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
    \let\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}

答案1

因为\xaller要在这里使用,它必须是可扩展的。所以它既不能使用\def也不能使用\uppercase

为了制作一个可扩展的版本(在我看来也更具可读性),你可以使用 expl3:

\ExplSyntaxOn
\cs_new:Npn \xaller #1 #2 {
  \use:c { #2 \int_to_Roman:n { #1 } }
}
\ExplSyntaxOff

第二个问题是你使用\let

\let\monStyle\xaller{2}{variableStyle}

为创建\monStyle一个别名\xaller,但\xaller不会展开,{2}{variableStyle}只是作为常规文本输出到文档中。稍后,当\monStyle使用 时,TeX 会尝试读取\xaller参数并错过数字。可以通过展开\xaller三次(这需要很多\expandafters)或使用\def以下方法修复此问题:

\def\monStyle{\xaller{2}{variableStyle}}

这产生了工作版本

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

答案2

问题在于您混合了新旧风格的编程,以及对\let工作原理的误解。

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

在此处输入图片描述

相关内容