我正在尝试使用宏为环境定义一些选项。
\usepackage{tabularray}
....
% previous parameter definition, does not scale
\def\cellax{1}
\def\cellay{2}
\def\cellaw{4}
\def\cellbx{2}
\def\cellby{3}
\def\cellbw{5}
% want to use a macro taking arguments
\newcommand{\newcell}[3]{
hline{#2-{#2+1}}={#1-{#1 + #3 - 1}}{solid},
vline{#1,#1+#3}={#2}{solid},
cell{#2}{#1}={c=#3}{c},
}
\begin{table}[!ht]
\ttfamily
\centering
$\begin{tblr}{
hline{1}={1-Z}{solid},
hline{2}={1-Z}{solid},
vline{1}={1}{solid},
vline{2-11}={1}{dashed},
%
hline{\cellay-{\cellay+1}}={\cellax-{\cellax + \cellaw - 1}}{solid},
vline{\cellax,\cellax+\cellaw}={\cellay}{solid},
cell{\cellay}{\cellax}={c=\cellaw}{c},
%
hline{\cellby-{\cellby+1}}={\cellbx-{\cellbx + \cellbw - 1}}{solid},
vline{\cellbx,\cellbx+\cellbw}={\cellby}{solid},
cell{\cellby}{\cellbx}={c=\cellbw}{c},
% Want to use it here ....
\newcell{4, 4, 4},
%
hspan = even,
}
x_1&x_2&x_3&x_4&x_5&x_6&x_7&x_8&x_9&x_{10}&\ldots\\
n_1&\\
&n_2 \\
&&n_3 \\
&&&&\ddots \\
\end{tblr}$
\end{table}
本质上,我试图用一个宏替换使用\cellax
(“单元格 A,x 坐标”)\cellbx
等的定义,该宏采用 3 个参数并扩展为几个hline
s 和vline
s 以及的定义。据我所知,cell
这些都是tblr
来自包的环境选项。tabularray
此代码在 中产生错误“您不能在水平模式下使用宏参数字符 #” newcommand
,但即使我在宏定义中插入具体值,它似乎也不起作用。没有创建新单元格。
- 如何在环境选项中正确扩展宏?
- 如何在宏中使用参数扩展到选项列表?
答案1
如果所有 key=value 内容都可以完全扩展,则可以使用在-environment 读取\expanded
之前对其进行扩展。然后,您应该保护不进行扩展(使用下面的代码中的 ,或用不应进一步扩展的内容替换)。tblr
\begin
\noexpand
\unexpanded{<stuff>}
<stuff>
正如我在评论中指出的那样,TeX 中的参数是一组单独的括号,因此应该用\newcell{4}{4}{4}
代替\newcell{4, 4, 4}
。此外,的参数数量\newcommand
在括号中给出,而不是括号,因为这是一个可选参数:\newcommand{\newcell}[3]{<replacement text>}
。
应用这些内容后,您的代码将变为以下形式:
\documentclass[preview]{standalone}
\usepackage{tabularray}
% previous parameter definition, does not scale
\def\cellax{1}
\def\cellay{2}
\def\cellaw{4}
\def\cellbx{2}
\def\cellby{3}
\def\cellbw{5}
% want to use a macro taking arguments
\newcommand{\newcell}[3]{
hline{#2-{#2+1}}={#1-{#1 + #3 - 1}}{solid},
vline{#1,#1+#3}={#2}{solid},
cell{#2}{#1}={c=#3}{c},
}
\begin{document}
\begin{table}[!ht]
\ttfamily
\centering
$\expanded{\noexpand\begin{tblr}{
hline{1}={1-Z}{solid},
hline{2}={1-Z}{solid},
vline{1}={1}{solid},
vline{2-11}={1}{dashed},
%
hline{\cellay-{\cellay+1}}={\cellax-{\cellax + \cellaw - 1}}{solid},
vline{\cellax,\cellax+\cellaw}={\cellay}{solid},
cell{\cellay}{\cellax}={c=\cellaw}{c},
%
hline{\cellby-{\cellby+1}}={\cellbx-{\cellbx + \cellbw - 1}}{solid},
vline{\cellbx,\cellbx+\cellbw}={\cellby}{solid},
cell{\cellby}{\cellbx}={c=\cellbw}{c},
% Want to use it here ....
\newcell{4}{4}{4},
%
hspan = even,
}}
x_1&x_2&x_3&x_4&x_5&x_6&x_7&x_8&x_9&x_{10}&\ldots\\
n_1&\\
&n_2 \\
&&n_3 \\
&&&&\ddots \\
\end{tblr}$
\end{table}
\end{document}
提供更多控制的替代方法是使用expkv
1及其 key=value-expansion 语法。在下面的前面,V:
指示\newcell
扩展expkv
以下内容一次(如果它有,=
它将扩展值而不是键)。其他所有内容均原封不动地转发(或至少几乎原封不动,键名周围的一组外括号将被剥离 - 您的 MWE 中不存在)。
为了简化将键列表包装到expkv
扩展机制中的工作,我编写了一个简短的辅助宏\keyexpander
。如果您需要解释,请直接询问。
\documentclass[preview]{standalone}
\usepackage{tabularray}
\usepackage{expkv-cs}
\newcommand*\keyexpander{\ekvoptarg\keyexpanderKV{}}
\ekvcSplitAndForward\keyexpanderKV\keyexpanderDO
{
pre = {}
,post = {}
,keyProc = \keyexpanderKEY
,pairProc = \keyexpanderPAIR
}
\ekvcSecondaryKeys\keyexpanderKV
{
nmeta oarg = { pre = [, post = ] }
,nmeta brace-keys =
{ keyProc = \keyexpanderKEYBR, pairProc = \keyexpanderPAIRBR }
,nmeta plain-keys =
{ keyProc = \keyexpanderKEY, pairProc = \keyexpanderPAIR }
}
\newcommand\keyexpanderDO[6]
{%
\expanded
{%
\unexpanded{#5#1}%
{%
\IfBlankF{#6}
{%
\unexpanded\expandafter\expandafter\expandafter
{%
\expandafter\keyexpanderCOMMA\expanded
{\expanded{\ekvparse{#3}{#4}{#6}}}%
}%
}%
}%
}%
#2%
}
\def\keyexpanderCOMMA, {}
\newcommand\keyexpanderKEY[1]{, \unexpanded{#1}}
\newcommand\keyexpanderPAIR[2]{, \unexpanded{#1}= {\unexpanded{#2}}}
\newcommand\keyexpanderKEYBR[1]{, {\unexpanded{#1}}}
\newcommand\keyexpanderPAIRBR[2]{, {\unexpanded{#1}}= {\unexpanded{#2}}}
% previous parameter definition, does not scale
\def\cellax{1}
\def\cellay{2}
\def\cellaw{4}
\def\cellbx{2}
\def\cellby{3}
\def\cellbw{5}
% want to use a macro taking arguments
\newcommand{\newcell}[3]{
hline{#2-{#2+1}}={#1-{#1 + #3 - 1}}{solid},
vline{#1,#1+#3}={#2}{solid},
cell{#2}{#1}={c=#3}{c},
}
\begin{document}
\begin{table}[!ht]
\ttfamily
\centering
$\keyexpander{\begin{tblr}}{
hline{1}={1-Z}{solid},
hline{2}={1-Z}{solid},
vline{1}={1}{solid},
vline{2-11}={1}{dashed},
%
hline{\cellay-{\cellay+1}}={\cellax-{\cellax + \cellaw - 1}}{solid},
vline{\cellax,\cellax+\cellaw}={\cellay}{solid},
cell{\cellay}{\cellax}={c=\cellaw}{c},
%
hline{\cellby-{\cellby+1}}={\cellbx-{\cellbx + \cellbw - 1}}{solid},
vline{\cellbx,\cellbx+\cellbw}={\cellby}{solid},
cell{\cellby}{\cellbx}={c=\cellbw}{c},
% Want to use it here ....
V: \newcell{4}{4}{4},
%
hspan = even,
}
x_1&x_2&x_3&x_4&x_5&x_6&x_7&x_8&x_9&x_{10}&\ldots\\
n_1&\\
&n_2 \\
&&n_3 \\
&&&&\ddots \\
\end{tblr}$
\end{table}
\end{document}
输出如上。
1免责声明:我是的作者expkv
。
答案2
仅使用 TeX 基元即可实现相同的图表。创建这样的宏会更有趣。
\newdimen\bw \bw=1.8em
\def\dashrule{\lower4pt\vbox to15pt{%
\cleaders\vbox{\kern.5pt\hrule height2pt width.4pt\kern.5pt}\vfil}%
}
\def\xcells#1{\ifx\relax#1\else
\hbox to\bw{\hfil$x_{#1}$\hfil \dashrule}%
\expandafter\xcells\fi
}
\def\boxik#1#2#3{
\moveright#1\bw\vbox{\kern-.4pt
\hrule
\hbox to#2\bw{\vrule height 11pt depth4pt \hfil$#3$\hfil\vrule}
\hrule
}
}
\vbox{\offinterlineskip
\hrule
\hbox{\vrule\kern-.4pt \xcells 123456789{10}\relax \kern2pt\dots\kern2pt}
\hrule
\boxik 0 4 {n_1}
\boxik 1 5 {n_2}
\boxik 2 5 {n_3}
\moveright 4.5\bw\hbox{$\ddots$}
}