Отображать подписи над рисунками с помощью \caption ниже \includegraphics при использовании endfloat

Отображать подписи над рисунками с помощью \caption ниже \includegraphics при использовании endfloat

Фон: Мой файл 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этому поводу...

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