erb-formatter 0.2.2 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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