如何测试两个宏是否具有相同的定义

如何测试两个宏是否具有相同的定义

我想测试两个宏是否具有相同的定义。我天真的尝试\detokenize似乎在这种简单情况下不起作用。但是,我以前使用过类似的方法,它似乎在更复杂的案例中有效,但现在它在这个简单的测试案例中失败了,我有点困惑:

在此处输入图片描述

由于\meaning和相同\iff\MyIffWithDotsbNonStar我期望它们匹配。

相关(但不同):

平均能量损失

\documentclass{article}
\usepackage{mathtools}
\usepackage{xstring}
\usepackage{xcolor}
\usepackage{bm}% only for highlighting thre cross
\usepackage{amssymb}% only for checkmark symbol
\usepackage[paperwidth=10in]{geometry}% for better display of output

\newcommand{\MyIffWithDotsbNonStar}{\DOTSB\;\Longleftrightarrow \;}
\newcommand{\MyIffWithoutDotsbNonStar}{\;\Longleftrightarrow \;}

\newcommand*{\MyIffWithDotsbStar}{\DOTSB\;\Longleftrightarrow \;}
\newcommand*{\MyIffWithoutDotsbStar}{\;\Longleftrightarrow \;}

\newcommand*{\OK}{\textcolor{blue}{\checkmark}}
\newcommand*{\NotOK}{\textcolor{red}{\pmb{$\times$}}}

\newcommand{\MacrosHaveSameDefintiion}[4]{%
    % #1 = macros 1
    % #2 = macros 2
    % #3 = code to execute if macros are identical
    % #4 = code to execute if macros differ
    Macros \texttt{\string#1} and \texttt{\string#2} are
    \IfStrEq{\detokenize{#1}}{\detokenize{#2}}{#3}{#4}%
}%

\begin{document}
\par \verb|\iff|: \texttt{\meaning\iff}
\par \verb|\MyIffWithDotsbNonStar|: \texttt{\meaning\MyIffWithDotsbNonStar}
\medskip

\par\MacrosHaveSameDefintiion{\iff}{\iff}{identical}{different}  \OK

\par\MacrosHaveSameDefintiion{\iff}{\MyIffWithDotsbNonStar}{identical}{different} \NotOK
\par\MacrosHaveSameDefintiion{\iff}{\MyIffWithoutDotsbNonStar}{identical}{different} \OK

\par\MacrosHaveSameDefintiion{\iff}{\MyIffWithDotsbStar}{identical}{different} \OK
\par\MacrosHaveSameDefintiion{\iff}{\MyIffWithoutDotsbStar}{identical}{different} \OK

\end{document}

答案1

这个条件语句\ifx正是你想要的。如果你这样做

\ifx\macroA\macroB

其中和\macroA都是\macroB宏(由\def、、定义,或为以此方式定义的宏),则如果满足以下所有条件,则返回 true \gdef\edef\xdef\let\ifx

  1. 这两个宏在 和 方面具有相同的状态,\long\outer处理 LaTeX 时我们可以将这一点放在一边

  2. 两个宏都有相同的参数文本

  3. 两个宏都有相同的替换文本

这应该是首选,因为它是 TeX 原语。测试

\ifx\iff\iff
\ifx\iff\MyIffWithDotsbNonStar

都返回 true。然而,

\ifx\iff\MyIffWithDotsbStar

将返回 false,因为\iff\long\MyIffWithDotsbStar不是。

您的测试失败,因为您没有扩展宏,因此您正在比较由

\detokenize{\iff}

\detokenize{\MyIffWithDotsbNonStar}

这显然是不同的。如果添加\expandafter,则测试应返回 true。

\documentclass{article}
\usepackage{mathtools}
\usepackage{xstring}
\usepackage{xcolor}
\usepackage{bm}% only for highlighting thre cross
\usepackage{amssymb}% only for checkmark symbol
\usepackage[paperwidth=10in]{geometry}% for better display of output

\newcommand{\MyIffWithDotsbNonStar}{\DOTSB\;\Longleftrightarrow \;}
\newcommand{\MyIffWithoutDotsbNonStar}{\;\Longleftrightarrow \;}

\newcommand*{\MyIffWithDotsbStar}{\DOTSB\;\Longleftrightarrow \;}
\newcommand*{\MyIffWithoutDotsbStar}{\;\Longleftrightarrow \;}

\newcommand*{\OK}{\textcolor{blue}{\checkmark}}
\newcommand*{\NotOK}{\textcolor{red}{\pmb{$\times$}}}

\newcommand{\MacrosHaveSameDefintiion}[4]{%
    % #1 = macros 1
    % #2 = macros 2
    % #3 = code to execute if macros are identical
    % #4 = code to execute if macros differ
    Macros \texttt{\string#1} and \texttt{\string#2} are
    \IfStrEq{\detokenize\expandafter{#1}}{\detokenize\expandafter{#2}}{#3}{#4}%
}%

\begin{document}
\par \verb|\iff|: \texttt{\meaning\iff}
\par \verb|\MyIffWithDotsbNonStar|: \texttt{\meaning\MyIffWithDotsbNonStar}
\medskip

\par\MacrosHaveSameDefintiion{\iff}{\iff}{identical}{different}  \OK

\par\MacrosHaveSameDefintiion{\iff}{\MyIffWithDotsbNonStar}{identical}{different} \NotOK
\par\MacrosHaveSameDefintiion{\iff}{\MyIffWithoutDotsbNonStar}{identical}{different} \OK

\par\MacrosHaveSameDefintiion{\iff}{\MyIffWithDotsbStar}{identical}{different} \OK
\par\MacrosHaveSameDefintiion{\iff}{\MyIffWithoutDotsbStar}{identical}{different} \OK

\end{document}

在此处输入图片描述

但这似乎是用大锤打死苍蝇。测试结果为假阳性:测试 2 和 4 给出了“相同”的结果,而它们不应该如此。

相关内容