
Фон: Мой файл TeX генерируется из R Markdown, а подписи автоматически размещаются под включенными рисунками. Вот минимальный пример того, как выглядит мой сгенерированный файл TeX:
\documentclass[man]{apa7}
\title{Test}
\begin{document}
\maketitle
Lorem ipsum
\begin{figure}
The figure
\caption{The caption.}
\end{figure}
\end{document}
Проблема: Подписи к рисункам должны быть визуализированывышесоответствующая цифра (согласно рекомендациям АПА) без перемещения \caption
.
Что я пробовал: Я понимаю, что подписи можно отображать над рисунком без изменения кода через floatrow
пакет и \floatsetup[figure]{style=plaintop}
. Однако загрузка floatrow
мешает endfloat
, который загружается apa7
. В частности, рисунки больше не размещаются в конце документа, а отображаются на месте:
\documentclass[man]{apa7}
\usepackage{floatrow}
\floatsetup[figure]{style=plaintop}
\title{Test}
\begin{document}
\maketitle
Lorem ipsum
\begin{figure}
The figure
\caption{The caption.}
\end{figure}
\end{document}
Согласно документации endfloat
, floatrow
всегда должен быть загружен до endfloat
(и, таким образом, до apa7
). Поэтому я пытаюсь загрузить floatrow
через \RequirePackage{}
, но это приводит к ошибкам. Я могу исправить некоторые из них, отменив определение двух длин, но это оставляет меня со следующей ошибкой, которую я, похоже, не могу устранить:
! Missing \endcsname inserted.
<to be read again>
\@classoptionslist
l.1453 \ProcessOptionsWithKV{floatrow}
Вот минимальный воспроизводимый пример:
\RequirePackage{floatrow}
\let\abovecaptionskip\undefined
\let\belowcaptionskip\undefined
\documentclass{apa7}
\begin{document}
Lorem ipsum
\end{document}
Обратите внимание, что несмотря на сообщение об ошибке я получаю отрендеренный PDF-файл, который выглядит так, как и ожидалось. Также это не относится к apa7
; я получаю ту же ошибку, когда использую класс документа article
или book
.
решение1
Интересно, что apa7 конвертируется figure
в figure*
. В любом случае, основная идея заключается в том, чтобы сохранить подпись и рисунок в отдельных ящиках сохранения и поменять их порядок.
\documentclass[man]{apa7}
%\documentclass{article}
%\usepackage{endfloat}
\usepackage{lipsum}% MWE only
% udbox is a \vbox version of lrbox
\makeatletter
\def\udbox#1{%
\edef\reserved@a{%
\endgroup
\setbox#1\vbox{%
\begingroup\aftergroup}%
\def\noexpand\@currenvir{\@currenvir}%
\def\noexpand\@currenvline{\on@line}}%
\reserved@a
\@endpefalse
\color@setgroup
\ignorespaces}
\def\endudbox{\unskip\color@endgroup}
\makeatother
\newsavebox{\mycaptionbox}
\newsavebox{\myfigurebox}
\makeatletter
\let\normalmakecaption=\@makecaption
\def\@makecaption#1#2{\def\test{figure}%
\ifx\@captype\test \global\setbox\mycaptionbox=\vbox{\normalmakecaption{#1}{#2}}%
\else \normalmakecaption{#1}{#2}%
\fi}
\makeatother
\let\normalfigure=\figure
\let\endnormalfigure=\endfigure
\renewenvironment{figure}[1][tbp]{\normalfigure
\begin{udbox}{\myfigurebox}}%
{\end{udbox}\unvbox\mycaptionbox
\unvbox\myfigurebox\endnormalfigure}
\expandafter\let\expandafter\normalfigurestar\csname figure*\endcsname
\expandafter\let\expandafter\endnormalfigurestar\csname endfigure*\endcsname
\renewenvironment{figure*}[1][tbp]{\normalfigurestar
\begin{udbox}{\myfigurebox}}%
{\end{udbox}\unvbox\mycaptionbox
\unvbox\myfigurebox\endnormalfigurestar}
\title{Test}
\begin{document}
\maketitle
Lorem ipsum
\begin{figure}
\lipsum[1]
\caption{The caption.}
\end{figure}
\end{document}
решение2
Пакет efloat
выполняет свои переопределения и т. д figure
. figure*
внутри \efloat@AtBeginDocument
и обычно \efloat@AtBeginDocument
определяется как либо \@iden
или \AtBeginDocument
. В этом случае оба выполнят переопределения слишком рано, поскольку floatrow
пакет выполняет свои переопределения \AtBeginDocument
. Поэтому трюк, позволяющий решить вашу ситуацию, заключается в том, чтобы еще больше отсрочить переопределения, выполняемые пакетом endfloat
.
К счастью, определение \efloat@AtBeginDocument
сделано, \providecommand
поскольку автор efloat
уже имел в виду предоставить пользователю возможность самостоятельно определять точный момент, когда следует выполнять переопределения: "(Примечание: \efloat@AtBeginDocument будет определен с помощью \providecommand, поэтому классы документов и пакеты могут предварительно определить его при необходимости.)" (Цитата взята из efloat
документации по коду)
Приведенное ниже решение определяет собственную версию \efloat@AtBeginDocument
, сохраняя содержимое в макросе с именем , \efloatredefinitions
который можно применить позже, особенно после того, как переопределения пакета floatrow
уже выполнены.
% Store the code of efloat re-definitions into \efloatredefinitions
% (This code must be defined before the efloat package is loaded.)
\makeatletter
\newcommand\efloatredefinitions{}
\newcommand\efloat@AtBeginDocument{\g@addto@macro\efloatredefinitions}
\makeatother
\documentclass[man]{apa7}
\usepackage{floatrow}
\floatsetup[figure]{style=plaintop}
% Do the efloat re-definitions after the re-definitions of floatrow were done
%\show\efloatredefinitions
\AtBeginDocument{\efloatredefinitions} % or simply \efloatredefinitions after \begin{document}
\title{Test}
\begin{document}
\maketitle
Lorem ipsum
\begin{figure}
The figure
\caption{The caption.}
\end{figure}
\end{document}
PS: Было бы неплохо, если бы пакет endfloat
предлагал опцию "storeredefinitions" или подобную, чтобы ее \PassOptionsToPackage{storeredefinitions}{endfloat}
можно было использовать вместо определения \efloat@AtBeginDocument
самой по себе. Напишу автору письмо по endfloat
этому поводу...