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