Module: TextAnalyzer

Included in:
MarkdownExec::HashDelegatorParent
Defined in:
lib/text_analyzer.rb

Class Method Summary collapse

Class Method Details

.analyze_hierarchy(hierarchy, pattern, default_color, match_color, text_sym: :text, style_sym: :color) ⇒ Array<Hash>+

Analyzes a hierarchical structure (String or Array) and highlights segments based on the pattern

Parameters:

  • hierarchy (String, Array)

    the hierarchical structure to be analyzed

  • pattern (Regexp)

    the pattern to match against the text

  • default_color (String)

    the color for non-matching segments

  • match_color (String)

    the color for matching segments

Returns:

Raises:

  • (ArgumentError)

    if the hierarchy structure is neither a String nor an Array



14
15
16
17
18
19
20
21
22
23
24
25
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
# File 'lib/text_analyzer.rb', line 14

def self.analyze_hierarchy(
  hierarchy, pattern, default_color, match_color,
  text_sym: :text, style_sym: :color
)
  case hierarchy
  when String
    highlight_segments(hierarchy, pattern, default_color, match_color)

  when Hash
    decorated = highlight_segments(hierarchy[text_sym], pattern,
                                   hierarchy[style_sym], match_color)

    case decorated
    when String
      hierarchy
    when Array
      if decorated.length == 1
        hierarchy
      else
        decorated
      end
    else
      decorated
    end

  when Array
    hierarchy.map do |element|
      analyze_hierarchy(element, pattern, default_color, match_color)
    end

  when HierarchyString
    hierarchy.replace_text! do |substring|
      substring # no change
    end

  else
    warn [hierarchy.class, hierarchy].inspect
    raise ArgumentError, 'Invalid hierarchy structure'
  end
end

.highlight_segments(text, pattern, default_color, match_color) ⇒ Array<Hash>

Highlights segments of the text based on the pattern

Parameters:

  • text (String)

    the text to be analyzed

  • pattern (Regexp)

    the pattern to match against the text

  • default_color (String)

    the color for non-matching segments

  • match_color (String)

    the color for matching segments

Returns:

  • (Array<Hash>)

    an array of hashes, each containing a segment of text and its corresponding color



63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/text_analyzer.rb', line 63

def self.highlight_segments(text, pattern, default_color, match_color)
  segments = []

  yield_matches_and_non_matches(text, pattern) do |segment, is_match|
    segments << if is_match
                  { text: segment, color: match_color }
                else
                  { text: segment, color: default_color }
                end
  end

  segments
end

.yield_matches_and_non_matches(text, pattern) {|segment, is_match| ... } ⇒ Object

Yields matching and non-matching segments of the text based on the pattern

Parameters:

  • text (String)

    the text to be analyzed

  • pattern (Regexp)

    the pattern to match against the text

Yield Parameters:

  • segment (String)

    a segment of the text

  • is_match (Boolean)

    true if the segment matches the pattern, false otherwise



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/text_analyzer.rb', line 84

def self.yield_matches_and_non_matches(text, pattern)
  last_end = nil

  text.scan(pattern) do |match|
    match_start = Regexp.last_match.begin(0)
    match_end = Regexp.last_match.end(0)

    # Yield the non-matching segment before the match
    yield text[(last_end || 0)...match_start], false if last_end.nil? || match_start > last_end

    # Yield the matching segment
    yield match.first, true

    last_end = match_end
  end

  last_end ||= 0
  # Yield any remaining non-matching segment after the last match
  return unless last_end < text.length

  yield text[last_end..-1], false
end