[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
A patch for rst.el
From: |
Wei-Wei Guo |
Subject: |
A patch for rst.el |
Date: |
Tue, 28 Apr 2009 21:29:53 +0800 |
User-agent: |
Thunderbird 2.0.0.21 (X11/20090302) |
Dear all,
I made a patch for rst.el, see the attachment.
I sent a rst.el patch months ago and Glenn Morris filed it as a wishlist item:
http://emacsbugs.donarmstrong.com/cgi-bin/bugreport.cgi?bug=1610
I promoted the functionalities recently so I send it here again. Added
functionalities
include:
- Insert bullet list and enumeration by 'M-RET'.
- Insert directives and options by 'C-c C-d'.
- Insert option by 'C-c C-o'.
- Insert hyperlink, footnote, and citation by 'C-c C-h'.
- Jump within hyperlinks by 'C-c l', 'C-c n', and 'C-c t'.
- jump within footnotes, and citation by 'C-c r', 'C-c m', and 'C-c u'.
- Add your own directives by function 'rst-add-directives'.
Hope it useful.
Best wishes,
Wei-Wei
--- rst.el 2009-04-01 08:28:16.000000000 +0800
+++ rst.el.new 2009-04-28 17:36:38.000000000 +0800
@@ -36,6 +36,8 @@
;; from it;
;; - Functions to insert and automatically update a TOC in your source
;; document;
+;; - Function to insert list, processing item bullets and enumerations
+;; automatically;
;; - Font-lock highlighting of notable reStructuredText structures;
;; - Some other convenience functions.
;;
@@ -166,11 +168,6 @@
;; - numbering: automatically detect if we have a section-numbering directive
in
;; the corresponding section, to render the toc.
;;
-;; bulleted and enumerated list items
-;; ----------------------------------
-;; - We need to provide way to rebullet bulleted lists, and that would include
-;; automatic enumeration as well.
-;;
;; Other
;; -----
;; - It would be nice to differentiate between text files using
@@ -239,14 +236,14 @@
;; Section Decorations.
;;
;; The adjustment function that decorates or rotates a section title.
- (define-key map [(control c) (control a)] 'rst-adjust)
- (define-key map [(control c) (control ?=)] 'rst-adjust)
+ ;(define-key map [(control c) (control a)] 'rst-adjust)
+ ;(define-key map [(control c) (control ?=)] 'rst-adjust)
(define-key map [(control ?=)] 'rst-adjust) ;; (Does not work on the Mac
OSX.)
;; Display the hierarchy of decorations implied by the current document
contents.
- (define-key map [(control c) (control h)]
'rst-display-decorations-hierarchy)
+ (define-key map [(control c) (control t)]
'rst-display-decorations-hierarchy)
;; Homogeneize the decorations in the document.
(define-key map [(control c) (control s)] 'rst-straighten-decorations)
-;; (define-key map [(control c) (control s)] 'rst-straighten-deco-spacing)
+ ;(define-key map [(control c) (control s)] 'rst-straighten-deco-spacing)
;;
;; Section Movement and Selection.
@@ -254,39 +251,75 @@
;; Mark the subsection where the cursor is.
(define-key map [(control c) (control m)] 'rst-mark-section)
;; Move forward/backward between section titles.
- (define-key map [(control c) (control n)] 'rst-forward-section)
- (define-key map [(control c) (control p)] 'rst-backward-section)
+ (define-key map [(meta n)] 'rst-forward-section)
+ (define-key map [(meta p)] 'rst-backward-section)
;;
;; Operating on Blocks of Text.
;;
+ ;; Inserts bullet list or enumeration list.
+ (define-key map [(meta return)] 'rst-insert-list)
+ ;; Inserts definition list.
+ ;(define-key map [(control c) t] 'rst-insert-definition)
+ ;; Inserts field list.
+ ;(define-key map [(control c) f] 'rst-insert-field)
;; Makes paragraphs in region as a bullet list.
- (define-key map [(control c) (control b)] 'rst-bullet-list-region)
+ ;(define-key map [(control c) (control b)] 'rst-bullet-list-region)
;; Makes paragraphs in region as a enumeration.
- (define-key map [(control c) (control e)] 'rst-enumerate-region)
+ ;(define-key map [(control c) (control e)] 'rst-enumerate-region)
;; Converts bullets to an enumeration.
- (define-key map [(control c) (control v)]
'rst-convert-bullets-to-enumeration)
+ ;(define-key map [(control c) (control v)]
'rst-convert-bullets-to-enumeration)
;; Makes region a line-block.
- (define-key map [(control c) (control d)] 'rst-line-block-region)
+ ;(define-key map [(control c) (control d)] 'rst-line-block-region)
;; Make sure that all the bullets in the region are consistent.
- (define-key map [(control c) (control w)] 'rst-straighten-bullets-region)
+ ;(define-key map [(control c) (control w)] 'rst-straighten-bullets-region)
;; Shift region left or right (taking into account of
enumerations/bullets, etc.).
(define-key map [(control c) (control l)] 'rst-shift-region-left)
(define-key map [(control c) (control r)] 'rst-shift-region-right)
;; Comment/uncomment the active region.
- (define-key map [(control c) (control c)] 'comment-region)
+ ;(define-key map [(control c) (control c)] 'comment-region)
+
+ ;; Insert option or directive.
+ (define-key map [(control c) (control o)] 'rst-insert-option)
+ (define-key map [(control c) (control d)] 'rst-insert-directive)
+ ;; Insert text replace definition.
+ ;(define-key map [(control c) t] 'rst-insert-replace)
+ ;; Insert image and figures
+ ;(define-key map [(control c) p] 'rst-insert-image)
+ ;(define-key map [(control c) m] 'rst-insert-figure)
+ ;; Insert admonition
+ ;(define-key map [(control c) t] 'rst-insert-admonition)
+
+ ;;
+ ;; Hypylink, Footnote, and Citation Features.
+ ;;
+ (define-key map [(control c) (control h)] 'rst-insert-link)
+ ;; Insert hyperlink
+ ;(define-key map [(control c) l] 'rst-insert-inline-link)
+ ;; Insert footnote
+ ;(define-key map [(control c) f] 'rst-insert-footnote)
+ ;; Insert citation
+ ;(define-key map [(control c) c] 'rst-insert-citation)
+ ;; Hyperlink jumping
+ (define-key map [(control c) (l)] 'rst-link-jump-to-reference)
+ (define-key map [(control c) (n)] 'rst-link-jump-within-targets)
+ (define-key map [(control c) (t)] 'rst-link-jump-to-target)
+ ;; Footnote and citation jumping
+ (define-key map [(control c) (r)] 'rst-footnote-citation-jump-to-reference)
+ (define-key map [(control c) (m)]
'rst-footnote-citation-jump-within-targets)
+ (define-key map [(control c) (u)] 'rst-footnote-citation-jump-to-target)
;;
;; Table-of-Contents Features.
;;
;; Enter a TOC buffer to view and move to a specific section.
(define-key map [(control c) (control t)] 'rst-toc)
- ;; Insert a TOC here.
- (define-key map [(control c) (control i)] 'rst-toc-insert)
+ ;; Insert a TOC here. use `rst-insert-directive' instead
+ ;(define-key map [(control c) i] 'rst-toc-insert)
;; Update the document's TOC (without changing the cursor position).
(define-key map [(control c) (control u)] 'rst-toc-update)
;; Got to the section under the cursor (cursor must be in TOC).
- (define-key map [(control c) (control f)] 'rst-goto-section)
+ ;(define-key map [(control c) (control f)] 'rst-goto-section)
;;
;; Converting Documents from Emacs.
@@ -344,8 +377,8 @@
(defcustom rst-mode-hook nil
- "Hook run when Rst mode is turned on.
-The hook for Text mode is run before this one."
+ "Hook run when Rst Mode is turned on.
+The hook for Text Mode is run before this one."
:group 'rst
:type '(hook))
@@ -1504,6 +1537,66 @@
)))
+;=================================================
+; list related functions.
+
+;==============
+; Borrowed from a2r.el (version 1.3), writen by Lawrence Mitchell
<address@hidden>
+; I need to make some tiny changes on the functions, so I put it here.
+; -- Wei-Wei Guo
+
+(defconst arabic-to-roman
+ '((1000 . "M") (900 . "CM") (500 . "D") (400 . "CD")
+ (100 . "C") (90 . "XC") (50 . "L") (40 . "XL")
+ (10 . "X") (9 . "IX") (5 . "V") (4 . "IV")
+ (1 . "I"))
+ "List of maps between Arabic numbers and their Roman numeral equivalents.")
+
+(defun arabic-to-roman (num &optional arg)
+ "Convert Arabic number NUM to its Roman numeral representation.
+
+Obviously, NUM must be greater than zero. Don't blame me, blame the
+Romans, I mean \"what have the Romans ever _done_ for /us/?\" (with
+apologies to Monty Python).
+If optional prefix ARG is non-nil, insert in current buffer."
+ (let ((map arabic-to-roman)
+ res)
+ (while (and map (> num 0))
+ (if (or (= num (caar map))
+ (> num (caar map)))
+ (setq res (concat res (cdar map))
+ num (- num (caar map)))
+ (setq map (cdr map))))
+ res))
+
+(defconst roman-to-arabic
+ '(("M" . 1000) ("CM" . 900) ("D" . 500) ("CD" . 400)
+ ("C" . 100) ("XC" . 90) ("L" . 50) ("XL" . 40)
+ ("X" . 10) ("IX" . 9) ("V" . 5) ("IV" . 4)
+ ("I" . 1))
+ "List of maps between Roman numerals and their Arabic equivalents.")
+
+(defun roman-to-arabic (string &optional arg)
+ "Convert STRING of Roman numerals to an Arabic number.
+
+If STRING contains a letter which isn't a valid Roman numeral, the rest
+of the string from that point onwards is ignored.
+
+Hence:
+MMD == 2500
+and
+MMDFLXXVI == 2500.
+If optional ARG is non-nil, insert in current buffer."
+ (let ((res 0)
+ (map roman-to-arabic))
+ (while map
+ (if (string-match (concat "^" (caar map)) string)
+ (setq res (+ res (cdar map))
+ string (replace-match "" nil t string))
+ (setq map (cdr map))))
+ res))
+;==============
+
(defun rst-find-pfx-in-region (beg end pfx-re)
"Find all the positions of prefixes in region between BEG and END.
This is used to find bullets and enumerated list items. PFX-RE
@@ -1528,23 +1621,221 @@
(forward-line 1)) )
(nreverse pfx)))
+(defun rst-insert-list-pos (newitem)
+ "Arrage relative position of a newly inserted list item.
+
+Adding a new list might consider three situations:
+
+ (a) Current line is a blank line.
+ (b) Previous line is a blank line.
+ (c) Following line is a blank line.
+
+When (a) and (b), just add the new list at current line.
+
+when (a) and not (b), add a blank line before adding the new list.
+
+When not (a), add a blank line and a new line at current point.
+
+Other situations are just ignored and left to users themselves."
+ (if (save-excursion
+ (beginning-of-line)
+ (looking-at "^[ \t]*$"))
+ (if (save-excursion
+ (forward-line -1)
+ (looking-at "^[ \t]*$"))
+ (insert (concat newitem " "))
+ (insert (concat "\n" newitem " ")))
+ (progn
+ (insert (concat "\n\n" newitem " ")))))
+
+(defvar rst-initial-enums
+ '("#." "1." "a." "A." "I." "i." "(1)" "(a)" "(A)" "(I)" "(i)" "1)" "a)" "A)"
"I)" "i)")
+ "List of initial enumerates.")
+
+(defvar rst-initial-items
+ (append (mapcar 'char-to-string rst-bullets) rst-initial-enums)
+ "List of initial items. It's collection of bullets and enumerations")
+
+(defun rst-insert-list-new-item ()
+ "Insert a new list item.
+
+User is asked to select the item style first, for example (a), i), +. Use TAB
+for completition and choices.
+
+If user selects bullets or #, it's just added with position arranged by
+`rst-insert-list-new-pos'.
+
+If user selects enumerates, a further prompt is given. User need to input a
+starting item, for example 'e' for 'A)' style. The position is also arranged by
+`rst-insert-list-new-pos'.
+"
+ (interactive)
+ (let (itemstyle itemno itemfirst)
+ (setq itemstyle (completing-read "Providing perfered item (default '#.'): "
+ rst-initial-items nil t nil nil "#."))
+ (when (string-match "[aA1Ii]" itemstyle)
+ (setq itemfirst (match-string 0 itemstyle))
+ (cond ((equal itemfirst "a")
+ (progn
+ (setq itemno (read-string "Providing starting (default a): "
nil nil "a"))
+ (setq itemstyle (replace-match
+ (downcase itemno)
+ nil nil itemstyle))))
+ ((equal itemfirst "A")
+ (progn
+ (setq itemno (read-string "Providing starting (default A): "
nil nil "A"))
+ (setq itemstyle (replace-match
+ (upcase itemno)
+ nil nil itemstyle))))
+ ((equal itemfirst "I")
+ (progn
+ (setq itemno (read-number "Providing starting (default 1): " 1))
+ (string-match "[aA1Ii]" itemstyle)
+ (setq itemstyle (replace-match
+ (arabic-to-roman itemno)
+ nil nil itemstyle))))
+ ((equal itemfirst "i")
+ (progn
+ (setq itemno (read-number "Providing starting (default 1): " 1))
+ (string-match "[aA1Ii]" itemstyle)
+ (setq itemstyle (replace-match
+ (downcase (arabic-to-roman itemno))
+ nil nil itemstyle))))
+ ((equal itemfirst "1")
+ (progn
+ (setq itemno (read-number "Providing starting (default 1): " 1))
+ (string-match "[aA1Ii]" itemstyle)
+ (setq itemstyle (replace-match
+ (number-to-string itemno)
+ nil nil itemstyle))))
+ ))
+ (rst-insert-list-pos itemstyle)))
+
(defvar rst-re-bullets
(format "\\([%s][ \t]\\)[^ \t]" (regexp-quote (concat rst-bullets)))
"Regexp for finding bullets.")
-;; (defvar rst-re-enumerations
-;; "\\(\\(#\\|[0-9]+\\)\\.[ \t]\\)[^ \t]"
-;; "Regexp for finding bullets.")
+(defvar rst-re-enumerates
+ (format "^[ \t]*\\(%s\\|%s\\)[ \t]"
+ "\\([0-9]+\\|[a-zA-Z]\\|[IVXLCDMivxlcdm]+\\)\\."
+ "(?\\([0-9]+\\|[a-zA-Z]\\|[IVXLCDMivxlcdm]+\\))")
+ "Regexp for finding enumerates (# is not included).")
(defvar rst-re-items
- (format "\\(%s\\|%s\\)[^ \t]"
- (format "[%s][ \t]" (regexp-quote (concat rst-bullets)))
- "\\(#\\|[0-9]+\\)\\.[ \t]")
- "Regexp for finding bullets.")
+ (format "^[ \t]*\\(%s\\|%s\\|%s\\)[ \t]"
+ (format "[%s]" (regexp-quote (concat rst-bullets)))
+ "\\(#\\|[a-z]\\|[0-9]+\\|[A-Z]\\|[IVXLCDM]+\\|[ivxlcdm]+\\)\\."
+ "(?\\([a-z]\\|[0-9]+\\|[A-Z]\\|[IVXLCDM]+\\|[ivxlcdm]+\\))")
+ "Regexp for finding bullets and enumerates.")
-(defvar rst-preferred-bullets
- '(?- ?* ?+)
- "List of favourite bullets to set for straightening bullets.")
+(defun rst-list-match-string (reg)
+ "Match a regex in a line and return the matched string by match-string.
+
+If nothing matched, a empty string is returned."
+ (let (matched)
+ (save-excursion
+ (end-of-line)
+ (if (re-search-backward reg (line-beginning-position) t)
+ (setq matched (match-string 0))
+ (setq matched "")))
+ matched))
+
+(defun rst-insert-list-continue ()
+ "Insert a list item with current list style and indentation level.
+
+The function works for all style of bullet lists and enumeration lists. Only
one
+thing need to be noticed:
+
+List style alphabetical list, such as 'a.', and roman numerical list, such as
'i.',
+have some overlapping items, for example 'v.' The function can deal with the
+problem elegantly in most situations. But when those overlapped list proceeded
+by a blank line, it is hard to determine which type to use automatically. The
+function uses roman numerical list defaultly. If you want alphabetical list,
just
+use a prefix (\\[universal-argument]).
+"
+ (interactive)
+ (let (curitem newitem itemno previtem tmpitem)
+ (setq curitem (rst-list-match-string rst-re-items))
+ (cond ((string-match (format "#.\\|[%s]"
+ (regexp-quote (concat rst-bullets))) curitem)
+ (setq newitem curitem))
+ ((string-match "[0-9]+" curitem)
+ (progn
+ (setq itemno (1+
+ (string-to-number
+ (match-string 0 curitem))))
+ (setq newitem (replace-match
+ (number-to-string itemno)
+ nil nil curitem))))
+ ((and (string-match "[IVXLCDMivxlcdm]+" curitem)
+ (progn
+ (setq tmpitem (match-string 0 curitem))
+ (or (> (length tmpitem) 1)
+ (and (= (length tmpitem) 1)
+ (null current-prefix-arg)
+ (progn
+ (save-excursion
+ (forward-line -1)
+ (setq previtem (rst-list-match-string
rst-re-enumerates))
+ (when (string-match "[a-zA-Z]+" previtem)
+ (setq previtem (match-string 0 previtem))))
+ (or (> (length previtem) 1)
+ (= (length previtem) 0)))))))
+ (progn
+ (setq itemno (1+ (roman-to-arabic tmpitem)))
+ (string-match "[IVXLCDMivxlcdm]+" curitem)
+ (if (isearch-no-upper-case-p tmpitem nil)
+ (setq newitem (replace-match
+ (downcase (arabic-to-roman itemno))
+ nil nil curitem))
+ (setq newitem (replace-match
+ (arabic-to-roman itemno)
+ nil nil curitem)))))
+ ((string-match "[a-zA-Z]" curitem)
+ (progn
+ (setq itemno (1+
+ (string-to-char
+ (match-string 0 curitem))))
+ (setq newitem (replace-match
+ (char-to-string itemno)
+ nil nil curitem)))))
+ (insert (concat "\n" newitem))))
+
+
+(defun rst-insert-list ()
+ "Insert a list item at the current point.
+
+The command can insert a new list or a continuing list. When it is called at a
+non-list line, it will promote to insert new list. When it is called at a list
+line, it will insert a list with the same list style.
+
+1. When inserting a new list:
+
+User is asked to select the item style first, for example (a), i), +. Use TAB
+for completition and choices.
+
+ (a) If user selects bullets or #, it's just added.
+ (b) If user selects enumerates, a further prompt is given. User need to input
a
+starting item, for example 'e' for 'A)' style.
+
+The position of the new list is arranged according whether or not the current
line
+and the previous line are blank lines.
+
+2. When continuing a list, one thing need to be noticed:
+
+List style alphabetical list, such as 'a.', and roman numerical list, such as
'i.',
+have some overlapping items, for example 'v.' The function can deal with the
+problem elegantly in most situations. But when those overlapped list proceeded
+by a blank line, it is hard to determine which type to use automatically. The
+function uses roman numerical list defaultly. If you want alphabetical list,
just
+use a prefix (\\[universal-argument]).
+"
+ (interactive)
+ (if (equal (rst-list-match-string rst-re-items) "")
+ (rst-insert-list-new-item)
+ (rst-insert-list-continue)))
+
+;==============
(defun rst-straighten-bullets-region (beg end)
"Make all the bulleted list items in the region consistent.
@@ -1552,9 +1843,9 @@
after you have merged multiple bulleted lists to make them use
the same/correct/consistent bullet characters.
-See variable `rst-preferred-bullets' for the list of bullets to
-adjust. If bullets are found on levels beyond the
-`rst-preferred-bullets' list, they are not modified."
+See variable `rst-bullets' for the list of bullets to adjust.
+If bullets are found on levels beyond the `rst-bullets' list,
+they are not modified."
(interactive "r")
(let ((bullets (rst-find-pfx-in-region beg end
@@ -1573,7 +1864,7 @@
(let ((poslist ())) ; List of (indent . positions).
(maphash (lambda (x y) (push (cons x y) poslist)) levtable)
- (let ((bullets rst-preferred-bullets))
+ (let ((bullets rst-bullets))
(dolist (x (sort poslist 'car-less-than-car))
(when bullets
;; Apply the characters.
@@ -1583,6 +1874,9 @@
(insert (string (car bullets))))
(setq bullets (cdr bullets))))))))
+;=================================================
+
+
(defun rst-rstrip (str)
"Strips the whitespace at the end of string STR."
(string-match "[ \t\n]*\\'" str)
@@ -1908,7 +2202,7 @@
(let ((p (point)))
(save-excursion
(when (rst-toc-insert-find-delete-contents)
- (insert "\n ")
+ (insert "\n ")
(rst-toc-insert)
))
;; Somehow save-excursion does not really work well.
@@ -2816,7 +3110,7 @@
1 rst-block-face)
;; `Enumerated Lists`_
(list
- (concat re-bol "\\((?\\(#\\|[0-9]+\\|[A-Za-z]\\|[IVXLCMivxlcm]+\\)[.)]"
+ (concat re-bol "\\((?\\(#\\|[0-9]+\\|[A-Za-z]\\|[IVXLCDMivxlcdm]+\\)[.)]"
re-blksep1 "\\)")
1 rst-block-face)
;; `Definition Lists`_ FIXME: missing
@@ -3182,6 +3476,624 @@
(set-match-data mtc)
t))))
+
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; directives and hyperlinks.
+
+;===== directive type list and command =====
+
+(defvar rst-directive-type-alist
+ '(("definition" . rst-insert-definition)
+ ("field" . rst-insert-field)
+ ("admonition" . rst-insert-admonition)
+ ("image" . rst-insert-image)
+ ("figure" . rst-insert-figure)
+ ("topic" . rst-insert-topic)
+ ("sidebar" . rst-insert-sidebar)
+ ("line-block" . rst-insert-line-block)
+ ("parsed-literal" . rst-insert-parsed-literal)
+ ("rubric" . rst-insert-rubric)
+ ("epigraph" . rst-insert-epigraph)
+ ("highlights" . rst-insert-highlights)
+ ("pull-quote" . rst-insert-pull-quote)
+ ("compound" . rst-insert-compound)
+ ("container" . rst-insert-container)
+ ("table" . rst-insert-table)
+ ("csv-table" . rst-insert-csv-table)
+ ("list-table" . rst-insert-list-table)
+ ("contents" . rst-insert-contents)
+ ("sectnum" . rst-insert-sectnum)
+ ("replace" . rst-insert-replace)
+ ("unicode" . rst-insert-unicode)
+ ("date" . rst-insert-date)
+ ("include" . rst-insert-include)
+ ("raw" . rst-insert-raw))
+ "List of directive inserting functions of directive types.")
+
+(defvar rst-directive-types
+ '("definition" "field" "admonition"
+ "image" "figure"
+ "topic" "sidebar" "line-block" "parsed-literal" "rubric" "epigraph"
+ "highlights" "pull-quote" "compound" "container"
+ "table" "csv-table" "list-table"
+ "contents" "sectnum" "include" "raw"
+ "replace" "unicode" "date"
+)
+ "List of directive types")
+
+(defvar rst-directive-option-list
+ '(("definition" rst-option-definition t)
+ ("field" rst-option-field t)
+ ("admonition" rst-option-admonition nil)
+ ("image" rst-option-image nil)
+ ("figure" rst-option-figure t)
+ ("topic" nil t)
+ ("sidebar" rst-option-sidebar t)
+ ("line-block" nil t)
+ ("parsed-literal" nil t)
+ ("rubric" nil nil)
+ ("epigraph" nil t)
+ ("highlights" nil t)
+ ("pull-quote" nil t)
+ ("compound" nil t)
+ ("container" nil t)
+ ("table" nil t)
+ ("csv-table" rst-option-csv-table t)
+ ("list-table" rst-option-list-table t)
+ ("contents" rst-contents-option nil)
+ ("sectnum" rst-sectnum-option nil)
+ ("replace" nil nil)
+ ("unicode" rst-option-unicode nil)
+ ("date" nil nil)
+ ("include" rst-include-option nil)
+ ("raw" rst-option-raw t))
+ "List of option functions of directive types.")
+
+(defun rst-add-directive-type (type directfunc optalist content)
+ "Adding new directive to directive alist and completion list.
+
+Use the following way to add directive type.
+
+ (rst-add-directive-type \"definition\"
+ 'rst-insert-definition
+ 'rst-directive-options
+ 'content-presence-boolean)
+"
+ (add-to-list 'rst-directive-types type)
+ (add-to-list 'rst-directive-type-alist (cons type directfunc))
+ (add-to-list 'rst-directive-option-list (list type optalist content)))
+
+(defun rst-add-directives (directlist)
+ "Meta function of add directives.
+
+Elements of directives should arranged as
+
+ (type funciton option-list content-boolean).
+"
+ (dolist (direct directlist)
+ (eval (cons 'rst-add-directive-type direct))))
+
+(defun rst-insert-directive ()
+ "Meta-function of all directives."
+ (interactive)
+ (let (type optlist)
+ (setq type (completing-read "Providing directive type: "
rst-directive-types))
+ (funcall (cdr (assoc type rst-directive-type-alist)))
+ (setq optlist (eval (car (cdr (assoc type rst-directive-option-list)))))
+ (if optlist
+ (while (y-or-n-p "Set directive option(s)? ")
+ (rst-option-directive optlist)))
+ (if (eval (cadr (cdr (assoc type rst-directive-option-list))))
+ (insert "\n ")
+ (newline))))
+
+;==== directive and list definitions ====
+
+;--- list looks like directive ---
+
+(defun rst-insert-definition ()
+ "Insert a definition list"
+ (interactive)
+ (let (term classifiers classel)
+ (setq term (read-string "Providing the definition's term: "))
+ (setq classifiers (read-string "Providing classifier(s) (if many,
seperated by ', '): "))
+ (if (equal classifiers "")
+ (insert term "\n ")
+ (progn
+ (setq classifiers (split-string classifiers ", "))
+ (dolist (tmpclass classifiers)
+ (setq classel (concat classel " : " tmpclass)))
+ (insert term classel "\n ")))))
+
+(defun rst-insert-field ()
+ "Insert a field list."
+ (interactive)
+ (let (field value)
+ (setq field (read-string "Providing field: "))
+ (save-excursion
+ (beginning-of-line)
+ (insert (concat ":" field ": ")))))
+
+;--- function for defining directives ---
+
+(defun rst-insert-directive-type (type &optional argument)
+ "Insert the first line of directive"
+ (insert (concat ".. " type ":: " argument "\n")))
+
+(defun rst-insert-directive-option (option &optional value)
+ "Insert an option line of directive"
+ (insert (concat " :" option ": " value "\n")))
+
+(defun rst-insert-option ()
+ "Insert a directive option."
+ (interactive)
+ (let (option value)
+ (save-excursion
+ (beginning-of-line)
+ (when (looking-at "^\\.\\. \\sw+::")
+ (setq option (read-string "Providing directive option: "))
+ (setq value (read-string "Providing option value: "))
+ (newline)
+ (rst-insert-directive-option option value)))))
+
+(defun rst-option-directive (optalist)
+ "Insert directive options in directive inserting function."
+ (let (optlist option type value)
+ (setq optlist (mapcar 'car optalist))
+ (setq option (completing-read "Providing option: " optlist))
+ (setq type (car (cdr (assoc option optalist))))
+ (setq value
+ (cond
+ ((equal type "flag") nil)
+ ((equal type "option") (completing-read
+ "Providing optional value: "
+ (cadr (cdr (assoc option optalist)))))
+ ((equal type "number") (number-to-string
+ (read-number "Providing numeric value: ")))
+ ((equal type "string") (read-string "Providing value: "))))
+ (rst-insert-directive-option option value)))
+
+;--- directives ---
+
+(defun rst-insert-admonition ()
+ "Insert a admonition."
+ (interactive)
+ (let (admon argu)
+ (setq admon (read-string "Providing admonition type: "))
+ (setq argu (read-string "Providing admonition description: "))
+ (rst-insert-directive-type admon argu)))
+
+(defun rst-insert-image ()
+ "Insert a image."
+ (interactive)
+ (let (arg)
+ (setq arg (read-string "Providing image and its path: "))
+ (rst-insert-directive-type "image" arg)))
+
+(defvar rst-option-image
+'(("align" "option" ("top" "middle" "bottom" "left" "center" "right"))
+ ("width" "number" 300)
+ ("height" "number" 300)
+ ("scale" "number" 80)
+ ("alt" "string" "")
+ ("target" "string" "")))
+
+(defun rst-insert-figure ()
+ "Insert a image."
+ (interactive)
+ (let (arg)
+ (setq arg (read-string "Providing figure and its path: "))
+ (rst-insert-directive-type "figure" arg)))
+
+(defvar rst-option-figure
+'(("align" "option" ("left" "center" "right"))
+ ("width" "number" 300)
+ ("height" "number" 300)
+ ("scale" "number" 80)
+ ("figwidth" "string" "350")
+ ("alt" "string" "")
+ ("target" "string" "")))
+
+(defun rst-insert-topic ()
+ "Insert a topic."
+ (interactive)
+ (let (arg)
+ (setq arg (read-string "Providing topic title: "))
+ (rst-insert-directive-type "topic" arg)))
+
+(defun rst-insert-sidebar ()
+ "Insert a sidebar."
+ (interactive)
+ (let (arg)
+ (setq arg (read-string "Providing sidebar title: "))
+ (rst-insert-directive-type "sidebar" arg)))
+
+(defvar rst-option-sidebar
+'(("subtitle" "string" "")))
+
+(defun rst-insert-line-block ()
+ "Insert a line block."
+ (interactive)
+ (rst-insert-directive-type "line-block"))
+
+(defun rst-insert-parsed-literal ()
+ "Insert a parsed literal."
+ (interactive)
+ (rst-insert-directive-type "parsed-literal"))
+
+(defun rst-insert-rubric ()
+ "Insert a rubric title."
+ (interactive)
+ (let (arg)
+ (setq arg (read-string "Providing rubric title: "))
+ (rst-insert-directive-type "rubric" arg)))
+
+(defun rst-insert-epigraph ()
+ "Insert a epigraph."
+ (interactive)
+ (rst-insert-directive-type "epigraph"))
+
+(defun rst-insert-highlights ()
+ "Insert a highlights."
+ (interactive)
+ (rst-insert-directive-type "highlights"))
+
+(defun rst-insert-pull-quote ()
+ "Insert a pull quote."
+ (interactive)
+ (rst-insert-directive-type "pull-quote"))
+
+(defun rst-insert-compound ()
+ "Insert a compound."
+ (interactive)
+ (rst-insert-directive-type "compound"))
+
+(defun rst-insert-container ()
+ "Insert a container."
+ (interactive)
+ (let (arg)
+ (setq arg (read-string "Providing container title: "))
+ (rst-insert-directive-type "container" arg)))
+
+(defun rst-insert-table ()
+ "Insert a table."
+ (interactive)
+ (let (arg)
+ (setq arg (read-string "Providing table title: "))
+ (rst-insert-directive-type "table" arg)))
+
+(defun rst-insert-csv-table ()
+ "Insert a table."
+ (interactive)
+ (let (arg)
+ (setq arg (read-string "Providing table title: "))
+ (rst-insert-directive-type "csv-table" arg)))
+
+(defvar rst-option-csv-table
+'(("widths" "string" "")
+ ("header-rows" "number" 0)
+ ("stub-columns" "number" 0)
+ ("header" "string" "")
+ ("file" "string" "")
+ ("url" "string" "")
+ ("encoding" "string" "")
+ ("delim" "string" "")
+ ("quote" "string" "")
+ ("keepspace" "flag" nil)
+ ("escape" "string" "")))
+
+(defun rst-insert-list-table ()
+ "Insert a table."
+ (interactive)
+ (let (arg)
+ (setq arg (read-string "Providing table title: "))
+ (rst-insert-directive-type "list-table" arg)))
+
+(defvar rst-option-list-table
+'(("widths" "string" "")
+ ("header-rows" "number" 0)
+ ("stub-columns" "number" 0)))
+
+(defun rst-insert-contents ()
+ "Insert a contents."
+ (interactive)
+ (let (arg)
+ (setq arg (read-string "Providing contents title: "))
+ (rst-insert-directive-type "contents" arg)))
+
+(defvar rst-option-contents
+'(("backlinks" "option" ("entry" "top" "none"))
+ ("depth" "number" 2)
+ ("local" "flag" nil)))
+
+(defun rst-insert-sectnum ()
+ "Set section-autonumbering."
+ (interactive)
+ (rst-insert-directive-type "sectnum"))
+
+(defvar rst-option-sectnum
+'(("prefix" "string" "")
+ ("suffix" "string" "")
+ ("depth" "number" 2)
+ ("start" "number" 1)))
+
+(defun rst-insert-replace ()
+ "Insert the head of word replace."
+ (interactive)
+ (let (tag)
+ (setq tag (read-string "Providing replaced word: "))
+ (rst-insert-directive-type (concat "|" tag "| replace"))))
+
+(defun rst-insert-unicode ()
+ "Insert unicode replacement."
+ (interactive)
+ (let (tag)
+ (setq tag (read-string "Providing unicode string: "))
+ (rst-insert-directive-type (concat "|" tag "| unicode"))))
+
+(defvar rst-option-unicode
+ '(("ltrim" "flag" nil)
+ ("rtrim" "flag" nil)
+ ("trim" "flag" nil)))
+
+(defun rst-insert-date ()
+ "Insert date or time."
+ (interactive)
+ (let (type value)
+ (setq type (completing-read "Insert date or time? " '("date" "time")))
+ (cond
+ ((equal type "date")
+ (setq value (read-string "Providing date format: " nil nil "%Y-%m-%d")))
+ ((equal type "time")
+ (setq value (read-string "Providing time format: " nil nil "%H:%M"))))
+ (rst-insert-directive-type (concat "|" type "| date") value)))
+
+(defun rst-insert-include ()
+ "Insert an external file."
+ (interactive)
+ (let (arg)
+ (setq arg (read-string "Providing file path: "))
+ (rst-insert-directive-type "include" arg)))
+
+(defvar rst-option-include
+ '(("start-after" "string" "")
+ ("end-before" "string" "")
+ ("encoding" "string" "")
+ ("literal" "flag" nil)))
+
+(defun rst-insert-raw ()
+ "Insert raw data."
+ (interactive)
+ (let (arg)
+ (setq arg (read-string "Providing raw data type: "))
+ (rst-insert-directive-type "raw" arg)))
+
+(defvar rst-option-raw
+ '(("file" "string" "")
+ ("url" "string" "")
+ ("encoding" "string" "")))
+
+
+;==== links ====
+
+;--- link inserting ---
+
+(defvar rst-link-type-alist
+ '(("hyperlink" . rst-insert-inline-link)
+ ("footnote" . rst-insert-footnote)
+ ("citation" . rst-insert-citation))
+ "List of link types.")
+
+(defvar rst-link-type
+ '("hyperlink" "footnote" "citation")
+ "List of link types for completion")
+
+(defun rst-insert-link ()
+ "Meta-function of all directives."
+ (interactive)
+ (let (type)
+ (setq type (completing-read "Providing link type: " rst-link-type))
+ (funcall (cdr (assoc type rst-link-type-alist)))))
+
+(defun rst-insert-inline-link ()
+ "Insert a inline link with both target and reference."
+ (interactive)
+ (let (link target reference)
+ (setq link (read-string "Providing link name: "))
+ (if (string-match " " link)
+ (progn
+ (setq target (concat "`" link "`_"))
+ (setq reference (concat ".. _`" link "`: ")))
+ (progn
+ (setq target (concat link "_"))
+ (setq reference (concat ".. _" link ": "))))
+ (save-excursion
+ (if (equal (char-before) (string-to-char " "))
+ (insert target " ")
+ (insert (concat " " target " ")))
+ (end-of-line)
+ (insert (concat "\n\n" reference)))))
+
+(defun rst-insert-footnote ()
+ "Insert a inline footnote with both target and reference."
+ (interactive)
+ (let (footnote target reference)
+ (setq footnote (read-string "Providing footnote name: "))
+ (setq target (concat "[#" footnote "]_"))
+ (setq reference (concat ".. [#" footnote "] "))
+ (save-excursion
+ (if (equal (char-before) (string-to-char " "))
+ (insert target " ")
+ (insert (concat " " target " ")))
+ (end-of-line)
+ (insert (concat "\n\n" reference)))))
+
+(defun rst-insert-citation ()
+ "Insert a inline citation with both target and reference."
+ (interactive)
+ (let (citation target reference)
+ (setq citation (read-string "Providing citation name: "))
+ (setq target (concat "[" citation "]_"))
+ (setq reference (concat ".. [" citation "] "))
+ (save-excursion
+ (if (equal (char-before) (string-to-char " "))
+ (insert target " ")
+ (insert (concat " " target " ")))
+ (end-of-line)
+ (insert (concat "\n\n" reference)))))
+
+;--- link jumping ---
+
+(defun rst-hyper-link-reference-match ()
+ "Match link target around the point."
+ (let (link reference target)
+ (save-excursion
+ (if (search-forward "_"
+ (save-excursion
+ (forward-sentence)
+ (point))
+ t 1)
+ (progn
+ (backward-char)
+ (unless (equal (char-before) ?\\)
+ (if (equal (char-before) ?`)
+ (progn
+ (forward-char)
+ (re-search-backward "`[[:alnum:][:punct:][:space:]]+`_"
+ (save-excursion
+ (search-backward "`" nil t 2)
+ (point))
+ t)
+ (setq reference (match-string 0))
+ (setq link (substring reference 0 -1)))
+ (progn
+ (forward-char)
+ (re-search-backward " \\sw+_"
+ (save-excursion
+ (search-backward " ")
+ (point))
+ t)
+ (setq reference (match-string 0))
+ (setq link (substring reference 1 -1)))))
+ (setq target (concat ".. _" link ":")))))
+ (list reference target)))
+
+(defun rst-link-jump-to-target ()
+ "Jump from intertext link reference to link target."
+ (interactive)
+ (let ((target (elt (rst-hyper-link-reference-match) 1)))
+ (when (save-excursion
+ (goto-char (point-min))
+ (search-forward target))
+ (goto-char (point-min))
+ (search-forward target))))
+
+(defun rst-link-jump-within-references ()
+ "Jump within references of an intertext link, if exist."
+ (interactive)
+ (let ((reference (elt (rst-hyper-link-reference-match) 0)))
+ (if (save-excursion
+ (search-forward reference nil t 1))
+ (progn
+ (search-forward reference nil t 1)
+ (backward-char 1))
+ (when (y-or-n-p "No link reference behind. Search from the beginning?")
+ (goto-char (point-min))
+ (search-forward reference nil t 1)
+ (backward-char 1)))))
+
+(defun rst-hyper-link-target-match ()
+ "Match link reference at the target line."
+ (let (link reference target)
+ (save-excursion
+ (when (search-backward ".. _" (line-beginning-position) t 1)
+ (re-search-forward
+ "^\\.\\. _`?[[:alnum:][:punct:][:space:]]+`?: "
+ (line-end-position) t 1)
+ (setq target (match-string 0))))
+ (setq link (substring target 4 -2))
+ (if (equal (substring link 0 1) "`")
+ (setq reference (concat link "_"))
+ (setq reference (concat " " link "_")))
+ (list reference target)))
+
+(defun rst-link-jump-to-reference ()
+ "Jump from intertext link target to link reference."
+ (interactive)
+ (let ((reference (elt (rst-hyper-link-target-match) 0)))
+ (when (save-excursion
+ (goto-char (point-max))
+ (search-backward reference))
+ (goto-char (point-max))
+ (search-backward reference))))
+
+;--- footnote and citation ---
+
+(defun rst-footnote-citation-reference-match ()
+ "Match footnote or citation reference around the point."
+ (let (link reference target)
+ (save-excursion
+ (when (search-forward "]_"
+ (save-excursion
+ (forward-sentence)
+ (point))
+ t 1)
+ (re-search-backward "\\[[[:alnum:][:punct:][:space:]]+\\]_"
+ (save-excursion
+ (search-backward "[" nil t 1)
+ (point))
+ t)
+ (setq reference (match-string 0))))
+ (setq link (substring reference 1 -2))
+ (setq target (concat ".. [" link "]"))
+ (list reference target)))
+
+(defun rst-footnote-citation-target-match ()
+ "Match footnote or citation reference at the target line."
+ (let (link reference target)
+ (save-excursion
+ (when (search-backward ".. [" (line-beginning-position) t 1)
+ (re-search-forward
+ "^\\.\\. \\[[[:alnum:][:punct:][:space:]]+\\] "
+ (line-end-position) t 1)
+ (setq target (match-string 0))))
+ (setq link (substring target 4 -2))
+ (setq reference (concat " [" link "]_"))
+ (list reference target)))
+
+(defun rst-footnote-citation-jump-to-target ()
+ "Jump from footnote or citation reference to target."
+ (interactive)
+ (let ((target (elt (rst-footnote-citation-reference-match) 1)))
+ (when (save-excursion
+ (goto-char (point-min))
+ (search-forward target))
+ (goto-char (point-min))
+ (search-forward target))))
+
+(defun rst-footnote-citation-jump-within-references ()
+ "Jump within references of an footnote or citation, if exist."
+ (interactive)
+ (let ((reference (elt (rst-footnote-citation-reference-match) 0)))
+ (if (save-excursion
+ (search-forward reference nil t 1))
+ (progn
+ (search-forward reference nil t 1)
+ (backward-char 1))
+ (when (y-or-n-p "No link reference behind. Search from the beginning?")
+ (goto-char (point-min))
+ (search-forward reference nil t 1)
+ (backward-char 2)))))
+
+(defun rst-footnote-citation-jump-to-reference ()
+ "Jump from footnote or citation target to reference."
+ (interactive)
+ (let ((reference (elt (rst-footnote-citation-target-match) 0)))
+ (when (save-excursion
+ (goto-char (point-max))
+ (search-backward reference))
+ (goto-char (point-max))
+ (search-backward reference))))
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- A patch for rst.el,
Wei-Wei Guo <=