我正在尝试使用该ifthen
包自动重新调整一些自定义垂直空间,这样如果文档在第一次编译时有奇数页,第二次编译将减少垂直空间,这样我就能以偶数页完成。但是,我遇到了无法\pageref
返回正确页数的问题。
例如
首次编译产生 3 页。
第二次汇编有 2 页;但页脚显示为第 2 页(共 3 页)。
连续编译无法解决问题;它仍然是“第 2 页,共 3 页”(事实上,在我的实际文档中,第三次编译再次返回 3 页,最后一页显示“第 3 页,共 2 页”。第四次编译然后返回 2 页文档,最后一页再次显示“第 2 页,共 3 页”,并且循环往复。但我无法在我的 MWE 中重现这种情况)。
梅威瑟:
\documentclass[9pt,leqno]{extarticle}
\usepackage{lastpage}
\usepackage{fancyhdr}
\pagestyle{fancy}
\lhead{Detail}
\chead{About}
\rhead{Doc}
\lfoot{Name}
\cfoot{Title}
\rfoot{Pg. \thepage\ of \pageref{LastPage}}
\usepackage{lipsum}
%1. Define custom spaces, with glue
% Full space
\newlength{\myqSp} % Define the length variable
\setlength{\myqSp}{1.3in plus .4in minus .4in} % Initialize value
% Define the different vertical spacing commands
\def\qSp{\vspace{\myqSp}}
\def\sqSp{\vspace{0.25\myqSp}}
\def\mqSp{\vspace{.6\myqSp}}
\usepackage{ifthen}
\begin{document}
% if-then statement for automatically reducing the definition of vertical space if the number of pages is odd. N.B. I have only included the command for the first spacing command (\qSp), to illustrate the MWE.
\ifthenelse{\isodd{\pageref{LastPage}}}{\def\qSp{\vspace{0.3\myqSp}}}{\null}
\lipsum[1] \qSp
\lipsum[1] \qSp
\lipsum[1] \qSp
\lipsum[1] \qSp
\lipsum[1] \qSp
\lipsum[1] \qSp
\lipsum[1] \qSp
\end{document}
动机与推理
首先,我是也在寻找其他解决方案,以便最终得到一份偶数页的文档,并且我知道这可以通过不同的方式(甚至更简单(尽管是手动的))来实现。虽然我非常感谢这方面的建议,但我真的希望了解这个问题,这样我就可以学习 :)
需要此功能与我使用的打印机有关,该打印机不支持双面打印,再加上我要打印多份文档:因此,让文档自动调整垂直空间以确保页数相等,可以大大方便快速高效地组装文档。文档中留下的空间是供学生做作业的,因此非常灵活。
答案1
根据LastPage
docs,它会将页数写入 .aux 文件,并在下一次编译时提供正确的页数。然而,在下一次编译时,由于您的代码,页数会有所不同。因此,如果您使用 LatexMK,那么它将来回运行,直到达到最大运行次数,这就是\pageref{LastPage}
和页数不一致的原因。
因此\pageref{LastPage}
包含的页数以前的运行。一种解决方案是使用指令写入 .aux 文件,\write
说明您已经完成修复,然后不再执行此操作。但是,这种方法只能执行一次,并且必须删除该文件。
相反,我们需要检查奇数/偶数是否真的发生了变化,并在必要时保留我们的更改。让我们看看我们希望它在不同的运行中如何表现:
假设我们首先运行奇数页。比如说 3 页。
- 运行:我们不知道最后一页或之前的页数。什么也不做。
- 运行:我们现在知道文档的最后一页是(3),而且是奇数页。然后我们在文件中写入奇数页,以及下次运行预计的偶数页数(3-1=2)。现在我们通过收紧来修复它。
- run: LastPage 现在告诉我们页数是偶数 (2),但我们仍想进行收紧。我们写道,我们已经处理好了,下次运行时应该有给定的页数 (2)。如果预期页数 (2) 是我们拥有的页数,则进行收紧,并在收紧之前再次写入它实际上是一个奇数,以及我们预期的页数。
- 运行:现在我们已添加一页。我们必须注意到现在的页数不同了(3),但 LastPage 仍显示 2 页。这将在下次运行中更新:
- 页数与预期不同(预期为 2,但实际为 3)。从
.aux
文件中删除所有内容并转到步骤 2!
编辑:如果您在编辑之前使用了以下代码,它可能会做一些奇怪的事情。如下所示:
这确实有效,但需要注意的是:可能会有特殊情况。
\makeatletter
% 'Function' for writing to .aux if we have odd pages, and how many pages to expect.
\def\writeOdd#1{
\edef\toExpect{\number\numexpr\lastpage@lastpage-1}
\write\@auxout{\string\xdef\string\wasodd{#1}}
\write\@auxout{\string\xdef\string\expectPages{\toExpect}}
}
% 'Function' for keeping our values in the aux file
\def\keepOdd{
\write\@auxout{\string\xdef\string\wasodd{\wasodd}}
\write\@auxout{\string\xdef\string\expectPages{\expectPages}}
}
\def\tighten{
\def\qSp{\vspace{0.3\myqSp}}
}
%Do we know whether the last run had an odd number of pages?
\ifcsname wasodd\endcsname
% If it was odd and we got the expected number of pages, then keep our values and do the tightening
\if\wasodd1
\if\expectPages\lastpage@lastpage
\keepOdd
\tighten
\fi
\fi
\else
\ifcsname lastpage@lastpage\endcsname
%We do not know how many pages to expect or whether the last ones were odd, so let's check and do tightening
\ifthenelse{\isodd{\pageref{LastPage}}}{\writeOdd{1}\tighten}{\null}
\fi
\fi
\makeatother
答案2
您的引用中的问题来自重复编译:
在第一遍中,标签的位置存储在 .aux 文件中。此外,在编译结束时(因此后(标签位置已存储)您更改了一些间距,以达到偶数页数。这可能会导致标签最终出现在不同的(较早的页面上)。
在下一次传递时,将使用老的标签位置(可能错误!)。这些位置用于解析引用。然后使用新的标签位置重写辅助文件...
并且您总是使用 pageref 到最后一页来调整下一个编译时,你会遇到问题:
第 1 次运行:最后一页 = 3写入 .aux 文件
第二次运行:从辅助文件读取的 LastPage,值:3 => 用于纠正长度;最后,(当您充分调整长度时)写入新值最后一页 = 2
第三次运行:从辅助文件读取的最后一页,值:2 =>无修正所以你最终会得到 3 页...
等等。
除非必须自动完成此操作,否则我认为最好的方法是将警告打印到控制台/日志文件并手动进行更正。