该everypage
软件包最后一次修改是在 2007 年 6 月(https://www.ctan.org/pkg/everypage)。然而,在过去的几个月里,自从我升级了 LaTeX 安装后,它的行为就不同了。唯一合乎逻辑的结论是,底层 TeX 发生了一些变化,导致了这种行为。
我在回答中注意到了这一点有哪些方法可以将内容绝对定位在页面上?。我已经“修正”了该答案以解释这些变化,尽管我仍然对这些变化感到不安。在修订后的答案中, 的定义\atxy
如下
\newcommand\atxy[3]{%
\AddThispageHook{\hspace*{\dimexpr-\PageLeftMargin-\hoffset+#1\relax}\smash{%
\raisebox{\dimexpr\PageTopMargin+\voffset-#2\relax}{\textcolor{red}{#3}}}%
\setbox0=\hbox{#3}%
\hspace*{-\dimexpr\wd0-\PageLeftMargin-\hoffset+#1\relax}%
}}
但最初的定义更简单:
\newcommand\atxy[3]{%
\AddThispageHook{\smash{\hspace*{\dimexpr-\PageLeftMargin-\hoffset+#1\relax}%
\raisebox{\dimexpr\PageTopMargin+\voffset-#2\relax}{\textcolor{red}{#3}}}}}
但是,使用 的原始定义\atxy
,输出从
更改为:
发生了什么事?我最终弄清楚了,之前,每个元素都是\AddThispageHook
相对于左边距开始排版的。现在,每个元素都是相对于前一个元素停止\AddThispageHook
的左/右边距位置进行排版的。\AddThispageHook
您可以在示例中看到,这(6,4)
是首字母\atxy
,并且排版正确。下一个是(0,1)
。现在,它不是相对于纸张边缘设置的,而是相对于设置的(6,4)
。当我进行第三次调用时,\textbullet(5,6)
我已经从纸张的右边缘掉下来了,再也看不见了。
我最终\atxy
对上面所见的内容进行了修改,通过使用\hspace
向左移动回到左边距的起始点,遵循排版来修复此行为。这样,旧版和新版 LaTeX 安装的行为都相同。
\\
然而,这次修订是我第二次尝试。我第一次尝试在末尾添加一个,\AddThispageHook
以使“光标”返回到左边距。虽然这修复了“较新”的 LaTeX 行为,但它实际上破坏了“较旧”的 LaTeX 安装的行为,然后它会抱怨没有行可以结束(尝试在\\
没有文本的行时的标准错误)。
因此,一方面,我通过重写\atxy
来解释新everypage
行为,从而回答了我的问题。但由于该软件包多年未升级,我担心 TeX 内部发生了一些变化,这可能会以其他方式反过来困扰我。
如果能对 TeX 内部的哪些变化导致了这种行为everypage
以及在什么情况下需要注意这种意外变化可能会影响其他代码片段有一个明确的诊断,那就太好了。我尝试联系软件包作者,但没有成功。
这是一个 MWE,如果你想玩的话
\documentclass{article}
\usepackage{everypage}
\usepackage{xcolor}
\usepackage{lipsum}
% THESE ARE LaTeX DEFAULTS; CAN CHANGE IF NEEDED.
\def\PageTopMargin{1in}
\def\PageLeftMargin{1in}
% REVISED DEFINITION
\newcommand\atxy[3]{%
\AddThispageHook{\hspace*{\dimexpr-\PageLeftMargin-\hoffset+#1\relax}\smash{%
\raisebox{\dimexpr\PageTopMargin+\voffset-#2\relax}{\textcolor{red}{#3}}}%
\setbox0=\hbox{#3}%
\hspace*{-\dimexpr\wd0-\PageLeftMargin-\hoffset+#1\relax}%
}}
% ORIGINAL DEFINITION
\renewcommand\atxy[3]{%
\AddThispageHook{\smash{\hspace*{\dimexpr-\PageLeftMargin-\hoffset+#1\relax}%
\raisebox{\dimexpr\PageTopMargin+\voffset-#2\relax}{\textcolor{red}{#3}}}}}
% VERIFIED THAT SETTING \hoffset AND \voffset DO NOT BREAK SOLUTION.
%\hoffset=0.4in
%\voffset=0.2in
\begin{document}
\atxy{6in}{4in}{(6,4)}
\lipsum[1]
\atxy{0in}{1in}{(0,1)}
\atxy{5in}{6in}{\textbullet(5,6)}
\atxy{5in}{6.2in}{\makebox[0pt]{centered at (5,6.2)}}
\end{document}
答案1
您的代码暗中利用了 \smash 在旧系统中充当 \hbox 的事实。这意味着它没有切换到水平模式:
\documentclass{article}
\begin{document}
\smash{abc}
\smash{xyz}
\end{document}
texlive 2017 中的输出:
立即输出
如果你在 smash 周围添加一个 \hbox,你就会回到以前的行为:
\documentclass{article}
\usepackage{everypage}
\usepackage{xcolor}
\usepackage{lipsum}
% THESE ARE LaTeX DEFAULTS; CAN CHANGE IF NEEDED.
\def\PageTopMargin{1in}
\def\PageLeftMargin{1in}
% ORIGINAL DEFINITION
\newcommand\atxy[3]{%
\AddThispageHook{\hbox{\smash{\hspace*{\dimexpr-\PageLeftMargin-\hoffset+#1\relax}%
\raisebox{\dimexpr\PageTopMargin+\voffset-#2\relax}{\textcolor{red}{#3}}}}}}
% VERIFIED THAT SETTING \hoffset AND \voffset DO NOT BREAK SOLUTION.
%\hoffset=0.4in
%\voffset=0.2in
\begin{document}
\atxy{6in}{4in}{(6,4)}
\lipsum[1]
\atxy{0in}{1in}{(0,1)}
\atxy{5in}{6in}{\textbullet(5,6)}
\atxy{5in}{6.2in}{\makebox[0pt]{centered at (5,6.2)}}
\end{document}