![在某个时间点之后反转页面顺序的 hack 被最新版本的 polyglossia 破坏](https://linux22.com/image/434312/%E5%9C%A8%E6%9F%90%E4%B8%AA%E6%97%B6%E9%97%B4%E7%82%B9%E4%B9%8B%E5%90%8E%E5%8F%8D%E8%BD%AC%E9%A1%B5%E9%9D%A2%E9%A1%BA%E5%BA%8F%E7%9A%84%20hack%20%E8%A2%AB%E6%9C%80%E6%96%B0%E7%89%88%E6%9C%AC%E7%9A%84%20polyglossia%20%E7%A0%B4%E5%9D%8F.png)
在这个问题中:
用户 @BrunoLeFloch 提供了一个非常有用的使用该包进行页面反转的技巧atbegshi
。不幸的是,在最新版本的 TeXLive 中,当同时使用希伯来语和英语时,这会触发错误,由于细节超出了我的能力范围,我想请大家帮忙了解问题所在。这是一个最简单的例子:
\documentclass{article}
\usepackage{atbegshi}
\makeatletter
\usepackage{polyglossia}
\setmainlanguage{english}
\setotherlanguage{french}
\newif\ifRP%
\newbox\RPbox%
\setbox\RPbox\vbox{\vskip1pt}%
\AtBeginShipout{%
\ifRP
\AtBeginShipoutDiscard%
\global\setbox\RPbox\vbox{\unvbox\RPbox
\box\AtBeginShipoutBox\kern\c@page sp}%
\fi
}%
\renewcommand{\RPtrue}{% reverse page order
\clearpage
\ifRP\RPfalse\fi
\global\let\ifRP\iftrue
}%
\renewcommand{\RPfalse}{% resume normal page order
\clearpage
\global\let\ifRP\iffalse
\setbox\RPbox\vbox{\unvbox\RPbox
\def\protect{\noexpand\protect\noexpand}%
\@whilesw\ifdim0pt=\lastskip\fi
{\c@page\lastkern\unkern\shipout\lastbox}%
}%
}%
\makeatother
\begin{document}
\RPtrue
\begin{french}
Fou
\newpage
\end{french}
Bar % Note: Originally, this question was posted without the extra text.
\RPfalse
\end{document}
错误信息:
! Missing } inserted.
<inserted text>
}
l.48 \end{document}
我应该提到这确实适用于 TeXLive 2019。
编辑:以下是 TL 2021 的 .aux 文件:
\relax
\selectlanguage *{english}
\@writefile{toc}{\selectlanguage *{english}}
\@writefile{lof}{\selectlanguage *{english}}
\@writefile{lot}{\selectlanguage *{english}}
\bgroup
\@writefile{toc}{\bgroup }
\@writefile{lof}{\bgroup }
\@writefile{lot}{\bgroup }
\selectlanguage *{french}
\@writefile{toc}{\selectlanguage *{french}}
\@writefile{lof}{\selectlanguage *{french}}
\@writefile{lot}{\selectlanguage *{french}}
\gdef \@abspage@last{1}
2019 年的情况如下:
\relax
\protect \select@language {english}
\@writefile{toc}{\protect \select@language {english}}
\@writefile{lof}{\protect \select@language {english}}
\@writefile{lot}{\protect \select@language {english}}
\protect \select@language {french}
\@writefile{toc}{\protect \select@language {french}}
\@writefile{lof}{\protect \select@language {french}}
\@writefile{lot}{\protect \select@language {french}}
答案1
有一个内部(etoolbox 样式)布尔值 ( xpg@inbiditable
),polyglossia
您可以在代码中使用它来交换\bgroup
和\egroup
插入到辅助(更新:提供布尔值来解释下面的评论):
\documentclass{article}
\usepackage{atbegshi}
\makeatletter
\usepackage{polyglossia}
\setmainlanguage{english}
\setotherlanguage{french}
\newif\ifRP%
\newbox\RPbox%
\setbox\RPbox\vbox{\vskip1pt}%
\AtBeginShipout{%
\ifRP
\AtBeginShipoutDiscard%
\global\setbox\RPbox\vbox{\unvbox\RPbox
\box\AtBeginShipoutBox\kern\c@page sp}%
\fi
}%
% This boolean is missing in older polyglossia versions
\providebool{xpg@inbiditable}
\renewcommand{\RPtrue}{% reverse page order
\booltrue{xpg@inbiditable}
\clearpage
\ifRP\RPfalse\fi
\global\let\ifRP\iftrue
}%
\renewcommand{\RPfalse}{% resume normal page order
\boolfalse{xpg@inbiditable}
\clearpage
\global\let\ifRP\iffalse
\setbox\RPbox\vbox{\unvbox\RPbox
\def\protect{\noexpand\protect\noexpand}%
\@whilesw\ifdim0pt=\lastskip\fi
{\c@page\lastkern\unkern\shipout\lastbox}%
}%
}%
\makeatother
\begin{document}
\RPtrue
\begin{french}
Fou
\newpage
Bar
\end{french}
\RPfalse
\end{document}
答案2
这只是部分答案,但这是我在合理时间内能做出的最好的答案。
环境otherlanguage
(由 使用\begin{french}...\end{french}
)在页面的开头和结尾处插入一个“whatsit”(\write\@auxout{\bgroup}
和)。当页面实际发送到 pdf 文件时,这两个“whatsit”使 TeX 将和写入辅助文件,以使某些设置在辅助文件中本地化。这有助于确保目录中的标题使用正确的语言规则等。\write\@auxout{\egroup}
\bgroup
\egroup
\selectlanguage
由于我们颠倒了页面的顺序,\bgroup\selectlanguage{french}...\egroup
变成了\egroup \bgroup\selectlanguage{french}...
,这导致 TeX 抱怨嵌套不好(\bgroup
与 相同{
和\egroup
与 相同}
)。
最简单的解决方法是使用\selectlanguage{french} ... \selectlanguage{english}
而不是french
环境,就像我下面做的那样。但是,为了使辅助文件中的语言设置正确,需要经常重新选择语言。我不确定如何正确地做到这一点;一种选择似乎是将其放在\selectlanguage{french}
每个部分标题之前,但这可能还不够。
\documentclass{article}
\usepackage{lipsum}
\usepackage{atbegshi}
\makeatletter
\usepackage{polyglossia}
\setmainlanguage{english}
\setotherlanguage{french}
\newif\ifRP%
\newbox\RPbox%
\setbox\RPbox\vbox{\vskip1pt}%
\AtBeginShipout{%
\ifRP
\AtBeginShipoutDiscard%
\global\setbox\RPbox\vbox{\unvbox\RPbox
\box\AtBeginShipoutBox\kern\c@page sp}%
\fi
}%
\renewcommand{\RPtrue}{% reverse page order
\clearpage
\ifRP\RPfalse\fi
\global\let\ifRP\iftrue
}%
\renewcommand{\RPfalse}{% resume normal page order
\clearpage
\global\let\ifRP\iffalse
\setbox\RPbox\vbox{\unvbox\RPbox
\def\protect{\noexpand\protect\noexpand}%
\@whilesw\ifdim0pt=\lastskip\fi
{\c@page\lastkern\unkern\shipout\lastbox}%
}%
}%
\makeatother
\begin{document}
\section{Start in English}
\lipsum[1-10]
\RPtrue
\selectlanguage{french}
\section{Some French}
\lipsum[11-20]
Fou
\newpage
\selectlanguage{french} % needed just before any section/subsection and perhaps in figures etc.
\section{More French}
\lipsum[21-30]
\selectlanguage{english}
\section{English stuff}
\lipsum[31-40]
\RPfalse
\selectlanguage{english} % needed otherwise the last selectlanguage (after reversal) was french
\section{And finally some English}
\lipsum[41-50]
\end{document}
其他方法可能是仅反转具有相同语言的页面,或者相反确保语言环境不跨越任何分页符。