aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/textmodes
diff options
context:
space:
mode:
authorStefan Monnier2004-05-03 23:04:55 +0000
committerStefan Monnier2004-05-03 23:04:55 +0000
commit8bf38a9bfef78cbfe65762db736188cfaa99dbd7 (patch)
tree4bf2fc4b6f73e4fb294467c0ee371aff2043fa95 /lisp/textmodes
parente0db3d3f0048af8557090bc93d75bcfd43774bbc (diff)
downloademacs-8bf38a9bfef78cbfe65762db736188cfaa99dbd7.tar.gz
emacs-8bf38a9bfef78cbfe65762db736188cfaa99dbd7.zip
(bibtex-progress-message): Fix docstring.
(bibtex-entry-update): New command bound to C-c C-u. (bibtex-text-in-string): Fix regexp. (bibtex-assoc-of-regexp): Remove. (bibtex-progress-message): Fix docstring. (bibtex-inside-field): Use if. (bibtex-assoc-regexp): New function. (bibtex-format-entry): Make code more robust so it formats also old entries. (bibtex-autokey-demangle-title): Merge with obsolete function bibtex-assoc-of-regexp. (bibtex-field-list): New function. (bibtex-entry): Use bibtex-field-list. (bibtex-parse-entry): Fix docstring. (bibtex-print-help-message): Use bibtex-field-list. (bibtex-make-field): Use bibtex-field-list. (bibtex-entry-index): Bugfix. Return crossref key if required. (bibtex-lessp): Fix docstring.
Diffstat (limited to 'lisp/textmodes')
-rw-r--r--lisp/textmodes/bibtex.el367
1 files changed, 196 insertions, 171 deletions
diff --git a/lisp/textmodes/bibtex.el b/lisp/textmodes/bibtex.el
index 1926661bbab..5c95b138720 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
@@ -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,7 +1764,7 @@ 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))
@@ -1772,9 +1773,7 @@ Formats current entry according to variable `bibtex-entry-format'."
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-ignore-case (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 creq (nth 0 (nth 2 entry-list))) ; crossref part
1778 1777
1779 ;; unify case of entry name 1778 ;; unify case of entry name
1780 (when (memq 'unify-case format) 1779 (when (memq 'unify-case format)
@@ -1791,20 +1790,32 @@ Formats current entry according to variable `bibtex-entry-format'."
1791 ;; determine if entry has crossref field and if at least 1790 ;; determine if entry has crossref field and if at least
1792 ;; one alternative is non-empty 1791 ;; one alternative is non-empty
1793 (goto-char (point-min)) 1792 (goto-char (point-min))
1794 (while (setq bounds (bibtex-search-forward-field 1793 (let* ((fields-alist (bibtex-parse-entry))
1795 bibtex-field-name)) 1794 (case-fold-search t)
1796 (goto-char (bibtex-start-of-name-in-field bounds)) 1795 (field (bibtex-assoc-regexp "\\(OPT\\)?crossref\\>"
1797 (cond ((looking-at "ALT") 1796 fields-alist)))
1798 (setq alternatives-there t) 1797 (setq crossref-key (and field
1799 (goto-char (bibtex-start-of-text-in-field bounds)) 1798 (not (string-match bibtex-empty-field-re
1800 (if (not (looking-at bibtex-empty-field-re)) 1799 (cdr field)))
1801 (setq non-empty-alternative t))) 1800 (cdr field))
1802 ((and (looking-at "\\(OPT\\)?crossref\\>") 1801 req-field-list (if crossref-key
1803 (progn (goto-char (bibtex-start-of-text-in-field bounds)) 1802 (nth 0 (nth 2 entry-list)) ; crossref part
1804 (not (looking-at bibtex-empty-field-re)))) 1803 (nth 0 (nth 1 entry-list)))) ; required part
1805 (setq crossref-key 1804
1806 (bibtex-text-in-field-bounds bounds t)))) 1805 (dolist (rfield req-field-list)
1807 (goto-char (bibtex-end-of-field bounds))) 1806 (when (nth 3 rfield) ; we should have an alternative
1807 (setq alternatives-there t
1808 field (bibtex-assoc-regexp
1809 (concat "\\(ALT\\)?" (car rfield) "\\>")
1810 fields-alist))
1811 (if (and field
1812 (not (string-match bibtex-empty-field-re
1813 (cdr field))))
1814 (cond ((not non-empty-alternative)
1815 (setq non-empty-alternative t))
1816 ((memq 'required-fields format)
1817 (error "More than one non-empty alternative.")))))))
1818
1808 (if (and alternatives-there 1819 (if (and alternatives-there
1809 (not non-empty-alternative) 1820 (not non-empty-alternative)
1810 (memq 'required-fields format)) 1821 (memq 'required-fields format))
@@ -1832,18 +1843,23 @@ Formats current entry according to variable `bibtex-entry-format'."
1832 ;; quite some redundancy compared with what we need to do 1843 ;; quite some redundancy compared with what we need to do
1833 ;; anyway. So for speed-up we avoid using them. 1844 ;; anyway. So for speed-up we avoid using them.
1834 1845
1835 (when (and opt-alt 1846 (if (memq 'opts-or-alts format)
1836 (memq 'opts-or-alts format)) 1847 (cond ((and empty-field
1837 (if empty-field 1848 (or opt-alt
1838 ;; Either it is an empty ALT field. Then we have checked 1849 (let ((field (assoc-ignore-case
1839 ;; already that we have one non-empty alternative. 1850 field-name req-field-list)))
1840 ;; Or it is an empty OPT field that we do not miss anyway. 1851 (or (not field) ; OPT field
1841 ;; So we can safely delete this field. 1852 (nth 3 field))))) ; ALT field
1842 (progn (delete-region beg-field end-field) 1853 ;; Either it is an empty ALT field. Then we have checked
1843 (setq deleted t)) 1854 ;; already that we have one non-empty alternative. Or it
1844 ;; otherwise: not empty, delete "OPT" or "ALT" 1855 ;; is an empty OPT field that we do not miss anyway.
1845 (goto-char beg-name) 1856 ;; So we can safely delete this field.
1846 (delete-char 3))) 1857 (delete-region beg-field end-field)
1858 (setq deleted t))
1859 ;; otherwise: not empty, delete "OPT" or "ALT"
1860 (opt-alt
1861 (goto-char beg-name)
1862 (delete-char 3))))
1847 1863
1848 (unless deleted 1864 (unless deleted
1849 (push field-name field-list) 1865 (push field-name field-list)
@@ -1902,8 +1918,7 @@ Formats current entry according to variable `bibtex-entry-format'."
1902 ;; if empty field, complain 1918 ;; if empty field, complain
1903 (if (and empty-field 1919 (if (and empty-field
1904 (memq 'required-fields format) 1920 (memq 'required-fields format)
1905 (assoc-ignore-case field-name 1921 (assoc-ignore-case field-name req-field-list))
1906 (if crossref-key creq req)))
1907 (error "Mandatory field `%s' is empty" field-name)) 1922 (error "Mandatory field `%s' is empty" field-name))
1908 1923
1909 ;; unify case of field name 1924 ;; unify case of field name
@@ -1925,8 +1940,8 @@ Formats current entry according to variable `bibtex-entry-format'."
1925 1940
1926 ;; check whether all required fields are present 1941 ;; check whether all required fields are present
1927 (if (memq 'required-fields format) 1942 (if (memq 'required-fields format)
1928 (let (altlist (found 0)) 1943 (let ((found 0) altlist)
1929 (dolist (fname (if crossref-key creq req)) 1944 (dolist (fname req-field-list)
1930 (if (nth 3 fname) 1945 (if (nth 3 fname)
1931 (push (car fname) altlist)) 1946 (push (car fname) altlist))
1932 (unless (or (member (car fname) field-list) 1947 (unless (or (member (car fname) field-list)
@@ -1940,7 +1955,7 @@ Formats current entry according to variable `bibtex-entry-format'."
1940 (error "Alternative mandatory field `%s' is missing" 1955 (error "Alternative mandatory field `%s' is missing"
1941 altlist)) 1956 altlist))
1942 ((> found 1) 1957 ((> found 1)
1943 (error "Alternative fields `%s' is defined %s times" 1958 (error "Alternative fields `%s' are defined %s times"
1944 altlist found)))))) 1959 altlist found))))))
1945 1960
1946 ;; update point 1961 ;; update point
@@ -2051,8 +2066,8 @@ and return results as a list."
2051 (setq titlestring (substring titlestring 0 (match-beginning 0)))))) 2066 (setq titlestring (substring titlestring 0 (match-beginning 0))))))
2052 ;; gather words from titlestring into a list. Ignore 2067 ;; gather words from titlestring into a list. Ignore
2053 ;; specific words and use only a specific amount of words. 2068 ;; specific words and use only a specific amount of words.
2054 (let (case-fold-search titlewords titlewords-extra titleword end-match 2069 (let ((counter 0)
2055 (counter 0)) 2070 case-fold-search titlewords titlewords-extra titleword end-match)
2056 (while (and (or (not (numberp bibtex-autokey-titlewords)) 2071 (while (and (or (not (numberp bibtex-autokey-titlewords))
2057 (< counter (+ bibtex-autokey-titlewords 2072 (< counter (+ bibtex-autokey-titlewords
2058 bibtex-autokey-titlewords-stretch))) 2073 bibtex-autokey-titlewords-stretch)))
@@ -2079,10 +2094,14 @@ and return results as a list."
2079 "Do some abbreviations on TITLEWORD. 2094 "Do some abbreviations on TITLEWORD.
2080The rules are defined in `bibtex-autokey-titleword-abbrevs' 2095The rules are defined in `bibtex-autokey-titleword-abbrevs'
2081and `bibtex-autokey-titleword-length'." 2096and `bibtex-autokey-titleword-length'."
2082 (let ((abbrev (bibtex-assoc-of-regexp 2097 (let ((case-folde-search t)
2083 titleword bibtex-autokey-titleword-abbrevs))) 2098 (alist bibtex-autokey-titleword-abbrevs))
2084 (if abbrev 2099 (while (and alist
2085 (cdr abbrev) 2100 (not (string-match (concat "\\`\\(?:" (caar alist) "\\)\\'")
2101 titleword)))
2102 (setq alist (cdr alist)))
2103 (if alist
2104 (cdar alist)
2086 (bibtex-autokey-abbrev titleword 2105 (bibtex-autokey-abbrev titleword
2087 bibtex-autokey-titleword-length)))) 2106 bibtex-autokey-titleword-length))))
2088 2107
@@ -2384,6 +2403,7 @@ of a word, all strings are listed. Return completion."
2384 (display-completion-list (all-completions part-of-word 2403 (display-completion-list (all-completions part-of-word
2385 completions))) 2404 completions)))
2386 (message "Making completion list...done") 2405 (message "Making completion list...done")
2406 ;; return value is handled by choose-completion-string-functions
2387 nil)))) 2407 nil))))
2388 2408
2389(defun bibtex-complete-string-cleanup (str) 2409(defun bibtex-complete-string-cleanup (str)
@@ -2629,6 +2649,34 @@ non-nil.
2629 (easy-menu-add bibtex-entry-menu) 2649 (easy-menu-add bibtex-entry-menu)
2630 (run-hooks 'bibtex-mode-hook)) 2650 (run-hooks 'bibtex-mode-hook))
2631 2651
2652(defun bibtex-field-list (entry-type)
2653 "Return list of allowed fields for entry ENTRY-TYPE.
2654More specifically, the return value is a cons pair (REQUIRED . OPTIONAL),
2655where REQUIRED and OPTIONAL are lists of the required and optional field
2656names for ENTRY-TYPE according to `bibtex-entry-field-alist'."
2657 (let ((e (assoc-ignore-case entry-type bibtex-entry-field-alist))
2658 required optional)
2659 (unless e
2660 (error "Bibtex entry type %s not defined" entry-type))
2661 (if (and (member-ignore-case entry-type bibtex-include-OPTcrossref)
2662 (nth 2 e))
2663 (setq required (nth 0 (nth 2 e))
2664 optional (nth 1 (nth 2 e)))
2665 (setq required (nth 0 (nth 1 e))
2666 optional (nth 1 (nth 1 e))))
2667 (if bibtex-include-OPTkey
2668 (push (list "key"
2669 "Used for reference key creation if author and editor fields are missing"
2670 (if (or (stringp bibtex-include-OPTkey)
2671 (fboundp bibtex-include-OPTkey))
2672 bibtex-include-OPTkey))
2673 optional))
2674 (if (member-ignore-case entry-type bibtex-include-OPTcrossref)
2675 (push '("crossref" "Reference key of the cross-referenced entry")
2676 optional))
2677 (setq optional (append optional bibtex-user-optional-fields))
2678 (cons required optional)))
2679
2632(defun bibtex-entry (entry-type) 2680(defun bibtex-entry (entry-type)
2633 "Insert a new BibTeX entry. 2681 "Insert a new BibTeX entry.
2634After insertion it calls the functions in `bibtex-add-entry-hook'." 2682After insertion it calls the functions in `bibtex-add-entry-hook'."
@@ -2638,38 +2686,17 @@ After insertion it calls the functions in `bibtex-add-entry-hook'."
2638 bibtex-entry-field-alist 2686 bibtex-entry-field-alist
2639 nil t nil 'bibtex-entry-type-history))) 2687 nil t nil 'bibtex-entry-type-history)))
2640 (list e-t))) 2688 (list e-t)))
2641 (let* (required optional 2689 (let ((key (if bibtex-maintain-sorted-entries
2642 (key (if bibtex-maintain-sorted-entries 2690 (bibtex-read-key (format "%s key: " entry-type))))
2643 (bibtex-read-key (format "%s key: " entry-type)))) 2691 (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)) 2692 (unless (bibtex-prepare-new-entry (list key nil entry-type))
2656 (error "Entry with key `%s' already exists" key)) 2693 (error "Entry with key `%s' already exists" key))
2657 (indent-to-column bibtex-entry-offset) 2694 (indent-to-column bibtex-entry-offset)
2658 (insert "@" entry-type (bibtex-entry-left-delimiter)) 2695 (insert "@" entry-type (bibtex-entry-left-delimiter))
2659 (if key 2696 (if key (insert key))
2660 (insert key))
2661 (save-excursion 2697 (save-excursion
2662 (mapcar 'bibtex-make-field required) 2698 (mapcar 'bibtex-make-field (car field-list))
2663 (if (member entry-type bibtex-include-OPTcrossref) 2699 (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 2700 (if bibtex-comma-after-last-field
2674 (insert ",")) 2701 (insert ","))
2675 (insert "\n") 2702 (insert "\n")
@@ -2680,10 +2707,31 @@ After insertion it calls the functions in `bibtex-add-entry-hook'."
2680 (bibtex-autofill-entry)) 2707 (bibtex-autofill-entry))
2681 (run-hooks 'bibtex-add-entry-hook))) 2708 (run-hooks 'bibtex-add-entry-hook)))
2682 2709
2710(defun bibtex-entry-update ()
2711 "Update an existing BibTeX entry.
2712In the BibTeX entry at point, make new fields for those items that may occur
2713according to `bibtex-entry-field-alist', but are not yet present."
2714 (interactive)
2715 (save-excursion
2716 (bibtex-beginning-of-entry)
2717 ;; For inserting new fields, we use the fact that
2718 ;; bibtex-parse-entry moves point to the end of the last field.
2719 (let* ((fields-alist (bibtex-parse-entry))
2720 (field-list (bibtex-field-list
2721 (substring (cdr (assoc "=type=" fields-alist))
2722 1)))) ; don't want @
2723 (dolist (field (car field-list))
2724 (unless (assoc-ignore-case (car field) fields-alist)
2725 (bibtex-make-field field)))
2726 (dolist (field (cdr field-list))
2727 (unless (assoc-ignore-case (car field) fields-alist)
2728 (bibtex-make-optional-field field))))))
2729
2683(defun bibtex-parse-entry () 2730(defun bibtex-parse-entry ()
2684 "Parse entry at point, return an alist. 2731 "Parse entry at point, return an alist.
2685The alist elements have the form (FIELD . TEXT), where FIELD can also be 2732The alist elements have the form (FIELD . TEXT), where FIELD can also be
2686the special strings \"=type=\" and \"=key=\"." 2733the special strings \"=type=\" and \"=key=\".
2734Move point to the end of the last field."
2687 (let (alist bounds) 2735 (let (alist bounds)
2688 (when (looking-at bibtex-entry-head) 2736 (when (looking-at bibtex-entry-head)
2689 (push (cons "=type=" (match-string bibtex-type-in-head)) alist) 2737 (push (cons "=type=" (match-string bibtex-type-in-head)) alist)
@@ -2774,28 +2822,14 @@ the special strings \"=type=\" and \"=key=\"."
2774 (looking-at "OPT\\|ALT")) 2822 (looking-at "OPT\\|ALT"))
2775 (match-end 0) mb) 2823 (match-end 0) mb)
2776 (bibtex-end-of-name-in-field bounds))) 2824 (bibtex-end-of-name-in-field bounds)))
2777 (entry-type (progn (re-search-backward 2825 (field-list (bibtex-field-list (progn (re-search-backward
2778 bibtex-entry-maybe-empty-head nil t) 2826 bibtex-entry-maybe-empty-head nil t)
2779 (bibtex-type-in-head))) 2827 (bibtex-type-in-head))))
2780 (entry-list (assoc-ignore-case entry-type 2828 (comment (assoc-ignore-case field-name
2781 bibtex-entry-field-alist)) 2829 (append (car field-list)
2782 (c-r-list (elt entry-list 2)) 2830 (cdr field-list)))))
2783 (req-opt-list (if (and (member entry-type
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 2831 (if comment
2798 (message (elt comment 1)) 2832 (message (nth 1 comment))
2799 (message "No comment available"))))) 2833 (message "No comment available")))))
2800 2834
2801(defun bibtex-make-field (field &optional called-by-yank) 2835(defun bibtex-make-field (field &optional called-by-yank)
@@ -2804,24 +2838,13 @@ FIELD is either a string or a list of the form
2804\(FIELD-NAME COMMENT-STRING INIT ALTERNATIVE-FLAG) as in 2838\(FIELD-NAME COMMENT-STRING INIT ALTERNATIVE-FLAG) as in
2805`bibtex-entry-field-alist'." 2839`bibtex-entry-field-alist'."
2806 (interactive 2840 (interactive
2807 (list (let* ((entry-type 2841 (list (let ((completion-ignore-case t)
2808 (save-excursion 2842 (field-list (bibtex-field-list
2809 (bibtex-enclosing-entry-maybe-empty-head) 2843 (save-excursion
2810 (bibtex-type-in-head))) 2844 (bibtex-enclosing-entry-maybe-empty-head)
2811 ;; "preliminary" completion list 2845 (bibtex-type-in-head)))))
2812 (fl (nth 1 (assoc-ignore-case 2846 (completing-read "BibTeX field name: "
2813 entry-type bibtex-entry-field-alist))) 2847 (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)))) 2848 nil nil nil bibtex-field-history))))
2826 (unless (consp field) 2849 (unless (consp field)
2827 (setq field (list field))) 2850 (setq field (list field)))
@@ -2848,8 +2871,9 @@ FIELD is either a string or a list of the form
2848 ((fboundp init) 2871 ((fboundp init)
2849 (insert (funcall init))))) 2872 (insert (funcall init)))))
2850 (if (not called-by-yank) (insert (bibtex-field-right-delimiter))) 2873 (if (not called-by-yank) (insert (bibtex-field-right-delimiter)))
2851 (if (interactive-p) 2874 (when (interactive-p)
2852 (forward-char -1))) 2875 (forward-char -1)
2876 (bibtex-print-help-message)))
2853 2877
2854(defun bibtex-beginning-of-entry () 2878(defun bibtex-beginning-of-entry ()
2855 "Move to beginning of BibTeX entry (beginning of line). 2879 "Move to beginning of BibTeX entry (beginning of line).
@@ -2982,13 +3006,14 @@ the entries of the BibTeX buffer. Return nil if no entry found."
2982 "\\(OPT\\)?crossref" t))) 3006 "\\(OPT\\)?crossref" t)))
2983 (list key 3007 (list key
2984 (if bounds (bibtex-text-in-field-bounds bounds t)) 3008 (if bounds (bibtex-text-in-field-bounds bounds t))
2985 entry-name)))) 3009 entry-name)))
2986 (list key nil entry-name))))) 3010 (list key nil entry-name))))))
2987 3011
2988(defun bibtex-lessp (index1 index2) 3012(defun bibtex-lessp (index1 index2)
2989 "Predicate for sorting BibTeX entries with indices INDEX1 and INDEX2. 3013 "Predicate for sorting BibTeX entries with indices INDEX1 and INDEX2.
2990Each index is a list (KEY CROSSREF-KEY ENTRY-NAME). 3014Each index is a list (KEY CROSSREF-KEY ENTRY-NAME).
2991The predicate depends on the variable `bibtex-maintain-sorted-entries'." 3015The predicate depends on the variable `bibtex-maintain-sorted-entries'.
3016If its value is nil use plain sorting."
2992 (cond ((not index1) (not index2)) ; indices can be nil 3017 (cond ((not index1) (not index2)) ; indices can be nil
2993 ((not index2) nil) 3018 ((not index2) nil)
2994 ((equal bibtex-maintain-sorted-entries 'crossref) 3019 ((equal bibtex-maintain-sorted-entries 'crossref)
@@ -3886,5 +3911,5 @@ is outside key or BibTeX field."
3886 3911
3887(provide 'bibtex) 3912(provide 'bibtex)
3888 3913
3889;;; arch-tag: ee2be3af-caad-427f-b42a-d20fad630d04 3914;; arch-tag: ee2be3af-caad-427f-b42a-d20fad630d04
3890;;; bibtex.el ends here 3915;;; bibtex.el ends here