comparison lisp/textmodes/bibtex.el @ 57054:0b058857c704

(bibtex-mark-active, bibtex-run-with-idle-timer): Move `if' inside the defun. (bibtex-autokey-titleword-ignore): Regexp is used in a case insensitive env. (bibtex-mode-map): Rearrange order of menus. (bibtex-quoted-string-re): Obsolete. (bibtex-complete-key-cleanup): Variable replaced by new function. (bibtex-font-lock-keywords): Use backquotes. (bibtex-font-lock-url-regexp): New internal variable. (bibtex-name-in-field): New opt arg remove-opt-alt to remove "OPT" and "ALT". (bibtex-insert-current-kill, bibtex-make-field) (bibtex-prepare-new-entry, bibtex-yank-pop, bibtex-String): Use unless. (bibtex-parse-field-text): Simplify. (bibtex-string=): New helper function. (bibtex-member-of-regexp): Merge with bibtex-autokey-get-title. (bibtex-map-entries): Use bibtex-string=. (bibtex-search-entry): Use not. (bibtex-enclosing-field): Fix docstring. (bibtex-assoc-regexp): Obsolete. (bibtex-format-entry): Use assoc-string and bibtex-string=. (bibtex-autokey-get-names): Handle empty name field. (bibtex-parse-strings): Use assoc-string and unless. (bibtex-complete-string-cleanup): Expansion list is passed as an argument. Use assoc-string. (bibtex-pop): Simplify. (bibtex-mode): Set font-lock-extra-managed-props. (bibtex-entry-update): Use assoc-string. (bibtex-parse-entry): Remove "OPT" and "ALT" from FIELD. (bibtex-autofill-entry): Use bibtex-string=. (bibtex-print-help-message): Simplify. (bibtex-find-entry): New optional arg START. (bibtex-validate): Use bibtex-string= and assoc-string. Do not call obsolete function compilation-parse-errors. (bibtex-remove-delimiters): Only remove delimiters if present. (bibtex-copy-entry-as-kill): Add docstring. (bibtex-clean-entry): Use bibtex-string=. Handle empty keys. Detect duplicate keys if bibtex-maintain-sorted-entries is nil. (bibtex-complete): Use bibtex-predefined-month-strings, bibtex-string=, and new function bibtex-complete-key-cleanup. (bibtex-generate-url-list): New variable. (bibtex-url): New command bound to C-c C-l and mouse-2. (bibtex-url-map): New local keymap for bibtex-url-mouse. (bibtex-font-lock-url): New function.
author Stefan Monnier <monnier@iro.umontreal.ca>
date Fri, 10 Sep 2004 21:24:50 +0000
parents 1b2cb608f18e
children 3d9707888790
comparison
equal deleted inserted replaced
57053:abdfb8ccbb2b 57054:0b058857c704
638 :group 'bibtex-autokey 638 :group 'bibtex-autokey
639 :type 'integer) 639 :type 'integer)
640 640
641 (defcustom bibtex-autokey-titleword-ignore 641 (defcustom bibtex-autokey-titleword-ignore
642 '("A" "An" "On" "The" "Eine?" "Der" "Die" "Das" 642 '("A" "An" "On" "The" "Eine?" "Der" "Die" "Das"
643 "[^A-Z].*" ".*[^a-zA-Z0-9].*") 643 "[^A-Z].*" ".*[^A-Z0-9].*")
644 "*Determines words from the title that are not to be used in the key. 644 "*Determines words from the title that are not to be used in the key.
645 Each item of the list is a regexp. If a word of the title matchs a 645 Each item of the list is a regexp. If a word of the title matchs a
646 regexp from that list, it is not included in the title part of the key. 646 regexp from that list, it is not included in the title part of the key.
647 See `bibtex-generate-autokey' for details." 647 See `bibtex-generate-autokey' for details."
648 :group 'bibtex-autokey 648 :group 'bibtex-autokey
760 760
761 (defcustom bibtex-autofill-types '("Proceedings") 761 (defcustom bibtex-autofill-types '("Proceedings")
762 "Automatically fill fields if possible for those BibTeX entry types." 762 "Automatically fill fields if possible for those BibTeX entry types."
763 :type '(repeat string)) 763 :type '(repeat string))
764 764
765 (defcustom bibtex-complete-key-cleanup nil 765 (defcustom bibtex-generate-url-list
766 "*Function called by `bibtex-complete' after insertion of a key fragment." 766 '((("url" . t) ("url" t)))
767 :group 'bibtex-autokey 767 "List of schemes for generating the URL of a BibTeX entry.
768 :type '(choice (const :tag "None" nil) 768 These schemes are used by `bibtex-url'.
769 (function :tag "Cleanup function"))) 769
770 Each scheme is of the form ((FIELD . REGEXP) STEPS).
771
772 FIELD is a field name as returned by `bibtex-parse-entry'.
773 REGEXP is matched against the text of FIELD.
774 If the match succeeds, the list STEPS is used to generate the URL.
775 If REGEXP is t, always generate the URL if FIELD is present.
776
777 If an element of STEPS is a list (FIELD MATCH FILTER),
778 the text of FIELD is matched against MATCH.
779 If MATCH is t, the text of FIELD is accepted as is.
780 If MATCH is a cons cell (REGEXP . REPLACE), the text is matched against REGEXP.
781 If REPLACE is a string, the text is replaced with REPLACE. If REPLACE is a
782 number, it specifies which parenthesized expression in the match is taken.
783 The optional element FILTER is a function for piping the match through it.
784 The text strings are then concatenated to generate the URL.
785
786 If an element of STEPS is a string, it is simply added to the URL.
787
788 Case is always ignored. Always remove the field delimiters."
789 :group 'bibtex
790 :type '(repeat
791 (list :tag "Scheme"
792 (cons :tag "Matcher" :extra-offset 4
793 (string :tag "BibTeX field")
794 (choice (regexp :tag "Regexp")
795 (const :tag "Accept as is" t)))
796 (repeat :tag "Steps to generate URL" :inline t
797 (choice
798 (string :tag "Literal text")
799 (list (string :tag "BibTeX field")
800 (choice (const :tag "Accept as is" t)
801 (cons (string :tag "Field")
802 (choice (regexp :tag "Regexp")
803 (integer :tag "Matched parenthesis"))))
804 (option (function :tag "Filter" :value ignore))))))))
770 805
771 ;; bibtex-font-lock-keywords is a user option as well, but since the 806 ;; bibtex-font-lock-keywords is a user option as well, but since the
772 ;; patterns used to define this variable are defined in a later 807 ;; patterns used to define this variable are defined in a later
773 ;; section of this file, it is defined later. 808 ;; section of this file, it is defined later.
774 809
799 (define-key km "\C-c\"" 'bibtex-remove-delimiters) 834 (define-key km "\C-c\"" 'bibtex-remove-delimiters)
800 (define-key km "\C-c{" 'bibtex-remove-delimiters) 835 (define-key km "\C-c{" 'bibtex-remove-delimiters)
801 (define-key km "\C-c}" 'bibtex-remove-delimiters) 836 (define-key km "\C-c}" 'bibtex-remove-delimiters)
802 (define-key km "\C-c\C-c" 'bibtex-clean-entry) 837 (define-key km "\C-c\C-c" 'bibtex-clean-entry)
803 (define-key km "\C-c\C-q" 'bibtex-fill-entry) 838 (define-key km "\C-c\C-q" 'bibtex-fill-entry)
839 (define-key km "\C-c\C-s" 'bibtex-find-entry)
804 (define-key km "\C-c?" 'bibtex-print-help-message) 840 (define-key km "\C-c?" 'bibtex-print-help-message)
805 (define-key km "\C-c\C-p" 'bibtex-pop-previous) 841 (define-key km "\C-c\C-p" 'bibtex-pop-previous)
806 (define-key km "\C-c\C-n" 'bibtex-pop-next) 842 (define-key km "\C-c\C-n" 'bibtex-pop-next)
807 (define-key km "\C-c\C-k" 'bibtex-kill-field) 843 (define-key km "\C-c\C-k" 'bibtex-kill-field)
808 (define-key km "\C-c\M-k" 'bibtex-copy-field-as-kill) 844 (define-key km "\C-c\M-k" 'bibtex-copy-field-as-kill)
819 (define-key km "\C-\M-l" 'bibtex-reposition-window) 855 (define-key km "\C-\M-l" 'bibtex-reposition-window)
820 (define-key km "\C-\M-h" 'bibtex-mark-entry) 856 (define-key km "\C-\M-h" 'bibtex-mark-entry)
821 (define-key km "\C-c\C-b" 'bibtex-entry) 857 (define-key km "\C-c\C-b" 'bibtex-entry)
822 (define-key km "\C-c\C-rn" 'bibtex-narrow-to-entry) 858 (define-key km "\C-c\C-rn" 'bibtex-narrow-to-entry)
823 (define-key km "\C-c\C-rw" 'widen) 859 (define-key km "\C-c\C-rw" 'widen)
860 (define-key km "\C-c\C-l" 'bibtex-url)
824 (define-key km "\C-c\C-o" 'bibtex-remove-OPT-or-ALT) 861 (define-key km "\C-c\C-o" 'bibtex-remove-OPT-or-ALT)
825 (define-key km "\C-c\C-e\C-i" 'bibtex-InProceedings) 862 (define-key km "\C-c\C-e\C-i" 'bibtex-InProceedings)
826 (define-key km "\C-c\C-ei" 'bibtex-InCollection) 863 (define-key km "\C-c\C-ei" 'bibtex-InCollection)
827 (define-key km "\C-c\C-eI" 'bibtex-InBook) 864 (define-key km "\C-c\C-eI" 'bibtex-InBook)
828 (define-key km "\C-c\C-e\C-a" 'bibtex-Article) 865 (define-key km "\C-c\C-e\C-a" 'bibtex-Article)
852 ["Beginning of Entry" bibtex-beginning-of-entry t] 889 ["Beginning of Entry" bibtex-beginning-of-entry t]
853 ["End of Entry" bibtex-end-of-entry t]) 890 ["End of Entry" bibtex-end-of-entry t])
854 ("Moving in BibTeX Buffer" 891 ("Moving in BibTeX Buffer"
855 ["Find Entry" bibtex-find-entry t] 892 ["Find Entry" bibtex-find-entry t]
856 ["Find Crossref Entry" bibtex-find-crossref t]) 893 ["Find Crossref Entry" bibtex-find-crossref t])
857 ("Operating on Current Entry"
858 ["Fill Entry" bibtex-fill-entry t]
859 ["Clean Entry" bibtex-clean-entry t]
860 "--" 894 "--"
861 ["Kill Entry" bibtex-kill-entry t]
862 ["Copy Entry to Kill Ring" bibtex-copy-entry-as-kill t]
863 ["Paste Most Recently Killed Entry" bibtex-yank t]
864 ["Paste Previously Killed Entry" bibtex-yank-pop t]
865 "--"
866 ["Ispell Entry" bibtex-ispell-entry t]
867 ["Ispell Entry Abstract" bibtex-ispell-abstract t]
868 ["Narrow to Entry" bibtex-narrow-to-entry t]
869 "--"
870 ["View Cite Locations (RefTeX)" reftex-view-crossref-from-bibtex
871 (fboundp 'reftex-view-crossref-from-bibtex)])
872 ("Operating on Current Field" 895 ("Operating on Current Field"
873 ["Fill Field" fill-paragraph t] 896 ["Fill Field" fill-paragraph t]
874 ["Remove Delimiters" bibtex-remove-delimiters t] 897 ["Remove Delimiters" bibtex-remove-delimiters t]
875 ["Remove OPT or ALT Prefix" bibtex-remove-OPT-or-ALT t] 898 ["Remove OPT or ALT Prefix" bibtex-remove-OPT-or-ALT t]
876 ["Clear Field" bibtex-empty-field t] 899 ["Clear Field" bibtex-empty-field t]
886 ["Snatch from Similar Preceding Field" bibtex-pop-previous t] 909 ["Snatch from Similar Preceding Field" bibtex-pop-previous t]
887 "--" 910 "--"
888 ["String or Key Complete" bibtex-complete t] 911 ["String or Key Complete" bibtex-complete t]
889 "--" 912 "--"
890 ["Help about Current Field" bibtex-print-help-message t]) 913 ["Help about Current Field" bibtex-print-help-message t])
914 ("Operating on Current Entry"
915 ["Fill Entry" bibtex-fill-entry t]
916 ["Clean Entry" bibtex-clean-entry t]
917 ["Update Entry" bibtex-entry-update t]
918 "--"
919 ["Kill Entry" bibtex-kill-entry t]
920 ["Copy Entry to Kill Ring" bibtex-copy-entry-as-kill t]
921 ["Paste Most Recently Killed Entry" bibtex-yank t]
922 ["Paste Previously Killed Entry" bibtex-yank-pop t]
923 "--"
924 ["Ispell Entry" bibtex-ispell-entry t]
925 ["Ispell Entry Abstract" bibtex-ispell-abstract t]
926 ["Narrow to Entry" bibtex-narrow-to-entry t]
927 "--"
928 ["View Cite Locations (RefTeX)" reftex-view-crossref-from-bibtex
929 (fboundp 'reftex-view-crossref-from-bibtex)])
891 ("Operating on Buffer or Region" 930 ("Operating on Buffer or Region"
892 ["Validate Entries" bibtex-validate t] 931 ["Validate Entries" bibtex-validate t]
893 ["Sort Entries" bibtex-sort-buffer t] 932 ["Sort Entries" bibtex-sort-buffer t]
894 ["Reformat Entries" bibtex-reformat t] 933 ["Reformat Entries" bibtex-reformat t]
895 ["Count Entries" bibtex-count-entries t]) 934 ["Count Entries" bibtex-count-entries t]
896 ("Miscellaneous" 935 "--"
897 ["Convert Alien Buffer" bibtex-convert-alien t]))) 936 ["Convert Alien Buffer" bibtex-convert-alien t])))
898 937
899 (easy-menu-define 938 (easy-menu-define
900 bibtex-entry-menu bibtex-mode-map "Entry-Types Menu in BibTeX mode" 939 bibtex-entry-menu bibtex-mode-map "Entry-Types Menu in BibTeX mode"
901 (list "Entry-Types" 940 (list "Entry-Types"
913 ["Unpublished" bibtex-Unpublished t] 952 ["Unpublished" bibtex-Unpublished t]
914 ["Miscellaneous" bibtex-Misc t] 953 ["Miscellaneous" bibtex-Misc t]
915 ["String" bibtex-String t] 954 ["String" bibtex-String t]
916 ["Preamble" bibtex-Preamble t])) 955 ["Preamble" bibtex-Preamble t]))
917 956
957 (defvar bibtex-url-map
958 (let ((km (make-sparse-keymap)))
959 (define-key km [(mouse-2)] 'bibtex-url)
960 km)
961 "Local keymap for clickable URLs.")
962 (fset 'bibtex-url-map bibtex-url-map)
963
918 964
919 ;; Internal Variables 965 ;; Internal Variables
920 966
921 (defvar bibtex-pop-previous-search-point nil 967 (defvar bibtex-pop-previous-search-point nil
922 "Next point where `bibtex-pop-previous' starts looking for a similar entry.") 968 "Next point where `bibtex-pop-previous' starts looking for a similar entry.")
1038 1084
1039 1085
1040 (defconst bibtex-empty-field-re "\"\"\\|{}" 1086 (defconst bibtex-empty-field-re "\"\"\\|{}"
1041 "Regexp matching an empty field.") 1087 "Regexp matching an empty field.")
1042 1088
1043 (defconst bibtex-quoted-string-re
1044 (concat "\""
1045 "\\("
1046 "[^\"\\]" ; anything but quote or backslash
1047 "\\|"
1048 "\\("
1049 "\\\\\\(.\\|\n\\)" ; any backslash quoted character
1050 "\\)"
1051 "\\)*"
1052 "\"")
1053 "Regexp matching a field string enclosed by quotes.")
1054
1055 (defconst bibtex-font-lock-syntactic-keywords 1089 (defconst bibtex-font-lock-syntactic-keywords
1056 `((,(concat "^[ \t]*\\(" (substring bibtex-comment-start 0 1) "\\)" 1090 `((,(concat "^[ \t]*\\(" (substring bibtex-comment-start 0 1) "\\)"
1057 (substring bibtex-comment-start 1) "\\>") 1091 (substring bibtex-comment-start 1) "\\>")
1058 1 '(11)))) 1092 1 '(11))))
1059 1093
1060 (defvar bibtex-font-lock-keywords 1094 (defvar bibtex-font-lock-keywords
1061 (list 1095 ;; entry type and reference key
1062 ;; entry type and reference key 1096 `((,bibtex-entry-maybe-empty-head
1063 (list bibtex-entry-maybe-empty-head 1097 (,bibtex-type-in-head font-lock-function-name-face)
1064 (list bibtex-type-in-head 'font-lock-function-name-face) 1098 (,bibtex-key-in-head font-lock-constant-face nil t))
1065 (list bibtex-key-in-head 'font-lock-constant-face nil t)) 1099 ;; optional field names (treated as comments)
1066 ;; optional field names (treated as comments) 1100 (,(concat "^[ \t]*\\(OPT" bibtex-field-name "\\)[ \t]*=")
1067 (list 1101 1 font-lock-comment-face)
1068 (concat "^[ \t]*\\(OPT" bibtex-field-name "\\)[ \t]*=") 1102 ;; field names
1069 1 'font-lock-comment-face) 1103 (,(concat "^[ \t]*\\(" bibtex-field-name "\\)[ \t]*=")
1070 ;; field names 1104 1 font-lock-variable-name-face)
1071 (list (concat "^[ \t]*\\(" bibtex-field-name "\\)[ \t]*=") 1105 ;; url
1072 1 'font-lock-variable-name-face)) 1106 (bibtex-font-lock-url 0 '(face nil mouse-face highlight
1107 keymap bibtex-url-map)))
1073 "*Default expressions to highlight in BibTeX mode.") 1108 "*Default expressions to highlight in BibTeX mode.")
1109
1110 (defvar bibtex-font-lock-url-regexp
1111 (concat "\\<" (regexp-opt (mapcar 'caar bibtex-generate-url-list) t)
1112 "\\>[ \t]*=[ \t]*")
1113 "Regexp for `bibtex-font-lock-url'.")
1074 1114
1075 (defvar bibtex-field-name-for-parsing nil 1115 (defvar bibtex-field-name-for-parsing nil
1076 "Temporary variable storing the name string to be parsed by the callback 1116 "Temporary variable storing the name string to be parsed by the callback
1077 function `bibtex-parse-field-name'.") 1117 function `bibtex-parse-field-name'.")
1078 1118
1087 `bibtex-maintain-sorted-entries' is `entry-class'.") 1127 `bibtex-maintain-sorted-entries' is `entry-class'.")
1088 1128
1089 1129
1090 ;; Special support taking care of variants 1130 ;; Special support taking care of variants
1091 (defvar zmacs-regions) 1131 (defvar zmacs-regions)
1092 (if (boundp 'mark-active) 1132 (defalias 'bibtex-mark-active
1093 (defun bibtex-mark-active () 1133 (if (boundp 'mark-active)
1094 ;; In Emacs mark-active indicates if mark is active. 1134 ;; In Emacs mark-active indicates if mark is active.
1095 mark-active) 1135 (lambda () mark-active)
1096 (defun bibtex-mark-active ()
1097 ;; In XEmacs (mark) returns nil when not active. 1136 ;; In XEmacs (mark) returns nil when not active.
1098 (if zmacs-regions (mark) (mark t)))) 1137 (lambda () (if zmacs-regions (mark) (mark t)))))
1099 1138
1100 (if (fboundp 'run-with-idle-timer) 1139 (defalias 'bibtex-run-with-idle-timer
1101 ;; timer.el is distributed with Emacs 1140 (if (fboundp 'run-with-idle-timer)
1102 (fset 'bibtex-run-with-idle-timer 'run-with-idle-timer) 1141 ;; timer.el is distributed with Emacs
1103 ;; timer.el is not distributed with XEmacs 1142 'run-with-idle-timer
1104 ;; Notice that this does not (yet) pass the arguments, but they 1143 ;; timer.el is not distributed with XEmacs
1105 ;; are not used (yet) in bibtex.el. Fix if needed. 1144 ;; Notice that this does not (yet) pass the arguments, but they
1106 (defun bibtex-run-with-idle-timer (secs repeat function &rest args) 1145 ;; are not used (yet) in bibtex.el. Fix if needed.
1107 (start-itimer "bibtex" function secs (if repeat secs nil) t))) 1146 (lambda (secs repeat function &rest args)
1147 (start-itimer "bibtex" function secs (if repeat secs nil) t))))
1108 1148
1109 1149
1110 ;; Support for hideshow minor mode 1150 ;; Support for hideshow minor mode
1111 (defun bibtex-hs-forward-sexp (arg) 1151 (defun bibtex-hs-forward-sexp (arg)
1112 "Replacement for `forward-sexp' to be used by `hs-minor-mode'." 1152 "Replacement for `forward-sexp' to be used by `hs-minor-mode'."
1213 (cond ((looking-at bibtex-field-const) 1253 (cond ((looking-at bibtex-field-const)
1214 (goto-char (match-end 0))) 1254 (goto-char (match-end 0)))
1215 ((setq boundaries (bibtex-parse-field-string)) 1255 ((setq boundaries (bibtex-parse-field-string))
1216 (goto-char (cdr boundaries))) 1256 (goto-char (cdr boundaries)))
1217 ((setq failure t))) 1257 ((setq failure t)))
1218 (if (not (looking-at "[ \t\n]*#[ \t\n]*")) 1258 (if (looking-at "[ \t\n]*#[ \t\n]*")
1219 (setq end-point (point)) 1259 (goto-char (match-end 0))
1220 (goto-char (match-end 0)))) 1260 (setq end-point (point))))
1221 (if (and (not failure) 1261 (if (and (not failure)
1222 end-point) 1262 end-point)
1223 (cons starting-point end-point)))) 1263 (cons starting-point end-point))))
1224 1264
1225 (defun bibtex-parse-field (name) 1265 (defun bibtex-parse-field (name)
1292 (defsubst bibtex-start-of-text-in-field (bounds) 1332 (defsubst bibtex-start-of-text-in-field (bounds)
1293 (cadr bounds)) 1333 (cadr bounds))
1294 (defsubst bibtex-end-of-text-in-field (bounds) 1334 (defsubst bibtex-end-of-text-in-field (bounds)
1295 (cddr bounds)) 1335 (cddr bounds))
1296 1336
1297 (defun bibtex-name-in-field (bounds) 1337 (defun bibtex-name-in-field (bounds &optional remove-opt-alt)
1298 "Get content of name in BibTeX field defined via BOUNDS." 1338 "Get content of name in BibTeX field defined via BOUNDS.
1299 (buffer-substring-no-properties (nth 1 (car bounds)) 1339 If optional arg REMOVE-OPT-ALT is non-nil remove \"OPT\" and \"ALT\"."
1300 (nth 2 (car bounds)))) 1340 (let ((name (buffer-substring-no-properties (nth 1 (car bounds))
1341 (nth 2 (car bounds)))))
1342 (if (and remove-opt-alt
1343 (string-match "\\`\\(OPT\\|ALT\\)" name))
1344 (substring name 3)
1345 name)))
1301 1346
1302 (defun bibtex-text-in-field-bounds (bounds &optional remove-delim) 1347 (defun bibtex-text-in-field-bounds (bounds &optional remove-delim)
1303 "Get content of text in BibTeX field defined via BOUNDS. 1348 "Get content of text in BibTeX field defined via BOUNDS.
1304 If optional arg REMOVE-DELIM is non-nil remove enclosing field delimiters 1349 If optional arg REMOVE-DELIM is non-nil remove enclosing field delimiters
1305 if present." 1350 if present."
1436 (match-end bibtex-key-in-head)) 1481 (match-end bibtex-key-in-head))
1437 empty)) 1482 empty))
1438 1483
1439 ;; Helper Functions 1484 ;; Helper Functions
1440 1485
1486 (defsubst bibtex-string= (str1 str2)
1487 "Return t if two strings are equal, ignoring case."
1488 (eq t (compare-strings str1 0 nil str2 0 nil t)))
1489
1441 (defun bibtex-delete-whitespace () 1490 (defun bibtex-delete-whitespace ()
1442 "Delete all whitespace starting at point." 1491 "Delete all whitespace starting at point."
1443 (if (looking-at "[ \t\n]+") 1492 (if (looking-at "[ \t\n]+")
1444 (delete-region (point) (match-end 0)))) 1493 (delete-region (point) (match-end 0))))
1445 1494
1446 (defun bibtex-current-line () 1495 (defun bibtex-current-line ()
1447 "Compute line number of point regardless whether the buffer is narrowed." 1496 "Compute line number of point regardless whether the buffer is narrowed."
1448 (+ (count-lines 1 (point)) 1497 (+ (count-lines 1 (point))
1449 (if (equal (current-column) 0) 1 0))) 1498 (if (equal (current-column) 0) 1 0)))
1450
1451 (defun bibtex-member-of-regexp (string list)
1452 "Return non-nil if STRING is exactly matched by an element of LIST.
1453 The value is actually the tail of LIST whose car matches STRING."
1454 (let (case-fold-search)
1455 (while (and list
1456 (not (string-match (concat "\\`\\(?:" (car list) "\\)\\'") string)))
1457 (setq list (cdr list)))
1458 list))
1459 1499
1460 (defun bibtex-skip-to-valid-entry (&optional backward) 1500 (defun bibtex-skip-to-valid-entry (&optional backward)
1461 "Unless at beginning of a valid BibTeX entry, move point to beginning of the 1501 "Unless at beginning of a valid BibTeX entry, move point to beginning of the
1462 next valid one. With optional argument BACKWARD non-nil, move backward to 1502 next valid one. With optional argument BACKWARD non-nil, move backward to
1463 beginning of previous valid one. A valid entry is a syntactical correct one 1503 beginning of previous valid one. A valid entry is a syntactical correct one
1499 (key (bibtex-key-in-head "")) 1539 (key (bibtex-key-in-head ""))
1500 (beg (copy-marker (match-beginning 0))) 1540 (beg (copy-marker (match-beginning 0)))
1501 (end (copy-marker (save-excursion (bibtex-end-of-entry))))) 1541 (end (copy-marker (save-excursion (bibtex-end-of-entry)))))
1502 (save-excursion 1542 (save-excursion
1503 (if (or (and (not bibtex-sort-ignore-string-entries) 1543 (if (or (and (not bibtex-sort-ignore-string-entries)
1504 (string-equal "string" (downcase entry-type))) 1544 (bibtex-string= entry-type "string"))
1505 (assoc-string entry-type bibtex-entry-field-alist t)) 1545 (assoc-string entry-type bibtex-entry-field-alist t))
1506 (funcall fun key beg end))) 1546 (funcall fun key beg end)))
1507 (goto-char end))))) 1547 (goto-char end)))))
1508 1548
1509 (defun bibtex-progress-message (&optional flag interval) 1549 (defun bibtex-progress-message (&optional flag interval)
1573 (re-search-backward entry-head-re bound noerror)) 1613 (re-search-backward entry-head-re bound noerror))
1574 (setq found (bibtex-search-entry empty-head pnt t))) 1614 (setq found (bibtex-search-entry empty-head pnt t)))
1575 (if found 1615 (if found
1576 (progn (goto-char (match-beginning 0)) 1616 (progn (goto-char (match-beginning 0))
1577 found) 1617 found)
1578 (cond ((equal noerror nil) 1618 (cond ((not noerror)
1579 ;; yell 1619 ;; yell
1580 (error "Backward search of BibTeX entry failed")) 1620 (error "Backward search of BibTeX entry failed"))
1581 ((equal noerror t) 1621 ((equal noerror t)
1582 ;; don't move 1622 ;; don't move
1583 (goto-char pnt))) 1623 (goto-char pnt)))
1682 (if (or (= (preceding-char) ?}) 1722 (if (or (= (preceding-char) ?})
1683 (= (preceding-char) ?\")) 1723 (= (preceding-char) ?\"))
1684 (forward-char -1))) 1724 (forward-char -1)))
1685 1725
1686 (defun bibtex-enclosing-field (&optional noerr) 1726 (defun bibtex-enclosing-field (&optional noerr)
1687 "Search for BibTeX field enclosing point. Point moves to end of field. 1727 "Search for BibTeX field enclosing point.
1688 Use `match-beginning' and `match-end' to parse the field. If NOERR is non-nil, 1728 Use `match-beginning' and `match-end' to parse the field. If NOERR is non-nil,
1689 no error is signalled. In this case, bounds are returned on success, 1729 no error is signalled. In this case, bounds are returned on success,
1690 nil otherwise." 1730 nil otherwise. Does not move point."
1691 (let ((bounds (bibtex-search-backward-field bibtex-field-name t))) 1731 (let ((bounds (bibtex-search-backward-field bibtex-field-name t)))
1692 (if (and bounds 1732 (if (and bounds
1693 (<= (bibtex-start-of-field bounds) (point)) 1733 (<= (bibtex-start-of-field bounds) (point))
1694 (>= (bibtex-end-of-field bounds) (point))) 1734 (>= (bibtex-end-of-field bounds) (point)))
1695 bounds 1735 bounds
1730 (forward-char))) 1770 (forward-char)))
1731 (set-mark (point)) 1771 (set-mark (point))
1732 (message "Mark set") 1772 (message "Mark set")
1733 (bibtex-make-field (list (elt current 1) nil (elt current 2)) t)) 1773 (bibtex-make-field (list (elt current 1) nil (elt current 2)) t))
1734 ((equal bibtex-last-kill-command 'entry) 1774 ((equal bibtex-last-kill-command 'entry)
1735 (if (not (eobp)) 1775 (unless (eobp) (bibtex-beginning-of-entry))
1736 (bibtex-beginning-of-entry))
1737 (set-mark (point)) 1776 (set-mark (point))
1738 (message "Mark set") 1777 (message "Mark set")
1739 (insert (elt current 1))) 1778 (insert (elt current 1)))
1740 (t 1779 (t
1741 (error "Unknown tag field: %s. Please submit a bug report" 1780 (error "Unknown tag field: %s. Please submit a bug report"
1742 bibtex-last-kill-command)))))) 1781 bibtex-last-kill-command))))))
1743
1744 (defun bibtex-assoc-regexp (regexp alist)
1745 "Return non-nil if REGEXP matches the car of an element of ALIST.
1746 The value is actually the element of ALIST matched by REGEXP.
1747 Case is ignored if `case-fold-search' is non-nil in the current buffer."
1748 (while (and alist
1749 (not (string-match regexp (caar alist))))
1750 (setq alist (cdr alist)))
1751 (car alist))
1752 1782
1753 (defun bibtex-format-entry () 1783 (defun bibtex-format-entry ()
1754 "Helper function for `bibtex-clean-entry'. 1784 "Helper function for `bibtex-clean-entry'.
1755 Formats current entry according to variable `bibtex-entry-format'." 1785 Formats current entry according to variable `bibtex-entry-format'."
1756 (save-excursion 1786 (save-excursion
1762 numerical-fields 1792 numerical-fields
1763 last-comma page-dashes delimiters 1793 last-comma page-dashes delimiters
1764 unify-case inherit-booktitle) 1794 unify-case inherit-booktitle)
1765 bibtex-entry-format)) 1795 bibtex-entry-format))
1766 crossref-key bounds alternatives-there non-empty-alternative 1796 crossref-key bounds alternatives-there non-empty-alternative
1767 entry-list req-field-list field-done field-list) 1797 entry-list req-field-list field-list)
1768 1798
1769 ;; identify entry type 1799 ;; identify entry type
1770 (goto-char (point-min)) 1800 (goto-char (point-min))
1771 (re-search-forward bibtex-entry-type) 1801 (re-search-forward bibtex-entry-type)
1772 (let ((beg-type (1+ (match-beginning 0))) 1802 (let ((beg-type (1+ (match-beginning 0)))
1790 1820
1791 ;; determine if entry has crossref field and if at least 1821 ;; determine if entry has crossref field and if at least
1792 ;; one alternative is non-empty 1822 ;; one alternative is non-empty
1793 (goto-char (point-min)) 1823 (goto-char (point-min))
1794 (let* ((fields-alist (bibtex-parse-entry)) 1824 (let* ((fields-alist (bibtex-parse-entry))
1795 (case-fold-search t) 1825 (field (assoc-string "crossref" fields-alist t)))
1796 (field (bibtex-assoc-regexp "\\`\\(OPT\\)?crossref\\'"
1797 fields-alist)))
1798 (setq crossref-key (and field 1826 (setq crossref-key (and field
1799 (not (string-match bibtex-empty-field-re 1827 (not (string-match bibtex-empty-field-re
1800 (cdr field))) 1828 (cdr field)))
1801 (cdr field)) 1829 (cdr field))
1802 req-field-list (if crossref-key 1830 req-field-list (if crossref-key
1804 (nth 0 (nth 1 entry-list)))) ; required part 1832 (nth 0 (nth 1 entry-list)))) ; required part
1805 1833
1806 (dolist (rfield req-field-list) 1834 (dolist (rfield req-field-list)
1807 (when (nth 3 rfield) ; we should have an alternative 1835 (when (nth 3 rfield) ; we should have an alternative
1808 (setq alternatives-there t 1836 (setq alternatives-there t
1809 field (bibtex-assoc-regexp 1837 field (assoc-string (car rfield) fields-alist t))
1810 (concat "\\`\\(ALT\\)?" (car rfield) "\\'")
1811 fields-alist))
1812 (if (and field 1838 (if (and field
1813 (not (string-match bibtex-empty-field-re 1839 (not (string-match bibtex-empty-field-re
1814 (cdr field)))) 1840 (cdr field))))
1815 (cond ((not non-empty-alternative) 1841 (cond ((not non-empty-alternative)
1816 (setq non-empty-alternative t)) 1842 (setq non-empty-alternative t))
1885 (delete-char 1) 1911 (delete-char 1)
1886 (insert (bibtex-field-right-delimiter)))) 1912 (insert (bibtex-field-right-delimiter))))
1887 1913
1888 ;; update page dashes 1914 ;; update page dashes
1889 (if (and (memq 'page-dashes format) 1915 (if (and (memq 'page-dashes format)
1890 (string-match "\\`\\(OPT\\)?pages\\'" field-name) 1916 (bibtex-string= field-name "pages")
1891 (progn (goto-char beg-text) 1917 (progn (goto-char beg-text)
1892 (looking-at 1918 (looking-at
1893 "\\([\"{][0-9]+\\)[ \t\n]*--?[ \t\n]*\\([0-9]+[\"}]\\)"))) 1919 "\\([\"{][0-9]+\\)[ \t\n]*--?[ \t\n]*\\([0-9]+[\"}]\\)")))
1894 (replace-match "\\1-\\2")) 1920 (replace-match "\\1-\\2"))
1895 1921
1896 ;; use book title of crossref'd entry 1922 ;; use book title of crossref'd entry
1897 (if (and (memq 'inherit-booktitle format) 1923 (if (and (memq 'inherit-booktitle format)
1898 empty-field 1924 empty-field
1899 (equal (downcase field-name) "booktitle") 1925 (bibtex-string= field-name "booktitle")
1900 crossref-key) 1926 crossref-key)
1901 (let ((title (save-restriction 1927 (let ((title (save-restriction
1902 (widen) 1928 (widen)
1903 (if (bibtex-find-entry crossref-key) 1929 (if (bibtex-find-entry crossref-key)
1904 (bibtex-text-in-field "title"))))) 1930 (bibtex-text-in-field "title")))))
1907 (goto-char (1+ beg-text)) 1933 (goto-char (1+ beg-text))
1908 (insert title)))) 1934 (insert title))))
1909 1935
1910 ;; Use booktitle to set a missing title. 1936 ;; Use booktitle to set a missing title.
1911 (if (and empty-field 1937 (if (and empty-field
1912 (equal (downcase field-name) "title")) 1938 (bibtex-string= field-name "title"))
1913 (let ((booktitle (bibtex-text-in-field "booktitle"))) 1939 (let ((booktitle (bibtex-text-in-field "booktitle")))
1914 (when booktitle 1940 (when booktitle
1915 (setq empty-field nil) 1941 (setq empty-field nil)
1916 (goto-char (1+ beg-text)) 1942 (goto-char (1+ beg-text))
1917 (insert booktitle)))) 1943 (insert booktitle))))
2021 2047
2022 (defun bibtex-autokey-get-names () 2048 (defun bibtex-autokey-get-names ()
2023 "Get contents of the name field of the current entry. 2049 "Get contents of the name field of the current entry.
2024 Do some modifications based on `bibtex-autokey-name-change-strings' 2050 Do some modifications based on `bibtex-autokey-name-change-strings'
2025 and return results as a list." 2051 and return results as a list."
2026 (let ((case-fold-search t)) 2052 (let ((case-fold-search t)
2027 (mapcar 'bibtex-autokey-demangle-name 2053 (names (bibtex-autokey-get-field "author\\|editor"
2028 (split-string (bibtex-autokey-get-field 2054 bibtex-autokey-name-change-strings)))
2029 "author\\|editor" 2055 ;; Some entries do not have a name field.
2030 bibtex-autokey-name-change-strings) 2056 (unless (string= "" names)
2031 "[ \t\n]+and[ \t\n]+")))) 2057 (mapcar 'bibtex-autokey-demangle-name
2058 (split-string names "[ \t\n]+and[ \t\n]+")))))
2032 2059
2033 (defun bibtex-autokey-demangle-name (fullname) 2060 (defun bibtex-autokey-demangle-name (fullname)
2034 "Get the last part from a well-formed name and perform abbreviations." 2061 "Get the last part from a well-formed name and perform abbreviations."
2035 (let* (case-fold-search 2062 (let* (case-fold-search
2036 (name (cond ((string-match "\\([A-Z][^, ]*\\)[^,]*," fullname) 2063 (name (cond ((string-match "\\([A-Z][^, ]*\\)[^,]*," fullname)
2057 (funcall bibtex-autokey-name-case-convert name) 2084 (funcall bibtex-autokey-name-case-convert name)
2058 bibtex-autokey-name-length))) 2085 bibtex-autokey-name-length)))
2059 2086
2060 (defun bibtex-autokey-get-title () 2087 (defun bibtex-autokey-get-title ()
2061 "Get title field contents up to a terminator." 2088 "Get title field contents up to a terminator."
2062 (let ((titlestring 2089 (let ((case-fold-search t)
2090 (titlestring
2063 (bibtex-autokey-get-field "title" 2091 (bibtex-autokey-get-field "title"
2064 bibtex-autokey-titleword-change-strings))) 2092 bibtex-autokey-titleword-change-strings)))
2065 ;; ignore everything past a terminator 2093 ;; ignore everything past a terminator
2066 (let ((case-fold-search t)) 2094 (dolist (terminator bibtex-autokey-title-terminators)
2067 (dolist (terminator bibtex-autokey-title-terminators) 2095 (if (string-match terminator titlestring)
2068 (if (string-match terminator titlestring) 2096 (setq titlestring (substring titlestring 0 (match-beginning 0)))))
2069 (setq titlestring (substring titlestring 0 (match-beginning 0))))))
2070 ;; gather words from titlestring into a list. Ignore 2097 ;; gather words from titlestring into a list. Ignore
2071 ;; specific words and use only a specific amount of words. 2098 ;; specific words and use only a specific amount of words.
2072 (let ((counter 0) 2099 (let ((counter 0)
2073 case-fold-search titlewords titlewords-extra titleword end-match) 2100 titlewords titlewords-extra titleword end-match)
2074 (while (and (or (not (numberp bibtex-autokey-titlewords)) 2101 (while (and (or (not (numberp bibtex-autokey-titlewords))
2075 (< counter (+ bibtex-autokey-titlewords 2102 (< counter (+ bibtex-autokey-titlewords
2076 bibtex-autokey-titlewords-stretch))) 2103 bibtex-autokey-titlewords-stretch)))
2077 (string-match "\\b\\w+" titlestring)) 2104 (string-match "\\b\\w+" titlestring))
2078 (setq end-match (match-end 0) 2105 (setq end-match (match-end 0)
2079 titleword (substring titlestring 2106 titleword (substring titlestring
2080 (match-beginning 0) end-match)) 2107 (match-beginning 0) end-match))
2081 (unless (bibtex-member-of-regexp titleword 2108 (unless (let ((lst bibtex-autokey-titleword-ignore))
2082 bibtex-autokey-titleword-ignore) 2109 (while (and lst
2110 (not (string-match (concat "\\`\\(?:" (car lst)
2111 "\\)\\'") titleword)))
2112 (setq lst (cdr lst)))
2113 lst)
2083 (setq titleword 2114 (setq titleword
2084 (funcall bibtex-autokey-titleword-case-convert titleword)) 2115 (funcall bibtex-autokey-titleword-case-convert titleword))
2085 (if (or (not (numberp bibtex-autokey-titlewords)) 2116 (if (or (not (numberp bibtex-autokey-titlewords))
2086 (< counter bibtex-autokey-titlewords)) 2117 (< counter bibtex-autokey-titlewords))
2087 (setq titlewords (append titlewords (list titleword))) 2118 (setq titlewords (append titlewords (list titleword)))
2095 2126
2096 (defun bibtex-autokey-demangle-title (titleword) 2127 (defun bibtex-autokey-demangle-title (titleword)
2097 "Do some abbreviations on TITLEWORD. 2128 "Do some abbreviations on TITLEWORD.
2098 The rules are defined in `bibtex-autokey-titleword-abbrevs' 2129 The rules are defined in `bibtex-autokey-titleword-abbrevs'
2099 and `bibtex-autokey-titleword-length'." 2130 and `bibtex-autokey-titleword-length'."
2100 (let ((case-folde-search t) 2131 (let ((case-fold-search t)
2101 (alist bibtex-autokey-titleword-abbrevs)) 2132 (alist bibtex-autokey-titleword-abbrevs))
2102 (while (and alist 2133 (while (and alist
2103 (not (string-match (concat "\\`\\(?:" (caar alist) "\\)\\'") 2134 (not (string-match (concat "\\`\\(?:" (caar alist) "\\)\\'")
2104 titleword))) 2135 titleword)))
2105 (setq alist (cdr alist))) 2136 (setq alist (cdr alist)))
2306 (listp bibtex-strings)) 2337 (listp bibtex-strings))
2307 bibtex-strings)) 2338 bibtex-strings))
2308 bounds key) 2339 bounds key)
2309 (if (listp add) 2340 (if (listp add)
2310 (dolist (string add) 2341 (dolist (string add)
2311 (unless (assoc (car string) strings) 2342 (unless (assoc-string (car string) strings t)
2312 (push string strings)))) 2343 (push string strings))))
2313 (catch 'userkey 2344 (catch 'userkey
2314 (while (setq bounds (bibtex-search-forward-string)) 2345 (while (setq bounds (bibtex-search-forward-string))
2315 (if (and abortable 2346 (if (and abortable
2316 (input-pending-p)) 2347 (input-pending-p))
2317 ;; user has aborted by typing a key --> return `aborted' 2348 ;; user has aborted by typing a key --> return `aborted'
2318 (throw 'userkey 'aborted)) 2349 (throw 'userkey 'aborted))
2319 (setq key (bibtex-reference-key-in-string bounds)) 2350 (setq key (bibtex-reference-key-in-string bounds))
2320 (if (not (assoc key strings)) 2351 (unless (assoc-string key strings t)
2321 (push (cons key (bibtex-text-in-string bounds t)) 2352 (push (cons key (bibtex-text-in-string bounds t))
2322 strings)) 2353 strings))
2323 (goto-char (bibtex-end-of-text-in-string bounds))) 2354 (goto-char (bibtex-end-of-text-in-string bounds)))
2324 ;; successful operation --> return `bibtex-strings' 2355 ;; successful operation --> return `bibtex-strings'
2325 (setq bibtex-strings strings)))))) 2356 (setq bibtex-strings strings))))))
2326 2357
2327 (defun bibtex-string-files-init () 2358 (defun bibtex-string-files-init ()
2407 completions))) 2438 completions)))
2408 (message "Making completion list...done") 2439 (message "Making completion list...done")
2409 ;; return value is handled by choose-completion-string-functions 2440 ;; return value is handled by choose-completion-string-functions
2410 nil)))) 2441 nil))))
2411 2442
2412 (defun bibtex-complete-string-cleanup (str) 2443 (defun bibtex-complete-string-cleanup (str strings-alist)
2413 "Cleanup after inserting string STR. 2444 "Cleanup after inserting string STR.
2414 Remove enclosing field delimiters for string STR. Display message with 2445 Remove enclosing field delimiters for string STR. Display message with
2415 expansion of STR." 2446 expansion of STR using expansion list STRINGS-ALIST."
2416 (let ((pair (assoc str bibtex-strings))) 2447 (let ((pair (if (stringp str)
2448 (assoc-string str strings-alist t))))
2417 (when pair 2449 (when pair
2418 (if (cdr pair) 2450 (if (cdr pair)
2419 (message "Abbreviation for `%s'" (cdr pair))) 2451 (message "Abbreviation for `%s'" (cdr pair)))
2420 (save-excursion 2452 (save-excursion
2421 (bibtex-inside-field) 2453 (bibtex-inside-field)
2424 (let ((boundaries (bibtex-parse-field-string))) 2456 (let ((boundaries (bibtex-parse-field-string)))
2425 (if (and boundaries 2457 (if (and boundaries
2426 (equal (cdr boundaries) 2458 (equal (cdr boundaries)
2427 (bibtex-end-of-text-in-field bounds))) 2459 (bibtex-end-of-text-in-field bounds)))
2428 (bibtex-remove-delimiters)))))))) 2460 (bibtex-remove-delimiters))))))))
2461
2462 (defun bibtex-complete-key-cleanup (key)
2463 "Display message on entry KEY after completion of a crossref key."
2464 (save-excursion
2465 ;; Don't do anything if we completed the key of an entry.
2466 (let ((pnt (bibtex-beginning-of-entry)))
2467 (if (and (stringp key)
2468 (bibtex-find-entry key)
2469 (/= pnt (point)))
2470 (let* ((bibtex-autokey-name-case-convert 'identity)
2471 (bibtex-autokey-name-length 'infty)
2472 (nl (bibtex-autokey-get-names))
2473 (name (concat (nth 0 nl) (if (nth 1 nl) " etal")))
2474 (year (bibtex-autokey-get-field "year"))
2475 (bibtex-autokey-titlewords 5)
2476 (bibtex-autokey-titlewords-stretch 2)
2477 (bibtex-autokey-titleword-case-convert 'identity)
2478 (bibtex-autokey-titleword-length 5)
2479 (title (mapconcat 'identity
2480 (bibtex-autokey-get-title) " "))
2481 (journal (bibtex-autokey-get-field
2482 "journal" bibtex-autokey-transcriptions))
2483 (volume (bibtex-autokey-get-field "volume"))
2484 (pages (bibtex-autokey-get-field "pages" '(("-.*\\'" . "")))))
2485 (message "Ref:%s"
2486 (mapconcat (lambda (arg)
2487 (if (not (string= "" (cdr arg)))
2488 (concat (car arg) (cdr arg))))
2489 `((" " . ,name) (" " . ,year)
2490 (": " . ,title) (", " . ,journal)
2491 (" " . ,volume) (":" . ,pages))
2492 "")))))))
2429 2493
2430 (defun bibtex-choose-completion-string (choice buffer mini-p base-size) 2494 (defun bibtex-choose-completion-string (choice buffer mini-p base-size)
2431 ;; Code borrowed from choose-completion-string: 2495 ;; Code borrowed from choose-completion-string:
2432 ;; We must duplicate the code from choose-completion-string 2496 ;; We must duplicate the code from choose-completion-string
2433 ;; because it runs the hook choose-completion-string-functions 2497 ;; because it runs the hook choose-completion-string-functions
2458 (bibtex-inside-field) 2522 (bibtex-inside-field)
2459 (let* ((case-fold-search t) 2523 (let* ((case-fold-search t)
2460 (bounds (bibtex-enclosing-field)) 2524 (bounds (bibtex-enclosing-field))
2461 (start-old-text (bibtex-start-of-text-in-field bounds)) 2525 (start-old-text (bibtex-start-of-text-in-field bounds))
2462 (stop-old-text (bibtex-end-of-text-in-field bounds)) 2526 (stop-old-text (bibtex-end-of-text-in-field bounds))
2463 (start-name (bibtex-start-of-name-in-field bounds)) 2527 (field-name (bibtex-name-in-field bounds t)))
2464 (stop-name (bibtex-end-of-name-in-field bounds))
2465 ;; construct regexp for field with same name as this one,
2466 ;; ignoring possible OPT's or ALT's
2467 (field-name (progn
2468 (goto-char start-name)
2469 (buffer-substring-no-properties
2470 (if (looking-at "\\(OPT\\)\\|\\(ALT\\)")
2471 (match-end 0)
2472 (point))
2473 stop-name))))
2474 ;; if executed several times in a row, start each search where 2528 ;; if executed several times in a row, start each search where
2475 ;; the last one was finished 2529 ;; the last one was finished
2476 (unless (eq last-command 'bibtex-pop) 2530 (unless (eq last-command 'bibtex-pop)
2477 (bibtex-enclosing-entry-maybe-empty-head) 2531 (bibtex-enclosing-entry-maybe-empty-head)
2478 (setq bibtex-pop-previous-search-point (match-beginning 0) 2532 (setq bibtex-pop-previous-search-point (match-beginning 0)
2637 ;; entries should be fontified in the same way as 2691 ;; entries should be fontified in the same way as
2638 ;; brace-delimited ones 2692 ;; brace-delimited ones
2639 ) 2693 )
2640 nil 2694 nil
2641 (font-lock-syntactic-keywords . bibtex-font-lock-syntactic-keywords) 2695 (font-lock-syntactic-keywords . bibtex-font-lock-syntactic-keywords)
2696 (font-lock-extra-managed-props . (mouse-face keymap))
2642 (font-lock-mark-block-function 2697 (font-lock-mark-block-function
2643 . (lambda () 2698 . (lambda ()
2644 (set-mark (bibtex-end-of-entry)) 2699 (set-mark (bibtex-end-of-entry))
2645 (bibtex-beginning-of-entry))))) 2700 (bibtex-beginning-of-entry)))))
2646 (setq imenu-generic-expression 2701 (setq imenu-generic-expression
2647 (list (list nil bibtex-entry-head bibtex-key-in-head))) 2702 (list (list nil bibtex-entry-head bibtex-key-in-head)))
2648 (make-local-variable 'choose-completion-string-functions) 2703 (make-local-variable 'choose-completion-string-functions)
2649 (setq imenu-case-fold-search t) 2704 (setq imenu-case-fold-search t)
2720 ;; For inserting new fields, we use the fact that 2775 ;; For inserting new fields, we use the fact that
2721 ;; bibtex-parse-entry moves point to the end of the last field. 2776 ;; bibtex-parse-entry moves point to the end of the last field.
2722 (let* ((fields-alist (bibtex-parse-entry)) 2777 (let* ((fields-alist (bibtex-parse-entry))
2723 (field-list (bibtex-field-list 2778 (field-list (bibtex-field-list
2724 (substring (cdr (assoc "=type=" fields-alist)) 2779 (substring (cdr (assoc "=type=" fields-alist))
2725 1))) ; don't want @ 2780 1)))) ; don't want @
2726 (case-fold-search t))
2727 (dolist (field (car field-list)) 2781 (dolist (field (car field-list))
2728 (unless (bibtex-assoc-regexp (concat "\\`\\(ALT\\)?" (car field) "\\'") 2782 (unless (assoc-string (car field) fields-alist t)
2729 fields-alist)
2730 (bibtex-make-field field))) 2783 (bibtex-make-field field)))
2731 (dolist (field (cdr field-list)) 2784 (dolist (field (cdr field-list))
2732 (unless (bibtex-assoc-regexp (concat "\\`\\(OPT\\)?" (car field) "\\'") 2785 (unless (assoc-string (car field) fields-alist t)
2733 fields-alist)
2734 (bibtex-make-optional-field field)))))) 2786 (bibtex-make-optional-field field))))))
2735 2787
2736 (defun bibtex-parse-entry () 2788 (defun bibtex-parse-entry ()
2737 "Parse entry at point, return an alist. 2789 "Parse entry at point, return an alist.
2738 The alist elements have the form (FIELD . TEXT), where FIELD can also be 2790 The alist elements have the form (FIELD . TEXT), where FIELD can also be
2739 the special strings \"=type=\" and \"=key=\". For the FIELD \"=key=\" 2791 the special strings \"=type=\" and \"=key=\". For the FIELD \"=key=\"
2740 TEXT may be nil. Move point to the end of the last field." 2792 TEXT may be nil. Remove \"OPT\" and \"ALT\" from FIELD.
2793 Move point to the end of the last field."
2741 (let (alist bounds) 2794 (let (alist bounds)
2742 (when (looking-at bibtex-entry-maybe-empty-head) 2795 (when (looking-at bibtex-entry-maybe-empty-head)
2743 (push (cons "=type=" (match-string bibtex-type-in-head)) alist) 2796 (push (cons "=type=" (match-string bibtex-type-in-head)) alist)
2744 (push (cons "=key=" (match-string bibtex-key-in-head)) alist) 2797 (push (cons "=key=" (match-string bibtex-key-in-head)) alist)
2745 (goto-char (match-end 0)) 2798 (goto-char (match-end 0))
2746 (while (setq bounds (bibtex-parse-field bibtex-field-name)) 2799 (while (setq bounds (bibtex-parse-field bibtex-field-name))
2747 (push (cons (bibtex-name-in-field bounds) 2800 (push (cons (bibtex-name-in-field bounds t)
2748 (bibtex-text-in-field-bounds bounds)) 2801 (bibtex-text-in-field-bounds bounds))
2749 alist) 2802 alist)
2750 (goto-char (bibtex-end-of-field bounds)))) 2803 (goto-char (bibtex-end-of-field bounds))))
2751 alist)) 2804 alist))
2752 2805
2768 (save-excursion 2821 (save-excursion
2769 (goto-char (1- (match-beginning 0))) 2822 (goto-char (1- (match-beginning 0)))
2770 (bibtex-beginning-of-entry) 2823 (bibtex-beginning-of-entry)
2771 (when (and 2824 (when (and
2772 (looking-at bibtex-entry-head) 2825 (looking-at bibtex-entry-head)
2773 (equal type (match-string bibtex-type-in-head)) 2826 (bibtex-string= type (match-string bibtex-type-in-head))
2774 ;; In case we found ourselves :-( 2827 ;; In case we found ourselves :-(
2775 (not (equal key (setq tmp (match-string bibtex-key-in-head))))) 2828 (not (equal key (setq tmp (match-string bibtex-key-in-head)))))
2776 (setq other-key tmp) 2829 (setq other-key tmp)
2777 (setq other (point)))) 2830 (setq other (point))))
2778 (save-excursion 2831 (save-excursion
2779 (bibtex-end-of-entry) 2832 (bibtex-end-of-entry)
2780 (bibtex-skip-to-valid-entry) 2833 (bibtex-skip-to-valid-entry)
2781 (when (and 2834 (when (and
2782 (looking-at bibtex-entry-head) 2835 (looking-at bibtex-entry-head)
2783 (equal type (match-string bibtex-type-in-head)) 2836 (bibtex-string= type (match-string bibtex-type-in-head))
2784 ;; In case we found ourselves :-( 2837 ;; In case we found ourselves :-(
2785 (not (equal key (setq tmp (match-string bibtex-key-in-head)))) 2838 (not (equal key (setq tmp (match-string bibtex-key-in-head))))
2786 (or (not other-key) 2839 (or (not other-key)
2787 ;; Check which is the best match. 2840 ;; Check which is the best match.
2788 (< (length (try-completion "" (list key other-key))) 2841 (< (length (try-completion "" (list key other-key)))
2792 ;; Then fill the new entry's fields with the chosen other entry. 2845 ;; Then fill the new entry's fields with the chosen other entry.
2793 (when other 2846 (when other
2794 (setq other (save-excursion (goto-char other) (bibtex-parse-entry))) 2847 (setq other (save-excursion (goto-char other) (bibtex-parse-entry)))
2795 (setq key-end (point)) ;In case parse-entry changed the buffer. 2848 (setq key-end (point)) ;In case parse-entry changed the buffer.
2796 (while (setq bounds (bibtex-parse-field bibtex-field-name)) 2849 (while (setq bounds (bibtex-parse-field bibtex-field-name))
2797 (goto-char (bibtex-start-of-name-in-field bounds)) 2850 (let ((text (assoc-string (bibtex-name-in-field bounds t)
2798 (let* ((name (buffer-substring 2851 other t)))
2799 (if (looking-at "ALT\\|OPT") (match-end 0) (point))
2800 (bibtex-end-of-name-in-field bounds)))
2801 (text (assoc-string name other t)))
2802 (goto-char (bibtex-start-of-text-in-field bounds)) 2852 (goto-char (bibtex-start-of-text-in-field bounds))
2803 (if (not (and (looking-at bibtex-empty-field-re) text)) 2853 (if (not (and (looking-at bibtex-empty-field-re) text))
2804 (goto-char (bibtex-end-of-field bounds)) 2854 (goto-char (bibtex-end-of-field bounds))
2805 (delete-region (point) (bibtex-end-of-text-in-field bounds)) 2855 (delete-region (point) (bibtex-end-of-text-in-field bounds))
2806 (insert (cdr text))))) 2856 (insert (cdr text)))))
2819 (defun bibtex-print-help-message () 2869 (defun bibtex-print-help-message ()
2820 "Print helpful information about current field in current BibTeX entry." 2870 "Print helpful information about current field in current BibTeX entry."
2821 (interactive) 2871 (interactive)
2822 (save-excursion 2872 (save-excursion
2823 (let* ((case-fold-search t) 2873 (let* ((case-fold-search t)
2824 (bounds (bibtex-enclosing-field)) 2874 (field-name (bibtex-name-in-field (bibtex-enclosing-field) t))
2825 (mb (bibtex-start-of-name-in-field bounds))
2826 (field-name (buffer-substring-no-properties
2827 (if (progn (goto-char mb)
2828 (looking-at "OPT\\|ALT"))
2829 (match-end 0) mb)
2830 (bibtex-end-of-name-in-field bounds)))
2831 (field-list (bibtex-field-list (progn (re-search-backward 2875 (field-list (bibtex-field-list (progn (re-search-backward
2832 bibtex-entry-maybe-empty-head nil t) 2876 bibtex-entry-maybe-empty-head nil t)
2833 (bibtex-type-in-head)))) 2877 (bibtex-type-in-head))))
2834 (comment (assoc-string field-name 2878 (comment (assoc-string field-name
2835 (append (car field-list) 2879 (append (car field-list)
2866 (insert (car field) " ") 2910 (insert (car field) " ")
2867 (if bibtex-align-at-equal-sign 2911 (if bibtex-align-at-equal-sign
2868 (indent-to-column (+ bibtex-entry-offset 2912 (indent-to-column (+ bibtex-entry-offset
2869 (- bibtex-text-indentation 2)))) 2913 (- bibtex-text-indentation 2))))
2870 (insert "= ") 2914 (insert "= ")
2871 (if (not bibtex-align-at-equal-sign) 2915 (unless bibtex-align-at-equal-sign
2872 (indent-to-column (+ bibtex-entry-offset 2916 (indent-to-column (+ bibtex-entry-offset
2873 bibtex-text-indentation))) 2917 bibtex-text-indentation)))
2874 (if (not called-by-yank) (insert (bibtex-field-left-delimiter))) 2918 (unless called-by-yank (insert (bibtex-field-left-delimiter)))
2875 (let ((init (nth 2 field))) 2919 (let ((init (nth 2 field)))
2876 (cond ((stringp init) 2920 (cond ((stringp init)
2877 (insert init)) 2921 (insert init))
2878 ((fboundp init) 2922 ((fboundp init)
2879 (insert (funcall init))))) 2923 (insert (funcall init)))))
2880 (if (not called-by-yank) (insert (bibtex-field-right-delimiter))) 2924 (unless called-by-yank (insert (bibtex-field-right-delimiter)))
2881 (when (interactive-p) 2925 (when (interactive-p)
2882 (forward-char -1) 2926 (forward-char -1)
2883 (bibtex-print-help-message))) 2927 (bibtex-print-help-message)))
2884 2928
2885 (defun bibtex-beginning-of-entry () 2929 (defun bibtex-beginning-of-entry ()
3082 (let ((pos (save-excursion (bibtex-find-entry crossref-key)))) 3126 (let ((pos (save-excursion (bibtex-find-entry crossref-key))))
3083 (if (and pos (> (point) pos)) 3127 (if (and pos (> (point) pos))
3084 (error "This entry must not follow the crossrefed entry!")) 3128 (error "This entry must not follow the crossrefed entry!"))
3085 (goto-char pos))) 3129 (goto-char pos)))
3086 3130
3087 (defun bibtex-find-entry (key) 3131 (defun bibtex-find-entry (key &optional start)
3088 "Move point to the beginning of BibTeX entry named KEY. 3132 "Move point to the beginning of BibTeX entry named KEY.
3089 Return position of entry if KEY is found or nil if not found." 3133 Return position of entry if KEY is found or nil if not found.
3090 (interactive (list (bibtex-read-key "Find key: "))) 3134 Optional arg START is buffer position where the search starts.
3135 If it is nil, start search at beginning of buffer.
3136 With prefix arg, the value of START is position of point."
3137 (interactive (list (bibtex-read-key "Find key: ")
3138 (if current-prefix-arg (point))))
3091 (let* (case-fold-search 3139 (let* (case-fold-search
3092 (pnt (save-excursion 3140 (pnt (save-excursion
3093 (goto-char (point-min)) 3141 (goto-char (or start (point-min)))
3094 (if (re-search-forward (concat "^[ \t]*\\(" 3142 (if (re-search-forward (concat "^[ \t]*\\("
3095 bibtex-entry-type 3143 bibtex-entry-type
3096 "\\)[ \t]*[({][ \t\n]*\\(" 3144 "\\)[ \t]*[({][ \t\n]*\\("
3097 (regexp-quote key) 3145 (regexp-quote key)
3098 "\\)[ \t\n]*[,=]") 3146 "\\)[ \t\n]*[,=]")
3155 (when (or (not actual-index) 3203 (when (or (not actual-index)
3156 (bibtex-lessp actual-index index)) 3204 (bibtex-lessp actual-index index))
3157 ;; buffer contains no valid entries or 3205 ;; buffer contains no valid entries or
3158 ;; greater than last entry --> append 3206 ;; greater than last entry --> append
3159 (bibtex-end-of-entry) 3207 (bibtex-end-of-entry)
3160 (if (not (bobp)) 3208 (unless (bobp) (newline (forward-line 2)))
3161 (newline (forward-line 2)))
3162 (beginning-of-line))))) 3209 (beginning-of-line)))))
3163 (unless key-exist t))) 3210 (unless key-exist t)))
3164 3211
3165 (defun bibtex-validate (&optional test-thoroughly) 3212 (defun bibtex-validate (&optional test-thoroughly)
3166 "Validate if buffer or region is syntactically correct. 3213 "Validate if buffer or region is syntactically correct.
3231 3278
3232 (when test-thoroughly 3279 (when test-thoroughly
3233 (goto-char (point-min)) 3280 (goto-char (point-min))
3234 (bibtex-progress-message 3281 (bibtex-progress-message
3235 "Checking required fields and month fields") 3282 "Checking required fields and month fields")
3236 (let ((bibtex-sort-ignore-string-entries t) 3283 (let ((bibtex-sort-ignore-string-entries t))
3237 (questionable-month
3238 (regexp-opt (mapcar 'car bibtex-predefined-month-strings))))
3239 (bibtex-map-entries 3284 (bibtex-map-entries
3240 (lambda (key beg end) 3285 (lambda (key beg end)
3241 (bibtex-progress-message) 3286 (bibtex-progress-message)
3242 (let* ((entry-list (progn 3287 (let* ((entry-list (progn
3243 (goto-char beg) 3288 (goto-char beg)
3249 crossref-there bounds) 3294 crossref-there bounds)
3250 (goto-char beg) 3295 (goto-char beg)
3251 (while (setq bounds (bibtex-search-forward-field 3296 (while (setq bounds (bibtex-search-forward-field
3252 bibtex-field-name end)) 3297 bibtex-field-name end))
3253 (goto-char (bibtex-start-of-text-in-field bounds)) 3298 (goto-char (bibtex-start-of-text-in-field bounds))
3254 (let ((field-name (downcase (bibtex-name-in-field bounds))) 3299 (let ((field-name (bibtex-name-in-field bounds)))
3255 case-fold-search) 3300 (if (and (bibtex-string= field-name "month")
3256 (if (and (equal field-name "month") 3301 (not (assoc-string (bibtex-text-in-field-bounds bounds)
3257 (not (string-match questionable-month 3302 bibtex-predefined-month-strings t)))
3258 (bibtex-text-in-field-bounds bounds))))
3259 (push (list (bibtex-current-line) 3303 (push (list (bibtex-current-line)
3260 "Questionable month field") 3304 "Questionable month field")
3261 error-list)) 3305 error-list))
3262 (setq req (delete (assoc-string field-name req t) req) 3306 (setq req (delete (assoc-string field-name req t) req)
3263 creq (delete (assoc-string field-name creq t) creq)) 3307 creq (delete (assoc-string field-name creq t) creq))
3264 (if (equal field-name "crossref") 3308 (if (bibtex-string= field-name "crossref")
3265 (setq crossref-there t)))) 3309 (setq crossref-there t))))
3266 (if crossref-there 3310 (if crossref-there
3267 (setq req creq)) 3311 (setq req creq))
3268 (if (or (> (length req) 1) 3312 (if (or (> (length req) 1)
3269 (and (= (length req) 1) 3313 (and (= (length req) 1)
3303 "") 3347 "")
3304 "\n") 3348 "\n")
3305 (dolist (err error-list) 3349 (dolist (err error-list)
3306 (insert bufnam ":" (number-to-string (elt err 0)) 3350 (insert bufnam ":" (number-to-string (elt err 0))
3307 ": " (elt err 1) "\n")) 3351 ": " (elt err 1) "\n"))
3308 (compilation-parse-errors nil nil)
3309 (setq compilation-old-error-list compilation-error-list)
3310 ;; this is necessary to avoid reparsing of buffer if you
3311 ;; switch to compilation buffer and enter `compile-goto-error'
3312 (set-buffer-modified-p nil) 3352 (set-buffer-modified-p nil)
3313 (toggle-read-only 1) 3353 (toggle-read-only 1)
3314 (goto-char (point-min)) 3354 (goto-char (point-min))
3315 (other-window -1) 3355 (other-window -1)
3316 ;; return nil 3356 ;; return nil
3393 (defun bibtex-remove-delimiters () 3433 (defun bibtex-remove-delimiters ()
3394 "Remove \"\" or {} around string." 3434 "Remove \"\" or {} around string."
3395 (interactive) 3435 (interactive)
3396 (save-excursion 3436 (save-excursion
3397 (bibtex-inside-field) 3437 (bibtex-inside-field)
3398 (let ((bounds (bibtex-enclosing-field))) 3438 (let* ((bounds (bibtex-enclosing-field))
3399 (goto-char (bibtex-start-of-text-in-field bounds)) 3439 (end (bibtex-end-of-text-in-field bounds))
3400 (delete-char 1) 3440 (start (bibtex-start-of-text-in-field bounds)))
3401 (goto-char (1- (bibtex-end-of-text-in-field bounds))) 3441 (if (memq (char-before end) '(?\} ?\"))
3402 (delete-backward-char 1)))) 3442 (delete-region (1- end) end))
3443 (if (memq (char-after start) '(?\{ ?\"))
3444 (delete-region start (1+ start))))))
3403 3445
3404 (defun bibtex-kill-field (&optional copy-only) 3446 (defun bibtex-kill-field (&optional copy-only)
3405 "Kill the entire enclosing BibTeX field. 3447 "Kill the entire enclosing BibTeX field.
3406 With prefix arg COPY-ONLY, copy the current field to `bibtex-field-kill-ring', 3448 With prefix arg COPY-ONLY, copy the current field to `bibtex-field-kill-ring',
3407 but do not actually kill it." 3449 but do not actually kill it."
3453 (unless copy-only 3495 (unless copy-only
3454 (delete-region beg end)))) 3496 (delete-region beg end))))
3455 (setq bibtex-last-kill-command 'entry)) 3497 (setq bibtex-last-kill-command 'entry))
3456 3498
3457 (defun bibtex-copy-entry-as-kill () 3499 (defun bibtex-copy-entry-as-kill ()
3500 "Copy the entire enclosing BibTeX entry to `bibtex-entry-kill-ring'."
3458 (interactive) 3501 (interactive)
3459 (bibtex-kill-entry t)) 3502 (bibtex-kill-entry t))
3460 3503
3461 (defun bibtex-yank (&optional n) 3504 (defun bibtex-yank (&optional n)
3462 "Reinsert the last BibTeX item. 3505 "Reinsert the last BibTeX item.
3480 If N is negative, this is a more recent kill. 3523 If N is negative, this is a more recent kill.
3481 3524
3482 The sequence of kills wraps around, so that after the oldest one 3525 The sequence of kills wraps around, so that after the oldest one
3483 comes the newest one." 3526 comes the newest one."
3484 (interactive "*p") 3527 (interactive "*p")
3485 (if (not (eq last-command 'bibtex-yank)) 3528 (unless (eq last-command 'bibtex-yank)
3486 (error "Previous command was not a BibTeX yank")) 3529 (error "Previous command was not a BibTeX yank"))
3487 (setq this-command 'bibtex-yank) 3530 (setq this-command 'bibtex-yank)
3488 (let ((inhibit-read-only t)) 3531 (let ((inhibit-read-only t))
3489 (delete-region (point) (mark t)) 3532 (delete-region (point) (mark t))
3490 (bibtex-insert-current-kill n))) 3533 (bibtex-insert-current-kill n)))
3491 3534
3531 (let ((case-fold-search t) 3574 (let ((case-fold-search t)
3532 entry-type key) 3575 entry-type key)
3533 (bibtex-beginning-of-entry) 3576 (bibtex-beginning-of-entry)
3534 (save-excursion 3577 (save-excursion
3535 (when (re-search-forward bibtex-entry-maybe-empty-head nil t) 3578 (when (re-search-forward bibtex-entry-maybe-empty-head nil t)
3536 (setq entry-type (downcase (bibtex-type-in-head))) 3579 (setq entry-type (bibtex-type-in-head))
3537 (setq key (bibtex-key-in-head)))) 3580 (setq key (bibtex-key-in-head))))
3538 ;; formatting 3581 ;; formatting
3539 (cond ((equal entry-type "preamble") 3582 (cond ((bibtex-string= entry-type "preamble")
3540 ;; (bibtex-format-preamble) 3583 ;; (bibtex-format-preamble)
3541 (error "No clean up of @Preamble entries")) 3584 (error "No clean up of @Preamble entries"))
3542 ((equal entry-type "string")) 3585 ((bibtex-string= entry-type "string"))
3543 ;; (bibtex-format-string) 3586 ;; (bibtex-format-string)
3544 (t (bibtex-format-entry))) 3587 (t (bibtex-format-entry)))
3545 ;; set key 3588 ;; set key
3546 (when (or new-key (not key)) 3589 (when (or new-key (not key))
3547 (setq key (bibtex-generate-autokey)) 3590 (setq key (bibtex-generate-autokey))
3548 (if bibtex-autokey-edit-before-use 3591 ;; Sometimes bibtex-generate-autokey returns an empty string
3592 (if (or bibtex-autokey-edit-before-use (string= "" key))
3549 (setq key (bibtex-read-key "Key to use: " key))) 3593 (setq key (bibtex-read-key "Key to use: " key)))
3550 (re-search-forward bibtex-entry-maybe-empty-head) 3594 (re-search-forward bibtex-entry-maybe-empty-head)
3551 (if (match-beginning bibtex-key-in-head) 3595 (if (match-beginning bibtex-key-in-head)
3552 (delete-region (match-beginning bibtex-key-in-head) 3596 (delete-region (match-beginning bibtex-key-in-head)
3553 (match-end bibtex-key-in-head))) 3597 (match-end bibtex-key-in-head)))
3561 (goto-char (match-beginning 0))) 3605 (goto-char (match-beginning 0)))
3562 (point))) 3606 (point)))
3563 (entry (buffer-substring start end)) 3607 (entry (buffer-substring start end))
3564 (index (progn (goto-char start) 3608 (index (progn (goto-char start)
3565 (bibtex-entry-index))) 3609 (bibtex-entry-index)))
3566 no-error) 3610 error)
3567 (if (and bibtex-maintain-sorted-entries 3611 (if (and bibtex-maintain-sorted-entries
3568 (not (and bibtex-sort-ignore-string-entries 3612 (not (and bibtex-sort-ignore-string-entries
3569 (equal entry-type "string")))) 3613 (bibtex-string= entry-type "string"))))
3570 (progn 3614 (progn
3571 (delete-region start end) 3615 (delete-region start end)
3572 (setq no-error (bibtex-prepare-new-entry index)) 3616 (setq error (not (bibtex-prepare-new-entry index)))
3573 (insert entry) 3617 (insert entry)
3574 (forward-char -1) 3618 (forward-char -1)
3575 (bibtex-beginning-of-entry) ; moves backward 3619 (bibtex-beginning-of-entry) ; moves backward
3576 (re-search-forward bibtex-entry-head)) 3620 (re-search-forward bibtex-entry-head))
3577 (setq no-error (bibtex-find-entry (car index)))) 3621 (bibtex-find-entry key)
3578 (unless no-error 3622 (setq error (or (/= (point) start)
3623 (bibtex-find-entry key end))))
3624 (if error
3579 (error "New inserted entry yields duplicate key")))) 3625 (error "New inserted entry yields duplicate key"))))
3580 ;; final clean up 3626 ;; final clean up
3581 (unless called-by-reformat 3627 (unless called-by-reformat
3582 (save-excursion 3628 (save-excursion
3583 (save-restriction 3629 (save-restriction
3584 (bibtex-narrow-to-entry) 3630 (bibtex-narrow-to-entry)
3585 ;; Only update the list of keys if it has been built already. 3631 ;; Only update the list of keys if it has been built already.
3586 (cond ((equal entry-type "string") 3632 (cond ((bibtex-string= entry-type "string")
3587 (if (listp bibtex-strings) (bibtex-parse-strings t))) 3633 (if (listp bibtex-strings) (bibtex-parse-strings t)))
3588 ((listp bibtex-reference-keys) (bibtex-parse-keys t))) 3634 ((listp bibtex-reference-keys) (bibtex-parse-keys t)))
3589 (run-hooks 'bibtex-clean-entry-hook)))))) 3635 (run-hooks 'bibtex-clean-entry-hook))))))
3590 3636
3591 (defun bibtex-fill-field-bounds (bounds justify &optional move) 3637 (defun bibtex-fill-field-bounds (bounds justify &optional move)
3750 (message "Buffer is now parsable. Please save it."))) 3796 (message "Buffer is now parsable. Please save it.")))
3751 3797
3752 (defun bibtex-complete () 3798 (defun bibtex-complete ()
3753 "Complete word fragment before point according to context. 3799 "Complete word fragment before point according to context.
3754 If point is inside key or crossref field perform key completion based on 3800 If point is inside key or crossref field perform key completion based on
3755 `bibtex-reference-keys'. Inside any other field perform string 3801 `bibtex-reference-keys'. Inside a month field perform key completion
3756 completion based on `bibtex-strings'. An error is signaled if point 3802 based on `bibtex-predefined-month-strings'. Inside any other field
3757 is outside key or BibTeX field." 3803 perform string completion based on `bibtex-strings'. An error is
3804 signaled if point is outside key or BibTeX field."
3758 (interactive) 3805 (interactive)
3759 (let* ((pnt (point)) 3806 (let ((pnt (point))
3760 (case-fold-search t) 3807 (case-fold-search t)
3761 bounds compl) 3808 bounds name compl)
3762 (save-excursion 3809 (save-excursion
3763 (if (and (setq bounds (bibtex-enclosing-field t)) 3810 (if (and (setq bounds (bibtex-enclosing-field t))
3764 (>= pnt (bibtex-start-of-text-in-field bounds)) 3811 (>= pnt (bibtex-start-of-text-in-field bounds))
3765 (<= pnt (bibtex-end-of-text-in-field bounds))) 3812 (<= pnt (bibtex-end-of-text-in-field bounds)))
3766 (progn 3813 (setq name (bibtex-name-in-field bounds t)
3767 (goto-char (bibtex-start-of-name-in-field bounds)) 3814 compl (cond ((bibtex-string= name "crossref")
3768 (setq compl (if (string= "crossref" 3815 'key)
3769 (downcase 3816 ((bibtex-string= name "month")
3770 (buffer-substring-no-properties 3817 bibtex-predefined-month-strings)
3771 (if (looking-at "\\(OPT\\)\\|\\(ALT\\)") 3818 (t (if (listp bibtex-strings)
3772 (match-end 0) 3819 bibtex-strings
3773 (point)) 3820 ;; so that bibtex-complete-string-cleanup
3774 (bibtex-end-of-name-in-field bounds)))) 3821 ;; can do its job
3775 'key 3822 (bibtex-parse-strings
3776 'str))) 3823 (bibtex-string-files-init))))))
3777 (bibtex-beginning-of-entry) 3824 (bibtex-beginning-of-entry)
3778 (if (and (re-search-forward bibtex-entry-maybe-empty-head nil t) 3825 (if (and (re-search-forward bibtex-entry-maybe-empty-head nil t)
3779 ;; point is inside a key 3826 ;; point is inside a key
3780 (or (and (match-beginning bibtex-key-in-head) 3827 (or (and (match-beginning bibtex-key-in-head)
3781 (>= pnt (match-beginning bibtex-key-in-head)) 3828 (>= pnt (match-beginning bibtex-key-in-head))
3787 3834
3788 (cond ((equal compl 'key) 3835 (cond ((equal compl 'key)
3789 ;; key completion 3836 ;; key completion
3790 (setq choose-completion-string-functions 3837 (setq choose-completion-string-functions
3791 (lambda (choice buffer mini-p base-size) 3838 (lambda (choice buffer mini-p base-size)
3792 (bibtex-choose-completion-string choice buffer mini-p base-size) 3839 (bibtex-choose-completion-string choice buffer mini-p base-size)
3793 (if bibtex-complete-key-cleanup 3840 (bibtex-complete-key-cleanup choice)
3794 (funcall bibtex-complete-key-cleanup choice))
3795 ;; return t (required by choose-completion-string-functions) 3841 ;; return t (required by choose-completion-string-functions)
3796 t)) 3842 t))
3797 (let ((choice (bibtex-complete-internal bibtex-reference-keys))) 3843 (bibtex-complete-key-cleanup (bibtex-complete-internal
3798 (if bibtex-complete-key-cleanup 3844 bibtex-reference-keys)))
3799 (funcall bibtex-complete-key-cleanup choice)))) 3845
3800 3846 (compl
3801 ((equal compl 'str)
3802 ;; string completion 3847 ;; string completion
3803 (setq choose-completion-string-functions 3848 (setq choose-completion-string-functions
3804 (lambda (choice buffer mini-p base-size) 3849 `(lambda (choice buffer mini-p base-size)
3805 (bibtex-choose-completion-string choice buffer mini-p base-size) 3850 (bibtex-choose-completion-string choice buffer mini-p base-size)
3806 (bibtex-complete-string-cleanup choice) 3851 (bibtex-complete-string-cleanup choice ',compl)
3807 ;; return t (required by choose-completion-string-functions) 3852 ;; return t (required by choose-completion-string-functions)
3808 t)) 3853 t))
3809 (bibtex-complete-string-cleanup (bibtex-complete-internal bibtex-strings))) 3854 (bibtex-complete-string-cleanup (bibtex-complete-internal compl)
3855 compl))
3810 3856
3811 (t (error "Point outside key or BibTeX field"))))) 3857 (t (error "Point outside key or BibTeX field")))))
3812 3858
3813 (defun bibtex-Article () 3859 (defun bibtex-Article ()
3814 "Insert a new BibTeX @Article entry; see also `bibtex-entry'." 3860 "Insert a new BibTeX @Article entry; see also `bibtex-entry'."
3878 (defun bibtex-String (&optional key) 3924 (defun bibtex-String (&optional key)
3879 "Insert a new BibTeX @String entry with key KEY." 3925 "Insert a new BibTeX @String entry with key KEY."
3880 (interactive (list (completing-read "String key: " bibtex-strings 3926 (interactive (list (completing-read "String key: " bibtex-strings
3881 nil nil nil 'bibtex-key-history))) 3927 nil nil nil 'bibtex-key-history)))
3882 (let ((bibtex-maintain-sorted-entries 3928 (let ((bibtex-maintain-sorted-entries
3883 (if (not bibtex-sort-ignore-string-entries) 3929 (unless bibtex-sort-ignore-string-entries
3884 bibtex-maintain-sorted-entries)) 3930 bibtex-maintain-sorted-entries))
3885 endpos) 3931 endpos)
3886 (unless (bibtex-prepare-new-entry (list key nil "String")) 3932 (unless (bibtex-prepare-new-entry (list key nil "String"))
3887 (error "Entry with key `%s' already exists" key)) 3933 (error "Entry with key `%s' already exists" key))
3888 (if (zerop (length key)) (setq key nil)) 3934 (if (zerop (length key)) (setq key nil))
3889 (indent-to-column bibtex-entry-offset) 3935 (indent-to-column bibtex-entry-offset)
3911 (let ((endpos (point))) 3957 (let ((endpos (point)))
3912 (insert (bibtex-entry-right-delimiter) 3958 (insert (bibtex-entry-right-delimiter)
3913 "\n") 3959 "\n")
3914 (goto-char endpos))) 3960 (goto-char endpos)))
3915 3961
3962 (defun bibtex-url (&optional event)
3963 "Browse a URL for the BibTeX entry at position PNT.
3964 The URL is generated using the schemes defined in `bibtex-generate-url-list'
3965 \(see there\). Then the URL is passed to `browse-url'."
3966 (interactive (list last-input-event))
3967 (save-excursion
3968 (if event (posn-set-point (event-end event)))
3969 (bibtex-beginning-of-entry)
3970 (let ((fields-alist (bibtex-parse-entry))
3971 (case-fold-search t)
3972 (lst bibtex-generate-url-list)
3973 field url scheme)
3974 (while (setq scheme (car lst))
3975 (when (and (setq field (assoc-string (caar scheme) fields-alist t))
3976 (or (eq t (cdar scheme))
3977 (string-match (cdar scheme) (cdr field))))
3978 (setq lst nil)
3979 (dolist (step (cdr scheme))
3980 (cond ((stringp step)
3981 (setq url (concat url step)))
3982 ((setq field (assoc-string (car step) fields-alist t))
3983 ;; always remove field delimiters
3984 (let* ((text (if (string-match "\\`[{\"]\\(.*\\)[}\"]\\'"
3985 (cdr field))
3986 (match-string 1 (cdr field))
3987 (cdr field)))
3988 (str (cond ((eq t (nth 1 step))
3989 text)
3990 ((and (consp (nth 1 step))
3991 (string-match (car (nth 1 step))
3992 text))
3993 (if (numberp (cdr (nth 1 step)))
3994 (match-string (cdr (nth 1 step))
3995 text)
3996 (replace-match (cdr (nth 1 step))
3997 nil nil text)))
3998 ;; If the scheme is set up correctly,
3999 ;; we should never reach this point
4000 (t (error "Match failed: %s" text)))))
4001 (setq url (concat url (if (fboundp (nth 2 step))
4002 (funcall (nth 2 step) str)
4003 str)))))
4004 ;; If the scheme is set up correctly,
4005 ;; we should never reach this point
4006 (t (error "Step failed: %s" step))))
4007 (message "%s" url)
4008 (browse-url url))
4009 (setq lst (cdr lst)))
4010 (unless url (message "No URL known.")))))
4011
4012 (defun bibtex-font-lock-url (bound)
4013 "Font-lock for URLs."
4014 (let ((case-fold-search t)
4015 (bounds (bibtex-enclosing-field t))
4016 (pnt (point))
4017 found url)
4018 ;; We use start-of-field as syntax-begin
4019 (goto-char (if bounds (bibtex-start-of-field bounds) pnt))
4020 (while (and (not found)
4021 (search-forward-regexp bibtex-font-lock-url-regexp bound t)
4022 (save-match-data (setq bounds (bibtex-parse-field-text)))
4023 (>= bound (car bounds)))
4024 (let ((field (match-string-no-properties 1))
4025 (lst bibtex-generate-url-list))
4026 (while (and (not found)
4027 (setq url (caar lst)))
4028 (when (bibtex-string= field (car url))
4029 (if (eq t (cdr url))
4030 (progn
4031 (goto-char (min bound (cdr bounds)))
4032 (set-match-data (list (car bounds) (point)))
4033 (setq found t))
4034 (goto-char (car bounds))
4035 (setq found (search-forward-regexp (cdr url)
4036 (min bound (cdr bounds)) t)))
4037 (if (< (match-beginning 0) pnt)
4038 (setq found nil)))
4039 (setq lst (cdr lst)))))
4040 found))
4041
3916 4042
3917 ;; Make BibTeX a Feature 4043 ;; Make BibTeX a Feature
3918 4044
3919 (provide 'bibtex) 4045 (provide 'bibtex)
3920 4046