n3 2.4.0 → 2.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/N3Lexer.js CHANGED
@@ -88,6 +88,7 @@ class N3Lexer {
88
88
  this._boolean = /^(?:true|false)(?=[.,;!\^\s#()\[\]\{\}"'<>])/;
89
89
  this._atKeyword = /^@[a-z]+(?=[\s#<:])/i;
90
90
  this._keyword = /^(?:PREFIX|BASE|VERSION|GRAPH)(?=[\s#<])/i;
91
+ this._n3Id = /^id(?=[\s#<])/;
91
92
  this._shortPredicates = /^a(?=[\s#()\[\]\{\}"'<>])/;
92
93
  this._newline = /^[ \t]*(?:#[^\n\r]*)?(?:\r\n|\n|\r)[ \t]*/;
93
94
  this._comment = /#([^\n\r]*)/;
@@ -315,6 +316,10 @@ class N3Lexer {
315
316
  // Try to find an abbreviated predicate
316
317
  if (match = this._shortPredicates.exec(input)) type = 'abbreviation', value = 'a';else inconclusive = true;
317
318
  break;
319
+ case 'i':
320
+ // Try to find the IRI property list identifier
321
+ if (this._n3Mode && (match = this._n3Id.exec(input))) type = 'id';else inconclusive = true;
322
+ break;
318
323
  case '=':
319
324
  // Try to find an implication arrow or equals sign
320
325
  if (this._n3Mode && input.length > 1) {
package/lib/N3Parser.js CHANGED
@@ -36,6 +36,8 @@ class N3Parser {
36
36
  this._supportsQuads = !(isTurtle || isTriG || isNTriples || isN3);
37
37
  // Whether the log:isImpliedBy predicate is supported
38
38
  this._isImpliedBy = options.isImpliedBy;
39
+ // Whether an undeclared empty prefix resolves against the document IRI
40
+ this._implicitEmptyPrefix = !!options.implicitEmptyPrefix;
39
41
  // Whether an empty formula is read as the boolean literal true,
40
42
  // as in the N3 spec tests (opt-in until the next major version)
41
43
  this._emptyFormulaAsTrue = !!options.emptyFormulaAsTrue;
@@ -457,11 +459,33 @@ class N3Parser {
457
459
  if (parentParent.type === '<<') {
458
460
  return this._error('Unexpected compound blank node expression in reified triple', token);
459
461
  }
462
+ if (token.type === 'id') return this._readIriPropertyListId;
460
463
  this._predicate = null;
461
464
  return this._readPredicate(token);
462
465
  }
463
466
  }
464
467
 
468
+ // ### `_readIriPropertyListId` replaces a property list's blank node with its IRI
469
+ _readIriPropertyListId(token) {
470
+ const iri = this._readEntity(token);
471
+ if (iri === undefined) return;
472
+ if (iri.termType !== 'NamedNode') return this._error(`Expected IRI after id but got ${token.type}`, token);
473
+ const placeholder = this._subject;
474
+ this._subject = iri;
475
+ const context = this._contextStack[this._contextStack.length - 1];
476
+ if (context.subject === placeholder) context.subject = iri;
477
+ if (context.predicate === placeholder) context.predicate = iri;
478
+ if (context.object === placeholder) context.object = iri;
479
+ this._predicate = null;
480
+ return this._readIriPropertyListPredicate;
481
+ }
482
+
483
+ // ### `_readIriPropertyListPredicate` requires properties after an IRI property list ID
484
+ _readIriPropertyListPredicate(token) {
485
+ if (token.type === ';' || token.type === ']' || token.type === '.' || token.type === '}') return this._error(`Expected predicate but got ${token.type}`, token);
486
+ return this._readPredicate(token);
487
+ }
488
+
465
489
  // ### `_readBlankNodeTail` reads the end of a blank node
466
490
  _readBlankNodeTail(token) {
467
491
  if (token.type !== ']') return this._readBlankNodePunctuation(token);
@@ -1384,6 +1408,8 @@ class N3Parser {
1384
1408
  this._sparqlStyle = false;
1385
1409
  this._prefixes = Object.create(null);
1386
1410
  this._prefixes._ = this._blankNodePrefix ? this._blankNodePrefix.substr(2) : `b${blankNodePrefix++}_`;
1411
+ // Optionally bind the N3 empty prefix to the document's local namespace
1412
+ if (this._n3Mode && this._implicitEmptyPrefix && this._base) this._prefixes[''] = this._resolveIRI('#');
1387
1413
  this._prefixCallback = onPrefix || noop;
1388
1414
  this._versionCallback = onVersion || noop;
1389
1415
  this._inversePredicate = false;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n3",
3
- "version": "2.4.0",
3
+ "version": "2.6.0",
4
4
  "description": "Lightning fast, asynchronous, streaming Turtle / N3 / RDF library.",
5
5
  "author": "Ruben Verborgh <ruben.verborgh@gmail.com>",
6
6
  "keywords": [
package/src/N3Lexer.js CHANGED
@@ -57,6 +57,7 @@ export default class N3Lexer {
57
57
  this._boolean = /^(?:true|false)(?=[.,;!\^\s#()\[\]\{\}"'<>])/;
58
58
  this._atKeyword = /^@[a-z]+(?=[\s#<:])/i;
59
59
  this._keyword = /^(?:PREFIX|BASE|VERSION|GRAPH)(?=[\s#<])/i;
60
+ this._n3Id = /^id(?=[\s#<])/;
60
61
  this._shortPredicates = /^a(?=[\s#()\[\]\{\}"'<>])/;
61
62
  this._newline = /^[ \t]*(?:#[^\n\r]*)?(?:\r\n|\n|\r)[ \t]*/;
62
63
  this._comment = /#([^\n\r]*)/;
@@ -318,6 +319,14 @@ export default class N3Lexer {
318
319
  inconclusive = true;
319
320
  break;
320
321
 
322
+ case 'i':
323
+ // Try to find the IRI property list identifier
324
+ if (this._n3Mode && (match = this._n3Id.exec(input)))
325
+ type = 'id';
326
+ else
327
+ inconclusive = true;
328
+ break;
329
+
321
330
  case '=':
322
331
  // Try to find an implication arrow or equals sign
323
332
  if (this._n3Mode && input.length > 1) {
package/src/N3Parser.js CHANGED
@@ -29,6 +29,8 @@ export default class N3Parser {
29
29
  this._supportsQuads = !(isTurtle || isTriG || isNTriples || isN3);
30
30
  // Whether the log:isImpliedBy predicate is supported
31
31
  this._isImpliedBy = options.isImpliedBy;
32
+ // Whether an undeclared empty prefix resolves against the document IRI
33
+ this._implicitEmptyPrefix = !!options.implicitEmptyPrefix;
32
34
  // Whether an empty formula is read as the boolean literal true,
33
35
  // as in the N3 spec tests (opt-in until the next major version)
34
36
  this._emptyFormulaAsTrue = !!options.emptyFormulaAsTrue;
@@ -480,11 +482,41 @@ export default class N3Parser {
480
482
  if (parentParent.type === '<<') {
481
483
  return this._error('Unexpected compound blank node expression in reified triple', token);
482
484
  }
485
+ if (token.type === 'id')
486
+ return this._readIriPropertyListId;
483
487
  this._predicate = null;
484
488
  return this._readPredicate(token);
485
489
  }
486
490
  }
487
491
 
492
+ // ### `_readIriPropertyListId` replaces a property list's blank node with its IRI
493
+ _readIriPropertyListId(token) {
494
+ const iri = this._readEntity(token);
495
+ if (iri === undefined)
496
+ return;
497
+ if (iri.termType !== 'NamedNode')
498
+ return this._error(`Expected IRI after id but got ${token.type}`, token);
499
+
500
+ const placeholder = this._subject;
501
+ this._subject = iri;
502
+ const context = this._contextStack[this._contextStack.length - 1];
503
+ if (context.subject === placeholder)
504
+ context.subject = iri;
505
+ if (context.predicate === placeholder)
506
+ context.predicate = iri;
507
+ if (context.object === placeholder)
508
+ context.object = iri;
509
+ this._predicate = null;
510
+ return this._readIriPropertyListPredicate;
511
+ }
512
+
513
+ // ### `_readIriPropertyListPredicate` requires properties after an IRI property list ID
514
+ _readIriPropertyListPredicate(token) {
515
+ if (token.type === ';' || token.type === ']' || token.type === '.' || token.type === '}')
516
+ return this._error(`Expected predicate but got ${token.type}`, token);
517
+ return this._readPredicate(token);
518
+ }
519
+
488
520
  // ### `_readBlankNodeTail` reads the end of a blank node
489
521
  _readBlankNodeTail(token) {
490
522
  if (token.type !== ']')
@@ -1492,6 +1524,9 @@ export default class N3Parser {
1492
1524
  this._prefixes = Object.create(null);
1493
1525
  this._prefixes._ = this._blankNodePrefix ? this._blankNodePrefix.substr(2)
1494
1526
  : `b${blankNodePrefix++}_`;
1527
+ // Optionally bind the N3 empty prefix to the document's local namespace
1528
+ if (this._n3Mode && this._implicitEmptyPrefix && this._base)
1529
+ this._prefixes[''] = this._resolveIRI('#');
1495
1530
  this._prefixCallback = onPrefix || noop;
1496
1531
  this._versionCallback = onVersion || noop;
1497
1532
  this._inversePredicate = false;