aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2005-12-14 17:15:20 +0000
committerStefan Monnier2005-12-14 17:15:20 +0000
commitcdc61d3531f5e0e99e7548e50c532132991b6880 (patch)
tree42b0fe535c599e89e5114612984f3a7c5834fc91
parentd49e540c484c3f87be3d414abde99dd50ce37f45 (diff)
downloademacs-cdc61d3531f5e0e99e7548e50c532132991b6880.tar.gz
emacs-cdc61d3531f5e0e99e7548e50c532132991b6880.zip
(bibtex-expand-strings)
(bibtex-autokey-expand-string, bibtex-name-part) (bibtex-entry-type-whitespace, bibtex-entry-type-str) (bibtex-any-entry-maybe-empty-head, bibtex-string-type) (bibtex-preamble-prefix, bibtex-string-empty-key): New variables. (bibtex-entry-type, bibtex-entry-head): Match only valid entries. (bibtex-entry-postfix, bibtex-known-entry-type-re) (bibtex-valid-entry-re, bibtex-any-valid-entry-re) (bibtex-valid-entry-whitespace-re, bibtex-empty-field-re) (bibtex-field-name-for-parsing, bibtex-remove-delimiters-string) (bibtex-beginning-of-last-entry): Remove. (bibtex-parse-field-name): Use bibtex-field-name. Issue error message if comma is missing but buffer is read-only. (bibtex-parse-field-text): Handle whitespaces at the end of field text. Return 3-element list with beginning and end of field text and end of field. (bibtex-end-of-text-in-field, bibtex-end-of-field): Change accordingly. (bibtex-parse-field): Remove arg name. Use bibtex-field-name. (bibtex-search-forward-field, bibtex-search-backward-field): Search always delimited by limits of entry. Use more efficient search algorithms. (bibtex-name-in-field): Use bibtex-start-of-name-in-field and bibtex-end-of-name-in-field. (bibtex-text-in-field-bounds): Handle BibTeX strings when extracting the content of a field. (bibtex-text-in-field): Use search limits. (bibtex-parse-string-prefix): Handle empty string keys based on bibtex-string-empty-key. (bibtex-parse-string): Fix docstring. (bibtex-text-in-string): Use bibtex-text-in-field-bounds. (bibtex-preamble-prefix, bibtex-strings): New functions. (bibtex-skip-to-valid-entry): Include preceding whitespace in BibTeX entries (consistent with other BibTeX functions). (bibtex-map-entries): Use bibtex-skip-to-valid-entry. (bibtex-search-entry): Fix docstring. Simplify. (bibtex-flash-head, bibtex-complete-string-cleanup) (bibtex-count-entries, bibtex-sort-buffer): Simplify. (bibtex-beginning-of-first-entry): Use bibtex-skip-to-valid-entry. (bibtex-parse-entry): New optional arg content. (bibtex-format-entry, bibtex-autofill-entry, bibtex-url): Use it. Use bibtex-text-in-field-bounds. (bibtex-print-help-message): Handle BibTeX strings and preambles. (bibtex-end-of-entry): Use bibtex-preamble-prefix and bibtex-parse-string-postfix. (bibtex-find-text-internal): New function. (bibtex-remove-delimiters): Use it. (bibtex-find-text): Use it. New optional arg help. (bibtex-complete): Handle BibTeX string and preamble entries. (bibtex-Preamble): Fix order of closing delimiters.
-rw-r--r--etc/NEWS4
-rw-r--r--lisp/ChangeLog58
-rw-r--r--lisp/textmodes/bibtex.el831
3 files changed, 506 insertions, 387 deletions
diff --git a/etc/NEWS b/etc/NEWS
index 69be423eff6..010a6c43abf 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -2539,6 +2539,10 @@ in multiple BibTeX files.
2539*** The new command `bibtex-copy-summary-as-kill' pushes summary 2539*** The new command `bibtex-copy-summary-as-kill' pushes summary
2540of BibTeX entry to kill ring (bound to C-c C-t). 2540of BibTeX entry to kill ring (bound to C-c C-t).
2541 2541
2542*** The new variables bibtex-expand-strings and
2543bibtex-autokey-expand-strings control the expansion of strings when
2544extracting the content of a BibTeX field.
2545
2542+++ 2546+++
2543** In Enriched mode, `set-left-margin' and `set-right-margin' are now 2547** In Enriched mode, `set-left-margin' and `set-right-margin' are now
2544by default bound to `C-c [' and `C-c ]' instead of the former `C-c C-l' 2548by default bound to `C-c [' and `C-c ]' instead of the former `C-c C-l'
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index b9db971e623..9a71565c2b3 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,61 @@
12005-12-14 Roland Winkler <Roland.Winkler@physik.uni-erlangen.de>
2
3 * textmodes/bibtex.el (bibtex-expand-strings)
4 (bibtex-autokey-expand-string, bibtex-name-part)
5 (bibtex-entry-type-whitespace, bibtex-entry-type-str)
6 (bibtex-any-entry-maybe-empty-head, bibtex-string-type)
7 (bibtex-preamble-prefix, bibtex-string-empty-key): New variables.
8 (bibtex-entry-type, bibtex-entry-head): Match only valid entries.
9 (bibtex-entry-postfix, bibtex-known-entry-type-re)
10 (bibtex-valid-entry-re, bibtex-any-valid-entry-re)
11 (bibtex-valid-entry-whitespace-re, bibtex-empty-field-re)
12 (bibtex-field-name-for-parsing, bibtex-remove-delimiters-string)
13 (bibtex-beginning-of-last-entry): Remove.
14 (bibtex-parse-field-name): Use bibtex-field-name. Issue error
15 message if comma is missing but buffer is read-only.
16 (bibtex-parse-field-text): Handle whitespaces at the end of field
17 text. Return 3-element list with beginning and end of field text
18 and end of field.
19 (bibtex-end-of-text-in-field, bibtex-end-of-field): Change accordingly.
20 (bibtex-parse-field): Remove arg name. Use bibtex-field-name.
21 (bibtex-search-forward-field, bibtex-search-backward-field):
22 Search always delimited by limits of entry. Use more efficient
23 search algorithms.
24 (bibtex-name-in-field): Use bibtex-start-of-name-in-field and
25 bibtex-end-of-name-in-field.
26 (bibtex-text-in-field-bounds): Handle BibTeX strings when
27 extracting the content of a field.
28 (bibtex-text-in-field): Use search limits.
29 (bibtex-parse-string-prefix): Handle empty string keys based on
30 bibtex-string-empty-key.
31 (bibtex-parse-string): Fix docstring.
32 (bibtex-text-in-string): Use bibtex-text-in-field-bounds.
33 (bibtex-preamble-prefix, bibtex-strings): New functions.
34 (bibtex-skip-to-valid-entry): Include preceding whitespace in
35 BibTeX entries (consistent with other BibTeX functions).
36 (bibtex-map-entries): Use bibtex-skip-to-valid-entry.
37 (bibtex-search-entry): Fix docstring. Simplify.
38 (bibtex-flash-head, bibtex-complete-string-cleanup)
39 (bibtex-count-entries, bibtex-sort-buffer): Simplify.
40 (bibtex-beginning-of-first-entry): Use bibtex-skip-to-valid-entry.
41 (bibtex-parse-entry): New optional arg content.
42 (bibtex-format-entry, bibtex-autofill-entry, bibtex-url): Use it.
43 Use bibtex-text-in-field-bounds.
44 (bibtex-print-help-message): Handle BibTeX strings and preambles.
45 (bibtex-end-of-entry): Use bibtex-preamble-prefix and
46 bibtex-parse-string-postfix.
47 (bibtex-find-text-internal): New function.
48 (bibtex-remove-delimiters): Use it.
49 (bibtex-find-text): Use it. New optional arg help.
50 (bibtex-complete): Handle BibTeX string and preamble entries.
51 (bibtex-Preamble): Fix order of closing delimiters.
52
532005-12-14 Stefan Monnier <monnier@iro.umontreal.ca>
54
55 * vc.el (vc-default-revert): New fun.
56
57 * vc-mcvs.el (vc-mcvs-revert): Fix call to vc-default-revert.
58
12005-12-14 Romain Francoise <romain@orebokech.com> 592005-12-14 Romain Francoise <romain@orebokech.com>
2 60
3 * font-lock.el (font-lock-keywords-alist): Rename `append' to `how'. 61 * font-lock.el (font-lock-keywords-alist): Rename `append' to `how'.
diff --git a/lisp/textmodes/bibtex.el b/lisp/textmodes/bibtex.el
index 7b736708268..82c79ae2569 100644
--- a/lisp/textmodes/bibtex.el
+++ b/lisp/textmodes/bibtex.el
@@ -551,6 +551,12 @@ See `bibtex-generate-autokey' for details."
551 :group 'bibtex-autokey 551 :group 'bibtex-autokey
552 :type 'string) 552 :type 'string)
553 553
554(defcustom bibtex-autokey-expand-strings nil
555 "If non-nil, expand strings when extracting the content of a BibTeX field.
556See `bibtex-generate-autokey' for details."
557 :group 'bibtex-autokey
558 :type 'boolean)
559
554(defvar bibtex-autokey-transcriptions 560(defvar bibtex-autokey-transcriptions
555 '(;; language specific characters 561 '(;; language specific characters
556 ("\\\\aa" . "a") ; \aa -> a 562 ("\\\\aa" . "a") ; \aa -> a
@@ -809,6 +815,8 @@ submatch), or a function called with the field's text as argument
809and with the `match-data' properly set. 815and with the `match-data' properly set.
810 816
811Case is always ignored. Always remove the field delimiters. 817Case is always ignored. Always remove the field delimiters.
818If `bibtex-expand-strings' is non-nil, BibTeX strings are expanded
819for generating the URL.
812 820
813The following is a complex example, see http://link.aps.org/linkfaq.html. 821The following is a complex example, see http://link.aps.org/linkfaq.html.
814 822
@@ -840,12 +848,17 @@ The following is a complex example, see http://link.aps.org/linkfaq.html.
840 (integer :tag "Sub-match") 848 (integer :tag "Sub-match")
841 (function :tag "Filter")))))))) 849 (function :tag "Filter"))))))))
842 850
843;; bibtex-font-lock-keywords is a user option as well, but since the 851(defcustom bibtex-expand-strings nil
852 "If non-nil, expand strings when extracting the content of a BibTeX field."
853 :group 'bibtex
854 :type 'boolean)
855
856;; `bibtex-font-lock-keywords' is a user option as well, but since the
844;; patterns used to define this variable are defined in a later 857;; patterns used to define this variable are defined in a later
845;; section of this file, it is defined later. 858;; section of this file, it is defined later.
846 859
847 860
848;; Syntax Table, Keybindings and BibTeX Entry List 861;; Syntax Table and Keybindings
849(defvar bibtex-mode-syntax-table 862(defvar bibtex-mode-syntax-table
850 (let ((st (make-syntax-table))) 863 (let ((st (make-syntax-table)))
851 (modify-syntax-entry ?\" "\"" st) 864 (modify-syntax-entry ?\" "\"" st)
@@ -1073,10 +1086,11 @@ The CDRs of the elements are t for header keys and nil for crossref keys.")
1073 "Last reformat reference keys option given.") 1086 "Last reformat reference keys option given.")
1074 1087
1075(defconst bibtex-field-name "[^\"#%'(),={} \t\n0-9][^\"#%'(),={} \t\n]*" 1088(defconst bibtex-field-name "[^\"#%'(),={} \t\n0-9][^\"#%'(),={} \t\n]*"
1076 "Regexp matching the name part of a BibTeX field.") 1089 "Regexp matching the name of a BibTeX field.")
1077 1090
1078(defconst bibtex-entry-type (concat "@" bibtex-field-name) 1091(defconst bibtex-name-part
1079 "Regexp matching the type part of a BibTeX entry.") 1092 (concat ",[ \t\n]*\\(" bibtex-field-name "\\)[ \t\n]*=")
1093 "Regexp matching the name part of a BibTeX field.")
1080 1094
1081(defconst bibtex-reference-key "[][[:alnum:].:;?!`'/*@+|()<>&_^$-]+" 1095(defconst bibtex-reference-key "[][[:alnum:].:;?!`'/*@+|()<>&_^$-]+"
1082 "Regexp matching the reference key part of a BibTeX entry.") 1096 "Regexp matching the reference key part of a BibTeX entry.")
@@ -1084,54 +1098,56 @@ The CDRs of the elements are t for header keys and nil for crossref keys.")
1084(defconst bibtex-field-const "[][[:alnum:].:;?!`'/*@+=|<>&_^$-]+" 1098(defconst bibtex-field-const "[][[:alnum:].:;?!`'/*@+=|<>&_^$-]+"
1085 "Regexp matching a BibTeX field constant.") 1099 "Regexp matching a BibTeX field constant.")
1086 1100
1087(defconst bibtex-entry-head 1101(defvar bibtex-entry-type
1102 (concat "@[ \t]*\\(?:"
1103 (regexp-opt (mapcar 'car bibtex-entry-field-alist)) "\\)")
1104 "Regexp matching the name of a BibTeX entry.")
1105
1106(defvar bibtex-entry-type-whitespace
1107 (concat "[ \t]*" bibtex-entry-type)
1108 "Regexp matching the name of a BibTeX entry preceded by whitespace.")
1109
1110(defvar bibtex-entry-type-str
1111 (concat "@[ \t]*\\(?:"
1112 (regexp-opt (append '("String")
1113 (mapcar 'car bibtex-entry-field-alist))) "\\)")
1114 "Regexp matching the name of a BibTeX entry (including @String).")
1115
1116(defvar bibtex-entry-head
1088 (concat "^[ \t]*\\(" 1117 (concat "^[ \t]*\\("
1089 bibtex-entry-type 1118 bibtex-entry-type
1090 "\\)[ \t]*[({][ \t\n]*\\(" 1119 "\\)[ \t]*[({][ \t\n]*\\("
1091 bibtex-reference-key 1120 bibtex-reference-key
1092 "\\)") 1121 "\\)")
1093 "Regexp matching the header line of a BibTeX entry.") 1122 "Regexp matching the header line of a BibTeX entry (including key).")
1094 1123
1095(defconst bibtex-entry-maybe-empty-head 1124(defvar bibtex-entry-maybe-empty-head
1096 (concat bibtex-entry-head "?") 1125 (concat bibtex-entry-head "?")
1097 "Regexp matching the header line of a BibTeX entry (possibly without key).") 1126 "Regexp matching the header line of a BibTeX entry (possibly without key).")
1098 1127
1128(defconst bibtex-any-entry-maybe-empty-head
1129 (concat "^[ \t]*\\(@[ \t]*" bibtex-field-name "\\)[ \t]*[({][ \t\n]*\\("
1130 bibtex-reference-key "\\)?")
1131 "Regexp matching the header line of any BibTeX entry (possibly without key).")
1132
1099(defconst bibtex-type-in-head 1 1133(defconst bibtex-type-in-head 1
1100 "Regexp subexpression number of the type part in `bibtex-entry-head'.") 1134 "Regexp subexpression number of the type part in `bibtex-entry-head'.")
1101 1135
1102(defconst bibtex-key-in-head 2 1136(defconst bibtex-key-in-head 2
1103 "Regexp subexpression number of the key part in `bibtex-entry-head'.") 1137 "Regexp subexpression number of the key part in `bibtex-entry-head'.")
1104 1138
1105(defconst bibtex-string-maybe-empty-head 1139(defconst bibtex-empty-field-re "\\`\\(\"\"\\|{}\\)\\'"
1106 (concat "^[ \t]*\\(@String\\)[ \t]*[({]\\(" 1140 "Regexp matching the text part (as a string) of an empty field.")
1107 bibtex-reference-key
1108 "\\)?")
1109 "Regexp matching the header line of a BibTeX String entry.")
1110
1111(defconst bibtex-entry-postfix "[ \t\n]*,?[ \t\n]*[})]"
1112 "Regexp matching the postfix of a BibTeX entry.")
1113
1114(defvar bibtex-known-entry-type-re
1115 (regexp-opt (mapcar 'car bibtex-entry-field-alist))
1116 "Regexp matching the name of a BibTeX entry.")
1117
1118(defvar bibtex-valid-entry-re
1119 (concat "@[ \t]*\\(" bibtex-known-entry-type-re "\\)")
1120 "Regexp matching the name of a valid BibTeX entry.")
1121 1141
1122(defvar bibtex-valid-entry-whitespace-re 1142(defconst bibtex-string-type "^[ \t]*\\(@[ \t]*String\\)[ \t]*[({][ \t\n]*"
1123 (concat "[ \t]*\\(" bibtex-valid-entry-re "\\)") 1143 "Regexp matching the name of a BibTeX String entry.")
1124 "Regexp matching the name of a valid BibTeX entry preceded by whitespace.")
1125 1144
1126(defvar bibtex-any-valid-entry-re 1145(defconst bibtex-string-maybe-empty-head
1127 (concat "@[ \t]*" 1146 (concat bibtex-string-type "\\(" bibtex-reference-key "\\)?")
1128 (regexp-opt (append '("String") 1147 "Regexp matching the header line of a BibTeX String entry.")
1129 (mapcar 'car bibtex-entry-field-alist))
1130 t))
1131 "Regexp matching the name of any valid BibTeX entry (including string).")
1132 1148
1133(defconst bibtex-empty-field-re "\\`\\(\"\"\\|{}\\)\\'" 1149(defconst bibtex-preamble-prefix "[ \t]*@[ \t]*Preamble[ \t]*"
1134 "Regexp matching the text part (as a string) of an empty field.") 1150 "Regexp matching the prefix part of a preamble.")
1135 1151
1136(defconst bibtex-font-lock-syntactic-keywords 1152(defconst bibtex-font-lock-syntactic-keywords
1137 `((,(concat "^[ \t]*\\(" (substring bibtex-comment-start 0 1) "\\)" 1153 `((,(concat "^[ \t]*\\(" (substring bibtex-comment-start 0 1) "\\)"
@@ -1140,7 +1156,7 @@ The CDRs of the elements are t for header keys and nil for crossref keys.")
1140 1156
1141(defvar bibtex-font-lock-keywords 1157(defvar bibtex-font-lock-keywords
1142 ;; entry type and reference key 1158 ;; entry type and reference key
1143 `((,bibtex-entry-maybe-empty-head 1159 `((,bibtex-any-entry-maybe-empty-head
1144 (,bibtex-type-in-head font-lock-function-name-face) 1160 (,bibtex-type-in-head font-lock-function-name-face)
1145 (,bibtex-key-in-head font-lock-constant-face nil t)) 1161 (,bibtex-key-in-head font-lock-constant-face nil t))
1146 ;; optional field names (treated as comments) 1162 ;; optional field names (treated as comments)
@@ -1160,9 +1176,8 @@ The CDRs of the elements are t for header keys and nil for crossref keys.")
1160 "[ \t]*=[ \t]*") 1176 "[ \t]*=[ \t]*")
1161 "Regexp for `bibtex-font-lock-url'.") 1177 "Regexp for `bibtex-font-lock-url'.")
1162 1178
1163(defvar bibtex-field-name-for-parsing nil 1179(defvar bibtex-string-empty-key nil
1164 "Regexp of field name to be parsed by function `bibtex-parse-field-name'. 1180 "If non-nil, `bibtex-parse-string' accepts empty key.")
1165Passed by dynamic scoping.")
1166 1181
1167(defvar bibtex-sort-entry-class-alist 1182(defvar bibtex-sort-entry-class-alist
1168 (let ((i -1) alist) 1183 (let ((i -1) alist)
@@ -1193,8 +1208,8 @@ ARG is ignored."
1193 "Parse a string of the format <left-hand-side = right-hand-side>. 1208 "Parse a string of the format <left-hand-side = right-hand-side>.
1194The functions PARSE-LHS and PARSE-RHS are used to parse the corresponding 1209The functions PARSE-LHS and PARSE-RHS are used to parse the corresponding
1195substrings. These functions are expected to return nil if parsing is not 1210substrings. These functions are expected to return nil if parsing is not
1196successful. If both functions return non-nil, a pair containing the returned 1211successful. If the returned values of both functions are non-nil,
1197values of the functions PARSE-LHS and PARSE-RHS is returned." 1212return a cons pair of these values. Do not move point."
1198 (save-match-data 1213 (save-match-data
1199 (save-excursion 1214 (save-excursion
1200 (let ((left (funcall parse-lhs)) 1215 (let ((left (funcall parse-lhs))
@@ -1206,7 +1221,7 @@ values of the functions PARSE-LHS and PARSE-RHS is returned."
1206 (cons left right)))))) 1221 (cons left right))))))
1207 1222
1208(defun bibtex-parse-field-name () 1223(defun bibtex-parse-field-name ()
1209 "Parse the field name stored in `bibtex-field-name-for-parsing'. 1224 "Parse the name part of a BibTeX field.
1210If the field name is found, return a triple consisting of the position of the 1225If the field name is found, return a triple consisting of the position of the
1211very first character of the match, the actual starting position of the name 1226very first character of the match, the actual starting position of the name
1212part and end position of the match. Move point to end of field name. 1227part and end position of the match. Move point to end of field name.
@@ -1215,14 +1230,18 @@ BibTeX field as necessary."
1215 (cond ((looking-at ",[ \t\n]*") 1230 (cond ((looking-at ",[ \t\n]*")
1216 (let ((start (point))) 1231 (let ((start (point)))
1217 (goto-char (match-end 0)) 1232 (goto-char (match-end 0))
1218 (when (looking-at bibtex-field-name-for-parsing) 1233 (when (looking-at bibtex-field-name)
1219 (goto-char (match-end 0)) 1234 (goto-char (match-end 0))
1220 (list start (match-beginning 0) (match-end 0))))) 1235 (list start (match-beginning 0) (match-end 0)))))
1221 ;; Maybe add a missing comma. 1236 ;; Maybe add a missing comma.
1222 ((and bibtex-autoadd-commas 1237 ((and bibtex-autoadd-commas
1223 (looking-at (concat "[ \t\n]*\\(?:" bibtex-field-name-for-parsing 1238 (looking-at (concat "[ \t\n]*\\(?:" bibtex-field-name
1224 "\\)[ \t\n]*="))) 1239 "\\)[ \t\n]*=")))
1225 (skip-chars-backward " \t\n") 1240 (skip-chars-backward " \t\n")
1241 ;; It can be confusing if non-editing commands try to
1242 ;; modify the buffer.
1243 (if buffer-read-only
1244 (error "Comma missing at buffer position %s" (point)))
1226 (insert ",") 1245 (insert ",")
1227 (forward-char -1) 1246 (forward-char -1)
1228 ;; Now try again. 1247 ;; Now try again.
@@ -1251,7 +1270,8 @@ BibTeX field as necessary."
1251(defun bibtex-parse-field-string () 1270(defun bibtex-parse-field-string ()
1252 "Parse a BibTeX field string enclosed by braces or quotes. 1271 "Parse a BibTeX field string enclosed by braces or quotes.
1253If a syntactically correct string is found, a pair containing the start and 1272If a syntactically correct string is found, a pair containing the start and
1254end position of the field string is returned, nil otherwise." 1273end position of the field string is returned, nil otherwise.
1274Do not move point."
1255 (let ((end-point 1275 (let ((end-point
1256 (or (and (eq (following-char) ?\") 1276 (or (and (eq (following-char) ?\")
1257 (save-excursion 1277 (save-excursion
@@ -1283,101 +1303,129 @@ returned, nil otherwise. Move point to end of field text."
1283 (if (looking-at "[ \t\n]*#[ \t\n]*") 1303 (if (looking-at "[ \t\n]*#[ \t\n]*")
1284 (goto-char (match-end 0)) 1304 (goto-char (match-end 0))
1285 (setq end-point (point)))) 1305 (setq end-point (point))))
1306 (skip-chars-forward " \t\n")
1286 (if (and (not failure) 1307 (if (and (not failure)
1287 end-point) 1308 end-point)
1288 (cons starting-point end-point)))) 1309 (list starting-point end-point (point)))))
1310
1311(defun bibtex-parse-field ()
1312 "Parse the BibTeX field beginning at the position of point.
1313If a syntactically correct field is found, return a cons pair containing
1314the boundaries of the name and text parts of the field. Do not move point."
1315 (bibtex-parse-association 'bibtex-parse-field-name
1316 'bibtex-parse-field-text))
1289 1317
1290(defun bibtex-parse-field (name) 1318(defsubst bibtex-start-of-field (bounds)
1291 "Parse a BibTeX field of regexp NAME. 1319 (nth 0 (car bounds)))
1292If a syntactically correct field is found, a pair containing the boundaries of 1320(defsubst bibtex-start-of-name-in-field (bounds)
1293the name and text parts of the field is returned." 1321 (nth 1 (car bounds)))
1294 (let ((bibtex-field-name-for-parsing name)) 1322(defsubst bibtex-end-of-name-in-field (bounds)
1295 (bibtex-parse-association 'bibtex-parse-field-name 1323 (nth 2 (car bounds)))
1296 'bibtex-parse-field-text))) 1324(defsubst bibtex-start-of-text-in-field (bounds)
1325 (nth 1 bounds))
1326(defsubst bibtex-end-of-text-in-field (bounds)
1327 (nth 2 bounds))
1328(defsubst bibtex-end-of-field (bounds)
1329 (nth 3 bounds))
1297 1330
1298(defun bibtex-search-forward-field (name &optional bound) 1331(defun bibtex-search-forward-field (name &optional bound)
1299 "Search forward to find a BibTeX field of name NAME. 1332 "Search forward to find a BibTeX field of name NAME.
1300If a syntactically correct field is found, a pair containing the boundaries of 1333If a syntactically correct field is found, return a pair containing
1301the name and text parts of the field is returned. The search is limited by 1334the boundaries of the name and text parts of the field. The search
1302optional arg BOUND. If BOUND is t the search is limited by the end of the 1335is limited by optional arg BOUND or if nil by the end of the current
1303current entry. Do not move point." 1336entry. Do not move point."
1304 (save-match-data 1337 (save-match-data
1305 (save-excursion 1338 (save-excursion
1306 (unless (integer-or-marker-p bound) 1339 (if bound
1307 (setq bound (if bound 1340 ;; If the search is bounded we need not worry we could overshoot.
1308 (save-excursion (bibtex-end-of-entry)) 1341 ;; This is indeed the case when `bibtex-search-forward-field' is
1309 (point-max)))) 1342 ;; called many times. So we optimize this part of this function.
1310 (let ((case-fold-search t) 1343 (let ((name-part (concat ",[ \t\n]*\\(" name "\\)[ \t\n]*=[ \t\n]*"))
1311 (bibtex-field-name-for-parsing name) 1344 (case-fold-search t) left right)
1312 boundaries temp-boundaries) 1345 (while (and (not right)
1313 (while (and (not boundaries) 1346 (re-search-forward name-part bound t))
1314 (< (point) bound) 1347 (setq left (list (match-beginning 0) (match-beginning 1)
1315 (search-forward "," bound t)) 1348 (match-end 1))
1316 (goto-char (match-beginning 0)) 1349 ;; Don't worry that the field text could be past bound.
1317 (if (and (setq temp-boundaries 1350 right (bibtex-parse-field-text)))
1318 (bibtex-parse-association 'bibtex-parse-field-name 1351 (if right (cons left right)))
1319 'bibtex-parse-field-text)) 1352 (let ((regexp (concat bibtex-name-part "\\|"
1320 (<= (cddr temp-boundaries) bound)) 1353 bibtex-any-entry-maybe-empty-head))
1321 (setq boundaries temp-boundaries) 1354 (case-fold-search t) bounds)
1322 (forward-char 1))) 1355 (catch 'done
1323 boundaries)))) 1356 (if (looking-at "[ \t]*@") (goto-char (match-end 0)))
1357 (while (and (not bounds)
1358 (re-search-forward regexp nil t))
1359 (if (match-beginning 2)
1360 ;; We found a new entry
1361 (throw 'done nil)
1362 ;; We found a field
1363 (goto-char (match-beginning 0))
1364 (setq bounds (bibtex-parse-field))))
1365 ;; Step through all fields so that we cannot overshoot.
1366 (while bounds
1367 (goto-char (bibtex-start-of-name-in-field bounds))
1368 (if (looking-at name) (throw 'done bounds))
1369 (goto-char (bibtex-end-of-field bounds))
1370 (setq bounds (bibtex-parse-field)))))))))
1324 1371
1325(defun bibtex-search-backward-field (name &optional bound) 1372(defun bibtex-search-backward-field (name &optional bound)
1326 "Search backward to find a BibTeX field of name NAME. 1373 "Search backward to find a BibTeX field of name NAME.
1327If a syntactically correct field is found, a pair containing the boundaries of 1374If a syntactically correct field is found, return a pair containing
1328the name and text parts of the field is returned. The search is limited by 1375the boundaries of the name and text parts of the field. The search
1329optional arg BOUND. If BOUND is t the search is limited by the beginning of the 1376is limited by the optional arg BOUND. If BOUND is nil the search is
1330current entry. Do not move point." 1377limited by the beginning of the current entry. Do not move point."
1331 (save-match-data 1378 (save-match-data
1332 (save-excursion 1379 (save-excursion
1333 (unless (integer-or-marker-p bound) 1380 (let ((name-part (concat ",[ \t\n]*\\(?:" name "\\)[ \t\n]*="))
1334 (setq bound (if bound 1381 (case-fold-search t)
1335 (save-excursion (bibtex-beginning-of-entry)) 1382 bounds)
1336 (point-min)))) 1383 (unless bound (setq bound (save-excursion (bibtex-beginning-of-entry))))
1337 (let ((case-fold-search t) 1384 (while (and (not bounds)
1338 (bibtex-field-name-for-parsing name) 1385 (search-backward "," bound t)
1339 boundaries temp-boundaries) 1386 (looking-at name-part))
1340 (while (and (not boundaries) 1387 (setq bounds (bibtex-parse-field)))
1341 (>= (point) bound) 1388 bounds))))
1342 (search-backward "," bound t))
1343 (if (setq temp-boundaries
1344 (bibtex-parse-association 'bibtex-parse-field-name
1345 'bibtex-parse-field-text))
1346 (setq boundaries temp-boundaries)))
1347 boundaries))))
1348
1349(defsubst bibtex-start-of-field (bounds)
1350 (nth 0 (car bounds)))
1351(defsubst bibtex-start-of-name-in-field (bounds)
1352 (nth 1 (car bounds)))
1353(defsubst bibtex-end-of-name-in-field (bounds)
1354 (nth 2 (car bounds)))
1355(defsubst bibtex-end-of-field (bounds)
1356 (cddr bounds))
1357(defsubst bibtex-start-of-text-in-field (bounds)
1358 (cadr bounds))
1359(defsubst bibtex-end-of-text-in-field (bounds)
1360 (cddr bounds))
1361 1389
1362(defun bibtex-name-in-field (bounds &optional remove-opt-alt) 1390(defun bibtex-name-in-field (bounds &optional remove-opt-alt)
1363 "Get content of name in BibTeX field defined via BOUNDS. 1391 "Get content of name in BibTeX field defined via BOUNDS.
1364If optional arg REMOVE-OPT-ALT is non-nil remove \"OPT\" and \"ALT\"." 1392If optional arg REMOVE-OPT-ALT is non-nil remove \"OPT\" and \"ALT\"."
1365 (let ((name (buffer-substring-no-properties (nth 1 (car bounds)) 1393 (let ((name (buffer-substring-no-properties
1366 (nth 2 (car bounds))))) 1394 (bibtex-start-of-name-in-field bounds)
1395 (bibtex-end-of-name-in-field bounds))))
1367 (if (and remove-opt-alt 1396 (if (and remove-opt-alt
1368 (string-match "\\`\\(OPT\\|ALT\\)" name)) 1397 (string-match "\\`\\(OPT\\|ALT\\)" name))
1369 (substring name 3) 1398 (substring name 3)
1370 name))) 1399 name)))
1371 1400
1372(defun bibtex-text-in-field-bounds (bounds &optional remove-delim) 1401(defun bibtex-text-in-field-bounds (bounds &optional content)
1373 "Get content of text in BibTeX field defined via BOUNDS. 1402 "Get text in BibTeX field defined via BOUNDS.
1374If optional arg REMOVE-DELIM is non-nil remove enclosing field delimiters 1403If optional arg CONTENT is non-nil extract content of field
1375if present." 1404by removing field delimiters and concatenating the resulting string.
1376 (let ((content (buffer-substring-no-properties (cadr bounds) 1405If `bibtex-expand-strings' is non-nil, also expand BibTeX strings."
1377 (cddr bounds)))) 1406 (if content
1378 (if remove-delim 1407 (save-excursion
1379 (bibtex-remove-delimiters-string content) 1408 (let ((epoint (bibtex-end-of-text-in-field bounds))
1380 content))) 1409 content opoint temp)
1410 (goto-char (bibtex-start-of-text-in-field bounds))
1411 (while (< (setq opoint (point)) epoint)
1412 (cond ((looking-at bibtex-field-const)
1413 (let ((mtch (match-string-no-properties 0)))
1414 (goto-char (match-end 0))
1415 (setq temp (if bibtex-expand-strings
1416 (cdr (assoc-string mtch (bibtex-strings) t)))
1417 content (concat content (or temp mtch)))))
1418
1419 ((setq temp (bibtex-parse-field-string))
1420 (setq content (concat content (buffer-substring-no-properties
1421 (1+ (car temp))
1422 (1- (cdr temp)))))
1423 (goto-char (cdr temp)))
1424 (t (error "Malformed text field")))
1425 (re-search-forward "\\=[ \t\n]*#[ \t\n]*" nil t))
1426 content))
1427 (buffer-substring-no-properties (bibtex-start-of-text-in-field bounds)
1428 (bibtex-end-of-text-in-field bounds))))
1381 1429
1382(defun bibtex-text-in-field (field &optional follow-crossref) 1430(defun bibtex-text-in-field (field &optional follow-crossref)
1383 "Get content of field FIELD of current BibTeX entry. 1431 "Get content of field FIELD of current BibTeX entry.
@@ -1388,13 +1436,13 @@ If optional arg FOLLOW-CROSSREF is non-nil, follow crossref."
1388 ;; We want to jump back and forth while searching FIELD 1436 ;; We want to jump back and forth while searching FIELD
1389 (bibtex-narrow-to-entry) 1437 (bibtex-narrow-to-entry)
1390 (goto-char (point-min)) 1438 (goto-char (point-min))
1391 (let ((bounds (bibtex-search-forward-field field)) 1439 (let ((bounds (bibtex-search-forward-field field (point-max)))
1392 crossref-field) 1440 crossref-field)
1393 (cond (bounds (bibtex-text-in-field-bounds bounds t)) 1441 (cond (bounds (bibtex-text-in-field-bounds bounds t))
1394 ((and follow-crossref 1442 ((and follow-crossref
1395 (progn (goto-char (point-min)) 1443 (progn (goto-char (point-min))
1396 (setq bounds (bibtex-search-forward-field 1444 (setq bounds (bibtex-search-forward-field
1397 "\\(OPT\\)?crossref")))) 1445 "\\(OPT\\)?crossref" (point-max)))))
1398 (setq crossref-field (bibtex-text-in-field-bounds bounds t)) 1446 (setq crossref-field (bibtex-text-in-field-bounds bounds t))
1399 (widen) 1447 (widen)
1400 (if (bibtex-find-crossref crossref-field) 1448 (if (bibtex-find-crossref crossref-field)
@@ -1406,16 +1454,21 @@ If optional arg FOLLOW-CROSSREF is non-nil, follow crossref."
1406 "Parse the prefix part of a BibTeX string entry, including reference key. 1454 "Parse the prefix part of a BibTeX string entry, including reference key.
1407If the string prefix is found, return a triple consisting of the position of 1455If the string prefix is found, return a triple consisting of the position of
1408the very first character of the match, the actual starting position of the 1456the very first character of the match, the actual starting position of the
1409reference key and the end position of the match." 1457reference key and the end position of the match.
1458If `bibtex-string-empty-key' is non-nil accept empty string key."
1410 (let ((case-fold-search t)) 1459 (let ((case-fold-search t))
1411 (if (looking-at "^[ \t]*@string[ \t\n]*[({][ \t\n]*") 1460 (if (looking-at bibtex-string-type)
1412 (let ((start (point))) 1461 (let ((start (point)))
1413 (goto-char (match-end 0)) 1462 (goto-char (match-end 0))
1414 (when (looking-at bibtex-reference-key) 1463 (cond ((looking-at bibtex-reference-key)
1415 (goto-char (match-end 0)) 1464 (goto-char (match-end 0))
1416 (list start 1465 (list start
1417 (match-beginning 0) 1466 (match-beginning 0)
1418 (match-end 0))))))) 1467 (match-end 0)))
1468 ((and bibtex-string-empty-key
1469 (looking-at "="))
1470 (skip-chars-backward " \t\n")
1471 (list start (point) (point))))))))
1419 1472
1420(defun bibtex-parse-string-postfix () 1473(defun bibtex-parse-string-postfix ()
1421 "Parse the postfix part of a BibTeX string entry, including the text. 1474 "Parse the postfix part of a BibTeX string entry, including the text.
@@ -1425,18 +1478,18 @@ character of the string entry. Move point past BibTeX string entry."
1425 (let* ((case-fold-search t) 1478 (let* ((case-fold-search t)
1426 (bounds (bibtex-parse-field-text))) 1479 (bounds (bibtex-parse-field-text)))
1427 (when bounds 1480 (when bounds
1428 (goto-char (cdr bounds)) 1481 (goto-char (nth 1 bounds))
1429 (when (looking-at "[ \t\n]*[})]") 1482 (when (looking-at "[ \t\n]*[})]")
1430 (goto-char (match-end 0)) 1483 (goto-char (match-end 0))
1431 (list (car bounds) 1484 (list (car bounds)
1432 (cdr bounds) 1485 (nth 1 bounds)
1433 (match-end 0)))))) 1486 (match-end 0))))))
1434 1487
1435(defun bibtex-parse-string () 1488(defun bibtex-parse-string ()
1436 "Parse a BibTeX string entry. 1489 "Parse a BibTeX string entry beginning at the position of point.
1437If a syntactically correct entry is found, a pair containing the boundaries of 1490If a syntactically correct entry is found, return a cons pair containing
1438the reference key and text parts of the entry is returned. 1491the boundaries of the reference key and text parts of the entry.
1439Move point past BibTeX string entry." 1492Do not move point."
1440 (bibtex-parse-association 'bibtex-parse-string-prefix 1493 (bibtex-parse-association 'bibtex-parse-string-prefix
1441 'bibtex-parse-string-postfix)) 1494 'bibtex-parse-string-postfix))
1442 1495
@@ -1449,8 +1502,7 @@ the reference key and text parts of the string is returned. Do not move point."
1449 (let ((case-fold-search t) 1502 (let ((case-fold-search t)
1450 boundaries) 1503 boundaries)
1451 (while (and (not boundaries) 1504 (while (and (not boundaries)
1452 (search-forward-regexp 1505 (search-forward-regexp bibtex-string-type nil t))
1453 "^[ \t]*@string[ \t\n]*[({][ \t\n]*" nil t))
1454 (goto-char (match-beginning 0)) 1506 (goto-char (match-beginning 0))
1455 (unless (setq boundaries (bibtex-parse-string)) 1507 (unless (setq boundaries (bibtex-parse-string))
1456 (forward-char 1))) 1508 (forward-char 1)))
@@ -1465,25 +1517,22 @@ the reference key and text parts of the field is returned. Do not move point."
1465 (let ((case-fold-search t) 1517 (let ((case-fold-search t)
1466 boundaries) 1518 boundaries)
1467 (while (and (not boundaries) 1519 (while (and (not boundaries)
1468 (search-backward-regexp 1520 (search-backward-regexp bibtex-string-type nil t))
1469 "^[ \t]*@string[ \t\n]*[({][ \t\n]*" nil t))
1470 (goto-char (match-beginning 0)) 1521 (goto-char (match-beginning 0))
1471 (setq boundaries (bibtex-parse-string))) 1522 (setq boundaries (bibtex-parse-string)))
1472 boundaries)))) 1523 boundaries))))
1473 1524
1474(defun bibtex-reference-key-in-string (bounds) 1525(defun bibtex-reference-key-in-string (bounds)
1526 "Return the key part of a BibTeX string defined via BOUNDS"
1475 (buffer-substring-no-properties (nth 1 (car bounds)) 1527 (buffer-substring-no-properties (nth 1 (car bounds))
1476 (nth 2 (car bounds)))) 1528 (nth 2 (car bounds))))
1477 1529
1478(defun bibtex-text-in-string (bounds &optional remove-delim) 1530(defun bibtex-text-in-string (bounds &optional content)
1479 "Get content of text in BibTeX string field defined via BOUNDS. 1531 "Get text in BibTeX string field defined via BOUNDS.
1480If optional arg REMOVE-DELIM is non-nil remove enclosing field 1532If optional arg CONTENT is non-nil extract content
1481delimiters if present." 1533by removing field delimiters and concatenating the resulting string.
1482 (let ((content (buffer-substring-no-properties (nth 0 (cdr bounds)) 1534If `bibtex-expand-strings' is non-nil, also expand BibTeX strings."
1483 (nth 1 (cdr bounds))))) 1535 (bibtex-text-in-field-bounds bounds content))
1484 (if remove-delim
1485 (bibtex-remove-delimiters-string content)
1486 content)))
1487 1536
1488(defsubst bibtex-start-of-text-in-string (bounds) 1537(defsubst bibtex-start-of-text-in-string (bounds)
1489 (nth 0 (cdr bounds))) 1538 (nth 0 (cdr bounds)))
@@ -1503,14 +1552,16 @@ delimiters if present."
1503 (or (match-string-no-properties bibtex-key-in-head) 1552 (or (match-string-no-properties bibtex-key-in-head)
1504 empty)) 1553 empty))
1505 1554
1506;; Helper Functions 1555(defun bibtex-preamble-prefix (&optional delim)
1556 "Parse the prefix part of a BibTeX Preamble.
1557Point must be at beginning of prefix part. If prefix is found move point
1558to its end and return position of point. If optional arg DELIM is non-nil,
1559move past the opening delimiter. If no preamble is found return nil."
1560 (let ((case-fold-search t))
1561 (re-search-forward (concat "\\=" bibtex-preamble-prefix
1562 (if delim "[({][ \t\n]*")) nil t)))
1507 1563
1508(defun bibtex-remove-delimiters-string (str) 1564;; Helper Functions
1509 "Remove delimiters of string STR."
1510 (if (and (memq (aref str 0) '(?\{ ?\"))
1511 (memq (aref str (1- (length str))) '(?\} ?\")))
1512 (substring str 1 -1)
1513 str))
1514 1565
1515(defsubst bibtex-string= (str1 str2) 1566(defsubst bibtex-string= (str1 str2)
1516 "Return t if STR1 and STR2 are equal, ignoring case." 1567 "Return t if STR1 and STR2 are equal, ignoring case."
@@ -1533,15 +1584,17 @@ With optional argument BACKWARD non-nil, move backward to
1533beginning of previous valid one. A valid entry is a syntactical correct one 1584beginning of previous valid one. A valid entry is a syntactical correct one
1534with type contained in `bibtex-entry-field-alist' or, if 1585with type contained in `bibtex-entry-field-alist' or, if
1535`bibtex-sort-ignore-string-entries' is nil, a syntactical correct string 1586`bibtex-sort-ignore-string-entries' is nil, a syntactical correct string
1536entry. Return buffer position of beginning and ending of entry if a valid 1587entry. Return buffer position of beginning and end of entry if a valid
1537entry is found, nil otherwise." 1588entry is found, nil otherwise."
1538 (interactive "P") 1589 (interactive "P")
1539 (let ((case-fold-search t) 1590 (let ((case-fold-search t)
1540 found) 1591 found)
1592 (beginning-of-line)
1593 ;; Loop till we look at a valid entry.
1541 (while (not (or found (if backward (bobp) (eobp)))) 1594 (while (not (or found (if backward (bobp) (eobp))))
1542 (let ((pnt (point)) 1595 (let ((pnt (point))
1543 bounds) 1596 bounds)
1544 (cond ((or (and (looking-at bibtex-valid-entry-re) 1597 (cond ((or (and (looking-at bibtex-entry-type-whitespace)
1545 (setq found (bibtex-search-entry nil nil t)) 1598 (setq found (bibtex-search-entry nil nil t))
1546 (equal (match-beginning 0) pnt)) 1599 (equal (match-beginning 0) pnt))
1547 (and (not bibtex-sort-ignore-string-entries) 1600 (and (not bibtex-sort-ignore-string-entries)
@@ -1549,11 +1602,10 @@ entry is found, nil otherwise."
1549 (setq found (cons (bibtex-start-of-field bounds) 1602 (setq found (cons (bibtex-start-of-field bounds)
1550 (bibtex-end-of-string bounds))))) 1603 (bibtex-end-of-string bounds)))))
1551 (goto-char pnt)) 1604 (goto-char pnt))
1552 (backward 1605 (backward (re-search-backward "^[ \t]*@" nil 'move))
1553 (if (re-search-backward "^[ \t]*\\(@\\)" nil 'move) 1606 (t (re-search-forward "\\=[ \t]*@" nil t) ;; don't be stuck
1554 (goto-char (match-beginning 1)))) 1607 (if (re-search-forward "^[ \t]*@" nil 'move)
1555 (t (if (re-search-forward "\n[ \t]*@" nil 'move) 1608 (goto-char (match-beginning 0)))))))
1556 (forward-char -1))))))
1557 found)) 1609 found))
1558 1610
1559(defun bibtex-map-entries (fun) 1611(defun bibtex-map-entries (fun)
@@ -1562,20 +1614,14 @@ FUN is called with three arguments, the key of the entry and the buffer
1562positions (marker) of beginning and end of entry. Point is inside the entry. 1614positions (marker) of beginning and end of entry. Point is inside the entry.
1563If `bibtex-sort-ignore-string-entries' is non-nil, FUN is not called for 1615If `bibtex-sort-ignore-string-entries' is non-nil, FUN is not called for
1564@String entries." 1616@String entries."
1565 (let ((case-fold-search t)) 1617 (let ((case-fold-search t)
1618 found)
1566 (save-excursion 1619 (save-excursion
1567 (goto-char (point-min)) 1620 (goto-char (point-min))
1568 (while (re-search-forward bibtex-entry-head nil t) 1621 (while (setq found (bibtex-skip-to-valid-entry))
1569 (let ((entry-type (bibtex-type-in-head)) 1622 (looking-at bibtex-any-entry-maybe-empty-head)
1570 (key (bibtex-key-in-head "")) 1623 (funcall fun (bibtex-key-in-head "") (car found) (cdr found))
1571 (beg (copy-marker (match-beginning 0))) 1624 (goto-char (cdr found))))))
1572 (end (copy-marker (save-excursion (bibtex-end-of-entry)))))
1573 (save-excursion
1574 (if (or (and (not bibtex-sort-ignore-string-entries)
1575 (bibtex-string= entry-type "string"))
1576 (assoc-string entry-type bibtex-entry-field-alist t))
1577 (funcall fun key beg end)))
1578 (goto-char end))))))
1579 1625
1580(defun bibtex-progress-message (&optional flag interval) 1626(defun bibtex-progress-message (&optional flag interval)
1581 "Echo a message about progress of current buffer. 1627 "Echo a message about progress of current buffer.
@@ -1631,9 +1677,9 @@ BOUND and NOERROR are exactly as in `re-search-forward'. If BACKWARD
1631is non-nil, search in reverse direction. Move point past the closing 1677is non-nil, search in reverse direction. Move point past the closing
1632delimiter (at the beginning of entry if BACKWARD is non-nil). 1678delimiter (at the beginning of entry if BACKWARD is non-nil).
1633Return a cons pair with buffer positions of beginning and end of entry. 1679Return a cons pair with buffer positions of beginning and end of entry.
1634After call to this function MATCH-BEGINNING and MATCH-END functions 1680After a call to this function `match-data' corresponds to the head part
1635are defined, but only for the head part of the entry 1681of the entry, see regexp `bibtex-entry-head'.
1636\(especially (match-end 0) just gives the end of the head part)." 1682Ignore @String and @Preamble entries."
1637 (let ((pnt (point)) 1683 (let ((pnt (point))
1638 (entry-head-re (if empty-head 1684 (entry-head-re (if empty-head
1639 bibtex-entry-maybe-empty-head 1685 bibtex-entry-maybe-empty-head
@@ -1643,16 +1689,13 @@ are defined, but only for the head part of the entry
1643 (while (and (not found) 1689 (while (and (not found)
1644 (re-search-backward entry-head-re bound noerror)) 1690 (re-search-backward entry-head-re bound noerror))
1645 (setq found (bibtex-search-entry empty-head pnt t))) 1691 (setq found (bibtex-search-entry empty-head pnt t)))
1646 (if found 1692 (cond (found
1647 (progn (goto-char (match-beginning 0)) 1693 (goto-char (match-beginning 0))
1648 found) 1694 found)
1649 (cond ((not noerror) 1695 ((not noerror) ;; yell
1650 ;; yell 1696 (error "Backward search of BibTeX entry failed"))
1651 (error "Backward search of BibTeX entry failed")) 1697 (t (if (eq noerror t) (goto-char pnt)) ;; don't move
1652 ((eq noerror t) 1698 nil)))
1653 ;; don't move
1654 (goto-char pnt)))
1655 nil))
1656 (let (found) 1699 (let (found)
1657 (unless bound (setq bound (point-max))) 1700 (unless bound (setq bound (point-max)))
1658 (while (and (not found) 1701 (while (and (not found)
@@ -1662,52 +1705,41 @@ are defined, but only for the head part of the entry
1662 (if (save-excursion 1705 (if (save-excursion
1663 (goto-char (match-end bibtex-type-in-head)) 1706 (goto-char (match-end bibtex-type-in-head))
1664 (looking-at "[ \t]*(")) 1707 (looking-at "[ \t]*("))
1665 ;; entry opened with parenthesis 1708 ",?[ \t\n]*)" ;; entry opened with `('
1666 ?\) 1709 ",?[ \t\n]*}")) ;; entry opened with `{'
1667 ?\})) 1710 bounds)
1668 (infix-start (point)) 1711 (skip-chars-forward " \t\n" bound)
1669 finished bounds) 1712 ;; loop over all BibTeX fields
1670 (while (not finished) 1713 (while (and (setq bounds (bibtex-parse-field))
1671 (skip-chars-forward " \t\n" bound) 1714 (<= (bibtex-end-of-field bounds) bound))
1672 (if (and (setq bounds (bibtex-parse-field bibtex-field-name)) 1715 (goto-char (bibtex-end-of-field bounds)))
1673 (<= (bibtex-end-of-field bounds) bound)) 1716 ;; This matches the infix* part.
1674 (setq infix-start (bibtex-end-of-field bounds)) 1717 (when (and (looking-at entry-closer)
1675 (setq finished t))
1676 (goto-char infix-start))
1677 ;; This matches the infix* part. The AND construction assures
1678 ;; that BOUND is respected.
1679 (when (and (looking-at bibtex-entry-postfix)
1680 (eq (char-before (match-end 0)) entry-closer)
1681 (<= (match-end 0) bound)) 1718 (<= (match-end 0) bound))
1682 (goto-char (match-end 0)) 1719 (goto-char (match-end 0))
1683 (setq found t))))) 1720 (setq found t)))))
1684 (if found 1721 (cond (found
1685 (cons (match-beginning 0) (point)) 1722 (cons (match-beginning 0) (point)))
1686 (cond ((not noerror) 1723 ((not noerror) ;; yell
1687 ;; yell 1724 (error "Search of BibTeX entry failed"))
1688 (error "Search of BibTeX entry failed")) 1725 (t (if (eq noerror t) (goto-char pnt)) ;; don't move
1689 ((eq noerror t) 1726 nil))))))
1690 ;; don't move
1691 (goto-char pnt)))
1692 nil)))))
1693 1727
1694(defun bibtex-flash-head () 1728(defun bibtex-flash-head ()
1695 "Flash at BibTeX entry head before point, if exists." 1729 "Flash at BibTeX entry head before point, if exists."
1696 (let ((case-fold-search t) 1730 (let ((case-fold-search t)
1731 (pnt (point))
1697 flash) 1732 flash)
1698 (cond ((re-search-backward bibtex-entry-head nil t) 1733 (save-excursion
1699 (goto-char (match-beginning bibtex-type-in-head)) 1734 (bibtex-beginning-of-entry)
1700 (setq flash (match-end bibtex-key-in-head))) 1735 (when (and (looking-at bibtex-any-entry-maybe-empty-head)
1701 (t 1736 (< (point) pnt))
1702 (end-of-line) 1737 (goto-char (match-beginning bibtex-type-in-head))
1703 (skip-chars-backward " \t") 1738 (setq flash (match-end bibtex-key-in-head))
1704 (setq flash (point)) 1739 (if (pos-visible-in-window-p (point))
1705 (beginning-of-line) 1740 (sit-for 1)
1706 (skip-chars-forward " \t"))) 1741 (message "From: %s"
1707 (if (pos-visible-in-window-p (point)) 1742 (buffer-substring (point) flash)))))))
1708 (sit-for 1)
1709 (message "From: %s"
1710 (buffer-substring (point) flash)))))
1711 1743
1712(defun bibtex-make-optional-field (field) 1744(defun bibtex-make-optional-field (field)
1713 "Make an optional field named FIELD in current BibTeX entry." 1745 "Make an optional field named FIELD in current BibTeX entry."
@@ -1731,17 +1763,11 @@ are defined, but only for the head part of the entry
1731 (skip-chars-forward " \t\n"))) 1763 (skip-chars-forward " \t\n")))
1732 1764
1733(defun bibtex-beginning-of-first-entry () 1765(defun bibtex-beginning-of-first-entry ()
1734 "Go to the beginning of the first BibTeX entry in buffer. Return point." 1766 "Go to beginning of line of first BibTeX entry in buffer.
1767If `bibtex-sort-ignore-string-entries' is non-nil, @String entries
1768are ignored. Return point"
1735 (goto-char (point-min)) 1769 (goto-char (point-min))
1736 (if (re-search-forward "^[ \t]*@" nil 'move) 1770 (bibtex-skip-to-valid-entry)
1737 (beginning-of-line))
1738 (point))
1739
1740(defun bibtex-beginning-of-last-entry ()
1741 "Go to the beginning of the last BibTeX entry in buffer."
1742 (goto-char (point-max))
1743 (if (re-search-backward "^[ \t]*@" nil 'move)
1744 (beginning-of-line))
1745 (point)) 1771 (point))
1746 1772
1747(defun bibtex-inside-field () 1773(defun bibtex-inside-field ()
@@ -1758,7 +1784,7 @@ are defined, but only for the head part of the entry
1758 "Search for BibTeX field enclosing point. 1784 "Search for BibTeX field enclosing point.
1759Unless NOERR is non-nil, signal an error if no enclosing field is found. 1785Unless NOERR is non-nil, signal an error if no enclosing field is found.
1760On success return bounds, nil otherwise. Do not move point." 1786On success return bounds, nil otherwise. Do not move point."
1761 (let ((bounds (bibtex-search-backward-field bibtex-field-name t))) 1787 (let ((bounds (bibtex-search-backward-field bibtex-field-name)))
1762 (if (and bounds 1788 (if (and bounds
1763 (<= (bibtex-start-of-field bounds) (point)) 1789 (<= (bibtex-start-of-field bounds) (point))
1764 (>= (bibtex-end-of-field bounds) (point))) 1790 (>= (bibtex-end-of-field bounds) (point)))
@@ -1793,7 +1819,7 @@ Beginning (but not end) of entry is given by (`match-beginning' 0)."
1793 (length (eval kr))) 1819 (length (eval kr)))
1794 (eval kr)))))) 1820 (eval kr))))))
1795 (if (eq bibtex-last-kill-command 'field) 1821 (if (eq bibtex-last-kill-command 'field)
1796 (let (bibtex-help-message) 1822 (progn
1797 (bibtex-find-text) 1823 (bibtex-find-text)
1798 (if (looking-at "[}\"]") 1824 (if (looking-at "[}\"]")
1799 (forward-char)) 1825 (forward-char))
@@ -1846,12 +1872,11 @@ Formats current entry according to variable `bibtex-entry-format'."
1846 ;; determine if entry has crossref field and if at least 1872 ;; determine if entry has crossref field and if at least
1847 ;; one alternative is non-empty 1873 ;; one alternative is non-empty
1848 (goto-char (point-min)) 1874 (goto-char (point-min))
1849 (let* ((fields-alist (bibtex-parse-entry)) 1875 (let* ((fields-alist (bibtex-parse-entry t))
1850 (field (assoc-string "crossref" fields-alist t))) 1876 (field (assoc-string "crossref" fields-alist t)))
1851 (setq crossref-key (and field 1877 (setq crossref-key (and field
1852 (not (string-match bibtex-empty-field-re 1878 (not (equal "" (cdr field)))
1853 (cdr field))) 1879 (cdr field))
1854 (bibtex-remove-delimiters-string (cdr field)))
1855 req-field-list (if crossref-key 1880 req-field-list (if crossref-key
1856 (nth 0 (nth 2 entry-list)) ; crossref part 1881 (nth 0 (nth 2 entry-list)) ; crossref part
1857 (nth 0 (nth 1 entry-list)))) ; required part 1882 (nth 0 (nth 1 entry-list)))) ; required part
@@ -1861,8 +1886,7 @@ Formats current entry according to variable `bibtex-entry-format'."
1861 (setq alternatives-there t 1886 (setq alternatives-there t
1862 field (assoc-string (car rfield) fields-alist t)) 1887 field (assoc-string (car rfield) fields-alist t))
1863 (if (and field 1888 (if (and field
1864 (not (string-match bibtex-empty-field-re 1889 (not (equal "" (cdr field))))
1865 (cdr field))))
1866 (cond ((not non-empty-alternative) 1890 (cond ((not non-empty-alternative)
1867 (setq non-empty-alternative t)) 1891 (setq non-empty-alternative t))
1868 ((memq 'required-fields format) 1892 ((memq 'required-fields format)
@@ -1875,7 +1899,8 @@ Formats current entry according to variable `bibtex-entry-format'."
1875 1899
1876 ;; process all fields 1900 ;; process all fields
1877 (goto-char (point-min)) 1901 (goto-char (point-min))
1878 (while (setq bounds (bibtex-search-forward-field bibtex-field-name)) 1902 (while (setq bounds (bibtex-search-forward-field
1903 bibtex-field-name (point-max)))
1879 (let* ((beg-field (copy-marker (bibtex-start-of-field bounds))) 1904 (let* ((beg-field (copy-marker (bibtex-start-of-field bounds)))
1880 (end-field (copy-marker (bibtex-end-of-field bounds) t)) 1905 (end-field (copy-marker (bibtex-end-of-field bounds) t))
1881 (beg-name (copy-marker (bibtex-start-of-name-in-field bounds))) 1906 (beg-name (copy-marker (bibtex-start-of-name-in-field bounds)))
@@ -1887,9 +1912,7 @@ Formats current entry according to variable `bibtex-entry-format'."
1887 beg-name (+ beg-name 3)))) 1912 beg-name (+ beg-name 3))))
1888 (field-name (buffer-substring-no-properties 1913 (field-name (buffer-substring-no-properties
1889 (if opt-alt (+ beg-name 3) beg-name) end-name)) 1914 (if opt-alt (+ beg-name 3) beg-name) end-name))
1890 (empty-field (string-match bibtex-empty-field-re 1915 (empty-field (equal "" (bibtex-text-in-field-bounds bounds t)))
1891 (buffer-substring-no-properties
1892 beg-text end-text)))
1893 deleted) 1916 deleted)
1894 1917
1895 ;; We have more elegant high-level functions for several 1918 ;; We have more elegant high-level functions for several
@@ -2065,7 +2088,8 @@ is returned unchanged."
2065Optional arg CHANGE-LIST is a list of substitution patterns that is 2088Optional arg CHANGE-LIST is a list of substitution patterns that is
2066applied to the content of FIELD. It is an alist with pairs 2089applied to the content of FIELD. It is an alist with pairs
2067\(OLD-REGEXP . NEW-STRING\)." 2090\(OLD-REGEXP . NEW-STRING\)."
2068 (let ((content (bibtex-text-in-field field bibtex-autokey-use-crossref)) 2091 (let* ((bibtex-expand-strings bibtex-autokey-expand-strings)
2092 (content (bibtex-text-in-field field bibtex-autokey-use-crossref))
2069 case-fold-search) 2093 case-fold-search)
2070 (unless content (setq content "")) 2094 (unless content (setq content ""))
2071 (dolist (pattern change-list content) 2095 (dolist (pattern change-list content)
@@ -2195,6 +2219,7 @@ The algorithm works as follows.
2195 2219
2196The name part: 2220The name part:
2197 1. Use the author or editor field to generate the name part of the key. 2221 1. Use the author or editor field to generate the name part of the key.
2222 Expand BibTeX strings if `bibtex-autokey-expand-strings' is non-nil.
2198 2. Change the content of the name field according to 2223 2. Change the content of the name field according to
2199 `bibtex-autokey-name-change-strings' (see there for further detail). 2224 `bibtex-autokey-name-change-strings' (see there for further detail).
2200 3. Use the first `bibtex-autokey-names' names in the name field. If there 2225 3. Use the first `bibtex-autokey-names' names in the name field. If there
@@ -2299,7 +2324,9 @@ If optional arg GLOBAL is non-nil, completion is based on the keys in
2299 "Set `bibtex-reference-keys' to the keys used in the whole buffer. 2324 "Set `bibtex-reference-keys' to the keys used in the whole buffer.
2300Find both entry keys and crossref entries. If ABORTABLE is non-nil abort 2325Find both entry keys and crossref entries. If ABORTABLE is non-nil abort
2301on user input. If VERBOSE is non-nil give messages about progress. 2326on user input. If VERBOSE is non-nil give messages about progress.
2302Return alist of keys if parsing was completed, `aborted' otherwise." 2327Return alist of keys if parsing was completed, `aborted' otherwise.
2328If `bibtex-parse-keys-fast' is non-nil, use fast but simplified algorithm
2329for parsing BibTeX keys. If parsing fails, try to set this variable to nil."
2303 (let (ref-keys crossref-keys) 2330 (let (ref-keys crossref-keys)
2304 (save-excursion 2331 (save-excursion
2305 (save-match-data 2332 (save-match-data
@@ -2387,6 +2414,11 @@ Return alist of strings if parsing was completed, `aborted' otherwise."
2387 ;; successful operation --> return `bibtex-strings' 2414 ;; successful operation --> return `bibtex-strings'
2388 (setq bibtex-strings strings)))))) 2415 (setq bibtex-strings strings))))))
2389 2416
2417(defun bibtex-strings ()
2418 "Return `bibtex-strings'. Initialize this variable if necessary."
2419 (if (listp bibtex-strings) bibtex-strings
2420 (bibtex-parse-strings (bibtex-string-files-init))))
2421
2390(defun bibtex-string-files-init () 2422(defun bibtex-string-files-init ()
2391 "Return initialization for `bibtex-strings'. 2423 "Return initialization for `bibtex-strings'.
2392Use `bibtex-predefined-strings' and BibTeX files `bibtex-string-files'." 2424Use `bibtex-predefined-strings' and BibTeX files `bibtex-string-files'."
@@ -2521,8 +2553,7 @@ of a word, all strings are listed. Return completion."
2521 (t 2553 (t
2522 (message "Making completion list...") 2554 (message "Making completion list...")
2523 (with-output-to-temp-buffer "*Completions*" 2555 (with-output-to-temp-buffer "*Completions*"
2524 (display-completion-list (all-completions part-of-word 2556 (display-completion-list (all-completions part-of-word completions)
2525 completions)
2526 part-of-word)) 2557 part-of-word))
2527 (message "Making completion list...done") 2558 (message "Making completion list...done")
2528 ;; return value is handled by choose-completion-string-functions 2559 ;; return value is handled by choose-completion-string-functions
@@ -2533,17 +2564,10 @@ of a word, all strings are listed. Return completion."
2533Remove enclosing field delimiters for STR. Display message with 2564Remove enclosing field delimiters for STR. Display message with
2534expansion of STR using expansion list COMPL." 2565expansion of STR using expansion list COMPL."
2535 (save-excursion 2566 (save-excursion
2536 (bibtex-inside-field) 2567 (let ((abbr (cdr (if (stringp str)
2537 (let ((bounds (bibtex-enclosing-field))
2538 (abbr (cdr (if (stringp str)
2539 (assoc-string str compl t))))) 2568 (assoc-string str compl t)))))
2540 (if abbr (message "Abbreviation for `%s'" abbr)) 2569 (if abbr (message "Abbreviation for `%s'" abbr))
2541 (goto-char (bibtex-start-of-text-in-field bounds)) 2570 (bibtex-remove-delimiters))))
2542 (let ((boundaries (bibtex-parse-field-string)))
2543 (if (and boundaries
2544 (equal (cdr boundaries)
2545 (bibtex-end-of-text-in-field bounds)))
2546 (bibtex-remove-delimiters))))))
2547 2571
2548(defun bibtex-complete-crossref-cleanup (key) 2572(defun bibtex-complete-crossref-cleanup (key)
2549 "Display summary message on entry KEY after completion of a crossref key. 2573 "Display summary message on entry KEY after completion of a crossref key.
@@ -2598,8 +2622,7 @@ Used as default value of `bibtex-summary-function'."
2598(defun bibtex-pop (arg direction) 2622(defun bibtex-pop (arg direction)
2599 "Fill current field from the ARGth same field's text in DIRECTION. 2623 "Fill current field from the ARGth same field's text in DIRECTION.
2600Generic function used by `bibtex-pop-previous' and `bibtex-pop-next'." 2624Generic function used by `bibtex-pop-previous' and `bibtex-pop-next'."
2601 (let (bibtex-help-message) 2625 (bibtex-find-text)
2602 (bibtex-find-text))
2603 (save-excursion 2626 (save-excursion
2604 ;; parse current field 2627 ;; parse current field
2605 (bibtex-inside-field) 2628 (bibtex-inside-field)
@@ -2642,8 +2665,7 @@ Generic function used by `bibtex-pop-previous' and `bibtex-pop-next'."
2642 (goto-char stop-old-text) 2665 (goto-char stop-old-text)
2643 (delete-region start-old-text stop-old-text) 2666 (delete-region start-old-text stop-old-text)
2644 (insert new-text))))) 2667 (insert new-text)))))
2645 (let (bibtex-help-message) 2668 (bibtex-find-text)
2646 (bibtex-find-text))
2647 (setq this-command 'bibtex-pop)) 2669 (setq this-command 'bibtex-pop))
2648 2670
2649(defun bibtex-beginning-of-field () 2671(defun bibtex-beginning-of-field ()
@@ -2667,7 +2689,7 @@ begins at the beginning of a line. We use this function for font-locking."
2667 (setq field (match-string-no-properties 1))) 2689 (setq field (match-string-no-properties 1)))
2668 (setq bounds (bibtex-parse-field-text)) 2690 (setq bounds (bibtex-parse-field-text))
2669 (progn 2691 (progn
2670 (setq start (car bounds) end (cdr bounds)) 2692 (setq start (car bounds) end (nth 1 bounds))
2671 ;; Always ignore field delimiters 2693 ;; Always ignore field delimiters
2672 (if (memq (char-before end) '(?\} ?\")) 2694 (if (memq (char-before end) '(?\} ?\"))
2673 (setq end (1- end))) 2695 (setq end (1- end)))
@@ -2905,20 +2927,21 @@ according to `bibtex-field-list', but are not yet present."
2905 (unless (assoc-string (car field) fields-alist t) 2927 (unless (assoc-string (car field) fields-alist t)
2906 (bibtex-make-optional-field field)))))) 2928 (bibtex-make-optional-field field))))))
2907 2929
2908(defun bibtex-parse-entry () 2930(defun bibtex-parse-entry (&optional content)
2909 "Parse entry at point, return an alist. 2931 "Parse entry at point, return an alist.
2910The alist elements have the form (FIELD . TEXT), where FIELD can also be 2932The alist elements have the form (FIELD . TEXT), where FIELD can also be
2911the special strings \"=type=\" and \"=key=\". For the FIELD \"=key=\" 2933the special strings \"=type=\" and \"=key=\". For the FIELD \"=key=\"
2912TEXT may be nil. Remove \"OPT\" and \"ALT\" from FIELD. 2934TEXT may be nil. Remove \"OPT\" and \"ALT\" from FIELD.
2913Move point to the end of the last field." 2935Move point to the end of the last field.
2936If optional arg CONTENT is non-nil extract content of text fields."
2914 (let (alist bounds) 2937 (let (alist bounds)
2915 (when (looking-at bibtex-entry-maybe-empty-head) 2938 (when (looking-at bibtex-entry-maybe-empty-head)
2916 (push (cons "=type=" (bibtex-type-in-head)) alist) 2939 (push (cons "=type=" (bibtex-type-in-head)) alist)
2917 (push (cons "=key=" (bibtex-key-in-head)) alist) 2940 (push (cons "=key=" (bibtex-key-in-head)) alist)
2918 (goto-char (match-end 0)) 2941 (goto-char (match-end 0))
2919 (while (setq bounds (bibtex-parse-field bibtex-field-name)) 2942 (while (setq bounds (bibtex-parse-field))
2920 (push (cons (bibtex-name-in-field bounds t) 2943 (push (cons (bibtex-name-in-field bounds t)
2921 (bibtex-text-in-field-bounds bounds)) 2944 (bibtex-text-in-field-bounds bounds content))
2922 alist) 2945 alist)
2923 (goto-char (bibtex-end-of-field bounds)))) 2946 (goto-char (bibtex-end-of-field bounds))))
2924 alist)) 2947 alist))
@@ -2970,14 +2993,11 @@ entry (for example, the year parts of the keys)."
2970 (when other 2993 (when other
2971 (setq other (save-excursion (goto-char other) (bibtex-parse-entry))) 2994 (setq other (save-excursion (goto-char other) (bibtex-parse-entry)))
2972 (setq key-end (point)) ;In case parse-entry changed the buffer. 2995 (setq key-end (point)) ;In case parse-entry changed the buffer.
2973 (while (setq bounds (bibtex-parse-field bibtex-field-name)) 2996 (while (setq bounds (bibtex-parse-field))
2974 (let ((text (assoc-string (bibtex-name-in-field bounds t) 2997 (let ((text (assoc-string (bibtex-name-in-field bounds t)
2975 other t))) 2998 other t)))
2976 (if (not (and text 2999 (if (not (and text
2977 (string-match bibtex-empty-field-re 3000 (equal "" (bibtex-text-in-field-bounds bounds t))))
2978 (buffer-substring-no-properties
2979 (bibtex-start-of-text-in-field bounds)
2980 (bibtex-end-of-text-in-field bounds)))))
2981 (goto-char (bibtex-end-of-field bounds)) 3001 (goto-char (bibtex-end-of-field bounds))
2982 (goto-char (bibtex-start-of-text-in-field bounds)) 3002 (goto-char (bibtex-start-of-text-in-field bounds))
2983 (delete-region (point) (bibtex-end-of-text-in-field bounds)) 3003 (delete-region (point) (bibtex-end-of-text-in-field bounds))
@@ -2997,19 +3017,25 @@ entry (for example, the year parts of the keys)."
2997(defun bibtex-print-help-message () 3017(defun bibtex-print-help-message ()
2998 "Print helpful information about current field in current BibTeX entry." 3018 "Print helpful information about current field in current BibTeX entry."
2999 (interactive) 3019 (interactive)
3000 (save-excursion 3020 (let* ((case-fold-search t)
3001 (let* ((case-fold-search t) 3021 (type (save-excursion
3002 (field-name (bibtex-name-in-field (bibtex-enclosing-field) t)) 3022 (bibtex-beginning-of-entry)
3003 (field-list (bibtex-field-list (progn (re-search-backward 3023 (looking-at bibtex-any-entry-maybe-empty-head)
3004 bibtex-entry-maybe-empty-head nil t) 3024 (bibtex-type-in-head)))
3005 (bibtex-type-in-head)))) 3025 comment field-list)
3006 (comment (assoc-string field-name 3026 (cond ((bibtex-string= type "string")
3007 (append (car field-list) 3027 (message "String definition"))
3008 (cdr field-list)) 3028 ((bibtex-string= type "preamble")
3009 t))) 3029 (message "Preamble definition"))
3010 (if comment 3030 (t
3011 (message "%s" (nth 1 comment)) 3031 (setq field-list (bibtex-field-list type)
3012 (message "No comment available"))))) 3032 comment
3033 (assoc-string (bibtex-name-in-field (bibtex-enclosing-field) t)
3034 (append (car field-list) (cdr field-list))
3035 t))
3036 (if comment
3037 (message "%s" (nth 1 comment))
3038 (message "No comment available"))))))
3013 3039
3014(defun bibtex-make-field (field &optional move interactive) 3040(defun bibtex-make-field (field &optional move interactive)
3015 "Make a field named FIELD in current BibTeX entry. 3041 "Make a field named FIELD in current BibTeX entry.
@@ -3032,11 +3058,10 @@ MOVE and INTERACTIVE are t when called interactively."
3032 t t)) 3058 t t))
3033 (unless (consp field) 3059 (unless (consp field)
3034 (setq field (list field))) 3060 (setq field (list field)))
3035 (if move 3061 (when move
3036 (let (bibtex-help-message) 3062 (bibtex-find-text)
3037 (bibtex-find-text) 3063 (if (looking-at "[}\"]")
3038 (if (looking-at "[}\"]") 3064 (forward-char)))
3039 (forward-char))))
3040 (insert ",\n") 3065 (insert ",\n")
3041 (indent-to-column (+ bibtex-entry-offset bibtex-field-indentation)) 3066 (indent-to-column (+ bibtex-entry-offset bibtex-field-indentation))
3042 (if (nth 3 field) (insert "ALT")) 3067 (if (nth 3 field) (insert "ALT"))
@@ -3079,16 +3104,16 @@ Return the new location of point."
3079 (org (point)) 3104 (org (point))
3080 (pnt (bibtex-beginning-of-entry)) 3105 (pnt (bibtex-beginning-of-entry))
3081 err bounds) 3106 err bounds)
3082 (cond ((looking-at bibtex-valid-entry-whitespace-re) 3107 (cond ((looking-at bibtex-entry-type-whitespace)
3083 (bibtex-search-entry t nil t) 3108 (bibtex-search-entry t nil t)
3084 (unless (equal (match-beginning 0) pnt) 3109 (unless (equal (match-beginning 0) pnt)
3085 (setq err t))) 3110 (setq err t)))
3111 ;; @String
3086 ((setq bounds (bibtex-parse-string)) 3112 ((setq bounds (bibtex-parse-string))
3087 (goto-char (bibtex-end-of-string bounds))) 3113 (goto-char (bibtex-end-of-string bounds)))
3088 ((looking-at "[ \t]*@[ \t]*preamble[ \t\n]*") 3114 ;; @Preamble
3089 (goto-char (match-end 0)) 3115 ((bibtex-preamble-prefix t)
3090 (if (looking-at "[({]") 3116 (unless (bibtex-parse-string-postfix) ;; @String postfix OK
3091 (forward-sexp 1)
3092 (setq err t))) 3117 (setq err t)))
3093 (t 3118 (t
3094 (if (interactive-p) 3119 (if (interactive-p)
@@ -3142,15 +3167,10 @@ otherwise count all entries except @String entries.
3142If mark is active count entries in region, if not in whole buffer." 3167If mark is active count entries in region, if not in whole buffer."
3143 (interactive "P") 3168 (interactive "P")
3144 (let ((number 0) 3169 (let ((number 0)
3145 (bibtex-sort-ignore-string-entries 3170 (bibtex-sort-ignore-string-entries (not count-string-entries)))
3146 (not count-string-entries))) 3171 (save-restriction
3147 (save-excursion 3172 (if mark-active (narrow-to-region (region-beginning) (region-end)))
3148 (save-restriction 3173 (bibtex-map-entries (lambda (key beg end) (setq number (1+ number)))))
3149 (narrow-to-region (if mark-active (region-beginning)
3150 (bibtex-beginning-of-first-entry))
3151 (if mark-active (region-end) (point-max)))
3152 (bibtex-map-entries (lambda (key beg end)
3153 (setq number (1+ number))))))
3154 (message "%s contains %d entries." 3174 (message "%s contains %d entries."
3155 (if mark-active "Region" "Buffer") 3175 (if mark-active "Region" "Buffer")
3156 number))) 3176 number)))
@@ -3166,7 +3186,7 @@ If mark is active count entries in region, if not in whole buffer."
3166 (interactive) 3186 (interactive)
3167 (let ((bounds (save-excursion 3187 (let ((bounds (save-excursion
3168 (bibtex-beginning-of-entry) 3188 (bibtex-beginning-of-entry)
3169 (bibtex-search-forward-field "abstract" t)))) 3189 (bibtex-search-forward-field "abstract"))))
3170 (if bounds 3190 (if bounds
3171 (ispell-region (bibtex-start-of-text-in-field bounds) 3191 (ispell-region (bibtex-start-of-text-in-field bounds)
3172 (bibtex-end-of-text-in-field bounds)) 3192 (bibtex-end-of-text-in-field bounds))
@@ -3194,7 +3214,7 @@ of the head of the entry found. Return nil if no entry found."
3194 ;; Don't search CROSSREF-KEY if we don't need it. 3214 ;; Don't search CROSSREF-KEY if we don't need it.
3195 (if (eq bibtex-maintain-sorted-entries 'crossref) 3215 (if (eq bibtex-maintain-sorted-entries 'crossref)
3196 (let ((bounds (bibtex-search-forward-field 3216 (let ((bounds (bibtex-search-forward-field
3197 "\\(OPT\\)?crossref" t))) 3217 "\\(OPT\\)?crossref")))
3198 (list key 3218 (list key
3199 (if bounds (bibtex-text-in-field-bounds bounds t)) 3219 (if bounds (bibtex-text-in-field-bounds bounds t))
3200 entry-name)) 3220 entry-name))
@@ -3237,17 +3257,13 @@ If its value is nil use plain sorting. Text outside of BibTeX entries is not
3237affected. If `bibtex-sort-ignore-string-entries' is non-nil, @String entries 3257affected. If `bibtex-sort-ignore-string-entries' is non-nil, @String entries
3238are ignored." 3258are ignored."
3239 (interactive) 3259 (interactive)
3240 (save-restriction 3260 (bibtex-beginning-of-first-entry) ;; needed by `sort-subr'
3241 (narrow-to-region (bibtex-beginning-of-first-entry)
3242 (save-excursion (goto-char (point-max))
3243 (bibtex-end-of-entry)))
3244 (bibtex-skip-to-valid-entry)
3245 (sort-subr nil 3261 (sort-subr nil
3246 'bibtex-skip-to-valid-entry ; NEXTREC function 3262 'bibtex-skip-to-valid-entry ; NEXTREC function
3247 'bibtex-end-of-entry ; ENDREC function 3263 'bibtex-end-of-entry ; ENDREC function
3248 'bibtex-entry-index ; STARTKEY function 3264 'bibtex-entry-index ; STARTKEY function
3249 nil ; ENDKEY function 3265 nil ; ENDKEY function
3250 'bibtex-lessp))) ; PREDICATE 3266 'bibtex-lessp)) ; PREDICATE
3251 3267
3252(defun bibtex-find-crossref (crossref-key &optional pnt split) 3268(defun bibtex-find-crossref (crossref-key &optional pnt split)
3253 "Move point to the beginning of BibTeX entry CROSSREF-KEY. 3269 "Move point to the beginning of BibTeX entry CROSSREF-KEY.
@@ -3265,7 +3281,7 @@ entry and SPLIT is t."
3265 (let ((crossref-key 3281 (let ((crossref-key
3266 (save-excursion 3282 (save-excursion
3267 (bibtex-beginning-of-entry) 3283 (bibtex-beginning-of-entry)
3268 (let ((bounds (bibtex-search-forward-field "crossref" t))) 3284 (let ((bounds (bibtex-search-forward-field "crossref")))
3269 (if bounds 3285 (if bounds
3270 (bibtex-text-in-field-bounds bounds t)))))) 3286 (bibtex-text-in-field-bounds bounds t))))))
3271 (list (bibtex-read-key "Find crossref key: " crossref-key t) 3287 (list (bibtex-read-key "Find crossref key: " crossref-key t)
@@ -3361,11 +3377,10 @@ Return t if preparation was successful or nil if entry KEY already exists."
3361 (key-exist) 3377 (key-exist)
3362 (t ; bibtex-maintain-sorted-entries is non-nil 3378 (t ; bibtex-maintain-sorted-entries is non-nil
3363 (let* ((case-fold-search t) 3379 (let* ((case-fold-search t)
3364 (left (save-excursion (bibtex-beginning-of-first-entry) 3380 (left (save-excursion (bibtex-beginning-of-first-entry)))
3365 (bibtex-skip-to-valid-entry) 3381 (bounds (save-excursion (goto-char (point-max))
3366 (point))) 3382 (bibtex-skip-to-valid-entry t)))
3367 (right (save-excursion (bibtex-beginning-of-last-entry) 3383 (right (if bounds (cdr bounds) (point-min)))
3368 (bibtex-end-of-entry)))
3369 (found (if (>= left right) left)) 3384 (found (if (>= left right) left))
3370 actual-index new) 3385 actual-index new)
3371 (save-excursion 3386 (save-excursion
@@ -3412,9 +3427,8 @@ Return t if test was successful, nil otherwise."
3412 error-list syntax-error) 3427 error-list syntax-error)
3413 (save-excursion 3428 (save-excursion
3414 (save-restriction 3429 (save-restriction
3415 (narrow-to-region (if mark-active (region-beginning) 3430 (if mark-active
3416 (bibtex-beginning-of-first-entry)) 3431 (narrow-to-region (region-beginning) (region-end)))
3417 (if mark-active (region-end) (point-max)))
3418 3432
3419 ;; looking if entries fit syntactical structure 3433 ;; looking if entries fit syntactical structure
3420 (goto-char (point-min)) 3434 (goto-char (point-min))
@@ -3424,7 +3438,7 @@ Return t if test was successful, nil otherwise."
3424 (bibtex-progress-message) 3438 (bibtex-progress-message)
3425 (forward-char -1) 3439 (forward-char -1)
3426 (let ((pnt (point))) 3440 (let ((pnt (point)))
3427 (if (not (looking-at bibtex-any-valid-entry-re)) 3441 (if (not (looking-at bibtex-entry-type-str))
3428 (forward-char) 3442 (forward-char)
3429 (bibtex-skip-to-valid-entry) 3443 (bibtex-skip-to-valid-entry)
3430 (if (equal (point) pnt) 3444 (if (equal (point) pnt)
@@ -3634,33 +3648,27 @@ With prefix BEGIN non-nil, move point to its beginning."
3634 (goto-char start) 3648 (goto-char start)
3635 (end-of-line) 3649 (end-of-line)
3636 (forward-char)))) 3650 (forward-char))))
3637 (bibtex-find-text begin)) 3651 (bibtex-find-text begin nil bibtex-help-message))
3638 3652
3639(defun bibtex-find-text (&optional begin noerror) 3653(defun bibtex-find-text (&optional begin noerror help)
3640 "Move point to end of text of current BibTeX field. 3654 "Move point to end of text of current BibTeX field.
3641With optional prefix BEGIN non-nil, move point to its beginning. 3655With optional prefix BEGIN non-nil, move point to its beginning.
3642Unless NOERROR is non-nil, an error is signaled if point is not 3656Unless NOERROR is non-nil, an error is signaled if point is not
3643on a BibTeX field." 3657on a BibTeX field. If optional arg HELP is non-nil print help message.
3644 (interactive "P") 3658When called interactively, the value of HELP is `bibtex-help-message'."
3645 (let* ((pnt (point)) 3659 (interactive (list current-prefix-arg nil bibtex-help-message))
3646 (_ (bibtex-inside-field)) 3660 (let ((pnt (point))
3647 (bounds (bibtex-enclosing-field t))) 3661 (bounds (bibtex-find-text-internal)))
3648 (beginning-of-line) 3662 (beginning-of-line)
3649 (cond (bounds 3663 (cond (bounds
3650 (if begin 3664 (if begin
3651 (progn (goto-char (bibtex-start-of-text-in-field bounds)) 3665 (progn (goto-char (nth 1 bounds))
3652 (if (looking-at "[{\"]") 3666 (if (looking-at "[{\"]")
3653 (forward-char))) 3667 (forward-char)))
3654 (goto-char (bibtex-end-of-text-in-field bounds)) 3668 (goto-char (nth 2 bounds))
3655 (if (or (= (preceding-char) ?}) 3669 (if (memq (preceding-char) '(?} ?\"))
3656 (= (preceding-char) ?\"))
3657 (forward-char -1))) 3670 (forward-char -1)))
3658 (if bibtex-help-message 3671 (if help (bibtex-print-help-message)))
3659 (bibtex-print-help-message)))
3660 ((setq bounds (bibtex-parse-string))
3661 (goto-char (if begin
3662 (1+ (bibtex-start-of-text-in-string bounds))
3663 (1- (bibtex-end-of-text-in-string bounds)))))
3664 ((looking-at bibtex-entry-maybe-empty-head) 3672 ((looking-at bibtex-entry-maybe-empty-head)
3665 (goto-char (if begin 3673 (goto-char (if begin
3666 (match-beginning bibtex-key-in-head) 3674 (match-beginning bibtex-key-in-head)
@@ -3669,6 +3677,56 @@ on a BibTeX field."
3669 (goto-char pnt) 3677 (goto-char pnt)
3670 (unless noerror (error "Not on BibTeX field")))))) 3678 (unless noerror (error "Not on BibTeX field"))))))
3671 3679
3680(defun bibtex-find-text-internal (&optional noerror subfield)
3681 "Find text part of current BibTeX field, @String or @Preamble.
3682Return list (NAME START END) with field name, start and end of text
3683or nil if not found.
3684If optional arg NOERROR is non-nil, an error message is suppressed if text
3685is not found. If optional arg SUBFIELD is non-nil START and END correspond
3686to the current subfield delimited by #."
3687 (save-excursion
3688 (let ((pnt (point))
3689 (_ (bibtex-inside-field))
3690 (bounds (bibtex-enclosing-field t))
3691 (case-fold-search t)
3692 (bibtex-string-empty-key t)
3693 name start end)
3694 (bibtex-beginning-of-entry)
3695 (cond (bounds
3696 (setq name (bibtex-name-in-field bounds t)
3697 start (bibtex-start-of-text-in-field bounds)
3698 end (bibtex-end-of-text-in-field bounds)))
3699 ;; @String
3700 ((setq bounds (bibtex-parse-string))
3701 (setq name "@String" ;; not a field name!
3702 start (bibtex-start-of-text-in-string bounds)
3703 end (bibtex-end-of-text-in-string bounds)))
3704 ;; @Preamble
3705 ((and (bibtex-preamble-prefix t)
3706 (setq bounds (bibtex-parse-field-text)))
3707 (setq name "@Preamble" ;; not a field name!
3708 start (car bounds)
3709 end (nth 1 bounds)))
3710 (t (unless noerror (error "Not on BibTeX field"))))
3711 (when (and start end subfield)
3712 (goto-char start)
3713 (let (done)
3714 (while (not done)
3715 (if (or (prog1 (looking-at bibtex-field-const)
3716 (setq end (match-end 0)))
3717 (prog1 (setq bounds (bibtex-parse-field-string))
3718 (setq end (cdr bounds))))
3719 (progn
3720 (if (and (<= start pnt) (<= pnt end))
3721 (setq done t)
3722 (goto-char end))
3723 (if (looking-at "[ \t\n]*#[ \t\n]*")
3724 (setq start (goto-char (match-end 0)))))
3725 (unless noerror (error "Not on text part of BibTeX field"))
3726 (setq done t start nil end nil)))))
3727 (if (and start end)
3728 (list name start end)))))
3729
3672(defun bibtex-remove-OPT-or-ALT () 3730(defun bibtex-remove-OPT-or-ALT ()
3673 "Remove the string starting optional/alternative fields. 3731 "Remove the string starting optional/alternative fields.
3674Align text and go thereafter to end of text." 3732Align text and go thereafter to end of text."
@@ -3695,17 +3753,16 @@ Align text and go thereafter to end of text."
3695 (bibtex-inside-field))) 3753 (bibtex-inside-field)))
3696 3754
3697(defun bibtex-remove-delimiters () 3755(defun bibtex-remove-delimiters ()
3698 "Remove \"\" or {} around string." 3756 "Remove \"\" or {} around current BibTeX field text."
3699 (interactive) 3757 (interactive)
3700 (save-excursion 3758 ;; `bibtex-find-text-internal' issues an error message if bounds is nil.
3701 (bibtex-inside-field) 3759 (let* ((bounds (bibtex-find-text-internal nil t))
3702 (let* ((bounds (bibtex-enclosing-field)) 3760 (start (nth 1 bounds))
3703 (end (bibtex-end-of-text-in-field bounds)) 3761 (end (nth 2 bounds)))
3704 (start (bibtex-start-of-text-in-field bounds))) 3762 (if (memq (char-before end) '(?\} ?\"))
3705 (if (memq (char-before end) '(?\} ?\")) 3763 (delete-region (1- end) end))
3706 (delete-region (1- end) end)) 3764 (if (memq (char-after start) '(?\{ ?\"))
3707 (if (memq (char-after start) '(?\{ ?\")) 3765 (delete-region start (1+ start)))))
3708 (delete-region start (1+ start))))))
3709 3766
3710(defun bibtex-kill-field (&optional copy-only) 3767(defun bibtex-kill-field (&optional copy-only)
3711 "Kill the entire enclosing BibTeX field. 3768 "Kill the entire enclosing BibTeX field.
@@ -3719,7 +3776,7 @@ but do not actually kill it."
3719 (end (bibtex-end-of-field bounds)) 3776 (end (bibtex-end-of-field bounds))
3720 (beg (bibtex-start-of-field bounds))) 3777 (beg (bibtex-start-of-field bounds)))
3721 (goto-char end) 3778 (goto-char end)
3722 (skip-chars-forward " \t\n,") 3779 (skip-chars-forward ",")
3723 (push (list (bibtex-name-in-field bounds) nil 3780 (push (list (bibtex-name-in-field bounds) nil
3724 (bibtex-text-in-field-bounds bounds)) 3781 (bibtex-text-in-field-bounds bounds))
3725 bibtex-field-kill-ring) 3782 bibtex-field-kill-ring)
@@ -3803,9 +3860,9 @@ comes the newest one."
3803 (let ((bounds (bibtex-enclosing-field))) 3860 (let ((bounds (bibtex-enclosing-field)))
3804 (goto-char (bibtex-start-of-text-in-field bounds)) 3861 (goto-char (bibtex-start-of-text-in-field bounds))
3805 (delete-region (point) (bibtex-end-of-text-in-field bounds)) 3862 (delete-region (point) (bibtex-end-of-text-in-field bounds))
3806 (insert (concat (bibtex-field-left-delimiter) 3863 (insert (bibtex-field-left-delimiter)
3807 (bibtex-field-right-delimiter)) ) 3864 (bibtex-field-right-delimiter))
3808 (bibtex-find-text t))) 3865 (bibtex-find-text t nil bibtex-help-message)))
3809 3866
3810(defun bibtex-pop-previous (arg) 3867(defun bibtex-pop-previous (arg)
3811 "Replace text of current field with the similar field in previous entry. 3868 "Replace text of current field with the similar field in previous entry.
@@ -3837,7 +3894,7 @@ At end of the cleaning process, the functions in
3837 (interactive "P") 3894 (interactive "P")
3838 (let ((case-fold-search t) 3895 (let ((case-fold-search t)
3839 (start (bibtex-beginning-of-entry)) 3896 (start (bibtex-beginning-of-entry))
3840 (_ (looking-at bibtex-entry-maybe-empty-head)) 3897 (_ (looking-at bibtex-any-entry-maybe-empty-head))
3841 (entry-type (bibtex-type-in-head)) 3898 (entry-type (bibtex-type-in-head))
3842 (key (bibtex-key-in-head))) 3899 (key (bibtex-key-in-head)))
3843 ;; formatting 3900 ;; formatting
@@ -3994,18 +4051,18 @@ If `bibtex-align-at-equal-sign' is non-nil, align equal signs, too."
3994 "Realign BibTeX entries such that they are separated by one blank line." 4051 "Realign BibTeX entries such that they are separated by one blank line."
3995 (goto-char (point-min)) 4052 (goto-char (point-min))
3996 (let ((case-fold-search t) 4053 (let ((case-fold-search t)
3997 (valid-entry (concat "[ \t\n]*\\(" bibtex-valid-entry-re "\\)"))) 4054 (entry-type (concat "[ \t\n]*\\(" bibtex-entry-type "\\)")))
3998 ;; No blank lines prior to the first valid entry if there no 4055 ;; No blank lines prior to the first entry if there no
3999 ;; non-white characters in front of it. 4056 ;; non-white characters in front of it.
4000 (when (looking-at valid-entry) 4057 (when (looking-at entry-type)
4001 (replace-match "\\1")) 4058 (replace-match "\\1"))
4002 ;; Valid entries are separated by one blank line. 4059 ;; Entries are separated by one blank line.
4003 (while (re-search-forward valid-entry nil t) 4060 (while (re-search-forward entry-type nil t)
4004 (replace-match "\n\n\\1")) 4061 (replace-match "\n\n\\1"))
4005 ;; One blank line past the last valid entry if it is followed by 4062 ;; One blank line past the last entry if it is followed by
4006 ;; non-white characters, no blank line otherwise. 4063 ;; non-white characters, no blank line otherwise.
4007 (beginning-of-line) 4064 (beginning-of-line)
4008 (when (re-search-forward bibtex-valid-entry-re nil t) 4065 (when (re-search-forward bibtex-entry-type nil t)
4009 (bibtex-end-of-entry) 4066 (bibtex-end-of-entry)
4010 (bibtex-delete-whitespace) 4067 (bibtex-delete-whitespace)
4011 (open-line (if (eobp) 1 2))))) 4068 (open-line (if (eobp) 1 2)))))
@@ -4101,11 +4158,13 @@ entries from minibuffer."
4101If point is inside key or crossref field perform key completion based on 4158If point is inside key or crossref field perform key completion based on
4102`bibtex-reference-keys'. Inside a month field perform key completion 4159`bibtex-reference-keys'. Inside a month field perform key completion
4103based on `bibtex-predefined-month-strings'. Inside any other field 4160based on `bibtex-predefined-month-strings'. Inside any other field
4104perform string completion based on `bibtex-strings'. An error is 4161\(including a String or Preamble definition) perform string completion
4105signaled if point is outside key or BibTeX field." 4162based on `bibtex-strings'.
4163An error is signaled if point is outside key or BibTeX field."
4106 (interactive) 4164 (interactive)
4107 (let ((pnt (point)) 4165 (let ((pnt (point))
4108 (case-fold-search t) 4166 (case-fold-search t)
4167 (bibtex-string-empty-key t)
4109 bounds name compl) 4168 bounds name compl)
4110 (save-excursion 4169 (save-excursion
4111 (if (and (setq bounds (bibtex-enclosing-field t)) 4170 (if (and (setq bounds (bibtex-enclosing-field t))
@@ -4119,22 +4178,23 @@ signaled if point is outside key or BibTeX field."
4119 ;; point is in month field 4178 ;; point is in month field
4120 bibtex-predefined-month-strings) 4179 bibtex-predefined-month-strings)
4121 ;; point is in other field 4180 ;; point is in other field
4122 (t (if (listp bibtex-strings) 4181 (t (bibtex-strings))))
4123 bibtex-strings
4124 ;; so that bibtex-complete-string-cleanup
4125 ;; can do its job
4126 (bibtex-parse-strings
4127 (bibtex-string-files-init))))))
4128 (bibtex-beginning-of-entry) 4182 (bibtex-beginning-of-entry)
4129 (cond ((and (looking-at bibtex-string-maybe-empty-head) 4183 (cond ((setq bounds (bibtex-parse-string))
4130 ;; point is inside a string key 4184 ;; point is inside a @String key
4131 (or (and (match-beginning bibtex-key-in-head) 4185 (cond ((and (>= pnt (nth 1 (car bounds)))
4132 (>= pnt (match-beginning bibtex-key-in-head)) 4186 (<= pnt (nth 2 (car bounds))))
4133 (<= pnt (match-end bibtex-key-in-head))) 4187 (setq compl 'string))
4134 ;; or point is on empty string key 4188 ;; point is inside a @String field
4135 (and (not (match-beginning bibtex-key-in-head)) 4189 ((and (>= pnt (bibtex-start-of-text-in-string bounds))
4136 (= pnt (match-end 0))))) 4190 (<= pnt (bibtex-end-of-text-in-string bounds)))
4137 (setq compl 'string)) 4191 (setq compl (bibtex-strings)))))
4192 ;; point is inside a @Preamble field
4193 ((and (bibtex-preamble-prefix t)
4194 (setq bounds (bibtex-parse-field-text))
4195 (>= pnt (car bounds))
4196 (<= pnt (nth 1 bounds)))
4197 (setq compl (bibtex-strings)))
4138 ((and (looking-at bibtex-entry-maybe-empty-head) 4198 ((and (looking-at bibtex-entry-maybe-empty-head)
4139 ;; point is inside a key 4199 ;; point is inside a key
4140 (or (and (match-beginning bibtex-key-in-head) 4200 (or (and (match-beginning bibtex-key-in-head)
@@ -4282,8 +4342,8 @@ signaled if point is outside key or BibTeX field."
4282 (bibtex-entry-left-delimiter) 4342 (bibtex-entry-left-delimiter)
4283 (bibtex-field-left-delimiter)) 4343 (bibtex-field-left-delimiter))
4284 (let ((endpos (point))) 4344 (let ((endpos (point)))
4285 (insert (bibtex-entry-right-delimiter) 4345 (insert (bibtex-field-right-delimiter)
4286 (bibtex-field-right-delimiter) 4346 (bibtex-entry-right-delimiter)
4287 "\n") 4347 "\n")
4288 (goto-char endpos))) 4348 (goto-char endpos)))
4289 4349
@@ -4296,7 +4356,8 @@ The URL is generated using the schemes defined in `bibtex-generate-url-list'
4296 (save-excursion 4356 (save-excursion
4297 (if pos (goto-char pos)) 4357 (if pos (goto-char pos))
4298 (bibtex-beginning-of-entry) 4358 (bibtex-beginning-of-entry)
4299 (let ((fields-alist (bibtex-parse-entry)) 4359 ;; Always remove field delimiters
4360 (let ((fields-alist (bibtex-parse-entry t))
4300 ;; Always ignore case, 4361 ;; Always ignore case,
4301 (case-fold-search t) 4362 (case-fold-search t)
4302 (lst bibtex-generate-url-list) 4363 (lst bibtex-generate-url-list)
@@ -4304,18 +4365,14 @@ The URL is generated using the schemes defined in `bibtex-generate-url-list'
4304 (while (setq scheme (pop lst)) 4365 (while (setq scheme (pop lst))
4305 (when (and (setq field (cdr (assoc-string (caar scheme) 4366 (when (and (setq field (cdr (assoc-string (caar scheme)
4306 fields-alist t))) 4367 fields-alist t)))
4307 ;; Always remove field delimiters 4368 (string-match (cdar scheme) field))
4308 (progn (setq field (bibtex-remove-delimiters-string field))
4309 (string-match (cdar scheme) field)))
4310 (setq lst nil 4369 (setq lst nil
4311 scheme (cdr scheme) 4370 scheme (cdr scheme)
4312 url (if (null scheme) (match-string 0 field) 4371 url (if (null scheme) (match-string 0 field)
4313 (if (stringp (car scheme)) 4372 (if (stringp (car scheme))
4314 (setq fmt (pop scheme))) 4373 (setq fmt (pop scheme)))
4315 (dolist (step scheme) 4374 (dolist (step scheme)
4316 ;; Always remove field delimiters 4375 (setq field (cdr (assoc-string (car step) fields-alist t)))
4317 (setq field (bibtex-remove-delimiters-string
4318 (cdr (assoc-string (car step) fields-alist t))))
4319 (if (string-match (nth 1 step) field) 4376 (if (string-match (nth 1 step) field)
4320 (setq field (cond ((functionp (nth 2 step)) 4377 (setq field (cond ((functionp (nth 2 step))
4321 (funcall (nth 2 step) field)) 4378 (funcall (nth 2 step) field))