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