![Latex でのアサーション](https://rvso.com/image/305761/Latex%20%E3%81%A7%E3%81%AE%E3%82%A2%E3%82%B5%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3.png)
私は長いLaTeX文書を書いていて、数学記号を定義するために多くのマクロを使っています。表記が衝突しないようにしたいのです。例えば、次のようなものです。
\newcommand{\symbolone}{A}
\newcommand{\symboltwo}{A}
起こるはずがありません。LaTeXでアサーションのようなものはありますか?
\assert{\symbolone != \symboltwo}
?
答え1
\singledef
私のソリューションでは、制御シーケンス ( など) を定義するマクロを導入しています\def
が、さらに 2 つの機能も提供しています。
- 制御シーケンスが定義されているかどうかを確認します。定義されている場合は、エラー メッセージが印刷され、制御シーケンスは元の意味を保持します。
- 定義された制御シーケンスの名前を
\singledeflist
内部マクロに保存します。次の制御シーケンスが を介して定義されると、それが定義されますが、同じ制御シーケンス ( を介して同等) が で定義され保存されている\singledef
かどうかがチェックされます。そうである場合、エラー メッセージが印刷され、新しい制御シーケンスは未定義のままになります。\ifx
\singledeflist
コード:
\def\singledeflist{}
\def\singledef#1{%
\ifx#1\undefined
\def\next{\singledefA#1}%
\afterassignment\next
\expandafter\def\expandafter#1%
\else
\errmessage{The \string#1 is defined already}%
\expandafter\def\expandafter\tmp
\fi
}
\def\singledefA#1{\def\next{\singledefB#1}\expandafter\next\singledeflist\end}
\def\singledefB#1#2{%
\ifx#2\end
\expandafter\def\expandafter\singledeflist\expandafter{\singledeflist#1}%
\else
\ifx#1#2%
\errmessage{The \string#1 is the same as \string#2}%
\let#1=\undefined
\singledefC
\fi
\expandafter\next
\fi
}
\def\singledefC#1\end{\fi\fi}
\singledef\A{aha} % this is like \def\A{aha}
\singledef\B{bha} % this is like \def\B{bha}
\singledef\C{bha} % this prints the error: The \C is the same as \B
答え2
@egregは、完全に展開された2つの文字列を比較する方法を示しました(完全に展開された2つの文字列が等しいかどうかをテストする場合)、ここで彼のテクニックを適用することができます。
シンボルを再利用する場合に備えてエラー メッセージを追加しました。
\documentclass{article}
\usepackage{pdftexcmds}
\newcommand{\symbolI}{A}
\newcommand{\symbolII}{\pi r^2}
\newcommand{\symbolIII}{\pi r^2}
\makeatletter
\newcommand{\TestSameSymbols}[2]{%
\ifnum\pdf@strcmp{#1}{#2}=\z@
\typeout{%
ERROR: \noexpand#2 (#2) is the same as \noexpand#1.%
}
\fi%
}
\makeatother
\begin{document}
\TestSameSymbols{\symbolI}{\symbolII}
\TestSameSymbols{\symbolII}{\symbolIII}
\[ \symbolI = \symbolII \]
\end{document}