rdf-rdfa 1.99.3 → 2.0.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +487 -0
- data/VERSION +1 -1
- data/lib/rdf/rdfa.rb +0 -3
- data/lib/rdf/rdfa/context.rb +21 -9
- data/lib/rdf/rdfa/context/xml.rb +1 -0
- data/lib/rdf/rdfa/format.rb +6 -60
- data/lib/rdf/rdfa/reader.rb +55 -39
- data/lib/rdf/rdfa/reader/nokogiri.rb +1 -1
- data/lib/rdf/rdfa/writer.rb +119 -117
- metadata +134 -59
- data/README +0 -1
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
2.0.0.beta1
|
data/lib/rdf/rdfa.rb
CHANGED
@@ -35,8 +35,5 @@ module RDF
|
|
35
35
|
HTML_RDFA_CONTEXT = "http://www.w3.org/2011/rdfa-context/html-rdfa-1.1"
|
36
36
|
XHTML_RDFA_CONTEXT = "http://www.w3.org/2011/rdfa-context/xhtml-rdfa-1.1"
|
37
37
|
XML_RDFA_CONTEXT = "http://www.w3.org/2011/rdfa-context/rdfa-1.1"
|
38
|
-
|
39
|
-
def self.debug?; @debug; end
|
40
|
-
def self.debug=(value); @debug = value; end
|
41
38
|
end
|
42
39
|
end
|
data/lib/rdf/rdfa/context.rb
CHANGED
@@ -8,6 +8,8 @@ module RDF::RDFa
|
|
8
8
|
# The class may be backed by an RDF::Repository, which will be used to retrieve a context graph
|
9
9
|
# or to load into, if no such graph exists
|
10
10
|
class Context
|
11
|
+
include RDF::Util::Logger
|
12
|
+
|
11
13
|
# Prefix mappings defined in this context
|
12
14
|
# @!attribute [r] prefixes
|
13
15
|
# @return [Hash{Symbol => RDF::URI}]
|
@@ -43,6 +45,7 @@ module RDF::RDFa
|
|
43
45
|
@prefixes = options.fetch(:prefixes, {})
|
44
46
|
@terms = options.fetch(:terms, {})
|
45
47
|
@vocabulary = options[:vocabulary]
|
48
|
+
@options = options.dup
|
46
49
|
|
47
50
|
yield(self) if block_given?
|
48
51
|
self
|
@@ -61,7 +64,6 @@ module RDF::RDFa
|
|
61
64
|
##
|
62
65
|
# Repository used for saving contexts
|
63
66
|
# @return [RDF::Repository]
|
64
|
-
# @raise [RDF::RDFa::ContextError] if context does not support contexts
|
65
67
|
def self.repository
|
66
68
|
@repository ||= RDF::Repository.new(title: "RDFa Contexts")
|
67
69
|
end
|
@@ -71,7 +73,13 @@ module RDF::RDFa
|
|
71
73
|
# @param [RDF::Repository] repo
|
72
74
|
# @return [RDF::Repository]
|
73
75
|
def self.repository=(repo)
|
74
|
-
|
76
|
+
unless repo.supports?(:graph_name)
|
77
|
+
if respond_to?(:log_fatal)
|
78
|
+
log_fatal("Context Repository must support graph_name", exception: ContextError)
|
79
|
+
else
|
80
|
+
abort("Context Repository must support graph_name")
|
81
|
+
end
|
82
|
+
end
|
75
83
|
@repository = repo
|
76
84
|
end
|
77
85
|
|
@@ -87,18 +95,22 @@ module RDF::RDFa
|
|
87
95
|
cache[uri] = Struct.new(:prefixes, :terms, :vocabulary).new({}, {}, nil)
|
88
96
|
# Now do the actual load
|
89
97
|
cache[uri] = new(uri) do |context|
|
90
|
-
|
98
|
+
log_debug("process_context: retrieve context <#{uri}>") if respond_to?(:log_debug)
|
91
99
|
Context.load(uri)
|
92
|
-
context.parse(repository.query(
|
100
|
+
context.parse(repository.query(graph_name: uri))
|
93
101
|
end
|
94
102
|
rescue Exception => e
|
95
|
-
|
103
|
+
if respond_to?(:log_fatal)
|
104
|
+
log_error("Context #{uri}: #{e.message}")
|
105
|
+
else
|
106
|
+
abort("Context #{uri}: #{e.message}")
|
107
|
+
end
|
96
108
|
end
|
97
109
|
|
98
110
|
# Load context into repository
|
99
111
|
def self.load(uri)
|
100
112
|
uri = RDF::URI.intern(uri)
|
101
|
-
repository.load(uri.to_s, base_uri: uri,
|
113
|
+
repository.load(uri.to_s, base_uri: uri, graph_name: uri) unless repository.has_graph?(uri)
|
102
114
|
end
|
103
115
|
|
104
116
|
# @return [RDF::Repository]
|
@@ -146,12 +158,12 @@ module RDF::RDFa
|
|
146
158
|
# @param [RDF::Enumerable, Enumerator] enumerable
|
147
159
|
# @return [void] ignored
|
148
160
|
def parse(enumerable)
|
149
|
-
|
161
|
+
log_debug("process_context: parse context <#{uri}>") if respond_to?(:log_debug)
|
150
162
|
resource_info = {}
|
151
163
|
enumerable.each do |statement|
|
152
164
|
res = resource_info[statement.subject] ||= {}
|
153
165
|
next unless statement.object.is_a?(RDF::Literal)
|
154
|
-
|
166
|
+
log_debug("process_context: statement=#{statement.inspect}") if respond_to?(:log_debug)
|
155
167
|
%w(uri term prefix vocabulary).each do |term|
|
156
168
|
res[term] ||= statement.object.value if statement.predicate == RDF::RDFA[term]
|
157
169
|
end
|
@@ -164,7 +176,7 @@ module RDF::RDFa
|
|
164
176
|
term = res["term"]
|
165
177
|
prefix = res["prefix"]
|
166
178
|
vocab = res["vocabulary"]
|
167
|
-
|
179
|
+
log_debug("process_context: uri=#{uri.inspect}, term=#{term.inspect}, prefix=#{prefix.inspect}, vocabulary=#{vocab.inspect}") if respond_to?(:log_debug)
|
168
180
|
|
169
181
|
@vocabulary = vocab if vocab
|
170
182
|
|
data/lib/rdf/rdfa/context/xml.rb
CHANGED
@@ -7,6 +7,7 @@ class RDF::RDFa::Context
|
|
7
7
|
@_rdfa_1_1_prof ||= RDF::RDFa::Context.new(RDF::URI("http://www.w3.org/2011/rdfa-context/rdfa-1.1"), {
|
8
8
|
prefixes: {
|
9
9
|
cc: "http://creativecommons.org/ns#",
|
10
|
+
csvw: "http://www.w3.org/ns/csvw#",
|
10
11
|
ctag: "http://commontag.org/ns#",
|
11
12
|
dc: "http://purl.org/dc/terms/",
|
12
13
|
dc11: "http://purl.org/dc/elements/1.1/",
|
data/lib/rdf/rdfa/format.rb
CHANGED
@@ -19,7 +19,9 @@ module RDF::RDFa
|
|
19
19
|
# @see http://www.w3.org/TR/rdf-testcases/#ntriples
|
20
20
|
class Format < RDF::Format
|
21
21
|
content_encoding 'utf-8'
|
22
|
-
content_type 'text/html',
|
22
|
+
content_type 'text/html',
|
23
|
+
aliases: %w(application/xhtml+xml image/svg+xml),
|
24
|
+
extensions: [:html, :xhtml, :svg]
|
23
25
|
reader { RDF::RDFa::Reader }
|
24
26
|
writer { RDF::RDFa::Writer }
|
25
27
|
|
@@ -37,65 +39,9 @@ module RDF::RDFa
|
|
37
39
|
sample.match(/<[^>]*DOCTYPE\s+html[^>]*>.*xmlns:/im)
|
38
40
|
) && !sample.match(/<(\w+:)?(RDF)/)
|
39
41
|
end
|
40
|
-
end
|
41
|
-
|
42
|
-
# Aliases for RDFa::Format
|
43
|
-
#
|
44
|
-
# This allows the following:
|
45
|
-
#
|
46
|
-
# @example Obtaining an HTML format class
|
47
|
-
# RDF::Format.for(:lite) # RDF::RDFa::Lite
|
48
|
-
# RDF::Format.for(:lite).reader # RDF::RDFa::Reader
|
49
|
-
# RDF::Format.for(:lite).writer # RDF::RDFa::Writer
|
50
|
-
class Lite < RDF::Format
|
51
|
-
content_encoding 'utf-8'
|
52
|
-
content_type 'text/html', extension: :html
|
53
|
-
reader { RDF::RDFa::Reader }
|
54
|
-
writer { RDF::RDFa::Writer }
|
55
|
-
end
|
56
|
-
|
57
|
-
# Aliases for RDFa::Format
|
58
|
-
#
|
59
|
-
# This allows the following:
|
60
|
-
#
|
61
|
-
# @example Obtaining an HTML format class
|
62
|
-
# RDF::Format.for(:html) # RDF::RDFa::HTML
|
63
|
-
# RDF::Format.for(:html).reader # RDF::RDFa::Reader
|
64
|
-
# RDF::Format.for(:html).writer # RDF::RDFa::Writer
|
65
|
-
class HTML < RDF::Format
|
66
|
-
content_encoding 'utf-8'
|
67
|
-
content_type 'text/html', extension: :html
|
68
|
-
reader { RDF::RDFa::Reader }
|
69
|
-
writer { RDF::RDFa::Writer }
|
70
|
-
end
|
71
|
-
|
72
|
-
# Aliases for RDFa::Format
|
73
|
-
#
|
74
|
-
# This allows the following:
|
75
|
-
#
|
76
|
-
# @example Obtaining an HTML format class
|
77
|
-
# RDF::Format.for(:xhtml) # RDF::RDFa::XHTML
|
78
|
-
# RDF::Format.for(:xhtml).reader # RDF::RDFa::Reader
|
79
|
-
# RDF::Format.for(:xhtml).writer # RDF::RDFa::Writer
|
80
|
-
class XHTML < RDF::Format
|
81
|
-
content_encoding 'utf-8'
|
82
|
-
content_type 'application/xhtml+xml', extension: :xhtml
|
83
|
-
reader { RDF::RDFa::Reader }
|
84
|
-
writer { RDF::RDFa::Writer }
|
85
|
-
end
|
86
42
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
#
|
91
|
-
# @example Obtaining an HTML format class
|
92
|
-
# RDF::Format.for(:svg) # RDF::RDFa::SVG
|
93
|
-
# RDF::Format.for(:svg).reader # RDF::RDFa::Reader
|
94
|
-
# RDF::Format.for(:svg).writer # RDF::RDFa::Writer
|
95
|
-
class SVG < RDF::Format
|
96
|
-
content_encoding 'utf-8'
|
97
|
-
content_type 'image/svg+xml', extension: :svg
|
98
|
-
reader { RDF::RDFa::Reader }
|
99
|
-
writer { RDF::RDFa::Writer }
|
43
|
+
def self.symbols
|
44
|
+
[:rdfa, :lite, :html, :xhtml, :svg]
|
45
|
+
end
|
100
46
|
end
|
101
47
|
end
|
data/lib/rdf/rdfa/reader.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
begin
|
2
2
|
require 'nokogiri'
|
3
|
-
rescue LoadError
|
3
|
+
rescue LoadError
|
4
4
|
:rexml
|
5
5
|
end
|
6
6
|
require 'rdf/ntriples'
|
@@ -28,6 +28,7 @@ module RDF::RDFa
|
|
28
28
|
class Reader < RDF::Reader
|
29
29
|
format Format
|
30
30
|
include Expansion
|
31
|
+
include RDF::Util::Logger
|
31
32
|
|
32
33
|
XHTML = "http://www.w3.org/1999/xhtml"
|
33
34
|
|
@@ -99,16 +100,6 @@ module RDF::RDFa
|
|
99
100
|
# @return [Module]
|
100
101
|
attr_reader :implementation
|
101
102
|
|
102
|
-
##
|
103
|
-
# Warnings found during processing
|
104
|
-
# @return [Array<String>]
|
105
|
-
attr_reader :warnings
|
106
|
-
|
107
|
-
##
|
108
|
-
# Accumulated errors found during processing
|
109
|
-
# @return [Array<String>]
|
110
|
-
attr_reader :errors
|
111
|
-
|
112
103
|
# The Recursive Baggage
|
113
104
|
# @private
|
114
105
|
class EvaluationContext # :nodoc:
|
@@ -252,6 +243,31 @@ module RDF::RDFa
|
|
252
243
|
end
|
253
244
|
end
|
254
245
|
|
246
|
+
##
|
247
|
+
# RDFa Reader options
|
248
|
+
# @see http://www.rubydoc.info/github/ruby-rdf/rdf/RDF/Reader#options-class_method
|
249
|
+
def self.options
|
250
|
+
super + [
|
251
|
+
RDF::CLI::Option.new(
|
252
|
+
symbol: :vocab_expansion,
|
253
|
+
datatype: TrueClass,
|
254
|
+
on: ["--vocab-expansion"],
|
255
|
+
description: "Perform OWL2 expansion on the resulting graph.") {true},
|
256
|
+
RDF::CLI::Option.new(
|
257
|
+
symbol: :host_language,
|
258
|
+
datatype: %w(xml xhtml1 xhtml5 html4 svg),
|
259
|
+
on: ["--host-language HOSTLANG", %w(xml xhtml1 xhtml5 html4 svg)],
|
260
|
+
description: "Host Language. One of xml, xhtml1, xhtml5, html4, or svg") do |arg|
|
261
|
+
arg.to_sym
|
262
|
+
end,
|
263
|
+
RDF::CLI::Option.new(
|
264
|
+
symbol: :rdfagraph,
|
265
|
+
datatype: %w(output processor both),
|
266
|
+
on: ["--rdfagraph RDFAGRAPH", %w(output processor both)],
|
267
|
+
description: "Used to indicate if either or both of the :output or :processor graphs are output.") {|arg| arg.to_sym},
|
268
|
+
]
|
269
|
+
end
|
270
|
+
|
255
271
|
##
|
256
272
|
# Initializes the RDFa reader instance.
|
257
273
|
#
|
@@ -276,12 +292,6 @@ module RDF::RDFa
|
|
276
292
|
# Value is an array containing on or both of :output or :processor.
|
277
293
|
# @option options [Repository] :vocab_repository (nil)
|
278
294
|
# Repository to save loaded vocabularies.
|
279
|
-
# @option options [Array] :errors
|
280
|
-
# array for placing errors found when parsing
|
281
|
-
# @option options [Array] :warnings
|
282
|
-
# array for placing warnings found when parsing
|
283
|
-
# @option options [Array] :debug
|
284
|
-
# Array to place debug messages
|
285
295
|
# @return [reader]
|
286
296
|
# @yield [reader] `self`
|
287
297
|
# @yieldparam [RDF::Reader] reader
|
@@ -289,13 +299,11 @@ module RDF::RDFa
|
|
289
299
|
# @raise [RDF::ReaderError] if _validate_
|
290
300
|
def initialize(input = $stdin, options = {}, &block)
|
291
301
|
super do
|
292
|
-
@errors = @options[:errors]
|
293
|
-
@warnings = @options[:warnings]
|
294
|
-
@debug = @options[:debug]
|
295
302
|
@options = {reference_folding: true}.merge(@options)
|
296
303
|
@repository = RDF::Repository.new
|
297
304
|
|
298
305
|
@options[:rdfagraph] = case @options[:rdfagraph]
|
306
|
+
when 'all' then [:output, :processor]
|
299
307
|
when String, Symbol then @options[:rdfagraph].to_s.split(',').map(&:strip).map(&:to_sym)
|
300
308
|
when Array then @options[:rdfagraph].map {|o| o.to_s.to_sym}
|
301
309
|
else []
|
@@ -396,9 +404,13 @@ module RDF::RDFa
|
|
396
404
|
|
397
405
|
if reader = RDF::Reader.for(content_type: type.to_s)
|
398
406
|
add_debug(el, "=> reader #{reader.to_sym}")
|
399
|
-
# Wrap input in a RemoteDocument with appropriate content-type
|
407
|
+
# Wrap input in a RemoteDocument with appropriate content-type and base
|
400
408
|
doc = if input.is_a?(String)
|
401
|
-
RDF::Util::File::RemoteDocument.new(input,
|
409
|
+
RDF::Util::File::RemoteDocument.new(input,
|
410
|
+
options.merge(
|
411
|
+
content_type: type.to_s,
|
412
|
+
base_uri: base_uri
|
413
|
+
))
|
402
414
|
else
|
403
415
|
input
|
404
416
|
end
|
@@ -457,6 +469,10 @@ module RDF::RDFa
|
|
457
469
|
yield RDF::Statement.new(*statement.to_triple) if @options[:rdfagraph].include?(:processor)
|
458
470
|
end
|
459
471
|
end
|
472
|
+
|
473
|
+
if validate? && log_statistics[:error]
|
474
|
+
raise RDF::ReaderError, "Errors found during processing"
|
475
|
+
end
|
460
476
|
end
|
461
477
|
enum_for(:each_statement)
|
462
478
|
end
|
@@ -496,30 +512,30 @@ module RDF::RDFa
|
|
496
512
|
# @param [#display_path, #to_s] node XML Node or string for showing context
|
497
513
|
# @param [String] message
|
498
514
|
# @yieldreturn [String] appended to message, to allow for lazy-evaulation of message
|
499
|
-
def add_debug(node, message = "")
|
500
|
-
|
501
|
-
message = message + yield if block_given?
|
502
|
-
add_processor_message(node, message, RDF::RDFA.Info)
|
515
|
+
def add_debug(node, message = "", &block)
|
516
|
+
add_processor_message(node, message, nil, &block)
|
503
517
|
end
|
504
518
|
|
505
|
-
def add_info(node, message, process_class = RDF::RDFA.Info)
|
506
|
-
add_processor_message(node, message, process_class)
|
519
|
+
def add_info(node, message, process_class = RDF::RDFA.Info, &block)
|
520
|
+
add_processor_message(node, message, process_class, &block)
|
507
521
|
end
|
508
522
|
|
509
523
|
def add_warning(node, message, process_class = RDF::RDFA.Warning)
|
510
|
-
@warnings << "#{node_path(node)}: #{message}" if @warnings
|
511
524
|
add_processor_message(node, message, process_class)
|
512
525
|
end
|
513
526
|
|
514
527
|
def add_error(node, message, process_class = RDF::RDFA.Error)
|
515
|
-
@errors << "#{node_path(node)}: #{message}" if @errors
|
516
528
|
add_processor_message(node, message, process_class)
|
517
|
-
raise RDF::ReaderError, message if validate?
|
518
529
|
end
|
519
530
|
|
520
|
-
def add_processor_message(node, message, process_class)
|
521
|
-
|
522
|
-
|
531
|
+
def add_processor_message(node, message, process_class, &block)
|
532
|
+
case process_class
|
533
|
+
when RDF::RDFA.Error then log_error(node_path(node), message, &block)
|
534
|
+
when RDF::RDFA.Warning then log_warn(node_path(node), message, &block)
|
535
|
+
when RDF::RDFA.Info then log_info(node_path(node), message, &block)
|
536
|
+
else log_debug(node_path(node), message, &block)
|
537
|
+
end
|
538
|
+
process_class ||= RDF::RDFA.Info
|
523
539
|
if @options[:processor_callback] || @options[:rdfagraph].include?(:processor)
|
524
540
|
n = RDF::Node.new
|
525
541
|
processor_statements = [
|
@@ -605,10 +621,10 @@ module RDF::RDFa
|
|
605
621
|
next
|
606
622
|
end
|
607
623
|
|
608
|
-
|
624
|
+
old_logger = @options[:logger]
|
609
625
|
begin
|
610
626
|
add_info(root, "load_initial_contexts: load #{uri.to_base}")
|
611
|
-
|
627
|
+
@options[:logger] = false
|
612
628
|
context = Context.find(uri)
|
613
629
|
|
614
630
|
# Add URI Mappings to prefixes
|
@@ -619,11 +635,11 @@ module RDF::RDFa
|
|
619
635
|
yield :term_mappings, context.terms unless context.terms.empty?
|
620
636
|
yield :default_vocabulary, context.vocabulary if context.vocabulary
|
621
637
|
rescue Exception => e
|
622
|
-
|
638
|
+
options[:logger] = old_logger
|
623
639
|
add_error(root, e.message)
|
624
640
|
raise # In case we're not in strict mode, we need to be sure processing stops
|
625
641
|
ensure
|
626
|
-
|
642
|
+
@options[:logger] = old_logger
|
627
643
|
end
|
628
644
|
end
|
629
645
|
end
|
@@ -1174,7 +1190,7 @@ module RDF::RDFa
|
|
1174
1190
|
add_debug(element, "[Step 11] value literal (#{attrs[:value]})")
|
1175
1191
|
v = attrs[:value].to_s
|
1176
1192
|
# Figure it out by parsing
|
1177
|
-
dt_lit = %w(Integer
|
1193
|
+
dt_lit = %w(Integer Decimal Double).map {|t| RDF::Literal.const_get(t)}.detect do |dt|
|
1178
1194
|
v.match(dt::GRAMMAR)
|
1179
1195
|
end || RDF::Literal
|
1180
1196
|
dt_lit.new(v)
|
@@ -280,7 +280,7 @@ module RDF::RDFa
|
|
280
280
|
# Document errors
|
281
281
|
def doc_errors
|
282
282
|
# FIXME: Nokogiri version 1.5.5 thinks many HTML5 elements are invalid
|
283
|
-
@doc.errors.reject {|e| e.to_s =~ /(Tag (?:article|aside|audio|canvas|command|
|
283
|
+
@doc.errors.reject {|e| e.to_s =~ /(Tag (?:article|aside|audio|canvas|command|datalist|details|embed|figcaption|figure|footer|header|hgroup|keygen|main|mark|meter|nav|output|progress|ruby|section|time|video|wbr) invalid|Missing attribute name)/}
|
284
284
|
end
|
285
285
|
|
286
286
|
##
|
data/lib/rdf/rdfa/writer.rb
CHANGED
@@ -49,6 +49,7 @@ module RDF::RDFa
|
|
49
49
|
# @author [Gregg Kellogg](http://kellogg-assoc.com/)
|
50
50
|
class Writer < RDF::Writer
|
51
51
|
format RDF::RDFa::Format
|
52
|
+
include RDF::Util::Logger
|
52
53
|
|
53
54
|
# Defines rdf:type of subjects to be emitted at the beginning of the document.
|
54
55
|
# @return [Array<URI>]
|
@@ -62,8 +63,9 @@ module RDF::RDFa
|
|
62
63
|
# @return [Array<URI>]
|
63
64
|
attr :heading_predicates
|
64
65
|
|
65
|
-
|
66
|
-
|
66
|
+
HAML_OPTIONS = {
|
67
|
+
ugly: false, # to preserve whitespace without using entities
|
68
|
+
}
|
67
69
|
|
68
70
|
# @return [Graph] Graph of statements serialized
|
69
71
|
attr_accessor :graph
|
@@ -71,6 +73,19 @@ module RDF::RDFa
|
|
71
73
|
# @return [RDF::URI] Base URI used for relativizing URIs
|
72
74
|
attr_accessor :base_uri
|
73
75
|
|
76
|
+
##
|
77
|
+
# RDFa Writer options
|
78
|
+
# @see http://www.rubydoc.info/github/ruby-rdf/rdf/RDF/Writer#options-class_method
|
79
|
+
def self.options
|
80
|
+
super + [
|
81
|
+
RDF::CLI::Option.new(
|
82
|
+
symbol: :lang,
|
83
|
+
datatype: String,
|
84
|
+
on: ["--lang"],
|
85
|
+
description: "Output as root @lang attribute, and avoid generation _@lang_ where possible."),
|
86
|
+
]
|
87
|
+
end
|
88
|
+
|
74
89
|
##
|
75
90
|
# Initializes the RDFa writer instance.
|
76
91
|
#
|
@@ -124,25 +139,6 @@ module RDF::RDFa
|
|
124
139
|
end
|
125
140
|
end
|
126
141
|
|
127
|
-
##
|
128
|
-
# Write whole graph
|
129
|
-
#
|
130
|
-
# @param [Graph] graph
|
131
|
-
# @return [void]
|
132
|
-
def write_graph(graph)
|
133
|
-
@graph = graph
|
134
|
-
end
|
135
|
-
|
136
|
-
##
|
137
|
-
# Addes a statement to be serialized
|
138
|
-
# @param [RDF::Statement] statement
|
139
|
-
# @return [void]
|
140
|
-
# @raise [RDF::WriterError] if validating and attempting to write an invalid {RDF::Term}.
|
141
|
-
def write_statement(statement)
|
142
|
-
raise RDF::WriterError, "Statement #{statement.inspect} is invalid" if validate? && statement.invalid?
|
143
|
-
@graph.insert(statement)
|
144
|
-
end
|
145
|
-
|
146
142
|
##
|
147
143
|
# Addes a triple to be serialized
|
148
144
|
# @param [RDF::Resource] subject
|
@@ -153,7 +149,7 @@ module RDF::RDFa
|
|
153
149
|
# @abstract
|
154
150
|
# @raise [RDF::WriterError] if validating and attempting to write an invalid {RDF::Term}.
|
155
151
|
def write_triple(subject, predicate, object)
|
156
|
-
|
152
|
+
@graph.insert(RDF::Statement(subject, predicate, object))
|
157
153
|
end
|
158
154
|
|
159
155
|
##
|
@@ -163,16 +159,15 @@ module RDF::RDFa
|
|
163
159
|
def write_epilogue
|
164
160
|
@base_uri = RDF::URI(@options[:base_uri]) if @options[:base_uri]
|
165
161
|
@lang = @options[:lang]
|
166
|
-
@debug = @options[:debug]
|
167
162
|
self.reset
|
168
163
|
|
169
|
-
|
164
|
+
log_debug {"\nserialize: graph size: #{@graph.size}"}
|
170
165
|
|
171
166
|
preprocess
|
172
167
|
|
173
168
|
# Prefixes
|
174
169
|
prefix = prefixes.keys.map {|pk| "#{pk}: #{prefixes[pk]}"}.sort.join(" ") unless prefixes.empty?
|
175
|
-
|
170
|
+
log_debug {"\nserialize: prefixes: #{prefix.inspect}"}
|
176
171
|
|
177
172
|
subjects = order_subjects
|
178
173
|
|
@@ -196,6 +191,8 @@ module RDF::RDFa
|
|
196
191
|
subject(s)
|
197
192
|
end
|
198
193
|
@output.write(doc)
|
194
|
+
|
195
|
+
super
|
199
196
|
end
|
200
197
|
|
201
198
|
protected
|
@@ -307,7 +304,7 @@ module RDF::RDFa
|
|
307
304
|
# @return String
|
308
305
|
# The rendered document is returned as a string
|
309
306
|
def render_property(predicate, objects, options = {}, &block)
|
310
|
-
|
307
|
+
log_debug {"render_property(#{predicate}): #{objects.inspect}, #{options.inspect}"}
|
311
308
|
# If there are multiple objects, and no :property_values is defined, call recursively with
|
312
309
|
# each object
|
313
310
|
|
@@ -317,19 +314,19 @@ module RDF::RDFa
|
|
317
314
|
# Separate out the objects which are lists and render separately
|
318
315
|
list_objects = objects.reject do |o|
|
319
316
|
o == RDF.nil ||
|
320
|
-
(l = RDF::List.new(o, @graph)).invalid?
|
317
|
+
(l = RDF::List.new(subject: o, graph: @graph)).invalid?
|
321
318
|
end
|
322
319
|
unless list_objects.empty?
|
323
320
|
# Render non-list objects
|
324
|
-
|
325
|
-
nl =
|
321
|
+
log_debug {"properties with lists: #{list_objects} non-lists: #{objects - list_objects}"}
|
322
|
+
nl = log_depth {render_property(predicate, objects - list_objects, options, &block)} unless objects == list_objects
|
326
323
|
return nl.to_s + list_objects.map do |object|
|
327
324
|
# Render each list as multiple properties and set :inlist to true
|
328
|
-
list = RDF::List.new(object, @graph)
|
325
|
+
list = RDF::List.new(subject: object, graph: @graph)
|
329
326
|
list.each_statement {|st| subject_done(st.subject)}
|
330
327
|
|
331
|
-
|
332
|
-
|
328
|
+
log_debug {"list: #{list.inspect} #{list.to_a}"}
|
329
|
+
log_depth do
|
333
330
|
render_property(predicate, list.to_a, options.merge(inlist: "true")) do |object|
|
334
331
|
yield(object, true) if block_given?
|
335
332
|
end
|
@@ -340,10 +337,10 @@ module RDF::RDFa
|
|
340
337
|
if objects.length > 1 && template.nil?
|
341
338
|
# If there is no property_values template, render each property using property_value template
|
342
339
|
objects.map do |object|
|
343
|
-
|
340
|
+
log_depth {render_property(predicate, [object], options, &block)}
|
344
341
|
end.join(" ")
|
345
342
|
else
|
346
|
-
|
343
|
+
log_fatal("Missing property template", exception: RDF::WriterError) if template.nil?
|
347
344
|
|
348
345
|
template = options[:haml] || (
|
349
346
|
objects.to_a.length > 1 &&
|
@@ -410,7 +407,7 @@ module RDF::RDFa
|
|
410
407
|
select {|s| !seen.include?(s)}.
|
411
408
|
each do |class_uri|
|
412
409
|
graph.query(predicate: RDF.type, object: class_uri).map {|st| st.subject}.sort.uniq.each do |subject|
|
413
|
-
#
|
410
|
+
#log_debug {"order_subjects: #{subject.inspect}"}
|
414
411
|
subjects << subject
|
415
412
|
seen[subject] = true
|
416
413
|
end
|
@@ -422,7 +419,7 @@ module RDF::RDFa
|
|
422
419
|
map {|r| [r.is_a?(RDF::Node) ? 1 : 0, ref_count(r), r]}.
|
423
420
|
sort
|
424
421
|
|
425
|
-
|
422
|
+
log_debug {"order_subjects: #{recursable.inspect}"}
|
426
423
|
|
427
424
|
subjects += recursable.map{|r| r.last}
|
428
425
|
end
|
@@ -446,7 +443,7 @@ module RDF::RDFa
|
|
446
443
|
prop_list << prop.to_s
|
447
444
|
end
|
448
445
|
|
449
|
-
|
446
|
+
log_debug {"order_properties: #{prop_list.join(', ')}"}
|
450
447
|
prop_list
|
451
448
|
end
|
452
449
|
|
@@ -454,7 +451,7 @@ module RDF::RDFa
|
|
454
451
|
# @param [RDF::Statement] statement
|
455
452
|
# @return [ignored]
|
456
453
|
def preprocess_statement(statement)
|
457
|
-
#
|
454
|
+
#log_debug {"preprocess: #{statement.inspect}"}
|
458
455
|
bump_reference(statement.object)
|
459
456
|
@subjects[statement.subject] = true
|
460
457
|
get_curie(statement.subject)
|
@@ -465,7 +462,7 @@ module RDF::RDFa
|
|
465
462
|
|
466
463
|
# Reset parser to run again
|
467
464
|
def reset
|
468
|
-
@
|
465
|
+
@options[:log_depth] = 0
|
469
466
|
prefixes = {}
|
470
467
|
@references = {}
|
471
468
|
@serialized = {}
|
@@ -502,7 +499,7 @@ module RDF::RDFa
|
|
502
499
|
typeof = type_of(properties.delete(RDF.type.to_s), subject)
|
503
500
|
prop_list = order_properties(properties)
|
504
501
|
|
505
|
-
|
502
|
+
log_debug {"props: #{prop_list.inspect}"}
|
506
503
|
|
507
504
|
render_opts = {typeof: typeof, property_values: properties}.merge(options)
|
508
505
|
|
@@ -539,7 +536,7 @@ module RDF::RDFa
|
|
539
536
|
# Nodes without a curie need a blank @typeof to generate a subject
|
540
537
|
typeof ||= "" unless curie
|
541
538
|
|
542
|
-
|
539
|
+
log_debug {"subject: #{curie.inspect}, typeof: #{typeof.inspect}" }
|
543
540
|
|
544
541
|
typeof.freeze
|
545
542
|
end
|
@@ -552,17 +549,17 @@ module RDF::RDFa
|
|
552
549
|
# See if there's a template based on the sorted concatenation of all types of this subject
|
553
550
|
# or any type of this subject
|
554
551
|
tmpl = find_template(subject)
|
555
|
-
|
552
|
+
log_debug {"subject: found template #{tmpl[:identifier] || tmpl.inspect}"} if tmpl
|
556
553
|
|
557
554
|
# Render this subject
|
558
555
|
# If :rel is specified and :typeof is nil, use @resource instead of @about.
|
559
556
|
# Pass other options from calling context
|
560
557
|
with_template(tmpl) do
|
561
558
|
render_subject(subject, prop_list, render_opts) do |pred|
|
562
|
-
|
559
|
+
log_depth do
|
563
560
|
pred = RDF::URI(pred) if pred.is_a?(String)
|
564
561
|
values = render_opts[:property_values][pred.to_s]
|
565
|
-
|
562
|
+
log_debug {"subject: #{get_curie(subject)}, pred: #{get_curie(pred)}, values: #{values.inspect}"}
|
566
563
|
predicate(pred, values)
|
567
564
|
end
|
568
565
|
end
|
@@ -578,15 +575,15 @@ module RDF::RDFa
|
|
578
575
|
# Objects to serialize
|
579
576
|
# @return [String]
|
580
577
|
def predicate(predicate, objects)
|
581
|
-
|
578
|
+
log_debug {"predicate: #{predicate.inspect}, objects: #{objects}"}
|
582
579
|
|
583
580
|
return if objects.to_a.empty?
|
584
581
|
|
585
|
-
|
582
|
+
log_debug {"predicate: #{get_curie(predicate)}"}
|
586
583
|
render_property(predicate, objects) do |o, inlist=nil|
|
587
584
|
# Yields each object, for potential recursive definition.
|
588
585
|
# If nil is returned, a leaf is produced
|
589
|
-
|
586
|
+
log_depth {subject(o, rel: get_curie(predicate), inlist: inlist, element: (:li if objects.length > 1 || inlist))} if !is_done?(o) && @subjects.include?(o)
|
590
587
|
end
|
591
588
|
end
|
592
589
|
|
@@ -596,8 +593,12 @@ module RDF::RDFa
|
|
596
593
|
# @return [String, nil]
|
597
594
|
# @raise [RDF::WriterError]
|
598
595
|
def get_dt_curie(literal)
|
599
|
-
|
600
|
-
|
596
|
+
if literal.is_a?(RDF::Literal)
|
597
|
+
get_curie(literal.datatype) if literal.literal? && literal.datatype?
|
598
|
+
else
|
599
|
+
log_error("Getting datatype CURIE for #{literal.inspect}, which must be a literal")
|
600
|
+
nil
|
601
|
+
end
|
601
602
|
end
|
602
603
|
|
603
604
|
# Haml rendering helper. Return language for plain literal, if there is no language, or it is the same as the document, return nil
|
@@ -606,8 +607,12 @@ module RDF::RDFa
|
|
606
607
|
# @return [Symbol, nil]
|
607
608
|
# @raise [RDF::WriterError]
|
608
609
|
def get_lang(literal)
|
609
|
-
|
610
|
-
|
610
|
+
if literal.is_a?(RDF::Literal)
|
611
|
+
literal.language if literal.literal? && literal.language && literal.language.to_s != @lang.to_s
|
612
|
+
else
|
613
|
+
log_error("Getting language for #{literal.inspect}, which must be a literal")
|
614
|
+
nil
|
615
|
+
end
|
611
616
|
end
|
612
617
|
|
613
618
|
# Haml rendering helper. Data to be added to a @content value, for specific datatypes
|
@@ -616,21 +621,28 @@ module RDF::RDFa
|
|
616
621
|
# @return [String, nil]
|
617
622
|
# @raise [RDF::WriterError]
|
618
623
|
def get_content(literal)
|
619
|
-
raise RDF::WriterError, "Getting content for #{literal.inspect}, which must be a literal" unless literal.is_a?(RDF::Literal)
|
620
624
|
case literal
|
621
625
|
when RDF::Literal::Date, RDF::Literal::Time, RDF::Literal::DateTime, RDF::Literal::Duration
|
622
626
|
literal.to_s
|
627
|
+
when RDF::Literal then nil
|
628
|
+
else
|
629
|
+
log_error("Getting content for #{literal.inspect}, which must be a literal")
|
630
|
+
nil
|
623
631
|
end
|
624
632
|
end
|
625
633
|
|
626
|
-
# Haml rendering helper. Display value for object, may be humanized into a non-canonical form
|
634
|
+
# Haml rendering helper. Display value for object, may be humanized into a non-canonical form
|
627
635
|
#
|
628
636
|
# @param [RDF::Literal] literal
|
629
637
|
# @return [String]
|
630
638
|
# @raise [RDF::WriterError]
|
631
639
|
def get_value(literal)
|
632
|
-
|
633
|
-
|
640
|
+
if literal.is_a?(RDF::Literal)
|
641
|
+
literal.humanize
|
642
|
+
else
|
643
|
+
log_error("Getting value for #{literal.inspect}, which must be a literal")
|
644
|
+
nil
|
645
|
+
end
|
634
646
|
end
|
635
647
|
|
636
648
|
# Haml rendering helper. Return an appropriate label for a resource.
|
@@ -639,8 +651,12 @@ module RDF::RDFa
|
|
639
651
|
# @return [String]
|
640
652
|
# @raise [RDF::WriterError]
|
641
653
|
def get_predicate_name(resource)
|
642
|
-
|
643
|
-
|
654
|
+
if resource.is_a?(RDF::URI)
|
655
|
+
get_curie(resource)
|
656
|
+
else
|
657
|
+
log_error("Getting predicate name for #{resource.inspect}, which must be a URI")
|
658
|
+
nil
|
659
|
+
end
|
644
660
|
end
|
645
661
|
|
646
662
|
# Haml rendering helper. Return appropriate, term, CURIE or URI for the given resource.
|
@@ -649,42 +665,50 @@ module RDF::RDFa
|
|
649
665
|
# @return [String] value to use to identify URI
|
650
666
|
# @raise [RDF::WriterError]
|
651
667
|
def get_curie(resource)
|
652
|
-
|
653
|
-
|
668
|
+
case resource
|
669
|
+
when RDF::URI
|
670
|
+
begin
|
671
|
+
uri = resource.to_s
|
672
|
+
|
673
|
+
curie = case
|
674
|
+
when @uri_to_term_or_curie.has_key?(uri)
|
675
|
+
log_debug {"get_curie(#{uri}): uri_to_term_or_curie #{@uri_to_term_or_curie[uri].inspect}"}
|
676
|
+
return @uri_to_term_or_curie[uri]
|
677
|
+
when base_uri && uri.index(base_uri.to_s) == 0
|
678
|
+
log_debug {"get_curie(#{uri}): base_uri (#{uri.sub(base_uri.to_s, "")})"}
|
679
|
+
uri.sub(base_uri.to_s, "")
|
680
|
+
when @vocabulary && uri.index(@vocabulary) == 0
|
681
|
+
log_debug {"get_curie(#{uri}): vocabulary"}
|
682
|
+
uri.sub(@vocabulary, "")
|
683
|
+
when u = @uri_to_prefix.keys.detect {|u| uri.index(u.to_s) == 0}
|
684
|
+
log_debug {"get_curie(#{uri}): uri_to_prefix"}
|
685
|
+
# Use a defined prefix
|
686
|
+
prefix = @uri_to_prefix[u]
|
687
|
+
prefix(prefix, u) # Define for output
|
688
|
+
uri.sub(u.to_s, "#{prefix}:")
|
689
|
+
when @options[:standard_prefixes] && vocab = RDF::Vocabulary.detect {|v| uri.index(v.to_uri.to_s) == 0}
|
690
|
+
log_debug {"get_curie(#{uri}): standard_prefixes"}
|
691
|
+
prefix = vocab.__name__.to_s.split('::').last.downcase
|
692
|
+
prefix(prefix, vocab.to_uri) # Define for output
|
693
|
+
uri.sub(vocab.to_uri.to_s, "#{prefix}:")
|
694
|
+
else
|
695
|
+
log_debug {"get_curie(#{uri}): none"}
|
696
|
+
uri
|
697
|
+
end
|
654
698
|
|
655
|
-
|
699
|
+
#log_debug {"get_curie(#{resource}) => #{curie}"}
|
656
700
|
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
when @vocabulary && uri.index(@vocabulary) == 0
|
665
|
-
add_debug {"get_curie(#{uri}): vocabulary"}
|
666
|
-
uri.sub(@vocabulary, "")
|
667
|
-
when u = @uri_to_prefix.keys.detect {|u| uri.index(u.to_s) == 0}
|
668
|
-
add_debug {"get_curie(#{uri}): uri_to_prefix"}
|
669
|
-
# Use a defined prefix
|
670
|
-
prefix = @uri_to_prefix[u]
|
671
|
-
prefix(prefix, u) # Define for output
|
672
|
-
uri.sub(u.to_s, "#{prefix}:")
|
673
|
-
when @options[:standard_prefixes] && vocab = RDF::Vocabulary.detect {|v| uri.index(v.to_uri.to_s) == 0}
|
674
|
-
add_debug {"get_curie(#{uri}): standard_prefixes"}
|
675
|
-
prefix = vocab.__name__.to_s.split('::').last.downcase
|
676
|
-
prefix(prefix, vocab.to_uri) # Define for output
|
677
|
-
uri.sub(vocab.to_uri.to_s, "#{prefix}:")
|
701
|
+
@uri_to_term_or_curie[uri] = curie
|
702
|
+
rescue ArgumentError => e
|
703
|
+
log_error("Invalid URI #{uri.inspect}: #{e.message}")
|
704
|
+
nil
|
705
|
+
end
|
706
|
+
when RDF::Node then resource.to_s
|
707
|
+
when RDF::Literal then nil
|
678
708
|
else
|
679
|
-
|
680
|
-
|
709
|
+
log_error("Getting CURIE for #{resource.inspect}, which must be a resource")
|
710
|
+
nil
|
681
711
|
end
|
682
|
-
|
683
|
-
#add_debug {"get_curie(#{resource}) => #{curie}"}
|
684
|
-
|
685
|
-
@uri_to_term_or_curie[uri] = curie
|
686
|
-
rescue ArgumentError => e
|
687
|
-
raise RDF::WriterError, "Invalid URI #{uri.inspect}: #{e.message}"
|
688
712
|
end
|
689
713
|
private
|
690
714
|
|
@@ -700,18 +724,6 @@ module RDF::RDFa
|
|
700
724
|
CGI.escapeHTML(str).gsub(/[\n\r]/) {|c| '&#x' + c.unpack('h').first + ';'}
|
701
725
|
end
|
702
726
|
|
703
|
-
# Increase depth around a method invocation
|
704
|
-
# @yield
|
705
|
-
# Yields with no arguments
|
706
|
-
# @yieldreturn [Object] returns the result of yielding
|
707
|
-
# @return [Object]
|
708
|
-
def depth
|
709
|
-
@depth += 1
|
710
|
-
ret = yield
|
711
|
-
@depth -= 1
|
712
|
-
ret
|
713
|
-
end
|
714
|
-
|
715
727
|
# Set the template to use within block
|
716
728
|
# @param [Hash{Symbol => String}] templ template to use for block evaluation; merged in with the existing template.
|
717
729
|
# @yield
|
@@ -743,20 +755,22 @@ module RDF::RDFa
|
|
743
755
|
# @return [String]
|
744
756
|
# @raise [RDF::WriterError]
|
745
757
|
def hamlify(template, locals = {})
|
746
|
-
|
758
|
+
log_debug {"hamlify template: #{template}"}
|
747
759
|
template = haml_template[template] if template.is_a?(Symbol)
|
748
760
|
|
749
761
|
template = template.align_left
|
750
|
-
|
762
|
+
log_debug {"hamlify locals: #{locals.inspect}"}
|
751
763
|
|
752
764
|
Haml::Engine.new(template, @options[:haml_options] || HAML_OPTIONS).render(self, locals) do |*args|
|
753
765
|
yield(*args) if block_given?
|
754
766
|
end
|
755
767
|
rescue Haml::Error => e
|
756
|
-
|
768
|
+
log_fatal("#{e.inspect}\n" +
|
757
769
|
"rendering #{template}\n" +
|
758
770
|
"with options #{(@options[:haml_options] || HAML_OPTIONS).inspect}\n" +
|
759
|
-
"and locals #{locals.inspect}"
|
771
|
+
"and locals #{locals.inspect}",
|
772
|
+
exception: RDF::WriterError
|
773
|
+
)
|
760
774
|
end
|
761
775
|
|
762
776
|
##
|
@@ -794,18 +808,6 @@ module RDF::RDFa
|
|
794
808
|
def ref_count(node)
|
795
809
|
@references.fetch(node, 0)
|
796
810
|
end
|
797
|
-
|
798
|
-
# Add debug event to debug array, if specified
|
799
|
-
#
|
800
|
-
# @param [String] message
|
801
|
-
# @yieldreturn [String] appended to message, to allow for lazy-evaulation of message
|
802
|
-
def add_debug(message = "")
|
803
|
-
return unless ::RDF::RDFa.debug? || @debug
|
804
|
-
message = message + yield if block_given?
|
805
|
-
msg = "#{' ' * @depth}#{message}"
|
806
|
-
STDERR.puts msg if ::RDF::RDFa.debug?
|
807
|
-
@debug << msg.force_encoding("utf-8") if @debug.is_a?(Array)
|
808
|
-
end
|
809
811
|
end
|
810
812
|
end
|
811
813
|
|