在数学模式下,编写逗号分隔值序列的最佳方法是什么?目前,我正在使用
$ s_1 $, $s_2$, $s_3$, $s_4$, $\dots $
但这确实很繁琐。有没有更优雅的方法?
答案1
如上所述,由于字体的原因,最好不要在数学模式下完全设置文本列表。这里有一个快速宏可以帮您完成此操作,使用文本模式逗号。
已添加可选参数,以确定列表如何结束。默认以 结束列表, \ldots
。如果提供了可选参数,则列表是有限的:
如果可选参数为空,则不会向底层列表添加任何内容,但是
如果可选参数是其他内容,则列表将通过
\ldots
out 扩展到可选参数中指定的索引。
这是 MWE。
\documentclass{article}
\usepackage{listofitems}
\newcommand\textlist[3][\cr]{%
\readlist\indices{#3}%
\foreachitem\x\in\indices{%
\ifnum\xcnt=1\else, \fi$#2_{\x}$%
}%
\ifx\cr#1\relax, \ldots\else%
\if\relax#1\relax\else, \ldots, $#2_{#1}$\fi%
\fi%
}
\begin{document}
Infinite list: \textlist{s}{1,2,3,4}.
Finite list: \textlist[]{\alpha}{2,4,6}.
Extended finite list: \textlist[13]{a}{1,2,3}.
Ending on a separate index: \textlist[j]{a}{1,2,3}.
\end{document}
根据 OP 的要求,这里是替代版本,其中没有可选参数表示有限列表(无\ldots
),而空白可选参数表示无限列表。扩展的有限列表在语法上保持不变:
\documentclass{article}
\usepackage{listofitems}
\newcommand\textlist[3][\cr]{%
\readlist\indices{#3}%
\foreachitem\x\in\indices{%
\ifnum\xcnt=1\else, \fi$#2_{\x}$%
}%
\ifx\cr#1\relax\else%
\if\relax#1\relax, \ldots\else, \ldots, $#2_{#1}$\fi%
\fi%
}
\begin{document}
Infinite list: \textlist[]{s}{1,2,3,4}.
Finite list: \textlist{\alpha}{2,4,6}.
Extended finite list: \textlist[13]{a}{1,2,3}.
Ending on a separate index: \textlist[j]{a}{1,2,3}.
\end{document}
答案2
这是一个灵活的语法。如果我们调用,则会添加尾随的点\makelist*
。
最后\parbox
显示了可能的换行符。最好使用\dotsc
(带逗号的点)代替\dots
或\ldots
,以保持“输入独立性”。
\documentclass{article}
\usepackage{amsmath}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\makelist}{sm}
{
\paul_makelist:n { #2 }
\IfBooleanT{ #1 } { ,\nobreakspace$\dotsc$ }
}
\seq_new:N \l__paul_list_input_seq
\seq_new:N \l__paul_list_output_seq
\cs_new_protected:Nn \paul_makelist:n
{
% split the list at commas
\seq_set_from_clist:Nn \l__paul_list_input_seq { #1 }
% substitute each item with \__paul_list_addmath:n { <item> }
\seq_set_map:NNn
\l__paul_list_output_seq
\l__paul_list_input_seq
{ \__paul_list_addmath:n { \exp_not:n { ##1 } } }
% output the list with the stated separators
\seq_use:Nnnn \l__paul_list_output_seq
{ ,\nobreakspace } % between two
{ ,~ } % between more than two
{ ,\nobreakspace } % between last two
}
\cs_new_protected:Nn \__paul_list_addmath:n
{
% if the item is \dotsc, we want to have a non breaking space before it
\str_if_eq:nnT { #1 } { \dotsc } { \unskip\nobreakspace }
$#1$
}
\ExplSyntaxOff
\begin{document}
A finite sequence \makelist{s_1,s_2,s_3}
Another finite sequence \makelist{s_1,s_2,\dots,s_n}
An infinite sequence \makelist*{s_1,s_2,s_3,s_4}
Another infinite sequence \makelist*{s_1,s_2,\dots,s_n}
\parbox[t]{0pt}{
\makelist{s_1,s_2,s_3}
\makelist{s_1,s_2,\dots,s_n}
\makelist*{s_1,s_2,s_3,s_4}
\makelist*{s_1,s_2,\dots,s_n}
}
\end{document}