人们!
我想将字母格式(即)作为调用另一个宏的\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}
\noexpand
tiny
keycommand
\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
在这里因为它在定义内)表示。