aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/textmodes
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/textmodes')
-rw-r--r--lisp/textmodes/artist.el45
-rw-r--r--lisp/textmodes/bibtex.el566
-rw-r--r--lisp/textmodes/fill.el10
-rw-r--r--lisp/textmodes/flyspell.el139
-rw-r--r--lisp/textmodes/ispell.el9
-rw-r--r--lisp/textmodes/paragraphs.el62
-rw-r--r--lisp/textmodes/picture.el10
-rw-r--r--lisp/textmodes/table.el17
-rw-r--r--lisp/textmodes/tex-mode.el31
-rw-r--r--lisp/textmodes/texinfmt.el4
10 files changed, 478 insertions, 415 deletions
diff --git a/lisp/textmodes/artist.el b/lisp/textmodes/artist.el
index e4f143c3b87..9535d39b1d1 100644
--- a/lisp/textmodes/artist.el
+++ b/lisp/textmodes/artist.el
@@ -1,6 +1,6 @@
1;;; artist.el --- draw ascii graphics with your mouse 1;;; artist.el --- draw ascii graphics with your mouse
2 2
3;; Copyright (C) 2000, 2001 Free Software Foundation, Inc. 3;; Copyright (C) 2000, 2001, 2004 Free Software Foundation, Inc.
4 4
5;; Author: Tomas Abrahamsson <tab@lysator.liu.se> 5;; Author: Tomas Abrahamsson <tab@lysator.liu.se>
6;; Maintainer: Tomas Abrahamsson <tab@lysator.liu.se> 6;; Maintainer: Tomas Abrahamsson <tab@lysator.liu.se>
@@ -1698,19 +1698,14 @@ info-variant-part."
1698 (t (cons (car l) (artist-butlast (cdr l)))))) 1698 (t (cons (car l) (artist-butlast (cdr l))))))
1699 1699
1700 1700
1701(defun artist-last (seq &optional n) 1701(defun artist-last (l &optional n)
1702 "Return the last link in the list SEQ. 1702 "Return the last link in the list L.
1703With optional argument N, returns Nth-to-last link (default 1)." 1703With optional argument N, returns Nth-to-last link (default 1)."
1704 (if (not n) 1704 (nth (- (length l) (or n 1)) l))
1705 (setq n 1))
1706 (let ((len (length seq)))
1707 (elt seq (- len n))))
1708 1705
1709(defun artist-remove-nulls (l) 1706(defun artist-remove-nulls (l)
1710 "Remove nils in list L." 1707 "Remove nils in list L."
1711 (cond ((null l) nil) 1708 (remq nil l))
1712 ((null (car l)) (artist-remove-nulls (cdr l)))
1713 (t (cons (car l) (artist-remove-nulls (cdr l))))))
1714 1709
1715(defun artist-uniq (l) 1710(defun artist-uniq (l)
1716 "Remove consecutive duplicates in list L. Comparison is done with `equal'." 1711 "Remove consecutive duplicates in list L. Comparison is done with `equal'."
@@ -3368,8 +3363,8 @@ The POINT-LIST is expected to cover the first quadrant."
3368 (append right-half left-half))) 3363 (append right-half left-half)))
3369 3364
3370 3365
3371(defun artist-draw-ellipse-general (x y x-radius y-radius) 3366(defun artist-draw-ellipse-general (x1 y1 x-radius y-radius)
3372 "Draw an ellipse with center at X, Y and X-RADIUS and Y-RADIUS. 3367 "Draw an ellipse with center at X1, Y1 and X-RADIUS and Y-RADIUS.
3373 3368
3374Output is an ellipse, which is a list (END-POINT-1 END-POINT-2 SHAPE-INFO). 3369Output is an ellipse, which is a list (END-POINT-1 END-POINT-2 SHAPE-INFO).
3375 3370
@@ -3379,15 +3374,15 @@ SHAPE-INFO is a two-element vector on the form [POINT-LIST FILL-INFO].
3379POINT-LIST is a list of vectors on the form [X Y SAVED-CHAR NEW-CHAR]. 3374POINT-LIST is a list of vectors on the form [X Y SAVED-CHAR NEW-CHAR].
3380FILL-INFO is a list of vectors on the form [X Y ELLIPSE-WIDTH-ON-THIS-LINE]. 3375FILL-INFO is a list of vectors on the form [X Y ELLIPSE-WIDTH-ON-THIS-LINE].
3381 3376
3382Ellipses with zero y-radius are not drawn correctly." 3377Ellipses with zero Y-RADIUS are not drawn correctly."
3383 (let* ((point-list (artist-ellipse-generate-quadrant x-radius y-radius)) 3378 (let* ((point-list (artist-ellipse-generate-quadrant x-radius y-radius))
3384 (fill-info (artist-ellipse-compute-fill-info point-list)) 3379 (fill-info (artist-ellipse-compute-fill-info point-list))
3385 (shape-info (make-vector 2 0))) 3380 (shape-info (make-vector 2 0)))
3386 3381
3387 (setq point-list (artist-calculate-new-chars point-list)) 3382 (setq point-list (artist-calculate-new-chars point-list))
3388 (setq point-list (artist-ellipse-mirror-quadrant point-list)) 3383 (setq point-list (artist-ellipse-mirror-quadrant point-list))
3389 (setq point-list (artist-ellipse-point-list-add-center x y point-list)) 3384 (setq point-list (artist-ellipse-point-list-add-center x1 y1 point-list))
3390 (setq fill-info (artist-ellipse-fill-info-add-center x y fill-info)) 3385 (setq fill-info (artist-ellipse-fill-info-add-center x1 y1 fill-info))
3391 3386
3392 ;; Draw the ellipse 3387 ;; Draw the ellipse
3393 (setq point-list 3388 (setq point-list
@@ -3404,12 +3399,12 @@ Ellipses with zero y-radius are not drawn correctly."
3404 3399
3405 (aset shape-info 0 point-list) 3400 (aset shape-info 0 point-list)
3406 (aset shape-info 1 fill-info) 3401 (aset shape-info 1 fill-info)
3407 (artist-make-2point-object (artist-make-endpoint x y) 3402 (artist-make-2point-object (artist-make-endpoint x1 y1)
3408 (artist-make-endpoint x-radius y-radius) 3403 (artist-make-endpoint x-radius y-radius)
3409 shape-info))) 3404 shape-info)))
3410 3405
3411(defun artist-draw-ellipse-with-0-height (x y x-radius y-radius) 3406(defun artist-draw-ellipse-with-0-height (x1 y1 x-radius y-radius)
3412 "Draw an ellipse with center at X, Y and X-RADIUS and Y-RADIUS. 3407 "Draw an ellipse with center at X1, Y1 and X-RADIUS and Y-RADIUS.
3413 3408
3414Output is an ellipse, which is a list (END-POINT-1 END-POINT-2 SHAPE-INFO). 3409Output is an ellipse, which is a list (END-POINT-1 END-POINT-2 SHAPE-INFO).
3415 3410
@@ -3419,10 +3414,10 @@ SHAPE-INFO is a two-element vector on the form [POINT-LIST FILL-INFO].
3419POINT-LIST is a list of vectors on the form [X Y SAVED-CHAR NEW-CHAR]. 3414POINT-LIST is a list of vectors on the form [X Y SAVED-CHAR NEW-CHAR].
3420FILL-INFO is a list of vectors on the form [X Y ELLIPSE-WIDTH-ON-THIS-LINE]. 3415FILL-INFO is a list of vectors on the form [X Y ELLIPSE-WIDTH-ON-THIS-LINE].
3421 3416
3422The Y-RADIUS must be 0, but the X-RADUIS must not be 0." 3417The Y-RADIUS must be 0, but the X-RADIUS must not be 0."
3423 (let ((point-list nil) 3418 (let ((point-list nil)
3424 (width (max (- (abs (* 2 x-radius)) 1))) 3419 (width (max (- (abs (* 2 x-radius)) 1)))
3425 (left-edge (1+ (- x (abs x-radius)))) 3420 (left-edge (1+ (- x1 (abs x-radius))))
3426 (line-char (if artist-line-char-set artist-line-char ?-)) 3421 (line-char (if artist-line-char-set artist-line-char ?-))
3427 (i 0) 3422 (i 0)
3428 (point-list nil) 3423 (point-list nil)
@@ -3430,7 +3425,7 @@ The Y-RADIUS must be 0, but the X-RADUIS must not be 0."
3430 (shape-info (make-vector 2 0))) 3425 (shape-info (make-vector 2 0)))
3431 (while (< i width) 3426 (while (< i width)
3432 (let* ((line-x (+ left-edge i)) 3427 (let* ((line-x (+ left-edge i))
3433 (line-y y) 3428 (line-y y1)
3434 (new-coord (artist-new-coord line-x line-y))) 3429 (new-coord (artist-new-coord line-x line-y)))
3435 (artist-coord-add-saved-char new-coord 3430 (artist-coord-add-saved-char new-coord
3436 (artist-get-char-at-xy line-x line-y)) 3431 (artist-get-char-at-xy line-x line-y))
@@ -3440,7 +3435,7 @@ The Y-RADIUS must be 0, but the X-RADUIS must not be 0."
3440 (setq i (1+ i)))) 3435 (setq i (1+ i))))
3441 (aset shape-info 0 point-list) 3436 (aset shape-info 0 point-list)
3442 (aset shape-info 1 fill-info) 3437 (aset shape-info 1 fill-info)
3443 (artist-make-2point-object (artist-make-endpoint x y) 3438 (artist-make-2point-object (artist-make-endpoint x1 y1)
3444 (artist-make-endpoint x-radius y-radius) 3439 (artist-make-endpoint x-radius y-radius)
3445 shape-info))) 3440 shape-info)))
3446 3441
@@ -3954,7 +3949,7 @@ The 2-point shape SHAPE is drawn from X1, Y1 to X2, Y2."
3954 3949
3955(defun artist-draw-region-trim-line-endings (min-y max-y) 3950(defun artist-draw-region-trim-line-endings (min-y max-y)
3956 "Trim lines in current draw-region from MIN-Y to MAX-Y. 3951 "Trim lines in current draw-region from MIN-Y to MAX-Y.
3957Trimming here means removing white space at end of a line" 3952Trimming here means removing white space at end of a line."
3958 ;; Safetyc check: switch min-y and max-y if if max-y is smaller 3953 ;; Safetyc check: switch min-y and max-y if if max-y is smaller
3959 (if (< max-y min-y) 3954 (if (< max-y min-y)
3960 (let ((tmp min-y)) 3955 (let ((tmp min-y))
@@ -4286,7 +4281,7 @@ If optional argument THIS-IS-LAST-POINT is non-nil, this point is the last."
4286 4281
4287(defun artist-key-set-point-common (arg) 4282(defun artist-key-set-point-common (arg)
4288 "Common routine for setting point in current shape. 4283 "Common routine for setting point in current shape.
4289With ARG set to t, set the last point." 4284With non-nil ARG, set the last point."
4290 (let ((draw-how (artist-go-get-draw-how-from-symbol artist-curr-go)) 4285 (let ((draw-how (artist-go-get-draw-how-from-symbol artist-curr-go))
4291 (col (artist-current-column)) 4286 (col (artist-current-column))
4292 (row (artist-current-line)) 4287 (row (artist-current-line))
@@ -4793,7 +4788,7 @@ If optional argument STATE is positive, turn borders on."
4793 4788
4794 4789
4795(defun artist-mouse-choose-operation (ev op) 4790(defun artist-mouse-choose-operation (ev op)
4796 "Choose operation for evenvt EV and operation OP." 4791 "Choose operation for event EV and operation OP."
4797 (interactive 4792 (interactive
4798 (progn 4793 (progn
4799 (select-window (posn-window (event-start last-input-event))) 4794 (select-window (posn-window (event-start last-input-event)))
diff --git a/lisp/textmodes/bibtex.el b/lisp/textmodes/bibtex.el
index 82b15cf4eb5..15348205c51 100644
--- a/lisp/textmodes/bibtex.el
+++ b/lisp/textmodes/bibtex.el
@@ -1,6 +1,7 @@
1;;; bibtex.el --- BibTeX mode for GNU Emacs 1;;; bibtex.el --- BibTeX mode for GNU Emacs
2 2
3;; Copyright (C) 1992,94,95,96,97,98,1999,2003 Free Software Foundation, Inc. 3;; Copyright (C) 1992,94,95,96,97,98,1999,2003,2004
4;; Free Software Foundation, Inc.
4 5
5;; Author: Stefan Schoef <schoef@offis.uni-oldenburg.de> 6;; Author: Stefan Schoef <schoef@offis.uni-oldenburg.de>
6;; Bengt Martensson <bengt@mathematik.uni-Bremen.de> 7;; Bengt Martensson <bengt@mathematik.uni-Bremen.de>
@@ -811,6 +812,7 @@ If non-nil, the column for the equal sign is the value of
811 (define-key km "\C-c\M-y" 'bibtex-yank-pop) 812 (define-key km "\C-c\M-y" 'bibtex-yank-pop)
812 (define-key km "\C-c\C-d" 'bibtex-empty-field) 813 (define-key km "\C-c\C-d" 'bibtex-empty-field)
813 (define-key km "\C-c\C-f" 'bibtex-make-field) 814 (define-key km "\C-c\C-f" 'bibtex-make-field)
815 (define-key km "\C-c\C-u" 'bibtex-entry-update)
814 (define-key km "\C-c$" 'bibtex-ispell-abstract) 816 (define-key km "\C-c$" 'bibtex-ispell-abstract)
815 (define-key km "\M-\C-a" 'bibtex-beginning-of-entry) 817 (define-key km "\M-\C-a" 'bibtex-beginning-of-entry)
816 (define-key km "\M-\C-e" 'bibtex-end-of-entry) 818 (define-key km "\M-\C-e" 'bibtex-end-of-entry)
@@ -1122,44 +1124,6 @@ function `bibtex-parse-field-name'.")
1122 '(bibtex-mode "@\\S(*\\s(" "\\s)" nil bibtex-hs-forward-sexp nil)) 1124 '(bibtex-mode "@\\S(*\\s(" "\\s)" nil bibtex-hs-forward-sexp nil))
1123 1125
1124 1126
1125(defconst bibtex-braced-string-syntax-table
1126 (let ((st (make-syntax-table)))
1127 (modify-syntax-entry ?\{ "(}" st)
1128 (modify-syntax-entry ?\} "){" st)
1129 (modify-syntax-entry ?\[ "." st)
1130 (modify-syntax-entry ?\] "." st)
1131 (modify-syntax-entry ?\( "." st)
1132 (modify-syntax-entry ?\) "." st)
1133 (modify-syntax-entry ?\\ "." st)
1134 (modify-syntax-entry ?\" "." st)
1135 st)
1136 "Syntax-table to parse matched braces.")
1137
1138(defconst bibtex-quoted-string-syntax-table
1139 (let ((st (make-syntax-table)))
1140 (modify-syntax-entry ?\\ "\\" st)
1141 (modify-syntax-entry ?\" "\"" st)
1142 st)
1143 "Syntax-table to parse matched quotes.")
1144
1145(defun bibtex-parse-field-string ()
1146 "Parse a field string enclosed by braces or quotes.
1147If a syntactically correct string is found, a pair containing the start and
1148end position of the field string is returned, nil otherwise."
1149 (let ((end-point
1150 (or (and (eq (following-char) ?\")
1151 (save-excursion
1152 (with-syntax-table bibtex-quoted-string-syntax-table
1153 (forward-sexp 1))
1154 (point)))
1155 (and (eq (following-char) ?\{)
1156 (save-excursion
1157 (with-syntax-table bibtex-braced-string-syntax-table
1158 (forward-sexp 1))
1159 (point))))))
1160 (if end-point
1161 (cons (point) end-point))))
1162
1163(defun bibtex-parse-association (parse-lhs parse-rhs) 1127(defun bibtex-parse-association (parse-lhs parse-rhs)
1164 "Parse a string of the format <left-hand-side = right-hand-side>. 1128 "Parse a string of the format <left-hand-side = right-hand-side>.
1165The functions PARSE-LHS and PARSE-RHS are used to parse the corresponding 1129The functions PARSE-LHS and PARSE-RHS are used to parse the corresponding
@@ -1199,6 +1163,44 @@ BibTeX field as necessary."
1199 ;; Now try again. 1163 ;; Now try again.
1200 (bibtex-parse-field-name)))) 1164 (bibtex-parse-field-name))))
1201 1165
1166(defconst bibtex-braced-string-syntax-table
1167 (let ((st (make-syntax-table)))
1168 (modify-syntax-entry ?\{ "(}" st)
1169 (modify-syntax-entry ?\} "){" st)
1170 (modify-syntax-entry ?\[ "." st)
1171 (modify-syntax-entry ?\] "." st)
1172 (modify-syntax-entry ?\( "." st)
1173 (modify-syntax-entry ?\) "." st)
1174 (modify-syntax-entry ?\\ "." st)
1175 (modify-syntax-entry ?\" "." st)
1176 st)
1177 "Syntax-table to parse matched braces.")
1178
1179(defconst bibtex-quoted-string-syntax-table
1180 (let ((st (make-syntax-table)))
1181 (modify-syntax-entry ?\\ "\\" st)
1182 (modify-syntax-entry ?\" "\"" st)
1183 st)
1184 "Syntax-table to parse matched quotes.")
1185
1186(defun bibtex-parse-field-string ()
1187 "Parse a field string enclosed by braces or quotes.
1188If a syntactically correct string is found, a pair containing the start and
1189end position of the field string is returned, nil otherwise."
1190 (let ((end-point
1191 (or (and (eq (following-char) ?\")
1192 (save-excursion
1193 (with-syntax-table bibtex-quoted-string-syntax-table
1194 (forward-sexp 1))
1195 (point)))
1196 (and (eq (following-char) ?\{)
1197 (save-excursion
1198 (with-syntax-table bibtex-braced-string-syntax-table
1199 (forward-sexp 1))
1200 (point))))))
1201 (if end-point
1202 (cons (point) end-point))))
1203
1202(defun bibtex-parse-field-text () 1204(defun bibtex-parse-field-text ()
1203 "Parse the text part of a BibTeX field. 1205 "Parse the text part of a BibTeX field.
1204The text part is either a string, or an empty string, or a constant followed 1206The text part is either a string, or an empty string, or a constant followed
@@ -1410,7 +1412,7 @@ delimiters if present."
1410 (let ((content (buffer-substring-no-properties (nth 0 (cdr bounds)) 1412 (let ((content (buffer-substring-no-properties (nth 0 (cdr bounds))
1411 (nth 1 (cdr bounds))))) 1413 (nth 1 (cdr bounds)))))
1412 (if (and remove-delim 1414 (if (and remove-delim
1413 (string-match "\\`{\\(.*\\)}\\'" content)) 1415 (string-match "\\`[{\"]\\(.*\\)[}\"]\\'" content))
1414 (substring content (match-beginning 1) (match-end 1)) 1416 (substring content (match-beginning 1) (match-end 1))
1415 content))) 1417 content)))
1416 1418
@@ -1455,16 +1457,6 @@ The value is actually the tail of LIST whose car matches STRING."
1455 (setq list (cdr list))) 1457 (setq list (cdr list)))
1456 list)) 1458 list))
1457 1459
1458(defun bibtex-assoc-of-regexp (string alist)
1459 "Return non-nil if STRING is exactly matched by the car of an
1460element of ALIST (case ignored). The value is actually the element
1461of LIST whose car matches STRING."
1462 (let ((case-fold-search t))
1463 (while (and alist
1464 (not (string-match (concat "\\`\\(?:" (caar alist) "\\)\\'") string)))
1465 (setq alist (cdr alist)))
1466 (car alist)))
1467
1468(defun bibtex-skip-to-valid-entry (&optional backward) 1460(defun bibtex-skip-to-valid-entry (&optional backward)
1469 "Unless at beginning of a valid BibTeX entry, move point to beginning of the 1461 "Unless at beginning of a valid BibTeX entry, move point to beginning of the
1470next valid one. With optional argument BACKWARD non-nil, move backward to 1462next valid one. With optional argument BACKWARD non-nil, move backward to
@@ -1510,7 +1502,7 @@ FUN will not be called for @String entries."
1510 (save-excursion 1502 (save-excursion
1511 (if (or (and (not bibtex-sort-ignore-string-entries) 1503 (if (or (and (not bibtex-sort-ignore-string-entries)
1512 (string-equal "string" (downcase entry-type))) 1504 (string-equal "string" (downcase entry-type)))
1513 (assoc-ignore-case entry-type bibtex-entry-field-alist)) 1505 (assoc-string entry-type bibtex-entry-field-alist t))
1514 (funcall fun key beg end))) 1506 (funcall fun key beg end)))
1515 (goto-char end))))) 1507 (goto-char end)))))
1516 1508
@@ -1519,8 +1511,8 @@ FUN will not be called for @String entries."
1519If FLAG is a string, the message is initialized (in this case a 1511If FLAG is a string, the message is initialized (in this case a
1520value for INTERVAL may be given as well (if not this is set to 5)). 1512value for INTERVAL may be given as well (if not this is set to 5)).
1521If FLAG is done, the message is deinitialized. 1513If FLAG is done, the message is deinitialized.
1522If FLAG is absent, a message is echoed if point was incremented 1514If FLAG is nil, a message is echoed if point was incremented at least
1523at least INTERVAL percent since last message was echoed." 1515`bibtex-progress-interval' percent since last message was echoed."
1524 (cond ((stringp flag) 1516 (cond ((stringp flag)
1525 (setq bibtex-progress-lastmes flag) 1517 (setq bibtex-progress-lastmes flag)
1526 (setq bibtex-progress-interval (or interval 5) 1518 (setq bibtex-progress-interval (or interval 5)
@@ -1685,11 +1677,11 @@ are defined, but only for the head part of the entry
1685 "Try to avoid point being at end of a BibTeX field." 1677 "Try to avoid point being at end of a BibTeX field."
1686 (end-of-line) 1678 (end-of-line)
1687 (skip-chars-backward " \t") 1679 (skip-chars-backward " \t")
1688 (cond ((= (preceding-char) ?,) 1680 (if (= (preceding-char) ?,)
1689 (forward-char -2))) 1681 (forward-char -2))
1690 (cond ((or (= (preceding-char) ?}) 1682 (if (or (= (preceding-char) ?})
1691 (= (preceding-char) ?\")) 1683 (= (preceding-char) ?\"))
1692 (forward-char -1)))) 1684 (forward-char -1)))
1693 1685
1694(defun bibtex-enclosing-field (&optional noerr) 1686(defun bibtex-enclosing-field (&optional noerr)
1695 "Search for BibTeX field enclosing point. Point moves to end of field. 1687 "Search for BibTeX field enclosing point. Point moves to end of field.
@@ -1749,6 +1741,15 @@ Beginning (but not end) of entry is given by (`match-beginning' 0)."
1749 (error "Unknown tag field: %s. Please submit a bug report" 1741 (error "Unknown tag field: %s. Please submit a bug report"
1750 bibtex-last-kill-command)))))) 1742 bibtex-last-kill-command))))))
1751 1743
1744(defun bibtex-assoc-regexp (regexp alist)
1745 "Return non-nil if REGEXP matches the car of an element of ALIST.
1746The value is actually the element of ALIST matched by REGEXP.
1747Case is ignored if `case-fold-search' is non-nil in the current buffer."
1748 (while (and alist
1749 (not (string-match regexp (caar alist))))
1750 (setq alist (cdr alist)))
1751 (car alist))
1752
1752(defun bibtex-format-entry () 1753(defun bibtex-format-entry ()
1753 "Helper function for `bibtex-clean-entry'. 1754 "Helper function for `bibtex-clean-entry'.
1754Formats current entry according to variable `bibtex-entry-format'." 1755Formats current entry according to variable `bibtex-entry-format'."
@@ -1763,18 +1764,17 @@ Formats current entry according to variable `bibtex-entry-format'."
1763 unify-case inherit-booktitle) 1764 unify-case inherit-booktitle)
1764 bibtex-entry-format)) 1765 bibtex-entry-format))
1765 crossref-key bounds alternatives-there non-empty-alternative 1766 crossref-key bounds alternatives-there non-empty-alternative
1766 entry-list req creq field-done field-list) 1767 entry-list req-field-list field-done field-list)
1767 1768
1768 ;; identify entry type 1769 ;; identify entry type
1769 (goto-char (point-min)) 1770 (goto-char (point-min))
1770 (re-search-forward bibtex-entry-type) 1771 (re-search-forward bibtex-entry-type)
1771 (let ((beg-type (1+ (match-beginning 0))) 1772 (let ((beg-type (1+ (match-beginning 0)))
1772 (end-type (match-end 0))) 1773 (end-type (match-end 0)))
1773 (setq entry-list (assoc-ignore-case (buffer-substring-no-properties 1774 (setq entry-list (assoc-string (buffer-substring-no-properties
1774 beg-type end-type) 1775 beg-type end-type)
1775 bibtex-entry-field-alist) 1776 bibtex-entry-field-alist
1776 req (nth 0 (nth 1 entry-list)) ; required part 1777 t))
1777 creq (nth 0 (nth 2 entry-list))) ; crossref part
1778 1778
1779 ;; unify case of entry name 1779 ;; unify case of entry name
1780 (when (memq 'unify-case format) 1780 (when (memq 'unify-case format)
@@ -1791,20 +1791,32 @@ Formats current entry according to variable `bibtex-entry-format'."
1791 ;; determine if entry has crossref field and if at least 1791 ;; determine if entry has crossref field and if at least
1792 ;; one alternative is non-empty 1792 ;; one alternative is non-empty
1793 (goto-char (point-min)) 1793 (goto-char (point-min))
1794 (while (setq bounds (bibtex-search-forward-field 1794 (let* ((fields-alist (bibtex-parse-entry))
1795 bibtex-field-name)) 1795 (case-fold-search t)
1796 (goto-char (bibtex-start-of-name-in-field bounds)) 1796 (field (bibtex-assoc-regexp "\\`\\(OPT\\)?crossref\\'"
1797 (cond ((looking-at "ALT") 1797 fields-alist)))
1798 (setq alternatives-there t) 1798 (setq crossref-key (and field
1799 (goto-char (bibtex-start-of-text-in-field bounds)) 1799 (not (string-match bibtex-empty-field-re
1800 (if (not (looking-at bibtex-empty-field-re)) 1800 (cdr field)))
1801 (setq non-empty-alternative t))) 1801 (cdr field))
1802 ((and (looking-at "\\(OPT\\)?crossref\\>") 1802 req-field-list (if crossref-key
1803 (progn (goto-char (bibtex-start-of-text-in-field bounds)) 1803 (nth 0 (nth 2 entry-list)) ; crossref part
1804 (not (looking-at bibtex-empty-field-re)))) 1804 (nth 0 (nth 1 entry-list)))) ; required part
1805 (setq crossref-key 1805
1806 (bibtex-text-in-field-bounds bounds t)))) 1806 (dolist (rfield req-field-list)
1807 (goto-char (bibtex-end-of-field bounds))) 1807 (when (nth 3 rfield) ; we should have an alternative
1808 (setq alternatives-there t
1809 field (bibtex-assoc-regexp
1810 (concat "\\`\\(ALT\\)?" (car rfield) "\\'")
1811 fields-alist))
1812 (if (and field
1813 (not (string-match bibtex-empty-field-re
1814 (cdr field))))
1815 (cond ((not non-empty-alternative)
1816 (setq non-empty-alternative t))
1817 ((memq 'required-fields format)
1818 (error "More than one non-empty alternative.")))))))
1819
1808 (if (and alternatives-there 1820 (if (and alternatives-there
1809 (not non-empty-alternative) 1821 (not non-empty-alternative)
1810 (memq 'required-fields format)) 1822 (memq 'required-fields format))
@@ -1832,18 +1844,23 @@ Formats current entry according to variable `bibtex-entry-format'."
1832 ;; quite some redundancy compared with what we need to do 1844 ;; quite some redundancy compared with what we need to do
1833 ;; anyway. So for speed-up we avoid using them. 1845 ;; anyway. So for speed-up we avoid using them.
1834 1846
1835 (when (and opt-alt 1847 (if (memq 'opts-or-alts format)
1836 (memq 'opts-or-alts format)) 1848 (cond ((and empty-field
1837 (if empty-field 1849 (or opt-alt
1838 ;; Either it is an empty ALT field. Then we have checked 1850 (let ((field (assoc-string
1839 ;; already that we have one non-empty alternative. 1851 field-name req-field-list t)))
1840 ;; Or it is an empty OPT field that we do not miss anyway. 1852 (or (not field) ; OPT field
1841 ;; So we can safely delete this field. 1853 (nth 3 field))))) ; ALT field
1842 (progn (delete-region beg-field end-field) 1854 ;; Either it is an empty ALT field. Then we have checked
1843 (setq deleted t)) 1855 ;; already that we have one non-empty alternative. Or it
1844 ;; otherwise: not empty, delete "OPT" or "ALT" 1856 ;; is an empty OPT field that we do not miss anyway.
1845 (goto-char beg-name) 1857 ;; So we can safely delete this field.
1846 (delete-char 3))) 1858 (delete-region beg-field end-field)
1859 (setq deleted t))
1860 ;; otherwise: not empty, delete "OPT" or "ALT"
1861 (opt-alt
1862 (goto-char beg-name)
1863 (delete-char 3))))
1847 1864
1848 (unless deleted 1865 (unless deleted
1849 (push field-name field-list) 1866 (push field-name field-list)
@@ -1902,16 +1919,17 @@ Formats current entry according to variable `bibtex-entry-format'."
1902 ;; if empty field, complain 1919 ;; if empty field, complain
1903 (if (and empty-field 1920 (if (and empty-field
1904 (memq 'required-fields format) 1921 (memq 'required-fields format)
1905 (assoc-ignore-case field-name 1922 (assoc-string field-name req-field-list t))
1906 (if crossref-key creq req)))
1907 (error "Mandatory field `%s' is empty" field-name)) 1923 (error "Mandatory field `%s' is empty" field-name))
1908 1924
1909 ;; unify case of field name 1925 ;; unify case of field name
1910 (if (memq 'unify-case format) 1926 (if (memq 'unify-case format)
1911 (let ((fname (car (assoc-ignore-case 1927 (let ((fname (car (assoc-string
1912 field-name (append (nth 0 (nth 1 entry-list)) 1928 field-name
1913 (nth 1 (nth 1 entry-list)) 1929 (append (nth 0 (nth 1 entry-list))
1914 bibtex-user-optional-fields))))) 1930 (nth 1 (nth 1 entry-list))
1931 bibtex-user-optional-fields)
1932 t))))
1915 (if fname 1933 (if fname
1916 (progn 1934 (progn
1917 (delete-region beg-name end-name) 1935 (delete-region beg-name end-name)
@@ -1925,8 +1943,8 @@ Formats current entry according to variable `bibtex-entry-format'."
1925 1943
1926 ;; check whether all required fields are present 1944 ;; check whether all required fields are present
1927 (if (memq 'required-fields format) 1945 (if (memq 'required-fields format)
1928 (let (altlist (found 0)) 1946 (let ((found 0) altlist)
1929 (dolist (fname (if crossref-key creq req)) 1947 (dolist (fname req-field-list)
1930 (if (nth 3 fname) 1948 (if (nth 3 fname)
1931 (push (car fname) altlist)) 1949 (push (car fname) altlist))
1932 (unless (or (member (car fname) field-list) 1950 (unless (or (member (car fname) field-list)
@@ -1940,7 +1958,7 @@ Formats current entry according to variable `bibtex-entry-format'."
1940 (error "Alternative mandatory field `%s' is missing" 1958 (error "Alternative mandatory field `%s' is missing"
1941 altlist)) 1959 altlist))
1942 ((> found 1) 1960 ((> found 1)
1943 (error "Alternative fields `%s' is defined %s times" 1961 (error "Alternative fields `%s' are defined %s times"
1944 altlist found)))))) 1962 altlist found))))))
1945 1963
1946 ;; update point 1964 ;; update point
@@ -2051,8 +2069,8 @@ and return results as a list."
2051 (setq titlestring (substring titlestring 0 (match-beginning 0)))))) 2069 (setq titlestring (substring titlestring 0 (match-beginning 0))))))
2052 ;; gather words from titlestring into a list. Ignore 2070 ;; gather words from titlestring into a list. Ignore
2053 ;; specific words and use only a specific amount of words. 2071 ;; specific words and use only a specific amount of words.
2054 (let (case-fold-search titlewords titlewords-extra titleword end-match 2072 (let ((counter 0)
2055 (counter 0)) 2073 case-fold-search titlewords titlewords-extra titleword end-match)
2056 (while (and (or (not (numberp bibtex-autokey-titlewords)) 2074 (while (and (or (not (numberp bibtex-autokey-titlewords))
2057 (< counter (+ bibtex-autokey-titlewords 2075 (< counter (+ bibtex-autokey-titlewords
2058 bibtex-autokey-titlewords-stretch))) 2076 bibtex-autokey-titlewords-stretch)))
@@ -2079,10 +2097,14 @@ and return results as a list."
2079 "Do some abbreviations on TITLEWORD. 2097 "Do some abbreviations on TITLEWORD.
2080The rules are defined in `bibtex-autokey-titleword-abbrevs' 2098The rules are defined in `bibtex-autokey-titleword-abbrevs'
2081and `bibtex-autokey-titleword-length'." 2099and `bibtex-autokey-titleword-length'."
2082 (let ((abbrev (bibtex-assoc-of-regexp 2100 (let ((case-folde-search t)
2083 titleword bibtex-autokey-titleword-abbrevs))) 2101 (alist bibtex-autokey-titleword-abbrevs))
2084 (if abbrev 2102 (while (and alist
2085 (cdr abbrev) 2103 (not (string-match (concat "\\`\\(?:" (caar alist) "\\)\\'")
2104 titleword)))
2105 (setq alist (cdr alist)))
2106 (if alist
2107 (cdar alist)
2086 (bibtex-autokey-abbrev titleword 2108 (bibtex-autokey-abbrev titleword
2087 bibtex-autokey-titleword-length)))) 2109 bibtex-autokey-titleword-length))))
2088 2110
@@ -2239,8 +2261,8 @@ Return alist of keys if parsing was completed, `aborted' otherwise."
2239 ;; This is a crossref. 2261 ;; This is a crossref.
2240 (buffer-substring-no-properties 2262 (buffer-substring-no-properties
2241 (1+ (match-beginning 3)) (1- (match-end 3)))) 2263 (1+ (match-beginning 3)) (1- (match-end 3))))
2242 ((assoc-ignore-case (bibtex-type-in-head) 2264 ((assoc-string (bibtex-type-in-head)
2243 bibtex-entry-field-alist) 2265 bibtex-entry-field-alist t)
2244 ;; This is an entry. 2266 ;; This is an entry.
2245 (match-string-no-properties bibtex-key-in-head))))) 2267 (match-string-no-properties bibtex-key-in-head)))))
2246 (if (and (stringp key) 2268 (if (and (stringp key)
@@ -2295,7 +2317,7 @@ Return alist of strings if parsing was completed, `aborted' otherwise."
2295 ;; user has aborted by typing a key --> return `aborted' 2317 ;; user has aborted by typing a key --> return `aborted'
2296 (throw 'userkey 'aborted)) 2318 (throw 'userkey 'aborted))
2297 (setq key (bibtex-reference-key-in-string bounds)) 2319 (setq key (bibtex-reference-key-in-string bounds))
2298 (if (not (assoc-ignore-case key strings)) 2320 (if (not (assoc key strings))
2299 (push (cons key (bibtex-text-in-string bounds t)) 2321 (push (cons key (bibtex-text-in-string bounds t))
2300 strings)) 2322 strings))
2301 (goto-char (bibtex-end-of-text-in-string bounds))) 2323 (goto-char (bibtex-end-of-text-in-string bounds)))
@@ -2384,6 +2406,7 @@ of a word, all strings are listed. Return completion."
2384 (display-completion-list (all-completions part-of-word 2406 (display-completion-list (all-completions part-of-word
2385 completions))) 2407 completions)))
2386 (message "Making completion list...done") 2408 (message "Making completion list...done")
2409 ;; return value is handled by choose-completion-string-functions
2387 nil)))) 2410 nil))))
2388 2411
2389(defun bibtex-complete-string-cleanup (str) 2412(defun bibtex-complete-string-cleanup (str)
@@ -2629,6 +2652,34 @@ non-nil.
2629 (easy-menu-add bibtex-entry-menu) 2652 (easy-menu-add bibtex-entry-menu)
2630 (run-hooks 'bibtex-mode-hook)) 2653 (run-hooks 'bibtex-mode-hook))
2631 2654
2655(defun bibtex-field-list (entry-type)
2656 "Return list of allowed fields for entry ENTRY-TYPE.
2657More specifically, the return value is a cons pair (REQUIRED . OPTIONAL),
2658where REQUIRED and OPTIONAL are lists of the required and optional field
2659names for ENTRY-TYPE according to `bibtex-entry-field-alist'."
2660 (let ((e (assoc-string entry-type bibtex-entry-field-alist t))
2661 required optional)
2662 (unless e
2663 (error "Bibtex entry type %s not defined" entry-type))
2664 (if (and (member-ignore-case entry-type bibtex-include-OPTcrossref)
2665 (nth 2 e))
2666 (setq required (nth 0 (nth 2 e))
2667 optional (nth 1 (nth 2 e)))
2668 (setq required (nth 0 (nth 1 e))
2669 optional (nth 1 (nth 1 e))))
2670 (if bibtex-include-OPTkey
2671 (push (list "key"
2672 "Used for reference key creation if author and editor fields are missing"
2673 (if (or (stringp bibtex-include-OPTkey)
2674 (fboundp bibtex-include-OPTkey))
2675 bibtex-include-OPTkey))
2676 optional))
2677 (if (member-ignore-case entry-type bibtex-include-OPTcrossref)
2678 (push '("crossref" "Reference key of the cross-referenced entry")
2679 optional))
2680 (setq optional (append optional bibtex-user-optional-fields))
2681 (cons required optional)))
2682
2632(defun bibtex-entry (entry-type) 2683(defun bibtex-entry (entry-type)
2633 "Insert a new BibTeX entry. 2684 "Insert a new BibTeX entry.
2634After insertion it calls the functions in `bibtex-add-entry-hook'." 2685After insertion it calls the functions in `bibtex-add-entry-hook'."
@@ -2638,38 +2689,17 @@ After insertion it calls the functions in `bibtex-add-entry-hook'."
2638 bibtex-entry-field-alist 2689 bibtex-entry-field-alist
2639 nil t nil 'bibtex-entry-type-history))) 2690 nil t nil 'bibtex-entry-type-history)))
2640 (list e-t))) 2691 (list e-t)))
2641 (let* (required optional 2692 (let ((key (if bibtex-maintain-sorted-entries
2642 (key (if bibtex-maintain-sorted-entries 2693 (bibtex-read-key (format "%s key: " entry-type))))
2643 (bibtex-read-key (format "%s key: " entry-type)))) 2694 (field-list (bibtex-field-list entry-type)))
2644 (e (assoc-ignore-case entry-type bibtex-entry-field-alist))
2645 (r-n-o (elt e 1))
2646 (c-ref (elt e 2)))
2647 (if (not e)
2648 (error "Bibtex entry type %s not defined" entry-type))
2649 (if (and (member entry-type bibtex-include-OPTcrossref)
2650 c-ref)
2651 (setq required (elt c-ref 0)
2652 optional (elt c-ref 1))
2653 (setq required (elt r-n-o 0)
2654 optional (elt r-n-o 1)))
2655 (unless (bibtex-prepare-new-entry (list key nil entry-type)) 2695 (unless (bibtex-prepare-new-entry (list key nil entry-type))
2656 (error "Entry with key `%s' already exists" key)) 2696 (error "Entry with key `%s' already exists" key))
2657 (indent-to-column bibtex-entry-offset) 2697 (indent-to-column bibtex-entry-offset)
2658 (insert "@" entry-type (bibtex-entry-left-delimiter)) 2698 (insert "@" entry-type (bibtex-entry-left-delimiter))
2659 (if key 2699 (if key (insert key))
2660 (insert key))
2661 (save-excursion 2700 (save-excursion
2662 (mapcar 'bibtex-make-field required) 2701 (mapcar 'bibtex-make-field (car field-list))
2663 (if (member entry-type bibtex-include-OPTcrossref) 2702 (mapcar 'bibtex-make-optional-field (cdr field-list))
2664 (bibtex-make-optional-field '("crossref")))
2665 (if bibtex-include-OPTkey
2666 (if (or (stringp bibtex-include-OPTkey)
2667 (fboundp bibtex-include-OPTkey))
2668 (bibtex-make-optional-field
2669 (list "key" nil bibtex-include-OPTkey))
2670 (bibtex-make-optional-field '("key"))))
2671 (mapcar 'bibtex-make-optional-field optional)
2672 (mapcar 'bibtex-make-optional-field bibtex-user-optional-fields)
2673 (if bibtex-comma-after-last-field 2703 (if bibtex-comma-after-last-field
2674 (insert ",")) 2704 (insert ","))
2675 (insert "\n") 2705 (insert "\n")
@@ -2680,15 +2710,39 @@ After insertion it calls the functions in `bibtex-add-entry-hook'."
2680 (bibtex-autofill-entry)) 2710 (bibtex-autofill-entry))
2681 (run-hooks 'bibtex-add-entry-hook))) 2711 (run-hooks 'bibtex-add-entry-hook)))
2682 2712
2713(defun bibtex-entry-update ()
2714 "Update an existing BibTeX entry.
2715In the BibTeX entry at point, make new fields for those items that may occur
2716according to `bibtex-entry-field-alist', but are not yet present."
2717 (interactive)
2718 (save-excursion
2719 (bibtex-beginning-of-entry)
2720 ;; For inserting new fields, we use the fact that
2721 ;; bibtex-parse-entry moves point to the end of the last field.
2722 (let* ((fields-alist (bibtex-parse-entry))
2723 (field-list (bibtex-field-list
2724 (substring (cdr (assoc "=type=" fields-alist))
2725 1))) ; don't want @
2726 (case-fold-search t))
2727 (dolist (field (car field-list))
2728 (unless (bibtex-assoc-regexp (concat "\\`\\(ALT\\)?" (car field) "\\'")
2729 fields-alist)
2730 (bibtex-make-field field)))
2731 (dolist (field (cdr field-list))
2732 (unless (bibtex-assoc-regexp (concat "\\`\\(OPT\\)?" (car field) "\\'")
2733 fields-alist)
2734 (bibtex-make-optional-field field))))))
2735
2683(defun bibtex-parse-entry () 2736(defun bibtex-parse-entry ()
2684 "Parse entry at point, return an alist. 2737 "Parse entry at point, return an alist.
2685The alist elements have the form (FIELD . TEXT), where FIELD can also be 2738The alist elements have the form (FIELD . TEXT), where FIELD can also be
2686the special strings \"=type=\" and \"=key=\"." 2739the special strings \"=type=\" and \"=key=\". For the FIELD \"=key=\"
2740TEXT may be nil. Move point to the end of the last field."
2687 (let (alist bounds) 2741 (let (alist bounds)
2688 (when (looking-at bibtex-entry-head) 2742 (when (looking-at bibtex-entry-maybe-empty-head)
2689 (push (cons "=type=" (match-string bibtex-type-in-head)) alist) 2743 (push (cons "=type=" (match-string bibtex-type-in-head)) alist)
2690 (push (cons "=key=" (match-string bibtex-key-in-head)) alist) 2744 (push (cons "=key=" (match-string bibtex-key-in-head)) alist)
2691 (goto-char (match-end bibtex-key-in-head)) 2745 (goto-char (match-end 0))
2692 (while (setq bounds (bibtex-parse-field bibtex-field-name)) 2746 (while (setq bounds (bibtex-parse-field bibtex-field-name))
2693 (push (cons (bibtex-name-in-field bounds) 2747 (push (cons (bibtex-name-in-field bounds)
2694 (bibtex-text-in-field-bounds bounds)) 2748 (bibtex-text-in-field-bounds bounds))
@@ -2744,7 +2798,7 @@ the special strings \"=type=\" and \"=key=\"."
2744 (let* ((name (buffer-substring 2798 (let* ((name (buffer-substring
2745 (if (looking-at "ALT\\|OPT") (match-end 0) (point)) 2799 (if (looking-at "ALT\\|OPT") (match-end 0) (point))
2746 (bibtex-end-of-name-in-field bounds))) 2800 (bibtex-end-of-name-in-field bounds)))
2747 (text (assoc-ignore-case name other))) 2801 (text (assoc-string name other t)))
2748 (goto-char (bibtex-start-of-text-in-field bounds)) 2802 (goto-char (bibtex-start-of-text-in-field bounds))
2749 (if (not (and (looking-at bibtex-empty-field-re) text)) 2803 (if (not (and (looking-at bibtex-empty-field-re) text))
2750 (goto-char (bibtex-end-of-field bounds)) 2804 (goto-char (bibtex-end-of-field bounds))
@@ -2774,28 +2828,15 @@ the special strings \"=type=\" and \"=key=\"."
2774 (looking-at "OPT\\|ALT")) 2828 (looking-at "OPT\\|ALT"))
2775 (match-end 0) mb) 2829 (match-end 0) mb)
2776 (bibtex-end-of-name-in-field bounds))) 2830 (bibtex-end-of-name-in-field bounds)))
2777 (entry-type (progn (re-search-backward 2831 (field-list (bibtex-field-list (progn (re-search-backward
2778 bibtex-entry-maybe-empty-head nil t) 2832 bibtex-entry-maybe-empty-head nil t)
2779 (bibtex-type-in-head))) 2833 (bibtex-type-in-head))))
2780 (entry-list (assoc-ignore-case entry-type 2834 (comment (assoc-string field-name
2781 bibtex-entry-field-alist)) 2835 (append (car field-list)
2782 (c-r-list (elt entry-list 2)) 2836 (cdr field-list))
2783 (req-opt-list (if (and (member entry-type 2837 t)))
2784 bibtex-include-OPTcrossref)
2785 c-r-list)
2786 c-r-list
2787 (elt entry-list 1)))
2788 (list-of-entries (append (elt req-opt-list 0)
2789 (elt req-opt-list 1)
2790 bibtex-user-optional-fields
2791 (if (member entry-type
2792 bibtex-include-OPTcrossref)
2793 '(("crossref" "Reference key of the cross-referenced entry")))
2794 (if bibtex-include-OPTkey
2795 '(("key" "Used for reference key creation if author and editor fields are missing")))))
2796 (comment (assoc-ignore-case field-name list-of-entries)))
2797 (if comment 2838 (if comment
2798 (message (elt comment 1)) 2839 (message (nth 1 comment))
2799 (message "No comment available"))))) 2840 (message "No comment available")))))
2800 2841
2801(defun bibtex-make-field (field &optional called-by-yank) 2842(defun bibtex-make-field (field &optional called-by-yank)
@@ -2804,24 +2845,13 @@ FIELD is either a string or a list of the form
2804\(FIELD-NAME COMMENT-STRING INIT ALTERNATIVE-FLAG) as in 2845\(FIELD-NAME COMMENT-STRING INIT ALTERNATIVE-FLAG) as in
2805`bibtex-entry-field-alist'." 2846`bibtex-entry-field-alist'."
2806 (interactive 2847 (interactive
2807 (list (let* ((entry-type 2848 (list (let ((completion-ignore-case t)
2808 (save-excursion 2849 (field-list (bibtex-field-list
2809 (bibtex-enclosing-entry-maybe-empty-head) 2850 (save-excursion
2810 (bibtex-type-in-head))) 2851 (bibtex-enclosing-entry-maybe-empty-head)
2811 ;; "preliminary" completion list 2852 (bibtex-type-in-head)))))
2812 (fl (nth 1 (assoc-ignore-case 2853 (completing-read "BibTeX field name: "
2813 entry-type bibtex-entry-field-alist))) 2854 (append (car field-list) (cdr field-list))
2814 ;; "full" completion list
2815 (field-list (append (nth 0 fl)
2816 (nth 1 fl)
2817 bibtex-user-optional-fields
2818 (if (member entry-type
2819 bibtex-include-OPTcrossref)
2820 '(("crossref")))
2821 (if bibtex-include-OPTkey
2822 '(("key")))))
2823 (completion-ignore-case t))
2824 (completing-read "BibTeX field name: " field-list
2825 nil nil nil bibtex-field-history)))) 2855 nil nil nil bibtex-field-history))))
2826 (unless (consp field) 2856 (unless (consp field)
2827 (setq field (list field))) 2857 (setq field (list field)))
@@ -2848,8 +2878,9 @@ FIELD is either a string or a list of the form
2848 ((fboundp init) 2878 ((fboundp init)
2849 (insert (funcall init))))) 2879 (insert (funcall init)))))
2850 (if (not called-by-yank) (insert (bibtex-field-right-delimiter))) 2880 (if (not called-by-yank) (insert (bibtex-field-right-delimiter)))
2851 (if (interactive-p) 2881 (when (interactive-p)
2852 (forward-char -1))) 2882 (forward-char -1)
2883 (bibtex-print-help-message)))
2853 2884
2854(defun bibtex-beginning-of-entry () 2885(defun bibtex-beginning-of-entry ()
2855 "Move to beginning of BibTeX entry (beginning of line). 2886 "Move to beginning of BibTeX entry (beginning of line).
@@ -2982,13 +3013,14 @@ the entries of the BibTeX buffer. Return nil if no entry found."
2982 "\\(OPT\\)?crossref" t))) 3013 "\\(OPT\\)?crossref" t)))
2983 (list key 3014 (list key
2984 (if bounds (bibtex-text-in-field-bounds bounds t)) 3015 (if bounds (bibtex-text-in-field-bounds bounds t))
2985 entry-name)))) 3016 entry-name)))
2986 (list key nil entry-name))))) 3017 (list key nil entry-name))))))
2987 3018
2988(defun bibtex-lessp (index1 index2) 3019(defun bibtex-lessp (index1 index2)
2989 "Predicate for sorting BibTeX entries with indices INDEX1 and INDEX2. 3020 "Predicate for sorting BibTeX entries with indices INDEX1 and INDEX2.
2990Each index is a list (KEY CROSSREF-KEY ENTRY-NAME). 3021Each index is a list (KEY CROSSREF-KEY ENTRY-NAME).
2991The predicate depends on the variable `bibtex-maintain-sorted-entries'." 3022The predicate depends on the variable `bibtex-maintain-sorted-entries'.
3023If its value is nil use plain sorting."
2992 (cond ((not index1) (not index2)) ; indices can be nil 3024 (cond ((not index1) (not index2)) ; indices can be nil
2993 ((not index2) nil) 3025 ((not index2) nil)
2994 ((equal bibtex-maintain-sorted-entries 'crossref) 3026 ((equal bibtex-maintain-sorted-entries 'crossref)
@@ -3017,12 +3049,10 @@ The predicate depends on the variable `bibtex-maintain-sorted-entries'."
3017(defun bibtex-sort-buffer () 3049(defun bibtex-sort-buffer ()
3018 "Sort BibTeX buffer alphabetically by key. 3050 "Sort BibTeX buffer alphabetically by key.
3019The predicate for sorting is defined via `bibtex-maintain-sorted-entries'. 3051The predicate for sorting is defined via `bibtex-maintain-sorted-entries'.
3020Text outside of BibTeX entries is not affected. If 3052If its value is nil use plain sorting. Text outside of BibTeX entries is not
3021`bibtex-sort-ignore-string-entries' is non-nil, @String entries will be 3053affected. If `bibtex-sort-ignore-string-entries' is non-nil, @String entries
3022ignored." 3054will be ignored."
3023 (interactive) 3055 (interactive)
3024 (unless bibtex-maintain-sorted-entries
3025 (error "You must choose a sorting scheme"))
3026 (save-restriction 3056 (save-restriction
3027 (narrow-to-region (bibtex-beginning-of-first-entry) 3057 (narrow-to-region (bibtex-beginning-of-first-entry)
3028 (save-excursion (goto-char (point-max)) 3058 (save-excursion (goto-char (point-max))
@@ -3212,8 +3242,8 @@ Returns t if test was successful, nil otherwise."
3212 (let* ((entry-list (progn 3242 (let* ((entry-list (progn
3213 (goto-char beg) 3243 (goto-char beg)
3214 (bibtex-search-entry nil end) 3244 (bibtex-search-entry nil end)
3215 (assoc-ignore-case (bibtex-type-in-head) 3245 (assoc-string (bibtex-type-in-head)
3216 bibtex-entry-field-alist))) 3246 bibtex-entry-field-alist t)))
3217 (req (copy-sequence (elt (elt entry-list 1) 0))) 3247 (req (copy-sequence (elt (elt entry-list 1) 0)))
3218 (creq (copy-sequence (elt (elt entry-list 2) 0))) 3248 (creq (copy-sequence (elt (elt entry-list 2) 0)))
3219 crossref-there bounds) 3249 crossref-there bounds)
@@ -3229,8 +3259,8 @@ Returns t if test was successful, nil otherwise."
3229 (push (list (bibtex-current-line) 3259 (push (list (bibtex-current-line)
3230 "Questionable month field") 3260 "Questionable month field")
3231 error-list)) 3261 error-list))
3232 (setq req (delete (assoc-ignore-case field-name req) req) 3262 (setq req (delete (assoc-string field-name req t) req)
3233 creq (delete (assoc-ignore-case field-name creq) creq)) 3263 creq (delete (assoc-string field-name creq t) creq))
3234 (if (equal field-name "crossref") 3264 (if (equal field-name "crossref")
3235 (setq crossref-there t)))) 3265 (setq crossref-there t))))
3236 (if crossref-there 3266 (if crossref-there
@@ -3523,27 +3553,30 @@ At end of the cleaning process, the functions in
3523 (match-end bibtex-key-in-head))) 3553 (match-end bibtex-key-in-head)))
3524 (insert key)) 3554 (insert key))
3525 ;; sorting 3555 ;; sorting
3526 (let* ((start (bibtex-beginning-of-entry)) 3556 (unless called-by-reformat
3527 (end (progn (bibtex-end-of-entry) 3557 (let* ((start (bibtex-beginning-of-entry))
3528 (if (re-search-forward 3558 (end (progn (bibtex-end-of-entry)
3529 bibtex-entry-maybe-empty-head nil 'move) 3559 (if (re-search-forward
3530 (goto-char (match-beginning 0))) 3560 bibtex-entry-maybe-empty-head nil 'move)
3531 (point))) 3561 (goto-char (match-beginning 0)))
3532 (entry (buffer-substring start end)) 3562 (point)))
3533 (index (progn (goto-char start) 3563 (entry (buffer-substring start end))
3534 (bibtex-entry-index)))) 3564 (index (progn (goto-char start)
3535 (delete-region start end) 3565 (bibtex-entry-index)))
3536 (unless (prog1 (or called-by-reformat 3566 no-error)
3537 (if (and bibtex-maintain-sorted-entries 3567 (if (and bibtex-maintain-sorted-entries
3538 (not (and bibtex-sort-ignore-string-entries 3568 (not (and bibtex-sort-ignore-string-entries
3539 (equal entry-type "string")))) 3569 (equal entry-type "string"))))
3540 (bibtex-prepare-new-entry index) 3570 (progn
3541 (not (bibtex-find-entry (car index))))) 3571 (delete-region start end)
3542 (insert entry) 3572 (setq no-error (bibtex-prepare-new-entry index))
3543 (forward-char -1) 3573 (insert entry)
3544 (bibtex-beginning-of-entry) ; moves backward 3574 (forward-char -1)
3545 (re-search-forward bibtex-entry-head)) 3575 (bibtex-beginning-of-entry) ; moves backward
3546 (error "New inserted entry yields duplicate key"))) 3576 (re-search-forward bibtex-entry-head))
3577 (setq no-error (bibtex-find-entry (car index))))
3578 (unless no-error
3579 (error "New inserted entry yields duplicate key"))))
3547 ;; final clean up 3580 ;; final clean up
3548 (unless called-by-reformat 3581 (unless called-by-reformat
3549 (save-excursion 3582 (save-excursion
@@ -3621,91 +3654,89 @@ If `bibtex-align-at-equal-sign' is non-nil, align equal signs, too."
3621 (indent-to-column bibtex-entry-offset) 3654 (indent-to-column bibtex-entry-offset)
3622 (goto-char pnt))) 3655 (goto-char pnt)))
3623 3656
3624(defun bibtex-reformat (&optional additional-options called-by-convert-alien) 3657(defun bibtex-realign ()
3658 "Realign BibTeX entries such that they are separated by one blank line."
3659 (goto-char (point-min))
3660 (let ((case-fold-search t))
3661 (when (looking-at bibtex-valid-entry-whitespace-re)
3662 (replace-match "\\1"))
3663 (while (re-search-forward bibtex-valid-entry-whitespace-re nil t)
3664 (replace-match "\n\n\\1"))))
3665
3666(defun bibtex-reformat (&optional read-options)
3625 "Reformat all BibTeX entries in buffer or region. 3667 "Reformat all BibTeX entries in buffer or region.
3626With prefix argument, read options for reformatting from minibuffer. 3668With prefix argument, read options for reformatting from minibuffer.
3627With \\[universal-argument] \\[universal-argument] prefix argument, reuse previous answers (if any) again. 3669With \\[universal-argument] \\[universal-argument] prefix argument, reuse previous answers (if any) again.
3628If mark is active it reformats entries in region, if not in whole buffer." 3670If mark is active reformat entries in region, if not in whole buffer."
3629 (interactive "*P") 3671 (interactive "*P")
3630 (let* ((pnt (point)) 3672 (let* ((pnt (point))
3631 (use-previous-options 3673 (use-previous-options
3632 (and (equal (prefix-numeric-value additional-options) 16) 3674 (and (equal (prefix-numeric-value read-options) 16)
3633 (or bibtex-reformat-previous-options 3675 (or bibtex-reformat-previous-options
3634 bibtex-reformat-previous-reference-keys))) 3676 bibtex-reformat-previous-reference-keys)))
3635 (bibtex-entry-format 3677 (bibtex-entry-format
3636 (if additional-options 3678 (if read-options
3637 (if use-previous-options 3679 (if use-previous-options
3638 bibtex-reformat-previous-options 3680 bibtex-reformat-previous-options
3639 (setq bibtex-reformat-previous-options 3681 (setq bibtex-reformat-previous-options
3640 (delq nil (list 3682 (mapcar (lambda (option)
3641 (if (or called-by-convert-alien 3683 (if (y-or-n-p (car option)) (cdr option)))
3642 (y-or-n-p "Realign entries (recommended)? ")) 3684 `(("Realign entries (recommended)? " . 'realign)
3643 'realign) 3685 ("Remove empty optional and alternative fields? " . 'opts-or-alts)
3644 (if (y-or-n-p "Remove empty optional and alternative fields? ") 3686 ("Remove delimiters around pure numerical fields? " . 'numerical-fields)
3645 'opts-or-alts) 3687 (,(concat (if bibtex-comma-after-last-field "Insert" "Remove")
3646 (if (y-or-n-p "Remove delimiters around pure numerical fields? ") 3688 " comma at end of entry? ") . 'last-comma)
3647 'numerical-fields) 3689 ("Replace double page dashes by single ones? " . 'page-dashes)
3648 (if (y-or-n-p (concat (if bibtex-comma-after-last-field "Insert" "Remove") 3690 ("Force delimiters? " . 'delimiters)
3649 " comma at end of entry? ")) 3691 ("Unify case of entry types and field names? " . 'unify-case)))))
3650 'last-comma)
3651 (if (y-or-n-p "Replace double page dashes by single ones? ")
3652 'page-dashes)
3653 (if (y-or-n-p "Force delimiters? ")
3654 'delimiters)
3655 (if (y-or-n-p "Unify case of entry types and field names? ")
3656 'unify-case)))))
3657 '(realign))) 3692 '(realign)))
3658 (reformat-reference-keys (if additional-options 3693 (reformat-reference-keys
3659 (if use-previous-options 3694 (if read-options
3660 bibtex-reformat-previous-reference-keys 3695 (if use-previous-options
3661 (setq bibtex-reformat-previous-reference-keys 3696 bibtex-reformat-previous-reference-keys
3662 (y-or-n-p "Generate new reference keys automatically? "))))) 3697 (setq bibtex-reformat-previous-reference-keys
3663 bibtex-autokey-edit-before-use 3698 (y-or-n-p "Generate new reference keys automatically? ")))))
3664 (bibtex-sort-ignore-string-entries t)
3665 (start-point (if (bibtex-mark-active) 3699 (start-point (if (bibtex-mark-active)
3666 (region-beginning) 3700 (region-beginning)
3667 (bibtex-beginning-of-first-entry) 3701 (point-min)))
3668 (bibtex-skip-to-valid-entry)
3669 (point)))
3670 (end-point (if (bibtex-mark-active) 3702 (end-point (if (bibtex-mark-active)
3671 (region-end) 3703 (region-end)
3672 (point-max)))) 3704 (point-max)))
3705 (bibtex-sort-ignore-string-entries t)
3706 bibtex-autokey-edit-before-use)
3707
3673 (save-restriction 3708 (save-restriction
3674 (narrow-to-region start-point end-point) 3709 (narrow-to-region start-point end-point)
3675 (when (memq 'realign bibtex-entry-format) 3710 (if (memq 'realign bibtex-entry-format)
3676 (goto-char (point-min)) 3711 (bibtex-realign))
3677 (while (re-search-forward bibtex-valid-entry-whitespace-re nil t)
3678 (replace-match "\n\\1")))
3679 (goto-char start-point) 3712 (goto-char start-point)
3680 (bibtex-progress-message "Formatting" 1) 3713 (bibtex-progress-message "Formatting" 1)
3681 (bibtex-map-entries (lambda (key beg end) 3714 (bibtex-map-entries (lambda (key beg end)
3682 (bibtex-progress-message) 3715 (bibtex-progress-message)
3683 (bibtex-clean-entry reformat-reference-keys t) 3716 (bibtex-clean-entry reformat-reference-keys t)))
3684 (when (memq 'realign bibtex-entry-format) 3717 (when (memq 'realign bibtex-entry-format)
3685 (goto-char end) 3718 (bibtex-delete-whitespace)
3686 (bibtex-delete-whitespace) 3719 (open-line (if (eobp) 1 2)))
3687 (open-line 2))))
3688 (bibtex-progress-message 'done)) 3720 (bibtex-progress-message 'done))
3689 (when (and reformat-reference-keys 3721 (when (and reformat-reference-keys
3690 bibtex-maintain-sorted-entries 3722 bibtex-maintain-sorted-entries)
3691 (not called-by-convert-alien)) 3723 (bibtex-progress-message "Sorting" 1)
3692 (bibtex-sort-buffer) 3724 (bibtex-sort-buffer)
3693 (kill-local-variable 'bibtex-reference-keys)) 3725 (kill-local-variable 'bibtex-reference-keys)
3726 (bibtex-progress-message 'done))
3694 (goto-char pnt))) 3727 (goto-char pnt)))
3695 3728
3696(defun bibtex-convert-alien (&optional do-additional-reformatting) 3729(defun bibtex-convert-alien (&optional read-options)
3697 "Convert an alien BibTeX buffer to be fully usable by BibTeX mode. 3730 "Convert an alien BibTeX buffer to be fully usable by BibTeX mode.
3698If a file does not conform with some standards used by BibTeX mode, 3731If a file does not conform with all standards used by BibTeX mode,
3699some of the high-level features of BibTeX mode will not be available. 3732some of the high-level features of BibTeX mode will not be available.
3700This function tries to convert current buffer to conform with these standards. 3733This function tries to convert current buffer to conform with these standards.
3701With prefix argument DO-ADDITIONAL-REFORMATTING 3734With prefix argument READ-OPTIONS non-nil, read options for reformatting
3702non-nil, read options for reformatting entries from minibuffer." 3735entries from minibuffer."
3703 (interactive "*P") 3736 (interactive "*P")
3704 (message "Starting to validate buffer...") 3737 (message "Starting to validate buffer...")
3705 (sit-for 1 nil t) 3738 (sit-for 1 nil t)
3706 (goto-char (point-min)) 3739 (bibtex-realign)
3707 (while (re-search-forward "[ \t\n]+@" nil t)
3708 (replace-match "\n@"))
3709 (message 3740 (message
3710 "If errors occur, correct them and call `bibtex-convert-alien' again") 3741 "If errors occur, correct them and call `bibtex-convert-alien' again")
3711 (sit-for 5 nil t) 3742 (sit-for 5 nil t)
@@ -3714,10 +3745,7 @@ non-nil, read options for reformatting entries from minibuffer."
3714 (bibtex-validate)) 3745 (bibtex-validate))
3715 (message "Starting to reformat entries...") 3746 (message "Starting to reformat entries...")
3716 (sit-for 2 nil t) 3747 (sit-for 2 nil t)
3717 (bibtex-reformat do-additional-reformatting t) 3748 (bibtex-reformat read-options)
3718 (when bibtex-maintain-sorted-entries
3719 (message "Starting to sort buffer...")
3720 (bibtex-sort-buffer))
3721 (goto-char (point-max)) 3749 (goto-char (point-max))
3722 (message "Buffer is now parsable. Please save it."))) 3750 (message "Buffer is now parsable. Please save it.")))
3723 3751
@@ -3890,5 +3918,5 @@ is outside key or BibTeX field."
3890 3918
3891(provide 'bibtex) 3919(provide 'bibtex)
3892 3920
3893;;; arch-tag: ee2be3af-caad-427f-b42a-d20fad630d04 3921;; arch-tag: ee2be3af-caad-427f-b42a-d20fad630d04
3894;;; bibtex.el ends here 3922;;; bibtex.el ends here
diff --git a/lisp/textmodes/fill.el b/lisp/textmodes/fill.el
index aaa10fbce5f..a888003402d 100644
--- a/lisp/textmodes/fill.el
+++ b/lisp/textmodes/fill.el
@@ -155,7 +155,7 @@ Leave one space between words, two at end of sentences or after colons
155and `sentence-end-without-period'). 155and `sentence-end-without-period').
156Remove indentation from each line." 156Remove indentation from each line."
157 (interactive "*r") 157 (interactive "*r")
158 (let ((end-spc-re (concat "\\(" sentence-end "\\) *\\| +"))) 158 (let ((end-spc-re (concat "\\(" (sentence-end) "\\) *\\| +")))
159 (save-excursion 159 (save-excursion
160 (goto-char beg) 160 (goto-char beg)
161 ;; Nuke tabs; they get screwed up in a fill. 161 ;; Nuke tabs; they get screwed up in a fill.
@@ -349,7 +349,7 @@ and `fill-nobreak-invisible'."
349 (save-excursion 349 (save-excursion
350 (skip-chars-backward ". ") 350 (skip-chars-backward ". ")
351 (and (looking-at "\\.") 351 (and (looking-at "\\.")
352 (not (looking-at sentence-end)))) 352 (not (looking-at (sentence-end)))))
353 ;; Don't split a line if the rest would look like a new paragraph. 353 ;; Don't split a line if the rest would look like a new paragraph.
354 (unless use-hard-newlines 354 (unless use-hard-newlines
355 (save-excursion 355 (save-excursion
@@ -424,10 +424,10 @@ Point is moved to just past the fill prefix on the first line."
424 ;; loses on split abbrevs ("Mr.\nSmith") 424 ;; loses on split abbrevs ("Mr.\nSmith")
425 (let ((eol-double-space-re 425 (let ((eol-double-space-re
426 (cond 426 (cond
427 ((not colon-double-space) (concat sentence-end "$")) 427 ((not colon-double-space) (concat (sentence-end) "$"))
428 ;; Try to add the : inside the `sentence-end' regexp. 428 ;; Try to add the : inside the `sentence-end' regexp.
429 ((string-match "\\[[^][]*\\(\\.\\)[^][]*\\]" sentence-end) 429 ((string-match "\\[[^][]*\\(\\.\\)[^][]*\\]" (sentence-end))
430 (concat (replace-match ".:" nil nil sentence-end 1) "$")) 430 (concat (replace-match ".:" nil nil (sentence-end) 1) "$"))
431 ;; Can't find the right spot to insert the colon. 431 ;; Can't find the right spot to insert the colon.
432 (t "[.?!:][])}\"']*$"))) 432 (t "[.?!:][])}\"']*$")))
433 (sentence-end-without-space-list 433 (sentence-end-without-space-list
diff --git a/lisp/textmodes/flyspell.el b/lisp/textmodes/flyspell.el
index 3d41042e8d7..aff42866349 100644
--- a/lisp/textmodes/flyspell.el
+++ b/lisp/textmodes/flyspell.el
@@ -3,6 +3,7 @@
3;; Copyright (C) 1998, 2000, 2001, 2002 Free Software Foundation, Inc. 3;; Copyright (C) 1998, 2000, 2001, 2002 Free Software Foundation, Inc.
4 4
5;; Author: Manuel Serrano <Manuel.Serrano@unice.fr> 5;; Author: Manuel Serrano <Manuel.Serrano@unice.fr>
6;; Maintainer: FSF
6;; Keywords: convenience 7;; Keywords: convenience
7 8
8;; This file is part of GNU Emacs. 9;; This file is part of GNU Emacs.
@@ -1516,46 +1517,51 @@ for the overlay."
1516;*---------------------------------------------------------------------*/ 1517;*---------------------------------------------------------------------*/
1517(defun flyspell-highlight-incorrect-region (beg end poss) 1518(defun flyspell-highlight-incorrect-region (beg end poss)
1518 "Set up an overlay on a misspelled word, in the buffer from BEG to END." 1519 "Set up an overlay on a misspelled word, in the buffer from BEG to END."
1519 (unless (run-hook-with-args-until-success 1520 (let ((inhibit-read-only t))
1520 'flyspell-incorrect-hook beg end poss) 1521 (unless (run-hook-with-args-until-success
1521 (if (or flyspell-highlight-properties (not (flyspell-properties-at-p beg))) 1522 'flyspell-incorrect-hook beg end poss)
1522 (progn 1523 (if (or flyspell-highlight-properties
1523 ;; we cleanup current overlay at the same position 1524 (not (flyspell-properties-at-p beg)))
1524 (if (and (not flyspell-persistent-highlight) 1525 (progn
1525 (overlayp flyspell-overlay)) 1526 ;; we cleanup current overlay at the same position
1526 (delete-overlay flyspell-overlay) 1527 (if (and (not flyspell-persistent-highlight)
1527 (let ((overlays (overlays-at beg))) 1528 (overlayp flyspell-overlay))
1528 (while (consp overlays) 1529 (delete-overlay flyspell-overlay)
1529 (if (flyspell-overlay-p (car overlays)) 1530 (let ((overlays (overlays-at beg)))
1530 (delete-overlay (car overlays))) 1531 (while (consp overlays)
1531 (setq overlays (cdr overlays))))) 1532 (if (flyspell-overlay-p (car overlays))
1532 ;; now we can use a new overlay 1533 (delete-overlay (car overlays)))
1533 (setq flyspell-overlay 1534 (setq overlays (cdr overlays)))))
1534 (make-flyspell-overlay beg end 1535 ;; now we can use a new overlay
1535 'flyspell-incorrect-face 1536 (setq flyspell-overlay
1536 'highlight)))))) 1537 (make-flyspell-overlay
1538 beg end 'flyspell-incorrect-face 'highlight)))))))
1537 1539
1538;*---------------------------------------------------------------------*/ 1540;*---------------------------------------------------------------------*/
1539;* flyspell-highlight-duplicate-region ... */ 1541;* flyspell-highlight-duplicate-region ... */
1540;*---------------------------------------------------------------------*/ 1542;*---------------------------------------------------------------------*/
1541(defun flyspell-highlight-duplicate-region (beg end) 1543(defun flyspell-highlight-duplicate-region (beg end)
1542 "Set up an overlay on a duplicated word, in the buffer from BEG to END." 1544 "Set up an overlay on a duplicated word, in the buffer from BEG to END."
1543 (if (or flyspell-highlight-properties (not (flyspell-properties-at-p beg))) 1545 (let ((inhibit-read-only t))
1544 (progn 1546 (unless (run-hook-with-args-until-success
1545 ;; we cleanup current overlay at the same position 1547 'flyspell-incorrect-hook beg end poss)
1546 (if (and (not flyspell-persistent-highlight) 1548 (if (or flyspell-highlight-properties
1547 (overlayp flyspell-overlay)) 1549 (not (flyspell-properties-at-p beg)))
1548 (delete-overlay flyspell-overlay) 1550 (progn
1549 (let ((overlays (overlays-at beg))) 1551 ;; we cleanup current overlay at the same position
1550 (while (consp overlays) 1552 (if (and (not flyspell-persistent-highlight)
1551 (if (flyspell-overlay-p (car overlays)) 1553 (overlayp flyspell-overlay))
1552 (delete-overlay (car overlays))) 1554 (delete-overlay flyspell-overlay)
1553 (setq overlays (cdr overlays))))) 1555 (let ((overlays (overlays-at beg)))
1554 ;; now we can use a new overlay 1556 (while (consp overlays)
1555 (setq flyspell-overlay 1557 (if (flyspell-overlay-p (car overlays))
1556 (make-flyspell-overlay beg end 1558 (delete-overlay (car overlays)))
1557 'flyspell-duplicate-face 1559 (setq overlays (cdr overlays)))))
1558 'highlight))))) 1560 ;; now we can use a new overlay
1561 (setq flyspell-overlay
1562 (make-flyspell-overlay beg end
1563 'flyspell-duplicate-face
1564 'highlight)))))))
1559 1565
1560;*---------------------------------------------------------------------*/ 1566;*---------------------------------------------------------------------*/
1561;* flyspell-auto-correct-cache ... */ 1567;* flyspell-auto-correct-cache ... */
@@ -2061,23 +2067,23 @@ possible corrections as returned by 'ispell-parse-output'.
2061 2067
2062This function is meant to be added to 'flyspell-incorrect-hook'." 2068This function is meant to be added to 'flyspell-incorrect-hook'."
2063 (when (consp poss) 2069 (when (consp poss)
2064 (let ((temp-buffer (get-buffer-create " *flyspell-temp*")) 2070 (catch 'done
2065 found) 2071 (let ((str (buffer-substring beg end))
2066 (save-excursion 2072 (i 0) (len (- end beg)) tmp)
2067 (copy-to-buffer temp-buffer beg end) 2073 (while (< (1+ i) len)
2068 (set-buffer temp-buffer) 2074 (setq tmp (aref str i))
2069 (goto-char (1+ (point-min))) 2075 (aset str i (aref str (1+ i)))
2070 (while (and (not (eobp)) (not found)) 2076 (aset str (1+ i) tmp)
2071 (transpose-chars 1) 2077 (when (member str (nth 2 poss))
2072 (if (member (buffer-string) (nth 2 poss)) 2078 (save-excursion
2073 (setq found (point)) 2079 (goto-char (+ beg i 1))
2074 (transpose-chars -1) 2080 (transpose-chars 1))
2075 (forward-char)))) 2081 (throw 'done t))
2076 (when found 2082 (setq tmp (aref str i))
2077 (save-excursion 2083 (aset str i (aref str (1+ i)))
2078 (goto-char (+ beg found -1)) 2084 (aset str (1+ i) tmp)
2079 (transpose-chars -1) 2085 (setq i (1+ i))))
2080 t))))) 2086 nil)))
2081 2087
2082(defun flyspell-maybe-correct-doubling (beg end poss) 2088(defun flyspell-maybe-correct-doubling (beg end poss)
2083 "Check replacements for doubled characters. 2089 "Check replacements for doubled characters.
@@ -2091,24 +2097,19 @@ possible corrections as returned by 'ispell-parse-output'.
2091 2097
2092This function is meant to be added to 'flyspell-incorrect-hook'." 2098This function is meant to be added to 'flyspell-incorrect-hook'."
2093 (when (consp poss) 2099 (when (consp poss)
2094 (let ((temp-buffer (get-buffer-create " *flyspell-temp*")) 2100 (catch 'done
2095 found) 2101 (let ((str (buffer-substring beg end))
2096 (save-excursion 2102 (i 0) (len (- end beg)))
2097 (copy-to-buffer temp-buffer beg end) 2103 (while (< (1+ i) len)
2098 (set-buffer temp-buffer) 2104 (when (and (= (aref str i) (aref str (1+ i)))
2099 (goto-char (1+ (point-min))) 2105 (member (concat (substring str 0 (1+ i))
2100 (while (and (not (eobp)) (not found)) 2106 (substring str (+ i 2)))
2101 (when (char-equal (char-after) (char-before)) 2107 (nth 2 poss)))
2102 (delete-char 1) 2108 (goto-char (+ beg i))
2103 (if (member (buffer-string) (nth 2 poss)) 2109 (delete-char 1)
2104 (setq found (point)) 2110 (throw 'done t))
2105 (insert-char (char-before) 1))) 2111 (setq i (1+ i))))
2106 (forward-char))) 2112 nil)))
2107 (when found
2108 (save-excursion
2109 (goto-char (+ beg found -1))
2110 (delete-char 1)
2111 t)))))
2112 2113
2113;*---------------------------------------------------------------------*/ 2114;*---------------------------------------------------------------------*/
2114;* flyspell-already-abbrevp ... */ 2115;* flyspell-already-abbrevp ... */
diff --git a/lisp/textmodes/ispell.el b/lisp/textmodes/ispell.el
index 39fe89bdaaa..77c63379e2b 100644
--- a/lisp/textmodes/ispell.el
+++ b/lisp/textmodes/ispell.el
@@ -501,7 +501,8 @@ and then re-start emacs."
501 (choice :tag "Coding system" 501 (choice :tag "Coding system"
502 (const iso-8859-1) 502 (const iso-8859-1)
503 (const iso-8859-2) 503 (const iso-8859-2)
504 (const koi8-r)))) 504 (const koi8-r)
505 (const windows-1251))))
505 :group 'ispell) 506 :group 'ispell)
506 507
507 508
@@ -630,6 +631,10 @@ and then re-start emacs."
630 "[\341\342\367\347\344\345\263\366\372\351\352\353\354\355\356\357\360\362\363\364\365\346\350\343\376\373\375\370\371\377\374\340\361\301\302\327\307\304\305\243\326\332\311\312\313\314\315\316\317\320\322\323\324\325\306\310\303\336\333\335\330\331\337\334\300\321]" 631 "[\341\342\367\347\344\345\263\366\372\351\352\353\354\355\356\357\360\362\363\364\365\346\350\343\376\373\375\370\371\377\374\340\361\301\302\327\307\304\305\243\326\332\311\312\313\314\315\316\317\320\322\323\324\325\306\310\303\336\333\335\330\331\337\334\300\321]"
631 "[^\341\342\367\347\344\345\263\366\372\351\352\353\354\355\356\357\360\362\363\364\365\346\350\343\376\373\375\370\371\377\374\340\361\301\302\327\307\304\305\243\326\332\311\312\313\314\315\316\317\320\322\323\324\325\306\310\303\336\333\335\330\331\337\334\300\321]" 632 "[^\341\342\367\347\344\345\263\366\372\351\352\353\354\355\356\357\360\362\363\364\365\346\350\343\376\373\375\370\371\377\374\340\361\301\302\327\307\304\305\243\326\332\311\312\313\314\315\316\317\320\322\323\324\325\306\310\303\336\333\335\330\331\337\334\300\321]"
632 "" nil nil nil koi8-r) 633 "" nil nil nil koi8-r)
634 ("russianw" ; russianw.aff (CP1251 charset)
635 "[\300\301\302\303\304\305\250\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\334\333\332\335\336\337\340\341\342\343\344\345\270\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\374\373\372\375\376\377]"
636 "[^\300\301\302\303\304\305\250\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\334\333\332\335\336\337\340\341\342\343\344\345\270\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\374\373\372\375\376\377]"
637 "" nil nil nil windows-1251)
633 ("slovak" ; Slovakian 638 ("slovak" ; Slovakian
634 "[A-Za-z\301\304\311\315\323\332\324\300\305\245\335\256\251\310\317\253\322\341\344\351\355\363\372\364\340\345\265\375\276\271\350\357\273\362]" 639 "[A-Za-z\301\304\311\315\323\332\324\300\305\245\335\256\251\310\317\253\322\341\344\351\355\363\372\364\340\345\265\375\276\271\350\357\273\362]"
635 "[^A-Za-z\301\304\311\315\323\332\324\300\305\245\335\256\251\310\317\253\322\341\344\351\355\363\372\364\340\345\265\375\276\271\350\357\273\362]" 640 "[^A-Za-z\301\304\311\315\323\332\324\300\305\245\335\256\251\310\317\253\322\341\344\351\355\363\372\364\340\345\265\375\276\271\350\357\273\362]"
@@ -3274,7 +3279,7 @@ You can bind this to the key C-c i in GNUS or mail by adding to
3274 (equal major-mode 'message-mode)) ;GNUS 5 3279 (equal major-mode 'message-mode)) ;GNUS 5
3275 (concat "In article <" "\\|" 3280 (concat "In article <" "\\|"
3276 "[^,;&+=\n]+ <[^,;&+=]+> writes:" "\\|" 3281 "[^,;&+=\n]+ <[^,;&+=]+> writes:" "\\|"
3277 message-yank-prefix "\\|" 3282 message-cite-prefix-regexp "\\|"
3278 default-prefix)) 3283 default-prefix))
3279 ((equal major-mode 'mh-letter-mode) ; mh mail message 3284 ((equal major-mode 'mh-letter-mode) ; mh mail message
3280 (concat "[^,;&+=\n]+ writes:" "\\|" 3285 (concat "[^,;&+=\n]+ writes:" "\\|"
diff --git a/lisp/textmodes/paragraphs.el b/lisp/textmodes/paragraphs.el
index f7595e24cb5..e9cc4f397de 100644
--- a/lisp/textmodes/paragraphs.el
+++ b/lisp/textmodes/paragraphs.el
@@ -120,49 +120,62 @@ text indented by a margin setting."
120This is relevant for filling. See also `sentence-end-without-period' 120This is relevant for filling. See also `sentence-end-without-period'
121and `colon-double-space'. 121and `colon-double-space'.
122 122
123If you change this, you should also change `sentence-end'. See Info 123This value is used by the function `sentence-end' to construct the
124node `Sentences'." 124regexp describing the end of a sentence, in case when the value of
125the variable `sentence-end' is nil. See Info node `Sentences'."
125 :type 'boolean 126 :type 'boolean
126 :group 'fill) 127 :group 'fill)
127 128
128(defcustom sentence-end-without-period nil 129(defcustom sentence-end-without-period nil
129 "*Non-nil means a sentence will end without a period. 130 "*Non-nil means a sentence will end without a period.
130For example, a sentence in Thai text ends with double space but 131For example, a sentence in Thai text ends with double space but
131without a period." 132without a period.
133
134This value is used by the function `sentence-end' to construct the
135regexp describing the end of a sentence, in case when the value of
136the variable `sentence-end' is nil. See Info node `Sentences'."
132 :type 'boolean 137 :type 'boolean
133 :group 'fill) 138 :group 'fill)
134 139
135(defcustom sentence-end-without-space 140(defcustom sentence-end-without-space
136 "$B!#!%!)!*$A!##.#?#!$(0!$!%!)!*$(G!$!%!)!*(B" 141 "$B!#!%!)!*$A!##.#?#!$(0!$!%!)!*$(G!$!%!)!*(B"
137 "*String containing characters that end sentence without following spaces. 142 "*String containing characters that end sentence without following spaces.
138If you change this, you should also change `sentence-end'. See Info 143
139node `Sentences'." 144This value is used by the function `sentence-end' to construct the
145regexp describing the end of a sentence, in case when the value of
146the variable `sentence-end' is nil. See Info node `Sentences'."
140 :group 'paragraphs 147 :group 'paragraphs
141 :type 'string) 148 :type 'string)
142 149
143(defcustom sentence-end 150(defcustom sentence-end nil
144 (purecopy
145 ;; This is a bit stupid since it's not auto-updated when the
146 ;; other variables are changes, but it's still useful info.
147 (concat (if sentence-end-without-period "\\w \\|")
148 "\\([.?!][]\"')}]*"
149 (if sentence-end-double-space
150 "\\($\\| $\\|\t\\| \\)" "\\($\\|[\t ]\\)")
151 "\\|[" sentence-end-without-space "]+\\)"
152 "[ \t\n]*"))
153 "*Regexp describing the end of a sentence. 151 "*Regexp describing the end of a sentence.
154The value includes the whitespace following the sentence. 152The value includes the whitespace following the sentence.
155All paragraph boundaries also end sentences, regardless. 153All paragraph boundaries also end sentences, regardless.
156 154
157The default value specifies that in order to be recognized as the end 155The value nil means to use the default value defined by the
158of a sentence, the ending period, question mark, or exclamation point 156function `sentence-end'. You should always use this function
159must be followed by two spaces, unless it's inside some sort of quotes 157to obtain the value of this variable."
160or parenthesis.
161
162See also the variable `sentence-end-double-space', the variable
163`sentence-end-without-period' and Info node `Sentences'."
164 :group 'paragraphs 158 :group 'paragraphs
165 :type 'regexp) 159 :type '(choice regexp (const :tag "Use default value" nil)))
160
161(defun sentence-end ()
162 "Return the regexp describing the end of a sentence.
163
164This function returns either the value of the variable `sentence-end'
165if it is non-nil, or the default value constructed from the
166variables `sentence-end-double-space', `sentence-end-without-period'
167and `sentence-end-without-space'. The default value specifies
168that in order to be recognized as the end of a sentence, the
169ending period, question mark, or exclamation point must be
170followed by two spaces, unless it's inside some sort of quotes or
171parenthesis. See Info node `Sentences'."
172 (or sentence-end
173 (concat (if sentence-end-without-period "\\w \\|")
174 "\\([.?!][]\"'\xd0c9\x5397d)}]*"
175 (if sentence-end-double-space
176 "\\($\\| $\\|\t\\| \\)" "\\($\\|[\t ]\\)")
177 "\\|[" sentence-end-without-space "]+\\)"
178 "[ \t\n]*")))
166 179
167(defcustom page-delimiter "^\014" 180(defcustom page-delimiter "^\014"
168 "*Regexp describing line-beginnings that separate pages." 181 "*Regexp describing line-beginnings that separate pages."
@@ -411,7 +424,8 @@ The variable `sentence-end' is a regular expression that matches ends of
411sentences. Also, every paragraph boundary terminates sentences as well." 424sentences. Also, every paragraph boundary terminates sentences as well."
412 (interactive "p") 425 (interactive "p")
413 (or arg (setq arg 1)) 426 (or arg (setq arg 1))
414 (let ((opoint (point))) 427 (let ((opoint (point))
428 (sentence-end (sentence-end)))
415 (while (< arg 0) 429 (while (< arg 0)
416 (let ((pos (point)) 430 (let ((pos (point))
417 (par-beg (save-excursion (start-of-paragraph-text) (point)))) 431 (par-beg (save-excursion (start-of-paragraph-text) (point))))
diff --git a/lisp/textmodes/picture.el b/lisp/textmodes/picture.el
index 0497a823049..b3c69ca657f 100644
--- a/lisp/textmodes/picture.el
+++ b/lisp/textmodes/picture.el
@@ -636,7 +636,15 @@ Leaves the region surrounding the rectangle."
636 (define-key picture-mode-map "\C-c`" 'picture-movement-nw) 636 (define-key picture-mode-map "\C-c`" 'picture-movement-nw)
637 (define-key picture-mode-map "\C-c'" 'picture-movement-ne) 637 (define-key picture-mode-map "\C-c'" 'picture-movement-ne)
638 (define-key picture-mode-map "\C-c/" 'picture-movement-sw) 638 (define-key picture-mode-map "\C-c/" 'picture-movement-sw)
639 (define-key picture-mode-map "\C-c\\" 'picture-movement-se))) 639 (define-key picture-mode-map "\C-c\\" 'picture-movement-se)
640 (define-key picture-mode-map [(control ?c) left] 'picture-movement-left)
641 (define-key picture-mode-map [(control ?c) right] 'picture-movement-right)
642 (define-key picture-mode-map [(control ?c) up] 'picture-movement-up)
643 (define-key picture-mode-map [(control ?c) down] 'picture-movement-down)
644 (define-key picture-mode-map [(control ?c) home] 'picture-movement-nw)
645 (define-key picture-mode-map [(control ?c) prior] 'picture-movement-ne)
646 (define-key picture-mode-map [(control ?c) end] 'picture-movement-sw)
647 (define-key picture-mode-map [(control ?c) next] 'picture-movement-se)))
640 648
641(defcustom picture-mode-hook nil 649(defcustom picture-mode-hook nil
642 "If non-nil, its value is called on entry to Picture mode. 650 "If non-nil, its value is called on entry to Picture mode.
diff --git a/lisp/textmodes/table.el b/lisp/textmodes/table.el
index 93ea3cc0c14..7b13d498b2e 100644
--- a/lisp/textmodes/table.el
+++ b/lisp/textmodes/table.el
@@ -1,11 +1,11 @@
1;;; table.el --- create and edit WYSIWYG text based embedded tables 1;;; table.el --- create and edit WYSIWYG text based embedded tables
2 2
3;; Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc. 3;; Copyright (C) 2000, 01, 02, 03, 04 Free Software Foundation, Inc.
4 4
5;; Keywords: wp, convenience 5;; Keywords: wp, convenience
6;; Author: Takaaki Ota <Takaaki.Ota@am.sony.com> 6;; Author: Takaaki Ota <Takaaki.Ota@am.sony.com>
7;; Created: Sat Jul 08 2000 13:28:45 (PST) 7;; Created: Sat Jul 08 2000 13:28:45 (PST)
8;; Revised: Tue Dec 09 2003 14:36:50 (PST) 8;; Revised: Tue Jun 01 2004 11:36:39 (PDT)
9 9
10;; This file is part of GNU Emacs. 10;; This file is part of GNU Emacs.
11 11
@@ -1410,6 +1410,8 @@ the last cache point coordinate."
1410 end-of-buffer 1410 end-of-buffer
1411 forward-word 1411 forward-word
1412 backward-word 1412 backward-word
1413 forward-sentence
1414 backward-sentence
1413 forward-paragraph 1415 forward-paragraph
1414 backward-paragraph)) 1416 backward-paragraph))
1415 1417
@@ -1434,9 +1436,18 @@ the last cache point coordinate."
1434 (cons (cons command func-symbol) 1436 (cons (cons command func-symbol)
1435 table-command-remap-alist)))) 1437 table-command-remap-alist))))
1436 '(kill-region 1438 '(kill-region
1439 kill-ring-save
1437 delete-region 1440 delete-region
1438 copy-region-as-kill 1441 copy-region-as-kill
1439 kill-line)) 1442 kill-line
1443 kill-word
1444 backward-kill-word
1445 kill-sentence
1446 backward-kill-sentence
1447 kill-paragraph
1448 backward-kill-paragraph
1449 kill-sexp
1450 backward-kill-sexp))
1440 1451
1441;; Pasting Group 1452;; Pasting Group
1442(mapcar 1453(mapcar
diff --git a/lisp/textmodes/tex-mode.el b/lisp/textmodes/tex-mode.el
index 75a064c8959..c35ba53dbaa 100644
--- a/lisp/textmodes/tex-mode.el
+++ b/lisp/textmodes/tex-mode.el
@@ -1944,21 +1944,22 @@ for the error messages."
1944 (or (null last-filename) 1944 (or (null last-filename)
1945 (not (string-equal last-filename filename)))) 1945 (not (string-equal last-filename filename))))
1946 (error-location 1946 (error-location
1947 (save-excursion 1947 (with-current-buffer
1948 (if (equal filename (concat tex-zap-file ".tex")) 1948 (if (equal filename (concat tex-zap-file ".tex"))
1949 (set-buffer tex-last-buffer-texed) 1949 tex-last-buffer-texed
1950 (set-buffer (find-file-noselect filename))) 1950 (find-file-noselect filename))
1951 (if new-file 1951 (save-excursion
1952 (progn (goto-line linenum) (setq last-position nil)) 1952 (if new-file
1953 (goto-char last-position) 1953 (progn (goto-line linenum) (setq last-position nil))
1954 (forward-line (- linenum last-linenum))) 1954 (goto-char last-position)
1955 ;; first try a forward search for the error text, 1955 (forward-line (- linenum last-linenum)))
1956 ;; then a backward search limited by the last error. 1956 ;; first try a forward search for the error text,
1957 (let ((starting-point (point))) 1957 ;; then a backward search limited by the last error.
1958 (or (re-search-forward error-text nil t) 1958 (let ((starting-point (point)))
1959 (re-search-backward error-text last-position t) 1959 (or (re-search-forward error-text nil t)
1960 (goto-char starting-point))) 1960 (re-search-backward error-text last-position t)
1961 (point-marker)))) 1961 (goto-char starting-point)))
1962 (point-marker)))))
1962 (goto-char this-error) 1963 (goto-char this-error)
1963 (if (and compilation-error-list 1964 (if (and compilation-error-list
1964 (or (and find-at-least 1965 (or (and find-at-least
diff --git a/lisp/textmodes/texinfmt.el b/lisp/textmodes/texinfmt.el
index 3e79d18a108..cc382b70528 100644
--- a/lisp/textmodes/texinfmt.el
+++ b/lisp/textmodes/texinfmt.el
@@ -2899,7 +2899,7 @@ Default is to leave paragraph indentation as is."
2899 1)) 2899 1))
2900 (symbol-value indexvar))))) 2900 (symbol-value indexvar)))))
2901 2901
2902(defconst texinfo-indexvar-alist 2902(defvar texinfo-indexvar-alist
2903 '(("cp" . texinfo-cindex) 2903 '(("cp" . texinfo-cindex)
2904 ("fn" . texinfo-findex) 2904 ("fn" . texinfo-findex)
2905 ("vr" . texinfo-vindex) 2905 ("vr" . texinfo-vindex)
@@ -3032,7 +3032,7 @@ Default is to leave paragraph indentation as is."
3032 (indent-to 54) 3032 (indent-to 54)
3033 (insert 3033 (insert
3034 (if (nth 2 (car indexelts)) 3034 (if (nth 2 (car indexelts))
3035 (format " %d." (nth 2 (car indexelts))) 3035 (format " (line %3d)" (1+ (nth 2 (car indexelts))))
3036 "") 3036 "")
3037 "\n")) 3037 "\n"))
3038 ;; index entries from @include'd file 3038 ;; index entries from @include'd file