对于 reledac 的一些非常特殊的需求,我需要在每次更改页面计数器的值时获取它,可以通过settocounter
,也可以使用addotcounter
。
所以我做了类似的事情(这是一个非常简化的例子,实际上,我不会直接排版计数器)。
\documentclass{article}
\usepackage{etoolbox}
\usepackage{xstring}
%\usepackage{calc}
\makeatletter
\newcount\this@c@page
\newcommand{\set@this@c@page}{\global\this@c@page=\value{page}}
\apptocmd{\setcounter}{%
\relax\IfStrEq{#1}{page}{\set@this@c@page}{}%
}%
{\PackageWarning{mypackage}{success}}%
{\PackageWarning{mypackage}{fail}}%
\apptocmd{\addtocounter}{%
\relax\IfStrEq{#1}{page}{\set@this@c@page}{}%
}%
{\PackageWarning{mypackage}{success}}%
{\PackageWarning{mypackage}{fail}}%
\begin{document}
s
\newpage
\the\this@c@page
\end{document}
一切都运行良好,除非我使用calc
包。在这种情况下,this@c@page
仍然等于 0。似乎使用此包重新定义宏会改变我们可以获取计数器值的时间,但我不明白为什么。
有什么窍门吗?
答案1
页面计数器使用以下方式递增,\stepcounter
并由以下方式更新:calc
\stepcounter
。这是加载前的定义calc
(包含在内核中latex.ltx
):
\def\stepcounter#1{%
\addtocounter{#1}\@ne
\begingroup
\let\@elt\@stpelt
\csname cl@#1\endcsname
\endgroup}
请注意 的\stepcounter
使用方式\addtocounter
,您已对其进行了更新,因此可以按预期工作。以下是 的新定义\stepcounter
(由 重新定义calc
):
\def\stepcounter#1{\@ifundefined {c@#1}%
{\@nocounterr {#1}}%
{\global\advance\csname c@#1\endcsname \@ne
\begingroup
\let\@elt\@stpelt \csname cl@#1\endcsname
\endgroup}}%
使用calc
,\stepcounter
不使用\addtocounter
,因此不会更新计数器page
或捕获它的方式。
要解决此问题,您必须按照与和\stepcounter
相同的方式进行更新:\setcounter
\addtocounter
\apptocmd{\stepcounter}{%
\relax\IfStrEq{#1}{page}{\set@this@c@page}{}%
}%
{\PackageWarning{mypackage}{success}}%
{\PackageWarning{mypackage}{fail}}%
calc
提到更新是\setcounter
为了避免经历“整个calc
过程”(通过\addtocounter
)。