Tokenizar y aplicar comando

Tokenizar y aplicar comando

Tengo una cadena separada por comas. Sobre eso quiero obtener cada elemento y aplicar un comando. Tengo lo siguiente, que funciona.

\documentclass[12pt]{article}

\usepackage[trim]{tokenizer}

\newcommand{\cadd}[1]{
        \def\Source{#1}
    \whiledo{\not\equal{\Source}{}}
    {
        \GetTokens{TokenOne}{TokenTwo}{\Source}
        \textbf{\TokenOne}
        \let\Source\TokenTwo
    }
}

\begin{document}

\cadd{a,b,c}

\end{document}

Pero me gustaría tener lo siguiente

\documentclass[12pt]{article}

\usepackage[trim]{tokenizer}

\newcommand{\cadd}[1]{
    \whiledo{\not\equal{#1}{}}
    {
        \GetTokens{TokenOne}{TokenTwo}{#1}
        \textbf{\TokenOne}
        \let\#1\TokenTwo
    }
}

\begin{document}

\cadd{a,b,c}

\end{document}

Pero \let\#1\TokenTwoestá dando un error. ¿Cómo puedo utilizar #1con\let

Respuesta1

#1se reemplaza en la primera llamada de la macro. si macro\cadd

\newcommand{\cadd}[1]{
    \whiledo{\not\equal{#1}{}}
    {
        \GetTokens{TokenOne}{TokenTwo}{#1}
        \textbf{\TokenOne}
        \let\#1\TokenTwo
    }
}

se llama como \cadd{a,b,c}, entonces se convierte en:

<space>
\whiledo{\not\equal{a,b,c}{}}<space>
{<space>
  \GetTokens{TokenOne}{TokenTwo}{a,b,c}<space>
  \textbf{\TokenOne}<space>
  \let\#1\TokenTwo
}<space>
  • La línea \let\#1\TokenTwoconsta de la \letasignación \let\#=1y \TokenTwo. #1solo se reemplaza en la expansión macro con el primer argumento.
  • Hay muchas fichas de espacio (causadas por el final de la línea):

    • El primero se ignora en modo vertical, porque el párrafo aún no ha comenzado.
    • El segundo se ignora si \whiledolee el cuerpo del bucle como un argumento no delimitado.
    • El tercero y el cuarto estarán presentes en la salida.
    • El último se elimina por ser el final del párrafo.

    Los tokens de espacio al final de la línea se pueden evitar utilizando el carácter de comentario, como se ve en el siguiente ejemplo.

Hay muchos analizadores para listas separadas por comas. Uno de ellos se proporciona por paquete kvsetkeys:

\documentclass[12pt]{article}

\usepackage{kvsetkeys}

\makeatletter
\newcommand{\cadd}[1]{%
  \comma@parse{#1}{\caddentry}%
}
\newcommand*{\caddentry}[1]{%
  \textbf{[#1]}%
}
\makeatother

\begin{document}

\cadd{a,b,c}

\cadd{ a , b , c }

\cadd{abc, def, ghi}

\cadd{{ with spaces }, {a b c}}

\end{document}

Resultado

Respuesta2

Heiko ha cubierto muy bien los detalles aquí. Para completar, una solución que utiliza la función de mapeo de lista de comas de LaTeX3\clist_map_inline:nn

\documentclass{article}
\usepackage{expl3,xparse}
\ExplSyntaxOn
\NewDocumentCommand { \cadd } { m }
  { \clist_map_inline:nn {#1} { [ \textbf {##1} ] } }
\ExplSyntaxOff
\begin{document}
\cadd{a,b,c}

\cadd{ a , b , c }

\cadd{abc, def, ghi}

\cadd{{ with spaces }, {a b c}}

\end{document}

La idea subyacente es muy similar a la respuesta de Heiko: en lugar de tener que hacer el mapeo a mano, use un comando prediseñado que se ocupe de encontrar el final de la lista.

información relacionada