rdf-rdfa 0.2.2 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|