emacsincludeorg-modetransclusion

ISO transclusion in emacs org-mode


Q: is there any way to do transclusion in emacs org-mode?

By "transclusion", I mean stuff like, at some point in fileA.org and fileB.org, "including" fileInc.org - and having the tree from fileInc.org appear in both places. Actually appear, not just be linked to. (Possibly with conditional inclusion, transformation, e.g. nesting depth (number of ***s)).

I know about #setupfile, but that seems only to work for modes, not real text.

I know about http://orgmode.org/manual/Include-files.html, but AFAIK they only work at export time.

I am looking for something that works in a normal emacs org-mode buffer. (Actually, something that worked in non-org-mode buffers might be nice.)

I have boiler plate that I want to include in multiple files.

Does something like this exist?


Solution

  • Hmm... I don't think anything like this exists, but it was easy enough to write a dynamic block to do this. The following elisp works for me:

    (defun org-dblock-write:transclusion (params)
      (progn
        (with-temp-buffer
          (insert-file-contents (plist-get params :filename))
          (let ((range-start (or (plist-get params :min) (line-number-at-pos (point-min))))
                (range-end (or (plist-get params :max) (line-number-at-pos (point-max)))))
            (copy-region-as-kill (line-beginning-position range-start)
                                 (line-end-position range-end))))
        (yank)))
    

    Then to include a line range from a given file, you can create a dynamic block like so:

     #+BEGIN: transclusion :filename "~/testfile.org" :min 2 :max 4
     #+END:
    

    And auto-populate with C-c C-x C-u. Skip the min and max args to include the entire file. Note that you can bind org-update-all-dblocks to a hook, so that this range is updated whenever you visit the file or save.

    More info on dynamic blocks at http://orgmode.org/org.html#Dynamic-blocks. Hope this helps!