Sha256: 68ff927bad807bca45ebf27f1870a2cb8f450056dce4c8a3ffbaf57350676716
Contents?: true
Size: 1.71 KB
Versions: 1
Compression:
Stored size: 1.71 KB
Contents
# frozen_string_literal: true module Parser class Lexer::Dedenter # Tab (\t) counts as 8 spaces TAB_WIDTH = 8 def initialize(dedent_level) @dedent_level = dedent_level @at_line_begin = true @indent_level = 0 end # For a heredoc like # <<-HERE # a # b # HERE # this method gets called with " a\n" and " b\n" # # However, the following heredoc: # # <<-HERE # a\ # b # HERE # calls this method only once with a string " a\\\n b\n" # # This is important because technically it's a single line, # but it has to be concatenated __after__ dedenting. # # It has no effect for non-squiggly heredocs, i.e. it simply removes "\\\n" # Of course, lexer could do it but once again: it's all because of dedenting. # def dedent(string) lines = string.split("\\\n") if @at_line_begin lines_to_dedent = lines else _first, *lines_to_dedent = lines end lines_to_dedent.each do |line| 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 line.slice!(0, remove) end string.replace(lines.join) @at_line_begin = string.end_with?("\n") end def interrupt @at_line_begin = false end end end
Version data entries
1 entries across 1 versions & 1 rubygems
Version | Path |
---|---|
parser-2.7.0.0 | lib/parser/lexer/dedenter.rb |