rst.el 149 KB
Newer Older
Stefan Monnier's avatar
Stefan Monnier committed
1 2
;;; rst.el --- Mode for viewing and editing reStructuredText-documents.

Paul Eggert's avatar
Paul Eggert committed
3
;; Copyright (C) 2003-2015 Free Software Foundation, Inc.
Stefan Monnier's avatar
Stefan Monnier committed
4

5
;; Maintainer: Stefan Merten <smerten@oekonux.de>
6 7
;; Author: Stefan Merten <smerten@oekonux.de>,
;;         Martin Blais <blais@furius.ca>,
8 9
;;         David Goodger <goodger@python.org>,
;;         Wei-Wei Guo <wwguocn@gmail.com>
Stefan Monnier's avatar
Stefan Monnier committed
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27

;; This file is part of GNU Emacs.

;; GNU Emacs is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.

;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.

;;; Commentary:

28
;; This package provides major mode rst-mode, which supports documents marked
29 30 31 32
;; up using the reStructuredText format.  Support includes font locking as well
;; as a lot of convenience functions for editing.  It does this by defining a
;; Emacs major mode: rst-mode (ReST).  This mode is derived from text-mode.
;; This package also contains:
Stefan Monnier's avatar
Stefan Monnier committed
33 34
;;
;; - Functions to automatically adjust and cycle the section underline
35
;;   adornments;
Stefan Monnier's avatar
Stefan Monnier committed
36 37 38 39
;; - A mode that displays the table of contents and allows you to jump anywhere
;;   from it;
;; - Functions to insert and automatically update a TOC in your source
;;   document;
40 41 42 43 44
;; - Function to insert list, processing item bullets and enumerations
;;   automatically;
;; - Font-lock highlighting of most reStructuredText structures;
;; - Indentation and filling according to reStructuredText syntax;
;; - Cursor movement according to reStructuredText syntax;
Stefan Monnier's avatar
Stefan Monnier committed
45 46 47 48 49 50 51 52 53 54 55 56
;; - Some other convenience functions.
;;
;; See the accompanying document in the docutils documentation about
;; the contents of this package and how to use it.
;;
;; For more information about reStructuredText, see
;; http://docutils.sourceforge.net/rst.html
;;
;; For full details on how to use the contents of this file, see
;; http://docutils.sourceforge.net/docs/user/emacs.html
;;
;;
57
;; There are a number of convenient key bindings provided by rst-mode.
Stefan Monnier's avatar
Stefan Monnier committed
58
;; For more on bindings, see rst-mode-map below.  There are also many variables
59
;; that can be customized, look for defcustom in this file.
Stefan Monnier's avatar
Stefan Monnier committed
60 61
;;
;; If you use the table-of-contents feature, you may want to add a hook to
62
;; update the TOC automatically every time you adjust a section title::
Stefan Monnier's avatar
Stefan Monnier committed
63 64 65
;;
;;   (add-hook 'rst-adjust-hook 'rst-toc-update)
;;
Stefan Monnier's avatar
Stefan Monnier committed
66 67
;; Syntax highlighting: font-lock is enabled by default.  If you want to turn
;; off syntax highlighting to rst-mode, you can use the following::
Stefan Monnier's avatar
Stefan Monnier committed
68 69 70 71 72
;;
;;   (setq font-lock-global-modes '(not rst-mode ...))
;;
;;
;;
73
;; Customization is done by customizable variables contained in customization
74
;; group "rst" and subgroups.  Group "rst" is contained in the "wp" group.
Stefan Monnier's avatar
Stefan Monnier committed
75 76 77 78
;;

;;; DOWNLOAD

79 80
;; The latest release of this file lies in the docutils source code repository:
;;   http://docutils.svn.sourceforge.net/svnroot/docutils/trunk/docutils/tools/editors/emacs/rst.el
Stefan Monnier's avatar
Stefan Monnier committed
81 82 83

;;; INSTALLATION

84
;; Add the following lines to your init file:
Stefan Monnier's avatar
Stefan Monnier committed
85 86 87 88 89 90
;;
;;   (require 'rst)
;;
;; If you are using `.txt' as a standard extension for reST files as
;; http://docutils.sourceforge.net/FAQ.html#what-s-the-standard-filename-extension-for-a-restructuredtext-file
;; suggests you may use one of the `Local Variables in Files' mechanism Emacs
Stefan Monnier's avatar
Stefan Monnier committed
91
;; provides to set the major mode automatically.  For instance you may use::
Stefan Monnier's avatar
Stefan Monnier committed
92 93 94
;;
;;    .. -*- mode: rst -*-
;;
Stefan Monnier's avatar
Stefan Monnier committed
95 96
;; in the very first line of your file.  The following code is useful if you
;; want automatically enter rst-mode from any file with compatible extensions:
Stefan Monnier's avatar
Stefan Monnier committed
97 98
;;
;; (setq auto-mode-alist
99 100 101
;;       (append '(("\\.txt\\'" . rst-mode)
;;                 ("\\.rst\\'" . rst-mode)
;;                 ("\\.rest\\'" . rst-mode)) auto-mode-alist))
Stefan Monnier's avatar
Stefan Monnier committed
102 103
;;

104
;;; Code:
Stefan Monnier's avatar
Stefan Monnier committed
105

106 107
;; FIXME: Check through major mode conventions again.

Stefan Merten's avatar
Stefan Merten committed
108 109
;; FIXME: Add proper ";;;###autoload" comments.

110 111 112
;; FIXME: When 24.1 is common place remove use of `lexical-let' and put "-*-
;;        lexical-binding: t -*-" in the first line.

113 114
;; FIXME: Use `testcover'.

115 116 117
;; FIXME: The adornment classification often called `ado' should be a
;;        `defstruct'.

118 119 120
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Support for `testcover'

121 122
(when (and (boundp 'testcover-1value-functions)
	   (boundp 'testcover-compose-functions))
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
  ;; Below `lambda' is used in a loop with varying parameters and is thus not
  ;; 1valued.
  (setq testcover-1value-functions
	(delq 'lambda testcover-1value-functions))
  (add-to-list 'testcover-compose-functions 'lambda))

(defun rst-testcover-defcustom ()
  "Remove all customized variables from `testcover-module-constants'.
This seems to be a bug in `testcover': `defcustom' variables are
considered constants.  Revert it with this function after each `defcustom'."
  (when (boundp 'testcover-module-constants)
    (setq testcover-module-constants
	  (delq nil
		(mapcar
		 (lambda (sym)
		   (if (not (plist-member (symbol-plist sym) 'standard-value))
		       sym))
		 testcover-module-constants)))))

(defun rst-testcover-add-compose (fun)
  "Add FUN to `testcover-compose-functions'."
  (when (boundp 'testcover-compose-functions)
    (add-to-list 'testcover-compose-functions fun)))

(defun rst-testcover-add-1value (fun)
  "Add FUN to `testcover-1value-functions'."
  (when (boundp 'testcover-1value-functions)
    (add-to-list 'testcover-1value-functions fun)))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Common Lisp stuff

155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
;; Only use of macros is allowed - may be replaced by `cl-lib' some time.
(eval-when-compile
  (require 'cl))

;; Redefine some functions from `cl.el' in a proper namespace until they may be
;; used from there.

(defun rst-signum (x)
  "Return 1 if X is positive, -1 if negative, 0 if zero."
  (cond
   ((> x 0) 1)
   ((< x 0) -1)
   (t 0)))

(defun rst-some (seq &optional pred)
  "Return non-nil if any element of SEQ yields non-nil when PRED is applied.
Apply PRED to each element of list SEQ until the first non-nil
Stefan Merten's avatar
Stefan Merten committed
172
result is yielded and return this result.  PRED defaults to
173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200
`identity'."
  (unless pred
    (setq pred 'identity))
  (catch 'rst-some
    (dolist (elem seq)
      (let ((r (funcall pred elem)))
	(when r
	  (throw 'rst-some r))))))

(defun rst-position-if (pred seq)
  "Return position of first element satisfying PRED in list SEQ or nil."
  (catch 'rst-position-if
    (let ((i 0))
      (dolist (elem seq)
	(when (funcall pred elem)
	  (throw 'rst-position-if i))
	(incf i)))))

(defun rst-position (elem seq)
  "Return position of ELEM in list SEQ or nil.
Comparison done with `equal'."
  ;; Create a closure containing `elem' so the `lambda' always sees our
  ;; parameter instead of an `elem' which may be in dynamic scope at the time
  ;; of execution of the `lambda'.
  (lexical-let ((elem elem))
    (rst-position-if (function (lambda (e)
				 (equal elem e)))
		     seq)))
Stefan Monnier's avatar
Stefan Monnier committed
201

202
;; FIXME: Embed complicated `defconst's in `eval-when-compile'.
203

204 205 206
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Versions

207
;; testcover: ok.
208
(defun rst-extract-version (delim-re head-re re tail-re var &optional default)
209 210 211
  "Extract the version from a variable according to the given regexes.
Return the version after regex DELIM-RE and HEAD-RE matching RE
and before TAIL-RE and DELIM-RE in VAR or DEFAULT for no match."
212 213 214 215 216 217 218
  (if (string-match
       (concat delim-re head-re "\\(" re "\\)" tail-re delim-re)
       var)
      (match-string 1 var)
    default))

;; Use CVSHeader to really get information from CVS and not other version
219
;; control systems.
220
(defconst rst-cvs-header
221
  "$CVSHeader: sm/rst_el/rst.el,v 1.327.2.6 2012-10-07 13:05:50 stefan Exp $")
222 223 224
(defconst rst-cvs-rev
  (rst-extract-version "\\$" "CVSHeader: \\S + " "[0-9]+\\(?:\\.[0-9]+\\)+"
		       " .*" rst-cvs-header "0.0")
225
  "The CVS revision of this file.  CVS revision is the development revision.")
226 227 228 229
(defconst rst-cvs-timestamp
  (rst-extract-version "\\$" "CVSHeader: \\S + \\S + "
		       "[0-9]+-[0-9]+-[0-9]+ [0-9]+:[0-9]+:[0-9]+" " .*"
		       rst-cvs-header "1970-01-01 00:00:00")
230
  "The CVS time stamp of this file.")
231

232
;; Use LastChanged... to really get information from SVN.
233 234
(defconst rst-svn-rev
  (rst-extract-version "\\$" "LastChangedRevision: " "[0-9]+" " "
235
		       "$LastChangedRevision: 7515 $")
236 237 238 239
  "The SVN revision of this file.
SVN revision is the upstream (docutils) revision.")
(defconst rst-svn-timestamp
  (rst-extract-version "\\$" "LastChangedDate: " ".+?+" " "
240
		       "$LastChangedDate: 2012-09-20 23:28:53 +0200 (Thu, 20 Sep 2012) $")
241
  "The SVN time stamp of this file.")
242

243
;; Maintained by the release process.
244 245
(defconst rst-official-version
  (rst-extract-version "%" "OfficialVersion: " "[0-9]+\\(?:\\.[0-9]+\\)+" " "
246
		       "%OfficialVersion: 1.4.0 %")
247 248 249
  "Official version of the package.")
(defconst rst-official-cvs-rev
  (rst-extract-version "[%$]" "Revision: " "[0-9]+\\(?:\\.[0-9]+\\)+" " "
250
		       "%Revision: 1.327 %")
251 252 253 254 255 256 257 258
  "CVS revision of this file in the official version.")

(defconst rst-version
  (if (equal rst-official-cvs-rev rst-cvs-rev)
      rst-official-version
    (format "%s (development %s [%s])" rst-official-version
	    rst-cvs-rev rst-cvs-timestamp))
  "The version string.
259 260
Starts with the current official version.  For developer versions
in parentheses follows the development revision and the time stamp.")
261 262

(defconst rst-package-emacs-version-alist
263 264 265 266 267 268
  '(("1.0.0" . "24.3")
    ("1.1.0" . "24.3")
    ("1.2.0" . "24.3")
    ("1.2.1" . "24.3")
    ("1.3.0" . "24.3")
    ("1.3.1" . "24.3")
269
    ("1.4.0" . "24.3")
Stefan Merten's avatar
Stefan Merten committed
270
    ))
271 272 273 274 275 276 277

(unless (assoc rst-official-version rst-package-emacs-version-alist)
  (error "Version %s not listed in `rst-package-emacs-version-alist'"
	 rst-version))

(add-to-list 'customize-package-emacs-version-alist
	     (cons 'ReST rst-package-emacs-version-alist))
Stefan Monnier's avatar
Stefan Monnier committed
278

279 280
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Initialize customization
Stefan Monnier's avatar
Stefan Monnier committed
281 282


Juanma Barranquero's avatar
Juanma Barranquero committed
283
(defgroup rst nil "Support for reStructuredText documents."
Stefan Monnier's avatar
Stefan Monnier committed
284 285 286 287 288 289
  :group 'wp
  :version "23.1"
  :link '(url-link "http://docutils.sourceforge.net/rst.html"))


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
290 291 292
;; Facilities for regular expressions used everywhere

;; The trailing numbers in the names give the number of referenceable regex
293
;; groups contained in the regex.
294 295

;; Used to be customizable but really is not customizable but fixed by the reST
296
;; syntax.
297
(defconst rst-bullets
298
  ;; Sorted so they can form a character class when concatenated.
299
  '(?- ?* ?+ ? ? ?)
300 301 302 303 304 305 306 307 308
  "List of all possible bullet characters for bulleted lists.")

(defconst rst-uri-schemes
  '("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")
  "Supported URI schemes.")

(defconst rst-adornment-chars
309
  ;; Sorted so they can form a character class when concatenated.
310 311 312 313 314 315 316 317 318 319 320
  '(?\]
    ?! ?\" ?# ?$ ?% ?& ?' ?\( ?\) ?* ?+ ?, ?. ?/ ?: ?\; ?< ?= ?> ?? ?@ ?\[ ?\\
    ?^ ?_ ?` ?{ ?| ?} ?~
    ?-)
  "Characters which may be used in adornments for sections and transitions.")

(defconst rst-max-inline-length
  1000
  "Maximum length of inline markup to recognize.")

(defconst rst-re-alist-def
321 322 323 324 325 326 327 328
  ;; `*-beg' matches * at the beginning of a line.
  ;; `*-end' matches * at the end of a line.
  ;; `*-prt' matches a part of *.
  ;; `*-tag' matches *.
  ;; `*-sta' matches the start of * which may be followed by respective content.
  ;; `*-pfx' matches the delimiter left of *.
  ;; `*-sfx' matches the delimiter right of *.
  ;; `*-hlp' helper for *.
329 330 331 332 333 334
  ;;
  ;; A trailing number says how many referenceable groups are contained.
  `(

    ;; Horizontal white space (`hws')
    (hws-prt "[\t ]")
335 336
    (hws-tag hws-prt "*") ; Optional sequence of horizontal white space.
    (hws-sta hws-prt "+") ; Mandatory sequence of horizontal white space.
337 338

    ;; Lines (`lin')
339 340 341
    (lin-beg "^" hws-tag) ; Beginning of a possibly indented line.
    (lin-end hws-tag "$") ; End of a line with optional trailing white space.
    (linemp-tag "^" hws-tag "$") ; Empty line with optional white space.
342 343 344

    ;; Various tags and parts
    (ell-tag "\\.\\.\\.") ; Ellipsis
345 346 347 348 349 350 351 352
    (bul-tag ,(concat "[" rst-bullets "]")) ; A bullet.
    (ltr-tag "[a-zA-Z]") ; A letter enumerator tag.
    (num-prt "[0-9]") ; A number enumerator part.
    (num-tag num-prt "+") ; A number enumerator tag.
    (rom-prt "[IVXLCDMivxlcdm]") ; A roman enumerator part.
    (rom-tag rom-prt "+") ; A roman enumerator tag.
    (aut-tag "#") ; An automatic enumerator tag.
    (dcl-tag "::") ; Double colon.
353 354 355

    ;; Block lead in (`bli')
    (bli-sfx (:alt hws-sta "$")) ; Suffix of a block lead-in with *optional*
356
				 ; immediate content.
357 358

    ;; Various starts
359
    (bul-sta bul-tag bli-sfx) ; Start of a bulleted item.
360 361 362 363 364 365 366

    ;; Explicit markup tag (`exm')
    (exm-tag "\\.\\.")
    (exm-sta exm-tag hws-sta)
    (exm-beg lin-beg exm-sta)

    ;; Counters in enumerations (`cnt')
367 368
    (cntany-tag (:alt ltr-tag num-tag rom-tag aut-tag)) ; An arbitrary counter.
    (cntexp-tag (:alt ltr-tag num-tag rom-tag)) ; An arbitrary explicit counter.
369 370 371 372

    ;; Enumerator (`enm')
    (enmany-tag (:alt
		 (:seq cntany-tag "\\.")
373
		 (:seq "(?" cntany-tag ")"))) ; An arbitrary enumerator.
374 375 376
    (enmexp-tag (:alt
		 (:seq cntexp-tag "\\.")
		 (:seq "(?" cntexp-tag ")"))) ; An arbitrary explicit
377
					      ; enumerator.
378 379
    (enmaut-tag (:alt
		 (:seq aut-tag "\\.")
380 381 382
		 (:seq "(?" aut-tag ")"))) ; An automatic enumerator.
    (enmany-sta enmany-tag bli-sfx) ; An arbitrary enumerator start.
    (enmexp-sta enmexp-tag bli-sfx) ; An arbitrary explicit enumerator start.
383
    (enmexp-beg lin-beg enmexp-sta) ; An arbitrary explicit enumerator start
384
				    ; at the beginning of a line.
385 386

    ;; Items may be enumerated or bulleted (`itm')
387
    (itmany-tag (:alt enmany-tag bul-tag)) ; An arbitrary item tag.
388
    (itmany-sta-1 (:grp itmany-tag) bli-sfx) ; An arbitrary item start, group
389
					     ; is the item tag.
390 391
    (itmany-beg-1 lin-beg itmany-sta-1) ; An arbitrary item start at the
				        ; beginning of a line, group is the
392
				        ; item tag.
393 394

    ;; Inline markup (`ilm')
395 396
    (ilm-pfx (:alt "^" hws-prt "[-'\"([{<‘“«’/:]"))
    (ilm-sfx (:alt "$" hws-prt "[]-'\")}>’”»/:.,;!?\\]"))
397 398

    ;; Inline markup content (`ilc')
399 400 401
    (ilcsgl-tag "\\S ") ; A single non-white character.
    (ilcast-prt (:alt "[^*\\]" "\\\\.")) ; Part of non-asterisk content.
    (ilcbkq-prt (:alt "[^`\\]" "\\\\.")) ; Part of non-backquote content.
402
    (ilcbkqdef-prt (:alt "[^`\\\n]" "\\\\.")) ; Part of non-backquote
403 404
					      ; definition.
    (ilcbar-prt (:alt "[^|\\]" "\\\\.")) ; Part of non-vertical-bar content.
405
    (ilcbardef-prt (:alt "[^|\\\n]" "\\\\.")) ; Part of non-vertical-bar
406 407 408 409 410
					      ; definition.
    (ilcast-sfx "[^\t *\\]") ; Suffix of non-asterisk content.
    (ilcbkq-sfx "[^\t `\\]") ; Suffix of non-backquote content.
    (ilcbar-sfx "[^\t |\\]") ; Suffix of non-vertical-bar content.
    (ilcrep-hlp ,(format "\\{0,%d\\}" rst-max-inline-length)) ; Repeat count.
411 412 413
    (ilcast-tag (:alt ilcsgl-tag
		      (:seq ilcsgl-tag
			    ilcast-prt ilcrep-hlp
414
			    ilcast-sfx))) ; Non-asterisk content.
415 416 417
    (ilcbkq-tag (:alt ilcsgl-tag
		      (:seq ilcsgl-tag
			    ilcbkq-prt ilcrep-hlp
418
			    ilcbkq-sfx))) ; Non-backquote content.
419 420 421
    (ilcbkqdef-tag (:alt ilcsgl-tag
			 (:seq ilcsgl-tag
			       ilcbkqdef-prt ilcrep-hlp
422
			       ilcbkq-sfx))) ; Non-backquote definition.
423 424 425
    (ilcbar-tag (:alt ilcsgl-tag
		      (:seq ilcsgl-tag
			    ilcbar-prt ilcrep-hlp
426
			    ilcbar-sfx))) ; Non-vertical-bar content.
427 428 429
    (ilcbardef-tag (:alt ilcsgl-tag
			 (:seq ilcsgl-tag
			       ilcbardef-prt ilcrep-hlp
430
			       ilcbar-sfx))) ; Non-vertical-bar definition.
431 432

    ;; Fields (`fld')
433 434 435
    (fldnam-prt (:alt "[^:\n]" "\\\\:")) ; Part of a field name.
    (fldnam-tag fldnam-prt "+") ; A field name.
    (fld-tag ":" fldnam-tag ":") ; A field marker.
436 437

    ;; Options (`opt')
438 439 440 441 442
    (optsta-tag (:alt "[-+/]" "--")) ; Start of an option.
    (optnam-tag "\\sw" (:alt "-" "\\sw") "*") ; Name of an option.
    (optarg-tag (:shy "[ =]\\S +")) ; Option argument.
    (optsep-tag (:shy "," hws-prt)) ; Separator between options.
    (opt-tag (:shy optsta-tag optnam-tag optarg-tag "?")) ; A complete option.
443 444

    ;; Footnotes and citations (`fnc')
445
    (fncnam-prt "[^]\n]") ; Part of a footnote or citation name.
446 447
    (fncnam-tag fncnam-prt "+") ; A footnote or citation name.
    (fnc-tag "\\[" fncnam-tag "]") ; A complete footnote or citation tag.
448 449
    (fncdef-tag-2 (:grp exm-sta)
		  (:grp fnc-tag)) ; A complete footnote or citation definition
450
				  ; tag.  First group is the explicit markup
451
				  ; start, second group is the footnote /
452
				  ; citation tag.
453
    (fnc-sta-2 fncdef-tag-2 bli-sfx) ; Start of a footnote or citation
454
				     ; definition.  First group is the explicit
455
				     ; markup start, second group is the
456
				     ; footnote / citation tag.
457 458

    ;; Substitutions (`sub')
459
    (sub-tag "|" ilcbar-tag "|") ; A complete substitution tag.
460
    (subdef-tag "|" ilcbardef-tag "|") ; A complete substitution definition
461
				       ; tag.
462 463

    ;; Symbol (`sym')
464 465
    (sym-prt "[-+.:_]") ; Non-word part of a symbol.
    (sym-tag (:shy "\\sw+" (:shy sym-prt "\\sw+") "*"))
466 467 468 469 470 471 472 473

    ;; URIs (`uri')
    (uri-tag (:alt ,@rst-uri-schemes))

    ;; Adornment (`ado')
    (ado-prt "[" ,(concat rst-adornment-chars) "]")
    (adorep3-hlp "\\{3,\\}") ; There must be at least 3 characters because
			     ; otherwise explicit markup start would be
474
			     ; recognized.
475
    (adorep2-hlp "\\{2,\\}") ; As `adorep3-hlp' but when the first of three
476
			     ; characters is matched differently.
477 478 479
    (ado-tag-1-1 (:grp ado-prt)
		 "\\1" adorep2-hlp) ; A complete adornment, group is the first
				    ; adornment character and MUST be the FIRST
480
				    ; group in the whole expression.
481 482 483
    (ado-tag-1-2 (:grp ado-prt)
		 "\\2" adorep2-hlp) ; A complete adornment, group is the first
				    ; adornment character and MUST be the
484
				    ; SECOND group in the whole expression.
485 486 487 488
    (ado-beg-2-1 "^" (:grp ado-tag-1-2)
		 lin-end) ; A complete adornment line; first group is the whole
			  ; adornment and MUST be the FIRST group in the whole
			  ; expression; second group is the first adornment
489
			  ; character.
490 491

    ;; Titles (`ttl')
492 493
    (ttl-tag "\\S *\\w\\S *") ; A title text.
    (ttl-beg lin-beg ttl-tag) ; A title text at the beginning of a line.
494 495 496 497 498

    ;; Directives and substitution definitions (`dir')
    (dir-tag-3 (:grp exm-sta)
	       (:grp (:shy subdef-tag hws-sta) "?")
	       (:grp sym-tag dcl-tag)) ; A directive or substitution definition
499
				       ; tag.  First group is explicit markup
500 501 502
				       ; start, second group is a possibly
				       ; empty substitution tag, third group is
				       ; the directive tag including the double
503
				       ; colon.
504
    (dir-sta-3 dir-tag-3 bli-sfx) ; Start of a directive or substitution
505
				  ; definition.  Groups are as in dir-tag-3.
506 507 508

    ;; Literal block (`lit')
    (lit-sta-2 (:grp (:alt "[^.\n]" "\\.[^.\n]") ".*") "?"
509
	       (:grp dcl-tag) "$") ; Start of a literal block.  First group is
510 511
				   ; any text before the double colon tag which
				   ; may not exist, second group is the double
512
				   ; colon tag.
513 514

    ;; Comments (`cmt')
515
    (cmt-sta-1 (:grp exm-sta) "[^[|_\n]"
516 517
	       (:alt "[^:\n]" (:seq ":" (:alt "[^:\n]" "$")))
	       "*$") ; Start of a comment block; first group is explicit markup
518
		     ; start.
519 520 521 522

    ;; Paragraphs (`par')
    (par-tag- (:alt itmany-tag fld-tag opt-tag fncdef-tag-2 dir-tag-3 exm-tag)
	      ) ; Tag at the beginning of a paragraph; there may be groups in
523
		; certain cases.
524 525 526 527 528
    )
  "Definition alist of relevant regexes.
Each entry consists of the symbol naming the regex and an
argument list for `rst-re'.")

529 530
(defvar rst-re-alist) ; Forward declare to use it in `rst-re'.

531
;; FIXME: Use `sregex' or `rx' instead of re-inventing the wheel.
532 533
(rst-testcover-add-compose 'rst-re)
;; testcover: ok.
534 535 536 537 538 539 540 541 542 543
(defun rst-re (&rest args)
  "Interpret ARGS as regular expressions and return a regex string.
Each element of ARGS may be one of the following:

A string which is inserted unchanged.

A character which is resolved to a quoted regex.

A symbol which is resolved to a string using `rst-re-alist-def'.

544 545
A list with a keyword in the car.  Each element of the cdr of such
a list is recursively interpreted as ARGS.  The results of this
546 547 548 549 550 551 552 553 554 555 556
interpretation are concatenated according to the keyword.

For the keyword `:seq' the results are simply concatenated.

For the keyword `:shy' the results are concatenated and
surrounded by a shy-group (\"\\(?:...\\)\").

For the keyword `:alt' the results form an alternative (\"\\|\")
which is shy-grouped (\"\\(?:...\\)\").

For the keyword `:grp' the results are concatenated and form a
557
referenceable group (\"\\(...\\)\").
558 559

After interpretation of ARGS the results are concatenated as for
560
`:seq'."
561 562 563 564 565 566 567 568
  (apply 'concat
	 (mapcar
	  (lambda (re)
	    (cond
	     ((stringp re)
	      re)
	     ((symbolp re)
	      (cadr (assoc re rst-re-alist)))
569
	     ((characterp re)
570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590
	      (regexp-quote (char-to-string re)))
	     ((listp re)
	      (let ((nested
		     (mapcar (lambda (elt)
			       (rst-re elt))
			     (cdr re))))
		(cond
		 ((eq (car re) :seq)
		  (mapconcat 'identity nested ""))
		 ((eq (car re) :shy)
		  (concat "\\(?:" (mapconcat 'identity nested "") "\\)"))
		 ((eq (car re) :grp)
		  (concat "\\(" (mapconcat 'identity nested "") "\\)"))
		 ((eq (car re) :alt)
		  (concat "\\(?:" (mapconcat 'identity nested "\\|") "\\)"))
		 (t
		  (error "Unknown list car: %s" (car re))))))
	     (t
	      (error "Unknown object type for building regex: %s" re))))
	  args)))

591
;; FIXME: Remove circular dependency between `rst-re' and `rst-re-alist'.
592 593 594 595 596 597 598 599 600 601
(with-no-warnings ; Silence byte-compiler about this construction.
  (defconst rst-re-alist
    ;; Shadow global value we are just defining so we can construct it step by
    ;; step.
    (let (rst-re-alist)
      (dolist (re rst-re-alist-def rst-re-alist)
	(setq rst-re-alist
	      (nconc rst-re-alist
		     (list (list (car re) (apply 'rst-re (cdr re))))))))
    "Alist mapping symbols from `rst-re-alist-def' to regex strings."))
602

Stefan Monnier's avatar
Stefan Monnier committed
603 604

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
605
;; Mode definition
606

607
;; testcover: ok.
608
(defun rst-define-key (keymap key def &rest deprecated)
609 610
  "Bind like `define-key' but add deprecated key definitions.
KEYMAP, KEY, and DEF are as in `define-key'.  DEPRECATED key
611 612
definitions should be in vector notation.  These are defined
as well but give an additional message."
613
  (define-key keymap key def)
614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635
  (when deprecated
    (let* ((command-name (symbol-name def))
           (forwarder-function-name
            (if (string-match "^rst-\\(.*\\)$" command-name)
                (concat "rst-deprecated-"
                        (match-string 1 command-name))
              (error "not an RST command: %s" command-name)))
           (forwarder-function (intern forwarder-function-name)))
      (unless (fboundp forwarder-function)
        (defalias forwarder-function
          (lexical-let ((key key) (def def))
            (lambda ()
              (interactive)
              (call-interactively def)
              (message "[Deprecated use of key %s; use key %s instead]"
          (key-description (this-command-keys))
          (key-description key))))
          (format "Deprecated binding for %s, use \\[%s] instead."
                  def def)))
      (dolist (dep-key deprecated)
        (define-key keymap dep-key forwarder-function)))))
 ;; Key bindings.
Stefan Monnier's avatar
Stefan Monnier committed
636 637 638
(defvar rst-mode-map
  (let ((map (make-sparse-keymap)))

639
    ;; \C-c is the general keymap.
640 641
    (rst-define-key map [?\C-c ?\C-h] 'describe-prefix-bindings)

Stefan Monnier's avatar
Stefan Monnier committed
642
    ;;
643
    ;; Section Adornments
Stefan Monnier's avatar
Stefan Monnier committed
644
    ;;
645 646
    ;; The adjustment function that adorns or rotates a section title.
    (rst-define-key map [?\C-c ?\C-=] 'rst-adjust [?\C-c ?\C-a t])
Stefan Merten's avatar
Stefan Merten committed
647 648
    (rst-define-key map [?\C-=] 'rst-adjust) ; Does not work on the Mac OSX and
					     ; on consoles.
649

650
    ;; \C-c \C-a is the keymap for adornments.
651
    (rst-define-key map [?\C-c ?\C-a ?\C-h] 'describe-prefix-bindings)
Stefan Merten's avatar
Stefan Merten committed
652 653
    ;; Another binding which works with all types of input.
    (rst-define-key map [?\C-c ?\C-a ?\C-a] 'rst-adjust)
654 655
    ;; Display the hierarchy of adornments implied by the current document
    ;; contents.
656 657 658 659
    (rst-define-key map [?\C-c ?\C-a ?\C-d] 'rst-display-adornments-hierarchy)
    ;; Homogenize the adornments in the document.
    (rst-define-key map [?\C-c ?\C-a ?\C-s] 'rst-straighten-adornments
		    [?\C-c ?\C-s])
Stefan Monnier's avatar
Stefan Monnier committed
660 661

    ;;
662
    ;; Section Movement and Selection
Stefan Monnier's avatar
Stefan Monnier committed
663 664
    ;;
    ;; Mark the subsection where the cursor is.
665
    (rst-define-key map [?\C-\M-h] 'rst-mark-section
666
		    ;; Same as mark-defun sgml-mark-current-element.
667
		    [?\C-c ?\C-m])
668
    ;; Move backward/forward between section titles.
669
    ;; FIXME: Also bind similar to outline mode.
670
    (rst-define-key map [?\C-\M-a] 'rst-backward-section
671
		    ;; Same as beginning-of-defun.
672
		    [?\C-c ?\C-n])
673
    (rst-define-key map [?\C-\M-e] 'rst-forward-section
674
		    ;; Same as end-of-defun.
675
		    [?\C-c ?\C-p])
Stefan Monnier's avatar
Stefan Monnier committed
676 677

    ;;
678
    ;; Operating on regions
Stefan Monnier's avatar
Stefan Monnier committed
679
    ;;
680
    ;; \C-c \C-r is the keymap for regions.
681 682 683 684
    (rst-define-key map [?\C-c ?\C-r ?\C-h] 'describe-prefix-bindings)
    ;; Makes region a line-block.
    (rst-define-key map [?\C-c ?\C-r ?\C-l] 'rst-line-block-region
		    [?\C-c ?\C-d])
685
    ;; Shift region left or right according to tabs.
686 687 688 689
    (rst-define-key map [?\C-c ?\C-r tab] 'rst-shift-region
		    [?\C-c ?\C-r t] [?\C-c ?\C-l t])

    ;;
690
    ;; Operating on lists
691
    ;;
692
    ;; \C-c \C-l is the keymap for lists.
693
    (rst-define-key map [?\C-c ?\C-l ?\C-h] 'describe-prefix-bindings)
Stefan Monnier's avatar
Stefan Monnier committed
694
    ;; Makes paragraphs in region as a bullet list.
695 696
    (rst-define-key map [?\C-c ?\C-l ?\C-b] 'rst-bullet-list-region
		    [?\C-c ?\C-b])
Stefan Monnier's avatar
Stefan Monnier committed
697
    ;; Makes paragraphs in region as a enumeration.
698 699
    (rst-define-key map [?\C-c ?\C-l ?\C-e] 'rst-enumerate-region
		    [?\C-c ?\C-e])
Stefan Monnier's avatar
Stefan Monnier committed
700
    ;; Converts bullets to an enumeration.
701 702
    (rst-define-key map [?\C-c ?\C-l ?\C-c] 'rst-convert-bullets-to-enumeration
		    [?\C-c ?\C-v])
Stefan Monnier's avatar
Stefan Monnier committed
703
    ;; Make sure that all the bullets in the region are consistent.
704 705
    (rst-define-key map [?\C-c ?\C-l ?\C-s] 'rst-straighten-bullets-region
		    [?\C-c ?\C-w])
706
    ;; Insert a list item.
707
    (rst-define-key map [?\C-c ?\C-l ?\C-i] 'rst-insert-list)
Stefan Monnier's avatar
Stefan Monnier committed
708 709

    ;;
710
    ;; Table-of-Contents Features
Stefan Monnier's avatar
Stefan Monnier committed
711
    ;;
712
    ;; \C-c \C-t is the keymap for table of contents.
713
    (rst-define-key map [?\C-c ?\C-t ?\C-h] 'describe-prefix-bindings)
Stefan Monnier's avatar
Stefan Monnier committed
714
    ;; Enter a TOC buffer to view and move to a specific section.
715
    (rst-define-key map [?\C-c ?\C-t ?\C-t] 'rst-toc)
Stefan Monnier's avatar
Stefan Monnier committed
716
    ;; Insert a TOC here.
717 718
    (rst-define-key map [?\C-c ?\C-t ?\C-i] 'rst-toc-insert
		    [?\C-c ?\C-i])
Stefan Monnier's avatar
Stefan Monnier committed
719
    ;; Update the document's TOC (without changing the cursor position).
720 721
    (rst-define-key map [?\C-c ?\C-t ?\C-u] 'rst-toc-update
		    [?\C-c ?\C-u])
722
    ;; Go to the section under the cursor (cursor must be in TOC).
723 724
    (rst-define-key map [?\C-c ?\C-t ?\C-j] 'rst-goto-section
		    [?\C-c ?\C-f])
Stefan Monnier's avatar
Stefan Monnier committed
725 726

    ;;
727
    ;; Converting Documents from Emacs
Stefan Monnier's avatar
Stefan Monnier committed
728
    ;;
729
    ;; \C-c \C-c is the keymap for compilation.
730
    (rst-define-key map [?\C-c ?\C-c ?\C-h] 'describe-prefix-bindings)
Stefan Monnier's avatar
Stefan Monnier committed
731
    ;; Run one of two pre-configured toolset commands on the document.
732 733 734 735
    (rst-define-key map [?\C-c ?\C-c ?\C-c] 'rst-compile
		    [?\C-c ?1])
    (rst-define-key map [?\C-c ?\C-c ?\C-a] 'rst-compile-alt-toolset
		    [?\C-c ?2])
Stefan Monnier's avatar
Stefan Monnier committed
736
    ;; Convert the active region to pseudo-xml using the docutils tools.
737 738
    (rst-define-key map [?\C-c ?\C-c ?\C-x] 'rst-compile-pseudo-region
		    [?\C-c ?3])
Stefan Monnier's avatar
Stefan Monnier committed
739
    ;; Convert the current document to PDF and launch a viewer on the results.
740 741
    (rst-define-key map [?\C-c ?\C-c ?\C-p] 'rst-compile-pdf-preview
		    [?\C-c ?4])
Stefan Monnier's avatar
Stefan Monnier committed
742
    ;; Convert the current document to S5 slides and view in a web browser.
743 744
    (rst-define-key map [?\C-c ?\C-c ?\C-s] 'rst-compile-slides-preview
		    [?\C-c ?5])
Stefan Monnier's avatar
Stefan Monnier committed
745 746

    map)
747
  "Keymap for reStructuredText mode commands.
Stefan Monnier's avatar
Stefan Monnier committed
748
This inherits from Text mode.")
Stefan Monnier's avatar
Stefan Monnier committed
749 750 751 752


;; Abbrevs.
(define-abbrev-table 'rst-mode-abbrev-table
753 754 755 756 757 758 759
  (mapcar (lambda (x) (append x '(nil 0 system)))
          '(("contents" ".. contents::\n..\n   ")
            ("con" ".. contents::\n..\n   ")
            ("cont" "[...]")
            ("skip" "\n\n[...]\n\n  ")
            ("seq" "\n\n[...]\n\n  ")
            ;; FIXME: Add footnotes, links, and more.
760 761
            ))
  "Abbrev table used while in `rst-mode'.")
Stefan Monnier's avatar
Stefan Monnier committed
762 763 764 765 766 767 768 769 770 771


;; Syntax table.
(defvar rst-mode-syntax-table
  (let ((st (copy-syntax-table text-mode-syntax-table)))
    (modify-syntax-entry ?$ "." st)
    (modify-syntax-entry ?% "." st)
    (modify-syntax-entry ?& "." st)
    (modify-syntax-entry ?' "." st)
    (modify-syntax-entry ?* "." st)
772 773
    (modify-syntax-entry ?+ "." st)
    (modify-syntax-entry ?- "." st)
Stefan Monnier's avatar
Stefan Monnier committed
774 775 776 777 778
    (modify-syntax-entry ?/ "." st)
    (modify-syntax-entry ?< "." st)
    (modify-syntax-entry ?= "." st)
    (modify-syntax-entry ?> "." st)
    (modify-syntax-entry ?\\ "\\" st)
779
    (modify-syntax-entry ?_ "." st)
Stefan Monnier's avatar
Stefan Monnier committed
780
    (modify-syntax-entry ?| "." st)
781 782 783 784 785 786
    (modify-syntax-entry ?« "." st)
    (modify-syntax-entry ?» "." st)
    (modify-syntax-entry ? "." st)
    (modify-syntax-entry ? "." st)
    (modify-syntax-entry ? "." st)
    (modify-syntax-entry ? "." st)
Stefan Monnier's avatar
Stefan Monnier committed
787 788 789 790
    st)
  "Syntax table used while in `rst-mode'.")

(defcustom rst-mode-hook nil
791 792
  "Hook run when `rst-mode' is turned on.
The hook for `text-mode' is run before this one."
Stefan Monnier's avatar
Stefan Monnier committed
793 794
  :group 'rst
  :type '(hook))
795
(rst-testcover-defcustom)
Stefan Monnier's avatar
Stefan Monnier committed
796

797 798
;; Pull in variable definitions silencing byte-compiler.
(require 'newcomment)
Stefan Monnier's avatar
Stefan Monnier committed
799

800 801
(defvar electric-pair-pairs)

802 803
;; Use rst-mode for *.rst and *.rest files.  Many ReStructured-Text files
;; use *.txt, but this is too generic to be set as a default.
804
;;;###autoload (add-to-list 'auto-mode-alist (purecopy '("\\.re?st\\'" . rst-mode)))
Stefan Monnier's avatar
Stefan Monnier committed
805 806 807
;;;###autoload
(define-derived-mode rst-mode text-mode "ReST"
  "Major mode for editing reStructuredText documents.
808
\\<rst-mode-map>
Stefan Monnier's avatar
Stefan Monnier committed
809

810 811
Turning on `rst-mode' calls the normal hooks `text-mode-hook'
and `rst-mode-hook'.  This mode also supports font-lock
812
highlighting.
813 814

\\{rst-mode-map}"
815 816 817
  :abbrev-table rst-mode-abbrev-table
  :syntax-table rst-mode-syntax-table
  :group 'rst
Stefan Monnier's avatar
Stefan Monnier committed
818

819
  ;; Paragraph recognition.
820 821 822 823
  (set (make-local-variable 'paragraph-separate)
       (rst-re '(:alt
		 "\f"
		 lin-end)))
Stefan Monnier's avatar
Stefan Monnier committed
824
  (set (make-local-variable 'paragraph-start)
825 826 827 828
       (rst-re '(:alt
		 "\f"
		 lin-end
		 (:seq hws-tag par-tag- bli-sfx))))
Stefan Monnier's avatar
Stefan Monnier committed
829

830
  ;; Indenting and filling.
831 832 833 834 835 836
  (set (make-local-variable 'indent-line-function) 'rst-indent-line)
  (set (make-local-variable 'adaptive-fill-mode) t)
  (set (make-local-variable 'adaptive-fill-regexp)
       (rst-re 'hws-tag 'par-tag- "?" 'hws-tag))
  (set (make-local-variable 'adaptive-fill-function) 'rst-adaptive-fill)
  (set (make-local-variable 'fill-paragraph-handle-comment) nil)
Stefan Monnier's avatar
Stefan Monnier committed
837

838
  ;; Comments.
Stefan Monnier's avatar
Stefan Monnier committed
839
  (set (make-local-variable 'comment-start) ".. ")
840 841 842 843 844 845
  (set (make-local-variable 'comment-start-skip)
       (rst-re 'lin-beg 'exm-tag 'bli-sfx))
  (set (make-local-variable 'comment-continue) "   ")
  (set (make-local-variable 'comment-multi-line) t)
  (set (make-local-variable 'comment-use-syntax) nil)
  ;; reStructuredText has not really a comment ender but nil is not really a
846
  ;; permissible value.
847 848 849
  (set (make-local-variable 'comment-end) "")
  (set (make-local-variable 'comment-end-skip) nil)

850 851
  ;; Commenting in reStructuredText is very special so use our own set of
  ;; functions.
852 853 854 855 856 857 858 859 860 861
  (set (make-local-variable 'comment-line-break-function)
       'rst-comment-line-break)
  (set (make-local-variable 'comment-indent-function)
       'rst-comment-indent)
  (set (make-local-variable 'comment-insert-comment-function)
       'rst-comment-insert-comment)
  (set (make-local-variable 'comment-region-function)
       'rst-comment-region)
  (set (make-local-variable 'uncomment-region-function)
       'rst-uncomment-region)
Stefan Monnier's avatar
Stefan Monnier committed
862

863 864 865
  (set (make-local-variable 'electric-pair-pairs)
       '((?\" . ?\") (?\* . ?\*) (?\` . ?\`)))

866 867 868 869 870 871
  ;; Imenu and which function.
  ;; FIXME: Check documentation of `which-function' for alternative ways to
  ;;        determine the current function name.
  (set (make-local-variable 'imenu-create-index-function)
       'rst-imenu-create-index)

872 873 874 875 876 877
  ;; Font lock.
  (set (make-local-variable 'font-lock-defaults)
       '(rst-font-lock-keywords
	 t nil nil nil
	 (font-lock-multiline . t)
	 (font-lock-mark-block-function . mark-paragraph)))
878 879
  (add-hook 'font-lock-extend-region-functions 'rst-font-lock-extend-region t)

880
  ;; Text after a changed line may need new fontification.
881 882 883 884
  (set (make-local-variable 'jit-lock-contextually) t)

  ;; Indentation is not deterministic.
  (setq electric-indent-inhibit t))
Stefan Monnier's avatar
Stefan Monnier committed
885 886 887

;;;###autoload
(define-minor-mode rst-minor-mode
Chong Yidong's avatar
Chong Yidong committed
888 889 890 891
  "Toggle ReST minor mode.
With a prefix argument ARG, enable ReST minor mode if ARG is
positive, and disable it otherwise.  If called from Lisp, enable
the mode if ARG is omitted or nil.
Stefan Monnier's avatar
Stefan Monnier committed
892

Juanma Barranquero's avatar
Juanma Barranquero committed
893 894 895
When ReST minor mode is enabled, the ReST mode keybindings
are installed on top of the major mode bindings.  Use this
for modes derived from Text mode, like Mail mode."
Stefan Monnier's avatar
Stefan Monnier committed
896 897 898 899 900 901 902 903 904
 ;; The initial value.
 nil
 ;; The indicator for the mode line.
 " ReST"
 ;; The minor mode bindings.
 rst-mode-map
 :group 'rst)

;; FIXME: can I somehow install these too?
905 906
;;        :abbrev-table rst-mode-abbrev-table
;;        :syntax-table rst-mode-syntax-table
Stefan Monnier's avatar
Stefan Monnier committed
907 908 909


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
910 911
;; Section Adornment Adjustment
;; ============================
Stefan Monnier's avatar
Stefan Monnier committed
912 913 914 915 916
;;
;; The following functions implement a smart automatic title sectioning feature.
;; The idea is that with the cursor sitting on a section title, we try to get as
;; much information from context and try to do the best thing automatically.
;; This function can be invoked many times and/or with prefix argument to rotate
917
;; between the various sectioning adornments.
Stefan Monnier's avatar
Stefan Monnier committed
918 919
;;
;; Definitions: the two forms of sectioning define semantically separate section
920
;; levels.  A sectioning ADORNMENT consists in:
Stefan Monnier's avatar
Stefan Monnier committed
921 922 923 924 925 926 927 928 929
;;
;;   - a CHARACTER
;;
;;   - a STYLE which can be either of 'simple' or 'over-and-under'.
;;
;;   - an INDENT (meaningful for the over-and-under style only) which determines
;;     how many characters and over-and-under style is hanging outside of the
;;     title at the beginning and ending.
;;
930
;; Here are two examples of adornments (| represents the window border, column
Stefan Monnier's avatar
Stefan Monnier committed
931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946
;; 0):
;;
;;                                  |
;; 1. char: '-'   e                 |Some Title
;;    style: simple                 |----------
;;                                  |
;; 2. char: '='                     |==============
;;    style: over-and-under         |  Some Title
;;    indent: 2                     |==============
;;                                  |
;;
;; Some notes:
;;
;; - The underlining character that is used depends on context. The file is
;;   scanned to find other sections and an appropriate character is selected.
;;   If the function is invoked on a section that is complete, the character is
947
;;   rotated among the existing section adornments.
Stefan Monnier's avatar
Stefan Monnier committed
948 949
;;
;;   Note that when rotating the characters, if we come to the end of the
950 951 952 953
;;   hierarchy of adornments, the variable rst-preferred-adornments is
;;   consulted to propose a new underline adornment, and if continued, we cycle
;;   the adornments all over again.  Set this variable to nil if you want to
;;   limit the underlining character propositions to the existing adornments in
Stefan Monnier's avatar
Stefan Monnier committed
954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975
;;   the file.
;;
;; - An underline/overline that is not extended to the column at which it should
;;   be hanging is dubbed INCOMPLETE.  For example::
;;
;;      |Some Title
;;      |-------
;;
;; Examples of default invocation:
;;
;;   |Some Title       --->    |Some Title
;;   |                         |----------
;;
;;   |Some Title       --->    |Some Title
;;   |-----                    |----------
;;
;;   |                         |------------
;;   | Some Title      --->    | Some Title
;;   |                         |------------
;;
;; In over-and-under style, when alternating the style, a variable is
;; available to select how much default indent to use (it can be zero).  Note
976
;; that if the current section adornment already has an indent, we don't
Stefan Monnier's avatar
Stefan Monnier committed
977 978 979 980 981
;; adjust it to the default, we rather use the current indent that is already
;; there for adjustment (unless we cycle, in which case we use the indent
;; that has been found previously).

(defgroup rst-adjust nil
982
  "Settings for adjustment and cycling of section title adornments."
Stefan Monnier's avatar
Stefan Monnier committed
983 984 985
  :group 'rst
  :version "21.1")

986
(define-obsolete-variable-alias
987
  'rst-preferred-decorations 'rst-preferred-adornments "rst 1.0.0")
988 989 990 991 992 993 994 995 996 997 998
(defcustom rst-preferred-adornments '((?= over-and-under 1)
				      (?= simple 0)
				      (?- simple 0)
				      (?~ simple 0)
				      (?+ simple 0)
				      (?` simple 0)
				      (?# simple 0)
				      (?@ simple 0))
  "Preferred hierarchy of section title adornments.

A list consisting of lists of the form (CHARACTER STYLE INDENT).
999
CHARACTER is the character used.  STYLE is one of the symbols
1000 1001 1002 1003
`over-and-under' or `simple'.  INDENT is an integer giving the
wanted indentation for STYLE `over-and-under'.  CHARACTER and
STYLE are always used when a section adornment is described.
In other places, t instead of a list stands for a transition.
1004 1005

This sequence is consulted to offer a new adornment suggestion