\csname if... 在 for 循环中

\csname if... 在 for 循环中

有人可以解释一下这里出了什么问题吗:

\newcommand\@doctypes{apple,banana,pineapple}

\@for\@doctype:=\@doctypes\do{%
  \expandafter\newif\csname if\@doctype\endcsname
  \expandafter\def\csname\@doctype\endcsname#1{%
    \csname if\@doctype\endcsname#1\fi%
  }
}

它会产生一个Argument of \@fornoop has an extra }错误

没有 for 循环也能正常工作

\def\@doctype{apple}

\expandafter\def\csname\@doctype\endcsname#1{%
  \csname if\@doctype\endcsname#1\fi%
}

编辑:是否可以在循环中声明选项?

\newcommand*\@doctypes{apple,banana,pineapple}

\@for\@doctype:=\@doctypes\do{%
  \expandafter\newif\csname if\@doctype\endcsname
  \expandafter\edef\csname\@doctype\endcsname#1{%
    \expandafter\noexpand\csname if\@doctype\endcsname#1%
    \expandafter\noexpand\csname fi\endcsname%
  }
  \DeclareOption{\@doctype}{%
    \setdoctype{\@doctype}
  }
}

\newcommand*\setdoctype[1]{%
  \@for\@doctype:=\@doctypes\do{%
    \csname\@doctype false\endcsname
  }
  \csname#1true\endcsname
}

答案1

替换文本中的某些内容\fi不平衡\if...,因此会混淆循环代码。

您可以执行\csname fi\endcsname,这样\fi就不会被看到;使用\edef和扩展控制,您可以获得所需的替换文本。

\makeatletter
\newcommand\@doctypes{apple,banana,pineapple}

\@for\@doctype:=\@doctypes\do{%
  \expandafter\newif\csname if\@doctype\endcsname
  \expandafter\edef\csname\@doctype\endcsname#1{%
    \expandafter\noexpand\csname if\@doctype\endcsname
      #1%
    \expandafter\noexpand\csname fi\endcsname
  }%
}
\makeatother

如果你这样做\show\apple,你会得到

> \apple=macro:
#1->\ifapple #1\fi .

以下是声明选项的方案:

\ProvidesPackage{timt}

\newcommand*\timt@doctypes{apple,banana,pineapple}

\@for\timt@doctype:=\timt@doctypes\do{%
  \expandafter\newif\csname if\timt@doctype\endcsname
  \expandafter\edef\csname\timt@doctype\endcsname#1{%
    \expandafter\noexpand\csname if\timt@doctype\endcsname
      #1%
    \expandafter\noexpand\csname fi\endcsname
  }
  \begingroup\edef\x{\endgroup
    \noexpand\DeclareOption{\timt@doctype}{%
      \noexpand\setdoctype{\timt@doctype}%
    }
  }\x
}

\newcommand*\setdoctype[1]{%
  \@for\timt@doctype:=\timt@doctypes\do{%
    \csname\timt@doctype false\endcsname
  }%
  \csname#1true\endcsname
}

\ProcessOptions\relax

测试文档是

\documentclass{article}
\usepackage[banana]{timt}

\begin{document}

\show\ifapple
\show\ifbanana
\show\ifpineapple

这些问题

> \ifapple=\iffalse.
l.6 \show\ifapple

? 
> \ifbanana=\iftrue.
l.7 \show\ifbanana

? 
> \ifpineapple=\iffalse.
l.8 \show\ifpineapple

相关内容