comparison lisp/textmodes/bibtex.el @ 67894:d742983a2136

(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.
author Roland Winkler <Roland.Winkler@physik.uni-erlangen.de>
date Thu, 29 Dec 2005 15:23:52 +0000
parents d195eef388b8
children 823f54b91fe2
comparison
equal deleted inserted replaced
67893:6af57e0a5d45 67894:d742983a2136
851 (defcustom bibtex-expand-strings nil 851 (defcustom bibtex-expand-strings nil
852 "If non-nil, expand strings when extracting the content of a BibTeX field." 852 "If non-nil, expand strings when extracting the content of a BibTeX field."
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
860 860
861 ;; Syntax Table and Keybindings 861 ;; Syntax Table and Keybindings
1089 1089
1090 (defconst bibtex-field-name "[^\"#%'(),={} \t\n0-9][^\"#%'(),={} \t\n]*" 1090 (defconst bibtex-field-name "[^\"#%'(),={} \t\n0-9][^\"#%'(),={} \t\n]*"
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:].:;?!`'/*@+|()<>&_^$-]+"
1098 "Regexp matching the reference key part of a BibTeX entry.") 1098 "Regexp matching the reference key part of a BibTeX entry.")
1099 1099
1102 1102
1103 (defvar bibtex-entry-type 1103 (defvar bibtex-entry-type
1104 (concat "@[ \t]*\\(?:" 1104 (concat "@[ \t]*\\(?:"
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
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 1107
1118 (defvar bibtex-entry-head 1108 (defvar bibtex-entry-head
1119 (concat "^[ \t]*\\(" 1109 (concat "^[ \t]*\\("
1120 bibtex-entry-type 1110 bibtex-entry-type
1121 "\\)[ \t]*[({][ \t\n]*\\(" 1111 "\\)[ \t]*[({][ \t\n]*\\("
1130 (defconst bibtex-any-entry-maybe-empty-head 1120 (defconst bibtex-any-entry-maybe-empty-head
1131 (concat "^[ \t]*\\(@[ \t]*" bibtex-field-name "\\)[ \t]*[({][ \t\n]*\\(" 1121 (concat "^[ \t]*\\(@[ \t]*" bibtex-field-name "\\)[ \t]*[({][ \t\n]*\\("
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
1141 (defconst bibtex-empty-field-re "\\`\\(\"\"\\|{}\\)\\'"
1142 "Regexp matching the text part (as a string) of an empty field.")
1143 1136
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
1147 (defconst bibtex-string-maybe-empty-head 1140 (defconst bibtex-string-maybe-empty-head
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) "\\)"
1156 (substring bibtex-comment-start 1) "\\>") 1150 (substring bibtex-comment-start 1) "\\>")
1157 1 '(11)))) 1151 1 '(11))))
1227 If the field name is found, return a triple consisting of the position of the 1221 If the field name is found, return a triple consisting of the position of the
1228 very first character of the match, the actual starting position of the name 1222 very first character of the match, the actual starting position of the name
1229 part and end position of the match. Move point to end of field name. 1223 part and end position of the match. Move point to end of field name.
1230 If `bibtex-autoadd-commas' is non-nil add missing comma at end of preceding 1224 If `bibtex-autoadd-commas' is non-nil add missing comma at end of preceding
1231 BibTeX field as necessary." 1225 BibTeX 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
1241 "\\)[ \t\n]*="))) 1232 "\\)[ \t\n]*=")))
1242 (skip-chars-backward " \t\n") 1233 (skip-chars-backward " \t\n")
1332 1323
1333 (defun bibtex-search-forward-field (name &optional bound) 1324 (defun bibtex-search-forward-field (name &optional bound)
1334 "Search forward to find a BibTeX field of name NAME. 1325 "Search forward to find a BibTeX field of name NAME.
1335 If a syntactically correct field is found, return a pair containing 1326 If a syntactically correct field is found, return a pair containing
1336 the boundaries of the name and text parts of the field. The search 1327 the boundaries of the name and text parts of the field. The search
1337 is limited by optional arg BOUND or if nil by the end of the current 1328 is limited by optional arg BOUND. If BOUND is t the search is limited
1338 entry. Do not move point." 1329 by 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.
1376 If a syntactically correct field is found, return a pair containing 1367 If a syntactically correct field is found, return a pair containing
1377 the boundaries of the name and text parts of the field. The search 1368 the boundaries of the name and text parts of the field. The search
1378 is limited by the optional arg BOUND. If BOUND is nil the search is 1369 is limited by the optional arg BOUND. If BOUND is t the search is
1379 limited by the beginning of the current entry. Do not move point." 1370 limited 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.
1394 If optional arg REMOVE-OPT-ALT is non-nil remove \"OPT\" and \"ALT\"." 1396 If optional arg REMOVE-OPT-ALT is non-nil remove \"OPT\" and \"ALT\"."
1395 (let ((name (buffer-substring-no-properties 1397 (let ((name (buffer-substring-no-properties
1405 If optional arg CONTENT is non-nil extract content of field 1407 If optional arg CONTENT is non-nil extract content of field
1406 by removing field delimiters and concatenating the resulting string. 1408 by removing field delimiters and concatenating the resulting string.
1407 If `bibtex-expand-strings' is non-nil, also expand BibTeX strings." 1409 If `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
1432 (defun bibtex-text-in-field (field &optional follow-crossref) 1431 (defun bibtex-text-in-field (field &optional follow-crossref)
1433 "Get content of field FIELD of current BibTeX entry. 1432 "Get content of field FIELD of current BibTeX entry.
1434 Return nil if not found. 1433 Return nil if not found.
1435 If optional arg FOLLOW-CROSSREF is non-nil, follow crossref." 1434 If 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.
1453 (bibtex-text-in-field field)))))))) 1448 (bibtex-text-in-field field))))))))
1454 1449
1485 (goto-char (match-end 0)) 1480 (goto-char (match-end 0))
1486 (list (car bounds) 1481 (list (car bounds)
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.
1492 If a syntactically correct entry is found, return a cons pair containing 1487 If a syntactically correct entry is found, return a cons pair containing
1493 the boundaries of the reference key and text parts of the entry. 1488 the boundaries of the reference key and text parts of the entry.
1494 Do not move point." 1489 If 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
1497 1492 'bibtex-parse-string-postfix)))
1498 (defun bibtex-search-forward-string () 1493
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.
1500 If a syntactically correct entry is found, a pair containing the boundaries of 1496 If a syntactically correct entry is found, a pair containing the boundaries of
1501 the reference key and text parts of the string is returned. Do not move point." 1497 the reference key and text parts of the string is returned.
1498 If 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.
1515 If a syntactically correct entry is found, a pair containing the boundaries of
1516 the 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"
1529 (buffer-substring-no-properties (nth 1 (car bounds)) 1510 (buffer-substring-no-properties (nth 1 (car bounds))
1530 (nth 2 (car bounds)))) 1511 (nth 2 (car bounds))))
1552 (defsubst bibtex-key-in-head (&optional empty) 1533 (defsubst bibtex-key-in-head (&optional empty)
1553 "Extract BibTeX key in head. Return optional arg EMPTY if key is empty." 1534 "Extract BibTeX key in head. Return optional arg EMPTY if key is empty."
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.
1559 Point must be at beginning of prefix part. If prefix is found move point 1540 Point must be at beginning of preamble. Do not move point."
1560 to its end and return position of point. If optional arg DELIM is non-nil,
1561 move 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
1568 (defsubst bibtex-string= (str1 str2) 1550 (defsubst bibtex-string= (str1 str2)
1569 "Return t if STR1 and STR2 are equal, ignoring case." 1551 "Return t if STR1 and STR2 are equal, ignoring case."
1576 1558
1577 (defun bibtex-current-line () 1559 (defun bibtex-current-line ()
1578 "Compute line number of point regardless whether the buffer is narrowed." 1560 "Compute line number of point regardless whether the buffer is narrowed."
1579 (+ (count-lines 1 (point)) 1561 (+ (count-lines 1 (point))
1580 (if (bolp) 1 0))) 1562 (if (bolp) 1 0)))
1563
1564 (defun bibtex-valid-entry (&optional empty-key)
1565 "Parse a valid BibTeX entry (maybe without key if EMPTY-KEY is t).
1566 A valid entry is a syntactical correct one with type contained in
1567 `bibtex-entry-field-alist'. Ignore @String and @Preamble entries.
1568 Return a cons pair with buffer positions of beginning and end of entry
1569 if a valid entry is found, nil otherwise. Do not move point.
1570 After a call to this function `match-data' corresponds to the header
1571 of 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))))))
1581 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.
1584 Do not move if we are already at beginning of a valid BibTeX entry. 1595 Do not move if we are already at beginning of a valid BibTeX entry.
1585 With optional argument BACKWARD non-nil, move backward to 1596 With optional argument BACKWARD non-nil, move backward to
1588 `bibtex-sort-ignore-string-entries' is nil, a syntactical correct string 1599 `bibtex-sort-ignore-string-entries' is nil, a syntactical correct string
1589 entry. Return buffer position of beginning and end of entry if a valid 1600 entry. Return buffer position of beginning and end of entry if a valid
1590 entry is found, nil otherwise." 1601 entry 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).
1615 FUN is called with three arguments, the key of the entry and the buffer 1620 FUN is called with three arguments, the key of the entry and the buffer
1616 positions (marker) of beginning and end of entry. Point is inside the entry. 1621 positions of beginning and end of entry. Also, point is at beginning of
1617 If `bibtex-sort-ignore-string-entries' is non-nil, FUN is not called for 1622 entry and `match-data' corresponds to the header of the entry,
1618 @String entries." 1623 see regexp `bibtex-entry-head'. If `bibtex-sort-ignore-string-entries'
1624 is 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
1622 (goto-char (point-min)) 1628 (goto-char (point-min))
1623 (while (setq found (bibtex-skip-to-valid-entry)) 1629 (while (setq found (bibtex-skip-to-valid-entry))
1671 "Return a string dependent on `bibtex-entry-delimiters'." 1677 "Return a string dependent on `bibtex-entry-delimiters'."
1672 (if (eq bibtex-entry-delimiters 'braces) 1678 (if (eq bibtex-entry-delimiters 'braces)
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).
1678 BOUND and NOERROR are exactly as in `re-search-forward'. If BACKWARD
1679 is non-nil, search in reverse direction. Move point past the closing
1680 delimiter (at the beginning of entry if BACKWARD is non-nil).
1681 Return a cons pair with buffer positions of beginning and end of entry.
1682 After a call to this function `match-data' corresponds to the head part
1683 of the entry, see regexp `bibtex-entry-head'.
1684 Ignore @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."
1748 (if (consp field) 1698 (if (consp field)
1749 (bibtex-make-field (cons (concat "OPT" (car field)) (cdr field))) 1699 (bibtex-make-field (cons (concat "OPT" (car field)) (cdr field)))
1770 are ignored. Return point" 1720 are ignored. Return point"
1771 (goto-char (point-min)) 1721 (goto-char (point-min))
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.
1727 For `bibtex-mode''s internal algorithms, a field begins at the comma
1728 following the preceding field. Usually, this is not what the user expects.
1729 Thus if COMMA is non-nil, the \"current field\" includes the terminating comma.
1787 Unless NOERR is non-nil, signal an error if no enclosing field is found. 1730 Unless NOERR is non-nil, signal an error if no enclosing field is found.
1788 On success return bounds, nil otherwise. Do not move point." 1731 On 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)))
1799 Beginning (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)) 1748 Optional 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) 1755 Optional 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'.
1838 Formats current entry according to variable `bibtex-entry-format'." 1777 Formats current entry according to variable `bibtex-entry-format'."
1839 (save-excursion 1778 (save-excursion
1898 (not non-empty-alternative) 1837 (not non-empty-alternative)
1899 (memq 'required-fields format)) 1838 (memq 'required-fields 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)))
1909 (end-name (copy-marker (bibtex-end-of-name-in-field bounds))) 1847 (end-name (copy-marker (bibtex-end-of-name-in-field bounds)))
1910 (beg-text (copy-marker (bibtex-start-of-text-in-field bounds))) 1848 (beg-text (copy-marker (bibtex-start-of-text-in-field bounds)))
2037 (error "Alternative mandatory field `%s' is missing" 1975 (error "Alternative mandatory field `%s' is missing"
2038 altlist)) 1976 altlist))
2039 ((> found 1) 1977 ((> found 1)
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
2043 ;; update point
2044 (if (looking-at (bibtex-field-right-delimiter))
2045 (forward-char))
2046 1980
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
2050 (not (looking-at ","))) 1984 (not (looking-at ",")))
2563 2497
2564 (defun bibtex-complete-string-cleanup (str compl) 2498 (defun bibtex-complete-string-cleanup (str compl)
2565 "Cleanup after inserting string STR. 2499 "Cleanup after inserting string STR.
2566 Remove enclosing field delimiters for STR. Display message with 2500 Remove enclosing field delimiters for STR. Display message with
2567 expansion of STR using expansion list COMPL." 2501 expansion 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)))))
2571 (if abbr (message "Abbreviation for `%s'" abbr)) 2506 (if abbr (message "Abbreviation for `%s'" abbr))
2572 (bibtex-remove-delimiters)))) 2507 (bibtex-remove-delimiters))))
2622 (error "Entry not found"))) 2557 (error "Entry not found")))
2623 2558
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.
2626 Generic function used by `bibtex-pop-previous' and `bibtex-pop-next'." 2561 Generic 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 ()
2674 "Move point backward to beginning of field. 2611 "Move point backward to beginning of field.
2675 This function uses a simple, fast algorithm assuming that the field 2612 This function uses a simple, fast algorithm assuming that the field
2859 `bibtex-include-OPTkey', `bibtex-include-OPTcrossref', 2796 `bibtex-include-OPTkey', `bibtex-include-OPTcrossref',
2860 and `bibtex-user-optional-fields'." 2797 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))
2868 optional (nth 1 (nth 2 e))) 2805 optional (nth 1 (nth 2 e)))
2869 (setq required (nth 0 (nth 1 e)) 2806 (setq required (nth 0 (nth 1 e))
2916 according to `bibtex-field-list', but are not yet present." 2853 according to `bibtex-field-list', but are not yet present."
2917 (interactive) 2854 (interactive)
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)))
2928 (dolist (field (cdr field-list)) 2866 (dolist (field (cdr field-list))
2929 (unless (assoc-string (car field) fields-alist t) 2867 (unless (assoc-string (car field) fields-alist t)
2962 (when (looking-at bibtex-entry-head) 2900 (when (looking-at bibtex-entry-head)
2963 (let ((type (bibtex-type-in-head)) 2901 (let ((type (bibtex-type-in-head))
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)
2970 ;; First see whether to use the previous or the next entry 2909 ;; First see whether to use the previous or the next entry
2971 ;; for "inspiration". 2910 ;; for "inspiration".
3014 (suffix (substring key (length prefix))) 2953 (suffix (substring key (length prefix)))
3015 (other-suffix (substring other-key (length prefix)))) 2954 (other-suffix (substring other-key (length prefix))))
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) 2960 Optional arg COMMA is as in `bibtex-enclosing-field'. It is t for
3022 (let* ((case-fold-search t) 2961 interactive 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.
3044 FIELD is either a string or a list of the form 2983 FIELD is either a string or a list of the form
3045 \(FIELD-NAME COMMENT-STRING INIT ALTERNATIVE-FLAG) as in 2984 \(FIELD-NAME COMMENT-STRING INIT ALTERNATIVE-FLAG) as in
3050 MOVE and INTERACTIVE are t when called interactively." 2989 MOVE and INTERACTIVE are t when called interactively."
3051 (interactive 2990 (interactive
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))
3059 nil nil nil bibtex-field-history)) 2999 nil nil nil bibtex-field-history))
3060 t t)) 3000 t t))
3079 (insert (cond ((stringp init) init) 3019 (insert (cond ((stringp init) init)
3080 ((fboundp init) (funcall init)) 3020 ((fboundp init) (funcall init))
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).
3089 If inside an entry, move to the beginning of it, otherwise move to the 3030 If inside an entry, move to the beginning of it, otherwise move to the
3090 beginning of the previous entry. If point is ahead of all BibTeX entries 3031 beginning of the previous entry. If point is ahead of all BibTeX entries
3101 If inside an entry, move to the end of it, otherwise move to the end 3042 If inside an entry, move to the end of it, otherwise move to the end
3102 of the previous entry. Do not move if ahead of first entry. 3043 of the previous entry. Do not move if ahead of first entry.
3103 Return the new location of point." 3044 Return 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."
3131 ;; code adapted from `goto-line' 3063 ;; code adapted from `goto-line'
3132 (goto-char (point-min)) 3064 (goto-char (point-min))
3186 (defun bibtex-ispell-abstract () 3118 (defun bibtex-ispell-abstract ()
3187 "Check abstract of BibTeX entry for spelling errors." 3119 "Check abstract of BibTeX entry for spelling errors."
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))
3195 (error "No abstract in entry")))) 3127 (error "No abstract in entry"))))
3196 3128
3214 ;; all entry names should be downcase (for ease of comparison) 3146 ;; all entry names should be downcase (for ease of comparison)
3215 (entry-name (downcase (bibtex-type-in-head)))) 3147 (entry-name (downcase (bibtex-type-in-head))))
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))
3223 (list key nil entry-name)))))) 3155 (list key nil entry-name))))))
3224 3156
3281 entry and SPLIT is t." 3213 entry and SPLIT is t."
3282 (interactive 3214 (interactive
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)
3290 (point) t))) 3222 (point) t)))
3291 (let (buffer pos eqb) 3223 (let (buffer pos eqb)
3427 (interactive "P") 3359 (interactive "P")
3428 (let* ((case-fold-search t) 3360 (let* ((case-fold-search t)
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))) 3365
3434 3366 ;; Check syntactical structure of entries
3435 ;; looking if entries fit syntactical structure
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)
3469 (push (cons (bibtex-current-line) 3399 (push (cons (bibtex-current-line)
3470 (format "Duplicate key `%s'" key)) 3400 (format "Duplicate key `%s'" key))
3496 "Checking required fields and month fields") 3426 "Checking required fields and month fields")
3497 (let ((bibtex-sort-ignore-string-entries t)) 3427 (let ((bibtex-sort-ignore-string-entries t))
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.
3516 (let ((month (bibtex-text-in-field-bounds bounds))) 3441 (let ((month (bibtex-text-in-field-bounds bounds)))
3517 (not (or (string-match "\\`[\"{].+[\"}]\\'" month) 3442 (not (or (string-match "\\`[\"{].+[\"}]\\'" month)
3519 month 3444 month
3520 bibtex-predefined-month-strings t))))) 3445 bibtex-predefined-month-strings t)))))
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)
3539 (push (car field) alt) 3465 (push (car field) alt)
3540 (push (cons (save-excursion (goto-char beg) 3466 (push (cons (save-excursion (goto-char beg)
3571 (insert (format "%s:%d: %s\n" file (car err) (cdr err)))) 3497 (insert (format "%s:%d: %s\n" file (car err) (cdr err))))
3572 (set-buffer-modified-p nil) 3498 (set-buffer-modified-p nil)
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'.
3584 With optional prefix arg STRINGS, check for duplicate strings, too. 3509 With optional prefix arg STRINGS, check for duplicate strings, too.
3585 Return t if test was successful, nil otherwise." 3510 Return t if test was successful, nil otherwise."
3629 (dolist (err (sort error-list 'string-lessp)) (insert err)) 3554 (dolist (err (sort error-list 'string-lessp)) (insert err))
3630 (set-buffer-modified-p nil) 3555 (set-buffer-modified-p nil)
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.
3641 With prefix BEGIN non-nil, move point to its beginning." 3565 With prefix BEGIN non-nil, move point to its beginning. Optional arg COMMA
3642 (interactive "P") 3566 is 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.
3657 With optional prefix BEGIN non-nil, move point to its beginning. 3586 With optional prefix BEGIN non-nil, move point to its beginning.
3658 Unless NOERROR is non-nil, an error is signaled if point is not 3587 Unless NOERROR is non-nil, an error is signaled if point is not
3659 on a BibTeX field. If optional arg HELP is non-nil print help message. 3588 on a BibTeX field. If optional arg HELP is non-nil print help message.
3660 When called interactively, the value of HELP is `bibtex-help-message'." 3589 When called interactively, the value of HELP is `bibtex-help-message'.
3661 (interactive (list current-prefix-arg nil bibtex-help-message)) 3590 Optional arg COMMA is as in `bibtex-enclosing-field'. It is t for
3662 (let ((pnt (point)) 3591 interactive 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))
3668 (if (looking-at "[{\"]") 3597 (if (looking-at "[{\"]")
3669 (forward-char))) 3598 (forward-char)))
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 3604
3676 (match-beginning bibtex-key-in-head) 3605 (defun bibtex-find-text-internal (&optional noerror subfield comma)
3677 (match-end 0)))) 3606 "Find text part of current BibTeX field or entry head.
3678 (t 3607 Return list (NAME START-TEXT END-TEXT END) with field or entry name,
3679 (goto-char pnt) 3608 start and end of text and end of field or entry head, or nil if not found.
3680 (unless noerror (error "Not on BibTeX field"))))))
3681
3682 (defun bibtex-find-text-internal (&optional noerror subfield)
3683 "Find text part of current BibTeX field, @String or @Preamble.
3684 Return list (NAME START END) with field name, start and end of text
3685 or nil if not found.
3686 If optional arg NOERROR is non-nil, an error message is suppressed if text 3609 If optional arg NOERROR is non-nil, an error message is suppressed if text
3687 is not found. If optional arg SUBFIELD is non-nil START and END correspond 3610 is not found. If optional arg SUBFIELD is non-nil START-TEXT and END-TEXT
3688 to the current subfield delimited by #." 3611 correspond to the current subfield delimited by #.
3612 Optional 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.
3734 Align text and go thereafter to end of text." 3679 Align text and go thereafter to end of text. Optional arg COMMA
3735 (interactive) 3680 is 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")
3742 (delete-region (match-beginning 0) (match-end 0)) 3687 (delete-region (match-beginning 0) (match-end 0))
3743 ;; make field non-OPT 3688 ;; make field non-OPT
3749 (insert " ")) 3694 (insert " "))
3750 (search-forward "=") 3695 (search-forward "=")
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." 3703 Optional arg COMMA is as in `bibtex-enclosing-field'. It is t for
3759 (interactive) 3704 interactive 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) '(?\} ?\"))
3765 (delete-region (1- end) end)) 3710 (delete-region (1- end) end))
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.
3771 With prefix arg COPY-ONLY, copy the current field to `bibtex-field-kill-ring', 3716 With prefix arg COPY-ONLY, copy the current field to `bibtex-field-kill-ring',
3772 but do not actually kill it." 3717 but 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)
3781 (skip-chars-forward ",") 3726 (skip-chars-forward ",")
3782 (push (list (bibtex-name-in-field bounds) nil 3727 (push (list (bibtex-name-in-field bounds) nil
3789 (setq bibtex-field-kill-ring-yank-pointer bibtex-field-kill-ring) 3734 (setq bibtex-field-kill-ring-yank-pointer bibtex-field-kill-ring)
3790 (unless copy-only 3735 (unless copy-only
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) 3741 Optional arg COMMA is as in `bibtex-enclosing-field'. It is t for
3797 (bibtex-kill-field t)) 3742 interactive 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.
3801 With prefix arg COPY-ONLY, copy the current entry to `bibtex-entry-kill-ring', 3748 With prefix arg COPY-ONLY, copy the current entry to `bibtex-entry-kill-ring',
3802 but do not actually kill it." 3749 but do not actually kill it."
3804 (save-excursion 3751 (save-excursion
3805 (let* ((case-fold-search t) 3752 (let* ((case-fold-search t)
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)
3813 bibtex-entry-kill-ring) 3760 bibtex-entry-kill-ring)
3814 (if (> (length bibtex-entry-kill-ring) bibtex-entry-kill-ring-max) 3761 (if (> (length bibtex-entry-kill-ring) bibtex-entry-kill-ring-max)
3829 "Reinsert the last BibTeX item. 3776 "Reinsert the last BibTeX item.
3830 More precisely, reinsert the field or entry killed or yanked most recently. 3777 More precisely, reinsert the field or entry killed or yanked most recently.
3831 With argument N, reinsert the Nth most recently killed BibTeX item. 3778 With argument N, reinsert the Nth most recently killed BibTeX item.
3832 See also the command \\[bibtex-yank-pop]." 3779 See 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.
3839 This command is allowed only immediately after a `bibtex-yank' or a 3786 This 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
3841 previously killed BibTeX item. `bibtex-yank-pop' deletes that item 3788 previously killed BibTeX item. `bibtex-yank-pop' deletes that item
3842 and inserts in its place a different killed BibTeX item. 3789 and inserts in its place a different killed BibTeX item.
3843 3790
3844 With no argument, the previous kill is inserted. 3791 With no argument, the previous kill is inserted.
3845 With argument N, insert the Nth previous kill. 3792 With argument N, insert the Nth previous kill.
3851 (unless (eq last-command 'bibtex-yank) 3798 (unless (eq last-command 'bibtex-yank)
3852 (error "Previous command was not a BibTeX yank")) 3799 (error "Previous command was not a BibTeX yank"))
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) 3807 Optional arg COMMA is as in `bibtex-enclosing-field'. It is t for
3861 (bibtex-inside-field) 3808 interactive 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)
3866 (bibtex-field-right-delimiter)) 3814 (bibtex-field-right-delimiter))
3867 (bibtex-find-text t nil bibtex-help-message))) 3815 (bibtex-find-text t nil bibtex-help-message)))
3958 ;; Only update the list of keys if it has been built already. 3906 ;; Only update the list of keys if it has been built already.
3959 (cond ((eq entry-type 'string) 3907 (cond ((eq entry-type 'string)
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)
3967 (cond ((not (assoc key bibtex-reference-keys)) 3915 (cond ((not (assoc key bibtex-reference-keys))
3968 (push (cons key t) bibtex-reference-keys)) 3916 (push (cons key t) bibtex-reference-keys))
3986 (defun bibtex-fill-field-bounds (bounds justify &optional move) 3934 (defun bibtex-fill-field-bounds (bounds justify &optional move)
3987 "Fill BibTeX field delimited by BOUNDS. 3935 "Fill BibTeX field delimited by BOUNDS.
3988 If JUSTIFY is non-nil justify as well. 3936 If JUSTIFY is non-nil justify as well.
3989 If optional arg MOVE is non-nil move point to end of field." 3937 If 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))
4016 (if move (goto-char end-field)))) 3963 (if move (goto-char end-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.
4020 Optional prefix arg JUSTIFY non-nil means justify as well. 3967 If optional prefix JUSTIFY is non-nil justify as well.
4021 In BibTeX mode this function is bound to `fill-paragraph-function'." 3968 In 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.
4031 Realign entry, so that every field starts on a separate line. Field 3977 Realign entry, so that every field starts on a separate line. Field
4032 names appear in column `bibtex-field-indentation', field text starts in 3978 names appear in column `bibtex-field-indentation', field text starts in
4033 column `bibtex-text-indentation' and continuation lines start here, too. 3979 column `bibtex-text-indentation' and continuation lines start here, too.
4034 If `bibtex-align-at-equal-sign' is non-nil, align equal signs, too." 3980 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)
4049 (indent-to-column bibtex-entry-offset) 3997 (indent-to-column bibtex-entry-offset)
4050 (goto-char pnt))) 3998 (goto-char pnt)))
4113 (y-or-n-p "Generate new reference keys automatically? "))))) 4061 (y-or-n-p "Generate new reference keys automatically? ")))))
4114 (bibtex-sort-ignore-string-entries t) 4062 (bibtex-sort-ignore-string-entries t)
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)
4123 (bibtex-map-entries (lambda (key beg end) 4070 (bibtex-map-entries (lambda (key beg end)
4124 (bibtex-progress-message) 4071 (bibtex-progress-message)
4141 entries from minibuffer." 4088 entries from minibuffer."
4142 (interactive "*P") 4089 (interactive "*P")
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)
4155 (goto-char (point-max)) 4100 (goto-char (point-max))
4156 (message "Buffer is now parsable. Please save it."))) 4101 (message "Buffer is now parsable. Please save it.")))
4164 based on `bibtex-strings'. 4109 based on `bibtex-strings'.
4165 An error is signaled if point is outside key or BibTeX field." 4110 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)
4176 compl (cond ((bibtex-string= name "crossref") 4120 compl (cond ((bibtex-string= name "crossref")
4177 ;; point is in crossref field 4121 ;; point is in crossref field
4180 ;; point is in month field 4124 ;; point is in month field
4181 bibtex-predefined-month-strings) 4125 bibtex-predefined-month-strings)
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))))
4189 (setq compl 'string)) 4133 (setq compl 'string))
4190 ;; point is inside a @String field 4134 ;; point is inside a @String field
4191 ((and (>= pnt (bibtex-start-of-text-in-string bounds)) 4135 ((and (>= pnt (bibtex-start-of-text-in-string bounds))
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)
4203 (>= pnt (match-beginning bibtex-key-in-head)) 4146 (>= pnt (match-beginning bibtex-key-in-head))
4204 (<= pnt (match-end bibtex-key-in-head))) 4147 (<= pnt (match-end bibtex-key-in-head)))