aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/textmodes/bibtex.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/textmodes/bibtex.el')
-rw-r--r--lisp/textmodes/bibtex.el566
1 files changed, 297 insertions, 269 deletions
diff --git a/lisp/textmodes/bibtex.el b/lisp/textmodes/bibtex.el
index 82b15cf4eb5..15348205c51 100644
--- a/lisp/textmodes/bibtex.el
+++ b/lisp/textmodes/bibtex.el
@@ -1,6 +1,7 @@
1;;; bibtex.el --- BibTeX mode for GNU Emacs 1;;; bibtex.el --- BibTeX mode for GNU Emacs
2 2
3;; Copyright (C) 1992,94,95,96,97,98,1999,2003 Free Software Foundation, Inc. 3;; Copyright (C) 1992,94,95,96,97,98,1999,2003,2004
4;; Free Software Foundation, Inc.
4 5
5;; Author: Stefan Schoef <schoef@offis.uni-oldenburg.de> 6;; Author: Stefan Schoef <schoef@offis.uni-oldenburg.de>
6;; Bengt Martensson <bengt@mathematik.uni-Bremen.de> 7;; Bengt Martensson <bengt@mathematik.uni-Bremen.de>
@@ -811,6 +812,7 @@ If non-nil, the column for the equal sign is the value of
811 (define-key km "\C-c\M-y" 'bibtex-yank-pop) 812 (define-key km "\C-c\M-y" 'bibtex-yank-pop)
812 (define-key km "\C-c\C-d" 'bibtex-empty-field) 813 (define-key km "\C-c\C-d" 'bibtex-empty-field)
813 (define-key km "\C-c\C-f" 'bibtex-make-field) 814 (define-key km "\C-c\C-f" 'bibtex-make-field)
815 (define-key km "\C-c\C-u" 'bibtex-entry-update)
814 (define-key km "\C-c$" 'bibtex-ispell-abstract) 816 (define-key km "\C-c$" 'bibtex-ispell-abstract)
815 (define-key km "\M-\C-a" 'bibtex-beginning-of-entry) 817 (define-key km "\M-\C-a" 'bibtex-beginning-of-entry)
816 (define-key km "\M-\C-e" 'bibtex-end-of-entry) 818 (define-key km "\M-\C-e" 'bibtex-end-of-entry)
@@ -1122,44 +1124,6 @@ function `bibtex-parse-field-name'.")
1122 '(bibtex-mode "@\\S(*\\s(" "\\s)" nil bibtex-hs-forward-sexp nil)) 1124 '(bibtex-mode "@\\S(*\\s(" "\\s)" nil bibtex-hs-forward-sexp nil))
1123 1125
1124 1126
1125(defconst bibtex-braced-string-syntax-table
1126 (let ((st (make-syntax-table)))
1127 (modify-syntax-entry ?\{ "(}" st)
1128 (modify-syntax-entry ?\} "){" st)
1129 (modify-syntax-entry ?\[ "." st)
1130 (modify-syntax-entry ?\] "." st)
1131 (modify-syntax-entry ?\( "." st)
1132 (modify-syntax-entry ?\) "." st)
1133 (modify-syntax-entry ?\\ "." st)
1134 (modify-syntax-entry ?\" "." st)
1135 st)
1136 "Syntax-table to parse matched braces.")
1137
1138(defconst bibtex-quoted-string-syntax-table
1139 (let ((st (make-syntax-table)))
1140 (modify-syntax-entry ?\\ "\\" st)
1141 (modify-syntax-entry ?\" "\"" st)
1142 st)
1143 "Syntax-table to parse matched quotes.")
1144
1145(defun bibtex-parse-field-string ()
1146 "Parse a field string enclosed by braces or quotes.
1147If a syntactically correct string is found, a pair containing the start and
1148end position of the field string is returned, nil otherwise."
1149 (let ((end-point
1150 (or (and (eq (following-char) ?\")
1151 (save-excursion
1152 (with-syntax-table bibtex-quoted-string-syntax-table
1153 (forward-sexp 1))
1154 (point)))
1155 (and (eq (following-char) ?\{)
1156 (save-excursion
1157 (with-syntax-table bibtex-braced-string-syntax-table
1158 (forward-sexp 1))
1159 (point))))))
1160 (if end-point
1161 (cons (point) end-point))))
1162
1163(defun bibtex-parse-association (parse-lhs parse-rhs) 1127(defun bibtex-parse-association (parse-lhs parse-rhs)
1164 "Parse a string of the format <left-hand-side = right-hand-side>. 1128 "Parse a string of the format <left-hand-side = right-hand-side>.
1165The functions PARSE-LHS and PARSE-RHS are used to parse the corresponding 1129The functions PARSE-LHS and PARSE-RHS are used to parse the corresponding
@@ -1199,6 +1163,44 @@ BibTeX field as necessary."
1199 ;; Now try again. 1163 ;; Now try again.
1200 (bibtex-parse-field-name)))) 1164 (bibtex-parse-field-name))))
1201 1165
1166(defconst bibtex-braced-string-syntax-table
1167 (let ((st (make-syntax-table)))
1168 (modify-syntax-entry ?\{ "(}" st)
1169 (modify-syntax-entry ?\} "){" st)
1170 (modify-syntax-entry ?\[ "." st)
1171 (modify-syntax-entry ?\] "." st)
1172 (modify-syntax-entry ?\( "." st)
1173 (modify-syntax-entry ?\) "." st)
1174 (modify-syntax-entry ?\\ "." st)
1175 (modify-syntax-entry ?\" "." st)
1176 st)
1177 "Syntax-table to parse matched braces.")
1178
1179(defconst bibtex-quoted-string-syntax-table
1180 (let ((st (make-syntax-table)))
1181 (modify-syntax-entry ?\\ "\\" st)
1182 (modify-syntax-entry ?\" "\"" st)
1183 st)
1184 "Syntax-table to parse matched quotes.")
1185
1186(defun bibtex-parse-field-string ()
1187 "Parse a field string enclosed by braces or quotes.
1188If a syntactically correct string is found, a pair containing the start and
1189end position of the field string is returned, nil otherwise."
1190 (let ((end-point
1191 (or (and (eq (following-char) ?\")
1192 (save-excursion
1193 (with-syntax-table bibtex-quoted-string-syntax-table
1194 (forward-sexp 1))
1195 (point)))
1196 (and (eq (following-char) ?\{)
1197 (save-excursion
1198 (with-syntax-table bibtex-braced-string-syntax-table
1199 (forward-sexp 1))
1200 (point))))))
1201 (if end-point
1202 (cons (point) end-point))))
1203
1202(defun bibtex-parse-field-text () 1204(defun bibtex-parse-field-text ()
1203 "Parse the text part of a BibTeX field. 1205 "Parse the text part of a BibTeX field.
1204The text part is either a string, or an empty string, or a constant followed 1206The text part is either a string, or an empty string, or a constant followed
@@ -1410,7 +1412,7 @@ delimiters if present."
1410 (let ((content (buffer-substring-no-properties (nth 0 (cdr bounds)) 1412 (let ((content (buffer-substring-no-properties (nth 0 (cdr bounds))
1411 (nth 1 (cdr bounds))))) 1413 (nth 1 (cdr bounds)))))
1412 (if (and remove-delim 1414 (if (and remove-delim
1413 (string-match "\\`{\\(.*\\)}\\'" content)) 1415 (string-match "\\`[{\"]\\(.*\\)[}\"]\\'" content))
1414 (substring content (match-beginning 1) (match-end 1)) 1416 (substring content (match-beginning 1) (match-end 1))
1415 content))) 1417 content)))
1416 1418
@@ -1455,16 +1457,6 @@ The value is actually the tail of LIST whose car matches STRING."
1455 (setq list (cdr list))) 1457 (setq list (cdr list)))
1456 list)) 1458 list))
1457 1459
1458(defun bibtex-assoc-of-regexp (string alist)
1459 "Return non-nil if STRING is exactly matched by the car of an
1460element of ALIST (case ignored). The value is actually the element
1461of LIST whose car matches STRING."
1462 (let ((case-fold-search t))
1463 (while (and alist
1464 (not (string-match (concat "\\`\\(?:" (caar alist) "\\)\\'") string)))
1465 (setq alist (cdr alist)))
1466 (car alist)))
1467
1468(defun bibtex-skip-to-valid-entry (&optional backward) 1460(defun bibtex-skip-to-valid-entry (&optional backward)
1469 "Unless at beginning of a valid BibTeX entry, move point to beginning of the 1461 "Unless at beginning of a valid BibTeX entry, move point to beginning of the
1470next valid one. With optional argument BACKWARD non-nil, move backward to 1462next valid one. With optional argument BACKWARD non-nil, move backward to
@@ -1510,7 +1502,7 @@ FUN will not be called for @String entries."
1510 (save-excursion 1502 (save-excursion
1511 (if (or (and (not bibtex-sort-ignore-string-entries) 1503 (if (or (and (not bibtex-sort-ignore-string-entries)
1512 (string-equal "string" (downcase entry-type))) 1504 (string-equal "string" (downcase entry-type)))
1513 (assoc-ignore-case entry-type bibtex-entry-field-alist)) 1505 (assoc-string entry-type bibtex-entry-field-alist t))
1514 (funcall fun key beg end))) 1506 (funcall fun key beg end)))
1515 (goto-char end))))) 1507 (goto-char end)))))
1516 1508
@@ -1519,8 +1511,8 @@ FUN will not be called for @String entries."
1519If FLAG is a string, the message is initialized (in this case a 1511If FLAG is a string, the message is initialized (in this case a
1520value for INTERVAL may be given as well (if not this is set to 5)). 1512value for INTERVAL may be given as well (if not this is set to 5)).
1521If FLAG is done, the message is deinitialized. 1513If FLAG is done, the message is deinitialized.
1522If FLAG is absent, a message is echoed if point was incremented 1514If FLAG is nil, a message is echoed if point was incremented at least
1523at least INTERVAL percent since last message was echoed." 1515`bibtex-progress-interval' percent since last message was echoed."
1524 (cond ((stringp flag) 1516 (cond ((stringp flag)
1525 (setq bibtex-progress-lastmes flag) 1517 (setq bibtex-progress-lastmes flag)
1526 (setq bibtex-progress-interval (or interval 5) 1518 (setq bibtex-progress-interval (or interval 5)
@@ -1685,11 +1677,11 @@ are defined, but only for the head part of the entry
1685 "Try to avoid point being at end of a BibTeX field." 1677 "Try to avoid point being at end of a BibTeX field."
1686 (end-of-line) 1678 (end-of-line)
1687 (skip-chars-backward " \t") 1679 (skip-chars-backward " \t")
1688 (cond ((= (preceding-char) ?,) 1680 (if (= (preceding-char) ?,)
1689 (forward-char -2))) 1681 (forward-char -2))
1690 (cond ((or (= (preceding-char) ?}) 1682 (if (or (= (preceding-char) ?})
1691 (= (preceding-char) ?\")) 1683 (= (preceding-char) ?\"))
1692 (forward-char -1)))) 1684 (forward-char -1)))
1693 1685
1694(defun bibtex-enclosing-field (&optional noerr) 1686(defun bibtex-enclosing-field (&optional noerr)
1695 "Search for BibTeX field enclosing point. Point moves to end of field. 1687 "Search for BibTeX field enclosing point. Point moves to end of field.
@@ -1749,6 +1741,15 @@ Beginning (but not end) of entry is given by (`match-beginning' 0)."
1749 (error "Unknown tag field: %s. Please submit a bug report" 1741 (error "Unknown tag field: %s. Please submit a bug report"
1750 bibtex-last-kill-command)))))) 1742 bibtex-last-kill-command))))))
1751 1743
1744(defun bibtex-assoc-regexp (regexp alist)
1745 "Return non-nil if REGEXP matches the car of an element of ALIST.
1746The value is actually the element of ALIST matched by REGEXP.
1747Case is ignored if `case-fold-search' is non-nil in the current buffer."
1748 (while (and alist
1749 (not (string-match regexp (caar alist))))
1750 (setq alist (cdr alist)))
1751 (car alist))
1752
1752(defun bibtex-format-entry () 1753(defun bibtex-format-entry ()
1753 "Helper function for `bibtex-clean-entry'. 1754 "Helper function for `bibtex-clean-entry'.
1754Formats current entry according to variable `bibtex-entry-format'." 1755Formats current entry according to variable `bibtex-entry-format'."
@@ -1763,18 +1764,17 @@ Formats current entry according to variable `bibtex-entry-format'."
1763 unify-case inherit-booktitle) 1764 unify-case inherit-booktitle)
1764 bibtex-entry-format)) 1765 bibtex-entry-format))
1765 crossref-key bounds alternatives-there non-empty-alternative 1766 crossref-key bounds alternatives-there non-empty-alternative
1766 entry-list req creq field-done field-list) 1767 entry-list req-field-list field-done field-list)
1767 1768
1768 ;; identify entry type 1769 ;; identify entry type
1769 (goto-char (point-min)) 1770 (goto-char (point-min))
1770 (re-search-forward bibtex-entry-type) 1771 (re-search-forward bibtex-entry-type)
1771 (let ((beg-type (1+ (match-beginning 0))) 1772 (let ((beg-type (1+ (match-beginning 0)))
1772 (end-type (match-end 0))) 1773 (end-type (match-end 0)))
1773 (setq entry-list (assoc-ignore-case (buffer-substring-no-properties 1774 (setq entry-list (assoc-string (buffer-substring-no-properties
1774 beg-type end-type) 1775 beg-type end-type)
1775 bibtex-entry-field-alist) 1776 bibtex-entry-field-alist
1776 req (nth 0 (nth 1 entry-list)) ; required part 1777 t))
1777 creq (nth 0 (nth 2 entry-list))) ; crossref part
1778 1778
1779 ;; unify case of entry name 1779 ;; unify case of entry name
1780 (when (memq 'unify-case format) 1780 (when (memq 'unify-case format)
@@ -1791,20 +1791,32 @@ Formats current entry according to variable `bibtex-entry-format'."
1791 ;; determine if entry has crossref field and if at least 1791 ;; determine if entry has crossref field and if at least
1792 ;; one alternative is non-empty 1792 ;; one alternative is non-empty
1793 (goto-char (point-min)) 1793 (goto-char (point-min))
1794 (while (setq bounds (bibtex-search-forward-field 1794 (let* ((fields-alist (bibtex-parse-entry))
1795 bibtex-field-name)) 1795 (case-fold-search t)
1796 (goto-char (bibtex-start-of-name-in-field bounds)) 1796 (field (bibtex-assoc-regexp "\\`\\(OPT\\)?crossref\\'"
1797 (cond ((looking-at "ALT") 1797 fields-alist)))
1798 (setq alternatives-there t) 1798 (setq crossref-key (and field
1799 (goto-char (bibtex-start-of-text-in-field bounds)) 1799 (not (string-match bibtex-empty-field-re
1800 (if (not (looking-at bibtex-empty-field-re)) 1800 (cdr field)))
1801 (setq non-empty-alternative t))) 1801 (cdr field))
1802 ((and (looking-at "\\(OPT\\)?crossref\\>") 1802 req-field-list (if crossref-key
1803 (progn (goto-char (bibtex-start-of-text-in-field bounds)) 1803 (nth 0 (nth 2 entry-list)) ; crossref part
1804 (not (looking-at bibtex-empty-field-re)))) 1804 (nth 0 (nth 1 entry-list)))) ; required part
1805 (setq crossref-key 1805
1806 (bibtex-text-in-field-bounds bounds t)))) 1806 (dolist (rfield req-field-list)
1807 (goto-char (bibtex-end-of-field bounds))) 1807 (when (nth 3 rfield) ; we should have an alternative
1808 (setq alternatives-there t
1809 field (bibtex-assoc-regexp
1810 (concat "\\`\\(ALT\\)?" (car rfield) "\\'")
1811 fields-alist))
1812 (if (and field
1813 (not (string-match bibtex-empty-field-re
1814 (cdr field))))
1815 (cond ((not non-empty-alternative)
1816 (setq non-empty-alternative t))
1817 ((memq 'required-fields format)
1818 (error "More than one non-empty alternative.")))))))
1819
1808 (if (and alternatives-there 1820 (if (and alternatives-there
1809 (not non-empty-alternative) 1821 (not non-empty-alternative)
1810 (memq 'required-fields format)) 1822 (memq 'required-fields format))
@@ -1832,18 +1844,23 @@ Formats current entry according to variable `bibtex-entry-format'."
1832 ;; quite some redundancy compared with what we need to do 1844 ;; quite some redundancy compared with what we need to do
1833 ;; anyway. So for speed-up we avoid using them. 1845 ;; anyway. So for speed-up we avoid using them.
1834 1846
1835 (when (and opt-alt 1847 (if (memq 'opts-or-alts format)
1836 (memq 'opts-or-alts format)) 1848 (cond ((and empty-field
1837 (if empty-field 1849 (or opt-alt
1838 ;; Either it is an empty ALT field. Then we have checked 1850 (let ((field (assoc-string
1839 ;; already that we have one non-empty alternative. 1851 field-name req-field-list t)))
1840 ;; Or it is an empty OPT field that we do not miss anyway. 1852 (or (not field) ; OPT field
1841 ;; So we can safely delete this field. 1853 (nth 3 field))))) ; ALT field
1842 (progn (delete-region beg-field end-field) 1854 ;; Either it is an empty ALT field. Then we have checked
1843 (setq deleted t)) 1855 ;; already that we have one non-empty alternative. Or it
1844 ;; otherwise: not empty, delete "OPT" or "ALT" 1856 ;; is an empty OPT field that we do not miss anyway.
1845 (goto-char beg-name) 1857 ;; So we can safely delete this field.
1846 (delete-char 3))) 1858 (delete-region beg-field end-field)
1859 (setq deleted t))
1860 ;; otherwise: not empty, delete "OPT" or "ALT"
1861 (opt-alt
1862 (goto-char beg-name)
1863 (delete-char 3))))
1847 1864
1848 (unless deleted 1865 (unless deleted
1849 (push field-name field-list) 1866 (push field-name field-list)
@@ -1902,16 +1919,17 @@ Formats current entry according to variable `bibtex-entry-format'."
1902 ;; if empty field, complain 1919 ;; if empty field, complain
1903 (if (and empty-field 1920 (if (and empty-field
1904 (memq 'required-fields format) 1921 (memq 'required-fields format)
1905 (assoc-ignore-case field-name 1922 (assoc-string field-name req-field-list t))
1906 (if crossref-key creq req)))
1907 (error "Mandatory field `%s' is empty" field-name)) 1923 (error "Mandatory field `%s' is empty" field-name))
1908 1924
1909 ;; unify case of field name 1925 ;; unify case of field name
1910 (if (memq 'unify-case format) 1926 (if (memq 'unify-case format)
1911 (let ((fname (car (assoc-ignore-case 1927 (let ((fname (car (assoc-string
1912 field-name (append (nth 0 (nth 1 entry-list)) 1928 field-name
1913 (nth 1 (nth 1 entry-list)) 1929 (append (nth 0 (nth 1 entry-list))
1914 bibtex-user-optional-fields))))) 1930 (nth 1 (nth 1 entry-list))
1931 bibtex-user-optional-fields)
1932 t))))
1915 (if fname 1933 (if fname
1916 (progn 1934 (progn
1917 (delete-region beg-name end-name) 1935 (delete-region beg-name end-name)
@@ -1925,8 +1943,8 @@ Formats current entry according to variable `bibtex-entry-format'."
1925 1943
1926 ;; check whether all required fields are present 1944 ;; check whether all required fields are present
1927 (if (memq 'required-fields format) 1945 (if (memq 'required-fields format)
1928 (let (altlist (found 0)) 1946 (let ((found 0) altlist)
1929 (dolist (fname (if crossref-key creq req)) 1947 (dolist (fname req-field-list)
1930 (if (nth 3 fname) 1948 (if (nth 3 fname)
1931 (push (car fname) altlist)) 1949 (push (car fname) altlist))
1932 (unless (or (member (car fname) field-list) 1950 (unless (or (member (car fname) field-list)
@@ -1940,7 +1958,7 @@ Formats current entry according to variable `bibtex-entry-format'."
1940 (error "Alternative mandatory field `%s' is missing" 1958 (error "Alternative mandatory field `%s' is missing"
1941 altlist)) 1959 altlist))
1942 ((> found 1) 1960 ((> found 1)
1943 (error "Alternative fields `%s' is defined %s times" 1961 (error "Alternative fields `%s' are defined %s times"
1944 altlist found)))))) 1962 altlist found))))))
1945 1963
1946 ;; update point 1964 ;; update point
@@ -2051,8 +2069,8 @@ and return results as a list."
2051 (setq titlestring (substring titlestring 0 (match-beginning 0)))))) 2069 (setq titlestring (substring titlestring 0 (match-beginning 0))))))
2052 ;; gather words from titlestring into a list. Ignore 2070 ;; gather words from titlestring into a list. Ignore
2053 ;; specific words and use only a specific amount of words. 2071 ;; specific words and use only a specific amount of words.
2054 (let (case-fold-search titlewords titlewords-extra titleword end-match 2072 (let ((counter 0)
2055 (counter 0)) 2073 case-fold-search titlewords titlewords-extra titleword end-match)
2056 (while (and (or (not (numberp bibtex-autokey-titlewords)) 2074 (while (and (or (not (numberp bibtex-autokey-titlewords))
2057 (< counter (+ bibtex-autokey-titlewords 2075 (< counter (+ bibtex-autokey-titlewords
2058 bibtex-autokey-titlewords-stretch))) 2076 bibtex-autokey-titlewords-stretch)))
@@ -2079,10 +2097,14 @@ and return results as a list."
2079 "Do some abbreviations on TITLEWORD. 2097 "Do some abbreviations on TITLEWORD.
2080The rules are defined in `bibtex-autokey-titleword-abbrevs' 2098The rules are defined in `bibtex-autokey-titleword-abbrevs'
2081and `bibtex-autokey-titleword-length'." 2099and `bibtex-autokey-titleword-length'."
2082 (let ((abbrev (bibtex-assoc-of-regexp 2100 (let ((case-folde-search t)
2083 titleword bibtex-autokey-titleword-abbrevs))) 2101 (alist bibtex-autokey-titleword-abbrevs))
2084 (if abbrev 2102 (while (and alist
2085 (cdr abbrev) 2103 (not (string-match (concat "\\`\\(?:" (caar alist) "\\)\\'")
2104 titleword)))
2105 (setq alist (cdr alist)))
2106 (if alist
2107 (cdar alist)
2086 (bibtex-autokey-abbrev titleword 2108 (bibtex-autokey-abbrev titleword
2087 bibtex-autokey-titleword-length)))) 2109 bibtex-autokey-titleword-length))))
2088 2110
@@ -2239,8 +2261,8 @@ Return alist of keys if parsing was completed, `aborted' otherwise."
2239 ;; This is a crossref. 2261 ;; This is a crossref.
2240 (buffer-substring-no-properties 2262 (buffer-substring-no-properties
2241 (1+ (match-beginning 3)) (1- (match-end 3)))) 2263 (1+ (match-beginning 3)) (1- (match-end 3))))
2242 ((assoc-ignore-case (bibtex-type-in-head) 2264 ((assoc-string (bibtex-type-in-head)
2243 bibtex-entry-field-alist) 2265 bibtex-entry-field-alist t)
2244 ;; This is an entry. 2266 ;; This is an entry.
2245 (match-string-no-properties bibtex-key-in-head))))) 2267 (match-string-no-properties bibtex-key-in-head)))))
2246 (if (and (stringp key) 2268 (if (and (stringp key)
@@ -2295,7 +2317,7 @@ Return alist of strings if parsing was completed, `aborted' otherwise."
2295 ;; user has aborted by typing a key --> return `aborted' 2317 ;; user has aborted by typing a key --> return `aborted'
2296 (throw 'userkey 'aborted)) 2318 (throw 'userkey 'aborted))
2297 (setq key (bibtex-reference-key-in-string bounds)) 2319 (setq key (bibtex-reference-key-in-string bounds))
2298 (if (not (assoc-ignore-case key strings)) 2320 (if (not (assoc key strings))
2299 (push (cons key (bibtex-text-in-string bounds t)) 2321 (push (cons key (bibtex-text-in-string bounds t))
2300 strings)) 2322 strings))
2301 (goto-char (bibtex-end-of-text-in-string bounds))) 2323 (goto-char (bibtex-end-of-text-in-string bounds)))
@@ -2384,6 +2406,7 @@ of a word, all strings are listed. Return completion."
2384 (display-completion-list (all-completions part-of-word 2406 (display-completion-list (all-completions part-of-word
2385 completions))) 2407 completions)))
2386 (message "Making completion list...done") 2408 (message "Making completion list...done")
2409 ;; return value is handled by choose-completion-string-functions
2387 nil)))) 2410 nil))))
2388 2411
2389(defun bibtex-complete-string-cleanup (str) 2412(defun bibtex-complete-string-cleanup (str)
@@ -2629,6 +2652,34 @@ non-nil.
2629 (easy-menu-add bibtex-entry-menu) 2652 (easy-menu-add bibtex-entry-menu)
2630 (run-hooks 'bibtex-mode-hook)) 2653 (run-hooks 'bibtex-mode-hook))
2631 2654
2655(defun bibtex-field-list (entry-type)
2656 "Return list of allowed fields for entry ENTRY-TYPE.
2657More specifically, the return value is a cons pair (REQUIRED . OPTIONAL),
2658where REQUIRED and OPTIONAL are lists of the required and optional field
2659names for ENTRY-TYPE according to `bibtex-entry-field-alist'."
2660 (let ((e (assoc-string entry-type bibtex-entry-field-alist t))
2661 required optional)
2662 (unless e
2663 (error "Bibtex entry type %s not defined" entry-type))
2664 (if (and (member-ignore-case entry-type bibtex-include-OPTcrossref)
2665 (nth 2 e))
2666 (setq required (nth 0 (nth 2 e))
2667 optional (nth 1 (nth 2 e)))
2668 (setq required (nth 0 (nth 1 e))
2669 optional (nth 1 (nth 1 e))))
2670 (if bibtex-include-OPTkey
2671 (push (list "key"
2672 "Used for reference key creation if author and editor fields are missing"
2673 (if (or (stringp bibtex-include-OPTkey)
2674 (fboundp bibtex-include-OPTkey))
2675 bibtex-include-OPTkey))
2676 optional))
2677 (if (member-ignore-case entry-type bibtex-include-OPTcrossref)
2678 (push '("crossref" "Reference key of the cross-referenced entry")
2679 optional))
2680 (setq optional (append optional bibtex-user-optional-fields))
2681 (cons required optional)))
2682
2632(defun bibtex-entry (entry-type) 2683(defun bibtex-entry (entry-type)
2633 "Insert a new BibTeX entry. 2684 "Insert a new BibTeX entry.
2634After insertion it calls the functions in `bibtex-add-entry-hook'." 2685After insertion it calls the functions in `bibtex-add-entry-hook'."
@@ -2638,38 +2689,17 @@ After insertion it calls the functions in `bibtex-add-entry-hook'."
2638 bibtex-entry-field-alist 2689 bibtex-entry-field-alist
2639 nil t nil 'bibtex-entry-type-history))) 2690 nil t nil 'bibtex-entry-type-history)))
2640 (list e-t))) 2691 (list e-t)))
2641 (let* (required optional 2692 (let ((key (if bibtex-maintain-sorted-entries
2642 (key (if bibtex-maintain-sorted-entries 2693 (bibtex-read-key (format "%s key: " entry-type))))
2643 (bibtex-read-key (format "%s key: " entry-type)))) 2694 (field-list (bibtex-field-list entry-type)))
2644 (e (assoc-ignore-case entry-type bibtex-entry-field-alist))
2645 (r-n-o (elt e 1))
2646 (c-ref (elt e 2)))
2647 (if (not e)
2648 (error "Bibtex entry type %s not defined" entry-type))
2649 (if (and (member entry-type bibtex-include-OPTcrossref)
2650 c-ref)
2651 (setq required (elt c-ref 0)
2652 optional (elt c-ref 1))
2653 (setq required (elt r-n-o 0)
2654 optional (elt r-n-o 1)))
2655 (unless (bibtex-prepare-new-entry (list key nil entry-type)) 2695 (unless (bibtex-prepare-new-entry (list key nil entry-type))
2656 (error "Entry with key `%s' already exists" key)) 2696 (error "Entry with key `%s' already exists" key))
2657 (indent-to-column bibtex-entry-offset) 2697 (indent-to-column bibtex-entry-offset)
2658 (insert "@" entry-type (bibtex-entry-left-delimiter)) 2698 (insert "@" entry-type (bibtex-entry-left-delimiter))
2659 (if key 2699 (if key (insert key))
2660 (insert key))
2661 (save-excursion 2700 (save-excursion
2662 (mapcar 'bibtex-make-field required) 2701 (mapcar 'bibtex-make-field (car field-list))
2663 (if (member entry-type bibtex-include-OPTcrossref) 2702 (mapcar 'bibtex-make-optional-field (cdr field-list))
2664 (bibtex-make-optional-field '("crossref")))
2665 (if bibtex-include-OPTkey
2666 (if (or (stringp bibtex-include-OPTkey)
2667 (fboundp bibtex-include-OPTkey))
2668 (bibtex-make-optional-field
2669 (list "key" nil bibtex-include-OPTkey))
2670 (bibtex-make-optional-field '("key"))))
2671 (mapcar 'bibtex-make-optional-field optional)
2672 (mapcar 'bibtex-make-optional-field bibtex-user-optional-fields)
2673 (if bibtex-comma-after-last-field 2703 (if bibtex-comma-after-last-field
2674 (insert ",")) 2704 (insert ","))
2675 (insert "\n") 2705 (insert "\n")
@@ -2680,15 +2710,39 @@ After insertion it calls the functions in `bibtex-add-entry-hook'."
2680 (bibtex-autofill-entry)) 2710 (bibtex-autofill-entry))
2681 (run-hooks 'bibtex-add-entry-hook))) 2711 (run-hooks 'bibtex-add-entry-hook)))
2682 2712
2713(defun bibtex-entry-update ()
2714 "Update an existing BibTeX entry.
2715In the BibTeX entry at point, make new fields for those items that may occur
2716according to `bibtex-entry-field-alist', but are not yet present."
2717 (interactive)
2718 (save-excursion
2719 (bibtex-beginning-of-entry)
2720 ;; For inserting new fields, we use the fact that
2721 ;; bibtex-parse-entry moves point to the end of the last field.
2722 (let* ((fields-alist (bibtex-parse-entry))
2723 (field-list (bibtex-field-list
2724 (substring (cdr (assoc "=type=" fields-alist))
2725 1))) ; don't want @
2726 (case-fold-search t))
2727 (dolist (field (car field-list))
2728 (unless (bibtex-assoc-regexp (concat "\\`\\(ALT\\)?" (car field) "\\'")
2729 fields-alist)
2730 (bibtex-make-field field)))
2731 (dolist (field (cdr field-list))
2732 (unless (bibtex-assoc-regexp (concat "\\`\\(OPT\\)?" (car field) "\\'")
2733 fields-alist)
2734 (bibtex-make-optional-field field))))))
2735
2683(defun bibtex-parse-entry () 2736(defun bibtex-parse-entry ()
2684 "Parse entry at point, return an alist. 2737 "Parse entry at point, return an alist.
2685The alist elements have the form (FIELD . TEXT), where FIELD can also be 2738The alist elements have the form (FIELD . TEXT), where FIELD can also be
2686the special strings \"=type=\" and \"=key=\"." 2739the special strings \"=type=\" and \"=key=\". For the FIELD \"=key=\"
2740TEXT may be nil. Move point to the end of the last field."
2687 (let (alist bounds) 2741 (let (alist bounds)
2688 (when (looking-at bibtex-entry-head) 2742 (when (looking-at bibtex-entry-maybe-empty-head)
2689 (push (cons "=type=" (match-string bibtex-type-in-head)) alist) 2743 (push (cons "=type=" (match-string bibtex-type-in-head)) alist)
2690 (push (cons "=key=" (match-string bibtex-key-in-head)) alist) 2744 (push (cons "=key=" (match-string bibtex-key-in-head)) alist)
2691 (goto-char (match-end bibtex-key-in-head)) 2745 (goto-char (match-end 0))
2692 (while (setq bounds (bibtex-parse-field bibtex-field-name)) 2746 (while (setq bounds (bibtex-parse-field bibtex-field-name))
2693 (push (cons (bibtex-name-in-field bounds) 2747 (push (cons (bibtex-name-in-field bounds)
2694 (bibtex-text-in-field-bounds bounds)) 2748 (bibtex-text-in-field-bounds bounds))
@@ -2744,7 +2798,7 @@ the special strings \"=type=\" and \"=key=\"."
2744 (let* ((name (buffer-substring 2798 (let* ((name (buffer-substring
2745 (if (looking-at "ALT\\|OPT") (match-end 0) (point)) 2799 (if (looking-at "ALT\\|OPT") (match-end 0) (point))
2746 (bibtex-end-of-name-in-field bounds))) 2800 (bibtex-end-of-name-in-field bounds)))
2747 (text (assoc-ignore-case name other))) 2801 (text (assoc-string name other t)))
2748 (goto-char (bibtex-start-of-text-in-field bounds)) 2802 (goto-char (bibtex-start-of-text-in-field bounds))
2749 (if (not (and (looking-at bibtex-empty-field-re) text)) 2803 (if (not (and (looking-at bibtex-empty-field-re) text))
2750 (goto-char (bibtex-end-of-field bounds)) 2804 (goto-char (bibtex-end-of-field bounds))
@@ -2774,28 +2828,15 @@ the special strings \"=type=\" and \"=key=\"."
2774 (looking-at "OPT\\|ALT")) 2828 (looking-at "OPT\\|ALT"))
2775 (match-end 0) mb) 2829 (match-end 0) mb)
2776 (bibtex-end-of-name-in-field bounds))) 2830 (bibtex-end-of-name-in-field bounds)))
2777 (entry-type (progn (re-search-backward 2831 (field-list (bibtex-field-list (progn (re-search-backward
2778 bibtex-entry-maybe-empty-head nil t) 2832 bibtex-entry-maybe-empty-head nil t)
2779 (bibtex-type-in-head))) 2833 (bibtex-type-in-head))))
2780 (entry-list (assoc-ignore-case entry-type 2834 (comment (assoc-string field-name
2781 bibtex-entry-field-alist)) 2835 (append (car field-list)
2782 (c-r-list (elt entry-list 2)) 2836 (cdr field-list))
2783 (req-opt-list (if (and (member entry-type 2837 t)))
2784 bibtex-include-OPTcrossref)
2785 c-r-list)
2786 c-r-list
2787 (elt entry-list 1)))
2788 (list-of-entries (append (elt req-opt-list 0)
2789 (elt req-opt-list 1)
2790 bibtex-user-optional-fields
2791 (if (member entry-type
2792 bibtex-include-OPTcrossref)
2793 '(("crossref" "Reference key of the cross-referenced entry")))
2794 (if bibtex-include-OPTkey
2795 '(("key" "Used for reference key creation if author and editor fields are missing")))))
2796 (comment (assoc-ignore-case field-name list-of-entries)))
2797 (if comment 2838 (if comment
2798 (message (elt comment 1)) 2839 (message (nth 1 comment))
2799 (message "No comment available"))))) 2840 (message "No comment available")))))
2800 2841
2801(defun bibtex-make-field (field &optional called-by-yank) 2842(defun bibtex-make-field (field &optional called-by-yank)
@@ -2804,24 +2845,13 @@ FIELD is either a string or a list of the form
2804\(FIELD-NAME COMMENT-STRING INIT ALTERNATIVE-FLAG) as in 2845\(FIELD-NAME COMMENT-STRING INIT ALTERNATIVE-FLAG) as in
2805`bibtex-entry-field-alist'." 2846`bibtex-entry-field-alist'."
2806 (interactive 2847 (interactive
2807 (list (let* ((entry-type 2848 (list (let ((completion-ignore-case t)
2808 (save-excursion 2849 (field-list (bibtex-field-list
2809 (bibtex-enclosing-entry-maybe-empty-head) 2850 (save-excursion
2810 (bibtex-type-in-head))) 2851 (bibtex-enclosing-entry-maybe-empty-head)
2811 ;; "preliminary" completion list 2852 (bibtex-type-in-head)))))
2812 (fl (nth 1 (assoc-ignore-case 2853 (completing-read "BibTeX field name: "
2813 entry-type bibtex-entry-field-alist))) 2854 (append (car field-list) (cdr field-list))
2814 ;; "full" completion list
2815 (field-list (append (nth 0 fl)
2816 (nth 1 fl)
2817 bibtex-user-optional-fields
2818 (if (member entry-type
2819 bibtex-include-OPTcrossref)
2820 '(("crossref")))
2821 (if bibtex-include-OPTkey
2822 '(("key")))))
2823 (completion-ignore-case t))
2824 (completing-read "BibTeX field name: " field-list
2825 nil nil nil bibtex-field-history)))) 2855 nil nil nil bibtex-field-history))))
2826 (unless (consp field) 2856 (unless (consp field)
2827 (setq field (list field))) 2857 (setq field (list field)))
@@ -2848,8 +2878,9 @@ FIELD is either a string or a list of the form
2848 ((fboundp init) 2878 ((fboundp init)
2849 (insert (funcall init))))) 2879 (insert (funcall init)))))
2850 (if (not called-by-yank) (insert (bibtex-field-right-delimiter))) 2880 (if (not called-by-yank) (insert (bibtex-field-right-delimiter)))
2851 (if (interactive-p) 2881 (when (interactive-p)
2852 (forward-char -1))) 2882 (forward-char -1)
2883 (bibtex-print-help-message)))
2853 2884
2854(defun bibtex-beginning-of-entry () 2885(defun bibtex-beginning-of-entry ()
2855 "Move to beginning of BibTeX entry (beginning of line). 2886 "Move to beginning of BibTeX entry (beginning of line).
@@ -2982,13 +3013,14 @@ the entries of the BibTeX buffer. Return nil if no entry found."
2982 "\\(OPT\\)?crossref" t))) 3013 "\\(OPT\\)?crossref" t)))
2983 (list key 3014 (list key
2984 (if bounds (bibtex-text-in-field-bounds bounds t)) 3015 (if bounds (bibtex-text-in-field-bounds bounds t))
2985 entry-name)))) 3016 entry-name)))
2986 (list key nil entry-name))))) 3017 (list key nil entry-name))))))
2987 3018
2988(defun bibtex-lessp (index1 index2) 3019(defun bibtex-lessp (index1 index2)
2989 "Predicate for sorting BibTeX entries with indices INDEX1 and INDEX2. 3020 "Predicate for sorting BibTeX entries with indices INDEX1 and INDEX2.
2990Each index is a list (KEY CROSSREF-KEY ENTRY-NAME). 3021Each index is a list (KEY CROSSREF-KEY ENTRY-NAME).
2991The predicate depends on the variable `bibtex-maintain-sorted-entries'." 3022The predicate depends on the variable `bibtex-maintain-sorted-entries'.
3023If its value is nil use plain sorting."
2992 (cond ((not index1) (not index2)) ; indices can be nil 3024 (cond ((not index1) (not index2)) ; indices can be nil
2993 ((not index2) nil) 3025 ((not index2) nil)
2994 ((equal bibtex-maintain-sorted-entries 'crossref) 3026 ((equal bibtex-maintain-sorted-entries 'crossref)
@@ -3017,12 +3049,10 @@ The predicate depends on the variable `bibtex-maintain-sorted-entries'."
3017(defun bibtex-sort-buffer () 3049(defun bibtex-sort-buffer ()
3018 "Sort BibTeX buffer alphabetically by key. 3050 "Sort BibTeX buffer alphabetically by key.
3019The predicate for sorting is defined via `bibtex-maintain-sorted-entries'. 3051The predicate for sorting is defined via `bibtex-maintain-sorted-entries'.
3020Text outside of BibTeX entries is not affected. If 3052If its value is nil use plain sorting. Text outside of BibTeX entries is not
3021`bibtex-sort-ignore-string-entries' is non-nil, @String entries will be 3053affected. If `bibtex-sort-ignore-string-entries' is non-nil, @String entries
3022ignored." 3054will be ignored."
3023 (interactive) 3055 (interactive)
3024 (unless bibtex-maintain-sorted-entries
3025 (error "You must choose a sorting scheme"))
3026 (save-restriction 3056 (save-restriction
3027 (narrow-to-region (bibtex-beginning-of-first-entry) 3057 (narrow-to-region (bibtex-beginning-of-first-entry)
3028 (save-excursion (goto-char (point-max)) 3058 (save-excursion (goto-char (point-max))
@@ -3212,8 +3242,8 @@ Returns t if test was successful, nil otherwise."
3212 (let* ((entry-list (progn 3242 (let* ((entry-list (progn
3213 (goto-char beg) 3243 (goto-char beg)
3214 (bibtex-search-entry nil end) 3244 (bibtex-search-entry nil end)
3215 (assoc-ignore-case (bibtex-type-in-head) 3245 (assoc-string (bibtex-type-in-head)
3216 bibtex-entry-field-alist))) 3246 bibtex-entry-field-alist t)))
3217 (req (copy-sequence (elt (elt entry-list 1) 0))) 3247 (req (copy-sequence (elt (elt entry-list 1) 0)))
3218 (creq (copy-sequence (elt (elt entry-list 2) 0))) 3248 (creq (copy-sequence (elt (elt entry-list 2) 0)))
3219 crossref-there bounds) 3249 crossref-there bounds)
@@ -3229,8 +3259,8 @@ Returns t if test was successful, nil otherwise."
3229 (push (list (bibtex-current-line) 3259 (push (list (bibtex-current-line)
3230 "Questionable month field") 3260 "Questionable month field")
3231 error-list)) 3261 error-list))
3232 (setq req (delete (assoc-ignore-case field-name req) req) 3262 (setq req (delete (assoc-string field-name req t) req)
3233 creq (delete (assoc-ignore-case field-name creq) creq)) 3263 creq (delete (assoc-string field-name creq t) creq))
3234 (if (equal field-name "crossref") 3264 (if (equal field-name "crossref")
3235 (setq crossref-there t)))) 3265 (setq crossref-there t))))
3236 (if crossref-there 3266 (if crossref-there
@@ -3523,27 +3553,30 @@ At end of the cleaning process, the functions in
3523 (match-end bibtex-key-in-head))) 3553 (match-end bibtex-key-in-head)))
3524 (insert key)) 3554 (insert key))
3525 ;; sorting 3555 ;; sorting
3526 (let* ((start (bibtex-beginning-of-entry)) 3556 (unless called-by-reformat
3527 (end (progn (bibtex-end-of-entry) 3557 (let* ((start (bibtex-beginning-of-entry))
3528 (if (re-search-forward 3558 (end (progn (bibtex-end-of-entry)
3529 bibtex-entry-maybe-empty-head nil 'move) 3559 (if (re-search-forward
3530 (goto-char (match-beginning 0))) 3560 bibtex-entry-maybe-empty-head nil 'move)
3531 (point))) 3561 (goto-char (match-beginning 0)))
3532 (entry (buffer-substring start end)) 3562 (point)))
3533 (index (progn (goto-char start) 3563 (entry (buffer-substring start end))
3534 (bibtex-entry-index)))) 3564 (index (progn (goto-char start)
3535 (delete-region start end) 3565 (bibtex-entry-index)))
3536 (unless (prog1 (or called-by-reformat 3566 no-error)
3537 (if (and bibtex-maintain-sorted-entries 3567 (if (and bibtex-maintain-sorted-entries
3538 (not (and bibtex-sort-ignore-string-entries 3568 (not (and bibtex-sort-ignore-string-entries
3539 (equal entry-type "string")))) 3569 (equal entry-type "string"))))
3540 (bibtex-prepare-new-entry index) 3570 (progn
3541 (not (bibtex-find-entry (car index))))) 3571 (delete-region start end)
3542 (insert entry) 3572 (setq no-error (bibtex-prepare-new-entry index))
3543 (forward-char -1) 3573 (insert entry)
3544 (bibtex-beginning-of-entry) ; moves backward 3574 (forward-char -1)
3545 (re-search-forward bibtex-entry-head)) 3575 (bibtex-beginning-of-entry) ; moves backward
3546 (error "New inserted entry yields duplicate key"))) 3576 (re-search-forward bibtex-entry-head))
3577 (setq no-error (bibtex-find-entry (car index))))
3578 (unless no-error
3579 (error "New inserted entry yields duplicate key"))))
3547 ;; final clean up 3580 ;; final clean up
3548 (unless called-by-reformat 3581 (unless called-by-reformat
3549 (save-excursion 3582 (save-excursion
@@ -3621,91 +3654,89 @@ If `bibtex-align-at-equal-sign' is non-nil, align equal signs, too."
3621 (indent-to-column bibtex-entry-offset) 3654 (indent-to-column bibtex-entry-offset)
3622 (goto-char pnt))) 3655 (goto-char pnt)))
3623 3656
3624(defun bibtex-reformat (&optional additional-options called-by-convert-alien) 3657(defun bibtex-realign ()
3658 "Realign BibTeX entries such that they are separated by one blank line."
3659 (goto-char (point-min))
3660 (let ((case-fold-search t))
3661 (when (looking-at bibtex-valid-entry-whitespace-re)
3662 (replace-match "\\1"))
3663 (while (re-search-forward bibtex-valid-entry-whitespace-re nil t)
3664 (replace-match "\n\n\\1"))))
3665
3666(defun bibtex-reformat (&optional read-options)
3625 "Reformat all BibTeX entries in buffer or region. 3667 "Reformat all BibTeX entries in buffer or region.
3626With prefix argument, read options for reformatting from minibuffer. 3668With prefix argument, read options for reformatting from minibuffer.
3627With \\[universal-argument] \\[universal-argument] prefix argument, reuse previous answers (if any) again. 3669With \\[universal-argument] \\[universal-argument] prefix argument, reuse previous answers (if any) again.
3628If mark is active it reformats entries in region, if not in whole buffer." 3670If mark is active reformat entries in region, if not in whole buffer."
3629 (interactive "*P") 3671 (interactive "*P")
3630 (let* ((pnt (point)) 3672 (let* ((pnt (point))
3631 (use-previous-options 3673 (use-previous-options
3632 (and (equal (prefix-numeric-value additional-options) 16) 3674 (and (equal (prefix-numeric-value read-options) 16)
3633 (or bibtex-reformat-previous-options 3675 (or bibtex-reformat-previous-options
3634 bibtex-reformat-previous-reference-keys))) 3676 bibtex-reformat-previous-reference-keys)))
3635 (bibtex-entry-format 3677 (bibtex-entry-format
3636 (if additional-options 3678 (if read-options
3637 (if use-previous-options 3679 (if use-previous-options
3638 bibtex-reformat-previous-options 3680 bibtex-reformat-previous-options
3639 (setq bibtex-reformat-previous-options 3681 (setq bibtex-reformat-previous-options
3640 (delq nil (list 3682 (mapcar (lambda (option)
3641 (if (or called-by-convert-alien 3683 (if (y-or-n-p (car option)) (cdr option)))
3642 (y-or-n-p "Realign entries (recommended)? ")) 3684 `(("Realign entries (recommended)? " . 'realign)
3643 'realign) 3685 ("Remove empty optional and alternative fields? " . 'opts-or-alts)
3644 (if (y-or-n-p "Remove empty optional and alternative fields? ") 3686 ("Remove delimiters around pure numerical fields? " . 'numerical-fields)
3645 'opts-or-alts) 3687 (,(concat (if bibtex-comma-after-last-field "Insert" "Remove")
3646 (if (y-or-n-p "Remove delimiters around pure numerical fields? ") 3688 " comma at end of entry? ") . 'last-comma)
3647 'numerical-fields) 3689 ("Replace double page dashes by single ones? " . 'page-dashes)
3648 (if (y-or-n-p (concat (if bibtex-comma-after-last-field "Insert" "Remove") 3690 ("Force delimiters? " . 'delimiters)
3649 " comma at end of entry? ")) 3691 ("Unify case of entry types and field names? " . 'unify-case)))))
3650 'last-comma)
3651 (if (y-or-n-p "Replace double page dashes by single ones? ")
3652 'page-dashes)
3653 (if (y-or-n-p "Force delimiters? ")
3654 'delimiters)
3655 (if (y-or-n-p "Unify case of entry types and field names? ")
3656 'unify-case)))))
3657 '(realign))) 3692 '(realign)))
3658 (reformat-reference-keys (if additional-options 3693 (reformat-reference-keys
3659 (if use-previous-options 3694 (if read-options
3660 bibtex-reformat-previous-reference-keys 3695 (if use-previous-options
3661 (setq bibtex-reformat-previous-reference-keys 3696 bibtex-reformat-previous-reference-keys
3662 (y-or-n-p "Generate new reference keys automatically? "))))) 3697 (setq bibtex-reformat-previous-reference-keys
3663 bibtex-autokey-edit-before-use 3698 (y-or-n-p "Generate new reference keys automatically? ")))))
3664 (bibtex-sort-ignore-string-entries t)
3665 (start-point (if (bibtex-mark-active) 3699 (start-point (if (bibtex-mark-active)
3666 (region-beginning) 3700 (region-beginning)
3667 (bibtex-beginning-of-first-entry) 3701 (point-min)))
3668 (bibtex-skip-to-valid-entry)
3669 (point)))
3670 (end-point (if (bibtex-mark-active) 3702 (end-point (if (bibtex-mark-active)
3671 (region-end) 3703 (region-end)
3672 (point-max)))) 3704 (point-max)))
3705 (bibtex-sort-ignore-string-entries t)
3706 bibtex-autokey-edit-before-use)
3707
3673 (save-restriction 3708 (save-restriction
3674 (narrow-to-region start-point end-point) 3709 (narrow-to-region start-point end-point)
3675 (when (memq 'realign bibtex-entry-format) 3710 (if (memq 'realign bibtex-entry-format)
3676 (goto-char (point-min)) 3711 (bibtex-realign))
3677 (while (re-search-forward bibtex-valid-entry-whitespace-re nil t)
3678 (replace-match "\n\\1")))
3679 (goto-char start-point) 3712 (goto-char start-point)
3680 (bibtex-progress-message "Formatting" 1) 3713 (bibtex-progress-message "Formatting" 1)
3681 (bibtex-map-entries (lambda (key beg end) 3714 (bibtex-map-entries (lambda (key beg end)
3682 (bibtex-progress-message) 3715 (bibtex-progress-message)
3683 (bibtex-clean-entry reformat-reference-keys t) 3716 (bibtex-clean-entry reformat-reference-keys t)))
3684 (when (memq 'realign bibtex-entry-format) 3717 (when (memq 'realign bibtex-entry-format)
3685 (goto-char end) 3718 (bibtex-delete-whitespace)
3686 (bibtex-delete-whitespace) 3719 (open-line (if (eobp) 1 2)))
3687 (open-line 2))))
3688 (bibtex-progress-message 'done)) 3720 (bibtex-progress-message 'done))
3689 (when (and reformat-reference-keys 3721 (when (and reformat-reference-keys
3690 bibtex-maintain-sorted-entries 3722 bibtex-maintain-sorted-entries)
3691 (not called-by-convert-alien)) 3723 (bibtex-progress-message "Sorting" 1)
3692 (bibtex-sort-buffer) 3724 (bibtex-sort-buffer)
3693 (kill-local-variable 'bibtex-reference-keys)) 3725 (kill-local-variable 'bibtex-reference-keys)
3726 (bibtex-progress-message 'done))
3694 (goto-char pnt))) 3727 (goto-char pnt)))
3695 3728
3696(defun bibtex-convert-alien (&optional do-additional-reformatting) 3729(defun bibtex-convert-alien (&optional read-options)
3697 "Convert an alien BibTeX buffer to be fully usable by BibTeX mode. 3730 "Convert an alien BibTeX buffer to be fully usable by BibTeX mode.
3698If a file does not conform with some standards used by BibTeX mode, 3731If a file does not conform with all standards used by BibTeX mode,
3699some of the high-level features of BibTeX mode will not be available. 3732some of the high-level features of BibTeX mode will not be available.
3700This function tries to convert current buffer to conform with these standards. 3733This function tries to convert current buffer to conform with these standards.
3701With prefix argument DO-ADDITIONAL-REFORMATTING 3734With prefix argument READ-OPTIONS non-nil, read options for reformatting
3702non-nil, read options for reformatting entries from minibuffer." 3735entries from minibuffer."
3703 (interactive "*P") 3736 (interactive "*P")
3704 (message "Starting to validate buffer...") 3737 (message "Starting to validate buffer...")
3705 (sit-for 1 nil t) 3738 (sit-for 1 nil t)
3706 (goto-char (point-min)) 3739 (bibtex-realign)
3707 (while (re-search-forward "[ \t\n]+@" nil t)
3708 (replace-match "\n@"))
3709 (message 3740 (message
3710 "If errors occur, correct them and call `bibtex-convert-alien' again") 3741 "If errors occur, correct them and call `bibtex-convert-alien' again")
3711 (sit-for 5 nil t) 3742 (sit-for 5 nil t)
@@ -3714,10 +3745,7 @@ non-nil, read options for reformatting entries from minibuffer."
3714 (bibtex-validate)) 3745 (bibtex-validate))
3715 (message "Starting to reformat entries...") 3746 (message "Starting to reformat entries...")
3716 (sit-for 2 nil t) 3747 (sit-for 2 nil t)
3717 (bibtex-reformat do-additional-reformatting t) 3748 (bibtex-reformat read-options)
3718 (when bibtex-maintain-sorted-entries
3719 (message "Starting to sort buffer...")
3720 (bibtex-sort-buffer))
3721 (goto-char (point-max)) 3749 (goto-char (point-max))
3722 (message "Buffer is now parsable. Please save it."))) 3750 (message "Buffer is now parsable. Please save it.")))
3723 3751
@@ -3890,5 +3918,5 @@ is outside key or BibTeX field."
3890 3918
3891(provide 'bibtex) 3919(provide 'bibtex)
3892 3920
3893;;; arch-tag: ee2be3af-caad-427f-b42a-d20fad630d04 3921;; arch-tag: ee2be3af-caad-427f-b42a-d20fad630d04
3894;;; bibtex.el ends here 3922;;; bibtex.el ends here