aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoland Winkler2008-01-09 01:37:50 +0000
committerRoland Winkler2008-01-09 01:37:50 +0000
commit65e10478884e9f4a3ed55d55c7545efab1c2e9cd (patch)
tree8b30e3bfbc7985f30e094af7cddfd59d21e7df5c
parent59ce725a3b68cbc324f01bc8dc5f9e07286431d1 (diff)
downloademacs-65e10478884e9f4a3ed55d55c7545efab1c2e9cd.tar.gz
emacs-65e10478884e9f4a3ed55d55c7545efab1c2e9cd.zip
(bibtex-initialize): New autoloaded command. Rename from function
bibtex-files-expand. New optional arg select. (bibtex-flash-head): Allow blink-matching-delay being zero. (bibtex-clean-entry): Use atomic-change-group. (bibtex-format-entry): Check presence of required fields only after formatting of fields. Use member-ignore-case. Do not use bibtex-parse-entry. Do not use booktitle field to set a missing title. (bibtex-autofill-entry): Do not call undo-boundary. (bibtex-lessp): Handle crossref keys that point to another bibtex file. (bibtex-sort-buffer, bibtex-prepare-new-entry, bibtex-validate): Parse keys if necessary.
-rw-r--r--lisp/ChangeLog17
-rw-r--r--lisp/textmodes/bibtex.el263
2 files changed, 154 insertions, 126 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index ae32b19e7b3..cc79ba3b156 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,20 @@
12008-01-08 Roland Winkler <Roland.Winkler@physik.uni-erlangen.de>
2
3 * textmodes/bibtex.el (bibtex-initialize): New autoloaded
4 command. Rename from function bibtex-files-expand. New optional
5 arg select.
6 (bibtex-flash-head): Allow blink-matching-delay being zero.
7 (bibtex-clean-entry): Use atomic-change-group.
8 (bibtex-format-entry): Check presence of required fields only
9 after formatting of fields. Use member-ignore-case. Do not use
10 bibtex-parse-entry. Do not use booktitle field to set a missing
11 title.
12 (bibtex-autofill-entry): Do not call undo-boundary.
13 (bibtex-lessp): Handle crossref keys that point to another bibtex
14 file.
15 (bibtex-sort-buffer, bibtex-prepare-new-entry, bibtex-validate):
16 Parse keys if necessary.
17
12008-01-08 Nick Roberts <nickrob@snap.net.nz> 182008-01-08 Nick Roberts <nickrob@snap.net.nz>
2 19
3 * progmodes/gdb-ui.el (gdb-var-list-children-1): Put varnum in 20 * progmodes/gdb-ui.el (gdb-var-list-children-1): Put varnum in
diff --git a/lisp/textmodes/bibtex.el b/lisp/textmodes/bibtex.el
index 9cdd3082168..1544e4fd24f 100644
--- a/lisp/textmodes/bibtex.el
+++ b/lisp/textmodes/bibtex.el
@@ -119,6 +119,7 @@ inherit-booktitle If entry contains a crossref field and the booktitle
119realign Realign entries, so that field texts and perhaps equal 119realign Realign entries, so that field texts and perhaps equal
120 signs (depending on the value of 120 signs (depending on the value of
121 `bibtex-align-at-equal-sign') begin in the same column. 121 `bibtex-align-at-equal-sign') begin in the same column.
122 Also fill fields.
122last-comma Add or delete comma on end of last field in entry, 123last-comma Add or delete comma on end of last field in entry,
123 according to value of `bibtex-comma-after-last-field'. 124 according to value of `bibtex-comma-after-last-field'.
124delimiters Change delimiters according to variables 125delimiters Change delimiters according to variables
@@ -1085,6 +1086,7 @@ Used by `bibtex-find-crossref' and for font-locking."
1085 "--" 1086 "--"
1086 ["Convert Alien Buffer" bibtex-convert-alien t]) 1087 ["Convert Alien Buffer" bibtex-convert-alien t])
1087 ("Operating on Multiple Buffers" 1088 ("Operating on Multiple Buffers"
1089 ["(Re)Initialize BibTeX Buffers" bibtex-initialize t]
1088 ["Validate Entries" bibtex-validate-globally t]))) 1090 ["Validate Entries" bibtex-validate-globally t])))
1089 1091
1090(easy-menu-define 1092(easy-menu-define
@@ -1782,7 +1784,7 @@ If FLAG is nil, a message is echoed if point was incremented at least
1782 ")")) 1784 ")"))
1783 1785
1784(defun bibtex-flash-head (prompt) 1786(defun bibtex-flash-head (prompt)
1785 "Flash at BibTeX entry head before point, if exists." 1787 "Flash at BibTeX entry head before point, if it exists."
1786 (let ((case-fold-search t) 1788 (let ((case-fold-search t)
1787 (pnt (point))) 1789 (pnt (point)))
1788 (save-excursion 1790 (save-excursion
@@ -1790,7 +1792,8 @@ If FLAG is nil, a message is echoed if point was incremented at least
1790 (when (and (looking-at bibtex-any-entry-maybe-empty-head) 1792 (when (and (looking-at bibtex-any-entry-maybe-empty-head)
1791 (< (point) pnt)) 1793 (< (point) pnt))
1792 (goto-char (match-beginning bibtex-type-in-head)) 1794 (goto-char (match-beginning bibtex-type-in-head))
1793 (if (pos-visible-in-window-p (point)) 1795 (if (and (< 0 blink-matching-delay)
1796 (pos-visible-in-window-p (point)))
1794 (sit-for blink-matching-delay) 1797 (sit-for blink-matching-delay)
1795 (message "%s%s" prompt (buffer-substring-no-properties 1798 (message "%s%s" prompt (buffer-substring-no-properties
1796 (point) (match-end bibtex-key-in-head)))))))) 1799 (point) (match-end bibtex-key-in-head))))))))
@@ -1875,38 +1878,42 @@ Optional arg COMMA is as in `bibtex-enclosing-field'."
1875(defun bibtex-format-entry () 1878(defun bibtex-format-entry ()
1876 "Helper function for `bibtex-clean-entry'. 1879 "Helper function for `bibtex-clean-entry'.
1877Formats current entry according to variable `bibtex-entry-format'." 1880Formats current entry according to variable `bibtex-entry-format'."
1881 ;; initialize `bibtex-field-braces-opt' if necessary
1882 (if (and bibtex-field-braces-alist (not bibtex-field-braces-opt))
1883 (setq bibtex-field-braces-opt
1884 (bibtex-field-re-init bibtex-field-braces-alist 'braces)))
1885 ;; initialize `bibtex-field-strings-opt' if necessary
1886 (if (and bibtex-field-strings-alist (not bibtex-field-strings-opt))
1887 (setq bibtex-field-strings-opt
1888 (bibtex-field-re-init bibtex-field-strings-alist 'strings)))
1889
1878 (save-excursion 1890 (save-excursion
1879 (save-restriction 1891 (save-restriction
1880 (bibtex-narrow-to-entry) 1892 (bibtex-narrow-to-entry)
1881 (let ((case-fold-search t) 1893 (let ((case-fold-search t)
1882 (format (if (eq bibtex-entry-format t) 1894 (format (if (eq bibtex-entry-format t)
1883 '(realign opts-or-alts required-fields 1895 '(realign opts-or-alts required-fields numerical-fields
1884 numerical-fields 1896 page-dashes whitespace inherit-booktitle
1885 last-comma page-dashes delimiters 1897 last-comma delimiters unify-case braces
1886 unify-case inherit-booktitle) 1898 strings)
1887 bibtex-entry-format)) 1899 bibtex-entry-format))
1888 crossref-key bounds alternatives-there non-empty-alternative 1900 bounds crossref-key req-field-list default-field-list field-list)
1889 entry-list req-field-list field-list) 1901
1890 1902 ;; There are more elegant high-level functions for several tasks
1891 ;; Initialize `bibtex-field-braces-opt' and `bibtex-field-strings-opt' 1903 ;; done by `bibtex-format-entry'. However, they contain some
1892 ;; if necessary. 1904 ;; redundancy compared with what we need to do anyway.
1893 (unless bibtex-field-braces-opt 1905 ;; So for speed-up we avoid using them.
1894 (setq bibtex-field-braces-opt 1906 ;; (`bibtex-format-entry' is called many times by `bibtex-reformat'.)
1895 (bibtex-field-re-init bibtex-field-braces-alist 'braces)))
1896 (unless bibtex-field-strings-opt
1897 (setq bibtex-field-strings-opt
1898 (bibtex-field-re-init bibtex-field-strings-alist 'strings)))
1899 1907
1900 ;; identify entry type 1908 ;; identify entry type
1901 (goto-char (point-min)) 1909 (goto-char (point-min))
1902 (or (re-search-forward bibtex-entry-type nil t) 1910 (or (re-search-forward bibtex-entry-type nil t)
1903 (error "Not inside a BibTeX entry")) 1911 (error "Not inside a BibTeX entry"))
1904 (let ((beg-type (1+ (match-beginning 0))) 1912 (let* ((beg-type (1+ (match-beginning 0)))
1905 (end-type (match-end 0))) 1913 (end-type (match-end 0))
1906 (setq entry-list (assoc-string (buffer-substring-no-properties 1914 (entry-list (assoc-string (buffer-substring-no-properties
1907 beg-type end-type) 1915 beg-type end-type)
1908 bibtex-entry-field-alist 1916 bibtex-entry-field-alist t)))
1909 t))
1910 1917
1911 ;; unify case of entry name 1918 ;; unify case of entry name
1912 (when (memq 'unify-case format) 1919 (when (memq 'unify-case format)
@@ -1918,35 +1925,24 @@ Formats current entry according to variable `bibtex-entry-format'."
1918 (goto-char end-type) 1925 (goto-char end-type)
1919 (skip-chars-forward " \t\n") 1926 (skip-chars-forward " \t\n")
1920 (delete-char 1) 1927 (delete-char 1)
1921 (insert (bibtex-entry-left-delimiter)))) 1928 (insert (bibtex-entry-left-delimiter)))
1922 1929
1923 ;; determine if entry has crossref field and if at least 1930 ;; Do we have a crossref key?
1924 ;; one alternative is non-empty 1931 (goto-char (point-min))
1925 (goto-char (point-min)) 1932 (if (setq bounds (bibtex-search-forward-field "crossref"))
1926 (let* ((fields-alist (bibtex-parse-entry t)) 1933 (let ((text (bibtex-text-in-field-bounds bounds t)))
1927 (field (assoc-string "crossref" fields-alist t))) 1934 (unless (equal "" text)
1928 (setq crossref-key (and field 1935 (setq crossref-key text))))
1929 (not (equal "" (cdr field))) 1936
1930 (cdr field)) 1937 ;; list of required fields appropriate for an entry with
1931 req-field-list (if crossref-key 1938 ;; or without crossref key.
1932 (nth 0 (nth 2 entry-list)) ; crossref part 1939 (setq req-field-list (if (and crossref-key (nth 2 entry-list))
1933 (nth 0 (nth 1 entry-list)))) ; required part 1940 (car (nth 2 entry-list))
1934 1941 (car (nth 1 entry-list)))
1935 (dolist (rfield req-field-list) 1942 ;; default list of fields that may appear in this entry
1936 (when (nth 3 rfield) ; we should have an alternative 1943 default-field-list (append (nth 0 (nth 1 entry-list))
1937 (setq alternatives-there t 1944 (nth 1 (nth 1 entry-list))
1938 field (assoc-string (car rfield) fields-alist t)) 1945 bibtex-user-optional-fields)))
1939 (if (and field
1940 (not (equal "" (cdr field))))
1941 (cond ((not non-empty-alternative)
1942 (setq non-empty-alternative t))
1943 ((memq 'required-fields format)
1944 (error "More than one non-empty alternative")))))))
1945
1946 (if (and alternatives-there
1947 (not non-empty-alternative)
1948 (memq 'required-fields format))
1949 (error "All alternatives are empty"))
1950 1946
1951 ;; process all fields 1947 ;; process all fields
1952 (bibtex-beginning-first-field (point-min)) 1948 (bibtex-beginning-first-field (point-min))
@@ -1965,25 +1961,18 @@ Formats current entry according to variable `bibtex-entry-format'."
1965 (empty-field (equal "" (bibtex-text-in-field-bounds bounds t))) 1961 (empty-field (equal "" (bibtex-text-in-field-bounds bounds t)))
1966 deleted) 1962 deleted)
1967 1963
1968 ;; We have more elegant high-level functions for several
1969 ;; tasks done by `bibtex-format-entry'. However, they contain
1970 ;; quite some redundancy compared with what we need to do
1971 ;; anyway. So for speed-up we avoid using them.
1972
1973 (if (memq 'opts-or-alts format) 1964 (if (memq 'opts-or-alts format)
1965 ;; delete empty optional and alternative fields
1966 ;; (but keep empty required fields)
1974 (cond ((and empty-field 1967 (cond ((and empty-field
1975 (or opt-alt 1968 (or opt-alt
1976 (let ((field (assoc-string 1969 (let ((field (assoc-string
1977 field-name req-field-list t))) 1970 field-name req-field-list t)))
1978 (or (not field) ; OPT field 1971 (or (not field) ; OPT field
1979 (nth 3 field))))) ; ALT field 1972 (nth 3 field))))) ; ALT field
1980 ;; Either it is an empty ALT field. Then we have checked
1981 ;; already that we have one non-empty alternative. Or it
1982 ;; is an empty OPT field that we do not miss anyway.
1983 ;; So we can safely delete this field.
1984 (delete-region beg-field end-field) 1973 (delete-region beg-field end-field)
1985 (setq deleted t)) 1974 (setq deleted t))
1986 ;; otherwise: not empty, delete "OPT" or "ALT" 1975 ;; otherwise nonempty field: delete "OPT" or "ALT"
1987 (opt-alt 1976 (opt-alt
1988 (goto-char beg-name) 1977 (goto-char beg-name)
1989 (delete-char 3)))) 1978 (delete-char 3))))
@@ -2087,16 +2076,7 @@ Formats current entry according to variable `bibtex-entry-format'."
2087 (goto-char (1+ beg-text)) 2076 (goto-char (1+ beg-text))
2088 (insert title)))) 2077 (insert title))))
2089 2078
2090 ;; Use booktitle to set a missing title. 2079 ;; if empty field is a required field, complain
2091 (if (and empty-field
2092 (bibtex-string= field-name "title"))
2093 (let ((booktitle (bibtex-text-in-field "booktitle")))
2094 (when booktitle
2095 (setq empty-field nil)
2096 (goto-char (1+ beg-text))
2097 (insert booktitle))))
2098
2099 ;; if empty field, complain
2100 (if (and empty-field 2080 (if (and empty-field
2101 (memq 'required-fields format) 2081 (memq 'required-fields format)
2102 (assoc-string field-name req-field-list t)) 2082 (assoc-string field-name req-field-list t))
@@ -2104,12 +2084,8 @@ Formats current entry according to variable `bibtex-entry-format'."
2104 2084
2105 ;; unify case of field name 2085 ;; unify case of field name
2106 (if (memq 'unify-case format) 2086 (if (memq 'unify-case format)
2107 (let ((fname (car (assoc-string 2087 (let ((fname (car (assoc-string field-name
2108 field-name 2088 default-field-list t))))
2109 (append (nth 0 (nth 1 entry-list))
2110 (nth 1 (nth 1 entry-list))
2111 bibtex-user-optional-fields)
2112 t))))
2113 (if fname 2089 (if fname
2114 (progn 2090 (progn
2115 (delete-region beg-name end-name) 2091 (delete-region beg-name end-name)
@@ -2123,23 +2099,21 @@ Formats current entry according to variable `bibtex-entry-format'."
2123 2099
2124 ;; check whether all required fields are present 2100 ;; check whether all required fields are present
2125 (if (memq 'required-fields format) 2101 (if (memq 'required-fields format)
2126 (let ((found 0) altlist) 2102 (let ((found 0) alt-list)
2127 (dolist (fname req-field-list) 2103 (dolist (fname req-field-list)
2128 (if (nth 3 fname) 2104 (cond ((nth 3 fname) ; t if field has alternative flag
2129 (push (car fname) altlist)) 2105 (push (car fname) alt-list)
2130 (unless (or (member (car fname) field-list) 2106 (if (member-ignore-case (car fname) field-list)
2131 (nth 3 fname)) 2107 (setq found (1+ found))))
2132 (error "Mandatory field `%s' is missing" (car fname)))) 2108 ((not (member-ignore-case (car fname) field-list))
2133 (when altlist 2109 (error "Mandatory field `%s' is missing" (car fname)))))
2134 (dolist (fname altlist) 2110 (if alt-list
2135 (if (member fname field-list) 2111 (cond ((= found 0)
2136 (setq found (1+ found)))) 2112 (error "Alternative mandatory field `%s' is missing"
2137 (cond ((= found 0) 2113 alt-list))
2138 (error "Alternative mandatory field `%s' is missing" 2114 ((> found 1)
2139 altlist)) 2115 (error "Alternative fields `%s' are defined %s times"
2140 ((> found 1) 2116 alt-list found))))))
2141 (error "Alternative fields `%s' are defined %s times"
2142 altlist found))))))
2143 2117
2144 ;; update comma after last field 2118 ;; update comma after last field
2145 (if (memq 'last-comma format) 2119 (if (memq 'last-comma format)
@@ -2158,7 +2132,7 @@ Formats current entry according to variable `bibtex-entry-format'."
2158 (delete-char 1) 2132 (delete-char 1)
2159 (insert (bibtex-entry-right-delimiter))) 2133 (insert (bibtex-entry-right-delimiter)))
2160 2134
2161 ;; fill entry 2135 ;; realign and fill entry
2162 (if (memq 'realign format) 2136 (if (memq 'realign format)
2163 (bibtex-fill-entry)))))) 2137 (bibtex-fill-entry))))))
2164 2138
@@ -2426,7 +2400,7 @@ Concatenate the key:
2426 (apply 'append 2400 (apply 'append
2427 (mapcar (lambda (buf) 2401 (mapcar (lambda (buf)
2428 (with-current-buffer buf bibtex-reference-keys)) 2402 (with-current-buffer buf bibtex-reference-keys))
2429 (bibtex-files-expand t))) 2403 (bibtex-initialize t)))
2430 bibtex-reference-keys)) 2404 bibtex-reference-keys))
2431 2405
2432(defun bibtex-read-key (prompt &optional key global) 2406(defun bibtex-read-key (prompt &optional key global)
@@ -2606,14 +2580,22 @@ Parsing initializes `bibtex-reference-keys' and `bibtex-strings'."
2606 (setq bibtex-buffer-last-parsed-tick (buffer-modified-tick))))) 2580 (setq bibtex-buffer-last-parsed-tick (buffer-modified-tick)))))
2607 (setq buffers (cdr buffers)))))) 2581 (setq buffers (cdr buffers))))))
2608 2582
2609(defun bibtex-files-expand (&optional current force) 2583;;;###autoload
2610 "Return an expanded list of BibTeX buffers based on `bibtex-files'. 2584(defun bibtex-initialize (&optional current force select)
2585 "(Re)Initialize BibTeX buffers.
2586Visit the BibTeX files defined by `bibtex-files' and return a list
2587of corresponding buffers.
2611Initialize in these buffers `bibtex-reference-keys' if not yet set. 2588Initialize in these buffers `bibtex-reference-keys' if not yet set.
2612List of BibTeX buffers includes current buffer if CURRENT is non-nil. 2589List of BibTeX buffers includes current buffer if CURRENT is non-nil.
2613If FORCE is non-nil, (re)initialize `bibtex-reference-keys' even if 2590If FORCE is non-nil, (re)initialize `bibtex-reference-keys' even if
2614already set." 2591already set. If SELECT is non-nil interactively select a BibTeX buffer.
2592When called interactively, FORCE is t, CURRENT is t if current buffer uses
2593`bibtex-mode', and SELECT is t if current buffer does not use `bibtex-mode',"
2594 (interactive (list (eq major-mode 'bibtex-mode) t
2595 (not (eq major-mode 'bibtex-mode))))
2615 (let ((file-path (split-string (or bibtex-file-path default-directory) ":+")) 2596 (let ((file-path (split-string (or bibtex-file-path default-directory) ":+"))
2616 file-list dir-list buffer-list) 2597 file-list dir-list buffer-list)
2598 ;; generate list of BibTeX files
2617 (dolist (file bibtex-files) 2599 (dolist (file bibtex-files)
2618 (cond ((eq file 'bibtex-file-path) 2600 (cond ((eq file 'bibtex-file-path)
2619 (setq dir-list (append dir-list file-path))) 2601 (setq dir-list (append dir-list file-path)))
@@ -2624,34 +2606,46 @@ already set."
2624 (file-name-absolute-p file)) 2606 (file-name-absolute-p file))
2625 (push file file-list)) 2607 (push file file-list))
2626 (t 2608 (t
2627 (let (fullfilename found) 2609 (let (expanded-file-name found)
2628 (dolist (dir file-path) 2610 (dolist (dir file-path)
2629 (when (file-readable-p 2611 (when (file-readable-p
2630 (setq fullfilename (expand-file-name file dir))) 2612 (setq expanded-file-name (expand-file-name file dir)))
2631 (push fullfilename file-list) 2613 (push expanded-file-name file-list)
2632 (setq found t))) 2614 (setq found t)))
2633 (unless found 2615 (unless found
2634 (error "File %s not in paths defined via bibtex-file-path" 2616 (error "File `%s' not in paths defined via bibtex-file-path"
2635 file)))))) 2617 file))))))
2636 (dolist (file file-list) 2618 (dolist (file file-list)
2637 (unless (file-readable-p file) 2619 (unless (file-readable-p file)
2638 (error "BibTeX file %s not found" file))) 2620 (error "BibTeX file `%s' not found" file)))
2639 ;; expand dir-list 2621 ;; expand dir-list
2640 (dolist (dir dir-list) 2622 (dolist (dir dir-list)
2641 (setq file-list 2623 (setq file-list
2642 (append file-list (directory-files dir t "\\.bib\\'" t)))) 2624 (append file-list (directory-files dir t "\\.bib\\'" t))))
2643 (delete-dups file-list) 2625 (delete-dups file-list)
2626 ;; visit files in FILE-LIST
2644 (dolist (file file-list) 2627 (dolist (file file-list)
2645 (when (file-readable-p file) 2628 (if (file-readable-p file)
2646 (push (find-file-noselect file) buffer-list) 2629 (push (find-file-noselect file) buffer-list)))
2647 (with-current-buffer (car buffer-list) 2630 ;; include current buffer iff we want it
2648 (if (or force (not (listp bibtex-reference-keys)))
2649 (bibtex-parse-keys)))))
2650 (cond ((and current (not (memq (current-buffer) buffer-list))) 2631 (cond ((and current (not (memq (current-buffer) buffer-list)))
2651 (push (current-buffer) buffer-list) 2632 (push (current-buffer) buffer-list))
2652 (if force (bibtex-parse-keys)))
2653 ((and (not current) (memq (current-buffer) buffer-list)) 2633 ((and (not current) (memq (current-buffer) buffer-list))
2654 (setq buffer-list (delq (current-buffer) buffer-list)))) 2634 (setq buffer-list (delq (current-buffer) buffer-list))))
2635 ;; parse keys
2636 (dolist (buffer buffer-list)
2637 (with-current-buffer buffer
2638 (if (or force (nlistp bibtex-reference-keys))
2639 (bibtex-parse-keys))))
2640 ;; select BibTeX buffer
2641 (if select
2642 (if buffer-list
2643 (switch-to-buffer
2644 (completing-read "Switch to BibTeX buffer: "
2645 (mapcar 'buffer-name buffer-list)
2646 nil t
2647 (if current (buffer-name (current-buffer)))))
2648 (message "No BibTeX buffers defined")))
2655 buffer-list)) 2649 buffer-list))
2656 2650
2657(defun bibtex-complete-internal (completions) 2651(defun bibtex-complete-internal (completions)
@@ -3130,7 +3124,6 @@ field contents of the neighboring entry. Finally try to update the text
3130based on the difference between the keys of the neighboring and the current 3124based on the difference between the keys of the neighboring and the current
3131entry (for example, the year parts of the keys)." 3125entry (for example, the year parts of the keys)."
3132 (interactive) 3126 (interactive)
3133 (undo-boundary) ;So you can easily undo it, if it didn't work right.
3134 (bibtex-beginning-of-entry) 3127 (bibtex-beginning-of-entry)
3135 (when (looking-at bibtex-entry-head) 3128 (when (looking-at bibtex-entry-head)
3136 (let ((type (bibtex-type-in-head)) 3129 (let ((type (bibtex-type-in-head))
@@ -3413,13 +3406,18 @@ If its value is nil use plain sorting."
3413 (cond ((not index1) (not index2)) ; indices can be nil 3406 (cond ((not index1) (not index2)) ; indices can be nil
3414 ((not index2) nil) 3407 ((not index2) nil)
3415 ((eq bibtex-maintain-sorted-entries 'crossref) 3408 ((eq bibtex-maintain-sorted-entries 'crossref)
3416 (if (nth 1 index1) 3409 ;; CROSSREF-KEY may be nil or it can point to an entry
3417 (if (nth 1 index2) 3410 ;; in another BibTeX file. In both cases we ignore CROSSREF-KEY.
3411 (if (and (nth 1 index1)
3412 (cdr (assoc-string (nth 1 index1) bibtex-reference-keys)))
3413 (if (and (nth 1 index2)
3414 (cdr (assoc-string (nth 1 index2) bibtex-reference-keys)))
3418 (or (string-lessp (nth 1 index1) (nth 1 index2)) 3415 (or (string-lessp (nth 1 index1) (nth 1 index2))
3419 (and (string-equal (nth 1 index1) (nth 1 index2)) 3416 (and (string-equal (nth 1 index1) (nth 1 index2))
3420 (string-lessp (nth 0 index1) (nth 0 index2)))) 3417 (string-lessp (nth 0 index1) (nth 0 index2))))
3421 (not (string-lessp (nth 0 index2) (nth 1 index1)))) 3418 (not (string-lessp (nth 0 index2) (nth 1 index1))))
3422 (if (nth 1 index2) 3419 (if (and (nth 1 index2)
3420 (cdr (assoc-string (nth 1 index2) bibtex-reference-keys)))
3423 (string-lessp (nth 0 index1) (nth 1 index2)) 3421 (string-lessp (nth 0 index1) (nth 1 index2))
3424 (string-lessp (nth 0 index1) (nth 0 index2))))) 3422 (string-lessp (nth 0 index1) (nth 0 index2)))))
3425 ((eq bibtex-maintain-sorted-entries 'entry-class) 3423 ((eq bibtex-maintain-sorted-entries 'entry-class)
@@ -3444,6 +3442,9 @@ are ignored."
3444 (interactive) 3442 (interactive)
3445 (bibtex-beginning-of-first-entry) ; Needed by `sort-subr' 3443 (bibtex-beginning-of-first-entry) ; Needed by `sort-subr'
3446 (bibtex-init-sort-entry-class-alist) ; Needed by `bibtex-lessp'. 3444 (bibtex-init-sort-entry-class-alist) ; Needed by `bibtex-lessp'.
3445 (if (and (eq bibtex-maintain-sorted-entries 'crossref)
3446 (nlistp bibtex-reference-keys))
3447 (bibtex-parse-keys)) ; Needed by `bibtex-lessp'.
3447 (sort-subr nil 3448 (sort-subr nil
3448 'bibtex-skip-to-valid-entry ; NEXTREC function 3449 'bibtex-skip-to-valid-entry ; NEXTREC function
3449 'bibtex-end-of-entry ; ENDREC function 3450 'bibtex-end-of-entry ; ENDREC function
@@ -3539,7 +3540,7 @@ Otherwise, use `set-buffer'. DISPLAY is t when called interactively."
3539 (interactive (list (bibtex-read-key "Find key: " nil current-prefix-arg) 3540 (interactive (list (bibtex-read-key "Find key: " nil current-prefix-arg)
3540 current-prefix-arg nil t)) 3541 current-prefix-arg nil t))
3541 (if (and global bibtex-files) 3542 (if (and global bibtex-files)
3542 (let ((buffer-list (bibtex-files-expand t)) 3543 (let ((buffer-list (bibtex-initialize t))
3543 buffer found) 3544 buffer found)
3544 (while (and (not found) 3545 (while (and (not found)
3545 (setq buffer (pop buffer-list))) 3546 (setq buffer (pop buffer-list)))
@@ -3581,6 +3582,9 @@ search to look for place for KEY. This requires that buffer is sorted,
3581see `bibtex-validate'. 3582see `bibtex-validate'.
3582Return t if preparation was successful or nil if entry KEY already exists." 3583Return t if preparation was successful or nil if entry KEY already exists."
3583 (bibtex-init-sort-entry-class-alist) ; Needed by `bibtex-lessp'. 3584 (bibtex-init-sort-entry-class-alist) ; Needed by `bibtex-lessp'.
3585 (if (and (eq bibtex-maintain-sorted-entries 'crossref)
3586 (nlistp bibtex-reference-keys))
3587 (bibtex-parse-keys)) ; Needed by `bibtex-lessp'.
3584 (let ((key (nth 0 index)) 3588 (let ((key (nth 0 index))
3585 key-exist) 3589 key-exist)
3586 (cond ((or (null key) 3590 (cond ((or (null key)
@@ -3671,6 +3675,9 @@ Return t if test was successful, nil otherwise."
3671 (setq syntax-error t) 3675 (setq syntax-error t)
3672 3676
3673 ;; Check for duplicate keys and correct sort order 3677 ;; Check for duplicate keys and correct sort order
3678 (bibtex-init-sort-entry-class-alist) ; Needed by `bibtex-lessp'.
3679 (bibtex-parse-keys) ; Possibly needed by `bibtex-lessp'.
3680 ; Always needed by subsequent global key check.
3674 (let (previous current key-list) 3681 (let (previous current key-list)
3675 (bibtex-progress-message "Checking for duplicate keys") 3682 (bibtex-progress-message "Checking for duplicate keys")
3676 (bibtex-map-entries 3683 (bibtex-map-entries
@@ -3692,9 +3699,12 @@ Return t if test was successful, nil otherwise."
3692 (bibtex-progress-message 'done)) 3699 (bibtex-progress-message 'done))
3693 3700
3694 ;; Check for duplicate keys in `bibtex-files'. 3701 ;; Check for duplicate keys in `bibtex-files'.
3695 (bibtex-parse-keys) 3702 ;; `bibtex-validate' only compares keys in current buffer with keys
3703 ;; in `bibtex-files'. `bibtex-validate-globally' compares keys for
3704 ;; each file in `bibtex-files' with keys of all other files in
3705 ;; `bibtex-files'.
3696 ;; We don't want to be fooled by outdated `bibtex-reference-keys'. 3706 ;; We don't want to be fooled by outdated `bibtex-reference-keys'.
3697 (dolist (buffer (bibtex-files-expand nil t)) 3707 (dolist (buffer (bibtex-initialize nil t))
3698 (dolist (key (with-current-buffer buffer bibtex-reference-keys)) 3708 (dolist (key (with-current-buffer buffer bibtex-reference-keys))
3699 (when (and (cdr key) 3709 (when (and (cdr key)
3700 (cdr (assoc-string (car key) bibtex-reference-keys))) 3710 (cdr (assoc-string (car key) bibtex-reference-keys)))
@@ -3792,7 +3802,7 @@ Return t if test was successful, nil otherwise."
3792With optional prefix arg STRINGS, check for duplicate strings, too. 3802With optional prefix arg STRINGS, check for duplicate strings, too.
3793Return t if test was successful, nil otherwise." 3803Return t if test was successful, nil otherwise."
3794 (interactive "P") 3804 (interactive "P")
3795 (let ((buffer-list (bibtex-files-expand t)) 3805 (let ((buffer-list (bibtex-initialize t))
3796 buffer-key-list current-buf current-keys error-list) 3806 buffer-key-list current-buf current-keys error-list)
3797 ;; Check for duplicate keys within BibTeX buffer 3807 ;; Check for duplicate keys within BibTeX buffer
3798 (dolist (buffer buffer-list) 3808 (dolist (buffer buffer-list)
@@ -4133,14 +4143,15 @@ At end of the cleaning process, the functions in
4133 (error "Not inside a BibTeX entry"))) 4143 (error "Not inside a BibTeX entry")))
4134 (entry-type (bibtex-type-in-head)) 4144 (entry-type (bibtex-type-in-head))
4135 (key (bibtex-key-in-head))) 4145 (key (bibtex-key-in-head)))
4136 ;; formatting 4146 ;; formatting (undone if error occurs)
4137 (cond ((bibtex-string= entry-type "preamble") 4147 (atomic-change-group
4138 ;; (bibtex-format-preamble) 4148 (cond ((bibtex-string= entry-type "preamble")
4139 (error "No clean up of @Preamble entries")) 4149 ;; (bibtex-format-preamble)
4140 ((bibtex-string= entry-type "string") 4150 (error "No clean up of @Preamble entries"))
4141 (setq entry-type 'string)) 4151 ((bibtex-string= entry-type "string")
4142 ;; (bibtex-format-string) 4152 (setq entry-type 'string))
4143 (t (bibtex-format-entry))) 4153 ;; (bibtex-format-string)
4154 (t (bibtex-format-entry))))
4144 ;; set key 4155 ;; set key
4145 (when (or new-key (not key)) 4156 (when (or new-key (not key))
4146 (setq key (bibtex-generate-autokey)) 4157 (setq key (bibtex-generate-autokey))
@@ -4184,7 +4195,7 @@ At end of the cleaning process, the functions in
4184 (bibtex-find-entry key nil end)))) 4195 (bibtex-find-entry key nil end))))
4185 (if error 4196 (if error
4186 (error "New inserted entry yields duplicate key")) 4197 (error "New inserted entry yields duplicate key"))
4187 (dolist (buffer (bibtex-files-expand)) 4198 (dolist (buffer (bibtex-initialize))
4188 (with-current-buffer buffer 4199 (with-current-buffer buffer
4189 (if (cdr (assoc-string key bibtex-reference-keys)) 4200 (if (cdr (assoc-string key bibtex-reference-keys))
4190 (error "Duplicate key in %s" (buffer-file-name))))) 4201 (error "Duplicate key in %s" (buffer-file-name)))))