扩展 `rotation` 包以设置 PDF 旋转

扩展 `rotation` 包以设置 PDF 旋转

我正在尝试扩展该rotating包,以便通过设置 PDF 页面属性在 PDF 输出中显示正确旋转的各个页面/Rotate。我有一个适用于 XeLaTeX 的工作版本,但是,我无法为 LuaLaTeX 完成此操作。请考虑以下 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}

使用 XeLaTeX 编译此 MWE 时,将获得所需的行为:包含内容的浮动页面sidewaysfigure(第 3 页)在 PDF 输出中正确旋转。但使用 LuaLaTeX 编译时,第 2 页也会旋转,这是不理想的。


使用 XeLaTeX 编译时所需的 PDF 页面方向。 使用 XeLaTeX 编译时所需的 PDF 页面方向。


使用 LuaLaTeX 编译时,第 2 页的 PDF 页面方向错误。 使用 LuaLaTeX 编译时,第 2 页的 PDF 页面方向错误。


我认为这是因为内容的定义sidewaysfigure(连同 PDF 属性的设置)已经在第 2 页进行了评估,如果内容不是浮动的,内容就会出现在第 2 页。我找不到解决这个问题的方法,如果能提供任何想法,我将非常高兴。

注意:MWE 只是一个简化的示例,它没有正确考虑基于页码(偶数/奇数)的页面方向。为了更容易理解 MWE,我删除了这些代码部分。

答案1

根据回答另一个问题根据 Ulrike Fischer 的评论,我开发了以下补丁,其中也考虑了偶数/奇数页:

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

谢谢你!

答案2

主要问题是,它\afterpage可以正常工作,但设置页面属性必须延迟到 TeX 不再适用于上一页。幸运的是,\latelua允许执行延迟到适当时刻的 Lua 代码,因此您可以使用

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

答案3

尽管DigNative 的解决方案对于 XeLaTeX 来说,它在大多数情况下都有效,但我遇到了一些麻烦。事实证明,它\thepage会扩展到第一次运行时的页码,这可能不等于最后一次运行时的页码。1具体来说,根据我是否\clearpage在之前使用sidewaysfigure,或者是否有多个数字相互跟随,我会得到不同的结果。

为了解决这个问题,我采用了\label+的方法\pageref,类似于 Ulrike Fischer 在此评论。一个补充说明:因为\pageref不扩展为数字而是扩展为文本(这取决于)\pagenumbering,所以它甚至可能不会就像数字一样,我不得不使用包\getpagerefnumber中的命令refcount2

请注意,我没有更新 LuaLaTeX 部分,这似乎工作正常。但由于我使用的是 XeLaTeX,所以我想加入这个修复程序 :)

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

相关内容