I have this file structure:

├── main.org
└── part1
    ├── img/
    └── part.org


* Main file
** Part 1


#+begin_src gnuplot :exports none :results file :file ./img/fig1.png
plot x**2

#+name: fig1
#+caption: Plot

I want to be able to export to latex both main.org and part.org (basically what org-thesis does) and also to generate figures only in their respective part*/img/ folder.

The problem is: when I export main.org org-mode changes [[./img/fig1.png]] to [[part1/img/fig1.png]] but ignores :file ./img/fig1.png.

If I create img/ on the same level as main.org then org-mode correctly generates figures in that folder (but tries to use those in part1/img/).

So is there a way for :file filename to have the same behaviour as [[filename]]?


You might be able to achieve what you want within Org mode (one can never discount the ability of Org mode to solve problems like this!). But it might be simpler to use external facilities.

My suggestion would be to add an img/ directory at the main level, and then add symbolic links to all the image files. main.org would access them as ./img/figN.png through the symbolic links, whereas each part would access its figures using the same name, ./img/figN.png, but as the actual file. The structure would look like this:

|-- img
|   |-- fig1.png -> ../part1/img/fig1.png
|   `-- fig2.png -> ../part2/img/fig2.png
|-- part1
|   |-- img
|   |   `-- fig1.png
|   `-- part1.org
|-- part2
|   |-- img
|   |   `-- fig2.png
|   `-- part2.org
`-- main.org

The symbolic links in the top img/ directory can be created in bulk with a command like this:

 find ./*/img -type f -name '*.png' | xargs bash -c 'ln -sf "${@/./..}" ./img' link

executed at the top level of the tree (the same level as main.org). N.B. This command will NOT work if the pathnames contain spaces (i.e. no part 1 or fig 2.png allowed); it's probably possible to deal with that limitation but it's left as an exercise for the interested reader (adding -print0 to the find command and -r0 to the xargs command is NOT enough).

The pieces of the command can be understood as follows:

  • find ./*/img -type f -name '*.png' finds all the normal files (-type f) with names matching *.png in all the img/ subdirs one level down from the current directory (./*/img). It prints them out separated by spaces.
  • xargs bash -c 'ln -sf "${@/./..}" ./img' echo passes the accumulated pathnames to a shell which modifies each one by changing the initial ./ to an initial ../ (see the tree above for the necessity of this step) and then passes them all to a ln -sf ... ./img command which creates the symbolic links (-s), forcing the creation even if a link exists already (-f).

Hope this helps, even though it has nothing to do with emacs!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.