w_syntax_tree-erb 0.9.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 +7 -0
- data/.github/ISSUE_TEMPLATE/formatting-report.md +37 -0
- data/.github/ISSUE_TEMPLATE/general.md +10 -0
- data/.github/dependabot.yml +6 -0
- data/.github/workflows/auto-merge.yml +22 -0
- data/.github/workflows/main.yml +32 -0
- data/.gitignore +10 -0
- data/CHANGELOG.md +16 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +38 -0
- data/LICENSE +21 -0
- data/README.md +84 -0
- data/Rakefile +16 -0
- data/check_erb_parse.rb +20 -0
- data/lib/syntax_tree/erb/format.rb +230 -0
- data/lib/syntax_tree/erb/nodes.rb +511 -0
- data/lib/syntax_tree/erb/parser.rb +741 -0
- data/lib/syntax_tree/erb/pretty_print.rb +214 -0
- data/lib/syntax_tree/erb/version.rb +7 -0
- data/lib/syntax_tree/erb/visitor.rb +54 -0
- data/lib/syntax_tree/erb.rb +30 -0
- data/syntax_tree-erb.gemspec +33 -0
- metadata +151 -0
@@ -0,0 +1,214 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SyntaxTree
|
4
|
+
module ERB
|
5
|
+
class PrettyPrint < Visitor
|
6
|
+
attr_reader :q
|
7
|
+
|
8
|
+
def initialize(q)
|
9
|
+
@q = q
|
10
|
+
end
|
11
|
+
|
12
|
+
# Visit a Token node.
|
13
|
+
def visit_token(node)
|
14
|
+
q.pp(node.value)
|
15
|
+
end
|
16
|
+
|
17
|
+
# Visit a Document node.
|
18
|
+
def visit_document(node)
|
19
|
+
visit_node("document", node)
|
20
|
+
end
|
21
|
+
|
22
|
+
def visit_block(node)
|
23
|
+
visit_node(node.class.to_s, node)
|
24
|
+
end
|
25
|
+
|
26
|
+
# Visit an HtmlNode.
|
27
|
+
def visit_html(node)
|
28
|
+
visit_node("html", node)
|
29
|
+
end
|
30
|
+
|
31
|
+
# Visit an HtmlNode::OpeningTag node.
|
32
|
+
def visit_opening_tag(node)
|
33
|
+
visit_node("opening_tag", node)
|
34
|
+
end
|
35
|
+
|
36
|
+
# Visit an HtmlNode::ClosingTag node.
|
37
|
+
def visit_closing_tag(node)
|
38
|
+
visit_node("closing_tag", node)
|
39
|
+
end
|
40
|
+
|
41
|
+
# Visit an ErbNode node.
|
42
|
+
def visit_erb(node)
|
43
|
+
q.group do
|
44
|
+
q.text("(erb")
|
45
|
+
q.nest(2) do
|
46
|
+
q.breakable
|
47
|
+
visit(node.opening_tag)
|
48
|
+
if node.keyword
|
49
|
+
q.breakable
|
50
|
+
visit(node.keyword)
|
51
|
+
end
|
52
|
+
if node.content
|
53
|
+
q.breakable
|
54
|
+
q.text("content")
|
55
|
+
end
|
56
|
+
|
57
|
+
q.breakable
|
58
|
+
visit(node.closing_tag)
|
59
|
+
end
|
60
|
+
q.breakable("")
|
61
|
+
q.text(")")
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def visit_erb_block(node)
|
66
|
+
q.group do
|
67
|
+
q.text("(erb_block")
|
68
|
+
q.nest(2) do
|
69
|
+
q.breakable
|
70
|
+
q.seplist(node.elements) { |child_node| visit(child_node) }
|
71
|
+
end
|
72
|
+
q.breakable
|
73
|
+
visit(node.closing)
|
74
|
+
q.breakable("")
|
75
|
+
q.text(")")
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def visit_erb_if(node, key = "erb_if")
|
80
|
+
q.group do
|
81
|
+
q.text("(")
|
82
|
+
visit(node.opening)
|
83
|
+
q.nest(2) do
|
84
|
+
q.breakable()
|
85
|
+
q.seplist(node.child_nodes) { |child_node| visit(child_node) }
|
86
|
+
end
|
87
|
+
q.breakable
|
88
|
+
visit(node.closing)
|
89
|
+
q.breakable("")
|
90
|
+
q.text(")")
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def visit_erb_elsif(node)
|
95
|
+
visit_erb_if(node, "erb_elsif")
|
96
|
+
end
|
97
|
+
|
98
|
+
def visit_erb_else(node)
|
99
|
+
visit_erb_if(node, "erb_else")
|
100
|
+
end
|
101
|
+
|
102
|
+
def visit_erb_case(node)
|
103
|
+
visit_erb_if(node, "erb_case")
|
104
|
+
end
|
105
|
+
|
106
|
+
def visit_erb_case_when(node)
|
107
|
+
visit_erb_if(node, "erb_when")
|
108
|
+
end
|
109
|
+
|
110
|
+
def visit_erb_end(node)
|
111
|
+
q.text("erb_end")
|
112
|
+
end
|
113
|
+
|
114
|
+
# Visit an ErbContent node.
|
115
|
+
def visit_erb_content(node)
|
116
|
+
q.text(node.value)
|
117
|
+
end
|
118
|
+
|
119
|
+
# Visit an Attribute node.
|
120
|
+
def visit_attribute(node)
|
121
|
+
visit_node("attribute", node)
|
122
|
+
end
|
123
|
+
|
124
|
+
# Visit a HtmlString node.
|
125
|
+
def visit_html_string(node)
|
126
|
+
visit_node("html_string", node)
|
127
|
+
end
|
128
|
+
|
129
|
+
# Visit a CharData node.
|
130
|
+
def visit_char_data(node)
|
131
|
+
visit_node("char_data", node)
|
132
|
+
end
|
133
|
+
|
134
|
+
def visit_erb_close(node)
|
135
|
+
visit_node("erb_close", node)
|
136
|
+
end
|
137
|
+
|
138
|
+
def visit_erb_do_close(node)
|
139
|
+
visit_node("erb_do_close", node)
|
140
|
+
end
|
141
|
+
|
142
|
+
# Visit a Doctype node.
|
143
|
+
def visit_doctype(node)
|
144
|
+
visit_node("doctype", node)
|
145
|
+
end
|
146
|
+
|
147
|
+
def visit_html_comment(node)
|
148
|
+
visit_node("html_comment", node)
|
149
|
+
end
|
150
|
+
|
151
|
+
private
|
152
|
+
|
153
|
+
# A generic visit node function for how we pretty print nodes.
|
154
|
+
def visit_node(type, node)
|
155
|
+
q.group do
|
156
|
+
q.text("(#{type}")
|
157
|
+
q.nest(2) do
|
158
|
+
q.breakable
|
159
|
+
q.seplist(node.child_nodes) { |child_node| visit(child_node) }
|
160
|
+
end
|
161
|
+
q.breakable("")
|
162
|
+
q.text(")")
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
def comments(node)
|
167
|
+
return if node.comments.empty?
|
168
|
+
|
169
|
+
q.breakable
|
170
|
+
q.group(2, "(", ")") do
|
171
|
+
q.seplist(node.comments) { |comment| q.pp(comment) }
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
def field(_name, value)
|
176
|
+
q.breakable
|
177
|
+
q.pp(value)
|
178
|
+
end
|
179
|
+
|
180
|
+
def list(_name, values)
|
181
|
+
q.breakable
|
182
|
+
q.group(2, "(", ")") { q.seplist(values) { |value| q.pp(value) } }
|
183
|
+
end
|
184
|
+
|
185
|
+
def node(_node, type)
|
186
|
+
q.group(2, "(", ")") do
|
187
|
+
q.text(type)
|
188
|
+
yield
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
def pairs(_name, values)
|
193
|
+
q.group(2, "(", ")") do
|
194
|
+
q.seplist(values) do |(key, value)|
|
195
|
+
q.pp(key)
|
196
|
+
|
197
|
+
if value
|
198
|
+
q.text("=")
|
199
|
+
q.group(2) do
|
200
|
+
q.breakable("")
|
201
|
+
q.pp(value)
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
def text(_name, value)
|
209
|
+
q.breakable
|
210
|
+
q.text(value)
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SyntaxTree
|
4
|
+
module ERB
|
5
|
+
# Provides a visitor interface for visiting certain nodes. It's used
|
6
|
+
# internally to implement formatting and pretty-printing. It could also be
|
7
|
+
# used externally to visit a subset of nodes that are relevant to a certain
|
8
|
+
# task.
|
9
|
+
class Visitor < SyntaxTree::Visitor
|
10
|
+
def visit(node)
|
11
|
+
node&.accept(self)
|
12
|
+
end
|
13
|
+
|
14
|
+
alias visit_statements visit_child_nodes
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def visit_all(nodes)
|
19
|
+
nodes.map { |node| visit(node) }
|
20
|
+
end
|
21
|
+
|
22
|
+
def visit_child_nodes(node)
|
23
|
+
visit_all(node.child_nodes)
|
24
|
+
end
|
25
|
+
|
26
|
+
# Visit a Token node.
|
27
|
+
alias visit_token visit_child_nodes
|
28
|
+
|
29
|
+
# Visit a Document node.
|
30
|
+
alias visit_document visit_child_nodes
|
31
|
+
|
32
|
+
# Visit an Html node.
|
33
|
+
alias visit_html visit_child_nodes
|
34
|
+
|
35
|
+
# Visit an HtmlNode::OpeningTag node.
|
36
|
+
alias visit_opening_tag visit_child_nodes
|
37
|
+
|
38
|
+
# Visit an HtmlNode::ClosingTag node.
|
39
|
+
alias visit_closing_tag visit_child_nodes
|
40
|
+
|
41
|
+
# Visit an Attribute node.
|
42
|
+
alias visit_attribute visit_child_nodes
|
43
|
+
|
44
|
+
# Visit a CharData node.
|
45
|
+
alias visit_char_data visit_child_nodes
|
46
|
+
|
47
|
+
# Visit an ErbNode node.
|
48
|
+
alias visit_erb visit_child_nodes
|
49
|
+
|
50
|
+
# Visit a HtmlString node.
|
51
|
+
alias visit_html_string visit_child_nodes
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "prettier_print"
|
4
|
+
require "syntax_tree"
|
5
|
+
|
6
|
+
require_relative "erb/nodes"
|
7
|
+
require_relative "erb/parser"
|
8
|
+
require_relative "erb/visitor"
|
9
|
+
|
10
|
+
require_relative "erb/format"
|
11
|
+
require_relative "erb/pretty_print"
|
12
|
+
|
13
|
+
module SyntaxTree
|
14
|
+
module ERB
|
15
|
+
MAX_WIDTH = 80
|
16
|
+
def self.format(source, maxwidth = MAX_WIDTH, options: nil)
|
17
|
+
PrettierPrint.format(+"", maxwidth) { |q| parse(source).format(q) }
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.parse(source)
|
21
|
+
Parser.new(source).parse
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.read(filepath)
|
25
|
+
File.read(filepath)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
register_handler(".erb", ERB)
|
30
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "lib/syntax_tree/erb/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "w_syntax_tree-erb"
|
7
|
+
spec.version = SyntaxTree::ERB::VERSION
|
8
|
+
spec.authors = ["Kevin Newton", "David Wessman"]
|
9
|
+
spec.email = %w[kddnewton@gmail.com david@wessman.co]
|
10
|
+
|
11
|
+
spec.summary = "Syntax Tree support for ERB"
|
12
|
+
spec.homepage = "https://github.com/davidwessman/syntax_tree-erb"
|
13
|
+
spec.license = "MIT"
|
14
|
+
spec.metadata = { "rubygems_mfa_required" => "true" }
|
15
|
+
|
16
|
+
spec.files =
|
17
|
+
Dir.chdir(__dir__) do
|
18
|
+
`git ls-files -z`.split("\x0")
|
19
|
+
.reject { |f| f.match(%r{^(test|spec|features)/}) }
|
20
|
+
end
|
21
|
+
|
22
|
+
spec.bindir = "exe"
|
23
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
24
|
+
spec.require_paths = %w[lib]
|
25
|
+
|
26
|
+
spec.add_dependency "prettier_print", ">= 1.2.0"
|
27
|
+
spec.add_dependency "syntax_tree", ">= 6.1.1"
|
28
|
+
|
29
|
+
spec.add_development_dependency "bundler"
|
30
|
+
spec.add_development_dependency "minitest"
|
31
|
+
spec.add_development_dependency "rake"
|
32
|
+
spec.add_development_dependency "simplecov"
|
33
|
+
end
|
metadata
ADDED
@@ -0,0 +1,151 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: w_syntax_tree-erb
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.9.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Kevin Newton
|
8
|
+
- David Wessman
|
9
|
+
autorequire:
|
10
|
+
bindir: exe
|
11
|
+
cert_chain: []
|
12
|
+
date: 2023-06-22 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: prettier_print
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - ">="
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: 1.2.0
|
21
|
+
type: :runtime
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: 1.2.0
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: syntax_tree
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - ">="
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: 6.1.1
|
35
|
+
type: :runtime
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: 6.1.1
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: bundler
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ">="
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '0'
|
49
|
+
type: :development
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: minitest
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
63
|
+
type: :development
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: rake
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
84
|
+
- !ruby/object:Gem::Dependency
|
85
|
+
name: simplecov
|
86
|
+
requirement: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '0'
|
91
|
+
type: :development
|
92
|
+
prerelease: false
|
93
|
+
version_requirements: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - ">="
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '0'
|
98
|
+
description:
|
99
|
+
email:
|
100
|
+
- kddnewton@gmail.com
|
101
|
+
- david@wessman.co
|
102
|
+
executables: []
|
103
|
+
extensions: []
|
104
|
+
extra_rdoc_files: []
|
105
|
+
files:
|
106
|
+
- ".github/ISSUE_TEMPLATE/formatting-report.md"
|
107
|
+
- ".github/ISSUE_TEMPLATE/general.md"
|
108
|
+
- ".github/dependabot.yml"
|
109
|
+
- ".github/workflows/auto-merge.yml"
|
110
|
+
- ".github/workflows/main.yml"
|
111
|
+
- ".gitignore"
|
112
|
+
- CHANGELOG.md
|
113
|
+
- Gemfile
|
114
|
+
- Gemfile.lock
|
115
|
+
- LICENSE
|
116
|
+
- README.md
|
117
|
+
- Rakefile
|
118
|
+
- check_erb_parse.rb
|
119
|
+
- lib/syntax_tree/erb.rb
|
120
|
+
- lib/syntax_tree/erb/format.rb
|
121
|
+
- lib/syntax_tree/erb/nodes.rb
|
122
|
+
- lib/syntax_tree/erb/parser.rb
|
123
|
+
- lib/syntax_tree/erb/pretty_print.rb
|
124
|
+
- lib/syntax_tree/erb/version.rb
|
125
|
+
- lib/syntax_tree/erb/visitor.rb
|
126
|
+
- syntax_tree-erb.gemspec
|
127
|
+
homepage: https://github.com/davidwessman/syntax_tree-erb
|
128
|
+
licenses:
|
129
|
+
- MIT
|
130
|
+
metadata:
|
131
|
+
rubygems_mfa_required: 'true'
|
132
|
+
post_install_message:
|
133
|
+
rdoc_options: []
|
134
|
+
require_paths:
|
135
|
+
- lib
|
136
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
137
|
+
requirements:
|
138
|
+
- - ">="
|
139
|
+
- !ruby/object:Gem::Version
|
140
|
+
version: '0'
|
141
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
requirements: []
|
147
|
+
rubygems_version: 3.4.1
|
148
|
+
signing_key:
|
149
|
+
specification_version: 4
|
150
|
+
summary: Syntax Tree support for ERB
|
151
|
+
test_files: []
|