diff options
-rw-r--r-- | ChangeLog | 1 | ||||
-rw-r--r-- | serd/serd.h | 5 | ||||
-rw-r--r-- | src/reader.c | 96 | ||||
-rw-r--r-- | src/writer.c | 201 | ||||
-rw-r--r-- | tests/test-07.out | 2 | ||||
-rw-r--r-- | tests/test-blank-in-list.out | 4 | ||||
-rw-r--r-- | tests/test-blank-in-list.ttl | 2 | ||||
-rw-r--r-- | tests/test-list-in-blank.out | 6 | ||||
-rw-r--r-- | tests/test-list-in-blank.ttl | 2 | ||||
-rw-r--r-- | tests/test-list-subject.out | 5 | ||||
-rw-r--r-- | tests/test-list-subject.ttl | 1 | ||||
-rw-r--r-- | tests/test-pretty.out | 46 | ||||
-rw-r--r-- | tests/test-pretty.ttl | 44 |
13 files changed, 319 insertions, 96 deletions
@@ -24,6 +24,7 @@ serd (UNRELEASED) unstable; urgency=low * Add serd_node_new_blob and serd_base64_decode for handling arbitrary binary data via base64 encoding. * Support compilation as C++ under MSVC++. + * Impement pretty-printing for collections. -- David Robillard <d@drobilla.net> (UNRELEASED) diff --git a/serd/serd.h b/serd/serd.h index c69d0eaa..8cca4a3f 100644 --- a/serd/serd.h +++ b/serd/serd.h @@ -117,7 +117,10 @@ typedef enum { SERD_EMPTY_O = 1 << 2, /**< Empty blank node object */ SERD_ANON_S_BEGIN = 1 << 3, /**< Start of anonymous subject */ SERD_ANON_O_BEGIN = 1 << 4, /**< Start of anonymous object */ - SERD_ANON_CONT = 1 << 5 /**< Continuation of anonymous node */ + SERD_ANON_CONT = 1 << 5, /**< Continuation of anonymous node */ + SERD_LIST_S_BEGIN = 1 << 6, /**< Start of list subject */ + SERD_LIST_O_BEGIN = 1 << 7, /**< Start of list object */ + SERD_LIST_CONT = 1 << 8 /**< Continuation of list */ } SerdStatementFlag; /** diff --git a/src/reader.c b/src/reader.c index e365e45f..38d0c21a 100644 --- a/src/reader.c +++ b/src/reader.c @@ -277,7 +277,7 @@ emit_statement(SerdReader* reader, SerdStatementFlags* flags, deref(reader, o), deref(reader, d), deref(reader, l)); - *flags = (*flags & SERD_ANON_CONT) ? SERD_ANON_CONT : 0; + *flags &= SERD_ANON_CONT|SERD_LIST_CONT; // Preserve only cont flags return ret; } @@ -1008,7 +1008,7 @@ blank_id(SerdReader* reader) static bool read_blank(SerdReader* reader, ReadContext ctx, bool subject, Ref* dest) { - const bool was_anon_subject = subject && (*ctx.flags | SERD_ANON_CONT); + const SerdStatementFlags old_flags = *ctx.flags; switch (peek_byte(reader)) { case '_': *dest = read_nodeID(reader); @@ -1016,25 +1016,29 @@ read_blank(SerdReader* reader, ReadContext ctx, bool subject, Ref* dest) case '[': eat_byte_safe(reader, '['); read_ws_star(reader); - *dest = blank_id(reader); - if (peek_byte(reader) == ']') { - eat_byte_safe(reader, ']'); + + const bool empty = (peek_byte(reader) == ']'); + if (empty) { *ctx.flags |= (subject) ? SERD_EMPTY_S : SERD_EMPTY_O; - if (ctx.subject) { - TRY_RET(emit_statement(reader, ctx.flags, - ctx.graph, ctx.subject, ctx.predicate, - *dest, 0, 0)); - } - return true; + } else { + *ctx.flags |= (subject) ? SERD_ANON_S_BEGIN : SERD_ANON_O_BEGIN; } - *ctx.flags |= (subject) ? SERD_ANON_S_BEGIN : SERD_ANON_O_BEGIN; + *dest = blank_id(reader); if (ctx.subject) { TRY_RET(emit_statement(reader, ctx.flags, ctx.graph, ctx.subject, ctx.predicate, *dest, 0, 0)); } + ctx.subject = *dest; + *ctx.flags &= ~(SERD_LIST_CONT); + + if (empty) { + eat_byte_safe(reader, ']'); + return true; + } + if (!subject) { *ctx.flags |= SERD_ANON_CONT; } @@ -1044,20 +1048,10 @@ read_blank(SerdReader* reader, ReadContext ctx, bool subject, Ref* dest) if (reader->end_sink) { reader->end_sink(reader->handle, deref(reader, *dest)); } - if (!was_anon_subject) { - *ctx.flags &= ~SERD_ANON_CONT; - } + *ctx.flags = old_flags; return true; case '(': - if (read_collection(reader, ctx, dest)) { - if (ctx.subject) { - TRY_RET(emit_statement(reader, ctx.flags, - ctx.graph, ctx.subject, ctx.predicate, - *dest, 0, 0)); - } - return true; - } - return false; + return read_collection(reader, ctx, dest); default: return error(reader, "illegal blank node\n"); } @@ -1199,32 +1193,23 @@ static bool read_collection_rec(SerdReader* reader, ReadContext ctx) { read_ws_star(reader); - if (peek_byte(reader) == ')') { + const bool end = (peek_byte(reader) == ')'); + const Ref rest = (end ? reader->rdf_nil : blank_id(reader)); + *ctx.flags |= SERD_LIST_CONT; + TRY_RET(emit_statement(reader, ctx.flags, ctx.graph, + ctx.subject, reader->rdf_rest, rest, 0, 0)); + + if (end) { eat_byte_safe(reader, ')'); - TRY_RET(emit_statement(reader, ctx.flags, - 0, - ctx.subject, - reader->rdf_rest, - reader->rdf_nil, 0, 0)); - return false; } else { - const Ref rest = blank_id(reader); - TRY_RET(emit_statement(reader, ctx.flags, - ctx.graph, - ctx.subject, - reader->rdf_rest, - rest, 0, 0)); - ctx.subject = rest; - ctx.predicate = reader->rdf_first; + ctx.subject = rest; + ctx.predicate = reader->rdf_first; if (read_object(reader, ctx)) { - read_collection_rec(reader, ctx); - pop_node(reader, rest); - return true; - } else { - pop_node(reader, rest); - return false; + TRY_RET(read_collection_rec(reader, ctx)); } } + *ctx.flags &= ~SERD_LIST_CONT; + return true; } // [22] itemList ::= object+ @@ -1232,22 +1217,33 @@ read_collection_rec(SerdReader* reader, ReadContext ctx) static bool read_collection(SerdReader* reader, ReadContext ctx, Ref* dest) { - TRY_RET(eat_byte_safe(reader, '(')); + eat_byte_safe(reader, '('); read_ws_star(reader); - if (peek_byte(reader) == ')') { // Empty collection - eat_byte_safe(reader, ')'); + + if (peek_byte(reader) == ')') { *dest = reader->rdf_nil; + if (ctx.subject) { + TRY_RET(emit_statement(reader, ctx.flags, ctx.graph, + ctx.subject, ctx.predicate, *dest, 0, 0)); + } + eat_byte_safe(reader, ')'); return true; } - *dest = blank_id(reader); + *dest = blank_id(reader); + *ctx.flags |= (!ctx.subject) ? SERD_LIST_S_BEGIN : SERD_LIST_O_BEGIN; + + if (ctx.subject) { + TRY_RET(emit_statement(reader, ctx.flags, ctx.graph, + ctx.subject, ctx.predicate, *dest, 0, 0)); + *ctx.flags = SERD_LIST_CONT; + } ctx.subject = *dest; ctx.predicate = reader->rdf_first; if (!read_object(reader, ctx)) { return error(reader, "unexpected end of collection\n"); } - ctx.subject = *dest; return read_collection_rec(reader, ctx); } diff --git a/src/writer.c b/src/writer.c index 469e0090..84bd465b 100644 --- a/src/writer.c +++ b/src/writer.c @@ -36,6 +36,43 @@ static const WriteContext WRITE_CONTEXT_NULL = { { 0, 0, 0, 0, SERD_NOTHING } }; +typedef enum { + SEP_NONE, + SEP_END_S, ///< End of a subject ('.') + SEP_END_P, ///< End of a predicate (';') + SEP_END_O, ///< End of an object (',') + SEP_S_P, ///< Between a subject and predicate (whitespace) + SEP_P_O, ///< Between a predicate and object (whitespace) + SEP_ANON_BEGIN, ///< Start of anonymous node ('[') + SEP_ANON_END, ///< End of anonymous node (']') + SEP_LIST_BEGIN, ///< Start of list ('(') + SEP_LIST_SEP, ///< List separator (whitespace) + SEP_LIST_END ///< End of list (')') +} Sep; + +typedef struct { + const char* str; ///< Sep string + uint8_t len; ///< Length of sep string + uint8_t space_before; ///< Newline before sep + uint8_t space_after_node; ///< Newline after sep if after node + uint8_t space_after_sep; ///< Newline after sep if after sep +} SepRule; + +static const SepRule rules[] = { + { NULL, 0, 0, 0, 0 }, + { " .\n\n", 4, 0, 0, 0 }, + { " ;", 2, 0, 1, 1 }, + { " ,", 2, 0, 1, 0 }, + { NULL, 0, 0, 1, 0 }, + { " ", 1, 0, 0, 0 }, + { "[", 1, 0, 1, 1 }, + { "]", 1, 0, 0, 0 }, + { "(", 1, 0, 0, 0 }, + { NULL, 1, 0, 1, 0 }, + { ")", 1, 1, 0, 0 }, + { "\n", 1, 0, 1, 0 } +}; + struct SerdWriterImpl { SerdSyntax syntax; SerdStyle style; @@ -46,9 +83,12 @@ struct SerdWriterImpl { SerdSink sink; void* stream; WriteContext context; + SerdNode list_subj; + unsigned list_depth; uint8_t* bprefix; size_t bprefix_len; unsigned indent; + Sep last_sep; bool empty; }; @@ -202,16 +242,8 @@ write_text(SerdWriter* writer, TextContext ctx, } static void -serd_writer_write_delim(SerdWriter* writer, const uint8_t delim) +write_newline(SerdWriter* writer) { - switch (delim) { - case '\n': - break; - default: - sink(" ", 1, writer); - case '[': - sink(&delim, 1, writer); - } sink("\n", 1, writer); for (unsigned i = 0; i < writer->indent; ++i) { sink("\t", 1, writer); @@ -219,6 +251,25 @@ serd_writer_write_delim(SerdWriter* writer, const uint8_t delim) } static void +write_sep(SerdWriter* writer, const Sep sep) +{ + const SepRule* rule = &rules[sep]; + if (rule->space_before) { + write_newline(writer); + } + if (rule->str) { + sink(rule->str, rule->len, writer); + } + if ( (writer->last_sep && rule->space_after_sep) + || (!writer->last_sep && rule->space_after_node)) { + write_newline(writer); + } else if (writer->last_sep && rule->space_after_node) { + sink(" ", 1, writer); + } + writer->last_sep = sep; +} + +static void reset_context(SerdWriter* writer, bool del) { if (del) { @@ -257,10 +308,22 @@ write_node(SerdWriter* writer, && ((field == FIELD_SUBJECT && (flags & SERD_ANON_S_BEGIN)) || (field == FIELD_OBJECT && (flags & SERD_ANON_O_BEGIN)))) { ++writer->indent; - serd_writer_write_delim(writer, '['); + write_sep(writer, SEP_ANON_BEGIN); + } else if (writer->syntax != SERD_NTRIPLES + && (field == FIELD_SUBJECT && (flags & SERD_LIST_S_BEGIN))) { + assert(writer->list_depth == 0); + copy_node(&writer->list_subj, node); + ++writer->list_depth; + ++writer->indent; + write_sep(writer, SEP_LIST_BEGIN); + } else if (writer->syntax != SERD_NTRIPLES + && (field == FIELD_OBJECT && (flags & SERD_LIST_O_BEGIN))) { + ++writer->indent; + ++writer->list_depth; + write_sep(writer, SEP_LIST_BEGIN); } else if (writer->syntax != SERD_NTRIPLES - && ((field == FIELD_SUBJECT && (flags & SERD_EMPTY_S)) - || (field == FIELD_OBJECT && (flags & SERD_EMPTY_O)))) { + && ((field == FIELD_SUBJECT && (flags & SERD_EMPTY_S)) + || (field == FIELD_OBJECT && (flags & SERD_EMPTY_O)))) { sink("[]", 2, writer); } else { sink("_:", 2, writer); @@ -325,7 +388,11 @@ write_node(SerdWriter* writer, if ((writer->syntax == SERD_TURTLE) && !strcmp((const char*)node->buf, NS_RDF "type")) { sink("a", 1, writer); - return true; + break; + } else if ((writer->syntax == SERD_TURTLE) + && !strcmp((const char*)node->buf, NS_RDF "nil")) { + sink("()", 2, writer); + break; } else if ((writer->style & SERD_STYLE_CURIED) && serd_uri_string_has_scheme(node->buf)) { SerdNode prefix; @@ -334,7 +401,7 @@ write_node(SerdWriter* writer, write_text(writer, WRITE_URI, prefix.buf, prefix.n_bytes, '>'); sink(":", 1, writer); write_text(writer, WRITE_URI, suffix.buf, suffix.len, '>'); - return true; + break; } } else if ((writer->style & SERD_STYLE_RESOLVED) && !serd_uri_string_has_scheme(node->buf)) { @@ -345,7 +412,7 @@ write_node(SerdWriter* writer, sink("<", 1, writer); serd_uri_serialise(&abs_uri, (SerdSink)sink, writer); sink(">", 1, writer); - return true; + break; } sink("<", 1, writer); write_text(writer, WRITE_URI, node->buf, node->n_bytes, '>'); @@ -353,6 +420,7 @@ write_node(SerdWriter* writer, default: break; } + writer->last_sep = SEP_NONE; return true; } @@ -367,6 +435,45 @@ is_resource(const SerdNode* node) } } +static void +serd_writer_write_predicate(SerdWriter* writer, + SerdStatementFlags flags, + const SerdNode* predicate) +{ + if (!(flags & (SERD_LIST_CONT|SERD_LIST_S_BEGIN))) { + write_node(writer, predicate, NULL, NULL, FIELD_PREDICATE, flags); + write_sep(writer, SEP_P_O); + } + copy_node(&writer->context.predicate, predicate); +} + +static bool +serd_writer_write_object(SerdWriter* writer, + SerdStatementFlags flags, + const SerdNode* predicate, + const SerdNode* object, + const SerdNode* object_datatype, + const SerdNode* object_lang) +{ + if (!strcmp((const char*)object->buf, NS_RDF "nil")) { + if (flags & SERD_LIST_CONT) { + --writer->indent; + write_sep(writer, SEP_LIST_END); + return true; + } else { + sink("()", 2, writer); + } + } else if (strcmp((const char*)predicate->buf, NS_RDF "rest")) { + if (!strcmp((const char*)predicate->buf, NS_RDF "first")) { + write_sep(writer, SEP_LIST_SEP); + } + + write_node(writer, object, object_datatype, object_lang, + FIELD_OBJECT, flags); + } + return false; +} + SERD_API SerdStatus serd_writer_write_statement(SerdWriter* writer, @@ -399,15 +506,15 @@ serd_writer_write_statement(SerdWriter* writer, default: break; } + + bool was_list_end = false; if (serd_node_equals(subject, &writer->context.subject)) { if (serd_node_equals(predicate, &writer->context.predicate)) { // Abbreviate S P - if ((flags & SERD_ANON_O_BEGIN)) { - sink(" , ", 3, writer); // ] , [ - } else { + if (!(flags & SERD_ANON_O_BEGIN)) { ++writer->indent; - serd_writer_write_delim(writer, ','); } + write_sep(writer, SEP_END_O); write_node(writer, object, object_datatype, object_lang, FIELD_OBJECT, flags); if (!(flags & SERD_ANON_O_BEGIN)) { @@ -415,35 +522,34 @@ serd_writer_write_statement(SerdWriter* writer, } } else { // Abbreviate S - if (writer->context.predicate.type) { - serd_writer_write_delim(writer, ';'); - } else { - serd_writer_write_delim(writer, '\n'); + if (!(flags & SERD_LIST_CONT)) { + write_sep(writer, + (writer->context.predicate.type + ? SEP_END_P : SEP_S_P)); } - write_node(writer, predicate, NULL, NULL, FIELD_PREDICATE, flags); - copy_node(&writer->context.predicate, predicate); - sink(" ", 1, writer); - write_node(writer, object, object_datatype, object_lang, - FIELD_OBJECT, flags); + + serd_writer_write_predicate(writer, flags, predicate); + + was_list_end = serd_writer_write_object( + writer, flags, predicate, object, object_datatype, object_lang); } } else { + // No abbreviation if (writer->context.subject.type) { assert(writer->indent > 0); --writer->indent; - if (serd_stack_is_empty(&writer->anon_stack)) { - serd_writer_write_delim(writer, '.'); - serd_writer_write_delim(writer, '\n'); + if (serd_stack_is_empty(&writer->anon_stack) + && !(flags & SERD_LIST_CONT)) { + write_sep(writer, SEP_END_S); } } else if (!writer->empty) { - serd_writer_write_delim(writer, '\n'); + write_sep(writer, SEP_S_P); } - if (!(flags & SERD_ANON_CONT)) { + if (!(flags & (SERD_ANON_CONT|SERD_LIST_CONT))) { write_node(writer, subject, NULL, NULL, FIELD_SUBJECT, flags); ++writer->indent; - if (!(flags & SERD_ANON_S_BEGIN)) { - serd_writer_write_delim(writer, '\n'); - } + write_sep(writer, SEP_S_P); } else { ++writer->indent; } @@ -451,15 +557,19 @@ serd_writer_write_statement(SerdWriter* writer, reset_context(writer, false); copy_node(&writer->context.subject, subject); - write_node(writer, predicate, NULL, NULL, FIELD_PREDICATE, flags); - copy_node(&writer->context.predicate, predicate); - sink(" ", 1, writer); + serd_writer_write_predicate(writer, flags, predicate); - write_node(writer, object, object_datatype, object_lang, - FIELD_OBJECT, flags); + was_list_end = serd_writer_write_object( + writer, flags, predicate, object, object_datatype, object_lang); } - if ((flags & SERD_ANON_S_BEGIN) || (flags & SERD_ANON_O_BEGIN)) { + if (was_list_end) { + if (--writer->list_depth == 0 && writer->list_subj.type) { + reset_context(writer, false); + writer->context.subject = writer->list_subj; + writer->list_subj = SERD_NODE_NULL; + } + } else if (flags & (SERD_ANON_S_BEGIN|SERD_ANON_O_BEGIN)) { WriteContext* ctx = (WriteContext*)serd_stack_push( &writer->anon_stack, sizeof(WriteContext)); *ctx = writer->context; @@ -490,8 +600,8 @@ serd_writer_end_anon(SerdWriter* writer, } assert(writer->indent > 0); --writer->indent; - serd_writer_write_delim(writer, '\n'); - sink("]", 1, writer); + write_sep(writer, SEP_END_P); + write_sep(writer, SEP_ANON_END); reset_context(writer, true); writer->context = *anon_stack_top(writer); serd_stack_pop(&writer->anon_stack, sizeof(WriteContext)); @@ -536,9 +646,12 @@ serd_writer_new(SerdSyntax syntax, writer->sink = sink; writer->stream = stream; writer->context = context; + writer->list_subj = SERD_NODE_NULL; + writer->list_depth = 0; writer->bprefix = NULL; writer->bprefix_len = 0; writer->indent = 0; + writer->last_sep = SEP_NONE; writer->empty = true; if (style & SERD_STYLE_BULK) { writer->bulk_sink = serd_bulk_sink_new(sink, stream, SERD_PAGE_SIZE); diff --git a/tests/test-07.out b/tests/test-07.out index 4a4e8ee2..e17cc7be 100644 --- a/tests/test-07.out +++ b/tests/test-07.out @@ -1,5 +1,5 @@ +<http://example.org/stuff/1.0/a> <http://example.org/stuff/1.0/b> _:genid1 . _:genid1 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> "apple" . _:genid1 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> _:genid2 . _:genid2 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> "banana" . _:genid2 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> <http://www.w3.org/1999/02/22-rdf-syntax-ns#nil> . -<http://example.org/stuff/1.0/a> <http://example.org/stuff/1.0/b> _:genid1 . diff --git a/tests/test-blank-in-list.out b/tests/test-blank-in-list.out new file mode 100644 index 00000000..2e0c0eb0 --- /dev/null +++ b/tests/test-blank-in-list.out @@ -0,0 +1,4 @@ +<http://example.org/stuff/1.0/a> <http://example.org/stuff/1.0/b> _:genid1 . +_:genid1 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> _:genid2 . +_:genid2 <http://example.org/stuff/1.0/c> <http://example.org/stuff/1.0/d> . +_:genid1 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> <http://www.w3.org/1999/02/22-rdf-syntax-ns#nil> . diff --git a/tests/test-blank-in-list.ttl b/tests/test-blank-in-list.ttl new file mode 100644 index 00000000..5c0b0766 --- /dev/null +++ b/tests/test-blank-in-list.ttl @@ -0,0 +1,2 @@ +@prefix : <http://example.org/stuff/1.0/> . +:a :b ( [ :c :d ] ) . diff --git a/tests/test-list-in-blank.out b/tests/test-list-in-blank.out new file mode 100644 index 00000000..76023a8b --- /dev/null +++ b/tests/test-list-in-blank.out @@ -0,0 +1,6 @@ +<http://example.org/stuff/1.0/a> <http://example.org/stuff/1.0/b> _:genid1 . +_:genid1 <http://example.org/stuff/1.0/c> _:genid2 . +_:genid2 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> "apple" . +_:genid2 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> _:genid3 . +_:genid3 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> "banana" . +_:genid3 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> <http://www.w3.org/1999/02/22-rdf-syntax-ns#nil> . diff --git a/tests/test-list-in-blank.ttl b/tests/test-list-in-blank.ttl new file mode 100644 index 00000000..bdf75fce --- /dev/null +++ b/tests/test-list-in-blank.ttl @@ -0,0 +1,2 @@ +@prefix : <http://example.org/stuff/1.0/> . +:a :b [ :c ( "apple" "banana" ) ] . diff --git a/tests/test-list-subject.out b/tests/test-list-subject.out new file mode 100644 index 00000000..e0e7f497 --- /dev/null +++ b/tests/test-list-subject.out @@ -0,0 +1,5 @@ +_:genid1 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> "apple" . +_:genid1 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> _:genid2 . +_:genid2 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> "banana" . +_:genid2 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> <http://www.w3.org/1999/02/22-rdf-syntax-ns#nil> . +_:genid1 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://example.org/List> . diff --git a/tests/test-list-subject.ttl b/tests/test-list-subject.ttl new file mode 100644 index 00000000..624336ae --- /dev/null +++ b/tests/test-list-subject.ttl @@ -0,0 +1 @@ +("apple" "banana") a <http://example.org/List> .
\ No newline at end of file diff --git a/tests/test-pretty.out b/tests/test-pretty.out new file mode 100644 index 00000000..c61f7c22 --- /dev/null +++ b/tests/test-pretty.out @@ -0,0 +1,46 @@ +<http://www.w3.org/1999/02/22-rdf-syntax-ns#nil> <http://example.org/isA> <http://example.org/List> . +_:genid1 <http://example.org/isA> <http://example.org/Blank> . +<http://www.w3.org/1999/02/22-rdf-syntax-ns#nil> <http://example.org/sameAs> <http://www.w3.org/1999/02/22-rdf-syntax-ns#nil> . +_:genid2 <http://example.org/sameAs> _:genid3 . +_:genid4 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> "apple" . +_:genid4 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> _:genid5 . +_:genid5 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> "banana" . +_:genid5 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> _:genid6 . +_:genid6 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> "pear" . +_:genid6 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> <http://www.w3.org/1999/02/22-rdf-syntax-ns#nil> . +_:genid4 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://example.org/List> . +_:genid7 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> _:genid8 . +_:genid8 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> <http://example.org/a> . +_:genid8 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> _:genid9 . +_:genid9 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> <http://example.org/b> . +_:genid9 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> <http://www.w3.org/1999/02/22-rdf-syntax-ns#nil> . +_:genid7 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> _:genid10 . +_:genid10 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> _:genid11 . +_:genid11 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> <http://example.org/c> . +_:genid11 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> _:genid12 . +_:genid12 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> <http://example.org/d> . +_:genid12 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> <http://www.w3.org/1999/02/22-rdf-syntax-ns#nil> . +_:genid10 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> <http://www.w3.org/1999/02/22-rdf-syntax-ns#nil> . +_:genid7 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://example.org/List> . +_:genid13 <http://example.org/list> _:genid14 . +_:genid14 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> "apple" . +_:genid14 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> _:genid15 . +_:genid15 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> "banana" . +_:genid15 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> _:genid16 . +_:genid16 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> "pear" . +_:genid16 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> <http://www.w3.org/1999/02/22-rdf-syntax-ns#nil> . +_:genid17 <http://example.org/a> <http://example.org/b> . +_:genid17 <http://example.org/a> <http://example.org/c> . +_:genid17 <http://example.org/a> <http://example.org/d> . +_:genid18 <http://example.org/a> _:genid19 . +_:genid19 <http://example.org/b> <http://example.org/c> . +_:genid19 <http://example.org/d> <http://example.org/e> . +_:genid18 <http://example.org/a> _:genid20 . +_:genid20 <http://example.org/f> <http://example.org/g> . +_:genid21 <http://example.org/list> _:genid22 . +_:genid22 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> _:genid23 . +_:genid23 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://example.org/Apple> . +_:genid22 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> _:genid24 . +_:genid24 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> _:genid25 . +_:genid25 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://example.org/Banana> . +_:genid24 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> <http://www.w3.org/1999/02/22-rdf-syntax-ns#nil> . diff --git a/tests/test-pretty.ttl b/tests/test-pretty.ttl new file mode 100644 index 00000000..4eb7204f --- /dev/null +++ b/tests/test-pretty.ttl @@ -0,0 +1,44 @@ +@prefix : <http://example.org/> . + +() :isA :List . + +[] :isA :Blank . + +() :sameAs () . + +[] :sameAs [] . + +( + "apple" + "banana" + "pear" +) a :List . + +( + (:a :b) + (:c :d) +) a :List . + +[] + :list ( + "apple" + "banana" + "pear" + ) . + +[] + :a :b , :c , :d . + +[] + :a [ + :b :c ; + :d :e ; + ] , [ + :f :g + ] . + +[] + :list ( + [ a :Apple ] + [ a :Banana ] + ) .
\ No newline at end of file |