comparison lisp/textmodes/bibtex.el @ 81591:33952a25e52a

(bibtex-entry-format): New options `whitespace', `braces', and `string'. (bibtex-field-braces-alist, bibtex-field-strings-alist) (bibtex-field-braces-opt, bibtex-field-strings-opt) (bibtex-cite-matcher-alist): New variables. (bibtex-font-lock-keywords): Use bibtex-cite-matcher-alist. (bibtex-flash-head): Use blink-matching-delay. (bibtex-insert-kill, bibtex-mark-entry): Use push-mark. (bibtex-format-entry, bibtex-reformat): Handle new options of bibtex-entry-format. (bibtex-field-re-init, bibtex-font-lock-cite, bibtex-dist): New functions. (bibtex-complete-internal): Do not display messages while minibuffer is used. Do not leave around a completions buffer that is out of date. (bibtex-copy-summary-as-kill): New optional arg. (bibtex-font-lock-url): New optional arg no-button. (bibtex-find-crossref): Use `bibtex-cite-matcher-alist'. (bibtex-url): Allow multiple URLs per entry.
author Roland Winkler <Roland.Winkler@physik.uni-erlangen.de>
date Sat, 23 Jun 2007 22:00:03 +0000
parents 372e6a7ea660
children b98604865ea0 988f1edc9674
comparison
equal deleted inserted replaced
81590:ffabac9ec014 81591:33952a25e52a
32 ;;; Commentary: 32 ;;; Commentary:
33 33
34 ;; Major mode for editing and validating BibTeX files. 34 ;; Major mode for editing and validating BibTeX files.
35 35
36 ;; Usage: 36 ;; Usage:
37 ;; See documentation for function bibtex-mode or type "\M-x describe-mode" 37 ;; See documentation for `bibtex-mode' or type "M-x describe-mode"
38 ;; when you are in BibTeX mode. 38 ;; when you are in BibTeX mode.
39 39
40 ;; Todo: 40 ;; Todo:
41 ;; Distribute texinfo file. 41 ;; Distribute texinfo file.
42 42
110 remove OPT and ALT prefixes from used fields. 110 remove OPT and ALT prefixes from used fields.
111 required-fields Signal an error if a required field is missing. 111 required-fields Signal an error if a required field is missing.
112 numerical-fields Delete delimiters around numeral fields. 112 numerical-fields Delete delimiters around numeral fields.
113 page-dashes Change double dashes in page field to single dash 113 page-dashes Change double dashes in page field to single dash
114 (for scribe compatibility). 114 (for scribe compatibility).
115 whitespace Delete whitespace at the beginning and end of fields.
115 inherit-booktitle If entry contains a crossref field and the booktitle 116 inherit-booktitle If entry contains a crossref field and the booktitle
116 field is empty, set the booktitle field to the content 117 field is empty, set the booktitle field to the content
117 of the title field of the crossreferenced entry. 118 of the title field of the crossreferenced entry.
118 realign Realign entries, so that field texts and perhaps equal 119 realign Realign entries, so that field texts and perhaps equal
119 signs (depending on the value of 120 signs (depending on the value of
121 last-comma Add or delete comma on end of last field in entry, 122 last-comma Add or delete comma on end of last field in entry,
122 according to value of `bibtex-comma-after-last-field'. 123 according to value of `bibtex-comma-after-last-field'.
123 delimiters Change delimiters according to variables 124 delimiters Change delimiters according to variables
124 `bibtex-field-delimiters' and `bibtex-entry-delimiters'. 125 `bibtex-field-delimiters' and `bibtex-entry-delimiters'.
125 unify-case Change case of entry and field names. 126 unify-case Change case of entry and field names.
127 braces Enclose parts of field entries by braces according to
128 `bibtex-field-braces-alist'.
129 strings Replace parts of field entries by string constants
130 according to `bibtex-field-strings-alist'.
126 131
127 The value t means do all of the above formatting actions. 132 The value t means do all of the above formatting actions.
128 The value nil means do no formatting at all." 133 The value nil means do no formatting at all."
129 :group 'bibtex 134 :group 'bibtex
130 :type '(choice (const :tag "None" nil) 135 :type '(choice (const :tag "None" nil)
132 (set :menu-tag "Some" 137 (set :menu-tag "Some"
133 (const opts-or-alts) 138 (const opts-or-alts)
134 (const required-fields) 139 (const required-fields)
135 (const numerical-fields) 140 (const numerical-fields)
136 (const page-dashes) 141 (const page-dashes)
142 (const whitespace)
137 (const inherit-booktitle) 143 (const inherit-booktitle)
138 (const realign) 144 (const realign)
139 (const last-comma) 145 (const last-comma)
140 (const delimiters) 146 (const delimiters)
141 (const unify-case)))) 147 (const unify-case)
148 (const braces)
149 (const strings))))
150
151 (defcustom bibtex-field-braces-alist nil
152 "Alist of field regexps that \\[bibtex-clean-entry] encloses by braces.
153 Each element has the form (FIELDS REGEXP), where FIELDS is a list
154 of BibTeX field names and REGEXP is a regexp.
155 Whitespace in REGEXP will be replaced by \"[ \\t\\n]+\"."
156 :group 'bibtex
157 :type '(repeat (list (repeat (string :tag "field name"))
158 (choice (regexp :tag "regexp")
159 (sexp :tag "sexp")))))
160
161 (defcustom bibtex-field-strings-alist nil
162 "Alist of regexps that \\[bibtex-clean-entry] replaces by string constants.
163 Each element has the form (FIELDS REGEXP TO-STR), where FIELDS is a list
164 of BibTeX field names. In FIELDS search for REGEXP, which are replaced
165 by the BibTeX string constant TO-STR.
166 Whitespace in REGEXP will be replaced by \"[ \\t\\n]+\"."
167 :group 'bibtex
168 :type '(repeat (list (repeat (string :tag "field name"))
169 (regexp :tag "From regexp")
170 (regexp :tag "To string constant"))))
142 171
143 (defcustom bibtex-clean-entry-hook nil 172 (defcustom bibtex-clean-entry-hook nil
144 "List of functions to call when entry has been cleaned. 173 "List of functions to call when entry has been cleaned.
145 Functions are called with point inside the cleaned entry, and the buffer 174 Functions are called with point inside the cleaned entry, and the buffer
146 narrowed to just the entry." 175 narrowed to just the entry."
897 (choice (string :tag "Replacement") 926 (choice (string :tag "Replacement")
898 (integer :tag "Sub-match") 927 (integer :tag "Sub-match")
899 (function :tag "Filter")))))))) 928 (function :tag "Filter"))))))))
900 (put 'bibtex-generate-url-list 'risky-local-variable t) 929 (put 'bibtex-generate-url-list 'risky-local-variable t)
901 930
931 (defcustom bibtex-cite-matcher-alist
932 '(("\\\\cite[ \t\n]*{\\([^}]+\\)}" . 1))
933 "Alist of rules to identify cited keys in a BibTeX entry.
934 Each rule should be of the form (REGEXP . SUBEXP), where SUBEXP
935 specifies which parenthesized expression in REGEXP is a cited key.
936 Case is significant.
937 Used by `bibtex-find-crossref' and for font-locking."
938 :group 'bibtex
939 :type '(repeat (cons (regexp :tag "Regexp")
940 (integer :tag "Number"))))
941
902 (defcustom bibtex-expand-strings nil 942 (defcustom bibtex-expand-strings nil
903 "If non-nil, expand strings when extracting the content of a BibTeX field." 943 "If non-nil, expand strings when extracting the content of a BibTeX field."
904 :group 'bibtex 944 :group 'bibtex
905 :type 'boolean) 945 :type 'boolean)
906 946
1068 ["Preamble" bibtex-Preamble t])) 1108 ["Preamble" bibtex-Preamble t]))
1069 1109
1070 1110
1071 ;; Internal Variables 1111 ;; Internal Variables
1072 1112
1113 (defvar bibtex-field-braces-opt nil
1114 "Optimized value of `bibtex-field-braces-alist'.
1115 Created by `bibtex-field-re-init'.
1116 It is a an alist with elements (FIELD . REGEXP).")
1117
1118 (defvar bibtex-field-strings-opt nil
1119 "Optimized value of `bibtex-field-strings-alist'.
1120 Created by `bibtex-field-re-init'.
1121 It is a an alist with elements (FIELD RULE1 RULE2 ...),
1122 where each RULE is (REGEXP . TO-STR).")
1123
1073 (defvar bibtex-pop-previous-search-point nil 1124 (defvar bibtex-pop-previous-search-point nil
1074 "Next point where `bibtex-pop-previous' starts looking for a similar entry.") 1125 "Next point where `bibtex-pop-previous' starts looking for a similar entry.")
1075 1126
1076 (defvar bibtex-pop-next-search-point nil 1127 (defvar bibtex-pop-next-search-point nil
1077 "Next point where `bibtex-pop-next' starts looking for a similar entry.") 1128 "Next point where `bibtex-pop-next' starts looking for a similar entry.")
1213 1 font-lock-comment-face) 1264 1 font-lock-comment-face)
1214 ;; field names 1265 ;; field names
1215 (,(concat "^[ \t]*\\(" bibtex-field-name "\\)[ \t]*=") 1266 (,(concat "^[ \t]*\\(" bibtex-field-name "\\)[ \t]*=")
1216 1 font-lock-variable-name-face) 1267 1 font-lock-variable-name-face)
1217 ;; url 1268 ;; url
1218 (bibtex-font-lock-url) (bibtex-font-lock-crossref)) 1269 (bibtex-font-lock-url) (bibtex-font-lock-crossref)
1270 ;; cite
1271 ,@(mapcar (lambda (matcher)
1272 `((lambda (bound) (bibtex-font-lock-cite ',matcher bound))))
1273 bibtex-cite-matcher-alist))
1219 "*Default expressions to highlight in BibTeX mode.") 1274 "*Default expressions to highlight in BibTeX mode.")
1220 1275
1221 (defvar bibtex-font-lock-url-regexp 1276 (defvar bibtex-font-lock-url-regexp
1222 ;; Assume that field names begin at the beginning of a line. 1277 ;; Assume that field names begin at the beginning of a line.
1223 (concat "^[ \t]*" 1278 (concat "^[ \t]*"
1224 (regexp-opt (delete-dups (mapcar 'caar bibtex-generate-url-list)) t) 1279 (regexp-opt (delete-dups (mapcar 'caar bibtex-generate-url-list)) t)
1225 "[ \t]*=[ \t]*") 1280 "[ \t]*=[ \t]*")
1226 "Regexp for `bibtex-font-lock-url'.") 1281 "Regexp for `bibtex-font-lock-url' derived from `bibtex-generate-url-list'.")
1227 1282
1228 (defvar bibtex-string-empty-key nil 1283 (defvar bibtex-string-empty-key nil
1229 "If non-nil, `bibtex-parse-string' accepts empty key.") 1284 "If non-nil, `bibtex-parse-string' accepts empty key.")
1230 1285
1231 (defvar bibtex-sort-entry-class-alist nil 1286 (defvar bibtex-sort-entry-class-alist nil
1551 (save-excursion (goto-char (match-beginning 0)) 1606 (save-excursion (goto-char (match-beginning 0))
1552 (setq bounds (bibtex-parse-string empty-key)))) 1607 (setq bounds (bibtex-parse-string empty-key))))
1553 bounds)))) 1608 bounds))))
1554 1609
1555 (defun bibtex-reference-key-in-string (bounds) 1610 (defun bibtex-reference-key-in-string (bounds)
1556 "Return the key part of a BibTeX string defined via BOUNDS" 1611 "Return the key part of a BibTeX string defined via BOUNDS."
1557 (buffer-substring-no-properties (nth 1 (car bounds)) 1612 (buffer-substring-no-properties (nth 1 (car bounds))
1558 (nth 2 (car bounds)))) 1613 (nth 2 (car bounds))))
1559 1614
1560 (defun bibtex-text-in-string (bounds &optional content) 1615 (defun bibtex-text-in-string (bounds &optional content)
1561 "Get text in BibTeX string field defined via BOUNDS. 1616 "Get text in BibTeX string field defined via BOUNDS.
1624 (goto-char (match-end 0)) 1679 (goto-char (match-end 0))
1625 (let ((entry-closer 1680 (let ((entry-closer
1626 (if (save-excursion 1681 (if (save-excursion
1627 (goto-char (match-end bibtex-type-in-head)) 1682 (goto-char (match-end bibtex-type-in-head))
1628 (looking-at "[ \t]*(")) 1683 (looking-at "[ \t]*("))
1629 ",?[ \t\n]*)" ;; entry opened with `(' 1684 ",?[ \t\n]*)" ; entry opened with `('
1630 ",?[ \t\n]*}")) ;; entry opened with `{' 1685 ",?[ \t\n]*}")) ; entry opened with `{'
1631 bounds) 1686 bounds)
1632 (skip-chars-forward " \t\n") 1687 (skip-chars-forward " \t\n")
1633 ;; loop over all BibTeX fields 1688 ;; loop over all BibTeX fields
1634 (while (setq bounds (bibtex-parse-field)) 1689 (while (setq bounds (bibtex-parse-field))
1635 (goto-char (bibtex-end-of-field bounds))) 1690 (goto-char (bibtex-end-of-field bounds)))
1734 (bibtex-beginning-of-entry) 1789 (bibtex-beginning-of-entry)
1735 (when (and (looking-at bibtex-any-entry-maybe-empty-head) 1790 (when (and (looking-at bibtex-any-entry-maybe-empty-head)
1736 (< (point) pnt)) 1791 (< (point) pnt))
1737 (goto-char (match-beginning bibtex-type-in-head)) 1792 (goto-char (match-beginning bibtex-type-in-head))
1738 (if (pos-visible-in-window-p (point)) 1793 (if (pos-visible-in-window-p (point))
1739 (sit-for 1) 1794 (sit-for blink-matching-delay)
1740 (message "%s%s" prompt (buffer-substring-no-properties 1795 (message "%s%s" prompt (buffer-substring-no-properties
1741 (point) (match-end bibtex-key-in-head)))))))) 1796 (point) (match-end bibtex-key-in-head))))))))
1742 1797
1743 (defun bibtex-make-optional-field (field) 1798 (defun bibtex-make-optional-field (field)
1744 "Make an optional field named FIELD in current BibTeX entry." 1799 "Make an optional field named FIELD in current BibTeX entry."
1799 1854
1800 (defun bibtex-insert-kill (n &optional comma) 1855 (defun bibtex-insert-kill (n &optional comma)
1801 "Reinsert the Nth stretch of killed BibTeX text (field or entry). 1856 "Reinsert the Nth stretch of killed BibTeX text (field or entry).
1802 Optional arg COMMA is as in `bibtex-enclosing-field'." 1857 Optional arg COMMA is as in `bibtex-enclosing-field'."
1803 (unless bibtex-last-kill-command (error "BibTeX kill ring is empty")) 1858 (unless bibtex-last-kill-command (error "BibTeX kill ring is empty"))
1804 (let ((fun (lambda (kryp kr) ;; adapted from `current-kill' 1859 (let ((fun (lambda (kryp kr) ; adapted from `current-kill'
1805 (car (set kryp (nthcdr (mod (- n (length (eval kryp))) 1860 (car (set kryp (nthcdr (mod (- n (length (eval kryp)))
1806 (length kr)) kr)))))) 1861 (length kr)) kr))))))
1807 (if (eq bibtex-last-kill-command 'field) 1862 (if (eq bibtex-last-kill-command 'field)
1808 (progn 1863 (progn
1809 ;; insert past the current field 1864 ;; insert past the current field
1810 (goto-char (bibtex-end-of-field (bibtex-enclosing-field comma))) 1865 (goto-char (bibtex-end-of-field (bibtex-enclosing-field comma)))
1811 (set-mark (point)) 1866 (push-mark)
1812 (message "Mark set")
1813 (bibtex-make-field (funcall fun 'bibtex-field-kill-ring-yank-pointer 1867 (bibtex-make-field (funcall fun 'bibtex-field-kill-ring-yank-pointer
1814 bibtex-field-kill-ring) t nil t)) 1868 bibtex-field-kill-ring) t nil t))
1815 ;; insert past the current entry 1869 ;; insert past the current entry
1816 (bibtex-skip-to-valid-entry) 1870 (bibtex-skip-to-valid-entry)
1817 (set-mark (point)) 1871 (push-mark)
1818 (message "Mark set")
1819 (insert (funcall fun 'bibtex-entry-kill-ring-yank-pointer 1872 (insert (funcall fun 'bibtex-entry-kill-ring-yank-pointer
1820 bibtex-entry-kill-ring))))) 1873 bibtex-entry-kill-ring)))))
1821 1874
1822 (defun bibtex-format-entry () 1875 (defun bibtex-format-entry ()
1823 "Helper function for `bibtex-clean-entry'. 1876 "Helper function for `bibtex-clean-entry'.
1832 last-comma page-dashes delimiters 1885 last-comma page-dashes delimiters
1833 unify-case inherit-booktitle) 1886 unify-case inherit-booktitle)
1834 bibtex-entry-format)) 1887 bibtex-entry-format))
1835 crossref-key bounds alternatives-there non-empty-alternative 1888 crossref-key bounds alternatives-there non-empty-alternative
1836 entry-list req-field-list field-list) 1889 entry-list req-field-list field-list)
1890
1891 ;; Initialize `bibtex-field-braces-opt' and `bibtex-field-strings-opt'
1892 ;; if necessary.
1893 (unless bibtex-field-braces-opt
1894 (setq bibtex-field-braces-opt
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)))
1837 1899
1838 ;; identify entry type 1900 ;; identify entry type
1839 (goto-char (point-min)) 1901 (goto-char (point-min))
1840 (or (re-search-forward bibtex-entry-type nil t) 1902 (or (re-search-forward bibtex-entry-type nil t)
1841 (error "Not inside a BibTeX entry")) 1903 (error "Not inside a BibTeX entry"))
1902 (if opt-alt (+ beg-name 3) beg-name) end-name)) 1964 (if opt-alt (+ beg-name 3) beg-name) end-name))
1903 (empty-field (equal "" (bibtex-text-in-field-bounds bounds t))) 1965 (empty-field (equal "" (bibtex-text-in-field-bounds bounds t)))
1904 deleted) 1966 deleted)
1905 1967
1906 ;; We have more elegant high-level functions for several 1968 ;; We have more elegant high-level functions for several
1907 ;; tasks done by bibtex-format-entry. However, they contain 1969 ;; tasks done by `bibtex-format-entry'. However, they contain
1908 ;; quite some redundancy compared with what we need to do 1970 ;; quite some redundancy compared with what we need to do
1909 ;; anyway. So for speed-up we avoid using them. 1971 ;; anyway. So for speed-up we avoid using them.
1910 1972
1911 (if (memq 'opts-or-alts format) 1973 (if (memq 'opts-or-alts format)
1912 (cond ((and empty-field 1974 (cond ((and empty-field
1954 (bibtex-string= field-name "pages") 2016 (bibtex-string= field-name "pages")
1955 (progn (goto-char beg-text) 2017 (progn (goto-char beg-text)
1956 (looking-at 2018 (looking-at
1957 "\\([\"{][0-9]+\\)[ \t\n]*--?[ \t\n]*\\([0-9]+[\"}]\\)"))) 2019 "\\([\"{][0-9]+\\)[ \t\n]*--?[ \t\n]*\\([0-9]+[\"}]\\)")))
1958 (replace-match "\\1-\\2")) 2020 (replace-match "\\1-\\2"))
2021
2022 ;; remove whitespace at beginning and end of field
2023 (when (memq 'whitespace format)
2024 (goto-char beg-text)
2025 (if (looking-at "\\([{\"]\\)[ \t\n]+")
2026 (replace-match "\\1"))
2027 (goto-char end-text)
2028 (if (looking-back "[ \t\n]+\\([}\"]\\)" beg-text t)
2029 (replace-match "\\1")))
2030
2031 ;; enclose field text by braces according to
2032 ;; `bibtex-field-braces-alist'.
2033 (let (case-fold-search temp) ; Case-sensitive search
2034 (when (and (memq 'braces format)
2035 (setq temp (cdr (assoc-string field-name
2036 bibtex-field-braces-opt t))))
2037 (goto-char beg-text)
2038 (while (re-search-forward temp end-text t)
2039 (let ((beg (match-beginning 0))
2040 (bounds (bibtex-find-text-internal nil t)))
2041 (unless (or (nth 4 bounds) ; string constant
2042 ;; match already surrounded by braces
2043 ;; (braces are inside field delimiters)
2044 (and (< (point) (1- (nth 2 bounds)))
2045 (< (1+ (nth 1 bounds)) beg)
2046 (looking-at "}")
2047 (save-excursion (goto-char (1- beg))
2048 (looking-at "{"))))
2049 (insert "}")
2050 (goto-char beg)
2051 (insert "{")))))
2052
2053 ;; replace field text by BibTeX string constants according to
2054 ;; `bibtex-field-strings-alist'.
2055 (when (and (memq 'strings format)
2056 (setq temp (cdr (assoc-string field-name
2057 bibtex-field-strings-opt t))))
2058 (goto-char beg-text)
2059 (dolist (re temp)
2060 (while (re-search-forward (car re) end-text t)
2061 (let ((bounds (save-match-data
2062 (bibtex-find-text-internal nil t))))
2063 (unless (nth 4 bounds)
2064 ;; if match not at right subfield boundary...
2065 (if (< (match-end 0) (1- (nth 2 bounds)))
2066 (insert " # " (bibtex-field-left-delimiter))
2067 (delete-char 1))
2068 (replace-match (cdr re))
2069 (goto-char (match-beginning 0))
2070 ;; if match not at left subfield boundary...
2071 (if (< (1+ (nth 1 bounds)) (match-beginning 0))
2072 (insert (bibtex-field-right-delimiter) " # ")
2073 (delete-backward-char 1))))))))
1959 2074
1960 ;; use book title of crossref'd entry 2075 ;; use book title of crossref'd entry
1961 (if (and (memq 'inherit-booktitle format) 2076 (if (and (memq 'inherit-booktitle format)
1962 empty-field 2077 empty-field
1963 (bibtex-string= field-name "booktitle") 2078 (bibtex-string= field-name "booktitle")
2045 2160
2046 ;; fill entry 2161 ;; fill entry
2047 (if (memq 'realign format) 2162 (if (memq 'realign format)
2048 (bibtex-fill-entry)))))) 2163 (bibtex-fill-entry))))))
2049 2164
2165 (defun bibtex-field-re-init (regexp-alist type)
2166 "Calculate optimized value for bibtex-regexp-TYPE-opt.
2167 This value is based on bibtex-regexp-TYPE-alist. TYPE is 'braces or 'strings.
2168 Return optimized value to be used by `bibtex-format-entry'."
2169 (setq regexp-alist
2170 (mapcar (lambda (e)
2171 (list (car e)
2172 (replace-regexp-in-string "[ \t\n]+" "[ \t\n]+" (nth 1 e))
2173 (nth 2 e))) ; nil for 'braces'.
2174 regexp-alist))
2175 (let (opt-list)
2176 ;; Loop over field names
2177 (dolist (field (delete-dups (apply 'append (mapcar 'car regexp-alist))))
2178 (let (rules)
2179 ;; Collect all matches we have for this field name
2180 (dolist (e regexp-alist)
2181 (if (assoc-string field (car e) t)
2182 (push (cons (nth 1 e) (nth 2 e)) rules)))
2183 (if (eq type 'braces)
2184 ;; concatenate all regexps to a single regexp
2185 (setq rules (concat "\\(?:" (mapconcat 'car rules "\\|") "\\)")))
2186 ;; create list of replacement rules.
2187 (push (cons field rules) opt-list)))
2188 opt-list))
2189
2050 2190
2051 (defun bibtex-autokey-abbrev (string len) 2191 (defun bibtex-autokey-abbrev (string len)
2052 "Return an abbreviation of STRING with at least LEN characters. 2192 "Return an abbreviation of STRING with at least LEN characters.
2053 If LEN is positive the abbreviation is terminated only after a consonant 2193 If LEN is positive the abbreviation is terminated only after a consonant
2054 or at the word end. If LEN is negative the abbreviation is strictly 2194 or at the word end. If LEN is negative the abbreviation is strictly
2097 additional-names) 2237 additional-names)
2098 (unless (or (not (numberp bibtex-autokey-names)) 2238 (unless (or (not (numberp bibtex-autokey-names))
2099 (<= (length name-list) 2239 (<= (length name-list)
2100 (+ bibtex-autokey-names 2240 (+ bibtex-autokey-names
2101 bibtex-autokey-names-stretch))) 2241 bibtex-autokey-names-stretch)))
2102 ;; Take bibtex-autokey-names elements from beginning of name-list 2242 ;; Take `bibtex-autokey-names' elements from beginning of name-list
2103 (setq name-list (nreverse (nthcdr (- (length name-list) 2243 (setq name-list (nreverse (nthcdr (- (length name-list)
2104 bibtex-autokey-names) 2244 bibtex-autokey-names)
2105 (nreverse name-list))) 2245 (nreverse name-list)))
2106 additional-names bibtex-autokey-additional-names)) 2246 additional-names bibtex-autokey-additional-names))
2107 (concat (mapconcat 'identity name-list 2247 (concat (mapconcat 'identity name-list
2159 bibtex-autokey-titlewords-stretch))) 2299 bibtex-autokey-titlewords-stretch)))
2160 (string-match "\\b\\w+" titlestring)) 2300 (string-match "\\b\\w+" titlestring))
2161 (setq word (match-string 0 titlestring) 2301 (setq word (match-string 0 titlestring)
2162 titlestring (substring titlestring (match-end 0))) 2302 titlestring (substring titlestring (match-end 0)))
2163 ;; Ignore words matched by one of the elements of 2303 ;; Ignore words matched by one of the elements of
2164 ;; bibtex-autokey-titleword-ignore 2304 ;; `bibtex-autokey-titleword-ignore'
2165 (unless (let ((lst bibtex-autokey-titleword-ignore)) 2305 (unless (let ((lst bibtex-autokey-titleword-ignore))
2166 (while (and lst 2306 (while (and lst
2167 (not (string-match (concat "\\`\\(?:" (car lst) 2307 (not (string-match (concat "\\`\\(?:" (car lst)
2168 "\\)\\'") word))) 2308 "\\)\\'") word)))
2169 (setq lst (cdr lst))) 2309 (setq lst (cdr lst)))
2171 (setq counter (1+ counter)) 2311 (setq counter (1+ counter))
2172 (if (or (not (numberp bibtex-autokey-titlewords)) 2312 (if (or (not (numberp bibtex-autokey-titlewords))
2173 (<= counter bibtex-autokey-titlewords)) 2313 (<= counter bibtex-autokey-titlewords))
2174 (push word titlewords) 2314 (push word titlewords)
2175 (push word titlewords-extra)))) 2315 (push word titlewords-extra))))
2176 ;; Obey bibtex-autokey-titlewords-stretch: 2316 ;; Obey `bibtex-autokey-titlewords-stretch':
2177 ;; If by now we have processed all words in titlestring, we include 2317 ;; If by now we have processed all words in titlestring, we include
2178 ;; titlewords-extra in titlewords. Otherwise, we ignore titlewords-extra. 2318 ;; titlewords-extra in titlewords. Otherwise, we ignore titlewords-extra.
2179 (unless (string-match "\\b\\w+" titlestring) 2319 (unless (string-match "\\b\\w+" titlestring)
2180 (setq titlewords (append titlewords-extra titlewords))) 2320 (setq titlewords (append titlewords-extra titlewords)))
2181 (mapconcat 'bibtex-autokey-demangle-title (nreverse titlewords) 2321 (mapconcat 'bibtex-autokey-demangle-title (nreverse titlewords)
2182 bibtex-autokey-titleword-separator)))) 2322 bibtex-autokey-titleword-separator))))
2183 2323
2341 (let ((key (bibtex-key-in-head))) 2481 (let ((key (bibtex-key-in-head)))
2342 (unless (assoc key ref-keys) 2482 (unless (assoc key ref-keys)
2343 (push (cons key t) ref-keys))))))) 2483 (push (cons key t) ref-keys)))))))
2344 2484
2345 (let (;; ignore @String entries because they are handled 2485 (let (;; ignore @String entries because they are handled
2346 ;; separately by bibtex-parse-strings 2486 ;; separately by `bibtex-parse-strings'
2347 (bibtex-sort-ignore-string-entries t) 2487 (bibtex-sort-ignore-string-entries t)
2348 bounds) 2488 bounds)
2349 (bibtex-map-entries 2489 (bibtex-map-entries
2350 (lambda (key beg end) 2490 (lambda (key beg end)
2351 (if (and abortable 2491 (if (and abortable
2397 (goto-char (bibtex-end-of-text-in-string bounds))) 2537 (goto-char (bibtex-end-of-text-in-string bounds)))
2398 ;; successful operation --> return `bibtex-strings' 2538 ;; successful operation --> return `bibtex-strings'
2399 (setq bibtex-strings strings)))))) 2539 (setq bibtex-strings strings))))))
2400 2540
2401 (defun bibtex-strings () 2541 (defun bibtex-strings ()
2402 "Return `bibtex-strings'. Initialize this variable if necessary." 2542 "Return `bibtex-strings'. Initialize this variable if necessary."
2403 (if (listp bibtex-strings) bibtex-strings 2543 (if (listp bibtex-strings) bibtex-strings
2404 (bibtex-parse-strings (bibtex-string-files-init)))) 2544 (bibtex-parse-strings (bibtex-string-files-init))))
2405 2545
2406 (defun bibtex-string-files-init () 2546 (defun bibtex-string-files-init ()
2407 "Return initialization for `bibtex-strings'. 2547 "Return initialization for `bibtex-strings'.
2454 (if (and (eq major-mode 'bibtex-mode) 2594 (if (and (eq major-mode 'bibtex-mode)
2455 (not (eq (buffer-modified-tick) 2595 (not (eq (buffer-modified-tick)
2456 bibtex-buffer-last-parsed-tick))) 2596 bibtex-buffer-last-parsed-tick)))
2457 (save-restriction 2597 (save-restriction
2458 (widen) 2598 (widen)
2459 ;; Output no progress messages in bibtex-parse-keys 2599 ;; Output no progress messages in `bibtex-parse-keys'
2460 ;; because when in y-or-n-p that can hide the question. 2600 ;; because when in `y-or-n-p' that can hide the question.
2461 (if (and (listp (bibtex-parse-keys t)) 2601 (if (and (listp (bibtex-parse-keys t))
2462 ;; update bibtex-strings 2602 ;; update `bibtex-strings'
2463 (listp (bibtex-parse-strings strings-init t))) 2603 (listp (bibtex-parse-strings strings-init t)))
2464 2604
2465 ;; remember that parsing was successful 2605 ;; remember that parsing was successful
2466 (setq bibtex-buffer-last-parsed-tick (buffer-modified-tick))))) 2606 (setq bibtex-buffer-last-parsed-tick (buffer-modified-tick)))))
2467 (setq buffers (cdr buffers)))))) 2607 (setq buffers (cdr buffers))))))
2517 (defun bibtex-complete-internal (completions) 2657 (defun bibtex-complete-internal (completions)
2518 "Complete word fragment before point to longest prefix of COMPLETIONS. 2658 "Complete word fragment before point to longest prefix of COMPLETIONS.
2519 COMPLETIONS is an alist of strings. If point is not after the part 2659 COMPLETIONS is an alist of strings. If point is not after the part
2520 of a word, all strings are listed. Return completion." 2660 of a word, all strings are listed. Return completion."
2521 ;; Return value is used by cleanup functions. 2661 ;; Return value is used by cleanup functions.
2662 ;; Code inspired by `lisp-complete-symbol'.
2522 (let* ((case-fold-search t) 2663 (let* ((case-fold-search t)
2523 (beg (save-excursion 2664 (beg (save-excursion
2524 (re-search-backward "[ \t{\"]") 2665 (re-search-backward "[ \t{\"]")
2525 (forward-char) 2666 (forward-char)
2526 (point))) 2667 (point)))
2527 (end (point)) 2668 (end (point))
2528 (part-of-word (buffer-substring-no-properties beg end)) 2669 (pattern (buffer-substring-no-properties beg end))
2529 (completion (try-completion part-of-word completions))) 2670 (completion (try-completion pattern completions)))
2530 (cond ((not completion) 2671 (cond ((not completion)
2531 (error "Can't find completion for `%s'" part-of-word)) 2672 (error "Can't find completion for `%s'" pattern))
2532 ((eq completion t) 2673 ((eq completion t)
2533 part-of-word) 2674 pattern)
2534 ((not (string= part-of-word completion)) 2675 ((not (string= pattern completion))
2535 (delete-region beg end) 2676 (delete-region beg end)
2536 (insert completion) 2677 (insert completion)
2678 ;; Don't leave around a completions buffer that's out of date.
2679 (let ((win (get-buffer-window "*Completions*" 0)))
2680 (if win (with-selected-window win (bury-buffer))))
2537 completion) 2681 completion)
2538 (t 2682 (t
2539 (message "Making completion list...") 2683 (let ((minibuf-is-in-use
2540 (with-output-to-temp-buffer "*Completions*" 2684 (eq (minibuffer-window) (selected-window))))
2541 (display-completion-list (all-completions part-of-word completions) 2685 (unless minibuf-is-in-use (message "Making completion list..."))
2542 part-of-word)) 2686 (with-output-to-temp-buffer "*Completions*"
2543 (message "Making completion list...done") 2687 (display-completion-list
2688 (sort (all-completions pattern completions) 'string<) pattern))
2689 (unless minibuf-is-in-use
2690 (message "Making completion list...done")))
2544 nil)))) 2691 nil))))
2545 2692
2546 (defun bibtex-complete-string-cleanup (str compl) 2693 (defun bibtex-complete-string-cleanup (str compl)
2547 "Cleanup after inserting string STR. 2694 "Cleanup after inserting string STR.
2548 Remove enclosing field delimiters for STR. Display message with 2695 Remove enclosing field delimiters for STR. Display message with
2560 (save-excursion 2707 (save-excursion
2561 (if (and (stringp key) 2708 (if (and (stringp key)
2562 (bibtex-find-entry key t)) 2709 (bibtex-find-entry key t))
2563 (message "Ref: %s" (funcall bibtex-summary-function))))) 2710 (message "Ref: %s" (funcall bibtex-summary-function)))))
2564 2711
2565 (defun bibtex-copy-summary-as-kill () 2712 (defun bibtex-copy-summary-as-kill (&optional arg)
2566 "Push summery of current BibTeX entry to kill ring. 2713 "Push summery of current BibTeX entry to kill ring.
2567 Use `bibtex-summary-function' to generate summary." 2714 Use `bibtex-summary-function' to generate summary.
2568 (interactive) 2715 If prefix ARG is non-nil push BibTeX entry's URL to kill ring
2569 (save-excursion 2716 that is generated by calling `bibtex-url'."
2570 (bibtex-beginning-of-entry) 2717 (interactive "P")
2571 (if (looking-at bibtex-entry-maybe-empty-head) 2718 (if arg (let ((url (bibtex-url nil t)))
2572 (kill-new (message "%s" (funcall bibtex-summary-function))) 2719 (if url (kill-new (message "%s" url))
2573 (error "No entry found")))) 2720 (message "No URL known")))
2721 (save-excursion
2722 (bibtex-beginning-of-entry)
2723 (if (looking-at bibtex-entry-maybe-empty-head)
2724 (kill-new (message "%s" (funcall bibtex-summary-function)))
2725 (error "No entry found")))))
2574 2726
2575 (defun bibtex-summary () 2727 (defun bibtex-summary ()
2576 "Return summary of current BibTeX entry. 2728 "Return summary of current BibTeX entry.
2577 Used as default value of `bibtex-summary-function'." 2729 Used as default value of `bibtex-summary-function'."
2578 ;; It would be neat to customize this function. How? 2730 ;; It would be neat to make this function customizable. How?
2579 (if (looking-at bibtex-entry-maybe-empty-head) 2731 (if (looking-at bibtex-entry-maybe-empty-head)
2580 (let* ((bibtex-autokey-name-case-convert-function 'identity) 2732 (let* ((bibtex-autokey-name-case-convert-function 'identity)
2581 (bibtex-autokey-name-length 'infty) 2733 (bibtex-autokey-name-length 'infty)
2582 (bibtex-autokey-names 1) 2734 (bibtex-autokey-names 1)
2583 (bibtex-autokey-names-stretch 0) 2735 (bibtex-autokey-names-stretch 0)
2662 (let ((field-reg (concat "^[ \t]*" bibtex-field-name "[ \t]*="))) 2814 (let ((field-reg (concat "^[ \t]*" bibtex-field-name "[ \t]*=")))
2663 (beginning-of-line) 2815 (beginning-of-line)
2664 (unless (looking-at field-reg) 2816 (unless (looking-at field-reg)
2665 (re-search-backward field-reg nil t)))) 2817 (re-search-backward field-reg nil t))))
2666 2818
2667 (defun bibtex-font-lock-url (bound) 2819 (defun bibtex-font-lock-url (bound &optional no-button)
2668 "Font-lock for URLs. BOUND limits the search." 2820 "Font-lock for URLs. BOUND limits the search.
2821 If NO-BUTTON is non-nil do not generate buttons."
2669 (let ((case-fold-search t) 2822 (let ((case-fold-search t)
2670 (pnt (point)) 2823 (pnt (point))
2671 field bounds start end found) 2824 name bounds start end found)
2672 (bibtex-beginning-of-field) 2825 (bibtex-beginning-of-field)
2673 (while (and (not found) 2826 (while (and (not found)
2674 (<= (point) bound) 2827 (<= (point) bound)
2675 (prog1 (re-search-forward bibtex-font-lock-url-regexp bound t) 2828 (prog1 (re-search-forward bibtex-font-lock-url-regexp bound t)
2676 (setq field (match-string-no-properties 1))) 2829 (setq name (match-string-no-properties 1)))
2677 (setq bounds (bibtex-parse-field-text)) 2830 (setq bounds (bibtex-parse-field-text))
2678 (progn 2831 (progn
2679 (setq start (car bounds) end (nth 1 bounds)) 2832 (setq start (car bounds) end (nth 1 bounds))
2680 ;; Always ignore field delimiters 2833 ;; Always ignore field delimiters
2681 (if (memq (char-before end) '(?\} ?\")) 2834 (if (memq (char-before end) '(?\} ?\"))
2682 (setq end (1- end))) 2835 (setq end (1- end)))
2683 (if (memq (char-after start) '(?\{ ?\")) 2836 (if (memq (char-after start) '(?\{ ?\"))
2684 (setq start (1+ start))) 2837 (setq start (1+ start)))
2685 (>= bound start))) 2838 (if (< start pnt) (setq start (min pnt end)))
2686 (let ((lst bibtex-generate-url-list) url) 2839 (<= start bound)))
2687 (goto-char start) 2840 (if (<= pnt start)
2688 (while (and (not found) 2841 (let ((lst bibtex-generate-url-list) url)
2689 (setq url (car (pop lst)))) 2842 (while (and (not found) (setq url (car (pop lst))))
2690 (setq found (and (bibtex-string= field (car url)) 2843 (goto-char start)
2691 (re-search-forward (cdr url) end t) 2844 (setq found (and (bibtex-string= name (car url))
2692 (>= (match-beginning 0) pnt))))) 2845 (re-search-forward (cdr url) end t))))))
2693 (goto-char end)) 2846 (unless found (goto-char end)))
2694 (if found (bibtex-button (match-beginning 0) (match-end 0) 2847 (if (and found (not no-button))
2695 'bibtex-url (match-beginning 0))) 2848 (bibtex-button (match-beginning 0) (match-end 0)
2849 'bibtex-url (match-beginning 0)))
2696 found)) 2850 found))
2697 2851
2698 (defun bibtex-font-lock-crossref (bound) 2852 (defun bibtex-font-lock-crossref (bound)
2699 "Font-lock for crossref fields. BOUND limits the search." 2853 "Font-lock for crossref fields. BOUND limits the search."
2700 (let ((case-fold-search t) 2854 (let ((case-fold-search t)
2710 found (>= start pnt))) 2864 found (>= start pnt)))
2711 (if found (bibtex-button start end 'bibtex-find-crossref 2865 (if found (bibtex-button start end 'bibtex-find-crossref
2712 (buffer-substring-no-properties start end) 2866 (buffer-substring-no-properties start end)
2713 start t)) 2867 start t))
2714 found)) 2868 found))
2869
2870 (defun bibtex-font-lock-cite (matcher bound)
2871 "Font-lock for cited keys.
2872 MATCHER identifies the cited key, see `bibtex-cite-matcher-alist'.
2873 BOUND limits the search."
2874 (let (case-fold-search)
2875 (if (re-search-forward (car matcher) bound t)
2876 (let ((start (match-beginning (cdr matcher)))
2877 (end (match-end (cdr matcher))))
2878 (bibtex-button start end 'bibtex-find-crossref
2879 (buffer-substring-no-properties start end)
2880 start t t)
2881 t))))
2715 2882
2716 (defun bibtex-button-action (button) 2883 (defun bibtex-button-action (button)
2717 "Call BUTTON's BibTeX function." 2884 "Call BUTTON's BibTeX function."
2718 (apply (button-get button 'bibtex-function) 2885 (apply (button-get button 'bibtex-function)
2719 (button-get button 'bibtex-args))) 2886 (button-get button 'bibtex-args)))
2829 (bibtex-beginning-of-entry))))) 2996 (bibtex-beginning-of-entry)))))
2830 (setq imenu-generic-expression 2997 (setq imenu-generic-expression
2831 (list (list nil bibtex-entry-head bibtex-key-in-head)) 2998 (list (list nil bibtex-entry-head bibtex-key-in-head))
2832 imenu-case-fold-search t) 2999 imenu-case-fold-search t)
2833 (make-local-variable 'choose-completion-string-functions) 3000 (make-local-variable 'choose-completion-string-functions)
2834 ;; XEmacs needs easy-menu-add, Emacs does not care 3001 ;; XEmacs needs `easy-menu-add', Emacs does not care
2835 (easy-menu-add bibtex-edit-menu) 3002 (easy-menu-add bibtex-edit-menu)
2836 (easy-menu-add bibtex-entry-menu) 3003 (easy-menu-add bibtex-entry-menu)
2837 (run-mode-hooks 'bibtex-mode-hook)) 3004 (run-mode-hooks 'bibtex-mode-hook))
2838 3005
2839 (defun bibtex-field-list (entry-type) 3006 (defun bibtex-field-list (entry-type)
3123 ;; @String or @Preamble 3290 ;; @String or @Preamble
3124 ((setq bounds (or (bibtex-parse-string t) (bibtex-parse-preamble))) 3291 ((setq bounds (or (bibtex-parse-string t) (bibtex-parse-preamble)))
3125 (goto-char (bibtex-end-of-string bounds))) 3292 (goto-char (bibtex-end-of-string bounds)))
3126 ((looking-at bibtex-any-valid-entry-type) 3293 ((looking-at bibtex-any-valid-entry-type)
3127 ;; Parsing of entry failed 3294 ;; Parsing of entry failed
3128 (error "Syntactically incorrect BibTeX entry starts here.")) 3295 (error "Syntactically incorrect BibTeX entry starts here"))
3129 (t (if (interactive-p) (message "Not on a known BibTeX entry.")) 3296 (t (if (interactive-p) (message "Not on a known BibTeX entry."))
3130 (goto-char pnt))) 3297 (goto-char pnt)))
3131 (point))) 3298 (point)))
3132 3299
3133 (defun bibtex-goto-line (arg) 3300 (defun bibtex-goto-line (arg)
3161 (goto-char pnt))))) 3328 (goto-char pnt)))))
3162 3329
3163 (defun bibtex-mark-entry () 3330 (defun bibtex-mark-entry ()
3164 "Put mark at beginning, point at end of current BibTeX entry." 3331 "Put mark at beginning, point at end of current BibTeX entry."
3165 (interactive) 3332 (interactive)
3166 (set-mark (bibtex-beginning-of-entry)) 3333 (push-mark (bibtex-beginning-of-entry))
3167 (bibtex-end-of-entry)) 3334 (bibtex-end-of-entry))
3168 3335
3169 (defun bibtex-count-entries (&optional count-string-entries) 3336 (defun bibtex-count-entries (&optional count-string-entries)
3170 "Count number of entries in current buffer or region. 3337 "Count number of entries in current buffer or region.
3171 With prefix argument COUNT-STRING-ENTRIES count all entries, 3338 With prefix argument COUNT-STRING-ENTRIES count all entries,
3225 (if bounds (bibtex-text-in-field-bounds bounds t)) 3392 (if bounds (bibtex-text-in-field-bounds bounds t))
3226 entry-name)) 3393 entry-name))
3227 (list key nil entry-name)))))) 3394 (list key nil entry-name))))))
3228 3395
3229 (defun bibtex-init-sort-entry-class-alist () 3396 (defun bibtex-init-sort-entry-class-alist ()
3397 "Initialize `bibtex-sort-entry-class-alist' (buffer-local)."
3230 (unless (local-variable-p 'bibtex-sort-entry-class-alist) 3398 (unless (local-variable-p 'bibtex-sort-entry-class-alist)
3231 (set (make-local-variable 'bibtex-sort-entry-class-alist) 3399 (set (make-local-variable 'bibtex-sort-entry-class-alist)
3232 (let ((i -1) alist) 3400 (let ((i -1) alist)
3233 (dolist (class bibtex-sort-entry-class alist) 3401 (dolist (class bibtex-sort-entry-class alist)
3234 (setq i (1+ i)) 3402 (setq i (1+ i))
3281 'bibtex-end-of-entry ; ENDREC function 3449 'bibtex-end-of-entry ; ENDREC function
3282 'bibtex-entry-index ; STARTKEY function 3450 'bibtex-entry-index ; STARTKEY function
3283 nil ; ENDKEY function 3451 nil ; ENDKEY function
3284 'bibtex-lessp)) ; PREDICATE 3452 'bibtex-lessp)) ; PREDICATE
3285 3453
3286 (defun bibtex-find-crossref (crossref-key &optional pnt split) 3454 (defun bibtex-find-crossref (crossref-key &optional pnt split noerror)
3287 "Move point to the beginning of BibTeX entry CROSSREF-KEY. 3455 "Move point to the beginning of BibTeX entry CROSSREF-KEY.
3288 If `bibtex-files' is non-nil, search all these files. 3456 If `bibtex-files' is non-nil, search all these files.
3289 Otherwise the search is limited to the current buffer. 3457 Otherwise the search is limited to the current buffer.
3290 Return position of entry if CROSSREF-KEY is found or nil otherwise. 3458 Return position of entry if CROSSREF-KEY is found or nil otherwise.
3291 If CROSSREF-KEY is in the same buffer like current entry but before it 3459 If CROSSREF-KEY is in the same buffer like current entry but before it
3292 an error is signaled. Optional arg PNT is the position of the referencing 3460 an error is signaled. If NOERRER is non-nil this error is suppressed.
3293 entry. It defaults to position of point. If optional arg SPLIT is non-nil, 3461 Optional arg PNT is the position of the referencing entry. It defaults
3294 split window so that both the referencing and the crossrefed entry are 3462 to position of point. If optional arg SPLIT is non-nil, split window
3295 displayed. 3463 so that both the referencing and the crossrefed entry are displayed.
3296 If called interactively, CROSSREF-KEY defaults to crossref key of current 3464
3297 entry and SPLIT is t." 3465 If called interactively, CROSSREF-KEY defaults to either the crossref key
3466 of current entry or a key matched by `bibtex-cite-matcher-alist',
3467 whatever is nearer to the position of point. SPLIT is t. NOERROR is nil
3468 for a crossref key, t otherwise."
3298 (interactive 3469 (interactive
3299 (let ((crossref-key 3470 (save-excursion
3300 (save-excursion 3471 (let* ((pnt (point))
3301 (bibtex-beginning-of-entry) 3472 (_ (bibtex-beginning-of-entry))
3302 (let ((bounds (bibtex-search-forward-field "crossref" t))) 3473 (end (cdr (bibtex-valid-entry t)))
3303 (if bounds 3474 (_ (unless end (error "Not inside valid entry")))
3304 (bibtex-text-in-field-bounds bounds t)))))) 3475 (beg (match-end 0)) ; set by `bibtex-valid-entry'
3305 (list (bibtex-read-key "Find crossref key: " crossref-key t) 3476 (bounds (bibtex-search-forward-field "crossref" end))
3306 (point) t))) 3477 case-fold-search best temp crossref-key)
3478 (if bounds
3479 (setq crossref-key (bibtex-text-in-field-bounds bounds t)
3480 best (cons (bibtex-dist pnt (bibtex-end-of-field bounds)
3481 (bibtex-start-of-field bounds))
3482 crossref-key)))
3483 (dolist (matcher bibtex-cite-matcher-alist)
3484 (goto-char beg)
3485 (while (re-search-forward (car matcher) end t)
3486 (setq temp (bibtex-dist pnt (match-end (cdr matcher))
3487 (match-beginning (cdr matcher))))
3488 ;; Accept the key closest to the position of point.
3489 (if (or (not best) (< temp (car best)))
3490 (setq best (cons temp (match-string-no-properties
3491 (cdr matcher)))))))
3492 (goto-char pnt)
3493 (setq temp (bibtex-read-key "Find crossref key: " (cdr best) t))
3494 (list temp (point) t (not (and crossref-key
3495 (string= temp crossref-key)))))))
3496
3307 (let (buffer pos eqb) 3497 (let (buffer pos eqb)
3308 (save-excursion 3498 (save-excursion
3309 (setq pos (bibtex-find-entry crossref-key t) 3499 (setq pos (bibtex-find-entry crossref-key t)
3310 buffer (current-buffer))) 3500 buffer (current-buffer)))
3311 (setq eqb (eq buffer (current-buffer))) 3501 (setq eqb (eq buffer (current-buffer)))
3312 (cond ((not pos) 3502 (cond ((not pos)
3313 (if split (message "Crossref key `%s' not found" crossref-key))) 3503 (if split (message "Crossref key `%s' not found" crossref-key)))
3314 (split ; called (quasi) interactively 3504 (split ; called (quasi) interactively
3315 (unless pnt (setq pnt (point))) 3505 (unless pnt (setq pnt (point)))
3316 (goto-char pnt) 3506 (goto-char pnt)
3317 (if eqb (select-window (split-window)) 3507 (if (and eqb (= pos (save-excursion (bibtex-beginning-of-entry))))
3318 (pop-to-buffer buffer)) 3508 (message "Key `%s' is current entry" crossref-key)
3319 (goto-char pos) 3509 (if eqb (select-window (split-window))
3320 (bibtex-reposition-window) 3510 (pop-to-buffer buffer))
3321 (beginning-of-line) 3511 (goto-char pos)
3322 (if (and eqb (> pnt pos)) 3512 (bibtex-reposition-window)
3323 (error "The referencing entry must precede the crossrefed entry!"))) 3513 (beginning-of-line)
3514 (if (and eqb (> pnt pos) (not noerror))
3515 (error "The referencing entry must precede the crossrefed entry!"))))
3324 ;; `bibtex-find-crossref' is called noninteractively during 3516 ;; `bibtex-find-crossref' is called noninteractively during
3325 ;; clean-up of an entry. Then it is not possible to check 3517 ;; clean-up of an entry. Then it is not possible to check
3326 ;; whether the current entry and the crossrefed entry have 3518 ;; whether the current entry and the crossrefed entry have
3327 ;; the correct sorting order. 3519 ;; the correct sorting order.
3328 (eqb (goto-char pos)) 3520 (eqb (goto-char pos))
3329 (t (set-buffer buffer) (goto-char pos))) 3521 (t (set-buffer buffer) (goto-char pos)))
3330 pos)) 3522 pos))
3523
3524 (defun bibtex-dist (pos beg end)
3525 "Return distance between POS and region delimited by BEG and END."
3526 (cond ((and (<= beg pos) (<= pos end)) 0)
3527 ((< pos beg) (- beg pos))
3528 (t (- pos end))))
3331 3529
3332 (defun bibtex-find-entry (key &optional global start display) 3530 (defun bibtex-find-entry (key &optional global start display)
3333 "Move point to the beginning of BibTeX entry named KEY. 3531 "Move point to the beginning of BibTeX entry named KEY.
3334 Return position of entry if KEY is found or nil if not found. 3532 Return position of entry if KEY is found or nil if not found.
3335 With prefix arg GLOBAL non-nil, search KEY in `bibtex-files'. 3533 With prefix arg GLOBAL non-nil, search KEY in `bibtex-files'.
3392 (not bibtex-maintain-sorted-entries))) 3590 (not bibtex-maintain-sorted-entries)))
3393 (bibtex-move-outside-of-entry)) 3591 (bibtex-move-outside-of-entry))
3394 ;; if key-exist is non-nil due to the previous cond clause 3592 ;; if key-exist is non-nil due to the previous cond clause
3395 ;; then point will be at beginning of entry named key. 3593 ;; then point will be at beginning of entry named key.
3396 (key-exist) 3594 (key-exist)
3397 (t ; bibtex-maintain-sorted-entries is non-nil 3595 (t ; `bibtex-maintain-sorted-entries' is non-nil
3398 (let* ((case-fold-search t) 3596 (let* ((case-fold-search t)
3399 (left (save-excursion (bibtex-beginning-of-first-entry))) 3597 (left (save-excursion (bibtex-beginning-of-first-entry)))
3400 (bounds (save-excursion (goto-char (point-max)) 3598 (bounds (save-excursion (goto-char (point-max))
3401 (bibtex-skip-to-valid-entry t))) 3599 (bibtex-skip-to-valid-entry t)))
3402 (right (if bounds (cdr bounds) (point-min))) 3600 (right (if bounds (cdr bounds) (point-min)))
3574 (unless (eq major-mode 'compilation-mode) (compilation-mode)) 3772 (unless (eq major-mode 'compilation-mode) (compilation-mode))
3575 (toggle-read-only -1) 3773 (toggle-read-only -1)
3576 (delete-region (point-min) (point-max)) 3774 (delete-region (point-min) (point-max))
3577 (insert "BibTeX mode command `bibtex-validate'\n" 3775 (insert "BibTeX mode command `bibtex-validate'\n"
3578 (if syntax-error 3776 (if syntax-error
3579 "Maybe undetected errors due to syntax errors. Correct and validate again.\n" 3777 "Maybe undetected errors due to syntax errors. Correct and validate again.\n"
3580 "\n")) 3778 "\n"))
3581 (dolist (err error-list) 3779 (dolist (err error-list)
3582 (insert (format "%s:%d: %s\n" file (car err) (cdr err)))) 3780 (insert (format "%s:%d: %s\n" file (car err) (cdr err))))
3583 (set-buffer-modified-p nil) 3781 (set-buffer-modified-p nil)
3584 (toggle-read-only 1) 3782 (toggle-read-only 1)
3735 start-text (or (match-beginning bibtex-key-in-head) 3933 start-text (or (match-beginning bibtex-key-in-head)
3736 (match-end 0)) 3934 (match-end 0))
3737 end-text (or (match-end bibtex-key-in-head) 3935 end-text (or (match-end bibtex-key-in-head)
3738 (match-end 0)) 3936 (match-end 0))
3739 end end-text 3937 end end-text
3740 no-sub t) ;; subfields do not make sense 3938 no-sub t) ; subfields do not make sense
3741 (setq failure t))) 3939 (setq failure t)))
3742 (t (setq failure t))) 3940 (t (setq failure t)))
3743 (when (and subfield (not failure)) 3941 (when (and subfield (not failure))
3744 (setq failure no-sub) 3942 (setq failure no-sub)
3745 (unless failure 3943 (unless failure
3924 begin on separate lines prior to calling `bibtex-clean-entry' or if 4122 begin on separate lines prior to calling `bibtex-clean-entry' or if
3925 'realign is contained in `bibtex-entry-format'.) 4123 'realign is contained in `bibtex-entry-format'.)
3926 Don't call `bibtex-clean-entry' on @Preamble entries. 4124 Don't call `bibtex-clean-entry' on @Preamble entries.
3927 At end of the cleaning process, the functions in 4125 At end of the cleaning process, the functions in
3928 `bibtex-clean-entry-hook' are called with region narrowed to entry." 4126 `bibtex-clean-entry-hook' are called with region narrowed to entry."
3929 ;; Opt. arg called-by-reformat is t if bibtex-clean-entry 4127 ;; Opt. arg CALLED-BY-REFORMAT is t if `bibtex-clean-entry'
3930 ;; is called by bibtex-reformat 4128 ;; is called by `bibtex-reformat'
3931 (interactive "P") 4129 (interactive "P")
3932 (let ((case-fold-search t) 4130 (let ((case-fold-search t)
3933 (start (bibtex-beginning-of-entry)) 4131 (start (bibtex-beginning-of-entry))
3934 (_ (or (looking-at bibtex-any-entry-maybe-empty-head) 4132 (_ (or (looking-at bibtex-any-entry-maybe-empty-head)
3935 (error "Not inside a BibTeX entry"))) 4133 (error "Not inside a BibTeX entry")))
3944 ;; (bibtex-format-string) 4142 ;; (bibtex-format-string)
3945 (t (bibtex-format-entry))) 4143 (t (bibtex-format-entry)))
3946 ;; set key 4144 ;; set key
3947 (when (or new-key (not key)) 4145 (when (or new-key (not key))
3948 (setq key (bibtex-generate-autokey)) 4146 (setq key (bibtex-generate-autokey))
3949 ;; Sometimes bibtex-generate-autokey returns an empty string 4147 ;; Sometimes `bibtex-generate-autokey' returns an empty string
3950 (if (or bibtex-autokey-edit-before-use (string= "" key)) 4148 (if (or bibtex-autokey-edit-before-use (string= "" key))
3951 (setq key (if (eq entry-type 'string) 4149 (setq key (if (eq entry-type 'string)
3952 (bibtex-read-string-key key) 4150 (bibtex-read-string-key key)
3953 (bibtex-read-key "Key to use: " key)))) 4151 (bibtex-read-key "Key to use: " key))))
3954 (save-excursion 4152 (save-excursion
4025 If optional arg MOVE is non-nil move point to end of field." 4223 If optional arg MOVE is non-nil move point to end of field."
4026 (let ((end-field (copy-marker (bibtex-end-of-field bounds)))) 4224 (let ((end-field (copy-marker (bibtex-end-of-field bounds))))
4027 (if (not justify) 4225 (if (not justify)
4028 (goto-char (bibtex-start-of-text-in-field bounds)) 4226 (goto-char (bibtex-start-of-text-in-field bounds))
4029 (goto-char (bibtex-start-of-field bounds)) 4227 (goto-char (bibtex-start-of-field bounds))
4030 (forward-char) ;; leading comma 4228 (forward-char) ; leading comma
4031 (bibtex-delete-whitespace) 4229 (bibtex-delete-whitespace)
4032 (open-line 1) 4230 (open-line 1)
4033 (forward-char) 4231 (forward-char)
4034 (indent-to-column (+ bibtex-entry-offset 4232 (indent-to-column (+ bibtex-entry-offset
4035 bibtex-field-indentation)) 4233 bibtex-field-indentation))
4043 (forward-char) 4241 (forward-char)
4044 (bibtex-delete-whitespace) 4242 (bibtex-delete-whitespace)
4045 (if bibtex-align-at-equal-sign 4243 (if bibtex-align-at-equal-sign
4046 (insert " ") 4244 (insert " ")
4047 (indent-to-column bibtex-text-indentation))) 4245 (indent-to-column bibtex-text-indentation)))
4048 ;; Paragraphs within fields are not preserved. Bother? 4246 ;; Paragraphs within fields are not preserved. Bother?
4049 (fill-region-as-paragraph (line-beginning-position) end-field 4247 (fill-region-as-paragraph (line-beginning-position) end-field
4050 default-justification nil (point)) 4248 default-justification nil (point))
4051 (if move (goto-char end-field)))) 4249 (if move (goto-char end-field))))
4052 4250
4053 (defun bibtex-fill-field (&optional justify) 4251 (defun bibtex-fill-field (&optional justify)
4128 ("Remove empty optional and alternative fields? " . 'opts-or-alts) 4326 ("Remove empty optional and alternative fields? " . 'opts-or-alts)
4129 ("Remove delimiters around pure numerical fields? " . 'numerical-fields) 4327 ("Remove delimiters around pure numerical fields? " . 'numerical-fields)
4130 (,(concat (if bibtex-comma-after-last-field "Insert" "Remove") 4328 (,(concat (if bibtex-comma-after-last-field "Insert" "Remove")
4131 " comma at end of entry? ") . 'last-comma) 4329 " comma at end of entry? ") . 'last-comma)
4132 ("Replace double page dashes by single ones? " . 'page-dashes) 4330 ("Replace double page dashes by single ones? " . 'page-dashes)
4331 ("Delete whitespace at the beginning and end of fields? " . 'whitespace)
4133 ("Inherit booktitle? " . 'inherit-booktitle) 4332 ("Inherit booktitle? " . 'inherit-booktitle)
4134 ("Force delimiters? " . 'delimiters) 4333 ("Force delimiters? " . 'delimiters)
4135 ("Unify case of entry types and field names? " . 'unify-case)))))) 4334 ("Unify case of entry types and field names? " . 'unify-case)
4335 ("Enclose parts of field entries by braces? " . 'braces)
4336 ("Replace parts of field entries by string constants? " . 'strings))))))
4136 ;; Do not include required-fields because `bibtex-reformat' 4337 ;; Do not include required-fields because `bibtex-reformat'
4137 ;; cannot handle the error messages of `bibtex-format-entry'. 4338 ;; cannot handle the error messages of `bibtex-format-entry'.
4138 ;; Use `bibtex-validate' to check for required fields. 4339 ;; Use `bibtex-validate' to check for required fields.
4139 ((eq t bibtex-entry-format) 4340 ((eq t bibtex-entry-format)
4140 '(realign opts-or-alts numerical-fields delimiters 4341 '(realign opts-or-alts numerical-fields delimiters
4141 last-comma page-dashes unify-case inherit-booktitle)) 4342 last-comma page-dashes unify-case inherit-booktitle
4343 whitespace braces strings))
4142 (t 4344 (t
4143 (remove 'required-fields (push 'realign bibtex-entry-format))))) 4345 (remove 'required-fields (push 'realign bibtex-entry-format)))))
4144 (reformat-reference-keys 4346 (reformat-reference-keys
4145 (if read-options 4347 (if read-options
4146 (if use-previous-options 4348 (if use-previous-options
4176 entries from minibuffer." 4378 entries from minibuffer."
4177 (interactive "*P") 4379 (interactive "*P")
4178 (message "Starting to validate buffer...") 4380 (message "Starting to validate buffer...")
4179 (sit-for 1 nil t) 4381 (sit-for 1 nil t)
4180 (bibtex-realign) 4382 (bibtex-realign)
4181 (deactivate-mark) ; So bibtex-validate works on the whole buffer. 4383 (deactivate-mark) ; So `bibtex-validate' works on the whole buffer.
4182 (if (not (let (bibtex-maintain-sorted-entries) 4384 (if (not (let (bibtex-maintain-sorted-entries)
4183 (bibtex-validate))) 4385 (bibtex-validate)))
4184 (message "Correct errors and call `bibtex-convert-alien' again") 4386 (message "Correct errors and call `bibtex-convert-alien' again")
4185 (message "Starting to reformat entries...") 4387 (message "Starting to reformat entries...")
4186 (sit-for 2 nil t) 4388 (sit-for 2 nil t)
4187 (bibtex-reformat read-options) 4389 (bibtex-reformat read-options)
4188 (goto-char (point-max)) 4390 (goto-char (point-max))
4189 (message "Buffer is now parsable. Please save it."))) 4391 (message "Buffer is now parsable. Please save it.")))
4190 4392
4191 (defun bibtex-complete () 4393 (defun bibtex-complete ()
4192 "Complete word fragment before point according to context. 4394 "Complete word fragment before point according to context.
4193 If point is inside key or crossref field perform key completion based on 4395 If point is inside key or crossref field perform key completion based on
4194 `bibtex-reference-keys'. Inside a month field perform key completion 4396 `bibtex-reference-keys'. Inside a month field perform key completion
4247 ((eq compl 'crossref-key) 4449 ((eq compl 'crossref-key)
4248 ;; crossref key completion 4450 ;; crossref key completion
4249 ;; 4451 ;;
4250 ;; If we quit the *Completions* buffer without requesting 4452 ;; If we quit the *Completions* buffer without requesting
4251 ;; a completion, `choose-completion-string-functions' is still 4453 ;; a completion, `choose-completion-string-functions' is still
4252 ;; non-nil. Therefore, `choose-completion-string-functions' is 4454 ;; non-nil. Therefore, `choose-completion-string-functions' is
4253 ;; always set (either to non-nil or nil) when a new completion 4455 ;; always set (either to non-nil or nil) when a new completion
4254 ;; is requested. 4456 ;; is requested.
4255 (let (completion-ignore-case) 4457 (let (completion-ignore-case)
4256 (setq choose-completion-string-functions 4458 (setq choose-completion-string-functions
4257 (lambda (choice buffer mini-p base-size) 4459 (lambda (choice buffer mini-p base-size)
4274 (setq choose-completion-string-functions 4476 (setq choose-completion-string-functions
4275 `(lambda (choice buffer mini-p base-size) 4477 `(lambda (choice buffer mini-p base-size)
4276 (setq choose-completion-string-functions nil) 4478 (setq choose-completion-string-functions nil)
4277 (choose-completion-string choice buffer base-size) 4479 (choose-completion-string choice buffer base-size)
4278 (bibtex-complete-string-cleanup choice ',compl) 4480 (bibtex-complete-string-cleanup choice ',compl)
4279 t)) ; needed by choose-completion-string-functions 4481 t)) ; needed by `choose-completion-string-functions'
4280 (bibtex-complete-string-cleanup (bibtex-complete-internal compl) 4482 (bibtex-complete-string-cleanup (bibtex-complete-internal compl)
4281 compl))) 4483 compl)))
4282 4484
4283 (t (setq choose-completion-string-functions nil) 4485 (t (setq choose-completion-string-functions nil)
4284 (error "Point outside key or BibTeX field"))))) 4486 (error "Point outside key or BibTeX field")))))
4389 4591
4390 (defun bibtex-url (&optional pos no-browse) 4592 (defun bibtex-url (&optional pos no-browse)
4391 "Browse a URL for the BibTeX entry at point. 4593 "Browse a URL for the BibTeX entry at point.
4392 Optional POS is the location of the BibTeX entry. 4594 Optional POS is the location of the BibTeX entry.
4393 The URL is generated using the schemes defined in `bibtex-generate-url-list' 4595 The URL is generated using the schemes defined in `bibtex-generate-url-list'
4394 \(see there\). Then the URL is passed to `browse-url' unless NO-BROWSE is nil. 4596 \(see there\). If multiple schemes match for this entry, or the same scheme
4597 matches more than once, use the one for which the first step's match is the
4598 closest to POS. The URL is passed to `browse-url' unless NO-BROWSE is t.
4395 Return the URL or nil if none can be generated." 4599 Return the URL or nil if none can be generated."
4396 (interactive) 4600 (interactive)
4601 (unless pos (setq pos (point)))
4397 (save-excursion 4602 (save-excursion
4398 (if pos (goto-char pos)) 4603 (goto-char pos)
4399 (bibtex-beginning-of-entry) 4604 (bibtex-beginning-of-entry)
4400 ;; Always remove field delimiters 4605 (let ((end (save-excursion (bibtex-end-of-entry)))
4401 (let ((fields-alist (bibtex-parse-entry t)) 4606 (fields-alist (save-excursion (bibtex-parse-entry t)))
4402 ;; Always ignore case, 4607 ;; Always ignore case,
4403 (case-fold-search t) 4608 (case-fold-search t)
4404 (lst bibtex-generate-url-list) 4609 text url scheme obj fmt fl-match step)
4405 field url scheme obj fmt) 4610 ;; The return value of `bibtex-parse-entry' (i.e., FIELDS-ALIST)
4406 (while (setq scheme (pop lst)) 4611 ;; is always used to generate the URL. However, if the BibTeX
4407 (when (and (setq field (cdr (assoc-string (caar scheme) 4612 ;; entry contains more than one URL, we have multiple matches
4408 fields-alist t))) 4613 ;; for the first step defining the generation of the URL.
4409 (string-match (cdar scheme) field)) 4614 ;; Therefore, we try to initiate the generation of the URL
4410 (setq lst nil 4615 ;; based on the match of `bibtex-font-lock-url' that is the
4411 scheme (cdr scheme) 4616 ;; closest to POS. If that fails (no match found) we try to
4412 url (if (null scheme) (match-string 0 field) 4617 ;; initiate the generation of the URL based on the properly
4413 (if (stringp (car scheme)) 4618 ;; concatenated CONTENT of the field as returned by
4414 (setq fmt (pop scheme))) 4619 ;; `bibtex-text-in-field-bounds'. The latter approach can
4415 (dolist (step scheme) 4620 ;; differ from the former because `bibtex-font-lock-url' uses
4416 (setq field (cdr (assoc-string (car step) fields-alist t))) 4621 ;; the buffer itself.
4417 (if (string-match (nth 1 step) field) 4622 (while (bibtex-font-lock-url end t)
4418 (push (cond ((functionp (nth 2 step)) 4623 (push (list (bibtex-dist pos (match-beginning 0) (match-end 0))
4419 (funcall (nth 2 step) field)) 4624 (match-beginning 0)
4420 ((numberp (nth 2 step)) 4625 (buffer-substring-no-properties
4421 (match-string (nth 2 step) field)) 4626 (match-beginning 0) (match-end 0)))
4422 (t 4627 fl-match)
4423 (replace-match (nth 2 step) t nil field))) 4628 ;; `bibtex-font-lock-url' moves point to end of match.
4424 obj) 4629 (forward-char))
4425 ;; If the scheme is set up correctly, 4630 (when fl-match
4426 ;; we should never reach this point 4631 (setq fl-match (car (sort fl-match (lambda (x y) (< (car x) (car y))))))
4427 (error "Match failed: %s" field))) 4632 (goto-char (nth 1 fl-match))
4428 (if fmt (apply 'format fmt (nreverse obj)) 4633 (bibtex-beginning-of-field) (re-search-backward ",")
4429 (apply 'concat (nreverse obj))))) 4634 (let* ((bounds (bibtex-parse-field))
4430 (if (interactive-p) (message "%s" url)) 4635 (name (bibtex-name-in-field bounds))
4431 (unless no-browse (browse-url url)))) 4636 (content (bibtex-text-in-field-bounds bounds t))
4637 (lst bibtex-generate-url-list))
4638 ;; This match can fail when CONTENT differs from text in buffer.
4639 (when (string-match (regexp-quote (nth 2 fl-match)) content)
4640 ;; TEXT is the part of CONTENT that starts with the match
4641 ;; of `bibtex-font-lock-url' we are looking for.
4642 (setq text (substring content (match-beginning 0)))
4643 (while (and (not url) (setq scheme (pop lst)))
4644 ;; Verify the match of `bibtex-font-lock-url' by
4645 ;; comparing with TEXT.
4646 (when (and (bibtex-string= (caar scheme) name)
4647 (string-match (cdar scheme) text))
4648 (setq url t scheme (cdr scheme)))))))
4649
4650 ;; If the match of `bibtex-font-lock-url' was not approved
4651 ;; parse FIELDS-ALIST, i.e., the output of `bibtex-parse-entry'.
4652 (unless url
4653 (let ((lst bibtex-generate-url-list))
4654 (while (and (not url) (setq scheme (pop lst)))
4655 (when (and (setq text (cdr (assoc-string (caar scheme)
4656 fields-alist t)))
4657 (string-match (cdar scheme) text))
4658 (setq url t scheme (cdr scheme))))))
4659
4660 (when url
4661 (setq url (if (null scheme) (match-string 0 text)
4662 (if (stringp (car scheme))
4663 (setq fmt (pop scheme)))
4664 (dotimes (i (length scheme))
4665 (setq step (nth i scheme))
4666 ;; The first step shall use TEXT as obtained earlier.
4667 (unless (= i 0)
4668 (setq text (cdr (assoc-string (car step) fields-alist t))))
4669 (if (string-match (nth 1 step) text)
4670 (push (cond ((functionp (nth 2 step))
4671 (funcall (nth 2 step) text))
4672 ((numberp (nth 2 step))
4673 (match-string (nth 2 step) text))
4674 (t
4675 (replace-match (nth 2 step) t nil text)))
4676 obj)
4677 ;; If SCHEME is set up correctly,
4678 ;; we should never reach this point
4679 (error "Match failed: %s" text)))
4680 (if fmt (apply 'format fmt (nreverse obj))
4681 (apply 'concat (nreverse obj)))))
4682 (if (interactive-p) (message "%s" url))
4683 (unless no-browse (browse-url url)))
4432 (if (and (not url) (interactive-p)) (message "No URL known.")) 4684 (if (and (not url) (interactive-p)) (message "No URL known."))
4433 url))) 4685 url)))
4434 4686
4435 4687
4436 ;; Make BibTeX a Feature 4688 ;; Make BibTeX a Feature