xml-mixup 0.1.13 → 0.1.15
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 +79 -71
- data/xml-mixup.gemspec +5 -5
- metadata +17 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 83154ccf54f91484833c4f3b6990bce856635bc95864eeae11edb5b791d1118c
|
4
|
+
data.tar.gz: 6cc3737aedbaf7b5c9c04dc621b003c3047b6f86c16f9ab954da4a5bb4c774d0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f4591665e4d05cbe1b5d3d638f37f54d5e39a8ff79f4037814783c954cdeebb7809f4f3890f481148f4ff24c7a42d981df97b0d361965f078ba5b1f5f49876de
|
7
|
+
data.tar.gz: 7fe10c1db99f7fdf143f7fb49b20cdf68b4c157758c72cfb31cd8ba71cbbbad4647b574e3353c61ea9bd4169b2f9d8b2000c27d3b1f28a667929f8fd62f7ac56
|
data/lib/xml/mixup/version.rb
CHANGED
data/lib/xml/mixup.rb
CHANGED
@@ -5,7 +5,7 @@ require 'set'
|
|
5
5
|
module XML::Mixup
|
6
6
|
# these are node attachment protocols
|
7
7
|
private
|
8
|
-
|
8
|
+
|
9
9
|
ADJACENT = {
|
10
10
|
parent: lambda do |node, parent|
|
11
11
|
if parent.node_type == 9 and node.node_type == 1
|
@@ -28,8 +28,64 @@ module XML::Mixup
|
|
28
28
|
RESERVED = Set.new(%w{comment cdata doctype dtd elem element
|
29
29
|
pi processing-instruction tag}.map {|x| "##{x}"}).freeze
|
30
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
|
+
|
31
57
|
public
|
32
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
|
+
# early bailout for most likely condition
|
69
|
+
if ATOMS.any? { |x| obj.is_a? x }
|
70
|
+
obj.to_s
|
71
|
+
elsif obj.is_a? Hash
|
72
|
+
tmp = obj.sort.map do |kv|
|
73
|
+
v = flatten_attr kv[1], args
|
74
|
+
v.nil? ? nil : "#{kv[0].to_s}: #{v}"
|
75
|
+
end.compact
|
76
|
+
tmp.empty? ? nil : tmp.join(' ')
|
77
|
+
elsif obj.respond_to? :call
|
78
|
+
flatten_attr obj.call(*args), args
|
79
|
+
elsif obj.respond_to? :map
|
80
|
+
tmp = obj.map { |x| flatten_attr x, args }.reject do |x|
|
81
|
+
x.nil? || x == ''
|
82
|
+
end
|
83
|
+
tmp.empty? ? nil : tmp.join(' ')
|
84
|
+
else
|
85
|
+
obj.to_s
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
33
89
|
# Generate a handy blank document.
|
34
90
|
#
|
35
91
|
# @param version [Numeric, nil]
|
@@ -48,6 +104,8 @@ module XML::Mixup
|
|
48
104
|
# include XML::Mixup
|
49
105
|
# end
|
50
106
|
#
|
107
|
+
# # note you can now also just call XML::Mixup.markup
|
108
|
+
#
|
51
109
|
# something = Anything.new
|
52
110
|
#
|
53
111
|
# # generate a structure
|
@@ -70,18 +128,18 @@ module XML::Mixup
|
|
70
128
|
# # case, it will be a text node containing 'lolwut'.
|
71
129
|
#
|
72
130
|
# doc = node.document
|
73
|
-
# puts doc.to_xml
|
131
|
+
# puts doc.to_xml
|
74
132
|
#
|
75
133
|
# @param spec [Hash, Array, Nokogiri::XML::Node, Proc, #to_s] An XML
|
76
134
|
# tree specification. May be composed of multiple hashes and
|
77
135
|
# arrays. See the spec spec.
|
78
|
-
#
|
136
|
+
#
|
79
137
|
# @param doc [Nokogiri::XML::Document, nil] an optional XML document
|
80
|
-
# instance; will be
|
138
|
+
# instance; will be created if none given.
|
81
139
|
#
|
82
140
|
# @param args [#to_a] Any arguments to be passed to any callbacks
|
83
141
|
# anywhere in the spec. Assumed to be an array.
|
84
|
-
#
|
142
|
+
#
|
85
143
|
# @param parent [Nokogiri::XML::Node] The node under which the
|
86
144
|
# evaluation result of the spec is to be attached. This is the
|
87
145
|
# default adjacent node, which in turn defaults to the document if
|
@@ -168,7 +226,7 @@ module XML::Mixup
|
|
168
226
|
x = x.to_a
|
169
227
|
name = x.shift
|
170
228
|
children = x
|
171
|
-
else
|
229
|
+
else
|
172
230
|
name = x
|
173
231
|
end
|
174
232
|
elsif (compact = spec.select { |k, _| k.respond_to?(:to_a) or
|
@@ -177,10 +235,10 @@ module XML::Mixup
|
|
177
235
|
raise %q{Spec can't have duplicate compact keys} if compact.count > 1
|
178
236
|
children, name = compact.first
|
179
237
|
children = children.is_a?(Hash) ||
|
180
|
-
children.is_a?(Nokogiri::XML::Node) ? [children] : children.to_a
|
238
|
+
children.is_a?(Nokogiri::XML::Node) ? [children] : children.to_a
|
181
239
|
elsif (special = spec.select { |k, _| k.respond_to? :to_s and
|
182
240
|
k.to_s.start_with? ?# }) and !special.empty?
|
183
|
-
# these are special keys
|
241
|
+
# these are special keys
|
184
242
|
raise %q{Spec can't have multiple special keys} if special.count > 1
|
185
243
|
name, children = special.first
|
186
244
|
|
@@ -200,7 +258,7 @@ module XML::Mixup
|
|
200
258
|
|
201
259
|
# don't forget to reset the child nodes
|
202
260
|
children = children.is_a?(Hash) || !children.respond_to?(:to_a) ?
|
203
|
-
[children] : children.to_a
|
261
|
+
[children] : children.to_a
|
204
262
|
end
|
205
263
|
|
206
264
|
# note the name can be nil because it can be inferred
|
@@ -214,7 +272,7 @@ module XML::Mixup
|
|
214
272
|
# now we dispatch based on the name
|
215
273
|
if name == '#comment'
|
216
274
|
# first up, comments
|
217
|
-
node = doc.create_comment
|
275
|
+
node = doc.create_comment flatten_attr(children, args).to_s
|
218
276
|
|
219
277
|
# attach it
|
220
278
|
ADJACENT[adj].call node, nodes[adj]
|
@@ -228,14 +286,14 @@ module XML::Mixup
|
|
228
286
|
content = ''
|
229
287
|
if (c = children[1..children.length]) and c.length > 0
|
230
288
|
#warn c.inspect
|
231
|
-
content =
|
289
|
+
content = flatten_attr(c, args).to_s
|
232
290
|
else
|
233
291
|
content = attr.sort.map { |pair|
|
234
|
-
v =
|
292
|
+
v = flatten_attr(pair[1], args) or next
|
235
293
|
"#{pair[0].to_s}=\"#{v}\""
|
236
294
|
}.compact.join(' ')
|
237
295
|
end
|
238
|
-
|
296
|
+
|
239
297
|
node = Nokogiri::XML::ProcessingInstruction.new(doc, target, content)
|
240
298
|
|
241
299
|
#warn node.inspect, content
|
@@ -271,14 +329,14 @@ module XML::Mixup
|
|
271
329
|
#ADJACENT[adj].call node, nodes[adj]
|
272
330
|
elsif name == '#cdata'
|
273
331
|
# let's not forget cdata sections
|
274
|
-
node = doc.create_cdata
|
332
|
+
node = doc.create_cdata flatten_attr(children, args)
|
275
333
|
# attach it
|
276
334
|
ADJACENT[adj].call node, nodes[adj]
|
277
335
|
|
278
336
|
else
|
279
337
|
# finally, an element
|
280
338
|
|
281
|
-
raise
|
339
|
+
raise "Element name inference NOT IMPLEMENTED: #{spec}" unless name
|
282
340
|
|
283
341
|
# first check the name
|
284
342
|
prefix = local = nil
|
@@ -292,7 +350,7 @@ module XML::Mixup
|
|
292
350
|
at = {}
|
293
351
|
attr.each do |k, v|
|
294
352
|
k = k.to_s
|
295
|
-
v =
|
353
|
+
v = flatten_attr(v, args) or next
|
296
354
|
if (md = /^xmlns(?::(.*))?$/i.match(k))
|
297
355
|
ns[md[1]] = v
|
298
356
|
else
|
@@ -335,7 +393,7 @@ module XML::Mixup
|
|
335
393
|
# generate the node
|
336
394
|
node = element name, doc: doc, ns: ns, attr: at, args: args
|
337
395
|
|
338
|
-
# attach it
|
396
|
+
# attach it
|
339
397
|
ADJACENT[adj].call node, nodes[adj]
|
340
398
|
|
341
399
|
# don't forget the children!
|
@@ -375,7 +433,7 @@ module XML::Mixup
|
|
375
433
|
#
|
376
434
|
# @param prefix [Hash] the contents of the root node's +prefix=+
|
377
435
|
# and +xmlns:*+ attributes.
|
378
|
-
#
|
436
|
+
#
|
379
437
|
# @param vocab [#to_s] the contents of the root node's +vocab=+.
|
380
438
|
#
|
381
439
|
# @param lang [#to_s] the contents of +lang=+ and when applicable,
|
@@ -425,7 +483,7 @@ module XML::Mixup
|
|
425
483
|
# namespaces. Defaults to +true+.
|
426
484
|
#
|
427
485
|
# @param args [#to_a] Arguments for any callbacks in the spec.
|
428
|
-
#
|
486
|
+
#
|
429
487
|
# @return [Nokogiri::XML::Node] the last node generated, in document order.
|
430
488
|
|
431
489
|
def xhtml_stub doc: nil, base: nil, ns: {}, prefix: {}, vocab: nil,
|
@@ -455,7 +513,7 @@ module XML::Mixup
|
|
455
513
|
elsif title.is_a? Hash
|
456
514
|
# nothing
|
457
515
|
elsif title.respond_to? :to_a
|
458
|
-
title = title.to_a
|
516
|
+
title = title.to_a.dup
|
459
517
|
text = title.shift
|
460
518
|
props = title
|
461
519
|
title = { '#title' => text }
|
@@ -475,7 +533,7 @@ module XML::Mixup
|
|
475
533
|
# construct document tree
|
476
534
|
|
477
535
|
head ||= {}
|
478
|
-
if head.is_a? Hash and head.empty?
|
536
|
+
if head.is_a? Hash and head.empty?
|
479
537
|
head[nil] = [:head, title, base, link, meta, style, script, extra]
|
480
538
|
elsif head.is_a? Array
|
481
539
|
# children of unmarked head element
|
@@ -527,56 +585,6 @@ module XML::Mixup
|
|
527
585
|
markup spec: spec, doc: doc, args: args
|
528
586
|
end
|
529
587
|
|
530
|
-
private
|
531
|
-
|
532
|
-
def element tag, doc: nil, ns: {}, attr: {}, args: []
|
533
|
-
raise 'Document node must be present' unless doc
|
534
|
-
pfx = nil
|
535
|
-
if tag.respond_to? :to_a
|
536
|
-
pfx = tag[0]
|
537
|
-
tag = tag.to_a[0..1].join ':'
|
538
|
-
elsif m = tag.match(/([^:]+):/)
|
539
|
-
pfx = m[1]
|
540
|
-
end
|
541
|
-
|
542
|
-
elem = doc.create_element tag.to_s
|
543
|
-
elem.default_namespace = ns[pfx] if ns[pfx]
|
544
|
-
|
545
|
-
ns.keys.sort { |a, b| a.to_s <=> b.to_s }.each do |p|
|
546
|
-
elem.add_namespace((p.nil? ? p : p.to_s), ns[p].to_s)
|
547
|
-
end
|
548
|
-
attr.sort.each do |k, v|
|
549
|
-
v = flatten(v, args) or next
|
550
|
-
elem[k.to_s] = v
|
551
|
-
end
|
552
|
-
|
553
|
-
elem
|
554
|
-
end
|
555
|
-
|
556
|
-
ATOMS = [String, Symbol, Numeric, FalseClass, TrueClass].freeze
|
557
|
-
|
558
|
-
# yo dawg
|
559
|
-
|
560
|
-
def flatten obj, args
|
561
|
-
return if obj.nil?
|
562
|
-
# early bailout for most likely condition
|
563
|
-
if ATOMS.any? { |x| obj.is_a? x }
|
564
|
-
obj.to_s
|
565
|
-
elsif obj.is_a? Hash
|
566
|
-
tmp = obj.sort.map do |kv|
|
567
|
-
v = flatten(kv[1], args)
|
568
|
-
v.nil? ? nil : "#{kv[0].to_s}: #{v}"
|
569
|
-
end.compact
|
570
|
-
tmp.empty? ? nil : tmp.join(' ')
|
571
|
-
elsif obj.respond_to? :call
|
572
|
-
flatten(obj.call(*args), args)
|
573
|
-
elsif obj.respond_to? :map
|
574
|
-
tmp = obj.map { |x| flatten(x, args) }.reject { |x| x.nil? || x == '' }
|
575
|
-
tmp.empty? ? nil : tmp.join(' ')
|
576
|
-
else
|
577
|
-
obj.to_s
|
578
|
-
end
|
579
|
-
end
|
580
588
|
|
581
589
|
# add class methods too
|
582
590
|
extend self
|
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", "
|
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.15
|
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:
|
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:
|
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,8 +104,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
104
104
|
- !ruby/object:Gem::Version
|
105
105
|
version: '0'
|
106
106
|
requirements: []
|
107
|
-
rubygems_version: 3.
|
108
|
-
signing_key:
|
107
|
+
rubygems_version: 3.3.11
|
108
|
+
signing_key:
|
109
109
|
specification_version: 4
|
110
110
|
summary: A mixin for (XML) markup
|
111
111
|
test_files: []
|