检测成对的嵌套宏

检测成对的嵌套宏

我创建了一个自动检测的宏\dif,定义为

\newcommand{\dif}{\mathrm{d}}

界定一个积分,在这种情况下,在积分的参数和之间\dif添加一个小空格。宏由以下代码给出

\makeatletter
\let\originalint\int
\def\int@arg{b}
\renewcommand\int{\@ifstar\originalint{\expandafter\myint}}
\def\myint{\let\int@opt\@empty\def\int@op{\originalint}%
    \int@test@opt}
\def\int@test@opt{\@ifnextchar[\int@option{\int@test}}
\def\int@option[#1]{\def\int@opt{#1}\int@test}
\def\int@test{\@ifnextchar\limits\int@catchlimits{\@ifnextchar_\int@catchsub{\@ifnextchar^\int@catchsup{\int@print}}}}
\def\int@catchlimits\limits{\expandafter\def\expandafter\int@op\expandafter{\int@op\limits}\int@test}
\def\int@catchsub_#1{\expandafter\def\expandafter\int@op\expandafter{\int@op_{#1}}\int@test}
\def\int@catchsup^#1{\expandafter\def\expandafter\int@op\expandafter{\int@op^{#1}}\int@test}
\def\int@print#1\dif#2{%
        \ifx\int@opt\@empty%
            \int@op%
        \else%
            \ifx\int@opt\int@arg%
                \expandafter\smashoperator\expandafter{\int@op}%
            \else%
                \expandafter\smashoperator\expandafter[\expandafter\int@opt\expandafter]\expandafter{\int@op}%
            \fi%
        \fi%
        #1 \, \dif #2   
}
\makeatother

当存在嵌套积分时,就会出现问题,例如

\begin{equation}
\int_1^{10} \int_{\{u = t\}} \vert\nabla u \vert \dif \sigma \dif t
\end{equation}

在这种情况下,代码产生以下输出

在此处输入图片描述

前面有两个空格\dif \sigma,前面没有空格\dif t。一个明显的解决方法是将内部积分分组

\begin{equation}
\int_1^{10} {\int_{\{u = t\}} \vert\nabla u \vert \dif \sigma} \dif t
\end{equation}

有什么方法可以自动完成吗?

答案1

\dif也许将宏机制传递的标记包装起来\@firstofone{...},从而将它们隐藏在处理\dif- 分隔参数的宏中,这样可以解决问题吗?

\documentclass{article}

\newcommand{\dif}{\mathrm{d}}

\makeatletter
\let\originalint\int
\def\int@arg{b}
\renewcommand\int{\@ifstar\originalint{\expandafter\myint}}
\def\myint{\let\int@opt\@empty\def\int@op{\originalint}%
    \int@test@opt}
\def\int@test@opt{\@ifnextchar[\int@option{\int@test}}
\def\int@option[#1]{\def\int@opt{#1}\int@test}
\def\int@test{\@ifnextchar\limits\int@catchlimits{\@ifnextchar_\int@catchsub{\@ifnextchar^\int@catchsup{\int@print}}}}
\def\int@catchlimits\limits{\expandafter\def\expandafter\int@op\expandafter{\int@op\limits}\int@test}
\def\int@catchsub_#1{\expandafter\def\expandafter\int@op\expandafter{\int@op_{#1}}\int@test}
\def\int@catchsup^#1{\expandafter\def\expandafter\int@op\expandafter{\int@op^{#1}}\int@test}
\def\int@print#1\dif#2{%
        \ifx\int@opt\@empty
            \int@op
        \else
            \ifx\int@opt\int@arg
                \expandafter\smashoperator\expandafter{\int@op}%
            \else
                \expandafter\smashoperator\expandafter[\expandafter\int@opt\expandafter]\expandafter{\int@op}%
            \fi
        \fi
        #1 \, \@firstofone{\dif}#2%
}

\begin{document}

\begin{equation}
\int_1^{10} \int_{\{u = t\}} \vert\nabla u \vert \dif \sigma \dif t
\end{equation}

\end{document}

在此处输入图片描述

\int实际上,当使用分隔参数进行操作时,如果嵌套积分,则和的配对\dif是错误的,但在某些情况下这可能不会影响视觉输出。

然而,没有办法自动检测一个标记是否\dif界定了积分的参数或者是积分参数的组成部分,因此会出现这样的情况,如果不隐藏在或\dif之间不界定积分参数的标记,你就无法逃脱。{...}\firstofone{...}

我对正在使用的 documentclass/preamble 等做了一些猜测。
最好提供一个最小可重复示例人们可以将其复制粘贴到新文件并进行编译以重现您获得的输出,而无需进行猜测和编辑。

答案2

通常的方法是使用\mathop这里让 TeX 根据前一项添加或不添加空格

在此处输入图片描述

\documentclass{article}

\usepackage{amsmath}

\newcommand\dif{\mathop{}\!d}

\begin{document}

\begin{equation}
\int_1^{10} \int_{\{u = t\}} \vert\nabla u \vert \dif \sigma \dif t
\end{equation}
\end{document}

或者,如果你真的必须,用直立的d

\newcommand\dif{\mathop{}\!\mathrm{d}}

在此处输入图片描述

相关内容