假设作为文本的一部分,我想要一个单词或短语列表,其中没有相对顺序,并且足够短,以便几个可以放在同一行上(但并非所有组合都适合相同数量的列)。我希望以网格方式布局它们,最后一行或最后一列可能缺少一些短语。我可能会将其放在框架中或内联中。现在,
- 我不想自己决定行数和列数,因为我不在乎(也就是说:实现的命令不需要行数和列数,只需要列表);另外,
- LaTeX 越想压缩空间,我希望它能够压缩水平的列与列之间留出空间,以便可以容纳另一个列。
请注意,我说的是“列表”,但我不是指itemize
列表。
答案1
如果允许用户指定列数,可以使用以下方法:
\layout[<columns (default 3)>]{<csv list>}
如果必须自动计算列数,请参阅附录在这个答案的最后。
妇女权利委员会:
\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}
附录(自动进行列计数)
这仅通过将框内容居中而不是左对齐来实现边距居中。我更喜欢左对齐,但对于 OP 来说,相对于边距的居中似乎很重要。
自动估计列数的方法是先找到最大宽度条目(两边用空格填充)并存储在 中\maxwd
。对 进行除法\textwidth
,\maxwd
得到一行中可以容纳的 [实数] 列数。删除该实数的小数部分,得到一行中可以容纳的整数列数。用\textwidth
这个整数除以 ,得到列宽。将每个项目放在\makebox
这个大小的 中,以 结尾\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}
为了演示实际的框对齐,取消注释两行源代码,以查看它确实是边距对齐的:
要恢复列中的左对齐,只需将 中的[c]
对齐替换为即可。[l]
\makebox
答案2
\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}