-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 org-mode format for labels, tblnames too.
-
-#+BEGIN_SRC emacs-lisp :tangle org-ref.el
-(defun org-ref-count-labels (label)
- "Counts number of matches for label in the document"
- (+ (count-matches (format "label:%s\\b[^-:]" label) (point-min) (point-max))
- ;; 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))
- (count-matches (format "\\label{%s}" label) (point-min) (point-max))
- ;; this is the org-format #+label:
- (count-matches (format "^#\\+label:\\s-*%s\\b[^-:]" label) (point-min) (point-max))
- (let ((custom-id-count 0))
- (org-map-entries
- (lambda ()
- (when (string= label (org-entry-get (point) "CUSTOM_ID"))
- (setq custom-id-count (+ 1 custom-id-count)))))
- custom-id-count)))
-
-(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!"
- (let ((count (org-ref-count-labels label)))
- (message (format "%s occurence%s"
- count
- (if (or (= count 0)
- (> count 1))
- "s"
- ""))
- (org-ref-count-labels label))))
- (lambda (keyword desc format)
- (cond
- ((eq format 'html) (format "(<label>%s</label>)" path))
- ((eq format 'latex)
- (format "\\label{%s}" keyword)))))
-#+END_SRC