- ;; and finally if a key is specified, we modify the reftex menu
- (when key
- (setf (nth 2 (assoc 'org reftex-cite-format-builtin))
- (append (nth 2 (assoc 'org reftex-cite-format-builtin))
- `((,key . ,(concat type ":%l")))))))
-
-;; create all the link types and their completion functions
-(mapcar 'org-ref-define-citation-link org-ref-cite-types)
-#+END_SRC
-
-#+RESULTS:
-
-*** org-ref-insert-cite-link
-We need a convenient method to insert links. In reftex you use the keystroke C-c ], which gives you a minibuffer to search the bibtex files from. This function is bound to that same keystroke here [[*org-mode%20/%20reftex%20setup][org-mode / reftex setup]]. This function will append to a cite link if you call it while on a link.
-
-#+BEGIN_SRC emacs-lisp :tangle org-ref.el
-(defun org-ref-insert-cite-link (alternative-cite)
- "Insert a default citation link using reftex. If you are on a link, it
-appends to the end of the link, otherwise, a new link is
-inserted. Use a prefix arg to get a menu of citation types."
- (interactive "P")
- (org-ref-find-bibliography)
- (let* ((object (org-element-context))
- (link-string-beginning (org-element-property :begin object))
- (link-string-end (org-element-property :end object))
- (path (org-element-property :path object)))
-
- (if (not alternative-cite)
-
- (cond
- ;; case where we are in a link
- ((and (equal (org-element-type object) 'link)
- (-contains? org-ref-cite-types (org-element-property :type object)))
- (goto-char link-string-end)
- ;; sometimes there are spaces at the end of the link
- ;; this code moves point pack until no spaces are there
- (while (looking-back " ") (backward-char))
- (insert (concat "," (mapconcat 'identity (reftex-citation t ?a) ","))))
-
- ;; We are next to a link, and we want to append
- ((save-excursion
- (backward-char)
- (and (equal (org-element-type (org-element-context)) 'link)
- (-contains? org-ref-cite-types (org-element-property :type (org-element-context)))))
- (while (looking-back " ") (backward-char))
- (insert (concat "," (mapconcat 'identity (reftex-citation t ?a) ","))))
-
- ;; insert fresh link
- (t
- (insert
- (concat org-ref-default-citation-link
- ":"
- (mapconcat 'identity (reftex-citation t) ",")))))
-
- ;; you pressed a C-u so we run this code
- (reftex-citation))))
-#+END_SRC
-cite:zhou-2004-first-lda-u,paier-2006-errat,boes-2015-estim-bulk
-
-
-#+RESULTS:
-: org-ref-insert-cite-link
-
-*** Completion in cite links
-If you know the specific bibtex key, you may like to use completion directly. You use this with the org-mode machinery and tab completion. Here is the prototypical completion function. These are now all created when the links are created.
-
-#+BEGIN_SRC emacs-lisp :tangle no
-(defun org-cite-complete-link (&optional arg)
- "Completion function for cite links"
- (format "%s:%s"
- org-ref-default-citation-link
- (completing-read
- "bibtex key: "
- (let ((bibtex-files (org-ref-find-bibliography)))
- (bibtex-global-key-alist)))))
-#+END_SRC
-
-Alternatively, you may shortcut the org-machinery with this command. You will be prompted for a citation type, and then offered key completion.
-
-#+BEGIN_SRC emacs-lisp :tangle org-ref.el
-(defun org-ref-insert-cite-with-completion (type)
- "Insert a cite link with completion"
- (interactive (list (ido-completing-read "Type: " org-ref-cite-types)))
- (insert (funcall (intern (format "org-%s-complete-link" type)))))
-#+END_SRC
-
-** Storing links to a bibtex entry
-org-mode already defines a store link function for bibtex entries. It does not store the link I want though, it only stores a brief citation of the entry. I want a citation link. Here is a function to do that.
-
-#+BEGIN_SRC emacs-lisp :tangle org-ref.el
-(defun org-ref-store-bibtex-entry-link ()
- "Save a citation link to the current bibtex entry. Saves in the default link type."
- (interactive)
- (let ((link (concat org-ref-default-citation-link
- ":"
- (save-excursion
- (bibtex-beginning-of-entry)
- (reftex-get-bib-field "=key=" (bibtex-parse-entry))))))
- (message "saved %s" link)
- (push (list link) org-stored-links)
- (car org-stored-links)))
-#+END_SRC
-
-** Index entries
-org-ref minimally supports index entries. To make an index in a file, you should put in the LaTeX header these lines
-
-
-#+LATEX_HEADER: \usepackage{makeidx}
-#+LATEX_HEADER: \makeindex
-
-
-Finally, put \makeindex at the end of the document where you want the index to appear. You will need to run the makeindex program at an appropriate point in your LaTeX to pdf, or use ox-manuscript, which will do it for you.
-
-
-Use index links to create entries (see http://en.wikibooks.org/wiki/LaTeX/Indexing). Clicking on an index link runs occur on the buffer for the entry. The link exports to LaTeX. Some links may need to be enclosed in double brackets if they have spaces in them.
-
-
-index:hello
-index:hello!Peter
-[[index:hello!Sam@\textsl{Sam}]]
-[[index:Lin@\textbf{Lin}]]
-[[index:Joe|textit]]
-[[index:Lin@\textbf{Lin}]]
-[[index:Peter|see {hello}]]
-[[index:Jen|seealso{Jenny}]]
-
-index:encodings!input!cp850
-
-#+BEGIN_SRC emacs-lisp :tangle org-ref.el
-(org-add-link-type
- "index"
- (lambda (path)
- (occur path))
-
- (lambda (path desc format)
- (cond
- ((eq format 'latex)
- (format "\\index{%s}" path)))))
-
-;; this will generate a temporary index of entries in the file.
-(org-add-link-type
- "printindex"
- (lambda (path)
- (let ((*index-links* '())
- (*initial-letters* '()))
-
- ;; get links
- (org-element-map (org-element-parse-buffer) 'link
- (lambda (link)
- (let ((type (nth 0 link))
- (plist (nth 1 link)))
-
- (when (equal (plist-get plist ':type) "index")
- (add-to-list
- '*index-links*
- (cons (plist-get plist :path)
- (format
- "[[elisp:(progn (switch-to-buffer \"%s\") (goto-char %s))][%s]]"
-(current-buffer)
- (plist-get plist :begin) ;; position of link
- ;; grab a description
- (save-excursion
- (goto-char (plist-get plist :begin))
- (if (thing-at-point 'sentence)
- ;; get a sentence
- (replace-regexp-in-string
- "\n" "" (thing-at-point 'sentence))
- ;; or call it a link
- "link")))))))))
-
- ;; sort the links
- (setq *index-links* (cl-sort *index-links* 'string-lessp :key 'car))
-
- ;; now first letters
- (dolist (link *index-links*)
- (add-to-list '*initial-letters* (substring (car link) 0 1) t))
-
- ;; now create the index
- (switch-to-buffer (get-buffer-create "*index*"))
- (org-mode)
- (erase-buffer)
- (insert "#+TITLE: Index\n\n")
- (dolist (letter *initial-letters*)
- (insert (format "* %s\n" (upcase letter)))
- ;; now process the links
- (while (and
- ,*index-links*
- (string= letter (substring (car (car *index-links*)) 0 1)))
- (let ((link (pop *index-links*)))
- (insert (format "%s %s\n\n" (car link) (cdr link))))))
- (switch-to-buffer "*index*")))
- ;; formatting
- (lambda (path desc format)
- (cond
- ((eq format 'latex)
- (format "\\printindex")))))
-#+END_SRC
-
-#+RESULTS:
-| lambda | (path) | (let ((*index-links* (quote nil)) (*initial-letters* (quote nil))) (org-element-map (org-element-parse-buffer) (quote link) (lambda (link) (let ((type (nth 0 link)) (plist (nth 1 link))) (when (equal (plist-get plist (quote :type)) index) (add-to-list (quote *index-links*) (cons (plist-get plist :path) (format [[elisp:(progn (switch-to-buffer "%s") (goto-char %s))][%s]] (current-buffer) (plist-get plist :begin) (save-excursion (goto-char (plist-get plist :begin)) (if (thing-at-point (quote sentence)) (replace-regexp-in-string \n (thing-at-point (quote sentence))) link))))))))) (setq *index-links* (cl-sort *index-links* (quote string-lessp) :key (quote car))) (dolist (link *index-links*) (add-to-list (quote *initial-letters*) (substring (car link) 0 1) t)) (switch-to-buffer (get-buffer-create *index*)) (org-mode) (erase-buffer) (insert #+TITLE: Index\n\n) (dolist (letter *initial-letters*) (insert (format * %s\n (upcase letter))) (while (and *index-links* (string= letter (substring (car (car *index-links*)) 0 1))) (let ((link (pop *index-links*))) (insert (format %s %s\n\n (car link) (cdr link)))))) (switch-to-buffer *index*)) |
-| lambda | (path desc format) | (cond ((eq format (quote latex)) (format \printindex))) |
-
-** Glossary
-org-ref provides some minimal support for a glossary. See http://en.wikibooks.org/wiki/LaTeX/Glossary for details. You need to put these lines in the header.
-
-#+LATEX_HEADER: \usepackage{glossaries}
-#+LATEX_HEADER: \makeglossaries
-
-And at the end of the document put \makeglossaries.
-
-#+BEGIN_SRC emacs-lisp :tangle org-ref.el
-(org-add-link-type
- "newglossaryentry"
- nil ;; no follow action
- (lambda (path desc format)
- (cond
- ((eq format 'latex)
- (format "\\newglossaryentry{%s}{%s}" path desc)))))
-
-
-;; link to entry
-(org-add-link-type
- "gls"
- nil ;; no follow action
- (lambda (path desc format)
- (cond
- ((eq format 'latex)
- (format "\\gls{%s}" path)))))
-
-;; plural
-(org-add-link-type
- "glspl"
- nil ;; no follow action
- (lambda (path desc format)
- (cond
- ((eq format 'latex)
- (format "\\glspl{%s}" path)))))
-
-;; capitalized link
-(org-add-link-type
- "Gls"
- nil ;; no follow action
- (lambda (path desc format)
- (cond
- ((eq format 'latex)
- (format "\\Gls{%s}" path)))))
-
-;; capitalized link
-(org-add-link-type
- "Glspl"
- nil ;; no follow action
- (lambda (path desc format)
- (cond
- ((eq format 'latex)
- (format "\\Glspl{%s}" path)))))
-#+END_SRC
-
-* Utilities
-** create simple text citation from bibtex entry
-
-#+BEGIN_SRC emacs-lisp :tangle org-ref.el
-(defun org-ref-bib-citation ()
- "From a bibtex entry, create and return a simple citation string.
-This assumes you are in an article."
-
- (bibtex-beginning-of-entry)
- (let* ((cb (current-buffer))
- (bibtex-expand-strings t)
- (entry (loop for (key . value) in (bibtex-parse-entry t)
- collect (cons (downcase key) value)))
- (title (replace-regexp-in-string "\n\\|\t\\|\s+" " " (reftex-get-bib-field "title" entry)))
- (year (reftex-get-bib-field "year" entry))
- (author (replace-regexp-in-string "\n\\|\t\\|\s+" " " (reftex-get-bib-field "author" entry)))
- (key (reftex-get-bib-field "=key=" entry))
- (journal (reftex-get-bib-field "journal" entry))
- (volume (reftex-get-bib-field "volume" entry))
- (pages (reftex-get-bib-field "pages" entry))
- (doi (reftex-get-bib-field "doi" entry))
- (url (reftex-get-bib-field "url" entry))
- )
- ;;authors, "title", Journal, vol(iss):pages (year).
- (format "%s, \"%s\", %s, %s:%s (%s)"
- author title journal volume pages year)))
-#+END_SRC
-
-#+RESULTS:
-: org-ref-bib-citation
-
-
-#+BEGIN_SRC emacs-lisp :tangle org-ref.el
-(defun org-ref-bib-html-citation ()
- "from a bibtex entry, create and return a simple citation with html links."
-
- (bibtex-beginning-of-entry)
- (let* ((cb (current-buffer))
- (bibtex-expand-strings t)
- (entry (loop for (key . value) in (bibtex-parse-entry t)
- collect (cons (downcase key) value)))
- (title (replace-regexp-in-string "\n\\|\t\\|\s+" " " (reftex-get-bib-field "title" entry)))
- (year (reftex-get-bib-field "year" entry))
- (author (replace-regexp-in-string "\n\\|\t\\|\s+" " " (reftex-get-bib-field "author" entry)))
- (key (reftex-get-bib-field "=key=" entry))
- (journal (reftex-get-bib-field "journal" entry))
- (volume (reftex-get-bib-field "volume" entry))
- (pages (reftex-get-bib-field "pages" entry))
- (doi (reftex-get-bib-field "doi" entry))
- (url (reftex-get-bib-field "url" entry))
- )
- ;;authors, "title", Journal, vol(iss):pages (year).
- (concat (format "%s, \"%s\", %s, %s:%s (%s)."
- author title journal volume pages year)
- (when url (format " <a href=\"%s\">link</a>" url))
- (when doi (format " <a href=\"http://dx.doi.org/%s\">doi</a>" doi)))
- ))
-#+END_SRC
-
-** open pdf from bibtex
-We bind this to a key here: [[*key%20bindings%20for%20utilities][key bindings for utilities]].
-#+BEGIN_SRC emacs-lisp :tangle org-ref.el
-(defun org-ref-open-bibtex-pdf ()
- "open pdf for a bibtex entry, if it exists. assumes point is in
-the entry of interest in the bibfile. but does not check that."
- (interactive)
- (save-excursion
- (bibtex-beginning-of-entry)
- (let* ((bibtex-expand-strings t)
- (entry (bibtex-parse-entry t))
- (key (reftex-get-bib-field "=key=" entry))
- (pdf (format (concat org-ref-pdf-directory "%s.pdf") key)))
- (message "%s" pdf)
- (if (file-exists-p pdf)
- (org-open-link-from-string (format "[[file:%s]]" pdf))
- (ding)))))
-#+END_SRC
-
-** open notes from bibtex
-We bind this to a key here [[*key%20bindings%20for%20utilities][key bindings for utilities]].
-
-#+BEGIN_SRC emacs-lisp :tangle org-ref.el
-(defun org-ref-open-bibtex-notes ()
- "from a bibtex entry, open the notes if they exist, and create a heading if they do not.
-
-I never did figure out how to use reftex to make this happen
-non-interactively. the reftex-format-citation function did not
-work perfectly; there were carriage returns in the strings, and
-it did not put the key where it needed to be. so, below I replace
-the carriage returns and extra spaces with a single space and
-construct the heading by hand."
- (interactive)
-
- (bibtex-beginning-of-entry)
- (let* ((cb (current-buffer))
- (bibtex-expand-strings t)
- (entry (loop for (key . value) in (bibtex-parse-entry t)
- collect (cons (downcase key) value)))
- (title (replace-regexp-in-string "\n\\|\t\\|\s+" " " (reftex-get-bib-field "title" entry)))
- (year (reftex-get-bib-field "year" entry))
- (author (replace-regexp-in-string "\n\\|\t\\|\s+" " " (reftex-get-bib-field "author" entry)))
- (key (reftex-get-bib-field "=key=" entry))
- (journal (reftex-get-bib-field "journal" entry))
- (volume (reftex-get-bib-field "volume" entry))
- (pages (reftex-get-bib-field "pages" entry))
- (doi (reftex-get-bib-field "doi" entry))
- (url (reftex-get-bib-field "url" entry))
- )
-
- ;; save key to clipboard to make saving pdf later easier by pasting.
- (with-temp-buffer
- (insert key)
- (kill-ring-save (point-min) (point-max)))
-
- ;; 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))
- ;; put new entry in notes if we don't find it.
- (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:
- :Custom_ID: %s
- :AUTHOR: %s
- :JOURNAL: %s
- :YEAR: %s
- :VOLUME: %s
- :PAGES: %s
- :DOI: %s
- :URL: %s
- :END:
-[[cite:%s]] [[file:%s/%s.pdf][pdf]]\n\n"
-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]].
-
-+ 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