我使用的词汇表定义来自列出命名列表的最佳方法是什么?。我需要一个宏来检查参数是否包含下划线符号(“_”)。我定义了,myfun
但宏中的参数不是\acrshort(symbI)
。F_a
我该如何解决这个问题?谢谢您的帮助!!
\documentclass{article}
\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: } \showitems*\mymat
}
\begin{document}
\printglossary[style=mystyle,type=\acronymtype]
\section*{Math section}
\begin{equation}
\symbI = \symbII \symbIII
\end{equation}
$ \myfun{\symbI} $
\end{document}
代码返回:
我希望获得:
(编辑)来自 Steven B. Segletes 代码的第二个代码
如果我使用宏来定义新的缩写词,代码将不起作用。现在,我使用\mysubscripta
in\simbV
来添加_a
缩写词的定义。
\documentclass{article}
\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}}%
\global\expandafter\def\csname #2def\endcsname{#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]{
\expandafter\expandafter\expandafter\findus
\expandafter\expandafter\expandafter{\csname#1def\endcsname}%
{has \_}{does not have \_}
}
\usepackage{tokcycle}
\newcommand\findus[3]{%
\gdef\usfound{F}%
\tokcycle{\ifx_##1\gdef\usfound{T}\fi}{\processtoks{##1}}{}{}{#1}%
\tctestifcon{\if T\usfound}{#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}
解决此问题的主要目的是定义一个宏来为首字母缩略词添加下标和上标,并避免出现双重下标/上标错误。例如,我想要执行,\myfun{\symbI}
它将返回F_{ab}^{c}
where \symbI
isF_a
或\myfun{symbII}
,它将返回M_{db}^{ec}
where \simbII
is M_d^e
。
答案1
如果你
\myacro[sort=ra]{symbI}{\ensuremath{F_a}\xspace}{some explanation for $F$}
,然后⟨控制序列⟩ \symbI
不会传递标记,但会传递对while\ensuremath{F_a}\xspace
的调用,而不能完全扩展。这是什么意思?扩展在 TeX 的胃中进行。(临时)分配等在 TeX 的胃中进行。一些来自扩展的标记旨在触发(临时)分配或字体更改等,因此需要由胃处理,以便后续来自扩展的标记也能被正确处理/进一步扩展。 所以你需要一个在 TeX 的胃中进行的检查,而所有通过可扩展标记进行的检查和分叉以及任何有趣的宏欺骗只能在先前的阶段,即 TeX 的胃中进行。因此,你的要求与 TeX 的工作方式有点矛盾。\acrshort
\acrshort
\acroshort...
\acroshort...
\if.. ...\else ... \fi
但是 acronym-package 内部定义了一个控制序列\glo@symbI@short
,它将应用的结果传递\protected@edef
给 tokens \ensuremath{F_a}\xspace
。
因此,你可以\myacro
通过
\csname glo@\expandafter\expandafter\expandafter\glsdetoklabel
\expandafter\expandafter\expandafter{\expandafter\@gobble\string⟨control sequence⟩}@short\endcsname
下划线嵌套在 的花括号中\ensuremath
。
因此,您需要一个例程来检测可能嵌套在花括号中的下划线。在下面的示例中,我编写了自己的例程\CheckWhetherUnderscore
来检测标记序列是否包含类别代码为 8(下标)的下划线。
为了查明首字母缩略词底层的扩展是否\SymbI
提供下划线,您可以将其应用于 \CheckWhetherUnderscore
扩展的结果\glo@symbI@short
。
但这并不能提供信息,即底层首字母缩略词的扩展是否\SymbI
提供了控制序列,而这些控制序列本身是否会扩展为带有下划线的内容。
概要:
您希望检查\myfun
的参数是否包含\SymbI
和/或任何其他内容(可能也不是完全可扩展的),但\SymbI
由于它不是完全可扩展的,因此无法使用。
我能为您做的就是提供一个例程,\CheckWhetherUnderscore
用于检测标记序列是否包含类别代码 8(下标)的下划线,并展示如何将其应用于的顶级扩展\glo@symbI@short
。
请注意:如果的顶层扩展\glo@symbI@short
包含下划线,则例程\CheckWhetherUnderscore
会检测该下划线的存在,无论在进一步处理来自扩展的标记时该下划线是否会被吞噬/删除\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}
答案2
宏\findus
在未展开的参数中搜索 a_
并相应地分叉到#2
或#3
。我已将其合并到 OP 中\myfun
。
即使_
嵌入到组中,它也能正常工作,就像 的情况一样\mathrm{F_a}
。
REEDITED 处理 OP 的附加情况,其中_
不是显式的,但包含在宏定义中。在这种情况下,我调整了宏\findus
以将 应用于\protected@edef
其参数,以尽可能地扩展。这样它就可以找到扩展为 的内容_
,在本例中为\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.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}}%
\global\expandafter\def\csname #2def\endcsname{#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]{
\expandafter\expandafter\expandafter\findus
\expandafter\expandafter\expandafter{\csname#1def\endcsname}%
{has \_}{does not have \_}
}
\usepackage{tokcycle}
\makeatletter
\newcommand\findus[3]{%
\protected@edef\tmp{#1}%
\gdef\usfound{F}%
\def\tmpA{\tokcycle{\tctestifx{_####1}{\gdef\usfound{T}}{}}
{\processtoks{####1}}{}{}}%
\expandafter\tmpA\expandafter{\tmp}%
\tctestifcon{\if T\usfound}{#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}