configurar pdfauthor usando una compleja macro de procesamiento de listas

configurar pdfauthor usando una compleja macro de procesamiento de listas

He creado una macro \joinlistque agrega comas u otros delimitadores entre los elementos de una etoolboxlista interna. Tiene un manejo especial para listas de sólo dos elementos ("a y b"). También sabe cómo poner un delimitador diferente entre los dos últimos elementos de listas más largas ("a, byc"). Aquí está la definición, creada por mí:

% typical use: \joinlist{\listmacro}{, }{, and }{ and }

\RequirePackage{etoolbox}

\newcommand{\@join@ignore}[1]{} % used to ignore current list element when counting
\newcount\@join@listlength % used to count length of list
\newcount\@join@currentnum % used to track current list element number

\newcommand{\joinlist}[4]{%
  %
  % count list elements
  \@join@listlength 0 %
  \forlistloop{\advance\@join@listlength 1\relax\@join@ignore}{#1}%
  %
  % now join list elements, tracking current element number
  \@join@currentnum 0 %
  \forlistloop{%
    \advance\@join@currentnum 1 %
    \ifnumequal{\the\@join@currentnum}{1}%
    {}% first
    {% not first
      \ifnumequal{\the\@join@currentnum}{\the\@join@listlength}%
      {% last
        \ifnumequal{\the\@join@listlength}{2}%
        {#4}% last of exactly two
        {#3}% last of more than two
      }%
      {#2}% neither first nor last
    }%
  }%
  {#1}}

Guarde lo anterior como join-list.styy luego considere el siguiente pequeño ejemplo que muestra un problema:

\documentclass{article}

\usepackage{hyperref}
\usepackage{join-list}

\begin{document}

    \newcommand{\people}[0]{}
    \listadd{\people}{a}
    \joinlist{\people}{, }{, and }{ and }  % a

    \listadd{\people}{b}
    \joinlist{\people}{, }{, and }{ and }  % a and b

    \listadd{\people}{c}
    \joinlist{\people}{, }{, and }{ and }  % a, b, and c

    \hypersetup{pdfauthor=\joinlist{\people}{, }{, and }{ and }}

\end{document}

\joinlistfunciona bien para crear contenido del cuerpo del documento. Vemos "a", luego "a y b", luego "a, b y c" como se esperaba.

Desafortunadamente, usar esto \hypersetup{pdfauthor=...}no funciona como se esperaba. En su lugar, establece los metadatos del autor del PDF del documento en "0 1110 1, a1, b1 y c". Es evidente que algo salió muy mal al ampliar/evaluar la \joinlistmacro en este contexto.

¿Qué estoy haciendo mal aquí? ¿Cómo puedo arreglar esto? ¿Existen otras formas de \joinlistmejorar mi macro? ¿Existe ya una macro similar en algún paquete ampliamente disponible? (Busqué pero no encontré ninguno).

Respuesta1

El problema es que \joinlistno es "ampliable": debe realizar asignaciones que \advance\@join@currentnum 1no se pueden realizar en el valor de pdfauthor=.

Con expl3(la capa de programación ya no tan experimental para LaTeX3), hay lo que necesitas.

\documentclass{article}

\usepackage{hyperref}

\RequirePackage{xparse}
\ExplSyntaxOn
\DeclareExpandableDocumentCommand{\joinlist}{ m m m m }
 {
  \seq_use:cnnn { g_liblit_list_#1_seq } { #2 } { #3 } { #4 }
 }
\cs_generate_variant:Nn \seq_use:Nnnn { c }
\NewDocumentCommand{\newlist}{ m }
 {
  \seq_new:c { g_liblit_list_#1_seq }
 }
\NewDocumentCommand{\listadd}{ m m }
 {
  \seq_gput_right:cn { g_liblit_list_#1_seq } { #2 }
 }
\ExplSyntaxOff

\begin{document}

\newlist{people}
\listadd{people}{a}
\joinlist{people}{ and }{, }{, and } % a

\listadd{people}{b}
\joinlist{people}{ and }{, }{, and }  % a and b

\listadd{people}{c}
\joinlist{people}{ and }{, }{, and }  % a, b, and c

\hypersetup{pdfauthor=\joinlist{people}{ and }{, }{, and }}

\end{document}

Hay algunos cambios con respecto a su configuración. Las listas tienen un nombre, en lugar de ser llamadas por una macro; Se puede crear uno nuevo mediante \newlist. Además, el orden de los argumentos \joinlistes diferente:

  1. el nombre de la lista;
  2. qué debe ir entre los elementos en caso de dos elementos;
  3. qué debe ir entre los elementos cuando hay más de dos (excepto los dos últimos);
  4. ¿Qué debería pasar entre losúltimodos elementos cuando son más de dos.

En caso de que la lista esté vacía no se producirá nada; con un solo elemento, ese será producido.

Esta versión de \joinlistes ampliable y no hay problema en darle como valor pdfauthor=.

Puede utilizar el código del preámbulo como reemplazo directo del suyo en el .styarchivo.

ingrese la descripción de la imagen aquí

información relacionada