在环境选项列表中扩展宏

在环境选项列表中扩展宏

我正在尝试使用宏为环境定义一些选项。

\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 个参数并扩展为几个hlines 和vlines 以及的定义。据我所知,cell这些都是tblr来自包的环境选项。tabularray

此代码在 中产生错误“您不能在水平模式下使用宏参数字符 #” newcommand,但即使我在宏定义中插入具体值,它似乎也不起作用。没有创建新单元格。

在此处输入图片描述

  1. 如何在环境选项中正确扩展宏?
  2. 如何在宏中使用参数扩展到选项列表?

答案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}

在此处输入图片描述


提供更多控制的替代方法是使用expkv1及其 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$}
}

相关内容