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,v


From: Roland Winkler
Subject: [Emacs-diffs] Changes to emacs/lisp/textmodes/bibtex.el,v
Date: Wed, 09 Jan 2008 01:35:46 +0000

CVSROOT:        /sources/emacs
Module name:    emacs
Changes by:     Roland Winkler <winkler>        08/01/09 01:35:46

Index: bibtex.el
===================================================================
RCS file: /sources/emacs/emacs/lisp/textmodes/bibtex.el,v
retrieving revision 1.131
retrieving revision 1.132
diff -u -b -r1.131 -r1.132
--- bibtex.el   8 Jan 2008 20:45:44 -0000       1.131
+++ bibtex.el   9 Jan 2008 01:35:45 -0000       1.132
@@ -119,6 +119,7 @@
 realign             Realign entries, so that field texts and perhaps equal
                       signs (depending on the value of
                       `bibtex-align-at-equal-sign') begin in the same column.
+                      Also fill fields.
 last-comma          Add or delete comma on end of last field in entry,
                       according to value of `bibtex-comma-after-last-field'.
 delimiters          Change delimiters according to variables
@@ -1085,6 +1086,7 @@
      "--"
      ["Convert Alien Buffer" bibtex-convert-alien t])
     ("Operating on Multiple Buffers"
+     ["(Re)Initialize BibTeX Buffers" bibtex-initialize t]
      ["Validate Entries" bibtex-validate-globally t])))
 
 (easy-menu-define
@@ -1782,7 +1784,7 @@
     ")"))
 
 (defun bibtex-flash-head (prompt)
-  "Flash at BibTeX entry head before point, if exists."
+  "Flash at BibTeX entry head before point, if it exists."
   (let ((case-fold-search t)
         (pnt (point)))
     (save-excursion
@@ -1790,7 +1792,8 @@
       (when (and (looking-at bibtex-any-entry-maybe-empty-head)
                  (< (point) pnt))
         (goto-char (match-beginning bibtex-type-in-head))
-        (if (pos-visible-in-window-p (point))
+        (if (and (< 0 blink-matching-delay)
+                 (pos-visible-in-window-p (point)))
             (sit-for blink-matching-delay)
           (message "%s%s" prompt (buffer-substring-no-properties
                                   (point) (match-end bibtex-key-in-head))))))))
@@ -1875,38 +1878,42 @@
 (defun bibtex-format-entry ()
   "Helper function for `bibtex-clean-entry'.
 Formats current entry according to variable `bibtex-entry-format'."
+  ;; initialize `bibtex-field-braces-opt' if necessary
+  (if (and bibtex-field-braces-alist (not bibtex-field-braces-opt))
+      (setq bibtex-field-braces-opt
+            (bibtex-field-re-init bibtex-field-braces-alist 'braces)))
+  ;; initialize `bibtex-field-strings-opt' if necessary
+  (if (and bibtex-field-strings-alist (not bibtex-field-strings-opt))
+      (setq bibtex-field-strings-opt
+            (bibtex-field-re-init bibtex-field-strings-alist 'strings)))
+
   (save-excursion
     (save-restriction
       (bibtex-narrow-to-entry)
       (let ((case-fold-search t)
             (format (if (eq bibtex-entry-format t)
-                        '(realign opts-or-alts required-fields
-                                  numerical-fields
-                                  last-comma page-dashes delimiters
-                                  unify-case inherit-booktitle)
+                        '(realign opts-or-alts required-fields numerical-fields
+                                  page-dashes whitespace inherit-booktitle
+                                  last-comma delimiters unify-case braces
+                                  strings)
                       bibtex-entry-format))
-            crossref-key bounds alternatives-there non-empty-alternative
-            entry-list req-field-list field-list)
+            bounds crossref-key req-field-list default-field-list field-list)
 
-        ;; Initialize `bibtex-field-braces-opt' and `bibtex-field-strings-opt'
-        ;; if necessary.
-        (unless bibtex-field-braces-opt
-          (setq bibtex-field-braces-opt
-                (bibtex-field-re-init bibtex-field-braces-alist 'braces)))
-        (unless bibtex-field-strings-opt
-          (setq bibtex-field-strings-opt
-                (bibtex-field-re-init bibtex-field-strings-alist 'strings)))
+        ;; There are more elegant high-level functions for several tasks
+        ;; done by `bibtex-format-entry'.  However, they contain some
+        ;; redundancy compared with what we need to do anyway.
+        ;; So for speed-up we avoid using them.
+        ;; (`bibtex-format-entry' is called many times by `bibtex-reformat'.)
 
         ;; identify entry type
         (goto-char (point-min))
         (or (re-search-forward bibtex-entry-type nil t)
             (error "Not inside a BibTeX entry"))
-        (let ((beg-type (1+ (match-beginning 0)))
-              (end-type (match-end 0)))
-          (setq entry-list (assoc-string (buffer-substring-no-properties
+        (let* ((beg-type (1+ (match-beginning 0)))
+               (end-type (match-end 0))
+               (entry-list (assoc-string (buffer-substring-no-properties
                                          beg-type end-type)
-                                        bibtex-entry-field-alist
-                                        t))
+                                        bibtex-entry-field-alist t)))
 
           ;; unify case of entry name
           (when (memq 'unify-case format)
@@ -1918,35 +1925,24 @@
             (goto-char end-type)
             (skip-chars-forward " \t\n")
             (delete-char 1)
-            (insert (bibtex-entry-left-delimiter))))
+            (insert (bibtex-entry-left-delimiter)))
 
-        ;; determine if entry has crossref field and if at least
-        ;; one alternative is non-empty
+          ;; Do we have a crossref key?
         (goto-char (point-min))
-        (let* ((fields-alist (bibtex-parse-entry t))
-               (field (assoc-string "crossref" fields-alist t)))
-          (setq crossref-key (and field
-                                  (not (equal "" (cdr field)))
-                                  (cdr field))
-                req-field-list (if crossref-key
-                                   (nth 0 (nth 2 entry-list)) ; crossref part
-                                 (nth 0 (nth 1 entry-list)))) ; required part
-
-          (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 (equal "" (cdr field))))
-                  (cond ((not non-empty-alternative)
-                         (setq non-empty-alternative t))
-                        ((memq 'required-fields format)
-                         (error "More than one non-empty alternative")))))))
-
-        (if (and alternatives-there
-                 (not non-empty-alternative)
-                 (memq 'required-fields format))
-            (error "All alternatives are empty"))
+          (if (setq bounds (bibtex-search-forward-field "crossref"))
+              (let ((text (bibtex-text-in-field-bounds bounds t)))
+                (unless (equal "" text)
+                  (setq crossref-key text))))
+
+          ;; list of required fields appropriate for an entry with
+          ;; or without crossref key.
+          (setq req-field-list (if (and crossref-key (nth 2 entry-list))
+                                   (car (nth 2 entry-list))
+                                 (car (nth 1 entry-list)))
+                ;; default list of fields that may appear in this entry
+                default-field-list (append (nth 0 (nth 1 entry-list))
+                                           (nth 1 (nth 1 entry-list))
+                                           bibtex-user-optional-fields)))
 
         ;; process all fields
         (bibtex-beginning-first-field (point-min))
@@ -1965,25 +1961,18 @@
                  (empty-field (equal "" (bibtex-text-in-field-bounds bounds 
t)))
                  deleted)
 
-            ;; We have more elegant high-level functions for several
-            ;; tasks done by `bibtex-format-entry'.  However, they contain
-            ;; quite some redundancy compared with what we need to do
-            ;; anyway.  So for speed-up we avoid using them.
-
             (if (memq 'opts-or-alts format)
+                ;; delete empty optional and alternative fields
+                ;; (but keep empty required fields)
                 (cond ((and empty-field
                             (or opt-alt
                                 (let ((field (assoc-string
                                               field-name req-field-list t)))
                                   (or (not field)       ; OPT field
                                       (nth 3 field))))) ; ALT field
-                       ;; Either it is an empty ALT field.  Then we have 
checked
-                       ;; already that we have one non-empty alternative.  Or 
it
-                       ;; is an empty OPT field that we do not miss anyway.
-                       ;; So we can safely delete this field.
                        (delete-region beg-field end-field)
                        (setq deleted t))
-                      ;; otherwise: not empty, delete "OPT" or "ALT"
+                      ;; otherwise nonempty field: delete "OPT" or "ALT"
                       (opt-alt
                        (goto-char beg-name)
                        (delete-char 3))))
@@ -2087,16 +2076,7 @@
                       (goto-char (1+ beg-text))
                       (insert title))))
 
-             ;; 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)
-                     (goto-char (1+ beg-text))
-                     (insert booktitle))))
-
-              ;; if empty field, complain
+              ;; if empty field is a required field, complain
               (if (and empty-field
                        (memq 'required-fields format)
                        (assoc-string field-name req-field-list t))
@@ -2104,12 +2084,8 @@
 
               ;; unify case of field name
               (if (memq 'unify-case format)
-                  (let ((fname (car (assoc-string
-                                     field-name
-                                    (append (nth 0 (nth 1 entry-list))
-                                            (nth 1 (nth 1 entry-list))
-                                            bibtex-user-optional-fields)
-                                    t))))
+                  (let ((fname (car (assoc-string field-name
+                                                  default-field-list t))))
                     (if fname
                         (progn
                           (delete-region beg-name end-name)
@@ -2123,23 +2099,21 @@
 
         ;; check whether all required fields are present
         (if (memq 'required-fields format)
-            (let ((found 0) altlist)
+            (let ((found 0) alt-list)
               (dolist (fname req-field-list)
-                (if (nth 3 fname)
-                    (push (car fname) altlist))
-                (unless (or (member (car fname) field-list)
-                            (nth 3 fname))
-                  (error "Mandatory field `%s' is missing" (car fname))))
-              (when altlist
-                (dolist (fname altlist)
-                  (if (member fname field-list)
+                (cond ((nth 3 fname) ; t if field has alternative flag
+                       (push (car fname) alt-list)
+                       (if (member-ignore-case (car fname) field-list)
                       (setq found (1+ found))))
+                      ((not (member-ignore-case (car fname) field-list))
+                       (error "Mandatory field `%s' is missing" (car fname)))))
+              (if alt-list
                 (cond ((= found 0)
                        (error "Alternative mandatory field `%s' is missing"
-                              altlist))
+                                alt-list))
                       ((> found 1)
                        (error "Alternative fields `%s' are defined %s times"
-                              altlist found))))))
+                                alt-list found))))))
 
         ;; update comma after last field
         (if (memq 'last-comma format)
@@ -2158,7 +2132,7 @@
           (delete-char 1)
           (insert (bibtex-entry-right-delimiter)))
 
-        ;; fill entry
+        ;; realign and fill entry
         (if (memq 'realign format)
             (bibtex-fill-entry))))))
 
@@ -2426,7 +2400,7 @@
       (apply 'append
              (mapcar (lambda (buf)
                        (with-current-buffer buf bibtex-reference-keys))
-                     (bibtex-files-expand t)))
+                     (bibtex-initialize t)))
     bibtex-reference-keys))
 
 (defun bibtex-read-key (prompt &optional key global)
@@ -2606,14 +2580,22 @@
                   (setq bibtex-buffer-last-parsed-tick 
(buffer-modified-tick)))))
         (setq buffers (cdr buffers))))))
 
-(defun bibtex-files-expand (&optional current force)
-  "Return an expanded list of BibTeX buffers based on `bibtex-files'.
+;;;###autoload
+(defun bibtex-initialize (&optional current force select)
+  "(Re)Initialize BibTeX buffers.
+Visit the BibTeX files defined by `bibtex-files' and return a list
+of corresponding buffers.
 Initialize in these buffers `bibtex-reference-keys' if not yet set.
 List of BibTeX buffers includes current buffer if CURRENT is non-nil.
 If FORCE is non-nil, (re)initialize `bibtex-reference-keys' even if
-already set."
+already set.  If SELECT is non-nil interactively select a BibTeX buffer.
+When called interactively, FORCE is t, CURRENT is t if current buffer uses
+`bibtex-mode', and SELECT is t if current buffer does not use `bibtex-mode',"
+  (interactive (list (eq major-mode 'bibtex-mode) t
+                     (not (eq major-mode 'bibtex-mode))))
   (let ((file-path (split-string (or bibtex-file-path default-directory) ":+"))
         file-list dir-list buffer-list)
+    ;; generate list of BibTeX files
     (dolist (file bibtex-files)
       (cond ((eq file 'bibtex-file-path)
              (setq dir-list (append dir-list file-path)))
@@ -2624,34 +2606,46 @@
                     (file-name-absolute-p file))
              (push file file-list))
             (t
-             (let (fullfilename found)
+             (let (expanded-file-name found)
                (dolist (dir file-path)
                  (when (file-readable-p
-                        (setq fullfilename (expand-file-name file dir)))
-                   (push fullfilename file-list)
+                        (setq expanded-file-name (expand-file-name file dir)))
+                   (push expanded-file-name file-list)
                    (setq found t)))
                (unless found
-                 (error "File %s not in paths defined via bibtex-file-path"
+                 (error "File `%s' not in paths defined via bibtex-file-path"
                         file))))))
     (dolist (file file-list)
       (unless (file-readable-p file)
-        (error "BibTeX file %s not found" file)))
+        (error "BibTeX file `%s' not found" file)))
     ;; expand dir-list
     (dolist (dir dir-list)
       (setq file-list
             (append file-list (directory-files dir t "\\.bib\\'" t))))
     (delete-dups file-list)
+    ;; visit files in FILE-LIST
     (dolist (file file-list)
-      (when (file-readable-p file)
-        (push (find-file-noselect file) buffer-list)
-        (with-current-buffer (car buffer-list)
-          (if (or force (not (listp bibtex-reference-keys)))
-            (bibtex-parse-keys)))))
+      (if (file-readable-p file)
+        (push (find-file-noselect file) buffer-list)))
+    ;; include current buffer iff we want it
     (cond ((and current (not (memq (current-buffer) buffer-list)))
-           (push (current-buffer) buffer-list)
-           (if force (bibtex-parse-keys)))
+           (push (current-buffer) buffer-list))
           ((and (not current) (memq (current-buffer) buffer-list))
            (setq buffer-list (delq (current-buffer) buffer-list))))
+    ;; parse keys
+    (dolist (buffer buffer-list)
+      (with-current-buffer buffer
+        (if (or force (nlistp bibtex-reference-keys))
+            (bibtex-parse-keys))))
+    ;; select BibTeX buffer
+    (if select
+        (if buffer-list
+            (switch-to-buffer
+             (completing-read "Switch to BibTeX buffer: "
+                              (mapcar 'buffer-name buffer-list)
+                              nil t
+                              (if current (buffer-name (current-buffer)))))
+          (message "No BibTeX buffers defined")))
     buffer-list))
 
 (defun bibtex-complete-internal (completions)
@@ -3130,7 +3124,6 @@
 based on the difference between the keys of the neighboring and the current
 entry (for example, the year parts of the keys)."
   (interactive)
-  (undo-boundary)      ;So you can easily undo it, if it didn't work right.
   (bibtex-beginning-of-entry)
   (when (looking-at bibtex-entry-head)
     (let ((type (bibtex-type-in-head))
@@ -3413,13 +3406,18 @@
   (cond ((not index1) (not index2)) ; indices can be nil
         ((not index2) nil)
         ((eq bibtex-maintain-sorted-entries 'crossref)
-         (if (nth 1 index1)
-             (if (nth 1 index2)
+         ;; CROSSREF-KEY may be nil or it can point to an entry
+         ;; in another BibTeX file.  In both cases we ignore CROSSREF-KEY.
+         (if (and (nth 1 index1)
+                  (cdr (assoc-string (nth 1 index1) bibtex-reference-keys)))
+             (if (and (nth 1 index2)
+                      (cdr (assoc-string (nth 1 index2) 
bibtex-reference-keys)))
                  (or (string-lessp (nth 1 index1) (nth 1 index2))
                      (and (string-equal (nth 1 index1) (nth 1 index2))
                           (string-lessp (nth 0 index1) (nth 0 index2))))
                (not (string-lessp (nth 0 index2) (nth 1 index1))))
-           (if (nth 1 index2)
+           (if (and (nth 1 index2)
+                    (cdr (assoc-string (nth 1 index2) bibtex-reference-keys)))
                (string-lessp (nth 0 index1) (nth 1 index2))
              (string-lessp (nth 0 index1) (nth 0 index2)))))
         ((eq bibtex-maintain-sorted-entries 'entry-class)
@@ -3444,6 +3442,9 @@
   (interactive)
   (bibtex-beginning-of-first-entry)     ; Needed by `sort-subr'
   (bibtex-init-sort-entry-class-alist)  ; Needed by `bibtex-lessp'.
+  (if (and (eq bibtex-maintain-sorted-entries 'crossref)
+           (nlistp bibtex-reference-keys))
+      (bibtex-parse-keys))              ; Needed by `bibtex-lessp'.
   (sort-subr nil
              'bibtex-skip-to-valid-entry   ; NEXTREC function
              'bibtex-end-of-entry          ; ENDREC function
@@ -3539,7 +3540,7 @@
   (interactive (list (bibtex-read-key "Find key: " nil current-prefix-arg)
                      current-prefix-arg nil t))
   (if (and global bibtex-files)
-      (let ((buffer-list (bibtex-files-expand t))
+      (let ((buffer-list (bibtex-initialize t))
             buffer found)
         (while (and (not found)
                     (setq buffer (pop buffer-list)))
@@ -3581,6 +3582,9 @@
 see `bibtex-validate'.
 Return t if preparation was successful or nil if entry KEY already exists."
   (bibtex-init-sort-entry-class-alist)  ; Needed by `bibtex-lessp'.
+  (if (and (eq bibtex-maintain-sorted-entries 'crossref)
+           (nlistp bibtex-reference-keys))
+      (bibtex-parse-keys))              ; Needed by `bibtex-lessp'.
   (let ((key (nth 0 index))
         key-exist)
     (cond ((or (null key)
@@ -3671,6 +3675,9 @@
             (setq syntax-error t)
 
           ;; Check for duplicate keys and correct sort order
+          (bibtex-init-sort-entry-class-alist)  ; Needed by `bibtex-lessp'.
+          (bibtex-parse-keys) ; Possibly needed by `bibtex-lessp'.
+                              ; Always needed by subsequent global key check.
           (let (previous current key-list)
             (bibtex-progress-message "Checking for duplicate keys")
             (bibtex-map-entries
@@ -3692,9 +3699,12 @@
             (bibtex-progress-message 'done))
 
           ;; Check for duplicate keys in `bibtex-files'.
-          (bibtex-parse-keys)
+          ;; `bibtex-validate' only compares keys in current buffer with keys
+          ;; in `bibtex-files'. `bibtex-validate-globally' compares keys for
+          ;; each file in `bibtex-files' with keys of all other files in
+          ;; `bibtex-files'.
           ;; We don't want to be fooled by outdated `bibtex-reference-keys'.
-          (dolist (buffer (bibtex-files-expand nil t))
+          (dolist (buffer (bibtex-initialize nil t))
             (dolist (key (with-current-buffer buffer bibtex-reference-keys))
               (when (and (cdr key)
                          (cdr (assoc-string (car key) bibtex-reference-keys)))
@@ -3792,7 +3802,7 @@
 With optional prefix arg STRINGS, check for duplicate strings, too.
 Return t if test was successful, nil otherwise."
   (interactive "P")
-  (let ((buffer-list (bibtex-files-expand t))
+  (let ((buffer-list (bibtex-initialize t))
         buffer-key-list current-buf current-keys error-list)
     ;; Check for duplicate keys within BibTeX buffer
     (dolist (buffer buffer-list)
@@ -4133,14 +4143,15 @@
               (error "Not inside a BibTeX entry")))
         (entry-type (bibtex-type-in-head))
         (key (bibtex-key-in-head)))
-    ;; formatting
+    ;; formatting (undone if error occurs)
+    (atomic-change-group
     (cond ((bibtex-string= entry-type "preamble")
            ;; (bibtex-format-preamble)
            (error "No clean up of @Preamble entries"))
           ((bibtex-string= entry-type "string")
            (setq entry-type 'string))
           ;; (bibtex-format-string)
-          (t (bibtex-format-entry)))
+            (t (bibtex-format-entry))))
     ;; set key
     (when (or new-key (not key))
       (setq key (bibtex-generate-autokey))
@@ -4184,7 +4195,7 @@
                           (bibtex-find-entry key nil end))))
         (if error
             (error "New inserted entry yields duplicate key"))
-        (dolist (buffer (bibtex-files-expand))
+        (dolist (buffer (bibtex-initialize))
           (with-current-buffer buffer
             (if (cdr (assoc-string key bibtex-reference-keys))
                 (error "Duplicate key in %s" (buffer-file-name)))))




reply via email to

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