From mboxrd@z Thu Jan 1 00:00:00 1970 From: Richard Lawrence Subject: Re: Managing bibtex database using org-mode? Date: Thu, 08 May 2014 09:30:09 -0700 Message-ID: <871tw4xmge.fsf@berkeley.edu> References: <5369F4E8.3020807@gmail.com> <587A9279-A389-4A3F-808D-1E090741DD98@agrarianresearch.org> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Return-path: Received: from eggs.gnu.org ([2001:4830:134:3::10]:50316) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WiREt-0003pK-1o for emacs-orgmode@gnu.org; Thu, 08 May 2014 12:32:12 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1WiREn-0007im-GY for emacs-orgmode@gnu.org; Thu, 08 May 2014 12:32:06 -0400 Received: from plane.gmane.org ([80.91.229.3]:47173) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WiREn-0007ic-6b for emacs-orgmode@gnu.org; Thu, 08 May 2014 12:32:01 -0400 Received: from list by plane.gmane.org with local (Exim 4.69) (envelope-from ) id 1WiREk-0002Zj-Nw for emacs-orgmode@gnu.org; Thu, 08 May 2014 18:31:58 +0200 Received: from c-67-164-45-159.hsd1.ca.comcast.net ([67.164.45.159]) by main.gmane.org with esmtp (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Thu, 08 May 2014 18:31:58 +0200 Received: from richard.lawrence by c-67-164-45-159.hsd1.ca.comcast.net with local (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Thu, 08 May 2014 18:31:58 +0200 List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org Sender: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org To: emacs-orgmode@gnu.org Cc: Vikas Rawal --=-=-= Hi Vikas and all, Vikas Rawal writes: >> I manage my whole bibtex database on org. It makes my workflow more >> integrated. It allows me to keep bib info, todo states and notes all >> in the same place, and it allows me to access it all through the >> agenda. I just periodically run org-bibtex to make sure that I have a >> updated bib file. > > This is exactly what I have in mind. Would you mind sharing an example > file, and may be an outline of your work flow? I also manage my whole bibtex database in Org. Here is my setup: 1) I store new readings as I come across them using a capture template. (See the attached "reading.txt".) This template is pretty basic, but I think it could easily be adapted to store more data, such as links to PDFs, or automatically import Bibtex entries (over org-protocol?) using a function from org-bibtex. The relevant stanza from my org-capture-templates is: #+BEGIN_SRC elisp ("dr" "Reading" entry (file+olp ,dissertation-agenda-file "Reading list") (file ,(concat org-template-directory "/reading.txt")) :prepend t) #+END_SRC 2) I use a post-capture hook to detect whether a captured entry is a reading (it looks for the AUTHOR property) and optionally add bibliographic data using org-bibtex-create-in-current-entry: #+BEGIN_SRC elisp (defun add-bibliographic-data () ; this is a bit hacky: we detect the AUTHOR property, and create bibtex entries if ; it is present (message "optionally adding bibliographic data") (if (and (org-entry-get (point) "AUTHOR") (y-or-n-p "Add bibliographic data? ")) ; with prefix arg to get all fields: (org-bibtex-create-in-current-entry 1) nil)) (add-hook 'org-capture-before-finalize-hook (lambda () (add-bibliographic-data))) #+END_SRC This completes the `front-end' portion of my setup, which gets data on new readings into Org. The `back-end' setup, which exports the captured entries to a .bib file, involves a Makefile that calls wrappers around org-bibtex functions. 3) All the wrapper functions do is walk over the Org tree containing my reading list, using org-map-entries, and export each entry with a defined CUSTOM_ID value using org-bibtex-headline to a new buffer. (It skips those with no CUSTOM_ID, since these won't produce valid bibtex entries.) This buffer then gets saved as the new .bib file. The code is in bib-export.el, attached. Note that this code makes some assumptions about my setup (mostly that all reading entries are stored under a top-level "Reading list" heading in a certain Org file); it is not suitable for general use without some adaptation. You can call the wrapper functions from within Emacs using M-x reading-list-to-bibtex. 4) I also call the wrapper functions from a Makefile. This allows me to get a fresh copy of my .bib file whenever it's needed, just by typing `make bib'. Here's the relevant stanza from the Makefile, which lives in the same directory as the file containing my reading list (tasks.org): #+BEGIN_SRC make EMACS=emacs BATCH_EMACS=$(EMACS) --batch -Q --load lib/el/org-dissertation.el build/dissertation.bib: tasks.org lib/el/bib-export.el $(BATCH_EMACS) --load lib/el/bib-export.el --file tasks.org \ --funcall reading-list-to-bibtex bib: build/dissertation.bib #+END_SRC That's it! Hope you find that useful. Best, Richard --=-=-= Content-Disposition: attachment; filename=reading.txt ** %^{Todo state|FIND|PRINT|READ|NOTES} [#%^{Priority|A|B|C}] %^{Description|Reading} %^g %^{TITLE}p %^{AUTHOR}p %^{AREA}p %? :PROPERTIES: :Entered: %U :END: --=-=-= Content-Type: application/emacs-lisp Content-Disposition: attachment; filename=bib-export.el Content-Transfer-Encoding: quoted-printable ;; load locally installed org mode package=20 (add-to-list 'load-path "~/src/org-mode/lisp") (require 'org-install) (setq dissertation-bib-file "~/Documents/philosophy/dissertation/build/diss= ertation.bib") (defun add-headline-to-bib-buffer (bib-buffer) "Export headline at point to Bibtex into the given buffer" (let ((bib-entry (org-bibtex-headline)) (custom-id (org-entry-get (point) "CUSTOM_ID"))) (if (and custom-id bib-entry) (with-current-buffer bib-buffer (insert bib-entry))))) =20=20=20=20 (defun export-subtree-to-bib-buffer (headline bib-buffer) "Export the entries in the subtree at point to Bibtex into the given buff= er." (save-excursion (goto-char (org-find-exact-headline-in-buffer headline)) (org-map-entries (lambda () (add-headline-to-bib-buffer bib-buffer)) t ; match: all entries below this one 'tree ; scope: just this subtree ))) (defun reading-list-to-bibtex () "Export 'Reading list' headline in current buffer to dissertation.bib" (interactive) (let ((org-buffer (current-buffer)) (bib-buffer (create-file-buffer "dissertation.bib"))) (export-subtree-to-bib-buffer "Reading list" bib-buffer) (with-current-buffer bib-buffer (write-file dissertation-bib-file)))) =20=20=20 --=-=-=--