外部文件的自定义 xparse 命令中的下标问题

外部文件的自定义 xparse 命令中的下标问题

编译此代码时:

\documentclass{article}

\usepackage{testPackage}
\usepackage{xparse}

\NewDocumentCommand{\foo}{mm}{#1_{#2}}

\begin{document}
$\foo A i$, $\fooT A i$
\end{document}

其中testPackage包括定义:

\usepackage{xparse}
...
\ExplSyntaxOn
...
\NewDocumentCommand{\fooT}{mm}{#1_{#2}}
...
\ExplSyntaxOff

我得到输出:

在此处输入图片描述

尽管两个命令执行相同的操作,但为什么在第二个版本中下标排版不正确?

答案1

我假设 OP 已经将\ExplSyntaxOn...\ExplSyntaxOff定义为包装器\fooT。这当然会改变 catcodes,并且_会以不同的方式进行解释。

如果不需要任何语法expl3(例如 think of\cs_new:N等),请不要使用\ExplSyntax...。 就\NewDocumentCommand足够了!

\documentclass{article}

%\usepackage{testPackage}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\fooT}{mm}{#1_{#2}}
\ExplSyntaxOff
\NewDocumentCommand{\fooother}{mm}{#1_{#2}}
\NewDocumentCommand{\foo}{mm}{#1_{#2}}

\begin{document}
$\foo{A}{i}$, $\fooT{A}{i}$, $\fooother{A}{i}$
\end{document}

在此处输入图片描述

答案2

\ExplSyntaxOn和之间的惯例\ExplSyntaxOff基本上是:

  1. 空格和行尾会被忽略(当然,在控制序列名称的中间不会被忽略)

  2. _并且:可以(并且应该)成为控制序列名称的一部分,因此它们具有类别代码 11(字母)

  3. ~与普通的太空令牌相同

这样做的结果是_不能在数学模式下使用 来引入下标。原因很常见:如果你这样做

\ExplSyntaxOn
\NewDocumentCommand{\fooT}{mm}{#1_{#2}}
\ExplSyntaxOff

当 为字母时,的替换文本\fooT会被标记化,因此每次调用_时都会如此。\fooT

为了解决这个问题,expl3内核提供了

\c_math_subscript_token

_因此,当定义主体中需要 8 时,您应该使用它,无论是引入下标还是进行\peek_...测试检查。

使用\sb也是可能的,这在上面的代码中可能更有吸引力;所以

\ExplSyntaxOn
\NewDocumentCommand{\fooA}{mm}{#1\c_math_subscript_token{#2}}
\ExplSyntaxOff

或者

\ExplSyntaxOn
\NewDocumentCommand{\fooA}{mm}{#1\sb{#2}}
\ExplSyntaxOff

是等效的。前一种语法最好在纯expl3上下文中使用。

答案3

如果由于某种原因需要在 expl3 语法中使用下标,则可以随时使用\sb

\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\fooT}{mm}{#1\sb{#2}}
\ExplSyntaxOff

相关内容