Class: Parser::Lexer::Dedenter

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

Instance Method Summary collapse

Instance Method Details

#dedent(string) ⇒ Object

[View source]

83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'opal/lib/opal/parser/patch.rb', line 83

def dedent(string)
  original_encoding = string.encoding
  # Prevent the following error when processing binary encoded source.
  # "\xC0".split # => ArgumentError (invalid byte sequence in UTF-8)
  lines = string.force_encoding(Encoding::BINARY).split("\\\n")
  if lines.length == 1
    # If the line continuation sequence was found but there is no second
    # line, it was not really a line continuation and must be ignored.
    lines = [string.force_encoding(original_encoding)]
  else
    lines.map! { |s| s.force_encoding(original_encoding) }
  end

  lines.each_with_index do |line, index|
    next if (index == 0) && !@at_line_begin
    left_to_remove = @dedent_level
    remove = 0

    line.each_char do |char|
      break if left_to_remove <= 0
      case char
      when "\s"
        remove += 1
        left_to_remove -= 1
      when "\t"
        break if TAB_WIDTH * (remove / TAB_WIDTH + 1) > @dedent_level
        remove += 1
        left_to_remove -= TAB_WIDTH
      else
        # no more spaces or tabs
        break
      end
    end

    lines[index] = line[remove..-1]
  end

  string = lines.join

  @at_line_begin = string.end_with?("\n")

  string
end