xml-mixup 0.1.12 → 0.1.16
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/xml/mixup/version.rb +1 -1
- data/lib/xml/mixup.rb +85 -77
- data/xml-mixup.gemspec +5 -5
- metadata +15 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f2987df3a876da2b544c023d70a16dc8a44eb8bf391af07436263004b180f095
|
4
|
+
data.tar.gz: d04b0ad24255030ae51d50c7d198d95baf08570ec6a3e411b61119ef329a1542
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6537916b1380983c64e39aaf54048a0a08e6df07662c7319c07df566dee3320dd850b1153cfa705a7f18bacad12a26949d13b968f59c21a76270007889a2a3c2
|
7
|
+
data.tar.gz: 85d6a953e37ec44ca90f6b28dcb39483de885b094b17fa70caabf9ad18f52d6e723345391c264033df094f82f0db79e892231152615f9e305161badeca80dd8c
|
data/lib/xml/mixup/version.rb
CHANGED
data/lib/xml/mixup.rb
CHANGED
@@ -3,12 +3,9 @@ require 'nokogiri'
|
|
3
3
|
require 'set'
|
4
4
|
|
5
5
|
module XML::Mixup
|
6
|
-
|
7
|
-
#
|
8
|
-
|
9
6
|
# these are node attachment protocols
|
10
7
|
private
|
11
|
-
|
8
|
+
|
12
9
|
ADJACENT = {
|
13
10
|
parent: lambda do |node, parent|
|
14
11
|
if parent.node_type == 9 and node.node_type == 1
|
@@ -31,8 +28,65 @@ module XML::Mixup
|
|
31
28
|
RESERVED = Set.new(%w{comment cdata doctype dtd elem element
|
32
29
|
pi processing-instruction tag}.map {|x| "##{x}"}).freeze
|
33
30
|
|
31
|
+
ATOMS = [String, Symbol, Numeric, FalseClass, TrueClass].freeze
|
32
|
+
|
33
|
+
def element tag, doc: nil, ns: {}, attr: {}, args: []
|
34
|
+
raise 'Document node must be present' unless doc
|
35
|
+
pfx = nil
|
36
|
+
if tag.respond_to? :to_a
|
37
|
+
pfx = tag[0]
|
38
|
+
tag = tag.to_a[0..1].join ':'
|
39
|
+
elsif m = tag.match(/([^:]+):/)
|
40
|
+
pfx = m[1]
|
41
|
+
end
|
42
|
+
|
43
|
+
elem = doc.create_element tag.to_s
|
44
|
+
elem.default_namespace = ns[pfx] if ns[pfx]
|
45
|
+
|
46
|
+
ns.keys.sort { |a, b| a.to_s <=> b.to_s }.each do |p|
|
47
|
+
elem.add_namespace((p.nil? ? p : p.to_s), ns[p].to_s)
|
48
|
+
end
|
49
|
+
attr.sort.each do |k, v|
|
50
|
+
v = flatten_attr(v, args) or next
|
51
|
+
elem[k.to_s] = v
|
52
|
+
end
|
53
|
+
|
54
|
+
elem
|
55
|
+
end
|
56
|
+
|
34
57
|
public
|
35
58
|
|
59
|
+
# Returns a string suitable for an XML attribute.
|
60
|
+
#
|
61
|
+
# @param obj [Object] the object to be flattened
|
62
|
+
# @param args [Array, nil] callback arguments
|
63
|
+
#
|
64
|
+
# @return [String] the attribute in question.
|
65
|
+
#
|
66
|
+
def flatten_attr obj, args = []
|
67
|
+
return if obj.nil?
|
68
|
+
args ||= []
|
69
|
+
# early bailout for most likely condition
|
70
|
+
if ATOMS.any? { |x| obj.is_a? x }
|
71
|
+
obj.to_s
|
72
|
+
elsif obj.is_a? Hash
|
73
|
+
tmp = obj.sort.map do |kv|
|
74
|
+
v = flatten_attr kv[1], args
|
75
|
+
v.nil? ? nil : "#{kv[0].to_s}: #{v}"
|
76
|
+
end.compact
|
77
|
+
tmp.empty? ? nil : tmp.join(' ')
|
78
|
+
elsif obj.respond_to? :call
|
79
|
+
flatten_attr obj.call(*args), args
|
80
|
+
elsif obj.respond_to? :map
|
81
|
+
tmp = obj.map { |x| flatten_attr x, args }.reject do |x|
|
82
|
+
x.nil? || x == ''
|
83
|
+
end
|
84
|
+
tmp.empty? ? nil : tmp.join(' ')
|
85
|
+
else
|
86
|
+
obj.to_s
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
36
90
|
# Generate a handy blank document.
|
37
91
|
#
|
38
92
|
# @param version [Numeric, nil]
|
@@ -51,6 +105,8 @@ module XML::Mixup
|
|
51
105
|
# include XML::Mixup
|
52
106
|
# end
|
53
107
|
#
|
108
|
+
# # note you can now also just call XML::Mixup.markup
|
109
|
+
#
|
54
110
|
# something = Anything.new
|
55
111
|
#
|
56
112
|
# # generate a structure
|
@@ -73,18 +129,18 @@ module XML::Mixup
|
|
73
129
|
# # case, it will be a text node containing 'lolwut'.
|
74
130
|
#
|
75
131
|
# doc = node.document
|
76
|
-
# puts doc.to_xml
|
132
|
+
# puts doc.to_xml
|
77
133
|
#
|
78
134
|
# @param spec [Hash, Array, Nokogiri::XML::Node, Proc, #to_s] An XML
|
79
135
|
# tree specification. May be composed of multiple hashes and
|
80
136
|
# arrays. See the spec spec.
|
81
|
-
#
|
137
|
+
#
|
82
138
|
# @param doc [Nokogiri::XML::Document, nil] an optional XML document
|
83
|
-
# instance; will be
|
139
|
+
# instance; will be created if none given.
|
84
140
|
#
|
85
141
|
# @param args [#to_a] Any arguments to be passed to any callbacks
|
86
142
|
# anywhere in the spec. Assumed to be an array.
|
87
|
-
#
|
143
|
+
#
|
88
144
|
# @param parent [Nokogiri::XML::Node] The node under which the
|
89
145
|
# evaluation result of the spec is to be attached. This is the
|
90
146
|
# default adjacent node, which in turn defaults to the document if
|
@@ -171,7 +227,7 @@ module XML::Mixup
|
|
171
227
|
x = x.to_a
|
172
228
|
name = x.shift
|
173
229
|
children = x
|
174
|
-
else
|
230
|
+
else
|
175
231
|
name = x
|
176
232
|
end
|
177
233
|
elsif (compact = spec.select { |k, _| k.respond_to?(:to_a) or
|
@@ -180,10 +236,10 @@ module XML::Mixup
|
|
180
236
|
raise %q{Spec can't have duplicate compact keys} if compact.count > 1
|
181
237
|
children, name = compact.first
|
182
238
|
children = children.is_a?(Hash) ||
|
183
|
-
children.is_a?(Nokogiri::XML::Node) ? [children] : children.to_a
|
239
|
+
children.is_a?(Nokogiri::XML::Node) ? [children] : children.to_a
|
184
240
|
elsif (special = spec.select { |k, _| k.respond_to? :to_s and
|
185
241
|
k.to_s.start_with? ?# }) and !special.empty?
|
186
|
-
# these are special keys
|
242
|
+
# these are special keys
|
187
243
|
raise %q{Spec can't have multiple special keys} if special.count > 1
|
188
244
|
name, children = special.first
|
189
245
|
|
@@ -203,7 +259,7 @@ module XML::Mixup
|
|
203
259
|
|
204
260
|
# don't forget to reset the child nodes
|
205
261
|
children = children.is_a?(Hash) || !children.respond_to?(:to_a) ?
|
206
|
-
[children] : children.to_a
|
262
|
+
[children] : children.to_a
|
207
263
|
end
|
208
264
|
|
209
265
|
# note the name can be nil because it can be inferred
|
@@ -217,7 +273,7 @@ module XML::Mixup
|
|
217
273
|
# now we dispatch based on the name
|
218
274
|
if name == '#comment'
|
219
275
|
# first up, comments
|
220
|
-
node = doc.create_comment
|
276
|
+
node = doc.create_comment flatten_attr(children, args).to_s
|
221
277
|
|
222
278
|
# attach it
|
223
279
|
ADJACENT[adj].call node, nodes[adj]
|
@@ -231,14 +287,14 @@ module XML::Mixup
|
|
231
287
|
content = ''
|
232
288
|
if (c = children[1..children.length]) and c.length > 0
|
233
289
|
#warn c.inspect
|
234
|
-
content =
|
290
|
+
content = flatten_attr(c, args).to_s
|
235
291
|
else
|
236
292
|
content = attr.sort.map { |pair|
|
237
|
-
v =
|
293
|
+
v = flatten_attr(pair[1], args) or next
|
238
294
|
"#{pair[0].to_s}=\"#{v}\""
|
239
295
|
}.compact.join(' ')
|
240
296
|
end
|
241
|
-
|
297
|
+
|
242
298
|
node = Nokogiri::XML::ProcessingInstruction.new(doc, target, content)
|
243
299
|
|
244
300
|
#warn node.inspect, content
|
@@ -274,14 +330,14 @@ module XML::Mixup
|
|
274
330
|
#ADJACENT[adj].call node, nodes[adj]
|
275
331
|
elsif name == '#cdata'
|
276
332
|
# let's not forget cdata sections
|
277
|
-
node = doc.create_cdata
|
333
|
+
node = doc.create_cdata flatten_attr(children, args)
|
278
334
|
# attach it
|
279
335
|
ADJACENT[adj].call node, nodes[adj]
|
280
336
|
|
281
337
|
else
|
282
338
|
# finally, an element
|
283
339
|
|
284
|
-
raise
|
340
|
+
raise "Element name inference NOT IMPLEMENTED: #{spec}" unless name
|
285
341
|
|
286
342
|
# first check the name
|
287
343
|
prefix = local = nil
|
@@ -295,7 +351,7 @@ module XML::Mixup
|
|
295
351
|
at = {}
|
296
352
|
attr.each do |k, v|
|
297
353
|
k = k.to_s
|
298
|
-
v =
|
354
|
+
v = flatten_attr(v, args) or next
|
299
355
|
if (md = /^xmlns(?::(.*))?$/i.match(k))
|
300
356
|
ns[md[1]] = v
|
301
357
|
else
|
@@ -338,7 +394,7 @@ module XML::Mixup
|
|
338
394
|
# generate the node
|
339
395
|
node = element name, doc: doc, ns: ns, attr: at, args: args
|
340
396
|
|
341
|
-
# attach it
|
397
|
+
# attach it
|
342
398
|
ADJACENT[adj].call node, nodes[adj]
|
343
399
|
|
344
400
|
# don't forget the children!
|
@@ -368,9 +424,9 @@ module XML::Mixup
|
|
368
424
|
# Generates an XHTML stub, with optional RDFa attributes. All
|
369
425
|
# parameters are optional.
|
370
426
|
#
|
371
|
-
# *This method is still under development.* I am still trying
|
372
|
-
# figure out how I want it to behave. Some parts may not work as
|
373
|
-
#
|
427
|
+
# @note *This method is still under development.* I am still trying
|
428
|
+
# to figure out how I want it to behave. Some parts may not work as
|
429
|
+
# advertised.
|
374
430
|
#
|
375
431
|
# @param doc [Nokogiri::XML::Document, nil] an optional document.
|
376
432
|
#
|
@@ -378,7 +434,7 @@ module XML::Mixup
|
|
378
434
|
#
|
379
435
|
# @param prefix [Hash] the contents of the root node's +prefix=+
|
380
436
|
# and +xmlns:*+ attributes.
|
381
|
-
#
|
437
|
+
#
|
382
438
|
# @param vocab [#to_s] the contents of the root node's +vocab=+.
|
383
439
|
#
|
384
440
|
# @param lang [#to_s] the contents of +lang=+ and when applicable,
|
@@ -428,7 +484,7 @@ module XML::Mixup
|
|
428
484
|
# namespaces. Defaults to +true+.
|
429
485
|
#
|
430
486
|
# @param args [#to_a] Arguments for any callbacks in the spec.
|
431
|
-
#
|
487
|
+
#
|
432
488
|
# @return [Nokogiri::XML::Node] the last node generated, in document order.
|
433
489
|
|
434
490
|
def xhtml_stub doc: nil, base: nil, ns: {}, prefix: {}, vocab: nil,
|
@@ -458,7 +514,7 @@ module XML::Mixup
|
|
458
514
|
elsif title.is_a? Hash
|
459
515
|
# nothing
|
460
516
|
elsif title.respond_to? :to_a
|
461
|
-
title = title.to_a
|
517
|
+
title = title.to_a.dup
|
462
518
|
text = title.shift
|
463
519
|
props = title
|
464
520
|
title = { '#title' => text }
|
@@ -478,7 +534,7 @@ module XML::Mixup
|
|
478
534
|
# construct document tree
|
479
535
|
|
480
536
|
head ||= {}
|
481
|
-
if head.is_a? Hash and head.empty?
|
537
|
+
if head.is_a? Hash and head.empty?
|
482
538
|
head[nil] = [:head, title, base, link, meta, style, script, extra]
|
483
539
|
elsif head.is_a? Array
|
484
540
|
# children of unmarked head element
|
@@ -530,55 +586,7 @@ module XML::Mixup
|
|
530
586
|
markup spec: spec, doc: doc, args: args
|
531
587
|
end
|
532
588
|
|
533
|
-
private
|
534
|
-
|
535
|
-
def element tag, doc: nil, ns: {}, attr: {}, args: []
|
536
|
-
raise 'Document node must be present' unless doc
|
537
|
-
pfx = nil
|
538
|
-
if tag.respond_to? :to_a
|
539
|
-
pfx = tag[0]
|
540
|
-
tag = tag.to_a[0..1].join ':'
|
541
|
-
elsif m = tag.match(/([^:]+):/)
|
542
|
-
pfx = m[1]
|
543
|
-
end
|
544
|
-
|
545
|
-
elem = doc.create_element tag.to_s
|
546
|
-
elem.default_namespace = ns[pfx] if ns[pfx]
|
547
|
-
|
548
|
-
ns.keys.sort { |a, b| a.to_s <=> b.to_s }.each do |p|
|
549
|
-
elem.add_namespace((p.nil? ? p : p.to_s), ns[p].to_s)
|
550
|
-
end
|
551
|
-
attr.sort.each do |k, v|
|
552
|
-
v = flatten(v, args) or next
|
553
|
-
elem[k.to_s] = v
|
554
|
-
end
|
555
|
-
|
556
|
-
elem
|
557
|
-
end
|
558
|
-
|
559
|
-
ATOMS = [String, Symbol, Numeric, FalseClass, TrueClass].freeze
|
560
|
-
|
561
|
-
# yo dawg
|
562
|
-
|
563
|
-
def flatten obj, args
|
564
|
-
return if obj.nil?
|
565
|
-
# early bailout for most likely condition
|
566
|
-
if ATOMS.any? { |x| obj.is_a? x }
|
567
|
-
obj.to_s
|
568
|
-
elsif obj.is_a? Hash
|
569
|
-
tmp = obj.sort.map do |kv|
|
570
|
-
v = flatten(kv[1], args)
|
571
|
-
v.nil? ? nil : "#{kv[0].to_s}: #{v}"
|
572
|
-
end.compact
|
573
|
-
tmp.empty? ? nil : tmp.join(' ')
|
574
|
-
elsif obj.respond_to? :call
|
575
|
-
flatten(obj.call(*args), args)
|
576
|
-
elsif obj.respond_to? :map
|
577
|
-
tmp = obj.map { |x| flatten(x, args) }.reject { |x| x.nil? || x == '' }
|
578
|
-
tmp.empty? ? nil : tmp.join(' ')
|
579
|
-
else
|
580
|
-
obj.to_s
|
581
|
-
end
|
582
|
-
end
|
583
589
|
|
590
|
+
# add class methods too
|
591
|
+
extend self
|
584
592
|
end
|
data/xml-mixup.gemspec
CHANGED
@@ -12,7 +12,7 @@ Gem::Specification.new do |spec|
|
|
12
12
|
spec.summary = %q{A mixin for (XML) markup}
|
13
13
|
spec.description = %q{XML::Mixup uses declarative data structures to incrementally generate XML.}
|
14
14
|
spec.homepage = "https://github.com/doriantaylor/rb-xml-mixup"
|
15
|
-
spec.required_ruby_version = "
|
15
|
+
spec.required_ruby_version = ">= 2.0"
|
16
16
|
|
17
17
|
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
18
18
|
f.match(%r{^(test|spec|features)/})
|
@@ -21,9 +21,9 @@ Gem::Specification.new do |spec|
|
|
21
21
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
22
22
|
spec.require_paths = ["lib"]
|
23
23
|
|
24
|
-
spec.add_development_dependency "bundler", "~> 1
|
25
|
-
spec.add_development_dependency "rake", "~>
|
26
|
-
spec.add_development_dependency "rspec", "~> 3.
|
24
|
+
spec.add_development_dependency "bundler", "~> 2.1"
|
25
|
+
spec.add_development_dependency "rake", "~> 13.0"
|
26
|
+
spec.add_development_dependency "rspec", "~> 3.9"
|
27
27
|
|
28
|
-
spec.add_dependency "nokogiri", ">= 1.
|
28
|
+
spec.add_dependency "nokogiri", ">= 1.13.6"
|
29
29
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: xml-mixup
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.16
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dorian Taylor
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-06-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -16,56 +16,56 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '1
|
19
|
+
version: '2.1'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '1
|
26
|
+
version: '2.1'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '13.0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '13.0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rspec
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '3.
|
47
|
+
version: '3.9'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '3.
|
54
|
+
version: '3.9'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: nokogiri
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: 1.
|
61
|
+
version: 1.13.6
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: 1.
|
68
|
+
version: 1.13.6
|
69
69
|
description: XML::Mixup uses declarative data structures to incrementally generate
|
70
70
|
XML.
|
71
71
|
email:
|
@@ -89,13 +89,13 @@ homepage: https://github.com/doriantaylor/rb-xml-mixup
|
|
89
89
|
licenses:
|
90
90
|
- Apache-2.0
|
91
91
|
metadata: {}
|
92
|
-
post_install_message:
|
92
|
+
post_install_message:
|
93
93
|
rdoc_options: []
|
94
94
|
require_paths:
|
95
95
|
- lib
|
96
96
|
required_ruby_version: !ruby/object:Gem::Requirement
|
97
97
|
requirements:
|
98
|
-
- - "
|
98
|
+
- - ">="
|
99
99
|
- !ruby/object:Gem::Version
|
100
100
|
version: '2.0'
|
101
101
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
@@ -104,9 +104,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
104
104
|
- !ruby/object:Gem::Version
|
105
105
|
version: '0'
|
106
106
|
requirements: []
|
107
|
-
|
108
|
-
|
109
|
-
signing_key:
|
107
|
+
rubygems_version: 3.3.11
|
108
|
+
signing_key:
|
110
109
|
specification_version: 4
|
111
110
|
summary: A mixin for (XML) markup
|
112
111
|
test_files: []
|