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.
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
(add-to-list 'auto-mode-alist '("\\.epub\\'" . nov-mode))
)
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.
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 ()
(face-remap-add-relative 'variable-pitch :family "Liberation Serif"
:height 1.0))
(add-hook 'nov-mode-hook 'my-nov-font-setup)
(setq nov-text-width 80)
(setq nov-text-width t)
(setq visual-fill-column-center-text t)
(add-hook 'nov-mode-hook 'visual-line-mode)
(add-hook 'nov-mode-hook 'visual-fill-column-mode)
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.
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 ()
(face-remap-add-relative 'variable-pitch :family "Liberation Serif"
:height 1.5)
(toggle-scroll-bar -1)
(setq mode-line-format nil
nov-header-line-format ""
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.
(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 ()
(face-remap-add-relative 'variable-pitch :family "Liberation Serif"
:height 1.5)
(scroll-lock-mode 1)
(toggle-scroll-bar -1)
(setq mode-line-format nil
nov-header-line-format ""
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
(add-to-list 'auto-mode-alist '("\\.epub\\'" . nov-mode))
(add-hook 'nov-mode-hook 'nov-display)
(add-hook 'nov-mode-hook 'visual-fill-column-mode)
:bind
(
:map nov-mode-map
("C-q" . 'toggle-nov-cursor))
)
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.