X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/26e06f4464c58704889bdc536edc25b73e8c0179..d355a0b79173c5d479fed0c7b1b7b81cc652b42c:/lisp/textmodes/bibtex.el diff --git a/lisp/textmodes/bibtex.el b/lisp/textmodes/bibtex.el index e5e3f4d769..e17cd9e5b2 100644 --- a/lisp/textmodes/bibtex.el +++ b/lisp/textmodes/bibtex.el @@ -1,7 +1,7 @@ ;;; bibtex.el --- BibTeX mode for GNU Emacs ;; Copyright (C) 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2001, 2002, -;; 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +;; 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. ;; Author: Stefan Schoef ;; Bengt Martensson @@ -163,7 +163,7 @@ The value nil means do no formatting at all." "Alist of field regexps that \\[bibtex-clean-entry] encloses by braces. Each element has the form (FIELDS REGEXP), where FIELDS is a list of BibTeX field names and REGEXP is a regexp. -Whitespace in REGEXP will be replaced by \"[ \\t\\n]+\"." +Space characters in REGEXP will be replaced by \"[ \\t\\n]+\"." :group 'bibtex :type '(repeat (list (repeat (string :tag "field name")) (choice (regexp :tag "regexp") @@ -174,7 +174,7 @@ Whitespace in REGEXP will be replaced by \"[ \\t\\n]+\"." Each element has the form (FIELDS REGEXP TO-STR), where FIELDS is a list of BibTeX field names. In FIELDS search for REGEXP, which are replaced by the BibTeX string constant TO-STR. -Whitespace in REGEXP will be replaced by \"[ \\t\\n]+\"." +Space characters in REGEXP will be replaced by \"[ \\t\\n]+\"." :group 'bibtex :type '(repeat (list (repeat (string :tag "field name")) (regexp :tag "From regexp") @@ -216,7 +216,7 @@ If value of `bibtex-maintain-sorted-entries' is `entry-class' entries are ordered according to the classes they belong to. Each class contains a list of entry types. An entry `catch-all' applies to all entries not explicitly mentioned." - :group 'BibTeX + :group 'bibtex :type '(repeat (choice :tag "Class" (const :tag "catch-all" (catch-all)) (repeat :tag "Entry type" string)))) @@ -746,11 +746,11 @@ See `bibtex-generate-autokey' for details." (defcustom bibtex-autokey-titleword-ignore '("A" "An" "On" "The" "Eine?" "Der" "Die" "Das" - "[^[:upper:]].*" ".*[^[:upper:]0-9].*") + "[^[:upper:]].*" ".*[^[:upper:][:lower:]0-9].*") "Determines words from the title that are not to be used in the key. Each item of the list is a regexp. If a word of the title matches a regexp from that list, it is not included in the title part of the key. -See `bibtex-generate-autokey' for details." +Case is significant. See `bibtex-generate-autokey' for details." :group 'bibtex-autokey :type '(repeat regexp)) @@ -907,8 +907,9 @@ and with the `match-data' properly set. Case is always ignored. Always remove the field delimiters. If `bibtex-expand-strings' is non-nil, BibTeX strings are expanded for generating the URL. +Set this variable before loading BibTeX mode. -The following is a complex example, see http://link.aps.org/linkfaq.html. +The following is a complex example, see URL `http://link.aps.org/'. (((\"journal\" . \"\\\\=<\\(PR[ABCDEL]?\\|RMP\\)\\\\=>\") \"http://link.aps.org/abstract/%s/v%s/p%s\" @@ -945,10 +946,12 @@ The following is a complex example, see http://link.aps.org/linkfaq.html. Each rule should be of the form (REGEXP . SUBEXP), where SUBEXP specifies which parenthesized expression in REGEXP is a cited key. Case is significant. -Used by `bibtex-search-crossref' and for font-locking." +Used by `bibtex-search-crossref' and for font-locking. +Set this variable before loading BibTeX mode." :group 'bibtex :type '(repeat (cons (regexp :tag "Regexp") - (integer :tag "Number")))) + (integer :tag "Number"))) + :version "23.1") (defcustom bibtex-expand-strings nil "If non-nil, expand strings when extracting the content of a BibTeX field." @@ -1512,8 +1515,8 @@ If `bibtex-expand-strings' is non-nil, also expand BibTeX strings." (save-excursion (goto-char (bibtex-start-of-text-in-field bounds)) (let ((epoint (bibtex-end-of-text-in-field bounds)) - content opoint) - (while (< (setq opoint (point)) epoint) + content) + (while (< (point) epoint) (if (looking-at bibtex-field-const) (let ((mtch (match-string-no-properties 0))) (push (or (if bibtex-expand-strings @@ -1724,13 +1727,18 @@ entry and `match-data' corresponds to the header of the entry, see regexp `bibtex-entry-head'. If `bibtex-sort-ignore-string-entries' is non-nil, FUN is not called for @String entries." (let ((case-fold-search t) + (end-marker (make-marker)) found) + ;; Use marker to keep track of the buffer position of the end of + ;; a BibTeX entry as this position may change during reformatting. + (set-marker-insertion-type end-marker t) (save-excursion (goto-char (point-min)) (while (setq found (bibtex-skip-to-valid-entry)) + (set-marker end-marker (cdr found)) (looking-at bibtex-any-entry-maybe-empty-head) - (funcall fun (bibtex-key-in-head "") (car found) (cdr found)) - (goto-char (cdr found)))))) + (funcall fun (bibtex-key-in-head "") (car found) end-marker) + (goto-char end-marker))))) (defun bibtex-progress-message (&optional flag interval) "Echo a message about progress of current buffer. @@ -1828,13 +1836,16 @@ are ignored. Return point" "Search for BibTeX field enclosing point. For `bibtex-mode''s internal algorithms, a field begins at the comma following the preceding field. Usually, this is not what the user expects. -Thus if COMMA is non-nil, the \"current field\" includes the terminating comma. +Thus if COMMA is non-nil, the \"current field\" includes the terminating comma +as well as the entry delimiter if it appears on the same line. Unless NOERR is non-nil, signal an error if no enclosing field is found. On success return bounds, nil otherwise. Do not move point." (save-excursion (when comma (end-of-line) (skip-chars-backward " \t") + ;; Ignore entry delimiter and comma at end of line. + (if (memq (preceding-char) '(?} ?\))) (forward-char -1)) (if (= (preceding-char) ?,) (forward-char -1))) (let ((bounds (bibtex-search-backward-field bibtex-field-name t))) @@ -1870,7 +1881,14 @@ Optional arg COMMA is as in `bibtex-enclosing-field'." (bibtex-skip-to-valid-entry) (push-mark) (insert (funcall fun 'bibtex-entry-kill-ring-yank-pointer - bibtex-entry-kill-ring))))) + bibtex-entry-kill-ring)) + (unless (functionp bibtex-reference-keys) + ;; update `bibtex-reference-keys' + (save-excursion + (goto-char (mark t)) + (looking-at bibtex-any-entry-maybe-empty-head) + (let ((key (bibtex-key-in-head))) + (if key (push (cons key t) bibtex-reference-keys)))))))) (defun bibtex-format-entry () "Helper function for `bibtex-clean-entry'. @@ -1891,6 +1909,7 @@ Formats current entry according to variable `bibtex-entry-format'." last-comma delimiters unify-case braces strings) bibtex-entry-format)) + (left-delim-re (regexp-quote (bibtex-field-left-delimiter))) bounds crossref-key req-field-list default-field-list field-list alt-fields error-field-name) (unwind-protect @@ -1930,7 +1949,8 @@ Formats current entry according to variable `bibtex-entry-format'." ;; Do we have a crossref key? (goto-char (point-min)) - (if (setq bounds (bibtex-search-forward-field "crossref")) + (if (setq bounds (bibtex-search-forward-field + "\\(OPT\\)?crossref")) (let ((text (bibtex-text-in-field-bounds bounds t))) (unless (equal "" text) (setq crossref-key text)))) @@ -1985,6 +2005,17 @@ Formats current entry according to variable `bibtex-entry-format'." (unless deleted (push field-name field-list) + ;; Remove whitespace at beginning and end of field. + ;; We do not look at individual parts of the field + ;; as {foo } # bar # { baz} is a fine field. + (when (memq 'whitespace format) + (goto-char beg-text) + (if (looking-at "\\([{\"]\\)[ \t\n]+") + (replace-match "\\1")) + (goto-char end-text) + (if (looking-back "[ \t\n]+\\([}\"]\\)" beg-text t) + (replace-match "\\1"))) + ;; remove delimiters from purely numerical fields (when (and (memq 'numerical-fields format) (progn (goto-char beg-text) @@ -1997,13 +2028,21 @@ Formats current entry according to variable `bibtex-entry-format'." ;; update delimiters (when (memq 'delimiters format) (goto-char beg-text) - (when (looking-at "[{\"]") - (delete-char 1) - (insert (bibtex-field-left-delimiter))) - (goto-char (1- (marker-position end-text))) - (when (looking-at "[}\"]") - (delete-char 1) - (insert (bibtex-field-right-delimiter)))) + ;; simplified from `bibtex-parse-field-text', as we + ;; already checked that the field format is correct + (while (< (point) end-text) + (if (looking-at bibtex-field-const) + (goto-char (match-end 0)) + (let ((boundaries (bibtex-parse-field-string))) + (if (looking-at left-delim-re) + (goto-char (cdr boundaries)) + (delete-char 1) + (insert (bibtex-field-left-delimiter)) + (goto-char (1- (cdr boundaries))) + (delete-char 1) + (insert (bibtex-field-right-delimiter))))) + (if (looking-at "[ \t\n]*#[ \t\n]*") + (goto-char (match-end 0))))) ;; update page dashes (if (and (memq 'page-dashes format) @@ -2013,15 +2052,6 @@ Formats current entry according to variable `bibtex-entry-format'." "\\([\"{][0-9]+\\)[ \t\n]*--?[ \t\n]*\\([0-9]+[\"}]\\)"))) (replace-match "\\1-\\2")) - ;; remove whitespace at beginning and end of field - (when (memq 'whitespace format) - (goto-char beg-text) - (if (looking-at "\\([{\"]\\)[ \t\n]+") - (replace-match "\\1")) - (goto-char end-text) - (if (looking-back "[ \t\n]+\\([}\"]\\)" beg-text t) - (replace-match "\\1"))) - ;; enclose field text by braces according to ;; `bibtex-field-braces-alist'. (let (case-fold-search temp) ; Case-sensitive search @@ -2064,7 +2094,7 @@ Formats current entry according to variable `bibtex-entry-format'." ;; if match not at left subfield boundary... (if (< (1+ (nth 1 bounds)) (match-beginning 0)) (insert (bibtex-field-right-delimiter) " # ") - (delete-backward-char 1)))))))) + (delete-char -1)))))))) ;; use book title of crossref'd entry (if (and (memq 'inherit-booktitle format) @@ -2151,7 +2181,7 @@ Formats current entry according to variable `bibtex-entry-format'." (if (memq 'realign format) (bibtex-fill-entry))))) - ;; Unwindform: move point to location where error occured if possible + ;; Unwindform: move point to location where error occurred if possible (if error-field-name (let (bounds) (when (save-excursion @@ -2171,7 +2201,7 @@ Return optimized value to be used by `bibtex-format-entry'." (setq regexp-alist (mapcar (lambda (e) (list (car e) - (replace-regexp-in-string "[ \t\n]+" "[ \t\n]+" (nth 1 e)) + (replace-regexp-in-string " +" "[ \t\n]+" (nth 1 e)) (nth 2 e))) ; nil for 'braces'. regexp-alist)) (let (opt-list) @@ -2295,6 +2325,10 @@ Return the result as a string" ;; gather words from titlestring into a list. Ignore ;; specific words and use only a specific amount of words. (let ((counter 0) + (ignore-re (concat "\\`\\(?:" + (mapconcat 'identity + bibtex-autokey-titleword-ignore "\\|") + "\\)\\'")) titlewords titlewords-extra word) (while (and (or (not (numberp bibtex-autokey-titlewords)) (< counter (+ bibtex-autokey-titlewords @@ -2303,13 +2337,9 @@ Return the result as a string" (setq word (match-string 0 titlestring) titlestring (substring titlestring (match-end 0))) ;; Ignore words matched by one of the elements of - ;; `bibtex-autokey-titleword-ignore' - (unless (let ((lst bibtex-autokey-titleword-ignore)) - (while (and lst - (not (string-match (concat "\\`\\(?:" (car lst) - "\\)\\'") word))) - (setq lst (cdr lst))) - lst) + ;; `bibtex-autokey-titleword-ignore'. Case is significant. + (unless (let (case-fold-search) + (string-match ignore-re word)) (setq counter (1+ counter)) (if (or (not (numberp bibtex-autokey-titlewords)) (<= counter bibtex-autokey-titlewords)) @@ -2428,8 +2458,10 @@ Concatenate the key: (apply 'append (mapcar (lambda (buf) (with-current-buffer buf bibtex-reference-keys)) - (bibtex-initialize t))) - bibtex-reference-keys)) + ;; include current buffer only if it uses `bibtex-mode' + (bibtex-initialize (eq major-mode 'bibtex-mode)))) + (if (eq major-mode 'bibtex-mode) + bibtex-reference-keys))) (defun bibtex-read-key (prompt &optional key global) "Read BibTeX key from minibuffer using PROMPT and default KEY. @@ -2519,8 +2551,7 @@ Return alist of strings if parsing was completed, `aborted' otherwise." (save-excursion (save-match-data (goto-char (point-min)) - (let ((strings (if (and add - (listp bibtex-strings)) + (let ((strings (if (and add (not (functionp bibtex-strings))) bibtex-strings)) bounds key) (if (listp add) @@ -2543,8 +2574,9 @@ Return alist of strings if parsing was completed, `aborted' otherwise." (defun bibtex-strings () "Return `bibtex-strings'. Initialize this variable if necessary." - (if (listp bibtex-strings) bibtex-strings - (bibtex-parse-strings (bibtex-string-files-init)))) + (if (functionp bibtex-strings) + (bibtex-parse-strings (bibtex-string-files-init)) + bibtex-strings)) (defun bibtex-string-files-init () "Return initialization for `bibtex-strings'. @@ -2656,7 +2688,11 @@ When called interactively, FORCE is t, CURRENT is t if current buffer uses (dolist (file file-list) (if (file-readable-p file) (push (find-file-noselect file) buffer-list))) - ;; include current buffer iff we want it + ;; Include current buffer iff we want it. + ;; Exclude current buffer if it doesn't use `bibtex-mode'. + ;; Thus calling `bibtex-initialize' gives meaningful results for + ;; any current buffer. + (unless (and current (eq major-mode 'bibtex-mode)) (setq current nil)) (cond ((and current (not (memq (current-buffer) buffer-list))) (push (current-buffer) buffer-list)) ((and (not current) (memq (current-buffer) buffer-list)) @@ -2664,8 +2700,10 @@ When called interactively, FORCE is t, CURRENT is t if current buffer uses ;; parse keys (dolist (buffer buffer-list) (with-current-buffer buffer - (if (or force (nlistp bibtex-reference-keys)) - (bibtex-parse-keys)))) + (if (or force (functionp bibtex-reference-keys)) + (bibtex-parse-keys)) + (unless (functionp bibtex-strings) + (bibtex-parse-strings (bibtex-string-files-init))))) ;; select BibTeX buffer (if select (if buffer-list @@ -2683,35 +2721,13 @@ COMPLETIONS is an alist of strings. If point is not after the part of a word, all strings are listed. Return completion." ;; Return value is used by cleanup functions. ;; Code inspired by `lisp-complete-symbol'. - (let* ((case-fold-search t) - (beg (save-excursion + (let ((beg (save-excursion (re-search-backward "[ \t{\"]") (forward-char) (point))) - (end (point)) - (pattern (buffer-substring-no-properties beg end)) - (completion (try-completion pattern completions))) - (cond ((not completion) - (error "Can't find completion for `%s'" pattern)) - ((eq completion t) - pattern) - ((not (string= pattern completion)) - (delete-region beg end) - (insert completion) - ;; Don't leave around a completions buffer that's out of date. - (let ((win (get-buffer-window "*Completions*" 0))) - (if win (with-selected-window win (bury-buffer)))) - completion) - (t - (let ((minibuf-is-in-use - (eq (minibuffer-window) (selected-window)))) - (unless minibuf-is-in-use (message "Making completion list...")) - (with-output-to-temp-buffer "*Completions*" - (display-completion-list - (sort (all-completions pattern completions) 'string<) pattern)) - (unless minibuf-is-in-use - (message "Making completion list...done"))) - nil)))) + (end (point))) + (when (completion-in-region beg end completions) + (buffer-substring beg (point))))) (defun bibtex-complete-string-cleanup (str compl) "Cleanup after inserting string STR. @@ -2931,7 +2947,7 @@ BOUND limits the search." General information on working with BibTeX mode: -Use commands such as \\[bibtex-Book] to get a template for a specific entry. +Use commands such as \\\\[bibtex-Book] to get a template for a specific entry. Then fill in all desired fields using \\[bibtex-next-field] to jump from field to field. After having filled in all desired fields in the entry, clean the new entry with the command \\[bibtex-clean-entry]. @@ -3315,7 +3331,8 @@ Return the new location of point." ((looking-at bibtex-any-valid-entry-type) ;; Parsing of entry failed (error "Syntactically incorrect BibTeX entry starts here")) - (t (if (interactive-p) (message "Not on a known BibTeX entry.")) + (t (if (called-interactively-p 'interactive) + (message "Not on a known BibTeX entry.")) (goto-char pnt))) (point))) @@ -3472,7 +3489,7 @@ are ignored." (bibtex-beginning-of-first-entry) ; Needed by `sort-subr' (bibtex-init-sort-entry-class-alist) ; Needed by `bibtex-lessp'. (if (and (eq bibtex-maintain-sorted-entries 'crossref) - (nlistp bibtex-reference-keys)) + (functionp bibtex-reference-keys)) (bibtex-parse-keys)) ; Needed by `bibtex-lessp'. (sort-subr nil 'bibtex-skip-to-valid-entry ; NEXTREC function @@ -3503,7 +3520,7 @@ for a crossref key, t otherwise." (end (cdr (bibtex-valid-entry t))) (_ (unless end (error "Not inside valid entry"))) (beg (match-end 0)) ; set by `bibtex-valid-entry' - (bounds (bibtex-search-forward-field "crossref" end)) + (bounds (bibtex-search-forward-field "\\(OPT\\)?crossref" end)) case-fold-search best temp crossref-key) (if bounds (setq crossref-key (bibtex-text-in-field-bounds bounds t) @@ -3579,8 +3596,7 @@ mode is not `bibtex-mode', START is nil, and DISPLAY is t." (while (and (not found) (setq buffer (pop buffer-list))) (with-current-buffer buffer - (if (and (listp bibtex-reference-keys) - (cdr (assoc-string key bibtex-reference-keys))) + (if (cdr (assoc-string key bibtex-reference-keys)) ;; `bibtex-search-entry' moves point if key found (setq found (bibtex-search-entry key))))) (cond ((and found display) @@ -3620,7 +3636,7 @@ see `bibtex-validate'. Return t if preparation was successful or nil if entry KEY already exists." (bibtex-init-sort-entry-class-alist) ; Needed by `bibtex-lessp'. (if (and (eq bibtex-maintain-sorted-entries 'crossref) - (nlistp bibtex-reference-keys)) + (functionp bibtex-reference-keys)) (bibtex-parse-keys)) ; Needed by `bibtex-lessp'. (let ((key (nth 0 index)) key-exist) @@ -3827,7 +3843,8 @@ Return t if test was successful, nil otherwise." (insert (format "%s:%d: %s\n" file (car err) (cdr err)))) (set-buffer-modified-p nil) (toggle-read-only 1) - (goto-line 3)) ; first error message + (goto-char (point-min)) + (forward-line 2)) ; first error message (display-buffer err-buf) nil) ; return `nil' (i.e., buffer is invalid) (message "%s is syntactically correct" @@ -3843,8 +3860,7 @@ Return t if test was successful, nil otherwise." buffer-key-list current-buf current-keys error-list) ;; Check for duplicate keys within BibTeX buffer (dolist (buffer buffer-list) - (save-excursion - (set-buffer buffer) + (with-current-buffer buffer (let (entry-type key key-list) (goto-char (point-min)) (while (re-search-forward bibtex-entry-head nil t) @@ -3884,7 +3900,8 @@ Return t if test was successful, nil otherwise." (dolist (err (sort error-list 'string-lessp)) (insert err)) (set-buffer-modified-p nil) (toggle-read-only 1) - (goto-line 3)) ; first error message + (goto-char (point-min)) + (forward-line 2)) ; first error message (display-buffer err-buf) nil) ; return `nil' (i.e., buffer is invalid) (message "No duplicate keys.") @@ -4055,7 +4072,11 @@ but do not actually kill it. Optional arg COMMA is as in (end (bibtex-end-of-field bounds)) (beg (bibtex-start-of-field bounds))) (goto-char end) - (skip-chars-forward ",") + ;; Preserve white space at end of BibTeX entry + (if (looking-at "[ \t\n]*[)}]") + (progn (skip-chars-backward " \t\n") + (setq end (point))) + (skip-chars-forward ",")) (push (list (bibtex-name-in-field bounds) nil (bibtex-text-in-field-bounds bounds)) bibtex-field-kill-ring) @@ -4069,7 +4090,7 @@ but do not actually kill it. Optional arg COMMA is as in (setq bibtex-last-kill-command 'field)) (defun bibtex-copy-field-as-kill (&optional comma) - "Copy the BibTeX field at point to the kill ring. + "Copy the BibTeX field at point to `bibtex-field-kill-ring'. Optional arg COMMA is as in `bibtex-enclosing-field'. It is t for interactive calls." (interactive (list t)) @@ -4083,6 +4104,8 @@ but do not actually kill it." (save-excursion (let* ((case-fold-search t) (beg (bibtex-beginning-of-entry)) + (key (progn (looking-at bibtex-any-entry-maybe-empty-head) + (bibtex-key-in-head))) (end (progn (bibtex-end-of-entry) (if (re-search-forward bibtex-any-entry-maybe-empty-head nil 'move) @@ -4096,7 +4119,11 @@ but do not actually kill it." nil)) (setq bibtex-entry-kill-ring-yank-pointer bibtex-entry-kill-ring) (unless copy-only - (delete-region beg end)))) + (delete-region beg end) + ;; remove key from `bibtex-reference-keys'. + (unless (functionp bibtex-reference-keys) + (setq bibtex-reference-keys + (delete (cons key t) bibtex-reference-keys)))))) (setq bibtex-last-kill-command 'entry)) (defun bibtex-copy-entry-as-kill () @@ -4130,7 +4157,16 @@ comes the newest one." (unless (eq last-command 'bibtex-yank) (error "Previous command was not a BibTeX yank")) (setq this-command 'bibtex-yank) - (let ((inhibit-read-only t)) + (let ((inhibit-read-only t) key) + ;; point is at end of yanked entry + (unless (functionp bibtex-reference-keys) + ;; remove key of yanked entry from `bibtex-reference-keys' + (save-excursion + (goto-char (mark t)) + (if (and (looking-at bibtex-any-entry-maybe-empty-head) + (setq key (bibtex-key-in-head))) + (setq bibtex-reference-keys + (delete (cons key t) bibtex-reference-keys))))) (delete-region (point) (mark t)) (bibtex-insert-kill n t))) @@ -4235,23 +4271,27 @@ At end of the cleaning process, the functions in (if (cdr (assoc-string key bibtex-reference-keys)) (error "Duplicate key in %s" (buffer-file-name))))) - ;; Only update the list of keys if it has been built already. + ;; Only update `bibtex-strings' and `bibtex-reference-keys' + ;; if they have been built already. (cond ((eq entry-type 'string) - (if (and (listp bibtex-strings) - (not (assoc key bibtex-strings))) - (push (cons key (bibtex-text-in-string - (bibtex-parse-string) t)) - bibtex-strings))) + ;; We have a @String entry. + (unless (or (functionp bibtex-strings) + (assoc key bibtex-strings)) + (push (cons key (bibtex-text-in-string + (bibtex-parse-string) t)) + bibtex-strings))) ;; We have a normal entry. - ((listp bibtex-reference-keys) - (cond ((not (assoc key bibtex-reference-keys)) - (push (cons key t) bibtex-reference-keys)) - ((not (cdr (assoc key bibtex-reference-keys))) - ;; Turn a crossref key into a header key - (setq bibtex-reference-keys - (cons (cons key t) - (delete (list key) bibtex-reference-keys))))) - ;; Handle crossref key. + ((not (functionp bibtex-reference-keys)) + (let ((found (assoc key bibtex-reference-keys))) + (cond ((not found) + (push (cons key t) bibtex-reference-keys)) + ((not (cdr found)) + ;; Turn a crossref key into a header key + (setq bibtex-reference-keys + (cons (cons key t) + (delete (list key) bibtex-reference-keys)))))) + ;; If entry has a crossref key, it goes into the list + ;; `bibtex-reference-keys', too. (if (and (nth 1 index) (not (assoc (nth 1 index) bibtex-reference-keys))) (push (list (nth 1 index)) bibtex-reference-keys))))) @@ -4388,7 +4428,7 @@ If mark is active reformat entries in region, if not in whole buffer." last-comma page-dashes unify-case inherit-booktitle whitespace braces strings)) (t - (remove 'required-fields (push 'realign bibtex-entry-format))))) + (cons 'realign (remove 'required-fields bibtex-entry-format))))) (reformat-reference-keys (if read-options (if use-previous-options @@ -4502,9 +4542,9 @@ An error is signaled if point is outside key or BibTeX field." ;; is requested. (let (completion-ignore-case) (setq choose-completion-string-functions - (lambda (choice buffer mini-p base-size) + (lambda (choice buffer base-position &rest ignored) (setq choose-completion-string-functions nil) - (choose-completion-string choice buffer base-size) + (choose-completion-string choice buffer base-position) (bibtex-complete-crossref-cleanup choice) t)) ; needed by choose-completion-string-functions (bibtex-complete-crossref-cleanup @@ -4520,9 +4560,9 @@ An error is signaled if point is outside key or BibTeX field." ;; string completion (let ((completion-ignore-case t)) (setq choose-completion-string-functions - `(lambda (choice buffer mini-p base-size) + `(lambda (choice buffer base-position &rest ignored) (setq choose-completion-string-functions nil) - (choose-completion-string choice buffer base-size) + (choose-completion-string choice buffer base-position) (bibtex-complete-string-cleanup choice ',compl) t)) ; needed by `choose-completion-string-functions' (bibtex-complete-string-cleanup (bibtex-complete-internal compl) @@ -4725,9 +4765,10 @@ Return the URL or nil if none can be generated." (error "Match failed: %s" text))) (if fmt (apply 'format fmt (nreverse obj)) (apply 'concat (nreverse obj))))) - (if (interactive-p) (message "%s" url)) + (if (called-interactively-p 'interactive) (message "%s" url)) (unless no-browse (browse-url url))) - (if (and (not url) (interactive-p)) (message "No URL known.")) + (if (and (not url) (called-interactively-p 'interactive)) + (message "No URL known.")) url)))