erb-formatter 0.4.2 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +19 -4
- data/erb-formatter.gemspec +1 -1
- data/lib/erb/formatter/command_line.rb +6 -2
- data/lib/erb/formatter/version.rb +1 -1
- data/lib/erb/formatter.rb +41 -64
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ba78d2f06a198fd4f9af049e11a4f0ec92fcfa56e16688eaa65b3ea9253320ca
|
4
|
+
data.tar.gz: 5d06c40737f856c445cf70fd530639e8876c60dad08d9fdc91acc12e42c9e086
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4997b2e942b1fe2ed3a0bf0b0e828ba7565090bf781508accd4d64540e90b986d7d0414534e066cd149d56d8d208342dd20c6ac1ba749498e03b080d4e799a10
|
7
|
+
data.tar.gz: 59901e642196b0538e88379384d655a8f6a174007ba30fa7829b25db829cedbc8bcb94ef80e58b026e6223cc166fa442db798c84a18d38baecf5c36d63cee3cf
|
data/README.md
CHANGED
@@ -33,13 +33,18 @@ Or install it yourself as:
|
|
33
33
|
|
34
34
|
## Usage
|
35
35
|
|
36
|
+
### From [Visual Studio Code](https://code.visualstudio.com)
|
37
|
+
|
38
|
+
Just install the [Ruby ERB::Formatter 🪜](https://marketplace.visualstudio.com/items?itemName=elia.erb-formatter) extension
|
39
|
+
and follow the setup instructions there.
|
40
|
+
|
36
41
|
### From the command line
|
37
42
|
|
38
43
|
Update files in-place:
|
39
44
|
|
40
45
|
$ erb-format app/views/**/*.html.erb --write
|
41
46
|
|
42
|
-
or use stdin/stdout (useful for editor integrations):
|
47
|
+
or use stdin/stdout (useful for editor integrations):
|
43
48
|
|
44
49
|
$ echo "<div > asdf <% if 123%> <%='foobar'%> <%end-%> </div>" | erb-format --stdin
|
45
50
|
<div>
|
@@ -51,7 +56,7 @@ or use stdin/stdout (useful for editor integrations):
|
|
51
56
|
|
52
57
|
Check out `erb-format --help` for more options.
|
53
58
|
|
54
|
-
### From Ruby
|
59
|
+
### From [Ruby](https://www.ruby-lang.org/en/)
|
55
60
|
|
56
61
|
```ruby
|
57
62
|
require 'erb/formatter'
|
@@ -76,7 +81,7 @@ ERB
|
|
76
81
|
# </div>
|
77
82
|
```
|
78
83
|
|
79
|
-
### With `lint-staged`
|
84
|
+
### With [`lint-staged`](https://github.com/okonet/lint-staged#readme)
|
80
85
|
|
81
86
|
Add the gem to your gemfile and the following to your `package.json`:
|
82
87
|
|
@@ -87,7 +92,7 @@ Add the gem to your gemfile and the following to your `package.json`:
|
|
87
92
|
}
|
88
93
|
```
|
89
94
|
|
90
|
-
### As a TextMate
|
95
|
+
### As a [TextMate](http://macromates.com) command
|
91
96
|
|
92
97
|
Create a command with the following settings:
|
93
98
|
|
@@ -104,6 +109,16 @@ cd "$TM_PROJECT_DIRECTORY"
|
|
104
109
|
bundle exec erb-format --stdin-filename "$TM_FILEPATH" < /dev/stdin 2> /dev/stdout
|
105
110
|
```
|
106
111
|
|
112
|
+
### With [(Neo)VIM ALE](https://github.com/dense-analysis/ale)
|
113
|
+
|
114
|
+
Enable `erb-formatter` as a fixer in the ALE config:
|
115
|
+
|
116
|
+
```vim
|
117
|
+
let g:ale_fixers = {
|
118
|
+
\ 'eruby': ['erb-formatter'],
|
119
|
+
\}
|
120
|
+
```
|
121
|
+
|
107
122
|
## Development
|
108
123
|
|
109
124
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
data/erb-formatter.gemspec
CHANGED
@@ -10,7 +10,7 @@ class ERB::Formatter::CommandLine
|
|
10
10
|
@argv = argv.dup
|
11
11
|
@stdin = stdin
|
12
12
|
|
13
|
-
@write, @filename, @read_stdin, @code = nil
|
13
|
+
@write, @filename, @read_stdin, @code, @single_class_per_line = nil
|
14
14
|
|
15
15
|
OptionParser.new do |parser|
|
16
16
|
parser.banner = "Usage: #{$0} FILENAME... --write"
|
@@ -37,6 +37,10 @@ class ERB::Formatter::CommandLine
|
|
37
37
|
@width = value
|
38
38
|
end
|
39
39
|
|
40
|
+
parser.on("--single-class-per-line", "Print each class on a separate line") do |value|
|
41
|
+
@single_class_per_line = value
|
42
|
+
end
|
43
|
+
|
40
44
|
parser.on("--[no-]debug", "Enable debug mode") do |value|
|
41
45
|
$DEBUG = value
|
42
46
|
end
|
@@ -77,7 +81,7 @@ class ERB::Formatter::CommandLine
|
|
77
81
|
if ignore_list.should_ignore_file? filename
|
78
82
|
print code unless write
|
79
83
|
else
|
80
|
-
html = ERB::Formatter.new(code, filename: filename, line_width: @width || 80)
|
84
|
+
html = ERB::Formatter.new(code, filename: filename, line_width: @width || 80, single_class_per_line: @single_class_per_line)
|
81
85
|
|
82
86
|
if write
|
83
87
|
File.write(filename, html)
|
data/lib/erb/formatter.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
# frozen_string_literal: false
|
2
2
|
|
3
3
|
require 'pp'
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require 'securerandom'
|
4
|
+
require 'erb'
|
5
|
+
require 'yaml'
|
7
6
|
require 'strscan'
|
8
7
|
require 'stringio'
|
8
|
+
require 'securerandom'
|
9
9
|
require 'erb/formatter/version'
|
10
10
|
|
11
11
|
require 'syntax_tree'
|
@@ -38,8 +38,6 @@ class ERB::Formatter
|
|
38
38
|
|
39
39
|
ERB_TAG = %r{(<%(?:==|=|-|))\s*(.*?)\s*(-?%>)}m
|
40
40
|
ERB_PLACEHOLDER = %r{erb[a-z0-9]+tag}
|
41
|
-
ERB_END = %r{(<%-?)\s*(end)\s*(-?%>)}
|
42
|
-
ERB_ELSE = %r{(<%-?)\s*(else|elsif\b.*)\s*(-?%>)}
|
43
41
|
|
44
42
|
TAG_NAME = /[a-z0-9_:-]+/
|
45
43
|
TAG_NAME_ONLY = /\A#{TAG_NAME}\z/
|
@@ -49,20 +47,15 @@ class ERB::Formatter
|
|
49
47
|
|
50
48
|
SELF_CLOSING_TAG = /\A(area|base|br|col|command|embed|hr|img|input|keygen|link|menuitem|meta|param|source|track|wbr)\z/i
|
51
49
|
|
52
|
-
|
50
|
+
RUBY_OPEN_BLOCK = ->(code) do
|
53
51
|
# is nil when the parsing is broken, meaning it's an open expression
|
54
52
|
Ripper.sexp(code).nil?
|
55
53
|
end.freeze
|
54
|
+
RUBY_CLOSE_BLOCK = /\Aend\z/
|
55
|
+
RUBY_REOPEN_BLOCK = /\A(else|elsif\b(.*)|when\b(.*))\z/
|
56
56
|
|
57
57
|
RUBOCOP_STDIN_MARKER = "===================="
|
58
58
|
|
59
|
-
# Override the max line length to account from already indented ERB
|
60
|
-
module RubocopForcedMaxLineLength
|
61
|
-
def max
|
62
|
-
Thread.current['RuboCop::Cop::Layout::LineLength#max'] || super
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
59
|
module DebugShovel
|
67
60
|
def <<(string)
|
68
61
|
puts "ADDING: #{string.inspect} FROM:\n #{caller(1, 5).join("\n ")}"
|
@@ -74,13 +67,14 @@ class ERB::Formatter
|
|
74
67
|
new(source, filename: filename).html
|
75
68
|
end
|
76
69
|
|
77
|
-
def initialize(source, line_width: 80, filename: nil, debug: $DEBUG)
|
70
|
+
def initialize(source, line_width: 80, single_class_per_line: false, filename: nil, debug: $DEBUG)
|
78
71
|
@original_source = source
|
79
72
|
@filename = filename || '(erb)'
|
80
73
|
@line_width = line_width
|
81
74
|
@source = remove_front_matter source.dup
|
82
75
|
@html = +""
|
83
76
|
@debug = debug
|
77
|
+
@single_class_per_line = single_class_per_line
|
84
78
|
|
85
79
|
html.extend DebugShovel if @debug
|
86
80
|
|
@@ -104,10 +98,13 @@ class ERB::Formatter
|
|
104
98
|
end
|
105
99
|
|
106
100
|
def remove_front_matter(source)
|
107
|
-
source.
|
108
|
-
|
109
|
-
|
110
|
-
|
101
|
+
return source unless source.start_with?("---\n")
|
102
|
+
|
103
|
+
first_body_line = YAML.parse(source).children.first.end_line + 1
|
104
|
+
lines = source.lines
|
105
|
+
|
106
|
+
@front_matter = lines[0...first_body_line].join
|
107
|
+
lines[first_body_line..].join
|
111
108
|
end
|
112
109
|
|
113
110
|
attr_accessor \
|
@@ -124,6 +121,7 @@ class ERB::Formatter
|
|
124
121
|
|
125
122
|
attr_html = ""
|
126
123
|
tag_stack_push(['attr='], attrs)
|
124
|
+
|
127
125
|
attrs.scan(ATTR).flatten.each do |attr|
|
128
126
|
attr.strip!
|
129
127
|
full_attr = indented(attr)
|
@@ -132,59 +130,38 @@ class ERB::Formatter
|
|
132
130
|
if full_attr.size > line_width && MULTILINE_ATTR_NAMES.include?(name) && attr.match?(QUOTED_ATTR)
|
133
131
|
attr_html << indented("#{name}=#{value[0]}")
|
134
132
|
tag_stack_push('attr"', value)
|
135
|
-
|
136
|
-
|
133
|
+
|
134
|
+
value_parts = value[1...-1].strip.split(/\s+/)
|
135
|
+
|
136
|
+
if !@single_class_per_line && name == 'class'
|
137
|
+
line = value_parts.shift
|
138
|
+
value_parts.each do |value_part|
|
139
|
+
if (line.size + value_part.size + 1) <= line_width
|
140
|
+
line << " #{value_part}"
|
141
|
+
else
|
142
|
+
attr_html << indented(line)
|
143
|
+
line = value_part
|
144
|
+
end
|
145
|
+
end
|
146
|
+
attr_html << indented(line) if line
|
147
|
+
else
|
148
|
+
value_parts.each do |value_part|
|
149
|
+
attr_html << indented(value_part)
|
150
|
+
end
|
137
151
|
end
|
152
|
+
|
138
153
|
tag_stack_pop('attr"', value)
|
139
154
|
attr_html << indented(value[-1])
|
140
155
|
else
|
141
156
|
attr_html << full_attr
|
142
157
|
end
|
143
158
|
end
|
159
|
+
|
144
160
|
tag_stack_pop(['attr='], attrs)
|
145
161
|
attr_html << indented("")
|
146
162
|
attr_html
|
147
163
|
end
|
148
164
|
|
149
|
-
def format_erb_attributes(string)
|
150
|
-
erb_scanner = StringScanner.new(string.to_s)
|
151
|
-
erb_pre_pos = 0
|
152
|
-
until erb_scanner.eos?
|
153
|
-
if erb_scanner.scan_until(erb_tags_regexp)
|
154
|
-
erb_pre_match = erb_scanner.pre_match
|
155
|
-
erb_pre_match = erb_pre_match[erb_pre_pos..]
|
156
|
-
erb_pre_pos = erb_scanner.pos
|
157
|
-
|
158
|
-
erb_code = erb_tags[erb_scanner.captures.first]
|
159
|
-
|
160
|
-
format_attributes(erb_pre_match)
|
161
|
-
|
162
|
-
erb_open, ruby_code, erb_close = ERB_TAG.match(erb_code).captures
|
163
|
-
full_erb_tag = "#{erb_open} #{ruby_code} #{erb_close}"
|
164
|
-
|
165
|
-
case ruby_code
|
166
|
-
when /\Aend\z/
|
167
|
-
tag_stack_pop('%erb%', ruby_code)
|
168
|
-
html << (erb_pre_match.match?(/\s+\z/) ? indented(full_erb_tag) : full_erb_tag)
|
169
|
-
when /\A(else|elsif\b(.*))\z/
|
170
|
-
tag_stack_pop('%erb%', ruby_code)
|
171
|
-
html << (erb_pre_match.match?(/\s+\z/) ? indented(full_erb_tag) : full_erb_tag)
|
172
|
-
tag_stack_push('%erb%', ruby_code)
|
173
|
-
when ERB_OPEN_BLOCK
|
174
|
-
html << (erb_pre_match.match?(/\s+\z/) ? indented(full_erb_tag) : full_erb_tag)
|
175
|
-
tag_stack_push('%erb%', ruby_code)
|
176
|
-
else
|
177
|
-
ruby_code = format_ruby(ruby_code, autoclose: false)
|
178
|
-
html << (erb_pre_match.match?(/\s+\z/) ? indented(full_erb_tag) : full_erb_tag)
|
179
|
-
end
|
180
|
-
else
|
181
|
-
rest = erb_scanner.rest.to_s
|
182
|
-
format_erb_attributes(rest)
|
183
|
-
erb_scanner.terminate
|
184
|
-
end
|
185
|
-
end
|
186
|
-
end
|
187
|
-
|
188
165
|
def tag_stack_push(tag_name, code)
|
189
166
|
tag_stack << [tag_name, code]
|
190
167
|
p PUSH: tag_stack if @debug
|
@@ -258,8 +235,8 @@ class ERB::Formatter
|
|
258
235
|
|
259
236
|
def format_ruby(code, autoclose: false)
|
260
237
|
if autoclose
|
261
|
-
code += "\nend" unless
|
262
|
-
code += "\n}" unless
|
238
|
+
code += "\nend" unless RUBY_OPEN_BLOCK["#{code}\nend"]
|
239
|
+
code += "\n}" unless RUBY_OPEN_BLOCK["#{code}\n}"]
|
263
240
|
end
|
264
241
|
p RUBY_IN_: code if @debug
|
265
242
|
|
@@ -303,16 +280,16 @@ class ERB::Formatter
|
|
303
280
|
erb_open << ' ' unless ruby_code.start_with?('#')
|
304
281
|
|
305
282
|
case ruby_code
|
306
|
-
when
|
283
|
+
when RUBY_CLOSE_BLOCK
|
307
284
|
full_erb_tag = "#{erb_open}#{ruby_code} #{erb_close}"
|
308
285
|
tag_stack_pop('%erb%', ruby_code)
|
309
286
|
html << (erb_pre_match.match?(/\s+\z/) ? indented(full_erb_tag) : full_erb_tag)
|
310
|
-
when
|
287
|
+
when RUBY_REOPEN_BLOCK
|
311
288
|
full_erb_tag = "#{erb_open}#{ruby_code} #{erb_close}"
|
312
289
|
tag_stack_pop('%erb%', ruby_code)
|
313
290
|
html << (erb_pre_match.match?(/\s+\z/) ? indented(full_erb_tag) : full_erb_tag)
|
314
291
|
tag_stack_push('%erb%', ruby_code)
|
315
|
-
when
|
292
|
+
when RUBY_OPEN_BLOCK
|
316
293
|
full_erb_tag = "#{erb_open}#{ruby_code} #{erb_close}"
|
317
294
|
html << (erb_pre_match.match?(/\s+\z/) ? indented(full_erb_tag) : full_erb_tag)
|
318
295
|
tag_stack_push('%erb%', ruby_code)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: erb-formatter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.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: 2023-
|
11
|
+
date: 2023-12-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: syntax_tree
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '6.0'
|
20
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: '
|
26
|
+
version: '6.0'
|
27
27
|
description:
|
28
28
|
email:
|
29
29
|
- elia@schito.me
|
@@ -68,7 +68,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
68
68
|
- !ruby/object:Gem::Version
|
69
69
|
version: '0'
|
70
70
|
requirements: []
|
71
|
-
rubygems_version: 3.
|
71
|
+
rubygems_version: 3.3.23
|
72
72
|
signing_key:
|
73
73
|
specification_version: 4
|
74
74
|
summary: Format ERB files with speed and precision.
|