我想测试两个宏是否具有相同的定义。我天真的尝试\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
这两个宏在 和 方面具有相同的状态,
\long
但\outer
处理 LaTeX 时我们可以将这一点放在一边两个宏都有相同的参数文本
两个宏都有相同的替换文本
这应该是首选,因为它是 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 给出了“相同”的结果,而它们不应该如此。