19

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 Answers1

20

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:

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}
Peter Grill
  • 223,288
  • @Qrrbrbirlbel: I think you are right (have corrected), but surprisingly PackageError does not issue a PackageError if 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
  • 1
    I normally just use \typeout{message}\QUITHERE, where \QUITHERE is not defined, but thought I would use the official way of reporting errors. Alternatively, you could use my preamble, or some other relevant text as the first parameter to \PackageError. – Peter Grill Nov 07 '12 at 01:58
  • 2
    @PeterGrill you can use \GenericError (four arguments). – Gonzalo Medina Nov 07 '12 at 02:01
  • 2
    You'll need to use \DeclareRobustCommand not \newcommand or 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 GenericError so that it does not appear to be a package error. – Peter Grill Nov 07 '12 at 02:20
  • @DavidCarlisle: Thanks, have updated solution. – Peter Grill Nov 07 '12 at 02:22
  • @PeterGrill The first argument (see macros2e.pdf) is for continuation text (to be invoked by the \MessageBreak command 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 \MessageBreak explicitly, 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 GenericError as 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