在某个时间点之后反转页面顺序的 hack 被最新版本的 polyglossia 破坏

在某个时间点之后反转页面顺序的 hack 被最新版本的 polyglossia 破坏

在这个问题中:

从某一点开始反转页面顺序

用户 @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}

其他方法可能是仅反转具有相同语言的页面,或者相反确保语言环境不跨越任何分页符。

相关内容