擴充 `rotating` 套件來設定 PDF 旋轉

擴充 `rotating` 套件來設定 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 頁上進行了評估,如果內容不是浮動的,則會出現在該頁面上。我沒有找到解決這個問題的方法,並且很高興有任何想法。

注意: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}

相關內容