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