¿Cómo puedo analizar una lista en un accesorio keyval?

¿Cómo puedo analizar una lista en un accesorio keyval?

Estoy intentando almacenar una lista separada por comas en una propiedad clave-valor para usarla más tarde, pero no logro que funcione correctamente.

Realmente no entiendo cómo analiza látex un parámetro keyval, pero supongo que está procesando el parámetro como texto sin formato.

Este es el código que tengo actualmente:

\documentclass{article}
\usepackage{expl3}
\usepackage{xparse}

\ExplSyntaxOn

\NewDocumentCommand { \getvmeta } { m } { \prop_item:cn { g_rvnlatex_doc_prop } { #1 } }
\NewDocumentCommand { \setvmeta } { m m } { \prop_gput:cnV { g_rvnlatex_doc_prop } { #1 } #2 }

\keys_define:nn { ravenhill/latex/meta } {
    author .clist_set:N = \l_rvnlatex_author_clist ,
}

\NewDocumentCommand { \setup } { m } { 
  \group_begin:
  \prop_new:c { g_rvnlatex_doc_prop }
  \keys_set:nn { ravenhill/latex/meta } { #1 }
  \setvmeta { author } { \l_rvnlatex_author_clist }
  \group_end:
}

\NewDocumentCommand { \authorblock } { } {
  \clist_new:N \l__authblock_authcopy_clist
  \clist_set:Nn \l__authblock_authcopy_clist { \getvmeta { author } }
  \clist_use:Nnnn \l__authblock_authcopy_clist { ~and~ } { ,~ } { ,~and~ }
}
\ExplSyntaxOff
  
\setup { 
    author = {John, Bob},
}

\begin{document}
  \authorblock
\end{document}

El resultado que obtuve es John,Boben lugar deJohn and Bob .

¿Se me escapa algo?

Respuesta1

Tu suposición es correcta. cuando usas

\clist_set:Nn \l__authblock_authcopy_clist { \getvmeta { author } }

el analizador de listas sólo ve \getvmeta { author }lo que, en lo que a él respecta, no es diferente agetvmeta { author } , ya que no tiene coma allí.

Para exponer la lista de comas que pasó a la authorclave, debe expandirla \getvmeta{author}a su contenido. Para hacer eso, use \clist_set:Nx( xsignifica expansión exhaustiva). Funcionará porque \prop_item:Nnfunciona por expansión, por lo que puede devolver el elemento en un contexto de expansión (también debe permitir \getvmetala expansión declarándolo con ).\NewExpandableDocumentCommand

Además, mueva las declaraciones de variables fuera de los comandos a nivel de usuario: nunca se sabe si alguien intentará usarlas, digamos, \setupdos veces, y si lo hace, su código generará un error al intentar declarar una variable que ya existe.

\documentclass{article}
\usepackage{expl3}
\usepackage{xparse}

\ExplSyntaxOn

\NewExpandableDocumentCommand { \getvmeta } { m }
  { \prop_item:Nn \g_rvnlatex_doc_prop {#1} }
\NewDocumentCommand { \setvmeta } { m m }
  { \prop_gput:NnV \g_rvnlatex_doc_prop {#1} #2 }

\keys_define:nn { ravenhill/latex/meta }
  { author .clist_set:N = \l_rvnlatex_author_clist }

\prop_new:N \g_rvnlatex_doc_prop
\clist_new:N \l__authblock_authcopy_clist

\NewDocumentCommand \setup { m }
  {
    \group_begin:
      \keys_set:nn { ravenhill/latex/meta } {#1}
      \setvmeta { author } { \l_rvnlatex_author_clist }
    \group_end:
  }

\NewDocumentCommand \authorblock { }
  {
    \clist_set:Nx \l__authblock_authcopy_clist { \getvmeta { author } }
    \clist_use:Nnnn \l__authblock_authcopy_clist { ~and~ } { ,~ } { ,~and~ }
  }
\ExplSyntaxOff

\setup{author = {John, Bob}}

\begin{document}
  \authorblock
\end{document}

información relacionada