例如如果我运行
%! TEX program = lualatex
\documentclass{article}
\begin{document}
{% prepare a token list <a> (assume this is provided by user)
\catcode 13=12\relax % 12:other
\global\def\a{line 1^^M^^Mline 2^^M^^Mnewlinechar=\the\newlinechar^^M}%
}
% scan \a, but with newlinechar=13...
\newlinechar=13\relax
\expandafter\scantokens\expandafter{\a}
% but then the code inside should still see newlinechar=10.
\end{document}
每个由 charcode 为 13 的字符分隔的部分将作为单独的行写出;然而里面的代码将看到 \newlinechar=13。
假设我希望里面的代码看到的值等于正常值,即 10。我该如何实现?(该命令似乎没有提供任何明显的方法来实现。)
(还假设里面的代码是任意的用户提供的内容,可能不应该被触碰,并且它可能包含应该遵守的 catcode 更改命令。)
答案1
好吧,我能找到几种方法。
修改输入以适应换行符
正如 Skillmon 所建议的那样。
\cs_generate_variant:Nn \tl_replace_all:Nnn { Nee }
\tl_replace_all:Nee \a { \char_generate:nn { 13 } { 12 } } { \char_generate:nn { \newlinechar } { 12 } }
\tl_set_rescan:Nno \a {} { \a }
问题\newlinechar
:如果是 -1 或其他奇怪的值(例如) ,则会出现问题/
,并且用户代码恰好/
也有一个。
扩展\scantokens
一次然后恢复 newlinechar
看起来的 o 扩展\scantokens
与 的 o 扩展类似\@@input
,将内容放在输入流的前面。
这将适用于问题中的示例。(执行之前先\endgroup
展开\scantokens
一次。另一个是展开\a
。旁注,\scantokens
是一个原语,它展开以下标记直到看到{
,所以\expandafter
之前的另一个是不必要的。)
%! TEX program = lualatex
\documentclass{article}
\begin{document}
{% prepare a token list <a> (assume this is provided by user)
\catcode 13=12\relax % 12:other
\global\def\a{line 1^^M^^Mline 2^^M^^Mnewlinechar=\the\newlinechar^^M}%
}
% scan \a, but with newlinechar=13...
\begingroup\newlinechar=13\relax\expandafter\endgroup
\scantokens\expandafter{\a}
% but then the code inside should still see newlinechar=10.
\end{document}
使用活动字符恢复重新扫描的标记内的换行符
%! TEX program = lualatex
\documentclass{article}
\begin{document}
{% prepare a token list <a> (assume this is provided by user)
\catcode 13=12\relax % 12:other
\global\def\a{line 1^^M^^Mline 2^^M^^Mnewlinechar=\the\newlinechar^^M}%
}
\begingroup
\catcode `\~\active
\let~\endgroup
\newlinechar=13\relax
\scantokens\expandafter{\expandafter~\a}
\end{document}
我认为这种方法没有任何缺点(如果的默认 catcode~
未激活,它将在组关闭时重置,这\endlinechar
无关紧要)。基本上
- 开一个群
- 使其
~
处于活动状态,并使其在执行时关闭组 - 放
\newlinechar
- 传递
~⟨content⟩
给\scantokens
。当~
执行重新扫描时,该组将被关闭。