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.
Files changed (106) hide show
  1. data/.gemrc +0 -0
  2. data/.gitignore +6 -0
  3. data/AUTHORS +3 -0
  4. data/Gemfile +4 -0
  5. data/README.rdoc +25 -45
  6. data/Rakefile +59 -0
  7. data/bin/dot2ruby +0 -0
  8. data/bin/gem2gv +0 -0
  9. data/bin/git2gv +0 -0
  10. data/bin/ruby2gv +0 -0
  11. data/bin/xml2gv +0 -0
  12. data/examples/sample48.rb +2 -2
  13. data/examples/sample62.rb +24 -0
  14. data/examples/sample63.rb +32 -0
  15. data/examples/sample64.rb +31 -0
  16. data/examples/sample65.rb +9 -0
  17. data/lib/graphviz.rb +55 -25
  18. data/lib/graphviz/constants.rb +103 -100
  19. data/lib/graphviz/core_ext.rb +57 -34
  20. data/lib/graphviz/dot2ruby.rb +9 -0
  21. data/lib/graphviz/dsl.rb +59 -0
  22. data/lib/graphviz/node.rb +2 -1
  23. data/lib/graphviz/types.rb +0 -4
  24. data/lib/graphviz/types/arrow_type.rb +32 -0
  25. data/lib/graphviz/types/color.rb +56 -0
  26. data/lib/graphviz/types/color_list.rb +22 -0
  27. data/lib/graphviz/types/esc_string.rb +5 -14
  28. data/lib/graphviz/types/gv_bool.rb +49 -0
  29. data/lib/graphviz/types/gv_double.rb +12 -2
  30. data/lib/graphviz/types/html_string.rb +3 -1
  31. data/lib/graphviz/types/lbl_string.rb +2 -1
  32. data/lib/graphviz/types/rect.rb +34 -0
  33. data/lib/graphviz/types/spline_type.rb +75 -0
  34. data/lib/graphviz/utils.rb +2 -2
  35. data/lib/graphviz/utils/colors.rb +1019 -0
  36. data/ruby-graphviz.gemspec +57 -0
  37. data/test/test_examples.rb +4 -0
  38. data/test/{test_init.rb → test_graph.rb} +1 -1
  39. data/test/test_types.rb +65 -0
  40. data/test/test_utils_colors.rb +57 -0
  41. metadata +100 -112
  42. data/examples/rgv/rgv.ps +0 -125
  43. data/examples/rgv/test_rgv.rb +0 -12
  44. data/examples/rgv/test_rgv.rb.ps +0 -393
  45. data/examples/simpsons.gv +0 -69
  46. data/test/output/sample01.rb.png +0 -0
  47. data/test/output/sample02.rb.png +0 -0
  48. data/test/output/sample03.rb.png +0 -0
  49. data/test/output/sample04.rb.png +0 -0
  50. data/test/output/sample05.rb.png +0 -0
  51. data/test/output/sample06.rb.png +0 -0
  52. data/test/output/sample07.rb.png +0 -0
  53. data/test/output/sample08.rb.png +0 -0
  54. data/test/output/sample09.rb.png +0 -0
  55. data/test/output/sample10.rb.png +0 -0
  56. data/test/output/sample11.rb.png +0 -0
  57. data/test/output/sample12.rb.png +0 -0
  58. data/test/output/sample13.rb.png +0 -0
  59. data/test/output/sample14.rb.png +0 -0
  60. data/test/output/sample15.rb.png +0 -0
  61. data/test/output/sample16.rb.png +0 -0
  62. data/test/output/sample17.rb.png +0 -0
  63. data/test/output/sample18.rb.png +0 -0
  64. data/test/output/sample19.rb.png +0 -0
  65. data/test/output/sample20.rb.png +0 -0
  66. data/test/output/sample21.rb.html +0 -3
  67. data/test/output/sample21.rb.png +0 -0
  68. data/test/output/sample22.rb.html +0 -5
  69. data/test/output/sample22.rb.png +0 -0
  70. data/test/output/sample23.rb.png +0 -0
  71. data/test/output/sample24.rb.png +0 -0
  72. data/test/output/sample25.rb.png +0 -0
  73. data/test/output/sample26.rb.png +0 -0
  74. data/test/output/sample28.rb.png +0 -0
  75. data/test/output/sample29.rb.svg +0 -21
  76. data/test/output/sample30.rb.ps +0 -923
  77. data/test/output/sample31.rb.png +0 -0
  78. data/test/output/sample32.rb.png +0 -0
  79. data/test/output/sample35.rb.gv +0 -24
  80. data/test/output/sample35.rb.png +0 -0
  81. data/test/output/sample37.rb.dot +0 -50
  82. data/test/output/sample37.rb.png +0 -0
  83. data/test/output/sample38.rb.png +0 -0
  84. data/test/output/sample39.rb.png +0 -0
  85. data/test/output/sample40.rb.png +0 -0
  86. data/test/output/sample41.rb.svg +0 -8
  87. data/test/output/sample42.rb.png +0 -0
  88. data/test/output/sample43.rb.png +0 -0
  89. data/test/output/sample44.rb.png +0 -0
  90. data/test/output/sample45.rb.png +0 -0
  91. data/test/output/sample46.rb.png +0 -0
  92. data/test/output/sample47.rb.png +0 -0
  93. data/test/output/sample48.rb.png +0 -0
  94. data/test/output/sample49.rb.png +0 -0
  95. data/test/output/sample50.rb.png +0 -0
  96. data/test/output/sample51.rb.png +0 -0
  97. data/test/output/sample52.rb.png +0 -0
  98. data/test/output/sample53.rb.png +0 -0
  99. data/test/output/sample54.rb.png +0 -0
  100. data/test/output/sample55.rb.png +0 -0
  101. data/test/output/sample56.rb.svg +0 -28
  102. data/test/output/sample58.rb.png +0 -0
  103. data/test/output/sample59.rb.png +0 -0
  104. data/test/output/sample60.rb.png +0 -0
  105. data/test/output/sample61.rb.png +0 -0
  106. data/test/output/sample99.rb.png +0 -0
@@ -1,43 +1,66 @@
1
1
  class String
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
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
- def symbolize_keys
15
- inject({}) do |options, (key, value)|
16
- options[(key.to_sym rescue key) || key] = value
37
+ def symbolize_keys
38
+ inject({}) do |options, (key, value)|
39
+ options[(key.to_sym rescue key) || key] = value
17
40
  options
18
- end
19
- end
20
-
21
- # x = {
22
- # :none => String,
23
- # :png => "file.png",
24
- # :svg => "file.svg"
25
- # }
26
- #
27
- # x.each_except( :key => [:none], :value => [/\.png$/] ) do |k, v|
28
- # puts "#{k} -> #{v}"
29
- # end
30
- #
31
- # => svg -> file.svg
32
- def each_except( e, &b )
33
- key_table = (e[:key]||[]).clone.delete_if {|i| i.kind_of? Regexp }
34
- key_regexp = (e[:key]||[]).clone.delete_if {|i| key_table.include? i }.map {|i| i.to_s }.join("|")
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
- value_table = (e[:value]||[]).clone.delete_if {|i| i.kind_of? Regexp }
37
- value_regexp = (e[:value]||[]).clone.delete_if {|i| value_table.include? i }.map {|i| i.to_s }.join("|")
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
- self.each do |k, v|
40
- 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))
41
- end
42
- end
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
@@ -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
@@ -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
+
@@ -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
@@ -19,7 +19,3 @@ class GraphViz
19
19
  end
20
20
  end
21
21
  end
22
-
23
- #x = :EscString
24
- #GraphViz::Types.const_get(x).new( "toto" )
25
-
@@ -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
- return data
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
@@ -1,3 +1,4 @@
1
+ # TODO: Remove
1
2
  class GraphViz
2
3
  class Types
3
4
  class HtmlString < Common
@@ -11,6 +12,7 @@ class GraphViz
11
12
 
12
13
  alias :to_gv :output
13
14
  alias :to_s :output
15
+ alias :to_ruby :output
14
16
  end
15
17
  end
16
- end
18
+ end
@@ -16,6 +16,7 @@ class GraphViz
16
16
 
17
17
  alias :to_gv :output
18
18
  alias :to_s :output
19
+ alias :to_ruby :output
19
20
  end
20
21
  end
21
- end
22
+ end