# How to use \edef to wrap an existing macro with @inmatherr?

I have a handful of existing macros that I want to wrap in some custom processing. Here's an example of the kind of thing I'm aiming to do:

\makeatletter
\let\olddag\textdagger
\renewcommand\textdagger{\@inmatherr\textdagger \olddag}
\makeatother


Then if were to try to use $\textdagger$, I'd get a error, rather than the existing behavior of typesetting nothing appropriate. However, \textdagger in regular text mode will fall through to its existing definition.

My question is, how can I achieve the same effect but without making the assignment to the intermediate command \olddag? I suspect there would be some voodoo using \edef and/or \expandafter that would enable me to expand:

{\@inmatherr\textdagger \textdagger}


or perhaps:

{\noexpand\@inmatherr\noexpand\textdagger \textdagger}


at definition time, so that when I invoke \textdagger in the body of my document, I don't get a TeX stack overflow. But I haven't yet been able to find what it is.

These other questions (and answers) may be relevant:

But I haven't yet been able to piece together a solution from them. I guess it's no news that LaTeX's order-of-evaluation rules aren't that transparent.

-

\documentclass{article}

\makeatletter

\expandafter
\renewcommand
\expandafter\textdagger
\expandafter{%
\expandafter\@inmatherr
\expandafter\textdagger
\textdagger}

\makeatoher

\begin{document}

\textdagger $\textdagger$

\end{document}


The above shows the general technique but in this case you already get a warning, \textdagger by default makes

LaTeX Warning: Command \textdagger invalid in math mode on input line 8.


so an alternative would be to redefine that warning command to be an error.

-
Perfect, that's just what I was looking for. And yes, I just cared about the general technique, not this particular case. But in fact my regular workflow (Markdown source -- Pandoc --> pdflatex --> output) doesn't show me the warnings. –  dubiousjim Jul 4 at 22:26
@dubiousjim add grep -i warning *.log to the end of that pipeline :-) –  David Carlisle Jul 4 at 22:31
Two questions: (i) Can you explain what the third \expandafter (the one just before the {) is doing? I don't understand why it is needed. (Is the { parsed as just another token, like \renewcommand? so we have to skip over it too?) (ii) Is there some translation of this solution using \edef instead? If there is, that would help me understand better how \edef and \expandafter stand to each other. –  dubiousjim Jul 4 at 22:51
@dubiousjim yes { is just a token at that point, it's not so easy to use \edef as \edef fully expands things (and breaks any fragile command) but you just want to expand \textdagger once. –  David Carlisle Jul 4 at 23:14
I noticed that this technique will not work with some commands, such as \bullet. I guess because it's not expandable? What I did in those cases was to say texdef -tlatex bullet on my command line and get the expansion, and then just manually include that into any \renewcommand... –  dubiousjim Jul 5 at 21:53
show 1 more comment

The behavior of \textdagger is shared by all commands that are defined with \OMS-cmd, so a way to get errors when they're used in math mode is to change \@inmathwarn in the definition of \OMS-cmd with \@inmatherr. See Why does \textbackslash render as "n" in math mode? for more information about the issue.

\documentclass{article}
\usepackage{etoolbox}
\makeatletter
\expandafter\patchcmd\csname OMS-cmd\endcsname{\@inmathwarn}{\@inmatherr}{}{}
\makeatother
\begin{document}
$\textdagger$
\end{document}


This gives

! LaTeX Error: Command \textdagger invalid in math mode.

See the LaTeX manual or LaTeX Companion for explanation.
Type  H <return>  for immediate help.
...

l.7 $\textdagger$

-
The easy solution I'm using now is just \makeatletter\let\@inmathwarn\@inmatherr\makeatother. But I did want to understand better how to use \expandafter properly, anyway. –  dubiousjim Jul 5 at 21:50