\scantokens/\tex_scantokens:D 和 \tl_rescan:nn 之间本质/关键区别是什么?

\scantokens/\tex_scantokens:D 和 \tl_rescan:nn 之间本质/关键区别是什么?

第三部分 l3names 包——原语的命名空间, 部分1 设置 LaTeX3 编程语言界面3.pdf说:

该模块专门用于原语(以及这些的模拟),不应直接在 LaTeX3 代码中使用(“内核级”代码之外)。因此,这里没有记录这些原语:应参考 TeXbook、TeX by Topic 以及 pdfTeX、XeTeX、LuaTeX、pTeX 和 upTeX 手册以了解原语的详细信息。这些原语通常根据原语的\tex_⟨name⟩:D⟨姓名⟩在 pdfTeX 中,当原语与 pdf 输出无关时,省略前导 pdf。

在回答最近一个问题时我读到了这些陈述:

应该绝不\scantokens在 expl3 代码中使用。
应该绝不\...:D在 expl3 代码中使用控制序列。

我偶然发现了一个问题,我不知道如何在没有\scantokens/ 的情况下做到这一点\tex_scantokens:D

我使用 xparse 并打算将+v包含\verb*|...|-directives 的 -argument 传递给某个函数来重新标记输入。

在下面(第一个)示例中\tex_scantokens:D,一切都按我预期的方式进行:

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\group_begin:
\char_set_catcode_other:N \^^M
\use:n{
  \group_end:
  \NewDocumentCommand\PassVerbArgToRetokenizer{+v}{
    \group_begin:
    \tl_set:Nn \l_tmpa_tl {#1}
    \exp_args:Nnc \use:n { \exp_args:Nno \tl_put_right:Nn { \l_tmpa_tl } } {@percentchar}
    \exp_args:Nno \tl_put_left:Nn {\l_tmpa_tl} {\token_to_str:N\endgroup ^^M}
    %\tl_show:N \l_tmpa_tl
    \tex_newlinechar:D=\tex_endlinechar:D
    \exp_args:NV \tex_scantokens:D {\l_tmpa_tl}
  }
}
\ExplSyntaxOff

\begin{document}

\PassVerbArgToRetokenizer|\verb*+Some verbatim stuff!+|

\end{document}

您将获得一个包含以下内容的 .pdf 文件:

在此处输入图片描述

在以下(第二个)示例中,\tl_rescan:nn使用了而不是,\tex_scantokens:D并且您会收到一条错误消息:
! LaTeX Error: \verb ended by end of line.

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\group_begin:
\char_set_catcode_other:N \^^M
\use:n{
  \group_end:
  \NewDocumentCommand\PassVerbArgToRetokenizer{+v}{
    \group_begin:
    \tl_set:Nn \l_tmpa_tl {#1}
    \exp_args:Nnc \use:n { \exp_args:Nno \tl_put_right:Nn { \l_tmpa_tl } } {@percentchar}
    \exp_args:Nno \tl_put_left:Nn {\l_tmpa_tl} {\token_to_str:N\endgroup ^^M}
    %\tl_show:N \l_tmpa_tl
    %\tex_newlinechar:D=\tex_endlinechar:D
    %\exp_args:NnV \tl_rescan:nn {\tex_newlinechar:D=\tex_endlinechar:D} {\l_tmpa_tl}
    \exp_args:NnV \tl_rescan:nn {} {\l_tmpa_tl}
  }
}
\ExplSyntaxOff

\begin{document}

\PassVerbArgToRetokenizer|\verb*+Some verbatim stuff!+|

\end{document}

我的问题是:

  1. \scantokens使用/ 的结果\tex_scantokens:D与使用 的结果不同。 / 和\tl_rescan:nn之间哪个本质/关键差异导致了结果的差异?\scantokens\tex_scantokens:D\tl_rescan:nn

(第一个问题的答案也许能够让我自己回答下面的问题。)

\tl_rescan:nn(我想这与触发插入整个 token 序列有关,而这些 token 序列是由“重新扫描”整个序列一次性插入到标记流中:在示例中,TeX 将 active作为参数的+第二个分隔符。(这是通过对 active 进行一些小写欺骗来实现的。)如果事物已经被标记化并一次性插入,则在执行 时第二个已经是 catcode 12(其他) ,因此 TeX 找不到表示参数结束的匹配分隔符。\verb*~+\verb*\verb*

如果我理解正确的话,\tl_rescan:nn一方面会触发 TeX 重新标记(这样就会产生标记)整个 ⟨tokens⟩-顺序立即并立即一次性将整个结果标记序列附加到 TeX 食道中的标记流中。
\scantokens/\tex_scantokens:D另一方面触发 TeX 仅根据需要一点一点地重新标记事物(并以此方式产生标记),在此使用 的\scantokens参数作为输入源(就好像参数的标记未展开就写入文件一样)而不是某些 .tex 输入文件,并且每次生成标记时,它只生成其他消化器官所要求的尽可能多的标记。 其他消化器官依次一点一点地处理这些标记,并在此例如执行由这些标记表示的 catcode 更改。 这些变化反过来可能会影响后续事物如何(重新)标记 - 无论是通过\scantokens,还是通过读取/处理 .tex 输入文件,还是通过从控制台读取。)

  1. \tl_rescan:nn我对如何工作/做什么的误解在哪里\tl_rescan:nn
  2. 在第二个例子中我做错了什么?
  3. 我怎样才能利用 expl3 提供的东西来实现,而不使用\tex_scantokens:D我在第一个示例中得到的东西\tex_scantokens:D

相关内容