emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] Changes to emacs/lisp/textmodes/bibtex.el


From: Stefan Monnier
Subject: [Emacs-diffs] Changes to emacs/lisp/textmodes/bibtex.el
Date: Fri, 10 Sep 2004 17:30:15 -0400

Index: emacs/lisp/textmodes/bibtex.el
diff -c emacs/lisp/textmodes/bibtex.el:1.83 emacs/lisp/textmodes/bibtex.el:1.84
*** emacs/lisp/textmodes/bibtex.el:1.83 Tue Jun  1 23:31:00 2004
--- emacs/lisp/textmodes/bibtex.el      Fri Sep 10 21:24:49 2004
***************
*** 640,646 ****
  
  (defcustom bibtex-autokey-titleword-ignore
    '("A" "An" "On" "The" "Eine?" "Der" "Die" "Das"
!     "[^A-Z].*" ".*[^a-zA-Z0-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 matchs a
  regexp from that list, it is not included in the title part of the key.
--- 640,646 ----
  
  (defcustom bibtex-autokey-titleword-ignore
    '("A" "An" "On" "The" "Eine?" "Der" "Die" "Das"
!     "[^A-Z].*" ".*[^A-Z0-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 matchs a
  regexp from that list, it is not included in the title part of the key.
***************
*** 762,772 ****
    "Automatically fill fields if possible for those BibTeX entry types."
    :type '(repeat string))
  
! (defcustom bibtex-complete-key-cleanup nil
!   "*Function called by `bibtex-complete' after insertion of a key fragment."
!   :group 'bibtex-autokey
!   :type '(choice (const :tag "None" nil)
!                  (function :tag "Cleanup function")))
  
  ;; bibtex-font-lock-keywords is a user option as well, but since the
  ;; patterns used to define this variable are defined in a later
--- 762,807 ----
    "Automatically fill fields if possible for those BibTeX entry types."
    :type '(repeat string))
  
! (defcustom bibtex-generate-url-list
!   '((("url" . t) ("url" t)))
!   "List of schemes for generating the URL of a BibTeX entry.
! These schemes are used by `bibtex-url'.
! 
! Each scheme is of the form ((FIELD . REGEXP) STEPS).
! 
! FIELD is a field name as returned by `bibtex-parse-entry'.
! REGEXP is matched against the text of FIELD. 
! If the match succeeds, the list STEPS is used to generate the URL.
! If REGEXP is t, always generate the URL if FIELD is present.
! 
! If an element of STEPS is a list (FIELD MATCH FILTER),
! the text of FIELD is matched against MATCH. 
! If MATCH is t, the text of FIELD is accepted as is. 
! If MATCH is a cons cell (REGEXP . REPLACE), the text is matched against 
REGEXP. 
! If REPLACE is a string, the text is replaced with REPLACE. If REPLACE is a 
! number, it specifies which parenthesized expression in the match is taken. 
! The optional element FILTER is a function for piping the match through it.
! The text strings are then concatenated to generate the URL.
! 
! If an element of STEPS is a string, it is simply added to the URL.
! 
! Case is always ignored. Always remove the field delimiters."
!   :group 'bibtex
!   :type '(repeat
!           (list :tag "Scheme" 
!                 (cons :tag "Matcher" :extra-offset 4
!                       (string :tag "BibTeX field")
!                       (choice (regexp :tag "Regexp")
!                               (const :tag "Accept as is" t)))
!                 (repeat :tag "Steps to generate URL" :inline t
!                         (choice
!                          (string :tag "Literal text")
!                          (list (string :tag "BibTeX field")
!                                (choice (const :tag "Accept as is" t)
!                                        (cons (string :tag "Field")
!                                              (choice (regexp :tag "Regexp")
!                                                      (integer :tag "Matched 
parenthesis"))))
!                                (option (function :tag "Filter" :value 
ignore))))))))
  
  ;; bibtex-font-lock-keywords is a user option as well, but since the
  ;; patterns used to define this variable are defined in a later
***************
*** 801,806 ****
--- 836,842 ----
      (define-key km "\C-c}" 'bibtex-remove-delimiters)
      (define-key km "\C-c\C-c" 'bibtex-clean-entry)
      (define-key km "\C-c\C-q" 'bibtex-fill-entry)
+     (define-key km "\C-c\C-s" 'bibtex-find-entry)
      (define-key km "\C-c?" 'bibtex-print-help-message)
      (define-key km "\C-c\C-p" 'bibtex-pop-previous)
      (define-key km "\C-c\C-n" 'bibtex-pop-next)
***************
*** 821,826 ****
--- 857,863 ----
      (define-key km "\C-c\C-b" 'bibtex-entry)
      (define-key km "\C-c\C-rn" 'bibtex-narrow-to-entry)
      (define-key km "\C-c\C-rw" 'widen)
+     (define-key km "\C-c\C-l" 'bibtex-url)
      (define-key km "\C-c\C-o" 'bibtex-remove-OPT-or-ALT)
      (define-key km "\C-c\C-e\C-i" 'bibtex-InProceedings)
      (define-key km "\C-c\C-ei" 'bibtex-InCollection)
***************
*** 854,874 ****
      ("Moving in BibTeX Buffer"
       ["Find Entry" bibtex-find-entry t]
       ["Find Crossref Entry" bibtex-find-crossref t])
-     ("Operating on Current Entry"
-      ["Fill Entry" bibtex-fill-entry t]
-      ["Clean Entry" bibtex-clean-entry t]
       "--"
-      ["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)])
      ("Operating on Current Field"
       ["Fill Field" fill-paragraph t]
       ["Remove Delimiters" bibtex-remove-delimiters t]
--- 891,897 ----
***************
*** 888,899 ****
       ["String or Key Complete" bibtex-complete t]
       "--"
       ["Help about Current Field" bibtex-print-help-message t])
      ("Operating on Buffer or Region"
       ["Validate Entries" bibtex-validate t]
       ["Sort Entries" bibtex-sort-buffer t]
       ["Reformat Entries" bibtex-reformat t]
!      ["Count Entries" bibtex-count-entries t])
!     ("Miscellaneous"
       ["Convert Alien Buffer" bibtex-convert-alien t])))
  
  (easy-menu-define
--- 911,938 ----
       ["String or Key Complete" bibtex-complete t]
       "--"
       ["Help about Current Field" bibtex-print-help-message t])
+     ("Operating on Current Entry"
+      ["Fill Entry" bibtex-fill-entry t]
+      ["Clean Entry" bibtex-clean-entry t]
+      ["Update Entry" bibtex-entry-update t]
+      "--"
+      ["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)])
      ("Operating on Buffer or Region"
       ["Validate Entries" bibtex-validate t]
       ["Sort Entries" bibtex-sort-buffer t]
       ["Reformat Entries" bibtex-reformat t]
!      ["Count Entries" bibtex-count-entries t]
!      "--"
       ["Convert Alien Buffer" bibtex-convert-alien t])))
  
  (easy-menu-define
***************
*** 915,920 ****
--- 954,966 ----
          ["String" bibtex-String t]
          ["Preamble" bibtex-Preamble t]))
  
+ (defvar bibtex-url-map
+   (let ((km (make-sparse-keymap)))
+     (define-key km [(mouse-2)] 'bibtex-url)
+     km)
+   "Local keymap for clickable URLs.")
+ (fset 'bibtex-url-map bibtex-url-map)
+     
  
  ;; Internal Variables
  
***************
*** 1040,1077 ****
  (defconst bibtex-empty-field-re "\"\"\\|{}"
    "Regexp matching an empty field.")
  
- (defconst bibtex-quoted-string-re
-   (concat "\""
-           "\\("
-           "[^\"\\]"          ; anything but quote or backslash
-           "\\|"
-           "\\("
-           "\\\\\\(.\\|\n\\)" ; any backslash quoted character
-           "\\)"
-           "\\)*"
-           "\"")
-   "Regexp matching a field string enclosed by quotes.")
- 
  (defconst bibtex-font-lock-syntactic-keywords
    `((,(concat "^[ \t]*\\(" (substring bibtex-comment-start 0 1) "\\)"
                (substring bibtex-comment-start 1) "\\>")
       1 '(11))))
  
  (defvar bibtex-font-lock-keywords
!   (list
!    ;; entry type and reference key
!    (list bibtex-entry-maybe-empty-head
!          (list bibtex-type-in-head 'font-lock-function-name-face)
!          (list bibtex-key-in-head 'font-lock-constant-face nil t))
!    ;; optional field names (treated as comments)
!    (list
!     (concat "^[ \t]*\\(OPT" bibtex-field-name "\\)[ \t]*=")
!     1 'font-lock-comment-face)
!    ;; field names
!    (list (concat "^[ \t]*\\(" bibtex-field-name "\\)[ \t]*=")
!          1 'font-lock-variable-name-face))
    "*Default expressions to highlight in BibTeX mode.")
  
  (defvar bibtex-field-name-for-parsing nil
    "Temporary variable storing the name string to be parsed by the callback
  function `bibtex-parse-field-name'.")
--- 1086,1117 ----
  (defconst bibtex-empty-field-re "\"\"\\|{}"
    "Regexp matching an empty field.")
  
  (defconst bibtex-font-lock-syntactic-keywords
    `((,(concat "^[ \t]*\\(" (substring bibtex-comment-start 0 1) "\\)"
                (substring bibtex-comment-start 1) "\\>")
       1 '(11))))
  
  (defvar bibtex-font-lock-keywords
!   ;; entry type and reference key
!   `((,bibtex-entry-maybe-empty-head
!      (,bibtex-type-in-head font-lock-function-name-face)
!      (,bibtex-key-in-head font-lock-constant-face nil t))
!     ;; optional field names (treated as comments)
!     (,(concat "^[ \t]*\\(OPT" bibtex-field-name "\\)[ \t]*=")
!      1 font-lock-comment-face)
!     ;; field names
!     (,(concat "^[ \t]*\\(" bibtex-field-name "\\)[ \t]*=")
!      1 font-lock-variable-name-face)
!     ;; url
!     (bibtex-font-lock-url 0 '(face nil mouse-face highlight 
!                                    keymap bibtex-url-map)))
    "*Default expressions to highlight in BibTeX mode.")
  
+ (defvar bibtex-font-lock-url-regexp
+   (concat "\\<" (regexp-opt (mapcar 'caar bibtex-generate-url-list) t)
+           "\\>[ \t]*=[ \t]*")
+   "Regexp for `bibtex-font-lock-url'.")
+ 
  (defvar bibtex-field-name-for-parsing nil
    "Temporary variable storing the name string to be parsed by the callback
  function `bibtex-parse-field-name'.")
***************
*** 1089,1110 ****
  
  ;; Special support taking care of variants
  (defvar zmacs-regions)
! (if (boundp 'mark-active)
!     (defun bibtex-mark-active ()
        ;; In Emacs mark-active indicates if mark is active.
!       mark-active)
!   (defun bibtex-mark-active ()
      ;; In XEmacs (mark) returns nil when not active.
!     (if zmacs-regions (mark) (mark t))))
  
! (if (fboundp 'run-with-idle-timer)
!     ;; timer.el is distributed with Emacs
!     (fset 'bibtex-run-with-idle-timer 'run-with-idle-timer)
!   ;; timer.el is not distributed with XEmacs
!   ;; Notice that this does not (yet) pass the arguments, but they
!   ;; are not used (yet) in bibtex.el. Fix if needed.
!   (defun bibtex-run-with-idle-timer (secs repeat function &rest args)
!     (start-itimer "bibtex" function secs (if repeat secs nil) t)))
  
  
  ;; Support for hideshow minor mode
--- 1129,1150 ----
  
  ;; Special support taking care of variants
  (defvar zmacs-regions)
! (defalias 'bibtex-mark-active
!   (if (boundp 'mark-active)
        ;; In Emacs mark-active indicates if mark is active.
!       (lambda () mark-active)
      ;; In XEmacs (mark) returns nil when not active.
!     (lambda () (if zmacs-regions (mark) (mark t)))))
  
! (defalias 'bibtex-run-with-idle-timer
!   (if (fboundp 'run-with-idle-timer)
!       ;; timer.el is distributed with Emacs
!       'run-with-idle-timer
!     ;; timer.el is not distributed with XEmacs
!     ;; Notice that this does not (yet) pass the arguments, but they
!     ;; are not used (yet) in bibtex.el. Fix if needed.
!     (lambda (secs repeat function &rest args)
!       (start-itimer "bibtex" function secs (if repeat secs nil) t))))
  
  
  ;; Support for hideshow minor mode
***************
*** 1215,1223 ****
              ((setq boundaries (bibtex-parse-field-string))
               (goto-char (cdr boundaries)))
              ((setq failure t)))
!       (if (not (looking-at "[ \t\n]*#[ \t\n]*"))
!           (setq end-point (point))
!         (goto-char (match-end 0))))
      (if (and (not failure)
               end-point)
          (cons starting-point end-point))))
--- 1255,1263 ----
              ((setq boundaries (bibtex-parse-field-string))
               (goto-char (cdr boundaries)))
              ((setq failure t)))
!       (if (looking-at "[ \t\n]*#[ \t\n]*")
!           (goto-char (match-end 0))
!         (setq end-point (point))))
      (if (and (not failure)
               end-point)
          (cons starting-point end-point))))
***************
*** 1294,1303 ****
  (defsubst bibtex-end-of-text-in-field (bounds)
    (cddr bounds))
  
! (defun bibtex-name-in-field (bounds)
!   "Get content of name in BibTeX field defined via BOUNDS."
!   (buffer-substring-no-properties (nth 1 (car bounds))
!                                   (nth 2 (car bounds))))
  
  (defun bibtex-text-in-field-bounds (bounds &optional remove-delim)
    "Get content of text in BibTeX field defined via BOUNDS.
--- 1334,1348 ----
  (defsubst bibtex-end-of-text-in-field (bounds)
    (cddr bounds))
  
! (defun bibtex-name-in-field (bounds &optional remove-opt-alt)
!   "Get content of name in BibTeX field defined via BOUNDS.
! If optional arg REMOVE-OPT-ALT is non-nil remove \"OPT\" and \"ALT\"."
!   (let ((name (buffer-substring-no-properties (nth 1 (car bounds))
!                                               (nth 2 (car bounds)))))
!     (if (and remove-opt-alt
!              (string-match "\\`\\(OPT\\|ALT\\)" name))
!         (substring name 3)
!       name)))
  
  (defun bibtex-text-in-field-bounds (bounds &optional remove-delim)
    "Get content of text in BibTeX field defined via BOUNDS.
***************
*** 1438,1443 ****
--- 1483,1492 ----
  
  ;; Helper Functions
  
+ (defsubst bibtex-string= (str1 str2)
+   "Return t if two strings are equal, ignoring case."
+   (eq t (compare-strings str1 0 nil str2 0 nil t)))
+ 
  (defun bibtex-delete-whitespace ()
    "Delete all whitespace starting at point."
    (if (looking-at "[ \t\n]+")
***************
*** 1448,1462 ****
    (+ (count-lines 1 (point))
       (if (equal (current-column) 0) 1 0)))
  
- (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))
- 
  (defun bibtex-skip-to-valid-entry (&optional backward)
    "Unless at beginning of a valid BibTeX entry, move point to beginning of the
  next valid one. With optional argument BACKWARD non-nil, move backward to
--- 1497,1502 ----
***************
*** 1501,1507 ****
              (end (copy-marker (save-excursion (bibtex-end-of-entry)))))
          (save-excursion
            (if (or (and (not bibtex-sort-ignore-string-entries)
!                        (string-equal "string" (downcase entry-type)))
                    (assoc-string entry-type bibtex-entry-field-alist t))
                (funcall fun key beg end)))
          (goto-char end)))))
--- 1541,1547 ----
              (end (copy-marker (save-excursion (bibtex-end-of-entry)))))
          (save-excursion
            (if (or (and (not bibtex-sort-ignore-string-entries)
!                        (bibtex-string= entry-type "string"))
                    (assoc-string entry-type bibtex-entry-field-alist t))
                (funcall fun key beg end)))
          (goto-char end)))))
***************
*** 1575,1581 ****
            (if found
                (progn (goto-char (match-beginning 0))
                       found)
!             (cond ((equal noerror nil)
                     ;; yell
                     (error "Backward search of BibTeX entry failed"))
                    ((equal noerror t)
--- 1615,1621 ----
            (if found
                (progn (goto-char (match-beginning 0))
                       found)
!             (cond ((not noerror)
                     ;; yell
                     (error "Backward search of BibTeX entry failed"))
                    ((equal noerror t)
***************
*** 1684,1693 ****
        (forward-char -1)))
  
  (defun bibtex-enclosing-field (&optional noerr)
!   "Search for BibTeX field enclosing point. Point moves to end of field.
  Use `match-beginning' and `match-end' to parse the field. If NOERR is non-nil,
  no error is signalled. In this case, bounds are returned on success,
! nil otherwise."
    (let ((bounds (bibtex-search-backward-field bibtex-field-name t)))
      (if (and bounds
               (<= (bibtex-start-of-field bounds) (point))
--- 1724,1733 ----
        (forward-char -1)))
  
  (defun bibtex-enclosing-field (&optional noerr)
!   "Search for BibTeX field enclosing point.
  Use `match-beginning' and `match-end' to parse the field. If NOERR is non-nil,
  no error is signalled. In this case, bounds are returned on success,
! nil otherwise. Does not move point."
    (let ((bounds (bibtex-search-backward-field bibtex-field-name t)))
      (if (and bounds
               (<= (bibtex-start-of-field bounds) (point))
***************
*** 1732,1739 ****
          (message "Mark set")
          (bibtex-make-field (list (elt current 1) nil (elt current 2)) t))
         ((equal bibtex-last-kill-command 'entry)
!         (if (not (eobp))
!             (bibtex-beginning-of-entry))
          (set-mark (point))
          (message "Mark set")
          (insert (elt current 1)))
--- 1772,1778 ----
          (message "Mark set")
          (bibtex-make-field (list (elt current 1) nil (elt current 2)) t))
         ((equal bibtex-last-kill-command 'entry)
!         (unless (eobp) (bibtex-beginning-of-entry))
          (set-mark (point))
          (message "Mark set")
          (insert (elt current 1)))
***************
*** 1741,1755 ****
          (error "Unknown tag field: %s.  Please submit a bug report"
                 bibtex-last-kill-command))))))
  
- (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))
- 
  (defun bibtex-format-entry ()
    "Helper function for `bibtex-clean-entry'.
  Formats current entry according to variable `bibtex-entry-format'."
--- 1780,1785 ----
***************
*** 1764,1770 ****
                                    unify-case inherit-booktitle)
                        bibtex-entry-format))
              crossref-key bounds alternatives-there non-empty-alternative
!             entry-list req-field-list field-done field-list)
  
          ;; identify entry type
          (goto-char (point-min))
--- 1794,1800 ----
                                    unify-case inherit-booktitle)
                        bibtex-entry-format))
              crossref-key bounds alternatives-there non-empty-alternative
!             entry-list req-field-list field-list)
  
          ;; identify entry type
          (goto-char (point-min))
***************
*** 1792,1800 ****
          ;; one alternative is non-empty
          (goto-char (point-min))
          (let* ((fields-alist (bibtex-parse-entry))
!                (case-fold-search t)
!                (field (bibtex-assoc-regexp "\\`\\(OPT\\)?crossref\\'"
!                                            fields-alist)))
            (setq crossref-key (and field
                                    (not (string-match bibtex-empty-field-re
                                                       (cdr field)))
--- 1822,1828 ----
          ;; one alternative is non-empty
          (goto-char (point-min))
          (let* ((fields-alist (bibtex-parse-entry))
!                (field (assoc-string "crossref" fields-alist t)))
            (setq crossref-key (and field
                                    (not (string-match bibtex-empty-field-re
                                                       (cdr field)))
***************
*** 1806,1814 ****
            (dolist (rfield req-field-list)
              (when (nth 3 rfield) ; we should have an alternative
                (setq alternatives-there t
!                     field (bibtex-assoc-regexp
!                            (concat "\\`\\(ALT\\)?" (car rfield) "\\'")
!                            fields-alist))
                (if (and field
                         (not (string-match bibtex-empty-field-re
                                            (cdr field))))
--- 1834,1840 ----
            (dolist (rfield req-field-list)
              (when (nth 3 rfield) ; we should have an alternative
                (setq alternatives-there t
!                     field (assoc-string (car rfield) fields-alist t))
                (if (and field
                         (not (string-match bibtex-empty-field-re
                                            (cdr field))))
***************
*** 1887,1893 ****
  
                ;; update page dashes
                (if (and (memq 'page-dashes format)
!                        (string-match "\\`\\(OPT\\)?pages\\'" field-name)
                         (progn (goto-char beg-text)
                                (looking-at
                                 "\\([\"{][0-9]+\\)[ \t\n]*--?[ 
\t\n]*\\([0-9]+[\"}]\\)")))
--- 1913,1919 ----
  
                ;; update page dashes
                (if (and (memq 'page-dashes format)
!                        (bibtex-string= field-name "pages")
                         (progn (goto-char beg-text)
                                (looking-at
                                 "\\([\"{][0-9]+\\)[ \t\n]*--?[ 
\t\n]*\\([0-9]+[\"}]\\)")))
***************
*** 1896,1902 ****
                ;; use book title of crossref'd entry
                (if (and (memq 'inherit-booktitle format)
                         empty-field
!                        (equal (downcase field-name) "booktitle")
                         crossref-key)
                    (let ((title (save-restriction
                                   (widen)
--- 1922,1928 ----
                ;; use book title of crossref'd entry
                (if (and (memq 'inherit-booktitle format)
                         empty-field
!                        (bibtex-string= field-name "booktitle")
                         crossref-key)
                    (let ((title (save-restriction
                                   (widen)
***************
*** 1909,1915 ****
  
              ;; Use booktitle to set a missing title.
              (if (and empty-field
!                      (equal (downcase field-name) "title"))
                  (let ((booktitle (bibtex-text-in-field "booktitle")))
                    (when booktitle
                      (setq empty-field nil)
--- 1935,1941 ----
  
              ;; Use booktitle to set a missing title.
              (if (and empty-field
!                      (bibtex-string= field-name "title"))
                  (let ((booktitle (bibtex-text-in-field "booktitle")))
                    (when booktitle
                      (setq empty-field nil)
***************
*** 2023,2034 ****
    "Get contents of the name field of the current entry.
  Do some modifications based on `bibtex-autokey-name-change-strings'
  and return results as a list."
!   (let ((case-fold-search t))
!     (mapcar 'bibtex-autokey-demangle-name
!             (split-string (bibtex-autokey-get-field
!                            "author\\|editor"
!                            bibtex-autokey-name-change-strings)
!                           "[ \t\n]+and[ \t\n]+"))))
  
  (defun bibtex-autokey-demangle-name (fullname)
    "Get the last part from a well-formed name and perform abbreviations."
--- 2049,2061 ----
    "Get contents of the name field of the current entry.
  Do some modifications based on `bibtex-autokey-name-change-strings'
  and return results as a list."
!   (let ((case-fold-search t)
!         (names (bibtex-autokey-get-field "author\\|editor"
!                                          bibtex-autokey-name-change-strings)))
!     ;; Some entries do not have a name field.
!     (unless (string= "" names)
!       (mapcar 'bibtex-autokey-demangle-name
!               (split-string names "[ \t\n]+and[ \t\n]+")))))
  
  (defun bibtex-autokey-demangle-name (fullname)
    "Get the last part from a well-formed name and perform abbreviations."
***************
*** 2059,2076 ****
  
  (defun bibtex-autokey-get-title ()
    "Get title field contents up to a terminator."
!   (let ((titlestring
           (bibtex-autokey-get-field "title"
                                     bibtex-autokey-titleword-change-strings)))
      ;; ignore everything past a terminator
!     (let ((case-fold-search t))
!       (dolist (terminator bibtex-autokey-title-terminators)
!         (if (string-match terminator titlestring)
!             (setq titlestring (substring titlestring 0 (match-beginning 
0))))))
      ;; gather words from titlestring into a list. Ignore
      ;; specific words and use only a specific amount of words.
      (let ((counter 0)
!           case-fold-search titlewords titlewords-extra titleword end-match)
        (while (and (or (not (numberp bibtex-autokey-titlewords))
                        (< counter (+ bibtex-autokey-titlewords
                                      bibtex-autokey-titlewords-stretch)))
--- 2086,2103 ----
  
  (defun bibtex-autokey-get-title ()
    "Get title field contents up to a terminator."
!   (let ((case-fold-search t)
!         (titlestring
           (bibtex-autokey-get-field "title"
                                     bibtex-autokey-titleword-change-strings)))
      ;; ignore everything past a terminator
!     (dolist (terminator bibtex-autokey-title-terminators)
!       (if (string-match terminator titlestring)
!           (setq titlestring (substring titlestring 0 (match-beginning 0)))))
      ;; gather words from titlestring into a list. Ignore
      ;; specific words and use only a specific amount of words.
      (let ((counter 0)
!           titlewords titlewords-extra titleword end-match)
        (while (and (or (not (numberp bibtex-autokey-titlewords))
                        (< counter (+ bibtex-autokey-titlewords
                                      bibtex-autokey-titlewords-stretch)))
***************
*** 2078,2085 ****
          (setq end-match (match-end 0)
                titleword (substring titlestring
                                     (match-beginning 0) end-match))
!         (unless (bibtex-member-of-regexp titleword
!                                          bibtex-autokey-titleword-ignore)
            (setq titleword
                  (funcall bibtex-autokey-titleword-case-convert titleword))
            (if (or (not (numberp bibtex-autokey-titlewords))
--- 2105,2116 ----
          (setq end-match (match-end 0)
                titleword (substring titlestring
                                     (match-beginning 0) end-match))
!         (unless (let ((lst bibtex-autokey-titleword-ignore))
!                   (while (and lst
!                               (not (string-match (concat "\\`\\(?:" (car lst)
!                                                          "\\)\\'") 
titleword)))
!                     (setq lst (cdr lst)))
!                   lst)
            (setq titleword
                  (funcall bibtex-autokey-titleword-case-convert titleword))
            (if (or (not (numberp bibtex-autokey-titlewords))
***************
*** 2097,2103 ****
    "Do some abbreviations on TITLEWORD.
  The rules are defined in `bibtex-autokey-titleword-abbrevs'
  and `bibtex-autokey-titleword-length'."
!   (let ((case-folde-search t)
          (alist bibtex-autokey-titleword-abbrevs))
      (while (and alist
                  (not (string-match (concat "\\`\\(?:" (caar alist) "\\)\\'")
--- 2128,2134 ----
    "Do some abbreviations on TITLEWORD.
  The rules are defined in `bibtex-autokey-titleword-abbrevs'
  and `bibtex-autokey-titleword-length'."
!   (let ((case-fold-search t)
          (alist bibtex-autokey-titleword-abbrevs))
      (while (and alist
                  (not (string-match (concat "\\`\\(?:" (caar alist) "\\)\\'")
***************
*** 2308,2314 ****
              bounds key)
          (if (listp add)
              (dolist (string add)
!               (unless (assoc (car string) strings)
                  (push string strings))))
          (catch 'userkey
            (while (setq bounds (bibtex-search-forward-string))
--- 2339,2345 ----
              bounds key)
          (if (listp add)
              (dolist (string add)
!               (unless (assoc-string (car string) strings t)
                  (push string strings))))
          (catch 'userkey
            (while (setq bounds (bibtex-search-forward-string))
***************
*** 2317,2325 ****
                  ;; user has aborted by typing a key --> return `aborted'
                  (throw 'userkey 'aborted))
              (setq key (bibtex-reference-key-in-string bounds))
!             (if (not (assoc key strings))
!                 (push (cons key (bibtex-text-in-string bounds t))
!                       strings))
              (goto-char (bibtex-end-of-text-in-string bounds)))
            ;; successful operation --> return `bibtex-strings'
            (setq bibtex-strings strings))))))
--- 2348,2356 ----
                  ;; user has aborted by typing a key --> return `aborted'
                  (throw 'userkey 'aborted))
              (setq key (bibtex-reference-key-in-string bounds))
!             (unless (assoc-string key strings t)
!               (push (cons key (bibtex-text-in-string bounds t))
!                     strings))
              (goto-char (bibtex-end-of-text-in-string bounds)))
            ;; successful operation --> return `bibtex-strings'
            (setq bibtex-strings strings))))))
***************
*** 2409,2419 ****
             ;; return value is handled by choose-completion-string-functions
             nil))))
  
! (defun bibtex-complete-string-cleanup (str)
    "Cleanup after inserting string STR.
! Remove enclosing field delimiters for string STR. Display message with
! expansion of STR."
!   (let ((pair (assoc str bibtex-strings)))
      (when pair
        (if (cdr pair)
            (message "Abbreviation for `%s'" (cdr pair)))
--- 2440,2451 ----
             ;; return value is handled by choose-completion-string-functions
             nil))))
  
! (defun bibtex-complete-string-cleanup (str strings-alist)
    "Cleanup after inserting string STR.
! Remove enclosing field delimiters for string STR.  Display message with
! expansion of STR using expansion list STRINGS-ALIST."
!   (let ((pair (if (stringp str)
!                   (assoc-string str strings-alist t))))
      (when pair
        (if (cdr pair)
            (message "Abbreviation for `%s'" (cdr pair)))
***************
*** 2427,2432 ****
--- 2459,2496 ----
                              (bibtex-end-of-text-in-field bounds)))
                  (bibtex-remove-delimiters))))))))
  
+ (defun bibtex-complete-key-cleanup (key)
+   "Display message on entry KEY after completion of a crossref key."
+   (save-excursion
+     ;; Don't do anything if we completed the key of an entry.
+     (let ((pnt (bibtex-beginning-of-entry)))
+       (if (and (stringp key)
+                (bibtex-find-entry key)
+                (/= pnt (point)))
+           (let* ((bibtex-autokey-name-case-convert 'identity)
+                  (bibtex-autokey-name-length 'infty)
+                  (nl (bibtex-autokey-get-names))
+                  (name (concat (nth 0 nl) (if (nth 1 nl) " etal")))
+                  (year (bibtex-autokey-get-field "year"))
+                  (bibtex-autokey-titlewords 5)
+                  (bibtex-autokey-titlewords-stretch 2)
+                  (bibtex-autokey-titleword-case-convert 'identity)
+                  (bibtex-autokey-titleword-length 5)
+                  (title (mapconcat 'identity
+                                    (bibtex-autokey-get-title) " "))
+                  (journal (bibtex-autokey-get-field
+                            "journal" bibtex-autokey-transcriptions))
+                  (volume (bibtex-autokey-get-field "volume"))
+                  (pages (bibtex-autokey-get-field "pages" '(("-.*\\'" . 
"")))))
+             (message "Ref:%s"
+                      (mapconcat (lambda (arg)
+                                   (if (not (string= "" (cdr arg)))
+                                       (concat (car arg) (cdr arg))))
+                                 `((" " . ,name) (" " . ,year)
+                                   (": " . ,title) (", " . ,journal)
+                                   (" " . ,volume) (":" . ,pages))
+                                 "")))))))
+ 
  (defun bibtex-choose-completion-string (choice buffer mini-p base-size)
    ;; Code borrowed from choose-completion-string:
    ;; We must duplicate the code from choose-completion-string
***************
*** 2460,2476 ****
             (bounds (bibtex-enclosing-field))
             (start-old-text (bibtex-start-of-text-in-field bounds))
             (stop-old-text (bibtex-end-of-text-in-field bounds))
!            (start-name (bibtex-start-of-name-in-field bounds))
!            (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))))
        ;; if executed several times in a row, start each search where
        ;; the last one was finished
        (unless (eq last-command 'bibtex-pop)
--- 2524,2530 ----
             (bounds (bibtex-enclosing-field))
             (start-old-text (bibtex-start-of-text-in-field bounds))
             (stop-old-text (bibtex-end-of-text-in-field bounds))
!            (field-name (bibtex-name-in-field bounds t)))
        ;; if executed several times in a row, start each search where
        ;; the last one was finished
        (unless (eq last-command 'bibtex-pop)
***************
*** 2639,2647 ****
                  )
           nil
           (font-lock-syntactic-keywords . bibtex-font-lock-syntactic-keywords)
         (font-lock-mark-block-function
          . (lambda ()
!          (set-mark (bibtex-end-of-entry))
              (bibtex-beginning-of-entry)))))
    (setq imenu-generic-expression
          (list (list nil bibtex-entry-head bibtex-key-in-head)))
--- 2693,2702 ----
                  )
           nil
           (font-lock-syntactic-keywords . bibtex-font-lock-syntactic-keywords)
+          (font-lock-extra-managed-props . (mouse-face keymap))
         (font-lock-mark-block-function
          . (lambda ()
!               (set-mark (bibtex-end-of-entry))
              (bibtex-beginning-of-entry)))))
    (setq imenu-generic-expression
          (list (list nil bibtex-entry-head bibtex-key-in-head)))
***************
*** 2722,2750 ****
      (let* ((fields-alist (bibtex-parse-entry))
             (field-list (bibtex-field-list
                          (substring (cdr (assoc "=type=" fields-alist))
!                                    1))) ; don't want @
!            (case-fold-search t))
        (dolist (field (car field-list))
!         (unless (bibtex-assoc-regexp (concat "\\`\\(ALT\\)?" (car field) 
"\\'")
!                                      fields-alist)
            (bibtex-make-field field)))
        (dolist (field (cdr field-list))
!         (unless (bibtex-assoc-regexp (concat "\\`\\(OPT\\)?" (car field) 
"\\'")
!                                      fields-alist)
            (bibtex-make-optional-field field))))))
  
  (defun bibtex-parse-entry ()
    "Parse entry at point, return an alist.
  The alist elements have the form (FIELD . TEXT), where FIELD can also be
! the special strings \"=type=\" and \"=key=\". For the FIELD \"=key=\"
! TEXT may be nil. Move point to the end of the last field."
    (let (alist bounds)
      (when (looking-at bibtex-entry-maybe-empty-head)
        (push (cons "=type=" (match-string bibtex-type-in-head)) alist)
        (push (cons "=key=" (match-string bibtex-key-in-head)) alist)
        (goto-char (match-end 0))
        (while (setq bounds (bibtex-parse-field bibtex-field-name))
!       (push (cons (bibtex-name-in-field bounds)
                    (bibtex-text-in-field-bounds bounds))
              alist)
        (goto-char (bibtex-end-of-field bounds))))
--- 2777,2803 ----
      (let* ((fields-alist (bibtex-parse-entry))
             (field-list (bibtex-field-list
                          (substring (cdr (assoc "=type=" fields-alist))
!                                    1)))) ; don't want @
        (dolist (field (car field-list))
!         (unless (assoc-string (car field) fields-alist t)
            (bibtex-make-field field)))
        (dolist (field (cdr field-list))
!         (unless (assoc-string (car field) fields-alist t)
            (bibtex-make-optional-field field))))))
  
  (defun bibtex-parse-entry ()
    "Parse entry at point, return an alist.
  The alist elements have the form (FIELD . TEXT), where FIELD can also be
! the special strings \"=type=\" and \"=key=\".  For the FIELD \"=key=\"
! TEXT may be nil.  Remove \"OPT\" and \"ALT\" from FIELD.
! Move point to the end of the last field."
    (let (alist bounds)
      (when (looking-at bibtex-entry-maybe-empty-head)
        (push (cons "=type=" (match-string bibtex-type-in-head)) alist)
        (push (cons "=key=" (match-string bibtex-key-in-head)) alist)
        (goto-char (match-end 0))
        (while (setq bounds (bibtex-parse-field bibtex-field-name))
!       (push (cons (bibtex-name-in-field bounds t)
                    (bibtex-text-in-field-bounds bounds))
              alist)
        (goto-char (bibtex-end-of-field bounds))))
***************
*** 2770,2776 ****
        (bibtex-beginning-of-entry)
        (when (and
               (looking-at bibtex-entry-head)
!              (equal type (match-string bibtex-type-in-head))
               ;; In case we found ourselves :-(
               (not (equal key (setq tmp (match-string bibtex-key-in-head)))))
          (setq other-key tmp)
--- 2823,2829 ----
        (bibtex-beginning-of-entry)
        (when (and
               (looking-at bibtex-entry-head)
!              (bibtex-string= type (match-string bibtex-type-in-head))
               ;; In case we found ourselves :-(
               (not (equal key (setq tmp (match-string bibtex-key-in-head)))))
          (setq other-key tmp)
***************
*** 2780,2786 ****
        (bibtex-skip-to-valid-entry)
        (when (and
               (looking-at bibtex-entry-head)
!              (equal type (match-string bibtex-type-in-head))
               ;; In case we found ourselves :-(
               (not (equal key (setq tmp (match-string bibtex-key-in-head))))
               (or (not other-key)
--- 2833,2839 ----
        (bibtex-skip-to-valid-entry)
        (when (and
               (looking-at bibtex-entry-head)
!              (bibtex-string= type (match-string bibtex-type-in-head))
               ;; In case we found ourselves :-(
               (not (equal key (setq tmp (match-string bibtex-key-in-head))))
               (or (not other-key)
***************
*** 2794,2804 ****
        (setq other (save-excursion (goto-char other) (bibtex-parse-entry)))
        (setq key-end (point))      ;In case parse-entry changed the buffer.
        (while (setq bounds (bibtex-parse-field bibtex-field-name))
!         (goto-char (bibtex-start-of-name-in-field bounds))
!         (let* ((name (buffer-substring
!                       (if (looking-at "ALT\\|OPT") (match-end 0) (point))
!                       (bibtex-end-of-name-in-field bounds)))
!                (text (assoc-string name other t)))
            (goto-char (bibtex-start-of-text-in-field bounds))
            (if (not (and (looking-at bibtex-empty-field-re) text))
                (goto-char (bibtex-end-of-field bounds))
--- 2847,2854 ----
        (setq other (save-excursion (goto-char other) (bibtex-parse-entry)))
        (setq key-end (point))      ;In case parse-entry changed the buffer.
        (while (setq bounds (bibtex-parse-field bibtex-field-name))
!         (let ((text (assoc-string (bibtex-name-in-field bounds t)
!                                     other t)))
            (goto-char (bibtex-start-of-text-in-field bounds))
            (if (not (and (looking-at bibtex-empty-field-re) text))
                (goto-char (bibtex-end-of-field bounds))
***************
*** 2821,2833 ****
    (interactive)
    (save-excursion
      (let* ((case-fold-search t)
!            (bounds (bibtex-enclosing-field))
!            (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)))
             (field-list (bibtex-field-list (progn (re-search-backward
                                                    
bibtex-entry-maybe-empty-head nil t)
                                                   (bibtex-type-in-head))))
--- 2871,2877 ----
    (interactive)
    (save-excursion
      (let* ((case-fold-search t)
!            (field-name (bibtex-name-in-field (bibtex-enclosing-field) t))
             (field-list (bibtex-field-list (progn (re-search-backward
                                                    
bibtex-entry-maybe-empty-head nil t)
                                                   (bibtex-type-in-head))))
***************
*** 2868,2883 ****
        (indent-to-column (+ bibtex-entry-offset
                             (- bibtex-text-indentation 2))))
    (insert "= ")
!   (if (not bibtex-align-at-equal-sign)
!       (indent-to-column (+ bibtex-entry-offset
!                            bibtex-text-indentation)))
!   (if (not called-by-yank) (insert (bibtex-field-left-delimiter)))
    (let ((init (nth 2 field)))
      (cond ((stringp init)
             (insert init))
            ((fboundp init)
             (insert (funcall init)))))
!   (if (not called-by-yank) (insert (bibtex-field-right-delimiter)))
    (when (interactive-p)
      (forward-char -1)
      (bibtex-print-help-message)))
--- 2912,2927 ----
        (indent-to-column (+ bibtex-entry-offset
                             (- bibtex-text-indentation 2))))
    (insert "= ")
!   (unless bibtex-align-at-equal-sign
!     (indent-to-column (+ bibtex-entry-offset
!                          bibtex-text-indentation)))
!   (unless called-by-yank (insert (bibtex-field-left-delimiter)))
    (let ((init (nth 2 field)))
      (cond ((stringp init)
             (insert init))
            ((fboundp init)
             (insert (funcall init)))))
!   (unless called-by-yank (insert (bibtex-field-right-delimiter)))
    (when (interactive-p)
      (forward-char -1)
      (bibtex-print-help-message)))
***************
*** 3084,3096 ****
          (error "This entry must not follow the crossrefed entry!"))
      (goto-char pos)))
  
! (defun bibtex-find-entry (key)
    "Move point to the beginning of BibTeX entry named KEY.
! Return position of entry if KEY is found or nil if not found."
!   (interactive (list (bibtex-read-key "Find key: ")))
    (let* (case-fold-search
           (pnt (save-excursion
!                 (goto-char (point-min))
                  (if (re-search-forward (concat "^[ \t]*\\("
                                                 bibtex-entry-type
                                                 "\\)[ \t]*[({][ \t\n]*\\("
--- 3128,3144 ----
          (error "This entry must not follow the crossrefed entry!"))
      (goto-char pos)))
  
! (defun bibtex-find-entry (key &optional start)
    "Move point to the beginning of BibTeX entry named KEY.
! Return position of entry if KEY is found or nil if not found.
! Optional arg START is buffer position where the search starts.
! If it is nil, start search at beginning of buffer.
! With prefix arg, the value of START is position of point."
!   (interactive (list (bibtex-read-key "Find key: ")
!                      (if current-prefix-arg (point))))
    (let* (case-fold-search
           (pnt (save-excursion
!                 (goto-char (or start (point-min)))
                  (if (re-search-forward (concat "^[ \t]*\\("
                                                 bibtex-entry-type
                                                 "\\)[ \t]*[({][ \t\n]*\\("
***************
*** 3157,3164 ****
                 ;; buffer contains no valid entries or
                 ;; greater than last entry --> append
                 (bibtex-end-of-entry)
!                (if (not (bobp))
!                    (newline (forward-line 2)))
                 (beginning-of-line)))))
      (unless key-exist t)))
  
--- 3205,3211 ----
                 ;; buffer contains no valid entries or
                 ;; greater than last entry --> append
                 (bibtex-end-of-entry)
!                (unless (bobp) (newline (forward-line 2)))
                 (beginning-of-line)))))
      (unless key-exist t)))
  
***************
*** 3233,3241 ****
              (goto-char (point-min))
              (bibtex-progress-message
               "Checking required fields and month fields")
!             (let ((bibtex-sort-ignore-string-entries t)
!                   (questionable-month
!                    (regexp-opt (mapcar 'car 
bibtex-predefined-month-strings))))
                (bibtex-map-entries
                 (lambda (key beg end)
                   (bibtex-progress-message)
--- 3280,3286 ----
              (goto-char (point-min))
              (bibtex-progress-message
               "Checking required fields and month fields")
!             (let ((bibtex-sort-ignore-string-entries t))
                (bibtex-map-entries
                 (lambda (key beg end)
                   (bibtex-progress-message)
***************
*** 3251,3267 ****
                     (while (setq bounds (bibtex-search-forward-field
                                          bibtex-field-name end))
                       (goto-char (bibtex-start-of-text-in-field bounds))
!                      (let ((field-name (downcase (bibtex-name-in-field 
bounds)))
!                            case-fold-search)
!                        (if (and (equal field-name "month")
!                                 (not (string-match questionable-month
!                                                    
(bibtex-text-in-field-bounds bounds))))
                             (push (list (bibtex-current-line)
                                         "Questionable month field")
                                   error-list))
                         (setq req (delete (assoc-string field-name req t) req)
                               creq (delete (assoc-string field-name creq t) 
creq))
!                        (if (equal field-name "crossref")
                             (setq crossref-there t))))
                     (if crossref-there
                         (setq req creq))
--- 3296,3311 ----
                     (while (setq bounds (bibtex-search-forward-field
                                          bibtex-field-name end))
                       (goto-char (bibtex-start-of-text-in-field bounds))
!                      (let ((field-name (bibtex-name-in-field bounds)))
!                        (if (and (bibtex-string= field-name "month")
!                                 (not (assoc-string 
(bibtex-text-in-field-bounds bounds)
!                                                    
bibtex-predefined-month-strings t)))
                             (push (list (bibtex-current-line)
                                         "Questionable month field")
                                   error-list))
                         (setq req (delete (assoc-string field-name req t) req)
                               creq (delete (assoc-string field-name creq t) 
creq))
!                        (if (bibtex-string= field-name "crossref")
                             (setq crossref-there t))))
                     (if crossref-there
                         (setq req creq))
***************
*** 3305,3314 ****
            (dolist (err error-list)
              (insert bufnam ":" (number-to-string (elt err 0))
                      ": " (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'
            (set-buffer-modified-p nil)
            (toggle-read-only 1)
            (goto-char (point-min))
--- 3349,3354 ----
***************
*** 3395,3405 ****
    (interactive)
    (save-excursion
      (bibtex-inside-field)
!     (let ((bounds (bibtex-enclosing-field)))
!       (goto-char (bibtex-start-of-text-in-field bounds))
!       (delete-char 1)
!       (goto-char (1- (bibtex-end-of-text-in-field bounds)))
!       (delete-backward-char 1))))
  
  (defun bibtex-kill-field (&optional copy-only)
    "Kill the entire enclosing BibTeX field.
--- 3435,3447 ----
    (interactive)
    (save-excursion
      (bibtex-inside-field)
!     (let* ((bounds (bibtex-enclosing-field))
!          (end (bibtex-end-of-text-in-field bounds))
!          (start (bibtex-start-of-text-in-field bounds)))
!       (if (memq (char-before end) '(?\} ?\"))
!         (delete-region (1- end) end))
!       (if (memq (char-after start) '(?\{ ?\"))
!         (delete-region start (1+ start))))))
  
  (defun bibtex-kill-field (&optional copy-only)
    "Kill the entire enclosing BibTeX field.
***************
*** 3455,3460 ****
--- 3497,3503 ----
    (setq bibtex-last-kill-command 'entry))
  
  (defun bibtex-copy-entry-as-kill ()
+   "Copy the entire enclosing BibTeX entry to `bibtex-entry-kill-ring'."
    (interactive)
    (bibtex-kill-entry t))
  
***************
*** 3482,3489 ****
  The sequence of kills wraps around, so that after the oldest one
  comes the newest one."
    (interactive "*p")
!   (if (not (eq last-command 'bibtex-yank))
!       (error "Previous command was not a BibTeX yank"))
    (setq this-command 'bibtex-yank)
    (let ((inhibit-read-only t))
      (delete-region (point) (mark t))
--- 3525,3532 ----
  The sequence of kills wraps around, so that after the oldest one
  comes the newest one."
    (interactive "*p")
!   (unless (eq last-command 'bibtex-yank)
!     (error "Previous command was not a BibTeX yank"))
    (setq this-command 'bibtex-yank)
    (let ((inhibit-read-only t))
      (delete-region (point) (mark t))
***************
*** 3533,3551 ****
      (bibtex-beginning-of-entry)
      (save-excursion
        (when (re-search-forward bibtex-entry-maybe-empty-head nil t)
!         (setq entry-type (downcase (bibtex-type-in-head)))
          (setq key (bibtex-key-in-head))))
      ;; formatting
!     (cond ((equal entry-type "preamble")
             ;; (bibtex-format-preamble)
             (error "No clean up of @Preamble entries"))
!           ((equal entry-type "string"))
             ;; (bibtex-format-string)
            (t (bibtex-format-entry)))
      ;; set key
      (when (or new-key (not key))
        (setq key (bibtex-generate-autokey))
!       (if bibtex-autokey-edit-before-use
            (setq key (bibtex-read-key "Key to use: " key)))
        (re-search-forward bibtex-entry-maybe-empty-head)
        (if (match-beginning bibtex-key-in-head)
--- 3576,3595 ----
      (bibtex-beginning-of-entry)
      (save-excursion
        (when (re-search-forward bibtex-entry-maybe-empty-head nil t)
!         (setq entry-type (bibtex-type-in-head))
          (setq key (bibtex-key-in-head))))
      ;; formatting
!     (cond ((bibtex-string= entry-type "preamble")
             ;; (bibtex-format-preamble)
             (error "No clean up of @Preamble entries"))
!           ((bibtex-string= entry-type "string"))
             ;; (bibtex-format-string)
            (t (bibtex-format-entry)))
      ;; set key
      (when (or new-key (not key))
        (setq key (bibtex-generate-autokey))
!       ;; Sometimes bibtex-generate-autokey returns an empty string
!       (if (or bibtex-autokey-edit-before-use (string= "" key))
            (setq key (bibtex-read-key "Key to use: " key)))
        (re-search-forward bibtex-entry-maybe-empty-head)
        (if (match-beginning bibtex-key-in-head)
***************
*** 3563,3581 ****
               (entry (buffer-substring start end))
               (index (progn (goto-char start)
                             (bibtex-entry-index)))
!              no-error)
          (if (and bibtex-maintain-sorted-entries
                   (not (and bibtex-sort-ignore-string-entries
!                            (equal entry-type "string"))))
              (progn
                (delete-region start end)
!               (setq no-error (bibtex-prepare-new-entry index))
                (insert entry)
                (forward-char -1)
                (bibtex-beginning-of-entry) ; moves backward
                (re-search-forward bibtex-entry-head))
!           (setq no-error (bibtex-find-entry (car index))))
!         (unless no-error
            (error "New inserted entry yields duplicate key"))))
      ;; final clean up
      (unless called-by-reformat
--- 3607,3627 ----
               (entry (buffer-substring start end))
               (index (progn (goto-char start)
                             (bibtex-entry-index)))
!              error)
          (if (and bibtex-maintain-sorted-entries
                   (not (and bibtex-sort-ignore-string-entries
!                            (bibtex-string= entry-type "string"))))
              (progn
                (delete-region start end)
!               (setq error (not (bibtex-prepare-new-entry index)))
                (insert entry)
                (forward-char -1)
                (bibtex-beginning-of-entry) ; moves backward
                (re-search-forward bibtex-entry-head))
!           (bibtex-find-entry key)
!           (setq error (or (/= (point) start)
!                           (bibtex-find-entry key end))))
!         (if error
            (error "New inserted entry yields duplicate key"))))
      ;; final clean up
      (unless called-by-reformat
***************
*** 3583,3589 ****
          (save-restriction
            (bibtex-narrow-to-entry)
            ;; Only update the list of keys if it has been built already.
!           (cond ((equal entry-type "string")
                   (if (listp bibtex-strings) (bibtex-parse-strings t)))
                  ((listp bibtex-reference-keys) (bibtex-parse-keys t)))
            (run-hooks 'bibtex-clean-entry-hook))))))
--- 3629,3635 ----
          (save-restriction
            (bibtex-narrow-to-entry)
            ;; Only update the list of keys if it has been built already.
!           (cond ((bibtex-string= entry-type "string")
                   (if (listp bibtex-strings) (bibtex-parse-strings t)))
                  ((listp bibtex-reference-keys) (bibtex-parse-keys t)))
            (run-hooks 'bibtex-clean-entry-hook))))))
***************
*** 3752,3779 ****
  (defun bibtex-complete ()
    "Complete word fragment before point according to context.
  If point is inside key or crossref field perform key completion based on
! `bibtex-reference-keys'. Inside any other field perform string
! completion based on `bibtex-strings'. An error is signaled if point
! is outside key or BibTeX field."
    (interactive)
!   (let* ((pnt (point))
!          (case-fold-search t)
!          bounds compl)
      (save-excursion
        (if (and (setq bounds (bibtex-enclosing-field t))
                 (>= pnt (bibtex-start-of-text-in-field bounds))
                 (<= pnt (bibtex-end-of-text-in-field bounds)))
!           (progn
!             (goto-char (bibtex-start-of-name-in-field bounds))
!             (setq compl (if (string= "crossref"
!                                      (downcase
!                                       (buffer-substring-no-properties
!                                        (if (looking-at 
"\\(OPT\\)\\|\\(ALT\\)")
!                                            (match-end 0)
!                                          (point))
!                                        (bibtex-end-of-name-in-field bounds))))
!                             'key
!                           'str)))
          (bibtex-beginning-of-entry)
          (if (and (re-search-forward bibtex-entry-maybe-empty-head nil t)
                   ;; point is inside a key
--- 3798,3826 ----
  (defun bibtex-complete ()
    "Complete word fragment before point according to context.
  If point is inside key or crossref field perform key completion based on
! `bibtex-reference-keys'.  Inside a month field perform key completion
! based on `bibtex-predefined-month-strings'.  Inside any other field
! perform string completion based on `bibtex-strings'.  An error is
! signaled if point is outside key or BibTeX field."
    (interactive)
!   (let ((pnt (point))
!         (case-fold-search t)
!         bounds name compl)
      (save-excursion
        (if (and (setq bounds (bibtex-enclosing-field t))
                 (>= pnt (bibtex-start-of-text-in-field bounds))
                 (<= pnt (bibtex-end-of-text-in-field bounds)))
!           (setq name (bibtex-name-in-field bounds t)
!                 compl (cond ((bibtex-string= name "crossref")
!                              'key)
!                             ((bibtex-string= name "month")
!                              bibtex-predefined-month-strings)
!                             (t (if (listp bibtex-strings)
!                                    bibtex-strings
!                                  ;; so that bibtex-complete-string-cleanup
!                                  ;; can do its job
!                                  (bibtex-parse-strings
!                                   (bibtex-string-files-init))))))
          (bibtex-beginning-of-entry)
          (if (and (re-search-forward bibtex-entry-maybe-empty-head nil t)
                   ;; point is inside a key
***************
*** 3789,3812 ****
             ;; key completion
             (setq choose-completion-string-functions
                   (lambda (choice buffer mini-p base-size)
!                    (bibtex-choose-completion-string choice buffer mini-p 
base-size)
!                    (if bibtex-complete-key-cleanup
!                        (funcall bibtex-complete-key-cleanup choice))
                     ;; return t (required by 
choose-completion-string-functions)
                     t))
!            (let ((choice (bibtex-complete-internal bibtex-reference-keys)))
!              (if bibtex-complete-key-cleanup
!                  (funcall bibtex-complete-key-cleanup choice))))
  
!           ((equal compl 'str)
             ;; string completion
             (setq choose-completion-string-functions
!                  (lambda (choice buffer mini-p base-size)
                     (bibtex-choose-completion-string choice buffer mini-p 
base-size)
!                    (bibtex-complete-string-cleanup choice)
                     ;; return t (required by 
choose-completion-string-functions)
                     t))
!            (bibtex-complete-string-cleanup (bibtex-complete-internal 
bibtex-strings)))
  
            (t (error "Point outside key or BibTeX field")))))
  
--- 3836,3858 ----
             ;; key completion
             (setq choose-completion-string-functions
                   (lambda (choice buffer mini-p base-size)
!                     (bibtex-choose-completion-string choice buffer mini-p 
base-size)
!                    (bibtex-complete-key-cleanup choice)
                     ;; return t (required by 
choose-completion-string-functions)
                     t))
!            (bibtex-complete-key-cleanup (bibtex-complete-internal 
!                                          bibtex-reference-keys)))
  
!           (compl
             ;; string completion
             (setq choose-completion-string-functions
!                  `(lambda (choice buffer mini-p base-size)
                     (bibtex-choose-completion-string choice buffer mini-p 
base-size)
!                    (bibtex-complete-string-cleanup choice ',compl)
                     ;; return t (required by 
choose-completion-string-functions)
                     t))
!            (bibtex-complete-string-cleanup (bibtex-complete-internal compl)
!                                            compl))
  
            (t (error "Point outside key or BibTeX field")))))
  
***************
*** 3880,3887 ****
    (interactive (list (completing-read "String key: " bibtex-strings
                                        nil nil nil 'bibtex-key-history)))
    (let ((bibtex-maintain-sorted-entries
!          (if (not bibtex-sort-ignore-string-entries)
!              bibtex-maintain-sorted-entries))
          endpos)
      (unless (bibtex-prepare-new-entry (list key nil "String"))
        (error "Entry with key `%s' already exists" key))
--- 3926,3933 ----
    (interactive (list (completing-read "String key: " bibtex-strings
                                        nil nil nil 'bibtex-key-history)))
    (let ((bibtex-maintain-sorted-entries
!          (unless bibtex-sort-ignore-string-entries
!            bibtex-maintain-sorted-entries))
          endpos)
      (unless (bibtex-prepare-new-entry (list key nil "String"))
        (error "Entry with key `%s' already exists" key))
***************
*** 3913,3918 ****
--- 3959,4044 ----
              "\n")
      (goto-char endpos)))
  
+ (defun bibtex-url (&optional event)
+   "Browse a URL for the BibTeX entry at position PNT.
+ The URL is generated using the schemes defined in `bibtex-generate-url-list'
+ \(see there\). Then the URL is passed to `browse-url'."
+   (interactive (list last-input-event))
+   (save-excursion
+     (if event (posn-set-point (event-end event)))
+     (bibtex-beginning-of-entry)
+     (let ((fields-alist (bibtex-parse-entry))
+           (case-fold-search t)
+           (lst bibtex-generate-url-list)
+           field url scheme)
+       (while (setq scheme (car lst))
+         (when (and (setq field (assoc-string (caar scheme) fields-alist t))
+                    (or (eq t (cdar scheme))
+                        (string-match (cdar scheme) (cdr field))))
+           (setq lst nil)
+           (dolist (step (cdr scheme))
+             (cond ((stringp step)
+                    (setq url (concat url step)))
+                   ((setq field (assoc-string (car step) fields-alist t))
+                    ;; always remove field delimiters
+                    (let* ((text (if (string-match "\\`[{\"]\\(.*\\)[}\"]\\'" 
+                                                   (cdr field))
+                                     (match-string 1 (cdr field))
+                                   (cdr field)))
+                           (str (cond ((eq t (nth 1 step))
+                                       text)
+                                      ((and (consp (nth 1 step))
+                                            (string-match (car (nth 1 step))
+                                                          text))
+                                       (if (numberp (cdr (nth 1 step)))
+                                           (match-string (cdr (nth 1 step))
+                                                         text)
+                                         (replace-match (cdr (nth 1 step))
+                                                        nil nil text)))
+                                      ;; If the scheme is set up correctly,
+                                      ;; we should never reach this point
+                                      (t (error "Match failed: %s" text)))))
+                      (setq url (concat url (if (fboundp (nth 2 step))
+                                                (funcall (nth 2 step) str)
+                                              str)))))
+                   ;; If the scheme is set up correctly,
+                   ;; we should never reach this point
+                   (t (error "Step failed: %s" step))))
+           (message "%s" url)
+           (browse-url url))
+         (setq lst (cdr lst)))
+     (unless url (message "No URL known.")))))
+ 
+ (defun bibtex-font-lock-url (bound)
+   "Font-lock for URLs."
+   (let ((case-fold-search t)
+         (bounds (bibtex-enclosing-field t))
+         (pnt (point))
+         found url)
+     ;; We use start-of-field as syntax-begin
+     (goto-char (if bounds (bibtex-start-of-field bounds) pnt))
+     (while (and (not found)
+                 (search-forward-regexp bibtex-font-lock-url-regexp bound t)
+                 (save-match-data (setq bounds (bibtex-parse-field-text)))
+                 (>= bound (car bounds)))
+       (let ((field (match-string-no-properties 1))
+             (lst bibtex-generate-url-list))
+         (while (and (not found)
+                     (setq url (caar lst)))
+           (when (bibtex-string= field (car url))
+             (if (eq t (cdr url))
+                 (progn
+                   (goto-char (min bound (cdr bounds)))
+                   (set-match-data (list (car bounds) (point)))
+                   (setq found t))
+               (goto-char (car bounds))
+               (setq found (search-forward-regexp (cdr url) 
+                                                  (min bound (cdr bounds)) t)))
+             (if (< (match-beginning 0) pnt)
+                 (setq found nil)))
+           (setq lst (cdr lst)))))
+     found))
+ 
  
  ;; Make BibTeX a Feature
  




reply via email to

[Prev in Thread] Current Thread [Next in Thread]