Skip to content

Commit 5ee8bd7

Browse files
nicholascaraucampiapre-commit-ci[bot]
authored
Longturtle improvements (#2500)
* small updates to the longturtle serializer and an improved test for it * add docco --------- Co-authored-by: Iwan Aucamp <aucampia@gmail.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent b1ff089 commit 5ee8bd7

File tree

3 files changed

+268
-210
lines changed

3 files changed

+268
-210
lines changed

docs/plugin_serializers.rst

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ xml :class:`~rdflib.plugins.serializers.rdfxml.XMLSerializer`
3232

3333
JSON-LD
3434
-------
35-
JSON-LD - 'json-ld' - has been incorprated in rdflib since v6.0.0.
35+
JSON-LD - 'json-ld' - has been incorporated into RDFLib since v6.0.0.
3636

3737
HexTuples
3838
---------
@@ -43,3 +43,12 @@ Hextuple) will be an empty string.
4343

4444
For context-aware (multi-graph) serialization, the 'graph' field of the default graph will be an empty string and
4545
the values for other graphs will be Blank Node IDs or IRIs.
46+
47+
Longturtle
48+
----------
49+
Longturtle is just the turtle format with newlines preferred over compactness - multiple nodes on the same line
50+
to enhance the format's text file version control (think Git) friendliness - and more modern forms of prefix markers -
51+
PREFIX instead of @prefix - to make it as similar to SPARQL as possible.
52+
53+
Longturtle is Turtle 1.1 compliant and will work wherever ordinary turtle works, however some very old parsers don't
54+
understand PREFIX, only @prefix...

rdflib/plugins/serializers/longturtle.py

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
on the start of the next line
1414
* uses default encoding (encode()) is used instead of "latin-1"
1515
16-
- Nicholas Car, 2021
16+
- Nicholas Car, 2023
1717
"""
1818

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

103103
self.endDocument()
104-
self.write("\n")
105104

106105
self.base = None
107106

@@ -168,21 +167,20 @@ def s_default(self, subject):
168167
self.path(subject, SUBJECT)
169168
self.write("\n" + self.indent())
170169
self.predicateList(subject)
171-
self.write(" ;\n.")
170+
self.write("\n.")
172171
return True
173172

174173
def s_squared(self, subject):
175174
if (self._references[subject] > 0) or not isinstance(subject, BNode):
176175
return False
177176
self.write("\n" + self.indent() + "[]")
178-
self.predicateList(subject)
177+
self.predicateList(subject, newline=False)
179178
self.write(" ;\n.")
180179
return True
181180

182181
def path(self, node, position, newline=False):
183182
if not (
184-
self.p_squared(node, position, newline)
185-
or self.p_default(node, position, newline)
183+
self.p_squared(node, position) or self.p_default(node, position, newline)
186184
):
187185
raise Error("Cannot serialize node '%s'" % (node,))
188186

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

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

210-
def p_squared(self, node, position, newline=False):
208+
def p_squared(
209+
self,
210+
node,
211+
position,
212+
):
211213
if (
212214
not isinstance(node, BNode)
213215
or node in self._serialized
@@ -216,23 +218,19 @@ def p_squared(self, node, position, newline=False):
216218
):
217219
return False
218220

219-
if not newline:
220-
self.write(" ")
221-
222221
if self.isValidList(node):
223222
# this is a list
224223
self.depth += 2
225-
self.write("(\n")
226-
self.depth -= 1
224+
self.write(" (\n")
225+
self.depth -= 2
227226
self.doList(node)
228-
self.depth -= 1
229-
self.write("\n" + self.indent(1) + ")")
227+
self.write("\n" + self.indent() + ")")
230228
else:
229+
# this is a Blank Node
231230
self.subjectDone(node)
232-
self.depth += 2
233-
self.write("[\n")
234-
self.depth -= 1
235-
self.predicateList(node, newline=False)
231+
self.write("\n" + self.indent(1) + "[\n")
232+
self.depth += 1
233+
self.predicateList(node)
236234
self.depth -= 1
237235
self.write("\n" + self.indent(1) + "]")
238236

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

283282
def verb(self, node, newline=False):
284283
self.path(node, VERB, newline)
@@ -291,11 +290,13 @@ def objectList(self, objects):
291290
self.depth += depthmod
292291
first_nl = False
293292
if count > 1:
294-
self.write("\n" + self.indent(1))
293+
if not isinstance(objects[0], BNode):
294+
self.write("\n" + self.indent(1))
295295
first_nl = True
296296
self.path(objects[0], OBJECT, newline=first_nl)
297297
for obj in objects[1:]:
298-
self.write(" ,\n")
299-
self.write(self.indent(1))
298+
self.write(" ,")
299+
if not isinstance(obj, BNode):
300+
self.write("\n" + self.indent(1))
300301
self.path(obj, OBJECT, newline=True)
301302
self.depth -= depthmod

0 commit comments

Comments
 (0)