You can read about my other Emacs configurations .


I recently bought Mastering Emacs (I’ll share my thoughts in a future post) and it is provided in both EPUB and PDF format.

Naturally I wanted to use Emacs to read the book, because:

  • I didn’t want to open yet-another tool (Calibre I love you, but your ebook reader is sloooow and clunky)

  • I wanted to be able to try things as I was reading them

    …you can safely evaluate elisp from an info buffer; a web browser session; or indeed anywhere else.

    Evaluating Elisp in Emacs

  • I wanted to be able to reference interesting things, bookmark them and add them to my notes or Zettelkasten

There’s a section in Mastering Emacs that mentions how to read EPUBs in Emacs, but here is how I set it up.

It’s in three steps:

  1. Add ability to have a column of text in the centre of my window - this isn’t something required for reading books, it’s something I’ve wanted for a while.
  2. Make the centre column width adaptive to my window size
  3. Configure Emacs to open EPUBs

visual-fill-column

I like the option of distraction free reading and writing. That means sometimes, I want to have my text centred on my screen, but, also not taking up the full width (especially on a wide-screen monitor). I guess I could resize my window (frame in Emacs parlance), but the computer should do the work for me.

So I use visual-fill-column:

The primary purpose of visual-fill-column-mode is to wrap text at fill-column in buffers that use visual-line-mode.

Centering the text - Another use case for visual-fill-column is to centre the text in a window. This effect is achieved by setting the user option visual-fill-column-center-text. Note that visual-fill-column-mode is not dependent on visual-line-mode, so it can be used to centre text in buffers that use auto-fill-mode or in programming modes.

I simply added this to my setup:

(use-package visual-fill-column)

Adaptive centre column width

I didn’t just want to have my centre column being defined by fill-column (the column beyond which automatic line-wrapping should happen), I wanted it to be adaptive. I want a comfortable centre column, wider for wide screens, but not too wide. How’s that for a hand-waving definition?

So I came up with my-centre-width - it calculates what the fill-column size should be for “comfortable” centring.

For small windows (window-width <= 1.1 * fill-column) we simply return 90% of the fill-column; for larger windows we get the maximum of either half the current window-width or the fill-column. The max is there for something like fill-column being 100, and window-width being 120 - in that case the result would be 100 (fill-column), rather than 60 (half window-width).

(defun my-centre-width ()
  "Return a fill column that makes centring pleasant regardless of screen size"
  (let ((window-width (window-width)))
    (floor (if (<= window-width (* 1.1 fill-column))
               (* 0.9 window-width)
             (max (/ window-width 2) fill-column)))))

As an aside: Don’t you just love that name spaces in (Common/Emacs) Lisp allow the function window-width to co-exist with the variable window-width!

nov.el

nov.el provides a major mode for reading EPUB documents.

Following the README I’ve come up with the following variation…

(use-package nov
  :init (defun my-nov-font-setup ()
          (face-remap-add-relative 'variable-pitch :family "Liberation Serif"
                                   :height 1.3)
          (setq fill-column (my-centre-width)
                nov-text-width (- fill-column 2)
                visual-fill-column-center-text t))
  :hook ((nov-mode . my-nov-font-setup)
         (nov-mode . visual-line-mode)
         (nov-mode . visual-fill-column-mode)))

(add-to-list 'auto-mode-alist '("\\.epub\\'" . nov-mode))

What I’ve done here is specified that I want the Liberation font. I’m setting the fill column to be my “comfortable” width (for visual-fill-column mode) and setting nov-text-width to be slightly smaller so that nov mode renders the text correctly in the centre of the screen.

If you don’t have the Liberation font installed (like I didn’t) and you use Homebrew as your package manager, it’s as simple as

brew install homebrew/cask-fonts/font-liberation

…and then

Reading EPUBs is as simple as opening the file!