フロートがどのページにあるかを知るにはどうすればよいですか (ドキュメントのすべてのページを確認せずに)?

フロートがどのページにあるかを知るにはどうすればよいですか (ドキュメントのすべてのページを確認せずに)?

この質問から新しいパッケージが生まれました:
chkfloat

私の (2 列の) ドキュメントに小さな調整を加えると、フロート (1 列と 2 列の両方) があちこちに移動することになります。フロートがFページ にPある場合よりも、ページ にある場合の方がドキュメントの見栄えがよくなることはわかっていますP+1。しかし、私のドキュメントは長く、ビルドのたびにすべてのページをチェックしてフロートが動いたかどうかを確認するのは面倒です。

したがって、フロートのサブセットに対して とが指定されているF(n)ページにフロートがない場合、LaTeX でエラーが発生するように (または少なくとも何らかの方法で警告するように) したいと思います(ただし、そもそも 1 つのフロートの追跡を処理できる回答があればうれしいです)。ただし、フロート自体の中にチェック コードを配置することはできません。このコードは、フロートが「配置される」ときではなく、フロートが「読み取られる」ときに実行されるためです。P(n)F(n)P(n)

フロート パラメータを微調整して、フロートが好みの場所に表示されるようにできる場合でも、これは便利な自動テストになります。したがって、私の質問の焦点は、フロート パラメータに関するものではありません。ただし、LaTeX に、指定したおおよその場所 (つまり、フローティングの場所) にフロートを配置するように強制する魔法のパラメータがある場合は別です (「ここ」だけではなく、2 列のフロートではそもそも不可能だと思います)。

明らかに、LaTeX はどのフロートがどのページに表示されるかを追跡しており、\listoffiguresこの情報を表示できます。しかし、テストを行うために自分でその情報にアクセスする最良の方法がわかりません。フロートが配置されたときに呼び出されるフックはありますか? テストは 1 回の実行で完了するのが望ましいですが (図のリストは更新に 2 回の実行が必要であることに注意してください)、これは必須ではありません。

試しに、1 つのフロートを含む 1 列の MWE を用意しました。\lipsum範囲を変更すると、フロートの配置場所が変わります。(2 列であることで大きな違いが出る場合は、修正した MWE を提供することもできます。)

\documentclass{article}
\usepackage[a4paper]{geometry}%don't trust MikTeX's defaults!
\usepackage{lipsum}
\begin{document}
    % choose which of the following two lines to use to configure where the float appears.
    \lipsum[1-5]% figure appears on page 2 if this line is used
    %\lipsum[1-4]% figure appears on page 1 if this line is used
    \begin{figure}
        \centering
        Hello world. I was typeset on page \thepage, but that may not be where I appear!

        \rule{4cm}{4cm}

        \caption{fig}
    \end{figure}
    ***Figure appeared in the text just above here.***

    \lipsum[5-8]
    \listoffigures
\end{document}

答え1

JLDIaz とは異なるアプローチです。コードをプリアンブルの と の間に挿入するだけですSTART HEREEND HEREコードには自己コメントが付けられています。

述べる:これをパッケージにしました。このコードを直接使用しないでください。パッケージを入手して使用する

\documentclass{article}

% START HERE
\makeatletter
% tolerances
\PassOptionsToPackage{patch}{kvoptions}
\RequirePackage{kvoptions}
\DeclareStringOption{tolerance}
\def\chkfloat@tolerance{1}
\ProcessKeyvalOptions*
% store original macros \@float and \@caption
\let\chkfloat@float\@float
\let\chkfloat@caption\@caption
% make \@float remember the page where the float should be
\def\@float{\edef\chkfloat@page{\thepage}\chkfloat@float}
% make \@caption write to a file .fof the information about final page, original page and float caption
\def\@caption#1[#2]#3{\chkfloat@caption{#1}[#2]{#3}%
  \addtocontents{fof}{\protect\chkfloat@{\thepage}{\chkfloat@page}{\csname fnum@#1\endcsname: #2}}%
}
% checking macro
\def\chkfloat@#1#2#3{\ifnum#1>\numexpr#2+\chkfloat@tolerance\relax
  \begingroup\let\on@line\@gobble\def\nobreakspace{ }\GenericWarning{}{Float misplaced on pages #2->#1, #3}\endgroup
\fi
}
% process the file .fof
\@starttoc{fof}

\makeatother
% END HERE

\begin{document}

Hello world!

\begin{figure}[b]
FIGURE BOTTOM
\caption{Figure at bottom}
\end{figure}

\begin{figure}[p]
FIGURE PAGE
\caption{Figure at its page}
\end{figure}

\end{document}

答え2

ここにアイデアがあります。\labelキャプションの横の コマンドを使用すると、LaTeX はファイルに.aux図番号とページ番号 (図が表示される実際のページ番号) を書き込みます。さらに、そのページ番号を保存するマクロを定義します。これは コマンド で取得できます\pageref

アイデアとしては、各図に、\label図が表示されるページを指定する を追加することです。たとえば、次のようになります。\label{ShouldBeOnPage1}外部スクリプトは-auxファイルを読み取り、ラベルの名前とそのページ番号の値を比較できます。

さらに良いことに、LaTeX ではこのチェックを文書の最後で実行できます。次の MWE は基本的な考え方を示していますが、チェックするのは 1 つの図だけです。適切な解決策にはすべての図をチェックするループが含まれますが、完全な解決策を実装する知識が不足しています。最初の図で行ったように、各チェックを手動で指定できます。

\documentclass{article}
\usepackage[a4paper]{geometry}%don't trust MikTeX's defaults!
\usepackage{lipsum}

\def\CheckFloat#1{%  The macro which does the check for a single figure
% The parameter is the page number at which the figure should appear
\expandafter\ifx#1\pageref{ShouldBeOnPage#1}%
\relax
\else\GenericWarning{(Floats)}{Warning: A float which should appear on page #1 is misplaced (to page \pageref{ShouldBeOnPage#1})}
\fi
}


\AtEndDocument{% Manually do all checks
 \CheckFloat{1}
}

\begin{document}
% choose which of the following two lines to use to configure where the float appears.
\lipsum[1-5]% figure appears on page 2 if this line is used
%\lipsum[1-4]% figure appears on page 1 if this line is used
\begin{figure}
\centering
Hello world. I was typeset on page \thepage, but that may not be where I appear!

\rule{4cm}{4cm}

\caption{fig}\label{ShouldBeOnPage1}  % <----- Add this to the figures
\end{figure}
***Figure appeared in the text just above here.***

\lipsum[5-8]
\listoffigures
\end{document}

この例を実行すると、次の警告が表示されます:

Warning: A float which should appear on page 1 is misplaced (to page 2\hbox {})
 on input line 33.

私のコードでは、1 ページにつき 1 つの図を想定していることに注意してください。適切な解決策としては、図番号に基づいて各図のマクロを定義し、図が表示されるページを保存し、図番号と予想されるページに基づいてラベルを作成し、 を介して実際のページを提供することです\pageref

これは完全な解決策ではないことは承知していますが、このアイデアが価値あるもので、私よりも熟練した誰かがそれを完成させてくれることを願っています。

関連情報