使用命令\openout
,\write
我将文本输出到文件中。如何输出制表符?
\documentclass{article}
\begin{document}
\newwrite\tempfile
\immediate\openout\tempfile="filename.txt"
\immediate\write\tempfile{I want a tab at the beginning of this line}
\immediate\closeout\tempfile
\end{document}
编辑1
按照 egreg 的解决方案,我使用\catcode`\^^I=12
。如果我直接使用代码,则此方法有效,但如果我将代码括在命令中,则无效:
\documentclass{article}
\begin{document}
\newwrite\tempfile
\immediate\openout\tempfile="filename.txt"
\begingroup
\catcode`\^^I=12 %
\immediate\write\tempfile{^^II want a tab at the beginning of this line}
\endgroup
\immediate\closeout\tempfile
\newcommand{\test}{
\newwrite\tempfilee
\begingroup\catcode`\^^I=12 %
\immediate\openout\tempfilee="filename2.txt"
\immediate\write\tempfilee{^^II want a tab at the beginning of this line}
\endgroup
}
\test
coucou
\end{document}
编辑2再次感谢 egreg。第二种解决方案有效,但如果我\test
从另一个命令内部调用则无效,而这正是我需要的:
\newwrite\tempfile
\immediate\openout\tempfile=\jobname.out
\def\test{\begingroup\catcode`\^^I=12 \testaux}
\def\testaux#1{\immediate\write\tempfile{#1}\endgroup}
\newcommand{\makeit}{
\test{^^I<-TAB again}
}
\test{ <-TAB} % WORKS
\test{^^I<-TAB} %WORkS
\makeit %DOES NOT WORK
\immediate\closeout\tempfile
编辑3。egreg 的第二个解决方案有效......但如果它在内部则无效AtEndDocument
:
\documentclass{article}
\AtEndDocument{\test{^^Ifin du document}
\immediate\closeout\tempfile }
\begin{document}
\newwrite\tempfile
\immediate\openout\tempfile=output.txt
\catcode`\^^I=\active
\def^^I{}
\def\test#1{\begingroup
\edef^^I{\string^^I}\immediate\write\tempfile{#1}\endgroup}
\test{^^I<-coucou} %% WORKS
\def\foo{\test{^^I<-Jojo}}
\foo %% WORKS
\end{document}
但是最后一句“fin du document”没有 TAB。
答案1
遗憾的是,在文件中写入文字 TAB 字符取决于您拥有的 TeX 发行版以及格式的初始化方式。
pdftex
使用 TeX Live 发行版,pdflatex
和的格式latex
都已准备好,只需输入选项-translate-file=cp227.tcx
,即可使 TAB 字符“可打印”。
编译输入
\newwrite\tempfile
\immediate\openout\tempfile=\jobname.out
\begingroup
\catcode`\^^I=12 %
\immediate\write\tempfile{^^I<-TAB}
\endgroup
\immediate\closeout\tempfile
\csname @@end\endcsname\end % trick for stopping with Plain TeX and LaTeX
使用tex
和使用pdftex
(在 TeX Live 发行版上)将产生两个不同的结果(我报告“十六进制转储”):
5e 5e 49 3c 2d 54 41 42 0a
(tex
)09 3c 2d 54 41 42 0a
(pdftex
)
确实tex
是不是设置 TCX 转换,使 TAB 字符可打印。
luatex
如果用或编译文件,lualatex
结果将与情况 2 一样。用xetex
它仍然不同。
5e 5e 49 3c 2d 54 41 42 0a
(xetex
)09 3c 2d 54 41 42 0a
(xetex -8bit
)
因此,^^I
以这种形式写出的是用tex
、xetex
或xelatex
,而以文字 TAB 的形式写出的是用pdftex
、pdflatex
或,也可以是用和luatex
。lualatex
xetex
xelatex
假如他们被要求-8bit
选择。
这个故事的寓意是:不要使用 TAB,也不要尝试将它们写入文件中,因为其结果在各个系统和机器上是不可预测的。
如何定义一个命令,将一行写入尊重 TAB 字符的文件(假设pdftex
)?
必须记住,一旦 TeX 读入标记列表,类别代码就会固定。因此,必须使用不同的策略:
\newwrite\tempfile
\immediate\openout\tempfile=\jobname.out
\def\test{\begingroup\catcode`\^^I=12 \testaux}
\def\testaux#1{\immediate\write\tempfile{#1}\endgroup}
\test{ <-TAB}
\test{^^I<-TAB}
\immediate\closeout\tempfile
\csname @@end\endcsname\end
这将写入\jobname.out
(再次显示十六进制转储)
09 3c 2d 54 41 42 0a 09 3c 2d 54 41 42 0a
因此写入了两个文字 TABS(第一个参数中的空格被\test
认为是 TAB,不幸的是,在此系统上它可能会转换为空格)。
如果您\test
还需要在另一个命令的参数中工作,那么上述技巧将不起作用:类似于 的操作\foo{x \test{^^I<-TAB}}
,其中接受一个参数,将会破坏在而不是 在 中\foo
完成的参数的延迟抓取:当 TeX 将参数存储到它时,它会修复类别代码。\testaux
\test
\foo
但是还有另一个问题:TeX^^I
一读取空格标记(当^^I
类别代码为 10 时)就会将其规范化。所以你的问题更难解决。如果你不需要文件中的 TAB,除了为了编写它之外,你可以这样做
\catcode`\^^I=\active
\def^^I{}
\newwrite\tempfile
\immediate\openout\tempfile=\jobname.out
\def\test#1{\begingroup
\edef^^I{\string^^I}\immediate\write\tempfile{#1}\endgroup}
\test{ <-TAB}
\test{^^I<-TAB}
\def\foo#1{#1\test{#1}}
\foo{^^I<-TAB}
\immediate\closeout\tempfile
\csname @@end\endcsname\end
这样做的局限性是 TAB 不会打印任何内容,而序列<SPACE><TAB><SPACE>
将打印二空格。
好好考虑一下不是沿着这条路前进。
如果需要的命令\test
数量有限,可以像上面那样给出正确的定义。如果你想允许\test
作为参数任何指挥部,你运气不好。
如果你需要做的只是写\AtEndDocument
,你可以说
\begingroup
\catcode`\^^I=12
\gdef\EndTest{\test{^^I<-TAB}}
\endgroup
\AtEndDocument{\EndTest}
可以不定义新命令:
\begingroup
\lccode`?=`\^^I
\lowercase{\endgroup\AtEndDocument{\test{?fin du document}}}
\AtEndDocument{\immediate\closeout\tempfile}
您可以使用不同于的字符?
,重要的是它是一个 12 类字符。
答案2
您可以定义一个新的宏,\mytab
为 TAB 字符提供类别 12。
\begingroup
\catcode`\^^I=12
\gdef\mytab{^^I}
\endgroup
然后,使用\mytab
(末尾有一个空格) 代替^^I
或<TAB>
:
\documentclass{article}
% memoize TAB char
\begingroup
\catcode`\^^I=12
\gdef\mytab{^^I}
\endgroup
% open temp file
\newwrite\tempfile
\immediate\openout\tempfile=\jobname.out
% macro to write to temp file
\def\writetotemp#1{\immediate\write\tempfile{#1}}
\AtEndDocument{\writetotemp{\mytab<-TABEND}}
\AtEndDocument{\immediate\closeout\tempfile}
\begin{document}
\immediate\write\tempfile{\mytab <-TAB1}
\writetotemp{\mytab <-TAB2}
\end{document}
以下是 的转储\jobname.out
:
0000000 \t < - T A B 1 \n \t < - T A B 2 \n
3c09 542d 4241 0a31 3c09 542d 4241 0a32
0000020 \t < - T A B E N D \n
3c09 542d 4241 4e45 0a44
0000032