![xstring:替换宏中定义的文本的子字符串](https://linux22.com/image/438778/xstring%EF%BC%9A%E6%9B%BF%E6%8D%A2%E5%AE%8F%E4%B8%AD%E5%AE%9A%E4%B9%89%E7%9A%84%E6%96%87%E6%9C%AC%E7%9A%84%E5%AD%90%E5%AD%97%E7%AC%A6%E4%B8%B2.png)
我不确定问题标题中的术语是否正确,但这是我正在寻找的内容。
我正在尝试整理一个类文件,该文件指定了我所在大学对论文/学位论文的格式要求。我尝试做的一件事是设置一个命令\abstractheader
来打印摘要页的页眉。
摘要页的一部分列出了候选人的学位。大学的格式要求是,每所大学的名称都应大写。使用\MakeUpperCase{}
或很容易确保这textcase
一点\MakeTextUppercase{}
。
但是,问题是,当我使用这两个命令中的任何一个时,它也会将“Ph.D.”打印为“PH.D.”,这是不正确的(根据格式指南)。它应该保留为“Ph.D.”我想要做的是确保其余文本全部大写,但防止字符串“Ph.D.”以大写形式打印。
我尝试在命令定义中使用xstring
的宏,用户可以使用该宏输入有关其学位的信息,将其替换为。但是当我这样做时,我收到一个错误,关于 定义中的非法参数编号,我不知道如何解决。\StrSubstitute
\alldegrees
Ph.D.
\NoCaseChange{Ph.D.}
\reserved@a
当然,另一种选择是要求用户\NoCaseChange{Ph.D.}
在输入信息时手动指定或仅按要求输入所有内容,但这两种方式都会有点违背尝试设置一个实现格式要求的文件的目的。
MWE 不包含类文件,但其理念是序言中的内容最终会成为单独类的一部分(也包括其他内容)。
梅威瑟:
\documentclass{article}
% To go in a class file
\usepackage{xstring}
\usepackage{textcase}
\makeatletter
\def\@alldegrees{}
\newcommand\alldegrees[1]{%
%\def\@alldegrees{\StrSubstitute{#1}{Ph.D.}{\NoCaseChange{Ph.D.}}} % produces error
\def\@alldegrees{#1}
}
\newcommand{\partofabstractheader}{ % Real command will have more stuff
\MakeTextUppercase{\@alldegrees}
}
\makeatother
% To be defined in user's preamble
\alldegrees{B.A., My Uni1\\
M.A., My Uni2\\
Ph.D., My Uni3} % produces: PH.D., MY UNI3
%\alldegrees{B.A., My Uni1\\
% M.A., My Uni2\\
% \NoCaseChange{Ph.D.}, MyUni3} % produces Ph.D., MY UNI3; but not as straightforward for end user
\begin{document}
\partofabstractheader
\end{document}
答案1
使用更加强大的字符串替换。
\documentclass{article}
% To go in a class file
\usepackage{textcase}
\makeatletter
\def\@alldegrees{}
\newcommand\alldegrees[1]{%
\def\@alldegrees{#1}%
\uncapitalizephd\@alldegrees
}
\newcommand{\partofabstractheader}{ % Real command will have more stuff
\MakeTextUppercase{\@alldegrees}
}
\makeatother
\ExplSyntaxOn
\cs_new_protected:Npn \uncapitalizephd #1
{
\regex_replace_all:nnN { Ph\.D\. } { \c{NoCaseChange}\cB\{Ph.D.\cE\} } #1
}
\ExplSyntaxOff
% To be defined in user's preamble
\alldegrees{B.A., My Uni1\\
M.A., My Uni2\\
Ph.D., My Uni3} % produces: PH.D., MY UNI3
\begin{document}
\partofabstractheader
\end{document}
答案2
在这里,我介绍\ConditionalTextUppercase
一下设置一切\MakeUppercase
除了参数中指定的分隔符分隔的字符串短语 \setsepchar
。分隔符为||
。宏使用listofitems
包来完成其工作。
在 MWE 中,我将Ph.D
和Mc
设为延迟大写的字符串短语。可能会添加更多例外情况。
\documentclass{article}
% To go in a class file
%\usepackage{xstring}
\input listofitems% or \usepackage{listofitems}
\usepackage{textcase}
\setsepchar{Ph.D.||Mc}
\makeatletter
\def\@alldegrees{}
\newcommand\alldegrees[1]{%
%\def\@alldegrees{\StrSubstitute{#1}{Ph.D.}{\NoCaseChange{Ph.D.}}} % produces error
\def\@alldegrees{#1}
}
\newcommand{\partofabstractheader}{ % Real command will have more stuff
\ConditionalTextUppercase{\@alldegrees}
}
\makeatother
\newcommand\ConditionalTextUppercase[1]{%
\readlist\cuclist{#1}%
\foreachitem\zz\in\cuclist[]{%
\ifnum\zzcnt=1 \else\cuclistsep[\zzcnt-1]\fi
\expandafter\MakeTextUppercase\expandafter{\zz}%
}
}
% To be defined in user's preamble
\alldegrees{B.A., My Uni1\\
M.A., McHenry College\\
Ph.D., My Uni3} % produces: PH.D., MY UNI3
%\alldegrees{B.A., My Uni1\\
% M.A., My Uni2\\
% \NoCaseChange{Ph.D.}, MyUni3} % produces Ph.D., MY UNI3; but not as straightforward for end user
\begin{document}
\partofabstractheader
\end{document}