aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--NEWS3
-rw-r--r--src/reader.c25
-rw-r--r--src/writer.c52
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 <d@drobilla.net> Tue, 16 Dec 2014 12:17:44 -0500
+ -- David Robillard <d@drobilla.net> 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
@@ -435,6 +435,14 @@ typedef enum {
} 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,
const SerdNode* datatype,
@@ -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;
}