n3 0.4.2 → 0.5.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/.eslintrc ADDED
@@ -0,0 +1,173 @@
1
+ {
2
+ env: {
3
+ node: true,
4
+ },
5
+
6
+ rules: {
7
+ // Possible Errors
8
+ comma-dangle: [2, "always-multiline"],
9
+ no-cond-assign: 0,
10
+ no-console: 2,
11
+ no-constant-condition: 0,
12
+ no-debugger: 2,
13
+ no-dupe-args: 2,
14
+ no-dupe-keys: 2,
15
+ no-duplicate-case: 2,
16
+ no-empty: 2,
17
+ no-empty-character-class: 2,
18
+ no-ex-assign: 2,
19
+ no-extra-boolean-cast: 2,
20
+ no-extra-parens: 0,
21
+ no-extra-semi: 2,
22
+ no-func-assign: 2,
23
+ no-inner-declarations: 2,
24
+ no-invalid-regexp: 2,
25
+ no-irregular-whitespace: 2,
26
+ no-negated-in-lhs: 2,
27
+ no-obj-calls: 2,
28
+ no-regex-spaces: 2,
29
+ no-sparse-arrays: 2,
30
+ no-unreachable: 2,
31
+ use-isnan: 2,
32
+ valid-jsdoc: 0,
33
+ valid-typeof: 2,
34
+ no-unexpected-multiline: 2,
35
+
36
+ // Best Practices
37
+ accessor-pairs: 2,
38
+ block-scoped-var: 2,
39
+ complexity: 0,
40
+ consistent-return: 0,
41
+ curly: 0,
42
+ default-case: 0,
43
+ dot-notation: 2,
44
+ dot-location: [2, "property"],
45
+ eqeqeq: 2,
46
+ guard-for-in: 0,
47
+ no-alert: 2,
48
+ no-caller: 2,
49
+ no-div-regex: 2,
50
+ no-else-return: 0,
51
+ no-empty-label: 2,
52
+ no-eq-null: 2,
53
+ no-eval: 2,
54
+ no-extend-native: 2,
55
+ no-extra-bind: 2,
56
+ no-fallthrough: 0,
57
+ no-floating-decimal: 2,
58
+ no-implicit-coercion: 0,
59
+ no-implied-eval: 2,
60
+ no-invalid-this: 2,
61
+ no-iterator: 2,
62
+ no-labels: 2,
63
+ no-lone-blocks: 2,
64
+ no-loop-func: 2,
65
+ no-multi-spaces: 0,
66
+ no-multi-str: 2,
67
+ no-native-reassign: 2,
68
+ no-new-func: 2,
69
+ no-new-wrappers: 2,
70
+ no-new: 2,
71
+ no-octal-escape: 2,
72
+ no-octal: 2,
73
+ no-param-reassign: 0,
74
+ no-process-env: 2,
75
+ no-proto: 2,
76
+ no-redeclare: 2,
77
+ no-return-assign: 0,
78
+ no-script-url: 2,
79
+ no-self-compare: 2,
80
+ no-sequences: 0, // allow the comma operator
81
+ no-throw-literal: 2,
82
+ no-unused-expressions: 0,
83
+ no-useless-call: 2,
84
+ no-void: 2,
85
+ no-warning-comments: 2,
86
+ no-with: 2,
87
+ radix: 2,
88
+ vars-on-top: 0,
89
+ wrap-iife: 2,
90
+ yoda: 2,
91
+
92
+ // Strict Mode
93
+ strict: [2, "never"],
94
+
95
+ // Variables
96
+ init-declarations: 0,
97
+ no-catch-shadow: 2,
98
+ no-delete-var: 2,
99
+ no-label-var: 2,
100
+ no-shadow-restricted-names: 2,
101
+ no-shadow: 0,
102
+ no-undef-init: 2,
103
+ no-undef: 2,
104
+ no-undefined: 0,
105
+ no-unused-vars: 0,
106
+ no-use-before-define: [2, "nofunc"],
107
+
108
+ // Node.js
109
+ callback-return: 0,
110
+ handle-callback-err: 2,
111
+ no-mixed-requires: 2,
112
+ no-new-require: 2,
113
+ no-path-concat: 2,
114
+ no-process-exit: 2,
115
+ no-restricted-modules: 2,
116
+ no-sync: 2,
117
+
118
+ // Stylistic Issues
119
+ array-bracket-spacing: 0,
120
+ block-spacing: 2,
121
+ brace-style: [2, "stroustrup", { allowSingleLine: true }],
122
+ camelcase: 2,
123
+ comma-spacing: 2,
124
+ comma-style: 2,
125
+ computed-property-spacing: 2,
126
+ consistent-this: 0,
127
+ eol-last: 2,
128
+ func-names: 0,
129
+ func-style: [2, "declaration"],
130
+ id-length: 0,
131
+ id-match: 2,
132
+ indent: [2, 2, { VariableDeclarator: 2 }],
133
+ key-spacing: 0,
134
+ lines-around-comment: 2,
135
+ linebreak-style: 2,
136
+ max-nested-callbacks: [2, 1],
137
+ new-cap: 2,
138
+ new-parens: 2,
139
+ newline-after-var: 0,
140
+ no-array-constructor: 2,
141
+ no-continue: 2,
142
+ no-inline-comments: 0,
143
+ no-lonely-if: 2,
144
+ no-mixed-spaces-and-tabs: 2,
145
+ no-multiple-empty-lines: 0,
146
+ no-nested-ternary: 0,
147
+ no-new-object: 2,
148
+ no-spaced-func: 2,
149
+ no-ternary: 0,
150
+ no-trailing-spaces: 2,
151
+ no-underscore-dangle: 0,
152
+ no-unneeded-ternary: 2,
153
+ object-curly-spacing: [2, "always"],
154
+ one-var: 0,
155
+ operator-assignment: 2,
156
+ operator-linebreak: 2,
157
+ padded-blocks: [2, "never"],
158
+ quote-props: [2, "consistent-as-needed"],
159
+ quotes: [2, "single", "avoid-escape"],
160
+ semi-spacing: 2,
161
+ semi: 2,
162
+ sort-vars: 0,
163
+ space-after-keywords: 2,
164
+ space-before-blocks: 2,
165
+ space-before-function-paren: [2, {"anonymous": "always", "named": "never"}],
166
+ space-in-parens: 2,
167
+ space-infix-ops: 2,
168
+ space-return-throw-case: 2,
169
+ space-unary-ops: 2,
170
+ spaced-comment: 2,
171
+ wrap-regex: 0,
172
+ },
173
+ }
package/.travis.yml CHANGED
@@ -1,10 +1,7 @@
1
1
  language: node_js
2
2
  node_js:
3
- - "0.10"
4
-
5
- branches:
6
- except:
7
- - browser
8
- - earl
3
+ - "4"
4
+ - "6"
5
+ - "node"
9
6
 
10
7
  sudo: false
package/README.md CHANGED
@@ -6,13 +6,13 @@ It offers:
6
6
  - [**Parsing**](#parsing) triples/quads from
7
7
  [Turtle](http://www.w3.org/TR/turtle/),
8
8
  [TriG](http://www.w3.org/TR/trig/),
9
- [N-Triples](http://www.w3.org/TR/ntriples/)
10
- and [N-Quads](http://www.w3.org/TR/nquads/).
9
+ [N-Triples](http://www.w3.org/TR/n-triples/)
10
+ and [N-Quads](http://www.w3.org/TR/n-quads/).
11
11
  - [**Writing**](#Writing) triples/quads to
12
12
  [Turtle](http://www.w3.org/TR/turtle/),
13
13
  [TriG](http://www.w3.org/TR/trig/),
14
- [N-Triples](http://www.w3.org/TR/ntriples/)
15
- and [N-Quads](http://www.w3.org/TR/nquads/).
14
+ [N-Triples](http://www.w3.org/TR/n-triples/)
15
+ and [N-Quads](http://www.w3.org/TR/n-quads/).
16
16
  - **Storage** of triples/quads in memory
17
17
 
18
18
  Parsing and writing is:
@@ -199,7 +199,7 @@ A dedicated `prefix` event signals every prefix with `prefix` and `iri` argument
199
199
  Write triples through `addTriple`.
200
200
 
201
201
  ``` js
202
- var writer = N3.Writer({ prefixes: { 'c': 'http://example.org/cartoons#' } });
202
+ var writer = N3.Writer({ prefixes: { c: 'http://example.org/cartoons#' } });
203
203
  writer.addTriple('http://example.org/cartoons#Tom',
204
204
  'http://www.w3.org/1999/02/22-rdf-syntax-ns#type',
205
205
  'http://example.org/cartoons#Cat');
@@ -225,7 +225,7 @@ var writer2 = N3.Writer({ format: 'application/trig' });
225
225
  `N3.Writer` can also write triples to a Node.js stream.
226
226
 
227
227
  ``` js
228
- var writer = N3.Writer(process.stdout, { prefixes: { 'c': 'http://example.org/cartoons#' } });
228
+ var writer = N3.Writer(process.stdout, { prefixes: { c: 'http://example.org/cartoons#' } });
229
229
  writer.addTriple('http://example.org/cartoons#Tom',
230
230
  'http://www.w3.org/1999/02/22-rdf-syntax-ns#type',
231
231
  'http://example.org/cartoons#Cat');
@@ -244,12 +244,47 @@ writer.end();
244
244
  ``` js
245
245
  var streamParser = new N3.StreamParser(),
246
246
  inputStream = fs.createReadStream('cartoons.ttl'),
247
- streamWriter = new N3.StreamWriter({ 'c': 'http://example.org/cartoons#' });
247
+ streamWriter = new N3.StreamWriter({ prefixes: { c: 'http://example.org/cartoons#' } });
248
248
  inputStream.pipe(streamParser);
249
249
  streamParser.pipe(streamWriter);
250
250
  streamWriter.pipe(process.stdout);
251
251
  ```
252
252
 
253
+ ### Blank nodes and lists
254
+ You might want to use the `[…]` and list `(…)` notations of Turtle and TriG.
255
+ However, a streaming writer cannot create these automatically:
256
+ the shorthand notations are only possible if blank nodes or list heads are not used later on,
257
+ which can only be determined conclusively at the end of the stream.
258
+
259
+ The `blank` and `list` functions allow you to create them manually instead:
260
+ ```js
261
+ var writer = N3.Writer({ prefixes: { c: 'http://example.org/cartoons#',
262
+ foaf: 'http://xmlns.com/foaf/0.1/' } });
263
+ writer.addTriple(writer.blank('http://xmlns.com/foaf/0.1/givenName', '"Tom"@en'),
264
+ 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type',
265
+ 'http://example.org/cartoons#Cat');
266
+ writer.addTriple('http://example.org/cartoons#Jerry',
267
+ 'http://xmlns.com/foaf/0.1/knows',
268
+ writer.blank([{
269
+ predicate: 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type',
270
+ object: 'http://example.org/cartoons#Cat'
271
+ },{
272
+ predicate: 'http://xmlns.com/foaf/0.1/givenName',
273
+ object: '"Tom"@en',
274
+ }]));
275
+ writer.addTriple('http://example.org/cartoons#Mammy',
276
+ 'http://example.org/cartoons#hasPets',
277
+ writer.list([
278
+ 'http://example.org/cartoons#Tom',
279
+ 'http://example.org/cartoons#Jerry'
280
+ ]));
281
+ writer.end(function (error, result) { console.log(result); });
282
+ ```
283
+
284
+ Be careful to use the output of `blank` and `list`
285
+ **only once** and **only as argument to `addTriple`** of the same writer,
286
+ as return values of these functions are unspecified.
287
+
253
288
  ## Storing
254
289
 
255
290
  `N3.Store` allows you to store triples in memory and find them fast.
@@ -318,7 +353,7 @@ N3Util.isLiteral('_:b1'); // false
318
353
 
319
354
  **Prefixed names** can be tested and expanded:
320
355
  ``` js
321
- var prefixes = { 'rdfs': 'http://www.w3.org/2000/01/rdf-schema#' };
356
+ var prefixes = { rdfs: 'http://www.w3.org/2000/01/rdf-schema#' };
322
357
  N3Util.isPrefixedName('rdfs:label'); // true;
323
358
  N3Util.expandPrefixedName('rdfs:label', prefixes); // http://www.w3.org/2000/01/rdf-schema#label
324
359
  ```
package/lib/N3Lexer.js CHANGED
@@ -27,7 +27,7 @@ function N3Lexer(options) {
27
27
  this._tokenize = this.tokenize;
28
28
  this.tokenize = function (input, callback) {
29
29
  this._tokenize(input, function (error, token) {
30
- if (!error && /IRI|prefixed|literal|langcode|type|\.|eof/.test(token.type))
30
+ if (!error && /^(?:IRI|prefixed|literal|langcode|type|\.|eof)$/.test(token.type))
31
31
  callback && callback(error, token);
32
32
  else
33
33
  callback && callback(error || self._syntaxError(token.type, callback = null));
@@ -100,17 +100,14 @@ N3Lexer.prototype = {
100
100
 
101
101
  case '<':
102
102
  // Try to find a full IRI without escape sequences.
103
- if (match = this._unescapedIri.exec(input)) {
104
- type = 'IRI';
105
- value = match[1];
106
- }
103
+ if (match = this._unescapedIri.exec(input))
104
+ type = 'IRI', value = match[1];
107
105
  // Try to find a full IRI with escape sequences.
108
106
  else if (match = this._iri.exec(input)) {
109
107
  unescaped = this._unescape(match[1]);
110
108
  if (unescaped === null || illegalIriChars.test(unescaped))
111
109
  return reportSyntaxError(this);
112
- type = 'IRI';
113
- value = unescaped;
110
+ type = 'IRI', value = unescaped;
114
111
  }
115
112
  break;
116
113
 
@@ -119,27 +116,21 @@ N3Lexer.prototype = {
119
116
  // we always need a non-dot character before deciding it is a prefixed name.
120
117
  // Therefore, try inserting a space if we're at the end of the input.
121
118
  if ((match = this._blank.exec(input)) ||
122
- inputFinished && (match = this._blank.exec(input + ' '))) {
123
- type = 'prefixed';
124
- prefix = '_';
125
- value = match[1];
126
- }
119
+ inputFinished && (match = this._blank.exec(input + ' ')))
120
+ type = 'prefixed', prefix = '_', value = match[1];
127
121
  break;
128
122
 
129
123
  case '"':
130
124
  case "'":
131
125
  // Try to find a non-empty double-quoted literal without escape sequences.
132
- if (match = this._unescapedString.exec(input)) {
133
- type = 'literal';
134
- value = match[0];
135
- }
126
+ if (match = this._unescapedString.exec(input))
127
+ type = 'literal', value = match[0];
136
128
  // Try to find any other literal wrapped in a pair of single or double quotes.
137
129
  else if (match = this._singleQuotedString.exec(input)) {
138
130
  unescaped = this._unescape(match[0]);
139
131
  if (unescaped === null)
140
132
  return reportSyntaxError(this);
141
- type = 'literal';
142
- value = unescaped.replace(/^'|'$/g, '"');
133
+ type = 'literal', value = unescaped.replace(/^'|'$/g, '"');
143
134
  }
144
135
  // Try to find a literal wrapped in three pairs of single or double quotes.
145
136
  else if (match = this._tripleQuotedString.exec(input)) {
@@ -149,21 +140,17 @@ N3Lexer.prototype = {
149
140
  unescaped = this._unescape(unescaped);
150
141
  if (unescaped === null)
151
142
  return reportSyntaxError(this);
152
- type = 'literal';
153
- value = unescaped.replace(/^'|'$/g, '"');
143
+ type = 'literal', value = unescaped.replace(/^'|'$/g, '"');
154
144
  }
155
145
  break;
156
146
 
157
147
  case '@':
158
148
  // Try to find a language code.
159
- if (this._prevTokenType === 'literal' && (match = this._langcode.exec(input))) {
160
- type = 'langcode';
161
- value = match[1];
162
- }
149
+ if (this._prevTokenType === 'literal' && (match = this._langcode.exec(input)))
150
+ type = 'langcode', value = match[1];
163
151
  // Try to find a keyword.
164
- else if (match = this._keyword.exec(input)) {
152
+ else if (match = this._keyword.exec(input))
165
153
  type = match[0];
166
- }
167
154
  break;
168
155
 
169
156
  case '.':
@@ -211,20 +198,16 @@ N3Lexer.prototype = {
211
198
  case 'f':
212
199
  case 't':
213
200
  // Try to match a boolean.
214
- if (match = this._boolean.exec(input)) {
215
- type = 'literal';
216
- value = '"' + match[0] + '"^^http://www.w3.org/2001/XMLSchema#boolean';
217
- }
201
+ if (match = this._boolean.exec(input))
202
+ type = 'literal', value = '"' + match[0] + '"^^http://www.w3.org/2001/XMLSchema#boolean';
218
203
  else
219
204
  inconclusive = true;
220
205
  break;
221
206
 
222
207
  case 'a':
223
208
  // Try to find an abbreviated predicate.
224
- if (match = this._shortPredicates.exec(input)) {
225
- type = 'abbreviation';
226
- value = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type';
227
- }
209
+ if (match = this._shortPredicates.exec(input))
210
+ type = 'abbreviation', value = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type';
228
211
  else
229
212
  inconclusive = true;
230
213
  break;
@@ -250,19 +233,14 @@ N3Lexer.prototype = {
250
233
  if (inconclusive) {
251
234
  // Try to find a prefix.
252
235
  if ((this._prevTokenType === '@prefix' || this._prevTokenType === 'PREFIX') &&
253
- (match = this._prefix.exec(input))) {
254
- type = 'prefix';
255
- value = match[1] || '';
256
- }
236
+ (match = this._prefix.exec(input)))
237
+ type = 'prefix', value = match[1] || '';
257
238
  // Try to find a prefixed name. Since it can contain (but not end with) a dot,
258
239
  // we always need a non-dot character before deciding it is a prefixed name.
259
240
  // Therefore, try inserting a space if we're at the end of the input.
260
241
  else if ((match = this._prefixed.exec(input)) ||
261
- inputFinished && (match = this._prefixed.exec(input + ' '))) {
262
- type = 'prefixed';
263
- prefix = match[1] || '';
264
- value = this._unescape(match[2]);
265
- }
242
+ inputFinished && (match = this._prefixed.exec(input + ' ')))
243
+ type = 'prefixed', prefix = match[1] || '', value = this._unescape(match[2]);
266
244
  }
267
245
 
268
246
  // A type token is special: it can only be emitted after an IRI or prefixed name is read.
@@ -369,9 +347,8 @@ N3Lexer.prototype = {
369
347
 
370
348
  // Parses until the end
371
349
  function end() {
372
- if (self._input !== null) {
350
+ if (self._input !== null)
373
351
  self._tokenizeToEnd(callback, true);
374
- }
375
352
  }
376
353
  },
377
354
  };