使用 \@ifnextchar 定义“上午”时间的宏

使用 \@ifnextchar 定义“上午”时间的宏

我想创建一个针对一天中各个时间的宏,如下所示:

\newcommand{\pmtime}{a.m.\xspace}

问题在于 LaTeX 认为 am 中的最后一个句号表示句子的结束,因此产生的空格\xspace太大。

\newcommand{\amtime}{a.m.\ }

上述内容也无济于事,因为现在添加了常规大小的空格,即使宏确实出现在句子末尾。

我阅读\@ifnextchar并尝试了以下内容:

\newcommand{\amtime}{a.m.\@ifnextchar.{}{\ }}

这在文本中扩展为a.m.ifnextchar.(在这种情况下,宏后面没有句点。

答案1

由于字母am是小写的,因此 TeX 不认为a.m.是缩写。\@之后重置空间因子,并且 TeX 不会插入更大的空间(参见 egreg 的评论)。

\@ifnextchar其名称中有(“at”),因此应使用和@对(除非在包或类文件中使用)。然后有 catcode和可以作为命令名称的一部分(参见 Werner 的评论)。\makeatletter\makeatother@letter

\@ifnextchar有删除后续空格的副作用,因此下面的示例使用\ltx@ifnextchar@nospaceltxcmds来保持后续空格不变。 As\@ifnextchar\ltx@ifnextchar@nospace有三个参数,即所寻找的标记(此处为点)。 如果后面跟着一个点,则\@gobble删除该点以避免出现连续的点。\xspace仅在下一个标记不是点的情况下才需要( 的第三个参数\ltx@ifnextchar@nospace)。

\documentclass{article}
\usepackage{xspace}
\usepackage{ltxcmds}[2011/04/14]
\makeatletter
\newcommand{\amtime}{%
  a.m.\@%
  \ltx@ifnextchar@nospace.\@gobble\xspace
}
\newcommand{\pmtime}{%
  p.m.\@%
  \ltx@ifnextchar@nospace.\@gobble\xspace
}
\makeatother

\begin{document}
  7\amtime, 8\amtime and 9\amtime.
\end{document}

结果

答案2

如果你使用 ,那么这个\@ifnextchar事情已经由 来处理了\xspace。你只需要向 TeX 声明句号不是句子的结尾,并且该命令\@就是为了这个目的:

\usepackage{xspace}
\newcommand{\amtime}{\,a.m.\@\xspace}

将具有正确的间距。请注意\,将“am”与其前面的数字稍微分开(并且此空格永远不会用于换行)。

但是,我通常建议不要这样做:记住在后面需要空格的情况下\xspace写字真的不是那么困难。\amtime{}

你为什么不尝试

\newcommand{\amtime}{\,\textsc{am}}

可以避免经期吗?

答案3

不幸的是,您使用\@\@ifnextchar并没有引发错误,因为\@是有效的控制序列。以下可能是您希望通过使用 实现的目标\@ifnextchar

在此处输入图片描述

\documentclass{article}
\usepackage{xspace}% http://ctan.org/pkg/xspace
\makeatletter
\newcommand{\amtime}{a.m.\@ifnextchar.{}{\ }}
\makeatother
\begin{document}
It is 8a.m. at the moment. \par
It is 8a.m.\xspace at the moment. \par
It is 8a.m.\ at the moment. \par
It is 8\amtime at the moment.
\end{document}

\makeatletter注意和的用法\makeatother。参见做什么\makeatletter\makeatother做什么?

不过,使用起来更简单

It is 8a.m.\@ at the moment.

如果你可能使用宏作为

It is 8\amtime, time to rise from bed.

间距将不正确。您可以嵌套条件来检查以下标点符号\amtime

\newcommand{\amtime}{a.m.\@ifnextchar.{}{\@ifnextchar,{}{\ }}}

然而,这很快就变得笨拙。egreg 的答案(使用\@\xspace)提供了一种更优雅和更全面的替代方案。

相关内容