TikZ 3.0 手册第 83 页有(不是完整的代码):
\list{--}{\topsep=2pt\itemsep=0pt\parsep=0pt
\parskip=0pt\labelwidth=8pt\leftmargin=8pt
\itemindent=0pt\labelsep=2pt}
#5
\endlist
问题:
- 将输入传递给命令的能力(#5 进入列表的--)就像这是一些 TikZ 属性,还是我们已经在纯 TeX 中拥有它了?
- 还有哪些命令允许我传递这样的输入?
上面的内容\list
似乎不是 LaTeX,因为没有 \begin{list} 和 \end{list},而且上面的定义在 TeX 中使用输入 tikz.tex 也可以编译成功
抱歉,如果这太基础了,我正在尝试学习更多关于“魔法”的知识,但我对纯 TeX 了解不多(刚刚订购了 TeX 书)。
答案1
第一个问题:是\list
LaTeX 吗?
首先,一个命令是否是 LaTeX 通常意味着:它是否以 LaTeX 格式定义?如果是\list
,则它是在 LaTeX 中定义的,它不是 TeX 的原始形式,也不是在 plainTeX 中定义的。
其次,您可能想知道这是否是 LaTeX,因为它不遵循\begin{list}
-\end{list}
样式。我之所以称其为这种样式,是因为\begin
和\end
本身就是在 LaTeX 中定义的命令,而不是基元,因此没有什么可以阻止您重新定义它们、直接使用它们的定义或将它们隐藏在其他宏中。具体来说,
\begin{something}{arg}
content
\end{something}
这是基本上扩展为
\something{arg}content\endsomething
因此,问题中的代码是 LaTeX,因为它使用以 LaTeX 格式定义的宏,而不仅仅是 TeX。它不遵循 LaTeX 样式,但与其等效。当涉及解析的复杂性(例如查找以\endsomething
了解环境何时结束)时,您通常会找到此等效版本。
第二个问题:kev-val 参数
我猜当你写“像这样传递输入”时,你的意思是“以 key-val 样式传递参数”。
让我们看看普通风格和 key-val 风格之间的区别。
当你写作时
\newcommand{\bla}[2]{Hi #1, #2 #2 bla}
为了正确使用\bla
,您必须在花括号中指定一个强制参数(这又与 LaTeX 约定有关),如下所示:
\bla{Manu}{bye} % produces Hi Manu, bye bye bla
我们将这种风格称为“位置参数”。这很简单,但是当你的宏需要很多参数时,可能不是所有参数都是必需的,1) 编写宏 2) 记住哪个参数是哪个,就会变得非常麻烦。可以在命令中找到一个\cventry
示例moderncv
。
由于 TikZ 允许您自定义每个图形项目的各个方面,如果使用带有位置参数的标准接口,那么记住哪个参数意味着什么、哪个是可选的、哪个不是等将非常困难。相反,这是 TikZ 的优势之一,他们定义了一个名为的包,pfgkeys
允许您解析一串 key-val 参数并对其进行处理。我所说的 key-val 参数是指
color=red, draw, right=1 of a
现在请注意如何使用这些类型的参数:
\tikz[color=red, draw, right=1 of a] {...}
这表明该\tikz
命令有一个可选参数和一个强制参数,理想情况下:
\newcommand{\tikz}[2][]{
% #1 contains an optional list of key-val args
% #2 contains some other stuff describing graphics
}
因此,您会看到,key-val 参数仍然打包成单个位置参数。\tikz
内部所做的是将该参数传递给“解析 key-val”宏,该宏能够将 key-val 列表分解为其项,并根据键的定义方式(在其他地方)对其进行相应的操作。
我建议阅读 PGF 手册的“密钥管理”部分,pgfkeys
软件包是非常强大的。
回到\list
现在,你可能已经注意到,你的例子与我上面写的 key-val 代码有点不同:我的键不是以 开头的\
。这就是主要的区别!\list
宏在内部做了什么理想情况下工作原理如下:
\newenvironment{list}[2]{
% do some fancy stuff
\begingroup % limit the scope of modifications to this env
#2 % just execute whatever is in arg 2
\def\labelitemi{#1} % set the label of items to be arg 1
% other fancy stuff to start the list
}{
\endgroup
% code to end the list
}
这是不是实际发生了什么,但它很适合说明。请注意,arg 1 只是为了让您能够在花哨的东西之间插入代码\list
,而不是在所有东西之前或之后插入代码。具体来说,示例代码绑定#1
到
\topsep=2pt\itemsep=0pt\parsep=0pt
\parskip=0pt\labelwidth=8pt\leftmargin=8pt
\itemindent=0pt\labelsep=2pt
它可能看起来像一个 key-val 列表,但实际上不是!这个列表确实不是需要解析才能理解,它只是一段可以按原样执行的代码。各种作业基本上相当于 LaTeX\setlength{\topsep}{2pt}
。所以长度您可以使用可读的、看起来很像 key-val 接口的赋值语法,但它是长度的特殊性(仅此而已)。
还有哪些包使用 key-val 接口?
有很多,我希望有更多!很少有专门用于解析(解释)键值参数列表的包,并且具有定义键及其效果的功能。我知道的有
keyval
xkeyval
pgfkeys
- LaTeX3 软件包提供类似的功能
在我看来,最强大、最易读的是pgfkeys
PGF/TikZ 内部使用的那个。
但是 LaTeX 本身中唯一存在与 key-val 接口有点相似的东西的部分是documentclass
参数;使用 key-val 接口是每个包的独立选择,你必须阅读每个包的文档才能理解它们使用的参数接口是什么(或者在它们的源代码中查找我提到的 key-val 包!)。