Define macros by using TikZ's \foreach
You can do without TikZ, and, what may be more important, avoid making the macros global. You can use the built-in \@for
macro instead.
\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}
There are many ways in which you may generalize this and/or make it more user-friendly. I do not know what the ultimate purpose will be, but this is to give you some idea.
\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}
The \foreach
function is meant for repetitive actions in TikZ pictures and has several drawbacks when employed elsewhere, the main one being that every cycle is performed in a group.
Here's a more general way to accomplish your needs; the defined macros can have as many arguments as you like (from none to nine, of course). In the fourth argument (the template) you denote by #1
the current item in the cycle and by ##1
, ##2
and so on the defined macro arguments.
\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}
Thanks to the comments of Phelype Oleinik and LaTeXer, the following solution has been build.
\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}