aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoland Winkler2005-12-29 15:25:28 +0000
committerRoland Winkler2005-12-29 15:25:28 +0000
commitffc1e1db038d748fd94c8d0f1f17d9193d114c7e (patch)
tree96fddbc45a93928ffd029bf4b883b583f7ffab92
parent88ec8c53c63b091d8b7ccc8fef3b5948f4c0a53e (diff)
downloademacs-ffc1e1db038d748fd94c8d0f1f17d9193d114c7e.tar.gz
emacs-ffc1e1db038d748fd94c8d0f1f17d9193d114c7e.zip
(bibtex-entry-type-whitespace)
(bibtex-entry-type-str, bibtex-empty-field-re) (bibtex-search-backward-string, bibtex-preamble-prefix) (bibtex-search-entry, bibtex-enclosing-entry-maybe-empty-head): Removed. (bibtex-any-valid-entry-type): New variable. (bibtex-parse-field-name): Simplify. (bibtex-parse-string, bibtex-search-forward-string): New arg empty-key. (bibtex-preamble-prefix): Include left delimiter. (bibtex-search-forward-field, bibtex-search-backward-field): Allow unbounded search past entry boundaries (required by bibtex-pop). (bibtex-text-in-field-bounds): Use push. (bibtex-text-in-field): Do not use bibtex-narrow-to-entry. (bibtex-parse-preamble, bibtex-valid-entry) (bibtex-beginning-first-field): New functions. (bibtex-skip-to-valid-entry): Use bibtex-valid-entry. Fix regexp. (bibtex-map-entries): Fix docstring. (bibtex-flash-head): New arg prompt. Simplify. (bibtex-enclosing-field): Include code of bibtex-inside-field. (bibtex-insert-kill): Simplify. Always insert text past the current field or entry. (bibtex-format-entry): Use bibtex-parse-field. (bibtex-pop): Use bibtex-beginning-of-entry and bibtex-end-of-entry to initiate the search. Insert empty field if we found ourselves. (bibtex-print-help-message): New args field and comma. Handle entry keys. (bibtex-make-field): Use bibtex-beginning-of-entry. (bibtex-end-of-entry): Use bibtex-valid-entry. Recognize any invalid entry. (bibtex-validate): Use bibtex-valid-entry and bibtex-parse-string. Handle preambles. Simplify code for thorough test. (bibtex-next-field, bibtex-find-text, bibtex-find-text-internal): New arg comma. Handle entry heads. (bibtex-remove-OPT-or-ALT, bibtex-remove-delimiters) (bibtex-kill-field, bibtex-copy-field-as-kil, bibtex-empty-field): New arg comma. (bibtex-kill-entry): Use bibtex-any-entry-maybe-empty-head. (bibtex-fill-field): Simplify. (bibtex-fill-entry): Use bibtex-beginning-first-field and bibtex-parse-field. (bibtex-convert-alien): Do not wait before calling bibtex-validate. (bibtex-complete): Use bibtex-parse-preamble.
-rw-r--r--lisp/ChangeLog48
-rw-r--r--lisp/textmodes/bibtex.el1049
2 files changed, 544 insertions, 553 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 288e4d7ed44..9190aa3c988 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,51 @@
12005-12-29 Roland Winkler <Roland.Winkler@physik.uni-erlangen.de>
2
3 * textmodes/bibtex.el (bibtex-entry-type-whitespace)
4 (bibtex-entry-type-str, bibtex-empty-field-re)
5 (bibtex-search-backward-string, bibtex-preamble-prefix)
6 (bibtex-search-entry, bibtex-enclosing-entry-maybe-empty-head):
7 Removed.
8 (bibtex-any-valid-entry-type): New variable.
9 (bibtex-parse-field-name): Simplify.
10 (bibtex-parse-string, bibtex-search-forward-string): New arg
11 empty-key.
12 (bibtex-preamble-prefix): Include left delimiter.
13 (bibtex-search-forward-field, bibtex-search-backward-field): Allow
14 unbounded search past entry boundaries (required by bibtex-pop).
15 (bibtex-text-in-field-bounds): Use push.
16 (bibtex-text-in-field): Do not use bibtex-narrow-to-entry.
17 (bibtex-parse-preamble, bibtex-valid-entry)
18 (bibtex-beginning-first-field): New functions.
19 (bibtex-skip-to-valid-entry): Use bibtex-valid-entry. Fix regexp.
20 (bibtex-map-entries): Fix docstring.
21 (bibtex-flash-head): New arg prompt. Simplify.
22 (bibtex-enclosing-field): Include code of bibtex-inside-field.
23 (bibtex-insert-kill): Simplify. Always insert text past the
24 current field or entry.
25 (bibtex-format-entry): Use bibtex-parse-field.
26 (bibtex-pop): Use bibtex-beginning-of-entry and
27 bibtex-end-of-entry to initiate the search. Insert empty field if
28 we found ourselves.
29 (bibtex-print-help-message): New args field and comma. Handle
30 entry keys.
31 (bibtex-make-field): Use bibtex-beginning-of-entry.
32 (bibtex-end-of-entry): Use bibtex-valid-entry. Recognize any
33 invalid entry.
34 (bibtex-validate): Use bibtex-valid-entry and bibtex-parse-string.
35 Handle preambles. Simplify code for thorough test.
36 (bibtex-next-field, bibtex-find-text, bibtex-find-text-internal):
37 New arg comma. Handle entry heads.
38 (bibtex-remove-OPT-or-ALT, bibtex-remove-delimiters)
39 (bibtex-kill-field, bibtex-copy-field-as-kil, bibtex-empty-field):
40 New arg comma.
41 (bibtex-kill-entry): Use bibtex-any-entry-maybe-empty-head.
42 (bibtex-fill-field): Simplify.
43 (bibtex-fill-entry): Use bibtex-beginning-first-field and
44 bibtex-parse-field.
45 (bibtex-convert-alien): Do not wait before calling
46 bibtex-validate.
47 (bibtex-complete): Use bibtex-parse-preamble.
48
12005-12-29 Nick Roberts <nickrob@snap.net.nz> 492005-12-29 Nick Roberts <nickrob@snap.net.nz>
2 50
3 * progmodes/gdb-ui.el (gdb-tooltip-print, gdb-tooltip-print-1): 51 * progmodes/gdb-ui.el (gdb-tooltip-print, gdb-tooltip-print-1):
diff --git a/lisp/textmodes/bibtex.el b/lisp/textmodes/bibtex.el
index 161b5fbc126..a98fc2ddee1 100644
--- a/lisp/textmodes/bibtex.el
+++ b/lisp/textmodes/bibtex.el
@@ -853,7 +853,7 @@ The following is a complex example, see http://link.aps.org/linkfaq.html.
853 :group 'bibtex 853 :group 'bibtex
854 :type 'boolean) 854 :type 'boolean)
855 855
856;; `bibtex-font-lock-keywords' is a user option as well, but since the 856;; `bibtex-font-lock-keywords' is a user option, too. But since the
857;; patterns used to define this variable are defined in a later 857;; patterns used to define this variable are defined in a later
858;; section of this file, it is defined later. 858;; section of this file, it is defined later.
859 859
@@ -1091,7 +1091,7 @@ The CDRs of the elements are t for header keys and nil for crossref keys.")
1091 "Regexp matching the name of a BibTeX field.") 1091 "Regexp matching the name of a BibTeX field.")
1092 1092
1093(defconst bibtex-name-part 1093(defconst bibtex-name-part
1094 (concat ",[ \t\n]*\\(" bibtex-field-name "\\)[ \t\n]*=") 1094 (concat ",[ \t\n]*\\(" bibtex-field-name "\\)")
1095 "Regexp matching the name part of a BibTeX field.") 1095 "Regexp matching the name part of a BibTeX field.")
1096 1096
1097(defconst bibtex-reference-key "[][[:alnum:].:;?!`'/*@+|()<>&_^$-]+" 1097(defconst bibtex-reference-key "[][[:alnum:].:;?!`'/*@+|()<>&_^$-]+"
@@ -1105,16 +1105,6 @@ The CDRs of the elements are t for header keys and nil for crossref keys.")
1105 (regexp-opt (mapcar 'car bibtex-entry-field-alist)) "\\)") 1105 (regexp-opt (mapcar 'car bibtex-entry-field-alist)) "\\)")
1106 "Regexp matching the name of a BibTeX entry.") 1106 "Regexp matching the name of a BibTeX entry.")
1107 1107
1108(defvar bibtex-entry-type-whitespace
1109 (concat "[ \t]*" bibtex-entry-type)
1110 "Regexp matching the name of a BibTeX entry preceded by whitespace.")
1111
1112(defvar bibtex-entry-type-str
1113 (concat "@[ \t]*\\(?:"
1114 (regexp-opt (append '("String")
1115 (mapcar 'car bibtex-entry-field-alist))) "\\)")
1116 "Regexp matching the name of a BibTeX entry (including @String).")
1117
1118(defvar bibtex-entry-head 1108(defvar bibtex-entry-head
1119 (concat "^[ \t]*\\(" 1109 (concat "^[ \t]*\\("
1120 bibtex-entry-type 1110 bibtex-entry-type
@@ -1132,15 +1122,18 @@ The CDRs of the elements are t for header keys and nil for crossref keys.")
1132 bibtex-reference-key "\\)?") 1122 bibtex-reference-key "\\)?")
1133 "Regexp matching the header line of any BibTeX entry (possibly without key).") 1123 "Regexp matching the header line of any BibTeX entry (possibly without key).")
1134 1124
1125(defvar bibtex-any-valid-entry-type
1126 (concat "^[ \t]*@[ \t]*\\(?:"
1127 (regexp-opt (append '("String" "Preamble")
1128 (mapcar 'car bibtex-entry-field-alist))) "\\)")
1129 "Regexp matching any valid BibTeX entry (including String and Preamble).")
1130
1135(defconst bibtex-type-in-head 1 1131(defconst bibtex-type-in-head 1
1136 "Regexp subexpression number of the type part in `bibtex-entry-head'.") 1132 "Regexp subexpression number of the type part in `bibtex-entry-head'.")
1137 1133
1138(defconst bibtex-key-in-head 2 1134(defconst bibtex-key-in-head 2
1139 "Regexp subexpression number of the key part in `bibtex-entry-head'.") 1135 "Regexp subexpression number of the key part in `bibtex-entry-head'.")
1140 1136
1141(defconst bibtex-empty-field-re "\\`\\(\"\"\\|{}\\)\\'"
1142 "Regexp matching the text part (as a string) of an empty field.")
1143
1144(defconst bibtex-string-type "^[ \t]*\\(@[ \t]*String\\)[ \t]*[({][ \t\n]*" 1137(defconst bibtex-string-type "^[ \t]*\\(@[ \t]*String\\)[ \t]*[({][ \t\n]*"
1145 "Regexp matching the name of a BibTeX String entry.") 1138 "Regexp matching the name of a BibTeX String entry.")
1146 1139
@@ -1148,8 +1141,9 @@ The CDRs of the elements are t for header keys and nil for crossref keys.")
1148 (concat bibtex-string-type "\\(" bibtex-reference-key "\\)?") 1141 (concat bibtex-string-type "\\(" bibtex-reference-key "\\)?")
1149 "Regexp matching the header line of a BibTeX String entry.") 1142 "Regexp matching the header line of a BibTeX String entry.")
1150 1143
1151(defconst bibtex-preamble-prefix "[ \t]*@[ \t]*Preamble[ \t]*" 1144(defconst bibtex-preamble-prefix
1152 "Regexp matching the prefix part of a preamble.") 1145 "[ \t]*\\(@[ \t]*Preamble\\)[ \t]*[({][ \t\n]*"
1146 "Regexp matching the prefix part of a BibTeX Preamble entry.")
1153 1147
1154(defconst bibtex-font-lock-syntactic-keywords 1148(defconst bibtex-font-lock-syntactic-keywords
1155 `((,(concat "^[ \t]*\\(" (substring bibtex-comment-start 0 1) "\\)" 1149 `((,(concat "^[ \t]*\\(" (substring bibtex-comment-start 0 1) "\\)"
@@ -1229,12 +1223,9 @@ very first character of the match, the actual starting position of the name
1229part and end position of the match. Move point to end of field name. 1223part and end position of the match. Move point to end of field name.
1230If `bibtex-autoadd-commas' is non-nil add missing comma at end of preceding 1224If `bibtex-autoadd-commas' is non-nil add missing comma at end of preceding
1231BibTeX field as necessary." 1225BibTeX field as necessary."
1232 (cond ((looking-at ",[ \t\n]*") 1226 (cond ((looking-at bibtex-name-part)
1233 (let ((start (point))) 1227 (goto-char (match-end 0))
1234 (goto-char (match-end 0)) 1228 (list (match-beginning 0) (match-beginning 1) (match-end 0)))
1235 (when (looking-at bibtex-field-name)
1236 (goto-char (match-end 0))
1237 (list start (match-beginning 0) (match-end 0)))))
1238 ;; Maybe add a missing comma. 1229 ;; Maybe add a missing comma.
1239 ((and bibtex-autoadd-commas 1230 ((and bibtex-autoadd-commas
1240 (looking-at (concat "[ \t\n]*\\(?:" bibtex-field-name 1231 (looking-at (concat "[ \t\n]*\\(?:" bibtex-field-name
@@ -1334,60 +1325,71 @@ the boundaries of the name and text parts of the field. Do not move point."
1334 "Search forward to find a BibTeX field of name NAME. 1325 "Search forward to find a BibTeX field of name NAME.
1335If a syntactically correct field is found, return a pair containing 1326If a syntactically correct field is found, return a pair containing
1336the boundaries of the name and text parts of the field. The search 1327the boundaries of the name and text parts of the field. The search
1337is limited by optional arg BOUND or if nil by the end of the current 1328is limited by optional arg BOUND. If BOUND is t the search is limited
1338entry. Do not move point." 1329by the end of the current entry. Do not move point."
1339 (save-match-data 1330 (save-match-data
1340 (save-excursion 1331 (save-excursion
1341 (if bound 1332 (if (eq bound t)
1342 ;; If the search is bounded we need not worry we could overshoot. 1333 (let ((regexp (concat bibtex-name-part "[ \t\n]*=\\|"
1343 ;; This is indeed the case when `bibtex-search-forward-field' is 1334 bibtex-any-entry-maybe-empty-head))
1344 ;; called many times. So we optimize this part of this function. 1335 (case-fold-search t) bounds)
1345 (let ((name-part (concat ",[ \t\n]*\\(" name "\\)[ \t\n]*=[ \t\n]*")) 1336 (catch 'done
1346 (case-fold-search t) left right) 1337 (if (looking-at "[ \t]*@") (goto-char (match-end 0)))
1347 (while (and (not right) 1338 (while (and (not bounds)
1348 (re-search-forward name-part bound t)) 1339 (re-search-forward regexp nil t))
1349 (setq left (list (match-beginning 0) (match-beginning 1) 1340 (if (match-beginning 2)
1350 (match-end 1)) 1341 ;; We found a new entry
1351 ;; Don't worry that the field text could be past bound. 1342 (throw 'done nil)
1352 right (bibtex-parse-field-text))) 1343 ;; We found a field
1353 (if right (cons left right))) 1344 (goto-char (match-beginning 0))
1354 (let ((regexp (concat bibtex-name-part "\\|" 1345 (setq bounds (bibtex-parse-field))))
1355 bibtex-any-entry-maybe-empty-head)) 1346 ;; Step through all fields so that we cannot overshoot.
1356 (case-fold-search t) bounds) 1347 (while bounds
1357 (catch 'done 1348 (goto-char (bibtex-start-of-name-in-field bounds))
1358 (if (looking-at "[ \t]*@") (goto-char (match-end 0))) 1349 (if (looking-at name) (throw 'done bounds))
1359 (while (and (not bounds) 1350 (goto-char (bibtex-end-of-field bounds))
1360 (re-search-forward regexp nil t)) 1351 (setq bounds (bibtex-parse-field)))))
1361 (if (match-beginning 2) 1352 ;; Bounded search or bound is nil (i.e. we cannot overshoot).
1362 ;; We found a new entry 1353 ;; Indeed, the search is bounded when `bibtex-search-forward-field'
1363 (throw 'done nil) 1354 ;; is called many times. So we optimize this part of this function.
1364 ;; We found a field 1355 (let ((name-part (concat ",[ \t\n]*\\(" name "\\)[ \t\n]*=[ \t\n]*"))
1365 (goto-char (match-beginning 0)) 1356 (case-fold-search t) left right)
1366 (setq bounds (bibtex-parse-field)))) 1357 (while (and (not right)
1367 ;; Step through all fields so that we cannot overshoot. 1358 (re-search-forward name-part bound t))
1368 (while bounds 1359 (setq left (list (match-beginning 0) (match-beginning 1)
1369 (goto-char (bibtex-start-of-name-in-field bounds)) 1360 (match-end 1))
1370 (if (looking-at name) (throw 'done bounds)) 1361 ;; Don't worry that the field text could be past bound.
1371 (goto-char (bibtex-end-of-field bounds)) 1362 right (bibtex-parse-field-text)))
1372 (setq bounds (bibtex-parse-field))))))))) 1363 (if right (cons left right)))))))
1373 1364
1374(defun bibtex-search-backward-field (name &optional bound) 1365(defun bibtex-search-backward-field (name &optional bound)
1375 "Search backward to find a BibTeX field of name NAME. 1366 "Search backward to find a BibTeX field of name NAME.
1376If a syntactically correct field is found, return a pair containing 1367If a syntactically correct field is found, return a pair containing
1377the boundaries of the name and text parts of the field. The search 1368the boundaries of the name and text parts of the field. The search
1378is limited by the optional arg BOUND. If BOUND is nil the search is 1369is limited by the optional arg BOUND. If BOUND is t the search is
1379limited by the beginning of the current entry. Do not move point." 1370limited by the beginning of the current entry. Do not move point."
1380 (save-match-data 1371 (save-match-data
1381 (save-excursion 1372 (if (eq bound t)
1382 (let ((name-part (concat ",[ \t\n]*\\(?:" name "\\)[ \t\n]*=")) 1373 (setq bound (save-excursion (bibtex-beginning-of-entry))))
1383 (case-fold-search t) 1374 (let ((name-part (concat ",[ \t\n]*\\(" name "\\)[ \t\n]*=[ \t\n]*"))
1384 bounds) 1375 (case-fold-search t) left right)
1385 (unless bound (setq bound (save-excursion (bibtex-beginning-of-entry)))) 1376 (save-excursion
1386 (while (and (not bounds) 1377 ;; the parsing functions are not designed for parsing backwards :-(
1387 (search-backward "," bound t) 1378 (when (search-backward "," bound t)
1388 (looking-at name-part)) 1379 (or (save-excursion
1389 (setq bounds (bibtex-parse-field))) 1380 (when (looking-at name-part)
1390 bounds)))) 1381 (setq left (list (match-beginning 0) (match-beginning 1)
1382 (match-end 1)))
1383 (goto-char (match-end 0))
1384 (setq right (bibtex-parse-field-text))))
1385 (while (and (not right)
1386 (re-search-backward name-part bound t))
1387 (setq left (list (match-beginning 0) (match-beginning 1)
1388 (match-end 1)))
1389 (save-excursion
1390 (goto-char (match-end 0))
1391 (setq right (bibtex-parse-field-text)))))
1392 (if right (cons left right)))))))
1391 1393
1392(defun bibtex-name-in-field (bounds &optional remove-opt-alt) 1394(defun bibtex-name-in-field (bounds &optional remove-opt-alt)
1393 "Get content of name in BibTeX field defined via BOUNDS. 1395 "Get content of name in BibTeX field defined via BOUNDS.
@@ -1407,25 +1409,22 @@ by removing field delimiters and concatenating the resulting string.
1407If `bibtex-expand-strings' is non-nil, also expand BibTeX strings." 1409If `bibtex-expand-strings' is non-nil, also expand BibTeX strings."
1408 (if content 1410 (if content
1409 (save-excursion 1411 (save-excursion
1412 (goto-char (bibtex-start-of-text-in-field bounds))
1410 (let ((epoint (bibtex-end-of-text-in-field bounds)) 1413 (let ((epoint (bibtex-end-of-text-in-field bounds))
1411 content opoint temp) 1414 content opoint)
1412 (goto-char (bibtex-start-of-text-in-field bounds))
1413 (while (< (setq opoint (point)) epoint) 1415 (while (< (setq opoint (point)) epoint)
1414 (cond ((looking-at bibtex-field-const) 1416 (if (looking-at bibtex-field-const)
1415 (let ((mtch (match-string-no-properties 0))) 1417 (let ((mtch (match-string-no-properties 0)))
1416 (goto-char (match-end 0)) 1418 (push (if bibtex-expand-strings
1417 (setq temp (if bibtex-expand-strings 1419 (cdr (assoc-string mtch (bibtex-strings) t))
1418 (cdr (assoc-string mtch (bibtex-strings) t))) 1420 mtch) content)
1419 content (concat content (or temp mtch))))) 1421 (goto-char (match-end 0)))
1420 1422 (let ((bounds (bibtex-parse-field-string)))
1421 ((setq temp (bibtex-parse-field-string)) 1423 (push (buffer-substring-no-properties
1422 (setq content (concat content (buffer-substring-no-properties 1424 (1+ (car bounds)) (1- (cdr bounds))) content)
1423 (1+ (car temp)) 1425 (goto-char (cdr bounds))))
1424 (1- (cdr temp)))))
1425 (goto-char (cdr temp)))
1426 (t (error "Malformed text field")))
1427 (re-search-forward "\\=[ \t\n]*#[ \t\n]*" nil t)) 1426 (re-search-forward "\\=[ \t\n]*#[ \t\n]*" nil t))
1428 content)) 1427 (apply 'concat (nreverse content))))
1429 (buffer-substring-no-properties (bibtex-start-of-text-in-field bounds) 1428 (buffer-substring-no-properties (bibtex-start-of-text-in-field bounds)
1430 (bibtex-end-of-text-in-field bounds)))) 1429 (bibtex-end-of-text-in-field bounds))))
1431 1430
@@ -1434,19 +1433,15 @@ If `bibtex-expand-strings' is non-nil, also expand BibTeX strings."
1434Return nil if not found. 1433Return nil if not found.
1435If optional arg FOLLOW-CROSSREF is non-nil, follow crossref." 1434If optional arg FOLLOW-CROSSREF is non-nil, follow crossref."
1436 (save-excursion 1435 (save-excursion
1437 (save-restriction 1436 (let* ((end (if follow-crossref (bibtex-end-of-entry) t))
1438 ;; We want to jump back and forth while searching FIELD 1437 (beg (bibtex-beginning-of-entry)) ; move point
1439 (bibtex-narrow-to-entry) 1438 (bounds (bibtex-search-forward-field field end)))
1440 (goto-char (point-min)) 1439 (cond (bounds (bibtex-text-in-field-bounds bounds t))
1441 (let ((bounds (bibtex-search-forward-field field (point-max))) 1440 ((and follow-crossref
1442 crossref-field) 1441 (progn (goto-char beg)
1443 (cond (bounds (bibtex-text-in-field-bounds bounds t)) 1442 (setq bounds (bibtex-search-forward-field
1444 ((and follow-crossref 1443 "\\(OPT\\)?crossref" end))))
1445 (progn (goto-char (point-min)) 1444 (let ((crossref-field (bibtex-text-in-field-bounds bounds t)))
1446 (setq bounds (bibtex-search-forward-field
1447 "\\(OPT\\)?crossref" (point-max)))))
1448 (setq crossref-field (bibtex-text-in-field-bounds bounds t))
1449 (widen)
1450 (if (bibtex-find-crossref crossref-field) 1445 (if (bibtex-find-crossref crossref-field)
1451 ;; Do not pass FOLLOW-CROSSREF because we want 1446 ;; Do not pass FOLLOW-CROSSREF because we want
1452 ;; to follow crossrefs only one level of recursion. 1447 ;; to follow crossrefs only one level of recursion.
@@ -1487,42 +1482,28 @@ character of the string entry. Move point past BibTeX string entry."
1487 (nth 1 bounds) 1482 (nth 1 bounds)
1488 (match-end 0)))))) 1483 (match-end 0))))))
1489 1484
1490(defun bibtex-parse-string () 1485(defun bibtex-parse-string (&optional empty-key)
1491 "Parse a BibTeX string entry beginning at the position of point. 1486 "Parse a BibTeX string entry beginning at the position of point.
1492If a syntactically correct entry is found, return a cons pair containing 1487If a syntactically correct entry is found, return a cons pair containing
1493the boundaries of the reference key and text parts of the entry. 1488the boundaries of the reference key and text parts of the entry.
1494Do not move point." 1489If EMPTY-KEY is non-nil, key may be empty. Do not move point."
1495 (bibtex-parse-association 'bibtex-parse-string-prefix 1490 (let ((bibtex-string-empty-key empty-key))
1496 'bibtex-parse-string-postfix)) 1491 (bibtex-parse-association 'bibtex-parse-string-prefix
1492 'bibtex-parse-string-postfix)))
1497 1493
1498(defun bibtex-search-forward-string () 1494(defun bibtex-search-forward-string (&optional empty-key)
1499 "Search forward to find a BibTeX string entry. 1495 "Search forward to find a BibTeX string entry.
1500If a syntactically correct entry is found, a pair containing the boundaries of 1496If a syntactically correct entry is found, a pair containing the boundaries of
1501the reference key and text parts of the string is returned. Do not move point." 1497the reference key and text parts of the string is returned.
1498If EMPTY-KEY is non-nil, key may be empty. Do not move point."
1502 (save-excursion 1499 (save-excursion
1503 (save-match-data 1500 (save-match-data
1504 (let ((case-fold-search t) 1501 (let ((case-fold-search t) bounds)
1505 boundaries) 1502 (while (and (not bounds)
1506 (while (and (not boundaries)
1507 (search-forward-regexp bibtex-string-type nil t)) 1503 (search-forward-regexp bibtex-string-type nil t))
1508 (goto-char (match-beginning 0)) 1504 (save-excursion (goto-char (match-beginning 0))
1509 (unless (setq boundaries (bibtex-parse-string)) 1505 (setq bounds (bibtex-parse-string empty-key))))
1510 (forward-char 1))) 1506 bounds))))
1511 boundaries))))
1512
1513(defun bibtex-search-backward-string ()
1514 "Search backward to find a BibTeX string entry.
1515If a syntactically correct entry is found, a pair containing the boundaries of
1516the reference key and text parts of the field is returned. Do not move point."
1517 (save-excursion
1518 (save-match-data
1519 (let ((case-fold-search t)
1520 boundaries)
1521 (while (and (not boundaries)
1522 (search-backward-regexp bibtex-string-type nil t))
1523 (goto-char (match-beginning 0))
1524 (setq boundaries (bibtex-parse-string)))
1525 boundaries))))
1526 1507
1527(defun bibtex-reference-key-in-string (bounds) 1508(defun bibtex-reference-key-in-string (bounds)
1528 "Return the key part of a BibTeX string defined via BOUNDS" 1509 "Return the key part of a BibTeX string defined via BOUNDS"
@@ -1554,14 +1535,15 @@ If `bibtex-expand-strings' is non-nil, also expand BibTeX strings."
1554 (or (match-string-no-properties bibtex-key-in-head) 1535 (or (match-string-no-properties bibtex-key-in-head)
1555 empty)) 1536 empty))
1556 1537
1557(defun bibtex-preamble-prefix (&optional delim) 1538(defun bibtex-parse-preamble ()
1558 "Parse the prefix part of a BibTeX Preamble. 1539 "Parse BibTeX preamble.
1559Point must be at beginning of prefix part. If prefix is found move point 1540Point must be at beginning of preamble. Do not move point."
1560to its end and return position of point. If optional arg DELIM is non-nil,
1561move past the opening delimiter. If no preamble is found return nil."
1562 (let ((case-fold-search t)) 1541 (let ((case-fold-search t))
1563 (re-search-forward (concat "\\=" bibtex-preamble-prefix 1542 (when (looking-at bibtex-preamble-prefix)
1564 (if delim "[({][ \t\n]*")) nil t))) 1543 (let ((start (match-beginning 0)) (pref-start (match-beginning 1))
1544 (bounds (save-excursion (goto-char (match-end 0))
1545 (bibtex-parse-string-postfix))))
1546 (if bounds (cons (list start pref-start) bounds))))))
1565 1547
1566;; Helper Functions 1548;; Helper Functions
1567 1549
@@ -1579,6 +1561,35 @@ move past the opening delimiter. If no preamble is found return nil."
1579 (+ (count-lines 1 (point)) 1561 (+ (count-lines 1 (point))
1580 (if (bolp) 1 0))) 1562 (if (bolp) 1 0)))
1581 1563
1564(defun bibtex-valid-entry (&optional empty-key)
1565 "Parse a valid BibTeX entry (maybe without key if EMPTY-KEY is t).
1566A valid entry is a syntactical correct one with type contained in
1567`bibtex-entry-field-alist'. Ignore @String and @Preamble entries.
1568Return a cons pair with buffer positions of beginning and end of entry
1569if a valid entry is found, nil otherwise. Do not move point.
1570After a call to this function `match-data' corresponds to the header
1571of the entry, see regexp `bibtex-entry-head'."
1572 (let ((case-fold-search t) end)
1573 (if (looking-at (if empty-key bibtex-entry-maybe-empty-head
1574 bibtex-entry-head))
1575 (save-excursion
1576 (save-match-data
1577 (goto-char (match-end 0))
1578 (let ((entry-closer
1579 (if (save-excursion
1580 (goto-char (match-end bibtex-type-in-head))
1581 (looking-at "[ \t]*("))
1582 ",?[ \t\n]*)" ;; entry opened with `('
1583 ",?[ \t\n]*}")) ;; entry opened with `{'
1584 bounds)
1585 (skip-chars-forward " \t\n")
1586 ;; loop over all BibTeX fields
1587 (while (setq bounds (bibtex-parse-field))
1588 (goto-char (bibtex-end-of-field bounds)))
1589 ;; This matches the infix* part.
1590 (if (looking-at entry-closer) (setq end (match-end 0)))))
1591 (if end (cons (match-beginning 0) end))))))
1592
1582(defun bibtex-skip-to-valid-entry (&optional backward) 1593(defun bibtex-skip-to-valid-entry (&optional backward)
1583 "Move point to beginning of the next valid BibTeX entry. 1594 "Move point to beginning of the next valid BibTeX entry.
1584Do not move if we are already at beginning of a valid BibTeX entry. 1595Do not move if we are already at beginning of a valid BibTeX entry.
@@ -1590,32 +1601,27 @@ entry. Return buffer position of beginning and end of entry if a valid
1590entry is found, nil otherwise." 1601entry is found, nil otherwise."
1591 (interactive "P") 1602 (interactive "P")
1592 (let ((case-fold-search t) 1603 (let ((case-fold-search t)
1593 found) 1604 found bounds)
1594 (beginning-of-line) 1605 (beginning-of-line)
1595 ;; Loop till we look at a valid entry. 1606 ;; Loop till we look at a valid entry.
1596 (while (not (or found (if backward (bobp) (eobp)))) 1607 (while (not (or found (if backward (bobp) (eobp))))
1597 (let ((pnt (point)) 1608 (cond ((setq found (or (bibtex-valid-entry)
1598 bounds) 1609 (and (not bibtex-sort-ignore-string-entries)
1599 (cond ((or (and (looking-at bibtex-entry-type-whitespace) 1610 (setq bounds (bibtex-parse-string))
1600 (setq found (bibtex-search-entry nil nil t)) 1611 (cons (bibtex-start-of-field bounds)
1601 (equal (match-beginning 0) pnt)) 1612 (bibtex-end-of-string bounds))))))
1602 (and (not bibtex-sort-ignore-string-entries) 1613 (backward (re-search-backward "^[ \t]*@" nil 'move))
1603 (setq bounds (bibtex-parse-string)) 1614 (t (if (re-search-forward "\n\\([ \t]*@\\)" nil 'move)
1604 (setq found (cons (bibtex-start-of-field bounds) 1615 (goto-char (match-beginning 1))))))
1605 (bibtex-end-of-string bounds)))))
1606 (goto-char pnt))
1607 (backward (re-search-backward "^[ \t]*@" nil 'move))
1608 (t (re-search-forward "\\=[ \t]*@" nil t) ;; don't be stuck
1609 (if (re-search-forward "^[ \t]*@" nil 'move)
1610 (goto-char (match-beginning 0)))))))
1611 found)) 1616 found))
1612 1617
1613(defun bibtex-map-entries (fun) 1618(defun bibtex-map-entries (fun)
1614 "Call FUN for each BibTeX entry in buffer (possibly narrowed). 1619 "Call FUN for each BibTeX entry in buffer (possibly narrowed).
1615FUN is called with three arguments, the key of the entry and the buffer 1620FUN is called with three arguments, the key of the entry and the buffer
1616positions (marker) of beginning and end of entry. Point is inside the entry. 1621positions of beginning and end of entry. Also, point is at beginning of
1617If `bibtex-sort-ignore-string-entries' is non-nil, FUN is not called for 1622entry and `match-data' corresponds to the header of the entry,
1618@String entries." 1623see regexp `bibtex-entry-head'. If `bibtex-sort-ignore-string-entries'
1624is non-nil, FUN is not called for @String entries."
1619 (let ((case-fold-search t) 1625 (let ((case-fold-search t)
1620 found) 1626 found)
1621 (save-excursion 1627 (save-excursion
@@ -1673,75 +1679,19 @@ If FLAG is nil, a message is echoed if point was incremented at least
1673 "}" 1679 "}"
1674 ")")) 1680 ")"))
1675 1681
1676(defun bibtex-search-entry (empty-head &optional bound noerror backward) 1682(defun bibtex-flash-head (prompt)
1677 "Search for a BibTeX entry (maybe without reference key if EMPTY-HEAD is t).
1678BOUND and NOERROR are exactly as in `re-search-forward'. If BACKWARD
1679is non-nil, search in reverse direction. Move point past the closing
1680delimiter (at the beginning of entry if BACKWARD is non-nil).
1681Return a cons pair with buffer positions of beginning and end of entry.
1682After a call to this function `match-data' corresponds to the head part
1683of the entry, see regexp `bibtex-entry-head'.
1684Ignore @String and @Preamble entries."
1685 (let ((pnt (point))
1686 (entry-head-re (if empty-head
1687 bibtex-entry-maybe-empty-head
1688 bibtex-entry-head)))
1689 (if backward
1690 (let (found)
1691 (while (and (not found)
1692 (re-search-backward entry-head-re bound noerror))
1693 (setq found (bibtex-search-entry empty-head pnt t)))
1694 (cond (found
1695 (goto-char (match-beginning 0))
1696 found)
1697 ((not noerror) ;; yell
1698 (error "Backward search of BibTeX entry failed"))
1699 (t (if (eq noerror t) (goto-char pnt)) ;; don't move
1700 nil)))
1701 (let (found)
1702 (unless bound (setq bound (point-max)))
1703 (while (and (not found)
1704 (re-search-forward entry-head-re bound noerror))
1705 (save-match-data
1706 (let ((entry-closer
1707 (if (save-excursion
1708 (goto-char (match-end bibtex-type-in-head))
1709 (looking-at "[ \t]*("))
1710 ",?[ \t\n]*)" ;; entry opened with `('
1711 ",?[ \t\n]*}")) ;; entry opened with `{'
1712 bounds)
1713 (skip-chars-forward " \t\n" bound)
1714 ;; loop over all BibTeX fields
1715 (while (and (setq bounds (bibtex-parse-field))
1716 (<= (bibtex-end-of-field bounds) bound))
1717 (goto-char (bibtex-end-of-field bounds)))
1718 ;; This matches the infix* part.
1719 (when (and (looking-at entry-closer)
1720 (<= (match-end 0) bound))
1721 (goto-char (match-end 0))
1722 (setq found t)))))
1723 (cond (found
1724 (cons (match-beginning 0) (point)))
1725 ((not noerror) ;; yell
1726 (error "Search of BibTeX entry failed"))
1727 (t (if (eq noerror t) (goto-char pnt)) ;; don't move
1728 nil))))))
1729
1730(defun bibtex-flash-head ()
1731 "Flash at BibTeX entry head before point, if exists." 1683 "Flash at BibTeX entry head before point, if exists."
1732 (let ((case-fold-search t) 1684 (let ((case-fold-search t)
1733 (pnt (point)) 1685 (pnt (point)))
1734 flash)
1735 (save-excursion 1686 (save-excursion
1736 (bibtex-beginning-of-entry) 1687 (bibtex-beginning-of-entry)
1737 (when (and (looking-at bibtex-any-entry-maybe-empty-head) 1688 (when (and (looking-at bibtex-any-entry-maybe-empty-head)
1738 (< (point) pnt)) 1689 (< (point) pnt))
1739 (goto-char (match-beginning bibtex-type-in-head)) 1690 (goto-char (match-beginning bibtex-type-in-head))
1740 (setq flash (match-end bibtex-key-in-head))
1741 (if (pos-visible-in-window-p (point)) 1691 (if (pos-visible-in-window-p (point))
1742 (sit-for 1) 1692 (sit-for 1)
1743 (message "From: %s" 1693 (message "%s%s" prompt (buffer-substring-no-properties
1744 (buffer-substring (point) flash))))))) 1694 (point) (match-end bibtex-key-in-head))))))))
1745 1695
1746(defun bibtex-make-optional-field (field) 1696(defun bibtex-make-optional-field (field)
1747 "Make an optional field named FIELD in current BibTeX entry." 1697 "Make an optional field named FIELD in current BibTeX entry."
@@ -1772,66 +1722,55 @@ are ignored. Return point"
1772 (bibtex-skip-to-valid-entry) 1722 (bibtex-skip-to-valid-entry)
1773 (point)) 1723 (point))
1774 1724
1775(defun bibtex-inside-field () 1725(defun bibtex-enclosing-field (&optional comma noerr)
1776 "Try to avoid point being at end of a BibTeX field."
1777 (end-of-line)
1778 (skip-chars-backward " \t")
1779 (if (= (preceding-char) ?,)
1780 (forward-char -2))
1781 (if (or (= (preceding-char) ?})
1782 (= (preceding-char) ?\"))
1783 (forward-char -1)))
1784
1785(defun bibtex-enclosing-field (&optional noerr)
1786 "Search for BibTeX field enclosing point. 1726 "Search for BibTeX field enclosing point.
1727For `bibtex-mode''s internal algorithms, a field begins at the comma
1728following the preceding field. Usually, this is not what the user expects.
1729Thus if COMMA is non-nil, the \"current field\" includes the terminating comma.
1787Unless NOERR is non-nil, signal an error if no enclosing field is found. 1730Unless NOERR is non-nil, signal an error if no enclosing field is found.
1788On success return bounds, nil otherwise. Do not move point." 1731On success return bounds, nil otherwise. Do not move point."
1789 (let ((bounds (bibtex-search-backward-field bibtex-field-name))) 1732 (save-excursion
1790 (if (and bounds 1733 (when comma
1791 (<= (bibtex-start-of-field bounds) (point)) 1734 (end-of-line)
1792 (>= (bibtex-end-of-field bounds) (point))) 1735 (skip-chars-backward " \t")
1793 bounds 1736 (if (= (preceding-char) ?,) (forward-char -1)))
1794 (unless noerr 1737
1795 (error "Can't find enclosing BibTeX field"))))) 1738 (let ((bounds (bibtex-search-backward-field bibtex-field-name t)))
1796 1739 (cond ((and bounds
1797(defun bibtex-enclosing-entry-maybe-empty-head () 1740 (<= (bibtex-start-of-field bounds) (point))
1798 "Search for BibTeX entry enclosing point. Move point to end of entry. 1741 (>= (bibtex-end-of-field bounds) (point)))
1799Beginning (but not end) of entry is given by (`match-beginning' 0)." 1742 bounds)
1800 (let ((case-fold-search t) 1743 ((not noerr)
1801 (old-point (point))) 1744 (error "Can't find enclosing BibTeX field"))))))
1802 (unless (re-search-backward bibtex-entry-maybe-empty-head nil t) 1745
1803 (goto-char old-point) 1746(defun bibtex-beginning-first-field (&optional beg)
1804 (error "Can't find beginning of enclosing BibTeX entry")) 1747 "Move point to beginning of first field.
1805 (goto-char (match-beginning bibtex-type-in-head)) 1748Optional arg BEG is beginning of entry."
1806 (unless (bibtex-search-entry t nil t) 1749 (if beg (goto-char beg) (bibtex-beginning-of-entry))
1807 (goto-char old-point) 1750 (looking-at bibtex-any-entry-maybe-empty-head)
1808 (error "Can't find end of enclosing BibTeX entry")))) 1751 (goto-char (match-end 0)))
1809 1752
1810(defun bibtex-insert-kill (n) 1753(defun bibtex-insert-kill (n &optional comma)
1811 "Reinsert the Nth stretch of killed BibTeX text." 1754 "Reinsert the Nth stretch of killed BibTeX text (field or entry).
1812 (if (not bibtex-last-kill-command) 1755Optional arg COMMA is as in `bibtex-enclosing-field'."
1813 (error "BibTeX kill ring is empty") 1756 (unless bibtex-last-kill-command (error "BibTeX kill ring is empty"))
1814 (let* ((kr (if (eq bibtex-last-kill-command 'field) 1757 (let ((fun (lambda (kryp kr) ;; adapted from `current-kill'
1815 'bibtex-field-kill-ring 1758 (car (set kryp (nthcdr (mod (- n (length (eval kryp)))
1816 'bibtex-entry-kill-ring)) 1759 (length kr)) kr))))))
1817 (kryp (if (eq bibtex-last-kill-command 'field) 1760 (if (eq bibtex-last-kill-command 'field)
1818 'bibtex-field-kill-ring-yank-pointer 1761 (progn
1819 'bibtex-entry-kill-ring-yank-pointer)) 1762 ;; insert past the current field
1820 (current (car (set kryp (nthcdr (mod (- n (length (eval kryp))) 1763 (goto-char (bibtex-end-of-field (bibtex-enclosing-field comma)))
1821 (length (eval kr))) 1764 (set-mark (point))
1822 (eval kr)))))) 1765 (message "Mark set")
1823 (if (eq bibtex-last-kill-command 'field) 1766 (bibtex-make-field (funcall fun 'bibtex-field-kill-ring-yank-pointer
1824 (progn 1767 bibtex-field-kill-ring) t))
1825 (bibtex-find-text) 1768 ;; insert past the current entry
1826 (if (looking-at "[}\"]") 1769 (bibtex-skip-to-valid-entry)
1827 (forward-char)) 1770 (set-mark (point))
1828 (set-mark (point)) 1771 (message "Mark set")
1829 (message "Mark set") 1772 (insert (funcall fun 'bibtex-entry-kill-ring-yank-pointer
1830 (bibtex-make-field current t)) 1773 bibtex-entry-kill-ring)))))
1831 (unless (eobp) (bibtex-beginning-of-entry))
1832 (set-mark (point))
1833 (message "Mark set")
1834 (insert current)))))
1835 1774
1836(defun bibtex-format-entry () 1775(defun bibtex-format-entry ()
1837 "Helper function for `bibtex-clean-entry'. 1776 "Helper function for `bibtex-clean-entry'.
@@ -1900,9 +1839,8 @@ Formats current entry according to variable `bibtex-entry-format'."
1900 (error "All alternatives are empty")) 1839 (error "All alternatives are empty"))
1901 1840
1902 ;; process all fields 1841 ;; process all fields
1903 (goto-char (point-min)) 1842 (bibtex-beginning-first-field (point-min))
1904 (while (setq bounds (bibtex-search-forward-field 1843 (while (setq bounds (bibtex-parse-field))
1905 bibtex-field-name (point-max)))
1906 (let* ((beg-field (copy-marker (bibtex-start-of-field bounds))) 1844 (let* ((beg-field (copy-marker (bibtex-start-of-field bounds)))
1907 (end-field (copy-marker (bibtex-end-of-field bounds) t)) 1845 (end-field (copy-marker (bibtex-end-of-field bounds) t))
1908 (beg-name (copy-marker (bibtex-start-of-name-in-field bounds))) 1846 (beg-name (copy-marker (bibtex-start-of-name-in-field bounds)))
@@ -2040,10 +1978,6 @@ Formats current entry according to variable `bibtex-entry-format'."
2040 (error "Alternative fields `%s' are defined %s times" 1978 (error "Alternative fields `%s' are defined %s times"
2041 altlist found)))))) 1979 altlist found))))))
2042 1980
2043 ;; update point
2044 (if (looking-at (bibtex-field-right-delimiter))
2045 (forward-char))
2046
2047 ;; update comma after last field 1981 ;; update comma after last field
2048 (if (memq 'last-comma format) 1982 (if (memq 'last-comma format)
2049 (cond ((and bibtex-comma-after-last-field 1983 (cond ((and bibtex-comma-after-last-field
@@ -2565,6 +2499,7 @@ of a word, all strings are listed. Return completion."
2565 "Cleanup after inserting string STR. 2499 "Cleanup after inserting string STR.
2566Remove enclosing field delimiters for STR. Display message with 2500Remove enclosing field delimiters for STR. Display message with
2567expansion of STR using expansion list COMPL." 2501expansion of STR using expansion list COMPL."
2502 ;; point is at position inside field where completion was requested
2568 (save-excursion 2503 (save-excursion
2569 (let ((abbr (cdr (if (stringp str) 2504 (let ((abbr (cdr (if (stringp str)
2570 (assoc-string str compl t))))) 2505 (assoc-string str compl t)))))
@@ -2624,50 +2559,52 @@ Used as default value of `bibtex-summary-function'."
2624(defun bibtex-pop (arg direction) 2559(defun bibtex-pop (arg direction)
2625 "Fill current field from the ARGth same field's text in DIRECTION. 2560 "Fill current field from the ARGth same field's text in DIRECTION.
2626Generic function used by `bibtex-pop-previous' and `bibtex-pop-next'." 2561Generic function used by `bibtex-pop-previous' and `bibtex-pop-next'."
2627 (bibtex-find-text) 2562 ;; parse current field
2628 (save-excursion 2563 (let* ((bounds (bibtex-enclosing-field t))
2629 ;; parse current field 2564 (start-old-field (bibtex-start-of-field bounds))
2630 (bibtex-inside-field) 2565 (start-old-text (bibtex-start-of-text-in-field bounds))
2631 (let* ((case-fold-search t) 2566 (end-old-text (bibtex-end-of-text-in-field bounds))
2632 (bounds (bibtex-enclosing-field)) 2567 (field-name (bibtex-name-in-field bounds t))
2633 (start-old-text (bibtex-start-of-text-in-field bounds)) 2568 failure)
2634 (stop-old-text (bibtex-end-of-text-in-field bounds)) 2569 (save-excursion
2635 (field-name (bibtex-name-in-field bounds t)))
2636 ;; if executed several times in a row, start each search where 2570 ;; if executed several times in a row, start each search where
2637 ;; the last one was finished 2571 ;; the last one was finished
2638 (unless (eq last-command 'bibtex-pop) 2572 (cond ((eq last-command 'bibtex-pop)
2639 (bibtex-enclosing-entry-maybe-empty-head) 2573 (goto-char (if (eq direction 'previous)
2640 (setq bibtex-pop-previous-search-point (match-beginning 0) 2574 bibtex-pop-previous-search-point
2641 bibtex-pop-next-search-point (point))) 2575 bibtex-pop-next-search-point)))
2642 (if (eq direction 'previous) 2576 ((eq direction 'previous)
2643 (goto-char bibtex-pop-previous-search-point) 2577 (bibtex-beginning-of-entry))
2644 (goto-char bibtex-pop-next-search-point)) 2578 (t (bibtex-end-of-entry)))
2645 ;; Now search for arg'th previous/next similar field 2579 ;; Search for arg'th previous/next similar field
2646 (let (bounds failure new-text) 2580 (while (and (not failure)
2647 (while (and (not failure) 2581 (>= (setq arg (1- arg)) 0))
2648 (> arg 0)) 2582 ;; The search of BibTeX fields is not bounded by entry boundaries
2649 (cond ((eq direction 'previous) 2583 (if (eq direction 'previous)
2650 (if (setq bounds (bibtex-search-backward-field field-name)) 2584 (if (setq bounds (bibtex-search-backward-field field-name))
2651 (goto-char (bibtex-start-of-field bounds)) 2585 (goto-char (bibtex-start-of-field bounds))
2652 (setq failure t))) 2586 (setq failure t))
2653 ((eq direction 'next) 2587 (if (setq bounds (bibtex-search-forward-field field-name))
2654 (if (setq bounds (bibtex-search-forward-field field-name)) 2588 (goto-char (bibtex-end-of-field bounds))
2655 (goto-char (bibtex-end-of-field bounds)) 2589 (setq failure t))))
2656 (setq failure t)))) 2590 (if failure
2657 (setq arg (- arg 1))) 2591 (error "No %s matching BibTeX field"
2658 (if failure 2592 (if (eq direction 'previous) "previous" "next"))
2659 (error "No %s matching BibTeX field" 2593 ;; Found a matching field. Remember boundaries.
2660 (if (eq direction 'previous) "previous" "next")) 2594 (let ((new-text (bibtex-text-in-field-bounds bounds))
2661 ;; Found a matching field. Remember boundaries. 2595 (nbeg (copy-marker (bibtex-start-of-field bounds)))
2662 (setq bibtex-pop-previous-search-point (bibtex-start-of-field bounds) 2596 (nend (copy-marker (bibtex-end-of-field bounds))))
2663 bibtex-pop-next-search-point (bibtex-end-of-field bounds) 2597 (bibtex-flash-head "From: ")
2664 new-text (bibtex-text-in-field-bounds bounds))
2665 (bibtex-flash-head)
2666 ;; Go back to where we started, delete old text, and pop new. 2598 ;; Go back to where we started, delete old text, and pop new.
2667 (goto-char stop-old-text) 2599 (goto-char end-old-text)
2668 (delete-region start-old-text stop-old-text) 2600 (delete-region start-old-text end-old-text)
2669 (insert new-text))))) 2601 (if (= nbeg start-old-field)
2670 (bibtex-find-text) 2602 (insert (bibtex-field-left-delimiter)
2603 (bibtex-field-right-delimiter))
2604 (insert new-text))
2605 (setq bibtex-pop-previous-search-point (marker-position nbeg)
2606 bibtex-pop-next-search-point (marker-position nend))))))
2607 (bibtex-find-text nil nil nil t)
2671 (setq this-command 'bibtex-pop)) 2608 (setq this-command 'bibtex-pop))
2672 2609
2673(defun bibtex-beginning-of-field () 2610(defun bibtex-beginning-of-field ()
@@ -2861,7 +2798,7 @@ and `bibtex-user-optional-fields'."
2861 (let ((e (assoc-string entry-type bibtex-entry-field-alist t)) 2798 (let ((e (assoc-string entry-type bibtex-entry-field-alist t))
2862 required optional) 2799 required optional)
2863 (unless e 2800 (unless e
2864 (error "BibTeX entry type %s not defined" entry-type)) 2801 (error "Fields for BibTeX entry type %s not defined" entry-type))
2865 (if (and (member-ignore-case entry-type bibtex-include-OPTcrossref) 2802 (if (and (member-ignore-case entry-type bibtex-include-OPTcrossref)
2866 (nth 2 e)) 2803 (nth 2 e))
2867 (setq required (nth 0 (nth 2 e)) 2804 (setq required (nth 0 (nth 2 e))
@@ -2918,10 +2855,11 @@ according to `bibtex-field-list', but are not yet present."
2918 (save-excursion 2855 (save-excursion
2919 (bibtex-beginning-of-entry) 2856 (bibtex-beginning-of-entry)
2920 ;; For inserting new fields, we use the fact that 2857 ;; For inserting new fields, we use the fact that
2921 ;; bibtex-parse-entry moves point to the end of the last field. 2858 ;; `bibtex-parse-entry' moves point to the end of the last field.
2922 (let* ((fields-alist (bibtex-parse-entry)) 2859 (let* ((fields-alist (bibtex-parse-entry))
2923 (field-list (bibtex-field-list 2860 (field-list (bibtex-field-list
2924 (cdr (assoc "=type=" fields-alist))))) 2861 (cdr (assoc "=type=" fields-alist)))))
2862 (skip-chars-backward " \t\n")
2925 (dolist (field (car field-list)) 2863 (dolist (field (car field-list))
2926 (unless (assoc-string (car field) fields-alist t) 2864 (unless (assoc-string (car field) fields-alist t)
2927 (bibtex-make-field field))) 2865 (bibtex-make-field field)))
@@ -2964,6 +2902,7 @@ entry (for example, the year parts of the keys)."
2964 (key (bibtex-key-in-head)) 2902 (key (bibtex-key-in-head))
2965 (key-end (match-end bibtex-key-in-head)) 2903 (key-end (match-end bibtex-key-in-head))
2966 (case-fold-search t) 2904 (case-fold-search t)
2905 (bibtex-sort-ignore-string-entries t)
2967 tmp other-key other bounds) 2906 tmp other-key other bounds)
2968 ;; The fields we want to change start right after the key. 2907 ;; The fields we want to change start right after the key.
2969 (goto-char key-end) 2908 (goto-char key-end)
@@ -3016,28 +2955,28 @@ entry (for example, the year parts of the keys)."
3016 (while (re-search-backward (regexp-quote other-suffix) key-end 'move) 2955 (while (re-search-backward (regexp-quote other-suffix) key-end 'move)
3017 (replace-match suffix))))))) 2956 (replace-match suffix)))))))
3018 2957
3019(defun bibtex-print-help-message () 2958(defun bibtex-print-help-message (&optional field comma)
3020 "Print helpful information about current field in current BibTeX entry." 2959 "Print helpful information about current FIELD in current BibTeX entry.
3021 (interactive) 2960Optional arg COMMA is as in `bibtex-enclosing-field'. It is t for
3022 (let* ((case-fold-search t) 2961interactive calls."
3023 (type (save-excursion 2962 (interactive (list nil t))
3024 (bibtex-beginning-of-entry) 2963 (unless field (setq field (car (bibtex-find-text-internal nil nil comma))))
3025 (looking-at bibtex-any-entry-maybe-empty-head) 2964 (if (string-match "@" field)
3026 (bibtex-type-in-head))) 2965 (cond ((bibtex-string= field "@string")
3027 comment field-list) 2966 (message "String definition"))
3028 (cond ((bibtex-string= type "string") 2967 ((bibtex-string= field "@preamble")
3029 (message "String definition")) 2968 (message "Preamble definition"))
3030 ((bibtex-string= type "preamble") 2969 (t (message "Entry key")))
3031 (message "Preamble definition")) 2970 (let* ((case-fold-search t)
3032 (t 2971 (type (save-excursion
3033 (setq field-list (bibtex-field-list type) 2972 (bibtex-beginning-of-entry)
3034 comment 2973 (looking-at bibtex-entry-maybe-empty-head)
3035 (assoc-string (bibtex-name-in-field (bibtex-enclosing-field) t) 2974 (bibtex-type-in-head)))
3036 (append (car field-list) (cdr field-list)) 2975 (field-list (bibtex-field-list type))
3037 t)) 2976 (comment (assoc-string field (append (car field-list)
3038 (if comment 2977 (cdr field-list)) t)))
3039 (message "%s" (nth 1 comment)) 2978 (if comment (message "%s" (nth 1 comment))
3040 (message "No comment available")))))) 2979 (message "No comment available")))))
3041 2980
3042(defun bibtex-make-field (field &optional move interactive) 2981(defun bibtex-make-field (field &optional move interactive)
3043 "Make a field named FIELD in current BibTeX entry. 2982 "Make a field named FIELD in current BibTeX entry.
@@ -3052,7 +2991,8 @@ MOVE and INTERACTIVE are t when called interactively."
3052 (list (let ((completion-ignore-case t) 2991 (list (let ((completion-ignore-case t)
3053 (field-list (bibtex-field-list 2992 (field-list (bibtex-field-list
3054 (save-excursion 2993 (save-excursion
3055 (bibtex-enclosing-entry-maybe-empty-head) 2994 (bibtex-beginning-of-entry)
2995 (looking-at bibtex-any-entry-maybe-empty-head)
3056 (bibtex-type-in-head))))) 2996 (bibtex-type-in-head)))))
3057 (completing-read "BibTeX field name: " 2997 (completing-read "BibTeX field name: "
3058 (append (car field-list) (cdr field-list)) 2998 (append (car field-list) (cdr field-list))
@@ -3081,8 +3021,9 @@ MOVE and INTERACTIVE are t when called interactively."
3081 (t (concat (bibtex-field-left-delimiter) 3021 (t (concat (bibtex-field-left-delimiter)
3082 (bibtex-field-right-delimiter)))))) 3022 (bibtex-field-right-delimiter))))))
3083 (when interactive 3023 (when interactive
3084 (forward-char -1) 3024 ;; (bibtex-find-text nil nil bibtex-help-message)
3085 (bibtex-print-help-message))) 3025 (if (memq (preceding-char) '(?} ?\")) (forward-char -1))
3026 (if bibtex-help-message (bibtex-print-help-message (car field)))))
3086 3027
3087(defun bibtex-beginning-of-entry () 3028(defun bibtex-beginning-of-entry ()
3088 "Move to beginning of BibTeX entry (beginning of line). 3029 "Move to beginning of BibTeX entry (beginning of line).
@@ -3103,28 +3044,19 @@ of the previous entry. Do not move if ahead of first entry.
3103Return the new location of point." 3044Return the new location of point."
3104 (interactive) 3045 (interactive)
3105 (let ((case-fold-search t) 3046 (let ((case-fold-search t)
3106 (org (point)) 3047 (pnt (point))
3107 (pnt (bibtex-beginning-of-entry)) 3048 (_ (bibtex-beginning-of-entry))
3108 err bounds) 3049 (bounds (bibtex-valid-entry t)))
3109 (cond ((looking-at bibtex-entry-type-whitespace) 3050 (cond (bounds (goto-char (cdr bounds))) ; regular entry
3110 (bibtex-search-entry t nil t) 3051 ;; @String or @Preamble
3111 (unless (equal (match-beginning 0) pnt) 3052 ((setq bounds (or (bibtex-parse-string t) (bibtex-parse-preamble)))
3112 (setq err t)))
3113 ;; @String
3114 ((setq bounds (bibtex-parse-string))
3115 (goto-char (bibtex-end-of-string bounds))) 3053 (goto-char (bibtex-end-of-string bounds)))
3116 ;; @Preamble 3054 ((looking-at bibtex-any-valid-entry-type)
3117 ((bibtex-preamble-prefix t) 3055 ;; Parsing of entry failed
3118 (unless (bibtex-parse-string-postfix) ;; @String postfix OK 3056 (error "Syntactically incorrect BibTeX entry starts here."))
3119 (setq err t))) 3057 (t (if (interactive-p) (message "Not on a known BibTeX entry."))
3120 (t 3058 (goto-char pnt)))
3121 (if (interactive-p) 3059 (point)))
3122 (message "Not on a known BibTeX entry."))
3123 (goto-char org)))
3124 (when err
3125 (goto-char pnt)
3126 (error "Syntactically incorrect BibTeX entry starts here")))
3127 (point))
3128 3060
3129(defun bibtex-goto-line (arg) 3061(defun bibtex-goto-line (arg)
3130 "Goto line ARG, counting from beginning of (narrowed) buffer." 3062 "Goto line ARG, counting from beginning of (narrowed) buffer."
@@ -3188,7 +3120,7 @@ If mark is active count entries in region, if not in whole buffer."
3188 (interactive) 3120 (interactive)
3189 (let ((bounds (save-excursion 3121 (let ((bounds (save-excursion
3190 (bibtex-beginning-of-entry) 3122 (bibtex-beginning-of-entry)
3191 (bibtex-search-forward-field "abstract")))) 3123 (bibtex-search-forward-field "abstract" t))))
3192 (if bounds 3124 (if bounds
3193 (ispell-region (bibtex-start-of-text-in-field bounds) 3125 (ispell-region (bibtex-start-of-text-in-field bounds)
3194 (bibtex-end-of-text-in-field bounds)) 3126 (bibtex-end-of-text-in-field bounds))
@@ -3216,7 +3148,7 @@ of the head of the entry found. Return nil if no entry found."
3216 ;; Don't search CROSSREF-KEY if we don't need it. 3148 ;; Don't search CROSSREF-KEY if we don't need it.
3217 (if (eq bibtex-maintain-sorted-entries 'crossref) 3149 (if (eq bibtex-maintain-sorted-entries 'crossref)
3218 (let ((bounds (bibtex-search-forward-field 3150 (let ((bounds (bibtex-search-forward-field
3219 "\\(OPT\\)?crossref"))) 3151 "\\(OPT\\)?crossref" t)))
3220 (list key 3152 (list key
3221 (if bounds (bibtex-text-in-field-bounds bounds t)) 3153 (if bounds (bibtex-text-in-field-bounds bounds t))
3222 entry-name)) 3154 entry-name))
@@ -3283,7 +3215,7 @@ entry and SPLIT is t."
3283 (let ((crossref-key 3215 (let ((crossref-key
3284 (save-excursion 3216 (save-excursion
3285 (bibtex-beginning-of-entry) 3217 (bibtex-beginning-of-entry)
3286 (let ((bounds (bibtex-search-forward-field "crossref"))) 3218 (let ((bounds (bibtex-search-forward-field "crossref" t)))
3287 (if bounds 3219 (if bounds
3288 (bibtex-text-in-field-bounds bounds t)))))) 3220 (bibtex-text-in-field-bounds bounds t))))))
3289 (list (bibtex-read-key "Find crossref key: " crossref-key t) 3221 (list (bibtex-read-key "Find crossref key: " crossref-key t)
@@ -3429,40 +3361,38 @@ Return t if test was successful, nil otherwise."
3429 error-list syntax-error) 3361 error-list syntax-error)
3430 (save-excursion 3362 (save-excursion
3431 (save-restriction 3363 (save-restriction
3432 (if mark-active 3364 (if mark-active (narrow-to-region (region-beginning) (region-end)))
3433 (narrow-to-region (region-beginning) (region-end)))
3434 3365
3435 ;; looking if entries fit syntactical structure 3366 ;; Check syntactical structure of entries
3436 (goto-char (point-min)) 3367 (goto-char (point-min))
3437 (bibtex-progress-message "Checking syntactical structure") 3368 (bibtex-progress-message "Checking syntactical structure")
3438 (let (bibtex-sort-ignore-string-entries) 3369 (let (bounds end)
3439 (while (re-search-forward "^[ \t]*@" nil t) 3370 (while (setq end (re-search-forward "^[ \t]*@" nil t))
3440 (bibtex-progress-message) 3371 (bibtex-progress-message)
3441 (forward-char -1) 3372 (goto-char (match-beginning 0))
3442 (let ((pnt (point))) 3373 (cond ((setq bounds (bibtex-valid-entry))
3443 (if (not (looking-at bibtex-entry-type-str)) 3374 (goto-char (cdr bounds)))
3444 (forward-char) 3375 ((setq bounds (or (bibtex-parse-string)
3445 (bibtex-skip-to-valid-entry) 3376 (bibtex-parse-preamble)))
3446 (if (equal (point) pnt) 3377 (goto-char (bibtex-end-of-string bounds)))
3447 (forward-char) 3378 ((looking-at bibtex-any-valid-entry-type)
3448 (goto-char pnt) 3379 (push (cons (bibtex-current-line)
3449 (push (cons (bibtex-current-line) 3380 "Syntax error (check esp. commas, braces, and quotes)")
3450 "Syntax error (check esp. commas, braces, and quotes)") 3381 error-list)
3451 error-list) 3382 (goto-char (match-end 0)))
3452 (forward-char)))))) 3383 (t (goto-char end)))))
3453 (bibtex-progress-message 'done) 3384 (bibtex-progress-message 'done)
3454 3385
3455 (if error-list 3386 (if error-list
3456 ;; proceed only if there were no syntax errors. 3387 ;; Continue only if there were no syntax errors.
3457 (setq syntax-error t) 3388 (setq syntax-error t)
3458 3389
3459 ;; looking for duplicate keys and correct sort order 3390 ;; Check for duplicate keys and correct sort order
3460 (let (previous current key-list) 3391 (let (previous current key-list)
3461 (bibtex-progress-message "Checking for duplicate keys") 3392 (bibtex-progress-message "Checking for duplicate keys")
3462 (bibtex-map-entries 3393 (bibtex-map-entries
3463 (lambda (key beg end) 3394 (lambda (key beg end)
3464 (bibtex-progress-message) 3395 (bibtex-progress-message)
3465 (goto-char beg)
3466 (setq current (bibtex-entry-index)) 3396 (setq current (bibtex-entry-index))
3467 (cond ((not previous)) 3397 (cond ((not previous))
3468 ((member key key-list) 3398 ((member key key-list)
@@ -3498,18 +3428,13 @@ Return t if test was successful, nil otherwise."
3498 (bibtex-map-entries 3428 (bibtex-map-entries
3499 (lambda (key beg end) 3429 (lambda (key beg end)
3500 (bibtex-progress-message) 3430 (bibtex-progress-message)
3501 (let* ((entry-list (progn 3431 (let* ((entry-list (assoc-string (bibtex-type-in-head)
3502 (goto-char beg) 3432 bibtex-entry-field-alist t))
3503 (bibtex-search-entry nil end)
3504 (assoc-string (bibtex-type-in-head)
3505 bibtex-entry-field-alist t)))
3506 (req (copy-sequence (elt (elt entry-list 1) 0))) 3433 (req (copy-sequence (elt (elt entry-list 1) 0)))
3507 (creq (copy-sequence (elt (elt entry-list 2) 0))) 3434 (creq (copy-sequence (elt (elt entry-list 2) 0)))
3508 crossref-there bounds alt-there field) 3435 crossref-there bounds alt-there field)
3509 (goto-char beg) 3436 (bibtex-beginning-first-field beg)
3510 (while (setq bounds (bibtex-search-forward-field 3437 (while (setq bounds (bibtex-parse-field))
3511 bibtex-field-name end))
3512 (goto-char (bibtex-start-of-text-in-field bounds))
3513 (let ((field-name (bibtex-name-in-field bounds))) 3438 (let ((field-name (bibtex-name-in-field bounds)))
3514 (if (and (bibtex-string= field-name "month") 3439 (if (and (bibtex-string= field-name "month")
3515 ;; Check only abbreviated month fields. 3440 ;; Check only abbreviated month fields.
@@ -3521,18 +3446,19 @@ Return t if test was successful, nil otherwise."
3521 (push (cons (bibtex-current-line) 3446 (push (cons (bibtex-current-line)
3522 "Questionable month field") 3447 "Questionable month field")
3523 error-list)) 3448 error-list))
3524 (setq field (assoc-string field-name req t)) 3449 (setq field (assoc-string field-name req t)
3450 req (delete field req)
3451 creq (delete (assoc-string field-name creq t) creq))
3525 (if (nth 3 field) 3452 (if (nth 3 field)
3526 (if alt-there (push (cons (bibtex-current-line) 3453 (if alt-there
3527 "More than one non-empty alternative") 3454 (push (cons (bibtex-current-line)
3528 error-list) 3455 "More than one non-empty alternative")
3456 error-list)
3529 (setq alt-there t))) 3457 (setq alt-there t)))
3530 (setq req (delete field req)
3531 creq (delete (assoc-string field-name creq t) creq))
3532 (if (bibtex-string= field-name "crossref") 3458 (if (bibtex-string= field-name "crossref")
3533 (setq crossref-there t)))) 3459 (setq crossref-there t)))
3534 (if crossref-there 3460 (goto-char (bibtex-end-of-field bounds)))
3535 (setq req creq)) 3461 (if crossref-there (setq req creq))
3536 (let (alt) 3462 (let (alt)
3537 (dolist (field req) 3463 (dolist (field req)
3538 (if (nth 3 field) 3464 (if (nth 3 field)
@@ -3573,11 +3499,10 @@ Return t if test was successful, nil otherwise."
3573 (toggle-read-only 1) 3499 (toggle-read-only 1)
3574 (goto-line 3)) ; first error message 3500 (goto-line 3)) ; first error message
3575 (display-buffer err-buf) 3501 (display-buffer err-buf)
3576 ;; return nil 3502 nil) ; return `nil' (i.e., buffer is invalid)
3577 nil)
3578 (message "%s is syntactically correct" 3503 (message "%s is syntactically correct"
3579 (if mark-active "Region" "Buffer")) 3504 (if mark-active "Region" "Buffer"))
3580 t))) 3505 t))) ; return `t' (i.e., buffer is valid)
3581 3506
3582(defun bibtex-validate-globally (&optional strings) 3507(defun bibtex-validate-globally (&optional strings)
3583 "Check for duplicate keys in `bibtex-files'. 3508 "Check for duplicate keys in `bibtex-files'.
@@ -3631,37 +3556,41 @@ Return t if test was successful, nil otherwise."
3631 (toggle-read-only 1) 3556 (toggle-read-only 1)
3632 (goto-line 3)) ; first error message 3557 (goto-line 3)) ; first error message
3633 (display-buffer err-buf) 3558 (display-buffer err-buf)
3634 ;; return nil 3559 nil) ; return `nil' (i.e., buffer is invalid)
3635 nil)
3636 (message "No duplicate keys.") 3560 (message "No duplicate keys.")
3637 t))) 3561 t))) ; return `t' (i.e., buffer is valid)
3638 3562
3639(defun bibtex-next-field (begin) 3563(defun bibtex-next-field (begin &optional comma)
3640 "Move point to end of text of next BibTeX field. 3564 "Move point to end of text of next BibTeX field or entry head.
3641With prefix BEGIN non-nil, move point to its beginning." 3565With prefix BEGIN non-nil, move point to its beginning. Optional arg COMMA
3642 (interactive "P") 3566is as in `bibtex-enclosing-field'. It is t for interactive calls."
3643 (bibtex-inside-field) 3567 (interactive (list current-prefix-arg t))
3644 (let ((start (point))) 3568 (let ((bounds (bibtex-find-text-internal t nil comma))
3645 (condition-case () 3569 end-of-entry)
3646 (let ((bounds (bibtex-enclosing-field))) 3570 (if (not bounds)
3647 (goto-char (bibtex-end-of-field bounds)) 3571 (setq end-of-entry t)
3648 (forward-char 2)) 3572 (goto-char (nth 3 bounds))
3649 (error 3573 (if (assoc-string (car bounds) '("@String" "@Preamble") t)
3650 (goto-char start) 3574 (setq end-of-entry t)
3651 (end-of-line) 3575 ;; BibTeX key or field
3652 (forward-char)))) 3576 (if (looking-at ",[ \t\n]*") (goto-char (match-end 0)))
3653 (bibtex-find-text begin nil bibtex-help-message)) 3577 ;; end of entry
3654 3578 (if (looking-at "[)}][ \t\n]*") (setq end-of-entry t))))
3655(defun bibtex-find-text (&optional begin noerror help) 3579 (if (and end-of-entry
3656 "Move point to end of text of current BibTeX field. 3580 (re-search-forward bibtex-any-entry-maybe-empty-head nil t))
3581 (goto-char (match-beginning 0)))
3582 (bibtex-find-text begin nil bibtex-help-message)))
3583
3584(defun bibtex-find-text (&optional begin noerror help comma)
3585 "Move point to end of text of current BibTeX field or entry head.
3657With optional prefix BEGIN non-nil, move point to its beginning. 3586With optional prefix BEGIN non-nil, move point to its beginning.
3658Unless NOERROR is non-nil, an error is signaled if point is not 3587Unless NOERROR is non-nil, an error is signaled if point is not
3659on a BibTeX field. If optional arg HELP is non-nil print help message. 3588on a BibTeX field. If optional arg HELP is non-nil print help message.
3660When called interactively, the value of HELP is `bibtex-help-message'." 3589When called interactively, the value of HELP is `bibtex-help-message'.
3661 (interactive (list current-prefix-arg nil bibtex-help-message)) 3590Optional arg COMMA is as in `bibtex-enclosing-field'. It is t for
3662 (let ((pnt (point)) 3591interactive calls."
3663 (bounds (bibtex-find-text-internal))) 3592 (interactive (list current-prefix-arg nil bibtex-help-message t))
3664 (beginning-of-line) 3593 (let ((bounds (bibtex-find-text-internal t nil comma)))
3665 (cond (bounds 3594 (cond (bounds
3666 (if begin 3595 (if begin
3667 (progn (goto-char (nth 1 bounds)) 3596 (progn (goto-char (nth 1 bounds))
@@ -3670,72 +3599,88 @@ When called interactively, the value of HELP is `bibtex-help-message'."
3670 (goto-char (nth 2 bounds)) 3599 (goto-char (nth 2 bounds))
3671 (if (memq (preceding-char) '(?} ?\")) 3600 (if (memq (preceding-char) '(?} ?\"))
3672 (forward-char -1))) 3601 (forward-char -1)))
3673 (if help (bibtex-print-help-message))) 3602 (if help (bibtex-print-help-message (car bounds))))
3674 ((looking-at bibtex-entry-maybe-empty-head) 3603 ((not noerror) (error "Not on BibTeX field")))))
3675 (goto-char (if begin
3676 (match-beginning bibtex-key-in-head)
3677 (match-end 0))))
3678 (t
3679 (goto-char pnt)
3680 (unless noerror (error "Not on BibTeX field"))))))
3681 3604
3682(defun bibtex-find-text-internal (&optional noerror subfield) 3605(defun bibtex-find-text-internal (&optional noerror subfield comma)
3683 "Find text part of current BibTeX field, @String or @Preamble. 3606 "Find text part of current BibTeX field or entry head.
3684Return list (NAME START END) with field name, start and end of text 3607Return list (NAME START-TEXT END-TEXT END) with field or entry name,
3685or nil if not found. 3608start and end of text and end of field or entry head, or nil if not found.
3686If optional arg NOERROR is non-nil, an error message is suppressed if text 3609If optional arg NOERROR is non-nil, an error message is suppressed if text
3687is not found. If optional arg SUBFIELD is non-nil START and END correspond 3610is not found. If optional arg SUBFIELD is non-nil START-TEXT and END-TEXT
3688to the current subfield delimited by #." 3611correspond to the current subfield delimited by #.
3612Optional arg COMMA is as in `bibtex-enclosing-field'."
3689 (save-excursion 3613 (save-excursion
3690 (let ((pnt (point)) 3614 (let ((pnt (point))
3691 (_ (bibtex-inside-field)) 3615 (bounds (bibtex-enclosing-field comma t))
3692 (bounds (bibtex-enclosing-field t))
3693 (case-fold-search t) 3616 (case-fold-search t)
3694 (bibtex-string-empty-key t) 3617 name start-text end-text end failure done no-sub)
3695 name start end)
3696 (bibtex-beginning-of-entry) 3618 (bibtex-beginning-of-entry)
3697 (cond (bounds 3619 (cond (bounds
3698 (setq name (bibtex-name-in-field bounds t) 3620 (setq name (bibtex-name-in-field bounds t)
3699 start (bibtex-start-of-text-in-field bounds) 3621 start-text (bibtex-start-of-text-in-field bounds)
3700 end (bibtex-end-of-text-in-field bounds))) 3622 end-text (bibtex-end-of-text-in-field bounds)
3623 end (bibtex-end-of-field bounds)))
3701 ;; @String 3624 ;; @String
3702 ((setq bounds (bibtex-parse-string)) 3625 ((setq bounds (bibtex-parse-string t))
3703 (setq name "@String" ;; not a field name! 3626 (if (<= pnt (bibtex-end-of-string bounds))
3704 start (bibtex-start-of-text-in-string bounds) 3627 (setq name "@String" ;; not a field name!
3705 end (bibtex-end-of-text-in-string bounds))) 3628 start-text (bibtex-start-of-text-in-string bounds)
3629 end-text (bibtex-end-of-text-in-string bounds)
3630 end (bibtex-end-of-string bounds))
3631 (setq failure t)))
3706 ;; @Preamble 3632 ;; @Preamble
3707 ((and (bibtex-preamble-prefix t) 3633 ((setq bounds (bibtex-parse-preamble))
3708 (setq bounds (bibtex-parse-field-text))) 3634 (if (<= pnt (bibtex-end-of-string bounds))
3709 (setq name "@Preamble" ;; not a field name! 3635 (setq name "@Preamble" ;; not a field name!
3710 start (car bounds) 3636 start-text (bibtex-start-of-text-in-string bounds)
3711 end (nth 1 bounds))) 3637 end-text (bibtex-end-of-text-in-string bounds)
3712 (t (unless noerror (error "Not on BibTeX field")))) 3638 end (bibtex-end-of-string bounds))
3713 (when (and start end subfield) 3639 (setq failure t)))
3714 (goto-char start) 3640 ;; BibTeX head
3715 (let (done) 3641 ((looking-at bibtex-entry-maybe-empty-head)
3642 (goto-char (match-end 0))
3643 (if comma (save-match-data
3644 (re-search-forward "\\=[ \t\n]*," nil t)))
3645 (if (<= pnt (point))
3646 (setq name (match-string-no-properties bibtex-type-in-head)
3647 start-text (or (match-beginning bibtex-key-in-head)
3648 (match-end 0))
3649 end-text (or (match-end bibtex-key-in-head)
3650 (match-end 0))
3651 end end-text
3652 no-sub t) ;; subfields do not make sense
3653 (setq failure t)))
3654 (t (setq failure t)))
3655 (when (and subfield (not failure))
3656 (setq failure no-sub)
3657 (unless failure
3658 (goto-char start-text)
3716 (while (not done) 3659 (while (not done)
3717 (if (or (prog1 (looking-at bibtex-field-const) 3660 (if (or (prog1 (looking-at bibtex-field-const)
3718 (setq end (match-end 0))) 3661 (setq end-text (match-end 0)))
3719 (prog1 (setq bounds (bibtex-parse-field-string)) 3662 (prog1 (setq bounds (bibtex-parse-field-string))
3720 (setq end (cdr bounds)))) 3663 (setq end-text (cdr bounds))))
3721 (progn 3664 (progn
3722 (if (and (<= start pnt) (<= pnt end)) 3665 (if (and (<= start-text pnt) (<= pnt end-text))
3723 (setq done t) 3666 (setq done t)
3724 (goto-char end)) 3667 (goto-char end-text))
3725 (if (looking-at "[ \t\n]*#[ \t\n]*") 3668 (if (looking-at "[ \t\n]*#[ \t\n]*")
3726 (setq start (goto-char (match-end 0))))) 3669 (setq start-text (goto-char (match-end 0)))))
3727 (unless noerror (error "Not on text part of BibTeX field")) 3670 (setq done t failure t)))))
3728 (setq done t start nil end nil))))) 3671 (cond ((not failure)
3729 (if (and start end) 3672 (list name start-text end-text end))
3730 (list name start end))))) 3673 ((and no-sub (not noerror))
3731 3674 (error "Not on text part of BibTeX field"))
3732(defun bibtex-remove-OPT-or-ALT () 3675 ((not noerror) (error "Not on BibTeX field"))))))
3676
3677(defun bibtex-remove-OPT-or-ALT (&optional comma)
3733 "Remove the string starting optional/alternative fields. 3678 "Remove the string starting optional/alternative fields.
3734Align text and go thereafter to end of text." 3679Align text and go thereafter to end of text. Optional arg COMMA
3735 (interactive) 3680is as in `bibtex-enclosing-field'. It is t for interactive calls."
3736 (bibtex-inside-field) 3681 (interactive (list t))
3737 (let ((case-fold-search t) 3682 (let ((case-fold-search t)
3738 (bounds (bibtex-enclosing-field))) 3683 (bounds (bibtex-enclosing-field comma)))
3739 (save-excursion 3684 (save-excursion
3740 (goto-char (bibtex-start-of-name-in-field bounds)) 3685 (goto-char (bibtex-start-of-name-in-field bounds))
3741 (when (looking-at "OPT\\|ALT") 3686 (when (looking-at "OPT\\|ALT")
@@ -3751,14 +3696,14 @@ Align text and go thereafter to end of text."
3751 (delete-horizontal-space) 3696 (delete-horizontal-space)
3752 (if bibtex-align-at-equal-sign 3697 (if bibtex-align-at-equal-sign
3753 (insert " ") 3698 (insert " ")
3754 (indent-to-column bibtex-text-indentation)))) 3699 (indent-to-column bibtex-text-indentation))))))
3755 (bibtex-inside-field))) 3700
3756 3701(defun bibtex-remove-delimiters (&optional comma)
3757(defun bibtex-remove-delimiters () 3702 "Remove \"\" or {} around current BibTeX field text.
3758 "Remove \"\" or {} around current BibTeX field text." 3703Optional arg COMMA is as in `bibtex-enclosing-field'. It is t for
3759 (interactive) 3704interactive calls."
3760 ;; `bibtex-find-text-internal' issues an error message if bounds is nil. 3705 (interactive (list t))
3761 (let* ((bounds (bibtex-find-text-internal nil t)) 3706 (let* ((bounds (bibtex-find-text-internal nil t comma))
3762 (start (nth 1 bounds)) 3707 (start (nth 1 bounds))
3763 (end (nth 2 bounds))) 3708 (end (nth 2 bounds)))
3764 (if (memq (char-before end) '(?\} ?\")) 3709 (if (memq (char-before end) '(?\} ?\"))
@@ -3766,15 +3711,15 @@ Align text and go thereafter to end of text."
3766 (if (memq (char-after start) '(?\{ ?\")) 3711 (if (memq (char-after start) '(?\{ ?\"))
3767 (delete-region start (1+ start))))) 3712 (delete-region start (1+ start)))))
3768 3713
3769(defun bibtex-kill-field (&optional copy-only) 3714(defun bibtex-kill-field (&optional copy-only comma)
3770 "Kill the entire enclosing BibTeX field. 3715 "Kill the entire enclosing BibTeX field.
3771With prefix arg COPY-ONLY, copy the current field to `bibtex-field-kill-ring', 3716With prefix arg COPY-ONLY, copy the current field to `bibtex-field-kill-ring',
3772but do not actually kill it." 3717but do not actually kill it. Optional arg COMMA is as in
3773 (interactive "P") 3718`bibtex-enclosing-field'. It is t for interactive calls."
3719 (interactive (list current-prefix-arg t))
3774 (save-excursion 3720 (save-excursion
3775 (bibtex-inside-field)
3776 (let* ((case-fold-search t) 3721 (let* ((case-fold-search t)
3777 (bounds (bibtex-enclosing-field)) 3722 (bounds (bibtex-enclosing-field comma))
3778 (end (bibtex-end-of-field bounds)) 3723 (end (bibtex-end-of-field bounds))
3779 (beg (bibtex-start-of-field bounds))) 3724 (beg (bibtex-start-of-field bounds)))
3780 (goto-char end) 3725 (goto-char end)
@@ -3791,10 +3736,12 @@ but do not actually kill it."
3791 (delete-region beg end)))) 3736 (delete-region beg end))))
3792 (setq bibtex-last-kill-command 'field)) 3737 (setq bibtex-last-kill-command 'field))
3793 3738
3794(defun bibtex-copy-field-as-kill () 3739(defun bibtex-copy-field-as-kill (&optional comma)
3795 "Copy the BibTeX field at point to the kill ring." 3740 "Copy the BibTeX field at point to the kill ring.
3796 (interactive) 3741Optional arg COMMA is as in `bibtex-enclosing-field'. It is t for
3797 (bibtex-kill-field t)) 3742interactive calls."
3743 (interactive (list t))
3744 (bibtex-kill-field t comma))
3798 3745
3799(defun bibtex-kill-entry (&optional copy-only) 3746(defun bibtex-kill-entry (&optional copy-only)
3800 "Kill the entire enclosing BibTeX entry. 3747 "Kill the entire enclosing BibTeX entry.
@@ -3806,7 +3753,7 @@ but do not actually kill it."
3806 (beg (bibtex-beginning-of-entry)) 3753 (beg (bibtex-beginning-of-entry))
3807 (end (progn (bibtex-end-of-entry) 3754 (end (progn (bibtex-end-of-entry)
3808 (if (re-search-forward 3755 (if (re-search-forward
3809 bibtex-entry-maybe-empty-head nil 'move) 3756 bibtex-any-entry-maybe-empty-head nil 'move)
3810 (goto-char (match-beginning 0))) 3757 (goto-char (match-beginning 0)))
3811 (point)))) 3758 (point))))
3812 (push (buffer-substring-no-properties beg end) 3759 (push (buffer-substring-no-properties beg end)
@@ -3831,13 +3778,13 @@ More precisely, reinsert the field or entry killed or yanked most recently.
3831With argument N, reinsert the Nth most recently killed BibTeX item. 3778With argument N, reinsert the Nth most recently killed BibTeX item.
3832See also the command \\[bibtex-yank-pop]." 3779See also the command \\[bibtex-yank-pop]."
3833 (interactive "*p") 3780 (interactive "*p")
3834 (bibtex-insert-kill (1- n)) 3781 (bibtex-insert-kill (1- n) t)
3835 (setq this-command 'bibtex-yank)) 3782 (setq this-command 'bibtex-yank))
3836 3783
3837(defun bibtex-yank-pop (n) 3784(defun bibtex-yank-pop (n)
3838 "Replace just-yanked killed BibTeX item with a different item. 3785 "Replace just-yanked killed BibTeX item with a different item.
3839This command is allowed only immediately after a `bibtex-yank' or a 3786This command is allowed only immediately after a `bibtex-yank' or a
3840`bibtex-yank-pop'. At such a time, the region contains a reinserted 3787`bibtex-yank-pop'. In this case, the region contains a reinserted
3841previously killed BibTeX item. `bibtex-yank-pop' deletes that item 3788previously killed BibTeX item. `bibtex-yank-pop' deletes that item
3842and inserts in its place a different killed BibTeX item. 3789and inserts in its place a different killed BibTeX item.
3843 3790
@@ -3853,13 +3800,14 @@ comes the newest one."
3853 (setq this-command 'bibtex-yank) 3800 (setq this-command 'bibtex-yank)
3854 (let ((inhibit-read-only t)) 3801 (let ((inhibit-read-only t))
3855 (delete-region (point) (mark t)) 3802 (delete-region (point) (mark t))
3856 (bibtex-insert-kill n))) 3803 (bibtex-insert-kill n t)))
3857 3804
3858(defun bibtex-empty-field () 3805(defun bibtex-empty-field (&optional comma)
3859 "Delete the text part of the current field, replace with empty text." 3806 "Delete the text part of the current field, replace with empty text.
3860 (interactive) 3807Optional arg COMMA is as in `bibtex-enclosing-field'. It is t for
3861 (bibtex-inside-field) 3808interactive calls."
3862 (let ((bounds (bibtex-enclosing-field))) 3809 (interactive (list t))
3810 (let ((bounds (bibtex-enclosing-field comma)))
3863 (goto-char (bibtex-start-of-text-in-field bounds)) 3811 (goto-char (bibtex-start-of-text-in-field bounds))
3864 (delete-region (point) (bibtex-end-of-text-in-field bounds)) 3812 (delete-region (point) (bibtex-end-of-text-in-field bounds))
3865 (insert (bibtex-field-left-delimiter) 3813 (insert (bibtex-field-left-delimiter)
@@ -3960,7 +3908,7 @@ At end of the cleaning process, the functions in
3960 (if (and (listp bibtex-strings) 3908 (if (and (listp bibtex-strings)
3961 (not (assoc key bibtex-strings))) 3909 (not (assoc key bibtex-strings)))
3962 (push (cons key (bibtex-text-in-string 3910 (push (cons key (bibtex-text-in-string
3963 (save-excursion (bibtex-parse-string)) t)) 3911 (bibtex-parse-string) t))
3964 bibtex-strings))) 3912 bibtex-strings)))
3965 ;; We have a normal entry. 3913 ;; We have a normal entry.
3966 ((listp bibtex-reference-keys) 3914 ((listp bibtex-reference-keys)
@@ -3988,28 +3936,27 @@ At end of the cleaning process, the functions in
3988If JUSTIFY is non-nil justify as well. 3936If JUSTIFY is non-nil justify as well.
3989If optional arg MOVE is non-nil move point to end of field." 3937If optional arg MOVE is non-nil move point to end of field."
3990 (let ((end-field (copy-marker (bibtex-end-of-field bounds)))) 3938 (let ((end-field (copy-marker (bibtex-end-of-field bounds))))
3991 (goto-char (bibtex-start-of-field bounds)) 3939 (if (not justify)
3992 (if justify 3940 (goto-char (bibtex-start-of-text-in-field bounds))
3993 (progn 3941 (goto-char (bibtex-start-of-field bounds))
3994 (forward-char) 3942 (forward-char) ;; leading comma
3995 (bibtex-delete-whitespace) 3943 (bibtex-delete-whitespace)
3996 (open-line 1) 3944 (open-line 1)
3997 (forward-char) 3945 (forward-char)
3998 (indent-to-column (+ bibtex-entry-offset 3946 (indent-to-column (+ bibtex-entry-offset
3999 bibtex-field-indentation)) 3947 bibtex-field-indentation))
4000 (re-search-forward "[ \t\n]*=" end-field) 3948 (re-search-forward "[ \t\n]*=" end-field)
4001 (replace-match "=") 3949 (replace-match "=")
4002 (forward-char -1) 3950 (forward-char -1)
4003 (if bibtex-align-at-equal-sign 3951 (if bibtex-align-at-equal-sign
4004 (indent-to-column 3952 (indent-to-column
4005 (+ bibtex-entry-offset (- bibtex-text-indentation 2))) 3953 (+ bibtex-entry-offset (- bibtex-text-indentation 2)))
4006 (insert " ")) 3954 (insert " "))
4007 (forward-char) 3955 (forward-char)
4008 (bibtex-delete-whitespace) 3956 (bibtex-delete-whitespace)
4009 (if bibtex-align-at-equal-sign 3957 (if bibtex-align-at-equal-sign
4010 (insert " ") 3958 (insert " ")
4011 (indent-to-column bibtex-text-indentation))) 3959 (indent-to-column bibtex-text-indentation)))
4012 (re-search-forward "[ \t\n]*=[ \t\n]*" end-field))
4013 ;; Paragraphs within fields are not preserved. Bother? 3960 ;; Paragraphs within fields are not preserved. Bother?
4014 (fill-region-as-paragraph (line-beginning-position) end-field 3961 (fill-region-as-paragraph (line-beginning-position) end-field
4015 default-justification nil (point)) 3962 default-justification nil (point))
@@ -4017,14 +3964,13 @@ If optional arg MOVE is non-nil move point to end of field."
4017 3964
4018(defun bibtex-fill-field (&optional justify) 3965(defun bibtex-fill-field (&optional justify)
4019 "Like \\[fill-paragraph], but fill current BibTeX field. 3966 "Like \\[fill-paragraph], but fill current BibTeX field.
4020Optional prefix arg JUSTIFY non-nil means justify as well. 3967If optional prefix JUSTIFY is non-nil justify as well.
4021In BibTeX mode this function is bound to `fill-paragraph-function'." 3968In BibTeX mode this function is bound to `fill-paragraph-function'."
4022 (interactive "*P") 3969 (interactive "*P")
4023 (let ((pnt (copy-marker (point))) 3970 (let ((pnt (copy-marker (point)))
4024 (bounds (bibtex-enclosing-field))) 3971 (bounds (bibtex-enclosing-field t)))
4025 (when bounds 3972 (bibtex-fill-field-bounds bounds justify)
4026 (bibtex-fill-field-bounds bounds justify) 3973 (goto-char pnt)))
4027 (goto-char pnt))))
4028 3974
4029(defun bibtex-fill-entry () 3975(defun bibtex-fill-entry ()
4030 "Fill current BibTeX entry. 3976 "Fill current BibTeX entry.
@@ -4035,14 +3981,16 @@ If `bibtex-align-at-equal-sign' is non-nil, align equal signs, too."
4035 (interactive "*") 3981 (interactive "*")
4036 (let ((pnt (copy-marker (point))) 3982 (let ((pnt (copy-marker (point)))
4037 (end (copy-marker (bibtex-end-of-entry))) 3983 (end (copy-marker (bibtex-end-of-entry)))
3984 (beg (bibtex-beginning-of-entry)) ; move point
4038 bounds) 3985 bounds)
4039 (bibtex-beginning-of-entry)
4040 (bibtex-delete-whitespace) 3986 (bibtex-delete-whitespace)
4041 (indent-to-column bibtex-entry-offset) 3987 (indent-to-column bibtex-entry-offset)
4042 (while (setq bounds (bibtex-search-forward-field bibtex-field-name end)) 3988 (bibtex-beginning-first-field beg)
3989 (while (setq bounds (bibtex-parse-field))
4043 (bibtex-fill-field-bounds bounds t t)) 3990 (bibtex-fill-field-bounds bounds t t))
4044 (if (looking-at ",") 3991 (if (looking-at ",")
4045 (forward-char)) 3992 (forward-char))
3993 (skip-chars-backward " \t\n")
4046 (bibtex-delete-whitespace) 3994 (bibtex-delete-whitespace)
4047 (open-line 1) 3995 (open-line 1)
4048 (forward-char) 3996 (forward-char)
@@ -4115,8 +4063,7 @@ If mark is active reformat entries in region, if not in whole buffer."
4115 bibtex-autokey-edit-before-use) 4063 bibtex-autokey-edit-before-use)
4116 4064
4117 (save-restriction 4065 (save-restriction
4118 (narrow-to-region (if mark-active (region-beginning) (point-min)) 4066 (if mark-active (narrow-to-region (region-beginning) (region-end)))
4119 (if mark-active (region-end) (point-max)))
4120 (if (memq 'realign bibtex-entry-format) 4067 (if (memq 'realign bibtex-entry-format)
4121 (bibtex-realign)) 4068 (bibtex-realign))
4122 (bibtex-progress-message "Formatting" 1) 4069 (bibtex-progress-message "Formatting" 1)
@@ -4143,12 +4090,10 @@ entries from minibuffer."
4143 (message "Starting to validate buffer...") 4090 (message "Starting to validate buffer...")
4144 (sit-for 1 nil t) 4091 (sit-for 1 nil t)
4145 (bibtex-realign) 4092 (bibtex-realign)
4146 (message
4147 "If errors occur, correct them and call `bibtex-convert-alien' again")
4148 (sit-for 5 nil t)
4149 (deactivate-mark) ; So bibtex-validate works on the whole buffer. 4093 (deactivate-mark) ; So bibtex-validate works on the whole buffer.
4150 (when (let (bibtex-maintain-sorted-entries) 4094 (if (not (let (bibtex-maintain-sorted-entries)
4151 (bibtex-validate)) 4095 (bibtex-validate)))
4096 (message "Correct errors and call `bibtex-convert-alien' again")
4152 (message "Starting to reformat entries...") 4097 (message "Starting to reformat entries...")
4153 (sit-for 2 nil t) 4098 (sit-for 2 nil t)
4154 (bibtex-reformat read-options) 4099 (bibtex-reformat read-options)
@@ -4166,10 +4111,9 @@ An error is signaled if point is outside key or BibTeX field."
4166 (interactive) 4111 (interactive)
4167 (let ((pnt (point)) 4112 (let ((pnt (point))
4168 (case-fold-search t) 4113 (case-fold-search t)
4169 (bibtex-string-empty-key t)
4170 bounds name compl) 4114 bounds name compl)
4171 (save-excursion 4115 (save-excursion
4172 (if (and (setq bounds (bibtex-enclosing-field t)) 4116 (if (and (setq bounds (bibtex-enclosing-field nil t))
4173 (>= pnt (bibtex-start-of-text-in-field bounds)) 4117 (>= pnt (bibtex-start-of-text-in-field bounds))
4174 (<= pnt (bibtex-end-of-text-in-field bounds))) 4118 (<= pnt (bibtex-end-of-text-in-field bounds)))
4175 (setq name (bibtex-name-in-field bounds t) 4119 (setq name (bibtex-name-in-field bounds t)
@@ -4182,7 +4126,7 @@ An error is signaled if point is outside key or BibTeX field."
4182 ;; point is in other field 4126 ;; point is in other field
4183 (t (bibtex-strings)))) 4127 (t (bibtex-strings))))
4184 (bibtex-beginning-of-entry) 4128 (bibtex-beginning-of-entry)
4185 (cond ((setq bounds (bibtex-parse-string)) 4129 (cond ((setq bounds (bibtex-parse-string t))
4186 ;; point is inside a @String key 4130 ;; point is inside a @String key
4187 (cond ((and (>= pnt (nth 1 (car bounds))) 4131 (cond ((and (>= pnt (nth 1 (car bounds)))
4188 (<= pnt (nth 2 (car bounds)))) 4132 (<= pnt (nth 2 (car bounds))))
@@ -4192,11 +4136,10 @@ An error is signaled if point is outside key or BibTeX field."
4192 (<= pnt (bibtex-end-of-text-in-string bounds))) 4136 (<= pnt (bibtex-end-of-text-in-string bounds)))
4193 (setq compl (bibtex-strings))))) 4137 (setq compl (bibtex-strings)))))
4194 ;; point is inside a @Preamble field 4138 ;; point is inside a @Preamble field
4195 ((and (bibtex-preamble-prefix t) 4139 ((setq bounds (bibtex-parse-preamble))
4196 (setq bounds (bibtex-parse-field-text)) 4140 (if (and (>= pnt (bibtex-start-of-text-in-string bounds))
4197 (>= pnt (car bounds)) 4141 (<= pnt (bibtex-end-of-text-in-string bounds)))
4198 (<= pnt (nth 1 bounds))) 4142 (setq compl (bibtex-strings))))
4199 (setq compl (bibtex-strings)))
4200 ((and (looking-at bibtex-entry-maybe-empty-head) 4143 ((and (looking-at bibtex-entry-maybe-empty-head)
4201 ;; point is inside a key 4144 ;; point is inside a key
4202 (or (and (match-beginning bibtex-key-in-head) 4145 (or (and (match-beginning bibtex-key-in-head)