Class: Ruumba::Parser

Inherits:
Object
  • Object
show all
Defined in:
lib/ruumba/parser.rb

Overview

Responsible for extracting interpolated Ruby.

Constant Summary collapse

ERB_REGEX =

The regular expression to capture interpolated Ruby.

/<%[-=]?(.*?)-?%>/m.freeze

Instance Method Summary collapse

Constructor Details

#initialize(region_start_marker = nil) ⇒ Parser

Returns a new instance of Parser.



11
12
13
# File 'lib/ruumba/parser.rb', line 11

def initialize(region_start_marker = nil)
  @region_start_marker = region_start_marker
end

Instance Method Details

#extract(contents) ⇒ String

Extracts Ruby code from an ERB template.

Returns:

  • (String)

    The extracted ruby code



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/ruumba/parser.rb', line 17

def extract(contents)
  file_text, matches = parse(contents)

  extracted_ruby = +''

  last_match = [0, 0]
  matches.each_with_index do |(start_index, end_index), index|
    handle_region_before(start_index, last_match.last, file_text, extracted_ruby)

    match_marker = "#{region_start_marker}_#{format('%010d', index + 1)}" if region_start_marker
    extracted_ruby << extract_match(file_text, start_index, end_index, match_marker)

    last_match = [start_index, end_index]
  end

  extracted_ruby << file_text[last_match.last..-1].gsub(/./, ' ')

  # if we replaced <%== with <%= raw, try to shift the columns back to the
  # left so they match the original again
  extracted_ruby.gsub!(/   raw/, 'raw')

  extracted_ruby
end

#replace(old_contents, new_contents) ⇒ Object



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
# File 'lib/ruumba/parser.rb', line 41

def replace(old_contents, new_contents)
  file_text, matches = parse(old_contents)

  auto_corrected_erb = +''

  last_match = [0, 0]
  matches.each_with_index do |(start_index, end_index), index|
    match_start = start_index
    prev_end_index = last_match.last

    if start_index > prev_end_index
      region_before = file_text[prev_end_index..match_start - 1]

      auto_corrected_erb << region_before
    end

    suffix = format('%010d', index + 1)
    match_marker = "#{region_start_marker}_#{suffix}"

    match_without_markers = new_contents[/\n#{match_marker}$\n(.*)\n#{match_marker}\n/m, 1]

    # auto-correct is still experimental and can cause invalid ruby to be generated when extracting ruby from ERBs
    return nil unless match_without_markers

    auto_corrected_erb << match_without_markers

    last_match = [start_index, end_index]
  end

  auto_corrected_erb << file_text[last_match.last..-1]

  auto_corrected_erb
end