使用 \multicolumn 删除行中的垂直线是可行的,但在 \@ifstar 条件调用的命令中使用时则不行

使用 \multicolumn 删除行中的垂直线是可行的,但在 \@ifstar 条件调用的命令中使用时则不行

以下按预期工作,从 LaTeX longtable 的顶行删除 vlines。 笔记:需要使用longtable,因为这个表跨越多个页面,而nicematrix目前不支持跨越多个页面。

\documentclass{article}
\usepackage{longtable}

\makeatletter
\newcommand{\@mc}[1]{\multicolumn{1}{l}{#1}}
\newcommand{\titleRow}[3]{\@mc{when} & \@mc{#1} & \@mc{#2} & \@mc{#3}\\[1pt]}
\makeatother

\begin{document}
\begin{longtable}[c]{|p{3cm}|p{3cm}|p{3cm}|p{3cm}|}    
    \titleRow{First}{Second}{Third}  
    \hline   
    January & Tom & Dick & Harry \\\hline
    February & Dick & Harry & Tom \\\hline
\end{longtable}
\end{document}

以下是预期的输出: 在此处输入图片描述

但是,\titleRow在带星号的版本中执行命令会导致放错位置\omit. \multispan -> \omit error。为什么以下内容无法按预期工作?

\documentclass{article}
\usepackage{longtable}

\makeatletter
\newcommand{\@mc}[1]{\multicolumn{1}{l}{#1}}
\newcommand{\titleRow}{\@ifstar\star@titleRow\nostar@titleRow}
\newcommand{\star@titleRow}[3]{\@mc{when} & \@mc{#1} & \@mc{#2} & \@mc{#3}\\[1pt]}
\newcommand{\nostar@titleRow}[3]{\@mc{} & \@mc{#1} & \@mc{#2} & \@mc{#3}\\[1pt]}
\makeatother

\begin{document}
\begin{longtable}[c]{|p{3cm}|p{3cm}|p{3cm}|p{3cm}|}    
    \titleRow{First}{Second}{Third}  
    \hline   
    January & Tom & Dick & Harry \\\hline
    February & Dick & Harry & Tom \\\hline
\end{longtable}
\end{document}

答案1

longtabletabular或任何其他表格制作环境都不是问题;TeX 扩展表格行开头的标记以查看是否\omit出现,并在找到不是的不可扩展命令时立即停止搜索\omit

好的,\omit你没见过的是什么?它是告诉 TeX 忽略对齐中特定列的模板的原始命令。并\multicolumn以 开头\omit。但\@ifstar事实并非如此。

对你的命令使用可扩展的版本*

\documentclass{article}
\usepackage{longtable}

\NewExpandableDocumentCommand{\titleRow}{smmm}{%
  \multicolumn{1}{l}{\IfBooleanF{#1}{when}} &
  \multicolumn{1}{l}{#2} &
  \multicolumn{1}{l}{#3} &
  \multicolumn{1}{l}{#4} \\[1pt]
}

\begin{document}

\begin{longtable}[c]{|p{3cm}|p{3cm}|p{3cm}|p{3cm}|}    
    \titleRow{First}{Second}{Third}  
    \hline
    January & Tom & Dick & Harry \\\hline
    February & Dick & Harry & Tom \\\hline
\end{longtable}

\bigskip

\begin{longtable}[c]{|p{3cm}|p{3cm}|p{3cm}|p{3cm}|}    
    \titleRow*{First}{Second}{Third}  
    \hline
    January & Tom & Dick & Harry \\\hline
    February & Dick & Harry & Tom \\\hline
\end{longtable}

\end{document}

在此处输入图片描述

答案2

问题是,宏\multicolumn(扩展为正确的\omit\span基元数)必须是扩展后表格单元格中的第一个对象。因为\halign基元(LaTeX 表格使用它)会查找表格单元格数据并在此处运行扩展处理器,直到在此处找到第一个不可扩展且非空间项。如果是,\omit\halign省略此单元格的前导码。在其他情况下,将使用给定单元格的前导码的左侧部分,然后是单元格中的数据,然后是前导码的右侧部分。

LaTeX宏\@ifstar使用\futureletTeX 基元,并且它是不可扩展的。因此单元格不会扩展到\multicolumn宏,即\omit。如果\omit在另一个上下文中遇到 (即在单元格中间),则 TeX 会报告错误。

解决方案是基于在\omit之前直接使用原始的\@ifstar,因为我们知道\omit将在两种情况下使用(已启动和非启动)。当然,在这种情况下,我们不需要\multicolumn在第一格中使用 ,因为\omit已经使用了。

\newcommand{\@mc}[1]{\multicolumn{1}{l}{#1}}
\newcommand{\titleRow}{\omit\@ifstar\star@titleRow\nostar@titleRow}
\newcommand{\star@titleRow}[3]{\enspace when\hfil & \@mc{#1} & \@mc{#2} & \@mc{#3}\\[1pt]}
\newcommand{\nostar@titleRow}[3]{ & \@mc{#1} & \@mc{#2} & \@mc{#3}\\[1pt]}

相关内容