带有 Expl3 的匿名命令

带有 Expl3 的匿名命令

以下代码允许我轻松地生成系列(参见代码下方的示例):

\documentclass{article}

\ExplSyntaxOn
\NewDocumentCommand \simpleseq { m m m } {
  \seq_set_split:Nnn \l_inner_seq {,} {#3}
  \seq_set_map:NNn \l_part_seq \l_inner_seq {\exp_not:n {#2}}
  \seq_use:Nn \l_part_seq {#1 \allowbreak}
}

\NewDocumentCommand \seq { O{,} O{\dots} D||{##1} s m s } {
  \seq_set_split:Nnn \l_outer_seq {;} {#5}
  \seq_set_map:NNn \l_final_seq \l_outer_seq {\exp_not:n {\simpleseq{#1}{#3}{##1}}}
  \IfBooleanT #4 { #2 #1 \allowbreak }
  \seq_use:Nn \l_final_seq {#1 \allowbreak #2 #1 \allowbreak }
  \IfBooleanT #6 { #1 \allowbreak #2 }
}
\ExplSyntaxOff

\begin{document}

\[\seq[-] {1,2,3}\] % 1 - 2 - 3
\[\seq{1,2;5,6;10,11}\] % 1, 2, ..., 5, 6, ..., 10, 11
\[\seq*{1,2;5,6}\] % ..., 1, 2, ..., 5, 6
\[\seq[\ ][---]{1,2;5,6}*\] % 1 2 --- 5 6 ---

\[\seq |A_{##1}| {1,2;7,8}*\] % A_1, A_2, ..., A_5, A_6
% How to alter commands so that I can use either of these versions?
%\[\seq |A_{#1}| {1,2;7,8}*\]
%\[\seq |A_{\v}| {1,2;7,8}*\]

\end{document}

我关心的是最后一个例子。我不喜欢使用##1作为参数。我想要#1\v

此外,欢迎对本代码质量提出任何建议,我是 Expl3 初学者......

答案1

定义一个临时函数:

\documentclass{article}
\usepackage{amsmath}
\usepackage{xparse}

\ExplSyntaxOn

\seq_new:N \l_fabian_inner_in_seq
\seq_new:N \l_fabian_inner_out_seq
\seq_new:N \l_fabian_outer_in_seq
\seq_new:N \l_fabian_outer_out_seq

\NewDocumentCommand \seq { O{,} O{\dots} d|| s m s }
 {
  \IfNoValueTF{#3}
   { \cs_set_eq:NN \__fabian_inner_process:n \use:n }
   { \cs_set_protected:Nn \__fabian_inner_process:n { #3 } }
  \IfBooleanT #4 { #2 #1 \allowbreak }
  \fabian_outer:nnn { #1 } { #2 } { #5 }
  \IfBooleanT #6 { #1 \allowbreak #2 }
 }
\cs_new_protected:Nn \fabian_outer:nnn
 {
  \seq_set_split:Nnn \l_fabian_outer_in_seq {;} {#3}
  \seq_set_map:NNn \l_fabian_outer_out_seq \l_fabian_outer_in_seq
   {
    \exp_not:n { \fabian_inner:nn { #1 } { ##1 } }
   }
  \seq_use:Nn \l_fabian_outer_out_seq {#1 \allowbreak #2 #1 \allowbreak }
 }
\cs_new_protected:Nn \fabian_inner:nn
 {
  \seq_set_split:Nnn \l_fabian_inner_in_seq { , } { #2 }
  \seq_set_map:NNn \l_fabian_inner_out_seq \l_fabian_inner_in_seq
   { \exp_not:n {\__fabian_inner_process:n { ##1 } } }
  \seq_use:Nn \l_fabian_inner_out_seq { #1 }
 }
\ExplSyntaxOff

\begin{document}
\begin{gather}
\seq[-] {1,2,3} % 1 - 2 - 3
\\
\seq{1,2;5,6;10,11} % 1, 2, ..., 5, 6, ..., 10, 11
\\
\seq*{1,2;5,6} % ..., 1, 2, ..., 5, 6
\\
\seq[\ ][\text{---}]{1,2;5,6}* % 1 2 --- 5 6 ---
\\
\seq |A_{#1}| {1,2;7,8}*
\\
\seq |A_{#1}| *{1,2;7,8}*
\end{gather}
\end{document}

在此处输入图片描述

答案2

以下修改有效,但看起来真的真的真的不安全,除非有人告诉我这是一个好主意(并给我论据让我相信他:p),否则我不会使用它。

\NewDocumentCommand \simpleseq { m m m } {
  \seq_set_split:Nnn \l_inner_seq {,} {#3}
  \seq_set_map:NNn \l_part_seq \l_inner_seq {\exp_not:n {\def\v{##1}#2}}
  \seq_use:Nn \l_part_seq {#1 \allowbreak}
}

经过一些测试后,它似乎不是那么不安全......

我刚刚了解到,这是\def本地绑定(而不是我认为的全局绑定)。

我做了一些测试,我\def编写了一个宏\v,使用它,使用我的命令,然后\v再次使用,一切都按预期工作。

无论如何,我仍然愿意接受更符合 Latex3 风格的解决方案 :-)

相关内容