diff options
| author | Miles Bader <miles@gnu.org> | 2004-06-28 07:56:49 +0000 |
|---|---|---|
| committer | Miles Bader <miles@gnu.org> | 2004-06-28 07:56:49 +0000 |
| commit | 327719ee8a3fcdb36ed6acaf6d8cb5fbdf0bd801 (patch) | |
| tree | 21de188e13b5e41a79bb50040933072ae0235217 /lisp/textmodes | |
| parent | 852f73b7fa7b71910282eacb6263b3ecfd4ee783 (diff) | |
| parent | 376de73927383d6062483db10b8a82448505f52b (diff) | |
| download | emacs-327719ee8a3fcdb36ed6acaf6d8cb5fbdf0bd801.tar.gz | |
Revision: miles@gnu.org--gnu-2004/emacs--unicode--0--patch-15
Merge from emacs--cvs-trunk--0
Patches applied:
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-218
- miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-220
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-221
Restore deleted tagline in etc/TUTORIAL.ru
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-222
- miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-228
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-229
Remove TeX output files from the archive
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-230
- miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-247
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-248
src/lisp.h (CYCLE_CHECK): Macro moved from xfaces.c
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-249
- miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-256
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-258
- miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-263
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-264
Update from CVS: lispref/display.texi: emacs -> Emacs.
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-265
- miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-274
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-275
Update from CVS: man/makefile.w32-in: Revert last change
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-276
- miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-295
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-296
Allow restarting an existing debugger session that's exited
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-297
- miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-299
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-300
- miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-327
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-328
Update from CVS: src/.gdbinit (xsymbol): Fix last change.
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-329
- miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-344
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-345
Tweak source regexps so that building in place won't cause problems
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-346
- miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-351
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-352
Update from CVS: lisp/flymake.el: New file.
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-353
- miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-361
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-362
Support " [...]" style defaults in minibuffer-electric-default-mode
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-363
(read-number): Use canonical format for default in prompt.
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-364
- miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-367
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-368
Improve display-supports-face-attributes-p on non-ttys
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-369
Rewrite face-differs-from-default-p
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-370
Move `display-supports-face-attributes-p' entirely into C code
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-371
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-372
Simplify face-differs-from-default-p; don't consider :stipple.
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-373
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-374
(tty_supports_face_attributes_p): Ensure attributes differ from default
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-375
- miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-376
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-377
(Fdisplay_supports_face_attributes_p): Work around bootstrapping problem
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-378
- miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-380
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-381
Face merging cleanups
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-382
- miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-384
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-385
src/xfaces.c (push_named_merge_point): Return 0 if a cycle is detected
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-386
- miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-395
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-396
Tweak arch tagging to make build/install-in-place less annoying
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-397
Work around vc-arch problems when building eshell
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-398
Tweak permissions
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-399
Tweak directory permissions
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-400
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-401
More build-in-place tweaking of arch tagging
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-402
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-403
Yet more build-in-place tweaking of arch tagging
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-404
- miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-409
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-410
Make sure image types are initialized for lookup too
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-411
- miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-416
Update from CVS
Diffstat (limited to 'lisp/textmodes')
| -rw-r--r-- | lisp/textmodes/artist.el | 45 | ||||
| -rw-r--r-- | lisp/textmodes/bibtex.el | 566 | ||||
| -rw-r--r-- | lisp/textmodes/fill.el | 10 | ||||
| -rw-r--r-- | lisp/textmodes/flyspell.el | 139 | ||||
| -rw-r--r-- | lisp/textmodes/ispell.el | 9 | ||||
| -rw-r--r-- | lisp/textmodes/paragraphs.el | 62 | ||||
| -rw-r--r-- | lisp/textmodes/picture.el | 10 | ||||
| -rw-r--r-- | lisp/textmodes/table.el | 17 | ||||
| -rw-r--r-- | lisp/textmodes/tex-mode.el | 31 | ||||
| -rw-r--r-- | lisp/textmodes/texinfmt.el | 4 |
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 @@ ;;; artist.el --- draw ascii graphics with your mouse -;; Copyright (C) 2000, 2001 Free Software Foundation, Inc. +;; Copyright (C) 2000, 2001, 2004 Free Software Foundation, Inc. ;; Author: Tomas Abrahamsson <tab@lysator.liu.se> ;; Maintainer: Tomas Abrahamsson <tab@lysator.liu.se> @@ -1698,19 +1698,14 @@ info-variant-part." (t (cons (car l) (artist-butlast (cdr l)))))) -(defun artist-last (seq &optional n) - "Return the last link in the list SEQ. +(defun artist-last (l &optional n) + "Return the last link in the list L. With optional argument N, returns Nth-to-last link (default 1)." - (if (not n) - (setq n 1)) - (let ((len (length seq))) - (elt seq (- len n)))) + (nth (- (length l) (or n 1)) l)) (defun artist-remove-nulls (l) "Remove nils in list L." - (cond ((null l) nil) - ((null (car l)) (artist-remove-nulls (cdr l))) - (t (cons (car l) (artist-remove-nulls (cdr l)))))) + (remq nil l)) (defun artist-uniq (l) "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." (append right-half left-half))) -(defun artist-draw-ellipse-general (x y x-radius y-radius) - "Draw an ellipse with center at X, Y and X-RADIUS and Y-RADIUS. +(defun artist-draw-ellipse-general (x1 y1 x-radius y-radius) + "Draw an ellipse with center at X1, Y1 and X-RADIUS and Y-RADIUS. Output is an ellipse, which is a list (END-POINT-1 END-POINT-2 SHAPE-INFO). @@ -3379,15 +3374,15 @@ SHAPE-INFO is a two-element vector on the form [POINT-LIST FILL-INFO]. POINT-LIST is a list of vectors on the form [X Y SAVED-CHAR NEW-CHAR]. FILL-INFO is a list of vectors on the form [X Y ELLIPSE-WIDTH-ON-THIS-LINE]. -Ellipses with zero y-radius are not drawn correctly." +Ellipses with zero Y-RADIUS are not drawn correctly." (let* ((point-list (artist-ellipse-generate-quadrant x-radius y-radius)) (fill-info (artist-ellipse-compute-fill-info point-list)) (shape-info (make-vector 2 0))) (setq point-list (artist-calculate-new-chars point-list)) (setq point-list (artist-ellipse-mirror-quadrant point-list)) - (setq point-list (artist-ellipse-point-list-add-center x y point-list)) - (setq fill-info (artist-ellipse-fill-info-add-center x y fill-info)) + (setq point-list (artist-ellipse-point-list-add-center x1 y1 point-list)) + (setq fill-info (artist-ellipse-fill-info-add-center x1 y1 fill-info)) ;; Draw the ellipse (setq point-list @@ -3404,12 +3399,12 @@ Ellipses with zero y-radius are not drawn correctly." (aset shape-info 0 point-list) (aset shape-info 1 fill-info) - (artist-make-2point-object (artist-make-endpoint x y) + (artist-make-2point-object (artist-make-endpoint x1 y1) (artist-make-endpoint x-radius y-radius) shape-info))) -(defun artist-draw-ellipse-with-0-height (x y x-radius y-radius) - "Draw an ellipse with center at X, Y and X-RADIUS and Y-RADIUS. +(defun artist-draw-ellipse-with-0-height (x1 y1 x-radius y-radius) + "Draw an ellipse with center at X1, Y1 and X-RADIUS and Y-RADIUS. Output is an ellipse, which is a list (END-POINT-1 END-POINT-2 SHAPE-INFO). @@ -3419,10 +3414,10 @@ SHAPE-INFO is a two-element vector on the form [POINT-LIST FILL-INFO]. POINT-LIST is a list of vectors on the form [X Y SAVED-CHAR NEW-CHAR]. FILL-INFO is a list of vectors on the form [X Y ELLIPSE-WIDTH-ON-THIS-LINE]. -The Y-RADIUS must be 0, but the X-RADUIS must not be 0." +The Y-RADIUS must be 0, but the X-RADIUS must not be 0." (let ((point-list nil) (width (max (- (abs (* 2 x-radius)) 1))) - (left-edge (1+ (- x (abs x-radius)))) + (left-edge (1+ (- x1 (abs x-radius)))) (line-char (if artist-line-char-set artist-line-char ?-)) (i 0) (point-list nil) @@ -3430,7 +3425,7 @@ The Y-RADIUS must be 0, but the X-RADUIS must not be 0." (shape-info (make-vector 2 0))) (while (< i width) (let* ((line-x (+ left-edge i)) - (line-y y) + (line-y y1) (new-coord (artist-new-coord line-x line-y))) (artist-coord-add-saved-char new-coord (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." (setq i (1+ i)))) (aset shape-info 0 point-list) (aset shape-info 1 fill-info) - (artist-make-2point-object (artist-make-endpoint x y) + (artist-make-2point-object (artist-make-endpoint x1 y1) (artist-make-endpoint x-radius y-radius) shape-info))) @@ -3954,7 +3949,7 @@ The 2-point shape SHAPE is drawn from X1, Y1 to X2, Y2." (defun artist-draw-region-trim-line-endings (min-y max-y) "Trim lines in current draw-region from MIN-Y to MAX-Y. -Trimming here means removing white space at end of a line" +Trimming here means removing white space at end of a line." ;; Safetyc check: switch min-y and max-y if if max-y is smaller (if (< max-y min-y) (let ((tmp min-y)) @@ -4286,7 +4281,7 @@ If optional argument THIS-IS-LAST-POINT is non-nil, this point is the last." (defun artist-key-set-point-common (arg) "Common routine for setting point in current shape. -With ARG set to t, set the last point." +With non-nil ARG, set the last point." (let ((draw-how (artist-go-get-draw-how-from-symbol artist-curr-go)) (col (artist-current-column)) (row (artist-current-line)) @@ -4793,7 +4788,7 @@ If optional argument STATE is positive, turn borders on." (defun artist-mouse-choose-operation (ev op) - "Choose operation for evenvt EV and operation OP." + "Choose operation for event EV and operation OP." (interactive (progn (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 @@ ;;; bibtex.el --- BibTeX mode for GNU Emacs -;; Copyright (C) 1992,94,95,96,97,98,1999,2003 Free Software Foundation, Inc. +;; Copyright (C) 1992,94,95,96,97,98,1999,2003,2004 +;; Free Software Foundation, Inc. ;; Author: Stefan Schoef <schoef@offis.uni-oldenburg.de> ;; Bengt Martensson <bengt@mathematik.uni-Bremen.de> @@ -811,6 +812,7 @@ If non-nil, the column for the equal sign is the value of (define-key km "\C-c\M-y" 'bibtex-yank-pop) (define-key km "\C-c\C-d" 'bibtex-empty-field) (define-key km "\C-c\C-f" 'bibtex-make-field) + (define-key km "\C-c\C-u" 'bibtex-entry-update) (define-key km "\C-c$" 'bibtex-ispell-abstract) (define-key km "\M-\C-a" 'bibtex-beginning-of-entry) (define-key km "\M-\C-e" 'bibtex-end-of-entry) @@ -1122,44 +1124,6 @@ function `bibtex-parse-field-name'.") '(bibtex-mode "@\\S(*\\s(" "\\s)" nil bibtex-hs-forward-sexp nil)) -(defconst bibtex-braced-string-syntax-table - (let ((st (make-syntax-table))) - (modify-syntax-entry ?\{ "(}" st) - (modify-syntax-entry ?\} "){" st) - (modify-syntax-entry ?\[ "." st) - (modify-syntax-entry ?\] "." st) - (modify-syntax-entry ?\( "." st) - (modify-syntax-entry ?\) "." st) - (modify-syntax-entry ?\\ "." st) - (modify-syntax-entry ?\" "." st) - st) - "Syntax-table to parse matched braces.") - -(defconst bibtex-quoted-string-syntax-table - (let ((st (make-syntax-table))) - (modify-syntax-entry ?\\ "\\" st) - (modify-syntax-entry ?\" "\"" st) - st) - "Syntax-table to parse matched quotes.") - -(defun bibtex-parse-field-string () - "Parse a field string enclosed by braces or quotes. -If a syntactically correct string is found, a pair containing the start and -end position of the field string is returned, nil otherwise." - (let ((end-point - (or (and (eq (following-char) ?\") - (save-excursion - (with-syntax-table bibtex-quoted-string-syntax-table - (forward-sexp 1)) - (point))) - (and (eq (following-char) ?\{) - (save-excursion - (with-syntax-table bibtex-braced-string-syntax-table - (forward-sexp 1)) - (point)))))) - (if end-point - (cons (point) end-point)))) - (defun bibtex-parse-association (parse-lhs parse-rhs) "Parse a string of the format <left-hand-side = right-hand-side>. The functions PARSE-LHS and PARSE-RHS are used to parse the corresponding @@ -1199,6 +1163,44 @@ BibTeX field as necessary." ;; Now try again. (bibtex-parse-field-name)))) +(defconst bibtex-braced-string-syntax-table + (let ((st (make-syntax-table))) + (modify-syntax-entry ?\{ "(}" st) + (modify-syntax-entry ?\} "){" st) + (modify-syntax-entry ?\[ "." st) + (modify-syntax-entry ?\] "." st) + (modify-syntax-entry ?\( "." st) + (modify-syntax-entry ?\) "." st) + (modify-syntax-entry ?\\ "." st) + (modify-syntax-entry ?\" "." st) + st) + "Syntax-table to parse matched braces.") + +(defconst bibtex-quoted-string-syntax-table + (let ((st (make-syntax-table))) + (modify-syntax-entry ?\\ "\\" st) + (modify-syntax-entry ?\" "\"" st) + st) + "Syntax-table to parse matched quotes.") + +(defun bibtex-parse-field-string () + "Parse a field string enclosed by braces or quotes. +If a syntactically correct string is found, a pair containing the start and +end position of the field string is returned, nil otherwise." + (let ((end-point + (or (and (eq (following-char) ?\") + (save-excursion + (with-syntax-table bibtex-quoted-string-syntax-table + (forward-sexp 1)) + (point))) + (and (eq (following-char) ?\{) + (save-excursion + (with-syntax-table bibtex-braced-string-syntax-table + (forward-sexp 1)) + (point)))))) + (if end-point + (cons (point) end-point)))) + (defun bibtex-parse-field-text () "Parse the text part of a BibTeX field. The text part is either a string, or an empty string, or a constant followed @@ -1410,7 +1412,7 @@ delimiters if present." (let ((content (buffer-substring-no-properties (nth 0 (cdr bounds)) (nth 1 (cdr bounds))))) (if (and remove-delim - (string-match "\\`{\\(.*\\)}\\'" content)) + (string-match "\\`[{\"]\\(.*\\)[}\"]\\'" content)) (substring content (match-beginning 1) (match-end 1)) content))) @@ -1455,16 +1457,6 @@ The value is actually the tail of LIST whose car matches STRING." (setq list (cdr list))) list)) -(defun bibtex-assoc-of-regexp (string alist) - "Return non-nil if STRING is exactly matched by the car of an -element of ALIST (case ignored). The value is actually the element -of LIST whose car matches STRING." - (let ((case-fold-search t)) - (while (and alist - (not (string-match (concat "\\`\\(?:" (caar alist) "\\)\\'") string))) - (setq alist (cdr alist))) - (car alist))) - (defun bibtex-skip-to-valid-entry (&optional backward) "Unless at beginning of a valid BibTeX entry, move point to beginning of the next valid one. With optional argument BACKWARD non-nil, move backward to @@ -1510,7 +1502,7 @@ FUN will not be called for @String entries." (save-excursion (if (or (and (not bibtex-sort-ignore-string-entries) (string-equal "string" (downcase entry-type))) - (assoc-ignore-case entry-type bibtex-entry-field-alist)) + (assoc-string entry-type bibtex-entry-field-alist t)) (funcall fun key beg end))) (goto-char end))))) @@ -1519,8 +1511,8 @@ FUN will not be called for @String entries." If FLAG is a string, the message is initialized (in this case a value for INTERVAL may be given as well (if not this is set to 5)). If FLAG is done, the message is deinitialized. -If FLAG is absent, a message is echoed if point was incremented -at least INTERVAL percent since last message was echoed." +If FLAG is nil, a message is echoed if point was incremented at least +`bibtex-progress-interval' percent since last message was echoed." (cond ((stringp flag) (setq bibtex-progress-lastmes flag) (setq bibtex-progress-interval (or interval 5) @@ -1685,11 +1677,11 @@ are defined, but only for the head part of the entry "Try to avoid point being at end of a BibTeX field." (end-of-line) (skip-chars-backward " \t") - (cond ((= (preceding-char) ?,) - (forward-char -2))) - (cond ((or (= (preceding-char) ?}) - (= (preceding-char) ?\")) - (forward-char -1)))) + (if (= (preceding-char) ?,) + (forward-char -2)) + (if (or (= (preceding-char) ?}) + (= (preceding-char) ?\")) + (forward-char -1))) (defun bibtex-enclosing-field (&optional noerr) "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)." (error "Unknown tag field: %s. Please submit a bug report" bibtex-last-kill-command)))))) +(defun bibtex-assoc-regexp (regexp alist) + "Return non-nil if REGEXP matches the car of an element of ALIST. +The value is actually the element of ALIST matched by REGEXP. +Case is ignored if `case-fold-search' is non-nil in the current buffer." + (while (and alist + (not (string-match regexp (caar alist)))) + (setq alist (cdr alist))) + (car alist)) + (defun bibtex-format-entry () "Helper function for `bibtex-clean-entry'. Formats current entry according to variable `bibtex-entry-format'." @@ -1763,18 +1764,17 @@ Formats current entry according to variable `bibtex-entry-format'." unify-case inherit-booktitle) bibtex-entry-format)) crossref-key bounds alternatives-there non-empty-alternative - entry-list req creq field-done field-list) + entry-list req-field-list field-done field-list) ;; identify entry type (goto-char (point-min)) (re-search-forward bibtex-entry-type) (let ((beg-type (1+ (match-beginning 0))) (end-type (match-end 0))) - (setq entry-list (assoc-ignore-case (buffer-substring-no-properties - beg-type end-type) - bibtex-entry-field-alist) - req (nth 0 (nth 1 entry-list)) ; required part - creq (nth 0 (nth 2 entry-list))) ; crossref part + (setq entry-list (assoc-string (buffer-substring-no-properties + beg-type end-type) + bibtex-entry-field-alist + t)) ;; unify case of entry name (when (memq 'unify-case format) @@ -1791,20 +1791,32 @@ Formats current entry according to variable `bibtex-entry-format'." ;; determine if entry has crossref field and if at least ;; one alternative is non-empty (goto-char (point-min)) - (while (setq bounds (bibtex-search-forward-field - bibtex-field-name)) - (goto-char (bibtex-start-of-name-in-field bounds)) - (cond ((looking-at "ALT") - (setq alternatives-there t) - (goto-char (bibtex-start-of-text-in-field bounds)) - (if (not (looking-at bibtex-empty-field-re)) - (setq non-empty-alternative t))) - ((and (looking-at "\\(OPT\\)?crossref\\>") - (progn (goto-char (bibtex-start-of-text-in-field bounds)) - (not (looking-at bibtex-empty-field-re)))) - (setq crossref-key - (bibtex-text-in-field-bounds bounds t)))) - (goto-char (bibtex-end-of-field bounds))) + (let* ((fields-alist (bibtex-parse-entry)) + (case-fold-search t) + (field (bibtex-assoc-regexp "\\`\\(OPT\\)?crossref\\'" + fields-alist))) + (setq crossref-key (and field + (not (string-match bibtex-empty-field-re + (cdr field))) + (cdr field)) + req-field-list (if crossref-key + (nth 0 (nth 2 entry-list)) ; crossref part + (nth 0 (nth 1 entry-list)))) ; required part + + (dolist (rfield req-field-list) + (when (nth 3 rfield) ; we should have an alternative + (setq alternatives-there t + field (bibtex-assoc-regexp + (concat "\\`\\(ALT\\)?" (car rfield) "\\'") + fields-alist)) + (if (and field + (not (string-match bibtex-empty-field-re + (cdr field)))) + (cond ((not non-empty-alternative) + (setq non-empty-alternative t)) + ((memq 'required-fields format) + (error "More than one non-empty alternative."))))))) + (if (and alternatives-there (not non-empty-alternative) (memq 'required-fields format)) @@ -1832,18 +1844,23 @@ Formats current entry according to variable `bibtex-entry-format'." ;; quite some redundancy compared with what we need to do ;; anyway. So for speed-up we avoid using them. - (when (and opt-alt - (memq 'opts-or-alts format)) - (if empty-field - ;; Either it is an empty ALT field. Then we have checked - ;; already that we have one non-empty alternative. - ;; Or it is an empty OPT field that we do not miss anyway. - ;; So we can safely delete this field. - (progn (delete-region beg-field end-field) - (setq deleted t)) - ;; otherwise: not empty, delete "OPT" or "ALT" - (goto-char beg-name) - (delete-char 3))) + (if (memq 'opts-or-alts format) + (cond ((and empty-field + (or opt-alt + (let ((field (assoc-string + field-name req-field-list t))) + (or (not field) ; OPT field + (nth 3 field))))) ; ALT field + ;; Either it is an empty ALT field. Then we have checked + ;; already that we have one non-empty alternative. Or it + ;; is an empty OPT field that we do not miss anyway. + ;; So we can safely delete this field. + (delete-region beg-field end-field) + (setq deleted t)) + ;; otherwise: not empty, delete "OPT" or "ALT" + (opt-alt + (goto-char beg-name) + (delete-char 3)))) (unless deleted (push field-name field-list) @@ -1902,16 +1919,17 @@ Formats current entry according to variable `bibtex-entry-format'." ;; if empty field, complain (if (and empty-field (memq 'required-fields format) - (assoc-ignore-case field-name - (if crossref-key creq req))) + (assoc-string field-name req-field-list t)) (error "Mandatory field `%s' is empty" field-name)) ;; unify case of field name (if (memq 'unify-case format) - (let ((fname (car (assoc-ignore-case - field-name (append (nth 0 (nth 1 entry-list)) - (nth 1 (nth 1 entry-list)) - bibtex-user-optional-fields))))) + (let ((fname (car (assoc-string + field-name + (append (nth 0 (nth 1 entry-list)) + (nth 1 (nth 1 entry-list)) + bibtex-user-optional-fields) + t)))) (if fname (progn (delete-region beg-name end-name) @@ -1925,8 +1943,8 @@ Formats current entry according to variable `bibtex-entry-format'." ;; check whether all required fields are present (if (memq 'required-fields format) - (let (altlist (found 0)) - (dolist (fname (if crossref-key creq req)) + (let ((found 0) altlist) + (dolist (fname req-field-list) (if (nth 3 fname) (push (car fname) altlist)) (unless (or (member (car fname) field-list) @@ -1940,7 +1958,7 @@ Formats current entry according to variable `bibtex-entry-format'." (error "Alternative mandatory field `%s' is missing" altlist)) ((> found 1) - (error "Alternative fields `%s' is defined %s times" + (error "Alternative fields `%s' are defined %s times" altlist found)))))) ;; update point @@ -2051,8 +2069,8 @@ and return results as a list." (setq titlestring (substring titlestring 0 (match-beginning 0)))))) ;; gather words from titlestring into a list. Ignore ;; specific words and use only a specific amount of words. - (let (case-fold-search titlewords titlewords-extra titleword end-match - (counter 0)) + (let ((counter 0) + case-fold-search titlewords titlewords-extra titleword end-match) (while (and (or (not (numberp bibtex-autokey-titlewords)) (< counter (+ bibtex-autokey-titlewords bibtex-autokey-titlewords-stretch))) @@ -2079,10 +2097,14 @@ and return results as a list." "Do some abbreviations on TITLEWORD. The rules are defined in `bibtex-autokey-titleword-abbrevs' and `bibtex-autokey-titleword-length'." - (let ((abbrev (bibtex-assoc-of-regexp - titleword bibtex-autokey-titleword-abbrevs))) - (if abbrev - (cdr abbrev) + (let ((case-folde-search t) + (alist bibtex-autokey-titleword-abbrevs)) + (while (and alist + (not (string-match (concat "\\`\\(?:" (caar alist) "\\)\\'") + titleword))) + (setq alist (cdr alist))) + (if alist + (cdar alist) (bibtex-autokey-abbrev titleword bibtex-autokey-titleword-length)))) @@ -2239,8 +2261,8 @@ Return alist of keys if parsing was completed, `aborted' otherwise." ;; This is a crossref. (buffer-substring-no-properties (1+ (match-beginning 3)) (1- (match-end 3)))) - ((assoc-ignore-case (bibtex-type-in-head) - bibtex-entry-field-alist) + ((assoc-string (bibtex-type-in-head) + bibtex-entry-field-alist t) ;; This is an entry. (match-string-no-properties bibtex-key-in-head))))) (if (and (stringp key) @@ -2295,7 +2317,7 @@ Return alist of strings if parsing was completed, `aborted' otherwise." ;; user has aborted by typing a key --> return `aborted' (throw 'userkey 'aborted)) (setq key (bibtex-reference-key-in-string bounds)) - (if (not (assoc-ignore-case key strings)) + (if (not (assoc key strings)) (push (cons key (bibtex-text-in-string bounds t)) strings)) (goto-char (bibtex-end-of-text-in-string bounds))) @@ -2384,6 +2406,7 @@ of a word, all strings are listed. Return completion." (display-completion-list (all-completions part-of-word completions))) (message "Making completion list...done") + ;; return value is handled by choose-completion-string-functions nil)))) (defun bibtex-complete-string-cleanup (str) @@ -2629,6 +2652,34 @@ non-nil. (easy-menu-add bibtex-entry-menu) (run-hooks 'bibtex-mode-hook)) +(defun bibtex-field-list (entry-type) + "Return list of allowed fields for entry ENTRY-TYPE. +More specifically, the return value is a cons pair (REQUIRED . OPTIONAL), +where REQUIRED and OPTIONAL are lists of the required and optional field +names for ENTRY-TYPE according to `bibtex-entry-field-alist'." + (let ((e (assoc-string entry-type bibtex-entry-field-alist t)) + required optional) + (unless e + (error "Bibtex entry type %s not defined" entry-type)) + (if (and (member-ignore-case entry-type bibtex-include-OPTcrossref) + (nth 2 e)) + (setq required (nth 0 (nth 2 e)) + optional (nth 1 (nth 2 e))) + (setq required (nth 0 (nth 1 e)) + optional (nth 1 (nth 1 e)))) + (if bibtex-include-OPTkey + (push (list "key" + "Used for reference key creation if author and editor fields are missing" + (if (or (stringp bibtex-include-OPTkey) + (fboundp bibtex-include-OPTkey)) + bibtex-include-OPTkey)) + optional)) + (if (member-ignore-case entry-type bibtex-include-OPTcrossref) + (push '("crossref" "Reference key of the cross-referenced entry") + optional)) + (setq optional (append optional bibtex-user-optional-fields)) + (cons required optional))) + (defun bibtex-entry (entry-type) "Insert a new BibTeX entry. After 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'." bibtex-entry-field-alist nil t nil 'bibtex-entry-type-history))) (list e-t))) - (let* (required optional - (key (if bibtex-maintain-sorted-entries - (bibtex-read-key (format "%s key: " entry-type)))) - (e (assoc-ignore-case entry-type bibtex-entry-field-alist)) - (r-n-o (elt e 1)) - (c-ref (elt e 2))) - (if (not e) - (error "Bibtex entry type %s not defined" entry-type)) - (if (and (member entry-type bibtex-include-OPTcrossref) - c-ref) - (setq required (elt c-ref 0) - optional (elt c-ref 1)) - (setq required (elt r-n-o 0) - optional (elt r-n-o 1))) + (let ((key (if bibtex-maintain-sorted-entries + (bibtex-read-key (format "%s key: " entry-type)))) + (field-list (bibtex-field-list entry-type))) (unless (bibtex-prepare-new-entry (list key nil entry-type)) (error "Entry with key `%s' already exists" key)) (indent-to-column bibtex-entry-offset) (insert "@" entry-type (bibtex-entry-left-delimiter)) - (if key - (insert key)) + (if key (insert key)) (save-excursion - (mapcar 'bibtex-make-field required) - (if (member entry-type bibtex-include-OPTcrossref) - (bibtex-make-optional-field '("crossref"))) - (if bibtex-include-OPTkey - (if (or (stringp bibtex-include-OPTkey) - (fboundp bibtex-include-OPTkey)) - (bibtex-make-optional-field - (list "key" nil bibtex-include-OPTkey)) - (bibtex-make-optional-field '("key")))) - (mapcar 'bibtex-make-optional-field optional) - (mapcar 'bibtex-make-optional-field bibtex-user-optional-fields) + (mapcar 'bibtex-make-field (car field-list)) + (mapcar 'bibtex-make-optional-field (cdr field-list)) (if bibtex-comma-after-last-field (insert ",")) (insert "\n") @@ -2680,15 +2710,39 @@ After insertion it calls the functions in `bibtex-add-entry-hook'." (bibtex-autofill-entry)) (run-hooks 'bibtex-add-entry-hook))) +(defun bibtex-entry-update () + "Update an existing BibTeX entry. +In the BibTeX entry at point, make new fields for those items that may occur +according to `bibtex-entry-field-alist', but are not yet present." + (interactive) + (save-excursion + (bibtex-beginning-of-entry) + ;; For inserting new fields, we use the fact that + ;; bibtex-parse-entry moves point to the end of the last field. + (let* ((fields-alist (bibtex-parse-entry)) + (field-list (bibtex-field-list + (substring (cdr (assoc "=type=" fields-alist)) + 1))) ; don't want @ + (case-fold-search t)) + (dolist (field (car field-list)) + (unless (bibtex-assoc-regexp (concat "\\`\\(ALT\\)?" (car field) "\\'") + fields-alist) + (bibtex-make-field field))) + (dolist (field (cdr field-list)) + (unless (bibtex-assoc-regexp (concat "\\`\\(OPT\\)?" (car field) "\\'") + fields-alist) + (bibtex-make-optional-field field)))))) + (defun bibtex-parse-entry () "Parse entry at point, return an alist. The alist elements have the form (FIELD . TEXT), where FIELD can also be -the special strings \"=type=\" and \"=key=\"." +the special strings \"=type=\" and \"=key=\". For the FIELD \"=key=\" +TEXT may be nil. Move point to the end of the last field." (let (alist bounds) - (when (looking-at bibtex-entry-head) + (when (looking-at bibtex-entry-maybe-empty-head) (push (cons "=type=" (match-string bibtex-type-in-head)) alist) (push (cons "=key=" (match-string bibtex-key-in-head)) alist) - (goto-char (match-end bibtex-key-in-head)) + (goto-char (match-end 0)) (while (setq bounds (bibtex-parse-field bibtex-field-name)) (push (cons (bibtex-name-in-field bounds) (bibtex-text-in-field-bounds bounds)) @@ -2744,7 +2798,7 @@ the special strings \"=type=\" and \"=key=\"." (let* ((name (buffer-substring (if (looking-at "ALT\\|OPT") (match-end 0) (point)) (bibtex-end-of-name-in-field bounds))) - (text (assoc-ignore-case name other))) + (text (assoc-string name other t))) (goto-char (bibtex-start-of-text-in-field bounds)) (if (not (and (looking-at bibtex-empty-field-re) text)) (goto-char (bibtex-end-of-field bounds)) @@ -2774,28 +2828,15 @@ the special strings \"=type=\" and \"=key=\"." (looking-at "OPT\\|ALT")) (match-end 0) mb) (bibtex-end-of-name-in-field bounds))) - (entry-type (progn (re-search-backward - bibtex-entry-maybe-empty-head nil t) - (bibtex-type-in-head))) - (entry-list (assoc-ignore-case entry-type - bibtex-entry-field-alist)) - (c-r-list (elt entry-list 2)) - (req-opt-list (if (and (member entry-type - bibtex-include-OPTcrossref) - c-r-list) - c-r-list - (elt entry-list 1))) - (list-of-entries (append (elt req-opt-list 0) - (elt req-opt-list 1) - bibtex-user-optional-fields - (if (member entry-type - bibtex-include-OPTcrossref) - '(("crossref" "Reference key of the cross-referenced entry"))) - (if bibtex-include-OPTkey - '(("key" "Used for reference key creation if author and editor fields are missing"))))) - (comment (assoc-ignore-case field-name list-of-entries))) + (field-list (bibtex-field-list (progn (re-search-backward + bibtex-entry-maybe-empty-head nil t) + (bibtex-type-in-head)))) + (comment (assoc-string field-name + (append (car field-list) + (cdr field-list)) + t))) (if comment - (message (elt comment 1)) + (message (nth 1 comment)) (message "No comment available"))))) (defun bibtex-make-field (field &optional called-by-yank) @@ -2804,24 +2845,13 @@ FIELD is either a string or a list of the form \(FIELD-NAME COMMENT-STRING INIT ALTERNATIVE-FLAG) as in `bibtex-entry-field-alist'." (interactive - (list (let* ((entry-type - (save-excursion - (bibtex-enclosing-entry-maybe-empty-head) - (bibtex-type-in-head))) - ;; "preliminary" completion list - (fl (nth 1 (assoc-ignore-case - entry-type bibtex-entry-field-alist))) - ;; "full" completion list - (field-list (append (nth 0 fl) - (nth 1 fl) - bibtex-user-optional-fields - (if (member entry-type - bibtex-include-OPTcrossref) - '(("crossref"))) - (if bibtex-include-OPTkey - '(("key"))))) - (completion-ignore-case t)) - (completing-read "BibTeX field name: " field-list + (list (let ((completion-ignore-case t) + (field-list (bibtex-field-list + (save-excursion + (bibtex-enclosing-entry-maybe-empty-head) + (bibtex-type-in-head))))) + (completing-read "BibTeX field name: " + (append (car field-list) (cdr field-list)) nil nil nil bibtex-field-history)))) (unless (consp field) (setq field (list field))) @@ -2848,8 +2878,9 @@ FIELD is either a string or a list of the form ((fboundp init) (insert (funcall init))))) (if (not called-by-yank) (insert (bibtex-field-right-delimiter))) - (if (interactive-p) - (forward-char -1))) + (when (interactive-p) + (forward-char -1) + (bibtex-print-help-message))) (defun bibtex-beginning-of-entry () "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." "\\(OPT\\)?crossref" t))) (list key (if bounds (bibtex-text-in-field-bounds bounds t)) - entry-name)))) - (list key nil entry-name))))) + entry-name))) + (list key nil entry-name)))))) (defun bibtex-lessp (index1 index2) "Predicate for sorting BibTeX entries with indices INDEX1 and INDEX2. Each index is a list (KEY CROSSREF-KEY ENTRY-NAME). -The predicate depends on the variable `bibtex-maintain-sorted-entries'." +The predicate depends on the variable `bibtex-maintain-sorted-entries'. +If its value is nil use plain sorting." (cond ((not index1) (not index2)) ; indices can be nil ((not index2) nil) ((equal bibtex-maintain-sorted-entries 'crossref) @@ -3017,12 +3049,10 @@ The predicate depends on the variable `bibtex-maintain-sorted-entries'." (defun bibtex-sort-buffer () "Sort BibTeX buffer alphabetically by key. The predicate for sorting is defined via `bibtex-maintain-sorted-entries'. -Text outside of BibTeX entries is not affected. If -`bibtex-sort-ignore-string-entries' is non-nil, @String entries will be -ignored." +If its value is nil use plain sorting. Text outside of BibTeX entries is not +affected. If `bibtex-sort-ignore-string-entries' is non-nil, @String entries +will be ignored." (interactive) - (unless bibtex-maintain-sorted-entries - (error "You must choose a sorting scheme")) (save-restriction (narrow-to-region (bibtex-beginning-of-first-entry) (save-excursion (goto-char (point-max)) @@ -3212,8 +3242,8 @@ Returns t if test was successful, nil otherwise." (let* ((entry-list (progn (goto-char beg) (bibtex-search-entry nil end) - (assoc-ignore-case (bibtex-type-in-head) - bibtex-entry-field-alist))) + (assoc-string (bibtex-type-in-head) + bibtex-entry-field-alist t))) (req (copy-sequence (elt (elt entry-list 1) 0))) (creq (copy-sequence (elt (elt entry-list 2) 0))) crossref-there bounds) @@ -3229,8 +3259,8 @@ Returns t if test was successful, nil otherwise." (push (list (bibtex-current-line) "Questionable month field") error-list)) - (setq req (delete (assoc-ignore-case field-name req) req) - creq (delete (assoc-ignore-case field-name creq) creq)) + (setq req (delete (assoc-string field-name req t) req) + creq (delete (assoc-string field-name creq t) creq)) (if (equal field-name "crossref") (setq crossref-there t)))) (if crossref-there @@ -3523,27 +3553,30 @@ At end of the cleaning process, the functions in (match-end bibtex-key-in-head))) (insert key)) ;; sorting - (let* ((start (bibtex-beginning-of-entry)) - (end (progn (bibtex-end-of-entry) - (if (re-search-forward - bibtex-entry-maybe-empty-head nil 'move) - (goto-char (match-beginning 0))) - (point))) - (entry (buffer-substring start end)) - (index (progn (goto-char start) - (bibtex-entry-index)))) - (delete-region start end) - (unless (prog1 (or called-by-reformat - (if (and bibtex-maintain-sorted-entries - (not (and bibtex-sort-ignore-string-entries - (equal entry-type "string")))) - (bibtex-prepare-new-entry index) - (not (bibtex-find-entry (car index))))) - (insert entry) - (forward-char -1) - (bibtex-beginning-of-entry) ; moves backward - (re-search-forward bibtex-entry-head)) - (error "New inserted entry yields duplicate key"))) + (unless called-by-reformat + (let* ((start (bibtex-beginning-of-entry)) + (end (progn (bibtex-end-of-entry) + (if (re-search-forward + bibtex-entry-maybe-empty-head nil 'move) + (goto-char (match-beginning 0))) + (point))) + (entry (buffer-substring start end)) + (index (progn (goto-char start) + (bibtex-entry-index))) + no-error) + (if (and bibtex-maintain-sorted-entries + (not (and bibtex-sort-ignore-string-entries + (equal entry-type "string")))) + (progn + (delete-region start end) + (setq no-error (bibtex-prepare-new-entry index)) + (insert entry) + (forward-char -1) + (bibtex-beginning-of-entry) ; moves backward + (re-search-forward bibtex-entry-head)) + (setq no-error (bibtex-find-entry (car index)))) + (unless no-error + (error "New inserted entry yields duplicate key")))) ;; final clean up (unless called-by-reformat (save-excursion @@ -3621,91 +3654,89 @@ If `bibtex-align-at-equal-sign' is non-nil, align equal signs, too." (indent-to-column bibtex-entry-offset) (goto-char pnt))) -(defun bibtex-reformat (&optional additional-options called-by-convert-alien) +(defun bibtex-realign () + "Realign BibTeX entries such that they are separated by one blank line." + (goto-char (point-min)) + (let ((case-fold-search t)) + (when (looking-at bibtex-valid-entry-whitespace-re) + (replace-match "\\1")) + (while (re-search-forward bibtex-valid-entry-whitespace-re nil t) + (replace-match "\n\n\\1")))) + +(defun bibtex-reformat (&optional read-options) "Reformat all BibTeX entries in buffer or region. With prefix argument, read options for reformatting from minibuffer. With \\[universal-argument] \\[universal-argument] prefix argument, reuse previous answers (if any) again. -If mark is active it reformats entries in region, if not in whole buffer." +If mark is active reformat entries in region, if not in whole buffer." (interactive "*P") (let* ((pnt (point)) (use-previous-options - (and (equal (prefix-numeric-value additional-options) 16) + (and (equal (prefix-numeric-value read-options) 16) (or bibtex-reformat-previous-options bibtex-reformat-previous-reference-keys))) (bibtex-entry-format - (if additional-options + (if read-options (if use-previous-options bibtex-reformat-previous-options (setq bibtex-reformat-previous-options - (delq nil (list - (if (or called-by-convert-alien - (y-or-n-p "Realign entries (recommended)? ")) - 'realign) - (if (y-or-n-p "Remove empty optional and alternative fields? ") - 'opts-or-alts) - (if (y-or-n-p "Remove delimiters around pure numerical fields? ") - 'numerical-fields) - (if (y-or-n-p (concat (if bibtex-comma-after-last-field "Insert" "Remove") - " comma at end of entry? ")) - 'last-comma) - (if (y-or-n-p "Replace double page dashes by single ones? ") - 'page-dashes) - (if (y-or-n-p "Force delimiters? ") - 'delimiters) - (if (y-or-n-p "Unify case of entry types and field names? ") - 'unify-case))))) + (mapcar (lambda (option) + (if (y-or-n-p (car option)) (cdr option))) + `(("Realign entries (recommended)? " . 'realign) + ("Remove empty optional and alternative fields? " . 'opts-or-alts) + ("Remove delimiters around pure numerical fields? " . 'numerical-fields) + (,(concat (if bibtex-comma-after-last-field "Insert" "Remove") + " comma at end of entry? ") . 'last-comma) + ("Replace double page dashes by single ones? " . 'page-dashes) + ("Force delimiters? " . 'delimiters) + ("Unify case of entry types and field names? " . 'unify-case))))) '(realign))) - (reformat-reference-keys (if additional-options - (if use-previous-options - bibtex-reformat-previous-reference-keys - (setq bibtex-reformat-previous-reference-keys - (y-or-n-p "Generate new reference keys automatically? "))))) - bibtex-autokey-edit-before-use - (bibtex-sort-ignore-string-entries t) + (reformat-reference-keys + (if read-options + (if use-previous-options + bibtex-reformat-previous-reference-keys + (setq bibtex-reformat-previous-reference-keys + (y-or-n-p "Generate new reference keys automatically? "))))) (start-point (if (bibtex-mark-active) (region-beginning) - (bibtex-beginning-of-first-entry) - (bibtex-skip-to-valid-entry) - (point))) + (point-min))) (end-point (if (bibtex-mark-active) (region-end) - (point-max)))) + (point-max))) + (bibtex-sort-ignore-string-entries t) + bibtex-autokey-edit-before-use) + (save-restriction (narrow-to-region start-point end-point) - (when (memq 'realign bibtex-entry-format) - (goto-char (point-min)) - (while (re-search-forward bibtex-valid-entry-whitespace-re nil t) - (replace-match "\n\\1"))) + (if (memq 'realign bibtex-entry-format) + (bibtex-realign)) (goto-char start-point) (bibtex-progress-message "Formatting" 1) (bibtex-map-entries (lambda (key beg end) (bibtex-progress-message) - (bibtex-clean-entry reformat-reference-keys t) - (when (memq 'realign bibtex-entry-format) - (goto-char end) - (bibtex-delete-whitespace) - (open-line 2)))) + (bibtex-clean-entry reformat-reference-keys t))) + (when (memq 'realign bibtex-entry-format) + (bibtex-delete-whitespace) + (open-line (if (eobp) 1 2))) (bibtex-progress-message 'done)) (when (and reformat-reference-keys - bibtex-maintain-sorted-entries - (not called-by-convert-alien)) + bibtex-maintain-sorted-entries) + (bibtex-progress-message "Sorting" 1) (bibtex-sort-buffer) - (kill-local-variable 'bibtex-reference-keys)) + (kill-local-variable 'bibtex-reference-keys) + (bibtex-progress-message 'done)) (goto-char pnt))) -(defun bibtex-convert-alien (&optional do-additional-reformatting) +(defun bibtex-convert-alien (&optional read-options) "Convert an alien BibTeX buffer to be fully usable by BibTeX mode. -If a file does not conform with some standards used by BibTeX mode, +If a file does not conform with all standards used by BibTeX mode, some of the high-level features of BibTeX mode will not be available. This function tries to convert current buffer to conform with these standards. -With prefix argument DO-ADDITIONAL-REFORMATTING -non-nil, read options for reformatting entries from minibuffer." +With prefix argument READ-OPTIONS non-nil, read options for reformatting +entries from minibuffer." (interactive "*P") (message "Starting to validate buffer...") (sit-for 1 nil t) - (goto-char (point-min)) - (while (re-search-forward "[ \t\n]+@" nil t) - (replace-match "\n@")) + (bibtex-realign) (message "If errors occur, correct them and call `bibtex-convert-alien' again") (sit-for 5 nil t) @@ -3714,10 +3745,7 @@ non-nil, read options for reformatting entries from minibuffer." (bibtex-validate)) (message "Starting to reformat entries...") (sit-for 2 nil t) - (bibtex-reformat do-additional-reformatting t) - (when bibtex-maintain-sorted-entries - (message "Starting to sort buffer...") - (bibtex-sort-buffer)) + (bibtex-reformat read-options) (goto-char (point-max)) (message "Buffer is now parsable. Please save it."))) @@ -3890,5 +3918,5 @@ is outside key or BibTeX field." (provide 'bibtex) -;;; arch-tag: ee2be3af-caad-427f-b42a-d20fad630d04 +;; arch-tag: ee2be3af-caad-427f-b42a-d20fad630d04 ;;; 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 and `sentence-end-without-period'). Remove indentation from each line." (interactive "*r") - (let ((end-spc-re (concat "\\(" sentence-end "\\) *\\| +"))) + (let ((end-spc-re (concat "\\(" (sentence-end) "\\) *\\| +"))) (save-excursion (goto-char beg) ;; Nuke tabs; they get screwed up in a fill. @@ -349,7 +349,7 @@ and `fill-nobreak-invisible'." (save-excursion (skip-chars-backward ". ") (and (looking-at "\\.") - (not (looking-at sentence-end)))) + (not (looking-at (sentence-end))))) ;; Don't split a line if the rest would look like a new paragraph. (unless use-hard-newlines (save-excursion @@ -424,10 +424,10 @@ Point is moved to just past the fill prefix on the first line." ;; loses on split abbrevs ("Mr.\nSmith") (let ((eol-double-space-re (cond - ((not colon-double-space) (concat sentence-end "$")) + ((not colon-double-space) (concat (sentence-end) "$")) ;; Try to add the : inside the `sentence-end' regexp. - ((string-match "\\[[^][]*\\(\\.\\)[^][]*\\]" sentence-end) - (concat (replace-match ".:" nil nil sentence-end 1) "$")) + ((string-match "\\[[^][]*\\(\\.\\)[^][]*\\]" (sentence-end)) + (concat (replace-match ".:" nil nil (sentence-end) 1) "$")) ;; Can't find the right spot to insert the colon. (t "[.?!:][])}\"']*$"))) (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 @@ ;; Copyright (C) 1998, 2000, 2001, 2002 Free Software Foundation, Inc. ;; Author: Manuel Serrano <Manuel.Serrano@unice.fr> +;; Maintainer: FSF ;; Keywords: convenience ;; This file is part of GNU Emacs. @@ -1516,46 +1517,51 @@ for the overlay." ;*---------------------------------------------------------------------*/ (defun flyspell-highlight-incorrect-region (beg end poss) "Set up an overlay on a misspelled word, in the buffer from BEG to END." - (unless (run-hook-with-args-until-success - 'flyspell-incorrect-hook beg end poss) - (if (or flyspell-highlight-properties (not (flyspell-properties-at-p beg))) - (progn - ;; we cleanup current overlay at the same position - (if (and (not flyspell-persistent-highlight) - (overlayp flyspell-overlay)) - (delete-overlay flyspell-overlay) - (let ((overlays (overlays-at beg))) - (while (consp overlays) - (if (flyspell-overlay-p (car overlays)) - (delete-overlay (car overlays))) - (setq overlays (cdr overlays))))) - ;; now we can use a new overlay - (setq flyspell-overlay - (make-flyspell-overlay beg end - 'flyspell-incorrect-face - 'highlight)))))) + (let ((inhibit-read-only t)) + (unless (run-hook-with-args-until-success + 'flyspell-incorrect-hook beg end poss) + (if (or flyspell-highlight-properties + (not (flyspell-properties-at-p beg))) + (progn + ;; we cleanup current overlay at the same position + (if (and (not flyspell-persistent-highlight) + (overlayp flyspell-overlay)) + (delete-overlay flyspell-overlay) + (let ((overlays (overlays-at beg))) + (while (consp overlays) + (if (flyspell-overlay-p (car overlays)) + (delete-overlay (car overlays))) + (setq overlays (cdr overlays))))) + ;; now we can use a new overlay + (setq flyspell-overlay + (make-flyspell-overlay + beg end 'flyspell-incorrect-face 'highlight))))))) ;*---------------------------------------------------------------------*/ ;* flyspell-highlight-duplicate-region ... */ ;*---------------------------------------------------------------------*/ (defun flyspell-highlight-duplicate-region (beg end) "Set up an overlay on a duplicated word, in the buffer from BEG to END." - (if (or flyspell-highlight-properties (not (flyspell-properties-at-p beg))) - (progn - ;; we cleanup current overlay at the same position - (if (and (not flyspell-persistent-highlight) - (overlayp flyspell-overlay)) - (delete-overlay flyspell-overlay) - (let ((overlays (overlays-at beg))) - (while (consp overlays) - (if (flyspell-overlay-p (car overlays)) - (delete-overlay (car overlays))) - (setq overlays (cdr overlays))))) - ;; now we can use a new overlay - (setq flyspell-overlay - (make-flyspell-overlay beg end - 'flyspell-duplicate-face - 'highlight))))) + (let ((inhibit-read-only t)) + (unless (run-hook-with-args-until-success + 'flyspell-incorrect-hook beg end poss) + (if (or flyspell-highlight-properties + (not (flyspell-properties-at-p beg))) + (progn + ;; we cleanup current overlay at the same position + (if (and (not flyspell-persistent-highlight) + (overlayp flyspell-overlay)) + (delete-overlay flyspell-overlay) + (let ((overlays (overlays-at beg))) + (while (consp overlays) + (if (flyspell-overlay-p (car overlays)) + (delete-overlay (car overlays))) + (setq overlays (cdr overlays))))) + ;; now we can use a new overlay + (setq flyspell-overlay + (make-flyspell-overlay beg end + 'flyspell-duplicate-face + 'highlight))))))) ;*---------------------------------------------------------------------*/ ;* flyspell-auto-correct-cache ... */ @@ -2061,23 +2067,23 @@ possible corrections as returned by 'ispell-parse-output'. This function is meant to be added to 'flyspell-incorrect-hook'." (when (consp poss) - (let ((temp-buffer (get-buffer-create " *flyspell-temp*")) - found) - (save-excursion - (copy-to-buffer temp-buffer beg end) - (set-buffer temp-buffer) - (goto-char (1+ (point-min))) - (while (and (not (eobp)) (not found)) - (transpose-chars 1) - (if (member (buffer-string) (nth 2 poss)) - (setq found (point)) - (transpose-chars -1) - (forward-char)))) - (when found - (save-excursion - (goto-char (+ beg found -1)) - (transpose-chars -1) - t))))) + (catch 'done + (let ((str (buffer-substring beg end)) + (i 0) (len (- end beg)) tmp) + (while (< (1+ i) len) + (setq tmp (aref str i)) + (aset str i (aref str (1+ i))) + (aset str (1+ i) tmp) + (when (member str (nth 2 poss)) + (save-excursion + (goto-char (+ beg i 1)) + (transpose-chars 1)) + (throw 'done t)) + (setq tmp (aref str i)) + (aset str i (aref str (1+ i))) + (aset str (1+ i) tmp) + (setq i (1+ i)))) + nil))) (defun flyspell-maybe-correct-doubling (beg end poss) "Check replacements for doubled characters. @@ -2091,24 +2097,19 @@ possible corrections as returned by 'ispell-parse-output'. This function is meant to be added to 'flyspell-incorrect-hook'." (when (consp poss) - (let ((temp-buffer (get-buffer-create " *flyspell-temp*")) - found) - (save-excursion - (copy-to-buffer temp-buffer beg end) - (set-buffer temp-buffer) - (goto-char (1+ (point-min))) - (while (and (not (eobp)) (not found)) - (when (char-equal (char-after) (char-before)) - (delete-char 1) - (if (member (buffer-string) (nth 2 poss)) - (setq found (point)) - (insert-char (char-before) 1))) - (forward-char))) - (when found - (save-excursion - (goto-char (+ beg found -1)) - (delete-char 1) - t))))) + (catch 'done + (let ((str (buffer-substring beg end)) + (i 0) (len (- end beg))) + (while (< (1+ i) len) + (when (and (= (aref str i) (aref str (1+ i))) + (member (concat (substring str 0 (1+ i)) + (substring str (+ i 2))) + (nth 2 poss))) + (goto-char (+ beg i)) + (delete-char 1) + (throw 'done t)) + (setq i (1+ i)))) + nil))) ;*---------------------------------------------------------------------*/ ;* 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." (choice :tag "Coding system" (const iso-8859-1) (const iso-8859-2) - (const koi8-r)))) + (const koi8-r) + (const windows-1251)))) :group 'ispell) @@ -630,6 +631,10 @@ and then re-start emacs." "[\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]" "[^\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]" "" nil nil nil koi8-r) + ("russianw" ; russianw.aff (CP1251 charset) + "[\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]" + "[^\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]" + "" nil nil nil windows-1251) ("slovak" ; Slovakian "[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]" "[^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 (equal major-mode 'message-mode)) ;GNUS 5 (concat "In article <" "\\|" "[^,;&+=\n]+ <[^,;&+=]+> writes:" "\\|" - message-yank-prefix "\\|" + message-cite-prefix-regexp "\\|" default-prefix)) ((equal major-mode 'mh-letter-mode) ; mh mail message (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." This is relevant for filling. See also `sentence-end-without-period' and `colon-double-space'. -If you change this, you should also change `sentence-end'. See Info -node `Sentences'." +This value is used by the function `sentence-end' to construct the +regexp describing the end of a sentence, in case when the value of +the variable `sentence-end' is nil. See Info node `Sentences'." :type 'boolean :group 'fill) (defcustom sentence-end-without-period nil "*Non-nil means a sentence will end without a period. For example, a sentence in Thai text ends with double space but -without a period." +without a period. + +This value is used by the function `sentence-end' to construct the +regexp describing the end of a sentence, in case when the value of +the variable `sentence-end' is nil. See Info node `Sentences'." :type 'boolean :group 'fill) (defcustom sentence-end-without-space "$B!#!%!)!*$A!##.#?#!$(0!$!%!)!*$(G!$!%!)!*(B" "*String containing characters that end sentence without following spaces. -If you change this, you should also change `sentence-end'. See Info -node `Sentences'." + +This value is used by the function `sentence-end' to construct the +regexp describing the end of a sentence, in case when the value of +the variable `sentence-end' is nil. See Info node `Sentences'." :group 'paragraphs :type 'string) -(defcustom sentence-end - (purecopy - ;; This is a bit stupid since it's not auto-updated when the - ;; other variables are changes, but it's still useful info. - (concat (if sentence-end-without-period "\\w \\|") - "\\([.?!][]\"')}]*" - (if sentence-end-double-space - "\\($\\| $\\|\t\\| \\)" "\\($\\|[\t ]\\)") - "\\|[" sentence-end-without-space "]+\\)" - "[ \t\n]*")) +(defcustom sentence-end nil "*Regexp describing the end of a sentence. The value includes the whitespace following the sentence. All paragraph boundaries also end sentences, regardless. -The default value specifies that in order to be recognized as the end -of a sentence, the ending period, question mark, or exclamation point -must be followed by two spaces, unless it's inside some sort of quotes -or parenthesis. - -See also the variable `sentence-end-double-space', the variable -`sentence-end-without-period' and Info node `Sentences'." +The value nil means to use the default value defined by the +function `sentence-end'. You should always use this function +to obtain the value of this variable." :group 'paragraphs - :type 'regexp) + :type '(choice regexp (const :tag "Use default value" nil))) + +(defun sentence-end () + "Return the regexp describing the end of a sentence. + +This function returns either the value of the variable `sentence-end' +if it is non-nil, or the default value constructed from the +variables `sentence-end-double-space', `sentence-end-without-period' +and `sentence-end-without-space'. The default value specifies +that in order to be recognized as the end of a sentence, the +ending period, question mark, or exclamation point must be +followed by two spaces, unless it's inside some sort of quotes or +parenthesis. See Info node `Sentences'." + (or sentence-end + (concat (if sentence-end-without-period "\\w \\|") + "\\([.?!][]\"'\xd0c9\x5397d)}]*" + (if sentence-end-double-space + "\\($\\| $\\|\t\\| \\)" "\\($\\|[\t ]\\)") + "\\|[" sentence-end-without-space "]+\\)" + "[ \t\n]*"))) (defcustom page-delimiter "^\014" "*Regexp describing line-beginnings that separate pages." @@ -411,7 +424,8 @@ The variable `sentence-end' is a regular expression that matches ends of sentences. Also, every paragraph boundary terminates sentences as well." (interactive "p") (or arg (setq arg 1)) - (let ((opoint (point))) + (let ((opoint (point)) + (sentence-end (sentence-end))) (while (< arg 0) (let ((pos (point)) (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." (define-key picture-mode-map "\C-c`" 'picture-movement-nw) (define-key picture-mode-map "\C-c'" 'picture-movement-ne) (define-key picture-mode-map "\C-c/" 'picture-movement-sw) - (define-key picture-mode-map "\C-c\\" 'picture-movement-se))) + (define-key picture-mode-map "\C-c\\" 'picture-movement-se) + (define-key picture-mode-map [(control ?c) left] 'picture-movement-left) + (define-key picture-mode-map [(control ?c) right] 'picture-movement-right) + (define-key picture-mode-map [(control ?c) up] 'picture-movement-up) + (define-key picture-mode-map [(control ?c) down] 'picture-movement-down) + (define-key picture-mode-map [(control ?c) home] 'picture-movement-nw) + (define-key picture-mode-map [(control ?c) prior] 'picture-movement-ne) + (define-key picture-mode-map [(control ?c) end] 'picture-movement-sw) + (define-key picture-mode-map [(control ?c) next] 'picture-movement-se))) (defcustom picture-mode-hook nil "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 @@ ;;; table.el --- create and edit WYSIWYG text based embedded tables -;; Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc. +;; Copyright (C) 2000, 01, 02, 03, 04 Free Software Foundation, Inc. ;; Keywords: wp, convenience ;; Author: Takaaki Ota <Takaaki.Ota@am.sony.com> ;; Created: Sat Jul 08 2000 13:28:45 (PST) -;; Revised: Tue Dec 09 2003 14:36:50 (PST) +;; Revised: Tue Jun 01 2004 11:36:39 (PDT) ;; This file is part of GNU Emacs. @@ -1410,6 +1410,8 @@ the last cache point coordinate." end-of-buffer forward-word backward-word + forward-sentence + backward-sentence forward-paragraph backward-paragraph)) @@ -1434,9 +1436,18 @@ the last cache point coordinate." (cons (cons command func-symbol) table-command-remap-alist)))) '(kill-region + kill-ring-save delete-region copy-region-as-kill - kill-line)) + kill-line + kill-word + backward-kill-word + kill-sentence + backward-kill-sentence + kill-paragraph + backward-kill-paragraph + kill-sexp + backward-kill-sexp)) ;; Pasting Group (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." (or (null last-filename) (not (string-equal last-filename filename)))) (error-location - (save-excursion - (if (equal filename (concat tex-zap-file ".tex")) - (set-buffer tex-last-buffer-texed) - (set-buffer (find-file-noselect filename))) - (if new-file - (progn (goto-line linenum) (setq last-position nil)) - (goto-char last-position) - (forward-line (- linenum last-linenum))) - ;; first try a forward search for the error text, - ;; then a backward search limited by the last error. - (let ((starting-point (point))) - (or (re-search-forward error-text nil t) - (re-search-backward error-text last-position t) - (goto-char starting-point))) - (point-marker)))) + (with-current-buffer + (if (equal filename (concat tex-zap-file ".tex")) + tex-last-buffer-texed + (find-file-noselect filename)) + (save-excursion + (if new-file + (progn (goto-line linenum) (setq last-position nil)) + (goto-char last-position) + (forward-line (- linenum last-linenum))) + ;; first try a forward search for the error text, + ;; then a backward search limited by the last error. + (let ((starting-point (point))) + (or (re-search-forward error-text nil t) + (re-search-backward error-text last-position t) + (goto-char starting-point))) + (point-marker))))) (goto-char this-error) (if (and compilation-error-list (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." 1)) (symbol-value indexvar))))) -(defconst texinfo-indexvar-alist +(defvar texinfo-indexvar-alist '(("cp" . texinfo-cindex) ("fn" . texinfo-findex) ("vr" . texinfo-vindex) @@ -3032,7 +3032,7 @@ Default is to leave paragraph indentation as is." (indent-to 54) (insert (if (nth 2 (car indexelts)) - (format " %d." (nth 2 (car indexelts))) + (format " (line %3d)" (1+ (nth 2 (car indexelts)))) "") "\n")) ;; index entries from @include'd file |
