在多列中平衡表的环境

在多列中平衡表的环境

在多列中平衡表的环境

我想要一个可以在多列环境中平衡表格的环境。

我的意思是,我希望拥有可能很长的表格状数据,这些数据会自动分成另一列,行数大致相等。

像这样,在第 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,长桌

这个答案产生了正确的输出,但是当我将其包装在环境中时却没有:

在 LaTeX 中平衡多列内的长表

我尝试了两种解决方法:

解决方案 A,修复 1:将\vbox{and替换}\bgroupand\egroup

第一次尝试导致列未对齐,并出现以下错误:

  • 未定义控制序列。\begin{myenvironment}
  • 包 longtable 错误:longtable 不是处于 1 列模式。
  • 未定义控制序列。\end{myenvironment}
  • 未对齐的列
  • @numberne出现在列中

解决方案 1,尝试 1

\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替换}\begingroupand\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}

相关内容