]> git.donarmstrong.com Git - lilypond.git/blob - scm/graphviz.scm
Merge branch 'hwn' of ssh+git://hanwen@git.sv.gnu.org/srv/git/lilypond
[lilypond.git] / scm / graphviz.scm
1 ;;;; graphviz.scm -- utilities for creating graphviz output
2 ;;;;
3 ;;;;  source file of the GNU LilyPond music typesetter
4 ;;;;
5 ;;;; (c) 2007 Joe Neeman <joeneeman@gmail.com>
6
7
8 (define-module (scm graphviz)
9   #:use-module (lily)
10   #:export
11   (make-graph add-node add-edge add-cluster
12               graph-write
13               ))
14
15 (define (make-graph filename)
16    #(() () () ()))
17
18
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))
24
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
29                                  (cdr cluster)
30                                  '())))
31     (vector-set! graph 3 (assq-set! cs
32                                     cluster-name
33                                     (cons node-id already-in-cluster)))))
34
35 (define (add-node graph label . cluster-name)
36   (let* ((ns (nodes graph))
37          (id (length ns)))
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)))
42     id))
43
44 (define (add-edge graph node1 node2)
45   (vector-set! graph 2 (cons `(,node1 . ,node2) (edges graph))))
46
47 (define (graph-write graph out)
48   (let ((ns (nodes graph))
49         (es (edges 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))
54          ns)
55     (map (lambda (e) (display (format "~a -> ~a\n" (car e) (cdr e)) out))
56          es)
57     (map (lambda (c)
58           (display (format "subgraph cluster_~a {\nlabel= \"~a\"\ncolor=blue\n"
59                            (string-filter (car c) char-alphabetic?)
60                            (car c))
61                    out)
62           (map (lambda (n) (display (format "~a\n" n) out)) (cdr c))
63           (display "}\n" out))
64          cs)
65     (display "}" out)))