Set tab width to 4
[markdown-mode.git] / markdown-mode.el
blobc39ff9502e76a0f1064342248984c7583bfc980e
1 ;;; markdown-mode.el --- Major mode to edit Markdown files in Emacs
3 ;; Copyright (C) 2007, 2008, 2009, 2010, 2011 Jason R. Blevins
4 ;; Copyright (C) 2007, 2009 Edward O'Connor <ted@oconnor.cx>
5 ;; Copyright (C) 2007 Conal Elliott <conal@conal.net>
6 ;; Copyright (C) 2008 Greg Bognar <greg_bognar@hms.harvard.edu>
7 ;; Copyright (C) 2008 Dmitry Dzhus <mail@sphinx.net.ru>
8 ;; Copyright (C) 2008 Bryan Kyle <bryan.kyle@gmail.com>
9 ;; Copyright (C) 2008 Ben Voui <intrigeri@boum.org>
10 ;; Copyright (C) 2009 Ankit Solanki <ankit.solanki@gmail.com>
11 ;; Copyright (C) 2009 Hilko Bengen <bengen@debian.org>
12 ;; Copyright (C) 2009 Peter Williams <pezra@barelyenough.org>
13 ;; Copyright (C) 2010 George Ogata <george.ogata@gmail.com>
14 ;; Copyright (C) 2011 Eric Merritt <ericbmerritt@gmail.com>
15 ;; Copyright (C) 2011 Philippe Ivaldi <pivaldi@sfr.fr>
17 ;; Version: 1.8-dev
18 ;; Keywords: Markdown major mode
19 ;; Author: Jason R. Blevins <jrblevin@sdf.org>
20 ;; URL: http://jblevins.org/projects/markdown-mode/
22 ;; This file is not part of GNU Emacs.
24 ;; This program is free software; you can redistribute it and/or modify
25 ;; it under the terms of the GNU General Public License as published by
26 ;; the Free Software Foundation; either version 2, or (at your option)
27 ;; any later version.
29 ;; This program is distributed in the hope that it will be useful,
30 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
31 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32 ;; GNU General Public License for more details.
34 ;; You should have received a copy of the GNU General Public License
35 ;; along with this program; if not, write to the Free Software
36 ;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
38 ;;; Commentary:
40 ;; markdown-mode is a major mode for editing [Markdown][]-formatted
41 ;; text files in GNU Emacs. markdown-mode is free software, licensed
42 ;; under the GNU GPL.
44 ;; [Markdown]: http://daringfireball.net/projects/markdown/
46 ;; The latest stable version is markdown-mode 1.7, released on October 1, 2009:
48 ;; * [markdown-mode.el][]
49 ;; * [Screenshot][]
50 ;; * [Release notes][]
52 ;; markdown-mode is also available in the Debian
53 ;; [emacs-goodies-el](http://packages.debian.org/emacs-goodies-el)
54 ;; package (beginning with revision 27.0-1) and the OpenBSD
55 ;; [textproc/markdown-mode](http://pkgsrc.se/textproc/markdown-mode) package.
57 ;; [markdown-mode.el]: http://jblevins.org/projects/markdown-mode/markdown-mode.el
58 ;; [screenshot]: http://jblevins.org/projects/markdown-mode/screenshots/20080604-001.png
59 ;; [release notes]: http://jblevins.org/projects/markdown-mode/rev-1-7
61 ;; The latest development version can be downloaded directly
62 ;; ([markdown-mode.el][devel.el]) or it can be obtained from the
63 ;; (browsable and clonable) Git repository at
64 ;; <http://jblevins.org/git/markdown-mode.git>. The entire repository,
65 ;; including the full project history, can be cloned via the Git protocol
66 ;; by running
68 ;; git clone git://jblevins.org/git/markdown-mode.git
70 ;; [devel.el]: http://jblevins.org/git/markdown-mode.git/plain/markdown-mode.el
72 ;;; Dependencies:
74 ;; markdown-mode requires easymenu, a standard package since GNU Emacs
75 ;; 19 and XEmacs 19, which provides a uniform interface for creating
76 ;; menus in GNU Emacs and XEmacs.
78 ;;; Installation:
80 ;; Make sure to place `markdown-mode.el` somewhere in the load-path and add
81 ;; the following lines to your `.emacs` file to associate markdown-mode
82 ;; with `.text` files:
84 ;; (autoload 'markdown-mode "markdown-mode.el"
85 ;; "Major mode for editing Markdown files" t)
86 ;; (setq auto-mode-alist
87 ;; (cons '("\\.text" . markdown-mode) auto-mode-alist))
89 ;; There is no consensus on an official file extension so change `.text` to
90 ;; `.mdwn`, `.md`, `.mdt`, or whatever you call your markdown files.
92 ;;; Customization:
94 ;; Although no configuration is *necessary* there are a few things
95 ;; that can be customized. The `M-x customize-mode` command
96 ;; provides an interface to all of the possible customizations:
98 ;; * `markdown-command' - the command used to run Markdown (default:
99 ;; `markdown'). This variable may be customized to pass
100 ;; command-line options to your Markdown processor of choice, but
101 ;; this command must accept input from `stdin`. If it does not, a
102 ;; simple wrapper script can be used to write `stdin` to a file
103 ;; and then pass that file to your Markdown interpreter. Ideally,
104 ;; this command will produce an XHTML fragment around which
105 ;; markdown-mode will wrap a header and footer (which can be
106 ;; further customized). However, it attempts to detect whether
107 ;; the command produces standalone XHTML output (via
108 ;; `markdown-xhtml-standalone-regexp'), in which case no header
109 ;; and footer content will be added.
111 ;; * `markdown-hr-length' - the length of horizontal rules
112 ;; (default: `5').
114 ;; * `markdown-bold-underscore' - set to a non-nil value to use two
115 ;; underscores for bold instead of two asterisks (default: `nil').
117 ;; * `markdown-italic-underscore' - set to a non-nil value to use
118 ;; underscores for italic instead of asterisks (default: `nil').
120 ;; * `markdown-indent-function' - the function to use for automatic
121 ;; indentation (default: `markdown-indent-line').
123 ;; * `markdown-indent-on-enter' - set to a non-nil value to
124 ;; automatically indent new lines when the enter key is pressed
125 ;; (default: `t')
127 ;; * `markdown-follow-wiki-link-on-enter' - set to a non-nil value
128 ;; to automatically open a linked document in a new buffer if the
129 ;; cursor is an wiki link
130 ;; (default: `t')
132 ;; * `markdown-uri-types' - a list of protocols for URIs that
133 ;; `markdown-mode' should highlight.
135 ;; * `markdown-enable-math' - syntax highlighting for
136 ;; LaTeX fragments (default: `nil').
138 ;; * `markdown-css-path' - CSS file to link to in XHTML output.
140 ;; * `markdown-xhtml-header-content' - additional content to include
141 ;; in the XHTML <head> block.
143 ;; * `markdown-xhtml-standalone-regexp' - a regular expression which
144 ;; indicates whether the output of `markdown-command' is standalone
145 ;; XHTML (default: `^\\(\<\?xml\\|\<!DOCTYPE\\|\<html\\)`). If
146 ;; this is not matched, we assume this output is a fragment and add
147 ;; our own header and footer.
149 ;; Additionally, the faces used for syntax highlighting can be modified to
150 ;; your liking by issuing `M-x customize-group RET markdown-faces`
151 ;; or by using the "Markdown Faces" link at the bottom of the mode
152 ;; customization screen.
154 ;;; Usage:
156 ;; Keybindings are grouped by prefixes based on their function. For
157 ;; example, commands dealing with headers begin with `C-c C-t`. The
158 ;; primary commands in each group will are described below. You can
159 ;; obtain a list of all keybindings by pressing `C-c C-h`.
161 ;; * Anchors: `C-c C-a`
163 ;; `C-c C-a l` inserts inline links of the form `[text](url)`. If
164 ;; there is an active region, text in the region is used for the
165 ;; link text. `C-c C-a w` acts similarly for wiki links of the
166 ;; form `[[WikiLink]]`.
168 ;; * Commands: `C-c C-c`
170 ;; `C-c C-c m` will run Markdown on the current buffer and preview
171 ;; the output in another buffer while `C-c C-c p` runs Markdown on
172 ;; the current buffer and previews the output in a browser.
173 ;; `C-c C-c e` will run Markdown on the current buffer and save
174 ;; the result in the file `basename.html`, where `basename` is the
175 ;; name of the Markdown file with the extension removed. **This
176 ;; file will be overwritten without notice.** Press `C-c C-c v`
177 ;; to view the exported file in a browser.
179 ;; `C-c C-c c` will check for undefined references. If there are
180 ;; any, a small buffer will open with a list of undefined
181 ;; references and the line numbers on which they appear. In Emacs
182 ;; 22 and greater, selecting a reference from this list and
183 ;; pressing `RET` will insert an empty reference definition at the
184 ;; end of the buffer. Similarly, selecting the line number will
185 ;; jump to the corresponding line.
187 ;; * Images: `C-c C-i`
189 ;; `C-c C-i i` inserts an image, using the active region (if any)
190 ;; as the alt text.
192 ;; * Physical styles: `C-c C-p`
194 ;; These commands all act on text in the active region, if any,
195 ;; and insert empty markup fragments otherwise. `C-c C-p b` makes
196 ;; the selected text bold, `C-c C-p f` formats the region as
197 ;; fixed-width text, and `C-c C-p i` is used for italic text.
199 ;; * Logical styles: `C-c C-s`
201 ;; These commands all act on text in the active region, if any,
202 ;; and insert empty markup fragments otherwise. Logical styles
203 ;; include blockquote (`C-c C-s b`), preformatted (`C-c C-s p`),
204 ;; code (`C-c C-s c`), emphasis (`C-c C-s e`), and strong (`C-c
205 ;; C-s s`).
207 ;; * Headers: `C-c C-t`
209 ;; All header commands use text in the active region, if any, as
210 ;; the header text. To insert an atx or hash style level-n
211 ;; header, press `C-c C-t n` where n is between 1 and 6. For a
212 ;; top-level setext or underline style header press `C-c C-t t`
213 ;; (mnemonic: title) and for a second-level underline-style header
214 ;; press `C-c C-t s` (mnemonic: section).
216 ;; * Other commands
218 ;; `C-c -` inserts a horizontal rule.
220 ;; Many of the commands described above behave differently depending on
221 ;; whether Transient Mark mode is enabled or not. When it makes sense,
222 ;; if Transient Mark mode is on and a region is active, the command
223 ;; applies to the text in the region (e.g., `C-c C-p b` makes the region
224 ;; bold). For users who prefer to work outside of Transient Mark mode,
225 ;; in Emacs 22 it can be enabled temporarily by pressing `C-SPC C-SPC`.
227 ;; When applicable, commands that specifically act on the region even
228 ;; outside of Transient Mark mode have the same keybinding as the with
229 ;; the exception of an additional `C-` prefix. For example,
230 ;; `markdown-insert-blockquote' is bound to `C-c C-s b` and only acts on
231 ;; the region in Transient Mark mode while `markdown-blockquote-region'
232 ;; is bound to `C-c C-s C-b` and always applies to the region (when
233 ;; nonempty).
235 ;; markdown-mode supports outline-minor-mode as well as org-mode-style
236 ;; visibility cycling for atx- or hash-style headers. There are two
237 ;; types of visibility cycling: Pressing `S-TAB` cycles globally between
238 ;; the table of contents view (headers only), outline view (top-level
239 ;; headers only), and the full document view. Pressing `TAB` while the
240 ;; point is at a header will cycle through levels of visibility for the
241 ;; subtree: completely folded, visible children, and fully visible.
242 ;; Note that mixing hash and underline style headers will give undesired
243 ;; results.
245 ;;; Extensions:
247 ;; Besides supporting the basic Markdown syntax, markdown-mode also
248 ;; includes syntax highlighting for `[[Wiki Links]]` by default. Wiki
249 ;; links may be followed automatically by hitting the enter key when
250 ;; your curser is on a wiki link or by hitting `C-c C-f`. The
251 ;; autofollowing on enter key may be controlled with the
252 ;; `markdown-follow-wiki-link-on-enter' customization. Use `M-p` and
253 ;; `M-n` to quickly jump to the previous and next wiki links,
254 ;; respectively.
256 ;; [SmartyPants][] support is possible by customizing `markdown-command'.
257 ;; If you install `SmartyPants.pl` at, say, `/usr/local/bin/smartypants`,
258 ;; then you can set `markdown-command' to `"markdown | smartypants"`.
259 ;; You can do this either by using `M-x customize-group markdown`
260 ;; or by placing the following in your `.emacs` file:
262 ;; (defun markdown-custom ()
263 ;; "markdown-mode-hook"
264 ;; (setq markdown-command "markdown | smartypants"))
265 ;; (add-hook 'markdown-mode-hook '(lambda() (markdown-custom)))
267 ;; [SmartyPants]: http://daringfireball.net/projects/smartypants/
269 ;; Experimental syntax highlighting for mathematical expressions written
270 ;; in LaTeX (only expressions denoted by `$..$`, `$$..$$`, or `\[..\]`)
271 ;; can be enabled by setting `markdown-enable-math' to a non-nil value,
272 ;; either via customize or by placing `(setq markdown-enable-itex t)`
273 ;; in `.emacs`, and restarting Emacs.
275 ;; A [GitHub Flavored Markdown](http://github.github.com/github-flavored-markdown/)
276 ;; mode, `gfm-mode', is also available. The GitHub implementation of
277 ;; differs slightly from standard Markdown. Most importantly, newlines are
278 ;; significant and trigger hard line breaks. As such, `gfm-mode' turns off
279 ;; `auto-fill-mode' and turns on `longlines-mode'.
281 ;;; Acknowledgments:
283 ;; markdown-mode has benefited greatly from the efforts of the
284 ;; following people:
286 ;; * Cyril Brulebois <cyril.brulebois@enst-bretagne.fr> for Debian packaging.
287 ;; * Conal Elliott <conal@conal.net> for a font-lock regexp patch.
288 ;; * Edward O'Connor <hober0@gmail.com> for a font-lock regexp fix and
289 ;; GitHub Flavored Markdown mode (`gfm-mode').
290 ;; * Greg Bognar <greg_bognar@hms.harvard.edu> for menus and running
291 ;; `markdown' with an active region.
292 ;; * Daniel Burrows <dburrows@debian.org> for filing Debian bug #456592.
293 ;; * Peter S. Galbraith <psg@debian.org> for maintaining emacs-goodies-el.
294 ;; * Dmitry Dzhus <mail@sphinx.net.ru> for reference checking functions.
295 ;; * Bryan Kyle <bryan.kyle@gmail.com> for indentation code.
296 ;; * Ben Voui <intrigeri@boum.org> for font-lock face customizations.
297 ;; * Ankit Solanki <ankit.solanki@gmail.com> for longlines.el
298 ;; compatibility and custom CSS.
299 ;; * Hilko Bengen <bengen@debian.org> for proper XHTML output.
300 ;; * Jose A. Ortega Ruiz <jao@gnu.org> for Emacs 23 fixes.
301 ;; * Alec Resnick <alec@sproutward.org> for bug reports.
302 ;; * Joost Kremers <j.kremers@em.uni-frankfurt.de> for bug reports
303 ;; regarding indentation.
304 ;; * Peter Williams <pezra@barelyenough.org> for fill-paragraph
305 ;; enhancements.
306 ;; * George Ogata <george.ogata@gmail.com> for fixing several
307 ;; byte-compilation warnings.
308 ;; * Eric Merritt <ericbmerritt@gmail.com> for wiki link features.
309 ;; * Philippe Ivaldi <pivaldi@sfr.fr> for XHTML preview
310 ;; customizations and XHTML export.
312 ;;; Bugs:
314 ;; Although markdown-mode is developed and tested primarily using
315 ;; GNU Emacs 24, compatibility with earlier Emacsen is also a
316 ;; priority.
318 ;; markdown-mode's syntax highlighting is accomplished using the
319 ;; search-based fontification features of Emacs through a series of
320 ;; regular expressions. Unfortunately, Emacs has trouble highlighting
321 ;; multi-line constructs using regular expressions and this creates
322 ;; several syntax-highlighting quirks such as mistaking indented
323 ;; lists for preformatted text, etc. Making markdown-mode's syntax
324 ;; highlighting more robust through the use of matching functions
325 ;; or syntactic font lock is a high-priority item for future work.
327 ;; If you find any bugs not mentioned here, please construct a test
328 ;; case and/or a patch and email me at <jrblevin@sdf.org>.
330 ;;; History:
332 ;; markdown-mode was written and is maintained by Jason Blevins. The
333 ;; first version was released on May 24, 2007.
335 ;; * 2007-05-24: Version 1.1
336 ;; * 2007-05-25: Version 1.2
337 ;; * 2007-06-05: [Version 1.3][]
338 ;; * 2007-06-29: Version 1.4
339 ;; * 2008-05-24: [Version 1.5][]
340 ;; * 2008-06-04: [Version 1.6][]
341 ;; * 2009-10-01: [Version 1.7][]
343 ;; [Version 1.3]: http://jblevins.org/projects/markdown-mode/rev-1-3
344 ;; [Version 1.5]: http://jblevins.org/projects/markdown-mode/rev-1-5
345 ;; [Version 1.6]: http://jblevins.org/projects/markdown-mode/rev-1-6
346 ;; [Version 1.7]: http://jblevins.org/projects/markdown-mode/rev-1-7
349 ;;; Code:
351 (require 'easymenu)
352 (require 'outline)
354 ;;; Constants =================================================================
356 (defconst markdown-mode-version "1.7-dev"
357 "Markdown mode version number.")
359 (defconst markdown-output-buffer-name "*markdown-output*"
360 "Name of temporary buffer for markdown command output.")
362 ;;; Customizable variables ====================================================
364 (defvar markdown-mode-hook nil
365 "Hook runs when Markdown mode is loaded.")
367 (defgroup markdown nil
368 "Major mode for editing text files in Markdown format."
369 :prefix "markdown-"
370 :group 'wp
371 :link '(url-link "http://jblevins.org/projects/markdown-mode/"))
373 (defcustom markdown-command "markdown"
374 "Command to run markdown."
375 :group 'markdown
376 :type 'string)
378 (defcustom markdown-hr-length 5
379 "Length of horizonal rules."
380 :group 'markdown
381 :type 'integer)
383 (defcustom markdown-bold-underscore nil
384 "Use two underscores for bold instead of two asterisks."
385 :group 'markdown
386 :type 'boolean)
388 (defcustom markdown-italic-underscore nil
389 "Use underscores for italic instead of asterisks."
390 :group 'markdown
391 :type 'boolean)
393 (defcustom markdown-indent-function 'markdown-indent-line
394 "Function to use to indent."
395 :group 'markdown
396 :type 'function)
398 (defcustom markdown-indent-on-enter t
399 "Automatically indent new lines when enter key is pressed."
400 :group 'markdown
401 :type 'boolean)
403 (defcustom markdown-follow-wiki-link-on-enter t
404 "Follow wiki link at point (if any) when the enter key is pressed."
405 :group 'markdown
406 :type 'boolean)
408 (defcustom markdown-uri-types
409 '("acap" "cid" "data" "dav" "fax" "file" "ftp" "gopher" "http" "https"
410 "imap" "ldap" "mailto" "mid" "modem" "news" "nfs" "nntp" "pop" "prospero"
411 "rtsp" "service" "sip" "tel" "telnet" "tip" "urn" "vemmi" "wais")
412 "Link types for syntax highlighting of URIs."
413 :group 'markdown
414 :type 'list)
416 (defcustom markdown-enable-math nil
417 "Syntax highlighting for inline LaTeX expressions.
418 This will not take effect until Emacs is restarted."
419 :group 'markdown
420 :type 'boolean)
422 (defcustom markdown-css-path ""
423 "URL of CSS file to link to in the output XHTML."
424 :group 'markdown
425 :type 'string)
427 (defcustom markdown-xhtml-header-content ""
428 "Additional content to include in the XHTML <head> block."
429 :group 'markdown
430 :type 'string)
432 (defcustom markdown-xhtml-standalone-regexp
433 "^\\(\<\?xml\\|\<!DOCTYPE\\|\<html\\)"
434 "Regexp indicating whether `markdown-command' output is standalone XHTML."
435 :group 'markdown
436 :type 'regexp)
438 ;;; Font lock =================================================================
440 (require 'font-lock)
442 (defvar markdown-italic-face 'markdown-italic-face
443 "Face name to use for italic text.")
445 (defvar markdown-bold-face 'markdown-bold-face
446 "Face name to use for bold text.")
448 (defvar markdown-header-face 'markdown-header-face
449 "Face name to use as a base for headers.")
451 (defvar markdown-header-face-1 'markdown-header-face-1
452 "Face name to use for level-1 headers.")
454 (defvar markdown-header-face-2 'markdown-header-face-2
455 "Face name to use for level-2 headers.")
457 (defvar markdown-header-face-3 'markdown-header-face-3
458 "Face name to use for level-3 headers.")
460 (defvar markdown-header-face-4 'markdown-header-face-4
461 "Face name to use for level-4 headers.")
463 (defvar markdown-header-face-5 'markdown-header-face-5
464 "Face name to use for level-5 headers.")
466 (defvar markdown-header-face-6 'markdown-header-face-6
467 "Face name to use for level-6 headers.")
469 (defvar markdown-inline-code-face 'markdown-inline-code-face
470 "Face name to use for inline code.")
472 (defvar markdown-list-face 'markdown-list-face
473 "Face name to use for list markers.")
475 (defvar markdown-blockquote-face 'markdown-blockquote-face
476 "Face name to use for blockquote.")
478 (defvar markdown-pre-face 'markdown-pre-face
479 "Face name to use for preformatted text.")
481 (defvar markdown-link-face 'markdown-link-face
482 "Face name to use for links.")
484 (defvar markdown-missing-link-face 'markdown-missing-link-face
485 "Face name to use for links where the linked file does not exist.")
487 (defvar markdown-reference-face 'markdown-reference-face
488 "Face name to use for reference.")
490 (defvar markdown-url-face 'markdown-url-face
491 "Face name to use for URLs.")
493 (defvar markdown-link-title-face 'markdown-link-title-face
494 "Face name to use for reference link titles.")
496 (defvar markdown-comment-face 'markdown-comment-face
497 "Face name to use for HTML comments.")
499 (defvar markdown-math-face 'markdown-math-face
500 "Face name to use for LaTeX expressions.")
502 (defgroup markdown-faces nil
503 "Faces used in Markdown Mode"
504 :group 'markdown
505 :group 'faces)
507 (defface markdown-italic-face
508 '((t :inherit font-lock-variable-name-face :italic t))
509 "Face for italic text."
510 :group 'markdown-faces)
512 (defface markdown-bold-face
513 '((t :inherit font-lock-variable-name-face :bold t))
514 "Face for bold text."
515 :group 'markdown-faces)
517 (defface markdown-header-face
518 '((t :inherit font-lock-function-name-face :weight bold))
519 "Base face for headers."
520 :group 'markdown-faces)
522 (defface markdown-header-face-1
523 '((t :inherit markdown-header-face))
524 "Face for level-1 headers."
525 :group 'markdown-faces)
527 (defface markdown-header-face-2
528 '((t :inherit markdown-header-face))
529 "Face for level-2 headers."
530 :group 'markdown-faces)
532 (defface markdown-header-face-3
533 '((t :inherit markdown-header-face))
534 "Face for level-3 headers."
535 :group 'markdown-faces)
537 (defface markdown-header-face-4
538 '((t :inherit markdown-header-face))
539 "Face for level-4 headers."
540 :group 'markdown-faces)
542 (defface markdown-header-face-5
543 '((t :inherit markdown-header-face))
544 "Face for level-5 headers."
545 :group 'markdown-faces)
547 (defface markdown-header-face-6
548 '((t :inherit markdown-header-face))
549 "Face for level-6 headers."
550 :group 'markdown-faces)
552 (defface markdown-inline-code-face
553 '((t :inherit font-lock-constant-face))
554 "Face for inline code."
555 :group 'markdown-faces)
557 (defface markdown-list-face
558 '((t :inherit font-lock-builtin-face))
559 "Face for list item markers."
560 :group 'markdown-faces)
562 (defface markdown-blockquote-face
563 '((t :inherit font-lock-doc-face))
564 "Face for blockquote sections."
565 :group 'markdown-faces)
567 (defface markdown-pre-face
568 '((t :inherit font-lock-constant-face))
569 "Face for preformatted text."
570 :group 'markdown-faces)
572 (defface markdown-link-face
573 '((t :inherit font-lock-keyword-face))
574 "Face for links."
575 :group 'markdown-faces)
577 (defface markdown-missing-link-face
578 '((t :inherit font-lock-warning-face))
579 "Face for missing links."
580 :group 'markdown-faces)
582 (defface markdown-reference-face
583 '((t :inherit font-lock-type-face))
584 "Face for link references."
585 :group 'markdown-faces)
587 (defface markdown-url-face
588 '((t :inherit font-lock-string-face))
589 "Face for URLs."
590 :group 'markdown-faces)
592 (defface markdown-link-title-face
593 '((t :inherit font-lock-comment-face))
594 "Face for reference link titles."
595 :group 'markdown-faces)
597 (defface markdown-comment-face
598 '((t :inherit font-lock-comment-face))
599 "Face for HTML comments."
600 :group 'markdown-faces)
602 (defface markdown-math-face
603 '((t :inherit font-lock-string-face))
604 "Face for LaTeX expressions."
605 :group 'markdown-faces)
607 (defconst markdown-regex-link-inline
608 "\\(!?\\[[^]]*?\\]\\)\\(([^\\)]*)\\)"
609 "Regular expression for a [text](file) or an image link ![text](file).")
611 (defconst markdown-regex-link-reference
612 "\\(!?\\[[^]]+?\\]\\)[ ]?\\(\\[[^]]*?\\]\\)"
613 "Regular expression for a reference link [text][id].")
615 (defconst markdown-regex-reference-definition
616 "^ \\{0,3\\}\\(\\[.+?\\]\\):\\s *\\(.*?\\)\\s *\\( \"[^\"]*\"$\\|$\\)"
617 "Regular expression for a link definition [id]: ...")
619 (defconst markdown-regex-header-1-atx
620 "^\\(# \\)\\(.*?\\)\\($\\| #+$\\)"
621 "Regular expression for level 1 atx-style (hash mark) headers.")
623 (defconst markdown-regex-header-2-atx
624 "^\\(## \\)\\(.*?\\)\\($\\| #+$\\)"
625 "Regular expression for level 2 atx-style (hash mark) headers.")
627 (defconst markdown-regex-header-3-atx
628 "^\\(### \\)\\(.*?\\)\\($\\| #+$\\)"
629 "Regular expression for level 3 atx-style (hash mark) headers.")
631 (defconst markdown-regex-header-4-atx
632 "^\\(#### \\)\\(.*?\\)\\($\\| #+$\\)"
633 "Regular expression for level 4 atx-style (hash mark) headers.")
635 (defconst markdown-regex-header-5-atx
636 "^\\(##### \\)\\(.*?\\)\\($\\| #+$\\)"
637 "Regular expression for level 5 atx-style (hash mark) headers.")
639 (defconst markdown-regex-header-6-atx
640 "^\\(###### \\)\\(.*?\\)\\($\\| #+$\\)"
641 "Regular expression for level 6 atx-style (hash mark) headers.")
643 (defconst markdown-regex-header-1-setext
644 "^\\(.*\\)\n\\(===+\\)$"
645 "Regular expression for level 1 setext-style (underline) headers.")
647 (defconst markdown-regex-header-2-setext
648 "^\\(.*\\)\n\\(---+\\)$"
649 "Regular expression for level 2 setext-style (underline) headers.")
651 (defconst markdown-regex-hr
652 "^\\(\\*[ ]?\\*[ ]?\\*[ ]?[\\* ]*\\|-[ ]?-[ ]?-[--- ]*\\)$"
653 "Regular expression for matching Markdown horizontal rules.")
655 (defconst markdown-regex-code
656 "\\(^\\|[^\\]\\)\\(\\(`\\{1,2\\}\\)\\([^ \\]\\|[^ ].*?[^ \\]\\)\\3\\)"
657 "Regular expression for matching inline code fragments.")
659 (defconst markdown-regex-pre
660 "^\\( \\|\t\\).*$"
661 "Regular expression for matching preformatted text sections.")
663 (defconst markdown-regex-list
664 "^[ \t]*\\([0-9]+\\.\\|[\\*\\+-]\\) "
665 "Regular expression for matching list markers.")
667 (defconst markdown-regex-bold
668 "\\(^\\|[^\\]\\)\\(\\([*_]\\{2\\}\\)\\(.\\|\n\\)*?[^\\ ]\\3\\)"
669 "Regular expression for matching bold text.")
671 (defconst markdown-regex-italic
672 "\\(^\\|[^\\]\\)\\(\\([*_]\\)\\([^ \\]\\3\\|[^ ]\\(.\\|\n\\)*?[^\\ ]\\3\\)\\)"
673 "Regular expression for matching italic text.")
675 (defconst markdown-regex-blockquote
676 "^>.*$"
677 "Regular expression for matching blockquote lines.")
679 (defconst markdown-regex-line-break
680 " $"
681 "Regular expression for matching line breaks.")
683 (defconst markdown-regex-wiki-link
684 "\\[\\[\\([^]]+\\)\\]\\]"
685 "Regular expression for matching wiki links.")
687 (defconst markdown-regex-uri
688 (concat
689 "\\(" (mapconcat 'identity markdown-uri-types "\\|")
690 "\\):[^]\t\n\r<>,;() ]+")
691 "Regular expression for matching inline URIs.")
693 (defconst markdown-regex-angle-uri
694 (concat
695 "\\(<\\)\\("
696 (mapconcat 'identity markdown-uri-types "\\|")
697 "\\):[^]\t\n\r<>,;()]+\\(>\\)")
698 "Regular expression for matching inline URIs in angle brackets.")
700 (defconst markdown-regex-email
701 "<\\(\\sw\\|\\s_\\|\\s.\\)+@\\(\\sw\\|\\s_\\|\\s.\\)+>"
702 "Regular expression for matching inline email addresses.")
704 (defconst markdown-regex-latex-expression
705 "\\(^\\|[^\\]\\)\\(\\$\\($\\([^\\$]\\|\\\\.\\)*\\$\\|\\([^\\$]\\|\\\\.\\)*\\)\\$\\)"
706 "Regular expression for itex $..$ or $$..$$ math mode expressions.")
708 (defconst markdown-regex-latex-display
709 "^\\\\\\[\\(.\\|\n\\)*?\\\\\\]$"
710 "Regular expression for itex \[..\] display mode expressions.")
712 (defconst markdown-regex-list-indent
713 "^\\(\\s *\\)\\([0-9]+\\.\\|[\\*\\+-]\\)\\(\\s +\\)"
714 "Regular expression for matching indentation of list items.")
716 (defvar markdown-mode-font-lock-keywords-basic
717 (list
718 '(markdown-match-comments 0 markdown-comment-face t t)
719 (cons markdown-regex-code '(2 markdown-inline-code-face))
720 (cons markdown-regex-pre 'markdown-pre-face)
721 (cons markdown-regex-blockquote 'markdown-blockquote-face)
722 (cons markdown-regex-header-1-setext 'markdown-header-face-1)
723 (cons markdown-regex-header-2-setext 'markdown-header-face-2)
724 (cons markdown-regex-header-1-atx 'markdown-header-face-1)
725 (cons markdown-regex-header-2-atx 'markdown-header-face-2)
726 (cons markdown-regex-header-3-atx 'markdown-header-face-3)
727 (cons markdown-regex-header-4-atx 'markdown-header-face-4)
728 (cons markdown-regex-header-5-atx 'markdown-header-face-5)
729 (cons markdown-regex-header-6-atx 'markdown-header-face-6)
730 (cons markdown-regex-hr 'markdown-header-face)
731 (cons markdown-regex-list 'markdown-list-face)
732 (cons markdown-regex-link-inline
733 '((1 markdown-link-face t)
734 (2 markdown-url-face t)))
735 (cons markdown-regex-link-reference
736 '((1 markdown-link-face t)
737 (2 markdown-reference-face t)))
738 (cons markdown-regex-reference-definition
739 '((1 markdown-reference-face t)
740 (2 markdown-url-face t)
741 (3 markdown-link-title-face t)))
742 (cons markdown-regex-bold '(2 markdown-bold-face))
743 (cons markdown-regex-italic '(2 markdown-italic-face))
744 (cons markdown-regex-angle-uri 'markdown-link-face)
745 (cons markdown-regex-uri 'markdown-link-face)
746 (cons markdown-regex-email 'markdown-link-face)
748 "Syntax highlighting for Markdown files.")
750 (defconst markdown-mode-font-lock-keywords-latex
751 (list
752 ;; Math mode $..$ or $$..$$
753 (cons markdown-regex-latex-expression '(2 markdown-math-face))
754 ;; Display mode equations with brackets: \[ \]
755 (cons markdown-regex-latex-display 'markdown-math-face)
756 ;; Equation reference (eq:foo)
757 (cons "(eq:\\w+)" 'markdown-reference-face)
758 ;; Equation reference \eqref{foo}
759 (cons "\\\\eqref{\\w+}" 'markdown-reference-face))
760 "Syntax highlighting for LaTeX fragments.")
762 (defvar markdown-mode-font-lock-keywords
763 (append
764 (if markdown-enable-math
765 markdown-mode-font-lock-keywords-latex)
766 markdown-mode-font-lock-keywords-basic)
767 "Default highlighting expressions for Markdown mode.")
771 ;;; Markdown parsing functions ================================================
773 (defun markdown-prev-line-blank-p ()
774 "Return t if the previous line is blank and nil otherwise."
775 (save-excursion
776 (forward-line -1)
777 (goto-char (point-at-bol))
778 (if (re-search-forward "^\\s *$" (point-at-eol) t) t)))
780 (defun markdown-prev-line-indent-p ()
781 "Return t if the previous line is indented and nil otherwise."
782 (save-excursion
783 (forward-line -1)
784 (goto-char (point-at-bol))
785 (if (re-search-forward "^\\s " (point-at-eol) t) t)))
787 (defun markdown-cur-line-indent ()
788 "Return the number of leading whitespace characters in the current line."
789 (save-excursion
790 (goto-char (point-at-bol))
791 (re-search-forward "^\\s +" (point-at-eol) t)
792 (current-column)))
794 (defun markdown-prev-line-indent ()
795 "Return the number of leading whitespace characters in the previous line."
796 (save-excursion
797 (forward-line -1)
798 (markdown-cur-line-indent)))
800 (defun markdown-prev-non-list-indent ()
801 "Return position of the first non-list-marker on the previous line."
802 (save-excursion
803 (forward-line -1)
804 (goto-char (point-at-bol))
805 (when (re-search-forward markdown-regex-list-indent (point-at-eol) t)
806 (current-column))))
808 ; From html-helper-mode
809 (defun markdown-match-comments (last)
810 "Match HTML comments from the point to LAST."
811 (cond ((search-forward "<!--" last t)
812 (backward-char 4)
813 (let ((beg (point)))
814 (cond ((search-forward-regexp "--[ \t]*>" last t)
815 (set-match-data (list beg (point)))
817 (t nil))))
818 (t nil)))
822 ;;; Syntax Table ==============================================================
824 (defvar markdown-mode-syntax-table
825 (let ((markdown-mode-syntax-table (make-syntax-table)))
826 (modify-syntax-entry ?\" "w" markdown-mode-syntax-table)
827 markdown-mode-syntax-table)
828 "Syntax table for `markdown-mode'.")
832 ;;; Element Insertion =========================================================
834 (defun markdown-wrap-or-insert (s1 s2)
835 "Insert the strings S1 and S2.
836 If Transient Mark mode is on and a region is active, wrap the strings S1
837 and S2 around the region."
838 (if (and transient-mark-mode mark-active)
839 (let ((a (region-beginning)) (b (region-end)))
840 (goto-char a)
841 (insert s1)
842 (goto-char (+ b (length s1)))
843 (insert s2))
844 (insert s1 s2)))
846 (defun markdown-insert-hr ()
847 "Insert a horizonal rule."
848 (interactive)
849 (let (hr)
850 (dotimes (count (- markdown-hr-length 1) hr) ; Count to n - 1
851 (setq hr (concat "* " hr))) ; Build HR string
852 (setq hr (concat hr "*\n")) ; Add the n-th *
853 (insert hr)))
855 (defun markdown-insert-bold ()
856 "Insert markup for a bold word or phrase.
857 If Transient Mark mode is on and a region is active, it is made bold."
858 (interactive)
859 (if markdown-bold-underscore
860 (markdown-wrap-or-insert "__" "__")
861 (markdown-wrap-or-insert "**" "**"))
862 (backward-char 2))
864 (defun markdown-insert-italic ()
865 "Insert markup for an italic word or phrase.
866 If Transient Mark mode is on and a region is active, it is made italic."
867 (interactive)
868 (if markdown-italic-underscore
869 (markdown-wrap-or-insert "_" "_")
870 (markdown-wrap-or-insert "*" "*"))
871 (backward-char 1))
873 (defun markdown-insert-code ()
874 "Insert markup for an inline code fragment.
875 If Transient Mark mode is on and a region is active, it is marked
876 as inline code."
877 (interactive)
878 (markdown-wrap-or-insert "`" "`")
879 (backward-char 1))
881 (defun markdown-insert-link ()
882 "Insert an inline link of the form []().
883 If Transient Mark mode is on and a region is active, it is used
884 as the link text."
885 (interactive)
886 (markdown-wrap-or-insert "[" "]")
887 (insert "()")
888 (backward-char 1))
890 (defun markdown-insert-wiki-link ()
891 "Insert a wiki link of the form [[WikiLink]].
892 If Transient Mark mode is on and a region is active, it is used
893 as the link text."
894 (interactive)
895 (markdown-wrap-or-insert "[[" "]]")
896 (backward-char 2))
898 (defun markdown-insert-image ()
899 "Insert an inline image tag of the form ![]().
900 If Transient Mark mode is on and a region is active, it is used
901 as the alt text of the image."
902 (interactive)
903 (markdown-wrap-or-insert "![" "]")
904 (insert "()")
905 (backward-char 1))
907 (defun markdown-insert-header-1 ()
908 "Insert a first level atx-style (hash mark) header.
909 If Transient Mark mode is on and a region is active, it is used
910 as the header text."
911 (interactive)
912 (markdown-insert-header 1))
914 (defun markdown-insert-header-2 ()
915 "Insert a second level atx-style (hash mark) header.
916 If Transient Mark mode is on and a region is active, it is used
917 as the header text."
918 (interactive)
919 (markdown-insert-header 2))
921 (defun markdown-insert-header-3 ()
922 "Insert a third level atx-style (hash mark) header.
923 If Transient Mark mode is on and a region is active, it is used
924 as the header text."
925 (interactive)
926 (markdown-insert-header 3))
928 (defun markdown-insert-header-4 ()
929 "Insert a fourth level atx-style (hash mark) header.
930 If Transient Mark mode is on and a region is active, it is used
931 as the header text."
932 (interactive)
933 (markdown-insert-header 4))
935 (defun markdown-insert-header-5 ()
936 "Insert a fifth level atx-style (hash mark) header.
937 If Transient Mark mode is on and a region is active, it is used
938 as the header text."
939 (interactive)
940 (markdown-insert-header 5))
942 (defun markdown-insert-header-6 ()
943 "Insert a sixth level atx-style (hash mark) header.
944 If Transient Mark mode is on and a region is active, it is used
945 as the header text."
946 (interactive)
947 (markdown-insert-header 6))
949 (defun markdown-insert-header (n)
950 "Insert an atx-style (hash mark) header.
951 With no prefix argument, insert a level-1 header. With prefix N,
952 insert a level-N header. If Transient Mark mode is on and the
953 region is active, it is used as the header text."
954 (interactive "p")
955 (unless n ; Test to see if n is defined
956 (setq n 1)) ; Default to level 1 header
957 (let (hdr hdrl hdrr)
958 (dotimes (count n hdr)
959 (setq hdr (concat "#" hdr))) ; Build a hash mark header string
960 (setq hdrl (concat hdr " "))
961 (setq hdrr (concat " " hdr))
962 (markdown-wrap-or-insert hdrl hdrr))
963 (backward-char (+ 1 n)))
965 (defun markdown-insert-title ()
966 "Insert a setext-style (underline) first level header.
967 If Transient Mark mode is on and a region is active, it is used
968 as the header text."
969 (interactive)
970 (if (and transient-mark-mode mark-active)
971 (let ((a (region-beginning))
972 (b (region-end))
973 (len 0)
974 (hdr))
975 (setq len (- b a))
976 (dotimes (count len hdr)
977 (setq hdr (concat "=" hdr))) ; Build a === title underline
978 (end-of-line)
979 (insert "\n" hdr "\n"))
980 (insert "\n==========\n")
981 (backward-char 12)))
983 (defun markdown-insert-section ()
984 "Insert a setext-style (underline) second level header.
985 If Transient Mark mode is on and a region is active, it is used
986 as the header text."
987 (interactive)
988 (if (and transient-mark-mode mark-active)
989 (let ((a (region-beginning))
990 (b (region-end))
991 (len 0)
992 (hdr))
993 (setq len (- b a))
994 (dotimes (count len hdr)
995 (setq hdr (concat "-" hdr))) ; Build a --- section underline
996 (end-of-line)
997 (insert "\n" hdr "\n"))
998 (insert "\n----------\n")
999 (backward-char 12)))
1001 (defun markdown-insert-blockquote ()
1002 "Start a blockquote section (or blockquote the region).
1003 If Transient Mark mode is on and a region is active, it is used as
1004 the blockquote text."
1005 (interactive)
1006 (if (and (boundp 'transient-mark-mode) transient-mark-mode mark-active)
1007 (markdown-blockquote-region (region-beginning) (region-end))
1008 (insert "> ")))
1010 (defun markdown-block-region (beg end prefix)
1011 "Format the region using a block prefix.
1012 Arguments BEG and END specify the beginning and end of the
1013 region.The characters PREFIX will appear at the beginning
1014 of each line."
1015 (if mark-active
1016 (save-excursion
1017 (let ((endpos end))
1018 ; Ensure that there is a leading blank line
1019 (goto-char beg)
1020 (while (not (looking-back "\n\n" 2))
1021 (insert "\n")
1022 (setq endpos (+ 1 endpos)))
1023 ; Insert blockquote characters
1024 (move-to-left-margin)
1025 (while (< (point-at-bol) endpos)
1026 (insert prefix)
1027 (setq endpos (+ (length prefix) endpos))
1028 (forward-line))
1029 ; Move back before any blank lines at the end
1030 (goto-char endpos)
1031 (while (looking-back "\n" 1)
1032 (backward-char))
1033 ; Ensure one blank line at the end
1034 (while (not (looking-at "\n\n"))
1035 (insert "\n")
1036 (backward-char))))))
1038 (defun markdown-blockquote-region (beg end)
1039 "Blockquote the region.
1040 Arguments BEG and END specify the beginning and end of the region."
1041 (interactive "*r")
1042 (markdown-block-region beg end "> "))
1044 (defun markdown-insert-pre ()
1045 "Start a preformatted section (or apply to the region).
1046 If Transient Mark mode is on and a region is active, it is marked
1047 as preformatted text."
1048 (interactive)
1049 (if (and (boundp 'transient-mark-mode) transient-mark-mode mark-active)
1050 (markdown-pre-region (region-beginning) (region-end))
1051 (insert " ")))
1053 (defun markdown-pre-region (beg end)
1054 "Format the region as preformatted text.
1055 Arguments BEG and END specify the beginning and end of the region."
1056 (interactive "*r")
1057 (markdown-block-region beg end " "))
1059 ;;; Indentation ====================================================================
1061 (defun markdown-indent-find-next-position (cur-pos positions)
1062 "Return the position after the index of CUR-POS in POSITIONS."
1063 (while (and positions
1064 (not (equal cur-pos (car positions))))
1065 (setq positions (cdr positions)))
1066 (or (cadr positions) 0))
1068 (defun markdown-indent-line ()
1069 "Indent the current line using some heuristics."
1070 (interactive)
1071 (if (markdown-prev-line-indent-p)
1072 ;; If the current column is any of the positions, remove all
1073 ;; of the positions up-to and including the current column
1074 (indent-line-to
1075 (markdown-indent-find-next-position
1076 (current-column) (markdown-calc-indents)))))
1078 (defun markdown-calc-indents ()
1079 "Return a list of indentation columns to cycle through."
1080 (let (pos
1081 prev-line-pos
1082 positions
1083 computed-pos)
1085 ;; Previous line indent
1086 (setq prev-line-pos (markdown-prev-line-indent))
1087 (setq positions (cons prev-line-pos positions))
1089 ;; Previous non-list-marker indent
1090 (setq pos (markdown-prev-non-list-indent))
1091 (if pos
1092 (setq positions (cons pos positions)))
1094 ;; Indentation of the previous line + tab-width
1095 (cond
1096 (prev-line-pos
1097 (setq positions (cons (+ prev-line-pos tab-width) positions)))
1099 (setq positions (cons tab-width positions))))
1101 ;; Indentation of the previous line - tab-width
1102 (if (and prev-line-pos
1103 (> prev-line-pos tab-width))
1104 (setq positions (cons (- prev-line-pos tab-width) positions)))
1106 ;; Indentation of preceeding list item
1107 (setq pos
1108 (save-excursion
1109 (forward-line -1)
1110 (catch 'break
1111 (while (not (equal (point) (point-min)))
1112 (forward-line -1)
1113 (goto-char (point-at-bol))
1114 (when (re-search-forward markdown-regex-list-indent (point-at-eol) t)
1115 (throw 'break (length (match-string 1)))))
1116 nil)))
1117 (if (and pos (not (eq pos prev-line-pos)))
1118 (setq positions (cons pos positions)))
1120 ;; First column
1121 (setq positions (cons 0 (reverse positions)))
1123 positions))
1125 (defun markdown-do-normal-return ()
1126 "Insert a newline and optionally indent the next line."
1127 (newline)
1128 (if markdown-indent-on-enter
1129 (funcall indent-line-function)))
1131 (defun markdown-enter-key ()
1132 "Handle RET according to context.
1133 If there is a wiki link at the point, follow it unless
1134 `markdown-follow-wiki-link-on-enter' is nil. Otherwise, process
1135 it in the usual way."
1136 (interactive)
1137 (if (and markdown-follow-wiki-link-on-enter (markdown-wiki-link-p))
1138 (markdown-follow-wiki-link-at-point)
1139 (markdown-do-normal-return)))
1143 ;;; Keymap ====================================================================
1145 (defvar markdown-mode-map
1146 (let ((map (make-keymap)))
1147 ;; Element insertion
1148 (define-key map "\C-c\C-al" 'markdown-insert-link)
1149 (define-key map "\C-c\C-aw" 'markdown-insert-wiki-link)
1150 (define-key map "\C-c\C-ii" 'markdown-insert-image)
1151 (define-key map "\C-c\C-t1" 'markdown-insert-header-1)
1152 (define-key map "\C-c\C-t2" 'markdown-insert-header-2)
1153 (define-key map "\C-c\C-t3" 'markdown-insert-header-3)
1154 (define-key map "\C-c\C-t4" 'markdown-insert-header-4)
1155 (define-key map "\C-c\C-t5" 'markdown-insert-header-5)
1156 (define-key map "\C-c\C-t6" 'markdown-insert-header-6)
1157 (define-key map "\C-c\C-pb" 'markdown-insert-bold)
1158 (define-key map "\C-c\C-ss" 'markdown-insert-bold)
1159 (define-key map "\C-c\C-pi" 'markdown-insert-italic)
1160 (define-key map "\C-c\C-se" 'markdown-insert-italic)
1161 (define-key map "\C-c\C-pf" 'markdown-insert-code)
1162 (define-key map "\C-c\C-sc" 'markdown-insert-code)
1163 (define-key map "\C-c\C-sb" 'markdown-insert-blockquote)
1164 (define-key map "\C-c\C-s\C-b" 'markdown-blockquote-region)
1165 (define-key map "\C-c\C-sp" 'markdown-insert-pre)
1166 (define-key map "\C-c\C-s\C-p" 'markdown-pre-region)
1167 (define-key map "\C-c-" 'markdown-insert-hr)
1168 (define-key map "\C-c\C-tt" 'markdown-insert-title)
1169 (define-key map "\C-c\C-ts" 'markdown-insert-section)
1170 ;; WikiLink Following
1171 (define-key map "\C-c\C-f" 'markdown-follow-wiki-link-at-point)
1172 (define-key map "\M-n" 'markdown-next-wiki-link)
1173 (define-key map "\M-p" 'markdown-previous-wiki-link)
1174 ;; Indentation
1175 (define-key map "\C-m" 'markdown-enter-key)
1176 ;; Visibility cycling
1177 (define-key map (kbd "<tab>") 'markdown-cycle)
1178 (define-key map (kbd "<S-iso-lefttab>") 'markdown-shifttab)
1179 ;; Markdown functions
1180 (define-key map "\C-c\C-cm" 'markdown)
1181 (define-key map "\C-c\C-cp" 'markdown-preview)
1182 (define-key map "\C-c\C-ce" 'markdown-export)
1183 (define-key map "\C-c\C-cv" 'markdown-export-and-view)
1184 ;; References
1185 (define-key map "\C-c\C-cc" 'markdown-check-refs)
1186 map)
1187 "Keymap for Markdown major mode.")
1189 ;;; Menu ==================================================================
1191 (easy-menu-define markdown-mode-menu markdown-mode-map
1192 "Menu for Markdown mode"
1193 '("Markdown"
1194 ("Show/Hide"
1195 ["Cycle visibility" markdown-cycle (outline-on-heading-p)]
1196 ["Cycle global visibility" markdown-shifttab])
1197 "---"
1198 ["Compile" markdown]
1199 ["Preview" markdown-preview]
1200 ["Export" markdown-export]
1201 ["Export & View" markdown-export-and-view]
1202 "---"
1203 ("Headers (setext)"
1204 ["Insert Title" markdown-insert-title]
1205 ["Insert Section" markdown-insert-section])
1206 ("Headers (atx)"
1207 ["First level" markdown-insert-header-1]
1208 ["Second level" markdown-insert-header-2]
1209 ["Third level" markdown-insert-header-3]
1210 ["Fourth level" markdown-insert-header-4]
1211 ["Fifth level" markdown-insert-header-5]
1212 ["Sixth level" markdown-insert-header-6])
1213 "---"
1214 ["Bold" markdown-insert-bold]
1215 ["Italic" markdown-insert-italic]
1216 ["Blockquote" markdown-insert-blockquote]
1217 ["Preformatted" markdown-insert-pre]
1218 ["Code" markdown-insert-code]
1219 "---"
1220 ["Insert inline link" markdown-insert-link]
1221 ["Insert image" markdown-insert-image]
1222 ["Insert horizontal rule" markdown-insert-hr]
1223 "---"
1224 ["Check references" markdown-check-refs]
1225 "---"
1226 ["Version" markdown-show-version]
1231 ;;; References ================================================================
1233 ;;; Undefined reference checking code by Dmitry Dzhus <mail@sphinx.net.ru>.
1235 (defconst markdown-refcheck-buffer
1236 "*Undefined references for %BUFFER%*"
1237 "Pattern for name of buffer for listing undefined references.
1238 The string %BUFFER% will be replaced by the corresponding
1239 `markdown-mode' buffer name.")
1241 (defun markdown-has-reference-definition (reference)
1242 "Find out whether Markdown REFERENCE is defined.
1244 REFERENCE should include the square brackets, like [this]."
1245 (let ((reference (downcase reference)))
1246 (save-excursion
1247 (goto-char (point-min))
1248 (catch 'found
1249 (while (re-search-forward markdown-regex-reference-definition nil t)
1250 (when (string= reference (downcase (match-string-no-properties 1)))
1251 (throw 'found t)))))))
1253 (defun markdown-get-undefined-refs ()
1254 "Return a list of undefined Markdown references.
1256 Result is an alist of pairs (reference . occurencies), where
1257 occurencies is itself another alist of pairs (label .
1258 line-number).
1260 For example, an alist corresponding to [Nice editor][Emacs] at line 12,
1261 \[GNU Emacs][Emacs] at line 45 and [manual][elisp] at line 127 is
1262 \((\"[emacs]\" (\"[Nice editor]\" . 12) (\"[GNU Emacs]\" . 45)) (\"[elisp]\" (\"[manual]\" . 127)))."
1263 (let ((missing))
1264 (save-excursion
1265 (goto-char (point-min))
1266 (while
1267 (re-search-forward markdown-regex-link-reference nil t)
1268 (let* ((label (match-string-no-properties 1))
1269 (reference (match-string-no-properties 2))
1270 (target (downcase (if (string= reference "[]") label reference))))
1271 (unless (markdown-has-reference-definition target)
1272 (let ((entry (assoc target missing)))
1273 (if (not entry)
1274 (add-to-list 'missing (cons target
1275 (list (cons label (markdown-line-number-at-pos)))) t)
1276 (setcdr entry
1277 (append (cdr entry) (list (cons label (markdown-line-number-at-pos))))))))))
1278 missing)))
1280 (defun markdown-add-missing-ref-definition (ref buffer &optional recheck)
1281 "Add blank REF definition to the end of BUFFER.
1283 REF is a Markdown reference in square brackets, like \"[lisp-history]\".
1285 When RECHECK is non-nil, BUFFER gets rechecked for undefined
1286 references so that REF disappears from the list of those links."
1287 (with-current-buffer buffer
1288 (when (not (eq major-mode 'markdown-mode))
1289 (error "Not available in current mode"))
1290 (goto-char (point-max))
1291 (indent-new-comment-line)
1292 (insert (concat ref ": ")))
1293 (switch-to-buffer-other-window buffer)
1294 (goto-char (point-max))
1295 (when recheck
1296 (markdown-check-refs t)))
1298 ;; Button which adds an empty Markdown reference definition to the end
1299 ;; of buffer specified as its 'target-buffer property. Reference name
1300 ;; is button's label
1301 (when (>= emacs-major-version 22)
1302 (define-button-type 'markdown-ref-button
1303 'help-echo "Push to create an empty reference definition"
1304 'face 'bold
1305 'action (lambda (b)
1306 (markdown-add-missing-ref-definition
1307 (button-label b) (button-get b 'target-buffer) t))))
1309 ;; Button jumping to line in buffer specified as its 'target-buffer
1310 ;; property. Line number is button's 'line property.
1311 (when (>= emacs-major-version 22)
1312 (define-button-type 'goto-line-button
1313 'help-echo "Push to go to this line"
1314 'face 'italic
1315 'action (lambda (b)
1316 (message (button-get b 'buffer))
1317 (switch-to-buffer-other-window (button-get b 'target-buffer))
1318 ;; use call-interactively to silence compiler
1319 (call-interactively 'goto-line (button-get b 'target-line)))))
1321 (defun markdown-check-refs (&optional silent)
1322 "Show all undefined Markdown references in current `markdown-mode' buffer.
1324 If SILENT is non-nil, do not message anything when no undefined
1325 references found.
1327 Links which have empty reference definitions are considered to be
1328 defined."
1329 (interactive "P")
1330 (when (not (eq major-mode 'markdown-mode))
1331 (error "Not available in current mode"))
1332 (let ((oldbuf (current-buffer))
1333 (refs (markdown-get-undefined-refs))
1334 (refbuf (get-buffer-create (replace-regexp-in-string
1335 "%BUFFER%" (buffer-name)
1336 markdown-refcheck-buffer t))))
1337 (if (null refs)
1338 (progn
1339 (when (not silent)
1340 (message "No undefined references found"))
1341 (kill-buffer refbuf))
1342 (with-current-buffer refbuf
1343 (when view-mode
1344 (View-exit-and-edit))
1345 (erase-buffer)
1346 (insert "Following references lack definitions:")
1347 (newline 2)
1348 (dolist (ref refs)
1349 (let ((button-label (format "%s" (car ref))))
1350 (if (>= emacs-major-version 22)
1351 ;; Create a reference button in Emacs 22
1352 (insert-text-button button-label
1353 :type 'markdown-ref-button
1354 'target-buffer oldbuf)
1355 ;; Insert reference as text in Emacs < 22
1356 (insert button-label)))
1357 (insert " (")
1358 (dolist (occurency (cdr ref))
1359 (let ((line (cdr occurency)))
1360 (if (>= emacs-major-version 22)
1361 ;; Create a line number button in Emacs 22
1362 (insert-button (number-to-string line)
1363 :type 'goto-line-button
1364 'target-buffer oldbuf
1365 'target-line line)
1366 ;; Insert line number as text in Emacs < 22
1367 (insert (number-to-string line)))
1368 (insert " "))) (delete-char -1)
1369 (insert ")")
1370 (newline))
1371 (view-buffer-other-window refbuf)
1372 (goto-char (point-min))
1373 (forward-line 2)))))
1375 ;;; Outline ===================================================================
1377 ;; The following visibility cycling code was taken from org-mode
1378 ;; by Carsten Dominik and adapted for markdown-mode.
1380 (defvar markdown-cycle-global-status 1)
1381 (defvar markdown-cycle-subtree-status nil)
1383 ;; Based on org-end-of-subtree from org.el
1384 (defun markdown-end-of-subtree (&optional invisible-OK)
1385 "Move to the end of the current subtree.
1386 Only visible heading lines are considered, unless INVISIBLE-OK is
1387 non-nil."
1388 (outline-back-to-heading invisible-OK)
1389 (let ((first t)
1390 (level (funcall outline-level)))
1391 (while (and (not (eobp))
1392 (or first (> (funcall outline-level) level)))
1393 (setq first nil)
1394 (outline-next-heading))
1395 (if (memq (preceding-char) '(?\n ?\^M))
1396 (progn
1397 ;; Go to end of line before heading
1398 (forward-char -1)
1399 (if (memq (preceding-char) '(?\n ?\^M))
1400 ;; leave blank line before heading
1401 (forward-char -1)))))
1402 (point))
1404 ;; Based on org-cycle from org.el.
1405 (defun markdown-cycle (&optional arg)
1406 "Visibility cycling for Markdown mode.
1407 If ARG is t, perform global visibility cycling. If the point is
1408 at an atx-style header, cycle visibility of the corresponding
1409 subtree. Otherwise, insert a tab using `indent-relative'."
1410 (interactive "P")
1411 (cond
1412 ((eq arg t) ;; Global cycling
1413 (cond
1414 ((and (eq last-command this-command)
1415 (eq markdown-cycle-global-status 2))
1416 ;; Move from overview to contents
1417 (hide-sublevels 1)
1418 (message "CONTENTS")
1419 (setq markdown-cycle-global-status 3))
1421 ((and (eq last-command this-command)
1422 (eq markdown-cycle-global-status 3))
1423 ;; Move from contents to all
1424 (show-all)
1425 (message "SHOW ALL")
1426 (setq markdown-cycle-global-status 1))
1429 ;; Defaults to overview
1430 (hide-body)
1431 (message "OVERVIEW")
1432 (setq markdown-cycle-global-status 2))))
1434 ((save-excursion (beginning-of-line 1) (looking-at outline-regexp))
1435 ;; At a heading: rotate between three different views
1436 (outline-back-to-heading)
1437 (let ((goal-column 0) eoh eol eos)
1438 ;; Determine boundaries
1439 (save-excursion
1440 (outline-back-to-heading)
1441 (save-excursion
1442 (beginning-of-line 2)
1443 (while (and (not (eobp)) ;; this is like `next-line'
1444 (get-char-property (1- (point)) 'invisible))
1445 (beginning-of-line 2)) (setq eol (point)))
1446 (outline-end-of-heading) (setq eoh (point))
1447 (markdown-end-of-subtree t)
1448 (skip-chars-forward " \t\n")
1449 (beginning-of-line 1) ; in case this is an item
1450 (setq eos (1- (point))))
1451 ;; Find out what to do next and set `this-command'
1452 (cond
1453 ((= eos eoh)
1454 ;; Nothing is hidden behind this heading
1455 (message "EMPTY ENTRY")
1456 (setq markdown-cycle-subtree-status nil))
1457 ((>= eol eos)
1458 ;; Entire subtree is hidden in one line: open it
1459 (show-entry)
1460 (show-children)
1461 (message "CHILDREN")
1462 (setq markdown-cycle-subtree-status 'children))
1463 ((and (eq last-command this-command)
1464 (eq markdown-cycle-subtree-status 'children))
1465 ;; We just showed the children, now show everything.
1466 (show-subtree)
1467 (message "SUBTREE")
1468 (setq markdown-cycle-subtree-status 'subtree))
1470 ;; Default action: hide the subtree.
1471 (hide-subtree)
1472 (message "FOLDED")
1473 (setq markdown-cycle-subtree-status 'folded)))))
1476 (funcall indent-line-function))))
1478 ;; Based on org-shifttab from org.el.
1479 (defun markdown-shifttab ()
1480 "Global visibility cycling.
1481 Calls `markdown-cycle' with argument t."
1482 (interactive)
1483 (markdown-cycle t))
1485 ;;; Commands ==================================================================
1487 (defun markdown (&optional output-buffer-name)
1488 "Run `markdown' on current buffer and insert output in buffer BUFFER-OUTPUT."
1489 (interactive)
1490 (let ((title (buffer-name))
1491 (begin-region)
1492 (end-region))
1493 (if (and (boundp 'transient-mark-mode) transient-mark-mode mark-active)
1494 (setq begin-region (region-beginning)
1495 end-region (region-end))
1496 (setq begin-region (point-min)
1497 end-region (point-max)))
1499 (unless output-buffer-name
1500 (setq output-buffer-name markdown-output-buffer-name))
1502 (shell-command-on-region begin-region end-region markdown-command
1503 output-buffer-name)
1504 (save-current-buffer
1505 (set-buffer output-buffer-name)
1506 (goto-char (point-min))
1507 (unless (markdown-output-standalone-p)
1508 (markdown-add-xhtml-header-and-footer title))
1509 (html-mode))))
1511 (defun markdown-output-standalone-p ()
1512 "Determine whether `markdown-command' output is standalone XHTML.
1513 Standalone XHTML output is identified by an occurrence of
1514 `markdown-xhtml-standalone-regexp' in the first five lines of output."
1515 (re-search-forward
1516 markdown-xhtml-standalone-regexp
1517 (save-excursion (goto-line 5) (point)) t))
1519 (defun markdown-add-xhtml-header-and-footer (title)
1520 "Wrap XHTML header and footer with given TITLE around current buffer."
1521 (insert "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"
1522 "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"\n"
1523 "\t\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n\n"
1524 "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n\n"
1525 "<head>\n<title>")
1526 (insert title)
1527 (insert "</title>\n")
1528 (if (> (length markdown-css-path) 0)
1529 (insert "<link rel=\"stylesheet\" type=\"text/css\" media=\"all\" href=\""
1530 markdown-css-path
1531 "\" />\n"))
1532 (when (> (length markdown-xhtml-header-content) 0)
1533 (insert markdown-xhtml-header-content))
1534 (insert "\n</head>\n\n"
1535 "<body>\n\n")
1536 (goto-char (point-max))
1537 (insert "\n"
1538 "</body>\n"
1539 "</html>\n"))
1541 (defun markdown-preview ()
1542 "Run `markdown' on the current buffer and preview the output in a browser."
1543 (interactive)
1544 (markdown markdown-output-buffer-name)
1545 (browse-url-of-buffer markdown-output-buffer-name))
1547 (defun markdown-export-file-name ()
1548 "Attempt to generate a filename for Markdown output.
1549 If the current buffer is visiting a file, we construct a new
1550 output filename based on that filename. Otherwise, return nil."
1551 (when (buffer-file-name)
1552 (concat (file-name-sans-extension (buffer-file-name)) ".html")))
1554 (defun markdown-export ()
1555 "Run Markdown on the current buffer, save to a file, and return the filename.
1556 The resulting filename will be constructed using the current filename, but
1557 with the extension removed and replaced with .html."
1558 (interactive)
1559 (let ((output-file (markdown-export-file-name))
1560 (output-buffer-name))
1561 (when output-file
1562 (setq output-buffer-name (buffer-name (find-file-noselect output-file)))
1563 (markdown output-buffer-name)
1564 (with-current-buffer output-buffer-name
1565 (save-buffer)
1566 (kill-buffer-and-window))
1567 output-file)))
1569 (defun markdown-export-and-view ()
1570 "Export to XHTML using `markdown-export' and browse the resulting file."
1571 (interactive)
1572 (browse-url (markdown-export)))
1574 ;;; WikiLink Following/Markup ========================================================
1576 (require 'thingatpt)
1578 (defun markdown-wiki-link-p ()
1579 "Return non-nil when `point' is at a true wiki link.
1580 A true wiki link name matches `markdown-regex-wiki-link' but does not
1581 match the current file name after conversion This modifies the data
1582 returned by `match-data'.
1584 If optional argument SHORTCUT is non-nil, we assume that
1585 `markdown-regex-wiki-link' has just been searched for. Note that the
1586 potential wiki link name must be available via `match-string'."
1587 (let ((case-fold-search nil))
1588 (and (thing-at-point-looking-at markdown-regex-wiki-link)
1589 (or (not buffer-file-name)
1590 (not (string-equal (buffer-file-name)
1591 (markdown-convert-wiki-link-to-filename
1592 (match-string 1)))))
1593 (not (save-match-data
1594 (save-excursion))))))
1596 (defun markdown-convert-wiki-link-to-filename (name)
1597 "Generate a filename from the wiki link NAME.
1598 Spaces are converted to underscores, following the convention
1599 used by the Python Markdown WikiLinks extension."
1600 (let ((new-ext (file-name-extension (buffer-file-name)))
1601 (new-basename (replace-regexp-in-string "[[:space:]\n]" "_" name)))
1602 (concat new-basename "." new-ext)))
1604 (defun markdown-follow-wiki-link (name)
1605 "Follow the wiki link NAME.
1606 Convert the name to a file name and call `find-file'. Ensure that
1607 the new buffer remains in `markdown-mode'."
1608 (let ((filename (markdown-convert-wiki-link-to-filename name)))
1609 (find-file filename))
1610 (markdown-mode))
1612 (defun markdown-follow-wiki-link-at-point ()
1613 "Find Wiki Link at point.
1614 See `markdown-wiki-link-p' and `markdown-follow-wiki-link'."
1615 (interactive)
1616 (if (markdown-wiki-link-p)
1617 (markdown-follow-wiki-link (match-string 1))
1618 (error "Point is not at a Wiki Link")))
1620 (defun markdown-next-wiki-link ()
1621 "Jump to next wiki link.
1622 See `markdown-wiki-link-p'."
1623 (interactive)
1624 (if (markdown-wiki-link-p)
1625 ; At a wiki link already, move past it.
1626 (goto-char (+ 1 (match-end 0))))
1627 (save-match-data
1628 ; Search for the next wiki link and move to the beginning.
1629 (re-search-forward markdown-regex-wiki-link nil t)
1630 (goto-char (match-beginning 0))))
1632 (defun markdown-previous-wiki-link ()
1633 "Jump to previous wiki link.
1634 See `markdown-wiki-link-p'."
1635 (interactive)
1636 (re-search-backward markdown-regex-wiki-link nil t))
1638 (defun markdown-highlight-wiki-link (from to face)
1639 "Highlight the wiki link in the region between FROM and TO using FACE."
1640 (let ((ov (make-overlay from to)))
1641 (overlay-put ov 'face face)))
1643 (defun markdown-unfontify-region-wiki-links (from to)
1644 "Remove wiki link faces from the region specified by FROM and TO."
1645 (interactive "nfrom: \nnto: ")
1646 (remove-overlays from to 'face markdown-link-face)
1647 (remove-overlays from to 'face markdown-missing-link-face))
1649 (defun markdown-fontify-region-wiki-links (from to)
1650 "Search region given by FROM and TO for wiki links and fontify them.
1651 If a wiki link is found check to see if the backing file exists
1652 and highlight accordingly."
1653 (goto-char from)
1654 (while (re-search-forward markdown-regex-wiki-link to t)
1655 (let ((highlight-beginning (match-beginning 0))
1656 (highlight-end (match-end 0))
1657 (file-name
1658 (markdown-convert-wiki-link-to-filename (match-string 1))))
1659 (if (file-exists-p file-name)
1660 (markdown-highlight-wiki-link
1661 highlight-beginning highlight-end markdown-link-face)
1662 (markdown-highlight-wiki-link
1663 highlight-beginning highlight-end markdown-missing-link-face)))))
1665 (defun markdown-extend-changed-region (from to)
1666 "Extend region given by FROM and TO so that we can fontify all links.
1667 The region is extended to the first newline before and the first
1668 newline after."
1669 ;; start looking for the first new line before 'from
1670 (goto-char from)
1671 (re-search-backward "\n" nil t)
1672 (let ((new-from (point-min))
1673 (new-to (point-max)))
1674 (if (not (= (point) from))
1675 (setq new-from (point)))
1676 ;; do the same thing for the first new line after 'to
1677 (goto-char to)
1678 (re-search-forward "\n" nil t)
1679 (if (not (= (point) to))
1680 (setq new-to (point)))
1681 (list new-from new-to)))
1683 (defun markdown-check-change-for-wiki-link (from to change)
1684 "Check region between FROM and TO for wiki links and re-fontfy as needed.
1685 Designed to be used with the `after-change-functions' hook.
1686 CHANGE is the number of bytes of pre-change text replaced by the
1687 given range."
1688 (interactive "nfrom: \nnto: \nnchange: ")
1689 (let* ((inhibit-point-motion-hooks t)
1690 (inhibit-quit t)
1691 (modified (buffer-modified-p))
1692 (buffer-undo-list t)
1693 (inhibit-read-only t)
1694 (inhibit-point-motion-hooks t)
1695 (inhibit-modification-hooks t)
1696 (current-point (point))
1697 deactivate-mark)
1698 (unwind-protect
1699 (save-restriction
1700 ;; Extend the region to fontify so that it starts
1701 ;; and ends at safe places.
1702 (multiple-value-bind (new-from new-to)
1703 (markdown-extend-changed-region from to)
1704 ;; Unfontify existing fontification (start from scratch)
1705 (markdown-unfontify-region-wiki-links new-from new-to)
1706 ;; Now do the fontification.
1707 (markdown-fontify-region-wiki-links new-from new-to)))
1708 (unless modified
1709 (restore-buffer-modified-p nil)))
1710 (goto-char current-point)))
1712 (defun markdown-fontify-buffer-wiki-links ()
1713 "Refontify all wiki links in the buffer."
1714 (interactive)
1715 (markdown-check-change-for-wiki-link (point-min) (point-max) 0))
1717 ;;; Miscellaneous =============================================================
1719 (defun markdown-line-number-at-pos (&optional pos)
1720 "Return (narrowed) buffer line number at position POS.
1721 If POS is nil, use current buffer location.
1722 This is an exact copy of `line-number-at-pos' for use in emacs21."
1723 (let ((opoint (or pos (point))) start)
1724 (save-excursion
1725 (goto-char (point-min))
1726 (setq start (point))
1727 (goto-char opoint)
1728 (forward-line 0)
1729 (1+ (count-lines start (point))))))
1731 (defun markdown-nobreak-p ()
1732 "Return nil if it is acceptable to break the current line at the point."
1733 ;; inside in square brackets (e.g., link anchor text)
1734 (looking-back "\\[[^]]*"))
1738 ;;; Mode definition ==========================================================
1740 (defun markdown-show-version ()
1741 "Show the version number in the minibuffer."
1742 (interactive)
1743 (message "markdown-mode, version %s" markdown-mode-version))
1745 ;;;###autoload
1746 (define-derived-mode markdown-mode text-mode "Markdown"
1747 "Major mode for editing Markdown files."
1748 ;; Natural Markdown tab width
1749 (setq tab-width 4)
1750 ;; Comments
1751 (make-local-variable 'comment-start)
1752 (setq comment-start "<!-- ")
1753 (make-local-variable 'comment-end)
1754 (setq comment-end " -->")
1755 (make-local-variable 'comment-start-skip)
1756 (setq comment-start-skip "<!--[ \t]*")
1757 (make-local-variable 'comment-column)
1758 (setq comment-column 0)
1759 ;; Font lock.
1760 (set (make-local-variable 'font-lock-defaults)
1761 '(markdown-mode-font-lock-keywords))
1762 (set (make-local-variable 'font-lock-multiline) t)
1763 ;; For menu support in XEmacs
1764 (easy-menu-add markdown-mode-menu markdown-mode-map)
1765 ;; Make filling work with lists (unordered, ordered, and definition)
1766 (set (make-local-variable 'paragraph-start)
1767 "\f\\|[ \t]*$\\|^[ \t]*[*+-] \\|^[ \t*][0-9]+\\.\\|^[ \t]*: ")
1768 ;; Outline mode
1769 (make-local-variable 'outline-regexp)
1770 (setq outline-regexp "#+")
1771 ;; Cause use of ellipses for invisible text.
1772 (add-to-invisibility-spec '(outline . t))
1773 ;; Indentation and filling
1774 (make-local-variable 'fill-nobreak-predicate)
1775 (add-hook 'fill-nobreak-predicate 'markdown-nobreak-p)
1776 (setq indent-line-function markdown-indent-function)
1778 ;; Prepare hooks for XEmacs compatibility
1779 (when (featurep 'xemacs)
1780 (make-local-hook 'after-change-functions)
1781 (make-local-hook 'window-configuration-change-hook))
1783 ;; Anytime text changes make sure it gets fontified correctly
1784 (add-hook 'after-change-functions 'markdown-check-change-for-wiki-link t t)
1786 ;; If we left the buffer there is a really good chance we were
1787 ;; creating one of the wiki link documents. Make sure we get
1788 ;; refontified when we come back.
1789 (add-hook 'window-configuration-change-hook
1790 'markdown-fontify-buffer-wiki-links t t)
1792 ;; do the initial link fontification
1793 (markdown-fontify-buffer-wiki-links))
1795 ;(add-to-list 'auto-mode-alist '("\\.text$" . markdown-mode))
1797 ;;; GitHub Flavored Markdown Mode ============================================
1799 (define-derived-mode gfm-mode markdown-mode "GFM"
1800 "Major mode for editing GitHub Flavored Markdown files."
1801 (auto-fill-mode 0)
1802 (longlines-mode 1))
1804 (provide 'markdown-mode)
1806 ;;; markdown-mode.el ends here