Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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.

share|improve this question
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 –  David Carlisle Jun 19 at 20:59
    
@DavidCarlisle: Please see my edit. –  Sisabe Jun 19 at 21:04
    
longtable package? –  David Carlisle Jun 19 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 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 –  David Carlisle Jun 19 at 21:27

2 Answers 2

up vote 3 down vote accepted

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

share|improve this answer
    
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 at 10:04
1  
@Sisabe What's the purpose of this command? –  egreg Jun 20 at 10:06
    
it is the equivalent of the below: \begin{xitemize} \item[Foo]\textbf{An item} ‎\end{xitemize}‎ –  Sisabe Jun 20 at 10:11
    
Actually, the real mycmd is more complicated and I've simplified that here to be a MWE. –  Sisabe Jun 20 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 at 10:24

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

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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