GraphvizR 0.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.
@@ -0,0 +1,5 @@
1
+ == 1.0.0 / 2007-02-11
2
+
3
+ * 1 major enhancement
4
+ * Birthday!
5
+
@@ -0,0 +1,7 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.txt
4
+ Rakefile
5
+ bin/graphviz_r
6
+ lib/graphviz_r.rb
7
+ test/test_graphviz_r.rb
@@ -0,0 +1,73 @@
1
+ GraphvizR
2
+ by ANDO Yasushi
3
+ http://blog.technohippy.net
4
+
5
+ == DESCRIPTION:
6
+
7
+ Generate Graphviz dot file.
8
+
9
+ == FEATURES/PROBLEMS:
10
+
11
+ * Generate Graphviz dot file
12
+
13
+ == SYNOPSYS:
14
+
15
+ === Command Line:
16
+
17
+ graphviz_r sample/record.rdot
18
+
19
+ === In Your Code:
20
+ This ruby code:
21
+
22
+ gvr = GraphvizR.new 'sample'
23
+ gvr.graph [:label => 'example', :size => '1.5, 2.5']
24
+ gvr.beta [:shape => :box]
25
+ gvr.alpha >> gvr.beta
26
+ (gvr.beta >> gvr.delta) [:label => 'label1']
27
+ gvr.delta >> gvr.gamma
28
+ gvr.to_dot
29
+
30
+ replies the dot code:
31
+
32
+ digraph sample {
33
+ graph [label = "example", size = "1.5, 2.5"];
34
+ beta [shape = box];
35
+ alpha -> beta;
36
+ beta -> delta [label = "label1"];
37
+ delta -> gamma;
38
+ }
39
+
40
+ To know more detail, please see test/test_graphviz_r.rb
41
+
42
+ == REQUIREMENTS:
43
+
44
+ * Check Graphviz specification
45
+
46
+ == INSTALL:
47
+
48
+ * sudo gem install graphviz_r
49
+
50
+ == LICENSE:
51
+
52
+ (The MIT License)
53
+
54
+ Copyright (c) 2007 FIX
55
+
56
+ Permission is hereby granted, free of charge, to any person obtaining
57
+ a copy of this software and associated documentation files (the
58
+ 'Software'), to deal in the Software without restriction, including
59
+ without limitation the rights to use, copy, modify, merge, publish,
60
+ distribute, sublicense, and/or sell copies of the Software, and to
61
+ permit persons to whom the Software is furnished to do so, subject to
62
+ the following conditions:
63
+
64
+ The above copyright notice and this permission notice shall be
65
+ included in all copies or substantial portions of the Software.
66
+
67
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
68
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
69
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
70
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
71
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
72
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
73
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,15 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require 'hoe'
5
+ require './lib/graphviz_r.rb'
6
+
7
+ Hoe.new('GraphvizR', GraphvizR::VERSION) do |p|
8
+ p.rubyforge_name = 'graphviz_r'
9
+ # p.summary = 'FIX'
10
+ # p.description = p.paragraphs_of('README.txt', 2..5).join("\n\n")
11
+ # p.url = p.paragraphs_of('README.txt', 0).first.split(/\n/)[1..-1]
12
+ p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
13
+ end
14
+
15
+ # vim: syntax=Ruby
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env ruby
2
+ require 'optparse'
3
+
4
+ $:.unshift File.join(File.dirname(__FILE__), '../lib')
5
+ require 'graphviz_r'
6
+
7
+ # define options
8
+ COMMAND_LINE = "#{$0} #{ARGV.join(' ')}"
9
+ OPT = Array.new 2
10
+ opt = OptionParser.new
11
+ opt.on('-o <outfile>', 'Output filename'){|v| OPT[0] = v}
12
+ opt.on('-T <format>', 'Image file format'){|v| OPT[1] = v}
13
+ opt.on_tail('-v', '--version', 'Show version.'){puts opt.ver; exit}
14
+ opt.banner = "Usage: graphviz_r [OPTIONS] RDOT_FILE"
15
+
16
+ Version = GraphvizR::VERSION
17
+ opt.parse! ARGV
18
+
19
+ rdotfile = ARGV.shift
20
+ rdot = File.read rdotfile
21
+ gvr = GraphvizR.new File.basename(rdotfile).split('.')[0]
22
+ gvr.instance_eval rdot
23
+ gvr.output *OPT
@@ -0,0 +1,249 @@
1
+ class GraphvizR
2
+ VERSION = '0.0.1'
3
+
4
+ class Attributes
5
+ def initialize(name, dot)
6
+ @name = name
7
+ @dot = dot
8
+ end
9
+
10
+ def [](prop)
11
+ @dot.send :"#{@name}=", prop
12
+ end
13
+ end
14
+
15
+ class Node
16
+ attr_reader :prop, :name
17
+
18
+ def initialize(name, port, dot)
19
+ @name = name
20
+ @port = port || []
21
+ @dot = dot
22
+ @prop = {}
23
+
24
+ if !@port.empty? and @port[0].is_a? Array and @port[0][0].is_a? Hash
25
+ @dot[@name] = @port[0][0]
26
+ end
27
+ end
28
+
29
+ def >>(node)
30
+ prop = @prop.merge node.prop
31
+ edge = Edge.new(self, node, prop)
32
+ @dot.add_edge edge
33
+ edge
34
+ end
35
+
36
+ def [](prop)
37
+ @dot[@name] = prop
38
+ @prop.merge! prop
39
+ self
40
+ end
41
+
42
+ def <=>(other)
43
+ @name <=> other.name
44
+ end
45
+
46
+ def to_sym
47
+ self
48
+ end
49
+
50
+ def to_dot
51
+ name = @port.dup
52
+ name.unshift @name
53
+ name.map{|e| e.to_dot}.join(':')
54
+ #@name.to_dot
55
+ end
56
+ end
57
+
58
+ class Edge
59
+ def initialize(from, to, prop={})
60
+ @from = from
61
+ @to = to
62
+ @property = prop
63
+ end
64
+
65
+ def [](prop)
66
+ @property.merge! prop
67
+ end
68
+
69
+ def node_to_dot(node)
70
+ node.is_a?(Array) ? node.map{|e| e.to_sym.to_dot}.join(':') : node.to_sym.to_dot
71
+ end
72
+
73
+ def to_dot
74
+ dot = "#{node_to_dot @from} -> #{node_to_dot @to}"
75
+ dot += " #{@property.to_dot}" unless @property.empty?
76
+ dot
77
+ end
78
+
79
+ def <=>(other)
80
+ to_dot <=> other.to_dot
81
+ end
82
+ end
83
+
84
+ def self.dot(name, prop)
85
+ GraphvizR.new(name, prop).to_dot
86
+ end
87
+
88
+ def initialize(name, prop={}, graph_type='digraph')
89
+ if name.is_a? Array
90
+ initialize(*name)
91
+ else
92
+ @name = name
93
+ @edges = []
94
+ @default_node_properties = {}
95
+ @node_properties = {}
96
+ @graph_properties = {}
97
+ @subgraphs = []
98
+ @graph_type = graph_type
99
+ interprete prop
100
+ end
101
+ end
102
+
103
+ def interprete(prop)
104
+ prop.each do |k, v|
105
+ case k
106
+ when :node_property, :node_properties
107
+ add_node_properties v
108
+ when :graph
109
+ @graph_properties.merge! v
110
+ when :label, :size, :color, :fillcolor, :style
111
+ @graph_properties[k] = v
112
+ when :node
113
+ @default_node_properties[k] = v
114
+ when :subgraphs
115
+ add_subgraph(v)
116
+ else
117
+ add_edge k, v
118
+ end
119
+ end
120
+ end
121
+
122
+ def add_node_properties(props)
123
+ @node_properties = props
124
+ end
125
+
126
+ def add_edge(from, to=nil)
127
+ if from.is_a? Hash
128
+ f = from.keys[0]
129
+ t = from[f]
130
+ p = to
131
+ @edges << Edge.new(f, t, p)
132
+ elsif to.nil?
133
+ # from is Edge instance
134
+ @edges << from
135
+ else
136
+ @edges << Edge.new(from, to)
137
+ end
138
+ end
139
+
140
+ def add_subgraph(graphs)
141
+ graphs.to_a.sort.each do |key_prop|
142
+ @subgraphs << self.class.new(key_prop[0], key_prop[1], 'subgraph')
143
+ end
144
+ end
145
+
146
+ def [](key, *args, &block)
147
+ if block
148
+ subgraph = self.class.new(key, {}, 'subgraph')
149
+ block.call subgraph
150
+ @subgraphs << subgraph
151
+ else
152
+ Node.new key, args, self
153
+ end
154
+ end
155
+
156
+ def []=(key, *args, &block)
157
+ @node_properties[key] = args[0]
158
+ end
159
+
160
+ [:label, :size, :color, :fillcolor, :style].each do |method|
161
+ define_method :"#{method}=" do |v|
162
+ @graph_properties[method] = v
163
+ end
164
+ end
165
+
166
+ def graph(*args)
167
+ if args.empty?
168
+ Attributes.new :graph, self
169
+ else
170
+ self.graph = args[0][0]
171
+ end
172
+ end
173
+
174
+ def graph=(prop)
175
+ @graph_properties.merge! prop
176
+ end
177
+
178
+ def to_dot
179
+ dot = "#{@graph_type} #{@name} {"
180
+ dot += "graph #{@graph_properties.to_dot};" unless @graph_properties.empty?
181
+ dot += @subgraphs.map{|e| e.to_dot}.join("\n") unless @subgraphs.empty?
182
+ dot += properties_to_dot(@default_node_properties) unless @default_node_properties.empty?
183
+ dot += properties_to_dot(@node_properties) unless @node_properties.empty?
184
+ dot += @edges.sort.map{|e| "#{e.to_dot};"}.join("\n")
185
+ dot += "}"
186
+ dot
187
+ end
188
+
189
+ def data(format='png')
190
+ gv = IO.popen "dot -q -T#{format || 'png'}", "w+"
191
+ gv.puts to_dot
192
+ gv.close_write
193
+ gv.read
194
+ ensure
195
+ gv.close
196
+ end
197
+
198
+ def output(filename=nil, format='png')
199
+ img = data(format)
200
+ File.open(filename || "#{@name}.#{format || 'png'}", "w+") do |file|
201
+ file.write img
202
+ end
203
+ end
204
+
205
+ def method_missing(name, *args, &block)
206
+ method =
207
+ if name.to_s =~ /=$/
208
+ name = name.to_s[0..-2].to_sym
209
+ :"[]="
210
+ else
211
+ :"[]"
212
+ end
213
+ self.send(method, name, *args, &block)
214
+ end
215
+
216
+ protected
217
+
218
+ def properties_to_dot(hash)
219
+ hash.to_a.sort.map{|e| "#{e[0]} #{e[1].to_dot};"}.join("\n")
220
+ end
221
+ end
222
+
223
+ class Number
224
+ def to_dot
225
+ to_s
226
+ end
227
+ end
228
+
229
+ class String
230
+ def to_dot
231
+ inspect
232
+ end
233
+ end
234
+
235
+ class Symbol
236
+ def to_dot
237
+ to_s
238
+ end
239
+
240
+ def <=>(other)
241
+ to_s <=> other.to_s
242
+ end
243
+ end
244
+
245
+ class Hash
246
+ def to_dot
247
+ "[#{to_a.sort.map{|e| "#{e[0].to_dot} = #{e[1].to_dot}"}.join(', ')}]"
248
+ end
249
+ end
@@ -0,0 +1,209 @@
1
+ # ref. http://homepage3.nifty.com/kaku-chan/graphviz/index.html
2
+
3
+ require 'test/unit'
4
+ require 'graphviz_r'
5
+
6
+ class TestGraphvizR < Test::Unit::TestCase
7
+ def test_string_to_dot
8
+ assert_equal '"str"', "str".to_dot
9
+ end
10
+
11
+ def test_symbol_to_dot
12
+ assert_equal "sym", :sym.to_dot
13
+ end
14
+
15
+ def test_hash_to_dot
16
+ assert_equal '[k1 = v1, k2 = "v2"]', {:k1 => :v1, :k2 => "v2"}.to_dot
17
+ end
18
+
19
+ def test_basic
20
+ dot = GraphvizR.dot(:sample,
21
+ :graph => {:size => "1.5, 2.5"},
22
+ :label => 'example',
23
+ :node_properties => {
24
+ :beta => {:shape => :box},
25
+ },
26
+ :alpha => :beta,
27
+ {:alpha => :gamma} => {:label => 'label1'},
28
+ :beta => :delta,
29
+ :delta => 'size'
30
+ )
31
+ assert_equal <<-end_of_string.gsub(/\s/, ''), dot.gsub(/\s/, '')
32
+ digraph sample {
33
+ graph [label = "example", size = "1.5, 2.5"];
34
+ beta [shape = box];
35
+ alpha -> beta;
36
+ alpha -> gamma [label = "label1"];
37
+ beta -> delta;
38
+ delta -> size;
39
+ }
40
+ end_of_string
41
+ end
42
+
43
+ #dot.graph = {:label => 'example', :size => '1.5, 2.5'}
44
+ #dot.beta = {:shape => :box}
45
+ #dot.graph[:label => 'example', :size => '1.5, 2.5']
46
+ #dot.beta[:shape => :box]
47
+ def test_basic_dynamic
48
+ dot = GraphvizR.new 'sample'
49
+ dot.graph [:label => 'example', :size => '1.5, 2.5']
50
+ dot.beta [:shape => :box]
51
+ dot.alpha >> dot.beta
52
+ (dot.alpha >> dot.gamma) [:label => 'label1']
53
+ (dot.beta >> dot.delta) [:label => 'label2']
54
+ dot.delta >> dot[:size]
55
+
56
+ assert_equal <<-end_of_string.gsub(/\s/, ''), dot.to_dot.gsub(/\s/, '')
57
+ digraph sample {
58
+ graph [label = "example", size = "1.5, 2.5"];
59
+ beta [shape = box];
60
+ alpha -> beta;
61
+ alpha -> gamma [label = "label1"];
62
+ beta -> delta [label = "label2"];
63
+ delta -> size;
64
+ }
65
+ end_of_string
66
+ end
67
+
68
+ def test_record
69
+ dot = GraphvizR.dot(:sample,
70
+ :graph => {:size => "1.5, 2.5"},
71
+ :node => {:shape => :record},
72
+ :node_properties => {
73
+ :node1 => {:label => "<p_left> left|<p_center>center|<p_right> right"},
74
+ :node2 => {:label => "left|center|right"}
75
+ },
76
+ :node1 => :node2,
77
+ [:node1, :p_left] => :node2,
78
+ :node2 => [:node1, :p_center],
79
+ {:node2 => [:node1, :p_right]} => {:label => 'record'}
80
+ )
81
+ assert_equal <<-end_of_string.gsub(/\s/, ''), dot.gsub(/\s/, '')
82
+ digraph sample {
83
+ graph [size = "1.5, 2.5"];
84
+ node [shape = record];
85
+ node1 [label = "<p_left> left|<p_center>center|<p_right> right"];
86
+ node2 [label = "left|center|right"];
87
+ node1 -> node2;
88
+ node1:p_left -> node2;
89
+ node2 -> node1:p_center;
90
+ node2 -> node1:p_right [label = "record"];
91
+ }
92
+ end_of_string
93
+ end
94
+
95
+ #dot.size = '1.5, 2.5'
96
+ #dot.node = {:shape => :record}
97
+ #d dot.node1 = {:label => "<p_left> left|<p_center>center|<p_right> right"}
98
+ #dot.node2 = {:label => "left|center|right"}
99
+ def test_record_dynamic
100
+ dot = GraphvizR.new 'sample'
101
+ dot.graph [:size => '1.5, 2.5']
102
+ dot.node [:shape => :record]
103
+ dot.node1 [:label => "<p_left> left|<p_center>center|<p_right> right"]
104
+ dot.node2 [:label => "left|center|right"]
105
+ dot.node1 >> dot.node2
106
+ dot.node1(:p_left) >> dot.node2
107
+ dot.node2 >> dot.node1(:p_center)
108
+ (dot.node2 >> dot.node1(:p_right)) [:label => 'record']
109
+
110
+ assert_equal <<-end_of_string.gsub(/\s/, ''), dot.to_dot.gsub(/\s/, '')
111
+ digraph sample {
112
+ graph [size = "1.5, 2.5"];
113
+ node [shape = record];
114
+ node1 [label = "<p_left> left|<p_center>center|<p_right> right"];
115
+ node2 [label = "left|center|right"];
116
+ node1 -> node2;
117
+ node1:p_left -> node2;
118
+ node2 -> node1:p_center;
119
+ node2 -> node1:p_right [label = "record"];
120
+ }
121
+ end_of_string
122
+ end
123
+
124
+ def test_subgraph
125
+ dot = GraphvizR.dot(:sample,
126
+ :subgraphs => {
127
+ :cluster0 => {
128
+ :color => :blue,
129
+ :style => :bold,
130
+ :label => "area 0",
131
+ {:a => :b} => {},
132
+ :a => :c
133
+ },
134
+ :cluster1 => {
135
+ :fillcolor => "#cc9966",
136
+ :style => :filled,
137
+ :label => "area 1",
138
+ [:d] => :e,
139
+ :d => :f
140
+ }
141
+ },
142
+ :b => :d,
143
+ {:c => :d} => {:ltail => :cluster0},
144
+ {:c => :f} => {:lhead => :cluster1},
145
+ {:a => :f} => {:ltail => :cluster0, :lhead => :cluster1}
146
+ )
147
+ assert_equal <<-end_of_string.gsub(/\s/, ''), dot.gsub(/\s/, '')
148
+ digraph sample {
149
+ subgraph cluster0 {
150
+ graph [color = blue, label ="area 0", style = bold];
151
+ a -> b;
152
+ a -> c;
153
+ }
154
+ subgraph cluster1 {
155
+ graph [fillcolor = "#cc9966", label = "area 1", style = filled];
156
+ d -> e;
157
+ d -> f;
158
+ }
159
+ a -> f [lhead = cluster1, ltail = cluster0];
160
+ b -> d;
161
+ c -> d [ltail = cluster0];
162
+ c -> f [lhead = cluster1];
163
+ }
164
+ end_of_string
165
+ end
166
+
167
+ #c0.color = :blue
168
+ #c0.label = 'area 0'
169
+ #c0.style = :bold
170
+ #c1.fillcolor = '#cc9966'
171
+ #c1.label = 'area 1'
172
+ #c1.style = :filled
173
+ def test_subgrpah_dynamic
174
+ dot = GraphvizR.new 'sample'
175
+ dot.cluster0 do |c0|
176
+ c0.graph [:color => :blue, :label => 'area 0', :style => :bold]
177
+ c0.a >> c0.b
178
+ c0.a >> c0.c
179
+ end
180
+ dot.cluster1 do |c1|
181
+ c1.graph [:fillcolor => '#cc9966', :label => 'area 1', :style => :filled]
182
+ c1.d >> c1.e
183
+ c1.d >> c1.f
184
+ end
185
+ (dot.a >> dot.f) [:lhead => :cluster1, :ltail => :cluster0]
186
+ dot.b >> dot.d
187
+ (dot.c >> dot.d) [:ltail => :cluster0]
188
+ (dot.c >> dot.f) [:lhead => :cluster1]
189
+
190
+ assert_equal <<-end_of_string.gsub(/\s/, ''), dot.to_dot.gsub(/\s/, '')
191
+ digraph sample {
192
+ subgraph cluster0 {
193
+ graph [color = blue, label ="area 0", style = bold];
194
+ a -> b;
195
+ a -> c;
196
+ }
197
+ subgraph cluster1 {
198
+ graph [fillcolor = "#cc9966", label = "area 1", style = filled];
199
+ d -> e;
200
+ d -> f;
201
+ }
202
+ a -> f [lhead = cluster1, ltail = cluster0];
203
+ b -> d;
204
+ c -> d [ltail = cluster0];
205
+ c -> f [lhead = cluster1];
206
+ }
207
+ end_of_string
208
+ end
209
+ end
metadata ADDED
@@ -0,0 +1,58 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.0
3
+ specification_version: 1
4
+ name: GraphvizR
5
+ version: !ruby/object:Gem::Version
6
+ version: 0.0.1
7
+ date: 2007-02-14 00:00:00 +09:00
8
+ summary: The author was too lazy to write a summary
9
+ require_paths:
10
+ - lib
11
+ email: ryand-ruby@zenspider.com
12
+ homepage: http://www.zenspider.com/ZSS/Products/GraphvizR/
13
+ rubyforge_project: graphviz_r
14
+ description: The author was too lazy to write a description
15
+ autorequire:
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: true
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ -
22
+ - ">"
23
+ - !ruby/object:Gem::Version
24
+ version: 0.0.0
25
+ version:
26
+ platform: ruby
27
+ signing_key:
28
+ cert_chain:
29
+ post_install_message:
30
+ authors:
31
+ - Ryan Davis
32
+ files:
33
+ - History.txt
34
+ - Manifest.txt
35
+ - README.txt
36
+ - Rakefile
37
+ - bin/graphviz_r
38
+ - lib/graphviz_r.rb
39
+ - test/test_graphviz_r.rb
40
+ test_files:
41
+ - test/test_graphviz_r.rb
42
+ rdoc_options: []
43
+ extra_rdoc_files: []
44
+ executables:
45
+ - graphviz_r
46
+ extensions: []
47
+ requirements: []
48
+ dependencies:
49
+ - !ruby/object:Gem::Dependency
50
+ name: hoe
51
+ version_requirement:
52
+ version_requirements: !ruby/object:Gem::Version::Requirement
53
+ requirements:
54
+ -
55
+ - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: 1.1.6
58
+ version: