
背景: 私の 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
ロードされる必要があります。したがって、 を介してロードしようとしますが、エラーが発生します。2 つの長さを未定義にすることでこれらのエラーの一部を修正できますが、解決できない次のエラーが残ります。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
興味深いことに、apa7figure
は に変換されます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