Renderize as legendas acima das figuras com \caption abaixo \includegraphics ao usar endfloat

Renderize as legendas acima das figuras com \caption abaixo \includegraphics ao usar endfloat

Fundo: Meu arquivo TeX é gerado a partir do R Markdown e as legendas são colocadas automaticamente abaixo das figuras incluídas. Aqui está um exemplo mínimo da aparência do meu arquivo TeX gerado:

\documentclass[man]{apa7}
\title{Test}

\begin{document}
\maketitle

Lorem ipsum

\begin{figure}
The figure
\caption{The caption.}
\end{figure}

\end{document}

Problema: As legendas das figuras precisam ser renderizadasacimao valor correspondente (de acordo com as diretrizes da APA) sem se mover \caption.

O que eu tentei: Entendo que as legendas podem ser renderizadas acima da figura sem alterar o código por meio do floatrowpacote e \floatsetup[figure]{style=plaintop}. No entanto, o carregamento floatrowinterfere no endfloat, que é carregado pelo apa7. Especificamente, as figuras não são mais colocadas no final do documento, mas sim renderizadas no local:

\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}

De acordo com a documentação do endfloat, floatrowdeve sempre ser carregado antes endfloat(e, portanto, antes do apa7). Por isso, tento carregar floatrowvia \RequirePackage{}, mas isso gera erros. Posso corrigir alguns deles indefinindo dois comprimentos, mas isso me deixa com o seguinte erro que não consigo resolver:

! Missing \endcsname inserted.
<to be read again> 
                   \@classoptionslist 
l.1453 \ProcessOptionsWithKV{floatrow}

Aqui está o exemplo reproduzível mínimo:

\RequirePackage{floatrow}
\let\abovecaptionskip\undefined
\let\belowcaptionskip\undefined

\documentclass{apa7}

\begin{document}

Lorem ipsum

\end{document}

Observe que, apesar da mensagem de erro, recebo um arquivo PDF renderizado com a aparência esperada. Além disso, isso não é específico para apa7; Recebo o mesmo erro quando uso a classe de documento articleou book.

Responder1

Curiosamente, o apa7 converte figureem figure*. De qualquer forma, a ideia básica é armazenar a legenda e a figura em saveboxes separados e inverter sua ordem.

\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}

Responder2

O efloatpacote está redefinindo figure, figure*etc. dentro de \efloat@AtBeginDocument, e geralmente \efloat@AtBeginDocumenté definido como \@idenou \AtBeginDocument. Neste caso ambos fariam as redefinições muito cedo já que o floatrowpacote faz suas redefinições \AtBeginDocument. Portanto, o truque para resolver sua situação é atrasar endfloatainda mais as redefinições feitas pelo pacote.

Felizmente a definição de \efloat@AtBeginDocumenté feita \providecommandpois o autor de efloatjá tinha em mente dar ao usuário a opção de autodeterminar o momento exato em que as redefinições deveriam ser feitas: "(Nota: \efloat@AtBeginDocument será definido usando \ providecommand para que classes e pacotes de documentos possam pré-defini-lo, se necessário.)" (Citação retirada da efloatdocumentação do código)

A solução abaixo define uma versão própria do \efloat@AtBeginDocument, armazenando o conteúdo em uma macro chamada \efloatredefinitionsque poderá ser aplicada posteriormente, principalmente após as redefinições do floatrowpacote já terem sido feitas.

% 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: Seria bom se o endfloatpacote oferecesse uma opção "storeredefinitions" ou similar para que \PassOptionsToPackage{storeredefinitions}{endfloat}pudesse ser usada em vez de definir \efloat@AtBeginDocumentpor conta própria. Vou escrever um e-mail para o autor endfloatsobre isso...

informação relacionada