pgfkeys 能处理活动逗号吗?

pgfkeys 能处理活动逗号吗?

当我尝试编译时

\begingroup
\def\iden#1{#1}
\catcode`\,=13
\catcode`\==13
\iden{\endgroup
  \pgfkeys{/my family/.is family}
  \pgfkeys{/my family/my keys/.cd,
    keya/.code=\def\mywidth{##1},
    keyb/.code=\def\mydefault{##1}%
  }%
}

我收到错误

{\edef}
\pgfkeyscurrentkey ->/my family/my keys/.cd, keya/.code
{undefined}
! Undefined control sequence.
\pgfkeyscurrentkey ->/my family/my keys/.cd,

请问我该如何克服这个问题?鍵盤“首席执行官(使用 Knuth 的术语)似乎无法固有地处理主动解析器。

答案1

原始答案

一般来说,只要使用分隔参数匹配来解析值列表,重新定义列表语法字符的 catcode 就会是一个问题(LaTeX 列表也是如此)。

可以重新定义\pgfkeys@@set为 re-catcode ,=如下所示:

\makeatletter
\long\def\pgfkeys@@set#1#2{%
  \let\pgfkeysdefaultpath\pgfkeys@root%
  {\catcode`\,=12\catcode`\==12
  \scantokens{\def\mytmp{#2}}%
  \expandafter
  }%
  \expandafter\pgfkeys@parse\mytmp,\pgfkeys@mainstop%
  \def\pgfkeysdefaultpath{#1}}
\makeatother

由于您的 MWE 没有产生任何输出,因此我没有得到太多的测试结果,但至少我没有收到任何错误 ;-)

不知道这是否是您正在寻找的那种通用的稳健解决方案......

编辑

请参阅下面的评论,了解为什么上述做法不是一个好主意。\scantokens将停用全部,和的实例=在其参数中,也在键的值中,它们需要处于活动状态才能实现它们最初被激活的目的。

根据下面 Joseph Wright 的评论,这里有一个涉及该kvsetkeys包的“解决方案”(这显然是一个非常乏味的工作。感谢 Heiko 取得的这一成就!):

\usepackage{kvsetkeys}
\usepackage{tikz}

\makeatletter
\long\def\pgfkeys@@set#1#2{%
  \let\pgfkeysdefaultpath\pgfkeys@root%
  \kv@normalize{#2}%
  \expandafter\pgfkeys@parse\kv@list,\pgfkeys@mainstop%
  \def\pgfkeysdefaultpath{#1}}
\makeatother

再次,我没有收到任何错误:-)

我很想知道这种方法的缺点是什么。

答案2

编辑(2012/04/21)

我需要更正和扩展包中的一些行,但超出了网站 30000 个字符的限制。因此,我已将包移至 CTAN,如下所示密钥

例子

\documentclass{article}
\usepackage{pgfkeys}
\usepackage{pgfkeyx}
\makeatletter

\begingroup
\def\iden#1{#1}
\catcode`\/=13
\catcode`\,=13
\catcode`\==13
\iden{\endgroup
  \pgfkeys{%
    % The spaces here are just examples of how they are removed by
    % normalization:
    / my family / .is family,
    /my family/my keys/.cd,
    keya / .code = \def\keyavalue{#1},
    keya/.default = {keya-default},
    keyb / .code = \def\myvalueb{#1},
    keyb /.default=keyb-default,
    .normal code=\def\x#1{#1},
    keyc/.code=\pgfqkeysalso\pgfkeyscurrentpath{#1},
    keyc/.value required,
    keyd/.is if with 2 callbacks =
      {true}{\def\x##1{##1-True-#1}}{\def\x##1{##1-False-#1}},
  }%
}

\pgfkeys{%
  /my family/my keys/.cd,
  keya={x},
  keyb=aa,
  keyc = {keya=aa, keyb=bb},
}

\pgfkeys{%
  /my family/my keys/.cd,
  keya/.restore default,
  .restore key defaults={keya,keyb}
}

\makeatother

\begin{document}
\pgfkeys{%
  /my family/my keys/keyd=true,
}
\ifkeyd
`keyd' is true.
\fi
%\show\x
\end{document}

相关内容