jkitchin / org-ref

org-mode modules for citations, cross-references, bibliographies in org-mode and useful bibtex tools to go with it.
GNU General Public License v3.0
1.36k stars 244 forks source link

Referencing images included from other files, or included by means of macros #550

Closed dangom closed 6 years ago

dangom commented 6 years ago

I'm writing an article with a somewhat large number of figures. The consequence is that my org-file looks somewhat distracting, an illustrated by the snippet below:

Proin neque massa, cursus ut, gravida ut, lobortis eget, lacus ref:image.
Cras placerat accumsan nulla.  

#+NAME: image
#+CAPTION: This is a very nice looking image
[[file:image.png]]

Curabitur vulputate vestibulum lorem.  
Proin quam nisl, tincidunt et, mattis eget, convallis nec, purus, ref:another-image.  

#+NAME: another-image
#+CAPTION: This is also a very nice looking image
[[file:another-image.png]]

To get rid of the visual pollution of org's boilerplate I thought of using macros to insert the images, as in:

#+MACRO: img (eval "#+NAME: $1\n#+CAPTION:$2\n[[file:$3]]")
Proin neque massa, cursus ut, gravida ut, lobortis eget, lacus ref:image.
Cras placerat accumsan nulla.  
{{{img(image, This is a very nice looking image, image.png)}}}

Curabitur vulputate vestibulum lorem.  
Proin quam nisl, tincidunt et, mattis eget, convallis nec, purus, ref:another-image.  
{{{img(another-image, This is a also a very nice looking image, another-image.png)}}}

Or alternatively, using includes:

Proin neque massa, cursus ut, gravida ut, lobortis eget, lacus ref:image.
Cras placerat accumsan nulla.  
#+INCLUDE: images.org::#image :only-contents t

Curabitur vulputate vestibulum lorem.  
Proin quam nisl, tincidunt et, mattis eget, convallis nec, purus, ref:another-image.  
#+INCLUDE: images.org::#another-image :only-contents t

Unfortunately, both of these solutions require me abandoning org-ref's "context" capabilities. What would be the recommended way to declutter an org-buffer without abandoning all the power of org-ref?

jagrg commented 6 years ago

You can add label to the CAPTION line and remove the NAME line. That would make 2 lines instead of 3 depending on the length of your captions. You can also hide the code inside a drawer. That would shrink the code to a single line when the drawer is folded.

On 26 Feb 2018, Daniel Gomez notifications@github.com wrote:

I'm writing an article with a somewhat large number of figures. The consequence is that my org-file looks somewhat distracting, an illustrated by the snippet below:

Proin neque massa, cursus ut, gravida ut, lobortis eget, lacus ref:image.
Cras placerat accumsan nulla.  

#+NAME: image
#+CAPTION: This is a very nice looking image
[[file:image.png]]

Curabitur vulputate vestibulum lorem.  
Proin quam nisl, tincidunt et, mattis eget, convallis nec, purus, ref:another-image.  

#+NAME: another-image
#+CAPTION: This is also a very nice looking image
[[file:another-image.png]]

To get rid of the visual pollution of org's boilerplate I thought of using macros to insert the images, as in:

#+MACRO: img (eval "#+NAME: $1\n#+CAPTION:$2\n[[file:$3]]")
Proin neque massa, cursus ut, gravida ut, lobortis eget, lacus ref:image.
Cras placerat accumsan nulla.  
{{{img(image, This is a very nice looking image, image.png)}}}

Curabitur vulputate vestibulum lorem.  
Proin quam nisl, tincidunt et, mattis eget, convallis nec, purus, ref:another-image.  
{{{img(another-image, This is a also a very nice looking image, another-image.png)}}}

Or alternatively, using includes:

Proin neque massa, cursus ut, gravida ut, lobortis eget, lacus ref:image.
Cras placerat accumsan nulla.  
#+INCLUDE: images.org::#image :only-contents t

Curabitur vulputate vestibulum lorem.  
Proin quam nisl, tincidunt et, mattis eget, convallis nec, purus, ref:another-image.  
#+INCLUDE: images.org::#another-image :only-contents t

Unfortunately, both of these solutions require me abandoning org-ref's "context" capabilities. What would be the recommended way to declutter an org-buffer without abandoning all the power of org-ref?

-- Jonathan Monthly Atmospheric CO₂: January 2018: 407.98, January 2017: 406.13

dangom commented 6 years ago

@jagrg Thanks for the suggestion. What would be the correct syntax to add a label to the caption line (and still have org-ref recognize it)?

jkitchin commented 6 years ago

I guess you will just be pushing the clutter around. One way might be using named results. That seems to work. The idea is to put the image text in a named src block, and put the results where you want them. strings in elisp self-evaluate, so on export you get the string where you want it, and the context labels from org-ref seem to still work.

Proin neque massa, cursus ut, gravida ut, lobortis eget, lacus ref:image.
Cras placerat accumsan nulla.

#+RESULTS: image

Curabitur vulputate vestibulum lorem.
Proin quam nisl, tincidunt et, mattis eget, convallis nec, purus, ref:another-image.

#+RESULTS: another-image

* images                                                           :noexport:

#+name: image
#+BEGIN_SRC emacs-lisp :results value raw :eval export
"#+NAME: image
,#+CAPTION: This is a very nice looking image
[[file:image.png]]"
#+END_SRC

#+name: another-image
#+BEGIN_SRC emacs-lisp :results value raw :eval export
"#+NAME: another-image
,#+CAPTION: This is also a very nice looking image
[[file:another-image.png]]"
#+END_SRC

More extreme would be to put overlays over the images to make them temporarily small, eg. only one line. Maybe something like:

(defvar *ov-decluttered* nil)

(defun ov-declutter (&optional clear)
  ""
  (interactive)
  (if *ov-decluttered*
      (remove-from-invisibility-spec '(decluttered . t)) 
    (let ((file-links (org-element-map (org-element-parse-buffer) 'link
            (lambda (link)
              (when (string= "file" (org-element-property :type link))
                link))))
      parent
      beg end ov)
      (loop for fl in file-links do
        (when (setq parent (org-element-property :parent fl))
          (setq end (org-element-property :end fl)
            beg (org-element-property :begin parent)
            ov (make-overlay beg end))
          (overlay-put ov 'invisible 'decluttered))) 
      (add-to-invisibility-spec '(decluttered . t))))
  (setq *ov-decluttered* (not *ov-decluttered*)))
jagrg commented 6 years ago

label:description :)

On 26 Feb 2018, Daniel Gomez notifications@github.com wrote:

@jagrg Thanks for the suggestion. What would be the correct syntax to add a label to the caption line (and still have org-ref recognize it)?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.*

-- Jonathan Monthly Atmospheric CO₂: January 2018: 407.98, January 2017: 406.13

jagrg commented 6 years ago

Both solutions are very nice. You might have to add :exports results to the first one.

On 26 Feb 2018, John Kitchin notifications@github.com wrote:

I guess you will just be pushing the clutter around. One way might be using named results. That seems to work. The idea is to put the image text in a named src block, and put the results where you want them. strings in elisp self-evaluate, so on export you get the string where you want it, and the context labels from org-ref seem to still work.

Proin neque massa, cursus ut, gravida ut, lobortis eget, lacus ref:image.
Cras placerat accumsan nulla.

#+RESULTS: image

Curabitur vulputate vestibulum lorem.
Proin quam nisl, tincidunt et, mattis eget, convallis nec, purus, ref:another-image.

#+RESULTS: another-image

* images                                                           :noexport:

#+name: image
#+BEGIN_SRC emacs-lisp :results value raw :eval export
"#+NAME: image
,#+CAPTION: This is a very nice looking image
[[file:image.png]]"
#+END_SRC

#+name: another-image
#+BEGIN_SRC emacs-lisp :results value raw :eval export
"#+NAME: another-image
,#+CAPTION: This is also a very nice looking image
[[file:another-image.png]]"
#+END_SRC

More extreme would be to put overlays over the images to make them temporarily small, eg. only one line. Maybe something like:

(defvar *ov-decluttered* nil)

(defun ov-declutter (&optional clear)
  ""
  (interactive)
  (if *ov-decluttered*
      (remove-from-invisibility-spec '(decluttered . t)) 
    (let ((file-links (org-element-map (org-element-parse-buffer) 'link
          (lambda (link)
            (when (string= "file" (org-element-property :type link))
              link))))
    parent
    beg end ov)
      (loop for fl in file-links do
      (when (setq parent (org-element-property :parent fl))
        (setq end (org-element-property :end fl)
          beg (org-element-property :begin parent)
          ov (make-overlay beg end))
        (overlay-put ov 'invisible 'decluttered))) 
      (add-to-invisibility-spec '(decluttered . t))))
  (setq *ov-decluttered* (not *ov-decluttered*)))

-- Jonathan Monthly Atmospheric CO₂: January 2018: 407.98, January 2017: 406.13

dangom commented 6 years ago

I tried all solutions and came to the conclusion that simple drawers are sufficient to declutter a buffer. As a bonus they startup folded and can be unfolded at will. Kind of like a selective decluttering -- and they play nice with pandoc.

Thanks for the quick help and suggestions =)