# How to automatically inline \input commands and bibliography?

I have a document that uses some \input commands and creates the bibliography via an external .bib file and bibtex.

Now I have to inline the \input commands (i.e. replace each \input command with the content of the corresponding file) and inline the bibliography (i.e. replace the bibliography command with the .tex code which is generated by bibtex). The inlining is required by the editor.

How can I do this automatically?

-

Before your \documentclass, add this:

\begin{filecontents}{file1}
Contents of file 1
\end{filecontents}

\begin{filecontents}{file2}
Contents of file 2
\end{filecontents}


And so on. No need to replace the \inputs

-
On a second read of the question, what you want to do is put mainfile.bbl in a filecontents environment before your documentclass call. – Seamus Feb 7 '11 at 21:33
Good outside-the-box-answer! ATM I find that this is a relatively elegant solution to the problem. I wrote a small shell script to automatically creates these environments for a document - I posted it as another answer. – maxschlepzig Feb 10 '11 at 20:44

rename the generated file.bbl to mybib.bbl and then replace your \bibliography command with \input{mybib.bbl}. If you are sure, that you won't run the bibtex program again, than simply replace it with \input{file.bbl}.

http://texnik.dante.de/misc/buildFile.pl is a Perl skript which creates one stand alone file. All \input and \include will be replaced by their contents

-
Ok, this answers the second part. At the end I want to automatically replace the \input commands as well. – maxschlepzig Feb 7 '11 at 21:04
@maxschlepzig: http://texnik.dante.de/misc/buildFile.pl is a Perl skript which creates one stand alone file. All \input and \include will be replaced by their contents – Herbert Feb 7 '11 at 21:33

Similar questions arise from time to time of (essentially) getting TeX to output a .tex file. The most practical way I found so far is to make all characters active (or variants that essentially amount to the same thing), and define them to store themselves to a buffer, which is then output to a file.

Then, the commands for which we wish to do more than just copy verbatim are redefined to do what we want (see the definition of \RLK@input below). There are subtelties, of course (only letters can appear in control sequence names, and not active characters).

Change InFile.tex to the file you want to "inline", and OutFile.tex to the output.

\def\RLKinputfile{InFile.tex}
\def\RLKoutputfile{OutFile.tex}

\catcode\@=11\relax

\long\gdef\RLKgobble#1{}
\long\gdef\RLKfirstoftwo#1#2{#1}
\long\gdef\RLKsecondoftwo#1#2{#2}

\gdef\RLK{%
\begingroup%
\count0=1\relax%
\loop%
\catcode\count0=\active%
\lccode~\count0\relax%
\lowercase{\protected\edef~{\RLKbuffer@append{\string~}}}%
\ifnum\count0<255%
\repeat%
\lccode\~\\%
\lowercase{\let~\RLKcatchcs}%
%
\input \RLKinputfile %
\endgroup%
}

\gdef\RLKbuffer{}
\protected\def\RLKbuffer@append#1{\xdef\RLKbuffer{\RLKbuffer#1}}

\newif\if@catchcs@
\protected\def\RLKcatchcs{%
% catches the control word, naively stopping at the first non A-Za-z
\def\RLKcatchcs@csname{}%
\RLKcatchcs@aux}
\def\RLKcatchcs@aux#1{%
\@catchcs@false% We have reached the end...
\unless\ifnum#1>z\relax%
\unless\ifnum#1<A\relax%
\@catchcs@true% ...except if we are in the range A-z...
\fi\fi%
\ifnum#1>Z\relax%
\ifnum#1<a\relax%
\@catchcs@false% ...and not in the range Z-a.
\fi\fi%
\if@catchcs@%
\expandafter\RLKfirstoftwo%
\else%
\expandafter\RLKsecondoftwo%
\fi%
% If we haven't reached the end, catch one more.
{\edef\RLKcatchcs@csname{\RLKcatchcs@csname\string#1}%
\RLKcatchcs@aux}%
% If we have, stop, do the relevant \RLK@... if it exists, otherwise
% just output to the buffer. And don't forget to put #1 back in the stream.
{\ifcsname RLK@\RLKcatchcs@csname\endcsname%
\csname RLK@\RLKcatchcs@csname\expandafter\endcsname%
\else%
\RLKbuffer@append{\expandafter\RLKgobble\string\\\RLKcatchcs@csname}%
\fi%
#1%
}%
}

% Define \input{...} to have the desired behaviour: actually input the file.
% We could do the same for other commands (\usepackage, etc.)
\begingroup
\catcode\{=\active
\catcode\}=\active
\catcode$$=1\relax \catcode$$=2\relax
\gdef\RLK@input{#1}(\RLKaux@input(#1))
\endgroup
\gdef\RLKaux@input#1{\expandafter\input \detokenize{#1} }

% Here it goes, we act.
\RLK

% Then output the \RLKbuffer to a file.
\newwrite\RLKwrite
\immediate\openout\RLKwrite \RLKoutputfile\relax
\newlinechar\endlinechar
\immediate\write\RLKwrite{\RLKbuffer}
\immediate\closeout\RLKwrite

% tex, pdftex will be stopped there,
% but latex, pdflatex will only see \relax.
\csname bye\endcsname

% this makes latex, pdflatex happy.
\documentclass{minimal}
\begin{document}
\end{document}


This should work with tex, latex, pdftex and pdflatex, and it shouldn't be hard to extend to other variants. Also, before people ask, RLK is just a random string of letters.

-

Using Seamus hints I wrote a small shell scripts that automatically inserts the necessary filecontents environments:

(for simplicity, it is assumed that all filenames don't contain any whitespace and that all input statements start at the fist column)

#!/bin/sh

set -e
set -u

SED=sed
TEXFILE=main.tex
BBL=main.bbl
BIB=biblio
OUTPUT=final/inlined.tex

rm -rf inl2.tmp inl.tmp final
mkdir final

$SED 's@\\bibliography{'$BIB'}@\\input{'$BBL'}@'$TEXFILE > inl.tmp

for i in grep '^\\\\input' inl.tmp | $SED 's/^[^{]\+{$$[^}]\+$$}.*$/\1/'; do
if echo $i | grep '\.' > /dev/null ; then file=$i
else
file=$i.tex fi echo$file
echo >> inl2.tmp
printf '\\begin{filecontents}{'$i'}' >> inl2.tmp echo >> inl2.tmp cat$file >> inl2.tmp
printf '\\end{filecontents}' >> inl2.tmp
echo >> inl2.tmp
echo >> inl2.tmp
done

cat inl2.tmp inl.tmp > \$OUTPUT

-

Thinking outside the box for a moment, I'd be tempted to do something like use a text editor (or a sed script) to change the \input directives to a suitable #include and then pass the result through the C Preprocessor.

It would also be straight-forward to implement the effect of \input with a Perl script.

I'm sure it is possible to do this in pure TeX, but the purity may not be worth the effort if there isn't an existing mechanism to ask TeX to dump the token stream back to a file at the right moment in its process.

Note that regardless of implementation choice, I would make sure that I didn't accidentally destroy the original document with this replacement.

-
Yeah, the plan is to call the solution via a Makefile an create the inline version as a new file. – maxschlepzig Feb 7 '11 at 21:47