Module: Canon::Comparison::ChildRealignment
- Defined in:
- lib/canon/comparison/child_realignment.rb
Overview
Shared two-cursor walk over child arrays with noise-aware realignment.
When positional pairing would match a noise node (whitespace-only text or comment) against a content node, the walker treats the noise node as a single-side gap: emits a diff for it and advances only that cursor, so the next iteration aligns content against content.
Noise classification is delegated to NodeInspector.noise_dimension_for, making the walk open for extension — new noise types only require adding a branch there.
The walk is parameterised by a diff emitter (a callable that receives node1, node2, diff1, diff2, dimension) so both the HTML comparator (DiffNodeBuilder.build) and the XML comparator (comparator.add_difference) reuse the same cursor logic.
Class Method Summary collapse
-
.walk(children1, children2, emitter, emit_structural_orphans: false) {|child1, child2| ... } ⇒ Symbol
Walk two child arrays, emitting diffs for noise nodes and yielding matched content pairs.
Class Method Details
.walk(children1, children2, emitter, emit_structural_orphans: false) {|child1, child2| ... } ⇒ Symbol
Walk two child arrays, emitting diffs for noise nodes and yielding matched content pairs.
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 86 87 88 |
# File 'lib/canon/comparison/child_realignment.rb', line 40 def walk(children1, children2, emitter, emit_structural_orphans: false) worst = Comparison::EQUIVALENT i = 0 j = 0 while i < children1.length || j < children2.length child1 = children1[i] child2 = children2[j] if child1.nil? result = emit_orphan(child2, :right, emitter, emit_structural_orphans) worst = result if result && result != Comparison::EQUIVALENT j += 1 next elsif child2.nil? result = emit_orphan(child1, :left, emitter, emit_structural_orphans) worst = result if result && result != Comparison::EQUIVALENT i += 1 next end dim1 = NodeInspector.noise_dimension_for(child1) dim2 = NodeInspector.noise_dimension_for(child2) if dim1 && !dim2 result = emit_inline_noise(child1, child2, dim1, :left, emitter) worst = result unless result == Comparison::EQUIVALENT i += 1 next elsif dim2 && !dim1 result = emit_inline_noise(child1, child2, dim2, :right, emitter) worst = result unless result == Comparison::EQUIVALENT j += 1 next end if block_given? child_result = yield(child1, child2) worst = child_result unless child_result == Comparison::EQUIVALENT end i += 1 j += 1 end worst end |