- Description
- Prerequisites
- Installation
- Configuration
- TODO
- News/Logs
It is a shr faces package that helps you apply your favourite org faces to shr
,
dash-docs
, eww
, nov.el
, and mu4e
.
- Configurable org-like heading faces, headline bullets, item bullets,paragraph indentation, fill-column, item bullet, versatile hyper links(http/https/file/mailto/etc) face and so on.
- Browse the internet or local html file with eww just like org mode.
- Read dash docsets with dash-docs and the beauty of org faces.
- Read epub files with nov.el , just like org mode.
- Read html email with mu/mu4e , the same reading experience just like org mode without formatting html to org file.
- Switch/jump the headlines just like org-mode in eww and nov.el with
imenu
oroccur
- Togle/cycle the headlines just like org-mode in eww and nov.el with outline minor mode
and
org-cycle/org-shifttab
- Enable indentation just like org-mode in eww and nov.el with
org-indent-mode
The project target is to apply org features to
shr
, and all libraries that render HTML withshr
(Simple HTML Renderer).As EmacsWiki says:
shr.el
is an HTML renderer in Emacs as of version 24.4 (based on libxml2, it was originally a part of Gnus). It’s the basis of the web browsereww
.
This package uses shr
, org
, imenu
, outline
, occur
Choose one of the following installation methods based on your needs:
(use-package shrface
:after shr
:quelpa
(shrface :repo "chenyanming/shrface" :fetcher github))
Add the following line to package.el
(package! shrface :recipe (:host github :repo "chenyanming/shrface"))
Run ./.emacs.d/bin/doom sync
Put shrface.el
to your load-path. Here is example of spacemacs
git clone git@github.com:chenyanming/shrface.git ~/.emacs.d/private/shrface
(add-to-list 'load-path (expand-file-name "~/.emacs.d/private/shrface"))
(require 'shrface)
From version 1.9
, users have to enable the shrface
by themselves, by calling
(shrface-basic)
or (shrface-trail)
after (require 'shrface)
. Be sure to wrap all
the following settings mentioned in this document into (with-eval-after-load
'shr)
, it can save you a lot of boot up time.
(with-eval-after-load 'shr ; lazy load is very important, it can save you a lot of boot up time
(require 'shrface)
(shrface-basic) ; enable shrfaces, must be called before loading eww/dash-docs/nov.el
(shrface-trial) ; enable shrface experimental face(s), must be called before loading eww/dash-docs/nov.el
(setq shrface-href-versatile t) ; enable versatile URL faces support
; (http/https/ftp/file/mailto/other), if
; `shrface-href-versatile' is nil, default
; face `shrface-href-face' would be used.
;; eww support
(with-eval-after-load 'eww
(add-hook 'eww-after-render-hook 'shrface-mode))
;; nov support
(with-eval-after-load 'nov
(setq nov-shr-rendering-functions '((img . nov-render-img) (title . nov-render-title))) ; reset nov-shr-rendering-functions, in case of the list get bigger and bigger
(setq nov-shr-rendering-functions (append nov-shr-rendering-functions shr-external-rendering-functions))
(add-hook 'nov-mode-hook 'shrface-mode))
;; mu4e support
(with-eval-after-load 'mu4e
(add-hook 'mu4e-view-mode-hook 'shrface-mode)))
- Check this section to see the supported faces: Supported Faces
- Check the experimental faces notes here: Experimental faces
- There is another library
inherit-org
to inherit org faces to even more non-org buffers, and it is no dependency/relationships withshrface
, check here https://github.com/chenyanming/inherit-org
Since nov-shr-rendering-functions
is not a customizable variable. Therefore,
following setting is not included into the package at this moment.
(setq nov-shr-rendering-functions '((img . nov-render-img) (title . nov-render-title))) ; reset nov-shr-rendering-functions, in case of the list get bigger and bigger
(setq nov-shr-rendering-functions (append nov-shr-rendering-functions shr-external-rendering-functions))
You can set the keybinding directly with the original org outline related
functions, like org-cycle
, org-shifttab
, org-content
, org-overview
, etc, and
most of outline
minior mode functions (prefix with outline-
) after testing.
Please notice, org-show-children
are not 100% supported, since the regexp-fmt
is
hard coded and override it is inappropriate (It is better to update org.el
directly). Besides, you can use outline-magic as alternative.
(with-eval-after-load 'nov
(evil-define-key '(evilified normal) nov-mode-map
(kbd "<tab>") 'org-cycle
(kbd "<S-tab>") 'org-shifttab
(kbd "C-j") 'outline-next-visible-heading
(kbd "C-k") 'outline-previous-visible-heading))
(with-eval-after-load 'eww
(evil-define-key '(evilified normal) eww-mode-map
(kbd "<tab>") 'org-cycle
(kbd "<S-tab>") 'org-shifttab
(kbd "C-j") 'outline-next-visible-heading
(kbd "C-k") 'outline-previous-visible-heading))
(map! :map nov-mode-map
:after nov
:n "<tab>" 'org-cycle
:n "S-<tab>" 'org-shifttab
:n "C-j" 'outline-next-visible-heading
:n "C-k" 'outline-previous-visible-heading)
(map! :map eww-mode-map
:after eww
:n "<tab>" 'org-cycle
:n "S-<tab>" 'org-shifttab
:n "C-j" 'outline-next-visible-heading
:n "C-k" 'outline-previous-visible-heading)
(with-eval-after-load 'nov
(define-key nov-mode-map (kbd "<tab>") 'org-cycle)
(define-key nov-mode-map (kbd "S-<tab>") 'org-shifttab)
(define-key nov-mode-map (kbd "C-j") 'outline-next-visible-heading)
(define-key nov-mode-map (kbd "C-k") 'outline-previous-visible-heading))
(with-eval-after-load 'eww
(define-key eww-mode-map (kbd "<tab>") 'org-cycle)
(define-key eww-mode-map (kbd "S-<tab>") 'org-shifttab)
(define-key eww-mode-map (kbd "C-j") 'outline-next-visible-heading)
(define-key eww-mode-map (kbd "C-k") 'outline-previous-visible-heading))
By calling shrface-baisic
and shrface-trail
, you will enable shrfaces globally.
M-x
shrface-occur
to list all headlines, and you can easily jump between them.
From version 1.8
, shrface-mode
is adapted, for it is more flexible to
enable/disable the following additional features:
imenu
outline-minior-mode
org-indent-mode
For example, to enable shrface-mode
to eww
, nov
or mu4e
(with-eval-after-load 'eww
(add-hook 'eww-after-render-hook 'shrface-mode)) ; this will affect eww and dash-docs
(with-eval-after-load 'nov
(setq nov-shr-rendering-functions '((img . nov-render-img) (title . nov-render-title))) ; reset nov-shr-rendering-functions, in case of the list get bigger and bigger
(setq nov-shr-rendering-functions (append nov-shr-rendering-functions shr-external-rendering-functions))
(add-hook 'nov-mode-hook 'shrface-mode))
(with-eval-after-load 'mu4e
(add-hook 'mu4e-view-mode-hook 'shrface-mode))
Besides, you can enable/disable shrface-mode
via M-x
Follow the following guide to setup the keybindings.
Keybinding SettingsYou can configure your farourite bullets up to 6 levels of headings (cycled through if less than 6 bullets in setting).
You can set it with:
(setq shrface-bullets-bullet-list '("◉" "○" "✸" "✿"))
PS: The bullets setting can be derived from org-bullets-bullet-list
or
org-superstar-headline-bullets-list
, if org-bullets or org-superstar is
available.
You can configure your favorite item bullet for shrface
You can set it with:
(setq shrface-item-bullet "➤")
PS: Only one type of item bullet is supported, prettified by
shrface-item-bullet-face
You can configure the paragraph indentation (obsolete, default is 0, because the
indentation is managed by org-indent-mode
started from version 1.6, but you can
still use it for more indentation spaces) and fill column for better reading
experience. These two settings is useful when you read epub
files that have lots
of paragraphs, like novels.
You can set them with:
(setq shrface-paragraph-indentation 0)
(setq shrface-paragraph-fill-column 120)
PS: The default setting is 0 and 120
You can enable versatile URL faces support simply by:
(setq shrface-href-versatile t)
The following types of URL can be customized.
- http
- https
- ftp
- file
- mailto
- other
Here are the faces supported:
(defcustom shrface-bullets-bullet-list
(or (bound-and-true-p org-bullets-bullet-list)
(bound-and-true-p org-superstar-headline-bullets-list)
'("◉"
"○"
"✸"
"✿"))
"Bullets for headings"
:group 'shrface
:type '(repeat (string :tag "Bullet character")))
(defface shrface-href-face '((t :inherit org-link))
"Default <href> face if `shrface-href-versatile' is nil"
:group 'shrface-faces)
(defface shrface-href-other-face '((t :inherit org-link :foreground "#87cefa"))
"Face used for <href> other than http:// https:// ftp://
file:// mailto:// if `shrface-href-versatile' is NON-nil. For
example, it can be used for fontifying charter links with epub
files when using nov.el."
:group 'shrface-faces)
(defface shrface-href-http-face '((t :inherit org-link :foreground "#39CCCC"))
"Face used for <href>, http:// if `shrface-href-versatile' is
NON-nil"
:group 'shrface-faces)
(defface shrface-href-https-face '((t :inherit org-link :foreground "#7FDBFF"))
"Face used for <href>, https:// if `shrface-href-versatile' is
NON-nil"
:group 'shrface-faces)
(defface shrface-href-ftp-face '((t :inherit org-link :foreground "#3D9970"))
"Face used for <href>, ftp:// if `shrface-href-versatile' is
NON-nil"
:group 'shrface-faces)
(defface shrface-href-file-face '((t :inherit org-link :foreground "#2ECC40"))
"Face used for <href>, file:// if `shrface-href-versatile' is
NON-nil"
:group 'shrface-faces)
(defface shrface-href-mailto-face '((t :inherit org-link :foreground "#FF851B"))
"Face used for <href>, mailto:// if `shrface-href-versatile' is
NON-nil"
:group 'shrface-faces)
(defface shrface-h1-face '((t :inherit org-level-1))
"Face used for <h1> headlines."
:group 'shrface-faces)
(defface shrface-h2-face '((t :inherit org-level-2))
"Face used for <h2> headlines."
:group 'shrface-faces)
(defface shrface-h3-face '((t :inherit org-level-3))
"Face used for <h3> headlines."
:group 'shrface-faces)
(defface shrface-h4-face '((t :inherit org-level-4))
"Face used for <h4> headlines."
:group 'shrface-faces)
(defface shrface-h5-face '((t :inherit org-level-5))
"Face used for <h5> headlines."
:group 'shrface-faces)
(defface shrface-h6-face '((t :inherit org-level-6))
"Face used for <h6> headlines."
:group 'shrface-faces)
(defface shrface-verbatim '((t :inherit org-verbatim))
"Face used for verbatim/emphasis - <em>."
:group 'shrface-faces)
(defface shrface-item-bullet-face '((t :inherit org-list-dt))
"Face used for unordered list bullet"
:group 'shrface-faces)
(defface shrface-item-number-face '((t :inherit org-list-dt))
"Face used for ordered list numbers"
:group 'shrface-faces)
(defface shrface-description-list-term-face '((t :inherit org-list-dt))
"Face used for description list terms <dt>"
:group 'shrface-faces)
(defface shrface-code '((t :inherit org-code))
"TODO Face used for inline code"
:group 'shrface-faces)
shrface-code
is experimental face, and it is not stable to use, but you can
still add the following statement to enable it:
(shrface-trial)
Please notice, shrface-code
is an experimental face, which may make eww
hangup
at some specific websites (not all). However, it work perfectly with local html files
during testing with dash-docs
or nov.el
For example, browse eww
with
https://github.com/chenyanming/shrface
eww
still keep connecting to the remote which sometimes
will trigger a loop, the only solution so far is after loading the page,
list all connections through
M-x list-processes
then press “d” to kill the connections before the hangup.
Welcome test and report.
You can install shr-tag-pre-highlight.el to enable source codes highlight and background color.
(use-package shr-tag-pre-highlight
:ensure t
:after shr
:config
(add-to-list 'shr-external-rendering-functions
'(pre . shr-tag-pre-highlight))
(when (version< emacs-version "26")
(with-eval-after-load 'eww
(advice-add 'eww-display-html :around
'eww-display-html--override-shr-external-rendering-functions))))
If you want to add indentation, background color, #+BEGIN_SRC lang
, and #+END_SRC
for, you can overwrite the function as following:
(require 'shr-tag-pre-highlight)
(add-to-list 'shr-external-rendering-functions '(pre . shrface-shr-tag-pre-highlight))
(defun shrface-shr-tag-pre-highlight (pre)
"Highlighting code in PRE."
(let* ((shr-folding-mode 'none)
(shr-current-font 'default)
(code (with-temp-buffer
(shr-generic pre)
(setq-local fill-column 120)
(indent-rigidly (point-min) (point-max) 2)
(if (eq "" (dom-texts pre))
nil
(progn
(setq-local fill-column shrface-paragraph-fill-column)
(indent-rigidly (point-min) (point-max) shrface-paragraph-indentation)))
(buffer-string)))
(lang (or (shr-tag-pre-highlight-guess-language-attr pre)
(let ((sym (language-detection-string code)))
(and sym (symbol-name sym)))))
(mode (and lang
(shr-tag-pre-highlight--get-lang-mode lang))))
(shr-ensure-newline)
(insert (make-string shrface-paragraph-indentation ?\ )) ; make indent string
;; (insert (propertize (concat "#+BEGIN_SRC " lang) 'face 'org-block-begin-line))
(shr-ensure-newline)
(setq start (point))
(insert
(or (and (fboundp mode)
(with-demoted-errors "Error while fontifying: %S"
(shrface-tag-pre-highlight-fontify code mode)
))
code))
(shr-ensure-newline)
(setq end (point))
(insert (make-string shrface-paragraph-indentation ?\ )) ; make indent string
;; (insert (propertize "#+END_SRC" 'face 'org-block-end-line ) )
(let* ((beg start)
(xx (make-overlay beg end)))
(overlay-put xx 'face '(:background "#292b2e" :height 150)))
(shr-ensure-newline)
(insert "\n")))
Sometimes a wrong language is detected, but it is still great for highlight, even just for eye pleasing. If you found the wrong detection is annoying, delete lang
just like below statement:
(insert (propertize (concat "#+BEGIN_SRC" ) 'face 'org-block-begin-line))
- [ ]
shrface-highlight
- [ ]
shrface-todo
- [ ]
shrface-babel
Version 2.1:
- New Feature:
shrface-occur
- New faces:
shrface-href-http-face
shrface-href-https-face
shrface-href-ftp-face
shrface-href-file-face
shrface-href-mailto-face
shrface-href-other-face
Version 2.0:
- New face:
shrface-description-list-term-face
Version 1.9:
- New Functions:
shrface-basic
andshrface-trail
Version 1.8:
- New face:
shrface-item-number-face
- New Minor Mode:
shrface-mode
Version 1.7:
- New feature:
shrface-item-bullet
- New face:
shrface-item-bullet-face
Version 1.6:
- New feature:
org-indent-mode
support (Enabled by default)
Version 1.5:
- New feature:
outline minior mode
support (Enabled by default, but not the keybindings)
Version 1.4:
- New feature:
imenu
support
Version 1.3:
- New face:
shrface-code
(Experimental face, disabled by default)
Version 1.2:
- New face:
shrface-verbatim
Version 1.1:
- Fixed bug: Wrong indentation handling make some items in paragraph disappear (such as images)
Version 1.0:
- New face:
shrface-bullets-bullet-list
- New face:
shrface-h1-face
- New face:
shrface-h2-face
- New face:
shrface-h3-face
- New face:
shrface-h4-face
- New face:
shrface-h5-face
- New face:
shrface-h6-face
- New face:
shrface-h6-face
- New face:
shrface-href-face
- New customizable variable:
shrface-paragraph-indentation
- New customizable variable:
shrface-paragraph-fill-column