1

In this question:

Reversing page order from a point onward

user @BrunoLeFloch offered a very useful hack for page reversal using the atbegshi package. Unfortunately, with recent versions of TeXLive, and when using both Hebrew and English, this triggers an error, and since the details are beyond my capabilities, I'd like to ask for help in understanding what's wrong. Here's a minimal(ish) example:

\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}

The error message:

! Missing } inserted.
<inserted text> 
                }
l.48 \end{document}

I should mention this does work with TeXLive 2019.


edit: Here are the .aux files with TL 2021:

\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}

and with 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}}
einpoklum
  • 12,311
  • why do you make your example more complicated by adding hebrew and a hebrew font not every one has? – Ulrike Fischer May 25 '21 at 21:45
  • @UlrikeFischer: 1. If I drop all of the Hebrew stuff, I can't reproduce the error. David CLM is part of the Culmus font package, probably the most popular cross-platform package of Hebrew fonts, and also the default Serif font in LibreOffice. But - IIRC, Ezra SIL is popular in LaTeX examples, so let's have that instead. – einpoklum May 25 '21 at 21:50
  • Actually, I can reproduce this with English and French! See edit. – einpoklum May 25 '21 at 21:55
  • I think that \begin{french} and \end{french} insert on the page some code to \write\@auxout{\bgroup} and \write\@auxout{\egroup}, respectively. When the pages are swapped, these two (delayed) \write commands get swapped, which means that the aux file ends up with \egroup before \bgroup. This is a bad nesting of groups, and it also messes up language settings in the aux file. Putting \RPtrue and \RPfalse inside the environment, or making sure that the language environments don't span more than one page, solves the problem. I don't see how to do better. – Bruno Le Floch May 26 '21 at 22:18
  • @BrunoLeFloch: If this is the case, then why do we not get this error with TeXLive 2019? – einpoklum May 27 '21 at 06:23
  • @einpoklum Presumably polyglossia changed? – Bruno Le Floch May 27 '21 at 10:24
  • @BrunoLeFloch: I've filed an issue on the polyglossia github repo. – einpoklum Jun 21 '21 at 21:04
  • Why don't you switch to babel instead of polyglossia? It at least doesn't insert these groups everywhere. – Ulrike Fischer Jun 22 '21 at 07:12
  • @UlrikeFischer: babel doesn't play nice with xelatex AFAICR; and it has issues of its own. – einpoklum Jun 22 '21 at 14:55
  • 1
    I'm not aware of specific problems with xelatex. 10 years ago this was different, but babel catched up in the last years. It is now well maintained, part of the latex project and gets regularly updates. But for languages with bidi I would consider lualatex anyway, the bidi package used with xelatex had no activity for more than a year I wouldn't trust it to stay stable. – Ulrike Fischer Jun 22 '21 at 15:12
  • @UlrikeFischer: Oh, I didn't realize that was the state of affairs... when I switched to xelatex, bidi and polyglossia my impression was that I was choosing where active community development was continuing ... maybe I mis-perceived. Is lualatex popular among people writing RTL documcnets? And - what do you use with lualatex for RTL content? – einpoklum Jun 22 '21 at 15:19
  • 1
    search the site or the babel documentation, a small example is here https://tex.stackexchange.com/a/573767/2388 – Ulrike Fischer Jun 22 '21 at 15:24

2 Answers2

3

This is a partial answer but it is the best I can do in reasonable time.

The otherlanguage environment (used by \begin{french}...\end{french}) inserts on the page a "whatsit" (\write\@auxout{\bgroup} and \write\@auxout{\egroup}) at the start and at the end of the environment. When the page is actually shipped out to the pdf file, the two "whatsit" make TeX write \bgroup and \egroup to the aux file, to make some \selectlanguage settings be local inside the aux file. This serves to ensure the correct language rules are used for titles in the toc and so on.

Since we are reversing the order of pages, the \bgroup\selectlanguage{french}...\egroup becomes \egroup \bgroup\selectlanguage{french}..., which makes TeX complain about a bad nesting (\bgroup is the same as { and \egroup the same as }).

The simplest workaround is to use \selectlanguage{french} ... \selectlanguage{english} instead of the french environment, as I do below. However, in order for the language setting to be correct everywhere in the aux file, one needs to reselect the language often. I am not sure how to do that properly; one option seems to be to just put \selectlanguage{french} just before every section title, but probably this is not enough.

\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}

Other ways could be to only reverse pages with the same language, or on the contrary make sure that the language environments don't span any page break.

  • Thank you, Bruno, for the effort. Since this goes into a document class of mine, I'll need to give some though to what to do myself and what to tell users of the class to do. There is still the question, though, of why this wasn't a problem in TeXLive 2019; perhaps it's possible to emulate whatever happens there? – einpoklum May 27 '21 at 11:07
  • Look carefully at the aux file you get in TeXLive 2019. I'm almost sure that the \setlanguage entries are in the wrong place so that parts of the aux file use the wrong language. I suppose that polyglossia changed, for instance by adding the \bgroup...\egroup construction, but I really don't know. – Bruno Le Floch May 27 '21 at 22:03
  • Edited the question to add the two aux files. \bgroup has indeed creeped in, but no \egroup. – einpoklum May 27 '21 at 22:56
  • The absence of \egroup comes from the fact that \end{french} is on an otherwise empty page, which gets discarded. Even if you remove all of the RP... code the same problem shows up: there is a \bgroup but no \egroup in the file. It seems adding \let\xpg@set@group@aux\relax and \let\xpg@unset@group@aux\relax after loading polyglossia will remove these groups. However it doesn't actually fix the problem of where \setlanguage entries are put in the aux file. – Bruno Le Floch May 28 '21 at 20:45
  • Actually, the particular problem of the empty page getting discarded is something I'm willing to ignore, at least for the purposes of this question (and since I don't know what the effects of it really are). That is, let's assume the \end{french} occurs on a non-emtpy page (I can even change the question to match), and get the egroup back. My question here is only about getting the error. – einpoklum May 28 '21 at 22:09
  • What I don't understand is where the problem is with the placement of \setlanguage in the aux file. Aren't we seeing the same thing both in TL 2019 and TL 2021 (with the egroup and bgroup removed)? Sorry for asking dumb questions, I'm much less of a TeX expert than my reputation may suggest. – einpoklum May 28 '21 at 22:11
  • Same in TL 2019 and 2021, yes, but both are wrong. If you have page1\newpage \begin{french} page2\newpage page3\end{french}\newpage page4, with the various page N containing section titles etc, then the aux file will have stuff from page 1, then page 3, then \setlanguage{french} then page 2 then page 4. So instead of having stuff from pages 2-3 in French you end up with stuff from pages 2 and 4 in French. The groups are there to restrict settings to a part of the file, stopping before p.4, but even ignoring this, I don't see how to make aux-file stuff from page 3 be in French. – Bruno Le Floch May 30 '21 at 07:19
1

There is an internal (etoolbox-style) boolean (xpg@inbiditable) in polyglossia which you can use in your code to swap \bgroup and \egroup insertion to the aux (UPDATE: provide bool to account for comment below):

\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}

einpoklum
  • 12,311
JSpitzm
  • 1,292
  • When I try this, I get: ! Package etoolbox Error: Boolean '\ifxpg@inbiditable' undefined. Tried with TeXLive 2019 and TeXLive 2021. – einpoklum Jun 26 '21 at 08:20
  • It won't work with the polyglossia version of TL 2019, but it should definitely work with TL 2021. The boolean has been introduced two years ago. Which version of polyglossia do you use? – JSpitzm Jun 26 '21 at 08:58
  • You're right. I was using TL 2021's latexmk, but that falls back to my system's default tex distribution. When I xelatex directly, it works. – einpoklum Jun 26 '21 at 09:03
  • If you want to make the code work on older systems, you can add \providebool{xpg@inbiditable} before the two \booltrue calls in the code. – JSpitzm Jun 26 '21 at 09:05
  • How mysterious... the user of a boolean says "a boolean is provided", and magically it is :-) – einpoklum Jun 26 '21 at 09:10
  • I have updated the code to account for this – JSpitzm Jun 26 '21 at 09:11
  • Oh, sorry, I made an edit myself. Let me revert. – einpoklum Jun 26 '21 at 09:13