xseed 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/.github/workflows/rake.yml +16 -0
  3. data/.github/workflows/release.yml +25 -0
  4. data/.gitignore +72 -0
  5. data/.rspec +3 -0
  6. data/.rubocop.yml +11 -0
  7. data/.rubocop_todo.yml +432 -0
  8. data/CHANGELOG.adoc +446 -0
  9. data/Gemfile +21 -0
  10. data/LICENSE.adoc +29 -0
  11. data/README.adoc +386 -0
  12. data/Rakefile +11 -0
  13. data/examples/README.adoc +334 -0
  14. data/examples/advanced_usage.rb +286 -0
  15. data/examples/html_generation.rb +167 -0
  16. data/examples/parser_usage.rb +102 -0
  17. data/examples/schemas/person.xsd +171 -0
  18. data/examples/simple_generation.rb +149 -0
  19. data/exe/xseed +6 -0
  20. data/lib/xseed/cli.rb +376 -0
  21. data/lib/xseed/documentation/config.rb +101 -0
  22. data/lib/xseed/documentation/constants.rb +76 -0
  23. data/lib/xseed/documentation/generators/hierarchy_table_generator.rb +554 -0
  24. data/lib/xseed/documentation/generators/instance_sample_generator.rb +723 -0
  25. data/lib/xseed/documentation/generators/properties_table_generator.rb +983 -0
  26. data/lib/xseed/documentation/html_generator.rb +836 -0
  27. data/lib/xseed/documentation/html_generator.rb.bak +723 -0
  28. data/lib/xseed/documentation/presentation/css_generator.rb +510 -0
  29. data/lib/xseed/documentation/presentation/javascript_generator.rb +151 -0
  30. data/lib/xseed/documentation/presentation/navigation_builder.rb +169 -0
  31. data/lib/xseed/documentation/schema_loader.rb +121 -0
  32. data/lib/xseed/documentation/utils/helpers.rb +205 -0
  33. data/lib/xseed/documentation/utils/namespaces.rb +149 -0
  34. data/lib/xseed/documentation/utils/references.rb +135 -0
  35. data/lib/xseed/documentation/utils/strings.rb +75 -0
  36. data/lib/xseed/models/element_declaration.rb +144 -0
  37. data/lib/xseed/parser/xsd_parser.rb +192 -0
  38. data/lib/xseed/version.rb +5 -0
  39. data/lib/xseed.rb +76 -0
  40. data/xseed.gemspec +39 -0
  41. metadata +158 -0
@@ -0,0 +1,286 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # Example: Advanced SVG Generation Usage
5
+ #
6
+ # This example demonstrates advanced features of Xseed including
7
+ # parser introspection, complex error handling, and custom workflows.
8
+
9
+ require "bundler/setup"
10
+ require "xseed"
11
+ require "fileutils"
12
+
13
+ # Advanced Example 1: Parser introspection and metadata extraction
14
+ def example_parser_introspection
15
+ puts "Advanced Example 1: Parser Introspection"
16
+ puts "=" * 60
17
+
18
+ xsd_file = File.join(__dir__, "schemas", "person.xsd")
19
+ parser = Xseed::Parser::XsdParser.new(xsd_file)
20
+
21
+ puts "Schema Metadata:"
22
+ puts " Target Namespace: #{parser.target_namespace || 'None'}"
23
+ puts " Version: #{parser.schema_version || 'Not specified'}"
24
+ puts " Element Form Default: #{parser.element_form_default || 'Not specified'}"
25
+ puts ""
26
+
27
+ puts "Global Elements:"
28
+ parser.elements.each do |element|
29
+ name = element["name"] || element.name
30
+ type = element["type"] || "inline"
31
+ puts " - #{name} (#{type})"
32
+
33
+ # Extract documentation
34
+ doc = parser.element_documentation(name)
35
+ puts " Doc: #{doc.strip}" if doc
36
+ end
37
+ puts ""
38
+
39
+ puts "Complex Types:"
40
+ parser.complex_types.each do |type|
41
+ name = type["name"] || type.name
42
+ puts " - #{name}"
43
+
44
+ # Extract documentation
45
+ doc = parser.type_documentation(name)
46
+ puts " Doc: #{doc.strip}" if doc
47
+ end
48
+ puts ""
49
+
50
+ puts "Simple Types:"
51
+ parser.simple_types.each do |type|
52
+ name = type["name"] || type.name
53
+ puts " - #{name}"
54
+ end
55
+ puts ""
56
+
57
+ puts "Namespaces:"
58
+ parser.namespaces.each do |prefix, uri|
59
+ puts " #{prefix}: #{uri}"
60
+ end
61
+ puts "\n"
62
+ end
63
+
64
+ # Advanced Example 2: Conditional generation based on schema analysis
65
+ def example_conditional_generation
66
+ puts "Advanced Example 2: Conditional Generation"
67
+ puts "=" * 60
68
+
69
+ xsd_file = File.join(__dir__, "schemas", "person.xsd")
70
+ parser = Xseed::Parser::XsdParser.new(xsd_file)
71
+
72
+ # Analyze schema complexity
73
+ total_components = parser.elements.size + parser.types.size
74
+ puts "Schema complexity: #{total_components} components"
75
+
76
+ if total_components > 50
77
+ puts "⚠ Large schema detected - generation may take time"
78
+ else
79
+ puts "✓ Schema size is optimal"
80
+ end
81
+
82
+ # Check for documentation
83
+ has_docs = !parser.documentation.nil?
84
+ puts has_docs ? "✓ Schema has documentation" : "⚠ No schema-level documentation"
85
+
86
+ # Generate with awareness of complexity
87
+ output_file = File.join(__dir__, "output", "conditional-person.svg")
88
+ FileUtils.mkdir_p(File.dirname(output_file))
89
+
90
+ start_time = Time.now
91
+ generator = Xseed::Svg::SvgGenerator.new(xsd_file)
92
+ generator.generate_file(output_file)
93
+ elapsed = Time.now - start_time
94
+
95
+ puts "\nGeneration completed in #{(elapsed * 1000).round(2)}ms"
96
+ puts "Output: #{output_file}\n\n"
97
+ end
98
+
99
+ # Advanced Example 3: Custom error handling and logging
100
+ def example_custom_error_handling
101
+ puts "Advanced Example 3: Custom Error Handling"
102
+ puts "=" * 60
103
+
104
+ test_files = [
105
+ File.join(__dir__, "schemas", "person.xsd"),
106
+ File.join(__dir__, "schemas", "nonexistent.xsd"),
107
+ File.join(__dir__, "invalid.txt"),
108
+ ]
109
+
110
+ results = { success: [], failed: [] }
111
+
112
+ test_files.each do |xsd_file|
113
+ puts "Processing: #{File.basename(xsd_file)}..."
114
+
115
+ generator = Xseed::Svg::SvgGenerator.new(xsd_file)
116
+ output_file = File.join(__dir__, "output",
117
+ "#{File.basename(xsd_file, '.xsd')}.svg")
118
+ FileUtils.mkdir_p(File.dirname(output_file))
119
+
120
+ generator.generate_file(output_file)
121
+ results[:success] << xsd_file
122
+ puts " ✓ Success\n"
123
+ rescue ArgumentError => e
124
+ results[:failed] << { file: xsd_file, error: "Validation: #{e.message}" }
125
+ puts " ✗ Validation error: #{e.message}\n"
126
+ rescue Xseed::ParserError => e
127
+ results[:failed] << { file: xsd_file, error: "Parser: #{e.message}" }
128
+ puts " ✗ Parser error: #{e.message}\n"
129
+ rescue Xseed::Svg::GenerationError => e
130
+ results[:failed] << { file: xsd_file, error: "Generation: #{e.message}" }
131
+ puts " ✗ Generation error: #{e.message}\n"
132
+ rescue StandardError => e
133
+ results[:failed] << { file: xsd_file, error: "Unexpected: #{e.message}" }
134
+ puts " ✗ Unexpected error: #{e.message}\n"
135
+ end
136
+
137
+ puts "\nSummary:"
138
+ puts " Successful: #{results[:success].size}"
139
+ puts " Failed: #{results[:failed].size}"
140
+
141
+ if results[:failed].any?
142
+ puts "\nFailed files:"
143
+ results[:failed].each do |failure|
144
+ puts " - #{File.basename(failure[:file])}: #{failure[:error]}"
145
+ end
146
+ end
147
+
148
+ puts "\n"
149
+ end
150
+
151
+ # Advanced Example 4: Performance monitoring
152
+ def example_performance_monitoring
153
+ puts "Advanced Example 4: Performance Monitoring"
154
+ puts "=" * 60
155
+
156
+ xsd_file = File.join(__dir__, "schemas", "person.xsd")
157
+ output_file = File.join(__dir__, "output", "perf-person.svg")
158
+ FileUtils.mkdir_p(File.dirname(output_file))
159
+
160
+ # Measure each phase
161
+ timings = {}
162
+
163
+ # Phase 1: File validation
164
+ timings[:validation] = measure_time do
165
+ File.exist?(xsd_file) && File.readable?(xsd_file)
166
+ end
167
+
168
+ # Phase 2: Parsing
169
+ parser = nil
170
+ timings[:parsing] = measure_time do
171
+ parser = Xseed::Parser::XsdParser.new(xsd_file)
172
+ end
173
+
174
+ # Phase 3: Generation
175
+ generator = Xseed::Svg::SvgGenerator.new(xsd_file)
176
+ timings[:generation] = measure_time do
177
+ generator.generate
178
+ end
179
+
180
+ # Phase 4: File writing
181
+ timings[:writing] = measure_time do
182
+ generator.generate_file(output_file)
183
+ end
184
+
185
+ # Total time
186
+ total = timings.values.sum
187
+
188
+ puts "Performance Breakdown:"
189
+ puts " Validation: #{format_time(timings[:validation])}"
190
+ puts " Parsing: #{format_time(timings[:parsing])}"
191
+ puts " Generation: #{format_time(timings[:generation])}"
192
+ puts " File Write: #{format_time(timings[:writing])}"
193
+ puts " ─────────────────────────"
194
+ puts " Total: #{format_time(total)}"
195
+
196
+ # File size info
197
+ file_size = File.size(output_file)
198
+ puts "\nOutput File:"
199
+ puts " Path: #{output_file}"
200
+ puts " Size: #{format_bytes(file_size)}"
201
+ puts " Rate: #{format_bytes(file_size / total)}/s" if total.positive?
202
+
203
+ puts "\n"
204
+ end
205
+
206
+ # Advanced Example 5: Integration with other tools
207
+ def example_tool_integration
208
+ puts "Advanced Example 5: Tool Integration"
209
+ puts "=" * 60
210
+
211
+ xsd_file = File.join(__dir__, "schemas", "person.xsd")
212
+ svg_file = File.join(__dir__, "output", "person-optimized.svg")
213
+ FileUtils.mkdir_p(File.dirname(svg_file))
214
+
215
+ # Generate SVG
216
+ puts "Step 1: Generate SVG..."
217
+ generator = Xseed::Svg::SvgGenerator.new(xsd_file)
218
+ generator.generate_file(svg_file)
219
+ puts " ✓ Generated: #{svg_file}"
220
+
221
+ # Example: Validate SVG with xmllint (if available)
222
+ if system("which xmllint > /dev/null 2>&1")
223
+ puts "\nStep 2: Validate SVG with xmllint..."
224
+ if system("xmllint --noout #{svg_file} 2>&1")
225
+ puts " ✓ SVG is valid XML"
226
+ else
227
+ puts " ✗ SVG validation failed"
228
+ end
229
+ else
230
+ puts "\nStep 2: xmllint not available (skipping validation)"
231
+ end
232
+
233
+ # Example: Display stats
234
+ puts "\nStep 3: File statistics..."
235
+ lines = File.readlines(svg_file).size
236
+ bytes = File.size(svg_file)
237
+ puts " Lines: #{lines}"
238
+ puts " Size: #{format_bytes(bytes)}"
239
+
240
+ puts "\n"
241
+ end
242
+
243
+ # Helper methods
244
+ def measure_time
245
+ start = Time.now
246
+ yield
247
+ Time.now - start
248
+ end
249
+
250
+ def format_time(seconds)
251
+ if seconds < 0.001
252
+ "#{(seconds * 1_000_000).round(2)}μs"
253
+ elsif seconds < 1
254
+ "#{(seconds * 1000).round(2)}ms"
255
+ else
256
+ "#{seconds.round(3)}s"
257
+ end
258
+ end
259
+
260
+ def format_bytes(bytes)
261
+ if bytes < 1024
262
+ "#{bytes}B"
263
+ elsif bytes < 1024 * 1024
264
+ "#{(bytes / 1024.0).round(2)}KB"
265
+ else
266
+ "#{(bytes / 1024.0 / 1024.0).round(2)}MB"
267
+ end
268
+ end
269
+
270
+ # Run all advanced examples
271
+ if __FILE__ == $PROGRAM_NAME
272
+ puts "\n"
273
+ puts "╔#{'═' * 58}╗"
274
+ puts "║#{' ' * 11}Xseed Advanced Usage Examples#{' ' * 16}║"
275
+ puts "╚#{'═' * 58}╝"
276
+ puts "\n"
277
+
278
+ example_parser_introspection
279
+ example_conditional_generation
280
+ example_custom_error_handling
281
+ example_performance_monitoring
282
+ example_tool_integration
283
+
284
+ puts "All advanced examples completed!"
285
+ puts "\nGenerated files are in: #{File.join(__dir__, 'output')}"
286
+ end
@@ -0,0 +1,167 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # Usage Examples for Xseed HTML Documentation Generation
5
+ # Phase 2: Weeks 5-6 - Final Integration and Testing
6
+
7
+ require_relative "../lib/xseed"
8
+
9
+ puts "=== Xseed HTML Documentation Generation Examples ===\n\n"
10
+
11
+ # Example 1: Basic HTML generation
12
+ puts "Example 1: Basic HTML Generation"
13
+ puts "-" * 50
14
+
15
+ begin
16
+ # Create generator with default configuration
17
+ xsd_path = File.expand_path("../spec/fixtures/simple/element_only.xsd",
18
+ __dir__)
19
+ generator = Xseed::Documentation::HtmlGenerator.new(xsd_path)
20
+
21
+ # Generate HTML to string
22
+ html = generator.generate
23
+
24
+ # Write to file
25
+ output_path = File.expand_path("../tmp/example1_basic.html", __dir__)
26
+ FileUtils.mkdir_p(File.dirname(output_path))
27
+ File.write(output_path, html)
28
+
29
+ puts "✓ Generated basic HTML documentation"
30
+ puts " Output: tmp/example1_basic.html"
31
+ puts " Features: Default styling, navigation, properties tables, instance samples"
32
+ puts
33
+ rescue StandardError => e
34
+ puts "✗ Error: #{e.message}"
35
+ puts
36
+ end
37
+
38
+ # Example 2: Custom configuration
39
+ puts "Example 2: Custom Configuration"
40
+ puts "-" * 50
41
+
42
+ begin
43
+ # Create custom configuration
44
+ config = Xseed::Documentation::Config.new
45
+ config.title = "My Custom Schema Documentation"
46
+ config.sort_by_component = true
47
+ config.print_glossary = true
48
+
49
+ # Create generator with custom config
50
+ xsd_path = File.expand_path("../spec/fixtures/simple/element_only.xsd",
51
+ __dir__)
52
+ generator = Xseed::Documentation::HtmlGenerator.new(xsd_path, config)
53
+
54
+ # Generate directly to file
55
+ output_path = File.expand_path("../tmp/example2_custom.html", __dir__)
56
+ FileUtils.mkdir_p(File.dirname(output_path))
57
+ generator.generate_file(output_path)
58
+
59
+ puts "✓ Generated HTML with custom configuration"
60
+ puts " Output: tmp/example2_custom.html"
61
+ puts " Custom title: #{config.title}"
62
+ puts " Sorted by component: #{config.sort_by_component}"
63
+ puts " Includes glossary: #{config.print_glossary}"
64
+ puts
65
+ rescue StandardError => e
66
+ puts "✗ Error: #{e.message}"
67
+ puts
68
+ end
69
+
70
+ # Example 3: External CSS/JS (demonstration)
71
+ puts "Example 3: External CSS/JS Configuration"
72
+ puts "-" * 50
73
+
74
+ begin
75
+ # Create configuration with external resources
76
+ config = Xseed::Documentation::Config.new
77
+ config.title = "Schema with External Resources"
78
+ # NOTE: These would typically point to actual hosted files
79
+ # config.external_css_url = "https://example.com/custom.css"
80
+ # config.jquery_url = "https://example.com/jquery.js"
81
+
82
+ xsd_path = File.expand_path("../spec/fixtures/simple/element_only.xsd",
83
+ __dir__)
84
+ generator = Xseed::Documentation::HtmlGenerator.new(xsd_path, config)
85
+
86
+ html = generator.generate
87
+ output_path = File.expand_path("../tmp/example3_external.html", __dir__)
88
+ FileUtils.mkdir_p(File.dirname(output_path))
89
+ File.write(output_path, html)
90
+
91
+ puts "✓ Generated HTML with external resource configuration"
92
+ puts " Output: tmp/example3_external.html"
93
+ puts " Note: External CSS/JS URLs can be configured via Config object"
94
+ puts " Default: Uses embedded styles and CDN-hosted jQuery/Bootstrap"
95
+ puts
96
+ rescue StandardError => e
97
+ puts "✗ Error: #{e.message}"
98
+ puts
99
+ end
100
+
101
+ # Example 4: Batch generation
102
+ puts "Example 4: Batch Generation"
103
+ puts "-" * 50
104
+
105
+ begin
106
+ # Define schemas to process
107
+ base_dir = File.expand_path("..", __dir__)
108
+ schemas = [
109
+ File.join(base_dir, "spec/fixtures/simple/element_only.xsd"),
110
+ ]
111
+
112
+ # Process each schema
113
+ tmp_dir = File.expand_path("../tmp", __dir__)
114
+ FileUtils.mkdir_p(tmp_dir)
115
+
116
+ schemas.each do |xsd_file|
117
+ next unless File.exist?(xsd_file)
118
+
119
+ name = File.basename(xsd_file, ".xsd")
120
+ output_file = File.join(tmp_dir, "batch_#{name}.html")
121
+
122
+ # Create generator
123
+ config = Xseed::Documentation::Config.new
124
+ config.title = "#{name.tr('_', ' ').capitalize} Schema"
125
+
126
+ generator = Xseed::Documentation::HtmlGenerator.new(xsd_file, config)
127
+ generator.generate_file(output_file)
128
+
129
+ puts "✓ Generated: #{output_file}"
130
+ end
131
+
132
+ puts "\n✓ Batch generation complete"
133
+ puts " All schemas processed successfully"
134
+ puts
135
+ rescue StandardError => e
136
+ puts "✗ Error: #{e.message}"
137
+ puts
138
+ end
139
+
140
+ # Example 5: CLI Usage Examples
141
+ puts "Example 5: CLI Usage"
142
+ puts "-" * 50
143
+
144
+ puts <<~CLI_EXAMPLES
145
+ Basic usage:
146
+ $ xseed html schema.xsd -o output.html
147
+
148
+ With custom title:
149
+ $ xseed html schema.xsd -o output.html --title "My Schema"
150
+
151
+ With verbose output:
152
+ $ xseed html schema.xsd -o output.html --verbose
153
+
154
+ Combine options:
155
+ $ xseed html schema.xsd -o output.html \\
156
+ --title "Custom Title" \\
157
+ --verbose
158
+
159
+ Using from Ruby code:
160
+ require 'xseed'
161
+ generator = Xseed::Documentation::HtmlGenerator.new('schema.xsd')
162
+ generator.generate_file('output.html')
163
+ CLI_EXAMPLES
164
+
165
+ puts "=== Examples Complete ===\n"
166
+ puts "Output files generated in tmp/ directory"
167
+ puts "Open any HTML file in a web browser to view the documentation"
@@ -0,0 +1,102 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "bundler/setup"
5
+ require "xseed/parser/xsd_parser"
6
+
7
+ # Example 1: Parse a simple XSD file
8
+ puts "=" * 60
9
+ puts "Example 1: Parsing a Simple XSD File"
10
+ puts "=" * 60
11
+
12
+ xsd_file = File.join(__dir__, "../spec/fixtures/simple/element_only.xsd")
13
+ parser = Xseed::Parser::XsdParser.new(xsd_file)
14
+
15
+ puts "\nTarget Namespace: #{parser.target_namespace}"
16
+ puts "Element Form Default: #{parser.element_form_default}"
17
+ puts "\nSchema Documentation:"
18
+ puts parser.documentation
19
+
20
+ puts "\nGlobal Elements:"
21
+ parser.elements.each do |element|
22
+ name = element["name"]
23
+ type = element["type"]
24
+ puts " - #{name} (#{type})"
25
+ doc = parser.element_documentation(name)
26
+ puts " Documentation: #{doc}" if doc
27
+ end
28
+
29
+ # Example 2: Parse XSD with complex types
30
+ puts "\n#{'=' * 60}"
31
+ puts "Example 2: Parsing XSD with Complex Types"
32
+ puts "=" * 60
33
+
34
+ xsd_file = File.join(__dir__, "../spec/fixtures/simple/complex_type.xsd")
35
+ parser = Xseed::Parser::XsdParser.new(xsd_file)
36
+
37
+ puts "\nTarget Namespace: #{parser.target_namespace}"
38
+
39
+ puts "\nComplex Types:"
40
+ parser.complex_types.each do |complex_type|
41
+ name = complex_type["name"]
42
+ puts " - #{name}"
43
+ doc = parser.type_documentation(name)
44
+ puts " Documentation: #{doc}" if doc
45
+ end
46
+
47
+ puts "\nGlobal Elements:"
48
+ parser.elements.each do |element|
49
+ puts " - #{element['name']} (type: #{element['type']})"
50
+ end
51
+
52
+ # Example 3: Parse XSD with simple types
53
+ puts "\n#{'=' * 60}"
54
+ puts "Example 3: Parsing XSD with Simple Types"
55
+ puts "=" * 60
56
+
57
+ xsd_file = File.join(__dir__, "../spec/fixtures/simple/simple_type.xsd")
58
+ parser = Xseed::Parser::XsdParser.new(xsd_file)
59
+
60
+ puts "\nTarget Namespace: #{parser.target_namespace}"
61
+
62
+ puts "\nSimple Types:"
63
+ parser.simple_types.each do |simple_type|
64
+ name = simple_type["name"]
65
+ puts " - #{name}"
66
+ doc = parser.type_documentation(name)
67
+ puts " Documentation: #{doc}" if doc
68
+ end
69
+
70
+ # Example 4: Explore namespace mappings
71
+ puts "\n#{'=' * 60}"
72
+ puts "Example 4: Namespace Mappings"
73
+ puts "=" * 60
74
+
75
+ puts "\nNamespace Prefixes:"
76
+ parser.namespaces.each do |prefix, uri|
77
+ puts " #{prefix} => #{uri}"
78
+ end
79
+
80
+ # Example 5: Parse real-world XSD
81
+ puts "\n#{'=' * 60}"
82
+ puts "Example 5: Parsing Real-World XSD (unitsml-v1.0.xsd)"
83
+ puts "=" * 60
84
+
85
+ xsd_file = File.join(
86
+ __dir__,
87
+ "../spec/fixtures/real_world/unitsml-v1.0.xsd",
88
+ )
89
+ parser = Xseed::Parser::XsdParser.new(xsd_file)
90
+
91
+ puts "\nTarget Namespace: #{parser.target_namespace}"
92
+ puts "Schema Version: #{parser.schema_version || 'N/A'}"
93
+ puts "\nStatistics:"
94
+ puts " Elements: #{parser.elements.size}"
95
+ puts " Complex Types: #{parser.complex_types.size}"
96
+ puts " Simple Types: #{parser.simple_types.size}"
97
+ puts " Total Types: #{parser.types.size}"
98
+ puts " Groups: #{parser.groups.size}"
99
+
100
+ puts "\n#{'=' * 60}"
101
+ puts "All examples completed successfully!"
102
+ puts "=" * 60