;;; bibtex.el --- BibTeX mode for GNU Emacs -*- lexical-binding: t -*-
-;; Copyright (C) 1992, 1994-1999, 2001-2012 Free Software Foundation, Inc.
+;; Copyright (C) 1992, 1994-1999, 2001-2014 Free Software Foundation,
+;; Inc.
;; Author: Stefan Schoef <schoef@offis.uni-oldenburg.de>
;; Bengt Martensson <bengt@mathematik.uni-Bremen.de>
nil
(("editor") ("editora") ("editorb") ("editorc")
("translator") ("annotator") ("commentator")
- ("introduction") ("foreword") ("afterword") ("titleaddon")
+ ("introduction") ("foreword") ("afterword") ("subtitle") ("titleaddon")
("maintitle") ("mainsubtitle") ("maintitleaddon")
("language") ("origlanguage") ("volume") ("part") ("edition") ("volumes")
("series") ("number") ("note") ("publisher") ("location") ("isbn")
("location") ("isbn") ("pagetotal") ("addendum") ("pubstate") ("doi")
("eprint") ("eprintclass") ("eprinttype") ("url") ("urldate")))
("InCollection" "Article in a Collection"
- (("author") ("editor") ("title") ("year" nil nil 0) ("date" nil nil 0))
+ (("author") ("title") ("year" nil nil 0) ("date" nil nil 0))
(("booktitle"))
- (("editora") ("editorb") ("editorc") ("translator") ("annotator")
+ (("editor") ("editora") ("editorb") ("editorc") ("translator") ("annotator")
("commentator") ("introduction") ("foreword") ("afterword")
("subtitle") ("titleaddon") ("maintitle") ("mainsubtitle")
("maintitleaddon") ("booksubtitle") ("booktitleaddon")
("addendum") ("pubstate") ("doi") ("eprint") ("eprintclass")
("eprinttype") ("url") ("urldate")))
("Proceedings" "Single-Volume Conference Proceedings"
- (("editor") ("title") ("year" nil nil 0) ("date" nil nil 0))
+ (("title") ("year" nil nil 0) ("date" nil nil 0))
nil
(("subtitle") ("titleaddon") ("maintitle") ("mainsubtitle")
("maintitleaddon") ("eventtitle") ("eventdate") ("venue") ("language")
+ ("editor")
("volume") ("part") ("volumes") ("series") ("number") ("note")
("organization") ("publisher") ("location") ("month")
("isbn") ("chapter") ("pages") ("pagetotal") ("addendum") ("pubstate")
("isbn") ("pagetotal") ("addendum") ("pubstate")
("doi") ("eprint") ("eprintclass") ("eprinttype") ("url") ("urldate")))
("InProceedings" "Article in Conference Proceedings"
- (("author") ("editor") ("title") ("year" nil nil 0) ("date" nil nil 0))
+ (("author") ("title") ("year" nil nil 0) ("date" nil nil 0))
(("booktitle"))
- (("subtitle") ("titleaddon") ("maintitle") ("mainsubtitle")
+ (("editor") ("subtitle") ("titleaddon") ("maintitle") ("mainsubtitle")
("maintitleaddon") ("booksubtitle") ("booktitleaddon")
("eventtitle") ("eventdate") ("venue") ("language")
("volume") ("part") ("volumes") ("series") ("number") ("note")
:group 'bibtex
:type '(repeat file))
-(defvar bibtex-string-file-path (getenv "BIBINPUTS")
- "Colon separated list of paths to search for `bibtex-string-files'.")
+(defcustom bibtex-string-file-path (getenv "BIBINPUTS")
+ "Colon-separated list of paths to search for `bibtex-string-files'."
+ :group 'bibtex
+ :type 'string)
(defcustom bibtex-files nil
"List of BibTeX files that are searched for entry keys.
:type '(repeat (choice (const :tag "bibtex-file-path" bibtex-file-path)
directory file)))
-(defvar bibtex-file-path (getenv "BIBINPUTS")
- "Colon separated list of paths to search for `bibtex-files'.")
+(defcustom bibtex-file-path (getenv "BIBINPUTS")
+ "Colon separated list of paths to search for `bibtex-files'."
+ :group 'bibtex
+ :type 'string)
(defcustom bibtex-search-entry-globally nil
"If non-nil, interactive calls of `bibtex-search-entry' search globally.
("\\\\`\\|\\\\'\\|\\\\\\^\\|\\\\~\\|\\\\=\\|\\\\\\.\\|\\\\u\\|\\\\v\\|\\\\H\\|\\\\t\\|\\\\c\\|\\\\d\\|\\\\b" . "")
;; braces, quotes, concatenation.
("[`'\"{}#]" . "")
+ ("\\\\-" . "") ; \- ->
;; spaces
("\\\\?[ \t\n]+\\|~" . " "))
"Alist of (OLD-REGEXP . NEW-STRING) pairs.
(function :tag "Personalized function")))
(defcustom bibtex-generate-url-list
- '((("url" . ".*:.*")))
+ '((("url" . ".*:.*"))
+ (("doi" . "10\\.[0-9]+/.+")
+ "http://dx.doi.org/%s"
+ ("doi" ".*" 0)))
"List of schemes for generating the URL of a BibTeX entry.
These schemes are used by `bibtex-url'.
(\"volume\" \".*\" 0)
(\"pages\" \"\\`[A-Z]?[0-9]+\" 0)))"
:group 'bibtex
+ :version "24.4"
:type '(repeat
(cons :tag "Scheme"
(cons :tag "Matcher" :extra-offset 4
Visit the BibTeX files defined by `bibtex-files' and return a list
of corresponding buffers.
Initialize in these buffers `bibtex-reference-keys' if not yet set.
-List of BibTeX buffers includes current buffer if CURRENT is non-nil.
+List of BibTeX buffers includes current buffer if CURRENT is non-nil
+and the current buffer visits a file using `bibtex-mode'.
If FORCE is non-nil, (re)initialize `bibtex-reference-keys' even if
already set. If SELECT is non-nil interactively select a BibTeX buffer.
-When called interactively, FORCE is t, CURRENT is t if current buffer uses
-`bibtex-mode', and SELECT is t if current buffer does not use `bibtex-mode',"
+
+When called interactively, FORCE is t, CURRENT is t if current buffer
+visits a file using `bibtex-mode', and SELECT is t if current buffer
+does not use `bibtex-mode',"
(interactive (list (eq major-mode 'bibtex-mode) t
(not (eq major-mode 'bibtex-mode))))
(let ((file-path (split-string (or bibtex-file-path default-directory) ":+"))
(if (file-readable-p file)
(push (find-file-noselect file) buffer-list)))
;; Include current buffer iff we want it.
- ;; Exclude current buffer if it doesn't use `bibtex-mode'.
- ;; Thus calling `bibtex-initialize' gives meaningful results for
- ;; any current buffer.
- (unless (and current (eq major-mode 'bibtex-mode)) (setq current nil))
+ ;; Exclude current buffer if it does not visit a file using `bibtex-mode'.
+ ;; This way we exclude BibTeX buffers such as `bibtex-search-buffer'
+ ;; that are not visiting a BibTeX file. Also, calling `bibtex-initialize'
+ ;; gives meaningful results for any current buffer.
+ (unless (and current (eq major-mode 'bibtex-mode) buffer-file-name)
+ (setq current nil))
(cond ((and current (not (memq (current-buffer) buffer-list)))
(push (current-buffer) buffer-list))
((and (not current) (memq (current-buffer) buffer-list))
(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)
;; Allow `bibtex-dialect' as a file-local variable.
(add-hook 'hack-local-variables-hook 'bibtex-set-dialect nil t))
(concat "^[ \t]*@[ \t]*\\(?:"
(regexp-opt
(append '("String" "Preamble")
- (mapcar 'car bibtex-entry-alist))) "\\)"))))
+ (mapcar 'car bibtex-entry-alist))) "\\)"))
+ (setq imenu-generic-expression
+ (list (list nil bibtex-entry-head bibtex-key-in-head))
+ imenu-case-fold-search t)))
;; Entry commands and menus for BibTeX dialects
;; We do not use `easy-menu-define' here because this gets confused
(if use-previous-options
bibtex-reformat-previous-options
(setq bibtex-reformat-previous-options
- (mapcar (lambda (option)
- (if (y-or-n-p (car option)) (cdr option)))
- `(("Realign entries (recommended)? " . 'realign)
- ("Remove empty optional and alternative fields? " . 'opts-or-alts)
- ("Remove delimiters around pure numerical fields? " . 'numerical-fields)
- (,(concat (if bibtex-comma-after-last-field "Insert" "Remove")
- " comma at end of entry? ") . 'last-comma)
- ("Replace double page dashes by single ones? " . 'page-dashes)
- ("Delete whitespace at the beginning and end of fields? " . 'whitespace)
- ("Inherit booktitle? " . 'inherit-booktitle)
- ("Force delimiters? " . 'delimiters)
- ("Unify case of entry types and field names? " . 'unify-case)
- ("Enclose parts of field entries by braces? " . 'braces)
- ("Replace parts of field entries by string constants? " . 'strings)
- ("Sort fields? " . 'sort-fields))))))
+ (delq nil
+ (mapcar (lambda (option)
+ (if (y-or-n-p (car option)) (cdr option)))
+ `(("Realign entries (recommended)? " . realign)
+ ("Remove empty optional and alternative fields? " . opts-or-alts)
+ ("Remove delimiters around pure numerical fields? " . numerical-fields)
+ (,(concat (if bibtex-comma-after-last-field "Insert" "Remove")
+ " comma at end of entry? ") . last-comma)
+ ("Replace double page dashes by single ones? " . page-dashes)
+ ("Delete whitespace at the beginning and end of fields? " . whitespace)
+ ("Inherit booktitle? " . inherit-booktitle)
+ ("Force delimiters? " . delimiters)
+ ("Unify case of entry types and field names? " . unify-case)
+ ("Enclose parts of field entries by braces? " . braces)
+ ("Replace parts of field entries by string constants? " . strings)
+ ("Sort fields? " . sort-fields)))))))
;; Do not include required-fields because `bibtex-reformat'
;; cannot handle the error messages of `bibtex-format-entry'.
;; Use `bibtex-validate' to check for required fields.
(if (stringp (car scheme))
(setq fmt (pop scheme)))
(dolist (step scheme)
+ ;; In the first STEP, if the field contains multiple
+ ;; matches, we want the match the closest to point.
+ ;; (if (eq step (car scheme))
(setq text (cdr (assoc-string (car step) fields-alist t)))
(if (string-match (nth 1 step) text)
(push (cond ((functionp (nth 2 step))
(if (string= "" field)
;; Unrestricted search.
(while (re-search-forward regexp nil t)
- (let ((beg (bibtex-beginning-of-entry))
- (end (bibtex-end-of-entry))
- key)
- (if (and (<= beg (match-beginning 0))
- (<= (match-end 0) end)
- (save-excursion
- (goto-char beg)
- (and (looking-at bibtex-entry-head)
- (setq key (bibtex-key-in-head))))
- (not (assoc key entries)))
- (push (list key file
- (buffer-substring-no-properties beg end))
- entries))))
+ (save-excursion
+ (let ((mbeg (match-beginning 0))
+ (mend (match-end 0))
+ (beg (bibtex-beginning-of-entry))
+ (end (bibtex-end-of-entry))
+ key)
+ (if (and (<= beg mbeg)
+ (<= mend end)
+ (progn
+ (goto-char beg)
+ (looking-at bibtex-entry-head))
+ (setq key (bibtex-key-in-head))
+ (not (assoc key entries)))
+ (push (list key file
+ (buffer-substring-no-properties beg end))
+ entries)))))
;; The following is slow. But it works reliably even in more
;; complicated cases with BibTeX string constants and crossrefed
;; entries. If you prefer speed over reliability, perform an