使用 TikZ 的 \foreach 定义宏

使用 TikZ 的 \foreach 定义宏

我想对下面的代码进行一点分解。

\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

你可以不用 TiZ,更重要的是,避免将宏设为全局的。您可以改用内置\@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}

相关内容