我有一个宏,它在调用时动态生成变量(参见宏工厂和调用时传递的参数(第二部分)了解构建的完整历史记录)。
我想添加一个常量来表示参数列表的长度。这个想法是,当使用 {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}