使用字母格式作为连续宏调用的参数

使用字母格式作为连续宏调用的参数

人们!

我想将字母格式(即)作为调用另一个宏的\tiny宏的参数。使用下面给出的代码,我期望得到这样的结果:\printarray\subprintarray

在此处输入图片描述

但我得到以下信息:

在此处输入图片描述

我不知道为什么在第二个宏调用中字母格式会丢失。我使用的技术是\protected@edef那个技术埃格尔带我进入类似的问题

这是我的代码:

\documentclass{letter}
\usepackage{keycommand}
\usepackage{tikz}

\makeatletter
\newkeycommand{\printarray}[myarray={"a","3.4","more", "Test"},arrayformat={\small}, n=3]
{
    \edef\tagsaux{\commandkey{myarray}};
    \edef\naux{\commandkey{n}};
    \protected@edef\formataux{\commandkey{arrayformat}};

    \subprintarray[submyarray=\tagsaux, subarrayformat={\formataux}, subn=\naux]
}

\newkeycommand{\subprintarray}[submyarray={"a","3.4","$sin(90)+4$"},subarrayformat={\small}, subn=3]
{   
    \protected@edef\subtags{\commandkey{submyarray}};

    \foreach \xpos in {1,2,...,\commandkey{subn}}{
        \path (1.5*\xpos, 1) node { \pgfmathparse{\subtags[\xpos]}\pgfmathresult };
        \path (1.5*\xpos, 0) node { \commandkey{subarrayformat} \pgfmathparse{\subtags[\xpos]}\pgfmathresult };
    }
}
\makeatother

\begin{document}
\def\tags{{"ABC","b","$\sin(20)+4$","111","4","5","6","7"}}

Call to \texttt{\textbackslash subprintarray}\\
\fbox{
\begin{tikzpicture}
    \subprintarray[submyarray=\tags,subarrayformat={\small },subn=4]
\end{tikzpicture}}

Call to \texttt{\textbackslash printarray}\\
\fbox{   
\begin{tikzpicture}
    \printarray[myarray=\tags,arrayformat={\tiny}, n=4]
\end{tikzpicture}}

\end{document}

我使用 TikZ-pgf 执行循环并处理数组,但我不认为这是问题。

请不要更改宏调用,而只修改宏内部。(为了更好地理解问题/解决方案,以下是解释漂亮的欢迎)

多谢!

答案1

据我所知,这个问题源于您在中的行\tiny中过早扩展了选项。在 之前添加以限制扩展似乎可以解决此问题(我最终得到了您的预期结果)。在调用中在 之前添加 也可以。我猜这是用于存储解析选项的方法的副产品(扩展为)。\protected@edef\formataux{\commandkey{arrayformat}};\printarray\expandafter\noexpand\command{arrayformat}\noexpandtinykeycommand\commandkey{arrayformat}\csname keycmd->printarray@arrayformat\endcsname

我建议使用,pgfkeys因为其行为更加直观和灵活。下面是您使用 实现的示例pgfkeys- 宏调用未经过修改,如所要求。在其中, 中的选项\printarray被解析,arrayformat直接存储在 中\formataux(即,\formataux扩展为\tiny,如预期的那样):

编辑:感谢@cfr 指出可以\pgfkeys在一次调用中全部定义,这是一种比(前者如果已经定义则会引发错误)\newcommand{\tags}更好的方法:\def\tags\tags

\documentclass{letter}
\usepackage{keycommand}
\usepackage{tikz}
\pgfkeys{/tikz/.cd,%
    myarray/.initial={"a","3.4","more", "Test"},
    myarray/.get=\tagsaux,
    myarray/.store in=\tagsaux,
    arrayformat/.initial={\small},
    arrayformat/.get=\formataux,
    arrayformat/.store in=\formataux,
    n/.initial=3,
    n/.get=\naux,
    n/.store in=\naux,
    submyarray/.initial={"a","3.4","$sin(90)+4$"},
    submyarray/.get=\subtagsaux,
    submyarray/.store in=\subtagsaux,
    subarrayformat/.initial={\small},
    subarrayformat/.get=\subformataux,
    subarrayformat/.store in=\subformataux,
    subn/.initial=3,
    subn/.get=\subnaux,
    subn/.store in=\subnaux}

\makeatletter
\newcommand{\printarray}[1][]{%
    \tikzset{#1}
    \subprintarray[submyarray=\tagsaux,subarrayformat=\formataux,subn=\naux]    
    }
\newcommand{\subprintarray}[1][]{%
    \tikzset{#1}
    \foreach \xpos in {1,2,...,\subnaux}{
        \path (1.5*\xpos, 1) node { \pgfmathparse{\subtagsaux[\xpos]}\pgfmathresult };
        \path (1.5*\xpos, 0) node { \subformataux \pgfmathparse{\subtagsaux[\xpos]}\pgfmathresult };
    }
}
\makeatother

\begin{document}
\newcommand{\tags}{{"ABC","b","$\sin(20)+4$","111","4","5","6","7"}}

Call to \texttt{\textbackslash subprintarray}\\
\fbox{
\begin{tikzpicture}
    \subprintarray[submyarray=\tags,subarrayformat={\small },subn=4]
\end{tikzpicture}}

Call to \texttt{\textbackslash printarray}\\
\fbox{   
\begin{tikzpicture}
    \printarray[myarray=\tags,arrayformat={\tiny }, n=4]
\end{tikzpicture}}

\end{document}

在此处输入图片描述

答案2

一些命令甚至无法存活\protected@edef,其中包括大小改变命令,这些命令不应该出现在移动参数中(移动参数是受\protected@edef或支配的参数\protected@write,通常是分段命令或标题)。

如果它们处于如此移动的参数中,则必须以 为前缀\protect

这是一个不同的策略,它可以避免keycommand其问题并加以利用expl3

\documentclass{letter}
\usepackage{xparse}
\usepackage{tikz}

\ExplSyntaxOn
\keys_define:nn { lbj/printarray }
 {
  myarray     .code:n      = \clist_set:No \l_lbj_printarray_myarray_clist { #1 },
  arrayformat .tl_set:N    = \l_lbj_printarray_arrayformat_tl,
  n           .int_set:N   = \l_lbj_printarray_n_int,
  myarray     .initial:n   = {"a","3.4","more", "Test"},
  arrayformat .initial:n   = \small,
  n           .initial:n   = 3,
 }
\keys_define:nn { lbj/subprintarray }
 {
  submyarray     .code:n      = \clist_set:No \l_lbj_printarray_submyarray_clist { #1 },
  subarrayformat .tl_set:N    = \l_lbj_printarray_subarrayformat_tl,
  subn           .int_set:N   = \l_lbj_printarray_subn_int,
  submyarray     .initial:n   = {"a","3.4","more", "$\sin(90)+4$"},
  subarrayformat .initial:n   = \small,
  subn           .initial:n   = 3,
 }

\NewDocumentCommand{\printarray}{ O{} }
 {
  \group_begin:
  \keys_set:nn { lbj/printarray } { #1 }
  \subprintarray[
   submyarray=\l_lbj_printarray_myarray_clist,
   subarrayformat=\l_lbj_printarray_arrayformat_tl,
   subn=\l_lbj_printarray_n_int,
  ]
  \group_end:
}

\NewDocumentCommand{\subprintarray}{ O{} }
 {
  \keys_set:nn { lbj/subprintarray } { #1 }
  \int_step_inline:nnnn {1} {1} {\l_lbj_printarray_subn_int}
   {
    \path (1.5*##1, 1) node {
      \strut
      \clist_item:Nn \l_lbj_printarray_submyarray_clist { ##1 }
    };
    \path (1.5*##1, 0) node {
      \l_lbj_printarray_subarrayformat_tl \strut
      \clist_item:Nn \l_lbj_printarray_submyarray_clist { ##1 }
    };
   }
 }
\ExplSyntaxOff

\begin{document}

\newcommand\tags{"ABC","b","$\sin(20)+4$","111","4","5","6","7"}

Call to \verb|\subprintarray|\\
\fbox{%
  \begin{tikzpicture}
    \subprintarray[submyarray=\tags,subarrayformat={\small },subn=4]
  \end{tikzpicture}}

Call to \verb|\printarray|\\
\fbox{%
  \begin{tikzpicture}
    \printarray[myarray=\tags,arrayformat={\tiny}, n=4]
  \end{tikzpicture}}

\end{document}

键是预先定义的,然后通过命令设置\keys_set:nn。您可以看到将值从 传递到 很容易\printarray\subprintarray此外,从 clist 变量中提取项目也比使用 更容易\pgfmathparse

\foreach可以使用\int_step_inline:nnnn没有特殊标记的;当前值只是用#1(它必须##1在这里因为它在定义内)表示。

在此处输入图片描述

相关内容