2

I would like to have an list (itemize) with a box around it. I know that \framebox doesn't work, because it doesn't support line breaks. Also I don't want to use \parbox because I'd have to set the width myself. I'm doing some work where I have tons of boxes and thus I don't want to always care about the width. It should auto scale, like \framebox does it.

Edit:

What I did is the following: (until now) [you need to include \usepackage{minibox} package]

\newcommand{\ltwo}[2] { \framebox{\minibox{$\bullet$ #1 \\ $\bullet$ #2}}}
\newcommand{\lthree}[3] { \framebox{\minibox{$\bullet$ #1 \\ $\bullet$ #2 \\ $\bullet$ #3}}}

\newcommand{\lfour}[4] { \framebox{\minibox{$\bullet$ #1 \\ $\bullet$ #2 \\ $\bullet$ #3 \\ $\bullet$ #4}}}

So I write:

\lthree{Hello}{The width will adjust to the width of this line}{ but not this}

I know I could write recursive macros, but I'm too inexperienced atm.

xotix
  • 266

1 Answers1

2

You could use some tricks from Macro to capture until end-of-line as argument to capture each \item and process it.

Below I've provided \boxitem and \varboxitem that would process each \item as either a boxed \parbox or varwidth box (of appropriate maximum width):

enter image description here

\documentclass{article}
\usepackage{xparse,environ,varwidth}
\usepackage[nopar]{lipsum}

\ExplSyntaxOn
\NewEnviron{myitemize}[1][]
 {
  \keys_set:nn { xotix/itemize } { #1 }
  \seq_set_split:NnV \l_xotix_itemize_input_seq { \item } \BODY
  \seq_pop_left:NN \l_xotix_itemize_input_seq \l_tmpa_tl
  \tl_use:N \l_xotix_itemize_pre_tl
  \seq_set_map:NNn
    \l_xotix_itemize_output_seq
    \l_xotix_itemize_input_seq
    { \exp_not:n { \__xotix_itemize_do:n { ##1 } } }
  \seq_use:NV \l_xotix_itemize_output_seq \l_xotix_itemize_sep_tl
  \tl_use:N \l_xotix_itemize_post_tl
 }

\seq_new:N \l_xotix_itemize_input_seq
\seq_new:N \l_xotix_itemize_output_seq
\cs_generate_variant:Nn \seq_set_split:Nnn { NnV }
\cs_generate_variant:Nn \seq_use:Nn { NV }

\keys_define:nn { xotix/itemize }
 {
  pre  .tl_set:N = \l_xotix_itemize_pre_tl,
  post .tl_set:N = \l_xotix_itemize_post_tl,
  sep  .tl_set:N = \l_xotix_itemize_sep_tl,
  action .code:n = \cs_set_eq:NN \__xotix_itemize_do:n #1,
  action .initial:n = \use:n,
 }
\ExplSyntaxOff

\NewDocumentCommand{\boxitem}{m}{%
  \item \fbox{\parbox[t]{\dimexpr\linewidth-2\fboxsep-2\fboxrule}{\strut #1\strut}}%
}

\NewDocumentCommand{\varboxitem}{m}{%
  \item \fbox{\begin{varwidth}[t]{\dimexpr\linewidth-2\fboxsep-2\fboxrule}
    \strut #1\strut
  \end{varwidth}}%
}

\begin{document}

\begin{myitemize}[
    action=\boxitem,
    pre=\begin{itemize},
    post=\end{itemize},
  ]
  \item First
  \item Second
  \item Last
\end{myitemize}

\begin{myitemize}[
    action=\varboxitem,
    pre=\begin{itemize},
    post=\end{itemize},
  ]
  \item First
  \item Second
  \item Last
\end{myitemize}

\clearpage

\begin{myitemize}[
    action=\boxitem,
    pre=\begin{itemize},
    post=\end{itemize},
  ]
  \item First
  \item \lipsum[2]
  \item Last
\end{myitemize}

\begin{myitemize}[
    action=\varboxitem,
    pre=\begin{itemize},
    post=\end{itemize},
  ]
  \item First
  \item \lipsum[2]
  \item Last
\end{myitemize}


\end{document}

\boxitem (which uses \parbox) sets its contents in a fixed-width box, while \varwidthbox may shrink if the contents is less than the specified maximum width. \struts have been added to allow for proper spacing around the baselines of the \items.

Of course, since all items are boxed, they won't break across the page boundary.

Werner
  • 603,163