ruby-graphviz 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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