rdflib 2.2.21 → 2.2.22-b51259b5

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.
Files changed (106) hide show
  1. package/dist/rdflib.min.js +1 -1
  2. package/dist/rdflib.min.js.LICENSE.txt +9 -1
  3. package/dist/rdflib.min.js.map +1 -1
  4. package/esm/blank-node.js +61 -114
  5. package/esm/class-order.js +1 -1
  6. package/esm/collection.js +70 -128
  7. package/esm/convert.js +1 -2
  8. package/esm/default-graph.js +14 -48
  9. package/esm/empty.js +8 -39
  10. package/esm/factories/canonical-data-factory.js +33 -65
  11. package/esm/factories/extended-term-factory.js +18 -25
  12. package/esm/factories/factory-types.js +3 -2
  13. package/esm/factories/rdflib-data-factory.js +9 -19
  14. package/esm/fetcher.js +1341 -1854
  15. package/esm/formula.js +639 -846
  16. package/esm/index.js +40 -76
  17. package/esm/jsonldparser.js +24 -49
  18. package/esm/jsonparser.js +1 -8
  19. package/esm/lists.js +47 -110
  20. package/esm/literal.js +120 -189
  21. package/esm/log.js +7 -7
  22. package/esm/n3parser.js +1015 -1412
  23. package/esm/named-node.js +70 -119
  24. package/esm/namespace.js +2 -5
  25. package/esm/node-internal.js +73 -110
  26. package/esm/node.js +2 -7
  27. package/esm/parse.js +12 -19
  28. package/esm/patch-parser.js +10 -30
  29. package/esm/query-to-sparql.js +0 -18
  30. package/esm/query.js +63 -147
  31. package/esm/rdfaparser.js +794 -997
  32. package/esm/rdfxmlparser.js +347 -461
  33. package/esm/serialize.js +9 -27
  34. package/esm/serializer.js +820 -1049
  35. package/esm/sparql-to-query.js +44 -134
  36. package/esm/statement.js +54 -85
  37. package/esm/store.js +830 -1103
  38. package/esm/types.js +22 -21
  39. package/esm/update-manager.js +869 -1106
  40. package/esm/updates-via.js +104 -161
  41. package/esm/uri.js +9 -53
  42. package/esm/utils/default-graph-uri.js +3 -2
  43. package/esm/utils/termValue.js +0 -1
  44. package/esm/utils/terms.js +19 -21
  45. package/esm/utils-js.js +20 -61
  46. package/esm/utils.js +10 -21
  47. package/esm/variable.js +32 -78
  48. package/esm/xsd.js +2 -2
  49. package/lib/blank-node.js +60 -113
  50. package/lib/class-order.js +1 -2
  51. package/lib/collection.js +69 -131
  52. package/lib/convert.js +3 -9
  53. package/lib/default-graph.js +13 -52
  54. package/lib/empty.js +8 -43
  55. package/lib/factories/canonical-data-factory.js +35 -79
  56. package/lib/factories/extended-term-factory.js +18 -32
  57. package/lib/factories/factory-types.d.ts +6 -6
  58. package/lib/factories/factory-types.js +1 -4
  59. package/lib/factories/rdflib-data-factory.js +9 -23
  60. package/lib/fetcher.d.ts +6 -6
  61. package/lib/fetcher.js +1370 -1843
  62. package/lib/formula.js +640 -855
  63. package/lib/index.js +66 -152
  64. package/lib/jsonldparser.js +23 -53
  65. package/lib/jsonparser.js +1 -10
  66. package/lib/lists.js +55 -112
  67. package/lib/literal.js +120 -195
  68. package/lib/log.d.ts +0 -6
  69. package/lib/log.js +7 -8
  70. package/lib/n3parser.js +1030 -1436
  71. package/lib/named-node.js +69 -126
  72. package/lib/namespace.js +2 -7
  73. package/lib/node-internal.js +74 -107
  74. package/lib/node.js +2 -12
  75. package/lib/parse.d.ts +1 -1
  76. package/lib/parse.js +12 -32
  77. package/lib/patch-parser.js +11 -34
  78. package/lib/query-to-sparql.js +0 -23
  79. package/lib/query.js +62 -167
  80. package/lib/rdfaparser.js +796 -1009
  81. package/lib/rdfxmlparser.js +349 -466
  82. package/lib/serialize.js +11 -37
  83. package/lib/serializer.js +823 -1064
  84. package/lib/sparql-to-query.js +42 -167
  85. package/lib/statement.js +55 -91
  86. package/lib/store.d.ts +1 -1
  87. package/lib/store.js +850 -1112
  88. package/lib/tf-types.d.ts +4 -4
  89. package/lib/types.d.ts +8 -8
  90. package/lib/types.js +23 -23
  91. package/lib/update-manager.d.ts +1 -1
  92. package/lib/update-manager.js +865 -1103
  93. package/lib/updates-via.js +105 -164
  94. package/lib/uri.js +8 -61
  95. package/lib/utils/default-graph-uri.js +3 -5
  96. package/lib/utils/termValue.js +0 -2
  97. package/lib/utils/terms.js +19 -40
  98. package/lib/utils-js.js +23 -88
  99. package/lib/utils.js +10 -27
  100. package/lib/variable.js +34 -85
  101. package/lib/xsd-internal.js +0 -3
  102. package/lib/xsd.js +2 -6
  103. package/package.json +35 -35
  104. package/src/fetcher.ts +2 -2
  105. package/src/update-manager.ts +12 -7
  106. package/changes.txt +0 -59
package/lib/serializer.js CHANGED
@@ -1,39 +1,21 @@
1
1
  "use strict";
2
2
 
3
3
  var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
-
5
- var _typeof = require("@babel/runtime/helpers/typeof");
6
-
7
4
  Object.defineProperty(exports, "__esModule", {
8
5
  value: true
9
6
  });
10
7
  exports.Serializer = void 0;
11
8
  exports.default = createSerializer;
12
-
13
- var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
14
-
15
- var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
16
-
17
9
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
18
-
19
10
  var _namedNode = _interopRequireDefault(require("./named-node"));
20
-
21
11
  var _blankNode = _interopRequireDefault(require("./blank-node"));
22
-
23
12
  var Uri = _interopRequireWildcard(require("./uri"));
24
-
25
13
  var Util = _interopRequireWildcard(require("./utils-js"));
26
-
27
14
  var _canonicalDataFactory = _interopRequireDefault(require("./factories/canonical-data-factory"));
28
-
29
15
  var _xsd = require("./xsd");
30
-
31
16
  var _solidNamespace = _interopRequireDefault(require("solid-namespace"));
32
-
33
- function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
34
-
35
- function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
36
-
17
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
18
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
37
19
  /* Serialization of RDF Graphs
38
20
  **
39
21
  ** Tim Berners-Lee 2006
@@ -41,15 +23,13 @@ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj &&
41
23
  ** This is or was https://github.com/linkeddata/rdflib.js/blob/main/src/serializer.js
42
24
  ** Licence: MIT
43
25
  */
26
+
44
27
  function createSerializer(store) {
45
28
  return new Serializer(store);
46
29
  }
47
-
48
30
  ;
49
-
50
- var Serializer = /*#__PURE__*/function () {
51
- function Serializer(store) {
52
- (0, _classCallCheck2.default)(this, Serializer);
31
+ class Serializer {
32
+ constructor(store) {
53
33
  (0, _defineProperty2.default)(this, "_notQNameChars", '\t\r\n !"#$%&\'()*.,+/;<=>?@[\\]^`{|}~');
54
34
  (0, _defineProperty2.default)(this, "_notNameChars", this._notQNameChars + ':');
55
35
  (0, _defineProperty2.default)(this, "validPrefix", new RegExp(/^[a-zA-Z][a-zA-Z0-9]*$/));
@@ -58,1182 +38,961 @@ var Serializer = /*#__PURE__*/function () {
58
38
  this.flags = '';
59
39
  this.base = null;
60
40
  this.prefixes = []; // suggested prefixes
61
-
62
41
  this.namespaces = []; // complementary
63
-
64
- var nsKeys = Object.keys((0, _solidNamespace.default)());
65
-
66
- for (var i in nsKeys) {
67
- var uri = (0, _solidNamespace.default)()[nsKeys[i]]('');
68
- var prefix = nsKeys[i];
42
+ const nsKeys = Object.keys((0, _solidNamespace.default)());
43
+ for (const i in nsKeys) {
44
+ const uri = (0, _solidNamespace.default)()[nsKeys[i]]('');
45
+ const prefix = nsKeys[i];
69
46
  this.prefixes[uri] = prefix;
70
47
  this.namespaces[prefix] = uri;
71
48
  }
72
-
73
49
  this.suggestPrefix('rdf', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'); // XML code assumes this!
74
-
75
50
  this.suggestPrefix('xml', 'reserved:reservedForFutureUse'); // XML reserves xml: in the spec.
76
51
 
77
52
  this.namespacesUsed = []; // Count actually used and so needed in @prefixes
78
-
79
53
  this.keywords = ['a']; // The only one we generate at the moment
80
-
81
54
  this.prefixchars = 'abcdefghijklmnopqustuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
82
55
  this.incoming = null; // Array not calculated yet
83
-
84
56
  this.formulas = []; // remembering original formulae from hashes
85
-
86
57
  this.store = store;
87
58
  this.rdfFactory = store.rdfFactory || _canonicalDataFactory.default;
88
59
  this.xsd = (0, _xsd.createXSD)(this.rdfFactory);
89
60
  }
90
-
91
- (0, _createClass2.default)(Serializer, [{
92
- key: "setBase",
93
- value: function setBase(base) {
94
- this.base = base;
95
- return this;
96
- }
97
- }, {
98
- key: "setFlags",
99
- value: function setFlags(flags) {
100
- this.flags = flags || '';
101
- return this;
61
+ setBase(base) {
62
+ this.base = base;
63
+ return this;
64
+ }
65
+ setFlags(flags) {
66
+ this.flags = flags || '';
67
+ return this;
68
+ }
69
+ toStr(x) {
70
+ var s = x.toNT();
71
+ if (x.termType === 'Graph') {
72
+ this.formulas[s] = x; // remember as reverse does not work
102
73
  }
103
- }, {
104
- key: "toStr",
105
- value: function toStr(x) {
106
- var s = x.toNT();
107
-
108
- if (x.termType === 'Graph') {
109
- this.formulas[s] = x; // remember as reverse does not work
110
- }
111
74
 
112
- return s;
75
+ return s;
76
+ }
77
+ fromStr(s) {
78
+ if (s[0] === '{') {
79
+ var x = this.formulas[s];
80
+ if (!x) console.log('No formula object for ' + s);
81
+ return x;
113
82
  }
114
- }, {
115
- key: "fromStr",
116
- value: function fromStr(s) {
117
- if (s[0] === '{') {
118
- var x = this.formulas[s];
119
- if (!x) console.log('No formula object for ' + s);
120
- return x;
121
- }
83
+ return this.store.fromNT(s);
84
+ }
122
85
 
123
- return this.store.fromNT(s);
86
+ /**
87
+ * Defines a set of [prefix, namespace] pairs to be used by this Serializer instance.
88
+ * Overrides previous prefixes if any
89
+ * @param namespaces
90
+ * @return {Serializer}
91
+ */
92
+ setNamespaces(namespaces) {
93
+ for (var px in namespaces) {
94
+ this.setPrefix(px, namespaces[px]);
124
95
  }
125
- /**
126
- * Defines a set of [prefix, namespace] pairs to be used by this Serializer instance.
127
- * Overrides previous prefixes if any
128
- * @param namespaces
129
- * @return {Serializer}
130
- */
131
-
132
- }, {
133
- key: "setNamespaces",
134
- value: function setNamespaces(namespaces) {
135
- for (var px in namespaces) {
136
- this.setPrefix(px, namespaces[px]);
137
- }
96
+ return this;
97
+ }
138
98
 
139
- return this;
99
+ /**
100
+ * Defines a namespace prefix, overriding any existing prefix for that URI
101
+ * @param prefix
102
+ * @param uri
103
+ */
104
+ setPrefix(prefix, uri) {
105
+ if (prefix.slice(0, 7) === 'default') return; // Try to weed these out
106
+ if (prefix.slice(0, 2) === 'ns') return; // From others inferior algos
107
+ if (!prefix || !uri) return; // empty strings not suitable
108
+
109
+ // remove any existing prefix targeting this uri
110
+ // for (let existingPrefix in this.namespaces) {
111
+ // if (this.namespaces[existingPrefix] == uri)
112
+ // delete this.namespaces[existingPrefix];
113
+ // }
114
+
115
+ // remove any existing mapping for this prefix
116
+ for (let existingNs in this.prefixes) {
117
+ if (this.prefixes[existingNs] == prefix) delete this.prefixes[existingNs];
140
118
  }
141
- /**
142
- * Defines a namespace prefix, overriding any existing prefix for that URI
143
- * @param prefix
144
- * @param uri
145
- */
146
-
147
- }, {
148
- key: "setPrefix",
149
- value: function setPrefix(prefix, uri) {
150
- if (prefix.slice(0, 7) === 'default') return; // Try to weed these out
151
-
152
- if (prefix.slice(0, 2) === 'ns') return; // From others inferior algos
153
-
154
- if (!prefix || !uri) return; // empty strings not suitable
155
- // remove any existing prefix targeting this uri
156
- // for (let existingPrefix in this.namespaces) {
157
- // if (this.namespaces[existingPrefix] == uri)
158
- // delete this.namespaces[existingPrefix];
159
- // }
160
- // remove any existing mapping for this prefix
119
+ this.prefixes[uri] = prefix;
120
+ this.namespaces[prefix] = uri;
121
+ }
161
122
 
162
- for (var existingNs in this.prefixes) {
163
- if (this.prefixes[existingNs] == prefix) delete this.prefixes[existingNs];
164
- }
123
+ /* Accumulate Namespaces
124
+ **
125
+ ** These are only hints. If two overlap, only one gets used
126
+ ** There is therefore no guarantee in general.
127
+ */
128
+ suggestPrefix(prefix, uri) {
129
+ if (prefix.slice(0, 7) === 'default') return; // Try to weed these out
130
+ if (prefix.slice(0, 2) === 'ns') return; // From others inferior algos
131
+ if (!prefix || !uri) return; // empty strings not suitable
132
+ if (prefix in this.namespaces || uri in this.prefixes) return; // already used
133
+ this.prefixes[uri] = prefix;
134
+ this.namespaces[prefix] = uri;
135
+ }
165
136
 
166
- this.prefixes[uri] = prefix;
167
- this.namespaces[prefix] = uri;
137
+ // Takes a namespace -> prefix map
138
+ suggestNamespaces(namespaces) {
139
+ for (var px in namespaces) {
140
+ this.suggestPrefix(px, namespaces[px]);
168
141
  }
169
- /* Accumulate Namespaces
170
- **
171
- ** These are only hints. If two overlap, only one gets used
172
- ** There is therefore no guarantee in general.
173
- */
174
-
175
- }, {
176
- key: "suggestPrefix",
177
- value: function suggestPrefix(prefix, uri) {
178
- if (prefix.slice(0, 7) === 'default') return; // Try to weed these out
179
-
180
- if (prefix.slice(0, 2) === 'ns') return; // From others inferior algos
181
-
182
- if (!prefix || !uri) return; // empty strings not suitable
183
-
184
- if (prefix in this.namespaces || uri in this.prefixes) return; // already used
185
-
186
- this.prefixes[uri] = prefix;
187
- this.namespaces[prefix] = uri;
188
- } // Takes a namespace -> prefix map
189
-
190
- }, {
191
- key: "suggestNamespaces",
192
- value: function suggestNamespaces(namespaces) {
193
- for (var px in namespaces) {
194
- this.suggestPrefix(px, namespaces[px]);
142
+ return this;
143
+ }
144
+ checkIntegrity() {
145
+ var p, ns;
146
+ for (p in this.namespaces) {
147
+ if (this.prefixes[this.namespaces[p]] !== p) {
148
+ throw new Error('Serializer integity error 1: ' + p + ', ' + this.namespaces[p] + ', ' + this.prefixes[this.namespaces[p]] + '!');
195
149
  }
196
-
197
- return this;
198
150
  }
199
- }, {
200
- key: "checkIntegrity",
201
- value: function checkIntegrity() {
202
- var p, ns;
203
-
204
- for (p in this.namespaces) {
205
- if (this.prefixes[this.namespaces[p]] !== p) {
206
- throw new Error('Serializer integity error 1: ' + p + ', ' + this.namespaces[p] + ', ' + this.prefixes[this.namespaces[p]] + '!');
207
- }
208
- }
209
-
210
- for (ns in this.prefixes) {
211
- if (this.namespaces[this.prefixes[ns]] !== ns) {
212
- throw new Error('Serializer integity error 2: ' + ns + ', ' + this.prefixs[ns] + ', ' + this.namespaces[this.prefixes[ns]] + '!');
213
- }
214
- }
215
- } // Make up an unused prefix for a random namespace
216
-
217
- }, {
218
- key: "makeUpPrefix",
219
- value: function makeUpPrefix(uri) {
220
- var p = uri;
221
-
222
- function canUseMethod(pp) {
223
- if (!this.validPrefix.test(pp)) return false; // bad format
224
-
225
- if (pp === 'ns') return false; // boring
226
-
227
- if (pp in this.namespaces) return false; // already used
228
-
229
- this.prefixes[uri] = pp;
230
- this.namespaces[pp] = uri;
231
- return pp;
232
- }
233
-
234
- var canUse = canUseMethod.bind(this);
235
- if ('#/'.indexOf(p[p.length - 1]) >= 0) p = p.slice(0, -1);
236
- var slash = p.lastIndexOf('/');
237
- if (slash >= 0) p = p.slice(slash + 1);
238
- var i = 0;
239
-
240
- while (i < p.length) {
241
- if (this.prefixchars.indexOf(p[i])) {
242
- i++;
243
- } else {
244
- break;
245
- }
246
- }
247
-
248
- p = p.slice(0, i);
249
- if (p.length < 6 && canUse(p)) return p; // exact is best
250
-
251
- if (canUse(p.slice(0, 3))) return p.slice(0, 3);
252
- if (canUse(p.slice(0, 2))) return p.slice(0, 2);
253
- if (canUse(p.slice(0, 4))) return p.slice(0, 4);
254
- if (canUse(p.slice(0, 1))) return p.slice(0, 1);
255
- if (canUse(p.slice(0, 5))) return p.slice(0, 5);
256
-
257
- if (!this.validPrefix.test(p)) {
258
- p = 'n'; // Otherwise the loop below may never termimnate
259
- }
260
-
261
- for (var j = 0;; j++) {
262
- if (canUse(p.slice(0, 3) + j)) return p.slice(0, 3) + j;
151
+ for (ns in this.prefixes) {
152
+ if (this.namespaces[this.prefixes[ns]] !== ns) {
153
+ throw new Error('Serializer integity error 2: ' + ns + ', ' + this.prefixs[ns] + ', ' + this.namespaces[this.prefixes[ns]] + '!');
263
154
  }
264
155
  }
265
- }, {
266
- key: "rootSubjects",
267
- value: function rootSubjects(sts) {
268
- var incoming = {};
269
- var subjects = {};
270
- var allBnodes = {};
271
- /* This scan is to find out which nodes will have to be the roots of trees
272
- ** in the serialized form. This will be any symbols, and any bnodes
273
- ** which hve more or less than one incoming arc, and any bnodes which have
274
- ** one incoming arc but it is an uninterrupted loop of such nodes back to itself.
275
- ** This should be kept linear time with repect to the number of statements.
276
- ** Note it does not use any indexing of the store.
277
- */
278
-
279
- for (var i = 0; i < sts.length; i++) {
280
- var st = sts[i];
281
-
282
- var checkMentions = function checkMentions(x) {
283
- if (!incoming.hasOwnProperty(x)) incoming[x] = [];
284
- incoming[x].push(st.subject); // List of things which will cause this to be printed
285
- };
286
-
287
- var st2 = [st.subject, st.predicate, st.object];
288
- st2.map(function (y) {
289
- if (y.termType === 'BlankNode') {
290
- allBnodes[y.toNT()] = true;
291
- } else if (y.termType === 'Collection') {
292
- y.elements.forEach(function (z) {
293
- checkMentions(z); // bnodes in collections important
294
- });
295
- }
296
- });
297
- checkMentions(sts[i].object);
298
- var ss = subjects[this.toStr(st.subject)]; // Statements with this as subject
299
-
300
- if (!ss) ss = [];
301
- ss.push(st);
302
- subjects[this.toStr(st.subject)] = ss; // Make hash. @@ too slow for formula?
303
- }
304
-
305
- var roots = [];
306
-
307
- for (var xNT in subjects) {
308
- if (!subjects.hasOwnProperty(xNT)) continue;
309
- var y = this.fromStr(xNT);
310
-
311
- if (y.termType !== 'BlankNode' || !incoming[y] || incoming[y].length !== 1) {
312
- roots.push(y);
313
- continue;
314
- }
315
- }
316
-
317
- this.incoming = incoming; // Keep for serializing @@ Bug for nested formulas
318
- // Now do the scan using existing roots
319
-
320
- var rootsHash = {};
321
-
322
- for (var k = 0; k < roots.length; k++) {
323
- rootsHash[roots[k].toNT()] = true;
324
- }
325
-
326
- return {
327
- 'roots': roots,
328
- 'subjects': subjects,
329
- 'rootsHash': rootsHash,
330
- 'incoming': incoming
331
- };
332
- } // //////////////////////////////////////////////////////
156
+ }
333
157
 
334
- }, {
335
- key: "toN3",
336
- value: function toN3(f) {
337
- return this.statementsToN3(f.statements);
158
+ // Make up an unused prefix for a random namespace
159
+ makeUpPrefix(uri) {
160
+ var p = uri;
161
+ function canUseMethod(pp) {
162
+ if (!this.validPrefix.test(pp)) return false; // bad format
163
+ if (pp === 'ns') return false; // boring
164
+ if (pp in this.namespaces) return false; // already used
165
+ this.prefixes[uri] = pp;
166
+ this.namespaces[pp] = uri;
167
+ return pp;
338
168
  }
339
- }, {
340
- key: "explicitURI",
341
- value: function explicitURI(uri) {
342
- if (this.flags.indexOf('r') < 0 && this.base) {
343
- uri = Uri.refTo(this.base, uri);
344
- } else if (this.flags.indexOf('u') >= 0) {
345
- // Unicode encoding NTriples style
346
- uri = backslashUify(uri);
169
+ var canUse = canUseMethod.bind(this);
170
+ if ('#/'.indexOf(p[p.length - 1]) >= 0) p = p.slice(0, -1);
171
+ var slash = p.lastIndexOf('/');
172
+ if (slash >= 0) p = p.slice(slash + 1);
173
+ var i = 0;
174
+ while (i < p.length) {
175
+ if (this.prefixchars.indexOf(p[i])) {
176
+ i++;
347
177
  } else {
348
- uri = hexify(uri);
178
+ break;
349
179
  }
350
-
351
- return '<' + uri + '>';
352
180
  }
353
- }, {
354
- key: "statementsToNTriples",
355
- value: function statementsToNTriples(sts) {
356
- var sorted = sts.slice();
357
- sorted.sort();
358
- var str = '';
359
- var rdfns = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#';
360
- var self = this;
361
- var kb = this.store;
362
- var factory = this.rdfFactory;
363
-
364
- var termToNT = function termToNT(x) {
365
- if (x.termType !== 'Collection') {
366
- return self.atomicTermToN3(x);
367
- }
368
-
369
- var list = x.elements;
370
- var rest = kb.sym(rdfns + 'nill');
371
-
372
- for (var i = list.length - 1; i >= 0; i--) {
373
- var bnode = factory.blankNode();
374
- str += termToNT(bnode) + ' ' + termToNT(kb.sym(rdfns + 'first')) + ' ' + termToNT(list[i]) + '.\n';
375
- str += termToNT(bnode) + ' ' + termToNT(kb.sym(rdfns + 'rest')) + ' ' + termToNT(rest) + '.\n';
376
- rest = bnode;
377
- }
181
+ p = p.slice(0, i);
182
+ if (p.length < 6 && canUse(p)) return p; // exact is best
183
+ if (canUse(p.slice(0, 3))) return p.slice(0, 3);
184
+ if (canUse(p.slice(0, 2))) return p.slice(0, 2);
185
+ if (canUse(p.slice(0, 4))) return p.slice(0, 4);
186
+ if (canUse(p.slice(0, 1))) return p.slice(0, 1);
187
+ if (canUse(p.slice(0, 5))) return p.slice(0, 5);
188
+ if (!this.validPrefix.test(p)) {
189
+ p = 'n'; // Otherwise the loop below may never termimnate
190
+ }
378
191
 
379
- return self.atomicTermToN3(rest);
192
+ for (var j = 0;; j++) if (canUse(p.slice(0, 3) + j)) return p.slice(0, 3) + j;
193
+ }
194
+ rootSubjects(sts) {
195
+ var incoming = {};
196
+ var subjects = {};
197
+ var allBnodes = {};
198
+
199
+ /* This scan is to find out which nodes will have to be the roots of trees
200
+ ** in the serialized form. This will be any symbols, and any bnodes
201
+ ** which hve more or less than one incoming arc, and any bnodes which have
202
+ ** one incoming arc but it is an uninterrupted loop of such nodes back to itself.
203
+ ** This should be kept linear time with repect to the number of statements.
204
+ ** Note it does not use any indexing of the store.
205
+ */
206
+ for (var i = 0; i < sts.length; i++) {
207
+ var st = sts[i];
208
+ var checkMentions = function (x) {
209
+ if (!incoming.hasOwnProperty(x)) incoming[x] = [];
210
+ incoming[x].push(st.subject); // List of things which will cause this to be printed
380
211
  };
381
212
 
382
- for (var i = 0; i < sorted.length; i++) {
383
- var st = sorted[i];
384
- var s = '';
385
- s += termToNT(st.subject) + ' ';
386
- s += termToNT(st.predicate) + ' ';
387
- s += termToNT(st.object) + ' ';
388
-
389
- if (this.flags.indexOf('q') >= 0) {
390
- // Do quads not nrtiples
391
- s += termToNT(st.why) + ' ';
213
+ var st2 = [st.subject, st.predicate, st.object];
214
+ st2.map(function (y) {
215
+ if (y.termType === 'BlankNode') {
216
+ allBnodes[y.toNT()] = true;
217
+ } else if (y.termType === 'Collection') {
218
+ y.elements.forEach(function (z) {
219
+ checkMentions(z); // bnodes in collections important
220
+ });
392
221
  }
222
+ });
393
223
 
394
- s += '.\n';
395
- str += s;
396
- }
397
-
398
- return str;
224
+ checkMentions(sts[i].object);
225
+ var ss = subjects[this.toStr(st.subject)]; // Statements with this as subject
226
+ if (!ss) ss = [];
227
+ ss.push(st);
228
+ subjects[this.toStr(st.subject)] = ss; // Make hash. @@ too slow for formula?
399
229
  }
400
- }, {
401
- key: "statementsToN3",
402
- value: function statementsToN3(sts) {
403
- var indent = 4;
404
- var width = 80;
405
- var kb = this.store; // A URI Map alows us to put the type statemnts at the top.
406
230
 
407
- var uriMap = {
408
- 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type': 'aaa:00'
409
- };
410
-
411
- var SPO = function SPO(x, y) {
412
- // Do limited canonicalization of bnodes
413
- return Util.heavyCompareSPO(x, y, kb, uriMap);
414
- };
415
-
416
- sts.sort(SPO);
417
-
418
- if (this.base && !this.defaultNamespace) {
419
- this.defaultNamespace = this.base + '#';
420
- }
421
-
422
- var predMap = {};
423
-
424
- if (this.flags.indexOf('s') < 0) {
425
- predMap['http://www.w3.org/2002/07/owl#sameAs'] = '=';
231
+ var roots = [];
232
+ for (var xNT in subjects) {
233
+ if (!subjects.hasOwnProperty(xNT)) continue;
234
+ var y = this.fromStr(xNT);
235
+ if (y.termType !== 'BlankNode' || !incoming[y] || incoming[y].length !== 1) {
236
+ roots.push(y);
237
+ continue;
426
238
  }
239
+ }
240
+ this.incoming = incoming; // Keep for serializing @@ Bug for nested formulas
427
241
 
428
- if (this.flags.indexOf('t') < 0) {
429
- predMap['http://www.w3.org/1999/02/22-rdf-syntax-ns#type'] = 'a';
430
- }
431
-
432
- if (this.flags.indexOf('i') < 0) {
433
- predMap['http://www.w3.org/2000/10/swap/log#implies'] = '=>';
434
- } // //////////////////////// Arrange the bits of text
435
-
436
-
437
- var spaces = function spaces(n) {
438
- var s = '';
439
-
440
- for (var i = 0; i < n; i++) {
441
- s += ' ';
442
- }
443
-
444
- return s;
445
- };
446
-
447
- var treeToLine = function treeToLine(tree) {
448
- var str = '';
242
+ // Now do the scan using existing roots
243
+ var rootsHash = {};
244
+ for (var k = 0; k < roots.length; k++) {
245
+ rootsHash[roots[k].toNT()] = true;
246
+ }
247
+ return {
248
+ 'roots': roots,
249
+ 'subjects': subjects,
250
+ 'rootsHash': rootsHash,
251
+ 'incoming': incoming
252
+ };
253
+ }
449
254
 
450
- for (var i = 0; i < tree.length; i++) {
451
- var branch = tree[i];
452
- var s2 = typeof branch === 'string' ? branch : treeToLine(branch); // Note the space before the dot in case statement ends with 123 or colon. which is in fact allowed but be conservative.
255
+ // //////////////////////////////////////////////////////
453
256
 
454
- if (i !== 0) {
455
- var ch = str.slice(-1) || ' ';
257
+ toN3(f) {
258
+ return this.statementsToN3(f.statements);
259
+ }
260
+ explicitURI(uri) {
261
+ if (this.flags.indexOf('r') < 0 && this.base) {
262
+ uri = Uri.refTo(this.base, uri);
263
+ } else if (this.flags.indexOf('u') >= 0) {
264
+ // Unicode encoding NTriples style
265
+ uri = backslashUify(uri);
266
+ } else {
267
+ uri = hexify(uri);
268
+ }
269
+ return '<' + uri + '>';
270
+ }
271
+ statementsToNTriples(sts) {
272
+ var sorted = sts.slice();
273
+ sorted.sort();
274
+ var str = '';
275
+ var rdfns = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#';
276
+ var self = this;
277
+ var kb = this.store;
278
+ var factory = this.rdfFactory;
279
+ var termToNT = function (x) {
280
+ if (x.termType !== 'Collection') {
281
+ return self.atomicTermToN3(x);
282
+ }
283
+ var list = x.elements;
284
+ var rest = kb.sym(rdfns + 'nill');
285
+ for (var i = list.length - 1; i >= 0; i--) {
286
+ var bnode = factory.blankNode();
287
+ str += termToNT(bnode) + ' ' + termToNT(kb.sym(rdfns + 'first')) + ' ' + termToNT(list[i]) + '.\n';
288
+ str += termToNT(bnode) + ' ' + termToNT(kb.sym(rdfns + 'rest')) + ' ' + termToNT(rest) + '.\n';
289
+ rest = bnode;
290
+ }
291
+ return self.atomicTermToN3(rest);
292
+ };
293
+ for (var i = 0; i < sorted.length; i++) {
294
+ var st = sorted[i];
295
+ var s = '';
296
+ s += termToNT(st.subject) + ' ';
297
+ s += termToNT(st.predicate) + ' ';
298
+ s += termToNT(st.object) + ' ';
299
+ if (this.flags.indexOf('q') >= 0) {
300
+ // Do quads not nrtiples
301
+ s += termToNT(st.why) + ' ';
302
+ }
303
+ s += '.\n';
304
+ str += s;
305
+ }
306
+ return str;
307
+ }
308
+ statementsToN3(sts) {
309
+ var indent = 4;
310
+ var width = 80;
311
+ var kb = this.store;
312
+ // A URI Map alows us to put the type statemnts at the top.
313
+ var uriMap = {
314
+ 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type': 'aaa:00'
315
+ };
316
+ var SPO = function (x, y) {
317
+ // Do limited canonicalization of bnodes
318
+ return Util.heavyCompareSPO(x, y, kb, uriMap);
319
+ };
320
+ sts.sort(SPO);
321
+ if (this.base && !this.defaultNamespace) {
322
+ this.defaultNamespace = this.base + '#';
323
+ }
324
+ var predMap = {};
325
+ if (this.flags.indexOf('s') < 0) {
326
+ predMap['http://www.w3.org/2002/07/owl#sameAs'] = '=';
327
+ }
328
+ if (this.flags.indexOf('t') < 0) {
329
+ predMap['http://www.w3.org/1999/02/22-rdf-syntax-ns#type'] = 'a';
330
+ }
331
+ if (this.flags.indexOf('i') < 0) {
332
+ predMap['http://www.w3.org/2000/10/swap/log#implies'] = '=>';
333
+ }
334
+ // //////////////////////// Arrange the bits of text
456
335
 
457
- if (s2 === ',' || s2 === ';') {// no gap
458
- } else if (s2 === '.' && !'0123456789.:'.includes(ch)) {// no gap except after number and colon
459
- // no gap
460
- } else {
461
- str += ' '; // separate from previous token
462
- }
336
+ var spaces = function (n) {
337
+ var s = '';
338
+ for (var i = 0; i < n; i++) s += ' ';
339
+ return s;
340
+ };
341
+ var treeToLine = function (tree) {
342
+ var str = '';
343
+ for (var i = 0; i < tree.length; i++) {
344
+ var branch = tree[i];
345
+ var s2 = typeof branch === 'string' ? branch : treeToLine(branch);
346
+ // Note the space before the dot in case statement ends with 123 or colon. which is in fact allowed but be conservative.
347
+ if (i !== 0) {
348
+ var ch = str.slice(-1) || ' ';
349
+ if (s2 === ',' || s2 === ';') {
350
+ // no gap
351
+ } else if (s2 === '.' && !'0123456789.:'.includes(ch)) {// no gap except after number and colon
352
+ // no gap
353
+ } else {
354
+ str += ' '; // separate from previous token
463
355
  }
464
-
465
- str += s2;
466
356
  }
467
357
 
468
- return str;
469
- }; // Convert a nested tree of lists and strings to a string
470
-
471
-
472
- var treeToString = function treeToString(tree, level) {
473
- var str = '';
474
- var lastLength = 100000;
475
- if (level === undefined) level = -1;
476
-
477
- for (var i = 0; i < tree.length; i++) {
478
- var branch = tree[i];
479
-
480
- if (typeof branch !== 'string') {
481
- var substr = treeToString(branch, level + 1);
482
-
483
- if (substr.length < 10 * (width - indent * level) && substr.indexOf('"""') < 0) {
484
- // Don't mess up multiline strings
485
- var line = treeToLine(branch);
486
-
487
- if (line.length < width - indent * level) {
488
- branch = line; // Note! treat as string below
358
+ str += s2;
359
+ }
360
+ return str;
361
+ };
489
362
 
490
- substr = '';
491
- }
363
+ // Convert a nested tree of lists and strings to a string
364
+ var treeToString = function (tree, level) {
365
+ var str = '';
366
+ var lastLength = 100000;
367
+ if (level === undefined) level = -1;
368
+ for (var i = 0; i < tree.length; i++) {
369
+ var branch = tree[i];
370
+ if (typeof branch !== 'string') {
371
+ var substr = treeToString(branch, level + 1);
372
+ if (substr.length < 10 * (width - indent * level) && substr.indexOf('"""') < 0) {
373
+ // Don't mess up multiline strings
374
+ var line = treeToLine(branch);
375
+ if (line.length < width - indent * level) {
376
+ branch = line; // Note! treat as string below
377
+ substr = '';
492
378
  }
493
-
494
- if (substr) lastLength = 10000;
495
- str += substr;
496
379
  }
497
-
498
- if (typeof branch === 'string') {
499
- if (branch.length === 1 && str.slice(-1) === '\n') {
500
- if (',.;'.indexOf(branch) >= 0) {
501
- str = str.slice(0, -1); // be conservative and ensure a whitespace between some chars and a final dot, as in treeToLine above
502
-
503
- if (branch == '.' && '0123456789.:'.includes(str.charAt(str.length - 1))) {
504
- str += ' ';
505
- lastLength += 1;
506
- }
507
-
508
- str += branch + '\n'; // slip punct'n on end
509
-
380
+ if (substr) lastLength = 10000;
381
+ str += substr;
382
+ }
383
+ if (typeof branch === 'string') {
384
+ if (branch.length === 1 && str.slice(-1) === '\n') {
385
+ if (',.;'.indexOf(branch) >= 0) {
386
+ str = str.slice(0, -1);
387
+ // be conservative and ensure a whitespace between some chars and a final dot, as in treeToLine above
388
+ if (branch == '.' && '0123456789.:'.includes(str.charAt(str.length - 1))) {
389
+ str += ' ';
510
390
  lastLength += 1;
511
- continue;
512
- }
513
- }
514
-
515
- if (lastLength < indent * level + 4 || // if new line not necessary
516
- lastLength + branch.length + 1 < width && ';.'.indexOf(str[str.length - 2]) < 0) {
517
- // or the string fits on last line
518
- str = str.slice(0, -1) + ' ' + branch + '\n'; // then continue on this line
519
-
520
- lastLength += branch.length + 1;
521
- } else {
522
- var _line = spaces(indent * level) + branch;
523
-
524
- str += _line + '\n';
525
- lastLength = _line.length;
526
-
527
- if (level < 0) {
528
- str += '\n'; // extra blank line
529
-
530
- lastLength = 100000; // don't touch
531
391
  }
392
+ str += branch + '\n'; // slip punct'n on end
393
+ lastLength += 1;
394
+ continue;
532
395
  }
533
396
  }
534
- }
535
-
536
- return str;
537
- }; // //////////////////////////////////////////// Structure for N3
538
- // Convert a set of statements into a nested tree of lists and strings
539
-
540
-
541
- function statementListToTreeMethod(statements) {
542
- var stats = this.rootSubjects(statements);
543
- var roots = stats.roots;
544
- var results = [];
545
-
546
- for (var i = 0; i < roots.length; i++) {
547
- var root = roots[i];
548
- results.push(subjectTree(root, stats));
549
- }
550
-
551
- return results;
552
- }
553
-
554
- var statementListToTree = statementListToTreeMethod.bind(this); // The tree for a subject
555
-
556
- function subjectTree(subject, stats) {
557
- if (subject.termType === 'BlankNode' && !stats.incoming[subject]) {
558
- return objectTree(subject, stats, true).concat(['.']); // Anonymous bnode subject
559
- }
560
-
561
- return [termToN3(subject, stats)].concat([propertyTree(subject, stats)]).concat(['.']);
562
- } // The property tree for a single subject or anonymous node
563
-
564
-
565
- function propertyTreeMethod(subject, stats) {
566
- var results = [];
567
- var lastPred = null;
568
- var sts = stats.subjects[this.toStr(subject)] || []; // relevant statements
569
-
570
- if (typeof sts === 'undefined') {
571
- throw new Error('Cant find statements for ' + subject);
572
- }
573
-
574
- var objects = [];
575
-
576
- for (var i = 0; i < sts.length; i++) {
577
- var st = sts[i];
578
-
579
- if (st.predicate.uri === lastPred) {
580
- objects.push(',');
397
+ if (lastLength < indent * level + 4 ||
398
+ // if new line not necessary
399
+ lastLength + branch.length + 1 < width && ';.'.indexOf(str[str.length - 2]) < 0) {
400
+ // or the string fits on last line
401
+ str = str.slice(0, -1) + ' ' + branch + '\n'; // then continue on this line
402
+ lastLength += branch.length + 1;
581
403
  } else {
582
- if (lastPred) {
583
- results = results.concat([objects]).concat([';']);
584
- objects = [];
404
+ let line = spaces(indent * level) + branch;
405
+ str += line + '\n';
406
+ lastLength = line.length;
407
+ if (level < 0) {
408
+ str += '\n'; // extra blank line
409
+ lastLength = 100000; // don't touch
585
410
  }
586
-
587
- results.push(predMap[st.predicate.uri] ? predMap[st.predicate.uri] : termToN3(st.predicate, stats));
588
411
  }
589
-
590
- lastPred = st.predicate.uri;
591
- objects.push(objectTree(st.object, stats));
592
412
  }
593
-
594
- results = results.concat([objects]);
595
- return results;
596
413
  }
597
414
 
598
- var propertyTree = propertyTreeMethod.bind(this);
599
-
600
- function objectTreeMethod(obj, stats, force) {
601
- if (obj.termType === 'BlankNode' && (force || stats.rootsHash[obj.toNT()] === undefined)) {
602
- // if not a root
603
- if (stats.subjects[this.toStr(obj)]) {
604
- return ['[', propertyTree(obj, stats), ']'];
605
- } else {
606
- return '[]';
607
- }
608
- }
415
+ return str;
416
+ };
417
+
418
+ // //////////////////////////////////////////// Structure for N3
419
+ // Convert a set of statements into a nested tree of lists and strings
420
+ function statementListToTreeMethod(statements) {
421
+ var stats = this.rootSubjects(statements);
422
+ var roots = stats.roots;
423
+ var results = [];
424
+ for (var i = 0; i < roots.length; i++) {
425
+ var root = roots[i];
426
+ results.push(subjectTree(root, stats));
427
+ }
428
+ return results;
429
+ }
430
+ var statementListToTree = statementListToTreeMethod.bind(this);
609
431
 
610
- return termToN3(obj, stats);
432
+ // The tree for a subject
433
+ function subjectTree(subject, stats) {
434
+ if (subject.termType === 'BlankNode' && !stats.incoming[subject]) {
435
+ return objectTree(subject, stats, true).concat(['.']); // Anonymous bnode subject
611
436
  }
612
437
 
613
- var objectTree = objectTreeMethod.bind(this);
614
-
615
- function termToN3Method(expr, stats) {
616
- //
617
- var i, res;
618
-
619
- switch (expr.termType) {
620
- case 'Graph':
621
- res = ['{'];
622
- res = res.concat(statementListToTree(expr.statements));
623
- return res.concat(['}']);
624
-
625
- case 'Collection':
626
- res = ['('];
627
-
628
- for (i = 0; i < expr.elements.length; i++) {
629
- res.push([objectTree(expr.elements[i], stats)]);
630
- }
631
-
632
- res.push(')');
633
- return res;
634
-
635
- default:
636
- return this.atomicTermToN3(expr);
438
+ return [termToN3(subject, stats)].concat([propertyTree(subject, stats)]).concat(['.']);
439
+ }
440
+ // The property tree for a single subject or anonymous node
441
+ function propertyTreeMethod(subject, stats) {
442
+ var results = [];
443
+ var lastPred = null;
444
+ var sts = stats.subjects[this.toStr(subject)] || []; // relevant statements
445
+ if (typeof sts === 'undefined') {
446
+ throw new Error('Cant find statements for ' + subject);
447
+ }
448
+ var objects = [];
449
+ for (var i = 0; i < sts.length; i++) {
450
+ var st = sts[i];
451
+ if (st.predicate.uri === lastPred) {
452
+ objects.push(',');
453
+ } else {
454
+ if (lastPred) {
455
+ results = results.concat([objects]).concat([';']);
456
+ objects = [];
457
+ }
458
+ results.push(predMap[st.predicate.uri] ? predMap[st.predicate.uri] : termToN3(st.predicate, stats));
637
459
  }
460
+ lastPred = st.predicate.uri;
461
+ objects.push(objectTree(st.object, stats));
638
462
  }
639
-
640
- Serializer.prototype.termToN3 = termToN3;
641
- var termToN3 = termToN3Method.bind(this);
642
-
643
- function prefixDirectivesMethod() {
644
- var str = '';
645
-
646
- if (this.defaultNamespace) {
647
- str += '@prefix : ' + this.explicitURI(this.defaultNamespace) + '.\n';
648
- }
649
-
650
- for (var ns in this.prefixes) {
651
- if (!this.prefixes.hasOwnProperty(ns)) continue;
652
- if (!this.namespacesUsed[ns]) continue;
653
- str += '@prefix ' + this.prefixes[ns] + ': ' + this.explicitURI(ns) + '.\n';
463
+ results = results.concat([objects]);
464
+ return results;
465
+ }
466
+ var propertyTree = propertyTreeMethod.bind(this);
467
+ function objectTreeMethod(obj, stats, force) {
468
+ if (obj.termType === 'BlankNode' && (force || stats.rootsHash[obj.toNT()] === undefined)) {
469
+ // if not a root
470
+ if (stats.subjects[this.toStr(obj)]) {
471
+ return ['[', propertyTree(obj, stats), ']'];
472
+ } else {
473
+ return '[]';
654
474
  }
655
-
656
- return str + '\n';
657
475
  }
658
-
659
- var prefixDirectives = prefixDirectivesMethod.bind(this); // Body of statementsToN3:
660
-
661
- var tree = statementListToTree(sts);
662
- return prefixDirectives() + treeToString(tree);
663
- } // //////////////////////////////////////////// Atomic Terms
664
- // Deal with term level things and nesting with no bnode structure
665
-
666
- }, {
667
- key: "atomicTermToN3",
668
- value: function atomicTermToN3(expr, stats) {
476
+ return termToN3(obj, stats);
477
+ }
478
+ var objectTree = objectTreeMethod.bind(this);
479
+ function termToN3Method(expr, stats) {
480
+ //
481
+ var i, res;
669
482
  switch (expr.termType) {
670
- case 'BlankNode':
671
- case 'Variable':
672
- return expr.toNT();
673
-
674
- case 'Literal':
675
- var val = expr.value;
676
-
677
- if (typeof val !== 'string') {
678
- throw new TypeError('Value of RDF literal node must be a string');
679
- } // var val = expr.value.toString() // should be a string already
680
-
681
-
682
- if (expr.datatype && this.flags.indexOf('x') < 0) {
683
- // Supress native numbers
684
- switch (expr.datatype.uri) {
685
- case 'http://www.w3.org/2001/XMLSchema#integer':
686
- return val;
687
-
688
- case 'http://www.w3.org/2001/XMLSchema#decimal':
689
- // In Turtle, must have dot
690
- if (val.indexOf('.') < 0) val += '.0';
691
- return val;
692
-
693
- case 'http://www.w3.org/2001/XMLSchema#double':
694
- {
695
- // Must force use of 'e'
696
- var eNotation = val.toLowerCase().indexOf('e') > 0;
697
- if (val.indexOf('.') < 0 && !eNotation) val += '.0';
698
- if (!eNotation) val += 'e0';
699
- return val;
700
- }
701
-
702
- case 'http://www.w3.org/2001/XMLSchema#boolean':
703
- return expr.value === '1' ? 'true' : 'false';
704
- }
483
+ case 'Graph':
484
+ res = ['{'];
485
+ res = res.concat(statementListToTree(expr.statements));
486
+ return res.concat(['}']);
487
+ case 'Collection':
488
+ res = ['('];
489
+ for (i = 0; i < expr.elements.length; i++) {
490
+ res.push([objectTree(expr.elements[i], stats)]);
705
491
  }
706
-
707
- var str = this.stringToN3(expr.value);
708
-
709
- if (expr.language) {
710
- str += '@' + expr.language;
711
- } else if (!expr.datatype.equals(this.xsd.string)) {
712
- str += '^^' + this.atomicTermToN3(expr.datatype, stats);
713
- }
714
-
715
- return str;
716
-
717
- case 'NamedNode':
718
- return this.symbolToN3(expr);
719
-
720
- case 'DefaultGraph':
721
- return '';
722
-
492
+ res.push(')');
493
+ return res;
723
494
  default:
724
- throw new Error('Internal: atomicTermToN3 cannot handle ' + expr + ' of termType: ' + expr.termType);
495
+ return this.atomicTermToN3(expr);
725
496
  }
726
- } // stringToN3: String escaping for N3
727
-
728
- }, {
729
- key: "stringToN3",
730
- value: function stringToN3(str, flags) {
731
- if (!flags) flags = 'e';
732
- var res = '';
733
- var i, j, k;
734
- var delim;
735
- var forbidden;
736
-
737
- if (str.length > 20 && // Long enough to make sense
738
- str.slice(-1) !== '"' && // corner case'
739
- flags.indexOf('n') < 0 && ( // Force single line
740
- str.indexOf('\n') > 0 || str.indexOf('"') > 0)) {
741
- delim = '"""';
742
- forbidden = this.forbidden3;
743
- } else {
744
- delim = '"';
745
- forbidden = this.forbidden1;
497
+ }
498
+ Serializer.prototype.termToN3 = termToN3;
499
+ var termToN3 = termToN3Method.bind(this);
500
+ function prefixDirectivesMethod() {
501
+ var str = '';
502
+ if (this.defaultNamespace) {
503
+ str += '@prefix : ' + this.explicitURI(this.defaultNamespace) + '.\n';
746
504
  }
505
+ for (var ns in this.prefixes) {
506
+ if (!this.prefixes.hasOwnProperty(ns)) continue;
507
+ if (!this.namespacesUsed[ns]) continue;
508
+ str += '@prefix ' + this.prefixes[ns] + ': ' + this.explicitURI(ns) + '.\n';
509
+ }
510
+ return str + '\n';
511
+ }
512
+ var prefixDirectives = prefixDirectivesMethod.bind(this);
513
+ // Body of statementsToN3:
514
+ var tree = statementListToTree(sts);
515
+ return prefixDirectives() + treeToString(tree);
516
+ }
517
+ // //////////////////////////////////////////// Atomic Terms
518
+
519
+ // Deal with term level things and nesting with no bnode structure
520
+ atomicTermToN3(expr, stats) {
521
+ switch (expr.termType) {
522
+ case 'BlankNode':
523
+ case 'Variable':
524
+ return expr.toNT();
525
+ case 'Literal':
526
+ var val = expr.value;
527
+ if (typeof val !== 'string') {
528
+ throw new TypeError('Value of RDF literal node must be a string');
529
+ }
530
+ // var val = expr.value.toString() // should be a string already
531
+ if (expr.datatype && this.flags.indexOf('x') < 0) {
532
+ // Supress native numbers
533
+ switch (expr.datatype.uri) {
534
+ case 'http://www.w3.org/2001/XMLSchema#integer':
535
+ return val;
536
+ case 'http://www.w3.org/2001/XMLSchema#decimal':
537
+ // In Turtle, must have dot
538
+ if (val.indexOf('.') < 0) val += '.0';
539
+ return val;
540
+ case 'http://www.w3.org/2001/XMLSchema#double':
541
+ {
542
+ // Must force use of 'e'
543
+ const eNotation = val.toLowerCase().indexOf('e') > 0;
544
+ if (val.indexOf('.') < 0 && !eNotation) val += '.0';
545
+ if (!eNotation) val += 'e0';
546
+ return val;
547
+ }
548
+ case 'http://www.w3.org/2001/XMLSchema#boolean':
549
+ return expr.value === '1' ? 'true' : 'false';
550
+ }
551
+ }
552
+ var str = this.stringToN3(expr.value);
553
+ if (expr.language) {
554
+ str += '@' + expr.language;
555
+ } else if (!expr.datatype.equals(this.xsd.string)) {
556
+ str += '^^' + this.atomicTermToN3(expr.datatype, stats);
557
+ }
558
+ return str;
559
+ case 'NamedNode':
560
+ return this.symbolToN3(expr);
561
+ case 'DefaultGraph':
562
+ return '';
563
+ default:
564
+ throw new Error('Internal: atomicTermToN3 cannot handle ' + expr + ' of termType: ' + expr.termType);
565
+ }
566
+ }
747
567
 
748
- for (i = 0; i < str.length;) {
749
- forbidden.lastIndex = 0;
750
- var m = forbidden.exec(str.slice(i));
751
- if (m == null) break;
752
- j = i + forbidden.lastIndex - 1;
753
- res += str.slice(i, j);
754
- var ch = str[j];
755
-
756
- if (ch === '"' && delim === '"""' && str.slice(j, j + 3) !== '"""') {
757
- res += ch;
568
+ // stringToN3: String escaping for N3
569
+
570
+ stringToN3(str, flags) {
571
+ if (!flags) flags = 'e';
572
+ var res = '';
573
+ var i, j, k;
574
+ var delim;
575
+ var forbidden;
576
+ if (str.length > 20 &&
577
+ // Long enough to make sense
578
+ str.slice(-1) !== '"' &&
579
+ // corner case'
580
+ flags.indexOf('n') < 0 && (
581
+ // Force single line
582
+ str.indexOf('\n') > 0 || str.indexOf('"') > 0)) {
583
+ delim = '"""';
584
+ forbidden = this.forbidden3;
585
+ } else {
586
+ delim = '"';
587
+ forbidden = this.forbidden1;
588
+ }
589
+ for (i = 0; i < str.length;) {
590
+ forbidden.lastIndex = 0;
591
+ var m = forbidden.exec(str.slice(i));
592
+ if (m == null) break;
593
+ j = i + forbidden.lastIndex - 1;
594
+ res += str.slice(i, j);
595
+ var ch = str[j];
596
+ if (ch === '"' && delim === '"""' && str.slice(j, j + 3) !== '"""') {
597
+ res += ch;
598
+ } else {
599
+ k = '\b\f\r\t\v\n\\"'.indexOf(ch); // No escaping of bell (7)?
600
+ if (k >= 0) {
601
+ res += '\\' + 'bfrtvn\\"'[k];
758
602
  } else {
759
- k = '\b\f\r\t\v\n\\"'.indexOf(ch); // No escaping of bell (7)?
760
-
761
- if (k >= 0) {
762
- res += '\\' + 'bfrtvn\\"'[k];
603
+ if (flags.indexOf('e') >= 0) {
604
+ // Unicode escaping in strings not unix style
605
+ res += '\\u' + ('000' + ch.charCodeAt(0).toString(16).toLowerCase()).slice(-4);
763
606
  } else {
764
- if (flags.indexOf('e') >= 0) {
765
- // Unicode escaping in strings not unix style
766
- res += "\\u" + ('000' + ch.charCodeAt(0).toString(16).toLowerCase()).slice(-4);
767
- } else {
768
- // no 'e' flag
769
- res += ch;
770
- }
607
+ // no 'e' flag
608
+ res += ch;
771
609
  }
772
610
  }
773
-
774
- i = j + 1;
775
611
  }
776
-
777
- return delim + res + str.slice(i) + delim;
778
- } // A single symbol, either in <> or namespace notation
779
-
780
- }, {
781
- key: "symbolToN3",
782
- value: function symbolToN3(x) {
783
- // c.f. symbolString() in notation3.py
784
- var uri = x.uri;
785
- var j = uri.indexOf('#');
786
-
787
- if (j < 0 && this.flags.indexOf('/') < 0) {
788
- j = uri.lastIndexOf('/');
789
- }
790
-
791
- if (j >= 0 && this.flags.indexOf('p') < 0 && ( // Can split at namespace but only if http[s]: URI or file: or ws[s] (why not others?)
792
- uri.indexOf('http') === 0 || uri.indexOf('ws') === 0 || uri.indexOf('file') === 0)) {
793
- var canSplit = true;
794
-
795
- for (var k = j + 1; k < uri.length; k++) {
796
- if (this._notNameChars.indexOf(uri[k]) >= 0) {
797
- canSplit = false;
798
- break;
799
- }
800
- }
801
- /*
802
- if (uri.slice(0, j + 1) === this.base + '#') { // base-relative
803
- if (canSplit) {
804
- return ':' + uri.slice(j + 1) // assume deafult ns is local
805
- } else {
806
- return '<#' + uri.slice(j + 1) + '>'
807
- }
808
- }
809
- */
810
-
811
-
812
- if (canSplit) {
813
- var localid = uri.slice(j + 1);
814
- var namesp = uri.slice(0, j + 1);
815
-
816
- if (this.defaultNamespace && this.defaultNamespace === namesp && this.flags.indexOf('d') < 0) {
817
- // d -> suppress default
818
- if (this.flags.indexOf('k') >= 0 && this.keyords.indexOf(localid) < 0) {
819
- return localid;
820
- }
821
-
822
- return ':' + localid;
823
- } // this.checkIntegrity() // @@@ Remove when not testing
824
-
825
-
826
- var prefix = this.prefixes[namesp];
827
- if (!prefix) prefix = this.makeUpPrefix(namesp);
828
-
829
- if (prefix) {
830
- this.namespacesUsed[namesp] = true;
831
- return prefix + ':' + localid;
832
- } // Fall though if can't do qname
833
-
612
+ i = j + 1;
613
+ }
614
+ return delim + res + str.slice(i) + delim;
615
+ }
616
+ // A single symbol, either in <> or namespace notation
617
+
618
+ symbolToN3(x) {
619
+ // c.f. symbolString() in notation3.py
620
+ var uri = x.uri;
621
+ var j = uri.indexOf('#');
622
+ if (j < 0 && this.flags.indexOf('/') < 0) {
623
+ j = uri.lastIndexOf('/');
624
+ }
625
+ if (j >= 0 && this.flags.indexOf('p') < 0 && (
626
+ // Can split at namespace but only if http[s]: URI or file: or ws[s] (why not others?)
627
+ uri.indexOf('http') === 0 || uri.indexOf('ws') === 0 || uri.indexOf('file') === 0)) {
628
+ var canSplit = true;
629
+ for (var k = j + 1; k < uri.length; k++) {
630
+ if (this._notNameChars.indexOf(uri[k]) >= 0) {
631
+ canSplit = false;
632
+ break;
834
633
  }
835
634
  }
836
-
837
- return this.explicitURI(uri);
838
- } // /////////////////////////// Quad store serialization
839
- // @para. write - a function taking a single string to be output
840
- //
841
-
842
- }, {
843
- key: "writeStore",
844
- value: function writeStore(write) {
845
- var kb = this.store;
846
- var fetcher = kb.fetcher;
847
- var session = fetcher && fetcher.appNode; // The core data
848
-
849
- var sources = this.store.index[3];
850
-
851
- for (var s in sources) {
852
- // -> assume we can use -> as short for log:semantics
853
- var source = kb.fromNT(s);
854
- if (session && source.equals(session)) continue;
855
- write('\n' + this.atomicTermToN3(source) + ' ' + this.atomicTermToN3(kb.sym('http://www.w3.org/2000/10/swap/log#semantics')) + ' { ' + this.statementsToN3(kb.statementsMatching(undefined, undefined, undefined, source)) + ' }.\n');
856
- } // The metadata from HTTP interactions:
857
-
858
-
859
- kb.statementsMatching(undefined, kb.sym('http://www.w3.org/2007/ont/link#requestedURI')).map(function (st) {
860
- write('\n<' + st.object.value + '> log:metadata {\n');
861
- var sts = kb.statementsMatching(undefined, undefined, undefined, st.subject);
862
- write(this.statementsToN3(this.statementsToN3(sts)));
863
- write('}.\n');
864
- }); // Inferences we have made ourselves not attributable to anyone else
865
-
866
- var metaSources = [];
867
- if (session) metaSources.push(session);
868
- var metadata = [];
869
- metaSources.map(function (source) {
870
- metadata = metadata.concat(kb.statementsMatching(undefined, undefined, undefined, source));
871
- });
872
- write(this.statementsToN3(metadata));
873
- } // ////////////////////////////////////////////// XML serialization
874
-
875
- }, {
876
- key: "statementsToXML",
877
- value: function statementsToXML(sts) {
878
- var indent = 4;
879
- var width = 80;
880
- var namespaceCounts = []; // which have been used
881
-
882
- namespaceCounts['http://www.w3.org/1999/02/22-rdf-syntax-ns#'] = true;
883
- var liPrefix = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#_'; // prefix for ordered list items
884
- // //////////////////////// Arrange the bits of XML text
885
-
886
- var spaces = function spaces(n) {
887
- var s = '';
888
-
889
- for (var i = 0; i < n; i++) {
890
- s += ' ';
891
- }
892
-
893
- return s;
894
- };
895
-
896
- var XMLtreeToLine = function XMLtreeToLine(tree) {
897
- var str = '';
898
-
899
- for (var i = 0; i < tree.length; i++) {
900
- var branch = tree[i];
901
- var s2 = typeof branch === 'string' ? branch : XMLtreeToLine(branch);
902
- str += s2;
903
- }
904
-
905
- return str;
906
- }; // Convert a nested tree of lists and strings to a string
907
-
908
-
909
- var XMLtreeToString = function XMLtreeToString(tree, level) {
910
- var str = '';
911
- var line;
912
- var lastLength = 100000;
913
- if (!level) level = 0;
914
-
915
- for (var i = 0; i < tree.length; i++) {
916
- var branch = tree[i];
917
-
918
- if (typeof branch !== 'string') {
919
- var substr = XMLtreeToString(branch, level + 1);
920
-
921
- if (substr.length < 10 * (width - indent * level) && substr.indexOf('"""') < 0) {
922
- // Don't mess up multiline strings
923
- line = XMLtreeToLine(branch);
924
-
925
- if (line.length < width - indent * level) {
926
- branch = ' ' + line; // @@ Hack: treat as string below
927
-
928
- substr = '';
635
+ /*
636
+ if (uri.slice(0, j + 1) === this.base + '#') { // base-relative
637
+ if (canSplit) {
638
+ return ':' + uri.slice(j + 1) // assume deafult ns is local
639
+ } else {
640
+ return '<#' + uri.slice(j + 1) + '>'
929
641
  }
930
642
  }
931
-
932
- if (substr) lastLength = 10000;
933
- str += substr;
934
- }
935
-
936
- if (typeof branch === 'string') {
937
- if (lastLength < indent * level + 4) {
938
- // continue
939
- str = str.slice(0, -1) + ' ' + branch + '\n';
940
- lastLength += branch.length + 1;
941
- } else {
942
- line = spaces(indent * level) + branch;
943
- str += line + '\n';
944
- lastLength = line.length;
945
- }
946
- } else {// not string
643
+ */
644
+ if (canSplit) {
645
+ var localid = uri.slice(j + 1);
646
+ var namesp = uri.slice(0, j + 1);
647
+ if (this.defaultNamespace && this.defaultNamespace === namesp && this.flags.indexOf('d') < 0) {
648
+ // d -> suppress default
649
+ if (this.flags.indexOf('k') >= 0 && this.keyords.indexOf(localid) < 0) {
650
+ return localid;
947
651
  }
652
+ return ':' + localid;
948
653
  }
949
-
950
- return str;
951
- };
952
-
953
- function statementListToXMLTreeMethod(statements) {
954
- this.suggestPrefix('rdf', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#');
955
- var stats = this.rootSubjects(statements);
956
- var roots = stats.roots;
957
- var results = [];
958
-
959
- for (var i = 0; i < roots.length; i++) {
960
- var root = roots[i];
961
- results.push(subjectXMLTree(root, stats));
654
+ // this.checkIntegrity() // @@@ Remove when not testing
655
+ var prefix = this.prefixes[namesp];
656
+ if (!prefix) prefix = this.makeUpPrefix(namesp);
657
+ if (prefix) {
658
+ this.namespacesUsed[namesp] = true;
659
+ return prefix + ':' + localid;
962
660
  }
963
-
964
- return results;
965
- }
966
-
967
- var statementListToXMLTree = statementListToXMLTreeMethod.bind(this);
968
-
969
- function escapeForXML(str) {
970
- if (typeof str === 'undefined') return '@@@undefined@@@@';
971
- return str.replace(/[&<"]/g, function (m) {
972
- switch (m[0]) {
973
- case '&':
974
- return '&amp;';
975
-
976
- case '<':
977
- return '&lt;';
978
-
979
- case '"':
980
- return '&quot;';
981
- // '
982
- }
983
- });
661
+ // Fall though if can't do qname
984
662
  }
663
+ }
985
664
 
986
- function relURIMethod(term) {
987
- return escapeForXML(this.base ? Util.uri.refTo(this.base, term.uri) : term.uri);
988
- }
989
-
990
- var relURI = relURIMethod.bind(this); // The tree for a subject
991
-
992
- function subjectXMLTreeMethod(subject, stats) {
993
- var results = [];
994
- var type, t, st, pred;
995
- var sts = stats.subjects[this.toStr(subject)]; // relevant statements
665
+ return this.explicitURI(uri);
666
+ }
996
667
 
997
- if (typeof sts === 'undefined') {
998
- // empty bnode
999
- return propertyXMLTree(subject, stats);
1000
- } // Sort only on the predicate, leave the order at object
1001
- // level undisturbed. This leaves multilingual content in
1002
- // the order of entry (for partner literals), which helps
1003
- // readability.
1004
- //
1005
- // For the predicate sort, we attempt to split the uri
1006
- // as a hint to the sequence
668
+ // /////////////////////////// Quad store serialization
1007
669
 
670
+ // @para. write - a function taking a single string to be output
671
+ //
672
+ writeStore(write) {
673
+ var kb = this.store;
674
+ var fetcher = kb.fetcher;
675
+ var session = fetcher && fetcher.appNode;
1008
676
 
1009
- sts.sort(function (a, b) {
1010
- var ap = a.predicate.uri;
1011
- var bp = b.predicate.uri;
677
+ // The core data
1012
678
 
1013
- if (ap.substring(0, liPrefix.length) === liPrefix || bp.substring(0, liPrefix.length) === liPrefix) {
1014
- // we're only interested in sorting list items
1015
- return ap.localeCompare(bp);
1016
- }
679
+ var sources = this.store.index[3];
680
+ for (var s in sources) {
681
+ // -> assume we can use -> as short for log:semantics
682
+ var source = kb.fromNT(s);
683
+ if (session && source.equals(session)) continue;
684
+ write('\n' + this.atomicTermToN3(source) + ' ' + this.atomicTermToN3(kb.sym('http://www.w3.org/2000/10/swap/log#semantics')) + ' { ' + this.statementsToN3(kb.statementsMatching(undefined, undefined, undefined, source)) + ' }.\n');
685
+ }
1017
686
 
1018
- var as = ap.substring(liPrefix.length);
1019
- var bs = bp.substring(liPrefix.length);
1020
- var an = parseInt(as, 10);
1021
- var bn = parseInt(bs, 10);
687
+ // The metadata from HTTP interactions:
1022
688
 
1023
- if (isNaN(an) || isNaN(bn) || an !== as || bn !== bs) {
1024
- // we only care about integers
1025
- return ap.localeCompare(bp);
1026
- }
689
+ kb.statementsMatching(undefined, kb.sym('http://www.w3.org/2007/ont/link#requestedURI')).map(function (st) {
690
+ write('\n<' + st.object.value + '> log:metadata {\n');
691
+ var sts = kb.statementsMatching(undefined, undefined, undefined, st.subject);
692
+ write(this.statementsToN3(this.statementsToN3(sts)));
693
+ write('}.\n');
694
+ });
1027
695
 
1028
- return an - bn;
1029
- });
696
+ // Inferences we have made ourselves not attributable to anyone else
1030
697
 
1031
- for (var i = 0; i < sts.length; i++) {
1032
- st = sts[i]; // look for a type
1033
-
1034
- if (st.predicate.uri === 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' && !type && st.object.termType === 'NamedNode') {
1035
- type = st.object;
1036
- continue; // don't include it as a child element
1037
- } // see whether predicate can be replaced with "li"
698
+ var metaSources = [];
699
+ if (session) metaSources.push(session);
700
+ var metadata = [];
701
+ metaSources.map(function (source) {
702
+ metadata = metadata.concat(kb.statementsMatching(undefined, undefined, undefined, source));
703
+ });
704
+ write(this.statementsToN3(metadata));
705
+ }
1038
706
 
707
+ // ////////////////////////////////////////////// XML serialization
1039
708
 
1040
- pred = st.predicate;
709
+ statementsToXML(sts) {
710
+ var indent = 4;
711
+ var width = 80;
712
+ var namespaceCounts = []; // which have been used
713
+ namespaceCounts['http://www.w3.org/1999/02/22-rdf-syntax-ns#'] = true;
714
+ var liPrefix = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#_'; // prefix for ordered list items
1041
715
 
1042
- if (pred.uri.substr(0, liPrefix.length) === liPrefix) {
1043
- var number = pred.uri.substr(liPrefix.length); // make sure these are actually numeric list items
716
+ // //////////////////////// Arrange the bits of XML text
1044
717
 
1045
- var intNumber = parseInt(number, 10);
718
+ var spaces = function (n) {
719
+ var s = '';
720
+ for (var i = 0; i < n; i++) s += ' ';
721
+ return s;
722
+ };
723
+ var XMLtreeToLine = function (tree) {
724
+ var str = '';
725
+ for (var i = 0; i < tree.length; i++) {
726
+ var branch = tree[i];
727
+ var s2 = typeof branch === 'string' ? branch : XMLtreeToLine(branch);
728
+ str += s2;
729
+ }
730
+ return str;
731
+ };
1046
732
 
1047
- if (number === intNumber.toString()) {
1048
- // was numeric; don't need to worry about ordering since we've already
1049
- // sorted the statements
1050
- pred = this.rdfFactory.namedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#li');
733
+ // Convert a nested tree of lists and strings to a string
734
+ var XMLtreeToString = function (tree, level) {
735
+ var str = '';
736
+ var line;
737
+ var lastLength = 100000;
738
+ if (!level) level = 0;
739
+ for (var i = 0; i < tree.length; i++) {
740
+ var branch = tree[i];
741
+ if (typeof branch !== 'string') {
742
+ var substr = XMLtreeToString(branch, level + 1);
743
+ if (substr.length < 10 * (width - indent * level) && substr.indexOf('"""') < 0) {
744
+ // Don't mess up multiline strings
745
+ line = XMLtreeToLine(branch);
746
+ if (line.length < width - indent * level) {
747
+ branch = ' ' + line; // @@ Hack: treat as string below
748
+ substr = '';
1051
749
  }
1052
750
  }
1053
-
1054
- t = qname(pred);
1055
-
1056
- switch (st.object.termType) {
1057
- case 'BlankNode':
1058
- if (stats.incoming[st.object].length === 1) {
1059
- // there should always be something in the incoming array for a bnode
1060
- results = results.concat(['<' + t + ' rdf:parseType="Resource">', subjectXMLTree(st.object, stats), '</' + t + '>']);
1061
- } else {
1062
- results = results.concat(['<' + t + ' rdf:nodeID="' + st.object.toNT().slice(2) + '"/>']);
1063
- }
1064
-
1065
- break;
1066
-
1067
- case 'NamedNode':
1068
- results = results.concat(['<' + t + ' rdf:resource="' + relURI(st.object) + '"/>']);
1069
- break;
1070
-
1071
- case 'Literal':
1072
- results = results.concat(['<' + t + (st.object.datatype.equals(this.xsd.string) ? '' : ' rdf:datatype="' + escapeForXML(st.object.datatype.uri) + '"') + (st.object.language ? ' xml:lang="' + st.object.language + '"' : '') + '>' + escapeForXML(st.object.value) + '</' + t + '>']);
1073
- break;
1074
-
1075
- case 'Collection':
1076
- results = results.concat(['<' + t + ' rdf:parseType="Collection">', collectionXMLTree(st.object, stats), '</' + t + '>']);
1077
- break;
1078
-
1079
- default:
1080
- throw new Error("Can't serialize object of type " + st.object.termType + ' into XML');
1081
- } // switch
1082
-
1083
- }
1084
-
1085
- var tag = type ? qname(type) : 'rdf:Description';
1086
- var attrs = '';
1087
-
1088
- if (subject.termType === 'BlankNode') {
1089
- if (!stats.incoming[subject] || stats.incoming[subject].length !== 1) {
1090
- // not an anonymous bnode
1091
- attrs = ' rdf:nodeID="' + subject.toNT().slice(2) + '"';
751
+ if (substr) lastLength = 10000;
752
+ str += substr;
753
+ }
754
+ if (typeof branch === 'string') {
755
+ if (lastLength < indent * level + 4) {
756
+ // continue
757
+ str = str.slice(0, -1) + ' ' + branch + '\n';
758
+ lastLength += branch.length + 1;
759
+ } else {
760
+ line = spaces(indent * level) + branch;
761
+ str += line + '\n';
762
+ lastLength = line.length;
1092
763
  }
1093
- } else {
1094
- attrs = ' rdf:about="' + relURI(subject) + '"';
764
+ } else {// not string
1095
765
  }
1096
-
1097
- return ['<' + tag + attrs + '>'].concat([results]).concat(['</' + tag + '>']);
1098
766
  }
1099
-
1100
- var subjectXMLTree = subjectXMLTreeMethod.bind(this);
1101
-
1102
- function collectionXMLTree(subject, stats) {
1103
- var res = [];
1104
-
1105
- for (var i = 0; i < subject.elements.length; i++) {
1106
- res.push(subjectXMLTree(subject.elements[i], stats));
1107
- }
1108
-
1109
- return res;
1110
- } // The property tree for a single subject or anonymos node
1111
-
1112
-
1113
- function propertyXMLTreeMethod(subject, stats) {
1114
- var results = [];
1115
- var sts = stats.subjects[this.toStr(subject)]; // relevant statements
1116
-
1117
- if (!sts) return results; // No relevant statements
1118
-
1119
- sts.sort();
1120
-
1121
- for (var i = 0; i < sts.length; i++) {
1122
- var st = sts[i];
1123
-
1124
- switch (st.object.termType) {
1125
- case 'BlankNode':
1126
- if (stats.rootsHash[st.object.toNT()]) {
1127
- // This bnode has been done as a root -- no content here @@ what bout first time
1128
- results = results.concat(['<' + qname(st.predicate) + ' rdf:nodeID="' + st.object.toNT().slice(2) + '">', '</' + qname(st.predicate) + '>']);
1129
- } else {
1130
- results = results.concat(['<' + qname(st.predicate) + ' rdf:parseType="Resource">', propertyXMLTree(st.object, stats), '</' + qname(st.predicate) + '>']);
1131
- }
1132
-
1133
- break;
1134
-
1135
- case 'NamedNode':
1136
- results = results.concat(['<' + qname(st.predicate) + ' rdf:resource="' + relURI(st.object) + '"/>']);
1137
- break;
1138
-
1139
- case 'Literal':
1140
- results = results.concat(['<' + qname(st.predicate) + (st.object.datatype.equals(this.xsd.string) ? '' : ' rdf:datatype="' + escapeForXML(st.object.datatype.value) + '"') + (st.object.language ? ' xml:lang="' + st.object.language + '"' : '') + '>' + escapeForXML(st.object.value) + '</' + qname(st.predicate) + '>']);
1141
- break;
1142
-
1143
- case 'Collection':
1144
- results = results.concat(['<' + qname(st.predicate) + ' rdf:parseType="Collection">', collectionXMLTree(st.object, stats), '</' + qname(st.predicate) + '>']);
1145
- break;
1146
-
1147
- default:
1148
- throw new Error("Can't serialize object of type " + st.object.termType + ' into XML');
1149
- } // switch
1150
-
1151
- }
1152
-
1153
- return results;
1154
- }
1155
-
1156
- var propertyXMLTree = propertyXMLTreeMethod.bind(this);
1157
-
1158
- function qnameMethod(term) {
1159
- var uri = term.uri;
1160
- var j = uri.indexOf('#');
1161
-
1162
- if (j < 0 && this.flags.indexOf('/') < 0) {
1163
- j = uri.lastIndexOf('/');
767
+ return str;
768
+ };
769
+ function statementListToXMLTreeMethod(statements) {
770
+ this.suggestPrefix('rdf', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#');
771
+ var stats = this.rootSubjects(statements);
772
+ var roots = stats.roots;
773
+ var results = [];
774
+ for (var i = 0; i < roots.length; i++) {
775
+ var root = roots[i];
776
+ results.push(subjectXMLTree(root, stats));
777
+ }
778
+ return results;
779
+ }
780
+ var statementListToXMLTree = statementListToXMLTreeMethod.bind(this);
781
+ function escapeForXML(str) {
782
+ if (typeof str === 'undefined') return '@@@undefined@@@@';
783
+ return str.replace(/[&<"]/g, function (m) {
784
+ switch (m[0]) {
785
+ case '&':
786
+ return '&amp;';
787
+ case '<':
788
+ return '&lt;';
789
+ case '"':
790
+ return '&quot;';
791
+ // '
1164
792
  }
793
+ });
794
+ }
1165
795
 
1166
- if (j < 0) throw new Error('Cannot make qname out of <' + uri + '>');
1167
-
1168
- for (var k = j + 1; k < uri.length; k++) {
1169
- if (this._notNameChars.indexOf(uri[k]) >= 0) {
1170
- throw new Error('Invalid character "' + uri[k] + '" cannot be in XML qname for URI: ' + uri);
796
+ function relURIMethod(term) {
797
+ return escapeForXML(this.base ? Util.uri.refTo(this.base, term.uri) : term.uri);
798
+ }
799
+ var relURI = relURIMethod.bind(this);
800
+
801
+ // The tree for a subject
802
+ function subjectXMLTreeMethod(subject, stats) {
803
+ var results = [];
804
+ var type, t, st, pred;
805
+ var sts = stats.subjects[this.toStr(subject)]; // relevant statements
806
+ if (typeof sts === 'undefined') {
807
+ // empty bnode
808
+ return propertyXMLTree(subject, stats);
809
+ }
810
+
811
+ // Sort only on the predicate, leave the order at object
812
+ // level undisturbed. This leaves multilingual content in
813
+ // the order of entry (for partner literals), which helps
814
+ // readability.
815
+ //
816
+ // For the predicate sort, we attempt to split the uri
817
+ // as a hint to the sequence
818
+ sts.sort(function (a, b) {
819
+ var ap = a.predicate.uri;
820
+ var bp = b.predicate.uri;
821
+ if (ap.substring(0, liPrefix.length) === liPrefix || bp.substring(0, liPrefix.length) === liPrefix) {
822
+ // we're only interested in sorting list items
823
+ return ap.localeCompare(bp);
824
+ }
825
+ var as = ap.substring(liPrefix.length);
826
+ var bs = bp.substring(liPrefix.length);
827
+ var an = parseInt(as, 10);
828
+ var bn = parseInt(bs, 10);
829
+ if (isNaN(an) || isNaN(bn) || an !== as || bn !== bs) {
830
+ // we only care about integers
831
+ return ap.localeCompare(bp);
832
+ }
833
+ return an - bn;
834
+ });
835
+ for (var i = 0; i < sts.length; i++) {
836
+ st = sts[i];
837
+ // look for a type
838
+ if (st.predicate.uri === 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' && !type && st.object.termType === 'NamedNode') {
839
+ type = st.object;
840
+ continue; // don't include it as a child element
841
+ }
842
+
843
+ // see whether predicate can be replaced with "li"
844
+ pred = st.predicate;
845
+ if (pred.uri.substr(0, liPrefix.length) === liPrefix) {
846
+ var number = pred.uri.substr(liPrefix.length);
847
+ // make sure these are actually numeric list items
848
+ var intNumber = parseInt(number, 10);
849
+ if (number === intNumber.toString()) {
850
+ // was numeric; don't need to worry about ordering since we've already
851
+ // sorted the statements
852
+ pred = this.rdfFactory.namedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#li');
1171
853
  }
1172
854
  }
855
+ t = qname(pred);
856
+ switch (st.object.termType) {
857
+ case 'BlankNode':
858
+ if (stats.incoming[st.object].length === 1) {
859
+ // there should always be something in the incoming array for a bnode
860
+ results = results.concat(['<' + t + ' rdf:parseType="Resource">', subjectXMLTree(st.object, stats), '</' + t + '>']);
861
+ } else {
862
+ results = results.concat(['<' + t + ' rdf:nodeID="' + st.object.toNT().slice(2) + '"/>']);
863
+ }
864
+ break;
865
+ case 'NamedNode':
866
+ results = results.concat(['<' + t + ' rdf:resource="' + relURI(st.object) + '"/>']);
867
+ break;
868
+ case 'Literal':
869
+ results = results.concat(['<' + t + (st.object.datatype.equals(this.xsd.string) ? '' : ' rdf:datatype="' + escapeForXML(st.object.datatype.uri) + '"') + (st.object.language ? ' xml:lang="' + st.object.language + '"' : '') + '>' + escapeForXML(st.object.value) + '</' + t + '>']);
870
+ break;
871
+ case 'Collection':
872
+ results = results.concat(['<' + t + ' rdf:parseType="Collection">', collectionXMLTree(st.object, stats), '</' + t + '>']);
873
+ break;
874
+ default:
875
+ throw new Error("Can't serialize object of type " + st.object.termType + ' into XML');
876
+ } // switch
877
+ }
1173
878
 
1174
- var localid = uri.slice(j + 1);
1175
- var namesp = uri.slice(0, j + 1);
1176
-
1177
- if (this.defaultNamespace && this.defaultNamespace === namesp && this.flags.indexOf('d') < 0) {
1178
- // d -> suppress default
1179
- return localid;
879
+ var tag = type ? qname(type) : 'rdf:Description';
880
+ var attrs = '';
881
+ if (subject.termType === 'BlankNode') {
882
+ if (!stats.incoming[subject] || stats.incoming[subject].length !== 1) {
883
+ // not an anonymous bnode
884
+ attrs = ' rdf:nodeID="' + subject.toNT().slice(2) + '"';
1180
885
  }
1181
-
1182
- var prefix = this.prefixes[namesp];
1183
- if (!prefix) prefix = this.makeUpPrefix(namesp);
1184
- namespaceCounts[namesp] = true;
1185
- return prefix + ':' + localid;
886
+ } else {
887
+ attrs = ' rdf:about="' + relURI(subject) + '"';
1186
888
  }
1187
-
1188
- var qname = qnameMethod.bind(this); // Body of toXML:
1189
-
1190
- var tree = statementListToXMLTree(sts);
1191
- var str = '<rdf:RDF';
1192
-
1193
- if (this.defaultNamespace) {
1194
- str += ' xmlns="' + escapeForXML(this.defaultNamespace) + '"';
889
+ return ['<' + tag + attrs + '>'].concat([results]).concat(['</' + tag + '>']);
890
+ }
891
+ var subjectXMLTree = subjectXMLTreeMethod.bind(this);
892
+ function collectionXMLTree(subject, stats) {
893
+ var res = [];
894
+ for (var i = 0; i < subject.elements.length; i++) {
895
+ res.push(subjectXMLTree(subject.elements[i], stats));
1195
896
  }
897
+ return res;
898
+ }
1196
899
 
1197
- for (var ns in namespaceCounts) {
1198
- if (!namespaceCounts.hasOwnProperty(ns)) continue; // Rel uris in xml ns is not strictly allowed in the XMLNS spec but needed in practice often
1199
-
1200
- var ns2 = this.base && this.flags.includes('z') ? Util.uri.refTo(this.base, ns) : ns;
1201
- str += '\n xmlns:' + this.prefixes[ns] + '="' + escapeForXML(ns2) + '"';
900
+ // The property tree for a single subject or anonymos node
901
+ function propertyXMLTreeMethod(subject, stats) {
902
+ var results = [];
903
+ var sts = stats.subjects[this.toStr(subject)]; // relevant statements
904
+ if (!sts) return results; // No relevant statements
905
+ sts.sort();
906
+ for (var i = 0; i < sts.length; i++) {
907
+ var st = sts[i];
908
+ switch (st.object.termType) {
909
+ case 'BlankNode':
910
+ if (stats.rootsHash[st.object.toNT()]) {
911
+ // This bnode has been done as a root -- no content here @@ what bout first time
912
+ results = results.concat(['<' + qname(st.predicate) + ' rdf:nodeID="' + st.object.toNT().slice(2) + '">', '</' + qname(st.predicate) + '>']);
913
+ } else {
914
+ results = results.concat(['<' + qname(st.predicate) + ' rdf:parseType="Resource">', propertyXMLTree(st.object, stats), '</' + qname(st.predicate) + '>']);
915
+ }
916
+ break;
917
+ case 'NamedNode':
918
+ results = results.concat(['<' + qname(st.predicate) + ' rdf:resource="' + relURI(st.object) + '"/>']);
919
+ break;
920
+ case 'Literal':
921
+ results = results.concat(['<' + qname(st.predicate) + (st.object.datatype.equals(this.xsd.string) ? '' : ' rdf:datatype="' + escapeForXML(st.object.datatype.value) + '"') + (st.object.language ? ' xml:lang="' + st.object.language + '"' : '') + '>' + escapeForXML(st.object.value) + '</' + qname(st.predicate) + '>']);
922
+ break;
923
+ case 'Collection':
924
+ results = results.concat(['<' + qname(st.predicate) + ' rdf:parseType="Collection">', collectionXMLTree(st.object, stats), '</' + qname(st.predicate) + '>']);
925
+ break;
926
+ default:
927
+ throw new Error("Can't serialize object of type " + st.object.termType + ' into XML');
928
+ } // switch
1202
929
  }
1203
930
 
1204
- str += '>';
1205
- var tree2 = [str, tree, '</rdf:RDF>']; // @@ namespace declrations
1206
-
1207
- return XMLtreeToString(tree2, -1);
1208
- } // End @@ body
931
+ return results;
932
+ }
933
+ var propertyXMLTree = propertyXMLTreeMethod.bind(this);
934
+ function qnameMethod(term) {
935
+ var uri = term.uri;
936
+ var j = uri.indexOf('#');
937
+ if (j < 0 && this.flags.indexOf('/') < 0) {
938
+ j = uri.lastIndexOf('/');
939
+ }
940
+ if (j < 0) throw new Error('Cannot make qname out of <' + uri + '>');
941
+ for (var k = j + 1; k < uri.length; k++) {
942
+ if (this._notNameChars.indexOf(uri[k]) >= 0) {
943
+ throw new Error('Invalid character "' + uri[k] + '" cannot be in XML qname for URI: ' + uri);
944
+ }
945
+ }
946
+ var localid = uri.slice(j + 1);
947
+ var namesp = uri.slice(0, j + 1);
948
+ if (this.defaultNamespace && this.defaultNamespace === namesp && this.flags.indexOf('d') < 0) {
949
+ // d -> suppress default
950
+ return localid;
951
+ }
952
+ var prefix = this.prefixes[namesp];
953
+ if (!prefix) prefix = this.makeUpPrefix(namesp);
954
+ namespaceCounts[namesp] = true;
955
+ return prefix + ':' + localid;
956
+ }
957
+ var qname = qnameMethod.bind(this);
1209
958
 
1210
- }]);
1211
- return Serializer;
1212
- }(); // String escaping utilities
959
+ // Body of toXML:
1213
960
 
961
+ var tree = statementListToXMLTree(sts);
962
+ var str = '<rdf:RDF';
963
+ if (this.defaultNamespace) {
964
+ str += ' xmlns="' + escapeForXML(this.defaultNamespace) + '"';
965
+ }
966
+ for (var ns in namespaceCounts) {
967
+ if (!namespaceCounts.hasOwnProperty(ns)) continue;
968
+ // Rel uris in xml ns is not strictly allowed in the XMLNS spec but needed in practice often
969
+ var ns2 = this.base && this.flags.includes('z') ? Util.uri.refTo(this.base, ns) : ns;
970
+ str += '\n xmlns:' + this.prefixes[ns] + '="' + escapeForXML(ns2) + '"';
971
+ }
972
+ str += '>';
973
+ var tree2 = [str, tree, '</rdf:RDF>']; // @@ namespace declrations
974
+ return XMLtreeToString(tree2, -1);
975
+ } // End @@ body
976
+ }
1214
977
 
978
+ // String escaping utilities
1215
979
  exports.Serializer = Serializer;
1216
-
1217
980
  function hexify(str) {
1218
981
  // also used in parser
1219
982
  return encodeURI(str);
1220
983
  }
1221
-
1222
984
  function backslashUify(str) {
1223
985
  var res = '';
1224
986
  var k;
1225
-
1226
987
  for (var i = 0; i < str.length; i++) {
1227
988
  k = str.charCodeAt(i);
1228
-
1229
989
  if (k > 65535) {
1230
- res += "\\U" + ('00000000' + k.toString(16)).slice(-8); // convert to upper?
990
+ res += '\\U' + ('00000000' + k.toString(16)).slice(-8); // convert to upper?
1231
991
  } else if (k > 126) {
1232
- res += "\\u" + ('0000' + k.toString(16)).slice(-4);
992
+ res += '\\u' + ('0000' + k.toString(16)).slice(-4);
1233
993
  } else {
1234
994
  res += str[i];
1235
995
  }
1236
996
  }
1237
-
1238
997
  return res;
1239
998
  }