Getting a list of figures in an org-buffer
Posted March 02, 2014 at 10:03 AM | categories: org-mode | tags:
Updated March 03, 2014 at 02:50 PM
Similar to the previous example of getting a list of tables, here we examine getting a list of figures. Here are two figure links, one with a label, and one with a caption.
Figure 1: An equation of state. this is the caption of the figure.
Figure 2: another figure
We define a link that will parse the buffer, and create links in a new buffer to the figures. We define a figure as a link with a :type of "file" that has a path that points to a file ending with png or pdf. We will improve on the list of tables by making the buffer read-only, and making a local key binding to kill the buffer by pressing "q". Here is our attempted code.
;; http://www.emacswiki.org/emacs/ElispCookbook#toc4 (defun string/ends-with (s ending) "return non-nil if string S ends with ENDING." (cond ((>= (length s) (length ending)) (let ((elength (length ending))) (string= (substring s (- 0 elength)) ending))) (t nil))) (org-add-link-type "list-of-figures" (lambda (link-string) (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\\)$" (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\")(goto-char %s))][figure %s: %s]] %s\n" c-b start counter (or name "") caption) (format "[[elisp:(progn (switch-to-buffer \"%s\")(goto-char %s))][figure %s: %s]]\n" c-b start counter (or name ""))))))))) (switch-to-buffer "*List of Figures*") (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))))) (lambda (keyword desc format) (cond ((eq format 'latex) (format "\\listoffigures")))))
This is a test to see if our function works for other image types. smiley.jpg
And a link to test it out:
This works too. I am not sure I am getting the figure name and caption in a bulletproof way. They seem to be buried in the :parent of the element, which is a paragraph element. The caption seems to be buried in a few sets of parentheses, hence the use of caaar
to get the caption out. I am not sure if the caption is always at that depth or not. As a proof of concept though, this is not too bad.
Copyright (C) 2014 by John Kitchin. See the License for information about copying.
Org-mode version = 8.2.5h