# Generate a merged LaTeX file, with \input code in place?

I'm currently working on an experiment that involves re-typesetting a digitized physical book from OCRed images. For various reasons involving the workflow, the resulting project architecture is a "backbone" LaTeX document containing a series of \input{page0000.tex} lines, one for each page image of the original book.

It seems like it should be trivial, but I must not have stumbled on the correct keywords: I'd like to be able to generate a single, monolithic LaTeX file, where the \input{} code has been replaced by the file contents—but not replacing the \included files. In other words: something to stitch together the pages into a single run-on LaTeX file.

I could do it rather simply in Ruby, but I just have to think there's a pure TeX (cli?) solution.

-
See the recent question Replace \input{fileX} by the content of fileX automatically. BTW: your title says something different than your text. –  Martin Scharrer Jul 2 '11 at 18:35
\included files (like .sty files). ?? You don't use \include for .sty files. You technically even can't AFAIK. If you only want the \input macros in-lined than simple rename \include to something else, run one of the above linked commands and rename them back. –  Martin Scharrer Jul 2 '11 at 18:37
Thanks; edited title and bad example accordingly. –  Bill Tozier Jul 2 '11 at 18:39
Since the individual page files are just concatenated in my "backbone" file, I can simply use cat 00*.tex > combined_pages.tex if I needed to use the shell, and a pure Ruby solution is only about a line long. Was hoping, for example, that TeX Live might be able to export to tex, for example? –  Bill Tozier Jul 2 '11 at 18:46
you can read and then write input files verbatim. Coding this with TeX is however much more work then with a scripting language like Perl or Ruby. –  Martin Scharrer Jul 2 '11 at 19:01
show 1 more comment

I'd use cat. But since you asked for a TeX implementation, here you go.

\endlinechar=-1
\newwrite\out
\message{Please enter input file name: }
\openin\in=\inname \relax
\ifeof\in
\immediate\write16{Failed to open \inname.}
\expandafter\end
\fi
\message{Please enter output file name: }
\immediate\openout\out=\outname \relax
\begingroup
\catcode@0
\catcode(1
\catcode)2
\catcode\{12
\catcode\}12
\catcodeI12
\catcodeN12
\catcodeP12
\catcodeU12
\catcodeT12
\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
}
\def\copyfile{
\openin\f=\file\relax
\ifeof\f
\immediate\write16{Failed to open \file. Continuing.}
\else
\begingroup
\loop
\unless\ifeof\f
\immediate\write\out{\line}
\repeat
\endgroup
\closein\f
\fi
}

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


You need to use e-TeX (pdfTeX would work) to run this. It will ask you for the name of the master file and for the name of the output file:

\$ 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
\outname=output
)
No pages of output.
Transcript written on merge.log.


Here, I entered base and output to the queries and it read base.tex and produced output.tex.

It isn't perfect. Spaces after \input{foo} are lost, but you can replace \input{foo} bar with \input{foo}{} bar to keep them. Also, it assumes that % is always a comment, at least on \input lines.

Here's my one test example.

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

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


a.tex through e.tex consist of a single letter, A through E, respectively. Here's the output.

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

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


Note that \input replacement is not recursive, although it probably could be, at least up to depth 14 (which would hit the maximum number of TeX input streams—unless e-TeX supports more).

Finally, this is totally ridiculous. Don't use it. Use something meant for dealing with files instead.

-
I'm happy to take this as a definitive explanation of why we should use command-line tools when they're available. :) Thanks! –  Bill Tozier Jul 4 '11 at 14:53