lwe_slate_serializer 1.0.0 → 1.0.1
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 +147 -122
- 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: 2baa0cc32467d4363e5fc73033befb4a9cd79ec838afe6e6753993d2b2c84e86
|
4
|
+
data.tar.gz: ca07a3ecdce7fadbf02cc5959ab9ca236839900483d68b51f4a5e224915bdc4d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4526ab16ef29cd444bbfc7db268987fe98f0740e35bd6d5f1a6c4f3dab76582bad196f82b4a0d762e5c031692e6b86c701814cdf3f9e9933188ab84723b308bc
|
7
|
+
data.tar.gz: 97f0425e77ef5b752aec8b02b5bf071f3e5d424cfd93bc5e45ac37d2267571120c4bb764ad2040207e054a9ecec8d40368f6ece85f3e5a4df6fdd0ff134ae469
|
@@ -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,183 @@ 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: ['a'], node: 'link'),
|
62
|
+
SerializerHandler.new(elements: ['ol'], node: 'ordered-list'),
|
63
|
+
SerializerHandler.new(elements: ['ul'], node: 'unordered-list'),
|
64
|
+
SerializerHandler.new(elements: ['li'], node: 'list-item'),
|
65
|
+
SerializerHandler.new(elements: ['p', 'div'], node: 'paragraph'),
|
66
|
+
SerializerHandler.new(elements: ['table'], node: 'table'),
|
67
|
+
SerializerHandler.new(elements: ['tbody'], node: 'tbody'),
|
68
|
+
SerializerHandler.new(elements: ['tr'], node: 'tr'),
|
69
|
+
SerializerHandler.new(elements: ['td'], node: 'td'),
|
70
|
+
SerializerHandler.new(elements: ['figure'], node: 'figure'),
|
71
|
+
SerializerHandler.new(elements: ['figcaption'], node: 'figcaption'),
|
72
|
+
]).each do |handler|
|
73
|
+
register_handler(handler)
|
58
74
|
end
|
75
|
+
end
|
59
76
|
|
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
|
77
|
+
def register_handler(handler)
|
78
|
+
handler.elements.each do |element|
|
79
|
+
@element_register[element] = handler.deserialize
|
68
80
|
end
|
81
|
+
@node_register[handler.node] = handler.serialize
|
82
|
+
@tag_register[handler.node] = handler.elements.first
|
83
|
+
end
|
69
84
|
|
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 == ''
|
85
|
+
class SerializerHandler
|
86
|
+
attr_reader :elements, :node, :serialize, :deserialize
|
83
87
|
|
84
|
-
|
85
|
-
|
86
|
-
|
88
|
+
def initialize(elements: [], node: nil, serialize: nil, deserialize: nil)
|
89
|
+
@elements = elements
|
90
|
+
@node = node
|
91
|
+
@serialize = serialize || ->(node, children, tag) do
|
92
|
+
"<#{tag}>#{children}</#{tag}>"
|
93
|
+
end
|
94
|
+
@deserialize = deserialize || ->(node, element) do
|
95
|
+
node.merge(type: @node)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
87
99
|
|
88
|
-
|
100
|
+
# Convert html to a Slate document
|
101
|
+
#
|
102
|
+
# @param value format [Hash] the Slate document
|
103
|
+
# @return [String] plain text version of the Slate documnent
|
104
|
+
def serialize(value)
|
105
|
+
return '' unless value.is_a?(Array)
|
89
106
|
|
90
|
-
|
91
|
-
|
92
|
-
type: type
|
93
|
-
}
|
107
|
+
value.map { |n| serialize_node(n) }.join
|
108
|
+
end
|
94
109
|
|
95
|
-
|
110
|
+
# Convert html to a Slate document
|
111
|
+
#
|
112
|
+
# @param html format [String] the HTML
|
113
|
+
# @param options [Hash]
|
114
|
+
# @option options [Array] :elements Lookup list to convert html tags to object types
|
115
|
+
# @option options [Array] :block_elemnts List of block types
|
116
|
+
# @option options [Array] :inline_elemnts List of inline types
|
117
|
+
# @option options [Array] :mark_elemnts List of mark types
|
118
|
+
def deserialize(html)
|
119
|
+
return empty_state if html.nil? || html == ''
|
120
|
+
|
121
|
+
html = html.gsub('<br>', "\n")
|
122
|
+
Nokogiri::HTML.fragment(html).elements.map do |element|
|
123
|
+
element_to_node(element)
|
96
124
|
end
|
125
|
+
end
|
97
126
|
|
98
|
-
|
99
|
-
type = convert_name_to_type(element)
|
100
|
-
nodes = element.children.flat_map do |child|
|
101
|
-
element_to_texts(child)
|
102
|
-
end
|
127
|
+
private
|
103
128
|
|
104
|
-
|
105
|
-
children: nodes,
|
106
|
-
type: type
|
107
|
-
}
|
108
|
-
end
|
129
|
+
attr_accessor :elements, :block_elements, :inline_elements, :mark_elements
|
109
130
|
|
110
|
-
|
111
|
-
|
112
|
-
|
131
|
+
def element_to_node(element, marks = [])
|
132
|
+
handler = @element_register[element.name]
|
133
|
+
|
134
|
+
mark = convert_name_to_mark(element.name)
|
135
|
+
marks = [*marks, mark].compact
|
113
136
|
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
137
|
+
children = element.children.flat_map do |child|
|
138
|
+
if child.text?
|
139
|
+
next if child.text.strip == ''
|
140
|
+
element_to_text(child, marks)
|
118
141
|
else
|
119
|
-
|
142
|
+
element_to_node(child, marks)
|
120
143
|
end
|
144
|
+
end.compact
|
121
145
|
|
122
|
-
|
123
|
-
end
|
146
|
+
children << { text: '' } if children.empty?
|
124
147
|
|
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
|
148
|
+
return children unless handler
|
149
|
+
handler.call({ children: children }, element)
|
150
|
+
end
|
134
151
|
|
135
|
-
|
136
|
-
|
137
|
-
|
152
|
+
# def element_to_texts(element)
|
153
|
+
# nodes = []
|
154
|
+
# mark = convert_name_to_mark(element.name)
|
155
|
+
|
156
|
+
# if element.class == Nokogiri::XML::Element
|
157
|
+
# element.children.each do |child|
|
158
|
+
# nodes << element_to_text(child, mark)
|
159
|
+
# end
|
160
|
+
# else
|
161
|
+
# nodes << element_to_text(element)
|
162
|
+
# end
|
163
|
+
|
164
|
+
# nodes
|
165
|
+
# end
|
166
|
+
|
167
|
+
def element_to_text(element, marks = [])
|
168
|
+
{
|
169
|
+
text: element.text
|
170
|
+
}.tap do |text|
|
171
|
+
marks.compact.each do |m|
|
172
|
+
text[m[:type].to_sym] = true
|
173
|
+
end
|
138
174
|
end
|
175
|
+
end
|
139
176
|
|
140
|
-
|
141
|
-
|
177
|
+
def convert_name_to_mark(name)
|
178
|
+
type = mark_elements[name.to_sym]
|
142
179
|
|
143
|
-
|
180
|
+
return nil unless type
|
181
|
+
{
|
182
|
+
type: type
|
183
|
+
}
|
184
|
+
end
|
144
185
|
|
186
|
+
def empty_state
|
187
|
+
[
|
145
188
|
{
|
146
|
-
type:
|
189
|
+
type: 'paragraph',
|
190
|
+
children: [
|
191
|
+
{
|
192
|
+
text: ''
|
193
|
+
}
|
194
|
+
]
|
147
195
|
}
|
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
|
196
|
+
]
|
197
|
+
end
|
170
198
|
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
199
|
+
def serialize_node(node)
|
200
|
+
if node[:text]
|
201
|
+
node[:text]
|
202
|
+
else
|
203
|
+
handler = @node_register[node[:type]]
|
204
|
+
children = node[:children].map { |n| serialize_node(n) }.join
|
176
205
|
|
177
|
-
|
178
|
-
|
179
|
-
if %i[ol1 ola].include?(element)
|
180
|
-
element = :ol
|
181
|
-
end
|
206
|
+
return children unless handler
|
182
207
|
|
183
|
-
|
184
|
-
|
208
|
+
tag = @tag_register[node[:type]]
|
209
|
+
handler.call(node, children, tag)
|
185
210
|
end
|
186
211
|
end
|
187
212
|
end
|