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 +4 -4
- data/README.md +9 -10
- data/erb-formatter.gemspec +2 -2
- data/exe/erb-format +3 -67
- data/exe/erb-formatter +5 -0
- data/lib/erb/formatter/command_line.rb +90 -0
- data/lib/erb/formatter/ignore_list.rb +1 -2
- data/lib/erb/formatter/version.rb +5 -1
- data/lib/erb/formatter.rb +39 -39
- metadata +11 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 93f3695219c717c8c307ccecad4141890ed86c11c397e36af0e569a24e303fd4
|
4
|
+
data.tar.gz: 67b9bd4f85b75b3ba8aaa18f370df3fa9f9f178f561aa02b4b1def6d04f6b8c2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
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
|
-
|
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
|
data/erb-formatter.gemspec
CHANGED
@@ -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.
|
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 '
|
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,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.
|
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
|
-
|
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
|
-
|
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
|
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
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
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
|
-
|
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..]]
|
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
|
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.
|
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:
|
11
|
+
date: 2023-01-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
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: :
|
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
|