phlexing 0.2.0 → 0.3.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/Gemfile.lock +2 -2
- data/lib/phlexing/converter.rb +66 -14
- data/lib/phlexing/helpers.rb +6 -2
- data/lib/phlexing/name_suggestor.rb +73 -0
- data/lib/phlexing/version.rb +1 -1
- data/lib/phlexing/visitor.rb +23 -0
- data/lib/phlexing.rb +2 -0
- metadata +18 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 36dca58e17556b8b085edeb24dbe3fc5f8c8cb976056a6f739a655c5d94d7a36
|
4
|
+
data.tar.gz: 21f2b6dbec24a29a4dbfe52bb25d77887e52c72d29098e41c5a80a2173e8cc66
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e52e0c6836f3e701c24f6ccf2338f823b5507497863e3af93d089712a2503213d2e86d5f3516f1f9d3e60bffd907de7ffbfc3661610141dd0f917f43a7cc2008
|
7
|
+
data.tar.gz: 00730543e38df6d87c1f5a1263ea964bfc27024de00dea885df86a5d60626afd665485899aad1d8cf350fba3df7e914879fda76040953125a4e9842e387c4b7b
|
data/Gemfile.lock
CHANGED
@@ -17,7 +17,7 @@ GIT
|
|
17
17
|
PATH
|
18
18
|
remote: .
|
19
19
|
specs:
|
20
|
-
phlexing (0.
|
20
|
+
phlexing (0.2.0)
|
21
21
|
erb_parser (~> 0.0.2)
|
22
22
|
html_press (~> 0.8.2)
|
23
23
|
nokogiri (~> 1.0)
|
@@ -62,7 +62,7 @@ GEM
|
|
62
62
|
parser (>= 3.1.1.0)
|
63
63
|
ruby-progressbar (1.11.0)
|
64
64
|
rufo (0.13.0)
|
65
|
-
treetop (1.6.
|
65
|
+
treetop (1.6.12)
|
66
66
|
polyglot (~> 0.3)
|
67
67
|
uglifier (2.7.2)
|
68
68
|
execjs (>= 0.3.0)
|
data/lib/phlexing/converter.rb
CHANGED
@@ -12,7 +12,7 @@ module Phlexing
|
|
12
12
|
|
13
13
|
using ::Phlexing::Refinements::StringRefinements
|
14
14
|
|
15
|
-
attr_accessor :html, :custom_elements
|
15
|
+
attr_accessor :html, :custom_elements, :ivars, :locals, :idents
|
16
16
|
|
17
17
|
def self.convert(html, **options)
|
18
18
|
new(html, **options).output
|
@@ -22,7 +22,12 @@ module Phlexing
|
|
22
22
|
@html = html
|
23
23
|
@buffer = StringIO.new
|
24
24
|
@custom_elements = Set.new
|
25
|
+
@ivars = Set.new
|
26
|
+
@locals = Set.new
|
27
|
+
@includes = Set.new
|
28
|
+
@idents = Set.new
|
25
29
|
@options = options
|
30
|
+
analyze_ruby
|
26
31
|
handle_node
|
27
32
|
end
|
28
33
|
|
@@ -50,9 +55,10 @@ module Phlexing
|
|
50
55
|
|
51
56
|
def handle_erb_element(node, level, newline: true)
|
52
57
|
if erb_safe_output?(node)
|
53
|
-
@buffer << "
|
58
|
+
@buffer << "unsafe_raw "
|
54
59
|
@buffer << node.text.from(1)
|
55
60
|
@buffer << "\n" if newline
|
61
|
+
|
56
62
|
return
|
57
63
|
end
|
58
64
|
|
@@ -163,27 +169,73 @@ module Phlexing
|
|
163
169
|
end
|
164
170
|
|
165
171
|
def output
|
166
|
-
|
172
|
+
out = StringIO.new
|
167
173
|
|
168
174
|
if @options.fetch(:phlex_class, false)
|
169
|
-
|
170
|
-
|
175
|
+
component_name = @options.fetch(:component_name, "Component")
|
176
|
+
component_name = "A#{component_name}" if component_name[0] == "0" || component_name[0].to_i != 0
|
177
|
+
|
178
|
+
parent_component = @options.fetch(:parent_component, "Phlex::HTML")
|
179
|
+
parent_component = "A#{parent_component}" if parent_component[0] == "0" || parent_component[0].to_i != 0
|
180
|
+
|
181
|
+
out << "class #{component_name}"
|
182
|
+
out << "< #{parent_component}\n"
|
183
|
+
|
184
|
+
if locals.any?
|
185
|
+
out << indent(1)
|
186
|
+
out << "attr_accessor "
|
187
|
+
out << locals.sort.map { |local| ":#{local}" }.join(", ")
|
188
|
+
out << "\n\n"
|
189
|
+
end
|
190
|
+
|
191
|
+
@custom_elements.sort.each do |element|
|
192
|
+
out << indent(1)
|
193
|
+
out << "register_element :#{element}\n"
|
194
|
+
end
|
171
195
|
|
172
|
-
|
173
|
-
|
196
|
+
kwargs = Set.new(ivars + locals).sort
|
197
|
+
|
198
|
+
if kwargs.any?
|
199
|
+
out << indent(1)
|
200
|
+
out << "def initialize("
|
201
|
+
out << kwargs.map { |kwarg| "#{kwarg}: " }.join(", ")
|
202
|
+
out << ")\n"
|
203
|
+
|
204
|
+
kwargs.each do |dep|
|
205
|
+
out << indent(2)
|
206
|
+
out << "@#{dep} = #{dep}\n"
|
207
|
+
end
|
208
|
+
|
209
|
+
out << indent(1)
|
210
|
+
out << "end\n"
|
174
211
|
end
|
175
212
|
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
213
|
+
out << indent(1)
|
214
|
+
out << "def template\n"
|
215
|
+
|
216
|
+
out << indent(2)
|
217
|
+
out << @buffer.string
|
218
|
+
|
219
|
+
out << indent(1)
|
220
|
+
out << "end\n"
|
221
|
+
out << "end\n"
|
180
222
|
else
|
181
|
-
|
223
|
+
out << @buffer.string
|
182
224
|
end
|
183
225
|
|
184
|
-
Rufo::Formatter.format(
|
226
|
+
Rufo::Formatter.format(out.string.strip)
|
185
227
|
rescue Rufo::SyntaxError
|
186
|
-
|
228
|
+
out.string.strip
|
229
|
+
end
|
230
|
+
|
231
|
+
def analyze_ruby
|
232
|
+
ruby_code = ErbParser.parse(html).tokens.map { |tag| tag.is_a?(ErbParser::ErbTag) && !tag.to_s.start_with?("<%#") ? tag.ruby_code.delete_prefix("=") : nil }.join("\n")
|
233
|
+
visitor = Phlexing::Visitor.new(self)
|
234
|
+
program = SyntaxTree.parse(ruby_code)
|
235
|
+
# puts program.construct_keys
|
236
|
+
visitor.visit(program)
|
237
|
+
rescue StandardError => e
|
238
|
+
puts e.inspect
|
187
239
|
end
|
188
240
|
|
189
241
|
def converted_erb
|
data/lib/phlexing/helpers.rb
CHANGED
@@ -1,7 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "phlex"
|
4
|
+
|
3
5
|
module Phlexing
|
4
6
|
module Helpers
|
7
|
+
KNOWN_ELEMENTS = Phlex::HTML::VOID_ELEMENTS.values + Phlex::HTML::STANDARD_ELEMENTS.values
|
8
|
+
|
5
9
|
def indent(level)
|
6
10
|
return "" if level == 1
|
7
11
|
|
@@ -33,10 +37,10 @@ module Phlexing
|
|
33
37
|
|
34
38
|
def node_name(node)
|
35
39
|
return "template_tag" if node.name == "template"
|
36
|
-
return node.name unless node.name.include?("-")
|
37
40
|
|
38
41
|
name = node.name.gsub("-", "_")
|
39
|
-
|
42
|
+
|
43
|
+
@custom_elements << name unless KNOWN_ELEMENTS.include?(name)
|
40
44
|
|
41
45
|
name
|
42
46
|
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Phlexing
|
4
|
+
class NameSuggestor
|
5
|
+
def self.suggest(html)
|
6
|
+
converter = Phlexing::Converter.new(html)
|
7
|
+
|
8
|
+
ivars = converter.ivars
|
9
|
+
locals = converter.locals
|
10
|
+
|
11
|
+
ids = extract(converter, :extract_id_from_element)
|
12
|
+
classes = extract(converter, :extract_class_from_element)
|
13
|
+
tags = extract(converter, :extract_tag_name_from_element)
|
14
|
+
|
15
|
+
return wrap(ivars.first) if ivars.one? && locals.none?
|
16
|
+
return wrap(locals.first) if locals.one? && ivars.none?
|
17
|
+
return wrap(ids.first) if ids.any?
|
18
|
+
return wrap(ivars.first) if ivars.any?
|
19
|
+
return wrap(locals.first) if locals.any?
|
20
|
+
return wrap(classes.first) if classes.any?
|
21
|
+
return wrap(tags.first) if tags.any?
|
22
|
+
|
23
|
+
"Component"
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.wrap(name)
|
27
|
+
"#{name}_component".gsub("-", "_").gsub(" ", "_").camelize
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.extract(converter, method)
|
31
|
+
return [] unless converter.parsed
|
32
|
+
|
33
|
+
converter.parsed.children.map { |element| send(method, element) }.compact
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.extract_id_from_element(element)
|
37
|
+
return if element.nil?
|
38
|
+
return if element.is_a?(Nokogiri::XML::Text)
|
39
|
+
|
40
|
+
id_attribute = element.attributes.try(:[], "id")
|
41
|
+
return if id_attribute.nil?
|
42
|
+
|
43
|
+
id = id_attribute.value.to_s.strip
|
44
|
+
return if id.include?("<erb")
|
45
|
+
|
46
|
+
id
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.extract_class_from_element(element)
|
50
|
+
return if element.nil?
|
51
|
+
return if element.is_a?(Nokogiri::XML::Text)
|
52
|
+
|
53
|
+
class_attribute = element.attributes.try(:[], "class")
|
54
|
+
|
55
|
+
return if class_attribute.nil?
|
56
|
+
|
57
|
+
classes = class_attribute.value.strip.split
|
58
|
+
|
59
|
+
return if classes.empty?
|
60
|
+
|
61
|
+
classes[0]
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.extract_tag_name_from_element(element)
|
65
|
+
return if element.nil?
|
66
|
+
return if element.is_a?(Nokogiri::XML::Text)
|
67
|
+
|
68
|
+
return if ["div", "span", "p", "erb"].include?(element.name)
|
69
|
+
|
70
|
+
element.name
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
data/lib/phlexing/version.rb
CHANGED
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "syntax_tree"
|
4
|
+
|
5
|
+
module Phlexing
|
6
|
+
class Visitor < SyntaxTree::Visitor
|
7
|
+
def initialize(converter)
|
8
|
+
@converter = converter
|
9
|
+
end
|
10
|
+
|
11
|
+
def visit_ivar(node)
|
12
|
+
@converter.ivars << node.value.from(1)
|
13
|
+
end
|
14
|
+
|
15
|
+
def visit_vcall(node)
|
16
|
+
@converter.locals << node.value.value
|
17
|
+
end
|
18
|
+
|
19
|
+
def visit_ident(node)
|
20
|
+
@converter.idents << node.value
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/phlexing.rb
CHANGED
@@ -3,6 +3,8 @@
|
|
3
3
|
require_relative "phlexing/version"
|
4
4
|
require_relative "phlexing/helpers"
|
5
5
|
require_relative "phlexing/refinements/string_refinements"
|
6
|
+
require_relative "phlexing/visitor"
|
7
|
+
require_relative "phlexing/name_suggestor"
|
6
8
|
require_relative "phlexing/converter"
|
7
9
|
|
8
10
|
module Phlexing
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: phlexing
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marco Roth
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-01-
|
11
|
+
date: 2023-01-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: erb_parser
|
@@ -66,6 +66,20 @@ dependencies:
|
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: 0.13.0
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: syntax_tree
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
69
83
|
description: Simple ERB to Phlex converter
|
70
84
|
email:
|
71
85
|
- marco.roth@hey.com
|
@@ -83,8 +97,10 @@ files:
|
|
83
97
|
- lib/phlexing.rb
|
84
98
|
- lib/phlexing/converter.rb
|
85
99
|
- lib/phlexing/helpers.rb
|
100
|
+
- lib/phlexing/name_suggestor.rb
|
86
101
|
- lib/phlexing/refinements/string_refinements.rb
|
87
102
|
- lib/phlexing/version.rb
|
103
|
+
- lib/phlexing/visitor.rb
|
88
104
|
- sig/phlexing.rbs
|
89
105
|
homepage: https://github.com/marcoroth/phlexing
|
90
106
|
licenses:
|