X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=scm%2Fgraphviz.scm;h=bc17f6185ebbfa79b8b8327504aba4dd345d6bcf;hb=5b4b0d6e9a197e8f9eb085b7c2ad78b8be3e5cfc;hp=d3a858fcef4fb6437578cf2f7f32bfcd6ed8a9b2;hpb=875b287f353888564d12882449447afcaabf097a;p=lilypond.git diff --git a/scm/graphviz.scm b/scm/graphviz.scm index d3a858fcef..bc17f6185e 100644 --- a/scm/graphviz.scm +++ b/scm/graphviz.scm @@ -1,35 +1,67 @@ +;;;; graphviz.scm -- utilities for creating graphviz output +;;;; +;;;; source file of the GNU LilyPond music typesetter +;;;; +;;;; (c) 2007--2008 Joe Neeman + + (define-module (scm graphviz) #:use-module (lily) - #:export (make-graph add-node add-edge)) + #:export + (make-empty-graph add-node add-edge add-cluster + graph-write + )) + +(define graph-type (make-record-type "graph" '(nodes edges clusters name))) + +(define make-graph (record-constructor graph-type)) +(define (make-empty-graph name) (make-graph '() '() '() name)) -(define (make-graph filename) - (let ((empty-graph (list->vector (list filename '() '() '())))) - (ly:atexit write-graph (list empty-graph)) - empty-graph)) +(define nodes (record-accessor graph-type 'nodes)) +(define edges (record-accessor graph-type 'edges)) +(define clusters (record-accessor graph-type 'clusters)) +(define set-nodes! (record-modifier graph-type 'nodes)) +(define set-edges! (record-modifier graph-type 'edges)) +(define set-clusters! (record-modifier graph-type 'clusters)) -(define (filename g) (vector-ref g 0)) -(define (nodes g) (vector-ref g 1)) -(define (edges g) (vector-ref g 2)) -(define (clusters g) (vector-ref g 3)) +(define (add-cluster graph node-id cluster-name) + (let* ((cs (clusters graph)) + (cluster (assq cluster-name cs)) + (already-in-cluster (if cluster + (cdr cluster) + '()))) + (set-clusters! graph (assq-set! cs + cluster-name + (cons node-id already-in-cluster))))) -(define (add-node graph label) - (let ((ns (nodes graph))) - (vector-set! graph 1 (cons `(,(length ns) . ,label) ns)) - (length ns))) +(define (add-node graph label . cluster-name) + (let* ((ns (nodes graph)) + (id (length ns))) + (set-nodes! graph (assq-set! ns id label)) + (if (and (not (null? cluster-name)) + (string? (car cluster-name))) + (add-cluster graph id (car cluster-name))) + id)) (define (add-edge graph node1 node2) - (vector-set! graph 2 (cons `(,node1 . ,node2) (edges graph)))) + (set-edges! graph (cons `(,node1 . ,node2) (edges graph)))) -(define (write-graph graph) - (let ((out (open-file (filename graph) "w")) - (ns (nodes graph)) +(define (graph-write graph out) + (let ((ns (nodes graph)) (es (edges graph)) - (cc (clusters graph))) - (ly:message (format "writing graph ~s..." (filename graph))) + (cs (clusters graph))) + (ly:message (format (_ "Writing graph `~a'...") (port-filename out))) (display "digraph G {\nrankdir=\"LR\"\nnode [shape=rectangle]\n" out) (map (lambda (n) (display (format "~a [label=\"~a\"]\n" (car n) (cdr n)) out)) ns) (map (lambda (e) (display (format "~a -> ~a\n" (car e) (cdr e)) out)) es) + (map (lambda (c) + (display (format "subgraph cluster_~a {\nlabel= \"~a\"\ncolor=blue\n" + (string-filter (car c) char-alphabetic?) + (car c)) + out) + (map (lambda (n) (display (format "~a\n" n) out)) (cdr c)) + (display "}\n" out)) + cs) (display "}" out))) - \ No newline at end of file