Class: RDF::RDFa::Writer
- Inherits:
-
Writer
- Object
- Writer
- RDF::RDFa::Writer
- Includes:
- Util::Logger
- Defined in:
- lib/rdf/rdfa/writer.rb,
lib/rdf/rdfa/writer/haml_templates.rb
Overview
An RDFa 1.1 serialiser in Ruby. The RDFa serializer makes use of Haml templates, allowing runtime-replacement with alternate templates. Note, however, that templates should be checked against the W3C test suite to ensure that valid RDFa is emitted.
Note that the natural interface is to write a whole graph at a time. Writing statements or Triples will create a graph to add them to and then serialize the graph.
The writer will add prefix definitions, and use them for creating @prefix definitions, and minting CURIEs
Constant Summary collapse
- HAML_OPTIONS =
{ format: :xhtml }
- BASE_HAML =
The default set of HAML templates used for RDFa code generation
{ identifier: "base", # Document # Locals: language, title, prefix, base, subjects # Yield: subjects.each doc: %q( !!! XML !!! 5 %html{**{xmlns: "http://www.w3.org/1999/xhtml", lang: lang, prefix: prefix}.compact} - if base || title %head - if base %base{**{href: base}.compact} - if title %title= title %body - subjects.map do |subject| != yield(subject) ), # Output for non-leaf resources # Note that @about may be omitted for Nodes that are not referenced # # If _rel_ and _resource_ are not nil, the tag will be written relative # to a previous subject. If _element_ is :li, the tag will be written # with <li> instead of <div>. # # Locals: subject, typeof, predicates, rel, element, inlist # Yield: predicates.each subject: %q( - if element == :li %li{**{rel: rel, resource: (about || resource), typeof: typeof, inlist: inlist}.compact} - if typeof %span.type!= typeof - predicates.each do |predicate| != yield(predicate) - else %div{**{rel: rel, resource: (about || resource), typeof: typeof, inlist: inlist}.compact} - if typeof %span.type!= typeof - predicates.each do |predicate| != yield(predicate) ), # Output for single-valued properties # Locals: predicate, object, inlist # Yields: object # If nil is returned, render as a leaf # Otherwise, render result property_value: %q( - if heading_predicates.include?(predicate) && object.literal? %h1{**{property: get_curie(predicate), content: get_content(object), lang: get_lang(object), datatype: get_dt_curie(object), inlist: inlist}.compact}= escape_entities(get_value(object)) - else %div.property %span.label = get_predicate_name(predicate) - if res = yield(object) != res - elsif get_curie(object) == 'rdf:nil' %span{rel: get_curie(predicate), inlist: ''} - elsif object.node? %span{**{property: get_curie(predicate), resource: get_curie(object), inlist: inlist}.compact}= get_curie(object) - elsif object.uri? %a{**{property: get_curie(predicate), href: object.to_s, inlist: inlist}.compact}= object.to_s - elsif object.datatype == RDF.XMLLiteral %span{**{property: get_curie(predicate), lang: get_lang(object), datatype: get_dt_curie(object), inlist: inlist}.compact}<!= get_value(object) - else %span{**{property: get_curie(predicate), content: get_content(object), lang: get_lang(object), datatype: get_dt_curie(object), inlist: inlist}.compact}= escape_entities(get_value(object)) ), # Output for multi-valued properties # Locals: predicate, :objects, :inlist # Yields: object for leaf resource rendering property_values: %q( %div.property %span.label = get_predicate_name(predicate) %ul - objects.each do |object| - if res = yield(object) != res - elsif object.node? %li{**{property: get_curie(predicate), resource: get_curie(object), inlist: inlist}.compact}= get_curie(object) - elsif object.uri? %li %a{**{property: get_curie(predicate), href: object.to_s, inlist: inlist}.compact}= object.to_s - elsif object.datatype == RDF.XMLLiteral %li{**{property: get_curie(predicate), lang: get_lang(object), datatype: get_curie(object.datatype), inlist: inlist}.compact}<!= get_value(object) - else %li{**{property: get_curie(predicate), content: get_content(object), lang: get_lang(object), datatype: get_dt_curie(object), inlist: inlist}.compact}= escape_entities(get_value(object)) ), }
- MIN_HAML =
An alternative, minimal HAML template for RDFa code generation. This version does not perform recursive object generation and does not attempt to create human readable output.
{ identifier: "min", # Document # Locals: language, title, prefix, base, subjects # Yield: subjects.each doc: %q( !!! XML !!! 5 %html{**{xmlns: "http://www.w3.org/1999/xhtml", lang: lang, prefix: prefix}.compact} - if base %head %base{*{href: base}.compact} %body - subjects.each do |subject| != yield(subject) ), # Output for non-leaf resources # Note that @about may be omitted for Nodes that are not referenced # # Locals: about, typeof, predicates, :inlist # Yield: predicates.each subject: %q( %div{**{rel: rel, resource: (about || resource), typeof: typeof}.compact} - predicates.each do |predicate| != yield(predicate) ), # Output for single-valued properties. # This version does not perform a recursive call, and renders all objects as leafs. # Locals: predicate, object, inlist # Yields: object # If nil is returned, render as a leaf # Otherwise, render result property_value: %q( - if res = yield(object) != res - elsif get_curie(object) == 'rdf:nil' %span{rel: get_curie(predicate), inlist: ''} - elsif object.node? %span{**{property: get_curie(predicate), resource: get_curie(object), inlist: inlist}.compact}= get_curie(object) - elsif object.uri? %a{**{property: get_curie(predicate), href: object.to_s, inlist: inlist}.compact}= object.to_s - elsif object.datatype == RDF.XMLLiteral %span{**{property: get_curie(predicate), lang: get_lang(object), datatype: get_dt_curie(object), inlist: inlist}.compact}<!= get_value(object) - else %span{**{property: get_curie(predicate), content: get_content(object), lang: get_lang(object), datatype: get_dt_curie(object), inlist: inlist}.compact}= escape_entities(get_value(object)) ) }
- DISTILLER_HAML =
{ identifier: "distiller", # Document # Locals: language, title, prefix, base, subjects # Yield: subjects.each doc: %q( !!! XML !!! 5 %html{**{xmlns: "http://www.w3.org/1999/xhtml", lang: lang, prefix: prefix}.compact} - if base || title %head - if base %base{href: base} - if title %title= title %link{rel: "stylesheet", href: "http://rdf.greggkellogg.net/css/distiller.css", type: "text/css"} %script{src: "https://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js", type: "text/javascript"} %script{src: "http://rdf.greggkellogg.net/js/distiller.js", type: "text/javascript"} %body - if base %p= "RDFa serialization URI base: <#{base}>" - subjects.each do |subject| != yield(subject) %footer %p= "Written by <a href='https://rubygems.org/gems/rdf-rdfa'>RDF::RDFa</a> version #{RDF::RDFa::VERSION}" ), # Output for non-leaf resources # Note that @about may be omitted for Nodes that are not referenced # # If _rel_ and _resource_ are not nil, the tag will be written relative # to a previous subject. If _element_ is :li, the tag will be written # with <li> instead of <div>. # # Note that @rel and @resource can be used together, or @about and @typeof, but # not both. # # Locals: subject, typeof, predicates, rel, element, inlist # Yield: predicates.each subject: %q( - if element == :li %li{**{rel: rel, resource: (about || resource), typeof: typeof, inlist: inlist}.compact} - if typeof %span.type!= typeof %table.properties - predicates.each do |predicate| != yield(predicate) - elsif rel %td{**{rel: rel, resource: (about || resource), typeof: typeof, inlist: inlist}.compact} - if typeof %span.type!= typeof %table.properties - predicates.each do |predicate| != yield(predicate) - else %div{**{resource: (about || resource), typeof: typeof, inlist: inlist}.compact} - if typeof %span.type!= typeof %table.properties - predicates.each do |predicate| != yield(predicate) ), # Output for single-valued properties # Locals: predicate, object, inlist # Yields: object # If nil is returned, render as a leaf # Otherwise, render result property_value: %q( - if heading_predicates.include?(predicate) && object.literal? %h1{**{property: get_curie(predicate), content: get_content(object), lang: get_lang(object), datatype: get_dt_curie(object), inlist: inlist}.compact}= escape_entities(get_value(object)) - else %tr.property %td.label = get_predicate_name(predicate) - if res = yield(object) != res - elsif get_curie(object) == 'rdf:nil' %td{rel: get_curie(predicate), inlist: ''}= "Empty" - elsif object.node? %td{**{property: get_curie(predicate), resource: get_curie(object), inlist: inlist}.compact}= get_curie(object) - elsif object.uri? %td %a{**{property: get_curie(predicate), href: object.to_s, inlist: inlist}.compact}= object.to_s - elsif object.datatype == RDF.XMLLiteral %td{**{property: get_curie(predicate), lang: get_lang(object), datatype: get_dt_curie(object), inlist: inlist}.compact}<!= get_value(object) - else %td{**{property: get_curie(predicate), content: get_content(object), lang: get_lang(object), datatype: get_dt_curie(object), inlist: inlist}.compact}= escape_entities(get_value(object)) ), # Output for multi-valued properties # Locals: predicate, objects, inliste # Yields: object for leaf resource rendering property_values: %q( %tr.property %td.label = get_predicate_name(predicate) %td %ul - objects.each do |object| - if res = yield(object) != res - elsif object.node? %li{**{property: get_curie(predicate), resource: get_curie(object), inlist: inlist}.compact}= get_curie(object) - elsif object.uri? %li %a{**{property: get_curie(predicate), href: object.to_s, inlist: inlist}.compact}= object.to_s - elsif object.datatype == RDF.XMLLiteral %li{**{property: get_curie(predicate), lang: get_lang(object), datatype: get_curie(object.datatype), inlist: inlist}.compact}<!= get_value(object) - else %li{**{property: get_curie(predicate), content: get_content(object), lang: get_lang(object), datatype: get_dt_curie(object), inlist: inlist}.compact}= escape_entities(get_value(object)) ), }
- HAML_TEMPLATES =
{base: BASE_HAML, min: MIN_HAML, distiller: DISTILLER_HAML}
- DEFAULT_HAML =
BASE_HAML
Instance Attribute Summary collapse
-
#base_uri ⇒ RDF::URI
Base URI used for relativizing URIs.
-
#graph ⇒ Graph
Graph of statements serialized.
-
#heading_predicates ⇒ Array<URI>
readonly
Defines order of predicates to use in heading.
-
#predicate_order ⇒ Array<URI>
readonly
Defines order of predicates to to emit at begninning of a resource description.
-
#top_classes ⇒ Array<URI>
readonly
Defines rdf:type of subjects to be emitted at the beginning of the document.
Class Method Summary collapse
-
.options ⇒ Object
RDFa Writer options.
Instance Method Summary collapse
- #haml_template ⇒ Hash<Symbol => String>
-
#initialize(output = $stdout, **options) {|writer| ... } ⇒ Writer
constructor
Initializes the RDFa writer instance.
-
#write_epilogue ⇒ void
Outputs the XHTML+RDFa representation of all stored triples.
-
#write_triple(subject, predicate, object) ⇒ void
abstract
Addes a triple to be serialized.
Constructor Details
#initialize(output = $stdout, **options) {|writer| ... } ⇒ Writer
Initializes the RDFa writer instance.
119 120 121 122 123 124 125 126 127 128 129 130 |
# File 'lib/rdf/rdfa/writer.rb', line 119 def initialize(output = $stdout, **, &block) super do @uri_to_term_or_curie = {} @uri_to_prefix = {} @top_classes = [:top_classes] || [RDF::RDFS.Class] @predicate_order = [:predicate_order] || [RDF.type, RDF::RDFS.label, RDF::URI("http://purl.org/dc/terms/title")] @heading_predicates = [:heading_predicates] || [RDF::RDFS.label, RDF::URI("http://purl.org/dc/terms/title")] @graph = RDF::Graph.new block.call(self) if block_given? end end |
Instance Attribute Details
#base_uri ⇒ RDF::URI
Returns Base URI used for relativizing URIs.
74 75 76 |
# File 'lib/rdf/rdfa/writer.rb', line 74 def base_uri @base_uri end |
#graph ⇒ Graph
Returns Graph of statements serialized.
71 72 73 |
# File 'lib/rdf/rdfa/writer.rb', line 71 def graph @graph end |
#heading_predicates ⇒ Array<URI> (readonly)
Defines order of predicates to use in heading.
64 65 66 |
# File 'lib/rdf/rdfa/writer.rb', line 64 def heading_predicates @heading_predicates end |
#predicate_order ⇒ Array<URI> (readonly)
Defines order of predicates to to emit at begninning of a resource description. Defaults to [rdf:type, rdfs:label, dc:title]
60 61 62 |
# File 'lib/rdf/rdfa/writer.rb', line 60 def predicate_order @predicate_order end |
#top_classes ⇒ Array<URI> (readonly)
Defines rdf:type of subjects to be emitted at the beginning of the document.
56 57 58 |
# File 'lib/rdf/rdfa/writer.rb', line 56 def top_classes @top_classes end |
Class Method Details
Instance Method Details
#haml_template ⇒ Hash<Symbol => String>
133 134 135 136 137 138 139 140 |
# File 'lib/rdf/rdfa/writer.rb', line 133 def haml_template return @haml_template if @haml_template case @options[:haml] when Symbol, String then HAML_TEMPLATES.fetch(@options[:haml].to_sym, DEFAULT_HAML) when Hash then @options[:haml] else DEFAULT_HAML end end |
#write_epilogue ⇒ void
This method returns an undefined value.
Outputs the XHTML+RDFa representation of all stored triples.
159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 |
# File 'lib/rdf/rdfa/writer.rb', line 159 def write_epilogue @base_uri = RDF::URI(@options[:base_uri]) if @options[:base_uri] @lang = @options[:lang] self.reset log_debug {"\nserialize: graph size: #{@graph.size}"} preprocess # Prefixes prefix = prefixes.keys.map {|pk| "#{pk}: #{prefixes[pk]}"}.sort.join(" ") unless prefixes.empty? log_debug {"\nserialize: prefixes: #{prefix.inspect}"} subjects = order_subjects # Take title from first subject having a heading predicate doc_title = nil titles = {} heading_predicates.each do |pred| @graph.query({predicate: pred}) do |statement| titles[statement.subject] ||= statement.object end end title_subject = subjects.detect {|subject| titles[subject]} doc_title = titles[title_subject] # Generate document doc = render_document(subjects, lang: @lang, base: base_uri, title: doc_title, prefix: prefix) do |s| subject(s) end @output.write(doc) super end |
#write_triple(subject, predicate, object) ⇒ void
This method returns an undefined value.
Addes a triple to be serialized
151 152 153 |
# File 'lib/rdf/rdfa/writer.rb', line 151 def write_triple(subject, predicate, object) @graph.insert(RDF::Statement(subject, predicate, object)) end |