640 |
|
|
641 |
(defcustom bibtex-autokey-titleword-ignore |
(defcustom bibtex-autokey-titleword-ignore |
642 |
'("A" "An" "On" "The" "Eine?" "Der" "Die" "Das" |
'("A" "An" "On" "The" "Eine?" "Der" "Die" "Das" |
643 |
"[^A-Z].*" ".*[^a-zA-Z0-9].*") |
"[^A-Z].*" ".*[^A-Z0-9].*") |
644 |
"*Determines words from the title that are not to be used in the key. |
"*Determines words from the title that are not to be used in the key. |
645 |
Each item of the list is a regexp. If a word of the title matchs a |
Each item of the list is a regexp. If a word of the title matchs a |
646 |
regexp from that list, it is not included in the title part of the key. |
regexp from that list, it is not included in the title part of the key. |
762 |
"Automatically fill fields if possible for those BibTeX entry types." |
"Automatically fill fields if possible for those BibTeX entry types." |
763 |
:type '(repeat string)) |
:type '(repeat string)) |
764 |
|
|
765 |
(defcustom bibtex-complete-key-cleanup nil |
(defcustom bibtex-generate-url-list |
766 |
"*Function called by `bibtex-complete' after insertion of a key fragment." |
'((("url" . t) ("url" t))) |
767 |
:group 'bibtex-autokey |
"List of schemes for generating the URL of a BibTeX entry. |
768 |
:type '(choice (const :tag "None" nil) |
These schemes are used by `bibtex-url'. |
769 |
(function :tag "Cleanup function"))) |
|
770 |
|
Each scheme is of the form ((FIELD . REGEXP) STEPS). |
771 |
|
|
772 |
|
FIELD is a field name as returned by `bibtex-parse-entry'. |
773 |
|
REGEXP is matched against the text of FIELD. |
774 |
|
If the match succeeds, the list STEPS is used to generate the URL. |
775 |
|
If REGEXP is t, always generate the URL if FIELD is present. |
776 |
|
|
777 |
|
If an element of STEPS is a list (FIELD MATCH FILTER), |
778 |
|
the text of FIELD is matched against MATCH. |
779 |
|
If MATCH is t, the text of FIELD is accepted as is. |
780 |
|
If MATCH is a cons cell (REGEXP . REPLACE), the text is matched against REGEXP. |
781 |
|
If REPLACE is a string, the text is replaced with REPLACE. If REPLACE is a |
782 |
|
number, it specifies which parenthesized expression in the match is taken. |
783 |
|
The optional element FILTER is a function for piping the match through it. |
784 |
|
The text strings are then concatenated to generate the URL. |
785 |
|
|
786 |
|
If an element of STEPS is a string, it is simply added to the URL. |
787 |
|
|
788 |
|
Case is always ignored. Always remove the field delimiters." |
789 |
|
:group 'bibtex |
790 |
|
:type '(repeat |
791 |
|
(list :tag "Scheme" |
792 |
|
(cons :tag "Matcher" :extra-offset 4 |
793 |
|
(string :tag "BibTeX field") |
794 |
|
(choice (regexp :tag "Regexp") |
795 |
|
(const :tag "Accept as is" t))) |
796 |
|
(repeat :tag "Steps to generate URL" :inline t |
797 |
|
(choice |
798 |
|
(string :tag "Literal text") |
799 |
|
(list (string :tag "BibTeX field") |
800 |
|
(choice (const :tag "Accept as is" t) |
801 |
|
(cons (string :tag "Field") |
802 |
|
(choice (regexp :tag "Regexp") |
803 |
|
(integer :tag "Matched parenthesis")))) |
804 |
|
(option (function :tag "Filter" :value ignore)))))))) |
805 |
|
|
806 |
;; bibtex-font-lock-keywords is a user option as well, but since the |
;; bibtex-font-lock-keywords is a user option as well, but since the |
807 |
;; patterns used to define this variable are defined in a later |
;; patterns used to define this variable are defined in a later |
836 |
(define-key km "\C-c}" 'bibtex-remove-delimiters) |
(define-key km "\C-c}" 'bibtex-remove-delimiters) |
837 |
(define-key km "\C-c\C-c" 'bibtex-clean-entry) |
(define-key km "\C-c\C-c" 'bibtex-clean-entry) |
838 |
(define-key km "\C-c\C-q" 'bibtex-fill-entry) |
(define-key km "\C-c\C-q" 'bibtex-fill-entry) |
839 |
|
(define-key km "\C-c\C-s" 'bibtex-find-entry) |
840 |
(define-key km "\C-c?" 'bibtex-print-help-message) |
(define-key km "\C-c?" 'bibtex-print-help-message) |
841 |
(define-key km "\C-c\C-p" 'bibtex-pop-previous) |
(define-key km "\C-c\C-p" 'bibtex-pop-previous) |
842 |
(define-key km "\C-c\C-n" 'bibtex-pop-next) |
(define-key km "\C-c\C-n" 'bibtex-pop-next) |
857 |
(define-key km "\C-c\C-b" 'bibtex-entry) |
(define-key km "\C-c\C-b" 'bibtex-entry) |
858 |
(define-key km "\C-c\C-rn" 'bibtex-narrow-to-entry) |
(define-key km "\C-c\C-rn" 'bibtex-narrow-to-entry) |
859 |
(define-key km "\C-c\C-rw" 'widen) |
(define-key km "\C-c\C-rw" 'widen) |
860 |
|
(define-key km "\C-c\C-l" 'bibtex-url) |
861 |
(define-key km "\C-c\C-o" 'bibtex-remove-OPT-or-ALT) |
(define-key km "\C-c\C-o" 'bibtex-remove-OPT-or-ALT) |
862 |
(define-key km "\C-c\C-e\C-i" 'bibtex-InProceedings) |
(define-key km "\C-c\C-e\C-i" 'bibtex-InProceedings) |
863 |
(define-key km "\C-c\C-ei" 'bibtex-InCollection) |
(define-key km "\C-c\C-ei" 'bibtex-InCollection) |
891 |
("Moving in BibTeX Buffer" |
("Moving in BibTeX Buffer" |
892 |
["Find Entry" bibtex-find-entry t] |
["Find Entry" bibtex-find-entry t] |
893 |
["Find Crossref Entry" bibtex-find-crossref t]) |
["Find Crossref Entry" bibtex-find-crossref t]) |
|
("Operating on Current Entry" |
|
|
["Fill Entry" bibtex-fill-entry t] |
|
|
["Clean Entry" bibtex-clean-entry t] |
|
894 |
"--" |
"--" |
|
["Kill Entry" bibtex-kill-entry t] |
|
|
["Copy Entry to Kill Ring" bibtex-copy-entry-as-kill t] |
|
|
["Paste Most Recently Killed Entry" bibtex-yank t] |
|
|
["Paste Previously Killed Entry" bibtex-yank-pop t] |
|
|
"--" |
|
|
["Ispell Entry" bibtex-ispell-entry t] |
|
|
["Ispell Entry Abstract" bibtex-ispell-abstract t] |
|
|
["Narrow to Entry" bibtex-narrow-to-entry t] |
|
|
"--" |
|
|
["View Cite Locations (RefTeX)" reftex-view-crossref-from-bibtex |
|
|
(fboundp 'reftex-view-crossref-from-bibtex)]) |
|
895 |
("Operating on Current Field" |
("Operating on Current Field" |
896 |
["Fill Field" fill-paragraph t] |
["Fill Field" fill-paragraph t] |
897 |
["Remove Delimiters" bibtex-remove-delimiters t] |
["Remove Delimiters" bibtex-remove-delimiters t] |
911 |
["String or Key Complete" bibtex-complete t] |
["String or Key Complete" bibtex-complete t] |
912 |
"--" |
"--" |
913 |
["Help about Current Field" bibtex-print-help-message t]) |
["Help about Current Field" bibtex-print-help-message t]) |
914 |
|
("Operating on Current Entry" |
915 |
|
["Fill Entry" bibtex-fill-entry t] |
916 |
|
["Clean Entry" bibtex-clean-entry t] |
917 |
|
["Update Entry" bibtex-entry-update t] |
918 |
|
"--" |
919 |
|
["Kill Entry" bibtex-kill-entry t] |
920 |
|
["Copy Entry to Kill Ring" bibtex-copy-entry-as-kill t] |
921 |
|
["Paste Most Recently Killed Entry" bibtex-yank t] |
922 |
|
["Paste Previously Killed Entry" bibtex-yank-pop t] |
923 |
|
"--" |
924 |
|
["Ispell Entry" bibtex-ispell-entry t] |
925 |
|
["Ispell Entry Abstract" bibtex-ispell-abstract t] |
926 |
|
["Narrow to Entry" bibtex-narrow-to-entry t] |
927 |
|
"--" |
928 |
|
["View Cite Locations (RefTeX)" reftex-view-crossref-from-bibtex |
929 |
|
(fboundp 'reftex-view-crossref-from-bibtex)]) |
930 |
("Operating on Buffer or Region" |
("Operating on Buffer or Region" |
931 |
["Validate Entries" bibtex-validate t] |
["Validate Entries" bibtex-validate t] |
932 |
["Sort Entries" bibtex-sort-buffer t] |
["Sort Entries" bibtex-sort-buffer t] |
933 |
["Reformat Entries" bibtex-reformat t] |
["Reformat Entries" bibtex-reformat t] |
934 |
["Count Entries" bibtex-count-entries t]) |
["Count Entries" bibtex-count-entries t] |
935 |
("Miscellaneous" |
"--" |
936 |
["Convert Alien Buffer" bibtex-convert-alien t]))) |
["Convert Alien Buffer" bibtex-convert-alien t]))) |
937 |
|
|
938 |
(easy-menu-define |
(easy-menu-define |
954 |
["String" bibtex-String t] |
["String" bibtex-String t] |
955 |
["Preamble" bibtex-Preamble t])) |
["Preamble" bibtex-Preamble t])) |
956 |
|
|
957 |
|
(defvar bibtex-url-map |
958 |
|
(let ((km (make-sparse-keymap))) |
959 |
|
(define-key km [(mouse-2)] 'bibtex-url) |
960 |
|
km) |
961 |
|
"Local keymap for clickable URLs.") |
962 |
|
(fset 'bibtex-url-map bibtex-url-map) |
963 |
|
|
964 |
|
|
965 |
;; Internal Variables |
;; Internal Variables |
966 |
|
|
1086 |
(defconst bibtex-empty-field-re "\"\"\\|{}" |
(defconst bibtex-empty-field-re "\"\"\\|{}" |
1087 |
"Regexp matching an empty field.") |
"Regexp matching an empty field.") |
1088 |
|
|
|
(defconst bibtex-quoted-string-re |
|
|
(concat "\"" |
|
|
"\\(" |
|
|
"[^\"\\]" ; anything but quote or backslash |
|
|
"\\|" |
|
|
"\\(" |
|
|
"\\\\\\(.\\|\n\\)" ; any backslash quoted character |
|
|
"\\)" |
|
|
"\\)*" |
|
|
"\"") |
|
|
"Regexp matching a field string enclosed by quotes.") |
|
|
|
|
1089 |
(defconst bibtex-font-lock-syntactic-keywords |
(defconst bibtex-font-lock-syntactic-keywords |
1090 |
`((,(concat "^[ \t]*\\(" (substring bibtex-comment-start 0 1) "\\)" |
`((,(concat "^[ \t]*\\(" (substring bibtex-comment-start 0 1) "\\)" |
1091 |
(substring bibtex-comment-start 1) "\\>") |
(substring bibtex-comment-start 1) "\\>") |
1092 |
1 '(11)))) |
1 '(11)))) |
1093 |
|
|
1094 |
(defvar bibtex-font-lock-keywords |
(defvar bibtex-font-lock-keywords |
1095 |
(list |
;; entry type and reference key |
1096 |
;; entry type and reference key |
`((,bibtex-entry-maybe-empty-head |
1097 |
(list bibtex-entry-maybe-empty-head |
(,bibtex-type-in-head font-lock-function-name-face) |
1098 |
(list bibtex-type-in-head 'font-lock-function-name-face) |
(,bibtex-key-in-head font-lock-constant-face nil t)) |
1099 |
(list bibtex-key-in-head 'font-lock-constant-face nil t)) |
;; optional field names (treated as comments) |
1100 |
;; optional field names (treated as comments) |
(,(concat "^[ \t]*\\(OPT" bibtex-field-name "\\)[ \t]*=") |
1101 |
(list |
1 font-lock-comment-face) |
1102 |
(concat "^[ \t]*\\(OPT" bibtex-field-name "\\)[ \t]*=") |
;; field names |
1103 |
1 'font-lock-comment-face) |
(,(concat "^[ \t]*\\(" bibtex-field-name "\\)[ \t]*=") |
1104 |
;; field names |
1 font-lock-variable-name-face) |
1105 |
(list (concat "^[ \t]*\\(" bibtex-field-name "\\)[ \t]*=") |
;; url |
1106 |
1 'font-lock-variable-name-face)) |
(bibtex-font-lock-url 0 '(face nil mouse-face highlight |
1107 |
|
keymap bibtex-url-map))) |
1108 |
"*Default expressions to highlight in BibTeX mode.") |
"*Default expressions to highlight in BibTeX mode.") |
1109 |
|
|
1110 |
|
(defvar bibtex-font-lock-url-regexp |
1111 |
|
(concat "\\<" (regexp-opt (mapcar 'caar bibtex-generate-url-list) t) |
1112 |
|
"\\>[ \t]*=[ \t]*") |
1113 |
|
"Regexp for `bibtex-font-lock-url'.") |
1114 |
|
|
1115 |
(defvar bibtex-field-name-for-parsing nil |
(defvar bibtex-field-name-for-parsing nil |
1116 |
"Temporary variable storing the name string to be parsed by the callback |
"Temporary variable storing the name string to be parsed by the callback |
1117 |
function `bibtex-parse-field-name'.") |
function `bibtex-parse-field-name'.") |
1129 |
|
|
1130 |
;; Special support taking care of variants |
;; Special support taking care of variants |
1131 |
(defvar zmacs-regions) |
(defvar zmacs-regions) |
1132 |
(if (boundp 'mark-active) |
(defalias 'bibtex-mark-active |
1133 |
(defun bibtex-mark-active () |
(if (boundp 'mark-active) |
1134 |
;; In Emacs mark-active indicates if mark is active. |
;; In Emacs mark-active indicates if mark is active. |
1135 |
mark-active) |
(lambda () mark-active) |
|
(defun bibtex-mark-active () |
|
1136 |
;; In XEmacs (mark) returns nil when not active. |
;; In XEmacs (mark) returns nil when not active. |
1137 |
(if zmacs-regions (mark) (mark t)))) |
(lambda () (if zmacs-regions (mark) (mark t))))) |
1138 |
|
|
1139 |
(if (fboundp 'run-with-idle-timer) |
(defalias 'bibtex-run-with-idle-timer |
1140 |
;; timer.el is distributed with Emacs |
(if (fboundp 'run-with-idle-timer) |
1141 |
(fset 'bibtex-run-with-idle-timer 'run-with-idle-timer) |
;; timer.el is distributed with Emacs |
1142 |
;; timer.el is not distributed with XEmacs |
'run-with-idle-timer |
1143 |
;; Notice that this does not (yet) pass the arguments, but they |
;; timer.el is not distributed with XEmacs |
1144 |
;; are not used (yet) in bibtex.el. Fix if needed. |
;; Notice that this does not (yet) pass the arguments, but they |
1145 |
(defun bibtex-run-with-idle-timer (secs repeat function &rest args) |
;; are not used (yet) in bibtex.el. Fix if needed. |
1146 |
(start-itimer "bibtex" function secs (if repeat secs nil) t))) |
(lambda (secs repeat function &rest args) |
1147 |
|
(start-itimer "bibtex" function secs (if repeat secs nil) t)))) |
1148 |
|
|
1149 |
|
|
1150 |
;; Support for hideshow minor mode |
;; Support for hideshow minor mode |
1255 |
((setq boundaries (bibtex-parse-field-string)) |
((setq boundaries (bibtex-parse-field-string)) |
1256 |
(goto-char (cdr boundaries))) |
(goto-char (cdr boundaries))) |
1257 |
((setq failure t))) |
((setq failure t))) |
1258 |
(if (not (looking-at "[ \t\n]*#[ \t\n]*")) |
(if (looking-at "[ \t\n]*#[ \t\n]*") |
1259 |
(setq end-point (point)) |
(goto-char (match-end 0)) |
1260 |
(goto-char (match-end 0)))) |
(setq end-point (point)))) |
1261 |
(if (and (not failure) |
(if (and (not failure) |
1262 |
end-point) |
end-point) |
1263 |
(cons starting-point end-point)))) |
(cons starting-point end-point)))) |
1334 |
(defsubst bibtex-end-of-text-in-field (bounds) |
(defsubst bibtex-end-of-text-in-field (bounds) |
1335 |
(cddr bounds)) |
(cddr bounds)) |
1336 |
|
|
1337 |
(defun bibtex-name-in-field (bounds) |
(defun bibtex-name-in-field (bounds &optional remove-opt-alt) |
1338 |
"Get content of name in BibTeX field defined via BOUNDS." |
"Get content of name in BibTeX field defined via BOUNDS. |
1339 |
(buffer-substring-no-properties (nth 1 (car bounds)) |
If optional arg REMOVE-OPT-ALT is non-nil remove \"OPT\" and \"ALT\"." |
1340 |
(nth 2 (car bounds)))) |
(let ((name (buffer-substring-no-properties (nth 1 (car bounds)) |
1341 |
|
(nth 2 (car bounds))))) |
1342 |
|
(if (and remove-opt-alt |
1343 |
|
(string-match "\\`\\(OPT\\|ALT\\)" name)) |
1344 |
|
(substring name 3) |
1345 |
|
name))) |
1346 |
|
|
1347 |
(defun bibtex-text-in-field-bounds (bounds &optional remove-delim) |
(defun bibtex-text-in-field-bounds (bounds &optional remove-delim) |
1348 |
"Get content of text in BibTeX field defined via BOUNDS. |
"Get content of text in BibTeX field defined via BOUNDS. |
1483 |
|
|
1484 |
;; Helper Functions |
;; Helper Functions |
1485 |
|
|
1486 |
|
(defsubst bibtex-string= (str1 str2) |
1487 |
|
"Return t if two strings are equal, ignoring case." |
1488 |
|
(eq t (compare-strings str1 0 nil str2 0 nil t))) |
1489 |
|
|
1490 |
(defun bibtex-delete-whitespace () |
(defun bibtex-delete-whitespace () |
1491 |
"Delete all whitespace starting at point." |
"Delete all whitespace starting at point." |
1492 |
(if (looking-at "[ \t\n]+") |
(if (looking-at "[ \t\n]+") |
1497 |
(+ (count-lines 1 (point)) |
(+ (count-lines 1 (point)) |
1498 |
(if (equal (current-column) 0) 1 0))) |
(if (equal (current-column) 0) 1 0))) |
1499 |
|
|
|
(defun bibtex-member-of-regexp (string list) |
|
|
"Return non-nil if STRING is exactly matched by an element of LIST. |
|
|
The value is actually the tail of LIST whose car matches STRING." |
|
|
(let (case-fold-search) |
|
|
(while (and list |
|
|
(not (string-match (concat "\\`\\(?:" (car list) "\\)\\'") string))) |
|
|
(setq list (cdr list))) |
|
|
list)) |
|
|
|
|
1500 |
(defun bibtex-skip-to-valid-entry (&optional backward) |
(defun bibtex-skip-to-valid-entry (&optional backward) |
1501 |
"Unless at beginning of a valid BibTeX entry, move point to beginning of the |
"Unless at beginning of a valid BibTeX entry, move point to beginning of the |
1502 |
next valid one. With optional argument BACKWARD non-nil, move backward to |
next valid one. With optional argument BACKWARD non-nil, move backward to |
1541 |
(end (copy-marker (save-excursion (bibtex-end-of-entry))))) |
(end (copy-marker (save-excursion (bibtex-end-of-entry))))) |
1542 |
(save-excursion |
(save-excursion |
1543 |
(if (or (and (not bibtex-sort-ignore-string-entries) |
(if (or (and (not bibtex-sort-ignore-string-entries) |
1544 |
(string-equal "string" (downcase entry-type))) |
(bibtex-string= entry-type "string")) |
1545 |
(assoc-string entry-type bibtex-entry-field-alist t)) |
(assoc-string entry-type bibtex-entry-field-alist t)) |
1546 |
(funcall fun key beg end))) |
(funcall fun key beg end))) |
1547 |
(goto-char end))))) |
(goto-char end))))) |
1615 |
(if found |
(if found |
1616 |
(progn (goto-char (match-beginning 0)) |
(progn (goto-char (match-beginning 0)) |
1617 |
found) |
found) |
1618 |
(cond ((equal noerror nil) |
(cond ((not noerror) |
1619 |
;; yell |
;; yell |
1620 |
(error "Backward search of BibTeX entry failed")) |
(error "Backward search of BibTeX entry failed")) |
1621 |
((equal noerror t) |
((equal noerror t) |
1724 |
(forward-char -1))) |
(forward-char -1))) |
1725 |
|
|
1726 |
(defun bibtex-enclosing-field (&optional noerr) |
(defun bibtex-enclosing-field (&optional noerr) |
1727 |
"Search for BibTeX field enclosing point. Point moves to end of field. |
"Search for BibTeX field enclosing point. |
1728 |
Use `match-beginning' and `match-end' to parse the field. If NOERR is non-nil, |
Use `match-beginning' and `match-end' to parse the field. If NOERR is non-nil, |
1729 |
no error is signalled. In this case, bounds are returned on success, |
no error is signalled. In this case, bounds are returned on success, |
1730 |
nil otherwise." |
nil otherwise. Does not move point." |
1731 |
(let ((bounds (bibtex-search-backward-field bibtex-field-name t))) |
(let ((bounds (bibtex-search-backward-field bibtex-field-name t))) |
1732 |
(if (and bounds |
(if (and bounds |
1733 |
(<= (bibtex-start-of-field bounds) (point)) |
(<= (bibtex-start-of-field bounds) (point)) |
1772 |
(message "Mark set") |
(message "Mark set") |
1773 |
(bibtex-make-field (list (elt current 1) nil (elt current 2)) t)) |
(bibtex-make-field (list (elt current 1) nil (elt current 2)) t)) |
1774 |
((equal bibtex-last-kill-command 'entry) |
((equal bibtex-last-kill-command 'entry) |
1775 |
(if (not (eobp)) |
(unless (eobp) (bibtex-beginning-of-entry)) |
|
(bibtex-beginning-of-entry)) |
|
1776 |
(set-mark (point)) |
(set-mark (point)) |
1777 |
(message "Mark set") |
(message "Mark set") |
1778 |
(insert (elt current 1))) |
(insert (elt current 1))) |
1780 |
(error "Unknown tag field: %s. Please submit a bug report" |
(error "Unknown tag field: %s. Please submit a bug report" |
1781 |
bibtex-last-kill-command)))))) |
bibtex-last-kill-command)))))) |
1782 |
|
|
|
(defun bibtex-assoc-regexp (regexp alist) |
|
|
"Return non-nil if REGEXP matches the car of an element of ALIST. |
|
|
The value is actually the element of ALIST matched by REGEXP. |
|
|
Case is ignored if `case-fold-search' is non-nil in the current buffer." |
|
|
(while (and alist |
|
|
(not (string-match regexp (caar alist)))) |
|
|
(setq alist (cdr alist))) |
|
|
(car alist)) |
|
|
|
|
1783 |
(defun bibtex-format-entry () |
(defun bibtex-format-entry () |
1784 |
"Helper function for `bibtex-clean-entry'. |
"Helper function for `bibtex-clean-entry'. |
1785 |
Formats current entry according to variable `bibtex-entry-format'." |
Formats current entry according to variable `bibtex-entry-format'." |
1794 |
unify-case inherit-booktitle) |
unify-case inherit-booktitle) |
1795 |
bibtex-entry-format)) |
bibtex-entry-format)) |
1796 |
crossref-key bounds alternatives-there non-empty-alternative |
crossref-key bounds alternatives-there non-empty-alternative |
1797 |
entry-list req-field-list field-done field-list) |
entry-list req-field-list field-list) |
1798 |
|
|
1799 |
;; identify entry type |
;; identify entry type |
1800 |
(goto-char (point-min)) |
(goto-char (point-min)) |
1822 |
;; one alternative is non-empty |
;; one alternative is non-empty |
1823 |
(goto-char (point-min)) |
(goto-char (point-min)) |
1824 |
(let* ((fields-alist (bibtex-parse-entry)) |
(let* ((fields-alist (bibtex-parse-entry)) |
1825 |
(case-fold-search t) |
(field (assoc-string "crossref" fields-alist t))) |
|
(field (bibtex-assoc-regexp "\\`\\(OPT\\)?crossref\\'" |
|
|
fields-alist))) |
|
1826 |
(setq crossref-key (and field |
(setq crossref-key (and field |
1827 |
(not (string-match bibtex-empty-field-re |
(not (string-match bibtex-empty-field-re |
1828 |
(cdr field))) |
(cdr field))) |
1834 |
(dolist (rfield req-field-list) |
(dolist (rfield req-field-list) |
1835 |
(when (nth 3 rfield) ; we should have an alternative |
(when (nth 3 rfield) ; we should have an alternative |
1836 |
(setq alternatives-there t |
(setq alternatives-there t |
1837 |
field (bibtex-assoc-regexp |
field (assoc-string (car rfield) fields-alist t)) |
|
(concat "\\`\\(ALT\\)?" (car rfield) "\\'") |
|
|
fields-alist)) |
|
1838 |
(if (and field |
(if (and field |
1839 |
(not (string-match bibtex-empty-field-re |
(not (string-match bibtex-empty-field-re |
1840 |
(cdr field)))) |
(cdr field)))) |
1913 |
|
|
1914 |
;; update page dashes |
;; update page dashes |
1915 |
(if (and (memq 'page-dashes format) |
(if (and (memq 'page-dashes format) |
1916 |
(string-match "\\`\\(OPT\\)?pages\\'" field-name) |
(bibtex-string= field-name "pages") |
1917 |
(progn (goto-char beg-text) |
(progn (goto-char beg-text) |
1918 |
(looking-at |
(looking-at |
1919 |
"\\([\"{][0-9]+\\)[ \t\n]*--?[ \t\n]*\\([0-9]+[\"}]\\)"))) |
"\\([\"{][0-9]+\\)[ \t\n]*--?[ \t\n]*\\([0-9]+[\"}]\\)"))) |
1922 |
;; use book title of crossref'd entry |
;; use book title of crossref'd entry |
1923 |
(if (and (memq 'inherit-booktitle format) |
(if (and (memq 'inherit-booktitle format) |
1924 |
empty-field |
empty-field |
1925 |
(equal (downcase field-name) "booktitle") |
(bibtex-string= field-name "booktitle") |
1926 |
crossref-key) |
crossref-key) |
1927 |
(let ((title (save-restriction |
(let ((title (save-restriction |
1928 |
(widen) |
(widen) |
1935 |
|
|
1936 |
;; Use booktitle to set a missing title. |
;; Use booktitle to set a missing title. |
1937 |
(if (and empty-field |
(if (and empty-field |
1938 |
(equal (downcase field-name) "title")) |
(bibtex-string= field-name "title")) |
1939 |
(let ((booktitle (bibtex-text-in-field "booktitle"))) |
(let ((booktitle (bibtex-text-in-field "booktitle"))) |
1940 |
(when booktitle |
(when booktitle |
1941 |
(setq empty-field nil) |
(setq empty-field nil) |
2049 |
"Get contents of the name field of the current entry. |
"Get contents of the name field of the current entry. |
2050 |
Do some modifications based on `bibtex-autokey-name-change-strings' |
Do some modifications based on `bibtex-autokey-name-change-strings' |
2051 |
and return results as a list." |
and return results as a list." |
2052 |
(let ((case-fold-search t)) |
(let ((case-fold-search t) |
2053 |
(mapcar 'bibtex-autokey-demangle-name |
(names (bibtex-autokey-get-field "author\\|editor" |
2054 |
(split-string (bibtex-autokey-get-field |
bibtex-autokey-name-change-strings))) |
2055 |
"author\\|editor" |
;; Some entries do not have a name field. |
2056 |
bibtex-autokey-name-change-strings) |
(unless (string= "" names) |
2057 |
"[ \t\n]+and[ \t\n]+")))) |
(mapcar 'bibtex-autokey-demangle-name |
2058 |
|
(split-string names "[ \t\n]+and[ \t\n]+"))))) |
2059 |
|
|
2060 |
(defun bibtex-autokey-demangle-name (fullname) |
(defun bibtex-autokey-demangle-name (fullname) |
2061 |
"Get the last part from a well-formed name and perform abbreviations." |
"Get the last part from a well-formed name and perform abbreviations." |
2086 |
|
|
2087 |
(defun bibtex-autokey-get-title () |
(defun bibtex-autokey-get-title () |
2088 |
"Get title field contents up to a terminator." |
"Get title field contents up to a terminator." |
2089 |
(let ((titlestring |
(let ((case-fold-search t) |
2090 |
|
(titlestring |
2091 |
(bibtex-autokey-get-field "title" |
(bibtex-autokey-get-field "title" |
2092 |
bibtex-autokey-titleword-change-strings))) |
bibtex-autokey-titleword-change-strings))) |
2093 |
;; ignore everything past a terminator |
;; ignore everything past a terminator |
2094 |
(let ((case-fold-search t)) |
(dolist (terminator bibtex-autokey-title-terminators) |
2095 |
(dolist (terminator bibtex-autokey-title-terminators) |
(if (string-match terminator titlestring) |
2096 |
(if (string-match terminator titlestring) |
(setq titlestring (substring titlestring 0 (match-beginning 0))))) |
|
(setq titlestring (substring titlestring 0 (match-beginning 0)))))) |
|
2097 |
;; gather words from titlestring into a list. Ignore |
;; gather words from titlestring into a list. Ignore |
2098 |
;; specific words and use only a specific amount of words. |
;; specific words and use only a specific amount of words. |
2099 |
(let ((counter 0) |
(let ((counter 0) |
2100 |
case-fold-search titlewords titlewords-extra titleword end-match) |
titlewords titlewords-extra titleword end-match) |
2101 |
(while (and (or (not (numberp bibtex-autokey-titlewords)) |
(while (and (or (not (numberp bibtex-autokey-titlewords)) |
2102 |
(< counter (+ bibtex-autokey-titlewords |
(< counter (+ bibtex-autokey-titlewords |
2103 |
bibtex-autokey-titlewords-stretch))) |
bibtex-autokey-titlewords-stretch))) |
2105 |
(setq end-match (match-end 0) |
(setq end-match (match-end 0) |
2106 |
titleword (substring titlestring |
titleword (substring titlestring |
2107 |
(match-beginning 0) end-match)) |
(match-beginning 0) end-match)) |
2108 |
(unless (bibtex-member-of-regexp titleword |
(unless (let ((lst bibtex-autokey-titleword-ignore)) |
2109 |
bibtex-autokey-titleword-ignore) |
(while (and lst |
2110 |
|
(not (string-match (concat "\\`\\(?:" (car lst) |
2111 |
|
"\\)\\'") titleword))) |
2112 |
|
(setq lst (cdr lst))) |
2113 |
|
lst) |
2114 |
(setq titleword |
(setq titleword |
2115 |
(funcall bibtex-autokey-titleword-case-convert titleword)) |
(funcall bibtex-autokey-titleword-case-convert titleword)) |
2116 |
(if (or (not (numberp bibtex-autokey-titlewords)) |
(if (or (not (numberp bibtex-autokey-titlewords)) |
2128 |
"Do some abbreviations on TITLEWORD. |
"Do some abbreviations on TITLEWORD. |
2129 |
The rules are defined in `bibtex-autokey-titleword-abbrevs' |
The rules are defined in `bibtex-autokey-titleword-abbrevs' |
2130 |
and `bibtex-autokey-titleword-length'." |
and `bibtex-autokey-titleword-length'." |
2131 |
(let ((case-folde-search t) |
(let ((case-fold-search t) |
2132 |
(alist bibtex-autokey-titleword-abbrevs)) |
(alist bibtex-autokey-titleword-abbrevs)) |
2133 |
(while (and alist |
(while (and alist |
2134 |
(not (string-match (concat "\\`\\(?:" (caar alist) "\\)\\'") |
(not (string-match (concat "\\`\\(?:" (caar alist) "\\)\\'") |
2339 |
bounds key) |
bounds key) |
2340 |
(if (listp add) |
(if (listp add) |
2341 |
(dolist (string add) |
(dolist (string add) |
2342 |
(unless (assoc (car string) strings) |
(unless (assoc-string (car string) strings t) |
2343 |
(push string strings)))) |
(push string strings)))) |
2344 |
(catch 'userkey |
(catch 'userkey |
2345 |
(while (setq bounds (bibtex-search-forward-string)) |
(while (setq bounds (bibtex-search-forward-string)) |
2348 |
;; user has aborted by typing a key --> return `aborted' |
;; user has aborted by typing a key --> return `aborted' |
2349 |
(throw 'userkey 'aborted)) |
(throw 'userkey 'aborted)) |
2350 |
(setq key (bibtex-reference-key-in-string bounds)) |
(setq key (bibtex-reference-key-in-string bounds)) |
2351 |
(if (not (assoc key strings)) |
(unless (assoc-string key strings t) |
2352 |
(push (cons key (bibtex-text-in-string bounds t)) |
(push (cons key (bibtex-text-in-string bounds t)) |
2353 |
strings)) |
strings)) |
2354 |
(goto-char (bibtex-end-of-text-in-string bounds))) |
(goto-char (bibtex-end-of-text-in-string bounds))) |
2355 |
;; successful operation --> return `bibtex-strings' |
;; successful operation --> return `bibtex-strings' |
2356 |
(setq bibtex-strings strings)))))) |
(setq bibtex-strings strings)))))) |
2440 |
;; return value is handled by choose-completion-string-functions |
;; return value is handled by choose-completion-string-functions |
2441 |
nil)))) |
nil)))) |
2442 |
|
|
2443 |
(defun bibtex-complete-string-cleanup (str) |
(defun bibtex-complete-string-cleanup (str strings-alist) |
2444 |
"Cleanup after inserting string STR. |
"Cleanup after inserting string STR. |
2445 |
Remove enclosing field delimiters for string STR. Display message with |
Remove enclosing field delimiters for string STR. Display message with |
2446 |
expansion of STR." |
expansion of STR using expansion list STRINGS-ALIST." |
2447 |
(let ((pair (assoc str bibtex-strings))) |
(let ((pair (if (stringp str) |
2448 |
|
(assoc-string str strings-alist t)))) |
2449 |
(when pair |
(when pair |
2450 |
(if (cdr pair) |
(if (cdr pair) |
2451 |
(message "Abbreviation for `%s'" (cdr pair))) |
(message "Abbreviation for `%s'" (cdr pair))) |
2459 |
(bibtex-end-of-text-in-field bounds))) |
(bibtex-end-of-text-in-field bounds))) |
2460 |
(bibtex-remove-delimiters)))))))) |
(bibtex-remove-delimiters)))))))) |
2461 |
|
|
2462 |
|
(defun bibtex-complete-key-cleanup (key) |
2463 |
|
"Display message on entry KEY after completion of a crossref key." |
2464 |
|
(save-excursion |
2465 |
|
;; Don't do anything if we completed the key of an entry. |
2466 |
|
(let ((pnt (bibtex-beginning-of-entry))) |
2467 |
|
(if (and (stringp key) |
2468 |
|
(bibtex-find-entry key) |
2469 |
|
(/= pnt (point))) |
2470 |
|
(let* ((bibtex-autokey-name-case-convert 'identity) |
2471 |
|
(bibtex-autokey-name-length 'infty) |
2472 |
|
(nl (bibtex-autokey-get-names)) |
2473 |
|
(name (concat (nth 0 nl) (if (nth 1 nl) " etal"))) |
2474 |
|
(year (bibtex-autokey-get-field "year")) |
2475 |
|
(bibtex-autokey-titlewords 5) |
2476 |
|
(bibtex-autokey-titlewords-stretch 2) |
2477 |
|
(bibtex-autokey-titleword-case-convert 'identity) |
2478 |
|
(bibtex-autokey-titleword-length 5) |
2479 |
|
(title (mapconcat 'identity |
2480 |
|
(bibtex-autokey-get-title) " ")) |
2481 |
|
(journal (bibtex-autokey-get-field |
2482 |
|
"journal" bibtex-autokey-transcriptions)) |
2483 |
|
(volume (bibtex-autokey-get-field "volume")) |
2484 |
|
(pages (bibtex-autokey-get-field "pages" '(("-.*\\'" . ""))))) |
2485 |
|
(message "Ref:%s" |
2486 |
|
(mapconcat (lambda (arg) |
2487 |
|
(if (not (string= "" (cdr arg))) |
2488 |
|
(concat (car arg) (cdr arg)))) |
2489 |
|
`((" " . ,name) (" " . ,year) |
2490 |
|
(": " . ,title) (", " . ,journal) |
2491 |
|
(" " . ,volume) (":" . ,pages)) |
2492 |
|
""))))))) |
2493 |
|
|
2494 |
(defun bibtex-choose-completion-string (choice buffer mini-p base-size) |
(defun bibtex-choose-completion-string (choice buffer mini-p base-size) |
2495 |
;; Code borrowed from choose-completion-string: |
;; Code borrowed from choose-completion-string: |
2496 |
;; We must duplicate the code from choose-completion-string |
;; We must duplicate the code from choose-completion-string |
2524 |
(bounds (bibtex-enclosing-field)) |
(bounds (bibtex-enclosing-field)) |
2525 |
(start-old-text (bibtex-start-of-text-in-field bounds)) |
(start-old-text (bibtex-start-of-text-in-field bounds)) |
2526 |
(stop-old-text (bibtex-end-of-text-in-field bounds)) |
(stop-old-text (bibtex-end-of-text-in-field bounds)) |
2527 |
(start-name (bibtex-start-of-name-in-field bounds)) |
(field-name (bibtex-name-in-field bounds t))) |
|
(stop-name (bibtex-end-of-name-in-field bounds)) |
|
|
;; construct regexp for field with same name as this one, |
|
|
;; ignoring possible OPT's or ALT's |
|
|
(field-name (progn |
|
|
(goto-char start-name) |
|
|
(buffer-substring-no-properties |
|
|
(if (looking-at "\\(OPT\\)\\|\\(ALT\\)") |
|
|
(match-end 0) |
|
|
(point)) |
|
|
stop-name)))) |
|
2528 |
;; if executed several times in a row, start each search where |
;; if executed several times in a row, start each search where |
2529 |
;; the last one was finished |
;; the last one was finished |
2530 |
(unless (eq last-command 'bibtex-pop) |
(unless (eq last-command 'bibtex-pop) |
2693 |
) |
) |
2694 |
nil |
nil |
2695 |
(font-lock-syntactic-keywords . bibtex-font-lock-syntactic-keywords) |
(font-lock-syntactic-keywords . bibtex-font-lock-syntactic-keywords) |
2696 |
|
(font-lock-extra-managed-props . (mouse-face keymap)) |
2697 |
(font-lock-mark-block-function |
(font-lock-mark-block-function |
2698 |
. (lambda () |
. (lambda () |
2699 |
(set-mark (bibtex-end-of-entry)) |
(set-mark (bibtex-end-of-entry)) |
2700 |
(bibtex-beginning-of-entry))))) |
(bibtex-beginning-of-entry))))) |
2701 |
(setq imenu-generic-expression |
(setq imenu-generic-expression |
2702 |
(list (list nil bibtex-entry-head bibtex-key-in-head))) |
(list (list nil bibtex-entry-head bibtex-key-in-head))) |
2777 |
(let* ((fields-alist (bibtex-parse-entry)) |
(let* ((fields-alist (bibtex-parse-entry)) |
2778 |
(field-list (bibtex-field-list |
(field-list (bibtex-field-list |
2779 |
(substring (cdr (assoc "=type=" fields-alist)) |
(substring (cdr (assoc "=type=" fields-alist)) |
2780 |
1))) ; don't want @ |
1)))) ; don't want @ |
|
(case-fold-search t)) |
|
2781 |
(dolist (field (car field-list)) |
(dolist (field (car field-list)) |
2782 |
(unless (bibtex-assoc-regexp (concat "\\`\\(ALT\\)?" (car field) "\\'") |
(unless (assoc-string (car field) fields-alist t) |
|
fields-alist) |
|
2783 |
(bibtex-make-field field))) |
(bibtex-make-field field))) |
2784 |
(dolist (field (cdr field-list)) |
(dolist (field (cdr field-list)) |
2785 |
(unless (bibtex-assoc-regexp (concat "\\`\\(OPT\\)?" (car field) "\\'") |
(unless (assoc-string (car field) fields-alist t) |
|
fields-alist) |
|
2786 |
(bibtex-make-optional-field field)))))) |
(bibtex-make-optional-field field)))))) |
2787 |
|
|
2788 |
(defun bibtex-parse-entry () |
(defun bibtex-parse-entry () |
2789 |
"Parse entry at point, return an alist. |
"Parse entry at point, return an alist. |
2790 |
The alist elements have the form (FIELD . TEXT), where FIELD can also be |
The alist elements have the form (FIELD . TEXT), where FIELD can also be |
2791 |
the special strings \"=type=\" and \"=key=\". For the FIELD \"=key=\" |
the special strings \"=type=\" and \"=key=\". For the FIELD \"=key=\" |
2792 |
TEXT may be nil. Move point to the end of the last field." |
TEXT may be nil. Remove \"OPT\" and \"ALT\" from FIELD. |
2793 |
|
Move point to the end of the last field." |
2794 |
(let (alist bounds) |
(let (alist bounds) |
2795 |
(when (looking-at bibtex-entry-maybe-empty-head) |
(when (looking-at bibtex-entry-maybe-empty-head) |
2796 |
(push (cons "=type=" (match-string bibtex-type-in-head)) alist) |
(push (cons "=type=" (match-string bibtex-type-in-head)) alist) |
2797 |
(push (cons "=key=" (match-string bibtex-key-in-head)) alist) |
(push (cons "=key=" (match-string bibtex-key-in-head)) alist) |
2798 |
(goto-char (match-end 0)) |
(goto-char (match-end 0)) |
2799 |
(while (setq bounds (bibtex-parse-field bibtex-field-name)) |
(while (setq bounds (bibtex-parse-field bibtex-field-name)) |
2800 |
(push (cons (bibtex-name-in-field bounds) |
(push (cons (bibtex-name-in-field bounds t) |
2801 |
(bibtex-text-in-field-bounds bounds)) |
(bibtex-text-in-field-bounds bounds)) |
2802 |
alist) |
alist) |
2803 |
(goto-char (bibtex-end-of-field bounds)))) |
(goto-char (bibtex-end-of-field bounds)))) |
2823 |
(bibtex-beginning-of-entry) |
(bibtex-beginning-of-entry) |
2824 |
(when (and |
(when (and |
2825 |
(looking-at bibtex-entry-head) |
(looking-at bibtex-entry-head) |
2826 |
(equal type (match-string bibtex-type-in-head)) |
(bibtex-string= type (match-string bibtex-type-in-head)) |
2827 |
;; In case we found ourselves :-( |
;; In case we found ourselves :-( |
2828 |
(not (equal key (setq tmp (match-string bibtex-key-in-head))))) |
(not (equal key (setq tmp (match-string bibtex-key-in-head))))) |
2829 |
(setq other-key tmp) |
(setq other-key tmp) |
2833 |
(bibtex-skip-to-valid-entry) |
(bibtex-skip-to-valid-entry) |
2834 |
(when (and |
(when (and |
2835 |
(looking-at bibtex-entry-head) |
(looking-at bibtex-entry-head) |
2836 |
(equal type (match-string bibtex-type-in-head)) |
(bibtex-string= type (match-string bibtex-type-in-head)) |
2837 |
;; In case we found ourselves :-( |
;; In case we found ourselves :-( |
2838 |
(not (equal key (setq tmp (match-string bibtex-key-in-head)))) |
(not (equal key (setq tmp (match-string bibtex-key-in-head)))) |
2839 |
(or (not other-key) |
(or (not other-key) |
2847 |
(setq other (save-excursion (goto-char other) (bibtex-parse-entry))) |
(setq other (save-excursion (goto-char other) (bibtex-parse-entry))) |
2848 |
(setq key-end (point)) ;In case parse-entry changed the buffer. |
(setq key-end (point)) ;In case parse-entry changed the buffer. |
2849 |
(while (setq bounds (bibtex-parse-field bibtex-field-name)) |
(while (setq bounds (bibtex-parse-field bibtex-field-name)) |
2850 |
(goto-char (bibtex-start-of-name-in-field bounds)) |
(let ((text (assoc-string (bibtex-name-in-field bounds t) |
2851 |
(let* ((name (buffer-substring |
other t))) |
|
(if (looking-at "ALT\\|OPT") (match-end 0) (point)) |
|
|
(bibtex-end-of-name-in-field bounds))) |
|
|
(text (assoc-string name other t))) |
|
2852 |
(goto-char (bibtex-start-of-text-in-field bounds)) |
(goto-char (bibtex-start-of-text-in-field bounds)) |
2853 |
(if (not (and (looking-at bibtex-empty-field-re) text)) |
(if (not (and (looking-at bibtex-empty-field-re) text)) |
2854 |
(goto-char (bibtex-end-of-field bounds)) |
(goto-char (bibtex-end-of-field bounds)) |
2871 |
(interactive) |
(interactive) |
2872 |
(save-excursion |
(save-excursion |
2873 |
(let* ((case-fold-search t) |
(let* ((case-fold-search t) |
2874 |
(bounds (bibtex-enclosing-field)) |
(field-name (bibtex-name-in-field (bibtex-enclosing-field) t)) |
|
(mb (bibtex-start-of-name-in-field bounds)) |
|
|
(field-name (buffer-substring-no-properties |
|
|
(if (progn (goto-char mb) |
|
|
(looking-at "OPT\\|ALT")) |
|
|
(match-end 0) mb) |
|
|
(bibtex-end-of-name-in-field bounds))) |
|
2875 |
(field-list (bibtex-field-list (progn (re-search-backward |
(field-list (bibtex-field-list (progn (re-search-backward |
2876 |
bibtex-entry-maybe-empty-head nil t) |
bibtex-entry-maybe-empty-head nil t) |
2877 |
(bibtex-type-in-head)))) |
(bibtex-type-in-head)))) |
2912 |
(indent-to-column (+ bibtex-entry-offset |
(indent-to-column (+ bibtex-entry-offset |
2913 |
(- bibtex-text-indentation 2)))) |
(- bibtex-text-indentation 2)))) |
2914 |
(insert "= ") |
(insert "= ") |
2915 |
(if (not bibtex-align-at-equal-sign) |
(unless bibtex-align-at-equal-sign |
2916 |
(indent-to-column (+ bibtex-entry-offset |
(indent-to-column (+ bibtex-entry-offset |
2917 |
bibtex-text-indentation))) |
bibtex-text-indentation))) |
2918 |
(if (not called-by-yank) (insert (bibtex-field-left-delimiter))) |
(unless called-by-yank (insert (bibtex-field-left-delimiter))) |
2919 |
(let ((init (nth 2 field))) |
(let ((init (nth 2 field))) |
2920 |
(cond ((stringp init) |
(cond ((stringp init) |
2921 |
(insert init)) |
(insert init)) |
2922 |
((fboundp init) |
((fboundp init) |
2923 |
(insert (funcall init))))) |
(insert (funcall init))))) |
2924 |
(if (not called-by-yank) (insert (bibtex-field-right-delimiter))) |
(unless called-by-yank (insert (bibtex-field-right-delimiter))) |
2925 |
(when (interactive-p) |
(when (interactive-p) |
2926 |
(forward-char -1) |
(forward-char -1) |
2927 |
(bibtex-print-help-message))) |
(bibtex-print-help-message))) |
3128 |
(error "This entry must not follow the crossrefed entry!")) |
(error "This entry must not follow the crossrefed entry!")) |
3129 |
(goto-char pos))) |
(goto-char pos))) |
3130 |
|
|
3131 |
(defun bibtex-find-entry (key) |
(defun bibtex-find-entry (key &optional start) |
3132 |
"Move point to the beginning of BibTeX entry named KEY. |
"Move point to the beginning of BibTeX entry named KEY. |
3133 |
Return position of entry if KEY is found or nil if not found." |
Return position of entry if KEY is found or nil if not found. |
3134 |
(interactive (list (bibtex-read-key "Find key: "))) |
Optional arg START is buffer position where the search starts. |
3135 |
|
If it is nil, start search at beginning of buffer. |
3136 |
|
With prefix arg, the value of START is position of point." |
3137 |
|
(interactive (list (bibtex-read-key "Find key: ") |
3138 |
|
(if current-prefix-arg (point)))) |
3139 |
(let* (case-fold-search |
(let* (case-fold-search |
3140 |
(pnt (save-excursion |
(pnt (save-excursion |
3141 |
(goto-char (point-min)) |
(goto-char (or start (point-min))) |
3142 |
(if (re-search-forward (concat "^[ \t]*\\(" |
(if (re-search-forward (concat "^[ \t]*\\(" |
3143 |
bibtex-entry-type |
bibtex-entry-type |
3144 |
"\\)[ \t]*[({][ \t\n]*\\(" |
"\\)[ \t]*[({][ \t\n]*\\(" |
3205 |
;; buffer contains no valid entries or |
;; buffer contains no valid entries or |
3206 |
;; greater than last entry --> append |
;; greater than last entry --> append |
3207 |
(bibtex-end-of-entry) |
(bibtex-end-of-entry) |
3208 |
(if (not (bobp)) |
(unless (bobp) (newline (forward-line 2))) |
|
(newline (forward-line 2))) |
|
3209 |
(beginning-of-line))))) |
(beginning-of-line))))) |
3210 |
(unless key-exist t))) |
(unless key-exist t))) |
3211 |
|
|
3280 |
(goto-char (point-min)) |
(goto-char (point-min)) |
3281 |
(bibtex-progress-message |
(bibtex-progress-message |
3282 |
"Checking required fields and month fields") |
"Checking required fields and month fields") |
3283 |
(let ((bibtex-sort-ignore-string-entries t) |
(let ((bibtex-sort-ignore-string-entries t)) |
|
(questionable-month |
|
|
(regexp-opt (mapcar 'car bibtex-predefined-month-strings)))) |
|
3284 |
(bibtex-map-entries |
(bibtex-map-entries |
3285 |
(lambda (key beg end) |
(lambda (key beg end) |
3286 |
(bibtex-progress-message) |
(bibtex-progress-message) |
3296 |
(while (setq bounds (bibtex-search-forward-field |
(while (setq bounds (bibtex-search-forward-field |
3297 |
bibtex-field-name end)) |
bibtex-field-name end)) |
3298 |
(goto-char (bibtex-start-of-text-in-field bounds)) |
(goto-char (bibtex-start-of-text-in-field bounds)) |
3299 |
(let ((field-name (downcase (bibtex-name-in-field bounds))) |
(let ((field-name (bibtex-name-in-field bounds))) |
3300 |
case-fold-search) |
(if (and (bibtex-string= field-name "month") |
3301 |
(if (and (equal field-name "month") |
(not (assoc-string (bibtex-text-in-field-bounds bounds) |
3302 |
(not (string-match questionable-month |
bibtex-predefined-month-strings t))) |
|
(bibtex-text-in-field-bounds bounds)))) |
|
3303 |
(push (list (bibtex-current-line) |
(push (list (bibtex-current-line) |
3304 |
"Questionable month field") |
"Questionable month field") |
3305 |
error-list)) |
error-list)) |
3306 |
(setq req (delete (assoc-string field-name req t) req) |
(setq req (delete (assoc-string field-name req t) req) |
3307 |
creq (delete (assoc-string field-name creq t) creq)) |
creq (delete (assoc-string field-name creq t) creq)) |
3308 |
(if (equal field-name "crossref") |
(if (bibtex-string= field-name "crossref") |
3309 |
(setq crossref-there t)))) |
(setq crossref-there t)))) |
3310 |
(if crossref-there |
(if crossref-there |
3311 |
(setq req creq)) |
(setq req creq)) |
3349 |
(dolist (err error-list) |
(dolist (err error-list) |
3350 |
(insert bufnam ":" (number-to-string (elt err 0)) |
(insert bufnam ":" (number-to-string (elt err 0)) |
3351 |
": " (elt err 1) "\n")) |
": " (elt err 1) "\n")) |
|
(compilation-parse-errors nil nil) |
|
|
(setq compilation-old-error-list compilation-error-list) |
|
|
;; this is necessary to avoid reparsing of buffer if you |
|
|
;; switch to compilation buffer and enter `compile-goto-error' |
|
3352 |
(set-buffer-modified-p nil) |
(set-buffer-modified-p nil) |
3353 |
(toggle-read-only 1) |
(toggle-read-only 1) |
3354 |
(goto-char (point-min)) |
(goto-char (point-min)) |
3435 |
(interactive) |
(interactive) |
3436 |
(save-excursion |
(save-excursion |
3437 |
(bibtex-inside-field) |
(bibtex-inside-field) |
3438 |
(let ((bounds (bibtex-enclosing-field))) |
(let* ((bounds (bibtex-enclosing-field)) |
3439 |
(goto-char (bibtex-start-of-text-in-field bounds)) |
(end (bibtex-end-of-text-in-field bounds)) |
3440 |
(delete-char 1) |
(start (bibtex-start-of-text-in-field bounds))) |
3441 |
(goto-char (1- (bibtex-end-of-text-in-field bounds))) |
(if (memq (char-before end) '(?\} ?\")) |
3442 |
(delete-backward-char 1)))) |
(delete-region (1- end) end)) |
3443 |
|
(if (memq (char-after start) '(?\{ ?\")) |
3444 |
|
(delete-region start (1+ start)))))) |
3445 |
|
|
3446 |
(defun bibtex-kill-field (&optional copy-only) |
(defun bibtex-kill-field (&optional copy-only) |
3447 |
"Kill the entire enclosing BibTeX field. |
"Kill the entire enclosing BibTeX field. |
3497 |
(setq bibtex-last-kill-command 'entry)) |
(setq bibtex-last-kill-command 'entry)) |
3498 |
|
|
3499 |
(defun bibtex-copy-entry-as-kill () |
(defun bibtex-copy-entry-as-kill () |
3500 |
|
"Copy the entire enclosing BibTeX entry to `bibtex-entry-kill-ring'." |
3501 |
(interactive) |
(interactive) |
3502 |
(bibtex-kill-entry t)) |
(bibtex-kill-entry t)) |
3503 |
|
|
3525 |
The sequence of kills wraps around, so that after the oldest one |
The sequence of kills wraps around, so that after the oldest one |
3526 |
comes the newest one." |
comes the newest one." |
3527 |
(interactive "*p") |
(interactive "*p") |
3528 |
(if (not (eq last-command 'bibtex-yank)) |
(unless (eq last-command 'bibtex-yank) |
3529 |
(error "Previous command was not a BibTeX yank")) |
(error "Previous command was not a BibTeX yank")) |
3530 |
(setq this-command 'bibtex-yank) |
(setq this-command 'bibtex-yank) |
3531 |
(let ((inhibit-read-only t)) |
(let ((inhibit-read-only t)) |
3532 |
(delete-region (point) (mark t)) |
(delete-region (point) (mark t)) |
3576 |
(bibtex-beginning-of-entry) |
(bibtex-beginning-of-entry) |
3577 |
(save-excursion |
(save-excursion |
3578 |
(when (re-search-forward bibtex-entry-maybe-empty-head nil t) |
(when (re-search-forward bibtex-entry-maybe-empty-head nil t) |
3579 |
(setq entry-type (downcase (bibtex-type-in-head))) |
(setq entry-type (bibtex-type-in-head)) |
3580 |
(setq key (bibtex-key-in-head)))) |
(setq key (bibtex-key-in-head)))) |
3581 |
;; formatting |
;; formatting |
3582 |
(cond ((equal entry-type "preamble") |
(cond ((bibtex-string= entry-type "preamble") |
3583 |
;; (bibtex-format-preamble) |
;; (bibtex-format-preamble) |
3584 |
(error "No clean up of @Preamble entries")) |
(error "No clean up of @Preamble entries")) |
3585 |
((equal entry-type "string")) |
((bibtex-string= entry-type "string")) |
3586 |
;; (bibtex-format-string) |
;; (bibtex-format-string) |
3587 |
(t (bibtex-format-entry))) |
(t (bibtex-format-entry))) |
3588 |
;; set key |
;; set key |
3589 |
(when (or new-key (not key)) |
(when (or new-key (not key)) |
3590 |
(setq key (bibtex-generate-autokey)) |
(setq key (bibtex-generate-autokey)) |
3591 |
(if bibtex-autokey-edit-before-use |
;; Sometimes bibtex-generate-autokey returns an empty string |
3592 |
|
(if (or bibtex-autokey-edit-before-use (string= "" key)) |
3593 |
(setq key (bibtex-read-key "Key to use: " key))) |
(setq key (bibtex-read-key "Key to use: " key))) |
3594 |
(re-search-forward bibtex-entry-maybe-empty-head) |
(re-search-forward bibtex-entry-maybe-empty-head) |
3595 |
(if (match-beginning bibtex-key-in-head) |
(if (match-beginning bibtex-key-in-head) |
3607 |
(entry (buffer-substring start end)) |
(entry (buffer-substring start end)) |
3608 |
(index (progn (goto-char start) |
(index (progn (goto-char start) |
3609 |
(bibtex-entry-index))) |
(bibtex-entry-index))) |
3610 |
no-error) |
error) |
3611 |
(if (and bibtex-maintain-sorted-entries |
(if (and bibtex-maintain-sorted-entries |
3612 |
(not (and bibtex-sort-ignore-string-entries |
(not (and bibtex-sort-ignore-string-entries |
3613 |
(equal entry-type "string")))) |
(bibtex-string= entry-type "string")))) |
3614 |
(progn |
(progn |
3615 |
(delete-region start end) |
(delete-region start end) |
3616 |
(setq no-error (bibtex-prepare-new-entry index)) |
(setq error (not (bibtex-prepare-new-entry index))) |
3617 |
(insert entry) |
(insert entry) |
3618 |
(forward-char -1) |
(forward-char -1) |
3619 |
(bibtex-beginning-of-entry) ; moves backward |
(bibtex-beginning-of-entry) ; moves backward |
3620 |
(re-search-forward bibtex-entry-head)) |
(re-search-forward bibtex-entry-head)) |
3621 |
(setq no-error (bibtex-find-entry (car index)))) |
(bibtex-find-entry key) |
3622 |
(unless no-error |
(setq error (or (/= (point) start) |
3623 |
|
(bibtex-find-entry key end)))) |
3624 |
|
(if error |
3625 |
(error "New inserted entry yields duplicate key")))) |
(error "New inserted entry yields duplicate key")))) |
3626 |
;; final clean up |
;; final clean up |
3627 |
(unless called-by-reformat |
(unless called-by-reformat |
3629 |
(save-restriction |
(save-restriction |
3630 |
(bibtex-narrow-to-entry) |
(bibtex-narrow-to-entry) |
3631 |
;; Only update the list of keys if it has been built already. |
;; Only update the list of keys if it has been built already. |
3632 |
(cond ((equal entry-type "string") |
(cond ((bibtex-string= entry-type "string") |
3633 |
(if (listp bibtex-strings) (bibtex-parse-strings t))) |
(if (listp bibtex-strings) (bibtex-parse-strings t))) |
3634 |
((listp bibtex-reference-keys) (bibtex-parse-keys t))) |
((listp bibtex-reference-keys) (bibtex-parse-keys t))) |
3635 |
(run-hooks 'bibtex-clean-entry-hook)))))) |
(run-hooks 'bibtex-clean-entry-hook)))))) |
3798 |
(defun bibtex-complete () |
(defun bibtex-complete () |
3799 |
"Complete word fragment before point according to context. |
"Complete word fragment before point according to context. |
3800 |
If point is inside key or crossref field perform key completion based on |
If point is inside key or crossref field perform key completion based on |
3801 |
`bibtex-reference-keys'. Inside any other field perform string |
`bibtex-reference-keys'. Inside a month field perform key completion |
3802 |
completion based on `bibtex-strings'. An error is signaled if point |
based on `bibtex-predefined-month-strings'. Inside any other field |
3803 |
is outside key or BibTeX field." |
perform string completion based on `bibtex-strings'. An error is |
3804 |
|
signaled if point is outside key or BibTeX field." |
3805 |
(interactive) |
(interactive) |
3806 |
(let* ((pnt (point)) |
(let ((pnt (point)) |
3807 |
(case-fold-search t) |
(case-fold-search t) |
3808 |
bounds compl) |
bounds name compl) |
3809 |
(save-excursion |
(save-excursion |
3810 |
(if (and (setq bounds (bibtex-enclosing-field t)) |
(if (and (setq bounds (bibtex-enclosing-field t)) |
3811 |
(>= pnt (bibtex-start-of-text-in-field bounds)) |
(>= pnt (bibtex-start-of-text-in-field bounds)) |
3812 |
(<= pnt (bibtex-end-of-text-in-field bounds))) |
(<= pnt (bibtex-end-of-text-in-field bounds))) |
3813 |
(progn |
(setq name (bibtex-name-in-field bounds t) |
3814 |
(goto-char (bibtex-start-of-name-in-field bounds)) |
compl (cond ((bibtex-string= name "crossref") |
3815 |
(setq compl (if (string= "crossref" |
'key) |
3816 |
(downcase |
((bibtex-string= name "month") |
3817 |
(buffer-substring-no-properties |
bibtex-predefined-month-strings) |
3818 |
(if (looking-at "\\(OPT\\)\\|\\(ALT\\)") |
(t (if (listp bibtex-strings) |
3819 |
(match-end 0) |
bibtex-strings |
3820 |
(point)) |
;; so that bibtex-complete-string-cleanup |
3821 |
(bibtex-end-of-name-in-field bounds)))) |
;; can do its job |
3822 |
'key |
(bibtex-parse-strings |
3823 |
'str))) |
(bibtex-string-files-init)))))) |
3824 |
(bibtex-beginning-of-entry) |
(bibtex-beginning-of-entry) |
3825 |
(if (and (re-search-forward bibtex-entry-maybe-empty-head nil t) |
(if (and (re-search-forward bibtex-entry-maybe-empty-head nil t) |
3826 |
;; point is inside a key |
;; point is inside a key |
3836 |
;; key completion |
;; key completion |
3837 |
(setq choose-completion-string-functions |
(setq choose-completion-string-functions |
3838 |
(lambda (choice buffer mini-p base-size) |
(lambda (choice buffer mini-p base-size) |
3839 |
(bibtex-choose-completion-string choice buffer mini-p base-size) |
(bibtex-choose-completion-string choice buffer mini-p base-size) |
3840 |
(if bibtex-complete-key-cleanup |
(bibtex-complete-key-cleanup choice) |
|
(funcall bibtex-complete-key-cleanup choice)) |
|
3841 |
;; return t (required by choose-completion-string-functions) |
;; return t (required by choose-completion-string-functions) |
3842 |
t)) |
t)) |
3843 |
(let ((choice (bibtex-complete-internal bibtex-reference-keys))) |
(bibtex-complete-key-cleanup (bibtex-complete-internal |
3844 |
(if bibtex-complete-key-cleanup |
bibtex-reference-keys))) |
|
(funcall bibtex-complete-key-cleanup choice)))) |
|
3845 |
|
|
3846 |
((equal compl 'str) |
(compl |
3847 |
;; string completion |
;; string completion |
3848 |
(setq choose-completion-string-functions |
(setq choose-completion-string-functions |
3849 |
(lambda (choice buffer mini-p base-size) |
`(lambda (choice buffer mini-p base-size) |
3850 |
(bibtex-choose-completion-string choice buffer mini-p base-size) |
(bibtex-choose-completion-string choice buffer mini-p base-size) |
3851 |
(bibtex-complete-string-cleanup choice) |
(bibtex-complete-string-cleanup choice ',compl) |
3852 |
;; return t (required by choose-completion-string-functions) |
;; return t (required by choose-completion-string-functions) |
3853 |
t)) |
t)) |
3854 |
(bibtex-complete-string-cleanup (bibtex-complete-internal bibtex-strings))) |
(bibtex-complete-string-cleanup (bibtex-complete-internal compl) |
3855 |
|
compl)) |
3856 |
|
|
3857 |
(t (error "Point outside key or BibTeX field"))))) |
(t (error "Point outside key or BibTeX field"))))) |
3858 |
|
|
3926 |
(interactive (list (completing-read "String key: " bibtex-strings |
(interactive (list (completing-read "String key: " bibtex-strings |
3927 |
nil nil nil 'bibtex-key-history))) |
nil nil nil 'bibtex-key-history))) |
3928 |
(let ((bibtex-maintain-sorted-entries |
(let ((bibtex-maintain-sorted-entries |
3929 |
(if (not bibtex-sort-ignore-string-entries) |
(unless bibtex-sort-ignore-string-entries |
3930 |
bibtex-maintain-sorted-entries)) |
bibtex-maintain-sorted-entries)) |
3931 |
endpos) |
endpos) |
3932 |
(unless (bibtex-prepare-new-entry (list key nil "String")) |
(unless (bibtex-prepare-new-entry (list key nil "String")) |
3933 |
(error "Entry with key `%s' already exists" key)) |
(error "Entry with key `%s' already exists" key)) |
3959 |
"\n") |
"\n") |
3960 |
(goto-char endpos))) |
(goto-char endpos))) |
3961 |
|
|
3962 |
|
(defun bibtex-url (&optional event) |
3963 |
|
"Browse a URL for the BibTeX entry at position PNT. |
3964 |
|
The URL is generated using the schemes defined in `bibtex-generate-url-list' |
3965 |
|
\(see there\). Then the URL is passed to `browse-url'." |
3966 |
|
(interactive (list last-input-event)) |
3967 |
|
(save-excursion |
3968 |
|
(if event (posn-set-point (event-end event))) |
3969 |
|
(bibtex-beginning-of-entry) |
3970 |
|
(let ((fields-alist (bibtex-parse-entry)) |
3971 |
|
(case-fold-search t) |
3972 |
|
(lst bibtex-generate-url-list) |
3973 |
|
field url scheme) |
3974 |
|
(while (setq scheme (car lst)) |
3975 |
|
(when (and (setq field (assoc-string (caar scheme) fields-alist t)) |
3976 |
|
(or (eq t (cdar scheme)) |
3977 |
|
(string-match (cdar scheme) (cdr field)))) |
3978 |
|
(setq lst nil) |
3979 |
|
(dolist (step (cdr scheme)) |
3980 |
|
(cond ((stringp step) |
3981 |
|
(setq url (concat url step))) |
3982 |
|
((setq field (assoc-string (car step) fields-alist t)) |
3983 |
|
;; always remove field delimiters |
3984 |
|
(let* ((text (if (string-match "\\`[{\"]\\(.*\\)[}\"]\\'" |
3985 |
|
(cdr field)) |
3986 |
|
(match-string 1 (cdr field)) |
3987 |
|
(cdr field))) |
3988 |
|
(str (cond ((eq t (nth 1 step)) |
3989 |
|
text) |
3990 |
|
((and (consp (nth 1 step)) |
3991 |
|
(string-match (car (nth 1 step)) |
3992 |
|
text)) |
3993 |
|
(if (numberp (cdr (nth 1 step))) |
3994 |
|
(match-string (cdr (nth 1 step)) |
3995 |
|
text) |
3996 |
|
(replace-match (cdr (nth 1 step)) |
3997 |
|
nil nil text))) |
3998 |
|
;; If the scheme is set up correctly, |
3999 |
|
;; we should never reach this point |
4000 |
|
(t (error "Match failed: %s" text))))) |
4001 |
|
(setq url (concat url (if (fboundp (nth 2 step)) |
4002 |
|
(funcall (nth 2 step) str) |
4003 |
|
str))))) |
4004 |
|
;; If the scheme is set up correctly, |
4005 |
|
;; we should never reach this point |
4006 |
|
(t (error "Step failed: %s" step)))) |
4007 |
|
(message "%s" url) |
4008 |
|
(browse-url url)) |
4009 |
|
(setq lst (cdr lst))) |
4010 |
|
(unless url (message "No URL known."))))) |
4011 |
|
|
4012 |
|
(defun bibtex-font-lock-url (bound) |
4013 |
|
"Font-lock for URLs." |
4014 |
|
(let ((case-fold-search t) |
4015 |
|
(bounds (bibtex-enclosing-field t)) |
4016 |
|
(pnt (point)) |
4017 |
|
found url) |
4018 |
|
;; We use start-of-field as syntax-begin |
4019 |
|
(goto-char (if bounds (bibtex-start-of-field bounds) pnt)) |
4020 |
|
(while (and (not found) |
4021 |
|
(search-forward-regexp bibtex-font-lock-url-regexp bound t) |
4022 |
|
(save-match-data (setq bounds (bibtex-parse-field-text))) |
4023 |
|
(>= bound (car bounds))) |
4024 |
|
(let ((field (match-string-no-properties 1)) |
4025 |
|
(lst bibtex-generate-url-list)) |
4026 |
|
(while (and (not found) |
4027 |
|
(setq url (caar lst))) |
4028 |
|
(when (bibtex-string= field (car url)) |
4029 |
|
(if (eq t (cdr url)) |
4030 |
|
(progn |
4031 |
|
(goto-char (min bound (cdr bounds))) |
4032 |
|
(set-match-data (list (car bounds) (point))) |
4033 |
|
(setq found t)) |
4034 |
|
(goto-char (car bounds)) |
4035 |
|
(setq found (search-forward-regexp (cdr url) |
4036 |
|
(min bound (cdr bounds)) t))) |
4037 |
|
(if (< (match-beginning 0) pnt) |
4038 |
|
(setq found nil))) |
4039 |
|
(setq lst (cdr lst))))) |
4040 |
|
found)) |
4041 |
|
|
4042 |
|
|
4043 |
;; Make BibTeX a Feature |
;; Make BibTeX a Feature |
4044 |
|
|