]> git.donarmstrong.com Git - lilypond.git/blob - scm/graphviz.scm
Merge branch 'master' into translation
[lilypond.git] / scm / graphviz.scm
1 ;;;; This file is part of LilyPond, the GNU music typesetter.
2 ;;;;
3 ;;;; Copyright (C) 2007--2012 Joe Neeman <joeneeman@gmail.com>
4 ;;;;
5 ;;;; LilyPond is free software: you can redistribute it and/or modify
6 ;;;; it under the terms of the GNU General Public License as published by
7 ;;;; the Free Software Foundation, either version 3 of the License, or
8 ;;;; (at your option) any later version.
9 ;;;;
10 ;;;; LilyPond is distributed in the hope that it will be useful,
11 ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 ;;;; GNU General Public License for more details.
14 ;;;;
15 ;;;; You should have received a copy of the GNU General Public License
16 ;;;; along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
17
18
19 (define-module (scm graphviz)
20   #:use-module (lily)
21   #:export
22   (make-empty-graph add-node add-edge add-cluster
23                     graph-write
24                     ))
25
26 (define graph-type (make-record-type "graph" '(nodes edges clusters name)))
27
28 (define make-graph (record-constructor graph-type))
29 (define (make-empty-graph name) (make-graph '() '() '() name))
30
31 (define nodes (record-accessor graph-type 'nodes))
32 (define edges (record-accessor graph-type 'edges))
33 (define clusters (record-accessor graph-type 'clusters))
34 (define set-nodes! (record-modifier graph-type 'nodes))
35 (define set-edges! (record-modifier graph-type 'edges))
36 (define set-clusters! (record-modifier graph-type 'clusters))
37
38 (define (add-cluster graph node-id cluster-name)
39   (let* ((cs (clusters graph))
40          (cluster (assoc cluster-name cs))
41          (already-in-cluster (if cluster
42                                  (cdr cluster)
43                                  '())))
44     (set-clusters! graph (assoc-set! cs
45                                      cluster-name
46                                      (cons node-id already-in-cluster)))))
47
48 (define (add-node graph label . cluster-name)
49   (let* ((ns (nodes graph))
50          (id (length ns)))
51     (set-nodes! graph (assv-set! ns id label))
52     (if (and (not (null? cluster-name))
53              (string? (car cluster-name)))
54         (add-cluster graph id (car cluster-name)))
55     id))
56
57 (define (add-edge graph node1 node2)
58   (set-edges! graph (cons `(,node1 . ,node2) (edges graph))))
59
60 (define (graph-write graph out)
61   (let ((ns (nodes graph))
62         (es (edges graph))
63         (cs (clusters graph)))
64     (ly:message (format #f (_ "Writing graph `~a'...") (port-filename out)))
65     (display "digraph G {\nrankdir=\"LR\"\nnode [shape=rectangle]\n" out)
66     (for-each (lambda (n) (format out "~a [label=\"~a\"]\n" (car n) (cdr n)))
67               ns)
68     (for-each (lambda (e) (format out "~a -> ~a\n" (car e) (cdr e)))
69               es)
70     (for-each (lambda (c)
71                 (format out "subgraph cluster_~a {\nlabel= \"~a\"\ncolor=blue\n"
72                         (string-filter (car c) char-alphabetic?)
73                         (car c))
74                 (for-each (lambda (n) (format out "~a\n" n)) (cdr c))
75                 (display "}\n" out))
76               cs)
77     (display "}" out)))