Class: Canon::Xml::LineRangeMapper
- Inherits:
-
Object
- Object
- Canon::Xml::LineRangeMapper
- Defined in:
- lib/canon/xml/line_range_mapper.rb
Overview
Maps DOM elements to line ranges in pretty-printed XML
This class builds a mapping between DOM elements and their corresponding line numbers in pretty-printed XML output. This enables line-accurate diff display that can highlight specific elements even when the XML structure is complex.
How it works
-
Pretty-prints the XML with consistent indentation
-
Traverses the DOM tree depth-first
-
For each element, finds its opening and closing tags in the pretty-printed output
-
Records the line range (start_line..end_line) for that element
-
Returns a Hash mapping element → LineRange
Usage
mapper = LineRangeMapper.new(indent: 2)
root = Canon::Xml::DataModel.from_xml(xml_string)
line_map = mapper.build_map(root, xml_string)
# Look up line range for an element
range = line_map[element]
puts "Element spans lines #{range.start_line} to #{range.end_line}"
Line Range Format
Each LineRange contains:
-
start_line: First line of the element (0-indexed)
-
end_line: Last line of the element (0-indexed)
-
elem: Reference to the DOM element
Defined Under Namespace
Classes: LineRange
Instance Method Summary collapse
-
#build_map(root, xml_string) ⇒ Hash
Build line range map for a DOM tree.
-
#initialize(indent: 2) ⇒ LineRangeMapper
constructor
A new instance of LineRangeMapper.
Constructor Details
#initialize(indent: 2) ⇒ LineRangeMapper
Returns a new instance of LineRangeMapper.
51 52 53 54 |
# File 'lib/canon/xml/line_range_mapper.rb', line 51 def initialize(indent: 2) @indent = indent @ranges = [] end |
Instance Method Details
#build_map(root, xml_string) ⇒ Hash
Build line range map for a DOM tree
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/canon/xml/line_range_mapper.rb', line 61 def build_map(root, xml_string) @ranges = [] @map = {} # Pretty-print to get consistent formatting pretty_xml = Canon::PrettyPrinter::Xml.new(indent: @indent).format(xml_string) @lines = pretty_xml.split("\n") # Track current line number @current_line = 0 # Build map recursively root.children.each do |child| map_node(child) end @map end |