这个问题导致了一个新的方案的出现:
chkfloat
对我的(双列)文档进行细微调整可能会导致浮动元素(单列和双列)到处移动。我知道如果浮动元素F
位于第 页P
,那么文档看起来会比第 页好看P+1
。但是,我的文档很长,每次构建后都要检查每一页以查看浮动元素是否移动,这很累人。
F(n)
因此,如果浮动不在页面上P(n)
,F(n)
并且为浮动的某些子集指定了浮动,我希望 LaTeX 会引发错误(或至少以某种方式提醒我)P(n)
(不过,我很高兴有一个可以处理跟踪一个浮动的答案!)。但是,不可能将检查代码放在浮动本身中,因为此代码是在浮动被“读取”时执行的,而不是在浮动被“放置”时执行的。
即使我可以调整浮点数参数以便浮点数出现在我喜欢的位置,这仍然是一个有用的自动化测试,所以我的问题的重点不是浮点数参数,除非有一些神奇的参数强制 LaTeX 将浮点数放在我指定的近似位置(即浮动位置!--- 不仅仅是“这里”,我认为这对于两列浮点数来说是不可能的)。
显然,LaTeX 会跟踪哪些浮动出现在哪个页面上,因为它\listoffigures
可以显示此信息。但我不确定自己访问该信息进行测试的最佳方式是什么;是否有一个钩子会在放置浮动时被调用?最好测试可以在一次运行中完成(请注意,图表列表需要两次运行才能更新),但这不是必需的。
我添加了一个单列 MWE 和一个浮点数以供使用。更改\lipsum
范围会改变浮点数的放置位置。(如果双列性质有很大不同,我可以尝试提供经过修改的 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
。
这个想法是给每个图添加一个,\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
。
我知道这不是一个完整的解决方案,但我希望这个想法是值得的,并且有比我更熟练的人来完成它。