-** open url in browser from bibtex
-
-We bind this to a key here [[*key%20bindings%20for%20utilities][key bindings for utilities]].
-
-+ This function may be duplicative of bibtex-url. But I think my function is better unless you do some complicated customization of bibtex-generate-url-list.
-
-#+BEGIN_SRC emacs-lisp :tangle org-ref.el
-(defun org-ref-open-in-browser ()
- "Open the bibtex entry at point in a browser using the url field or doi field"
-(interactive)
-(save-excursion
- (bibtex-beginning-of-entry)
- (catch 'done
- (let ((url (bibtex-autokey-get-field "url")))
- (when url
- (browse-url url)
- (throw 'done nil)))
-
- (let ((doi (bibtex-autokey-get-field "doi")))
- (when doi
- (if (string-match "^http" doi)
- (browse-url doi)
- (browse-url (format "http://dx.doi.org/%s" doi)))
- (throw 'done nil)))
- (message "No url or doi found"))))
-#+END_SRC
-
-** citeulike
- I discovered you could upload a bibtex entry to citeulike using http requests. The upload is actually done by a [[*The%20upload%20script][python script]], because it was easy to write. Here is the emacs command to do this. It is not a fast operation, and do not use it frequently.
-
-*** function to upload bibtex to citeulike
-
-#+BEGIN_SRC emacs-lisp :tangle org-ref.el
-(defun org-ref-upload-bibtex-entry-to-citeulike ()
- "with point in a bibtex entry get bibtex string and submit to citeulike.
-
-Relies on the python script /upload_bibtex_citeulike.py being in the user directory."
- (interactive)
- (message "uploading to citeulike")
- (save-restriction
- (bibtex-narrow-to-entry)
- (let ((startpos (point-min))
- (endpos (point-max))
- (bibtex-string (buffer-string))
- (script (concat "python " starter-kit-dir "/upload_bibtex_citeulike.py&")))
- (with-temp-buffer (insert bibtex-string)
- (shell-command-on-region (point-min) (point-max) script t nil nil t)))))
-#+END_SRC
-
-*** The upload script
-Here is the python script for uploading.
-
-*************** TODO document how to get the cookies
-*************** END
-
-# :tangle upload_bibtex_citeulike.py
-#+BEGIN_SRC python
-#!python
-import pickle, requests, sys
-
-# reload cookies
-with open('c:/Users/jkitchin/Dropbox/blogofile-jkitchin.github.com/_blog/cookies.pckl', 'rb') as f:
- cookies = pickle.load(f)
-
-url = 'http://www.citeulike.org/profile/jkitchin/import_do'
-
-bibtex = sys.stdin.read()
-
-data = {'pasted':bibtex,
- 'to_read':2,
- 'tag_parsing':'simple',
- 'strip_brackets':'no',
- 'update_id':'bib-key',
- 'btn_bibtex':'Import BibTeX file ...'}
-
-headers = {'content-type': 'multipart/form-data',
- 'User-Agent':'jkitchin/johnrkitchin@gmail.com bibtexupload'}
-
-r = requests.post(url, headers=headers, data=data, cookies=cookies, files={})
-print r
-#+END_SRC
-
-** Build a pdf from a bibtex file
- It is useful to have a pdf version of an entire bibliography to check it for formatting, spelling, or to share it. This function creates a pdf from a bibtex file. I only include the packages I commonly use in my bitex files.
-
-#+BEGIN_SRC emacs-lisp :tangle org-ref.el
-(defun org-ref-build-full-bibliography ()
- "build pdf of all bibtex entries, and open it."
- (interactive)
- (let* ((bibfile (file-name-nondirectory (buffer-file-name)))
- (bib-base (file-name-sans-extension bibfile))
- (texfile (concat bib-base ".tex"))
- (pdffile (concat bib-base ".pdf")))
- (find-file texfile)
- (erase-buffer)
- (insert (format "\\documentclass[12pt]{article}
-\\usepackage[version=3]{mhchem}
-\\usepackage{url}
-\\usepackage[numbers]{natbib}
-\\usepackage[colorlinks=true, linkcolor=blue, urlcolor=blue, pdfstartview=FitH]{hyperref}
-\\usepackage{doi}
-\\begin{document}
-\\nocite{*}
-\\bibliographystyle{unsrtnat}
-\\bibliography{%s}
-\\end{document}" bib-base))
- (save-buffer)
- (shell-command (concat "pdflatex " bib-base))
- (shell-command (concat "bibtex " bib-base))
- (shell-command (concat "pdflatex " bib-base))
- (shell-command (concat "pdflatex " bib-base))
- (kill-buffer texfile)
- (org-open-file pdffile)
- ))
-#+END_SRC
-
-** Extract bibtex entries cited in an org-file
-When you use your default bibliography file, and you want to send an org-file to a collaborator, you may need to include bibtex entries so the other person can see them. This function does that and puts the entries in a section at the end of the document that can be tangled to a bib-file.
-
-#+BEGIN_SRC emacs-lisp :tangle org-ref.el
-(defun org-ref-extract-bibtex-entries ()
- "extract the bibtex entries referred to by cite links in the current buffer into a src block at the bottom of the current buffer.
-
-If no bibliography is in the buffer the `reftex-default-bibliography' is used."
- (interactive)
- (let* ((temporary-file-directory (file-name-directory (buffer-file-name)))
- (tempname (make-temp-file "extract-bib"))
- (contents (buffer-string))
- (cb (current-buffer))
- basename texfile bibfile results)
-
- ;; open tempfile and insert org-buffer contents
- (find-file tempname)
- (insert contents)
- (setq basename (file-name-sans-extension
- (file-name-nondirectory buffer-file-name))
- texfile (concat tempname ".tex")
- bibfile (concat tempname ".bib"))
-
- ;; see if we have a bibliography, and insert the default one if not.
- (save-excursion
- (goto-char (point-min))
- (unless (re-search-forward "^bibliography:" (point-max) 'end)
- (insert (format "\nbibliography:%s"
- (mapconcat 'identity reftex-default-bibliography ",")))))
- (save-buffer)
-
- ;; get a latex file and extract the references
- (org-latex-export-to-latex)
- (find-file texfile)
- (reftex-parse-all)
- (reftex-create-bibtex-file bibfile)
- (save-buffer)
- ;; save results of the references
- (setq results (buffer-string))
-
- ;; kill buffers. these are named by basename, not full path
- (kill-buffer (concat basename ".bib"))
- (kill-buffer (concat basename ".tex"))
- (kill-buffer basename)
-
- (delete-file bibfile)
- (delete-file texfile)
- (delete-file tempname)
-
- ;; Now back to the original org buffer and insert the results
- (switch-to-buffer cb)
- (when (not (string= "" results))
- (save-excursion
- (goto-char (point-max))
- (insert "\n\n")
- (org-insert-heading)
- (insert (format " Bibtex entries
-
-,#+BEGIN_SRC text :tangle %s
-%s
-,#+END_SRC" (concat (file-name-sans-extension (file-name-nondirectory (buffer-file-name))) ".bib") results))))))
-#+END_SRC
-
-** Find bad cite links
- :PROPERTIES:
- :ID: 8515E800-EDA0-4B2A-85FD-55B6FF849203
- :END:
-Depending on how you enter citations, you may have citations with no corresponding bibtex entry. This function finds them and gives you a clickable table to navigate to them.
-
-#+BEGIN_SRC emacs-lisp :tangle org-ref.el
-(require 'cl)
-
-(defun index (substring list)
- "return the index of string in a list of strings"
- (let ((i 0)
- (found nil))
- (dolist (arg list i)
- (if (string-match (concat "^" substring "$") arg)
- (progn
- (setq found t)
- (return i)))
- (setq i (+ i 1)))
- ;; return counter if found, otherwise return nil
- (if found i nil)))
-
-
-(defun org-ref-find-bad-citations ()
- "Create a list of citation keys in an org-file that do not have a bibtex entry in the known bibtex files.
-
-Makes a new buffer with clickable links."
- (interactive)
- ;; generate the list of bibtex-keys and cited keys
- (let* ((bibtex-files (org-ref-find-bibliography))
- (bibtex-file-path (mapconcat (lambda (x) (file-name-directory (file-truename x))) bibtex-files ":"))
- (bibtex-keys (mapcar (lambda (x) (car x)) (bibtex-global-key-alist)))
- (bad-citations '()))
-
- (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 (index key bibtex-keys))
- (message-box "%s" link)
- (setq
- bad-citations
- (append
- bad-citations
- `(,(format "%s [[elisp:(progn (switch-to-buffer-other-frame \"%s\")(goto-char %s))][not found here]]\n"
- key
- (buffer-name)
- (plist-get plist :begin)))))
- )))))
- ;; set with-affilates to t to get citations in a caption
- nil nil nil t)
-
- (if bad-citations
- (progn
- (switch-to-buffer-other-window "*Missing citations*")
- (org-mode)
- (erase-buffer)
- (insert "* List of bad cite links\n")
- (insert (mapconcat 'identity bad-citations ""))
- ;(setq buffer-read-only t)
- (use-local-map (copy-keymap org-mode-map))
- (local-set-key "q" #'(lambda () (interactive) (kill-buffer))))
-
- (when (get-buffer "*Missing citations*")
- (kill-buffer "*Missing citations*"))
- (message "No bad cite links found"))))
-#+END_SRC
-
-** helm interface to org-ref
-In [[id:8515E800-EDA0-4B2A-85FD-55B6FF849203][Find bad cite links]] we wrote a function that finds bad links and creates a buffer of links to them.
-
-Here we develop a similar idea, but instead of an org-buffer with links, we create helm sources for bad cite links, bad ref links, and multiple labels.
-
-#+BEGIN_SRC emacs-lisp :tangle org-ref.el
-(defun org-ref-bad-cite-candidates ()
- "Returns a list of conses (key . marker) where key does not exist in the known bibliography files, and marker points to the key."
- (let* ((cp (point)) ; save to return to later
- (bibtex-files (org-ref-find-bibliography))
- (bibtex-file-path (mapconcat
- (lambda (x)
- (file-name-directory (file-truename x)))
- bibtex-files ":"))
- (bibtex-keys (mapcar (lambda (x) (car x))
- (bibtex-global-key-alist)))
- (bad-citations '()))
-
- (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 (index key bibtex-keys))
- (goto-char (plist-get plist :begin))
- (re-search-forward key)
- (push (cons key (point-marker)) bad-citations)))
- )))
- ;; add with-affiliates to get cites in caption
- nil nil nil t)
- (goto-char cp)
- bad-citations))
-
-
-(defun org-ref-bad-ref-candidates ()
- "Returns a list of conses (ref . marker) where ref is a ref link that does not point to anything (i.e. a label)."
- ;; first get a list of legitimate labels
- (let ((cp (point))
- (labels (org-ref-get-labels))
- (bad-refs '()))
- ;; now loop over ref links
- (goto-char (point-min))
- (org-element-map (org-element-parse-buffer) 'link
- (lambda (link)
- (let ((plist (nth 1 link)))
- (when (or (equal (plist-get plist ':type) "ref")
- (equal (plist-get plist ':type) "eqref")
- (equal (plist-get plist ':type) "pageref")
- (equal (plist-get plist ':type) "nameref"))
- (unless (-contains? labels (plist-get plist :path))
- (goto-char (plist-get plist :begin))
- (add-to-list
- 'bad-refs
- (cons (plist-get plist :path)
- (point-marker))))))))
- (goto-char cp)
- bad-refs))
-
-
-(defun org-ref-bad-label-candidates ()
- "Return a list of labels where label is multiply defined."
- (let ((labels (org-ref-get-labels))
- (multiple-labels '()))
- (when (not (= (length labels)
- (length (-uniq labels))))
- (dolist (label labels)
- (when (> (-count (lambda (a)
- (equal a label))
- labels) 1)
- ;; this is a multiply defined label.
- (let ((cp (point)))
- (goto-char (point-min))
- (while (re-search-forward
- (format "[^#+]label:%s\\s-" label) nil t)
- (push (cons label (point-marker)) multiple-labels))
-
- (goto-char (point-min))
- (while (re-search-forward
- (format "\\label{%s}\\s-?" label) nil t)
- (push (cons label (point-marker)) multiple-labels))
-
- (goto-char (point-min))
- (while (re-search-forward
- (format "^#\\+label:\\s-*%s" label) nil t)
- (push (cons label (point-marker)) multiple-labels))
-
- (goto-char (point-min))
- (while (re-search-forward
- (format "^#\\+tblname:\\s-*%s" label) nil t)
- (push (cons label (point-marker)) multiple-labels))
- (goto-char cp)))))
- multiple-labels))