Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

我想将某些内容固定排版在偶数页的页面底部,但使用\ifodd\value{page}进行判断时在某些情形下会失效 #288

Open
4 of 11 tasks
djunhao opened this issue Apr 23, 2023 · 4 comments

Comments

@djunhao
Copy link

djunhao commented Apr 23, 2023

检查

  • 已在 issues 中进行搜索(包括已关闭的问题)

编译环境

  • 操作系统

    • Windows 10/11
    • Windows 8/8.1
    • Windows 7
    • 更早版本的 Windows
    • macOS
    • Linux(请附发行版)
  • TeX 发行版

    • TeX Live 2023
    • MiKTeX
    • CTeX 套装 2.9.2.164
    • 更早版本的 CTeX 套装

我的问题:

我希望将一些内容排版在偶数页的页面底部,使用了_\ifodd\value{page}_来判断当前页是否奇数页。如果是,则创建一个新页面来排版需要置底的内容。但是,实践时发现,有时会碰到排版无法达到预期目的的情况。
经过多次尝试,目前发现以下三种种情况会导致置底内容无法排版在偶数页:

  1. 正文内容刚好排满偶数页;
  2. 当前正文在偶数页,且剩余高度不足于用来排版置底内容;
  3. 奇数页字数很少(文字少于一行。只要有第二行文字,置底内容就能正常排版在新建的偶数页。)

出现以上任意一种情形时,置底内容将会直接在下一页排版(奇数页)。以下代码展示了第三种情形:

示例代码

\documentclass[fontset=windows,linespread=1.5625]{ctexart}
\usepackage[a4paper,twoside,top=35mm,bottom=35mm,left=28mm,right=26mm,showframe]{geometry}
\usepackage{zhlipsum}
\newcommand{\makenotes}
{
\par
\ifodd\value{page}
\clearpage
\thispagestyle{empty}%
\hbox{}
\fi
% \null
% \vfill
\vspace*{\fill}
\noindent
\begin{tabular}{l}
\hline
《史记·十二本纪·项羽本纪》 \\
\hline
\end{tabular}
}
\begin{document}
\zihao{3}\fangsong
\zhlipsum[1-5][name=xiangyu]
\makenotes
\end{document}

请问各位老师、前辈,以上代码是哪里出错了吗?

@Sophanatprime
Copy link

Sophanatprime commented Apr 23, 2023

LaTeX 在执行到 \ifodd 时,还不知道自己要不要换页,所以 \value{page} 还是没换页时候的值。
应该告诉 LaTeX 还需要多少空间,在 LaTeX 决定要不要换页之后,才能得到想要的 \value{page}

\documentclass[fontset=windows,linespread=1.5625]{ctexart}
\usepackage[a4paper,twoside,top=35mm,bottom=35mm,left=28mm,right=26mm,showframe]{geometry}
\usepackage{zhlipsum}
\usepackage{needspace}

\newsavebox\makenotesbox
\newcommand{\makenotestext}
  {\begin{tabular}[b]{l}
     \hline
    《史记·十二本纪·项羽本纪》 \\
     \hline
   \end{tabular}}
\newcommand{\makenotes}
  {
    \par 
    \sbox{\makenotesbox}{\parbox[b]{\textwidth}{\makenotestext}}
    \needspace{%
      \ifdim\dp\makenotesbox>\maxdepth
        \dimexpr\ht\makenotesbox+\dp\makenotesbox-\maxdepth\relax
      \else \ht\makenotesbox\fi}
    \ifodd\value{page}
      \ifdim\pagegoal=\maxdimen \hbox{}\thispagestyle{empty}\fi
      \clearpage
      \thispagestyle{empty}%
      \hbox{}
    \fi
%   \null
%   \vfill
    \vspace*{\fill}
    \noindent \usebox{\makenotesbox}\newpage
  }

\begin{document}
\zihao{3}\fangsong
\zhlipsum[1-5][name=xiangyu]
\makenotes
\end{document}

@muzimuzhi
Copy link
Collaborator

使用 \value{page} 获得的不一定是当前页数,于是对它的奇偶判断也会出错。比如,用在一个跨页的段落里时,不论插入 \value{page} 的位置对应输出后换页前还是换页后的部分,\value{page} 获得的总是换页前的页数。

这里需要「仅在 shipout/输出一页 时展开」,对应的就是 \write(见 TeX by Topic, sec. 12.6.3 Expansion and \write),缺点是需要第二次编译。这就是 ifoddpage 包封装的 \ifoddpage

PS:texlive 2023 开始,\special 获得了一个新的关键词 shipout\special shipout<general text> 可以和 \write 一样,仅在 shipout 时展开 <general text>。详见 https://tug.org/texlive/doc/texlive-en/texlive-en.html#x1-920009.2https://tex.stackexchange.com/q/681452

@Sophanatprime
Copy link

在OP这种问题下,如果仅仅使用 \label 这类技术,最坏情况需要编译 n+1 次,而不是固定的两次吧,而且估计编译次数超过2次的概率比平时大。和 needspace 配合使用的话,当然是更好的选择。(除非取消某些页的 shipout,不用写入辅助文件的方式应该也行吧。)

\special 里好像不能放盒子?

@djunhao
Copy link
Author

djunhao commented Apr 24, 2023

谢谢 @Sophanatprime 前辈提供的解决方案。
谢谢 @muzimuzhi 老师提供的信息,我好好研究一下。主要是本人的水平很菜,有些很简单的问题可能也需要很长时间看文档、搜索示例才能弄明白。汗!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants