[请将此问题视为一个无实际意义的问题/“学术”问题。]
LaTeX 内核命令\newcommand
发明于几十年前解释3,解析并且\NewDocumentCommand
可用。
\newcommand
带来了可选参数的概念,即形成可选参数的标记需要嵌套在[
和之间]
。
对于按照\newcommand
处理可选参数的方式定义的宏,只有左方括号的存在才会[
被检测为可选参数存在的指示。匹配项的存在]
不会被检测。
用于检测明确提供的可选参数的开头是否存在的 LaTeX 2ε“机制”[
由内核宏\@protected@testopt
、\@testopt
和组成。\@x@protect
\kernel@ifnextchar
\kernel@ifnextchar
仅“查看”下一个标记的含义。
[
因此,可以通过提供catcode 12 的隐式形式来欺骗“机制” :
例如,定义后
\newcommand\mymacro[1][default]{optional argument: (#1)}
以下情况会导致奇怪的错误消息:
\let\lbracket=[
\mymacro\lbracket something
我期望这会产生以下输出:
,[
来自隐含的\lbracket
。
我的问题是:
为什么用于检测明确提供的可选参数的开头是否存在的 LaTeX 2ε 内核机制[
无法解决隐式的情况[
?
\@testopt
这可以通过如下定义轻松实现:
\newcommand\ExplicitImplicitFork[3]{%
\ForkExplicitImplicit!#3!{#1}![!{#2}!!!!#3%
}%
\@ifdefinable\ForkExplicitImplicit{%
\long\def\ForkExplicitImplicit#1![!#2#3!!!!{#2}%
}%
\renewcommand\@testopt[2]{%
\kernel@ifnextchar[{\ExplicitImplicitFork{#1}{#1[{#2}]}}{#1[{#2}]}%
}%
(在\kernel@ifnextchar
检测到其含义等于其含义的东西的情况下,显然存在既不同又可以作为未限定的参数进行处理/检查/“抓取”的东西......)[12
!
例如,尝试
\documentclass{article}
\makeatletter
\newcommand\ExplicitImplicitFork[3]{%
\ForkExplicitImplicit!#3!{#1}![!{#2}!!!!#3%
}%
\@ifdefinable\ForkExplicitImplicit{%
\long\def\ForkExplicitImplicit#1![!#2#3!!!!{#2}%
}%
\renewcommand\@testopt[2]{%
\kernel@ifnextchar[{\ExplicitImplicitFork{#1}{#1[{#2}]}}{#1[{#2}]}%
}%
\makeatother
\newcommand\mymacro[1][default]{optional argument: (#1)}
\begin{document}
With the modified \verb|\@testopt| this works out instead of leading to inscrutable error-messages:
\let\lbracket=[
\mymacro\lbracket something
\hrulefill
\mymacro something
\hrulefill
\mymacro[optional]something
\end{document}