Fix up comment convention on the arch-tag lines.
[bpt/emacs.git] / lisp / textmodes / bib-mode.el
CommitLineData
55535639 1;;; bib-mode.el --- major mode for editing bib files
c0274f38 2
f2e3589a 3;; Copyright (C) 1989, 2001, 2002, 2003, 2004, 2005,
12dc447f 4;; 2006, 2007, 2008 Free Software Foundation, Inc.
9750e079 5
e5167999 6;; Maintainer: FSF
e5167999
ER
7;; Keywords: bib
8
54369c0f
JB
9;; This file is part of GNU Emacs.
10
11;; GNU Emacs is free software; you can redistribute it and/or modify
12;; it under the terms of the GNU General Public License as published by
5a9dffec 13;; the Free Software Foundation; either version 3, or (at your option)
54369c0f
JB
14;; any later version.
15
16;; GNU Emacs is distributed in the hope that it will be useful,
17;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19;; GNU General Public License for more details.
20
21;; You should have received a copy of the GNU General Public License
b578f267 22;; along with GNU Emacs; see the file COPYING. If not, write to the
4fc5845f
LK
23;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
24;; Boston, MA 02110-1301, USA.
54369c0f 25
e41b2db1 26;;; Commentary:
54369c0f 27
54369c0f 28;; GNU Emacs code to help maintain databases compatible with (troff)
db95369b 29;; refer and lookbib. The file bib-file should be set to your
54369c0f
JB
30;; bibliography file. Keys are automagically inserted as you type,
31;; and appropriate keys are presented for various kinds of entries.
32
e41b2db1 33;;; Code:
55535639 34
d1ebc62e
SE
35(defgroup bib nil
36 "Major mode for editing bib files."
37 :prefix "bib-"
6700fc05 38 :group 'external
d1ebc62e 39 :group 'wp)
e41b2db1 40
d1ebc62e
SE
41(defcustom bib-file "~/my-bibliography.bib"
42 "Default name of file used by `addbib'."
43 :type 'file
44 :group 'bib)
54369c0f 45
d1ebc62e
SE
46(defcustom unread-bib-file "~/to-be-read.bib"
47 "Default name of file used by `unread-bib' in Bib mode."
48 :type 'file
49 :group 'bib)
54369c0f
JB
50
51(defvar bib-mode-map (copy-keymap text-mode-map))
52(define-key bib-mode-map "\C-M" 'return-key-bib)
53(define-key bib-mode-map "\C-c\C-u" 'unread-bib)
54(define-key bib-mode-map "\C-c\C-@" 'mark-bib)
55(define-key bib-mode-map "\e`" 'abbrev-mode)
54369c0f
JB
56
57(defun addbib ()
db95369b 58 "Set up editor to add to troff bibliography file specified
54369c0f
JB
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 )
db95369b 65
dda30de7 66(define-derived-mode bib-mode text-mode "Bib"
db95369b 67 "Mode for editing `lookbib' style bibliographies.
54369c0f
JB
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
db95369b 73 articles in books & proceedings: A* T D B E* I C P K W X
54369c0f
JB
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
db95369b 83R eport number or 'phd thesis' or 'masters thesis' or 'draft' or
54369c0f
JB
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:
dda30de7
SM
97\\{bib-mode-map}"
98 (abbrev-mode 1))
99
100(defconst bib-assoc
101 '((" *$" . "%A ")
102 ("%A ." . "%A ")
103 ("%A $" . "%T ")
104 ("%T " . "%D ")
105 ("%D " . "%J ")
106 ("%J ." . "%V ")
107 ("%V " . "%N ")
108 ("%N " . "%P ")
109 ("%P " . "%K ")
110 ("%K " . "%W ")
111 ("%W " . "%X ")
112 ("%X " . "")
113 ("%J $" . "%B ")
114 ("%B ." . "%E ")
115 ("%E ." . "%E ")
116 ("%E $" . "%I ")
117 ("%I " . "%C ")
118 ("%C " . "%P ")
119 ("%B $" . "%R ")
120 ("%R " . "%I "))
121 "Describes bibliographic database format.
122A line beginning with the car of an entry is followed by one beginning
123with the cdr.")
54369c0f
JB
124
125(defun bib-find-key (slots)
126 (cond
127 ((null slots)
128 (if (bobp)
129 ""
7caf6803 130 (progn (forward-line -1) (bib-find-key bib-assoc))))
54369c0f
JB
131 ((looking-at (car (car slots)))
132 (cdr (car slots)))
133 (t (bib-find-key (cdr slots)))
134 ))
135
136
d1ebc62e
SE
137(defcustom bib-auto-capitalize t
138 "*True to automatically capitalize appropriate fields in Bib mode."
139 :type 'boolean
140 :group 'bib)
54369c0f
JB
141
142(defconst bib-capitalized-fields "%[AETCBIJR]")
143
144(defun return-key-bib ()
145 "Magic when user hits return, used by `bib-mode'."
146 (interactive)
147 (if (eolp)
148 (let (empty new-key beg-current end-current)
149 (beginning-of-line)
150 (setq empty (looking-at "%. $"))
151 (if (not empty)
152 (progn
153 (end-of-line)
154 (newline)
155 (forward-line -1)
156 ))
157 (end-of-line)
158 (setq end-current (point))
159 (beginning-of-line)
160 (setq beg-current (point))
161 (setq new-key (bib-find-key bib-assoc))
162 (if (and (not empty) bib-auto-capitalize
163 (looking-at bib-capitalized-fields))
164 (save-excursion
7a953756 165 (bib-capitalize-title-region (+ (point) 3) end-current)))
54369c0f
JB
166 (goto-char beg-current)
167 (if empty
168 (kill-line nil)
169 (forward-line 1)
170 )
71a8775a 171 (insert new-key))
54369c0f
JB
172 (newline)))
173
174(defun mark-bib ()
175 "Set mark at beginning of current or previous bib entry, point at end."
176 (interactive)
177 (beginning-of-line nil)
178 (if (looking-at "^ *$") (re-search-backward "[^ \n]" nil 2))
179 (re-search-backward "^ *$" nil 2)
180 (re-search-forward "^%")
181 (beginning-of-line nil)
182 (push-mark (point))
183 (re-search-forward "^ *$" nil 2)
7caf6803 184 (forward-line 1)
54369c0f
JB
185 (beginning-of-line nil))
186
187(defun unread-bib ()
188 "Append current or previous entry to file of unread papers
189named by variable `unread-bib-file'."
190 (interactive)
191 (mark-bib)
192 (if (get-file-buffer unread-bib-file)
193 (append-to-buffer (get-file-buffer unread-bib-file) (mark) (point))
194 (append-to-file (mark) (point) unread-bib-file)))
195
196
7a953756 197(defvar bib-capitalize-title-stop-words
54369c0f
JB
198 (concat
199 "the\\|and\\|of\\|is\\|a\\|an\\|of\\|for\\|in\\|to\\|in\\|on\\|at\\|"
200 "by\\|with\\|that\\|its")
7a953756 201 "Words not to be capitalized in a title (unless the first word).")
54369c0f 202
7a953756
RS
203(defvar bib-capitalize-title-stop-regexp
204 (concat "\\(" bib-capitalize-title-stop-words "\\)\\(\\b\\|'\\)"))
54369c0f 205
7a953756 206(defun bib-capitalize-title-region (begin end)
54369c0f
JB
207 "Like `capitalize-region', but don't capitalize stop words, except the first."
208 (interactive "r")
209 (let ((case-fold-search nil) (orig-syntax-table (syntax-table)))
210 (unwind-protect
211 (save-restriction
212 (set-syntax-table text-mode-syntax-table)
213 (narrow-to-region begin end)
214 (goto-char (point-min))
215 (if (looking-at "[A-Z][a-z]*[A-Z]")
216 (forward-word 1)
217 (capitalize-word 1))
218 (while (re-search-forward "\\<" nil t)
219 (if (looking-at "[A-Z][a-z]*[A-Z]")
220 (forward-word 1)
221 (if (let ((case-fold-search t))
7a953756 222 (looking-at bib-capitalize-title-stop-regexp))
54369c0f
JB
223 (downcase-word 1)
224 (capitalize-word 1)))
225 ))
226 (set-syntax-table orig-syntax-table))))
227
228
7a953756 229(defun bib-capitalize-title (s)
54369c0f
JB
230 "Like `capitalize', but don't capitalize stop words, except the first."
231 (save-excursion
232 (set-buffer (get-buffer-create "$$$Scratch$$$"))
233 (erase-buffer)
234 (insert s)
7a953756 235 (bib-capitalize-title-region (point-min) (point-max))
54369c0f 236 (buffer-string)))
49116ac0
JB
237
238(provide 'bib-mode)
239
cbee283d 240;; arch-tag: e3a97958-3c2c-487f-9557-fafc3c98452d
c0274f38 241;;; bib-mode.el ends here