TeX - LaTeX Asked by Ruco on November 29, 2020
I’m using the glossary definition from What is the best way for a list of nomenclature?. I need a macro that checks if the argument contains underscore symbol ("_"). I defined myfun
but the argument inside the macro is acrshort(symbI)
instead of F_a
. How can I solve this issue? Thank you for advance!!
documentclass{article}
usepackage{xspace}
usepackage[acronym,nonumberlist]{glossaries}
renewcommand{acronymname}{List of Notations}
newglossarystyle{mystyle}{%
setglossarystyle{long}%
renewenvironment{theglossary}%
{begin{longtable}[l]{@{}p{0.1hsize}p{0.8hsize}}}%
{end{longtable}}%
renewcommand*{glsgroupheading}[1]{%
multicolumn{2}{@{}l}{bfseriesglsgetgrouptitle{##1}}[5pt]}%
}
newcommand*{Rgroupname}{Roman Symbols}
newcommand*{Ggroupname}{Greek Symbols}
newcommand*{myacro}[4][sort=s]{%
newacronym[#1]{#2}{#3}{#4}%
globalexpandafterdefcsname #2endcsname{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{_}
readlistmymat{#1}
ifnummymatlen>1
textbf{Do something when the argument has _}
else
textbf{Do something when the argument does not have _}
fi
textbf{the argument is: } showitems*mymat
}
begin{document}
printglossary[style=mystyle,type=acronymtype]
section*{Math section}
begin{equation}
symbI = symbII symbIII
end{equation}
$ myfun{symbI} $
end{document}
The code returns:
and I expected to obtain:
If I use a macro to define a new acronym the code doesn’t works. Now, I’m using mysubscripta
in simbV
to add _a
in the definition of the acronym.
documentclass{article}
usepackage{xspace}
usepackage[acronym,nonumberlist]{glossaries}
renewcommand{acronymname}{List of Notations}
newglossarystyle{mystyle}{%
setglossarystyle{long}%
renewenvironment{theglossary}%
{begin{longtable}[l]{@{}p{0.1hsize}p{0.8hsize}}}%
{end{longtable}}%
renewcommand*{glsgroupheading}[1]{%
multicolumn{2}{@{}l}{bfseriesglsgetgrouptitle{##1}}[5pt]}%
}
newcommand*{Rgroupname}{Roman Symbols}
newcommand*{Ggroupname}{Greek Symbols}
newcommand*{myacro}[4][sort=s]{%
newacronym[#1]{#2}{#3}{#4}%
globalexpandafterdefcsname #2endcsname{acrshort{#2}}%
globalexpandafterdefcsname #2defendcsname{#3}%
}
newcommand{mysubscripta}[1]{#1_a}
myacro[sort=ra]{symbI}{ensuremath{mathrm{F_a}}xspace}{some explanation for $F$}
myacro[sort=rb]{symbII}{ensuremath{M_d^e}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$}
myacro[sort=rc]{symbV}{ensuremath{mathrm{mysubscripta{F}}}xspace}{some explanation for $F$}
makeglossaries
newcommand{myfun}[1]{
expandafterexpandafterexpandafterfindus
expandafterexpandafterexpandafter{csname#1defendcsname}%
{has _}{does not have _}
}
usepackage{tokcycle}
newcommandfindus[3]{%
gdefusfound{F}%
tokcycle{ifx_##1gdefusfound{T}fi}{processtoks{##1}}{}{}{#1}%
tctestifcon{if Tusfound}{#2}{#3}}
begin{document}
printglossary[style=mystyle,type=acronymtype]
section*{Math section}
begin{equation}
symbI = symbII symbIII
end{equation}
symbI $ myfun{symbI} $
symbII $ myfun{symbII} $
symbV $ myfun{symbV} $
end{document}
The main objective of solving this issue is to define a macro to add a subscript and superscript to an acronym and to avoid the double subscript/superscript error. For example, I want to do myfun{symbI}
and it will retunrs F_{ab}^{c}
where symbI
is F_a
or myfun{symbII}
and it will returns M_{db}^{ec}
where simbII
is M_d^e
.
The macro findus
searches the unexpanded argument for a _
and forks to #2
or #3
accordingly. I have incorporated it into the OP's myfun
.
It works even if the _
is embedded down in a group, as in the case for mathrm{F_a}
.
REEDITED to handle OP's additional case, in which the _
was not explicit, but contained in a macro definition. I this case, I adjusted the macro findus
to apply a protected@edef
to its argument, to expand as much as possible. In this way it can find content that expands to _
, in this case, mysubscripta
.
documentclass{article}
usepackage{xspace}
usepackage[acronym,nonumberlist]{glossaries}
renewcommand{acronymname}{List of Notations}
newglossarystyle{mystyle}{%
setglossarystyle{long}%
renewenvironment{theglossary}%
{begin{longtable}[l]{@{}p{0.1hsize}p{0.8hsize}}}%
{end{longtable}}%
renewcommand*{glsgroupheading}[1]{%
multicolumn{2}{@{}l}{bfseriesglsgetgrouptitle{##1}}[5pt]}%
}
newcommand*{Rgroupname}{Roman Symbols}
newcommand*{Ggroupname}{Greek Symbols}
newcommand*{myacro}[4][sort=s]{%
newacronym[#1]{#2}{#3}{#4}%
globalexpandafterdefcsname #2endcsname{acrshort{#2}}%
globalexpandafterdefcsname #2defendcsname{#3}%
}
newcommand{mysubscripta}[1]{#1_a}
myacro[sort=ra]{symbI}{ensuremath{mathrm{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$}
myacro[sort=rc]{symbV}{ensuremath{mathrm{mysubscripta{F}}}xspace}{some explanation for $F$}
makeglossaries
usepackage{listofitems}
newcommand{myfun}[1]{
expandafterexpandafterexpandafterfindus
expandafterexpandafterexpandafter{csname#1defendcsname}%
{has _}{does not have _}
}
usepackage{tokcycle}
makeatletter
newcommandfindus[3]{%
protected@edeftmp{#1}%
gdefusfound{F}%
deftmpA{tokcycle{tctestifx{_####1}{gdefusfound{T}}{}}
{processtoks{####1}}{}{}}%
expandaftertmpAexpandafter{tmp}%
tctestifcon{if Tusfound}{#2}{#3}}
makeatother
begin{document}
printglossary[style=mystyle,type=acronymtype]
section*{Math section}
begin{equation}
symbI = symbII symbIII = symbV
end{equation}
symbI $ myfun{symbI} $
symbII $ myfun{symbII} $
symbV $ myfun{symbV} $
end{document}
Answered by Steven B. Segletes on November 29, 2020
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@expandafterexpandafterexpandafterglsdetoklabel
expandafterexpandafterexpandafter{expandafter@gobblestring⟨control sequence⟩}@shortendcsname
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
%%=============================================================================
newcommandUD@firstoftwo[2]{#1}%
newcommandUD@secondoftwo[2]{#2}%
newcommandUD@PassFirstToSecond[2]{#2{#1}}%
newcommandUD@Exchange[2]{#2#1}%
newcommandUD@removespace{}UD@firstoftwo{defUD@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>
newcommandUD@CheckWhetherNull[1]{%
romannumeralexpandafterUD@secondoftwostring{expandafter
UD@secondoftwoexpandafter{expandafter{string#1}expandafter
UD@secondoftwostring}expandafterUD@firstoftwoexpandafter{expandafter
UD@secondoftwostring}expandafterz@UD@secondoftwo}%
{expandafterz@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>}%
newcommandUD@CheckWhetherBrace[1]{%
romannumeralexpandafterUD@secondoftwoexpandafter{expandafter{%
string#1.}expandafterUD@firstoftwoexpandafter{expandafter
UD@secondoftwostring}expandafterz@UD@firstoftwo}%
{expandafterz@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>}%
newcommandUD@CheckWhetherLeadingTokens[3]{%
romannumeralUD@CheckWhetherNull{#1}{expandafterz@UD@secondoftwo}{%
expandafterUD@secondoftwostring{expandafter
UD@@CheckWhetherLeadingTokens#3{relax}#1#2}{}}%
}%
newcommandUD@@CheckWhetherLeadingTokens[1]{%
expandafterUD@CheckWhetherNullexpandafter{UD@firstoftwo{}#1}%
{UD@Exchange{UD@firstoftwo}}{UD@Exchange{UD@secondoftwo}}%
{expandafterexpandafterexpandafterexpandafter
expandafterexpandafterexpandafterz@expandafterexpandafter
expandafter}expandafterUD@secondoftwoexpandafter{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.
%%-----------------------------------------------------------------------------
newcommandUD@internaltokencheckdefiner[2]{%
@ifdefinable#1{longdef#1##1#2{{##1}}}%
}%
UD@internaltokencheckdefiner{UD@InternalExplicitSpaceCheckMacro}{ }%
%%-----------------------------------------------------------------------------
%% Extract first inner undelimited argument:
%%
%% romannumeralUD@ExtractFirstArgLoop{ABCDEUD@SelDOm} yields {A}
%%
%% romannumeralUD@ExtractFirstArgLoop{{AB}CDEUD@SelDOm} yields {AB}
%%.............................................................................
@ifdefinableUD@RemoveTillUD@SelDOm{%
longdefUD@RemoveTillUD@SelDOm#1#2UD@SelDOm{{#1}}%
}%
newcommandUD@ExtractFirstArgLoop[1]{%
expandafterUD@CheckWhetherNullexpandafter{UD@firstoftwo{}#1}%
{z@#1}%
{expandafterUD@ExtractFirstArgLoopexpandafter{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 !!!
%%-----------------------------------------------------------------------------
@ifdefinableDefineCheckForTokenSequence{%
DeclareRobustCommandDefineCheckForTokenSequence[3]{%
UD@internaltokencheckdefiner{#2}{#3}%
newcommand#1[1]{%
romannumeralUD@CheckForTokenSequenceLoop{##1}{#2}{#3}%
}%
}%
}%
newcommandUD@CheckForTokenSequenceLoop[3]{%
% #1 - <tokens to check>
% #2 - <internal token-check-macro>
% #3 - <token sequence>
% Do:
% UD@internaltokencheckdefiner{<internal token-check-macro>}{<token sequence>}%
% romannumeralUD@CheckForTokenSequenceLoop{<tokens to check>}%
% {<internal token-check-macro>}%
% {<token sequence>}%
%
UD@CheckWhetherNull{#1}{expandafterz@UD@secondoftwo}{%
UD@CheckWhetherLeadingTokens{#1}{#3}{#2}{%
expandafterz@UD@firstoftwo
}{%
UD@CheckWhetherBrace{#1}{%
romannumeralexpandafterUD@CheckForTokenSequenceLoop
romannumeralUD@ExtractFirstArgLoop{#1UD@SelDOm}{#2}{#3}%
{UD@firstoftwo}%
{expandafterUD@secondoftwoUD@secondoftwo}%
}{%
UD@CheckWhetherLeadingTokens{#1}{ }{UD@InternalExplicitSpaceCheckMacro}{%
expandafterUD@firstoftwoUD@secondoftwo
}{%
expandafterUD@secondoftwoUD@secondoftwo
}%
}%
{expandafterz@UD@firstoftwo}%
{%
{expandafterUD@CheckForTokenSequenceLoopexpandafter{UD@removespace#1}}%
{expandafterUD@CheckForTokenSequenceLoopexpandafter{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.1hsize}p{0.8hsize}}}%
{end{longtable}}%
renewcommand*{glsgroupheading}[1]{%
multicolumn{2}{@{}l}{bfseriesglsgetgrouptitle{##1}}[5pt]}%
}
newcommand*{Rgroupname}{Roman Symbols}
newcommand*{Ggroupname}{Greek Symbols}
newcommand*{myacro}[4][sort=s]{%
newacronym[#1]{#2}{#3}{#4}%
globalexpandafterdefcsname #2endcsname{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{_}%%%
readlistmymat{#1}%%%
ifnummymatlen>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@fontendcsnameshowitems*mymat}}%%%
}
begin{document}
printglossary[style=mystyle,type=acronymtype]
section*{Math section}
begin{equation}
symbI = symbII symbIII
end{equation}
$ myfun{symbI} $
parindent=0pt
vfillhrulevfill
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}
vfillhrulevfill
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}
vfillhrulevfill
verb|CheckWhetherUnderscore{_}{Underscore present}{Underscore not present}|:
CheckWhetherUnderscore{_}{Underscore present}{Underscore not present}
vfillhrulevfill
verb|CheckWhetherUnderscore{ }{Underscore present}{Underscore not present}|:
CheckWhetherUnderscore{ }{Underscore present}{Underscore not present}
vfillhrulevfill
verb|CheckWhetherUnderscore{}{Underscore present}{Underscore not present}|:
CheckWhetherUnderscore{}{Underscore present}{Underscore not present}
vfillhrulevfill
verb|CheckWhetherUnderscore{A_B}{Underscore present}{Underscore not present}|:
CheckWhetherUnderscore{A_B}{Underscore present}{Underscore not present}
vfillhrulevfill
makeatletter
verb|expandafterexpandafterexpandafterCheckWhetherUnderscore|
verb|expandafterexpandafterexpandafter{%|
verb| csname glo@expandafterexpandafterexpandafterglsdetoklabel|
verb| expandafterexpandafterexpandafter{%|
verb| expandafter@gobblestringsymbI}@shortendcsname|
verb|}{Underscore present}{Underscore not present}|:
expandafterexpandafterexpandafterCheckWhetherUnderscore
expandafterexpandafterexpandafter{%
csname glo@expandafterexpandafterexpandafterglsdetoklabel
expandafterexpandafterexpandafter{%
expandafter@gobblestringsymbI}@shortendcsname
}{Underscore present}{Underscore not present}
makeatother
end{document}
Answered by Ulrich Diez on November 29, 2020
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP