rdf-rdfa 0.3.1.2 → 0.3.3
Sign up to get free protection for your applications and to get access to all the features.
- data/.yardopts +2 -1
- data/Gemfile +18 -0
- data/History.md +14 -1
- data/README +291 -0
- data/README.md +236 -36
- data/Rakefile +7 -27
- data/UNLICENSE +24 -0
- data/VERSION +1 -1
- data/etc/basic.html +1 -1
- data/etc/profile.html +40 -0
- data/example-files/payswarm.html +449 -0
- data/example-files/payswarm.n3 +86 -0
- data/lib/rdf/rdfa.rb +5 -0
- data/lib/rdf/rdfa/format.rb +8 -4
- data/lib/rdf/rdfa/patches/graph_properties.rb +34 -0
- data/lib/rdf/rdfa/patches/nokogiri_hacks.rb +6 -0
- data/lib/rdf/rdfa/patches/string_hacks.rb +9 -0
- data/lib/rdf/rdfa/profile.rb +65 -41
- data/lib/rdf/rdfa/profile/xhtml.rb +36 -0
- data/lib/rdf/rdfa/profile/xml.rb +45 -0
- data/lib/rdf/rdfa/reader.rb +168 -92
- data/lib/rdf/rdfa/writer.rb +822 -0
- data/lib/rdf/rdfa/writer/haml_templates.rb +306 -0
- data/rdf-rdfa.gemspec +77 -23
- data/script/intern_vocabulary +83 -0
- data/script/parse +62 -27
- data/script/tc +87 -37
- data/spec/.gitignore +1 -0
- data/spec/matchers.rb +89 -154
- data/spec/profile_spec.rb +36 -21
- data/spec/{rdfa_reader_spec.rb → reader_spec.rb} +86 -159
- data/spec/spec_helper.rb +6 -29
- data/spec/test_helper.rb +97 -0
- data/spec/writer_spec.rb +385 -0
- metadata +203 -37
- data/spec/html4-manifest.yml +0 -1749
- data/spec/html5-manifest.yml +0 -1749
- data/spec/rdfa_helper.rb +0 -257
- data/spec/svgtiny-manifest.yml +0 -37
- data/spec/xhtml-manifest.yml +0 -1749
@@ -0,0 +1,86 @@
|
|
1
|
+
@base <http://recipes.payswarm.com/?p=10185> .
|
2
|
+
@prefix bibo: <http://purl.org/ontology/bibo/> .
|
3
|
+
@prefix cal: <http://www.w3.org/2002/12/cal/ical#> .
|
4
|
+
@prefix cc: <http://creativecommons.org/ns#> .
|
5
|
+
@prefix com: <http://purl.org/commerce#> .
|
6
|
+
@prefix dbp: <http://dbpedia.org/property/> .
|
7
|
+
@prefix dbp-owl: <http://dbpedia.org/ontology/> .
|
8
|
+
@prefix dbr: <http://dbpedia.org/resource/> .
|
9
|
+
@prefix dc: <http://purl.org/dc/terms/> .
|
10
|
+
@prefix dcterms: <http://purl.org/dc/terms/> .
|
11
|
+
@prefix doap: <http://usefulinc.com/ns/doap#> .
|
12
|
+
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
|
13
|
+
@prefix geo: <http://www.w3.org/2003/01/geo/wgs84_pos#> .
|
14
|
+
@prefix gr: <http://purl.org/goodrelations/v1#> .
|
15
|
+
@prefix grddl: <http://www.w3.org/2003/g/data-view#> .
|
16
|
+
@prefix og: <http://ogp.me/ns#> .
|
17
|
+
@prefix owl: <http://www.w3.org/2002/07/owl#> .
|
18
|
+
@prefix ps: <http://purl.org/payswarm#> .
|
19
|
+
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
|
20
|
+
@prefix rdfa: <http://www.w3.org/ns/rdfa#> .
|
21
|
+
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
|
22
|
+
@prefix rif: <http://www.w3.org/2007/rif#> .
|
23
|
+
@prefix rss: <http://purl.org/rss/1.0/> .
|
24
|
+
@prefix sd: <http://www.w3.org/ns/sparql-service-description#> .
|
25
|
+
@prefix sig: <http://purl.org/signature#> .
|
26
|
+
@prefix sioc: <http://rdfs.org/sioc/ns#> .
|
27
|
+
@prefix skos: <http://www.w3.org/2004/02/skos/core#> .
|
28
|
+
@prefix skosxl: <http://www.w3.org/2008/05/skos-xl#> .
|
29
|
+
@prefix v: <http://rdf.data-vocabulary.org/#> .
|
30
|
+
@prefix vcard: <http://www.w3.org/2006/vcard/ns#> .
|
31
|
+
@prefix void: <http://rdfs.org/ns/void#> .
|
32
|
+
@prefix wdr: <http://www.w3.org/2007/05/powder#> .
|
33
|
+
@prefix wdrs: <http://www.w3.org/2007/05/powder-s#> .
|
34
|
+
@prefix xhv: <http://www.w3.org/1999/xhtml/vocab#> .
|
35
|
+
@prefix xml: <http://www.w3.org/XML/1998/namespace> .
|
36
|
+
@prefix xmlns: <http://www.w3.org/2000/xmlns/> .
|
37
|
+
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
|
38
|
+
|
39
|
+
<#listing> com:payee <#listing-payee>;
|
40
|
+
com:payeeRule [ com:destinationOwnerType ps:Authority;
|
41
|
+
com:maximumRate "11.45"@en-US;
|
42
|
+
com:rateContext com:Inclusive,
|
43
|
+
com:Tax,
|
44
|
+
com:TaxExempt;
|
45
|
+
com:rateType com:Percentage;
|
46
|
+
a com:PayeeRule];
|
47
|
+
ps:asset <#asset>;
|
48
|
+
ps:assetHash "025b9b9f1eea31a9431f0c181a22df8a8257fc49"@en-US;
|
49
|
+
ps:license <http://purl.org/payswarm/licenses/blogging>;
|
50
|
+
ps:licenseHash "b94ba441c42432e82b6e3a076f4c614f83cac6ef"@en-US;
|
51
|
+
ps:validFrom "2011-04-18T00:00:00+0000"^^xsd:dateTime;
|
52
|
+
ps:validUntil "2011-04-19T00:00:00+0000"^^xsd:dateTime;
|
53
|
+
sig:signature [ dc:created "2011-04-18T00:00:00Z"^^xsd:dateTime;
|
54
|
+
dc:creator <https://payswarm.com/i/devuser/keys/4>;
|
55
|
+
sig:signatureValue "MqF1r37JSev+2uUKdr1ZOWVfNbTx8YdBZUMW4hlgeQyIiYxfbHF+eYhU+NLFrclTjj3i7qnwREIIBP0O0BFk72JIBl3JcCDKpfbA7pqiFuaGvxr9+Ba7o0pYojo0A6Mc/+0UD5rjdJc+qAH9hnMOzKpjyeMxUcR1Z6w0XXKXc8A="@en-US;
|
56
|
+
a sig:JsonldSignature];
|
57
|
+
a gr:Offering,
|
58
|
+
ps:Listing .
|
59
|
+
<> xhv:alternate <https://recipes.payswarm.com/?feed=comments-rss2>,
|
60
|
+
<https://recipes.payswarm.com/?feed=rss2>,
|
61
|
+
<https://recipes.payswarm.com/?feed=rss2&p=10185>;
|
62
|
+
xhv:bookmark <https://recipes.payswarm.com/?p=10185>;
|
63
|
+
xhv:index <https://recipes.payswarm.com>;
|
64
|
+
xhv:next <https://recipes.payswarm.com/?p=10186>;
|
65
|
+
xhv:prev <https://recipes.payswarm.com/?p=10184>;
|
66
|
+
xhv:start <https://recipes.payswarm.com/?p=1>;
|
67
|
+
xhv:stylesheet <https://recipes.payswarm.com/wp-content/plugins/payswarm/payswarm.css?ver=3.1>,
|
68
|
+
<https://recipes.payswarm.com/wp-content/themes/twentyten/style.css> .
|
69
|
+
<#asset> dc:creator [ foaf:name "chef"@en-US];
|
70
|
+
dc:title "Soft Breadsticks"@en-US;
|
71
|
+
ps:assetProvider <https://dev.payswarm.com:19100/i/devuser>;
|
72
|
+
ps:authority <https://payswarm.dev:19100/client-config>;
|
73
|
+
ps:contentUrl <>;
|
74
|
+
sig:signature [ dc:created "2011-04-18T00:00:00Z"^^xsd:dateTime;
|
75
|
+
dc:creator <https://payswarm.com/i/devuser/keys/4>;
|
76
|
+
sig:signatureValue "GYQHOxTJeyfky4NkxTm/IEcVGKYq7omDXPwdX+CYlJD9ur6RX35jM/RS3SeB7teGlJs1KtAx+l4ZUsAZa4sINYkr9fKh0k0K7TCbXp2X5sJ4ZCE3AvxZfc4IQEMuiiq+C8LHJv6g6tVmdl25UIbfroEBd/Hv+ID995VgapsSmQo="@en-US;
|
77
|
+
a sig:JsonldSignature];
|
78
|
+
a ps:Asset,
|
79
|
+
ps:WebPage .
|
80
|
+
<#listing-payee> com:currency "USD"@en-US;
|
81
|
+
com:destination <https://dev.payswarm.com:19100/i/devuser/accounts/primary>;
|
82
|
+
com:payeePosition "0"^^xsd:integer;
|
83
|
+
com:rate "0.04597"@en-US;
|
84
|
+
com:rateType com:FlatAmount;
|
85
|
+
a com:Payee;
|
86
|
+
rdfs:comment "Payment for Soft Breadsticks by chef."@en-US .
|
data/lib/rdf/rdfa.rb
CHANGED
@@ -27,10 +27,15 @@ 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
|
+
require 'rdf/rdfa/patches/string_hacks'
|
30
31
|
autoload :Profile, 'rdf/rdfa/profile'
|
31
32
|
autoload :Reader, 'rdf/rdfa/reader'
|
33
|
+
autoload :Writer, 'rdf/rdfa/writer'
|
32
34
|
autoload :VERSION, 'rdf/rdfa/version'
|
33
35
|
|
36
|
+
XML_RDFA_PROFILE = "http://www.w3.org/profile/rdfa-1.1"
|
37
|
+
XHTML_RDFA_PROFILE = "http://www.w3.org/profile/html-rdfa-1.1"
|
38
|
+
|
34
39
|
def self.debug?; @debug; end
|
35
40
|
def self.debug=(value); @debug = value; end
|
36
41
|
end
|
data/lib/rdf/rdfa/format.rb
CHANGED
@@ -18,12 +18,10 @@ module RDF::RDFa
|
|
18
18
|
#
|
19
19
|
# @see http://www.w3.org/TR/rdf-testcases/#ntriples
|
20
20
|
class Format < RDF::Format
|
21
|
-
content_type 'text/html', :extension => :html
|
22
|
-
content_type 'application/xhtml+xml', :extension => :xhtml
|
23
|
-
content_type 'image/svg+xml', :extension => :svg
|
24
21
|
content_encoding 'utf-8'
|
25
|
-
|
22
|
+
content_type 'text/html', :extension => :html
|
26
23
|
reader { RDF::RDFa::Reader }
|
24
|
+
writer { RDF::RDFa::Writer }
|
27
25
|
XMLNS = 'http://www.w3.org/1999/xhtml' # FIXME: This or XHV or none at all?
|
28
26
|
end
|
29
27
|
|
@@ -36,6 +34,8 @@ module RDF::RDFa
|
|
36
34
|
# RDF::Format.for(:html).reader # RDF::RDFa::Reader
|
37
35
|
# RDF::Format.for(:html).writer # RDF::RDFa::Writer
|
38
36
|
class HTML < RDF::Format
|
37
|
+
content_encoding 'utf-8'
|
38
|
+
content_type 'text/html', :extension => :html
|
39
39
|
reader { RDF::RDFa::Reader }
|
40
40
|
writer { RDF::RDFa::Writer }
|
41
41
|
end
|
@@ -49,6 +49,8 @@ module RDF::RDFa
|
|
49
49
|
# RDF::Format.for(:xhtml).reader # RDF::RDFa::Reader
|
50
50
|
# RDF::Format.for(:xhtml).writer # RDF::RDFa::Writer
|
51
51
|
class XHTML < RDF::Format
|
52
|
+
content_encoding 'utf-8'
|
53
|
+
content_type 'application/xhtml+xml', :extension => :xhtml
|
52
54
|
reader { RDF::RDFa::Reader }
|
53
55
|
writer { RDF::RDFa::Writer }
|
54
56
|
end
|
@@ -62,6 +64,8 @@ module RDF::RDFa
|
|
62
64
|
# RDF::Format.for(:svg).reader # RDF::RDFa::Reader
|
63
65
|
# RDF::Format.for(:svg).writer # RDF::RDFa::Writer
|
64
66
|
class SVG < RDF::Format
|
67
|
+
content_encoding 'utf-8'
|
68
|
+
content_type 'image/svg+xml', :extension => :svg
|
65
69
|
reader { RDF::RDFa::Reader }
|
66
70
|
writer { RDF::RDFa::Writer }
|
67
71
|
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module RDF
|
2
|
+
class Graph
|
3
|
+
# Resource properties
|
4
|
+
#
|
5
|
+
# Properties arranged as a hash with the predicate Term as index to an array of resources or literals
|
6
|
+
#
|
7
|
+
# Example:
|
8
|
+
# graph.load(':foo a :bar; rdfs:label "An example" .', "http://example.com/")
|
9
|
+
# graph.resources(URI.new("http://example.com/subject")) =>
|
10
|
+
# {
|
11
|
+
# "http://www.w3.org/1999/02/22-rdf-syntax-ns#type" => [<http://example.com/#bar>],
|
12
|
+
# "http://example.com/#label" => ["An example"]
|
13
|
+
# }
|
14
|
+
def properties(subject, recalc = false)
|
15
|
+
@properties ||= {}
|
16
|
+
@properties.delete(subject.to_s) if recalc
|
17
|
+
@properties[subject.to_s] ||= begin
|
18
|
+
hash = Hash.new
|
19
|
+
self.query(:subject => subject) do |statement|
|
20
|
+
pred = statement.predicate.to_s
|
21
|
+
|
22
|
+
hash[pred] ||= []
|
23
|
+
hash[pred] << statement.object
|
24
|
+
end
|
25
|
+
hash
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# Get type(s) of subject, returns a list of symbols
|
30
|
+
def type_of(subject)
|
31
|
+
query(:subject => subject, :predicate => RDF.type).map {|st| st.object}
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
class ::String
|
2
|
+
# Trim beginning of each line by the amount of indentation in the first line
|
3
|
+
def align_left
|
4
|
+
str = self.sub(/^\s*$/, '') # Remove leading newline
|
5
|
+
str = str[1..-1] if str[0,1] == "\n"
|
6
|
+
ws = str.match(/^(\s*)\S/m) ? $1 : ''
|
7
|
+
str.gsub(/^#{ws}/m, '')
|
8
|
+
end
|
9
|
+
end
|
data/lib/rdf/rdfa/profile.rb
CHANGED
@@ -30,45 +30,18 @@ module RDF::RDFa
|
|
30
30
|
# Parses the profile and places it in the repository and cache
|
31
31
|
#
|
32
32
|
# @param [RDF::URI, #to_s] uri URI of profile to be represented
|
33
|
-
|
33
|
+
# @yield [profile]
|
34
|
+
# @yieldparam [RDF::RDFa::Profile] profile
|
35
|
+
# @yieldreturn [void] ignored
|
36
|
+
# @return [RDF::RDFa::Profile]
|
37
|
+
def initialize(uri, options = {}, &block)
|
34
38
|
@uri = RDF::URI.intern(uri)
|
35
|
-
@prefixes = {}
|
36
|
-
@terms = {}
|
37
|
-
@vocabulary =
|
39
|
+
@prefixes = options.fetch(:prefixes, {})
|
40
|
+
@terms = options.fetch(:terms, {})
|
41
|
+
@vocabulary = options[:vocabulary]
|
38
42
|
|
39
|
-
|
40
|
-
|
41
|
-
resource_info = {}
|
42
|
-
repository.query(:context => uri).each do |statement|
|
43
|
-
res = resource_info[statement.subject] ||= {}
|
44
|
-
next 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
|
43
|
+
yield(self) if block_given?
|
44
|
+
self
|
72
45
|
end
|
73
46
|
|
74
47
|
##
|
@@ -76,7 +49,9 @@ module RDF::RDFa
|
|
76
49
|
# @private
|
77
50
|
def self.cache
|
78
51
|
require 'rdf/util/cache' unless defined?(::RDF::Util::Cache)
|
79
|
-
@cache ||=
|
52
|
+
@cache ||= begin
|
53
|
+
RDF::Util::Cache.new(-1)
|
54
|
+
end
|
80
55
|
end
|
81
56
|
|
82
57
|
##
|
@@ -107,9 +82,13 @@ module RDF::RDFa
|
|
107
82
|
# Return something to make the caller happy if we're re-entered
|
108
83
|
cache[uri] = Struct.new(:prefixes, :terms, :vocabulary).new({}, {}, nil)
|
109
84
|
# Now do the actual load
|
110
|
-
cache[uri] = new(uri)
|
85
|
+
cache[uri] = new(uri) do |profile|
|
86
|
+
STDERR.puts("process_profile: retrieve profile <#{uri}>") if RDF::RDFa.debug?
|
87
|
+
Profile.load(uri)
|
88
|
+
profile.parse(repository.query(:context => uri))
|
89
|
+
end
|
111
90
|
rescue Exception => e
|
112
|
-
raise ProfileError, "
|
91
|
+
raise ProfileError, "Profile #{uri}: #{e.message}"
|
113
92
|
end
|
114
93
|
|
115
94
|
# Load profile into repository
|
@@ -166,10 +145,55 @@ module RDF::RDFa
|
|
166
145
|
name = name.to_s.empty? ? nil : (name.respond_to?(:to_sym) ? name.to_sym : name.to_s.to_sym)
|
167
146
|
uri.nil? ? terms[name] : terms[name] = uri
|
168
147
|
end
|
148
|
+
|
149
|
+
##
|
150
|
+
# Extract vocabulary, prefix mappings and terms from a enumerable object into an instance
|
151
|
+
#
|
152
|
+
# @param [RDF::Enumerable, Enumerator] queryable
|
153
|
+
# @return [void] ignored
|
154
|
+
def parse(enumerable)
|
155
|
+
STDERR.puts("process_profile: parse profile <#{uri}>") if RDF::RDFa.debug?
|
156
|
+
resource_info = {}
|
157
|
+
enumerable.each do |statement|
|
158
|
+
res = resource_info[statement.subject] ||= {}
|
159
|
+
next unless statement.object.is_a?(RDF::Literal)
|
160
|
+
STDERR.puts("process_profile: statement=#{statement.inspect}") if RDF::RDFa.debug?
|
161
|
+
%w(uri term prefix vocabulary).each do |term|
|
162
|
+
res[term] ||= statement.object.value if statement.predicate == RDF::RDFA[term]
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
resource_info.values.each do |res|
|
167
|
+
# If one of the objects is not a Literal or if there are additional rdfa:uri or rdfa:term
|
168
|
+
# predicates sharing the same subject, no mapping is created.
|
169
|
+
uri = res["uri"]
|
170
|
+
term = res["term"]
|
171
|
+
prefix = res["prefix"]
|
172
|
+
vocab = res["vocabulary"]
|
173
|
+
STDERR.puts("process_profile: uri=#{uri.inspect}, term=#{term.inspect}, prefix=#{prefix.inspect}, vocabulary=#{vocab.inspect}") if RDF::RDFa.debug?
|
174
|
+
|
175
|
+
@vocabulary = vocab if vocab
|
176
|
+
|
177
|
+
# For every extracted triple that is the common subject of an rdfa:prefix and an rdfa:uri
|
178
|
+
# predicate, create a mapping from the object literal of the rdfa:prefix predicate to the
|
179
|
+
# object literal of the rdfa:uri predicate. Add or update this mapping in the local list of
|
180
|
+
# URI mappings after transforming the 'prefix' component to lower-case.
|
181
|
+
# For every extracted
|
182
|
+
prefix(prefix.downcase, uri) if uri && prefix && prefix != "_"
|
183
|
+
|
184
|
+
# triple that is the common subject of an rdfa:term and an rdfa:uri predicate, create a
|
185
|
+
# mapping from the object literal of the rdfa:term predicate to the object literal of the
|
186
|
+
# rdfa:uri predicate. Add or update this mapping in the local term mappings.
|
187
|
+
term(term, uri) if term && uri
|
188
|
+
end
|
189
|
+
end
|
169
190
|
end
|
170
191
|
|
171
192
|
##
|
172
193
|
# The base class for RDF profile errors.
|
173
194
|
class ProfileError < IOError
|
174
195
|
end # ProfileError
|
175
|
-
end
|
196
|
+
end
|
197
|
+
|
198
|
+
# Load cooked profiles
|
199
|
+
Dir.glob(File.join(File.expand_path(File.dirname(__FILE__)), 'profile', '*')).each {|f| load f}
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# This file is automatically generated by script/intern_vocabulary
|
2
|
+
# RDFa vocabulary for http://www.w3.org/profile/html-rdfa-1.1
|
3
|
+
|
4
|
+
profile = RDF::RDFa::Profile.new(RDF::URI("http://www.w3.org/profile/html-rdfa-1.1"), {
|
5
|
+
:terms => {
|
6
|
+
:alternate => "http://www.w3.org/1999/xhtml/vocab#alternate",
|
7
|
+
:appendix => "http://www.w3.org/1999/xhtml/vocab#appendix",
|
8
|
+
:bookmark => "http://www.w3.org/1999/xhtml/vocab#bookmark",
|
9
|
+
:chapter => "http://www.w3.org/1999/xhtml/vocab#chapter",
|
10
|
+
:cite => "http://www.w3.org/1999/xhtml/vocab#cite",
|
11
|
+
:contents => "http://www.w3.org/1999/xhtml/vocab#contents",
|
12
|
+
:copyright => "http://www.w3.org/1999/xhtml/vocab#copyright",
|
13
|
+
:first => "http://www.w3.org/1999/xhtml/vocab#first",
|
14
|
+
:glossary => "http://www.w3.org/1999/xhtml/vocab#glossary",
|
15
|
+
:help => "http://www.w3.org/1999/xhtml/vocab#help",
|
16
|
+
:icon => "http://www.w3.org/1999/xhtml/vocab#icon",
|
17
|
+
:index => "http://www.w3.org/1999/xhtml/vocab#index",
|
18
|
+
:itsRules => "http://www.w3.org/1999/xhtml/vocab#itsRules",
|
19
|
+
:last => "http://www.w3.org/1999/xhtml/vocab#last",
|
20
|
+
:license => "http://www.w3.org/1999/xhtml/vocab#license",
|
21
|
+
:meta => "http://www.w3.org/1999/xhtml/vocab#meta",
|
22
|
+
:next => "http://www.w3.org/1999/xhtml/vocab#next",
|
23
|
+
:p3pv1 => "http://www.w3.org/1999/xhtml/vocab#p3pv1",
|
24
|
+
:prev => "http://www.w3.org/1999/xhtml/vocab#prev",
|
25
|
+
:role => "http://www.w3.org/1999/xhtml/vocab#role",
|
26
|
+
:section => "http://www.w3.org/1999/xhtml/vocab#section",
|
27
|
+
:start => "http://www.w3.org/1999/xhtml/vocab#start",
|
28
|
+
:stylesheet => "http://www.w3.org/1999/xhtml/vocab#stylesheet",
|
29
|
+
:subsection => "http://www.w3.org/1999/xhtml/vocab#subsection",
|
30
|
+
:top => "http://www.w3.org/1999/xhtml/vocab#top",
|
31
|
+
:transformation => "http://www.w3.org/2003/g/data-view#transformation",
|
32
|
+
:up => "http://www.w3.org/1999/xhtml/vocab#up",
|
33
|
+
},
|
34
|
+
})
|
35
|
+
|
36
|
+
RDF::RDFa::Profile.cache[RDF::URI("http://www.w3.org/profile/html-rdfa-1.1")] = profile
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# This file is automatically generated by script/intern_vocabulary
|
2
|
+
# RDFa vocabulary for http://www.w3.org/profile/rdfa-1.1
|
3
|
+
|
4
|
+
profile = RDF::RDFa::Profile.new(RDF::URI("http://www.w3.org/profile/rdfa-1.1"), {
|
5
|
+
:prefixes => {
|
6
|
+
:bibo => "http://purl.org/ontology/bibo/",
|
7
|
+
:cal => "http://www.w3.org/2002/12/cal/ical#",
|
8
|
+
:cc => "http://creativecommons.org/ns#",
|
9
|
+
:dbp => "http://dbpedia.org/property/",
|
10
|
+
:"dbp-owl" => "http://dbpedia.org/ontology/",
|
11
|
+
:dbr => "http://dbpedia.org/resource/",
|
12
|
+
:dc => "http://purl.org/dc/elements/1.1/",
|
13
|
+
:dcterms => "http://purl.org/dc/terms/",
|
14
|
+
:doap => "http://usefulinc.com/ns/doap#",
|
15
|
+
:foaf => "http://xmlns.com/foaf/0.1/",
|
16
|
+
:geo => "http://www.w3.org/2003/01/geo/wgs84_pos#",
|
17
|
+
:gr => "http://purl.org/goodrelations/v1#",
|
18
|
+
:grddl => "http://www.w3.org/2003/g/data-view#",
|
19
|
+
:og => "http://ogp.me/ns#",
|
20
|
+
:owl => "http://www.w3.org/2002/07/owl#",
|
21
|
+
:rdf => "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
|
22
|
+
:rdfa => "http://www.w3.org/ns/rdfa#",
|
23
|
+
:rdfs => "http://www.w3.org/2000/01/rdf-schema#",
|
24
|
+
:rif => "http://www.w3.org/2007/rif#",
|
25
|
+
:rss => "http://purl.org/rss/1.0/",
|
26
|
+
:sd => "http://www.w3.org/ns/sparql-service-description#",
|
27
|
+
:sioc => "http://rdfs.org/sioc/ns#",
|
28
|
+
:skos => "http://www.w3.org/2004/02/skos/core#",
|
29
|
+
:skosxl => "http://www.w3.org/2008/05/skos-xl#",
|
30
|
+
:v => "http://rdf.data-vocabulary.org/#",
|
31
|
+
:vcard => "http://www.w3.org/2006/vcard/ns#",
|
32
|
+
:void => "http://rdfs.org/ns/void#",
|
33
|
+
:wdr => "http://www.w3.org/2007/05/powder#",
|
34
|
+
:wdrs => "http://www.w3.org/2007/05/powder-s#",
|
35
|
+
:xhv => "http://www.w3.org/1999/xhtml/vocab#",
|
36
|
+
:xml => "http://www.w3.org/XML/1998/namespace",
|
37
|
+
:xmlns => "http://www.w3.org/2000/xmlns/",
|
38
|
+
:xsd => "http://www.w3.org/2001/XMLSchema#",
|
39
|
+
},
|
40
|
+
:terms => {
|
41
|
+
:describedby => "http://www.w3.org/2007/05/powder-s#describedby",
|
42
|
+
},
|
43
|
+
})
|
44
|
+
|
45
|
+
RDF::RDFa::Profile.cache[RDF::URI("http://www.w3.org/profile/rdfa-1.1")] = profile
|
data/lib/rdf/rdfa/reader.rb
CHANGED
@@ -6,23 +6,24 @@ 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/
|
9
|
+
# @see http://www.w3.org/TR/2010/WD-rdfa-core-20100422/ RDFa Core 1.1
|
10
|
+
# @see http://www.w3.org/TR/2010/WD-xhtml-rdfa-20100422/ XHTML+RDFa 1.1
|
10
11
|
#
|
11
12
|
# @author [Gregg Kellogg](http://kellogg-assoc.com/)
|
12
13
|
class Reader < RDF::Reader
|
13
14
|
format Format
|
14
15
|
|
15
16
|
SafeCURIEorCURIEorURI = {
|
16
|
-
:
|
17
|
-
:
|
17
|
+
:"rdfa1.0" => [:term, :safe_curie, :uri, :bnode],
|
18
|
+
:"rdfa1.1" => [:safe_curie, :curie, :term, :uri, :bnode],
|
18
19
|
}
|
19
20
|
TERMorCURIEorAbsURI = {
|
20
|
-
:
|
21
|
-
:
|
21
|
+
:"rdfa1.0" => [:term, :curie],
|
22
|
+
:"rdfa1.1" => [:term, :curie, :absuri],
|
22
23
|
}
|
23
24
|
TERMorCURIEorAbsURIprop = {
|
24
|
-
:
|
25
|
-
:
|
25
|
+
:"rdfa1.0" => [:curie],
|
26
|
+
:"rdfa1.1" => [:term, :curie, :absuri],
|
26
27
|
}
|
27
28
|
|
28
29
|
NC_REGEXP = Regexp.new(
|
@@ -39,11 +40,11 @@ module RDF::RDFa
|
|
39
40
|
Regexp::EXTENDED)
|
40
41
|
|
41
42
|
# Host language
|
42
|
-
# @return [:
|
43
|
+
# @return [:xml1, :xhtml1, :xhtml5, :html4, :html5, :svg]
|
43
44
|
attr_reader :host_language
|
44
45
|
|
45
46
|
# Version
|
46
|
-
# @return [:
|
47
|
+
# @return [:"rdfa1.0", :"rdfa1.1"]
|
47
48
|
attr_reader :version
|
48
49
|
|
49
50
|
# The Recursive Baggage
|
@@ -147,7 +148,7 @@ module RDF::RDFa
|
|
147
148
|
v << "uri_mappings[#{uri_mappings.keys.length}]"
|
148
149
|
v << "incomplete_triples[#{incomplete_triples.length}]"
|
149
150
|
v << "term_mappings[#{term_mappings.keys.length}]"
|
150
|
-
v.join(",")
|
151
|
+
v.join(", ")
|
151
152
|
end
|
152
153
|
end
|
153
154
|
|
@@ -170,9 +171,9 @@ module RDF::RDFa
|
|
170
171
|
# the prefix mappings to use (not supported by all readers)
|
171
172
|
# @option options [#to_s] :base_uri (nil)
|
172
173
|
# the base URI to use when resolving relative URIs
|
173
|
-
# @option options [:
|
174
|
+
# @option options [:xml1, :xhtml1, :xhtml5, :html4, :html5, :svg] :host_language (:xhtml1)
|
174
175
|
# Host Language
|
175
|
-
# @option options [:
|
176
|
+
# @option options [:"rdfa1.0", :"rdfa1.1"] :version (:"rdfa1.1")
|
176
177
|
# Parser version information
|
177
178
|
# @option options [Graph] :processor_graph (nil)
|
178
179
|
# Graph to record information, warnings and errors.
|
@@ -190,24 +191,93 @@ module RDF::RDFa
|
|
190
191
|
@debug = options[:debug]
|
191
192
|
@base_uri = uri(options[:base_uri])
|
192
193
|
|
193
|
-
@
|
194
|
+
@host_language = options[:host_language]
|
194
195
|
@processor_graph = options[:processor_graph]
|
195
196
|
|
196
197
|
@doc = case input
|
197
|
-
when Nokogiri::HTML::Document
|
198
|
-
|
199
|
-
|
198
|
+
when Nokogiri::HTML::Document
|
199
|
+
@host_language ||= :xhtml1
|
200
|
+
when Nokogiri::XML::Document
|
201
|
+
input
|
202
|
+
else
|
203
|
+
# Intuit from content type
|
204
|
+
@host_language ||= case input.respond_to?(:content_type) && input.content_type
|
205
|
+
when "text/xml", "application/xml"
|
206
|
+
:xml1
|
207
|
+
when "text/html", "application/xhtml+xml"
|
208
|
+
:xhtml1
|
209
|
+
when "image/svg+xml"
|
210
|
+
:svg
|
211
|
+
end
|
212
|
+
|
213
|
+
# Intuit from file extension
|
214
|
+
@host_language ||= case input.respond_to?(:path) && File.extname(input.path.to_s)
|
215
|
+
when ".html" then :html5
|
216
|
+
when ".xhtml" then :xhtml1
|
217
|
+
when ".svg" then :svg
|
218
|
+
end
|
219
|
+
|
220
|
+
Nokogiri::XML.parse(input, @base_uri.to_s)
|
200
221
|
end
|
201
222
|
|
202
|
-
@
|
203
|
-
|
223
|
+
if (@doc.nil? || @doc.root.nil?)
|
224
|
+
add_error(nil, "Empty document", RDF::RDFA.DocumentError)
|
225
|
+
raise RDF::ReaderError, "Empty Document"
|
226
|
+
end
|
227
|
+
add_warning(nil, "Synax errors:\n#{@doc.errors}", RDF::RDFA.DocumentError) if !@doc.errors.empty? && validate?
|
228
|
+
|
229
|
+
@version = options[:version] ? options[:version].to_sym : nil
|
230
|
+
|
231
|
+
# Check for version of the processor to use:
|
232
|
+
# * Check document type for "XHTML+RDFa 1.0"
|
233
|
+
# * Check @version attribute on the html element for the value "XHTML+RDFa 1.0"
|
234
|
+
@version ||= :"rdfa1.0" if @doc.doctype.to_s =~ /RDFa 1\.0/
|
235
|
+
@version ||= :"rdfa1.0" if @doc.root && @doc.root.attribute("version").to_s =~ /RDFa 1\.0/
|
236
|
+
@version ||= :"rdfa1.1" if @doc.root && @doc.root.attribute("version").to_s =~ /RDFa 1\.1/
|
237
|
+
@version ||= :"rdfa1.1"
|
238
|
+
|
239
|
+
# Intuit host_language from doctype
|
240
|
+
@host_language ||= case @doc.doctype.to_s
|
241
|
+
when /html 4/i then :html4
|
242
|
+
when /xhtml\+rdfa/i then :xhtml1
|
243
|
+
when /html/ then :html5
|
244
|
+
end
|
245
|
+
|
246
|
+
# Determine host language from element name
|
247
|
+
@host_language ||= case @doc.root.name.downcase.to_sym
|
248
|
+
when :html then :xhtml1
|
204
249
|
when :svg then :svg
|
205
|
-
else :
|
250
|
+
else :xml
|
206
251
|
end
|
207
252
|
|
208
|
-
|
209
|
-
|
210
|
-
|
253
|
+
# Otherwise, treat it as XML
|
254
|
+
@host_language ||= :xml1
|
255
|
+
|
256
|
+
# Section 4.2 RDFa Host Language Conformance
|
257
|
+
#
|
258
|
+
# The Host Language may require the automatic inclusion of one or more default RDFa Profiles.
|
259
|
+
@host_defaults = {
|
260
|
+
:vocabulary => nil,
|
261
|
+
:uri_mappings => {},
|
262
|
+
:profiles => [],
|
263
|
+
}
|
264
|
+
|
265
|
+
if @version == :"rdfa1.0"
|
266
|
+
# Add default term mappings
|
267
|
+
@host_defaults[:term_mappings] = %w(
|
268
|
+
alternate appendix bookmark cite chapter contents copyright first glossary help icon index
|
269
|
+
last license meta next p3pv1 prev role section stylesheet subsection start top up
|
270
|
+
).inject({}) { |hash, term| hash[term] = RDF::XHV[term]; hash }
|
271
|
+
end
|
272
|
+
|
273
|
+
case @host_language
|
274
|
+
when :xml1, :svg
|
275
|
+
@host_defaults[:profiles] = [XML_RDFA_PROFILE]
|
276
|
+
when :xhtml1, :xhtml5, :html4, :html5
|
277
|
+
@host_defaults[:profiles] = [XML_RDFA_PROFILE, XHTML_RDFA_PROFILE]
|
278
|
+
end
|
279
|
+
|
280
|
+
add_info(@doc, "version = #{@version}, host_language = #{@host_language}")
|
211
281
|
|
212
282
|
block.call(self) if block_given?
|
213
283
|
end
|
@@ -234,35 +304,11 @@ module RDF::RDFa
|
|
234
304
|
def each_statement(&block)
|
235
305
|
@callback = block
|
236
306
|
|
237
|
-
# Section 4.2 RDFa Host Language Conformance
|
238
|
-
#
|
239
|
-
# The Host Language may define a default RDFa Profile. If it does, the RDFa Profile triples that establish term or
|
240
|
-
# URI mappings associated with that profile must not change without changing the profile URI. RDFa Processors may
|
241
|
-
# embed, cache, or retrieve the RDFa Profile triples associated with that profile.
|
242
|
-
@host_defaults = case @host_language
|
243
|
-
when :xhtml
|
244
|
-
{
|
245
|
-
:vocabulary => nil,
|
246
|
-
:prefix => "xhv",
|
247
|
-
:uri_mappings => {"xhv" => RDF::XHV.to_s}, # RDF::XHTML is wrong
|
248
|
-
:term_mappings => %w(
|
249
|
-
alternate appendix bookmark cite chapter contents copyright first glossary help icon index
|
250
|
-
last license meta next p3pv1 prev role section stylesheet subsection start top up
|
251
|
-
).inject({}) { |hash, term| hash[term.to_sym] = RDF::XHV[term].to_s; hash },
|
252
|
-
}
|
253
|
-
else
|
254
|
-
{
|
255
|
-
:uri_mappings => {},
|
256
|
-
}
|
257
|
-
end
|
258
|
-
|
259
307
|
# Add prefix definitions from host defaults
|
260
308
|
@host_defaults[:uri_mappings].each_pair do |prefix, value|
|
261
309
|
prefix(prefix, value)
|
262
310
|
end
|
263
311
|
|
264
|
-
add_info(@doc, "version = #{@version}, host_language = #{@host_language}")
|
265
|
-
|
266
312
|
# parse
|
267
313
|
parse_whole_document(@doc, @base_uri)
|
268
314
|
end
|
@@ -319,19 +365,17 @@ module RDF::RDFa
|
|
319
365
|
end
|
320
366
|
|
321
367
|
def add_processor_message(node, message, process_class)
|
322
|
-
puts "#{node_path(node)}: #{message}" if ::RDF::RDFa
|
368
|
+
puts "#{node_path(node)}: #{message}" if ::RDF::RDFa.debug?
|
323
369
|
@debug << "#{node_path(node)}: #{message}" if @debug.is_a?(Array)
|
324
370
|
if @processor_graph
|
325
|
-
@processor_sequence ||= 0
|
326
371
|
n = RDF::Node.new
|
327
372
|
@processor_graph << RDF::Statement.new(n, RDF["type"], process_class)
|
328
373
|
@processor_graph << RDF::Statement.new(n, RDF::DC.description, message)
|
329
374
|
@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
375
|
@processor_graph << RDF::Statement.new(n, RDF::RDFA.context, @base_uri)
|
332
376
|
nc = RDF::Node.new
|
333
377
|
@processor_graph << RDF::Statement.new(nc, RDF["type"], RDF::PTR.XPathPointer)
|
334
|
-
@processor_graph << RDF::Statement.new(nc, RDF::PTR.expression, node.path)
|
378
|
+
@processor_graph << RDF::Statement.new(nc, RDF::PTR.expression, node.path) if node.respond_to?(:path)
|
335
379
|
@processor_graph << RDF::Statement.new(n, RDF::RDFA.context, nc)
|
336
380
|
end
|
337
381
|
end
|
@@ -355,9 +399,12 @@ module RDF::RDFa
|
|
355
399
|
def parse_whole_document(doc, base)
|
356
400
|
# find if the document has a base element
|
357
401
|
case @host_language
|
358
|
-
when :
|
402
|
+
when :xhtml1, :xhtml5, :html4, :html5
|
359
403
|
base_el = doc.at_css("html>head>base")
|
360
404
|
base = base_el.attribute("href").to_s.split("#").first if base_el
|
405
|
+
else
|
406
|
+
xml_base = doc.root.attribute_with_ns("base", RDF::XML.to_s)
|
407
|
+
base = xml_base if xml_base
|
361
408
|
end
|
362
409
|
|
363
410
|
if (base)
|
@@ -370,6 +417,18 @@ module RDF::RDFa
|
|
370
417
|
# initialize the evaluation context with the appropriate base
|
371
418
|
evaluation_context = EvaluationContext.new(base, @host_defaults)
|
372
419
|
|
420
|
+
if @version != :"rdfa1.0"
|
421
|
+
# Process default vocabularies
|
422
|
+
process_profile(doc.root, @host_defaults[:profiles]) do |which, value|
|
423
|
+
add_debug(doc.root, "parse_whole_document, #{which}: #{value.inspect}")
|
424
|
+
case which
|
425
|
+
when :uri_mappings then evaluation_context.uri_mappings.merge!(value)
|
426
|
+
when :term_mappings then evaluation_context.term_mappings.merge!(value)
|
427
|
+
when :default_vocabulary then evaluation_context.default_vocabulary = value
|
428
|
+
end
|
429
|
+
end
|
430
|
+
end
|
431
|
+
|
373
432
|
traverse(doc.root, evaluation_context)
|
374
433
|
add_debug("", "parse_whole_doc: traversal complete'")
|
375
434
|
end
|
@@ -379,7 +438,6 @@ module RDF::RDFa
|
|
379
438
|
# Yields each mapping
|
380
439
|
def process_profile(element, profiles)
|
381
440
|
profiles.
|
382
|
-
reverse.
|
383
441
|
map {|uri| uri(uri).normalize}.
|
384
442
|
each do |uri|
|
385
443
|
# Don't try to open ourselves!
|
@@ -389,10 +447,18 @@ module RDF::RDFa
|
|
389
447
|
end
|
390
448
|
|
391
449
|
old_debug = RDF::RDFa.debug?
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
450
|
+
begin
|
451
|
+
add_info(element, "process_profile: load <#{uri}>")
|
452
|
+
RDF::RDFa.debug = false
|
453
|
+
profile = Profile.find(uri)
|
454
|
+
rescue Exception => e
|
455
|
+
RDF::RDFa.debug = old_debug
|
456
|
+
add_error(element, e.message, RDF::RDFA.ProfileReferenceError)
|
457
|
+
raise # In case we're not in strict mode, we need to be sure processing stops
|
458
|
+
ensure
|
459
|
+
RDF::RDFa.debug = old_debug
|
460
|
+
end
|
461
|
+
|
396
462
|
# Add URI Mappings to prefixes
|
397
463
|
profile.prefixes.each_pair do |prefix, value|
|
398
464
|
prefix(prefix, value)
|
@@ -401,9 +467,6 @@ module RDF::RDFa
|
|
401
467
|
yield :term_mappings, profile.terms unless profile.terms.empty?
|
402
468
|
yield :default_vocabulary, profile.vocabulary if profile.vocabulary
|
403
469
|
end
|
404
|
-
rescue Exception => e
|
405
|
-
add_error(element, e.message, RDF::RDFA.ProfileReferenceError)
|
406
|
-
raise # In case we're not in strict mode, we need to be sure processing stops
|
407
470
|
end
|
408
471
|
|
409
472
|
# Extract the XMLNS mappings from an element
|
@@ -418,7 +481,7 @@ module RDF::RDFa
|
|
418
481
|
next if ns.prefix == "_"
|
419
482
|
|
420
483
|
# Downcase prefix for RDFa 1.1
|
421
|
-
pfx_lc = (@version == :
|
484
|
+
pfx_lc = (@version == :"rdfa1.0" || ns.prefix.nil?) ? ns.prefix : ns.prefix.to_s.downcase
|
422
485
|
if ns.prefix
|
423
486
|
uri_mappings[pfx_lc.to_sym] = ns.href
|
424
487
|
namespaces[pfx_lc] ||= ns.href
|
@@ -432,20 +495,25 @@ module RDF::RDFa
|
|
432
495
|
# Set mappings from @prefix
|
433
496
|
# prefix is a whitespace separated list of prefix-name URI pairs of the form
|
434
497
|
# NCName ':' ' '+ xs:anyURI
|
435
|
-
mappings = element.
|
498
|
+
mappings = element.attribute("prefix").to_s.strip.split(/\s+/)
|
436
499
|
while mappings.length > 0 do
|
437
500
|
prefix, uri = mappings.shift.downcase, mappings.shift
|
438
501
|
#puts "uri_mappings prefix #{prefix} <#{uri}>"
|
439
502
|
next unless prefix.match(/:$/)
|
440
503
|
prefix.chop!
|
441
504
|
|
505
|
+
unless prefix.match(NC_REGEXP)
|
506
|
+
add_error(element, "extract_mappings: Prefix #{prefix.inspect} does not match NCName production")
|
507
|
+
next
|
508
|
+
end
|
509
|
+
|
442
510
|
# A Conforming RDFa Processor must ignore any definition of a mapping for the '_' prefix.
|
443
511
|
next if prefix == "_"
|
444
512
|
|
445
513
|
uri_mappings[prefix.to_s.empty? ? nil : prefix.to_s.to_sym] = uri
|
446
514
|
prefix(prefix, uri)
|
447
515
|
add_info(element, "extract_mappings: prefix #{prefix} => <#{uri}>")
|
448
|
-
end unless @version == :
|
516
|
+
end unless @version == :"rdfa1.0"
|
449
517
|
end
|
450
518
|
|
451
519
|
# The recursive helper function
|
@@ -480,7 +548,7 @@ module RDF::RDFa
|
|
480
548
|
href = attrs['href']
|
481
549
|
vocab = attrs['vocab']
|
482
550
|
xml_base = element.attribute_with_ns("base", RDF::XML.to_s)
|
483
|
-
base = xml_base.to_s if xml_base &&
|
551
|
+
base = xml_base.to_s if xml_base && ![:xhtml1, :xhtml5, :html4, :html5].include?(@host_language)
|
484
552
|
base ||= evaluation_context.base
|
485
553
|
|
486
554
|
# Pull out the attributes needed for the skip test.
|
@@ -512,14 +580,29 @@ module RDF::RDFa
|
|
512
580
|
# Local term mappings [7.5 Steps 2]
|
513
581
|
# Next the current element is parsed for any updates to the local term mappings and local list of URI mappings via @profile.
|
514
582
|
# If @profile is present, its value is processed as defined in RDFa Profiles.
|
515
|
-
unless @version == :
|
583
|
+
unless @version == :"rdfa1.0"
|
516
584
|
begin
|
517
585
|
process_profile(element, profiles) do |which, value|
|
518
586
|
add_debug(element, "[Step 2] traverse, #{which}: #{value.inspect}")
|
519
587
|
case which
|
520
|
-
when :uri_mappings
|
521
|
-
|
522
|
-
|
588
|
+
when :uri_mappings
|
589
|
+
value.each do |k, v|
|
590
|
+
if k.to_s.match(NC_REGEXP)
|
591
|
+
uri_mappings[k] = v
|
592
|
+
else
|
593
|
+
add_error(element, "[Step 2] traverse: Prefix #{k.to_s.inspect} does not match NCName production")
|
594
|
+
end
|
595
|
+
end
|
596
|
+
when :term_mappings
|
597
|
+
value.each do |k, v|
|
598
|
+
if k.to_s.match(NC_REGEXP)
|
599
|
+
term_mappings[k] = v
|
600
|
+
else
|
601
|
+
add_error(element, "[Step 2] traverse: Term #{k.to_s.inspect} does not match NCName production")
|
602
|
+
end
|
603
|
+
end
|
604
|
+
when :default_vocabulary
|
605
|
+
default_vocabulary = value
|
523
606
|
end
|
524
607
|
end
|
525
608
|
rescue
|
@@ -538,12 +621,12 @@ module RDF::RDFa
|
|
538
621
|
unless vocab.nil?
|
539
622
|
default_vocabulary = if vocab.to_s.empty?
|
540
623
|
# Set default_vocabulary to host language default
|
541
|
-
add_debug(element, "[Step
|
624
|
+
add_debug(element, "[Step 3] traverse, reset default_vocaulary to #{@host_defaults.fetch(:vocabulary, nil).inspect}")
|
542
625
|
@host_defaults.fetch(:vocabulary, nil)
|
543
626
|
else
|
544
627
|
uri(vocab)
|
545
628
|
end
|
546
|
-
add_debug(element, "[Step
|
629
|
+
add_debug(element, "[Step 3] traverse, default_vocaulary: #{default_vocabulary.inspect}")
|
547
630
|
end
|
548
631
|
|
549
632
|
# Local term mappings [7.5 Steps 4]
|
@@ -560,8 +643,8 @@ module RDF::RDFa
|
|
560
643
|
language = case
|
561
644
|
when element.at_xpath("@xml:lang", "xml" => RDF::XML["uri"].to_s)
|
562
645
|
element.at_xpath("@xml:lang", "xml" => RDF::XML["uri"].to_s).to_s
|
563
|
-
when element.at_xpath("lang")
|
564
|
-
element.at_xpath("lang").to_s
|
646
|
+
when element.at_xpath("@lang")
|
647
|
+
element.at_xpath("@lang").to_s
|
565
648
|
else
|
566
649
|
language
|
567
650
|
end
|
@@ -605,15 +688,14 @@ module RDF::RDFa
|
|
605
688
|
# otherwise,
|
606
689
|
# if parent object is present, new subject is set to the value of parent object.
|
607
690
|
# Additionally, if @property is not present then the skip element flag is set to 'true';
|
608
|
-
new_subject ||= if
|
691
|
+
new_subject ||= if element == @doc.root && base
|
692
|
+
uri(base)
|
693
|
+
elsif [:xhtml1, :xhtml5, :html4, :html5].include?(@host_language) && element.name =~ /^(head|body)$/
|
609
694
|
# From XHTML+RDFa 1.1:
|
610
695
|
# if no URI is provided, then first check to see if the element is the head or body element.
|
611
696
|
# If it is, then act as if there is an empty @about present, and process it according to the rule for @about.
|
612
697
|
uri(base)
|
613
|
-
elsif
|
614
|
-
# XXX Spec confusion, assume that this is true
|
615
|
-
uri(base)
|
616
|
-
elsif element.attributes['typeof']
|
698
|
+
elsif typeof
|
617
699
|
RDF::Node.new
|
618
700
|
else
|
619
701
|
# if it's null, it's null and nothing changes
|
@@ -633,7 +715,9 @@ module RDF::RDFa
|
|
633
715
|
:restrictions => [:uri])
|
634
716
|
|
635
717
|
# If no URI is provided then the first match from the following rules will apply
|
636
|
-
new_subject ||= if
|
718
|
+
new_subject ||= if element == @doc.root && base
|
719
|
+
uri(base)
|
720
|
+
elsif [:xhtml1, :xhtml5, :html4, :html5].include?(@host_language) && element.name =~ /^(head|body)$/
|
637
721
|
# From XHTML+RDFa 1.1:
|
638
722
|
# if no URI is provided, then first check to see if the element is the head or body element.
|
639
723
|
# If it is, then act as if there is an empty @about present, and process it according to the rule for @about.
|
@@ -674,7 +758,7 @@ module RDF::RDFa
|
|
674
758
|
end
|
675
759
|
|
676
760
|
# Generate triples with given object [Step 9]
|
677
|
-
if current_object_resource
|
761
|
+
if new_subject and current_object_resource
|
678
762
|
rels.each do |r|
|
679
763
|
add_triple(element, new_subject, r, current_object_resource)
|
680
764
|
end
|
@@ -727,7 +811,7 @@ module RDF::RDFa
|
|
727
811
|
# typed literal
|
728
812
|
add_debug(element, "[Step 11] typed literal (#{datatype})")
|
729
813
|
RDF::Literal.new(content || element.inner_text.to_s, :datatype => datatype, :language => language, :validate => validate?, :canonicalize => canonicalize?)
|
730
|
-
elsif @version == :
|
814
|
+
elsif @version == :"rdfa1.1"
|
731
815
|
if datatype.to_s == RDF.XMLLiteral.to_s
|
732
816
|
# XML Literal
|
733
817
|
add_debug(element, "[Step 11(1.1)] XML Literal: #{element.inner_html}")
|
@@ -774,9 +858,9 @@ module RDF::RDFa
|
|
774
858
|
add_error(element, e.message)
|
775
859
|
end
|
776
860
|
|
777
|
-
|
861
|
+
# add each property
|
778
862
|
properties.each do |p|
|
779
|
-
add_triple(element, new_subject, p, current_object_literal)
|
863
|
+
add_triple(element, new_subject, p, current_object_literal) if new_subject
|
780
864
|
end
|
781
865
|
end
|
782
866
|
|
@@ -867,7 +951,7 @@ module RDF::RDFa
|
|
867
951
|
uri = curie_to_resource_or_bnode(element, value, options[:uri_mappings], evaluation_context.parent_subject, restrictions)
|
868
952
|
if uri
|
869
953
|
add_debug(element, "process_uri: #{value} => CURIE => <#{uri}>")
|
870
|
-
elsif @version == :
|
954
|
+
elsif @version == :"rdfa1.0" && value.to_s.match(/^xml/i)
|
871
955
|
# Special case to not allow anything starting with XML to be treated as a URI
|
872
956
|
elsif restrictions.include?(:absuri) || restrictions.include?(:uri)
|
873
957
|
begin
|
@@ -935,22 +1019,14 @@ module RDF::RDFa
|
|
935
1019
|
# As a special case, _: is also a valid reference for one specific bnode.
|
936
1020
|
bnode(reference)
|
937
1021
|
elsif curie.to_s.match(/^:/)
|
938
|
-
add_debug(element, "curie_to_resource_or_bnode: default prefix: defined? #{!!uri_mappings[""]}, defaults: #{@host_defaults[:prefix]}")
|
939
1022
|
# Default prefix
|
940
|
-
|
941
|
-
uri(uri_mappings[nil] + reference.to_s)
|
942
|
-
elsif @host_defaults[:prefix]
|
943
|
-
uri(uri_mappings[@host_defaults[:prefix]] + reference.to_s)
|
944
|
-
else
|
945
|
-
#add_warning(element, "Default namespace prefix is not defined", RDF::RDFA.UnresolvedCURIE)
|
946
|
-
nil
|
947
|
-
end
|
1023
|
+
RDF::XHV[reference.to_s]
|
948
1024
|
elsif !curie.to_s.match(/:/)
|
949
1025
|
# No prefix, undefined (in this context, it is evaluated as a term elsewhere)
|
950
1026
|
nil
|
951
1027
|
else
|
952
1028
|
# Prefixes always downcased
|
953
|
-
prefix = prefix.to_s.downcase unless @version == :
|
1029
|
+
prefix = prefix.to_s.downcase unless @version == :"rdfa1.0"
|
954
1030
|
add_debug(element, "curie_to_resource_or_bnode check for #{prefix.to_s.to_sym.inspect} in #{uri_mappings.inspect}")
|
955
1031
|
ns = uri_mappings[prefix.to_s.to_sym]
|
956
1032
|
if ns
|