I have defined a macro that I would like to be used exclusively in math mode. In order to enforce this, I would like the macro to throw an error message whenever it is used outside of math mode. What is the easiest way of making a macro math-mode-only?
1 Answers
You can use \ifmmode to check if you are in math mode, and trigger an error if not. An attempt to use it outside of math mode yields:
Attempt to use \MyMathModeMacro outside of math mode.
See my preamble documentation for explanation.
Type H for immediate help.
l.16 \MyMathModeMacro % <--- This will produce an error ?
Notes:
As David Carlisle pointed out, need to use
\DeclareRobustCommandinstead of\newcommandto avoid premature expansion. See \ifmmode doesn't seem to work correctly inside an array environment.If you want to allow the macro to be used in or outside of math mode, you can use
\ensuremathto typeset the content in math mode. But you should refer to When not to use \ensuremath for math macro? before doing this.
Code:
\documentclass{article}
\makeatletter
\DeclareRobustCommand{\MyMathModeMacro}{%
\ifmmode
E = m c^2
\else
\GenericError{\space\space\space\space}
{Attempt to use \@backslashchar MyMathModeMacro outside of math mode}
{See my preamble documentation for explanation.}
{Need to use either use inline or display math.}%
\fi
}
\makeatother
\begin{document}
$\MyMathModeMacro$
\MyMathModeMacro% <--- This will produce an error
\end{document}
- 223,288
-
@Qrrbrbirlbel: I think you are right (have corrected), but surprisingly
PackageErrordoes not issue aPackageErrorif it does not get 3 parameters?? – Peter Grill Nov 07 '12 at 01:51 -
@PeterGrill That was fast! I am wondering, is there a way of throwing an error in a way that doesn't make it look package-specific? (I might simply have defined this macro in my preamble.) – Lover of Structure Nov 07 '12 at 01:55
-
1I normally just use
\typeout{message}\QUITHERE, where\QUITHEREis not defined, but thought I would use the official way of reporting errors. Alternatively, you could usemy preamble, or some other relevant text as the first parameter to\PackageError. – Peter Grill Nov 07 '12 at 01:58 -
2
-
2You'll need to use
\DeclareRobustCommandnot\newcommandor you will get the wrong answer at the start of array cells. – David Carlisle Nov 07 '12 at 02:05 -
@user14996: Have updated to use
GenericErrorso that it does not appear to be a package error. – Peter Grill Nov 07 '12 at 02:20 -
-
@PeterGrill The first argument (see macros2e.pdf) is for continuation text (to be invoked by the
\MessageBreakcommand within the other arguments, as I understand). – Lover of Structure Nov 07 '12 at 09:09 -
@user14996: Thanks. Have replaced that with spaces. Anything better you can think of to put in there? – Peter Grill Nov 07 '12 at 09:45
-
@PeterGrill Hmm, I'm new to this, but I thought that one can simply leave the first argument empty: unless I use
\MessageBreakexplicitly, the first argument won't be invoked. But do correct me if I'm wrong. – Lover of Structure Nov 07 '12 at 10:01 -
I am new to
GenericErroras well. But from the doc you provided, having it there should not a problem. In case one decides to expand the message and add a\MessageBreak, then it is all ready to go. – Peter Grill Nov 07 '12 at 10:03
\ifmmode, or useensuremathso that it'll be in math mode. – Peter Grill Nov 07 '12 at 01:44