我有一个宏(比如\myMacro
),它接受三个参数(比如 a、b、c),我想编写另一个宏(比如\otherMacro
),给定三个参数列表(逗号分隔的列表,所有列表的长度相同,列表的长度为 2 或更大),\myMacro
依次映射到这些参数上。即
\otherMacro {a1, a2, a3}{b1, b2, b3}{c1, c2, c3}
给出表示
\myMacro{a1}{b1}{c1} \mapsto
(\myMacro{a2}{b2}{c2} , \myMacro{a3}{b3}{c3})
和
\otherMacro {a1, a2, a3, a4}{b1, b2, b3, b4}{c1, c2, c3, c4}
给出表示
\myMacro{a1}{b1}{c1} \mapsto
(\myMacro{a2}{b2}{c2} , \myMacro{a3}{b3}{c3}, \myMacro{a4}{b4}{c4})
我是 LaTeX 新手,如果已经有人问过类似的问题,我深感抱歉。我搜索了网站,发现了一些类似的问题,但我无法理解解决方案。
答案1
一个相当粗糙的版本:
\documentclass{article}
\makeatletter
\newcount\my@index
\newcommand\otherMacro[3]
{%
\my@index\z@
\@othermacro#1,\@nil#2,\@nil#3,\@nil
}
\def\@othermacro#1,#2\@nil#3,#4\@nil#5,#6\@nil
{%
\ifnum\my@index=\@ne\mapsto (\fi
\ifnum\my@index>\@ne,\fi
\myMacro{#1}{#3}{#5}%
\ifx\empty#2\empty
)%
\else
\advance\my@index\@ne
\@othermacro#2\@nil#4\@nil#6\@nil
\fi
}
\newcommand\myMacro[3]{\max(#1,#2,#3)}
\makeatother
\begin{document}
$\otherMacro {a1,a2,a3,a4}{b1,b2,b3,b4}{c1,c2,c3,c4}$
\end{document}
答案2
这适用于任意长度的列表(当然至少有两个元素):
\documentclass{article}
\usepackage{xparse}
\newcommand{\myMacro}[3]{[#1,#2,#3]} % define suitably
\ExplSyntaxOn
\NewDocumentCommand{\otherMacro}{mmm}{ \maps_splitargs:nnn {#1}{#2}{#3} }
\seq_new:N \l_maps_first_seq
\seq_new:N \l_maps_second_seq
\seq_new:N \l_maps_third_seq
\cs_new:Npn \maps_splitargs:nnn #1 #2 #3
{
\seq_set_split:Nnn \l_maps_first_seq {,} { #1 }
\seq_set_split:Nnn \l_maps_second_seq {,} { #2 }
\seq_set_split:Nnn \l_maps_third_seq {,} { #3 }
\prg_stepwise_inline:nnnn { 0 } { 1 } { \seq_length:N \l_maps_first_seq - 1 }
{
\tl_set:Nx \l_tmpa_tl
{
{ \seq_item:Nn \l_maps_first_seq { ##1 } }
{ \seq_item:Nn \l_maps_second_seq { ##1 } }
{ \seq_item:Nn \l_maps_third_seq { ##1 } }
}
\exp_after:wN \myMacro \l_tmpa_tl
\int_compare:nTF { ##1 = 0 }
{ \mapsto ( }
{ \int_compare:nTF { ##1 = \seq_length:N \l_maps_first_seq - 1 } { ) } { , } }
}
}
\ExplSyntaxOff
\begin{document}
$\otherMacro {a1,a2}{b1,b2}{c1,c2}$
$\otherMacro {a1,a2,a3}{b1,b2,b3}{c1,c2,c3}$
$\otherMacro {a1,a2,a3,a4}{b1,b2,b3,b4}{c1,c2,c3,c4}$
$\otherMacro {a1,a2,a3,a4,a5}{b1,b2,b3,b4,b5}{c1,c2,c3,c4,c5}$
\end{document}
重要变更
由于expl3
2012 年夏季所做的更改,上述代码应替换为以下内容:
\documentclass{article}
\usepackage{xparse}
\newcommand{\myMacro}[3]{[#1,#2,#3]} % define suitably
\ExplSyntaxOn
\NewDocumentCommand{\otherMacro}{mmm}{ \maps_splitargs:nnn {#1}{#2}{#3} }
\seq_new:N \l_maps_first_seq
\seq_new:N \l_maps_second_seq
\seq_new:N \l_maps_third_seq
\cs_new:Npn \maps_splitargs:nnn #1 #2 #3
{
\seq_set_split:Nnn \l_maps_first_seq {,} { #1 }
\seq_set_split:Nnn \l_maps_second_seq {,} { #2 }
\seq_set_split:Nnn \l_maps_third_seq {,} { #3 }
\int_step_inline:nnnn { 1 } { 1 } { \seq_count:N \l_maps_first_seq }
{
\tl_set:Nx \l_tmpa_tl
{
{ \seq_item:Nn \l_maps_first_seq { ##1 } }
{ \seq_item:Nn \l_maps_second_seq { ##1 } }
{ \seq_item:Nn \l_maps_third_seq { ##1 } }
}
\exp_after:wN \myMacro \l_tmpa_tl
\int_compare:nTF { ##1 = 1 }
{ \mapsto ( }
{ \int_compare:nTF { ##1 = \seq_count:N \l_maps_first_seq } { ) } { , } }
}
}
\ExplSyntaxOff
\begin{document}
$\otherMacro {a1,a2}{b1,b2}{c1,c2}$
$\otherMacro {a1,a2,a3}{b1,b2,b3}{c1,c2,c3}$
$\otherMacro {a1,a2,a3,a4}{b1,b2,b3,b4}{c1,c2,c3,c4}$
$\otherMacro {a1,a2,a3,a4,a5}{b1,b2,b3,b4,b5}{c1,c2,c3,c4,c5}$
\end{document}