0

I am trying to extend the rotating package to also show the respective pages properly rotated in the PDF output by setting the PDF page attribute /Rotate. I have a working version for XeLaTeX, however, I don't manage to get this done for LuaLaTeX. Please consider the following MWE:

\documentclass{article}
\usepackage{lipsum}
\usepackage{rotating}
\usepackage{etoolbox}
\usepackage{iftex}
\usepackage{afterpage}

\ifLuaTeX
    \edef\pdfpageattr{\pdfvariable pageattr}
\fi

\makeatletter
    \def\@PDFrot#1{%
        \ifXeTeX%
            \special{pdf: put @thispage <</Rotate #1>>}%
        \fi%
        \ifLuaTeX%
            \global\pdfpageattr\expandafter{\the\pdfpageattr/Rotate #1}%
            \afterpage{\global\pdfpageattr\expandafter{\the\pdfpageattr/Rotate 0}}%
        \fi%
    }

    \patchcmd{\@xrotfloat}%
        {\begin{minipage}\textheight}%
        {\begin{minipage}\textheight\@PDFrot{90}}%
        {}{}%
\makeatother

\begin{document}

    \lipsum[1-10]

    \begin{sidewaysfigure}
        \centering
        Test
        \caption{Just an example figure.}
    \end{sidewaysfigure}

    \lipsum[1-5]

\end{document}

When compiling this MWE with XeLaTeX, one will get the desired behavior: The float page with the sidewaysfigure contents (page 3) is properly rotated in the PDF output. But when compiled with LuaLaTeX, also page 2 will be rotated, too, which is not desired.


Desired PDF page orientations when compiled with XeLaTeX. Desired PDF page orientations when compiled with XeLaTeX.


Wrong PDF page orientation of page 2 when compiled with LuaLaTeX. Wrong PDF page orientation of page 2 when compiled with LuaLaTeX.


I think this is because the definition of the sidewaysfigure contents (together with setting the PDF attribute) will already be evaluated on page 2, where the content would appear if it would not be a float. I've found no way of circumventing this problem and would be glad for any idea.

N.B.: The MWE is just a reduced example, which does not properly take the orientation of the page based on its page number (even/odd) into account. I eliminated these code parts for the sake of easier understanding of the MWE.

1

3 Answers 3

1

Based on the answer to another question provided in comment by Ulrike Fischer, I developed the following patch which also takes even/odd pages into account:

\documentclass{article}
\usepackage{lipsum}
\usepackage{rotating}
\usepackage{etoolbox}
\usepackage{iftex}
\usepackage{pdflscape}
\usepackage{atbegshi}
\usepackage{zref-user}

\makeatletter
    \ifXeTeX%
        \patchcmd{\@xrotfloat}%
            {\begin{minipage}\textheight}%
            {%
                \begin{minipage}\textheight%
                \ifnumodd{\thepage}%
                    {\special{pdf: put @thispage <</Rotate 90>>}}%
                    {\special{pdf: put @thispage <</Rotate -90>>}}%
            }%
            {}{}%
    \fi%
    \ifLuaTeX%
        \newcounter{cntsideways}%
        \AtBeginShipout{%
            \ifnum\zref@extractdefault{rotate\number\value{page}}{page}{0}=0%
                \PLS@RemoveRotate%
            \else%
                \ifnumodd{\thepage}{\PLS@AddRotate{90}}{\PLS@AddRotate{-90}}%
            \fi}%
        \patchcmd{\@xrotfloat}%
            {\begin{minipage}\textheight}%
            {\begin{minipage}\textheight\rotatesidewayslabel}%
            {}{}%
        \newcommand\rotatesidewayslabel{\stepcounter{cntsideways}%
        \zlabel{tmp\thecntsideways}\zlabel{rotate\zref@extractdefault{tmp\thecntsideways}{page}{0}}}%
    \fi%
\makeatother

\begin{document}

    \lipsum[1-10]

    \begin{sidewaysfigure}
        \centering
        Test
        \caption{Just an example figure.}
    \end{sidewaysfigure}

    \lipsum[1-5]

\end{document}

Thank you!

1

The primary problem is that \afterpage works fine, but setting the pageattribute has to be delayed until TeX no longer works on the previous page. Luckily, \latelua allows executing Lua code which is delayed to a proper moment, so you can use

\documentclass{article}
\usepackage{lipsum}
\usepackage{rotating}
\usepackage{etoolbox}
\usepackage{iftex}
\usepackage{afterpage}

\ifLuaTeX
    \edef\pdfpageattr{\pdfvariable pageattr}
\fi

\makeatletter
    \def\@PDFrot#1{%
        \ifXeTeX%
            \special{pdf: put @thispage <</Rotate #1>>}%
        \fi%
        \ifLuaTeX%
            \latelua{pdf.setpageattributes(string.gsub(pdf.getpageattributes() or '', '/Rotate [+-]?\csstring\%d+', '') .. '/Rotate #1')}%
            \afterpage{\directlua{pdf.setpageattributes((string.gsub(pdf.getpageattributes(), '/Rotate #1', '')))}}%
        \fi%
    }

    \patchcmd{\@xrotfloat}%
        {\begin{minipage}\textheight}%
        {\begin{minipage}\textheight\@PDFrot{90}}%
        {}{}%
\makeatother

\begin{document}

    \lipsum[1-10]

    \begin{sidewaysfigure}
        \centering
        Test
        \caption{Just an example figure.}
    \end{sidewaysfigure}

    \lipsum[1-5]


    \lipsum[1-10]

    \begin{sidewaysfigure}
        \centering
        Test
        \caption{Just an example figure.}
    \end{sidewaysfigure}

    \lipsum[1-5]


    \lipsum[1-10]

    \begin{sidewaysfigure}
        \centering
        Test
        \caption{Just an example figure.}
    \end{sidewaysfigure}

    \lipsum[1-5]

\end{document}
2
  • If the sidewaysfigure directly follow each other, one ends with multiply attributes in the pdf: /Rotate 90/Rotate 90/Rotate 90. (And there is a stray ishow\@xrotfloat in your code). Commented Mar 16, 2019 at 18:23
  • It looks as if for once afterpage is actually useful - I wonder what @DavidCarlisle will say about this ;-). Commented Mar 16, 2019 at 19:12
0

While DigNative's solution for XeLaTeX works for the most part, I had some trouble with it. It turns out that \thepage expands to the page number as it is on the first run, which might not equal the page number in the final run. 1 Specifically, I got different results based on whether I used \clearpage before the sidewaysfigure or not, or when I had multiple figures following each other.

To solve this, I went for an approach with \label+\pageref, similar to what Ulrike Fischer mentioned in this comment. One side note: because \pageref does not expand to a number but to text (which depends on the \pagenumbering, so it might not even look like a number), I had to use the \getpagerefnumber command from the refcount package. 2

Note that I didn't update the LuaLaTeX part, that seems to work fine. But as I'm using XeLaTeX, I wanted to throw in this fix :)

\documentclass[twoside]{article}
\usepackage{lipsum}
\usepackage{rotating}
\usepackage{etoolbox}
\usepackage{iftex}
\usepackage{pdflscape}
\usepackage{refcount}
\usepackage{atbegshi}
\usepackage{zref-user}

\makeatletter
    \ifXeTeX%
        \newcounter{rotfigcount}%
        \patchcmd{\@xrotfloat}%
            {\begin{minipage}\textheight}%
            {%
                \begin{minipage}\textheight%
                \stepcounter{rotfigcount}%
                \label{rotfig:\therotfigcount}%
                \ifnumodd{\getpagerefnumber{rotfig:\therotfigcount}}%
                    {\special{pdf: put @thispage <</Rotate 90>>}}%
                    {\special{pdf: put @thispage <</Rotate -90>>}}%
            }%
            {}{}%
    \fi%
    \ifLuaTeX%
        \newcounter{cntsideways}%
        \AtBeginShipout{%
            \ifnum\zref@extractdefault{rotate\number\value{page}}{page}{0}=0%
                \PLS@RemoveRotate%
            \else%
                \ifnumodd{\thepage}{\PLS@AddRotate{90}}{\PLS@AddRotate{-90}}%
            \fi}%
        \patchcmd{\@xrotfloat}%
            {\begin{minipage}\textheight}%
            {\begin{minipage}\textheight\rotatesidewayslabel}%
            {}{}%
        \newcommand\rotatesidewayslabel{\stepcounter{cntsideways}%
        \zlabel{tmp\thecntsideways}\zlabel{rotate\zref@extractdefault{tmp\thecntsideways}{page}{0}}}%
    \fi%
\makeatotherz

\begin{document}

    \lipsum[1-10]

    \begin{sidewaysfigure}
        \centering
        Test
        \caption{Just an example figure.}
    \end{sidewaysfigure}

    \begin{sidewaysfigure}
        \centering
        Test 2
        \caption{Just a second example figure.}
    \end{sidewaysfigure}

    \lipsum[1-5]

\end{document}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .