使用 \input 模拟直接输入的文本

使用 \input 模拟直接输入的文本

我目前有用 Plain TeX 编写的以下代码:

\loadtoks\END
int main(void)
{
    printf("Hello World! %!@#$%&*&^\n");
}
\END

{\tt\the\toks0}
\bye

这个宏\loadtoks是我自己写的。它将每个 ASCII 字符的 catcode 设置为 12,这样特殊字符现在就只是普通字符了,然后它会向前扫描以查找给定的 \END 标记。在扫描过程中,它会将找到的每个标记附加到 \toks0 寄存器中。例如,也可以执行 ,\loadtoks+Hello World+在这种情况下,结束标记将是+。它的内部情况比这更复杂一些,但这基本上就是它的要点。

现在,我需要做的是:

\loadtoks\END
\input file.txt
\END

{\tt\the\toks0}
\bye

当然,这只是简单地排版单词“\input file.txt”,而不是读入文件。但自然而然,我需要它做的是实际读入文件,并表现得好像文件的内容实际上已经直接输入到 TeX 源文件中(如第一个示例中所示)。

我已经为此绞尽脑汁一段时间了,但似乎无法弄清楚。请注意,我知道 LaTeX 的 \verb,但我严格使用 Plain TeX,我很想找到一种仅使用 TeX 的纯宏和原始宏的解决方案。

答案1

我将尝试回答这个长期未回答的问题。这个问题的问题是宏\loadtoks未显示。这让我们想起了本网站经常提到的 MWE。

我尝试估算你的神秘且未公开的宏\loadtoks。我的意思是,你将所有 catcode 设置为 12(其他),并且第一个参数(\END在示例中)由处理\string并作为分隔符。这意味着:

\newcount\tmpnum
\def\loadtoks#1{\bgroup \tmpnum=32
   \loop\advance\tmpnum by1 \ifnum\tmpnum<128 \catcode\tmpnum=12 \repeat
   \obeylines \obeyspaces
   \expandafter\def\expandafter
      \loadtoksA\expandafter##\expandafter1\string#1{\egroup\toks0={##1}}%
   \loadtoksA
}
{\obeyspaces\global\let =\ }

\loadtoks\END
int main(void)
{
    printf("Hello World! %!@#$%&*&^\n");
}
\END
{\tt\the\toks0}
\bye

有效。现在,您的问题是关于读取外部文件。首先,恕我直言,在传统 TeX 中通过扫描整个文件内容作为参数来做到这一点是不可能的。File ended while scanning出现错误,并且无法在文件末尾放置某些内容作为分隔符。如果您坚持使用传统 TeX,则需要使用带有\read原语的循环,并且必须使用测试逐行读取文件\ifeof

但是,如果您使用的是 eTeX,那么您可以通过 tokens 寄存器将 tokens 放在文件末尾之后\everyeof。因此,您需要做的就是处理分隔符\string\everyeof写入一些\expandafters:

\everyeof \expandafter{\string\END} 
\expandafter\loadtoks\expandafter\END
\input file.txt

{\tt\the\toks0}
\bye

编辑:\expandafter删除一个多余的。

答案2

借助 包,可以将文件内容加载到宏中catchfile。由于 ,该包需要 e-TeX \everyeof

具有可见空间的示例:

\input catchfile.sty\relax
\CatchFileDef\MyFileContents{file.txt}{%
  \def\do#1{\catcode`#1=12 }%
  \dospecials
  \obeylines
}

{\tt\MyFileContents}

\bye

结果中有可见空格

不可见空格的示例:

\input catchfile.sty\relax
\CatchFileDef\MyFileContents{file.txt}{%
  \def\do#1{\catcode`#1=12 }%
  \dospecials
  \obeylines
  \obeyspaces
}

\begingroup
  \def\temp#1{\endgroup
    \def\DefActiveSpace{\def#1}%
  }%
  \catcode`\ =\active
\temp{ }

{\tt\DefActiveSpace{\ }\MyFileContents}

\bye

结果显示空格不可见

相关内容