org-bibtex.el 8.1 KB

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