3

I have some LaTeX code

\begin{figure}
    ABC
    \caption{def}
\end{figure}

And I would like to be able to find its height in a pdf output. The method outlined here doesn't work, yielding the error:

! LaTeX Error: Not in outer par mode.

I considered the idea of using \write18 and somehow measuring the size of the figure by itself using pixel-grabbing tricks, but if the document had a globally changed caption size, that would mess things up.

I was wondering if there was a valid way to do this.

  • you want to get the height of ABC or the whole figure including caption – touhami Mar 24 '16 at 7:00
  • The whole figure. Like how much space the whole thing uses on the page. – k_g Mar 24 '16 at 7:01
3

Here is a solution

\documentclass{article}
\usepackage{capt-of}

\newsavebox\mybox
\begin{document}    
\sbox\mybox{\parbox[b]{\textwidth}{ABC\captionof{figure}{bla bla}}}
\the\ht\mybox
\end{document}

Here is another solution:

\documentclass{article}

\begin{document}
\the\pagetotal

\begin{figure}[h]
    ABC
    \caption{def}
\end{figure}

\the\pagetotal

\end{document}

Update In this example we try to reproduce float position by hand in the first page and in seconde page we let latex does the job.

Note: as one can see for top position there is no problem. Reproducing bottom position is difficult (if not impossible?) enter image description here

\documentclass{article}
\usepackage{capt-of}
\usepackage{lipsum}

\newsavebox\mybox
\newcommand\myfigure[1][(Manually)]{\rule{5cm}{1cm}\captionof{figure}{My figure #1}}

\begin{document}                           
\sbox\mybox{\parbox[b]{\linewidth}{\myfigure
                             \boxmaxdepth \maxdepth
                             \vbox{}
                             \vskip -\floatsep
                             \topfigrule
                             \vskip \textfloatsep}} 

\noindent\parbox[b]{\linewidth}{\myfigure
                             \boxmaxdepth \maxdepth
                             \vbox{}
                             \vskip -\floatsep
                             \topfigrule
                             \vskip \textfloatsep}
\the\ht\mybox****\lipsum[3]

\sbox\mybox{\parbox[b]{\textwidth}{\myfigure}}
\noindent\parbox[b]{\textwidth}{\myfigure}
Height without any vspace:\the\ht\mybox****\lipsum[3-4]

bla bla

this is difficult, see value of the height in next page


\sbox\mybox{\parbox[b]{\linewidth}{\vskip \textfloatsep
                             \botfigrule
                             \vbox{}
                             \vskip -\floatsep
                             \myfigure}}
\noindent\parbox[b]{\linewidth}{\vskip \textfloatsep
                             \botfigrule
                             \vbox{}
                             \vskip -\floatsep
                             \myfigure}
\newpage\the\ht\mybox****\lipsum[3]
\begin{figure}[t]
\myfigure[(\LaTeX)]
\end{figure}
\lipsum[3-4]
\begin{figure}[b]
\myfigure[(\LaTeX)]
\end{figure}
\lipsum[3]
\end{document}
  • Does this include the depth of of possible descenders in the caption like g or p etc.? – user31729 Mar 24 '16 at 7:18
  • I'll have to test this out with more complex examples, but it seems to work with \includegraphics and multi-line comments. I'll have to test a little more before accepting, but I'll +1. @ChristianHupfer for my purposes, I can be a few pixels off. I just can't be an entire caption off. – k_g Mar 24 '16 at 7:26
  • I think this is not so good (there is \textfloatsep not considered here) I will see later. – touhami Mar 24 '16 at 7:28
  • Also, @touhami, is there anything other than caption -> captionof and disabling label I need to do to automate this process? – k_g Mar 24 '16 at 7:28
  • @touhami. The new solution doesn't work if the figure is placed somewhere other than the current location (I'm trying to extract figures sizes from existing documents) – k_g Mar 24 '16 at 7:35
5

The figure is stored in a box so you can measure it (you'd need to work a bit harder for h floats as they may be used before the reporting happens if done after the environment as here)

\documentclass{article}

\begin{document}


\begin{figure}
    ABC
    \caption{def}
\xdef\thisfloat{\the\csname @currbox\endcsname}%
\end{figure}
\typeout{%
** This float + caption has height + depth:^^J**
\the\dimexpr\ht\thisfloat+\dp\thisfloat\relax}

\end{document}

Produces a log of

** This float + caption has height + depth:
** 30.77776pt

or collected up until the end:

\documentclass{article}

\begin{document}


\begin{figure}
    ABC
    \caption{def\label{z}}
\xdef\thisfloat{\the\csname @currbox\endcsname}%
\end{figure}
\edef\tmp{\noexpand\AtEndDocument{%
\noexpand\foo{z}{\the\dimexpr\ht\thisfloat+\dp\thisfloat\relax}}}%
\tmp

aaaa

\begin{figure}
    ABC\\
XYZ
    \caption{def\label{z2}}
\xdef\thisfloat{\the\csname @currbox\endcsname}%
\end{figure}
\edef\tmp{\noexpand\AtEndDocument{%
\noexpand\foo{z2}{\the\dimexpr\ht\thisfloat+\dp\thisfloat\relax}}}%
\tmp


aaaa


\def\foo#1#2{% whatever you want to do with the data
\typeout{**^^J%
** This float (#1) + caption has height + depth: #2^^J**
}}

\end{document}

**
** This float (z) + caption has height + depth: 30.77776pt
** 
**
** This float (z2) + caption has height + depth: 42.77776pt
** 
  • Is there a way to put that code in uniquely named variables so that it can be placed \AtEndDocument? I'm currently using something to trap labels so I can use labels as IDs. – k_g Mar 27 '16 at 0:39
  • @k_g updated answer – David Carlisle Mar 27 '16 at 0:53
  • Sorry if I was unclear, but I was implying that using \AtEndDocument could be used to solve the h problem because the reporting would be done at the end of the document. – k_g Mar 27 '16 at 1:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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