]> git.donarmstrong.com Git - org-ref.git/blobdiff - org-ref.org
added new doi menu link for org-mode
[org-ref.git] / org-ref.org
index 62e9804063331dbce20da913f39b412f6f265c76..30bf03006a56807061533ebd416bb99e1780e794 100644 (file)
@@ -92,10 +92,28 @@ There are some variables needed later to tell this library where you store your
   :group 'org-ref)
 
 (defcustom org-ref-bibliography-entry-format
-  "%a, %t, <i>%j</i>, <b>%v(%n)</b>, %p (%y). <a href=\"%U\">link</a>. <a href=\"http://dx.doi.org/%D\">doi</a>."
-  "string to format an entry. Just the reference, no numbering at the beginning, etc..."
+  '(("article" . "%a, %t, <i>%j</i>, <b>%v(%n)</b>, %p (%y). <a href=\"%U\">link</a>. <a href=\"http://dx.doi.org/%D\">doi</a>.")
+
+    ("book" . "%a, %t, %u (%y).")
+
+    ("proceedings" . "%e, %t in %S, %u (%y).")
+
+    ("inproceedings" . "%a, %t, %p, in %b, edited by %e, %u (%y)"))
+
+  "string to format an entry. Just the reference, no numbering at the beginning, etc... see the `org-ref-reftex-format-citation' docstring for the escape codes."
   :type 'string
   :group 'org-ref)
+
+(defcustom org-ref-open-notes-function
+  (lambda ()
+    (org-show-entry)
+    (show-branches)
+    (show-children)
+    (org-cycle '(64))
+    ;;(org-tree-to-indirect-buffer)
+    (outline-previous-visible-heading 1)
+    (recenter-top-bottom 0))
+  "User-defined way to open a notes entry. This is excecuted after the entry is found, with the cursor at the beginning of the headline. The default setting fully expands the notes, and moves the headline to the top of the buffer") 
 #+END_SRC
 
 This next variable determines the citation types that are available in org-ref. Links for each one are automatically generated, and completion functions are automatically generated. Users may add to this list in their own init files.
@@ -133,6 +151,8 @@ This next variable determines the citation types that are available in org-ref.
     "footcites" "footcitetexts"
     "smartcites" "Smartcites" "textcites" "Textcites"
     "supercites" "autocites" "Autocites"
+    ;; for the bibentry package
+    "bibentry"
     )
   "List of citation types known in org-ref"
   :type '(repeat :tag "List of citation types" string)
@@ -263,6 +283,7 @@ It is also possible to access all other BibTeX database fields:
 %B booktitle, abbreviated          %T title, abbreviated
 %U url
 %D doi
+%S series
 
 Usually, only %l is needed.  The other stuff is mainly for the echo area
 display, and for (setq reftex-comment-citations t).
@@ -324,6 +345,7 @@ environment, only %l is available."
                                (org-ref-reftex-get-bib-field "pages" entry)
                                "[- .]+")))
                ((= l ?s) (org-ref-reftex-get-bib-field "school" entry))
+               ((= l ?S) (org-ref-reftex-get-bib-field "series" entry))
                ((= l ?u) (org-ref-reftex-get-bib-field "publisher" entry))
                ((= l ?U) (org-ref-reftex-get-bib-field "url" entry))
                ((= l ?r) (org-ref-reftex-get-bib-field "address" entry))
@@ -347,10 +369,10 @@ environment, only %l is available."
   format)
 
 (defun org-ref-get-bibtex-entry-citation (key)
-  "returns a string for the bibliography entry corresponding to key, and formatted according to `org-ref-bibliography-entry-format'"
+  "returns a string for the bibliography entry corresponding to key, and formatted according to the type in `org-ref-bibliography-entry-format'"
 
   (let ((org-ref-bibliography-files (org-ref-find-bibliography))
-       (file) (entry))
+       (file) (entry) (bibtex-entry) (entry-type) (format))
 
     (setq file (catch 'result
                 (loop for file in org-ref-bibliography-files do
@@ -361,7 +383,14 @@ environment, only %l is available."
     (with-temp-buffer
       (insert-file-contents file)
       (bibtex-search-entry key nil 0)
-      (setq entry  (org-ref-reftex-format-citation (bibtex-parse-entry) org-ref-bibliography-entry-format)))
+      (setq bibtex-entry (bibtex-parse-entry))
+      (setq entry-type (downcase (cdr (assoc "=type=" bibtex-entry))))
+      (setq format (cdr (assoc entry-type org-ref-bibliography-entry-format)))
+      (if format
+         (setq entry  (org-ref-reftex-format-citation bibtex-entry format))
+       (save-restriction
+         (bibtex-narrow-to-entry)
+         (setq entry (buffer-string)))))      
     entry))
 #+END_SRC
 
@@ -379,7 +408,7 @@ Here is how to use the function. You call it with point in an entry in a bibtex
 
 I am not sure why full author names are not used.
 
-This code provides some functions to generate a simple sorted bibliography in html. First we get all the keys in the bufer.
+This code provides some functions to generate a simple sorted bibliography in html. First we get all the keys in the buffer.
 
 #+BEGIN_SRC emacs-lisp :tangle org-ref.el
 (defun org-ref-get-bibtex-keys ()
@@ -423,6 +452,79 @@ Now, we map over the whole list of keys, and the whole bibliography, formatted a
 
 I do not have plans to make a numbered bibliography with numbered citations anytime soon. This will require changing the way the citation links are exported, and keeping track of the numbers.
 
+*** An org bibliography
+You can export an org-file to an org-file or org-buffer (org-org-epxort-as-org). In this case, it would be useful convert the cite links to links to custom_ids, and the bibliography link to a first-level heading Bibliography with org-bibtex like headings for each entry. This code should enable this. Right now, it does not appear to work for org export though.
+
+First, we get the string for a single entry.
+#+BEGIN_SRC emacs-lisp :tangle org-ref.el
+(defun org-ref-get-bibtex-entry-org (key)
+  "returns an org string for the bibliography entry corresponding to key"
+  (let ((org-ref-bibliography-files (org-ref-find-bibliography))
+       (file) (entry) (bibtex-entry) (entry-type) (format))
+
+    (setq file (catch 'result
+                (loop for file in org-ref-bibliography-files do
+                      (if (org-ref-key-in-file-p key (file-truename file)) 
+                          (throw 'result file)
+                        (message "%s not found in %s" key (file-truename file))))))
+
+    (with-temp-buffer
+      (insert-file-contents file)
+      (bibtex-search-entry key nil 0)
+      (setq entry (bibtex-parse-entry))
+      (format "** %s - %s
+  :PROPERTIES:
+  %s
+  :END:
+" (org-ref-reftex-get-bib-field "author" entry)
+(org-ref-reftex-get-bib-field "title" entry)
+(concat "   :CUSTOM_ID: " (org-ref-reftex-get-bib-field "=key=" entry) "\n"
+       (mapconcat (lambda (element) (format "   :%s: %s"
+                                            (upcase (car element))
+                                            (cdr element)))
+                  entry
+                  "\n"))))))
+#+END_SRC
+
+Now, we loop over the keys, and combine all the entries into a bibliography.
+#+BEGIN_SRC emacs-lisp :tangle org-ref.el 
+(defun org-ref-get-org-bibliography ()
+  "Create an org bibliography when there are keys"
+  (let ((keys (org-ref-get-bibtex-keys)))
+    (when keys
+      (concat "* Bibliography
+"
+             (mapconcat (lambda (x) (org-ref-get-bibtex-entry-org x)) keys "\n")
+             "\n"))))
+#+END_SRC
+
+*** An ascii bibliography
+
+This function gets the html for one entry.
+
+#+BEGIN_SRC emacs-lisp :tangle org-ref.el
+(defun org-ref-get-bibtex-entry-ascii (key)
+  "returns an ascii string for the bibliography entry corresponding to key"
+
+  (format "[%s] %s" key (org-ref-get-bibtex-entry-citation key)))
+#+END_SRC
+
+Now, we map over the whole list of keys, and the whole bibliography, formatted as an unordered list.
+
+#+BEGIN_SRC emacs-lisp :tangle org-ref.el 
+(defun org-ref-get-ascii-bibliography ()
+  "Create an html bibliography when there are keys"
+  (let ((keys (org-ref-get-bibtex-keys)))
+    (when keys
+      (concat 
+"Bibliography
+=============
+"
+             (mapconcat (lambda (x) (org-ref-get-bibtex-entry-ascii x)) keys "\n")
+             "\n"))))
+#+END_SRC
+
+
 *** the links
 We use a link for the bibliography so that we can click on it to open the bibliography file. The link may have more than one bibliography file in it, separated by commas. Clicking opens the file under the cursor. The bibliographies should be full filenames with the bib extension. Clicking on this link makes reftex-default-bibliography local and sets it to the list of files in the link. We need this to use reftex's searching capability.
 
@@ -474,10 +576,93 @@ We use a link for the bibliography so that we can click on it to open the biblio
                     ;; formatting code
                   (lambda (keyword desc format)
                     (cond
+                     ((eq format 'org) (org-ref-get-org-bibliography))
+                      ((eq format 'ascii) (org-ref-get-ascii-bibliography))
                      ((eq format 'html) (org-ref-get-html-bibliography))
                      ((eq format 'latex)
-                        ;; write out the latex bibliography command
-                      (format "\\bibliography{%s}" (replace-regexp-in-string  "\\.bib" "" keyword))))))
+                      ;; write out the latex bibliography command                     
+                      (format "\\bibliography{%s}" (replace-regexp-in-string  "\\.bib" "" (mapconcat 'identity
+                                                                                                     (mapcar 'expand-file-name
+                                                                                                             (split-string keyword ","))
+                                                                                                     ",")))))))
+                                                                              
+#+END_SRC
+
+Believe it or not, sometimes it makes sense /not/ to include the bibliography in a document (e.g. when you are required to submit references as a separate file). To generate the references,  in another file, you must make a little tex file with these contents, and then compile it.
+
+#+BEGIN_LaTeX
+  \input{project-description.bbl}
+#+END_LaTeX
+
+Here, we make a =nobibliography= link that acts like the bibliography, enables creation of the bbl file, but does not put an actual bibliography in the file.
+
+#+BEGIN_SRC emacs-lisp :tangle org-ref.el
+(org-add-link-type "nobibliography"
+                  ;; this code is run on clicking. The bibliography
+                  ;; may contain multiple files. this code finds the
+                  ;; one you clicked on and opens it.
+                  (lambda (link-string)        
+                      ;; get link-string boundaries
+                      ;; we have to go to the beginning of the line, and then search forward
+                      
+                    (let* ((bibfile)
+                           ;; object is the link you clicked on
+                           (object (org-element-context))
+                           (link-string-beginning) 
+                           (link-string-end))
+
+                    (save-excursion
+                      (goto-char (org-element-property :begin object))
+                      (search-forward link-string nil nil 1)
+                      (setq link-string-beginning (match-beginning 0))
+                      (setq link-string-end (match-end 0)))
+
+                      ;; We set the reftex-default-bibliography
+                      ;; here. it should be a local variable only in
+                      ;; the current buffer. We need this for using
+                      ;; reftex to do citations.
+                      (set (make-local-variable 'reftex-default-bibliography) 
+                           (split-string (org-element-property :path object) ","))
+
+                      ;; now if we have comma separated bibliographies
+                      ;; we find the one clicked on. we want to
+                      ;; search forward to next comma from point
+                      (save-excursion
+                        (if (search-forward "," link-string-end 1 1)
+                            (setq key-end (- (match-end 0) 1)) ; we found a match
+                          (setq key-end (point)))) ; no comma found so take the point
+                      ;; and backward to previous comma from point
+                      (save-excursion
+                        (if (search-backward "," link-string-beginning 1 1)
+                            (setq key-beginning (+ (match-beginning 0) 1)) ; we found a match
+                          (setq key-beginning (point)))) ; no match found
+                      ;; save the key we clicked on.
+                      (setq bibfile (org-ref-strip-string (buffer-substring key-beginning key-end)))
+                      (find-file bibfile))) ; open file on click
+
+                    ;; formatting code
+                  (lambda (keyword desc format)
+                    (cond
+                     ((eq format 'org) (org-ref-get-org-bibliography))
+                      ((eq format 'ascii) (org-ref-get-ascii-bibliography))
+                     ((eq format 'html) (org-ref-get-html-bibliography))
+                     ((eq format 'latex)
+                      ;; write out the latex bibliography command                     
+
+;                     (format "{\\setbox0\\vbox{\\bibliography{%s}}}"
+;                             (replace-regexp-in-string  "\\.bib" "" (mapconcat 'identity
+;                                                                               (mapcar 'expand-file-name
+;                                                                                       (split-string keyword ","))
+;                                                                               ",")))
+
+                      (format "\\nobibliography{%s}"
+                              (replace-regexp-in-string  "\\.bib" "" (mapconcat 'identity
+                                                                                (mapcar 'expand-file-name
+                                                                                        (split-string keyword ","))
+                                                                                ",")))
+
+                      ))))                                                                            
 #+END_SRC
 
 #+BEGIN_SRC emacs-lisp :tangle org-ref.el
@@ -485,10 +670,12 @@ We use a link for the bibliography so that we can click on it to open the biblio
                   (lambda (arg) (message "Nothing implemented for clicking here."))
                   (lambda (keyword desc format)
                     (cond
+                      ((eq format 'org) (org-ref-get-org-bibliography))
                       ((eq format 'html) (org-ref-get-html-bibliography))
                      ((eq format 'latex)
-                      ;; write out the latex bibliography command
-                      (format "\\printbibliography" keyword)))))
+                      ;; write out the biblatex bibliography command
+                      "\\printbibliography"))
+))
 #+END_SRC
 
 We also create a bibliographystyle link. There is nothing to do on clicking here, and we create it for consistency. This sets the style for latex export, so use something appropriate there, e.g. unsrt, plain, plainnat, ...
@@ -777,6 +964,7 @@ At the moment, ref links are not usable for section links. You need [[#CUSTOM_ID
      ;; we did not find anything, so go back to where we came
      (org-mark-ring-goto)
      (error "%s not found" label))
+   (org-show-entry)
    (message "go back with (org-mark-ring-goto) `C-c &`"))
  ;formatting
  (lambda (keyword desc format)
@@ -1002,30 +1190,43 @@ to get a comma, or the beginning of the link. that delimits the
 keyword we clicked on. We also strip the text properties."
   (interactive)
   (let* ((object (org-element-context))         
-        (link-string (org-element-property :path object)))    
-    
-    ;; we need the link path start and end
-    (save-excursion
+        (link-string (org-element-property :path object)))
+    ;; you may click on the part before the citations. here we make
+    ;; sure to move to the beginning so you get the first citation.
+    (let ((cp (point)))
       (goto-char (org-element-property :begin object))
-      (search-forward link-string nil nil 1)
-      (setq link-string-beginning (match-beginning 0))
-      (setq link-string-end (match-end 0)))
+      (search-forward link-string (org-element-property :end object))
+      (goto-char (match-beginning 0))
+      ;; check if we clicked before the path and move as needed.
+      (unless (< cp (point))
+       (goto-char cp)))
+       
+    (if (not (org-element-property :contents-begin object))
+       ;; this means no description in the link
+       (progn    
+         ;; we need the link path start and end
+         (save-excursion
+           (goto-char (org-element-property :begin object))
+           (search-forward link-string nil nil 1)
+           (setq link-string-beginning (match-beginning 0))
+           (setq link-string-end (match-end 0)))
 
-    ;; The key is the text between commas, or the link boundaries
-    (save-excursion
-      (if (search-forward "," link-string-end t 1)
-         (setq key-end (- (match-end 0) 1)) ; we found a match
-       (setq key-end link-string-end))) ; no comma found so take the end
-    ;; and backward to previous comma from point which defines the start character
-    (save-excursion
-      (if (search-backward "," link-string-beginning 1 1)
-         (setq key-beginning (+ (match-beginning 0) 1)) ; we found a match
-       (setq key-beginning link-string-beginning))) ; no match found
-    ;; save the key we clicked on.
-    (setq bibtex-key (org-ref-strip-string (buffer-substring key-beginning key-end)))
-    (set-text-properties 0 (length bibtex-key) nil bibtex-key)
-    bibtex-key
-    ))
+         ;; The key is the text between commas, or the link boundaries
+         (save-excursion
+           (if (search-forward "," link-string-end t 1)
+               (setq key-end (- (match-end 0) 1)) ; we found a match
+             (setq key-end link-string-end))) ; no comma found so take the end
+         ;; and backward to previous comma from point which defines the start character
+         (save-excursion
+           (if (search-backward "," link-string-beginning 1 1)
+               (setq key-beginning (+ (match-beginning 0) 1)) ; we found a match
+             (setq key-beginning link-string-beginning))) ; no match found
+         ;; save the key we clicked on.
+         (setq bibtex-key (org-ref-strip-string (buffer-substring key-beginning key-end)))
+         (set-text-properties 0 (length bibtex-key) nil bibtex-key)
+         bibtex-key)
+      ;; link with description. assume only one key
+      link-string)))
 #+END_SRC
 
 We also need to find which bibliography file that key is in. For that, we need to know which bibliography files are referred to in the file. If none are specified with a bibliography link, we use the default bibliography. This function searches for a bibliography link, and then the LaTeX bibliography link. We also consider the addbibresource link which is used with biblatex.
@@ -1085,11 +1286,9 @@ Now, we can see if an entry is in a file.
 (defun org-ref-key-in-file-p (key filename)
   "determine if the key is in the file"
   (interactive "skey: \nsFile: ")
-
-  (with-temp-buffer
-    (insert-file-contents filename)
-    (prog1
-        (bibtex-search-entry key nil 0))))
+  (save-current-buffer
+    (let ((bibtex-files (list filename)))
+      (bibtex-search-entry key t))))
 #+END_SRC
 
 Finally, we want to know which file the key is in.
@@ -1340,6 +1539,19 @@ We will want to generate formatting functions for each citation type. The reason
 (defmacro org-ref-make-format-function (type)
   `(defun ,(intern (format "org-ref-format-%s" type)) (keyword desc format)
      (cond
+      ((eq format 'org)
+       (mapconcat
+       (lambda (key)
+         (format "[[#%s][%s]]" key key))
+       (org-ref-split-and-strip-string keyword) ","))
+
+      ((eq format 'ascii)
+       (concat "["
+              (mapconcat
+               (lambda (key)
+                 (format "%s" key))
+               (org-ref-split-and-strip-string keyword) ",") "]"))
+       
       ((eq format 'html) 
        (mapconcat 
        (lambda (key) 
@@ -1492,55 +1704,6 @@ org-mode already defines a store link function for bibtex entries. It does not s
     (car org-stored-links)))
 #+END_SRC
 
-** An html bibliography
-This code provides some functions to generate a simple bibliography in html.
-
-#+BEGIN_SRC emacs-lisp :tangle org-ref.el
-(defun org-ref-get-bibtex-keys ()
-  "return a list of unique keys in the buffer"
-  (interactive)
-  (let ((keys '()))
-    (org-element-map (org-element-parse-buffer) 'link
-      (lambda (link)       
-       (let ((plist (nth 1 link)))                          
-         (when (-contains? org-ref-cite-types (plist-get plist ':type))
-           (dolist 
-               (key 
-                (org-ref-split-and-strip-string (plist-get plist ':path)))
-             (when (not (-contains? keys key))
-               (setq keys (append keys (list key)))))))))
-    keys))
-#+END_SRC
-
-
-#+BEGIN_SRC emacs-lisp :tangle org-ref.el
-(defun org-ref-get-bibtex-entry-html (key)
- (let ((org-ref-bibliography-files (org-ref-find-bibliography))
-       (file) (entry))
-
-   (setq file (catch 'result
-               (loop for file in org-ref-bibliography-files do
-                     (if (org-ref-key-in-file-p key (file-truename file)) 
-                         (throw 'result file)))))
-   (if file (with-temp-buffer
-              (insert-file-contents file)
-              (prog1
-                  (bibtex-search-entry key nil 0)
-                (setq entry  (org-ref-bib-html-citation)))
-              (format "<li><a id=\"%s\">[%s] %s</a></li>" key key entry)))))
-#+END_SRC
-
-
-#+BEGIN_SRC emacs-lisp :tangle org-ref.el 
-(defun org-ref-get-html-bibliography ()
-  "Create an html bibliography when there are keys"
-  (let ((keys (org-ref-get-bibtex-keys)))
-    (when keys
-      (concat "<h1>Bibliography</h1>
-<ul>"
-             (mapconcat (lambda (x) (org-ref-get-bibtex-entry-html x)) keys "\n")
-             "\n</ul>"))))
-#+END_SRC
 
 * Utilities
 ** create simple text citation from bibtex entry
@@ -1657,12 +1820,14 @@ construct the heading by hand."
     
     ;; now look for entry in the notes file
     (if  org-ref-bibliography-notes
-       (find-file org-ref-bibliography-notes)
+       (find-file-other-window org-ref-bibliography-notes)
       (error "org-ref-bib-bibliography-notes is not set to anything"))
     
     (goto-char (point-min))
     ;; put new entry in notes if we don't find it.
-    (unless (re-search-forward (format ":Custom_ID: %s$" key) nil 'end)
+    (if (re-search-forward (format ":Custom_ID: %s$" key) nil 'end)
+       (funcall org-ref-open-notes-function)
+      ;; no entry found, so add one    
       (insert (format "\n** TODO %s - %s" year title))
       (insert (format"
  :PROPERTIES:
@@ -1680,6 +1845,25 @@ key author journal year volume pages doi url key org-ref-pdf-directory key))
 (save-buffer))))
 #+END_SRC
 
+#+BEGIN_SRC emacs-lisp :tangle org-ref.el
+(defun org-ref-open-notes-from-reftex ()
+  "Call reftex, and open notes for selected entry."
+  (interactive)
+  (let ((bibtex-key )))
+
+    ;; now look for entry in the notes file
+    (if  org-ref-bibliography-notes
+       (find-file-other-window org-ref-bibliography-notes)
+      (error "org-ref-bib-bibliography-notes is not set to anything"))
+    
+    (goto-char (point-min))
+    
+    (re-search-forward (format
+                       ":Custom_ID: %s$"
+                       (first (reftex-citation t)) nil 'end))
+    (funcall org-ref-open-notes-function))
+#+END_SRC
+
 ** open url in browser from bibtex
 
 We bind this to a key here [[*key%20bindings%20for%20utilities][key bindings for utilities]].
@@ -2156,6 +2340,7 @@ I like convenience. Here are some aliases for faster typing.
 (defalias 'orp 'org-ref-open-pdf-at-point)
 (defalias 'oru 'org-ref-open-url-at-point)
 (defalias 'orn 'org-ref-open-notes-at-point)
+(defalias 'ornr 'org-ref-open-notes-from-reftex)
 
 (defalias 'orib 'org-ref-insert-bibliography-link)
 (defalias 'oric 'org-ref-insert-cite-link)