为什么使用 etoolbox 和 kvoptions 时会错误地处理逗号分隔列表?

为什么使用 etoolbox 和 kvoptions 时会错误地处理逗号分隔列表?

我试图从一些包选项传递的列表中挑选出一些东西kvoptions,但docsvlist似乎没有识别出逗号。

我怀疑这可能与 Knuth 的“嘴和胃”范式有关,但我的技术水平不够,无法理解其中的原因,也不知道该如何正确地做到这一点。有人能解释一下发生了什么吗?

这是我的 MWE:

测试x.sty:

\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{testx}
\RequirePackage{kvoptions}
\RequirePackage{etoolbox}
\SetupKeyvalOptions{family=test,prefix=test@}
\DeclareStringOption{refnames}
\ProcessKeyvalOptions*
\newcommand{\vtag}{(None)}
\csdef{xferret}{}      % This is what I want to extract
\newcommand{\testtag}[1]{%
    \PackageWarning{testx}{Processing #1}
    \def\do##1{%
        \ifcsdef{x##1}{%
            \renewcommand{\vtag}{##1}%
            \listbreak
        }{%
            \PackageWarning{testx}{##1 not selected}
        }
    }%
    \docsvlist{#1}%
}%
\testtag{\test@refnames}

测试.tex:

\documentclass[10pt,a4paper]{article}
\usepackage[refnames={rat, ferret, 1.0, mole}]{testx}
\begin{document}
\vtag
\testtag{rat, ferret, 1.0, mole}
\vtag
\end{document}

第一个\vtag(包中的集合)产生“(无)”

第二个\vtag产生“雪貂”

在日志中,我们有以下内容:

(摘自包装):

Package testx Warning: Processing rat, ferret, 1.0, mole on input line 22.
Package testx Warning: rat, ferret, 1.0, mole not selected on input line 22.

(来自文档主体中的调用)

Package testx Warning: Processing rat, ferret, 1.0, mole on input line 5.
Package testx Warning: rat not selected on input line 5.

答案1

这是一个经典的扩展​​问题。发生的事情是

\testtag{\test@refnames}

完全按照写入的方式传递\test@refnames。在写入日志时,TeX 会完全展开它,因此您会看到预期的结果。但是

\docsvlist{#1}%

视为\test@refnames#1没有逗号。因此您需要\test@refnames正确扩展。根据其他用途,要么

\expandafter\testtag\expandafter{\test@refnames}

在使用点或

\expandafter\docsvlist\expandafter{#1}%

在内部宏中(但不能同时使用!)。无论哪种情况,TeX 都会按照 将其\expandafter转换\test@refnames为其内容扩展处理宏。

相关内容