Warning: This answer has been completely rewritten. Althought the general idea remains the same as in its first version, the new code differs in many aspects. I am going to add some explanation, too.
The code
The following code defines two commands:
\GrabFontIdentifier lets the control sequence passed
in its last mandatory argument equal to the font selector
bound to the NFSS symbol font name passed in its first mandatory
argument. By default, it assumes the binding made for the normal
math version, but a different math version (e.g., bold)
can be specified in an optional argument. Since it performs
an assignment, this command is obviously not purely expandable.
\SameFontIdentifier can be used as pseudo-argument to an \if
to test whether a given control sequence initialized with
\GrabFontIdentifier is or is not the font selector bound to a
given NFSS specification (encoding/family/weight/shape).
This command is purely expandable.
I think it’s best to look at the code, which, besides defining these two commands, also shows how to use them (it is a complete compilable example):
\documentclass[12pt]{article}
\makeatletter
\newcommand*\GrabFontIdentifier[3][normal]{%
% #1 <- a NFSS math version name, defaults to "normal"
% #2 <- a NFSS symbol font name, e.g. "operators"
% #3 <- a control sequence, e.g. "\next"
\@ifundefined{sym#2}{%
\global\let#3\@undefined
}{%
\sbox\z@{%
\mathversion{#1}%
$%
\expandafter\global\expandafter\let\expandafter#3%
\the\textfont\csname sym#2\endcsname
$%
}%
}%
}
\newcommand*\SameFontIdentifier[5]{%
% #1 <- control sequence to test, e.g. "\next"
% #2 <- encoding, e.g. "OT1"
% #3 <- family name, e.g. "cmr"
% #4 <- weight, e.g. "m"
% #5 <- shape, e.g. "n"
TT\fi
\expandafter\ifx\csname #2/#3/#4/#5/\tf@size\endcsname #1%
}
% Needed in order to make sure "\tf@size" is defined:
\sbox\z@{$$}
\makeatother
\begin{document}
\GrabFontIdentifier[bold]{operators}\next
% Test these ones too:
% \GrabFontIdentifier[bold]{letters}\next
% \GrabFontIdentifier{operators}\next
% \GrabFontIdentifier{letters}\next
% \GrabFontIdentifier{nonExistentName}\next
First test:
\if\SameFontIdentifier\next{OT1}{cmr}{bx}{n}%
Coincides.
\else
Does not coincide.
\fi
Second test:
\if\SameFontIdentifier\next{OML}{cmm}{b}{it}%
Coincides.
\else
Does not coincide.
\fi
\end{document}
The following enhancements have been introduced in comparison with the previous version of the code:
The argument of \SameFontIdentifier (previously named
\TestFontIdentifier) devoted to the font size has been eliminated:
indeed, the specification of the size is extraneous to the problem
at hand. The “text” size is now automatically supplied.
As already said, \SameFontIdentifier has been made purely expandable.
It was not so before (my mistake).
The case of a nonexistent symbol font name is correctly handled.
This too was not so before (my mistake again).
The idiom \if\SameFontIdentifier … \else … \fi is typical, and I am not going to discuss it here; I’ll only mention that this construction allows you to have an explicit \if to go with \else and \fi, for the case in which the whole code segment is being skipped over because of an outer false conditional. If you prefer a LaTeX-style conditional, you can go this way instead:
\documentclass[12pt]{article}
\makeatletter
\newcommand*\GrabFontIdentifier[3][normal]{%
% #1 <- a NFSS math version name, defaults to "normal"
% #2 <- a NFSS symbol font name, e.g. "operators"
% #3 <- a control sequence, e.g. "\next"
\@ifundefined{sym#2}{%
\global\let#3\@undefined
}{%
\sbox\z@{%
\mathversion{#1}%
$%
\expandafter\global\expandafter\let\expandafter#3%
\the\textfont\csname sym#2\endcsname
$%
}%
}%
}
\newcommand*\IfSameFontIdentifier[5]{% plus two "hidden" arguments
% #1 <- control sequence to test, e.g. "\next"
% #2 <- encoding, e.g. "OT1"
% #3 <- family name, e.g. "cmr"
% #4 <- weight, e.g. "m"
% #5 <- shape, e.g. "n"
% #6 <- TRUE text
% #7 <- FALSE text
\expandafter\ifx\csname #2/#3/#4/#5/\tf@size\endcsname #1%
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi
}
% Needed in order to make sure "\tf@size" is defined:
\sbox\z@{$$}
\makeatother
\begin{document}
\GrabFontIdentifier[bold]{operators}\next
% Test these ones too:
% \GrabFontIdentifier[bold]{letters}\next
% \GrabFontIdentifier{operators}\next
% \GrabFontIdentifier{letters}\next
% \GrabFontIdentifier{nonExistentName}\next
First test:
\IfSameFontIdentifier\next{OT1}{cmr}{bx}{n}
{Coincides.}
{Does not coincide.}
Second test:
\IfSameFontIdentifier\next{OML}{cmm}{b}{it}
{Coincides.}
{Does not coincide.}
\end{document}
Some explanations
The idea is simple: in \GrabFontIdentifier, we first deal with the case of a nonexistent symbol font name: in this case, we \let the target control sequence to be undefined. Otherwise, we typeset a temporary box (which we are not going to use any more) and use a suitable chain of \expandafters to let the target control sequence equal to the expansion of \the\textfontn (for example, of \the\textfont1 in case #2 is letters), where the number n is supplied by \csname sym#2\endcsname.
And what is the expansion of \the\textfontn? The answer is given on the last two lines of page 214 of _The TeXbook:
\the<font> produces a font identifier that selects the specified font.
Moreover, the syntax diagrams on page 271 confirm that \textfont<4-bit number> makes a correct instance of <font>.
On the other hand, NFSS defines control sequences of the form \csname<enc>/<family>/<weight>/<shape>/<size>\endcsname as font identifiers for the font having encoding <enc>, etc.; so, in \SameFontIdentifier, we simply test whether the control sequence constructed in this way from the supplied arguments is \ifx-equal to the control sequence passed in the first argument. And indeed, if you look at the top of page 219, where the conditions for an \ifx test being successful are specified, you will find that:
The condition is true if (a) the two tokens are not macros
and they both represent the same (character code, category code) pair
or the same TeX primitive or the same \font or \chardef
or \countdef, etc.;…
I think that this should be enough to be forgiven for the hasty answer I gave before…
\TestFontIdentifier-\GrabFontIdentifierworks because\DeclareSymbolFontessentially defines\sym<#1>to mean the font with the specified encoding-family-weight-shape combination. And I guess there should be no argument for size, since\DeclareSymbolFontdoesn't have such an argument. Anyway, I will use your solution in my package, hoping it works. And I believe it should, once I remove size. – MickG Aug 06 '15 at 13:37TT\fiis simply to get rid of the\if, which in turn is necessary to avoidExtra \elsewhen processing the lines of the test. – MickG Aug 06 '15 at 13:38\csname sym#1\csnameis just the family number corresponding to symbol font#1). – GuM Aug 06 '15 at 13:46