![将特定形状的表格指定为新命令](https://linux22.com/image/359831/%E5%B0%86%E7%89%B9%E5%AE%9A%E5%BD%A2%E7%8A%B6%E7%9A%84%E8%A1%A8%E6%A0%BC%E6%8C%87%E5%AE%9A%E4%B8%BA%E6%96%B0%E5%91%BD%E4%BB%A4.png)
我的文档的许多地方都有这样的表格:
My table is $ R = \raisebox{1.5ex}{{\begin{tabular}{lll}
\textit{x} & \textit{y} & \\ \cline{1-2}
\multicolumn{1}{|l}{a} & \multicolumn{1}{l|}{A} & 1 \\
\multicolumn{1}{|l}{a} & \multicolumn{1}{l|}{B} & 2 \\
\multicolumn{1}{|l}{b} & \multicolumn{1}{l|}{C} & 4 \\
\multicolumn{1}{|l}{b} & \multicolumn{1}{l|}{D} & 7 \\ \cline{1-2}
\end{tabular}}} $
它是一个内联表格,内容被框起来,而标题(第一行)和最后一列都像上图一样突出。标题为斜体。
本身tabular
被凸起,1.5ex
以便仅将框架框与基线对齐,而不是整个表格。因此,在图片中,=
位于框架的中心。(这可能不是最好的方法,因为它与字体大小相关,但到目前为止我还没有找到更好的方法)。
我想将其指定tabular
为一个命令,其中我只传递(x,y)
(标题)和(a,A,1),(a,B,2),(b,C,4),(b,D,7)
(内容),而不指定任何对齐和格式。
我该怎么做?
答案1
使用内联宏完成堆栈
\mystack{<table content>}{<column labels>}{<row labels>}
表格以文本模式设置,而标签以数学模式设置。此宏可以处理任意尺寸。
修改后的答案(处理任意宽度的列数据)
这利用了一个很好的tabstackengine
特性,即最近创建的堆栈的单元格尺寸被保存下来,并可以通过\TABwd{<column>}
、\TABht{<row>}
和访问\TABdp{<row>}
。因此,可以堆叠盒装矩阵,并且其列宽尺寸可用于创建适当宽度的列标签。
\documentclass{article}
\usepackage{tabstackengine,listofitems}
\setstacktabbedgap{\tabcolsep}
\makeatletter
\newcommand\mystack[3]{%
\savestack\mydata{\tabbedCenterstack{#1}}%
\setsepchar{&}%
\readlist\mycollabels{#2}%
\def\collabelstack{}%
\foreachitem\x\in\mycollabels{%
\ifnum\xcnt>1\relax\g@addto@macro\collabelstack{&}\fi%
\expandafter\protected@edef\expandafter\collabelstack\expandafter{%
\collabelstack\makebox[\TABwd{\xcnt}]{$\x$}}%
}%
\stackon{\fbox{\mydata}}{\expandafter\Matrixstack\expandafter{\collabelstack}}%
\hspace{\tabcolsep}%
\Vectorstack{#3}%
}
\makeatother
\begin{document}
My table is $R = \mystack{a&AAA&t\\a&B&z\\b&C&qq\\b&D&r}{x&y&z}{1\\2\\4\\7}$
\end{document}
原始答案(假设列数据宽度均匀)
\documentclass{article}
\usepackage{tabstackengine}
\setstacktabbedgap{2\tabcolsep}
\newcommand\mystack[3]{%
\stackon{\fbox{\tabbedCenterstack{#1}}}{\Matrixstack{#2}}\hspace{\tabcolsep}%
\Vectorstack{#3}%
}
\begin{document}
My table is $R = \mystack{a&A\\a&B\\b&C\\b&D}{x&y}{1\\2\\4\\7}$
\end{document}
答案2
\raisebox[1.5ex]{..}
只需使用标题并将其添加为额外行,即可将表格居中而无需指定\phantom
。以下新命令接受标题元素作为两个参数,并将表格的其余部分作为第三个参数。我还删除了multicolumn
表格主体中的需要,以提高可读性。
\documentclass[12pt,a4paper]{article}
\begin{document}
\newcommand{\ctabular}[3]{\begin{tabular}{|ll|l}
\multicolumn{1}{l}{\textit{#1}} & \multicolumn{1}{l}{\textit{#2}} & \\ \cline{1-2}
#3 \\ \cline{1-2}
\multicolumn{1}{l}{\phantom{\textit{#1}}} & \multicolumn{1}{l}{\phantom{\textit{#2}}} &
\end{tabular}
}
My table is $ R = \ctabular{x}{y}{
a & A & 1 \\
a & B & 2 \\
b & C & 4 \\
b & D & 7} $
\end{document}
答案3
\documentclass{article}
\usepackage{array}
\newcommand{\mcl}[1]{\multicolumn{1}{l}{#1}}
\newcommand\carray[3]{\raisebox{1.5ex}{\begin{tabular}{|ll|l}
\mcl{$#1$} & \mcl{$#2$} & \\ \cline{1-2}
#3 \\ \cline{1-2}
\end{tabular}}
}
\usepackage{lipsum}
\begin{document}
\lipsum*[11]
My table is $ R = \carray{x}{y}{
a & A & 1 \\
a & B & 2 \\
b & C & 4 \\
b & D & 7 }$
\lipsum[11]
\end{document}
笔记: 这样的解决方案并不能省去大量的打字工作:)并且它的泛化并不简单。另外使用这样的表格作为内联元素并不是一个明智的想法(见上图)。