Werden wir Helden für einen Tag

Home | About | Archive

Advent of emacs #14: How I do academic writing in emacs

Posted on Dec 14, 2022 by Chung-hong Chan

Manuscript writing is really the thing that I (should) do to bring bread and butter on the table. An end. Programming is just a means to an end. I again promise you that I will talk about this topic (means vs end) in detail in a later post in this series.

As I said in another blog post, I can only write some papers in emacs. Manuscript writing should be a team sport and one can’t force your teammates to use a specific writing apparatus. My language context likes to abuse the mathematical concept of “Highest Common Factor” (HCF) and apply it in this kind of situations. An academic writing team needs to find out the HCF that all members can comfortably collaborate. And formats such as \(\LaTeX\), rmarkdown, quarto are automatically out. Notice the obvious missing format: I don’t even need to mention it. The current HCFs in mainstream social sciences are either sending around Microsoft Word files through e-mail, MS Office 365, or Google Docs 1.

Some of you may know, I recently have a new job and my new coworkers are more techy. I am kind-of happy that the HCF changes (for the better). At least someone explicitly told me he/she hates Microsoft Word. Good sign! And I have actually written some papers already with my new coworkers in rmarkdown! Yay!

Today, I am going to talk about markdown. In a later post, I will talk about \(\LaTeX\) and the craziness associated with it.

(R)mardown and quarto

I really like markdown. John Gruber and Aaron Schwarz (†) created a really nice markup language that feels so nice to write and nice to look at. Github Flavored Markdown (GFM) and Pandoc’s Markdown, two of the many further improvements, have almost no quirks. This blog post is also written in GFM (and gets parsed by Kramdown, and processed by Jekyll).

RMarkdown and Quarto are based on pandoc and thus Pandoc’s Markdown is used. You might probably know, one can mix markdown with R (RMarkdown) / R, Python, Julia, or whatnot (Quarto); render the markdown to the formats we usually want, e.g. PDF or MS Word; and sell the PDF or MS Word for bread and butter and bring them on the table.

RMarkdown and Quarto are developed and promoted by RStudio Posit. There’s no wonder the support for the two formats is the best on RStudio the IDE. But I would argue that the support for the two formats is at least the second best on emacs. (Well, if one is used to emacs, it is the best.) It is because of the wonderful architecture of polymode. polymode is for editing code in more than one language. Applying the emacs lingo, polymode allows two different major modes to run simultaneously in one buffer. You might ask: Why? Well. It is now extremely common to edit a file with more than one language. The Ruby world has Embedded Ruby Template (erb) and liquid; The Python world has Jinja. PHP can be embeded in HTML.

The R World is insane in this regard: We have RMarkdown/Quarto (Markdown and R), sweave (\(\LaTeX\) and R), Rcpp (C++ and R), and also the “R Documentation” (Rd and R). When one uses RMarkdown/Quarto to write academic papers, it is actually quite common also to mix \(\LaTeX\) in it (so 3 languages). R programmers are usually polyglots. And for polyglots, polymode is the natural choice. This is a demo of adding an R code block in a markdown document.

Editing the embedded code block has all the ESS goodness. In the above demo, I used a yasnippet (day 9) to quickly insert an R Code block. Evaluate the code immediately using my C-q setup (Okay! Okay! I will talk about it).

And my setup is pretty standard.

(use-package poly-markdown)
(use-package poly-R
  (add-to-list 'auto-mode-alist '("\\.rmd" . poly-markdown+r-mode))
(use-package quarto-mode)

quarto-mode is built on top of polymode with some extra commands such as quarto-preview.


One minor nuissance about the polymode is the command polymode-weave. In case you still remember from day 3, weaving is to extract all the content of a file in the documentation language. I usually just associate it with rendering (producing either the PDF or Word file). The command polymode-weave can get the job done. But I don’t like it for asking too many questions. I like RStudio’s no-BS “knit” button. So I have this:

(defvar knit-preview nil "Whether or not to open the pdf file")
(add-to-list 'display-buffer-alist '("*Async Shell Command*" display-buffer-no-window (nil)))

(defun knit ()
  (message "Rendering...")
  (if knit-preview
	  (fset 'current-shell-command 'shell-command)
    (fset 'current-shell-command 'async-shell-command))
  (if (string= (file-name-extension buffer-file-name) "qmd")
	  (current-shell-command (concat "Rscript -e \"quarto::quarto_render('" buffer-file-name "', output_format = 'all', quiet = TRUE)\""))
    (current-shell-command (concat "Rscript -e \"rmarkdown::render('" buffer-file-name "', output_format = 'all', quiet = TRUE)\"")))
  (setq-local pdf-file-name (replace-regexp-in-string " " "-" (concat (file-name-sans-extension buffer-file-name) ".pdf")))
  (if (and knit-preview (file-exists-p pdf-file-name))
	  (find-file pdf-file-name)))

And I have something equivalent of pressing the “knit” button (M-x knit). In the following demo, I set the variable knit-preview to t.

You might notice that the document in this demo is academic writing (A referee report for a journal article). And we will go back to the topic of bibliography in tomorrow’s post.


  1. It is also important to note that in Europe, some countries (e.g. France and Denmark) ban MS Office 365 and Google Docs for education due to insufficient data privacy protection by the US big tech companies. In Germany, only the state of Hessen bans Office 365 in schools. I actually agree with that. But I still need to bring bread and butter on the table. And I need to use both. 

Powered by Jekyll and profdr theme