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,135 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Xseed
4
+ module Documentation
5
+ module Utils
6
+ # References utility module for handling XSD component references
7
+ #
8
+ # This module provides methods for extracting component names, prefixes,
9
+ # and namespaces from qualified and unqualified references in XML Schema.
10
+ #
11
+ # Based on XS3P references.xsl utilities.
12
+ module References
13
+ XSD_NAMESPACE = "http://www.w3.org/2001/XMLSchema"
14
+
15
+ # Extracts the local name from a reference
16
+ #
17
+ # @param ref [String, nil] The reference string (e.g., "xs:string" or "SimpleType")
18
+ # @return [String] The local name part of the reference
19
+ #
20
+ # @example
21
+ # get_ref_name("xs:string") #=> "string"
22
+ # get_ref_name("SimpleType") #=> "SimpleType"
23
+ # get_ref_name(nil) #=> ""
24
+ def get_ref_name(ref)
25
+ return "" if ref.nil? || ref.empty?
26
+
27
+ if ref.include?(":")
28
+ # Extract local name after first colon
29
+ ref.split(":", 2).last
30
+ else
31
+ # No prefix, return as-is
32
+ ref
33
+ end
34
+ end
35
+
36
+ # Extracts the namespace prefix from a reference
37
+ #
38
+ # @param ref [String, nil] The reference string (e.g., "xs:string")
39
+ # @return [String] The namespace prefix or empty string if none
40
+ #
41
+ # @example
42
+ # get_ref_prefix("xs:string") #=> "xs"
43
+ # get_ref_prefix("SimpleType") #=> ""
44
+ # get_ref_prefix(nil) #=> ""
45
+ def get_ref_prefix(ref)
46
+ return "" if ref.nil? || ref.empty?
47
+
48
+ if ref.include?(":")
49
+ # Extract prefix before first colon
50
+ ref.split(":", 2).first
51
+ else
52
+ # No prefix
53
+ ""
54
+ end
55
+ end
56
+
57
+ # Resolves the namespace URI from a reference prefix
58
+ #
59
+ # @param ref [String, nil] The reference string (e.g., "xs:string")
60
+ # @param schema [Object] The schema object with namespaces hash
61
+ # @return [String, nil] The resolved namespace URI or nil
62
+ #
63
+ # @example
64
+ # get_ref_namespace("xs:string", schema) #=> "http://www.w3.org/2001/XMLSchema"
65
+ # get_ref_namespace("SimpleType", schema) #=> nil
66
+ def get_ref_namespace(ref, schema)
67
+ return nil if ref.nil? || ref.empty? || schema.nil?
68
+
69
+ prefix = get_ref_prefix(ref)
70
+ return nil if prefix.empty?
71
+
72
+ schema.namespaces[prefix]
73
+ end
74
+
75
+ # Returns the declared prefix of the schema's target namespace
76
+ #
77
+ # @param schema [Object] The schema object with target_namespace and namespaces
78
+ # @return [String] The prefix for the target namespace or empty string
79
+ #
80
+ # @example
81
+ # get_this_prefix(schema) #=> "tns"
82
+ def get_this_prefix(schema)
83
+ return "" if schema.nil? || schema.target_namespace.nil?
84
+
85
+ target_ns = schema.target_namespace
86
+ namespaces = schema.namespaces || {}
87
+
88
+ # Find the prefix that maps to the target namespace
89
+ prefix = namespaces.find { |_k, v| v == target_ns }&.first
90
+ prefix || ""
91
+ end
92
+
93
+ # Returns the declared prefix of the XML Schema namespace
94
+ #
95
+ # @param schema [Object] The schema object with namespaces hash
96
+ # @return [String] The prefix for XSD namespace or empty string
97
+ #
98
+ # @example
99
+ # get_xsd_prefix(schema) #=> "xs" or "xsd"
100
+ def get_xsd_prefix(schema)
101
+ return "" if schema.nil?
102
+
103
+ namespaces = schema.namespaces || {}
104
+
105
+ # Find the prefix that maps to the XSD namespace
106
+ prefix = namespaces.find { |_k, v| v == XSD_NAMESPACE }&.first
107
+ prefix || ""
108
+ end
109
+
110
+ # Resolves a type reference to its components
111
+ #
112
+ # @param ref [String, nil] The type reference (e.g., "xs:string" or "MyType")
113
+ # @param schema [Object] The schema object with namespaces
114
+ # @return [Hash] Hash with :namespace, :prefix, and :local_name keys
115
+ #
116
+ # @example
117
+ # resolve_type_ref("xs:string", schema)
118
+ # #=> { namespace: "http://www.w3.org/2001/XMLSchema",
119
+ # # prefix: "xs", local_name: "string" }
120
+ def resolve_type_ref(ref, schema)
121
+ if ref.nil? || ref.empty?
122
+ return { namespace: nil, prefix: "",
123
+ local_name: "" }
124
+ end
125
+
126
+ {
127
+ namespace: get_ref_namespace(ref, schema),
128
+ prefix: get_ref_prefix(ref),
129
+ local_name: get_ref_name(ref),
130
+ }
131
+ end
132
+ end
133
+ end
134
+ end
135
+ end
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Xseed
4
+ module Documentation
5
+ module Utils
6
+ # String manipulation utilities
7
+ # Ported from xs3p utils/strings.xsl
8
+ module Strings
9
+ # Translates occurrences of single and double quotes with escape
10
+ # characters
11
+ #
12
+ # @param text [String] Text to translate
13
+ # @return [String] Text with escaped quotes
14
+ def self.escape_quotes(text)
15
+ return text if text.nil? || text.empty?
16
+
17
+ # Escape single quotes
18
+ result = text.gsub("'", "\\\\'")
19
+ # Escape double quotes
20
+ result.gsub('"', '\\\\"')
21
+ end
22
+
23
+ # Repeatedly output content
24
+ #
25
+ # @param content [String] The content to be output
26
+ # @param count [Integer] Number of times to output the content
27
+ # @return [String] Repeated content
28
+ def self.repeat(content, count)
29
+ return "" if count <= 0
30
+
31
+ content * count
32
+ end
33
+
34
+ # Translates occurrences of a string in a piece of text with another
35
+ # string
36
+ #
37
+ # @param value [String] Text to translate
38
+ # @param str_to_replace [String] String to be replaced
39
+ # @param replacement_str [String] Replacement text
40
+ # @return [String] Translated text
41
+ def self.translate(value, str_to_replace, replacement_str)
42
+ return value if value.nil? || value.empty?
43
+ return value unless value.include?(str_to_replace)
44
+
45
+ value.gsub(str_to_replace, replacement_str)
46
+ end
47
+
48
+ # Normalizes whitespace in a string by:
49
+ # - Converting tabs and newlines to spaces
50
+ # - Collapsing multiple spaces to single space
51
+ # - Trimming leading and trailing whitespace
52
+ #
53
+ # @param text [String] Text to normalize
54
+ # @return [String] Normalized text
55
+ def self.normalize_whitespace(text)
56
+ return "" if text.nil? || text.empty?
57
+
58
+ text.gsub(/[\t\n\r]+/, " ")
59
+ .gsub(/\s+/, " ")
60
+ .strip
61
+ end
62
+
63
+ # Splits a string by whitespace into an array
64
+ #
65
+ # @param text [String] Text to split
66
+ # @return [Array<String>] Array of tokens
67
+ def self.split_whitespace(text)
68
+ return [] if text.nil? || text.empty?
69
+
70
+ normalize_whitespace(text).split
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,144 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "lutaml/model"
4
+
5
+ module Xseed
6
+ module Models
7
+ # Represents an XSD element declaration
8
+ #
9
+ # This model captures all properties of an xs:element declaration including
10
+ # name, type, occurrence constraints, and documentation.
11
+ #
12
+ # @example Creating an element
13
+ # element = ElementDeclaration.new(
14
+ # name: "Person",
15
+ # type: "PersonType",
16
+ # min_occurs: 0,
17
+ # max_occurs: "unbounded"
18
+ # )
19
+ #
20
+ class ElementDeclaration < Lutaml::Model::Serializable
21
+ attribute :name, :string
22
+ attribute :type, :string
23
+ attribute :min_occurs, :integer, default: -> { 1 }
24
+ attribute :max_occurs, :string, default: -> { "1" }
25
+ attribute :nillable, Lutaml::Model::Type::Boolean, default: -> { false }
26
+ attribute :abstract, Lutaml::Model::Type::Boolean, default: -> { false }
27
+ attribute :substitution_group, :string
28
+ attribute :documentation, :string
29
+ attribute :default_value, :string
30
+ attribute :fixed_value, :string
31
+
32
+ xml do
33
+ root "element"
34
+ namespace "http://www.w3.org/2001/XMLSchema", "xs"
35
+
36
+ map_attribute "name", to: :name
37
+ map_attribute "type", to: :type
38
+ map_attribute "minOccurs", to: :min_occurs
39
+ map_attribute "maxOccurs", to: :max_occurs
40
+ map_attribute "nillable", to: :nillable
41
+ map_attribute "abstract", to: :abstract
42
+ map_attribute "substitutionGroup", to: :substitution_group
43
+ map_attribute "default", to: :default_value
44
+ map_attribute "fixed", to: :fixed_value
45
+ end
46
+
47
+ yaml do
48
+ map "name", to: :name
49
+ map "type", to: :type
50
+ map "min_occurs", to: :min_occurs
51
+ map "max_occurs", to: :max_occurs
52
+ map "nillable", to: :nillable
53
+ map "abstract", to: :abstract
54
+ map "substitution_group", to: :substitution_group
55
+ map "documentation", to: :documentation
56
+ map "default_value", to: :default_value
57
+ map "fixed_value", to: :fixed_value
58
+ end
59
+
60
+ json do
61
+ map "name", to: :name
62
+ map "type", to: :type
63
+ map "minOccurs", to: :min_occurs
64
+ map "maxOccurs", to: :max_occurs
65
+ map "nillable", to: :nillable
66
+ map "abstract", to: :abstract
67
+ map "substitutionGroup", to: :substitution_group
68
+ map "documentation", to: :documentation
69
+ map "defaultValue", to: :default_value
70
+ map "fixedValue", to: :fixed_value
71
+ end
72
+
73
+ # Parse an element declaration from an XSD Nokogiri node
74
+ #
75
+ # @param node [Nokogiri::XML::Element] The xs:element node
76
+ # @return [ElementDeclaration] The parsed element declaration
77
+ def self.from_xsd_node(node)
78
+ new(
79
+ name: node["name"],
80
+ type: node["type"],
81
+ min_occurs: parse_occurs(node["minOccurs"], 1),
82
+ max_occurs: node["maxOccurs"] || "1",
83
+ nillable: parse_boolean(node["nillable"]),
84
+ abstract: parse_boolean(node["abstract"]),
85
+ substitution_group: node["substitutionGroup"],
86
+ default_value: node["default"],
87
+ fixed_value: node["fixed"],
88
+ documentation: extract_documentation(node),
89
+ )
90
+ end
91
+
92
+ # Check if the element is optional (minOccurs = 0)
93
+ #
94
+ # @return [Boolean] true if the element is optional
95
+ def optional?
96
+ min_occurs.zero?
97
+ end
98
+
99
+ # Check if the element is unbounded (maxOccurs = "unbounded")
100
+ #
101
+ # @return [Boolean] true if the element is unbounded
102
+ def unbounded?
103
+ max_occurs == "unbounded"
104
+ end
105
+
106
+ # Check if the element has documentation
107
+ #
108
+ # @return [Boolean] true if documentation is present
109
+ def documented?
110
+ !documentation.nil? && !documentation.empty?
111
+ end
112
+
113
+ # Get occurrence string representation
114
+ #
115
+ # @return [String] Occurrence representation like "[0..1]" or "[1..∞]"
116
+ def occurrence_string
117
+ return "" if min_occurs == 1 && max_occurs == "1"
118
+
119
+ max_display = max_occurs == "unbounded" ? "∞" : max_occurs
120
+ "[#{min_occurs}..#{max_display}]"
121
+ end
122
+
123
+ private_class_method def self.parse_occurs(value, default)
124
+ return default if value.nil? || value.empty?
125
+
126
+ value.to_i
127
+ end
128
+
129
+ private_class_method def self.parse_boolean(value)
130
+ value == "true"
131
+ end
132
+
133
+ private_class_method def self.extract_documentation(node)
134
+ doc_node = node.at_xpath(
135
+ "xs:annotation/xs:documentation",
136
+ "xs" => "http://www.w3.org/2001/XMLSchema",
137
+ )
138
+ return nil unless doc_node
139
+
140
+ doc_node.text.strip
141
+ end
142
+ end
143
+ end
144
+ end
@@ -0,0 +1,192 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "nokogiri"
4
+
5
+ module Xseed
6
+ module Parser
7
+ # XSD Parser for extracting schema components and metadata
8
+ #
9
+ # This class parses XML Schema Definition (XSD) files using Nokogiri
10
+ # and provides methods to access schema components such as elements,
11
+ # types, groups, and documentation.
12
+ #
13
+ # @example Parse an XSD file
14
+ # parser = Xseed::Parser::XsdParser.new("schema.xsd")
15
+ # elements = parser.elements
16
+ # types = parser.types
17
+ #
18
+ class XsdParser
19
+ attr_reader :document, :schema, :target_namespace
20
+
21
+ XSD_NS = "http://www.w3.org/2001/XMLSchema"
22
+
23
+ # Initialize the parser with an XSD file path
24
+ #
25
+ # @param xsd_file_path [String] Path to the XSD file
26
+ # @raise [Errno::ENOENT] if file does not exist
27
+ def initialize(xsd_file_path)
28
+ content = File.read(xsd_file_path)
29
+ @document = Nokogiri::XML(content, &:strict)
30
+ @schema = @document.root
31
+
32
+ raise ParserError, "Invalid XSD: No root element found" unless @schema
33
+
34
+ parse_schema
35
+ rescue Nokogiri::XML::SyntaxError => e
36
+ raise ParserError, "Invalid XML syntax: #{e.message}"
37
+ end
38
+
39
+ # Get the elementFormDefault attribute value
40
+ #
41
+ # @return [String, nil] The elementFormDefault value
42
+ def element_form_default
43
+ schema["elementFormDefault"]
44
+ end
45
+
46
+ # Get the schema version attribute
47
+ #
48
+ # @return [String, nil] The schema version if present
49
+ def schema_version
50
+ schema["version"]
51
+ end
52
+
53
+ # Get all global element definitions
54
+ #
55
+ # @return [Array<Nokogiri::XML::Element>] Array of element nodes
56
+ def elements
57
+ xpath("//xs:schema/xs:element")
58
+ end
59
+
60
+ # Get all complex type definitions
61
+ #
62
+ # @return [Array<Nokogiri::XML::Element>] Array of complexType nodes
63
+ def complex_types
64
+ xpath("//xs:schema/xs:complexType")
65
+ end
66
+
67
+ # Get all simple type definitions
68
+ #
69
+ # @return [Array<Nokogiri::XML::Element>] Array of simpleType nodes
70
+ def simple_types
71
+ xpath("//xs:schema/xs:simpleType")
72
+ end
73
+
74
+ # Get all type definitions (both complex and simple)
75
+ #
76
+ # @return [Array<Nokogiri::XML::Element>] Array of type nodes
77
+ def types
78
+ complex_types + simple_types
79
+ end
80
+
81
+ # Get all group definitions
82
+ #
83
+ # @return [Array<Nokogiri::XML::Element>] Array of group nodes
84
+ def groups
85
+ xpath("//xs:schema/xs:group")
86
+ end
87
+
88
+ # Get all attribute group definitions
89
+ #
90
+ # @return [Array<Nokogiri::XML::Element>] Array of attributeGroup nodes
91
+ def attribute_groups
92
+ xpath("//xs:schema/xs:attributeGroup")
93
+ end
94
+
95
+ # Get namespace mappings from the schema
96
+ #
97
+ # @return [Hash<String, String>] Hash mapping prefixes to namespace URIs
98
+ def namespaces
99
+ schema.namespaces.transform_keys do |key|
100
+ key.sub(/^xmlns:/, "")
101
+ end
102
+ end
103
+
104
+ # Get schema-level documentation
105
+ #
106
+ # @return [String, nil] The documentation text or nil
107
+ def documentation
108
+ doc_node = schema.at_xpath(
109
+ "xs:annotation/xs:documentation",
110
+ "xs" => XSD_NS,
111
+ )
112
+ return nil unless doc_node
113
+
114
+ doc_node.text.strip
115
+ end
116
+
117
+ # Get documentation for a specific element by name
118
+ #
119
+ # @param element_name [String] The name of the element
120
+ # @return [String, nil] The documentation text or nil
121
+ def element_documentation(element_name)
122
+ element = schema.at_xpath(
123
+ "xs:element[@name='#{element_name}']",
124
+ "xs" => XSD_NS,
125
+ )
126
+ return nil unless element
127
+
128
+ extract_documentation(element)
129
+ end
130
+
131
+ # Get documentation for a specific type by name
132
+ #
133
+ # @param type_name [String] The name of the type
134
+ # @return [String, nil] The documentation text or nil
135
+ def type_documentation(type_name)
136
+ type_node = schema.at_xpath(
137
+ "xs:complexType[@name='#{type_name}'] | " \
138
+ "xs:simpleType[@name='#{type_name}']",
139
+ "xs" => XSD_NS,
140
+ )
141
+ return nil unless type_node
142
+
143
+ extract_documentation(type_node)
144
+ end
145
+
146
+ # Get all import declarations
147
+ #
148
+ # @return [Array<Nokogiri::XML::Element>] Array of import nodes
149
+ def imports
150
+ xpath("//xs:schema/xs:import")
151
+ end
152
+
153
+ # Get all include declarations
154
+ #
155
+ # @return [Array<Nokogiri::XML::Element>] Array of include nodes
156
+ def includes
157
+ xpath("//xs:schema/xs:include")
158
+ end
159
+
160
+ private
161
+
162
+ # Parse the schema and extract metadata
163
+ def parse_schema
164
+ return unless schema
165
+
166
+ @target_namespace = schema["targetNamespace"]
167
+ end
168
+
169
+ # Execute XPath query with XSD namespace
170
+ #
171
+ # @param xpath_expr [String] XPath expression
172
+ # @return [Array<Nokogiri::XML::Element>] Matching nodes
173
+ def xpath(xpath_expr)
174
+ document.xpath(xpath_expr, "xs" => XSD_NS)
175
+ end
176
+
177
+ # Extract documentation from an XML node
178
+ #
179
+ # @param node [Nokogiri::XML::Element] The node to extract from
180
+ # @return [String, nil] The documentation text or nil
181
+ def extract_documentation(node)
182
+ doc_node = node.at_xpath(
183
+ "xs:annotation/xs:documentation",
184
+ "xs" => XSD_NS,
185
+ )
186
+ return nil unless doc_node
187
+
188
+ doc_node.text.strip
189
+ end
190
+ end
191
+ end
192
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Xseed
4
+ VERSION = "1.0.0"
5
+ end
data/lib/xseed.rb ADDED
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "xseed/version"
4
+
5
+ module Xseed
6
+ class Error < StandardError; end
7
+ class ParserError < Error; end
8
+ class GenerationError < Error; end
9
+
10
+ autoload :CLI, "xseed/cli"
11
+
12
+ module Parser
13
+ autoload :XsdParser, "xseed/parser/xsd_parser"
14
+ autoload :SchemaParser, "xseed/parser/schema_parser"
15
+ autoload :NamespaceResolver, "xseed/parser/namespace_resolver"
16
+ autoload :AnnotationExtractor, "xseed/parser/annotation_extractor"
17
+ end
18
+
19
+ module Models
20
+ autoload :Schema, "xseed/models/schema"
21
+ autoload :Element, "xseed/models/element"
22
+ autoload :ComplexType, "xseed/models/complex_type"
23
+ autoload :SimpleType, "xseed/models/simple_type"
24
+ autoload :Attribute, "xseed/models/attribute"
25
+ autoload :Group, "xseed/models/group"
26
+ end
27
+
28
+ module Documentation
29
+ autoload :Generator, "xseed/documentation/generator"
30
+ autoload :HtmlGenerator, "xseed/documentation/html_generator"
31
+ autoload :Config, "xseed/documentation/config"
32
+
33
+ module Core
34
+ autoload :Parameters, "xseed/documentation/core/parameters"
35
+ autoload :Constants, "xseed/documentation/core/constants"
36
+ end
37
+
38
+ module Utilities
39
+ autoload :StringHelpers, "xseed/documentation/utilities/string_helpers"
40
+ autoload :NamespaceHelpers,
41
+ "xseed/documentation/utilities/namespace_helpers"
42
+ autoload :ReferenceResolver,
43
+ "xseed/documentation/utilities/reference_resolver"
44
+ autoload :SchemaLocationHelper,
45
+ "xseed/documentation/utilities/schema_location_helper"
46
+ end
47
+
48
+ module Renderers
49
+ autoload :XMLPrettyPrinter,
50
+ "xseed/documentation/renderers/xml_pretty_printer"
51
+ autoload :GlossaryRenderer,
52
+ "xseed/documentation/renderers/glossary_renderer"
53
+ autoload :UIComponentRenderer,
54
+ "xseed/documentation/renderers/ui_component_renderer"
55
+ end
56
+
57
+ module Sections
58
+ autoload :ComponentLinks,
59
+ "xseed/documentation/sections/component_links"
60
+ autoload :HierarchyTables,
61
+ "xseed/documentation/sections/hierarchy_tables"
62
+ autoload :PropertiesTables,
63
+ "xseed/documentation/sections/properties_tables"
64
+ autoload :SchemaComponents,
65
+ "xseed/documentation/sections/schema_components"
66
+ end
67
+
68
+ module Presentation
69
+ autoload :HTMLDocument,
70
+ "xseed/documentation/presentation/html_document"
71
+ autoload :Navigation, "xseed/documentation/presentation/navigation"
72
+ autoload :CSSStyles, "xseed/documentation/presentation/css_styles"
73
+ autoload :JavaScript, "xseed/documentation/presentation/javascript"
74
+ end
75
+ end
76
+ end
data/xseed.gemspec ADDED
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lib/xseed/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "xseed"
7
+ spec.version = Xseed::VERSION
8
+ spec.authors = ["Ribose"]
9
+ spec.email = ["open.source@ribose.com"]
10
+
11
+ spec.summary = "Ruby XSD documentation generator with unified SVG and HTML output"
12
+ spec.description = "Generate comprehensive XSD documentation with SVG diagrams (via xsdvi gem) and HTML reference (XS3P port)"
13
+ spec.homepage = "https://github.com/metanorma/xseed"
14
+ spec.license = "BSD-2-Clause"
15
+
16
+ spec.required_ruby_version = ">= 2.7.0"
17
+
18
+ spec.metadata["homepage_uri"] = spec.homepage
19
+ spec.metadata["source_code_uri"] = spec.homepage
20
+ spec.metadata["changelog_uri"] = "#{spec.homepage}/blob/main/CHANGELOG.adoc"
21
+ spec.metadata["rubygems_mfa_required"] = "true"
22
+
23
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
24
+ `git ls-files -z`.split("\x0").reject do |f|
25
+ f.match(%r{\A(?:test|spec|features)/})
26
+ end
27
+ end
28
+
29
+ spec.bindir = "exe"
30
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
31
+ spec.require_paths = ["lib"]
32
+
33
+ # Runtime dependencies
34
+ spec.add_dependency "lutaml-model", "~> 0.7"
35
+ spec.add_dependency "lutaml-xsd", "~> 1.0"
36
+ spec.add_dependency "nokogiri", "~> 1.16"
37
+ spec.add_dependency "thor", "~> 1.3"
38
+ spec.add_dependency "xsdvi", "~> 1.0"
39
+ end