Wie kann ich herausfinden, auf welchen Seiten sich meine Floats befinden (ohne jede Seite des Dokuments anzusehen)?

Wie kann ich herausfinden, auf welchen Seiten sich meine Floats befinden (ohne jede Seite des Dokuments anzusehen)?

Diese Frage führte zu einem neuen Paket:
chkfloat

Kleine Änderungen an meinem (zweispaltigen) Dokument können dazu führen, dass meine Floats (sowohl ein- als auch zweispaltig) überall hin verschoben werden. Ich weiß, dass mein Dokument wahrscheinlich besser aussieht, wenn Floats beispielsweise Fauf Seite sind P, als wenn sie auf Seite sind P+1. Ich habe jedoch ein langes Dokument und es ist mühsam, nach jedem Erstellen jede Seite zu überprüfen, um festzustellen, ob sich meine Floats verschoben haben.

Daher möchte ich, dass LaTeX einen Fehler ausgibt (oder mich zumindest irgendwie warnt), wenn Float F(n)nicht auf der Seite ist , auf P(n)der F(n)es P(n)für eine Teilmenge meiner Floats angegeben ist (ich wäre jedoch mit einer Antwort zufrieden, die sich mit der Verfolgung eines Floats von Anfang an befasst!). Es ist jedoch nicht möglich, Prüfcode in die Floats selbst einzufügen, da dieser Code ausgeführt wird, wenn die Floats „gelesen“ werden, und nicht, wenn sie „platziert“ werden.

Auch wenn ich die Float-Parameter so anpassen kann, dass die Floats an den von mir bevorzugten Stellen erscheinen, wäre dies dennoch ein nützlicher automatisierter Test. Der Schwerpunkt meiner Frage soll sich also nicht auf Float-Parameter beziehen, es sei denn, es gibt einige magische Parameter, die LaTeX zwingen, die Floats ungefähr an den von mir angegebenen Stellen zu platzieren (das heißt, Float-Stellen! – nicht nur „hier“, was, wie ich annehme, für zweispaltige Floats ohnehin nicht möglich ist).

LaTeX merkt sich offensichtlich, welche Floats auf welcher Seite erscheinen, da es \listoffiguresdiese Informationen anzeigen kann. Aber ich bin mir nicht sicher, wie ich am besten selbst auf diese Informationen zugreifen kann, um den Test durchzuführen. Gibt es einen Hook, der aufgerufen wird, wenn ein Float platziert wird? Vorzugsweise würde der Test in einem Durchgang funktionieren (beachten Sie, dass die Aktualisierung der Abbildungsliste zwei Durchläufe benötigt), aber das ist nicht unbedingt erforderlich.

Ich habe ein einspaltiges MWE mit einem einzelnen Float zum Ausprobieren beigefügt. Durch Ändern des \lipsumBereichs ändert sich, wo das Float platziert wird. (Wenn die zweispaltige Natur einen großen Unterschied macht, kann ich versuchen, ein modifiziertes MWE bereitzustellen.)

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

Antwort1

Anderer Ansatz als JLDIaz. Fügen Sie den Code einfach zwischen START HEREund END HEREam Ende Ihrer Präambel ein. Der Code ist selbstkommentiert.

Anmerkung:Ich habe daraus ein Paket gemacht. Verwenden Sie diesen Code nicht direkt, besserHolen und verwenden Sie das Paket.

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

Antwort2

Hier ist eine Idee. Wenn Sie den Befehl \labelneben einer Bildunterschrift verwenden, schreibt LaTeX .auxdie Abbildungsnummer und die Seitenzahl (die tatsächliche Seitenzahl, auf der die Abbildung erscheint) in die Datei. Darüber hinaus definiert es ein Makro, das diese Seitenzahl speichert, die mit dem Befehl abgerufen werden kann \pageref.

Die Idee besteht darin, zu jeder Abbildung ein Etikett hinzuzufügen, \labeldas die Seite angibt, auf der die Abbildung erscheinen soll, beispielsweise: \label{ShouldBeOnPage1}. Ein externes Skript könnte die -auxDatei lesen und den Namen des Etiketts mit dem Wert seiner Seitenzahl vergleichen.

Noch besser ist, dass LaTeX diese Prüfung am Ende des Dokuments durchführen kann. Das folgende MWE liefert die Grundidee, prüft aber nur eine einzige Abbildung. Eine richtige Lösung würde eine Schleife zur Prüfung aller Abbildungen enthalten, aber mir fehlt das Wissen, um die vollständige Lösung zu implementieren. Sie können jede Prüfung manuell angeben, wie ich es bei der ersten Abbildung getan habe:

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

Beim Ausführen dieses Beispiels erhalten Sie die Warnung:

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

Beachten Sie, dass mein Code von einer einzelnen Abbildung pro Seite ausgeht. Eine richtige Lösung würde für jede Abbildung basierend auf der Abbildungsnummer ein Makro definieren, das die Seite speichert, auf der die Abbildung erscheinen soll, und ein Etikett erstellen, das ebenfalls auf der Abbildungsnummer und der erwarteten Seite basiert und die tatsächliche Seite über bereitstellt \pageref.

Ich weiß, dass dies keine vollständige Lösung ist, aber ich hoffe, dass die Idee wertvoll ist und jemand, der geschickter ist als ich, sie fertigstellt.

verwandte Informationen