Thanks
[markdown-mode/intrigeri.git] / markdown-mode.el
blob732e809d7c9fe501558323406a75d860046c8145
1 ;;; markdown-mode.el --- Major mode to edit Markdown files in Emacs
3 ;; Copyright (C) 2007, 2008 Jason Blevins
5 ;; Version: 1.7-dev
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)
15 ;; any later version.
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.
26 ;;; Commentary:
28 ;; markdown-mode is a major mode for editing [Markdown][]-formatted
29 ;; text files in GNU Emacs. markdown-mode is free software, licensed
30 ;; under the GNU GPL.
32 ;; [Markdown]: http://daringfireball.net/projects/markdown/
34 ;; The latest version is markdown-mode 1.6, released on June 4. 2008:
36 ;; * [markdown-mode.el][]
37 ;; * [Screenshot][]
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/20080604-001.png
45 ;; [release notes]: http://jblevins.org/projects/markdown-mode/rev-1-6
47 ;;; Dependencies:
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.
53 ;;; Installation:
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.
67 ;;; Usage:
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)`. If
80 ;; there is an active region, text in the region is used for the link
81 ;; text. `C-c C-a w` acts similarly for wiki links of the form
82 ;; `[[WikiLink]]`.
84 ;; * Commands: `C-c C-c`
86 ;; `C-c C-c m` will run Markdown on the current buffer and preview the
87 ;; output in another buffer while `C-c C-c p` runs Markdown on the
88 ;; current buffer and previews the output in a browser.
90 ;; `C-c C-c c` will check for undefined references. If there are any,
91 ;; a small buffer will open with a list of undefined references and
92 ;; the line numbers on which they appear. In Emacs 22 and greater,
93 ;; selecting a reference from this list and pressing `RET` will insert
94 ;; an empty reference definition at the end of the buffer. Similarly,
95 ;; selecting the line number will jump to the corresponding line.
97 ;; * Images: `C-c C-i`
99 ;; `C-c C-i i` inserts an image, using the active region (if any) as
100 ;; the alt text.
102 ;; * Physical styles: `C-c C-p`
104 ;; These commands all act on text in the active region, if any, and
105 ;; insert empty markup fragments otherwise. `C-c C-p b` makes the
106 ;; selected text bold, `C-c C-p f` formats the region as fixed-width
107 ;; text, and `C-c C-p i` is used for italic text.
109 ;; * Logical styles: `C-c C-s`
111 ;; These commands all act on text in the active region, if any, and
112 ;; insert empty markup fragments otherwise. Logical styles include
113 ;; blockquote (`C-c C-s b`), preformatted (`C-c C-s p`), code (`C-c C-s c`),
114 ;; emphasis (`C-c C-s e`), and strong (`C-c C-s s`).
116 ;; * Headers: `C-c C-t`
118 ;; All header commands use text in the active region, if any, as the
119 ;; header text. To insert an atx or hash style level-n header, press
120 ;; `C-c C-t n` where n is between 1 and 5. For a top-level setext or
121 ;; underline style header press `C-c C-t t` (mnemonic: title) and for
122 ;; a second-level underline-style header press `C-c C-t s`
123 ;; (mnemonic: section).
125 ;; * Other commands
127 ;; `C-c -` inserts a horizontal rule.
129 ;; Many of the commands described above behave differently depending on
130 ;; whether Transient Mark mode is enabled or not. When it makes sense,
131 ;; if Transient Mark mode is on and a region is active, the command
132 ;; applies to the text in the region (e.g., `C-c C-p b` makes the region
133 ;; bold). For users who prefer to work outside of Transient Mark mode,
134 ;; in Emacs 22 it can be enabled temporarily by pressing `C-SPC C-SPC`.
136 ;; When applicable, commands that specifically act on the region even
137 ;; outside of Transient Mark mode have the same keybinding as the with
138 ;; the exception of an additional `C-` prefix. For example,
139 ;; `markdown-insert-blockquote` is bound to `C-c C-s b` and only acts on
140 ;; the region in Transient Mark mode while `markdown-blockquote-region`
141 ;; is bound to `C-c C-s C-b` and always applies to the region (when
142 ;; nonempty).
144 ;; Markdown mode supports outline-minor-mode as well as org-mode-style
145 ;; visibility cycling for atx- or hash-style headers. There are two
146 ;; types of visibility cycling: Pressing `S-TAB` cycles globally between
147 ;; the table of contents view (headers only), outline view (top-level
148 ;; headers only), and the full document view. Pressing `TAB` while the
149 ;; point is at a header will cycle through levels of visibility for the
150 ;; subtree: completely folded, visiable children, and fully visible.
151 ;; Note that mixing hash and underline style headers will give undesired
152 ;; results.
154 ;;; Extensions:
156 ;; Besides supporting the basic Markdown syntax, markdown-mode also
157 ;; includes syntax highlighting for `[[Wiki Links]]` by default.
159 ;; [SmartyPants][] support is possible by customizing `markdown-command`.
160 ;; If you install `SmartyPants.pl` at, say, `/usr/local/bin/smartypants`,
161 ;; then you can set `markdown-command` to `"markdown | smartypants"`.
162 ;; You can do this either by using `M-x customize-group markdown`
163 ;; or by placing the following in your `.emacs` file:
165 ;; (defun markdown-custom ()
166 ;; "markdown-mode-hook"
167 ;; (setq markdown-command "markdown | smartypants"))
168 ;; (add-hook 'markdown-mode-hook '(lambda() (markdown-custom)))
170 ;; Experimental syntax highlighting for mathematical expressions written
171 ;; in LaTeX (only expressions denoted by `$..$`, `$$..$$`, or `\[..\]`)
172 ;; can be enabled by editing `markdown-mode.el` and changing `(defvar
173 ;; markdown-enable-itex nil)` to `(defvar markdown-enable-itex t)`.
175 ;; [SmartyPants]: http://daringfireball.net/projects/smartypants/
177 ;;; Thanks:
179 ;; * Cyril Brulebois <cyril.brulebois@enst-bretagne.fr> for Debian packaging.
180 ;; * Conal Elliott <conal@conal.net> for a font-lock regexp patch.
181 ;; * Edward O'Connor <hober0@gmail.com> for a font-lock regexp fix.
182 ;; * Greg Bognar <greg_bognar@hms.harvard.edu> for menus and a patch.
183 ;; * Daniel Burrows <dburrows@debian.org> for filing Debian bug #456592.
184 ;; * Peter S. Galbraith <psg@debian.org> for maintaining emacs-goodies-el.
185 ;; * Dmitry Dzhus <mail@sphinx.net.ru> for reference checking functions.
186 ;; * Bryan Kyle <bryan.kyle@gmail.com> for indentation code.
187 ;; * intrigeri <intrigeri@boum.org> for face customizations.
189 ;;; Bugs:
191 ;; Markdown mode is developed and tested primarily using GNU Emacs 22
192 ;; although compatibility with GNU Emacs 21 is also a priority.
194 ;; Presently Markdown mode does not attempt to distinguish between
195 ;; multiple indentation levels and preformatted text (four or more
196 ;; leading spaces). I am not aware of a way to handle this using
197 ;; Emacs's regexp-based font-lock facilities. Implementing a more
198 ;; robust approach to syntax highlighting is a high-priority item for
199 ;; future work.
201 ;; If you find any bugs, such as syntax highlighting issues, please
202 ;; construct a test case and email me at <jrblevin@sdf.lonestar.org>.
203 ;; Comments and patches are welcome!
205 ;;; History:
207 ;; markdown-mode was written and is maintained by Jason Blevins. The
208 ;; first revision, 1.1, was released on May 24, 2007.
213 ;;; Code:
215 (require 'easymenu)
216 (require 'outline)
218 ;;; User Customizable Variables ===============================================
220 ;; To enable LaTeX/itex syntax highlighting, change to
221 ;; (defvar markdown-enable-itex t)
222 (defvar markdown-enable-itex nil)
225 ;;; Customizable variables ====================================================
227 ;; Current revision
228 (defconst markdown-mode-version "1.7-dev")
230 ;; A hook for users to run their own code when the mode is loaded.
231 (defvar markdown-mode-hook nil)
234 ;;; Customizable variables ====================================================
236 (defgroup markdown nil
237 "Major mode for editing text files in Markdown format."
238 :prefix "markdown-"
239 :group 'wp
240 :link '(url-link "http://jblevins.org/projects/markdown-mode/"))
242 (defcustom markdown-command "markdown"
243 "Command to run markdown."
244 :group 'markdown
245 :type 'string)
247 (defcustom markdown-hr-length 5
248 "Length of horizonal rules."
249 :group 'markdown
250 :type 'integer)
252 (defcustom markdown-bold-underscore nil
253 "Use two underscores for bold instead of two asterisks."
254 :group 'markdown
255 :type 'boolean)
257 (defcustom markdown-italic-underscore nil
258 "Use underscores for italic instead of asterisks."
259 :group 'markdown
260 :type 'boolean)
262 (defcustom markdown-indent-function 'markdown-indent-line
263 "Function to use to indent."
264 :group 'markdown
265 :type 'function)
267 (defcustom markdown-indent-on-enter t
268 "Automatically indent new lines when enter key is pressed."
269 :group 'markdown
270 :type 'boolean)
272 ;;; Font lock =================================================================
274 (require 'font-lock)
277 (defvar markdown-italic-face 'markdown-italic-face
278 "Face name to use for italic text.")
280 (defvar markdown-bold-face 'markdown-bold-face
281 "Face name to use for bold text.")
283 (defvar markdown-header-face 'markdown-header-face
284 "Face name to use as a base for headers.")
286 (defvar markdown-header-face-1 'markdown-header-face-1
287 "Face name to use for level-1 headers.")
289 (defvar markdown-header-face-2 'markdown-header-face-2
290 "Face name to use for level-2 headers.")
292 (defvar markdown-header-face-3 'markdown-header-face-3
293 "Face name to use for level-3 headers.")
295 (defvar markdown-header-face-4 'markdown-header-face-4
296 "Face name to use for level-4 headers.")
298 (defvar markdown-inline-code-face 'markdown-inline-code-face
299 "Face name to use for inline code.")
301 (defvar markdown-list-face 'markdown-list-face
302 "Face name to use for list markers.")
304 (defvar markdown-blockquote-face 'markdown-blockquote-face
305 "Face name to use for blockquote.")
307 (defvar markdown-link-face 'markdown-link-face
308 "Face name to use for links.")
310 (defvar markdown-reference-face 'markdown-reference-face
311 "Face name to use for reference.")
313 (defvar markdown-url-face 'markdown-url-face
314 "Face name to use for URLs.")
316 (defvar markdown-math-face 'markdown-math-face
317 "Face name to use for LaTeX expressions.")
320 (defgroup markdown-faces nil
321 "Faces used in Markdown Mode"
322 :group 'markdown
323 :group 'faces)
325 (defface markdown-italic-face
326 '((t :inherit font-lock-variable-name-face))
327 "Face for italic text."
328 :group 'markdown-faces)
330 (defface markdown-bold-face
331 '((t :inherit font-lock-type-face))
332 "Face for bold text."
333 :group 'markdown-faces)
335 (defface markdown-header-face
336 '((t :inherit font-lock-function-name-face))
337 "Base face for headers."
338 :group 'markdown-faces)
340 (defface markdown-header-face-1
341 '((t :inherit markdown-header-face))
342 "Face for level-1 headers."
343 :group 'markdown-faces)
345 (defface markdown-header-face-2
346 '((t :inherit markdown-header-face))
347 "Face for level-2 headers."
348 :group 'markdown-faces)
350 (defface markdown-header-face-3
351 '((t :inherit markdown-header-face))
352 "Face for level-3 headers."
353 :group 'markdown-faces)
355 (defface markdown-header-face-4
356 '((t :inherit markdown-header-face))
357 "Face for level-4 headers."
358 :group 'markdown-faces)
360 (defface markdown-inline-code-face
361 '((t :inherit font-lock-builtin-face))
362 "Face for inline code."
363 :group 'markdown-faces)
365 (defface markdown-list-face
366 '((t :inherit font-lock-variable-name-face))
367 "Face for list item markers."
368 :group 'markdown-faces)
370 (defface markdown-blockquote-face
371 '((t :inherit font-lock-comment-face))
372 "Face for blockquote sections and preformatted text."
373 :group 'markdown-faces)
375 (defface markdown-link-face
376 '((t :inherit font-lock-constant-face))
377 "Face for links."
378 :group 'markdown-faces)
380 (defface markdown-reference-face
381 '((t :inherit font-lock-type-face))
382 "Face for link references."
383 :group 'markdown-faces)
385 (defface markdown-url-face
386 '((t :inherit markdown-link-face))
387 "Face for URLs."
388 :group 'markdown-faces)
390 (defface markdown-math-face
391 '((t :inherit font-lock-builtin-face))
392 "Face for LaTeX expressions."
393 :group 'markdown-faces)
395 (defconst markdown-regex-link-inline
396 "\\(!?\\[[^]]*?\\]\\)\\(([^\\)]*)\\)"
397 "Regular expression for a [text](file) or an image link ![text](file).")
399 (defconst markdown-regex-link-reference
400 "\\(!?\\[[^]]+?\\]\\)[ ]?\\(\\[[^]]*?\\]\\)"
401 "Regular expression for a reference link [text][id].")
403 (defconst markdown-regex-reference-definition
404 "^ \\{0,3\\}\\(\\[.+?\\]\\):\\s *\\(.*?\\)\\s *\\( \"[^\"]*\"$\\|$\\)"
405 "Regular expression for a link definition [id]: ...")
407 (defconst markdown-regex-header-1-atx
408 "^\\(# \\)\\(.*?\\)\\($\\| #+$\\)"
409 "Regular expression for level 1 atx-style (hash mark) headers.")
411 (defconst markdown-regex-header-2-atx
412 "^\\(## \\)\\(.*?\\)\\($\\| #+$\\)"
413 "Regular expression for level 2 atx-style (hash mark) headers.")
415 (defconst markdown-regex-header-3-atx
416 "^\\(### \\)\\(.*?\\)\\($\\| #+$\\)"
417 "Regular expression for level 3 atx-style (hash mark) headers.")
419 (defconst markdown-regex-header-4-atx
420 "^\\(#### \\)\\(.*?\\)\\($\\| #+$\\)"
421 "Regular expression for level 4 atx-style (hash mark) headers.")
423 (defconst markdown-regex-header-1-setext
424 "^\\(.*\\)\n\\(===+\\)$"
425 "Regular expression for level 1 setext-style (underline) headers.")
427 (defconst markdown-regex-header-2-setext
428 "^\\(.*\\)\n\\(---+\\)$"
429 "Regular expression for level 2 setext-style (underline) headers.")
431 (defconst markdown-regex-hr
432 "^\\(\\*[ ]?\\*[ ]?\\*[ ]?[\\* ]*\\|-[ ]?-[ ]?-[--- ]*\\)$"
433 "Regular expression for matching Markdown horizontal rules.")
435 (defconst markdown-regex-code
436 "\\(^\\|[^\\]\\)\\(\\(`\\{1,2\\}\\)\\([^ \\]\\|[^ ].*?[^ \\]\\)\\3\\)"
437 "Regular expression for matching inline code fragments.")
439 (defconst markdown-regex-pre
440 "^ .*$"
441 "Regular expression for matching preformatted text sections.")
443 (defconst markdown-regex-list
444 "^[ \t]*\\([0-9]+\\.\\|[\\*\\+-]\\) "
445 "Regular expression for matching list markers.")
447 (defconst markdown-regex-bold
448 "\\(^\\|[^\\]\\)\\(\\([*_]\\{2\\}\\)\\(.\\|\n\\)*?[^\\ ]\\3\\)"
449 "Regular expression for matching bold text.")
451 (defconst markdown-regex-italic
452 "\\(^\\|[^\\]\\)\\(\\([*_]\\)\\([^ \\]\\3\\|[^ ]\\(.\\|\n\\)*?[^\\ ]\\3\\)\\)"
453 "Regular expression for matching italic text.")
455 (defconst markdown-regex-blockquote
456 "^>.*$"
457 "Regular expression for matching blockquote lines.")
459 (defconst markdown-regex-line-break
460 " $"
461 "Regular expression for matching line breaks.")
463 (defconst markdown-regex-wiki-link
464 "\\[\\[[^]]+\\]\\]"
465 "Regular expression for matching wiki links.")
467 (defconst markdown-regex-uri
468 "<\\(acap\\|cid\\|data\\|dav\\|fax\\|file\\|ftp\\|gopher\\|http\\|https\\|imap\\|ldap\\|mailto\\|mid\\|modem\\|news\\|nfs\\|nntp\\|pop\\|prospero\\|rtsp\\|service\\|sip\\|tel\\|telnet\\|tip\\|urn\\|vemmi\\|wais\\)://[^>]*>"
469 "Regular expression for matching inline URIs.")
471 (defconst markdown-regex-email
472 "<\\(\\sw\\|\\s_\\|\\s.\\)+@\\(\\sw\\|\\s_\\|\\s.\\)+>"
473 "Regular expression for matching inline email addresses.")
475 (defconst markdown-regex-latex-expression
476 "\\(^\\|[^\\]\\)\\(\\$\\($\\([^\\$]\\|\\\\.\\)*\\$\\|\\([^\\$]\\|\\\\.\\)*\\)\\$\\)"
477 "Regular expression for itex $..$ or $$..$$ math mode expressions.")
479 (defconst markdown-regex-latex-display
480 "^\\\\\\[\\(.\\|\n\\)*?\\\\\\]$"
481 "Regular expression for itex \[..\] display mode expressions.")
483 (defvar markdown-mode-font-lock-keywords-basic
484 (list
485 (cons markdown-regex-code '(2 markdown-inline-code-face))
486 (cons markdown-regex-pre 'markdown-blockquote-face)
487 (cons markdown-regex-blockquote 'markdown-blockquote-face)
488 (cons markdown-regex-header-1-setext 'markdown-header-face-1)
489 (cons markdown-regex-header-2-setext 'markdown-header-face-2)
490 (cons markdown-regex-header-1-atx 'markdown-header-face-1)
491 (cons markdown-regex-header-2-atx 'markdown-header-face-2)
492 (cons markdown-regex-header-3-atx 'markdown-header-face-3)
493 (cons markdown-regex-header-4-atx 'markdown-header-face-4)
494 (cons markdown-regex-hr 'markdown-header-face)
495 (cons markdown-regex-list 'markdown-list-face)
496 (cons markdown-regex-link-inline
497 '((1 markdown-link-face t)
498 (2 markdown-url-face t)))
499 (cons markdown-regex-link-reference
500 '((1 markdown-link-face t)
501 (2 markdown-reference-face t)))
502 (cons markdown-regex-reference-definition
503 '((1 markdown-reference-face t)
504 (2 markdown-url-face t)
505 (3 markdown-link-face t)))
506 (cons markdown-regex-wiki-link 'markdown-link-face)
507 (cons markdown-regex-bold '(2 markdown-bold-face))
508 (cons markdown-regex-italic '(2 markdown-italic-face))
509 (cons markdown-regex-uri 'markdown-link-face)
510 (cons markdown-regex-email 'markdown-link-face)
512 "Syntax highlighting for Markdown files.")
515 ;; Includes additional Latex/itex/Instiki font lock keywords
516 (defconst markdown-mode-font-lock-keywords-itex
517 (append
518 (list
519 ;; itex math mode $..$ or $$..$$
520 (cons markdown-regex-latex-expression '(2 markdown-math-face))
521 ;; Display mode equations with brackets: \[ \]
522 (cons markdown-regex-latex-display 'markdown-math-face)
523 ;; Equation reference (eq:foo)
524 (cons "(eq:\\w+)" 'markdown-reference-face)
525 ;; Equation reference \eqref
526 (cons "\\\\eqref{\\w+}" 'markdown-reference-face))
527 markdown-mode-font-lock-keywords-basic)
528 "Syntax highlighting for Markdown, itex, and wiki expressions.")
531 (defvar markdown-mode-font-lock-keywords
532 (if markdown-enable-itex
533 markdown-mode-font-lock-keywords-itex
534 markdown-mode-font-lock-keywords-basic)
535 "Default highlighting expressions for Markdown mode.")
539 ;;; Syntax Table ==============================================================
541 (defvar markdown-mode-syntax-table
542 (let ((markdown-mode-syntax-table (make-syntax-table)))
543 (modify-syntax-entry ?\" "w" markdown-mode-syntax-table)
544 markdown-mode-syntax-table)
545 "Syntax table for `markdown-mode'.")
549 ;;; Element Insertion =========================================================
551 (defun markdown-wrap-or-insert (s1 s2)
552 "Insert the strings S1 and S2.
553 If Transient Mark mode is on and a region is active, wrap the strings S1
554 and S2 around the region."
555 (if (and transient-mark-mode mark-active)
556 (let ((a (region-beginning)) (b (region-end)))
557 (goto-char a)
558 (insert s1)
559 (goto-char (+ b (length s1)))
560 (insert s2))
561 (insert s1 s2)))
563 (defun markdown-insert-hr ()
564 "Insert a horizonal rule."
565 (interactive)
566 (let (hr)
567 (dotimes (count (- markdown-hr-length 1) hr) ; Count to n - 1
568 (setq hr (concat "* " hr))) ; Build HR string
569 (setq hr (concat hr "*\n")) ; Add the n-th *
570 (insert hr)))
572 (defun markdown-insert-bold ()
573 "Insert markup for a bold word or phrase.
574 If Transient Mark mode is on and a region is active, it is made bold."
575 (interactive)
576 (if markdown-bold-underscore
577 (markdown-wrap-or-insert "__" "__")
578 (markdown-wrap-or-insert "**" "**"))
579 (backward-char 2))
581 (defun markdown-insert-italic ()
582 "Insert markup for an italic word or phrase.
583 If Transient Mark mode is on and a region is active, it is made italic."
584 (interactive)
585 (if markdown-italic-underscore
586 (markdown-wrap-or-insert "_" "_")
587 (markdown-wrap-or-insert "*" "*"))
588 (backward-char 1))
590 (defun markdown-insert-code ()
591 "Insert markup for an inline code fragment.
592 If Transient Mark mode is on and a region is active, it is marked
593 as inline code."
594 (interactive)
595 (markdown-wrap-or-insert "`" "`")
596 (backward-char 1))
598 (defun markdown-insert-link ()
599 "Insert an inline link of the form []().
600 If Transient Mark mode is on and a region is active, it is used
601 as the link text."
602 (interactive)
603 (markdown-wrap-or-insert "[" "]")
604 (insert "()")
605 (backward-char 1))
607 (defun markdown-insert-wiki-link ()
608 "Insert a wiki link of the form [[WikiLink]].
609 If Transient Mark mode is on and a region is active, it is used
610 as the link text."
611 (interactive)
612 (markdown-wrap-or-insert "[[" "]]")
613 (backward-char 2))
615 (defun markdown-insert-image ()
616 "Insert an inline image tag of the form ![]().
617 If Transient Mark mode is on and a region is active, it is used
618 as the alt text of the image."
619 (interactive)
620 (markdown-wrap-or-insert "![" "]")
621 (insert "()")
622 (backward-char 1))
624 (defun markdown-insert-header-1 ()
625 "Insert a first level atx-style (hash mark) header.
626 If Transient Mark mode is on and a region is active, it is used
627 as the header text."
628 (interactive)
629 (markdown-insert-header 1))
631 (defun markdown-insert-header-2 ()
632 "Insert a second level atx-style (hash mark) header.
633 If Transient Mark mode is on and a region is active, it is used
634 as the header text."
635 (interactive)
636 (markdown-insert-header 2))
638 (defun markdown-insert-header-3 ()
639 "Insert a third level atx-style (hash mark) header.
640 If Transient Mark mode is on and a region is active, it is used
641 as the header text."
642 (interactive)
643 (markdown-insert-header 3))
645 (defun markdown-insert-header-4 ()
646 "Insert a fourth level atx-style (hash mark) header.
647 If Transient Mark mode is on and a region is active, it is used
648 as the header text."
649 (interactive)
650 (markdown-insert-header 4))
652 (defun markdown-insert-header-5 ()
653 "Insert a fifth level atx-style (hash mark) header.
654 If Transient Mark mode is on and a region is active, it is used
655 as the header text."
656 (interactive)
657 (markdown-insert-header 5))
659 (defun markdown-insert-header (n)
660 "Insert an atx-style (hash mark) header.
661 With no prefix argument, insert a level-1 header. With prefix N,
662 insert a level-N header. If Transient Mark mode is on and the
663 region is active, it is used as the header text."
664 (interactive "p")
665 (unless n ; Test to see if n is defined
666 (setq n 1)) ; Default to level 1 header
667 (let (hdr hdrl hdrr)
668 (dotimes (count n hdr)
669 (setq hdr (concat "#" hdr))) ; Build a hash mark header string
670 (setq hdrl (concat hdr " "))
671 (setq hdrr (concat " " hdr))
672 (markdown-wrap-or-insert hdrl hdrr))
673 (backward-char (+ 1 n)))
675 (defun markdown-insert-title ()
676 "Insert a setext-style (underline) first level header.
677 If Transient Mark mode is on and a region is active, it is used
678 as the header text."
679 (interactive)
680 (if (and transient-mark-mode mark-active)
681 (let ((a (region-beginning))
682 (b (region-end))
683 (len 0)
684 (hdr))
685 (setq len (- b a))
686 (dotimes (count len hdr)
687 (setq hdr (concat "=" hdr))) ; Build a === title underline
688 (end-of-line)
689 (insert "\n" hdr "\n"))
690 (insert "\n==========\n")
691 (backward-char 12)))
693 (defun markdown-insert-section ()
694 "Insert a setext-style (underline) second level header.
695 If Transient Mark mode is on and a region is active, it is used
696 as the header text."
697 (interactive)
698 (if (and transient-mark-mode mark-active)
699 (let ((a (region-beginning))
700 (b (region-end))
701 (len 0)
702 (hdr))
703 (setq len (- b a))
704 (dotimes (count len hdr)
705 (setq hdr (concat "-" hdr))) ; Build a --- section underline
706 (end-of-line)
707 (insert "\n" hdr "\n"))
708 (insert "\n----------\n")
709 (backward-char 12)))
711 (defun markdown-insert-blockquote ()
712 "Start a blockquote section (or blockquote the region).
713 If Transient Mark mode is on and a region is active, it is used as
714 the blockquote text."
715 (interactive)
716 (if (and (boundp 'transient-mark-mode) transient-mark-mode mark-active)
717 (markdown-blockquote-region (region-beginning) (region-end))
718 (insert "> ")))
720 (defun markdown-block-region (beg end prefix)
721 "Format the region using a block prefix.
722 Arguments BEG and END specify the beginning and end of the
723 region.The characters PREFIX will appear at the beginning
724 of each line."
725 (if mark-active
726 (save-excursion
727 (let ((endpos end))
728 ; Ensure that there is a leading blank line
729 (goto-char beg)
730 (while (not (looking-back "\n\n" 2))
731 (insert "\n")
732 (setq endpos (+ 1 endpos)))
733 ; Insert blockquote characters
734 (move-to-left-margin)
735 (while (< (point-at-bol) endpos)
736 (insert prefix)
737 (setq endpos (+ (length prefix) endpos))
738 (forward-line))
739 ; Move back before any blank lines at the end
740 (goto-char endpos)
741 (while (looking-back "\n" 1)
742 (backward-char))
743 ; Ensure one blank line at the end
744 (while (not (looking-at "\n\n"))
745 (insert "\n")
746 (backward-char))))))
748 (defun markdown-blockquote-region (beg end)
749 "Blockquote the region.
750 Arguments BEG and END specify the beginning and end of the region."
751 (interactive "*r")
752 (markdown-block-region beg end "> "))
754 (defun markdown-insert-pre ()
755 "Start a preformatted section (or apply to the region).
756 If Transient Mark mode is on and a region is active, it is marked
757 as preformatted text."
758 (interactive)
759 (if (and (boundp 'transient-mark-mode) transient-mark-mode mark-active)
760 (markdown-pre-region (region-beginning) (region-end))
761 (insert " ")))
763 (defun markdown-pre-region (beg end)
764 "Format the region as preformatted text.
765 Arguments BEG and END specify the beginning and end of the region."
766 (interactive "*r")
767 (markdown-block-region beg end " "))
769 ;;; Indentation ====================================================================
771 ;;; Indentation functions contributed by Bryan Kyle <bryan.kyle@gmail.com>..
773 (defun markdown-indent-find-next-position (cur-pos positions)
774 "Return the position after the index of CUR-POS in POSITIONS."
775 (while (and positions
776 (not (equal cur-pos (car positions))))
777 (setq positions (cdr positions)))
778 (or (cadr positions) 0))
780 (defun markdown-indent-line ()
781 "Indent the current line using some heuristics."
782 (interactive)
783 (let (cur-pos
784 prev-line-pos
785 positions
786 computed-pos)
787 (setq cur-pos (current-column))
789 ;; Indentation of previous line
790 (setq pos
791 (save-excursion
792 (forward-line -1)
793 (goto-char (point-at-bol))
794 (when (re-search-forward "\s+" (point-at-eol) t)
795 (current-column))))
796 (if pos
797 (progn
798 (setq prev-line-pos pos)
799 (setq positions (cons pos positions))))
801 ;; Position of the first non-list marker on the previous line
802 (setq pos
803 (save-excursion
804 (forward-line -1)
805 (goto-char (point-at-bol))
806 (when (re-search-forward "\s*\\([0-9]\\.\\|[-\\*\\+]\\)\s*" (point-at-eol) t)
807 (current-column))))
808 (if pos
809 (setq positions (cons pos positions)))
811 ;; Indentation of the previous line + tab-width
812 (cond
813 (prev-line-pos
814 (setq positions (cons (+ (car positions) tab-width) positions)))
817 (setq positions (cons tab-width positions))))
819 ;; Indentation of the previous line - tab-width
820 (if (and prev-line-pos
821 (> prev-line-pos tab-width))
822 (setq positions (cons (- prev-line-pos tab-width) positions)))
824 ;; Indentation of the bullet of any preceeding line
825 (setq pos
826 (save-excursion
827 (catch 'break
828 (while (not (equal (point) 0))
829 (forward-line -1)
830 (goto-char (point-at-bol))
831 (when (re-search-forward "\s*\\([0-9]\\.\\|[-\\*\\+]\\)" (point-at-eol) t)
832 (throw 'break (- (current-column) (length (match-string 1))))))
833 nil)))
834 (if pos
835 (setq positions (cons pos positions)))
838 (setq positions (cons 0 (reverse positions)))
840 ;; If the current column is any of the positions, remove all of the positions up-to
841 ;; and including the current column
843 (setq computed-pos (markdown-indent-find-next-position cur-pos positions))
844 (indent-line-to computed-pos)))
847 (defun markdown-enter-key ()
848 "Insert a newline and optionally indent the next line."
849 (interactive)
850 (let (indent)
851 (if markdown-indent-on-enter
852 (setq indent
853 (save-excursion
854 (goto-char (point-at-bol))
855 (if (re-search-forward "^\s" (point-at-eol) t) t))))
856 (insert "\n")
857 (if indent (funcall indent-line-function))))
861 ;;; Keymap ====================================================================
863 (defvar markdown-mode-map
864 (let ((markdown-mode-map (make-keymap)))
865 ;; Element insertion
866 (define-key markdown-mode-map "\C-c\C-al" 'markdown-insert-link)
867 (define-key markdown-mode-map "\C-c\C-aw" 'markdown-insert-wiki-link)
868 (define-key markdown-mode-map "\C-c\C-ii" 'markdown-insert-image)
869 (define-key markdown-mode-map "\C-c\C-t1" 'markdown-insert-header-1)
870 (define-key markdown-mode-map "\C-c\C-t2" 'markdown-insert-header-2)
871 (define-key markdown-mode-map "\C-c\C-t3" 'markdown-insert-header-3)
872 (define-key markdown-mode-map "\C-c\C-t4" 'markdown-insert-header-4)
873 (define-key markdown-mode-map "\C-c\C-t5" 'markdown-insert-header-5)
874 (define-key markdown-mode-map "\C-c\C-pb" 'markdown-insert-bold)
875 (define-key markdown-mode-map "\C-c\C-ss" 'markdown-insert-bold)
876 (define-key markdown-mode-map "\C-c\C-pi" 'markdown-insert-italic)
877 (define-key markdown-mode-map "\C-c\C-se" 'markdown-insert-italic)
878 (define-key markdown-mode-map "\C-c\C-pf" 'markdown-insert-code)
879 (define-key markdown-mode-map "\C-c\C-sc" 'markdown-insert-code)
880 (define-key markdown-mode-map "\C-c\C-sb" 'markdown-insert-blockquote)
881 (define-key markdown-mode-map "\C-c\C-s\C-b" 'markdown-blockquote-region)
882 (define-key markdown-mode-map "\C-c\C-sp" 'markdown-insert-pre)
883 (define-key markdown-mode-map "\C-c\C-s\C-p" 'markdown-pre-region)
884 (define-key markdown-mode-map "\C-c-" 'markdown-insert-hr)
885 (define-key markdown-mode-map "\C-c\C-tt" 'markdown-insert-title)
886 (define-key markdown-mode-map "\C-c\C-ts" 'markdown-insert-section)
887 ;; Indentation
888 (define-key markdown-mode-map "\C-m" 'markdown-enter-key)
889 ;; Visibility cycling
890 (define-key markdown-mode-map (kbd "<tab>") 'markdown-cycle)
891 (define-key markdown-mode-map (kbd "<S-iso-lefttab>") 'markdown-shifttab)
892 ;; Markdown functions
893 (define-key markdown-mode-map "\C-c\C-cm" 'markdown)
894 (define-key markdown-mode-map "\C-c\C-cp" 'markdown-preview)
895 ;; References
896 (define-key markdown-mode-map "\C-c\C-cc" 'markdown-check-refs)
897 markdown-mode-map)
898 "Keymap for Markdown major mode.")
900 ;;; Menu ==================================================================
902 (easy-menu-define markdown-mode-menu markdown-mode-map
903 "Menu for Markdown mode"
904 '("Markdown"
905 ("Show/Hide"
906 ["Cycle visibility" markdown-cycle (outline-on-heading-p)]
907 ["Cycle global visibility" markdown-shifttab])
908 "---"
909 ["Compile" markdown]
910 ["Preview" markdown-preview]
911 "---"
912 ("Headers (setext)"
913 ["Insert Title" markdown-insert-title]
914 ["Insert Section" markdown-insert-section])
915 ("Headers (atx)"
916 ["First level" markdown-insert-header-1]
917 ["Second level" markdown-insert-header-2]
918 ["Third level" markdown-insert-header-3]
919 ["Fourth level" markdown-insert-header-4]
920 ["Fifth level" markdown-insert-header-5])
921 "---"
922 ["Bold" markdown-insert-bold]
923 ["Italic" markdown-insert-italic]
924 ["Blockquote" markdown-insert-blockquote]
925 ["Preformatted" markdown-insert-pre]
926 ["Code" markdown-insert-code]
927 "---"
928 ["Insert inline link" markdown-insert-link]
929 ["Insert image" markdown-insert-image]
930 ["Insert horizontal rule" markdown-insert-hr]
931 "---"
932 ["Check references" markdown-check-refs]
933 "---"
934 ["Version" markdown-show-version]
939 ;;; References ================================================================
941 ;;; Undefined reference checking code by Dmitry Dzhus <mail@sphinx.net.ru>.
943 (defconst markdown-refcheck-buffer
944 "*Undefined references for %BUFFER%*"
945 "Pattern for name of buffer for listing undefined references.
946 The string %BUFFER% will be replaced by the corresponding
947 `markdown-mode' buffer name.")
949 (defun markdown-has-reference-definition (reference)
950 "Find out whether Markdown REFERENCE is defined.
952 REFERENCE should include the square brackets, like [this]."
953 (let ((reference (downcase reference)))
954 (save-excursion
955 (goto-char (point-min))
956 (catch 'found
957 (while (re-search-forward markdown-regex-reference-definition nil t)
958 (when (string= reference (downcase (match-string-no-properties 1)))
959 (throw 'found t)))))))
961 (defun markdown-get-undefined-refs ()
962 "Return a list of undefined Markdown references.
964 Result is an alist of pairs (reference . occurencies), where
965 occurencies is itself another alist of pairs (label .
966 line-number).
968 For example, an alist corresponding to [Nice editor][Emacs] at line 12,
969 \[GNU Emacs][Emacs] at line 45 and [manual][elisp] at line 127 is
970 \((\"[emacs]\" (\"[Nice editor]\" . 12) (\"[GNU Emacs]\" . 45)) (\"[elisp]\" (\"[manual]\" . 127)))."
971 (let ((missing))
972 (save-excursion
973 (goto-char (point-min))
974 (while
975 (re-search-forward markdown-regex-link-reference nil t)
976 (let* ((label (match-string-no-properties 1))
977 (reference (match-string-no-properties 2))
978 (target (downcase (if (string= reference "[]") label reference))))
979 (unless (markdown-has-reference-definition target)
980 (let ((entry (assoc target missing)))
981 (if (not entry)
982 (add-to-list 'missing (cons target
983 (list (cons label (markdown-line-number-at-pos)))) t)
984 (setcdr entry
985 (append (cdr entry) (list (cons label (markdown-line-number-at-pos))))))))))
986 missing)))
988 (defun markdown-add-missing-ref-definition (ref buffer &optional recheck)
989 "Add blank REF definition to the end of BUFFER.
991 REF is a Markdown reference in square brackets, like \"[lisp-history]\".
993 When RECHECK is non-nil, BUFFER gets rechecked for undefined
994 references so that REF disappears from the list of those links."
995 (with-current-buffer buffer
996 (when (not (eq major-mode 'markdown-mode))
997 (error "Not available in current mdoe"))
998 (goto-char (point-max))
999 (indent-new-comment-line)
1000 (insert (concat ref ": ")))
1001 (switch-to-buffer-other-window buffer)
1002 (goto-char (point-max))
1003 (when recheck
1004 (markdown-check-refs t)))
1006 ;; Button which adds an empty Markdown reference definition to the end
1007 ;; of buffer specified as its 'target-buffer property. Reference name
1008 ;; is button's label
1009 (when (>= emacs-major-version 22)
1010 (define-button-type 'markdown-ref-button
1011 'help-echo "Push to create an empty reference definition"
1012 'face 'bold
1013 'action (lambda (b)
1014 (markdown-add-missing-ref-definition
1015 (button-label b) (button-get b 'target-buffer) t))))
1017 ;; Button jumping to line in buffer specified as its 'target-buffer
1018 ;; property. Line number is button's 'line property.
1019 (when (>= emacs-major-version 22)
1020 (define-button-type 'goto-line-button
1021 'help-echo "Push to go to this line"
1022 'face 'italic
1023 'action (lambda (b)
1024 (message (button-get b 'buffer))
1025 (switch-to-buffer-other-window (button-get b 'target-buffer))
1026 (goto-line (button-get b 'target-line)))))
1028 (defun markdown-check-refs (&optional silent)
1029 "Show all undefined Markdown references in current `markdown-mode' buffer.
1031 If SILENT is non-nil, do not message anything when no undefined
1032 references found.
1034 Links which have empty reference definitions are considered to be
1035 defined."
1036 (interactive "P")
1037 (when (not (eq major-mode 'markdown-mode))
1038 (error "Not available in current mode"))
1039 (let ((oldbuf (current-buffer))
1040 (refs (markdown-get-undefined-refs))
1041 (refbuf (get-buffer-create (replace-regexp-in-string
1042 "%BUFFER%" (buffer-name)
1043 markdown-refcheck-buffer t))))
1044 (if (null refs)
1045 (progn
1046 (when (not silent)
1047 (message "No undefined references found"))
1048 (kill-buffer refbuf))
1049 (with-current-buffer refbuf
1050 (when view-mode
1051 (View-exit-and-edit))
1052 (erase-buffer)
1053 (insert "Following references lack definitions:")
1054 (newline 2)
1055 (dolist (ref refs)
1056 (let ((button-label (format "%s" (car ref))))
1057 (if (>= emacs-major-version 22)
1058 ;; Create a reference button in Emacs 22
1059 (insert-text-button button-label
1060 :type 'markdown-ref-button
1061 'target-buffer oldbuf)
1062 ;; Insert reference as text in Emacs < 22
1063 (insert button-label)))
1064 (insert " (")
1065 (dolist (occurency (cdr ref))
1066 (let ((line (cdr occurency)))
1067 (if (>= emacs-major-version 22)
1068 ;; Create a line number button in Emacs 22
1069 (insert-button (number-to-string line)
1070 :type 'goto-line-button
1071 'target-buffer oldbuf
1072 'target-line line)
1073 ;; Insert line number as text in Emacs < 22
1074 (insert (number-to-string line)))
1075 (insert " "))) (delete-backward-char 1)
1076 (insert ")")
1077 (newline))
1078 (view-buffer-other-window refbuf)
1079 (goto-line 4)))))
1082 ;;; Outline ===================================================================
1084 ;; The following visibility cycling code was taken from org-mode
1085 ;; by Carsten Dominik and adapted for markdown-mode.
1087 (defvar markdown-cycle-global-status 1)
1088 (defvar markdown-cycle-subtree-status nil)
1090 ;; Based on org-end-of-subtree from org.el
1091 (defun markdown-end-of-subtree (&optional invisible-OK)
1092 "Move to the end of the current subtree.
1093 Only visible heading lines are considered, unless INVISIBLE-OK is
1094 non-nil."
1095 (outline-back-to-heading invisible-OK)
1096 (let ((first t)
1097 (level (funcall outline-level)))
1098 (while (and (not (eobp))
1099 (or first (> (funcall outline-level) level)))
1100 (setq first nil)
1101 (outline-next-heading))
1102 (if (memq (preceding-char) '(?\n ?\^M))
1103 (progn
1104 ;; Go to end of line before heading
1105 (forward-char -1)
1106 (if (memq (preceding-char) '(?\n ?\^M))
1107 ;; leave blank line before heading
1108 (forward-char -1)))))
1109 (point))
1111 ;; Based on org-cycle from org.el.
1112 (defun markdown-cycle (&optional arg)
1113 "Visibility cycling for Markdown mode.
1114 If ARG is t, perform global visibility cycling. If the point is
1115 at an atx-style header, cycle visibility of the corresponding
1116 subtree. Otherwise, insert a tab using `indent-relative'."
1117 (interactive "P")
1118 (cond
1119 ((eq arg t) ;; Global cycling
1120 (cond
1121 ((and (eq last-command this-command)
1122 (eq markdown-cycle-global-status 2))
1123 ;; Move from overview to contents
1124 (hide-sublevels 1)
1125 (message "CONTENTS")
1126 (setq markdown-cycle-global-status 3))
1128 ((and (eq last-command this-command)
1129 (eq markdown-cycle-global-status 3))
1130 ;; Move from contents to all
1131 (show-all)
1132 (message "SHOW ALL")
1133 (setq markdown-cycle-global-status 1))
1136 ;; Defaults to overview
1137 (hide-body)
1138 (message "OVERVIEW")
1139 (setq markdown-cycle-global-status 2))))
1141 ((save-excursion (beginning-of-line 1) (looking-at outline-regexp))
1142 ;; At a heading: rotate between three different views
1143 (outline-back-to-heading)
1144 (let ((goal-column 0) eoh eol eos)
1145 ;; Determine boundaries
1146 (save-excursion
1147 (outline-back-to-heading)
1148 (save-excursion
1149 (beginning-of-line 2)
1150 (while (and (not (eobp)) ;; this is like `next-line'
1151 (get-char-property (1- (point)) 'invisible))
1152 (beginning-of-line 2)) (setq eol (point)))
1153 (outline-end-of-heading) (setq eoh (point))
1154 (markdown-end-of-subtree t)
1155 (skip-chars-forward " \t\n")
1156 (beginning-of-line 1) ; in case this is an item
1157 (setq eos (1- (point))))
1158 ;; Find out what to do next and set `this-command'
1159 (cond
1160 ((= eos eoh)
1161 ;; Nothing is hidden behind this heading
1162 (message "EMPTY ENTRY")
1163 (setq markdown-cycle-subtree-status nil))
1164 ((>= eol eos)
1165 ;; Entire subtree is hidden in one line: open it
1166 (show-entry)
1167 (show-children)
1168 (message "CHILDREN")
1169 (setq markdown-cycle-subtree-status 'children))
1170 ((and (eq last-command this-command)
1171 (eq markdown-cycle-subtree-status 'children))
1172 ;; We just showed the children, now show everything.
1173 (show-subtree)
1174 (message "SUBTREE")
1175 (setq markdown-cycle-subtree-status 'subtree))
1177 ;; Default action: hide the subtree.
1178 (hide-subtree)
1179 (message "FOLDED")
1180 (setq markdown-cycle-subtree-status 'folded)))))
1183 (message "TAB")
1184 (funcall indent-line-function))))
1186 ;; Based on org-shifttab from org.el.
1187 (defun markdown-shifttab ()
1188 "Global visibility cycling.
1189 Calls `markdown-cycle' with argument t."
1190 (interactive)
1191 (markdown-cycle t))
1193 ;;; Commands ==================================================================
1195 (defun markdown ()
1196 "Run markdown on the current buffer and preview the output in another buffer."
1197 (interactive)
1198 (if (and (boundp 'transient-mark-mode) transient-mark-mode mark-active)
1199 (shell-command-on-region (region-beginning) (region-end) markdown-command
1200 "*markdown-output*" nil)
1201 (shell-command-on-region (point-min) (point-max) markdown-command
1202 "*markdown-output*" nil)))
1204 (defun markdown-preview ()
1205 "Run markdown on the current buffer and preview the output in a browser."
1206 (interactive)
1207 (markdown)
1208 (browse-url-of-buffer "*markdown-output*"))
1211 ;;; Miscellaneous =============================================================
1213 (defun markdown-line-number-at-pos (&optional pos)
1214 "Return (narrowed) buffer line number at position POS.
1215 If POS is nil, use current buffer location.
1216 This is an exact copy of `line-number-at-pos' for use in emacs21."
1217 (let ((opoint (or pos (point))) start)
1218 (save-excursion
1219 (goto-char (point-min))
1220 (setq start (point))
1221 (goto-char opoint)
1222 (forward-line 0)
1223 (1+ (count-lines start (point))))))
1227 ;;; Mode definition ==========================================================
1229 (defun markdown-show-version ()
1230 "Show the version number in the minibuffer."
1231 (interactive)
1232 (message "markdown-mode, version %s" markdown-mode-version))
1234 (define-derived-mode markdown-mode text-mode "Markdown"
1235 "Major mode for editing Markdown files."
1236 ;; Font lock.
1237 (set (make-local-variable 'font-lock-defaults)
1238 '(markdown-mode-font-lock-keywords))
1239 (set (make-local-variable 'font-lock-multiline) t)
1240 ;; For menu support in XEmacs
1241 (easy-menu-add markdown-mode-menu markdown-mode-map)
1242 ;; Make filling work with lists
1243 (set (make-local-variable 'paragraph-start)
1244 "\f\\|[ \t]*$\\|^[ \t]*[*+-] \\|^[ \t*][0-9]+\\. ")
1245 ;; Outline mode
1246 (make-local-variable 'outline-regexp)
1247 (setq outline-regexp "#+")
1248 ;; Cause use of ellipses for invisible text.
1249 (add-to-invisibility-spec '(outline . t))
1250 ;; Indentation
1251 (setq indent-line-function markdown-indent-function))
1253 ;(add-to-list 'auto-mode-alist '("\\.text$" . markdown-mode))
1255 (provide 'markdown-mode)
1257 ;;; markdown-mode.el ends here