我有一个缩写“foo”。但是,我稍后可能会想将其更改为简单的“foo”。因此,我定义了一个宏,以便轻松地在两个选项之间切换(通过取消注释相关行):
\documentclass{article}
% f.o.o. option
\newcommand{\foo}{f.o.o.\@}
% foo option
%\newcommand{\foo}{foo}
\begin{document}
It could be a \foo{}, but then it might not be a \foo{}.
\end{document}
除了末尾的句号外,此方法运行正常。如果我使用 foo 选项,则文本将正确显示为:
它可能是一个 foo,但也可能不是一个 foo。
但是,如果我使用 foo 选项,那么就会多出一个句点:
它可能是一个 foo,但也可能不是一个 foo。
有没有一些巧妙的方法可以用 foo 选项动态删除尾随句点?这个问题提供了一种用于删除尾随句点的好方法xstring
,但我不知道如何提前\newcommand
查看以下字符。
答案1
这里我首先检查下一个标记是否为{
;如果是,则传递括号中的内容(通常为空)并重新检查。
如果后面跟着句号,则会被忽略,因此使用标准的句末空格;否则\@
会发出。
\documentclass{article}
\ExplSyntaxOn
\NewDocumentCommand{\foo}{}
{
f.o.o.
\peek_catcode:NTF \c_group_begin_token
{
\dwolfeu_foo_brace:n
}
{
\dwolfeu_foo_checkperiod:
}
}
\cs_new_protected:Nn \dwolfeu_foo_brace:n
{% deliver the argument unbraced
\dwolfeu_foo_checkperiod: #1
}
\cs_new_protected:Nn \dwolfeu_foo_checkperiod:
{
\peek_charcode_remove:NTF . {} { \@ }
}
\ExplSyntaxOff
\begin{document}
\xspaceskip=20pt
It could be a \foo{}, but then it might not be a \foo{}. Text follows.
It could be a \foo, but then it might not be a \foo. Text follows.
It could be a \foo{} with normal space.
It could be a \foo. With sentence-ending space.
\end{document}
我使用了一个较大的值\xspaceskip
只是为了更好地显示句子结尾空格的使用时间。
答案2
如果您只想使用 TeX 原语,那么您可以使用以下代码:
\def\foo{f.o.o.\checknextdot}
\def\checknextdot{\futurelet\next\checknextdotA}
\def\checknextdotA{\let\nextA=\relax
\ifx\next.\def\nextA##1{}\fi
\ifx\next\bgroup\def\nextA##1{\checknextdot}\fi
\nextA
}
在 OpTeX 中,您可以使用以下宏:
\def\foo{f.o.o.\checknextdot}
\def\checknextdot{\isnextchar.{\ignoreit}%
{\isnextchar\bgroup{\ea\checknextdot\ignoreit}
{}}}
两种变体的测试代码:
It could be a \foo{}, but then it might not be a \foo{}. Text follows.
It could be a \foo, but then it might not be a \foo. Text follows.
It could be a \foo{} with normal space.
It could be a \foo. With sentence-ending space.