Расширение пакета `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}

При компиляции этого MWE с XeLaTeX, мы получим желаемое поведение: плавающая страница с содержимым sidewaysfigure(страница 3) правильно повернута в выводе PDF. Но при компиляции с LuaLaTeX также будет повернута страница 2, что нежелательно.


Требуемая ориентация страниц PDF-файла при компиляции с помощью XeLaTeX. Требуемая ориентация страниц PDF-файла при компиляции с помощью XeLaTeX.


Неправильная ориентация страницы PDF-файла на странице 2 при компиляции с помощью LuaLaTeX. Неправильная ориентация страницы PDF-файла на странице 2 при компиляции с помощью LuaLaTeX.


Я думаю, это потому, что определение содержимого sidewaysfigure(вместе с настройкой атрибута PDF) уже будет оценено на странице 2, где содержимое появилось бы, если бы оно не было float. Я не нашел способа обойти эту проблему и был бы рад любой идее.

Примечание:MWE — это всего лишь сокращенный пример, который не учитывает должным образом ориентацию страницы на основе ее номера (четная/нечетная). Я исключил эти части кода для более легкого понимания MWE.

решение1

На основеответ на другой вопроспредоставленный в комментарии Ульрике Фишер, я разработал следующий патч, который также учитывает четные/нечетные страницы:

\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работает нормально, но установка pageattribute должна быть отложена до тех пор, пока 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 , подобному тому, о котором упоминала Ульрике Фишер вэтот комментарий. Одно замечание: поскольку \pagerefрасширяется не до числа, а до текста (который зависит от\pagenumbering , поэтому он может даже несмотретькак число), мне пришлось использовать \getpagerefnumberкоманду изrefcount пакета.2

Обратите внимание, что я не обновил часть 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}

Связанный контент