2008-11-23 Carsten Dominik <carsten.dominik@gmail.com>
[bpt/emacs.git] / lisp / org / org-bibtex.el
CommitLineData
20908596
CD
1;;; org-bibtex.el --- Org links to BibTeX entries
2;;
3;; Copyright 2007, 2008 Free Software Foundation, Inc.
4;;
5;; Author: Bastien Guerry <bzg at altern dot org>
6;; Carsten Dominik <carsten dot dominik at gmail dot com>
7;; Keywords: org, wp, remember
ce4fdcb9 8;; Version: 6.13
20908596
CD
9;;
10;; This file is part of GNU Emacs.
11;;
b1fc2b50 12;; GNU Emacs is free software: you can redistribute it and/or modify
20908596 13;; it under the terms of the GNU General Public License as published by
b1fc2b50
GM
14;; the Free Software Foundation, either version 3 of the License, or
15;; (at your option) any later version.
20908596
CD
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
b1fc2b50 23;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
20908596
CD
24;;
25;;; Commentary:
26;;
27;; This file implements links to database entries in BibTeX files.
28;; Instead of defining a special link prefix, it uses the normal file
29;; links combined with a custom search mechanism to find entries
30;; by reference key. And it constucts a nice description tag for
31;; the link that contains the author name, the year and a short title.
32;;
33;; It also stores detailed information about the entry so that
34;; remember templates can access and enter this information easily.
35;;
36;; The available properties for each entry are listed here:
37;;
38;; :author :publisher :volume :pages
39;; :editor :url :number :journal
40;; :title :year :series :address
41;; :booktitle :month :annote :abstract
42;; :key :btype
43;;
44;; Here is an example of a remember template that use some of this
45;; information (:author :year :title :journal :pages):
46;;
47;; (setq org-remember-templates
48;; '((?b "* READ %?\n\n%a\n\n%:author (%:year): %:title\n \
49;; In %:journal, %:pages.")))
50;;
51;; Let's say you want to remember this BibTeX entry:
52;;
53;; @Article{dolev83,
54;; author = {Danny Dolev and Andrew C. Yao},
55;; title = {On the security of public-key protocols},
56;; journal = {IEEE Transaction on Information Theory},
57;; year = 1983,
58;; volume = 2,
59;; number = 29,
60;; pages = {198--208},
61;; month = {Mars}
62;; }
63;;
64;; M-x `org-remember' on this entry will produce this buffer:
65;;
66;; =====================================================================
67;; * READ <== [point here]
68;;
69;; [[file:/file.bib::dolev83][Dolev & Yao 1983: security of public key protocols]]
70;;
71;; Danny Dolev and Andrew C. Yao (1983): On the security of public-key protocols
72;; In IEEE Transaction on Information Theory, 198--208.
73;; =====================================================================
74;;
75;;; History:
76;;
77;; The link creation part has been part of Org-mode for a long time.
78;;
79;; Creating better remember template information was inspired by a request
80;; of Austin Frank: http://article.gmane.org/gmane.emacs.orgmode/4112
81;; and then imlemented by Bastien Guerry.
82;;
83;; Org-mode loads this module by default - if this is not what you want,
84;; configure the variable `org-modules'.
85
86;;; Code:
87
88(require 'org)
89
90(defvar description nil) ; dynamically scoped from org.el
91
92(declare-function bibtex-beginning-of-entry "bibtex" ())
93(declare-function bibtex-generate-autokey "bibtex" ())
94(declare-function bibtex-parse-entry "bibtex" (&optional content))
95(declare-function bibtex-url "bibtex" (&optional pos no-browse))
96
97(org-add-link-type "bibtex" 'org-bibtex-open)
98(add-hook 'org-store-link-functions 'org-bibtex-store-link)
99
100;; (defun org-bibtex-publish (path)
101;; "Build the description of the BibTeX entry for publishing."
102;; (let* ((search (when (string-match "::\\(.+\\)\\'" path)
103;; (match-string 1 path)))
104;; (path (substring path 0 (match-beginning 0)))
105;; key)
106;; (with-temp-buffer
107;; (org-open-file path t nil search)
108;; (setq key (org-create-file-search-functions)))
109;; (or description key)))
110
111(defun org-bibtex-open (path)
112 "Visit the bibliography entry on PATH."
113 (let* ((search (when (string-match "::\\(.+\\)\\'" path)
114 (match-string 1 path)))
115 (path (substring path 0 (match-beginning 0))))
116 (org-open-file path t nil search)))
117
118(defun org-bibtex-store-link ()
119 "Store a link to a BibTeX entry."
120 (when (eq major-mode 'bibtex-mode)
121 (let* ((search (org-create-file-search-in-bibtex))
122 (link (concat "file:" (abbreviate-file-name buffer-file-name)
123 "::" search))
124 (entry (mapcar ; repair strings enclosed in "..." or {...}
125 (lambda(c)
126 (if (string-match
127 "^\\(?:{\\|\"\\)\\(.*\\)\\(?:}\\|\"\\)$" (cdr c))
128 (cons (car c) (match-string 1 (cdr c))) c))
129 (save-excursion
130 (bibtex-beginning-of-entry)
131 (bibtex-parse-entry)))))
132 (org-store-link-props
133 :key (cdr (assoc "=key=" entry))
134 :author (or (cdr (assoc "author" entry)) "[no author]")
135 :editor (or (cdr (assoc "editor" entry)) "[no editor]")
136 :title (or (cdr (assoc "title" entry)) "[no title]")
137 :booktitle (or (cdr (assoc "booktitle" entry)) "[no booktitle]")
138 :journal (or (cdr (assoc "journal" entry)) "[no journal]")
139 :publisher (or (cdr (assoc "publisher" entry)) "[no publisher]")
140 :pages (or (cdr (assoc "pages" entry)) "[no pages]")
141 :url (or (cdr (assoc "url" entry)) "[no url]")
142 :year (or (cdr (assoc "year" entry)) "[no year]")
143 :month (or (cdr (assoc "month" entry)) "[no month]")
144 :address (or (cdr (assoc "address" entry)) "[no address]")
145 :volume (or (cdr (assoc "volume" entry)) "[no volume]")
146 :number (or (cdr (assoc "number" entry)) "[no number]")
147 :annote (or (cdr (assoc "annote" entry)) "[no annotation]")
148 :series (or (cdr (assoc "series" entry)) "[no series]")
149 :abstract (or (cdr (assoc "abstract" entry)) "[no abstract]")
150 :btype (or (cdr (assoc "=type=" entry)) "[no type]")
151 :type "bibtex"
152 :link link
153 :description description))))
154
155(defun org-create-file-search-in-bibtex ()
156 "Create the search string and description for a BibTeX database entry."
157 ;; Make a good description for this entry, using names, year and the title
158 ;; Put it into the `description' variable which is dynamically scoped.
159 (let ((bibtex-autokey-names 1)
160 (bibtex-autokey-names-stretch 1)
161 (bibtex-autokey-name-case-convert-function 'identity)
162 (bibtex-autokey-name-separator " & ")
163 (bibtex-autokey-additional-names " et al.")
164 (bibtex-autokey-year-length 4)
165 (bibtex-autokey-name-year-separator " ")
166 (bibtex-autokey-titlewords 3)
167 (bibtex-autokey-titleword-separator " ")
168 (bibtex-autokey-titleword-case-convert-function 'identity)
169 (bibtex-autokey-titleword-length 'infty)
170 (bibtex-autokey-year-title-separator ": "))
171 (setq description (bibtex-generate-autokey)))
172 ;; Now parse the entry, get the key and return it.
173 (save-excursion
174 (bibtex-beginning-of-entry)
175 (cdr (assoc "=key=" (bibtex-parse-entry)))))
176
177(defun org-execute-file-search-in-bibtex (s)
178 "Find the link search string S as a key for a database entry."
179 (when (eq major-mode 'bibtex-mode)
180 ;; Yes, we want to do the search in this file.
181 ;; We construct a regexp that searches for "@entrytype{" followed by the key
182 (goto-char (point-min))
183 (and (re-search-forward (concat "@[a-zA-Z]+[ \t\n]*{[ \t\n]*"
184 (regexp-quote s) "[ \t\n]*,") nil t)
185 (goto-char (match-beginning 0)))
186 (if (and (match-beginning 0) (equal current-prefix-arg '(16)))
187 ;; Use double prefix to indicate that any web link should be browsed
188 (let ((b (current-buffer)) (p (point)))
189 ;; Restore the window configuration because we just use the web link
190 (set-window-configuration org-window-config-before-follow-link)
191 (save-excursion (set-buffer b) (goto-char p)
192 (bibtex-url)))
193 (recenter 0)) ; Move entry start to beginning of window
194 ;; return t to indicate that the search is done.
195 t))
196
197;; Finally add the link search function to the right hook.
198(add-hook 'org-execute-file-search-functions 'org-execute-file-search-in-bibtex)
199
200(provide 'org-bibtex)
201
88ac7b50 202;; arch-tag: 83987d5a-01b8-41c7-85bc-77700f1285f5
b349f79f 203
20908596 204;;; org-bibtex.el ends here