0

The code below outputs:

ERROR: Package Foo Error: Unknown key, \l_keys_key_tl

Why does \l_keys_key_tl expand at Hook 1, not Hook 2?

\documentclass{report}
\usepackage{xparse}

\ExplSyntaxOn

  \msg_new:nnn
  {Foo}
  {generic}
  {#1}

  \keys_define:nn { \__erw_foo_options }
  {
    key .value_required:n = true,

    unknown .code:n =
    {
      { Unknown~key,~\l_keys_key_tl}  % Hook 1

      \msg_error:nnn
      { Foo }
      { generic }
      { Unknown~key,~\l_keys_key_tl} % Hook 2
    }
  }

  \NewDocumentCommand{\FooOptions}
  {m}
  {
   \keys_set:nn { \__erw_foo_options } {#1}
  }

 \NewDocumentCommand{\FooTest}
 {}
 {

   \FooOptions{bar}

 }


  \ExplSyntaxOff

  \begin{document}

\FooTest

  \end{document}
1
  • 1
    IIRC, the error message for unknown keys comes for free with l3keys. There should be no need to explicitly handle this situation.
    – frougon
    Commented Mar 5, 2020 at 19:57

1 Answer 1

2

The expansion behaviour of \msg_error:nnn, etc., is tightly defined: they pass the third (fourth, etc.) arguments unchanged. As such, you want to expand the variable using \msg_error:nnx. In contrast, just 'dumping the text' will convert the tl to its expansion at point-of-typesetting: this is the documented behaviour of token lists.

5
  • 1
    Also, \keys_define:nn { \__erw_foo_options } uses \__erw_foo_options literally as the family for keys: you almost certainly mean something like \keys_define:nn { erw } ....
    – Joseph Wright
    Commented Mar 5, 2020 at 17:56
  • Thanks for the explanation! Is the non-expanding behavior of \msg_new:nnn something that has changed in the last 3 years or so? Because I have code where I used \exp_not:n in the third argument of \msg_new:nnn, as if it were handled by \message... but this would appear to be unnecessary. Remark: \l_keys_key_tl appears to work, but my interface3.pdf doesn't document it (it documents \l_keys_key_str, which also works).
    – frougon
    Commented Mar 5, 2020 at 18:07
  • @JosephWright I guess you meant \keys_define:nn { __erw_foo_options } (a name, not a token)?
    – Erwann
    Commented Mar 5, 2020 at 18:13
  • @JosephWright Ah, I see in the .dtx: “\begin{variable}{\l_keys_key_str, \l_keys_key_tl} The |tl| version is deprecated but has to be handled manually.”. @Erwann I'm not Joseph, but I'd say “no”. The first argument of \keys_define:nn is usually the package name (and erw is three tokens).
    – frougon
    Commented Mar 5, 2020 at 18:15
  • @frougon. OK, I get it.
    – Erwann
    Commented Mar 5, 2020 at 18:20

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .