n3 3.0.0-alpha.4 → 3.0.0-alpha.6
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 +56 -0
- package/browser/n3.esm.min.js +15 -16
- package/browser/n3.min.js +15 -16
- package/lib/N3Lexer.js +255 -160
- package/lib/N3Parser.js +70 -32
- package/lib/N3Reasoner.js +1 -1
- package/lib/N3Store.js +50 -6
- package/lib/N3StreamParser.js +4 -0
- package/lib/N3Writer.js +65 -19
- package/lib/Util.js +1 -1
- package/package.json +2 -29
- package/src/N3Lexer.js +269 -171
- package/src/N3Parser.js +81 -32
- package/src/N3Reasoner.js +1 -1
- package/src/N3Store.js +61 -9
- package/src/N3StreamParser.js +2 -0
- package/src/N3Writer.js +70 -23
- package/src/Util.js +1 -1
package/lib/N3Parser.js
CHANGED
|
@@ -11,6 +11,10 @@ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e
|
|
|
11
11
|
// **N3Parser** parses N3 documents.
|
|
12
12
|
|
|
13
13
|
let blankNodePrefix = 0;
|
|
14
|
+
// Detects `.` and `..` path segments in an IRI
|
|
15
|
+
const dotSegments = /(^|\/)\.\.?($|[/#?])/;
|
|
16
|
+
// Detects `.` and `..` segments in the path of an IRI, ignoring its query and fragment
|
|
17
|
+
const pathDotSegments = /^[^?#]*(?:^|\/)\.\.?(?:$|[/#?])/;
|
|
14
18
|
|
|
15
19
|
// ## Constructor
|
|
16
20
|
class N3Parser {
|
|
@@ -54,10 +58,17 @@ class N3Parser {
|
|
|
54
58
|
return null;
|
|
55
59
|
};
|
|
56
60
|
this._blankNodePrefix = typeof options.blankNodePrefix !== 'string' ? '' : options.blankNodePrefix.replace(/^(?!_:)/, '_:');
|
|
61
|
+
// Map the token types of additional directives (@name and NAME) to their names
|
|
62
|
+
this._directives = null;
|
|
63
|
+
if (options.directives) {
|
|
64
|
+
this._directives = Object.create(null);
|
|
65
|
+
for (const name of options.directives) this._directives[`@${name.toLowerCase()}`] = this._directives[name.toUpperCase()] = name;
|
|
66
|
+
}
|
|
57
67
|
this._lexer = options.lexer || new _N3Lexer.default({
|
|
58
68
|
lineMode: isLineMode,
|
|
59
69
|
n3: isN3,
|
|
60
|
-
isImpliedBy: this._isImpliedBy
|
|
70
|
+
isImpliedBy: this._isImpliedBy,
|
|
71
|
+
directives: options.directives
|
|
61
72
|
});
|
|
62
73
|
// Disable explicit quantifiers by default
|
|
63
74
|
this._explicitQuantifiers = !!options.explicitQuantifiers;
|
|
@@ -66,6 +77,9 @@ class N3Parser {
|
|
|
66
77
|
// Disable parsing of unsupported versions by default
|
|
67
78
|
this._parseUnsupportedVersions = !!options.parseUnsupportedVersions;
|
|
68
79
|
this._version = options.version;
|
|
80
|
+
// Maximum nesting depth of triple terms (default 1024; Infinity disables the limit)
|
|
81
|
+
const maxTripleTermDepth = options.maxTripleTermDepth;
|
|
82
|
+
this._maxTripleTermDepth = maxTripleTermDepth === Infinity || Number.isInteger(maxTripleTermDepth) && maxTripleTermDepth >= 0 ? maxTripleTermDepth : 1024;
|
|
69
83
|
}
|
|
70
84
|
|
|
71
85
|
// ## Static class methods
|
|
@@ -82,6 +96,7 @@ class N3Parser {
|
|
|
82
96
|
if (!baseIRI) {
|
|
83
97
|
this._base = '';
|
|
84
98
|
this._basePath = '';
|
|
99
|
+
this._basePathHasDotSegments = false;
|
|
85
100
|
} else {
|
|
86
101
|
// Remove fragment if present
|
|
87
102
|
const fragmentPos = baseIRI.indexOf('#');
|
|
@@ -91,12 +106,31 @@ class N3Parser {
|
|
|
91
106
|
const queryPos = baseIRI.indexOf('?');
|
|
92
107
|
const path = queryPos < 0 ? baseIRI : baseIRI.substr(0, queryPos);
|
|
93
108
|
this._basePath = baseIRI.indexOf('/') < 0 ? baseIRI : path.substr(0, path.lastIndexOf('/') + 1);
|
|
94
|
-
|
|
109
|
+
const base = baseIRI;
|
|
110
|
+
baseIRI = baseIRI.match(/^(?:([a-z][a-z0-9+.-]*:))?(\/\/[^\/?#]*)?/i);
|
|
95
111
|
this._baseRoot = baseIRI[0];
|
|
96
112
|
this._baseScheme = baseIRI[1];
|
|
113
|
+
// If the base has an authority but an empty path,
|
|
114
|
+
// relative IRIs merge under the path '/' (RFC 3986 §5.2.3)
|
|
115
|
+
if (baseIRI[2] !== undefined && (base.length === this._baseRoot.length || base[this._baseRoot.length] === '?')) this._basePath = `${this._baseRoot}/`;
|
|
116
|
+
// Check once whether resolving against the base path needs to remove dot segments
|
|
117
|
+
this._basePathHasDotSegments = dotSegments.test(this._basePath);
|
|
97
118
|
}
|
|
98
119
|
}
|
|
99
120
|
|
|
121
|
+
// ### `_enterTripleTerm` stores the current parsing context when entering a triple term,
|
|
122
|
+
// failing if triple terms nest deeper than the maximum depth
|
|
123
|
+
_enterTripleTerm(type, subject, predicate, token) {
|
|
124
|
+
if (this._tripleTermDepth >= this._maxTripleTermDepth) {
|
|
125
|
+
this._error(`Triple terms nested deeper than ${this._maxTripleTermDepth} level${this._maxTripleTermDepth === 1 ? '' : 's'}`, token);
|
|
126
|
+
return false;
|
|
127
|
+
}
|
|
128
|
+
this._tripleTermDepth++;
|
|
129
|
+
this._saveContext(type, this._graph, subject, predicate, null);
|
|
130
|
+
this._graph = null;
|
|
131
|
+
return true;
|
|
132
|
+
}
|
|
133
|
+
|
|
100
134
|
// ### `_saveContext` stores the current parsing context
|
|
101
135
|
// when entering a new scope (list, blank node, formula)
|
|
102
136
|
_saveContext(type, graph, subject, predicate, object) {
|
|
@@ -127,7 +161,7 @@ class N3Parser {
|
|
|
127
161
|
// Prefix and base declarations are scoped to their formula,
|
|
128
162
|
// so record prefix changes to undo them when the formula ends
|
|
129
163
|
if (type === 'formula') {
|
|
130
|
-
context.base = [this._base, this._basePath, this._baseRoot, this._baseScheme];
|
|
164
|
+
context.base = [this._base, this._basePath, this._baseRoot, this._baseScheme, this._basePathHasDotSegments];
|
|
131
165
|
this._prefixChanges = [];
|
|
132
166
|
}
|
|
133
167
|
this._contextStack.push(context);
|
|
@@ -167,7 +201,7 @@ class N3Parser {
|
|
|
167
201
|
if (this._n3Mode) {
|
|
168
202
|
this._inversePredicate = context.inverse;
|
|
169
203
|
this._expectOf = context.expectOf;
|
|
170
|
-
if (type === 'formula') [this._base, this._basePath, this._baseRoot, this._baseScheme] = context.base;
|
|
204
|
+
if (type === 'formula') [this._base, this._basePath, this._baseRoot, this._baseScheme, this._basePathHasDotSegments] = context.base;
|
|
171
205
|
if (this._prefixChanges !== context.prefixChanges) {
|
|
172
206
|
undoChanges(this._prefixes, this._prefixChanges);
|
|
173
207
|
this._prefixChanges = context.prefixChanges;
|
|
@@ -219,8 +253,13 @@ class N3Parser {
|
|
|
219
253
|
}
|
|
220
254
|
case 'GRAPH':
|
|
221
255
|
if (this._supportsNamedGraphs) return this._readNamedGraphLabel;
|
|
222
|
-
// Otherwise, the next token must be a subject
|
|
256
|
+
// Otherwise, the next token must be a subject, unless it is an additional directive
|
|
223
257
|
default:
|
|
258
|
+
if (this._directives !== null && token.type in this._directives && this._graph === null) {
|
|
259
|
+
this._sparqlStyle = token.type[0] !== '@';
|
|
260
|
+
this._directiveCallback(this._directives[token.type]);
|
|
261
|
+
return this._readDeclarationPunctuation;
|
|
262
|
+
}
|
|
224
263
|
return this._readSubject(token);
|
|
225
264
|
}
|
|
226
265
|
}
|
|
@@ -339,13 +378,9 @@ class N3Parser {
|
|
|
339
378
|
}
|
|
340
379
|
case '<<(':
|
|
341
380
|
if (!this._n3Mode) return this._error('Disallowed triple term as subject', token);
|
|
342
|
-
this.
|
|
343
|
-
this._graph = null;
|
|
344
|
-
return this._readSubject;
|
|
381
|
+
return this._enterTripleTerm('<<(', null, null, token) && this._readSubject;
|
|
345
382
|
case '<<':
|
|
346
|
-
this.
|
|
347
|
-
this._graph = null;
|
|
348
|
-
return this._readSubject;
|
|
383
|
+
return this._enterTripleTerm('<<', null, null, token) && this._readSubject;
|
|
349
384
|
default:
|
|
350
385
|
// Read the subject entity
|
|
351
386
|
if ((this._subject = this._readEntity(token)) === undefined) return;
|
|
@@ -468,13 +503,9 @@ class N3Parser {
|
|
|
468
503
|
this._saveContext('formula', this._graph, this._subject, this._predicate, this._graph = this._factory.blankNode());
|
|
469
504
|
return this._readInFormulaContext;
|
|
470
505
|
case '<<(':
|
|
471
|
-
this.
|
|
472
|
-
this._graph = null;
|
|
473
|
-
return this._readSubject;
|
|
506
|
+
return this._enterTripleTerm('<<(', this._subject, this._predicate, token) && this._readSubject;
|
|
474
507
|
case '<<':
|
|
475
|
-
this.
|
|
476
|
-
this._graph = null;
|
|
477
|
-
return this._readSubject;
|
|
508
|
+
return this._enterTripleTerm('<<', this._subject, this._predicate, token) && this._readSubject;
|
|
478
509
|
default:
|
|
479
510
|
// Read the object entity
|
|
480
511
|
if ((this._object = this._readEntity(token)) === undefined) return;
|
|
@@ -669,13 +700,8 @@ class N3Parser {
|
|
|
669
700
|
this._subject = null;
|
|
670
701
|
return this._readInFormulaContext;
|
|
671
702
|
case '<<(':
|
|
672
|
-
this._saveContext('<<(', this._graph, null, null, null);
|
|
673
|
-
this._graph = null;
|
|
674
|
-
next = this._readSubject;
|
|
675
|
-
break;
|
|
676
703
|
case '<<':
|
|
677
|
-
this.
|
|
678
|
-
this._graph = null;
|
|
704
|
+
if (!this._enterTripleTerm(token.type, null, null, token)) return;
|
|
679
705
|
next = this._readSubject;
|
|
680
706
|
break;
|
|
681
707
|
default:
|
|
@@ -1007,7 +1033,8 @@ class N3Parser {
|
|
|
1007
1033
|
// ### `_readVersion` reads version string declaration
|
|
1008
1034
|
_readVersion(token) {
|
|
1009
1035
|
if (token.type !== 'literal') return this._error('Expected literal to follow version declaration', token);
|
|
1010
|
-
|
|
1036
|
+
// Only short strings are allowed, so no numbers or booleans (which have a datatype prefix)
|
|
1037
|
+
if (token.prefix !== '' || token.tripleQuoted) return this._error('Version declarations must use single quotes', token);
|
|
1011
1038
|
this._versionCallback(token.value);
|
|
1012
1039
|
if (!this._isValidVersion(token.value)) return this._error(`Detected unsupported version: "${token.value}"`, token);
|
|
1013
1040
|
return this._readDeclarationPunctuation;
|
|
@@ -1167,6 +1194,7 @@ class N3Parser {
|
|
|
1167
1194
|
// Read the quad and restore the previous context
|
|
1168
1195
|
const quad = this._createQuad(this._subject, this._predicate, this._object, this._graph, this._inversePredicate);
|
|
1169
1196
|
this._restoreContext('<<(', token);
|
|
1197
|
+
this._tripleTermDepth--;
|
|
1170
1198
|
|
|
1171
1199
|
// If we're in a list, continue processing that list
|
|
1172
1200
|
const stack = this._contextStack,
|
|
@@ -1202,6 +1230,7 @@ class N3Parser {
|
|
|
1202
1230
|
this._tripleTerm = null;
|
|
1203
1231
|
const reifier = this._readTripleTerm();
|
|
1204
1232
|
this._restoreContext('<<', token);
|
|
1233
|
+
this._tripleTermDepth--;
|
|
1205
1234
|
|
|
1206
1235
|
// // If we're in a list, continue processing that list
|
|
1207
1236
|
const stack = this._contextStack,
|
|
@@ -1426,19 +1455,25 @@ class N3Parser {
|
|
|
1426
1455
|
}
|
|
1427
1456
|
// Resolve root-relative IRIs at the root of the base IRI
|
|
1428
1457
|
case '/':
|
|
1429
|
-
// Resolve scheme-relative IRIs to the scheme
|
|
1430
|
-
|
|
1458
|
+
// Resolve scheme-relative IRIs to the scheme,
|
|
1459
|
+
// keeping the reference's authority intact (RFC 3986 §5.2.4)
|
|
1460
|
+
if (iri[1] !== '/') return this._baseRoot + this._removeDotSegments(iri);
|
|
1461
|
+
// Without a base scheme, a leading ':' marks where the authority starts
|
|
1462
|
+
return this._baseScheme ? this._removeDotSegments(this._baseScheme + iri) : this._removeDotSegments(`:${iri}`).substr(1);
|
|
1431
1463
|
// Resolve all other IRIs at the base IRI's path
|
|
1432
1464
|
default:
|
|
1433
1465
|
// Relative IRIs cannot contain a colon in the first path segment
|
|
1434
|
-
|
|
1466
|
+
if (/^[^/:]*:/.test(iri)) return null;
|
|
1467
|
+
// Only scan the joined IRI for dot segments if either part can contain them,
|
|
1468
|
+
// as the base path can be long and the joined IRI would need to be copied
|
|
1469
|
+
return this._basePathHasDotSegments || pathDotSegments.test(iri) ? this._removeDotSegments(this._basePath + iri) : this._basePath + iri;
|
|
1435
1470
|
}
|
|
1436
1471
|
}
|
|
1437
1472
|
|
|
1438
1473
|
// ### `_removeDotSegments` resolves './' and '../' path segments in an IRI as per RFC3986
|
|
1439
1474
|
_removeDotSegments(iri) {
|
|
1440
1475
|
// Don't modify the IRI if it does not contain any dot segments
|
|
1441
|
-
if (
|
|
1476
|
+
if (!dotSegments.test(iri)) return iri;
|
|
1442
1477
|
|
|
1443
1478
|
// Start with an imaginary slash before the IRI in order to resolve trailing './' and '../'
|
|
1444
1479
|
const length = iri.length;
|
|
@@ -1454,8 +1489,8 @@ class N3Parser {
|
|
|
1454
1489
|
if (pathStart < 0) {
|
|
1455
1490
|
// Skip two slashes before the authority
|
|
1456
1491
|
if (iri[++i] === '/' && iri[++i] === '/')
|
|
1457
|
-
// Skip to
|
|
1458
|
-
while ((pathStart = i + 1) < length && iri[pathStart] !== '/') i = pathStart;
|
|
1492
|
+
// Skip to the end of the authority
|
|
1493
|
+
while ((pathStart = i + 1) < length && iri[pathStart] !== '/' && iri[pathStart] !== '?' && iri[pathStart] !== '#') i = pathStart;
|
|
1459
1494
|
}
|
|
1460
1495
|
break;
|
|
1461
1496
|
// Don't modify a query string or fragment
|
|
@@ -1503,12 +1538,13 @@ class N3Parser {
|
|
|
1503
1538
|
parse(input, quadCallback, prefixCallback, versionCallback) {
|
|
1504
1539
|
// The second parameter also accepts an object of named callbacks.
|
|
1505
1540
|
// As a second and third parameter it still accepts a separate quadCallback and prefixCallback for backward compatibility as well
|
|
1506
|
-
let onQuad, onPrefix, onComment, onVersion, onToken, onTokenEnd;
|
|
1507
|
-
if (quadCallback && (quadCallback.onQuad || quadCallback.onPrefix || quadCallback.onComment || quadCallback.onVersion || quadCallback.onToken || quadCallback.onTokenEnd)) {
|
|
1541
|
+
let onQuad, onPrefix, onComment, onVersion, onDirective, onToken, onTokenEnd;
|
|
1542
|
+
if (quadCallback && (quadCallback.onQuad || quadCallback.onPrefix || quadCallback.onComment || quadCallback.onVersion || quadCallback.onDirective || quadCallback.onToken || quadCallback.onTokenEnd)) {
|
|
1508
1543
|
onQuad = quadCallback.onQuad;
|
|
1509
1544
|
onPrefix = quadCallback.onPrefix;
|
|
1510
1545
|
onComment = quadCallback.onComment;
|
|
1511
1546
|
onVersion = quadCallback.onVersion;
|
|
1547
|
+
onDirective = quadCallback.onDirective;
|
|
1512
1548
|
onToken = quadCallback.onToken;
|
|
1513
1549
|
onTokenEnd = quadCallback.onTokenEnd;
|
|
1514
1550
|
} else {
|
|
@@ -1526,6 +1562,7 @@ class N3Parser {
|
|
|
1526
1562
|
if (this._n3Mode && this._implicitEmptyPrefix && this._base) this._prefixes[''] = this._resolveIRI('#');
|
|
1527
1563
|
this._prefixCallback = onPrefix || noop;
|
|
1528
1564
|
this._versionCallback = onVersion || noop;
|
|
1565
|
+
this._directiveCallback = onDirective || noop;
|
|
1529
1566
|
this._inversePredicate = false;
|
|
1530
1567
|
this._expectOf = false;
|
|
1531
1568
|
this._quantified = Object.create(null);
|
|
@@ -1533,6 +1570,7 @@ class N3Parser {
|
|
|
1533
1570
|
this._prefixChanges = null;
|
|
1534
1571
|
this._quantifiedChanges = null;
|
|
1535
1572
|
this._emptyFormula = false;
|
|
1573
|
+
this._tripleTermDepth = 0;
|
|
1536
1574
|
let readToken = token => {
|
|
1537
1575
|
return this._readCallback = this._readCallback(token);
|
|
1538
1576
|
};
|
package/lib/N3Reasoner.js
CHANGED
|
@@ -154,7 +154,7 @@ class N3Reasoner {
|
|
|
154
154
|
premise,
|
|
155
155
|
conclusion
|
|
156
156
|
}) {
|
|
157
|
-
const varMapping =
|
|
157
|
+
const varMapping = Object.create(null);
|
|
158
158
|
const toId = value => value.termType === 'Variable' ?
|
|
159
159
|
// If the term is a variable, then create an empty object that values can be placed into
|
|
160
160
|
varMapping[value.value] = varMapping[value.value] || {} :
|
package/lib/N3Store.js
CHANGED
|
@@ -116,6 +116,31 @@ function difference(s1, s2, depth = 4) {
|
|
|
116
116
|
return target;
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
+
// Returns the key of a term in the entity index.
|
|
120
|
+
// Keys mark the term type by their first character, so the IRI of a named node
|
|
121
|
+
// that starts with such a marker (as relative IRIs can) is wrapped in < and >.
|
|
122
|
+
const markedIRI = /^[?_"[.<]/;
|
|
123
|
+
function entityKey(term) {
|
|
124
|
+
// Strings are term ids, which only need wrapping when they are IRIs starting with <
|
|
125
|
+
if (typeof term === 'string') return term.charCodeAt(0) !== 0x3C || term === '<>' ? term : `<${term}>`;
|
|
126
|
+
// IDs of IRIs usually start with a lowercase scheme letter, which never marks a term type
|
|
127
|
+
const id = (0, _N3DataFactory.termToId)(term);
|
|
128
|
+
if (id.charCodeAt(0) >= 0x61 || !term) return id;
|
|
129
|
+
// Keys of quoted triples are built from the keys of their components
|
|
130
|
+
if (term.termType === 'Quad') return JSON.stringify(quadKeyParts(term));
|
|
131
|
+
return term.termType !== 'NamedNode' || !markedIRI.test(term.value) ? id : `<${term.value}>`;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Returns the keys of the components of a quad, nested like the parts of its internal id
|
|
135
|
+
function quadKeyParts(quad) {
|
|
136
|
+
const parts = [nestedKey(quad.subject), nestedKey(quad.predicate), nestedKey(quad.object)];
|
|
137
|
+
if (quad.graph && !(0, _N3Util.isDefaultGraph)(quad.graph)) parts.push(nestedKey(quad.graph));
|
|
138
|
+
return parts;
|
|
139
|
+
}
|
|
140
|
+
function nestedKey(term) {
|
|
141
|
+
return term.termType === 'Quad' ? quadKeyParts(term) : entityKey(term);
|
|
142
|
+
}
|
|
143
|
+
|
|
119
144
|
// ## Constructor
|
|
120
145
|
class N3EntityIndex {
|
|
121
146
|
constructor(options = {}) {
|
|
@@ -132,6 +157,9 @@ class N3EntityIndex {
|
|
|
132
157
|
this._factory = options.factory || _N3DataFactory.default;
|
|
133
158
|
}
|
|
134
159
|
_termFromId(id) {
|
|
160
|
+
// A key in < and > is a named node
|
|
161
|
+
if (id[0] === '<') return this._factory.namedNode(id.substring(1, id.length - 1));
|
|
162
|
+
// A key starting with . is a quoted triple
|
|
135
163
|
if (id[0] === '.') {
|
|
136
164
|
const entities = this._entities;
|
|
137
165
|
const terms = id.split('.');
|
|
@@ -148,12 +176,25 @@ class N3EntityIndex {
|
|
|
148
176
|
let g;
|
|
149
177
|
return s && p && o && ((0, _N3Util.isDefaultGraph)(term.graph) || (g = this._termToNumericId(term.graph))) && this._ids[g ? `.${s}.${p}.${o}.${g}` : `.${s}.${p}.${o}`];
|
|
150
178
|
}
|
|
151
|
-
return this.
|
|
179
|
+
return typeof term === 'string' ? this._stringToNumericId(term) : this._ids[entityKey(term)];
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// Returns the numeric id of a term given as a string id
|
|
183
|
+
_stringToNumericId(term) {
|
|
184
|
+
// The string is the key unless it is an IRI starting with <. Read the first character
|
|
185
|
+
// from the stored key after a match, which is cheaper than from a concatenated string.
|
|
186
|
+
const id = this._ids[term];
|
|
187
|
+
if (id ? this._entities[id].charCodeAt(0) !== 0x3C : term.charCodeAt(0) !== 0x3C) return id;
|
|
188
|
+
return term === '<>' ? id : this._ids[`<${term}>`];
|
|
152
189
|
}
|
|
153
190
|
_termToNewNumericId(term) {
|
|
191
|
+
if (typeof term === 'string') return this._stringToNumericId(term) || this._addEntity(entityKey(term));
|
|
154
192
|
// This assumes that no graph term is present - we may wish to error if there is one
|
|
155
|
-
const str = term && term.termType === 'Quad' ? `.${this._termToNewNumericId(term.subject)}.${this._termToNewNumericId(term.predicate)}.${this._termToNewNumericId(term.object)}${(0, _N3Util.isDefaultGraph)(term.graph) ? '' : `.${this._termToNewNumericId(term.graph)}`}` : (
|
|
156
|
-
return this._ids[str] ||
|
|
193
|
+
const str = term && term.termType === 'Quad' ? `.${this._termToNewNumericId(term.subject)}.${this._termToNewNumericId(term.predicate)}.${this._termToNewNumericId(term.object)}${(0, _N3Util.isDefaultGraph)(term.graph) ? '' : `.${this._termToNewNumericId(term.graph)}`}` : entityKey(term);
|
|
194
|
+
return this._ids[str] || this._addEntity(str);
|
|
195
|
+
}
|
|
196
|
+
_addEntity(key) {
|
|
197
|
+
return this._ids[this._entities[++this._id] = key] = this._id;
|
|
157
198
|
}
|
|
158
199
|
createBlankNode(suggestedName) {
|
|
159
200
|
let name, index;
|
|
@@ -576,8 +617,11 @@ class N3Store {
|
|
|
576
617
|
}
|
|
577
618
|
|
|
578
619
|
// ### `removeQuads` removes multiple quads from the store
|
|
620
|
+
// returns `true` if all quads were removed, `false` if some were not found
|
|
579
621
|
removeQuads(quads) {
|
|
580
|
-
|
|
622
|
+
let removed = true;
|
|
623
|
+
for (let i = 0; i < quads.length; i++) removed = this.removeQuad(quads[i]) && removed;
|
|
624
|
+
return removed;
|
|
581
625
|
}
|
|
582
626
|
|
|
583
627
|
// ### `remove` removes a stream of quads from the store
|
|
@@ -1305,7 +1349,7 @@ function intersectMatchPatterns(left, right) {
|
|
|
1305
1349
|
for (let i = 0; i < 4; i++) {
|
|
1306
1350
|
const leftTerm = left[i],
|
|
1307
1351
|
rightTerm = right[i];
|
|
1308
|
-
if (leftTerm === null || leftTerm === undefined) result[i] = rightTerm;else if (rightTerm === null || rightTerm === undefined || (
|
|
1352
|
+
if (leftTerm === null || leftTerm === undefined) result[i] = rightTerm;else if (rightTerm === null || rightTerm === undefined || entityKey(leftTerm) === entityKey(rightTerm)) result[i] = leftTerm;else return false;
|
|
1309
1353
|
}
|
|
1310
1354
|
return result;
|
|
1311
1355
|
}
|
|
@@ -1368,7 +1412,7 @@ class DatasetCoreAndReadableStream extends _readableStream.Readable {
|
|
|
1368
1412
|
object,
|
|
1369
1413
|
graph
|
|
1370
1414
|
} = this;
|
|
1371
|
-
return !this._matchesNothing && (subject === null || subject === undefined || (
|
|
1415
|
+
return !this._matchesNothing && (subject === null || subject === undefined || entityKey(subject) === entityKey(quad.subject)) && (predicate === null || predicate === undefined || entityKey(predicate) === entityKey(quad.predicate)) && (object === null || object === undefined || entityKey(object) === entityKey(quad.object)) && (graph === null || graph === undefined || entityKey(graph) === entityKey(quad.graph));
|
|
1372
1416
|
}
|
|
1373
1417
|
|
|
1374
1418
|
// ### `_assertMatchesPattern` rejects a Quad outside this view.
|
package/lib/N3StreamParser.js
CHANGED
|
@@ -28,6 +28,10 @@ class N3StreamParser extends _readableStream.Transform {
|
|
|
28
28
|
// Emit prefixes through the `prefix` event
|
|
29
29
|
onPrefix: (prefix, uri) => {
|
|
30
30
|
this.emit('prefix', prefix, uri);
|
|
31
|
+
},
|
|
32
|
+
// Emit additional directives through the `directive` event
|
|
33
|
+
onDirective: name => {
|
|
34
|
+
this.emit('directive', name);
|
|
31
35
|
}
|
|
32
36
|
};
|
|
33
37
|
if (options && options.comments) callbacks.onComment = comment => {
|
package/lib/N3Writer.js
CHANGED
|
@@ -18,10 +18,19 @@ const {
|
|
|
18
18
|
rdf,
|
|
19
19
|
xsd
|
|
20
20
|
} = _IRIs.default;
|
|
21
|
+
const {
|
|
22
|
+
hasOwnProperty
|
|
23
|
+
} = Object.prototype;
|
|
21
24
|
|
|
22
|
-
// Characters in
|
|
25
|
+
// Characters that require escaping in Turtle, TriG, and N3,
|
|
26
|
+
// where characters outside the Basic Multilingual Plane are escaped as well
|
|
23
27
|
const escape = /["\\\t\n\r\b\f\u0000-\u0019\ud800-\udbff]/,
|
|
24
28
|
escapeAll = /["\\\t\n\r\b\f\u0000-\u0019]|[\ud800-\udbff][\udc00-\udfff]/g,
|
|
29
|
+
// Characters that require escaping in canonical N-Triples and N-Quads:
|
|
30
|
+
// U+0000–U+001F, `"`, `\`, U+007F, U+FFFE, and U+FFFF.
|
|
31
|
+
// A negated class is as fast to test as a shorter class listing characters.
|
|
32
|
+
canonicalEscape = /[^ !#-\[\]-~\u0080-\uFFFD]/,
|
|
33
|
+
canonicalEscapeAll = /[^ !#-\[\]-~\u0080-\uFFFD]/g,
|
|
25
34
|
escapedCharacters = {
|
|
26
35
|
'\\': '\\\\',
|
|
27
36
|
'"': '\\"',
|
|
@@ -32,6 +41,9 @@ const escape = /["\\\t\n\r\b\f\u0000-\u0019\ud800-\udbff]/,
|
|
|
32
41
|
'\f': '\\f'
|
|
33
42
|
};
|
|
34
43
|
|
|
44
|
+
// Characters that a version label cannot contain
|
|
45
|
+
const invalidVersionLabel = /["\\\u0000-\u001f\u007f]|[\ud800-\udbff](?![\udc00-\udfff])|(?:^|[^\ud800-\udbff])[\udc00-\udfff]/;
|
|
46
|
+
|
|
35
47
|
// ## Placeholder class to represent already pretty-printed terms
|
|
36
48
|
class SerializedTerm extends _N3DataFactory.Term {
|
|
37
49
|
// Pretty-printed nodes are not equal to any other node
|
|
@@ -71,12 +83,20 @@ class N3Writer {
|
|
|
71
83
|
this._endStream = options.end === undefined ? true : !!options.end;
|
|
72
84
|
}
|
|
73
85
|
|
|
86
|
+
// A version label is written as-is, so it cannot contain characters that need escaping,
|
|
87
|
+
// nor unpaired surrogates (which cannot be encoded)
|
|
88
|
+
if (options.version && invalidVersionLabel.test(options.version)) throw new Error(`Invalid version label: ${JSON.stringify(options.version)}`);
|
|
89
|
+
|
|
74
90
|
// Initialize writer, depending on the format
|
|
75
91
|
this._subject = null;
|
|
76
92
|
if (!/triple|quad/i.test(options.format)) {
|
|
77
93
|
this._lineMode = false;
|
|
94
|
+
this._escape = escape, this._escapeAll = escapeAll, this._characterReplacer = characterReplacer;
|
|
78
95
|
this._graph = DEFAULTGRAPH;
|
|
96
|
+
if (options.version) this._write(`@version "${options.version}".\n`);
|
|
79
97
|
this._prefixIRIs = Object.create(null);
|
|
98
|
+
// Escaped prefix IRIs and names for the prefix matcher, computed once per prefix
|
|
99
|
+
this._prefixPatterns = Object.create(null);
|
|
80
100
|
if (options.baseIRI) {
|
|
81
101
|
this._baseIri = new _BaseIRI.default(options.baseIRI);
|
|
82
102
|
if (options.writeBase !== false) this._write(`@base <${options.baseIRI}>.\n`);
|
|
@@ -85,6 +105,10 @@ class N3Writer {
|
|
|
85
105
|
} else {
|
|
86
106
|
this._lineMode = true;
|
|
87
107
|
this._writeQuad = this._writeQuadLine;
|
|
108
|
+
// N-Triples and N-Quads are written in their canonical form
|
|
109
|
+
this._escape = canonicalEscape, this._escapeAll = canonicalEscapeAll;
|
|
110
|
+
this._characterReplacer = canonicalCharacterReplacer;
|
|
111
|
+
if (options.version) this._write(`VERSION "${options.version}"\n`);
|
|
88
112
|
}
|
|
89
113
|
}
|
|
90
114
|
|
|
@@ -100,6 +124,15 @@ class N3Writer {
|
|
|
100
124
|
this._outputStream.write(string, 'utf8', callback);
|
|
101
125
|
}
|
|
102
126
|
|
|
127
|
+
// ### `_endStatement` finishes a pending statement and closes an open graph block
|
|
128
|
+
_endStatement() {
|
|
129
|
+
if (this._subject !== null) {
|
|
130
|
+
this._write(this._inDefaultGraph ? '.\n' : '\n}\n');
|
|
131
|
+
this._subject = null;
|
|
132
|
+
this._graph = DEFAULTGRAPH;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
103
136
|
// ### `_writeQuad` writes the quad to the output stream
|
|
104
137
|
_writeQuad(subject, predicate, object, graph, done) {
|
|
105
138
|
try {
|
|
@@ -163,7 +196,7 @@ class N3Writer {
|
|
|
163
196
|
// A blank node or list is represented as-is
|
|
164
197
|
if (entity.termType !== 'NamedNode') {
|
|
165
198
|
// If it is a list head, pretty-print it
|
|
166
|
-
if (this._lists &&
|
|
199
|
+
if (this._lists && hasOwnProperty.call(this._lists, entity.value)) entity = this.list(this._lists[entity.value]);
|
|
167
200
|
// Terms from this library already hold their serialization as id
|
|
168
201
|
if (entity instanceof _N3DataFactory.Term) return entity.id;
|
|
169
202
|
return entity.termType === 'Variable' ? `?${entity.value}` : `_:${entity.value}`;
|
|
@@ -174,9 +207,9 @@ class N3Writer {
|
|
|
174
207
|
iri = this._baseIri.toRelative(iri);
|
|
175
208
|
}
|
|
176
209
|
// Escape special characters
|
|
177
|
-
if (
|
|
210
|
+
if (this._escape.test(iri)) iri = iri.replace(this._escapeAll, this._characterReplacer);
|
|
178
211
|
// Try to represent the IRI as prefixed name, unless no prefixes were added
|
|
179
|
-
const prefixMatch = this._hasPrefixes ? this._prefixRegex.exec(iri) : null;
|
|
212
|
+
const prefixMatch = this._hasPrefixes ? (this._prefixRegex || this._createPrefixRegex()).exec(iri) : null;
|
|
180
213
|
return !prefixMatch ? `<${iri}>` : this._prefixIRIs[prefixMatch[1]] + prefixMatch[2];
|
|
181
214
|
}
|
|
182
215
|
|
|
@@ -184,7 +217,7 @@ class N3Writer {
|
|
|
184
217
|
_encodeLiteral(literal) {
|
|
185
218
|
// Escape special characters
|
|
186
219
|
let value = literal.value;
|
|
187
|
-
if (
|
|
220
|
+
if (this._escape.test(value)) value = value.replace(this._escapeAll, this._characterReplacer);
|
|
188
221
|
|
|
189
222
|
// Write a language-tagged literal
|
|
190
223
|
const language = literal.language;
|
|
@@ -254,7 +287,9 @@ class N3Writer {
|
|
|
254
287
|
object,
|
|
255
288
|
graph
|
|
256
289
|
}) {
|
|
257
|
-
|
|
290
|
+
// Canonical N-Triples and N-Quads put spaces inside the delimiters
|
|
291
|
+
const space = this._lineMode ? ' ' : '';
|
|
292
|
+
return `<<(${space}${this._encodeSubject(subject)} ${this._encodePredicate(predicate)} ${this._encodeObject(object)}${(0, _N3Util.isDefaultGraph)(graph) ? '' : ` ${this._encodeIriOrBlank(graph)}`}${space})>>`;
|
|
258
293
|
}
|
|
259
294
|
|
|
260
295
|
// ### `_blockedWrite` replaces `_write` after the writer has been closed
|
|
@@ -296,26 +331,29 @@ class N3Writer {
|
|
|
296
331
|
if (typeof iri !== 'string') iri = iri.value;
|
|
297
332
|
hasPrefixes = true;
|
|
298
333
|
// Finish a possible pending quad
|
|
299
|
-
|
|
300
|
-
this._write(this._inDefaultGraph ? '.\n' : '\n}\n');
|
|
301
|
-
this._subject = null, this._graph = '';
|
|
302
|
-
}
|
|
334
|
+
this._endStatement();
|
|
303
335
|
// Store and write the prefix
|
|
304
336
|
this._prefixIRIs[iri] = prefix += ':';
|
|
337
|
+
this._prefixPatterns[iri] = (0, _Util.escapeRegex)(iri);
|
|
305
338
|
this._write(`@prefix ${prefix} <${iri}>.\n`);
|
|
306
339
|
}
|
|
307
|
-
// Recreate the prefix matcher
|
|
340
|
+
// Recreate the prefix matcher when it is next needed, so that adding
|
|
341
|
+
// prefixes one by one does not rebuild it for every prefix
|
|
308
342
|
if (hasPrefixes) {
|
|
309
343
|
this._hasPrefixes = true;
|
|
310
|
-
|
|
311
|
-
for (const prefixIRI in this._prefixIRIs) IRIlist += IRIlist ? `|${prefixIRI}` : prefixIRI;
|
|
312
|
-
IRIlist = (0, _Util.escapeRegex)(IRIlist, /[\]\/\(\)\*\+\?\.\\\$]/g, '\\$&');
|
|
313
|
-
this._prefixRegex = new RegExp(`^(${IRIlist})([_a-zA-Z0-9](?:\\.?[\\-_a-zA-Z0-9])*)$`);
|
|
344
|
+
this._prefixRegex = null;
|
|
314
345
|
}
|
|
315
346
|
// End a prefix block with a newline
|
|
316
347
|
this._write(hasPrefixes ? '\n' : '', done);
|
|
317
348
|
}
|
|
318
349
|
|
|
350
|
+
// ### `_createPrefixRegex` creates the matcher for the current prefixes
|
|
351
|
+
_createPrefixRegex() {
|
|
352
|
+
let IRIlist = '';
|
|
353
|
+
for (const prefixIRI in this._prefixPatterns) IRIlist += IRIlist ? `|${this._prefixPatterns[prefixIRI]}` : this._prefixPatterns[prefixIRI];
|
|
354
|
+
return this._prefixRegex = new RegExp(`^(${IRIlist})([_a-zA-Z0-9](?:\\.?[\\-_a-zA-Z0-9])*)$`);
|
|
355
|
+
}
|
|
356
|
+
|
|
319
357
|
// ### `blank` creates a blank node with the given content
|
|
320
358
|
blank(predicate, object) {
|
|
321
359
|
let children = predicate,
|
|
@@ -367,10 +405,7 @@ class N3Writer {
|
|
|
367
405
|
// ### `end` signals the end of the output stream
|
|
368
406
|
end(done) {
|
|
369
407
|
// Finish a possible pending quad
|
|
370
|
-
|
|
371
|
-
this._write(this._inDefaultGraph ? '.\n' : '\n}\n');
|
|
372
|
-
this._subject = null;
|
|
373
|
-
}
|
|
408
|
+
this._endStatement();
|
|
374
409
|
// Disallow further writing
|
|
375
410
|
this._write = this._blockedWrite;
|
|
376
411
|
|
|
@@ -405,4 +440,15 @@ function characterReplacer(character) {
|
|
|
405
440
|
}
|
|
406
441
|
}
|
|
407
442
|
return result;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
// Replaces a character by its canonical N-Triples escape:
|
|
446
|
+
// a short escape where one exists, and an upper-case `\uXXXX` escape otherwise
|
|
447
|
+
function canonicalCharacterReplacer(character) {
|
|
448
|
+
let result = escapedCharacters[character];
|
|
449
|
+
if (result === undefined) {
|
|
450
|
+
result = character.charCodeAt(0).toString(16).toUpperCase();
|
|
451
|
+
result = '\\u0000'.substr(0, 6 - result.length) + result;
|
|
452
|
+
}
|
|
453
|
+
return result;
|
|
408
454
|
}
|
package/lib/Util.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "n3",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.6",
|
|
4
4
|
"description": "Lightning fast, asynchronous, streaming Turtle / N3 / RDF library.",
|
|
5
5
|
"author": "Ruben Verborgh <ruben.verborgh@gmail.com>",
|
|
6
6
|
"keywords": [
|
|
@@ -60,44 +60,17 @@
|
|
|
60
60
|
"test": "jest",
|
|
61
61
|
"lint": "eslint src perf test spec",
|
|
62
62
|
"prepare": "npm run build",
|
|
63
|
-
"spec": "
|
|
64
|
-
"spec-1-1": "npm run spec-1-1-turtle && npm run spec-1-1-ntriples && npm run spec-1-1-nquads && npm run spec-1-1-trig",
|
|
63
|
+
"spec": "node spec/run.js",
|
|
65
64
|
"spec-1-1-earl": "npm run spec-1-1-earl-turtle && npm run spec-1-1-earl-ntriples && npm run spec-1-1-earl-nquads && npm run spec-1-1-earl-trig",
|
|
66
|
-
"spec-1-1-ntriples": "rdf-test-suite spec/parser.js https://w3c.github.io/rdf-tests/rdf/rdf11/rdf-n-triples/manifest.ttl -i '{ \"format\": \"n-triples\" }' -c .rdf-test-suite-cache/",
|
|
67
|
-
"spec-1-1-nquads": "rdf-test-suite spec/parser.js https://w3c.github.io/rdf-tests/rdf/rdf11/rdf-n-quads/manifest.ttl -i '{ \"format\": \"n-quads\" }' -c .rdf-test-suite-cache/",
|
|
68
|
-
"spec-1-1-turtle": "rdf-test-suite spec/parser.js https://w3c.github.io/rdf-tests/rdf/rdf11/rdf-turtle/manifest.ttl -i '{ \"format\": \"turtle\" }' -c .rdf-test-suite-cache/ --skip \"(bad-numeric-escape|bareword_decimal)\"",
|
|
69
|
-
"spec-1-1-trig": "rdf-test-suite spec/parser.js https://w3c.github.io/rdf-tests/rdf/rdf11/rdf-trig/manifest.ttl -i '{ \"format\": \"trig\" }' -c .rdf-test-suite-cache/ --skip \"(bad-numeric-escape|IRI-resolution-01)\"",
|
|
70
65
|
"spec-1-1-earl-ntriples": "rdf-test-suite spec/parser.js https://w3c.github.io/rdf-tests/rdf/rdf11/rdf-n-triples/manifest.ttl -i '{ \"format\": \"n-triples\" }' -c .rdf-test-suite-cache/ -o earl -p spec/earl-meta.json > spec/earl-ntriples.ttl",
|
|
71
66
|
"spec-1-1-earl-nquads": "rdf-test-suite spec/parser.js https://w3c.github.io/rdf-tests/rdf/rdf11/rdf-n-quads/manifest.ttl -i '{ \"format\": \"n-quads\" }' -c .rdf-test-suite-cache/ -o earl -p spec/earl-meta.json > spec/earl-nquads.ttl",
|
|
72
67
|
"spec-1-1-earl-turtle": "rdf-test-suite spec/parser.js https://w3c.github.io/rdf-tests/rdf/rdf11/rdf-turtle/manifest.ttl -i '{ \"format\": \"turtle\" }' -c .rdf-test-suite-cache/ -o earl -p spec/earl-meta.json > spec/earl-turtle.ttl",
|
|
73
68
|
"spec-1-1-earl-trig": "rdf-test-suite spec/parser.js https://w3c.github.io/rdf-tests/rdf/rdf11/rdf-trig/manifest.ttl -i '{ \"format\": \"trig\" }' -c .rdf-test-suite-cache/ -o earl -p spec/earl-meta.json > spec/earl-trig.ttl",
|
|
74
|
-
"spec-1-2": "npm run spec-1-2-turtle && npm run spec-1-2-ntriples && npm run spec-1-2-nquads && npm run spec-1-2-trig && npm run spec-1-2-turtle-eval && npm run spec-1-2-trig-eval",
|
|
75
69
|
"spec-1-2-earl": "npm run spec-1-2-earl-turtle && npm run spec-1-2-earl-ntriples && npm run spec-1-2-earl-nquads && npm run spec-1-2-earl-trig",
|
|
76
|
-
"spec-1-2-ntriples": "rdf-test-suite spec/parser.js https://w3c.github.io/rdf-tests/rdf/rdf12/rdf-n-triples/syntax/manifest.ttl -i '{ \"format\": \"n-triples\" }' -c .rdf-test-suite-cache/",
|
|
77
|
-
"spec-1-2-nquads": "rdf-test-suite spec/parser.js https://w3c.github.io/rdf-tests/rdf/rdf12/rdf-n-quads/syntax/manifest.ttl -i '{ \"format\": \"n-quads\" }' -c .rdf-test-suite-cache/",
|
|
78
|
-
"spec-1-2-turtle": "rdf-test-suite spec/parser.js https://w3c.github.io/rdf-tests/rdf/rdf12/rdf-turtle/syntax/manifest.ttl -i '{ \"format\": \"turtle\" }' -c .rdf-test-suite-cache/",
|
|
79
|
-
"spec-1-2-trig": "rdf-test-suite spec/parser.js https://w3c.github.io/rdf-tests/rdf/rdf12/rdf-trig/syntax/manifest.ttl -i '{ \"format\": \"trig\" }' -c .rdf-test-suite-cache/",
|
|
80
|
-
"spec-1-2-turtle-eval": "rdf-test-suite spec/parser.js https://w3c.github.io/rdf-tests/rdf/rdf12/rdf-turtle/eval/manifest.ttl -i '{ \"format\": \"turtle\" }' -c .rdf-test-suite-cache/",
|
|
81
|
-
"spec-1-2-trig-eval": "rdf-test-suite spec/parser.js https://w3c.github.io/rdf-tests/rdf/rdf12/rdf-trig/eval/manifest.ttl -i '{ \"format\": \"trig\" }' -c .rdf-test-suite-cache/",
|
|
82
70
|
"spec-1-2-earl-ntriples": "rdf-test-suite spec/parser.js https://w3c.github.io/rdf-tests/rdf/rdf12/rdf-n-triples/syntax/manifest.ttl -i '{ \"format\": \"n-triples\" }' -c .rdf-test-suite-cache/ -o earl -p spec/earl-meta.json > spec/earl-ntriples.ttl",
|
|
83
71
|
"spec-1-2-earl-nquads": "rdf-test-suite spec/parser.js https://w3c.github.io/rdf-tests/rdf/rdf12/rdf-n-quads/syntax/manifest.ttl -i '{ \"format\": \"n-quads\" }' -c .rdf-test-suite-cache/ -o earl -p spec/earl-meta.json > spec/earl-nquads.ttl",
|
|
84
72
|
"spec-1-2-earl-turtle": "rdf-test-suite spec/parser.js https://w3c.github.io/rdf-tests/rdf/rdf12/rdf-turtle/syntax/manifest.ttl -i '{ \"format\": \"turtle\" }' -c .rdf-test-suite-cache/ -o earl -p spec/earl-meta.json > spec/earl-turtle.ttl",
|
|
85
73
|
"spec-1-2-earl-trig": "rdf-test-suite spec/parser.js https://w3c.github.io/rdf-tests/rdf/rdf12/rdf-trig/syntax/manifest.ttl -i '{ \"format\": \"trig\" }' -c .rdf-test-suite-cache/ -o earl -p spec/earl-meta.json > spec/earl-trig.ttl",
|
|
86
|
-
"spec-writer": "npm run spec-writer-1-1-turtle && npm run spec-writer-1-1-ntriples && npm run spec-writer-1-1-nquads && npm run spec-writer-1-1-trig && npm run spec-writer-1-2-turtle && npm run spec-writer-1-2-ntriples && npm run spec-writer-1-2-nquads && npm run spec-writer-1-2-trig && npm run spec-writer-1-2-turtle-eval && npm run spec-writer-1-2-trig-eval",
|
|
87
|
-
"spec-writer-1-1-turtle": "rdf-test-suite spec/writer.js https://w3c.github.io/rdf-tests/rdf/rdf11/rdf-turtle/manifest.ttl -i '{ \"format\": \"turtle\" }' -c .rdf-test-suite-cache/ --skip \"(bad-numeric-escape|bareword_decimal)\"",
|
|
88
|
-
"spec-writer-1-1-ntriples": "rdf-test-suite spec/writer.js https://w3c.github.io/rdf-tests/rdf/rdf11/rdf-n-triples/manifest.ttl -i '{ \"format\": \"n-triples\" }' -c .rdf-test-suite-cache/",
|
|
89
|
-
"spec-writer-1-1-nquads": "rdf-test-suite spec/writer.js https://w3c.github.io/rdf-tests/rdf/rdf11/rdf-n-quads/manifest.ttl -i '{ \"format\": \"n-quads\" }' -c .rdf-test-suite-cache/",
|
|
90
|
-
"spec-writer-1-1-trig": "rdf-test-suite spec/writer.js https://w3c.github.io/rdf-tests/rdf/rdf11/rdf-trig/manifest.ttl -i '{ \"format\": \"trig\" }' -c .rdf-test-suite-cache/ --skip \"(bad-numeric-escape|IRI-resolution-01)\"",
|
|
91
|
-
"spec-writer-1-2-turtle": "rdf-test-suite spec/writer.js https://w3c.github.io/rdf-tests/rdf/rdf12/rdf-turtle/syntax/manifest.ttl -i '{ \"format\": \"turtle\" }' -c .rdf-test-suite-cache/",
|
|
92
|
-
"spec-writer-1-2-ntriples": "rdf-test-suite spec/writer.js https://w3c.github.io/rdf-tests/rdf/rdf12/rdf-n-triples/syntax/manifest.ttl -i '{ \"format\": \"n-triples\" }' -c .rdf-test-suite-cache/",
|
|
93
|
-
"spec-writer-1-2-nquads": "rdf-test-suite spec/writer.js https://w3c.github.io/rdf-tests/rdf/rdf12/rdf-n-quads/syntax/manifest.ttl -i '{ \"format\": \"n-quads\" }' -c .rdf-test-suite-cache/",
|
|
94
|
-
"spec-writer-1-2-trig": "rdf-test-suite spec/writer.js https://w3c.github.io/rdf-tests/rdf/rdf12/rdf-trig/syntax/manifest.ttl -i '{ \"format\": \"trig\" }' -c .rdf-test-suite-cache/",
|
|
95
|
-
"spec-writer-1-2-turtle-eval": "rdf-test-suite spec/writer.js https://w3c.github.io/rdf-tests/rdf/rdf12/rdf-turtle/eval/manifest.ttl -i '{ \"format\": \"turtle\" }' -c .rdf-test-suite-cache/",
|
|
96
|
-
"spec-writer-1-2-trig-eval": "rdf-test-suite spec/writer.js https://w3c.github.io/rdf-tests/rdf/rdf12/rdf-trig/eval/manifest.ttl -i '{ \"format\": \"trig\" }' -c .rdf-test-suite-cache/",
|
|
97
|
-
"spec-n3": "npm run spec-n3-parser && npm run spec-n3-extended",
|
|
98
|
-
"spec-n3-fetch": "sh scripts/fetch-n3-tests.sh",
|
|
99
|
-
"spec-n3-parser": "npm run spec-n3-fetch && rdf-test-suite spec/parser.js https://w3c-cg.github.io/N3/tests/N3Tests/manifest-parser.ttl -i '{ \"format\": \"text/n3\" }' -m 'https://w3c-cg.github.io/N3/tests/~.n3-tests/tests/'",
|
|
100
|
-
"spec-n3-extended": "npm run spec-n3-fetch && rdf-test-suite spec/parser.js https://w3c-cg.github.io/N3/tests/N3Tests/manifest-extended.ttl -i '{ \"format\": \"text/n3\" }' -m 'https://w3c-cg.github.io/N3/tests/~.n3-tests/tests/'",
|
|
101
74
|
"spec-clean": "rm -rf .rdf-test-suite-cache/ .n3-tests/",
|
|
102
75
|
"docs": "cd src && docco *.js -o ../docs && cd .."
|
|
103
76
|
},
|