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.
@@ -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: []