6

Pardon me if this is a dumb question, but I am a bit rusty about this.

I want to store a list like one generated by the enumerate environment in a re-usable box that I may re-use within a TikZ picture and elsewhere.

In a manner of speaking, fancybox.sty does this with an actual framed box rather than a re-usable box.

Naively, I am looking to do something like:

\documentclass[a4paper,12pt]{article}
\begin{document}
\newsavebox{\enumbox}
\sbox{\enumbox}{%
\begin{enumerate}
    \item Title
    \item Abstract
    \item Keywords
    \item Outline
\end{enumerate}
}
{\centering\usebox{\enumbox}}
\end{document}

Of course, the above does not work because it is neither a parbox nor an lrbox.

Is there any package that does this? Otherwise, what do I have to do to get what I am seeking?

Thanks in advance.

2 Answers 2

8

You need to save the enumerate contents in a \vbox:

\setbox\enumbox\vbox{% …

Though, the \centering won’t work because the box is—due to enumerate’s nature— \linewidth wide.
Using it without \centering results in an overfull \hbox because the paragraph indention is inserted as usual.

Solution A

It seems, that in your case you simply could define a macro as

\newcommand*{\enummacro}{\begin{enumerate} … \end{enumerate}}

and use that inside a TikZ node. Advantage: The node would not be \linewidth wide but only as wide as you would have specified.

Solution B

You could measure the width of the list elements (assuming that they all fit on one line width-wise).

Here, I opted for an easier list defining and processing solution, namely

\newcommand*{\mylist}{Title,Abstract,Keywords,Outline}

The \mylist macro only contains the comma-separated elements.

The \getWidthOf macro needs \tikz@textfont and the smuggle macro to be usable inside a tikzpicture (no warranties here).

Solution C

As the enumerate environment introduces vertical and horizontal space which with I do not want to deal and also because the following looks better and is easier to maintain, yet another solution but with a simple tabular.

Code A (enumerate with guessed width)

\documentclass[a4paper,12pt]{article}
\usepackage{tikz}
\newcommand{\enummacro}{%
\begin{enumerate}
    \item Title
    \item Abstract
    \item Keywords
    \item Outline
\end{enumerate}}
\newsavebox\enumbox

\begin{document}
\setbox\enumbox\vbox{\enummacro}
\noindent\usebox\enumbox

\begin{tikzpicture}
    \node[draw, text width=8em, align=center] {\enummacro};
\end{tikzpicture}
\end{document}

Output (enumerate with guessed width)

enter image description here

Solution B (properly measured enumerate)

\documentclass[a4paper,12pt]{article}
\usepackage{tikz}

\newcommand*{\mylist}{Title,Abstract,Keywords,Outline}
\newlength{\widthOfWidestElement}

\makeatletter
\def\qrr@smuggle@length@through@interruptpgfpicture#1\endpgfinterruptpicture{%
    \edef\@tempa{\the#1}%
    \expandafter\endpgfinterruptpicture\expandafter#1\@tempa}
\newcommand*{\getWidthOf}[1]{%
    \pgfinterruptpicture
    \setlength{\widthOfWidestElement}{0pt}%
    \@for\@element:=#1\do{%
        \sbox0{\tikz@textfont\@element}%
        \ifdim\wd0>\widthOfWidestElement\widthOfWidestElement=\wd0\fi
    }%
    \qrr@smuggle@length@through@interruptpgfpicture\widthOfWidestElement
    \endpgfinterruptpicture
    \advance\widthOfWidestElement\itemindent
    \advance\widthOfWidestElement\leftmargin
    \advance\widthOfWidestElement\rightmargin
}
\newcommand*{\makeEnumerate}[1]{%
    \enumerate % maybe better output with
               % \parskip\z@
        \@for\@element:=#1\do{%
            \item \@element
        }
    \endenumerate
}
\makeatother
\begin{document}

\begin{tikzpicture}
    \getWidthOf{\mylist}
    \node[draw, text width=\widthOfWidestElement, align=center] {\makeEnumerate\mylist};
\end{tikzpicture}
\end{document}

Output B (properly measured enumerate)

enter image description here

Code C (tabular)

\documentclass[a4paper,12pt]{article}
\usepackage{tikz,array}

\newcommand*{\mylist}{Title,Abstract,Keywords,Outline}

\makeatletter
\newcommand*{\makeFakeEnumerate}[1]{%
    \begingroup
    \def\@temptabbody{}%
    \setcounter{enumi}{0}%
    \@for\@element:=#1\do{%
        \expandafter\g@addto@macro\expandafter\@temptabbody\expandafter{\expandafter&\@element \\}}%
    \tabular{>{\refstepcounter{enumi}\theenumi.}rl}
        \@temptabbody
    \endtabular
    \endgroup
}
\makeatother
\begin{document}
\begin{tikzpicture}
    \node[draw] {\makeFakeEnumerate\mylist};
\end{tikzpicture}
\end{document}

Output C (tabular)

enter image description here

3
  • Thank you. I have one question though. Is there any way to loop through the enumerate entries to get the longest so that the box width may be determined automatically? Thanks.
    – chandra
    Mar 30, 2013 at 14:37
  • Would you be interesting in using \newcommand*{\enummacro}{Title,Abstract,Keywords,Outline} as a list which will be used to get measured and to set up the enumerate environment? What is your end goal here? Maybe you could use a tabular with two columns of which the last one is a line-breaking-disallowing l column. Mar 30, 2013 at 15:18
  • Thank you for the tabular output C that mimics an enumerate environment but which is easy to maintain. I am using the makeFakeEnumerate command in a manuscript and the result here is exactly what I wanted: i.imgur.com/FKAosW9.png. I guess that I could adapt this to display bullet-points in a makeFakeItemize command as well. Thank you very much.
    – chandra
    Apr 1, 2013 at 10:57
7

Unless there is a compelling reason to use a box, it is much simpler to:

\documentclass[a4paper,12pt]{article}
\begin{document}
\newcommand\enumbox{%
\enumerate
    \item test
    \item Abstract
    \item Keywords
    \item Outline
\endenumerate
}
\enumbox
\end{document}

If you want to center do this:

\documentclass[a4paper,12pt]{article}
\usepackage{lipsum}
\begin{document}
\newcommand\enumbox{%
\enumerate
    \item test
    \item Abstract
    \item Keywords
    \item Outline
\endenumerate
}
\lipsum[1]\centering
\fbox{\hbox to 3cm{\vbox{\enumbox}}}
\end{document}
2
  • Thank you. I have the same question as above. Is there a way of determining the required box width (which is manually set to 3 cm here) by looping through the entries to find the longest? I looked at the forloop package but wasn't sure it was suited for this. I would like to automate this, please.
    – chandra
    Mar 30, 2013 at 14:40
  • @chandra It is possible, will post a solution in the morning, as I am on the other side of the world:) Mar 30, 2013 at 15:53

You must log in to answer this question.

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