在给定范围内更新辅助命令的命令:关于设计的问题

在给定范围内更新辅助命令的命令:关于设计的问题

我的问题是关于重新定义其他辅助命令的命令的设计。为了提出我的问题,我需要给出一个小的设置来描述我的意思。让我们从我的个人序言中取出一些辅助命令,并针对这个问题进行一些小的修改:

\DeclarePairedDelimiter{\parenth}{(}{)}

\providecommand{\intvar}{}
\ProvideDocumentCommand{\integral}{s m m e{_^}}{%
    \renewcommand{\intvar}{#2}
    \int%
    \IfValueT{#4}{_{#4}}%
    \IfValueT{#5}{^{#5}}%
    \IfBooleanTF{#1}{\parenth*{#3}}{#3}%
    \odif{#2}%
}

\ProvideDocumentCommand{\fourier}{s m m m E{_^}{{-\infty}{\infty}}}{%
    \IfBooleanTF{#1}{%
        \integral*{#2}{{#4}e^{-2\pi i{#2}{#3}}}_{#5}^{#6}%
    }{%
        \integral{#2}{{#4}e^{-2\pi i{#2}{#3}}}_{#5}^{#6}%
    }%
}

为了省去您解读命令的麻烦,它们采用 和 的形式\integral{variable}{body}_{from}^{to}\fourier{var from}{var to}{body}_{from}^{to}其中下标和上标是可选的。现在,请注意我对命令 的使用\intvar。为了回答这个问题,我已将其添加到\integral命令定义中。其目的是允许用户获取积分的积分变量。例如:

\begin{gather*}
    \integral{x}{f(\intvar) g(\intvar)}_{0}^{1}\\
    \fourier{t}{\xi}{f(\intvar)}
\end{gather*}

给我们:

如果我们改变积分变量,但不改变主体:

\begin{gather*}
    \integral{z}{f(\intvar) g(\intvar)}_{0}^{1}\\
    \fourier{\theta}{\xi}{f(\intvar)}
\end{gather*}

我们得到了预期的结果:

因此,我的问题涉及这样的情况,您可以\integral在另一个\integral命令(或派生命令,例如\fourier)中使用 。这样做显然意味着 会\intvar像预期的那样接受该“级别”的变量。例如:

\begin{gather*}
    \integral{x}{f(\intvar)\integral{y}{g(\intvar)}}
\end{gather*}

给予:

但是,此代码仍然相当危险,并且可能会产生文档永远无法编译的情况。例如,此处\intvar永远无法编译:\integral{x}{\fourier{\intvar}{...}{...}}因为它尝试将的值设置\intval\intval,然后是递归的。(如何处理才能使这种情况永远不会发生?)

我的问题是:如何正确编写带有此类内部定义命令的宏?说实话,我从未想过需要这样做。但这个例子很有趣,我想到了很多,希望能了解更多。

这是通过更仔细的设计考虑和测试来实现的,还是通过更高级的 expl3 来实现的?是否有可帮助完成此类任务的软件包?

此外,您能否设计一个可以\intvar从更高级别引用的案例?例如,如果我想引用当前积分范围周围的积分的积分变量。在这种情况下,\intvar只会引用该范围的积分变量。这是可以毫不费力完成的事情吗?如果是这样,人们会如何定义这样的命令(例如,他们使用什么工具:包、低级宏等)?还有其他需要考虑的因素吗?

答案1

使用分组。

还可以减少代码重复。

\documentclass{article}
\usepackage{mathtools}

\newcommand{\odif}{\mathop{}\!d}
\DeclarePairedDelimiter{\parenth}{(}{)}

\providecommand{\intvar}{}
\NewDocumentCommand{\integral}{s m m e{_^}}{%
    \begingroup
    \renewcommand{\intvar}{#2}%
    \int
    \IfValueT{#4}{_{#4}}%
    \IfValueT{#5}{^{#5}}%
    \IfBooleanTF{#1}{\parenth*{#3}}{#3}%
    \odif#2%
    \endgroup
}

\NewDocumentCommand{\fourier}{s m m m E{_^}{{-\infty}{\infty}}}{%
    \expanded{\integral\IfBooleanT{#1}{*}}%
    {#2}{{#4}e^{-2\pi i{#2}{#3}}}_{#5}^{#6}%
}

\begin{document}

\begin{gather*}
    \integral{x}{f(\intvar) g(\intvar)}_{0}^{1} \\
    \fourier{t}{\xi}{f(\intvar)} \\
    \integral{x}{f(\intvar)\integral{y}{g(\intvar)}} \\
    \integral*{x}{f(\intvar) + g(\intvar)}_{0}^{1} \\
    \fourier*{t}{\xi}{f(\intvar)} \\
    \integral{x}{f(\intvar)\integral*{y}{g(\intvar)+2}}
\end{gather*}

\end{document}

在此处输入图片描述

然而,我不建议\parenth*随意使用。

相关内容