/[emacs]/emacs/lisp/textmodes/bibtex.el
ViewVC logotype

Diff of /emacs/lisp/textmodes/bibtex.el

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

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

Legend:
Removed from v.1.83  
changed lines
  Added in v.1.84

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26