rdf-rdfa 0.2.2 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -0
- data/.yardopts +3 -1
- data/History.rdoc +52 -0
- data/README.rdoc +2 -2
- data/Rakefile +12 -17
- data/VERSION +1 -1
- data/lib/rdf/.gitignore +2 -0
- data/lib/rdf/rdfa.rb +1 -1
- data/lib/rdf/rdfa/patches/literal_hacks.rb +15 -17
- data/lib/rdf/rdfa/profile.rb +167 -0
- data/lib/rdf/rdfa/reader.rb +287 -199
- data/lib/rdf/rdfa/version.rb +4 -7
- data/lib/rdf/rdfa/vocab.rb +1 -0
- data/rdf-rdfa.gemspec +16 -125
- data/script/parse +16 -9
- data/script/tc +29 -13
- data/spec/html4-manifest.yml +491 -3855
- data/spec/html5-manifest.yml +491 -3855
- data/spec/literal_spec.rb +7 -8
- data/spec/profile_spec.rb +53 -0
- data/spec/rdfa_helper.rb +48 -47
- data/spec/rdfa_reader_spec.rb +312 -172
- data/spec/spec_helper.rb +12 -3
- data/spec/svgtiny-manifest.yml +37 -0
- data/spec/xhtml-manifest.yml +533 -2824
- metadata +19 -126
- data/History.txt +0 -30
- data/lib/rdf/rdfa/patches/uri_hacks.rb +0 -24
- data/spec/rdfa-triples/0001.nt +0 -1
- data/spec/rdfa-triples/0006.nt +0 -2
- data/spec/rdfa-triples/0007.nt +0 -3
- data/spec/rdfa-triples/0008.nt +0 -1
- data/spec/rdfa-triples/0009.nt +0 -1
- data/spec/rdfa-triples/0010.nt +0 -2
- data/spec/rdfa-triples/0011.nt +0 -3
- data/spec/rdfa-triples/0012.nt +0 -1
- data/spec/rdfa-triples/0013.nt +0 -1
- data/spec/rdfa-triples/0014.nt +0 -1
- data/spec/rdfa-triples/0015.nt +0 -2
- data/spec/rdfa-triples/0017.nt +0 -3
- data/spec/rdfa-triples/0018.nt +0 -1
- data/spec/rdfa-triples/0019.nt +0 -1
- data/spec/rdfa-triples/0020.nt +0 -1
- data/spec/rdfa-triples/0021.nt +0 -1
- data/spec/rdfa-triples/0023.nt +0 -1
- data/spec/rdfa-triples/0025.nt +0 -2
- data/spec/rdfa-triples/0026.nt +0 -1
- data/spec/rdfa-triples/0027.nt +0 -1
- data/spec/rdfa-triples/0029.nt +0 -1
- data/spec/rdfa-triples/0030.nt +0 -1
- data/spec/rdfa-triples/0031.nt +0 -1
- data/spec/rdfa-triples/0032.nt +0 -1
- data/spec/rdfa-triples/0033.nt +0 -2
- data/spec/rdfa-triples/0034.nt +0 -1
- data/spec/rdfa-triples/0035.nt +0 -1
- data/spec/rdfa-triples/0036.nt +0 -1
- data/spec/rdfa-triples/0037.nt +0 -1
- data/spec/rdfa-triples/0038.nt +0 -1
- data/spec/rdfa-triples/0039.nt +0 -1
- data/spec/rdfa-triples/0040.nt +0 -1
- data/spec/rdfa-triples/0041.nt +0 -1
- data/spec/rdfa-triples/0042.nt +0 -0
- data/spec/rdfa-triples/0046.nt +0 -3
- data/spec/rdfa-triples/0047.nt +0 -3
- data/spec/rdfa-triples/0048.nt +0 -3
- data/spec/rdfa-triples/0049.nt +0 -2
- data/spec/rdfa-triples/0050.nt +0 -2
- data/spec/rdfa-triples/0051.nt +0 -2
- data/spec/rdfa-triples/0052.nt +0 -1
- data/spec/rdfa-triples/0053.nt +0 -2
- data/spec/rdfa-triples/0054.nt +0 -2
- data/spec/rdfa-triples/0055.nt +0 -2
- data/spec/rdfa-triples/0056.nt +0 -3
- data/spec/rdfa-triples/0057.nt +0 -4
- data/spec/rdfa-triples/0058.nt +0 -6
- data/spec/rdfa-triples/0059.nt +0 -6
- data/spec/rdfa-triples/0060.nt +0 -2
- data/spec/rdfa-triples/0061.nt +0 -1
- data/spec/rdfa-triples/0062.nt +0 -1
- data/spec/rdfa-triples/0063.nt +0 -1
- data/spec/rdfa-triples/0064.nt +0 -1
- data/spec/rdfa-triples/0065.nt +0 -3
- data/spec/rdfa-triples/0066.nt +0 -1
- data/spec/rdfa-triples/0067.nt +0 -1
- data/spec/rdfa-triples/0068.nt +0 -1
- data/spec/rdfa-triples/0069.nt +0 -1
- data/spec/rdfa-triples/0070.nt +0 -1
- data/spec/rdfa-triples/0071.nt +0 -1
- data/spec/rdfa-triples/0072.nt +0 -1
- data/spec/rdfa-triples/0073.nt +0 -1
- data/spec/rdfa-triples/0074.nt +0 -1
- data/spec/rdfa-triples/0075.nt +0 -1
- data/spec/rdfa-triples/0076.nt +0 -23
- data/spec/rdfa-triples/0077.nt +0 -23
- data/spec/rdfa-triples/0078.nt +0 -6
- data/spec/rdfa-triples/0079.nt +0 -3
- data/spec/rdfa-triples/0080.nt +0 -1
- data/spec/rdfa-triples/0081.nt +0 -6
- data/spec/rdfa-triples/0082.nt +0 -8
- data/spec/rdfa-triples/0083.nt +0 -6
- data/spec/rdfa-triples/0084.nt +0 -8
- data/spec/rdfa-triples/0085.nt +0 -4
- data/spec/rdfa-triples/0086.nt +0 -0
- data/spec/rdfa-triples/0087.nt +0 -23
- data/spec/rdfa-triples/0088.nt +0 -3
- data/spec/rdfa-triples/0089.nt +0 -1
- data/spec/rdfa-triples/0090.nt +0 -1
- data/spec/rdfa-triples/0091.nt +0 -3
- data/spec/rdfa-triples/0092.nt +0 -3
- data/spec/rdfa-triples/0093.nt +0 -2
- data/spec/rdfa-triples/0094.nt +0 -3
- data/spec/rdfa-triples/0099.nt +0 -1
- data/spec/rdfa-triples/0100.nt +0 -1
- data/spec/rdfa-triples/0101.nt +0 -1
- data/spec/rdfa-triples/0102.nt +0 -1
- data/spec/rdfa-triples/0103.nt +0 -1
- data/spec/rdfa-triples/0104.nt +0 -3
- data/spec/rdfa-triples/0105.nt +0 -1
- data/spec/rdfa-triples/0106.nt +0 -1
- data/spec/rdfa-triples/0107.nt +0 -0
- data/spec/rdfa-triples/0108.nt +0 -1
- data/spec/rdfa-triples/0109.nt +0 -1
- data/spec/rdfa-triples/0110.nt +0 -1
- data/spec/rdfa-triples/0111.nt +0 -2
- data/spec/rdfa-triples/0112.nt +0 -1
- data/spec/rdfa-triples/0113.nt +0 -2
- data/spec/rdfa-triples/0114.nt +0 -3
- data/spec/rdfa-triples/0115.nt +0 -4
- data/spec/rdfa-triples/0116.nt +0 -2
- data/spec/rdfa-triples/0117.nt +0 -2
- data/spec/rdfa-triples/0118.nt +0 -1
- data/spec/rdfa-triples/0119.nt +0 -1
- data/spec/rdfa-triples/0120.nt +0 -1
- data/spec/rdfa-triples/0121.nt +0 -2
- data/spec/rdfa-triples/0122.nt +0 -1
- data/spec/rdfa-triples/0123.nt +0 -3
- data/spec/rdfa-triples/0124.nt +0 -4
- data/spec/rdfa-triples/0125.nt +0 -1
- data/spec/rdfa-triples/0126.nt +0 -3
- data/spec/rdfa-triples/1001.nt +0 -6
- data/spec/xhtml11-manifest.yml +0 -4707
data/.gitignore
CHANGED
data/.yardopts
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
--title "
|
1
|
+
--title "RDFa parser for RDF.rb."
|
2
2
|
--output-dir doc/yard
|
3
3
|
--protected
|
4
4
|
--no-private
|
@@ -6,6 +6,8 @@
|
|
6
6
|
--markup rdoc
|
7
7
|
--readme README.rdoc
|
8
8
|
-
|
9
|
+
READEME.rdoc
|
9
10
|
AUTHORS
|
11
|
+
History.rdoc
|
10
12
|
CONTRIBUTORS
|
11
13
|
VERSION
|
data/History.rdoc
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
=== 0.3.0
|
2
|
+
* RDF.rb 0.3.0 compatibility updates
|
3
|
+
* Remove literal_normalization and qname_hacks, add back uri_hacks (until 0.3.0)
|
4
|
+
* URI canonicalization and validation.
|
5
|
+
* Added :canonicalize, and :intern options.
|
6
|
+
* Change :strict option to :validate.
|
7
|
+
* Add check to ensure that predicates are not literals, it's not legal in any RDF variant.
|
8
|
+
* Collect prefixes when extracting mappings.
|
9
|
+
* Added :profile_repository option to RDF::RDFa::Reader.initialize. This MUST be an RDF::Repository and will be used to save profiles that are encountered.
|
10
|
+
* Fixme, for now, retrieval should include HTTP headers and perform appropriate HTTP cache control and check for potential updates.
|
11
|
+
* Update to 2010-10-26 LC version of RDFa Core 1.1
|
12
|
+
* Deep processing of XMLLiterals
|
13
|
+
* Case sensitive Terms
|
14
|
+
* Updated processor graph vocabulary
|
15
|
+
* Upgrade for changes to RDFa 1.1 test suite
|
16
|
+
* Allow use of xml:base for non-HTML languages
|
17
|
+
* XHTML has no default vocabulary.
|
18
|
+
* No longer pass vocabularies, prefixes or terms when creating XMLLiterals. Only namespaces derived via xmlns are passed to Literal#typed.
|
19
|
+
* Literal::XML
|
20
|
+
* Add all in-scope namespaces, not just those that seem to be used.
|
21
|
+
* RSpec 2 compatibility.
|
22
|
+
|
23
|
+
=== 0.2.2
|
24
|
+
* Ruby 1.9.2 compatibility
|
25
|
+
* Added script/parse as command-line option for parsing files.
|
26
|
+
* Add back support for RDFa 1.0 as well as RDFa 1.1. Parser checks @version to determine which
|
27
|
+
* Update RDFa processing to WD-rdfa-core-20100803 semantics
|
28
|
+
* Added Processor Graph and required output
|
29
|
+
* Reverse order of processing profiles
|
30
|
+
* Don't process element if any profile fails
|
31
|
+
* XMLLiterals must be explicitly specified as @datatype
|
32
|
+
* TERMorCURIEorAbsURI requires an absolute URI, not document relative
|
33
|
+
* Extract a new default vocabulary from @profile.
|
34
|
+
|
35
|
+
=== 0.2.1
|
36
|
+
* Update for RDF 0.2.1
|
37
|
+
|
38
|
+
=== 0.2.0
|
39
|
+
* Updates for RDF 0.2.0
|
40
|
+
* Use URI#intern instead of URI#new
|
41
|
+
* Change use of Graph#predicates and Graph#objects to use as enumerables
|
42
|
+
|
43
|
+
=== 0.0.3
|
44
|
+
* Removed internal graph in Reader and implement each_triple & each_statement to perform parsing
|
45
|
+
|
46
|
+
=== 0.0.2
|
47
|
+
* Remove dependency on Namespace
|
48
|
+
* Changed to RDF::RDFa, and moved files accordingly.
|
49
|
+
* Added vocab definitions for RDA, XHV, XML, XSI and OWL
|
50
|
+
|
51
|
+
=== 0.0.1
|
52
|
+
* First port from RdfContext version 0.5.4
|
data/README.rdoc
CHANGED
@@ -25,7 +25,7 @@ Instantiate a parser and parse source, specifying type and base-URL
|
|
25
25
|
end
|
26
26
|
|
27
27
|
== Dependencies
|
28
|
-
* [RDF.rb](http://rubygems.org/gems/rdf) (>= 0.
|
28
|
+
* [RDF.rb](http://rubygems.org/gems/rdf) (>= 0.3.0)
|
29
29
|
* [Nokogiri](http://rubygems.org/gems/nokogiri) (>= 1.3.3)
|
30
30
|
|
31
31
|
== TODO
|
@@ -37,7 +37,7 @@ Instantiate a parser and parse source, specifying type and base-URL
|
|
37
37
|
== Resources:
|
38
38
|
* RDF.rb[http://rdf.rubyforge.org/]
|
39
39
|
* Distiller[http://kellogg-assoc/distiller]
|
40
|
-
* RDoc[http://rdoc.info/
|
40
|
+
* RDoc[http://rdoc.info/github/gkellogg/rdf-rdfa]
|
41
41
|
* History[http://github.com/gkellogg/rdf-rdfa/blob/master/History.txt]
|
42
42
|
* "RDFa 1.1 Core"[http://www.w3.org/TR/2010/WD-rdfa-core-20100422/]
|
43
43
|
* "XHTML+RDFa 1.1 Core"[http://www.w3.org/TR/2010/WD-xhtml-rdfa-20100422/]
|
data/Rakefile
CHANGED
@@ -13,39 +13,32 @@ begin
|
|
13
13
|
gemspec.email = "gregg@kellogg-assoc.com"
|
14
14
|
gemspec.homepage = "http://github.com/gkellogg/rdf-rdfa"
|
15
15
|
gemspec.authors = ["Gregg Kellogg"]
|
16
|
-
gemspec.add_dependency('rdf', '>= 0.
|
16
|
+
gemspec.add_dependency('rdf', '>= 0.3.0')
|
17
17
|
gemspec.add_dependency('nokogiri', '>= 1.3.3')
|
18
|
-
gemspec.add_development_dependency('rspec')
|
18
|
+
gemspec.add_development_dependency('rspec', '>= 2.1.0')
|
19
19
|
gemspec.add_development_dependency('rdf-spec', '>= 0.2.1')
|
20
20
|
gemspec.add_development_dependency('rdf-rdfxml', '>= 0.2.1')
|
21
21
|
gemspec.add_development_dependency('rdf-isomorphic')
|
22
22
|
gemspec.add_development_dependency('yard')
|
23
|
-
gemspec.extra_rdoc_files = %w(README.rdoc History.
|
23
|
+
gemspec.extra_rdoc_files = %w(README.rdoc History.rdoc AUTHORS CONTRIBUTORS)
|
24
24
|
end
|
25
25
|
Jeweler::GemcutterTasks.new
|
26
26
|
rescue LoadError
|
27
27
|
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
28
28
|
end
|
29
29
|
|
30
|
-
require '
|
31
|
-
|
32
|
-
spec.libs << 'lib' << 'spec'
|
33
|
-
spec.spec_files = FileList['spec/*_spec.rb']
|
34
|
-
end
|
30
|
+
require 'rspec/core/rake_task'
|
31
|
+
RSpec::Core::RakeTask.new(:spec)
|
35
32
|
|
36
33
|
desc "Run specs through RCov"
|
37
|
-
|
38
|
-
spec.libs << 'lib' << 'spec'
|
39
|
-
spec.pattern = 'spec/*_spec.rb'
|
34
|
+
RSpec::Core::RakeTask.new("spec:rcov") do |spec|
|
40
35
|
spec.rcov = true
|
41
|
-
spec.rcov_opts =
|
36
|
+
spec.rcov_opts = %q[--exclude "spec"]
|
42
37
|
end
|
43
38
|
|
44
39
|
desc "Generate HTML report specs"
|
45
|
-
|
46
|
-
spec.
|
47
|
-
spec.spec_files = FileList['spec/*_spec.rb']
|
48
|
-
spec.spec_opts = ["--format", "html:doc/spec.html"]
|
40
|
+
RSpec::Core::RakeTask.new("doc:spec") do |spec|
|
41
|
+
spec.rspec_opts = ["--format", "html", "-o", "doc/spec.html"]
|
49
42
|
end
|
50
43
|
|
51
44
|
YARD::Rake::YardocTask.new do |t|
|
@@ -60,10 +53,12 @@ namespace :spec do
|
|
60
53
|
require 'spec/rdfa_helper'
|
61
54
|
require 'fileutils'
|
62
55
|
|
63
|
-
%w(xhtml
|
56
|
+
%w(xhtml html4 html5 svgtiny).each do |suite|
|
64
57
|
yaml = manifest_file = File.join(File.dirname(__FILE__), "spec", "#{suite}-manifest.yml")
|
65
58
|
FileUtils.rm_f(yaml)
|
59
|
+
#RDF::RDFa.debug = true
|
66
60
|
RdfaHelper::TestCase.to_yaml(suite, yaml)
|
61
|
+
#RDF::RDFa.debug = false
|
67
62
|
end
|
68
63
|
end
|
69
64
|
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.3.0
|
data/lib/rdf/.gitignore
ADDED
data/lib/rdf/rdfa.rb
CHANGED
@@ -27,7 +27,7 @@ module RDF
|
|
27
27
|
require 'rdf/rdfa/vocab'
|
28
28
|
require 'rdf/rdfa/patches/literal_hacks'
|
29
29
|
require 'rdf/rdfa/patches/nokogiri_hacks'
|
30
|
-
|
30
|
+
autoload :Profile, 'rdf/rdfa/profile'
|
31
31
|
autoload :Reader, 'rdf/rdfa/reader'
|
32
32
|
autoload :VERSION, 'rdf/rdfa/version'
|
33
33
|
|
@@ -20,7 +20,7 @@ module RDF; class Literal
|
|
20
20
|
##
|
21
21
|
# @param [Object] value
|
22
22
|
# @option options [String] :lexical (nil)
|
23
|
-
# @option options [Hash] :namespaces ({}) Use
|
23
|
+
# @option options [Hash] :namespaces ({}) Use "" to declare default namespace
|
24
24
|
# @option options [Symbol] :language (nil)
|
25
25
|
# @option options [:nokogiri, :libxml, or :rexml] :library
|
26
26
|
def initialize(value, options = {})
|
@@ -68,17 +68,15 @@ module RDF; class Literal
|
|
68
68
|
def parse_value(value, options)
|
69
69
|
ns_hash = {}
|
70
70
|
options[:namespaces].each_pair do |prefix, uri|
|
71
|
-
prefix = prefix
|
71
|
+
prefix = prefix.to_s
|
72
72
|
attr = prefix.empty? ? "xmlns" : "xmlns:#{prefix}"
|
73
73
|
ns_hash[attr] = uri.to_s
|
74
74
|
end
|
75
|
-
ns_strs = []
|
76
|
-
ns_hash.each_pair {|a, u| ns_strs << "#{a}=\"#{u}\""}
|
77
75
|
|
78
76
|
case @library
|
79
|
-
when :nokogiri then parse_value_nokogiri(value,
|
80
|
-
when :libxml then parse_value_libxml(value,
|
81
|
-
when :rexml then parse_value_rexml(value,
|
77
|
+
when :nokogiri then parse_value_nokogiri(value, ns_hash, options)
|
78
|
+
when :libxml then parse_value_libxml(value, ns_hash, options)
|
79
|
+
when :rexml then parse_value_rexml(value, ns_hash, options)
|
82
80
|
else value.to_s
|
83
81
|
end
|
84
82
|
end
|
@@ -99,10 +97,12 @@ module RDF; class Literal
|
|
99
97
|
# to the required element, and does not properly order either namespaces or attributes.
|
100
98
|
#
|
101
99
|
# An open-issue in Nokogiri is to add support for C14N from the underlying libxml2 libraries.
|
102
|
-
def parse_value_nokogiri(value,
|
100
|
+
def parse_value_nokogiri(value, ns_hash, options)
|
103
101
|
elements = if value.is_a?(Nokogiri::XML::NodeSet)
|
104
102
|
value
|
105
103
|
else
|
104
|
+
ns_strs = []
|
105
|
+
ns_hash.each_pair {|a, u| ns_strs << "#{a}=\"#{u}\""}
|
106
106
|
# Add inherited namespaces to created root element so that they're inherited to sub-elements
|
107
107
|
Nokogiri::XML::Document.parse("<foo #{ns_strs.join(" ")}>#{value.to_s}</foo>").root.children
|
108
108
|
end
|
@@ -110,17 +110,15 @@ module RDF; class Literal
|
|
110
110
|
elements.map do |c|
|
111
111
|
if c.is_a?(Nokogiri::XML::Element)
|
112
112
|
c = Nokogiri::XML.parse(c.dup.to_xml(:save_with => Nokogiri::XML::Node::SaveOptions::NO_EMPTY_TAGS)).root
|
113
|
-
# Gather namespaces from self and decendant nodes
|
114
|
-
c.traverse do |n|
|
115
|
-
ns = n.namespace
|
116
|
-
next unless ns
|
117
|
-
prefix = ns.prefix ? "xmlns:#{ns.prefix}" : "xmlns"
|
118
|
-
c[prefix] = ns.href.to_s unless c.namespaces[prefix]
|
119
|
-
end
|
120
113
|
|
114
|
+
# Apply defined namespaces
|
115
|
+
ns_hash.each_pair do |prefix, href|
|
116
|
+
c[prefix] = href unless c.namespaces[prefix]
|
117
|
+
end
|
118
|
+
|
121
119
|
# Add language
|
122
|
-
if language && c["lang"].to_s.empty?
|
123
|
-
c["xml:lang"] = language.to_s
|
120
|
+
if options[:language] && c["lang"].to_s.empty?
|
121
|
+
c["xml:lang"] = options[:language].to_s
|
124
122
|
end
|
125
123
|
end
|
126
124
|
c
|
@@ -0,0 +1,167 @@
|
|
1
|
+
module RDF::RDFa
|
2
|
+
##
|
3
|
+
# Profile representation existing of a hash of terms, prefixes, a default vocabulary and a URI.
|
4
|
+
#
|
5
|
+
# Profiles are used for storing RDFa profile representations. A representation is created
|
6
|
+
# by serializing a profile graph (typically also in RDFa, but may be in other representations).
|
7
|
+
#
|
8
|
+
# The class may be backed by an RDF::Repository, which will be used to retrieve a profile graph
|
9
|
+
# or to load into, if no such graph exists
|
10
|
+
class Profile
|
11
|
+
# Prefix mappings defined in this profile
|
12
|
+
# @return [Hash{Symbol => RDF::URI}]
|
13
|
+
attr_reader :prefixes
|
14
|
+
|
15
|
+
# Term mappings defined in this profile
|
16
|
+
# @return [Hash{Symbol => RDF::URI}]
|
17
|
+
attr_reader :terms
|
18
|
+
|
19
|
+
# Default URI defined for this vocabulary
|
20
|
+
# @return [RDF::URI]
|
21
|
+
attr_reader :vocabulary
|
22
|
+
|
23
|
+
# URI defining this profile
|
24
|
+
# @return [RDF::URI]
|
25
|
+
attr_reader :uri
|
26
|
+
|
27
|
+
##
|
28
|
+
# Initialize a new profile from the given URI.
|
29
|
+
#
|
30
|
+
# Parses the profile and places it in the repository and cache
|
31
|
+
#
|
32
|
+
# @param [RDF::URI, #to_s] uri URI of profile to be represented
|
33
|
+
def initialize(uri)
|
34
|
+
@uri = RDF::URI.intern(uri)
|
35
|
+
@prefixes = {}
|
36
|
+
@terms = {}
|
37
|
+
@vocabulary = nil
|
38
|
+
|
39
|
+
Profile.load(@uri)
|
40
|
+
|
41
|
+
resource_info = {}
|
42
|
+
repository.query(:context => uri).each do |statement|
|
43
|
+
res = resource_info[statement.subject] ||= {}
|
44
|
+
raise RDF::ProfileError, "#{statement.object.inspect} must be a Literal" unless statement.object.is_a?(RDF::Literal)
|
45
|
+
%w(uri term prefix vocabulary).each do |term|
|
46
|
+
res[term] ||= statement.object.value if statement.predicate == RDF::RDFA[term]
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
resource_info.values.each do |res|
|
51
|
+
# If one of the objects is not a Literal or if there are additional rdfa:uri or rdfa:term
|
52
|
+
# predicates sharing the same subject, no mapping is created.
|
53
|
+
uri = res["uri"]
|
54
|
+
term = res["term"]
|
55
|
+
prefix = res["prefix"]
|
56
|
+
vocab = res["vocabulary"]
|
57
|
+
|
58
|
+
@vocabulary = vocab if vocab
|
59
|
+
|
60
|
+
# For every extracted triple that is the common subject of an rdfa:prefix and an rdfa:uri
|
61
|
+
# predicate, create a mapping from the object literal of the rdfa:prefix predicate to the
|
62
|
+
# object literal of the rdfa:uri predicate. Add or update this mapping in the local list of
|
63
|
+
# URI mappings after transforming the 'prefix' component to lower-case.
|
64
|
+
# For every extracted
|
65
|
+
prefix(prefix.downcase, uri) if uri && prefix && prefix != "_"
|
66
|
+
|
67
|
+
# triple that is the common subject of an rdfa:term and an rdfa:uri predicate, create a
|
68
|
+
# mapping from the object literal of the rdfa:term predicate to the object literal of the
|
69
|
+
# rdfa:uri predicate. Add or update this mapping in the local term mappings.
|
70
|
+
term(term, uri) if term && uri
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
##
|
75
|
+
# @return [RDF::Util::Cache]
|
76
|
+
# @private
|
77
|
+
def self.cache
|
78
|
+
require 'rdf/util/cache' unless defined?(::RDF::Util::Cache)
|
79
|
+
@cache ||= RDF::Util::Cache.new(-1)
|
80
|
+
end
|
81
|
+
|
82
|
+
##
|
83
|
+
# Repository used for saving profiles
|
84
|
+
# @return [RDF::Repository]
|
85
|
+
# @raise [RDF::RDFa::ProfileError] if profile does not support contexts
|
86
|
+
def self.repository
|
87
|
+
@repository ||= RDF::Repository.new(:title => "RDFa Profiles")
|
88
|
+
end
|
89
|
+
|
90
|
+
##
|
91
|
+
# Set repository used for saving profiles
|
92
|
+
# @param [RDF::Repository] repo
|
93
|
+
# @return [RDF::Repository]
|
94
|
+
def self.repository=(repo)
|
95
|
+
raise ProfileError, "Profile Repository must support context" unless repo.supports?(:context)
|
96
|
+
@repository = repo
|
97
|
+
end
|
98
|
+
|
99
|
+
# Return a profile faulting through the cache
|
100
|
+
# @return [RDF::RDFa::Profile]
|
101
|
+
def self.find(uri)
|
102
|
+
uri = RDF::URI.intern(uri)
|
103
|
+
|
104
|
+
cache[uri] ||= new(uri)
|
105
|
+
end
|
106
|
+
|
107
|
+
# Load profile into repository
|
108
|
+
def self.load(uri)
|
109
|
+
uri = RDF::URI.intern(uri)
|
110
|
+
repository.load(uri.to_s, :base_uri => uri, :context => uri) unless repository.has_context?(uri)
|
111
|
+
end
|
112
|
+
|
113
|
+
# @return [RDF::Repository]
|
114
|
+
def repository
|
115
|
+
Profile.repository
|
116
|
+
end
|
117
|
+
|
118
|
+
##
|
119
|
+
# Defines the given named URI prefix for this profile.
|
120
|
+
#
|
121
|
+
# @example Defining a URI prefix
|
122
|
+
# profile.prefix :dc, RDF::URI('http://purl.org/dc/terms/')
|
123
|
+
#
|
124
|
+
# @example Returning a URI prefix
|
125
|
+
# profile.prefix(:dc) #=> RDF::URI('http://purl.org/dc/terms/')
|
126
|
+
#
|
127
|
+
# @overload prefix(name, uri)
|
128
|
+
# @param [Symbol, #to_s] name
|
129
|
+
# @param [RDF::URI, #to_s] uri
|
130
|
+
#
|
131
|
+
# @overload prefix(name)
|
132
|
+
# @param [Symbol, #to_s] name
|
133
|
+
#
|
134
|
+
# @return [RDF::URI]
|
135
|
+
def prefix(name, uri = nil)
|
136
|
+
name = name.to_s.empty? ? nil : (name.respond_to?(:to_sym) ? name.to_sym : name.to_s.to_sym)
|
137
|
+
uri.nil? ? prefixes[name] : prefixes[name] = uri
|
138
|
+
end
|
139
|
+
|
140
|
+
##
|
141
|
+
# Defines the given named URI term for this profile.
|
142
|
+
#
|
143
|
+
# @example Defining a URI term
|
144
|
+
# profile.term :title, RDF::URI('http://purl.org/dc/terms/title')
|
145
|
+
#
|
146
|
+
# @example Returning a URI profile
|
147
|
+
# profile.term(:title) #=> RDF::URI('http://purl.org/dc/terms/TITLE')
|
148
|
+
#
|
149
|
+
# @overload term(name, uri)
|
150
|
+
# @param [Symbol, #to_s] name
|
151
|
+
# @param [RDF::URI, #to_s] uri
|
152
|
+
#
|
153
|
+
# @overload term(name)
|
154
|
+
# @param [Symbol, #to_s] name
|
155
|
+
#
|
156
|
+
# @return [RDF::URI]
|
157
|
+
def term(name, uri = nil)
|
158
|
+
name = name.to_s.empty? ? nil : (name.respond_to?(:to_sym) ? name.to_sym : name.to_s.to_sym)
|
159
|
+
uri.nil? ? terms[name] : terms[name] = uri
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
##
|
164
|
+
# The base class for RDF profile errors.
|
165
|
+
class ProfileError < IOError
|
166
|
+
end # ProfileError
|
167
|
+
end
|
data/lib/rdf/rdfa/reader.rb
CHANGED
@@ -6,7 +6,7 @@ module RDF::RDFa
|
|
6
6
|
#
|
7
7
|
# Based on processing rules described here:
|
8
8
|
# @see http://www.w3.org/TR/rdfa-syntax/#s_model RDFa 1.0
|
9
|
-
# @see http://www.w3.org/2010/02/rdfa/drafts/2010/
|
9
|
+
# @see http://www.w3.org/2010/02/rdfa/drafts/2010/WD-rdfa-core-20101026/ RDFa 1.1
|
10
10
|
#
|
11
11
|
# @author [Gregg Kellogg](http://kellogg-assoc.com/)
|
12
12
|
class Reader < RDF::Reader
|
@@ -39,9 +39,13 @@ module RDF::RDFa
|
|
39
39
|
Regexp::EXTENDED)
|
40
40
|
|
41
41
|
# Host language
|
42
|
-
# @return [:xhtml]
|
42
|
+
# @return [:xhtml, :svg]
|
43
43
|
attr_reader :host_language
|
44
44
|
|
45
|
+
# Version
|
46
|
+
# @return [:rdfa_1_0, :rdfa_1_1]
|
47
|
+
attr_reader :version
|
48
|
+
|
45
49
|
# The Recursive Baggage
|
46
50
|
# @private
|
47
51
|
class EvaluationContext # :nodoc:
|
@@ -76,6 +80,11 @@ module RDF::RDFa
|
|
76
80
|
#
|
77
81
|
# @return [Hash{Symbol => String}]
|
78
82
|
attr :uri_mappings, true
|
83
|
+
# A list of current, in-scope Namespaces. This is the subset of uri_mappings
|
84
|
+
# which are defined using xmlns.
|
85
|
+
#
|
86
|
+
# @return [Hash{String => Namespace}]
|
87
|
+
attr :namespaces, true
|
79
88
|
# A list of incomplete triples.
|
80
89
|
#
|
81
90
|
# A triple can be incomplete when no object resource
|
@@ -115,6 +124,7 @@ module RDF::RDFa
|
|
115
124
|
@base = base
|
116
125
|
@parent_subject = @base
|
117
126
|
@parent_object = nil
|
127
|
+
@namespaces = {}
|
118
128
|
@incomplete_triples = []
|
119
129
|
@language = nil
|
120
130
|
@uri_mappings = host_defaults.fetch(:uri_mappings, {})
|
@@ -129,6 +139,7 @@ module RDF::RDFa
|
|
129
139
|
# clone the evaluation context correctly
|
130
140
|
@uri_mappings = from.uri_mappings.clone
|
131
141
|
@incomplete_triples = from.incomplete_triples.clone
|
142
|
+
@namespaces = from.namespaces.clone
|
132
143
|
end
|
133
144
|
|
134
145
|
def inspect
|
@@ -143,26 +154,44 @@ module RDF::RDFa
|
|
143
154
|
##
|
144
155
|
# Initializes the RDFa reader instance.
|
145
156
|
#
|
146
|
-
# @param [Nokogiri::HTML::Document, Nokogiri::XML::Document,
|
147
|
-
#
|
148
|
-
# @
|
149
|
-
#
|
150
|
-
# @option options [
|
151
|
-
#
|
152
|
-
# @option options [
|
157
|
+
# @param [Nokogiri::HTML::Document, Nokogiri::XML::Document, IO, File, String] input
|
158
|
+
# the input stream to read
|
159
|
+
# @param [Hash{Symbol => Object}] options
|
160
|
+
# any additional options
|
161
|
+
# @option options [Encoding] :encoding (Encoding::UTF_8)
|
162
|
+
# the encoding of the input stream (Ruby 1.9+)
|
163
|
+
# @option options [Boolean] :validate (false)
|
164
|
+
# whether to validate the parsed statements and values
|
165
|
+
# @option options [Boolean] :canonicalize (false)
|
166
|
+
# whether to canonicalize parsed literals
|
167
|
+
# @option options [Boolean] :intern (true)
|
168
|
+
# whether to intern all parsed URIs
|
169
|
+
# @option options [Hash] :prefixes (Hash.new)
|
170
|
+
# the prefix mappings to use (not supported by all readers)
|
171
|
+
# @option options [#to_s] :base_uri (nil)
|
172
|
+
# the base URI to use when resolving relative URIs
|
173
|
+
# @option options [:xhtml] :host_language (:xhtml)
|
174
|
+
# Host Language
|
175
|
+
# @option options [:rdfa_1_0, :rdfa_1_1] :version (:rdfa_1_1)
|
176
|
+
# Parser version information
|
177
|
+
# @option options [Graph] :processor_graph (nil)
|
178
|
+
# Graph to record information, warnings and errors.
|
179
|
+
# @option options [Repository] :profile_repository (nil)
|
180
|
+
# Repository to save profile graphs.
|
181
|
+
# @option options [Array] :debug
|
182
|
+
# Array to place debug messages
|
153
183
|
# @return [reader]
|
154
|
-
# @yield [reader]
|
155
|
-
# @yieldparam
|
156
|
-
# @
|
184
|
+
# @yield [reader] `self`
|
185
|
+
# @yieldparam [RDF::Reader] reader
|
186
|
+
# @yieldreturn [void] ignored
|
187
|
+
# @raise [Error]:: Raises RDF::ReaderError if _validate_
|
157
188
|
def initialize(input = $stdin, options = {}, &block)
|
158
189
|
super do
|
159
190
|
@debug = options[:debug]
|
160
|
-
@
|
161
|
-
@base_uri = RDF::URI.intern(options[:base_uri])
|
162
|
-
@@vocabulary_cache ||= {}
|
191
|
+
@base_uri = uri(options[:base_uri])
|
163
192
|
|
164
193
|
@version = options[:version] ? options[:version].to_sym : :rdfa_1_1
|
165
|
-
@
|
194
|
+
@processor_graph = options[:processor_graph]
|
166
195
|
|
167
196
|
@doc = case input
|
168
197
|
when Nokogiri::HTML::Document then input
|
@@ -170,13 +199,32 @@ module RDF::RDFa
|
|
170
199
|
else Nokogiri::XML.parse(input, @base_uri.to_s)
|
171
200
|
end
|
172
201
|
|
173
|
-
|
174
|
-
|
202
|
+
@host_language = options[:host_language] || case @doc.root.name.downcase.to_sym
|
203
|
+
when :html then :xhtml
|
204
|
+
when :svg then :svg
|
205
|
+
else :xhtml
|
206
|
+
end
|
207
|
+
|
208
|
+
add_error(nil, "Empty document", RDF::RDFA.DocumentError) if (@doc.nil? || @doc.root.nil?)
|
209
|
+
add_warning(nil, "Synax errors:\n#{@doc.errors}", RDF::RDFA.DocumentError) if !@doc.errors.empty? && validate?
|
210
|
+
add_error("Empty document") if (@doc.nil? || @doc.root.nil?) && validate?
|
175
211
|
|
176
212
|
block.call(self) if block_given?
|
177
213
|
end
|
214
|
+
self.profile_repository = options[:profile_repository] if options[:profile_repository]
|
178
215
|
end
|
179
216
|
|
217
|
+
# @return [RDF::Repository]
|
218
|
+
def profile_repository
|
219
|
+
Profile.repository
|
220
|
+
end
|
221
|
+
|
222
|
+
# @param [RDF::Repository] repo
|
223
|
+
# @return [RDF::Repository]
|
224
|
+
def profile_repository=(repo)
|
225
|
+
Profile.repository = repo
|
226
|
+
end
|
227
|
+
|
180
228
|
##
|
181
229
|
# Iterates the given block for each RDF statement in the input.
|
182
230
|
#
|
@@ -194,20 +242,25 @@ module RDF::RDFa
|
|
194
242
|
@host_defaults = case @host_language
|
195
243
|
when :xhtml
|
196
244
|
{
|
197
|
-
:vocabulary =>
|
245
|
+
:vocabulary => nil,
|
198
246
|
:prefix => "xhv",
|
199
247
|
:uri_mappings => {"xhv" => RDF::XHV.to_s}, # RDF::XHTML is wrong
|
200
248
|
:term_mappings => %w(
|
201
249
|
alternate appendix bookmark cite chapter contents copyright first glossary help icon index
|
202
250
|
last license meta next p3pv1 prev role section stylesheet subsection start top up
|
203
|
-
).inject({}) { |hash, term| hash[term] = RDF::XHV[term]; hash },
|
251
|
+
).inject({}) { |hash, term| hash[term.to_sym] = RDF::XHV[term].to_s; hash },
|
204
252
|
}
|
205
253
|
else
|
206
|
-
{
|
254
|
+
{
|
255
|
+
:uri_mappings => {},
|
256
|
+
}
|
207
257
|
end
|
208
258
|
|
209
|
-
|
210
|
-
|
259
|
+
# Add prefix definitions from host defaults
|
260
|
+
@host_defaults[:uri_mappings].each_pair do |prefix, value|
|
261
|
+
prefix(prefix, value)
|
262
|
+
end
|
263
|
+
|
211
264
|
add_debug(@doc, "version = #{@version}, host_language = #{@host_language}")
|
212
265
|
|
213
266
|
# parse
|
@@ -249,35 +302,39 @@ module RDF::RDFa
|
|
249
302
|
# @param [XML Node, any] node:: XML Node or string for showing context
|
250
303
|
# @param [String] message::
|
251
304
|
def add_debug(node, message)
|
252
|
-
add_processor_message(node, message, RDF::RDFA.
|
305
|
+
add_processor_message(node, message, RDF::RDFA.Info)
|
253
306
|
end
|
254
307
|
|
255
|
-
def add_info(node, message, process_class = RDF::RDFA.
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
308
|
+
def add_info(node, message, process_class = RDF::RDFA.Info)
|
309
|
+
add_processor_message(node, message, process_class)
|
310
|
+
end
|
311
|
+
|
312
|
+
def add_warning(node, message, process_class = RDF::RDFA.Warning)
|
313
|
+
add_processor_message(node, message, process_class)
|
314
|
+
end
|
315
|
+
|
316
|
+
def add_error(node, message, process_class = RDF::RDFA.Error)
|
317
|
+
add_processor_message(node, message, process_class)
|
318
|
+
raise RDF::ReaderError, message if validate?
|
319
|
+
end
|
320
|
+
|
321
|
+
def add_processor_message(node, message, process_class)
|
322
|
+
puts "#{node_path(node)}: #{message}" if ::RDF::RDFa::debug?
|
323
|
+
@debug << "#{node_path(node)}: #{message}" if @debug.is_a?(Array)
|
324
|
+
if @processor_graph
|
325
|
+
@processor_sequence ||= 0
|
326
|
+
n = RDF::Node.new
|
327
|
+
@processor_graph << RDF::Statement.new(n, RDF["type"], process_class)
|
328
|
+
@processor_graph << RDF::Statement.new(n, RDF::DC.description, message)
|
329
|
+
@processor_graph << RDF::Statement.new(n, RDF::DC.date, RDF::Literal::Date.new(DateTime.now))
|
330
|
+
@processor_graph << RDF::Statement.new(n, RDF::RDFA.sequence, RDF::Literal::Integer.new(@processor_sequence += 1))
|
331
|
+
@processor_graph << RDF::Statement.new(n, RDF::RDFA.context, @base_uri)
|
332
|
+
nc = RDF::Node.new
|
333
|
+
@processor_graph << RDF::Statement.new(nc, RDF["type"], RDF::PTR.XPathPointer)
|
334
|
+
@processor_graph << RDF::Statement.new(nc, RDF::PTR.expression, node.path)
|
335
|
+
@processor_graph << RDF::Statement.new(n, RDF::RDFA.context, nc)
|
336
|
+
end
|
337
|
+
end
|
281
338
|
|
282
339
|
# add a statement, object can be literal or URI or bnode
|
283
340
|
#
|
@@ -286,10 +343,10 @@ module RDF::RDFa
|
|
286
343
|
# @param [URI] predicate:: the predicate of the statement
|
287
344
|
# @param [URI, BNode, Literal] object:: the object of the statement
|
288
345
|
# @return [Statement]:: Added statement
|
289
|
-
# @raise [ReaderError]:: Checks parameter types and raises if they are incorrect if parsing mode is
|
346
|
+
# @raise [ReaderError]:: Checks parameter types and raises if they are incorrect if parsing mode is _validate_.
|
290
347
|
def add_triple(node, subject, predicate, object)
|
291
348
|
statement = RDF::Statement.new(subject, predicate, object)
|
292
|
-
add_debug(node, "statement: #{statement
|
349
|
+
add_debug(node, "statement: #{RDF::NTriples.serialize(statement)}")
|
293
350
|
@callback.call(statement)
|
294
351
|
end
|
295
352
|
|
@@ -297,93 +354,55 @@ module RDF::RDFa
|
|
297
354
|
# Parsing an RDFa document (this is *not* the recursive method)
|
298
355
|
def parse_whole_document(doc, base)
|
299
356
|
# find if the document has a base element
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
base = base_el.
|
357
|
+
case @host_language
|
358
|
+
when :xhtml
|
359
|
+
base_el = doc.at_css("html>head>base")
|
360
|
+
base = base_el.attribute("href").to_s.split("#").first if base_el
|
361
|
+
end
|
362
|
+
|
363
|
+
if (base)
|
304
364
|
# Strip any fragment from base
|
305
365
|
base = base.to_s.split("#").first
|
306
|
-
|
307
|
-
add_debug(
|
366
|
+
base = uri(base)
|
367
|
+
add_debug("", "parse_whole_doc: base='#{base}'")
|
308
368
|
end
|
309
369
|
|
310
370
|
# initialize the evaluation context with the appropriate base
|
311
|
-
evaluation_context = EvaluationContext.new(
|
312
|
-
|
371
|
+
evaluation_context = EvaluationContext.new(base, @host_defaults)
|
372
|
+
|
313
373
|
traverse(doc.root, evaluation_context)
|
314
374
|
end
|
315
375
|
|
316
376
|
# Parse and process URI mappings, Term mappings and a default vocabulary from @profile
|
317
377
|
#
|
318
378
|
# Yields each mapping
|
319
|
-
def process_profile(element)
|
320
|
-
|
379
|
+
def process_profile(element, profiles)
|
380
|
+
profiles.
|
381
|
+
reverse.
|
382
|
+
map {|uri| uri(uri).normalize}.
|
383
|
+
each do |uri|
|
321
384
|
# Don't try to open ourselves!
|
322
|
-
if @
|
323
|
-
add_debug(element, "process_profile: skip recursive profile <#{
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
:default_vocabulary => nil
|
332
|
-
}
|
333
|
-
um = @@vocabulary_cache[profile][:uri_mappings]
|
334
|
-
tm = @@vocabulary_cache[profile][:term_mappings]
|
335
|
-
add_debug(element, "process_profile: parse profile <#{profile}>")
|
336
|
-
|
337
|
-
# Parse profile, and extract mappings from graph
|
338
|
-
old_debug, old_verbose, = ::RDF::RDFa::debug?, $verbose
|
339
|
-
::RDF::RDFa::debug, $verbose = false, false
|
340
|
-
# Fixme, RDF isn't smart enough to figure this out from MIME-Type
|
341
|
-
load_opts = {:base_uri => profile}
|
342
|
-
load_opts[:format] = :rdfa unless RDF::Format.for(:file_name => profile)
|
343
|
-
p_graph = RDF::Graph.load(profile, load_opts)
|
344
|
-
::RDF::RDFa::debug, $verbose = old_debug, old_verbose
|
345
|
-
p_graph.subjects.each do |subject|
|
346
|
-
# If one of the objects is not a Literal or if there are additional rdfa:uri or rdfa:term
|
347
|
-
# predicates sharing the same subject, no mapping is created.
|
348
|
-
uri = p_graph.first_object([subject, RDF::RDFA['uri'], nil])
|
349
|
-
term = p_graph.first_object([subject, RDF::RDFA['term'], nil])
|
350
|
-
prefix = p_graph.first_object([subject, RDF::RDFA['prefix'], nil])
|
351
|
-
vocab = p_graph.first_object([subject, RDF::RDFA['vocabulary'], nil])
|
352
|
-
add_debug(element, "process_profile: uri=#{uri.inspect}, term=#{term.inspect}, prefix=#{prefix.inspect}, vocabulary=#{vocab.inspect}")
|
353
|
-
|
354
|
-
raise RDF::ReaderError, "rdf:uri #{uri.inspect} must be a Literal" unless uri.nil? || uri.is_a?(RDF::Literal)
|
355
|
-
raise RDF::ReaderError, "rdf:term #{term.inspect} must be a Literal" unless term.nil? || term.is_a?(RDF::Literal)
|
356
|
-
raise RDF::ReaderError, "rdf:prefix #{prefix.inspect} must be a Literal" unless prefix.nil? || prefix.is_a?(RDF::Literal)
|
357
|
-
raise RDF::ReaderError, "rdf:vocabulary #{vocab.inspect} must be a Literal" unless vocab.nil? || vocab.is_a?(RDF::Literal)
|
358
|
-
|
359
|
-
@@vocabulary_cache[profile][:default_vocabulary] = vocab.value if vocab
|
360
|
-
|
361
|
-
# For every extracted triple that is the common subject of an rdfa:prefix and an rdfa:uri
|
362
|
-
# predicate, create a mapping from the object literal of the rdfa:prefix predicate to the
|
363
|
-
# object literal of the rdfa:uri predicate. Add or update this mapping in the local list of
|
364
|
-
# URI mappings after transforming the 'prefix' component to lower-case.
|
365
|
-
# For every extracted
|
366
|
-
um[prefix.value.downcase] = uri.value if prefix && prefix.value != "_"
|
367
|
-
|
368
|
-
# triple that is the common subject of an rdfa:term and an rdfa:uri predicate, create a
|
369
|
-
# mapping from the object literal of the rdfa:term predicate to the object literal of the
|
370
|
-
# rdfa:uri predicate. Add or update this mapping in the local term mappings.
|
371
|
-
tm[term.value.downcase] = RDF::URI.intern(uri.value) if term
|
372
|
-
end
|
373
|
-
rescue RDF::ReaderError => e
|
374
|
-
add_error(element, e.message, RDF::RDFA.ProfileReferenceError)
|
375
|
-
raise # Incase we're not in strict mode, we need to be sure processing stops
|
376
|
-
end
|
385
|
+
if @base_uri == uri
|
386
|
+
add_debug(element, "process_profile: skip recursive profile <#{uri}>")
|
387
|
+
next
|
388
|
+
end
|
389
|
+
|
390
|
+
next unless profile = Profile.find(uri)
|
391
|
+
# Add URI Mappings to prefixes
|
392
|
+
profile.prefixes.each_pair do |prefix, value|
|
393
|
+
prefix(prefix, value)
|
377
394
|
end
|
378
|
-
|
379
|
-
yield :
|
380
|
-
yield :
|
381
|
-
yield :default_vocabulary, profile_mappings[:default_vocabulary] if profile_mappings[:default_vocabulary]
|
395
|
+
yield :uri_mappings, profile.prefixes unless profile.prefixes.empty?
|
396
|
+
yield :term_mappings, profile.terms unless profile.terms.empty?
|
397
|
+
yield :default_vocabulary, profile.vocabulary if profile.vocabulary
|
382
398
|
end
|
399
|
+
rescue Exception => e
|
400
|
+
add_error(element, e.message, RDF::RDFA.ProfileReferenceError)
|
401
|
+
raise # In case we're not in strict mode, we need to be sure processing stops
|
383
402
|
end
|
384
403
|
|
385
404
|
# Extract the XMLNS mappings from an element
|
386
|
-
def extract_mappings(element, uri_mappings,
|
405
|
+
def extract_mappings(element, uri_mappings, namespaces)
|
387
406
|
# look for xmlns
|
388
407
|
# (note, this may be dependent on @host_language)
|
389
408
|
# Regardless of how the mapping is declared, the value to be mapped must be converted to lower case,
|
@@ -396,8 +415,12 @@ module RDF::RDFa
|
|
396
415
|
# Downcase prefix for RDFa 1.1
|
397
416
|
pfx_lc = (@version == :rdfa_1_0 || ns.prefix.nil?) ? ns.prefix : ns.prefix.to_s.downcase
|
398
417
|
if ns.prefix
|
399
|
-
uri_mappings[pfx_lc] = ns.href
|
418
|
+
uri_mappings[pfx_lc.to_sym] = ns.href
|
419
|
+
namespaces[pfx_lc] ||= ns.href
|
420
|
+
prefix(pfx_lc, ns.href)
|
400
421
|
add_debug(element, "extract_mappings: xmlns:#{ns.prefix} => <#{ns.href}>")
|
422
|
+
else
|
423
|
+
namespaces[""] ||= ns.href
|
401
424
|
end
|
402
425
|
end
|
403
426
|
|
@@ -414,7 +437,8 @@ module RDF::RDFa
|
|
414
437
|
# A Conforming RDFa Processor must ignore any definition of a mapping for the '_' prefix.
|
415
438
|
next if prefix == "_"
|
416
439
|
|
417
|
-
uri_mappings[prefix] = uri
|
440
|
+
uri_mappings[prefix.to_s.empty? ? nil : prefix.to_s.to_sym] = uri
|
441
|
+
prefix(prefix, uri)
|
418
442
|
add_debug(element, "extract_mappings: prefix #{prefix} => <#{uri}>")
|
419
443
|
end unless @version == :rdfa_1_0
|
420
444
|
end
|
@@ -423,7 +447,7 @@ module RDF::RDFa
|
|
423
447
|
def traverse(element, evaluation_context)
|
424
448
|
if element.nil?
|
425
449
|
add_debug(element, "traverse nil element")
|
426
|
-
raise RDF::ReaderError, "Can't parse nil element" if
|
450
|
+
raise RDF::ReaderError, "Can't parse nil element" if validate?
|
427
451
|
return nil
|
428
452
|
end
|
429
453
|
|
@@ -435,6 +459,7 @@ module RDF::RDFa
|
|
435
459
|
new_subject = nil
|
436
460
|
current_object_resource = nil
|
437
461
|
uri_mappings = evaluation_context.uri_mappings.clone
|
462
|
+
namespaces = evaluation_context.namespaces.clone
|
438
463
|
incomplete_triples = []
|
439
464
|
language = evaluation_context.language
|
440
465
|
term_mappings = evaluation_context.term_mappings.clone
|
@@ -450,6 +475,9 @@ module RDF::RDFa
|
|
450
475
|
resource = attrs['resource']
|
451
476
|
href = attrs['href']
|
452
477
|
vocab = attrs['vocab']
|
478
|
+
xml_base = element.attribute_with_ns("base", RDF::XML.to_s)
|
479
|
+
base = xml_base.to_s if xml_base && @host_language != :xhtml
|
480
|
+
base ||= evaluation_context.base
|
453
481
|
|
454
482
|
# Pull out the attributes needed for the skip test.
|
455
483
|
property = attrs['property'].to_s.strip if attrs['property']
|
@@ -458,13 +486,31 @@ module RDF::RDFa
|
|
458
486
|
content = attrs['content'].to_s if attrs['content']
|
459
487
|
rel = attrs['rel'].to_s.strip if attrs['rel']
|
460
488
|
rev = attrs['rev'].to_s.strip if attrs['rev']
|
489
|
+
profiles = attrs['profile'].to_s.split(/\s/) # In-scope profiles in order for passing to XMLLiteral
|
490
|
+
|
491
|
+
attrs = {
|
492
|
+
:about => about,
|
493
|
+
:src => src,
|
494
|
+
:resource => resource,
|
495
|
+
:href => href,
|
496
|
+
:vocab => vocab,
|
497
|
+
:base => xml_base,
|
498
|
+
:property => property,
|
499
|
+
:typeof => typeof,
|
500
|
+
:daetatype => datatype,
|
501
|
+
:rel => rel,
|
502
|
+
:rev => rev,
|
503
|
+
:profiles => (profiles.empty? ? nil : profiles),
|
504
|
+
}.select{|k,v| v}
|
505
|
+
|
506
|
+
add_debug(element, "traverse " + attrs.map{|a| "#{a.first}: #{a.last}"}.join(", ")) unless attrs.empty?
|
461
507
|
|
462
508
|
# Local term mappings [7.5 Steps 2]
|
463
509
|
# Next the current element is parsed for any updates to the local term mappings and local list of URI mappings via @profile.
|
464
510
|
# If @profile is present, its value is processed as defined in RDFa Profiles.
|
465
511
|
unless @version == :rdfa_1_0
|
466
512
|
begin
|
467
|
-
process_profile(element) do |which, value|
|
513
|
+
process_profile(element, profiles) do |which, value|
|
468
514
|
add_debug(element, "[Step 2] traverse, #{which}: #{value.inspect}")
|
469
515
|
case which
|
470
516
|
when :uri_mappings then uri_mappings.merge!(value)
|
@@ -476,7 +522,7 @@ module RDF::RDFa
|
|
476
522
|
# Skip this element and all sub-elements
|
477
523
|
# If any referenced RDFa Profile is not available, then the current element and its children must not place any
|
478
524
|
# triples in the default graph .
|
479
|
-
raise if
|
525
|
+
raise if validate?
|
480
526
|
return
|
481
527
|
end
|
482
528
|
end
|
@@ -491,7 +537,7 @@ module RDF::RDFa
|
|
491
537
|
add_debug(element, "[Step 2] traverse, reset default_vocaulary to #{@host_defaults.fetch(:vocabulary, nil).inspect}")
|
492
538
|
@host_defaults.fetch(:vocabulary, nil)
|
493
539
|
else
|
494
|
-
|
540
|
+
uri(vocab)
|
495
541
|
end
|
496
542
|
add_debug(element, "[Step 2] traverse, default_vocaulary: #{default_vocabulary.inspect}")
|
497
543
|
end
|
@@ -499,7 +545,7 @@ module RDF::RDFa
|
|
499
545
|
# Local term mappings [7.5 Steps 4]
|
500
546
|
# Next, the current element is then examined for URI mapping s and these are added to the local list of URI mappings.
|
501
547
|
# Note that a URI mapping will simply overwrite any current mapping in the list that has the same name
|
502
|
-
extract_mappings(element, uri_mappings,
|
548
|
+
extract_mappings(element, uri_mappings, namespaces)
|
503
549
|
|
504
550
|
# Language information [7.5 Step 5]
|
505
551
|
# From HTML5 [3.2.3.3]
|
@@ -516,39 +562,37 @@ module RDF::RDFa
|
|
516
562
|
language
|
517
563
|
end
|
518
564
|
language = nil if language.to_s.empty?
|
519
|
-
add_debug(element, "HTML5 [3.2.3.3] traverse, lang: #{language || 'nil'}") if
|
565
|
+
add_debug(element, "HTML5 [3.2.3.3] traverse, lang: #{language || 'nil'}") if language
|
520
566
|
|
521
567
|
# rels and revs
|
522
|
-
rels = process_uris(element, rel, evaluation_context,
|
568
|
+
rels = process_uris(element, rel, evaluation_context, base,
|
523
569
|
:uri_mappings => uri_mappings,
|
524
570
|
:term_mappings => term_mappings,
|
525
571
|
:vocab => default_vocabulary,
|
526
572
|
:restrictions => TERMorCURIEorAbsURI[@version])
|
527
|
-
revs = process_uris(element, rev, evaluation_context,
|
573
|
+
revs = process_uris(element, rev, evaluation_context, base,
|
528
574
|
:uri_mappings => uri_mappings,
|
529
575
|
:term_mappings => term_mappings,
|
530
576
|
:vocab => default_vocabulary,
|
531
577
|
:restrictions => TERMorCURIEorAbsURI[@version])
|
532
578
|
|
533
|
-
add_debug(element, "traverse,
|
534
|
-
add_debug(element, "traverse, property: #{property.nil? ? 'nil' : property}, typeof: #{typeof.nil? ? 'nil' : typeof}, datatype: #{datatype.nil? ? 'nil' : datatype}, content: #{content.nil? ? 'nil' : content}")
|
535
|
-
add_debug(element, "traverse, rels: #{rels.join(" ")}, revs: #{revs.join(" ")}")
|
579
|
+
add_debug(element, "traverse, rels: #{rels.join(" ")}, revs: #{revs.join(" ")}") unless (rels + revs).empty?
|
536
580
|
|
537
581
|
if !(rel || rev)
|
538
582
|
# Establishing a new subject if no rel/rev [7.5 Step 6]
|
539
583
|
# May not be valid, but can exist
|
540
584
|
new_subject = if about
|
541
|
-
process_uri(element, about, evaluation_context,
|
585
|
+
process_uri(element, about, evaluation_context, base,
|
542
586
|
:uri_mappings => uri_mappings,
|
543
587
|
:restrictions => SafeCURIEorCURIEorURI[@version])
|
544
588
|
elsif src
|
545
|
-
process_uri(element, src, evaluation_context, :restrictions => [:uri])
|
589
|
+
process_uri(element, src, evaluation_context, base, :restrictions => [:uri])
|
546
590
|
elsif resource
|
547
|
-
process_uri(element, resource, evaluation_context,
|
591
|
+
process_uri(element, resource, evaluation_context, base,
|
548
592
|
:uri_mappings => uri_mappings,
|
549
593
|
:restrictions => SafeCURIEorCURIEorURI[@version])
|
550
594
|
elsif href
|
551
|
-
process_uri(element, href, evaluation_context, :restrictions => [:uri])
|
595
|
+
process_uri(element, href, evaluation_context, base, :restrictions => [:uri])
|
552
596
|
end
|
553
597
|
|
554
598
|
# If no URI is provided by a resource attribute, then the first match from the following rules
|
@@ -557,11 +601,14 @@ module RDF::RDFa
|
|
557
601
|
# otherwise,
|
558
602
|
# if parent object is present, new subject is set to the value of parent object.
|
559
603
|
# Additionally, if @property is not present then the skip element flag is set to 'true';
|
560
|
-
new_subject ||= if @host_language == :xhtml && element.name =~ /^(head|body)$/ &&
|
604
|
+
new_subject ||= if @host_language == :xhtml && element.name =~ /^(head|body)$/ && base
|
561
605
|
# From XHTML+RDFa 1.1:
|
562
606
|
# if no URI is provided, then first check to see if the element is the head or body element.
|
563
607
|
# If it is, then act as if there is an empty @about present, and process it according to the rule for @about.
|
564
|
-
|
608
|
+
uri(base)
|
609
|
+
elsif @host_language != :xhtml && base
|
610
|
+
# XXX Spec confusion, assume that this is true
|
611
|
+
uri(base)
|
565
612
|
elsif element.attributes['typeof']
|
566
613
|
RDF::Node.new
|
567
614
|
else
|
@@ -574,10 +621,10 @@ module RDF::RDFa
|
|
574
621
|
# [7.5 Step 7]
|
575
622
|
# If the current element does contain a @rel or @rev attribute, then the next step is to
|
576
623
|
# establish both a value for new subject and a value for current object resource:
|
577
|
-
new_subject = process_uri(element, about, evaluation_context,
|
624
|
+
new_subject = process_uri(element, about, evaluation_context, base,
|
578
625
|
:uri_mappings => uri_mappings,
|
579
626
|
:restrictions => SafeCURIEorCURIEorURI[@version]) ||
|
580
|
-
process_uri(element, src, evaluation_context,
|
627
|
+
process_uri(element, src, evaluation_context, base,
|
581
628
|
:uri_mappings => uri_mappings,
|
582
629
|
:restrictions => [:uri])
|
583
630
|
|
@@ -586,7 +633,7 @@ module RDF::RDFa
|
|
586
633
|
# From XHTML+RDFa 1.1:
|
587
634
|
# if no URI is provided, then first check to see if the element is the head or body element.
|
588
635
|
# If it is, then act as if there is an empty @about present, and process it according to the rule for @about.
|
589
|
-
|
636
|
+
uri(base)
|
590
637
|
elsif element.attributes['typeof']
|
591
638
|
RDF::Node.new
|
592
639
|
else
|
@@ -597,11 +644,11 @@ module RDF::RDFa
|
|
597
644
|
|
598
645
|
# Then the current object resource is set to the URI obtained from the first match from the following rules:
|
599
646
|
current_object_resource = if resource
|
600
|
-
process_uri(element, resource, evaluation_context,
|
647
|
+
process_uri(element, resource, evaluation_context, base,
|
601
648
|
:uri_mappings => uri_mappings,
|
602
649
|
:restrictions => SafeCURIEorCURIEorURI[@version])
|
603
650
|
elsif href
|
604
|
-
process_uri(element, href, evaluation_context,
|
651
|
+
process_uri(element, href, evaluation_context, base,
|
605
652
|
:restrictions => [:uri])
|
606
653
|
end
|
607
654
|
|
@@ -611,7 +658,7 @@ module RDF::RDFa
|
|
611
658
|
# Process @typeof if there is a subject [Step 8]
|
612
659
|
if new_subject and typeof
|
613
660
|
# Typeof is TERMorCURIEorAbsURIs
|
614
|
-
types = process_uris(element, typeof, evaluation_context,
|
661
|
+
types = process_uris(element, typeof, evaluation_context, base,
|
615
662
|
:uri_mappings => uri_mappings,
|
616
663
|
:term_mappings => term_mappings,
|
617
664
|
:vocab => default_vocabulary,
|
@@ -647,7 +694,7 @@ module RDF::RDFa
|
|
647
694
|
|
648
695
|
# Establish current object literal [Step 11]
|
649
696
|
if property
|
650
|
-
properties = process_uris(element, property, evaluation_context,
|
697
|
+
properties = process_uris(element, property, evaluation_context, base,
|
651
698
|
:uri_mappings => uri_mappings,
|
652
699
|
:term_mappings => term_mappings,
|
653
700
|
:vocab => default_vocabulary,
|
@@ -658,7 +705,7 @@ module RDF::RDFa
|
|
658
705
|
false
|
659
706
|
else
|
660
707
|
add_debug(element, "Illegal predicate: #{p.inspect}")
|
661
|
-
raise RDF::ReaderError, "predicate #{p.inspect} must be a URI" if
|
708
|
+
raise RDF::ReaderError, "predicate #{p.inspect} must be a URI" if validate?
|
662
709
|
true
|
663
710
|
end
|
664
711
|
end
|
@@ -667,45 +714,67 @@ module RDF::RDFa
|
|
667
714
|
children_node_types = element.children.collect{|c| c.class}.uniq
|
668
715
|
|
669
716
|
# the following 3 IF clauses should be mutually exclusive. Written as is to prevent extensive indentation.
|
670
|
-
datatype = process_uri(element, datatype, evaluation_context,
|
717
|
+
datatype = process_uri(element, datatype, evaluation_context, base,
|
671
718
|
:uri_mappings => uri_mappings,
|
672
719
|
:term_mappings => term_mappings,
|
673
720
|
:vocab => default_vocabulary,
|
674
721
|
:restrictions => TERMorCURIEorAbsURI[@version]) unless datatype.to_s.empty?
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
|
722
|
+
begin
|
723
|
+
current_object_literal = if !datatype.to_s.empty? && datatype.to_s != RDF.XMLLiteral.to_s
|
724
|
+
# typed literal
|
725
|
+
add_debug(element, "[Step 11] typed literal (#{datatype})")
|
726
|
+
RDF::Literal.new(content || element.inner_text.to_s, :datatype => datatype, :language => language, :validate => validate?, :canonicalize => canonicalize?)
|
727
|
+
elsif @version == :rdfa_1_1
|
728
|
+
if datatype.to_s == RDF.XMLLiteral.to_s
|
729
|
+
# XML Literal
|
730
|
+
add_debug(element, "[Step 11(1.1)] XML Literal: #{element.inner_html}")
|
731
|
+
|
732
|
+
# In order to maintain maximum portability of this literal, any children of the current node that are
|
733
|
+
# elements must have the current in scope XML namespace declarations (if any) declared on the
|
734
|
+
# serialized element using their respective attributes. Since the child element node could also
|
735
|
+
# declare new XML namespaces, the RDFa Processor must be careful to merge these together when
|
736
|
+
# generating the serialized element definition. For avoidance of doubt, any re-declarations on the
|
737
|
+
# child node must take precedence over declarations that were active on the current node.
|
738
|
+
begin
|
739
|
+
RDF::Literal.new(element.inner_html,
|
740
|
+
:datatype => RDF.XMLLiteral,
|
741
|
+
:language => language,
|
742
|
+
:namespaces => namespaces,
|
743
|
+
:validate => validate?,
|
744
|
+
:canonicalize => canonicalize?)
|
745
|
+
rescue ArgumentError => e
|
746
|
+
add_error(element, e.message)
|
747
|
+
end
|
748
|
+
else
|
749
|
+
# plain literal
|
750
|
+
add_debug(element, "[Step 11(1.1)] plain literal")
|
751
|
+
RDF::Literal.new(content || element.inner_text.to_s, :language => language, :validate => validate?, :canonicalize => canonicalize?)
|
752
|
+
end
|
685
753
|
else
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
|
754
|
+
if content || (children_node_types == [Nokogiri::XML::Text]) || (element.children.length == 0) || datatype == ""
|
755
|
+
# plain literal
|
756
|
+
add_debug(element, "[Step 11 (1.0)] plain literal")
|
757
|
+
RDF::Literal.new(content || element.inner_text.to_s, :language => language, :validate => validate?, :canonicalize => canonicalize?)
|
758
|
+
elsif children_node_types != [Nokogiri::XML::Text] and (datatype == nil or datatype.to_s == RDF.XMLLiteral.to_s)
|
759
|
+
# XML Literal
|
760
|
+
add_debug(element, "[Step 11 (1.0)] XML Literal: #{element.inner_html}")
|
761
|
+
recurse = false
|
762
|
+
RDF::Literal.new(element.inner_html,
|
763
|
+
:datatype => RDF.XMLLiteral,
|
764
|
+
:language => language,
|
765
|
+
:namespaces => namespaces,
|
766
|
+
:validate => validate?,
|
767
|
+
:canonicalize => canonicalize?)
|
768
|
+
end
|
700
769
|
end
|
770
|
+
rescue ArgumentError => e
|
771
|
+
add_error(element, e.message)
|
701
772
|
end
|
702
773
|
|
703
774
|
# add each property
|
704
775
|
properties.each do |p|
|
705
776
|
add_triple(element, new_subject, p, current_object_literal)
|
706
777
|
end
|
707
|
-
# SPEC CONFUSION: "the triple has been created" ==> there may be more than one
|
708
|
-
# set the recurse flag above in the IF about xmlliteral, as it is the only place that can happen
|
709
778
|
end
|
710
779
|
|
711
780
|
if not skip and new_subject && !evaluation_context.incomplete_triples.empty?
|
@@ -727,22 +796,26 @@ module RDF::RDFa
|
|
727
796
|
uri_mappings == evaluation_context.uri_mappings &&
|
728
797
|
term_mappings == evaluation_context.term_mappings &&
|
729
798
|
default_vocabulary == evaluation_context.default_vocabulary &&
|
799
|
+
base == evaluation_context.base
|
730
800
|
new_ec = evaluation_context
|
731
801
|
add_debug(element, "[Step 13] skip: reused ec")
|
732
802
|
else
|
733
803
|
new_ec = evaluation_context.clone
|
804
|
+
new_ec.base = base
|
734
805
|
new_ec.language = language
|
735
806
|
new_ec.uri_mappings = uri_mappings
|
807
|
+
new_ec.namespaces = namespaces
|
736
808
|
new_ec.term_mappings = term_mappings
|
737
809
|
new_ec.default_vocabulary = default_vocabulary
|
738
810
|
add_debug(element, "[Step 13] skip: cloned ec")
|
739
811
|
end
|
740
812
|
else
|
741
813
|
# create a new evaluation context
|
742
|
-
new_ec = EvaluationContext.new(
|
814
|
+
new_ec = EvaluationContext.new(base, @host_defaults)
|
743
815
|
new_ec.parent_subject = new_subject || evaluation_context.parent_subject
|
744
816
|
new_ec.parent_object = current_object_resource || new_subject || evaluation_context.parent_subject
|
745
817
|
new_ec.uri_mappings = uri_mappings
|
818
|
+
new_ec.namespaces = namespaces
|
746
819
|
new_ec.incomplete_triples = incomplete_triples
|
747
820
|
new_ec.language = language
|
748
821
|
new_ec.term_mappings = term_mappings
|
@@ -758,13 +831,13 @@ module RDF::RDFa
|
|
758
831
|
end
|
759
832
|
|
760
833
|
# space-separated TERMorCURIEorAbsURI or SafeCURIEorCURIEorURI
|
761
|
-
def process_uris(element, value, evaluation_context, options)
|
834
|
+
def process_uris(element, value, evaluation_context, base, options)
|
762
835
|
return [] if value.to_s.empty?
|
763
836
|
add_debug(element, "process_uris: #{value}")
|
764
|
-
value.to_s.split(/\s+/).map {|v| process_uri(element, v, evaluation_context, options)}.compact
|
837
|
+
value.to_s.split(/\s+/).map {|v| process_uri(element, v, evaluation_context, base, options)}.compact
|
765
838
|
end
|
766
839
|
|
767
|
-
def process_uri(element, value, evaluation_context, options = {})
|
840
|
+
def process_uri(element, value, evaluation_context, base, options = {})
|
768
841
|
return if value.nil?
|
769
842
|
restrictions = options[:restrictions]
|
770
843
|
add_debug(element, "process_uri: #{value}, restrictions = #{restrictions.inspect}")
|
@@ -797,20 +870,20 @@ module RDF::RDFa
|
|
797
870
|
begin
|
798
871
|
# AbsURI does not use xml:base
|
799
872
|
if restrictions.include?(:absuri)
|
800
|
-
uri =
|
873
|
+
uri = uri(value)
|
801
874
|
unless uri.absolute?
|
802
875
|
uri = nil
|
803
876
|
raise RDF::ReaderError, "Relative URI #{value}"
|
804
877
|
end
|
805
878
|
else
|
806
|
-
uri =
|
879
|
+
uri = uri(base, Addressable::URI.parse(value))
|
807
880
|
end
|
808
881
|
rescue Addressable::URI::InvalidURIError => e
|
809
|
-
add_warning(element, "Malformed prefix #{value}", RDF::RDFA.
|
882
|
+
add_warning(element, "Malformed prefix #{value}", RDF::RDFA.UnresolvedCURIE)
|
810
883
|
rescue RDF::ReaderError => e
|
811
884
|
add_debug(element, e.message)
|
812
885
|
if value.to_s =~ /^\(^\w\):/
|
813
|
-
add_warning(element, "Undefined prefix #{$1}", RDF::RDFA.
|
886
|
+
add_warning(element, "Undefined prefix #{$1}", RDF::RDFA.UnresolvedCURIE)
|
814
887
|
else
|
815
888
|
add_warning(element, "Relative URI #{value}")
|
816
889
|
end
|
@@ -828,17 +901,22 @@ module RDF::RDFa
|
|
828
901
|
# <em>options[:term_mappings]</em>:: Term mappings
|
829
902
|
# <em>options[:vocab]</em>:: Default vocabulary
|
830
903
|
def process_term(element, value, options)
|
831
|
-
|
832
|
-
|
833
|
-
|
834
|
-
|
835
|
-
|
836
|
-
|
904
|
+
if options[:term_mappings].is_a?(Hash)
|
905
|
+
# If the term is in the local term mappings, use the associated URI (case sensitive).
|
906
|
+
return uri(options[:term_mappings][value.to_s.to_sym]) if options[:term_mappings].has_key?(value.to_s.to_sym)
|
907
|
+
|
908
|
+
# Otherwise, check for case-insensitive match
|
909
|
+
options[:term_mappings].each_pair do |term, uri|
|
910
|
+
return uri(uri) if term.to_s.downcase == value.to_s.downcase
|
911
|
+
end
|
912
|
+
end
|
913
|
+
|
914
|
+
if options[:vocab]
|
837
915
|
# Otherwise, if there is a local default vocabulary the URI is obtained by concatenating that value and the term.
|
838
|
-
|
916
|
+
uri(options[:vocab] + value)
|
839
917
|
else
|
840
918
|
# Finally, if there is no local default vocabulary, the term has no associated URI and must be ignored.
|
841
|
-
add_warning(element, "Term #{value} is not defined", RDF::RDFA.
|
919
|
+
add_warning(element, "Term #{value} is not defined", RDF::RDFA.UnresolvedTerm)
|
842
920
|
nil
|
843
921
|
end
|
844
922
|
end
|
@@ -856,12 +934,12 @@ module RDF::RDFa
|
|
856
934
|
elsif curie.to_s.match(/^:/)
|
857
935
|
add_debug(element, "curie_to_resource_or_bnode: default prefix: defined? #{!!uri_mappings[""]}, defaults: #{@host_defaults[:prefix]}")
|
858
936
|
# Default prefix
|
859
|
-
if uri_mappings[
|
860
|
-
|
937
|
+
if uri_mappings[nil]
|
938
|
+
uri(uri_mappings[nil] + reference.to_s)
|
861
939
|
elsif @host_defaults[:prefix]
|
862
|
-
|
940
|
+
uri(uri_mappings[@host_defaults[:prefix]] + reference.to_s)
|
863
941
|
else
|
864
|
-
#add_warning(element, "Default namespace prefix is not defined", RDF::RDFA.
|
942
|
+
#add_warning(element, "Default namespace prefix is not defined", RDF::RDFA.UnresolvedCURIE)
|
865
943
|
nil
|
866
944
|
end
|
867
945
|
elsif !curie.to_s.match(/:/)
|
@@ -870,14 +948,24 @@ module RDF::RDFa
|
|
870
948
|
else
|
871
949
|
# Prefixes always downcased
|
872
950
|
prefix = prefix.to_s.downcase unless @version == :rdfa_1_0
|
873
|
-
|
951
|
+
add_debug(element, "curie_to_resource_or_bnode check for #{prefix.to_s.to_sym.inspect} in #{uri_mappings.inspect}")
|
952
|
+
ns = uri_mappings[prefix.to_s.to_sym]
|
874
953
|
if ns
|
875
|
-
|
954
|
+
uri(ns + reference.to_s)
|
876
955
|
else
|
877
|
-
|
956
|
+
add_debug(element, "curie_to_resource_or_bnode No namespace mapping for #{prefix}")
|
878
957
|
nil
|
879
958
|
end
|
880
959
|
end
|
881
960
|
end
|
961
|
+
|
962
|
+
def uri(value, append = nil)
|
963
|
+
value = RDF::URI.new(value)
|
964
|
+
value = value.join(append) if append
|
965
|
+
value.validate! if validate?
|
966
|
+
value.canonicalize! if canonicalize?
|
967
|
+
value = RDF::URI.intern(value) if intern?
|
968
|
+
value
|
969
|
+
end
|
882
970
|
end
|
883
971
|
end
|