3

I want the output of the code below to be like this image. How to do this?
Please keep in mind that the width of [Foo Bar Foo]'s is variable. So it should be calculated automatically.

\documentclass{book}
\begin{document}
\noindent Just enough text to make the line break so we get to see a second line.
\begin{itemize}
  \item[Foo] An item
  \item[Foo Bar Foo] An item An item An item An item An item An item An item An item An item An item An item An item An item An item  
  \item[Bar Bar] An item 
\end{itemize}
Just enough text to make the line break so we get to see a second line.
\end{document}

enter image description here

Edit: I don't want to use tabular or similar environment, because there are many items which should span some pages.

5
  • 1
    simplest is to use a tabular rather than a list, or you could do like bibitem and have an option to give the widest label, or you need two passes and save the widest label in the aux file to align on a second pass Jun 19, 2014 at 20:59
  • @DavidCarlisle: Please see my edit.
    – Sisabe
    Jun 19, 2014 at 21:04
  • longtable package? Jun 19, 2014 at 21:10
  • @DavidCarlisle: Isn't there any other way to solve this problem? I don't have pleasant experience with tabular-like environment.
    – Sisabe
    Jun 19, 2014 at 21:14
  • 1
    yes as I say you can do a two pass solution to record the widest entry, I may post something in a bit of noone else has Jun 19, 2014 at 21:27

2 Answers 2

3

If you don't have dangerous things like labels or counter settings (numbered equations, for instance) in the body of the itemize, you can locally redefine \item to do the measurement:

\documentclass{article}
\usepackage{enumitem,environ}

\newlength{\xitemlenx}
\newlength{\xitemleny}
\NewEnviron{xitemize}{%
  \setbox0=\vbox{
    \xitemlenx=0pt
    \def\item[##1]{\measureitem{##1}}
    \BODY
    \global\xitemleny\xitemlenx
  }%
  \itemize[
    leftmargin=\dimexpr\xitemleny+\labelsep,
    labelwidth=\xitemleny,
    align=left
  ]
  \BODY
  \enditemize
}
\newcommand{\measureitem}[1]{%
  \settowidth{\dimen0}{#1}%
  \ifdim\dimen0>\xitemlenx
    \xitemlenx=\dimen0
  \fi
}

\begin{document}

Just enough text to make the line break so we get to see a second line.
Just enough text to make the line break so we get to see a second line.
\begin{xitemize}
  \item[Foo] An item
  \item[Foo Bar Foo] An item An item An item An item An item An item An item An item An item An item An item An item An item An item  
  \item[Bar Bar] An item 
\end{xitemize}
Just enough text to make the line break so we get to see a second line.
Just enough text to make the line break so we get to see a second line.
\end{document}

enter image description here

If you need a single item, as you seem to from your comments, it's easier because just one label needs to be measured; here's the idea, integrated in the previous code.

\documentclass{article}
\usepackage{enumitem,environ}

\newlength{\xitemlenx}
\newlength{\xitemleny}
\NewEnviron{xitemize}{%
  \setbox0=\vbox{
    \xitemlenx=0pt
    \def\item[##1]{\measureitem{##1}}
    \BODY
    \global\xitemleny\xitemlenx
  }%
  \itemize[
    leftmargin=\dimexpr\xitemleny+\labelsep,
    labelwidth=\xitemleny,
    align=left
  ]
  \BODY
  \enditemize
}
\newcommand{\measureitem}[1]{%
  \settowidth{\dimen0}{#1}%
  \ifdim\dimen0>\xitemlenx
    \xitemlenx=\dimen0
  \fi
}

\newcommand{\singleitem}[2]{%
  \settowidth{\xitemleny}{#1}%
  \begin{itemize}[
    leftmargin=\dimexpr\xitemleny+\labelsep,
    labelwidth=\xitemleny,
    align=left
  ]
  \item[#1]\textbf{#2}
  \end{itemize}%
}

\begin{document}

Just enough text to make the line break so we get to see a second line.
Just enough text to make the line break so we get to see a second line.
\begin{xitemize}
  \item[Foo] An item
  \item[Foo Bar Foo] An item An item An item An item An item An item An item An item An item An item An item An item An item An item  
  \item[Bar Bar] An item 
\end{xitemize}
Just enough text to make the line break so we get to see a second line.
Just enough text to make the line break so we get to see a second line.
Now a single item:
\singleitem{Foo Bar}{An item An item An item An item An item An item An item An item An item An item An item An item An item An item}
Just enough text to make the line break so we get to see a second line.
Just enough text to make the line break so we get to see a second line.

\end{document}

enter image description here

10
  • Thanks for your answer. Just one thing: for simplicity, I've defined a command named mycmd as \newcommand{\mycmd}[2]{% \begin{xitemize} \item[#1] \textbf{#2} \end{xitemize} ‎}‎‎‎ and I use it as \mycmd{...}{...} in the body, but it doesn't work. Could you please tell me how to solve this?
    – Sisabe
    Jun 20, 2014 at 10:04
  • 1
    @Sisabe What's the purpose of this command?
    – egreg
    Jun 20, 2014 at 10:06
  • it is the equivalent of the below: \begin{xitemize} \item[Foo]\textbf{An item} ‎\end{xitemize}‎
    – Sisabe
    Jun 20, 2014 at 10:11
  • Actually, the real mycmd is more complicated and I've simplified that here to be a MWE.
    – Sisabe
    Jun 20, 2014 at 10:12
  • @Sisabe If you have a single \item, you just need to measure its argument: much less complication. I'll add it to my answer; please tell me if it doesn't suit your needs.
    – egreg
    Jun 20, 2014 at 10:24
2

With the ltablex package, wich combines the functionalities of tabularx and longtable, it's very easy:

\documentclass{book}
\usepackage[utf8]{inputenc}
\usepackage{fourier, heuristica}
\usepackage{array, ltablex}

\begin{document}
\noindent Just enough text to make the line break so we get to see a second line. Text text text text tex text text text tex.

\begin{tabularx}{\linewidth}{@{}l@{\quad}X@{}}
 Foo & An item \\
Foo Bar Foo & An item An item An item An item An item An item An item An item An item An item An item An item An item An item\\
Bar Bar & An item
\end{tabularx}
Just enough text to make the line break so we get to see a second line. Text text text text tex text text text tex.

\end{document} 

enter image description here

You must log in to answer this question.

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