1

Suppose as part of my text I want to have a list of words or short phrases, where they have no relative order, and are short enough so that several may fit on the same line (but not all combinations would fit the same number of columns). I would like to have them laid out in a grid-like fashion, with either the last line or the last column possibly missing some phrases. I might put this in a frame or inline. Now,

  • I don't want to decide myself on the number of rows and columns, since I don't care (that is: the implemented command does not take a number of rows nor of columns, just the list); plus,
  • The more LaTeX wants to squeeze space, I want it to be able to squeeze the horizontal space between the columns to possibly fit another one in there.

Note that I say "list" but I don't mean an itemize list.

  • 1
    It would be great if you could provide a graphical example (picture) of what you want. – TeXnician Feb 17 '17 at 16:43
  • 1
    Is the 2nd list element the 2nd column of the 1st row, or the 2nd row of the 1st column? Is it OK to ask the user to specify the total number of columns? – Steven B. Segletes Feb 17 '17 at 16:43
  • @StevenB.Segletes: (1) Doesn't matter, whichever you like better. (2) No. – einpoklum Feb 17 '17 at 16:59
2

If you permit the user to specify the number of columns, here is a way:

\layout[<columns (default 3)>]{<csv list>}

If columns must be auto-counted, please see ADDENDUM at the end of this answer.

The MWE:

\documentclass{article}
\usepackage{listofitems,fp}
\makeatletter
\newcommand\layout[2][3]{%
  \par\noindent%
  \edef\tmp{\strip@pt\textwidth}%
  \FPdiv\result{\tmp}{#1}%
  \readlist*\mylist{#2}%
  \foreachitem\x\in\mylist{\makebox[\result pt][l]{\x}\allowbreak}%
}
\makeatother
\begin{document}
Here with 3 columns:
\layout[3]{this, is my, list, of, items, in, my, extended, list, of, words}

Here with 5 columns:
\layout[5]{this, is my, list, of, items, in, my, extended, list, of, words}
\end{document}

enter image description here

ADDENDUM (Automates the column count)

This achieves margin centering only by way of centering the box contents, rather than left aligning them. I prefer left alignment, but centering wrt margin seemed important to the OP.

The method to autoestimate the column count is to first find the maximum width entry (padded with a space on each side) and store in \maxwd. Perform a division of \textwidth by \maxwd to get a [real number] of columns that would fit on a line. Remove the fractional part of that real number to reveal the number of integer columns that will comfortably fit on a line. Divide the \textwidth by this integer, to obtain the column width. Place each item in a \makebox of this size, ending with an \allowbreak.

\documentclass{article}
\usepackage{listofitems,lipsum,FP}
\makeatletter
\newcommand\layout[1]{%
  \par\noindent%
  \readlist*\mylist{#1}%
  \def\maxwd{0pt}%
  \foreachitem\x\in\mylist{%
    \setbox0=\hbox{~\x~}%
    \ifdim\wd0>\maxwd\relax\edef\maxwd{\the\wd0}\fi%
  }%
  \edef\tmpA{\strip@pt\textwidth}%
  \edef\tmpB{\strip@pt\dimexpr\maxwd\relax}%
  \FPdiv\result{\tmpA}{\tmpB}%
  \edef\tmpC{\expandafter\makeint\result\relax}%
  \FPdiv\result{\tmpA}{\tmpC}%
  \foreachitem\x\in\mylist{%
%    \fboxsep=-\fboxrule\relax\fbox{\strut% <--COMMENT HERE
      \makebox[\result pt]{\x}%
%    }% <--COMMENT HERE
  \allowbreak}%
}
\makeatother
\def\makeint#1.#2\relax{#1}
\parskip 1em
\begin{document}
\lipsum[1]

\layout{this, is my, list, of, items, in, my, extended, list, of, words}

\layout{this, is my, list, of, items, in, my, extended, list, of, words,
including really, big ones}

\layout{this, is my, list, of, items, in, my, extended, list, of, words,
including really big ones}
\end{document}

enter image description here

To demonstate the actual box alignment, uncomment the two lines of source code, to see it really is margin aligned:

enter image description here

To recover left-alignment in the columns, simply replace the [c] alignemnt with [l] in the \makebox.

  • Well, (1) the user must specifically not have to specify the number of columns and (2) I'd want at least as much spacing from the margins to the first and last columns. But this is a start - so +1. – einpoklum Feb 17 '17 at 16:59
  • @einpoklum Part (2) becomes an issue because of the left-alignment used in the columns. It can be addressed by using [c] rather than [l] alignment for my \makebox, but of course that means the columns are no longer left-aligned. So, is center-alignment OK? – Steven B. Segletes Feb 17 '17 at 17:22
  • @einpoklum Please see my addendum – Steven B. Segletes Feb 17 '17 at 17:48
0

enter image description here

\documentclass{article}
\addtolength\oddsidemargin{-3cm}

\makeatletter
\def\zz#1{%
\setbox0\vbox{%
\global\setbox1\box\voidb@x
\halign{##\hfill\cr#1\crcr}%
\loop
\unskip\unskip
\setbox0\lastbox
\global\setbox1\hbox{\ifvoid1 \else\unhbox1\ \fi\box0}%
\ifnum\lastnodetype>-1
\repeat
}%
\begin{flushleft}\unhbox1\end{flushleft}}



\begin{document}

\def\test{\zz{%
one two three\cr
Suppose as part of my text\cr
no relative order\cr
I might put this in a frame\cr
spacing\cr
lists\cr
multicolumn\cr
automation\cr
Lay out a list\cr
very short phrases\cr
automatically-varying\cr
number of columns\cr
Can you help?\cr
\TeX\ - \LaTeX\cr
 Stack Exchange\cr
everyone sharing\cr
knowledge\cr
If you're able\cr
answer this question\cr
please do!\cr
Your Answer\cr
}}


\test

{\hsize.3\hsize \test}

{\hsize1.5\hsize \test}

\end{document}

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.