From 6cddb77e8c80e51bcc1c763485580432953737cb Mon Sep 17 00:00:00 2001 From: TEC Date: Fri, 25 Dec 2020 19:16:55 +0800 Subject: [PATCH] Read and manage ebooks from Emacs --- config.org | 161 ++++++++++++++++++++++++++++++++++++++- misc/screenshots/nov.png | 3 + 2 files changed, 163 insertions(+), 1 deletion(-) create mode 100644 misc/screenshots/nov.png diff --git a/config.org b/config.org index 7b0a7ef..615eae7 100644 --- a/config.org +++ b/config.org @@ -1135,7 +1135,7 @@ theme. (gif-screencast-write-colormap) (add-hook 'doom-load-theme-hook #'gif-screencast-write-colormap)) #+end_src -*** Improving features +*** Features **** CalcTeX This is a nice extension to ~calc~ @@ -1201,6 +1201,20 @@ GoldenDict, it's likely we'll be able to switch from ~sdcv~ to that in the futur Since GoldenDict supports StarDict files, I expect this will be a relatively painless switch. +**** Calibre and ebook reading +For managing my ebooks, I'll hook into the well-established ebook library +manager [[https://calibre-ebook.com/][calibre]]. A number of Emacs clients for this exist, but this seems like a +good option. +#+begin_src emacs-lisp +(package! calibredb :pin "3f4ed7868bed75f633a8bc86909251a7b070dd55") +#+end_src + +Then for reading them, the only currently viable options seems to be [[https://depp.brause.cc/nov.el/][nov.el]]. +#+begin_src emacs-lisp +(package! nov :pin "0ece7ccbf79c074a3e4fbad1d1fa06647093f8e4") +#+end_src + +Together these should give me a rather good experience reading ebooks. **** Screenshots This makes it a breeze to take lovely screenshots. #+begin_src emacs-lisp @@ -2135,6 +2149,151 @@ Nested snippets are good, enable that. (setq yas-triggers-in-field t) #+end_src * Applications +** Ebooks +[[xkcd:548]] +=calibredb= lets us use calibre through Emacs, because who wouldn't want to use +something through Emacs? +#+begin_src emacs-lisp +(use-package! calibredb + :commands calibredb + :config + (setq calibredb-root-dir "~/Desktop/TEC/Other/Ebooks" + calibredb-db-dir (expand-file-name "metadata.db" calibredb-root-dir)) + (map! :map calibredb-show-mode-map + :ne "?" #'calibredb-entry-dispatch + :ne "o" #'calibredb-find-file + :ne "O" #'calibredb-find-file-other-frame + :ne "V" #'calibredb-open-file-with-default-tool + :ne "s" #'calibredb-set-metadata-dispatch + :ne "e" #'calibredb-export-dispatch + :ne "q" #'calibredb-entry-quit + :ne "." #'calibredb-open-dired + :ne [tab] #'calibredb-toggle-view-at-point + :ne "M-t" #'calibredb-set-metadata--tags + :ne "M-a" #'calibredb-set-metadata--author_sort + :ne "M-A" #'calibredb-set-metadata--authors + :ne "M-T" #'calibredb-set-metadata--title + :ne "M-c" #'calibredb-set-metadata--comments) + (map! :map calibredb-search-mode-map + :ne [mouse-3] #'calibredb-search-mouse + :ne "RET" #'calibredb-find-file + :ne "?" #'calibredb-dispatch + :ne "a" #'calibredb-add + :ne "A" #'calibredb-add-dir + :ne "c" #'calibredb-clone + :ne "d" #'calibredb-remove + :ne "D" #'calibredb-remove-marked-items + :ne "j" #'calibredb-next-entry + :ne "k" #'calibredb-previous-entry + :ne "l" #'calibredb-virtual-library-list + :ne "L" #'calibredb-library-list + :ne "n" #'calibredb-virtual-library-next + :ne "N" #'calibredb-library-next + :ne "p" #'calibredb-virtual-library-previous + :ne "P" #'calibredb-library-previous + :ne "s" #'calibredb-set-metadata-dispatch + :ne "S" #'calibredb-switch-library + :ne "o" #'calibredb-find-file + :ne "O" #'calibredb-find-file-other-frame + :ne "v" #'calibredb-view + :ne "V" #'calibredb-open-file-with-default-tool + :ne "." #'calibredb-open-dired + :ne "b" #'calibredb-catalog-bib-dispatch + :ne "e" #'calibredb-export-dispatch + :ne "r" #'calibredb-search-refresh-and-clear-filter + :ne "R" #'calibredb-search-clear-filter + :ne "q" #'calibredb-search-quit + :ne "m" #'calibredb-mark-and-forward + :ne "f" #'calibredb-toggle-favorite-at-point + :ne "x" #'calibredb-toggle-archive-at-point + :ne "h" #'calibredb-toggle-highlight-at-point + :ne "u" #'calibredb-unmark-and-forward + :ne "i" #'calibredb-edit-annotation + :ne "DEL" #'calibredb-unmark-and-backward + :ne [backtab] #'calibredb-toggle-view + :ne [tab] #'calibredb-toggle-view-at-point + :ne "M-n" #'calibredb-show-next-entry + :ne "M-p" #'calibredb-show-previous-entry + :ne "/" #'calibredb-search-live-filter + :ne "M-t" #'calibredb-set-metadata--tags + :ne "M-a" #'calibredb-set-metadata--author_sort + :ne "M-A" #'calibredb-set-metadata--authors + :ne "M-T" #'calibredb-set-metadata--title + :ne "M-c" #'calibredb-set-metadata--comments)) +#+end_src + +Then, to actually read the ebooks we use =nov=. + +#+attr_html: :class invertible :alt Excerpt of the GNU Emacs manual viewed through nov.el +[[https://tecosaur.com/lfs/emacs-config/screenshots/nov.png]] + +#+begin_src emacs-lisp +(use-package! nov + :mode ("\\.epub\\'" . nov-mode) + :config + (map! :map nov-mode-map + :n "RET" #'nov-scroll-up) + + (defun doom-modeline-segment--nov-info () + (concat + " " + (propertize + (cdr (assoc 'creator nov-metadata)) + 'face 'doom-modeline-project-parent-dir) + " " + (cdr (assoc 'title nov-metadata)) + " " + (propertize + (format "%d/%d" + (1+ nov-documents-index) + (length nov-documents)) + 'face 'doom-modeline-info))) + + (advice-add 'nov-render-title :override #'ignore) + + (defun +nov-mode-setup () + (face-remap-add-relative 'variable-pitch + :family "Merriweather" + :height 1.4 + :width 'semi-expanded) + (face-remap-add-relative 'default :height 1.3) + (setq-local line-spacing 0.2 + next-screen-context-lines 4 + shr-use-colors nil) + (require 'visual-fill-column nil t) + (setq-local visual-fill-column-center-text t + visual-fill-column-width 80 + nov-text-width 80) + (visual-fill-column-mode 1) + (hl-line-mode -1) + + (add-to-list '+lookup-definition-functions #'+lookup/dictionary-definition) + + (setq-local mode-line-format + `((:eval + (doom-modeline-segment--workspace-name)) + (:eval + (doom-modeline-segment--window-number)) + (:eval + (doom-modeline-segment--nov-info)) + ,(propertize + " %P " + 'face 'doom-modeline-buffer-minor-mode) + ,(propertize + " " + 'face (if (doom-modeline--active) 'mode-line 'mode-line-inactive) + 'display `((space + :align-to + (- (+ right right-fringe right-margin) + ,(* (let ((width (doom-modeline--font-width))) + (or (and (= width 1) 1) + (/ width (frame-char-width) 1.0))) + (string-width + (format-mode-line (cons "" '(:eval (doom-modeline-segment--major-mode)))))))))) + (:eval (doom-modeline-segment--major-mode))))) + + (add-hook 'nov-mode-hook #'+nov-mode-setup)) +#+end_src ** IRC =circe= is a client for IRC in Emacs (hey, isn't that a nice project name+acronym), and a greek enchantress who turned humans into animals. diff --git a/misc/screenshots/nov.png b/misc/screenshots/nov.png new file mode 100644 index 0000000..41f6505 --- /dev/null +++ b/misc/screenshots/nov.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:11cebde7da560a1f58f20a50595392c27430f0aa97128965b19ad44b5e39cc2e +size 53788