ruby-graphviz 0.9.7 → 0.9.8
Sign up to get free protection for your applications and to get access to all the features.
- data/AUTHORS +2 -0
- data/ChangeLog.rdoc +9 -0
- data/README.rdoc +11 -0
- data/bin/gem2gv +166 -0
- data/bin/ruby2gv +76 -33
- data/examples/HTML-Labels.rb +8 -1
- data/examples/dot/hello_test.rb +1 -1
- data/examples/maketest.bat +94 -0
- data/examples/maketest.sh +10 -0
- data/examples/sample01.rb +1 -1
- data/examples/sample28.rb +12 -0
- data/examples/sample29.rb +8 -0
- data/examples/sample30.rb +12 -0
- data/examples/sdlshapes/README +2 -0
- data/examples/sdlshapes/sdl.ps +655 -0
- data/examples/sdlshapes/sdlshapes.dot +78 -0
- data/examples/testxml.rb +1 -1
- data/lib/graphviz.rb +43 -18
- data/lib/graphviz/attrs.rb +5 -4
- data/lib/graphviz/constants.rb +184 -151
- data/lib/graphviz/edge.rb +2 -2
- data/lib/graphviz/node.rb +10 -4
- data/lib/graphviz/parser.rb +15 -0
- data/lib/graphviz/types.rb +21 -0
- data/lib/graphviz/types/esc_string.rb +29 -0
- data/lib/graphviz/types/html_string.rb +16 -0
- data/lib/graphviz/xml.rb +1 -1
- data/test/test_init.rb +46 -0
- metadata +15 -2
data/AUTHORS
CHANGED
data/ChangeLog.rdoc
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
0.9.8 :
|
2
|
+
* Update graph and node posibility to set properties (see sample28.rb)
|
3
|
+
* Issue #7: Path option is never being used to find the executable
|
4
|
+
* Adding classes to check if the attributes are in the correct type
|
5
|
+
* Issue #8: dots in href are escaped with backslash, which corrupts the URL (see sample29.rb)
|
6
|
+
* Add posibility to use external libraries (see sample30.rb)
|
7
|
+
* Add options -u and -s to ruby2gv
|
8
|
+
* Add gem2gv
|
9
|
+
|
1
10
|
0.9.7 :
|
2
11
|
* Issue #2: Small bug correction in escape_path_containing_blanks (by Andreas Ronge)
|
3
12
|
* Issue #4: New find_executable (by reactive)
|
data/README.rdoc
CHANGED
@@ -4,6 +4,7 @@ Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Gregoire Lejeune
|
|
4
4
|
|
5
5
|
* Doc : http://rdoc.info/projects/glejeune/Ruby-Graphviz
|
6
6
|
* Sources : http://github.com/glejeune/Ruby-Graphviz
|
7
|
+
* Continuous Integration : http://runcoderun.com/glejeune/Ruby-Graphviz
|
7
8
|
|
8
9
|
== DESCRIPTION
|
9
10
|
|
@@ -52,6 +53,16 @@ Create a graph from a file
|
|
52
53
|
}
|
53
54
|
}.output(:png => "sample.png")
|
54
55
|
|
56
|
+
Ruby/GraphViz also include :
|
57
|
+
|
58
|
+
* ruby2gv, a simple tool that's allow you to create a dependency graph from a ruby script. Example : http://drp.ly/dShaZ
|
59
|
+
|
60
|
+
ruby2gv -Tpng -oruby2gv.png ruby2gv
|
61
|
+
|
62
|
+
* gem2gv, a tools that's allow you to create a dependency graph between gems. Example : http://drp.ly/dSj9Y
|
63
|
+
|
64
|
+
gem2gv -Tpng -oruby-graphviz.png ruby-graphviz
|
65
|
+
|
55
66
|
== INSTALLATION
|
56
67
|
|
57
68
|
sudo gem install ruby-graphviz
|
data/bin/gem2gv
ADDED
@@ -0,0 +1,166 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Copyright (C) 2010 Gregoire Lejeune <gregoire.lejeune@free.fr>
|
3
|
+
#
|
4
|
+
# This program is free software; you can redistribute it and/or modify
|
5
|
+
# it under the terms of the GNU General Public License as published by
|
6
|
+
# the Free Software Foundation; either version 2 of the License, or
|
7
|
+
# (at your option) any later version.
|
8
|
+
#
|
9
|
+
# This program is distributed in the hope that it will be useful,
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
# GNU General Public License for more details.
|
13
|
+
#
|
14
|
+
# You should have received a copy of the GNU General Public License
|
15
|
+
# along with this program; if not, write to the Free Software
|
16
|
+
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
17
|
+
|
18
|
+
require 'rubygems'
|
19
|
+
require 'graphviz'
|
20
|
+
require 'getoptlong'
|
21
|
+
|
22
|
+
class Gem2Gv
|
23
|
+
def initialize( xGVPath, xUse )
|
24
|
+
@oGraph = GraphViz::new( :G, :path => xGVPath, :use => xUse )
|
25
|
+
|
26
|
+
@nodes = []
|
27
|
+
@name = 'gem2gv'
|
28
|
+
end
|
29
|
+
|
30
|
+
def out( xFormat = "dot", xFile = nil )
|
31
|
+
if xFile.nil? == true
|
32
|
+
@oGraph.output( xFormat => String )
|
33
|
+
else
|
34
|
+
@oGraph.output( xFormat => xFile )
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def go( gemName, version = ">0" )
|
39
|
+
nodes = getDependency(gemName, version)
|
40
|
+
|
41
|
+
createEdges( gemName, version, nodes )
|
42
|
+
|
43
|
+
nodes.each do |node|
|
44
|
+
unless @nodes.include?(node)
|
45
|
+
@nodes << node
|
46
|
+
go( node[:name], node[:version] )
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def getDependency( gemName, version = ">0" )
|
52
|
+
nodes = []
|
53
|
+
|
54
|
+
dependency = Gem::Dependency.new( gemName, version )
|
55
|
+
fetcher = Gem::SpecFetcher.fetcher
|
56
|
+
|
57
|
+
fetcher.find_matching(dependency).each do |spec_tuple, source_uri|
|
58
|
+
spec = fetcher.fetch_spec spec_tuple, URI.parse(source_uri)
|
59
|
+
|
60
|
+
spec.dependencies.each do |dep|
|
61
|
+
#nodes << { :name => dep.name, :version => dep.version_requirements.to_s} unless nodes.include?({ :name => dep.name, :version => dep.version_requirements.to_s})
|
62
|
+
nodes << { :name => dep.name, :version => ">0" } unless nodes.include?({ :name => dep.name, :version => ">0" })
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
return nodes
|
67
|
+
end
|
68
|
+
|
69
|
+
def getNode( name, version )
|
70
|
+
#nodeName = "#{name}#{version}"
|
71
|
+
#nodeLabel = "#{name}\n#{version}"
|
72
|
+
nodeName = "#{name}"
|
73
|
+
nodeLabel = "#{name}"
|
74
|
+
return @oGraph.get_node(nodeName) || @oGraph.add_node( nodeName, "label" => nodeLabel )
|
75
|
+
end
|
76
|
+
|
77
|
+
def createEdges( gemName, version, nodes )
|
78
|
+
nodeA = getNode( gemName, version )
|
79
|
+
|
80
|
+
nodes.each do |node|
|
81
|
+
nodeB = getNode( node[:name], node[:version] )
|
82
|
+
@oGraph.add_edge( nodeA, nodeB )
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def usage
|
88
|
+
puts "usage: gem2gv [-Tformat] [-ofile] [-h] [-V] gemname"
|
89
|
+
puts "-T, --output-format format Output format (default: PNG)"
|
90
|
+
puts "-o, --output-file file Output file (default: STDOUT)"
|
91
|
+
puts "-p, --path Graphviz path"
|
92
|
+
puts "-u, --use PROGRAM Program to use (default: dot)"
|
93
|
+
puts "-s, --stop LIB[,LIB, ...] Stop on libs"
|
94
|
+
puts "-V, --version Show version"
|
95
|
+
puts "-h, --help Show this usage message"
|
96
|
+
end
|
97
|
+
|
98
|
+
def version
|
99
|
+
puts "Gem2GraphViz v#{Constants::RGV_VERSION}, (c)2010 Gregoire Lejeune <gregoire.lejeune@free.fr>"
|
100
|
+
puts ""
|
101
|
+
puts "This program is free software; you can redistribute it and/or modify"
|
102
|
+
puts "it under the terms of the GNU General Public License as published by"
|
103
|
+
puts "the Free Software Foundation; either version 2 of the License, or"
|
104
|
+
puts "(at your option) any later version."
|
105
|
+
puts ""
|
106
|
+
puts "This program is distributed in the hope that it will be useful,"
|
107
|
+
puts "but WITHOUT ANY WARRANTY; without even the implied warranty of"
|
108
|
+
puts "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the"
|
109
|
+
puts "GNU General Public License for more details."
|
110
|
+
puts ""
|
111
|
+
puts "You should have received a copy of the GNU General Public License"
|
112
|
+
puts "along with this program; if not, write to the Free Software"
|
113
|
+
puts "Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA"
|
114
|
+
end
|
115
|
+
|
116
|
+
xOutFormat = "png"
|
117
|
+
xOutFile = nil
|
118
|
+
xGVPath = ""
|
119
|
+
xUse = "dot"
|
120
|
+
xStops = []
|
121
|
+
|
122
|
+
oOpt = GetoptLong.new(
|
123
|
+
['--output-format', '-T', GetoptLong::REQUIRED_ARGUMENT],
|
124
|
+
['--output-file', '-o', GetoptLong::REQUIRED_ARGUMENT],
|
125
|
+
['--path', '-p', GetoptLong::REQUIRED_ARGUMENT],
|
126
|
+
['--use', '-u', GetoptLong::REQUIRED_ARGUMENT],
|
127
|
+
['--help', '-h', GetoptLong::NO_ARGUMENT],
|
128
|
+
['--version', '-V', GetoptLong::NO_ARGUMENT]
|
129
|
+
)
|
130
|
+
|
131
|
+
begin
|
132
|
+
oOpt.each_option do |xOpt, xValue|
|
133
|
+
case xOpt
|
134
|
+
when '--output-format'
|
135
|
+
xOutFormat = xValue
|
136
|
+
when '--output-file'
|
137
|
+
xOutFile = xValue
|
138
|
+
when '--path'
|
139
|
+
xGVPath = xValue
|
140
|
+
when '--use'
|
141
|
+
xUse = xValue
|
142
|
+
when '--help'
|
143
|
+
usage( )
|
144
|
+
exit
|
145
|
+
when '--version'
|
146
|
+
version( )
|
147
|
+
exit
|
148
|
+
end
|
149
|
+
end
|
150
|
+
rescue GetoptLong::InvalidOption => e
|
151
|
+
usage( )
|
152
|
+
exit
|
153
|
+
end
|
154
|
+
|
155
|
+
xGem = ARGV[0]
|
156
|
+
|
157
|
+
if xGem.nil? == true
|
158
|
+
usage( )
|
159
|
+
exit
|
160
|
+
end
|
161
|
+
|
162
|
+
|
163
|
+
g = Gem2Gv.new( xGVPath, xUse )
|
164
|
+
g.go( xGem )
|
165
|
+
result = g.out( xOutFormat, xOutFile )
|
166
|
+
puts result unless result.nil?
|
data/bin/ruby2gv
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
# Copyright (C) 2005, 2006, 2007 Gregoire Lejeune <gregoire.lejeune@free.fr>
|
2
|
+
# Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Gregoire Lejeune <gregoire.lejeune@free.fr>
|
3
3
|
#
|
4
4
|
# This program is free software; you can redistribute it and/or modify
|
5
5
|
# it under the terms of the GNU General Public License as published by
|
@@ -15,26 +15,29 @@
|
|
15
15
|
# along with this program; if not, write to the Free Software
|
16
16
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
17
17
|
|
18
|
+
require 'rubygems'
|
18
19
|
require 'getoptlong'
|
19
20
|
require 'graphviz'
|
20
|
-
require
|
21
|
+
require 'graphviz/constants'
|
21
22
|
require 'rbconfig'
|
23
|
+
require 'mkmf'
|
22
24
|
|
23
25
|
DEBUG = false
|
24
26
|
|
25
27
|
class Rb2Gv
|
26
|
-
REQUIRE = /^\s*require\s*("|')([^\1]*)(\1)/
|
28
|
+
REQUIRE = /^\s*require\s*("|')([^\1\s]*)(\1)/
|
27
29
|
|
28
|
-
def initialize( xGVPath )
|
29
|
-
@oGraph = GraphViz::new( "G", :path => xGVPath )
|
30
|
-
@oGraph['size'] = '10,10'
|
30
|
+
def initialize( xGVPath, xUse = "dot", xStops = [] )
|
31
|
+
@oGraph = GraphViz::new( "G", :path => xGVPath, :use => xUse )
|
32
|
+
# @oGraph['size'] = '10,10'
|
31
33
|
@hxNodes = Hash::new( )
|
32
|
-
@hxEdge =
|
34
|
+
@hxEdge = Array::new( )
|
35
|
+
@lxStops = xStops
|
33
36
|
end
|
34
37
|
|
35
38
|
public
|
36
39
|
def parse( xFile )
|
37
|
-
@hxNodes[xFile] = gv_newNode( xFile )
|
40
|
+
@hxNodes[xFile] = gv_newNode( xFile, "box", "forestgreen" )
|
38
41
|
puts "+ Node #{xFile}" if DEBUG
|
39
42
|
|
40
43
|
parseFile( xFile, nil, xFile )
|
@@ -42,14 +45,14 @@ class Rb2Gv
|
|
42
45
|
|
43
46
|
def out( xFormat = "dot", xFile = nil )
|
44
47
|
if xFile.nil? == true
|
45
|
-
@oGraph.output(
|
48
|
+
@oGraph.output( xFormat => String )
|
46
49
|
else
|
47
|
-
@oGraph.output(
|
50
|
+
@oGraph.output( xFormat => xFile )
|
48
51
|
end
|
49
52
|
end
|
50
53
|
|
51
54
|
private
|
52
|
-
def gv_newNode( xNode, xShape = "box", xColor = nil )
|
55
|
+
def gv_newNode( xNode, xShape = "box", xColor = nil )
|
53
56
|
xNodeName = xNode.gsub( /[^a-zA-Z0-9]/, "_" )
|
54
57
|
if xColor.nil? == true
|
55
58
|
@oGraph.add_node( xNodeName, "label" => xNode, "shape" => xShape )
|
@@ -58,20 +61,43 @@ class Rb2Gv
|
|
58
61
|
end
|
59
62
|
end
|
60
63
|
|
61
|
-
def getLibraryPath( xLib, xExt = "rb" )
|
64
|
+
def getLibraryPath( xLib, xExt = ["rb"] )
|
65
|
+
|
62
66
|
xPath = [ "libexecdir", "libdir", "sitedir", "rubylibdir", "sitelibdir", "archdir", "sitedir", "sitearchdir" ]
|
63
67
|
xRbLib = with_config( xLib+'lib', xLib)
|
64
|
-
|
65
|
-
|
68
|
+
|
69
|
+
if /\.(rb|so|bundle|dll)$/.match( xRbLib )
|
70
|
+
match = /^(.*)\.([^\.]*)$/.match(xRbLib)
|
71
|
+
xRbFile, xExt = match[1], [match[2]]
|
66
72
|
else
|
67
|
-
xRbFile = xRbLib
|
73
|
+
xRbFile = xRbLib
|
68
74
|
end
|
69
75
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
76
|
+
xExt.each do |e|
|
77
|
+
xRbFileWithExt = xRbFile + "." + e
|
78
|
+
|
79
|
+
# Search in "standard" paths
|
80
|
+
xPath.each do |xDir|
|
81
|
+
xCurrentPath = Config::expand( Config::CONFIG[xDir] )
|
82
|
+
xFileFound = File.join( xCurrentPath, xRbFileWithExt )
|
83
|
+
if File.exist?( xFileFound )
|
84
|
+
return xFileFound
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# Search in "rubygems" :: This is not utile but...
|
89
|
+
spec = Gem.searcher.find(xLib)
|
90
|
+
unless spec.nil?
|
91
|
+
spec.require_paths.unshift spec.bindir if spec.bindir
|
92
|
+
xPath = spec.require_paths.map do |path|
|
93
|
+
File.join spec.full_gem_path, path
|
94
|
+
end
|
95
|
+
xPath.each do |xCurrentPath|
|
96
|
+
xFileFound = File.join( xCurrentPath, xRbFileWithExt )
|
97
|
+
if File.exist?( xFileFound )
|
98
|
+
return xFileFound
|
99
|
+
end
|
100
|
+
end
|
75
101
|
end
|
76
102
|
end
|
77
103
|
|
@@ -92,28 +118,34 @@ class Rb2Gv
|
|
92
118
|
|
93
119
|
xData.each do |xLine|
|
94
120
|
if lxLineMatch = REQUIRE.match( xLine )
|
95
|
-
xRequiredLib = lxLineMatch[2]
|
121
|
+
xRequiredLib = lxLineMatch[2].gsub( /\.(rb|so)$/, "" )
|
96
122
|
|
97
123
|
if @hxNodes.has_key?( xRequiredLib ) == false
|
98
124
|
puts " + Node #{xRequiredLib}" if DEBUG
|
99
125
|
|
100
126
|
xRequiredFile = getLibraryPath( xRequiredLib )
|
101
127
|
if xRequiredFile.nil? == false
|
102
|
-
@
|
103
|
-
|
128
|
+
unless @lxStops.include?(xRequiredLib)
|
129
|
+
@hxNodes[xRequiredLib] = gv_newNode( xRequiredLib )
|
130
|
+
parseFile( xRequiredFile, xFile, xRequiredLib )
|
131
|
+
else
|
132
|
+
@hxNodes[xRequiredLib] = gv_newNode( xRequiredLib, "invhouse", "deepskyblue" )
|
133
|
+
end
|
104
134
|
else
|
105
|
-
if getLibraryPath( xRequiredLib, "so" )
|
106
|
-
@hxNodes[xRequiredLib] = gv_newNode( xRequiredLib, "
|
135
|
+
if (v = getLibraryPath( xRequiredLib, ["so", "bundle", "dll"] )) == nil
|
136
|
+
@hxNodes[xRequiredLib] = gv_newNode( xRequiredLib, "box", "red" )
|
107
137
|
else
|
108
|
-
@hxNodes[xRequiredLib] = gv_newNode( xRequiredLib, "
|
138
|
+
@hxNodes[xRequiredLib] = gv_newNode( xRequiredLib, "box", "grey" )
|
109
139
|
end
|
110
140
|
end
|
111
141
|
|
112
142
|
end
|
113
143
|
|
114
144
|
puts " + Edge #{xLib} -> #{xRequiredLib}" if DEBUG
|
115
|
-
@
|
116
|
-
|
145
|
+
unless @hxEdge.include?( "#{@hxNodes[xLib].name}-#{@hxNodes[xRequiredLib].name}" )
|
146
|
+
@oGraph.add_edge( @hxNodes[xLib], @hxNodes[xRequiredLib] )
|
147
|
+
@hxEdge << "#{@hxNodes[xLib].name}-#{@hxNodes[xRequiredLib].name}"
|
148
|
+
end
|
117
149
|
end
|
118
150
|
end
|
119
151
|
|
@@ -122,16 +154,18 @@ class Rb2Gv
|
|
122
154
|
end
|
123
155
|
|
124
156
|
def usage
|
125
|
-
puts "usage: ruby2gv
|
157
|
+
puts "usage: ruby2gv [-Tformat] [-ofile] [-h] [-V] script"
|
126
158
|
puts "-T, --output-format format Output format (default: PNG)"
|
127
159
|
puts "-o, --output-file file Output file (default: STDOUT)"
|
128
160
|
puts "-p, --path Graphviz path"
|
161
|
+
puts "-u, --use PROGRAM Program to use (default: dot)"
|
162
|
+
puts "-s, --stop LIB[,LIB, ...] Stop on libs"
|
129
163
|
puts "-V, --version Show version"
|
130
164
|
puts "-h, --help Show this usage message"
|
131
165
|
end
|
132
166
|
|
133
167
|
def version
|
134
|
-
puts "Ruby2GraphViz v#{Constants::RGV_VERSION}, (c)2005 Gregoire Lejeune <gregoire.lejeune@free.fr>"
|
168
|
+
puts "Ruby2GraphViz v#{Constants::RGV_VERSION}, (c)2005, 2009, 2010 Gregoire Lejeune <gregoire.lejeune@free.fr>"
|
135
169
|
puts ""
|
136
170
|
puts "This program is free software; you can redistribute it and/or modify"
|
137
171
|
puts "it under the terms of the GNU General Public License as published by"
|
@@ -150,12 +184,16 @@ end
|
|
150
184
|
|
151
185
|
xOutFormat = "png"
|
152
186
|
xOutFile = nil
|
153
|
-
xGVPath =
|
187
|
+
xGVPath = ""
|
188
|
+
xUse = "dot"
|
189
|
+
xStops = []
|
154
190
|
|
155
191
|
oOpt = GetoptLong.new(
|
156
192
|
['--output-format', '-T', GetoptLong::REQUIRED_ARGUMENT],
|
157
193
|
['--output-file', '-o', GetoptLong::REQUIRED_ARGUMENT],
|
158
194
|
['--path', '-p', GetoptLong::REQUIRED_ARGUMENT],
|
195
|
+
['--use', '-u', GetoptLong::REQUIRED_ARGUMENT],
|
196
|
+
['--stop', '-s', GetoptLong::REQUIRED_ARGUMENT],
|
159
197
|
['--help', '-h', GetoptLong::NO_ARGUMENT],
|
160
198
|
['--version', '-V', GetoptLong::NO_ARGUMENT]
|
161
199
|
)
|
@@ -169,6 +207,10 @@ begin
|
|
169
207
|
xOutFile = xValue
|
170
208
|
when '--path'
|
171
209
|
xGVPath = xValue
|
210
|
+
when '--use'
|
211
|
+
xUse = xValue
|
212
|
+
when '--stop'
|
213
|
+
xStops = xValue.split( "," ).map{ |x| x.strip }
|
172
214
|
when '--help'
|
173
215
|
usage( )
|
174
216
|
exit
|
@@ -189,6 +231,7 @@ if xFile.nil? == true
|
|
189
231
|
exit
|
190
232
|
end
|
191
233
|
|
192
|
-
o = Rb2Gv::new( xGVPath )
|
234
|
+
o = Rb2Gv::new( xGVPath, xUse, xStops )
|
193
235
|
o.parse( xFile )
|
194
|
-
o.out( xOutFormat, xOutFile )
|
236
|
+
result = o.out( xOutFormat, xOutFile )
|
237
|
+
puts result unless result.nil?
|
data/examples/HTML-Labels.rb
CHANGED
@@ -7,7 +7,14 @@ g.node["shape"] = "plaintext"
|
|
7
7
|
|
8
8
|
g.add_node( "HTML" )
|
9
9
|
|
10
|
-
g.add_node( "struct1", "html" => '
|
10
|
+
g.add_node( "struct1", "html" => '
|
11
|
+
<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
|
12
|
+
<TR>
|
13
|
+
<TD>left</TD>
|
14
|
+
<TD PORT="f1">mid dle</TD>
|
15
|
+
<TD PORT="f2">right</TD>
|
16
|
+
</TR>
|
17
|
+
</TABLE>' )
|
11
18
|
|
12
19
|
g.add_node( "struct2", "html" => '<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0"> <TR><TD PORT="f0">one</TD><TD>two</TD></TR> </TABLE>' )
|
13
20
|
g.add_node( "struct3", "html" => '<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" CELLPADDING="4"> <TR> <TD ROWSPAN="3">hello<BR/>world</TD> <TD COLSPAN="3">b</TD> <TD ROWSPAN="3">g</TD> <TD ROWSPAN="3">h</TD> </TR> <TR> <TD>c</TD><TD PORT="here">d</TD><TD>e</TD> </TR> <TR> <TD COLSPAN="3">f</TD> </TR> </TABLE>' )
|
data/examples/dot/hello_test.rb
CHANGED