Skip to content

Commit

Permalink
Finish 3.3.0
Browse files Browse the repository at this point in the history
  • Loading branch information
gkellogg committed Sep 1, 2023
2 parents 4765724 + c2bcdc1 commit fa05795
Show file tree
Hide file tree
Showing 36 changed files with 368 additions and 161 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Expand Up @@ -25,7 +25,7 @@ jobs:
strategy:
fail-fast: false
matrix:
ruby: [2.6, 2.7, '3.0', 3.1, 3.2, ruby-head, jruby]
ruby: ['3.0', 3.1, 3.2, ruby-head, jruby]
steps:
- name: Clone repository
uses: actions/checkout@v3
Expand Down
2 changes: 1 addition & 1 deletion Gemfile
Expand Up @@ -31,6 +31,6 @@ group :test do
gem "rake"
gem "equivalent-xml"
gem 'fasterer'
gem 'simplecov', '~> 0.21', platforms: :mri
gem 'simplecov', '~> 0.22', platforms: :mri
gem 'simplecov-lcov', '~> 0.8', platforms: :mri
end
70 changes: 36 additions & 34 deletions README.md
Expand Up @@ -14,26 +14,28 @@ This is a pure-Ruby library for working with [Resource Description Framework

1. [Features](#features)
2. [Differences between RDF 1.0 and RDF 1.1](#differences-between-rdf-1-0-and-rdf-1-1)
3. [Tutorials](#tutorials)
4. [Command Line](#command-line)
5. [Examples](#examples)
6. [Reader/Writer convenience methods](#reader/writer-convenience-methods)
7. [RDF* (RDFStar)](#rdf*-(rdfstar))
8. [Documentation](#documentation)
9. [Dependencies](#dependencies)
10. [Installation](#installation)
11. [Download](#download)
12. [Resources](#resources)
13. [Mailing List](#mailing-list)
14. [Authors](#authors)
15. [Contributors](#contributors)
16. [Contributing](#contributing)
17. [License](#license)
3. [Differences between RDF 1.1 and RDF 1.2](#differences-between-rdf-1-1-and-rdf-1-2)
4. [Tutorials](#tutorials)
5. [Command Line](#command-line)
6. [Examples](#examples)
7. [Reader/Writer convenience methods](#reader/writer-convenience-methods)
8. [RDF 1.2](#rdf\_12)
9. [Documentation](#documentation)
10. [Dependencies](#dependencies)
11. [Installation](#installation)
12. [Download](#download)
13. [Resources](#resources)
14. [Mailing List](#mailing-list)
15. [Authors](#authors)
16. [Contributors](#contributors)
17. [Contributing](#contributing)
18. [License](#license)

## Features

* 100% pure Ruby with minimal dependencies and no bloat.
* Fully compatible with [RDF 1.1][] specifications.
* Provisional support for [RDF 1.2][] specifications.
* 100% free and unencumbered [public domain](https://unlicense.org/) software.
* Provides a clean, well-designed RDF object model and related APIs.
* Supports parsing and serializing [N-Triples][] and [N-Quads][] out of the box, with more
Expand All @@ -45,11 +47,10 @@ This is a pure-Ruby library for working with [Resource Description Framework
not modify any of Ruby's core classes or standard library.
* Based entirely on Ruby's autoloading, meaning that you can generally make
use of any one part of the library without needing to load up the rest.
* Compatible with Ruby Ruby >= 2.4, Rubinius and JRuby 9.0+.
* Note, changes in mapping hashes to keyword arguments for Ruby 2.7+ may require that arguments be passed more explicitly, especially when the first argument is a Hash and there are optional keyword arguments. In this case, Hash argument may need to be explicitly included within `{}` and the optional keyword arguments may need to be specified using `**{}` if there are no keyword arguments.
* Compatible with Ruby Ruby >= 3.0, Rubinius and JRuby 9.0+.
* Note, changes in mapping hashes to keyword arguments for Ruby 3+ may require that arguments be passed more explicitly, especially when the first argument is a Hash and there are optional keyword arguments. In this case, Hash argument may need to be explicitly included within `{}` and the optional keyword arguments may need to be specified using `**{}` if there are no keyword arguments.
* Performs auto-detection of input to select appropriate Reader class if one
cannot be determined from file characteristics.
* Provisional support for [RDF*][].

### HTTP requests

Expand Down Expand Up @@ -102,6 +103,10 @@ the 1.1 release of RDF.rb:

Notably, {RDF::Queryable#query} and {RDF::Query#execute} are now completely symmetric; this allows an implementation of {RDF::Queryable} to optimize queries using implementation-specific logic, allowing for substantial performance improvements when executing BGP queries.

## Differences between RDF 1.1 and RDF 1.2
* {RDF::Literal} has an optional `direction` property for directional language-tagged strings.
* Removes support for legacy `text/plain` (as an alias for `application/n-triples`) and `text/x-nquads` (as an alias for `application/n-quads`)

## Tutorials

* [Getting data from the Semantic Web using Ruby and RDF.rb](https://semanticweb.org/wiki/Getting_data_from_the_Semantic_Web_%28Ruby%29)
Expand Down Expand Up @@ -260,23 +265,24 @@ A separate [SPARQL][SPARQL doc] gem builds on basic BGP support to provide full
foaf[:name] #=> RDF::URI("http://xmlns.com/foaf/0.1/name")
foaf['mbox'] #=> RDF::URI("http://xmlns.com/foaf/0.1/mbox")

## RDF* (RDFStar)
## RDF 1.2

[RDF.rb][] includes provisional support for [RDF*][] with an N-Triples/N-Quads syntax extension that uses inline statements in the _subject_ or _object_ position.
[RDF.rb][] includes provisional support for [RDF 1.2][] with an N-Triples/N-Quads syntax for quoted triples in the _subject_ or _object_ position.
[RDF.rb][] includes provisional support for [RDF 1.2][] directional language-tagged strings, which are literals of type `rdf:dirLangString` having both a `language` and `direction`.

Internally, an `RDF::Statement` is treated as another resource, along with `RDF::URI` and `RDF::Node`, which allows an `RDF::Statement` to have a `#subject` or `#object` which is also an `RDF::Statement`.

**Note: This feature is subject to change or elimination as the standards process progresses.**

### Serializing a Graph containing embedded statements
### Serializing a Graph containing quoted triples

require 'rdf/ntriples'
statement = RDF::Statement(RDF::URI('bob'), RDF::Vocab::FOAF.age, RDF::Literal(23))
graph = RDF::Graph.new << [statement, RDF::URI("ex:certainty"), RDF::Literal(0.9)]
graph.dump(:ntriples, validate: false)
# => '<<<bob> <http://xmlns.com/foaf/0.1/age> "23"^^<http://www.w3.org/2001/XMLSchema#integer>>> <ex:certainty> "0.9"^^<http://www.w3.org/2001/XMLSchema#double> .'

### Reading a Graph containing embedded statements
### Reading a Graph containing quoted triples

By default, the N-Triples reader will reject a document containing a subject resource.

Expand All @@ -286,13 +292,6 @@ By default, the N-Triples reader will reject a document containing a subject res
end
# => RDF::ReaderError

Readers support a boolean valued `rdfstar` option.

graph = RDF::Graph.new do |graph|
RDF::NTriples::Reader.new(nt, rdfstar: true) {|reader| graph << reader}
end
graph.count #=> 1

## Documentation

<https://ruby-rdf.github.io/rdf>
Expand Down Expand Up @@ -398,16 +397,17 @@ from BNode identity (i.e., they each entail the other)

## Dependencies

* [Ruby](https://ruby-lang.org/) (>= 2.6)
* [Ruby](https://ruby-lang.org/) (>= 3.0)
* [LinkHeader][] (>= 0.0.8)
* [bcp47_spec][] ( ~> 0.2)
* Soft dependency on [RestClient][] (>= 2.1)

## Installation

The recommended installation method is via [RubyGems](https://rubygems.org/).
To install the latest official release of RDF.rb, do:

% [sudo] gem install rdf # Ruby 2.6+
% [sudo] gem install rdf # Ruby 3+

## Download

Expand Down Expand Up @@ -481,8 +481,10 @@ This is free and unencumbered public domain software. For more information,
see <https://unlicense.org/> or the accompanying {file:UNLICENSE} file.

[RDF]: https://www.w3.org/RDF/
[N-Triples]: https://www.w3.org/TR/n-triples/
[N-Quads]: https://www.w3.org/TR/n-quads/
[LinkHeader]: https://github.com/asplake/link_header
[bcp47_spec]: https://github.com/dadah89/bcp47_spec
[N-Triples]: https://www.w3.org/TR/rdf-n-triples/
[N-Quads]: https://www.w3.org/TR/rdf-n-quads/
[YARD]: https://yardoc.org/
[YARD-GS]: https://rubydoc.info/docs/yard/file/docs/GettingStarted.md
[PDD]: https://unlicense.org/#unlicensing-contributions
Expand All @@ -496,6 +498,7 @@ see <https://unlicense.org/> or the accompanying {file:UNLICENSE} file.
[SPARQL doc]: https://ruby-rdf.github.io/sparql
[RDF 1.0]: https://www.w3.org/TR/2004/REC-rdf-concepts-20040210/
[RDF 1.1]: https://www.w3.org/TR/rdf11-concepts/
[RDF 1.2]: https://www.w3.org/TR/rdf12-concepts/
[SPARQL 1.1]: https://www.w3.org/TR/sparql11-query/
[RDF.rb]: https://ruby-rdf.github.io/
[RDF::DO]: https://ruby-rdf.github.io/rdf-do
Expand All @@ -510,7 +513,6 @@ see <https://unlicense.org/> or the accompanying {file:UNLICENSE} file.
[RDF::TriX]: https://ruby-rdf.github.io/rdf-trix
[RDF::Turtle]: https://ruby-rdf.github.io/rdf-turtle
[RDF::Raptor]: https://ruby-rdf.github.io/rdf-raptor
[RDF*]: https://w3c.github.io/rdf-star/rdf-star-cg-spec.html
[LinkedData]: https://ruby-rdf.github.io/linkeddata
[JSON::LD]: https://ruby-rdf.github.io/json-ld
[RestClient]: https://rubygems.org/gems/rest-client
Expand Down
2 changes: 1 addition & 1 deletion VERSION
@@ -1 +1 @@
3.2.11
3.3.0
7 changes: 0 additions & 7 deletions etc/n-triples-star.ebnf

This file was deleted.

46 changes: 40 additions & 6 deletions etc/n-triples.ebnf
@@ -1,6 +1,40 @@
[1] ntriplesDoc ::= triple? (EOL triple)* EOL?
[2] triple ::= subject predicate object '.'
[3] subject ::= IRIREF | BLANK_NODE_LABEL
[4] predicate ::= IRIREF
[5] object ::= IRIREF | BLANK_NODE_LABEL | literal
[6] literal ::= STRING_LITERAL_QUOTE ('^^' IRIREF | LANGTAG)?
ntriplesDoc ::= triple? (EOL triple)* EOL?
triple ::= subject predicate object '.'
subject ::= IRIREF | BLANK_NODE_LABEL | quotedTriple
predicate ::= IRIREF
object ::= IRIREF | BLANK_NODE_LABEL | literal | quotedTriple
literal ::= STRING_LITERAL_QUOTE ('^^' IRIREF | LANG_DIR )?
quotedTriple ::= '<<' subject predicate object '>>'

@terminals

IRIREF ::= '<' ([^#x00-#x20<>"{}|^`\] | UCHAR)* '>'
BLANK_NODE_LABEL ::= '_:' ( PN_CHARS_U | [0-9] ) ((PN_CHARS|'.')* PN_CHARS)?
LANG_DIR ::= "@" [a-zA-Z]+ ( "-" [a-zA-Z0-9]+ )* ('--' [a-zA-Z]+)?`
STRING_LITERAL_QUOTE ::= '"' ( [^#x22#x5C#xA#xD] | ECHAR | UCHAR )* '"'
UCHAR ::= ( "\u" HEX HEX HEX HEX )
| ( "\U" HEX HEX HEX HEX HEX HEX HEX HEX )
ECHAR ::= ("\" [tbnrf"'])
PN_CHARS_BASE ::= ([A-Z]
| [a-z]
| [#x00C0-#x00D6]
| [#x00D8-#x00F6]
| [#x00F8-#x02FF]
| [#x0370-#x037D]
| [#x037F-#x1FFF]
| [#x200C-#x200D]
| [#x2070-#x218F]
| [#x2C00-#x2FEF]
| [#x3001-#xD7FF]
| [#xF900-#xFDCF]
| [#xFDF0-#xFFFD]
| [#x10000-#xEFFFF])
PN_CHARS_U ::= PN_CHARS_BASE | '_'
PN_CHARS ::= (PN_CHARS_U
| "-"
| [0-9]
| #x00B7
| [#x0300-#x036F]
| [#x203F-#x2040])
HEX ::= ([0-9] | [A-F] | [a-f])
EOL ::= [#xD#xA]+
2 changes: 1 addition & 1 deletion lib/rdf/cli.rb
Expand Up @@ -60,7 +60,7 @@ module RDF
# RDF::CLI::Option.new(
# symbol: :canonicalize,
# on: ["--canonicalize"],
# description: "Canonicalize input/output.") {true},
# description: "Canonicalize URI/literal forms.") {true},
# RDF::CLI::Option.new(
# symbol: :uri,
# on: ["--uri STRING"],
Expand Down
25 changes: 23 additions & 2 deletions lib/rdf/mixin/enumerable.rb
Expand Up @@ -83,7 +83,8 @@ def to_a
# * `:literal_equality' preserves [term-equality](https://www.w3.org/TR/rdf11-concepts/#dfn-literal-term-equality) for literals. Literals are equal only if their lexical values and datatypes are equal, character by character. Literals may be "inlined" to value-space for efficiency only if `:literal_equality` is `false`.
# * `:validity` allows a concrete Enumerable implementation to indicate that it does or does not support valididty checking. By default implementations are assumed to support validity checking.
# * `:skolemize` supports [Skolemization](https://www.w3.org/wiki/BnodeSkolemization) of an `Enumerable`. Implementations supporting this feature must implement a `#skolemize` method, taking a base URI used for minting URIs for BNodes as stable identifiers and a `#deskolemize` method, also taking a base URI used for turning URIs having that prefix back into the same BNodes which were originally skolemized.
# * `:rdfstar` supports RDF* where statements may be subjects or objects of other statements.
# * `:quoted_triples` supports RDF 1.2 quoted triples.
# * `:base_direction` supports RDF 1.2 directional language-tagged strings.
#
# @param [Symbol, #to_sym] feature
# @return [Boolean]
Expand Down Expand Up @@ -720,13 +721,33 @@ def enum_graph
end
alias_method :enum_graphs, :enum_graph

##
# Enumerates each statement using its canonical representation.
#
# @note This is updated by `RDF::Normalize` to also canonicalize blank nodes.
#
# @return [RDF::Enumerable]
def canonicalize
this = self
Enumerable::Enumerator.new do |yielder|
this.send(:each_statement) {|y| yielder << y.canonicalize}
end
end

##
# Mutating canonicalization not supported
#
# @raise NotImplementedError
def canonicalize!
raise NotImplementedError, "Canonicalizing enumerables not supported"
end

##
# Returns all RDF statements in `self` as an array.
#
# Mixes in `RDF::Enumerable` into the returned object.
#
# @return [Array]
# @since 0.2.0
def to_a
super.extend(RDF::Enumerable)
end
Expand Down
2 changes: 1 addition & 1 deletion lib/rdf/mixin/queryable.rb
Expand Up @@ -140,7 +140,7 @@ def query_execute(query, **options, &block)
# method in order to provide for storage-specific optimized triple
# pattern matching.
#
# ## RDFStar (RDF*)
# ## RDF-star
#
# Statements may have embedded statements as either a subject or object, recursively.
#
Expand Down
7 changes: 5 additions & 2 deletions lib/rdf/mixin/writable.rb
Expand Up @@ -127,8 +127,11 @@ def insert_graph(graph)
def insert_statements(statements)
each = statements.respond_to?(:each_statement) ? :each_statement : :each
statements.__send__(each) do |statement|
if statement.embedded? && respond_to?(:supports?) && !supports?(:rdfstar)
raise ArgumentError, "Wriable does not support embedded statements"
if statement.embedded? && respond_to?(:supports?) && !supports?(:quoted_triples)
raise ArgumentError, "Writable does not support quoted triples"
end
if statement.object && statement.object.literal? && statement.object.direction? && !supports?(:base_direction)
raise ArgumentError, "Writable does not support directional languaged-tagged strings"
end
insert_statement(statement)
end
Expand Down
2 changes: 1 addition & 1 deletion lib/rdf/model/dataset.rb
Expand Up @@ -104,7 +104,7 @@ def isolation_level
# @private
# @see RDF::Enumerable#supports?
def supports?(feature)
return true if %i(graph_name rdfstar).include?(feature)
return true if %i(graph_name quoted_triples).include?(feature)
super
end

Expand Down
7 changes: 5 additions & 2 deletions lib/rdf/model/graph.rb
Expand Up @@ -305,8 +305,11 @@ def query_pattern(pattern, **options, &block)
# @private
# @see RDF::Mutable#insert
def insert_statement(statement)
if statement.embedded? && !@data.supports?(:rdfstar)
raise ArgumentError, "Graph does not support embedded statements"
if statement.embedded? && !@data.supports?(:quoted_triples)
raise ArgumentError, "Graph does not support quoted triples"
end
if statement.object && statement.object.literal? && statement.object.direction? && !@data.supports?(:base_direction)
raise ArgumentError, "Graph does not support directional languaged-tagged strings"
end
statement = statement.dup
statement.graph_name = graph_name
Expand Down

0 comments on commit fa05795

Please sign in to comment.