If you are sure that \grad
will be followed by a fixed (but easily extendable) set of binary operators, this should work:
\documentclass{article}
\usepackage{amsmath}
\usepackage{xparse}
\DeclareMathOperator{\gradop}{grad}
\ExplSyntaxOn
% the list of admissible binary operators
\tl_const:Nn \c_denis_grad_ops_tl { \cdot \wedge }
\NewDocumentCommand{\grad}{}
{
\gradop
\peek_after:Nw \denis_grad_check:
}
\cs_new_protected:Nn \denis_grad_check:
{
\tl_map_inline:Nn \c_denis_grad_ops_tl
{% if the token matches one in the list, issue {\!}
\token_if_eq_meaning:NNT \l_peek_token ##1 { \tl_map_break:n { {\!} } }
}
}
\ExplSyntaxOff
\begin{document}
\begin{gather*}
\grad F \\
\mathop{\mathrm{grad}} F\\
\grad \cdot F \\
\mathrm{grad}\cdot F \\
\grad \wedge F \\
\mathrm{grad}\wedge F
\end{gather*}
\end{document}

If a binary operator in the list follows, we issue {\!}
that fixes the spacing: the thin space between the operator and the empty atom is nullified by \!
and the empty atom will provide the required bit for the spacing around binary operators.
A slightly different version with an interface for adding binary operators; the initial declaration
\OperatorBinary{\cdot,\wedge} % initialize
should go in the class, together with instructions such as
You can define operator names that behave well when followed by binary operation symbols with
\DeclareMathOperatorX{<cs>}{<name>}
for example
\DeclareMathOperatorX{\grad}{grad}
to be used like \grad f
or else like \grad\cdot F
. The predefined list of admissible binary operators includes \cdot
and \wedge
, but it can be augmented by saying in the preamble, for instance,
\OperatorBinary{\times}
(the argument can be a list like in the initial declaration which is \OperatorBinary{\cdot,\wedge}
. No operator of this type is predefined, use \DeclareMathOperatorX
for defining the one you'll be using.
\documentclass{article}
\usepackage{amsmath}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\DeclareMathOperatorX}{mm}
{
\NewDocumentCommand{#1}{}
{
\operatorname{#2}
\peek_after:Nw \denis_opx_check:
}
}
\NewDocumentCommand{\OperatorBinary}{m}
{
\clist_gput_right:Nn \g_denis_opx_binary_clist { #1 }
}
\clist_new:N \g_denis_opx_binary_clist
\cs_new_protected:Nn \denis_opx_check:
{
\clist_map_inline:Nn \g_denis_opx_binary_clist
{
\token_if_eq_meaning:NNT \l_peek_token ##1 { \clist_map_break:n { {\!} } }
}
}
\ExplSyntaxOff
\OperatorBinary{\cdot,\wedge} % initialize
\DeclareMathOperatorX{\grad}{grad}
\begin{document}
\begin{gather*}
\grad F \\
\mathop{\mathrm{grad}} F\\
\grad \cdot F \\
\mathrm{grad}\cdot F \\
\grad \wedge F \\
\mathrm{grad}\wedge F
\end{gather*}
\end{document}
{}
as in{\grad}
– David Carlisle Jan 28 '16 at 17:00\grad{f}
,\grad{\cdot F}
or\grad{\wedge F}
? – egreg Jan 28 '16 at 17:40\grad{f}
is okay but\grad{\cdot F}
and\grad{\wedge F}
are conceptually suspect :) – Denis Bitouzé Jan 28 '16 at 19:50\grad
is always followed by a certain fixed set of tokens, if not by a variable, it can be arranged, I guess. – egreg Jan 28 '16 at 19:58