在同一个列表中,第一项是一个 tabular,其内容用硬代码写死,第二项也是一个 tabular,其内容与第一项相同,只是其每个单元格是由循环逻辑生成的,第三项无实际意义,只用于参考项与项之间的空白间隔。理论上,项与项之间的间隔应该是相同的,但是现在的问题是,第二项会有多余的空白间隔,有点无法理解这个多出来的空白间隔是从哪里来的,还望大佬解惑。
代码如下:
\documentclass[zihao=-4]{ctexart}
\usepackage{geometry}
\geometry{a4paper,left=25mm,right=25mm,top=25mm,bottom=25mm, headheight=20mm}
\usepackage{expl3}
\usepackage{tabularx}
\usepackage{layouts}
\ctexset{linestretch=1.245, autoindent=2\ccwd}
\begin{document}
\ExplSyntaxOn
\begin{list}{}{
\setlength{\itemsep}{0pt}
\setlength{\parsep}{0pt}
\setlength{\topsep}{0ex}
\setlength{\partopsep}{0pt}
\setlength{\parskip}{0pt}
}
\item 一二三四五一二三四五一二三四五
\par
\begin{tabular*}{\linewidth}{p{0.25\linewidth}p{0.25\linewidth}p{0.25\linewidth}p{0.25\linewidth} }
A.~$5$~~~ &A.~$5$~~~ &A.~$5$~~~ &A.~$5$~~~ \\
\end{tabular*}
\item 一二三四五一二三四五一二三四五
\par
\begin{tabular*}{\linewidth}{p{0.25\linewidth}p{0.25\linewidth}p{0.25\linewidth}p{0.25\linewidth} }
\int_step_inline:nn { 4 } {
A.~$5$~~~ \int_compare:nNnTF {#1}{=}{4}{\\}{&}
}
\end{tabular*}
\item 一二三四五一二三四五一二三四五
\currentlist
\begin{figure}
\listdesign
\end{figure}
\end{list}
\ExplSyntaxOff
\end{document}
生成的效果图如下:
问题可简化为
\documentclass[zihao=-4]{ctexart}
\usepackage{geometry}
\geometry{a4paper,left=25mm,right=25mm,top=25mm,bottom=25mm, headheight=20mm}
\usepackage{expl3}
\usepackage{tabularx}
\usepackage{layouts}
\ctexset{linestretch=1.245, autoindent=2\ccwd}
\begin{document}
\ExplSyntaxOn
\begin{tabular*}{\linewidth}{p{0.25\linewidth}p{0.25\linewidth}p{0.25\linewidth}p{0.25\linewidth}}
\int_step_inline:nn { 4 } { A. 5 \int_compare:nNnTF {#1} = { 4 } { \\ } { & } }
\end{tabular*}
\par
????????
\ExplSyntaxOff
\end{document}
实际还可进一步简化,
\begin{tabular}{l}
A \\ \relax
\end{tabular}
\par
???????
上面这个同样会出现“多余的”空行。
其原因是,\relax
是在表格新的一行中。这个表格实际有两行,只不过第二行是空白行。
回到你的问题,实际上,将 \int_step_inline:nn
相应的换成 \int_step_function:nN
则不会出现多余的空行。
这涉及到 \int_step_inline:nn
的内部实现。
为了能够处理嵌套的 ...inline:nn
情况,有一个专门记录嵌套数的 int,它在一个新的嵌套开始前加1,在嵌套完成后减 1。在你的代码中,嵌套完成时的最后一个记号是 \\
,在这个记号之后,...inline:nn
还会追加一个减 1 的操作,这操作在 LaTeX 看来,语法上并不属于表格的当前行,因为当前行已经在此前的 \\
处结束了,它是下一行的内容。自然就会留下一个空白行。
想要移除这个空白行也很简单,方法也很多,如自己定义一个不追加加一减一操作的 ...inline:nn
:
\cs_set_protected:Npn \my_int_step_inline:nn #1#2
{
\cs_gset:Npn \__my_tmp:w ##1 {#2}
\int_step_function:nN {#1} \__my_tmp:w
}
这是完全可行的(要注意全局定义 \__my_tmp:w
,因为每一个单元格都在一个组中),只是嵌套使用时会有点小问题。
感谢大佬指导~~
一开始我一直怀疑是不是列表项参数与 tabular 环境有冲突之类的,尝试置零了所有可能与“空行”有关的参数,还是不行。原来是
\int_step_inline:nn
为了实现嵌套,首先需要把当前循环逻辑封装成一个函数并以当前嵌套层数作为该函数名的结尾,在完成该函数的循环后,再进行嵌套层数的减一操作。应该就是下面这段代码吧:知道了原理,那就好办了,只需要先把 tabular 的构建代码拼接好,再一次性使用就可以了。
最后,再次感谢大佬的指导~~~