TikZ 编程/宏,\list 构造

TikZ 编程/宏,\list 构造

TikZ 3.0 手册第 83 页有(不是完整的代码):

    \list{--}{\topsep=2pt\itemsep=0pt\parsep=0pt
    \parskip=0pt\labelwidth=8pt\leftmargin=8pt
    \itemindent=0pt\labelsep=2pt}
     #5
    \endlist

问题

  1. 将输入传递给命令的能力(#5 进入列表的--)就像这是一些 TikZ 属性,还是我们已经在纯 TeX 中拥有它了?
  2. 还有哪些命令允许我传递这样的输入?

上面的内容\list似乎不是 LaTeX,因为没有 \begin{list} 和 \end{list},而且上面的定义在 TeX 中使用输入 tikz.tex 也可以编译成功

抱歉,如果这太基础了,我正在尝试学习更多关于“魔法”的知识,但我对纯 TeX 了解不多(刚刚订购了 TeX 书)。

答案1

第一个问题:是\listLaTeX 吗?

首先,一个命令是否是 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 接口?

有很多,我希望有更多!很少有专门用于解析(解释)键值参数列表的包,并且具有定义键及其效果的功能。我知道的有

  1. keyval
  2. xkeyval
  3. pgfkeys
  4. LaTeX3 软件包提供类似的功能

在我看来,最强大、最易读的是pgfkeysPGF/TikZ 内部使用的那个。

但是 LaTeX 本身中唯一存在与 key-val 接口有点相似的东西的部分是documentclass参数;使用 key-val 接口是每个包的独立选择,你必须阅读每个包的文档才能理解它们使用的参数接口是什么(或者在它们的源代码中查找我提到的 key-val 包!)。

相关内容