canon 0.3.3 → 0.3.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 52174949c77e8f33286b2875ac5e4052e6f5671b64e53e48a3b0b3128bb598a1
4
- data.tar.gz: 0b2efb1c4fa7e060f6d54f1c149bd775d45fab66e09ac7bbf306f0a6142360fa
3
+ metadata.gz: 53a9382cf5977e8e1b65a847cd11f9f2c61a162c3913a64588e4d48c71cfbf94
4
+ data.tar.gz: 851f0227e56cffdd225fce23ec32b78b3b44f43e08137a39572a2db237d94aaf
5
5
  SHA512:
6
- metadata.gz: 4e78d8618af59c255979bf3987a1be3e7419e009354b73ca64df75600ce8c2f1cc90aa515eb14be97149fe5426243efacda4ff42eab63b5fc8f291407baa046e
7
- data.tar.gz: 2596286ac94921e6021590fe6f1ece71d827145743cc993f703cfca079fb91472845c67f25a3e9ad03aecd471c6cc482cd78854a5e9ce85d16bd8f0ea5643636
6
+ metadata.gz: 67710ade1d18f99c23e4477540303f45867d145c7f92df59f2f1277cf442c576eca2a3d8562cb92972f56d80dbe111e6104d28353cb7c5091d690490605772ff
7
+ data.tar.gz: e8d2783baa8fba878cb3cbb7a602dff3563f23dfb15df95ca5c24c075475d53c8319f2579bf3ce3c533e1989b1c75b91b72913c57c30279278a59de68202aef0
data/lib/canon/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Canon
4
- VERSION = "0.3.3"
4
+ VERSION = "0.3.4"
5
5
  end
@@ -126,28 +126,49 @@ module Canon
126
126
  end
127
127
  end
128
128
 
129
+ # --- Shared construction kernels (identical semantics per engine) ---
130
+
131
+ # Attach document-level children (prolog/epilog PIs, comments,
132
+ # document-level text) to the canon root, in document order,
133
+ # skipping the document element and the doctype. `converter`
134
+ # converts one engine child to a canon node (or nil).
135
+ def self.add_document_children(root, children, document_element,
136
+ skip_types, converter)
137
+ children.each do |child|
138
+ next if child.equal?(document_element)
139
+ next if skip_types.any? { |type| child.is_a?(type) }
140
+
141
+ node = converter.call(child)
142
+ root.add_child(node) if node
143
+ end
144
+ end
145
+
146
+ # In-scope namespace bindings: the element's own declarations
147
+ # shadow inherited ones; xml is prebound at the base. Declaration
148
+ # pairs are [prefix-or-nil, uri]; nil and "" both mean the default
149
+ # namespace.
150
+ def self.merge_namespace_scope(inherited, declaration_pairs)
151
+ scope = inherited ? inherited.dup : { "xml" => "http://www.w3.org/XML/1998/namespace" }
152
+ declaration_pairs.each do |prefix, uri|
153
+ scope[prefix || ""] = uri
154
+ end
155
+ scope
156
+ end
157
+
129
158
  def self.build_from_nokogiri(nokogiri_doc, preserve_whitespace: false)
130
159
  root = Nodes::RootNode.new
131
160
 
161
+ converter = ->(child) { build_node_from_nokogiri(child, preserve_whitespace: preserve_whitespace) }
162
+ skip_types = defined?(Nokogiri) ? [Nokogiri::XML::DTD] : []
163
+
132
164
  if nokogiri_doc.is_a?(Nokogiri::XML::Document) && nokogiri_doc.root
133
165
  root.add_child(build_element_node(nokogiri_doc.root,
134
166
  preserve_whitespace: preserve_whitespace))
135
- nokogiri_doc.children.each do |child|
136
- next if child == nokogiri_doc.root
137
- next if child.is_a?(Nokogiri::XML::DTD)
138
-
139
- node = build_node_from_nokogiri(child,
140
- preserve_whitespace: preserve_whitespace)
141
- root.add_child(node) if node
142
- end
167
+ add_document_children(root, nokogiri_doc.children, nokogiri_doc.root,
168
+ skip_types, converter)
143
169
  else
144
- nokogiri_doc.children.each do |child|
145
- next if child.is_a?(Nokogiri::XML::DTD)
146
-
147
- node = build_node_from_nokogiri(child,
148
- preserve_whitespace: preserve_whitespace)
149
- root.add_child(node) if node
150
- end
170
+ add_document_children(root, nokogiri_doc.children, nil,
171
+ skip_types, converter)
151
172
  end
152
173
 
153
174
  root
@@ -198,16 +219,14 @@ inherited_namespaces: nil)
198
219
  element
199
220
  end
200
221
 
201
- # In-scope namespace bindings: the element's own declarations
202
- # shadow inherited ones, xml is prebound. The scope is passed down
222
+ # In-scope bindings via the shared kernel; the scope is passed down
203
223
  # the recursion — one definition fetch per element instead of an
204
224
  # ancestor walk per element (O(n) total, not O(n * depth)).
205
225
  def self.nokogiri_namespace_scope(nokogiri_element, inherited)
206
- scope = inherited ? inherited.dup : { "xml" => "http://www.w3.org/XML/1998/namespace" }
207
- nokogiri_element.namespace_definitions.each do |ns|
208
- scope[ns.prefix || ""] = ns.href
209
- end
210
- scope
226
+ merge_namespace_scope(inherited,
227
+ nokogiri_element.namespace_definitions.map do |ns|
228
+ [ns.prefix, ns.href]
229
+ end)
211
230
  end
212
231
 
213
232
  def self.build_attribute_nodes(nokogiri_element, element)
@@ -283,26 +302,18 @@ inherited_namespaces: nil)
283
302
  def self.build_from_moxml(moxml_doc, preserve_whitespace: false)
284
303
  root = Nodes::RootNode.new
285
304
 
305
+ converter = ->(child) { build_moxml_node(child, preserve_whitespace: preserve_whitespace) }
306
+ skip_types = [Moxml::Doctype]
307
+
286
308
  if moxml_doc.is_a?(Moxml::Document) && moxml_doc.root
287
309
  element = build_moxml_subtree_from_records(moxml_doc.root,
288
310
  preserve_whitespace: preserve_whitespace)
289
311
  root.add_child(element) if element
290
- moxml_doc.children.each do |child|
291
- next if child.equal?(moxml_doc.root)
292
- next if child.is_a?(Moxml::Doctype)
293
-
294
- node = build_moxml_node(child,
295
- preserve_whitespace: preserve_whitespace)
296
- root.add_child(node) if node
297
- end
312
+ add_document_children(root, moxml_doc.children, moxml_doc.root,
313
+ skip_types, converter)
298
314
  else
299
- moxml_doc.children.each do |child|
300
- next if child.is_a?(Moxml::Doctype)
301
-
302
- node = build_moxml_node(child,
303
- preserve_whitespace: preserve_whitespace)
304
- root.add_child(node) if node
305
- end
315
+ add_document_children(root, moxml_doc.children, nil,
316
+ skip_types, converter)
306
317
  end
307
318
 
308
319
  root
@@ -401,14 +412,11 @@ preserve_whitespace: false)
401
412
  Nodes::TextNode.new(value: content, original: content)
402
413
  end
403
414
 
404
- # Expand each element's own declarations to in-scope bindings:
405
- # the element's declarations shadow inherited ones; xml is
406
- # prebound. Scope flows down the canon tree — no engine calls.
415
+ # Expand each element's own declarations to in-scope bindings via
416
+ # the shared kernel. Scope flows down the canon tree — no engine
417
+ # calls.
407
418
  def self.assign_moxml_namespace_scopes(element, inherited, own_namespaces)
408
- scope = inherited.dup
409
- own_namespaces[element].to_a.each do |prefix, uri|
410
- scope[prefix || ""] = uri
411
- end
419
+ scope = merge_namespace_scope(inherited, own_namespaces[element].to_a)
412
420
 
413
421
  scope.each do |prefix, uri|
414
422
  element.add_namespace(Nodes::NamespaceNode.new(
@@ -474,11 +482,10 @@ inherited_namespaces: nil)
474
482
  # of an ancestor walk through the adapter layer (the Nokogiri
475
483
  # collector walks ancestors because those calls are cheap there).
476
484
  def self.moxml_namespace_scope(moxml_element, inherited)
477
- scope = inherited ? inherited.dup : { "xml" => "http://www.w3.org/XML/1998/namespace" }
478
- moxml_element.namespace_definitions.each do |decl|
479
- scope[decl.prefix || ""] = decl.uri
480
- end
481
- scope
485
+ merge_namespace_scope(inherited,
486
+ moxml_element.namespace_definitions.map do |decl|
487
+ [decl.prefix, decl.uri]
488
+ end)
482
489
  end
483
490
 
484
491
  def self.build_moxml_attribute_nodes(moxml_element, element)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: canon
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.3
4
+ version: 0.3.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.