# Advent of emacs #22: How I do ebook reading in emacs

Posted on Dec 22, 2022 by Chung-hong Chan

Welcome to another episode of “A Poseur Wandering the emacs lisp World”, I am your host, chainsawriot. Today I will give another example of programming using emacs lisp to extend emacs.

# Example 2: minimalize nov

Like many poseurs, I read. Also like a lot of enemies of free software, I buy and read many DRM-ed ebooks with my proprietary, making-Jeff-Bezos-rich Amazon Kindle.

For technical books, I usually buy them from Humble Bundle. I usually get a dozen of books for less than 20 euros. The books are not DRM-protected and usually EPUB files are available. Similarly, I got free books also from Project Gutenberg, e.g. this book I am using to learn Latin. Similarly, the books are in free-as-free-speech EPUB.

nov by Vasilij Schneidermann et al is a EPUB reading mode for emacs. While emacs is a good editor, it can be a decent document viewer too. I have talked about GNU TexInfo on day 8.

  (use-package nov
:config
)


By default, nov displays an EPUB file like this:

Not bad. But not great. Comme si comme ça. I want to have a kind-of immersive reading experience. It still looks quite like, well, emacs.

## Take 1: Following the README

The README file of nov actually provides instructions to improve the reading experience. Basically, it adjusts the fonts and text width (using visual-fill-column mode).

(defun my-nov-font-setup ()
:height 1.0))
(setq nov-text-width 80)
(setq nov-text-width t)
(setq visual-fill-column-center-text t)


Much better. But can I push it even further? In general, the README teaches me to create a hook function (my-nov-font-setup) and put it into nov-mode-hook (see day 17). So, I should be able to add more things into this hook function.

## Take 2: Disable, disable, disable

What I wanted to do is to disable all the information display, specifically modeline, the header, the scroll bar, and even the cursor.

(defun nov-display ()
:height 1.5)
(toggle-scroll-bar -1)
(setq mode-line-format nil
cursor-type nil))
(setq nov-text-width 120)


Much more immersive. But disabling the cursor creates a problem: I sometimes need the cursor to interacting with the TOC and even to copy save content into the kill ring. I need to have a way to toggle the cursor.

## Take 3: Toggling the cursor

(defvar nov-cursor nil "Whether the cursor is enabled")

(defun toggle-nov-cursor ()
"Toggle nov cursor mode"
(interactive)
(if nov-cursor
(progn
(setq cursor-type nil
nov-cursor nil)
(scroll-lock-mode 1))
(progn
(setq cursor-type t
nov-cursor t)
(scroll-lock-mode -1)
)))

(defun nov-display ()
:height 1.5)
(scroll-lock-mode 1)
(toggle-scroll-bar -1)
(setq mode-line-format nil
cursor-type nil))
(use-package visual-fill-column
:config
(setq-default visual-fill-column-center-text t)
(setq-default visual-fill-column-width 120))
(use-package nov
:config

And after this wall of emacs lisp, I can enable and disable the cursor by pressing C-q. In the following demo, I switch off the dark mode and also switch off the mode line of StumpWM. It’s almost like a full screen Kindle.
Now, this is the 3rd time I talked about C-q. I will explain it tomorrow.