jnboehm

My LaTeX Editing Setup

I recently finished my Bachelor's thesis, which I wrote in LaTeX. Since I quite liked the setup, I wanted to share it; hopefully it helps others. It mostly relies on standard utils and not much fancy stuff, which should make it easy to incorporate and adapt it as needed to one's own workflow.

Project structure

The structure of the project looks similar to this:

.
├── build/
├── figures/
├── latexmkrc
├── literature.bib
├── main.tex
├── pres.tex
├── readme.org
├── tables/
├── tex/
├── tikz/
└── vendor/
  • build/ This directory can be ignored, it will be automatically created in the build process and hold all relevant files, including the pdf.

  • figures/, tables/, tikz/ These directories hold files that will be used in the main document and most of the time wrapped in a figure or table environment.

  • latexmkrc This is the configuration file for latexmk. See the next chapter for a thorough explanation of its use.

  • literature.bib The bib file for the document. This is preferred over a global bib file so that the document can be compiled on other computers.

  • main.tex & pres.tex These are the files from which the main documents will be generated. The main file creates the thesis and the file pres.tex was used for the Bachelor defense.

  • readme.org An org-file to describe the project. These can be rendered by both Github and Gitlab and is my preferred markup format (in fact this post is also written in the org-mode format).

  • tex/ Holds the tex source code, which will be included from the tex files in the base directory.

  • vendor/ This is used to share files that are not included in the “usual” TeX distributions. As an example, my uni offers a beamer theme for presentations, which I used and put into this directory.

Components

I used the following programs:

  • latexmk

  • Emacs

  • pdf-tools (an Emacs package)

latexmk automates the compilation process of your document. It finds out how many times the compiler and bibtex needs to be run in order to resolve citations and references within your document. The program should already be installed on your system, it comes with the TeX Live distribution, which is most likely already installed if you use Linux for writing and compiling LaTeX. If not, consult the official page on how to get the program.

Emacs is the editor that I use. You can most likely install it in the way you would expect. If you do not want to use it, then you will need to make some changes to use this setup, although they should be fairly minor.

pdf-tools is a package that displays pdfs inside of Emacs and offeres a couple more features. In general it is an improvement over the default doc-view for displaying pdfs. The notable thing about it is the option to use synctex. The program can be substituted with any pdf viewer but this guide uses this one and some changes are necessary to switch to another one.

Emacs

You need to have Emacs running in server-mode and have the package pdf-tools installed. To accomplish both, type

M-x server-start
M-x package-install RET pdf-tools

The first statment will start a server that can be used to communicate with Emacs from the command line. The second one will install the required package. If you are visiting a pdf-file you can then do M-x pdf-view-mode to start the pdf viewer in Emacs, but you probably want that to be the default. By adding the following statement to your init file, you will automatcally use the new pdf viewer to display pdfs inside of Emacs.

(add-to-list 'auto-mode-alist '("\\.pdf\\'" . pdf-view-mode))

Because a function is used later, it needs to be defined in Emacs, consequently the following statment should be added to the init file as well. The function is mostly taken from this issue.

  (defun pdf-view-revert-buffer-maybe (file)
    (when-let ((buf (find-buffer-visiting file)))
      (with-current-buffer buf
        (when (derived-mode-p 'pdf-view-mode)
          (pdf-view-revert-buffer nil t)))))

If you use use-package, put the following into your init file instead, it automatically configures pdf-tools correctly for later use. The commented lines are needed if the program pdfinfo is not found and if you need more control over the synctex synchronization.

  (use-package pdf-tools
    :functions (pdf-view-revert-buffer-maybe pdf-view-revert-buffer)
    :mode ("\\.pdf\\'" . pdf-view-mode)
    :bind (:map pdf-view-mode-map
                ("TAB" . pdf-outline))
    ;; :config (setq pdf-info-epdfinfo-program (expand-file-name "pdf-tools/server/epdfinfo" borg-drone-directory)
    ;;               pdf-sync-backward-display-action '(display-buffer-use-some-frame))

    (add-hook 'pdf-view-mode-hook #'pdf-sync-minor-mode)
    (add-hook 'pdf-view-mode-hook #'pdf-links-minor-mode)

    (defun pdf-view-revert-buffer-maybe (file)
      (when-let ((buf (find-buffer-visiting file)))
        (with-current-buffer buf
          (when (derived-mode-p 'pdf-view-mode)
            (pdf-view-revert-buffer nil t))))))

latexmk

The compilation program is a bit involved and by using latexmk this can be entirely circumvented. By running it in continous mode (latexmk -pvc) it will not exit after the compilation but instead wait for more changes to any of the source files. In addition to continously watching and compiling the files, it will also update the pdf viewer. Initially, the value of $pdf_previewer is used to start the pdf viewer. The variable $pdf_update_command controls the behavior of telling the pdf viewer that a new pdf file exists. Here the fact that emacs is used for displaying the pdf can be used and we use the custom defined function to update the pdf.

$pdf_mode = 1;
@default_files = ('main.tex');
$pdf_previewer="emacsclient -e '(find-file-other-window %S)'";
# TEXINPUTS is set, more info: http://www.tex.ac.uk/FAQ-graphicspath.html
$pdflatex='TEXINPUTS=tex:tikz:tables:figures:vendor:: texfot --quiet lualatex %O -synctex=1 -interaction=nonstopmode -file-line-error %S';
$pdf_update_method = 4;
# Custom update function that needs to be defined inside of emacs
$pdf_update_command = "emacsclient -e '(pdf-view-revert-buffer-maybe %S)'";
$out_dir = "build";
$aux_dir = "build";
# because the bibtex rule is exec'd in $aux_dir, the path needs to be
# corrected to find .bst files in vendor/
$bibtex = 'BSTINPUTS=../vendor:: bibtex %O %B';

Because I did not want to specify the prefix of the directory when I want to include a file, I have set the variable $TEXINPUTS in the command $pdflatex. This prompts the latex compiler to search for files in the specified directories, along with the standard ones.

The program texfot that is called instead of lualatex filters unncecessary output and reduces the amount of information that is printed to the console.

Using the setup

Now the only thing left is starting to write the document and compiling it. To do this I open a tex file of the project in Emacs and navigate to the project directory in a normal terminal. Afterwards I type (in the directory where the file latexmkrc is)

latexmk -pvc

This will compile the file main.tex and start the pdf viewer. Then, after making changes to any of the files that are needed to generate the document will result in another compilation and an update to the displayed pdf.

To do the same for the presentation it suffices to simply specify its name on the command line, i. e.

latexmk -pvc pres.tex

And that's it. It works quite well for my needs and I am happy with the setup. Hope it helps!


Last modified:

Tags: latex emacs