Module: Cecil::Text

Defined in:
lib/cecil/text.rb

Overview

Helper methods for string searching, manipulating, etc.

Class Method Summary collapse

Class Method Details

.closers(src, block_ending_pairs) {|String| ... } ⇒ Object .closers(src, block_ending_pairs) ⇒ Enumerator<String>

Returns or yields each closing bracket.

Overloads:

  • .closers(src, block_ending_pairs) {|String| ... } ⇒ Object

    With block given, behaves like each_closer

    Yields:

    • (String)
  • .closers(src, block_ending_pairs) ⇒ Enumerator<String>

    When no block is given, returns an enumerator of the each_closer method

    Returns:

    • (Enumerator<String>)

Parameters:

  • src (String)
  • block_ending_pairs (Hash{String=>String})


103
104
105
106
107
108
109
110
# File 'lib/cecil/text.rb', line 103

def closers(src, block_ending_pairs)
  return enum_for(:closers, src, block_ending_pairs) unless block_given?

  while match_ending_pair(src, block_ending_pairs) in [opener, closer]
    yield closer
    src = src[0...-opener.size]
  end
end

.interpolate_named(template, placeholders, idents_to_values) ⇒ String

Interpolate named placeholder values into a string

Parameters:

  • template (String)
  • placeholders (Array<Placeholder>)
  • idents_to_values (Hash{#to_s=>#to_s)

    ]

Returns:

  • (String)

    template, except with placeholders replaced with provided values



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/cecil/text.rb', line 39

def interpolate_named(template, placeholders, idents_to_values)
  duplicated_keys = idents_to_values.keys.group_by(&:to_s).values.select { _1.size > 1 }
  if duplicated_keys.any?
    keys_list = duplicated_keys.map { "\n - #{_1.map(&:inspect).join(", ")}\n" }.join
    raise "Duplicate placeholder value keys:#{keys_list}"
  end

  values_idents = idents_to_values.keys.to_set(&:to_s)
  match_idents = placeholders.to_set(&:ident)

  if match_idents != values_idents
    missing_values = match_idents - values_idents
    extra_values = values_idents - match_idents
    message = "Mismatch between placeholders and provide values."
    message << "\n Missing values for placeholders #{missing_values.join(", ")}" if missing_values.any?
    message << "\n Missing placeholders for values #{extra_values.join(", ")}" if extra_values.any?

    raise message
  end

  replace(template, placeholders, idents_to_values)
end

.interpolate_positional(template, placeholders, values) ⇒ String

Interpolate positional placeholder values into a string

Parameters:

  • template (String)
  • placeholders (Array<Placeholder>)
  • values (Array<#to_s>)

Returns:

  • (String)

    template, except with placeholders replaced with provided values



22
23
24
25
26
27
28
29
30
# File 'lib/cecil/text.rb', line 22

def interpolate_positional(template, placeholders, values)
  match_idents = placeholders.to_set(&:ident)

  if match_idents.size != values.size
    raise "Mismatch between number of placeholders (#{match_idents.size}) and given values (#{values.size})"
  end

  replace(template, placeholders, match_idents.zip(values).to_h)
end

.match_ending_pair(src, block_ending_pairs) ⇒ Object

Returns any closing bracket found

Parameters:

  • src (String)
  • block_ending_pairs (Hash{String=>String})


85
86
87
88
89
# File 'lib/cecil/text.rb', line 85

def match_ending_pair(src, block_ending_pairs)
  return if src.empty?

  block_ending_pairs.detect { |opener, _closer| src.end_with?(opener) }
end

.replace(template, placeholders, idents_to_values) ⇒ String

Replace placeholders in the string with provided values

Parameters:

  • template (String)
  • placeholders (Array<Placeholder>)
  • idents_to_values (Hash{#to_s=>#to_s)

    ]

Returns:

  • (String)

    template, except with placeholders replaced with provided values



69
70
71
72
73
74
75
76
77
78
79
# File 'lib/cecil/text.rb', line 69

def replace(template, placeholders, idents_to_values)
  values = idents_to_values.transform_keys(&:to_s)

  template.dup.tap do |new_src|
    placeholders.reverse.each do |placeholder|
      value = values.fetch(placeholder.ident)

      new_src[placeholder.range] = value.to_s
    end
  end
end

.scan_for_re_matches(str, regexp) ⇒ Array<MatchData>

Scan a string for matches on a Regexp and return each MatchObject

Parameters:

  • str (String)

    the string to scan

  • regexp (Regexp)

    the regexp to scan with

Returns:

  • (Array<MatchData>)

    The MatchData objects for each instance of the regexp matched in the string



13
# File 'lib/cecil/text.rb', line 13

def scan_for_re_matches(str, regexp) = str.to_enum(:scan, regexp).map { Regexp.last_match }