如果宏或参数(比如#1
)包含一些字符串,比如,我可以使用类似以下方法Mystring
创建宏:\PrefixMystring{}{}
\expandafter\newcommand\csname Prefix#1\endcsname[2]{
the arguments are ##1 and ##2
}
我想做一些类似的事情\NewExpandableDocumentCommand
,正确的做法是什么?
\documentclass[]{article}
\begin{document}
%% \createNewAnimal{Cat}{Miaou} should create a new command \helloCat{Bob} outputting "Miaou Bob".
\NewDocumentCommand{\createNewAnimal}{mm}{
%%% How can I do the same with NewExpandableDocumentCommand instead of newcommand?
\expandafter\newcommand\csname hello#1\endcsname[1]{
#2 ##1.
}
}
\createNewAnimal{Cat}{Miaou}
\createNewAnimal{Dog}{Woooof}
\helloCat{Bob}
\helloDog{Alice}
\end{document}
编辑
哦,事实上,在我的测试中,上述方法失败了\NewExpandableDocumentCommand
...但原因是我在参数周围添加了括号,例如:\expandafter\NewExpandableDocumentCommand{\csname zx#2\endcsname}{}{…}
而不是\expandafter\NewExpandableDocumentCommand\csname zx#2\endcsname{}{…}
,这导致了错误:
ERROR: LaTeX cmd Error: First argument of '\NewExpandableDocumentCommand' must be a command
问题解决:
\documentclass[]{article}
\begin{document}
%% \createNewAnimal{Cat}{Miaou} should create a new command \helloCat{Bob} outputting "Miaou Bob".
\NewDocumentCommand{\createNewAnimal}{mm}{
%%% How can I do the same with NewExpandableDocumentCommand instead of newcommand?
\expandafter\NewDocumentCommand\csname hello#1\endcsname{m}{
#2 ##1.
}
}
\createNewAnimal{Cat}{Miaou}
\createNewAnimal{Dog}{Woooof}
\helloCat{Bob}
\helloDog{Alice}
\end{document}
答案1
我认为\ExpandArgs
这是有可能的(但我不知道是否有更好的选择)。
\documentclass[]{article}
\begin{document}
%% \createNewAnimal{Cat}{Miaou} should create a new command \helloCat{Bob} outputting "Miaou Bob".
\NewDocumentCommand{\createNewAnimal}{mm}{%
\ExpandArgs{c}\NewExpandableDocumentCommand{hello#1}{m}{#2 ##1.}%
}
\createNewAnimal{Cat}{Miaou}
\createNewAnimal{Dog}{Woooof}
\helloCat{Bob}
\helloDog{Alice}
\end{document}
答案2
我建议使用通用宏工厂。
\documentclass{article}
\ExplSyntaxOn
\NewDocumentCommand{\NewPrefixedDocumentCommand}{mmmm}
{% #1 = prefix
% #2 = added part
% #3 = argument list
% #4 = replacement text
\tobiasbora_prefixed:Nnnnn \NewDocumentCommand { #1 } { #2 } { #3 } { #4 }
}
\NewDocumentCommand{\NewPrefixedExpandableDocumentCommand}{mmmm}
{% #1 = prefix
% #2 = added part
% #3 = argument list
% #4 = replacement text
\tobiasbora_prefixed:Nnnnn \NewExpandableDocumentCommand { #1 } { #2 } { #3 } { #4 }
}
\cs_new_protected:Nn \tobiasbora_prefixed:Nnnnn
{
\exp_args:Nc #1 { #2 #3 } { #4 } { #5 }
}
\ExplSyntaxOff
% test for the generic function
\NewPrefixedDocumentCommand{Prefix}{Test}{mm}{Do something with #1 and #2}
% test for your use case
\NewDocumentCommand{\createNewAnimal}{mm}{%
\NewPrefixedDocumentCommand{hello}{#1}{m}{#2 ##1.}%
}
\createNewAnimal{Cat}{Miaou}
\createNewAnimal{Dog}{Woooof}
\begin{document}
\PrefixTest{A}{B}
\helloCat{Bob}
\helloDog{Alice}
\end{document}
在这些特殊情况下您可能还会使用\NewPrefixedExpandableDocumentCommand
,但请小心:使用Expandable
不会应用某种魔法使本来不可扩展的东西变得可扩展。
答案3
您可以简单地使用 TeX 原语来解决您的“动物问题”:
\def\createNewAnimal#1#2{\expandafter\def\csname hello#1\endcsname##1{#2 ##1}}
\createNewAnimal{Cat}{Miaou}
\createNewAnimal{Dog}{Woooof}
\helloCat{Bob} % prints: Miaou Bob
\helloDog{Alice} % prints: Woooof Alice