AloisJanicek / shrface

It is a shr faces package that helps you apply your favourite org faces to shr, dash-docs, eww, nov.el and mu4e.

Home Page:https://github.com/chenyanming/shrface

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

SHRFACE

Table of Contents

Description

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 or occur
  • 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 with shr (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 browser eww.

Screenshots when using eww

Screenshots when using dash-docs

Version 1.3: New face shrface-code, unleash the full power of dash-docs

Screenshots when using nov.el

Screenshots when using mu4e

Screenshots when using imenu-list, helm-imenu, counsel-imenu

Version 1.4: New feature, imenu support

Screenshots with outline minior mode and org-indent-mode

Version 1.5: New feature, outline minior mode support (use org-cycle and org-shifttab)

Screenshots with shrface-occur

Version 2.1: New feature, list all headlines with occur

Prerequisites

This package uses shr, org, imenu, outline, occur

Installation

Choose one of the following installation methods based on your needs:

ues-package

(use-package shrface
  :after shr
  :quelpa
  (shrface :repo "chenyanming/shrface" :fetcher github))

Doom Emacs

Add the following line to package.el

(package! shrface :recipe (:host github :repo "chenyanming/shrface"))

Run ./.emacs.d/bin/doom sync

Spacemacs or other emacs distributions

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)

Configuration

Quick Start

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

Notes about setting for nov.el

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

Keybinding Settings

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.

Spacemacs

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

Doom emacs

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

Other emacs

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

Features Anatomy

shrface-basic and shrface-trail

By calling shrface-baisic and shrface-trail, you will enable shrfaces globally.

shrface-occur

M-x shrface-occur to list all headlines, and you can easily jump between them.

shrface-mode

From version 1.8, shrface-mode is adapted, for it is more flexible to enable/disable the following additional features:

  1. imenu
  2. outline-minior-mode
  3. 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 Settings

Headline bullets (h1 to h6)

You 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.

Item bullet

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

Paragraph indentation and fill column

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

Versatile URL

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

Supported faces

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)

Experimental face(s)

(defface shrface-code '((t :inherit org-code))
  "TODO Face used for inline code"
  :group 'shrface-faces)

Enable the shrface-code

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)

Important notes on experimental faces

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.

(Optional) Enable source codes highlight

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

Hacking the shr-tag-pre-highlight.el

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

Screenshots when both enable shrface and the code highlights

TODO

  • [ ] shrface-highlight
  • [ ] shrface-todo
  • [ ] shrface-babel

News/Logs

2020-04-23

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

2020-04-20

Version 2.0:

  • New face: shrface-description-list-term-face

2020-04-19

Version 1.9:

  • New Functions: shrface-basic and shrface-trail

2020-04-18

Version 1.8:

  • New face: shrface-item-number-face
  • New Minor Mode: shrface-mode

2020-04-17

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)

2020-04-16

Version 1.5:

  • New feature: outline minior mode support (Enabled by default, but not the keybindings)

2020-04-15

Version 1.4:

  • New feature: imenu support

2020-04-13

Version 1.3:

  • New face: shrface-code (Experimental face, disabled by default)

2020-04-12

Version 1.2:

  • New face: shrface-verbatim

2020-04-11

Version 1.1:

  • Fixed bug: Wrong indentation handling make some items in paragraph disappear (such as images)

2020-04-10

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

About

It is a shr faces package that helps you apply your favourite org faces to shr, dash-docs, eww, nov.el and mu4e.

https://github.com/chenyanming/shrface

License:GNU General Public License v3.0


Languages

Language:Emacs Lisp 100.0%