1

Question

There are many questions with respect to putting a frame around the content of a float environment. The usual answer is to put \includegraphics in some kind of box

\begin{figure}
    \fbox{
        \includegraphics{...}
    }
    \caption{...}
\end{figure}

In my case, I am trying to leave the interface to the figure environment intact and just exchange the figure environment with some other environment that puts everything in a box

\begin{figureFramed}
    \includegraphics{...}
    \caption{...}
\end{figureFramed}

I have found similar solutions with adjustbox, where we add a simple option to \includegraphics.

Assume that I cannot change the contents of the current figure environment that a user put there. It therefore already is a customised environment. Just the definition of the environment may be changed. How could I achieve the desired behaviour?

I tried the following with the package environ

\NewEnviron{figureFramed}{
    \begin{figure}
        \fcolorbox{orange}{white}{
            \BODY
        }
    \end{figure}
}

The problem with this solution is that the \caption command does not work anymore since I wrapped \BODY within an \fcolorbox which seemingly interferes with the implementation of \caption.

Unsurprisingly, moving \caption behind the \fcolorbox works as expected

\NewEnviron{figureFramed}[1]{
    \begin{figure}
        \setlength{\fboxrule}{5pt}
        \setlength{\fboxsep}{5pt}
        \centering
        \fcolorbox{orange}{white}{
            \BODY
        }
        \caption{#1}
    \end{figure}
}

but now I have changed the interface to the environment and it requires an additional argument.

A possible solution would be to redefine \caption within the body, capture the argument and reapply it after the \fcolorbox if a \caption was issued at the usage location. I would not know how to achieve that though since I am not that proficient in latex.

Any hints and implementation examples are highly appreciated.

Minimal Working Example

Here is a minimal working example which does also include additional functionality of the environments that may be important to decide which implementation would fit.

\documentclass{article}

\usepackage{ifthen}
\usepackage{xcolor}
\usepackage{environ}

\newcommand{\solutioncolor}{red}

\newboolean{bSolution}
\setboolean{bSolution}{true}

\NewEnviron{solutionFigureA}[1]{%
    \ifthenelse{\boolean{#1}}{%
        \begin{figure}[p]
            \setlength{\fboxrule}{5pt}
            \setlength{\fboxsep}{5pt}
            \centering
            \fcolorbox{\solutioncolor}{white}{%
                \BODY
            }
        \end{figure}
    }{}
}

\NewEnviron{solutionFigureB}[2]{%
    \ifthenelse{\boolean{#1}}{%
        \begin{figure}
            \setlength{\fboxrule}{5pt}
            \setlength{\fboxsep}{5pt}
            \centering
            \fcolorbox{\solutioncolor}{white}{%
                \BODY
            }
            \caption{#2}
        \end{figure}
    }{}
}

\begin{document}
% This does work.
%
    \begin{solutionFigureB}{bSolution}{How are you?}
        Hi there!
    \end{solutionFigureB}
    
% This does not work.
%
    \begin{solutionFigureA}{bSolution}
        Hi there!
        \caption{How are you?}
    \end{solutionFigureA}
\end{document}
1
  • 1
    you could use figure and \usepackage{float} \floatstyle{boxed} Commented May 16 at 22:22

2 Answers 2

2

You can do it yourself by using saveboxes and redefining \caption internally.

\documentclass{article}
\usepackage{xcolor}

\newcommand{\solutioncolor}{red}
\newsavebox{\figurebox}
\newsavebox{\captionbox}

\newcommand{\mycaption}[2][\empty]{\bgroup
  \setlength{\hsize}{\dimexpr \hsize+2\fboxrule+2\fboxsep}% or \advance\hsize...
  \ifx\empty#1\relax
    \global\setbox\captionbox=\vtop{\normalcaption{#2}}%
  \else
    \global\setbox\captionbox=\vtop{\normalcaption[#1]{#2}}%
  \fi
\egroup}

\newenvironment{myfigure}[1][p]{\begin{figure}[#1]
  \setlength{\fboxrule}{5pt}%
  \setlength{\fboxsep}{5pt}%
  \let\normalcaption=\caption
  \let\caption=\mycaption
  \begin{lrbox}{\figurebox}%
    \begin{minipage}{\dimexpr \linewidth-2\fboxrule-2\fboxsep}%
    \centering}%
{\end{minipage}%
  \end{lrbox}%
  \fcolorbox{\solutioncolor}{white}{\usebox\figurebox}\par
  \usebox\captionbox\par
\end{figure}}
  
\begin{document}
  \begin{myfigure}
        Hi there!
        \caption{How are you?}
  \end{myfigure}
\end{document}
1
  • The gist of this is exactly what I had in mind and was trying to express. I appreciate your help. I mostly understand what is going on and should be able to apply it successfully.
    – Simon
    Commented May 25 at 7:45
1

For a general solution framing every figure body see the other answer(s). But if you need it only to frame images loaded by \includegraphics, you can alternatively redefine \includegraphics inside the figure, e.g.:

\documentclass{article}
\usepackage{xcolor}
\usepackage{graphicx}

\NewDocumentEnvironment{framedimage}{o}{%
  \NewCommandCopy{\unframedincludegraphics}{\includegraphics}%
  \RenewDocumentCommand{\includegraphics}{O{}m}{%
    \begingroup
      \setlength{\fboxrule}{5pt}%
      \setlength{\fboxsep}{5pt}%
      \fcolorbox{\solutioncolor}{white}{%
        \unframedincludegraphics[{##1}]{##2}%
      }%
    \endgroup
  }%
  \IfValueTF{#1}{\figure[#1]}{\figure}%
}{%
  \endfigure
}
  
\newcommand{\solutioncolor}{red}
  
\begin{document}
  \begin{framedimage}
    \includegraphics{example-image}
    \caption{How are you?}
  \end{framedimage}
\end{document}

You can also define generally usable \framedincludegraphics and \unframedincludegraphics and even patch the change into the figure environment:

\documentclass{article}
\usepackage{xcolor}
\usepackage{graphicx}

\NewCommandCopy{\unframedincludegraphics}{\includegraphics}%
\NewDocumentCommand{\framedincludegraphics}{O{}m}{%
  \begingroup
    \setlength{\fboxrule}{5pt}%
    \setlength{\fboxsep}{5pt}%
    \fcolorbox{\solutioncolor}{white}{%
      \unframedincludegraphics[{#1}]{#2}%
    }%
  \endgroup
}%

\AddToHook{env/figure/before}{%
  \RenewCommandCopy{\includegraphics}{\framedincludegraphics}%
}

\newcommand{\solutioncolor}{red}
  
\begin{document}
  \begin{figure}
    \includegraphics{example-image}
    \caption{How are you?}
  \end{figure}
\end{document}

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