我正在做代码降临 (2022)在 LaTeX3 中(不,确实如此)。每个挑战都涉及一些输入,对于第 6 天来说,这些输入只有一行,而且很长(4096 个字符)。这一行需要逐个字符地处理,所以我想让 TeX 逐个字符地读取它。现在,我知道 TeX 可以轻松处理这种长度的标记列表,但我在 LaTeX3 中执行 AoC 的目的是为了更好地理解语言,而不是找到最有效或最有效的解决方案。因此,即使我最终没有使用逐个字符的方法,而是将整个文件读入单个标记列表,我仍然想知道如何做到这一点。
以下是我尝试过的:
\cs_set_eq:Nc \aoc_input: {@@input} % to get an expandable file input
\cs_new:Npn \aoc_process_char:w #1
{
\tl_if_eq:nnF {#1} {\par} % this doesn't work
{
\aoc_process_char:w
}
}
\exp_after:wN \aoc_process_char:w \aoc_input: file.txt\relax
这不起作用,因为\par
文件末尾的\outer
不能用作函数的参数。因此,在阅读此网站时,我看到了依次\let
对每个标记执行某些操作并进行测试的建议,例如:
\def\dostuff{%
\ifx\tmpvar\par
\else
\expandafter
\slurptoken
\fi
}
\def\slurptoken{\afterassignment\dostuff\let\tmpvar=}
\expandafter\slurptoken\@@input file.txt\relax
我正在努力将其转换为 LaTeX3 语法。感觉其中一种\peek_after:Nw
函数应该是我正在寻找的,但我需要一个从流中吸收标记的函数,而remove
名称中带有的函数只测试 charcode 或 catcode,而我希望能够使用该标记进行更多处理。
那么上述 TeX 代码的最佳 LaTeX3 等效代码是什么?
答案1
我认为最简单的方法是使用
\peek_analysis_map_inline:n { <inline code> }
此函数在输入流中向前查看,并将后面的标记提供给<inline code>
。<inline code>
接收三个参数:
- 某些东西
o
- 或 -x
扩展到所见的标记; - 标记的字符代码(如果是控制序列则为 -1);
- 令牌的类别代码(如果是控制序列则为 0),以十六进制表示。
有了这些信息,您就可以对输入进行任何所需的处理。
\peek_analysis_map_inline:n
特别好,因为它会花一些时间来区分 a{
和 a \bgroup
,这并不简单(用通常的\futurelet
方法是不可能的),而且它使得根据需要处理标记变得非常容易。
下面是一个示例。它从基础开始,检查文件是否存在。然后插入\tex_everyeof:D { \__loopspace_file_process_end: }
一个标记来表示文件结束。然后输入文件,并用 进行处理\peek_analysis_map_inline:n
。
\ExplSyntaxOn
\NewDocumentCommand \processfile { m }
{ \loopspace_file_process:n {#1} }
\cs_new_protected:Npn \loopspace_file_process:n #1
{
\file_if_exist:nTF {#1}
{ \__loopspace_file_process:n {#1} }
{ \msg_error:nnn { loopspace } { file-not-found } {#1} }
}
\msg_new:nnn { loopspace } { file-not-found } { File~'#1'~not~found. }
\cs_new_protected:Npn \__loopspace_file_process:n #1
{
\group_begin:
\tex_everyeof:D { \__loopspace_file_process_end: }
\exp_after:wN \__loopspace_file_process:w \tex_input:D {#1}
\group_end:
}
\cs_new_protected:Npn \__loopspace_file_process:w
{
\peek_analysis_map_inline:n
{
\int_compare:nNnT {##2} = { -1 }
{
\exp_after:wN \token_if_eq_meaning:NNT
##1 \__loopspace_file_process_end:
{ \peek_analysis_map_break: }
}
% process token:
\mode_leave_vertical:
\exp_after:wN \token_to_str:N ##1 ~ ( ##2 ,~ ##3 ) \par
% --------------
}
}
\cs_new_protected:Npn \__loopspace_file_process_end:
{ \msg_error:nn { loopspace } { premature-end } }
\msg_new:nnn { loopspace } { premature-break }
{
Premature~usage~of~\iow_char:N\\peek_analysis_map_break:.\\
Some~content~may~have~been~left~over.
}
\ExplSyntaxOff
\documentclass{article}
\begin{filecontents}{tmp.tex}
Lorem ipsum \textbf{dolor sit amet}. \bgroup{}$&#^_
\end{filecontents}
\begin{document}
\ttfamily \processfile{tmp.tex}
\end{document}