[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] Changes to emacs/lisp/textmodes/bibtex.el [emacs-unicode-2
From: |
Miles Bader |
Subject: |
[Emacs-diffs] Changes to emacs/lisp/textmodes/bibtex.el [emacs-unicode-2] |
Date: |
Wed, 15 Sep 2004 05:23:16 -0400 |
Index: emacs/lisp/textmodes/bibtex.el
diff -c emacs/lisp/textmodes/bibtex.el:1.77.2.2
emacs/lisp/textmodes/bibtex.el:1.77.2.3
*** emacs/lisp/textmodes/bibtex.el:1.77.2.2 Mon Jun 28 07:29:50 2004
--- emacs/lisp/textmodes/bibtex.el Wed Sep 15 08:59:53 2004
***************
*** 1,6 ****
;;; bibtex.el --- BibTeX mode for GNU Emacs
! ;; Copyright (C) 1992,94,95,96,97,98,1999,2003,2004
;; Free Software Foundation, Inc.
;; Author: Stefan Schoef <address@hidden>
--- 1,6 ----
;;; bibtex.el --- BibTeX mode for GNU Emacs
! ;; Copyright (C) 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2003, 2004
;; Free Software Foundation, Inc.
;; Author: Stefan Schoef <address@hidden>
***************
*** 61,73 ****
:type 'hook)
(defcustom bibtex-field-delimiters 'braces
! "*Type of field delimiters. Allowed values are `braces' or `double-quotes'."
:group 'bibtex
:type '(choice (const braces)
(const double-quotes)))
(defcustom bibtex-entry-delimiters 'braces
! "*Type of entry delimiters. Allowed values are `braces' or `parentheses'."
:group 'bibtex
:type '(choice (const braces)
(const parentheses)))
--- 61,73 ----
:type 'hook)
(defcustom bibtex-field-delimiters 'braces
! "*Type of field delimiters. Allowed values are `braces' or
`double-quotes'."
:group 'bibtex
:type '(choice (const braces)
(const double-quotes)))
(defcustom bibtex-entry-delimiters 'braces
! "*Type of entry delimiters. Allowed values are `braces' or `parentheses'."
:group 'bibtex
:type '(choice (const braces)
(const parentheses)))
***************
*** 154,163 ****
Allowed non-nil values are:
plain All entries are sorted alphabetically.
crossref All entries are sorted alphabetically unless an entry has a
! crossref field. These crossrefed entries are placed in
alphabetical order immediately preceding the main entry.
entry-class The entries are divided into classes according to their
! entry name, see `bibtex-sort-entry-class'. Within each class
the entries are sorted alphabetically.
See also `bibtex-sort-ignore-string-entries'."
:group 'bibtex
--- 154,163 ----
Allowed non-nil values are:
plain All entries are sorted alphabetically.
crossref All entries are sorted alphabetically unless an entry has a
! crossref field. These crossrefed entries are placed in
alphabetical order immediately preceding the main entry.
entry-class The entries are divided into classes according to their
! entry name, see `bibtex-sort-entry-class'. Within each class
the entries are sorted alphabetically.
See also `bibtex-sort-ignore-string-entries'."
:group 'bibtex
***************
*** 172,179 ****
("Book" "Proceedings"))
"*List of classes of BibTeX entry names, used for sorting entries.
If value of `bibtex-maintain-sorted-entries' is `entry-class'
! entries are ordered according to the classes they belong to. Each
! class contains a list of entry names. An entry `catch-all' applies
to all entries not explicitely mentioned.")
(defcustom bibtex-sort-ignore-string-entries t
--- 172,179 ----
("Book" "Proceedings"))
"*List of classes of BibTeX entry names, used for sorting entries.
If value of `bibtex-maintain-sorted-entries' is `entry-class'
! entries are ordered according to the classes they belong to. Each
! class contains a list of entry names. An entry `catch-all' applies
to all entries not explicitely mentioned.")
(defcustom bibtex-sort-ignore-string-entries t
***************
*** 640,646 ****
(defcustom bibtex-autokey-titleword-ignore
'("A" "An" "On" "The" "Eine?" "Der" "Die" "Das"
! "[^A-Z].*" ".*[^a-zA-Z0-9].*")
"*Determines words from the title that are not to be used in the key.
Each item of the list is a regexp. If a word of the title matchs a
regexp from that list, it is not included in the title part of the key.
--- 640,646 ----
(defcustom bibtex-autokey-titleword-ignore
'("A" "An" "On" "The" "Eine?" "Der" "Die" "Das"
! "[^A-Z].*" ".*[^A-Z0-9].*")
"*Determines words from the title that are not to be used in the key.
Each item of the list is a regexp. If a word of the title matchs a
regexp from that list, it is not included in the title part of the key.
***************
*** 762,772 ****
"Automatically fill fields if possible for those BibTeX entry types."
:type '(repeat string))
! (defcustom bibtex-complete-key-cleanup nil
! "*Function called by `bibtex-complete' after insertion of a key fragment."
! :group 'bibtex-autokey
! :type '(choice (const :tag "None" nil)
! (function :tag "Cleanup function")))
;; bibtex-font-lock-keywords is a user option as well, but since the
;; patterns used to define this variable are defined in a later
--- 762,808 ----
"Automatically fill fields if possible for those BibTeX entry types."
:type '(repeat string))
! (defcustom bibtex-generate-url-list
! '((("url" . ".*:.*"))
! ;; Example of a complex setup.
! (("journal" . "\\<\\(PR[ABCDEL]?\\|RMP\\)\\>")
! "http://publish.aps.org/abstract/"
! ("journal" ".*" downcase)
! "/v"
! ("volume" ".*" 0)
! "/p"
! ("pages" "\\`\\([0-9]+\\)" 1)))
! "List of schemes for generating the URL of a BibTeX entry.
! These schemes are used by `bibtex-url'.
!
! Each scheme is of the form ((FIELD . REGEXP) STEP...).
!
! FIELD is a field name as returned by `bibtex-parse-entry'.
! REGEXP is matched against the text of FIELD. If the match succeed, then
! this scheme will be used. If no STEPS are specified the matched text is used
! as the URL, otherwise the URL is built by concatenating the STEPS.
!
! A STEP can be a string or a list (FIELD REGEXP REPLACE) in which case
! the text of FIELD is matched against REGEXP, and is replaced with REPLACE.
! REPLACE can be a string, or a number (which selects the corresponding
submatch)
! or a function called with the field's text as argument and with the
! `match-data' properly set.
!
! Case is always ignored. Always remove the field delimiters."
! :group 'bibtex
! :type '(repeat
! (list :tag "Scheme"
! (cons :tag "Matcher" :extra-offset 4
! (string :tag "BibTeX field")
! (regexp :tag "Regexp"))
! (repeat :tag "Steps to generate URL" :inline t
! (choice
! (string :tag "Literal text")
! (list (string :tag "BibTeX field")
! (regexp :tag "Regexp")
! (choice (string :tag "Replacement")
! (integer :tag "Sub-match")
! (function :tag "Filter"))))))))
;; bibtex-font-lock-keywords is a user option as well, but since the
;; patterns used to define this variable are defined in a later
***************
*** 801,806 ****
--- 837,843 ----
(define-key km "\C-c}" 'bibtex-remove-delimiters)
(define-key km "\C-c\C-c" 'bibtex-clean-entry)
(define-key km "\C-c\C-q" 'bibtex-fill-entry)
+ (define-key km "\C-c\C-s" 'bibtex-find-entry)
(define-key km "\C-c?" 'bibtex-print-help-message)
(define-key km "\C-c\C-p" 'bibtex-pop-previous)
(define-key km "\C-c\C-n" 'bibtex-pop-next)
***************
*** 821,826 ****
--- 858,864 ----
(define-key km "\C-c\C-b" 'bibtex-entry)
(define-key km "\C-c\C-rn" 'bibtex-narrow-to-entry)
(define-key km "\C-c\C-rw" 'widen)
+ (define-key km "\C-c\C-l" 'bibtex-url)
(define-key km "\C-c\C-o" 'bibtex-remove-OPT-or-ALT)
(define-key km "\C-c\C-e\C-i" 'bibtex-InProceedings)
(define-key km "\C-c\C-ei" 'bibtex-InCollection)
***************
*** 854,874 ****
("Moving in BibTeX Buffer"
["Find Entry" bibtex-find-entry t]
["Find Crossref Entry" bibtex-find-crossref t])
- ("Operating on Current Entry"
- ["Fill Entry" bibtex-fill-entry t]
- ["Clean Entry" bibtex-clean-entry t]
"--"
- ["Kill Entry" bibtex-kill-entry t]
- ["Copy Entry to Kill Ring" bibtex-copy-entry-as-kill t]
- ["Paste Most Recently Killed Entry" bibtex-yank t]
- ["Paste Previously Killed Entry" bibtex-yank-pop t]
- "--"
- ["Ispell Entry" bibtex-ispell-entry t]
- ["Ispell Entry Abstract" bibtex-ispell-abstract t]
- ["Narrow to Entry" bibtex-narrow-to-entry t]
- "--"
- ["View Cite Locations (RefTeX)" reftex-view-crossref-from-bibtex
- (fboundp 'reftex-view-crossref-from-bibtex)])
("Operating on Current Field"
["Fill Field" fill-paragraph t]
["Remove Delimiters" bibtex-remove-delimiters t]
--- 892,898 ----
***************
*** 888,899 ****
["String or Key Complete" bibtex-complete t]
"--"
["Help about Current Field" bibtex-print-help-message t])
("Operating on Buffer or Region"
["Validate Entries" bibtex-validate t]
["Sort Entries" bibtex-sort-buffer t]
["Reformat Entries" bibtex-reformat t]
! ["Count Entries" bibtex-count-entries t])
! ("Miscellaneous"
["Convert Alien Buffer" bibtex-convert-alien t])))
(easy-menu-define
--- 912,939 ----
["String or Key Complete" bibtex-complete t]
"--"
["Help about Current Field" bibtex-print-help-message t])
+ ("Operating on Current Entry"
+ ["Fill Entry" bibtex-fill-entry t]
+ ["Clean Entry" bibtex-clean-entry t]
+ ["Update Entry" bibtex-entry-update t]
+ "--"
+ ["Kill Entry" bibtex-kill-entry t]
+ ["Copy Entry to Kill Ring" bibtex-copy-entry-as-kill t]
+ ["Paste Most Recently Killed Entry" bibtex-yank t]
+ ["Paste Previously Killed Entry" bibtex-yank-pop t]
+ "--"
+ ["Ispell Entry" bibtex-ispell-entry t]
+ ["Ispell Entry Abstract" bibtex-ispell-abstract t]
+ ["Narrow to Entry" bibtex-narrow-to-entry t]
+ "--"
+ ["View Cite Locations (RefTeX)" reftex-view-crossref-from-bibtex
+ (fboundp 'reftex-view-crossref-from-bibtex)])
("Operating on Buffer or Region"
["Validate Entries" bibtex-validate t]
["Sort Entries" bibtex-sort-buffer t]
["Reformat Entries" bibtex-reformat t]
! ["Count Entries" bibtex-count-entries t]
! "--"
["Convert Alien Buffer" bibtex-convert-alien t])))
(easy-menu-define
***************
*** 915,920 ****
--- 955,967 ----
["String" bibtex-String t]
["Preamble" bibtex-Preamble t]))
+ (defvar bibtex-url-map
+ (let ((km (make-sparse-keymap)))
+ (define-key km [(mouse-2)] 'bibtex-url)
+ km)
+ "Local keymap for clickable URLs.")
+ (fset 'bibtex-url-map bibtex-url-map)
+
;; Internal Variables
***************
*** 954,961 ****
(make-variable-buffer-local 'bibtex-reference-keys)
(defvar bibtex-buffer-last-parsed-tick nil
! "Last value returned by `buffer-modified-tick' when buffer
! was parsed for keys the last time.")
(defvar bibtex-parse-idle-timer nil
"Stores if timer is already installed.")
--- 1001,1007 ----
(make-variable-buffer-local 'bibtex-reference-keys)
(defvar bibtex-buffer-last-parsed-tick nil
! "Value of `buffer-modified-tick' last time buffer was parsed for keys.")
(defvar bibtex-parse-idle-timer nil
"Stores if timer is already installed.")
***************
*** 1040,1080 ****
(defconst bibtex-empty-field-re "\"\"\\|{}"
"Regexp matching an empty field.")
- (defconst bibtex-quoted-string-re
- (concat "\""
- "\\("
- "[^\"\\]" ; anything but quote or backslash
- "\\|"
- "\\("
- "\\\\\\(.\\|\n\\)" ; any backslash quoted character
- "\\)"
- "\\)*"
- "\"")
- "Regexp matching a field string enclosed by quotes.")
-
(defconst bibtex-font-lock-syntactic-keywords
`((,(concat "^[ \t]*\\(" (substring bibtex-comment-start 0 1) "\\)"
(substring bibtex-comment-start 1) "\\>")
1 '(11))))
(defvar bibtex-font-lock-keywords
! (list
! ;; entry type and reference key
! (list bibtex-entry-maybe-empty-head
! (list bibtex-type-in-head 'font-lock-function-name-face)
! (list bibtex-key-in-head 'font-lock-constant-face nil t))
! ;; optional field names (treated as comments)
! (list
! (concat "^[ \t]*\\(OPT" bibtex-field-name "\\)[ \t]*=")
! 1 'font-lock-comment-face)
! ;; field names
! (list (concat "^[ \t]*\\(" bibtex-field-name "\\)[ \t]*=")
! 1 'font-lock-variable-name-face))
"*Default expressions to highlight in BibTeX mode.")
(defvar bibtex-field-name-for-parsing nil
! "Temporary variable storing the name string to be parsed by the callback
! function `bibtex-parse-field-name'.")
(defvar bibtex-sort-entry-class-alist
(let ((i -1) alist)
--- 1086,1120 ----
(defconst bibtex-empty-field-re "\"\"\\|{}"
"Regexp matching an empty field.")
(defconst bibtex-font-lock-syntactic-keywords
`((,(concat "^[ \t]*\\(" (substring bibtex-comment-start 0 1) "\\)"
(substring bibtex-comment-start 1) "\\>")
1 '(11))))
(defvar bibtex-font-lock-keywords
! ;; entry type and reference key
! `((,bibtex-entry-maybe-empty-head
! (,bibtex-type-in-head font-lock-function-name-face)
! (,bibtex-key-in-head font-lock-constant-face nil t))
! ;; optional field names (treated as comments)
! (,(concat "^[ \t]*\\(OPT" bibtex-field-name "\\)[ \t]*=")
! 1 font-lock-comment-face)
! ;; field names
! (,(concat "^[ \t]*\\(" bibtex-field-name "\\)[ \t]*=")
! 1 font-lock-variable-name-face)
! ;; url
! (bibtex-font-lock-url 0 '(face nil mouse-face highlight
! keymap bibtex-url-map)))
"*Default expressions to highlight in BibTeX mode.")
+ (defvar bibtex-font-lock-url-regexp
+ (concat "\\<" (regexp-opt (mapcar 'caar bibtex-generate-url-list) t)
+ "\\>[ \t]*=[ \t]*")
+ "Regexp for `bibtex-font-lock-url'.")
+
(defvar bibtex-field-name-for-parsing nil
! "Regexp of field name to be parsed by function `bibtex-parse-field-name'.
! Passed by dynamic scoping.")
(defvar bibtex-sort-entry-class-alist
(let ((i -1) alist)
***************
*** 1083,1123 ****
(dolist (entry class)
;; all entry names should be downcase (for ease of comparison)
(push (cons (if (stringp entry) (downcase entry) entry) i) alist))))
! "Alist for the classes of the entry types if the value of
! `bibtex-maintain-sorted-entries' is `entry-class'.")
;; Special support taking care of variants
(defvar zmacs-regions)
! (if (boundp 'mark-active)
! (defun bibtex-mark-active ()
;; In Emacs mark-active indicates if mark is active.
! mark-active)
! (defun bibtex-mark-active ()
;; In XEmacs (mark) returns nil when not active.
! (if zmacs-regions (mark) (mark t))))
! (if (fboundp 'run-with-idle-timer)
! ;; timer.el is distributed with Emacs
! (fset 'bibtex-run-with-idle-timer 'run-with-idle-timer)
! ;; timer.el is not distributed with XEmacs
! ;; Notice that this does not (yet) pass the arguments, but they
! ;; are not used (yet) in bibtex.el. Fix if needed.
! (defun bibtex-run-with-idle-timer (secs repeat function &rest args)
! (start-itimer "bibtex" function secs (if repeat secs nil) t)))
;; Support for hideshow minor mode
(defun bibtex-hs-forward-sexp (arg)
! "Replacement for `forward-sexp' to be used by `hs-minor-mode'."
! (if (< arg 0)
! (backward-sexp 1)
! (if (looking-at "@\\S(*\\s(")
! (progn
! (goto-char (match-end 0))
! (forward-char -1)
! (forward-sexp 1))
! (forward-sexp 1))))
(add-to-list
'hs-special-modes-alist
--- 1123,1160 ----
(dolist (entry class)
;; all entry names should be downcase (for ease of comparison)
(push (cons (if (stringp entry) (downcase entry) entry) i) alist))))
! "Alist mapping entry types to their sorting index.
! Auto-generated from `bibtex-sort-entry-class'.
! Used when `bibtex-maintain-sorted-entries' is `entry-class'.")
;; Special support taking care of variants
(defvar zmacs-regions)
! (defalias 'bibtex-mark-active
! (if (boundp 'mark-active)
;; In Emacs mark-active indicates if mark is active.
! (lambda () mark-active)
;; In XEmacs (mark) returns nil when not active.
! (lambda () (if zmacs-regions (mark) (mark t)))))
! (defalias 'bibtex-run-with-idle-timer
! (if (fboundp 'run-with-idle-timer)
! ;; timer.el is distributed with Emacs
! 'run-with-idle-timer
! ;; timer.el is not distributed with XEmacs
! ;; Notice that this does not (yet) pass the arguments, but they
! ;; are not used (yet) in bibtex.el. Fix if needed.
! (lambda (secs repeat function &rest args)
! (start-itimer "bibtex" function secs (if repeat secs nil) t))))
;; Support for hideshow minor mode
(defun bibtex-hs-forward-sexp (arg)
! "Replacement for `forward-sexp' to be used by `hs-minor-mode'.
! ARG is ignored."
! (if (looking-at "@\\S(*\\s(")
! (goto-char (1- (match-end 0))))
! (forward-sexp 1))
(add-to-list
'hs-special-modes-alist
***************
*** 1144,1150 ****
"Parse the field name stored in `bibtex-field-name-for-parsing'.
If the field name is found, return a triple consisting of the position of the
very first character of the match, the actual starting position of the name
! part and end position of the match. Move point to end of field name.
If `bibtex-autoadd-commas' is non-nil add missing comma at end of preceeding
BibTeX field as necessary."
(cond ((looking-at ",[ \t\n]*")
--- 1181,1187 ----
"Parse the field name stored in `bibtex-field-name-for-parsing'.
If the field name is found, return a triple consisting of the position of the
very first character of the match, the actual starting position of the name
! part and end position of the match. Move point to end of field name.
If `bibtex-autoadd-commas' is non-nil add missing comma at end of preceeding
BibTeX field as necessary."
(cond ((looking-at ",[ \t\n]*")
***************
*** 1206,1212 ****
The text part is either a string, or an empty string, or a constant followed
by one or more <# (string|constant)> pairs. If a syntactically correct text
is found, a pair containing the start and end position of the text is
! returned, nil otherwise. Move point to end of field text."
(let ((starting-point (point))
end-point failure boundaries)
(while (not (or end-point failure))
--- 1243,1249 ----
The text part is either a string, or an empty string, or a constant followed
by one or more <# (string|constant)> pairs. If a syntactically correct text
is found, a pair containing the start and end position of the text is
! returned, nil otherwise. Move point to end of field text."
(let ((starting-point (point))
end-point failure boundaries)
(while (not (or end-point failure))
***************
*** 1215,1223 ****
((setq boundaries (bibtex-parse-field-string))
(goto-char (cdr boundaries)))
((setq failure t)))
! (if (not (looking-at "[ \t\n]*#[ \t\n]*"))
! (setq end-point (point))
! (goto-char (match-end 0))))
(if (and (not failure)
end-point)
(cons starting-point end-point))))
--- 1252,1260 ----
((setq boundaries (bibtex-parse-field-string))
(goto-char (cdr boundaries)))
((setq failure t)))
! (if (looking-at "[ \t\n]*#[ \t\n]*")
! (goto-char (match-end 0))
! (setq end-point (point))))
(if (and (not failure)
end-point)
(cons starting-point end-point))))
***************
*** 1234,1241 ****
"Search forward to find a field of name NAME.
If a syntactically correct field is found, a pair containing the boundaries of
the name and text parts of the field is returned. The search is limited by
! optional arg BOUND. If BOUND is t the search is limited by the end of the
current
! entry. Do not move point."
(save-match-data
(save-excursion
(unless (integer-or-marker-p bound)
--- 1271,1278 ----
"Search forward to find a field of name NAME.
If a syntactically correct field is found, a pair containing the boundaries of
the name and text parts of the field is returned. The search is limited by
! optional arg BOUND. If BOUND is t the search is limited by the end of the
! current entry. Do not move point."
(save-match-data
(save-excursion
(unless (integer-or-marker-p bound)
***************
*** 1261,1268 ****
"Search backward to find a field of name NAME.
If a syntactically correct field is found, a pair containing the boundaries of
the name and text parts of the field is returned. The search is limited by
! optional arg BOUND. If BOUND is t the search is limited by the beginning of
the
! current entry. Do not move point."
(save-match-data
(save-excursion
(unless (integer-or-marker-p bound)
--- 1298,1305 ----
"Search backward to find a field of name NAME.
If a syntactically correct field is found, a pair containing the boundaries of
the name and text parts of the field is returned. The search is limited by
! optional arg BOUND. If BOUND is t the search is limited by the beginning of
the
! current entry. Do not move point."
(save-match-data
(save-excursion
(unless (integer-or-marker-p bound)
***************
*** 1294,1303 ****
(defsubst bibtex-end-of-text-in-field (bounds)
(cddr bounds))
! (defun bibtex-name-in-field (bounds)
! "Get content of name in BibTeX field defined via BOUNDS."
! (buffer-substring-no-properties (nth 1 (car bounds))
! (nth 2 (car bounds))))
(defun bibtex-text-in-field-bounds (bounds &optional remove-delim)
"Get content of text in BibTeX field defined via BOUNDS.
--- 1331,1345 ----
(defsubst bibtex-end-of-text-in-field (bounds)
(cddr bounds))
! (defun bibtex-name-in-field (bounds &optional remove-opt-alt)
! "Get content of name in BibTeX field defined via BOUNDS.
! If optional arg REMOVE-OPT-ALT is non-nil remove \"OPT\" and \"ALT\"."
! (let ((name (buffer-substring-no-properties (nth 1 (car bounds))
! (nth 2 (car bounds)))))
! (if (and remove-opt-alt
! (string-match "\\`\\(OPT\\|ALT\\)" name))
! (substring name 3)
! name)))
(defun bibtex-text-in-field-bounds (bounds &optional remove-delim)
"Get content of text in BibTeX field defined via BOUNDS.
***************
*** 1311,1317 ****
content)))
(defun bibtex-text-in-field (field &optional follow-crossref)
! "Get content of field FIELD of current BibTeX entry. Return nil if not
found.
If optional arg FOLLOW-CROSSREF is non-nil, follow crossref."
(save-excursion
(save-restriction
--- 1353,1359 ----
content)))
(defun bibtex-text-in-field (field &optional follow-crossref)
! "Get content of field FIELD of current BibTeX entry. Return nil if not
found.
If optional arg FOLLOW-CROSSREF is non-nil, follow crossref."
(save-excursion
(save-restriction
***************
*** 1351,1357 ****
"Parse the postfix part of a BibTeX string entry, including the text.
If the string postfix is found, return a triple consisting of the position of
the actual starting and ending position of the text and the very last
! character of the string entry. Move point past BibTeX string entry."
(let* ((case-fold-search t)
(bounds (bibtex-parse-field-text)))
(when bounds
--- 1393,1399 ----
"Parse the postfix part of a BibTeX string entry, including the text.
If the string postfix is found, return a triple consisting of the position of
the actual starting and ending position of the text and the very last
! character of the string entry. Move point past BibTeX string entry."
(let* ((case-fold-search t)
(bounds (bibtex-parse-field-text)))
(when bounds
***************
*** 1373,1379 ****
(defun bibtex-search-forward-string ()
"Search forward to find a BibTeX string entry.
If a syntactically correct entry is found, a pair containing the boundaries of
! the reference key and text parts of the string is returned. Do not move
point."
(save-excursion
(save-match-data
(let ((case-fold-search t)
--- 1415,1421 ----
(defun bibtex-search-forward-string ()
"Search forward to find a BibTeX string entry.
If a syntactically correct entry is found, a pair containing the boundaries of
! the reference key and text parts of the string is returned. Do not move
point."
(save-excursion
(save-match-data
(let ((case-fold-search t)
***************
*** 1389,1395 ****
(defun bibtex-search-backward-string ()
"Search backward to find a BibTeX string entry.
If a syntactically correct entry is found, a pair containing the boundaries of
! the reference key and text parts of the field is returned. Do not move point."
(save-excursion
(save-match-data
(let ((case-fold-search t)
--- 1431,1437 ----
(defun bibtex-search-backward-string ()
"Search backward to find a BibTeX string entry.
If a syntactically correct entry is found, a pair containing the boundaries of
! the reference key and text parts of the field is returned. Do not move
point."
(save-excursion
(save-match-data
(let ((case-fold-search t)
***************
*** 1430,1436 ****
(match-end bibtex-type-in-head)))
(defun bibtex-key-in-head (&optional empty)
! "Extract BibTeX key in head. Return optional arg EMPTY if key is empty."
(if (match-beginning bibtex-key-in-head)
(buffer-substring-no-properties (match-beginning bibtex-key-in-head)
(match-end bibtex-key-in-head))
--- 1472,1478 ----
(match-end bibtex-type-in-head)))
(defun bibtex-key-in-head (&optional empty)
! "Extract BibTeX key in head. Return optional arg EMPTY if key is empty."
(if (match-beginning bibtex-key-in-head)
(buffer-substring-no-properties (match-beginning bibtex-key-in-head)
(match-end bibtex-key-in-head))
***************
*** 1438,1443 ****
--- 1480,1489 ----
;; Helper Functions
+ (defsubst bibtex-string= (str1 str2)
+ "Return t if STR1 and STR2 are equal, ignoring case."
+ (eq t (compare-strings str1 0 nil str2 0 nil t)))
+
(defun bibtex-delete-whitespace ()
"Delete all whitespace starting at point."
(if (looking-at "[ \t\n]+")
***************
*** 1448,1469 ****
(+ (count-lines 1 (point))
(if (equal (current-column) 0) 1 0)))
- (defun bibtex-member-of-regexp (string list)
- "Return non-nil if STRING is exactly matched by an element of LIST.
- The value is actually the tail of LIST whose car matches STRING."
- (let (case-fold-search)
- (while (and list
- (not (string-match (concat "\\`\\(?:" (car list) "\\)\\'")
string)))
- (setq list (cdr list)))
- list))
-
(defun bibtex-skip-to-valid-entry (&optional backward)
! "Unless at beginning of a valid BibTeX entry, move point to beginning of the
! next valid one. With optional argument BACKWARD non-nil, move backward to
! beginning of previous valid one. A valid entry is a syntactical correct one
with type contained in `bibtex-entry-field-alist' or, if
`bibtex-sort-ignore-string-entries' is nil, a syntactical correct string
! entry. Return buffer position of beginning and ending of entry if a valid
entry is found, nil otherwise."
(interactive "P")
(let ((case-fold-search t)
--- 1494,1507 ----
(+ (count-lines 1 (point))
(if (equal (current-column) 0) 1 0)))
(defun bibtex-skip-to-valid-entry (&optional backward)
! "Move point to beginning of the next valid BibTeX entry.
! Do not move if we are already at beginning of a valid BibTeX entry.
! With optional argument BACKWARD non-nil, move backward to
! beginning of previous valid one. A valid entry is a syntactical correct one
with type contained in `bibtex-entry-field-alist' or, if
`bibtex-sort-ignore-string-entries' is nil, a syntactical correct string
! entry. Return buffer position of beginning and ending of entry if a valid
entry is found, nil otherwise."
(interactive "P")
(let ((case-fold-search t)
***************
*** 1488,1496 ****
(defun bibtex-map-entries (fun)
"Call FUN for each BibTeX entry starting with the current.
! Do this to the end of the file. FUN is called with three arguments, the key of
the entry and the buffer positions (marker) of beginning and end of entry.
! Point is inside the entry. If `bibtex-sort-ignore-string-entries' is non-nil,
FUN will not be called for @String entries."
(let ((case-fold-search t))
(bibtex-beginning-of-entry)
--- 1526,1534 ----
(defun bibtex-map-entries (fun)
"Call FUN for each BibTeX entry starting with the current.
! Do this to the end of the file. FUN is called with three arguments, the key
of
the entry and the buffer positions (marker) of beginning and end of entry.
! Point is inside the entry. If `bibtex-sort-ignore-string-entries' is non-nil,
FUN will not be called for @String entries."
(let ((case-fold-search t))
(bibtex-beginning-of-entry)
***************
*** 1501,1507 ****
(end (copy-marker (save-excursion (bibtex-end-of-entry)))))
(save-excursion
(if (or (and (not bibtex-sort-ignore-string-entries)
! (string-equal "string" (downcase entry-type)))
(assoc-string entry-type bibtex-entry-field-alist t))
(funcall fun key beg end)))
(goto-char end)))))
--- 1539,1545 ----
(end (copy-marker (save-excursion (bibtex-end-of-entry)))))
(save-excursion
(if (or (and (not bibtex-sort-ignore-string-entries)
! (bibtex-string= entry-type "string"))
(assoc-string entry-type bibtex-entry-field-alist t))
(funcall fun key beg end)))
(goto-char end)))))
***************
*** 1556,1563 ****
(defun bibtex-search-entry (empty-head &optional bound noerror backward)
"Search for a BibTeX entry (maybe without reference key if EMPTY-HEAD is t).
! BOUND and NOERROR are exactly as in `re-search-forward'. If BACKWARD
! is non-nil, search is done in reverse direction. Point is moved past the
closing delimiter (at the beginning of entry if BACKWARD is non-nil).
Return a cons pair with buffer positions of beginning and end of entry.
After call to this function MATCH-BEGINNING and MATCH-END functions
--- 1594,1601 ----
(defun bibtex-search-entry (empty-head &optional bound noerror backward)
"Search for a BibTeX entry (maybe without reference key if EMPTY-HEAD is t).
! BOUND and NOERROR are exactly as in `re-search-forward'. If BACKWARD
! is non-nil, search is done in reverse direction. Point is moved past the
closing delimiter (at the beginning of entry if BACKWARD is non-nil).
Return a cons pair with buffer positions of beginning and end of entry.
After call to this function MATCH-BEGINNING and MATCH-END functions
***************
*** 1575,1581 ****
(if found
(progn (goto-char (match-beginning 0))
found)
! (cond ((equal noerror nil)
;; yell
(error "Backward search of BibTeX entry failed"))
((equal noerror t)
--- 1613,1619 ----
(if found
(progn (goto-char (match-beginning 0))
found)
! (cond ((not noerror)
;; yell
(error "Backward search of BibTeX entry failed"))
((equal noerror t)
***************
*** 1660,1666 ****
(skip-chars-forward " \t\n")))
(defun bibtex-beginning-of-first-entry ()
! "Go to the beginning of the first BibTeX entry in buffer. Return point."
(goto-char (point-min))
(if (re-search-forward "^[ \t]*@" nil 'move)
(beginning-of-line))
--- 1698,1704 ----
(skip-chars-forward " \t\n")))
(defun bibtex-beginning-of-first-entry ()
! "Go to the beginning of the first BibTeX entry in buffer. Return point."
(goto-char (point-min))
(if (re-search-forward "^[ \t]*@" nil 'move)
(beginning-of-line))
***************
*** 1684,1693 ****
(forward-char -1)))
(defun bibtex-enclosing-field (&optional noerr)
! "Search for BibTeX field enclosing point. Point moves to end of field.
! Use `match-beginning' and `match-end' to parse the field. If NOERR is non-nil,
! no error is signalled. In this case, bounds are returned on success,
! nil otherwise."
(let ((bounds (bibtex-search-backward-field bibtex-field-name t)))
(if (and bounds
(<= (bibtex-start-of-field bounds) (point))
--- 1722,1731 ----
(forward-char -1)))
(defun bibtex-enclosing-field (&optional noerr)
! "Search for BibTeX field enclosing point.
! Use `match-beginning' and `match-end' to parse the field. If NOERR is
non-nil,
! no error is signalled. In this case, bounds are returned on success,
! nil otherwise. Does not move point."
(let ((bounds (bibtex-search-backward-field bibtex-field-name t)))
(if (and bounds
(<= (bibtex-start-of-field bounds) (point))
***************
*** 1697,1703 ****
(error "Can't find enclosing BibTeX field")))))
(defun bibtex-enclosing-entry-maybe-empty-head ()
! "Search for BibTeX entry enclosing point. Move point to end of entry.
Beginning (but not end) of entry is given by (`match-beginning' 0)."
(let ((case-fold-search t)
(old-point (point)))
--- 1735,1741 ----
(error "Can't find enclosing BibTeX field")))))
(defun bibtex-enclosing-entry-maybe-empty-head ()
! "Search for BibTeX entry enclosing point. Move point to end of entry.
Beginning (but not end) of entry is given by (`match-beginning' 0)."
(let ((case-fold-search t)
(old-point (point)))
***************
*** 1732,1739 ****
(message "Mark set")
(bibtex-make-field (list (elt current 1) nil (elt current 2)) t))
((equal bibtex-last-kill-command 'entry)
! (if (not (eobp))
! (bibtex-beginning-of-entry))
(set-mark (point))
(message "Mark set")
(insert (elt current 1)))
--- 1770,1776 ----
(message "Mark set")
(bibtex-make-field (list (elt current 1) nil (elt current 2)) t))
((equal bibtex-last-kill-command 'entry)
! (unless (eobp) (bibtex-beginning-of-entry))
(set-mark (point))
(message "Mark set")
(insert (elt current 1)))
***************
*** 1741,1755 ****
(error "Unknown tag field: %s. Please submit a bug report"
bibtex-last-kill-command))))))
- (defun bibtex-assoc-regexp (regexp alist)
- "Return non-nil if REGEXP matches the car of an element of ALIST.
- The value is actually the element of ALIST matched by REGEXP.
- Case is ignored if `case-fold-search' is non-nil in the current buffer."
- (while (and alist
- (not (string-match regexp (caar alist))))
- (setq alist (cdr alist)))
- (car alist))
-
(defun bibtex-format-entry ()
"Helper function for `bibtex-clean-entry'.
Formats current entry according to variable `bibtex-entry-format'."
--- 1778,1783 ----
***************
*** 1764,1770 ****
unify-case inherit-booktitle)
bibtex-entry-format))
crossref-key bounds alternatives-there non-empty-alternative
! entry-list req-field-list field-done field-list)
;; identify entry type
(goto-char (point-min))
--- 1792,1798 ----
unify-case inherit-booktitle)
bibtex-entry-format))
crossref-key bounds alternatives-there non-empty-alternative
! entry-list req-field-list field-list)
;; identify entry type
(goto-char (point-min))
***************
*** 1792,1800 ****
;; one alternative is non-empty
(goto-char (point-min))
(let* ((fields-alist (bibtex-parse-entry))
! (case-fold-search t)
! (field (bibtex-assoc-regexp "\\`\\(OPT\\)?crossref\\'"
! fields-alist)))
(setq crossref-key (and field
(not (string-match bibtex-empty-field-re
(cdr field)))
--- 1820,1826 ----
;; one alternative is non-empty
(goto-char (point-min))
(let* ((fields-alist (bibtex-parse-entry))
! (field (assoc-string "crossref" fields-alist t)))
(setq crossref-key (and field
(not (string-match bibtex-empty-field-re
(cdr field)))
***************
*** 1806,1814 ****
(dolist (rfield req-field-list)
(when (nth 3 rfield) ; we should have an alternative
(setq alternatives-there t
! field (bibtex-assoc-regexp
! (concat "\\`\\(ALT\\)?" (car rfield) "\\'")
! fields-alist))
(if (and field
(not (string-match bibtex-empty-field-re
(cdr field))))
--- 1832,1838 ----
(dolist (rfield req-field-list)
(when (nth 3 rfield) ; we should have an alternative
(setq alternatives-there t
! field (assoc-string (car rfield) fields-alist t))
(if (and field
(not (string-match bibtex-empty-field-re
(cdr field))))
***************
*** 1887,1893 ****
;; update page dashes
(if (and (memq 'page-dashes format)
! (string-match "\\`\\(OPT\\)?pages\\'" field-name)
(progn (goto-char beg-text)
(looking-at
"\\([\"{][0-9]+\\)[ \t\n]*--?[
\t\n]*\\([0-9]+[\"}]\\)")))
--- 1911,1917 ----
;; update page dashes
(if (and (memq 'page-dashes format)
! (bibtex-string= field-name "pages")
(progn (goto-char beg-text)
(looking-at
"\\([\"{][0-9]+\\)[ \t\n]*--?[
\t\n]*\\([0-9]+[\"}]\\)")))
***************
*** 1896,1902 ****
;; use book title of crossref'd entry
(if (and (memq 'inherit-booktitle format)
empty-field
! (equal (downcase field-name) "booktitle")
crossref-key)
(let ((title (save-restriction
(widen)
--- 1920,1926 ----
;; use book title of crossref'd entry
(if (and (memq 'inherit-booktitle format)
empty-field
! (bibtex-string= field-name "booktitle")
crossref-key)
(let ((title (save-restriction
(widen)
***************
*** 1909,1915 ****
;; Use booktitle to set a missing title.
(if (and empty-field
! (equal (downcase field-name) "title"))
(let ((booktitle (bibtex-text-in-field "booktitle")))
(when booktitle
(setq empty-field nil)
--- 1933,1939 ----
;; Use booktitle to set a missing title.
(if (and empty-field
! (bibtex-string= field-name "title"))
(let ((booktitle (bibtex-text-in-field "booktitle")))
(when booktitle
(setq empty-field nil)
***************
*** 1990,1997 ****
(defun bibtex-autokey-abbrev (string len)
"Return an abbreviation of STRING with at least LEN characters.
If LEN is positive the abbreviation is terminated only after a consonant
! or at the word end. If LEN is negative the abbreviation is strictly
! enforced using abs (LEN) characters. If LEN is not a number, STRING
is returned unchanged."
(cond ((or (not (numberp len))
(<= (length string) (abs len)))
--- 2014,2021 ----
(defun bibtex-autokey-abbrev (string len)
"Return an abbreviation of STRING with at least LEN characters.
If LEN is positive the abbreviation is terminated only after a consonant
! or at the word end. If LEN is negative the abbreviation is strictly
! enforced using abs (LEN) characters. If LEN is not a number, STRING
is returned unchanged."
(cond ((or (not (numberp len))
(<= (length string) (abs len)))
***************
*** 2007,2015 ****
string)))))
(defun bibtex-autokey-get-field (field &optional change-list)
! "Get content of BibTeX field FIELD. Return empty string if not found.
Optional arg CHANGE-LIST is a list of substitution patterns that is
! applied to the content of FIELD. It is an alist with pairs
\(OLD-REGEXP . NEW-STRING\)."
(let ((content (bibtex-text-in-field field bibtex-autokey-use-crossref))
case-fold-search)
--- 2031,2039 ----
string)))))
(defun bibtex-autokey-get-field (field &optional change-list)
! "Get content of BibTeX field FIELD. Return empty string if not found.
Optional arg CHANGE-LIST is a list of substitution patterns that is
! applied to the content of FIELD. It is an alist with pairs
\(OLD-REGEXP . NEW-STRING\)."
(let ((content (bibtex-text-in-field field bibtex-autokey-use-crossref))
case-fold-search)
***************
*** 2023,2037 ****
"Get contents of the name field of the current entry.
Do some modifications based on `bibtex-autokey-name-change-strings'
and return results as a list."
! (let ((case-fold-search t))
! (mapcar 'bibtex-autokey-demangle-name
! (split-string (bibtex-autokey-get-field
! "author\\|editor"
! bibtex-autokey-name-change-strings)
! "[ \t\n]+and[ \t\n]+"))))
(defun bibtex-autokey-demangle-name (fullname)
! "Get the last part from a well-formed name and perform abbreviations."
(let* (case-fold-search
(name (cond ((string-match "\\([A-Z][^, ]*\\)[^,]*," fullname)
;; Name is of the form "von Last, First" or
--- 2047,2062 ----
"Get contents of the name field of the current entry.
Do some modifications based on `bibtex-autokey-name-change-strings'
and return results as a list."
! (let ((case-fold-search t)
! (names (bibtex-autokey-get-field "author\\|editor"
! bibtex-autokey-name-change-strings)))
! ;; Some entries do not have a name field.
! (unless (string= "" names)
! (mapcar 'bibtex-autokey-demangle-name
! (split-string names "[ \t\n]+and[ \t\n]+")))))
(defun bibtex-autokey-demangle-name (fullname)
! "Get the last part from a well-formed FULLNAME and perform abbreviations."
(let* (case-fold-search
(name (cond ((string-match "\\([A-Z][^, ]*\\)[^,]*," fullname)
;; Name is of the form "von Last, First" or
***************
*** 2059,2076 ****
(defun bibtex-autokey-get-title ()
"Get title field contents up to a terminator."
! (let ((titlestring
(bibtex-autokey-get-field "title"
bibtex-autokey-titleword-change-strings)))
;; ignore everything past a terminator
! (let ((case-fold-search t))
! (dolist (terminator bibtex-autokey-title-terminators)
! (if (string-match terminator titlestring)
! (setq titlestring (substring titlestring 0 (match-beginning
0))))))
;; gather words from titlestring into a list. Ignore
;; specific words and use only a specific amount of words.
(let ((counter 0)
! case-fold-search titlewords titlewords-extra titleword end-match)
(while (and (or (not (numberp bibtex-autokey-titlewords))
(< counter (+ bibtex-autokey-titlewords
bibtex-autokey-titlewords-stretch)))
--- 2084,2101 ----
(defun bibtex-autokey-get-title ()
"Get title field contents up to a terminator."
! (let ((case-fold-search t)
! (titlestring
(bibtex-autokey-get-field "title"
bibtex-autokey-titleword-change-strings)))
;; ignore everything past a terminator
! (dolist (terminator bibtex-autokey-title-terminators)
! (if (string-match terminator titlestring)
! (setq titlestring (substring titlestring 0 (match-beginning 0)))))
;; gather words from titlestring into a list. Ignore
;; specific words and use only a specific amount of words.
(let ((counter 0)
! titlewords titlewords-extra titleword end-match)
(while (and (or (not (numberp bibtex-autokey-titlewords))
(< counter (+ bibtex-autokey-titlewords
bibtex-autokey-titlewords-stretch)))
***************
*** 2078,2085 ****
(setq end-match (match-end 0)
titleword (substring titlestring
(match-beginning 0) end-match))
! (unless (bibtex-member-of-regexp titleword
! bibtex-autokey-titleword-ignore)
(setq titleword
(funcall bibtex-autokey-titleword-case-convert titleword))
(if (or (not (numberp bibtex-autokey-titlewords))
--- 2103,2114 ----
(setq end-match (match-end 0)
titleword (substring titlestring
(match-beginning 0) end-match))
! (unless (let ((lst bibtex-autokey-titleword-ignore))
! (while (and lst
! (not (string-match (concat "\\`\\(?:" (car lst)
! "\\)\\'")
titleword)))
! (setq lst (cdr lst)))
! lst)
(setq titleword
(funcall bibtex-autokey-titleword-case-convert titleword))
(if (or (not (numberp bibtex-autokey-titlewords))
***************
*** 2097,2103 ****
"Do some abbreviations on TITLEWORD.
The rules are defined in `bibtex-autokey-titleword-abbrevs'
and `bibtex-autokey-titleword-length'."
! (let ((case-folde-search t)
(alist bibtex-autokey-titleword-abbrevs))
(while (and alist
(not (string-match (concat "\\`\\(?:" (caar alist) "\\)\\'")
--- 2126,2132 ----
"Do some abbreviations on TITLEWORD.
The rules are defined in `bibtex-autokey-titleword-abbrevs'
and `bibtex-autokey-titleword-length'."
! (let ((case-fold-search t)
(alist bibtex-autokey-titleword-abbrevs))
(while (and alist
(not (string-match (concat "\\`\\(?:" (caar alist) "\\)\\'")
***************
*** 2119,2125 ****
`bibtex-autokey-name-change-strings' to the corresponding new
one (see documentation of this variable for further detail).
4. For every of at least first `bibtex-autokey-names' names in
! the name field, determine the last name. If there are maximal
`bibtex-autokey-names' + `bibtex-autokey-names-stretch'
names, all names are used.
5. From every last name, take at least `bibtex-autokey-name-length'
--- 2148,2154 ----
`bibtex-autokey-name-change-strings' to the corresponding new
one (see documentation of this variable for further detail).
4. For every of at least first `bibtex-autokey-names' names in
! the name field, determine the last name. If there are maximal
`bibtex-autokey-names' + `bibtex-autokey-names-stretch'
names, all names are used.
5. From every last name, take at least `bibtex-autokey-name-length'
***************
*** 2128,2139 ****
`bibtex-autokey-name-case-convert'.
7. Build the name part of the key by concatenating all
abbreviated last names with the string
! `bibtex-autokey-name-separator' between any two. If there are
more names than are used in the name part, prepend the string
contained in `bibtex-autokey-additional-names'.
8. Build the year part of the key by truncating the contents of
the year field to the rightmost `bibtex-autokey-year-length'
! digits (useful values are 2 and 4). If the year field (or any
other field required to generate the key) is absent, but the entry
has a valid crossref field and the variable
`bibtex-autokey-use-crossref' is non-nil, use the field of the
--- 2157,2168 ----
`bibtex-autokey-name-case-convert'.
7. Build the name part of the key by concatenating all
abbreviated last names with the string
! `bibtex-autokey-name-separator' between any two. If there are
more names than are used in the name part, prepend the string
contained in `bibtex-autokey-additional-names'.
8. Build the year part of the key by truncating the contents of
the year field to the rightmost `bibtex-autokey-year-length'
! digits (useful values are 2 and 4). If the year field (or any
other field required to generate the key) is absent, but the entry
has a valid crossref field and the variable
`bibtex-autokey-use-crossref' is non-nil, use the field of the
***************
*** 2149,2155 ****
appear in `bibtex-autokey-titleword-ignore'.
Build the title part of the key by using at least the first
`bibtex-autokey-titlewords' words from this
! abbreviated title. If the abbreviated title ends after
maximal `bibtex-autokey-titlewords' +
`bibtex-autokey-titlewords-stretch' words, all
words from the abbreviated title are used.
--- 2178,2184 ----
appear in `bibtex-autokey-titleword-ignore'.
Build the title part of the key by using at least the first
`bibtex-autokey-titlewords' words from this
! abbreviated title. If the abbreviated title ends after
maximal `bibtex-autokey-titlewords' +
`bibtex-autokey-titlewords-stretch' words, all
words from the abbreviated title are used.
***************
*** 2170,2182 ****
and the title part with `bibtex-autokey-name-year-separator'
between the name part and the year part if both are non-empty
and `bibtex-autokey-year-title-separator' between the year
! part and the title part if both are non-empty. If the year
part is empty, but not the other two parts,
`bibtex-autokey-year-title-separator' is used as well.
16. If the value of `bibtex-autokey-before-presentation-function'
! is non-nil, it must be a function taking one argument. This
function is then called with the generated key as the
! argument. The return value of this function (a string) is
used as the key.
17. If the value of `bibtex-autokey-edit-before-use' is non-nil,
the key is then presented in the minibuffer to the user,
--- 2199,2211 ----
and the title part with `bibtex-autokey-name-year-separator'
between the name part and the year part if both are non-empty
and `bibtex-autokey-year-title-separator' between the year
! part and the title part if both are non-empty. If the year
part is empty, but not the other two parts,
`bibtex-autokey-year-title-separator' is used as well.
16. If the value of `bibtex-autokey-before-presentation-function'
! is non-nil, it must be a function taking one argument. This
function is then called with the generated key as the
! argument. The return value of this function (a string) is
used as the key.
17. If the value of `bibtex-autokey-edit-before-use' is non-nil,
the key is then presented in the minibuffer to the user,
***************
*** 2230,2238 ****
The buffer might possibly be restricted.
Find both entry keys and crossref entries.
If ADD is non-nil add the new keys to `bibtex-reference-keys' instead of
! simply resetting it. If ADD is an alist of keys, also add ADD to
! `bibtex-reference-keys'. If ABORTABLE is non-nil abort on user
! input. If VERBOSE is non-nil gives messages about progress.
Return alist of keys if parsing was completed, `aborted' otherwise."
(let ((reference-keys (if (and add
(listp bibtex-reference-keys))
--- 2259,2267 ----
The buffer might possibly be restricted.
Find both entry keys and crossref entries.
If ADD is non-nil add the new keys to `bibtex-reference-keys' instead of
! simply resetting it. If ADD is an alist of keys, also add ADD to
! `bibtex-reference-keys'. If ABORTABLE is non-nil abort on user
! input. If VERBOSE is non-nil gives messages about progress.
Return alist of keys if parsing was completed, `aborted' otherwise."
(let ((reference-keys (if (and add
(listp bibtex-reference-keys))
***************
*** 2296,2303 ****
"Set `bibtex-strings' to the string definitions in the whole buffer.
The buffer might possibly be restricted.
If ADD is non-nil add the new strings to `bibtex-strings' instead of
! simply resetting it. If ADD is an alist of strings, also add ADD to
! `bibtex-strings'. If ABORTABLE is non-nil abort on user input.
Return alist of strings if parsing was completed, `aborted' otherwise."
(save-excursion
(save-match-data
--- 2325,2332 ----
"Set `bibtex-strings' to the string definitions in the whole buffer.
The buffer might possibly be restricted.
If ADD is non-nil add the new strings to `bibtex-strings' instead of
! simply resetting it. If ADD is an alist of strings, also add ADD to
! `bibtex-strings'. If ABORTABLE is non-nil abort on user input.
Return alist of strings if parsing was completed, `aborted' otherwise."
(save-excursion
(save-match-data
***************
*** 2308,2314 ****
bounds key)
(if (listp add)
(dolist (string add)
! (unless (assoc (car string) strings)
(push string strings))))
(catch 'userkey
(while (setq bounds (bibtex-search-forward-string))
--- 2337,2343 ----
bounds key)
(if (listp add)
(dolist (string add)
! (unless (assoc-string (car string) strings t)
(push string strings))))
(catch 'userkey
(while (setq bounds (bibtex-search-forward-string))
***************
*** 2317,2325 ****
;; user has aborted by typing a key --> return `aborted'
(throw 'userkey 'aborted))
(setq key (bibtex-reference-key-in-string bounds))
! (if (not (assoc key strings))
! (push (cons key (bibtex-text-in-string bounds t))
! strings))
(goto-char (bibtex-end-of-text-in-string bounds)))
;; successful operation --> return `bibtex-strings'
(setq bibtex-strings strings))))))
--- 2346,2354 ----
;; user has aborted by typing a key --> return `aborted'
(throw 'userkey 'aborted))
(setq key (bibtex-reference-key-in-string bounds))
! (unless (assoc-string key strings t)
! (push (cons key (bibtex-text-in-string bounds t))
! strings))
(goto-char (bibtex-end-of-text-in-string bounds)))
;; successful operation --> return `bibtex-strings'
(setq bibtex-strings strings))))))
***************
*** 2357,2363 ****
(append bibtex-predefined-strings (nreverse compl)))))
(defun bibtex-parse-buffers-stealthily ()
! "Called by `bibtex-run-with-idle-timer'. Whenever emacs has been idle
for `bibtex-parse-keys-timeout' seconds, all BibTeX buffers (starting
with the current) are parsed."
(save-excursion
--- 2386,2393 ----
(append bibtex-predefined-strings (nreverse compl)))))
(defun bibtex-parse-buffers-stealthily ()
! "Parse buffer in the background during idle time.
! Called by `bibtex-run-with-idle-timer'. Whenever Emacs has been idle
for `bibtex-parse-keys-timeout' seconds, all BibTeX buffers (starting
with the current) are parsed."
(save-excursion
***************
*** 2381,2389 ****
(setq buffers (cdr buffers))))))
(defun bibtex-complete-internal (completions)
! "Complete word fragment before point to longest prefix of one
! string defined in list COMPLETIONS. If point is not after the part
! of a word, all strings are listed. Return completion."
(let* ((case-fold-search t)
(beg (save-excursion
(re-search-backward "[ \t{\"]")
--- 2411,2419 ----
(setq buffers (cdr buffers))))))
(defun bibtex-complete-internal (completions)
! "Complete word fragment before point to longest prefix of COMPLETIONS.
! COMPLETIONS should be a list of strings. If point is not after the part
! of a word, all strings are listed. Return completion."
(let* ((case-fold-search t)
(beg (save-excursion
(re-search-backward "[ \t{\"]")
***************
*** 2409,2419 ****
;; return value is handled by choose-completion-string-functions
nil))))
! (defun bibtex-complete-string-cleanup (str)
"Cleanup after inserting string STR.
! Remove enclosing field delimiters for string STR. Display message with
! expansion of STR."
! (let ((pair (assoc str bibtex-strings)))
(when pair
(if (cdr pair)
(message "Abbreviation for `%s'" (cdr pair)))
--- 2439,2450 ----
;; return value is handled by choose-completion-string-functions
nil))))
! (defun bibtex-complete-string-cleanup (str strings-alist)
"Cleanup after inserting string STR.
! Remove enclosing field delimiters for string STR. Display message with
! expansion of STR using expansion list STRINGS-ALIST."
! (let ((pair (if (stringp str)
! (assoc-string str strings-alist t))))
(when pair
(if (cdr pair)
(message "Abbreviation for `%s'" (cdr pair)))
***************
*** 2427,2432 ****
--- 2458,2495 ----
(bibtex-end-of-text-in-field bounds)))
(bibtex-remove-delimiters))))))))
+ (defun bibtex-complete-key-cleanup (key)
+ "Display message on entry KEY after completion of a crossref key."
+ (save-excursion
+ ;; Don't do anything if we completed the key of an entry.
+ (let ((pnt (bibtex-beginning-of-entry)))
+ (if (and (stringp key)
+ (bibtex-find-entry key)
+ (/= pnt (point)))
+ (let* ((bibtex-autokey-name-case-convert 'identity)
+ (bibtex-autokey-name-length 'infty)
+ (nl (bibtex-autokey-get-names))
+ (name (concat (nth 0 nl) (if (nth 1 nl) " etal")))
+ (year (bibtex-autokey-get-field "year"))
+ (bibtex-autokey-titlewords 5)
+ (bibtex-autokey-titlewords-stretch 2)
+ (bibtex-autokey-titleword-case-convert 'identity)
+ (bibtex-autokey-titleword-length 5)
+ (title (mapconcat 'identity
+ (bibtex-autokey-get-title) " "))
+ (journal (bibtex-autokey-get-field
+ "journal" bibtex-autokey-transcriptions))
+ (volume (bibtex-autokey-get-field "volume"))
+ (pages (bibtex-autokey-get-field "pages" '(("-.*\\'" .
"")))))
+ (message "Ref:%s"
+ (mapconcat (lambda (arg)
+ (if (not (string= "" (cdr arg)))
+ (concat (car arg) (cdr arg))))
+ `((" " . ,name) (" " . ,year)
+ (": " . ,title) (", " . ,journal)
+ (" " . ,volume) (":" . ,pages))
+ "")))))))
+
(defun bibtex-choose-completion-string (choice buffer mini-p base-size)
;; Code borrowed from choose-completion-string:
;; We must duplicate the code from choose-completion-string
***************
*** 2450,2456 ****
(set-window-point window (point))))
(defun bibtex-pop (arg direction)
! "Generic function used by `bibtex-pop-previous' and `bibtex-pop-next'."
(let (bibtex-help-message)
(bibtex-find-text nil))
(save-excursion
--- 2513,2520 ----
(set-window-point window (point))))
(defun bibtex-pop (arg direction)
! "Fill current field from the ARG'th same field's text in DIRECTION.
! Generic function used by `bibtex-pop-previous' and `bibtex-pop-next'."
(let (bibtex-help-message)
(bibtex-find-text nil))
(save-excursion
***************
*** 2460,2476 ****
(bounds (bibtex-enclosing-field))
(start-old-text (bibtex-start-of-text-in-field bounds))
(stop-old-text (bibtex-end-of-text-in-field bounds))
! (start-name (bibtex-start-of-name-in-field bounds))
! (stop-name (bibtex-end-of-name-in-field bounds))
! ;; construct regexp for field with same name as this one,
! ;; ignoring possible OPT's or ALT's
! (field-name (progn
! (goto-char start-name)
! (buffer-substring-no-properties
! (if (looking-at "\\(OPT\\)\\|\\(ALT\\)")
! (match-end 0)
! (point))
! stop-name))))
;; if executed several times in a row, start each search where
;; the last one was finished
(unless (eq last-command 'bibtex-pop)
--- 2524,2530 ----
(bounds (bibtex-enclosing-field))
(start-old-text (bibtex-start-of-text-in-field bounds))
(stop-old-text (bibtex-end-of-text-in-field bounds))
! (field-name (bibtex-name-in-field bounds t)))
;; if executed several times in a row, start each search where
;; the last one was finished
(unless (eq last-command 'bibtex-pop)
***************
*** 2523,2537 ****
General information on working with BibTeX mode:
You should use commands such as \\[bibtex-Book] to get a template for a
! specific entry. You should then fill in all desired fields using
! \\[bibtex-next-field] to jump from field to field. After having filled
in all desired fields in the entry, you should clean the new entry
with the command \\[bibtex-clean-entry].
Some features of BibTeX mode are available only by setting the variable
! `bibtex-maintain-sorted-entries' to non-nil. However, then BibTeX mode will
work only with buffers containing valid (syntactical correct) entries
! and with entries being sorted. This is usually the case, if you have
created a buffer completely with BibTeX mode and finished every new
entry with \\[bibtex-clean-entry].
--- 2577,2591 ----
General information on working with BibTeX mode:
You should use commands such as \\[bibtex-Book] to get a template for a
! specific entry. You should then fill in all desired fields using
! \\[bibtex-next-field] to jump from field to field. After having filled
in all desired fields in the entry, you should clean the new entry
with the command \\[bibtex-clean-entry].
Some features of BibTeX mode are available only by setting the variable
! `bibtex-maintain-sorted-entries' to non-nil. However, then BibTeX mode will
work only with buffers containing valid (syntactical correct) entries
! and with entries being sorted. This is usually the case, if you have
created a buffer completely with BibTeX mode and finished every new
entry with \\[bibtex-clean-entry].
***************
*** 2639,2647 ****
)
nil
(font-lock-syntactic-keywords . bibtex-font-lock-syntactic-keywords)
(font-lock-mark-block-function
. (lambda ()
! (set-mark (bibtex-end-of-entry))
(bibtex-beginning-of-entry)))))
(setq imenu-generic-expression
(list (list nil bibtex-entry-head bibtex-key-in-head)))
--- 2693,2702 ----
)
nil
(font-lock-syntactic-keywords . bibtex-font-lock-syntactic-keywords)
+ (font-lock-extra-managed-props . (mouse-face keymap))
(font-lock-mark-block-function
. (lambda ()
! (set-mark (bibtex-end-of-entry))
(bibtex-beginning-of-entry)))))
(setq imenu-generic-expression
(list (list nil bibtex-entry-head bibtex-key-in-head)))
***************
*** 2681,2687 ****
(cons required optional)))
(defun bibtex-entry (entry-type)
! "Insert a new BibTeX entry.
After insertion it calls the functions in `bibtex-add-entry-hook'."
(interactive (let* ((completion-ignore-case t)
(e-t (completing-read
--- 2736,2742 ----
(cons required optional)))
(defun bibtex-entry (entry-type)
! "Insert a new BibTeX entry of type ENTRY-TYPE.
After insertion it calls the functions in `bibtex-add-entry-hook'."
(interactive (let* ((completion-ignore-case t)
(e-t (completing-read
***************
*** 2698,2705 ****
(insert "@" entry-type (bibtex-entry-left-delimiter))
(if key (insert key))
(save-excursion
! (mapcar 'bibtex-make-field (car field-list))
! (mapcar 'bibtex-make-optional-field (cdr field-list))
(if bibtex-comma-after-last-field
(insert ","))
(insert "\n")
--- 2753,2760 ----
(insert "@" entry-type (bibtex-entry-left-delimiter))
(if key (insert key))
(save-excursion
! (mapc 'bibtex-make-field (car field-list))
! (mapc 'bibtex-make-optional-field (cdr field-list))
(if bibtex-comma-after-last-field
(insert ","))
(insert "\n")
***************
*** 2722,2750 ****
(let* ((fields-alist (bibtex-parse-entry))
(field-list (bibtex-field-list
(substring (cdr (assoc "=type=" fields-alist))
! 1))) ; don't want @
! (case-fold-search t))
(dolist (field (car field-list))
! (unless (bibtex-assoc-regexp (concat "\\`\\(ALT\\)?" (car field)
"\\'")
! fields-alist)
(bibtex-make-field field)))
(dolist (field (cdr field-list))
! (unless (bibtex-assoc-regexp (concat "\\`\\(OPT\\)?" (car field)
"\\'")
! fields-alist)
(bibtex-make-optional-field field))))))
(defun bibtex-parse-entry ()
"Parse entry at point, return an alist.
The alist elements have the form (FIELD . TEXT), where FIELD can also be
! the special strings \"=type=\" and \"=key=\". For the FIELD \"=key=\"
! TEXT may be nil. Move point to the end of the last field."
(let (alist bounds)
(when (looking-at bibtex-entry-maybe-empty-head)
(push (cons "=type=" (match-string bibtex-type-in-head)) alist)
(push (cons "=key=" (match-string bibtex-key-in-head)) alist)
(goto-char (match-end 0))
(while (setq bounds (bibtex-parse-field bibtex-field-name))
! (push (cons (bibtex-name-in-field bounds)
(bibtex-text-in-field-bounds bounds))
alist)
(goto-char (bibtex-end-of-field bounds))))
--- 2777,2803 ----
(let* ((fields-alist (bibtex-parse-entry))
(field-list (bibtex-field-list
(substring (cdr (assoc "=type=" fields-alist))
! 1)))) ; don't want @
(dolist (field (car field-list))
! (unless (assoc-string (car field) fields-alist t)
(bibtex-make-field field)))
(dolist (field (cdr field-list))
! (unless (assoc-string (car field) fields-alist t)
(bibtex-make-optional-field field))))))
(defun bibtex-parse-entry ()
"Parse entry at point, return an alist.
The alist elements have the form (FIELD . TEXT), where FIELD can also be
! the special strings \"=type=\" and \"=key=\". For the FIELD \"=key=\"
! TEXT may be nil. Remove \"OPT\" and \"ALT\" from FIELD.
! Move point to the end of the last field."
(let (alist bounds)
(when (looking-at bibtex-entry-maybe-empty-head)
(push (cons "=type=" (match-string bibtex-type-in-head)) alist)
(push (cons "=key=" (match-string bibtex-key-in-head)) alist)
(goto-char (match-end 0))
(while (setq bounds (bibtex-parse-field bibtex-field-name))
! (push (cons (bibtex-name-in-field bounds t)
(bibtex-text-in-field-bounds bounds))
alist)
(goto-char (bibtex-end-of-field bounds))))
***************
*** 2770,2776 ****
(bibtex-beginning-of-entry)
(when (and
(looking-at bibtex-entry-head)
! (equal type (match-string bibtex-type-in-head))
;; In case we found ourselves :-(
(not (equal key (setq tmp (match-string bibtex-key-in-head)))))
(setq other-key tmp)
--- 2823,2829 ----
(bibtex-beginning-of-entry)
(when (and
(looking-at bibtex-entry-head)
! (bibtex-string= type (match-string bibtex-type-in-head))
;; In case we found ourselves :-(
(not (equal key (setq tmp (match-string bibtex-key-in-head)))))
(setq other-key tmp)
***************
*** 2780,2786 ****
(bibtex-skip-to-valid-entry)
(when (and
(looking-at bibtex-entry-head)
! (equal type (match-string bibtex-type-in-head))
;; In case we found ourselves :-(
(not (equal key (setq tmp (match-string bibtex-key-in-head))))
(or (not other-key)
--- 2833,2839 ----
(bibtex-skip-to-valid-entry)
(when (and
(looking-at bibtex-entry-head)
! (bibtex-string= type (match-string bibtex-type-in-head))
;; In case we found ourselves :-(
(not (equal key (setq tmp (match-string bibtex-key-in-head))))
(or (not other-key)
***************
*** 2794,2804 ****
(setq other (save-excursion (goto-char other) (bibtex-parse-entry)))
(setq key-end (point)) ;In case parse-entry changed the buffer.
(while (setq bounds (bibtex-parse-field bibtex-field-name))
! (goto-char (bibtex-start-of-name-in-field bounds))
! (let* ((name (buffer-substring
! (if (looking-at "ALT\\|OPT") (match-end 0) (point))
! (bibtex-end-of-name-in-field bounds)))
! (text (assoc-string name other t)))
(goto-char (bibtex-start-of-text-in-field bounds))
(if (not (and (looking-at bibtex-empty-field-re) text))
(goto-char (bibtex-end-of-field bounds))
--- 2847,2854 ----
(setq other (save-excursion (goto-char other) (bibtex-parse-entry)))
(setq key-end (point)) ;In case parse-entry changed the buffer.
(while (setq bounds (bibtex-parse-field bibtex-field-name))
! (let ((text (assoc-string (bibtex-name-in-field bounds t)
! other t)))
(goto-char (bibtex-start-of-text-in-field bounds))
(if (not (and (looking-at bibtex-empty-field-re) text))
(goto-char (bibtex-end-of-field bounds))
***************
*** 2821,2833 ****
(interactive)
(save-excursion
(let* ((case-fold-search t)
! (bounds (bibtex-enclosing-field))
! (mb (bibtex-start-of-name-in-field bounds))
! (field-name (buffer-substring-no-properties
! (if (progn (goto-char mb)
! (looking-at "OPT\\|ALT"))
! (match-end 0) mb)
! (bibtex-end-of-name-in-field bounds)))
(field-list (bibtex-field-list (progn (re-search-backward
bibtex-entry-maybe-empty-head nil t)
(bibtex-type-in-head))))
--- 2871,2877 ----
(interactive)
(save-excursion
(let* ((case-fold-search t)
! (field-name (bibtex-name-in-field (bibtex-enclosing-field) t))
(field-list (bibtex-field-list (progn (re-search-backward
bibtex-entry-maybe-empty-head nil t)
(bibtex-type-in-head))))
***************
*** 2843,2849 ****
"Make a field named FIELD in current BibTeX entry.
FIELD is either a string or a list of the form
\(FIELD-NAME COMMENT-STRING INIT ALTERNATIVE-FLAG) as in
! `bibtex-entry-field-alist'."
(interactive
(list (let ((completion-ignore-case t)
(field-list (bibtex-field-list
--- 2887,2894 ----
"Make a field named FIELD in current BibTeX entry.
FIELD is either a string or a list of the form
\(FIELD-NAME COMMENT-STRING INIT ALTERNATIVE-FLAG) as in
! `bibtex-entry-field-alist'.
! If CALLED-BY-YANK is non-nil, don't insert delimiters."
(interactive
(list (let ((completion-ignore-case t)
(field-list (bibtex-field-list
***************
*** 2868,2883 ****
(indent-to-column (+ bibtex-entry-offset
(- bibtex-text-indentation 2))))
(insert "= ")
! (if (not bibtex-align-at-equal-sign)
! (indent-to-column (+ bibtex-entry-offset
! bibtex-text-indentation)))
! (if (not called-by-yank) (insert (bibtex-field-left-delimiter)))
(let ((init (nth 2 field)))
(cond ((stringp init)
(insert init))
((fboundp init)
(insert (funcall init)))))
! (if (not called-by-yank) (insert (bibtex-field-right-delimiter)))
(when (interactive-p)
(forward-char -1)
(bibtex-print-help-message)))
--- 2913,2928 ----
(indent-to-column (+ bibtex-entry-offset
(- bibtex-text-indentation 2))))
(insert "= ")
! (unless bibtex-align-at-equal-sign
! (indent-to-column (+ bibtex-entry-offset
! bibtex-text-indentation)))
! (unless called-by-yank (insert (bibtex-field-left-delimiter)))
(let ((init (nth 2 field)))
(cond ((stringp init)
(insert init))
((fboundp init)
(insert (funcall init)))))
! (unless called-by-yank (insert (bibtex-field-right-delimiter)))
(when (interactive-p)
(forward-char -1)
(bibtex-print-help-message)))
***************
*** 2885,2892 ****
(defun bibtex-beginning-of-entry ()
"Move to beginning of BibTeX entry (beginning of line).
If inside an entry, move to the beginning of it, otherwise move to the
! beginning of the previous entry. If point is ahead of all BibTeX entries
! move point to the beginning of buffer. Return the new location of point."
(interactive)
(skip-chars-forward " \t")
(if (looking-at "@")
--- 2930,2937 ----
(defun bibtex-beginning-of-entry ()
"Move to beginning of BibTeX entry (beginning of line).
If inside an entry, move to the beginning of it, otherwise move to the
! beginning of the previous entry. If point is ahead of all BibTeX entries
! move point to the beginning of buffer. Return the new location of point."
(interactive)
(skip-chars-forward " \t")
(if (looking-at "@")
***************
*** 2897,2903 ****
(defun bibtex-end-of-entry ()
"Move to end of BibTeX entry (past the closing brace).
If inside an entry, move to the end of it, otherwise move to the end
! of the previous entry. Do not move if ahead of first entry.
Return the new location of point."
(interactive)
(let ((case-fold-search t)
--- 2942,2948 ----
(defun bibtex-end-of-entry ()
"Move to end of BibTeX entry (past the closing brace).
If inside an entry, move to the end of it, otherwise move to the end
! of the previous entry. Do not move if ahead of first entry.
Return the new location of point."
(interactive)
(let ((case-fold-search t)
***************
*** 2997,3005 ****
(bibtex-end-of-entry))))
(defun bibtex-entry-index ()
! "Return the index of the BibTeX entry at point. Move point.
The index is a list (KEY CROSSREF-KEY ENTRY-NAME) that is used for sorting
! the entries of the BibTeX buffer. Return nil if no entry found."
(let ((case-fold-search t))
(if (re-search-forward bibtex-entry-maybe-empty-head nil t)
(let ((key (bibtex-key-in-head))
--- 3042,3050 ----
(bibtex-end-of-entry))))
(defun bibtex-entry-index ()
! "Return the index of the BibTeX entry at point. Move point.
The index is a list (KEY CROSSREF-KEY ENTRY-NAME) that is used for sorting
! the entries of the BibTeX buffer. Return nil if no entry found."
(let ((case-fold-search t))
(if (re-search-forward bibtex-entry-maybe-empty-head nil t)
(let ((key (bibtex-key-in-head))
***************
*** 3049,3056 ****
(defun bibtex-sort-buffer ()
"Sort BibTeX buffer alphabetically by key.
The predicate for sorting is defined via `bibtex-maintain-sorted-entries'.
! If its value is nil use plain sorting. Text outside of BibTeX entries is not
! affected. If `bibtex-sort-ignore-string-entries' is non-nil, @String entries
will be ignored."
(interactive)
(save-restriction
--- 3094,3101 ----
(defun bibtex-sort-buffer ()
"Sort BibTeX buffer alphabetically by key.
The predicate for sorting is defined via `bibtex-maintain-sorted-entries'.
! If its value is nil use plain sorting. Text outside of BibTeX entries is not
! affected. If `bibtex-sort-ignore-string-entries' is non-nil, @String entries
will be ignored."
(interactive)
(save-restriction
***************
*** 3084,3096 ****
(error "This entry must not follow the crossrefed entry!"))
(goto-char pos)))
! (defun bibtex-find-entry (key)
"Move point to the beginning of BibTeX entry named KEY.
! Return position of entry if KEY is found or nil if not found."
! (interactive (list (bibtex-read-key "Find key: ")))
(let* (case-fold-search
(pnt (save-excursion
! (goto-char (point-min))
(if (re-search-forward (concat "^[ \t]*\\("
bibtex-entry-type
"\\)[ \t]*[({][ \t\n]*\\("
--- 3129,3145 ----
(error "This entry must not follow the crossrefed entry!"))
(goto-char pos)))
! (defun bibtex-find-entry (key &optional start)
"Move point to the beginning of BibTeX entry named KEY.
! Return position of entry if KEY is found or nil if not found.
! Optional arg START is buffer position where the search starts.
! If it is nil, start search at beginning of buffer.
! With prefix arg, the value of START is position of point."
! (interactive (list (bibtex-read-key "Find key: ")
! (if current-prefix-arg (point))))
(let* (case-fold-search
(pnt (save-excursion
! (goto-char (or start (point-min)))
(if (re-search-forward (concat "^[ \t]*\\("
bibtex-entry-type
"\\)[ \t]*[({][ \t\n]*\\("
***************
*** 3108,3114 ****
INDEX is a list (KEY CROSSREF-KEY ENTRY-NAME).
Move point where the entry KEY should be placed.
If `bibtex-maintain-sorted-entries' is non-nil, perform a binary
! search to look for place for KEY. This will fail if buffer is not in
sorted order, see \\[bibtex-validate].)
Return t if preparation was successful or nil if entry KEY already exists."
(let ((key (nth 0 index))
--- 3157,3163 ----
INDEX is a list (KEY CROSSREF-KEY ENTRY-NAME).
Move point where the entry KEY should be placed.
If `bibtex-maintain-sorted-entries' is non-nil, perform a binary
! search to look for place for KEY. This will fail if buffer is not in
sorted order, see \\[bibtex-validate].)
Return t if preparation was successful or nil if entry KEY already exists."
(let ((key (nth 0 index))
***************
*** 3157,3164 ****
;; buffer contains no valid entries or
;; greater than last entry --> append
(bibtex-end-of-entry)
! (if (not (bobp))
! (newline (forward-line 2)))
(beginning-of-line)))))
(unless key-exist t)))
--- 3206,3212 ----
;; buffer contains no valid entries or
;; greater than last entry --> append
(bibtex-end-of-entry)
! (unless (bobp) (newline (forward-line 2)))
(beginning-of-line)))))
(unless key-exist t)))
***************
*** 3233,3241 ****
(goto-char (point-min))
(bibtex-progress-message
"Checking required fields and month fields")
! (let ((bibtex-sort-ignore-string-entries t)
! (questionable-month
! (regexp-opt (mapcar 'car
bibtex-predefined-month-strings))))
(bibtex-map-entries
(lambda (key beg end)
(bibtex-progress-message)
--- 3281,3287 ----
(goto-char (point-min))
(bibtex-progress-message
"Checking required fields and month fields")
! (let ((bibtex-sort-ignore-string-entries t))
(bibtex-map-entries
(lambda (key beg end)
(bibtex-progress-message)
***************
*** 3251,3267 ****
(while (setq bounds (bibtex-search-forward-field
bibtex-field-name end))
(goto-char (bibtex-start-of-text-in-field bounds))
! (let ((field-name (downcase (bibtex-name-in-field
bounds)))
! case-fold-search)
! (if (and (equal field-name "month")
! (not (string-match questionable-month
!
(bibtex-text-in-field-bounds bounds))))
(push (list (bibtex-current-line)
"Questionable month field")
error-list))
(setq req (delete (assoc-string field-name req t) req)
creq (delete (assoc-string field-name creq t)
creq))
! (if (equal field-name "crossref")
(setq crossref-there t))))
(if crossref-there
(setq req creq))
--- 3297,3312 ----
(while (setq bounds (bibtex-search-forward-field
bibtex-field-name end))
(goto-char (bibtex-start-of-text-in-field bounds))
! (let ((field-name (bibtex-name-in-field bounds)))
! (if (and (bibtex-string= field-name "month")
! (not (assoc-string
(bibtex-text-in-field-bounds bounds)
!
bibtex-predefined-month-strings t)))
(push (list (bibtex-current-line)
"Questionable month field")
error-list))
(setq req (delete (assoc-string field-name req t) req)
creq (delete (assoc-string field-name creq t)
creq))
! (if (bibtex-string= field-name "crossref")
(setq crossref-there t))))
(if crossref-there
(setq req creq))
***************
*** 3305,3314 ****
(dolist (err error-list)
(insert bufnam ":" (number-to-string (elt err 0))
": " (elt err 1) "\n"))
- (compilation-parse-errors nil nil)
- (setq compilation-old-error-list compilation-error-list)
- ;; this is necessary to avoid reparsing of buffer if you
- ;; switch to compilation buffer and enter `compile-goto-error'
(set-buffer-modified-p nil)
(toggle-read-only 1)
(goto-char (point-min))
--- 3350,3355 ----
***************
*** 3395,3405 ****
(interactive)
(save-excursion
(bibtex-inside-field)
! (let ((bounds (bibtex-enclosing-field)))
! (goto-char (bibtex-start-of-text-in-field bounds))
! (delete-char 1)
! (goto-char (1- (bibtex-end-of-text-in-field bounds)))
! (delete-backward-char 1))))
(defun bibtex-kill-field (&optional copy-only)
"Kill the entire enclosing BibTeX field.
--- 3436,3448 ----
(interactive)
(save-excursion
(bibtex-inside-field)
! (let* ((bounds (bibtex-enclosing-field))
! (end (bibtex-end-of-text-in-field bounds))
! (start (bibtex-start-of-text-in-field bounds)))
! (if (memq (char-before end) '(?\} ?\"))
! (delete-region (1- end) end))
! (if (memq (char-after start) '(?\{ ?\"))
! (delete-region start (1+ start))))))
(defun bibtex-kill-field (&optional copy-only)
"Kill the entire enclosing BibTeX field.
***************
*** 3455,3460 ****
--- 3498,3504 ----
(setq bibtex-last-kill-command 'entry))
(defun bibtex-copy-entry-as-kill ()
+ "Copy the entire enclosing BibTeX entry to `bibtex-entry-kill-ring'."
(interactive)
(bibtex-kill-entry t))
***************
*** 3482,3489 ****
The sequence of kills wraps around, so that after the oldest one
comes the newest one."
(interactive "*p")
! (if (not (eq last-command 'bibtex-yank))
! (error "Previous command was not a BibTeX yank"))
(setq this-command 'bibtex-yank)
(let ((inhibit-read-only t))
(delete-region (point) (mark t))
--- 3526,3533 ----
The sequence of kills wraps around, so that after the oldest one
comes the newest one."
(interactive "*p")
! (unless (eq last-command 'bibtex-yank)
! (error "Previous command was not a BibTeX yank"))
(setq this-command 'bibtex-yank)
(let ((inhibit-read-only t))
(delete-region (point) (mark t))
***************
*** 3519,3525 ****
Check that no required fields are empty and formats entry dependent
on the value of `bibtex-entry-format'.
If the reference key of the entry is empty or a prefix argument is given,
! calculate a new reference key. (Note: this will only work if fields in entry
begin on separate lines prior to calling `bibtex-clean-entry' or if
'realign is contained in `bibtex-entry-format'.)
Don't call `bibtex-clean-entry' on @Preamble entries.
--- 3563,3569 ----
Check that no required fields are empty and formats entry dependent
on the value of `bibtex-entry-format'.
If the reference key of the entry is empty or a prefix argument is given,
! calculate a new reference key. (Note: this will only work if fields in entry
begin on separate lines prior to calling `bibtex-clean-entry' or if
'realign is contained in `bibtex-entry-format'.)
Don't call `bibtex-clean-entry' on @Preamble entries.
***************
*** 3533,3551 ****
(bibtex-beginning-of-entry)
(save-excursion
(when (re-search-forward bibtex-entry-maybe-empty-head nil t)
! (setq entry-type (downcase (bibtex-type-in-head)))
(setq key (bibtex-key-in-head))))
;; formatting
! (cond ((equal entry-type "preamble")
;; (bibtex-format-preamble)
(error "No clean up of @Preamble entries"))
! ((equal entry-type "string"))
;; (bibtex-format-string)
(t (bibtex-format-entry)))
;; set key
(when (or new-key (not key))
(setq key (bibtex-generate-autokey))
! (if bibtex-autokey-edit-before-use
(setq key (bibtex-read-key "Key to use: " key)))
(re-search-forward bibtex-entry-maybe-empty-head)
(if (match-beginning bibtex-key-in-head)
--- 3577,3596 ----
(bibtex-beginning-of-entry)
(save-excursion
(when (re-search-forward bibtex-entry-maybe-empty-head nil t)
! (setq entry-type (bibtex-type-in-head))
(setq key (bibtex-key-in-head))))
;; formatting
! (cond ((bibtex-string= entry-type "preamble")
;; (bibtex-format-preamble)
(error "No clean up of @Preamble entries"))
! ((bibtex-string= entry-type "string"))
;; (bibtex-format-string)
(t (bibtex-format-entry)))
;; set key
(when (or new-key (not key))
(setq key (bibtex-generate-autokey))
! ;; Sometimes bibtex-generate-autokey returns an empty string
! (if (or bibtex-autokey-edit-before-use (string= "" key))
(setq key (bibtex-read-key "Key to use: " key)))
(re-search-forward bibtex-entry-maybe-empty-head)
(if (match-beginning bibtex-key-in-head)
***************
*** 3563,3581 ****
(entry (buffer-substring start end))
(index (progn (goto-char start)
(bibtex-entry-index)))
! no-error)
(if (and bibtex-maintain-sorted-entries
(not (and bibtex-sort-ignore-string-entries
! (equal entry-type "string"))))
(progn
(delete-region start end)
! (setq no-error (bibtex-prepare-new-entry index))
(insert entry)
(forward-char -1)
(bibtex-beginning-of-entry) ; moves backward
(re-search-forward bibtex-entry-head))
! (setq no-error (bibtex-find-entry (car index))))
! (unless no-error
(error "New inserted entry yields duplicate key"))))
;; final clean up
(unless called-by-reformat
--- 3608,3628 ----
(entry (buffer-substring start end))
(index (progn (goto-char start)
(bibtex-entry-index)))
! error)
(if (and bibtex-maintain-sorted-entries
(not (and bibtex-sort-ignore-string-entries
! (bibtex-string= entry-type "string"))))
(progn
(delete-region start end)
! (setq error (not (bibtex-prepare-new-entry index)))
(insert entry)
(forward-char -1)
(bibtex-beginning-of-entry) ; moves backward
(re-search-forward bibtex-entry-head))
! (bibtex-find-entry key)
! (setq error (or (/= (point) start)
! (bibtex-find-entry key end))))
! (if error
(error "New inserted entry yields duplicate key"))))
;; final clean up
(unless called-by-reformat
***************
*** 3583,3589 ****
(save-restriction
(bibtex-narrow-to-entry)
;; Only update the list of keys if it has been built already.
! (cond ((equal entry-type "string")
(if (listp bibtex-strings) (bibtex-parse-strings t)))
((listp bibtex-reference-keys) (bibtex-parse-keys t)))
(run-hooks 'bibtex-clean-entry-hook))))))
--- 3630,3636 ----
(save-restriction
(bibtex-narrow-to-entry)
;; Only update the list of keys if it has been built already.
! (cond ((bibtex-string= entry-type "string")
(if (listp bibtex-strings) (bibtex-parse-strings t)))
((listp bibtex-reference-keys) (bibtex-parse-keys t)))
(run-hooks 'bibtex-clean-entry-hook))))))
***************
*** 3752,3779 ****
(defun bibtex-complete ()
"Complete word fragment before point according to context.
If point is inside key or crossref field perform key completion based on
! `bibtex-reference-keys'. Inside any other field perform string
! completion based on `bibtex-strings'. An error is signaled if point
! is outside key or BibTeX field."
(interactive)
! (let* ((pnt (point))
! (case-fold-search t)
! bounds compl)
(save-excursion
(if (and (setq bounds (bibtex-enclosing-field t))
(>= pnt (bibtex-start-of-text-in-field bounds))
(<= pnt (bibtex-end-of-text-in-field bounds)))
! (progn
! (goto-char (bibtex-start-of-name-in-field bounds))
! (setq compl (if (string= "crossref"
! (downcase
! (buffer-substring-no-properties
! (if (looking-at
"\\(OPT\\)\\|\\(ALT\\)")
! (match-end 0)
! (point))
! (bibtex-end-of-name-in-field bounds))))
! 'key
! 'str)))
(bibtex-beginning-of-entry)
(if (and (re-search-forward bibtex-entry-maybe-empty-head nil t)
;; point is inside a key
--- 3799,3827 ----
(defun bibtex-complete ()
"Complete word fragment before point according to context.
If point is inside key or crossref field perform key completion based on
! `bibtex-reference-keys'. Inside a month field perform key completion
! based on `bibtex-predefined-month-strings'. Inside any other field
! perform string completion based on `bibtex-strings'. An error is
! signaled if point is outside key or BibTeX field."
(interactive)
! (let ((pnt (point))
! (case-fold-search t)
! bounds name compl)
(save-excursion
(if (and (setq bounds (bibtex-enclosing-field t))
(>= pnt (bibtex-start-of-text-in-field bounds))
(<= pnt (bibtex-end-of-text-in-field bounds)))
! (setq name (bibtex-name-in-field bounds t)
! compl (cond ((bibtex-string= name "crossref")
! 'key)
! ((bibtex-string= name "month")
! bibtex-predefined-month-strings)
! (t (if (listp bibtex-strings)
! bibtex-strings
! ;; so that bibtex-complete-string-cleanup
! ;; can do its job
! (bibtex-parse-strings
! (bibtex-string-files-init))))))
(bibtex-beginning-of-entry)
(if (and (re-search-forward bibtex-entry-maybe-empty-head nil t)
;; point is inside a key
***************
*** 3789,3812 ****
;; key completion
(setq choose-completion-string-functions
(lambda (choice buffer mini-p base-size)
! (bibtex-choose-completion-string choice buffer mini-p
base-size)
! (if bibtex-complete-key-cleanup
! (funcall bibtex-complete-key-cleanup choice))
;; return t (required by
choose-completion-string-functions)
t))
! (let ((choice (bibtex-complete-internal bibtex-reference-keys)))
! (if bibtex-complete-key-cleanup
! (funcall bibtex-complete-key-cleanup choice))))
! ((equal compl 'str)
;; string completion
(setq choose-completion-string-functions
! (lambda (choice buffer mini-p base-size)
(bibtex-choose-completion-string choice buffer mini-p
base-size)
! (bibtex-complete-string-cleanup choice)
;; return t (required by
choose-completion-string-functions)
t))
! (bibtex-complete-string-cleanup (bibtex-complete-internal
bibtex-strings)))
(t (error "Point outside key or BibTeX field")))))
--- 3837,3859 ----
;; key completion
(setq choose-completion-string-functions
(lambda (choice buffer mini-p base-size)
! (bibtex-choose-completion-string choice buffer mini-p
base-size)
! (bibtex-complete-key-cleanup choice)
;; return t (required by
choose-completion-string-functions)
t))
! (bibtex-complete-key-cleanup (bibtex-complete-internal
! bibtex-reference-keys)))
! (compl
;; string completion
(setq choose-completion-string-functions
! `(lambda (choice buffer mini-p base-size)
(bibtex-choose-completion-string choice buffer mini-p
base-size)
! (bibtex-complete-string-cleanup choice ',compl)
;; return t (required by
choose-completion-string-functions)
t))
! (bibtex-complete-string-cleanup (bibtex-complete-internal compl)
! compl))
(t (error "Point outside key or BibTeX field")))))
***************
*** 3880,3887 ****
(interactive (list (completing-read "String key: " bibtex-strings
nil nil nil 'bibtex-key-history)))
(let ((bibtex-maintain-sorted-entries
! (if (not bibtex-sort-ignore-string-entries)
! bibtex-maintain-sorted-entries))
endpos)
(unless (bibtex-prepare-new-entry (list key nil "String"))
(error "Entry with key `%s' already exists" key))
--- 3927,3934 ----
(interactive (list (completing-read "String key: " bibtex-strings
nil nil nil 'bibtex-key-history)))
(let ((bibtex-maintain-sorted-entries
! (unless bibtex-sort-ignore-string-entries
! bibtex-maintain-sorted-entries))
endpos)
(unless (bibtex-prepare-new-entry (list key nil "String"))
(error "Entry with key `%s' already exists" key))
***************
*** 3913,3918 ****
--- 3960,4040 ----
"\n")
(goto-char endpos)))
+ (defun bibtex-url (&optional event)
+ "Browse a URL for the BibTeX entry at position PNT.
+ The URL is generated using the schemes defined in `bibtex-generate-url-list'
+ \(see there\). Then the URL is passed to `browse-url'."
+ (interactive (list last-input-event))
+ (save-excursion
+ (if event (posn-set-point (event-end event)))
+ (bibtex-beginning-of-entry)
+ (let ((fields-alist (bibtex-parse-entry))
+ (case-fold-search t)
+ (lst bibtex-generate-url-list)
+ field url scheme)
+ (while (setq scheme (car lst))
+ (when (and (setq field (cdr (assoc-string (caar scheme)
+ fields-alist t)))
+ (progn
+ (if (string-match "\\`[{\"]\\(.*\\)[}\"]\\'" field)
+ (setq field (match-string 1 field)))
+ (string-match (cdar scheme) field)))
+ (setq lst nil)
+ (if (null (cdr scheme))
+ (setq url (match-string 0 field)))
+ (dolist (step (cdr scheme))
+ (cond ((stringp step)
+ (setq url (concat url step)))
+ ((setq field (assoc-string (car step) fields-alist t))
+ ;; always remove field delimiters
+ (let* ((text (if (string-match "\\`[{\"]\\(.*\\)[}\"]\\'"
+ (cdr field))
+ (match-string 1 (cdr field))
+ (cdr field)))
+ (str (if (string-match (nth 1 step) text)
+ (cond
+ ((functionp (nth 2 step))
+ (funcall (nth 2 step) text))
+ ((numberp (nth 2 step))
+ (match-string (nth 2 step) text))
+ (t
+ (replace-match (nth 2 step) nil nil text)))
+ ;; If the scheme is set up correctly,
+ ;; we should never reach this point
+ (error "Match failed: %s" text))))
+ (setq url (concat url str))))
+ ;; If the scheme is set up correctly,
+ ;; we should never reach this point
+ (t (error "Step failed: %s" step))))
+ (message "%s" url)
+ (browse-url url))
+ (setq lst (cdr lst)))
+ (unless url (message "No URL known.")))))
+
+ (defun bibtex-font-lock-url (bound)
+ "Font-lock for URLs."
+ (let ((case-fold-search t)
+ (bounds (bibtex-enclosing-field t))
+ (pnt (point))
+ found field)
+ ;; We use start-of-field as syntax-begin
+ (goto-char (if bounds (bibtex-start-of-field bounds) pnt))
+ (while (and (not found)
+ (prog1 (re-search-forward bibtex-font-lock-url-regexp bound t)
+ (setq field (match-string-no-properties 1)))
+ (setq bounds (bibtex-parse-field-text))
+ (>= bound (car bounds))
+ (>= (car bounds) pnt))
+ (let ((lst bibtex-generate-url-list) url)
+ (goto-char (car bounds))
+ (while (and (not found)
+ (setq url (caar lst)))
+ (when (bibtex-string= field (car url))
+ (setq found (re-search-forward (cdr url) (cdr bounds) t)))
+ (setq lst (cdr lst))))
+ (goto-char (cdr bounds)))
+ found))
+
;; Make BibTeX a Feature
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Emacs-diffs] Changes to emacs/lisp/textmodes/bibtex.el [emacs-unicode-2],
Miles Bader <=