Class: Rng::RncBuilder
- Inherits:
-
Object
- Object
- Rng::RncBuilder
- Defined in:
- lib/rng/rnc_builder.rb
Overview
RncBuilder converts RNG Grammar objects to RNC (RELAX NG Compact Syntax) text format.
This class traverses the RNG object model and generates readable RNC syntax strings. It handles all major RELAX NG patterns including:
-
Elements and attributes
-
Named pattern definitions
-
Occurrence markers (*, +, ?)
-
Choice and group patterns
-
Mixed content
-
Value literals and datatypes
-
Namespace declarations
Instance Method Summary collapse
-
#build(schema) ⇒ String
Build RNC text from a Grammar object or Element.
-
#build_div(div) ⇒ String
Build RNC syntax for a div grouping construct.
-
#escape_rnc_string(str) ⇒ String
Escape a string value for use in RNC double-quoted string literals.
Instance Method Details
#build(schema) ⇒ String
Build RNC text from a Grammar object or Element
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/rng/rnc_builder.rb', line 26 def build(schema) @datatype_prefix = nil @datatype_library_uri = nil # Handle simple element (direct Element object, not Grammar) return build_element(schema) if schema.is_a?(Element) # Grammar with start and/or named patterns result = [] # Collect datatype libraries from data elements collect_datatype_libraries(schema) # Add namespace declaration if present if schema.ns && !schema.ns.empty? && schema.ns != 'omitted' && schema.ns != 'empty' result << "default namespace = \"#{schema.ns}\"" result << '' end # Add datatype library if present (grammar-level or from data elements) dt_lib = schema.datatypeLibrary if schema.datatypeLibrary && !%w[omitted empty].include?(schema.datatypeLibrary) dt_lib ||= @datatype_library_uri if dt_lib result << "datatypes xsd = \"#{dt_lib}\"" @datatype_prefix = 'xsd' result << '' end # Process start pattern if schema.start && !schema.start.empty? start = schema.start.first # Add documentation if present result << build_documentation(start.documentation).chomp if start.documentation && !start.documentation.empty? start_pattern = build_pattern(start) result << "start = #{start_pattern}" result << '' end # Process named patterns (define elements) if schema.define && !schema.define.empty? schema.define.each do |define| # Add documentation if present result << build_documentation(define.documentation).chomp if define.documentation && !define.documentation.empty? pattern = build_pattern(define) result << "#{define.name} = #{pattern}" result << '' end end # Process div elements (grouping containers) if schema.div && !schema.div.empty? schema.div.each do |div| div_content = build_div(div) result << div_content result << '' end end result.join("\n") end |
#build_div(div) ⇒ String
Build RNC syntax for a div grouping construct
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/rng/rnc_builder.rb', line 105 def build_div(div) result = 'div {' parts = [] # Process divs within div if div.div && !div.div.empty? div.div.each do |nested_div| parts << build_div(nested_div) end end # Process start within div if div.start && !div.start.empty? div.start.each do |start| parts << "start = #{build_pattern(start)}" end end # Process defines within div if div.define && !div.define.empty? div.define.each do |define| parts << "#{define.name} = #{build_pattern(define)}" end end if parts.empty? "#{result} }" else "#{result}\n #{parts.join("\n ")}\n}" end end |
#escape_rnc_string(str) ⇒ String
Escape a string value for use in RNC double-quoted string literals. RNC string escape sequences: \ (backslash), " (double quote), n (newline), r (carriage return), t (tab)
93 94 95 96 97 98 99 |
# File 'lib/rng/rnc_builder.rb', line 93 def escape_rnc_string(str) str.gsub('\\') { '\\\\' } .gsub('"') { '\\"' } .gsub("\n") { '\\n' } .gsub("\r") { '\\r' } .gsub("\t") { '\\t' } end |