   :group 'markdown
   :type 'boolean)
 
+(defcustom markdown-indent-function 'markdown-indent-line
+  "Function to use to indent."
+  :group 'markdown
+  :type 'function)
+
+(defcustom markdown-indent-on-enter t
+  "Automatically indent new lines when enter key is pressed."
+  :group 'markdown
+  :type 'boolean)
+
+(defcustom markdown-follow-wiki-link-on-enter t
+  "Follow wiki link at point (if any) when the enter key is pressed."
+  :group 'markdown
+  :type 'boolean)
+
+(defcustom markdown-uri-types
+  '("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")
+  "Link types for syntax highlighting of URIs."
+  :group 'markdown
+  :type 'list)
+
+(defcustom markdown-enable-math nil
+  "Syntax highlighting for inline LaTeX expressions.
+This will not take effect until Emacs is restarted."
+  :group 'markdown
+  :type 'boolean)
+
+(defcustom markdown-css-path ""
+  "URL of CSS file to link to in the output XHTML."
+  :group 'markdown
+  :type 'string)
+
+(defcustom markdown-xhtml-header-content ""
+  "Additional content to include in the XHTML <head> block."
+  :group 'markdown
+  :type 'string)
+
+(defcustom markdown-xhtml-standalone-regexp
+  "^\\(\<\?xml\\|\<!DOCTYPE\\|\<html\\)"
+  "Regexp indicating whether `markdown-command' output is standalone XHTML."
+  :group 'markdown
+  :type 'regexp)
 
 ;;; Font lock =================================================================
 
 (require 'font-lock)
+
+(defvar markdown-italic-face 'markdown-italic-face
+  "Face name to use for italic text.")
+
+(defvar markdown-bold-face 'markdown-bold-face
+  "Face name to use for bold text.")
+
+(defvar markdown-header-face 'markdown-header-face
+  "Face name to use as a base for headers.")
+
+(defvar markdown-header-face-1 'markdown-header-face-1
+  "Face name to use for level-1 headers.")
+
+(defvar markdown-header-face-2 'markdown-header-face-2
+  "Face name to use for level-2 headers.")
+
+(defvar markdown-header-face-3 'markdown-header-face-3
+  "Face name to use for level-3 headers.")
+
+(defvar markdown-header-face-4 'markdown-header-face-4
+  "Face name to use for level-4 headers.")
+
+(defvar markdown-header-face-5 'markdown-header-face-5
+  "Face name to use for level-5 headers.")
+
+(defvar markdown-header-face-6 'markdown-header-face-6
+  "Face name to use for level-6 headers.")
+
+(defvar markdown-inline-code-face 'markdown-inline-code-face
+  "Face name to use for inline code.")
+
+(defvar markdown-list-face 'markdown-list-face
+  "Face name to use for list markers.")
+
+(defvar markdown-blockquote-face 'markdown-blockquote-face
+  "Face name to use for blockquote.")
+
+(defvar markdown-pre-face 'markdown-pre-face
+  "Face name to use for preformatted text.")
+
+(defvar markdown-link-face 'markdown-link-face
+  "Face name to use for links.")
+
+(defvar markdown-missing-link-face 'markdown-missing-link-face
+  "Face name to use for links where the linked file does not exist.")
+
+(defvar markdown-reference-face 'markdown-reference-face
+  "Face name to use for reference.")
+
+(defvar markdown-url-face 'markdown-url-face
+  "Face name to use for URLs.")
+
+(defvar markdown-link-title-face 'markdown-link-title-face
+  "Face name to use for reference link titles.")
+
+(defvar markdown-comment-face 'markdown-comment-face
+  "Face name to use for HTML comments.")
+
+(defvar markdown-math-face 'markdown-math-face
+  "Face name to use for LaTeX expressions.")
 
 (defgroup markdown-faces nil
   "Faces used in Markdown Mode"
   :group 'markdown
   :group 'faces)
 
-(defcustom markdown-italic-face 'font-lock-variable-name-face
-  "Italic text."
-  :group 'markdown-faces
-  :type '(face))
-
-(defcustom markdown-bold-face 'font-lock-type-face
-  "Bold text"
-  :group 'markdown-faces
-  :type '(face))
-
-(defcustom markdown-header-face 'font-lock-function-name-face
-  "Headers"
-  :group 'markdown-faces
-  :type '(face))
-
-(defcustom markdown-inline-code-face 'font-lock-builtin-face
-  "Inline code"
-  :group 'markdown-faces
-  :type '(face))
-
-(defcustom markdown-list-face 'font-lock-variable-name-face
-  "List item markers"
-  :group 'markdown-faces
-  :type '(face))
-
-(defcustom markdown-blockquote-face 'font-lock-comment-face
-  "Blockquote sections and preformatted text"
-  :group 'markdown-faces
-  :type '(face))
-
-(defcustom markdown-link-face 'font-lock-constant-face
-  "Link text"
-  :group 'markdown-faces
-  :type '(face))
-
-(defcustom markdown-reference-face 'font-lock-type-face
-  "Link references"
-  :group 'markdown-faces
-  :type '(face))
-
-(defcustom markdown-url-face 'font-lock-string-face
-  "URLs"
-  :group 'markdown-faces
-  :type '(face))
-
-(defcustom markdown-math-face 'font-lock-builtin-face
-  "LaTeX expressions"
-  :group 'markdown-faces
-  :type '(face))
+(defface markdown-italic-face
+  '((t :inherit font-lock-variable-name-face :italic t))
+  "Face for italic text."
+  :group 'markdown-faces)
+
+(defface markdown-bold-face
+  '((t :inherit font-lock-variable-name-face :bold t))
+  "Face for bold text."
+  :group 'markdown-faces)
+
+(defface markdown-header-face
+  '((t :inherit font-lock-function-name-face :weight bold))
+  "Base face for headers."
+  :group 'markdown-faces)
+
+(defface markdown-header-face-1
+  '((t :inherit markdown-header-face))
+  "Face for level-1 headers."
+  :group 'markdown-faces)
+
+(defface markdown-header-face-2
+  '((t :inherit markdown-header-face))
+  "Face for level-2 headers."
+  :group 'markdown-faces)
+
+(defface markdown-header-face-3
+  '((t :inherit markdown-header-face))
+  "Face for level-3 headers."
+  :group 'markdown-faces)
+
+(defface markdown-header-face-4
+  '((t :inherit markdown-header-face))
+  "Face for level-4 headers."
+  :group 'markdown-faces)
+
+(defface markdown-header-face-5
+  '((t :inherit markdown-header-face))
+  "Face for level-5 headers."
+  :group 'markdown-faces)
+
+(defface markdown-header-face-6
+  '((t :inherit markdown-header-face))
+  "Face for level-6 headers."
+  :group 'markdown-faces)
+
+(defface markdown-inline-code-face
+  '((t :inherit font-lock-constant-face))
+  "Face for inline code."
+  :group 'markdown-faces)
+
+(defface markdown-list-face
+  '((t :inherit font-lock-builtin-face))
+  "Face for list item markers."
+  :group 'markdown-faces)
+
+(defface markdown-blockquote-face
+  '((t :inherit font-lock-doc-face))
+  "Face for blockquote sections."
+  :group 'markdown-faces)
+
+(defface markdown-pre-face
+  '((t :inherit font-lock-constant-face))
+  "Face for preformatted text."
+  :group 'markdown-faces)
+
+(defface markdown-link-face
+  '((t :inherit font-lock-keyword-face))
+  "Face for links."
+  :group 'markdown-faces)
+
+(defface markdown-missing-link-face
+  '((t :inherit font-lock-warning-face))
+  "Face for missing links."
+  :group 'markdown-faces)
+
+(defface markdown-reference-face
+  '((t :inherit font-lock-type-face))
+  "Face for link references."
+  :group 'markdown-faces)
+
+(defface markdown-url-face
+  '((t :inherit font-lock-string-face))
+  "Face for URLs."
+  :group 'markdown-faces)
+
+(defface markdown-link-title-face
+  '((t :inherit font-lock-comment-face))
+  "Face for reference link titles."
+  :group 'markdown-faces)
+
+(defface markdown-comment-face
+  '((t :inherit font-lock-comment-face))
+  "Face for HTML comments."
+  :group 'markdown-faces)
+
+(defface markdown-math-face
+  '((t :inherit font-lock-string-face))
+  "Face for LaTeX expressions."
+  :group 'markdown-faces)
 
 (defconst markdown-regex-link-inline
   "\\(!?\\[[^]]*?\\]\\)\\(([^\\)]*)\\)"
-  "Regular expression for a [text](file) or an image link ![text](file)")
+  "Regular expression for a [text](file) or an image link ![text](file).")
 
 (defconst markdown-regex-link-reference
   "\\(!?\\[[^]]+?\\]\\)[ ]?\\(\\[[^]]*?\\]\\)"
-  "Regular expression for a reference link [text][id]")
+  "Regular expression for a reference link [text][id].")
 
 (defconst markdown-regex-reference-definition
   "^ \\{0,3\\}\\(\\[.+?\\]\\):\\s *\\(.*?\\)\\s *\\( \"[^\"]*\"$\\|$\\)"
   "Regular expression for a link definition [id]: ...")
 
-(defconst markdown-regex-header-atx
-  "^\\(#+ \\)\\(.*?\\)\\($\\| #+$\\)"
-  "Regular expression for atx-style (hash mark) headers")
-
-(defconst markdown-regex-header-setext
-  "^\\(.*\\)\n\\(===+\\|---+\\)$"
-  "Regular expression for setext-style (underline) headers")
+(defconst markdown-regex-header-1-atx
+  "^\\(# \\)\\(.*?\\)\\($\\| #+$\\)"
+  "Regular expression for level 1 atx-style (hash mark) headers.")
+
+(defconst markdown-regex-header-2-atx
+  "^\\(## \\)\\(.*?\\)\\($\\| #+$\\)"
+  "Regular expression for level 2 atx-style (hash mark) headers.")
+
+(defconst markdown-regex-header-3-atx
+  "^\\(### \\)\\(.*?\\)\\($\\| #+$\\)"
+  "Regular expression for level 3 atx-style (hash mark) headers.")
+
+(defconst markdown-regex-header-4-atx
+  "^\\(#### \\)\\(.*?\\)\\($\\| #+$\\)"
+  "Regular expression for level 4 atx-style (hash mark) headers.")
+
+(defconst markdown-regex-header-5-atx
+  "^\\(##### \\)\\(.*?\\)\\($\\| #+$\\)"
+  "Regular expression for level 5 atx-style (hash mark) headers.")
+
+(defconst markdown-regex-header-6-atx
+  "^\\(###### \\)\\(.*?\\)\\($\\| #+$\\)"
+  "Regular expression for level 6 atx-style (hash mark) headers.")
+
+(defconst markdown-regex-header-1-setext
+  "^\\(.*\\)\n\\(===+\\)$"
+  "Regular expression for level 1 setext-style (underline) headers.")
+
+(defconst markdown-regex-header-2-setext
+  "^\\(.*\\)\n\\(---+\\)$"
+  "Regular expression for level 2 setext-style (underline) headers.")
 
 (defconst markdown-regex-hr
   "^\\(\\*[ ]?\\*[ ]?\\*[ ]?[\\* ]*\\|-[ ]?-[ ]?-[--- ]*\\)$"
-  "Regular expression for matching Markdown horizontal rules")
+  "Regular expression for matching Markdown horizontal rules.")
 
 (defconst markdown-regex-code
-  "\\(^\\|[^\\]\\)\\(\\(`\\{1,2\\}\\)\\([^ \\]\\|[^ ].*?[^ \\]\\)\\3\\)"
-  "Regular expression for matching inline code fragments")
+  "\\(^\\|[^\\]\\)\\(\\(`\\{1,2\\}\\)\\([^ \\]\\|[^ ]\\(.\\|\n[^\n]\\)*?[^ \\]\\)\\3\\)"
+  "Regular expression for matching inline code fragments.")
 
 (defconst markdown-regex-pre
-  "^    .*$"
-  "Regular expression for matching preformatted text sections")
+  "^\\(    \\|\t\\).*$"
+  "Regular expression for matching preformatted text sections.")
 
 (defconst markdown-regex-list
   "^[ \t]*\\([0-9]+\\.\\|[\\*\\+-]\\) "
-  "Regular expression for matching list markers")
+  "Regular expression for matching list markers.")
 
 (defconst markdown-regex-bold
-  "\\(^\\|[^\\]\\)\\(\\([*_]\\{2\\}\\)\\(.\\|\n\\)*?[^\\ ]\\3\\)"
-  "Regular expression for matching bold text")
+  "\\(^\\|[^\\]\\)\\(\\([*_]\\{2\\}\\)\\(.\\|\n[^\n]\\)*?[^\\ ]\\3\\)"
+  "Regular expression for matching bold text.")
 
 (defconst markdown-regex-italic
-  "\\(^\\|[^\\]\\)\\(\\([*_]\\)\\([^ \\]\\3\\|[^ ]\\(.\\|\n\\)*?[^\\ ]\\3\\)\\)"
-  "Regular expression for matching italic text")
+  "\\(^\\|[^\\]\\)\\(\\([*_]\\)\\([^ \\]\\3\\|[^ ]\\(.\\|\n[^\n]\\)*?[^\\ ]\\3\\)\\)"
+  "Regular expression for matching italic text.")
 
 (defconst markdown-regex-blockquote
   "^>.*$"
-  "Regular expression for matching blockquote lines")
+  "Regular expression for matching blockquote lines.")
 
 (defconst markdown-regex-line-break
   "  $"
-  "Regular expression for matching line breaks")
+  "Regular expression for matching line breaks.")
 
 (defconst markdown-regex-wiki-link
-  "\\[\\[[^]]+\\]\\]"
-  "Regular expression for matching wiki links")
+  "\\[\\[\\([^]|]+\\)\\(|\\([^]]+\\)\\)?\\]\\]"
+  "Regular expression for matching wiki links.
+This matches typical bracketed [[WikiLinks]] as well as 'aliased'
+wiki links of the form [[PageName|link text]].  In this regular
+expression, #1 matches the page name and #3 matches the link
+text.")
 
 (defconst markdown-regex-uri
-  "<\\(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\\)://[^>]*>"
-  "Regular expression for matching inline URIs")
+  (concat
+   "\\(" (mapconcat 'identity markdown-uri-types "\\|")
+   "\\):[^]\t\n\r<>,;() ]+")
+  "Regular expression for matching inline URIs.")
+
+(defconst markdown-regex-angle-uri
+  (concat
+   "\\(<\\)\\("
+   (mapconcat 'identity markdown-uri-types "\\|")
+   "\\):[^]\t\n\r<>,;()]+\\(>\\)")
+  "Regular expression for matching inline URIs in angle brackets.")
 
 (defconst markdown-regex-email
   "<\\(\\sw\\|\\s_\\|\\s.\\)+@\\(\\sw\\|\\s_\\|\\s.\\)+>"
-  "Regular expression for matching inline email addresses")
+  "Regular expression for matching inline email addresses.")
 
 (defconst markdown-regex-latex-expression
   "\\(^\\|[^\\]\\)\\(\\$\\($\\([^\\$]\\|\\\\.\\)*\\$\\|\\([^\\$]\\|\\\\.\\)*\\)\\$\\)"
-  "Regular expression for itex $..$ or $$..$$ math mode expressions")
+  "Regular expression for itex $..$ or $$..$$ math mode expressions.")
 
 (defconst markdown-regex-latex-display
     "^\\\\\\[\\(.\\|\n\\)*?\\\\\\]$"
-  "Regular expression for itex \[..\] display mode expressions")
-
-(defconst markdown-mode-font-lock-keywords-basic
+  "Regular expression for itex \[..\] display mode expressions.")
+
+(defconst markdown-regex-list-indent
+  "^\\(\\s *\\)\\([0-9]+\\.\\|[\\*\\+-]\\)\\(\\s +\\)"
+  "Regular expression for matching indentation of list items.")
+
+(defvar markdown-mode-font-lock-keywords-basic
   (list
+   '(markdown-match-pre-blocks 0 markdown-pre-face t t)
+   (cons markdown-regex-blockquote 'markdown-blockquote-face)
+   (cons markdown-regex-header-1-setext 'markdown-header-face-1)
+   (cons markdown-regex-header-2-setext 'markdown-header-face-2)
+   (cons markdown-regex-header-1-atx 'markdown-header-face-1)
+   (cons markdown-regex-header-2-atx 'markdown-header-face-2)
+   (cons markdown-regex-header-3-atx 'markdown-header-face-3)
+   (cons markdown-regex-header-4-atx 'markdown-header-face-4)
+   (cons markdown-regex-header-5-atx 'markdown-header-face-5)
+   (cons markdown-regex-header-6-atx 'markdown-header-face-6)
+   (cons markdown-regex-hr 'markdown-header-face)
+   '(markdown-match-comments 0 markdown-comment-face t t)
    (cons markdown-regex-code '(2 markdown-inline-code-face))
-   (cons markdown-regex-pre markdown-blockquote-face)
-   (cons markdown-regex-header-setext markdown-header-face)
-   (cons markdown-regex-header-atx markdown-header-face)
-   (cons markdown-regex-list markdown-list-face)
-   (cons markdown-regex-hr markdown-header-face)
+   (cons markdown-regex-list 'markdown-list-face)
    (cons markdown-regex-link-inline
          '((1 markdown-link-face t)
            (2 markdown-url-face t)))

  (backward-char 1))

(defun markdown-insert-link ()
  "Inserts an inline link of the form []().
If Transient Mark mode is on and a region is active, it is used
as the link text."
  (interactive)

as preformatted text."
  (interactive)
  (if (and (boundp 'transient-mark-mode) transient-mark-mode mark-active)
      (markdown-pre-region (region-beginning) (region-end))
    (insert "    ")))

(defun markdown-pre-region (beg end)
  "Format the region as preformatted text.
Arguments BEG and END specify the beginning and end of the region."
  (interactive "*r")
  (markdown-block-region beg end "    "))

;;; Indentation ====================================================================

(defun markdown-indent-find-next-position (cur-pos positions)
  "Return the position after the index of CUR-POS in POSITIONS."
  (while (and positions
              (not (equal cur-pos (car positions))))
    (setq positions (cdr positions)))
  (or (cadr positions) 0))

(defun markdown-indent-line ()
  "Indent the current line using some heuristics.
If the _previous_ command was either `markdown-enter-key' or
`markdown-cycle', then we should cycle to the next
reasonable indentation position.  Otherwise, we could have been
called directly by `markdown-enter-key', by an initial call of
`markdown-cycle', or indirectly by `auto-fill-mode'.  In
these cases, indent to the default position."
  (interactive)
  (let ((positions (markdown-calc-indents))
        (cur-pos (current-column)))
    (if (not (equal this-command 'markdown-cycle))
        (indent-line-to (car positions))
      (setq positions (sort (delete-dups positions) '<))
      (indent-line-to
       (markdown-indent-find-next-position cur-pos positions)))))

(defun markdown-calc-indents ()
  "Return a list of indentation columns to cycle through.
The first element in the returned list should be considered the
default indentation level."
  (let (pos prev-line-pos positions)

    ;; Previous line indent
    (setq prev-line-pos (markdown-prev-line-indent))
    (setq positions (cons prev-line-pos positions))

    ;; Previous non-list-marker indent
    (setq pos (markdown-prev-non-list-indent))
    (if pos
        (setq positions (cons pos positions)))

    ;; Indentation of the previous line + tab-width
    (cond
     (prev-line-pos
      (setq positions (cons (+ prev-line-pos tab-width) positions)))
     (t
      (setq positions (cons tab-width positions))))

    ;; Indentation of the previous line - tab-width
    (if (and prev-line-pos
             (> prev-line-pos tab-width))
        (setq positions (cons (- prev-line-pos tab-width) positions)))

    ;; Indentation of preceeding list item
    (setq pos
          (save-excursion
            (forward-line -1)
            (catch 'break
              (while (not (equal (point) (point-min)))
                (forward-line -1)
                (goto-char (point-at-bol))
                (when (re-search-forward markdown-regex-list-indent (point-at-eol) t)
                  (throw 'break (length (match-string 1)))))
              nil)))
    (if (and pos (not (eq pos prev-line-pos)))
        (setq positions (cons pos positions)))

    ;; First column
    (setq positions (cons 0 positions))

    (reverse positions)))

(defun markdown-do-normal-return ()
  "Insert a newline and optionally indent the next line."
  (newline)
  (if markdown-indent-on-enter
      (funcall indent-line-function)))

(defun markdown-enter-key ()
  "Handle RET according to context.
If there is a wiki link at the point, follow it unless
`markdown-follow-wiki-link-on-enter' is nil.  Otherwise, process
it in the usual way."
  (interactive)
  (if (and markdown-follow-wiki-link-on-enter (markdown-wiki-link-p))
      (markdown-follow-wiki-link-at-point)
    (markdown-do-normal-return)))


