
Вот как я работаю с неограниченным количеством аргументов макроса. Есть ли лучший способ сделать это?
\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}
К каждой записи можно добавить форматирование с завершающим необязательным аргументом (без него макрос будет таким же, как и в предыдущей версии).
\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
не будет нарушен, но это произойдет случайно).
решение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}