Class: RDF::RDFa::Writer

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

Direct Known Subclasses

RDF::RDFXML::Writer

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, #canonicalize?, 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, #validate?, #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

  • :validate (Boolean) — default: false

    whether to validate terms when serializing

  • :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:



104
105
106
107
108
109
110
111
112
113
114
115
# File 'vendor/bundler/ruby/2.1.0/bundler/gems/rdf-rdfa-a3313b2e5b0b/lib/rdf/rdfa/writer.rb', line 104

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

Returns Base URI used for relativizing URIs

Returns:

  • (RDF::URI)

    Base URI used for relativizing URIs



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

def base_uri
  @base_uri
end

- (Graph) graph

Returns Graph of statements serialized

Returns:

  • (Graph)

    Graph of statements serialized



69
70
71
# File 'vendor/bundler/ruby/2.1.0/bundler/gems/rdf-rdfa-a3313b2e5b0b/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.1.0/bundler/gems/rdf-rdfa-a3313b2e5b0b/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.1.0/bundler/gems/rdf-rdfa-a3313b2e5b0b/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.1.0/bundler/gems/rdf-rdfa-a3313b2e5b0b/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:



619
620
621
622
623
624
625
# File 'vendor/bundler/ruby/2.1.0/bundler/gems/rdf-rdfa-a3313b2e5b0b/lib/rdf/rdfa/writer.rb', line 619

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:



663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
# File 'vendor/bundler/ruby/2.1.0/bundler/gems/rdf-rdfa-a3313b2e5b0b/lib/rdf/rdfa/writer.rb', line 663

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 ArgumentError => 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:



599
600
601
602
# File 'vendor/bundler/ruby/2.1.0/bundler/gems/rdf-rdfa-a3313b2e5b0b/lib/rdf/rdfa/writer.rb', line 599

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

- (Symbol?) 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:



609
610
611
612
# File 'vendor/bundler/ruby/2.1.0/bundler/gems/rdf-rdfa-a3313b2e5b0b/lib/rdf/rdfa/writer.rb', line 609

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.to_s != @lang.to_s
end

- (String) get_predicate_name(resource) (protected)

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

Parameters:

Returns:

Raises:



653
654
655
656
# File 'vendor/bundler/ruby/2.1.0/bundler/gems/rdf-rdfa-a3313b2e5b0b/lib/rdf/rdfa/writer.rb', line 653

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:



632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
# File 'vendor/bundler/ruby/2.1.0/bundler/gems/rdf-rdfa-a3313b2e5b0b/lib/rdf/rdfa/writer.rb', line 632

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:



118
119
120
121
122
123
124
125
# File 'vendor/bundler/ruby/2.1.0/bundler/gems/rdf-rdfa-a3313b2e5b0b/lib/rdf/rdfa/writer.rb', line 118

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.



435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
# File 'vendor/bundler/ruby/2.1.0/bundler/gems/rdf-rdfa-a3313b2e5b0b/lib/rdf/rdfa/writer.rb', line 435

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:



398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
# File 'vendor/bundler/ruby/2.1.0/bundler/gems/rdf-rdfa-a3313b2e5b0b/lib/rdf/rdfa/writer.rb', line 398

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:



581
582
583
584
585
586
587
588
589
590
591
592
# File 'vendor/bundler/ruby/2.1.0/bundler/gems/rdf-rdfa-a3313b2e5b0b/lib/rdf/rdfa/writer.rb', line 581

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

- (ignored) preprocess (protected)

Perform any preprocessing of statements required

Returns:

  • (ignored)


367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
# File 'vendor/bundler/ruby/2.1.0/bundler/gems/rdf-rdfa-a3313b2e5b0b/lib/rdf/rdfa/writer.rb', line 367

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 unless k.to_s == "dcterms"
    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)


456
457
458
459
460
461
462
463
464
465
# File 'vendor/bundler/ruby/2.1.0/bundler/gems/rdf-rdfa-a3313b2e5b0b/lib/rdf/rdfa/writer.rb', line 456

def preprocess_statement(statement)
  #add_debug {"preprocess: #{statement.inspect}"}
  bump_reference(statement.subject)
  bump_reference(statement.object)
  @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

- (Hash{String => Object}) properties_for_subject(subject) (protected)

Parameters:

Returns:



515
516
517
518
519
520
521
522
523
# File 'vendor/bundler/ruby/2.1.0/bundler/gems/rdf-rdfa-a3313b2e5b0b/lib/rdf/rdfa/writer.rb', line 515

def properties_for_subject(subject)
  properties = {}
  @graph.query(:subject => subject) do |st|
    key = st.predicate.to_s.freeze
    properties[key] ||= []
    properties[key] << st.object
  end
  properties
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



226
227
228
229
230
231
232
233
234
235
236
# File 'vendor/bundler/ruby/2.1.0/bundler/gems/rdf-rdfa-a3313b2e5b0b/lib/rdf/rdfa/writer.rb', line 226

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, inlist| ... } (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, inlist Yields object and if it is contained in a list.

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



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
353
354
355
356
357
358
359
360
361
362
363
# File 'vendor/bundler/ruby/2.1.0/bundler/gems/rdf-rdfa-a3313b2e5b0b/lib/rdf/rdfa/writer.rb', line 309

def render_property(predicate, objects, options = {}, &block)
  add_debug {"render_property(#{predicate}): #{objects.inspect}, #{options.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.reject do |o|
    o == RDF.nil ||
    (l = RDF::List.new(o, @graph)).invalid?
  end
  unless list_objects.empty?
    # Render non-list objects
    add_debug {"properties with lists: #{list_objects} non-lists: #{objects - list_objects}"}
    nl = depth {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}"}
      depth do
        render_property(predicate, list.to_a, options.merge(:inlist => "true")) do |object|
          yield(object, true) if block_given?
        end
      end
    end.join(" ")
  end

  if objects.length > 1 && template.nil?
    # If there is no property_values template, render each property using property_value template
    objects.map do |object|
      depth {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, &block)
  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



271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
# File 'vendor/bundler/ruby/2.1.0/bundler/gems/rdf-rdfa-a3313b2e5b0b/lib/rdf/rdfa/writer.rb', line 271

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

- (String) render_subject_template(subject, prop_list, render_opts) (protected)

Parameters:

Returns:



552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
# File 'vendor/bundler/ruby/2.1.0/bundler/gems/rdf-rdfa-a3313b2e5b0b/lib/rdf/rdfa/writer.rb', line 552

def render_subject_template(subject, prop_list, render_opts)
  # 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)
  add_debug {"subject: found template #{tmpl[:identifier] || tmpl.inspect}"} if tmpl

  # Render this subject
  # If :rel is specified and :typeof is nil, use @resource instead of @about.
  # Pass other options from calling context
  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 = render_opts[:property_values][pred.to_s]
        add_debug {"subject: #{get_curie(subject)}, pred: #{get_curie(pred)}, values: #{values.inspect}"}
        predicate(pred, values)
      end
    end
  end
end

- (Object) reset (protected)

Reset parser to run again



468
469
470
471
472
473
474
# File 'vendor/bundler/ruby/2.1.0/bundler/gems/rdf-rdfa-a3313b2e5b0b/lib/rdf/rdfa/writer.rb', line 468

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

- (String) 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:



497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
# File 'vendor/bundler/ruby/2.1.0/bundler/gems/rdf-rdfa-a3313b2e5b0b/lib/rdf/rdfa/writer.rb', line 497

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

  subject_done(subject)

  properties = properties_for_subject(subject)
  typeof = type_of(properties.delete(RDF.type.to_s), subject)
  prop_list = order_properties(properties)

  add_debug {"props: #{prop_list.inspect}"}

  render_opts = {:typeof => typeof, :property_values => properties}.merge(options)

  render_subject_template(subject, prop_list, render_opts)
end

- (String) type_of(type, subject) (protected)

Returns string representation of the specific RDF.type uri

Parameters:

Returns:

  • (String)

    string representation of the specific RDF.type uri



528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
# File 'vendor/bundler/ruby/2.1.0/bundler/gems/rdf-rdfa-a3313b2e5b0b/lib/rdf/rdfa/writer.rb', line 528

def type_of(type, subject)
  # Find appropriate template
  curie = case
  when subject.node?
    subject.to_s if ref_count(subject) > 1
  else
    get_curie(subject)
  end

  typeof = Array(type).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

  add_debug {"subject: #{curie.inspect}, typeof: #{typeof.inspect}" }

  typeof.freeze
end

- write_epilogue

This method returns an undefined value.

Outputs the XHTML+RDFa representation of all stored triples.



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
197
198
199
# File 'vendor/bundler/ruby/2.1.0/bundler/gems/rdf-rdfa-a3313b2e5b0b/lib/rdf/rdfa/writer.rb', line 163

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:



132
133
134
# File 'vendor/bundler/ruby/2.1.0/bundler/gems/rdf-rdfa-a3313b2e5b0b/lib/rdf/rdfa/writer.rb', line 132

def write_graph(graph)
  @graph = graph
end

- write_statement(statement)

This method returns an undefined value.

Addes a statement to be serialized

Parameters:

Raises:



141
142
143
144
# File 'vendor/bundler/ruby/2.1.0/bundler/gems/rdf-rdfa-a3313b2e5b0b/lib/rdf/rdfa/writer.rb', line 141

def write_statement(statement)
  raise RDF::WriterError, "Statement #{statement.inspect} is invalid" if validate? && statement.invalid?
  @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

  • (RDF::WriterError)

    if validating and attempting to write an invalid Term.



155
156
157
# File 'vendor/bundler/ruby/2.1.0/bundler/gems/rdf-rdfa-a3313b2e5b0b/lib/rdf/rdfa/writer.rb', line 155

def write_triple(subject, predicate, object)
  write_statement Statement.new(subject, predicate, object)
end