Class: RDF::RDFa::Writer

Inherits:
Writer show all
Defined in:
vendor/bundler/ruby/2.0.0/bundler/gems/rdf-rdfa-62d8bd55f649/lib/rdf/rdfa/writer.rb,
vendor/bundler/ruby/2.0.0/bundler/gems/rdf-rdfa-62d8bd55f649/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

Examples:

Obtaining a RDFa writer class

RDF::Writer.for(:html)          => RDF::RDFa::Writer
RDF::Writer.for("etc/test.html")
RDF::Writer.for(:file_name      => "etc/test.html")
RDF::Writer.for(:file_extension => "html")
RDF::Writer.for(:content_type   => "application/xhtml+xml")
RDF::Writer.for(:content_type   => "text/html")

Serializing RDF graph into an XHTML+RDFa file

RDF::RDFa::Write.open("etc/test.html") do |writer|
  writer << graph
end

Serializing RDF statements into an XHTML+RDFa file

RDF::RDFa::Writer.open("etc/test.html") do |writer|
  graph.each_statement do |statement|
    writer << statement
  end
end

Serializing RDF statements into an XHTML+RDFa string

RDF::RDFa::Writer.buffer do |writer|
  graph.each_statement do |statement|
    writer << statement
  end
end

Creating @base and @prefix definitions in output

RDF::RDFa::Writer.buffer(:base_uri => "http://example.com/", :prefixes => {
    :foaf => "http://xmlns.com/foaf/0.1/"}
) do |writer|
  graph.each_statement do |statement|
    writer << statement
  end
end

Author:

Constant Summary

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}
      - if base || title
        %head
          - if base
            %base{:href => base}
          - if title
            %title= title
      %body
        - subjects.each 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}
        - if typeof
          %span.type!= typeof
        - predicates.each do |predicate|
          != yield(predicate)
    - else
      %div{:rel => rel, :resource => (about || resource), :typeof => typeof, :inlist => inlist}
        - 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}= 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}= get_curie(object)
        - elsif object.uri?
          %a{:property => get_curie(predicate), :href => object.to_s, :inlist => inlist}= object.to_s
        - elsif object.datatype == RDF.XMLLiteral
          %span{:property => get_curie(predicate), :lang => get_lang(object), :datatype => get_dt_curie(object), :inlist => inlist}<!= get_value(object)
        - else
          %span{:property => get_curie(predicate), :content => get_content(object), :lang => get_lang(object), :datatype => get_dt_curie(object), :inlist => inlist}= 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}= get_curie(object)
          - elsif object.uri?
            %li
              %a{:property => get_curie(predicate), :href => object.to_s, :inlist => inlist}= object.to_s
          - elsif object.datatype == RDF.XMLLiteral
            %li{:property => get_curie(predicate), :lang => get_lang(object), :datatype => get_curie(object.datatype), :inlist => inlist}<!= get_value(object)
          - else
            %li{:property => get_curie(predicate), :content => get_content(object), :lang => get_lang(object), :datatype => get_dt_curie(object), :inlist => inlist}= 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}
      - if base
        %head
          %base{:href => base}
      %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}
      - 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}= get_curie(object)
  - elsif object.uri?
    %a{:property => get_curie(predicate), :href => object.to_s, :inlist => inlist}= object.to_s
  - elsif object.datatype == RDF.XMLLiteral
    %span{:property => get_curie(predicate), :lang => get_lang(object), :datatype => get_dt_curie(object), :inlist => inlist}<!= get_value(object)
  - else
    %span{:property => get_curie(predicate), :content => get_content(object), :lang => get_lang(object), :datatype => get_dt_curie(object), :inlist => inlist}= 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}
      - if base || title
        %head
          - if base
            %base{:href => base}
          - if title
            %title= title
          %link{:rel => "stylesheet", :href => "http://rdf.kellogg-assoc.com/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.kellogg-assoc.com/js/distiller.js", :type => "text/javascript"}
      %body
        - if base
          %p= "RDFa serialization URI base: &lt;#{base}&gt;"
        - subjects.each do |subject|
          != yield(subject)
        %footer
          %p= "Written by <a href='http://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}
        - if typeof
          %span.type!= typeof
        %table.properties
          - predicates.each do |predicate|
            != yield(predicate)
    - else
      %td{:rel => rel, :resource => (about || resource), :typeof => typeof, :inlist => inlist}
        - 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}= 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}= get_curie(object)
        - elsif object.uri?
          %td
            %a{:property => get_curie(predicate), :href => object.to_s, :inlist => inlist}= object.to_s
        - elsif object.datatype == RDF.XMLLiteral
          %td{:property => get_curie(predicate), :lang => get_lang(object), :datatype => get_dt_curie(object), :inlist => inlist}<!= get_value(object)
        - else
          %td{:property => get_curie(predicate), :content => get_content(object), :lang => get_lang(object), :datatype => get_dt_curie(object), :inlist => inlist}= 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}= get_curie(object)
            - elsif object.uri?
              %li
                %a{:property => get_curie(predicate), :href => object.to_s, :inlist => inlist}= object.to_s
            - elsif object.datatype == RDF.XMLLiteral
              %li{:property => get_curie(predicate), :lang => get_lang(object), :datatype => get_curie(object.datatype), :inlist => inlist}<!= get_value(object)
            - else
              %li{:property => get_curie(predicate), :content => get_content(object), :lang => get_lang(object), :datatype => get_dt_curie(object), :inlist => inlist}= escape_entities(get_value(object))
  ),
}
HAML_TEMPLATES =
{:base => BASE_HAML, :min => MIN_HAML, :distiller => DISTILLER_HAML}
DEFAULT_HAML =
BASE_HAML
HAML_OPTIONS =
{
  :ugly => false, # to preserve whitespace without using entities
}

Instance Attribute Summary (collapse)

Attributes inherited from Writer

#options

Instance Method Summary (collapse)

Methods inherited from Writer

buffer, dump, each, #encoding, #escaped, #flush, for, format, #format_list, #format_literal, #format_node, #format_term, #format_uri, #node_id, open, #prefix, #prefixes, #prefixes=, #puts, #quoted, #to_sym, to_sym, #uri_for, #write_comment, #write_prologue, #write_statements, #write_triples

Methods included from Util::Aliasing::LateBound

#alias_method

Methods included from Writable

#<<, #insert, #insert_graph, #insert_reader, #insert_statement, #insert_statements, #writable?

Constructor Details

- (Writer) initialize(output = $stdout, options = {}) {|writer| ... }

Initializes the RDFa writer instance.

Parameters:

  • output (IO, File) (defaults to: $stdout)

    the output stream

  • options (Hash{Symbol => Object}) (defaults to: {})

    any additional options

Options Hash (options):

  • :canonicalize (Boolean) — default: false

    whether to canonicalize literals when serializing

  • :prefixes (Hash) — default: Hash.new

    the prefix mappings to use

  • :base_uri (#to_s) — default: nil

    the base URI to use when constructing relative URIs, set as html>head>base.href

  • :lang (#to_s) — default: nil

    Output as root @lang attribute, and avoid generation @lang where possible

  • :standard_prefixes (Boolean) — default: false

    Add standard prefixes to prefixes, if necessary.

  • :top_classes (Array<RDF::URI>) — default: [RDF::RDFS.Class]

    Defines rdf:type of subjects to be emitted at the beginning of the document.

  • :predicate_order (Array<RDF::URI>) — default: [RDF.type, RDF::RDFS.label, RDF::DC.title]

    Defines order of predicates to to emit at begninning of a resource description..

  • :heading_predicates (Array<RDF::URI>) — default: [RDF::RDFS.label, RDF::DC.title]

    Defines order of predicates to use in heading.

  • :haml (String, Symbol, Hash{Symbol => String}) — default: DEFAULT_HAML

    HAML templates used for generating code

  • :haml_options (Hash) — default: HAML_OPTIONS

    Options to pass to Haml::Engine.new. Default options set :ugly => false to ensure that whitespace in literals with newlines is properly preserved.

Yields:

  • (writer)

Yield Parameters:



102
103
104
105
106
107
108
109
110
111
112
113
# File 'vendor/bundler/ruby/2.0.0/bundler/gems/rdf-rdfa-62d8bd55f649/lib/rdf/rdfa/writer.rb', line 102

def initialize(output = $stdout, options = {}, &block)
  super do
    @uri_to_term_or_curie = {}
    @uri_to_prefix = {}
    @top_classes = options[:top_classes] || [RDF::RDFS.Class]
    @predicate_order = options[:predicate_order] || [RDF.type, RDF::RDFS.label, RDF::DC.title]
    @heading_predicates = options[:heading_predicates] || [RDF::RDFS.label, RDF::DC.title]
    @graph = RDF::Graph.new

    block.call(self) if block_given?
  end
end

Instance Attribute Details

- (RDF::URI) base_uri

Base URI used for relativizing URIs

Returns:

  • (RDF::URI)

    Base URI used for relativizing URIs



72
73
74
# File 'vendor/bundler/ruby/2.0.0/bundler/gems/rdf-rdfa-62d8bd55f649/lib/rdf/rdfa/writer.rb', line 72

def base_uri
  @base_uri
end

- (Graph) graph

Graph of statements serialized

Returns:

  • (Graph)

    Graph of statements serialized



69
70
71
# File 'vendor/bundler/ruby/2.0.0/bundler/gems/rdf-rdfa-62d8bd55f649/lib/rdf/rdfa/writer.rb', line 69

def graph
  @graph
end

- (Array<URI>) heading_predicates (readonly)

Defines order of predicates to use in heading.

Returns:



62
63
64
# File 'vendor/bundler/ruby/2.0.0/bundler/gems/rdf-rdfa-62d8bd55f649/lib/rdf/rdfa/writer.rb', line 62

def heading_predicates
  @heading_predicates
end

- (Array<URI>) predicate_order (readonly)

Defines order of predicates to to emit at begninning of a resource description. Defaults to [rdf:type, rdfs:label, dc:title]

Returns:



58
59
60
# File 'vendor/bundler/ruby/2.0.0/bundler/gems/rdf-rdfa-62d8bd55f649/lib/rdf/rdfa/writer.rb', line 58

def predicate_order
  @predicate_order
end

- (Array<URI>) top_classes (readonly)

Defines rdf:type of subjects to be emitted at the beginning of the document.

Returns:



54
55
56
# File 'vendor/bundler/ruby/2.0.0/bundler/gems/rdf-rdfa-62d8bd55f649/lib/rdf/rdfa/writer.rb', line 54

def top_classes
  @top_classes
end

Instance Method Details

- (String?) get_content(literal) (protected)

Haml rendering helper. Data to be added to a @content value

Parameters:

Returns:

Raises:



582
583
584
585
586
587
588
# File 'vendor/bundler/ruby/2.0.0/bundler/gems/rdf-rdfa-62d8bd55f649/lib/rdf/rdfa/writer.rb', line 582

def get_content(literal)
  raise RDF::WriterError, "Getting content for #{literal.inspect}, which must be a literal" unless literal.is_a?(RDF::Literal)
  case literal
  when RDF::Literal::Date, RDF::Literal::Time, RDF::Literal::DateTime
    literal.to_s
  end
end

- (String) get_curie(resource) (protected)

Haml rendering helper. Return appropriate, term, CURIE or URI for the given resource.

Parameters:

Returns:

  • (String)

    value to use to identify URI

Raises:



626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
# File 'vendor/bundler/ruby/2.0.0/bundler/gems/rdf-rdfa-62d8bd55f649/lib/rdf/rdfa/writer.rb', line 626

def get_curie(resource)
  raise RDF::WriterError, "Getting CURIE for #{resource.inspect}, which must be an RDF value" unless resource.is_a?(RDF::Value)
  return resource.to_s unless resource.uri?

  uri = resource.to_s

  curie = case
  when @uri_to_term_or_curie.has_key?(uri)
    add_debug {"get_curie(#{uri}): uri_to_term_or_curie #{@uri_to_term_or_curie[uri].inspect}"}
    return @uri_to_term_or_curie[uri]
  when base_uri && uri.index(base_uri.to_s) == 0
    add_debug {"get_curie(#{uri}): base_uri (#{uri.sub(base_uri.to_s, "")})"}
    uri.sub(base_uri.to_s, "")
  when @vocabulary && uri.index(@vocabulary) == 0
    add_debug {"get_curie(#{uri}): vocabulary"}
    uri.sub(@vocabulary, "")
  when u = @uri_to_prefix.keys.detect {|u| uri.index(u.to_s) == 0}
    add_debug {"get_curie(#{uri}): uri_to_prefix"}
    # Use a defined prefix
    prefix = @uri_to_prefix[u]
    prefix(prefix, u)  # Define for output
    uri.sub(u.to_s, "#{prefix}:")
  when @options[:standard_prefixes] && vocab = RDF::Vocabulary.detect {|v| uri.index(v.to_uri.to_s) == 0}
    add_debug {"get_curie(#{uri}): standard_prefixes"}
    prefix = vocab.__name__.to_s.split('::').last.downcase
    prefix(prefix, vocab.to_uri) # Define for output
    uri.sub(vocab.to_uri.to_s, "#{prefix}:")
  else
    add_debug {"get_curie(#{uri}): none"}
    uri
  end

  #add_debug {"get_curie(#{resource}) => #{curie}"}

  @uri_to_term_or_curie[uri] = curie
rescue Argument => e
  raise RDF::WriterError, "Invalid URI #{uri.inspect}: #{e.message}"
end

- (String?) get_dt_curie(literal) (protected)

Haml rendering helper. Return CURIE for the literal datatype, if the literal is a typed literal.

Parameters:

Returns:

Raises:



562
563
564
565
# File 'vendor/bundler/ruby/2.0.0/bundler/gems/rdf-rdfa-62d8bd55f649/lib/rdf/rdfa/writer.rb', line 562

def get_dt_curie(literal)
  raise RDF::WriterError, "Getting datatype CURIE for #{literal.inspect}, which must be a literal" unless literal.is_a?(RDF::Literal)
  get_curie(literal.datatype) if literal.literal? && literal.datatype?
end

- (String?) get_lang(literal) (protected)

Haml rendering helper. Return language for plain literal, if there is no language, or it is the same as the document, return nil

Parameters:

Returns:

Raises:



572
573
574
575
# File 'vendor/bundler/ruby/2.0.0/bundler/gems/rdf-rdfa-62d8bd55f649/lib/rdf/rdfa/writer.rb', line 572

def get_lang(literal)
  raise RDF::WriterError, "Getting datatype CURIE for #{literal.inspect}, which must be a literal" unless literal.is_a?(RDF::Literal)
  literal.language if literal.literal? && literal.language && literal.language != @lang
end

- (String) get_predicate_name(resource) (protected)

Haml rendering helper. Return an appropriate label for a resource.

Parameters:

Returns:

Raises:



616
617
618
619
# File 'vendor/bundler/ruby/2.0.0/bundler/gems/rdf-rdfa-62d8bd55f649/lib/rdf/rdfa/writer.rb', line 616

def get_predicate_name(resource)
  raise RDF::WriterError, "Getting predicate name for #{resource.inspect}, which must be a resource" unless resource.is_a?(RDF::Resource)
  get_curie(resource)
end

- (String) get_value(literal) (protected)

Haml rendering helper. Display value for object, may be non-canonical if get_content returns a non-nil value

Parameters:

Returns:

Raises:



595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
# File 'vendor/bundler/ruby/2.0.0/bundler/gems/rdf-rdfa-62d8bd55f649/lib/rdf/rdfa/writer.rb', line 595

def get_value(literal)
  raise RDF::WriterError, "Getting value for #{literal.inspect}, which must be a literal" unless literal.is_a?(RDF::Literal)
  case literal
  when RDF::Literal::Date
    literal.object.strftime("%A, %d %B %Y")
  when RDF::Literal::Time
    literal.object.strftime("%H:%M:%S %Z").sub(/\+00:00/, "UTC")
  when RDF::Literal::DateTime
    literal.object.strftime("%H:%M:%S %Z on %A, %d %B %Y").sub(/\+00:00/, "UTC")
  else
    literal.to_s
  end
rescue
  literal.to_s  # When all else fails ...
end

- (Hash<Symbol => String>) haml_template

Returns:



116
117
118
119
120
121
122
123
# File 'vendor/bundler/ruby/2.0.0/bundler/gems/rdf-rdfa-62d8bd55f649/lib/rdf/rdfa/writer.rb', line 116

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

- (Array<String>) order_properties(properties) (protected)

Take a hash from predicate uris to lists of values. Sort the lists of values. Return a sorted list of properties.

Parameters:

Returns:

  • (Array<String>)

    ] Ordered list of properties. Uses predicate_order.



424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
# File 'vendor/bundler/ruby/2.0.0/bundler/gems/rdf-rdfa-62d8bd55f649/lib/rdf/rdfa/writer.rb', line 424

def order_properties(properties)
  # Make sorted list of properties
  prop_list = []

  predicate_order.each do |prop|
    next unless properties[prop.to_s]
    prop_list << prop.to_s
  end

  properties.keys.sort.each do |prop|
    next if prop_list.include?(prop.to_s)
    prop_list << prop.to_s
  end

  add_debug {"order_properties: #{prop_list.join(', ')}"}
  prop_list
end

- (Array<Resource>) order_subjects (protected)

Order subjects for output. Override this to output subjects in another order.

Uses #top_classes and #base_uri.

Returns:



387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
# File 'vendor/bundler/ruby/2.0.0/bundler/gems/rdf-rdfa-62d8bd55f649/lib/rdf/rdfa/writer.rb', line 387

def order_subjects
  seen = {}
  subjects = []

  # Start with base_uri
  if base_uri && @subjects.keys.include?(base_uri)
    subjects << base_uri
    seen[base_uri] = true
  end

  # Add distinguished classes
  top_classes.
  select {|s| !seen.include?(s)}.
  each do |class_uri|
    graph.query(:predicate => RDF.type, :object => class_uri).map {|st| st.subject}.sort.uniq.each do |subject|
      #add_debug {"order_subjects: #{subject.inspect}"}
      subjects << subject
      seen[subject] = true
    end
  end

  # Sort subjects by resources over nodes, ref_counts and the subject URI itself
  recursable = @subjects.keys.
    select {|s| !seen.include?(s)}.
    map {|r| [r.is_a?(RDF::Node) ? 1 : 0, ref_count(r), r]}.
    sort

  add_debug {"order_subjects: #{recursable.inspect}"}

  subjects += recursable.map{|r| r.last}
end

- (String) predicate(predicate, objects) (protected)

Write a predicate with one or more values.

Values may be a combination of Literal and Resource (Node or URI).

Parameters:

Returns:



544
545
546
547
548
549
550
551
552
553
554
555
# File 'vendor/bundler/ruby/2.0.0/bundler/gems/rdf-rdfa-62d8bd55f649/lib/rdf/rdfa/writer.rb', line 544

def predicate(predicate, objects)
  add_debug {"predicate: #{predicate.inspect}, objects: #{objects}"}

  return if objects.to_a.empty?

  add_debug {"predicate: #{get_curie(predicate)}"}
  render_property(predicate, objects) do |o|
    # Yields each object, for potential recursive definition.
    # If nil is returned, a leaf is produced
    depth {subject(o, :rel => get_curie(predicate), :element => (:li if objects.length > 1))} if !is_done?(o) && @subjects.include?(o)
  end
end

- (ignored) preprocess (protected)

Perform any preprocessing of statements required

Returns:

  • (ignored)


356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
# File 'vendor/bundler/ruby/2.0.0/bundler/gems/rdf-rdfa-62d8bd55f649/lib/rdf/rdfa/writer.rb', line 356

def preprocess
  # Load initial contexts
  # Add terms and prefixes to local store for converting URIs
  # Keep track of vocabulary from left-most context
  [XML_RDFA_CONTEXT, HTML_RDFA_CONTEXT].each do |uri|
    ctx = Context.find(uri)
    ctx.prefixes.each_pair do |k, v|
      @uri_to_prefix[v] = k
    end

    ctx.terms.each_pair do |k, v|
      @uri_to_term_or_curie[v] = k
    end

    @vocabulary = ctx.vocabulary.to_s if ctx.vocabulary
  end

  # Load defined prefixes
  (@options[:prefixes] || {}).each_pair do |k, v|
    @uri_to_prefix[v.to_s] = k
  end
  @options[:prefixes] = {}  # Will define actual used when matched

  # Process each statement to establish CURIEs and Terms
  @graph.each {|statement| preprocess_statement(statement)}
end

- (ignored) preprocess_statement(statement) (protected)

Perform any statement preprocessing required. This is used to perform reference counts and determine required prefixes.

Parameters:

Returns:

  • (ignored)


445
446
447
448
449
450
451
452
453
454
# File 'vendor/bundler/ruby/2.0.0/bundler/gems/rdf-rdfa-62d8bd55f649/lib/rdf/rdfa/writer.rb', line 445

def preprocess_statement(statement)
  #add_debug {"preprocess: #{statement.inspect}"}
  references = ref_count(statement.object) + 1
  @references[statement.object] = references
  @subjects[statement.subject] = true
  get_curie(statement.subject)
  get_curie(statement.predicate)
  get_curie(statement.object)
  get_curie(statement.object.datatype) if statement.object.literal? && statement.object.has_datatype?
end

- (Object) render_document(subjects, options = {}) {|subject| ... } (protected)

Render document using haml_template[:doc]. Yields each subject to be rendered separately.

Parameters:

  • subjects (Array<RDF::Resource>)

    Ordered list of subjects. Template must yield to each subject, which returns the serialization of that subject (@see #subject_template)

  • options (Hash{Symbol => Object}) (defaults to: {})

    Rendering options passed to Haml render.

Options Hash (options):

  • base (RDF::URI) — default: nil

    Base URI added to document, used for shortening URIs within the document.

  • language (Symbol, String) — default: nil

    Value of @lang attribute in document, also allows included literals to omit an @lang attribute if it is equivalent to that of the document.

  • title (String) — default: nil

    Value of html>head>title element.

  • prefix (String) — default: nil

    Value of @prefix attribute.

  • haml (String) — default: haml_template[:doc]

    Haml template to render.

Yields:

  • (subject)

    Yields each subject

Yield Parameters:

Yield Returns:

  • (:ignored)

Returns:

  • String The rendered document is returned as a string



221
222
223
224
225
226
227
228
229
230
231
# File 'vendor/bundler/ruby/2.0.0/bundler/gems/rdf-rdfa-62d8bd55f649/lib/rdf/rdfa/writer.rb', line 221

def render_document(subjects, options = {})
  template = options[:haml] || :doc
  options = {
    :prefix => nil,
    :subjects => subjects,
    :title => nil,
  }.merge(options)
  hamlify(template, options) do |subject|
    yield(subject) if block_given?
  end
end

- (Object) render_property(predicate, objects, options = {}) {|object| ... } (protected)

Render a single- or multi-valued predicate using haml_template[:property_value] or haml_template[:property_values]. Yields each object for optional rendering. The block should only render for recursive subject definitions (i.e., where the object is also a subject and is rendered underneath the first referencing subject).

If a multi-valued property definition is not found within the template, the writer will use the single-valued property definition multiple times.

Parameters:

  • predicate (Array<RDF::Resource>)

    Predicate to render.

  • objects (Array<RDF::Resource>)

    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.

  • options (Hash{Symbol => Object}) (defaults to: {})

    Rendering options passed to Haml render.

Options Hash (options):

  • haml (String) — default: haml_template[:property_value], haml_template[:property_values]

    Haml template to render. Otherwise, uses haml_template[:property_value] or haml_template[:property_values] depending on the cardinality of objects.

Yields:

  • (object)

    Yields object.

Yield Parameters:

Yield Returns:

  • (String, nil)

    The block should only return a string for recursive object definitions.

Returns:

  • String The rendered document is returned as a string



303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
# File 'vendor/bundler/ruby/2.0.0/bundler/gems/rdf-rdfa-62d8bd55f649/lib/rdf/rdfa/writer.rb', line 303

def render_property(predicate, objects, options = {}, &block)
  add_debug {"render_property(#{predicate}): #{objects.inspect}"}
  # If there are multiple objects, and no :property_values is defined, call recursively with
  # each object

  template = options[:haml]
  template ||= objects.length > 1 ? haml_template[:property_values] : haml_template[:property_value]

  # Separate out the objects which are lists and render separately
  list_objects = objects.select {|o| o != RDF.nil && RDF::List.new(o, @graph).valid?}
  unless list_objects.empty?
    # Render non-list objects
    add_debug {"properties with lists: non-lists: #{objects - list_objects} lists: #{list_objects}"}
    nl = render_property(predicate, objects - list_objects, options, &block) unless objects == list_objects
    return nl.to_s + list_objects.map do |object|
      # Render each list as multiple properties and set :inlist to true
      list = RDF::List.new(object, @graph)
      list.each_statement {|st| subject_done(st.subject)}

      add_debug {"list: #{list.inspect} #{list.to_a}"}
      render_property(predicate, list.to_a, options.merge(:inlist => "true"), &block)
    end.join(" ")
  end

  if objects.length > 1 && template.nil?
    # Uf there is no property_values template, render each property using property_value template
    objects.map do |object|
      render_property(predicate, [object], options, &block)
    end.join(" ")
  else
    raise RDF::WriterError, "Missing property template" if template.nil?

    template = options[:haml] || (
      objects.to_a.length > 1 &&
      haml_template.has_key?(:property_values) ?
        :property_values :
        :property_value)
    options = {
      :objects    => objects,
      :object     => objects.first,
      :predicate  => predicate,
      :property   => get_curie(predicate),
      :rel        => get_curie(predicate),
      :inlist     => nil,
    }.merge(options)
    hamlify(template, options) do |object|
      yield(object) if block_given?
    end
  end
end

- (Object) render_subject(subject, predicates, options = {}) {|predicate| ... } (protected)

Render a subject using haml_template[:subject].

The subject template may be called either as a top-level element, or recursively under another element if the rel local is not nil.

Yields each predicate/property to be rendered separately (@see #render_property_value and #render_property_values).

Return Haml template for document from haml_template[:subject]

Parameters:

  • subject (Array<RDF::Resource>)

    Subject to render

  • predicates (Array<RDF::Resource>)

    Predicates of subject. Each property is yielded for separate rendering.

  • options (Hash{Symbol => Object}) (defaults to: {})

    Rendering options passed to Haml render.

Options Hash (options):

  • about (String) — default: nil

    About description, a CURIE, URI or Node definition. May be nil if no @about is rendered (e.g. unreferenced Nodes)

  • resource (String) — default: nil

    Resource description, a CURIE, URI or Node definition. May be nil if no @resource is rendered

  • rel (String) — default: nil

    Optional @rel property description, a CURIE, URI or Node definition.

  • typeof (String) — default: nil

    RDF type as a CURIE, URI or Node definition. If :about is nil, this defaults to the empty string ("").

  • element (:li, nil) — default: nil

    Render with <li>, otherwise with template default.

  • haml (String) — default: haml_template[:subject]

    Haml template to render.

Yields:

  • (predicate)

    Yields each predicate

Yield Parameters:

Yield Returns:

  • (:ignored)

Returns:

  • String The rendered document is returned as a string



266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
# File 'vendor/bundler/ruby/2.0.0/bundler/gems/rdf-rdfa-62d8bd55f649/lib/rdf/rdfa/writer.rb', line 266

def render_subject(subject, predicates, options = {})
  template = options[:haml] || :subject
  options = {
    :about      => (get_curie(subject) unless options[:rel]),
    :base       => base_uri,
    :element    => nil,
    :predicates => predicates,
    :rel        => nil,
    :inlist     => nil,
    :resource   => (get_curie(subject) if options[:rel]),
    :subject    => subject,
    :typeof     => nil,
  }.merge(options)
  hamlify(template, options) do |predicate|
    yield(predicate) if block_given?
  end
end

- (Object) reset (protected)

Reset parser to run again



457
458
459
460
461
462
463
# File 'vendor/bundler/ruby/2.0.0/bundler/gems/rdf-rdfa-62d8bd55f649/lib/rdf/rdfa/writer.rb', line 457

def reset
  @depth = 0
  prefixes = {}
  @references = {}
  @serialized = {}
  @subjects = {}
end

- (Nokogiri::XML::Element, {Namespace}) subject(subject, options = {}) (protected)

Display a subject.

If the Haml template contains an entry matching the subject's rdf:type URI, that entry will be used as the template for this subject and it's properties.

Examples:

Displays a subject as a Resource Definition:

<div typeof="rdfs:Resource" about="http://example.com/resource">
  <h1 property="dc:title">label</h1>
  <ul>
    <li content="2009-04-30T06:15:51Z" property="dc:created">2009-04-30T06:15:51+00:00</li>
  </ul>
</div>

Parameters:

Options Hash (options):

  • :element(:div) (:li, nil)

    Serialize using <li> rather than template default element

  • :rel (RDF::Resource) — default: nil

    Optional @rel property

Returns:



486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
# File 'vendor/bundler/ruby/2.0.0/bundler/gems/rdf-rdfa-62d8bd55f649/lib/rdf/rdfa/writer.rb', line 486

def subject(subject, options = {})
  return if is_done?(subject)

  subject_done(subject)

  properties = {}
  @graph.query(:subject => subject) do |st|
    properties[st.predicate.to_s] ||= []
    properties[st.predicate.to_s] << st.object
  end
  prop_list = order_properties(properties)

  # Find appropriate template
  curie ||= case
  when subject.node?
    subject.to_s if ref_count(subject) >= (@depth == 0 ? 0 : 1)
  else
    get_curie(subject)
  end

  # See if there's a template based on the sorted concatenation of all types of this subject
  # or any type of this subject
  tmpl = find_template(subject)

  typeof = [properties.delete(RDF.type.to_s)].flatten.compact.map {|r| get_curie(r)}.join(" ")
  typeof = nil if typeof.empty?

  # Nodes without a curie need a blank @typeof to generate a subject
  typeof ||= "" unless curie
  prop_list -= [RDF.type.to_s]

  add_debug {"subject: found template #{tmpl[:identifier] || tmpl.inspect}"} if tmpl
  add_debug {"subject: #{curie.inspect}, typeof: #{typeof.inspect}, props: #{prop_list.inspect}"}

  # Render this subject
  # If :rel is specified and :typeof is nil, use @resource instead of @about.
  # Pass other options from calling context
  render_opts = {:typeof => typeof}.merge(options)
  with_template(tmpl) do
    render_subject(subject, prop_list, render_opts) do |pred|
      depth do
        pred = RDF::URI(pred) if pred.is_a?(String)
        values = properties[pred.to_s]
        add_debug {"subject: #{get_curie(subject)}, pred: #{get_curie(pred)}, values: #{values.inspect}"}
        predicate(pred, values)
      end
    end
  end
end

- write_epilogue

This method returns an undefined value.

Outputs the XHTML+RDFa representation of all stored triples.



158
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
# File 'vendor/bundler/ruby/2.0.0/bundler/gems/rdf-rdfa-62d8bd55f649/lib/rdf/rdfa/writer.rb', line 158

def write_epilogue
  @base_uri = RDF::URI(@options[:base_uri]) if @options[:base_uri]
  @lang = @options[:lang]
  @debug = @options[:debug]
  self.reset

  add_debug {"\nserialize: graph size: #{@graph.size}"}

  preprocess

  # Prefixes
  prefix = prefixes.keys.map {|pk| "#{pk}: #{prefixes[pk]}"}.sort.join(" ") unless prefixes.empty?
  add_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)
end

- write_graph(graph)

This method returns an undefined value.

Write whole graph

Parameters:



130
131
132
# File 'vendor/bundler/ruby/2.0.0/bundler/gems/rdf-rdfa-62d8bd55f649/lib/rdf/rdfa/writer.rb', line 130

def write_graph(graph)
  @graph = graph
end

- write_statement(statement)

This method returns an undefined value.

Addes a statement to be serialized

Parameters:



138
139
140
# File 'vendor/bundler/ruby/2.0.0/bundler/gems/rdf-rdfa-62d8bd55f649/lib/rdf/rdfa/writer.rb', line 138

def write_statement(statement)
  @graph.insert(statement)
end

- write_triple(subject, predicate, object)

This method is abstract.

This method returns an undefined value.

Addes a triple to be serialized

Parameters:

Raises:

  • (NotImplementedError)

    unless implemented in subclass



150
151
152
# File 'vendor/bundler/ruby/2.0.0/bundler/gems/rdf-rdfa-62d8bd55f649/lib/rdf/rdfa/writer.rb', line 150

def write_triple(subject, predicate, object)
  @graph.insert(Statement.new(subject, predicate, object))
end