* lisp/net/rcirc.el: Add PRIVMSG and CTCP functions.
[bpt/emacs.git] / lisp / textmodes / bib-mode.el
CommitLineData
55535639 1;;; bib-mode.el --- major mode for editing bib files
c0274f38 2
73b0cd50 3;; Copyright (C) 1989, 2001-2011 Free Software Foundation, Inc.
9750e079 4
841a91fe
GM
5;; Author: Henry Kautz
6;; (according to authors.el)
e5167999 7;; Maintainer: FSF
e5167999
ER
8;; Keywords: bib
9
54369c0f
JB
10;; This file is part of GNU Emacs.
11
1fecc8fe 12;; GNU Emacs is free software: you can redistribute it and/or modify
54369c0f 13;; it under the terms of the GNU General Public License as published by
1fecc8fe
GM
14;; the Free Software Foundation, either version 3 of the License, or
15;; (at your option) any later version.
54369c0f
JB
16
17;; GNU Emacs is distributed in the hope that it will be useful,
18;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20;; GNU General Public License for more details.
21
22;; You should have received a copy of the GNU General Public License
1fecc8fe 23;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
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-"
6700fc05 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 ""
7caf6803 129 (progn (forward-line -1) (bib-find-key bib-assoc))))
54369c0f
JB
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)
7caf6803 183 (forward-line 1)
54369c0f
JB
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 229 "Like `capitalize', but don't capitalize stop words, except the first."
9a529312
SM
230 (with-current-buffer (get-buffer-create "$$$Scratch$$$")
231 (erase-buffer)
232 (insert s)
233 (bib-capitalize-title-region (point-min) (point-max))
234 (buffer-string)))
49116ac0
JB
235
236(provide 'bib-mode)
237
c0274f38 238;;; bib-mode.el ends here