生成合并的 LaTeX 文件,其中包含 \input 代码?

生成合并的 LaTeX 文件,其中包含 \input 代码?

我目前正在进行一项实验,该实验涉及根据 OCR 图像重新排版一本数字化的实体书。由于涉及工作流程的各种原因,最终的项目架构是一个“主干”LaTeX 文档,其中包含一系列\input{page0000.tex}线条,每行代表原始书籍的每一页图像。

这看起来应该很简单,但我肯定没有找到正确的关键词:我希望能够生成一个单一的整体式 LaTeX 文件,其中\input{}代码已被文件内容替换——但是不是替换\included 文件。换句话说:将页面拼接成单个运行的 LaTeX 文件。

我可以用 Ruby 相当简单地做到这一点,但我只是认为有一个纯 TeX(cli?)解决方案。

答案1

我会用cat。但既然你要求 TeX 实现,那就用它吧。

\endlinechar=-1
\newread\in
\newwrite\out
\message{Please enter input file name: }
\read16to\inname
\openin\in=\inname \relax
\ifeof\in
        \immediate\write16{Failed to open \inname.}
        \expandafter\end
\fi
\message{Please enter output file name: }
\read16to\outname
\immediate\openout\out=\outname \relax
\begingroup
\catcode`@0
\catcode`(1
\catcode`)2
\catcode`\{12
\catcode`\}12
\catcode`I12
\catcode`N12
\catcode`P12
\catcode`U12
\catcode`T12
\catcode`\\12
@lowercase(
        @gdef@dosplitline#1\INPUT{#2}#3@splitsentinal(@def@ante(#1)@def@file(#2)@def@post(#3))
        @gdef@splitline(@expandafter@dosplitline@line\INPUT{@sentinal}@splitsentinal)
)
@endgroup
\def\splitpost{\expandafter\dosplitline\post\splitsentinal}
\def\sentinal{\sentinal}
\catcode`\%12
\def\processline{
        \ifx\file\sentinal
                \immediate\write\out{\ante}
                \let\temp\relax
        \else
                \immediate\write\out{\ante%}
                \let\temp\processline
                \copyfile
                \splitpost
                \ifx\empty\ante
                        \ifx\file\sentinal
                                \let\temp\relax
                        \fi
                \fi
        \fi
        \temp
}
\newread\f
\def\copyfile{
        \openin\f=\file\relax
        \ifeof\f
                \immediate\write16{Failed to open \file. Continuing.}
        \else
                \begingroup
                \loop
                        \readline\f to\line
                        \unless\ifeof\f
                        \immediate\write\out{\line}
                \repeat
                \endgroup
                \closein\f
        \fi
}

\loop
        \readline\in to\line
        \unless\ifeof\in
        \splitline
        \processline
\repeat
\closein\in
\immediate\closeout\out
\end

您需要使用 e-TeX(pdfTeX 也可以)来运行它。它会询问您主文件的名称和输出文件的名称:

$ etex merge
This is pdfTeX, Version 3.1415926-1.40.11 (TeX Live 2010)
 restricted \write18 enabled.
entering extended mode
(./merge.tex Please enter input file name: 
\inname=base
Please enter output file name: 
\outname=output
 )
No pages of output.
Transcript written on merge.log.

在这里,我输入了baseoutput查询,它读取base.tex并生成了output.tex

它并不完美。后面的空格\input{foo}会丢失,但你可以用 替换它们\input{foo} bar\input{foo}{} bar保留它们。此外,它假设%始终是注释,至少\input在行上是注释。

这是我的一个测试示例。

\documentclass{article}
\begin{document}
\input{a}

asdf \input{b}\input{c}{} \input{d}{}
\input{e}{} asdf
\end{document}

a.texe.tex分别由单个字母 A 到 E 组成。以下是输出。

\documentclass{article}
\begin{document}
%
A

asdf %
B
%
C
{} %
D
{}
%
E
{} asdf
\end{document}

请注意,\input替换不是递归的,尽管它可能至少达到深度 14(这将达到 TeX 输入流的最大数量 - 除非 e-TeX 支持更多)。

最后,这太荒谬了。不要使用它。改用专门处理文件的东西。

相关内容