为什么下面的代码不起作用?来自一个失败的、现已修复的 SO 答案我的:
\documentclass{article}
\usepackage{expl3}
\ExplSyntaxOn
\newcommand\latinabbrev[1]{
\peek_meaning:NTF . {% Same as \@ifnextchar
#1\@}
{ \peek_charcode:NTF a {% Check whether next char has same catcode as \'a, i.e., is a letter
#1.\@ }
{#1.\@}}}
\ExplSyntaxOff
%Omit final dot from each def.
\def\cf{\latinabbrev{cf}}
\begin{document}
Knuth, \cf The TeXbook.
\end{document}
此代码应检查下一个字符以看它是否是一个点(因此代码不应插入另一个点,并且它应该将即将到来的点隔开,就像它在句子末尾一样),或者是 catcode 10(然后它应该插入一个点和一个空格),或者是其他东西(然后它应该插入一个点)。
尽管其他两个分支似乎可以工作,但\peek_charcode:NTF
似乎永远不会采用其真实分支,例如在这种\cf T
情况下。为什么不呢?
答案1
我想你想要\peek_catcode:NTF
这里:
\documentclass{article}
\usepackage{expl3}
\ExplSyntaxOn
\newcommand \latinabbrev [1] {
\peek_meaning:NTF .
{ #1 \@ }
{
\peek_catcode:NTF a
{ #1 . \@ ~ }
{ #1 . \@ }
}
}
\ExplSyntaxOff
%Omit final dot from each def.
\def\cf{\latinabbrev{cf}}
\begin{document}
Knuth, \cf The TeXbook.
\end{document}
peek_charcode:NTF
检查字符代码,在本例中查找字母“a”。请记住,TeX 将忽略后面的空格\cf
,您在这里永远看不到空格!
答案2
使用 \futurelet。它是 TeX 的一个原语,也是做这种事情的唯一方法。事实上,这就是它被引入的原因。
LaTeX 3 在底层使用了 \futurelet,在我看来,这让事情变得更加复杂,速度也慢了很多。
如果您理解这一点,您就可以自己解决问题(也许除了将空格标记放入 \test 宏的问题)。
$ tex
This is TeX, Version 3.1415926 (TeX Live 2009)
**\relax
*\def\test{\message{\ifcat\tmp_YES\else NO\fi}}
*\futurelet\tmp\test a
NO
*\futurelet\tmp\test _
YES!
Missing $ inserted.