10

In my paper I have several tex files, mainly produced by some other tools (.bbl by bibtex, .eps_tex by inkscape etc.).

I would like to combine them into a single tex file as required by my publisher.

If possible, I'd like to automate it, so that even if any of my references of figures changes I still have an up-to-date version of the manuscript.

Is it possible to do that in LaTeX, or are there any third-party tools for that?

13
  • This should be doable. Have a look at this question on input vs include. If you have a more specific question please provide a MWE as described here of what you have tried so far. Aug 15, 2011 at 4:57
  • 5
    ...or, perhaps this one: Replace \input{fileX} by the content of fileX automatically.
    – Werner
    Aug 15, 2011 at 5:01
  • @Werner: That link have a problem in that if the file underlying file changed, the .tex file would have to be regenerated. I think it is much better to just refer to the actual files rather than copying their content into some other file. Aug 15, 2011 at 5:08
  • @Peter: The OP requested "to combine them into a single .tex file" which makes me think the he wants to strip all \input, \include references, hence the suggestion.
    – Werner
    Aug 15, 2011 at 5:11
  • @Werner: You have a point there. But it was also mentioned to always have an up-to-date version, so I am not sure exactly what is desired. Aug 15, 2011 at 5:14

3 Answers 3

8

If you need to have your bibliography in the same file as your main text, you can use the filecontents environment:

\begin{filecontents}{bibliography.bbl}
% <contents of bibliography.bbl>
\end{filecontents}
\documentclass{article} % or whatever
\begin{document}
...

When you run latex on this file, it will write a bibliography.bbl file to the same folder as the tex file is in. Note the filecontents environment comes before the document class.

In this way, you need only send one file to the publisher.

As for images, I would check the publisher requirements vis-à-vis pictures: they might require them in a particular format, but I doubt they want them all embedded in the actual file...

the filecontents package allows for more flexible use of filecontents environments.

5
  • 1
    See also tex.stackexchange.com/questions/20317/…
    – N.N.
    Aug 15, 2011 at 13:05
  • This snippet, if I understand it correctly, does the opposite thing to what I need - it creates a separate file out of the filecontents environment. Nevertheless, this is an interesting trick I'll probably use in the future. As for embedding images - .eps files should be kept separate indeed. It's only .eps_tex ones, which have to be embedded in the manuscript as they contain actual TeX wrapper code (using figure environment). The code includes the .eps file and adds text labels to it. I like this method as it allows me to use TeX code inside figures.
    – Andrzej
    Aug 15, 2011 at 13:13
  • 1
    @Andrzej You will have only one file to send to the publisher. When they run latex on it, it will create all the files necessary to compile your document. So no: it does what you want. It combines all your files into one document...
    – Seamus
    Aug 15, 2011 at 13:36
  • @Seamus, I still think that's the other way around. My question was "how do I get a single file out of many" not "how do I split my file into parts at runtime". bibliography.bbl is an autogenerated file and I want it to stay like this until the very last moment, when I have to merge everything into one file and push it to the publisher. Also, once merged, there is no need to split the file again - LaTeX will compile the merged file just fine, only the autogenerated contents will be "frozen".
    – Andrzej
    Aug 15, 2011 at 17:51
  • @Andrzej then I don't understand your question. What do you want your single file to look like? You want to include the contents of the autogenerated files in a single file? This is exactly what this does. If the question is "How do I automatically get the contents of the various files copied into a single file?" then you should make that clearer.
    – Seamus
    Aug 16, 2011 at 10:49
6

@Werner recommended using one of preprocessors for merging the files. I tried a latexexpand perl script and this is what I found:

  1. It works fine for plain \input macros. It requires them to located in their own lines, as the whole line with \input will be removed.
  2. It does not support more complex use cases. For example it will not expand bibtex bibliographies.

I've modified the script so that it does the (2). There is no guarantee it will work with anything other than my document, though:

#!/usr/bin/perl
# - latexpand   D. Musliner University of Michigan
# Short program to expand out LaTeX \input and \include commands.
# Essentially a tiny part of 'go' hacked out.
# Removes comments as a side effect, does not deal with escaped %s.
#
# 15 Sept 1999  M. Lovell       Hewlett-Packard, Co
# Improved comment removal code.  Now handles escaped %'s.
#
#
$TEXINPUTS = $ENV{'TEXINPUTS'};
if (!$TEXINPUTS) { $TEXINPUTS = '.'; }

&scan_for_includes(shift);

#************************************************************
# - looks recursively for included & inputted files, expands.
# - note only primitive comment removal: cannot deal with escaped %s.

sub scan_for_includes
{
  local(*FILE); if (!open(FILE,$_[0]))
    { warn "WARNING: could not open input file [$_[0]]\n"; return; }
  while(<FILE>)
    {
    # comment removal
    s/^%.*\n//;
    s/([^\\])%.*\n/$1/;

    if (/\\include[{\s]+([^\001}]*)[\s}]/)
      {
        $full_filename = $1;
        if ($1 =~ m/\./)
          { $full_filename = &find_file($full_filename,$TEXINPUTS); }
        else
          { $full_filename = &find_file("$full_filename.tex",$TEXINPUTS); }
        warn "  Found include for file [$full_filename]\n";
        &scan_for_includes($full_filename);
      }
    elsif (/\\input[{\s]+([^\001}]*)[\s}]/)
      {
        $full_filename = $1;
        if ($1 =~ m/\./)
          { $full_filename = &find_file($full_filename,$TEXINPUTS); }
        else
          { $full_filename = &find_file("$full_filename.tex",$TEXINPUTS); }
        warn "  Found input for file [$full_filename]\n";
        &scan_for_includes($full_filename);
      }
    elsif (/\\bibliographystyle/) {}
    elsif (/\\bibliography/) {
        $bibfname = $_[0];
        $bibfname =~ s/.tex$//;
        $bibfname = "${bibfname}.bbl";
        &scan_for_includes($bibfname);
    }
    else { print; }
    }
}

#************************************************************
# given filename and path, return full name of file, or die if none found.

sub find_file
{
  foreach $dir (split(':',$_[1]))
    { if (-e "$dir/$_[0]") { return("$dir/$_[0]"); } }
  die "ERROR: Could not find file [$_[0]] in path [$_[1]]\n";
}

For the sake of completeness this is my Makefile:

TEX = latex
INKSCAPE = inkscape
documentfile = manuscript_work
finalfile = manuscript
referencefile = bibliography
figures =   \
        figures/fig1.eps \
        figures/fig2.eps \


figures_tex = $(addsuffix .eps_tex,$(basename $(figures)))

all: document

document: $(finalfile).pdf

$(finalfile).pdf: $(finalfile).ps
    ps2pdf $(finalfile).ps

$(finalfile).ps: $(finalfile).dvi
    dvips $(finalfile).dvi

$(finalfile).dvi: $(finalfile).tex
    while ($(TEX) $(finalfile) ; \
        grep -q "Rerun to get cross" $(finalfile).log ) do true ; \
    done

$(finalfile).tex: $(documentfile).tex $(figures) $(figures_tex) $(documentfile).bbl
    ./latexexpand $(documentfile).tex > $(finalfile).tex #use modified latexexpand script

figures/%.eps: figures/%.svg
    $(INKSCAPE) $< -z -C --export-eps=$@ --export-latex

$(documentfile).bbl: $(referencefile).bib
    $(TEX) $(documentfile)
    bibtex $(documentfile)
3
  • This one looks really promising. Maybe put it somewhere public so that it can be version control and improved on?
    – recluze
    Jan 19, 2012 at 2:24
  • I've only made minor changes, targeted specifically into my workflow (latex+bibtex). I'd be happy if these modified fixes were added into the latexexpand script but then for tools of this size this place isn't bad at all.
    – Andrzej
    Feb 24, 2012 at 3:17
  • This post seems to refer to an old version of latexpand. latexpand now does all this and more. (disclaimer: I'm the author) May 27, 2015 at 19:46
4

This is precisely the use-case for which latexpand was written. It should be able to do all this for you (if not, please report a bug).

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .