在多列中平衡表的环境
我想要一个可以在多列环境中平衡表格的环境。
我的意思是,我希望拥有可能很长的表格状数据,这些数据会自动分成另一列,行数大致相等。
像这样,在第 3 行之后自动拆分,将 2 列表格拆分为 2 列多列(艺术家的演绎)
lipsum lipsum lipsum lipsum lipsum
row1 col2 row4 col2
row2 col2 row5 col2
row3 col2
lipsum lipsum lipsum lipsum lipsum
此外,我正在寻求使用xparse
和来multicol
执行此操作,以便将要通过自定义环境使用的列数传递给多列。
此外,我还在寻求使用书籍类别和showframe
包。
我尝试过两种解决方案:
解决方案A,长桌
这个答案产生了正确的输出,但是当我将其包装在环境中时却没有:
我尝试了两种解决方法:
解决方案 A,修复 1:将\vbox{
and替换}
为\bgroup
and\egroup
第一次尝试导致列未对齐,并出现以下错误:
- 未定义控制序列。\begin{myenvironment}
- 包 longtable 错误:longtable 不是处于 1 列模式。
- 未定义控制序列。\end{myenvironment}
- 未对齐的列
@numberne
出现在列中
\documentclass[]{book}
\usepackage{showframe}
\usepackage[]{geometry}
\usepackage{longtable}
\usepackage{multicol}
\usepackage{xparse}
\newsavebox\ltmcbox
\def\shortlipsum{\par Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut purus elit, vestibulum ut, placerat ac, adipiscing vitae, felis.\par}
\newcounter{entryno}
\setcounter{entryno}{1}
\def\tabline{Test & \the\value{entryno} & Description\addtocounter{entryno}{1}\\}
\def\tablines{\tabline\tabline\tabline\tabline\tabline}
\NewDocumentEnvironment{myenvironment}{O{2}}
{
\begin{multicols}{#1}
\setbox\ltmcbox\vbox\bgroup
\makeatletter\col@number\@ne
\begin{longtable}{|l|l|l|}
}
{
\makeatletter\col@number\@ne
\end{longtable}
\unskip
\unpenalty
\unpenalty
\egroup\unvbox\ltmcbox
\end{multicols}
}
\begin{document}
This works great!
\shortlipsum
\begin{multicols}{2}
\shortlipsum
\medskip
\setbox\ltmcbox\vbox{
\makeatletter\col@number\@ne
\begin{longtable}{|l|l|l|}
\tablines\tablines\tablines\tablines\tablines\tablines
\end{longtable}
\unskip
\unpenalty
\unpenalty
}
\unvbox\ltmcbox
\medskip
\shortlipsum
\end{multicols}
\shortlipsum
\par
This does not work!
\begin{myenvironment}
\tablines\tablines\tablines\tablines\tablines\tablines
\end{myenvironment}
\shortlipsum
\end{document}
解决方案 A,修复 2:将\vbox{
and替换}
为\begingroup
and\endgroup
第二次尝试导致第一次尝试之后的输出丢失,\shortlipsum
并且:
- 缺少 { 插入。\begin{myenvironment}
- 未定义控制序列。\begin{myenvironment}
- 包 longtable 错误:longtable 不是处于 1 列模式。
- 未定义控制序列。\end{myenvironment}
- 缺少} 插入。\end{myenvironment}
\documentclass[]{book}
\usepackage{showframe}
\usepackage[]{geometry}
\usepackage{longtable}
\usepackage{multicol}
\usepackage{xparse}
\newsavebox\ltmcbox
\def\shortlipsum{\par Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut purus elit, vestibulum ut, placerat ac, adipiscing vitae, felis.\par}
\newcounter{entryno}
\setcounter{entryno}{1}
\def\tabline{Test & \the\value{entryno} & Description\addtocounter{entryno}{1}\\}
\def\tablines{\tabline\tabline\tabline\tabline\tabline}
\NewDocumentEnvironment{myenvironment}{O{2}}
{
\begin{multicols}{#1}
\setbox\ltmcbox\vbox\begingroup
\makeatletter\col@number\@ne
\begin{longtable}{|l|l|l|}
}
{
\makeatletter\col@number\@ne
\end{longtable}
\unskip
\unpenalty
\unpenalty
\endgroup\unvbox\ltmcbox
\end{multicols}
}
\begin{document}
This works great!
\shortlipsum
\begin{multicols}{2}
\shortlipsum
\medskip
\setbox\ltmcbox\vbox{
\makeatletter\col@number\@ne
\begin{longtable}{|l|l|l|}
\tablines\tablines\tablines\tablines\tablines\tablines
\end{longtable}
\unskip
\unpenalty
\unpenalty
}
\unvbox\ltmcbox
\medskip
\shortlipsum
\end{multicols}
\shortlipsum
\par
This does not work!
\begin{myenvironment}
\tablines\tablines\tablines\tablines\tablines\tablines
\end{myenvironment}
\shortlipsum
\end{document}
解决方案 B,带 savebox 的伪嵌套 longtable
这个答案也产生了我想要的结果,但我无法使其与文本一致。
我试过了:
解决方案 B,修复 1:将命令包装在环境中并删除表,效果很好!
然而...
一切正常,直到我添加showframe
包并得到以下结果:
- 缺少}插入。\begin{myenvironment}3
- 额外的 },或者被遗忘的 \endgroup{myenvironment}
- 长桌下增加了空间
\documentclass[]{book}
%\usepackage{showframe}
\usepackage{longtable}
\usepackage{multicol}
\usepackage{lipsum}
\usepackage{capt-of}
\usepackage{xparse}
\def\shortlipsum{\par Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut purus elit, vestibulum ut, placerat ac, adipiscing vitae, felis.\par}
\newcounter{entryno}
\setcounter{entryno}{1}
\def\tabline{Test & \the\value{entryno} & Description\addtocounter{entryno}{1}\\}
\def\tablines{\tabline\tabline\tabline\tabline\tabline}
\makeatletter
\newsavebox\ltmcbox
\newsavebox\xxbox
\newenvironment{multicolslongtable}[1]{
\setbox\ltmcbox\vbox\bgroup
\col@number\@ne
\begin{longtable}{#1}
}
{
\end{longtable}
\unskip
\unpenalty
\unpenalty\egroup
\unvbox\ltmcbox
}
\makeatother
\NewDocumentEnvironment{myenvironment}{O{2}}
{
\savebox\xxbox\bgroup
\begin{minipage}{\textwidth}
\begin{multicols}{#1}
\begin{multicolslongtable}{| l | l | l |}
}
{
\end{multicolslongtable}
\end{multicols}
\end{minipage}
\egroup
\begin{multicols}{#1}
\usebox\xxbox
\end{multicols}
}
\begin{document}
\shortlipsum
\begin{myenvironment}[2]
\tablines\tablines\tablines\tablines\tablines\tablines
\end{myenvironment}
\shortlipsum
\end{document}
答案1
解决方法是使用包showframe
中的选项geometry
而不是showframe
包中的选项。
谢谢阿博阿马尔!
下面的代码展示了一个使用多列(带有 showframe)中的长表平衡表格数据的环境,通过结合以下答案xparse
和轻微重构:
% environment to balance a table in a multicol
\documentclass[]{book}
\usepackage[showframe]{geometry}
\usepackage{longtable}
\usepackage{multicol}
\usepackage{lipsum}
\usepackage{xparse}
% helpers for the test
\def\shortlipsum{\par Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut purus elit, vestibulum ut, placerat ac, adipiscing vitae, felis.\par}
\newcounter{entryno}
\setcounter{entryno}{1}
\def\tabline{Test & \the\value{entryno} & Description\addtocounter{entryno}{1}\\}
\def\tablines{\tabline\tabline\tabline\tabline\tabline\tabline\tabline\tabline\tabline}
% box for a multi column long table
% SEE https://tex.stackexchange.com/questions/161827/balanced-longtables-multicol-and-page-breaks
\makeatletter
\newsavebox\ltmcbox
\newsavebox\xxbox
\newenvironment{multicolslongtable}[1]{
\setbox\ltmcbox\vbox\bgroup
\col@number\@ne
\begin{longtable}{#1}
}
{
\end{longtable}
\unskip
\unpenalty
\unpenalty\egroup
\unvbox\ltmcbox
}
\makeatother
% environment to accept table input and produce multicol
\NewDocumentEnvironment{myenvironment}{O{2}}
{
\savebox\xxbox\bgroup
\begin{minipage}{\textwidth}
\begin{multicols}{#1}
\begin{multicolslongtable}{| l | l | l |}
}
{
\end{multicolslongtable}
\end{multicols}
\end{minipage}
\egroup
\begin{multicols}{#1}
\centering
\usebox\xxbox
\end{multicols}
}
% patch multicols to allow for one column
% SEE https://tex.stackexchange.com/questions/233866/one-column-multicol-environment
\let\multicolmulticols\multicols
\let\endmulticolmulticols\endmulticols
\RenewDocumentEnvironment{multicols}{mO{}}
{%
\ifnum#1=1
#2%
\else % More than 1 column
\multicolmulticols{#1}[#2]
\fi
}
{%
\ifnum#1=1
\else % More than 1 column
\endmulticolmulticols
\fi
}
\begin{document}
\section{one column}
\shortlipsum
\begin{myenvironment}[1]
\tablines
\end{myenvironment}
\shortlipsum
\section{two column}
\shortlipsum
\begin{myenvironment}
\tablines
\end{myenvironment}
\shortlipsum
\section{three column}
\shortlipsum
\begin{myenvironment}[3]
\tablines
\end{myenvironment}
\shortlipsum
\end{document}