Fix up Rubinius specific library specs.
[rbx.git] / lib / rdoc / dot.rb
blobfbd2cfba0205040ac4855b3a6b0606122875b560
1 module RDoc; end
3 module RDoc::DOT
5   TAB = '  '
6   TAB2 = TAB * 2
8   # options for node declaration
9   NODE_OPTS = [
10     'bgcolor',
11     'color',
12     'fontcolor',
13     'fontname',
14     'fontsize',
15     'height',
16     'width',
17     'label',
18     'layer',
19     'rank',
20     'shape',
21     'shapefile',
22     'style',
23     'URL',
24   ]
26   # options for edge declaration
27   EDGE_OPTS = [
28     'color',
29     'decorate',
30     'dir',
31     'fontcolor',
32     'fontname',
33     'fontsize',
34     'id',
35     'label',
36     'layer',
37     'lhead',
38     'ltail',
39     'minlen',
40     'style',
41     'weight'
42   ]
44   # options for graph declaration
45   GRAPH_OPTS = [
46     'bgcolor',
47     'center',
48     'clusterrank',
49     'color',
50     'compound',
51     'concentrate',
52     'fillcolor',
53     'fontcolor',
54     'fontname',
55     'fontsize',
56     'label',
57     'layerseq',
58     'margin',
59     'mclimit',
60     'nodesep',
61     'nslimit',
62     'ordering',
63     'orientation',
64     'page',
65     'rank',
66     'rankdir',
67     'ranksep',
68     'ratio',
69     'size',
70     'style',
71     'URL'
72   ]
74   # a root class for any element in dot notation
75   class SimpleElement
76     attr_accessor :name
78     def initialize( params = {} )
79       @label = params['name'] ? params['name'] : ''
80     end
82     def to_s
83       @name
84     end
85   end
87   # an element that has options ( node, edge or graph )
88   class Element < SimpleElement
89     #attr_reader :parent
90     attr_accessor :name, :options
92     def initialize( params = {}, option_list = [] )
93       super( params )
94       @name = params['name'] ? params['name'] : nil
95       @parent = params['parent'] ? params['parent'] : nil
96       @options = {}
97       option_list.each{ |i|
98         @options[i] = params[i] if params[i]
99       }
100       @options['label'] ||= @name if @name != 'node'
101     end
103     def each_option
104       @options.each{ |i| yield i }
105     end
107     def each_option_pair
108       @options.each_pair{ |key, val| yield key, val }
109     end
111     #def parent=( thing )
112     #    @parent.delete( self ) if defined?( @parent ) and @parent
113     #    @parent = thing
114     #end
115   end
118   # this is used when we build nodes that have shape=record
119   # ports don't have options :)
120   class Port < SimpleElement
121     attr_accessor :label
123     def initialize( params = {} )
124       super( params )
125       @name = params['label'] ? params['label'] : ''
126     end
127     def to_s
128       ( @name && @name != "" ? "<#{@name}>" : "" ) + "#{@label}"
129     end
130   end
132   # node element
133   class Node < Element
135     def initialize( params = {}, option_list = NODE_OPTS )
136       super( params, option_list )
137       @ports = params['ports'] ? params['ports'] : []
138     end
140     def each_port
141       @ports.each{ |i| yield i }
142     end
144     def << ( thing )
145       @ports << thing
146     end
148     def push ( thing )
149       @ports.push( thing )
150     end
152     def pop
153       @ports.pop
154     end
156     def to_s( t = '' )
158       label = @options['shape'] != 'record' && @ports.length == 0 ?
159         @options['label'] ?
160         t + TAB + "label = \"#{@options['label']}\"\n" :
161                     '' :
162                     t + TAB + 'label = "' + " \\\n" +
163                     t + TAB2 + "#{@options['label']}| \\\n" +
164                     @ports.collect{ |i|
165         t + TAB2 + i.to_s
166       }.join( "| \\\n" ) + " \\\n" +
167         t + TAB + '"' + "\n"
169         t + "#{@name} [\n" +
170         @options.to_a.collect{ |i|
171         i[1] && i[0] != 'label' ?
172           t + TAB + "#{i[0]} = #{i[1]}" : nil
173       }.compact.join( ",\n" ) + ( label != '' ? ",\n" : "\n" ) +
174         label +
175         t + "]\n"
176     end
177   end
179   # subgraph element is the same to graph, but has another header in dot
180   # notation
181   class Subgraph < Element
183     def initialize( params = {}, option_list = GRAPH_OPTS )
184       super( params, option_list )
185       @nodes = params['nodes'] ? params['nodes'] : []
186       @dot_string = 'subgraph'
187     end
189     def each_node
190       @nodes.each{ |i| yield i }
191     end
193     def << ( thing )
194       @nodes << thing
195     end
197     def push( thing )
198       @nodes.push( thing )
199     end
201     def pop
202       @nodes.pop
203     end
205     def to_s( t = '' )
206       hdr = t + "#{@dot_string} #{@name} {\n"
208       options = @options.to_a.collect{ |name, val|
209         val && name != 'label' ?
210           t + TAB + "#{name} = #{val}" :
211         name ? t + TAB + "#{name} = \"#{val}\"" : nil
212       }.compact.join( "\n" ) + "\n"
214       nodes = @nodes.collect{ |i|
215         i.to_s( t + TAB )
216       }.join( "\n" ) + "\n"
217       hdr + options + nodes + t + "}\n"
218     end
219   end
221   # this is graph
222   class Digraph < Subgraph
223     def initialize( params = {}, option_list = GRAPH_OPTS )
224       super( params, option_list )
225       @dot_string = 'digraph'
226     end
227   end
229   # this is edge
230   class Edge < Element
231     attr_accessor :from, :to
232     def initialize( params = {}, option_list = EDGE_OPTS )
233       super( params, option_list )
234       @from = params['from'] ? params['from'] : nil
235       @to = params['to'] ? params['to'] : nil
236     end
238     def to_s( t = '' )
239       t + "#{@from} -> #{to} [\n" +
240         @options.to_a.collect{ |i|
241         i[1] && i[0] != 'label' ?
242           t + TAB + "#{i[0]} = #{i[1]}" :
243         i[1] ? t + TAB + "#{i[0]} = \"#{i[1]}\"" : nil
244       }.compact.join( "\n" ) + "\n" + t + "]\n"
245     end
246   end