Skip to content

Commit

Permalink
Add :rdf_star option on Turtle/TriG encoder
Browse files Browse the repository at this point in the history
  • Loading branch information
marcelotto committed May 7, 2024
1 parent 0805dde commit 8353e2a
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 12 deletions.
16 changes: 9 additions & 7 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,21 @@ Elixir v1.15 or later, where this issue has been resolved.
### Added

- `RDF.TriG` with an implementation of the TriG serialization language.
- Capability to add custom content on the Turtle/TriG encoders with the `:content` option.
- Option `:line_prefix` on Turtle/TriG encoder for a function defining custom line prefixes.
- Option `:indent_width` on Turtle/TriG encoder to customize the indentation width.
- Option `:pn_local_validation` on Turtle/TriG encoder for controlling IRI validation
when encoding as a prefixed name.
- Several new options on the Turtle/TriG encoder for more customizations and
performance optimizations:
- Capability to add custom content on the Turtle/TriG encoders with the `:content` option.
- `:line_prefix` for a function defining custom line prefixes
- `:indent_width` to customize the indentation width
- `:pn_local_validation` for controlling IRI validation when encoding prefixed names
- `:rdf_star` allowing to skip an RDF-star related preprocessing step
- `RDF.Dataset.update_all_graphs/2` to apply a function on all graphs of a dataset.
- `RDF.Dataset.named_graphs/1` to get a list of all named graphs of a dataset.
- `RDF.Dataset.graph_names/1` to get a list of all graph names of a dataset.
- `RDF.Graph.prefixes/2` which allows to specify a custom return value when the prefixes
are empty.
- `RDF.PrefixMap.empty?/1` to check of a `RDF.PrefixMap` is empty.
- `RDF.PrefixMap.limit/2` to limit a `RDF.PrefixMap` to a subset of some given prefixes.
- Performance improvements of N-Triples and N-Quads encoders.
- `RDF.Graph.prefixes/2` which allows to specify a custom return value when the prefixes
are empty.

### Changed

Expand Down
7 changes: 5 additions & 2 deletions lib/rdf/serializations/turtle_trig/encoder.ex
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ defmodule RDF.TurtleTriG.Encoder do
- Note: Currently, a `:strict` mode, which would provide comprehensive validation
conforming strictly to the Turtle specification, is not implemented.
Contributions for implementing this mode are welcome.
- `:rdf_star`: Allows to skip a RDF-star related preprocessing step. This can be
used to improve performance a little bit when you know the encoded data doesn't
include any RDF-star statements. Defaults to the returned value of `RDF.star?/0`.
"""
end

Expand Down Expand Up @@ -189,7 +192,7 @@ defmodule RDF.TurtleTriG.Encoder do

defp graph_statements(%{single_triple_lines: true} = state) do
state.graph
|> CompactStarGraph.compact()
|> CompactStarGraph.compact(state.rdf_star)
|> Sequencer.descriptions(State.base_iri(state))
|> Enum.map(
&(&1
Expand All @@ -202,7 +205,7 @@ defmodule RDF.TurtleTriG.Encoder do

defp graph_statements(state) do
state.graph
|> CompactStarGraph.compact()
|> CompactStarGraph.compact(state.rdf_star)
|> Sequencer.descriptions(State.base_iri(state))
|> Enum.map(&(&1 |> description_statements(state) |> indented(state)))
|> Enum.reject(&Enum.empty?/1)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ defmodule RDF.TurtleTriG.Encoder.CompactStarGraph do

alias RDF.{Graph, Description}

def compact(graph) do
def compact(graph, false), do: graph

def compact(graph, true) do
Enum.reduce(graph.descriptions, graph, fn
{{_, _, _} = quoted_triple, _}, compact_graph ->
# First check the original graph to see if the quoted triple is asserted.
Expand Down
6 changes: 4 additions & 2 deletions lib/rdf/serializations/turtle_trig/encoder/state.ex
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ defmodule RDF.TurtleTriG.Encoder.State do
:base_indent,
:indentation,
:indent_step,
:bnode_info
:bnode_info,
:rdf_star
]

@default_indent_width 4
Expand Down Expand Up @@ -49,7 +50,8 @@ defmodule RDF.TurtleTriG.Encoder.State do
indent_step: opts |> Keyword.get(:indent_width, @default_indent_width) |> indent_string(),
line_prefix: line_prefix,
single_triple_lines: !!line_prefix || Keyword.get(opts, :single_triple_lines),
bnode_info: BnodeInfo.new(data)
bnode_info: BnodeInfo.new(data),
rdf_star: Keyword.get(opts, :rdf_star, RDF.star?())
}
|> init_indentation()
end
Expand Down
12 changes: 12 additions & 0 deletions test/unit/serializations/turtle_encoder_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -809,6 +809,18 @@ defmodule RDF.Turtle.EncoderTest do
# a case with RDF-star annotations in tested also in turtle_star_encoder_test.exs
end

test ":rdf_star option" do
graph =
Graph.new([
{EX.S1, EX.p1(), EX.O1},
{EX.S1, EX.p2(), 42},
{EX.S2, EX.p3(), ~B<foo>}
])

assert Turtle.Encoder.encode!(graph, rdf_star: false) ==
Turtle.Encoder.encode!(graph, rdf_star: true)
end

%{
"full IRIs without base" => %{
input: "<http://a/b> <http://a/c> <http://a/d> .",
Expand Down

0 comments on commit 8353e2a

Please sign in to comment.