Macro only to be defined in math mode

I would not use \everymath.

\documentclass{article}
\usepackage{letltxmacro}

\makeatletter
\newcommand{\mathdef}[2]{%
  \@ifundefined{#1}{\@mathdef@new{#1}{#2}}{\@mathdef@remember{#1}{#2}}
}

\newcommand{\@mathdef@remember}[2]{%
  \expandafter\LetLtxMacro
    \csname textmode@#1\expandafter\endcsname
    \csname #1\endcsname
  \expandafter\def\csname mathmode@#1\endcsname{#2}%
  \expandafter\DeclareRobustCommand\csname#1\endcsname{%
    \ifmmode\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
     {\csname mathmode@#1\endcsname}{\csname textmode@#1\endcsname}%
  }%
}
\newcommand{\@mathdef@new}[2]{%
  \expandafter\DeclareRobustCommand\csname#1\endcsname{#2}%
}
\makeatother

\mathdef{d}{\mathop{}\!\mathrm{d}}

\begin{document}

\d{x} is an x with a dot below and $\int f(x) \d x$ is an integral over $x$.

\end{document}

enter image description here

I don't think this is a good way to go, though. It's confusing and prone to errors.

See When to use \LetLtxMacro? for information about \LetLtxMacro.

It's a bit easier with etoolbox:

\documentclass{article}
\usepackage{etoolbox}

\makeatletter
\newcommand{\mathdef}[2]{%
  \@ifundefined{#1}{\@mathdef@new{#1}{#2}}{\@mathdef@remember{#1}{#2}}
}

\newcommand{\@mathdef@remember}[2]{%
  \expandafter\robustify\csname#1\endcsname
  \csletcs{textmode@#1}{#1}%
  \csdef{mathmode@#1}{#2}%
  \protected\csdef{#1}{%
    \ifmmode\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
     {\csuse{mathmode@#1}}{\csuse{textmode@#1}}%
  }%
}
\newcommand{\@mathdef@new}[2]{%
  \protected\csdef{#1}{#2}%
}
\makeatother

\mathdef{d}{\mathop{}\!\mathrm{d}}

\begin{document}

\d{x} is an x with a dot below and $\int f(x) \d x$ is an integral over $x$.

\end{document}

Why do I use \DeclareRobustCommand (first version) or \protected (second version) all around?

When TeX does a write operation it is in no mode at all, in particular it is not in math mode. A simplistic definition such as

\newcommand{\foo}{%
  \relax % if this comes first in an alignment
  \ifmmode
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi
  \foo@math\foo@text
}

would always choose \foo@text if found in a \write. The above protections make the \mathdef commands to write themselves, so no choice is made at \write time.

Why not using \everymath? Try the following example and see.

\documentclass{article}

\everymath{\let\foo\foomath}
\newcommand{\foo}{Foo}
\newcommand{\foomath}{Ops}

\begin{document}

Text: \foo

Math: $\foo$

Ops: abc\textsuperscript{\foo}

\end{document}

My idea is very similar to egreg's, but I'd like to add an optional argument, so the math command could process arguments itself. The code:

\documentclass{article}

\usepackage{xparse}
\DeclareDocumentCommand{\mathdef}{mO{0}m}{%
  \expandafter\let\csname old\string#1\endcsname=#1
  \expandafter\newcommand\csname new\string#1\endcsname[#2]{#3}
  \DeclareRobustCommand#1{%
    \ifmmode
      \expandafter\let\expandafter\next\csname new\string#1\endcsname
    \else
      \expandafter\let\expandafter\next\csname old\string#1\endcsname
    \fi
    \next
  }%
}

\mathdef{\v}[1]{\tilde{#1}}
\mathdef{\d}{\mathrm{d}}

\begin{document}
Ha\v{c}ek and tilde $\v{a}+\v{b}=1$.

\d x  is an x with a dot below and $\int f(x) \d x$ is an integral over $x$.
\end{document}

The result:

enter image description here


You wish to use the \PushPostHook-macro from the everyhook-package for (re)defining macros that process arguments?

Issue 1:

In LaTeX arguments are denoted by #1 and #2 and the like, i.e., by sequences of hashes trailed by a digit in the range 1..9.

When it comes to nesting definitions, hashes need to be doubled for the inner definitions:

\def\outsidemacro#1{%
  \def\insidemacro##1{This is insidemacro's argument: ##1.}%  
  This is outsidemacro's argument: #1.%
}

During expansion, two consecutive hashes will be collapsed into one hash, i.e., the amount of hashes will be halved.

I.e., \outsidemacro{foo} yields:

\def\insidemacro#1{This is insidemacro's argument: #1.}%  
This is outsidemacro's argument: foo.%

Looking at the definition of \PushPostHook via \show\PushPostHook yields:

> \PushPostHook=\protected\long macro:
#1#2->\eh@checkhook {#1}\PushPostHook \letcs \eh@tempi {eh@post#1}\expandafter 
\gdef \csname eh@post#1\expandafter \endcsname \expandafter {\eh@tempi \eh@hook
separator #2}\undef \eh@tempi .

As you can see, the tokens are kept in macros whose names are of pattern \eh@post⟨name of hook⟩.

E.g., \eh@postmath and \eh@postdisplay.

For adding tokens to such a macro, \PushPostHook lets the macro in question equal to \eh@tempi and then redefines the macro in question by appending the tokens in question behind the expansion of \eh@tempi.

Expanding \eh@tempi is a crucial point:

In case the definition of \eh@tempi contains hashes (#), during expansion two consecutive hashes will collapse into one of them.

This implies:

Whenever \PushPostHook is called for adding things to \eh@postmath or \eh@postdisplay, the amount of consecutive hashes with things that are already in \eh@postmath or \eh@postdisplay will be halved.

This will be a problem especially when calling \PushPostHook several times for adding things to \eh@postmath or \eh@postdisplay.

You can avoid the halving of the amount of consecutive hashes by maintaining things by means of a token register because when the content of a token register is "spit out" via \the, the amount of hashes will not be reduced. When "spitting out" due to \the takes place during \edef, the amount of hashes will not only be not reduced but it will be doubled.

If you do, e.g.,

\myscratchtoks{#}
\edef\mymacro{\the\myscratchtoks}

, in the definition of \mymacro the amount of hashes coming from \myscratchtoks will be doubled. When expanding \mymacro, that doubled amount will be halved and thus the expansion of \mymacro delivers the same amount of hashes as would be delivered by \the\myscratchtoks.

Therefore I suggest adding things to a token-register and using \PushPostHook only for "flushing" that token-register.

Issue 2:

If you wish to maintain macros that can also process arguments, I suggest implementing something that can be used similarly to the prefixes \long or \global.

In the example below I used #{-notation for implementing a macro \mathcommand which processes left-brace-delimited arguments that are trailed by brace-nested arguments. As the ⟨definition text⟩ of a macro always is to be nested in braces, you can use the processing of left-brace-delimited-arguments for fetching all tokens that come before a ⟨definition text⟩.
Such tokens can be the definition-command itself (e.g., \renewcommand* or \global\long\def), the control-sequence-token that is to be (re)defined, and the ⟨parameter text⟩.

E.g., with

\mathcommand\renewcommand*\mymacrowitharguments[2]{%
  \mbox{math-arg~1: }(#1) 
  \mbox{ math-arg~2: }(#2)
}%

, \mathcommand's first (left-brace-delimited) argument will be the sequence \renewcommand*\mymacrowitharguments[2] and its second argument is formed by the stuff that is nested inside braces: \mbox{math-arg~1: }(#1) \mbox{ math-arg~2: }(#2).
\mathcommand will add the sequence ⟨first argument⟩{⟨second argument⟩}, i.e., the sequence \renewcommand*\mymacrowitharguments[2]{\mbox{math-arg~1: }(#1) \mbox{ math-arg~2: }(#2) } to the token-register \mymathhooktoks.

I also implemented a macro \mathcommandfromname which also fetches a left-brace-delimited argument and takes the stuff that is behind that argument and that therefore is nested in braces for the name of a control-sequence-token which can be formed via \csname..\endcsname:

E.g.,

\mathcommandfromname\renewcommand*{mymacrowitharguments}[2]{%
  \mbox{math-arg~1: }(#1) 
  \mbox{ math-arg~2: }(#2)
}%

yields:

\mathcommand\renewcommand*\mymacrowitharguments[2]{%
  \mbox{math-arg~1: }(#1) 
  \mbox{ math-arg~2: }(#2)
}%

\documentclass{article}

\usepackage{everyhook}

\newtoks\myscratchtoks
\newcommand\mymathhookmacro{}%

\PushPostHook{math}{\mymathhookmacro}%
\PushPostHook{display}{\mymathhookmacro}%

\newcommand{\mathcommand}{}%
\long\def\mathcommand#1#{\innermathcommand{#1}}%
\newcommand{\innermathcommand}[2]{%
  \begingroup
  \expandafter\myscratchtoks\expandafter{\mymathhookmacro#1{#2}}%
  \xdef\mymathhookmacro{\the\myscratchtoks}%
  \endgroup
}

\newcommand\exchange[2]{#2#1}%
\newcommand\mathcommandfromname{}%
\long\def\mathcommandfromname#1#{\romannumeral0\innermathcommandfromname{#1}}%
\newcommand\innermathcommandfromname[2]{%
  \expandafter\exchange\expandafter{\csname#2\endcsname}{ \mathcommand#1}%
}%

%----------------------------------------------------------------

\newcommand*\mymacrowitharguments[2]{%
  non-math-arg~1: \textbf{(#1)} %
  non-math-arg~2: \textbf{(#2)}%
}%

\mathcommand\renewcommand*\mymacrowitharguments[2]{%
  \mbox{math-arg~1: }(#1)
  \mbox{ math-arg~2: }(#2)
}%

\newcommand*\myothermacrowitharguments[2]{%
  other-non-math-arg~1: \textbf{(#1)} %
  other-non-math-arg~2: \textbf{(#2)}%
}%

\mathcommandfromname\renewcommand*{myothermacrowitharguments}[2]{%
  \mbox{other-math-arg~1: }(#1)
  \mbox{ other-math-arg~2: }(#2)
}%

\mathcommand\renewcommand*\d{\mathrm{d}}%

\parindent=0ex

\begin{document}

\d x  is an x with a dot below and $\int f(x) \d x$ is an 
integral over $x$.

\bigskip

Testing with \verb|\mymacrowitharguments|:\smallskip

outside math:\\
\mymacrowitharguments{arg A}{arg B}
\smallskip

inside math:\\
$\mymacrowitharguments{arg A}{arg B}$
\bigskip

Testing with \verb|\myothermacrowitharguments|:\smallskip

outside math:\\
\myothermacrowitharguments{arg A}{arg B}
\smallskip

inside math:\\
$\myothermacrowitharguments{arg A}{arg B}$

\end{document}

enter image description here