我想对下面的代码进行一点分解。
\documentclass[12pt]{article}
\usepackage{tikz}
\newcommand\testabove[1]{above #1}
\newcommand\testbelow[1]{below #1}
\newcommand\testright[1]{right #1}
\newcommand\testleft[1]{left #1}
\begin{document}
\testabove{A} ;
\testbelow{B} ;
\testright{C} ;
\testleft{D}
\end{document}
我的想法是使用\foreach
循环,tikz
但以下几行代码是错误的。我确信我需要使用,\expandafter
但我的任何尝试都没有奏效。
我可以调整下面的几行来获得我的因式分解吗?
\foreach \kind in {above, below, right, left}{
\newcommand\csname test\kind\endcsname[1]{\kind #1}
}
使用\expandafter\gdef\csname test\kind\endcsname##1{kind ##1}
定义了四个宏,但不是正确的宏,因为我没有使用{\kind ##1}
。
确实\expandafter\gdef\csname test\kind\endcsname##1{\kind ##1}
给出了错误信息Undefined control sequence \testabove #1->\kind
。
我怎样才能使其\kind
扩展{\kind ##1}
?
答案1
你可以不用 Ti钾Z,更重要的是,避免将宏设为全局的。您可以改用内置\@for
宏。
\documentclass{article}
\makeatletter
\@for\next:={above,below,right,left}\do{%
\expandafter\edef\csname test\next\endcsname#1{\next #1}}
\makeatother
\begin{document}
\testabove{A}
\testbelow{B}
\testright{C}
\testleft{D}
\end{document}
您可以通过多种方式将其概括化和/或使其更加用户友好。我不知道最终目的是什么,但这可以为您提供一些想法。
\documentclass{article}
\makeatletter
\newcommand{\MultiDef}[3][]{\@for\next:=#3\do{%
\expandafter\edef\csname #2\next\endcsname##1{#1{\next} ##1}}}
\makeatother
\begin{document}
\MultiDef{test}{above,below,right,left}
\testabove{A}
\testbelow{B}
\testright{C}
\testleft{D}
\MultiDef[hibernate ]{pft}{above,below,right,left}
\pftabove{A}
\pftbelow{B}
\pftright{C}
\pftleft{D}
\end{document}
答案2
该\foreach
功能用于 Ti 中的重复操作钾Z 图片在其他地方使用时有几个缺点,最主要的是每个循环都是以组的形式执行的。
这是满足您需求的更通用的方法;定义的宏可以有任意数量的参数(当然,从零到九个)。在第四个参数(模板)中,您用 表示#1
循环中的当前项,用表示##1
,##2
依此类推,定义宏的参数。
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\batchdefine}{mO{0}mm}
{% #1 is the prefix
% #2 (default 0) is the number of arguments
% #3 is a comma separated list
% #4 is the template
\clist_map_inline:nn { #3 }
{
\projetmbc_batchdefine:cnn { #1 ##1 } { #2 } { #4 }
}
}
\cs_new_protected:Nn \projetmbc_batchdefine:Nnn
{
\newcommand{#1}[#2]{#3}
}
\cs_generate_variant:Nn \projetmbc_batchdefine:Nnn { c }
\ExplSyntaxOff
\batchdefine{test}[1]{
above, below, right, left
}{#1 ##1}
\batchdefine{TEST}[2]{
above, below, right, left
}{##1 #1 ##2}
\begin{document}
\testabove{a} \testbelow{b} \testright{r} \testleft{l}
\TESTabove{a}{A} \TESTbelow{b}{B} \TESTright{r}{R} \TESTleft{l}{L}
\end{document}
答案3
感谢 Phelype Oleinik 和 LaTeXer 的评论,我们构建了以下解决方案。
\documentclass[12pt]{article}
\usepackage{tikz}
\foreach \kind in {above,below,right,left}{
\expandafter\xdef\csname test\kind\endcsname##1{\kind ##1}
}
\begin{document}
\testabove{A} ;
\testbelow{B} ;
\testright{C} ;
\testleft{D}
\end{document}