els-cas-templates模板文档最后放置浮动体总页数不对?

发布于 2025-02-26 21:21:26

mwe.zip
els-cas-templates模板定义了lastpage用以显示总页数:

\def\lastpage{100}

\AtEndDocument{%
%   \clearpage
   \immediate\write\@auxout{\string\csxdef{lastpage}{\thepage}}
}

但是如果文档最后放置浮动体,则总页数只是有文字的最后一页,是什么原因呢?如何解决
image.png

下面是自己实现的一个示例代码,也会出现同样的问题:

\documentclass{article}
\usepackage{graphicx}
\usepackage{lipsum}

\makeatletter
\ExplSyntaxOn
\iow_new:N \l_lastpage_file 
\file_if_exist:nTF{\c_sys_jobname_str.page}
{
  \file_input:n{\c_sys_jobname_str.page}
}
{
  \cs_set_eq:NN \lastpage \relax
}
\AtEndDocument{
\iow_open:Nn \l_lastpage_file{\c_sys_jobname_str.page}
\iow_now:Nx \l_lastpage_file 
{
  \cs_set:Npn \exp_not:N \lastpage 
  {
    \thepage
  }
}
\iow_close:N \l_lastpage_file 
}
\cs_new:Npn \__first_foot: 
{ 
  \parbox[t]{\textwidth}
  { 
    ~  \hfill Page~ \thepage {} ~of~ \lastpage }
} 
\cs_set_eq:NN \@evenfoot \__first_foot:
\cs_set_eq:NN \@oddfoot \__first_foot:
\ExplSyntaxOff
\makeatother


\begin{document}

\lipsum[1-50]

\begin{figure}
    \centering
    \includegraphics[width=\textwidth]{1}
    \caption{Example image}
\end{figure}

\begin{figure}
    \centering
    \includegraphics[width=\textwidth]{1}
    \caption{Example image}
\end{figure}

\begin{figure}
    \centering
    \includegraphics[width=\textwidth]{1}
    \caption{Example image}
\end{figure}

\begin{figure}
    \centering
    \includegraphics[width=\textwidth]{1}
    \caption{Example image}
\end{figure}

\end{document}

查看更多

关注者
0
被浏览
201
2 个回答
远方不远
远方不远 2025-02-27
这家伙很懒,什么也没写!

l3语法看不懂。下面是在标准文档类中的简短的例子,以供参考。

image.png

image.png

image.png

\documentclass[UTF8]{ctexart}
\usepackage{graphicx,lipsum,zhlipsum,lastpage,mwe,geometry,fancyhdr,pgffor}
  \geometry{margin=2in,showframe,a4paper}
  \pagestyle{fancy}
  \fancyhf{}
  \setlength{\headheight}{12pt}
  \renewcommand{\headrulewidth}{0pt}
\begin{document}

\cfoot{Page~\thepage~of~\pageref{LastPage}}

\lipsum[1-8]

\pagenumbering{arabic}

\zhlipsum[1-4]

\foreach \x in {1,2,3} {
    \begin{figure}
        \centering
        \includegraphics[width=\textwidth]{example-image}
        \caption{Example Image \x}
    \end{figure}
}

\end{document}
Sagittarius Rover
Sagittarius Rover 2025-02-28
我要成为Typst糕手/(ㄒoㄒ)/~~

我还没看你expl3的实现,但是当我们发现在某个模板中lastpage表现异常的时候,我们应该首先在标准文档类中尝试一下lastpage的功能,这样可以确定是文档类设置的冲突问题还是lastpage的问题,@u101077 老师给出的示例已经可以说明,这个问题来源于els-cas-templates模板造成的可能冲突。

同时我们发现els-cas-templates模板已经在TL中包含,因此我们可以做如下的最简测试:

\documentclass{cas-sc}%由于OP的MWE中例子为单列,因此采用`cas-sc`
\usepackage{graphicx}
\usepackage{lipsum}
\usepackage{lastpage}
\usepackage{fancyhdr}
\pagestyle{fancy}
\renewcommand{\headrulewidth}{0pt}
\cfoot{Page~\thepage~of~\pageref{LastPage}}

\begin{document}

\lipsum[1-20]

\begin{figure}
    \centering
    \includegraphics[width=\textwidth]{example-image}
    \caption{Example image}
\end{figure}

\begin{figure}
    \centering
    \includegraphics[width=\textwidth]{example-image}
    \caption{Example image}
\end{figure}

\end{document}
els-cas-templates模板定义了lastpage用以显示总页数,但是如果文档最后放置浮动体,则总页数只是有文字的最后一页

一方面....上面的直接调用cas-sc的MWE并无法体现你的问题,所以首先你应该补充基于els-cas-templates的MWE,以体现这一点。

image.png


另一方面关于你写的自我l3实现,很精彩。这里唯一的小瑕疵是patch的时间不对。我想从结果你也能猜出,\lastpage展开为\thepage的时间仅仅是在排版完所有文本(不包括浮动体)所致,在lthooks-doc.pdfltshipout-doc.pdf中我们可以找到应该在浮动体排版结束之后再加入这个patch:
因此我探索出的一个方法是用\AddToHook{shipout/lastpage},这样可以保证在浮动体被浮动算法排版之后再展开\lastpage\thepage:

(我也不是很懂输出例程(output rountine),无法给出更详细的解释...)

但总而言之,修改后的mwe如下:

\documentclass{article}
\usepackage{graphicx}
\usepackage{lipsum}

\makeatletter
\ExplSyntaxOn
\iow_new:N \l_lastpage_file 
\file_if_exist:nTF{\c_sys_jobname_str.page}
{
  \file_input:n{\c_sys_jobname_str.page}
}
{
  \cs_set_eq:NN \lastpage \relax
}
% \AtEndDocument{%
\AddToHook{shipout/lastpage}{%
\iow_open:Nn \l_lastpage_file{\c_sys_jobname_str.page}
\iow_now:Nx \l_lastpage_file 
{
  \cs_set:Npn \exp_not:N \lastpage 
  {
    \thepage
  }
}
\iow_close:N \l_lastpage_file 
}
\cs_new:Npn \__first_foot: 
{ 
  \parbox[t]{\textwidth}
  {~\hfill Page~\thepage{}~of~ \lastpage}
} 
\cs_set_eq:NN \@evenfoot \__first_foot:
\cs_set_eq:NN \@oddfoot \__first_foot:
\ExplSyntaxOff
\makeatother

\begin{document}

\lipsum[1-50]

\begin{figure}
    \centering
    \includegraphics[width=\textwidth]{example-image}
    \caption{Example image}
\end{figure}

\begin{figure}
    \centering
    \includegraphics[width=\textwidth]{example-image}
    \caption{Example image}
\end{figure}

\begin{figure}
    \centering
    \includegraphics[width=\textwidth]{example-image}
    \caption{Example image}
\end{figure}

\begin{figure}
    \centering
    \includegraphics[width=\textwidth]{example-image}
    \caption{Example image}
\end{figure}

\end{document}

若如此做可以得到:
image.png

此外我的l3编程经验并不多,而且对于l3file模块也不够了解,但我仍感觉你的这一段实现似乎有点不太符合逻辑:

\file_if_exist:nTF{\c_sys_jobname_str.page}
{%
  \file_input:n{\c_sys_jobname_str.page}
}
{%
  \cs_set_eq:NN \lastpage \relax
}

设想如果一个10页的文档首先被编译,那么.page文档首先展开得到\lastpage=10,如果之后添加了部分内容,这个文档变为15页,但是上面的逻辑仍然会得到\lastpage=10,这反复读取.page似乎不利于多次编译,或者需要用户在第一次编译之后使用latexmk -c删除,我不太明白这一设计的目的是什么,如果已有.page就直接使用(为了节省编译时间咩?)如果我来写的话,我反而会担心这一辅助文件记录了上一次编译的信息,所以应该会是类似这样的删除.page的伪代码思路:

\file_if_exist:nT{\c_sys_jobname_str.page}
{%
  %\file_input:n{\c_sys_jobname_str.page}
  <DELETE FILE> \c_sys_jobname_str.page
}
\cs_set_eq:NN \lastpage \relax

因为我不会改,也与本问题无关,因此我没改动。也希望原题主能解释下这里如此设计的思路,以上...


一个彩蛋...似乎旧版本的lastpage使用的也是\AtEndDocument...我有点感到迷惑,是不是旧版的lastpage.sty就会导致这一问题呢...(所以是我不能复现的原因(?),我的版本是2024-07-07 v2.1c):

image.png

撰写答案

请登录后再发布答案,点击登录

发布
问题

分享
好友

手机
浏览

扫码手机浏览