Closed vanabel closed 6 years ago
I am not sure that \include
does what you think it does.
LaTeX takes a set of inputs and generates a single (main) output file. Packages like beamerswitch
cheat by using shell-escape to run LaTeX recursively, so you think you are running it once but are actually (for instance) running it four times to generate four PDFs.
\include
and \input
behave slightly differently, but in essence what they do is insert the content of the named file into the current one so it is as if you had written them in the main file. (\include
does some extra things as well as explained by this answer on TeX.se.) They do not generate additional output PDFs.
The packages subfile
and standalone
, as you have discovered, allow you some extra flexibility, so you can insert multiple standalone documents into a single 'master' document. The idea is that you either run LaTeX on main.tex
to get all the chapters in one main.pdf
, or run LaTeX individually on each chapter to get one PDF per chapter. If this is more flexibility than you need, and you only want to get single chapter PDFs, then you need to change tactic.
Instead of trying to include your chapters in your main file, you need to insert a common preamble into each of your chapters.
%preamble.tex
\PassOptionsToClass{a4paper,12pt}{article}
\PassOptionsToClass{14pt}{beamer}
\documentclass[alsoarticle]{beamerswitch}
\handoutlayout{nup=3plus,border=1pt}
\articlelayout{maketitle,frametitles=none}
\usepackage[british]{babel}
\mode<article>{
\usepackage[hmargin=3cm,vmargin=2.5cm]{geometry}
}
\mode<presentation>{
\usefonttheme{professionalfonts}
}
\mode<handout>{
\usecolortheme{dove}
}
\usepackage{libertine}
\title{A demonstration of the \textsf{beamerswitch} class}
\author{Alex Ball}
\institute{University of Life}
\date{1 September 2016}
\subject{A LaTeX class}
\keywords{CTAN, literate programming}
%chapter1.tex
\input{preamble.tex}
\subtitle{Chapter 1}
\begin{document}
\begin{frame}
\maketitle
\end{frame}
\end{document}
%chapter2.tex
\input{preamble.tex}
\subtitle{Chapter 2}
\begin{document}
\begin{frame}
\maketitle
\end{frame}
\end{document}
Now for the magic. You want to compile all of these in one shot. One of the nice features of latexmk
is that if you don't specify a filename it will compile all the .tex
files in the current working directory for you. This is slightly more than you want, so you need to create a directory-specific .latexmkrc
file to protect the .tex
files you don't want to compile directly:
# .latexmkrc
@default_excluded_files = ( 'preamble.tex' );
So to compile all your chapters at once, run the following and go make yourself a hot beverage of your choice while it completes:
latexmk -pdfxe -shell-escape
I hope that helps.
Thanks for your detailed response. Here is my write18
answer of my original question, which almost output the same results as your posted answer. But fails when I use it with the class beamerswitch
:
My main.tex
%main.tex
\documentclass{article}
\gdef\chaplist{sec1,sec2}
\makeatletter
\@for\fname:=\chaplist\do{
\immediate\write18{%
pdflatex -jobname="\jobname-\fname"
\gdef\string\notinmain{1}
\noexpand\AtBeginDocument{\noexpand\input{\fname}}
\string\input\space\jobname%
}
}
\makeatother
\title{Compile each section based on the master file}
\author{Van Abel}
\date{\today}
\begin{document}
\ifx\notinmain\undefined
\maketitle
\tableofcontents
The value of \texttt{\string\notinmain} in \texttt{\jobname} is: \texttt{\meaning\notinmain}
\makeatletter
\@for\fname:=\chaplist\do{
\include{\fname}
}
\makeatother
\fi
\end{document}
and
%sec1.tex
\section{The titile of section 1}
The value of \texttt{\string\notinmain} in \texttt{\jobname} is:\texttt{\meaning\notinmain}
%sec2.tex
\ifdefined\notinmain
\ifnum\notinmain=1
\addtocounter{section}{1}
\fi
\fi
\section{The titile of section 2}
The value of \texttt{\string\notinmain} in \texttt{\jobname} is: \texttt{\meaning\notinmain}
then with a single xelatex --shell-escape main
, we will get three files main.pdf
, main-sec1.pdf
, main-sec2.pdf
. Moreover, main.pdf
contains all the sections and main-sec1/2
contains only the specified section.
What are you trying to achieve here? And is this the best way to go about it?
If you want to have whole_course.pdf
, chapter1.pdf
, chapter2.pdf
in multiple forms, then probably what you want to do is adapt my answer above. Move the maketitle commands to the preamble file:
% preamble.tex
...
\usepackage{etoolbox}
\AfterEndPreamble{
\begin{frame}
\maketitle
\end{frame}
}
...
...so that you only get the course content in the {document}
environment in your chapter files. Your whole course document would then look something like this (the standalone
package strips out the preamble in the input files and transforms the inner {document}
environment into a simple group):
% whole_course.tex
\input{preamble}
\usepackage{standalone}
\renewcommand{\PassOptionsToClass}[2]{}
\begin{document}
% code for your sectional title slide for chapter 1, then...
\mode<all>{\input{chapter1.tex}}
% code for your sectional title slide for chapter 2, then...
\mode<all>{\input{chapter2.tex}}
\end{document}
Or you could simply concatenate your PDF files with a tool like pdfjam
, pdftk
or .tex files that use pdfpages
(named so they get compiled after your chapters).
But purely as an intellectual exercise, let's have a look at your latest solution. On my system your code fails with the following when initiated from XeLaTeX or PDFLaTeX:
! I can't find file `gdef'.
This is because your backslashes are not properly escaped; you should be using \string\\
. Also, recent versions of LuaLaTeX do not support \write18
for running system commands. You should be using the shellesc
package instead.
So assuming you fix your code:
\usepackage{shellesc}
\makeatletter
\@for\fname:=\chaplist\do{
\ShellEscape{%
pdflatex -jobname="\jobname-\fname"
\string\\gdef\string\\notinmain{1}
\string\\AtBeginDocument{\string\\input{\fname}}
\string\\input{\jobname}%
}
}
\makeatother
and replace \documentclass{article}
with documentclass[article]{beamerswitch}
everything works as you intend.
Now, if you then try and use the beamerswitch
features you will find yourself running into all sort of complications.
If you want multiple versions of the chapter files, then you will need to run pdflatex
over them with shell-escape enabled, which means they will also run the above spawning process themselves (trying to compile main-sec1-sec1.pdf
and inputting main-sec1.tex
) unless you do something to stop that happening. (Another \ifx
wrapper should do it.)
But of course when your main-sec1
job runs, beamerswitch
will try to run pdflatex
over main-sec1.tex
(which doesn't exist) with jobname main-sec1-slides
. So when running these jobs, you will need to redefine \BeamerswitchSpawn
to run the spawned processes over main
instead of the actual jobname. It would probably be easiest (but inelegant) to hard-code this in your main.tex
file.
In order for the \ifx
switch to work in the main body of your file, you will need to add a \mode<all>
line at the beginning to switch off the ignorenonframetext
behaviour in the beamer modes. But then you lose half the benefit of using beamerswitch
to generate PDFs in article mode.
Also remember that if you are doing fiddly things with your code in a {frame}
environment you may need the [fragile]
slide option.
Is it really worth all this hassle when much simpler options are available to you?
This seems kind of off-topic, but I hope you can help me work this out (and may view this as a feature request if you think it is proper).
In case I have to prepare a calculus course, I would like to get
beamer
andarticle
at the same time for each chapter. So the best way is to write amain
file first, and theninclude
each chapter file in the main file. The problem is I can't get them compiled separately when I compile the main file.For example, the main file given as
with
and
As you can see, I expect that when I compile
main.tex
, I will get four separated pdf files:chapter1.pdf
,chapter2.pdf
andchapter1-article.pdf
,chapter2-article.pdf
.I try to search
\write18
but I don't know how to make it work. Also, I observed that there is a package namedsubfiles
which almost work as expected, but there are two main problem:beamerswitch
;chapter1.tex
andchapter2.tex
separately to getchapter1.pdf
andchapter2.pdf
.A working MME of
subfile
is given as following:and