Argument of \\drs has an extra }.
当我尝试处理以下内容时,出现以下信息:
\documentclass{article}
\usepackage{tikz}
\newcommand{\drs}[2][lambda/.initial={}]{%
\{%
{\pgfkeys{/drs/.cd, #1, print}}%
\}%
}
\pgfkeys{/drs/.cd,
print/.code = {\pgfkeysvalueof{/drs/lambda}},
lambda/.code = {%
\pgfkeys{/drs/.cd,
list/.list = {#1},
}%
},
list/.code = {\pgfkeys{/drs/lambda/.append = (#1)}}
}
\begin{document}
\drs[lambda={a,b,{\drs[lambda={x}]{Bar}}}]{Foo}
\end{document}
但括号的数量是正确的。我怀疑这与宏扩展的顺序有关。
任何帮助将不胜感激。
编辑:发现一个相关错误(我认为):
\documentclass{article}
\usepackage{tikz}
\makeatletter
\pgfkeys{/drs/.cd,
%
% lambda
%
lambda/.code={%
\pgfkeys{/drs/.cd,
lambda list/.list={#1},
lambda string
}%
},
lambda list/.code={\pgfkeys{/drs/lambda/.append={$\lambda$#1.}}},
lambda string/.code=\def\draw@drs@lambda{\pgfkeysvalueof{/drs/lambda}},
%
% presupposition
%
presupposition/.code={%
\pgfkeys{/drs/.cd,
presupposition list/.list={#1},
presupposition string
}%
},
presupposition list/.code={\pgfkeys{/drs/presupposition/.append={#1}}},
presupposition string/.code={\def\draw@drs@presupposition{\pgfkeysvalueof{/drs/presupposition}}},
}
\newcommand{\drs}[2][]{%
\begingroup%
\def\mymacroempty{}%
% DRS building blocks
\def\draw@drs@presupposition{}%
\def\draw@drs@lambda{}%
\pgfkeys{/drs/.cd,
presupposition/.initial={},
lambda/.initial={},
#1
}%
[ presupposition: \draw@drs@presupposition ]%
\endgroup%
}
\makeatother
\begin{document}
\drs[presupposition={\drs[presupposition={m}]{}}]{%
Foo%
}
\end{document}
一切按预期进行,并打印出来
[ presupposition: [ presupposition: m]]
向嵌套\drs
调用添加 lambda 选项
\drs[presupposition={\drs[lambda=x,presupposition={m}]{}}]{%
Foo%
}
生产
[ presupposition: [ presupposition: ]]
嵌套的预设被吞噬了。我猜这又和扩展时间有关,但我不知道该如何修复它。:-)
答案1
这是一个微妙的!
当前的问题出在这一行:
list/.code = {\pgfkeys{/drs/lambda/.append = (#1)}}
一些测试表明这\pgfkeys
被视为=
特殊事物。因此,任何带有的东西都=
必须受到保护。您可以使用以下方法进行测试:
\pgfkeys{/drs/lambda/.append = hello=world}
\pgfkeys{/drs/lambda/.show value}
\pgfkeys{/drs/lambda/.append = {hello=world}}
\pgfkeys{/drs/lambda/.show value}
第一次,只会hello
显示在日志中。第二次,我们得到全部hello=world
。因此,由于\drs...
列表中的位包含=
,因此需要对其进行保护。
乍一看,你似乎已经这样做了,因为你是{\drs[lambda={x}]{Bar}}
列表中的一个术语。但再多做一些实验就会发现,/.list
迭代器会剥离所有分组,那么实际上传递的是\drs[lambda={x}]{Bar}
调用:
\pgfkeys{/drs/lambda/.append = (\drs[lambda={x}]{Bar})
这会触发错误。直接的解决方案是在list/.code
代码中加上括号:
list/.code = {\pgfkeys{/drs/lambda/.append = {(#1)}}}
测试的值/drs/lambda
表明它现在得到了正确的东西。
但是,修复这个问题后,你会发现你的程序有一个小问题!由于扩展的顺序,内部\drs
执行后最外层的一个,因此它将 视为(a)(b)(\drs[lambda={x}]{Bar})
的初始值/drs/lambda
,向其添加一个\{(x)\}
,然后再次打印出完整值:(a)(b)(\drs[lambda={x}]{Bar})\{(x)\}
。其中包含对 的另一个调用\drs
。等等。等等。
您可以尝试通过在附加之前完全展开列表的参数来反转扩展顺序,#1
但我遇到了麻烦(我不完全理解,但似乎与 LaTeX 处理带有可选参数的命令的方式有关)。另一种方法是/drs/lambda
在每次调用时都将其清空drs
,因为在执行内部调用时,外部调用已经完成其工作并且不再需要。有几种(等效)方法可以做到这一点。例如,
\newcommand{\drs}[2][lambda/.initial={}]{%
\{%
{\pgfkeys{/drs/.cd, lambda/.initial={}, #1, print}}%
\}%
}
(这反而违背了默认参数的目的,因此可以将其删除。)
通过这两项修改,我得到:
{(a)(b)({(x)})}
用于输出。
更新:(回答更新后的问题)。第二个问题也是关于分组(而不是扩展)。当被.list
调用时,它会看到:
\drs [presupposition={m},lambda={a}]{}
就它而言,逗号是公平的。方括号定义的伪分组被忽略,因为它不是真正的分组。因此它将其拆分为\drs[presupposition={m}
和lambda={a}]{}
。这会弄乱以下内容。
修复这个问题取决于你还想用这些宏实现什么目的,以及你希望能够处理哪些其他类型的输入。最简单的修复方法是让宏\drs
有两个强制参数,而不是一个可选参数和一个强制参数。这将确保内部调用的参数\drs
受到保护,不会被外部调用拆分。另一种方法是在参数中使用键值对,从而\drs
获得单身的参数是一个列表,然后由 进行处理\pgfkeys
。