我想使用\def
之前使用过的 expl3 来解析下标和上标:
\documentclass{article}
\usepackage{expl3}
\ExplSyntaxOn
\cs_new:Npn \l__parsing_parse_superscript:n ^#1 {superscript = #1}
\cs_new:Npn \l__parsing_parse_subscript:n _#1 {subscript = #1}
\NewDocumentCommand\parsesuperscript{}{\l__parsing_parse_superscript:n}
\NewDocumentCommand\parsesubscript{}{\l__parsing_parse_subscript:n}
\ExplSyntaxOff
\begin{document}
\noindent
\parsesuperscript^10\\
\parsesubscript_100 % TODO error
\end{document}
上标解析正确。但是下标会出现错误,可能是因为\ExplSyntaxOn
下划线被视为字母。我也尝试在命令定义中使用\c_underscore_str
和 而\c_math_subscript_token
不是_
。如何转义下划线以解析下标?或者是否有其他解决方案可用于解析带有 expl3 的参数?
参考:
答案1
您的诊断是正确的:问题在于expl3
语法中,_
有 catcode 11。但是使用\c_underscore_str
也不好,因为它有 catcode 12,但在文档中_
(通常)有 catcode 8。
在您的定义中,您必须对下划线强制执行 catcode 8:
\ExplSyntaxOn
\cs_new:Npn \__michael_parse_superscript:w ^#1 {superscript = #1.}
\use:e
{
\cs_new:Npn \exp_not:N \__michael_parse_subscript:w
\char_generate:nn { `\_ } { 8 } #1
{subscript = #1.}
}
\NewDocumentCommand\parsesuperscript{}{\__michael_parse_superscript:w}
\NewDocumentCommand\parsesubscript{}{\__michael_parse_subscript:w}
\ExplSyntaxOff
(还要注意,使用 时\parsesubscript_100
,只有1
被抓取作为参数:您需要\parsesubscript_{100}
)。
但这并不是真正的解析,因为如果您使用该命令时不带以下内容_
,^
则会出错。您可以改用e
-type 参数(请注意,无论实际参数出现的顺序如何,它都可以正常工作):
\documentclass{article}
\usepackage{expl3}
\NewDocumentCommand \parsesupsub { e{^_} }
{
\IfValueT{#1}{superscript = #1.\\}
\IfValueT{#2}{subscript = #2.\\}
}
\parindent=0pt
\parskip=10pt
\begin{document}
\parsesupsub^{10}
\parsesupsub_{100}
\parsesupsub_{100}^{10}
\parsesupsub^{10}_{100}
\end{document}
您也可以使用 手动进行解析\peek_charcode_remove:NTF _ { <with> } { <without> }
,那么无论 的当前 catcode 是什么,它都会起作用_
。
关于命名(我写了一个解释这里),\l_
(或\g_
或\c_
) 前缀应仅用于变量。您正在定义命令,因此它们应以\module_...
if public 或\__module_...
if private 开头(我用作michael
模块名称)。此外,正如 Gaussler 在评论中指出的那样,:n
参数类型应为“普通”参数(以{
...分隔的标记}
)。由于参数文本中有一个“奇怪”的标记,因此您应该使用:w
。