rdf-microdata 1.1.1.3 → 1.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. checksums.yaml +4 -4
  2. data/README +3 -1
  3. data/VERSION +1 -1
  4. data/lib/rdf/microdata/reader.rb +75 -43
  5. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6a7730b9619c5f5a60b80e55cef375edcae56126
4
- data.tar.gz: 6fb318efa79dbaff4378e17442c6f3d61d0e5770
3
+ metadata.gz: b6e7808ba9a859c54b20c2d1afab262c8a72f392
4
+ data.tar.gz: d8444062fdb0099f152d89285dfe568aae19cb48
5
5
  SHA512:
6
- metadata.gz: be2e3262b1b0f8dba62f70994bf18c2a25b0eee1355f265e675fadf80639a1ee8c643a1a5997d7480536699543b56d5829a4f2550ea65295723a9e0167a40fc5
7
- data.tar.gz: 3c05f6a812ba268c3bb34499c8f4fde097675a0c3acd8bb61caa4c3e7fc6b5e62669abd20d57ce7ed3dc5b1315cd70890edd5c7e845508fc6dfe3464510a4845
6
+ metadata.gz: 79400d78724736c4e8a147f7ecb042f1df956b8ace50157baab1be14a9531aa6a892546728a8085cc37b4a93e9376fbdfe3da069ecf23fd744bf6d6e9c64b97f
7
+ data.tar.gz: 2e70ab743786160758ee287450f59e21946131001663577436e38bfc2361ffd9e6146d661c06dbc9e4eeb5da8ff88bcb4339c752c3523930193e892bc39e07ba
data/README CHANGED
@@ -18,7 +18,9 @@ Install with 'gem install rdf-microdata'
18
18
 
19
19
  ### Living implementation
20
20
  Microdata to RDF transformation is undergoing active development. This implementation attempts to be up-to-date
21
- as of the time of release, and is being used in developing the [Microdata RDF][] specification
21
+ as of the time of release, and is being used in developing the [Microdata RDF][] specification.
22
+
23
+ This implementation includes support for the proposed [@itemprop-reverse](https://www.w3.org/wiki/WebSchemas/InverseProperties#Proposed_Action:_New_attribute_.40itemprop-reverse) attribute.
22
24
 
23
25
  ### Microdata Registry
24
26
  The parser uses a build-in version of the [Microdata RDF][] registry.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.1.1.3
1
+ 1.1.2
@@ -147,6 +147,7 @@ module RDF::Microdata
147
147
 
148
148
  ##
149
149
  # Determine if property should be serialized as a list or not
150
+ #
150
151
  # @param [RDF::URI] predicateURI
151
152
  # @return [Boolean]
152
153
  def as_list(predicateURI)
@@ -161,6 +162,7 @@ module RDF::Microdata
161
162
 
162
163
  ##
163
164
  # Yield a equivalentProperty or subPropertyOf if appropriate
165
+ #
164
166
  # @param [RDF::URI] predicateURI
165
167
  # @yield statement
166
168
  # @yieldparam [RDF::Statement] statement
@@ -311,10 +313,12 @@ module RDF::Microdata
311
313
  def node_path(node)
312
314
  "<#{base_uri}>#{node.respond_to?(:display_path) ? node.display_path : node}"
313
315
  end
314
-
316
+
317
+ ##
315
318
  # Add debug event to debug array, if specified
316
319
  #
317
320
  # @param [Nokogiri::XML::Node, #to_s] node XML Node or string for showing context
321
+ #
318
322
  # @param [String] message
319
323
  # @yieldreturn [String] appended to message, to allow for lazy-evaulation of message
320
324
  def add_debug(node, message = "")
@@ -329,9 +333,11 @@ module RDF::Microdata
329
333
  raise RDF::ReaderError, message if validate?
330
334
  end
331
335
 
336
+ ##
332
337
  # add a statement, object can be literal or URI or bnode
333
338
  #
334
339
  # @param [Nokogiri::XML::Node, any] node XML Node or string for showing context
340
+ #
335
341
  # @param [URI, BNode] subject the subject of the statement
336
342
  # @param [URI] predicate the predicate of the statement
337
343
  # @param [URI, BNode, Literal] object the object of the statement
@@ -367,16 +373,14 @@ module RDF::Microdata
367
373
  items = []
368
374
  # 1) For each element that is also a top-level item run the following algorithm:
369
375
  #
370
- # 1) Generate the triples for an item item, using the evaluation context.
371
- # Let result be the (URI reference or blank node) subject returned.
376
+ # 1) Generate the triples for an item item, using the evaluation context. Let result be the (URI reference or blank node) subject returned.
372
377
  # 2) Append result to item list.
373
378
  getItems.each do |el|
374
379
  result = generate_triples(el, ec)
375
380
  items << result
376
381
  end
377
382
 
378
- # 2) Generate an RDF Collection list from
379
- # the ordered list of values. Set value to the value returned from generate an RDF Collection.
383
+ # 2) Generate an RDF Collection list from the ordered list of values. Set value to the value returned from generate an RDF Collection.
380
384
  value = generateRDFCollection(root, items)
381
385
 
382
386
  # 3) Generate the following triple:
@@ -390,6 +394,7 @@ module RDF::Microdata
390
394
 
391
395
  ##
392
396
  # Generate triples for an item
397
+ #
393
398
  # @param [RDF::Resource] item
394
399
  # @param [Hash{Symbol => Object}] ec
395
400
  # @option ec [Hash{Nokogiri::XML::Element} => RDF::Resource] memory
@@ -397,9 +402,7 @@ module RDF::Microdata
397
402
  # @return [RDF::Resource]
398
403
  def generate_triples(item, ec = {})
399
404
  memory = ec[:memory]
400
- # 1) If there is an entry for item in memory, then let subject be the subject of that entry.
401
- # Otherwise, if item has a global identifier and that global identifier is an absolute URL,
402
- # let subject be that global identifier. Otherwise, let subject be a new blank node.
405
+ # 1) If there is an entry for item in memory, then let subject be the subject of that entry. Otherwise, if item has a global identifier and that global identifier is an absolute URL, let subject be that global identifier. Otherwise, let subject be a new blank node.
403
406
  subject = if memory.include?(item.node)
404
407
  memory[item.node][:subject]
405
408
  elsif item.has_attribute?('itemid')
@@ -432,8 +435,7 @@ module RDF::Microdata
432
435
  add_debug(item) {"gentrips(7): vocab=#{vocab.inspect}"}
433
436
  add_triple(item, base_uri, USES_VOCAB, RDF::URI(vocab.uri)) if vocab
434
437
 
435
- # 8) Otherwise, if type is not empty, construct vocab by removing everything following the last
436
- # SOLIDUS U+002F ("/") or NUMBER SIGN U+0023 ("#") from the path component of type.
438
+ # 8) Otherwise, if type is not empty, construct vocab by removing everything following the last SOLIDUS U+002F ("/") or NUMBER SIGN U+0023 ("#") from the path component of type.
437
439
  vocab ||= begin
438
440
  type_vocab = type.to_s.sub(/([\/\#])[^\/\#]*$/, '\1')
439
441
  add_debug(item) {"gentrips(8): type_vocab=#{type_vocab.inspect}"}
@@ -446,9 +448,7 @@ module RDF::Microdata
446
448
  # 10) Set property list to an empty mapping between properties and one or more ordered values as established below.
447
449
  property_list = {}
448
450
 
449
- # 11. For each element _element_ that has one or more property names and is one of the
450
- # properties of the item _item_, in the order those elements are given by the algorithm
451
- # that returns the properties of an item, run the following substep:
451
+ # 11. For each element _element_ that has one or more property names and is one of the properties of the item _item_, in the order those elements are given by the algorithm that returns the properties of an item, run the following substep:
452
452
  props = item_properties(item)
453
453
  # 11.1. For each name name in element's property names, run the following substeps:
454
454
  props.each do |element|
@@ -475,8 +475,7 @@ module RDF::Microdata
475
475
  value = property_value(element)
476
476
  add_debug(item) {"gentrips(11.1.3) value=#{value.inspect}"}
477
477
 
478
- # 11.1.4) If value is an item, then generate the triples for value context.
479
- # Replace value by the subject returned from those steps.
478
+ # 11.1.4) If value is an item, then generate the triples for value context. Replace value by the subject returned from those steps.
480
479
  if value.is_a?(Hash)
481
480
  value = generate_triples(element, ec_new)
482
481
  add_debug(item) {"gentrips(11.1.4): value=#{value.inspect}"}
@@ -487,7 +486,49 @@ module RDF::Microdata
487
486
  property_list[predicate] << value
488
487
  end
489
488
  end
490
-
489
+
490
+ # 11r. For each element _element_ that has one or more property names and is one of the reverse properties of the item _item_, in the order those elements are given by the algorithm that returns the properties of an item, run the following substep:
491
+ props = item_properties(item, true)
492
+ # 11r.1. For each name name in element's reverse property names, run the following substeps:
493
+ props.each do |element|
494
+ element.attribute('itemprop-reverse').to_s.split(' ').compact.each do |name|
495
+ add_debug(item) {"gentrips(11r.1): name=#{name.inspect}, type=#{type}"}
496
+ # 11r.1.1) Let context be a copy of evaluation context with current type set to type and current vocabulary set to vocab.
497
+ ec_new = ec.merge({:current_type => type, :current_vocabulary => vocab})
498
+
499
+ # 11r.1.2) Let predicate be the result of generate predicate URI using context and name. Update context by setting current name to predicate.
500
+ predicate = vocab.predicateURI(name, ec_new)
501
+
502
+ # (Generate Predicate URI steps 6 and 7)
503
+ vocab.expand(predicate) do |statement|
504
+ add_debug(item) {
505
+ "gentrips(11.1.2): expansion #{statement.inspect}"
506
+ }
507
+ @callback.call(statement)
508
+ end
509
+
510
+ ec_new[:current_name] = predicate
511
+ add_debug(item) {"gentrips(11r.1.2): predicate=#{predicate}"}
512
+
513
+ # 11r.1.3) Let value be the property value of element.
514
+ value = property_value(element)
515
+ add_debug(item) {"gentrips(11r.1.3) value=#{value.inspect}"}
516
+
517
+ # 11r.1.4) If value is an item, then generate the triples for value context. Replace value by the subject returned from those steps.
518
+ if value.is_a?(Hash)
519
+ value = generate_triples(element, ec_new)
520
+ add_debug(item) {"gentrips(11.1.4): value=#{value.inspect}"}
521
+ elsif value.is_a?(RDF::Literal)
522
+ # 11r.1.4r) Otherwise, if value is a literal, ignore the value and continue to the next name; it is an error for the value of @itemprop-reverse to be a literal
523
+ add_error(element, "Value of @itemprop-reverse may not be a literal: #{value.inspect}")
524
+ next
525
+ end
526
+
527
+ # 11r.1.5r) Generate a property value using value as the subject and subject as the object
528
+ generatePropertyValues(item, value, predicate, [subject])
529
+ end
530
+ end
531
+
491
532
  # 12) For each predicate in property list
492
533
  property_list.each do |predicate, values|
493
534
  generatePropertyValues(item, subject, predicate, values)
@@ -497,8 +538,7 @@ module RDF::Microdata
497
538
  end
498
539
 
499
540
  def generatePropertyValues(element, subject, predicate, values)
500
- # If the registry contains a URI prefix that is a character for character match of predicate up to the length
501
- # of the URI prefix, set vocab as that URI prefix. Otherwise set vocab to null
541
+ # If the registry contains a URI prefix that is a character for character match of predicate up to the length of the URI prefix, set vocab as that URI prefix. Otherwise set vocab to null
502
542
  registry = Registry.find(predicate)
503
543
  add_debug("generatePropertyValues") { "list(#{predicate})? #{registry.as_list(predicate).inspect}"} if registry
504
544
  if registry && registry.as_list(predicate)
@@ -523,17 +563,15 @@ module RDF::Microdata
523
563
  end
524
564
 
525
565
  ##
526
- # To find the properties of an item defined by the element root, the user agent must try
527
- # to crawl the properties of the element root, with an empty list as the value of memory:
528
- # if this fails, then the properties of the item defined by the element root is an empty
529
- # list; otherwise, it is the returned list.
566
+ # To find the properties of an item defined by the element root, the user agent must try to crawl the properties of the element root, with an empty list as the value of memory: if this fails, then the properties of the item defined by the element root is an empty list; otherwise, it is the returned list.
530
567
  #
531
568
  # @param [Nokogiri::XML::Element] item
569
+ # @param [Boolean] reverse (false) return reverse properties
532
570
  # @return [Array<Nokogiri::XML::Element>]
533
571
  # List of property elements for an item
534
- def item_properties(item)
535
- add_debug(item, "item_properties")
536
- results, errors = crawl_properties(item, [])
572
+ def item_properties(item, reverse = false)
573
+ add_debug(item, "item_properties (#{reverse.inspect})")
574
+ results, errors = crawl_properties(item, [], reverse)
537
575
  raise CrawlFailure, "item_props: errors=#{errors}" if errors > 0
538
576
  results
539
577
  rescue CrawlFailure => e
@@ -542,38 +580,34 @@ module RDF::Microdata
542
580
  end
543
581
 
544
582
  ##
545
- # To crawl the properties of an element root with a list memory, the user agent must run
546
- # the following steps. These steps either fail or return a list with a count of errors.
547
- # The count of errors is used as part of the authoring conformance criteria below.
583
+ # To crawl the properties of an element root with a list memory, the user agent must run the following steps. These steps either fail or return a list with a count of errors. The count of errors is used as part of the authoring conformance criteria below.
548
584
  #
549
585
  # @param [Nokogiri::XML::Element] root
550
586
  # @param [Array<Nokokogiri::XML::Element>] memory
587
+ # @param [Boolean] reverse crawl reverse properties
551
588
  # @return [Array<Array<Nokogiri::XML::Element>, Integer>]
552
589
  # Resultant elements and error count
553
- def crawl_properties(root, memory)
590
+ def crawl_properties(root, memory, reverse)
554
591
 
555
592
  # 1. If root is in memory, then the algorithm fails; abort these steps.
556
593
  raise CrawlFailure, "crawl_props mem already has #{root.inspect}" if memory.include?(root)
557
594
 
558
- # 2. Collect all the elements in the item root; let results be the resulting
559
- # list of elements, and errors be the resulting count of errors.
595
+ # 2. Collect all the elements in the item root; let results be the resulting list of elements, and errors be the resulting count of errors.
560
596
  results, errors = elements_in_item(root)
561
- add_debug(root) {"crawl_properties results=#{results.map {|e| node_path(e)}.inspect}, errors=#{errors}"}
597
+ add_debug(root) {"crawl_properties reverse=#{reverse.inspect} results=#{results.map {|e| node_path(e)}.inspect}, errors=#{errors}"}
562
598
 
563
- # 3. Remove any elements from results that do not have an itemprop attribute specified.
564
- results = results.select {|e| e.has_attribute?('itemprop')}
599
+ # 3. Remove any elements from results that do not have an @itemprop (@itemprop-reverse) attribute specified.
600
+ results = results.select {|e| e.has_attribute?(reverse ? 'itemprop-reverse' : 'itemprop')}
565
601
 
566
602
  # 4. Let new memory be a new list consisting of the old list memory with the addition of root.
567
603
  new_memory = memory + [root]
568
604
 
569
- # 5. For each element in results that has an itemscope attribute specified,
570
- # crawl the properties of the element, with new memory as the memory.
605
+ # 5. For each element in results that has an @itemscope attribute specified, crawl the properties of the element, with new memory as the memory.
571
606
  results.select {|e| e.has_attribute?('itemscope')}.each do |element|
572
607
  begin
573
- crawl_properties(element, new_memory)
608
+ crawl_properties(element, new_memory, reverse)
574
609
  rescue CrawlFailure => e
575
- # If this fails, then remove the element from results and increment errors.
576
- # (If it succeeds, the return value is discarded.)
610
+ # If this fails, then remove the element from results and increment errors. (If it succeeds, the return value is discarded.)
577
611
  memory -= element
578
612
  add_error(element, e.message)
579
613
  errors += 1
@@ -584,8 +618,7 @@ module RDF::Microdata
584
618
  end
585
619
 
586
620
  ##
587
- # To collect all the elements in the item root, the user agent must run these steps.
588
- # They return a list of elements and a count of errors.
621
+ # To collect all the elements in the item root, the user agent must run these steps. They return a list of elements and a count of errors.
589
622
  #
590
623
  # @param [Nokogiri::XML::Element] root
591
624
  # @return [Array<Array<Nokogiri::XML::Element>, Integer>]
@@ -616,8 +649,7 @@ module RDF::Microdata
616
649
  add_error(current, "elements_in_item: results already includes #{current.inspect}")
617
650
  errors += 1
618
651
  elsif !current.has_attribute?('itemscope')
619
- # If current is not already in results and current does not have an itemscope attribute,
620
- # then: add all the child elements of current to pending.
652
+ # If current is not already in results and current does not have an itemscope attribute, then: add all the child elements of current to pending.
621
653
  pending += current.elements
622
654
  end
623
655
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rdf-microdata
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.1.3
4
+ version: 1.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gregg
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-06-16 00:00:00.000000000 Z
12
+ date: 2014-08-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rdf