-
Notifications
You must be signed in to change notification settings - Fork 58
/
Copy pathinit-markdown.el
136 lines (120 loc) · 4.75 KB
/
init-markdown.el
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
;;; init-markdown.el --- Markdown http://jblevins.org/projects/markdown-mode/ -*- lexical-binding: t -*-
;;; Commentary:
;;
;; This module provide a minor mode "impatient markdown mode", which similar to
;; impatient-mode but for markdown buffers as opposed to HTML buffers. It is
;; actually implemented with the impatient-mode itself.
;;
;; When you type command `impatient-markdown-mode' in a markdown buffer, Emacs
;; starts an embedded HTTP server listening to port 8080 (by default), and it
;; will direct your favorite web browser to URL
;; "http://localhost:8080/imp/live/<buffer-name.md>"
;;
;; Any change you make in the buffer from that point is automatically rendered
;; in real-time in the web browser. To stop the HTTP server, run
;; `impatient-markdown-mode' again. Note that Emacs will complain if you quit
;; before stopping the server.
;;
;; Before you can use it, you need to set the variable `markdown-command' to
;; the command to execute to render a markdown file into HTML. To use the
;; GitHub command, clone https://github.com/github/markup and set
;; `markdown-command' to the path of bin/github-markup in your after-init.el.
;; Other options include Pandoc or RedCarpet.
;;
;; Note: you can change the variable `httpd-port' if 8080 does not work in your
;; environment. Also the current implementation uses a temporary file whose
;; path is defined in `exordium-markdown-file' which can also be changed.
;;; Code:
(eval-when-compile
(unless (featurep 'init-require)
(load (file-name-concat (locate-user-emacs-file "modules") "init-require"))))
(exordium-require 'init-prefs)
(exordium-require 'init-lib)
(exordium-require 'init-window-manager)
(use-package markdown-mode
:commands (markdown-mode gfm-mode)
:mode
(("README\\.md\\'" . gfm-mode)
("\\.md\\'" . markdown-mode)
("\\.markdown\\'" . markdown-mode))
:hook
(markdown-mode . exordium-electric-mode-add-back-tick)
:config
;; TODO: he following feature seems to has changed and a new solution needs
;; to be developed.
;; Loud face for TODOs in markdown documents
;; (when exordium-font-lock
;; (setq markdown-mode-font-lock-keywords-core
;; (list
;; (cons markdown-regex-italic '(2 markdown-italic-face))
;; (cons "\\<\\(TODO\\|FIXME\\|TBD\\):" '(1 font-lock-warning-face)))))
)
;;; FIXME: quick workaround for a bug in markdown-mode 2.1 (font lock is broken)
(when (and (boundp 'markdown-mode-version)
(equal markdown-mode-version "2.1"))
(add-hook 'markdown-mode-hook #'font-lock-mode))
;;; Impatient markdown mode
(use-package impatient-mode
:defer t)
(use-package simple-httpd
:defer t
:autoload (httpd-send-header))
(define-minor-mode impatient-markdown-mode
"Markdown rendering for people who lack patience."
:group 'exordium
:lighter "" ;; impatient-mode already has a modeline marker "imp"
:keymap nil
:global nil
;; Body
(cond (impatient-markdown-mode
(start-imp-markdown))
(t
(stop-imp-markdown))))
(defcustom exordium-markdown-file "/tmp/imp-markdown-temp.md"
"Temporary file for markdown rendering."
:group 'exordium
:type 'string)
(defun markdown-to-html (buffer)
"Render markdown in BUFFER as HTML."
(let ((md-file exordium-markdown-file))
(unwind-protect
(progn
(with-temp-file md-file
(kill-region (point-min) (point-max))
(insert (with-current-buffer buffer (buffer-string))))
(shell-command-to-string
(concat markdown-command " " md-file)))
(delete-file md-file))))
(defun imp-markdown-visit-buffer ()
"Visit the buffer in a browser."
(browse-url
(format "http://localhost:%d/imp/live/%s/"
httpd-port (url-hexify-string (buffer-name)))))
(defun start-imp-markdown ()
"Start the impatient mode for markdown and open web browser.
Note that if the web browser wasn't running, Emacs starts it -
you may want to close the browser before Emacs in this
case (Emacs will complain at quit time otherwise)"
(httpd-start)
(impatient-mode 1)
;; Save the old function
(unless (fboundp 'imp--send-state-old)
(defalias 'imp--send-state-old (symbol-function 'imp--send-state)))
;; Define a new function
(defun imp--send-state (proc)
(let ((id (number-to-string imp-last-state))
(buffer (current-buffer)))
(with-temp-buffer
(insert (markdown-to-html buffer))
(httpd-send-header proc "text/html" 200
:Cache-Control "no-cache"
:X-Imp-Count id))))
(imp-markdown-visit-buffer))
(defun stop-imp-markdown ()
"Stop the impatient mode for markdown."
(impatient-mode 0)
(httpd-stop)
;; Restore the old function
(defalias 'imp--send-state 'imp--send-state-old))
(provide 'init-markdown)
;;; init-markdown.el ends here