diff options
| author | Roland Winkler | 2008-01-09 01:37:50 +0000 |
|---|---|---|
| committer | Roland Winkler | 2008-01-09 01:37:50 +0000 |
| commit | 65e10478884e9f4a3ed55d55c7545efab1c2e9cd (patch) | |
| tree | 8b30e3bfbc7985f30e094af7cddfd59d21e7df5c | |
| parent | 59ce725a3b68cbc324f01bc8dc5f9e07286431d1 (diff) | |
| download | emacs-65e10478884e9f4a3ed55d55c7545efab1c2e9cd.tar.gz emacs-65e10478884e9f4a3ed55d55c7545efab1c2e9cd.zip | |
(bibtex-initialize): New autoloaded command. Rename from function
bibtex-files-expand. New optional arg select.
(bibtex-flash-head): Allow blink-matching-delay being zero.
(bibtex-clean-entry): Use atomic-change-group.
(bibtex-format-entry): Check presence of required fields only after
formatting of fields. Use member-ignore-case. Do not use
bibtex-parse-entry. Do not use booktitle field to set a missing
title.
(bibtex-autofill-entry): Do not call undo-boundary.
(bibtex-lessp): Handle crossref keys that point to another bibtex
file.
(bibtex-sort-buffer, bibtex-prepare-new-entry, bibtex-validate):
Parse keys if necessary.
| -rw-r--r-- | lisp/ChangeLog | 17 | ||||
| -rw-r--r-- | lisp/textmodes/bibtex.el | 263 |
2 files changed, 154 insertions, 126 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index ae32b19e7b3..cc79ba3b156 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,20 @@ | |||
| 1 | 2008-01-08 Roland Winkler <Roland.Winkler@physik.uni-erlangen.de> | ||
| 2 | |||
| 3 | * textmodes/bibtex.el (bibtex-initialize): New autoloaded | ||
| 4 | command. Rename from function bibtex-files-expand. New optional | ||
| 5 | arg select. | ||
| 6 | (bibtex-flash-head): Allow blink-matching-delay being zero. | ||
| 7 | (bibtex-clean-entry): Use atomic-change-group. | ||
| 8 | (bibtex-format-entry): Check presence of required fields only | ||
| 9 | after formatting of fields. Use member-ignore-case. Do not use | ||
| 10 | bibtex-parse-entry. Do not use booktitle field to set a missing | ||
| 11 | title. | ||
| 12 | (bibtex-autofill-entry): Do not call undo-boundary. | ||
| 13 | (bibtex-lessp): Handle crossref keys that point to another bibtex | ||
| 14 | file. | ||
| 15 | (bibtex-sort-buffer, bibtex-prepare-new-entry, bibtex-validate): | ||
| 16 | Parse keys if necessary. | ||
| 17 | |||
| 1 | 2008-01-08 Nick Roberts <nickrob@snap.net.nz> | 18 | 2008-01-08 Nick Roberts <nickrob@snap.net.nz> |
| 2 | 19 | ||
| 3 | * progmodes/gdb-ui.el (gdb-var-list-children-1): Put varnum in | 20 | * progmodes/gdb-ui.el (gdb-var-list-children-1): Put varnum in |
diff --git a/lisp/textmodes/bibtex.el b/lisp/textmodes/bibtex.el index 9cdd3082168..1544e4fd24f 100644 --- a/lisp/textmodes/bibtex.el +++ b/lisp/textmodes/bibtex.el | |||
| @@ -119,6 +119,7 @@ inherit-booktitle If entry contains a crossref field and the booktitle | |||
| 119 | realign Realign entries, so that field texts and perhaps equal | 119 | realign Realign entries, so that field texts and perhaps equal |
| 120 | signs (depending on the value of | 120 | signs (depending on the value of |
| 121 | `bibtex-align-at-equal-sign') begin in the same column. | 121 | `bibtex-align-at-equal-sign') begin in the same column. |
| 122 | Also fill fields. | ||
| 122 | last-comma Add or delete comma on end of last field in entry, | 123 | last-comma Add or delete comma on end of last field in entry, |
| 123 | according to value of `bibtex-comma-after-last-field'. | 124 | according to value of `bibtex-comma-after-last-field'. |
| 124 | delimiters Change delimiters according to variables | 125 | delimiters Change delimiters according to variables |
| @@ -1085,6 +1086,7 @@ Used by `bibtex-find-crossref' and for font-locking." | |||
| 1085 | "--" | 1086 | "--" |
| 1086 | ["Convert Alien Buffer" bibtex-convert-alien t]) | 1087 | ["Convert Alien Buffer" bibtex-convert-alien t]) |
| 1087 | ("Operating on Multiple Buffers" | 1088 | ("Operating on Multiple Buffers" |
| 1089 | ["(Re)Initialize BibTeX Buffers" bibtex-initialize t] | ||
| 1088 | ["Validate Entries" bibtex-validate-globally t]))) | 1090 | ["Validate Entries" bibtex-validate-globally t]))) |
| 1089 | 1091 | ||
| 1090 | (easy-menu-define | 1092 | (easy-menu-define |
| @@ -1782,7 +1784,7 @@ If FLAG is nil, a message is echoed if point was incremented at least | |||
| 1782 | ")")) | 1784 | ")")) |
| 1783 | 1785 | ||
| 1784 | (defun bibtex-flash-head (prompt) | 1786 | (defun bibtex-flash-head (prompt) |
| 1785 | "Flash at BibTeX entry head before point, if exists." | 1787 | "Flash at BibTeX entry head before point, if it exists." |
| 1786 | (let ((case-fold-search t) | 1788 | (let ((case-fold-search t) |
| 1787 | (pnt (point))) | 1789 | (pnt (point))) |
| 1788 | (save-excursion | 1790 | (save-excursion |
| @@ -1790,7 +1792,8 @@ If FLAG is nil, a message is echoed if point was incremented at least | |||
| 1790 | (when (and (looking-at bibtex-any-entry-maybe-empty-head) | 1792 | (when (and (looking-at bibtex-any-entry-maybe-empty-head) |
| 1791 | (< (point) pnt)) | 1793 | (< (point) pnt)) |
| 1792 | (goto-char (match-beginning bibtex-type-in-head)) | 1794 | (goto-char (match-beginning bibtex-type-in-head)) |
| 1793 | (if (pos-visible-in-window-p (point)) | 1795 | (if (and (< 0 blink-matching-delay) |
| 1796 | (pos-visible-in-window-p (point))) | ||
| 1794 | (sit-for blink-matching-delay) | 1797 | (sit-for blink-matching-delay) |
| 1795 | (message "%s%s" prompt (buffer-substring-no-properties | 1798 | (message "%s%s" prompt (buffer-substring-no-properties |
| 1796 | (point) (match-end bibtex-key-in-head)))))))) | 1799 | (point) (match-end bibtex-key-in-head)))))))) |
| @@ -1875,38 +1878,42 @@ Optional arg COMMA is as in `bibtex-enclosing-field'." | |||
| 1875 | (defun bibtex-format-entry () | 1878 | (defun bibtex-format-entry () |
| 1876 | "Helper function for `bibtex-clean-entry'. | 1879 | "Helper function for `bibtex-clean-entry'. |
| 1877 | Formats current entry according to variable `bibtex-entry-format'." | 1880 | Formats current entry according to variable `bibtex-entry-format'." |
| 1881 | ;; initialize `bibtex-field-braces-opt' if necessary | ||
| 1882 | (if (and bibtex-field-braces-alist (not bibtex-field-braces-opt)) | ||
| 1883 | (setq bibtex-field-braces-opt | ||
| 1884 | (bibtex-field-re-init bibtex-field-braces-alist 'braces))) | ||
| 1885 | ;; initialize `bibtex-field-strings-opt' if necessary | ||
| 1886 | (if (and bibtex-field-strings-alist (not bibtex-field-strings-opt)) | ||
| 1887 | (setq bibtex-field-strings-opt | ||
| 1888 | (bibtex-field-re-init bibtex-field-strings-alist 'strings))) | ||
| 1889 | |||
| 1878 | (save-excursion | 1890 | (save-excursion |
| 1879 | (save-restriction | 1891 | (save-restriction |
| 1880 | (bibtex-narrow-to-entry) | 1892 | (bibtex-narrow-to-entry) |
| 1881 | (let ((case-fold-search t) | 1893 | (let ((case-fold-search t) |
| 1882 | (format (if (eq bibtex-entry-format t) | 1894 | (format (if (eq bibtex-entry-format t) |
| 1883 | '(realign opts-or-alts required-fields | 1895 | '(realign opts-or-alts required-fields numerical-fields |
| 1884 | numerical-fields | 1896 | page-dashes whitespace inherit-booktitle |
| 1885 | last-comma page-dashes delimiters | 1897 | last-comma delimiters unify-case braces |
| 1886 | unify-case inherit-booktitle) | 1898 | strings) |
| 1887 | bibtex-entry-format)) | 1899 | bibtex-entry-format)) |
| 1888 | crossref-key bounds alternatives-there non-empty-alternative | 1900 | bounds crossref-key req-field-list default-field-list field-list) |
| 1889 | entry-list req-field-list field-list) | 1901 | |
| 1890 | 1902 | ;; There are more elegant high-level functions for several tasks | |
| 1891 | ;; Initialize `bibtex-field-braces-opt' and `bibtex-field-strings-opt' | 1903 | ;; done by `bibtex-format-entry'. However, they contain some |
| 1892 | ;; if necessary. | 1904 | ;; redundancy compared with what we need to do anyway. |
| 1893 | (unless bibtex-field-braces-opt | 1905 | ;; So for speed-up we avoid using them. |
| 1894 | (setq bibtex-field-braces-opt | 1906 | ;; (`bibtex-format-entry' is called many times by `bibtex-reformat'.) |
| 1895 | (bibtex-field-re-init bibtex-field-braces-alist 'braces))) | ||
| 1896 | (unless bibtex-field-strings-opt | ||
| 1897 | (setq bibtex-field-strings-opt | ||
| 1898 | (bibtex-field-re-init bibtex-field-strings-alist 'strings))) | ||
| 1899 | 1907 | ||
| 1900 | ;; identify entry type | 1908 | ;; identify entry type |
| 1901 | (goto-char (point-min)) | 1909 | (goto-char (point-min)) |
| 1902 | (or (re-search-forward bibtex-entry-type nil t) | 1910 | (or (re-search-forward bibtex-entry-type nil t) |
| 1903 | (error "Not inside a BibTeX entry")) | 1911 | (error "Not inside a BibTeX entry")) |
| 1904 | (let ((beg-type (1+ (match-beginning 0))) | 1912 | (let* ((beg-type (1+ (match-beginning 0))) |
| 1905 | (end-type (match-end 0))) | 1913 | (end-type (match-end 0)) |
| 1906 | (setq entry-list (assoc-string (buffer-substring-no-properties | 1914 | (entry-list (assoc-string (buffer-substring-no-properties |
| 1907 | beg-type end-type) | 1915 | beg-type end-type) |
| 1908 | bibtex-entry-field-alist | 1916 | bibtex-entry-field-alist t))) |
| 1909 | t)) | ||
| 1910 | 1917 | ||
| 1911 | ;; unify case of entry name | 1918 | ;; unify case of entry name |
| 1912 | (when (memq 'unify-case format) | 1919 | (when (memq 'unify-case format) |
| @@ -1918,35 +1925,24 @@ Formats current entry according to variable `bibtex-entry-format'." | |||
| 1918 | (goto-char end-type) | 1925 | (goto-char end-type) |
| 1919 | (skip-chars-forward " \t\n") | 1926 | (skip-chars-forward " \t\n") |
| 1920 | (delete-char 1) | 1927 | (delete-char 1) |
| 1921 | (insert (bibtex-entry-left-delimiter)))) | 1928 | (insert (bibtex-entry-left-delimiter))) |
| 1922 | 1929 | ||
| 1923 | ;; determine if entry has crossref field and if at least | 1930 | ;; Do we have a crossref key? |
| 1924 | ;; one alternative is non-empty | 1931 | (goto-char (point-min)) |
| 1925 | (goto-char (point-min)) | 1932 | (if (setq bounds (bibtex-search-forward-field "crossref")) |
| 1926 | (let* ((fields-alist (bibtex-parse-entry t)) | 1933 | (let ((text (bibtex-text-in-field-bounds bounds t))) |
| 1927 | (field (assoc-string "crossref" fields-alist t))) | 1934 | (unless (equal "" text) |
| 1928 | (setq crossref-key (and field | 1935 | (setq crossref-key text)))) |
| 1929 | (not (equal "" (cdr field))) | 1936 | |
| 1930 | (cdr field)) | 1937 | ;; list of required fields appropriate for an entry with |
| 1931 | req-field-list (if crossref-key | 1938 | ;; or without crossref key. |
| 1932 | (nth 0 (nth 2 entry-list)) ; crossref part | 1939 | (setq req-field-list (if (and crossref-key (nth 2 entry-list)) |
| 1933 | (nth 0 (nth 1 entry-list)))) ; required part | 1940 | (car (nth 2 entry-list)) |
| 1934 | 1941 | (car (nth 1 entry-list))) | |
| 1935 | (dolist (rfield req-field-list) | 1942 | ;; default list of fields that may appear in this entry |
| 1936 | (when (nth 3 rfield) ; we should have an alternative | 1943 | default-field-list (append (nth 0 (nth 1 entry-list)) |
| 1937 | (setq alternatives-there t | 1944 | (nth 1 (nth 1 entry-list)) |
| 1938 | field (assoc-string (car rfield) fields-alist t)) | 1945 | bibtex-user-optional-fields))) |
| 1939 | (if (and field | ||
| 1940 | (not (equal "" (cdr field)))) | ||
| 1941 | (cond ((not non-empty-alternative) | ||
| 1942 | (setq non-empty-alternative t)) | ||
| 1943 | ((memq 'required-fields format) | ||
| 1944 | (error "More than one non-empty alternative"))))))) | ||
| 1945 | |||
| 1946 | (if (and alternatives-there | ||
| 1947 | (not non-empty-alternative) | ||
| 1948 | (memq 'required-fields format)) | ||
| 1949 | (error "All alternatives are empty")) | ||
| 1950 | 1946 | ||
| 1951 | ;; process all fields | 1947 | ;; process all fields |
| 1952 | (bibtex-beginning-first-field (point-min)) | 1948 | (bibtex-beginning-first-field (point-min)) |
| @@ -1965,25 +1961,18 @@ Formats current entry according to variable `bibtex-entry-format'." | |||
| 1965 | (empty-field (equal "" (bibtex-text-in-field-bounds bounds t))) | 1961 | (empty-field (equal "" (bibtex-text-in-field-bounds bounds t))) |
| 1966 | deleted) | 1962 | deleted) |
| 1967 | 1963 | ||
| 1968 | ;; We have more elegant high-level functions for several | ||
| 1969 | ;; tasks done by `bibtex-format-entry'. However, they contain | ||
| 1970 | ;; quite some redundancy compared with what we need to do | ||
| 1971 | ;; anyway. So for speed-up we avoid using them. | ||
| 1972 | |||
| 1973 | (if (memq 'opts-or-alts format) | 1964 | (if (memq 'opts-or-alts format) |
| 1965 | ;; delete empty optional and alternative fields | ||
| 1966 | ;; (but keep empty required fields) | ||
| 1974 | (cond ((and empty-field | 1967 | (cond ((and empty-field |
| 1975 | (or opt-alt | 1968 | (or opt-alt |
| 1976 | (let ((field (assoc-string | 1969 | (let ((field (assoc-string |
| 1977 | field-name req-field-list t))) | 1970 | field-name req-field-list t))) |
| 1978 | (or (not field) ; OPT field | 1971 | (or (not field) ; OPT field |
| 1979 | (nth 3 field))))) ; ALT field | 1972 | (nth 3 field))))) ; ALT field |
| 1980 | ;; Either it is an empty ALT field. Then we have checked | ||
| 1981 | ;; already that we have one non-empty alternative. Or it | ||
| 1982 | ;; is an empty OPT field that we do not miss anyway. | ||
| 1983 | ;; So we can safely delete this field. | ||
| 1984 | (delete-region beg-field end-field) | 1973 | (delete-region beg-field end-field) |
| 1985 | (setq deleted t)) | 1974 | (setq deleted t)) |
| 1986 | ;; otherwise: not empty, delete "OPT" or "ALT" | 1975 | ;; otherwise nonempty field: delete "OPT" or "ALT" |
| 1987 | (opt-alt | 1976 | (opt-alt |
| 1988 | (goto-char beg-name) | 1977 | (goto-char beg-name) |
| 1989 | (delete-char 3)))) | 1978 | (delete-char 3)))) |
| @@ -2087,16 +2076,7 @@ Formats current entry according to variable `bibtex-entry-format'." | |||
| 2087 | (goto-char (1+ beg-text)) | 2076 | (goto-char (1+ beg-text)) |
| 2088 | (insert title)))) | 2077 | (insert title)))) |
| 2089 | 2078 | ||
| 2090 | ;; Use booktitle to set a missing title. | 2079 | ;; if empty field is a required field, complain |
| 2091 | (if (and empty-field | ||
| 2092 | (bibtex-string= field-name "title")) | ||
| 2093 | (let ((booktitle (bibtex-text-in-field "booktitle"))) | ||
| 2094 | (when booktitle | ||
| 2095 | (setq empty-field nil) | ||
| 2096 | (goto-char (1+ beg-text)) | ||
| 2097 | (insert booktitle)))) | ||
| 2098 | |||
| 2099 | ;; if empty field, complain | ||
| 2100 | (if (and empty-field | 2080 | (if (and empty-field |
| 2101 | (memq 'required-fields format) | 2081 | (memq 'required-fields format) |
| 2102 | (assoc-string field-name req-field-list t)) | 2082 | (assoc-string field-name req-field-list t)) |
| @@ -2104,12 +2084,8 @@ Formats current entry according to variable `bibtex-entry-format'." | |||
| 2104 | 2084 | ||
| 2105 | ;; unify case of field name | 2085 | ;; unify case of field name |
| 2106 | (if (memq 'unify-case format) | 2086 | (if (memq 'unify-case format) |
| 2107 | (let ((fname (car (assoc-string | 2087 | (let ((fname (car (assoc-string field-name |
| 2108 | field-name | 2088 | default-field-list t)))) |
| 2109 | (append (nth 0 (nth 1 entry-list)) | ||
| 2110 | (nth 1 (nth 1 entry-list)) | ||
| 2111 | bibtex-user-optional-fields) | ||
| 2112 | t)))) | ||
| 2113 | (if fname | 2089 | (if fname |
| 2114 | (progn | 2090 | (progn |
| 2115 | (delete-region beg-name end-name) | 2091 | (delete-region beg-name end-name) |
| @@ -2123,23 +2099,21 @@ Formats current entry according to variable `bibtex-entry-format'." | |||
| 2123 | 2099 | ||
| 2124 | ;; check whether all required fields are present | 2100 | ;; check whether all required fields are present |
| 2125 | (if (memq 'required-fields format) | 2101 | (if (memq 'required-fields format) |
| 2126 | (let ((found 0) altlist) | 2102 | (let ((found 0) alt-list) |
| 2127 | (dolist (fname req-field-list) | 2103 | (dolist (fname req-field-list) |
| 2128 | (if (nth 3 fname) | 2104 | (cond ((nth 3 fname) ; t if field has alternative flag |
| 2129 | (push (car fname) altlist)) | 2105 | (push (car fname) alt-list) |
| 2130 | (unless (or (member (car fname) field-list) | 2106 | (if (member-ignore-case (car fname) field-list) |
| 2131 | (nth 3 fname)) | 2107 | (setq found (1+ found)))) |
| 2132 | (error "Mandatory field `%s' is missing" (car fname)))) | 2108 | ((not (member-ignore-case (car fname) field-list)) |
| 2133 | (when altlist | 2109 | (error "Mandatory field `%s' is missing" (car fname))))) |
| 2134 | (dolist (fname altlist) | 2110 | (if alt-list |
| 2135 | (if (member fname field-list) | 2111 | (cond ((= found 0) |
| 2136 | (setq found (1+ found)))) | 2112 | (error "Alternative mandatory field `%s' is missing" |
| 2137 | (cond ((= found 0) | 2113 | alt-list)) |
| 2138 | (error "Alternative mandatory field `%s' is missing" | 2114 | ((> found 1) |
| 2139 | altlist)) | 2115 | (error "Alternative fields `%s' are defined %s times" |
| 2140 | ((> found 1) | 2116 | alt-list found)))))) |
| 2141 | (error "Alternative fields `%s' are defined %s times" | ||
| 2142 | altlist found)))))) | ||
| 2143 | 2117 | ||
| 2144 | ;; update comma after last field | 2118 | ;; update comma after last field |
| 2145 | (if (memq 'last-comma format) | 2119 | (if (memq 'last-comma format) |
| @@ -2158,7 +2132,7 @@ Formats current entry according to variable `bibtex-entry-format'." | |||
| 2158 | (delete-char 1) | 2132 | (delete-char 1) |
| 2159 | (insert (bibtex-entry-right-delimiter))) | 2133 | (insert (bibtex-entry-right-delimiter))) |
| 2160 | 2134 | ||
| 2161 | ;; fill entry | 2135 | ;; realign and fill entry |
| 2162 | (if (memq 'realign format) | 2136 | (if (memq 'realign format) |
| 2163 | (bibtex-fill-entry)))))) | 2137 | (bibtex-fill-entry)))))) |
| 2164 | 2138 | ||
| @@ -2426,7 +2400,7 @@ Concatenate the key: | |||
| 2426 | (apply 'append | 2400 | (apply 'append |
| 2427 | (mapcar (lambda (buf) | 2401 | (mapcar (lambda (buf) |
| 2428 | (with-current-buffer buf bibtex-reference-keys)) | 2402 | (with-current-buffer buf bibtex-reference-keys)) |
| 2429 | (bibtex-files-expand t))) | 2403 | (bibtex-initialize t))) |
| 2430 | bibtex-reference-keys)) | 2404 | bibtex-reference-keys)) |
| 2431 | 2405 | ||
| 2432 | (defun bibtex-read-key (prompt &optional key global) | 2406 | (defun bibtex-read-key (prompt &optional key global) |
| @@ -2606,14 +2580,22 @@ Parsing initializes `bibtex-reference-keys' and `bibtex-strings'." | |||
| 2606 | (setq bibtex-buffer-last-parsed-tick (buffer-modified-tick))))) | 2580 | (setq bibtex-buffer-last-parsed-tick (buffer-modified-tick))))) |
| 2607 | (setq buffers (cdr buffers)))))) | 2581 | (setq buffers (cdr buffers)))))) |
| 2608 | 2582 | ||
| 2609 | (defun bibtex-files-expand (&optional current force) | 2583 | ;;;###autoload |
| 2610 | "Return an expanded list of BibTeX buffers based on `bibtex-files'. | 2584 | (defun bibtex-initialize (&optional current force select) |
| 2585 | "(Re)Initialize BibTeX buffers. | ||
| 2586 | Visit the BibTeX files defined by `bibtex-files' and return a list | ||
| 2587 | of corresponding buffers. | ||
| 2611 | Initialize in these buffers `bibtex-reference-keys' if not yet set. | 2588 | Initialize in these buffers `bibtex-reference-keys' if not yet set. |
| 2612 | List of BibTeX buffers includes current buffer if CURRENT is non-nil. | 2589 | List of BibTeX buffers includes current buffer if CURRENT is non-nil. |
| 2613 | If FORCE is non-nil, (re)initialize `bibtex-reference-keys' even if | 2590 | If FORCE is non-nil, (re)initialize `bibtex-reference-keys' even if |
| 2614 | already set." | 2591 | already set. If SELECT is non-nil interactively select a BibTeX buffer. |
| 2592 | When called interactively, FORCE is t, CURRENT is t if current buffer uses | ||
| 2593 | `bibtex-mode', and SELECT is t if current buffer does not use `bibtex-mode'," | ||
| 2594 | (interactive (list (eq major-mode 'bibtex-mode) t | ||
| 2595 | (not (eq major-mode 'bibtex-mode)))) | ||
| 2615 | (let ((file-path (split-string (or bibtex-file-path default-directory) ":+")) | 2596 | (let ((file-path (split-string (or bibtex-file-path default-directory) ":+")) |
| 2616 | file-list dir-list buffer-list) | 2597 | file-list dir-list buffer-list) |
| 2598 | ;; generate list of BibTeX files | ||
| 2617 | (dolist (file bibtex-files) | 2599 | (dolist (file bibtex-files) |
| 2618 | (cond ((eq file 'bibtex-file-path) | 2600 | (cond ((eq file 'bibtex-file-path) |
| 2619 | (setq dir-list (append dir-list file-path))) | 2601 | (setq dir-list (append dir-list file-path))) |
| @@ -2624,34 +2606,46 @@ already set." | |||
| 2624 | (file-name-absolute-p file)) | 2606 | (file-name-absolute-p file)) |
| 2625 | (push file file-list)) | 2607 | (push file file-list)) |
| 2626 | (t | 2608 | (t |
| 2627 | (let (fullfilename found) | 2609 | (let (expanded-file-name found) |
| 2628 | (dolist (dir file-path) | 2610 | (dolist (dir file-path) |
| 2629 | (when (file-readable-p | 2611 | (when (file-readable-p |
| 2630 | (setq fullfilename (expand-file-name file dir))) | 2612 | (setq expanded-file-name (expand-file-name file dir))) |
| 2631 | (push fullfilename file-list) | 2613 | (push expanded-file-name file-list) |
| 2632 | (setq found t))) | 2614 | (setq found t))) |
| 2633 | (unless found | 2615 | (unless found |
| 2634 | (error "File %s not in paths defined via bibtex-file-path" | 2616 | (error "File `%s' not in paths defined via bibtex-file-path" |
| 2635 | file)))))) | 2617 | file)))))) |
| 2636 | (dolist (file file-list) | 2618 | (dolist (file file-list) |
| 2637 | (unless (file-readable-p file) | 2619 | (unless (file-readable-p file) |
| 2638 | (error "BibTeX file %s not found" file))) | 2620 | (error "BibTeX file `%s' not found" file))) |
| 2639 | ;; expand dir-list | 2621 | ;; expand dir-list |
| 2640 | (dolist (dir dir-list) | 2622 | (dolist (dir dir-list) |
| 2641 | (setq file-list | 2623 | (setq file-list |
| 2642 | (append file-list (directory-files dir t "\\.bib\\'" t)))) | 2624 | (append file-list (directory-files dir t "\\.bib\\'" t)))) |
| 2643 | (delete-dups file-list) | 2625 | (delete-dups file-list) |
| 2626 | ;; visit files in FILE-LIST | ||
| 2644 | (dolist (file file-list) | 2627 | (dolist (file file-list) |
| 2645 | (when (file-readable-p file) | 2628 | (if (file-readable-p file) |
| 2646 | (push (find-file-noselect file) buffer-list) | 2629 | (push (find-file-noselect file) buffer-list))) |
| 2647 | (with-current-buffer (car buffer-list) | 2630 | ;; include current buffer iff we want it |
| 2648 | (if (or force (not (listp bibtex-reference-keys))) | ||
| 2649 | (bibtex-parse-keys))))) | ||
| 2650 | (cond ((and current (not (memq (current-buffer) buffer-list))) | 2631 | (cond ((and current (not (memq (current-buffer) buffer-list))) |
| 2651 | (push (current-buffer) buffer-list) | 2632 | (push (current-buffer) buffer-list)) |
| 2652 | (if force (bibtex-parse-keys))) | ||
| 2653 | ((and (not current) (memq (current-buffer) buffer-list)) | 2633 | ((and (not current) (memq (current-buffer) buffer-list)) |
| 2654 | (setq buffer-list (delq (current-buffer) buffer-list)))) | 2634 | (setq buffer-list (delq (current-buffer) buffer-list)))) |
| 2635 | ;; parse keys | ||
| 2636 | (dolist (buffer buffer-list) | ||
| 2637 | (with-current-buffer buffer | ||
| 2638 | (if (or force (nlistp bibtex-reference-keys)) | ||
| 2639 | (bibtex-parse-keys)))) | ||
| 2640 | ;; select BibTeX buffer | ||
| 2641 | (if select | ||
| 2642 | (if buffer-list | ||
| 2643 | (switch-to-buffer | ||
| 2644 | (completing-read "Switch to BibTeX buffer: " | ||
| 2645 | (mapcar 'buffer-name buffer-list) | ||
| 2646 | nil t | ||
| 2647 | (if current (buffer-name (current-buffer))))) | ||
| 2648 | (message "No BibTeX buffers defined"))) | ||
| 2655 | buffer-list)) | 2649 | buffer-list)) |
| 2656 | 2650 | ||
| 2657 | (defun bibtex-complete-internal (completions) | 2651 | (defun bibtex-complete-internal (completions) |
| @@ -3130,7 +3124,6 @@ field contents of the neighboring entry. Finally try to update the text | |||
| 3130 | based on the difference between the keys of the neighboring and the current | 3124 | based on the difference between the keys of the neighboring and the current |
| 3131 | entry (for example, the year parts of the keys)." | 3125 | entry (for example, the year parts of the keys)." |
| 3132 | (interactive) | 3126 | (interactive) |
| 3133 | (undo-boundary) ;So you can easily undo it, if it didn't work right. | ||
| 3134 | (bibtex-beginning-of-entry) | 3127 | (bibtex-beginning-of-entry) |
| 3135 | (when (looking-at bibtex-entry-head) | 3128 | (when (looking-at bibtex-entry-head) |
| 3136 | (let ((type (bibtex-type-in-head)) | 3129 | (let ((type (bibtex-type-in-head)) |
| @@ -3413,13 +3406,18 @@ If its value is nil use plain sorting." | |||
| 3413 | (cond ((not index1) (not index2)) ; indices can be nil | 3406 | (cond ((not index1) (not index2)) ; indices can be nil |
| 3414 | ((not index2) nil) | 3407 | ((not index2) nil) |
| 3415 | ((eq bibtex-maintain-sorted-entries 'crossref) | 3408 | ((eq bibtex-maintain-sorted-entries 'crossref) |
| 3416 | (if (nth 1 index1) | 3409 | ;; CROSSREF-KEY may be nil or it can point to an entry |
| 3417 | (if (nth 1 index2) | 3410 | ;; in another BibTeX file. In both cases we ignore CROSSREF-KEY. |
| 3411 | (if (and (nth 1 index1) | ||
| 3412 | (cdr (assoc-string (nth 1 index1) bibtex-reference-keys))) | ||
| 3413 | (if (and (nth 1 index2) | ||
| 3414 | (cdr (assoc-string (nth 1 index2) bibtex-reference-keys))) | ||
| 3418 | (or (string-lessp (nth 1 index1) (nth 1 index2)) | 3415 | (or (string-lessp (nth 1 index1) (nth 1 index2)) |
| 3419 | (and (string-equal (nth 1 index1) (nth 1 index2)) | 3416 | (and (string-equal (nth 1 index1) (nth 1 index2)) |
| 3420 | (string-lessp (nth 0 index1) (nth 0 index2)))) | 3417 | (string-lessp (nth 0 index1) (nth 0 index2)))) |
| 3421 | (not (string-lessp (nth 0 index2) (nth 1 index1)))) | 3418 | (not (string-lessp (nth 0 index2) (nth 1 index1)))) |
| 3422 | (if (nth 1 index2) | 3419 | (if (and (nth 1 index2) |
| 3420 | (cdr (assoc-string (nth 1 index2) bibtex-reference-keys))) | ||
| 3423 | (string-lessp (nth 0 index1) (nth 1 index2)) | 3421 | (string-lessp (nth 0 index1) (nth 1 index2)) |
| 3424 | (string-lessp (nth 0 index1) (nth 0 index2))))) | 3422 | (string-lessp (nth 0 index1) (nth 0 index2))))) |
| 3425 | ((eq bibtex-maintain-sorted-entries 'entry-class) | 3423 | ((eq bibtex-maintain-sorted-entries 'entry-class) |
| @@ -3444,6 +3442,9 @@ are ignored." | |||
| 3444 | (interactive) | 3442 | (interactive) |
| 3445 | (bibtex-beginning-of-first-entry) ; Needed by `sort-subr' | 3443 | (bibtex-beginning-of-first-entry) ; Needed by `sort-subr' |
| 3446 | (bibtex-init-sort-entry-class-alist) ; Needed by `bibtex-lessp'. | 3444 | (bibtex-init-sort-entry-class-alist) ; Needed by `bibtex-lessp'. |
| 3445 | (if (and (eq bibtex-maintain-sorted-entries 'crossref) | ||
| 3446 | (nlistp bibtex-reference-keys)) | ||
| 3447 | (bibtex-parse-keys)) ; Needed by `bibtex-lessp'. | ||
| 3447 | (sort-subr nil | 3448 | (sort-subr nil |
| 3448 | 'bibtex-skip-to-valid-entry ; NEXTREC function | 3449 | 'bibtex-skip-to-valid-entry ; NEXTREC function |
| 3449 | 'bibtex-end-of-entry ; ENDREC function | 3450 | 'bibtex-end-of-entry ; ENDREC function |
| @@ -3539,7 +3540,7 @@ Otherwise, use `set-buffer'. DISPLAY is t when called interactively." | |||
| 3539 | (interactive (list (bibtex-read-key "Find key: " nil current-prefix-arg) | 3540 | (interactive (list (bibtex-read-key "Find key: " nil current-prefix-arg) |
| 3540 | current-prefix-arg nil t)) | 3541 | current-prefix-arg nil t)) |
| 3541 | (if (and global bibtex-files) | 3542 | (if (and global bibtex-files) |
| 3542 | (let ((buffer-list (bibtex-files-expand t)) | 3543 | (let ((buffer-list (bibtex-initialize t)) |
| 3543 | buffer found) | 3544 | buffer found) |
| 3544 | (while (and (not found) | 3545 | (while (and (not found) |
| 3545 | (setq buffer (pop buffer-list))) | 3546 | (setq buffer (pop buffer-list))) |
| @@ -3581,6 +3582,9 @@ search to look for place for KEY. This requires that buffer is sorted, | |||
| 3581 | see `bibtex-validate'. | 3582 | see `bibtex-validate'. |
| 3582 | Return t if preparation was successful or nil if entry KEY already exists." | 3583 | Return t if preparation was successful or nil if entry KEY already exists." |
| 3583 | (bibtex-init-sort-entry-class-alist) ; Needed by `bibtex-lessp'. | 3584 | (bibtex-init-sort-entry-class-alist) ; Needed by `bibtex-lessp'. |
| 3585 | (if (and (eq bibtex-maintain-sorted-entries 'crossref) | ||
| 3586 | (nlistp bibtex-reference-keys)) | ||
| 3587 | (bibtex-parse-keys)) ; Needed by `bibtex-lessp'. | ||
| 3584 | (let ((key (nth 0 index)) | 3588 | (let ((key (nth 0 index)) |
| 3585 | key-exist) | 3589 | key-exist) |
| 3586 | (cond ((or (null key) | 3590 | (cond ((or (null key) |
| @@ -3671,6 +3675,9 @@ Return t if test was successful, nil otherwise." | |||
| 3671 | (setq syntax-error t) | 3675 | (setq syntax-error t) |
| 3672 | 3676 | ||
| 3673 | ;; Check for duplicate keys and correct sort order | 3677 | ;; Check for duplicate keys and correct sort order |
| 3678 | (bibtex-init-sort-entry-class-alist) ; Needed by `bibtex-lessp'. | ||
| 3679 | (bibtex-parse-keys) ; Possibly needed by `bibtex-lessp'. | ||
| 3680 | ; Always needed by subsequent global key check. | ||
| 3674 | (let (previous current key-list) | 3681 | (let (previous current key-list) |
| 3675 | (bibtex-progress-message "Checking for duplicate keys") | 3682 | (bibtex-progress-message "Checking for duplicate keys") |
| 3676 | (bibtex-map-entries | 3683 | (bibtex-map-entries |
| @@ -3692,9 +3699,12 @@ Return t if test was successful, nil otherwise." | |||
| 3692 | (bibtex-progress-message 'done)) | 3699 | (bibtex-progress-message 'done)) |
| 3693 | 3700 | ||
| 3694 | ;; Check for duplicate keys in `bibtex-files'. | 3701 | ;; Check for duplicate keys in `bibtex-files'. |
| 3695 | (bibtex-parse-keys) | 3702 | ;; `bibtex-validate' only compares keys in current buffer with keys |
| 3703 | ;; in `bibtex-files'. `bibtex-validate-globally' compares keys for | ||
| 3704 | ;; each file in `bibtex-files' with keys of all other files in | ||
| 3705 | ;; `bibtex-files'. | ||
| 3696 | ;; We don't want to be fooled by outdated `bibtex-reference-keys'. | 3706 | ;; We don't want to be fooled by outdated `bibtex-reference-keys'. |
| 3697 | (dolist (buffer (bibtex-files-expand nil t)) | 3707 | (dolist (buffer (bibtex-initialize nil t)) |
| 3698 | (dolist (key (with-current-buffer buffer bibtex-reference-keys)) | 3708 | (dolist (key (with-current-buffer buffer bibtex-reference-keys)) |
| 3699 | (when (and (cdr key) | 3709 | (when (and (cdr key) |
| 3700 | (cdr (assoc-string (car key) bibtex-reference-keys))) | 3710 | (cdr (assoc-string (car key) bibtex-reference-keys))) |
| @@ -3792,7 +3802,7 @@ Return t if test was successful, nil otherwise." | |||
| 3792 | With optional prefix arg STRINGS, check for duplicate strings, too. | 3802 | With optional prefix arg STRINGS, check for duplicate strings, too. |
| 3793 | Return t if test was successful, nil otherwise." | 3803 | Return t if test was successful, nil otherwise." |
| 3794 | (interactive "P") | 3804 | (interactive "P") |
| 3795 | (let ((buffer-list (bibtex-files-expand t)) | 3805 | (let ((buffer-list (bibtex-initialize t)) |
| 3796 | buffer-key-list current-buf current-keys error-list) | 3806 | buffer-key-list current-buf current-keys error-list) |
| 3797 | ;; Check for duplicate keys within BibTeX buffer | 3807 | ;; Check for duplicate keys within BibTeX buffer |
| 3798 | (dolist (buffer buffer-list) | 3808 | (dolist (buffer buffer-list) |
| @@ -4133,14 +4143,15 @@ At end of the cleaning process, the functions in | |||
| 4133 | (error "Not inside a BibTeX entry"))) | 4143 | (error "Not inside a BibTeX entry"))) |
| 4134 | (entry-type (bibtex-type-in-head)) | 4144 | (entry-type (bibtex-type-in-head)) |
| 4135 | (key (bibtex-key-in-head))) | 4145 | (key (bibtex-key-in-head))) |
| 4136 | ;; formatting | 4146 | ;; formatting (undone if error occurs) |
| 4137 | (cond ((bibtex-string= entry-type "preamble") | 4147 | (atomic-change-group |
| 4138 | ;; (bibtex-format-preamble) | 4148 | (cond ((bibtex-string= entry-type "preamble") |
| 4139 | (error "No clean up of @Preamble entries")) | 4149 | ;; (bibtex-format-preamble) |
| 4140 | ((bibtex-string= entry-type "string") | 4150 | (error "No clean up of @Preamble entries")) |
| 4141 | (setq entry-type 'string)) | 4151 | ((bibtex-string= entry-type "string") |
| 4142 | ;; (bibtex-format-string) | 4152 | (setq entry-type 'string)) |
| 4143 | (t (bibtex-format-entry))) | 4153 | ;; (bibtex-format-string) |
| 4154 | (t (bibtex-format-entry)))) | ||
| 4144 | ;; set key | 4155 | ;; set key |
| 4145 | (when (or new-key (not key)) | 4156 | (when (or new-key (not key)) |
| 4146 | (setq key (bibtex-generate-autokey)) | 4157 | (setq key (bibtex-generate-autokey)) |
| @@ -4184,7 +4195,7 @@ At end of the cleaning process, the functions in | |||
| 4184 | (bibtex-find-entry key nil end)))) | 4195 | (bibtex-find-entry key nil end)))) |
| 4185 | (if error | 4196 | (if error |
| 4186 | (error "New inserted entry yields duplicate key")) | 4197 | (error "New inserted entry yields duplicate key")) |
| 4187 | (dolist (buffer (bibtex-files-expand)) | 4198 | (dolist (buffer (bibtex-initialize)) |
| 4188 | (with-current-buffer buffer | 4199 | (with-current-buffer buffer |
| 4189 | (if (cdr (assoc-string key bibtex-reference-keys)) | 4200 | (if (cdr (assoc-string key bibtex-reference-keys)) |
| 4190 | (error "Duplicate key in %s" (buffer-file-name))))) | 4201 | (error "Duplicate key in %s" (buffer-file-name))))) |