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