Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I am trying to detect whether I am inside or outside a float. I know the way how caption works. It uses the internal \@captype. But in the example below you see that this test failed by using captionsetup{type=figure}. Of course this feature is really fussy.

I create a minimal example which changed the internal \@endfloatbox and \@floatboxreset to add a bool expression.

You will see that it works in the minimal example. Now my question: Do you know any reasons why I shouldn't do it. (It's for a package on 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}
share|improve this question

2 Answers 2

up vote 14 down vote accepted
\documentclass{scrbook}
\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}

The counter \@floatpenalty controls float processing. It defaults to 0, but is set to a negative value at a beginning of a float. This code checks for this value to be negative (inside float) or not (outside float) using low-level \ifnum test.

share|improve this answer

In most cases, test using \@captype should work:

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

With the usage \InFloat{INSIDE}{OUTSIDE}.

The code is based on the idea that \@captype stores the type of the float in which we are, i.e. \@captype -> figure inside figure etc. Especially, \@captype is undefined outside any float since floats form a group and the value is "forgotten" once we exit the float. Macro \@ifundefined takes macro name (without the leading \) and tests for being defined.

(This answer is added to provide a reference for future questions.)

share|improve this answer
    
I used this test in my original question. –  Marco Daniel Feb 25 '13 at 18:08
    
@MarcoDaniel I know. It is a bit strange situation where your question says "how to do X not using Y" where "Y" is quite natural answer to "X", one that suffices to some. If you felt it's better made CW, I would not complain. –  tohecz Feb 25 '13 at 18:17
    
No problem. I was a little bit confused ;-). Of course your answer shows the most general way. –  Marco Daniel Feb 25 '13 at 18:21

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.