我如何检测我是处于浮动环境之内还是之外?

我如何检测我是处于浮动环境之内还是之外?

我正在尝试检测我是在浮点数的内部还是外部。我知道工作方式caption。它使用内部的\@captype。但在下面的示例中,您会看到此测试因使用而失败captionsetup{type=figure}。当然,此功能确实很挑剔。

我创建了一个最小示例,它改变了内部\@endfloatbox\@floatboxreset添加了一个布尔表达式。

您将看到它在最小示例中有效。现在我的问题是:您知道我不应该这样做的原因吗?(这是针对 CTAN 上的一个包)

\documentclass{article}
\parindent0pt
\usepackage{caption}
\usepackage{etoolbox}
\makeatletter
\newbool{detect@float}
\appto\@endfloatbox{\boolfalse{detect@float}}
\preto\@floatboxreset{\booltrue{detect@float}}
\newrobustcmd*\testiffloat[1]{%
in \texttt{#1}\ \ifbool{detect@float}{Inside float}{Outside float}%
}
\newrobustcmd*\testiffloatI[1]{%
in \texttt{#1}\ 
\ifx\@captype\@undefined
   Outside float%
 \else
   Inside float%
\fi
}
\makeatother
\usepackage{lipsum}
\begin{document}
\testiffloat{text}\qquad\testiffloatI{text}

\begin{figure}[!ht]
\testiffloat{figure}\qquad\testiffloatI{figure}
\end{figure}

\testiffloat{text}\qquad\testiffloatI{text}


\begin{figure*}[!ht]
\testiffloat{figure*}\qquad\testiffloatI{figure*}
\end{figure*}

\testiffloat{text}\qquad\testiffloatI{text}

\begin{flushleft}
\testiffloat{flushleft}\qquad\testiffloatI{flushleft}
\captionsetup{type=figure}
\end{flushleft}

\begin{flushleft}
\captionsetup{type=figure}
\testiffloat{flushleft}\qquad\testiffloatI{flushleft}
\end{flushleft}

\testiffloat{text}\qquad\testiffloatI{text}
\end{document}

答案1

\documentclass{book}
\usepackage{caption}

\makeatletter   
\def\InFloat{\ifnum\@floatpenalty<0\relax in float \else outside float \fi}
\makeatother
\begin{document}

\begin{figure}\relax
[figure]: \InFloat
\end{figure}

\begin{center}
[center]: \InFloat
\end{center}

\captionsetup{type=figure}
\begin{center}
[center]: \InFloat
\end{center}

\end{document}

计数器\@floatpenalty控制浮点处理。其默认值为0,但在浮点的开头设置为负值。此代码使用低级\ifnum测试检查该值是负值(浮点内)还是非负值(浮点外)。

答案2

在大多数情况下,测试使用\@captype应该有效:

\makeatletter
\newcommand\InFloat[2]{\@ifundefined{@captype}{#2}{#1}}
\makeatothe‌‌​​r

与用法一致\InFloat{INSIDE}{OUTSIDE}

代码基于这样的想法,即\@captype存储我们所在的浮点数的类型,即\@captype -> figure内部figure等。特别是,\@captype在任何浮点数之外都是未定义的,因为浮点数形成一个组,一旦我们退出浮点数,该值就会被“遗忘”。宏\@ifundefined采用宏名(没有前导的\)并测试是否被定义。

(此答案是为了给后续的问题提供参考而添加的。)

相关内容