在使用 ltablex 包和嵌套 tabularx 环境时如何防止格式不良?

在使用 ltablex 包和嵌套 tabularx 环境时如何防止格式不良?

我正在准备一个长表格(> 1 页,因此我使用包longtable),设置为占据整个页面的 \textwidth。我的目标是制作信纸和 A4 大小的文档版本,但由于这些标准的大小不同,因此每个文档中的表格宽度都不同。

我希望将来能将表格扩展一些,并且我希望避免在 letter 和 A4 格式之间来回切换时手动调整相关长度参数。因此,我使用包tabularx和(对于最右边的列)X它提供的列类型,以便扩展表格的宽度。为了同时使用longtable和的功能,tabularx我使用了ltablex为此目的而设计的包。

除此之外,表格环境每行最右边的单元格包含另一个表。这个内部表同样有一列类型X。该ltablex包重新定义了tabularx环境,其结果是尝试将一个tabularx环境嵌套在另一个环境中会产生错误:

! Extra alignment tab has been changed to \cr. <template> \endtemplate

在一个相关问题的答案大卫·卡莱尔 (David Carlisle) 给出了解决该问题的方法,定义了一个restoretx恢复嵌套环境能力的命令tabularx

例如,这允许创建嵌套表,以便例如这个 mwe 编译并产生预期的结果:

\documentclass{article}
\usepackage{blindtext}
\usepackage{booktabs}
\usepackage{longtable}
\usepackage{tabularx}

%This block is from David Carlisle's code in the linked question
\makeatletter
\let\tx@\TX@endtabularx
\def\restoretx{\let\TX@endtabularx\tx@}
\makeatother

\usepackage{ltablex}

\newcommand{\innerTable}[2]{
    {
        \restoretx
        \begin{tabularx}{\linewidth}{cX}
        #1 & #2 \\
        \end{tabularx}
    }
}

\setlength{\parindent}{0cm}

\begin{document}
\begin{tabularx}{\linewidth}{cX}
    test & \innerTable{test2}{\blindtext[1]} \\
    test & \innerTable{test2}{\blindtext[1]} \\
      [...about 40 copies of this row in total...]
    test & \innerTable{test2}{\blindtext[1]} \\
    test & \innerTable{test2}{\blindtext[1]} \\
\end{tabularx}
\end{document}

典型页面: 在此处输入图片描述

上面例子中的行数并非偶然:如果我们添加少量行的额外副本,test & \innerTable{test2}{\blindtext[1]} \\那么文件仍会编译,但格式会严重破坏。在这种情况下,典型的页面现在看起来像 在此处输入图片描述 更糟糕的是,这种行为在运行过程中不一致:有时包含 40 行副本的文件可以正确编译,有时则不能。

查阅日志文件显示以下警告:

Package tabularx Warning: X Columns too narrow (table too wide) (tabularx) on input line 79.

我知道该tabularx包(可能是该ltablex包)会尝试通过某些迭代过程为每列计算X适当的宽度,所以我认为这个警告意味着该包放弃了尝试寻找合适的宽度。

有没有办法迫使ltablex人们更加努力地寻找X列的合适宽度,尽管要付出时间/内存的代价?(我实际使用的表比上面的长得多,大约有 170 行。)或者是否有另一种解决方法,仍然使用xtabular带有列的嵌套环境X?如果这无望(或者即使不是),可以使用哪些其他方法来达到相同的目的?

一些可能的解决方案——以及我最初拒绝它们的原因——我可能不得不接受它们:

  • 另一个包ltxtable也结合了longtabletabularx,其行为与 略有不同ltablex。但是(无论是安装还是使用)这个包似乎都很特殊,包括默认情况下表代码需要放在单独的文件中,我希望尽可能避免这种情况。(我希望可以通过使用另一个包来规避这个特殊的限制。) 编辑我尝试这样做,但编译完全失败,并报告内存问题:! TeX capacity exceeded, sorry [text input levels=15].

  • 也许我可以只测量和硬编码两种页面大小的相关长度,然后编写一个开关来检查页面大小以确定使用哪种大小——但这很笨拙,需要实际测量列大小(这是可行的, 尽管)。

这个问题顺便说一下,是相似的,但是 OP 的目的显然与我的有所不同,因为对此接受的答案(顺便说一下,也是由 David Carlisle 提出的)使用手动定义宽度的列,这正是我想要避免的。

编辑发布的答案建议使用xltabular包而不是包ltablex。这个包的优点很明显,就是不需要像\restoretx上面的 mwe 中那样定义命令,但使用包并不能解决问题。事实上,它产生的输出格式基本上以同样的方式被破坏:

在此处输入图片描述

答案1

编辑。tabularx包不适合用作其他表格中的嵌套表。一些测试表明,它可以嵌套多达 45 次,然后X列宽的计算(在每个嵌套中)tabularx不再起作用。

这是否可以解决是软件包作者要回答的问题。

同时可以通过两种方式来避免这种限制:

  • 主表限制为 45 个嵌套tabularx表,然后重复主表(这似乎不是 OP 的选项)
  • 而是tabularx使用tabular*并手动预先定义嵌套表中每列的宽度(这可能需要在检查第一次编译的结果后重新定义列宽之间的比率)

在这两种情况下,我都会改用ltablex(它abularx在很多方面重新定义,其中之一是,默认情况下,它会将X列转换l为小表的列)xltabular。对于第二种情况,解决方案可以是:

\documentclass{article}
\usepackage{lipsum}
\usepackage{booktabs, xltabular}

\newcommand{\innerTable}[2]%
{
\begin{tabular*}{\linewidth}{@{} >{\centering}p{\dimexpr0.12\linewidth-\tabcolsep}
             p{\dimexpr0.88\linewidth-\tabcolsep} @{}}
                #1 & #2    
 \end{tabular*}}

\setlength{\parindent}{0cm}
%---------------- show page layout. don't use in a real document!
\usepackage{showframe}
\renewcommand\ShowFrameLinethickness{0.15pt}
\renewcommand*\ShowFrameColor{\color{red}}
%---------------------------------------------------------------%

\begin{document}
\setlength\tabcolsep{4pt}
\begin{xltabular}{\linewidth}{@{} cX @{}}
    test & \innerTable{test 1}{\lipsum*[1]}  \\  \addlinespace
    test & \innerTable{test 2}{\lipsum*[2]}  \\  \addlinespace
    test & \innerTable{test 3}{\lipsum*[3]}  \\  \addlinespace
    test & \innerTable{test 4}{\lipsum*[4]}  \\  \addlinespace
    test & \innerTable{test 5}{\lipsum*[5]}  \\  \addlinespace
    
    test & \innerTable{test 6}{\lipsum*[6]}  \\  \addlinespace 
    test & \innerTable{test 7}{\lipsum*[7]}  \\  \addlinespace
    test & \innerTable{test 8}{\lipsum*[8]}  \\  \addlinespace
    test & \innerTable{test 9}{\lipsum*[9]}  \\  \addlinespace
    test & \innerTable{test 10}{\lipsum*[10]} \\  \addlinespace
    
    test & \innerTable{test 11}{\lipsum*[11]} \\  \addlinespace
    test & \innerTable{test 12}{\lipsum*[12]} \\  \addlinespace
    test & \innerTable{test 13}{\lipsum*[13]} \\  \addlinespace
    test & \innerTable{test 14}{\lipsum*[14]} \\  \addlinespace
    test & \innerTable{test 15}{\lipsum*[15]} \\  \addlinespace
    
    test & \innerTable{test 16}{\lipsum*[16]} \\  \addlinespace
    test & \innerTable{test 17}{\lipsum*[17]} \\  \addlinespace
    test & \innerTable{test 18}{\lipsum*[18]} \\  \addlinespace
    test & \innerTable{test 19}{\lipsum*[19]} \\  \addlinespace
    test & \innerTable{test 20}{\lipsum*[20]} \\  \addlinespace
    
    test & \innerTable{test 21}{\lipsum*[21]} \\  \addlinespace
    test & \innerTable{test 22}{\lipsum*[22]} \\  \addlinespace
    test & \innerTable{test 23}{\lipsum*[23]} \\  \addlinespace
    test & \innerTable{test 24}{\lipsum*[24]} \\  \addlinespace
    test & \innerTable{test 25}{\lipsum*[25]} \\  \addlinespace
    
    test & \innerTable{test 26}{\lipsum*[26]} \\  \addlinespace
    test & \innerTable{test 27}{\lipsum*[27]} \\  \addlinespace
    test & \innerTable{test 28}{\lipsum*[28]} \\  \addlinespace
    test & \innerTable{test 29}{\lipsum*[29]} \\  \addlinespace
    test & \innerTable{test 30}{\lipsum*[30]} \\  \addlinespace

    test & \innerTable{test 31}{\lipsum*[31]} \\  \addlinespace
    test & \innerTable{test 32}{\lipsum*[32]}  \\  \addlinespace
    test & \innerTable{test 33}{\lipsum*[33]}  \\  \addlinespace
    test & \innerTable{test 34}{\lipsum*[34]}  \\  \addlinespace
    test & \innerTable{test 35}{\lipsum*[35]}  \\  \addlinespace
    
    test & \innerTable{test 36}{\lipsum*[36]}  \\  \addlinespace
    test & \innerTable{test 37}{\lipsum*[37]}  \\  \addlinespace
    test & \innerTable{test 38}{\lipsum*[38]}  \\  \addlinespace
    test & \innerTable{test 39}{\lipsum*[39]}  \\  \addlinespace
    test & \innerTable{test 40}{\lipsum*[40]}  \\  \addlinespace
    
    test & \innerTable{test 41}{\lipsum*[41]}  \\  \addlinespace
    test & \innerTable{test 42}{\lipsum*[42]}  \\  \addlinespace
    test & \innerTable{test 43}{\lipsum*[43]}  \\  \addlinespace
    test & \innerTable{test 44}{\lipsum*[44]}  \\  \addlinespace
    test & \innerTable{test 45}{\lipsum*[45]}  \\  \addlinespace

    test & \innerTable{test 46}{\lipsum*[46]}  \\  \addlinespace
    test & \innerTable{test 47}{\lipsum*[47]}  \\  \addlinespace
    test & \innerTable{test 48}{\lipsum*[48]}  \\  \addlinespace
    test & \innerTable{test 49}{\lipsum*[49]}  \\  \addlinespace
    test & \innerTable{test 50}{\lipsum*[50]}  \\  \addlinespace

    test & \innerTable{test 51}{\lipsum*[51]}  \\  \addlinespace
    test & \innerTable{test 52}{\lipsum*[52]}  \\  \addlinespace
    test & \innerTable{test 53}{\lipsum*[53]}  \\  \addlinespace
    test & \innerTable{test 54}{\lipsum*[54]}  \\  \addlinespace
    test & \innerTable{test 55}{\lipsum*[55]}  \\  \addlinespace
    
    test & \innerTable{test 56}{\lipsum*[56]}  \\  \addlinespace
    test & \innerTable{test 57}{\lipsum*[57]}  \\  \addlinespace
    test & \innerTable{test 58}{\lipsum*[58]}  \\  \addlinespace
    test & \innerTable{test 59}{\lipsum*[59]}  \\  \addlinespace
    test & \innerTable{test 60}{\lipsum*[60]}  \\  \addlinespace
    
    test & \innerTable{test 61}{\lipsum*[61]}  \\  \addlinespace
    test & \innerTable{test 62}{\lipsum*[62]}  \\  \addlinespace
    test & \innerTable{test 63}{\lipsum*[63]}  \\  \addlinespace
    test & \innerTable{test 64}{\lipsum*[64]}  \\  \addlinespace
    test & \innerTable{test 65}{\lipsum*[65]}  \\  \addlinespace

    test & \innerTable{test 66}{\lipsum*[66]}  \\  \addlinespace
    test & \innerTable{test 67}{\lipsum*[67]}  \\  \addlinespace
    test & \innerTable{test 68}{\lipsum*[68]}  \\  \addlinespace
    test & \innerTable{test 69}{\lipsum*[69]}  \\  \addlinespace
    test & \innerTable{test 70}{\lipsum*[70]}  \\  \addlinespace
    
    test & \innerTable{test 71}{\lipsum*[71]}  \\  \addlinespace
    test & \innerTable{test 72}{\lipsum*[72]}  \\  \addlinespace
    test & \innerTable{test 73}{\lipsum*[73]}  \\  \addlinespace
    test & \innerTable{test 74}{\lipsum*[74]}  \\  \addlinespace
    test & \innerTable{test 75}{\lipsum*[75]}  \\  \addlinespace
    
    test & \innerTable{test 76}{\lipsum*[76]}  \\  \addlinespace
    test & \innerTable{test 77}{\lipsum*[77]}  \\  \addlinespace
    test & \innerTable{test 78}{\lipsum*[78]}  \\  \addlinespace
    test & \innerTable{test 79}{\lipsum*[79]}  \\  \addlinespace
    test & \innerTable{test 80}{\lipsum*[80]}  \\  \addlinespace
    
    test & \innerTable{test 81}{\lipsum*[81]}  \\  \addlinespace
    test & \innerTable{test 82}{\lipsum*[82]}  \\  \addlinespace
    test & \innerTable{test 83}{\lipsum*[83]}  \\  \addlinespace
    test & \innerTable{test 84}{\lipsum*[84]}  \\  \addlinespace
    test & \innerTable{test 85}{\lipsum*[85]}  \\  \addlinespace
    
    test & \innerTable{test 86}{\lipsum*[86]}  \\  \addlinespace
    test & \innerTable{test 87}{\lipsum*[87]}  \\  \addlinespace
    test & \innerTable{test 88}{\lipsum*[88]}  \\  \addlinespace
    test & \innerTable{test 89}{\lipsum*[89]}  \\  \addlinespace
    test & \innerTable{test 80}{\lipsum*[90]}  \\  \addlinespace 
    
    test & \innerTable{test 91}{\lipsum*[1]}  \\  \addlinespace
    test & \innerTable{test 92}{\lipsum*[1]}  \\  \addlinespace
    test & \innerTable{test 93}{\lipsum*[1]}  \\  \addlinespace
    test & \innerTable{test 94}{\lipsum*[1]}  \\  \addlinespace
    test & \innerTable{test 95}{\lipsum*[1]}  \\  \addlinespace

    test & \innerTable{test 96}{\lipsum*[96]}  \\  \addlinespace
    test & \innerTable{test 97}{\lipsum*[97]}  \\  \addlinespace
    test & \innerTable{test 98}{\lipsum*[98]}  \\  \addlinespace
    test & \innerTable{test 99}{\lipsum*[99]}  \\  \addlinespace
    test & \innerTable{test 100}{\lipsum*[100]}%\\  \addlinespace

    test & \innerTable{test 101}{\lipsum*[101]}  \\  \addlinespace
    test & \innerTable{test 102}{\lipsum*[102]}  \\  \addlinespace
    test & \innerTable{test 103}{\lipsum*[103]}  \\  \addlinespace
    test & \innerTable{test 104}{\lipsum*[104]}  \\  \addlinespace
    test & \innerTable{test 105}{\lipsum*[105]}  
\end{xltabular}
\end{document}

在此处输入图片描述

在此处输入图片描述 (红线表示页面布局)

附录: 您可以通过将单元格内容对齐到其顶部来巧妙地避免所有问题。在这种情况下,不再需要表格嵌套,并且表格记录更短:

\documentclass{article}
\usepackage{lipsum}
\usepackage{booktabs, xltabular}

\setlength{\parindent}{0cm}
%---------------- show page layout. don't use in a real document!
\usepackage{showframe}
\renewcommand\ShowFrameLinethickness{0.15pt}
\renewcommand*\ShowFrameColor{\color{red}}
%---------------------------------------------------------------%

\begin{document}
\setlength\tabcolsep{4pt}
\begin{xltabular}{\linewidth}{@{} cc X @{}}
    test & test 1 & \lipsum*[1]     \\  \addlinespace
    test & test 2 & \lipsum*[2]     \\  \addlinespace
    test & test 3 & \lipsum*[3]     \\  \addlinespace
    test & test 4 & \lipsum*[4]     \\  \addlinespace
    test & test 5 & \lipsum*[5]     \\  \addlinespace
% etc

    test & test 101 & \lipsum*[101] \\  \addlinespace
    test & test 102 & \lipsum*[102] \\  \addlinespace
    test & test 103 & \lipsum*[103] \\  \addlinespace
    test & test 104 & \lipsum*[104] \\  \addlinespace
    test & test 105 & \lipsum*[105] \\  \addlinespace
\end{xltabular}
\end{document}

这给出了(当然,在我看来)更漂亮,更专业的结果:

在此处输入图片描述

相关内容