xml-mixup 0.1.12 → 0.1.16
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|