禁止/要求某些 pgfkeys?

禁止/要求某些 pgfkeys?

我有一些命令,其命名参数由 pgfkeys 处理

\dog[breed=Labrador, name=Fido]
\human[name=John, car owned=Porsche]

我该如何安排

\dog[breed=Labrador, car owned=Rover]

给出错误信息Invalid key 'car owned',并且

\dog[name=Fido]

给出错误信息Missing required key 'breed'

这里有一个可以用作起点的 MWE。

\documentclass{article}
\usepackage{pgfkeys}

\makeatletter
\pgfkeys{/wickerson/.cd,
  breed/.store in =     {\wickerson@breed},
  name/.store in =      {\wickerson@name},
  car owned/.store in = {\wickerson@carowned}
}

\newcommand*\dog[1][]{%
  \pgfkeys{/wickerson/.cd, name=noName, breed=noBreed, #1}
  Dog is a {\wickerson@breed} and is called {\wickerson@name}.\par
}

\newcommand*\human[1][]{%
  \pgfkeys{/wickerson/.cd, name=noName, car owned=noCar, #1}
  Human is called {\wickerson@name} and owns a {\wickerson@carowned}.\par
}
\makeatother

\begin{document}

\dog[breed=Labrador, name=Fido]       % GOOD
\human[name=John, car owned=Porsche]  % GOOD
\dog[breed=Labrador, car owned=Rover] % BAD (irrelevant key given)
\dog[name=Fido]                       % BAD (required key missing)

\end{document}

答案1

根据要求将评论转换为答案。请注意,这是我第一次使用键值系统,因此不确定这种方法是否存在任何问题,但它确实满足了这个特定示例的两个要求:

  • 只能指定有效的密钥
  • 未指定的键将被标记为错误

dogkeys通过定义单独的和可以满足第一个要求humankeys。对于第二个要求,我们可以检查字符串值是否是默认值,以了解未提供该值。

笔记:

  • 包裹xstring用于字符串比较。

  • 这两个错误情况已被注释掉。否则将按预期产生错误。

代码:

\documentclass{article}
\usepackage{pgfkeys}
\usepackage{xstring}

\makeatletter
\pgfkeys{/dogkeys/.cd,
  breed/.store in =     {\wickerson@breed},
  name/.store in =      {\wickerson@name},
}
\pgfkeys{/humankeys/.cd,
  name/.store in =      {\wickerson@name},
  car owned/.store in = {\wickerson@carowned}
}

\newcommand*\CheckKeyIsNotDefaultValue[4]{%
    % #1 = package name (for error reporting)
    % #2 = key name
    % #3 = default key value (report error if key value matches)
    % #4 = actual value of key
  \IfStrEq{#4}{#3}{%
        \PackageError{#1}{Key '#2' not provided.}{}%
  }{}%
}

\newcommand*\dog[1][]{%
  \pgfkeys{/dogkeys/.cd, name=noName, breed=noBreed, #1}
  \CheckKeyIsNotDefaultValue{dogkeys}{breed}{noBreed}{\wickerson@breed}%
  \CheckKeyIsNotDefaultValue{dogkeys}{name}{noName}{\wickerson@name}%
  Dog is a {\wickerson@breed} and is called {\wickerson@name}.\par
}

\newcommand*\human[1][]{%
  \pgfkeys{/humankeys/.cd, name=noName, car owned=noCar, #1}
  \CheckKeyIsNotDefaultValue{humankeys}{name}{noName}{\wickerson@name}%
  \CheckKeyIsNotDefaultValue{humankeys}{car owned}{noCar}{\wickerson@carowned}%
  Human is called {\wickerson@name} and owns a {\wickerson@carowned}.\par
}
\makeatother

\begin{document}

\dog[breed=Labrador, name=Fido]        % GOOD
\human[name=John, car owned=Porsche]   % GOOD
%\dog[breed=Labrador, car owned=Rover] % BAD (irrelevant key given)
%\dog[breed=Fido]                      % BAD (required key missing)

\end{document}

答案2

为了禁止某些键(或者更确切地说,只允许某些键),我会将所有键定义为/wickerson/dog和的子键/wickerson/human。然后,您还可以安装/wickerson/dog/.unknown在调用未知键时执行的键(尽管此解决方案不知道所讨论的键在另一个上下文中是否有效)。

以下示例会引发错误

! Package Wickerson Error: The key "car owned" is not known in the "dog" context..

\documentclass{article}
\usepackage{pgfkeys}

\makeatletter
\pgfkeys{/wickerson/.cd,
  dog/breed/.store in =     {\wickerson@breed},
  dog/name/.store in =      {\wickerson@name},
  dog/.unknown/.code=   {\PackageError{Wickerson}{The key "\pgfkeyscurrentkeyRAW" is not known in the "dog" context.}{}},
  human/name/.store in =      {\wickerson@name},
  human/car owned/.store in = {\wickerson@carowned},
  human/.unknown/.code= {\PackageError{Wickerson}{The key "\pgfkeyscurrentkeyRAW" is not known in the "human" context.}{}},
}

\newcommand*\dog[1][]{%
  \pgfkeys{/wickerson/dog/.cd, name=noName, breed=noBreed, #1}
  Dog is a {\wickerson@breed} and is called {\wickerson@name}.\par
}

\newcommand*\human[1][]{%
  \pgfkeys{/wickerson/human/.cd, name=noName, car owned=noCar, #1}
  Human is called {\wickerson@name} and owns a {\wickerson@carowned}.\par
}
\makeatother

\begin{document}

\dog[breed=Labrador, name=Fido]       % GOOD
\human[name=John, car owned=Porsche]  % GOOD
\dog[breed=Labrador, car owned=Rover] % BAD (irrelevant key given)
\dog[name=Fido]                       % BAD (required key missing)

\end{document}

相关内容