\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
。