参数数量不受限制 - 良好做法

参数数量不受限制 - 良好做法

以下是我处理宏的无限数量参数的方法。有没有更好的方法?

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

答案1

我建议用不同的方法来应对你正在做的事情。

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

enter image description here

可以为每个条目添加格式,并带有尾随可选参数(如果没有它,宏与以前的版本相同)。

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

请注意,尾随参数中的宏必须是完全可扩展的或受保护的(这就是我定义的原因\pboxed;标准\boxed不会失败,但只是偶然)。

enter image description here

答案2

使用expl3(由 加载xparse)您可以使用内置序列类型。以下\vcoord仅使用内置函数定义您的序列类型。结果不可扩展。它还添加了两个宏,\readsequence一个设置序列变量(不可扩展),\usesequence另一个扩展为序列,每个序列元素由其参数分隔(可扩展)。您可以查看interface3用于 中可用功能的文档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}

答案3

不确定最佳实践,但你可以稍微简化定义:

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

相关内容