![keyval 对空选项很挑剔](https://linux22.com/image/454978/keyval%20%E5%AF%B9%E7%A9%BA%E9%80%89%E9%A1%B9%E5%BE%88%E6%8C%91%E5%89%94.png)
我正在尝试借助 来自动生成 beamer 讲义\pgfpagesuselayout
。我希望它们在 1 页上有 2 张幻灯片,而我的同事则希望它们在横向上有 4 张幻灯片。因此,我们通过使用不同的作业名称编译文件并在我们的类中使用条件来生成两个版本,当作业名称包含-HANDOUT
或时,条件会更改行为-HANDOUT4
。请注意,\pgfpagesuselayout
默认情况下使用纵向,并且没有portrait
选项,只有landscape
。
我默认初始化为 2 on 1 :
\str_const:Nn \g__chato_beamer_slides_per_page {2~on~1}
\str_const:Nn \g__chato_beamer_orientation {}
当合适的情况出现时,我会将其改为
\str_gset:Nn \g__chato_beamer_slides_per_page {4~on~1}
\str_gset:Nn \g__chato_beamer_orientation {landscape}
最后,我想说
\pgfpagesuselayout{\str_use:N\g__chato_beamer_slides_per_page}[a4paper,\str_use:N\g__chato_beamer_orientation,border~shrink=5mm]
在 4 对 1 模式下,这个方法很好用。在 2 对 1 模式下,我得到
! Package keyval Error: undefined.
它似乎对空选项不太满意。所以我尝试将部分集成a4paper
到变量中。但是,在 4 对 1 模式下,我得到了
! Package keyval Error: a4paper,landscape undefined.
我知道我可以解决这个问题,通过使用条件来单独调用\pgfpageuselayout
,或者恢复到我的第一个解决方案但设置
\str_const:Nn \g__chato_beamer_orientation {a4paper}
(对于重复选项我没有任何抱怨a4paper
)
但是,有人知道为什么keyval
看起来这么挑剔吗?我的选择具体出了什么问题a4paper,landscape
?这是一个错误吗?
答案1
keyval
非常挑剔,因为它使用以下方法测试是否为空
\KV@@sp@def\@tempa{#1}%
\ifx\@tempa\@empty\else
并且如果您的\str_use:N \g__chato_beamer_orientation
不是\@empty
,则它使用 中的键的内容\csname
(它将尝试构建一个名称为空的键,因为 是\g__chato_beamer_orientation
空的)并测试结果是否为\relax
,如果是这种情况(它是,空键名称未定义)您将收到未定义的键错误,通过\PackageError
该错误将完全展开\@tempa
,因此您的 也是如此\str_use:N
,并且您会看到空消息。
要在宏中存储多个键和值(或不存储任何键和值,实际上,所有不同于没有值的单个键的内容),您需要在keyval
解析之前扩展字符串。\use:e
例如,可以使用 来完成(由于可选参数expl3
, 's\exp_args:N...
对您来说并不适用)。因此,以下应该可以工作(但显然我无法测试它,您没有显示可编译的示例):
\use:e
{
\exp_not:n { \pgfpagesuselayout }
{ \g__chato_beamer_slides_per_page }
[ a4paper, \g__chato_beamer_orientation, border~shrink=5mm ]
}
\str_use:N
请注意,如果您愿意,可以省略字符串。