Tag Archives: LaTeX

F*ck you LaTeX

Some of you know that I have agreed to finish the textbook started by my good friend David Lucy who died far too young in 2018. After some heroic efforts by our publisher Taylor and Francis, I now have a set of LaTeX files that match the last coherent PDF file that David gave our editor, Rob Calver, before he was unable to work any more.

I set about converting this rather large, monolithic file into my normal workflow of a master knitr file, with child files for each of the chapters. As you might expect, when writing a book you often want to compile the chapter you are working on, rather than the whole document. This is especially true with this book, because I would like the JAGS code to be executed whilst the chapter is being compiled, and with nearly twenty chapters, this could take some time.

Again, this process is fairly straightforward. However, when compiling a chapter, the paths have to be relative to the folder the chapter is in, rather than to the master document. This means that if you provide paths for figures, code listings, or the bibliography, then these need to be changed when you only want to compile the chapter, or when you want to compile the whole book. After a bit of reading, I thought I should be able to do this in LaTeX itself as it is a programming language (or at least a macro language) of sorts—boy was I wrong!.

The basic solution to the problem is as follows:

  1. Define a logical variable to indicate whether you are working with the whole book or just the chapter in the master document and set it to TRUE or FALSE as needed.
  2. In each child document, set the paths so that they are relative to the chapter, or the book according to the value of the logical variable.

LaTeX does not have a logical type, but it does have a numeric type in the form of a counter. So step one can be done using the following commands:

%%%%% Are you working with individual chapters
\newcounter{local}
\setcounter{local}{1} %1 = TRUE 0 = FALSE

Step two, in theory is straightforward as well. Here is an example from my first chapter. This goes in my preamble:

\ifnum\value{local}=0{
  \graphicspath{{chapters/chapter01/figures/}}
  \lstset{inputpath=chapters/chapter01/R/}
}
\else{
  \graphicspath{{figures/}} 
  \lstset{inputpath=R/}
}\fi

and this appears at the end of the chapter

\ifnum\value{local}=1{
  \bibliography{../../bibliography/jags-references}
}\fi

We have to make sure that the bibliography is included if the whole book is compiled, so this gets added to the position where we would like the bibliography to appear in the master document:

\ifnum\value{local}=0{
  \bibliography{bibliography/jags-references}
}\fi

Seems fine right? Does it work? No. It seems to half work. Sometimes it works for the chapter, sometimes for the book, but the switching is never seamless.

James, you are an idiot

So remember how I said I was working with knitr? The solution of course is to use a well-defined (N.B. I am not going to argue the merits of R being a real programming language or not, but it is one used by real programmers!) programming language—R—and get knitr to print out the right LaTeX code. It took a tiny bit of fooling about to remember how to do this, but the essence is R chunks with chunk options echo=FALSE and results='asis' to make sure knitr does not try to mark up our LaTeX. So these two chunks appear in my master document:

<<R-master-chunk,echo=FALSE>>=
### Set this to true if compiling chapters only
compileChapterOnly = FALSE
@

and

<<R-set-bibpath-master,echo=FALSE,results='asis'>>=
cat("\\bibliography{bibliography/jags-references.bib}\n")
@

with the latter placed where I need the bibliography to appear.

And these two chunks are placed in each child document:

<<R-set-local-paths-ch01,echo=FALSE,results='asis'>>=
if(compileChapterOnly){
  cat("\\graphicspath{{figures/}}
                     \\lstset{inputpath=R/}\n")
}else{
  cat("\\graphicspath{{chapters/chapter01/figures/}}
  \\lstset{inputpath=chapters/chapter01/R/}\n")
}
@

and

<<R-set-local-bibpath-ch01,echo=FALSE,results='asis'>>=
if(compileChapterOnly){
  cat("\\bibliography{../../bibliography/jags-references}\n")
}
@

Note that each chunk in the child document has a chapter specific chunk tag, just to avoid duplicate tags when I compile the whole book.

I am pretty sure someone will point out my elementary LaTeX mistake, but then again there is not enough space in my head for understanding how all of LaTeX works. After all, I do have to get this book written (and not write blog posts).

Share Button