Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Longturtle improvements #2500

Merged
merged 12 commits into from
Jul 25, 2023
11 changes: 10 additions & 1 deletion docs/plugin_serializers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ xml :class:`~rdflib.plugins.serializers.rdfxml.XMLSerializer`

JSON-LD
-------
JSON-LD - 'json-ld' - has been incorprated in rdflib since v6.0.0.
JSON-LD - 'json-ld' - has been incorporated into RDFLib since v6.0.0.

HexTuples
---------
Expand All @@ -43,3 +43,12 @@ Hextuple) will be an empty string.

For context-aware (multi-graph) serialization, the 'graph' field of the default graph will be an empty string and
the values for other graphs will be Blank Node IDs or IRIs.

Longturtle
----------
Longturtle is just the turtle format with newlines preferred over compactness - multiple nodes on the same line
to enhance the format's text file version control (think Git) friendliness - and more modern forms of prefix markers -
PREFIX instead of @prefix - to make it as similar to SPARQL as possible.

Longturtle is Turtle 1.1 compliant and will work wherever ordinary turtle works, however some very old parsers don't
understand PREFIX, only @prefix...
43 changes: 22 additions & 21 deletions rdflib/plugins/serializers/longturtle.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
on the start of the next line
* uses default encoding (encode()) is used instead of "latin-1"

- Nicholas Car, 2021
- Nicholas Car, 2023
"""

from rdflib.exceptions import Error
Expand Down Expand Up @@ -101,7 +101,6 @@ def serialize(self, stream, base=None, encoding=None, spacious=None, **args):
self.write("\n")

self.endDocument()
self.write("\n")

self.base = None

Expand Down Expand Up @@ -168,21 +167,20 @@ def s_default(self, subject):
self.path(subject, SUBJECT)
self.write("\n" + self.indent())
self.predicateList(subject)
self.write(" ;\n.")
self.write("\n.")
return True

def s_squared(self, subject):
if (self._references[subject] > 0) or not isinstance(subject, BNode):
return False
self.write("\n" + self.indent() + "[]")
self.predicateList(subject)
self.predicateList(subject, newline=False)
self.write(" ;\n.")
return True

def path(self, node, position, newline=False):
if not (
self.p_squared(node, position, newline)
or self.p_default(node, position, newline)
self.p_squared(node, position) or self.p_default(node, position, newline)
):
raise Error("Cannot serialize node '%s'" % (node,))

Expand All @@ -207,7 +205,11 @@ def label(self, node, position):

return self.getQName(node, position == VERB) or node.n3()

def p_squared(self, node, position, newline=False):
def p_squared(
self,
node,
position,
):
if (
not isinstance(node, BNode)
or node in self._serialized
Expand All @@ -216,23 +218,19 @@ def p_squared(self, node, position, newline=False):
):
return False

if not newline:
self.write(" ")

if self.isValidList(node):
# this is a list
self.depth += 2
self.write("(\n")
self.depth -= 1
self.write(" (\n")
self.depth -= 2
self.doList(node)
self.depth -= 1
self.write("\n" + self.indent(1) + ")")
self.write("\n" + self.indent() + ")")
else:
# this is a Blank Node
self.subjectDone(node)
self.depth += 2
self.write("[\n")
self.depth -= 1
self.predicateList(node, newline=False)
self.write("\n" + self.indent(1) + "[\n")
self.depth += 1
self.predicateList(node)
self.depth -= 1
self.write("\n" + self.indent(1) + "]")

Expand Down Expand Up @@ -279,6 +277,7 @@ def predicateList(self, subject, newline=False):
self.write(" ;\n" + self.indent(1))
self.verb(predicate, newline=True)
self.objectList(properties[predicate])
self.write(" ;")

def verb(self, node, newline=False):
self.path(node, VERB, newline)
Expand All @@ -291,11 +290,13 @@ def objectList(self, objects):
self.depth += depthmod
first_nl = False
if count > 1:
self.write("\n" + self.indent(1))
if not isinstance(objects[0], BNode):
self.write("\n" + self.indent(1))
first_nl = True
self.path(objects[0], OBJECT, newline=first_nl)
for obj in objects[1:]:
self.write(" ,\n")
self.write(self.indent(1))
self.write(" ,")
if not isinstance(obj, BNode):
self.write("\n" + self.indent(1))
self.path(obj, OBJECT, newline=True)
self.depth -= depthmod
Loading
Loading