[Tex/LaTex] Box around a few items in an itemize environment

beamerframedlists

I'm using beamer and want to call out a few items in a list by drawing a box around them, and, ideally, having a small comment appear next to the box, like this:

enter image description here

Best Answer

One way to do that is to adapt the code from Highlight elements in the matrix. Below, I provide two macros \DrawBox and \DrawBoxWide depending on if you want to include the list markers or not. The default below is to produce a red box, but this can be adjusted to suit, or the options can be specified on a per use basis (as in the second example):

enter image description here

However, since the width of the box is based on the width of the last item, there is a possibility that the box won't be wide enough if the last item is shorter than the wides item within the box. For this case I have defined \DrawBox* and \DrawBoxWide* which use enclose the items in a box as wide as the line:

enter image description here

Note that in the above the width of the box is the full \linewidth. This is not an issue if the text uses the full width as is the case of the blue box above, but for the case where the text is not the full width (as is the case for the red box), one might desire a tight box around the text. In this case I would recommend that the last line be set in a box as wide as the widest text using:

\makebox[\widthof{\WidestText}][l]{<text>}\tikzmark{right}

which yields:

enter image description here

Syntax:

To use this you place \tikzmark{left} to mark the position where the top left of the box is, and \tikzmark{right} to mark the position of the bottom right of the box. After these two positions have been marked you call the \DrawBox or \DrawBoxWide (or the starred variant) macros to draw the box.

Notes:

  • This does require two runs: the first to compute the positions of the box, and the second to draw it in the correct spot.
  • Since this is using tikz, you automatically get all the flexibility inherent in tikz, such as line styles, line thickness, line color, fill, etc. These can be passed to the \DrawBox macros to customize each instance or provided as default options to maintain consistency.

Code:

\documentclass{article}
\usepackage{xparse}%  For \NewDocumentCommand
\usepackage{calc}%    For the \widthof macro
\usepackage{tikz}
\usetikzlibrary{calc}

\newcommand{\Text}{Lorem ipsum dolor sit amet, consectetur adipiscing elit. 
    Sed accumsan nulla ac ipsum elementum interdum. }

\newcommand{\tikzmark}[1]{\tikz[overlay,remember picture] \node (#1) {};}

\makeatletter
\NewDocumentCommand{\DrawBox}{s O{}}{%
    \tikz[overlay,remember picture]{
    \IfBooleanTF{#1}{%
        \coordinate (RightPoint) at ($(left |- right)+(\linewidth-\labelsep-\labelwidth,0.0)$);
    }{%
        \coordinate (RightPoint) at (right.east);
    }%
    \draw[red,#2]
      ($(left)+(-0.2em,0.9em)$) rectangle
      ($(RightPoint)+(0.2em,-0.3em)$);}
}

\NewDocumentCommand{\DrawBoxWide}{s O{}}{%
    \tikz[overlay,remember picture]{
    \IfBooleanTF{#1}{%
        \coordinate (RightPoint) at ($(left |- right)+(\linewidth-\labelsep-\labelwidth,0.0)$);
    }{%
        \coordinate (RightPoint) at (right.east);
    }%
    \draw[red,#2]
      ($(left)+(-\labelwidth,0.9em)$) rectangle
      ($(RightPoint)+(0.2em,-0.3em)$);}
}
\makeatother

\begin{document}
Using the \verb|\DrawBox and \DrawBoxWide|:
\medskip\par\noindent
\begin{minipage}{0.4\linewidth}
  \begin{enumerate}
        \item First Item
        \item \tikzmark{left}Second Item
        \item Third Item
        \item Fourth Item\tikzmark{right}
        \item Fifth Item
  \end{enumerate}
    \DrawBox[thick]
\end{minipage}
%
\begin{minipage}{0.4\linewidth}
  \begin{enumerate}
        \item First Item
        \item \tikzmark{left}Second Item
        \item Third item
        \item Fourth Item\tikzmark{right}
        \item Fifth Item
  \end{enumerate}
    \DrawBoxWide[thick, blue, fill=yellow, fill opacity=0.2]
\end{minipage}

Using the \verb|\DrawBox* and \DrawBoxWide*|:
\medskip\par\noindent
\begin{minipage}{0.4\linewidth}
  \begin{enumerate}
        \item First Item
        \item \tikzmark{left}Second Item
        \item Third item.
        \item Fourth Item\tikzmark{right}
        \item Fifth Item
  \end{enumerate}
    \DrawBox*[thick]
\end{minipage}
%
\begin{minipage}{0.4\linewidth}
  \begin{enumerate}
        \item First Item
        \item \tikzmark{left}Second Item
        \item Third item: \Text
        \item Fourth Item\tikzmark{right}
        \item Fifth Item
  \end{enumerate}
    \DrawBoxWide*[thick, blue, fill=yellow, fill opacity=0.2]
\end{minipage}

\noindent
For the case where the last line is not the longest and the lines before do not use the full width of the text, as would be the case below with \verb|\DrawBoxWide*|, you can use \verb|\makebox{\widthof{<widest_text>}{<text>}|

\newcommand*{\WidestText}{Third item which is wider}%
\begin{enumerate}
    \item First Item
    \item \tikzmark{left}Second Item
    \item Third item which is wider
    \item \makebox[\widthof{\WidestText}][l]{Fourth Item}\tikzmark{right}
    \item Fifth Item
\end{enumerate}
\DrawBoxWide[thick, brown]
\end{document}