Como posso analisar um clist em um suporte keyval?

Como posso analisar um clist em um suporte keyval?

Estou tentando armazenar uma lista separada por vírgula em uma propriedade de valor-chave para usá-la mais tarde, mas não consigo fazê-la funcionar corretamente.

Eu realmente não entendo como o latex analisa um parâmetro keyval, mas meu palpite é que ele está processando o parâmetro como texto simples.

Este é o código que tenho atualmente:

\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}

O resultado que obtive é John,Bobem vez de John and Bob.

Tem algo que estou perdendo?

Responder1

Seu palpite está correto. Quando você usa

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

o analisador clist vê apenas \getvmeta { author }which, no que lhe diz respeito, não é diferente de getvmeta { author }, já que não contém vírgula.

Para expor a lista de vírgulas que você passou para a authorchave, é necessário expandir \getvmeta{author}seu conteúdo. Para fazer isso, use \clist_set:Nx( xsignifica expansão exaustiva). Funcionará porque \prop_item:Nnfunciona por expansão para que possa retornar o item em um contexto de expansão (você também deve permitir \getvmetaa expansão declarando-o com ).\NewExpandableDocumentCommand

Além disso, mova as declarações de variáveis ​​para fora dos comandos de nível de usuário: você nunca sabe se alguém tentará usar, digamos, \setupduas vezes e, se o fizer, seu código apresentará um erro ao tentar declarar uma variável que já 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}

informação relacionada