daveray / dorothy

Hiccup-style generation of Graphviz graphs in Clojure
246 stars 25 forks source link

dorothy produces dot files that at least several recent Graphviz versions cannot parse for particular attribute values #18

Open jafingerhut opened 3 years ago

jafingerhut commented 3 years ago

In particular, when a node or edge label is a string value like "node" or "edge", and perhaps other strings that seem to be some kind of reserved keywords in the dot language, as of Dorothy version 0.7 it generates dot files where those attribute values do not have double quotes surrounding them, and several versions of Graphviz's dot command give an error when trying to read such a file.

Here are fairly short steps to reproduce:

(require '[dorothy.core :as d])

(def dorothy-digraph-args
  '({}
    ({:layout :dot}
     [:a {}]
     [:b {}]
     [:a :b {:label "node"}])))

(def x1 (d/digraph dorothy-digraph-args))
(def x2 (d/dot x1))
(spit "simple.dot" x2)
$ cat simple.dot
digraph {
graph [];
graph [layout=dot];
a;
b;
a -> b [label=node];
} 

Then in a terminal on an Ubuntu 18.04 Linux system with this version of dot installed, dot gives an error while attempting to parse that file:

$ dot -V
dot - graphviz version 2.40.1 (20161225.0304)
$ dot -Tpdf simple.dot > simple.pdf
Error: simple.dot: syntax error in line 6 near 'node'

Similarly on an Ubuntu 20.04 Linux system with this version of dot installed:

$ dot -V
dot - graphviz version 2.43.0 (0)
$ dot -Tpdf simple.dot > simple.pdf
Error: simple.dot: syntax error in line 6 near 'node'

Similarly on a macOS 10.14.6 system with this version of dot installed:

$ dot -V
dot - graphviz version 2.44.1 (20200629.0846)
$ dot -Tpdf simple.dot > simple.pdf
Error: simple.dot: syntax error in line 6 near 'node'

On all three system + Graphviz versions mentioned above, editing the file simple.dot to the following, adding double quotes around the values of all attributes, enabled dot to correctly parse the file and produce the desired drawing:

$ cat simple2.dot
digraph {
graph [];
graph [layout="dot"];
a;
b;
a -> b [label="node"];
}