我有一个易失性整数变量 ( counter
),有时我希望将其值保存到标记列表 ( saved_counter
)。
如果我仅使用 保存它\tl_set
,那么一旦counter
更改了值,这也会更改 的值saved_counter
,这是不可取的。
例子:
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{xparse}
\ExplSyntaxOn
\int_zero_new:N \counter % Set counter to 0.
\tl_new:N \saved_counter
\ExplSyntaxOff
\begin{document}
\ExplSyntaxOn
% Save C_0 in "saved_counter"
\tl_set:Nn \saved_counter {C \textsubscript {\the\counter}}
% Print the value of saved counter -> C_0
\saved_counter
% Change the value of counter for whatever the reason.
\int_incr:N \counter
% Print the value of saved counter again -> C_1
\saved_counter
\ExplSyntaxOff
\end{document}
我知道 LaTeX 中没有真正的变量,一切都是宏,因此,我明白为什么会发生这种情况。
但是,这似乎是一个常见问题,必须有一些方便的解决方案,例如将 的值扩展/转换counter
为字符串,然后将其分配给saved_counter
。
不幸的是,我是 LaTeX 新手,无法自己弄清楚。
答案1
您的代码存在问题,当您执行以下操作时:
\tl_set:Nn \saved_counter {C \textsubscript {\the\counter}}
令牌列表变量包含:
- C 字符标记;
- 控制
\textsubscript
序列标记; - 一个左括号字符标记;
- 控制
\the
序列标记; - 控制
\counter
序列标记; - 结束括号字符标记。
尤其\the\counter
是不是在您保存的标记列表中展开。稍后,当您使用标记列表,并由 TeX 逐个标记吸收。这就是为什么它反映计数器的值,当你的标记\saved_counter
被扩展时——在最后一刻。
解决方案是\the\counter
在您想要保存标记列表时进行扩展(我使用 LaTeX3-ish 方式以十进制表示法打印计数器,就像使用 LaTeX2e\arabic
或 TeX一样\number
):
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{xparse}
\ExplSyntaxOn
\int_zero_new:N \g_my_counter_int % Set counter to 0.
\tl_new:N \g_my_saved_tl
\cs_new_protected:Npn \my_update_token_list:n #1
{
\tl_gset:Nn \g_my_saved_tl { C \textsubscript {#1} }
}
\cs_generate_variant:Nn \my_update_token_list:n { x }
\NewDocumentCommand \myUpdateTokenList { m }
{
% The x-form eXpands the argument first
\my_update_token_list:x { \int_to_arabic:n {#1} }
}
\ExplSyntaxOff
\begin{document}
\ExplSyntaxOn
% Save the token list using the current counter value -> C_0
\myUpdateTokenList{\g_my_counter_int}
% Print the saved token list
\tl_use:N \g_my_saved_tl
% Change the counter value for whatever the reason.
\int_gincr:N \g_my_counter_int
% This is still the token list saved by \myUpdateTokenList above, where
% the value 0 had been used.
\tl_use:N \g_my_saved_tl
\ExplSyntaxOff
\end{document}
我还修改了您的代码,使其更符合 LaTeX3 规范(变量名),并使用全局 incr/set 函数来处理计数器和标记列表(取决于您的应用程序,但这种方式更直接)。我相信\ExplSyntaxOn
只把东西放进去会更干净里面序言。为此,您必须将所有 LaTeX3 代码包装在面向用户的命令中,就像我对 所做的那样\myUpdateTokenList
。这使得 LaTeX3 内容可供 LaTeX2e 访问:通过传递给您在\ExplSyntaxOn
机制下序言中实现的命令的参数。
答案2
答案是弗罗贡如果您不仅想保存值本身,还想保存附加材料,这种方法是最好的。但是还有其他方法。
我可能只会在一秒钟内保存该值int
:
\documentclass{article}
\usepackage{expl3}
\ExplSyntaxOn
\int_new:N \counter % Set counter to 0.
\int_new:N \l__iskustvo_saved_counter_int
\ExplSyntaxOff
\begin{document}
\ExplSyntaxOn
% Save C_0 in "saved_counter"
\int_set_eq:NN \l__iskustvo_saved_counter_int \counter
% Print the value of saved counter -> C_0
\int_use:N \l__iskustvo_saved_counter_int
% Change the value of counter for whatever the reason.
\int_incr:N \counter
% Print the value of saved counter again -> C_1
\int_use:N \l__iskustvo_saved_counter_int
\ExplSyntaxOff
\end{document}
如果要使用tl
,则可以使用V
-type 扩展保存该值
\documentclass{article}
\usepackage{expl3}
\ExplSyntaxOn
\int_new:N \counter % Set counter to 0.
\tl_new:N \l__iskustvo_saved_counter_tl
\ExplSyntaxOff
\begin{document}
\ExplSyntaxOn
% Save C_0 in "saved_counter"
\tl_set:NV \l__iskustvo_saved_counter_tl \counter
% Print the value of saved counter -> C_0
\l__iskustvo_saved_counter_tl
% Change the value of counter for whatever the reason.
\int_incr:N \counter
% Print the value of saved counter again -> C_1
\l__iskustvo_saved_counter_tl
\ExplSyntaxOff
\end{document}