Related articles
Hacker News mode and minor modes for websites // Bodacious Blog

This blog is about creating a minor mode for browsing asciinema.org and extending eww-mode to handle the video links.

I use tmux from emacs to spawn a new window that starts the playback when a link is clicked.

Demonstration

Here, I use the asciinema mode for browsing and opening asciinema recordings from my blog.

asciinema recording

Creating the asciinema-eww-mode minor mode

 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
(defun asciinema-eww-next-cast (&optional re)
  (interactive)
  (if
      (not re)
      (setq re " +[0-9][0-9]:[0-9][0-9][^0-9]"))
  (backward-to-indentation 0)
  (if (string-match-p re (current-line-string))
      (search-forward-regexp re))
  (ignore-errors (search-forward-regexp re))
  (backward-to-indentation 0))

(defun asciinema-eww-prev-cast (&optional re)
  (interactive)
  (if
      (not re)
      (setq re " +[0-9][0-9]:[0-9][0-9][^0-9]"))
  (backward-to-indentation 0)
  (ignore-errors (search-backward-regexp re))
  (backward-to-indentation 0))

(define-key asciinema-eww-mode-map (kbd "M-n") #'asciinema-eww-next-cast)
(define-key asciinema-eww-mode-map (kbd "M-p") #'asciinema-eww-prev-cast)

(cl-loop for eww in '(hn asciinema) do (eval `(defewwmode ,eww)))

(defun get-eww-mode-string-from-url (url)
  (cond ((string-match-p "^https?://news\.ycombinator\.com/?$" url) "hn")
        ((string-match-p "^https?://asciinema.org/" url) "asciinema")
        (t "")))
 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
(defun tm-asciinema-play (url)
  (interactive (list (read-string "asciinema url:")))
  (nw (concat "asciinema-play " (q url))))

(defun eww-follow-link (&optional external mouse-event)
  "Browse the URL under point.
If EXTERNAL is single prefix, browse the URL using `shr-external-browser'.
If EXTERNAL is double prefix, browse in new buffer."
  (interactive (list current-prefix-arg last-nonmenu-event))
  (mouse-set-point mouse-event)
  (let ((url (get-text-property (point) 'shr-url)))
    (setq eww-followed-link url)
    (cond
     ((not url)
      (message "No link under point"))
     ((string-match "^mailto:" url)
      (browse-url-mail url))
     ((string-match "^https?://asciinema.org/a/[a-zA-Z0-9]+$" url)
      (tm-asciinema-play url))
     ((and (consp external) (<= (car external) 4))
      (funcall shr-external-browser url))
     ;; This is a #target url in the same page as the current one.
     ((and (url-target (url-generic-parse-url url))
           (eww-same-page-p url (plist-get eww-data :url)))
      (let ((dom (plist-get eww-data :dom)))
        (eww-save-history)
        (eww-display-html 'utf-8 url dom nil (current-buffer))))
     (t
      (eww-browse-url url external)))))

Create the asciinema-play script

It simply says “loading video…” as the video starts.

1
2
3
#!/bin/bash
echo "loading video..."
asciinema play "$@"

Create the script asciinema-list-videos

This lists the videos and opens emacs with an org-mode document containing the links.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
#!/bin/bash
export TTY

is_tty() {
    # If stout is a tty
    [[ -t 1 ]]
}

# ( hs "$(basename "$0")" "$@" "#" "<==" "$(ps -o comm= $PPID)" 0</dev/null ) &>/dev/null

ci curl "https://asciinema.org/~mullikine" |
    grep -P '^<a href="/a/' |
    sed "s/^<a href=\"\\([^\"]\\+\\)\">\\(.*\\)<\\/a>/\\[\\[https:\\/\\/asciinema.org\\1\\]\\[\\2\\]\\]/" |
    {
        if is_tty; then
            og -ic org-mode
        else
            cat
        fi
    }

I made this interesting sed command using my real-time feedback repl.

Creating a complicated sed command with rtcmd

This almost deserves it’s own blog post.

asciinema recording

Just for laughs

I browse asciinema.org through emacs with my asciinema-eww-mode and load a recording of myself using asciinema-eww-mode to browse asciinema.org and play recordings from there.

asciinema recording

Related
Meta & Inception // Bodacious Blog