diff options
| author | Karoly Lorentey | 2004-11-06 17:52:02 +0000 |
|---|---|---|
| committer | Karoly Lorentey | 2004-11-06 17:52:02 +0000 |
| commit | 65ea79492334e2ef7b5b4e0d23b6f68ba2f4d0bb (patch) | |
| tree | 853cf391ca1abda4f4ccd6fe8e7bb43f7c86ee08 /lisp/textmodes | |
| parent | e0bc17abe6979d607e8de4684dddb96e53c60065 (diff) | |
| parent | 392cf16dd0ee9358f8af0cd0d8048b822456bbeb (diff) | |
| download | emacs-65ea79492334e2ef7b5b4e0d23b6f68ba2f4d0bb.tar.gz emacs-65ea79492334e2ef7b5b4e0d23b6f68ba2f4d0bb.zip | |
Merged in changes from CVS trunk.
Patches applied:
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-653
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-654
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-655
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-656
Update from CVS: lisp/man.el (Man-xref-normal-file): Fix help-echo.
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-657
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-658
Merge from gnus--rel--5.10
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-659
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-660
Merge from gnus--rel--5.10
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-661
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-662
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-663
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-664
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-665
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-666
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-667
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-668
Merge from gnus--rel--5.10
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-669
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-670
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-671
Update from CVS
* miles@gnu.org--gnu-2004/gnus--rel--5.10--patch-64
Update from CVS
* miles@gnu.org--gnu-2004/gnus--rel--5.10--patch-65
Update from CVS
* miles@gnu.org--gnu-2004/gnus--rel--5.10--patch-66
Update from CVS
* miles@gnu.org--gnu-2004/gnus--rel--5.10--patch-67
Update from CVS
* miles@gnu.org--gnu-2004/gnus--rel--5.10--patch-68
Update from CVS
git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-264
Diffstat (limited to 'lisp/textmodes')
| -rw-r--r-- | lisp/textmodes/bibtex.el | 1187 | ||||
| -rw-r--r-- | lisp/textmodes/flyspell.el | 4 | ||||
| -rw-r--r-- | lisp/textmodes/ispell.el | 5 | ||||
| -rw-r--r-- | lisp/textmodes/table.el | 3 | ||||
| -rw-r--r-- | lisp/textmodes/texinfo.el | 4 |
5 files changed, 722 insertions, 481 deletions
diff --git a/lisp/textmodes/bibtex.el b/lisp/textmodes/bibtex.el index ddc1d4ecb62..dd989fbea81 100644 --- a/lisp/textmodes/bibtex.el +++ b/lisp/textmodes/bibtex.el | |||
| @@ -42,6 +42,8 @@ | |||
| 42 | 42 | ||
| 43 | ;;; Code: | 43 | ;;; Code: |
| 44 | 44 | ||
| 45 | (require 'button) | ||
| 46 | |||
| 45 | 47 | ||
| 46 | ;; User Options: | 48 | ;; User Options: |
| 47 | 49 | ||
| @@ -496,7 +498,7 @@ Each element is a pair of strings (ABBREVIATION . EXPANSION)." | |||
| 496 | 498 | ||
| 497 | (defcustom bibtex-string-files nil | 499 | (defcustom bibtex-string-files nil |
| 498 | "*List of BibTeX files containing string definitions. | 500 | "*List of BibTeX files containing string definitions. |
| 499 | Those files must be specified using pathnames relative to the | 501 | List elements can be absolute file names or file names relative to the |
| 500 | directories specified in `bibtex-string-file-path'." | 502 | directories specified in `bibtex-string-file-path'." |
| 501 | :group 'bibtex | 503 | :group 'bibtex |
| 502 | :type '(repeat file)) | 504 | :type '(repeat file)) |
| @@ -504,6 +506,18 @@ directories specified in `bibtex-string-file-path'." | |||
| 504 | (defvar bibtex-string-file-path (getenv "BIBINPUTS") | 506 | (defvar bibtex-string-file-path (getenv "BIBINPUTS") |
| 505 | "*Colon separated list of paths to search for `bibtex-string-files'.") | 507 | "*Colon separated list of paths to search for `bibtex-string-files'.") |
| 506 | 508 | ||
| 509 | (defcustom bibtex-files nil | ||
| 510 | "*List of BibTeX files checked for duplicate keys. | ||
| 511 | List elements can be absolute file names or file names relative to the | ||
| 512 | directories specified in `bibtex-file-path'. If an element is a directory, | ||
| 513 | check all BibTeX files in this directory. If an element is the symbol | ||
| 514 | `bibtex-file-path', check all BibTeX files in `bibtex-file-path'." | ||
| 515 | :group 'bibtex | ||
| 516 | :type '(repeat file)) | ||
| 517 | |||
| 518 | (defvar bibtex-file-path (getenv "BIBINPUTS") | ||
| 519 | "*Colon separated list of paths to search for `bibtex-files'.") | ||
| 520 | |||
| 507 | (defcustom bibtex-help-message t | 521 | (defcustom bibtex-help-message t |
| 508 | "*If non-nil print help messages in the echo area on entering a new field." | 522 | "*If non-nil print help messages in the echo area on entering a new field." |
| 509 | :group 'bibtex | 523 | :group 'bibtex |
| @@ -557,7 +571,7 @@ See `bibtex-generate-autokey' for details." | |||
| 557 | ;; braces, quotes, concatenation. | 571 | ;; braces, quotes, concatenation. |
| 558 | ("[`'\"{}#]" . "") | 572 | ("[`'\"{}#]" . "") |
| 559 | ;; spaces | 573 | ;; spaces |
| 560 | ("[ \t\n]+" . " ")) | 574 | ("\\\\?[ \t\n]+\\|~" . " ")) |
| 561 | "Alist of (OLD-REGEXP . NEW-STRING) pairs. | 575 | "Alist of (OLD-REGEXP . NEW-STRING) pairs. |
| 562 | Used by the default values of `bibtex-autokey-name-change-strings' and | 576 | Used by the default values of `bibtex-autokey-name-change-strings' and |
| 563 | `bibtex-autokey-titleword-change-strings'. Defaults to translating some | 577 | `bibtex-autokey-titleword-change-strings'. Defaults to translating some |
| @@ -756,12 +770,22 @@ If non-nil, the column for the equal sign is the value of | |||
| 756 | 770 | ||
| 757 | (defcustom bibtex-autoadd-commas t | 771 | (defcustom bibtex-autoadd-commas t |
| 758 | "If non-nil automatically add missing commas at end of BibTeX fields." | 772 | "If non-nil automatically add missing commas at end of BibTeX fields." |
| 773 | :group 'bibtex | ||
| 759 | :type 'boolean) | 774 | :type 'boolean) |
| 760 | 775 | ||
| 761 | (defcustom bibtex-autofill-types '("Proceedings") | 776 | (defcustom bibtex-autofill-types '("Proceedings") |
| 762 | "Automatically fill fields if possible for those BibTeX entry types." | 777 | "Automatically fill fields if possible for those BibTeX entry types." |
| 778 | :group 'bibtex | ||
| 763 | :type '(repeat string)) | 779 | :type '(repeat string)) |
| 764 | 780 | ||
| 781 | (defcustom bibtex-summary-function 'bibtex-summary | ||
| 782 | "Function to call for generating a one-line summary of a BibTeX entry. | ||
| 783 | It takes one argument, the key of the entry. | ||
| 784 | Used by `bibtex-complete-key-cleanup' and `bibtex-copy-summary-as-kill'." | ||
| 785 | :group 'bibtex | ||
| 786 | :type '(choice (const :tag "Default" bibtex-summary) | ||
| 787 | (function :tag "Personalized function"))) | ||
| 788 | |||
| 765 | (defcustom bibtex-generate-url-list | 789 | (defcustom bibtex-generate-url-list |
| 766 | '((("url" . ".*:.*")) | 790 | '((("url" . ".*:.*")) |
| 767 | ;; Example of a complex setup. | 791 | ;; Example of a complex setup. |
| @@ -778,7 +802,7 @@ These schemes are used by `bibtex-url'. | |||
| 778 | Each scheme is of the form ((FIELD . REGEXP) STEP...). | 802 | Each scheme is of the form ((FIELD . REGEXP) STEP...). |
| 779 | 803 | ||
| 780 | FIELD is a field name as returned by `bibtex-parse-entry'. | 804 | FIELD is a field name as returned by `bibtex-parse-entry'. |
| 781 | REGEXP is matched against the text of FIELD. If the match succeed, then | 805 | REGEXP is matched against the text of FIELD. If the match succeeds, then |
| 782 | this scheme will be used. If no STEPS are specified the matched text is used | 806 | this scheme will be used. If no STEPS are specified the matched text is used |
| 783 | as the URL, otherwise the URL is built by concatenating the STEPS. | 807 | as the URL, otherwise the URL is built by concatenating the STEPS. |
| 784 | 808 | ||
| @@ -838,6 +862,7 @@ Case is always ignored. Always remove the field delimiters." | |||
| 838 | (define-key km "\C-c\C-c" 'bibtex-clean-entry) | 862 | (define-key km "\C-c\C-c" 'bibtex-clean-entry) |
| 839 | (define-key km "\C-c\C-q" 'bibtex-fill-entry) | 863 | (define-key km "\C-c\C-q" 'bibtex-fill-entry) |
| 840 | (define-key km "\C-c\C-s" 'bibtex-find-entry) | 864 | (define-key km "\C-c\C-s" 'bibtex-find-entry) |
| 865 | (define-key km "\C-c\C-t" 'bibtex-copy-summary-as-kill) | ||
| 841 | (define-key km "\C-c?" 'bibtex-print-help-message) | 866 | (define-key km "\C-c?" 'bibtex-print-help-message) |
| 842 | (define-key km "\C-c\C-p" 'bibtex-pop-previous) | 867 | (define-key km "\C-c\C-p" 'bibtex-pop-previous) |
| 843 | (define-key km "\C-c\C-n" 'bibtex-pop-next) | 868 | (define-key km "\C-c\C-n" 'bibtex-pop-next) |
| @@ -892,7 +917,9 @@ Case is always ignored. Always remove the field delimiters." | |||
| 892 | ("Moving in BibTeX Buffer" | 917 | ("Moving in BibTeX Buffer" |
| 893 | ["Find Entry" bibtex-find-entry t] | 918 | ["Find Entry" bibtex-find-entry t] |
| 894 | ["Find Crossref Entry" bibtex-find-crossref t]) | 919 | ["Find Crossref Entry" bibtex-find-crossref t]) |
| 895 | "--" | 920 | ("Moving between BibTeX Buffers" |
| 921 | ["Find Entry Globally" bibtex-find-entry-globally t]) | ||
| 922 | "--" | ||
| 896 | ("Operating on Current Field" | 923 | ("Operating on Current Field" |
| 897 | ["Fill Field" fill-paragraph t] | 924 | ["Fill Field" fill-paragraph t] |
| 898 | ["Remove Delimiters" bibtex-remove-delimiters t] | 925 | ["Remove Delimiters" bibtex-remove-delimiters t] |
| @@ -922,6 +949,8 @@ Case is always ignored. Always remove the field delimiters." | |||
| 922 | ["Paste Most Recently Killed Entry" bibtex-yank t] | 949 | ["Paste Most Recently Killed Entry" bibtex-yank t] |
| 923 | ["Paste Previously Killed Entry" bibtex-yank-pop t] | 950 | ["Paste Previously Killed Entry" bibtex-yank-pop t] |
| 924 | "--" | 951 | "--" |
| 952 | ["Copy Summary to Kill Ring" bibtex-copy-summary-as-kill t] | ||
| 953 | "--" | ||
| 925 | ["Ispell Entry" bibtex-ispell-entry t] | 954 | ["Ispell Entry" bibtex-ispell-entry t] |
| 926 | ["Ispell Entry Abstract" bibtex-ispell-abstract t] | 955 | ["Ispell Entry Abstract" bibtex-ispell-abstract t] |
| 927 | ["Narrow to Entry" bibtex-narrow-to-entry t] | 956 | ["Narrow to Entry" bibtex-narrow-to-entry t] |
| @@ -934,7 +963,9 @@ Case is always ignored. Always remove the field delimiters." | |||
| 934 | ["Reformat Entries" bibtex-reformat t] | 963 | ["Reformat Entries" bibtex-reformat t] |
| 935 | ["Count Entries" bibtex-count-entries t] | 964 | ["Count Entries" bibtex-count-entries t] |
| 936 | "--" | 965 | "--" |
| 937 | ["Convert Alien Buffer" bibtex-convert-alien t]))) | 966 | ["Convert Alien Buffer" bibtex-convert-alien t]) |
| 967 | ("Operating on Multiple Buffers" | ||
| 968 | ["Validate Entries" bibtex-validate-globally t]))) | ||
| 938 | 969 | ||
| 939 | (easy-menu-define | 970 | (easy-menu-define |
| 940 | bibtex-entry-menu bibtex-mode-map "Entry-Types Menu in BibTeX mode" | 971 | bibtex-entry-menu bibtex-mode-map "Entry-Types Menu in BibTeX mode" |
| @@ -955,13 +986,6 @@ Case is always ignored. Always remove the field delimiters." | |||
| 955 | ["String" bibtex-String t] | 986 | ["String" bibtex-String t] |
| 956 | ["Preamble" bibtex-Preamble t])) | 987 | ["Preamble" bibtex-Preamble t])) |
| 957 | 988 | ||
| 958 | (defvar bibtex-url-map | ||
| 959 | (let ((km (make-sparse-keymap))) | ||
| 960 | (define-key km [(mouse-2)] 'bibtex-url) | ||
| 961 | km) | ||
| 962 | "Local keymap for clickable URLs.") | ||
| 963 | (fset 'bibtex-url-map bibtex-url-map) | ||
| 964 | |||
| 965 | 989 | ||
| 966 | ;; Internal Variables | 990 | ;; Internal Variables |
| 967 | 991 | ||
| @@ -996,8 +1020,9 @@ Initialized from `bibtex-predefined-strings' and `bibtex-string-files'.") | |||
| 996 | (make-variable-buffer-local 'bibtex-strings) | 1020 | (make-variable-buffer-local 'bibtex-strings) |
| 997 | 1021 | ||
| 998 | (defvar bibtex-reference-keys | 1022 | (defvar bibtex-reference-keys |
| 999 | (lazy-completion-table bibtex-reference-keys bibtex-parse-keys nil nil t) | 1023 | (lazy-completion-table bibtex-reference-keys bibtex-parse-keys nil t) |
| 1000 | "Completion table for BibTeX reference keys.") | 1024 | "Completion table for BibTeX reference keys. |
| 1025 | The CDRs of the elements are t for header keys and nil for crossref keys.") | ||
| 1001 | (make-variable-buffer-local 'bibtex-reference-keys) | 1026 | (make-variable-buffer-local 'bibtex-reference-keys) |
| 1002 | 1027 | ||
| 1003 | (defvar bibtex-buffer-last-parsed-tick nil | 1028 | (defvar bibtex-buffer-last-parsed-tick nil |
| @@ -1103,13 +1128,13 @@ Initialized from `bibtex-predefined-strings' and `bibtex-string-files'.") | |||
| 1103 | (,(concat "^[ \t]*\\(" bibtex-field-name "\\)[ \t]*=") | 1128 | (,(concat "^[ \t]*\\(" bibtex-field-name "\\)[ \t]*=") |
| 1104 | 1 font-lock-variable-name-face) | 1129 | 1 font-lock-variable-name-face) |
| 1105 | ;; url | 1130 | ;; url |
| 1106 | (bibtex-font-lock-url 0 '(face nil mouse-face highlight | 1131 | bibtex-font-lock-url bibtex-font-lock-crossref) |
| 1107 | keymap bibtex-url-map))) | ||
| 1108 | "*Default expressions to highlight in BibTeX mode.") | 1132 | "*Default expressions to highlight in BibTeX mode.") |
| 1109 | 1133 | ||
| 1110 | (defvar bibtex-font-lock-url-regexp | 1134 | (defvar bibtex-font-lock-url-regexp |
| 1111 | (concat "\\<" (regexp-opt (mapcar 'caar bibtex-generate-url-list) t) | 1135 | ;; Assume that field names begin at the beginning of a line. |
| 1112 | "\\>[ \t]*=[ \t]*") | 1136 | (concat "^[ \t]*" (regexp-opt (mapcar 'caar bibtex-generate-url-list) t) |
| 1137 | "[ \t]*=[ \t]*") | ||
| 1113 | "Regexp for `bibtex-font-lock-url'.") | 1138 | "Regexp for `bibtex-font-lock-url'.") |
| 1114 | 1139 | ||
| 1115 | (defvar bibtex-field-name-for-parsing nil | 1140 | (defvar bibtex-field-name-for-parsing nil |
| @@ -1128,32 +1153,12 @@ Auto-generated from `bibtex-sort-entry-class'. | |||
| 1128 | Used when `bibtex-maintain-sorted-entries' is `entry-class'.") | 1153 | Used when `bibtex-maintain-sorted-entries' is `entry-class'.") |
| 1129 | 1154 | ||
| 1130 | 1155 | ||
| 1131 | ;; Special support taking care of variants | ||
| 1132 | (defvar zmacs-regions) | ||
| 1133 | (defalias 'bibtex-mark-active | ||
| 1134 | (if (boundp 'mark-active) | ||
| 1135 | ;; In Emacs mark-active indicates if mark is active. | ||
| 1136 | (lambda () mark-active) | ||
| 1137 | ;; In XEmacs (mark) returns nil when not active. | ||
| 1138 | (lambda () (if zmacs-regions (mark) (mark t))))) | ||
| 1139 | |||
| 1140 | (defalias 'bibtex-run-with-idle-timer | ||
| 1141 | (if (fboundp 'run-with-idle-timer) | ||
| 1142 | ;; timer.el is distributed with Emacs | ||
| 1143 | 'run-with-idle-timer | ||
| 1144 | ;; timer.el is not distributed with XEmacs | ||
| 1145 | ;; Notice that this does not (yet) pass the arguments, but they | ||
| 1146 | ;; are not used (yet) in bibtex.el. Fix if needed. | ||
| 1147 | (lambda (secs repeat function &rest args) | ||
| 1148 | (start-itimer "bibtex" function secs (if repeat secs nil) t)))) | ||
| 1149 | |||
| 1150 | |||
| 1151 | ;; Support for hideshow minor mode | 1156 | ;; Support for hideshow minor mode |
| 1152 | (defun bibtex-hs-forward-sexp (arg) | 1157 | (defun bibtex-hs-forward-sexp (arg) |
| 1153 | "Replacement for `forward-sexp' to be used by `hs-minor-mode'. | 1158 | "Replacement for `forward-sexp' to be used by `hs-minor-mode'. |
| 1154 | ARG is ignored." | 1159 | ARG is ignored." |
| 1155 | (if (looking-at "@\\S(*\\s(") | 1160 | (if (looking-at "@\\S(*\\s(") |
| 1156 | (goto-char (1- (match-end 0)))) | 1161 | (goto-char (1- (match-end 0)))) |
| 1157 | (forward-sexp 1)) | 1162 | (forward-sexp 1)) |
| 1158 | 1163 | ||
| 1159 | (add-to-list | 1164 | (add-to-list |
| @@ -1471,12 +1476,10 @@ delimiters if present." | |||
| 1471 | (buffer-substring-no-properties (1+ (match-beginning bibtex-type-in-head)) | 1476 | (buffer-substring-no-properties (1+ (match-beginning bibtex-type-in-head)) |
| 1472 | (match-end bibtex-type-in-head))) | 1477 | (match-end bibtex-type-in-head))) |
| 1473 | 1478 | ||
| 1474 | (defun bibtex-key-in-head (&optional empty) | 1479 | (defsubst bibtex-key-in-head (&optional empty) |
| 1475 | "Extract BibTeX key in head. Return optional arg EMPTY if key is empty." | 1480 | "Extract BibTeX key in head. Return optional arg EMPTY if key is empty." |
| 1476 | (if (match-beginning bibtex-key-in-head) | 1481 | (or (match-string-no-properties bibtex-key-in-head) |
| 1477 | (buffer-substring-no-properties (match-beginning bibtex-key-in-head) | 1482 | empty)) |
| 1478 | (match-end bibtex-key-in-head)) | ||
| 1479 | empty)) | ||
| 1480 | 1483 | ||
| 1481 | ;; Helper Functions | 1484 | ;; Helper Functions |
| 1482 | 1485 | ||
| @@ -1492,7 +1495,7 @@ delimiters if present." | |||
| 1492 | (defun bibtex-current-line () | 1495 | (defun bibtex-current-line () |
| 1493 | "Compute line number of point regardless whether the buffer is narrowed." | 1496 | "Compute line number of point regardless whether the buffer is narrowed." |
| 1494 | (+ (count-lines 1 (point)) | 1497 | (+ (count-lines 1 (point)) |
| 1495 | (if (equal (current-column) 0) 1 0))) | 1498 | (if (bolp) 1 0))) |
| 1496 | 1499 | ||
| 1497 | (defun bibtex-skip-to-valid-entry (&optional backward) | 1500 | (defun bibtex-skip-to-valid-entry (&optional backward) |
| 1498 | "Move point to beginning of the next valid BibTeX entry. | 1501 | "Move point to beginning of the next valid BibTeX entry. |
| @@ -1525,24 +1528,25 @@ entry is found, nil otherwise." | |||
| 1525 | found)) | 1528 | found)) |
| 1526 | 1529 | ||
| 1527 | (defun bibtex-map-entries (fun) | 1530 | (defun bibtex-map-entries (fun) |
| 1528 | "Call FUN for each BibTeX entry starting with the current. | 1531 | "Call FUN for each BibTeX entry in buffer (possibly narrowed). |
| 1529 | Do this to the end of the file. FUN is called with three arguments, the key of | 1532 | FUN is called with three arguments, the key of the entry and the buffer |
| 1530 | the entry and the buffer positions (marker) of beginning and end of entry. | 1533 | positions (marker) of beginning and end of entry. Point is inside the entry. |
| 1531 | Point is inside the entry. If `bibtex-sort-ignore-string-entries' is non-nil, | 1534 | If `bibtex-sort-ignore-string-entries' is non-nil, FUN will not be called for |
| 1532 | FUN will not be called for @String entries." | 1535 | @String entries." |
| 1533 | (let ((case-fold-search t)) | 1536 | (let ((case-fold-search t)) |
| 1534 | (bibtex-beginning-of-entry) | 1537 | (save-excursion |
| 1535 | (while (re-search-forward bibtex-entry-head nil t) | 1538 | (goto-char (point-min)) |
| 1536 | (let ((entry-type (bibtex-type-in-head)) | 1539 | (while (re-search-forward bibtex-entry-head nil t) |
| 1537 | (key (bibtex-key-in-head "")) | 1540 | (let ((entry-type (bibtex-type-in-head)) |
| 1538 | (beg (copy-marker (match-beginning 0))) | 1541 | (key (bibtex-key-in-head "")) |
| 1539 | (end (copy-marker (save-excursion (bibtex-end-of-entry))))) | 1542 | (beg (copy-marker (match-beginning 0))) |
| 1540 | (save-excursion | 1543 | (end (copy-marker (save-excursion (bibtex-end-of-entry))))) |
| 1541 | (if (or (and (not bibtex-sort-ignore-string-entries) | 1544 | (save-excursion |
| 1542 | (bibtex-string= entry-type "string")) | 1545 | (if (or (and (not bibtex-sort-ignore-string-entries) |
| 1543 | (assoc-string entry-type bibtex-entry-field-alist t)) | 1546 | (bibtex-string= entry-type "string")) |
| 1544 | (funcall fun key beg end))) | 1547 | (assoc-string entry-type bibtex-entry-field-alist t)) |
| 1545 | (goto-char end))))) | 1548 | (funcall fun key beg end))) |
| 1549 | (goto-char end)))))) | ||
| 1546 | 1550 | ||
| 1547 | (defun bibtex-progress-message (&optional flag interval) | 1551 | (defun bibtex-progress-message (&optional flag interval) |
| 1548 | "Echo a message about progress of current buffer. | 1552 | "Echo a message about progress of current buffer. |
| @@ -1581,13 +1585,13 @@ If FLAG is nil, a message is echoed if point was incremented at least | |||
| 1581 | "\"")) | 1585 | "\"")) |
| 1582 | 1586 | ||
| 1583 | (defun bibtex-entry-left-delimiter () | 1587 | (defun bibtex-entry-left-delimiter () |
| 1584 | "Return a string dependent on `bibtex-field-delimiters'." | 1588 | "Return a string dependent on `bibtex-entry-delimiters'." |
| 1585 | (if (equal bibtex-entry-delimiters 'braces) | 1589 | (if (equal bibtex-entry-delimiters 'braces) |
| 1586 | "{" | 1590 | "{" |
| 1587 | "(")) | 1591 | "(")) |
| 1588 | 1592 | ||
| 1589 | (defun bibtex-entry-right-delimiter () | 1593 | (defun bibtex-entry-right-delimiter () |
| 1590 | "Return a string dependent on `bibtex-field-delimiters'." | 1594 | "Return a string dependent on `bibtex-entry-delimiters'." |
| 1591 | (if (equal bibtex-entry-delimiters 'braces) | 1595 | (if (equal bibtex-entry-delimiters 'braces) |
| 1592 | "}" | 1596 | "}" |
| 1593 | ")")) | 1597 | ")")) |
| @@ -1641,7 +1645,7 @@ are defined, but only for the head part of the entry | |||
| 1641 | (setq infix-start (bibtex-end-of-field bounds)) | 1645 | (setq infix-start (bibtex-end-of-field bounds)) |
| 1642 | (setq finished t)) | 1646 | (setq finished t)) |
| 1643 | (goto-char infix-start)) | 1647 | (goto-char infix-start)) |
| 1644 | ;; This matches the infix* part. The AND construction assures | 1648 | ;; This matches the infix* part. The AND construction assures |
| 1645 | ;; that BOUND is respected. | 1649 | ;; that BOUND is respected. |
| 1646 | (when (and (looking-at bibtex-entry-postfix) | 1650 | (when (and (looking-at bibtex-entry-postfix) |
| 1647 | (eq (char-before (match-end 0)) entry-closer) | 1651 | (eq (char-before (match-end 0)) entry-closer) |
| @@ -1826,8 +1830,8 @@ Formats current entry according to variable `bibtex-entry-format'." | |||
| 1826 | (cdr field))) | 1830 | (cdr field))) |
| 1827 | (cdr field)) | 1831 | (cdr field)) |
| 1828 | req-field-list (if crossref-key | 1832 | req-field-list (if crossref-key |
| 1829 | (nth 0 (nth 2 entry-list)) ; crossref part | 1833 | (nth 0 (nth 2 entry-list)) ; crossref part |
| 1830 | (nth 0 (nth 1 entry-list)))) ; required part | 1834 | (nth 0 (nth 1 entry-list)))) ; required part |
| 1831 | 1835 | ||
| 1832 | (dolist (rfield req-field-list) | 1836 | (dolist (rfield req-field-list) |
| 1833 | (when (nth 3 rfield) ; we should have an alternative | 1837 | (when (nth 3 rfield) ; we should have an alternative |
| @@ -1864,9 +1868,9 @@ Formats current entry according to variable `bibtex-entry-format'." | |||
| 1864 | deleted) | 1868 | deleted) |
| 1865 | 1869 | ||
| 1866 | ;; We have more elegant high-level functions for several | 1870 | ;; We have more elegant high-level functions for several |
| 1867 | ;; tasks done by bibtex-format-entry. However, they contain | 1871 | ;; tasks done by bibtex-format-entry. However, they contain |
| 1868 | ;; quite some redundancy compared with what we need to do | 1872 | ;; quite some redundancy compared with what we need to do |
| 1869 | ;; anyway. So for speed-up we avoid using them. | 1873 | ;; anyway. So for speed-up we avoid using them. |
| 1870 | 1874 | ||
| 1871 | (if (memq 'opts-or-alts format) | 1875 | (if (memq 'opts-or-alts format) |
| 1872 | (cond ((and empty-field | 1876 | (cond ((and empty-field |
| @@ -1875,8 +1879,8 @@ Formats current entry according to variable `bibtex-entry-format'." | |||
| 1875 | field-name req-field-list t))) | 1879 | field-name req-field-list t))) |
| 1876 | (or (not field) ; OPT field | 1880 | (or (not field) ; OPT field |
| 1877 | (nth 3 field))))) ; ALT field | 1881 | (nth 3 field))))) ; ALT field |
| 1878 | ;; Either it is an empty ALT field. Then we have checked | 1882 | ;; Either it is an empty ALT field. Then we have checked |
| 1879 | ;; already that we have one non-empty alternative. Or it | 1883 | ;; already that we have one non-empty alternative. Or it |
| 1880 | ;; is an empty OPT field that we do not miss anyway. | 1884 | ;; is an empty OPT field that we do not miss anyway. |
| 1881 | ;; So we can safely delete this field. | 1885 | ;; So we can safely delete this field. |
| 1882 | (delete-region beg-field end-field) | 1886 | (delete-region beg-field end-field) |
| @@ -2041,19 +2045,33 @@ applied to the content of FIELD. It is an alist with pairs | |||
| 2041 | (dolist (pattern change-list content) | 2045 | (dolist (pattern change-list content) |
| 2042 | (setq content (replace-regexp-in-string (car pattern) | 2046 | (setq content (replace-regexp-in-string (car pattern) |
| 2043 | (cdr pattern) | 2047 | (cdr pattern) |
| 2044 | content))))) | 2048 | content t))))) |
| 2045 | 2049 | ||
| 2046 | (defun bibtex-autokey-get-names () | 2050 | (defun bibtex-autokey-get-names () |
| 2047 | "Get contents of the name field of the current entry. | 2051 | "Get contents of the name field of the current entry. |
| 2048 | Do some modifications based on `bibtex-autokey-name-change-strings' | 2052 | Do some modifications based on `bibtex-autokey-name-change-strings'. |
| 2049 | and return results as a list." | 2053 | Return the names as a concatenated string obeying `bibtex-autokey-names' |
| 2050 | (let ((case-fold-search t) | 2054 | and `bibtex-autokey-names-stretch'." |
| 2051 | (names (bibtex-autokey-get-field "author\\|editor" | 2055 | (let ((names (bibtex-autokey-get-field "author\\|editor" |
| 2052 | bibtex-autokey-name-change-strings))) | 2056 | bibtex-autokey-name-change-strings))) |
| 2053 | ;; Some entries do not have a name field. | 2057 | ;; Some entries do not have a name field. |
| 2054 | (unless (string= "" names) | 2058 | (unless (string= "" names) |
| 2055 | (mapcar 'bibtex-autokey-demangle-name | 2059 | (let* ((case-fold-search t) |
| 2056 | (split-string names "[ \t\n]+and[ \t\n]+"))))) | 2060 | (name-list (mapcar 'bibtex-autokey-demangle-name |
| 2061 | (split-string names "[ \t\n]+and[ \t\n]+"))) | ||
| 2062 | additional-names) | ||
| 2063 | (unless (or (not (numberp bibtex-autokey-names)) | ||
| 2064 | (<= (length name-list) | ||
| 2065 | (+ bibtex-autokey-names | ||
| 2066 | bibtex-autokey-names-stretch))) | ||
| 2067 | ;; Take bibtex-autokey-names elements from beginning of name-list | ||
| 2068 | (setq name-list (nreverse (nthcdr (- (length name-list) | ||
| 2069 | bibtex-autokey-names) | ||
| 2070 | (nreverse name-list))) | ||
| 2071 | additional-names bibtex-autokey-additional-names)) | ||
| 2072 | (concat (mapconcat 'identity name-list | ||
| 2073 | bibtex-autokey-name-separator) | ||
| 2074 | additional-names))))) | ||
| 2057 | 2075 | ||
| 2058 | (defun bibtex-autokey-demangle-name (fullname) | 2076 | (defun bibtex-autokey-demangle-name (fullname) |
| 2059 | "Get the last part from a well-formed FULLNAME and perform abbreviations." | 2077 | "Get the last part from a well-formed FULLNAME and perform abbreviations." |
| @@ -2082,8 +2100,15 @@ and return results as a list." | |||
| 2082 | (funcall bibtex-autokey-name-case-convert name) | 2100 | (funcall bibtex-autokey-name-case-convert name) |
| 2083 | bibtex-autokey-name-length))) | 2101 | bibtex-autokey-name-length))) |
| 2084 | 2102 | ||
| 2103 | (defun bibtex-autokey-get-year () | ||
| 2104 | "Return year field contents as a string obeying `bibtex-autokey-year-length'." | ||
| 2105 | (let ((yearfield (bibtex-autokey-get-field "year"))) | ||
| 2106 | (substring yearfield (max 0 (- (length yearfield) | ||
| 2107 | bibtex-autokey-year-length))))) | ||
| 2108 | |||
| 2085 | (defun bibtex-autokey-get-title () | 2109 | (defun bibtex-autokey-get-title () |
| 2086 | "Get title field contents up to a terminator." | 2110 | "Get title field contents up to a terminator. |
| 2111 | Return the result as a string" | ||
| 2087 | (let ((case-fold-search t) | 2112 | (let ((case-fold-search t) |
| 2088 | (titlestring | 2113 | (titlestring |
| 2089 | (bibtex-autokey-get-field "title" | 2114 | (bibtex-autokey-get-field "title" |
| @@ -2092,35 +2117,37 @@ and return results as a list." | |||
| 2092 | (dolist (terminator bibtex-autokey-title-terminators) | 2117 | (dolist (terminator bibtex-autokey-title-terminators) |
| 2093 | (if (string-match terminator titlestring) | 2118 | (if (string-match terminator titlestring) |
| 2094 | (setq titlestring (substring titlestring 0 (match-beginning 0))))) | 2119 | (setq titlestring (substring titlestring 0 (match-beginning 0))))) |
| 2095 | ;; gather words from titlestring into a list. Ignore | 2120 | ;; gather words from titlestring into a list. Ignore |
| 2096 | ;; specific words and use only a specific amount of words. | 2121 | ;; specific words and use only a specific amount of words. |
| 2097 | (let ((counter 0) | 2122 | (let ((counter 0) |
| 2098 | titlewords titlewords-extra titleword end-match) | 2123 | titlewords titlewords-extra word) |
| 2099 | (while (and (or (not (numberp bibtex-autokey-titlewords)) | 2124 | (while (and (or (not (numberp bibtex-autokey-titlewords)) |
| 2100 | (< counter (+ bibtex-autokey-titlewords | 2125 | (< counter (+ bibtex-autokey-titlewords |
| 2101 | bibtex-autokey-titlewords-stretch))) | 2126 | bibtex-autokey-titlewords-stretch))) |
| 2102 | (string-match "\\b\\w+" titlestring)) | 2127 | (string-match "\\b\\w+" titlestring)) |
| 2103 | (setq end-match (match-end 0) | 2128 | (setq word (match-string 0 titlestring) |
| 2104 | titleword (substring titlestring | 2129 | titlestring (substring titlestring (match-end 0))) |
| 2105 | (match-beginning 0) end-match)) | 2130 | ;; Ignore words matched by one of the elements of |
| 2131 | ;; bibtex-autokey-titleword-ignore | ||
| 2106 | (unless (let ((lst bibtex-autokey-titleword-ignore)) | 2132 | (unless (let ((lst bibtex-autokey-titleword-ignore)) |
| 2107 | (while (and lst | 2133 | (while (and lst |
| 2108 | (not (string-match (concat "\\`\\(?:" (car lst) | 2134 | (not (string-match (concat "\\`\\(?:" (car lst) |
| 2109 | "\\)\\'") titleword))) | 2135 | "\\)\\'") word))) |
| 2110 | (setq lst (cdr lst))) | 2136 | (setq lst (cdr lst))) |
| 2111 | lst) | 2137 | lst) |
| 2112 | (setq titleword | 2138 | (setq word (funcall bibtex-autokey-titleword-case-convert word) |
| 2113 | (funcall bibtex-autokey-titleword-case-convert titleword)) | 2139 | counter (1+ counter)) |
| 2114 | (if (or (not (numberp bibtex-autokey-titlewords)) | 2140 | (if (or (not (numberp bibtex-autokey-titlewords)) |
| 2115 | (< counter bibtex-autokey-titlewords)) | 2141 | (< counter bibtex-autokey-titlewords)) |
| 2116 | (setq titlewords (append titlewords (list titleword))) | 2142 | (push word titlewords) |
| 2117 | (setq titlewords-extra | 2143 | (push word titlewords-extra)))) |
| 2118 | (append titlewords-extra (list titleword)))) | 2144 | ;; Obey bibtex-autokey-titlewords-stretch: |
| 2119 | (setq counter (1+ counter))) | 2145 | ;; If by now we have processed all words in titlestring, we include |
| 2120 | (setq titlestring (substring titlestring end-match))) | 2146 | ;; titlewords-extra in titlewords. Otherwise, we ignore titlewords-extra. |
| 2121 | (unless (string-match "\\b\\w+" titlestring) | 2147 | (unless (string-match "\\b\\w+" titlestring) |
| 2122 | (setq titlewords (append titlewords titlewords-extra))) | 2148 | (setq titlewords (append titlewords-extra titlewords))) |
| 2123 | (mapcar 'bibtex-autokey-demangle-title titlewords)))) | 2149 | (mapconcat 'bibtex-autokey-demangle-title (nreverse titlewords) |
| 2150 | bibtex-autokey-titleword-separator)))) | ||
| 2124 | 2151 | ||
| 2125 | (defun bibtex-autokey-demangle-title (titleword) | 2152 | (defun bibtex-autokey-demangle-title (titleword) |
| 2126 | "Do some abbreviations on TITLEWORD. | 2153 | "Do some abbreviations on TITLEWORD. |
| @@ -2211,65 +2238,36 @@ The generation algorithm works as follows: | |||
| 2211 | the key is then presented in the minibuffer to the user, | 2238 | the key is then presented in the minibuffer to the user, |
| 2212 | where it can be edited. The key given by the user is then | 2239 | where it can be edited. The key given by the user is then |
| 2213 | used." | 2240 | used." |
| 2214 | (let* ((name-etal "") | 2241 | (let* ((names (bibtex-autokey-get-names)) |
| 2215 | (namelist | 2242 | (year (bibtex-autokey-get-year)) |
| 2216 | (let ((nl (bibtex-autokey-get-names)) | 2243 | (title (bibtex-autokey-get-title)) |
| 2217 | nnl) | ||
| 2218 | (if (or (not (numberp bibtex-autokey-names)) | ||
| 2219 | (<= (length nl) | ||
| 2220 | (+ bibtex-autokey-names | ||
| 2221 | bibtex-autokey-names-stretch))) | ||
| 2222 | nl | ||
| 2223 | (setq name-etal bibtex-autokey-additional-names) | ||
| 2224 | (while (< (length nnl) bibtex-autokey-names) | ||
| 2225 | (setq nnl (append nnl (list (car nl))) | ||
| 2226 | nl (cdr nl))) | ||
| 2227 | nnl))) | ||
| 2228 | (namepart (concat (mapconcat 'identity | ||
| 2229 | namelist | ||
| 2230 | bibtex-autokey-name-separator) | ||
| 2231 | name-etal)) | ||
| 2232 | (yearfield (bibtex-autokey-get-field "year")) | ||
| 2233 | (yearpart (if (equal yearfield "") | ||
| 2234 | "" | ||
| 2235 | (substring yearfield | ||
| 2236 | (- (length yearfield) | ||
| 2237 | bibtex-autokey-year-length)))) | ||
| 2238 | (titlepart (mapconcat 'identity | ||
| 2239 | (bibtex-autokey-get-title) | ||
| 2240 | bibtex-autokey-titleword-separator)) | ||
| 2241 | (autokey (concat bibtex-autokey-prefix-string | 2244 | (autokey (concat bibtex-autokey-prefix-string |
| 2242 | namepart | 2245 | names |
| 2243 | (unless (or (equal namepart "") | 2246 | (unless (or (equal names "") |
| 2244 | (equal yearpart "")) | 2247 | (equal year "")) |
| 2245 | bibtex-autokey-name-year-separator) | 2248 | bibtex-autokey-name-year-separator) |
| 2246 | yearpart | 2249 | year |
| 2247 | (unless (or (and (equal namepart "") | 2250 | (unless (or (and (equal names "") |
| 2248 | (equal yearpart "")) | 2251 | (equal year "")) |
| 2249 | (equal titlepart "")) | 2252 | (equal title "")) |
| 2250 | bibtex-autokey-year-title-separator) | 2253 | bibtex-autokey-year-title-separator) |
| 2251 | titlepart))) | 2254 | title))) |
| 2252 | (if bibtex-autokey-before-presentation-function | 2255 | (if bibtex-autokey-before-presentation-function |
| 2253 | (funcall bibtex-autokey-before-presentation-function autokey) | 2256 | (funcall bibtex-autokey-before-presentation-function autokey) |
| 2254 | autokey))) | 2257 | autokey))) |
| 2255 | 2258 | ||
| 2256 | 2259 | ||
| 2257 | (defun bibtex-parse-keys (&optional add abortable verbose) | 2260 | (defun bibtex-read-key (prompt &optional key) |
| 2261 | "Read BibTeX key from minibuffer using PROMPT and default KEY." | ||
| 2262 | (completing-read prompt bibtex-reference-keys | ||
| 2263 | nil nil key 'bibtex-key-history)) | ||
| 2264 | |||
| 2265 | (defun bibtex-parse-keys (&optional abortable verbose) | ||
| 2258 | "Set `bibtex-reference-keys' to the keys used in the whole buffer. | 2266 | "Set `bibtex-reference-keys' to the keys used in the whole buffer. |
| 2259 | The buffer might possibly be restricted. | 2267 | Find both entry keys and crossref entries. If ABORTABLE is non-nil abort on |
| 2260 | Find both entry keys and crossref entries. | 2268 | user input. If VERBOSE is non-nil gives messages about progress. Return alist |
| 2261 | If ADD is non-nil add the new keys to `bibtex-reference-keys' instead of | 2269 | of keys if parsing was completed, `aborted' otherwise." |
| 2262 | simply resetting it. If ADD is an alist of keys, also add ADD to | 2270 | (let (ref-keys crossref-keys) |
| 2263 | `bibtex-reference-keys'. If ABORTABLE is non-nil abort on user | ||
| 2264 | input. If VERBOSE is non-nil gives messages about progress. | ||
| 2265 | Return alist of keys if parsing was completed, `aborted' otherwise." | ||
| 2266 | (let ((reference-keys (if (and add | ||
| 2267 | (listp bibtex-reference-keys)) | ||
| 2268 | bibtex-reference-keys))) | ||
| 2269 | (if (listp add) | ||
| 2270 | (dolist (key add) | ||
| 2271 | (unless (assoc (car key) reference-keys) | ||
| 2272 | (push key reference-keys)))) | ||
| 2273 | (save-excursion | 2271 | (save-excursion |
| 2274 | (save-match-data | 2272 | (save-match-data |
| 2275 | (if verbose | 2273 | (if verbose |
| @@ -2286,22 +2284,24 @@ Return alist of keys if parsing was completed, `aborted' otherwise." | |||
| 2286 | (if (and abortable (input-pending-p)) | 2284 | (if (and abortable (input-pending-p)) |
| 2287 | ;; user has aborted by typing a key --> return `aborted' | 2285 | ;; user has aborted by typing a key --> return `aborted' |
| 2288 | (throw 'userkey 'aborted)) | 2286 | (throw 'userkey 'aborted)) |
| 2289 | (let ((key (cond ((match-end 3) | 2287 | (cond ((match-end 3) |
| 2290 | ;; This is a crossref. | 2288 | ;; This is a crossref. |
| 2291 | (buffer-substring-no-properties | 2289 | (let ((key (buffer-substring-no-properties |
| 2292 | (1+ (match-beginning 3)) (1- (match-end 3)))) | 2290 | (1+ (match-beginning 3)) (1- (match-end 3))))) |
| 2293 | ((assoc-string (bibtex-type-in-head) | 2291 | (unless (assoc key crossref-keys) |
| 2294 | bibtex-entry-field-alist t) | 2292 | (push (list key) crossref-keys)))) |
| 2295 | ;; This is an entry. | 2293 | ;; only keys of known entries |
| 2296 | (match-string-no-properties bibtex-key-in-head))))) | 2294 | ((assoc-string (bibtex-type-in-head) |
| 2297 | (if (and (stringp key) | 2295 | bibtex-entry-field-alist t) |
| 2298 | (not (assoc key reference-keys))) | 2296 | ;; This is an entry. |
| 2299 | (push (list key) reference-keys))))) | 2297 | (let ((key (bibtex-key-in-head))) |
| 2298 | (unless (assoc key ref-keys) | ||
| 2299 | (push (cons key t) ref-keys))))))) | ||
| 2300 | 2300 | ||
| 2301 | (let (;; ignore @String entries because they are handled | 2301 | (let (;; ignore @String entries because they are handled |
| 2302 | ;; separately by bibtex-parse-strings | 2302 | ;; separately by bibtex-parse-strings |
| 2303 | (bibtex-sort-ignore-string-entries t) | 2303 | (bibtex-sort-ignore-string-entries t) |
| 2304 | crossref-key bounds) | 2304 | bounds) |
| 2305 | (bibtex-map-entries | 2305 | (bibtex-map-entries |
| 2306 | (lambda (key beg end) | 2306 | (lambda (key beg end) |
| 2307 | (if (and abortable | 2307 | (if (and abortable |
| @@ -2309,17 +2309,19 @@ Return alist of keys if parsing was completed, `aborted' otherwise." | |||
| 2309 | ;; user has aborted by typing a key --> return `aborted' | 2309 | ;; user has aborted by typing a key --> return `aborted' |
| 2310 | (throw 'userkey 'aborted)) | 2310 | (throw 'userkey 'aborted)) |
| 2311 | (if verbose (bibtex-progress-message)) | 2311 | (if verbose (bibtex-progress-message)) |
| 2312 | (unless (assoc key reference-keys) | 2312 | (unless (assoc key ref-keys) |
| 2313 | (push (list key) reference-keys)) | 2313 | (push (cons key t) ref-keys)) |
| 2314 | (if (and (setq bounds (bibtex-search-forward-field "crossref" end)) | 2314 | (if (and (setq bounds (bibtex-search-forward-field "crossref" end)) |
| 2315 | (setq crossref-key (bibtex-text-in-field-bounds bounds t)) | 2315 | (setq key (bibtex-text-in-field-bounds bounds t)) |
| 2316 | (not (assoc crossref-key reference-keys))) | 2316 | (not (assoc key crossref-keys))) |
| 2317 | (push (list crossref-key) reference-keys)))))) | 2317 | (push (list key) crossref-keys)))))) |
| 2318 | 2318 | ||
| 2319 | (dolist (key crossref-keys) | ||
| 2320 | (unless (assoc (car key) ref-keys) (push key ref-keys))) | ||
| 2319 | (if verbose | 2321 | (if verbose |
| 2320 | (bibtex-progress-message 'done)) | 2322 | (bibtex-progress-message 'done)) |
| 2321 | ;; successful operation --> return `bibtex-reference-keys' | 2323 | ;; successful operation --> return `bibtex-reference-keys' |
| 2322 | (setq bibtex-reference-keys reference-keys)))))) | 2324 | (setq bibtex-reference-keys ref-keys)))))) |
| 2323 | 2325 | ||
| 2324 | (defun bibtex-parse-strings (&optional add abortable) | 2326 | (defun bibtex-parse-strings (&optional add abortable) |
| 2325 | "Set `bibtex-strings' to the string definitions in the whole buffer. | 2327 | "Set `bibtex-strings' to the string definitions in the whole buffer. |
| @@ -2355,39 +2357,44 @@ Return alist of strings if parsing was completed, `aborted' otherwise." | |||
| 2355 | 2357 | ||
| 2356 | (defun bibtex-string-files-init () | 2358 | (defun bibtex-string-files-init () |
| 2357 | "Return initialization for `bibtex-strings'. | 2359 | "Return initialization for `bibtex-strings'. |
| 2358 | Use `bibtex-predefined-strings' and bib files `bibtex-string-files'." | 2360 | Use `bibtex-predefined-strings' and BibTeX files `bibtex-string-files'." |
| 2359 | (save-match-data | 2361 | (save-match-data |
| 2360 | ;; collect pathnames | 2362 | (let ((dirlist (split-string (or bibtex-string-file-path default-directory) |
| 2361 | (let ((dirlist (split-string (or bibtex-string-file-path ".") | ||
| 2362 | ":+")) | 2363 | ":+")) |
| 2363 | (case-fold-search) | 2364 | (case-fold-search) |
| 2364 | compl) | 2365 | string-files fullfilename compl bounds found) |
| 2366 | ;; collect absolute file names of valid string files | ||
| 2365 | (dolist (filename bibtex-string-files) | 2367 | (dolist (filename bibtex-string-files) |
| 2366 | (unless (string-match "\\.bib\\'" filename) | 2368 | (unless (string-match "\\.bib\\'" filename) |
| 2367 | (setq filename (concat filename ".bib"))) | 2369 | (setq filename (concat filename ".bib"))) |
| 2368 | ;; test filenames | 2370 | ;; test filenames |
| 2369 | (let (fullfilename bounds found) | 2371 | (if (file-name-absolute-p filename) |
| 2372 | (if (file-readable-p filename) | ||
| 2373 | (push filename string-files) | ||
| 2374 | (error "BibTeX strings file %s not found" filename)) | ||
| 2370 | (dolist (dir dirlist) | 2375 | (dolist (dir dirlist) |
| 2371 | (when (file-readable-p | 2376 | (when (file-readable-p |
| 2372 | (setq fullfilename (expand-file-name filename dir))) | 2377 | (setq fullfilename (expand-file-name filename dir))) |
| 2373 | ;; file was found | 2378 | (push fullfilename string-files) |
| 2374 | (with-temp-buffer | ||
| 2375 | (insert-file-contents fullfilename) | ||
| 2376 | (goto-char (point-min)) | ||
| 2377 | (while (setq bounds (bibtex-search-forward-string)) | ||
| 2378 | (push (cons (bibtex-reference-key-in-string bounds) | ||
| 2379 | (bibtex-text-in-string bounds t)) | ||
| 2380 | compl) | ||
| 2381 | (goto-char (bibtex-end-of-string bounds)))) | ||
| 2382 | (setq found t))) | 2379 | (setq found t))) |
| 2383 | (unless found | 2380 | (unless found |
| 2384 | (error "File %s not in paths defined via bibtex-string-file-path" | 2381 | (error "File %s not in paths defined via bibtex-string-file-path" |
| 2385 | filename)))) | 2382 | filename)))) |
| 2383 | ;; parse string files | ||
| 2384 | (dolist (filename string-files) | ||
| 2385 | (with-temp-buffer | ||
| 2386 | (insert-file-contents filename) | ||
| 2387 | (goto-char (point-min)) | ||
| 2388 | (while (setq bounds (bibtex-search-forward-string)) | ||
| 2389 | (push (cons (bibtex-reference-key-in-string bounds) | ||
| 2390 | (bibtex-text-in-string bounds t)) | ||
| 2391 | compl) | ||
| 2392 | (goto-char (bibtex-end-of-string bounds))))) | ||
| 2386 | (append bibtex-predefined-strings (nreverse compl))))) | 2393 | (append bibtex-predefined-strings (nreverse compl))))) |
| 2387 | 2394 | ||
| 2388 | (defun bibtex-parse-buffers-stealthily () | 2395 | (defun bibtex-parse-buffers-stealthily () |
| 2389 | "Parse buffer in the background during idle time. | 2396 | "Parse buffer in the background during idle time. |
| 2390 | Called by `bibtex-run-with-idle-timer'. Whenever Emacs has been idle | 2397 | Called by `run-with-idle-timer'. Whenever Emacs has been idle |
| 2391 | for `bibtex-parse-keys-timeout' seconds, all BibTeX buffers (starting | 2398 | for `bibtex-parse-keys-timeout' seconds, all BibTeX buffers (starting |
| 2392 | with the current) are parsed." | 2399 | with the current) are parsed." |
| 2393 | (save-excursion | 2400 | (save-excursion |
| @@ -2402,7 +2409,7 @@ with the current) are parsed." | |||
| 2402 | (widen) | 2409 | (widen) |
| 2403 | ;; Output no progress messages in bibtex-parse-keys | 2410 | ;; Output no progress messages in bibtex-parse-keys |
| 2404 | ;; because when in y-or-n-p that can hide the question. | 2411 | ;; because when in y-or-n-p that can hide the question. |
| 2405 | (if (and (listp (bibtex-parse-keys nil t)) | 2412 | (if (and (listp (bibtex-parse-keys t)) |
| 2406 | ;; update bibtex-strings | 2413 | ;; update bibtex-strings |
| 2407 | (listp (bibtex-parse-strings strings-init t))) | 2414 | (listp (bibtex-parse-strings strings-init t))) |
| 2408 | 2415 | ||
| @@ -2410,6 +2417,51 @@ with the current) are parsed." | |||
| 2410 | (setq bibtex-buffer-last-parsed-tick (buffer-modified-tick))))) | 2417 | (setq bibtex-buffer-last-parsed-tick (buffer-modified-tick))))) |
| 2411 | (setq buffers (cdr buffers)))))) | 2418 | (setq buffers (cdr buffers)))))) |
| 2412 | 2419 | ||
| 2420 | (defun bibtex-files-expand (&optional current) | ||
| 2421 | "Return an expanded list of BibTeX buffers based on `bibtex-files'. | ||
| 2422 | Initialize in these buffers `bibtex-reference-keys' if not yet set. | ||
| 2423 | List includes current buffer if CURRENT is non-nil." | ||
| 2424 | (let ((file-path (split-string (or bibtex-file-path default-directory) ":+")) | ||
| 2425 | file-list dir-list buffer-list) | ||
| 2426 | (dolist (file bibtex-files) | ||
| 2427 | (cond ((eq file 'bibtex-file-path) | ||
| 2428 | (setq dir-list (append dir-list file-path))) | ||
| 2429 | ((file-accessible-directory-p file) | ||
| 2430 | (push file dir-list)) | ||
| 2431 | ((progn (unless (string-match "\\.bib\\'" file) | ||
| 2432 | (setq file (concat file ".bib"))) | ||
| 2433 | (file-name-absolute-p file)) | ||
| 2434 | (push file file-list)) | ||
| 2435 | (t | ||
| 2436 | (let (fullfilename found) | ||
| 2437 | (dolist (dir file-path) | ||
| 2438 | (when (file-readable-p | ||
| 2439 | (setq fullfilename (expand-file-name file dir))) | ||
| 2440 | (push fullfilename file-list) | ||
| 2441 | (setq found t))) | ||
| 2442 | (unless found | ||
| 2443 | (error "File %s not in paths defined via bibtex-file-path" | ||
| 2444 | file)))))) | ||
| 2445 | (dolist (file file-list) | ||
| 2446 | (unless (file-readable-p file) | ||
| 2447 | (error "BibTeX file %s not found" file))) | ||
| 2448 | ;; expand dir-list | ||
| 2449 | (dolist (dir dir-list) | ||
| 2450 | (setq file-list | ||
| 2451 | (append file-list (directory-files dir t "\\.bib\\'" t)))) | ||
| 2452 | (delete-dups file-list) | ||
| 2453 | (dolist (file file-list) | ||
| 2454 | (when (file-readable-p file) | ||
| 2455 | (push (find-file-noselect file) buffer-list) | ||
| 2456 | (with-current-buffer (car buffer-list) | ||
| 2457 | (unless (listp bibtex-reference-keys) | ||
| 2458 | (bibtex-parse-keys))))) | ||
| 2459 | (cond ((and current (not (memq (current-buffer) buffer-list))) | ||
| 2460 | (push (current-buffer) buffer-list)) | ||
| 2461 | ((and (not current) (memq (current-buffer) buffer-list)) | ||
| 2462 | (setq buffer-list (delq (current-buffer) buffer-list)))) | ||
| 2463 | buffer-list)) | ||
| 2464 | |||
| 2413 | (defun bibtex-complete-internal (completions) | 2465 | (defun bibtex-complete-internal (completions) |
| 2414 | "Complete word fragment before point to longest prefix of COMPLETIONS. | 2466 | "Complete word fragment before point to longest prefix of COMPLETIONS. |
| 2415 | COMPLETIONS should be a list of strings. If point is not after the part | 2467 | COMPLETIONS should be a list of strings. If point is not after the part |
| @@ -2459,58 +2511,59 @@ expansion of STR using expansion list STRINGS-ALIST." | |||
| 2459 | (bibtex-remove-delimiters)))))))) | 2511 | (bibtex-remove-delimiters)))))))) |
| 2460 | 2512 | ||
| 2461 | (defun bibtex-complete-key-cleanup (key) | 2513 | (defun bibtex-complete-key-cleanup (key) |
| 2462 | "Display message on entry KEY after completion of a crossref key." | 2514 | "Display summary message on entry KEY after completion of a crossref key. |
| 2515 | Use `bibtex-summary-function' to generate summary." | ||
| 2463 | (save-excursion | 2516 | (save-excursion |
| 2464 | ;; Don't do anything if we completed the key of an entry. | 2517 | ;; Don't do anything if we completed the key of an entry. |
| 2465 | (let ((pnt (bibtex-beginning-of-entry))) | 2518 | (let ((pnt (bibtex-beginning-of-entry))) |
| 2466 | (if (and (stringp key) | 2519 | (if (and (stringp key) |
| 2467 | (bibtex-find-entry key) | 2520 | (bibtex-find-entry key) |
| 2468 | (/= pnt (point))) | 2521 | (/= pnt (point))) |
| 2469 | (let* ((bibtex-autokey-name-case-convert 'identity) | 2522 | (message "Ref: %s" (funcall bibtex-summary-function key)))))) |
| 2470 | (bibtex-autokey-name-length 'infty) | 2523 | |
| 2471 | (nl (bibtex-autokey-get-names)) | 2524 | (defun bibtex-copy-summary-as-kill (key) |
| 2472 | (name (concat (nth 0 nl) (if (nth 1 nl) " etal"))) | 2525 | "Push summery of BibTeX entry KEY to kill ring. |
| 2473 | (year (bibtex-autokey-get-field "year")) | 2526 | Use `bibtex-summary-function' to generate summary." |
| 2474 | (bibtex-autokey-titlewords 5) | 2527 | (interactive |
| 2475 | (bibtex-autokey-titlewords-stretch 2) | 2528 | (list (bibtex-read-key |
| 2476 | (bibtex-autokey-titleword-case-convert 'identity) | 2529 | "Key: " (save-excursion |
| 2477 | (bibtex-autokey-titleword-length 5) | 2530 | (bibtex-beginning-of-entry) |
| 2478 | (title (mapconcat 'identity | 2531 | (when (re-search-forward bibtex-entry-head nil t) |
| 2479 | (bibtex-autokey-get-title) " ")) | 2532 | (bibtex-key-in-head)))))) |
| 2480 | (journal (bibtex-autokey-get-field | 2533 | (kill-new (message "%s" (funcall bibtex-summary-function key)))) |
| 2481 | "journal" bibtex-autokey-transcriptions)) | 2534 | |
| 2482 | (volume (bibtex-autokey-get-field "volume")) | 2535 | (defun bibtex-summary (key) |
| 2483 | (pages (bibtex-autokey-get-field "pages" '(("-.*\\'" . ""))))) | 2536 | "Return summary of BibTeX entry KEY. |
| 2484 | (message "Ref:%s" | 2537 | Used as default value of `bibtex-summary-function'." |
| 2485 | (mapconcat (lambda (arg) | 2538 | ;; It would be neat to customize this function. How? |
| 2486 | (if (not (string= "" (cdr arg))) | 2539 | (save-excursion |
| 2487 | (concat (car arg) (cdr arg)))) | 2540 | (if (bibtex-find-entry key) |
| 2488 | `((" " . ,name) (" " . ,year) | 2541 | (let* ((bibtex-autokey-name-case-convert 'identity) |
| 2489 | (": " . ,title) (", " . ,journal) | 2542 | (bibtex-autokey-name-length 'infty) |
| 2490 | (" " . ,volume) (":" . ,pages)) | 2543 | (bibtex-autokey-names 1) |
| 2491 | ""))))))) | 2544 | (bibtex-autokey-names-stretch 0) |
| 2492 | 2545 | (bibtex-autokey-name-separator " ") | |
| 2493 | (defun bibtex-choose-completion-string (choice buffer mini-p base-size) | 2546 | (bibtex-autokey-additional-names " etal") |
| 2494 | ;; Code borrowed from choose-completion-string: | 2547 | (names (bibtex-autokey-get-names)) |
| 2495 | ;; We must duplicate the code from choose-completion-string | 2548 | (bibtex-autokey-year-length 4) |
| 2496 | ;; because it runs the hook choose-completion-string-functions | 2549 | (year (bibtex-autokey-get-year)) |
| 2497 | ;; before it inserts the completion. But we want to do something | 2550 | (bibtex-autokey-titlewords 5) |
| 2498 | ;; after the completion has been inserted. | 2551 | (bibtex-autokey-titlewords-stretch 2) |
| 2499 | ;; | 2552 | (bibtex-autokey-titleword-case-convert 'identity) |
| 2500 | ;; Insert the completion into the buffer where it was requested. | 2553 | (bibtex-autokey-titleword-length 5) |
| 2501 | (set-buffer buffer) | 2554 | (bibtex-autokey-titleword-separator " ") |
| 2502 | (if base-size | 2555 | (title (bibtex-autokey-get-title)) |
| 2503 | (delete-region (+ base-size (point-min)) | 2556 | (journal (bibtex-autokey-get-field |
| 2504 | (point)) | 2557 | "journal" bibtex-autokey-transcriptions)) |
| 2505 | ;; Delete the longest partial match for CHOICE | 2558 | (volume (bibtex-autokey-get-field "volume")) |
| 2506 | ;; that can be found before point. | 2559 | (pages (bibtex-autokey-get-field "pages" '(("-.*\\'" . ""))))) |
| 2507 | (choose-completion-delete-max-match choice)) | 2560 | (mapconcat (lambda (arg) |
| 2508 | (insert choice) | 2561 | (if (not (string= "" (cdr arg))) |
| 2509 | (remove-text-properties (- (point) (length choice)) (point) | 2562 | (concat (car arg) (cdr arg)))) |
| 2510 | '(mouse-face nil)) | 2563 | `((" " . ,names) (" " . ,year) (": " . ,title) |
| 2511 | ;; Update point in the window that BUFFER is showing in. | 2564 | (", " . ,journal) (" " . ,volume) (":" . ,pages)) |
| 2512 | (let ((window (get-buffer-window buffer t))) | 2565 | "")) |
| 2513 | (set-window-point window (point)))) | 2566 | (error "Key `%s' not found." key)))) |
| 2514 | 2567 | ||
| 2515 | (defun bibtex-pop (arg direction) | 2568 | (defun bibtex-pop (arg direction) |
| 2516 | "Fill current field from the ARG'th same field's text in DIRECTION. | 2569 | "Fill current field from the ARG'th same field's text in DIRECTION. |
| @@ -2550,7 +2603,7 @@ Generic function used by `bibtex-pop-previous' and `bibtex-pop-next'." | |||
| 2550 | (if failure | 2603 | (if failure |
| 2551 | (error "No %s matching BibTeX field" | 2604 | (error "No %s matching BibTeX field" |
| 2552 | (if (eq direction 'previous) "previous" "next")) | 2605 | (if (eq direction 'previous) "previous" "next")) |
| 2553 | ;; Found a matching field. Remember boundaries. | 2606 | ;; Found a matching field. Remember boundaries. |
| 2554 | (setq bibtex-pop-previous-search-point (bibtex-start-of-field bounds) | 2607 | (setq bibtex-pop-previous-search-point (bibtex-start-of-field bounds) |
| 2555 | bibtex-pop-next-search-point (bibtex-end-of-field bounds) | 2608 | bibtex-pop-next-search-point (bibtex-end-of-field bounds) |
| 2556 | new-text (bibtex-text-in-field-bounds bounds)) | 2609 | new-text (bibtex-text-in-field-bounds bounds)) |
| @@ -2563,10 +2616,82 @@ Generic function used by `bibtex-pop-previous' and `bibtex-pop-next'." | |||
| 2563 | (bibtex-find-text nil)) | 2616 | (bibtex-find-text nil)) |
| 2564 | (setq this-command 'bibtex-pop)) | 2617 | (setq this-command 'bibtex-pop)) |
| 2565 | 2618 | ||
| 2566 | (defsubst bibtex-read-key (prompt &optional key) | 2619 | (defun bibtex-beginning-of-field () |
| 2567 | "Read BibTeX key from minibuffer using PROMPT and default KEY." | 2620 | "Move point backward to beginning of field. |
| 2568 | (completing-read prompt bibtex-reference-keys | 2621 | This function uses a simple, fast algorithm assuming that the field |
| 2569 | nil nil key 'bibtex-key-history)) | 2622 | begins at the beginning of a line. We use this function for font-locking." |
| 2623 | (let ((field-reg (concat "^[ \t]*" bibtex-field-name "[ \t]*="))) | ||
| 2624 | (beginning-of-line) | ||
| 2625 | (unless (looking-at field-reg) | ||
| 2626 | (re-search-backward field-reg nil t)))) | ||
| 2627 | |||
| 2628 | (defun bibtex-font-lock-url (bound) | ||
| 2629 | "Font-lock for URLs." | ||
| 2630 | (let ((case-fold-search t) | ||
| 2631 | (pnt (point)) | ||
| 2632 | field bounds start end found) | ||
| 2633 | (bibtex-beginning-of-field) | ||
| 2634 | (while (and (not found) | ||
| 2635 | (prog1 (re-search-forward bibtex-font-lock-url-regexp bound t) | ||
| 2636 | (setq field (match-string-no-properties 1))) | ||
| 2637 | (setq bounds (bibtex-parse-field-text)) | ||
| 2638 | (progn | ||
| 2639 | (setq start (car bounds) end (cdr bounds)) | ||
| 2640 | ;; Always ignore field delimiters | ||
| 2641 | (if (memq (char-before end) '(?\} ?\")) | ||
| 2642 | (setq end (1- end))) | ||
| 2643 | (if (memq (char-after start) '(?\{ ?\")) | ||
| 2644 | (setq start (1+ start))) | ||
| 2645 | (>= bound start))) | ||
| 2646 | (let ((lst bibtex-generate-url-list) url) | ||
| 2647 | (goto-char start) | ||
| 2648 | (while (and (not found) | ||
| 2649 | (setq url (caar lst))) | ||
| 2650 | (setq found (and (bibtex-string= field (car url)) | ||
| 2651 | (re-search-forward (cdr url) end t) | ||
| 2652 | (>= (match-beginning 0) pnt)) | ||
| 2653 | lst (cdr lst)))) | ||
| 2654 | (goto-char end)) | ||
| 2655 | (if found (bibtex-button (match-beginning 0) (match-end 0) | ||
| 2656 | 'bibtex-url (match-beginning 0))) | ||
| 2657 | found)) | ||
| 2658 | |||
| 2659 | (defun bibtex-font-lock-crossref (bound) | ||
| 2660 | "Font-lock for crossref fields." | ||
| 2661 | (let ((case-fold-search t) | ||
| 2662 | (pnt (point)) | ||
| 2663 | (crossref-reg (concat "^[ \t]*crossref[ \t]*=[ \t\n]*" | ||
| 2664 | "\\(\"[^\"]*\"\\|{[^}]*}\\)[ \t\n]*[,})]")) | ||
| 2665 | start end found) | ||
| 2666 | (bibtex-beginning-of-field) | ||
| 2667 | (while (and (not found) | ||
| 2668 | (re-search-forward crossref-reg bound t)) | ||
| 2669 | (setq start (1+ (match-beginning 1)) | ||
| 2670 | end (1- (match-end 1)) | ||
| 2671 | found (>= start pnt))) | ||
| 2672 | (if found (bibtex-button start end 'bibtex-find-crossref | ||
| 2673 | (buffer-substring-no-properties start end) | ||
| 2674 | start t)) | ||
| 2675 | found)) | ||
| 2676 | |||
| 2677 | (defun bibtex-button-action (button) | ||
| 2678 | "Call BUTTON's BibTeX function." | ||
| 2679 | (apply (button-get button 'bibtex-function) | ||
| 2680 | (button-get button 'bibtex-args))) | ||
| 2681 | |||
| 2682 | (define-button-type 'bibtex-url | ||
| 2683 | 'action 'bibtex-button-action | ||
| 2684 | 'bibtex-function 'bibtex-url | ||
| 2685 | 'help-echo (purecopy "mouse-2, RET: follow URL")) | ||
| 2686 | |||
| 2687 | (define-button-type 'bibtex-find-crossref | ||
| 2688 | 'action 'bibtex-button-action | ||
| 2689 | 'bibtex-function 'bibtex-find-crossref | ||
| 2690 | 'help-echo (purecopy "mouse-2, RET: follow crossref")) | ||
| 2691 | |||
| 2692 | (defun bibtex-button (beg end type &rest args) | ||
| 2693 | (make-text-button beg end 'type type 'bibtex-args args)) | ||
| 2694 | |||
| 2570 | 2695 | ||
| 2571 | ;; Interactive Functions: | 2696 | ;; Interactive Functions: |
| 2572 | 2697 | ||
| @@ -2668,7 +2793,7 @@ non-nil. | |||
| 2668 | (make-local-variable 'bibtex-buffer-last-parsed-tick) | 2793 | (make-local-variable 'bibtex-buffer-last-parsed-tick) |
| 2669 | ;; Install stealthy parse function if not already installed | 2794 | ;; Install stealthy parse function if not already installed |
| 2670 | (unless bibtex-parse-idle-timer | 2795 | (unless bibtex-parse-idle-timer |
| 2671 | (setq bibtex-parse-idle-timer (bibtex-run-with-idle-timer | 2796 | (setq bibtex-parse-idle-timer (run-with-idle-timer |
| 2672 | bibtex-parse-keys-timeout t | 2797 | bibtex-parse-keys-timeout t |
| 2673 | 'bibtex-parse-buffers-stealthily))) | 2798 | 'bibtex-parse-buffers-stealthily))) |
| 2674 | (set (make-local-variable 'paragraph-start) "[ \f\n\t]*$") | 2799 | (set (make-local-variable 'paragraph-start) "[ \f\n\t]*$") |
| @@ -2680,8 +2805,8 @@ non-nil. | |||
| 2680 | (set (make-local-variable 'outline-regexp) "[ \t]*@") | 2805 | (set (make-local-variable 'outline-regexp) "[ \t]*@") |
| 2681 | (set (make-local-variable 'fill-paragraph-function) 'bibtex-fill-field) | 2806 | (set (make-local-variable 'fill-paragraph-function) 'bibtex-fill-field) |
| 2682 | (set (make-local-variable 'fill-prefix) (make-string (+ bibtex-entry-offset | 2807 | (set (make-local-variable 'fill-prefix) (make-string (+ bibtex-entry-offset |
| 2683 | bibtex-contline-indentation) | 2808 | bibtex-contline-indentation) |
| 2684 | ? )) | 2809 | ? )) |
| 2685 | (set (make-local-variable 'font-lock-defaults) | 2810 | (set (make-local-variable 'font-lock-defaults) |
| 2686 | '(bibtex-font-lock-keywords | 2811 | '(bibtex-font-lock-keywords |
| 2687 | nil t ((?$ . "\"") | 2812 | nil t ((?$ . "\"") |
| @@ -2693,7 +2818,7 @@ non-nil. | |||
| 2693 | ) | 2818 | ) |
| 2694 | nil | 2819 | nil |
| 2695 | (font-lock-syntactic-keywords . bibtex-font-lock-syntactic-keywords) | 2820 | (font-lock-syntactic-keywords . bibtex-font-lock-syntactic-keywords) |
| 2696 | (font-lock-extra-managed-props . (mouse-face keymap)) | 2821 | (font-lock-extra-managed-props . (category)) |
| 2697 | (font-lock-mark-block-function | 2822 | (font-lock-mark-block-function |
| 2698 | . (lambda () | 2823 | . (lambda () |
| 2699 | (set-mark (bibtex-end-of-entry)) | 2824 | (set-mark (bibtex-end-of-entry)) |
| @@ -2776,8 +2901,7 @@ according to `bibtex-entry-field-alist', but are not yet present." | |||
| 2776 | ;; bibtex-parse-entry moves point to the end of the last field. | 2901 | ;; bibtex-parse-entry moves point to the end of the last field. |
| 2777 | (let* ((fields-alist (bibtex-parse-entry)) | 2902 | (let* ((fields-alist (bibtex-parse-entry)) |
| 2778 | (field-list (bibtex-field-list | 2903 | (field-list (bibtex-field-list |
| 2779 | (substring (cdr (assoc "=type=" fields-alist)) | 2904 | (cdr (assoc "=type=" fields-alist))))) |
| 2780 | 1)))) ; don't want @ | ||
| 2781 | (dolist (field (car field-list)) | 2905 | (dolist (field (car field-list)) |
| 2782 | (unless (assoc-string (car field) fields-alist t) | 2906 | (unless (assoc-string (car field) fields-alist t) |
| 2783 | (bibtex-make-field field))) | 2907 | (bibtex-make-field field))) |
| @@ -2793,8 +2917,8 @@ TEXT may be nil. Remove \"OPT\" and \"ALT\" from FIELD. | |||
| 2793 | Move point to the end of the last field." | 2917 | Move point to the end of the last field." |
| 2794 | (let (alist bounds) | 2918 | (let (alist bounds) |
| 2795 | (when (looking-at bibtex-entry-maybe-empty-head) | 2919 | (when (looking-at bibtex-entry-maybe-empty-head) |
| 2796 | (push (cons "=type=" (match-string bibtex-type-in-head)) alist) | 2920 | (push (cons "=type=" (bibtex-type-in-head)) alist) |
| 2797 | (push (cons "=key=" (match-string bibtex-key-in-head)) alist) | 2921 | (push (cons "=key=" (bibtex-key-in-head)) alist) |
| 2798 | (goto-char (match-end 0)) | 2922 | (goto-char (match-end 0)) |
| 2799 | (while (setq bounds (bibtex-parse-field bibtex-field-name)) | 2923 | (while (setq bounds (bibtex-parse-field bibtex-field-name)) |
| 2800 | (push (cons (bibtex-name-in-field bounds t) | 2924 | (push (cons (bibtex-name-in-field bounds t) |
| @@ -2809,8 +2933,8 @@ Move point to the end of the last field." | |||
| 2809 | (undo-boundary) ;So you can easily undo it, if it didn't work right. | 2933 | (undo-boundary) ;So you can easily undo it, if it didn't work right. |
| 2810 | (bibtex-beginning-of-entry) | 2934 | (bibtex-beginning-of-entry) |
| 2811 | (when (looking-at bibtex-entry-head) | 2935 | (when (looking-at bibtex-entry-head) |
| 2812 | (let ((type (match-string bibtex-type-in-head)) | 2936 | (let ((type (bibtex-type-in-head)) |
| 2813 | (key (match-string bibtex-key-in-head)) | 2937 | (key (bibtex-key-in-head)) |
| 2814 | (key-end (match-end bibtex-key-in-head)) | 2938 | (key-end (match-end bibtex-key-in-head)) |
| 2815 | (case-fold-search t) | 2939 | (case-fold-search t) |
| 2816 | tmp other-key other bounds) | 2940 | tmp other-key other bounds) |
| @@ -2823,9 +2947,9 @@ Move point to the end of the last field." | |||
| 2823 | (bibtex-beginning-of-entry) | 2947 | (bibtex-beginning-of-entry) |
| 2824 | (when (and | 2948 | (when (and |
| 2825 | (looking-at bibtex-entry-head) | 2949 | (looking-at bibtex-entry-head) |
| 2826 | (bibtex-string= type (match-string bibtex-type-in-head)) | 2950 | (bibtex-string= type (bibtex-type-in-head)) |
| 2827 | ;; In case we found ourselves :-( | 2951 | ;; In case we found ourselves :-( |
| 2828 | (not (equal key (setq tmp (match-string bibtex-key-in-head))))) | 2952 | (not (equal key (setq tmp (bibtex-key-in-head))))) |
| 2829 | (setq other-key tmp) | 2953 | (setq other-key tmp) |
| 2830 | (setq other (point)))) | 2954 | (setq other (point)))) |
| 2831 | (save-excursion | 2955 | (save-excursion |
| @@ -2833,9 +2957,9 @@ Move point to the end of the last field." | |||
| 2833 | (bibtex-skip-to-valid-entry) | 2957 | (bibtex-skip-to-valid-entry) |
| 2834 | (when (and | 2958 | (when (and |
| 2835 | (looking-at bibtex-entry-head) | 2959 | (looking-at bibtex-entry-head) |
| 2836 | (bibtex-string= type (match-string bibtex-type-in-head)) | 2960 | (bibtex-string= type (bibtex-type-in-head)) |
| 2837 | ;; In case we found ourselves :-( | 2961 | ;; In case we found ourselves :-( |
| 2838 | (not (equal key (setq tmp (match-string bibtex-key-in-head)))) | 2962 | (not (equal key (setq tmp (bibtex-key-in-head)))) |
| 2839 | (or (not other-key) | 2963 | (or (not other-key) |
| 2840 | ;; Check which is the best match. | 2964 | ;; Check which is the best match. |
| 2841 | (< (length (try-completion "" (list key other-key))) | 2965 | (< (length (try-completion "" (list key other-key))) |
| @@ -2883,24 +3007,26 @@ Move point to the end of the last field." | |||
| 2883 | (message (nth 1 comment)) | 3007 | (message (nth 1 comment)) |
| 2884 | (message "No comment available"))))) | 3008 | (message "No comment available"))))) |
| 2885 | 3009 | ||
| 2886 | (defun bibtex-make-field (field &optional called-by-yank) | 3010 | (defun bibtex-make-field (field &optional called-by-yank interactive) |
| 2887 | "Make a field named FIELD in current BibTeX entry. | 3011 | "Make a field named FIELD in current BibTeX entry. |
| 2888 | FIELD is either a string or a list of the form | 3012 | FIELD is either a string or a list of the form |
| 2889 | \(FIELD-NAME COMMENT-STRING INIT ALTERNATIVE-FLAG) as in | 3013 | \(FIELD-NAME COMMENT-STRING INIT ALTERNATIVE-FLAG) as in |
| 2890 | `bibtex-entry-field-alist'. | 3014 | `bibtex-entry-field-alist'. |
| 2891 | If CALLED-BY-YANK is non-nil, don't insert delimiters." | 3015 | If CALLED-BY-YANK is non-nil, don't insert delimiters. |
| 3016 | In that case, or when called interactively, also don't do (WHAT?)." | ||
| 2892 | (interactive | 3017 | (interactive |
| 2893 | (list (let ((completion-ignore-case t) | 3018 | (list (let ((completion-ignore-case t) |
| 2894 | (field-list (bibtex-field-list | 3019 | (field-list (bibtex-field-list |
| 2895 | (save-excursion | 3020 | (save-excursion |
| 2896 | (bibtex-enclosing-entry-maybe-empty-head) | 3021 | (bibtex-enclosing-entry-maybe-empty-head) |
| 2897 | (bibtex-type-in-head))))) | 3022 | (bibtex-type-in-head))))) |
| 2898 | (completing-read "BibTeX field name: " | 3023 | (completing-read "BibTeX field name: " |
| 2899 | (append (car field-list) (cdr field-list)) | 3024 | (append (car field-list) (cdr field-list)) |
| 2900 | nil nil nil bibtex-field-history)))) | 3025 | nil nil nil bibtex-field-history)) |
| 3026 | t)) | ||
| 2901 | (unless (consp field) | 3027 | (unless (consp field) |
| 2902 | (setq field (list field))) | 3028 | (setq field (list field))) |
| 2903 | (if (or (interactive-p) called-by-yank) | 3029 | (if (or interactive called-by-yank) |
| 2904 | (let (bibtex-help-message) | 3030 | (let (bibtex-help-message) |
| 2905 | (bibtex-find-text nil t t) | 3031 | (bibtex-find-text nil t t) |
| 2906 | (if (looking-at "[}\"]") | 3032 | (if (looking-at "[}\"]") |
| @@ -2923,7 +3049,7 @@ If CALLED-BY-YANK is non-nil, don't insert delimiters." | |||
| 2923 | ((fboundp init) | 3049 | ((fboundp init) |
| 2924 | (insert (funcall init))))) | 3050 | (insert (funcall init))))) |
| 2925 | (unless called-by-yank (insert (bibtex-field-right-delimiter))) | 3051 | (unless called-by-yank (insert (bibtex-field-right-delimiter))) |
| 2926 | (when (interactive-p) | 3052 | (when interactive |
| 2927 | (forward-char -1) | 3053 | (forward-char -1) |
| 2928 | (bibtex-print-help-message))) | 3054 | (bibtex-print-help-message))) |
| 2929 | 3055 | ||
| @@ -3003,17 +3129,13 @@ If mark is active it counts entries in region, if not in whole buffer." | |||
| 3003 | (not count-string-entries))) | 3129 | (not count-string-entries))) |
| 3004 | (save-excursion | 3130 | (save-excursion |
| 3005 | (save-restriction | 3131 | (save-restriction |
| 3006 | (narrow-to-region (if (bibtex-mark-active) | 3132 | (narrow-to-region (if mark-active (region-beginning) |
| 3007 | (region-beginning) | ||
| 3008 | (bibtex-beginning-of-first-entry)) | 3133 | (bibtex-beginning-of-first-entry)) |
| 3009 | (if (bibtex-mark-active) | 3134 | (if mark-active (region-end) (point-max))) |
| 3010 | (region-end) | ||
| 3011 | (point-max))) | ||
| 3012 | (goto-char (point-min)) | ||
| 3013 | (bibtex-map-entries (lambda (key beg end) | 3135 | (bibtex-map-entries (lambda (key beg end) |
| 3014 | (setq number (1+ number)))))) | 3136 | (setq number (1+ number)))))) |
| 3015 | (message "%s contains %d entries." | 3137 | (message "%s contains %d entries." |
| 3016 | (if (bibtex-mark-active) "Region" "Buffer") | 3138 | (if mark-active "Region" "Buffer") |
| 3017 | number))) | 3139 | number))) |
| 3018 | 3140 | ||
| 3019 | (defun bibtex-ispell-entry () | 3141 | (defun bibtex-ispell-entry () |
| @@ -3110,12 +3232,39 @@ will be ignored." | |||
| 3110 | nil ; ENDKEY function | 3232 | nil ; ENDKEY function |
| 3111 | 'bibtex-lessp))) ; PREDICATE | 3233 | 'bibtex-lessp))) ; PREDICATE |
| 3112 | 3234 | ||
| 3113 | (defun bibtex-find-crossref (crossref-key) | 3235 | (defun bibtex-find-entry-globally (key) |
| 3236 | "Move point to the beginning of BibTeX entry named KEY in `bibtex-files'." | ||
| 3237 | (interactive | ||
| 3238 | (list (let (key-alist) | ||
| 3239 | (dolist (buffer (bibtex-files-expand t)) | ||
| 3240 | (with-current-buffer buffer | ||
| 3241 | (setq key-alist (append bibtex-reference-keys key-alist)))) | ||
| 3242 | (completing-read "Find key: " key-alist | ||
| 3243 | nil nil nil 'bibtex-key-history)))) | ||
| 3244 | (let ((buffer-list (bibtex-files-expand t)) | ||
| 3245 | buffer found) | ||
| 3246 | (while (and (not found) | ||
| 3247 | (setq buffer (pop buffer-list))) | ||
| 3248 | (with-current-buffer buffer | ||
| 3249 | (if (cdr (assoc-string key bibtex-reference-keys)) | ||
| 3250 | (setq found t)))) | ||
| 3251 | (if found | ||
| 3252 | (progn | ||
| 3253 | (let ((same-window-buffer-names | ||
| 3254 | (cons (buffer-name buffer) same-window-buffer-names))) | ||
| 3255 | (pop-to-buffer buffer)) | ||
| 3256 | (bibtex-find-entry key)) | ||
| 3257 | (message "Key `%s' not found" key)))) | ||
| 3258 | |||
| 3259 | (defun bibtex-find-crossref (crossref-key &optional pnt split) | ||
| 3114 | "Move point to the beginning of BibTeX entry CROSSREF-KEY. | 3260 | "Move point to the beginning of BibTeX entry CROSSREF-KEY. |
| 3115 | Return position of entry if CROSSREF-KEY is found and nil otherwise. | 3261 | Return position of entry if CROSSREF-KEY is found and nil otherwise. |
| 3116 | If position of current entry is after CROSSREF-KEY an error is signaled. | 3262 | If position of current entry is after CROSSREF-KEY an error is signaled. |
| 3263 | Optional arg PNT is the position of the referencing entry. | ||
| 3264 | If optional arg SPLIT is non-nil, split window so that both the referencing | ||
| 3265 | and the crossrefed entry are displayed. | ||
| 3117 | If called interactively, CROSSREF-KEY defaults to crossref key of current | 3266 | If called interactively, CROSSREF-KEY defaults to crossref key of current |
| 3118 | entry." | 3267 | entry and SPLIT is t." |
| 3119 | (interactive | 3268 | (interactive |
| 3120 | (let ((crossref-key | 3269 | (let ((crossref-key |
| 3121 | (save-excursion | 3270 | (save-excursion |
| @@ -3123,11 +3272,23 @@ entry." | |||
| 3123 | (let ((bounds (bibtex-search-forward-field "crossref" t))) | 3272 | (let ((bounds (bibtex-search-forward-field "crossref" t))) |
| 3124 | (if bounds | 3273 | (if bounds |
| 3125 | (bibtex-text-in-field-bounds bounds t)))))) | 3274 | (bibtex-text-in-field-bounds bounds t)))))) |
| 3126 | (list (bibtex-read-key "Find crossref key: " crossref-key)))) | 3275 | (list (bibtex-read-key "Find crossref key: " crossref-key) (point) t))) |
| 3127 | (let ((pos (save-excursion (bibtex-find-entry crossref-key)))) | 3276 | (let ((pos (save-excursion (bibtex-find-entry crossref-key)))) |
| 3128 | (if (and pos (> (point) pos)) | 3277 | (unless pnt (setq pnt (point))) |
| 3129 | (error "This entry must not follow the crossrefed entry!")) | 3278 | (cond ((not pos) |
| 3130 | (goto-char pos))) | 3279 | (message "Crossref key `%s' not found" crossref-key)) |
| 3280 | (split | ||
| 3281 | (goto-char pnt) | ||
| 3282 | (select-window (split-window)) | ||
| 3283 | (goto-char pos) | ||
| 3284 | (beginning-of-line) | ||
| 3285 | (set-window-start (selected-window) (point)) | ||
| 3286 | (if (> pnt pos) | ||
| 3287 | (error "The referencing entry must preceed the crossrefed entry!"))) | ||
| 3288 | ((> pnt pos) | ||
| 3289 | (error "The referencing entry must preceed the crossrefed entry!")) | ||
| 3290 | (t (goto-char pos))) | ||
| 3291 | pos)) | ||
| 3131 | 3292 | ||
| 3132 | (defun bibtex-find-entry (key &optional start) | 3293 | (defun bibtex-find-entry (key &optional start) |
| 3133 | "Move point to the beginning of BibTeX entry named KEY. | 3294 | "Move point to the beginning of BibTeX entry named KEY. |
| @@ -3212,23 +3373,21 @@ Return t if preparation was successful or nil if entry KEY already exists." | |||
| 3212 | 3373 | ||
| 3213 | (defun bibtex-validate (&optional test-thoroughly) | 3374 | (defun bibtex-validate (&optional test-thoroughly) |
| 3214 | "Validate if buffer or region is syntactically correct. | 3375 | "Validate if buffer or region is syntactically correct. |
| 3215 | Only known entry types are checked, so you can put comments | 3376 | Check also for duplicate keys and correct sort order provided |
| 3216 | outside of entries. | 3377 | `bibtex-maintain-sorted-entries' is non-nil. |
| 3217 | With optional argument TEST-THOROUGHLY non-nil it checks for absence of | 3378 | With optional argument TEST-THOROUGHLY non-nil check also for |
| 3218 | required fields and questionable month fields as well. | 3379 | the absence of required fields and for questionable month fields. |
| 3219 | If mark is active, validate current region, if not the whole buffer. | 3380 | If mark is active, validate current region, if not the whole buffer. |
| 3220 | Returns t if test was successful, nil otherwise." | 3381 | Only check known entry types, so you can put comments outside of entries. |
| 3382 | Return t if test was successful, nil otherwise." | ||
| 3221 | (interactive "P") | 3383 | (interactive "P") |
| 3222 | (let* ((case-fold-search t) | 3384 | (let* ((case-fold-search t) |
| 3223 | error-list syntax-error) | 3385 | error-list syntax-error) |
| 3224 | (save-excursion | 3386 | (save-excursion |
| 3225 | (save-restriction | 3387 | (save-restriction |
| 3226 | (narrow-to-region (if (bibtex-mark-active) | 3388 | (narrow-to-region (if mark-active (region-beginning) |
| 3227 | (region-beginning) | ||
| 3228 | (bibtex-beginning-of-first-entry)) | 3389 | (bibtex-beginning-of-first-entry)) |
| 3229 | (if (bibtex-mark-active) | 3390 | (if mark-active (region-end) (point-max))) |
| 3230 | (region-end) | ||
| 3231 | (point-max))) | ||
| 3232 | 3391 | ||
| 3233 | ;; looking if entries fit syntactical structure | 3392 | ;; looking if entries fit syntactical structure |
| 3234 | (goto-char (point-min)) | 3393 | (goto-char (point-min)) |
| @@ -3244,41 +3403,54 @@ Returns t if test was successful, nil otherwise." | |||
| 3244 | (if (equal (point) pnt) | 3403 | (if (equal (point) pnt) |
| 3245 | (forward-char) | 3404 | (forward-char) |
| 3246 | (goto-char pnt) | 3405 | (goto-char pnt) |
| 3247 | (push (list (bibtex-current-line) | 3406 | (push (cons (bibtex-current-line) |
| 3248 | "Syntax error (check esp. commas, braces, and quotes)") | 3407 | "Syntax error (check esp. commas, braces, and quotes)") |
| 3249 | error-list) | 3408 | error-list) |
| 3250 | (forward-char)))))) | 3409 | (forward-char)))))) |
| 3251 | (bibtex-progress-message 'done) | 3410 | (bibtex-progress-message 'done) |
| 3252 | 3411 | ||
| 3253 | (if error-list | 3412 | (if error-list |
| 3413 | ;; proceed only if there were no syntax errors. | ||
| 3254 | (setq syntax-error t) | 3414 | (setq syntax-error t) |
| 3255 | ;; looking for correct sort order and duplicates (only if | 3415 | |
| 3256 | ;; there were no syntax errors) | 3416 | ;; looking for duplicate keys and correct sort order |
| 3257 | (if bibtex-maintain-sorted-entries | 3417 | (let (previous current key-list) |
| 3258 | (let (previous current) | 3418 | (bibtex-progress-message "Checking for duplicate keys") |
| 3259 | (goto-char (point-min)) | 3419 | (bibtex-map-entries |
| 3260 | (bibtex-progress-message "Checking correct sort order") | 3420 | (lambda (key beg end) |
| 3261 | (bibtex-map-entries | 3421 | (bibtex-progress-message) |
| 3262 | (lambda (key beg end) | 3422 | (goto-char beg) |
| 3263 | (bibtex-progress-message) | 3423 | (setq current (bibtex-entry-index)) |
| 3264 | (goto-char beg) | 3424 | (cond ((not previous)) |
| 3265 | (setq current (bibtex-entry-index)) | 3425 | ((member key key-list) |
| 3266 | (cond ((or (not previous) | 3426 | (push (cons (bibtex-current-line) |
| 3267 | (bibtex-lessp previous current)) | 3427 | (format "Duplicate key `%s'" key)) |
| 3268 | (setq previous current)) | 3428 | error-list)) |
| 3269 | ((string-equal (car previous) (car current)) | 3429 | ((and bibtex-maintain-sorted-entries |
| 3270 | (push (list (bibtex-current-line) | 3430 | (not (bibtex-lessp previous current))) |
| 3271 | "Duplicate key with previous") | 3431 | (push (cons (bibtex-current-line) |
| 3272 | error-list)) | 3432 | "Entries out of order") |
| 3273 | (t | 3433 | error-list))) |
| 3274 | (setq previous current) | 3434 | (push key key-list) |
| 3275 | (push (list (bibtex-current-line) | 3435 | (setq previous current))) |
| 3276 | "Entries out of order") | 3436 | (bibtex-progress-message 'done)) |
| 3277 | error-list))))) | 3437 | |
| 3278 | (bibtex-progress-message 'done))) | 3438 | ;; Check for duplicate keys in `bibtex-files'. |
| 3439 | (bibtex-parse-keys) | ||
| 3440 | (dolist (buffer (bibtex-files-expand)) | ||
| 3441 | (dolist (key (with-current-buffer buffer | ||
| 3442 | ;; We don't want to be fooled by outdated | ||
| 3443 | ;; bibtex-reference-keys. | ||
| 3444 | (bibtex-parse-keys) bibtex-reference-keys)) | ||
| 3445 | (when (and (cdr key) | ||
| 3446 | (cdr (assoc-string (car key) bibtex-reference-keys))) | ||
| 3447 | (bibtex-find-entry (car key)) | ||
| 3448 | (push (cons (bibtex-current-line) | ||
| 3449 | (format "Duplicate key `%s' in %s" (car key) | ||
| 3450 | (abbreviate-file-name (buffer-file-name buffer)))) | ||
| 3451 | error-list)))) | ||
| 3279 | 3452 | ||
| 3280 | (when test-thoroughly | 3453 | (when test-thoroughly |
| 3281 | (goto-char (point-min)) | ||
| 3282 | (bibtex-progress-message | 3454 | (bibtex-progress-message |
| 3283 | "Checking required fields and month fields") | 3455 | "Checking required fields and month fields") |
| 3284 | (let ((bibtex-sort-ignore-string-entries t)) | 3456 | (let ((bibtex-sort-ignore-string-entries t)) |
| @@ -3292,73 +3464,135 @@ Returns t if test was successful, nil otherwise." | |||
| 3292 | bibtex-entry-field-alist t))) | 3464 | bibtex-entry-field-alist t))) |
| 3293 | (req (copy-sequence (elt (elt entry-list 1) 0))) | 3465 | (req (copy-sequence (elt (elt entry-list 1) 0))) |
| 3294 | (creq (copy-sequence (elt (elt entry-list 2) 0))) | 3466 | (creq (copy-sequence (elt (elt entry-list 2) 0))) |
| 3295 | crossref-there bounds) | 3467 | crossref-there bounds alt-there field) |
| 3296 | (goto-char beg) | 3468 | (goto-char beg) |
| 3297 | (while (setq bounds (bibtex-search-forward-field | 3469 | (while (setq bounds (bibtex-search-forward-field |
| 3298 | bibtex-field-name end)) | 3470 | bibtex-field-name end)) |
| 3299 | (goto-char (bibtex-start-of-text-in-field bounds)) | 3471 | (goto-char (bibtex-start-of-text-in-field bounds)) |
| 3300 | (let ((field-name (bibtex-name-in-field bounds))) | 3472 | (let ((field-name (bibtex-name-in-field bounds))) |
| 3301 | (if (and (bibtex-string= field-name "month") | 3473 | (if (and (bibtex-string= field-name "month") |
| 3302 | (not (assoc-string (bibtex-text-in-field-bounds bounds) | 3474 | ;; Check only abbreviated month fields. |
| 3303 | bibtex-predefined-month-strings t))) | 3475 | (let ((month (bibtex-text-in-field-bounds bounds))) |
| 3304 | (push (list (bibtex-current-line) | 3476 | (not (or (string-match "\\`[\"{].+[\"}]\\'" month) |
| 3477 | (assoc-string | ||
| 3478 | month | ||
| 3479 | bibtex-predefined-month-strings t))))) | ||
| 3480 | (push (cons (bibtex-current-line) | ||
| 3305 | "Questionable month field") | 3481 | "Questionable month field") |
| 3306 | error-list)) | 3482 | error-list)) |
| 3307 | (setq req (delete (assoc-string field-name req t) req) | 3483 | (setq field (assoc-string field-name req t)) |
| 3484 | (if (nth 3 field) | ||
| 3485 | (if alt-there (push (cons (bibtex-current-line) | ||
| 3486 | "More than one non-empty alternative") | ||
| 3487 | error-list) | ||
| 3488 | (setq alt-there t))) | ||
| 3489 | (setq req (delete field req) | ||
| 3308 | creq (delete (assoc-string field-name creq t) creq)) | 3490 | creq (delete (assoc-string field-name creq t) creq)) |
| 3309 | (if (bibtex-string= field-name "crossref") | 3491 | (if (bibtex-string= field-name "crossref") |
| 3310 | (setq crossref-there t)))) | 3492 | (setq crossref-there t)))) |
| 3311 | (if crossref-there | 3493 | (if crossref-there |
| 3312 | (setq req creq)) | 3494 | (setq req creq)) |
| 3313 | (if (or (> (length req) 1) | 3495 | (let (alt) |
| 3314 | (and (= (length req) 1) | 3496 | (dolist (field req) |
| 3315 | (not (elt (car req) 3)))) | 3497 | (if (nth 3 field) |
| 3316 | ;; two (or more) fields missed or one field | 3498 | (push (car field) alt) |
| 3317 | ;; missed and this isn't flagged alternative | 3499 | (push (cons (save-excursion (goto-char beg) |
| 3318 | ;; (notice that this fails if there are more | 3500 | (bibtex-current-line)) |
| 3319 | ;; than two alternatives in a BibTeX entry, | 3501 | (format "Required field `%s' missing" |
| 3320 | ;; which isn't the case momentarily) | 3502 | (car field))) |
| 3321 | (push (list (save-excursion | 3503 | error-list))) |
| 3322 | (bibtex-beginning-of-entry) | 3504 | ;; The following fails if there are more than two |
| 3323 | (bibtex-current-line)) | 3505 | ;; alternatives in a BibTeX entry, which isn't |
| 3324 | (concat "Required field `" (caar req) "' missing")) | 3506 | ;; the case momentarily. |
| 3325 | error-list)))))) | 3507 | (if (cdr alt) |
| 3508 | (push (cons (save-excursion (goto-char beg) | ||
| 3509 | (bibtex-current-line)) | ||
| 3510 | (format "Alternative fields `%s'/`%s' missing" | ||
| 3511 | (car alt) (cadr alt))) | ||
| 3512 | error-list))))))) | ||
| 3326 | (bibtex-progress-message 'done))))) | 3513 | (bibtex-progress-message 'done))))) |
| 3514 | |||
| 3327 | (if error-list | 3515 | (if error-list |
| 3328 | (let ((bufnam (buffer-name)) | 3516 | (let ((file (file-name-nondirectory (buffer-file-name))) |
| 3329 | (dir default-directory)) | 3517 | (dir default-directory) |
| 3330 | (setq error-list | 3518 | (err-buf "*BibTeX validation errors*")) |
| 3331 | (sort error-list | 3519 | (setq error-list (sort error-list 'car-less-than-car)) |
| 3332 | (lambda (a b) | 3520 | (with-current-buffer (get-buffer-create err-buf) |
| 3333 | (< (car a) (car b))))) | 3521 | (setq default-directory dir) |
| 3334 | (let ((pop-up-windows t)) | 3522 | (unless (eq major-mode 'compilation-mode) (compilation-mode)) |
| 3335 | (pop-to-buffer nil t)) | 3523 | (toggle-read-only -1) |
| 3336 | (switch-to-buffer | 3524 | (delete-region (point-min) (point-max)) |
| 3337 | (get-buffer-create "*BibTeX validation errors*") t) | 3525 | (insert "BibTeX mode command `bibtex-validate'\n" |
| 3338 | ;; don't use switch-to-buffer-other-window, since this | 3526 | (if syntax-error |
| 3339 | ;; doesn't allow the second parameter NORECORD | 3527 | "Maybe undetected errors due to syntax errors. Correct and validate again.\n" |
| 3340 | (setq default-directory dir) | 3528 | "\n")) |
| 3341 | (toggle-read-only -1) | 3529 | (dolist (err error-list) |
| 3342 | (compilation-mode) | 3530 | (insert (format "%s:%d: %s\n" file (car err) (cdr err)))) |
| 3343 | (delete-region (point-min) (point-max)) | 3531 | (set-buffer-modified-p nil) |
| 3344 | (goto-char (point-min)) | 3532 | (toggle-read-only 1) |
| 3345 | (insert "BibTeX mode command `bibtex-validate'\n" | 3533 | (goto-line 3)) ; first error message |
| 3346 | (if syntax-error | 3534 | (display-buffer err-buf) |
| 3347 | "Maybe undetected errors due to syntax errors. Correct and validate again." | 3535 | ;; return nil |
| 3348 | "") | 3536 | nil) |
| 3349 | "\n") | 3537 | (message "%s is syntactically correct" |
| 3350 | (dolist (err error-list) | 3538 | (if mark-active "Region" "Buffer")) |
| 3351 | (insert bufnam ":" (number-to-string (elt err 0)) | 3539 | t))) |
| 3352 | ": " (elt err 1) "\n")) | 3540 | |
| 3353 | (set-buffer-modified-p nil) | 3541 | (defun bibtex-validate-globally (&optional strings) |
| 3354 | (toggle-read-only 1) | 3542 | "Check for duplicate keys in `bibtex-files'. |
| 3543 | With prefix arg STRINGS, check for duplicate strings, too. | ||
| 3544 | Return t if test was successful, nil otherwise." | ||
| 3545 | (interactive "P") | ||
| 3546 | (let ((buffer-list (bibtex-files-expand t)) | ||
| 3547 | buffer-key-list current-buf current-keys error-list) | ||
| 3548 | ;; Check for duplicate keys within BibTeX buffer | ||
| 3549 | (dolist (buffer buffer-list) | ||
| 3550 | (save-excursion | ||
| 3551 | (set-buffer buffer) | ||
| 3552 | (let (entry-type key key-list) | ||
| 3355 | (goto-char (point-min)) | 3553 | (goto-char (point-min)) |
| 3356 | (other-window -1) | 3554 | (while (re-search-forward bibtex-entry-head nil t) |
| 3555 | (setq entry-type (bibtex-type-in-head) | ||
| 3556 | key (bibtex-key-in-head)) | ||
| 3557 | (if (or (and strings (bibtex-string= entry-type "string")) | ||
| 3558 | (assoc-string entry-type bibtex-entry-field-alist t)) | ||
| 3559 | (if (member key key-list) | ||
| 3560 | (push (format "%s:%d: Duplicate key `%s'\n" | ||
| 3561 | (buffer-file-name) | ||
| 3562 | (bibtex-current-line) key) | ||
| 3563 | error-list) | ||
| 3564 | (push key key-list)))) | ||
| 3565 | (push (cons buffer key-list) buffer-key-list)))) | ||
| 3566 | |||
| 3567 | ;; Check for duplicate keys among BibTeX buffers | ||
| 3568 | (while (setq current-buf (pop buffer-list)) | ||
| 3569 | (setq current-keys (cdr (assq current-buf buffer-key-list))) | ||
| 3570 | (with-current-buffer current-buf | ||
| 3571 | (dolist (buffer buffer-list) | ||
| 3572 | (dolist (key (cdr (assq buffer buffer-key-list))) | ||
| 3573 | (when (assoc-string key current-keys) | ||
| 3574 | (bibtex-find-entry key) | ||
| 3575 | (push (format "%s:%d: Duplicat key `%s' in %s\n" | ||
| 3576 | (buffer-file-name) (bibtex-current-line) key | ||
| 3577 | (abbreviate-file-name (buffer-file-name buffer))) | ||
| 3578 | error-list)))))) | ||
| 3579 | |||
| 3580 | ;; Process error list | ||
| 3581 | (if error-list | ||
| 3582 | (let ((err-buf "*BibTeX validation errors*")) | ||
| 3583 | (with-current-buffer (get-buffer-create err-buf) | ||
| 3584 | (unless (eq major-mode 'compilation-mode) (compilation-mode)) | ||
| 3585 | (toggle-read-only -1) | ||
| 3586 | (delete-region (point-min) (point-max)) | ||
| 3587 | (insert "BibTeX mode command `bibtex-validate-globally'\n\n") | ||
| 3588 | (dolist (err (sort error-list 'string-lessp)) (insert err)) | ||
| 3589 | (set-buffer-modified-p nil) | ||
| 3590 | (toggle-read-only 1) | ||
| 3591 | (goto-line 3)) ; first error message | ||
| 3592 | (display-buffer err-buf) | ||
| 3357 | ;; return nil | 3593 | ;; return nil |
| 3358 | nil) | 3594 | nil) |
| 3359 | (if (bibtex-mark-active) | 3595 | (message "No duplicate keys.") |
| 3360 | (message "Region is syntactically correct") | ||
| 3361 | (message "Buffer is syntactically correct")) | ||
| 3362 | t))) | 3596 | t))) |
| 3363 | 3597 | ||
| 3364 | (defun bibtex-next-field (arg) | 3598 | (defun bibtex-next-field (arg) |
| @@ -3378,10 +3612,9 @@ Returns t if test was successful, nil otherwise." | |||
| 3378 | 3612 | ||
| 3379 | (defun bibtex-find-text (arg &optional as-if-interactive no-error) | 3613 | (defun bibtex-find-text (arg &optional as-if-interactive no-error) |
| 3380 | "Go to end of text of current field; with ARG, go to beginning." | 3614 | "Go to end of text of current field; with ARG, go to beginning." |
| 3381 | (interactive "P") | 3615 | (interactive "P\np") |
| 3382 | (bibtex-inside-field) | 3616 | (bibtex-inside-field) |
| 3383 | (let ((bounds (bibtex-enclosing-field (or (interactive-p) | 3617 | (let ((bounds (bibtex-enclosing-field as-if-interactive))) |
| 3384 | as-if-interactive)))) | ||
| 3385 | (if bounds | 3618 | (if bounds |
| 3386 | (progn (if arg | 3619 | (progn (if arg |
| 3387 | (progn (goto-char (bibtex-start-of-text-in-field bounds)) | 3620 | (progn (goto-char (bibtex-start-of-text-in-field bounds)) |
| @@ -3404,7 +3637,7 @@ Returns t if test was successful, nil otherwise." | |||
| 3404 | (match-end 0)))) | 3637 | (match-end 0)))) |
| 3405 | (t | 3638 | (t |
| 3406 | (unless no-error | 3639 | (unless no-error |
| 3407 | (error "Not on BibTeX field"))))))) | 3640 | (error "Not on BibTeX field"))))))) |
| 3408 | 3641 | ||
| 3409 | (defun bibtex-remove-OPT-or-ALT () | 3642 | (defun bibtex-remove-OPT-or-ALT () |
| 3410 | "Remove the string starting optional/alternative fields. | 3643 | "Remove the string starting optional/alternative fields. |
| @@ -3470,6 +3703,7 @@ but do not actually kill it." | |||
| 3470 | (setq bibtex-last-kill-command 'field)) | 3703 | (setq bibtex-last-kill-command 'field)) |
| 3471 | 3704 | ||
| 3472 | (defun bibtex-copy-field-as-kill () | 3705 | (defun bibtex-copy-field-as-kill () |
| 3706 | "Copy the field at point to the kill ring." | ||
| 3473 | (interactive) | 3707 | (interactive) |
| 3474 | (bibtex-kill-field t)) | 3708 | (bibtex-kill-field t)) |
| 3475 | 3709 | ||
| @@ -3492,9 +3726,9 @@ With prefix arg COPY-ONLY the current entry to | |||
| 3492 | (setcdr (nthcdr (1- bibtex-entry-kill-ring-max) | 3726 | (setcdr (nthcdr (1- bibtex-entry-kill-ring-max) |
| 3493 | bibtex-entry-kill-ring) | 3727 | bibtex-entry-kill-ring) |
| 3494 | nil)) | 3728 | nil)) |
| 3495 | (setq bibtex-entry-kill-ring-yank-pointer bibtex-entry-kill-ring) | 3729 | (setq bibtex-entry-kill-ring-yank-pointer bibtex-entry-kill-ring) |
| 3496 | (unless copy-only | 3730 | (unless copy-only |
| 3497 | (delete-region beg end)))) | 3731 | (delete-region beg end)))) |
| 3498 | (setq bibtex-last-kill-command 'entry)) | 3732 | (setq bibtex-last-kill-command 'entry)) |
| 3499 | 3733 | ||
| 3500 | (defun bibtex-copy-entry-as-kill () | 3734 | (defun bibtex-copy-entry-as-kill () |
| @@ -3584,7 +3818,7 @@ At end of the cleaning process, the functions in | |||
| 3584 | ;; (bibtex-format-preamble) | 3818 | ;; (bibtex-format-preamble) |
| 3585 | (error "No clean up of @Preamble entries")) | 3819 | (error "No clean up of @Preamble entries")) |
| 3586 | ((bibtex-string= entry-type "string")) | 3820 | ((bibtex-string= entry-type "string")) |
| 3587 | ;; (bibtex-format-string) | 3821 | ;; (bibtex-format-string) |
| 3588 | (t (bibtex-format-entry))) | 3822 | (t (bibtex-format-entry))) |
| 3589 | ;; set key | 3823 | ;; set key |
| 3590 | (when (or new-key (not key)) | 3824 | (when (or new-key (not key)) |
| @@ -3597,7 +3831,7 @@ At end of the cleaning process, the functions in | |||
| 3597 | (delete-region (match-beginning bibtex-key-in-head) | 3831 | (delete-region (match-beginning bibtex-key-in-head) |
| 3598 | (match-end bibtex-key-in-head))) | 3832 | (match-end bibtex-key-in-head))) |
| 3599 | (insert key)) | 3833 | (insert key)) |
| 3600 | ;; sorting | 3834 | |
| 3601 | (unless called-by-reformat | 3835 | (unless called-by-reformat |
| 3602 | (let* ((start (bibtex-beginning-of-entry)) | 3836 | (let* ((start (bibtex-beginning-of-entry)) |
| 3603 | (end (progn (bibtex-end-of-entry) | 3837 | (end (progn (bibtex-end-of-entry) |
| @@ -3606,9 +3840,12 @@ At end of the cleaning process, the functions in | |||
| 3606 | (goto-char (match-beginning 0))) | 3840 | (goto-char (match-beginning 0))) |
| 3607 | (point))) | 3841 | (point))) |
| 3608 | (entry (buffer-substring start end)) | 3842 | (entry (buffer-substring start end)) |
| 3609 | (index (progn (goto-char start) | 3843 | ;; include the crossref key in index |
| 3610 | (bibtex-entry-index))) | 3844 | (index (let ((bibtex-maintain-sorted-entries 'crossref)) |
| 3845 | (goto-char start) | ||
| 3846 | (bibtex-entry-index))) | ||
| 3611 | error) | 3847 | error) |
| 3848 | ;; sorting | ||
| 3612 | (if (and bibtex-maintain-sorted-entries | 3849 | (if (and bibtex-maintain-sorted-entries |
| 3613 | (not (and bibtex-sort-ignore-string-entries | 3850 | (not (and bibtex-sort-ignore-string-entries |
| 3614 | (bibtex-string= entry-type "string")))) | 3851 | (bibtex-string= entry-type "string")))) |
| @@ -3623,17 +3860,37 @@ At end of the cleaning process, the functions in | |||
| 3623 | (setq error (or (/= (point) start) | 3860 | (setq error (or (/= (point) start) |
| 3624 | (bibtex-find-entry key end)))) | 3861 | (bibtex-find-entry key end)))) |
| 3625 | (if error | 3862 | (if error |
| 3626 | (error "New inserted entry yields duplicate key")))) | 3863 | (error "New inserted entry yields duplicate key")) |
| 3627 | ;; final clean up | 3864 | (dolist (buffer (bibtex-files-expand)) |
| 3628 | (unless called-by-reformat | 3865 | (with-current-buffer buffer |
| 3629 | (save-excursion | 3866 | (if (cdr (assoc-string key bibtex-reference-keys)) |
| 3630 | (save-restriction | 3867 | (error "Duplicate key in %s" (buffer-file-name))))) |
| 3631 | (bibtex-narrow-to-entry) | 3868 | |
| 3632 | ;; Only update the list of keys if it has been built already. | 3869 | ;; Only update the list of keys if it has been built already. |
| 3633 | (cond ((bibtex-string= entry-type "string") | 3870 | (cond ((bibtex-string= entry-type "string") |
| 3634 | (if (listp bibtex-strings) (bibtex-parse-strings t))) | 3871 | (if (and (listp bibtex-strings) |
| 3635 | ((listp bibtex-reference-keys) (bibtex-parse-keys t))) | 3872 | (not (assoc key bibtex-strings))) |
| 3636 | (run-hooks 'bibtex-clean-entry-hook)))))) | 3873 | (push (list key) bibtex-strings))) |
| 3874 | ;; We have a normal entry. | ||
| 3875 | ((listp bibtex-reference-keys) | ||
| 3876 | (cond ((not (assoc key bibtex-reference-keys)) | ||
| 3877 | (push (cons key t) bibtex-reference-keys)) | ||
| 3878 | ((not (cdr (assoc key bibtex-reference-keys))) | ||
| 3879 | ;; Turn a crossref key into a header key | ||
| 3880 | (setq bibtex-reference-keys | ||
| 3881 | (cons (cons key t) | ||
| 3882 | (delete (list key) bibtex-reference-keys))))) | ||
| 3883 | ;; Handle crossref key. | ||
| 3884 | (if (and (nth 1 index) | ||
| 3885 | (not (assoc (nth 1 index) bibtex-reference-keys))) | ||
| 3886 | (push (list (nth 1 index)) bibtex-reference-keys))))) | ||
| 3887 | |||
| 3888 | ;; final clean up | ||
| 3889 | (if bibtex-clean-entry-hook | ||
| 3890 | (save-excursion | ||
| 3891 | (save-restriction | ||
| 3892 | (bibtex-narrow-to-entry) | ||
| 3893 | (run-hooks 'bibtex-clean-entry-hook))))))) | ||
| 3637 | 3894 | ||
| 3638 | (defun bibtex-fill-field-bounds (bounds justify &optional move) | 3895 | (defun bibtex-fill-field-bounds (bounds justify &optional move) |
| 3639 | "Fill BibTeX field delimited by BOUNDS. | 3896 | "Fill BibTeX field delimited by BOUNDS. |
| @@ -3705,13 +3962,24 @@ If `bibtex-align-at-equal-sign' is non-nil, align equal signs, too." | |||
| 3705 | "Realign BibTeX entries such that they are separated by one blank line." | 3962 | "Realign BibTeX entries such that they are separated by one blank line." |
| 3706 | (goto-char (point-min)) | 3963 | (goto-char (point-min)) |
| 3707 | (let ((case-fold-search t)) | 3964 | (let ((case-fold-search t)) |
| 3965 | ;; No blank lines prior to the first valid entry if there no | ||
| 3966 | ;; non-white characters in front of it. | ||
| 3708 | (when (looking-at bibtex-valid-entry-whitespace-re) | 3967 | (when (looking-at bibtex-valid-entry-whitespace-re) |
| 3709 | (replace-match "\\1")) | 3968 | (replace-match "\\1")) |
| 3969 | ;; Valid entries are separated by one blank line. | ||
| 3710 | (while (re-search-forward bibtex-valid-entry-whitespace-re nil t) | 3970 | (while (re-search-forward bibtex-valid-entry-whitespace-re nil t) |
| 3711 | (replace-match "\n\n\\1")))) | 3971 | (replace-match "\n\n\\1")) |
| 3972 | ;; One blank line past the last valid entry if it is followed by | ||
| 3973 | ;; non-white characters, no blank line otherwise. | ||
| 3974 | (beginning-of-line) | ||
| 3975 | (when (re-search-forward bibtex-valid-entry-re nil t) | ||
| 3976 | (bibtex-end-of-entry) | ||
| 3977 | (bibtex-delete-whitespace) | ||
| 3978 | (open-line (if (eobp) 1 2))))) | ||
| 3712 | 3979 | ||
| 3713 | (defun bibtex-reformat (&optional read-options) | 3980 | (defun bibtex-reformat (&optional read-options) |
| 3714 | "Reformat all BibTeX entries in buffer or region. | 3981 | "Reformat all BibTeX entries in buffer or region. |
| 3982 | Without prefix argument, reformatting is based on `bibtex-entry-format'. | ||
| 3715 | With prefix argument, read options for reformatting from minibuffer. | 3983 | With prefix argument, read options for reformatting from minibuffer. |
| 3716 | With \\[universal-argument] \\[universal-argument] prefix argument, reuse previous answers (if any) again. | 3984 | With \\[universal-argument] \\[universal-argument] prefix argument, reuse previous answers (if any) again. |
| 3717 | If mark is active reformat entries in region, if not in whole buffer." | 3985 | If mark is active reformat entries in region, if not in whole buffer." |
| @@ -3722,55 +3990,54 @@ If mark is active reformat entries in region, if not in whole buffer." | |||
| 3722 | (or bibtex-reformat-previous-options | 3990 | (or bibtex-reformat-previous-options |
| 3723 | bibtex-reformat-previous-reference-keys))) | 3991 | bibtex-reformat-previous-reference-keys))) |
| 3724 | (bibtex-entry-format | 3992 | (bibtex-entry-format |
| 3725 | (if read-options | 3993 | (cond (read-options |
| 3726 | (if use-previous-options | 3994 | (if use-previous-options |
| 3727 | bibtex-reformat-previous-options | 3995 | bibtex-reformat-previous-options |
| 3728 | (setq bibtex-reformat-previous-options | 3996 | (setq bibtex-reformat-previous-options |
| 3729 | (mapcar (lambda (option) | 3997 | (mapcar (lambda (option) |
| 3730 | (if (y-or-n-p (car option)) (cdr option))) | 3998 | (if (y-or-n-p (car option)) (cdr option))) |
| 3731 | `(("Realign entries (recommended)? " . 'realign) | 3999 | `(("Realign entries (recommended)? " . 'realign) |
| 3732 | ("Remove empty optional and alternative fields? " . 'opts-or-alts) | 4000 | ("Remove empty optional and alternative fields? " . 'opts-or-alts) |
| 3733 | ("Remove delimiters around pure numerical fields? " . 'numerical-fields) | 4001 | ("Remove delimiters around pure numerical fields? " . 'numerical-fields) |
| 3734 | (,(concat (if bibtex-comma-after-last-field "Insert" "Remove") | 4002 | (,(concat (if bibtex-comma-after-last-field "Insert" "Remove") |
| 3735 | " comma at end of entry? ") . 'last-comma) | 4003 | " comma at end of entry? ") . 'last-comma) |
| 3736 | ("Replace double page dashes by single ones? " . 'page-dashes) | 4004 | ("Replace double page dashes by single ones? " . 'page-dashes) |
| 3737 | ("Force delimiters? " . 'delimiters) | 4005 | ("Inherit booktitle? " . 'inherit-booktitle) |
| 3738 | ("Unify case of entry types and field names? " . 'unify-case))))) | 4006 | ("Force delimiters? " . 'delimiters) |
| 3739 | '(realign))) | 4007 | ("Unify case of entry types and field names? " . 'unify-case)))))) |
| 4008 | ;; Do not include required-fields because `bibtex-reformat' | ||
| 4009 | ;; cannot handle the error messages of `bibtex-format-entry'. | ||
| 4010 | ;; Use `bibtex-validate' to check for required fields. | ||
| 4011 | ((eq t bibtex-entry-format) | ||
| 4012 | '(realign opts-or-alts numerical-fields delimiters | ||
| 4013 | last-comma page-dashes unify-case inherit-booktitle)) | ||
| 4014 | (t | ||
| 4015 | (remove 'required-fields (push 'realign bibtex-entry-format))))) | ||
| 3740 | (reformat-reference-keys | 4016 | (reformat-reference-keys |
| 3741 | (if read-options | 4017 | (if read-options |
| 3742 | (if use-previous-options | 4018 | (if use-previous-options |
| 3743 | bibtex-reformat-previous-reference-keys | 4019 | bibtex-reformat-previous-reference-keys |
| 3744 | (setq bibtex-reformat-previous-reference-keys | 4020 | (setq bibtex-reformat-previous-reference-keys |
| 3745 | (y-or-n-p "Generate new reference keys automatically? "))))) | 4021 | (y-or-n-p "Generate new reference keys automatically? "))))) |
| 3746 | (start-point (if (bibtex-mark-active) | ||
| 3747 | (region-beginning) | ||
| 3748 | (point-min))) | ||
| 3749 | (end-point (if (bibtex-mark-active) | ||
| 3750 | (region-end) | ||
| 3751 | (point-max))) | ||
| 3752 | (bibtex-sort-ignore-string-entries t) | 4022 | (bibtex-sort-ignore-string-entries t) |
| 3753 | bibtex-autokey-edit-before-use) | 4023 | bibtex-autokey-edit-before-use) |
| 3754 | 4024 | ||
| 3755 | (save-restriction | 4025 | (save-restriction |
| 3756 | (narrow-to-region start-point end-point) | 4026 | (narrow-to-region (if mark-active (region-beginning) (point-min)) |
| 4027 | (if mark-active (region-end) (point-max))) | ||
| 3757 | (if (memq 'realign bibtex-entry-format) | 4028 | (if (memq 'realign bibtex-entry-format) |
| 3758 | (bibtex-realign)) | 4029 | (bibtex-realign)) |
| 3759 | (goto-char start-point) | ||
| 3760 | (bibtex-progress-message "Formatting" 1) | 4030 | (bibtex-progress-message "Formatting" 1) |
| 3761 | (bibtex-map-entries (lambda (key beg end) | 4031 | (bibtex-map-entries (lambda (key beg end) |
| 3762 | (bibtex-progress-message) | 4032 | (bibtex-progress-message) |
| 3763 | (bibtex-clean-entry reformat-reference-keys t))) | 4033 | (bibtex-clean-entry reformat-reference-keys t))) |
| 3764 | (when (memq 'realign bibtex-entry-format) | ||
| 3765 | (bibtex-delete-whitespace) | ||
| 3766 | (open-line (if (eobp) 1 2))) | ||
| 3767 | (bibtex-progress-message 'done)) | 4034 | (bibtex-progress-message 'done)) |
| 3768 | (when (and reformat-reference-keys | 4035 | (when reformat-reference-keys |
| 3769 | bibtex-maintain-sorted-entries) | ||
| 3770 | (bibtex-progress-message "Sorting" 1) | ||
| 3771 | (bibtex-sort-buffer) | ||
| 3772 | (kill-local-variable 'bibtex-reference-keys) | 4036 | (kill-local-variable 'bibtex-reference-keys) |
| 3773 | (bibtex-progress-message 'done)) | 4037 | (when bibtex-maintain-sorted-entries |
| 4038 | (bibtex-progress-message "Sorting" 1) | ||
| 4039 | (bibtex-sort-buffer) | ||
| 4040 | (bibtex-progress-message 'done))) | ||
| 3774 | (goto-char pnt))) | 4041 | (goto-char pnt))) |
| 3775 | 4042 | ||
| 3776 | (defun bibtex-convert-alien (&optional read-options) | 4043 | (defun bibtex-convert-alien (&optional read-options) |
| @@ -3837,21 +4104,23 @@ signaled if point is outside key or BibTeX field." | |||
| 3837 | ;; key completion | 4104 | ;; key completion |
| 3838 | (setq choose-completion-string-functions | 4105 | (setq choose-completion-string-functions |
| 3839 | (lambda (choice buffer mini-p base-size) | 4106 | (lambda (choice buffer mini-p base-size) |
| 3840 | (bibtex-choose-completion-string choice buffer mini-p base-size) | 4107 | (let ((choose-completion-string-functions nil)) |
| 4108 | (choose-completion-string choice buffer base-size)) | ||
| 3841 | (bibtex-complete-key-cleanup choice) | 4109 | (bibtex-complete-key-cleanup choice) |
| 3842 | ;; return t (required by choose-completion-string-functions) | 4110 | ;; return t (required by choose-completion-string-functions) |
| 3843 | t)) | 4111 | t)) |
| 3844 | (bibtex-complete-key-cleanup (bibtex-complete-internal | 4112 | (bibtex-complete-key-cleanup (bibtex-complete-internal |
| 3845 | bibtex-reference-keys))) | 4113 | bibtex-reference-keys))) |
| 3846 | 4114 | ||
| 3847 | (compl | 4115 | (compl |
| 3848 | ;; string completion | 4116 | ;; string completion |
| 3849 | (setq choose-completion-string-functions | 4117 | (setq choose-completion-string-functions |
| 3850 | `(lambda (choice buffer mini-p base-size) | 4118 | `(lambda (choice buffer mini-p base-size) |
| 3851 | (bibtex-choose-completion-string choice buffer mini-p base-size) | 4119 | (let ((choose-completion-string-functions nil)) |
| 3852 | (bibtex-complete-string-cleanup choice ',compl) | 4120 | (choose-completion-string choice buffer base-size)) |
| 3853 | ;; return t (required by choose-completion-string-functions) | 4121 | (bibtex-complete-string-cleanup choice ',compl) |
| 3854 | t)) | 4122 | ;; return t (required by choose-completion-string-functions) |
| 4123 | t)) | ||
| 3855 | (bibtex-complete-string-cleanup (bibtex-complete-internal compl) | 4124 | (bibtex-complete-string-cleanup (bibtex-complete-internal compl) |
| 3856 | compl)) | 4125 | compl)) |
| 3857 | 4126 | ||
| @@ -3960,80 +4229,56 @@ signaled if point is outside key or BibTeX field." | |||
| 3960 | "\n") | 4229 | "\n") |
| 3961 | (goto-char endpos))) | 4230 | (goto-char endpos))) |
| 3962 | 4231 | ||
| 3963 | (defun bibtex-url (&optional event) | 4232 | (defun bibtex-url (&optional pos) |
| 3964 | "Browse a URL for the BibTeX entry at position PNT. | 4233 | "Browse a URL for the BibTeX entry at point. |
| 4234 | Optional POS is the location of the BibTeX entry. | ||
| 3965 | The URL is generated using the schemes defined in `bibtex-generate-url-list' | 4235 | The URL is generated using the schemes defined in `bibtex-generate-url-list' |
| 3966 | \(see there\). Then the URL is passed to `browse-url'." | 4236 | \(see there\). Then the URL is passed to `browse-url'." |
| 3967 | (interactive (list last-input-event)) | 4237 | (interactive) |
| 3968 | (save-excursion | 4238 | (save-excursion |
| 3969 | (if event (posn-set-point (event-end event))) | 4239 | (if pos (goto-char pos)) |
| 3970 | (bibtex-beginning-of-entry) | 4240 | (bibtex-beginning-of-entry) |
| 3971 | (let ((fields-alist (bibtex-parse-entry)) | 4241 | (let ((fields-alist (bibtex-parse-entry)) |
| 4242 | ;; Always ignore case, | ||
| 3972 | (case-fold-search t) | 4243 | (case-fold-search t) |
| 3973 | (lst bibtex-generate-url-list) | 4244 | (lst bibtex-generate-url-list) |
| 4245 | (delim-regexp "\\`[{\"]\\(.*\\)[}\"]\\'") | ||
| 3974 | field url scheme) | 4246 | field url scheme) |
| 3975 | (while (setq scheme (car lst)) | 4247 | (while (setq scheme (pop lst)) |
| 3976 | (when (and (setq field (cdr (assoc-string (caar scheme) | 4248 | (when (and (setq field (cdr (assoc-string (caar scheme) |
| 3977 | fields-alist t))) | 4249 | fields-alist t))) |
| 3978 | (progn | 4250 | ;; Always remove field delimiters |
| 3979 | (if (string-match "\\`[{\"]\\(.*\\)[}\"]\\'" field) | 4251 | (progn (if (string-match delim-regexp field) |
| 3980 | (setq field (match-string 1 field))) | 4252 | (setq field (match-string 1 field))) |
| 3981 | (string-match (cdar scheme) field))) | 4253 | (string-match (cdar scheme) field))) |
| 3982 | (setq lst nil) | 4254 | (setq lst nil) |
| 3983 | (if (null (cdr scheme)) | 4255 | (if (null (cdr scheme)) |
| 3984 | (setq url (match-string 0 field))) | 4256 | (setq url (match-string 0 field))) |
| 3985 | (dolist (step (cdr scheme)) | 4257 | (dolist (step (cdr scheme)) |
| 3986 | (cond ((stringp step) | 4258 | (cond ((stringp step) |
| 3987 | (setq url (concat url step))) | 4259 | (setq url (concat url step))) |
| 3988 | ((setq field (assoc-string (car step) fields-alist t)) | 4260 | ((setq field (cdr (assoc-string (car step) fields-alist t))) |
| 3989 | ;; always remove field delimiters | 4261 | ;; Always remove field delimiters |
| 3990 | (let* ((text (if (string-match "\\`[{\"]\\(.*\\)[}\"]\\'" | 4262 | (if (string-match delim-regexp field) |
| 3991 | (cdr field)) | 4263 | (setq field (match-string 1 field))) |
| 3992 | (match-string 1 (cdr field)) | 4264 | (if (string-match (nth 1 step) field) |
| 3993 | (cdr field))) | 4265 | (setq field (cond |
| 3994 | (str (if (string-match (nth 1 step) text) | 4266 | ((functionp (nth 2 step)) |
| 3995 | (cond | 4267 | (funcall (nth 2 step) field)) |
| 3996 | ((functionp (nth 2 step)) | 4268 | ((numberp (nth 2 step)) |
| 3997 | (funcall (nth 2 step) text)) | 4269 | (match-string (nth 2 step) field)) |
| 3998 | ((numberp (nth 2 step)) | 4270 | (t |
| 3999 | (match-string (nth 2 step) text)) | 4271 | (replace-match (nth 2 step) nil nil field)))) |
| 4000 | (t | 4272 | ;; If the scheme is set up correctly, |
| 4001 | (replace-match (nth 2 step) nil nil text))) | 4273 | ;; we should never reach this point |
| 4002 | ;; If the scheme is set up correctly, | 4274 | (error "Match failed: %s" field)) |
| 4003 | ;; we should never reach this point | 4275 | (setq url (concat url field))) |
| 4004 | (error "Match failed: %s" text)))) | 4276 | ;; If the scheme is set up correctly, |
| 4005 | (setq url (concat url str)))) | 4277 | ;; we should never reach this point |
| 4006 | ;; If the scheme is set up correctly, | 4278 | (t (error "Step failed: %s" step)))) |
| 4007 | ;; we should never reach this point | 4279 | (message "%s" url) |
| 4008 | (t (error "Step failed: %s" step)))) | 4280 | (browse-url url))) |
| 4009 | (message "%s" url) | 4281 | (unless url (message "No URL known."))))) |
| 4010 | (browse-url url)) | ||
| 4011 | (setq lst (cdr lst))) | ||
| 4012 | (unless url (message "No URL known."))))) | ||
| 4013 | |||
| 4014 | (defun bibtex-font-lock-url (bound) | ||
| 4015 | "Font-lock for URLs." | ||
| 4016 | (let ((case-fold-search t) | ||
| 4017 | (bounds (bibtex-enclosing-field t)) | ||
| 4018 | (pnt (point)) | ||
| 4019 | found field) | ||
| 4020 | ;; We use start-of-field as syntax-begin | ||
| 4021 | (goto-char (if bounds (bibtex-start-of-field bounds) pnt)) | ||
| 4022 | (while (and (not found) | ||
| 4023 | (prog1 (re-search-forward bibtex-font-lock-url-regexp bound t) | ||
| 4024 | (setq field (match-string-no-properties 1))) | ||
| 4025 | (setq bounds (bibtex-parse-field-text)) | ||
| 4026 | (>= bound (car bounds)) | ||
| 4027 | (>= (car bounds) pnt)) | ||
| 4028 | (let ((lst bibtex-generate-url-list) url) | ||
| 4029 | (goto-char (car bounds)) | ||
| 4030 | (while (and (not found) | ||
| 4031 | (setq url (caar lst))) | ||
| 4032 | (when (bibtex-string= field (car url)) | ||
| 4033 | (setq found (re-search-forward (cdr url) (cdr bounds) t))) | ||
| 4034 | (setq lst (cdr lst)))) | ||
| 4035 | (goto-char (cdr bounds))) | ||
| 4036 | found)) | ||
| 4037 | 4282 | ||
| 4038 | 4283 | ||
| 4039 | ;; Make BibTeX a Feature | 4284 | ;; Make BibTeX a Feature |
diff --git a/lisp/textmodes/flyspell.el b/lisp/textmodes/flyspell.el index 93a7ebd52e4..556369077d8 100644 --- a/lisp/textmodes/flyspell.el +++ b/lisp/textmodes/flyspell.el | |||
| @@ -956,9 +956,7 @@ Mostly we check word delimiters." | |||
| 956 | ;*---------------------------------------------------------------------*/ | 956 | ;*---------------------------------------------------------------------*/ |
| 957 | (defun flyspell-word (&optional following) | 957 | (defun flyspell-word (&optional following) |
| 958 | "Spell check a word." | 958 | "Spell check a word." |
| 959 | (interactive (list current-prefix-arg)) | 959 | (interactive (list ispell-following-word)) |
| 960 | (if (interactive-p) | ||
| 961 | (setq following ispell-following-word)) | ||
| 962 | (save-excursion | 960 | (save-excursion |
| 963 | ;; use the correct dictionary | 961 | ;; use the correct dictionary |
| 964 | (flyspell-accept-buffer-local-defs) | 962 | (flyspell-accept-buffer-local-defs) |
diff --git a/lisp/textmodes/ispell.el b/lisp/textmodes/ispell.el index f0547d6d596..d221d39180f 100644 --- a/lisp/textmodes/ispell.el +++ b/lisp/textmodes/ispell.el | |||
| @@ -1410,12 +1410,9 @@ nil word is correct or spelling is accepted. | |||
| 1410 | \(\"word\" arg\) word is hand entered. | 1410 | \(\"word\" arg\) word is hand entered. |
| 1411 | quit spell session exited." | 1411 | quit spell session exited." |
| 1412 | 1412 | ||
| 1413 | (interactive (list nil nil current-prefix-arg)) | 1413 | (interactive (list ispell-following-word ispell-quietly current-prefix-arg)) |
| 1414 | (if continue | 1414 | (if continue |
| 1415 | (ispell-continue) | 1415 | (ispell-continue) |
| 1416 | (if (interactive-p) | ||
| 1417 | (setq following ispell-following-word | ||
| 1418 | quietly ispell-quietly)) | ||
| 1419 | (ispell-accept-buffer-local-defs) ; use the correct dictionary | 1416 | (ispell-accept-buffer-local-defs) ; use the correct dictionary |
| 1420 | (let ((cursor-location (point)) ; retain cursor location | 1417 | (let ((cursor-location (point)) ; retain cursor location |
| 1421 | (word (ispell-get-word following)) | 1418 | (word (ispell-get-word following)) |
diff --git a/lisp/textmodes/table.el b/lisp/textmodes/table.el index 7b13d498b2e..f064dd4dee0 100644 --- a/lisp/textmodes/table.el +++ b/lisp/textmodes/table.el | |||
| @@ -645,7 +645,8 @@ See `table-insert' for examples about how to use." | |||
| 645 | :group 'editing | 645 | :group 'editing |
| 646 | :group 'wp | 646 | :group 'wp |
| 647 | :group 'paragraphs | 647 | :group 'paragraphs |
| 648 | :group 'fill) | 648 | :group 'fill |
| 649 | :version "21.4") | ||
| 649 | 650 | ||
| 650 | (defgroup table-hooks nil | 651 | (defgroup table-hooks nil |
| 651 | "Hooks for table manipulation utilities" | 652 | "Hooks for table manipulation utilities" |
diff --git a/lisp/textmodes/texinfo.el b/lisp/textmodes/texinfo.el index 8e5b94114a3..54c9d6ad7db 100644 --- a/lisp/textmodes/texinfo.el +++ b/lisp/textmodes/texinfo.el | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | ;;; texinfo.el --- major mode for editing Texinfo files | 1 | ;;; texinfo.el --- major mode for editing Texinfo files |
| 2 | 2 | ||
| 3 | ;; Copyright (C) 1985,88,89,90,91,92,93,96,97,2000,01,03,04 | 3 | ;; Copyright (C) 1985, 1988, 1989, 1990, 1991, 1992, 1993, 1996, 1997, |
| 4 | ;; Free Software Foundation, Inc. | 4 | ;; 2000, 2001, 2003, 2004 Free Software Foundation, Inc. |
| 5 | 5 | ||
| 6 | ;; Author: Robert J. Chassell | 6 | ;; Author: Robert J. Chassell |
| 7 | ;; Date: [See date below for texinfo-version] | 7 | ;; Date: [See date below for texinfo-version] |