我想通过 LaTex 中的一些计算使我的生活更轻松,因此我定义了一个复合特定变量,称为\compound1molarmass
。我用来\newcommand
从 调用另一个函数,chemmacros
所以我需要将 #1 设置为compound1
。要执行计算,我需要调用\compound1molarmass
,并且我想使用#1
从 来\newcommand
执行此操作。
因此类似于\csname #1molarmass\endcsname
这样的东西,以便它被解释为\compound1molarmass
。不幸的是,以下代码不起作用。
\documentclass{scrartcl}
\usepackage{calculator}
\def\compound1molarmass{2}
\newcommand{\cmpd}[2]{\DIVIDE{#2}{\csname #1molarmass\endcsname}{\res}\res}
\begin{document}
\cmpd{compound1}{4}
\end{document}
理想情况下,此代码将输出类似 2 的值。运行此代码会导致许多未定义的控制序列。
答案1
你真的不能\def\compound1molarmass
,因为宏名只能由字母(或单个非字母)组成。你可能做
\expandafter\def\csname compound1molarmass\endcsname{2}
但还有更好的方法。
我建议
- 不要使用
\def
; - 不要使用
calculator
。
关于 1,最好使用“名称”而不是宏;关于 2,LaTeX 内核(几乎)完全管理浮点表达式。
\documentclass{article}
\ExplSyntaxOn
% this substitutes your \def
\NewDocumentCommand{\definecompoundmass}{mm}
{% #1 = compound name, #2 = mass
\fp_zero_new:c { l_hugel_cmpd_#1_fp }
\fp_set:cn { l_hugel_cmpd_#1_fp } { #2 }
}
\NewExpandableDocumentCommand{\cmpd}{mom}
{% #1 = compound name, #2 = number of digits to round at, #3 = factor
\IfNoValueTF { #2 }
{% no rounding
\fp_eval:n { (#3)/\fp_use:c { l_hugel_cmpd_#1_fp } }
}
{% rounding
\fp_eval:n { round( (#3)/\fp_use:c { l_hugel_cmpd_#1_fp } , #2 ) }
}
}
\ExplSyntaxOff
\definecompoundmass{compound1}{2}
\definecompoundmass{compound2}{3.12344}
\begin{document}
\cmpd{compound1}{4} % no rounding
\cmpd{compound2}{3} % no rounding
\cmpd{compound2}[2]{3} % round at two digits
\end{document}
存储质量的变量的分配对于它们出现的组来说是本地的,但是我相信最好在序言中定义它们,这样您就可以轻松找到它们。
答案2
\def\compound1molarmass{2}
定义控制字标记\compound由字符标记分隔并扩展为字符标记。112m11o11l11a11r11m11a11s11s11212
因此,由于-expression产生了未定义的控制字标记,因此\csname #1molarmass\endcsname
无法正常工作。#1
compound1
\csname..\endcsname
\compound1molarmass
大卫·卡莱尔建议您可以使用\ExpandArgs
/在定义/使用控制字标记之前,用\UseName
形成其名称的字符标记构造控制字标记:\compound1molarmass
\documentclass{scrartcl}
\usepackage{calculator}
%\ExplSyntaxOn
%\cs_new_eq:NN \UseName \use:c
%\cs_new:Npn \ExpandArgs #1
% {
% \cs_if_exist_use:cF { exp_args:N #1 }
% { \msg_expandable_error:nnn { kernel } { unknown-arg-expansion } {#1} }
% }
%\msg_new:nnn { kernel } { unknown-arg-expansion }{ Unknown~arg~expansion~"#1" }
%\ExplSyntaxOff
\ExpandArgs{Nc}\newcommand*{compound1molarmass}{2}
%\newcommand{\cmpd}[2]{\DIVIDE{#2}{\csname #1molarmass\endcsname}{\res}\res}
\newcommand{\cmpd}[2]{\DIVIDE{#2}{\UseName{#1molarmass}}{\res}\res}
%\newcommand{\cmpd}[2]{\ExpandArgs{nc}\DIVIDE{#2}{#1molarmass}{\res}\res}
\begin{document}
\cmpd{compound1}{4}
\end{document}