3

This is related to Shift all floats on page horizontally. While trying to redefine the standard figure environment I've run into compatibility issues with the [H] placement specifier from the float package.

Consider the simple example below which just adds some text to be displayed at the beginning and the end of the environment.

\documentclass{article}

\usepackage{mwe}

\makeatletter
\renewenvironment{figure}[1][\fps@figure]
  {\@float{figure}[#1]before}
  {after\end@float}
\makeatother

\usepackage{float}

\begin{document}

\begin{figure}[h]
   \includegraphics[width=.8\linewidth]{example-image}
\end{figure}

\end{document}

This works as expected with the standard latex figure placement specifiers by displaying the graphics between the "before" and "after" words, as illustrated by the image below. However, when I try to use [H] instead of [h] the text supposed to appear after the graphics is gone. Any suggestions how the example above could be fixed to work with the [H] placement specifier?

enter image description here

1
  • 4
    Don't use the [H] specifier under any circumstances.
    – egreg
    Apr 28, 2016 at 12:15

2 Answers 2

5

The problem lives in the code of the float package: If the placement [H] is used, \endfigure will be redefined locally with no respect on the original definition of \endfigure:

\def\@float@HH#1[H]{%
% Locally redefine the end of the environment.
  \expandafter\let\csname end#1\endcsname\float@endH
  ...

As consequence the following code compiles fine, although \jhzsweiurziuewzriuewzritewt is (obviously) not defined at all and therefore should give an error when used:

\documentclass{article}
\usepackage{mwe}

\makeatletter
\renewenvironment{figure}[1][\fps@figure]
  {\@float{figure}[#1]before}
  {\jhzsweiurziuewzriuewzritewt} % not defined but compiles fine anyway ;-)
\makeatother

\usepackage{float}

\begin{document}

\begin{figure}[H]
   \includegraphics[width=.8\linewidth]{example-image}
\end{figure}

\end{document}

What can we do about it? Patching \float@endH as well. We do this inside the redefinition of figure (and not globally) so the patch does not affect the other floating environments:

\documentclass{article}
\usepackage{mwe}

\makeatletter
\renewenvironment{figure}[1][\fps@figure]
  {% Next two code lines: Adaption to "HERE" feature of the float package
   \let\float@endH@ORI\float@endH
   \def\float@endH{after\float@endH@ORI}%
   % ...or \pretocmd{\float@endH}{after}{}{} when using `etoolbox`
   \@float{figure}[#1]before}
  {after\end@float}
\makeatother

\usepackage{float}

\begin{document}

\begin{figure}[H]
   \includegraphics[width=.8\linewidth]{example-image}
\end{figure}

\end{document}
4
  • Awesome! Many thanks for your answer and the thorough explanation of the problem. Using your suggestion I was also able to solve my original issue described in Shift all floats on page horizontally.
    – aoles
    Jun 11, 2016 at 17:17
  • 1
    @aoles I just realized that patching \float@endH globally was a bad idea of mine (since this would affect all floating environments), so I moved the patch inside the redefinition of figure.
    – user2574
    Jun 11, 2016 at 21:25
  • 2
    Obviously undefined? \jhzsweiurziuewzriuewzritewt is my favorite name for marking up spectral sequences; it has thirteen mandatory arguments and fourteen optional ones, just to keep the syntax at the bare minimum. ;-)
    – egreg
    Jun 11, 2016 at 21:28
  • Thank you @AxelSommerfeldt for the update! In this specific example it makes of course much more sense to redefine it only for the figure environment, but for my other question Shift all floats on page horizontally the global patch is just fine.
    – aoles
    Jun 12, 2016 at 9:17
1

The macro \fps@figure doesn't have an H option. To implement the H option from the figure package, you would need something like this:

\documentclass{article}
\usepackage{caption}
\usepackage{mwe}
\usepackage{showframe}

\newenvironment{Hfigure}{\setcaptiontype{figure}%
  \vskip\textfloatsep\begin{minipage}{\columnwidth}}%
  {\end{minipage}\vskip\textfloatsep\noindent}

\begin{document}
before
\begin{Hfigure}
\centering
\includegraphics{example-image}
\caption{test}
\end{Hfigure}
after
\end{document}
1
  • Thank you for your input! Unfortunately, your solution won't work for the specific case I described, because I would like to: 1. redefine the standard figure environment, and 2. support the placement specifier [H] defined in the float package, i.e. be able to write \begin{figure}[H].
    – aoles
    Apr 28, 2016 at 20:42

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .