`\write` 将不可打印的 ASCII 字符写入文件

`\write` 将不可打印的 ASCII 字符写入文件

\immediate\write\SomeStream{x}写入x在 中打开的文件\SomeStream。我想将不可打印的 ASCII 字符(例如 ``)写入文件。我的天真猜测是

\begingroup         %To keep the catcode change local
\catcode`\=11
\immediate\write\SomeStream{}
\endgroup

但是这会写出三个字符^^A而不是单个字符“”。有没有办法阻止 TeX 清理其输出?

梅威瑟:

\documentclass{minimal}
\newwrite\SomeStream
\immediate\openout\SomeStream NonPrintableASCII.test

\begingroup         %To keep the catcode change local
\catcode`\=11
\immediate\write\SomeStream{}
\endgroup

\immediate\closeout\SomeStream
\begin{document}
\end{document}

编辑:我的目标是编写一个文件并重新读取它,并进行可能疯狂的 catcode 更改(并且我使用不可打印的字符而不是为了^^A更加健壮。)。\scantokens完成工作(见下文)。

答案1

在某些 TeX 引擎中,没有办法。这取决于您使用的 TeX 引擎。其中一些可以使用翻译文件 ( foo.tcx) 来执行此操作。例如,pdfTeX:

pdflatex -translate-file=natural.tcx foo.tex

答案2

我知道以下内容可以使用以下模式解决每个可用 tex 引擎的任务:


\begingroup
\count0=0
\countdef\counter=0
\catcode`\^^00=11   \expandafter\xdef\csname pgfp@bin@\the\counter \endcsname{^^00}\advance\counter by1
catcode`\^^01=11    \expandafter\xdef\csname pgfp@bin@\the\counter \endcsname{^^01}\advance\counter by1
\catcode`\^^02=11   \expandafter\xdef\csname pgfp@bin@\the\counter \endcsname{^^02}\advance\counter by1
\endgroup

然后使用\csname pgfp@bin@0\endcsname获得二进制字符 0,\csname pgfp@bin@1\endcsname获得二进制字符 1,依此类推。但是,对于 TeX 中有意义的字符,这会变得非常混乱(但我看不出有其他方法可以解决这个问题)。但我相信您可以将其调整到您的应用程序中。

上面的代码实际上是 pgfplotsbinary.code.tex 的摘录——pgfplots 包使用它来生成低级阴影。如果需要,您可以从该文件中复制粘贴 TeX 字符的特殊处理。

它还具有一个可立即使用的“公共”接口。我将其 API 复制粘贴在此处:


% Returns a single character, which has the
% binary ASCII code '#1', with catcode 11.
%
% #1 (expands to) a number between 0 and 255 (inclusive).
%
% @see \pgfplotsgetchar Note that \pgfplotsgetchar is more powerful,
% but can't be used inside of \edef (it is not expandable) whereas
% \pgfplotscharno is.
\def\pgfplotscharno#1{\csname pgfp@bin@#1\endcsname}%

% Defines \pgfplotsretval to be the ASCII character for #1, with
% catcode 11.
%
% #1: either a number between 0 and 255 (inclusive) or a description
% of the character.
%
% Examples:
% \pgfplotsgetchar{35}
% \pgfplotsgetchar{`\#}   % code for '#'
% \pgfplotsgetchar{`\^^M} % Newline
% \pgfplotsgetchar{`\^^ff}% 255
%
% @see \pgfplotscharno
\def\pgfplotsgetchar#1{...}

我希望这有帮助。

答案3

我询问如何将不可打印字符写入文件,Leo Liu 的回答提供了一种方法:)

由于我的目标实际上是用 TeX 重新读取文件,保护它不受 catcode 更改的影响^,因此还有另一种方法。eTeX 原语\scantokens重新读取其参数(这几乎相当于写入文件并使用可能不同的 catcode 重新读取)。

为了展示它是如何工作的,我们首先使其^^A活跃,并将其定义为某个东西。

\documentclass{minimal}
\begin{document}
\catcode`\^^A=13
\def^^A{text}

然后我们在定义中使用它,并检查它\scantokens是否执行了应该的操作:该行扩展为Some text

\def\foo{Some ^^A}
\expandafter\scantokens\expandafter{\foo}

最后,我们将 的 catcode 改为^invalid ( 15),并重复该过程。Some text排版也一样。

\catcode`\^=15\relax
\expandafter\scantokens\expandafter{\foo}
\end{document}

TeX 不会抱怨这些字符,^^事实上它们已经消失了:^^A在定义时被改为一个字符\foo

相关内容