7

I do a lot of itemize lists in beamer presentation which, in a later step, I want to format nicely, for instance, typeset everything up to the first colon in boldface and the remaining part scriptsize inside a \parbox. A common idiom I use is to define a custom \Item command for this purpose that parses the item text and emits a \item with the intended formatting:

\documentclass{beamer}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{calc}

\begin{document}

\def\Item#1:#2\endItem{\item \parbox{2cm}{\strut\textbf{#1:}}\parbox[t]{\linewidth-2cm}{\footnotesize#2}}
\begin{frame}{A frame}
  Common metasyntactic variables (used to name absolutely anything)
  \begin{itemize}
    \Item foo: f*cked over and over? Well, we do not really know the meaning of this beast.\endItem
    \Item bar: beyond all reason?\endItem
  \end{itemize}
\end{frame}

\end{document}

enter image description here However, to scan the "rest" of the item's text as a macro argument, I have to finish eacht item by an explicit end marker \endItem, which I would like to avoid. As in this related question, I also do not want to put the item's text into groups of curly braces.

Is there another, more elegant way to scan to the end of an \item?

  • 2
    It's actually fubar, which evolved into foobar. – Werner May 10 '12 at 21:27
  • 1
    You can use \par as delimiter, instead of \endItem, but you'll need to leave a blank line at the end of each item. – egreg May 10 '12 at 21:30
  • @Werner: I know. My example is furchtbar :-) – Daniel May 11 '12 at 6:50
  • @egreg: I did consider this, but refrained from it I consider it as too fragile. The fact that the blank lines suddenly are mandatory would be a clear violation of the principle of least surprise for anybody editing my stuff. – Daniel May 11 '12 at 6:59
  • @Daniel TeX is not a language for general parsing; it's designed for typesetting paragraphs. In order to gather some user input for processing you have to delimit it in some way. An "inner" environment, using the environ package, might be a better solution than using \endItem. – egreg May 11 '12 at 9:17
6

You can recreate the same effect with a description list and some styling. Unfortunately, beamer doesn't have a template for the description part of the the description list. So setting the font size to \footnotesize has to involve some hack. Maybe someone can come up with a less intrusive one.

\documentclass{beamer}
\usepackage{etoolbox}

\setbeamertemplate{description item}{%
    \usebeamertemplate*{itemize item} %
    \insertdescriptionitem:\hfill%
}
\setbeamercolor{description item}{fg=black}
\setbeamerfont{description item}{series=\bfseries,size=\normalsize}
\setbeamersize{description width=2cm}

\makeatletter
\apptocmd\@@description{\footnotesize}
\makeatother

\begin{document}

\begin{frame}{A useless list}
  \begin{description}
    \item[first] This is the first list item
    \item[bar] And this is the second one
  \end{description}
\end{frame}

\end{document}

result

  • +1 Neat trick, which, however only solves this particular example. (Thats always the problem with MWEs, in the end you have oversimplified...). I am actually seeking a general solution that would also work if I want to parse into more than two parts. Moreover, I need to mix my customized \Items and ordinary \items within the same list. – Daniel May 11 '12 at 6:56
1

This is a bit of an old post but it is possible to do this using latex3 regular expressions. Namely, we can slurp up the entire contents of the environment and then split it into a sequence on the \item commands inside it. We can then add the closing \endItem's in when we process the sequence. I think I learned this trick from one of egreg's answers.

The code below uses the b argument option for \NewDocumentEnvironment from xparse. I am not sure exactly when the b option was added to xparse but it was quite recent so it is quite likely that the code below requires a version of l3packages that was released 2019-05-03 (currently the latest version) or later. The b option makes the contents of the environment equal to #1 -- previously I used the environ package to do this sort of thing. The output is the expected:

enter image description here

Here is the code:

\documentclass{beamer}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{calc}

\usepackage{xparse}
\ExplSyntaxOn
\seq_new:N \l_itemize_seq
\NewDocumentEnvironment{Itemize}{ +b }{
  \regex_split:nnN {\c{item}} {#1} \l_itemize_seq
  \seq_pop:NN \l_itemize_seq \l_tmpa_tl% remove the (hopefully) empty first item
  \seq_if_empty:NF \l_itemize_seq {
    \begin{itemize}
      \seq_map_inline:Nn \l_itemize_seq {\Item##1\endItem}
    \end{itemize}
  }
}{}
\ExplSyntaxOff

\begin{document}

\def\Item#1:#2\endItem{\item \parbox{2cm}{\strut\textbf{#1:}}%
   \parbox[t]{\linewidth-2cm}{\footnotesize#2}}
\begin{frame}{A frame}
  Common metasyntactic variables (used to name absolutely anything)
  \begin{Itemize}
    \item foo: f*cked over and over? Well, we do not really know the
          meaning of this beast.
    \item bar: beyond all reason?
  \end{Itemize}
\end{frame}

\end{document}

I have written this specifically for the \Item#1\endItem syntax of the question but it would be possible to make this more general.

  • Interesting approach using regexes to scan for the next \item. I have not yet tried it, but I assume it would fail on nested lists? Anyway, apparently it's time to learn xparse. :-) – Daniel May 4 at 8:36
  • @Daniel Yes nesting is bound to go wrong. Although, xparse is used above the real action is in latex3, which looks awful to start with but after a while starts to grow on you. – Andrew May 4 at 9:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.