动态定义变量,但它不是持久的

动态定义变量,但它不是持久的

我有一个宏,它在调用时动态生成变量(参见宏工厂和调用时传递的参数(第二部分)了解构建的完整历史记录)。

我想添加一个常量来表示参数列表的长度。这个想法是,当使用 {Pierre}{Jacques} 调用时,宏定义 variableI(设置为 Pierre)、variableII(设置为 Jacques)以及 variableConstanteLongueur(设置为 2)。

它几乎按预期工作:当我定义多个变量系列时,ConstanteLongueur 会采用定义的最后一个系列的长度值,而不是采用其系列的长度值。

以下是 MWE:

\documentclass[twoside]{article}
% package pour utiliser une macro nested ac ses propres args
\usepackage{xparse}
% package pour avoir foreach
\usepackage{tikz}
\errorcontextlines32
\begin{document}

%==================================================================================
%    Macro that define the variables and the variable ConstanteLongueur which is the lenght of the list
%==================================================================================
\ExplSyntaxOn
\NewDocumentCommand{\DefinitionVariables}{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:cn { #1 ConstanteLongueur } { \int_eval:n  { \l_aline_df_int } }

  % restart the recursion
  \__aline_df_peek:n { #1 }
 }

\ExplSyntaxOff
%==================================================================================
%     Code to be executed
%==================================================================================
\DefinitionVariables[variableNames]{Armelle}{Audrey}{Philippe}{Maxime}{Thierry}{Myriam}
\DefinitionVariables[variableColors]{yellow}{blue}{green}{red}


Longueur de variableColors, should print the number 4 :
\variableColorsConstanteLongueur

\variableColorsI

Longueur de variableNames, should print the number 6 :
\variableNamesConstanteLongueur

\variableNamesI


==============================\\After re-defining the variable Names\\==============================

\DefinitionVariables[variableNames]{Armelle}{Audrey}{Philippe}{Maxime}{Thierry}{Myriam}

Longueur de variableNames, should print the number 6 :
\variableNamesConstanteLongueur

\end{document}

如您所见,以“Armelle”开头的系列长度为 6,而以“yellow”开头的系列长度为 4。

但是当调用时\variableNamesConstanteLongueur给出的是 4 而不是 6 ;这令人费解,因为变量的定义是正确的( \variableNamesI 正确地为“Armelle”)。

你知道我错过了什么吗?

答案1

你的问题是

\tl_set:cn { #1 ConstanteLongueur } { \int_eval:n  { \l_aline_df_int } }

这将创建你想要的带有内容的令牌列表确切地 \int_eval:n { \l_aline_df_int }. 你想要的是结果在定义时进行评估:目前它是在使用时进行评估。因此

\tl_set:cx { #1 ConstanteLongueur } { \int_eval:n  { \l_aline_df_int } }

IE进行穷举扩展。

答案2

存储时需要充分扩展该值。

我建议采用不同的方法,而不是偷看支架:使用 clists 更容易。

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\DefinitionVariables}{O{variable}m}
 {% pass control to an inner function
  % #1 is the "name part", default "variable"
  \aline_df:nn { #1 } { #2 }
 }

\int_new:N \l_aline_df_int

\cs_new_protected:Nn \aline_df:nn
 {
  \int_zero:N \l_aline_df_int
  \clist_map_inline:nn { #2 }
   {
    \int_incr:N \l_aline_df_int
    \tl_clear_new:c { #1 \int_to_Roman:n { \l_aline_df_int } }
    \tl_set:cn { #1 \int_to_Roman:n { \l_aline_df_int }}  { ##1 }
   }
  \tl_clear_new:c { #1 ConstanteLongueur }
  \tl_set:cx { #1 ConstanteLongueur } { \int_eval:n { \l_aline_df_int } }
 }
\ExplSyntaxOff

\begin{document}

\DefinitionVariables[variableNames]{
  Armelle,
  Audrey,
  Philippe,
  Maxime,
  Thierry,
  Myriam
}
\DefinitionVariables[variableColors]{
  yellow,
  blue,
  green,
  red
}


Longueur de variableColors, should print the number 4:
\variableColorsConstanteLongueur

\variableColorsI

Longueur de variableNames, should print the number 6:
\variableNamesConstanteLongueur

\variableNamesI

\DefinitionVariables[variableNames]{
  Armelle,
  Audrey,
  Philippe,
  Maxime,
  Thierry,
  Myriam
}

Longueur de variableNames, should print the number 6:
\variableNamesConstanteLongueur

\variableNamesIII

\end{document}

在此处输入图片描述

相关内容