以下代码说明我不了解 的最基本知识之一pgfkeys
。即定义密钥需要什么。我已经阅读了手册的第 87.3 节及后续章节,但我仍然对密钥的定义时间有点困惑。
我原本以为用类似列表的方式运行样式{assignlabel}
就足以定义assignlabel
键了。看来不行。这是因为我还没有给/assignlabel
键分配值吗?
如果我运行下面的代码,我会得到
ERROR: Package pgfkeys Error: I do not know the key
'/printdoctable/assignlabel/' and I am going to ignore it. Perhaps
you misspelled it.
但是,如果我取消注释该.estore
行,此错误就会消失。我不明白为什么。该行只是将任何已分配的值存储到宏中,\assignlabel
对吗?我还没有为该键分配任何值,那么为什么现在定义了它?而且似乎/.is choice
处理程序也不足以定义它。这.estore
行代码在这里有什么特别之处?
\documentclass[12pt]{article}
\usepackage{pgfkeys}
\usepackage{xparse}
\pgfkeys
{
/printdoctable/.is family, /printdoctable,
default/.style =
{
assignlabel,
},
assignlabel/.is choice,
% assignlabel/.estore in = \assignlabel,
assignlabel/true/.estore in={\assignlabel},
assignlabel/false/.estore in={\assignlabel},
}
\NewDocumentCommand{\PrintDocTable}{O{}}
{
\pgfkeys{/printdoctable, default, #1}%
%\assignlabel
}
\begin{document}
\PrintDocTable[assignlabel=false]
\end{document}
答案1
这是为了强调我们的聊天,由于篇幅过长,无法在此进行全面回顾。
首先,问题似乎是如何定义 pgf 密钥。简短的回答是
assignlabel/.is choice,
已经这样做了,
default/.style =
{
assignlabel,
},
没有必要。
然后就是为什么你的代码不起作用的问题。这是因为你的代码中assignlabel
需要一个参数。要消除错误,只需为添加默认值即可assignlabel
,例如
\documentclass[12pt]{article}
\usepackage{pgfkeys}
\usepackage{xparse}
\pgfkeys
{
/printdoctable/.is family, /printdoctable,
default/.style =
{
assignlabel,
},
assignlabel/.is choice,
assignlabel/true/.estore in={\assignlabel},
assignlabel/false/.estore in={\assignlabel},
assignlabel/.default=true,
}
\NewDocumentCommand{\PrintDocTable}{O{}}
{
\pgfkeys{/printdoctable, default, #1}%
%\assignlabel
}
\begin{document}
\PrintDocTable[assignlabel=false]
\end{document}
不会导致错误(但此时也不太有用)。
然后聊天中提到,如果你只想要一个布尔值,那么使用/.is if
key 可能更好。此 key 在 pgfmanual v3.1.4 的第 974 页中有描述
这里的代码示例非常好,因为它说明了键的作用。保罗的回答又加了一个例子。
不幸的是,在我看来,v3.1.4 的代码示例/.is choice
并不是最理想的。
有两个问题:
- 首先,正如你在TeX 聊天
butt cap
在我们的聊天中,和的角色round cap
互换了。 - 此外,前三个
/.style
键确实应该是/.code
键。
这问题已报告并且很可能会在下一版本的 pgf 中得到解决。
答案2
这是我的解决方案(如果我理解您的要求),其中我定义了一个新的 if(\ifprintdoctableassignlabel
):
\documentclass[12pt]{article}
\usepackage{pgfkeys}
\usepackage{xparse}
\newif\ifprintdoctableassignlabel
\pgfkeys
{
/printdoctable/.is family,
/printdoctable,
assignlabel/.is if=printdoctableassignlabel,
default/.style={assignlabel=true},
}
\NewDocumentCommand{\PrintDocTable}{O{}}
{
\pgfkeys{/printdoctable,default,#1}%
\ifprintdoctableassignlabel
assignlabel is true
\else
assignlabel is false
\fi
}
\begin{document}
\PrintDocTable\par
\PrintDocTable[assignlabel=false]\par
\PrintDocTable[assignlabel=true]
\end{document}
结果:
分配标签为真
分配标签为假
分配标签为真
以下是使用处理程序的示例.is choice
:
\documentclass[12pt]{article}
\usepackage{pgfkeys}
\usepackage{xparse}
\newif\ifprintdoctableassignlabel
\pgfkeys
{
/printdoctable/.is family,
/printdoctable,
%
assignlabel/.is if=printdoctableassignlabel,
assignlabel/.default=true,
%
label/.is choice,
label/a/.code={\def\printdoctablelabel{choice a}},
label/b/.code={\def\printdoctablelabel{choice b}},
label/c/.code={\def\printdoctablelabel{choice c}},
%
predefined values/.style={
assignlabel=true,
label=a,
},
}
\NewDocumentCommand{\PrintDocTable}{O{}}
{%
\pgfkeys{/printdoctable,predefined values,#1}%
\ifprintdoctableassignlabel%
assignlabel is true%
\else%
assignlabel is false%
\fi%
\space(label=\printdoctablelabel)%
}
\begin{document}
\PrintDocTable[label=b]
\PrintDocTable[assignlabel=false]
\PrintDocTable[assignlabel,label=c]
\end{document}
结果:
assignlabel 为真(标签=选择 b)
assignlabel 为假(标签=选择 a)
assignlabel 为真(标签=选择 c)
答案3
首先,非常感谢@Schrödinger 的猫在聊天中非常耐心地回答我的问题,并给出了有用的答案。我认为如果我能总结一下上述问题中出现的困惑,那会有所帮助。我想我现在理解得更清楚了。虽然 PGF/TikZ 手册很好(而且比大多数文档(无论是 TeX 相关还是其他方面)都要好得多),但仍有几件事需要强调。
从顶部开始,出于某种原因,我似乎认为
default/.style =
{
assignlabel,
},
实际上初始化了相关键(在本例中为assignlabel
)。事实证明,这是大错特错的。处理程序实际上所做的只是在键(在命名空间内)和键值对列表.style
之间设置一种别名。因此,如果处理程序设置在该键上,则调用该处理程序会调用该键列表。但它实际上并没有定义任何这些键。这是一个重要的细节。default
printdoctable
.style
然而,这两条线路
assignlabel/.is choice,
和
assignlabel/.estore in = \assignlabel,
定义一个键。然而,这还不够,因为我写的方式assignlabel
没有默认值。所以当我调用
\pgfkeys{/printdoctable, default, #1}%
在我的回答中,default
部分出错了,因为它实际上是在调用assignlabel,
。此时它没有默认值。如果没有指定值,则组成 RHS 的键值对会.style
期望默认值。不过我仍然不确定错误消息的原因:
I do not know the key '/printdoctable/assignlabel/'
而不是抱怨没有分配值,这肯定会产生更好的错误消息。但由于 Tex 实际上没有变量或变量分配,所以它可能是一个 TeX 工件。
正如 @schrodinger's cat 解释的那样,解决这个问题的一种方法是assignlabel
使用
assignlabel/.default=true,
另一种方法是写
default/.style =
{
assignlabel=false,
},
它为键值对提供所需的值。