keyval_parse 入门

keyval_parse 入门

这个例子永远编译不完。我一定是用错了keyval_parse

\documentclass{report}
\usepackage{xparse}

% Relevant doc:
% http://www.texdoc.net/texmf-dist/doc/latex/l3kernel/interface3.pdf#part.21

\ExplSyntaxOn

\NewDocumentCommand{\mykeyvalparser}
{
  m % key
  m % val
}
{
  \tl_case:NnTF #1
  {
    foo{Hello, #2!}
    bar{Bye, #2!}
  }{}{No matching key}

}

\NewDocumentCommand{\mykeyparser}
{
  m % key
}
{
  \tl_case:NnTF #1
  {
    qux{QUX}
  }{}{No matching key}

}


\begin{document}

\keyval_parse:NNn
\mykeyparser
\mykeyvalparser
{
  foo=World,
  bar=Universe,
  qux
}%WANTED: Hello, World! Bye, Universe! QUX

\ExplSyntaxOff

\end{document}

编译日志:

Running `LaTeX' on `parser-1' with ``pdflatex  -file-line-error   -interaction=nonstopmode parser-1.tex''
This is pdfTeX, Version 3.14159265-2.6-1.40.20 (TeX Live 2019) (preloaded format=pdflatex)
 restricted \write18 enabled.
entering extended mode
(./parser-1.tex
LaTeX2e <2019-10-01>
(/usr/local/texlive/2019/texmf-dist/tex/latex/base/report.cls
Document Class: report 2019/08/27 v1.4j Standard LaTeX document class
(/usr/local/texlive/2019/texmf-dist/tex/latex/base/size10.clo))
(/usr/local/texlive/2019/texmf-dist/tex/latex/l3packages/xparse/xparse.sty
(/usr/local/texlive/2019/texmf-dist/tex/latex/l3kernel/expl3.sty
(/usr/local/texlive/2019/texmf-dist/tex/latex/l3kernel/expl3-code.tex
(/usr/local/texlive/2019/texmf-dist/tex/latex/l3kernel/l3deprecation.def))
(/usr/local/texlive/2019/texmf-dist/tex/latex/l3backend/l3backend-pdfmode.def))) (./parser-1.aux)
./parser-1.tex:45: Missing number, treated as zero.
<to be read again> 
                   o
l.45 }
      %WANTED: Hello, World! Bye, Universe! QUX

更新:

来自所引用的文档:

\keyval_parse:NNn〈function1〉 〈function2〉{〈key–value list〉}

因此

\keyval_parse:NNn \function:n \function:nn{ key1 = value1 , key2 = value2, key3 = , key4 }

被转换成输入流

\function:nn { key1 } { value1 }
\function:nn { key2 } { value2 }\function:nn { key3 } { }\function:n  { key4 }

答案1

正如@UlrikeFischer 在评论中指出的那样,您对 的使用\tl_case:NnTF是错误的。相反,您应该\str_case:nnTF在这里使用 。此外,您不应该将\NewDocumentCommand用作代码级函数,该函数将与 一起使用\keyval_parse:NNn,因此我将它们切换到不存在的模块的代码级my(您可能应该更改该名称)。哦,您还必须在~中明确添加空格\ExplSyntaxOn,因为其他空格将被忽略(并且~不是通常的不可破坏空格,而只是这里的普通空格)。

\documentclass{report}
\usepackage{xparse}

\ExplSyntaxOn
\cs_new:Npn \my_keyval_parser:nn #1 #2
  {
    \str_case:nnTF { #1 }
      {
        { foo } {Hello, ~ #2!}
        { bar } {Bye, ~ #2!}
      }
      {}
      { No ~ matching ~ key}
  }

\cs_new:Npn \my_key_parser:n #1
  {
    \str_case:nnTF { #1 }
      {
        { qux } {QUX}
      }
      {}
      { No ~ matching ~ key}
  }


\begin{document}

\keyval_parse:NNn
\my_key_parser:n
\my_keyval_parser:nn
{
  foo=World,
  bar=Universe,
  qux
}%WANTED: Hello, World! Bye, Universe! QUX

\ExplSyntaxOff

\end{document}

顺便说一句,正确的语法是\tl_case:NnTF将标记列表变量与标记列表变量(-type 参数)进行比较N,并且在您的情况下看起来像下面这样(在那里您还会看到为什么要使用\str_case:nn):

\tl_new:N \l_my_tmpa_tl
\tl_const:Nn \c__my_foo_tl { foo }
\tl_const:Nn \c__my_bar_tl { bar }
\tl_const:Nn \c__my_qux_tl { qux }
\cs_new_protected:Npn \my_keyval_parser:nn #1 #2
  {
    \tl_set:Nn \l_my_tmpa_tl { #1 }
    \tl_case:NnTF \l_my_tmpa_tl
      {
        \c__my_foo_tl {Hello, ~ #2!}
        \c__my_bar_tl {Bye, ~ #2!}
      }
      {}
      { No ~ matching ~ key}
  }
\cs_new_protected:Npn \my_key_parser:n #1
  {
    \tl_set:Nn \l_my_tmpa_tl { #1 }
    \tl_case:NnTF \l_my_tmpa_tl
      {
        \c__my_qux_tl {QUX}
      }
      {}
      { No ~ matching ~ key}
  }

相关内容