70

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?

honmaple
  • 889
  • 1
  • 8
  • 12
  • 4
    This isn't a programming question; it's more likely to be on-topic on the [emacs.se] site. – Toby Speight Jul 26 '17 at 16:49
  • I'm voting to close this question as off-topic because it's a general Emacs question, not about writing or compiling programs. – Toby Speight Jul 27 '17 at 11:13
  • 3
    Scroll down a bit and check for the best answer in 2020. I have tested *livedown-mode*, *flymd* and *impatient mode*, and IMHO the one that works better is `grip-mode`. The only drawback is that it has python/pip dependency. – nephewtom Feb 10 '20 at 19:37

7 Answers7

70

There are a few solutions listed here: http://wikemacs.org/wiki/Markdown#Live_preview_as_you_type.

The pure-Emacs (nearly) solution and easy one, requiring no extra library from Python or Nodejs, is impatient-mode.

Impatient-mode

It's designed to work with html but the doc gives a trick to make it work with markdown. It also works like a charm but requires one configuration step:

  • Install impatient-mode with M-x package-install RET impatient-mode RET, given you have configured package.el to use the melpa repository.
  • Start an emacs' web server with M-x httpd-start.
  • Start impatient mode in the buffers you're interested to live preview: M-x impatient-mode.
  • Open your browser to localhost:8080/imp. You'll see the list of buffers with the mode enabled. Click on one: you see live rendering of the buffer.

To enable markdown conversion, we follow wikemacs:

  • Define this elisp function somewhere, like in your init file:

     <!-- language: lang-lisp -->
    
      (defun markdown-html (buffer)
        (princ (with-current-buffer buffer
          (format "<!DOCTYPE html><html><title>Impatient Markdown</title><xmp theme=\"united\" style=\"display:none;\"> %s  </xmp><script src=\"http://ndossougbe.github.io/strapdown/dist/strapdown.js\"></script></html>" (buffer-substring-no-properties (point-min) (point-max))))
        (current-buffer)))
    
  • Tell impatient mode to use it: M-x imp-set-user-filter RET markdown-html RET.

  • Go back to your browser, it works!

livedown-mode (with npm)

https://github.com/shime/emacs-livedown requires the livedown npm package. Also, this emacs package is not in MELPA, you have to clone it locally. Otherwise, it is a good and lightweight solution.

Vmd-mode (npm, Electron)

Another solution is vmd-mode, which works with the vmd node package. This is not the most heavy-weight solution: vmd is based on Electron (!).

Grip-mode (Python, Github's rate limit)

Another one is grip-mode, that relies on a Python package:

pip install --user grip

M-x package-install grip-mode

Then run M-x grip-mode in the markdown buffer. It opens a new tab in your browser.

Unfortunately, at the time of writing, it is limited by Github's rate limit. Indeed, to render content as precisely as Github, it calls its API. It doesn't render content locally. As such we are limited to 60 calls an hour, which is very few. See this issue: https://github.com/joeyespo/grip/issues/35

Fred Liporace
  • 387
  • 4
  • 12
Ehvince
  • 17,274
  • 7
  • 58
  • 79
  • 2
    By the same author, you might want to check skewer-mode https://github.com/skeeto/skewer-mode, which provides live interaction with JavaScript, CSS, and HTML in a web browser ! – Ehvince Mar 23 '16 at 22:15
  • 3
    `impatient-mode` worked beautifully for me! Thanks @Ehvince. – Kellen Murphy Aug 07 '19 at 20:57
  • 2
    flymd doesn't work on Firefox since 68, see https://github.com/mola-T/flymd/issues/27 – kmarsh Dec 11 '19 at 15:53
  • I modified the code slightly to export my org-mode code as markdown and then display it: `defun markdown-html (buffer) (with-current-buffer buffer (org-md-export-as-markdown)) (princ (with-current-buffer "*Org MD Export*" ...`. Works great as long as `org-export-show-temporary-export-buffer` is `nil` – Pakman Jun 18 '20 at 13:39
  • The link to the script seems to be broken now for good, I replaced with `http://ndossougbe.github.io/strapdown/dist/strapdown.js` and got things working again. – Fred Liporace Aug 25 '22 at 18:33
  • When I type into the EMACS markdown buffer, impatient-mode scrolls my internet browser back to the top of the document. I tested the 26-06-2016 version of Strapdown.js without EMACS and the problem does not happen there, but I have to manually refresh the page in my web browser after making changes. How can I get EMACS impatient-mode to stop auto-scrolling my internet browser when I type in a buffer? – Shawn Eary Mar 21 '23 at 16:23
  • @ShawnEary Honestly, all solutions in Emacs to live preview Markdown suck. Use vscode. From a long time Emacs user. – nephewtom Jun 14 '23 at 10:27
  • @nephewtom - VSCode works pretty good, but I have problems navigating back to where I started when I test links: https://superuser.com/questions/1671277/go-back-in-visual-studio-code-when-testing-links-in-markdown-preview – Shawn Eary Jun 20 '23 at 20:24
16

I like this simpler approach that doesn't require another package nor a browser:

  • Execute M-x markdown-other-window on current buffer and display the result in other window.

  • Change to M-x html-mode and hide HTML tags M-x sgml-tags-invisible.

Then to update the html buffer run again markdown-other-window C-c C-c m on the markdown buffer.

Community
  • 1
  • 1
marcanuy
  • 23,118
  • 9
  • 64
  • 113
9

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

Jin
  • 12,748
  • 3
  • 36
  • 41
  • 5
    You can also do this in regular Emacs (At least in `GNU Emacs 26.1`)... Make sure to `brew install markdown` though on Mac – NerdOfCode Jul 10 '19 at 03:21
  • I found `markdown-live-preview-mode` is equivalent to `SPC m c P` instead of `SPC m c p`. Still thanks for sharing the tip. – TSLsun Apr 04 '20 at 13:25
  • In spacemacs, after pressing `SPC m c p` I get the error at the bottom `Markdown command markdown is not found`. Any idea why? – jmrah Feb 07 '21 at 12:20
  • that is a shell program to convert markdown to html. the package depends on that tool. Just install it using apt, pacman, dnf, or whatever your package manager is – onlycparra Feb 28 '22 at 09:30
  • You have to install makdrown package from your system package manager. – Odair Augusto Trujillo Orozco Jan 21 '23 at 23:59
7

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

seagle0128
  • 131
  • 2
  • 3
6

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"))
Saurabh
  • 5,176
  • 4
  • 32
  • 46
  • 2
    This is the most straightforward answer along with the referenced one and it works! I was getting the `Markdown command markdown error` in the mini buffer and could not figure out why – Jav Solo Jul 01 '21 at 16:21
  • After installing with homebrew, `which pandoc` returns `/opt/homebrew/bin/pandoc` obviously –  Apr 21 '22 at 10:09
4

@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 httpd-start
  2. On .md buffer M-x markdown-preview-like-god
  3. Go to localhost:8080/imp
Joakim Elofsson
  • 36,326
  • 1
  • 22
  • 28
FieryCod
  • 1,674
  • 1
  • 19
  • 27
2

You can use my emacs application framework: https://github.com/manateelazycat/emacs-application-framework

It's embed browser in your emacs, then you can write markdown at left side and preview update at right side.

Screenshot at: https://github.com/manateelazycat/emacs-application-framework/blob/master/screenshot/markdown_previewer.gif

How to install eaf please look https://github.com/manateelazycat/emacs-application-framework/blob/master/README.md