rdflib 2.2.21 → 2.2.22-04669b23

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