xml-mixup 0.1.13 → 0.1.15

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 78712630063acefe9860899c3ef4c7ec89551fe508a9fb3e588642afed153fb7
4
- data.tar.gz: 7b66b844418700e275d170424e7fc7fe91ab3645f5e0d2f063b9be589c2325a0
3
+ metadata.gz: 83154ccf54f91484833c4f3b6990bce856635bc95864eeae11edb5b791d1118c
4
+ data.tar.gz: 6cc3737aedbaf7b5c9c04dc621b003c3047b6f86c16f9ab954da4a5bb4c774d0
5
5
  SHA512:
6
- metadata.gz: 0b89a5ccf232b99adc00df21e92f047c6899c7e3e130195f2609f9e61d455f199571e5fa46cff2dbd691f2da5381d7e2f393a1a02fa2b4f67bbcdcf6f528b5a4
7
- data.tar.gz: cc3b89b5067275ae27cc496cbeb5fb451727e46ad7801a7a5dbfcd36a0e65253e813765ebce19514aa1da45dea7b6daf832abc224f834ead2e469ad70a2310e6
6
+ metadata.gz: f4591665e4d05cbe1b5d3d638f37f54d5e39a8ff79f4037814783c954cdeebb7809f4f3890f481148f4ff24c7a42d981df97b0d361965f078ba5b1f5f49876de
7
+ data.tar.gz: 7fe10c1db99f7fdf143f7fb49b20cdf68b4c157758c72cfb31cd8ba71cbbbad4647b574e3353c61ea9bd4169b2f9d8b2000c27d3b1f28a667929f8fd62f7ac56
@@ -1,5 +1,5 @@
1
1
  module XML
2
2
  module Mixup
3
- VERSION = "0.1.13"
3
+ VERSION = "0.1.15"
4
4
  end
5
5
  end
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 supplied if none given.
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 flatten(children, args).to_s
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 = flatten(c, args).to_s
289
+ content = flatten_attr(c, args).to_s
232
290
  else
233
291
  content = attr.sort.map { |pair|
234
- v = flatten(pair[1], args) or next
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 flatten(children, args)
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 'Element name inference NOT IMPLEMENTED' unless name
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 = flatten(v, args) or next
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 = "~> 2.0"
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.16"
25
- spec.add_development_dependency "rake", "~> 10.0"
26
- spec.add_development_dependency "rspec", "~> 3.0"
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.10"
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.13
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: 2019-12-12 00:00:00.000000000 Z
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.16'
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.16'
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: '10.0'
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: '10.0'
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.0'
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.0'
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.10'
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.10'
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.0.6
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: []