Как узнать, на каких страницах находятся мои плавающие элементы (не просматривая каждую страницу документа)?

Как узнать, на каких страницах находятся мои плавающие элементы (не просматривая каждую страницу документа)?

Этот вопрос привел к новому пакету:
chkfloat

Внесение небольших изменений в мой (двухколоночный) документ может привести к тому, что мои float (как одинарные, так и двойные) будут перемещаться по всему документу. Я знаю, что мой документ, скорее всего, будет выглядеть хорошо, если float Fбудет на странице P, скажем, чем если он будет на странице P+1. Однако у меня длинный документ, и утомительно проверять каждую страницу после каждой сборки, чтобы увидеть, переместились ли мои float.

Поэтому я хотел бы, чтобы LaTeX выдавал ошибку (или, по крайней мере, предупреждал меня каким-то образом), если float F(n)отсутствует на странице P(n), где F(n)и P(n)указан для некоторого подмножества моих float (хотя я был бы рад ответу, который мог бы отслеживать один float для начала!). Однако невозможно поместить код проверки внутрь самих float, потому что этот код выполняется, когда float «читается», а не когда они «размещаются».

Даже если я смогу настроить параметры плавающих объектов так, чтобы они появлялись в тех местах, которые мне нравятся, это все равно будет полезным автоматизированным тестом, поэтому мой вопрос не касается параметров плавающих объектов, если только нет каких-то магических параметров, которые заставляют LaTeX размещать плавающие объекты в приблизительных местах, которые я укажу (то есть в плавающих местах! --- а не просто «здесь», что, как я предполагаю, в любом случае невозможно для двухколоночных плавающих объектов).

Очевидно, LaTeX отслеживает, какие плавающие элементы появляются на какой странице, поскольку \listoffiguresможет показывать эту информацию. Но я не уверен, какой лучший способ доступа к этой информации для самостоятельного тестирования; есть ли хук, который вызывается при размещении плавающего элемента? Предпочтительно, чтобы тест работал за один запуск (обратите внимание, что список фигур обновляется за два запуска), но это не обязательно.

Я включил одноколоночный MWE с одним float для игры. Изменение \lipsumдиапазона меняет место размещения float. (Если двухколоночная природа имеет большое значение, я могу попробовать предоставить модифицированный 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 HEREи END 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.

Идея состоит в том, чтобы добавить к каждому рисунку a, \labelкоторый указывает страницу, на которой должен появиться рисунок, например: \label{ShouldBeOnPage1}Внешний скрипт может прочитать -auxфайл и сравнить имя метки со значением номера ее страницы.

Еще лучше, LaTeX может выполнить эту проверку в конце документа. Следующий MWE обеспечивает основную идею, но он проверяет только одну фигуру. Правильное решение включало бы цикл для проверки всех фигур, но у меня нет знаний, чтобы реализовать полное решение. Вы можете вручную указать каждую проверку, как я сделал с первой фигурой:

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

Обратите внимание, что мой код предполагает одну фигуру на страницу. Правильное решение будет определять макрос для каждой фигуры на основе номера фигуры, который хранит страницу, на которой должна появиться фигура, и создавать метку, основанную также на номере фигуры и ожидаемой странице, которая предоставит фактическую страницу через \pageref.

Я знаю, что это не полное решение, но я надеюсь, что эта идея стоит того, и кто-то более опытный, чем я, доведет ее до конца.

Связанный контент