该包的 LaTeX3 文档l3basics
列出了三个函数
\use_none_delimit_by_q_nil:w ... \q_nil
\use_none_delimit_by_q_stop:w ... \q_stop
\use_none_delimit_by_q_recursion_stop:w ... \q_recursion_stop
带有分隔参数,它们都...
从输入流中删除该部分。另外:nw
定义了三个变体,它们删除该...
部分但将其第一个参数放回到输入流中。
我想知道这些函数应该用来做什么。当起始命令和终止标记必须分布在代码中的两个不同位置时,读取由终止标记分隔的参数有时非常有用。
但是,这里有三个这样的函数,其名称表明这些函数应该在特殊情况下使用。它们还会从输入中删除它们收集的标记,这对于递归函数来说似乎很奇怪;收集标记并将其作为最终结果返回对我来说似乎更有用。
那么这些功能的预期用途是什么?
答案1
它们的目的正是您所期望的:删除最多一个给定的标记。但是,由于标记必须匹配确切地用例的结束。我们需要多个唯一的标记,特别是对于可扩展循环(使用\q_recursion_stop
)。根据确切的设置,可能会有嵌套标记,或者可能出于其他原因,其中一个或另一个是可取的。因此,我们有一个小集合,基于“通用”结束标记。
虽然我们(团队)有一些更复杂的核心循环结构,但“通用循环”代码很好地说明了分隔结尾的使用。例如,假设我们想要以三个标记为一组循环遍历某个输入数据结构。我们可以将其设置为
\input expl3-generic %
\ExplSyntaxOn
\cs_new:Npn \siracusa_loop:n #1
{
\__siracusa_loop:NNN
#1
\q_recursion_tail \q_recursion_tail \q_recursion_tail
\q_recursion_stop
}
\cs_new:Npn \__siracusa_loop:NNN #1#2#3
{
\quark_if_recursion_tail_stop:n {#3}
\quark_if_recursion_tail_stop:n {#2}
\quark_if_recursion_tail_stop:n {#1}
\tl_show:n { First ~"#1";~Second:~"#2";~Third~"#3" }
\__siracusa_loop:NNN
}
\siracusa_loop:n { ABC }
\siracusa_loop:n { ABC 123 }
\siracusa_loop:n { ABC D }
\siracusa_loop:n { ABC DE }
\tex_end:D
此处,“清理”隐藏在 内\quark_if_recursion_tail_stop:n
,需要\use_none_delimit_by_q_recursion_stop:w
。极少数情况下,可能需要手动执行此操作:通常在需要进行复杂改组的情况下。
答案2
根据 Joseph Wright 非常有用的回答,我认为我现在理解了这种函数背后的想法。我玩了一下,想出了一个\use_i_delimit_by_*
可以使用类似函数集的示例:
\input expl3-generic %
\ExplSyntaxOn
\cs_new:Npn \siracusa_loop:n #1
{
\__siracusa_loop:NNN
#1
\q_recursion_tail \q_recursion_tail \q_recursion_tail
\q_recursion_stop
}
\cs_new:Npn \__siracusa_loop:NNN #1#2#3
{
\siracusa_check_for_rest:Nn {#1} { }
\siracusa_check_for_rest:Nn {#2} { \tl_show:n { Rest ~"#1" } }
\siracusa_check_for_rest:Nn {#3} { \tl_show:n { Rest ~"#1#2" } }
\tl_show:n { First ~"#1";~Second:~"#2";~Third~"#3" }
\__siracusa_loop:NNN
}
\cs_new:Npn \siracusa_check_for_rest:Nn #1#2
{
\tl_if_empty:oT { \__quark_if_recursion_tail:w {} #1 {} ?! \q_recursion_tail ??! }
{\use_i_delimit_by_q_recursion_stop:nw { #2 } }
}
\siracusa_loop:n { ABC }
\siracusa_loop:n { ABC 123 }
\siracusa_loop:n { ABC D }
\siracusa_loop:n { ABC DE }
\tex_end:D
的定义\siracusa_check_for_rest:Nn
基于 的\quark_if_recursion_tail_stop:n
定义,只是用\use_i_delimit_by_q_recursion_stop:nw
代替\use_none_delimit_by_q_recursion_stop:w
。(这些名字到底是谁想出来的?;))
我们现在还可以在输出中获得剩余的输入标记:
第一个“A”;第二个:“B”;第三个“C”
第一个“A”;第二个:“B”;第三个“C”
第一个“1”;第二个:“2”;第三个“3”第一页“A”;第二页:“B”;第三页“C”
其余部分“D”第一个“A”;第二个:“B”;第三个“C”
其余“DE”