Add 2012 to FSF copyright years for Emacs files
[bpt/emacs.git] / lisp / textmodes / bib-mode.el
CommitLineData
55535639 1;;; bib-mode.el --- major mode for editing bib files
c0274f38 2
acaf905b 3;; Copyright (C) 1989, 2001-2012 Free Software Foundation, Inc.
9750e079 4
841a91fe
GM
5;; Author: Henry Kautz
6;; (according to authors.el)
e5167999 7;; Maintainer: FSF
e5167999
ER
8;; Keywords: bib
9
54369c0f
JB
10;; This file is part of GNU Emacs.
11
1fecc8fe 12;; GNU Emacs is free software: you can redistribute it and/or modify
54369c0f 13;; it under the terms of the GNU General Public License as published by
1fecc8fe
GM
14;; the Free Software Foundation, either version 3 of the License, or
15;; (at your option) any later version.
54369c0f
JB
16
17;; GNU Emacs is distributed in the hope that it will be useful,
18;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20;; GNU General Public License for more details.
21
22;; You should have received a copy of the GNU General Public License
1fecc8fe 23;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
54369c0f 24
e41b2db1 25;;; Commentary:
54369c0f 26
54369c0f 27;; GNU Emacs code to help maintain databases compatible with (troff)
db95369b 28;; refer and lookbib. The file bib-file should be set to your
54369c0f
JB
29;; bibliography file. Keys are automagically inserted as you type,
30;; and appropriate keys are presented for various kinds of entries.
31
e41b2db1 32;;; Code:
55535639 33
d1ebc62e
SE
34(defgroup bib nil
35 "Major mode for editing bib files."
36 :prefix "bib-"
6700fc05 37 :group 'external
d1ebc62e 38 :group 'wp)
e41b2db1 39
d1ebc62e
SE
40(defcustom bib-file "~/my-bibliography.bib"
41 "Default name of file used by `addbib'."
42 :type 'file
43 :group 'bib)
54369c0f 44
d1ebc62e
SE
45(defcustom unread-bib-file "~/to-be-read.bib"
46 "Default name of file used by `unread-bib' in Bib mode."
47 :type 'file
48 :group 'bib)
54369c0f 49
b016851c
SM
50(defvar bib-mode-map
51 (let ((map (make-sparse-keymap)))
52 (set-keymap-parent map text-mode-map)
53 (define-key map "\C-M" 'return-key-bib)
54 (define-key map "\C-c\C-u" 'unread-bib)
55 (define-key map "\C-c\C-@" 'mark-bib)
56 (define-key map "\e`" 'abbrev-mode)
57 map))
54369c0f
JB
58
59(defun addbib ()
db95369b 60 "Set up editor to add to troff bibliography file specified
54369c0f
JB
61by global variable `bib-file'. See description of `bib-mode'."
62 (interactive)
63 (find-file bib-file)
64 (goto-char (point-max))
65 (bib-mode)
66 )
db95369b 67
dda30de7 68(define-derived-mode bib-mode text-mode "Bib"
db95369b 69 "Mode for editing `lookbib' style bibliographies.
54369c0f
JB
70Hit RETURN to get next % field key.
71If you want to ignore this field, just hit RETURN again.
72Use `text-mode' to turn this feature off.
73
74 journal papers: A* T D J V N P K W X
db95369b 75 articles in books & proceedings: A* T D B E* I C P K W X
54369c0f
JB
76 tech reports: A* T D R I C K W X
77 books: A* T D I C K W X
78
79Fields:
80
81A uthor T itle D ate J ournal
82V olume N umber P age K eywords
83B in book or proceedings E ditor C ity & state
84I nstitution, school, or publisher
db95369b 85R eport number or 'phd thesis' or 'masters thesis' or 'draft' or
54369c0f
JB
86 'unnumbered' or 'unpublished'
87W here can be found locally (login name, or ailib, etc.)
88X comments (not used in indexing)
89
90\\[unread-bib] appends current entry to a different file (for example,
91a file of papers to be read in the future), given by the value of the
92variable `unread-bib-file'.
93\\[mark-bib] marks current or previous entry.
94Abbreviations are saved in `bib-mode-abbrev-table'.
95Hook can be stored in `bib-mode-hook'.
96Field keys given by variable `bib-assoc'.
97
98Commands:
dda30de7
SM
99\\{bib-mode-map}"
100 (abbrev-mode 1))
101
102(defconst bib-assoc
103 '((" *$" . "%A ")
104 ("%A ." . "%A ")
105 ("%A $" . "%T ")
106 ("%T " . "%D ")
107 ("%D " . "%J ")
108 ("%J ." . "%V ")
109 ("%V " . "%N ")
110 ("%N " . "%P ")
111 ("%P " . "%K ")
112 ("%K " . "%W ")
113 ("%W " . "%X ")
114 ("%X " . "")
115 ("%J $" . "%B ")
116 ("%B ." . "%E ")
117 ("%E ." . "%E ")
118 ("%E $" . "%I ")
119 ("%I " . "%C ")
120 ("%C " . "%P ")
121 ("%B $" . "%R ")
122 ("%R " . "%I "))
123 "Describes bibliographic database format.
124A line beginning with the car of an entry is followed by one beginning
125with the cdr.")
54369c0f
JB
126
127(defun bib-find-key (slots)
128 (cond
129 ((null slots)
130 (if (bobp)
131 ""
7caf6803 132 (progn (forward-line -1) (bib-find-key bib-assoc))))
54369c0f
JB
133 ((looking-at (car (car slots)))
134 (cdr (car slots)))
135 (t (bib-find-key (cdr slots)))
136 ))
137
138
d1ebc62e
SE
139(defcustom bib-auto-capitalize t
140 "*True to automatically capitalize appropriate fields in Bib mode."
141 :type 'boolean
142 :group 'bib)
54369c0f
JB
143
144(defconst bib-capitalized-fields "%[AETCBIJR]")
145
146(defun return-key-bib ()
147 "Magic when user hits return, used by `bib-mode'."
148 (interactive)
149 (if (eolp)
150 (let (empty new-key beg-current end-current)
151 (beginning-of-line)
152 (setq empty (looking-at "%. $"))
153 (if (not empty)
154 (progn
155 (end-of-line)
156 (newline)
157 (forward-line -1)
158 ))
159 (end-of-line)
160 (setq end-current (point))
161 (beginning-of-line)
162 (setq beg-current (point))
163 (setq new-key (bib-find-key bib-assoc))
164 (if (and (not empty) bib-auto-capitalize
165 (looking-at bib-capitalized-fields))
166 (save-excursion
7a953756 167 (bib-capitalize-title-region (+ (point) 3) end-current)))
54369c0f
JB
168 (goto-char beg-current)
169 (if empty
170 (kill-line nil)
171 (forward-line 1)
172 )
71a8775a 173 (insert new-key))
54369c0f
JB
174 (newline)))
175
176(defun mark-bib ()
177 "Set mark at beginning of current or previous bib entry, point at end."
178 (interactive)
179 (beginning-of-line nil)
180 (if (looking-at "^ *$") (re-search-backward "[^ \n]" nil 2))
181 (re-search-backward "^ *$" nil 2)
182 (re-search-forward "^%")
183 (beginning-of-line nil)
184 (push-mark (point))
185 (re-search-forward "^ *$" nil 2)
7caf6803 186 (forward-line 1)
54369c0f
JB
187 (beginning-of-line nil))
188
189(defun unread-bib ()
190 "Append current or previous entry to file of unread papers
191named by variable `unread-bib-file'."
192 (interactive)
193 (mark-bib)
194 (if (get-file-buffer unread-bib-file)
195 (append-to-buffer (get-file-buffer unread-bib-file) (mark) (point))
196 (append-to-file (mark) (point) unread-bib-file)))
197
198
7a953756 199(defvar bib-capitalize-title-stop-words
54369c0f
JB
200 (concat
201 "the\\|and\\|of\\|is\\|a\\|an\\|of\\|for\\|in\\|to\\|in\\|on\\|at\\|"
202 "by\\|with\\|that\\|its")
7a953756 203 "Words not to be capitalized in a title (unless the first word).")
54369c0f 204
7a953756
RS
205(defvar bib-capitalize-title-stop-regexp
206 (concat "\\(" bib-capitalize-title-stop-words "\\)\\(\\b\\|'\\)"))
54369c0f 207
7a953756 208(defun bib-capitalize-title-region (begin end)
54369c0f
JB
209 "Like `capitalize-region', but don't capitalize stop words, except the first."
210 (interactive "r")
211 (let ((case-fold-search nil) (orig-syntax-table (syntax-table)))
212 (unwind-protect
213 (save-restriction
214 (set-syntax-table text-mode-syntax-table)
215 (narrow-to-region begin end)
216 (goto-char (point-min))
217 (if (looking-at "[A-Z][a-z]*[A-Z]")
218 (forward-word 1)
219 (capitalize-word 1))
220 (while (re-search-forward "\\<" nil t)
221 (if (looking-at "[A-Z][a-z]*[A-Z]")
222 (forward-word 1)
223 (if (let ((case-fold-search t))
7a953756 224 (looking-at bib-capitalize-title-stop-regexp))
54369c0f
JB
225 (downcase-word 1)
226 (capitalize-word 1)))
227 ))
228 (set-syntax-table orig-syntax-table))))
229
230
7a953756 231(defun bib-capitalize-title (s)
54369c0f 232 "Like `capitalize', but don't capitalize stop words, except the first."
9a529312
SM
233 (with-current-buffer (get-buffer-create "$$$Scratch$$$")
234 (erase-buffer)
235 (insert s)
236 (bib-capitalize-title-region (point-min) (point-max))
237 (buffer-string)))
49116ac0
JB
238
239(provide 'bib-mode)
240
c0274f38 241;;; bib-mode.el ends here