w_syntax_tree-erb 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SyntaxTree
4
+ module ERB
5
+ VERSION = "0.9.0"
6
+ end
7
+ 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: []