![关于 pgfkeys 代码的一些问题](https://linux22.com/image/248548/%E5%85%B3%E4%BA%8E%20pgfkeys%20%E4%BB%A3%E7%A0%81%E7%9A%84%E4%B8%80%E4%BA%9B%E9%97%AE%E9%A2%98.png)
(1)在表达式中
\def\pgfkeysgetvalue#1#2{\expandafter\let\expandafter#2\csname pgfk@#1\endcsname}
#2
\relax
每当pgfk@#1
未定义时,都会被允许。这在 pgf 中是无害的吗?即使它是良性的,为什么不采用更正式的编码风格。
(2)在表达式中
\def\pgfkeysvalueof#1{\csname pgfk@#1\endcsname}
\pgfkeysvalueof{#1}
\relax
如果名称未定义,则将很简单pgfk@#1
。然后的参数\csname pgfk@#1\endcsname
将不被吸收(例如,将导致\@nodocument
LaTeX 文档环境之外)。为什么不需要先检查名称是否存在pgfk@#1
?
(3)为什么不能通过简单的抽象使下列表达式变得更加紧凑?
\long\def\pgfkeysdefnargs@#1#2#3#4{%
\ifcase#2\relax
\pgfkeyssetvalue{#1/.@args}{}%
\or
\pgfkeyssetvalue{#1/.@args}{##1}%
\or
\pgfkeyssetvalue{#1/.@args}{##1##2}%
\or
\pgfkeyssetvalue{#1/.@args}{##1##2##3}%
\or
\pgfkeyssetvalue{#1/.@args}{##1##2##3##4}%
\or
\pgfkeyssetvalue{#1/.@args}{##1##2##3##4##5}%
\or
\pgfkeyssetvalue{#1/.@args}{##1##2##3##4##5##6}%
\or
\pgfkeyssetvalue{#1/.@args}{##1##2##3##4##5##6}%
\or
\pgfkeyssetvalue{#1/.@args}{##1##2##3##4##5##6##7}%
\or
\pgfkeyssetvalue{#1/.@args}{##1##2##3##4##5##6##7##8}%
\or
\pgfkeyssetvalue{#1/.@args}{##1##2##3##4##5##6##7##8##9}%
\else
\pgfkeys@error{\string\pgfkeysdefnargs: expected <= 9 arguments, got #2}%
\fi
...
}
下面是我所指的抽象的伪代码:
initialize \pgfkeys@temptoks, \pgfkeys@tempcnta
\loop
\advance\pgfkeys@tempcnta\@ne
\edef\x{%
\pgfkeys@temptoks{\the\pgfkeys@temptoks\ifnum\pgfkeys@tempcnta
<\numexpr#1+1\relax<parameter chars>\the\pgfkeys@tempcnta\fi}%
}\x
\ifnum\pgfkeys@tempcnta<#1\relax
\repeat
在这里,如果您愿意的话,可以避免使用 eTeX。
答案1
没有检查\pgfkeysgetvalue
,\pgfkeysvalueof
因为这些方法假定所讨论的密钥存在。
事实上,\pgfkeysvalueof
设计的目的是可扩展(例如使用\edef\temp{\pgfkeysvalueof{/pgf/key}}
)。这里根本没有方法进行健全性检查(也许除了 lua 黑客攻击)。
检查密钥的首选方法是使用\pgfkeysifdefined{/pgf/key}{\pgfkeysgetvalue{/pgf/key}\temp}{... error handler ...}
。
答案2
冒着引起 Andrew Stacey 评论的风险,以下是我的想法,已包含在pgfkeys 补丁。
\pgfkeysnewdef*\pgfkeys@generateparameters#1#2{%
\ifnum#1<\numexpr#2+1\relax ####\number#1%
\expandafter\pgfkeys@generateparameters
\expandafter{\number\numexpr#1+1\expandafter}%
\expandafter{\number#2\expandafter}%
\fi
}
% Thanks to eTeX, \pgfkeys@generateparameters is expandable.
\pgfkeysnewdef\pgfkeysdefnargs@#1#2#3#4{%
\ifnum#2>9\relax
\pgfkeys@error{\string\pgfkeysdefnargs: I expected #2<=9 arguments but I saw #2}%
\else
\pgfkeyscsedef{pgfk@#1/.@args}{\pgfkeys@generateparameters{1}{#2}}%
\fi
...
}