xsdvi 1.0.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 (41) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +30 -0
  3. data/README.adoc +317 -0
  4. data/exe/xsdvi +6 -0
  5. data/lib/xsdvi/cli.rb +163 -0
  6. data/lib/xsdvi/svg/generator.rb +93 -0
  7. data/lib/xsdvi/svg/symbol.rb +234 -0
  8. data/lib/xsdvi/svg/symbols/all.rb +46 -0
  9. data/lib/xsdvi/svg/symbols/any.rb +59 -0
  10. data/lib/xsdvi/svg/symbols/any_attribute.rb +58 -0
  11. data/lib/xsdvi/svg/symbols/attribute.rb +64 -0
  12. data/lib/xsdvi/svg/symbols/choice.rb +46 -0
  13. data/lib/xsdvi/svg/symbols/element.rb +91 -0
  14. data/lib/xsdvi/svg/symbols/field.rb +42 -0
  15. data/lib/xsdvi/svg/symbols/key.rb +46 -0
  16. data/lib/xsdvi/svg/symbols/keyref.rb +49 -0
  17. data/lib/xsdvi/svg/symbols/loop.rb +35 -0
  18. data/lib/xsdvi/svg/symbols/schema.rb +42 -0
  19. data/lib/xsdvi/svg/symbols/selector.rb +42 -0
  20. data/lib/xsdvi/svg/symbols/sequence.rb +48 -0
  21. data/lib/xsdvi/svg/symbols/unique.rb +46 -0
  22. data/lib/xsdvi/tree/builder.rb +31 -0
  23. data/lib/xsdvi/tree/element.rb +62 -0
  24. data/lib/xsdvi/utils/resource_loader.rb +21 -0
  25. data/lib/xsdvi/utils/width_calculator.rb +23 -0
  26. data/lib/xsdvi/utils/writer.rb +29 -0
  27. data/lib/xsdvi/version.rb +5 -0
  28. data/lib/xsdvi/xsd_handler.rb +323 -0
  29. data/lib/xsdvi.rb +30 -0
  30. data/resources/svg/defined_symbols.svg +9 -0
  31. data/resources/svg/doctype.txt +1 -0
  32. data/resources/svg/menu_buttons.svg +7 -0
  33. data/resources/svg/script.js +265 -0
  34. data/resources/svg/style.css +29 -0
  35. data/resources/svg/style.html +3 -0
  36. data/resources/svg/style.xml +1 -0
  37. data/resources/svg/svg_end.txt +1 -0
  38. data/resources/svg/svg_start.txt +1 -0
  39. data/resources/svg/title.txt +1 -0
  40. data/resources/svg/xml_declaration.xml +1 -0
  41. metadata +113 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: cbb88134a26f0713dea31aa8032d38e06fc8fe5e9b04b321211dd86fac4eadb5
4
+ data.tar.gz: 21cf471f50d28f47267af0cdd85a3733941e3dd23026389dd21b23fbfc6a7330
5
+ SHA512:
6
+ metadata.gz: 6c7d8578f22756bd8ae89f9f516da49a02ce926579a05fff307d244a47f8ff33dfc595c60d0fec04ba94412f722bad879da8500043f7af89bea870f10ad2ffff
7
+ data.tar.gz: 4a74687246d90e2136311111f5046fd768f9347115e2f22cb517adb922c932ca0c508efa0b5fa8ecf0cc8d09e671781b29f85594b31b52836baec98c58e9c76d
data/LICENSE ADDED
@@ -0,0 +1,30 @@
1
+ Copyright (c) Ribose Inc. All rights reserved.
2
+
3
+ Redistribution and use in source and binary forms, with or without
4
+ modification, are permitted provided that the following conditions
5
+ are met:
6
+
7
+ 1. Redistributions of source code must retain the above copyright
8
+ notice, this list of conditions and the following disclaimer.
9
+
10
+ 2. Redistributions in binary form must reproduce the above copyright
11
+ notice, this list of conditions and the following disclaimer in
12
+ the documentation and/or other materials provided with the
13
+ distribution.
14
+
15
+ 3. Neither the name of Ribose nor the names of its contributors may
16
+ be used to endorse or promote products derived from this software
17
+ without specific prior written permission.
18
+
19
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23
+ COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29
+ ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30
+ POSSIBILITY OF SUCH DAMAGE.
data/README.adoc ADDED
@@ -0,0 +1,317 @@
1
+ = XSDVI Ruby
2
+
3
+ image:https://img.shields.io/gem/v/xsdvi.svg[Gem Version]
4
+ image:https://img.shields.io/badge/license-MIT-blue.svg[License]
5
+
6
+ == Purpose
7
+
8
+ XSDVI (XML Schema Definition Visualizer) is a Ruby gem that transforms W3C XML
9
+ Schema (XSD) files into interactive, hierarchical SVG diagrams. It provides a
10
+ visual representation of complex XML Schema structures, making it easier to
11
+ understand schema relationships, element hierarchies, attribute requirements,
12
+ and data type definitions.
13
+
14
+ The tool parses XSD files and generates SVG diagrams that display:
15
+
16
+ * Element structures with their types, cardinality, and attributes
17
+ * Compositor relationships (sequence, choice, all)
18
+ * Type hierarchies and inheritance
19
+ * Identity constraints (key, keyref, unique)
20
+ * Namespace information
21
+ * Documentation annotations from the schema
22
+ * Recursive references with loop detection
23
+
24
+ This is a pure Ruby port of the original Java XsdVi tool, providing the same
25
+ functionality with modern Ruby idioms and gemification for easy integration into
26
+ Ruby projects.
27
+
28
+ == Features
29
+
30
+ === XSD Component Visualization
31
+
32
+ * Elements and Attributes: Visual boxes showing element names, types, cardinality (min..max occurrences), required/optional status, and namespace information
33
+ * Compositors: Graphical representation of sequence (ordered), choice (alternatives), and all (unordered) element groups
34
+ * Wildcards: Display of `<any>` and `<anyAttribute>` with namespace constraints and processing modes
35
+ * Identity Constraints: Visualization of key, keyref, unique constraints with their selectors and fields
36
+ * Type Information: Display of simple and complex type definitions, base types, and anonymous types
37
+
38
+ === Interactive SVG Output
39
+
40
+ * Hierarchical Layout: Tree-structure visualization with proper indentation and connections
41
+ * Collapsible/Expandable: JavaScript-enabled expand/collapse functionality for complex schemas (optional)
42
+ * Clickable Elements: Navigate between related schema components
43
+ * Documentation Display: Inline display of `<xs:documentation>` annotations
44
+ * Color-coded Symbols: Different visual styles for elements, attributes, compositors, and constraints
45
+
46
+ === Flexible Output Options
47
+
48
+ * Single Diagram: Generate one SVG showing the entire schema or a specific root element
49
+ * Per-Element Diagrams: Generate separate SVG files for each top-level element
50
+ * Custom Styling: Embed CSS in SVG files or use external stylesheets
51
+ * Output Directory: Organize generated diagrams in custom folder structures
52
+
53
+ === Processing Capabilities
54
+
55
+ * Multiple XSD Files: Process multiple schema files in a single run
56
+ * Loop Detection: Automatically detects and marks recursive element references
57
+ * Namespace Handling: Properly displays and distinguishes multiple namespaces
58
+ * Documentation Extraction: Extracts and formats XSD documentation for display
59
+ * Large Schema Support: Handles complex, real-world schemas with hundreds of elements
60
+
61
+ == Installation
62
+
63
+ Add this line to your application's Gemfile:
64
+
65
+ [source,ruby]
66
+ ----
67
+ gem 'xsdvi'
68
+ ----
69
+
70
+ And then execute:
71
+
72
+ [source,shell]
73
+ ----
74
+ bundle install
75
+ ----
76
+
77
+ Or install it yourself as:
78
+
79
+ [source,shell]
80
+ ----
81
+ gem install xsdvi
82
+ ----
83
+
84
+ == Usage
85
+
86
+ === Basic usage
87
+
88
+ Generate an SVG diagram from an XSD file:
89
+
90
+ [source,shell]
91
+ ----
92
+ xsdvi generate schema.xsd
93
+ ----
94
+
95
+ This creates `schema.svg` in the current directory, showing all top-level
96
+ elements and their hierarchical structure.
97
+
98
+ === Generate diagram for specific root element
99
+
100
+ [source,shell]
101
+ ----
102
+ xsdvi generate schema.xsd -r UnitsML
103
+ ----
104
+
105
+ This generates a diagram starting from the `UnitsML` element, showing its
106
+ complete structure and all nested elements.
107
+
108
+ === Generate separate SVG for each element
109
+
110
+ [source,shell]
111
+ ----
112
+ xsdvi generate schema.xsd -r all -o -p output/diagrams
113
+ ----
114
+
115
+ This creates individual SVG files for each top-level element in the
116
+ `output/diagrams` directory.
117
+
118
+ === Command-line options
119
+
120
+ `-r, --root-node-name NAME`::
121
+ Specify the schema root element name to visualize. Use "all" to generate
122
+ diagrams for all top-level elements. If omitted, generates a complete schema
123
+ diagram showing all elements.
124
+
125
+ `-o, --one-node-only`::
126
+ Generate diagram showing only the specified element without its children
127
+ (single-level view). Automatically enabled when using `-r all`. This mode hides
128
+ the expand/collapse control buttons.
129
+
130
+ `-p, --output-path PATH`::
131
+ Specify output directory for generated SVG files. The tool automatically creates
132
+ the directory if it doesn't exist. If omitted, files are created in the current
133
+ directory.
134
+
135
+ `--embody-style`::
136
+ Embed CSS styling directly in each SVG file (default: true). This creates
137
+ self-contained SVG files that display correctly without external dependencies.
138
+
139
+ `--generate-style FILE`::
140
+ Generate an external CSS file with the specified name and reference it from SVG
141
+ files. Useful when generating multiple diagrams that should share styling.
142
+
143
+ `--use-style URL`::
144
+ Reference an existing external CSS file at the specified URL in generated SVG
145
+ files. The CSS file must be accessible when the SVG is viewed.
146
+
147
+ === Examples
148
+
149
+ .Generate full schema diagram with root element
150
+ [example]
151
+ ====
152
+ [source,shell]
153
+ ----
154
+ xsdvi generate UnitsML-v1.0.xsd -r UnitsML
155
+ ----
156
+
157
+ Creates `UnitsML.svg` showing the complete structure starting from the UnitsML
158
+ root element, including all nested elements, attributes, and constraints.
159
+ ====
160
+
161
+ .Generate diagram for single element only
162
+ [example]
163
+ ====
164
+ [source,shell]
165
+ ----
166
+ xsdvi generate UnitsML-v1.0.xsd -r Quantity -o
167
+ ----
168
+
169
+ Creates `Quantity.svg` showing only the Quantity element definition without
170
+ expanding its children, useful for focused documentation.
171
+ ====
172
+
173
+ .Generate separate diagrams for all top-level elements
174
+ [example]
175
+ ====
176
+ [source,shell]
177
+ ----
178
+ xsdvi generate UnitsML-v1.0.xsd -r all -o -p images/SVG
179
+ ----
180
+
181
+ Creates individual SVG files (`Quantity.svg`, `Unit.svg`, etc.) in the
182
+ `images/SVG` directory, one for each top-level element in the schema.
183
+ ====
184
+
185
+ .Generate diagram using external CSS
186
+ [example]
187
+ ====
188
+ [source,shell]
189
+ ----
190
+ xsdvi generate schema.xsd --generate-style custom.css -p output
191
+ ----
192
+
193
+ Creates `output/schema.svg` and `output/custom.css`, with the SVG referencing
194
+ the external stylesheet. Useful for customizing diagram appearance.
195
+ ====
196
+
197
+ == Architecture
198
+
199
+ === Core components
200
+
201
+ TreeElement and TreeBuilder:: Manage the tree structure representing the XSD
202
+ schema hierarchy. TreeElement provides parent-child relationships, traversal
203
+ methods, and unique node identification.
204
+
205
+ XsdHandler:: Parses XSD files using Nokogiri and builds the symbol tree
206
+ structure. Handles all XSD constructs including elements, attributes,
207
+ compositors, wildcards, and identity constraints. Performs loop detection for
208
+ recursive schemas.
209
+
210
+ Symbol classes::
211
+ 14 specialized symbol types representing different XSD constructs:
212
+ +
213
+ * Element, Attribute - schema components
214
+ * Choice, Sequence, All - compositors
215
+ * Any, AnyAttribute - wildcards
216
+ * Key, Keyref, Unique - identity constraints
217
+ * Selector, Field - constraint components
218
+ * Loop - recursive reference indicator
219
+ * Schema - root container
220
+
221
+ SVG::Generator:: Generates SVG output files from the symbol tree. Manages
222
+ layout, styling, resource loading, and recursive symbol drawing. Produces
223
+ interactive diagrams with JavaScript-enabled expand/collapse functionality.
224
+
225
+ CLI:: Thor-based command-line interface providing easy access to all generation
226
+ options with built-in help and validation.
227
+
228
+ === Data flow
229
+
230
+ [source]
231
+ ----
232
+ XSD File → XsdHandler (Nokogiri parsing)
233
+
234
+ Symbol Tree (TreeBuilder)
235
+
236
+ Symbol Processing (prepare_box, calculate dimensions)
237
+
238
+ SVG Generation (Generator.draw)
239
+
240
+ SVG File Output
241
+ ----
242
+
243
+
244
+ == Differences from Java version
245
+
246
+ === Text wrapping
247
+
248
+ The Ruby implementation uses a custom text wrapping algorithm that produces
249
+ slightly different line breaks compared to Apache Commons Text
250
+ `WordUtils.wrap()`. The Ruby version optimizes for keeping related content
251
+ together when it fits within the line width, while maintaining valid XML
252
+ structure.
253
+
254
+ Impact: Documentation text may wrap at different character positions, but
255
+ the visual output and functionality remain identical. The Ruby version ensures
256
+ HTML tags and entities in documentation are not broken across lines, improving
257
+ SVG validity.
258
+
259
+ Example:
260
+
261
+ Java may break HTML tags mid-structure:
262
+
263
+ [source,xml]
264
+ ----
265
+ <text>See &lt;a</text>
266
+ <text>href="...">text&lt;/a>.</text>
267
+ ----
268
+
269
+ Ruby keeps tags together for better validity:
270
+
271
+ [source,xml]
272
+ ----
273
+ <text>See &lt;a href="...">text&lt;/a>.</text>
274
+ ----
275
+
276
+ Both outputs are functionally equivalent and render correctly in SVG viewers.
277
+ The Ruby approach actually produces more semantically correct output by
278
+ preserving the integrity of embedded HTML elements.
279
+
280
+ == Development
281
+
282
+ After checking out the repo, run `bundle install` to install dependencies.
283
+
284
+ Run tests:
285
+
286
+ [source,shell]
287
+ ----
288
+ bundle exec rspec
289
+ ----
290
+
291
+ Run rubocop:
292
+
293
+ [source,shell]
294
+ ----
295
+ bundle exec rubocop
296
+ ----
297
+
298
+ == Contributing
299
+
300
+ Bug reports and pull requests are welcome on GitHub at
301
+ https://github.com/metanorma/xsdvi-ruby
302
+
303
+ == Copyright and license
304
+
305
+ Copyright https://www.ribose.com[Ribose Inc.]
306
+
307
+ The gem is available as open source under the Ribose 3-Clause BSD License.
308
+
309
+ == Acknowledgments
310
+
311
+ This is a Ruby port of the Metanorma version of the XsdVi tool, which is itself
312
+ a fork of the original XsdVi Java tool created by Václav Slavìtínský. See the
313
+ original project at https://sourceforge.net/projects/xsdvi/
314
+
315
+ The Ruby port maintains compatibility with the Java version's output format
316
+ while providing a pure Ruby implementation suitable for modern Ruby applications
317
+ and workflows.
data/exe/xsdvi ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require_relative "../lib/xsdvi"
5
+
6
+ Xsdvi::CLI.start(ARGV)
data/lib/xsdvi/cli.rb ADDED
@@ -0,0 +1,163 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "thor"
4
+
5
+ module Xsdvi
6
+ # Command-line interface for XSDVI
7
+ class CLI < Thor
8
+ def self.exit_on_failure?
9
+ true
10
+ end
11
+
12
+ desc "generate INPUT [INPUT2...] [OPTIONS]",
13
+ "Generate SVG diagrams from XSD schema files"
14
+ method_option :root_node_name,
15
+ type: :string,
16
+ aliases: "-r",
17
+ desc: "Schema root node name (or 'all' for all elements)"
18
+ method_option :one_node_only,
19
+ type: :boolean,
20
+ aliases: "-o",
21
+ desc: "Show only one element"
22
+ method_option :output_path,
23
+ type: :string,
24
+ aliases: "-p",
25
+ desc: "Output folder path"
26
+ method_option :embody_style,
27
+ type: :boolean,
28
+ default: true,
29
+ desc: "Embody CSS style in SVG (default: true)"
30
+ method_option :generate_style,
31
+ type: :string,
32
+ desc: "Generate CSS file with specified name"
33
+ method_option :use_style,
34
+ type: :string,
35
+ desc: "Use external CSS file at specified URL"
36
+ def generate(*inputs)
37
+ if inputs.empty?
38
+ puts "Error: No input files specified"
39
+ exit(1)
40
+ end
41
+
42
+ # Validate input files exist
43
+ inputs.each do |input|
44
+ unless File.exist?(input)
45
+ puts "Error: XSD file '#{input}' not found!"
46
+ exit(1)
47
+ end
48
+ end
49
+
50
+ # Process options
51
+ root_node_name = options[:root_node_name]
52
+ one_node_only = options[:one_node_only]
53
+ one_node_only = true if root_node_name == "all"
54
+ output_path = options[:output_path]
55
+
56
+ # Determine style mode
57
+ style_mode = determine_style_mode(options)
58
+
59
+ # Process each input file
60
+ builder = Tree::Builder.new
61
+ xsd_handler = XsdHandler.new(builder)
62
+ writer_helper = Utils::Writer.new
63
+ svg_generator = SVG::Generator.new(writer_helper)
64
+
65
+ svg_generator.hide_menu_buttons = one_node_only
66
+
67
+ apply_style_settings(svg_generator, style_mode, options)
68
+
69
+ inputs.each do |input|
70
+ process_input_file(
71
+ input,
72
+ xsd_handler,
73
+ svg_generator,
74
+ builder,
75
+ writer_helper,
76
+ root_node_name,
77
+ one_node_only,
78
+ output_path,
79
+ )
80
+ end
81
+ end
82
+
83
+ default_task :generate
84
+
85
+ private
86
+
87
+ def determine_style_mode(options)
88
+ return :generate_style if options[:generate_style]
89
+ return :use_style if options[:use_style]
90
+
91
+ :embody_style
92
+ end
93
+
94
+ def apply_style_settings(svg_generator, style_mode, options)
95
+ case style_mode
96
+ when :embody_style
97
+ puts "The style will be embodied"
98
+ svg_generator.embody_style = true
99
+ when :generate_style
100
+ style_url = options[:generate_style]
101
+ puts "Generating style #{style_url}..."
102
+ svg_generator.embody_style = false
103
+ svg_generator.style_uri = style_url
104
+ svg_generator.print_extern_style
105
+ puts "Done."
106
+ when :use_style
107
+ style_url = options[:use_style]
108
+ puts "Using external style #{style_url}"
109
+ svg_generator.embody_style = false
110
+ svg_generator.style_uri = style_url
111
+ end
112
+ end
113
+
114
+ def process_input_file(input, xsd_handler, svg_generator, builder,
115
+ writer_helper, root_node_name, one_node_only,
116
+ output_path)
117
+ puts "Parsing #{input}..."
118
+
119
+ xsd_handler.root_node_name = root_node_name
120
+ xsd_handler.one_node_only = one_node_only
121
+
122
+ # Parse and process XSD
123
+ xsd_handler.process_file(input)
124
+
125
+ puts "Processing XML Schema model..."
126
+
127
+ # Generate output filename
128
+ output_file = generate_output_filename(
129
+ input,
130
+ root_node_name,
131
+ one_node_only,
132
+ output_path,
133
+ )
134
+
135
+ puts "Drawing SVG #{output_file}..."
136
+ writer_helper.new_writer(output_file)
137
+
138
+ if builder.root
139
+ svg_generator.draw(builder.root)
140
+ puts "Done."
141
+ else
142
+ warn "SVG is empty!"
143
+ end
144
+ end
145
+
146
+ def generate_output_filename(input, root_node_name, one_node_only,
147
+ output_path)
148
+ basename = File.basename(input, ".*")
149
+ filename = if root_node_name && one_node_only
150
+ "#{root_node_name}.svg"
151
+ else
152
+ "#{basename}.svg"
153
+ end
154
+
155
+ if output_path
156
+ FileUtils.mkdir_p(output_path)
157
+ File.join(output_path, filename)
158
+ else
159
+ filename
160
+ end
161
+ end
162
+ end
163
+ end
@@ -0,0 +1,93 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../utils/resource_loader"
4
+
5
+ module Xsdvi
6
+ module SVG
7
+ # Generates SVG files from symbol trees
8
+ class Generator
9
+ attr_accessor :writer, :embody_style, :style_uri, :hide_menu_buttons
10
+
11
+ def initialize(writer)
12
+ @writer = writer
13
+ @embody_style = true
14
+ @style_uri = nil
15
+ @hide_menu_buttons = false
16
+ @resource_loader = Utils::ResourceLoader.new
17
+ end
18
+
19
+ def draw(root_symbol)
20
+ # Reset class variables before drawing
21
+ Symbol.reset_class_variables
22
+
23
+ svg_begin
24
+ draw_symbol(root_symbol)
25
+ svg_end
26
+ end
27
+
28
+ def print_extern_style
29
+ writer.new_writer(style_uri)
30
+ print(load_resource("svg/style.css"))
31
+ writer.close
32
+ end
33
+
34
+ def print(string)
35
+ writer.append("#{string}\n")
36
+ end
37
+
38
+ private
39
+
40
+ def svg_begin
41
+ print(load_resource("svg/xml_declaration.xml"))
42
+ print_style_ref unless embody_style
43
+ print(load_resource("svg/doctype.txt"))
44
+ print(load_resource("svg/svg_start.txt"))
45
+ print(load_resource("svg/title.txt"))
46
+
47
+ script = load_resource("svg/script.js")
48
+ script = script.gsub("%HEIGHT_SUM%", (Symbol::MAX_HEIGHT + Symbol::Y_INDENT).to_s)
49
+ script = script.gsub("%HEIGHT_HALF%", (Symbol::MAX_HEIGHT / 2).to_s)
50
+ print(script)
51
+
52
+ print_defs(embody_style, true)
53
+ print(load_resource("svg/menu_buttons.svg")) unless hide_menu_buttons
54
+ end
55
+
56
+ def svg_end
57
+ print(load_resource("svg/svg_end.txt"))
58
+ writer.close
59
+ end
60
+
61
+ def print_style_ref
62
+ style_template = load_resource("svg/style.xml")
63
+ print(style_template.gsub("%STYLE_URI%", style_uri))
64
+ end
65
+
66
+ def print_embodied_style
67
+ style_template = load_resource("svg/style.html")
68
+ style = load_resource("svg/style.css")
69
+ print(style_template.gsub("%STYLE%", style))
70
+ end
71
+
72
+ def print_defs(style, symbols)
73
+ print("<defs>")
74
+ print_embodied_style if style
75
+ print(load_resource("svg/defined_symbols.svg")) if symbols
76
+ print("</defs>")
77
+ end
78
+
79
+ def draw_symbol(symbol)
80
+ symbol.svg = self
81
+ symbol.prepare_box
82
+ symbol.draw
83
+ symbol.children.each do |child|
84
+ draw_symbol(child)
85
+ end
86
+ end
87
+
88
+ def load_resource(path)
89
+ @resource_loader.read_resource_file(path)
90
+ end
91
+ end
92
+ end
93
+ end