Я пытаюсь расширить пакет 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-файла на странице 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}