-;;; Commentary:
-;;
-;; Lisp code to setup bibliography cite, ref and label org-mode links. also
-;; sets up reftex and helm for org-mode citations. The links are clickable and
-;; do things that are useful. You should really read org-ref.org for details.
-;;
-;; Package-Requires: ((dash) (helm) (helm-bibtex))
-#+END_SRC
-
-** requires
-The only external require is reftex-cite
-
-#+BEGIN_SRC emacs-lisp :tangle org-ref.el
-(require 'reftex-cite)
-(require 'dash)
-(require 'helm)
-(require 'helm-bibtex)
-#+END_SRC
-
-** Custom variables
-There are some variables needed later to tell this library where you store your pdf files, where your notes file is, and your default bibliography. This variable is similar to the reftex-default-bibliography. I do not remember why I made it separate.
-
-#+BEGIN_SRC emacs-lisp :tangle org-ref.el
-(defgroup org-ref nil
- "customization group for org-ref")
-
-(defcustom org-ref-bibliography-notes
- nil
- "filename to where you will put all your notes about an entry in
- the default bibliography."
- :type 'file
- :group 'org-ref)
-
-(defcustom org-ref-default-bibliography
- nil
- "list of bibtex files to search for. You should use full-paths for each file."
- :type '(repeat :tag "List of bibtex files" file)
- :group 'org-ref)
-
-(defcustom org-ref-pdf-directory
- nil
- "directory where pdfs are stored by key. put a trailing / in"
- :type 'directory
- :group 'org-ref)
-
-(defcustom org-ref-default-citation-link
- "cite"
- "The default type of citation link to use"
- :type 'string
- :group 'org-ref)
-
-(defcustom org-ref-insert-cite-key
- "C-c ]"
- "Keyboard shortcut to insert a citation."
- :type 'string
- :group 'org-ref)
-
-(defcustom org-ref-bibliography-entry-format
- '(("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"
-:type 'function
-:group 'org-ref)
-
-
-(defcustom org-ref-open-pdf-function
- 'org-ref-open-pdf-at-point
-"User-defined function to open a pdf from a link. The function must get the key at point, and derive a path to the pdf file, then open it. The default function is `org-ref-open-pdf-at-point'."
- :type 'function
- :group 'org-ref)
-
-
-(defcustom org-ref-insert-cite-function
- 'helm-bibtex
- "Function to call to insert citation links. The default is `helm-bibtex'. org-ref modifies helm-bibtex a little bit to give org-mode citations, and to reorder default actions. You may use `org-ref-insert-cite-link' if you like the reftex interface."
- :type 'function
- :group 'org-ref)
-
-
-(defcustom org-ref-cite-onclick-function
- 'org-ref-cite-click-helm
- "Function that runs when you click on a cite link. The function must take no arguments. You may also use `org-ref-cite-onclick-minibuffer-menu' if you do not like helm."
- :type 'function
- :group 'org-ref)
-
-(defcustom org-ref-show-citation-on-enter t
- "If non-nil add a hook function to show the citation summary in
- the minibuffer just by putting the cursor in a link"
- :group 'org-ref)
-
-#+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.
-
-#+BEGIN_SRC emacs-lisp :tangle org-ref.el
-(defcustom org-ref-cite-types
- '("cite" "nocite" ;; the default latex cite commands
- ;; natbib cite commands, http://ctan.unixbrain.com/macros/latex/contrib/natbib/natnotes.pdf
- "citet" "citet*" "citep" "citep*"
- "citealt" "citealt*" "citealp" "citealp*"
- "citenum" "citetext"
- "citeauthor" "citeauthor*"
- "citeyear" "citeyear*"
- "Citet" "Citep" "Citealt" "Citealp" "Citeauthor"
- ;; biblatex commands
- ;; http://ctan.mirrorcatalogs.com/macros/latex/contrib/biblatex/doc/biblatex.pdf
- "Cite"
- "parencite" "Parencite"
- "footcite" "footcitetext"
- "textcite" "Textcite"
- "smartcite" "Smartcite"
- "cite*" "parencite*" "supercite"
- "autocite" "Autocite" "autocite*" "Autocite*"
- "Citeauthor*"
- "citetitle" "citetitle*"
- "citedate" "citedate*"
- "citeurl"
- "fullcite" "footfullcite"
- ;; "volcite" "Volcite" cannot support the syntax
- "notecite" "Notecite"
- "pnotecite" "Pnotecite"
- "fnotecite"
- ;; multicites. Very limited support for these.
- "cites" "Cites" "parencites" "Parencites"
- "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)
- :group 'org-ref)
-#+END_SRC
-
-We need a hook variable to store user-defined bibtex entry cleaning functions
-#+BEGIN_SRC emacs-lisp :tangle org-ref.el
-(defcustom org-ref-clean-bibtex-entry-hook nil
- "Hook that is run in org-ref-clean-bibtex-entry. The functions should take no arguments, and operate on the bibtex entry at point."
- :group 'org-ref
- :type 'hook)
-#+END_SRC
-
-** Program variables
-#+BEGIN_SRC emacs-lisp :tangle org-ref.el
-(defvar org-ref-bibliography-files
- nil
- "variable to hold bibliography files to be searched")
-#+END_SRC
-
-** org-mode / reftex setup
-
-We setup reftex here. We use a custom insert cite link function defined here: [[*org-ref-insert-cite-link][org-ref-insert-cite-link]]. We setup reftex to use our org citation format.
-
-#+BEGIN_SRC emacs-lisp :tangle org-ref.el
-(require 'reftex)
-(defun org-mode-reftex-setup ()
- (and (buffer-file-name)
- (file-exists-p (buffer-file-name))
- (global-auto-revert-mode t)
- ;; I do not remember why I put this next line in. It doesn't
- ;; work for org-files. Nothing very bad happens, but it gives
- ;; an annoying error. Commenting it out for now.
- ;(reftex-parse-all)
- )
- (make-local-variable 'reftex-cite-format)
- (setq reftex-cite-format 'org)
- (define-key org-mode-map (kbd org-ref-insert-cite-key) org-ref-insert-cite-function))
-
-(add-hook 'org-mode-hook 'org-mode-reftex-setup)
-
-(eval-after-load 'reftex-vars
- '(progn
- (add-to-list 'reftex-cite-format-builtin
- '(org "Org-mode citation"
- ((?\C-m . "cite:%l") ; default
- (?d . ",%l") ; for appending
- (?a . "autocite:%l")
- (?t . "citet:%l")
- (?T . "citet*:%l")
- (?p . "citep:%l")
- (?P . "citep*:%l")
- (?h . "citeauthor:%l")
- (?H . "citeauthor*:%l")
- (?y . "citeyear:%l")
- (?x . "citetext:%l")
- (?n . "nocite:%l")
- )))))
-#+END_SRC
-
-You may want to add new formats to the reftex-cite-format-builtin variable. Here is an example of adding two new formats. Note that this does not create the links.
-
-#+BEGIN_SRC emacs-lisp :tangle no
-;; add new format
-(setf (nth 2 (assoc 'org reftex-cite-format-builtin))
- (append (nth 2 (assoc 'org reftex-cite-format-builtin)) '((?W . "textcite:%l")
- (?z . "newcite:%l"))))
-#+END_SRC
-
-You can define a new citation link like this:
-#+BEGIN_SRC emacs-lisp :tangle no
-(org-ref-define-citation-link "citez" ?z)
-#+END_SRC
-
-* Links
-Most of this library is the creation of functional links to help with references and citations.
-** General utilities
-We need several general utilities for this module. They are organized here. We frequently need to remove white space from the front and back of a string. Here we do that for a string.
-
-#+BEGIN_SRC emacs-lisp :tangle org-ref.el
-(defun org-ref-strip-string (string)
- "strip leading and trailing whitespace from the string"
- (replace-regexp-in-string
- (concat search-whitespace-regexp "$" ) ""
- (replace-regexp-in-string
- (concat "^" search-whitespace-regexp ) "" string)))
-#+END_SRC
-
-It is helpful to make the previous function operate on a list of strings here.
-
-#+BEGIN_SRC emacs-lisp :tangle org-ref.el
-(defun org-ref-split-and-strip-string (string)
- "split key-string and strip keys. Assumes the key-string is comma delimited"
- (mapcar 'org-ref-strip-string (split-string string ",")))
-#+END_SRC
-
-** bibliography and bibliographystyle
-*** An html bibliography
-
-Reftex is no longer being developed. I want a url and doi option for formatting, so I am modifying this [[file:emacs-24.3/lisp/textmodes/reftex-cite.el::(defun%20reftex-format-citation%20(entry%20format)][function]] from reftex-cite to provide that. We need to modify the reftex-get-bib-field code a bit to remove enclosing braces and quotes so we can make nice looking links.
-
-#+BEGIN_SRC emacs-lisp :tangle org-ref.el
-(defun org-ref-reftex-get-bib-field (field entry &optional format)
- "similar to reftex-get-bib-field, but removes enclosing braces and quotes"
- (let ((result))
- (setq result (reftex-get-bib-field field entry format))
- (when (and (not (string= result "")) (string= "{" (substring result 0 1)))
- (setq result (substring result 1 -1)))
- (when (and (not (string= result "")) (string= "\"" (substring result 0 1)))
- (setq result (substring result 1 -1)))
- result))
-
-(defun org-ref-reftex-format-citation (entry format)
- "return a formatted string for the bibtex entry (from bibtex-parse-entry) according
-to the format argument. The format is a string with these percent escapes.
-
-In the format, the following percent escapes will be expanded.
-
-%l The BibTeX label of the citation.
-%a List of author names, see also `reftex-cite-punctuation'.
-%2a Like %a, but abbreviate more than 2 authors like Jones et al.
-%A First author name only.
-%e Works like %a, but on list of editor names. (%2e and %E work a well)
-
-It is also possible to access all other BibTeX database fields:
-%b booktitle %c chapter %d edition %h howpublished
-%i institution %j journal %k key %m month
-%n number %o organization %p pages %P first page
-%r address %s school %u publisher %t title
-%v volume %y year
-%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).
-
-%< as a special operator kills punctuation and space around it after the
-string has been formatted.
-
-A pair of square brackets indicates an optional argument, and RefTeX
-will prompt for the values of these arguments.
-
-Beware that all this only works with BibTeX database files. When
-citations are made from the \bibitems in an explicit thebibliography
-environment, only %l is available."
- ;; Format a citation from the info in the BibTeX ENTRY
-
- (unless (stringp format) (setq format "\\cite{%l}"))
-
- (if (and reftex-comment-citations
- (string-match "%l" reftex-cite-comment-format))
- (error "reftex-cite-comment-format contains invalid %%l"))
-
- (while (string-match
- "\\(\\`\\|[^%]\\)\\(\\(%\\([0-9]*\\)\\([a-zA-Z]\\)\\)[.,;: ]*\\)"
- format)
- (let ((n (string-to-number (match-string 4 format)))
- (l (string-to-char (match-string 5 format)))
- rpl b e)
- (save-match-data
- (setq rpl
- (cond
- ((= l ?l) (concat
- (org-ref-reftex-get-bib-field "&key" entry)
- (if reftex-comment-citations
- reftex-cite-comment-format
- "")))
- ((= l ?a) (reftex-format-names
- (reftex-get-bib-names "author" entry)
- (or n 2)))
- ((= l ?A) (car (reftex-get-bib-names "author" entry)))
- ((= l ?b) (org-ref-reftex-get-bib-field "booktitle" entry "in: %s"))
- ((= l ?B) (reftex-abbreviate-title
- (org-ref-reftex-get-bib-field "booktitle" entry "in: %s")))
- ((= l ?c) (org-ref-reftex-get-bib-field "chapter" entry))
- ((= l ?d) (org-ref-reftex-get-bib-field "edition" entry))
- ((= l ?D) (org-ref-reftex-get-bib-field "doi" entry))
- ((= l ?e) (reftex-format-names
- (reftex-get-bib-names "editor" entry)
- (or n 2)))
- ((= l ?E) (car (reftex-get-bib-names "editor" entry)))
- ((= l ?h) (org-ref-reftex-get-bib-field "howpublished" entry))
- ((= l ?i) (org-ref-reftex-get-bib-field "institution" entry))
- ((= l ?j) (org-ref-reftex-get-bib-field "journal" entry))
- ((= l ?k) (org-ref-reftex-get-bib-field "key" entry))
- ((= l ?m) (org-ref-reftex-get-bib-field "month" entry))
- ((= l ?n) (org-ref-reftex-get-bib-field "number" entry))
- ((= l ?o) (org-ref-reftex-get-bib-field "organization" entry))
- ((= l ?p) (org-ref-reftex-get-bib-field "pages" entry))
- ((= l ?P) (car (split-string
- (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))
- ;; strip enclosing brackets from title if they are there
- ((= l ?t) (org-ref-reftex-get-bib-field "title" entry))
- ((= l ?T) (reftex-abbreviate-title
- (org-ref-reftex-get-bib-field "title" entry)))
- ((= l ?v) (org-ref-reftex-get-bib-field "volume" entry))
- ((= l ?y) (org-ref-reftex-get-bib-field "year" entry)))))
-
- (if (string= rpl "")
- (setq b (match-beginning 2) e (match-end 2))
- (setq b (match-beginning 3) e (match-end 3)))
- (setq format (concat (substring format 0 b) rpl (substring format e)))))
- (while (string-match "%%" format)
- (setq format (replace-match "%" t t format)))
- (while (string-match "[ ,.;:]*%<" format)
- (setq format (replace-match "" t t format)))
- ;; also replace carriage returns, tabs, and multiple whitespaces
- (setq format (replace-regexp-in-string "\n\\|\t\\|\s+" " " format))
- format)
-
-(defun org-ref-get-bibtex-entry-citation (key)
- "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) (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 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
-
-#+RESULTS:
-: org-ref-reftex-format-citation
-
-Here is how to use the function. You call it with point in an entry in a bibtex file.
-
-#+BEGIN_SRC emacs-lisp :tangle no
-(let((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>."))
- (org-ref-get-bibtex-entry-citation "armiento-2014-high"))
-#+END_SRC
-#+RESULTS:
-: Armiento, Kozinsky, Hautier, , Fornari \& Ceder, High-throughput screening of perovskite alloys for piezoelectric performance and thermodynamic stability, <i>Phys. Rev. B</i>, <b>89()</b>, 134103 (2014). <a href="http://link.aps.org/doi/10.1103/PhysRevB.89.134103">link</a>. <a href="http://dx.doi.org/10.1103/PhysRevB.89.134103">doi</a>.
-
-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 buffer.
-
-#+BEGIN_SRC emacs-lisp :tangle org-ref.el
-(defun org-ref-get-bibtex-keys ()
- "return a list of unique keys in the buffer."
- (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)))))))))
- ;; Sort keys alphabetically
- (setq keys (cl-sort keys 'string-lessp :key 'downcase))
- keys))
-#+END_SRC
-
-This function gets the html for one entry.
-
-#+BEGIN_SRC emacs-lisp :tangle org-ref.el
-(defun org-ref-get-bibtex-entry-html (key)
- "returns an html string for the bibliography entry corresponding to key"
-
- (format "<li><a id=\"%s\">[%s] %s</a></li>" key 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-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
-
-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.
-
-#+BEGIN_SRC emacs-lisp :tangle org-ref.el
-(org-add-link-type "bibliography"
- ;; 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 "\\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
-(org-add-link-type "printbibliography"
- (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 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, ...
-
-#+BEGIN_SRC emacs-lisp :tangle org-ref.el
-(org-add-link-type "bibliographystyle"
- (lambda (arg) (message "Nothing implemented for clicking here."))
- (lambda (keyword desc format)
- (cond
- ((eq format 'latex)
- ;; write out the latex bibliography command
- (format "\\bibliographystyle{%s}" keyword)))))
-#+END_SRC
-
-*** Completion for bibliography link
-It would be nice
-
-#+BEGIN_SRC emacs-lisp :tangle org-ref.el
-(defun org-bibliography-complete-link (&optional arg)
- (format "bibliography:%s" (read-file-name "enter file: " nil nil t)))
-
-(defun org-ref-insert-bibliography-link ()
- "insert a bibliography with completion"
- (interactive)
- (insert (org-bibliography-complete-link)))
-#+END_SRC
-
-** addbibresource
-This is apparently used for biblatex.
-#+BEGIN_SRC emacs-lisp :tangle org-ref.el
-(org-add-link-type "addbibresource"
- ;; this code is run on clicking. The addbibresource
- ;; 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-addbibresource
- ;; 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-addbibresource)
- (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 'html) (format "")); no output for html
- ((eq format 'latex)
- ;; write out the latex addbibresource command
- (format "\\addbibresource{%s}" keyword)))))
-#+END_SRC
-
-** List of Figures
-
-In long documents, a list of figures is not uncommon. Here we create a clickable link that generates a temporary buffer containing a list of figures in the document, and their captions. We make a function that can be called interactively, and define a link type that is rendered in LaTeX to create the list of figures.
-
-#+BEGIN_SRC emacs-lisp :tangle org-ref.el
-(defun org-ref-list-of-figures (&optional arg)
- "Generate buffer with list of figures in them"
- (interactive)
- (save-excursion (widen)
- (let* ((c-b (buffer-name))
- (counter 0)
- (list-of-figures
- (org-element-map (org-element-parse-buffer) 'link
- (lambda (link)
- "create a link for to the figure"
- (when
- (and (string= (org-element-property :type link) "file")
- (string-match-p
- "[^.]*\\.\\(png\\|jpg\\|eps\\|pdf\\)$"
- (org-element-property :path link)))
- (incf counter)
-
- (let* ((start (org-element-property :begin link))
- (parent (car (cdr (org-element-property :parent link))))
- (caption (caaar (plist-get parent :caption)))
- (name (plist-get parent :name)))
- (if caption
- (format
- "[[elisp:(progn (switch-to-buffer \"%s\")(widen)(goto-char %s))][figure %s: %s]] %s\n"
- c-b start counter (or name "") caption)
- (format
- "[[elisp:(progn (switch-to-buffer \"%s\")(widen)(goto-char %s))][figure %s: %s]]\n"
- c-b start counter (or name "")))))))))
- (switch-to-buffer "*List of Figures*")
- (setq buffer-read-only nil)
- (org-mode)
- (erase-buffer)
- (insert (mapconcat 'identity list-of-figures ""))
- (setq buffer-read-only t)
- (use-local-map (copy-keymap org-mode-map))
- (local-set-key "q" #'(lambda () (interactive) (kill-buffer))))))
-
-(org-add-link-type
- "list-of-figures"
- 'org-ref-list-of-figures ; on click
- (lambda (keyword desc format)
- (cond
- ((eq format 'latex)
- (format "\\listoffigures")))))
-#+END_SRC
-
-** List of Tables
-
-#+BEGIN_SRC emacs-lisp :tangle org-ref.el
-(defun org-ref-list-of-tables (&optional arg)
- "Generate a buffer with a list of tables"
- (interactive)
- (save-excursion
- (widen)
- (let* ((c-b (buffer-name))
- (counter 0)
- (list-of-tables
- (org-element-map (org-element-parse-buffer 'element) 'table
- (lambda (table)
- "create a link for to the table"
- (incf counter)
- (let ((start (org-element-property :begin table))
- (name (org-element-property :name table))
- (caption (caaar (org-element-property :caption table))))
- (if caption
- (format
- "[[elisp:(progn (switch-to-buffer \"%s\")(widen)(goto-char %s))][table %s: %s]] %s\n"
- c-b start counter (or name "") caption)
- (format
- "[[elisp:(progn (switch-to-buffer \"%s\")(widen)(goto-char %s))][table %s: %s]]\n"
- c-b start counter (or name ""))))))))
- (switch-to-buffer "*List of Tables*")
- (setq buffer-read-only nil)
- (org-mode)
- (erase-buffer)
- (insert (mapconcat 'identity list-of-tables ""))
- (setq buffer-read-only t)
- (use-local-map (copy-keymap org-mode-map))
- (local-set-key "q" #'(lambda () (interactive) (kill-buffer))))))
-
-(org-add-link-type
- "list-of-tables"
- 'org-ref-list-of-tables
- (lambda (keyword desc format)
- (cond
- ((eq format 'latex)
- (format "\\listoftables")))))
-#+END_SRC
-** label
-
-The label link provides a way to create labels in org-mode. We make it clickable because we want to make sure labels are unique. This code will tell you how many instances of a label are found. We search for label links, LaTeX labels, and the org-mode format for labels. We probably should search for tblnames too.
-*************** TODO search tblnames, custom_ids and check for case sensitivity
-*************** END
-
-#+BEGIN_SRC emacs-lisp :tangle org-ref.el
-(org-add-link-type
- "label"
- (lambda (label)
- "on clicking count the number of label tags used in the buffer. A number greater than one means multiple labels!"
- (message (format "%s occurences"
- (+ (count-matches (format "label:%s\\b[^-:]" label) (point-min) (point-max) t)
- ;; for tblname, it is not enough to get word boundary
- ;; tab-little and tab-little-2 match then.
- (count-matches (format "^#\\+tblname:\\s-*%s\\b[^-:]" label) (point-min) (point-max) t)
- (count-matches (format "\\label{%s}\\b" label) (point-min) (point-max) t)
- ;; this is the org-format #+label:
- (count-matches (format "^#\\+label:\\s-*%s\\b[^-:]" label) (point-min) (point-max) t)))))
- (lambda (keyword desc format)
- (cond
- ((eq format 'html) (format "(<label>%s</label>)" path))
- ((eq format 'latex)
- (format "\\label{%s}" keyword)))))
-#+END_SRC