62

Is it possible to split an itemize list into several columns? (I'm sure it is, but I couldn't find a solution around here)

And additionally: Is it possible to automatically split a list into multiple columns if it reaches a certain item length?

so i want to display

item1
item2
item3

instead of

item1   item2   item3

while this should still happen

item1   item4
item2   item5
item3   item6
18

Here is some code that does the automatic column adjust thing, I used the code found in "count and use the number of items in advance" to help me.

\documentclass{article}
\usepackage{etoolbox,refcount}
\usepackage{multicol}

\newcounter{countitems}
\newcounter{nextitemizecount}
\newcommand{\setupcountitems}{%
  \stepcounter{nextitemizecount}%
  \setcounter{countitems}{0}%
  \preto\item{\stepcounter{countitems}}%
}
\makeatletter
\newcommand{\computecountitems}{%
  \edef\@currentlabel{\number\c@countitems}%
  \label{countitems@\number\numexpr\value{nextitemizecount}-1\relax}%
}
\newcommand{\nextitemizecount}{%
  \getrefnumber{countitems@\number\c@nextitemizecount}%
}
\newcommand{\previtemizecount}{%
  \getrefnumber{countitems@\number\numexpr\value{nextitemizecount}-1\relax}%
}
\makeatother    
\newenvironment{AutoMultiColItemize}{%
\ifnumcomp{\nextitemizecount}{>}{3}{\begin{multicols}{2}}{}%
\setupcountitems\begin{itemize}}%
{\end{itemize}%
\unskip\computecountitems\ifnumcomp{\previtemizecount}{>}{3}{\end{multicols}}{}}

\begin{document}

\begin{itemize}
    \item Here are two columns
  \begin{AutoMultiColItemize}
  \item Item 1
  \item Item 2
  \item Item 3
  \item Item 4
  \item Item 5
  \item Item 6
  \end{AutoMultiColItemize}
  \item AutoMultiColItemize can be nested in an itemize
  \item Or it does not have to be.
  \item Normal itemize, like this one, are still single column.
\end{itemize}
Here is one column
\begin{AutoMultiColItemize}
\item Item 1
\item Item 2
\item Item 3
\end{AutoMultiColItemize}

\end{document}

Here is what it looks like: Multiple Columns

  • 1
    Thanks a lot for this great solution! This makes documents with many lists definitely cleaner. As a Tex beginner, all this stuff is a new world to discover and I love it how fast one can get perfect help around the stackexchange network. Awesome Stackexchange folks =)! – Daniel Aug 2 '14 at 23:53
  • Great effort Strategy Thinker. Still one problem though, the items are not vertically aligned. Items of the right column are closer!! It becomes clearer if you add Item 4 in the last list. – AboAmmar Aug 3 '14 at 0:26
  • Thanks, I needed to add a \unskip after \end{itemize}, otherwise it would create a new line. – Strategy Thinker Aug 3 '14 at 16:38
  • The image illustrating the result doesn't exist anymore. – usernumber Oct 25 '17 at 18:39
  • @usernumber I restored that image using the wayback machine on web.archive.org – Daniel Nov 1 '17 at 12:43
95

Since you want multiple columns, you should use the multicol package:

enter image description here

Code:

\documentclass{article}
\usepackage{multicol}

\begin{document}
Two columns:
    \begin{multicols}{2}
    \begin{itemize}
        \item item 1
        \item item 2
        \item item 3
        \item item 4
        \item item 5
        \item item 6
    \end{itemize}
    \end{multicols}

Three columns:
    \begin{multicols}{3}
    \begin{itemize}
        \item item 1
        \item item 2
        \item item 3
        \item item 4
        \item item 5
        \item item 6
    \end{itemize}
    \end{multicols}
\end{document}
  • What can happen if you have an item with long text? Sure it will extend to the next column. What is the solution in this case? – AboAmmar Aug 2 '14 at 21:48
  • @AboAmmar: I am not sure I fully understand the problem you are describing. Please edit your question and provide a test case (MWE) that illustrates what you are describing and what you think the "correct" output should be. – Peter Grill Aug 3 '14 at 4:16
  • 12
    as much as it pains me to say, but multicol is not a good solution to this problem in a general case. It works alright in your examples above, because they all contain single line items and the same in each column, but this gets bad the moment you have different amounts of text per column. As multicol starts with slighly compressed column heights and works its way up to the point they balance you normally end up with uneven (and compressed glue and that can look rather horrible. See my talk from Tokyo 2013 (latex-project.org/papers) where I discuss some of those issues. – Frank Mittelbach Aug 5 '14 at 19:32
  • 1
    (for the lazy, the slides from the 2013 talk are at latex-project.org/publications/2013-10-23-FMi-stony-beamer.pdf). Any progress since this talk on that question, @FrankMittelbach ? – Clément Feb 2 at 19:39
8

Use multicol. If your items do not divide evenly into each column, add \item[\vspace{\fill}] to the end of your list to align the items.


The multicol package solution from AboAmmar works well if your enumerate items can be divided evenly into each column.

However, spacing between items can become inconsistent if each column does not hold an equal number of items. For example, dividing 7 items between 2 columns:

One can fix this easily by adding an 'empty' item at the end of the list as padding.

\item[\vspace{\fill}]

Which produces the following nicely aligned multi-columned enumerate list:

enter image description here

\documentclass[preview]{standalone}
\usepackage{multicol}
\begin{document}

\begin{multicols}{2}
  \begin{enumerate}
    \item one  \item two \item three \item four
    \item five \item six \item seven \item[\vspace{\fill}]
  \end{enumerate}
\end{multicols}

\end{document}
7

A quick possible solution is using the minipage environment as follows:

\documentclass[12pt,a4paper]{article}
\begin{document}

\begin{itemize}
\begin{minipage}{0.4\linewidth}
    \item item 1
    \item item 2
    \item item 3
\end{minipage}
\begin{minipage}{0.4\linewidth}
    \item item 4
    \item item 5
    \item item 6
\end{minipage}
\end{itemize}

\end{document}

This outputs:

enter image description here

  • I would note that this quickly becomes unmaintainable and doesn't purely represent the idea of columns. – Sean Allred Aug 2 '14 at 22:15
  • @Sean Allred- However, using two minipages will change how list items are numbered (column-wise rather than row-wise, as desired). Only the second part of the question hasn't been answered. None of the other 3 answers succeeded in this regard. – AboAmmar Aug 3 '14 at 0:00
  • Try it with enumerate instead. – Sean Allred Aug 3 '14 at 0:00
  • Good point about the desired behavior though; you're right in that multicol will always use as little vertical space as possible. Perhaps a better question to ask, in this case, is if it is possible to give the multicols environment a minimum vertical space to occupy. Edit: I spoke too soon; see the accepted answer :) – Sean Allred Aug 3 '14 at 0:10
  • I didn't know you could have a minipage inside itemize... it didn't work for me (beamer class), but of course having itemize inside minipages worked fine. – PatrickT Nov 26 '17 at 11:46
3

For the first question, you can do that with the tasks package, that was formerly part of the exsheets bundle. If you use MiKTeX, beware it requires the cntformats package (from the same author), that's not (yet) part of MiKTeX. To answer Werner's question, it can break across pages.Here is an example of how it works:

\documentclass[twoside, a4paper]{report}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[x11names]{xcolor}
\usepackage{fourier}
\usepackage[noheadfoot, nomarginpar, showframe]{geometry}

\usepackage{tasks}
 \DeclareInstance{tasks}{myitemize}{default}
 {
enumerate = false ,
label-width = 1.125em,
label-offset = 0.6em,
label-format = \bfseries\color{IndianRed3}
 }

\settasks{style = myitemize, column-sep = 2em}%
\pagestyle{plain}%


\begin{document}

\begin{tasks}(3)
    \task First item
    \task A second item
    \task A third one
    \task A second series, item 1
    \task Second series, item 2
    \task Second series, item 3
\end{tasks}

\end{document} 

enter image description here

Another solution would use the shortlst package, which is not part of any distribution for license reasons, so that you have to install it yourself. I patched it so as to be able to choose the number of columns with a key nc=value (3 by default) and the interline stretch il=value (1.33 by default).

The main advantage of this package is that if an item is longer than the column width it automatically spreads over two (or more) columns. Alternatively an item can be put in a parbox of width column width. I introduced a \paritem command, that takes as an optional argument the number of columns the item will spread over.

\documentclass[twoside, a4paper]{report}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[x11names]{xcolor}
\usepackage{fourier}
\usepackage[nohead, nomarginpar, showframe]{geometry}

\pagestyle{plain}%

\usepackage{ragged2e}

\usepackage{shortlst, setspace, xkeyval}

\makeatletter
\newcounter{ncol}
\define@key{lex}{nc}[3]{\setcounter{ncol}{#1}}%% 3 columns by default
\define@key{lex}{il}[1.33]{\def\@intln{#1}}% interlining![1]
\newenvironment{tabitemize}[1][]{%
\setkeys{lex}{nc,il,#1}
\settowidth{\labelwidth}{\quad\textbullet}
\setlength{\leftmargini}{\dimexpr\labelwidth+\labelsep\relax}%[1][3]
\setlength{\shortitemwidth}{\dimexpr\linewidth/\value{ncol}-\labelwidth-2\labelsep\relax}%
\renewcommand{\labelitemi}{\textcolor{Tomato3}{\bfseries\textbullet}}
\setstretch{\@intln}
\begin{shortitemize}}%
{\end{shortitemize}
 }%
 \newcommand\paritem[2][2]{\item \parbox[t]{\dimexpr#1\shortitemwidth + (2\labelsep + \labelwidth)*\numexpr#1-1\relax}{\setstretch{1}#2}}
\makeatother
\usepackage{lipsum} 

\begin{document}
\vspace*{1 cm}

\begin{tabitemize}
    \item First item
    \item A second, much longer item
    \item A third, short item
    \paritem[2]{A second series, with a much longer item. \lipsum[2]}%
    \item Second series, item 4\strut
    \item Second series, third item, a much much longer item\strut
    \item Second series, fourthr item\strut
\end{tabitemize}

\end{document} 

enter image description here

  • While I like the tasks package (obviously) it does not do what the OP wants: items are arranged per row instead of per column. (BTW: items cannot contain page breaks) – clemens Aug 2 '14 at 20:08
  • Oh! Sorry. I misread, due to the fact the solutions are better known in that case. Should I withdraw my answer? – Bernard Aug 2 '14 at 20:56
  • 3
    No, I'm sure it'll be useful for people. – clemens Aug 2 '14 at 20:57
0

Here is javascript code for TeXstudio macro that can do from this

One, two, three,
B is for bee. One, two,
The bee is near you. 

automatically to this (multicol package is required)

\begin{enumerate}
    \begin{multicols}{3}
        \item One, two, three,
        \item B is for bee. One, two,
        \item The bee is near you.
    \end{multicols}
\end{enumerate} 

Maximal number of columns and enviroment (enumerate or itemize) can be chosen by colmax and type variables.

%SCRIPT
var colmax = 4; //maximal number of columns
var type = 0; //0 for enumerate, 1 for itemize
var lt, c, d, n, out;
var txt = cursor.selectedText();
if (type == 0) lt = 'enumerate';
else lt = 'itemize';
function srch(re, str) {
       if (str.search(re) != -1)
          return 1;
       else
          return 0;}
var itarr = [srch(/enumerate/g, txt), srch(/itemize/g, txt), srch(/item/g, txt)]
var sum = itarr.reduce(add, 0);
function add(a, b) {return a + b;}
if (sum == 2)
    c = 2, d = 2;
    else if (sum == 1)
        c = 1, d = 0;   
    else {
        c = 0, d = 0;
        txt=txt.replace(/\n/g, '\n\\item ');}
txt.replace('\t','');
n = txt.split('\n').length-d;
for (n; n>colmax; n = 0.5*n);
n = Math.round(n);
cursor.removeSelectedText();
var p = ['\\begin{'+lt+'}\n', '\\begin{multicols}{'+n+'}\n', '\\item ', txt, '\n\\end{multicols}', '\n\\end{'+lt+'}'];
if (c == 2) out = [p[1], p[3], p[4]];
else if (c == 1) out = [p[0], p[1], p[3], p[4], p[5]];
else out = p;
editor.write(out.join(''));
  • Welcome to TeX.SX! It seems like your answer uses code from another language besides LaTeX - could you indicate what it is and what part of the LaTeX code it produces? – Jānis Lazovskis Jun 17 '16 at 18:30
  • It's written on javascript, i've edited my post. Latex examples inserted at the top. Is it ok? – Kll Yakovlev Jun 17 '16 at 20:39
  • Yes, looks good (I wasn't aware TeXstudio could read JavaScript macros! But now I know). However, it seems your answer has the same problem as Peter's, namely distributing everything across 3 columns, whereas OP wanted to fill out one column before starting the next. – Jānis Lazovskis Jun 17 '16 at 21:41

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.