1

I want to convert tree written in .org file to some XML code to generate graphic tree from it later (for example loading it to www.draw.io webpage).

tree example

In order to do this I need a bash script which will convert .org file containing:

* tree_root
** root_node_1
*** subnode
** root_node_2

to .xml file containing:

<mxCell id="b1" value="tree_root" > </mxCell>
<mxCell id="b2" value="root_node_1" ></mxCell>
    <mxCell id="a1" source="b2" target="b1">
<mxCell id="b3" value="subnode" ></mxCell>
    <mxCell id="a2" source="b3" target="b2">
<mxCell id="b4" value="root_node_2" ></mxCell>
    <mxCell id="a3" source="b4" target="b1">

In org mode headings are indicated by asterisks (* - first level heading, ** - second level heading, etc.)

Explanation:

  • Fields called id are names displayed in the boxes.
  • b1, b2, b3 stand for "box", names enumerated by line number in .org file,
  • a1, a2, a3 stand for "arrow" are the names enumerated by subsequent natural numbers,
  • source is id where arrow starts, target is id where the arrows points to.

I need some simple case, e.g. 6 levels deep max. I will extend it myself, but I need something to start with.

How to do this?

2
  • Can you say if there will be another heading at the "tree_root" level, and if so will there be 1 or 2 lines in the xml file associated with it? – icarus Nov 7 '18 at 16:09
  • This is not necessarily binary tree, and not necessarily rooted three. So you can have more than one or two nodes per level. Each one xml tag is for box or for arrow - one <></> for one box or one arrow. If this clarifies a little bit? – micholeodon Nov 7 '18 at 16:29
1

Maybe this will meet your requirements? Basic idea is to have an array (called labels) which holds what is effectively the line number of the last line starting with a particular number of stars. It will produce the wrong graph if you ever increase the number of stars by more than one, but handles decreases by any number correctly. Of course it doesn't handle text under the headings at all.

#!/bin/bash

typeset -a labels
typeset -i node=1

while read -r stars rest
do
    level=${#stars}
    labels[level]=$node
    printf '<mxCell id="b%d" value="%q" ></mxCell>\n' $node "$rest"
    case $level in
    (1) ;;
    (*) printf '    <mxCell id="a%d" source="b%d" target="b%d">\n' $((node-1)) $node ${labels[level-1]} ;;
    esac
    : $((node++))
done
1
  • Yes, this is exaclty what I was looking for ! Thank you very much. – micholeodon Nov 8 '18 at 10:36

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.