如何正确地将 int 变量的当前值存储到标记列表中?

如何正确地将 int 变量的当前值存储到标记列表中?

我有一个易失性整数变量 ( 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}

相关内容