aboutsummaryrefslogtreecommitdiff
path: root/README.rst
blob: f8a96c55f2432c57192a4d0e17ac6b0f5b741bde (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
nov.el
======

.. image:: https://raw.github.com/wasamasa/nov.el/master/img/novels.gif

About
-----

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

Features:

- Basic navigation (jump to TOC, previous/next chapter)
- Remembering and restoring the last read position
- Jump to next chapter when scrolling beyond end
- Storing and following Org links to EPUB files
- Renders EPUB2 (.ncx) and EPUB3 (<nav>) TOCs
- Hyperlinks to internal and external targets
- Supports textual and image documents
- Info-style history navigation
- View source of document files
- Metadata display
- Image rescaling

Screenshot
----------

.. image:: https://raw.github.com/wasamasa/nov.el/master/img/scrot.png

Installation
------------

Set up the `MELPA <https://melpa.org/>`_ or `MELPA Stable
<https://stable.melpa.org/>`_ repository if you haven't already and
install with ``M-x package-install RET nov RET``.

Setup
-----

Make sure you have an ``unzip`` executable on ``PATH``, otherwise the
extraction of EPUB files will fail.  If you for some reason have
``unzip`` in a non-standard location, customize ``nov-unzip-program``
to its path.  You'll also need an Emacs compiled with ``libxml2``
support, otherwise rendering will fail.

Put the following in your init file:

.. code:: elisp

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

Customization
-------------

While the defaults make for an acceptable reading experience, it can
be improved with any of the following changes:

Default font
............

To change the default font, use ``M-x customize-face RET
variable-pitch``, pick a different family, save and apply.  If you
dislike globally customizing that face, add the following to your init
file:

.. code:: elisp

    (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)

To completely disable the variable pitch font, customize
``nov-variable-pitch`` to ``nil``.  Text will be displayed with the
default face instead which should be using a monospace font.

Text width
..........

By default text is filled by the window width.  You can customize
``nov-text-width`` to a number of columns to change that:

.. code:: elisp

    (setq nov-text-width 80)

It's also possible to set it to ``t`` to inhibit text filling, this
can be used in combination with ``visual-line-mode`` and packages such
as ``visual-fill-column`` to implement more flexible filling:

.. code:: elisp

    (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)

Rendering
.........

In case you're not happy with the rendering at all, you can either use
``nov-pre-html-render-hook`` and ``nov-post-html-render-hook`` to
adjust the HTML before and after rendering or use your own rendering
function by customizing ``nov-render-html-function`` to one that
replaces HTML in a buffer with something nicer than the default
output.

Here's an advanced example of text justification with the `justify-kp
<https://github.com/Fuco1/justify-kp>`_ package:

.. code:: elisp

    (require 'justify-kp)
    (setq nov-text-width t)

    (defun my-nov-window-configuration-change-hook ()
      (my-nov-post-html-render-hook)
      (remove-hook 'window-configuration-change-hook
                   'my-nov-window-configuration-change-hook
                   t))

    (defun my-nov-post-html-render-hook ()
      (if (get-buffer-window)
          (let ((max-width (pj-line-width))
                buffer-read-only)
            (save-excursion
              (goto-char (point-min))
              (while (not (eobp))
                (when (not (looking-at "^[[:space:]]*$"))
                  (goto-char (line-end-position))
                  (when (> (shr-pixel-column) max-width)
                    (goto-char (line-beginning-position))
                    (pj-justify)))
                (forward-line 1))))
        (add-hook 'window-configuration-change-hook
                  'my-nov-window-configuration-change-hook
                  nil t)))

    (add-hook 'nov-post-html-render-hook 'my-nov-post-html-render-hook)

This customization yields the following look:

.. image:: https://raw.github.com/wasamasa/nov.el/master/img/justify-kp.png

Usage
-----

Open the EPUB file with ``C-x C-f ~/novels/novel.epub``, scroll with
``SPC`` and switch chapters with ``n`` and ``p``.  More keybinds can
be looked up with ``F1 m``.

Contributing
------------

See `CONTRIBUTING.rst
<https://github.com/wasamasa/nov.el/blob/master/CONTRIBUTING.rst>`_.

Alternatives
------------

The first one I've heard of is `epubmode.el
<https://www.emacswiki.org/emacs/epubmode.el>`_ which is, well, see
for yourself.  You might find `ereader
<https://github.com/bddean/emacs-ereader>`_ more useful, especially if
you're after Org integration and annotation support.