pgfkeys 从参数中去掉括号

pgfkeys 从参数中去掉括号

这很可能是 pgfkeys 太急于摘掉我的牙套

如果我使用 将{[[To ]], [[From]]}作为可选参数的值传递给宏pgfkeys,最外层的括号将被剥离。如果我将其作为单个强制参数传递,则不会发生这种情况。

我已经使用了pgfkeys一段时间。它对我来说通常效果很好,并且具有我需要的功能,而其他类似的关键软件包可能并非如此。所以我想知道,假设这是另一个问题中描述的问题,而不是用户错误,有人可以提出解决方法吗?在参数中添加额外的空格\normalmacro没有帮助。它们都会被剥离。

作为背景,这是与 LuaTeX 一起使用的,将数组从 TeX 传递到 Lua,但不需要 Lua 来说明该问题。

由于这里的一对额外的括号不会对打印输出产生影响,因此只有在\typeout终端和控制台的输出中才能看到差异。

\documentclass[12pt]{scrartcl}
\usepackage{pgfkeys}

\newcommand\colnames{}

\pgfkeys
{
  /foo/.is family, /foo,
  default/.style =
  {
    colnames,
  },
  colnames/.estore in = \colnames,
  colnames/.default = {},
}
\begin{document}

\NewDocumentCommand{\usingpgfkeys}{O{}}
{
  \pgfkeys{/foo, default, #1}%                                                                                                      
  \typeout{USINGPGFKEYS RETURNS \colnames}\colnames
}
 
\usingpgfkeys[colnames={[[`To`]], [[`From`]]}]

\NewDocumentCommand{\normalmacro}{m}{\typeout{NORMALMACRO RETURNS #1}#1}

\normalmacro{{[[`To`]], [[`From`]]}}

\end{document}

答案1

pgfkeys在我看来,在括号剥离方面相当难以预测。这取决于所用的键处理程序(如果我没记错的话,我已经有一段时间没有仔细研究过了)。

比较以下内容(以expkv可预测地剥离括号的解析器为例 - 当然您可以使用另一个,我知道的是:,,,expkv和)。simplekvkvsetkeysl3keys

如果您的pgfkeys使用,你必须把在你的值周围加上几组括号,以便一个括号可以保留下来,但如果你在第一个括号前加了一个空格,你只需要或者如果你在第一个括号后加一个空格,你还需要。如果您大胆地在第一个括号前后放置一个空格,那么您将无法获得想要的输入。

\documentclass[12pt]{scrartcl}
\usepackage{pgfkeys}

\newcommand\colnames

\pgfkeys
{
  /foo/.is family, /foo,
  default/.style =
  {
    colnames,
  },
  colnames/.estore in = \colnames,
  colnames/.default = {},
}

% more or less identical definition to your pgfkeys using expkv-def
\usepackage{expkv-def}
\ekvdefinekeys{foo}
  {
     store   colnames = \colnames
    ,default colnames = {}
    ,meta    default  = {colnames}
    ,default default  = {}
  }
\NewDocumentCommand \usingexpkv { O{} }
  {%
    \ekvset{foo}{default, #1}%
    \typeout{BAR RETURNS \colnames}\colnames
  }
% similar macro definition using expkv-cs
\usepackage{expkv-cs}
\ekvcSplit\usingexpkvcs
  {
    colnames = {}
  }
  {\typeout{BARR RETURNS #1}#1}

\begin{document}

\NewDocumentCommand{\usingpgfkeys}{O{}}
{
  \pgfkeys{/foo, default, #1}%                                                                                                      
  \typeout{FEE RETURNS \colnames}\colnames
}

\usingexpkv[colnames={{[[`To`]], [[`From`]]}}]

\usingexpkvcs{colnames={{[[`To`]], [[`From`]]}}}
 
\usingpgfkeys[colnames={{{{[[`To`]], [[`From`]]}}}}]

\NewDocumentCommand{\normalmacro}{m}{\typeout{BAZ REURNS #1}#1}

\normalmacro{{[[`To`]], [[`From`]]}}

\end{document}

答案2

严格pgfkeys控制键和值的空间修剪和括号剥离可能需要比预期更多的努力,因此我猜近期不会出现完整的修复。也许应该从编写测试开始。

这是您可以用于密钥的技巧,但目前仅限于您的特定用途(/.estore in)。我猜想可能存在一种更强大、更通用的方案。

这个技巧要求用户在正常值之前添加一个标记命令,然后宏作者在键定义中修剪该命令。

\documentclass[12pt]{scrartcl}
\usepackage{pgfkeys}

\newcommand\colnames{}

\pgfkeys
{
  /foo/.is family, /foo,
  colnames/.estore in = \colnames,
  colnames/.default = {},
}
\begin{document}
\ttfamily

\NewDocumentCommand{\usingpgfkeys}{O{}}
{%
  \pgfkeys{/foo, colnames, #1}% `colnames` is used to init \colnames
  \detokenize\expandafter{\colnames}%
}
\newcommand\mymark{}
 
using pgfkeys:
% use `colnames={\mymark<normal value>}` to disable further brace stripping
\usingpgfkeys[colnames={\mymark{[[`To`]], [[`From`]]}}]


\NewDocumentCommand{\normalmacro}{m}{\detokenize{#1}}

normal macro:
\normalmacro{{[[`To`]], [[`From`]]}}
\end{document}

在此处输入图片描述

相关内容