我最近在想,如果有一个宏可以在首字母缩略词的字母之间填充句号,比如说,\acr
它可以接受输入\acr{WHO}
并输出“WHO”,那将非常有用。我不知道 LaΤεΧ 中对首字母缩略词和首字母缩写词的正确处理是什么(最好对每个词使用单独的宏?)但无论如何,能够毫不费力地为它们加标点是很有用的。有人知道怎么做吗?
答案1
我在这里做的是设置一个递归。被调用的\acr
宏将参数传递给以\acraux
两个标记结尾的辅助宏\relax
。辅助宏将参数分解为“下一个”标记和其余所有内容(以 结尾\relax
)。
它会将“下一个”标记排版为带尾随点的标记,只要该下一个标记不是\relax
。然后,它会递归调用自身,重复此任务,同时消耗参数的剩余部分。\relax
当迭代接近结束时(即,当没有剩余字母标记时),第二个标记开始起作用。此时,通常终止的标记\relax
被吸收为\acraux
as #1
,因此\relax
会寻找另一个标记来终止 的参数\acraux
。它会找到最初随调用提供的第二个标记\relax
。现在 就是#1
,\relax
它会终止递归。
我可以稍微修改一下,以防止递归受到堆栈限制,但由于我预计首字母缩略词不会超过 64K 个字母,因此这个问题没有意义。(注意:递归是堆栈限制的,因为\acraux
被连续调用前终止\fi
被扩大。
\documentclass{article}
\newcommand\acr[1]{\acraux#1\relax\relax}
\def\acraux#1#2\relax{\ifx\relax#1\else#1.\acraux#2\relax\fi}
\begin{document}
\acr{WHO}
\end{document}
正如其他一些答案所提到的,人们可能希望首字母缩略词之间的间距与默认值不同。以下是一种方法:
\documentclass{article}
\def\acrspace{1.5pt}
\newcommand\acr[1]{\kern-\acrspace\acraux#1\relax\relax}
\def\acraux#1#2\relax{\ifx\relax#1\else\kern\acrspace#1.\acraux#2\relax\fi}
\begin{document}
Spacing about \acr{WHO} returned to normal.
\end{document}
答案2
这很容易做到LaTeX3 常用表达更详细一点,代码如下:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand\acr{m}{
\tl_set:Nn \l_tmpa_tl {#1}
\regex_replace_all:nnN {([A-Z])} {\1.} \l_tmpa_tl
\tl_use:N \l_tmpa_tl
}
\ExplSyntaxOff
\begin{document}
\acr{WHO}
\end{document}
生成:
答案3
逐项映射输入,并添加\@.
(这是因为最后一个句点可能跟在小写字符后面)。
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewExpandableDocumentCommand{\dacr}{m}
{
\confusedandbemused_dacr:n { #1 }
}
\cs_new:Nn \confusedandbemused_dacr:n
{
\tl_map_function:nN { #1 } \__confusedandbemused_dacr_add:n
}
\cs_new:Nn \__confusedandbemused_dacr_add:n
{
#1\@.
}
\ExplSyntaxOff
\begin{document}
\dacr{WHO}
\dacr{DA{Spo}}
\end{document}
除了最后一个句号外,在句号后添加空格的修改相对简单:我隔离第一个项目(带有\tl_head:n
),并处理其余项目,放置.\nobreakspace
前他们。在最后一个项目之后我放了\@.
。
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewExpandableDocumentCommand{\dacr}{m}
{
\confusedandbemused_dacr:n { #1 }
}
\cs_new:Nn \confusedandbemused_dacr:n
{
\tl_head:n { #1 }
\tl_map_function:eN { \tl_tail:n { #1 } } \__confusedandbemused_dacr_add:n
\@.
}
\cs_generate_variant:Nn \tl_map_function:nN { e }
\cs_new:Nn \__confusedandbemused_dacr_add:n
{
.\nobreakspace#1
}
\ExplSyntaxOff
\begin{document}
$|$\dacr{WHO}$|$
$|$\dacr{DA{Spo}}$|$
\end{document}