roadforest 0.0.3 → 0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. checksums.yaml +7 -0
  2. data/examples/file-management.rb +7 -9
  3. data/lib/roadforest/application/dispatcher.rb +44 -31
  4. data/lib/roadforest/application/parameters.rb +5 -4
  5. data/lib/roadforest/application/path-provider.rb +14 -1
  6. data/lib/roadforest/application/route-adapter.rb +15 -4
  7. data/lib/roadforest/application/services-host.rb +41 -7
  8. data/lib/roadforest/application.rb +4 -8
  9. data/lib/roadforest/authorization.rb +231 -0
  10. data/lib/roadforest/blob-model.rb +2 -11
  11. data/lib/roadforest/content-handling/engine.rb +12 -6
  12. data/lib/roadforest/content-handling/handler-wrap.rb +45 -0
  13. data/lib/roadforest/content-handling/media-type.rb +20 -12
  14. data/lib/roadforest/content-handling/type-handler.rb +76 -0
  15. data/lib/roadforest/content-handling/type-handlers/jsonld.rb +2 -146
  16. data/lib/roadforest/content-handling/type-handlers/rdf-handler.rb +38 -0
  17. data/lib/roadforest/content-handling/type-handlers/rdfa-writer/document-environment.rb +34 -0
  18. data/lib/roadforest/content-handling/type-handlers/rdfa-writer/object-environment.rb +62 -0
  19. data/lib/roadforest/content-handling/type-handlers/rdfa-writer/property-environment.rb +46 -0
  20. data/lib/roadforest/content-handling/type-handlers/rdfa-writer/render-engine.rb +574 -0
  21. data/lib/roadforest/content-handling/type-handlers/rdfa-writer/render-environment.rb +144 -0
  22. data/lib/roadforest/content-handling/type-handlers/rdfa-writer/subject-environment.rb +80 -0
  23. data/lib/roadforest/content-handling/type-handlers/rdfa-writer.rb +163 -0
  24. data/lib/roadforest/content-handling/type-handlers/rdfa.rb +175 -0
  25. data/lib/roadforest/content-handling/type-handlers/rdfpost.rb +297 -0
  26. data/lib/roadforest/debug.rb +10 -0
  27. data/lib/roadforest/http/graph-response.rb +3 -7
  28. data/lib/roadforest/http/graph-transfer.rb +28 -106
  29. data/lib/roadforest/http/keychain.rb +79 -0
  30. data/lib/roadforest/http/message.rb +9 -1
  31. data/lib/roadforest/http/user-agent.rb +115 -0
  32. data/lib/roadforest/http.rb +8 -0
  33. data/lib/roadforest/model.rb +48 -3
  34. data/lib/roadforest/rdf/graph-focus.rb +5 -3
  35. data/lib/roadforest/rdf/graph-store.rb +4 -2
  36. data/lib/roadforest/rdf/normalization.rb +6 -1
  37. data/lib/roadforest/remote-host.rb +22 -7
  38. data/lib/roadforest/resource/rdf/read-only.rb +15 -1
  39. data/lib/roadforest/templates/base/doc.haml +13 -0
  40. data/lib/roadforest/templates/base/property_value.haml +12 -0
  41. data/lib/roadforest/templates/base/property_values.haml +6 -0
  42. data/lib/roadforest/templates/base/subject.haml +4 -0
  43. data/lib/roadforest/templates/distiller/doc.haml +20 -0
  44. data/lib/roadforest/templates/distiller/nil-object.haml +1 -0
  45. data/lib/roadforest/templates/distiller/property_value.haml +7 -0
  46. data/lib/roadforest/templates/distiller/property_values.haml +7 -0
  47. data/lib/roadforest/templates/distiller/subject.haml +5 -0
  48. data/lib/roadforest/templates/min/doc.haml +10 -0
  49. data/lib/roadforest/templates/min/property_values.haml +7 -0
  50. data/lib/roadforest/templates/min/subject.haml +2 -0
  51. data/lib/roadforest/templates/nil-object.haml +0 -0
  52. data/lib/roadforest/templates/node-object.haml +1 -0
  53. data/lib/roadforest/templates/object.haml +1 -0
  54. data/lib/roadforest/templates/uri-object.haml +1 -0
  55. data/lib/roadforest/templates/xml-literal-object.haml +1 -0
  56. data/lib/roadforest/utility/class-registry.rb +4 -0
  57. data/spec/client.rb +119 -77
  58. data/spec/{excon-adapater.rb → excon-adapter.rb} +4 -0
  59. data/spec/full-integration.rb +6 -2
  60. data/spec/graph-store.rb +1 -1
  61. data/spec/media-types.rb +29 -2
  62. 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 &lt;li&gt;, 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