forum
forum copied to clipboard
能否扩展diagbox的斜线类型
diagbox宏包定义了几种表格线样式,能满足基本需求。但是对于复杂的表格斜线就有些难以实现了,能否定义一个更自由的画线命令,通过平移左上角和右下角的坐标实现画线自由?
tikz 的路子。
- 普通表格环境,见 https://tex.stackexchange.com/a/278162 ,
- nicematrix 包的表格环境,见 https://ask.latexstudio.net/ask/question/7454.html ,
- tabularray 包的表格环境,见下方例子。注意只是概念验证型尝试,主要模仿的 tabularray library
diagbox
。(因为题主没有写出来的实际需求就是tblr
环境)
\documentclass{article}
\usepackage{tabularray}
\ExplSyntaxOn
\NewTblrLibrary { tikzbox }
{
\RequirePackage{ tikz }
\NewContentCommand \tikzbox [2] []
{
\__tblr_lib_tikzbox_fix:n
{
\tikz[baseline=\dim_use:N \box_dp:N \l__tblr_strut_dp_box + \belowsep, ##1] {##2}
}
}
}
\box_new:N \l__tblr_tikz_box
\cs_new_protected:Npn \__tblr_lib_tikzbox_fix:n #1
{
\hbox_set:Nn \l__tblr_tikz_box {#1}
\box_set_ht:Nn \l__tblr_tikz_box { \box_ht:N \l__tblr_tikz_box - \abovesep }
\box_set_dp:Nn \l__tblr_tikz_box { \box_dp:N \l__tblr_tikz_box - \belowsep }
\box_set_wd:Nn \l__tblr_tikz_box { \box_wd:N \l__tblr_tikz_box - \rightsep }
\skip_horizontal:n { -\leftsep }
\box_use:N \l__tblr_tikz_box
}
\ExplSyntaxOff
\UseTblrLibrary{diagbox, tikzbox}
\begin{document}
\verb|\diagbox{Aa}{Pp}|\par
\begin{tblr}{hlines,vlines}
\diagbox{Aa}{Pp} & Beta & Gamma \\
Epsilon & Zeta & Eta \\
Iota & Kappa & Lambda \\
\end{tblr}
\bigskip
\verb|\tikzbox{<tikz drawing code>}|\par
\begin{tblr}{hlines,vlines}
\tikzbox{
\useasboundingbox (0,0) rectangle (3,1);
\pgfnodealias{cbb}{current bounding box}
\draw
(cbb.north west) -- (cbb.south east)
(cbb.north west) -- (cbb.south);
}
& Beta & Gamma \\
Epsilon & Zeta & Eta \\
Iota & Kappa & Lambda \\
\end{tblr}
\end{document}
注意,\tikzbox
的限制和 \diagbox
相同,需要手动保证是所在行最高、所在列最宽的单元格。
diagbox
包不但支持绘制斜表线,而且能根据表头内容自动计算单元格大小(而且这是重头戏)。实现上,单元格内容是一个(pict2e
包拓展的)picture
环境,斜表线用 \Line
绘制,表头文字用 \put
添加。如果只是增加斜线,找到实现里 \Line
的地方,增加更多 \Line
就行。如果既要添加斜线,又要添加表头文字并自动计算位置关系,需要解更多的方程。
\tikzbox
就只能画线,表头内容要手动添加(\node
),线和内容不重叠也要手动保证。
感谢解答!表头内容手动添加没问题的,提一个建议,能否实现表头行文字竖直居中?
红圈的文字偏下了,能否垂直方向居中?
\NewTblrLibrary { tikzbox }
{
\RequirePackage{ tikz }
\NewContentCommand \tikzbox [2] []
{
\__tblr_lib_tikzbox_fix:n
{
- \tikz[baseline=\dim_use:N \box_dp:N \l__tblr_strut_dp_box + \belowsep, ##1] {##2}
+ $\vcenter{\hbox{\tikz[##1] {##2}}}$
}
}
}
这样就把纵向偏离值降到和 \diagbox
一个水平了
一些比较例子
\documentclass{article}
\usepackage[margin=1cm]{geometry}
\usepackage{tabularray}
\ExplSyntaxOn
\NewTblrLibrary { tikzbox }
{
\RequirePackage{ tikz }
\NewContentCommand \tikzbox [2] []
{
\__tblr_lib_tikzbox_fix:n { $\vcenter{\hbox{\tikz[##1] {##2}}}$ }
}
}
\box_new:N \l__tblr_tikz_box
\cs_new_protected:Npn \__tblr_lib_tikzbox_fix:n #1
{
\hbox_set:Nn \l__tblr_tikz_box {#1}
\box_set_ht:Nn \l__tblr_tikz_box { \box_ht:N \l__tblr_tikz_box - \abovesep }
\box_set_dp:Nn \l__tblr_tikz_box { \box_dp:N \l__tblr_tikz_box - \belowsep }
\box_set_wd:Nn \l__tblr_tikz_box { \box_wd:N \l__tblr_tikz_box - \rightsep }
\skip_horizontal:n { -\leftsep }
\box_use:N \l__tblr_tikz_box
}
\ExplSyntaxOff
\UseTblrLibrary{diagbox, tikzbox}
\begin{document}
\noindent\verb|\diagbox[...]{...}{...}|\par
\newcommand\diagboxtest[3]{%
\begin{tblr}{hlines, vlines, baseline=3, #1}
\diagbox[#2]{Aa}{Pp}
& Beta & #3 \\
Epsilon & Zeta & Eta \\
Iota & Kappa & Lambda \\
\end{tblr}%
}
\def\diagboxtests#1#2{%
\texttt{\detokenize{#1}}\quad
\diagboxtest{#1} {} {Gamma}\quad
\diagboxtest{#1,#2}{height=1.2cm}{{Gamma \\ Gamma}}\quad
\diagboxtest{#1,#2}{height=1.3cm}{{Gamma \\ Gamma}}\par
}
\diagboxtests{row{1}=t}{cell{1}{1}=cyan!20}
\diagboxtests{row{1}=m}{}
\diagboxtests{row{1}=b}{cell{1}{1}=cyan!20}
\bigskip
\noindent\verb|\tikzbox{<tikz drawing code>}|\par
\newcommand\tikzboxtest[4]{%
\begin{tblr}{hlines, vlines, baseline=3, #1}
\tikzbox[#4]{
\useasboundingbox (0,0) rectangle (2,#2);
\pgfnodealias{cbb}{current bounding box}
\draw
(cbb.north west) -- (cbb.south east)
(cbb.north west) -- (cbb.south);
}
& Beta & #3 \\
Epsilon & Zeta & Eta \\
Iota & Kappa & Lambda \\
\end{tblr}
}
\def\tikzboxtests#1#2{%
\texttt{\detokenize{#1}}\quad
\tikzboxtest{#1} {1cm} {Gamma} {}\quad
\tikzboxtest{#1,#2}{1.2cm}{{Gamma \\ Gamma}}{}\quad
\tikzboxtest{#1,#2}{1.3cm}{{Gamma \\ Gamma}}{}\par
}
\tikzboxtests{row{1}=t}{cell{1}{1}=cyan!20}
\tikzboxtests{row{1}=m}{}
\tikzboxtests{row{1}=b}{cell{1}{1}=cyan!20}
\end{document}
不错。其中 \NewContentCommand
用于在表格内重定义已有的命令。如果 \tikzbox
这个命令没有任何宏包用过,也可以直接用 \NewDocumentCommand
来定义它。
如果只是画线的话,似乎用 l3draw
也可以?用 tikz
有点太重了。
不错。其中
\NewContentCommand
用于在表格内重定义已有的命令。如果\tikzbox
这个命令没有任何宏包用过,也可以直接用\NewDocumentCommand
来定义它。
@lvjr 有点想让 \tikzbox
只在 tblr
环境内有定义