How can I preview markdown in Emacs in real time?

Viewed 43821

I'm using spacemacs and I'm looking for a plugin to preview markdown in real time. I have found a plugin markdown-preview-eww, but it requires a gem and I prefer not to install ruby.

The markdown-mode just exports md to html, and it can't preview markdown in real time. Also, I don't like to generate any file without my agreement.

So, is there any plugin to preview markdown in emacs? Or does everyone use org-mode in emacs rather than markdown?

7 Answers

You can now do this in Spacemacs with markdown-live-preview-mode or SPC m c p.

I would like recommend grip-mode: Instant Github-flavored Markdown/Org preview.

Before following the steps in this answer, you would need to have a markdown parser installed on your system and a major mode to associate it to, in emacs.

Add emacs package repository to init.el

(require 'package)
(add-to-list 'package-archives
             '("melpa-stable" . "https://stable.melpa.org/packages/"))
(package-initialize)

Restart emacs and refresh packages:

M-x package-refresh-contents

Install emacs major mode markdown-mode by evaluating:

M-x package-install RET markdown-mode RET

Install markdown processor:

brew install pandoc
OR
sudo apt-get install pandoc

Map the markdown parser to the major-mode in ~/.emacs.d/init.ellike:

(custom-set-variables
  '(markdown-command "/usr/local/bin/pandoc"))

@Ehvince's answer inspired me to a little bit change the markdown-html function to provide exactly the same view as in Github.com.

(defun markdown-html (buffer)
  (princ (with-current-buffer buffer
           (format "<!DOCTYPE html><html><script src=\"https://cdnjs.cloudflare.com/ajax/libs/he/1.1.1/he.js\"></script><link rel=\"stylesheet\" href=\"https://assets-cdn.github.com/assets/github-e6bb18b320358b77abe040d2eb46b547.css\"><link rel=\"stylesheet\" href=\"https://assets-cdn.github.com/assets/frameworks-95aff0b550d3fe338b645a4deebdcb1b.css\"><title>Impatient Markdown</title><div id=\"markdown-content\" style=\"display:none\">%s</div><div class=\"markdown-body\" style=\"max-width:968px;margin:0 auto;\"></div><script>fetch('https://api.github.com/markdown', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ \"text\": document.getElementById('markdown-content').innerHTML, \"mode\": \"gfm\", \"context\": \"knit-pk/homepage-nuxtjs\"}) }).then(response => response.text()).then(response => {document.querySelector('.markdown-body').innerHTML = he.decode(response)}).then(() => { fetch(\"https://gist.githubusercontent.com/FieryCod/b6938b29531b6ec72de25c76fa978b2c/raw/\").then(response => response.text()).then(eval)});</script></html>"
                   (buffer-substring-no-properties (point-min) (point-max))))
         (current-buffer)))

Function which enables the impatient mode and automatically sets the imp-user-filter to markdown-html.

(defun markdown-preview-like-god ()
  (interactive)
  (impatient-mode 1)
  (setq imp-user-filter #'markdown-html)
  (cl-incf imp-last-state)
  (imp--notify-clients))

How to use:

  1. M-x http-start
  2. On .md buffer M-x markdown-preview-like-god
  3. Go to localhost:8080/imp
Related