erb-formatter 0.2.2 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b90b39bdcbed3837f51229bc9c840b0bd44d61fa48eace4e2c7b32aedcb90e3c
4
- data.tar.gz: d42ecb4464e92ceb46b9d266647db19c88540b369acb8585bec5800b4f0d6617
3
+ metadata.gz: 93f3695219c717c8c307ccecad4141890ed86c11c397e36af0e569a24e303fd4
4
+ data.tar.gz: 67b9bd4f85b75b3ba8aaa18f370df3fa9f9f178f561aa02b4b1def6d04f6b8c2
5
5
  SHA512:
6
- metadata.gz: 7e7ba4c9ad276e45a2ad557000fe565ed66bc9205a7aabaf432d5a99dd693758c73a7975fbe0a770fe0becd9f66be294d0f2bf168b1249b3fd4d416e20770611
7
- data.tar.gz: 0fed7945792aa4ad161c6b784796703c00b0aef7c69c61f4d77d4cfedbfae71ee76b1d2b7eeb106e6f3ec633031878dff5fd033605d7e61e0875ce1a3902b30d
6
+ metadata.gz: 1cf1a5c6d0cdf543b18d0203daa82e532168b1665b9343a066b40a20a60d0236a442ce018337814b079ae7f0d094e3a6583b2862659bccbc9de64ae02ce5cdbe
7
+ data.tar.gz: 1694c549a0ad05b6495b9632e3941179b62437892ee7e3c0e3712839ac23ae1056a2bc12c1f445ca8499d42448810e5eb2ba117498f296a9685cade08ff48426
data/README.md CHANGED
@@ -6,7 +6,7 @@ Features:
6
6
 
7
7
  - very fast
8
8
  - attempts to limit length (configurable)
9
- - tries to have an ouput similar to prettier for HTML
9
+ - tries to have an output similar to prettier for HTML
10
10
  - indents correctly ruby blocks (e.g. `if`/`elsif`/`do`/`end`)
11
11
  - designed to be integrated into editors and commit hooks
12
12
  - gives meaningful output in case of errors (most of the time)
@@ -19,19 +19,13 @@ Roadmap:
19
19
  - more ruby reformatting capabilities
20
20
  - JavaScript and CSS formatting
21
21
  - VSCode plugin
22
+ - fix spaces after attribute equal signs instead of complaining
22
23
 
23
24
  ## Installation
24
25
 
25
26
  Add this line to your application's Gemfile:
26
27
 
27
- ```ruby
28
- gem 'erb-formatter'
29
- gem 'rufo' # for enabling minimal ruby re-formatting
30
- ```
31
-
32
- And then execute:
33
-
34
- $ bundle install
28
+ $ bundle add erb-formatter
35
29
 
36
30
  Or install it yourself as:
37
31
 
@@ -41,6 +35,12 @@ Or install it yourself as:
41
35
 
42
36
  ### From the command line
43
37
 
38
+ Update files in-place:
39
+
40
+ $ erb-format app/views/**/*.html.erb --write
41
+
42
+ or use stdin/stdout (useful for editor integrations):
43
+
44
44
  $ echo "<div > asdf <% if 123%> <%='foobar'%> <%end-%> </div>" | erb-format --stdin
45
45
  <div>
46
46
  asdf
@@ -49,7 +49,6 @@ Or install it yourself as:
49
49
  <% end -%>
50
50
  </div>
51
51
 
52
-
53
52
  Check out `erb-format --help` for more options.
54
53
 
55
54
  ### From Ruby
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "lib/erb/formatter"
3
+ require_relative "lib/erb/formatter/version"
4
4
 
5
5
  Gem::Specification.new do |spec|
6
6
  spec.name = "erb-formatter"
@@ -28,5 +28,5 @@ Gem::Specification.new do |spec|
28
28
  spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
29
29
  spec.require_paths = ["lib"]
30
30
 
31
- spec.add_development_dependency "rufo"
31
+ spec.add_dependency "syntax_tree", '~> 5.0'
32
32
  end
data/exe/erb-format CHANGED
@@ -1,69 +1,5 @@
1
- #!/usr/bin/env ruby
1
+ #!/usr/bin/env ruby -W:no-experimental
2
2
 
3
- require 'optparse'
4
-
5
- write, filename, read_stdin, code = nil
6
-
7
- OptionParser.new do |parser|
8
- parser.banner = "Usage: #{$0} FILENAME... --write"
9
-
10
- parser.on("-w", "--[no-]write", "Write file") do |value|
11
- write = value
12
- end
13
-
14
- parser.on("--stdin-filename FILEPATH", "Set the stdin filename (implies --stdin)") do |value|
15
- filename = value
16
- read_stdin = true
17
- end
18
-
19
- parser.on("--[no-]stdin", "Read the file from stdin") do |value|
20
- if read_stdin == true && value == false
21
- abort "Can't set stdin filename and not use stdin at the same time"
22
- end
23
-
24
- read_stdin = value
25
- filename ||= '-'
26
- end
27
-
28
- parser.on("--[no-]debug", "Enable debug mode") do |value|
29
- $DEBUG = value
30
- end
31
-
32
- parser.on("-h", "--help", "Prints this help") do
33
- puts parser
34
- exit
35
- end
36
- end.parse!(ARGV)
37
-
38
- abort "Can't read both stdin and a list of files" if read_stdin && !ARGV.empty?
39
-
40
- # If multiple files are provided assume `--write` and
41
- # execute on each of them.
42
- if ARGV.size > 1
43
- ARGV.each do |arg|
44
- warn "==> Formatting #{arg}..."
45
- system __FILE__, arg, *[
46
- ('--write' if write)
47
- ].compact or exit(1)
48
- end
49
- exit
50
- end
51
-
52
- require 'erb/formatter'
53
-
54
- filename ||= ARGV.first
55
- code = read_stdin ? $stdin.read : File.read(filename)
56
- ignore = ERB::Formatter::IgnoreList.new
57
-
58
- if ignore.should_ignore_file? filename
59
- print code unless write
60
- else
61
- html = ERB::Formatter.format(code, filename: filename)
62
-
63
- if write
64
- File.write(filename, html)
65
- else
66
- puts html
67
- end
68
- end
3
+ require 'erb/formatter/command_line'
69
4
 
5
+ ERB::Formatter::CommandLine.new(ARGV).run
data/exe/erb-formatter ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby -W:no-experimental
2
+
3
+ require 'erb/formatter/command_line'
4
+
5
+ ERB::Formatter::CommandLine.new(ARGV).run
@@ -0,0 +1,90 @@
1
+
2
+ require 'erb/formatter'
3
+ require 'optparse'
4
+
5
+ class ERB::Formatter::CommandLine
6
+
7
+ attr_reader :write, :filename, :read_stdin
8
+
9
+ def initialize(argv, stdin: $stdin)
10
+ @argv = argv.dup
11
+ @stdin = stdin
12
+
13
+ @write, @filename, @read_stdin, @code = nil
14
+
15
+ OptionParser.new do |parser|
16
+ parser.banner = "Usage: #{$0} FILENAME... --write"
17
+
18
+ parser.on("-w", "--[no-]write", "Write file") do |value|
19
+ @write = value
20
+ end
21
+
22
+ parser.on("--stdin-filename FILEPATH", "Set the stdin filename (implies --stdin)") do |value|
23
+ @filename = value
24
+ @read_stdin = true
25
+ end
26
+
27
+ parser.on("--[no-]stdin", "Read the file from stdin") do |value|
28
+ if read_stdin == true && value == false
29
+ abort "Can't set stdin filename and not use stdin at the same time"
30
+ end
31
+
32
+ @read_stdin = value
33
+ @filename ||= '-'
34
+ end
35
+
36
+ parser.on("--print-width WIDTH", Integer, "Set the formatted output width") do |value|
37
+ @width = value
38
+ end
39
+
40
+ parser.on("--[no-]debug", "Enable debug mode") do |value|
41
+ $DEBUG = value
42
+ end
43
+
44
+ parser.on("-h", "--help", "Prints this help") do
45
+ puts parser
46
+ exit
47
+ end
48
+
49
+ parser.on("-v", "--version", "Show ERB::Formatter version number and quit") do
50
+ puts "ERB::Formatter #{ERB::Formatter::VERSION}"
51
+ exit
52
+ end
53
+ end.parse!(@argv)
54
+ end
55
+
56
+ def ignore_list
57
+ @ignore_list ||= ERB::Formatter::IgnoreList.new
58
+ end
59
+
60
+ def ignore?(filename)
61
+
62
+ end
63
+
64
+ def run
65
+ if read_stdin
66
+ abort "Can't read both stdin and a list of files" unless @argv.empty?
67
+ files = [
68
+ [@filename, @stdin.read]
69
+ ]
70
+ else
71
+ files = @argv.map do |filename|
72
+ [filename, File.read(filename)]
73
+ end
74
+ end
75
+
76
+ files.each do |(filename, code)|
77
+ if ignore_list.should_ignore_file? filename
78
+ print code unless write
79
+ else
80
+ html = ERB::Formatter.new(code, filename: filename, line_width: @width || 80)
81
+
82
+ if write
83
+ File.write(filename, html)
84
+ else
85
+ puts html
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
@@ -1,7 +1,7 @@
1
1
  class ERB::Formatter::IgnoreList
2
2
  def initialize(contents: nil, base_dir: Dir.pwd)
3
3
  ignore_list_path = "#{base_dir}/.format-erb-ignore"
4
- @contents = contents || (File.exists?(ignore_list_path) ? File.read(ignore_list_path) : '')
4
+ @contents = contents || (File.exist?(ignore_list_path) ? File.read(ignore_list_path) : '')
5
5
  @ignore_list = @contents.lines
6
6
  end
7
7
 
@@ -12,4 +12,3 @@ class ERB::Formatter::IgnoreList
12
12
  end
13
13
  end
14
14
  end
15
-
@@ -1,3 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'erb/formatter'
3
+ require 'erb'
4
+
5
+ class ERB::Formatter
6
+ VERSION = "0.4.0"
7
+ end
data/lib/erb/formatter.rb CHANGED
@@ -1,13 +1,26 @@
1
1
  # frozen_string_literal: false
2
2
 
3
+ require 'pp'
3
4
  require "erb"
4
5
  require "ripper"
5
6
  require 'securerandom'
6
7
  require 'strscan'
7
8
  require 'stringio'
9
+ require 'erb/formatter/version'
10
+
11
+ require 'syntax_tree'
8
12
 
9
13
  class ERB::Formatter
10
- VERSION = "0.2.2"
14
+ module SyntaxTreeCommandPatch
15
+ def format(q)
16
+ q.group do
17
+ q.format(message)
18
+ q.text(" ")
19
+ q.format(arguments) # WAS: q.nest(message.value.length + 1) { q.format(arguments) }
20
+ end
21
+ end
22
+ end
23
+
11
24
  autoload :IgnoreList, 'erb/formatter/ignore_list'
12
25
 
13
26
  class Error < StandardError; end
@@ -65,7 +78,7 @@ class ERB::Formatter
65
78
  @original_source = source
66
79
  @filename = filename || '(erb)'
67
80
  @line_width = line_width
68
- @source = source.dup
81
+ @source = remove_front_matter source.dup
69
82
  @html = +""
70
83
  @debug = debug
71
84
 
@@ -90,6 +103,13 @@ class ERB::Formatter
90
103
  freeze
91
104
  end
92
105
 
106
+ def remove_front_matter(source)
107
+ source.sub(/\A---\n[\s\S]*?\n---\n/) do |match|
108
+ @front_matter = match
109
+ match.gsub(/[^\n]/, ' ')
110
+ end
111
+ end
112
+
93
113
  attr_accessor \
94
114
  :source, :html, :tag_stack, :pre_pos, :pre_placeholders, :erb_tags, :erb_tags_regexp,
95
115
  :pre_placeholders_regexp, :tags_regexp, :line_width
@@ -151,7 +171,6 @@ class ERB::Formatter
151
171
  html << (erb_pre_match.match?(/\s+\z/) ? indented(full_erb_tag) : full_erb_tag)
152
172
  tag_stack_push('%erb%', ruby_code)
153
173
  when ERB_OPEN_BLOCK
154
- ruby_code = format_ruby(ruby_code, autoclose: true)
155
174
  html << (erb_pre_match.match?(/\s+\z/) ? indented(full_erb_tag) : full_erb_tag)
156
175
  tag_stack_push('%erb%', ruby_code)
157
176
  else
@@ -195,9 +214,10 @@ class ERB::Formatter
195
214
  super error
196
215
  end
197
216
 
198
- def indented(string)
217
+ def indented(string, strip: true)
218
+ string = string.strip if strip
199
219
  indent = " " * tag_stack.size
200
- "\n#{indent}#{string.strip}"
220
+ "\n#{indent}#{string}"
201
221
  end
202
222
 
203
223
  def format_text(text)
@@ -234,30 +254,6 @@ class ERB::Formatter
234
254
  end
235
255
  end
236
256
 
237
- def format_code_with_rubocop(code, line_width)
238
- stdin, stdout = $stdin, $stdout
239
- $stdin = StringIO.new(code)
240
- $stdout = StringIO.new
241
-
242
- Thread.current['RuboCop::Cop::Layout::LineLength#max'] = line_width
243
-
244
- @rubocop_cli ||= begin
245
- RuboCop::Cop::Layout::LineLength.prepend self
246
- RuboCop::CLI.new
247
- end
248
-
249
- @rubocop_cli.run([
250
- '--auto-correct',
251
- '--stdin', @filename,
252
- '-f', 'quiet',
253
- ])
254
-
255
- $stdout.string.split(RUBOCOP_STDIN_MARKER, 2).last
256
- ensure
257
- $stdin, $stdout = stdin, stdout
258
- Thread.current['RuboCop::Cop::Layout::LineLength#max'] = nil
259
- end
260
-
261
257
  def format_ruby(code, autoclose: false)
262
258
  if autoclose
263
259
  code += "\nend" unless ERB_OPEN_BLOCK["#{code}\nend"]
@@ -265,16 +261,17 @@ class ERB::Formatter
265
261
  end
266
262
  p RUBY_IN_: code if @debug
267
263
 
268
- offset = tag_stack.size * 2
269
- if defined? Rubocop
270
- code = format_code_with_rubocop(code, line_width - offset) if (offset + code.size) > line_width
271
- elsif defined?(Rufo)
272
- code = Rufo.format(code) rescue code
264
+ SyntaxTree::Command.prepend SyntaxTreeCommandPatch
265
+
266
+ code = begin
267
+ SyntaxTree.format(code)
268
+ rescue SyntaxTree::Parser::ParseError
269
+ code
273
270
  end
274
271
 
275
272
  lines = code.strip.lines
276
273
  lines = lines[0...-1] if autoclose
277
- code = lines.map { |l| indented(l) }.join.strip
274
+ code = lines.map { |l| indented(l.chomp("\n"), strip: false) }.join.strip
278
275
  p RUBY_OUT: code if @debug
279
276
  code
280
277
  end
@@ -301,22 +298,24 @@ class ERB::Formatter
301
298
 
302
299
  erb_open, ruby_code, erb_close = ERB_TAG.match(erb_code).captures
303
300
  erb_open << ' ' unless ruby_code.start_with?('#')
304
- full_erb_tag = "#{erb_open}#{ruby_code} #{erb_close}"
305
301
 
306
302
  case ruby_code
307
303
  when /\Aend\z/
304
+ full_erb_tag = "#{erb_open}#{ruby_code} #{erb_close}"
308
305
  tag_stack_pop('%erb%', ruby_code)
309
306
  html << (erb_pre_match.match?(/\s+\z/) ? indented(full_erb_tag) : full_erb_tag)
310
307
  when /\A(else|elsif\b(.*))\z/
308
+ full_erb_tag = "#{erb_open}#{ruby_code} #{erb_close}"
311
309
  tag_stack_pop('%erb%', ruby_code)
312
310
  html << (erb_pre_match.match?(/\s+\z/) ? indented(full_erb_tag) : full_erb_tag)
313
311
  tag_stack_push('%erb%', ruby_code)
314
312
  when ERB_OPEN_BLOCK
315
- ruby_code = format_ruby(ruby_code, autoclose: true)
313
+ full_erb_tag = "#{erb_open}#{ruby_code} #{erb_close}"
316
314
  html << (erb_pre_match.match?(/\s+\z/) ? indented(full_erb_tag) : full_erb_tag)
317
315
  tag_stack_push('%erb%', ruby_code)
318
316
  else
319
317
  ruby_code = format_ruby(ruby_code, autoclose: false)
318
+ full_erb_tag = "#{erb_open}#{ruby_code} #{erb_close}"
320
319
  html << (erb_pre_match.match?(/\s+\z/) ? indented(full_erb_tag) : full_erb_tag)
321
320
  end
322
321
  else
@@ -333,14 +332,14 @@ class ERB::Formatter
333
332
 
334
333
  until scanner.eos?
335
334
  if matched = scanner.scan_until(tags_regexp)
336
- p format_pre_match: [pre_pos, '..', scanner.pre_match[pre_pos..]] if @debug
335
+ p format_pre_match: [pre_pos, '..', scanner.pre_match[pre_pos..]] if @debug
337
336
  pre_match = scanner.pre_match[pre_pos..]
338
337
  p POS: pre_pos...scanner.pos, advanced: source[pre_pos...scanner.pos] if @debug
339
338
  p MATCHED: matched if @debug
340
339
  self.pre_pos = scanner.charpos
341
340
 
342
341
  # Don't accept `name= "value"` attributes
343
- raise "Bad attribute, please fix spaces after the equal sign." if BAD_ATTR.match? pre_match
342
+ raise "Bad attribute, please fix spaces after the equal sign:\n#{pre_match}" if BAD_ATTR.match? pre_match
344
343
 
345
344
  format_erb_tags(pre_match) if pre_match
346
345
 
@@ -376,6 +375,7 @@ class ERB::Formatter
376
375
  html.gsub!(erb_tags_regexp, erb_tags)
377
376
  html.gsub!(pre_placeholders_regexp, pre_placeholders)
378
377
  html.strip!
378
+ html.prepend @front_matter + "\n" if @front_matter
379
379
  html << "\n"
380
380
  end
381
381
  end
metadata CHANGED
@@ -1,34 +1,35 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: erb-formatter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Elia Schito
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-03-23 00:00:00.000000000 Z
11
+ date: 2023-01-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: rufo
14
+ name: syntax_tree
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0'
20
- type: :development
19
+ version: '5.0'
20
+ type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">="
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '0'
26
+ version: '5.0'
27
27
  description:
28
28
  email:
29
29
  - elia@schito.me
30
30
  executables:
31
31
  - erb-format
32
+ - erb-formatter
32
33
  extensions: []
33
34
  extra_rdoc_files: []
34
35
  files:
@@ -39,7 +40,9 @@ files:
39
40
  - Rakefile
40
41
  - erb-formatter.gemspec
41
42
  - exe/erb-format
43
+ - exe/erb-formatter
42
44
  - lib/erb/formatter.rb
45
+ - lib/erb/formatter/command_line.rb
43
46
  - lib/erb/formatter/ignore_list.rb
44
47
  - lib/erb/formatter/version.rb
45
48
  - sig/erb/formatter.rbs