我有一个带有 6 个标签的数学符号,但显示这种符号有多种惯例。一种方法是,[F^{abc}_d]_{ef}
但其他人使用,例如[F^{abc}_d]^{e}_{f}
或其他形式。由于我正开始写论文,所以我宁愿不做绝对的选择,并决定定义一个带有 6 个标签的命令作为输入,例如
\newcommand{\F}[6]{[F^{{#1} {#2} {#3}}_{#4}]^{#5}_{#6}}
但之后我必须输入,\F{a}{b}{c}{d}{e}{f}
这有点麻烦。有没有什么方法可以让我使用逗号分隔列表(例如\F{a,b,c,d,e,f}
)来调用新命令,而不是使用标准方法?
答案1
该listofitems
包可以使用逗号(默认)或其他指定标记来解析列表。
请注意,您的列表至少需要 5 个逗号,否则调用时会出现错误\Fvar[6]
。
\documentclass{article}
\usepackage{listofitems}
\newcommand{\F}[1]{%
\readlist*\Fvar{#1}%
[F^{{\Fvar[1]} {\Fvar[2]} {\Fvar[3]}}_{\Fvar[4]}]^{\Fvar[5]}_{\Fvar[6]}}
\begin{document}
\begin{equation}
\F{a,b,c,d,e,f}
\end{equation}
\end{document}
答案2
你可以试试
\documentclass{article}
\begin{document}
\def\F(#1,#2,#3,#4,#5,#6){[F^{{#1}{#2}{#3}}_{#4}]^{#5}_{#6}}
$\F(a,b,c,d,e,f)$
\end{document}
答案3
您可以使用 expl3\clist_map_function:nN
或类似物将逗号分隔列表的所有项目映射到一个函数,该函数将其参数附加到嵌套在括号中的标记列表中。
然后,您可以使用\tl_count:V
它来计算括号嵌套的参数。如果有六个,则继续在标记列表前面添加对底层宏的调用,以处理六个参数。如果没有六个,则引发错误。
一个问题是,它会\clist_map_function:nN
默默地跳过/丢弃空白的逗号列表项。可以通过正则表达式替换逗号列表中逗号之间出现的任意数量的水平空格(但嵌套在括号中)来防止这种情况。为了禁止逗号列表中的尾随逗号,可以对最后一个逗号和逗号列表末尾之间出现的任意数量的水平空格执行相同的操作。
\ExplSyntaxOn
\cs_new:Nn \__MyStuff_Replaceblankitems: {
\exp_args:NnV \regex_match:nnTF {\,([\s])*\,} \l_tmpb_tl
{ \regex_replace_all:nnN {\,([\s])*\,} {\,\{\1\}\,} \l_tmpb_tl \__MyStuff_Replaceblankitems: }
{ \regex_replace_all:nnN {\,([\s])*\z} {\,\{\1\}} \l_tmpb_tl }
}
\cs_new_protected:Npn \F #1 {
\tl_set:Nn \l_tmpb_tl {#1}
% nest blank items of the comma-list between braces so that \clist_map_function:nN will not discard them.
\__MyStuff_Replaceblankitems:
%\tl_show:N \l_tmpb_tl
\tl_clear:N \l_tmpa_tl
\exp_args:NV \clist_map_function:nN \l_tmpb_tl {\__MyStuff_PutRightTo_l_tempa_tl:n }
\int_compare:nNnTF {\tl_count:V {\l_tmpa_tl}} = {6}
{\tl_put_left:Nn \l_tmpa_tl {\__MyStuff_F:nnnnnn} \tl_use:N \l_tmpa_tl }
{\msg_error:nnn { MyStuff } { not-six-items } { \F }}
\tl_clear:N \l_tmpa_tl
\tl_clear:N \l_tmpb_tl
}
\cs_new:Nn \__MyStuff_F:nnnnnn {
[F\c_math_superscript_token{{#1}{#2}{#3}}
\c_math_subscript_token{#4}]
\c_math_superscript_token{#5}
\c_math_subscript_token{#6}
}
\cs_new:Nn \__MyStuff_PutRightTo_l_tempa_tl:n {\tl_put_right:Nn \l_tmpa_tl {{#1}}}
\msg_new:nnn { MyStuff }
{ not-six-items }
{ \token_to_str:N #1's~argument~does~not~hold~a~comma-list~with~six~components.}
\prop_gput:Nnn \g_msg_module_type_prop { MyStuff } {}
\prop_gput:Nnx \g_msg_module_name_prop { MyStuff } {\jobname.tex~(main)}
\ExplSyntaxOff
\documentclass{article}
\begin{document}
\[\F{a,b,c,d,e,f}\]
% These raise errors:
%\[\F{a,b,c,d,e,f, }\]
%\[\F{a,b,c,d,e,f,}\]
%\[\F{a,b,c,d,e, ,,f}\]
%\[\F{a,b,c,d,e,f,g}\]
\end{document}
答案4
您可以expl3
按编号使用并提取列表中的项目。
\documentclass{article}
\ExplSyntaxOn
\NewDocumentCommand{\F}{m}
{
\int_compare:nF { \clist_count:n { #1 } = 6 } { \ERROR }
[F
\sp
{
\clist_item:nn {#1}{1}
\clist_item:nn {#1}{2}
\clist_item:nn {#1}{3}
}
\sb
{
\clist_item:nn {#1}{4}
}
]
\sp
{
\clist_item:nn {#1}{5}
}
\sb
{
\clist_item:nn {#1}{6}
}
}
\ExplSyntaxOff
\begin{document}
$\F{a,b,c,d,e,f}$
\end{document}
一种不同的(更有效的)策略是替换{a,b,c,d,e,f}
为{a}{b}{c}{d}{e}{f}
,可以按以下方式完成:\clist_map_function:nN
我们可以使用一个支撑项目的函数;因此a,b,c,d,e,f
我们可以立即扩展映射,因此\gert_f:n
将被调用为
\gert_f:n { {a}{b}{c}{d}{e}{f} }
并且它可以将参数传递给“内部”的六个参数函数。
\documentclass{article}
\ExplSyntaxOn
\NewDocumentCommand{\F}{m}
{
\int_compare:nTF { \clist_count:n { #1 } = 6 }
{
\gert_f:e { \clist_map_function:nN { #1 } \__gert_f_brace:n }
}
{ \ERROR }
}
\cs_new_protected:Nn \gert_f:n
{
\__gert_f:nnnnnn #1
}
\cs_generate_variant:Nn \gert_f:n { e }
\cs_new_protected:Nn \__gert_f:nnnnnn
{
[F \sp { #1 #2 #3 } \sb { #4 }] \sp { #5 } \sb { #6 }
}
\cs_new:Nn \__gert_f_brace:n { {#1} }
\ExplSyntaxOff
\begin{document}
$\F{a,b,c,d,e,f}$
\end{document}
无论哪种情况,如果决定采用不同的输出样式,则只有一个地方可以应用更改。
错误检查只是暗示,可以轻松添加更详细的内容。
如果您计划保留空项,那么您需要将列表拆分为一个序列,这样空项就不会被丢弃。
\documentclass{article}
\ExplSyntaxOn
\NewDocumentCommand{\F}{m}
{
\seq_set_split:Nnn \l__gert_f_seq { , } { #1 }
\int_compare:nTF { \seq_count:N \l__gert_f_seq = 6 }
{
\gert_f:e { \seq_map_function:NN \l__gert_f_seq \__gert_f_brace:n }
}
{ \ERROR }
}
\seq_new:N \l__gert_f_seq
\cs_new_protected:Nn \gert_f:n
{
\__gert_f:nnnnnn #1
}
\cs_generate_variant:Nn \gert_f:n { e }
\cs_new_protected:Nn \__gert_f:nnnnnn
{
[F \sp { #1 #2 #3 } \sb { #4 }] \sp { #5 } \sb { #6 }
}
\cs_new:Nn \__gert_f_brace:n { {#1} }
\ExplSyntaxOff
\begin{document}
$\F{a,b,c,d,e,f}$
$\F{a,,c,d,,f}$
\end{document}