tex中的文件输出

tex中的文件输出

总所周知,任何编程系统都离不开输入输出的。在latex中我们很熟悉文件输入的方式,比如input,include。但对于文件输出的方式并不是非常熟悉,但实际上应用非常多的,比如编译时输出的辅助文件。下面我们来看一看,tex系统中的文件输出方式,以及在filecontents宏包,参考文献相关命令bibliography带来的输出,以及biblatex宏包中的输出。

1. tex系统文件输出方式

tex系统中的文件输出方式,与常见编程语言的文件输出是类似的。先打开一个文件,赋予一个句柄(或通道),然后顺着该句柄输出需要输出的内容,然后关闭文件。

打开和关闭文件的命令为openout,closeout,写一行内容的命令为write,下面为一个简单的例子:

% !Mode:: "TeX:UTF-8"
\documentclass{article}
\usepackage{ctex}
\begin{document}

\newwrite\foutfile
\immediate\openout\foutfile\jobname.dat
\def\outcmd{}
\immediate\write\foutfile{\string\outcmd}
\immediate\write\foutfile{A string to out}
\newcounter{numberA}
\setcounter{numberA}{0}
\loop \stepcounter{numberA} \ifnum\thenumberA<10 \immediate\write\foutfile{\thenumberA} \repeat
\immediate\closeout\foutfile

\end{document}

其中:输出的文件当前tex文件名.dat,第一个write输出了一个转换为文本的记号,第二个write输出了一个简单的字符串,第三个write则循环输出了1到9共9个数字。immediate命令表示立即执行输出。

输出的文件内容为:

\outcmd
A string to out
1
2
3
4
5
6
7
8
9

2. filecontents宏包的文件输出

其输出函数为filec@ntents,一个参数是文件名,首先检测了一些是否存在当前文件,接着用句柄\reserved@c打开文件,输出文档基本信息,然后利用一个循环把环境内的各行输出到文件中。

\gdef\filec@ntents#1{%
  \openin\@inputcheck#1 %
  \ifeof\@inputcheck%
    \@latex@warning@no@line%
        {Writing file `\@currdir#1'}%
  \else %
    \@latex@warning@no@line%
        {Overwriting file `\@currdir#1'}%
  \fi %
  \closein\@inputcheck %
  \chardef\reserved@c15 %
  \ch@ck7\reserved@c\write%
  \immediate\openout\reserved@c#1\relax%
  \if@tempswa%
    \immediate\write\reserved@c{%
      \@percentchar\@percentchar\space%
          \expandafter\@gobble\string\LaTeX2e file `#1'^^J%
      \@percentchar\@percentchar\space  generated by the %
        `\@currenvir' \expandafter\@gobblefour\string\newenvironment^^J%
      \@percentchar\@percentchar\space from source `\jobname' on %
         \number\year/\two@digits\month/\two@digits\day.^^J%
      \@percentchar\@percentchar}%
  \fi%
  \let\do\@makeother\dospecials%
  \count0=128\relax %
  \loop %
    \catcode\count0=11\relax %
    \advance\count0 by 1\relax %
    \ifnum\count0<256 %
  \repeat %
  \edef\E{\@backslashchar end\string{\@currenvir\string}}%
  \edef\reserved@b{%
    \def\noexpand\reserved@b%
         ####1\E####2\E####3\relax}%
  \reserved@b{%
    \ifx\relax##3\relax%
      \immediate\write\reserved@c{##1}%
    \else%
      \edef^^M{\noexpand\end{\@currenvir}}%
      \ifx\relax##1\relax%
      \else%
          \@latex@warning{Writing text `##1' before %
             \string\end{\@currenvir}\MessageBreak as last line of #1}%
        \immediate\write\reserved@c{##1}%
      \fi%
      \ifx\relax##2\relax%
      \else%
         \@latex@warning{%
           Ignoring text `##2' after \string\end{\@currenvir}}%
      \fi%
    \fi%
    ^^M}%
  \catcode`\^^L\active%
  \let\L\@undefined%
  \def^^L{\@ifundefined L^^J^^J^^J}%
  \catcode`\^^I\active%
  \let\I\@undefined%
  \def^^I{\@ifundefined I\space\space}%
  \catcode`\^^M\active%
  \edef^^M##1^^M{%
    \noexpand\reserved@b##1\E\E\relax}}%

2. latex内核命令\bibliography的文件输出

详见source2e.PDF,ltbibl.dtx一节。latex中利用命令\bibliography把参考文献信息写入到辅助文件中,然后由bibtex进行处理。

 \def\bibliography#1{%
 \if@filesw
 \immediate\write\@auxout{\string\bibdata{#1}}%
 \fi
 \@input@{\jobname.bbl}}

可以看到这是一个很简单的定义,就是把bib文件名输出到\@auxout句柄定义的辅助文件中,而且就只有一行数据\bibdata{bibfilename}。这样bibtex通过该行信息,确定文献信息所在的bib文件,进而进一步处理。

3. biblatex宏包的bcf文件输出

可以看到biblatex写bcf文件主控函数是\def\blx@ctrlwrite{,其中文件打开和关闭为:

\immediate\openout\blx@bcfout\jobname.bcf\relax
  \blx@auxwrite\blx@bcfout{}{\blx@tempa}%
  \global\undef\blx@tempa
  \endgroup
  \AfterEndDocument{%
    \def\do##1{%
      \csxappto{blx@sortingtemplates}{%
        \blx@xml@sortingtemplate{##1}
                        {\ifcsdef{blx@sortdef@locale@##1}{ locale="\csuse{blx@sortdef@locale@##1}"}{}}
                        {\csuse{blx@sortingtemplate@##1}}}}%
      \dolistloop\blx@sortingtemplatenames
    \blx@auxwrite\blx@bcfout{}{%
      \blx@xml@endsection\blx@nl
      \blx@xml@comment{SORTING TEMPLATES}%
      \csuse{blx@sortingtemplates}%
      \blx@xml@comment{DATALISTS}%
      \csuse{blx@dlists}%
      \blx@xml@endfile}%
    \immediate\closeout\blx@bcfout}}

其中,关闭文件是文件编译结尾处。定义的写文件\blx@auxwrite函数为:

\protected\def\blx@auxwrite#1#2#3{%
  \if@filesw
    \begingroup
    \blx@safe@actives
    \let\protect\string
    #2%
    \immediate\write#1{#3}%
    \endgroup
  \fi}

其中#1为文件句柄,#3为输出的内容。

4. 小结

可以看到,tex 中输出文件是一件比较常见的事情,而且大有作用,很多情况下用来输出一些辅助信息,帮助额外的程序比如bibtex,biber等进行下一步处理。如果要设计一个宏包,也考虑需要源文档中的信息来进一步额外处理,那么类似的方式是可以采用的。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值