4

Edit: I think this question is sufficiently distinct from this question because I am specifically asking for a method within TeX itself, i.e. not running some Perl script separately to do this, but instead having it happen automatically via some TeX magic whenever I compile the source.

Edit 2: To give some motivation for this question, I have always used \embedfile{jobname.tex} in my preamble to embed the source code into the PDF, but this doesn't work when you use \includes or \inputs. There is \usepackage{embedall} (and then \embedinput), but this means that your source files are embedded individually. I assumed that, in compiling and making a PDF, TeX at some point generates a single .tex file with all the \includes and \inputs expanded, and I was hoping to be able to use \embedfile to embed this single file into the PDF.

I can't seem to find an answer to this question anywhere, so sorry if it's been asked before.

Assume I have some main.tex file with the preamble, etc., and all my chapters are in some chapters directory, and I use \input{chapter1} in main.tex. Is there then a way to 'compile' this structure into one single .tex file, i.e. with each \input actually expanded and replaced with the contents of chapters/chapter1.tex, chapters/chapter2.tex, etc.?

I'm sure this wouldn't be too much of a faff to do with some bash script, but I was hoping that there was some (La)TeX way of doing this — maybe some such file is produced in the compilation process?


main.tex

[preamble]

\input{chapters/chapter1.tex}

\input{chapters/chapter2.tex}

...

chapters/chapter1.tex

\chapter{First chapter}

Lorem ipsum

chapters/chapter2.tex

\chapter{Second chapter}

Dolor sit amet

should become

main_single.tex

[preamble]

\chapter{First chapter}

Lorem ipsum

\chapter{Second chapter}

Dolor sit amet

...

  • 1
    So you don't want to use \input or \include but just copy the contents of each chapter into a new main input file. – Gold Digging Programmer Feb 10 at 16:44
  • 3
    Possible duplicate of Replace \input{fileX} by the content of fileX automatically – naphaneal Feb 10 at 16:48
  • 1
    @naphaneal that question is very similar, but I think it's different because I'm asking for a way to do this within the TeX document itself, using TeX, rather than running some Perl script separately – Tim Feb 10 at 16:51
  • 1
    No such a file is not created by the compilation process (and btw: \include does more than simply include the code, it also issues a \clearpage), so you would have to write code which writes such a file. – Ulrike Fischer Feb 10 at 17:01
  • 2
    tex never generates a combined file, in fact it never usually has more than a page of the source file in memory. early pages are typeset before the source for later ages have even been read from disk, even if the file is in a single source. – David Carlisle Feb 10 at 18:45
1

E.g., when it comes to conditional inputting/including of files, I see problems with the approach of automatic building of a single file from the source-files.

Also be aware that if with some of the contents of the pdf-file randomness created by the sources plays a rôle, embedding the sources alone might not provide all means needed for re-creating the pdf-file with exactly the same look.

The source may contain directives like:

   If at the time of encountering the directive it is morning, include goodmorning.tex.
   If at the time of encountering the directive it is afternoon, include goodafternoon.tex.
   If at the time of encountering the directive it is night, include goodnight.tex.

Or within the source, the pgf-package may have been loaded for generating and displaying random numbers.

The source may contain directives for displaying the system-date and time that was current at the moment when compilation was started. (This will be different when compiling at another time.)

The source may contain directives for delivering a random mix of exercises from a pool of exercises.

...

Be that as it may.

I suggest going the other direction:

Combine your main.tex and your input-files "by hand" within a single source-file from which the single input-files can be regained (semi-)automatically by means of the docstrip package. (The docstrip package is part of standard LaTeX installations.)

The docstrip package is a means for deriving different .tex-input-files from one (set of) master-file(s):
Within the master-file(s) you can place so-called tags. These tags are used for determining the content of the derived files as the tagged portions of text from the master-files will be copied to the derived files.

E.g., within the head of the main master-file you can call docstrip and have so-called \generate-directives for creating those files that are to be derived from the master-files.

More info about docstrip can be found at CTAN: https://ctan.org/pkg/docstrip

If you save the following example as a file with a name both other than main.tex and other than chapter1.tex and other than chapter2.tex and compile it by calling
tex ⟨file name⟩ or
pdftex ⟨file name⟩ or
latex ⟨file name⟩ or
pdflatex ⟨file name⟩
from the command-line/from the shell after (via the cd-command or the chdir-command or whatever) changing the working directory to the directory where you have saved that file, you will be asked to create the sub-directory "chapters".
When you have done this, then three new files will be created:
The file main.tex is in the current directory.
The files chapter1.tex and chapter2.tex will be in the sub-directory chapters.

%<*ignore>
% Section with docstrip directives for generating different 
% .tex-input-files:
\input docstrip
% Patch docstrip's \makeOther so that it also makes horizontal
% tab-char other (code-point 9 in ASCII and UTF 8)
% when making space-char other - if you don't apply this patch,
% docstrip will kill horizontal tabs at the beginnings of lines
% and will turn horizontal-tabs within lines into spaces:
\def\makeOther#1{%
  \ifnum`\ =`#1 \catcode9=12\relax\fi
  \catcode`#1=12\relax
}%
%
\nopreamble
\nopostamble
\askforoverwritetrue
\begingroup
\obeyspaces
\message{%
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!^^J%
!! Attention 1:                                            !!^^J%
!! ------------                                            !!^^J%
!! Make sure to have changed the working directory to the  !!^^J%
!! directory where the file that is currently compiled is  !!^^J%
!! stored.                                                 !!^^J%
!! ------------------------------------------------------- !!^^J%
!! Attention 2:                                            !!^^J%
!! ------------                                            !!^^J%
!! Make sure you have created the sub-directory "chapters" !!^^J%
!! within the directory where the file that is currently   !!^^J%
!! compiled is stored.                                     !!^^J%
!! You need to do this by hand as TeX won't do it for you. !!^^J%
!! If that sub-directory does not yet exist, you can do it !!^^J%
!! now.                                                    !!^^J%
!!                                                         !!^^J%
!! Press <return> after creating that sub-directory/when   !!^^J%
!! that sub-directory exists.                              !!^^J%
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!^^J%
}%
\endgroup
\immediate\read-1 to \mytempmacro
\generate{%
  \file{main.tex}{\from{\jobname.tex}{main}}%
  \file{./chapters/chapter1.tex}{\from{\jobname.tex}{chapter1}}%
  \file{./chapters/chapter2.tex}{\from{\jobname.tex}{chapter2}}%
}%
% Here you can probably insert \write18-calls suitable for your platform
% for calling pdflatex from console for compiling main.tex
%
%    \immediate\write18{pdflatex main.tex}
%    \immediate\write18{pdftexify main.tex}
%    \immediate\write18{latexmk -pdf main.tex}
%
\csname stop\endcsname % <- end this TeX-run in case you used (pdf)LaTeX
                       %    for generating the files.
\bye % <- end this TeX-run in case you used (pdf)TeX for generating the 
%    %    files.
%
%</ignore>
%
% In verbatim mode docstrip does not strip comments.
%
% Section containing main.tex
%
%<*main>
%<<This weird line does put DocStrip into and out of verbatim mode.
\documentclass{book}
% [preamble]
\begin{document}
\input{chapters/chapter1.tex}
\input{chapters/chapter2.tex}
\end{document}
%This weird line does put DocStrip into and out of verbatim mode.
%</main>
%
% Section containing chapter1.tex
%
%<*chapter1>
%<<This weird line does put DocStrip into and out of verbatim mode.
\chapter{First chapter}

Lorem ipsum
%This weird line does put DocStrip into and out of verbatim mode.
%</chapter1>
%
% Section containing chapter2.tex
%
%<*chapter2>
%<<This weird line does put DocStrip into and out of verbatim mode.
\chapter{Second chapter}

Dolor sit amet
%This weird line does put DocStrip into and out of verbatim mode.
%</chapter2>


If you absolutely don't like going the other direction:

If there is no nested inputting/including, i.e., if the structure is of a simple pattern where main.tex contains the preamble, the document-environment and a few \include-directives for including the files containing the single chapters (which in turn do not contain such \include/\input-directives), probably adding a few things to your files that under normal circumstances are taken for comments by LaTeX is sufficient for turning your set of files into something that can be combined within a single file by means of a little script that calls docstrip.

I.e., if you have the file main.tex

%<*BeforeChapterInput>
%<<This weird line does put DocStrip into and out of verbatim mode.
\documentclass{book}
% [preamble]
\begin{document}
%This weird line does put DocStrip into and out of verbatim mode.
%</BeforeChapterInput>
%<*ChapterInput>
\input{chapters/chapter1.tex}
\input{chapters/chapter2.tex}
%</ChapterInput>
%<*AfterChapterInput>
%<<This weird line does put DocStrip into and out of verbatim mode.
\end{document}
%This weird line does put DocStrip into and out of verbatim mode.
%</AfterChapterInput>

and within the sub-directory chapters the file chapter1.tex

%<<This weird line does put DocStrip into and out of verbatim mode.
\chapter{First chapter}

Lorem ipsum
%This weird line does put DocStrip into and out of verbatim mode.

and the file chapter2.tex

%<<This weird line does put DocStrip into and out of verbatim mode.
\chapter{Second chapter}

Dolor sit amet
%This weird line does put DocStrip into and out of verbatim mode.

, a file combined.tex can be created, which looks like this,

\documentclass{book}
% [preamble]
\begin{document}
\chapter{First chapter}

Lorem ipsum
\chapter{Second chapter}

Dolor sit amet
\end{document}

, by means of the following script - it must be stored in the same directory as main.tex and it needs to be compiled by calling
tex ⟨file name⟩ or
pdftex ⟨file name⟩ or
latex ⟨file name⟩ or
pdflatex ⟨file name⟩
from the command-line/from the shell after (via the cd-command or the chdir-command or whatever) changing the working directory to the directory where you have saved both main.tex and that script.

% Section with docstrip directives for generating different 
% .tex-input-files:
\input docstrip
% Patch docstrip's \makeOther so that it also makes horizontal
% tab-char other (code-point 9 in ASCII and UTF 8)
% when making space-char other - if you don't apply this patch,
% docstrip will kill horizontal tabs at the beginnings of lines
% and will turn horizontal-tabs within lines into spaces:
\def\makeOther#1{%
  \ifnum`\ =`#1 \catcode9=12\relax\fi
  \catcode`#1=12\relax
}%
%
\nopreamble
\nopostamble
\askforoverwritetrue
\begingroup
\obeyspaces
\message{%
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!^^J%
!! Attention 1:                                            !!^^J%
!! ------------                                            !!^^J%
!! Make sure to have changed the working directory to the  !!^^J%
!! directory where the file that is currently compiled is  !!^^J%
!! stored.                                                 !!^^J%
!! ------------------------------------------------------- !!^^J%
!! Attention 2:                                            !!^^J%
!! ------------                                            !!^^J%
!! Make sure the file main.tex is in the same directory as !!^^J%
!! the file that is currently compiled.                    !!^^J%
!! Also make sure that that directory has a subdirectory   !!^^J%
!! "chapters" where the files "chapter1.tex" and           !!^^J%
!! "chapter2.tex" can be found.                            !!^^J%
!!                                                         !!^^J%
!! Press <return> to continue.                             !!^^J%
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!^^J%
}%
\endgroup
\immediate\read-1 to \mytempmacro
\generate{%
  \file{combined.tex}{%
    \from{main.tex}{BeforeChapterInput}%
    \from{./chapters/chapter1.tex}{}%
    \from{./chapters/chapter2.tex}{}%
    \from{main.tex}{AfterChapterInput}%
  }%
}%
% Here you can probably insert \write18-calls suitable for your platform
% for calling pdflatex from console for compiling combined.tex
%
%    \immediate\write18{pdflatex combined.tex}
%    \immediate\write18{pdftexify combined.tex}
%    \immediate\write18{latexmk -pdf combined.tex}
%
\csname stop\endcsname % <- end this TeX-run in case you used (pdf)LaTeX
                       %    for generating the files.
\bye % <- end this TeX-run in case you used (pdf)TeX for generating the 
%    %    files.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.