我正在尝试在 LaTeX 3 命令中构建一个表格。MWE:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\createTable}{ m m }{
\begin{tabular}{|c*{#2}{|c}|}
\hline
\int_step_inline:nnnn {1} {1} {#1} {
##1
\int_step_inline:nnnn {1} {1} {#2} {
& x
}
\\\hline
}
\end{tabular}
}
\ExplSyntaxOff
\begin{document}
\createTable{5}{4}
\end{document}
这给了我以下输出,其中第一列的列线太长:
为了解决这个问题,我读了问题
虽然我仍然不明白问题的实际性质(或其给出的解决方案),但我能够重现解决方案使用 LaTeX3 语法生成仅具有可选参数的可扩展环境。
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\DeclareDocumentCommand{\fillRow}{ m m }{
#1
\int_step_inline:nnnn {1} {1} {#2} {
& x
}
\\\hline
}
\DeclareDocumentCommand{\BuildTable}{ m }{
\begin{tabular}{|c*{#1}{|c}|}
\hline
}
\def\endBuildTable{
\end{tabular}
}
\ExplSyntaxOff
\begin{document}
\begin{BuildTable}{4}
\fillRow{1}{4}
\fillRow{2}{4}
\fillRow{3}{4}
\fillRow{4}{4}
\fillRow{5}{4}
\end{BuildTable}
\end{document}
此代码输出所需的结果。但我不喜欢它,因为它需要 3 个命令而不是 1 个(小问题)。但最重要的是因为生成表的语法冗长、冗余和不灵活。因此,我决定通过将表生成命令放在另一个命令中进行抽象:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\DeclareDocumentCommand{\fillRow}{ m m }{
#1
\int_step_inline:nnnn {1} {1} {#2} {
& x
}
\\\hline
}
\DeclareDocumentCommand{\BuildTable}{ m }{
\begin{tabular}{|c*{#1}{|c}|}
\hline
}
\def\endBuildTable{
\end{tabular}
}
\DeclareDocumentCommand{\putTogether}{ m m }{
\begin{BuildTable}{#2}
\int_step_inline:nnnn {1} {1} {#1} {
\fillRow{##1}{#2}
}
\end{BuildTable}
}
\ExplSyntaxOff
\begin{document}
\putTogether{5}{4}
\end{document}
但这又让我回到原来的问题,因为第一列的列线又太长了。
有人能做到吗
- 向我解释我的原始代码到底有什么问题;
- 第二和第三个代码片段之间有什么区别;
- 如何编辑我的(原始)代码以解决我的问题?
答案1
问题是,\int_step_inline:nnnn
有一个不可扩展的终止部分,它会进入之前可以看到的方式\end{tabular}
,所以这会创建一个新的表格单元格(在新行中)。
您可以使用以下方法避免这种情况\prg_replicate:nn
:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\fillRow}{ m m }
{
#1 \prg_replicate:nn { #2 } { & x } \\ \hline
}
\NewDocumentCommand{\putTogether}{ m m }
{
\begin{tabular}{|c*{#1}{|c}|}
\hline
\int_gzero:N \g_tmpa_int
\prg_replicate:nn { #1 }
{
\int_gincr:N \g_tmpa_int
\fillRow{\int_to_arabic:n { \g_tmpa_int } } {#2}
}
\end{tabular}
}
\ExplSyntaxOff
\begin{document}
\putTogether{5}{4}
\end{document}
或者,您可以将表主体收集到令牌列表中并立即传递。
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\fillRow}{ m m }
{
#1 \prg_replicate:nn { #2 } { & x } \\ \hline
}
\NewDocumentCommand{\putTogether}{ m m }
{
\begin{tabular}{|c*{#1}{|c}|}
\hline
\tl_clear:N \l_tmpa_tl
\int_step_inline:nnnn { 1 } { 1 } { #1 }
{
\tl_put_right:Nn \l_tmpa_tl { \fillRow { ##1 } {#2} }
}
\tl_use:N \l_tmpa_tl
\end{tabular}
}
\ExplSyntaxOff
\begin{document}
\putTogether{5}{4}
\end{document}
答案2
目前还没有解释,但可以工作。我稍后会改进!
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\DeclareDocumentCommand{\fillRow}{ m m }{
#1
\int_step_inline:nnnn {1} {1} {#2} {
& x
}
% \hline
}
\DeclareDocumentCommand{\BuildTable}{ m }{
\begin{tabular}{|c*{#1}{|c}|}
\hline
}
\def\endBuildTable{
\end{tabular}
}
\DeclareDocumentCommand{\putTogether}{ m m }{
\begin{BuildTable}{#2}
\int_step_inline:nnnn {1} {1} {#1-1} {
\fillRow{##1}{#2} \\ \hline
}%
\fillRow{#1}{#2} \\
\hline
\end{BuildTable}
}
\ExplSyntaxOff
\begin{document}
\putTogether{5}{4}
\end{document}