当我尝试编译时
\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}