Extensão do pacote `rotating` para definir a rotação do PDF

Extensão do pacote `rotating` para definir a rotação do PDF

Estou tentando estender o rotatingpacote para mostrar também as respectivas páginas giradas corretamente na saída do PDF, definindo o atributo da página PDF /Rotate. Tenho uma versão funcional para XeLaTeX, porém não consigo fazer isso para LuaLaTeX. Considere o seguinte 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}

Ao compilar este MWE com XeLaTeX, obter-se-á o comportamento desejado: A página flutuante com o sidewaysfigureconteúdo (página 3) é girada corretamente na saída do PDF. Mas quando compilado com LuaLaTeX, a página 2 também será girada, o que não é desejado.


Orientações de página PDF desejadas quando compiladas com XeLaTeX. Orientações de página PDF desejadas quando compiladas com XeLaTeX.


Orientação incorreta da página PDF da página 2 quando compilada com LuaLaTeX. Orientação incorreta da página PDF da página 2 quando compilada com LuaLaTeX.


Acho que isso ocorre porque a definição do sidewaysfigureconteúdo (juntamente com a configuração do atributo PDF) já será avaliada na página 2, onde o conteúdo apareceria se não fosse um float. Não encontrei nenhuma maneira de contornar esse problema e ficaria feliz com qualquer ideia.

Observação:O MWE é apenas um exemplo reduzido, que não leva em consideração adequadamente a orientação da página com base no número da página (par/ímpar). Eliminei essas partes do código para facilitar a compreensão do MWE.

Responder1

Com base noresponda a outra perguntafornecido em comentário por Ulrike Fischer, desenvolvi o seguinte patch que também leva em consideração páginas pares/ímpares:

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

Obrigado!

Responder2

O principal problema é que \afterpagefunciona bem, mas a configuração do atributo page deve ser adiada até que o TeX não funcione mais na página anterior. Felizmente, \lateluapermite executar código Lua que é atrasado até um momento adequado, então você pode usar

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

Responder3

EnquantoA solução da DigNativepois o XeLaTeX funciona na maior parte, tive alguns problemas com ele. Acontece que isso \thepagese expande para o número da página como está na primeira execução, o que pode não ser igual ao número da página na execução final.1Especificamente, obtive resultados diferentes com base no fato de ter usado \clearpageantes sidewaysfigureou não, ou quando tive várias figuras seguidas umas das outras.

Para resolver isso, optei por uma abordagem com \label+ \pageref, semelhante ao que Ulrike Fischer mencionou emeste comentário. Uma observação lateral: porque \pagerefnão se expande para um número, mas para texto (que depende de \pagenumbering, então pode nem mesmoolharcomo um número), tive que usar o \getpagerefnumbercomando do refcountpacote.2

Observe que não atualizei a parte LuaLaTeX, parece funcionar bem. Mas como estou usando o XeLaTeX, queria lançar essa correção :)

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

informação relacionada