From 96894224c76b371a7198dc18b9f6be78e7eb1b97 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Wed, 17 Dec 2014 05:50:07 +0000 Subject: Add support for Turtle named inline nodes extension. git-svn-id: http://svn.drobilla.net/serd/trunk@482 490d8e77-9747-427b-9fa3-0b8f29cee8a0 --- NEWS | 3 ++- src/reader.c | 25 ++++++++++++++++++++++++- src/writer.c | 52 +++++++++++++++++++++++++++++++++++++--------------- 3 files changed, 63 insertions(+), 17 deletions(-) diff --git a/NEWS b/NEWS index 3bcb4bfe..144b4c63 100644 --- a/NEWS +++ b/NEWS @@ -5,10 +5,11 @@ serd (0.21.1) unstable; * Add serd_reader_set_strict() and -l (lax) option to serdi to tolerate parsing URIs with escaped characters * Fix reading statements ending with a blank then dot with no space + * Add support for Turtle named inline nodes extension * Report errors for invalid IRI characters and missing terminators * Fix warnings when building with ISO C++ compilers - -- David Robillard Tue, 16 Dec 2014 12:17:44 -0500 + -- David Robillard Wed, 17 Dec 2014 00:49:08 -0500 serd (0.20.0) stable; diff --git a/src/reader.c b/src/reader.c index d5c29c04..012dcb43 100644 --- a/src/reader.c +++ b/src/reader.c @@ -1072,6 +1072,21 @@ blank_id(SerdReader* reader) return ref; } +static Ref +read_blankName(SerdReader* reader) +{ + eat_byte_safe(reader, '='); + if (eat_byte_check(reader, '=') != '=') { + return r_err(reader, SERD_ERR_BAD_SYNTAX, "expected `='\n"); + } + + Ref subject = 0; + bool ate_dot = false; + read_ws_star(reader); + read_iri(reader, &subject, &ate_dot); + return subject; +} + static bool read_blank(SerdReader* reader, ReadContext ctx, bool subject, Ref* dest, bool* ate_dot) { @@ -1086,9 +1101,17 @@ read_blank(SerdReader* reader, ReadContext ctx, bool subject, Ref* dest, bool* a *ctx.flags |= (subject) ? SERD_EMPTY_S : SERD_EMPTY_O; } else { *ctx.flags |= (subject) ? SERD_ANON_S_BEGIN : SERD_ANON_O_BEGIN; + if (peek_delim(reader, '=')) { + if (!(*dest = read_blankName(reader)) || + !eat_delim(reader, ';')) { + return false; + } + } } - *dest = blank_id(reader); + if (!*dest) { + *dest = blank_id(reader); + } if (ctx.subject) { TRY_RET(emit_statement(reader, ctx, *dest, 0, 0)); } diff --git a/src/writer.c b/src/writer.c index 1c59a3e7..4eb39493 100644 --- a/src/writer.c +++ b/src/writer.c @@ -434,6 +434,14 @@ typedef enum { FIELD_OBJECT } Field; +static bool +is_inline_start(const SerdWriter* writer, Field field, SerdStatementFlags flags) +{ + return (writer->syntax != SERD_NTRIPLES && + ((field == FIELD_SUBJECT && (flags & SERD_ANON_S_BEGIN)) || + (field == FIELD_OBJECT && (flags & SERD_ANON_O_BEGIN)))); +} + static bool write_node(SerdWriter* writer, const SerdNode* node, @@ -443,13 +451,12 @@ write_node(SerdWriter* writer, SerdStatementFlags flags) { SerdChunk uri_prefix; - SerdChunk uri_suffix; + SerdNode prefix; + SerdChunk suffix; bool has_scheme; switch (node->type) { case SERD_BLANK: - if (writer->syntax != SERD_NTRIPLES - && ((field == FIELD_SUBJECT && (flags & SERD_ANON_S_BEGIN)) - || (field == FIELD_OBJECT && (flags & SERD_ANON_O_BEGIN)))) { + if (is_inline_start(writer, field, flags)) { ++writer->indent; write_sep(writer, SEP_ANON_BEGIN); } else if (writer->syntax != SERD_NTRIPLES @@ -484,18 +491,27 @@ write_node(SerdWriter* writer, case SERD_CURIE: switch (writer->syntax) { case SERD_NTRIPLES: - if (serd_env_expand(writer->env, node, &uri_prefix, &uri_suffix)) { + if (serd_env_expand(writer->env, node, &uri_prefix, &suffix)) { w_err(writer, SERD_ERR_BAD_CURIE, "undefined namespace prefix `%s'\n", node->buf); return false; } sink("<", 1, writer); write_uri(writer, uri_prefix.buf, uri_prefix.len); - write_uri(writer, uri_suffix.buf, uri_suffix.len); + write_uri(writer, suffix.buf, suffix.len); sink(">", 1, writer); break; case SERD_TURTLE: + if (is_inline_start(writer, field, flags)) { + ++writer->indent; + write_sep(writer, SEP_ANON_BEGIN); + sink("== ", 3, writer); + } write_lname(writer, node->buf, node->n_bytes); + if (is_inline_start(writer, field, flags)) { + sink(" ;", 2, writer); + write_newline(writer); + } } break; case SERD_LITERAL: @@ -536,6 +552,11 @@ write_node(SerdWriter* writer, } break; case SERD_URI: + if (is_inline_start(writer, field, flags)) { + ++writer->indent; + write_sep(writer, SEP_ANON_BEGIN); + sink("== ", 3, writer); + } has_scheme = serd_uri_string_has_scheme(node->buf); if (field == FIELD_PREDICATE && (writer->syntax == SERD_TURTLE) && !strcmp((const char*)node->buf, NS_RDF "type")) { @@ -545,15 +566,12 @@ write_node(SerdWriter* writer, && !strcmp((const char*)node->buf, NS_RDF "nil")) { sink("()", 2, writer); break; - } else if (has_scheme && (writer->style & SERD_STYLE_CURIED)) { - SerdNode prefix; - SerdChunk suffix; - if (serd_env_qualify(writer->env, node, &prefix, &suffix)) { - write_uri(writer, prefix.buf, prefix.n_bytes); - sink(":", 1, writer); - write_uri(writer, suffix.buf, suffix.len); - break; - } + } else if (has_scheme && (writer->style & SERD_STYLE_CURIED) && + serd_env_qualify(writer->env, node, &prefix, &suffix)) { + write_uri(writer, prefix.buf, prefix.n_bytes); + sink(":", 1, writer); + write_uri(writer, suffix.buf, suffix.len); + break; } sink("<", 1, writer); if (writer->style & SERD_STYLE_RESOLVED) { @@ -574,6 +592,10 @@ write_node(SerdWriter* writer, write_uri(writer, node->buf, node->n_bytes); } sink(">", 1, writer); + if (is_inline_start(writer, field, flags)) { + sink(" ;", 2, writer); + write_newline(writer); + } default: break; } -- cgit v1.2.1