# Use varwidth with algorithm2e

I’m trying to draw a box around an algortihm2e construct, like this:

I tried to use the varwidth package to get a box with the natural width of the content:

\documentclass{article}

\usepackage{algorithm2e}
\usepackage{varwidth}

\begin{document}
\fbox{\begin{varwidth}{10cm}
\If{condition}{
loop content
}
\end{varwidth}}
\end{document}


Unfortunatly, the result looks like this: It looks like varwidth takes the maximum width when an \If or \For construct is used inside. How can I get a box with the natural width?

• The concept of natural width does not apply. Like \vbox, it will fill the available space (\hsize}. Aug 23, 2019 at 15:57

## 2 Answers

Meanwhile, I came up with a hack myself: Overwriting the internal macro of algorithm2e that draws the blocks and use the varwidth environment there.

Here is a solution for the vlined option:

\documentclass{article}

\usepackage[vlined]{algorithm2e}
\usepackage{varwidth}

\makeatletter
\renewcommand{\algocf@Vline}[1]{%     no vskip in between boxes but a strut to separate them,
\strut\par\nointerlineskip% then interblock space stay the same whatever is inside it
\algocf@push{\skiprule}%        move to the right before the vertical rule
\vbox{\hbox{\vrule%
\begin{varwidth}{\hsize}%
\vbox{\algocf@push{\skiptext}%move the right after the rule
\hbox{%
\algocf@addskiptotal%
\begin{varwidth}{\hsize}%
#1% inside the block
\end{varwidth}%
}%
\Hlne}%
\end{varwidth}%
}\vskip\skiphlne}%
\algocf@pop{\skiprule}%\algocf@subskiptotal% restore indentation
\nointerlineskip}% no vskip after

\renewcommand{\algocf@Vsline}[1]{%    no vskip in between boxes but a strut to separate them,
\strut\par\nointerlineskip% then interblock space stay the same whatever is inside it
\algocf@bblockcode%
\algocf@push{\skiprule}%        move to the right before the vertical rule
\hbox{\vrule%               the vertical rule
\begin{varwidth}{\hsize}%
\vbox{\algocf@push{\skiptext}%move the right after the rule
\hbox{\algocf@addskiptotal%
\begin{varwidth}{\hsize}%
#1% inside the block
\end{varwidth}%
}}%
\end{varwidth}%
}%
\algocf@pop{\skiprule}% restore indentation
\algocf@eblockcode%
}
\makeatother

\begin{document}
\fbox{\begin{varwidth}{\hsize}
\If{condition}{
loop content

a line longer than the loop header
}
\end{varwidth}}
\end{document}


With other options for the block style \algocf@Noline might have to be adapted similarly (not tested).

Here is a kludge using \tikzmarks to locate the top, bottom and right side (more or less).

Note that without the minipage, algorithm2e will use space outside the margins.

\documentclass{article}

\usepackage{algorithm2e}
\usepackage{tikz}
\usetikzlibrary{tikzmark}

\begin{document}
\begin{minipage}{\textwidth}
\tikzmark{A}\If{condition\tikzmark{B}}{
loop content
}\tikzmark{C}
\end{minipage}%
\begin{tikzpicture}[overlay, remember picture]
%\draw[red] (pic cs:A) -- (pic cs:B) -- (pic cs:C);
\path (pic cs:B) node[right, inner sep=0pt] (BB) {\phantom{ \textbf{then}}};
\path (pic cs:C) ++(0,\baselineskip) coordinate (CC);
\draw (pic cs:A) ++(0, \ht\strutbox)  rectangle (BB.east |- CC);
\end{tikzpicture}
\end{document}


• Your solution requires \tikzmark{B} to be placed at the end of the longest line, when the loop body is wider than the loop header. I’m interested in a more general solution that works independent of what is inside the loop body. Aug 24, 2019 at 8:45