Closed xkwxdyy closed 1 month ago
因为论文模板的设置需求,我可能需要将
\clearpage
和\cleardoublepage
设置为\relax
。
不要这样做。很多 shipout/页面输出依赖于 \clearpage
和 \cleardoublepage
的原本定义,尤其是里面的 \newpage
部分。
原本的需求是什么?
用 latex 编译后,日志文件输出:
This is XeTeX, Version 3.141592653-2.6-0.999996 (TeX Live 2024) (preloaded format=xelatex 2024.4.3) 6 APR 2024 00:35 entering extended mode
最好说「用 xelatex 编译后」,因为「用 latex 编译」更多时候表示用 latex main.tex
编译,实际使用的是 pdflatex。
感觉应该是和
\AtEndDocument
的定义有关,但我没查到
不,不用 \AtEndDocument
,最后一页的内容也没有输出。
\documentclass{book}
\ExplSyntaxOn
\cs_set_eq:NN \clearpage \relax
\ExplSyntaxOff
\begin{document}
test
\end{document}
这是因为最后一页的输出,是由 \enddocument
里的 \clearpage
里的 \newpage
触发的。
\enddocument
在 LaTeX2e 2023-11-01 里的定义```tex %% run "latexdef -s \enddocument" % latex.ltx, line 12222: \def\enddocument{% \@kernel@before@enddocument \UseOneTimeHook{enddocument}% \@kernel@after@enddocument \@checkend{document}% \clearpage \UseOneTimeHook{enddocument/afterlastpage}% \@kernel@after@enddocument@afterlastpage \begingroup \if@filesw \immediate\closeout\@mainaux \let\@setckpt\@gobbletwo \let\@newl@bel\@testdef \let\new@label@record\@kernel@new@label@record@testdef \@tempswafalse \makeatletter \@@input\jobname.aux \fi \UseOneTimeHook{enddocument/afteraux}% \UseOneTimeHook{enddocument/info}% \endgroup \UseOneTimeHook{enddocument/end}% \deadcycles\z@\@@end} ```
加上 \AtEndDocument{...\newpage}
或等价的 \AddToHook{enddocument}{\newpage}
就能正常输出。
我非常不建议全局修改 \clearpage
和 \cleardoublepage
的定义。也许你只需要局部修改它们,也许你的需求可以以其他方式解决,「把 \clearpage
重定义为 \relax
使得最后一页不输出」是一个 X-Y problem。
不要这样做。很多 shipout/页面输出依赖于
\clearpage
和\cleardoublepage
的原本定义,尤其是里面的\newpage
部分。
好的,抱歉,这个
\cs_set_eq:NN \clearpage \relax
\cs_set_eq:NN \cleardoublepage \relax
其实是 VScode 的 copilot 搞出来的... 果然下次还是要小心点……
我非常不建议全局修改
\clearpage
和\cleardoublepage
的定义。也许你只需要局部修改它们,也许你的需求可以以其他方式解决,「把\clearpage
重定义为\relax
使得最后一页不输出」是一个 X-Y problem。
您说的对,我想了一下确实是 X-Y 问题了,可能是昨晚有点心急想把模板写完,有点晚了,就整理了 “Y” 的部分。
我后面发完 issue 后又重新弄了一下。最终发现不能改成 \relax
,而是改成 \newpage
就可以了
\cs_new:Nn \__whu_type_for_library_setting:
{
% 这样设置可以防止 \frontmatter 和 \mainmatter 里面的 \cleardoublepage 产生空白页
\cs_set_eq:NN \clearpage \newpage
\cs_set_eq:NN \cleardoublepage \newpage
}
但您说不要全局修改的话,我得想一下怎么处理。我的最初需求就是“不能产生任何空白页”,然后我加了 openany
之后发现还有,最后发现是 \frontmatter
和 \mainmatter
的问题,然后估计是因为里面有 \cleardoublepage
命令,所以就想着怎么去掉,但是如果直接重定义去掉 \frontmatter
和 \mainmatter
里的 \cleardoublepage
,会影响目录的页码。
我刚想到了:
\cs_new:Nn \__whu_type_for_library_setting:
{
% 这样设置可以防止 \frontmatter 和 \mainmatter 里面的 \cleardoublepage 产生空白页
\cs_set_eq:NN \__whu_cleardoublepage: \cleardoublepage
\AddToHook { cmd / frontmatter / before }
{ \cs_set_eq:NN \cleardoublepage \newpage }
\AddToHook { cmd / frontmatter / after }
{ \cs_set_eq:NN \cleardoublepage \__whu_cleardoublepage: }
\AddToHook { cmd / mainmatter / before }
{ \cs_set_eq:NN \cleardoublepage \newpage }
\AddToHook { cmd / mainmatter / after }
{ \cs_set_eq:NN \cleardoublepage \__whu_cleardoublepage: }
}
这样局部给 \frontmatter
和 \mainmatter
打钩子就行。
最好说「用
xelatex
编译后」,因为「用latex
编译」更多时候表示用latex main.tex
编译,实际使用的是pdflatex
。
抱歉,有点忘记了,我也觉得「用 latex
编译」这个说法怪怪的。感谢提醒。
我的最初需求就是“不能产生任何空白页”
如果是整个文档里都不产生空白页,不知道 \let\cleardoublepage=\clearpage
够不够用。
但是如果直接重定义去掉
\frontmatter
和\mainmatter
里的\cleardoublepage
,会影响目录的页码。
只把 \cleardoublepage
替换为 \clearpage
,应该不会影响页码。如果发现反例,可以提新 issue。
如果是整个文档里都不产生空白页,不知道
\let\cleardoublepage=\clearpage
够不够用。
试了一下,够用的!感谢。我在 source3.pdf
上查到
\cs_new_protected:Npn \cs_set_eq:NN #1 { \tex_let:D #1 =~ }
那这里写成 \cs_set_eq:NN \cleardoublepage \clearpage
也是一样的吧?我试了一下全局设置这个没啥问题,如果按您说的不要全局设置的话,也是像我上面那样改成
\cs_new:Nn \__whu_type_for_library_setting:
{
% 这样设置可以防止 \frontmatter 和 \mainmatter 里面的 \cleardoublepage 产生空白页
\cs_set_eq:NN \__whu_cleardoublepage: \cleardoublepage
\AddToHook { cmd / frontmatter / before }
{ \cs_set_eq:NN \cleardoublepage \clearpage }
\AddToHook { cmd / frontmatter / after }
{ \cs_set_eq:NN \cleardoublepage \__whu_cleardoublepage: }
\AddToHook { cmd / mainmatter / before }
{ \cs_set_eq:NN \cleardoublepage \clearpage }
\AddToHook { cmd / mainmatter / after }
{ \cs_set_eq:NN \cleardoublepage \__whu_cleardoublepage: }
}
打 hook 应该就行吧?(试了一下效果没问题)
我的最初需求就是“不能产生任何空白页”
提供原始需求可以帮助他人理解问题。
我非常不建议全局修改
\clearpage
和\cleardoublepage
的定义。
我觉得可以修改,尤其是比较简单的 \cleardoublepage
,但是改之前要看一下命令的原始定义(可以通过 texdoc source2e
找到),其中没搞懂的部分要尽可能保留。像 ustcthesis 中去掉 \cleardoublepage
空白页的页眉页码就是通过重定义这个命令实现了。
具体这个问题,“不能产生任何空白页”的需求可以使用 \cs_set_eq:NN \cleardoublepage \clearpage
实现。但这个需求太苛刻了,可能导致第 1 页(\mainmatter
)开启在左页,不太符合一般学位论文的习惯。建议再联系老师确认下。
最后发现是
\frontmatter
和\mainmatter
的问题,然后估计是因为里面有\cleardoublepage
命令,所以就想着怎么去掉
这几个命令非常简单,可以读一下源代码后直接重定义。
但是如果直接重定义去掉
\frontmatter
和\mainmatter
里的\cleardoublepage
,会影响目录的页码。
具体有什么影响?
具体这个问题,“不能产生任何空白页”的需求可以使用
\cs_set_eq:NN \cleardoublepage \clearpage
实现。但这个需求太苛刻了,可能导致第 1 页(\mainmatter
)开启在左页,不太符合一般学位论文的习惯。建议再联系老师确认下。
感谢提醒,这个是只有在提交图书馆才会进行这个设置,平时和打印的时候还是正常的 twoside 的。图书馆规定是不能有任何空白页的。
具体有什么影响?
抱歉,mwe 可能给不出来,因为写这种模板类的大项目一遇到问题就很难写 mwe,所以当时就没有整理 mwe。
但我记得效果,就是目录前的页码正常,但是目录开始时的 page
的值变成了 1(但样式没问题,是设置的 Roman),然后正文开始是 2(样式也没问题,是设置的 arabic),就类似于正文的 page 计数器往前移动了。
感觉 for-library
直接用 \if@twoside
控制就可以,不需要搞这么一大堆 hook。即 \cs_new:Nn \__whu_type_for_library_setting: { \@twosidefalse }
。
感觉
for-library
直接用\if@twoside
控制就可以,不需要搞这么一大堆 hook。即\cs_new:Nn \__whu_type_for_library_setting: { \@twosidefalse }
。
空白页确实可以去掉,这样做的原理是什么呢,为什么这样可以去掉空白页呢?
不过这样也有问题,一些奇偶不同的页眉页脚设置就失效了,变成了奇偶相同的了。
空白页确实可以去掉,这样做的原理是什么呢,为什么这样可以去掉空白页呢?
不过这样也有问题,一些奇偶不同的页眉页脚设置就失效了,变成了奇偶相同的了。
嗯确实。大致就是修改这个几个命令,哪个方法都差不多。另外提醒一下 \chapter
也有 \cleardoublepage
。
我建议开一个新 issue 讨论「如何不产生任何空白页」,重新描述一次需求,如因为用了、设置了什么产生的空白页(因为 article
文档类不产生空白页)、哪些空白页需要避免、哪些需要保留、整个文档有没有奇偶页的概念、哪些设置需要保持奇偶页不同。
检查清单
操作系统
mac os 14
TeX 发行版
TeXLive 2024
描述问题
因为论文模板的设置需求,我可能需要将
\clearpage
和\cleardoublepage
设置为\relax
。但是发现设置之后\AtEndDocument
里的内容并没有生成。最小工作示例(MWE)
用
latex
编译后,日志文件输出:并没有PDF 生成
链接
其他信息
感觉应该是和
\AtEndDocument
的定义有关,但我没查到附件
No response