Features Tree
Presentation
Features Tree is a small utility for linguists and especially conlangers that allows them to declare trees with any number of children per node. I especially made it with the option in mind to make feature contrastive trees as presentented by Joseph Windsor in his talk during the Language Creation Conference 8, with examples below.
   
   
Usage
TL;DR
In your *NIX terminal, clone the project, edit the example trees or create a new one, and execute this:
  cd features-tree
  chicken-csc features-tree.scm             # Compile the .scm file
  ./features-tree | dot -Tpng -o output.png # for PNG output
  ./features-tree | dot -Tsvg -o output.svg # for SVG output
More details
For now, the workflow is not the best, as you have to edit yourself the source code and re-compile it each time you edit your own tree.
You will have to declare a Scheme list containing your tree, and your typical node should be declared like so:
  ("text" (child1) (child2) ...)
Each child is itself a tree that should follow the same type of declaration, with as many child as you like per node –I discourage you to have more than nine children though, otherwise it might break the output. If a node does not have any child, it should be declared like so:
  ("text")
As an example, here is the tree that was used to declare the first example image:
  (define vowels
    '("[vowel]"
      ("[back]"
       ("[tense]"
        ("[high]" ("ü"))
        ("{high}" ("ö")))
       ("{tense}"
        ("[high]" ("u"))
        ("{high}" ("o"))))
      ("{back}"
       ("[tense]"
        ("[high]" ("y"))
        ("{high}" ("ë")))
       ("{tense}"
        ("[high]" ("i"))
        ("{high}" ("e"))))))
And here is the source code of the second example image:
  (define syntax-tree '("S"
      ("Obl")
      ("S'"
       ("NPerg"
        ("NP"))
       ("VP"
        ("NPdat"
         ("NP"))
        ("VP'"
         ("NPabs"
          ("NP"
           ("S")
           ("NP'"
            ("Adj")
            ("N"))))
         ("V'"
          ("Mood")
          ("Tense")
          ("V")
          ("Neg")))))))
    Once you’ve declared the  tree you want to get, modify the  last line of the
    source code (tree-to-dot  ...) by replacing the default  argument with the
    name   of   your   tree.    For   the   first   example,   we   would   call
    (tree-to-dot vowels),  while    for   the    second   we    would     call
    (tree-to-dot syntax-tree).
    Only one (tree-to-dot) call can be  done at once, else what follows might
    break!
    Once you’ve  done that, compile  your file! I  personally use Chicken  as my
    Scheme compiler, but if you already have another, you can use your own. Just
    replace my calls  to chicken-csc by your own compiler’s  command. Also, be
    aware that I use chicken-csc as  the command for che Chicken compiler, but
    if you also  use Chicken, you might  have to call csc  instead (this might
    mean you have an older version than the one I use).
Now that you’ve compiled your file, you will have to execute it. If your edits were alright, you should have some text output that looks like this, except that it will be way more compact.
  graph{
    node[shape=plaintext];
    graph[bgcolor="transparent"];
    0[label="[vowel]"];
    1[label="[back]"];
    0 -- 1;
    11[label="[tense]"];
    1 -- 11;
    111[label="[high]"];
    11 -- 111;
    1111[label="ü"];
    111 -- 1111;
    112[label="{high}"];
    11 -- 112;
    1121[label="ö"];
    112 -- 1121;
    12[label="{tense}"];
    1 -- 12;
    121[label="[high]"];
    12 -- 121;
    1211[label="u"];
    121 -- 1211;
    122[label="{high}"];
    12 -- 122;
    1221[label="o"];
    122 -- 1221;
    2[label="{back}"];
    0 -- 2;
    21[label="[tense]"];
    2 -- 21;
    211[label="[high]"];
    21 -- 211;
    2111[label="y"];
    211 -- 2111;
    212[label="{high}"];
    21 -- 212;
    2121[label="ë"];
    212 -- 2121;
    22[label="{tense}"];
    2 -- 22;
    221[label="[high]"];
    22 -- 221;
    2211[label="i"];
    221 -- 2211;
    222[label="{high}"];
    22 -- 222;
    2221[label="e"];
    222 -- 2221;
  }
If you get some errors, then you  fucked up somewhere in your tree, probably
    missing  some parenthesis  or you  forgot to  add the  ' before  the first
    parenthesis after the name of your tree. Go back to your source file and fix
    that. Also, it  might be easier to edit  the file if you have  a decent text
    editor, I’d  recommend using something along  the lines of VS  Code, Atom or
    Brackets,  or even  Emacs if  you  are not  afraid by  steep –but  extremely
    rewarding– learning curves.
Now, you need to have Graphviz’s dot tool installed to generate images. In your terminal, either redirect the output of your newly compiled program like so:
  ./features-tree | dot -Tpng -o output.png
Or simply copy  and paste the output  in a separate file, then  only run the
    dot part  of the above command.  You’ve got an output.png  file containing
    your tree now!
My elements are not aligned/centered, what do?
IDK, I’ve tried to look up the answer, but there was no trivial way to do it. If you found one, please tell me in a new issue, or even better, submit a PR!
How can I do that on Windows?
IDK. Get a UNIX terminal (like the Linux subsystem, Putty(?) or Cygwin) and apply what has been said before, maybe. If you have a better explanation, you are more than welcome to either send it with a new issue or a pull request.
License
Check out the /phundrak/features-tree/src/commit/9eccaba263c78e07f60813532af2b9da1400d359/LICENSE.org. TL;DR: a GPLv3 licence gives you the right to access, modify, and redistribute the source file at the condition it stays under the GPLv3 license, and if you somehow fuck up big time because of it (HOW?), you are responsible.