5

I am currently working with nested enumerate environments in which the second level is typeset using a multicols, as follows :

\documentclass[12pt, letterpaper]{article}

\usepackage{amsmath}
\usepackage{amsfonts}
\RequirePackage{amssymb}

\usepackage[T1]{fontenc}
\usepackage[french]{babel}

\usepackage{comment}
\usepackage{enumitem}
\usepackage{lmodern}
\usepackage{multicol}
\usepackage[usenames, dvipsnames, svgnames, table]{xcolor}

\begin{document}

\setlength{\columnsep}{2em}
\setlength{\columnseprule}{0pt}
\begin{enumerate}
  \item \begin{multicols}{5}
          \raggedcolumns
          \begin{enumerate}
            \item $0$
            \item $0$
            \item $-1$
            \item $-\infty $
            \item $\infty $
            \item $1$
            \item $2$
            \item $2$
            \item $1$
            \item $1$
            \item $2$
            \item $1$
            \item $0$
            \item $\textcolor {red}\nexists $
            \item $1$
            \item $\textcolor {red}\nexists $
          \end{enumerate}
        \end{multicols}
\end{enumerate}

\end{document}

Although the columns are created properly, the last column remains empty. Frank's balancing algorithm seems to provide a 4+4+4+4+0 balancing solution for this five (5) column layout. I would like the layout to use all five columns, given that there are more than a total of five items.

My questions are:

  1. Is this really due to multicols' balancing algorithm, or is it something specific in or missing from my code?
  2. Main question : is there a way to balance the layout using ALL available columns, for example 4+3+3+3+3, that does not require the use of \columnbreak?
  3. I tried using \usepackage[balancingshow]{multicol} to see what was happening with the balancing algorithm, but the tracing output is only showing badness for columns 1-4. Is this normal?

Note that if you comment the last \item, the balancing solution is 3+3+3+3+3, which uses all five (5) columns.

My motivation for wanting this is that I'm creating a very personalized question/answer-type package for my colleagues and the answers should be typeset using the "least possible amount of space". The presentation does not seem very optimal/natural when the last column remains empty.

I am aware that multicols' balancing algorithm cannot be optimal for all given situations and that it does a very good job in most cases, along with the fact that the package was created to typeset text.

2

Here is a solution with theshortlst package and a small patch in order to be able to choose the number of columns. It requires using shortlst, of course, setspace to adjust interlining and xkeyval. As shortlst in not in TeXLive nor MiKTeX (due to problems with its license, as far I know), you'll have to download from CTAN and install it in your local texmf directory.

\documentclass[12pt, letterpaper]{article}
\usepackage[utf8]{inputenc} 
\usepackage[T1]{fontenc} 

\usepackage{amsmath,amsfonts,amssymb}
\usepackage{lmodern}
\usepackage[dvipsnames,svgnames,table]{xcolor}

\usepackage{shortlst,setspace,xkeyval}%
\makeatletter
\newcounter{ncol}
\define@key{lex}{nc}[5]{\setcounter{ncol}{#1}}%% 5 columns by default
\define@key{lex}{il}[1.5]{\def\@intln{#1}}% interlining![enter image description here][1]
\newenvironment{shortanswers}[1][]{%
\setkeys{lex}{nc,il,#1}
\settowidth{\labelwidth}{\mbox{(m)}}
\setlength{\leftmargini}{\dimexpr\labelwidth+\labelsep\relax}%[1][3]
\setlength{\shortitemwidth}{\dimexpr\textwidth/\value{ncol}-\labelwidth-2\labelsep\relax}%
\renewcommand{\labelenumi}{\ensuremath{(\alph{enumi})}}
`\setstretch{\@intln}
\begin{shortenumerate}}%
{\end{shortenumerate}
 }%
\makeatother

\begin{document}

\begin{enumerate}
\item%
      \begin{shortanswers}
        \item $ 0 $
        \item $ 0 $
        \item $ -1 $
        \item $-\infty $
        \item $\infty $
        \item $1$
        \item $2$
        \item $2$
        \item $1$
        \item $1$
        \item $2$
        \item $1$
        \item $0$
        \item $\textcolor {red}\nexists $
        \item $1$
        \item $\textcolor {red}\nexists $
      \end{shortanswers}
\end{enumerate}

\end{document}

which results in:

enter image description here

  • Interesting solution! I've used shortlst before, but I ended up switching to a combination of enumitem and multicols for two reasons: 1. I found shortlst not to be easily customizable with regards to spacing, columns, etc. I see you've countered this by "patching" its functionalities, which brings me to the second point. 2. For the moment, I'm not sure the use of shortlst is a good choice on the long run, especially given that my entire team is using MiKTeK. I'd much prefer using "standard" packages that won't disappear or require "patches/hacks" every now and then. – feculededentier Feb 5 '14 at 13:57
  • @feculededentier: For me the main point is that it works as I want. It's the only package, along with tablists(version 0.0e!) that has these functionalities: putting items in columns while retaining a simple list-like synta. Multienum can do a similar formatting, but with a tabular-like syntax. And it 's the only one that uses 2 (or more) columns for an item automatically. Unfortunately I am not sufficiently aware of the internals of (La)TeX to make a valuable successor to this package that would incorporate my patches… – Bernard Feb 5 '14 at 14:17
2

edited (2017): no more use of xintfrac as computations can be done with \numexpr. Only need to load xinttools.


My two cents guess about the situation creating this stress to multicol is that it arises when you want D columns, have N items (which will occupy the same vertical space, imagine short words to simplify), when N\leq ceil(N/D)*(D-1).

For example N=16, D=5 gives 4*4=16. Bad. D=7 gives 3*6=18. Bad. D=4 gives 4*3=12 good, D=6 gives 3*5=15 good, D=3 gives 6*2=12 good.

\input xinttools.sty % \xintApply, \xintListWithSep, \»intSeq
\def\GoodDivisions #1{For #1: 
    \xintListWithSep{, }{\xintApply{\TestGoodness {#1}}{\xintSeq {1}{#1}}}}

\def\Ceil #1#2{\numexpr(#1+#2/2-1)/#2\relax}

\catcode`@ 11
\long\def\@firstoftwo#1#2{#1}
\long\def\@secondoftwo#1#2{#2}

\def\TestGoodness #1#2{#2 is
                       \ifnum #1>\numexpr\Ceil{#1}{#2}*(#2-1)\relax
                       \expandafter\@firstoftwo
                       \else
                       \expandafter\@secondoftwo
                       \fi
                       {Good}{Bad}}
\catcode`@ 12

\GoodDivisions {16}

\GoodDivisions {20}

\GoodDivisions {32}

\GoodDivisions {23}

\nopagenumbers

\bye

These predictions are untested! (works for 16 and 20 items at least.

gooddivisions

Here is now a table giving for each number of items up to 60 the compatible choices for a multicol with D columns.

table of good divisions

\documentclass[a4paper]{article}
\usepackage[vscale=0.9]{geometry}
\usepackage{color}

\usepackage{xinttools}

\newcommand*\TestColumns[1]{%
  \xintListWithSep{&}{\xintApply{\TestGoodness {#1}}{123456789{10}}}%
}

\makeatletter
\newcommand*\TestGoodness[2]{%
  \ifnum #1>\numexpr\Ceil{#1}{#2}*(#2-1)\relax
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi G{\textcolor{red}{B}}%
}
\makeatother

\newcommand*\Ceil[2]{\numexpr(#1+#2/2-1)/#2\relax}

\begin{document}\thispagestyle{empty}

\begin{tabular}{c*{10}c}
  &1&2&3&4&5&6&7&8&9&10\\
\hline
\xintFor* #1 in {\xintSeq {1}{60}}
            \do {#1&\TestColumns {#1}\\}
\hline
\end{tabular}

\end{document}
  • my predictions for 20 items seem validated! the 9 columns case is interesting, multicol does then only 7 columns, 20=6x3+2. – user4686 Feb 4 '14 at 19:04
  • so far everything I have tested (N=16, N=19, N=20, N=48, N=49 etc..) is compatible with the predictions from the table... – user4686 Feb 4 '14 at 19:51
  • Interesting analysis! I'd be intrigued to know whether this analysis is accurate, because it implies that the solution in which every column has the same amount of equally sized elements, except for the first column which contains an extra element is always bad. Even for displaying text, I don't see how this output is "bad" or undesirable. – feculededentier Feb 5 '14 at 13:44
  • @feculededentier the first case is with 4 lines we want to have over 3 columns:\documentclass{article} \usepackage{multicol} \begin{document} \begin{multicols}{3} first line\newline second line\newline third line\newline fourth line \end{multicols} \end{document} multicol understandably excludes doing 1+1+2 but does not seem to consider making 2+1+1, and ends up doing 2+2, thus leaving an empty third column. – user4686 Feb 5 '14 at 14:10
  • @feculededentier from the table above using 3 columns is safe if the text ends up on at least 5 lines, and using 4 columns is safe for text ending up on at least 10 lines, and using 5 columns for text ending up on at least 17 lines. Naturally, regular text might have enough stretch to move a word to an additional line and thus the stress on multicols is more easily seen when doing things like in your post, with one-liners, rather than full paragraphs allowing reflowing of text. – user4686 Feb 5 '14 at 14:15

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.