该命令\@ifnextchar
不能用于\section
和类似命令中。它失败并显示“TeX 容量超出”消息。这显然与目录和/或页码标记的节名回收有关,如以下最小对所示:
\documentclass{article}
\begin{document}
\makeatletter
\section[Safe command]{This: \@ifnextchar /{A}{B} works fine}
\section{This: \@ifnextchar /{A}{B} triggers an error}
The end.
\end{document}
我认为我已经排除了表面上的名称冲突,所以我把希望寄托在稳健性上。有没有我可以尝试的稳健版本,或者有其他方法可以解决这个限制?
笔记
我看到过一些关于
expl3
等效问题的讨论(例如,这里,但没有讨论稳健性。\@ifnextchar
我实际上正在使用一个不会跳过空格的自构造变体,所以最终我正在寻找具有相同属性的解决方案。这一切都与 gb4e 上的错误报告有关,Alan Munn 引起了我的注意。
编辑:
因为显然我的最小例子是也最小,这是实际用例(仍然简化):
在 中gb4e
,^
和_
被转换为\active
字符,以便它们可以在数学模式之外使用。为了正确地切换进出数学模式,它们需要检查下一个命令是否也是下标或上标命令,因此调用\@ifnextchar
(或者实际上是修改后的版本,但这里无关紧要)。
\documentclass{article}
\makeatletter
\catcode`\_=\active
\catcode`\^=\active
\def_#1{\@ifnextchar^{\automath@two_{#1}}{\ensuremath{\sb{#1}}}}
\def^#1{\@ifnextchar_{\automath@two^{#1}}{\ensuremath{\sp{#1}}}}
% handle consecutive sub- and super- scripts:
\def\automath@two#1#2#3#4{\ensuremath{#1{#2}\relax #3{#4}}}
\begin{document}
\section{This A_B fails}
\end{document}
答案1
您应该使用\protected\def
;这需要 e-TeX 扩展,然而,该扩展在 LaTeX 中已经活跃了好几年。
\documentclass{article}
\makeatletter
{ % Temporarily change catcodes
\catcode`\_=\active
\catcode`\^=\active
\global\def\automath{%
\catcode`\_=\active
\catcode`\^=\active
\protected\def_##1{\gb@ifnextchar^{\automath@two\sb{##1}}{\ensuremath{\sb{##1}}}}%
\protected\def^##1{\gb@ifnextchar_{\automath@two\sp{##1}}{\ensuremath{\sp{##1}}}}}
}
\def\automath@two#1#2#3#4{\ensuremath{#1{#2}#3{#4}}}
% Restore default catcodes for ^, _
\def\noautomath{\catcode`\_=8 \catcode`\^=7 }
% The original \@ifnextchar discards spaces when looking for the next
% ``character''. This variant accepts any token.
\long\def\gb@ifnextchar#1#2#3{%
\let\reserved@d=#1%
\def\reserved@a{#2}%
\def\reserved@b{#3}%
\futurelet\@let@token\@gbifnch}
\def\@gbifnch{%
\ifx\@let@token\reserved@d
\let\reserved@c\reserved@a
\else
\let\reserved@c\reserved@b
\fi
\reserved@c}
\makeatother
\begin{document}
\automath
\section{A subscript_{s}^{t}}
\section{A subscript^{t}_{s}}
\section{A subscript_{s} ^{t}}
\section{A subscript^{t} _{s}}
\end{document}
您可能必须在包的开头添加对 e-TeX 扩展是否存在的检查。
\gb@ifnextchar
我在聊天中从 Alan Munn 那里得到了定义。
答案2
\@ifnextchar
在移动参数(例如 的主参数)中使用脆弱命令(例如使用 定义的命令)的标准指令\section
是在其前面加上\protect
。