
マクロの無制限の数の引数を扱う方法は次のとおりです。もっと良い方法はありますか?
\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
各シーケンス要素を引数で区切ったシーケンスに展開するマクロ(展開可能)の2つを追加します。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}