100 自定义表格粗横线命令的宏展开问题

发布于 2025-03-09 18:04:00

我想自定义\thickhline命令替代\hline,以便控制表格横线粗细。以下代码是可行的:

\documentclass{article}
\newcommand \thickhline {
  \noalign{\global\arrayrulewidth1.5bp}
  \hline
  \noalign{\global\arrayrulewidth0.5bp}
}
\begin{document}
\begin{tabular}{ll}
  \thickhline
  a & b \\
  \hline
  c & d \\
  \thickhline
\end{tabular}
\end{document}

但是,一旦希望\thickhline接收一个可选的长度参数,例如

\newcommand \thickhline [1] [1.5bp] {
  \noalign{\global\arrayrulewidth#1}
  \hline
  \noalign{\global\arrayrulewidth0.5bp}
}

就会报错了。

我尝试了用\NewExpandableDocumentCommand定义以及用\@ifnextchar预读[两种方法,都不可行。应该这里面存在我不懂的宏展开问题。

我知道有很多表格宏包能做这件事情。我的问题是如何自定义具有一个可选参数的\thickhline命令?或者有没有其他打包控制表格线粗细命令的方法?

查看更多

关注者
0
被浏览
157
Sagittarius Rover
Sagittarius Rover 8小时前
我要成为Typst糕手/(ㄒoㄒ)/~~

usrguide中,如@u101077 老师所言,要使用\NewExpandableDocumentCommand才可以在表格内正确展开,但与此同时又有如下限制:

image.png

无法将唯一的参数定义为O型...

我不太懂展开,也不太懂是否有好的办法绕开这一限制,但OP又说:

我知道有很多表格宏包能做这件事情。我的问题是如何自定义具有一个可选参数的thickhline命令?或者有没有其他打包控制表格线粗细命令的方法?

因此我虽然发现booktabs中的toprule命令完全符合这一要求...但不确定OP是否“允许”站在前人的肩膀上,下面是直接偷Plain-TeX的方法,个人觉得这样的话,这个横线命令应该会比自己定义的更sound...

\documentclass{article}
\makeatletter
\newdimen\myheavyrulewidth
\myheavyrulewidth=1.5bp %<-default width here
\newdimen\belowrulesep
\newdimen\belowbottomsep
\newdimen\aboverulesep
\newdimen\abovetopsep
\newdimen\@aboverulesep
\newdimen\@belowrulesep
\newcount\@thisruleclass
\newcount\@lastruleclass
\@lastruleclass=0
\newdimen\@thisrulewidth
\def\futurenonspacelet#1{\def\@BTcs{#1}%
   \afterassignment\@BTfnslone\let\nexttoken= }
\def\@BTfnslone{\expandafter\futurelet\@BTcs\@BTfnsltwo}
\def\@BTfnsltwo{\expandafter\ifx\@BTcs\@sptoken\let\next=\@BTfnslthree
   \else\let\next=\nexttoken\fi \next}
\def\@BTfnslthree{\afterassignment\@BTfnslone\let\next= }
\def\Thickhline{\noalign{\ifnum0=`}\fi%<- modified from \toprule
  \@aboverulesep=\abovetopsep
  \global\@belowrulesep=\belowrulesep %global cos for use in the next noalign
  \global\@thisruleclass=\@ne
  \@ifnextchar[{\@BTrule}{\@BTrule[\myheavyrulewidth]}}%<- modified here
\def\@BTrule[#1]{%
  \ifx\longtable\undefined
    \let\@BTswitch\@BTnormal
  \else\ifx\hline\LT@hline
    \nobreak
    \let\@BTswitch\@BLTrule
  \else
    \let\@BTswitch\@BTnormal
  \fi\fi
  \global\@thisrulewidth=#1\relax
  % \ifnum\@thisruleclass=\tw@\vskip\@aboverulesep\else
  % \ifnum\@lastruleclass=\z@\vskip\@aboverulesep\else
  % \ifnum\@lastruleclass=\@ne\vskip\doublerulesep\fi\fi\fi
  \@BTswitch}
\AtBeginDocument{%
   \providecommand*\CT@arc@{}}%% colortbl support
\def\@BTnormal{%
    {\CT@arc@\hrule\@height\@thisrulewidth}%
    \futurenonspacelet\@tempa\@BTendrule}
\def\@BLTrule{\@ifnextchar({\@@BLTrule}{\@@BLTrule()}}
\def\@@BLTrule(#1){\@setrulekerning{#1}%
\global\@cmidlb\LT@cols
\ifnum0=`{\fi}%
\noalign{\ifnum0=`}\fi
\futurenonspacelet\@tempa\@BTendrule}
\def\@BTendrule{\ifx\@tempa\toprule\global\@lastruleclass=\@thisruleclass
  \else\ifx\@tempa\midrule\global\@lastruleclass=\@thisruleclass
  \else\ifx\@tempa\bottomrule\global\@lastruleclass=\@thisruleclass
  \else\ifx\@tempa\cmidrule\global\@lastruleclass=\@thisruleclass
  \else\ifx\@tempa\specialrule\global\@lastruleclass=\@thisruleclass
  \else\ifx\@tempa\addlinespace\global\@lastruleclass=\@thisruleclass
  \else\global\@lastruleclass=\z@\fi\fi\fi\fi\fi\fi
  % \ifnum\@lastruleclass=\@ne\relax\else\vskip\@belowrulesep\fi
  \ifnum0=`{\fi}}
\makeatother
\begin{document}

\begin{tabular}{ll}
\Thickhline
  a & b \\
\hline
  c & d \\
\Thickhline[1bp]
\end{tabular}

\end{document}

image.png


感觉抄的很不整洁(neat),上面应该还存在一些可以删的unused命令...

3 个回答
远方不远
远方不远 9小时前
这家伙很懒,什么也没写!

image.png
image.png
image.png

其实有点卡
其实有点卡 6小时前
这家伙很懒,什么也没写!

Plain TeX 的方法是我想要的,但它直接让我汗流浃背了。。

撰写答案

请登录后再发布答案,点击登录

发布
问题

分享
好友

手机
浏览

扫码手机浏览