背景:我的 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}
问题:需要渲染图片标题多于相应的图形(根据 APA 指南)无需移动\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}
endfloat
PS:如果包中能提供“storeredefinitions”或类似选项,这样\PassOptionsToPackage{storeredefinitions}{endfloat}
就可以使用,而不是单独定义,那就太好了\efloat@AtBeginDocument
。将给作者写一封电子邮件endfloat
...