1 ;;; markdown-mode.el --- Major mode to edit Markdown files in Emacs
3 ;; Copyright (C) 2007-2008 Jason Blevins
6 ;; Keywords: Markdown major mode
7 ;; Author: Jason Blevins <jrblevin@sdf.lonestar.org>
8 ;; URL: http://jblevins.org/projects/markdown-mode
10 ;; This file is not part of GNU Emacs.
12 ;; This program is free software; you can redistribute it and/or modify
13 ;; it under the terms of the GNU General Public License as published by
14 ;; the Free Software Foundation; either version 2, or (at your option)
17 ;; This program is distributed in the hope that it will be useful,
18 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 ;; GNU General Public License for more details.
22 ;; You should have received a copy of the GNU General Public License
23 ;; along with this program; if not, write to the Free Software
24 ;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 ;; markdown-mode is a major mode for editing [Markdown][]-formatted
29 ;; text files in GNU Emacs. markdown-mode is free software, licensed
32 ;; [Markdown]: http://daringfireball.net/projects/markdown/
34 ;; The latest version is markdown-mode 1.5, released on October 11, 2007:
36 ;; * [markdown-mode.el][]
38 ;; * [Release notes][]
40 ;; markdown-mode is also available in the Debian `emacs-goodies-el`
41 ;; package (beginning with revision 27.0-1).
43 ;; [markdown-mode.el]: http://code.jblevins.org/markdown-mode/markdown-mode.el
44 ;; [screenshot]: http://jblevins.org/projects/markdown-mode/screenshots/20071011-001.png
45 ;; [release notes]: http://jblevins.org/projects/markdown-mode/rev-1-5
49 ;; markdown-mode requires easymenu, a standard package since GNU Emacs
50 ;; 19 and XEmacs 19, which provides a uniform interface for creating
51 ;; menus in GNU Emacs and XEmacs.
55 ;; Make sure to place `markdown-mode.el` somewhere in the load-path and add
56 ;; the following lines to your `.emacs` file to associate markdown-mode
57 ;; with `.text` files:
59 ;; (autoload 'markdown-mode "markdown-mode.el"
60 ;; "Major mode for editing Markdown files" t)
61 ;; (setq auto-mode-alist
62 ;; (cons '("\\.text" . markdown-mode) auto-mode-alist))
64 ;; There is no consensus on an official file extension so change `.text` to
65 ;; `.mdwn`, `.md`, `.mdt`, or whatever you call your markdown files.
69 ;; Although no configuration is necessary there are a few things that can
70 ;; be customized (`M-x customize-mode`).
72 ;; Keybindings are grouped by prefixes based on their function. For
73 ;; example, commands dealing with headers begin with `C-c C-t`. The
74 ;; primary commands in each group will are described below. You can
75 ;; obtain a list of all keybindings by pressing `C-c C-h`.
77 ;; * Anchors: `C-c C-a`
79 ;; `C-c C-a l` inserts inline links of the form [text](url). Any text
80 ;; in the region is used for the link text.
82 ;; * Commands: `C-c C-c`
84 ;; `C-c C-c m` will run Markdown on the current buffer and preview the
85 ;; output in another buffer while `C-c C-c p` runs Markdown on the
86 ;; current buffer and previews the output in a browser.
88 ;; * Images: `C-c C-i`
90 ;; `C-c C-i i` inserts an image, using the current region (if any) as
93 ;; * Physical styles: `C-c C-p`
95 ;; These commands all act on text in the selected region, if any, and
96 ;; insert empty markup fragments otherwise. `C-c C-p b` makes the
97 ;; selected text bold, `C-c C-p f` formats the region as fixed-width
98 ;; text, and `C-c C-p i` is used for italic text.
100 ;; * Logical styles: `C-c C-s`
102 ;; These commands all act on text in the selected region, if any, and
103 ;; insert empty markup fragments otherwise. Logical styles include
104 ;; blockquote (`C-c C-s b`), code (`C-c C-s c`),
105 ;; emphasis (`C-c C-s e`), and strong (`C-c C-s s`).
107 ;; * Headers: `C-c C-t`
109 ;; All header commands use text in the region, if any, as the header
110 ;; text. To insert a hash-style level-n header, press `C-c C-t n`
111 ;; where n is between 1 and 5. For a top-level underline-style header
112 ;; press `C-c C-t t` (mnemonic: title) and for a second-level
113 ;; underline-style header press `C-c C-t s` (mnemonic: section).
117 ;; `C-c -` inserts a horizontal rule.
121 ;; Besides supporting the basic Markdown syntax, markdown-mode also
122 ;; includes syntax highlighting for `[[Wiki Links]]` and mathematical
123 ;; expressions written in LaTeX (only expressions denoted by `$..$`,
124 ;; `$$..$$`, or `\[..\]`). To enable these features, edit
125 ;; `markdown-mode.el` and change `(defvar markdown-enable-itex nil)`
126 ;; to`(defvar markdown-enable-itex t)`.
130 ;; * Cyril Brulebois <cyril.brulebois@enst-bretagne.fr> for Debian packaging.
131 ;; * Conal Elliott <conal@conal.net> for a font-lock regexp patch.
132 ;; * Edward O'Connor <hober0@gmail.com> for a font-lock regexp fix.
133 ;; * Greg Bognar <greg_bognar@hms.harvard.edu> for menus and a patch.
134 ;; * Daniel Burrows <dburrows@debian.org> for filing Debian bug #456592.
135 ;; * Peter S. Galbraith <psg@debian.org> for maintaining emacs-goodies-el.
139 ;; This mode has only been tested on Emacs 21.4 and 22.0. Please let me
140 ;; know if there are problems on other versions. If you find any bugs,
141 ;; such as syntax highlighting issues, please construct a test case and
142 ;; email me at <jrblevin@sdf.lonestar.org>.
150 ;;; User Customizable Variables ===============================================
152 ;; To enable itex/wiki syntax highlighting, change to
153 ;; (defvar markdown-enable-itex t)
154 (defvar markdown-enable-itex nil
)
157 ;;; Customizable variables ====================================================
160 (defconst markdown-mode-version
"1.6-dev")
162 ;; A hook for users to run their own code when the mode is loaded.
163 (defvar markdown-mode-hook nil
)
166 ;;; Customizable variables ====================================================
168 (defgroup markdown nil
173 (defcustom markdown-command
"markdown"
174 "Command to run markdown."
178 (defcustom markdown-hr-length
5
179 "Length of horizonal rules."
183 (defcustom markdown-bold-underscore nil
184 "Use two underscores for bold instead of two asterisks."
188 (defcustom markdown-italic-underscore nil
189 "Use underscores for italic instead of asterisks."
194 ;;; Font lock =================================================================
196 ;; Faces ----------------------------------------------------------------------
198 ;; Make new faces based on existing ones
200 ;;; This is not available in Emacs 21 so it has been disabled until
201 ;;; something can be built from scratch. If you are running Emacs 22 and
202 ;;; want to underline line breaks, uncomment this face and the associated
203 ;;; regular expression below.
205 ;(copy-face 'nobreak-space 'markdown-font-lock-line-break-face)
207 (copy-face 'font-lock-variable-name-face
'markdown-font-lock-italic-face
)
208 (copy-face 'font-lock-type-face
'markdown-font-lock-bold-face
)
209 (copy-face 'font-lock-builtin-face
'markdown-font-lock-inline-code-face
)
210 (copy-face 'font-lock-function-name-face
'markdown-font-lock-header-face
)
211 (copy-face 'font-lock-variable-name-face
'markdown-font-lock-list-face
)
212 (copy-face 'font-lock-comment-face
'markdown-font-lock-blockquote-face
)
213 (copy-face 'font-lock-constant-face
'markdown-font-lock-link-face
)
214 (copy-face 'font-lock-type-face
'markdown-font-lock-reference-face
)
215 (copy-face 'font-lock-string-face
'markdown-font-lock-url-face
)
216 (copy-face 'font-lock-builtin-face
'markdown-font-lock-math-face
)
218 ;; Define the extra font lock faces
219 ;(defvar markdown-font-lock-line-break-face 'markdown-font-lock-line-break-face
220 ; "Face name to use for line breaks.")
221 (defvar markdown-font-lock-italic-face
'markdown-font-lock-italic-face
222 "Face name to use for italics.")
223 (defvar markdown-font-lock-bold-face
'markdown-font-lock-bold-face
224 "Face name to use for bold.")
225 (defvar markdown-font-lock-header-face
'markdown-font-lock-header-face
226 "Face name to use for headers.")
227 (defvar markdown-font-lock-inline-code-face
'markdown-font-lock-inline-code-face
228 "Face name to use for inline code.")
229 (defvar markdown-font-lock-list-face
'markdown-font-lock-list-face
230 "Face name to use for list items.")
231 (defvar markdown-font-lock-blockquote-face
'markdown-font-lock-blockquote-face
232 "Face name to use for blockquotes and code blocks.")
233 (defvar markdown-font-lock-link-face
'markdown-font-lock-link-face
234 "Face name to use for links.")
235 (defvar markdown-font-lock-reference-face
'markdown-font-lock-reference-face
236 "Face name to use for references.")
237 (defvar markdown-font-lock-url-face
'markdown-font-lock-url-face
238 "Face name to use for URLs.")
239 (defvar markdown-font-lock-math-face
'markdown-font-lock-math-face
240 "Face name to use for itex expressions.")
242 ;; Regular expressions -------------------------------------------------------
245 (defconst regex-link-inline
"\\(!?\\[.*?\\]\\)\\(([^\\)]*)\\)"
246 "Regular expression for a [text](file) or an image link ![text](file)")
247 (defconst regex-link-reference
"\\(!?\\[.+?\\]\\)[ ]?\\(\\[.*?\\]\\)"
248 "Regular expression for a reference link [text][id]")
249 (defconst regex-reference-definition
250 "^ \\{0,3\\}\\(\\[.+?\\]\\):[ ]?\\(.*?\\)\\(\"[^\"]+?\"\\)?$"
251 "Regular expression for a link definition [id]: ...")
254 (defconst markdown-regex-latex-expression
255 "\\(^\\|[^\\]\\)\\(\\$\\($\\([^\\$]\\|\\\\.\\)*\\$\\|\\([^\\$]\\|\\\\.\\)*\\)\\$\\)"
256 "Regular expression for itex $..$ or $$..$$ math mode expressions")
257 (defconst markdown-regex-latex-display
258 "^\\\\\\[\\(.\\|\n\\)*?\\\\\\]$"
259 "Regular expression for itex \[..\] display mode expressions")
261 (defconst markdown-mode-font-lock-keywords-basic
264 ;;; Code ----------------------------------------------------------
266 ;; Double backtick style ``inline code``
267 (cons "``.+?``" 'markdown-font-lock-inline-code-face
)
268 ;; Single backtick style `inline code`
269 (cons "`.+?`" 'markdown-font-lock-inline-code-face
)
270 ;; Four-space indent style code block
271 (cons "^ .*$" 'markdown-font-lock-blockquote-face
)
273 ;;; Headers and Horizontal Rules ----------------------------------
275 ;; Equals style headers (===)
276 (cons ".*\n===+" 'markdown-font-lock-header-face
)
277 ;; Hyphen style headers (---)
278 (cons ".*\n---+" 'markdown-font-lock-header-face
)
279 ;; Hash style headers (###)
280 (cons "^#+ .*$" 'markdown-font-lock-header-face
)
281 ;; Asterisk style horizontal rules (* * *)
282 (cons "^\\*[ ]?\\*[ ]?\\*[ ]?[\\* ]*$" 'markdown-font-lock-header-face
)
283 ;; Hyphen style horizontal rules (- - -)
284 (cons "^-[ ]?-[ ]?-[--- ]*$" 'markdown-font-lock-header-face
)
286 ;;; Special cases -------------------------------------------------
288 ;; List item including bold
289 (cons "^\\s *\\* .*?[^\\\n]?\\(\\*\\*.*?[^\n\\]\\*\\*\\).*$"
290 '(1 'markdown-font-lock-bold-face
))
291 ;; List item including italics
292 (cons "^\\* .*?[^\\\n]?\\(\\*.*?[^\n\\]\\*\\).*$"
293 '(1 'markdown-font-lock-italic-face
))
295 ;;; Lists ---------------------------------------------------------
297 ;; Numbered lists (1. List item)
298 (cons "^[0-9]+\\.\\s " 'markdown-font-lock-list-face
)
299 ;; Level 1 list item (no indent) (* List item)
300 (cons "^\\(\\*\\|\\+\\|-\\) " '(1 'markdown-font-lock-list-face
))
301 ;; Level 2 list item (two or more spaces) ( * Second level list item)
302 (cons "^ [ ]*\\(\\*\\|\\+\\|-\\) " 'markdown-font-lock-list-face
)
304 ;;; Links ---------------------------------------------------------
306 (cons regex-link-inline
'(1 'markdown-font-lock-link-face t
))
307 (cons regex-link-inline
'(2 'markdown-font-lock-url-face t
))
308 (cons regex-link-reference
'(1 'markdown-font-lock-link-face t
))
309 (cons regex-link-reference
'(2 'markdown-font-lock-reference-face t
))
310 (cons regex-reference-definition
'(1 'markdown-font-lock-reference-face t
))
311 (cons regex-reference-definition
'(2 'markdown-font-lock-url-face t
))
312 (cons regex-reference-definition
'(3 'markdown-font-lock-link-face t
))
314 ;;; Bold ----------------------------------------------------------
316 ;; **Asterisk** and _underscore_ style bold
317 (cons "[^\\]\\(\\(\\*\\*\\|__\\)\\(.\\|\n\\)*?[^\\]\\2\\)"
318 '(1 'markdown-font-lock-bold-face
))
320 ;;; Italic --------------------------------------------------------
322 ;; *Asterisk* and _underscore_ style italic
323 (cons "[^\\]\\(\\(\\*\\|_\\)\\(.\\|\n\\)*?[^\\]\\2\\)"
324 '(1 'markdown-font-lock-italic-face
))
326 ;;; Blockquotes ---------------------------------------------------
328 (cons "^>.*$" 'markdown-font-lock-blockquote-face
)
330 ;;; Hard line breaks ----------------------------------------------
332 ;; Trailing whitespace (two spaces at end of line)
333 ; (cons " $" 'markdown-font-lock-line-break-face)
335 "Syntax highlighting for Markdown files.")
338 ;; Includes additional Latex/itex/Instiki font lock keywords
339 (defconst markdown-mode-font-lock-keywords-itex
343 ;;; itex expressions --------------------------------------------
345 ;; itex math mode $..$ or $$..$$
346 (cons markdown-regex-latex-expression
'(2 markdown-font-lock-math-face
))
347 ;; Display mode equations with brackets: \[ \]
348 (cons markdown-regex-latex-display
'markdown-font-lock-math-face
)
350 ;;; itex equation references ------------------------------------
352 ;; Equation reference (eq:foo)
353 (cons "(eq:\\w+)" 'markdown-font-lock-reference-face
)
354 ;; Equation reference \eqref
355 (cons "\\\\eqref{\\w+}" 'markdown-font-lock-reference-face
)
357 (cons "\\[\\[[^]]+\\]\\]" 'markdown-font-lock-link-face
))
358 markdown-mode-font-lock-keywords-basic
)
359 "Syntax highlighting for Markdown, itex, and wiki expressions.")
362 (defvar markdown-mode-font-lock-keywords
363 (if markdown-enable-itex
364 markdown-mode-font-lock-keywords-itex
365 markdown-mode-font-lock-keywords-basic
)
366 "Default highlighting expressions for Markdown mode")
370 ;;; Syntax Table ==============================================================
372 (defvar markdown-mode-syntax-table
373 (let ((markdown-mode-syntax-table (make-syntax-table)))
374 (modify-syntax-entry ?
\" "w" markdown-mode-syntax-table
)
375 markdown-mode-syntax-table
)
376 "Syntax table for markdown-mode")
380 ;;; Element Insertion =========================================================
382 (defun wrap-or-insert (s1 s2
)
383 "Insert the strings s1 and s2 around the current region or just insert them
384 if there is no region selected."
385 (if (and transient-mark-mode mark-active
)
386 (let ((a (region-beginning)) (b (region-end)))
393 (defun markdown-insert-hr ()
394 "Insert a horizonal rule."
397 (dotimes (count (- markdown-hr-length
1) hr
) ; Count to n - 1
398 (setq hr
(concat "* " hr
))) ; Build HR string
399 (setq hr
(concat hr
"*\n")) ; Add the n-th *
402 (defun markdown-insert-bold ()
403 "Make the active region bold or insert an empty bold word."
405 (if markdown-bold-underscore
406 (wrap-or-insert "__" "__")
407 (wrap-or-insert "**" "**"))
410 (defun markdown-insert-italic ()
411 "Make the active region italic or insert an empty italic word."
413 (if markdown-italic-underscore
414 (wrap-or-insert "_" "_")
415 (wrap-or-insert "*" "*"))
418 (defun markdown-insert-code ()
419 "Format the active region as inline code or insert an empty inline code
422 (wrap-or-insert "`" "`")
425 (defun markdown-insert-link ()
426 "Creates an empty link of the form [](). If there is an active region,
427 this text will be used for the link text."
429 (wrap-or-insert "[" "]")
433 (defun markdown-insert-image ()
434 "Creates an empty image of the form ![](). If there is an active region,
435 this text will be used for the alternate text for the image."
437 (wrap-or-insert "![" "]")
441 (defun markdown-insert-header-1 ()
442 "Creates a level 1 header"
444 (markdown-insert-header 1))
446 (defun markdown-insert-header-2 ()
447 "Creates a level 2 header"
449 (markdown-insert-header 2))
451 (defun markdown-insert-header-3 ()
452 "Creates a level 3 header"
454 (markdown-insert-header 3))
456 (defun markdown-insert-header-4 ()
457 "Creates a level 4 header"
459 (markdown-insert-header 4))
461 (defun markdown-insert-header-5 ()
462 "Creates a level 5 header"
464 (markdown-insert-header 5))
466 (defun markdown-insert-header (n)
467 "Creates a level n header. If there is an active region, it is used as the
470 (unless n
; Test to see if n is defined
471 (setq n
1)) ; Default to level 1 header
473 (dotimes (count n hdr
)
474 (setq hdr
(concat "#" hdr
))) ; Build a ### header string
475 (setq hdrl
(concat hdr
" "))
476 (setq hdrr
(concat " " hdr
))
477 (wrap-or-insert hdrl hdrr
))
478 (backward-char (+ 1 n
)))
480 (defun markdown-insert-title ()
481 "Use the active region to create an \"equals\" style title or insert
482 a blank title and move the cursor to the required position in order to
485 (if (and transient-mark-mode mark-active
)
486 (let ((a (region-beginning))
491 (dotimes (count len hdr
)
492 (setq hdr
(concat "=" hdr
))) ; Build a === title underline
494 (insert "\n" hdr
"\n"))
495 (insert "\n==========\n")
498 (defun markdown-insert-section ()
499 "Use the active region to create a dashed style section or insert
500 a blank section and move the cursor to the required position in order to
503 (if (and transient-mark-mode mark-active
)
504 (let ((a (region-beginning))
509 (dotimes (count len hdr
)
510 (setq hdr
(concat "-" hdr
))) ; Build a --- section underline
512 (insert "\n" hdr
"\n"))
513 (insert "\n----------\n")
516 (defun markdown-insert-blockquote ()
517 "Start a blank blockquote section unless there is an active region, in
518 which case it is turned into a blockquote region."
520 (if (and (boundp 'transient-mark-mode
) transient-mark-mode mark-active
)
521 (markdown-blockquote-region)
524 (defun markdown-blockquote-region (beg end
&optional arg
)
525 "Blockquote the region."
526 (interactive "*r\nP")
528 (perform-replace "^" "> " nil
1 nil nil nil beg end
)))
532 ;;; Keymap ====================================================================
534 (defvar markdown-mode-map
535 (let ((markdown-mode-map (make-keymap)))
537 (define-key markdown-mode-map
"\C-c\C-al" 'markdown-insert-link
)
538 (define-key markdown-mode-map
"\C-c\C-ii" 'markdown-insert-image
)
539 (define-key markdown-mode-map
"\C-c\C-t1" 'markdown-insert-header-1
)
540 (define-key markdown-mode-map
"\C-c\C-t2" 'markdown-insert-header-2
)
541 (define-key markdown-mode-map
"\C-c\C-t3" 'markdown-insert-header-3
)
542 (define-key markdown-mode-map
"\C-c\C-t4" 'markdown-insert-header-4
)
543 (define-key markdown-mode-map
"\C-c\C-t5" 'markdown-insert-header-5
)
544 (define-key markdown-mode-map
"\C-c\C-pb" 'markdown-insert-bold
)
545 (define-key markdown-mode-map
"\C-c\C-ss" 'markdown-insert-bold
)
546 (define-key markdown-mode-map
"\C-c\C-pi" 'markdown-insert-italic
)
547 (define-key markdown-mode-map
"\C-c\C-se" 'markdown-insert-italic
)
548 (define-key markdown-mode-map
"\C-c\C-pf" 'markdown-insert-code
)
549 (define-key markdown-mode-map
"\C-c\C-sc" 'markdown-insert-code
)
550 (define-key markdown-mode-map
"\C-c\C-sb" 'markdown-insert-blockquote
)
551 (define-key markdown-mode-map
"\C-c-" 'markdown-insert-hr
)
552 (define-key markdown-mode-map
"\C-c\C-tt" 'markdown-insert-title
)
553 (define-key markdown-mode-map
"\C-c\C-ts" 'markdown-insert-section
)
554 ;; Markdown functions
555 (define-key markdown-mode-map
"\C-c\C-cm" 'markdown
)
556 (define-key markdown-mode-map
"\C-c\C-cp" 'markdown-preview
)
558 "Keymap for Markdown major mode")
560 ;;; Menu ==================================================================
562 (easy-menu-define markdown-mode-menu markdown-mode-map
563 "Menu for Markdown mode"
566 ["Preview" markdown-preview
]
569 ["Insert Title" markdown-insert-title
]
570 ["Insert Section" markdown-insert-section
])
572 ["First level" markdown-insert-header-1
]
573 ["Second level" markdown-insert-header-2
]
574 ["Third level" markdown-insert-header-3
]
575 ["Fourth level" markdown-insert-header-4
]
576 ["Fifth level" markdown-insert-header-5
])
578 ["Bold" markdown-insert-bold
]
579 ["Italic" markdown-insert-italic
]
580 ["Blockquote" markdown-insert-blockquote
]
581 ["Code" markdown-insert-code
]
583 ["Insert inline link" markdown-insert-link
]
584 ["Insert image" markdown-insert-image
]
585 ["Insert horizontal rule" markdown-insert-hr
]
587 ["Version" markdown-show-version
]
592 ;;; Commands ==================================================================
595 "Run markdown on the current buffer and preview the output in another buffer."
597 (if (and (boundp 'transient-mark-mode
) transient-mark-mode mark-active
)
598 (shell-command-on-region (region-beginning) (region-end) markdown-command
599 "*markdown-output*" nil
)
600 (shell-command-on-region (point-min) (point-max) markdown-command
601 "*markdown-output*" nil
)))
603 (defun markdown-preview ()
604 "Run markdown on the current buffer and preview the output in a browser."
607 (browse-url-of-buffer "*markdown-output*"))
611 ;;; Mode definition ==========================================================
613 (defun markdown-show-version ()
614 "Show the version number in the minibuffer."
616 (message "markdown-mode, version %s" markdown-mode-version
))
618 (define-derived-mode markdown-mode fundamental-mode
"Markdown"
619 "Major mode for editing Markdown files."
621 (set (make-local-variable 'font-lock-defaults
)
622 '(markdown-mode-font-lock-keywords))
623 (set (make-local-variable 'font-lock-multiline
) t
)
624 ;; For menu support in XEmacs
625 (easy-menu-add markdown-mode-menu markdown-mode-map
))
627 ;(add-to-list 'auto-mode-alist '("\\.text$" . markdown-mode))
629 (provide 'markdown-mode
)
631 ;;; markdown-mode.el ends here