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