lwe_slate_serializer 1.0.5 → 1.0.7
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/lib/slate_serializer/html.rb +142 -121
- data/lib/slate_serializer/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 357ee78ae9c5e22655caebfce304878620477033d63f13a75923a8509dfb6f67
|
4
|
+
data.tar.gz: 03f957e81cea5001d40ab05316bee3910509acd5c5c9e396627d370f0782676b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ec50813c392a9fc2cc0acfd6063f3346c10512b364e7b7000ba351d654bca283c8c45638a82f8d95e0ffc72e6fd630dcf91a93873774b1e462ea6640ee690c10
|
7
|
+
data.tar.gz: c3e120dc1585c020715a4bc1392f0b4aba0c57d51908898d8ccc28f3fb8122fa1442fa108c4e16b89e9506cf7bea8e233112a07576e2771295f8b389ae56aac7
|
@@ -11,7 +11,6 @@ module SlateSerializer
|
|
11
11
|
'p': 'paragraph',
|
12
12
|
'div': 'paragraph',
|
13
13
|
'ol1': 'ordered-list',
|
14
|
-
'ola': 'alpha-ordered-list',
|
15
14
|
'ol': 'ordered-list',
|
16
15
|
'ul': 'unordered-list',
|
17
16
|
'table': 'table',
|
@@ -31,157 +30,179 @@ module SlateSerializer
|
|
31
30
|
MARK_ELEMENTS = {
|
32
31
|
'em': 'italic',
|
33
32
|
'strong': 'bold',
|
33
|
+
'b': 'bold',
|
34
34
|
'u': 'underline'
|
35
35
|
}.freeze
|
36
36
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
37
|
+
def initialize(options = {})
|
38
|
+
@elements = options[:elements] || ELEMENTS
|
39
|
+
@block_elements = options[:block_elements] || BLOCK_ELEMENTS
|
40
|
+
@inline_elements = options[:inline_elements] || INLINE_ELEMENTS
|
41
|
+
@mark_elements = options[:mark_elements] || MARK_ELEMENTS
|
42
|
+
@element_register = {}
|
43
|
+
@node_register = {}
|
44
|
+
@tag_register = {}
|
45
|
+
|
46
|
+
(options[:handlers] || [
|
47
|
+
SerializerHandler.new(
|
48
|
+
elements: ['img'],
|
49
|
+
node: 'image',
|
50
|
+
serialize: ->(node, children, tag) do
|
51
|
+
"<#{tag} src=\"#{node[:url]}\"/>"
|
52
|
+
end
|
53
|
+
),
|
54
|
+
SerializerHandler.new(
|
55
|
+
elements: ['hr'],
|
56
|
+
node: 'hr',
|
57
|
+
serialize: ->(node, children, tag) do
|
58
|
+
"<#{tag}/>"
|
59
|
+
end
|
60
|
+
),
|
61
|
+
SerializerHandler.new(elements: ['text']),
|
62
|
+
SerializerHandler.new(elements: ['i', 'em'], mark: 'italic'),
|
63
|
+
SerializerHandler.new(elements: ['u'], mark: 'underline'),
|
64
|
+
SerializerHandler.new(elements: ['strong', 'b'], mark: 'bold'),
|
65
|
+
SerializerHandler.new(elements: ['a'], node: 'link'),
|
66
|
+
SerializerHandler.new(elements: ['ol'], node: 'ordered-list'),
|
67
|
+
SerializerHandler.new(elements: ['ul'], node: 'unordered-list'),
|
68
|
+
SerializerHandler.new(elements: ['li'], node: 'list-item'),
|
69
|
+
SerializerHandler.new(elements: ['p', 'div'], node: 'paragraph'),
|
70
|
+
SerializerHandler.new(elements: ['table'], node: 'table'),
|
71
|
+
SerializerHandler.new(elements: ['tbody'], node: 'tbody'),
|
72
|
+
SerializerHandler.new(elements: ['tr'], node: 'tr'),
|
73
|
+
SerializerHandler.new(elements: ['td'], node: 'td'),
|
74
|
+
SerializerHandler.new(elements: ['figure'], node: 'figure'),
|
75
|
+
SerializerHandler.new(elements: ['figcaption'], node: 'figcaption'),
|
76
|
+
]).each do |handler|
|
77
|
+
register_handler(handler)
|
58
78
|
end
|
79
|
+
end
|
59
80
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
# @return [String] plain text version of the Slate documnent
|
64
|
-
def serializer(value)
|
65
|
-
return '' unless value.is_a?(Array)
|
66
|
-
|
67
|
-
value.map { |n| serialize_node(n) }.join
|
81
|
+
def register_handler(handler)
|
82
|
+
handler.elements.each do |element|
|
83
|
+
@element_register[element] = handler
|
68
84
|
end
|
85
|
+
@node_register[handler.node] = handler.serialize
|
86
|
+
@tag_register[handler.node] = handler.elements.first
|
87
|
+
end
|
69
88
|
|
70
|
-
|
71
|
-
|
72
|
-
attr_accessor :elements, :block_elements, :inline_elements, :mark_elements
|
73
|
-
|
74
|
-
def element_to_node(element)
|
75
|
-
type = convert_name_to_type(element)
|
76
|
-
children = element.children.flat_map do |child|
|
77
|
-
if block?(child)
|
78
|
-
element_to_node(child)
|
79
|
-
elsif inline?(child)
|
80
|
-
element_to_inline(child)
|
81
|
-
else
|
82
|
-
next if child.text.strip == ''
|
89
|
+
class SerializerHandler
|
90
|
+
attr_reader :elements, :node, :serialize, :deserialize, :mark
|
83
91
|
|
84
|
-
|
92
|
+
def initialize(elements: [], node: nil, mark: nil, serialize: nil, deserialize: nil)
|
93
|
+
@elements = elements
|
94
|
+
@node = node
|
95
|
+
@mark = mark
|
96
|
+
@serialize = serialize || ->(node, children, tag) do
|
97
|
+
"<#{tag}>#{children}</#{tag}>"
|
98
|
+
end
|
99
|
+
@deserialize = deserialize || ->(children, element) do
|
100
|
+
if @node
|
101
|
+
{ type: @node, children: children }
|
102
|
+
else
|
103
|
+
children
|
85
104
|
end
|
86
|
-
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
87
108
|
|
88
|
-
|
109
|
+
# Convert html to a Slate document
|
110
|
+
#
|
111
|
+
# @param value format [Hash] the Slate document
|
112
|
+
# @return [String] plain text version of the Slate documnent
|
113
|
+
def serialize(value)
|
114
|
+
return '' unless value.is_a?(Array)
|
89
115
|
|
90
|
-
|
91
|
-
|
92
|
-
type: type
|
93
|
-
}
|
116
|
+
value.map { |n| serialize_node(n) }.join
|
117
|
+
end
|
94
118
|
|
95
|
-
|
119
|
+
# Convert html to a Slate document
|
120
|
+
#
|
121
|
+
# @param html format [String] the HTML
|
122
|
+
# @param options [Hash]
|
123
|
+
# @option options [Array] :elements Lookup list to convert html tags to object types
|
124
|
+
# @option options [Array] :block_elemnts List of block types
|
125
|
+
# @option options [Array] :inline_elemnts List of inline types
|
126
|
+
# @option options [Array] :mark_elemnts List of mark types
|
127
|
+
def deserialize(html)
|
128
|
+
return empty_state if html.nil? || html == ''
|
129
|
+
|
130
|
+
html = html.gsub('<br>', "\n")
|
131
|
+
Nokogiri::HTML.fragment(html).elements.flat_map do |element|
|
132
|
+
element_to_node(element)
|
96
133
|
end
|
134
|
+
end
|
97
135
|
|
98
|
-
|
99
|
-
type = convert_name_to_type(element)
|
100
|
-
nodes = element.children.flat_map do |child|
|
101
|
-
element_to_texts(child)
|
102
|
-
end
|
136
|
+
private
|
103
137
|
|
104
|
-
|
105
|
-
children: nodes,
|
106
|
-
type: type
|
107
|
-
}
|
108
|
-
end
|
138
|
+
attr_accessor :elements, :block_elements, :inline_elements, :mark_elements
|
109
139
|
|
110
|
-
|
111
|
-
|
112
|
-
|
140
|
+
def element_to_node(element, marks = [])
|
141
|
+
handler = @element_register[element.name]
|
142
|
+
marks = [*marks, handler&.mark].compact
|
113
143
|
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
144
|
+
children = element.children.flat_map do |child|
|
145
|
+
if handler&.mark
|
146
|
+
element_to_text(child, marks)
|
147
|
+
elsif child.text?
|
148
|
+
next if child.text.strip == ''
|
149
|
+
element_to_text(child, marks)
|
118
150
|
else
|
119
|
-
|
151
|
+
element_to_node(child, marks)
|
120
152
|
end
|
153
|
+
end.compact
|
121
154
|
|
122
|
-
|
123
|
-
end
|
155
|
+
children << { text: '' } if children.empty?
|
124
156
|
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
}.tap do |text|
|
129
|
-
[mark, convert_name_to_mark(element.name)].compact.each do |m|
|
130
|
-
text[m[:type].to_sym] = true
|
131
|
-
end
|
132
|
-
end
|
133
|
-
end
|
157
|
+
return children unless handler
|
158
|
+
handler.deserialize.call(children, element)
|
159
|
+
end
|
134
160
|
|
135
|
-
|
136
|
-
|
137
|
-
|
161
|
+
def element_to_text(element, marks = [])
|
162
|
+
handler = @element_register[element.name]
|
163
|
+
marks = [*marks, handler.mark].compact
|
164
|
+
{
|
165
|
+
text: element.text
|
166
|
+
}.tap do |text|
|
167
|
+
marks.compact.each do |m|
|
168
|
+
text[m.to_sym] = true
|
169
|
+
end
|
138
170
|
end
|
171
|
+
end
|
139
172
|
|
140
|
-
|
141
|
-
|
173
|
+
def convert_name_to_mark(name)
|
174
|
+
type = mark_elements[name.to_sym]
|
142
175
|
|
143
|
-
|
176
|
+
return nil unless type
|
177
|
+
{
|
178
|
+
type: type
|
179
|
+
}
|
180
|
+
end
|
144
181
|
|
182
|
+
def empty_state
|
183
|
+
[
|
145
184
|
{
|
146
|
-
type:
|
185
|
+
type: 'paragraph',
|
186
|
+
children: [
|
187
|
+
{
|
188
|
+
text: ''
|
189
|
+
}
|
190
|
+
]
|
147
191
|
}
|
148
|
-
|
149
|
-
|
150
|
-
def block?(element)
|
151
|
-
block_elements.include?(element.name)
|
152
|
-
end
|
153
|
-
|
154
|
-
def inline?(element)
|
155
|
-
inline_elements.include?(element.name)
|
156
|
-
end
|
157
|
-
|
158
|
-
def empty_state
|
159
|
-
[
|
160
|
-
{
|
161
|
-
type: 'paragraph',
|
162
|
-
children: [
|
163
|
-
{
|
164
|
-
text: ''
|
165
|
-
}
|
166
|
-
]
|
167
|
-
}
|
168
|
-
]
|
169
|
-
end
|
192
|
+
]
|
193
|
+
end
|
170
194
|
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
195
|
+
def serialize_node(node)
|
196
|
+
if node[:text]
|
197
|
+
node[:text]
|
198
|
+
elsif node[:children]
|
199
|
+
handler = @node_register[node[:type]]
|
200
|
+
children = node[:children].map { |n| serialize_node(n) }.join
|
176
201
|
|
177
|
-
|
178
|
-
|
179
|
-
if %i[ol1 ola].include?(element)
|
180
|
-
element = :ol
|
181
|
-
end
|
202
|
+
return children unless handler
|
182
203
|
|
183
|
-
|
184
|
-
|
204
|
+
tag = @tag_register[node[:type]]
|
205
|
+
handler.call(node, children, tag)
|
185
206
|
end
|
186
207
|
end
|
187
208
|
end
|