ruby-graphviz 0.9.15 → 0.9.16
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.
- data/README.rdoc +10 -1
- data/bin/xml2gv +96 -0
- data/examples/dot/cluster.dot +0 -1
- data/examples/dot/hello_test.rb +21 -2
- data/examples/dot/test_parse.rb +1 -1
- data/examples/sample38.rb +1 -0
- data/lib/ext/gvpr/dot2ruby.g +2 -2
- data/lib/graphviz.rb +8 -31
- data/lib/graphviz/attrs.rb +10 -0
- data/lib/graphviz/constants.rb +1 -1
- data/lib/graphviz/edge.rb +19 -13
- data/lib/src/html_string_parser.gv +43 -0
- data/lib/src/html_string_parser.rb +422 -0
- data/lib/src/html_string_parser.rl +43 -0
- metadata +11 -21
- data/lib/graphviz/dot.treetop +0 -101
- data/lib/graphviz/parser.rb +0 -288
data/README.rdoc
CHANGED
@@ -12,11 +12,18 @@ Interface to the GraphViz graphing tool
|
|
12
12
|
|
13
13
|
== TODO
|
14
14
|
|
15
|
-
* GraphViz::Parser support block
|
16
15
|
* New FamilyTree
|
17
16
|
|
18
17
|
== CHANGELOG
|
19
18
|
|
19
|
+
=== 0.9.16 :
|
20
|
+
* Add <tt>xml2gv</tt>
|
21
|
+
* Rename <tt>GraphViz.parser2</tt> to <tt>GraphViz.parser</tt>
|
22
|
+
* Remove treetop dependency
|
23
|
+
* Ruby 1.9 (and MacRuby) compatibility -- Issue #12: see sample38.rb
|
24
|
+
* Add GraphViz::Attrs#each and GraphViz::Attrs#to_h
|
25
|
+
* Add GraphViz::Edge#node_one and GraphViz::Edge#node_two
|
26
|
+
|
20
27
|
=== 0.9.15 :
|
21
28
|
* Add <tt>GraphViz.parser2</tt>. <b>WARNING</b> this method will replace <tt>GraphViz.parser</tt>. So please don't use it, or only for testing.
|
22
29
|
* Bug correction in <tt>dot2ruby</tt>
|
@@ -261,6 +268,8 @@ Ruby/GraphViz also include :
|
|
261
268
|
|
262
269
|
* <tt>git2gv</tt>, a tools that's allow you to show your git commits : http://dl.dropbox.com/u/72629/ruby-graphviz-git.svg
|
263
270
|
|
271
|
+
* <tt>xml2gv</tt>, a tools that's allow you to show a xml file as graph.
|
272
|
+
|
264
273
|
== INSTALLATION
|
265
274
|
|
266
275
|
sudo gem install ruby-graphviz
|
data/bin/xml2gv
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Copyright (C) 2005, 2006, 2007, 2008, 2009, 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 'getoptlong'
|
20
|
+
require 'graphviz/xml'
|
21
|
+
|
22
|
+
def usage
|
23
|
+
puts "usage: xml2gv [-Tformat] [-ofile] [-h] [-V] script"
|
24
|
+
puts "-T, --output-format format Output format (default: PNG)"
|
25
|
+
puts "-o, --output-file file Output file (default: STDOUT)"
|
26
|
+
puts "-p, --path Graphviz path"
|
27
|
+
puts "-u, --use PROGRAM Program to use (default: dot)"
|
28
|
+
puts "-V, --version Show version"
|
29
|
+
puts "-h, --help Show this usage message"
|
30
|
+
end
|
31
|
+
|
32
|
+
def version
|
33
|
+
puts "XML2GraphViz v#{Constants::RGV_VERSION}, (c)2010 Gregoire Lejeune <gregoire.lejeune@free.fr>"
|
34
|
+
puts ""
|
35
|
+
puts "This program is free software; you can redistribute it and/or modify"
|
36
|
+
puts "it under the terms of the GNU General Public License as published by"
|
37
|
+
puts "the Free Software Foundation; either version 2 of the License, or"
|
38
|
+
puts "(at your option) any later version."
|
39
|
+
puts ""
|
40
|
+
puts "This program is distributed in the hope that it will be useful,"
|
41
|
+
puts "but WITHOUT ANY WARRANTY; without even the implied warranty of"
|
42
|
+
puts "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the"
|
43
|
+
puts "GNU General Public License for more details."
|
44
|
+
puts ""
|
45
|
+
puts "You should have received a copy of the GNU General Public License"
|
46
|
+
puts "along with this program; if not, write to the Free Software"
|
47
|
+
puts "Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA"
|
48
|
+
end
|
49
|
+
|
50
|
+
xOutFormat = "png"
|
51
|
+
xOutFile = nil
|
52
|
+
xGVPath = ""
|
53
|
+
xUse = "dot"
|
54
|
+
|
55
|
+
oOpt = GetoptLong.new(
|
56
|
+
['--output-format', '-T', GetoptLong::REQUIRED_ARGUMENT],
|
57
|
+
['--output-file', '-o', GetoptLong::REQUIRED_ARGUMENT],
|
58
|
+
['--path', '-p', GetoptLong::REQUIRED_ARGUMENT],
|
59
|
+
['--use', '-u', GetoptLong::REQUIRED_ARGUMENT],
|
60
|
+
['--help', '-h', GetoptLong::NO_ARGUMENT],
|
61
|
+
['--version', '-V', GetoptLong::NO_ARGUMENT]
|
62
|
+
)
|
63
|
+
|
64
|
+
begin
|
65
|
+
oOpt.each_option do |xOpt, xValue|
|
66
|
+
case xOpt
|
67
|
+
when '--output-format'
|
68
|
+
xOutFormat = xValue
|
69
|
+
when '--output-file'
|
70
|
+
xOutFile = xValue
|
71
|
+
when '--path'
|
72
|
+
xGVPath = xValue
|
73
|
+
when '--use'
|
74
|
+
xUse = xValue
|
75
|
+
when '--help'
|
76
|
+
usage( )
|
77
|
+
exit
|
78
|
+
when '--version'
|
79
|
+
version( )
|
80
|
+
exit
|
81
|
+
end
|
82
|
+
end
|
83
|
+
rescue GetoptLong::InvalidOption => e
|
84
|
+
usage( )
|
85
|
+
exit
|
86
|
+
end
|
87
|
+
|
88
|
+
xFile = ARGV[0]
|
89
|
+
|
90
|
+
if xFile.nil? == true
|
91
|
+
usage( )
|
92
|
+
exit
|
93
|
+
end
|
94
|
+
|
95
|
+
gvxml = GraphViz::XML::new( xFile, :text => true, :attrs => true )
|
96
|
+
gvxml.output( xOutFormat => xOutFile, :path => xGVPath )
|
data/examples/dot/cluster.dot
CHANGED
data/examples/dot/hello_test.rb
CHANGED
@@ -3,12 +3,31 @@
|
|
3
3
|
$:.unshift( "../../lib" );
|
4
4
|
require "graphviz"
|
5
5
|
|
6
|
-
GraphViz.
|
6
|
+
g = GraphViz.parse( "hello.dot", :path => "/usr/local/bin" ) { |g|
|
7
|
+
g.graph[:color] = "blue"
|
8
|
+
g.node[:color] = "red"
|
9
|
+
g.edge[:color] = "yellow"
|
7
10
|
g.get_node("Hello") { |n|
|
8
11
|
n.label = "Bonjour"
|
9
12
|
}
|
10
13
|
g.get_node("World") { |n|
|
11
14
|
n.label = "Le Monde"
|
12
15
|
}
|
13
|
-
}
|
16
|
+
}
|
17
|
+
|
18
|
+
g.graph.each do |k, v|
|
19
|
+
puts "graph : #{k} => #{v}"
|
20
|
+
end
|
21
|
+
|
22
|
+
g.node.each do |k, v|
|
23
|
+
puts "node : #{k} => #{v}"
|
24
|
+
end
|
25
|
+
|
26
|
+
g.edge.each do |k, v|
|
27
|
+
puts "edge : #{k} => #{v}"
|
28
|
+
end
|
29
|
+
|
30
|
+
puts "-----------"
|
31
|
+
|
32
|
+
puts g.output(:none => String)
|
14
33
|
|
data/examples/dot/test_parse.rb
CHANGED
data/examples/sample38.rb
CHANGED
data/lib/ext/gvpr/dot2ruby.g
CHANGED
@@ -114,7 +114,7 @@ N {
|
|
114
114
|
while( attr != "" ) {
|
115
115
|
attrv = aget( $, attr );
|
116
116
|
if( attrv != "" ) {
|
117
|
-
printf( ", :%s => '%s'", attr, attrv );
|
117
|
+
printf( ", :%s => '%s'", attr, gsub( attrv, "'", "\\'" ) );
|
118
118
|
} else {
|
119
119
|
printf( ", :%s => ''", attr );
|
120
120
|
}
|
@@ -143,7 +143,7 @@ E {
|
|
143
143
|
while( attr != "" ) {
|
144
144
|
attrv = aget( $, attr );
|
145
145
|
if( attrv != "" ) {
|
146
|
-
printf( ", :%s => '%s'", attr, attrv );
|
146
|
+
printf( ", :%s => '%s'", attr, gsub( attrv, "'", "\\'" ) );
|
147
147
|
} else {
|
148
148
|
printf( ", :%s => ''", attr );
|
149
149
|
}
|
data/lib/graphviz.rb
CHANGED
@@ -26,14 +26,13 @@ require 'graphviz/edge'
|
|
26
26
|
require 'graphviz/attrs'
|
27
27
|
require 'graphviz/constants'
|
28
28
|
|
29
|
-
# --> WILL BE REMOVED
|
30
|
-
require 'graphviz/parser'
|
31
|
-
|
32
29
|
require 'graphviz/dot2ruby'
|
33
30
|
require 'graphviz/types'
|
34
31
|
require 'graphviz/core_ext'
|
35
32
|
|
36
|
-
|
33
|
+
if /^1.8/.match RUBY_VERSION
|
34
|
+
$KCODE = "UTF8"
|
35
|
+
end
|
37
36
|
|
38
37
|
class GraphViz
|
39
38
|
include Constants
|
@@ -71,12 +70,15 @@ class GraphViz
|
|
71
70
|
|
72
71
|
# This accessor allow you to set global graph attributs
|
73
72
|
attr_accessor :graph
|
73
|
+
alias_method :graph_attrs, :graph
|
74
74
|
|
75
75
|
# This accessor allow you to set global nodes attributs
|
76
76
|
attr_accessor :node
|
77
|
+
alias_method :node_attrs, :node
|
77
78
|
|
78
79
|
# This accessor allow you to set global edges attributs
|
79
80
|
attr_accessor :edge
|
81
|
+
alias_method :edge_attrs, :edge
|
80
82
|
|
81
83
|
@elements_order
|
82
84
|
|
@@ -440,7 +442,7 @@ class GraphViz
|
|
440
442
|
|
441
443
|
@output = hOutput if hOutput.size > 0
|
442
444
|
|
443
|
-
xDOTScript = ("#{@oGraphType} #{GraphViz.escape(@name)} {\n" << xDOTScript).gsub(
|
445
|
+
xDOTScript = ("#{@oGraphType} #{GraphViz.escape(@name)} {\n" << xDOTScript).gsub( "\0", "" )
|
444
446
|
|
445
447
|
xOutputString = (@filename == String ||
|
446
448
|
@output.any? {|format, file| file == String })
|
@@ -611,29 +613,6 @@ class GraphViz
|
|
611
613
|
|
612
614
|
## ----------------------------------------------------------------------------
|
613
615
|
|
614
|
-
#
|
615
|
-
# Create a new graph from a GraphViz File
|
616
|
-
#
|
617
|
-
# Options :
|
618
|
-
# * :output : Output format (Constants::FORMATS) (default : dot)
|
619
|
-
# * :file : Output file name (default : none)
|
620
|
-
# * :use : Program to use (Constants::PROGRAMS) (default : dot)
|
621
|
-
# * :path : Program PATH
|
622
|
-
# * :parent : Parent graph (default : none)
|
623
|
-
# * :type : Graph type (Constants::GRAPHTYPE) (default : digraph)
|
624
|
-
#
|
625
|
-
def self.parse( xFile, hOpts = {}, &block )
|
626
|
-
# This method will be replaced by parser2.
|
627
|
-
# When it's time, remove
|
628
|
-
# graphviz/parser.rb
|
629
|
-
# graphviz/dot.treetop
|
630
|
-
# and remove line
|
631
|
-
# s.add_dependency('treetop')
|
632
|
-
# in Rakefile
|
633
|
-
g = GraphViz::Parser.parse( xFile, hOpts, &block )
|
634
|
-
return g
|
635
|
-
end
|
636
|
-
|
637
616
|
#
|
638
617
|
# Create a new graph from a GraphViz File
|
639
618
|
#
|
@@ -643,9 +622,7 @@ class GraphViz
|
|
643
622
|
# * :use : Program to use (Constants::PROGRAMS) (default : dot)
|
644
623
|
# * :path : Program PATH
|
645
624
|
#
|
646
|
-
|
647
|
-
#
|
648
|
-
def self.parse2( xFile, hOpts = {}, &block )
|
625
|
+
def self.parse( xFile, hOpts = {}, &block )
|
649
626
|
graph = Dot2Ruby::new( hOpts[:path], nil, nil ).eval( xFile )
|
650
627
|
yield( graph ) if( block and graph.nil? == false )
|
651
628
|
return graph
|
data/lib/graphviz/attrs.rb
CHANGED
data/lib/graphviz/constants.rb
CHANGED
data/lib/graphviz/edge.rb
CHANGED
@@ -54,6 +54,24 @@ class GraphViz
|
|
54
54
|
@oAttrEdge = GraphViz::Attrs::new( nil, "edge", EDGESATTRS )
|
55
55
|
end
|
56
56
|
|
57
|
+
# Return the node one as string (so with port if any)
|
58
|
+
def node_one
|
59
|
+
if @xNodeOnePort.nil?
|
60
|
+
GraphViz.escape(@xNodeOne)
|
61
|
+
else
|
62
|
+
GraphViz.escape(@xNodeOne, true) + ":#{@xNodeOnePort}"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# Return the node two as string (so with port if any)
|
67
|
+
def node_two
|
68
|
+
if @xNodeTwoPort.nil?
|
69
|
+
GraphViz.escape(@xNodeTwo)
|
70
|
+
else
|
71
|
+
GraphViz.escape(@xNodeTwo, true) + ":#{@xNodeTwoPort}"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
57
75
|
#
|
58
76
|
# Set value +xAttrValue+ to the edge attribut +xAttrName+
|
59
77
|
#
|
@@ -115,19 +133,7 @@ class GraphViz
|
|
115
133
|
xLink = " -- "
|
116
134
|
end
|
117
135
|
|
118
|
-
|
119
|
-
GraphViz.escape(@xNodeOne)
|
120
|
-
else
|
121
|
-
GraphViz.escape(@xNodeOne, true) + ":#{@xNodeOnePort}"
|
122
|
-
end
|
123
|
-
|
124
|
-
xNodeNameTwo = if @xNodeTwoPort.nil?
|
125
|
-
GraphViz.escape(@xNodeTwo)
|
126
|
-
else
|
127
|
-
GraphViz.escape(@xNodeTwo, true) + ":#{@xNodeTwoPort}"
|
128
|
-
end
|
129
|
-
|
130
|
-
xOut = xNodeNameOne + xLink + xNodeNameTwo
|
136
|
+
xOut = self.node_one + xLink + self.node_two
|
131
137
|
xAttr = ""
|
132
138
|
xSeparator = ""
|
133
139
|
@oAttrEdge.data.each do |k, v|
|
@@ -0,0 +1,43 @@
|
|
1
|
+
digraph html_string_lexer {
|
2
|
+
rankdir=LR;
|
3
|
+
node [ shape = point ];
|
4
|
+
ENTRY;
|
5
|
+
en_22;
|
6
|
+
node [ shape = circle, height = 0.2 ];
|
7
|
+
node [ fixedsize = true, height = 0.65, shape = doublecircle ];
|
8
|
+
22;
|
9
|
+
node [ shape = circle ];
|
10
|
+
1 -> 2 [ label = "'/'" ];
|
11
|
+
1 -> 10 [ label = "'B'" ];
|
12
|
+
1 -> 13 [ label = "'F'" ];
|
13
|
+
1 -> 18 [ label = "'b'" ];
|
14
|
+
1 -> 19 [ label = "'f'" ];
|
15
|
+
2 -> 3 [ label = "'F'" ];
|
16
|
+
2 -> 7 [ label = "'f'" ];
|
17
|
+
3 -> 4 [ label = "'O'" ];
|
18
|
+
4 -> 5 [ label = "'N'" ];
|
19
|
+
5 -> 6 [ label = "'T'" ];
|
20
|
+
6 -> 22 [ label = "'>' / last3, initts" ];
|
21
|
+
7 -> 8 [ label = "'o'" ];
|
22
|
+
8 -> 9 [ label = "'n'" ];
|
23
|
+
9 -> 6 [ label = "'t'" ];
|
24
|
+
10 -> 11 [ label = "'R'" ];
|
25
|
+
11 -> 12 [ label = "'\\t'..'\\r', SP" ];
|
26
|
+
11 -> 22 [ label = "'>' / last1, initts" ];
|
27
|
+
12 -> 22 [ label = "'>' / last1, initts" ];
|
28
|
+
12 -> 12 [ label = "DEF" ];
|
29
|
+
13 -> 14 [ label = "'O'" ];
|
30
|
+
14 -> 15 [ label = "'N'" ];
|
31
|
+
15 -> 16 [ label = "'T'" ];
|
32
|
+
16 -> 17 [ label = "'\\t'..'\\r', SP" ];
|
33
|
+
16 -> 22 [ label = "'>' / last2, initts" ];
|
34
|
+
17 -> 22 [ label = "'>' / last2, initts" ];
|
35
|
+
17 -> 17 [ label = "DEF" ];
|
36
|
+
18 -> 11 [ label = "'r'" ];
|
37
|
+
19 -> 20 [ label = "'o'" ];
|
38
|
+
20 -> 21 [ label = "'n'" ];
|
39
|
+
21 -> 16 [ label = "'t'" ];
|
40
|
+
22 -> 1 [ label = "'<' / ts" ];
|
41
|
+
ENTRY -> 22 [ label = "IN" ];
|
42
|
+
en_22 -> 22 [ label = "main" ];
|
43
|
+
}
|
@@ -0,0 +1,422 @@
|
|
1
|
+
|
2
|
+
# line 1 "html_string_parser.rl"
|
3
|
+
|
4
|
+
# line 20 "html_string_parser.rl"
|
5
|
+
|
6
|
+
|
7
|
+
|
8
|
+
# line 9 "html_string_parser.rb"
|
9
|
+
class << self
|
10
|
+
attr_accessor :_html_string_lexer_actions
|
11
|
+
private :_html_string_lexer_actions, :_html_string_lexer_actions=
|
12
|
+
end
|
13
|
+
self._html_string_lexer_actions = [
|
14
|
+
0, 1, 0, 1, 1, 1, 8, 1,
|
15
|
+
9, 2, 2, 3, 2, 2, 4, 2,
|
16
|
+
2, 5, 2, 2, 6, 2, 2, 7
|
17
|
+
]
|
18
|
+
|
19
|
+
class << self
|
20
|
+
attr_accessor :_html_string_lexer_key_offsets
|
21
|
+
private :_html_string_lexer_key_offsets, :_html_string_lexer_key_offsets=
|
22
|
+
end
|
23
|
+
self._html_string_lexer_key_offsets = [
|
24
|
+
0, 1, 1, 6, 8, 9, 10, 11,
|
25
|
+
12, 13, 14, 15, 16, 20, 21, 22,
|
26
|
+
23, 24, 27, 28, 39, 51, 64, 76,
|
27
|
+
88, 100, 112, 113, 114, 115, 116, 117,
|
28
|
+
118, 119
|
29
|
+
]
|
30
|
+
|
31
|
+
class << self
|
32
|
+
attr_accessor :_html_string_lexer_trans_keys
|
33
|
+
private :_html_string_lexer_trans_keys, :_html_string_lexer_trans_keys=
|
34
|
+
end
|
35
|
+
self._html_string_lexer_trans_keys = [
|
36
|
+
60, 47, 66, 70, 98, 102, 70, 102,
|
37
|
+
79, 78, 84, 62, 111, 110, 116, 82,
|
38
|
+
32, 62, 9, 13, 62, 79, 78, 84,
|
39
|
+
32, 9, 13, 62, 60, 95, 97, 99,
|
40
|
+
108, 101, 103, 110, 111, 115, 116, 47,
|
41
|
+
60, 95, 97, 99, 108, 101, 103, 110,
|
42
|
+
111, 115, 116, 60, 70, 95, 97, 99,
|
43
|
+
102, 108, 101, 103, 110, 111, 115, 116,
|
44
|
+
60, 79, 95, 97, 99, 108, 101, 103,
|
45
|
+
110, 111, 115, 116, 60, 78, 95, 97,
|
46
|
+
99, 108, 101, 103, 110, 111, 115, 116,
|
47
|
+
60, 84, 95, 97, 99, 108, 101, 103,
|
48
|
+
110, 111, 115, 116, 60, 62, 95, 97,
|
49
|
+
99, 108, 101, 103, 110, 111, 115, 116,
|
50
|
+
111, 110, 116, 62, 114, 111, 110, 116,
|
51
|
+
0
|
52
|
+
]
|
53
|
+
|
54
|
+
class << self
|
55
|
+
attr_accessor :_html_string_lexer_single_lengths
|
56
|
+
private :_html_string_lexer_single_lengths, :_html_string_lexer_single_lengths=
|
57
|
+
end
|
58
|
+
self._html_string_lexer_single_lengths = [
|
59
|
+
1, 0, 5, 2, 1, 1, 1, 1,
|
60
|
+
1, 1, 1, 1, 2, 1, 1, 1,
|
61
|
+
1, 1, 1, 5, 6, 7, 6, 6,
|
62
|
+
6, 6, 1, 1, 1, 1, 1, 1,
|
63
|
+
1, 1
|
64
|
+
]
|
65
|
+
|
66
|
+
class << self
|
67
|
+
attr_accessor :_html_string_lexer_range_lengths
|
68
|
+
private :_html_string_lexer_range_lengths, :_html_string_lexer_range_lengths=
|
69
|
+
end
|
70
|
+
self._html_string_lexer_range_lengths = [
|
71
|
+
0, 0, 0, 0, 0, 0, 0, 0,
|
72
|
+
0, 0, 0, 0, 1, 0, 0, 0,
|
73
|
+
0, 1, 0, 3, 3, 3, 3, 3,
|
74
|
+
3, 3, 0, 0, 0, 0, 0, 0,
|
75
|
+
0, 0
|
76
|
+
]
|
77
|
+
|
78
|
+
class << self
|
79
|
+
attr_accessor :_html_string_lexer_index_offsets
|
80
|
+
private :_html_string_lexer_index_offsets, :_html_string_lexer_index_offsets=
|
81
|
+
end
|
82
|
+
self._html_string_lexer_index_offsets = [
|
83
|
+
0, 2, 3, 9, 12, 14, 16, 18,
|
84
|
+
20, 22, 24, 26, 28, 32, 34, 36,
|
85
|
+
38, 40, 43, 45, 54, 64, 75, 85,
|
86
|
+
95, 105, 115, 117, 119, 121, 123, 125,
|
87
|
+
127, 129
|
88
|
+
]
|
89
|
+
|
90
|
+
class << self
|
91
|
+
attr_accessor :_html_string_lexer_indicies
|
92
|
+
private :_html_string_lexer_indicies, :_html_string_lexer_indicies=
|
93
|
+
end
|
94
|
+
self._html_string_lexer_indicies = [
|
95
|
+
1, 0, 0, 4, 5, 6, 7, 8,
|
96
|
+
0, 9, 10, 0, 11, 0, 12, 0,
|
97
|
+
13, 0, 14, 0, 15, 0, 16, 0,
|
98
|
+
13, 0, 17, 0, 18, 19, 18, 0,
|
99
|
+
19, 18, 20, 0, 21, 0, 22, 0,
|
100
|
+
23, 23, 0, 24, 23, 26, 0, 0,
|
101
|
+
0, 0, 0, 0, 0, 25, 27, 26,
|
102
|
+
0, 0, 0, 0, 0, 0, 0, 25,
|
103
|
+
26, 28, 0, 0, 0, 29, 0, 0,
|
104
|
+
0, 0, 25, 26, 30, 0, 0, 0,
|
105
|
+
0, 0, 0, 0, 25, 26, 31, 0,
|
106
|
+
0, 0, 0, 0, 0, 0, 25, 26,
|
107
|
+
32, 0, 0, 0, 0, 0, 0, 0,
|
108
|
+
25, 26, 33, 0, 0, 0, 0, 0,
|
109
|
+
0, 0, 25, 34, 0, 35, 0, 36,
|
110
|
+
0, 37, 0, 17, 0, 38, 0, 39,
|
111
|
+
0, 22, 0, 0
|
112
|
+
]
|
113
|
+
|
114
|
+
class << self
|
115
|
+
attr_accessor :_html_string_lexer_trans_targs
|
116
|
+
private :_html_string_lexer_trans_targs, :_html_string_lexer_trans_targs=
|
117
|
+
end
|
118
|
+
self._html_string_lexer_trans_targs = [
|
119
|
+
1, 2, 0, 0, 3, 11, 14, 30,
|
120
|
+
31, 4, 8, 5, 6, 7, 1, 9,
|
121
|
+
10, 12, 13, 1, 15, 16, 17, 18,
|
122
|
+
19, 19, 20, 21, 22, 26, 23, 24,
|
123
|
+
25, 19, 27, 28, 29, 1, 32, 33
|
124
|
+
]
|
125
|
+
|
126
|
+
class << self
|
127
|
+
attr_accessor :_html_string_lexer_trans_actions
|
128
|
+
private :_html_string_lexer_trans_actions, :_html_string_lexer_trans_actions=
|
129
|
+
end
|
130
|
+
self._html_string_lexer_trans_actions = [
|
131
|
+
21, 0, 7, 5, 0, 0, 0, 0,
|
132
|
+
0, 0, 0, 0, 0, 0, 18, 0,
|
133
|
+
0, 0, 0, 9, 0, 0, 0, 0,
|
134
|
+
15, 21, 0, 0, 0, 0, 0, 0,
|
135
|
+
0, 12, 0, 0, 0, 12, 0, 0
|
136
|
+
]
|
137
|
+
|
138
|
+
class << self
|
139
|
+
attr_accessor :_html_string_lexer_to_state_actions
|
140
|
+
private :_html_string_lexer_to_state_actions, :_html_string_lexer_to_state_actions=
|
141
|
+
end
|
142
|
+
self._html_string_lexer_to_state_actions = [
|
143
|
+
1, 0, 0, 0, 0, 0, 0, 0,
|
144
|
+
0, 0, 0, 0, 0, 0, 0, 0,
|
145
|
+
0, 0, 0, 0, 0, 0, 0, 0,
|
146
|
+
0, 0, 0, 0, 0, 0, 0, 0,
|
147
|
+
0, 0
|
148
|
+
]
|
149
|
+
|
150
|
+
class << self
|
151
|
+
attr_accessor :_html_string_lexer_from_state_actions
|
152
|
+
private :_html_string_lexer_from_state_actions, :_html_string_lexer_from_state_actions=
|
153
|
+
end
|
154
|
+
self._html_string_lexer_from_state_actions = [
|
155
|
+
3, 0, 0, 0, 0, 0, 0, 0,
|
156
|
+
0, 0, 0, 0, 0, 0, 0, 0,
|
157
|
+
0, 0, 0, 0, 0, 0, 0, 0,
|
158
|
+
0, 0, 0, 0, 0, 0, 0, 0,
|
159
|
+
0, 0
|
160
|
+
]
|
161
|
+
|
162
|
+
class << self
|
163
|
+
attr_accessor :_html_string_lexer_eof_trans
|
164
|
+
private :_html_string_lexer_eof_trans, :_html_string_lexer_eof_trans=
|
165
|
+
end
|
166
|
+
self._html_string_lexer_eof_trans = [
|
167
|
+
0, 3, 4, 4, 4, 4, 4, 4,
|
168
|
+
4, 4, 4, 4, 4, 4, 4, 4,
|
169
|
+
4, 4, 4, 3, 4, 4, 4, 4,
|
170
|
+
4, 4, 4, 4, 4, 4, 4, 4,
|
171
|
+
4, 4
|
172
|
+
]
|
173
|
+
|
174
|
+
class << self
|
175
|
+
attr_accessor :html_string_lexer_start
|
176
|
+
end
|
177
|
+
self.html_string_lexer_start = 0;
|
178
|
+
class << self
|
179
|
+
attr_accessor :html_string_lexer_first_final
|
180
|
+
end
|
181
|
+
self.html_string_lexer_first_final = 0;
|
182
|
+
class << self
|
183
|
+
attr_accessor :html_string_lexer_error
|
184
|
+
end
|
185
|
+
self.html_string_lexer_error = -1;
|
186
|
+
|
187
|
+
class << self
|
188
|
+
attr_accessor :html_string_lexer_en_main
|
189
|
+
end
|
190
|
+
self.html_string_lexer_en_main = 0;
|
191
|
+
|
192
|
+
|
193
|
+
# line 23 "html_string_parser.rl"
|
194
|
+
|
195
|
+
# ---------- %
|
196
|
+
|
197
|
+
def test( data )
|
198
|
+
puts "Check : #{data}"
|
199
|
+
data = data.unpack("c*") if(data.is_a?(String))
|
200
|
+
eof = data.length
|
201
|
+
|
202
|
+
|
203
|
+
# line 204 "html_string_parser.rb"
|
204
|
+
begin
|
205
|
+
p ||= 0
|
206
|
+
pe ||= data.length
|
207
|
+
cs = html_string_lexer_start
|
208
|
+
ts = nil
|
209
|
+
te = nil
|
210
|
+
act = 0
|
211
|
+
end
|
212
|
+
|
213
|
+
# line 32 "html_string_parser.rl"
|
214
|
+
|
215
|
+
# line 216 "html_string_parser.rb"
|
216
|
+
begin
|
217
|
+
_klen, _trans, _keys, _acts, _nacts = nil
|
218
|
+
_goto_level = 0
|
219
|
+
_resume = 10
|
220
|
+
_eof_trans = 15
|
221
|
+
_again = 20
|
222
|
+
_test_eof = 30
|
223
|
+
_out = 40
|
224
|
+
while true
|
225
|
+
_trigger_goto = false
|
226
|
+
if _goto_level <= 0
|
227
|
+
if p == pe
|
228
|
+
_goto_level = _test_eof
|
229
|
+
next
|
230
|
+
end
|
231
|
+
end
|
232
|
+
if _goto_level <= _resume
|
233
|
+
_acts = _html_string_lexer_from_state_actions[cs]
|
234
|
+
_nacts = _html_string_lexer_actions[_acts]
|
235
|
+
_acts += 1
|
236
|
+
while _nacts > 0
|
237
|
+
_nacts -= 1
|
238
|
+
_acts += 1
|
239
|
+
case _html_string_lexer_actions[_acts - 1]
|
240
|
+
when 1 then
|
241
|
+
# line 1 "NONE"
|
242
|
+
begin
|
243
|
+
ts = p
|
244
|
+
end
|
245
|
+
# line 246 "html_string_parser.rb"
|
246
|
+
end # from state action switch
|
247
|
+
end
|
248
|
+
if _trigger_goto
|
249
|
+
next
|
250
|
+
end
|
251
|
+
_keys = _html_string_lexer_key_offsets[cs]
|
252
|
+
_trans = _html_string_lexer_index_offsets[cs]
|
253
|
+
_klen = _html_string_lexer_single_lengths[cs]
|
254
|
+
_break_match = false
|
255
|
+
|
256
|
+
begin
|
257
|
+
if _klen > 0
|
258
|
+
_lower = _keys
|
259
|
+
_upper = _keys + _klen - 1
|
260
|
+
|
261
|
+
loop do
|
262
|
+
break if _upper < _lower
|
263
|
+
_mid = _lower + ( (_upper - _lower) >> 1 )
|
264
|
+
|
265
|
+
if data[p] < _html_string_lexer_trans_keys[_mid]
|
266
|
+
_upper = _mid - 1
|
267
|
+
elsif data[p] > _html_string_lexer_trans_keys[_mid]
|
268
|
+
_lower = _mid + 1
|
269
|
+
else
|
270
|
+
_trans += (_mid - _keys)
|
271
|
+
_break_match = true
|
272
|
+
break
|
273
|
+
end
|
274
|
+
end # loop
|
275
|
+
break if _break_match
|
276
|
+
_keys += _klen
|
277
|
+
_trans += _klen
|
278
|
+
end
|
279
|
+
_klen = _html_string_lexer_range_lengths[cs]
|
280
|
+
if _klen > 0
|
281
|
+
_lower = _keys
|
282
|
+
_upper = _keys + (_klen << 1) - 2
|
283
|
+
loop do
|
284
|
+
break if _upper < _lower
|
285
|
+
_mid = _lower + (((_upper-_lower) >> 1) & ~1)
|
286
|
+
if data[p] < _html_string_lexer_trans_keys[_mid]
|
287
|
+
_upper = _mid - 2
|
288
|
+
elsif data[p] > _html_string_lexer_trans_keys[_mid+1]
|
289
|
+
_lower = _mid + 2
|
290
|
+
else
|
291
|
+
_trans += ((_mid - _keys) >> 1)
|
292
|
+
_break_match = true
|
293
|
+
break
|
294
|
+
end
|
295
|
+
end # loop
|
296
|
+
break if _break_match
|
297
|
+
_trans += _klen
|
298
|
+
end
|
299
|
+
end while false
|
300
|
+
_trans = _html_string_lexer_indicies[_trans]
|
301
|
+
end
|
302
|
+
if _goto_level <= _eof_trans
|
303
|
+
cs = _html_string_lexer_trans_targs[_trans]
|
304
|
+
if _html_string_lexer_trans_actions[_trans] != 0
|
305
|
+
_acts = _html_string_lexer_trans_actions[_trans]
|
306
|
+
_nacts = _html_string_lexer_actions[_acts]
|
307
|
+
_acts += 1
|
308
|
+
while _nacts > 0
|
309
|
+
_nacts -= 1
|
310
|
+
_acts += 1
|
311
|
+
case _html_string_lexer_actions[_acts - 1]
|
312
|
+
when 2 then
|
313
|
+
# line 1 "NONE"
|
314
|
+
begin
|
315
|
+
te = p+1
|
316
|
+
end
|
317
|
+
when 3 then
|
318
|
+
# line 12 "html_string_parser.rl"
|
319
|
+
begin
|
320
|
+
act = 1; end
|
321
|
+
when 4 then
|
322
|
+
# line 13 "html_string_parser.rl"
|
323
|
+
begin
|
324
|
+
act = 2; end
|
325
|
+
when 5 then
|
326
|
+
# line 14 "html_string_parser.rl"
|
327
|
+
begin
|
328
|
+
act = 3; end
|
329
|
+
when 6 then
|
330
|
+
# line 15 "html_string_parser.rl"
|
331
|
+
begin
|
332
|
+
act = 4; end
|
333
|
+
when 7 then
|
334
|
+
# line 16 "html_string_parser.rl"
|
335
|
+
begin
|
336
|
+
act = 5; end
|
337
|
+
when 8 then
|
338
|
+
# line 16 "html_string_parser.rl"
|
339
|
+
begin
|
340
|
+
te = p
|
341
|
+
p = p - 1; begin puts "\t =>string" end
|
342
|
+
end
|
343
|
+
when 9 then
|
344
|
+
# line 1 "NONE"
|
345
|
+
begin
|
346
|
+
case act
|
347
|
+
when 1 then
|
348
|
+
begin begin p = ((te))-1; end
|
349
|
+
puts "\t =><BR>" end
|
350
|
+
when 2 then
|
351
|
+
begin begin p = ((te))-1; end
|
352
|
+
puts "\t =><FONT>...</FONT>"end
|
353
|
+
when 3 then
|
354
|
+
begin begin p = ((te))-1; end
|
355
|
+
puts "\t =><FONT>"end
|
356
|
+
when 4 then
|
357
|
+
begin begin p = ((te))-1; end
|
358
|
+
puts "\t =></FONT>"end
|
359
|
+
when 5 then
|
360
|
+
begin begin p = ((te))-1; end
|
361
|
+
puts "\t =>string" end
|
362
|
+
end
|
363
|
+
end
|
364
|
+
# line 365 "html_string_parser.rb"
|
365
|
+
end # action switch
|
366
|
+
end
|
367
|
+
end
|
368
|
+
if _trigger_goto
|
369
|
+
next
|
370
|
+
end
|
371
|
+
end
|
372
|
+
if _goto_level <= _again
|
373
|
+
_acts = _html_string_lexer_to_state_actions[cs]
|
374
|
+
_nacts = _html_string_lexer_actions[_acts]
|
375
|
+
_acts += 1
|
376
|
+
while _nacts > 0
|
377
|
+
_nacts -= 1
|
378
|
+
_acts += 1
|
379
|
+
case _html_string_lexer_actions[_acts - 1]
|
380
|
+
when 0 then
|
381
|
+
# line 1 "NONE"
|
382
|
+
begin
|
383
|
+
ts = nil; end
|
384
|
+
# line 385 "html_string_parser.rb"
|
385
|
+
end # to state action switch
|
386
|
+
end
|
387
|
+
if _trigger_goto
|
388
|
+
next
|
389
|
+
end
|
390
|
+
p += 1
|
391
|
+
if p != pe
|
392
|
+
_goto_level = _resume
|
393
|
+
next
|
394
|
+
end
|
395
|
+
end
|
396
|
+
if _goto_level <= _test_eof
|
397
|
+
if p == eof
|
398
|
+
if _html_string_lexer_eof_trans[cs] > 0
|
399
|
+
_trans = _html_string_lexer_eof_trans[cs] - 1;
|
400
|
+
_goto_level = _eof_trans
|
401
|
+
next;
|
402
|
+
end
|
403
|
+
end
|
404
|
+
end
|
405
|
+
if _goto_level <= _out
|
406
|
+
break
|
407
|
+
end
|
408
|
+
end
|
409
|
+
end
|
410
|
+
|
411
|
+
# line 33 "html_string_parser.rl"
|
412
|
+
end
|
413
|
+
|
414
|
+
# ----------
|
415
|
+
|
416
|
+
test "<BRRR ALIGN=\"LEFT\">"
|
417
|
+
test "<BR ALIGN=\"LEFT\">"
|
418
|
+
test "\\<BR ALIGN=\"LEFT\"\\>"
|
419
|
+
test "simple test"
|
420
|
+
test "<FONT COLOR=\"blue\">"
|
421
|
+
test "</FONT>"
|
422
|
+
test "<font>simple test</font>"
|
@@ -0,0 +1,43 @@
|
|
1
|
+
%%{
|
2
|
+
|
3
|
+
machine html_string_lexer;
|
4
|
+
|
5
|
+
br_tag = '<'('br'|'BR')(space{1,}[^>]*)*'>';
|
6
|
+
font_open_tag = '<'('font'|'FONT')(space{1,}[^>]*)'>';
|
7
|
+
font_close_tag = '</font>'|'</FONT>';
|
8
|
+
font_tag = font_open_tag [^font_close_tag]* font_close_tag;
|
9
|
+
string = any*;
|
10
|
+
|
11
|
+
main := |*
|
12
|
+
br_tag => { puts "\t =><BR>" };
|
13
|
+
font_tag => { puts "\t =><FONT>...</FONT>"};
|
14
|
+
font_open_tag => { puts "\t =><FONT>"};
|
15
|
+
font_close_tag => { puts "\t =></FONT>"};
|
16
|
+
string => { puts "\t =>string" };
|
17
|
+
space;
|
18
|
+
*|;
|
19
|
+
|
20
|
+
}%%
|
21
|
+
|
22
|
+
%% write data;
|
23
|
+
|
24
|
+
# ---------- %
|
25
|
+
|
26
|
+
def test( data )
|
27
|
+
puts "Check : #{data}"
|
28
|
+
data = data.unpack("c*") if(data.is_a?(String))
|
29
|
+
eof = data.length
|
30
|
+
|
31
|
+
%% write init;
|
32
|
+
%% write exec;
|
33
|
+
end
|
34
|
+
|
35
|
+
# ----------
|
36
|
+
|
37
|
+
test "<BRRR ALIGN=\"LEFT\">"
|
38
|
+
test "<BR ALIGN=\"LEFT\">"
|
39
|
+
test "\\<BR ALIGN=\"LEFT\"\\>"
|
40
|
+
test "simple test"
|
41
|
+
test "<FONT COLOR=\"blue\">"
|
42
|
+
test "</FONT>"
|
43
|
+
test "<font>simple test</font>"
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-graphviz
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 27
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 9
|
9
|
-
-
|
10
|
-
version: 0.9.
|
9
|
+
- 16
|
10
|
+
version: 0.9.16
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Gregoire Lejeune
|
@@ -15,23 +15,10 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-
|
18
|
+
date: 2010-08-02 00:00:00 +02:00
|
19
19
|
default_executable:
|
20
|
-
dependencies:
|
21
|
-
|
22
|
-
name: treetop
|
23
|
-
prerelease: false
|
24
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
|
-
requirements:
|
27
|
-
- - ">="
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
hash: 3
|
30
|
-
segments:
|
31
|
-
- 0
|
32
|
-
version: "0"
|
33
|
-
type: :runtime
|
34
|
-
version_requirements: *id001
|
20
|
+
dependencies: []
|
21
|
+
|
35
22
|
description: Ruby/Graphviz provides an interface to layout and generate images of directed graphs in a variety of formats (PostScript, PNG, etc.) using GraphViz.
|
36
23
|
email: gregoire.lejeune@free.fr
|
37
24
|
executables:
|
@@ -39,6 +26,7 @@ executables:
|
|
39
26
|
- gem2gv
|
40
27
|
- dot2ruby
|
41
28
|
- git2gv
|
29
|
+
- xml2gv
|
42
30
|
extensions: []
|
43
31
|
|
44
32
|
extra_rdoc_files:
|
@@ -54,6 +42,7 @@ files:
|
|
54
42
|
- bin/gem2gv
|
55
43
|
- bin/git2gv
|
56
44
|
- bin/ruby2gv
|
45
|
+
- bin/xml2gv
|
57
46
|
- examples/dot/balanced.dot
|
58
47
|
- examples/dot/cluster.dot
|
59
48
|
- examples/dot/dotgraph.dot
|
@@ -140,7 +129,6 @@ files:
|
|
140
129
|
- lib/graphviz/attrs.rb
|
141
130
|
- lib/graphviz/constants.rb
|
142
131
|
- lib/graphviz/core_ext.rb
|
143
|
-
- lib/graphviz/dot.treetop
|
144
132
|
- lib/graphviz/dot2ruby.rb
|
145
133
|
- lib/graphviz/edge.rb
|
146
134
|
- lib/graphviz/ext.rb
|
@@ -152,7 +140,6 @@ files:
|
|
152
140
|
- lib/graphviz/node.rb
|
153
141
|
- lib/graphviz/nothugly/nothugly.xsl
|
154
142
|
- lib/graphviz/nothugly.rb
|
155
|
-
- lib/graphviz/parser.rb
|
156
143
|
- lib/graphviz/types/esc_string.rb
|
157
144
|
- lib/graphviz/types/html_string.rb
|
158
145
|
- lib/graphviz/types/lbl_string.rb
|
@@ -160,6 +147,9 @@ files:
|
|
160
147
|
- lib/graphviz/utils.rb
|
161
148
|
- lib/graphviz/xml.rb
|
162
149
|
- lib/graphviz.rb
|
150
|
+
- lib/src/html_string_parser.gv
|
151
|
+
- lib/src/html_string_parser.rb
|
152
|
+
- lib/src/html_string_parser.rl
|
163
153
|
- test/support.rb
|
164
154
|
- test/test_examples.rb
|
165
155
|
- test/test_init.rb
|
data/lib/graphviz/dot.treetop
DELETED
@@ -1,101 +0,0 @@
|
|
1
|
-
grammar Dot
|
2
|
-
rule graph
|
3
|
-
space type:("graph" / "digraph") blank name:string space cluster:cluster space <GraphViz::Parser::Graph>
|
4
|
-
end
|
5
|
-
|
6
|
-
rule cluster
|
7
|
-
"{" content:(preference / node / edge / subgraph)* "}" <GraphViz::Parser::Cluster>
|
8
|
-
end
|
9
|
-
|
10
|
-
rule preference
|
11
|
-
graph_preference / named_graph_preference / node_preference / edge_preference
|
12
|
-
end
|
13
|
-
|
14
|
-
rule graph_preference
|
15
|
-
space key:name blank "=" blank value:string separator <GraphViz::Parser::GraphPreference>
|
16
|
-
end
|
17
|
-
|
18
|
-
rule named_graph_preference
|
19
|
-
space "graph" blank options:options? separator <GraphViz::Parser::NamedGraphPreference>
|
20
|
-
end
|
21
|
-
|
22
|
-
rule node_preference
|
23
|
-
space "node" blank options:options? separator <GraphViz::Parser::NodePreference>
|
24
|
-
end
|
25
|
-
|
26
|
-
rule edge_preference
|
27
|
-
space "edge" blank options:options? separator <GraphViz::Parser::EdgePreference>
|
28
|
-
end
|
29
|
-
|
30
|
-
rule node
|
31
|
-
space name:string blank options:options? separator <GraphViz::Parser::Node>
|
32
|
-
end
|
33
|
-
|
34
|
-
rule edge
|
35
|
-
direct_edge / undirect_edge
|
36
|
-
end
|
37
|
-
|
38
|
-
rule direct_edge
|
39
|
-
space node_one:string blank "->" blank node_two:string blank other_nodes:("->" blank next_node:string blank)* options:options? separator <GraphViz::Parser::Edge>
|
40
|
-
end
|
41
|
-
|
42
|
-
rule undirect_edge
|
43
|
-
space node_one:string blank "--" blank node_two:string blank other_nodes:("--" blank next_node:string blank)* options:options? separator <GraphViz::Parser::Edge>
|
44
|
-
end
|
45
|
-
|
46
|
-
rule subgraph
|
47
|
-
named_subgraph / anonymous_subgraph
|
48
|
-
end
|
49
|
-
|
50
|
-
rule named_subgraph
|
51
|
-
space "subgraph" blank name:string space cluster:cluster space <GraphViz::Parser::Subgraph>
|
52
|
-
end
|
53
|
-
|
54
|
-
rule anonymous_subgraph
|
55
|
-
space "subgraph" space cluster:cluster space <GraphViz::Parser::AnonymousSubgraph>
|
56
|
-
end
|
57
|
-
|
58
|
-
rule options
|
59
|
-
"[" space (name blank "=" blank string comma space)* name blank "=" blank string space "]" <GraphViz::Parser::Options>
|
60
|
-
end
|
61
|
-
|
62
|
-
rule string
|
63
|
-
name / quoted_string
|
64
|
-
end
|
65
|
-
|
66
|
-
rule comma
|
67
|
-
space ","
|
68
|
-
end
|
69
|
-
|
70
|
-
rule separator
|
71
|
-
blank ";" space
|
72
|
-
end
|
73
|
-
|
74
|
-
rule quoted_string
|
75
|
-
'"' [^"]* '"'
|
76
|
-
end
|
77
|
-
|
78
|
-
rule name
|
79
|
-
[a-zA-Z0-9_\.]+
|
80
|
-
end
|
81
|
-
|
82
|
-
rule blank
|
83
|
-
[\ \t]*
|
84
|
-
end
|
85
|
-
|
86
|
-
rule space
|
87
|
-
[\s\n\r\t]*
|
88
|
-
end
|
89
|
-
|
90
|
-
rule newline
|
91
|
-
CR LF
|
92
|
-
end
|
93
|
-
|
94
|
-
rule CR
|
95
|
-
[\r]?
|
96
|
-
end
|
97
|
-
|
98
|
-
rule LF
|
99
|
-
[\n]?
|
100
|
-
end
|
101
|
-
end
|
data/lib/graphviz/parser.rb
DELETED
@@ -1,288 +0,0 @@
|
|
1
|
-
# Copyright (C) 2009, 2010 Gregoire Lejeune <gregoire.lejeune@free.fr>
|
2
|
-
#
|
3
|
-
# This program is free software; you can redistribute it and/or modify
|
4
|
-
# it under the terms of the GNU General Public License as published by
|
5
|
-
# the Free Software Foundation; either version 2 of the License, or
|
6
|
-
# (at your option) any later version.
|
7
|
-
#
|
8
|
-
# This program is distributed in the hope that it will be useful,
|
9
|
-
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
10
|
-
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
11
|
-
# GNU General Public License for more details.
|
12
|
-
#
|
13
|
-
# You should have received a copy of the GNU General Public License
|
14
|
-
# along with this program; if not, write to the Free Software
|
15
|
-
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
16
|
-
require 'rubygems'
|
17
|
-
require 'treetop'
|
18
|
-
|
19
|
-
Treetop.load File.dirname(__FILE__) + '/dot.treetop'
|
20
|
-
|
21
|
-
class GraphViz
|
22
|
-
class Parser
|
23
|
-
|
24
|
-
class Context
|
25
|
-
def initialize
|
26
|
-
@graph = nil
|
27
|
-
@nodes = {}
|
28
|
-
@edges = []
|
29
|
-
@options = {
|
30
|
-
:node => {},
|
31
|
-
:edge => {}
|
32
|
-
}
|
33
|
-
end
|
34
|
-
|
35
|
-
def graph
|
36
|
-
@graph
|
37
|
-
end
|
38
|
-
|
39
|
-
def graph=(g)
|
40
|
-
@graph = g
|
41
|
-
end
|
42
|
-
|
43
|
-
def nodes
|
44
|
-
@nodes
|
45
|
-
end
|
46
|
-
|
47
|
-
def edges
|
48
|
-
@edges
|
49
|
-
end
|
50
|
-
|
51
|
-
def options
|
52
|
-
@options
|
53
|
-
end
|
54
|
-
|
55
|
-
def options=(o)
|
56
|
-
@options = o
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
class Graph < Treetop::Runtime::SyntaxNode
|
61
|
-
def eval( context, hOpts = [] )
|
62
|
-
# puts "GRAPH TYPE = #{type.text_value}"
|
63
|
-
# puts "GRAPH NAME = #{name.text_value}"
|
64
|
-
|
65
|
-
begin
|
66
|
-
hOpts = hOpts[0].merge( {:type => type.text_value} )
|
67
|
-
rescue
|
68
|
-
hOpts = {:type => type.text_value}
|
69
|
-
end
|
70
|
-
|
71
|
-
# Create Graph
|
72
|
-
context.graph = GraphViz.new( name.text_value.gsub(/"/, ""), hOpts )
|
73
|
-
|
74
|
-
# Eval cluster
|
75
|
-
cluster.eval( context )
|
76
|
-
|
77
|
-
return context.graph
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
class Cluster < Treetop::Runtime::SyntaxNode
|
82
|
-
def eval( context )
|
83
|
-
content.elements.each do |e|
|
84
|
-
e.eval( context )
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
class GraphPreference < Treetop::Runtime::SyntaxNode
|
90
|
-
def eval( context )
|
91
|
-
# puts "GRAPH PREFERENCE : "
|
92
|
-
# puts " #{key.text_value} = #{value.text_value.gsub(/"/, "")}"
|
93
|
-
context.graph[key.text_value] = value.text_value.gsub(/"/, "")
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
class NamedGraphPreference < Treetop::Runtime::SyntaxNode
|
98
|
-
def eval( context )
|
99
|
-
# puts "GRAPH PREFERENCES :"
|
100
|
-
options.eval().each do |k,v|
|
101
|
-
context.graph[k] = v
|
102
|
-
end
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
class NodePreference < Treetop::Runtime::SyntaxNode
|
107
|
-
def eval( context )
|
108
|
-
# puts "NODE PREFERENCES :"
|
109
|
-
context.options[:node] = context.options[:node].merge( options.eval() )
|
110
|
-
end
|
111
|
-
end
|
112
|
-
|
113
|
-
class EdgePreference < Treetop::Runtime::SyntaxNode
|
114
|
-
def eval( context )
|
115
|
-
# puts "EDGE PREFERENCES :"
|
116
|
-
context.options[:edge] = context.options[:edge].merge( options.eval() )
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
class Node < Treetop::Runtime::SyntaxNode
|
121
|
-
def eval( context )
|
122
|
-
node_name = name.text_value.gsub( /"/, "" )
|
123
|
-
# puts "NODE NAME = #{node_name}"
|
124
|
-
# puts "OPTIONS = "
|
125
|
-
|
126
|
-
# Create node
|
127
|
-
node = context.nodes[node_name] || context.graph.add_node( node_name )
|
128
|
-
|
129
|
-
# Add global options
|
130
|
-
context.options[:node].each do |k, v|
|
131
|
-
node[k] = v
|
132
|
-
end
|
133
|
-
|
134
|
-
# Add custom options
|
135
|
-
unless options.terminal?
|
136
|
-
options.eval().each do |k, v|
|
137
|
-
node[k] = v
|
138
|
-
end
|
139
|
-
end
|
140
|
-
|
141
|
-
# Save node
|
142
|
-
context.nodes[node_name] = node
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
|
-
class Edge < Treetop::Runtime::SyntaxNode
|
147
|
-
def create_node( name, context )
|
148
|
-
# puts " NEED TO CREATE NODE : #{name}"
|
149
|
-
# Create the node
|
150
|
-
node = context.graph.add_node( name )
|
151
|
-
|
152
|
-
# Add global options
|
153
|
-
context.options[:node].each do |k, v|
|
154
|
-
node[k] = v
|
155
|
-
end
|
156
|
-
|
157
|
-
# Save node
|
158
|
-
context.nodes[name] = node
|
159
|
-
end
|
160
|
-
|
161
|
-
def create_edge( one, two, edge_options, context )
|
162
|
-
# Create edge
|
163
|
-
edge = context.graph.add_edge( one, two )
|
164
|
-
|
165
|
-
# Add global options
|
166
|
-
context.options[:edge].each do |k, v|
|
167
|
-
edge[k] = v
|
168
|
-
end
|
169
|
-
|
170
|
-
# Add custom options
|
171
|
-
edge_options.each do |k, v|
|
172
|
-
edge[k] = v
|
173
|
-
end
|
174
|
-
|
175
|
-
# Save edge
|
176
|
-
context.edges << edge
|
177
|
-
end
|
178
|
-
|
179
|
-
def eval( context )
|
180
|
-
one_name = node_one.text_value.gsub( /"/, "" )
|
181
|
-
two_name = node_two.text_value.gsub( /"/, "" )
|
182
|
-
# puts "EDGE"
|
183
|
-
# puts "NODE ONE = #{one_name}"
|
184
|
-
# puts "NODE TWO = #{two_name}"
|
185
|
-
# puts "OPTIONS = "
|
186
|
-
|
187
|
-
# Get or create node one
|
188
|
-
one = context.nodes[one_name] || create_node( one_name, context )
|
189
|
-
|
190
|
-
# Get or create node two
|
191
|
-
two = context.nodes[two_name] || create_node( two_name, context )
|
192
|
-
|
193
|
-
# Get options
|
194
|
-
edge_options = {}
|
195
|
-
edge_options = options.eval() unless options.terminal?
|
196
|
-
|
197
|
-
# Create edge
|
198
|
-
create_edge( one, two, edge_options, context )
|
199
|
-
|
200
|
-
last_node = two
|
201
|
-
other_nodes.elements.each do |e|
|
202
|
-
new_node_name = e.next_node.text_value.gsub( /"/, "" )
|
203
|
-
# puts "OTHER NODE : #{new_node_name}"
|
204
|
-
|
205
|
-
new_node = context.nodes[new_node_name] || create_node( new_node_name, context )
|
206
|
-
create_edge( last_node, new_node, edge_options, context )
|
207
|
-
|
208
|
-
last_node = new_node
|
209
|
-
end
|
210
|
-
end
|
211
|
-
end
|
212
|
-
|
213
|
-
class Subgraph < Treetop::Runtime::SyntaxNode
|
214
|
-
def eval( context )
|
215
|
-
# puts "CREATE SUBGRAPH : #{name.text_value}"
|
216
|
-
|
217
|
-
# Save options
|
218
|
-
saved_options = context.options.clone
|
219
|
-
# Save graph
|
220
|
-
saved_graph = context.graph
|
221
|
-
|
222
|
-
# Create Graph
|
223
|
-
context.graph = context.graph.add_graph( name.text_value.gsub(/"/, "") )
|
224
|
-
#context.options = {
|
225
|
-
# :node => {},
|
226
|
-
# :edge => {}
|
227
|
-
#}
|
228
|
-
|
229
|
-
# Eval cluster
|
230
|
-
cluster.eval( context )
|
231
|
-
|
232
|
-
# Reinitialize graph and options
|
233
|
-
context.graph = saved_graph
|
234
|
-
context.options = saved_options
|
235
|
-
end
|
236
|
-
end
|
237
|
-
|
238
|
-
class AnonymousSubgraph < Treetop::Runtime::SyntaxNode
|
239
|
-
def eval( context )
|
240
|
-
# puts "CREATE ANONYMOUS SUBGRAPH"
|
241
|
-
|
242
|
-
# Save options
|
243
|
-
saved_options = context.options.clone
|
244
|
-
# Save graph
|
245
|
-
saved_graph = context.graph
|
246
|
-
|
247
|
-
# Create Graph
|
248
|
-
context.graph = context.graph.add_graph( )
|
249
|
-
#context.options = {
|
250
|
-
# :node => {},
|
251
|
-
# :edge => {}
|
252
|
-
#}
|
253
|
-
|
254
|
-
# Eval cluster
|
255
|
-
cluster.eval( context )
|
256
|
-
|
257
|
-
# Reinitialize graph and options
|
258
|
-
context.graph = saved_graph
|
259
|
-
context.options = saved_options
|
260
|
-
end
|
261
|
-
end
|
262
|
-
|
263
|
-
class Options < Treetop::Runtime::SyntaxNode
|
264
|
-
def eval
|
265
|
-
options = {}
|
266
|
-
elements[2].elements.each do |e|
|
267
|
-
# puts " #{e.elements[0].text_value} = #{e.elements[4].text_value}"
|
268
|
-
options[e.elements[0].text_value] = e.elements[4].text_value.gsub( /"/, "" )
|
269
|
-
end
|
270
|
-
# puts " #{elements[3].text_value} = #{elements[7].text_value}"
|
271
|
-
options[elements[3].text_value] = elements[7].text_value.gsub( /"/, "" )
|
272
|
-
|
273
|
-
return options
|
274
|
-
end
|
275
|
-
end
|
276
|
-
|
277
|
-
def self.parse( file, *hOpts, &block )
|
278
|
-
dot = open(file).read
|
279
|
-
parser = DotParser.new()
|
280
|
-
tree = parser.parse( dot )
|
281
|
-
graph = tree.eval( GraphViz::Parser::Context.new(), hOpts )
|
282
|
-
|
283
|
-
yield( graph ) if( block and graph.nil? == false )
|
284
|
-
|
285
|
-
return graph
|
286
|
-
end
|
287
|
-
end
|
288
|
-
end
|