13

Fast generation of graphs from a tree-like structure can be very useful when making notes in org-mode that require sharing and or beautification for other humans.

I couldn't find any way to do this other than to manually create a dynamic dot/graphviz block.

A translation from a structured tree to a simple directed graph should be fairly straightforward.

I'm looking for a simple way to traverse an org-mode tree (a selected region) and to translate the tree structure (and optionally some information from the contents of the structure) to a dot graph.

I can't possibly be the first to have come up with this. Has this been solved?

input

* la1
** la2
*** la3
*** la4
** la5

and perhaps a variable org-to-dot-preamble

digraph {
   rankdir=TB;
   splines=true;
   node [shape=box];

the output would look like an org-mode dynamic block

#+BEGIN_SRC dot :file out.png :cmdline -Kdot -Tpng
(contents of org-to-dot-preamble)

la1 -> la2
la1 -> la5
la2 -> la3
la2 -> la4
}
#+END_SRC

A more advanced version would first declare all the nodes and allow for some formatting.

input

* la1
  firstline
  secondline
** la2
   firstline
   secondline
*** la3
*** la4
    firstline
** la5

Some formatting variables

org-to-dot-shape
org-to-dot-font

output

#+BEGIN_SRC dot :file out.png :cmdline -Kdot -Tpng
(contents of org-to-dot-preamble)

la1 [shape=Mrecord, label="{firstline|secondline}", fontname = "helvetica"]
la2 [shape=Mrecord, label="{firstline|secondline}", fontname = "helvetica"]
la3 [shape=Mrecord, label="{firstline|secondline}", fontname = "helvetica"]
la4 [shape=Mrecord, label="{firstline|secondline}", fontname = "helvetica"]
la5 [shape=Mrecord, label="{firstline|secondline}", fontname = "helvetica"]

la1 -> la2
la1 -> la5
la2 -> la3
la2 -> la4
}
#+END_SRC

screenshot from an org-mode buffer of the mocked-up result

3
  • Very interesting question! Would conversion code create a dot graph of another org-mode buffer or it's own buffer? Cool idea!
    – Melioratus
    Commented Nov 24, 2015 at 23:02
  • Yes it would be useful, sort of how TikZ renders in LaTeX documents.
    – Emacs User
    Commented Nov 25, 2015 at 3:41
  • @Melioratus: I was thinking just to use the selected region and to either place the resulting dot code in the kill ring or just insert it at point.
    – Werner
    Commented Nov 25, 2015 at 12:02

4 Answers 4

4

Here is a working example that uses org-element API to parse the buffer headings:

* la1
** la2
*** la3
*** la4
** la5
**  Org element API test

#+name: lista
#+begin_src elisp
  (org-element-map (org-element-parse-buffer 'headline )
      'headline
    (lambda(hl)
      (let ((parent (org-element-property :parent hl )))
        (and (eq (org-element-type parent) 'headline)
             (list (org-element-property :title parent) (org-element-property :title hl))))))

#+end_src

#+RESULTS: lista
| la1 | la2                  |
| la2 | la3                  |
| la2 | la4                  |
| la1 | la5                  |
| la1 | Org element API test |

#+name: make-dot
#+BEGIN_SRC emacs-lisp :var table=lista :results output :exports none
  (mapcar #'(lambda (x)
                (princ (format "\"%s\" -> \"%s\";\n" (first x) (second x))))
          table)
#+END_SRC

#+RESULTS: make-dot
: "la1" -> "la2";
: "la2" -> "la3";
: "la2" -> "la4";
: "la1" -> "la5";
: "la1" -> "Org element API test";

#+BEGIN_SRC dot :file dependencias.pdf :cmdline -Tpdf :var input=make-dot :exports results
digraph {
   rankdir=TB;
   splines=true;
   node [shape=box];
   $input
  }
#+END_SRC

#+CAPTION: Dependency diagram
#+RESULTS:
[[file:dependencias.pdf]]

This works in several steps: first an elisp block uses org-element-parse-buffer to get all headlines, and extract a list of parent's title and headline title.

Then another source block transforms this list into dot syntax.

A third dot source block contains the DOT wrapping and includes the generated relations.

Cosmetic enhancements: filter out the section for the test itself; you could add a tag to this section and filter out by tag in the first block.

1
  • Fantastic! This is great! Commented Nov 29, 2015 at 10:24
4

You might be able to reuse some of the code from the bottom of http://pages.sachachua.com/evil-plans/ . I basically use org-map-entries to go through my headings. Since I have a directed graph instead of a strict tree, I use simple regular expression searches to parse the link structure from human-friendly text. If you're just working with a tree, you can create your tree structure from the headings directly. After that, it's a matter of generating the appropriate graphviz syntax, and org-babel can handle producing that and converting it into a PNG or SVG. Hope that helps!

1
  • That's a great org file, and some nice graphs.
    – db48x
    Commented Nov 27, 2015 at 4:35
3

It's not dot, but if you're in a hurry, followings might be helpful.

We need org-plus-contrib and FreeMind.app to produce a mindmap from org-mode documents.

Install extra org-mode package called org-plus-contrib by M-x package-list-packages .

Perhaps we might need to add

(require 'ox-freemind)

to our .emacs.

Then we can export our org-mode file to Freemind *.mm file by C-c C-e f f, org-freemind-export-to-freemind .

Now we open *.mm from Freemind.app, and voila !

org-to-mm-mouse-over

Mouse over to see contents of the nodes.

1

UPDATE: 2019

There is a package called org-mind-map

https://github.com/theodorewiles/org-mind-map

It creates graphviz directed graphs from org-mode files using the dot language.

After installing org-mind-map you can export an org file C-c C-e and select "Create a graph & dot file" g d

This will create an dot file from your org file. It will contain some visual customizations from the org-mind-map package by default. You can edit these out or copy the relevant parts to a new dot file.

1
  • It does not work any more. The package is still on Melpa, but no updates in the last 3 years. ;-( Debugger entered--Lisp error: (void-function org-export-define-derived-backend) Commented Nov 8, 2020 at 3:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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