使用 LaTeX3 操作 LaTeX2e 计数器

使用 LaTeX3 操作 LaTeX2e 计数器

我有一些expl3代码,想要操作使用 LaTeX2e 代码的包定义的计数器。

如果我想操纵计数器foo,我可以将 LaTeX2e 代码与 LaTeX3 代码混合:

% some expl3 code
\addtocounter{foo}{123}
% more expl3 code

或者我可以只使用命令来完成expl3

% some expl3 code
\int_gadd:Nn \c@foo { 123 }
% more expl3 code

哪种操作计数器的方法更可取?或者我选择哪种方法都无所谓?

编辑:这是使用该包的 MWE datenumber

\documentclass{article}
\usepackage{datenumber,xparse}

\makeatletter
\ExplSyntaxOn

\cs_new_protected:Npn \juhu_futuredate:n #1
{
  \setdatetoday
  \int_gadd:Nn \c@datenumber { #1 } % \addtocounter{datenumber}{#1}
  \setdatebynumber{\thedatenumber}
  In ~ #1 ~ days ~ is ~ \datedate.
}

\NewDocumentCommand{\futuredate}{m}
{
  \juhu_futuredate:n { #1 }
}

\ExplSyntaxOff
\makeatother

\begin{document}

\futuredate{7}

\end{document}

datenumber包定义了datenumber计数器并使用命令为其分配一个整数\setdatetoday\datedate根据给定的值打印日期\setdatebynumber。当然,我可以定义自己的整数并将其传递给命令\setdatebynumber,但给出的整数\setdatetoday并不简单,我想避免自己进行计算。

答案1

我想我可以提供一个或多或少“官方”的答案:使用 LaTeX2e 命令。混合这两个界面会带来麻烦,虽然我们正在研究几个领域,但我们还没有找到“用户级”的应对方法。(事实上,如何处理文档级变量的整个问题仍悬而未决。)

\setcounter我在这里使用的原因\c@...内部的对于 LaTeX2e,其全部要点expl3是拥有清晰的接口和内部结构。这里没有理由滥用接口(不会获得任何功能),因此请坚持使用它们。

答案2

第一的如果可能的话,我会避免使用内部命令:特别是当已经提供了接口时。例如,我会使用

\addtocounter{datenumber}{...}

而不是直接与

\c@datenumber

还,我会使用\addtocounterLaTeX 用户界面级别提供的计数器。我只会使用\int_gadd:Nn定义的类似计数器的东西expl3

下一个,我不会将@符号与expl3符号混用。如果必须同时使用两者,我会明确地将两者分开,如果它们必须以某种方式共享信息,我会创建一个接口。但如果可能的话,我会尽量避免将两者混用,即使使用接口也是如此。

然后我将创建自己的expl3命令集,以便直接与任何特定软件包提供的命令进行交互。在这些命令中,我将仅使用标准 LaTeX 宏/结构以及软件包为用户界面提供的任何 LaTeX 宏/结构。

最后,我会创建expl3代码在表面上纯粹是expl3代码。

因此,按照上述建议,你的 MWE 将变成如下形式:

\documentclass{article}
\usepackage{datenumber,xparse}

\makeatletter
%% define/work with functions that use `@` 
%% notation create an interface for these  
%% functions if necessary.                 
\makeatother

\ExplSyntaxOn
%% User level interface
\NewDocumentCommand{\futuredate}{m}
{
  \juhu_futuredate:n { #1 }
}

%% Internal `expl3` code that on the surface remains purely `expl3`
%% Though these functions might "stand in" for non-expl3 code.
\cs_new_protected:Npn \juhu_futuredate:n #1
{
  %% ... expl3 code ...
  \_juhu_initialize_date:
  %% ... expl3 code ...
  \_juhu_advance_date_by:n {#1}
  %% ... expl3 code ...
  \_juhu_reset_by_datenumber:
  %% ... expl3 code ...
  \_juhu_print_future_date:n {#1}
  %% ... expl3 code ...
}

%% Interface with commands from `datenumber` package
\cs_new_protected:Nn  \_juhu_initialize_date:       {\setdatetoday}
\cs_new_protected:Nn  \_juhu_reset_by_datenumber:   {\setdatebynumber{\thedatenumber}}  
\cs_new_protected:Npn \_juhu_advance_date_by:n #1   {\addtocounter{datenumber}{#1}}
\cs_new_protected:Npn \_juhu_print_future_date:n #1 {In ~ #1 ~ days ~ is ~ \datedate}

\ExplSyntaxOff

\begin{document}

\futuredate{7}

\end{document}

相关内容