在 expl3 中模拟 \@ifnextchar

在 expl3 中模拟 \@ifnextchar

我想写下面的expl3版本。

\documentclass{article}
\makeatletter
\def\ie{i.e\@ifnextchar.{}{.\@{} }}
\makeatother

\pagestyle{empty}
\begin{document}
\noindent
\ie Hello\newline
\ie. Hello\newline
\end{document}

我知道这个\peek_after:Nw命令,但我不知道如何实现它。事实上,所有命令\peek_...似乎都要求你明确地输入一个令牌。我似乎必须编写一个带参数的命令。

我可以尝试类似的事情:

\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\eg}{ m }
    {
        e.g
        \str_if_eq_x:nnF { . } { #1 }{.\@{} }
    }
\ExplSyntaxOff
\pagestyle{empty}
\begin{document}
\noindent
\eg Hello\newline
\eg. Hello\newline
{\eg} Hello
\end{document}

但仍存在一些症结。

首先,因为被定义为接受一个参数,所以它首先 \eg吞噬了以下内容。不存在这个问题。(我可以通过编写类似的东西来解决这个问题,但在我的H\ie\str_if_eq_x:nnF { . } { #1 }{.\@{} #1}真实的文档中所有这些都大大降低了 MWE,但当#1其中包含非字符的内容时,我会遇到更多问题。)

其次,{\eg}由于它期望一个参数,但遇到了它认为是不平衡括号。同样,{\ie}非常好地不存在这个问题。

所以这种方法确实不是我想要的。

这是我尝试使用\peek_after:Nw

\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn

\cs_new:Nn \ae_eg: 
    {
        \peek_after:Nw \ae_test_period:
    }

\cs_new:Nn \ae_test_period: 
    {
        \str_if_eq_x:nnF  { \l_peek_token }  { . }  { FALSE }
    }

\NewDocumentCommand{\eg}{}
    {
        e.g \ae_eg:
    }

\ExplSyntaxOff
\pagestyle{empty}
\begin{document}
\noindent
\eg. Hello\newline
\eg  Hello\newline
\end{document}

但从\l_peek_token未被视为与.

答案1

您正在寻找正确的位置\peek_after:wN,但这是最底层的函数(包装器\futurelet)。您想要的是\peek_meaning:NF

\documentclass{article}
\usepackage{expl3,xparse}
\ExplSyntaxOn
\NewDocumentCommand { \ie } { }
  {
    i.e
    \peek_meaning:NF . % Just a 'false' branch needed
       { . \@ ~ }
  }
\ExplSyntaxOff

\pagestyle{empty}
\begin{document}
\noindent
\ie Hello\newline
\ie. Hello\newline
\end{document}

\@ifnextchar使用 进行比较\ifx,这是meaning术语expl3\@ifnextchar还会跳过空格,这与此处无关,但可能意味着您想要\peek_meaning_ignore_spaces:N(TF),具体取决于完整的上下文。

答案2

看来我用错了平等测试:我应该写:

\cs_generate_variant:Nn \token_if_eq_meaning:NNTF {NnTF}
\cs_new:Nn \ae_test_period: 
    {
        \token_if_eq_meaning:NnTF  \l_peek_token   { . } {  }  { .\@{~} }
    }

相关内容