class Rufo::ErbFormatter

Attributes

code_mode[R]
current_column[RW]
current_lineno[RW]
result[R]
scanner[R]

Public Class Methods

format(code, **options) click to toggle source
# File lib/rufo/erb_formatter.rb, line 20
def self.format(code, **options)
  new(code, **options).format
end
new(code, **options) click to toggle source
# File lib/rufo/erb_formatter.rb, line 26
def initialize(code, **options)
  @options = options
  @scanner = CustomScanner.new(code)
  @code_mode = false
  @current_lineno = 0
  @current_column = 0
end

Public Instance Methods

format() click to toggle source
# File lib/rufo/erb_formatter.rb, line 34
def format
  out = []
  process_erb do |(type, content)|
    if type == :code
      formatted_code = process_code(content)
      indented_code = formatted_code.lines.join(" " * current_column)
      out << " #{indented_code} "
    else
      out << content
    end

    update_lineno(out.last)
    update_column(out.last)
  end
  @result = out.join("")
end

Private Instance Methods

determine_code_wrappers(code_str) click to toggle source
# File lib/rufo/erb_formatter.rb, line 107
def determine_code_wrappers(code_str)
  return nil, "\nend" if Ripper.sexp("#{code_str}\nend")
  return nil, "}" if Ripper.sexp("#{code_str} }")
  return "{", nil if Ripper.sexp("{ #{code_str}")
  return "begin", nil if Ripper.sexp("begin #{code_str}")
  return "begin\n", "\nend" if Ripper.sexp("begin\n#{code_str}\nend")
  return "if a\n", "\nend" if Ripper.sexp("if a\n#{code_str}\nend")
  return "case a\n", "\nend" if Ripper.sexp("case a\n#{code_str}\nend")
  raise_syntax_error!(code_str)
end
disable_code_mode() click to toggle source
# File lib/rufo/erb_formatter.rb, line 132
def disable_code_mode
  @code_mode = false
end
enable_code_mode() click to toggle source
# File lib/rufo/erb_formatter.rb, line 128
def enable_code_mode
  @code_mode = true
end
format_code(str) click to toggle source
# File lib/rufo/erb_formatter.rb, line 124
def format_code(str)
  Rufo::Formatter.format(str).chomp
end
process_code(code_str) click to toggle source
# File lib/rufo/erb_formatter.rb, line 92
def process_code(code_str)
  sexps = Ripper.sexp(code_str)
  if sexps.nil?
    prefix, suffix = determine_code_wrappers(code_str)
  end
  result = format_code("#{prefix} " + code_str + " #{suffix}")
  unless suffix.nil?
    result = result.chomp(suffix)
  end
  unless prefix.nil?
    result = result.sub(prefix, "")
  end
  result.strip
end
process_erb() { |:code, join("")| ... } click to toggle source
# File lib/rufo/erb_formatter.rb, line 72
def process_erb
  code = []
  scanner.scan do |token|
    if token.is_a?(String) && token.end_with?("%>")
      disable_code_mode
      yield [:code, code.join("")]
      yield [:text, token]
      code = []
    elsif code_mode
      code << token
    elsif token == :cr
      yield [:text, "\n"]
    else
      yield [:text, token]
    end

    enable_code_mode if token.is_a?(String) && token.start_with?("<%")
  end
end
raise_syntax_error!(code_str) click to toggle source
# File lib/rufo/erb_formatter.rb, line 118
def raise_syntax_error!(code_str)
  format_code(code_str)
rescue Rufo::SyntaxError => e
  raise Rufo::SyntaxError.new(e.message, current_lineno + e.lineno)
end
update_column(token) click to toggle source
# File lib/rufo/erb_formatter.rb, line 63
def update_column(token)
  last_newline_index = token.rindex("\n")
  if last_newline_index == nil
    self.current_column = current_column + token.length
  else
    self.current_column = token[last_newline_index..-1].length
  end
end
update_lineno(token) click to toggle source
# File lib/rufo/erb_formatter.rb, line 56
def update_lineno(token)
  lines = token.count("\n")
  if lines > 0
    self.current_lineno = current_lineno + lines
  end
end