Class: Metanorma::Utils::AnchorRanges

Inherits:
Object
  • Object
show all
Defined in:
lib/utils/anchor_ranges.rb

Overview

AnchorRanges provides efficient range checking for nodes based on anchor positions in a document. It determines whether an arbitrary node falls within the range # defined by two anchor points (A-B), where the range includes node A through all descendants of node B.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(doc) ⇒ AnchorRanges

Initialize with a Nokogiri document

Parameters:

  • doc (Nokogiri::XML::Document)

    The document to process



12
13
14
15
16
17
# File 'lib/utils/anchor_ranges.rb', line 12

def initialize(doc)
  @anchor_map = build_anchor_id_map(doc)
  @anchor_to_ord = nil
  @anchor_to_last_ord = nil
  @id_to_ord = nil
end

Instance Attribute Details

#anchor_mapObject (readonly)

Returns the value of attribute anchor_map.



8
9
10
# File 'lib/utils/anchor_ranges.rb', line 8

def anchor_map
  @anchor_map
end

Instance Method Details

#anchor_range(anchor) ⇒ Range?

Get the ordinal range for an anchor (start to last descendant)

Parameters:

  • anchor (String)

    The anchor to get the range for

Returns:

  • (Range, nil)

    The range of ordinals, or nil if anchor not found



57
58
59
60
61
62
63
# File 'lib/utils/anchor_ranges.rb', line 57

def anchor_range(anchor)
  start_ord = anchor_to_ord[anchor]
  end_ord = anchor_to_last_ord[anchor]
  return nil if start_ord.nil? || end_ord.nil?

  (start_ord..end_ord)
end

#anchor_to_last_ordHash

Get mapping of anchor to last descendant ord

Returns:

  • (Hash)

    anchor => last_ord



27
28
29
# File 'lib/utils/anchor_ranges.rb', line 27

def anchor_to_last_ord
  @anchor_to_last_ord ||= build_anchor_to_last_ord
end

#anchor_to_ordHash

Get mapping of anchor to ord

Returns:

  • (Hash)

    anchor => ord



21
22
23
# File 'lib/utils/anchor_ranges.rb', line 21

def anchor_to_ord
  @anchor_to_ord ||= build_anchor_to_ord
end

#id_to_ordHash

Get mapping of id to ord

Returns:

  • (Hash)

    id => ord



33
34
35
# File 'lib/utils/anchor_ranges.rb', line 33

def id_to_ord
  @id_to_ord ||= build_id_to_ord
end

#in_range?(node_id_or_anchor, anchor_a, anchor_b) ⇒ Boolean

Check if a node (by id or anchor) is within the range A-B

Parameters:

  • node_id_or_anchor (String)

    The id or anchor of the node to check

  • anchor_a (String)

    The anchor defining the start of the range

  • anchor_b (String)

    The anchor defining the end of the range

Returns:

  • (Boolean)

    true if the node is within the range A-B



42
43
44
45
46
47
48
49
50
51
52
# File 'lib/utils/anchor_ranges.rb', line 42

def in_range?(node_id_or_anchor, anchor_a, anchor_b)
  node_ord = find_node_ord(node_id_or_anchor)
  return false if node_ord.nil?

  start_ord = anchor_to_ord[anchor_a]
  end_ord = anchor_to_last_ord[anchor_b]

  return false if start_ord.nil? || end_ord.nil?

  node_ord >= start_ord && node_ord <= end_ord
end