lib/erb/formatter.rb in erb-formatter-0.3.0 vs lib/erb/formatter.rb in erb-formatter-0.4.0
- old
+ new
@@ -4,13 +4,24 @@
require "erb"
require "ripper"
require 'securerandom'
require 'strscan'
require 'stringio'
+require 'erb/formatter/version'
+require 'syntax_tree'
+
class ERB::Formatter
- VERSION = "0.3.0"
+ module SyntaxTreeCommandPatch
+ def format(q)
+ q.group do
+ q.format(message)
+ q.text(" ")
+ q.format(arguments) # WAS: q.nest(message.value.length + 1) { q.format(arguments) }
+ end
+ end
+ end
autoload :IgnoreList, 'erb/formatter/ignore_list'
class Error < StandardError; end
@@ -65,11 +76,11 @@
def initialize(source, line_width: 80, filename: nil, debug: $DEBUG)
@original_source = source
@filename = filename || '(erb)'
@line_width = line_width
- @source = source.dup
+ @source = remove_front_matter source.dup
@html = +""
@debug = debug
html.extend DebugShovel if @debug
@@ -90,10 +101,17 @@
format
freeze
end
+ def remove_front_matter(source)
+ source.sub(/\A---\n[\s\S]*?\n---\n/) do |match|
+ @front_matter = match
+ match.gsub(/[^\n]/, ' ')
+ end
+ end
+
attr_accessor \
:source, :html, :tag_stack, :pre_pos, :pre_placeholders, :erb_tags, :erb_tags_regexp,
:pre_placeholders_regexp, :tags_regexp, :line_width
alias to_s html
@@ -151,11 +169,10 @@
when /\A(else|elsif\b(.*))\z/
tag_stack_pop('%erb%', ruby_code)
html << (erb_pre_match.match?(/\s+\z/) ? indented(full_erb_tag) : full_erb_tag)
tag_stack_push('%erb%', ruby_code)
when ERB_OPEN_BLOCK
- ruby_code = format_ruby(ruby_code, autoclose: true)
html << (erb_pre_match.match?(/\s+\z/) ? indented(full_erb_tag) : full_erb_tag)
tag_stack_push('%erb%', ruby_code)
else
ruby_code = format_ruby(ruby_code, autoclose: false)
html << (erb_pre_match.match?(/\s+\z/) ? indented(full_erb_tag) : full_erb_tag)
@@ -195,13 +212,14 @@
].join("\n"))
error.set_backtrace caller.to_a + [location]
super error
end
- def indented(string)
+ def indented(string, strip: true)
+ string = string.strip if strip
indent = " " * tag_stack.size
- "\n#{indent}#{string.strip}"
+ "\n#{indent}#{string}"
end
def format_text(text)
p format_text: text if @debug
starting_space = text.match?(/\A\s/)
@@ -234,51 +252,28 @@
lines.each do |line|
html << indented(line)
end
end
- def format_code_with_rubocop(code, line_width)
- stdin, stdout = $stdin, $stdout
- $stdin = StringIO.new(code)
- $stdout = StringIO.new
-
- Thread.current['RuboCop::Cop::Layout::LineLength#max'] = line_width
-
- @rubocop_cli ||= begin
- RuboCop::Cop::Layout::LineLength.prepend self
- RuboCop::CLI.new
- end
-
- @rubocop_cli.run([
- '--auto-correct',
- '--stdin', @filename,
- '-f', 'quiet',
- ])
-
- $stdout.string.split(RUBOCOP_STDIN_MARKER, 2).last
- ensure
- $stdin, $stdout = stdin, stdout
- Thread.current['RuboCop::Cop::Layout::LineLength#max'] = nil
- end
-
def format_ruby(code, autoclose: false)
if autoclose
code += "\nend" unless ERB_OPEN_BLOCK["#{code}\nend"]
code += "\n}" unless ERB_OPEN_BLOCK["#{code}\n}"]
end
p RUBY_IN_: code if @debug
- offset = tag_stack.size * 2
- if defined? Rubocop
- code = format_code_with_rubocop(code, line_width - offset) if (offset + code.size) > line_width
- elsif defined?(Rufo)
- code = Rufo.format(code) rescue code
+ SyntaxTree::Command.prepend SyntaxTreeCommandPatch
+
+ code = begin
+ SyntaxTree.format(code)
+ rescue SyntaxTree::Parser::ParseError
+ code
end
lines = code.strip.lines
lines = lines[0...-1] if autoclose
- code = lines.map { |l| indented(l) }.join.strip
+ code = lines.map { |l| indented(l.chomp("\n"), strip: false) }.join.strip
p RUBY_OUT: code if @debug
code
end
def format_erb_tags(string)
@@ -301,26 +296,28 @@
format_text(erb_pre_match)
erb_open, ruby_code, erb_close = ERB_TAG.match(erb_code).captures
erb_open << ' ' unless ruby_code.start_with?('#')
- full_erb_tag = "#{erb_open}#{ruby_code} #{erb_close}"
case ruby_code
when /\Aend\z/
+ full_erb_tag = "#{erb_open}#{ruby_code} #{erb_close}"
tag_stack_pop('%erb%', ruby_code)
html << (erb_pre_match.match?(/\s+\z/) ? indented(full_erb_tag) : full_erb_tag)
when /\A(else|elsif\b(.*))\z/
+ full_erb_tag = "#{erb_open}#{ruby_code} #{erb_close}"
tag_stack_pop('%erb%', ruby_code)
html << (erb_pre_match.match?(/\s+\z/) ? indented(full_erb_tag) : full_erb_tag)
tag_stack_push('%erb%', ruby_code)
when ERB_OPEN_BLOCK
- ruby_code = format_ruby(ruby_code, autoclose: true)
+ full_erb_tag = "#{erb_open}#{ruby_code} #{erb_close}"
html << (erb_pre_match.match?(/\s+\z/) ? indented(full_erb_tag) : full_erb_tag)
tag_stack_push('%erb%', ruby_code)
else
ruby_code = format_ruby(ruby_code, autoclose: false)
+ full_erb_tag = "#{erb_open}#{ruby_code} #{erb_close}"
html << (erb_pre_match.match?(/\s+\z/) ? indented(full_erb_tag) : full_erb_tag)
end
else
p ERB_REST: erb_scanner.rest if @debug
rest = erb_scanner.rest.to_s
@@ -333,11 +330,11 @@
def format
scanner = StringScanner.new(source)
until scanner.eos?
if matched = scanner.scan_until(tags_regexp)
- p format_pre_match: [pre_pos, '..', scanner.pre_match[pre_pos..]] if @debug
+ p format_pre_match: [pre_pos, '..', scanner.pre_match[pre_pos..]] if @debug
pre_match = scanner.pre_match[pre_pos..]
p POS: pre_pos...scanner.pos, advanced: source[pre_pos...scanner.pos] if @debug
p MATCHED: matched if @debug
self.pre_pos = scanner.charpos
@@ -376,8 +373,9 @@
end
html.gsub!(erb_tags_regexp, erb_tags)
html.gsub!(pre_placeholders_regexp, pre_placeholders)
html.strip!
+ html.prepend @front_matter + "\n" if @front_matter
html << "\n"
end
end