1 ;;;; graphviz.scm -- utilities for creating graphviz output
3 ;;;; source file of the GNU LilyPond music typesetter
5 ;;;; (c) 2007 Joe Neeman <joeneeman@gmail.com>
8 (define-module (scm graphviz)
11 (make-graph add-node add-edge add-cluster
15 (define (make-graph filename)
19 ;; fixme: use structs/records.
20 ;; fixme add & use setters.
21 (define (nodes g) (vector-ref g 1))
22 (define (edges g) (vector-ref g 2))
23 (define (clusters g) (vector-ref g 3))
25 (define (add-cluster graph node-id cluster-name)
26 (let* ((cs (clusters graph))
27 (cluster (assq cluster-name cs))
28 (already-in-cluster (if cluster
31 (vector-set! graph 3 (assq-set! cs
33 (cons node-id already-in-cluster)))))
35 (define (add-node graph label . cluster-name)
36 (let* ((ns (nodes graph))
38 (vector-set! graph 1 (cons `(,id . ,label) ns))
39 (if (and (not (null? cluster-name))
40 (string? (car cluster-name)))
41 (add-cluster graph id (car cluster-name)))
44 (define (add-edge graph node1 node2)
45 (vector-set! graph 2 (cons `(,node1 . ,node2) (edges graph))))
47 (define (graph-write graph out)
48 (let ((ns (nodes graph))
50 (cs (clusters graph)))
51 (ly:message (format (_ "Writing graph `~a'...") (port-filename out)))
52 (display "digraph G {\nrankdir=\"LR\"\nnode [shape=rectangle]\n" out)
53 (map (lambda (n) (display (format "~a [label=\"~a\"]\n" (car n) (cdr n)) out))
55 (map (lambda (e) (display (format "~a -> ~a\n" (car e) (cdr e)) out))
58 (display (format "subgraph cluster_~a {\nlabel= \"~a\"\ncolor=blue\n"
59 (string-filter (car c) char-alphabetic?)
62 (map (lambda (n) (display (format "~a\n" n) out)) (cdr c))