1 ! Copyright (C) 2012 Alex Vondrak.
2 ! See https://factorcode.org/license.txt for BSD license.
3 USING: accessors classes classes.tuple combinators formatting graphviz
4 graphviz.attributes io io.files kernel namespaces sequences splitting
10 GENERIC: dot. ( obj -- )
12 ! Graphviz docs claim that there's no semantic difference
13 ! between quoted & unquoted IDs, but quoting them is the safest
14 ! option in case there's a keyword clash, spaces in the ID,
15 ! etc. This does mean that HTML labels aren't supported, but
16 ! they don't seem to work using the Graphviz API anyway.
18 ! Special escaping logic is required here because of the \l escape
20 : quote-string ( str -- str' )
21 { { "\"" "\\\"" } { "\0" "" } } [ first2 replace ] each
24 M: string dot. quote-string "%s " printf ;
26 : id. ( obj -- ) id>> dot. ;
29 "{" print [ dot. ";" print ] each "}" print ;
31 : statements. ( sub/graph -- ) statements>> dot. ;
35 : with-edgeop ( graph quot -- )
37 dup directed?>> "-> " "-- " ? edgeop
38 ] dip with-variable ; inline
40 : ?strict ( graph -- graph )
41 dup strict?>> [ "strict " write ] when ;
43 : (di)graph ( graph -- graph )
44 dup directed?>> "digraph " "graph " ? write ;
47 ?strict (di)graph dup id. [ statements. ] with-edgeop ;
50 "subgraph " write [ id. ] [ statements. ] bi ;
52 : attribute, ( attr value -- )
53 [ quote-string "%s=%s," printf ] [ drop ] if* ;
55 : attributes. ( attrs -- )
57 [ class-of "slots" word-prop ] [ tuple-slots ] bi
58 [ [ name>> ] dip attribute, ] 2each
61 M: graph-attributes dot. "graph" write attributes. ;
62 M: node-attributes dot. "node" write attributes. ;
63 M: edge-attributes dot. "edge" write attributes. ;
66 [ id. ] [ attributes>> attributes. ] bi ;
71 [ drop edgeop get write ]
73 [ attributes>> attributes. ]
78 : write-dot ( graph path encoding -- )
79 [ dot. ] with-file-writer ;