ruby-graphviz 1.0.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gemrc +0 -0
- data/.gitignore +6 -0
- data/AUTHORS +3 -0
- data/Gemfile +4 -0
- data/README.rdoc +25 -45
- data/Rakefile +59 -0
- data/bin/dot2ruby +0 -0
- data/bin/gem2gv +0 -0
- data/bin/git2gv +0 -0
- data/bin/ruby2gv +0 -0
- data/bin/xml2gv +0 -0
- data/examples/sample48.rb +2 -2
- data/examples/sample62.rb +24 -0
- data/examples/sample63.rb +32 -0
- data/examples/sample64.rb +31 -0
- data/examples/sample65.rb +9 -0
- data/lib/graphviz.rb +55 -25
- data/lib/graphviz/constants.rb +103 -100
- data/lib/graphviz/core_ext.rb +57 -34
- data/lib/graphviz/dot2ruby.rb +9 -0
- data/lib/graphviz/dsl.rb +59 -0
- data/lib/graphviz/node.rb +2 -1
- data/lib/graphviz/types.rb +0 -4
- data/lib/graphviz/types/arrow_type.rb +32 -0
- data/lib/graphviz/types/color.rb +56 -0
- data/lib/graphviz/types/color_list.rb +22 -0
- data/lib/graphviz/types/esc_string.rb +5 -14
- data/lib/graphviz/types/gv_bool.rb +49 -0
- data/lib/graphviz/types/gv_double.rb +12 -2
- data/lib/graphviz/types/html_string.rb +3 -1
- data/lib/graphviz/types/lbl_string.rb +2 -1
- data/lib/graphviz/types/rect.rb +34 -0
- data/lib/graphviz/types/spline_type.rb +75 -0
- data/lib/graphviz/utils.rb +2 -2
- data/lib/graphviz/utils/colors.rb +1019 -0
- data/ruby-graphviz.gemspec +57 -0
- data/test/test_examples.rb +4 -0
- data/test/{test_init.rb → test_graph.rb} +1 -1
- data/test/test_types.rb +65 -0
- data/test/test_utils_colors.rb +57 -0
- metadata +100 -112
- data/examples/rgv/rgv.ps +0 -125
- data/examples/rgv/test_rgv.rb +0 -12
- data/examples/rgv/test_rgv.rb.ps +0 -393
- data/examples/simpsons.gv +0 -69
- data/test/output/sample01.rb.png +0 -0
- data/test/output/sample02.rb.png +0 -0
- data/test/output/sample03.rb.png +0 -0
- data/test/output/sample04.rb.png +0 -0
- data/test/output/sample05.rb.png +0 -0
- data/test/output/sample06.rb.png +0 -0
- data/test/output/sample07.rb.png +0 -0
- data/test/output/sample08.rb.png +0 -0
- data/test/output/sample09.rb.png +0 -0
- data/test/output/sample10.rb.png +0 -0
- data/test/output/sample11.rb.png +0 -0
- data/test/output/sample12.rb.png +0 -0
- data/test/output/sample13.rb.png +0 -0
- data/test/output/sample14.rb.png +0 -0
- data/test/output/sample15.rb.png +0 -0
- data/test/output/sample16.rb.png +0 -0
- data/test/output/sample17.rb.png +0 -0
- data/test/output/sample18.rb.png +0 -0
- data/test/output/sample19.rb.png +0 -0
- data/test/output/sample20.rb.png +0 -0
- data/test/output/sample21.rb.html +0 -3
- data/test/output/sample21.rb.png +0 -0
- data/test/output/sample22.rb.html +0 -5
- data/test/output/sample22.rb.png +0 -0
- data/test/output/sample23.rb.png +0 -0
- data/test/output/sample24.rb.png +0 -0
- data/test/output/sample25.rb.png +0 -0
- data/test/output/sample26.rb.png +0 -0
- data/test/output/sample28.rb.png +0 -0
- data/test/output/sample29.rb.svg +0 -21
- data/test/output/sample30.rb.ps +0 -923
- data/test/output/sample31.rb.png +0 -0
- data/test/output/sample32.rb.png +0 -0
- data/test/output/sample35.rb.gv +0 -24
- data/test/output/sample35.rb.png +0 -0
- data/test/output/sample37.rb.dot +0 -50
- data/test/output/sample37.rb.png +0 -0
- data/test/output/sample38.rb.png +0 -0
- data/test/output/sample39.rb.png +0 -0
- data/test/output/sample40.rb.png +0 -0
- data/test/output/sample41.rb.svg +0 -8
- data/test/output/sample42.rb.png +0 -0
- data/test/output/sample43.rb.png +0 -0
- data/test/output/sample44.rb.png +0 -0
- data/test/output/sample45.rb.png +0 -0
- data/test/output/sample46.rb.png +0 -0
- data/test/output/sample47.rb.png +0 -0
- data/test/output/sample48.rb.png +0 -0
- data/test/output/sample49.rb.png +0 -0
- data/test/output/sample50.rb.png +0 -0
- data/test/output/sample51.rb.png +0 -0
- data/test/output/sample52.rb.png +0 -0
- data/test/output/sample53.rb.png +0 -0
- data/test/output/sample54.rb.png +0 -0
- data/test/output/sample55.rb.png +0 -0
- data/test/output/sample56.rb.svg +0 -28
- data/test/output/sample58.rb.png +0 -0
- data/test/output/sample59.rb.png +0 -0
- data/test/output/sample60.rb.png +0 -0
- data/test/output/sample61.rb.png +0 -0
- data/test/output/sample99.rb.png +0 -0
data/lib/graphviz/core_ext.rb
CHANGED
@@ -1,43 +1,66 @@
|
|
1
1
|
class String
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
2
|
+
def self.random(size)
|
3
|
+
s = ""
|
4
|
+
d = ("a".."z").to_a + ("A".."Z").to_a + ("0".."9").to_a
|
5
|
+
size.times {
|
6
|
+
s << d[rand(d.size)]
|
7
|
+
}
|
8
|
+
return s
|
9
|
+
end
|
10
|
+
|
11
|
+
def convert_base(from, to)
|
12
|
+
self.to_i(from).to_s(to)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class Object
|
17
|
+
def to_ruby
|
18
|
+
begin
|
19
|
+
eval self
|
20
|
+
rescue => e
|
21
|
+
self
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class Array
|
27
|
+
def all?(&b)
|
28
|
+
r = self.delete_if { |x|
|
29
|
+
yield x
|
30
|
+
}
|
31
|
+
r.size == 0
|
32
|
+
end
|
10
33
|
end
|
11
34
|
|
12
35
|
# From : http://www.geekmade.co.uk/2008/09/ruby-tip-normalizing-hash-keys-as-symbols/
|
13
36
|
class Hash
|
14
|
-
|
15
|
-
|
16
|
-
|
37
|
+
def symbolize_keys
|
38
|
+
inject({}) do |options, (key, value)|
|
39
|
+
options[(key.to_sym rescue key) || key] = value
|
17
40
|
options
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# x = {
|
45
|
+
# :none => String,
|
46
|
+
# :png => "file.png",
|
47
|
+
# :svg => "file.svg"
|
48
|
+
# }
|
49
|
+
#
|
50
|
+
# x.each_except( :key => [:none], :value => [/\.png$/] ) do |k, v|
|
51
|
+
# puts "#{k} -> #{v}"
|
52
|
+
# end
|
53
|
+
#
|
54
|
+
# => svg -> file.svg
|
55
|
+
def each_except( e, &b )
|
56
|
+
key_table = (e[:key]||[]).clone.delete_if {|i| i.kind_of? Regexp }
|
57
|
+
key_regexp = (e[:key]||[]).clone.delete_if {|i| key_table.include? i }.map {|i| i.to_s }.join("|")
|
35
58
|
|
36
|
-
|
37
|
-
|
59
|
+
value_table = (e[:value]||[]).clone.delete_if {|i| i.kind_of? Regexp }
|
60
|
+
value_regexp = (e[:value]||[]).clone.delete_if {|i| value_table.include? i }.map {|i| i.to_s }.join("|")
|
38
61
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
62
|
+
self.each do |k, v|
|
63
|
+
yield( k, v ) unless (key_table.size > 0 and key_table.include?(k)) or (key_regexp.size > 0 and k.to_s.match(key_regexp)) or (value_table.size > 0 and value_table.include?(v)) or (value_regexp.size > 0 and v.to_s.match(value_regexp))
|
64
|
+
end
|
65
|
+
end
|
43
66
|
end
|
data/lib/graphviz/dot2ruby.rb
CHANGED
@@ -47,4 +47,13 @@ class Dot2Ruby #:nodoc:
|
|
47
47
|
instance_eval(xOutput)
|
48
48
|
return @_graph_eval
|
49
49
|
end
|
50
|
+
|
51
|
+
def eval_string( data ) #:nodoc:
|
52
|
+
t = Tempfile::open( File.basename(__FILE__) )
|
53
|
+
t.print( data )
|
54
|
+
t.close
|
55
|
+
result = self.eval(t.path)
|
56
|
+
t.close
|
57
|
+
return result
|
58
|
+
end
|
50
59
|
end
|
data/lib/graphviz/dsl.rb
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'graphviz'
|
2
|
+
|
3
|
+
class GraphViz::DSL
|
4
|
+
attr_accessor :graph
|
5
|
+
|
6
|
+
def initialize(name, hOpts = {}, &block)
|
7
|
+
@graph = GraphViz.new(name, hOpts)
|
8
|
+
instance_eval(&block) if block
|
9
|
+
end
|
10
|
+
|
11
|
+
def method_missing(sym, *args, &block)
|
12
|
+
return @graph.get_graph(sym.to_s) unless @graph.get_graph(sym.to_s).nil?
|
13
|
+
return @graph.get_node(sym.to_s) unless @graph.get_node(sym.to_s).nil?
|
14
|
+
if(@graph.respond_to?(sym, true))
|
15
|
+
@graph.send(sym, *args)
|
16
|
+
elsif(block)
|
17
|
+
@graph.add_graph(GraphViz::DSL.new(sym, { :parent => @graph, :type => @graph.type }, &block).graph)
|
18
|
+
else
|
19
|
+
@graph.add_node(sym.to_s, *args)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def n(name)
|
24
|
+
return @graph.get_node(name) unless @graph.get_node(name.to_s).nil?
|
25
|
+
@graph.add_node(name)
|
26
|
+
end
|
27
|
+
|
28
|
+
def e(*args)
|
29
|
+
e = nil
|
30
|
+
last = args.shift
|
31
|
+
while current = args.shift
|
32
|
+
e = @graph.add_edge(last, current)
|
33
|
+
last = current
|
34
|
+
end
|
35
|
+
return e
|
36
|
+
end
|
37
|
+
|
38
|
+
def subgraph(name, &block)
|
39
|
+
@graph.add_graph(GraphViz::DSL.new(name, { :parent => @graph, :type => @graph.type }, &block).graph)
|
40
|
+
end
|
41
|
+
alias :cluster :subgraph
|
42
|
+
|
43
|
+
def output(hOpts = {})
|
44
|
+
@graph.output(hOpts)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def graph(name, hOpts = {}, &block)
|
49
|
+
GraphViz::DSL.new(name, hOpts.merge( { :type => "graph" } ), &block).graph
|
50
|
+
end
|
51
|
+
|
52
|
+
def digraph(name, hOpts = {}, &block)
|
53
|
+
GraphViz::DSL.new(name, hOpts.merge( { :type => "digraph" } ), &block).graph
|
54
|
+
end
|
55
|
+
|
56
|
+
def strict(name, hOpts = {}, &block)
|
57
|
+
GraphViz::DSL.new(name, hOpts.merge( { :type => "strict digraph" } ), &block).graph
|
58
|
+
end
|
59
|
+
|
data/lib/graphviz/node.rb
CHANGED
@@ -62,7 +62,7 @@ class GraphViz
|
|
62
62
|
return( (self.pg.nil?) ? nil : self.pg.root_graph )
|
63
63
|
end
|
64
64
|
|
65
|
-
|
65
|
+
#
|
66
66
|
# Set value +xAttrValue+ to the node attribut +xAttrName+
|
67
67
|
#
|
68
68
|
def []=( xAttrName, xAttrValue )
|
@@ -78,6 +78,7 @@ class GraphViz
|
|
78
78
|
xAttrName.each do |key, value|
|
79
79
|
self[key] = value
|
80
80
|
end
|
81
|
+
return self
|
81
82
|
else
|
82
83
|
(@oAttrNode[xAttrName.to_s].nil?)?nil:@oAttrNode[xAttrName.to_s].clone
|
83
84
|
end
|
data/lib/graphviz/types.rb
CHANGED
@@ -0,0 +1,32 @@
|
|
1
|
+
# >> x = "hello\n\t\\l\"world\""
|
2
|
+
# => "hello\n\t\\l\"world\""
|
3
|
+
# >> puts x.inspect.gsub( "\\\\", "\\" )
|
4
|
+
# "hello\n\t\l\"world\""
|
5
|
+
#
|
6
|
+
# OR
|
7
|
+
#
|
8
|
+
# >> x = 'hello\n\t\l"world"'
|
9
|
+
# => "hello\\n\\t\\l\"world\""
|
10
|
+
# >> puts x.inspect.gsub( "\\\\", "\\" )
|
11
|
+
# "hello\n\t\l\"world\""
|
12
|
+
|
13
|
+
class GraphViz
|
14
|
+
class Types
|
15
|
+
class ArrowType < Common
|
16
|
+
def check(data)
|
17
|
+
return data
|
18
|
+
end
|
19
|
+
|
20
|
+
def output
|
21
|
+
return @data.to_s.inspect.gsub( "\\\\", "\\" )
|
22
|
+
end
|
23
|
+
|
24
|
+
alias :to_gv :output
|
25
|
+
alias :to_s :output
|
26
|
+
|
27
|
+
def to_ruby
|
28
|
+
@data
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'graphviz/utils/colors'
|
2
|
+
|
3
|
+
class ColorException < RuntimeError
|
4
|
+
end
|
5
|
+
|
6
|
+
class GraphViz
|
7
|
+
class Types
|
8
|
+
class Color < Common
|
9
|
+
HEX_FOR_COLOR = /[0-9a-fA-F]{2}/
|
10
|
+
RGBA = /^#(#{HEX_FOR_COLOR})(#{HEX_FOR_COLOR})(#{HEX_FOR_COLOR})(#{HEX_FOR_COLOR})?$/
|
11
|
+
|
12
|
+
def check(data)
|
13
|
+
data = data.to_s if data.is_a?(Symbol)
|
14
|
+
if data[0].chr == "#"
|
15
|
+
m = RGBA.match(data)
|
16
|
+
if m.nil?
|
17
|
+
raise ColorException, "Wrong color definition RGBA #{data}"
|
18
|
+
end
|
19
|
+
@to_ruby = GraphViz::Utils::Colors.rgb(m[1], m[2], m[3], m[4])
|
20
|
+
return data
|
21
|
+
elsif data.include?(",") or data.include?(" ")
|
22
|
+
m = data.split(/(?:\s*,\s*|\s+)/).map { |x| x.to_f }
|
23
|
+
if m.size != 3
|
24
|
+
raise ColorException, "Wrong color definition HSV #{data}"
|
25
|
+
end
|
26
|
+
@to_ruby = GraphViz::Utils::Colors.hsv(m[0], m[1], m[2])
|
27
|
+
return data
|
28
|
+
elsif data.is_a?(Array)
|
29
|
+
if data.all? { |x| x.is_a?(String) and x =~ /^#{HEX_FOR_COLOR}$/ } and [3,4].include?(data.size)
|
30
|
+
@to_ruby = GraphViz::Utils::Colors.rgb(data[0], data[1], data[2], data[3])
|
31
|
+
return data
|
32
|
+
elsif data.all? { |x| x.kind_of?(Numeric) } and data.size == 3
|
33
|
+
@to_ruby = GraphViz::Utils::Colors.hsv(data[0], data[1], data[2])
|
34
|
+
return data
|
35
|
+
end
|
36
|
+
|
37
|
+
raise ColorException, "Wrong color definition Array #{data}"
|
38
|
+
else
|
39
|
+
@to_ruby = GraphViz::Utils::Colors.name(data)
|
40
|
+
return data
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def output
|
45
|
+
return @data.to_s.inspect.gsub( "\\\\", "\\" )
|
46
|
+
end
|
47
|
+
|
48
|
+
alias :to_gv :output
|
49
|
+
alias :to_s :output
|
50
|
+
|
51
|
+
def to_ruby
|
52
|
+
@to_ruby
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
class GraphViz
|
2
|
+
class Types
|
3
|
+
class ColorList < Common
|
4
|
+
def check(data)
|
5
|
+
data = data.to_s if data.is_a?(Symbol)
|
6
|
+
@to_ruby = data.split(/\s*:\s*/).map { |c| GraphViz::Types::Color.new(c).to_ruby }
|
7
|
+
return data
|
8
|
+
end
|
9
|
+
|
10
|
+
def output
|
11
|
+
return @data.to_s.inspect.gsub( "\\\\", "\\" )
|
12
|
+
end
|
13
|
+
|
14
|
+
alias :to_gv :output
|
15
|
+
alias :to_s :output
|
16
|
+
|
17
|
+
def to_ruby
|
18
|
+
@data
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -1,16 +1,3 @@
|
|
1
|
-
# >> x = "hello\n\t\\l\"world\""
|
2
|
-
# => "hello\n\t\\l\"world\""
|
3
|
-
# >> puts x.inspect.gsub( "\\\\", "\\" )
|
4
|
-
# "hello\n\t\l\"world\""
|
5
|
-
#
|
6
|
-
# OR
|
7
|
-
#
|
8
|
-
# >> x = 'hello\n\t\l"world"'
|
9
|
-
# => "hello\\n\\t\\l\"world\""
|
10
|
-
# >> puts x.inspect.gsub( "\\\\", "\\" )
|
11
|
-
# "hello\n\t\l\"world\""
|
12
|
-
|
13
|
-
|
14
1
|
class GraphViz
|
15
2
|
class Types
|
16
3
|
class EscString < Common
|
@@ -24,6 +11,10 @@ class GraphViz
|
|
24
11
|
|
25
12
|
alias :to_gv :output
|
26
13
|
alias :to_s :output
|
14
|
+
|
15
|
+
def to_ruby
|
16
|
+
@data
|
17
|
+
end
|
27
18
|
end
|
28
19
|
end
|
29
|
-
end
|
20
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
class BoolException < RuntimeError
|
2
|
+
end
|
3
|
+
|
4
|
+
# bool
|
5
|
+
#
|
6
|
+
# For the bool type,
|
7
|
+
# - TRUE values are represented by "true" or "yes" (case-insensitive), true and any non-zero integer
|
8
|
+
# - FALSE values by "false" or "no" (case-insensitive), false and zero.
|
9
|
+
#
|
10
|
+
# Example
|
11
|
+
#
|
12
|
+
# graph[:center] = "true"
|
13
|
+
# or
|
14
|
+
# graph[:center] = true
|
15
|
+
# or
|
16
|
+
# graph[:center] = 23
|
17
|
+
class GraphViz
|
18
|
+
class Types
|
19
|
+
class GvBool < Common
|
20
|
+
BOOL_TRUE = ["true", "yes"]
|
21
|
+
BOOL_FALSE = ["false", "no"]
|
22
|
+
|
23
|
+
def check(data)
|
24
|
+
if true == data or (data.is_a?(Integer) and data != 0) or (data.is_a?(String) and BOOL_TRUE.include?(data.downcase))
|
25
|
+
@to_ruby = true
|
26
|
+
return data
|
27
|
+
end
|
28
|
+
|
29
|
+
if false == data or (data.is_a?(Integer) and data == 0) or (data.is_a?(String) and BOOL_FALSE.include?(data.downcase))
|
30
|
+
@to_ruby = false
|
31
|
+
return data
|
32
|
+
end
|
33
|
+
|
34
|
+
raise BoolException, "Invalid bool value"
|
35
|
+
end
|
36
|
+
|
37
|
+
def output
|
38
|
+
return @data.to_s.inspect.gsub( "\\\\", "\\" )
|
39
|
+
end
|
40
|
+
|
41
|
+
alias :to_gv :output
|
42
|
+
alias :to_s :output
|
43
|
+
|
44
|
+
def to_ruby
|
45
|
+
@to_ruby
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -1,8 +1,17 @@
|
|
1
|
+
class DoubleException < RuntimeError
|
2
|
+
end
|
3
|
+
|
1
4
|
class GraphViz
|
2
5
|
class Types
|
3
6
|
class GvDouble < Common
|
7
|
+
FLOAT_MASK = /[-+]?(?:[0-9]*\.[0-9]+|[0-9]+)/
|
8
|
+
|
4
9
|
def check(data)
|
5
|
-
|
10
|
+
if data.kind_of?(Numeric) or (data.is_a?(String) and FLOAT_MASK.match(data))
|
11
|
+
return data
|
12
|
+
end
|
13
|
+
|
14
|
+
raise DoubleException, "Invalid double value"
|
6
15
|
end
|
7
16
|
|
8
17
|
def output
|
@@ -15,6 +24,7 @@ class GraphViz
|
|
15
24
|
|
16
25
|
alias :to_gv :output
|
17
26
|
alias :to_s :output
|
27
|
+
alias :to_ruby :to_f
|
18
28
|
end
|
19
29
|
end
|
20
|
-
end
|
30
|
+
end
|