关于 pgfkeys 代码的一些问题

关于 pgfkeys 代码的一些问题

(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将不被吸收(例如,将导致\@nodocumentLaTeX 文档环境之外)。为什么不需要先检查名称是否存在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
  ...
}

相关内容