我正在尝试使用共享计数器按页对一些对象进行编号。以下示例接近最小值。
\documentclass{article}
\usepackage{zref-perpage}
\newcommand*{\tablecaption}[1]{%
\setlength{\belowcaptionskip}{\abovecaptionskip}%
\setlength{\abovecaptionskip}{0pt}%
\caption{#1}%
}
\newcounter{maincounter}
\newtheorem{theorem}{Theorem}
\newtheorem{proposition}[theorem]{Proposition}
\makeatletter
\let\c@equation\c@maincounter
\let\c@figure\c@maincounter
\let\c@table\c@maincounter
\let\c@theorem\c@maincounter
\makeatother
\zmakeperpage{maincounter}
%\zmakeperpage{equation}
%\zmakeperpage{figure}
%\zmakeperpage{table}
%\zmakeperpage{theorem}
\renewcommand*{\themaincounter}{\arabic{zpage}.\arabic{maincounter}}
\renewcommand*{\theequation}{\themaincounter}
\renewcommand*{\thefigure}{\themaincounter}
\renewcommand*{\thetable}{\themaincounter}
\renewcommand*{\thetheorem}{\themaincounter}
\begin{document}
%
\begin{theorem}
Blah.
\end{theorem}
%
\begin{table}[h]
\centering
\tablecaption{A table}
\begin{tabular}{l | l}
1 & 2 \\
\hline
3 & 4
\end{tabular}
\end{table}
%
\begin{equation}
a = b
\end{equation}
%
\begin{figure}[b]
\centering
\rule{3cm}{2cm}
\caption{A black rectangle}
\end{figure}
%
\begin{proposition}
Blah.
\end{proposition}
%
\newpage
%
\begin{equation}
c = d
\end{equation}
%
\begin{table}[t]
\centering
\tablecaption{Another table}
\begin{tabular}{l | l}
a & b \\
\hline
c & d
\end{tabular}
\end{table}
%
\begin{theorem}
Blah.
\begin{equation}
e = f
\end{equation}
\end{theorem}
%
\end{document}
问题是计数器maincounter
不会在每次更改页面时重置,并且计数器的值zpage
始终为 0。如果我取消注释序言中的注释行,则每页重置都会起作用,计数器zpage
会增加,但计数器不再链接。
作为奖励,我希望每页上的不同物体按照其出现的顺序进行编号(可能类似于包\MakeSorted
的命令perpage
)。
更新
感谢 David Carlisle 的评论,我能够使用与包perpage
中的选项相关的代码footmisc
并使其与任何计数器一起工作。此解决方案的一个相对限制性方面是需要修补打印相应对象数量的命令:我们必须用一些代码包围它们,这些代码检查页面是否发生变化,并因此设置相关的计数器。因此,这种修补取决于加载的包及其可能的重新定义。(在这里,我正在使用和amsmath
。amsthm
)
那么,链接计数器非常容易:我只需要为一个“主”计数器加载每页机制并将其他计数器标识为该计数器。
至于不同对象编号中的当前页面编号,我尝试在增加计数器并打印之前制作一个标签(通过补丁,如前所述),以便能够使用\pageref
。
然而,这些补丁存在一些问题:它们破坏了引用机制;计数器和页面的一些不正确的值有时— 或者总是这样?— 阅读和书写。
以下是文档中经过测试的代码。不正确的引用用命令 标出\wrong
,该命令会用红色打印其参数。
\documentclass[a4paper, 11pt]{article}
% amsmath redefines the \label command, which messes up the mechanism that prints the current page number
\makeatletter
\let\label@original\label
\makeatother
\usepackage{etoolbox}
\usepackage{amsmath}
\usepackage{amsthm}
\usepackage{xcolor}
\allowdisplaybreaks
\makeatletter
\providecommand\protected@writeaux{%
\protected@write\@auxout
}
% Get and print the current page number
\newcounter{currentpage@mark}
\def\theCurrentPageMark{%
\global\advance\c@currentpage@mark\@ne
\label@original{currentpage@mark\the\c@currentpage@mark}%
}
\def\theCurrentPageRef{%
\expandafter\pageref{currentpage@mark\the\c@currentpage@mark}%
}
% Load some commands that reset a counter at each change of page
\def\load@PerPage@machinery#1{%
\expandafter\newif\csname ifPerPage@#1@hint\endcsname
\newcounter{PerPage@#1@next@reset}
\expandafter\newif\csname ifPerPage@#1@towrite\endcsname
\@nameuse{PerPage@#1@towritefalse}
\global\@namedef{PerPage@#1@initial@stab}{\@addtoreset{#1}{page}}
\AtBeginDocument{\@nameuse{PerPage@#1@initial@stab}}
\newcounter{@#1@serial}
\@namedef{PerPage@#1@cpage}{0}
\@nameuse{PerPage@#1@hinttrue}
\@namedef{PerPage@#1@hint}{%
\setcounter{#1}{0}%
\protected@writeaux\relax{\expandafter\protect\csname PerPage@#1@hinttrue\endcsname}%
\@tempcnta\csname c@@#1@serial\endcsname%
\advance\@tempcnta\@ne
\global\expandafter\csname c@PerPage@#1@next@reset\endcsname\@tempcnta
}
\AtBeginDocument{%
\protected@writeaux\relax{%
\protect\providecommand{\expandafter\protect\csname PerPage@#1@hinttrue\endcsname}{}%
}%
}
\@namedef{PerPage@#1@lastfoot}{-1}
\@namedef{PerPage@#1@aux}##1##2{%
\ifnum\csname PerPage@#1@lastfoot\endcsname<##1%
\@nameuse{ifPerPage@#1@hint}%
\@nameuse{PerPage@#1@reset}{##1}{##2}%
\@nameuse{PerPage@#1@hintfalse}%
\else
\gdef\@tempa{##2}%
{\expandafter}\expandafter\ifx\csname PerPage@#1@cpage\endcsname\@tempa
\else
\@nameuse{PerPage@#1@reset}{##1}{##2}%
\fi
\fi
\@namedef{PerPage@#1@lastfoot}{##1}%
\fi
\global\cslet{PerPage@#1@initial@stab}{\relax}%
}
\@namedef{PerPage@#1@reset}##1##2{%
\global\@namedef{PerPage@#1@cpage}{##2}%
\expandafter\gdef
\csname PerPage@#1@next-\@nameuse{PerPage@#1@prev@foot}\endcsname{##1}%
\@namedef{PerPage@#1@prev@foot}{##1}%
\expandafter\xdef
\csname PerPage@#1@next-\@nameuse{PerPage@#1@prev@foot}\endcsname{\the\@MM}%
}
\@namedef{PerPage@#1@prev@foot}{root}
\AtBeginDocument{%
\protected@writeaux\relax{%
\protect\providecommand{\expandafter\protect\csname PerPage@#1@aux\endcsname}[2]{}%
}%
\csname c@PerPage@#1@next@reset\endcsname\@ne
}
\AtEndDocument{%
\csletcs{PerPage@#1@aux}{PerPage@#1@endaux}%
\@namedef{PerPage@#1@lastfoot}{-1}%
\@nameuse{PerPage@#1@hintfalse}%
\@namedef{PerPage@#1@prev@foot}{root}%
}
\@namedef{PerPage@#1@endaux}##1##2{%
\ifnum\csname PerPage@#1@lastfoot\endcsname<##1%
\@nameuse{ifPerPage@#1@hint}%
\@nameuse{PerPage@#1@reset@end}{##1}{##2}%
\@nameuse{PerPage@#1@hintfalse}%
\else
\gdef\@tempa{##2}%
{\expandafter}\expandafter\ifx\csname PerPage@#1@cpage\endcsname\@tempa
\else
\@nameuse{PerPage@#1@reset@end}{##1}{##2}%
\fi
\fi
\@namedef{PerPage@#1@lastfoot}{##1}%
\fi
}
\@namedef{PerPage@#1@reset@end}##1##2{%
\def\@tempa{##1}%
{\expandafter}\expandafter\ifx\csname PerPage@#1@next-\@nameuse{PerPage@#1@prev@foot}\endcsname\@tempa
\else
\@tempswatrue
\fi
\global\@namedef{PerPage@#1@prev@foot}{##1}%
\global\@namedef{PerPage@#1@cpage}{##2}%
}
\pretocmd{\clearpage}{\@nameuse{PerPage@#1@hint}}{}{}
\@namedef{PerPage@#1}{%
\if@minipage\else
\global\expandafter\advance\csname c@@#1@serial\endcsname\@ne
\if@filesw
\expandafter\xdef\csname PerPage@#1@writetemp\endcsname{%
\noexpand\protected@writeaux\relax{%
\expandafter\string\csname PerPage@#1@aux\endcsname%
{\the\@nameuse{c@@#1@serial}}{\noexpand\thepage}%
}%
}%
\@nameuse{PerPage@#1@towritetrue}%
\fi
\ifnum\csname c@PerPage@#1@next@reset\endcsname>\csname c@@#1@serial\endcsname
\else
\global\expandafter\csname c@#1\endcsname\@ne
\expandafter\let\expandafter\@tempa
\csname PerPage@#1@next-\number\csname c@PerPage@#1@next@reset\endcsname\endcsname
\ifx\@tempa\relax
\global\expandafter\csname c@PerPage@#1@next@reset\endcsname\@MM
\else
\global\expandafter\csname c@PerPage@#1@next@reset\endcsname\@tempa
\fi
\fi
\fi
}
\@namedef{PerPage@#1@end}{%
\@nameuse{ifPerPage@#1@towrite}%
\@nameuse{PerPage@#1@writetemp}%
\@nameuse{PerPage@#1@towritefalse}%
\fi
}
}
\newcounter{maincounter}
\load@PerPage@machinery{maincounter}
% Patch some numbering commands to take into account the page number and the resetting
\newtheoremstyle{thmstyle}%
{\topsep}%
{\topsep}%
{\itshape}%
{}%
{\bfseries}%
{.}%
{ }%
{\thmname{#1}%
\thmnumber{\@ifnotempty{#1}{ }%
\theCurrentPageMark
\PerPage@maincounter
\@upn{#2}%
\PerPage@maincounter@end}%
\thmnote{ {\the\thm@notefont(#3)}}}
\theoremstyle{thmstyle}
\newtheorem{theorem}{Theorem}
\newtheorem{proposition}[theorem]{Proposition}
\pretocmd{\@footnotemark}{%
\theCurrentPageMark
\PerPage@maincounter
\global\csname c@\@mpfn\endcsname\c@footnote
\protected@xdef\@thefnmark{\thempfn}%
}{}{}
\apptocmd{\@footnotemark}{%
\PerPage@maincounter@end
}{}{}
\pretocmd{\tagform@}{%
\theCurrentPageMark
\PerPage@maincounter
}{}{}
\apptocmd{\tagform@}{%
\PerPage@maincounter@end
}{}{}
\pretocmd{\@caption}{%
\theCurrentPageMark
\PerPage@maincounter
}{}{}
\apptocmd{\@caption}{%
\PerPage@maincounter@end
}{}{}
% Link the counters
\let\c@footnote\c@maincounter
\let\c@equation\c@maincounter
\let\c@theorem\c@maincounter
\let\c@figure\c@maincounter
\let\c@table\c@maincounter
\renewcommand{\thefootnote}{\theCurrentPageRef.\arabic{footnote}}
\renewcommand{\theequation}{\theCurrentPageRef.\arabic{equation}}
\renewcommand{\thetheorem}{\theCurrentPageRef.\arabic{theorem}}
\renewcommand{\thefigure}{\theCurrentPageRef.\arabic{figure}}
\renewcommand{\thetable}{\theCurrentPageRef.\arabic{table}}
\newcounter{rptcount}
\long\def\rpt#1#2{%
\setcounter{rptcount}{#1}%
\loop #2%
\ifnum\therptcount>1 \addtocounter{rptcount}{-1}%
\repeat
}
\def\brack@iden[#1]{#1}
\newcommand*{\blindtext}[1]{%
\ifnum#1<\@ne
\else\ifnum#1=\@ne
Blah%
\else
Blah, %
\rpt{\numexpr#1-2\relax}{blah, }%
blah%
\fi\fi
\@ifnextchar[\brack@iden.%
}
\makeatother
\newcommand*{\tablecaption}[1]{%
\setlength{\belowcaptionskip}{\abovecaptionskip}%
\setlength{\abovecaptionskip}{0pt}%
\caption{#1}%
}
\newcommand*{\wrong}[1]{%
\textcolor{red}{#1}%
}
\begin{document}
%
\begin{theorem}\label{thm1}
Blah.
\end{theorem}
%
\begin{table}[h]
\centering
\tablecaption{A table}
\begin{tabular}{l | l}
1 & 2 \\
\hline
3 & 4
\end{tabular}
\end{table}
%
\begin{equation}\label{eq1}
a = b
\end{equation}
%
\begin{figure}[b]
\centering
\rule{3cm}{2cm}
\caption{A black rectangle}\label{fig1}
\end{figure}
%
\begin{proposition}
Blah.
\end{proposition}
%
Theorem~\wrong{\ref{thm1}}. Equation~\eqref{eq1}. \blindtext{301}\space Table~\ref{tbl1}. Equation~\eqref{eq2}.\par
%
\begin{equation}
c = d
\end{equation}
%
\begin{table}[t]
\centering
\tablecaption{Another table}\label{tbl1}
\begin{tabular}{l | l}
a & b \\
\hline
c & d
\end{tabular}
\end{table}
%
\begin{theorem}
Blah.
\begin{equation}
e = f
\end{equation}
\end{theorem}
%
Footnote~\ref{fn1}. \blindtext{398}[\footnotemark], blah\footnotemark, blah\footnote{\label{fn1}A footnote.}. Footnote~\ref{fn1}. Theorem~\wrong{\ref{thm1}}. Equations~\eqref{eq1} and~\eqref{eq2}. Figure~\ref{fig1}.\par
%
\blindtext{519}
%
\begin{align}
\alpha &= \beta \\
\gamma &= \delta \\
\varepsilon &= \zeta \label{eq2}
\end{align}
%
\blindtext{528}\space Figure~\wrong{\ref{fig2}}. Proposition~\wrong{\ref{prop1}}.\par
%
\begin{proposition}\label{prop1}
Blah.
\end{proposition}
%
Proposition~\wrong{\ref{prop1}}.
%
\begin{figure}[p]
\centering
\rule{4cm}{3cm}
\caption{Another black rectangle}\label{fig2}
\end{figure}
%
\end{document}