n3 1.26.0 → 2.0.0-beta.2
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/README.md +0 -7
- package/browser/n3.min.js +1 -1
- package/lib/IRIs.js +4 -3
- package/lib/N3DataFactory.js +34 -6
- package/lib/N3Lexer.js +35 -17
- package/lib/N3Parser.js +206 -44
- package/lib/N3Store.js +23 -24
- package/lib/N3Util.js +0 -6
- package/lib/N3Writer.js +11 -9
- package/lib/index.js +2 -9
- package/package.json +24 -12
- package/src/IRIs.js +7 -6
- package/src/N3DataFactory.js +38 -9
- package/src/N3Lexer.js +37 -17
- package/src/N3Parser.js +229 -53
- package/src/N3Store.js +21 -22
- package/src/N3Util.js +0 -5
- package/src/N3Writer.js +11 -7
- package/src/index.js +0 -3
- package/lib/BaseIRI.js +0 -93
- package/lib/Util.js +0 -9
- package/src/BaseIRI.js +0 -101
- package/src/Util.js +0 -3
package/lib/IRIs.js
CHANGED
|
@@ -20,7 +20,9 @@ var _default = exports.default = {
|
|
|
20
20
|
nil: `${RDF}nil`,
|
|
21
21
|
first: `${RDF}first`,
|
|
22
22
|
rest: `${RDF}rest`,
|
|
23
|
-
langString: `${RDF}langString
|
|
23
|
+
langString: `${RDF}langString`,
|
|
24
|
+
dirLangString: `${RDF}dirLangString`,
|
|
25
|
+
reifies: `${RDF}reifies`
|
|
24
26
|
},
|
|
25
27
|
owl: {
|
|
26
28
|
sameAs: 'http://www.w3.org/2002/07/owl#sameAs'
|
|
@@ -30,7 +32,6 @@ var _default = exports.default = {
|
|
|
30
32
|
forAll: `${SWAP}reify#forAll`
|
|
31
33
|
},
|
|
32
34
|
log: {
|
|
33
|
-
implies: `${SWAP}log#implies
|
|
34
|
-
isImpliedBy: `${SWAP}log#isImpliedBy`
|
|
35
|
+
implies: `${SWAP}log#implies`
|
|
35
36
|
}
|
|
36
37
|
};
|
package/lib/N3DataFactory.js
CHANGED
|
@@ -99,8 +99,17 @@ class Literal extends Term {
|
|
|
99
99
|
// Find the last quotation mark (e.g., '"abc"@en-us')
|
|
100
100
|
const id = this.id;
|
|
101
101
|
let atPos = id.lastIndexOf('"') + 1;
|
|
102
|
+
const dirPos = id.lastIndexOf('--');
|
|
102
103
|
// If "@" it follows, return the remaining substring; empty otherwise
|
|
103
|
-
return atPos < id.length && id[atPos++] === '@' ? id.substr(atPos).toLowerCase() : '';
|
|
104
|
+
return atPos < id.length && id[atPos++] === '@' ? (dirPos > atPos ? id.substr(0, dirPos) : id).substr(atPos).toLowerCase() : '';
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// ### The direction of this literal
|
|
108
|
+
get direction() {
|
|
109
|
+
// Find the last double dash (e.g., '"abc"@en-us--ltr')
|
|
110
|
+
const id = this.id;
|
|
111
|
+
const atPos = id.lastIndexOf('--') + 2;
|
|
112
|
+
return atPos > 1 && atPos < id.length ? id.substr(atPos).toLowerCase() : '';
|
|
104
113
|
}
|
|
105
114
|
|
|
106
115
|
// ### The datatype IRI of this literal
|
|
@@ -116,8 +125,8 @@ class Literal extends Term {
|
|
|
116
125
|
const char = dtPos < id.length ? id[dtPos] : '';
|
|
117
126
|
// If "^" it follows, return the remaining substring
|
|
118
127
|
return char === '^' ? id.substr(dtPos + 2) :
|
|
119
|
-
// If "@" follows, return rdf:langString; xsd:string otherwise
|
|
120
|
-
char !== '@' ? xsd.string : rdf.langString;
|
|
128
|
+
// If "@" follows, return rdf:langString or rdf:dirLangString; xsd:string otherwise
|
|
129
|
+
char !== '@' ? xsd.string : id.indexOf('--', dtPos) > 0 ? rdf.dirLangString : rdf.langString;
|
|
121
130
|
}
|
|
122
131
|
|
|
123
132
|
// ### Returns whether this object represents the same term as the other
|
|
@@ -126,13 +135,14 @@ class Literal extends Term {
|
|
|
126
135
|
// equality can be computed through ids
|
|
127
136
|
if (other instanceof Literal) return this.id === other.id;
|
|
128
137
|
// Otherwise, compare term type, value, language, and datatype
|
|
129
|
-
return !!other && !!other.datatype && this.termType === other.termType && this.value === other.value && this.language === other.language && this.datatype.value === other.datatype.value;
|
|
138
|
+
return !!other && !!other.datatype && this.termType === other.termType && this.value === other.value && this.language === other.language && (this.direction === other.direction || this.direction === '' && !other.direction) && this.datatype.value === other.datatype.value;
|
|
130
139
|
}
|
|
131
140
|
toJSON() {
|
|
132
141
|
return {
|
|
133
142
|
termType: this.termType,
|
|
134
143
|
value: this.value,
|
|
135
144
|
language: this.language,
|
|
145
|
+
direction: this.direction,
|
|
136
146
|
datatype: {
|
|
137
147
|
termType: 'NamedNode',
|
|
138
148
|
value: this.datatypeString
|
|
@@ -225,7 +235,20 @@ function termFromId(id, factory, nested) {
|
|
|
225
235
|
if (id[id.length - 1] === '"') return factory.literal(id.substr(1, id.length - 2));
|
|
226
236
|
// Literal with datatype or language
|
|
227
237
|
const endPos = id.lastIndexOf('"', id.length - 1);
|
|
228
|
-
|
|
238
|
+
let languageOrDatatype;
|
|
239
|
+
if (id[endPos + 1] === '@') {
|
|
240
|
+
languageOrDatatype = id.substr(endPos + 2);
|
|
241
|
+
const dashDashIndex = languageOrDatatype.lastIndexOf('--');
|
|
242
|
+
if (dashDashIndex > 0 && dashDashIndex < languageOrDatatype.length) {
|
|
243
|
+
languageOrDatatype = {
|
|
244
|
+
language: languageOrDatatype.substr(0, dashDashIndex),
|
|
245
|
+
direction: languageOrDatatype.substr(dashDashIndex + 2)
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
} else {
|
|
249
|
+
languageOrDatatype = factory.namedNode(id.substr(endPos + 3));
|
|
250
|
+
}
|
|
251
|
+
return factory.literal(id.substr(1, endPos - 1), languageOrDatatype);
|
|
229
252
|
case '[':
|
|
230
253
|
id = JSON.parse(id);
|
|
231
254
|
break;
|
|
@@ -258,7 +281,7 @@ function termToId(term, nested) {
|
|
|
258
281
|
case 'DefaultGraph':
|
|
259
282
|
return '';
|
|
260
283
|
case 'Literal':
|
|
261
|
-
return `"${term.value}"${term.language ? `@${term.language}` : term.datatype && term.datatype.value !== xsd.string ? `^^${term.datatype.value}` : ''}`;
|
|
284
|
+
return `"${term.value}"${term.language ? `@${term.language}${term.direction ? `--${term.direction}` : ''}` : term.datatype && term.datatype.value !== xsd.string ? `^^${term.datatype.value}` : ''}`;
|
|
262
285
|
case 'Quad':
|
|
263
286
|
const res = [termToId(term.subject, true), termToId(term.predicate, true), termToId(term.object, true)];
|
|
264
287
|
if (term.graph && term.graph.termType !== 'DefaultGraph') {
|
|
@@ -339,6 +362,11 @@ function literal(value, languageOrDataType) {
|
|
|
339
362
|
// Create a language-tagged string
|
|
340
363
|
if (typeof languageOrDataType === 'string') return new Literal(`"${value}"@${languageOrDataType.toLowerCase()}`);
|
|
341
364
|
|
|
365
|
+
// Create a language-tagged string with base direction
|
|
366
|
+
if (languageOrDataType !== undefined && !('termType' in languageOrDataType)) {
|
|
367
|
+
return new Literal(`"${value}"@${languageOrDataType.language.toLowerCase()}--${languageOrDataType.direction.toLowerCase()}`);
|
|
368
|
+
}
|
|
369
|
+
|
|
342
370
|
// Automatically determine datatype for booleans and numbers
|
|
343
371
|
let datatype = languageOrDataType ? languageOrDataType.value : '';
|
|
344
372
|
if (datatype === '') {
|
package/lib/N3Lexer.js
CHANGED
|
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
var _buffer = require("buffer");
|
|
8
|
+
var _queueMicrotask = _interopRequireDefault(require("queue-microtask"));
|
|
8
9
|
var _IRIs = _interopRequireDefault(require("./IRIs"));
|
|
9
10
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
10
11
|
// **N3Lexer** tokenizes N3 documents.
|
|
@@ -50,6 +51,7 @@ const lineModeRegExps = {
|
|
|
50
51
|
_unescapedIri: true,
|
|
51
52
|
_simpleQuotedString: true,
|
|
52
53
|
_langcode: true,
|
|
54
|
+
_dircode: true,
|
|
53
55
|
_blank: true,
|
|
54
56
|
_newline: true,
|
|
55
57
|
_comment: true,
|
|
@@ -67,15 +69,16 @@ class N3Lexer {
|
|
|
67
69
|
this._unescapedIri = /^<([^\x00-\x20<>\\"\{\}\|\^\`]*)>[ \t]*/; // IRI without escape sequences; no unescaping
|
|
68
70
|
this._simpleQuotedString = /^"([^"\\\r\n]*)"(?=[^"])/; // string without escape sequences
|
|
69
71
|
this._simpleApostropheString = /^'([^'\\\r\n]*)'(?=[^'])/;
|
|
70
|
-
this._langcode = /^@([a-z]+(?:-[a-z0-9]+)*)(?=[^a-z0-9
|
|
72
|
+
this._langcode = /^@([a-z]+(?:-[a-z0-9]+)*)(?=[^a-z0-9])/i;
|
|
73
|
+
this._dircode = /^--(ltr)|(rtl)/;
|
|
71
74
|
this._prefix = /^((?:[A-Za-z\xc0-\xd6\xd8-\xf6\xf8-\u02ff\u0370-\u037d\u037f-\u1fff\u200c\u200d\u2070-\u218f\u2c00-\u2fef\u3001-\ud7ff\uf900-\ufdcf\ufdf0-\ufffd]|[\ud800-\udb7f][\udc00-\udfff])(?:\.?[\-0-9A-Z_a-z\xb7\xc0-\xd6\xd8-\xf6\xf8-\u037d\u037f-\u1fff\u200c\u200d\u203f\u2040\u2070-\u218f\u2c00-\u2fef\u3001-\ud7ff\uf900-\ufdcf\ufdf0-\ufffd]|[\ud800-\udb7f][\udc00-\udfff])*)?:(?=[#\s<])/;
|
|
72
75
|
this._prefixed = /^((?:[A-Za-z\xc0-\xd6\xd8-\xf6\xf8-\u02ff\u0370-\u037d\u037f-\u1fff\u200c\u200d\u2070-\u218f\u2c00-\u2fef\u3001-\ud7ff\uf900-\ufdcf\ufdf0-\ufffd]|[\ud800-\udb7f][\udc00-\udfff])(?:\.?[\-0-9A-Z_a-z\xb7\xc0-\xd6\xd8-\xf6\xf8-\u037d\u037f-\u1fff\u200c\u200d\u203f\u2040\u2070-\u218f\u2c00-\u2fef\u3001-\ud7ff\uf900-\ufdcf\ufdf0-\ufffd]|[\ud800-\udb7f][\udc00-\udfff])*)?:((?:(?:[0-:A-Z_a-z\xc0-\xd6\xd8-\xf6\xf8-\u02ff\u0370-\u037d\u037f-\u1fff\u200c\u200d\u2070-\u218f\u2c00-\u2fef\u3001-\ud7ff\uf900-\ufdcf\ufdf0-\ufffd]|[\ud800-\udb7f][\udc00-\udfff]|%[0-9a-fA-F]{2}|\\[!#-\/;=?\-@_~])(?:(?:[\.\-0-:A-Z_a-z\xb7\xc0-\xd6\xd8-\xf6\xf8-\u037d\u037f-\u1fff\u200c\u200d\u203f\u2040\u2070-\u218f\u2c00-\u2fef\u3001-\ud7ff\uf900-\ufdcf\ufdf0-\ufffd]|[\ud800-\udb7f][\udc00-\udfff]|%[0-9a-fA-F]{2}|\\[!#-\/;=?\-@_~])*(?:[\-0-:A-Z_a-z\xb7\xc0-\xd6\xd8-\xf6\xf8-\u037d\u037f-\u1fff\u200c\u200d\u203f\u2040\u2070-\u218f\u2c00-\u2fef\u3001-\ud7ff\uf900-\ufdcf\ufdf0-\ufffd]|[\ud800-\udb7f][\udc00-\udfff]|%[0-9a-fA-F]{2}|\\[!#-\/;=?\-@_~]))?)?)(?:[ \t]+|(?=\.?[,;!\^\s#()\[\]\{\}"'<>]))/;
|
|
73
76
|
this._variable = /^\?(?:(?:[A-Z_a-z\xc0-\xd6\xd8-\xf6\xf8-\u02ff\u0370-\u037d\u037f-\u1fff\u200c\u200d\u2070-\u218f\u2c00-\u2fef\u3001-\ud7ff\uf900-\ufdcf\ufdf0-\ufffd]|[\ud800-\udb7f][\udc00-\udfff])(?:[\-0-:A-Z_a-z\xb7\xc0-\xd6\xd8-\xf6\xf8-\u037d\u037f-\u1fff\u200c\u200d\u203f\u2040\u2070-\u218f\u2c00-\u2fef\u3001-\ud7ff\uf900-\ufdcf\ufdf0-\ufffd]|[\ud800-\udb7f][\udc00-\udfff])*)(?=[.,;!\^\s#()\[\]\{\}"'<>])/;
|
|
74
77
|
this._blank = /^_:((?:[0-9A-Z_a-z\xc0-\xd6\xd8-\xf6\xf8-\u02ff\u0370-\u037d\u037f-\u1fff\u200c\u200d\u2070-\u218f\u2c00-\u2fef\u3001-\ud7ff\uf900-\ufdcf\ufdf0-\ufffd]|[\ud800-\udb7f][\udc00-\udfff])(?:\.?[\-0-9A-Z_a-z\xb7\xc0-\xd6\xd8-\xf6\xf8-\u037d\u037f-\u1fff\u200c\u200d\u203f\u2040\u2070-\u218f\u2c00-\u2fef\u3001-\ud7ff\uf900-\ufdcf\ufdf0-\ufffd]|[\ud800-\udb7f][\udc00-\udfff])*)(?:[ \t]+|(?=\.?[,;:\s#()\[\]\{\}"'<>]))/;
|
|
75
78
|
this._number = /^[\-+]?(?:(\d+\.\d*|\.?\d+)[eE][\-+]?|\d*(\.)?)\d+(?=\.?[,;:\s#()\[\]\{\}"'<>])/;
|
|
76
79
|
this._boolean = /^(?:true|false)(?=[.,;\s#()\[\]\{\}"'<>])/;
|
|
77
|
-
this.
|
|
78
|
-
this.
|
|
80
|
+
this._atKeyword = /^@[a-z]+(?=[\s#<:])/i;
|
|
81
|
+
this._keyword = /^(?:PREFIX|BASE|VERSION|GRAPH)(?=[\s#<])/i;
|
|
79
82
|
this._shortPredicates = /^a(?=[\s#()\[\]\{\}"'<>])/;
|
|
80
83
|
this._newline = /^[ \t]*(?:#[^\n\r]*)?(?:\r\n|\n|\r)[ \t]*/;
|
|
81
84
|
this._comment = /#([^\n\r]*)/;
|
|
@@ -83,9 +86,6 @@ class N3Lexer {
|
|
|
83
86
|
this._endOfFile = /^(?:#[^\n\r]*)?$/;
|
|
84
87
|
options = options || {};
|
|
85
88
|
|
|
86
|
-
// Whether the log:isImpliedBy predicate is supported
|
|
87
|
-
this._isImpliedBy = options.isImpliedBy;
|
|
88
|
-
|
|
89
89
|
// In line mode (N-Triples or N-Quads), only simple features may be parsed
|
|
90
90
|
if (this._lineMode = !!options.lineMode) {
|
|
91
91
|
this._n3Mode = false;
|
|
@@ -178,15 +178,15 @@ class N3Lexer {
|
|
|
178
178
|
if (value === null || illegalIriChars.test(value)) return reportSyntaxError(this);
|
|
179
179
|
type = 'IRI';
|
|
180
180
|
}
|
|
181
|
-
// Try to find a
|
|
182
|
-
else if (input.length >
|
|
181
|
+
// Try to find a triple term
|
|
182
|
+
else if (input.length > 2 && input[1] === '<' && input[2] === '(') type = '<<(', matchLength = 3;
|
|
183
|
+
// Try to find a reified triple
|
|
184
|
+
else if (!this._lineMode && input.length > (inputFinished ? 1 : 2) && input[1] === '<') type = '<<', matchLength = 2;
|
|
183
185
|
// Try to find a backwards implication arrow
|
|
184
|
-
else if (this._n3Mode && input.length > 1 && input[1] === '=')
|
|
185
|
-
matchLength = 2;
|
|
186
|
-
if (this._isImpliedBy) type = 'abbreviation', value = '<';else type = 'inverse', value = '>';
|
|
187
|
-
}
|
|
186
|
+
else if (this._n3Mode && input.length > 1 && input[1] === '=') type = 'inverse', matchLength = 2, value = '>';
|
|
188
187
|
break;
|
|
189
188
|
case '>':
|
|
189
|
+
// Try to find a reified triple
|
|
190
190
|
if (input.length > 1 && input[1] === '>') type = '>>', matchLength = 2;
|
|
191
191
|
break;
|
|
192
192
|
case '_':
|
|
@@ -235,9 +235,9 @@ class N3Lexer {
|
|
|
235
235
|
break;
|
|
236
236
|
case '@':
|
|
237
237
|
// Try to find a language code
|
|
238
|
-
if (this._previousMarker === 'literal' && (match = this._langcode.exec(input))) type = 'langcode', value = match[1];
|
|
238
|
+
if (this._previousMarker === 'literal' && (match = this._langcode.exec(input)) && match[1] !== 'version') type = 'langcode', value = match[1];
|
|
239
239
|
// Try to find a keyword
|
|
240
|
-
else if (match = this.
|
|
240
|
+
else if (match = this._atKeyword.exec(input)) type = match[0];
|
|
241
241
|
break;
|
|
242
242
|
case '.':
|
|
243
243
|
// Try to find a dot as punctuation
|
|
@@ -260,6 +260,12 @@ class N3Lexer {
|
|
|
260
260
|
case '9':
|
|
261
261
|
case '+':
|
|
262
262
|
case '-':
|
|
263
|
+
if (input[1] === '-') {
|
|
264
|
+
// Try to find a direction code
|
|
265
|
+
if (this._previousMarker === 'langcode' && (match = this._dircode.exec(input))) type = 'dircode', matchLength = 2, value = match[1] || match[2], matchLength = value.length + 2;
|
|
266
|
+
break;
|
|
267
|
+
}
|
|
268
|
+
|
|
263
269
|
// Try to find a number. Since it can contain (but not end with) a dot,
|
|
264
270
|
// we always need a non-dot character before deciding it is a number.
|
|
265
271
|
// Therefore, try inserting a space if we're at the end of the input.
|
|
@@ -274,8 +280,10 @@ class N3Lexer {
|
|
|
274
280
|
case 'P':
|
|
275
281
|
case 'G':
|
|
276
282
|
case 'g':
|
|
283
|
+
case 'V':
|
|
284
|
+
case 'v':
|
|
277
285
|
// Try to find a SPARQL-style keyword
|
|
278
|
-
if (match = this.
|
|
286
|
+
if (match = this._keyword.exec(input)) type = match[0].toUpperCase();else inconclusive = true;
|
|
279
287
|
break;
|
|
280
288
|
case 'f':
|
|
281
289
|
case 't':
|
|
@@ -295,13 +303,23 @@ class N3Lexer {
|
|
|
295
303
|
break;
|
|
296
304
|
case '!':
|
|
297
305
|
if (!this._n3Mode) break;
|
|
306
|
+
case ')':
|
|
307
|
+
if (!inputFinished && (input.length === 1 || input.length === 2 && input[1] === '>')) {
|
|
308
|
+
// Don't consume yet, as it *could* become a triple term end.
|
|
309
|
+
break;
|
|
310
|
+
}
|
|
311
|
+
// Try to find a triple term
|
|
312
|
+
if (input.length > 2 && input[1] === '>' && input[2] === '>') {
|
|
313
|
+
type = ')>>', matchLength = 3;
|
|
314
|
+
break;
|
|
315
|
+
}
|
|
298
316
|
case ',':
|
|
299
317
|
case ';':
|
|
300
318
|
case '[':
|
|
301
319
|
case ']':
|
|
302
320
|
case '(':
|
|
303
|
-
case ')':
|
|
304
321
|
case '}':
|
|
322
|
+
case '~':
|
|
305
323
|
if (!this._lineMode) {
|
|
306
324
|
matchLength = 1;
|
|
307
325
|
type = firstChar;
|
|
@@ -474,7 +492,7 @@ class N3Lexer {
|
|
|
474
492
|
if (typeof input === 'string') {
|
|
475
493
|
this._input = this._readStartingBom(input);
|
|
476
494
|
// If a callback was passed, asynchronously call it
|
|
477
|
-
if (typeof callback === 'function')
|
|
495
|
+
if (typeof callback === 'function') (0, _queueMicrotask.default)(() => this._tokenizeToEnd(callback, true));
|
|
478
496
|
// If no callback was passed, tokenize synchronously and return
|
|
479
497
|
else {
|
|
480
498
|
const tokens = [];
|