Número ilimitado de argumentos – Boas práticas

Número ilimitado de argumentos – Boas práticas

Aqui está como faço para trabalhar com um número ilimitado de argumentos de uma macro. Existe uma maneira melhor de fazer isso?

\documentclass[12pt,a4paper]{article}

\usepackage{ifmtarg}
\usepackage{nicematrix}

\makeatletter
    \def\backify#1|#2\@nil{%
        \@ifmtarg{#2}{%
            #1%
        }{%
            #1 \\ \backify#2\@nil%
        }%
    }

    \newcommand\vcoord[1]{%
        \begin{pmatrix}
            \backify#1|\@nil %
        \end{pmatrix}%
    }
\makeatother

\begin{document}

$\vcoord{3 | -4 | 0}$

\end{document}

Responder1

Proponho uma maneira diferente de lidar com o que você parece estar fazendo.

\documentclass[12pt,a4paper]{article}

\usepackage{xparse}
\usepackage{amsmath}

\ExplSyntaxOn

% a general purpose macro for defining other macros
\NewDocumentCommand{\makemultiargument}{mmmmm}
 {
  \projetmbc_multiarg:nnnnn { #1 } { #2 } { #3 } { #4 } { #5 }
 }

% allocate a private variable
\seq_new:N \l__projetmbc_generic_seq

% the internal version of the general purpose macro
\cs_new_protected:Nn \projetmbc_multiarg:nnnnn
 {% #1 = separator
  % #2 = multiargument
  % #3 = code before
  % #4 = code between
  % #5 = code after

  % a group allows nesting
  \group_begin:
  % split the multiargument into parts
  \seq_set_split:Nnn \l__projetmbc_generic_seq { #1 } { #2 }
  % execute the <code before>
  #3
  % deliver the items, with the chosen material between them
  \seq_use:Nn \l__projetmbc_generic_seq { #4 }
  % execute the <code after>
  #5
  % end the group started at the beginning
  \group_end:
 }

\ExplSyntaxOff

% separator: |; before: \begin{pmatrix}; between: \\, after: \end{pmatrix}
\newcommand{\vcoord}[1]{%
  \makemultiargument{|}{#1}{\begin{pmatrix}}{\\}{\end{pmatrix}}%
 }

\begin{document}

$\vcoord{3 | \vcoord{-4 | -3 } | 0}$ 

\end{document}

insira a descrição da imagem aqui

É possível adicionar formatação a cada entrada, com um argumento opcional à direita (sem ele a macro é a mesma da versão anterior).

\documentclass[12pt,a4paper]{article}

\usepackage{xparse}
\usepackage{amsmath}

\ExplSyntaxOn

\NewDocumentCommand{\makemultiargument}{mmmmmo}
 {
  \projetmbc_multiarg:nnnnnn { #1 } { #2 } { #3 } { #4 } { #5 } { #6 }
 }

\seq_new:N \l__projetmbc_generic_seq

\cs_new_protected:Nn \projetmbc_multiarg:nnnnnn
 {% #1 = separator
  % #2 = multiargument
  % #3 = code before
  % #4 = code between
  % #5 = code after
  % #6 = ornament to items

  % allow nesting
  \group_begin:
  % split the multiargument
  \seq_set_split:Nnn \l__projetmbc_generic_seq { #1 } { #2 }
  \tl_if_novalue:nF { #6 }
   {
    \seq_set_eq:NN \l__projetmbc_temp_seq \l__projetmbc_generic_seq
    \seq_set_map:NNn \l__projetmbc_generic_seq \l__projetmbc_generic_seq { #6 }
   }
  #3
  \seq_use:Nn \l__projetmbc_generic_seq { #4 }
  #5
  \group_end:
 }

\ExplSyntaxOff

\NewDocumentCommand{\vcoord}{m}
 {
  \makemultiargument{|}{#1}{\begin{pmatrix}}{\\}{\end{pmatrix}}
 }

\NewDocumentCommand{\pboxed}{m}{\boxed{#1}}

\begin{document}

$\vcoord{3 | \vcoord{-4 | -3 } | 0}$

$\makemultiargument{|}{-4 | -3  | 0}{\begin{pmatrix}}{\\}{\end{pmatrix}}[\pboxed{#1}]$

\end{document}

Cuidado, pois as macros no argumento final devem ser totalmente expansíveis ou protegidas (é por isso que defini \pboxed; o padrão \boxednão falharia, mas apenas por acaso).

insira a descrição da imagem aqui

Responder2

Usando expl3(que é carregado por xparse) você pode usar o tipo de sequência integrado. O seguinte define o \vcoorduso apenas de funções integradas. O resultado não é expansível. Ele também adiciona duas macros, \readsequenceque configuram uma variável de sequência (não expansível) e \usesequenceque se expande para a sequência com cada elemento da sequência separado por seu argumento (expansível). Você pode olharinterface3para a documentação das funções disponíveis em expl3.

\documentclass[]{article}

\usepackage{amsmath}
\usepackage{xparse}
\ExplSyntaxOn
\seq_new:N \l__projetmbc_seq
\NewDocumentCommand \readsequence { +m +m }
  {
    \seq_set_split:Nnn \l__projetmbc_seq { #1 } { #2 }
  }
\NewExpandableDocumentCommand \usesequence { +m }
  {
    \seq_use:Nnnn \l__projetmbc_seq { #1 } { #1 } { #1 }
  }
\NewDocumentCommand \vcoord { m }
  {
    \group_begin:
    \seq_set_split:Nnn \l__projetmbc_seq { | } { #1 }
    \begin { pmatrix }
      \seq_use:Nnnn \l__projetmbc_seq { \\ } { \\ } { \\ }
    \end { pmatrix }
    \group_end:
  }
\ExplSyntaxOff

\begin{document}
\readsequence{|}{a|b|c|d|e}
\[
  \begin{pmatrix}
    \usesequence{\\}
  \end{pmatrix}
\]

\[
  \vcoord{3|-4|0}
\]
\end{document}

Responder3

Não tenho certeza sobre as melhores práticas, mas você pode simplificar um pouco a definição:

\documentclass[12pt,a4paper]{article}

\usepackage{amsmath}


\long\def\backify#1|{#1\backify\\}
\def\endbackify#1#2{}

    \newcommand\vcoord[1]{%
        \begin{pmatrix}
            \backify#1|\endbackify|%
        \end{pmatrix}%
    }


\begin{document}

$\vcoord{3 | -4 | 0}$

\end{document}

informação relacionada