roadforest 0.0.3 → 0.1
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.
- checksums.yaml +7 -0
- data/examples/file-management.rb +7 -9
- data/lib/roadforest/application/dispatcher.rb +44 -31
- data/lib/roadforest/application/parameters.rb +5 -4
- data/lib/roadforest/application/path-provider.rb +14 -1
- data/lib/roadforest/application/route-adapter.rb +15 -4
- data/lib/roadforest/application/services-host.rb +41 -7
- data/lib/roadforest/application.rb +4 -8
- data/lib/roadforest/authorization.rb +231 -0
- data/lib/roadforest/blob-model.rb +2 -11
- data/lib/roadforest/content-handling/engine.rb +12 -6
- data/lib/roadforest/content-handling/handler-wrap.rb +45 -0
- data/lib/roadforest/content-handling/media-type.rb +20 -12
- data/lib/roadforest/content-handling/type-handler.rb +76 -0
- data/lib/roadforest/content-handling/type-handlers/jsonld.rb +2 -146
- data/lib/roadforest/content-handling/type-handlers/rdf-handler.rb +38 -0
- data/lib/roadforest/content-handling/type-handlers/rdfa-writer/document-environment.rb +34 -0
- data/lib/roadforest/content-handling/type-handlers/rdfa-writer/object-environment.rb +62 -0
- data/lib/roadforest/content-handling/type-handlers/rdfa-writer/property-environment.rb +46 -0
- data/lib/roadforest/content-handling/type-handlers/rdfa-writer/render-engine.rb +574 -0
- data/lib/roadforest/content-handling/type-handlers/rdfa-writer/render-environment.rb +144 -0
- data/lib/roadforest/content-handling/type-handlers/rdfa-writer/subject-environment.rb +80 -0
- data/lib/roadforest/content-handling/type-handlers/rdfa-writer.rb +163 -0
- data/lib/roadforest/content-handling/type-handlers/rdfa.rb +175 -0
- data/lib/roadforest/content-handling/type-handlers/rdfpost.rb +297 -0
- data/lib/roadforest/debug.rb +10 -0
- data/lib/roadforest/http/graph-response.rb +3 -7
- data/lib/roadforest/http/graph-transfer.rb +28 -106
- data/lib/roadforest/http/keychain.rb +79 -0
- data/lib/roadforest/http/message.rb +9 -1
- data/lib/roadforest/http/user-agent.rb +115 -0
- data/lib/roadforest/http.rb +8 -0
- data/lib/roadforest/model.rb +48 -3
- data/lib/roadforest/rdf/graph-focus.rb +5 -3
- data/lib/roadforest/rdf/graph-store.rb +4 -2
- data/lib/roadforest/rdf/normalization.rb +6 -1
- data/lib/roadforest/remote-host.rb +22 -7
- data/lib/roadforest/resource/rdf/read-only.rb +15 -1
- data/lib/roadforest/templates/base/doc.haml +13 -0
- data/lib/roadforest/templates/base/property_value.haml +12 -0
- data/lib/roadforest/templates/base/property_values.haml +6 -0
- data/lib/roadforest/templates/base/subject.haml +4 -0
- data/lib/roadforest/templates/distiller/doc.haml +20 -0
- data/lib/roadforest/templates/distiller/nil-object.haml +1 -0
- data/lib/roadforest/templates/distiller/property_value.haml +7 -0
- data/lib/roadforest/templates/distiller/property_values.haml +7 -0
- data/lib/roadforest/templates/distiller/subject.haml +5 -0
- data/lib/roadforest/templates/min/doc.haml +10 -0
- data/lib/roadforest/templates/min/property_values.haml +7 -0
- data/lib/roadforest/templates/min/subject.haml +2 -0
- data/lib/roadforest/templates/nil-object.haml +0 -0
- data/lib/roadforest/templates/node-object.haml +1 -0
- data/lib/roadforest/templates/object.haml +1 -0
- data/lib/roadforest/templates/uri-object.haml +1 -0
- data/lib/roadforest/templates/xml-literal-object.haml +1 -0
- data/lib/roadforest/utility/class-registry.rb +4 -0
- data/spec/client.rb +119 -77
- data/spec/{excon-adapater.rb → excon-adapter.rb} +4 -0
- data/spec/full-integration.rb +6 -2
- data/spec/graph-store.rb +1 -1
- data/spec/media-types.rb +29 -2
- metadata +102 -125
@@ -0,0 +1,574 @@
|
|
1
|
+
require 'roadforest/content-handling/type-handlers/rdfa-writer'
|
2
|
+
require 'roadforest/content-handling/type-handlers/rdfa-writer/document-environment'
|
3
|
+
require 'roadforest/content-handling/type-handlers/rdfa-writer/subject-environment'
|
4
|
+
require 'roadforest/content-handling/type-handlers/rdfa-writer/property-environment'
|
5
|
+
require 'roadforest/content-handling/type-handlers/rdfa-writer/object-environment'
|
6
|
+
require 'haml'
|
7
|
+
|
8
|
+
module RoadForest::MediaType
|
9
|
+
class RDFaWriter
|
10
|
+
class RenderEngine
|
11
|
+
# Defines rdf:type of subjects to be emitted at the beginning of the
|
12
|
+
# document.
|
13
|
+
# @return [Array<URI>]
|
14
|
+
attr_accessor :top_classes
|
15
|
+
|
16
|
+
# Defines order of predicates to to emit at begninning of a resource description. Defaults to `[rdf:type, rdfs:label, dc:title]`
|
17
|
+
# @return [Array<URI>]
|
18
|
+
attr_accessor :predicate_order
|
19
|
+
|
20
|
+
# Defines order of predicates to use in heading.
|
21
|
+
# @return [Array<URI>]
|
22
|
+
attr_accessor :heading_predicates
|
23
|
+
|
24
|
+
attr_accessor :prefixes, :base_uri, :lang, :standard_prefixes, :graph, :titles, :doc_title
|
25
|
+
attr_accessor :valise, :resource_name, :style_name, :template_cache, :haml_options
|
26
|
+
attr_reader :debug
|
27
|
+
|
28
|
+
def initialize(graph, debug=nil)
|
29
|
+
@debug = debug
|
30
|
+
@graph = graph
|
31
|
+
|
32
|
+
reset
|
33
|
+
|
34
|
+
yield self
|
35
|
+
|
36
|
+
setup
|
37
|
+
end
|
38
|
+
|
39
|
+
# Reset parser to run again
|
40
|
+
def reset
|
41
|
+
@debug_indent = 0
|
42
|
+
@uri_to_term_or_curie = {}
|
43
|
+
@uri_to_prefix = {}
|
44
|
+
@references = Hash.new{|h,k| h[k] = 0}
|
45
|
+
@prefixes = {}
|
46
|
+
@serialized = {}
|
47
|
+
@subjects = {}
|
48
|
+
@ordered_subjects = []
|
49
|
+
@titles = {}
|
50
|
+
@doc_title = ""
|
51
|
+
end
|
52
|
+
|
53
|
+
def template_cache
|
54
|
+
@template_cache ||= ::Tilt::Cache.new
|
55
|
+
end
|
56
|
+
|
57
|
+
def style_name
|
58
|
+
@style_name ||= "base"
|
59
|
+
end
|
60
|
+
|
61
|
+
def setup_env(env)
|
62
|
+
env.heading_predicates = heading_predicates
|
63
|
+
env.lang = lang
|
64
|
+
end
|
65
|
+
|
66
|
+
# Increase depth around a method invocation
|
67
|
+
# @yield
|
68
|
+
# Yields with no arguments
|
69
|
+
# @yieldreturn [Object] returns the result of yielding
|
70
|
+
# @return [Object]
|
71
|
+
def depth
|
72
|
+
@debug_indent += 1
|
73
|
+
ret = yield
|
74
|
+
@debug_indent -= 1
|
75
|
+
ret
|
76
|
+
end
|
77
|
+
|
78
|
+
def templates
|
79
|
+
@templates ||= [resource_name, style_name, nil].uniq.map do |name|
|
80
|
+
valise.sub_set(["templates", name].compact.join("/"))
|
81
|
+
end.inject do |left, right|
|
82
|
+
left + right
|
83
|
+
end.handle_templates do |config|
|
84
|
+
config.add_type("haml", { :template_cache => template_cache, :template_options => haml_options })
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
##
|
89
|
+
# Find a template appropriate for the subject.
|
90
|
+
# Override this method to provide templates based on attributes of a given subject
|
91
|
+
#
|
92
|
+
# @param [RDF::URI] subject
|
93
|
+
# @return [Hash] # return matched matched template
|
94
|
+
def find_template(kinds)
|
95
|
+
kind = kinds.shift
|
96
|
+
templates.contents(kind)
|
97
|
+
rescue Valise::Errors::NotFound
|
98
|
+
if kinds.empty?
|
99
|
+
raise RDF::WriterError, "Missing template for #{context.class.name}" if template.nil?
|
100
|
+
else
|
101
|
+
retry
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def find_environment_template(env)
|
106
|
+
find_template(env.template_kinds)
|
107
|
+
end
|
108
|
+
|
109
|
+
# Increase the reference count of this resource
|
110
|
+
# @param [RDF::Resource] resource
|
111
|
+
# @return [Integer] resulting reference count
|
112
|
+
def bump_reference(resource)
|
113
|
+
@references[resource] += 1
|
114
|
+
end
|
115
|
+
|
116
|
+
# Return the number of times this node has been referenced in the object position
|
117
|
+
# @param [RDF::Node] node
|
118
|
+
# @return [Boolean]
|
119
|
+
def ref_count(node)
|
120
|
+
@references[node]
|
121
|
+
end
|
122
|
+
|
123
|
+
# Add debug event to debug array, if specified
|
124
|
+
#
|
125
|
+
# @param [String] message
|
126
|
+
# @yieldreturn [String] appended to message, to allow for lazy-evaulation of message
|
127
|
+
def add_debug(message = nil)
|
128
|
+
return unless ::RoadForest.debug_io || @debug
|
129
|
+
message ||= ""
|
130
|
+
message = message + yield if block_given?
|
131
|
+
msg = "#{' ' * @debug_indent}#{message}"
|
132
|
+
RoadForest::debug(msg)
|
133
|
+
@debug << msg.force_encoding("utf-8") if @debug.is_a?(Array)
|
134
|
+
end
|
135
|
+
|
136
|
+
def setup
|
137
|
+
add_debug {"\nserialize setup: graph size: #{@graph.size}"}
|
138
|
+
|
139
|
+
preprocess
|
140
|
+
|
141
|
+
@ordered_subjects = order_subjects
|
142
|
+
|
143
|
+
# Take title from first subject having a heading predicate
|
144
|
+
@doc_title = nil
|
145
|
+
heading_predicates.each do |pred|
|
146
|
+
@graph.query(:predicate => pred) do |statement|
|
147
|
+
titles[statement.subject] ||= statement.object
|
148
|
+
end
|
149
|
+
end
|
150
|
+
title_subject = @ordered_subjects.detect {|subject| titles[subject]}
|
151
|
+
@doc_title = titles[title_subject]
|
152
|
+
end
|
153
|
+
|
154
|
+
# Perform any preprocessing of statements required
|
155
|
+
# @return [ignored]
|
156
|
+
def preprocess
|
157
|
+
# Load initial contexts
|
158
|
+
# Add terms and prefixes to local store for converting URIs
|
159
|
+
# Keep track of vocabulary from left-most context
|
160
|
+
[RDF::RDFa::XML_RDFA_CONTEXT, RDF::RDFa::HTML_RDFA_CONTEXT].each do |uri|
|
161
|
+
ctx = RDF::RDFa::Context.find(uri)
|
162
|
+
ctx.prefixes.each_pair do |k, v|
|
163
|
+
@uri_to_prefix[v] = k unless k.to_s == "dcterms"
|
164
|
+
end
|
165
|
+
|
166
|
+
ctx.terms.each_pair do |k, v|
|
167
|
+
@uri_to_term_or_curie[v] = k
|
168
|
+
end
|
169
|
+
|
170
|
+
@vocabulary = ctx.vocabulary.to_s if ctx.vocabulary
|
171
|
+
end
|
172
|
+
|
173
|
+
# Load defined prefixes
|
174
|
+
(@prefixes || {}).each_pair do |k, v|
|
175
|
+
@uri_to_prefix[v.to_s] = k
|
176
|
+
end
|
177
|
+
@prefixes = {} # Will define actual used when matched
|
178
|
+
|
179
|
+
# Process each statement to establish CURIEs and Terms
|
180
|
+
@graph.each {|statement| preprocess_statement(statement)}
|
181
|
+
add_debug{ "preprocess prefixes: #{@prefixes.inspect}" }
|
182
|
+
end
|
183
|
+
|
184
|
+
# Order subjects for output. Override this to output subjects in another order.
|
185
|
+
#
|
186
|
+
# Uses #top_classes and #base_uri.
|
187
|
+
# @return [Array<Resource>] Ordered list of subjects
|
188
|
+
def order_subjects
|
189
|
+
seen = {}
|
190
|
+
subjects = []
|
191
|
+
|
192
|
+
# Start with base_uri
|
193
|
+
if base_uri && @subjects.keys.include?(base_uri)
|
194
|
+
subjects << base_uri
|
195
|
+
seen[base_uri] = true
|
196
|
+
end
|
197
|
+
|
198
|
+
# Add distinguished classes
|
199
|
+
top_classes.select do |s|
|
200
|
+
!seen.include?(s)
|
201
|
+
end.each do |class_uri|
|
202
|
+
graph.query(:predicate => RDF.type, :object => class_uri).map {|st| st.subject}.sort.uniq.each do |subject|
|
203
|
+
#add_debug {"order_subjects: #{subject.inspect}"}
|
204
|
+
subjects << subject
|
205
|
+
seen[subject] = true
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
# Sort subjects by resources over nodes, ref_counts and the subject URI itself
|
210
|
+
recursable = @subjects.keys.select do |s|
|
211
|
+
!seen.include?(s)
|
212
|
+
end.map do |r|
|
213
|
+
[r.is_a?(RDF::Node) ? 1 : 0, ref_count(r), r]
|
214
|
+
end.sort
|
215
|
+
|
216
|
+
add_debug {"order_subjects: #{recursable.inspect}"}
|
217
|
+
|
218
|
+
subjects += recursable.map{|r| r.last}
|
219
|
+
end
|
220
|
+
|
221
|
+
# Take a hash from predicate uris to lists of values.
|
222
|
+
# Sort the lists of values. Return a sorted list of properties.
|
223
|
+
#
|
224
|
+
# @param [Hash{String => Array<Resource>}] properties A hash of Property to Resource mappings
|
225
|
+
# @return [Array<String>}] Ordered list of properties. Uses predicate_order.
|
226
|
+
def order_properties(properties)
|
227
|
+
# Make sorted list of properties
|
228
|
+
prop_list = []
|
229
|
+
|
230
|
+
predicate_order.each do |prop|
|
231
|
+
next unless properties[prop.to_s]
|
232
|
+
prop_list << prop.to_s
|
233
|
+
end
|
234
|
+
|
235
|
+
properties.keys.sort.each do |prop|
|
236
|
+
next if prop_list.include?(prop.to_s)
|
237
|
+
prop_list << prop.to_s
|
238
|
+
end
|
239
|
+
|
240
|
+
add_debug {"order_properties: #{prop_list.join(', ')}"}
|
241
|
+
prop_list
|
242
|
+
end
|
243
|
+
|
244
|
+
# Perform any statement preprocessing required. This is used to perform reference counts and determine required prefixes.
|
245
|
+
# @param [RDF::Statement] statement
|
246
|
+
# @return [ignored]
|
247
|
+
def preprocess_statement(statement)
|
248
|
+
#add_debug {"preprocess: #{statement.inspect}"}
|
249
|
+
bump_reference(statement.subject)
|
250
|
+
bump_reference(statement.object)
|
251
|
+
@subjects[statement.subject] = true
|
252
|
+
get_curie(statement.subject)
|
253
|
+
get_curie(statement.predicate)
|
254
|
+
get_curie(statement.object)
|
255
|
+
get_curie(statement.object.datatype) if statement.object.literal? && statement.object.has_datatype?
|
256
|
+
end
|
257
|
+
|
258
|
+
def get_curie(resource)
|
259
|
+
raise RDF::WriterError, "Getting CURIE for #{resource.inspect}, which must be an RDF value" unless resource.is_a? RDF::Value
|
260
|
+
return resource.to_s unless resource.uri?
|
261
|
+
|
262
|
+
uri = resource.to_s
|
263
|
+
|
264
|
+
curie =
|
265
|
+
case
|
266
|
+
when @uri_to_term_or_curie.has_key?(uri)
|
267
|
+
add_debug {"get_curie(#{uri}): uri_to_term_or_curie #{@uri_to_term_or_curie[uri].inspect}"}
|
268
|
+
return @uri_to_term_or_curie[uri]
|
269
|
+
when base_uri && uri.index(base_uri.to_s) == 0
|
270
|
+
add_debug {"get_curie(#{uri}): base_uri (#{uri.sub(base_uri.to_s, "")})"}
|
271
|
+
uri.sub(base_uri.to_s, "")
|
272
|
+
when @vocabulary && uri.index(@vocabulary) == 0
|
273
|
+
add_debug {"get_curie(#{uri}): vocabulary"}
|
274
|
+
uri.sub(@vocabulary, "")
|
275
|
+
when u = @uri_to_prefix.keys.detect {|u| uri.index(u.to_s) == 0}
|
276
|
+
add_debug {"get_curie(#{uri}): uri_to_prefix"}
|
277
|
+
prefix = @uri_to_prefix[u]
|
278
|
+
@prefixes[prefix] = u
|
279
|
+
uri.sub(u.to_s, "#{prefix}:")
|
280
|
+
when @standard_prefixes && vocab = RDF::Vocabulary.detect {|v| uri.index(v.to_uri.to_s) == 0}
|
281
|
+
add_debug {"get_curie(#{uri}): standard_prefixes"}
|
282
|
+
prefix = vocab.__name__.to_s.split('::').last.downcase
|
283
|
+
@prefixes[prefix] = vocab.to_uri
|
284
|
+
uri.sub(vocab.to_uri.to_s, "#{prefix}:")
|
285
|
+
else
|
286
|
+
add_debug {"get_curie(#{uri}): none"}
|
287
|
+
uri
|
288
|
+
end
|
289
|
+
|
290
|
+
add_debug {"get_curie(#{resource}) => #{curie}"}
|
291
|
+
|
292
|
+
@uri_to_term_or_curie[uri] = curie
|
293
|
+
rescue ArgumentError => e
|
294
|
+
raise RDF::WriterError, "Invalid URI #{uri.inspect}: #{e.message}"
|
295
|
+
end
|
296
|
+
|
297
|
+
def render(context)
|
298
|
+
add_debug "render"
|
299
|
+
if context.render_checked
|
300
|
+
return ""
|
301
|
+
end
|
302
|
+
template = find_environment_template(context)
|
303
|
+
depth do
|
304
|
+
add_debug{ "template: #{template.file}" }
|
305
|
+
add_debug{ "context: #{context.inspect}"}
|
306
|
+
|
307
|
+
template.render(context) do |item|
|
308
|
+
context.yielded(item)
|
309
|
+
end.sub(/\n\Z/,'')
|
310
|
+
end
|
311
|
+
end
|
312
|
+
|
313
|
+
# Mark a subject as done.
|
314
|
+
# @param [RDF::Resource] subject
|
315
|
+
# @return [Boolean]
|
316
|
+
def subject_done(subject)
|
317
|
+
@serialized[subject] = true
|
318
|
+
end
|
319
|
+
|
320
|
+
# Determine if the subject has been completed
|
321
|
+
# @param [RDF::Resource] subject
|
322
|
+
# @return [Boolean]
|
323
|
+
def is_done?(subject)
|
324
|
+
@serialized.include?(subject)
|
325
|
+
end
|
326
|
+
|
327
|
+
|
328
|
+
# @param [RDF::Resource] subject
|
329
|
+
# @return [Hash{String => Object}]
|
330
|
+
def properties_for_subject(subject)
|
331
|
+
properties = {}
|
332
|
+
@graph.query(:subject => subject) do |st|
|
333
|
+
key = st.predicate.to_s.freeze
|
334
|
+
properties[key] ||= []
|
335
|
+
properties[key] << st.object
|
336
|
+
end
|
337
|
+
properties
|
338
|
+
end
|
339
|
+
|
340
|
+
# @param [Array,NilClass] type
|
341
|
+
# @param [RDF::Resource] subject
|
342
|
+
# @return [String] string representation of the specific RDF.type uri
|
343
|
+
def type_of(type, subject)
|
344
|
+
# Find appropriate template
|
345
|
+
curie = case
|
346
|
+
when subject.node?
|
347
|
+
subject.to_s if ref_count(subject) > 1
|
348
|
+
else
|
349
|
+
get_curie(subject)
|
350
|
+
end
|
351
|
+
|
352
|
+
typeof = Array(type).map {|r| get_curie(r)}.join(" ")
|
353
|
+
typeof = nil if typeof.empty?
|
354
|
+
|
355
|
+
# Nodes without a curie need a blank @typeof to generate a subject
|
356
|
+
typeof ||= "" unless curie
|
357
|
+
|
358
|
+
add_debug {"subject: #{curie.inspect}, typeof: #{typeof.inspect}" }
|
359
|
+
|
360
|
+
typeof.freeze
|
361
|
+
end
|
362
|
+
|
363
|
+
def list_property_envs(predicate, list_objects)
|
364
|
+
return list_objects.map do |object|
|
365
|
+
# Render each list as multiple properties and set :inlist to true
|
366
|
+
list = RDF::List.new(object, @graph)
|
367
|
+
list.each_statement {|st| subject_done(st.subject)}
|
368
|
+
|
369
|
+
add_debug {"list: #{list.inspect} #{list.to_a}"}
|
370
|
+
env = simple_property_env(predicate, list.to_a)
|
371
|
+
env.inlist = "true"
|
372
|
+
env
|
373
|
+
end
|
374
|
+
end
|
375
|
+
|
376
|
+
def object_env(predicate, object)
|
377
|
+
subj = subject_env(object)
|
378
|
+
unless subj.nil?
|
379
|
+
subj.rel = get_curie(predicate)
|
380
|
+
return subj
|
381
|
+
end
|
382
|
+
|
383
|
+
env =
|
384
|
+
if get_curie(object) == 'rdf:nil'
|
385
|
+
NilObjectEnvironment.new(self)
|
386
|
+
elsif object.node?
|
387
|
+
NodeObjectEnvironment.new(self)
|
388
|
+
elsif object.uri?
|
389
|
+
UriObjectEnvironment.new(self)
|
390
|
+
elsif object.datatype == RDF.XMLLiteral
|
391
|
+
XMLLiteralObjectEnvironment.new(self)
|
392
|
+
else
|
393
|
+
ObjectEnvironment.new(self)
|
394
|
+
end
|
395
|
+
env.predicate = predicate
|
396
|
+
env.object = object
|
397
|
+
env.inlist = nil
|
398
|
+
|
399
|
+
env
|
400
|
+
end
|
401
|
+
|
402
|
+
def simple_property_env(predicate, objects)
|
403
|
+
return nil if objects.to_a.empty?
|
404
|
+
|
405
|
+
env = PropertyEnvironment.new(self)
|
406
|
+
setup_env(env)
|
407
|
+
env.object_terms = objects
|
408
|
+
env.predicate = predicate
|
409
|
+
env.inlist = nil
|
410
|
+
|
411
|
+
env
|
412
|
+
end
|
413
|
+
|
414
|
+
def subject_env(subject)
|
415
|
+
return unless @subjects.include?(subject)
|
416
|
+
properties = properties_for_subject(subject)
|
417
|
+
|
418
|
+
env = SubjectEnvironment.new(self)
|
419
|
+
env.base = base_uri
|
420
|
+
env.predicate_terms = order_properties(properties)
|
421
|
+
env.property_objects = properties
|
422
|
+
env.subject = subject
|
423
|
+
env.typeof = type_of(properties.delete(RDF.type.to_s), subject)
|
424
|
+
|
425
|
+
env
|
426
|
+
end
|
427
|
+
|
428
|
+
def document_env
|
429
|
+
env = DocumentEnvironment.new(self)
|
430
|
+
env.subject_terms = @ordered_subjects
|
431
|
+
env.title = doc_title
|
432
|
+
env.prefixes = prefixes
|
433
|
+
env.lang = lang
|
434
|
+
env.base = base_uri
|
435
|
+
env
|
436
|
+
end
|
437
|
+
|
438
|
+
# Render a single- or multi-valued predicate using
|
439
|
+
# `haml_template[:property_value]` or `haml_template[:property_values]`.
|
440
|
+
# Yields each object for optional rendering. The block should only render
|
441
|
+
# for recursive subject definitions (i.e., where the object is also a
|
442
|
+
# subject and is rendered underneath the first referencing subject).
|
443
|
+
#
|
444
|
+
# If a multi-valued property definition is not found within the template, the writer will use the single-valued property definition multiple times.
|
445
|
+
#
|
446
|
+
# @param [Array<RDF::Resource>] predicate
|
447
|
+
# Predicate to render.
|
448
|
+
# @param [Array<RDF::Resource>] objects
|
449
|
+
# List of objects to render. If the list contains only a single element, the :property_value template will be used. Otherwise, the :property_values template is used.
|
450
|
+
# @param [Hash{Symbol => Object}] options Rendering options passed to Haml render.
|
451
|
+
# @option options [String] :haml (haml_template[:property_value], haml_template[:property_values])
|
452
|
+
# Haml template to render. Otherwise, uses `haml_template[:property_value] or haml_template[:property_values]`
|
453
|
+
# depending on the cardinality of objects.
|
454
|
+
# @yield object, inlist
|
455
|
+
# Yields object and if it is contained in a list.
|
456
|
+
# @yieldparam [RDF::Resource] object
|
457
|
+
# @yieldparam [Boolean] inlist
|
458
|
+
# @yieldreturn [String, nil]
|
459
|
+
# The block should only return a string for recursive object definitions.
|
460
|
+
# @return String
|
461
|
+
# The rendered document is returned as a string
|
462
|
+
#
|
463
|
+
#
|
464
|
+
def render_predicate(subject, pred)
|
465
|
+
pred = RDF::URI(pred) if pred.is_a?(String)
|
466
|
+
objects = properties_for_subject(subject)[pred.to_s]
|
467
|
+
|
468
|
+
add_debug {"predicate: #{pred.inspect}, objects: #{objects}"}
|
469
|
+
|
470
|
+
return if objects.to_a.empty?
|
471
|
+
|
472
|
+
nonlists, lists = objects.partition do |object|
|
473
|
+
object == RDF.nil || (l = RDF::List.new(object, @graph)).invalid?
|
474
|
+
end
|
475
|
+
|
476
|
+
add_debug {"properties with lists: #{lists} non-lists: #{nonlists}"}
|
477
|
+
|
478
|
+
return ([simple_property_env(pred, nonlists)] + list_property_envs(pred, lists)).compact.map do |env|
|
479
|
+
render(env)
|
480
|
+
end.join(" ")
|
481
|
+
end
|
482
|
+
|
483
|
+
def is_list?(object)
|
484
|
+
!(object == RDF.nil || (l = RDF::List.new(object, @graph)).invalid?)
|
485
|
+
end
|
486
|
+
|
487
|
+
# @param [RDF::Resource] subject
|
488
|
+
# @param [Array] prop_list
|
489
|
+
# @param [Hash] render_opts
|
490
|
+
# @return [String]
|
491
|
+
def render_subject(subject)
|
492
|
+
# See if there's a template based on the sorted concatenation of all types of this subject
|
493
|
+
# or any type of this subject
|
494
|
+
|
495
|
+
env = subject_env(subject)
|
496
|
+
|
497
|
+
return if env.nil?
|
498
|
+
|
499
|
+
yield env if block_given?
|
500
|
+
|
501
|
+
add_debug {"props: #{env.predicates.inspect}"}
|
502
|
+
|
503
|
+
render(env)
|
504
|
+
end
|
505
|
+
|
506
|
+
# Render document using `haml_template[:doc]`. Yields each subject to be
|
507
|
+
# rendered separately.
|
508
|
+
#
|
509
|
+
# @param [Array<RDF::Resource>] subjects
|
510
|
+
# Ordered list of subjects. Template must yield to each subject, which returns
|
511
|
+
# the serialization of that subject (@see #subject_template)
|
512
|
+
# @param [Hash{Symbol => Object}] options Rendering options passed to Haml render.
|
513
|
+
# @option options [RDF::URI] base (nil)
|
514
|
+
# Base URI added to document, used for shortening URIs within the document.
|
515
|
+
# @option options [Symbol, String] language (nil)
|
516
|
+
# Value of @lang attribute in document, also allows included literals to omit
|
517
|
+
# an @lang attribute if it is equivalent to that of the document.
|
518
|
+
# @option options [String] title (nil)
|
519
|
+
# Value of html>head>title element.
|
520
|
+
# @option options [String] prefix (nil)
|
521
|
+
# Value of @prefix attribute.
|
522
|
+
# @option options [String] haml (haml_template[:doc])
|
523
|
+
# Haml template to render.
|
524
|
+
# @yield [subject]
|
525
|
+
# Yields each subject
|
526
|
+
# @yieldparam [RDF::URI] subject
|
527
|
+
# @yieldreturn [:ignored]
|
528
|
+
# @return String
|
529
|
+
# The rendered document is returned as a string
|
530
|
+
def render_document
|
531
|
+
add_debug{ "engine prefixes: #{prefixes.inspect}"}
|
532
|
+
env = document_env
|
533
|
+
|
534
|
+
yield env if block_given?
|
535
|
+
|
536
|
+
render(env)
|
537
|
+
end
|
538
|
+
|
539
|
+
# Render a subject using `haml_template[:subject]`.
|
540
|
+
#
|
541
|
+
# The _subject_ template may be called either as a top-level element, or recursively under another element if the _rel_ local is not nil.
|
542
|
+
#
|
543
|
+
# Yields each predicate/property to be rendered separately (@see #render_property_value and `#render_property_values`).
|
544
|
+
#
|
545
|
+
# @param [Array<RDF::Resource>] subject
|
546
|
+
# Subject to render
|
547
|
+
# @param [Array<RDF::Resource>] predicates
|
548
|
+
# Predicates of subject. Each property is yielded for separate rendering.
|
549
|
+
# @param [Hash{Symbol => Object}] options Rendering options passed to Haml render.
|
550
|
+
# @option options [String] about (nil)
|
551
|
+
# About description, a CURIE, URI or Node definition.
|
552
|
+
# May be nil if no @about is rendered (e.g. unreferenced Nodes)
|
553
|
+
# @option options [String] resource (nil)
|
554
|
+
# Resource description, a CURIE, URI or Node definition.
|
555
|
+
# May be nil if no @resource is rendered
|
556
|
+
# @option options [String] rel (nil)
|
557
|
+
# Optional @rel property description, a CURIE, URI or Node definition.
|
558
|
+
# @option options [String] typeof (nil)
|
559
|
+
# RDF type as a CURIE, URI or Node definition.
|
560
|
+
# If :about is nil, this defaults to the empty string ("").
|
561
|
+
# @option options [:li, nil] element (nil)
|
562
|
+
# Render with <li>, otherwise with template default.
|
563
|
+
# @option options [String] haml (haml_template[:subject])
|
564
|
+
# Haml template to render.
|
565
|
+
# @yield [predicate]
|
566
|
+
# Yields each predicate
|
567
|
+
# @yieldparam [RDF::URI] predicate
|
568
|
+
# @yieldreturn [:ignored]
|
569
|
+
# @return String
|
570
|
+
# The rendered document is returned as a string
|
571
|
+
# Return Haml template for document from `haml_template[:subject]`
|
572
|
+
end
|
573
|
+
end
|
574
|
+
end
|