在循环中连接/附加到宏

在循环中连接/附加到宏

我查看了该论坛上的答案,这些答案确实使我更接近解决上述问题的方法,但是 via\xdef和 via两种方法都\g@addto@macro给出了错误或错误的结果。

我想要做的是定义一个带有可选参数的宏,该宏在循环中进行解析:输入\gttest[Mg=x,Fe=y,Ca=z]应该创建一个化学式,形式为 Mg_x Fe_y Ca_(1-xy);此处给出的空格和括号仅用于清晰起见,不会出现在实际输出中。以下是代码(.sty 文件的一部分):

\RequirePackage{xspace}
\RequirePackage{xstring}
\RequirePackage{ifthen}
\RequirePackage{fp-eval}
\RequirePackage{twoopt}
% preliminaries for the components
\newcommand{\@sublow}{\vphantom{A}}
\newcommand{\@chem}[2]{%
\ifthenelse{\equal{#2}{1}}{#1}{%
\ensuremath{\mathrm{#1}\@sublow_{#2}}}}
\newcommand{\@GCresb}{}
\newcommand{\@GCresc}{}
\newcommand{\@GCtmpa}{}
\newcommand{\@GCtmpb}{}
\newcommand{\@GCtmpc}{}
\newcommand{\@GCtmpd}{}
\newcounter{isscmp}
\newcounter{jsscmp}
\newcounter{lsscmp}
\newcounter{nsscmp}
% the actual macro
\newcommand{\gttest}[1][]{%
\StrCount{#1}{=}[\nsscmp]%
\setcounter{lsscmp}{\nsscmp}%
\setcounter{isscmp}{0}%
\setcounter{nsscmp}{1}%
\renewcommand{\@GCtmpa}{}%
\renewcommand{\@GCresc}{}%
\whiledo{\value{nsscmp}<\value{lsscmp}\OR\value{nsscmp}=\value{lsscmp}}{%
\ifthenelse{\value{nsscmp}<\value{lsscmp}}{%
\StrPosition[\thensscmp]{#1}{,}[\jsscmp]%
\StrMid{#1}{\value{isscmp}+1}{\numexpr\jsscmp-1}[\@GCtmpb]}{%
\StrGobbleLeft{#1}{\value{isscmp}}[\@GCtmpb]}%
\StrBefore{\@GCtmpb}{=}[\@GCtmpc]%
\StrBehind{\@GCtmpb}{=}[\@GCtmpd]%
\ifthenelse{\value{nsscmp}<\value{lsscmp}}{%
% all but last comp.: use given subscript and accumulate
\xdef\@GCresc{\@GCresc-\@GCtmpd}%
\renewcommand{\@GCresb}{\@chem{\@GCtmpc}{\@GCtmpd}}}{%
% last comp.: apply closure condition \sum x_i=1
\renewcommand{\@GCresb}{\@chem{\@GCtmpc}{1\@GCresc}}}%
\xdef\@GCtmpa{\@GCtmpa\@GCresb}% <-- causes Incomplete iffalse
%\g@addto@macro\@GCtmpa{\@GCresb}% <-- produces wrong result
\setcounter{isscmp}{\jsscmp}%
\stepcounter{nsscmp}}%
\@GCtmpa}

在这种形式下,代码会抛出一个错误:

!不完整 \iffalse;第 5 行之后的所有文本都被忽略。

\fi

<*> 我的测试

如果我用xdef<-- 注释掉标有符号的行,并用 取消注释掉下一行g@addto...,程序运行顺利,但结果是 Ca_(1-xy) Ca_(1-xy) Ca_(1-xy)

那么 - 为什么这不起作用?虽然参数被正确解析,但我不知道第一个变体中不完整的 if 子句在哪里,也不知道最后一个附加部分在第二个变体中如何重复三次。

答案1

在此处输入图片描述

我认为编码比实际需要的要复杂得多,这使得跟踪扩展变得更加困难。我认为测试可以简单得多,例如:

\documentclass{article}

\makeatletter

\newcommand{\@chem}[2]{%
\def\xtest{#1}%
\def\xtest{1}%
\mathrm{#1}%
\ifx\xtest\ytest\else\@sublow_{#2}\fi}

\newcommand{\@sublow}{\vphantom{A}}

\newcommand\gttest[1][]{\ensuremath{%
\gdef\chem@last{1}%
\@for\tmp:=#1\@empty\do{%
\expandafter\x@chem\tmp\relax
}}}

\def\last@test#1\@empty#2#3\@nil{#2}

\def\x@chem#1=#2\relax{%
\expandafter\ifx\expandafter!\last@test#2!\@empty?\@nil
\@chem{#1}\chem@last
\else
\g@addto@macro\chem@last{-#2}%
\@chem{#1}{#2}%
\fi}
\begin{document}


\gttest[Mg=x,Fe=y,Ca=z]
\end{document}

相关内容