If you do
\myacro[sort=ra]{symbI}{\ensuremath{F_a}\xspace}{some explanation for $F$}
, then the ⟨control sequence⟩ \symbI
will not deliver the tokens \ensuremath{F_a}\xspace
but will deliver a call to \acrshort
while \acrshort
is not fully expandable. What does this mean? Expansion takes place in TeX's gullet. (Temporary) Assignments etc take place in TeX's stomach. Some tokens coming from expanding \acroshort...
are intended to trigger (temporary) assignments or changes of fonts etc and therefore need to be processed by the stomach for subsequent tokens also coming from expanding \acroshort...
being processed/further expanded correctly.
So you need a check which takes place in TeX's stomach while all checking and forking by means of expandable \if.. ...\else ... \fi
-tokens and whatsoever intriguing macro-trickery can take place only at a prior stage, in TeX's gullet. Thus your request is sort of contradictory to the ways in which TeX works.
But the acronym-package internally defines a control sequence \glo@symbI@short
which delivers the result of applying \protected@edef
to the tokens \ensuremath{F_a}\xspace
.
Thus you can get hold of the tokens passed to \myacro
via
\csname glo@\expandafter\expandafter\expandafter\glsdetoklabel
\expandafter\expandafter\expandafter{\expandafter\@gobble\string⟨control sequence⟩}@short\endcsname
The underscore is nested in curly argument-braces of \ensuremath
.
So you need a routine for detecting underscores that might be nested in curly braces.
In the example below I wrote my own routine \CheckWhetherUnderscore
for detecting whether a sequence of tokens contains an underscore of category code 8(subscript).
In order to find out if the expansion of the acronym underlying \SymbI
delivers an underscore you can apply \CheckWhetherUnderscore
to the result of expanding \glo@symbI@short
.
But this does not deliver information whether the expansion of the acronym underlying \SymbI
delivers control sequences which themselves expand to stuff with underscores.
Summa summarum:
You wish a check whereby \myfun
's argument contains \SymbI
and/or whatsoever other stuff (which probably isn't fully expandable either) while \SymbI
cannot be used as it is not fully expandable.
All I can do for you is provide a routine \CheckWhetherUnderscore
for detecting whether a sequence of tokens contains an underscore of category code 8(subscript) and show how to apply it to the top-level-expansion of \glo@symbI@short
.
Be aware: In case the top-level-expansion of \glo@symbI@short
contains an underscore, the routine \CheckWhetherUnderscore
detects the presence of that underscore no matter if that underscore would get gobbled/removed when further processing the tokens coming from expanding \glo@symbI@short
.
\documentclass{article}
\makeatletter
%%///////////////// Code of my own routine for defining checks ////////////////
%%////////////////////// for presence of token sequences //////////////////////
%%=============================================================================
%% Paraphernalia:
%% \UD@firstoftwo, \UD@secondoftwo,
%% \UD@PassFirstToSecond, \UD@Exchange, \UD@removespace
%% \UD@CheckWhetherNull, \UD@CheckWhetherBrace,
%% \UD@CheckWhetherLeadingTokens, \UD@ExtractFirstArg
%%=============================================================================
\newcommand\UD@firstoftwo[2]{#1}%
\newcommand\UD@secondoftwo[2]{#2}%
\newcommand\UD@PassFirstToSecond[2]{#2{#1}}%
\newcommand\UD@Exchange[2]{#2#1}%
\newcommand\UD@removespace{}\UD@firstoftwo{\def\UD@removespace}{} {}%
%%-----------------------------------------------------------------------------
%% Check whether argument is empty:
%%.............................................................................
%% \UD@CheckWhetherNull{<Argument which is to be checked>}%
%% {<Tokens to be delivered in case that argument
%% which is to be checked is empty>}%
%% {<Tokens to be delivered in case that argument
%% which is to be checked is not empty>}%
%%
%% The gist of this macro comes from Robert R. Schneck's \ifempty-macro:
%% <https://groups.google.com/forum/#!original/comp.text.tex/kuOEIQIrElc/lUg37FmhA74J>
\newcommand\UD@CheckWhetherNull[1]{%
\romannumeral\expandafter\UD@secondoftwo\string{\expandafter
\UD@secondoftwo\expandafter{\expandafter{\string#1}\expandafter
\UD@secondoftwo\string}\expandafter\UD@firstoftwo\expandafter{\expandafter
\UD@secondoftwo\string}\expandafter\z@\UD@secondoftwo}%
{\expandafter\z@\UD@firstoftwo}%
}%
%%-----------------------------------------------------------------------------
%% Check whether argument's first token is a catcode-1-character
%%.............................................................................
%% \UD@CheckWhetherBrace{<Argument which is to be checked>}%
%% {<Tokens to be delivered in case that argument
%% which is to be checked has leading
%% catcode-1-token>}%
%% {<Tokens to be delivered in case that argument
%% which is to be checked has no leading
%% catcode-1-token>}%
\newcommand\UD@CheckWhetherBrace[1]{%
\romannumeral\expandafter\UD@secondoftwo\expandafter{\expandafter{%
\string#1.}\expandafter\UD@firstoftwo\expandafter{\expandafter
\UD@secondoftwo\string}\expandafter\z@\UD@firstoftwo}%
{\expandafter\z@\UD@secondoftwo}%
}%
%%-----------------------------------------------------------------------------
%% Check whether argument's leading tokens form a specific
%% token-sequence that does neither contain explicit character tokens of
%% category code 1 or 2 nor contain tokens of category code 6:
%%.............................................................................
%% \UD@CheckWhetherLeadingTokens{<argument which is to be checked>}%
%% {<a <token sequence> without explicit
%% character tokens of category code
%% 1 or 2 and without tokens of
%% category code 6>}%
%% {<internal token-check-macro>}%
%% {<tokens to be delivered in case
%% <argument which is to be checked> has
%% <token sequence> as leading tokens>}%
%% {<tokens to be delivered in case
%% <argument which is to be checked>
%% does not have <token sequence> as
%% leading tokens>}%
\newcommand\UD@CheckWhetherLeadingTokens[3]{%
\romannumeral\UD@CheckWhetherNull{#1}{\expandafter\z@\UD@secondoftwo}{%
\expandafter\UD@secondoftwo\string{\expandafter
\UD@@CheckWhetherLeadingTokens#3{\relax}#1#2}{}}%
}%
\newcommand\UD@@CheckWhetherLeadingTokens[1]{%
\expandafter\UD@CheckWhetherNull\expandafter{\UD@firstoftwo{}#1}%
{\UD@Exchange{\UD@firstoftwo}}{\UD@Exchange{\UD@secondoftwo}}%
{\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\z@\expandafter\expandafter
\expandafter}\expandafter\UD@secondoftwo\expandafter{\string}%
}%
%%-----------------------------------------------------------------------------
%% \UD@internaltokencheckdefiner{<internal token-check-macro>}%
%% {<token sequence>}%
%% Defines <internal token-check-macro> to snap everything
%% until reaching <token sequence>-sequence and spit that out
%% nested in braces.
%%-----------------------------------------------------------------------------
\newcommand\UD@internaltokencheckdefiner[2]{%
\@ifdefinable#1{\long\def#1##1#2{{##1}}}%
}%
\UD@internaltokencheckdefiner{\UD@InternalExplicitSpaceCheckMacro}{ }%
%%-----------------------------------------------------------------------------
%% Extract first inner undelimited argument:
%%
%% \romannumeral\UD@ExtractFirstArgLoop{ABCDE\UD@SelDOm} yields {A}
%%
%% \romannumeral\UD@ExtractFirstArgLoop{{AB}CDE\UD@SelDOm} yields {AB}
%%.............................................................................
\@ifdefinable\UD@RemoveTillUD@SelDOm{%
\long\def\UD@RemoveTillUD@SelDOm#1#2\UD@SelDOm{{#1}}%
}%
\newcommand\UD@ExtractFirstArgLoop[1]{%
\expandafter\UD@CheckWhetherNull\expandafter{\UD@firstoftwo{}#1}%
{\z@#1}%
{\expandafter\UD@ExtractFirstArgLoop\expandafter{\UD@RemoveTillUD@SelDOm#1}}%
}%
%%=============================================================================
%% \DefineCheckForTokenSequence{<Macro for perfoming the check>}%
%% {<internal token-check-macro>}%
%% {<token sequence>}%
%%
%% defines <internal token-check-macro> and <Macro for perfoming the check>.
%%
%% Syntax of <Macro for perfoming the check> is:
%%
%% <Macro for perfoming the check>{<tokens to check>}%
%% {<token in case <tokens to check> contains
%% <token sequence> at least once>}%
%% {<token in case <tokens to check> does not
%% contain <token sequence> >}%
%%
%% !!! <token sequence> must not contain explicit character tokens of catcode 1 or 2 !!!
%% !!! <token sequence> must not contain tokens of catcode 6 !!!
%% !!! <token sequence> must not be empty !!!
%%-----------------------------------------------------------------------------
\@ifdefinable\DefineCheckForTokenSequence{%
\DeclareRobustCommand\DefineCheckForTokenSequence[3]{%
\UD@internaltokencheckdefiner{#2}{#3}%
\newcommand#1[1]{%
\romannumeral\UD@CheckForTokenSequenceLoop{##1}{#2}{#3}%
}%
}%
}%
\newcommand\UD@CheckForTokenSequenceLoop[3]{%
% #1 - <tokens to check>
% #2 - <internal token-check-macro>
% #3 - <token sequence>
% Do:
% \UD@internaltokencheckdefiner{<internal token-check-macro>}{<token sequence>}%
% \romannumeral\UD@CheckForTokenSequenceLoop{<tokens to check>}%
% {<internal token-check-macro>}%
% {<token sequence>}%
%
\UD@CheckWhetherNull{#1}{\expandafter\z@\UD@secondoftwo}{%
\UD@CheckWhetherLeadingTokens{#1}{#3}{#2}{%
\expandafter\z@\UD@firstoftwo
}{%
\UD@CheckWhetherBrace{#1}{%
\romannumeral\expandafter\UD@CheckForTokenSequenceLoop
\romannumeral\UD@ExtractFirstArgLoop{#1\UD@SelDOm}{#2}{#3}%
{\UD@firstoftwo}%
{\expandafter\UD@secondoftwo\UD@secondoftwo}%
}{%
\UD@CheckWhetherLeadingTokens{#1}{ }{\UD@InternalExplicitSpaceCheckMacro}{%
\expandafter\UD@firstoftwo\UD@secondoftwo
}{%
\expandafter\UD@secondoftwo\UD@secondoftwo
}%
}%
{\expandafter\z@\UD@firstoftwo}%
{%
{\expandafter\UD@CheckForTokenSequenceLoop\expandafter{\UD@removespace#1}}%
{\expandafter\UD@CheckForTokenSequenceLoop\expandafter{\UD@firstoftwo{}#1}}%
{#2}{#3}%
}%
}%
}%
}%
\makeatother
%%=============================================================================
%%///////////// End of code of my own routine for defining checks /////////////
%%/////////////////////for presence of token sequences ////////////////////////
% Define a check for presence of `_` :
\DefineCheckForTokenSequence{\CheckWhetherUnderscore}{\InternalUnderscoreCheckMacro}{_}%
\usepackage{xspace}
\usepackage[acronym,nonumberlist]{glossaries}
\renewcommand{\acronymname}{List of Notations}
\newglossarystyle{mystyle}{%
\setglossarystyle{long}%
\renewenvironment{theglossary}%
{\begin{longtable}[l]{@{}p{0.1\hsize}p{0.8\hsize}}}%
{\end{longtable}}%
\renewcommand*{\glsgroupheading}[1]{%
\multicolumn{2}{@{}l}{\bfseries\glsgetgrouptitle{##1}}\\[5pt]}%
}
\newcommand*{\Rgroupname}{Roman Symbols}
\newcommand*{\Ggroupname}{Greek Symbols}
\newcommand*{\myacro}[4][sort=s]{%
\newacronym[#1]{#2}{#3}{#4}%
\global\expandafter\def\csname #2\endcsname{\acrshort{#2}}%
}
\myacro[sort=ra]{symbI}{\ensuremath{F_a}\xspace}{some explanation for $F$}
\myacro[sort=rb]{symbII}{\ensuremath{M}\xspace}{some explanation for $M$}
\myacro[sort=ga]{symbIII}{\ensuremath{\alpha}\xspace}{some explanation for $\alpha$}
\myacro[sort=rc]{symbIV}{\ensuremath{U}\xspace}{some explanation for $u$}
\makeglossaries
\usepackage{listofitems}
\newcommand{\myfun}[1]{%%%
\setsepchar{_}%%%
\readlist\mymat{#1}%%%
\ifnum\mymatlen>1 %%%
\textbf{Do something when the argument has \_}\\
\else
\textbf{Do something when the argument does not have \_}\\
\fi
\textbf{the argument is: } {\hbox{\csname verbatim@font\endcsname\showitems*\mymat}}%%%
}
\begin{document}
\printglossary[style=mystyle,type=\acronymtype]
\section*{Math section}
\begin{equation}
\symbI = \symbII \symbIII
\end{equation}
$ \myfun{\symbI} $
\parindent=0pt
\vfill\hrule\vfill
\verb|\CheckWhetherUnderscore{A BC#1{De{g}F}}{Underscore present}{Underscore not present}|:\\
\CheckWhetherUnderscore{A BC#1{De{g}F}}{Underscore present}{Underscore not present}
\vfill\hrule\vfill
\verb|\CheckWhetherUnderscore{A BC#1{De{g{_}}F}}{Underscore present}{Underscore not present}|:\\
\CheckWhetherUnderscore{A BC#1{De{g{_}}F}}{Underscore present}{Underscore not present}
\vfill\hrule\vfill
\verb|\CheckWhetherUnderscore{_}{Underscore present}{Underscore not present}|:\\
\CheckWhetherUnderscore{_}{Underscore present}{Underscore not present}
\vfill\hrule\vfill
\verb|\CheckWhetherUnderscore{ }{Underscore present}{Underscore not present}|:\\
\CheckWhetherUnderscore{ }{Underscore present}{Underscore not present}
\vfill\hrule\vfill
\verb|\CheckWhetherUnderscore{}{Underscore present}{Underscore not present}|:\\
\CheckWhetherUnderscore{}{Underscore present}{Underscore not present}
\vfill\hrule\vfill
\verb|\CheckWhetherUnderscore{A_B}{Underscore present}{Underscore not present}|:\\
\CheckWhetherUnderscore{A_B}{Underscore present}{Underscore not present}
\vfill\hrule\vfill
\makeatletter
\verb|\expandafter\expandafter\expandafter\CheckWhetherUnderscore|\\
\verb|\expandafter\expandafter\expandafter{%|\\
\verb| \csname glo@\expandafter\expandafter\expandafter\glsdetoklabel|\\
\verb| \expandafter\expandafter\expandafter{%|\\
\verb| \expandafter\@gobble\string\symbI}@short\endcsname|\\
\verb|}{Underscore present}{Underscore not present}|:\\
\expandafter\expandafter\expandafter\CheckWhetherUnderscore
\expandafter\expandafter\expandafter{%
\csname glo@\expandafter\expandafter\expandafter\glsdetoklabel
\expandafter\expandafter\expandafter{%
\expandafter\@gobble\string\symbI}@short\endcsname
}{Underscore present}{Underscore not present}
\makeatother
\end{document}

\symbI
contains no underscore: it expands to\acrshort{symbI}
and this, in turn is not expandable; the underscore will appear when printing the result, way down what can be controlled with macro expansion. What would be the need for such a check?\myfun{\symbI}
to add a subscript, therefore, the macro should returns{F_a}_{b}