ruby-graphviz 0.9.15 → 0.9.16
Sign up to get free protection for your applications and to get access to all the features.
- 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
|