;;; bibtex.el --- BibTeX mode for GNU Emacs
-;; Copyright (C) 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2001, 2002,
-;; 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+;; Copyright (C) 1992, 1994-1999, 2001-2011 Free Software Foundation, Inc.
;; Author: Stefan Schoef <schoef@offis.uni-oldenburg.de>
;; Bengt Martensson <bengt@mathematik.uni-Bremen.de>
;; Mike Newton <newton@gumby.cs.caltech.edu>
;; Aaron Larson <alarson@src.honeywell.com>
;; Dirk Herrmann <D.Herrmann@tu-bs.de>
-;; Maintainer: Roland Winkler <roland.winkler@physik.uni-erlangen.de>
+;; Maintainer: Roland Winkler <winkler@gnu.org>
;; Keywords: BibTeX, LaTeX, TeX
;; This file is part of GNU Emacs.
"Alist of field regexps that \\[bibtex-clean-entry] encloses by braces.
Each element has the form (FIELDS REGEXP), where FIELDS is a list
of BibTeX field names and REGEXP is a regexp.
-Whitespace in REGEXP will be replaced by \"[ \\t\\n]+\"."
+Space characters in REGEXP will be replaced by \"[ \\t\\n]+\"."
:group 'bibtex
:type '(repeat (list (repeat (string :tag "field name"))
(choice (regexp :tag "regexp")
Each element has the form (FIELDS REGEXP TO-STR), where FIELDS is a list
of BibTeX field names. In FIELDS search for REGEXP, which are replaced
by the BibTeX string constant TO-STR.
-Whitespace in REGEXP will be replaced by \"[ \\t\\n]+\"."
+Space characters in REGEXP will be replaced by \"[ \\t\\n]+\"."
:group 'bibtex
:type '(repeat (list (repeat (string :tag "field name"))
(regexp :tag "From regexp")
Case is always ignored. Always remove the field delimiters.
If `bibtex-expand-strings' is non-nil, BibTeX strings are expanded
for generating the URL.
+Set this variable before loading BibTeX mode.
-The following is a complex example, see http://link.aps.org/linkfaq.html.
+The following is a complex example, see URL `http://link.aps.org/'.
(((\"journal\" . \"\\\\=<\\(PR[ABCDEL]?\\|RMP\\)\\\\=>\")
\"http://link.aps.org/abstract/%s/v%s/p%s\"
Each rule should be of the form (REGEXP . SUBEXP), where SUBEXP
specifies which parenthesized expression in REGEXP is a cited key.
Case is significant.
-Used by `bibtex-search-crossref' and for font-locking."
+Used by `bibtex-search-crossref' and for font-locking.
+Set this variable before loading BibTeX mode."
:group 'bibtex
:type '(repeat (cons (regexp :tag "Regexp")
(integer :tag "Number")))
(save-excursion
(goto-char (bibtex-start-of-text-in-field bounds))
(let ((epoint (bibtex-end-of-text-in-field bounds))
- content opoint)
- (while (< (setq opoint (point)) epoint)
+ content)
+ (while (< (point) epoint)
(if (looking-at bibtex-field-const)
(let ((mtch (match-string-no-properties 0)))
(push (or (if bibtex-expand-strings
see regexp `bibtex-entry-head'. If `bibtex-sort-ignore-string-entries'
is non-nil, FUN is not called for @String entries."
(let ((case-fold-search t)
+ (end-marker (make-marker))
found)
+ ;; Use marker to keep track of the buffer position of the end of
+ ;; a BibTeX entry as this position may change during reformatting.
+ (set-marker-insertion-type end-marker t)
(save-excursion
(goto-char (point-min))
(while (setq found (bibtex-skip-to-valid-entry))
+ (set-marker end-marker (cdr found))
(looking-at bibtex-any-entry-maybe-empty-head)
- (funcall fun (bibtex-key-in-head "") (car found) (cdr found))
- (goto-char (cdr found))))))
+ (funcall fun (bibtex-key-in-head "") (car found) end-marker)
+ (goto-char end-marker)))))
(defun bibtex-progress-message (&optional flag interval)
"Echo a message about progress of current buffer.
"Search for BibTeX field enclosing point.
For `bibtex-mode''s internal algorithms, a field begins at the comma
following the preceding field. Usually, this is not what the user expects.
-Thus if COMMA is non-nil, the \"current field\" includes the terminating comma.
+Thus if COMMA is non-nil, the \"current field\" includes the terminating comma
+as well as the entry delimiter if it appears on the same line.
Unless NOERR is non-nil, signal an error if no enclosing field is found.
On success return bounds, nil otherwise. Do not move point."
(save-excursion
(when comma
(end-of-line)
(skip-chars-backward " \t")
+ ;; Ignore entry delimiter and comma at end of line.
+ (if (memq (preceding-char) '(?} ?\))) (forward-char -1))
(if (= (preceding-char) ?,) (forward-char -1)))
(let ((bounds (bibtex-search-backward-field bibtex-field-name t)))
(bibtex-skip-to-valid-entry)
(push-mark)
(insert (funcall fun 'bibtex-entry-kill-ring-yank-pointer
- bibtex-entry-kill-ring)))))
+ bibtex-entry-kill-ring))
+ (unless (functionp bibtex-reference-keys)
+ ;; update `bibtex-reference-keys'
+ (save-excursion
+ (goto-char (mark t))
+ (looking-at bibtex-any-entry-maybe-empty-head)
+ (let ((key (bibtex-key-in-head)))
+ (if key (push (cons key t) bibtex-reference-keys))))))))
(defun bibtex-format-entry ()
"Helper function for `bibtex-clean-entry'.
(unless deleted
(push field-name field-list)
+ ;; Remove whitespace at beginning and end of field.
+ ;; We do not look at individual parts of the field
+ ;; as {foo } # bar # { baz} is a fine field.
+ (when (memq 'whitespace format)
+ (goto-char beg-text)
+ (if (looking-at "\\([{\"]\\)[ \t\n]+")
+ (replace-match "\\1"))
+ (goto-char end-text)
+ (if (looking-back "[ \t\n]+\\([}\"]\\)" beg-text t)
+ (replace-match "\\1")))
+
;; remove delimiters from purely numerical fields
(when (and (memq 'numerical-fields format)
(progn (goto-char beg-text)
"\\([\"{][0-9]+\\)[ \t\n]*--?[ \t\n]*\\([0-9]+[\"}]\\)")))
(replace-match "\\1-\\2"))
- ;; Remove whitespace at beginning and end of field.
- ;; We do not look at individual parts of the field
- ;; as {foo } # bar # { baz} is a fine field.
- (when (memq 'whitespace format)
- (goto-char beg-text)
- (if (looking-at "\\([{\"]\\)[ \t\n]+")
- (replace-match "\\1"))
- (goto-char end-text)
- (if (looking-back "[ \t\n]+\\([}\"]\\)" beg-text t)
- (replace-match "\\1")))
-
;; enclose field text by braces according to
;; `bibtex-field-braces-alist'.
(let (case-fold-search temp) ; Case-sensitive search
;; if match not at left subfield boundary...
(if (< (1+ (nth 1 bounds)) (match-beginning 0))
(insert (bibtex-field-right-delimiter) " # ")
- (delete-backward-char 1))))))))
+ (delete-char -1))))))))
;; use book title of crossref'd entry
(if (and (memq 'inherit-booktitle format)
(if (memq 'realign format)
(bibtex-fill-entry)))))
- ;; Unwindform: move point to location where error occured if possible
+ ;; Unwindform: move point to location where error occurred if possible
(if error-field-name
(let (bounds)
(when (save-excursion
(setq regexp-alist
(mapcar (lambda (e)
(list (car e)
- (replace-regexp-in-string "[ \t\n]+" "[ \t\n]+" (nth 1 e))
+ (replace-regexp-in-string " +" "[ \t\n]+" (nth 1 e))
(nth 2 e))) ; nil for 'braces'.
regexp-alist))
(let (opt-list)
(dolist (buffer buffer-list)
(with-current-buffer buffer
(if (or force (functionp bibtex-reference-keys))
- (bibtex-parse-keys))))
+ (bibtex-parse-keys))
+ (unless (functionp bibtex-strings)
+ (bibtex-parse-strings (bibtex-string-files-init)))))
;; select BibTeX buffer
(if select
(if buffer-list
of a word, all strings are listed. Return completion."
;; Return value is used by cleanup functions.
;; Code inspired by `lisp-complete-symbol'.
- (let* ((case-fold-search t)
- (beg (save-excursion
+ (let ((beg (save-excursion
(re-search-backward "[ \t{\"]")
(forward-char)
(point)))
- (end (point))
- (pattern (buffer-substring-no-properties beg end))
- (completion (try-completion pattern completions)))
- (cond ((not completion)
- (error "Can't find completion for `%s'" pattern))
- ((eq completion t)
- pattern)
- ((not (string= pattern completion))
- (delete-region beg end)
- (insert completion)
- ;; Don't leave around a completions buffer that's out of date.
- (let ((win (get-buffer-window "*Completions*" 0)))
- (if win (with-selected-window win (bury-buffer))))
- completion)
- (t
- (let ((minibuf-is-in-use
- (eq (minibuffer-window) (selected-window))))
- (unless minibuf-is-in-use (message "Making completion list..."))
- (with-output-to-temp-buffer "*Completions*"
- (display-completion-list
- (sort (all-completions pattern completions) 'string<) pattern))
- (unless minibuf-is-in-use
- (message "Making completion list...done")))
- nil))))
+ (end (point)))
+ (when (completion-in-region beg end completions)
+ (buffer-substring beg (point)))))
(defun bibtex-complete-string-cleanup (str compl)
"Cleanup after inserting string STR.
;; brace-delimited ones
)
nil
- (font-lock-syntactic-keywords . bibtex-font-lock-syntactic-keywords)
(font-lock-extra-managed-props . (category))
(font-lock-mark-block-function
. (lambda ()
(set-mark (bibtex-end-of-entry))
(bibtex-beginning-of-entry)))))
+ (set (make-local-variable 'syntax-propertize-function)
+ (syntax-propertize-via-font-lock
+ bibtex-font-lock-syntactic-keywords))
(setq imenu-generic-expression
(list (list nil bibtex-entry-head bibtex-key-in-head))
imenu-case-fold-search t)
(with-current-buffer (get-buffer-create err-buf)
(setq default-directory dir)
(unless (eq major-mode 'compilation-mode) (compilation-mode))
- (toggle-read-only -1)
- (delete-region (point-min) (point-max))
- (insert "BibTeX mode command `bibtex-validate'\n"
- (if syntax-error
- "Maybe undetected errors due to syntax errors. Correct and validate again.\n"
- "\n"))
- (dolist (err error-list)
- (insert (format "%s:%d: %s\n" file (car err) (cdr err))))
- (set-buffer-modified-p nil)
- (toggle-read-only 1)
+ (let ((inhibit-read-only t))
+ (delete-region (point-min) (point-max))
+ (insert "BibTeX mode command `bibtex-validate'\n"
+ (if syntax-error
+ "Maybe undetected errors due to syntax errors. \
+Correct and validate again.\n"
+ "\n"))
+ (dolist (err error-list)
+ (insert (format "%s:%d: %s\n" file (car err) (cdr err))))
+ (set-buffer-modified-p nil))
(goto-char (point-min))
(forward-line 2)) ; first error message
(display-buffer err-buf)
(let ((err-buf "*BibTeX validation errors*"))
(with-current-buffer (get-buffer-create err-buf)
(unless (eq major-mode 'compilation-mode) (compilation-mode))
- (toggle-read-only -1)
- (delete-region (point-min) (point-max))
- (insert "BibTeX mode command `bibtex-validate-globally'\n\n")
- (dolist (err (sort error-list 'string-lessp)) (insert err))
- (set-buffer-modified-p nil)
- (toggle-read-only 1)
+ (let ((inhibit-read-only t))
+ (delete-region (point-min) (point-max))
+ (insert "BibTeX mode command `bibtex-validate-globally'\n\n")
+ (dolist (err (sort error-list 'string-lessp)) (insert err))
+ (set-buffer-modified-p nil))
(goto-char (point-min))
(forward-line 2)) ; first error message
(display-buffer err-buf)
(end (bibtex-end-of-field bounds))
(beg (bibtex-start-of-field bounds)))
(goto-char end)
- (skip-chars-forward ",")
+ ;; Preserve white space at end of BibTeX entry
+ (if (looking-at "[ \t\n]*[)}]")
+ (progn (skip-chars-backward " \t\n")
+ (setq end (point)))
+ (skip-chars-forward ","))
(push (list (bibtex-name-in-field bounds) nil
(bibtex-text-in-field-bounds bounds))
bibtex-field-kill-ring)
(save-excursion
(let* ((case-fold-search t)
(beg (bibtex-beginning-of-entry))
+ (key (progn (looking-at bibtex-any-entry-maybe-empty-head)
+ (bibtex-key-in-head)))
(end (progn (bibtex-end-of-entry)
(if (re-search-forward
bibtex-any-entry-maybe-empty-head nil 'move)
nil))
(setq bibtex-entry-kill-ring-yank-pointer bibtex-entry-kill-ring)
(unless copy-only
- (delete-region beg end))))
+ (delete-region beg end)
+ ;; remove key from `bibtex-reference-keys'.
+ (unless (functionp bibtex-reference-keys)
+ (setq bibtex-reference-keys
+ (delete (cons key t) bibtex-reference-keys))))))
(setq bibtex-last-kill-command 'entry))
(defun bibtex-copy-entry-as-kill ()
(unless (eq last-command 'bibtex-yank)
(error "Previous command was not a BibTeX yank"))
(setq this-command 'bibtex-yank)
- (let ((inhibit-read-only t))
+ (let ((inhibit-read-only t) key)
+ ;; point is at end of yanked entry
+ (unless (functionp bibtex-reference-keys)
+ ;; remove key of yanked entry from `bibtex-reference-keys'
+ (save-excursion
+ (goto-char (mark t))
+ (if (and (looking-at bibtex-any-entry-maybe-empty-head)
+ (setq key (bibtex-key-in-head)))
+ (setq bibtex-reference-keys
+ (delete (cons key t) bibtex-reference-keys)))))
(delete-region (point) (mark t))
(bibtex-insert-kill n t)))
last-comma page-dashes unify-case inherit-booktitle
whitespace braces strings))
(t
- (remove 'required-fields (push 'realign bibtex-entry-format)))))
+ (cons 'realign (remove 'required-fields bibtex-entry-format)))))
(reformat-reference-keys
(if read-options
(if use-previous-options
(provide 'bibtex)
-;; arch-tag: ee2be3af-caad-427f-b42a-d20fad630d04
;;; bibtex.el ends here