У меня есть 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
Также,Я бы использовал \addtocounter
с счетчиками, предоставленными на уровне пользовательского интерфейса LaTeX. Я бы использовал \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}