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