Mercurial > emacs
comparison lisp/textmodes/bibtex.el @ 90261:7beb78bc1f8e
Revision: miles@gnu.org--gnu-2005/emacs--unicode--0--patch-97
Merge from emacs--cvs-trunk--0
Patches applied:
* emacs--cvs-trunk--0 (patch 616-696)
- Add lisp/mh-e/.arch-inventory
- Update from CVS
- Merge from gnus--rel--5.10
- Update from CVS: lisp/smerge-mode.el: Add 'tools' to file keywords.
- lisp/gnus/ChangeLog: Remove duplicate entry
* gnus--rel--5.10 (patch 147-181)
- Update from CVS
- Merge from emacs--cvs-trunk--0
- Update from CVS: lisp/mml.el (mml-preview): Doc fix.
- Update from CVS: texi/message.texi: Fix default values.
- Update from CVS: texi/gnus.texi (RSS): Addition.
author | Miles Bader <miles@gnu.org> |
---|---|
date | Mon, 16 Jan 2006 08:37:27 +0000 |
parents | 0ca0d9181b5e 0624a54493b5 |
children | 5b7d410e31f9 |
comparison
equal
deleted
inserted
replaced
90260:0ca0d9181b5e | 90261:7beb78bc1f8e |
---|---|
549 "String to append to the generated key if not all names could be used. | 549 "String to append to the generated key if not all names could be used. |
550 See `bibtex-generate-autokey' for details." | 550 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. | |
556 See `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 |
557 ("\\\\AA" . "A") ; \AA -> A | 563 ("\\\\AA" . "A") ; \AA -> A |
558 ("\\\"a\\|\\\\\\\"a\\|\\\\ae" . "ae") ; "a,\"a,\ae -> ae | 564 ("\\\"a\\|\\\\\\\"a\\|\\\\ae" . "ae") ; "a,\"a,\ae -> ae |
807 REPLACE can be a string, or a number (which selects the corresponding | 813 REPLACE can be a string, or a number (which selects the corresponding |
808 submatch), or a function called with the field's text as argument | 814 submatch), or a function called with the field's text as argument |
809 and with the `match-data' properly set. | 815 and with the `match-data' properly set. |
810 | 816 |
811 Case is always ignored. Always remove the field delimiters. | 817 Case is always ignored. Always remove the field delimiters. |
818 If `bibtex-expand-strings' is non-nil, BibTeX strings are expanded | |
819 for generating the URL. | |
812 | 820 |
813 The following is a complex example, see http://link.aps.org/linkfaq.html. | 821 The following is a complex example, see http://link.aps.org/linkfaq.html. |
814 | 822 |
815 (((\"journal\" . \"\\\\=<\\(PR[ABCDEL]?\\|RMP\\)\\\\=>\") | 823 (((\"journal\" . \"\\\\=<\\(PR[ABCDEL]?\\|RMP\\)\\\\=>\") |
816 \"http://link.aps.org/abstract/%s/v%s/p%s\" | 824 \"http://link.aps.org/abstract/%s/v%s/p%s\" |
838 (regexp :tag "Regexp") | 846 (regexp :tag "Regexp") |
839 (choice (string :tag "Replacement") | 847 (choice (string :tag "Replacement") |
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, too. 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) |
852 (modify-syntax-entry ?$ "$$ " st) | 865 (modify-syntax-entry ?$ "$$ " st) |
853 (modify-syntax-entry ?% "< " st) | 866 (modify-syntax-entry ?% "< " st) |
1029 (defvar bibtex-last-kill-command nil | 1042 (defvar bibtex-last-kill-command nil |
1030 "Type of the last kill command (either 'field or 'entry).") | 1043 "Type of the last kill command (either 'field or 'entry).") |
1031 | 1044 |
1032 (defvar bibtex-strings | 1045 (defvar bibtex-strings |
1033 (lazy-completion-table bibtex-strings | 1046 (lazy-completion-table bibtex-strings |
1034 bibtex-parse-strings (bibtex-string-files-init)) | 1047 (lambda () |
1048 (bibtex-parse-strings (bibtex-string-files-init)))) | |
1035 "Completion table for BibTeX string keys. | 1049 "Completion table for BibTeX string keys. |
1036 Initialized from `bibtex-predefined-strings' and `bibtex-string-files'.") | 1050 Initialized from `bibtex-predefined-strings' and `bibtex-string-files'.") |
1037 (make-variable-buffer-local 'bibtex-strings) | 1051 (make-variable-buffer-local 'bibtex-strings) |
1038 | 1052 |
1039 (defvar bibtex-reference-keys | 1053 (defvar bibtex-reference-keys |
1040 (lazy-completion-table bibtex-reference-keys bibtex-parse-keys nil t) | 1054 (lazy-completion-table bibtex-reference-keys |
1055 (lambda () (bibtex-parse-keys nil t))) | |
1041 "Completion table for BibTeX reference keys. | 1056 "Completion table for BibTeX reference keys. |
1042 The CDRs of the elements are t for header keys and nil for crossref keys.") | 1057 The CDRs of the elements are t for header keys and nil for crossref keys.") |
1043 (make-variable-buffer-local 'bibtex-reference-keys) | 1058 (make-variable-buffer-local 'bibtex-reference-keys) |
1044 | 1059 |
1045 (defvar bibtex-buffer-last-parsed-tick nil | 1060 (defvar bibtex-buffer-last-parsed-tick nil |
1071 | 1086 |
1072 (defvar bibtex-reformat-previous-reference-keys nil | 1087 (defvar bibtex-reformat-previous-reference-keys nil |
1073 "Last reformat reference keys option given.") | 1088 "Last reformat reference keys option given.") |
1074 | 1089 |
1075 (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.") | |
1092 | |
1093 (defconst bibtex-name-part | |
1094 (concat ",[ \t\n]*\\(" bibtex-field-name "\\)") | |
1076 "Regexp matching the name part of a BibTeX field.") | 1095 "Regexp matching the name part of a BibTeX field.") |
1077 | |
1078 (defconst bibtex-entry-type (concat "@" bibtex-field-name) | |
1079 "Regexp matching the type part of a BibTeX entry.") | |
1080 | 1096 |
1081 (defconst bibtex-reference-key "[][[:alnum:].:;?!`'/*@+|()<>&_^$-]+" | 1097 (defconst bibtex-reference-key "[][[:alnum:].:;?!`'/*@+|()<>&_^$-]+" |
1082 "Regexp matching the reference key part of a BibTeX entry.") | 1098 "Regexp matching the reference key part of a BibTeX entry.") |
1083 | 1099 |
1084 (defconst bibtex-field-const "[][[:alnum:].:;?!`'/*@+=|<>&_^$-]+" | 1100 (defconst bibtex-field-const "[][[:alnum:].:;?!`'/*@+=|<>&_^$-]+" |
1085 "Regexp matching a BibTeX field constant.") | 1101 "Regexp matching a BibTeX field constant.") |
1086 | 1102 |
1087 (defconst bibtex-entry-head | 1103 (defvar bibtex-entry-type |
1104 (concat "@[ \t]*\\(?:" | |
1105 (regexp-opt (mapcar 'car bibtex-entry-field-alist)) "\\)") | |
1106 "Regexp matching the name of a BibTeX entry.") | |
1107 | |
1108 (defvar bibtex-entry-head | |
1088 (concat "^[ \t]*\\(" | 1109 (concat "^[ \t]*\\(" |
1089 bibtex-entry-type | 1110 bibtex-entry-type |
1090 "\\)[ \t]*[({][ \t\n]*\\(" | 1111 "\\)[ \t]*[({][ \t\n]*\\(" |
1091 bibtex-reference-key | 1112 bibtex-reference-key |
1092 "\\)") | 1113 "\\)") |
1093 "Regexp matching the header line of a BibTeX entry.") | 1114 "Regexp matching the header line of a BibTeX entry (including key).") |
1094 | 1115 |
1095 (defconst bibtex-entry-maybe-empty-head | 1116 (defvar bibtex-entry-maybe-empty-head |
1096 (concat bibtex-entry-head "?") | 1117 (concat bibtex-entry-head "?") |
1097 "Regexp matching the header line of a BibTeX entry (possibly without key).") | 1118 "Regexp matching the header line of a BibTeX entry (possibly without key).") |
1098 | 1119 |
1120 (defconst bibtex-any-entry-maybe-empty-head | |
1121 (concat "^[ \t]*\\(@[ \t]*" bibtex-field-name "\\)[ \t]*[({][ \t\n]*\\(" | |
1122 bibtex-reference-key "\\)?") | |
1123 "Regexp matching the header line of any BibTeX entry (possibly without key).") | |
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 | |
1099 (defconst bibtex-type-in-head 1 | 1131 (defconst bibtex-type-in-head 1 |
1100 "Regexp subexpression number of the type part in `bibtex-entry-head'.") | 1132 "Regexp subexpression number of the type part in `bibtex-entry-head'.") |
1101 | 1133 |
1102 (defconst bibtex-key-in-head 2 | 1134 (defconst bibtex-key-in-head 2 |
1103 "Regexp subexpression number of the key part in `bibtex-entry-head'.") | 1135 "Regexp subexpression number of the key part in `bibtex-entry-head'.") |
1104 | 1136 |
1137 (defconst bibtex-string-type "^[ \t]*\\(@[ \t]*String\\)[ \t]*[({][ \t\n]*" | |
1138 "Regexp matching the name of a BibTeX String entry.") | |
1139 | |
1105 (defconst bibtex-string-maybe-empty-head | 1140 (defconst bibtex-string-maybe-empty-head |
1106 (concat "^[ \t]*\\(@String\\)[ \t]*[({]\\(" | 1141 (concat bibtex-string-type "\\(" bibtex-reference-key "\\)?") |
1107 bibtex-reference-key | |
1108 "\\)?") | |
1109 "Regexp matching the header line of a BibTeX String entry.") | 1142 "Regexp matching the header line of a BibTeX String entry.") |
1110 | 1143 |
1111 (defconst bibtex-entry-postfix "[ \t\n]*,?[ \t\n]*[})]" | 1144 (defconst bibtex-preamble-prefix |
1112 "Regexp matching the postfix of a BibTeX entry.") | 1145 "[ \t]*\\(@[ \t]*Preamble\\)[ \t]*[({][ \t\n]*" |
1113 | 1146 "Regexp matching the prefix part of a BibTeX Preamble entry.") |
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 | |
1122 (defvar bibtex-valid-entry-whitespace-re | |
1123 (concat "[ \t]*\\(" bibtex-valid-entry-re "\\)") | |
1124 "Regexp matching the name of a valid BibTeX entry preceded by whitespace.") | |
1125 | |
1126 (defvar bibtex-any-valid-entry-re | |
1127 (concat "@[ \t]*" | |
1128 (regexp-opt (append '("String") | |
1129 (mapcar 'car bibtex-entry-field-alist)) | |
1130 t)) | |
1131 "Regexp matching the name of any valid BibTeX entry (including string).") | |
1132 | |
1133 (defconst bibtex-empty-field-re "\\`\\(\"\"\\|{}\\)\\'" | |
1134 "Regexp matching the text part (as a string) of an empty field.") | |
1135 | 1147 |
1136 (defconst bibtex-font-lock-syntactic-keywords | 1148 (defconst bibtex-font-lock-syntactic-keywords |
1137 `((,(concat "^[ \t]*\\(" (substring bibtex-comment-start 0 1) "\\)" | 1149 `((,(concat "^[ \t]*\\(" (substring bibtex-comment-start 0 1) "\\)" |
1138 (substring bibtex-comment-start 1) "\\>") | 1150 (substring bibtex-comment-start 1) "\\>") |
1139 1 '(11)))) | 1151 1 '(11)))) |
1140 | 1152 |
1141 (defvar bibtex-font-lock-keywords | 1153 (defvar bibtex-font-lock-keywords |
1142 ;; entry type and reference key | 1154 ;; entry type and reference key |
1143 `((,bibtex-entry-maybe-empty-head | 1155 `((,bibtex-any-entry-maybe-empty-head |
1144 (,bibtex-type-in-head font-lock-function-name-face) | 1156 (,bibtex-type-in-head font-lock-function-name-face) |
1145 (,bibtex-key-in-head font-lock-constant-face nil t)) | 1157 (,bibtex-key-in-head font-lock-constant-face nil t)) |
1146 ;; optional field names (treated as comments) | 1158 ;; optional field names (treated as comments) |
1147 (,(concat "^[ \t]*\\(OPT" bibtex-field-name "\\)[ \t]*=") | 1159 (,(concat "^[ \t]*\\(OPT" bibtex-field-name "\\)[ \t]*=") |
1148 1 font-lock-comment-face) | 1160 1 font-lock-comment-face) |
1158 (concat "^[ \t]*" | 1170 (concat "^[ \t]*" |
1159 (regexp-opt (delete-dups (mapcar 'caar bibtex-generate-url-list)) t) | 1171 (regexp-opt (delete-dups (mapcar 'caar bibtex-generate-url-list)) t) |
1160 "[ \t]*=[ \t]*") | 1172 "[ \t]*=[ \t]*") |
1161 "Regexp for `bibtex-font-lock-url'.") | 1173 "Regexp for `bibtex-font-lock-url'.") |
1162 | 1174 |
1163 (defvar bibtex-field-name-for-parsing nil | 1175 (defvar bibtex-string-empty-key nil |
1164 "Regexp of field name to be parsed by function `bibtex-parse-field-name'. | 1176 "If non-nil, `bibtex-parse-string' accepts empty key.") |
1165 Passed by dynamic scoping.") | |
1166 | 1177 |
1167 (defvar bibtex-sort-entry-class-alist | 1178 (defvar bibtex-sort-entry-class-alist |
1168 (let ((i -1) alist) | 1179 (let ((i -1) alist) |
1169 (dolist (class bibtex-sort-entry-class alist) | 1180 (dolist (class bibtex-sort-entry-class alist) |
1170 (setq i (1+ i)) | 1181 (setq i (1+ i)) |
1191 | 1202 |
1192 (defun bibtex-parse-association (parse-lhs parse-rhs) | 1203 (defun bibtex-parse-association (parse-lhs parse-rhs) |
1193 "Parse a string of the format <left-hand-side = right-hand-side>. | 1204 "Parse a string of the format <left-hand-side = right-hand-side>. |
1194 The functions PARSE-LHS and PARSE-RHS are used to parse the corresponding | 1205 The functions PARSE-LHS and PARSE-RHS are used to parse the corresponding |
1195 substrings. These functions are expected to return nil if parsing is not | 1206 substrings. These functions are expected to return nil if parsing is not |
1196 successful. If both functions return non-nil, a pair containing the returned | 1207 successful. If the returned values of both functions are non-nil, |
1197 values of the functions PARSE-LHS and PARSE-RHS is returned." | 1208 return a cons pair of these values. Do not move point." |
1198 (save-match-data | 1209 (save-match-data |
1199 (save-excursion | 1210 (save-excursion |
1200 (let ((left (funcall parse-lhs)) | 1211 (let ((left (funcall parse-lhs)) |
1201 right) | 1212 right) |
1202 (if (and left | 1213 (if (and left |
1204 (goto-char (match-end 0)) | 1215 (goto-char (match-end 0)) |
1205 (setq right (funcall parse-rhs))) | 1216 (setq right (funcall parse-rhs))) |
1206 (cons left right)))))) | 1217 (cons left right)))))) |
1207 | 1218 |
1208 (defun bibtex-parse-field-name () | 1219 (defun bibtex-parse-field-name () |
1209 "Parse the field name stored in `bibtex-field-name-for-parsing'. | 1220 "Parse the name part of a BibTeX field. |
1210 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 |
1211 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 |
1212 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. |
1213 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 |
1214 BibTeX field as necessary." | 1225 BibTeX field as necessary." |
1215 (cond ((looking-at ",[ \t\n]*") | 1226 (cond ((looking-at bibtex-name-part) |
1216 (let ((start (point))) | 1227 (goto-char (match-end 0)) |
1217 (goto-char (match-end 0)) | 1228 (list (match-beginning 0) (match-beginning 1) (match-end 0))) |
1218 (when (looking-at bibtex-field-name-for-parsing) | |
1219 (goto-char (match-end 0)) | |
1220 (list start (match-beginning 0) (match-end 0))))) | |
1221 ;; Maybe add a missing comma. | 1229 ;; Maybe add a missing comma. |
1222 ((and bibtex-autoadd-commas | 1230 ((and bibtex-autoadd-commas |
1223 (looking-at (concat "[ \t\n]*\\(?:" bibtex-field-name-for-parsing | 1231 (looking-at (concat "[ \t\n]*\\(?:" bibtex-field-name |
1224 "\\)[ \t\n]*="))) | 1232 "\\)[ \t\n]*="))) |
1225 (skip-chars-backward " \t\n") | 1233 (skip-chars-backward " \t\n") |
1234 ;; It can be confusing if non-editing commands try to | |
1235 ;; modify the buffer. | |
1236 (if buffer-read-only | |
1237 (error "Comma missing at buffer position %s" (point))) | |
1226 (insert ",") | 1238 (insert ",") |
1227 (forward-char -1) | 1239 (forward-char -1) |
1228 ;; Now try again. | 1240 ;; Now try again. |
1229 (bibtex-parse-field-name)))) | 1241 (bibtex-parse-field-name)))) |
1230 | 1242 |
1249 "Syntax-table to parse matched quotes.") | 1261 "Syntax-table to parse matched quotes.") |
1250 | 1262 |
1251 (defun bibtex-parse-field-string () | 1263 (defun bibtex-parse-field-string () |
1252 "Parse a BibTeX field string enclosed by braces or quotes. | 1264 "Parse a BibTeX field string enclosed by braces or quotes. |
1253 If a syntactically correct string is found, a pair containing the start and | 1265 If a syntactically correct string is found, a pair containing the start and |
1254 end position of the field string is returned, nil otherwise." | 1266 end position of the field string is returned, nil otherwise. |
1267 Do not move point." | |
1255 (let ((end-point | 1268 (let ((end-point |
1256 (or (and (eq (following-char) ?\") | 1269 (or (and (eq (following-char) ?\") |
1257 (save-excursion | 1270 (save-excursion |
1258 (with-syntax-table bibtex-quoted-string-syntax-table | 1271 (with-syntax-table bibtex-quoted-string-syntax-table |
1259 (forward-sexp 1)) | 1272 (forward-sexp 1)) |
1281 (goto-char (cdr boundaries))) | 1294 (goto-char (cdr boundaries))) |
1282 ((setq failure t))) | 1295 ((setq failure t))) |
1283 (if (looking-at "[ \t\n]*#[ \t\n]*") | 1296 (if (looking-at "[ \t\n]*#[ \t\n]*") |
1284 (goto-char (match-end 0)) | 1297 (goto-char (match-end 0)) |
1285 (setq end-point (point)))) | 1298 (setq end-point (point)))) |
1299 (skip-chars-forward " \t\n") | |
1286 (if (and (not failure) | 1300 (if (and (not failure) |
1287 end-point) | 1301 end-point) |
1288 (cons starting-point end-point)))) | 1302 (list starting-point end-point (point))))) |
1289 | 1303 |
1290 (defun bibtex-parse-field (name) | 1304 (defun bibtex-parse-field () |
1291 "Parse a BibTeX field of regexp NAME. | 1305 "Parse the BibTeX field beginning at the position of point. |
1292 If a syntactically correct field is found, a pair containing the boundaries of | 1306 If a syntactically correct field is found, return a cons pair containing |
1293 the name and text parts of the field is returned." | 1307 the boundaries of the name and text parts of the field. Do not move point." |
1294 (let ((bibtex-field-name-for-parsing name)) | 1308 (bibtex-parse-association 'bibtex-parse-field-name |
1295 (bibtex-parse-association 'bibtex-parse-field-name | 1309 'bibtex-parse-field-text)) |
1296 'bibtex-parse-field-text))) | |
1297 | |
1298 (defun bibtex-search-forward-field (name &optional bound) | |
1299 "Search forward to find a BibTeX field of name NAME. | |
1300 If a syntactically correct field is found, a pair containing the boundaries of | |
1301 the name and text parts of the field is returned. The search is limited by | |
1302 optional arg BOUND. If BOUND is t the search is limited by the end of the | |
1303 current entry. Do not move point." | |
1304 (save-match-data | |
1305 (save-excursion | |
1306 (unless (integer-or-marker-p bound) | |
1307 (setq bound (if bound | |
1308 (save-excursion (bibtex-end-of-entry)) | |
1309 (point-max)))) | |
1310 (let ((case-fold-search t) | |
1311 (bibtex-field-name-for-parsing name) | |
1312 boundaries temp-boundaries) | |
1313 (while (and (not boundaries) | |
1314 (< (point) bound) | |
1315 (search-forward "," bound t)) | |
1316 (goto-char (match-beginning 0)) | |
1317 (if (and (setq temp-boundaries | |
1318 (bibtex-parse-association 'bibtex-parse-field-name | |
1319 'bibtex-parse-field-text)) | |
1320 (<= (cddr temp-boundaries) bound)) | |
1321 (setq boundaries temp-boundaries) | |
1322 (forward-char 1))) | |
1323 boundaries)))) | |
1324 | |
1325 (defun bibtex-search-backward-field (name &optional bound) | |
1326 "Search backward to find a BibTeX field of name NAME. | |
1327 If a syntactically correct field is found, a pair containing the boundaries of | |
1328 the name and text parts of the field is returned. The search is limited by | |
1329 optional arg BOUND. If BOUND is t the search is limited by the beginning of the | |
1330 current entry. Do not move point." | |
1331 (save-match-data | |
1332 (save-excursion | |
1333 (unless (integer-or-marker-p bound) | |
1334 (setq bound (if bound | |
1335 (save-excursion (bibtex-beginning-of-entry)) | |
1336 (point-min)))) | |
1337 (let ((case-fold-search t) | |
1338 (bibtex-field-name-for-parsing name) | |
1339 boundaries temp-boundaries) | |
1340 (while (and (not boundaries) | |
1341 (>= (point) bound) | |
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 | 1310 |
1349 (defsubst bibtex-start-of-field (bounds) | 1311 (defsubst bibtex-start-of-field (bounds) |
1350 (nth 0 (car bounds))) | 1312 (nth 0 (car bounds))) |
1351 (defsubst bibtex-start-of-name-in-field (bounds) | 1313 (defsubst bibtex-start-of-name-in-field (bounds) |
1352 (nth 1 (car bounds))) | 1314 (nth 1 (car bounds))) |
1353 (defsubst bibtex-end-of-name-in-field (bounds) | 1315 (defsubst bibtex-end-of-name-in-field (bounds) |
1354 (nth 2 (car bounds))) | 1316 (nth 2 (car bounds))) |
1317 (defsubst bibtex-start-of-text-in-field (bounds) | |
1318 (nth 1 bounds)) | |
1319 (defsubst bibtex-end-of-text-in-field (bounds) | |
1320 (nth 2 bounds)) | |
1355 (defsubst bibtex-end-of-field (bounds) | 1321 (defsubst bibtex-end-of-field (bounds) |
1356 (cddr bounds)) | 1322 (nth 3 bounds)) |
1357 (defsubst bibtex-start-of-text-in-field (bounds) | 1323 |
1358 (cadr bounds)) | 1324 (defun bibtex-search-forward-field (name &optional bound) |
1359 (defsubst bibtex-end-of-text-in-field (bounds) | 1325 "Search forward to find a BibTeX field of name NAME. |
1360 (cddr bounds)) | 1326 If a syntactically correct field is found, return a pair containing |
1327 the boundaries of the name and text parts of the field. The search | |
1328 is limited by optional arg BOUND. If BOUND is t the search is limited | |
1329 by the end of the current entry. Do not move point." | |
1330 (save-match-data | |
1331 (save-excursion | |
1332 (if (eq bound t) | |
1333 (let ((regexp (concat bibtex-name-part "[ \t\n]*=\\|" | |
1334 bibtex-any-entry-maybe-empty-head)) | |
1335 (case-fold-search t) bounds) | |
1336 (catch 'done | |
1337 (if (looking-at "[ \t]*@") (goto-char (match-end 0))) | |
1338 (while (and (not bounds) | |
1339 (re-search-forward regexp nil t)) | |
1340 (if (match-beginning 2) | |
1341 ;; We found a new entry | |
1342 (throw 'done nil) | |
1343 ;; We found a field | |
1344 (goto-char (match-beginning 0)) | |
1345 (setq bounds (bibtex-parse-field)))) | |
1346 ;; Step through all fields so that we cannot overshoot. | |
1347 (while bounds | |
1348 (goto-char (bibtex-start-of-name-in-field bounds)) | |
1349 (if (looking-at name) (throw 'done bounds)) | |
1350 (goto-char (bibtex-end-of-field bounds)) | |
1351 (setq bounds (bibtex-parse-field))))) | |
1352 ;; Bounded search or bound is nil (i.e. we cannot overshoot). | |
1353 ;; Indeed, the search is bounded when `bibtex-search-forward-field' | |
1354 ;; is called many times. So we optimize this part of this function. | |
1355 (let ((name-part (concat ",[ \t\n]*\\(" name "\\)[ \t\n]*=[ \t\n]*")) | |
1356 (case-fold-search t) left right) | |
1357 (while (and (not right) | |
1358 (re-search-forward name-part bound t)) | |
1359 (setq left (list (match-beginning 0) (match-beginning 1) | |
1360 (match-end 1)) | |
1361 ;; Don't worry that the field text could be past bound. | |
1362 right (bibtex-parse-field-text))) | |
1363 (if right (cons left right))))))) | |
1364 | |
1365 (defun bibtex-search-backward-field (name &optional bound) | |
1366 "Search backward to find a BibTeX field of name NAME. | |
1367 If a syntactically correct field is found, return a pair containing | |
1368 the boundaries of the name and text parts of the field. The search | |
1369 is limited by the optional arg BOUND. If BOUND is t the search is | |
1370 limited by the beginning of the current entry. Do not move point." | |
1371 (save-match-data | |
1372 (if (eq bound t) | |
1373 (setq bound (save-excursion (bibtex-beginning-of-entry)))) | |
1374 (let ((name-part (concat ",[ \t\n]*\\(" name "\\)[ \t\n]*=[ \t\n]*")) | |
1375 (case-fold-search t) left right) | |
1376 (save-excursion | |
1377 ;; the parsing functions are not designed for parsing backwards :-( | |
1378 (when (search-backward "," bound t) | |
1379 (or (save-excursion | |
1380 (when (looking-at name-part) | |
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))))))) | |
1361 | 1393 |
1362 (defun bibtex-name-in-field (bounds &optional remove-opt-alt) | 1394 (defun bibtex-name-in-field (bounds &optional remove-opt-alt) |
1363 "Get content of name in BibTeX field defined via BOUNDS. | 1395 "Get content of name in BibTeX field defined via BOUNDS. |
1364 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\"." |
1365 (let ((name (buffer-substring-no-properties (nth 1 (car bounds)) | 1397 (let ((name (buffer-substring-no-properties |
1366 (nth 2 (car bounds))))) | 1398 (bibtex-start-of-name-in-field bounds) |
1399 (bibtex-end-of-name-in-field bounds)))) | |
1367 (if (and remove-opt-alt | 1400 (if (and remove-opt-alt |
1368 (string-match "\\`\\(OPT\\|ALT\\)" name)) | 1401 (string-match "\\`\\(OPT\\|ALT\\)" name)) |
1369 (substring name 3) | 1402 (substring name 3) |
1370 name))) | 1403 name))) |
1371 | 1404 |
1372 (defun bibtex-text-in-field-bounds (bounds &optional remove-delim) | 1405 (defun bibtex-text-in-field-bounds (bounds &optional content) |
1373 "Get content of text in BibTeX field defined via BOUNDS. | 1406 "Get text in BibTeX field defined via BOUNDS. |
1374 If optional arg REMOVE-DELIM is non-nil remove enclosing field delimiters | 1407 If optional arg CONTENT is non-nil extract content of field |
1375 if present." | 1408 by removing field delimiters and concatenating the resulting string. |
1376 (let ((content (buffer-substring-no-properties (cadr bounds) | 1409 If `bibtex-expand-strings' is non-nil, also expand BibTeX strings." |
1377 (cddr bounds)))) | 1410 (if content |
1378 (if remove-delim | 1411 (save-excursion |
1379 (bibtex-remove-delimiters-string content) | 1412 (goto-char (bibtex-start-of-text-in-field bounds)) |
1380 content))) | 1413 (let ((epoint (bibtex-end-of-text-in-field bounds)) |
1414 content opoint) | |
1415 (while (< (setq opoint (point)) epoint) | |
1416 (if (looking-at bibtex-field-const) | |
1417 (let ((mtch (match-string-no-properties 0))) | |
1418 (push (or (if bibtex-expand-strings | |
1419 (cdr (assoc-string mtch (bibtex-strings) t))) | |
1420 mtch) content) | |
1421 (goto-char (match-end 0))) | |
1422 (let ((bounds (bibtex-parse-field-string))) | |
1423 (push (buffer-substring-no-properties | |
1424 (1+ (car bounds)) (1- (cdr bounds))) content) | |
1425 (goto-char (cdr bounds)))) | |
1426 (re-search-forward "\\=[ \t\n]*#[ \t\n]*" nil t)) | |
1427 (apply 'concat (nreverse content)))) | |
1428 (buffer-substring-no-properties (bibtex-start-of-text-in-field bounds) | |
1429 (bibtex-end-of-text-in-field bounds)))) | |
1381 | 1430 |
1382 (defun bibtex-text-in-field (field &optional follow-crossref) | 1431 (defun bibtex-text-in-field (field &optional follow-crossref) |
1383 "Get content of field FIELD of current BibTeX entry. | 1432 "Get content of field FIELD of current BibTeX entry. |
1384 Return nil if not found. | 1433 Return nil if not found. |
1385 If optional arg FOLLOW-CROSSREF is non-nil, follow crossref." | 1434 If optional arg FOLLOW-CROSSREF is non-nil, follow crossref." |
1386 (save-excursion | 1435 (save-excursion |
1387 (save-restriction | 1436 (let* ((end (if follow-crossref (bibtex-end-of-entry) t)) |
1388 ;; We want to jump back and forth while searching FIELD | 1437 (beg (bibtex-beginning-of-entry)) ; move point |
1389 (bibtex-narrow-to-entry) | 1438 (bounds (bibtex-search-forward-field field end))) |
1390 (goto-char (point-min)) | 1439 (cond (bounds (bibtex-text-in-field-bounds bounds t)) |
1391 (let ((bounds (bibtex-search-forward-field field)) | 1440 ((and follow-crossref |
1392 crossref-field) | 1441 (progn (goto-char beg) |
1393 (cond (bounds (bibtex-text-in-field-bounds bounds t)) | 1442 (setq bounds (bibtex-search-forward-field |
1394 ((and follow-crossref | 1443 "\\(OPT\\)?crossref" end)))) |
1395 (progn (goto-char (point-min)) | 1444 (let ((crossref-field (bibtex-text-in-field-bounds bounds t))) |
1396 (setq bounds (bibtex-search-forward-field | |
1397 "\\(OPT\\)?crossref")))) | |
1398 (setq crossref-field (bibtex-text-in-field-bounds bounds t)) | |
1399 (widen) | |
1400 (if (bibtex-find-crossref crossref-field) | 1445 (if (bibtex-find-crossref crossref-field) |
1401 ;; Do not pass FOLLOW-CROSSREF because we want | 1446 ;; Do not pass FOLLOW-CROSSREF because we want |
1402 ;; to follow crossrefs only one level of recursion. | 1447 ;; to follow crossrefs only one level of recursion. |
1403 (bibtex-text-in-field field)))))))) | 1448 (bibtex-text-in-field field)))))))) |
1404 | 1449 |
1405 (defun bibtex-parse-string-prefix () | 1450 (defun bibtex-parse-string-prefix () |
1406 "Parse the prefix part of a BibTeX string entry, including reference key. | 1451 "Parse the prefix part of a BibTeX string entry, including reference key. |
1407 If the string prefix is found, return a triple consisting of the position of | 1452 If the string prefix is found, return a triple consisting of the position of |
1408 the very first character of the match, the actual starting position of the | 1453 the very first character of the match, the actual starting position of the |
1409 reference key and the end position of the match." | 1454 reference key and the end position of the match. |
1455 If `bibtex-string-empty-key' is non-nil accept empty string key." | |
1410 (let ((case-fold-search t)) | 1456 (let ((case-fold-search t)) |
1411 (if (looking-at "^[ \t]*@string[ \t\n]*[({][ \t\n]*") | 1457 (if (looking-at bibtex-string-type) |
1412 (let ((start (point))) | 1458 (let ((start (point))) |
1413 (goto-char (match-end 0)) | 1459 (goto-char (match-end 0)) |
1414 (when (looking-at bibtex-reference-key) | 1460 (cond ((looking-at bibtex-reference-key) |
1415 (goto-char (match-end 0)) | 1461 (goto-char (match-end 0)) |
1416 (list start | 1462 (list start |
1417 (match-beginning 0) | 1463 (match-beginning 0) |
1418 (match-end 0))))))) | 1464 (match-end 0))) |
1465 ((and bibtex-string-empty-key | |
1466 (looking-at "=")) | |
1467 (skip-chars-backward " \t\n") | |
1468 (list start (point) (point)))))))) | |
1419 | 1469 |
1420 (defun bibtex-parse-string-postfix () | 1470 (defun bibtex-parse-string-postfix () |
1421 "Parse the postfix part of a BibTeX string entry, including the text. | 1471 "Parse the postfix part of a BibTeX string entry, including the text. |
1422 If the string postfix is found, return a triple consisting of the position of | 1472 If the string postfix is found, return a triple consisting of the position of |
1423 the actual starting and ending position of the text and the very last | 1473 the actual starting and ending position of the text and the very last |
1424 character of the string entry. Move point past BibTeX string entry." | 1474 character of the string entry. Move point past BibTeX string entry." |
1425 (let* ((case-fold-search t) | 1475 (let* ((case-fold-search t) |
1426 (bounds (bibtex-parse-field-text))) | 1476 (bounds (bibtex-parse-field-text))) |
1427 (when bounds | 1477 (when bounds |
1428 (goto-char (cdr bounds)) | 1478 (goto-char (nth 1 bounds)) |
1429 (when (looking-at "[ \t\n]*[})]") | 1479 (when (looking-at "[ \t\n]*[})]") |
1430 (goto-char (match-end 0)) | 1480 (goto-char (match-end 0)) |
1431 (list (car bounds) | 1481 (list (car bounds) |
1432 (cdr bounds) | 1482 (nth 1 bounds) |
1433 (match-end 0)))))) | 1483 (match-end 0)))))) |
1434 | 1484 |
1435 (defun bibtex-parse-string () | 1485 (defun bibtex-parse-string (&optional empty-key) |
1436 "Parse a BibTeX string entry. | 1486 "Parse a BibTeX string entry beginning at the position of point. |
1437 If a syntactically correct entry is found, a pair containing the boundaries of | 1487 If a syntactically correct entry is found, return a cons pair containing |
1438 the reference key and text parts of the entry is returned. | 1488 the boundaries of the reference key and text parts of the entry. |
1439 Move point past BibTeX string entry." | 1489 If EMPTY-KEY is non-nil, key may be empty. Do not move point." |
1440 (bibtex-parse-association 'bibtex-parse-string-prefix | 1490 (let ((bibtex-string-empty-key empty-key)) |
1441 'bibtex-parse-string-postfix)) | 1491 (bibtex-parse-association 'bibtex-parse-string-prefix |
1442 | 1492 'bibtex-parse-string-postfix))) |
1443 (defun bibtex-search-forward-string () | 1493 |
1494 (defun bibtex-search-forward-string (&optional empty-key) | |
1444 "Search forward to find a BibTeX string entry. | 1495 "Search forward to find a BibTeX string entry. |
1445 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 |
1446 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." | |
1447 (save-excursion | 1499 (save-excursion |
1448 (save-match-data | 1500 (save-match-data |
1449 (let ((case-fold-search t) | 1501 (let ((case-fold-search t) bounds) |
1450 boundaries) | 1502 (while (and (not bounds) |
1451 (while (and (not boundaries) | 1503 (search-forward-regexp bibtex-string-type nil t)) |
1452 (search-forward-regexp | 1504 (save-excursion (goto-char (match-beginning 0)) |
1453 "^[ \t]*@string[ \t\n]*[({][ \t\n]*" nil t)) | 1505 (setq bounds (bibtex-parse-string empty-key)))) |
1454 (goto-char (match-beginning 0)) | 1506 bounds)))) |
1455 (unless (setq boundaries (bibtex-parse-string)) | |
1456 (forward-char 1))) | |
1457 boundaries)))) | |
1458 | |
1459 (defun bibtex-search-backward-string () | |
1460 "Search backward to find a BibTeX string entry. | |
1461 If a syntactically correct entry is found, a pair containing the boundaries of | |
1462 the reference key and text parts of the field is returned. Do not move point." | |
1463 (save-excursion | |
1464 (save-match-data | |
1465 (let ((case-fold-search t) | |
1466 boundaries) | |
1467 (while (and (not boundaries) | |
1468 (search-backward-regexp | |
1469 "^[ \t]*@string[ \t\n]*[({][ \t\n]*" nil t)) | |
1470 (goto-char (match-beginning 0)) | |
1471 (setq boundaries (bibtex-parse-string))) | |
1472 boundaries)))) | |
1473 | 1507 |
1474 (defun bibtex-reference-key-in-string (bounds) | 1508 (defun bibtex-reference-key-in-string (bounds) |
1509 "Return the key part of a BibTeX string defined via BOUNDS" | |
1475 (buffer-substring-no-properties (nth 1 (car bounds)) | 1510 (buffer-substring-no-properties (nth 1 (car bounds)) |
1476 (nth 2 (car bounds)))) | 1511 (nth 2 (car bounds)))) |
1477 | 1512 |
1478 (defun bibtex-text-in-string (bounds &optional remove-delim) | 1513 (defun bibtex-text-in-string (bounds &optional content) |
1479 "Get content of text in BibTeX string field defined via BOUNDS. | 1514 "Get text in BibTeX string field defined via BOUNDS. |
1480 If optional arg REMOVE-DELIM is non-nil remove enclosing field | 1515 If optional arg CONTENT is non-nil extract content |
1481 delimiters if present." | 1516 by removing field delimiters and concatenating the resulting string. |
1482 (let ((content (buffer-substring-no-properties (nth 0 (cdr bounds)) | 1517 If `bibtex-expand-strings' is non-nil, also expand BibTeX strings." |
1483 (nth 1 (cdr bounds))))) | 1518 (bibtex-text-in-field-bounds bounds content)) |
1484 (if remove-delim | |
1485 (bibtex-remove-delimiters-string content) | |
1486 content))) | |
1487 | 1519 |
1488 (defsubst bibtex-start-of-text-in-string (bounds) | 1520 (defsubst bibtex-start-of-text-in-string (bounds) |
1489 (nth 0 (cdr bounds))) | 1521 (nth 0 (cdr bounds))) |
1490 (defsubst bibtex-end-of-text-in-string (bounds) | 1522 (defsubst bibtex-end-of-text-in-string (bounds) |
1491 (nth 1 (cdr bounds))) | 1523 (nth 1 (cdr bounds))) |
1501 (defsubst bibtex-key-in-head (&optional empty) | 1533 (defsubst bibtex-key-in-head (&optional empty) |
1502 "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." |
1503 (or (match-string-no-properties bibtex-key-in-head) | 1535 (or (match-string-no-properties bibtex-key-in-head) |
1504 empty)) | 1536 empty)) |
1505 | 1537 |
1538 (defun bibtex-parse-preamble () | |
1539 "Parse BibTeX preamble. | |
1540 Point must be at beginning of preamble. Do not move point." | |
1541 (let ((case-fold-search t)) | |
1542 (when (looking-at bibtex-preamble-prefix) | |
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)))))) | |
1547 | |
1506 ;; Helper Functions | 1548 ;; Helper Functions |
1507 | |
1508 (defun bibtex-remove-delimiters-string (str) | |
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 | 1549 |
1515 (defsubst bibtex-string= (str1 str2) | 1550 (defsubst bibtex-string= (str1 str2) |
1516 "Return t if STR1 and STR2 are equal, ignoring case." | 1551 "Return t if STR1 and STR2 are equal, ignoring case." |
1517 (eq t (compare-strings str1 0 nil str2 0 nil t))) | 1552 (eq t (compare-strings str1 0 nil str2 0 nil t))) |
1518 | 1553 |
1523 | 1558 |
1524 (defun bibtex-current-line () | 1559 (defun bibtex-current-line () |
1525 "Compute line number of point regardless whether the buffer is narrowed." | 1560 "Compute line number of point regardless whether the buffer is narrowed." |
1526 (+ (count-lines 1 (point)) | 1561 (+ (count-lines 1 (point)) |
1527 (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)))))) | |
1528 | 1592 |
1529 (defun bibtex-skip-to-valid-entry (&optional backward) | 1593 (defun bibtex-skip-to-valid-entry (&optional backward) |
1530 "Move point to beginning of the next valid BibTeX entry. | 1594 "Move point to beginning of the next valid BibTeX entry. |
1531 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. |
1532 With optional argument BACKWARD non-nil, move backward to | 1596 With optional argument BACKWARD non-nil, move backward to |
1533 beginning of previous valid one. A valid entry is a syntactical correct one | 1597 beginning of previous valid one. A valid entry is a syntactical correct one |
1534 with type contained in `bibtex-entry-field-alist' or, if | 1598 with type contained in `bibtex-entry-field-alist' or, if |
1535 `bibtex-sort-ignore-string-entries' is nil, a syntactical correct string | 1599 `bibtex-sort-ignore-string-entries' is nil, a syntactical correct string |
1536 entry. Return buffer position of beginning and ending of entry if a valid | 1600 entry. Return buffer position of beginning and end of entry if a valid |
1537 entry is found, nil otherwise." | 1601 entry is found, nil otherwise." |
1538 (interactive "P") | 1602 (interactive "P") |
1539 (let ((case-fold-search t) | 1603 (let ((case-fold-search t) |
1540 found) | 1604 found bounds) |
1605 (beginning-of-line) | |
1606 ;; Loop till we look at a valid entry. | |
1541 (while (not (or found (if backward (bobp) (eobp)))) | 1607 (while (not (or found (if backward (bobp) (eobp)))) |
1542 (let ((pnt (point)) | 1608 (cond ((setq found (or (bibtex-valid-entry) |
1543 bounds) | 1609 (and (not bibtex-sort-ignore-string-entries) |
1544 (cond ((or (and (looking-at bibtex-valid-entry-re) | 1610 (setq bounds (bibtex-parse-string)) |
1545 (setq found (bibtex-search-entry nil nil t)) | 1611 (cons (bibtex-start-of-field bounds) |
1546 (equal (match-beginning 0) pnt)) | 1612 (bibtex-end-of-string bounds)))))) |
1547 (and (not bibtex-sort-ignore-string-entries) | 1613 (backward (re-search-backward "^[ \t]*@" nil 'move)) |
1548 (setq bounds (bibtex-parse-string)) | 1614 (t (if (re-search-forward "\n\\([ \t]*@\\)" nil 'move) |
1549 (setq found (cons (bibtex-start-of-field bounds) | 1615 (goto-char (match-beginning 1)))))) |
1550 (bibtex-end-of-string bounds))))) | |
1551 (goto-char pnt)) | |
1552 (backward | |
1553 (if (re-search-backward "^[ \t]*\\(@\\)" nil 'move) | |
1554 (goto-char (match-beginning 1)))) | |
1555 (t (if (re-search-forward "\n[ \t]*@" nil 'move) | |
1556 (forward-char -1)))))) | |
1557 found)) | 1616 found)) |
1558 | 1617 |
1559 (defun bibtex-map-entries (fun) | 1618 (defun bibtex-map-entries (fun) |
1560 "Call FUN for each BibTeX entry in buffer (possibly narrowed). | 1619 "Call FUN for each BibTeX entry in buffer (possibly narrowed). |
1561 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 |
1562 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 |
1563 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, |
1564 @String entries." | 1623 see regexp `bibtex-entry-head'. If `bibtex-sort-ignore-string-entries' |
1565 (let ((case-fold-search t)) | 1624 is non-nil, FUN is not called for @String entries." |
1625 (let ((case-fold-search t) | |
1626 found) | |
1566 (save-excursion | 1627 (save-excursion |
1567 (goto-char (point-min)) | 1628 (goto-char (point-min)) |
1568 (while (re-search-forward bibtex-entry-head nil t) | 1629 (while (setq found (bibtex-skip-to-valid-entry)) |
1569 (let ((entry-type (bibtex-type-in-head)) | 1630 (looking-at bibtex-any-entry-maybe-empty-head) |
1570 (key (bibtex-key-in-head "")) | 1631 (funcall fun (bibtex-key-in-head "") (car found) (cdr found)) |
1571 (beg (copy-marker (match-beginning 0))) | 1632 (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 | 1633 |
1580 (defun bibtex-progress-message (&optional flag interval) | 1634 (defun bibtex-progress-message (&optional flag interval) |
1581 "Echo a message about progress of current buffer. | 1635 "Echo a message about progress of current buffer. |
1582 If FLAG is a string, the message is initialized (in this case a | 1636 If FLAG is a string, the message is initialized (in this case a |
1583 value for INTERVAL may be given as well (if not this is set to 5)). | 1637 value for INTERVAL may be given as well (if not this is set to 5)). |
1623 "Return a string dependent on `bibtex-entry-delimiters'." | 1677 "Return a string dependent on `bibtex-entry-delimiters'." |
1624 (if (eq bibtex-entry-delimiters 'braces) | 1678 (if (eq bibtex-entry-delimiters 'braces) |
1625 "}" | 1679 "}" |
1626 ")")) | 1680 ")")) |
1627 | 1681 |
1628 (defun bibtex-search-entry (empty-head &optional bound noerror backward) | 1682 (defun bibtex-flash-head (prompt) |
1629 "Search for a BibTeX entry (maybe without reference key if EMPTY-HEAD is t). | |
1630 BOUND and NOERROR are exactly as in `re-search-forward'. If BACKWARD | |
1631 is non-nil, search in reverse direction. Move point past the closing | |
1632 delimiter (at the beginning of entry if BACKWARD is non-nil). | |
1633 Return a cons pair with buffer positions of beginning and end of entry. | |
1634 After call to this function MATCH-BEGINNING and MATCH-END functions | |
1635 are defined, but only for the head part of the entry | |
1636 \(especially (match-end 0) just gives the end of the head part)." | |
1637 (let ((pnt (point)) | |
1638 (entry-head-re (if empty-head | |
1639 bibtex-entry-maybe-empty-head | |
1640 bibtex-entry-head))) | |
1641 (if backward | |
1642 (let (found) | |
1643 (while (and (not found) | |
1644 (re-search-backward entry-head-re bound noerror)) | |
1645 (setq found (bibtex-search-entry empty-head pnt t))) | |
1646 (if found | |
1647 (progn (goto-char (match-beginning 0)) | |
1648 found) | |
1649 (cond ((not noerror) | |
1650 ;; yell | |
1651 (error "Backward search of BibTeX entry failed")) | |
1652 ((eq noerror t) | |
1653 ;; don't move | |
1654 (goto-char pnt))) | |
1655 nil)) | |
1656 (let (found) | |
1657 (unless bound (setq bound (point-max))) | |
1658 (while (and (not found) | |
1659 (re-search-forward entry-head-re bound noerror)) | |
1660 (save-match-data | |
1661 (let ((entry-closer | |
1662 (if (save-excursion | |
1663 (goto-char (match-end bibtex-type-in-head)) | |
1664 (looking-at "[ \t]*(")) | |
1665 ;; entry opened with parenthesis | |
1666 ?\) | |
1667 ?\})) | |
1668 (infix-start (point)) | |
1669 finished bounds) | |
1670 (while (not finished) | |
1671 (skip-chars-forward " \t\n" bound) | |
1672 (if (and (setq bounds (bibtex-parse-field bibtex-field-name)) | |
1673 (<= (bibtex-end-of-field bounds) bound)) | |
1674 (setq infix-start (bibtex-end-of-field bounds)) | |
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)) | |
1682 (goto-char (match-end 0)) | |
1683 (setq found t))))) | |
1684 (if found | |
1685 (cons (match-beginning 0) (point)) | |
1686 (cond ((not noerror) | |
1687 ;; yell | |
1688 (error "Search of BibTeX entry failed")) | |
1689 ((eq noerror t) | |
1690 ;; don't move | |
1691 (goto-char pnt))) | |
1692 nil))))) | |
1693 | |
1694 (defun bibtex-flash-head () | |
1695 "Flash at BibTeX entry head before point, if exists." | 1683 "Flash at BibTeX entry head before point, if exists." |
1696 (let ((case-fold-search t) | 1684 (let ((case-fold-search t) |
1697 flash) | 1685 (pnt (point))) |
1698 (cond ((re-search-backward bibtex-entry-head nil t) | 1686 (save-excursion |
1699 (goto-char (match-beginning bibtex-type-in-head)) | 1687 (bibtex-beginning-of-entry) |
1700 (setq flash (match-end bibtex-key-in-head))) | 1688 (when (and (looking-at bibtex-any-entry-maybe-empty-head) |
1701 (t | 1689 (< (point) pnt)) |
1702 (end-of-line) | 1690 (goto-char (match-beginning bibtex-type-in-head)) |
1703 (skip-chars-backward " \t") | 1691 (if (pos-visible-in-window-p (point)) |
1704 (setq flash (point)) | 1692 (sit-for 1) |
1705 (beginning-of-line) | 1693 (message "%s%s" prompt (buffer-substring-no-properties |
1706 (skip-chars-forward " \t"))) | 1694 (point) (match-end bibtex-key-in-head)))))))) |
1707 (if (pos-visible-in-window-p (point)) | |
1708 (sit-for 1) | |
1709 (message "From: %s" | |
1710 (buffer-substring (point) flash))))) | |
1711 | 1695 |
1712 (defun bibtex-make-optional-field (field) | 1696 (defun bibtex-make-optional-field (field) |
1713 "Make an optional field named FIELD in current BibTeX entry." | 1697 "Make an optional field named FIELD in current BibTeX entry." |
1714 (if (consp field) | 1698 (if (consp field) |
1715 (bibtex-make-field (cons (concat "OPT" (car field)) (cdr field))) | 1699 (bibtex-make-field (cons (concat "OPT" (car field)) (cdr field))) |
1729 (re-search-forward "^[ \t]*[@\n]" nil 'move) | 1713 (re-search-forward "^[ \t]*[@\n]" nil 'move) |
1730 (backward-char 1))) | 1714 (backward-char 1))) |
1731 (skip-chars-forward " \t\n"))) | 1715 (skip-chars-forward " \t\n"))) |
1732 | 1716 |
1733 (defun bibtex-beginning-of-first-entry () | 1717 (defun bibtex-beginning-of-first-entry () |
1734 "Go to the beginning of the first BibTeX entry in buffer. Return point." | 1718 "Go to beginning of line of first BibTeX entry in buffer. |
1719 If `bibtex-sort-ignore-string-entries' is non-nil, @String entries | |
1720 are ignored. Return point" | |
1735 (goto-char (point-min)) | 1721 (goto-char (point-min)) |
1736 (if (re-search-forward "^[ \t]*@" nil 'move) | 1722 (bibtex-skip-to-valid-entry) |
1737 (beginning-of-line)) | |
1738 (point)) | 1723 (point)) |
1739 | 1724 |
1740 (defun bibtex-beginning-of-last-entry () | 1725 (defun bibtex-enclosing-field (&optional comma noerr) |
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)) | |
1746 | |
1747 (defun bibtex-inside-field () | |
1748 "Try to avoid point being at end of a BibTeX field." | |
1749 (end-of-line) | |
1750 (skip-chars-backward " \t") | |
1751 (if (= (preceding-char) ?,) | |
1752 (forward-char -2)) | |
1753 (if (or (= (preceding-char) ?}) | |
1754 (= (preceding-char) ?\")) | |
1755 (forward-char -1))) | |
1756 | |
1757 (defun bibtex-enclosing-field (&optional noerr) | |
1758 "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. | |
1759 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. |
1760 On success return bounds, nil otherwise. Do not move point." | 1731 On success return bounds, nil otherwise. Do not move point." |
1761 (let ((bounds (bibtex-search-backward-field bibtex-field-name t))) | 1732 (save-excursion |
1762 (if (and bounds | 1733 (when comma |
1763 (<= (bibtex-start-of-field bounds) (point)) | 1734 (end-of-line) |
1764 (>= (bibtex-end-of-field bounds) (point))) | 1735 (skip-chars-backward " \t") |
1765 bounds | 1736 (if (= (preceding-char) ?,) (forward-char -1))) |
1766 (unless noerr | 1737 |
1767 (error "Can't find enclosing BibTeX field"))))) | 1738 (let ((bounds (bibtex-search-backward-field bibtex-field-name t))) |
1768 | 1739 (cond ((and bounds |
1769 (defun bibtex-enclosing-entry-maybe-empty-head () | 1740 (<= (bibtex-start-of-field bounds) (point)) |
1770 "Search for BibTeX entry enclosing point. Move point to end of entry. | 1741 (>= (bibtex-end-of-field bounds) (point))) |
1771 Beginning (but not end) of entry is given by (`match-beginning' 0)." | 1742 bounds) |
1772 (let ((case-fold-search t) | 1743 ((not noerr) |
1773 (old-point (point))) | 1744 (error "Can't find enclosing BibTeX field")))))) |
1774 (unless (re-search-backward bibtex-entry-maybe-empty-head nil t) | 1745 |
1775 (goto-char old-point) | 1746 (defun bibtex-beginning-first-field (&optional beg) |
1776 (error "Can't find beginning of enclosing BibTeX entry")) | 1747 "Move point to beginning of first field. |
1777 (goto-char (match-beginning bibtex-type-in-head)) | 1748 Optional arg BEG is beginning of entry." |
1778 (unless (bibtex-search-entry t nil t) | 1749 (if beg (goto-char beg) (bibtex-beginning-of-entry)) |
1779 (goto-char old-point) | 1750 (looking-at bibtex-any-entry-maybe-empty-head) |
1780 (error "Can't find end of enclosing BibTeX entry")))) | 1751 (goto-char (match-end 0))) |
1781 | 1752 |
1782 (defun bibtex-insert-kill (n) | 1753 (defun bibtex-insert-kill (n &optional comma) |
1783 "Reinsert the Nth stretch of killed BibTeX text." | 1754 "Reinsert the Nth stretch of killed BibTeX text (field or entry). |
1784 (if (not bibtex-last-kill-command) | 1755 Optional arg COMMA is as in `bibtex-enclosing-field'." |
1785 (error "BibTeX kill ring is empty") | 1756 (unless bibtex-last-kill-command (error "BibTeX kill ring is empty")) |
1786 (let* ((kr (if (eq bibtex-last-kill-command 'field) | 1757 (let ((fun (lambda (kryp kr) ;; adapted from `current-kill' |
1787 'bibtex-field-kill-ring | 1758 (car (set kryp (nthcdr (mod (- n (length (eval kryp))) |
1788 'bibtex-entry-kill-ring)) | 1759 (length kr)) kr)))))) |
1789 (kryp (if (eq bibtex-last-kill-command 'field) | 1760 (if (eq bibtex-last-kill-command 'field) |
1790 'bibtex-field-kill-ring-yank-pointer | 1761 (progn |
1791 'bibtex-entry-kill-ring-yank-pointer)) | 1762 ;; insert past the current field |
1792 (current (car (set kryp (nthcdr (mod (- n (length (eval kryp))) | 1763 (goto-char (bibtex-end-of-field (bibtex-enclosing-field comma))) |
1793 (length (eval kr))) | 1764 (set-mark (point)) |
1794 (eval kr)))))) | 1765 (message "Mark set") |
1795 (if (eq bibtex-last-kill-command 'field) | 1766 (bibtex-make-field (funcall fun 'bibtex-field-kill-ring-yank-pointer |
1796 (let (bibtex-help-message) | 1767 bibtex-field-kill-ring) t)) |
1797 (bibtex-find-text) | 1768 ;; insert past the current entry |
1798 (if (looking-at "[}\"]") | 1769 (bibtex-skip-to-valid-entry) |
1799 (forward-char)) | 1770 (set-mark (point)) |
1800 (set-mark (point)) | 1771 (message "Mark set") |
1801 (message "Mark set") | 1772 (insert (funcall fun 'bibtex-entry-kill-ring-yank-pointer |
1802 (bibtex-make-field current t)) | 1773 bibtex-entry-kill-ring))))) |
1803 (unless (eobp) (bibtex-beginning-of-entry)) | |
1804 (set-mark (point)) | |
1805 (message "Mark set") | |
1806 (insert current))))) | |
1807 | 1774 |
1808 (defun bibtex-format-entry () | 1775 (defun bibtex-format-entry () |
1809 "Helper function for `bibtex-clean-entry'. | 1776 "Helper function for `bibtex-clean-entry'. |
1810 Formats current entry according to variable `bibtex-entry-format'." | 1777 Formats current entry according to variable `bibtex-entry-format'." |
1811 (save-excursion | 1778 (save-excursion |
1844 (insert (bibtex-entry-left-delimiter)))) | 1811 (insert (bibtex-entry-left-delimiter)))) |
1845 | 1812 |
1846 ;; determine if entry has crossref field and if at least | 1813 ;; determine if entry has crossref field and if at least |
1847 ;; one alternative is non-empty | 1814 ;; one alternative is non-empty |
1848 (goto-char (point-min)) | 1815 (goto-char (point-min)) |
1849 (let* ((fields-alist (bibtex-parse-entry)) | 1816 (let* ((fields-alist (bibtex-parse-entry t)) |
1850 (field (assoc-string "crossref" fields-alist t))) | 1817 (field (assoc-string "crossref" fields-alist t))) |
1851 (setq crossref-key (and field | 1818 (setq crossref-key (and field |
1852 (not (string-match bibtex-empty-field-re | 1819 (not (equal "" (cdr field))) |
1853 (cdr field))) | 1820 (cdr field)) |
1854 (bibtex-remove-delimiters-string (cdr field))) | |
1855 req-field-list (if crossref-key | 1821 req-field-list (if crossref-key |
1856 (nth 0 (nth 2 entry-list)) ; crossref part | 1822 (nth 0 (nth 2 entry-list)) ; crossref part |
1857 (nth 0 (nth 1 entry-list)))) ; required part | 1823 (nth 0 (nth 1 entry-list)))) ; required part |
1858 | 1824 |
1859 (dolist (rfield req-field-list) | 1825 (dolist (rfield req-field-list) |
1860 (when (nth 3 rfield) ; we should have an alternative | 1826 (when (nth 3 rfield) ; we should have an alternative |
1861 (setq alternatives-there t | 1827 (setq alternatives-there t |
1862 field (assoc-string (car rfield) fields-alist t)) | 1828 field (assoc-string (car rfield) fields-alist t)) |
1863 (if (and field | 1829 (if (and field |
1864 (not (string-match bibtex-empty-field-re | 1830 (not (equal "" (cdr field)))) |
1865 (cdr field)))) | |
1866 (cond ((not non-empty-alternative) | 1831 (cond ((not non-empty-alternative) |
1867 (setq non-empty-alternative t)) | 1832 (setq non-empty-alternative t)) |
1868 ((memq 'required-fields format) | 1833 ((memq 'required-fields format) |
1869 (error "More than one non-empty alternative"))))))) | 1834 (error "More than one non-empty alternative"))))))) |
1870 | 1835 |
1872 (not non-empty-alternative) | 1837 (not non-empty-alternative) |
1873 (memq 'required-fields format)) | 1838 (memq 'required-fields format)) |
1874 (error "All alternatives are empty")) | 1839 (error "All alternatives are empty")) |
1875 | 1840 |
1876 ;; process all fields | 1841 ;; process all fields |
1877 (goto-char (point-min)) | 1842 (bibtex-beginning-first-field (point-min)) |
1878 (while (setq bounds (bibtex-search-forward-field bibtex-field-name)) | 1843 (while (setq bounds (bibtex-parse-field)) |
1879 (let* ((beg-field (copy-marker (bibtex-start-of-field bounds))) | 1844 (let* ((beg-field (copy-marker (bibtex-start-of-field bounds))) |
1880 (end-field (copy-marker (bibtex-end-of-field bounds) t)) | 1845 (end-field (copy-marker (bibtex-end-of-field bounds) t)) |
1881 (beg-name (copy-marker (bibtex-start-of-name-in-field bounds))) | 1846 (beg-name (copy-marker (bibtex-start-of-name-in-field bounds))) |
1882 (end-name (copy-marker (bibtex-end-of-name-in-field bounds))) | 1847 (end-name (copy-marker (bibtex-end-of-name-in-field bounds))) |
1883 (beg-text (copy-marker (bibtex-start-of-text-in-field bounds))) | 1848 (beg-text (copy-marker (bibtex-start-of-text-in-field bounds))) |
1885 (opt-alt (string-match "OPT\\|ALT" | 1850 (opt-alt (string-match "OPT\\|ALT" |
1886 (buffer-substring-no-properties | 1851 (buffer-substring-no-properties |
1887 beg-name (+ beg-name 3)))) | 1852 beg-name (+ beg-name 3)))) |
1888 (field-name (buffer-substring-no-properties | 1853 (field-name (buffer-substring-no-properties |
1889 (if opt-alt (+ beg-name 3) beg-name) end-name)) | 1854 (if opt-alt (+ beg-name 3) beg-name) end-name)) |
1890 (empty-field (string-match bibtex-empty-field-re | 1855 (empty-field (equal "" (bibtex-text-in-field-bounds bounds t))) |
1891 (buffer-substring-no-properties | |
1892 beg-text end-text))) | |
1893 deleted) | 1856 deleted) |
1894 | 1857 |
1895 ;; We have more elegant high-level functions for several | 1858 ;; We have more elegant high-level functions for several |
1896 ;; tasks done by bibtex-format-entry. However, they contain | 1859 ;; tasks done by bibtex-format-entry. However, they contain |
1897 ;; quite some redundancy compared with what we need to do | 1860 ;; quite some redundancy compared with what we need to do |
2013 altlist)) | 1976 altlist)) |
2014 ((> found 1) | 1977 ((> found 1) |
2015 (error "Alternative fields `%s' are defined %s times" | 1978 (error "Alternative fields `%s' are defined %s times" |
2016 altlist found)))))) | 1979 altlist found)))))) |
2017 | 1980 |
2018 ;; update point | |
2019 (if (looking-at (bibtex-field-right-delimiter)) | |
2020 (forward-char)) | |
2021 | |
2022 ;; update comma after last field | 1981 ;; update comma after last field |
2023 (if (memq 'last-comma format) | 1982 (if (memq 'last-comma format) |
2024 (cond ((and bibtex-comma-after-last-field | 1983 (cond ((and bibtex-comma-after-last-field |
2025 (not (looking-at ","))) | 1984 (not (looking-at ","))) |
2026 (insert ",")) | 1985 (insert ",")) |
2063 (defun bibtex-autokey-get-field (field &optional change-list) | 2022 (defun bibtex-autokey-get-field (field &optional change-list) |
2064 "Get content of BibTeX field FIELD. Return empty string if not found. | 2023 "Get content of BibTeX field FIELD. Return empty string if not found. |
2065 Optional arg CHANGE-LIST is a list of substitution patterns that is | 2024 Optional arg CHANGE-LIST is a list of substitution patterns that is |
2066 applied to the content of FIELD. It is an alist with pairs | 2025 applied to the content of FIELD. It is an alist with pairs |
2067 \(OLD-REGEXP . NEW-STRING\)." | 2026 \(OLD-REGEXP . NEW-STRING\)." |
2068 (let ((content (bibtex-text-in-field field bibtex-autokey-use-crossref)) | 2027 (let* ((bibtex-expand-strings bibtex-autokey-expand-strings) |
2028 (content (bibtex-text-in-field field bibtex-autokey-use-crossref)) | |
2069 case-fold-search) | 2029 case-fold-search) |
2070 (unless content (setq content "")) | 2030 (unless content (setq content "")) |
2071 (dolist (pattern change-list content) | 2031 (dolist (pattern change-list content) |
2072 (setq content (replace-regexp-in-string (car pattern) | 2032 (setq content (replace-regexp-in-string (car pattern) |
2073 (cdr pattern) | 2033 (cdr pattern) |
2193 Use the author/editor, the year and the title field. | 2153 Use the author/editor, the year and the title field. |
2194 The algorithm works as follows. | 2154 The algorithm works as follows. |
2195 | 2155 |
2196 The name part: | 2156 The name part: |
2197 1. Use the author or editor field to generate the name part of the key. | 2157 1. Use the author or editor field to generate the name part of the key. |
2158 Expand BibTeX strings if `bibtex-autokey-expand-strings' is non-nil. | |
2198 2. Change the content of the name field according to | 2159 2. Change the content of the name field according to |
2199 `bibtex-autokey-name-change-strings' (see there for further detail). | 2160 `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 | 2161 3. Use the first `bibtex-autokey-names' names in the name field. If there |
2201 are up to `bibtex-autokey-names' + `bibtex-autokey-names-stretch' names, | 2162 are up to `bibtex-autokey-names' + `bibtex-autokey-names-stretch' names, |
2202 use all names. | 2163 use all names. |
2297 | 2258 |
2298 (defun bibtex-parse-keys (&optional abortable verbose) | 2259 (defun bibtex-parse-keys (&optional abortable verbose) |
2299 "Set `bibtex-reference-keys' to the keys used in the whole buffer. | 2260 "Set `bibtex-reference-keys' to the keys used in the whole buffer. |
2300 Find both entry keys and crossref entries. If ABORTABLE is non-nil abort | 2261 Find both entry keys and crossref entries. If ABORTABLE is non-nil abort |
2301 on user input. If VERBOSE is non-nil give messages about progress. | 2262 on user input. If VERBOSE is non-nil give messages about progress. |
2302 Return alist of keys if parsing was completed, `aborted' otherwise." | 2263 Return alist of keys if parsing was completed, `aborted' otherwise. |
2264 If `bibtex-parse-keys-fast' is non-nil, use fast but simplified algorithm | |
2265 for parsing BibTeX keys. If parsing fails, try to set this variable to nil." | |
2303 (let (ref-keys crossref-keys) | 2266 (let (ref-keys crossref-keys) |
2304 (save-excursion | 2267 (save-excursion |
2305 (save-match-data | 2268 (save-match-data |
2306 (if verbose | 2269 (if verbose |
2307 (bibtex-progress-message | 2270 (bibtex-progress-message |
2384 (push (cons key (bibtex-text-in-string bounds t)) | 2347 (push (cons key (bibtex-text-in-string bounds t)) |
2385 strings)) | 2348 strings)) |
2386 (goto-char (bibtex-end-of-text-in-string bounds))) | 2349 (goto-char (bibtex-end-of-text-in-string bounds))) |
2387 ;; successful operation --> return `bibtex-strings' | 2350 ;; successful operation --> return `bibtex-strings' |
2388 (setq bibtex-strings strings)))))) | 2351 (setq bibtex-strings strings)))))) |
2352 | |
2353 (defun bibtex-strings () | |
2354 "Return `bibtex-strings'. Initialize this variable if necessary." | |
2355 (if (listp bibtex-strings) bibtex-strings | |
2356 (bibtex-parse-strings (bibtex-string-files-init)))) | |
2389 | 2357 |
2390 (defun bibtex-string-files-init () | 2358 (defun bibtex-string-files-init () |
2391 "Return initialization for `bibtex-strings'. | 2359 "Return initialization for `bibtex-strings'. |
2392 Use `bibtex-predefined-strings' and BibTeX files `bibtex-string-files'." | 2360 Use `bibtex-predefined-strings' and BibTeX files `bibtex-string-files'." |
2393 (save-match-data | 2361 (save-match-data |
2500 | 2468 |
2501 (defun bibtex-complete-internal (completions) | 2469 (defun bibtex-complete-internal (completions) |
2502 "Complete word fragment before point to longest prefix of COMPLETIONS. | 2470 "Complete word fragment before point to longest prefix of COMPLETIONS. |
2503 COMPLETIONS is an alist of strings. If point is not after the part | 2471 COMPLETIONS is an alist of strings. If point is not after the part |
2504 of a word, all strings are listed. Return completion." | 2472 of a word, all strings are listed. Return completion." |
2473 ;; Return value is used by cleanup functions. | |
2505 (let* ((case-fold-search t) | 2474 (let* ((case-fold-search t) |
2506 (beg (save-excursion | 2475 (beg (save-excursion |
2507 (re-search-backward "[ \t{\"]") | 2476 (re-search-backward "[ \t{\"]") |
2508 (forward-char) | 2477 (forward-char) |
2509 (point))) | 2478 (point))) |
2519 (insert completion) | 2488 (insert completion) |
2520 completion) | 2489 completion) |
2521 (t | 2490 (t |
2522 (message "Making completion list...") | 2491 (message "Making completion list...") |
2523 (with-output-to-temp-buffer "*Completions*" | 2492 (with-output-to-temp-buffer "*Completions*" |
2524 (display-completion-list (all-completions part-of-word | 2493 (display-completion-list (all-completions part-of-word completions) |
2525 completions) | |
2526 part-of-word)) | 2494 part-of-word)) |
2527 (message "Making completion list...done") | 2495 (message "Making completion list...done") |
2528 ;; return value is handled by choose-completion-string-functions | |
2529 nil)))) | 2496 nil)))) |
2530 | 2497 |
2531 (defun bibtex-complete-string-cleanup (str compl) | 2498 (defun bibtex-complete-string-cleanup (str compl) |
2532 "Cleanup after inserting string STR. | 2499 "Cleanup after inserting string STR. |
2533 Remove enclosing field delimiters for STR. Display message with | 2500 Remove enclosing field delimiters for STR. Display message with |
2534 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 | |
2535 (save-excursion | 2503 (save-excursion |
2536 (bibtex-inside-field) | 2504 (let ((abbr (cdr (if (stringp str) |
2537 (let ((bounds (bibtex-enclosing-field)) | |
2538 (abbr (cdr (if (stringp str) | |
2539 (assoc-string str compl t))))) | 2505 (assoc-string str compl t))))) |
2540 (if abbr (message "Abbreviation for `%s'" abbr)) | 2506 (if abbr (message "Abbreviation for `%s'" abbr)) |
2541 (goto-char (bibtex-start-of-text-in-field bounds)) | 2507 (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 | 2508 |
2548 (defun bibtex-complete-crossref-cleanup (key) | 2509 (defun bibtex-complete-crossref-cleanup (key) |
2549 "Display summary message on entry KEY after completion of a crossref key. | 2510 "Display summary message on entry KEY after completion of a crossref key. |
2550 Use `bibtex-summary-function' to generate summary." | 2511 Use `bibtex-summary-function' to generate summary." |
2551 (save-excursion | 2512 (save-excursion |
2596 (error "Entry not found"))) | 2557 (error "Entry not found"))) |
2597 | 2558 |
2598 (defun bibtex-pop (arg direction) | 2559 (defun bibtex-pop (arg direction) |
2599 "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. |
2600 Generic function used by `bibtex-pop-previous' and `bibtex-pop-next'." | 2561 Generic function used by `bibtex-pop-previous' and `bibtex-pop-next'." |
2601 (let (bibtex-help-message) | 2562 ;; parse current field |
2602 (bibtex-find-text)) | 2563 (let* ((bounds (bibtex-enclosing-field t)) |
2603 (save-excursion | 2564 (start-old-field (bibtex-start-of-field bounds)) |
2604 ;; parse current field | 2565 (start-old-text (bibtex-start-of-text-in-field bounds)) |
2605 (bibtex-inside-field) | 2566 (end-old-text (bibtex-end-of-text-in-field bounds)) |
2606 (let* ((case-fold-search t) | 2567 (field-name (bibtex-name-in-field bounds t)) |
2607 (bounds (bibtex-enclosing-field)) | 2568 failure) |
2608 (start-old-text (bibtex-start-of-text-in-field bounds)) | 2569 (save-excursion |
2609 (stop-old-text (bibtex-end-of-text-in-field bounds)) | |
2610 (field-name (bibtex-name-in-field bounds t))) | |
2611 ;; if executed several times in a row, start each search where | 2570 ;; if executed several times in a row, start each search where |
2612 ;; the last one was finished | 2571 ;; the last one was finished |
2613 (unless (eq last-command 'bibtex-pop) | 2572 (cond ((eq last-command 'bibtex-pop) |
2614 (bibtex-enclosing-entry-maybe-empty-head) | 2573 (goto-char (if (eq direction 'previous) |
2615 (setq bibtex-pop-previous-search-point (match-beginning 0) | 2574 bibtex-pop-previous-search-point |
2616 bibtex-pop-next-search-point (point))) | 2575 bibtex-pop-next-search-point))) |
2617 (if (eq direction 'previous) | 2576 ((eq direction 'previous) |
2618 (goto-char bibtex-pop-previous-search-point) | 2577 (bibtex-beginning-of-entry)) |
2619 (goto-char bibtex-pop-next-search-point)) | 2578 (t (bibtex-end-of-entry))) |
2620 ;; Now search for arg'th previous/next similar field | 2579 ;; Search for arg'th previous/next similar field |
2621 (let (bounds failure new-text) | 2580 (while (and (not failure) |
2622 (while (and (not failure) | 2581 (>= (setq arg (1- arg)) 0)) |
2623 (> arg 0)) | 2582 ;; The search of BibTeX fields is not bounded by entry boundaries |
2624 (cond ((eq direction 'previous) | 2583 (if (eq direction 'previous) |
2625 (if (setq bounds (bibtex-search-backward-field field-name)) | 2584 (if (setq bounds (bibtex-search-backward-field field-name)) |
2626 (goto-char (bibtex-start-of-field bounds)) | 2585 (goto-char (bibtex-start-of-field bounds)) |
2627 (setq failure t))) | 2586 (setq failure t)) |
2628 ((eq direction 'next) | 2587 (if (setq bounds (bibtex-search-forward-field field-name)) |
2629 (if (setq bounds (bibtex-search-forward-field field-name)) | 2588 (goto-char (bibtex-end-of-field bounds)) |
2630 (goto-char (bibtex-end-of-field bounds)) | 2589 (setq failure t)))) |
2631 (setq failure t)))) | 2590 (if failure |
2632 (setq arg (- arg 1))) | 2591 (error "No %s matching BibTeX field" |
2633 (if failure | 2592 (if (eq direction 'previous) "previous" "next")) |
2634 (error "No %s matching BibTeX field" | 2593 ;; Found a matching field. Remember boundaries. |
2635 (if (eq direction 'previous) "previous" "next")) | 2594 (let ((new-text (bibtex-text-in-field-bounds bounds)) |
2636 ;; Found a matching field. Remember boundaries. | 2595 (nbeg (copy-marker (bibtex-start-of-field bounds))) |
2637 (setq bibtex-pop-previous-search-point (bibtex-start-of-field bounds) | 2596 (nend (copy-marker (bibtex-end-of-field bounds)))) |
2638 bibtex-pop-next-search-point (bibtex-end-of-field bounds) | 2597 (bibtex-flash-head "From: ") |
2639 new-text (bibtex-text-in-field-bounds bounds)) | |
2640 (bibtex-flash-head) | |
2641 ;; 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. |
2642 (goto-char stop-old-text) | 2599 (goto-char end-old-text) |
2643 (delete-region start-old-text stop-old-text) | 2600 (delete-region start-old-text end-old-text) |
2644 (insert new-text))))) | 2601 (if (= nbeg start-old-field) |
2645 (let (bibtex-help-message) | 2602 (insert (bibtex-field-left-delimiter) |
2646 (bibtex-find-text)) | 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) | |
2647 (setq this-command 'bibtex-pop)) | 2608 (setq this-command 'bibtex-pop)) |
2648 | 2609 |
2649 (defun bibtex-beginning-of-field () | 2610 (defun bibtex-beginning-of-field () |
2650 "Move point backward to beginning of field. | 2611 "Move point backward to beginning of field. |
2651 This function uses a simple, fast algorithm assuming that the field | 2612 This function uses a simple, fast algorithm assuming that the field |
2665 (<= (point) bound) | 2626 (<= (point) bound) |
2666 (prog1 (re-search-forward bibtex-font-lock-url-regexp bound t) | 2627 (prog1 (re-search-forward bibtex-font-lock-url-regexp bound t) |
2667 (setq field (match-string-no-properties 1))) | 2628 (setq field (match-string-no-properties 1))) |
2668 (setq bounds (bibtex-parse-field-text)) | 2629 (setq bounds (bibtex-parse-field-text)) |
2669 (progn | 2630 (progn |
2670 (setq start (car bounds) end (cdr bounds)) | 2631 (setq start (car bounds) end (nth 1 bounds)) |
2671 ;; Always ignore field delimiters | 2632 ;; Always ignore field delimiters |
2672 (if (memq (char-before end) '(?\} ?\")) | 2633 (if (memq (char-before end) '(?\} ?\")) |
2673 (setq end (1- end))) | 2634 (setq end (1- end))) |
2674 (if (memq (char-after start) '(?\{ ?\")) | 2635 (if (memq (char-after start) '(?\{ ?\")) |
2675 (setq start (1+ start))) | 2636 (setq start (1+ start))) |
2820 (bibtex-beginning-of-entry))))) | 2781 (bibtex-beginning-of-entry))))) |
2821 (setq imenu-generic-expression | 2782 (setq imenu-generic-expression |
2822 (list (list nil bibtex-entry-head bibtex-key-in-head)) | 2783 (list (list nil bibtex-entry-head bibtex-key-in-head)) |
2823 imenu-case-fold-search t) | 2784 imenu-case-fold-search t) |
2824 (make-local-variable 'choose-completion-string-functions) | 2785 (make-local-variable 'choose-completion-string-functions) |
2786 (make-local-variable 'completion-ignore-case) | |
2825 ;; XEmacs needs easy-menu-add, Emacs does not care | 2787 ;; XEmacs needs easy-menu-add, Emacs does not care |
2826 (easy-menu-add bibtex-edit-menu) | 2788 (easy-menu-add bibtex-edit-menu) |
2827 (easy-menu-add bibtex-entry-menu) | 2789 (easy-menu-add bibtex-entry-menu) |
2828 (run-mode-hooks 'bibtex-mode-hook)) | 2790 (run-mode-hooks 'bibtex-mode-hook)) |
2829 | 2791 |
2835 `bibtex-include-OPTkey', `bibtex-include-OPTcrossref', | 2797 `bibtex-include-OPTkey', `bibtex-include-OPTcrossref', |
2836 and `bibtex-user-optional-fields'." | 2798 and `bibtex-user-optional-fields'." |
2837 (let ((e (assoc-string entry-type bibtex-entry-field-alist t)) | 2799 (let ((e (assoc-string entry-type bibtex-entry-field-alist t)) |
2838 required optional) | 2800 required optional) |
2839 (unless e | 2801 (unless e |
2840 (error "BibTeX entry type %s not defined" entry-type)) | 2802 (error "Fields for BibTeX entry type %s not defined" entry-type)) |
2841 (if (and (member-ignore-case entry-type bibtex-include-OPTcrossref) | 2803 (if (and (member-ignore-case entry-type bibtex-include-OPTcrossref) |
2842 (nth 2 e)) | 2804 (nth 2 e)) |
2843 (setq required (nth 0 (nth 2 e)) | 2805 (setq required (nth 0 (nth 2 e)) |
2844 optional (nth 1 (nth 2 e))) | 2806 optional (nth 1 (nth 2 e))) |
2845 (setq required (nth 0 (nth 1 e)) | 2807 (setq required (nth 0 (nth 1 e)) |
2892 according to `bibtex-field-list', but are not yet present." | 2854 according to `bibtex-field-list', but are not yet present." |
2893 (interactive) | 2855 (interactive) |
2894 (save-excursion | 2856 (save-excursion |
2895 (bibtex-beginning-of-entry) | 2857 (bibtex-beginning-of-entry) |
2896 ;; For inserting new fields, we use the fact that | 2858 ;; For inserting new fields, we use the fact that |
2897 ;; bibtex-parse-entry moves point to the end of the last field. | 2859 ;; `bibtex-parse-entry' moves point to the end of the last field. |
2898 (let* ((fields-alist (bibtex-parse-entry)) | 2860 (let* ((fields-alist (bibtex-parse-entry)) |
2899 (field-list (bibtex-field-list | 2861 (field-list (bibtex-field-list |
2900 (cdr (assoc "=type=" fields-alist))))) | 2862 (cdr (assoc "=type=" fields-alist))))) |
2863 (skip-chars-backward " \t\n") | |
2901 (dolist (field (car field-list)) | 2864 (dolist (field (car field-list)) |
2902 (unless (assoc-string (car field) fields-alist t) | 2865 (unless (assoc-string (car field) fields-alist t) |
2903 (bibtex-make-field field))) | 2866 (bibtex-make-field field))) |
2904 (dolist (field (cdr field-list)) | 2867 (dolist (field (cdr field-list)) |
2905 (unless (assoc-string (car field) fields-alist t) | 2868 (unless (assoc-string (car field) fields-alist t) |
2906 (bibtex-make-optional-field field)))))) | 2869 (bibtex-make-optional-field field)))))) |
2907 | 2870 |
2908 (defun bibtex-parse-entry () | 2871 (defun bibtex-parse-entry (&optional content) |
2909 "Parse entry at point, return an alist. | 2872 "Parse entry at point, return an alist. |
2910 The alist elements have the form (FIELD . TEXT), where FIELD can also be | 2873 The alist elements have the form (FIELD . TEXT), where FIELD can also be |
2911 the special strings \"=type=\" and \"=key=\". For the FIELD \"=key=\" | 2874 the special strings \"=type=\" and \"=key=\". For the FIELD \"=key=\" |
2912 TEXT may be nil. Remove \"OPT\" and \"ALT\" from FIELD. | 2875 TEXT may be nil. Remove \"OPT\" and \"ALT\" from FIELD. |
2913 Move point to the end of the last field." | 2876 Move point to the end of the last field. |
2877 If optional arg CONTENT is non-nil extract content of text fields." | |
2914 (let (alist bounds) | 2878 (let (alist bounds) |
2915 (when (looking-at bibtex-entry-maybe-empty-head) | 2879 (when (looking-at bibtex-entry-maybe-empty-head) |
2916 (push (cons "=type=" (bibtex-type-in-head)) alist) | 2880 (push (cons "=type=" (bibtex-type-in-head)) alist) |
2917 (push (cons "=key=" (bibtex-key-in-head)) alist) | 2881 (push (cons "=key=" (bibtex-key-in-head)) alist) |
2918 (goto-char (match-end 0)) | 2882 (goto-char (match-end 0)) |
2919 (while (setq bounds (bibtex-parse-field bibtex-field-name)) | 2883 (while (setq bounds (bibtex-parse-field)) |
2920 (push (cons (bibtex-name-in-field bounds t) | 2884 (push (cons (bibtex-name-in-field bounds t) |
2921 (bibtex-text-in-field-bounds bounds)) | 2885 (bibtex-text-in-field-bounds bounds content)) |
2922 alist) | 2886 alist) |
2923 (goto-char (bibtex-end-of-field bounds)))) | 2887 (goto-char (bibtex-end-of-field bounds)))) |
2924 alist)) | 2888 alist)) |
2925 | 2889 |
2926 (defun bibtex-autofill-entry () | 2890 (defun bibtex-autofill-entry () |
2937 (when (looking-at bibtex-entry-head) | 2901 (when (looking-at bibtex-entry-head) |
2938 (let ((type (bibtex-type-in-head)) | 2902 (let ((type (bibtex-type-in-head)) |
2939 (key (bibtex-key-in-head)) | 2903 (key (bibtex-key-in-head)) |
2940 (key-end (match-end bibtex-key-in-head)) | 2904 (key-end (match-end bibtex-key-in-head)) |
2941 (case-fold-search t) | 2905 (case-fold-search t) |
2906 (bibtex-sort-ignore-string-entries t) | |
2942 tmp other-key other bounds) | 2907 tmp other-key other bounds) |
2943 ;; The fields we want to change start right after the key. | 2908 ;; The fields we want to change start right after the key. |
2944 (goto-char key-end) | 2909 (goto-char key-end) |
2945 ;; First see whether to use the previous or the next entry | 2910 ;; First see whether to use the previous or the next entry |
2946 ;; for "inspiration". | 2911 ;; for "inspiration". |
2968 other (point)))) | 2933 other (point)))) |
2969 ;; Then fill the new entry's fields with the chosen other entry. | 2934 ;; Then fill the new entry's fields with the chosen other entry. |
2970 (when other | 2935 (when other |
2971 (setq other (save-excursion (goto-char other) (bibtex-parse-entry))) | 2936 (setq other (save-excursion (goto-char other) (bibtex-parse-entry))) |
2972 (setq key-end (point)) ;In case parse-entry changed the buffer. | 2937 (setq key-end (point)) ;In case parse-entry changed the buffer. |
2973 (while (setq bounds (bibtex-parse-field bibtex-field-name)) | 2938 (while (setq bounds (bibtex-parse-field)) |
2974 (let ((text (assoc-string (bibtex-name-in-field bounds t) | 2939 (let ((text (assoc-string (bibtex-name-in-field bounds t) |
2975 other t))) | 2940 other t))) |
2976 (if (not (and text | 2941 (if (not (and text |
2977 (string-match bibtex-empty-field-re | 2942 (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)) | 2943 (goto-char (bibtex-end-of-field bounds)) |
2982 (goto-char (bibtex-start-of-text-in-field bounds)) | 2944 (goto-char (bibtex-start-of-text-in-field bounds)) |
2983 (delete-region (point) (bibtex-end-of-text-in-field bounds)) | 2945 (delete-region (point) (bibtex-end-of-text-in-field bounds)) |
2984 (insert (cdr text))))) | 2946 (insert (cdr text))))) |
2985 ;; Finally try to update the text based on the difference between | 2947 ;; Finally try to update the text based on the difference between |
2992 (suffix (substring key (length prefix))) | 2954 (suffix (substring key (length prefix))) |
2993 (other-suffix (substring other-key (length prefix)))) | 2955 (other-suffix (substring other-key (length prefix)))) |
2994 (while (re-search-backward (regexp-quote other-suffix) key-end 'move) | 2956 (while (re-search-backward (regexp-quote other-suffix) key-end 'move) |
2995 (replace-match suffix))))))) | 2957 (replace-match suffix))))))) |
2996 | 2958 |
2997 (defun bibtex-print-help-message () | 2959 (defun bibtex-print-help-message (&optional field comma) |
2998 "Print helpful information about current field in current BibTeX entry." | 2960 "Print helpful information about current FIELD in current BibTeX entry. |
2999 (interactive) | 2961 Optional arg COMMA is as in `bibtex-enclosing-field'. It is t for |
3000 (save-excursion | 2962 interactive calls." |
2963 (interactive (list nil t)) | |
2964 (unless field (setq field (car (bibtex-find-text-internal nil nil comma)))) | |
2965 (if (string-match "@" field) | |
2966 (cond ((bibtex-string= field "@string") | |
2967 (message "String definition")) | |
2968 ((bibtex-string= field "@preamble") | |
2969 (message "Preamble definition")) | |
2970 (t (message "Entry key"))) | |
3001 (let* ((case-fold-search t) | 2971 (let* ((case-fold-search t) |
3002 (field-name (bibtex-name-in-field (bibtex-enclosing-field) t)) | 2972 (type (save-excursion |
3003 (field-list (bibtex-field-list (progn (re-search-backward | 2973 (bibtex-beginning-of-entry) |
3004 bibtex-entry-maybe-empty-head nil t) | 2974 (looking-at bibtex-entry-maybe-empty-head) |
3005 (bibtex-type-in-head)))) | 2975 (bibtex-type-in-head))) |
3006 (comment (assoc-string field-name | 2976 (field-list (bibtex-field-list type)) |
3007 (append (car field-list) | 2977 (comment (assoc-string field (append (car field-list) |
3008 (cdr field-list)) | 2978 (cdr field-list)) t))) |
3009 t))) | 2979 (if comment (message "%s" (nth 1 comment)) |
3010 (if comment | |
3011 (message "%s" (nth 1 comment)) | |
3012 (message "No comment available"))))) | 2980 (message "No comment available"))))) |
3013 | 2981 |
3014 (defun bibtex-make-field (field &optional move interactive) | 2982 (defun bibtex-make-field (field &optional move interactive) |
3015 "Make a field named FIELD in current BibTeX entry. | 2983 "Make a field named FIELD in current BibTeX entry. |
3016 FIELD is either a string or a list of the form | 2984 FIELD is either a string or a list of the form |
3022 MOVE and INTERACTIVE are t when called interactively." | 2990 MOVE and INTERACTIVE are t when called interactively." |
3023 (interactive | 2991 (interactive |
3024 (list (let ((completion-ignore-case t) | 2992 (list (let ((completion-ignore-case t) |
3025 (field-list (bibtex-field-list | 2993 (field-list (bibtex-field-list |
3026 (save-excursion | 2994 (save-excursion |
3027 (bibtex-enclosing-entry-maybe-empty-head) | 2995 (bibtex-beginning-of-entry) |
2996 (looking-at bibtex-any-entry-maybe-empty-head) | |
3028 (bibtex-type-in-head))))) | 2997 (bibtex-type-in-head))))) |
3029 (completing-read "BibTeX field name: " | 2998 (completing-read "BibTeX field name: " |
3030 (append (car field-list) (cdr field-list)) | 2999 (append (car field-list) (cdr field-list)) |
3031 nil nil nil bibtex-field-history)) | 3000 nil nil nil bibtex-field-history)) |
3032 t t)) | 3001 t t)) |
3033 (unless (consp field) | 3002 (unless (consp field) |
3034 (setq field (list field))) | 3003 (setq field (list field))) |
3035 (if move | 3004 (when move |
3036 (let (bibtex-help-message) | 3005 (bibtex-find-text) |
3037 (bibtex-find-text) | 3006 (if (looking-at "[}\"]") |
3038 (if (looking-at "[}\"]") | 3007 (forward-char))) |
3039 (forward-char)))) | |
3040 (insert ",\n") | 3008 (insert ",\n") |
3041 (indent-to-column (+ bibtex-entry-offset bibtex-field-indentation)) | 3009 (indent-to-column (+ bibtex-entry-offset bibtex-field-indentation)) |
3042 (if (nth 3 field) (insert "ALT")) | 3010 (if (nth 3 field) (insert "ALT")) |
3043 (insert (car field) " ") | 3011 (insert (car field) " ") |
3044 (if bibtex-align-at-equal-sign | 3012 (if bibtex-align-at-equal-sign |
3052 (insert (cond ((stringp init) init) | 3020 (insert (cond ((stringp init) init) |
3053 ((fboundp init) (funcall init)) | 3021 ((fboundp init) (funcall init)) |
3054 (t (concat (bibtex-field-left-delimiter) | 3022 (t (concat (bibtex-field-left-delimiter) |
3055 (bibtex-field-right-delimiter)))))) | 3023 (bibtex-field-right-delimiter)))))) |
3056 (when interactive | 3024 (when interactive |
3057 (forward-char -1) | 3025 ;; (bibtex-find-text nil nil bibtex-help-message) |
3058 (bibtex-print-help-message))) | 3026 (if (memq (preceding-char) '(?} ?\")) (forward-char -1)) |
3027 (if bibtex-help-message (bibtex-print-help-message (car field))))) | |
3059 | 3028 |
3060 (defun bibtex-beginning-of-entry () | 3029 (defun bibtex-beginning-of-entry () |
3061 "Move to beginning of BibTeX entry (beginning of line). | 3030 "Move to beginning of BibTeX entry (beginning of line). |
3062 If inside an entry, move to the beginning of it, otherwise move to the | 3031 If inside an entry, move to the beginning of it, otherwise move to the |
3063 beginning of the previous entry. If point is ahead of all BibTeX entries | 3032 beginning of the previous entry. If point is ahead of all BibTeX entries |
3074 If inside an entry, move to the end of it, otherwise move to the end | 3043 If inside an entry, move to the end of it, otherwise move to the end |
3075 of the previous entry. Do not move if ahead of first entry. | 3044 of the previous entry. Do not move if ahead of first entry. |
3076 Return the new location of point." | 3045 Return the new location of point." |
3077 (interactive) | 3046 (interactive) |
3078 (let ((case-fold-search t) | 3047 (let ((case-fold-search t) |
3079 (org (point)) | 3048 (pnt (point)) |
3080 (pnt (bibtex-beginning-of-entry)) | 3049 (_ (bibtex-beginning-of-entry)) |
3081 err bounds) | 3050 (bounds (bibtex-valid-entry t))) |
3082 (cond ((looking-at bibtex-valid-entry-whitespace-re) | 3051 (cond (bounds (goto-char (cdr bounds))) ; regular entry |
3083 (bibtex-search-entry t nil t) | 3052 ;; @String or @Preamble |
3084 (unless (equal (match-beginning 0) pnt) | 3053 ((setq bounds (or (bibtex-parse-string t) (bibtex-parse-preamble))) |
3085 (setq err t))) | |
3086 ((setq bounds (bibtex-parse-string)) | |
3087 (goto-char (bibtex-end-of-string bounds))) | 3054 (goto-char (bibtex-end-of-string bounds))) |
3088 ((looking-at "[ \t]*@[ \t]*preamble[ \t\n]*") | 3055 ((looking-at bibtex-any-valid-entry-type) |
3089 (goto-char (match-end 0)) | 3056 ;; Parsing of entry failed |
3090 (if (looking-at "[({]") | 3057 (error "Syntactically incorrect BibTeX entry starts here.")) |
3091 (forward-sexp 1) | 3058 (t (if (interactive-p) (message "Not on a known BibTeX entry.")) |
3092 (setq err t))) | 3059 (goto-char pnt))) |
3093 (t | 3060 (point))) |
3094 (if (interactive-p) | |
3095 (message "Not on a known BibTeX entry.")) | |
3096 (goto-char org))) | |
3097 (when err | |
3098 (goto-char pnt) | |
3099 (error "Syntactically incorrect BibTeX entry starts here"))) | |
3100 (point)) | |
3101 | 3061 |
3102 (defun bibtex-goto-line (arg) | 3062 (defun bibtex-goto-line (arg) |
3103 "Goto line ARG, counting from beginning of (narrowed) buffer." | 3063 "Goto line ARG, counting from beginning of (narrowed) buffer." |
3104 ;; code adapted from `goto-line' | 3064 ;; code adapted from `goto-line' |
3105 (goto-char (point-min)) | 3065 (goto-char (point-min)) |
3140 With prefix argument COUNT-STRING-ENTRIES count all entries, | 3100 With prefix argument COUNT-STRING-ENTRIES count all entries, |
3141 otherwise count all entries except @String entries. | 3101 otherwise count all entries except @String entries. |
3142 If mark is active count entries in region, if not in whole buffer." | 3102 If mark is active count entries in region, if not in whole buffer." |
3143 (interactive "P") | 3103 (interactive "P") |
3144 (let ((number 0) | 3104 (let ((number 0) |
3145 (bibtex-sort-ignore-string-entries | 3105 (bibtex-sort-ignore-string-entries (not count-string-entries))) |
3146 (not count-string-entries))) | 3106 (save-restriction |
3147 (save-excursion | 3107 (if mark-active (narrow-to-region (region-beginning) (region-end))) |
3148 (save-restriction | 3108 (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." | 3109 (message "%s contains %d entries." |
3155 (if mark-active "Region" "Buffer") | 3110 (if mark-active "Region" "Buffer") |
3156 number))) | 3111 number))) |
3157 | 3112 |
3158 (defun bibtex-ispell-entry () | 3113 (defun bibtex-ispell-entry () |
3235 The predicate for sorting is defined via `bibtex-maintain-sorted-entries'. | 3190 The predicate for sorting is defined via `bibtex-maintain-sorted-entries'. |
3236 If its value is nil use plain sorting. Text outside of BibTeX entries is not | 3191 If its value is nil use plain sorting. Text outside of BibTeX entries is not |
3237 affected. If `bibtex-sort-ignore-string-entries' is non-nil, @String entries | 3192 affected. If `bibtex-sort-ignore-string-entries' is non-nil, @String entries |
3238 are ignored." | 3193 are ignored." |
3239 (interactive) | 3194 (interactive) |
3240 (save-restriction | 3195 (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 | 3196 (sort-subr nil |
3246 'bibtex-skip-to-valid-entry ; NEXTREC function | 3197 'bibtex-skip-to-valid-entry ; NEXTREC function |
3247 'bibtex-end-of-entry ; ENDREC function | 3198 'bibtex-end-of-entry ; ENDREC function |
3248 'bibtex-entry-index ; STARTKEY function | 3199 'bibtex-entry-index ; STARTKEY function |
3249 nil ; ENDKEY function | 3200 nil ; ENDKEY function |
3250 'bibtex-lessp))) ; PREDICATE | 3201 'bibtex-lessp)) ; PREDICATE |
3251 | 3202 |
3252 (defun bibtex-find-crossref (crossref-key &optional pnt split) | 3203 (defun bibtex-find-crossref (crossref-key &optional pnt split) |
3253 "Move point to the beginning of BibTeX entry CROSSREF-KEY. | 3204 "Move point to the beginning of BibTeX entry CROSSREF-KEY. |
3254 If `bibtex-files' is non-nil, search all these files. | 3205 If `bibtex-files' is non-nil, search all these files. |
3255 Otherwise the search is limited to the current buffer. | 3206 Otherwise the search is limited to the current buffer. |
3359 ;; if key-exist is non-nil due to the previous cond clause | 3310 ;; if key-exist is non-nil due to the previous cond clause |
3360 ;; then point will be at beginning of entry named key. | 3311 ;; then point will be at beginning of entry named key. |
3361 (key-exist) | 3312 (key-exist) |
3362 (t ; bibtex-maintain-sorted-entries is non-nil | 3313 (t ; bibtex-maintain-sorted-entries is non-nil |
3363 (let* ((case-fold-search t) | 3314 (let* ((case-fold-search t) |
3364 (left (save-excursion (bibtex-beginning-of-first-entry) | 3315 (left (save-excursion (bibtex-beginning-of-first-entry))) |
3365 (bibtex-skip-to-valid-entry) | 3316 (bounds (save-excursion (goto-char (point-max)) |
3366 (point))) | 3317 (bibtex-skip-to-valid-entry t))) |
3367 (right (save-excursion (bibtex-beginning-of-last-entry) | 3318 (right (if bounds (cdr bounds) (point-min))) |
3368 (bibtex-end-of-entry))) | |
3369 (found (if (>= left right) left)) | 3319 (found (if (>= left right) left)) |
3370 actual-index new) | 3320 actual-index new) |
3371 (save-excursion | 3321 (save-excursion |
3372 ;; Binary search | 3322 ;; Binary search |
3373 (while (not found) | 3323 (while (not found) |
3410 (interactive "P") | 3360 (interactive "P") |
3411 (let* ((case-fold-search t) | 3361 (let* ((case-fold-search t) |
3412 error-list syntax-error) | 3362 error-list syntax-error) |
3413 (save-excursion | 3363 (save-excursion |
3414 (save-restriction | 3364 (save-restriction |
3415 (narrow-to-region (if mark-active (region-beginning) | 3365 (if mark-active (narrow-to-region (region-beginning) (region-end))) |
3416 (bibtex-beginning-of-first-entry)) | 3366 |
3417 (if mark-active (region-end) (point-max))) | 3367 ;; Check syntactical structure of entries |
3418 | |
3419 ;; looking if entries fit syntactical structure | |
3420 (goto-char (point-min)) | 3368 (goto-char (point-min)) |
3421 (bibtex-progress-message "Checking syntactical structure") | 3369 (bibtex-progress-message "Checking syntactical structure") |
3422 (let (bibtex-sort-ignore-string-entries) | 3370 (let (bounds end) |
3423 (while (re-search-forward "^[ \t]*@" nil t) | 3371 (while (setq end (re-search-forward "^[ \t]*@" nil t)) |
3424 (bibtex-progress-message) | 3372 (bibtex-progress-message) |
3425 (forward-char -1) | 3373 (goto-char (match-beginning 0)) |
3426 (let ((pnt (point))) | 3374 (cond ((setq bounds (bibtex-valid-entry)) |
3427 (if (not (looking-at bibtex-any-valid-entry-re)) | 3375 (goto-char (cdr bounds))) |
3428 (forward-char) | 3376 ((setq bounds (or (bibtex-parse-string) |
3429 (bibtex-skip-to-valid-entry) | 3377 (bibtex-parse-preamble))) |
3430 (if (equal (point) pnt) | 3378 (goto-char (bibtex-end-of-string bounds))) |
3431 (forward-char) | 3379 ((looking-at bibtex-any-valid-entry-type) |
3432 (goto-char pnt) | 3380 (push (cons (bibtex-current-line) |
3433 (push (cons (bibtex-current-line) | 3381 "Syntax error (check esp. commas, braces, and quotes)") |
3434 "Syntax error (check esp. commas, braces, and quotes)") | 3382 error-list) |
3435 error-list) | 3383 (goto-char (match-end 0))) |
3436 (forward-char)))))) | 3384 (t (goto-char end))))) |
3437 (bibtex-progress-message 'done) | 3385 (bibtex-progress-message 'done) |
3438 | 3386 |
3439 (if error-list | 3387 (if error-list |
3440 ;; proceed only if there were no syntax errors. | 3388 ;; Continue only if there were no syntax errors. |
3441 (setq syntax-error t) | 3389 (setq syntax-error t) |
3442 | 3390 |
3443 ;; looking for duplicate keys and correct sort order | 3391 ;; Check for duplicate keys and correct sort order |
3444 (let (previous current key-list) | 3392 (let (previous current key-list) |
3445 (bibtex-progress-message "Checking for duplicate keys") | 3393 (bibtex-progress-message "Checking for duplicate keys") |
3446 (bibtex-map-entries | 3394 (bibtex-map-entries |
3447 (lambda (key beg end) | 3395 (lambda (key beg end) |
3448 (bibtex-progress-message) | 3396 (bibtex-progress-message) |
3449 (goto-char beg) | |
3450 (setq current (bibtex-entry-index)) | 3397 (setq current (bibtex-entry-index)) |
3451 (cond ((not previous)) | 3398 (cond ((not previous)) |
3452 ((member key key-list) | 3399 ((member key key-list) |
3453 (push (cons (bibtex-current-line) | 3400 (push (cons (bibtex-current-line) |
3454 (format "Duplicate key `%s'" key)) | 3401 (format "Duplicate key `%s'" key)) |
3480 "Checking required fields and month fields") | 3427 "Checking required fields and month fields") |
3481 (let ((bibtex-sort-ignore-string-entries t)) | 3428 (let ((bibtex-sort-ignore-string-entries t)) |
3482 (bibtex-map-entries | 3429 (bibtex-map-entries |
3483 (lambda (key beg end) | 3430 (lambda (key beg end) |
3484 (bibtex-progress-message) | 3431 (bibtex-progress-message) |
3485 (let* ((entry-list (progn | 3432 (let* ((entry-list (assoc-string (bibtex-type-in-head) |
3486 (goto-char beg) | 3433 bibtex-entry-field-alist t)) |
3487 (bibtex-search-entry nil end) | |
3488 (assoc-string (bibtex-type-in-head) | |
3489 bibtex-entry-field-alist t))) | |
3490 (req (copy-sequence (elt (elt entry-list 1) 0))) | 3434 (req (copy-sequence (elt (elt entry-list 1) 0))) |
3491 (creq (copy-sequence (elt (elt entry-list 2) 0))) | 3435 (creq (copy-sequence (elt (elt entry-list 2) 0))) |
3492 crossref-there bounds alt-there field) | 3436 crossref-there bounds alt-there field) |
3493 (goto-char beg) | 3437 (bibtex-beginning-first-field beg) |
3494 (while (setq bounds (bibtex-search-forward-field | 3438 (while (setq bounds (bibtex-parse-field)) |
3495 bibtex-field-name end)) | |
3496 (goto-char (bibtex-start-of-text-in-field bounds)) | |
3497 (let ((field-name (bibtex-name-in-field bounds))) | 3439 (let ((field-name (bibtex-name-in-field bounds))) |
3498 (if (and (bibtex-string= field-name "month") | 3440 (if (and (bibtex-string= field-name "month") |
3499 ;; Check only abbreviated month fields. | 3441 ;; Check only abbreviated month fields. |
3500 (let ((month (bibtex-text-in-field-bounds bounds))) | 3442 (let ((month (bibtex-text-in-field-bounds bounds))) |
3501 (not (or (string-match "\\`[\"{].+[\"}]\\'" month) | 3443 (not (or (string-match "\\`[\"{].+[\"}]\\'" month) |
3503 month | 3445 month |
3504 bibtex-predefined-month-strings t))))) | 3446 bibtex-predefined-month-strings t))))) |
3505 (push (cons (bibtex-current-line) | 3447 (push (cons (bibtex-current-line) |
3506 "Questionable month field") | 3448 "Questionable month field") |
3507 error-list)) | 3449 error-list)) |
3508 (setq field (assoc-string field-name req t)) | 3450 (setq field (assoc-string field-name req t) |
3451 req (delete field req) | |
3452 creq (delete (assoc-string field-name creq t) creq)) | |
3509 (if (nth 3 field) | 3453 (if (nth 3 field) |
3510 (if alt-there (push (cons (bibtex-current-line) | 3454 (if alt-there |
3511 "More than one non-empty alternative") | 3455 (push (cons (bibtex-current-line) |
3512 error-list) | 3456 "More than one non-empty alternative") |
3457 error-list) | |
3513 (setq alt-there t))) | 3458 (setq alt-there t))) |
3514 (setq req (delete field req) | |
3515 creq (delete (assoc-string field-name creq t) creq)) | |
3516 (if (bibtex-string= field-name "crossref") | 3459 (if (bibtex-string= field-name "crossref") |
3517 (setq crossref-there t)))) | 3460 (setq crossref-there t))) |
3518 (if crossref-there | 3461 (goto-char (bibtex-end-of-field bounds))) |
3519 (setq req creq)) | 3462 (if crossref-there (setq req creq)) |
3520 (let (alt) | 3463 (let (alt) |
3521 (dolist (field req) | 3464 (dolist (field req) |
3522 (if (nth 3 field) | 3465 (if (nth 3 field) |
3523 (push (car field) alt) | 3466 (push (car field) alt) |
3524 (push (cons (save-excursion (goto-char beg) | 3467 (push (cons (save-excursion (goto-char beg) |
3555 (insert (format "%s:%d: %s\n" file (car err) (cdr err)))) | 3498 (insert (format "%s:%d: %s\n" file (car err) (cdr err)))) |
3556 (set-buffer-modified-p nil) | 3499 (set-buffer-modified-p nil) |
3557 (toggle-read-only 1) | 3500 (toggle-read-only 1) |
3558 (goto-line 3)) ; first error message | 3501 (goto-line 3)) ; first error message |
3559 (display-buffer err-buf) | 3502 (display-buffer err-buf) |
3560 ;; return nil | 3503 nil) ; return `nil' (i.e., buffer is invalid) |
3561 nil) | |
3562 (message "%s is syntactically correct" | 3504 (message "%s is syntactically correct" |
3563 (if mark-active "Region" "Buffer")) | 3505 (if mark-active "Region" "Buffer")) |
3564 t))) | 3506 t))) ; return `t' (i.e., buffer is valid) |
3565 | 3507 |
3566 (defun bibtex-validate-globally (&optional strings) | 3508 (defun bibtex-validate-globally (&optional strings) |
3567 "Check for duplicate keys in `bibtex-files'. | 3509 "Check for duplicate keys in `bibtex-files'. |
3568 With optional prefix arg STRINGS, check for duplicate strings, too. | 3510 With optional prefix arg STRINGS, check for duplicate strings, too. |
3569 Return t if test was successful, nil otherwise." | 3511 Return t if test was successful, nil otherwise." |
3595 (with-current-buffer current-buf | 3537 (with-current-buffer current-buf |
3596 (dolist (buffer buffer-list) | 3538 (dolist (buffer buffer-list) |
3597 (dolist (key (cdr (assq buffer buffer-key-list))) | 3539 (dolist (key (cdr (assq buffer buffer-key-list))) |
3598 (when (assoc-string key current-keys) | 3540 (when (assoc-string key current-keys) |
3599 (bibtex-find-entry key) | 3541 (bibtex-find-entry key) |
3600 (push (format "%s:%d: Duplicat key `%s' in %s\n" | 3542 (push (format "%s:%d: Duplicate key `%s' in %s\n" |
3601 (buffer-file-name) (bibtex-current-line) key | 3543 (buffer-file-name) (bibtex-current-line) key |
3602 (abbreviate-file-name (buffer-file-name buffer))) | 3544 (abbreviate-file-name (buffer-file-name buffer))) |
3603 error-list)))))) | 3545 error-list)))))) |
3604 | 3546 |
3605 ;; Process error list | 3547 ;; Process error list |
3613 (dolist (err (sort error-list 'string-lessp)) (insert err)) | 3555 (dolist (err (sort error-list 'string-lessp)) (insert err)) |
3614 (set-buffer-modified-p nil) | 3556 (set-buffer-modified-p nil) |
3615 (toggle-read-only 1) | 3557 (toggle-read-only 1) |
3616 (goto-line 3)) ; first error message | 3558 (goto-line 3)) ; first error message |
3617 (display-buffer err-buf) | 3559 (display-buffer err-buf) |
3618 ;; return nil | 3560 nil) ; return `nil' (i.e., buffer is invalid) |
3619 nil) | |
3620 (message "No duplicate keys.") | 3561 (message "No duplicate keys.") |
3621 t))) | 3562 t))) ; return `t' (i.e., buffer is valid) |
3622 | 3563 |
3623 (defun bibtex-next-field (begin) | 3564 (defun bibtex-next-field (begin &optional comma) |
3624 "Move point to end of text of next BibTeX field. | 3565 "Move point to end of text of next BibTeX field or entry head. |
3625 With prefix BEGIN non-nil, move point to its beginning." | 3566 With prefix BEGIN non-nil, move point to its beginning. Optional arg COMMA |
3626 (interactive "P") | 3567 is as in `bibtex-enclosing-field'. It is t for interactive calls." |
3627 (bibtex-inside-field) | 3568 (interactive (list current-prefix-arg t)) |
3628 (let ((start (point))) | 3569 (let ((bounds (bibtex-find-text-internal t nil comma)) |
3629 (condition-case () | 3570 end-of-entry) |
3630 (let ((bounds (bibtex-enclosing-field))) | 3571 (if (not bounds) |
3631 (goto-char (bibtex-end-of-field bounds)) | 3572 (setq end-of-entry t) |
3632 (forward-char 2)) | 3573 (goto-char (nth 3 bounds)) |
3633 (error | 3574 (if (assoc-string (car bounds) '("@String" "@Preamble") t) |
3634 (goto-char start) | 3575 (setq end-of-entry t) |
3635 (end-of-line) | 3576 ;; BibTeX key or field |
3636 (forward-char)))) | 3577 (if (looking-at ",[ \t\n]*") (goto-char (match-end 0))) |
3637 (bibtex-find-text begin)) | 3578 ;; end of entry |
3638 | 3579 (if (looking-at "[)}][ \t\n]*") (setq end-of-entry t)))) |
3639 (defun bibtex-find-text (&optional begin noerror) | 3580 (if (and end-of-entry |
3640 "Move point to end of text of current BibTeX field. | 3581 (re-search-forward bibtex-any-entry-maybe-empty-head nil t)) |
3582 (goto-char (match-beginning 0))) | |
3583 (bibtex-find-text begin nil bibtex-help-message))) | |
3584 | |
3585 (defun bibtex-find-text (&optional begin noerror help comma) | |
3586 "Move point to end of text of current BibTeX field or entry head. | |
3641 With optional prefix BEGIN non-nil, move point to its beginning. | 3587 With optional prefix BEGIN non-nil, move point to its beginning. |
3642 Unless NOERROR is non-nil, an error is signaled if point is not | 3588 Unless NOERROR is non-nil, an error is signaled if point is not |
3643 on a BibTeX field." | 3589 on a BibTeX field. If optional arg HELP is non-nil print help message. |
3644 (interactive "P") | 3590 When called interactively, the value of HELP is `bibtex-help-message'. |
3645 (let* ((pnt (point)) | 3591 Optional arg COMMA is as in `bibtex-enclosing-field'. It is t for |
3646 (_ (bibtex-inside-field)) | 3592 interactive calls." |
3647 (bounds (bibtex-enclosing-field t))) | 3593 (interactive (list current-prefix-arg nil bibtex-help-message t)) |
3648 (beginning-of-line) | 3594 (let ((bounds (bibtex-find-text-internal t nil comma))) |
3649 (cond (bounds | 3595 (cond (bounds |
3650 (if begin | 3596 (if begin |
3651 (progn (goto-char (bibtex-start-of-text-in-field bounds)) | 3597 (progn (goto-char (nth 1 bounds)) |
3652 (if (looking-at "[{\"]") | 3598 (if (looking-at "[{\"]") |
3653 (forward-char))) | 3599 (forward-char))) |
3654 (goto-char (bibtex-end-of-text-in-field bounds)) | 3600 (goto-char (nth 2 bounds)) |
3655 (if (or (= (preceding-char) ?}) | 3601 (if (memq (preceding-char) '(?} ?\")) |
3656 (= (preceding-char) ?\")) | |
3657 (forward-char -1))) | 3602 (forward-char -1))) |
3658 (if bibtex-help-message | 3603 (if help (bibtex-print-help-message (car bounds)))) |
3659 (bibtex-print-help-message))) | 3604 ((not noerror) (error "Not on BibTeX field"))))) |
3660 ((setq bounds (bibtex-parse-string)) | 3605 |
3661 (goto-char (if begin | 3606 (defun bibtex-find-text-internal (&optional noerror subfield comma) |
3662 (1+ (bibtex-start-of-text-in-string bounds)) | 3607 "Find text part of current BibTeX field or entry head. |
3663 (1- (bibtex-end-of-text-in-string bounds))))) | 3608 Return list (NAME START-TEXT END-TEXT END) with field or entry name, |
3664 ((looking-at bibtex-entry-maybe-empty-head) | 3609 start and end of text and end of field or entry head, or nil if not found. |
3665 (goto-char (if begin | 3610 If optional arg NOERROR is non-nil, an error message is suppressed if text |
3666 (match-beginning bibtex-key-in-head) | 3611 is not found. If optional arg SUBFIELD is non-nil START-TEXT and END-TEXT |
3667 (match-end 0)))) | 3612 correspond to the current subfield delimited by #. |
3668 (t | 3613 Optional arg COMMA is as in `bibtex-enclosing-field'." |
3669 (goto-char pnt) | 3614 (save-excursion |
3670 (unless noerror (error "Not on BibTeX field")))))) | 3615 (let ((pnt (point)) |
3671 | 3616 (bounds (bibtex-enclosing-field comma t)) |
3672 (defun bibtex-remove-OPT-or-ALT () | 3617 (case-fold-search t) |
3618 name start-text end-text end failure done no-sub) | |
3619 (bibtex-beginning-of-entry) | |
3620 (cond (bounds | |
3621 (setq name (bibtex-name-in-field bounds t) | |
3622 start-text (bibtex-start-of-text-in-field bounds) | |
3623 end-text (bibtex-end-of-text-in-field bounds) | |
3624 end (bibtex-end-of-field bounds))) | |
3625 ;; @String | |
3626 ((setq bounds (bibtex-parse-string t)) | |
3627 (if (<= pnt (bibtex-end-of-string bounds)) | |
3628 (setq name "@String" ;; not a field name! | |
3629 start-text (bibtex-start-of-text-in-string bounds) | |
3630 end-text (bibtex-end-of-text-in-string bounds) | |
3631 end (bibtex-end-of-string bounds)) | |
3632 (setq failure t))) | |
3633 ;; @Preamble | |
3634 ((setq bounds (bibtex-parse-preamble)) | |
3635 (if (<= pnt (bibtex-end-of-string bounds)) | |
3636 (setq name "@Preamble" ;; not a field name! | |
3637 start-text (bibtex-start-of-text-in-string bounds) | |
3638 end-text (bibtex-end-of-text-in-string bounds) | |
3639 end (bibtex-end-of-string bounds)) | |
3640 (setq failure t))) | |
3641 ;; BibTeX head | |
3642 ((looking-at bibtex-entry-maybe-empty-head) | |
3643 (goto-char (match-end 0)) | |
3644 (if comma (save-match-data | |
3645 (re-search-forward "\\=[ \t\n]*," nil t))) | |
3646 (if (<= pnt (point)) | |
3647 (setq name (match-string-no-properties bibtex-type-in-head) | |
3648 start-text (or (match-beginning bibtex-key-in-head) | |
3649 (match-end 0)) | |
3650 end-text (or (match-end bibtex-key-in-head) | |
3651 (match-end 0)) | |
3652 end end-text | |
3653 no-sub t) ;; subfields do not make sense | |
3654 (setq failure t))) | |
3655 (t (setq failure t))) | |
3656 (when (and subfield (not failure)) | |
3657 (setq failure no-sub) | |
3658 (unless failure | |
3659 (goto-char start-text) | |
3660 (while (not done) | |
3661 (if (or (prog1 (looking-at bibtex-field-const) | |
3662 (setq end-text (match-end 0))) | |
3663 (prog1 (setq bounds (bibtex-parse-field-string)) | |
3664 (setq end-text (cdr bounds)))) | |
3665 (progn | |
3666 (if (and (<= start-text pnt) (<= pnt end-text)) | |
3667 (setq done t) | |
3668 (goto-char end-text)) | |
3669 (if (looking-at "[ \t\n]*#[ \t\n]*") | |
3670 (setq start-text (goto-char (match-end 0))))) | |
3671 (setq done t failure t))))) | |
3672 (cond ((not failure) | |
3673 (list name start-text end-text end)) | |
3674 ((and no-sub (not noerror)) | |
3675 (error "Not on text part of BibTeX field")) | |
3676 ((not noerror) (error "Not on BibTeX field")))))) | |
3677 | |
3678 (defun bibtex-remove-OPT-or-ALT (&optional comma) | |
3673 "Remove the string starting optional/alternative fields. | 3679 "Remove the string starting optional/alternative fields. |
3674 Align text and go thereafter to end of text." | 3680 Align text and go thereafter to end of text. Optional arg COMMA |
3675 (interactive) | 3681 is as in `bibtex-enclosing-field'. It is t for interactive calls." |
3676 (bibtex-inside-field) | 3682 (interactive (list t)) |
3677 (let ((case-fold-search t) | 3683 (let ((case-fold-search t) |
3678 (bounds (bibtex-enclosing-field))) | 3684 (bounds (bibtex-enclosing-field comma))) |
3679 (save-excursion | 3685 (save-excursion |
3680 (goto-char (bibtex-start-of-name-in-field bounds)) | 3686 (goto-char (bibtex-start-of-name-in-field bounds)) |
3681 (when (looking-at "OPT\\|ALT") | 3687 (when (looking-at "OPT\\|ALT") |
3682 (delete-region (match-beginning 0) (match-end 0)) | 3688 (delete-region (match-beginning 0) (match-end 0)) |
3683 ;; make field non-OPT | 3689 ;; make field non-OPT |
3689 (insert " ")) | 3695 (insert " ")) |
3690 (search-forward "=") | 3696 (search-forward "=") |
3691 (delete-horizontal-space) | 3697 (delete-horizontal-space) |
3692 (if bibtex-align-at-equal-sign | 3698 (if bibtex-align-at-equal-sign |
3693 (insert " ") | 3699 (insert " ") |
3694 (indent-to-column bibtex-text-indentation)))) | 3700 (indent-to-column bibtex-text-indentation)))))) |
3695 (bibtex-inside-field))) | 3701 |
3696 | 3702 (defun bibtex-remove-delimiters (&optional comma) |
3697 (defun bibtex-remove-delimiters () | 3703 "Remove \"\" or {} around current BibTeX field text. |
3698 "Remove \"\" or {} around string." | 3704 Optional arg COMMA is as in `bibtex-enclosing-field'. It is t for |
3699 (interactive) | 3705 interactive calls." |
3700 (save-excursion | 3706 (interactive (list t)) |
3701 (bibtex-inside-field) | 3707 (let* ((bounds (bibtex-find-text-internal nil t comma)) |
3702 (let* ((bounds (bibtex-enclosing-field)) | 3708 (start (nth 1 bounds)) |
3703 (end (bibtex-end-of-text-in-field bounds)) | 3709 (end (nth 2 bounds))) |
3704 (start (bibtex-start-of-text-in-field bounds))) | 3710 (if (memq (char-before end) '(?\} ?\")) |
3705 (if (memq (char-before end) '(?\} ?\")) | 3711 (delete-region (1- end) end)) |
3706 (delete-region (1- end) end)) | 3712 (if (memq (char-after start) '(?\{ ?\")) |
3707 (if (memq (char-after start) '(?\{ ?\")) | 3713 (delete-region start (1+ start))))) |
3708 (delete-region start (1+ start)))))) | 3714 |
3709 | 3715 (defun bibtex-kill-field (&optional copy-only comma) |
3710 (defun bibtex-kill-field (&optional copy-only) | |
3711 "Kill the entire enclosing BibTeX field. | 3716 "Kill the entire enclosing BibTeX field. |
3712 With prefix arg COPY-ONLY, copy the current field to `bibtex-field-kill-ring', | 3717 With prefix arg COPY-ONLY, copy the current field to `bibtex-field-kill-ring', |
3713 but do not actually kill it." | 3718 but do not actually kill it. Optional arg COMMA is as in |
3714 (interactive "P") | 3719 `bibtex-enclosing-field'. It is t for interactive calls." |
3720 (interactive (list current-prefix-arg t)) | |
3715 (save-excursion | 3721 (save-excursion |
3716 (bibtex-inside-field) | |
3717 (let* ((case-fold-search t) | 3722 (let* ((case-fold-search t) |
3718 (bounds (bibtex-enclosing-field)) | 3723 (bounds (bibtex-enclosing-field comma)) |
3719 (end (bibtex-end-of-field bounds)) | 3724 (end (bibtex-end-of-field bounds)) |
3720 (beg (bibtex-start-of-field bounds))) | 3725 (beg (bibtex-start-of-field bounds))) |
3721 (goto-char end) | 3726 (goto-char end) |
3722 (skip-chars-forward " \t\n,") | 3727 (skip-chars-forward ",") |
3723 (push (list (bibtex-name-in-field bounds) nil | 3728 (push (list (bibtex-name-in-field bounds) nil |
3724 (bibtex-text-in-field-bounds bounds)) | 3729 (bibtex-text-in-field-bounds bounds)) |
3725 bibtex-field-kill-ring) | 3730 bibtex-field-kill-ring) |
3726 (if (> (length bibtex-field-kill-ring) bibtex-field-kill-ring-max) | 3731 (if (> (length bibtex-field-kill-ring) bibtex-field-kill-ring-max) |
3727 (setcdr (nthcdr (1- bibtex-field-kill-ring-max) | 3732 (setcdr (nthcdr (1- bibtex-field-kill-ring-max) |
3730 (setq bibtex-field-kill-ring-yank-pointer bibtex-field-kill-ring) | 3735 (setq bibtex-field-kill-ring-yank-pointer bibtex-field-kill-ring) |
3731 (unless copy-only | 3736 (unless copy-only |
3732 (delete-region beg end)))) | 3737 (delete-region beg end)))) |
3733 (setq bibtex-last-kill-command 'field)) | 3738 (setq bibtex-last-kill-command 'field)) |
3734 | 3739 |
3735 (defun bibtex-copy-field-as-kill () | 3740 (defun bibtex-copy-field-as-kill (&optional comma) |
3736 "Copy the BibTeX field at point to the kill ring." | 3741 "Copy the BibTeX field at point to the kill ring. |
3737 (interactive) | 3742 Optional arg COMMA is as in `bibtex-enclosing-field'. It is t for |
3738 (bibtex-kill-field t)) | 3743 interactive calls." |
3744 (interactive (list t)) | |
3745 (bibtex-kill-field t comma)) | |
3739 | 3746 |
3740 (defun bibtex-kill-entry (&optional copy-only) | 3747 (defun bibtex-kill-entry (&optional copy-only) |
3741 "Kill the entire enclosing BibTeX entry. | 3748 "Kill the entire enclosing BibTeX entry. |
3742 With prefix arg COPY-ONLY, copy the current entry to `bibtex-entry-kill-ring', | 3749 With prefix arg COPY-ONLY, copy the current entry to `bibtex-entry-kill-ring', |
3743 but do not actually kill it." | 3750 but do not actually kill it." |
3745 (save-excursion | 3752 (save-excursion |
3746 (let* ((case-fold-search t) | 3753 (let* ((case-fold-search t) |
3747 (beg (bibtex-beginning-of-entry)) | 3754 (beg (bibtex-beginning-of-entry)) |
3748 (end (progn (bibtex-end-of-entry) | 3755 (end (progn (bibtex-end-of-entry) |
3749 (if (re-search-forward | 3756 (if (re-search-forward |
3750 bibtex-entry-maybe-empty-head nil 'move) | 3757 bibtex-any-entry-maybe-empty-head nil 'move) |
3751 (goto-char (match-beginning 0))) | 3758 (goto-char (match-beginning 0))) |
3752 (point)))) | 3759 (point)))) |
3753 (push (buffer-substring-no-properties beg end) | 3760 (push (buffer-substring-no-properties beg end) |
3754 bibtex-entry-kill-ring) | 3761 bibtex-entry-kill-ring) |
3755 (if (> (length bibtex-entry-kill-ring) bibtex-entry-kill-ring-max) | 3762 (if (> (length bibtex-entry-kill-ring) bibtex-entry-kill-ring-max) |
3770 "Reinsert the last BibTeX item. | 3777 "Reinsert the last BibTeX item. |
3771 More precisely, reinsert the field or entry killed or yanked most recently. | 3778 More precisely, reinsert the field or entry killed or yanked most recently. |
3772 With argument N, reinsert the Nth most recently killed BibTeX item. | 3779 With argument N, reinsert the Nth most recently killed BibTeX item. |
3773 See also the command \\[bibtex-yank-pop]." | 3780 See also the command \\[bibtex-yank-pop]." |
3774 (interactive "*p") | 3781 (interactive "*p") |
3775 (bibtex-insert-kill (1- n)) | 3782 (bibtex-insert-kill (1- n) t) |
3776 (setq this-command 'bibtex-yank)) | 3783 (setq this-command 'bibtex-yank)) |
3777 | 3784 |
3778 (defun bibtex-yank-pop (n) | 3785 (defun bibtex-yank-pop (n) |
3779 "Replace just-yanked killed BibTeX item with a different item. | 3786 "Replace just-yanked killed BibTeX item with a different item. |
3780 This command is allowed only immediately after a `bibtex-yank' or a | 3787 This command is allowed only immediately after a `bibtex-yank' or a |
3781 `bibtex-yank-pop'. At such a time, the region contains a reinserted | 3788 `bibtex-yank-pop'. In this case, the region contains a reinserted |
3782 previously killed BibTeX item. `bibtex-yank-pop' deletes that item | 3789 previously killed BibTeX item. `bibtex-yank-pop' deletes that item |
3783 and inserts in its place a different killed BibTeX item. | 3790 and inserts in its place a different killed BibTeX item. |
3784 | 3791 |
3785 With no argument, the previous kill is inserted. | 3792 With no argument, the previous kill is inserted. |
3786 With argument N, insert the Nth previous kill. | 3793 With argument N, insert the Nth previous kill. |
3792 (unless (eq last-command 'bibtex-yank) | 3799 (unless (eq last-command 'bibtex-yank) |
3793 (error "Previous command was not a BibTeX yank")) | 3800 (error "Previous command was not a BibTeX yank")) |
3794 (setq this-command 'bibtex-yank) | 3801 (setq this-command 'bibtex-yank) |
3795 (let ((inhibit-read-only t)) | 3802 (let ((inhibit-read-only t)) |
3796 (delete-region (point) (mark t)) | 3803 (delete-region (point) (mark t)) |
3797 (bibtex-insert-kill n))) | 3804 (bibtex-insert-kill n t))) |
3798 | 3805 |
3799 (defun bibtex-empty-field () | 3806 (defun bibtex-empty-field (&optional comma) |
3800 "Delete the text part of the current field, replace with empty text." | 3807 "Delete the text part of the current field, replace with empty text. |
3801 (interactive) | 3808 Optional arg COMMA is as in `bibtex-enclosing-field'. It is t for |
3802 (bibtex-inside-field) | 3809 interactive calls." |
3803 (let ((bounds (bibtex-enclosing-field))) | 3810 (interactive (list t)) |
3811 (let ((bounds (bibtex-enclosing-field comma))) | |
3804 (goto-char (bibtex-start-of-text-in-field bounds)) | 3812 (goto-char (bibtex-start-of-text-in-field bounds)) |
3805 (delete-region (point) (bibtex-end-of-text-in-field bounds)) | 3813 (delete-region (point) (bibtex-end-of-text-in-field bounds)) |
3806 (insert (concat (bibtex-field-left-delimiter) | 3814 (insert (bibtex-field-left-delimiter) |
3807 (bibtex-field-right-delimiter)) ) | 3815 (bibtex-field-right-delimiter)) |
3808 (bibtex-find-text t))) | 3816 (bibtex-find-text t nil bibtex-help-message))) |
3809 | 3817 |
3810 (defun bibtex-pop-previous (arg) | 3818 (defun bibtex-pop-previous (arg) |
3811 "Replace text of current field with the similar field in previous entry. | 3819 "Replace text of current field with the similar field in previous entry. |
3812 With arg, goes up ARG entries. Repeated, goes up so many times. May be | 3820 With arg, goes up ARG entries. Repeated, goes up so many times. May be |
3813 intermixed with \\[bibtex-pop-next] (bibtex-pop-next)." | 3821 intermixed with \\[bibtex-pop-next] (bibtex-pop-next)." |
3835 ;; Opt. arg called-by-reformat is t if bibtex-clean-entry | 3843 ;; Opt. arg called-by-reformat is t if bibtex-clean-entry |
3836 ;; is called by bibtex-reformat | 3844 ;; is called by bibtex-reformat |
3837 (interactive "P") | 3845 (interactive "P") |
3838 (let ((case-fold-search t) | 3846 (let ((case-fold-search t) |
3839 (start (bibtex-beginning-of-entry)) | 3847 (start (bibtex-beginning-of-entry)) |
3840 (_ (looking-at bibtex-entry-maybe-empty-head)) | 3848 (_ (looking-at bibtex-any-entry-maybe-empty-head)) |
3841 (entry-type (bibtex-type-in-head)) | 3849 (entry-type (bibtex-type-in-head)) |
3842 (key (bibtex-key-in-head))) | 3850 (key (bibtex-key-in-head))) |
3843 ;; formatting | 3851 ;; formatting |
3844 (cond ((bibtex-string= entry-type "preamble") | 3852 (cond ((bibtex-string= entry-type "preamble") |
3845 ;; (bibtex-format-preamble) | 3853 ;; (bibtex-format-preamble) |
3899 ;; Only update the list of keys if it has been built already. | 3907 ;; Only update the list of keys if it has been built already. |
3900 (cond ((eq entry-type 'string) | 3908 (cond ((eq entry-type 'string) |
3901 (if (and (listp bibtex-strings) | 3909 (if (and (listp bibtex-strings) |
3902 (not (assoc key bibtex-strings))) | 3910 (not (assoc key bibtex-strings))) |
3903 (push (cons key (bibtex-text-in-string | 3911 (push (cons key (bibtex-text-in-string |
3904 (save-excursion (bibtex-parse-string)) t)) | 3912 (bibtex-parse-string) t)) |
3905 bibtex-strings))) | 3913 bibtex-strings))) |
3906 ;; We have a normal entry. | 3914 ;; We have a normal entry. |
3907 ((listp bibtex-reference-keys) | 3915 ((listp bibtex-reference-keys) |
3908 (cond ((not (assoc key bibtex-reference-keys)) | 3916 (cond ((not (assoc key bibtex-reference-keys)) |
3909 (push (cons key t) bibtex-reference-keys)) | 3917 (push (cons key t) bibtex-reference-keys)) |
3927 (defun bibtex-fill-field-bounds (bounds justify &optional move) | 3935 (defun bibtex-fill-field-bounds (bounds justify &optional move) |
3928 "Fill BibTeX field delimited by BOUNDS. | 3936 "Fill BibTeX field delimited by BOUNDS. |
3929 If JUSTIFY is non-nil justify as well. | 3937 If JUSTIFY is non-nil justify as well. |
3930 If optional arg MOVE is non-nil move point to end of field." | 3938 If optional arg MOVE is non-nil move point to end of field." |
3931 (let ((end-field (copy-marker (bibtex-end-of-field bounds)))) | 3939 (let ((end-field (copy-marker (bibtex-end-of-field bounds)))) |
3932 (goto-char (bibtex-start-of-field bounds)) | 3940 (if (not justify) |
3933 (if justify | 3941 (goto-char (bibtex-start-of-text-in-field bounds)) |
3934 (progn | 3942 (goto-char (bibtex-start-of-field bounds)) |
3935 (forward-char) | 3943 (forward-char) ;; leading comma |
3936 (bibtex-delete-whitespace) | 3944 (bibtex-delete-whitespace) |
3937 (open-line 1) | 3945 (open-line 1) |
3938 (forward-char) | 3946 (forward-char) |
3939 (indent-to-column (+ bibtex-entry-offset | 3947 (indent-to-column (+ bibtex-entry-offset |
3940 bibtex-field-indentation)) | 3948 bibtex-field-indentation)) |
3941 (re-search-forward "[ \t\n]*=" end-field) | 3949 (re-search-forward "[ \t\n]*=" end-field) |
3942 (replace-match "=") | 3950 (replace-match "=") |
3943 (forward-char -1) | 3951 (forward-char -1) |
3944 (if bibtex-align-at-equal-sign | 3952 (if bibtex-align-at-equal-sign |
3945 (indent-to-column | 3953 (indent-to-column |
3946 (+ bibtex-entry-offset (- bibtex-text-indentation 2))) | 3954 (+ bibtex-entry-offset (- bibtex-text-indentation 2))) |
3947 (insert " ")) | 3955 (insert " ")) |
3948 (forward-char) | 3956 (forward-char) |
3949 (bibtex-delete-whitespace) | 3957 (bibtex-delete-whitespace) |
3950 (if bibtex-align-at-equal-sign | 3958 (if bibtex-align-at-equal-sign |
3951 (insert " ") | 3959 (insert " ") |
3952 (indent-to-column bibtex-text-indentation))) | 3960 (indent-to-column bibtex-text-indentation))) |
3953 (re-search-forward "[ \t\n]*=[ \t\n]*" end-field)) | |
3954 ;; Paragraphs within fields are not preserved. Bother? | 3961 ;; Paragraphs within fields are not preserved. Bother? |
3955 (fill-region-as-paragraph (line-beginning-position) end-field | 3962 (fill-region-as-paragraph (line-beginning-position) end-field |
3956 default-justification nil (point)) | 3963 default-justification nil (point)) |
3957 (if move (goto-char end-field)))) | 3964 (if move (goto-char end-field)))) |
3958 | 3965 |
3959 (defun bibtex-fill-field (&optional justify) | 3966 (defun bibtex-fill-field (&optional justify) |
3960 "Like \\[fill-paragraph], but fill current BibTeX field. | 3967 "Like \\[fill-paragraph], but fill current BibTeX field. |
3961 Optional prefix arg JUSTIFY non-nil means justify as well. | 3968 If optional prefix JUSTIFY is non-nil justify as well. |
3962 In BibTeX mode this function is bound to `fill-paragraph-function'." | 3969 In BibTeX mode this function is bound to `fill-paragraph-function'." |
3963 (interactive "*P") | 3970 (interactive "*P") |
3964 (let ((pnt (copy-marker (point))) | 3971 (let ((pnt (copy-marker (point))) |
3965 (bounds (bibtex-enclosing-field))) | 3972 (bounds (bibtex-enclosing-field t))) |
3966 (when bounds | 3973 (bibtex-fill-field-bounds bounds justify) |
3967 (bibtex-fill-field-bounds bounds justify) | 3974 (goto-char pnt))) |
3968 (goto-char pnt)))) | |
3969 | 3975 |
3970 (defun bibtex-fill-entry () | 3976 (defun bibtex-fill-entry () |
3971 "Fill current BibTeX entry. | 3977 "Fill current BibTeX entry. |
3972 Realign entry, so that every field starts on a separate line. Field | 3978 Realign entry, so that every field starts on a separate line. Field |
3973 names appear in column `bibtex-field-indentation', field text starts in | 3979 names appear in column `bibtex-field-indentation', field text starts in |
3974 column `bibtex-text-indentation' and continuation lines start here, too. | 3980 column `bibtex-text-indentation' and continuation lines start here, too. |
3975 If `bibtex-align-at-equal-sign' is non-nil, align equal signs, too." | 3981 If `bibtex-align-at-equal-sign' is non-nil, align equal signs, too." |
3976 (interactive "*") | 3982 (interactive "*") |
3977 (let ((pnt (copy-marker (point))) | 3983 (let ((pnt (copy-marker (point))) |
3978 (end (copy-marker (bibtex-end-of-entry))) | 3984 (end (copy-marker (bibtex-end-of-entry))) |
3985 (beg (bibtex-beginning-of-entry)) ; move point | |
3979 bounds) | 3986 bounds) |
3980 (bibtex-beginning-of-entry) | |
3981 (bibtex-delete-whitespace) | 3987 (bibtex-delete-whitespace) |
3982 (indent-to-column bibtex-entry-offset) | 3988 (indent-to-column bibtex-entry-offset) |
3983 (while (setq bounds (bibtex-search-forward-field bibtex-field-name end)) | 3989 (bibtex-beginning-first-field beg) |
3990 (while (setq bounds (bibtex-parse-field)) | |
3984 (bibtex-fill-field-bounds bounds t t)) | 3991 (bibtex-fill-field-bounds bounds t t)) |
3985 (if (looking-at ",") | 3992 (if (looking-at ",") |
3986 (forward-char)) | 3993 (forward-char)) |
3994 (skip-chars-backward " \t\n") | |
3987 (bibtex-delete-whitespace) | 3995 (bibtex-delete-whitespace) |
3988 (open-line 1) | 3996 (open-line 1) |
3989 (forward-char) | 3997 (forward-char) |
3990 (indent-to-column bibtex-entry-offset) | 3998 (indent-to-column bibtex-entry-offset) |
3991 (goto-char pnt))) | 3999 (goto-char pnt))) |
3992 | 4000 |
3993 (defun bibtex-realign () | 4001 (defun bibtex-realign () |
3994 "Realign BibTeX entries such that they are separated by one blank line." | 4002 "Realign BibTeX entries such that they are separated by one blank line." |
3995 (goto-char (point-min)) | 4003 (goto-char (point-min)) |
3996 (let ((case-fold-search t) | 4004 (let ((case-fold-search t) |
3997 (valid-entry (concat "[ \t\n]*\\(" bibtex-valid-entry-re "\\)"))) | 4005 (entry-type (concat "[ \t\n]*\\(" bibtex-entry-type "\\)"))) |
3998 ;; No blank lines prior to the first valid entry if there no | 4006 ;; No blank lines prior to the first entry if there no |
3999 ;; non-white characters in front of it. | 4007 ;; non-white characters in front of it. |
4000 (when (looking-at valid-entry) | 4008 (when (looking-at entry-type) |
4001 (replace-match "\\1")) | 4009 (replace-match "\\1")) |
4002 ;; Valid entries are separated by one blank line. | 4010 ;; Entries are separated by one blank line. |
4003 (while (re-search-forward valid-entry nil t) | 4011 (while (re-search-forward entry-type nil t) |
4004 (replace-match "\n\n\\1")) | 4012 (replace-match "\n\n\\1")) |
4005 ;; One blank line past the last valid entry if it is followed by | 4013 ;; One blank line past the last entry if it is followed by |
4006 ;; non-white characters, no blank line otherwise. | 4014 ;; non-white characters, no blank line otherwise. |
4007 (beginning-of-line) | 4015 (beginning-of-line) |
4008 (when (re-search-forward bibtex-valid-entry-re nil t) | 4016 (when (re-search-forward bibtex-entry-type nil t) |
4009 (bibtex-end-of-entry) | 4017 (bibtex-end-of-entry) |
4010 (bibtex-delete-whitespace) | 4018 (bibtex-delete-whitespace) |
4011 (open-line (if (eobp) 1 2))))) | 4019 (open-line (if (eobp) 1 2))))) |
4012 | 4020 |
4013 (defun bibtex-reformat (&optional read-options) | 4021 (defun bibtex-reformat (&optional read-options) |
4054 (y-or-n-p "Generate new reference keys automatically? "))))) | 4062 (y-or-n-p "Generate new reference keys automatically? "))))) |
4055 (bibtex-sort-ignore-string-entries t) | 4063 (bibtex-sort-ignore-string-entries t) |
4056 bibtex-autokey-edit-before-use) | 4064 bibtex-autokey-edit-before-use) |
4057 | 4065 |
4058 (save-restriction | 4066 (save-restriction |
4059 (narrow-to-region (if mark-active (region-beginning) (point-min)) | 4067 (if mark-active (narrow-to-region (region-beginning) (region-end))) |
4060 (if mark-active (region-end) (point-max))) | |
4061 (if (memq 'realign bibtex-entry-format) | 4068 (if (memq 'realign bibtex-entry-format) |
4062 (bibtex-realign)) | 4069 (bibtex-realign)) |
4063 (bibtex-progress-message "Formatting" 1) | 4070 (bibtex-progress-message "Formatting" 1) |
4064 (bibtex-map-entries (lambda (key beg end) | 4071 (bibtex-map-entries (lambda (key beg end) |
4065 (bibtex-progress-message) | 4072 (bibtex-progress-message) |
4082 entries from minibuffer." | 4089 entries from minibuffer." |
4083 (interactive "*P") | 4090 (interactive "*P") |
4084 (message "Starting to validate buffer...") | 4091 (message "Starting to validate buffer...") |
4085 (sit-for 1 nil t) | 4092 (sit-for 1 nil t) |
4086 (bibtex-realign) | 4093 (bibtex-realign) |
4087 (message | |
4088 "If errors occur, correct them and call `bibtex-convert-alien' again") | |
4089 (sit-for 5 nil t) | |
4090 (deactivate-mark) ; So bibtex-validate works on the whole buffer. | 4094 (deactivate-mark) ; So bibtex-validate works on the whole buffer. |
4091 (when (let (bibtex-maintain-sorted-entries) | 4095 (if (not (let (bibtex-maintain-sorted-entries) |
4092 (bibtex-validate)) | 4096 (bibtex-validate))) |
4097 (message "Correct errors and call `bibtex-convert-alien' again") | |
4093 (message "Starting to reformat entries...") | 4098 (message "Starting to reformat entries...") |
4094 (sit-for 2 nil t) | 4099 (sit-for 2 nil t) |
4095 (bibtex-reformat read-options) | 4100 (bibtex-reformat read-options) |
4096 (goto-char (point-max)) | 4101 (goto-char (point-max)) |
4097 (message "Buffer is now parsable. Please save it."))) | 4102 (message "Buffer is now parsable. Please save it."))) |
4099 (defun bibtex-complete () | 4104 (defun bibtex-complete () |
4100 "Complete word fragment before point according to context. | 4105 "Complete word fragment before point according to context. |
4101 If point is inside key or crossref field perform key completion based on | 4106 If point is inside key or crossref field perform key completion based on |
4102 `bibtex-reference-keys'. Inside a month field perform key completion | 4107 `bibtex-reference-keys'. Inside a month field perform key completion |
4103 based on `bibtex-predefined-month-strings'. Inside any other field | 4108 based on `bibtex-predefined-month-strings'. Inside any other field |
4104 perform string completion based on `bibtex-strings'. An error is | 4109 \(including a String or Preamble definition) perform string completion |
4105 signaled if point is outside key or BibTeX field." | 4110 based on `bibtex-strings'. |
4111 An error is signaled if point is outside key or BibTeX field." | |
4106 (interactive) | 4112 (interactive) |
4107 (let ((pnt (point)) | 4113 (let ((pnt (point)) |
4108 (case-fold-search t) | 4114 (case-fold-search t) |
4109 bounds name compl) | 4115 bounds name compl) |
4110 (save-excursion | 4116 (save-excursion |
4111 (if (and (setq bounds (bibtex-enclosing-field t)) | 4117 (if (and (setq bounds (bibtex-enclosing-field nil t)) |
4112 (>= pnt (bibtex-start-of-text-in-field bounds)) | 4118 (>= pnt (bibtex-start-of-text-in-field bounds)) |
4113 (<= pnt (bibtex-end-of-text-in-field bounds))) | 4119 (<= pnt (bibtex-end-of-text-in-field bounds))) |
4114 (setq name (bibtex-name-in-field bounds t) | 4120 (setq name (bibtex-name-in-field bounds t) |
4115 compl (cond ((bibtex-string= name "crossref") | 4121 compl (cond ((bibtex-string= name "crossref") |
4116 ;; point is in crossref field | 4122 ;; point is in crossref field |
4117 'crossref-key) | 4123 'crossref-key) |
4118 ((bibtex-string= name "month") | 4124 ((bibtex-string= name "month") |
4119 ;; point is in month field | 4125 ;; point is in month field |
4120 bibtex-predefined-month-strings) | 4126 bibtex-predefined-month-strings) |
4121 ;; point is in other field | 4127 ;; point is in other field |
4122 (t (if (listp bibtex-strings) | 4128 (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) | 4129 (bibtex-beginning-of-entry) |
4129 (cond ((and (looking-at bibtex-string-maybe-empty-head) | 4130 (cond ((setq bounds (bibtex-parse-string t)) |
4130 ;; point is inside a string key | 4131 ;; point is inside a @String key |
4131 (or (and (match-beginning bibtex-key-in-head) | 4132 (cond ((and (>= pnt (nth 1 (car bounds))) |
4132 (>= pnt (match-beginning bibtex-key-in-head)) | 4133 (<= pnt (nth 2 (car bounds)))) |
4133 (<= pnt (match-end bibtex-key-in-head))) | 4134 (setq compl 'string)) |
4134 ;; or point is on empty string key | 4135 ;; point is inside a @String field |
4135 (and (not (match-beginning bibtex-key-in-head)) | 4136 ((and (>= pnt (bibtex-start-of-text-in-string bounds)) |
4136 (= pnt (match-end 0))))) | 4137 (<= pnt (bibtex-end-of-text-in-string bounds))) |
4137 (setq compl 'string)) | 4138 (setq compl (bibtex-strings))))) |
4139 ;; point is inside a @Preamble field | |
4140 ((setq bounds (bibtex-parse-preamble)) | |
4141 (if (and (>= pnt (bibtex-start-of-text-in-string bounds)) | |
4142 (<= pnt (bibtex-end-of-text-in-string bounds))) | |
4143 (setq compl (bibtex-strings)))) | |
4138 ((and (looking-at bibtex-entry-maybe-empty-head) | 4144 ((and (looking-at bibtex-entry-maybe-empty-head) |
4139 ;; point is inside a key | 4145 ;; point is inside a key |
4140 (or (and (match-beginning bibtex-key-in-head) | 4146 (or (and (match-beginning bibtex-key-in-head) |
4141 (>= pnt (match-beginning bibtex-key-in-head)) | 4147 (>= pnt (match-beginning bibtex-key-in-head)) |
4142 (<= pnt (match-end bibtex-key-in-head))) | 4148 (<= pnt (match-end bibtex-key-in-head))) |
4145 (= pnt (match-end 0))))) | 4151 (= pnt (match-end 0))))) |
4146 (setq compl 'key))))) | 4152 (setq compl 'key))))) |
4147 | 4153 |
4148 (cond ((eq compl 'key) | 4154 (cond ((eq compl 'key) |
4149 ;; key completion: no cleanup needed | 4155 ;; key completion: no cleanup needed |
4150 (let (completion-ignore-case) | 4156 (setq choose-completion-string-functions nil |
4151 (bibtex-complete-internal (bibtex-global-key-alist)))) | 4157 completion-ignore-case nil) |
4158 (bibtex-complete-internal (bibtex-global-key-alist))) | |
4152 | 4159 |
4153 ((eq compl 'crossref-key) | 4160 ((eq compl 'crossref-key) |
4154 ;; crossref key completion | 4161 ;; crossref key completion |
4155 (let (completion-ignore-case) | 4162 ;; |
4156 (setq choose-completion-string-functions | 4163 ;; If we quit the *Completions* buffer without requesting |
4157 (lambda (choice buffer mini-p base-size) | 4164 ;; a completion, `choose-completion-string-functions' is still |
4158 (let ((choose-completion-string-functions nil)) | 4165 ;; non-nil. Therefore, `choose-completion-string-functions' is |
4159 (choose-completion-string choice buffer base-size)) | 4166 ;; always set (either to non-nil or nil) when a new completion |
4160 (bibtex-complete-crossref-cleanup choice) | 4167 ;; is requested. |
4161 ;; return t (needed by choose-completion-string-functions) | 4168 ;; Also, `choose-completion-delete-max-match' requires |
4162 t)) | 4169 ;; that we set `completion-ignore-case' (i.e., binding via `let' |
4163 (bibtex-complete-crossref-cleanup (bibtex-complete-internal | 4170 ;; is not sufficient). |
4164 (bibtex-global-key-alist))))) | 4171 (setq completion-ignore-case nil |
4172 choose-completion-string-functions | |
4173 (lambda (choice buffer mini-p base-size) | |
4174 (setq choose-completion-string-functions nil) | |
4175 (choose-completion-string choice buffer base-size) | |
4176 (bibtex-complete-crossref-cleanup choice) | |
4177 t)) ; needed by choose-completion-string-functions | |
4178 | |
4179 (bibtex-complete-crossref-cleanup (bibtex-complete-internal | |
4180 (bibtex-global-key-alist)))) | |
4165 | 4181 |
4166 ((eq compl 'string) | 4182 ((eq compl 'string) |
4167 ;; string key completion: no cleanup needed | 4183 ;; string key completion: no cleanup needed |
4168 (let ((completion-ignore-case t)) | 4184 (setq choose-completion-string-functions nil |
4169 (bibtex-complete-internal bibtex-strings))) | 4185 completion-ignore-case t) |
4186 (bibtex-complete-internal bibtex-strings)) | |
4170 | 4187 |
4171 (compl | 4188 (compl |
4172 ;; string completion | 4189 ;; string completion |
4173 (let ((completion-ignore-case t)) | 4190 (setq completion-ignore-case t |
4174 (setq choose-completion-string-functions | 4191 choose-completion-string-functions |
4175 `(lambda (choice buffer mini-p base-size) | 4192 `(lambda (choice buffer mini-p base-size) |
4176 (let ((choose-completion-string-functions nil)) | 4193 (setq choose-completion-string-functions nil) |
4177 (choose-completion-string choice buffer base-size)) | 4194 (choose-completion-string choice buffer base-size) |
4178 (bibtex-complete-string-cleanup choice ',compl) | 4195 (bibtex-complete-string-cleanup choice ',compl) |
4179 ;; return t (needed by choose-completion-string-functions) | 4196 t)) ; needed by choose-completion-string-functions |
4180 t)) | 4197 (bibtex-complete-string-cleanup (bibtex-complete-internal compl) |
4181 (bibtex-complete-string-cleanup (bibtex-complete-internal compl) | 4198 compl)) |
4182 compl))) | 4199 |
4183 | 4200 (t (setq choose-completion-string-functions nil |
4184 (t (error "Point outside key or BibTeX field"))))) | 4201 completion-ignore-case nil) ; default |
4202 (error "Point outside key or BibTeX field"))))) | |
4185 | 4203 |
4186 (defun bibtex-Article () | 4204 (defun bibtex-Article () |
4187 "Insert a new BibTeX @Article entry; see also `bibtex-entry'." | 4205 "Insert a new BibTeX @Article entry; see also `bibtex-entry'." |
4188 (interactive "*") | 4206 (interactive "*") |
4189 (bibtex-entry "Article")) | 4207 (bibtex-entry "Article")) |
4280 (indent-to-column bibtex-entry-offset) | 4298 (indent-to-column bibtex-entry-offset) |
4281 (insert "@Preamble" | 4299 (insert "@Preamble" |
4282 (bibtex-entry-left-delimiter) | 4300 (bibtex-entry-left-delimiter) |
4283 (bibtex-field-left-delimiter)) | 4301 (bibtex-field-left-delimiter)) |
4284 (let ((endpos (point))) | 4302 (let ((endpos (point))) |
4285 (insert (bibtex-entry-right-delimiter) | 4303 (insert (bibtex-field-right-delimiter) |
4286 (bibtex-field-right-delimiter) | 4304 (bibtex-entry-right-delimiter) |
4287 "\n") | 4305 "\n") |
4288 (goto-char endpos))) | 4306 (goto-char endpos))) |
4289 | 4307 |
4290 (defun bibtex-url (&optional pos) | 4308 (defun bibtex-url (&optional pos) |
4291 "Browse a URL for the BibTeX entry at point. | 4309 "Browse a URL for the BibTeX entry at point. |
4294 \(see there\). Then the URL is passed to `browse-url'." | 4312 \(see there\). Then the URL is passed to `browse-url'." |
4295 (interactive) | 4313 (interactive) |
4296 (save-excursion | 4314 (save-excursion |
4297 (if pos (goto-char pos)) | 4315 (if pos (goto-char pos)) |
4298 (bibtex-beginning-of-entry) | 4316 (bibtex-beginning-of-entry) |
4299 (let ((fields-alist (bibtex-parse-entry)) | 4317 ;; Always remove field delimiters |
4318 (let ((fields-alist (bibtex-parse-entry t)) | |
4300 ;; Always ignore case, | 4319 ;; Always ignore case, |
4301 (case-fold-search t) | 4320 (case-fold-search t) |
4302 (lst bibtex-generate-url-list) | 4321 (lst bibtex-generate-url-list) |
4303 field url scheme obj fmt) | 4322 field url scheme obj fmt) |
4304 (while (setq scheme (pop lst)) | 4323 (while (setq scheme (pop lst)) |
4305 (when (and (setq field (cdr (assoc-string (caar scheme) | 4324 (when (and (setq field (cdr (assoc-string (caar scheme) |
4306 fields-alist t))) | 4325 fields-alist t))) |
4307 ;; Always remove field delimiters | 4326 (string-match (cdar scheme) field)) |
4308 (progn (setq field (bibtex-remove-delimiters-string field)) | |
4309 (string-match (cdar scheme) field))) | |
4310 (setq lst nil | 4327 (setq lst nil |
4311 scheme (cdr scheme) | 4328 scheme (cdr scheme) |
4312 url (if (null scheme) (match-string 0 field) | 4329 url (if (null scheme) (match-string 0 field) |
4313 (if (stringp (car scheme)) | 4330 (if (stringp (car scheme)) |
4314 (setq fmt (pop scheme))) | 4331 (setq fmt (pop scheme))) |
4315 (dolist (step scheme) | 4332 (dolist (step scheme) |
4316 ;; Always remove field delimiters | 4333 (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) | 4334 (if (string-match (nth 1 step) field) |
4320 (setq field (cond ((functionp (nth 2 step)) | 4335 (setq field (cond ((functionp (nth 2 step)) |
4321 (funcall (nth 2 step) field)) | 4336 (funcall (nth 2 step) field)) |
4322 ((numberp (nth 2 step)) | 4337 ((numberp (nth 2 step)) |
4323 (match-string (nth 2 step) field)) | 4338 (match-string (nth 2 step) field)) |