CTeX-org / forum

A temporarily alternate forum of `bbs.ctex.org`
https://t.me/chinesetex
Apache License 2.0
210 stars 16 forks source link

空白页控制问题 #310

Closed xkwxdyy closed 1 month ago

xkwxdyy commented 6 months ago

检查清单

操作系统

mac os 14

TeX 发行版

TeXLive 2024

描述问题

因为论文模板的设置需求,我可能需要将 \clearpage\cleardoublepage 设置为 \relax。但是发现设置之后 \AtEndDocument 里的内容并没有生成。

最小工作示例(MWE)

\documentclass{book}
\ExplSyntaxOn
\cs_set_eq:NN \clearpage \relax
% \cs_set_eq:NN \cleardoublepage \relax
\ExplSyntaxOff
\AtEndDocument{\chapter{1}23}
\begin{document}
% \frontmatter
% \mainmatter
% \backmatter
test

\end{document}

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
 restricted \write18 enabled.
 file:line:error style messages enabled.
 %&-line parsing enabled.
**/Users/xiakangwei/Nutstore/LaTeX/00MWE/MWE3/MWE3
(/Users/xiakangwei/Nutstore/LaTeX/00MWE/MWE3/MWE3.tex
LaTeX2e <2023-11-01> patch level 1
L3 programming layer <2024-03-14>
(/usr/local/texlive/2024/texmf-dist/tex/latex/base/book.cls
Document Class: book 2023/05/17 v1.4n Standard LaTeX document class
(/usr/local/texlive/2024/texmf-dist/tex/latex/base/bk10.clo
File: bk10.clo 2023/05/17 v1.4n Standard LaTeX file (size option)
)
\c@part=\count184
\c@chapter=\count185
\c@section=\count186
\c@subsection=\count187
\c@subsubsection=\count188
\c@paragraph=\count189
\c@subparagraph=\count190
\c@figure=\count191
\c@table=\count192
\abovecaptionskip=\skip48
\belowcaptionskip=\skip49
\bibindent=\dimen140
) (/usr/local/texlive/2024/texmf-dist/tex/latex/l3backend/l3backend-xetex.def
File: l3backend-xetex.def 2024-03-14 L3 backend support: XeTeX
\g__graphics_track_int=\count193
\l__pdf_internal_box=\box51
\g__pdf_backend_object_int=\count194
\g__pdf_backend_annotation_int=\count195
\g__pdf_backend_link_int=\count196
) (./MWE3.aux)
\openout1 = `MWE3.aux'.

LaTeX Font Info:    Checking defaults for OML/cmm/m/it on input line 7.
LaTeX Font Info:    ... okay on input line 7.
LaTeX Font Info:    Checking defaults for OMS/cmsy/m/n on input line 7.
LaTeX Font Info:    ... okay on input line 7.
LaTeX Font Info:    Checking defaults for OT1/cmr/m/n on input line 7.
LaTeX Font Info:    ... okay on input line 7.
LaTeX Font Info:    Checking defaults for T1/cmr/m/n on input line 7.
LaTeX Font Info:    ... okay on input line 7.
LaTeX Font Info:    Checking defaults for TS1/cmr/m/n on input line 7.
LaTeX Font Info:    Trying to load font information for TS1+cmr on input line 7.
 (/usr/local/texlive/2024/texmf-dist/tex/latex/base/ts1cmr.fd
File: ts1cmr.fd 2023/04/13 v2.5m Standard LaTeX font definitions
)
LaTeX Font Info:    ... okay on input line 7.
LaTeX Font Info:    Checking defaults for TU/lmr/m/n on input line 7.
LaTeX Font Info:    ... okay on input line 7.
LaTeX Font Info:    Checking defaults for OMX/cmex/m/n on input line 7.
LaTeX Font Info:    ... okay on input line 7.
LaTeX Font Info:    Checking defaults for U/cmr/m/n on input line 7.
LaTeX Font Info:    ... okay on input line 7.

Chapter 1.
(./MWE3.aux)
 ***********
LaTeX2e <2023-11-01> patch level 1
L3 programming layer <2024-03-14>
 ***********
 ) 
Here is how much of TeX's memory you used:
 487 strings out of 474761
 9985 string characters out of 5757510
 1918145 words of memory out of 5000000
 22726 multiletter control sequences out of 15000+600000
 558101 words of font info for 40 fonts, out of 8000000 for 9000
 1348 hyphenation exceptions out of 8191
 35i,1n,50p,183b,113s stack positions out of 10000i,1000n,20000p,200000b,200000s

No pages of output.

并没有PDF 生成

链接

其他信息

感觉应该是和 \AtEndDocument 的定义有关,但我没查到

附件

No response

muzimuzhi commented 6 months 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

xkwxdyy commented 6 months ago

不要这样做。很多 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 编译」这个说法怪怪的。感谢提醒。

muzimuzhi commented 6 months ago

我的最初需求就是“不能产生任何空白页”

如果是整个文档里都不产生空白页,不知道 \let\cleardoublepage=\clearpage 够不够用。

但是如果直接重定义去掉 \frontmatter\mainmatter 里的 \cleardoublepage ,会影响目录的页码。

只把 \cleardoublepage 替换为 \clearpage,应该不会影响页码。如果发现反例,可以提新 issue。

xkwxdyy commented 6 months ago

如果是整个文档里都不产生空白页,不知道 \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 应该就行吧?(试了一下效果没问题)

zepinglee commented 6 months ago

我的最初需求就是“不能产生任何空白页”

提供原始需求可以帮助他人理解问题。

我非常不建议全局修改 \clearpage\cleardoublepage 的定义。

我觉得可以修改,尤其是比较简单的 \cleardoublepage,但是改之前要看一下命令的原始定义(可以通过 texdoc source2e 找到),其中没搞懂的部分要尽可能保留。像 ustcthesis 中去掉 \cleardoublepage 空白页的页眉页码就是通过重定义这个命令实现了。

Screenshot 2024-04-06 at 21 05 16

具体这个问题,“不能产生任何空白页”的需求可以使用 \cs_set_eq:NN \cleardoublepage \clearpage 实现。但这个需求太苛刻了,可能导致第 1 页(\mainmatter)开启在左页,不太符合一般学位论文的习惯。建议再联系老师确认下。

最后发现是 \frontmatter\mainmatter 的问题,然后估计是因为里面有 \cleardoublepage 命令,所以就想着怎么去掉

这几个命令非常简单,可以读一下源代码后直接重定义。

但是如果直接重定义去掉 \frontmatter\mainmatter 里的 \cleardoublepage ,会影响目录的页码。

具体有什么影响?

xkwxdyy commented 6 months ago

具体这个问题,“不能产生任何空白页”的需求可以使用 \cs_set_eq:NN \cleardoublepage \clearpage 实现。但这个需求太苛刻了,可能导致第 1 页(\mainmatter)开启在左页,不太符合一般学位论文的习惯。建议再联系老师确认下。

感谢提醒,这个是只有在提交图书馆才会进行这个设置,平时和打印的时候还是正常的 twoside 的。图书馆规定是不能有任何空白页的。

具体有什么影响?

抱歉,mwe 可能给不出来,因为写这种模板类的大项目一遇到问题就很难写 mwe,所以当时就没有整理 mwe。 但我记得效果,就是目录前的页码正常,但是目录开始时的 page 的值变成了 1(但样式没问题,是设置的 Roman),然后正文开始是 2(样式也没问题,是设置的 arabic),就类似于正文的 page 计数器往前移动了。

zepinglee commented 6 months ago

感觉 for-library 直接用 \if@twoside 控制就可以,不需要搞这么一大堆 hook。即 \cs_new:Nn \__whu_type_for_library_setting: { \@twosidefalse }

xkwxdyy commented 6 months ago

感觉 for-library 直接用 \if@twoside 控制就可以,不需要搞这么一大堆 hook。即 \cs_new:Nn \__whu_type_for_library_setting: { \@twosidefalse }

空白页确实可以去掉,这样做的原理是什么呢,为什么这样可以去掉空白页呢?

不过这样也有问题,一些奇偶不同的页眉页脚设置就失效了,变成了奇偶相同的了。

zepinglee commented 6 months ago

空白页确实可以去掉,这样做的原理是什么呢,为什么这样可以去掉空白页呢?

Screenshot 2024-04-07 at 12 15 20

不过这样也有问题,一些奇偶不同的页眉页脚设置就失效了,变成了奇偶相同的了。

嗯确实。大致就是修改这个几个命令,哪个方法都差不多。另外提醒一下 \chapter 也有 \cleardoublepage

Screenshot 2024-04-07 at 12 22 27
muzimuzhi commented 6 months ago

我建议开一个新 issue 讨论「如何不产生任何空白页」,重新描述一次需求,如因为用了、设置了什么产生的空白页(因为 article 文档类不产生空白页)、哪些空白页需要避免、哪些需要保留、整个文档有没有奇偶页的概念、哪些设置需要保持奇偶页不同。