如何在缺少可选 keyval 参数时执行 if-else 逻辑

如何在缺少可选 keyval 参数时执行 if-else 逻辑

我正在尝试使用 xparse 库和 xkeyval 为可选键值对制作一个宏。下面是我正在尝试做的一个简单示例

系统管理员

\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{cmd}

\RequirePackage{xparse}
\RequirePackage{xkeyval}

\define@key{keyvalTest}{width}{\def\kt@width{#1}}
\define@key{keyvalTest}{caption}{\def\kt@caption{#1}}

\NewDocumentCommand{\keyvalTest}{ o m }{
  \begingroup
    % Set the default values, and override any extra if any optional arguments are present, else just set the default values
    \IfValueTF{#1}
      {\setkeys{keyvalTest}{width={50mm}, caption=\NoValue, #1}}
      {\setkeys{keyvalTest}{width={50mm}, caption=\NoValue}}
      
    \noindent
    Path: #2 \\
    Width: \kt@width \\
    % Should print the caption if specified as an optional arg, else print "No Caption"
    \IfValueTF{\kt@caption}
      {Caption: \kt@caption}
      {No Caption}
  \endgroup
}

主文本

\documentclass{article}

\usepackage{cmd}

\begin{document}
  \keyvalTest{diagrams/pathToDiagram.pdf} \\
  
  \keyvalTest[caption={hello}, width=3cm]{diagrams/pathToDiagram.pdf}
\end{document}

这个例子给了我这样的:

并出现错误,指出\NoValue{}未定义。我只看到它在几个地方使用(例如这里),但我从未见过它在实际代码中使用。我猜它可能已被弃用,或者仅对 expl3 有效?

我经历过xparse 的文档找不到任何可以充当 NoValue 的宏。我也尝试过阅读它的源代码,但如果可能的话,我想避免使用 expl3。

我想知道我应该从哪里开始。我应该使用空白,并使用某种isblankisempty函数,还是有更好的方法来解决这个问题?我认为在缺少命名可选参数时执行 if else 逻辑会很常见,但我似乎在任何地方都找不到任何示例。

答案1

\IfValueTF正在检查您是否具有特殊字符序列,-NoValue-并在参数中设置了不太可能的类别代码。更好的方法是简单地检查是否\kt@caption已设置。您可以使用内部 LaTeX 命令\@ifundefined来管理此问题,方法是将您的定义重写为\keyvalTest

\NewDocumentCommand{\keyvalTest}{o m}{
  \IfValueTF{#1}
  {\setkeys{keyvaltest}{width=50mm,#1}}
  {\setkeys{keyvaltest}{width=50mm}}

  \noindent
    Path: #2 \\
    Width: \kt@width \\
    % Should print the caption if specified as an optional arg, else print "No Caption"
    \@ifundefined{kt@caption}
      {No Caption}
      {Caption: \kt@caption}
}

或者,您可以使用 e-TeX 命令\ifdefined,该命令使用 TeX 的低级 if 机制,并避免 2018 年之前的 LaTeX 出现问题。将\@ifundefined序列替换为:

\ifdefined\kt@caption
    Caption: \kt@caption
\else
    No Caption
\fi

答案2

我不会xkeyval与混合使用expl3,它具有自己的键值接口,并且在许多方面优于xkeyval

文件cmd.sty

\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{cmd}

%\RequirePackage{xparse} % not needed for LaTeX 2020-10-01 or later

\ExplSyntaxOn

\keys_define:nn { hsevenxfour/cmd }
 {
  width .dim_set:N = \l__hsevenxfour_cmd_width_dim,
  width .initial:n = 50mm,
  caption .tl_set:N = \l__hsevenxfour_cmd_caption_tl,
 }

\NewDocumentCommand{\keyvalTest}{ O{} m }
 {
  \group_begin:
  \keys_set:nn { hsevenxfour/cmd } { #1 }
  \noindent
  Path:~#2 \\
  Width:~\dim_eval:n { \l__hsevenxfour_cmd_width_dim } \\
  % Should print the caption if specified as an optional arg, else print "No Caption"
  \tl_if_empty:NTF \l__hsevenxfour_cmd_caption_tl
   {
    No~caption
   }
   {
    Caption:~\tl_use:N \l__hsevenxfour_cmd_caption_tl
   }
  \group_end:
}

\ExplSyntaxOff

文件test.tex

\documentclass{article}

\usepackage{cmd}

\begin{document}

\noindent
\keyvalTest{diagrams/pathToDiagram.pdf}

\noindent
\keyvalTest[caption={hello}, width=3cm]{diagrams/pathToDiagram.pdf}

\end{document}

输出

在此处输入图片描述

相关内容