此 MWE 在我的计算机上创建了一个无限循环。有人能向我解释一下原因吗?
\documentclass{article}
\usepackage{booktabs,xparse}
\NewDocumentCommand\hlineX{ m O{0pt} O{#2} }{%
\specialrule{#1}{#2}{#3}%
}%
\begin{document}
\begin{tabular}{|l|l|l|}
\hline
1 & 2 & 3 \\
\hlineX{1pt}
4 & 5 & 6 \\
\hline
\end{tabular}
\end{document}
在我创建的主要文档中,我遇到了不同的错误:
"Misplaced \noalign. [ E]"
"Missing } inserted. [ E]"
等等。它非常像 MWE,但加载了更多包。
当我使用\specialrule
没有xparse
它的命令时,它工作得很好。
答案1
似乎应该\hlineX
是可扩展的,因为一个简化的例子也会导致同样的问题。
\documentclass{article}
\usepackage{booktabs,xparse}
\protected\def\xline{\specialrule{1pt}{0pt}{0pt}}
\begin{document}
\begin{tabular}{|l|l|l|}
\hline
1 & 2 & 3 \\
\xline
4 & 5 & 6 \\
\hline
\end{tabular}
\end{document}
的可扩展变体\NewDocumentCommand
是\NewExpandableDocumentCommand
,并且由于它定义了可扩展的新命令,因此参数规范不应以可选参数结尾。因此,我们有以下工作示例,其语法经过\hlinex
修改:
\documentclass{article}
\usepackage{booktabs,xparse}
\NewExpandableDocumentCommand\hlineX{ O{0pt} O{#1} m }{%
\specialrule{#3}{#1}{#3}%
}
\begin{document}
\begin{tabular}{|l|l|l|}
\hline
1 & 2 & 3 \\
\hlineX[1pt][2pt]{1pt}
4 & 5 & 6 \\
\hline
\end{tabular}
\end{document}
答案2
muzimuzhi Z 的回答显示了您应该做什么来避免错误(您可能应该接受这个错误),但您的实际问题是询问为什么它会循环而不是如何避免错误。
循环与 xparse 其实没什么关系,除了寻找一个可选参数,之前是不允许的\specialrule
(或者\hrule
或者\multicolumn
或者\rowcolor
类似的特殊表格单元格命令)如果看到任何不可扩展的材料,单元格模板就会启动,而且插入规则的不对齐材料就太晚了。
循环的一个简单示例是
\documentclass{article}
\usepackage{booktabs}
\begin{document}
\tracingall
\begin{tabular}{|l|l|l|}
\hline
1 & 2 & 3 \\
\relax\specialrule{0pt}{0pt}{1pt}
4 & 5 & 6 \\
\hline
\end{tabular}
\end{document}
正如您的示例所示,这会停止并显示几个本质上是虚假的错误消息,但如果您滚动浏览它们,最终会遇到一个紧密循环并且必须终止程序,\tracingall
将显示:
.
.
.
\par ->
{\hrule}
\par ->
{\hrule}
\par ->
{\hrule}
.
.
.
这表明你实际上已经遇到了这个众所周知的循环条件:
\documentclass{article}
\begin{document}
{\let\par\relax x\hrule}
\end{document}
这使得 TeX 永远运行而不会出现任何错误。
\hrule
,在垂直模式下,只允许在段落之间插入一条横跨页面的水平线。如果在水平模式下遇到此标记,TeX 不会引发错误,它会在标记\par
之前插入标记以结束当前段落,\hrule
然后正常进行。
需要注意的是,与水平模式下垂直框结束的类似情况不同,TeX 不会执行原始的段落结束代码,而是直接将标记插入\par
输入流。
因此,如果像这里一样(并且由于 latex 表格中的技术原因)\par
在本地定义为不执行任何操作,则\hrule
触发插入,\par
其不执行任何操作,然后\hrule
再次看到,插入\par
....