在循环中用变量名定义新命令

在循环中用变量名定义新命令

我试图不写 26 行冗余代码;\magic它本身有效;但循环破坏了它

\usepackage{pgffor,amsfonts}
\newcommand{\magic}[1]{
  \expandafter\newcommand\csname b#1\endcsname{\mathbb{#1}}
  \expandafter\newcommand\csname c#1\endcsname{\mathcal{#1}}
  \expandafter\newcommand\csname f#1\endcsname{\mathfrak{#1}}   }
\foreach \x in {A,...,Z}{\magic{\x} }

答案1

理论上pgffor,通过添加一个 可以使其工作,\expandafter但定义是本地的,并且是在组中完成的,因此无法实现您想要的效果。因此,只需使用普通的 即可\loop

\documentclass{article}
\usepackage{amsfonts}
\newcommand{\magic}[1]{%
  \expandafter\newcommand\csname b#1\endcsname{\mathbb{#1}}%
  \expandafter\newcommand\csname c#1\endcsname{\mathcal{#1}}%
  \expandafter\newcommand\csname f#1\endcsname{\mathfrak{#1}}%  
}
\newcounter{iloop}  
\setcounter{iloop}{0}%
\loop
\stepcounter{iloop}%
\edef\pft{\Alph{iloop}}%
\expandafter\magic\pft%
\ifnum\value{iloop}<26\relax
\repeat
\begin{document}

$\bB$
\end{document}

在此处输入图片描述

不用说,如果您计划与他人合作并共享 TeX 文件,定义这样的宏不是一个好主意。

答案2

pgffor循环内部,需要发生两件事:需要在\x到达之前扩展\magic;并且里面的定义\magic需要是全局的,以突破 for 循环的范围。

我还删除了很多杂散的空间。

\documentclass{article}
\usepackage{pgffor,amsfonts}
\newcommand{\magic}[1]{%
  \expandafter\gdef\csname b#1\endcsname{\mathbb{#1}}%
  \expandafter\gdef\csname c#1\endcsname{\mathcal{#1}}%
  \expandafter\gdef\csname f#1\endcsname{\mathfrak{#1}}}
\begin{document}  
\foreach \x in {A,...,Z}{\expandafter\magic\expandafter{\x}}

$\bX \cB \fH$
\end{document}

在此处输入图片描述

答案3

不完美,但很简短..

\usepackage{amsfonts,dowith}
\newcommand{\magic}[1]{
  \expandafter\newcommand\csname b#1\endcsname{\mathbb{#1}}
  \expandafter\newcommand\csname c#1\endcsname{\mathcal{#1}}
  \expandafter\newcommand\csname f#1\endcsname{\mathfrak{#1}}   }
\DoWith\magic ABCDEFGHIJKLMNOPQRSTUVWXYZ\StopDoing

答案4

具有expl3良好的语法:

\documentclass{article}
\usepackage{amsfonts}
\usepackage{xparse}

\ExplSyntaxOn

\NewDocumentCommand{\magic}{m}
 {
  \prop_set_from_keyval:Nn \l_tmpa_prop { #1 }
  \int_step_inline:nnn { `A } { `Z }
   {
    \prop_map_inline:Nn \l_tmpa_prop
     {
      \cs_new_protected:cpx { ####1 \char_generate:nn { ##1 } { 11 } }
       {
        \exp_not:N ####2 { \char_generate:nn { ##1 } { 11 } }
       }
     }
   }
 }

\ExplSyntaxOff

\magic{b=\mathbb,c=\mathcal,f=\mathfrak}

\begin{document}

$\bA+\cF+\fG$

\end{document}

在此处输入图片描述

我们存储一个包含属性b=\mathbbc=\mathcal和 的属性列表f=\mathfrak。然后我们启动一个由大写字母的 ASCII 数字索引的循环,并使用这些属性来定义所需的控制序列。

在代码中##1代表循环中的当前整数、####1当前键和####2属性(在每个级别我们都需要将井号加倍)。

##1为 65 时(即 的 ASCII 码A),代码确实

\cs_new_protected:cpx { b \char_generate:nn { 65 } { 11 } }
 {
  \exp_not:N \mathbb { \char_generate:nn { 65 } { 11 } }
 }

对于c和也类似f。这相当于说

\cs_new_protected:Npn \bA { \mathbb { A } }

当然,也可以使用pgffor;您将无法检查命令是否尚存在。

\documentclass{article}
\usepackage{amsfonts}
\usepackage{pgffor}

\begingroup
\newcommand\makecommand[3]{%
  \expandafter\xdef\csname #1#2\endcsname{\noexpand#3{#2}}%
}
\foreach \x in {A,...,Z} {
  \makecommand{b}{\x}{\mathbb}
  \makecommand{c}{\x}{\mathcal}
  \makecommand{f}{\x}{\mathfrak}
}
\endgroup

\begin{document}

$\bA+\cF+\fG$

\end{document}

相关内容