以复合方式组合两个宏

以复合方式组合两个宏

在此示例中,有两个宏:1)用于删除its 参数中\removefinalpoints任意数量的结束点;2)一个宏用于将关键字序列中的每个单词大写,这些单词由 分隔,由 定义。我想将关键字大写,然后删除最后一个(多个)结束点,这样我就可以得到仅以一个结束点结尾的关键字的预期列表。在下面的代码中,我注释了单词行,但没有删除结束点。.\capitalizekeywords\sep\def\sep{\unskip. }

\documentclass[11pt,draft]{article}
\usepackage{xstring}
\usepackage{mfirstuc}

\makeatletter 
\def\sep{\unskip. }%
\newcommand{\capitalizekeywords}[2][\sep]{%
  \def\dolist##1{\expandafter\@dolist##1#1\@eol}%
  \def\@dolist##1#1##2\@eol{%
    \begingroup\setbox0=\hbox{##1\unskip}\ifdim\wd0=0pt\endgroup\else\endgroup\ignorespaces\makefirstuc{##1}\unskip\sep\fi%
    \ifx\@eol##2\@eol\else\@dolist##2\@eol\fi}%
  \dolist{#2}%
}

\newcommand{\removefinalpoints}[1]{%
  \IfEndWith{#1}{.}{%
    \StrGobbleRight{#1}{1}[\preresult]%
    \def\result{\removefinalpoints\preresult}%
  }{\def\result{#1}}{\result}%
}

\setlength{\parindent}{\z@}%
\newcommand{\keywords}[1]{%
   %\emph{keywords: }\capitalizekeywords{#1}\unskip.\par
   \emph{keywords: }\removefinalpoints{\capitalizekeywords{#1}}\unskip.\par
}
\makeatother

\begin{document}

\keywords{one \sep two \sep three.}
\keywords{one \sep two \sep three}
\removefinalpoints{test 123.}\par
\removefinalpoints{test 123..}

\end{document}

我猜想它与有关\expandafter,但我尝试使用它但没有成功。

答案1

您可以使用 来完成expl3

\text_titlecase:n收集各种项目时忽略前导和尾随空格。然后通过应用(将首字母大写)对项目进行转换。接下来,通过在它们之间放置逗号和空格(在代码中用 表示~,因为我们在expl3编程环境中)以及尾随句点来传递整个列表。然后将多个句点减少为一个,并传递最终结果。

\documentclass{article}

\ExplSyntaxOn

\NewDocumentCommand{\keywords}{m}
 {
  \par\noindent
  \emph{Keywords:~}
  \seq_set_split:Nnn \l_tmpa_seq { \sep } { #1 }
  \seq_set_map_x:NNn \l_tmpb_seq \l_tmpa_seq { \text_titlecase:n { ##1 } }
  \tl_set:Nx \l_tmpa_tl { \seq_use:Nn \l_tmpb_seq { .~ }. }
  \regex_replace_all:nnN { \.+ } { \. } \l_tmpa_tl
  \tl_use:N \l_tmpa_tl
 }

\ExplSyntaxOff

\begin{document}

\keywords{one \sep two. \sep three.}

\keywords{one \sep two \sep three}

\end{document}

在此处输入图片描述

相关内容