xamplr-gen 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. data/.document +5 -0
  2. data/.gitignore +22 -0
  3. data/COPYING +619 -0
  4. data/LICENSE +4 -0
  5. data/Makefile +11 -0
  6. data/README.md +33 -0
  7. data/Rakefile +66 -0
  8. data/VERSION +1 -0
  9. data/bin/xampl-gen +17 -0
  10. data/features/step_definitions/xamplr-gen_steps.rb +0 -0
  11. data/features/support/env.rb +6 -0
  12. data/features/xamplr-gen.feature +9 -0
  13. data/lib/xamplr-gen.rb +13 -0
  14. data/lib/xamplr-gen/.cvsignore +1 -0
  15. data/lib/xamplr-gen/graphml-out.rb +449 -0
  16. data/lib/xamplr-gen/my.gen.elements.xml +461 -0
  17. data/lib/xamplr-gen/simpleTemplate/danger.rx +4 -0
  18. data/lib/xamplr-gen/simpleTemplate/obsolete/input-c.r4 +35 -0
  19. data/lib/xamplr-gen/simpleTemplate/obsolete/play.r6.txt +12 -0
  20. data/lib/xamplr-gen/simpleTemplate/obsolete/play_more.r6.txt +20 -0
  21. data/lib/xamplr-gen/simpleTemplate/obsolete/test001.r5 +8 -0
  22. data/lib/xamplr-gen/simpleTemplate/obsolete/test002.r5 +13 -0
  23. data/lib/xamplr-gen/simpleTemplate/obsolete/test003.r5 +37 -0
  24. data/lib/xamplr-gen/simpleTemplate/old/r6.000.rb +122 -0
  25. data/lib/xamplr-gen/simpleTemplate/old/r6.001.rb +145 -0
  26. data/lib/xamplr-gen/simpleTemplate/play.r6 +12 -0
  27. data/lib/xamplr-gen/simpleTemplate/play_more.r6 +20 -0
  28. data/lib/xamplr-gen/simpleTemplate/play_noblanks.r6 +21 -0
  29. data/lib/xamplr-gen/simpleTemplate/playq.r6 +16 -0
  30. data/lib/xamplr-gen/simpleTemplate/r6.rb +87 -0
  31. data/lib/xamplr-gen/simpleTemplate/simple-template.rb +75 -0
  32. data/lib/xamplr-gen/templates/.cvsignore +3 -0
  33. data/lib/xamplr-gen/templates/child.template +47 -0
  34. data/lib/xamplr-gen/templates/child_indexed.template +89 -0
  35. data/lib/xamplr-gen/templates/child_modules.template +5 -0
  36. data/lib/xamplr-gen/templates/element_classes.template +11 -0
  37. data/lib/xamplr-gen/templates/element_data.template +283 -0
  38. data/lib/xamplr-gen/templates/element_empty.template +277 -0
  39. data/lib/xamplr-gen/templates/element_mixed.template +278 -0
  40. data/lib/xamplr-gen/templates/element_simple.template +277 -0
  41. data/lib/xamplr-gen/templates/package.template +38 -0
  42. data/lib/xamplr-gen/xampl-cl-gen.rb +89 -0
  43. data/lib/xamplr-gen/xampl-generator.rb +561 -0
  44. data/lib/xamplr-gen/xampl-hand-generated.rb +1534 -0
  45. data/lib/xamplr-gen/yuml-out.rb +127 -0
  46. data/licence.rb +17 -0
  47. data/test/helper.rb +10 -0
  48. data/test/test_xamplr-gen.rb +7 -0
  49. data/xamplr-gen.gemspec +98 -0
  50. metadata +124 -0
data/LICENSE ADDED
@@ -0,0 +1,4 @@
1
+ Copyright (c) 2002-2010 Bob Hutchison
2
+
3
+ see COPYING for licence details
4
+
data/Makefile ADDED
@@ -0,0 +1,11 @@
1
+
2
+ check:
3
+ git clean -dx --dry-run
4
+
5
+ clean:
6
+ git clean -fdx
7
+ ln -s ../dot.idea .idea
8
+
9
+ release:
10
+ rake version:bump:patch release
11
+
data/README.md ADDED
@@ -0,0 +1,33 @@
1
+ # xamplr-gen
2
+
3
+ xamplr-gen is part of a set of software tools that supports development of ruby applications.
4
+
5
+ It consists of three gems hosted on gem cutter, source code on
6
+ github.
7
+
8
+ * xamplr-pp -- this is a pure ruby pull parser
9
+ * xamplr -- this is the xampl runtime
10
+ * xamplr-gen -- this is the code generator
11
+
12
+ There is an additional fourth github repository containing
13
+ examples and documentation that will be coming soon.
14
+
15
+ Yes, that means that there's no documentation. And no examples. I agree, this is a very bad situation.
16
+
17
+ ## Installation:
18
+
19
+ > sudo gem install xamplr-gen
20
+
21
+ This will install all three gems.
22
+
23
+
24
+ ## License:
25
+
26
+ xamplr-pp and xamlpr are both licensed under the LGPLv3.
27
+
28
+ xamplr-gen is licensed under AGPLv3
29
+
30
+ An alternative license may be negotiated, contact me (hutch@xampl.com)
31
+
32
+ Copyright (c) 2002-2010 Bob Hutchison.
33
+
data/Rakefile ADDED
@@ -0,0 +1,66 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "xamplr-gen"
8
+ gem.summary = %Q{This is the xampl code generator for Ruby}
9
+ gem.description = %Q{This is the xampl code generator for Ruby.}
10
+ gem.email = "hutch@xampl.com"
11
+ gem.homepage = "http://github.com/hutch/xamplr-gen"
12
+ gem.authors = ["Bob Hutchison"]
13
+ gem.add_development_dependency "cucumber", ">= 0"
14
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
15
+
16
+ gem.add_dependency('xamplr', '>=1.9.0')
17
+ end
18
+ Jeweler::GemcutterTasks.new
19
+ rescue LoadError
20
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
21
+ end
22
+
23
+ require 'rake/testtask'
24
+ Rake::TestTask.new(:test) do |test|
25
+ test.libs << 'lib' << 'test'
26
+ test.pattern = 'test/**/test_*.rb'
27
+ test.verbose = true
28
+ end
29
+
30
+ begin
31
+ require 'rcov/rcovtask'
32
+ Rcov::RcovTask.new do |test|
33
+ test.libs << 'test'
34
+ test.pattern = 'test/**/test_*.rb'
35
+ test.verbose = true
36
+ end
37
+ rescue LoadError
38
+ task :rcov do
39
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
40
+ end
41
+ end
42
+
43
+ task :test => :check_dependencies
44
+
45
+ begin
46
+ require 'cucumber/rake/task'
47
+ Cucumber::Rake::Task.new(:features)
48
+
49
+ task :features => :check_dependencies
50
+ rescue LoadError
51
+ task :features do
52
+ abort "Cucumber is not available. In order to run features, you must: sudo gem install cucumber"
53
+ end
54
+ end
55
+
56
+ task :default => :test
57
+
58
+ require 'rake/rdoctask'
59
+ Rake::RDocTask.new do |rdoc|
60
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
61
+
62
+ rdoc.rdoc_dir = 'rdoc'
63
+ rdoc.title = "xamplr-gen #{version}"
64
+ rdoc.rdoc_files.include('README*')
65
+ rdoc.rdoc_files.include('lib/**/*.rb')
66
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.9.0
data/bin/xampl-gen ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+ #!/usr/bin/env ruby -w -I..
3
+
4
+ require 'xamplr-gen'
5
+ require 'xamplr-gen/xampl-cl-gen'
6
+
7
+ include XamplGenerator
8
+ include Xampl
9
+
10
+ project_specialisations = File.join(%w{ . project-generator.rb })
11
+ if File.exists?(project_specialisations) then
12
+ load project_specialisations
13
+ end
14
+
15
+ generator = ProjectGenerator.new
16
+ generator.generate
17
+
File without changes
@@ -0,0 +1,6 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__) + '/../../lib')
2
+ require 'xamplr-gen'
3
+
4
+ require 'test/unit/assertions'
5
+
6
+ World(Test::Unit::Assertions)
@@ -0,0 +1,9 @@
1
+ Feature: something something
2
+ In order to something something
3
+ A user something something
4
+ something something something
5
+
6
+ Scenario: something something
7
+ Given inspiration
8
+ When I create a sweet new gem
9
+ Then everyone should see how awesome I am
data/lib/xamplr-gen.rb ADDED
@@ -0,0 +1,13 @@
1
+ require 'fileutils'
2
+ require 'set'
3
+ require 'getoptlong'
4
+
5
+ require 'xamplr'
6
+ require 'xamplr-pp'
7
+
8
+ require "xamplr-gen/xampl-hand-generated"
9
+ require "xamplr-gen/simpleTemplate/simple-template"
10
+ require "xamplr-gen/graphml-out"
11
+ require "xamplr-gen/yuml-out"
12
+ require 'xamplr-gen/xampl-generator'
13
+
@@ -0,0 +1 @@
1
+ .cvs.log
@@ -0,0 +1,449 @@
1
+
2
+ module XamplGenerator
3
+
4
+ class GraphMLOut
5
+
6
+ def initialize(elements_map)
7
+ @elements_map = elements_map
8
+ end
9
+
10
+ def generate_class_nodes(element, include_mixins)
11
+
12
+ node = @element_to_node_map[element.nstag]
13
+
14
+ class_name = "#{ element.package }::#{ element.class_name }"
15
+ mixin_name = "#{ element.package }::#{ element.class_name }"
16
+
17
+ if element.persisted then
18
+ write_entity_node(node, class_name, element.kind)
19
+ else
20
+ write_internal_node(node, class_name, element.kind)
21
+ end
22
+
23
+ if include_mixins then
24
+ mixin_node = @mixed_in[element.nstag]
25
+ #puts "#{ element.nstag } => #{ node }, mixin: [#{ mixin_node }]"
26
+ if mixin_node then
27
+ write_mixin_node(mixin_node, class_name)
28
+ end
29
+ end
30
+ # puts "NODE #{ node } #{ class_name }"
31
+ # puts "NODE #{ mixin_node } #{ mixin_name }"
32
+ end
33
+
34
+ def generate_edges(element, include_mixins)
35
+ # for each child, generate an entity-ref or internal-ref edge
36
+ # for each child, generate a mixin-ref edge
37
+
38
+ return if ignore_package(element.package)
39
+
40
+ element.child_element_child.each do | celement |
41
+ next if ignore_package(celement.package)
42
+
43
+ cnstag = "{{#{ celement.namespace }}}#{ celement.element_name }"
44
+
45
+ referenced_element = @ns_to_element_map[ cnstag ]
46
+ next unless referenced_element
47
+
48
+ this_node = @element_to_node_map[ element.nstag ]
49
+
50
+ other_node = @element_to_node_map[ cnstag ]
51
+ other_mixin = @mixed_in[ cnstag ]
52
+
53
+ if referenced_element.persisted then
54
+ @current_edge += 1
55
+ write_entity_ref_edge(@current_edge, this_node, other_node)
56
+ # puts "ER EDGE #{ @current_edge }, #{ this_node } --> #{ other_node } :: #{ element.class_name } --> #{ referenced_element.class_name }"
57
+ else
58
+ @current_edge += 1
59
+ write_internal_ref_edge(@current_edge, this_node, other_node)
60
+ # puts "IR EDGE #{ @current_edge }, #{ this_node } --> #{ other_node } :: #{ element.class_name } --> #{ referenced_element.class_name }"
61
+ end
62
+ if include_mixins then
63
+ @current_edge += 1
64
+ write_mixin_ref_edge(@current_edge, this_node, other_mixin)
65
+ # puts "MI EDGE #{ @current_edge }, #{ this_node } --> #{ other_mixin } :: #{ element.class_name } --> #{ referenced_element.class_name }"
66
+ end
67
+ end
68
+ end
69
+
70
+ def ignore_package(package)
71
+ return true if @excluded_packages.member?(package)
72
+ return false if @included_packages.nil?
73
+ return true unless @included_packages.member?(package)
74
+ return false
75
+ end
76
+
77
+ def write_graph_ml(base_filename, excluded_packages=[ ], included_packages=nil, include_mixins=true)
78
+ filename = "#{base_filename}.graphml"
79
+
80
+ @excluded_packages = Set.new(excluded_packages)
81
+ @included_packages = included_packages ? Set.new(included_packages) : nil
82
+
83
+ @element_to_node_map = {}
84
+ @ns_to_element_map = {}
85
+ @element_to_child_element_map = {}
86
+ @mixed_in = {}
87
+
88
+ nodes = 0
89
+ edges = 0
90
+ mixins = 0
91
+
92
+ @elements_map.each_value do |elements|
93
+ elements.element_child.each do |element|
94
+ next if ignore_package(element.package)
95
+ nodes += 1
96
+
97
+ @element_to_node_map[element.nstag] = nodes
98
+ @ns_to_element_map[element.nstag] = element
99
+ @element_to_child_element_map[element.nstag] = map = {}
100
+
101
+ element.child_element_child.each do | celement |
102
+ edges += 1
103
+ cnstag = "{{#{ celement.namespace }}}#{ celement.element_name }"
104
+ map[cnstag] = edges
105
+ unless @mixed_in.include?(cnstag) then
106
+ mixins += 1
107
+ @mixed_in[cnstag] = mixins
108
+ end
109
+ end
110
+ end
111
+ end
112
+
113
+ @mixed_in.each do | k, v |
114
+ @mixed_in[k] = v + nodes
115
+ end
116
+
117
+ # puts "#{File.basename(__FILE__)}:#{__LINE__} #{ @element_to_node_map.inspect }"
118
+
119
+ @reference_edges = edges
120
+
121
+ File.open(filename, "w") do | out |
122
+ @out = out
123
+
124
+ if include_mixins then
125
+ write_graphml_start(nodes + mixins, 2 * edges)
126
+ else
127
+ write_graphml_start(nodes, edges)
128
+ end
129
+ @elements_map.each_value do |elements|
130
+ elements.element_child.each do |element|
131
+ generate_class_nodes(element, include_mixins)
132
+ end
133
+ end
134
+
135
+ @current_edge = 0
136
+ @elements_map.each_value do |elements|
137
+ elements.element_child.each do |element|
138
+ generate_edges(element, include_mixins)
139
+ end
140
+ end
141
+ write_graphml_end
142
+ # puts "#{File.basename(__FILE__)}:#{__LINE__} EDGES:: predicted: #{ 2 * edges }, actual: #{ @current_edge }"
143
+ end
144
+ return nil
145
+ end
146
+
147
+ def write_entity_node(node, class_name, kind)
148
+ @out << <<EOS
149
+ <node id="n#{ node }">
150
+ <data key="d0">
151
+ <y:UMLClassNode>
152
+ <y:Geometry height="102.0"
153
+ width="111.0"
154
+ x="-5.5"
155
+ y="174.0"/>
156
+ <y:Fill color="#99CCFF"
157
+ transparent="false"/>
158
+ <y:BorderStyle color="#000000"
159
+ type="line"
160
+ width="2.0"/>
161
+ <y:NodeLabel alignment="center"
162
+ autoSizePolicy="content"
163
+ fontFamily="Dialog"
164
+ fontSize="13"
165
+ fontStyle="bold"
166
+ hasBackgroundColor="false"
167
+ hasLineColor="false"
168
+ height="19.310546875"
169
+ modelName="internal"
170
+ modelPosition="c"
171
+ textColor="#000000"
172
+ visible="true"
173
+ width="49.6904296875"
174
+ x="30.65478515625"
175
+ y="26.1328125">#{ class_name }
176
+ </y:NodeLabel>
177
+ <y:UML clipContent="true"
178
+ constraint=""
179
+ omitDetails="false"
180
+ stereotype="#{ kind }"
181
+ use3DEffect="false">
182
+ <!--y:AttributeLabel>bar
183
+ bar2</y:AttributeLabel>
184
+ <y:MethodLabel>foo()</y:MethodLabel-->
185
+ </y:UML>
186
+ </y:UMLClassNode>
187
+ </data>
188
+ <data key="d1">UMLClass</data>
189
+ </node>
190
+ EOS
191
+ end
192
+
193
+ def write_internal_node(node, class_name, kind)
194
+ @out << <<EOS
195
+ <node id="n#{ node }">
196
+ <data key="d0">
197
+ <y:UMLClassNode>
198
+ <y:Geometry height="102.0"
199
+ width="91.0"
200
+ x="4.5"
201
+ y="-1.0"/>
202
+ <y:Fill color="#CCFFCC"
203
+ transparent="false"/>
204
+ <y:BorderStyle color="#000000"
205
+ type="line"
206
+ width="1.0"/>
207
+ <y:NodeLabel alignment="center"
208
+ autoSizePolicy="content"
209
+ fontFamily="Dialog"
210
+ fontSize="13"
211
+ fontStyle="bold"
212
+ hasBackgroundColor="false"
213
+ hasLineColor="false"
214
+ height="19.310546875"
215
+ modelName="internal"
216
+ modelPosition="c"
217
+ textColor="#000000"
218
+ visible="true"
219
+ width="39.83251953125"
220
+ x="25.583740234375"
221
+ y="26.1328125">#{ class_name }
222
+ </y:NodeLabel>
223
+ <y:UML clipContent="true"
224
+ constraint=""
225
+ omitDetails="false"
226
+ stereotype="#{ kind }"
227
+ use3DEffect="false">
228
+ <!--y:AttributeLabel>bar</y:AttributeLabel>
229
+ <y:MethodLabel>foo()</y:MethodLabel-->
230
+ </y:UML>
231
+ </y:UMLClassNode>
232
+ </data>
233
+ <data key="d1">UMLClass</data>
234
+ </node>
235
+ EOS
236
+ end
237
+
238
+ def write_mixin_node(node, class_name)
239
+ @out << <<EOS
240
+ <node id="n#{ node }">
241
+ <data key="d0">
242
+ <y:UMLClassNode>
243
+ <y:Geometry height="102.0"
244
+ width="136.0"
245
+ x="-18.0"
246
+ y="349.0"/>
247
+ <y:Fill color="#FFCC99"
248
+ transparent="false"/>
249
+ <y:BorderStyle color="#000000"
250
+ type="line"
251
+ width="1.0"/>
252
+ <y:NodeLabel alignment="center"
253
+ autoSizePolicy="content"
254
+ fontFamily="Dialog"
255
+ fontSize="13"
256
+ fontStyle="bold"
257
+ hasBackgroundColor="false"
258
+ hasLineColor="false"
259
+ height="19.310546875"
260
+ modelName="internal"
261
+ modelPosition="c"
262
+ textColor="#000000"
263
+ visible="true"
264
+ width="110.818359375"
265
+ x="12.5908203125"
266
+ y="26.1328125">#{ class_name }
267
+ </y:NodeLabel>
268
+ <y:UML clipContent="true"
269
+ constraint=""
270
+ omitDetails="false"
271
+ stereotype="mixin"
272
+ use3DEffect="false">
273
+ <!--y:AttributeLabel></y:AttributeLabel>
274
+ <y:MethodLabel></y:MethodLabel-->
275
+ </y:UML>
276
+ </y:UMLClassNode>
277
+ </data>
278
+ <data key="d1">UMLClass</data>
279
+ </node>
280
+ EOS
281
+ end
282
+
283
+ def write_entity_ref_edge(edge, class_node, external_node)
284
+ @out << <<EOS
285
+ <edge id="e#{ edge }"
286
+ source="n#{ class_node }"
287
+ target="n#{ external_node }">
288
+ <data key="d2">
289
+ <y:PolyLineEdge>
290
+ <y:Path sx="0.0"
291
+ sy="0.0"
292
+ tx="0.0"
293
+ ty="0.0"/>
294
+ <y:LineStyle color="#000000"
295
+ type="line"
296
+ width="2.0"/>
297
+ <y:Arrows source="none"
298
+ target="short"/>
299
+ <y:EdgeLabel alignment="center"
300
+ distance="2.0"
301
+ fontFamily="Dialog"
302
+ fontSize="12"
303
+ fontStyle="plain"
304
+ hasBackgroundColor="false"
305
+ hasLineColor="false"
306
+ height="4.0"
307
+ modelName="six_pos"
308
+ modelPosition="tail"
309
+ preferredPlacement="anywhere"
310
+ ratio="0.5"
311
+ textColor="#000000"
312
+ visible="true"
313
+ width="4.0"
314
+ x="30.000732421875"
315
+ y="2.0"></y:EdgeLabel>
316
+ <y:BendStyle smoothed="false"/>
317
+ </y:PolyLineEdge>
318
+ </data>
319
+ <data key="d3">UMLuses</data>
320
+ </edge>
321
+ EOS
322
+ end
323
+
324
+ def write_internal_ref_edge(edge, class_node, internal_node)
325
+ @out << <<EOS
326
+ <edge id="e#{ edge }"
327
+ source="n#{ class_node }"
328
+ target="n#{ internal_node }">
329
+ <data key="d2">
330
+ <y:PolyLineEdge>
331
+ <y:Path sx="0.0"
332
+ sy="0.0"
333
+ tx="0.0"
334
+ ty="0.0"/>
335
+ <y:LineStyle color="#000000"
336
+ type="line"
337
+ width="1.0"/>
338
+ <y:Arrows source="none"
339
+ target="short"/>
340
+ <y:EdgeLabel alignment="center"
341
+ distance="2.0"
342
+ fontFamily="Dialog"
343
+ fontSize="12"
344
+ fontStyle="plain"
345
+ hasBackgroundColor="false"
346
+ hasLineColor="false"
347
+ height="4.0"
348
+ modelName="six_pos"
349
+ modelPosition="tail"
350
+ preferredPlacement="anywhere"
351
+ ratio="0.5"
352
+ textColor="#000000"
353
+ visible="true"
354
+ width="4.0"
355
+ x="2.0"
356
+ y="-38.529541015625"></y:EdgeLabel>
357
+ <y:BendStyle smoothed="false"/>
358
+ </y:PolyLineEdge>
359
+ </data>
360
+ <data key="d3">UMLuses</data>
361
+ </edge>
362
+ EOS
363
+ end
364
+
365
+ def write_mixin_ref_edge(edge, class_node, mixin_node)
366
+ @out << <<EOS
367
+ <edge id="e#{ edge }"
368
+ source="n#{ mixin_node }"
369
+ target="n#{ class_node }">
370
+ <data key="d2">
371
+ <y:PolyLineEdge>
372
+ <y:Path sx="0.0"
373
+ sy="0.0"
374
+ tx="0.0"
375
+ ty="0.0"/>
376
+ <y:LineStyle color="#000000"
377
+ type="line"
378
+ width="1.0"/>
379
+ <y:Arrows source="white_delta"
380
+ target="none"/>
381
+ <y:EdgeLabel alignment="center"
382
+ distance="2.0"
383
+ fontFamily="Dialog"
384
+ fontSize="12"
385
+ fontStyle="plain"
386
+ hasBackgroundColor="false"
387
+ hasLineColor="false"
388
+ height="4.0"
389
+ modelName="six_pos"
390
+ modelPosition="tail"
391
+ preferredPlacement="anywhere"
392
+ ratio="0.5"
393
+ textColor="#000000"
394
+ visible="true"
395
+ width="4.0"
396
+ x="2.0"
397
+ y="34.529541015625"></y:EdgeLabel>
398
+ <y:BendStyle smoothed="false"/>
399
+ </y:PolyLineEdge>
400
+ </data>
401
+ <data key="d3">UMLinherits</data>
402
+ </edge>
403
+ EOS
404
+ end
405
+
406
+ def write_graphml_start(nodes, edges)
407
+ @out << <<EOS
408
+ <?xml version="1.0" encoding="UTF-8"?>
409
+ <graphml xmlns="http://graphml.graphdrawing.org/xmlns/graphml"
410
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
411
+ xmlns:y="http://www.yworks.com/xml/graphml"
412
+ xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns/graphml http://www.yworks.com/xml/schema/graphml/1.0/ygraphml.xsd">
413
+ <key for="node"
414
+ id="d0"
415
+ yfiles.type="nodegraphics"/>
416
+ <key attr.name="description"
417
+ attr.type="string"
418
+ for="node"
419
+ id="d1"/>
420
+ <key for="edge"
421
+ id="d2"
422
+ yfiles.type="edgegraphics"/>
423
+ <key attr.name="description"
424
+ attr.type="string"
425
+ for="edge"
426
+ id="d3"/>
427
+ <key for="graphml"
428
+ id="d4"
429
+ yfiles.type="resources"/>
430
+ <graph edgedefault="directed"
431
+ id="G"
432
+ parse.edges="#{ edges }"
433
+ parse.nodes="#{ nodes }"
434
+ parse.order="free">
435
+ EOS
436
+ end
437
+
438
+ def write_graphml_end
439
+ @out << <<EOS
440
+ </graph>
441
+ <data key="d4">
442
+ <y:Resources/>
443
+ </data>
444
+ </graphml>
445
+ EOS
446
+ end
447
+
448
+ end
449
+ end