Class: Rng::IncludeProcessor

Inherits:
Object
  • Object
show all
Defined in:
lib/rng/include_processor.rb

Overview

Handles RNC file inclusion and grammar merging

This class processes include directives in RNC files, resolving them recursively while preventing circular includes. It supports both:

  • Grammar-level includes (inside grammar blocks)

  • Top-level includes (Metanorma-style schemas)

Examples:

Parse a file with includes

processor = Rng::IncludeProcessor.new
grammar = processor.parse_file("schema.rnc")

Instance Method Summary collapse

Constructor Details

#initialize(converter = RncToRngConverter.new) ⇒ IncludeProcessor

Initialize with optional converter

Parameters:

  • converter (RncToRngConverter) (defaults to: RncToRngConverter.new)

    Converter for parse tree to RNG XML



21
22
23
# File 'lib/rng/include_processor.rb', line 21

def initialize(converter = RncToRngConverter.new)
  @converter = converter
end

Instance Method Details

#parse_file(file_path, base_dir = nil, visited_files = Set.new) ⇒ Grammar

Parse a file with include resolution

Parameters:

  • file_path (String)

    Path to RNC file

  • base_dir (String, nil) (defaults to: nil)

    Base directory for resolving relative paths

  • visited_files (Set) (defaults to: Set.new)

    Set of already visited file paths (for circular detection)

Returns:

  • (Grammar)

    Parsed grammar object



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/rng/include_processor.rb', line 31

def parse_file(file_path, base_dir = nil, visited_files = Set.new)
  tree = parse_file_to_tree(file_path, base_dir, visited_files)

  # Process raw_grammar/raw_override/raw_patterns first (before include resolution)
  # The include processor needs parsed content in the tree
  process_raw_nodes!(tree)

  # Process any includes in the tree (top-level or grammar-level)
  process_includes(tree, base_dir || File.dirname(File.expand_path(file_path)),
                   visited_files)

  # Extract namespace from wrapper level if present
  namespace = tree[:namespace]

  # Build grammar tree from different structures
  grammar_tree = build_grammar_tree(tree)
  grammar_tree[:namespace] = namespace if namespace

  # Convert to RNG XML and then to Grammar object
  rng_xml = @converter.convert(grammar_tree)
  Grammar.from_xml(rng_xml)
end