yaml 2.0.0-4 → 2.0.0-8

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 (220) hide show
  1. package/README.md +5 -5
  2. package/browser/dist/compose/compose-collection.js +12 -9
  3. package/browser/dist/compose/compose-doc.js +23 -6
  4. package/browser/dist/compose/compose-node.js +27 -17
  5. package/browser/dist/compose/compose-scalar.js +21 -23
  6. package/browser/dist/compose/composer.js +108 -78
  7. package/browser/dist/compose/resolve-block-map.js +41 -29
  8. package/browser/dist/compose/resolve-block-scalar.js +14 -17
  9. package/browser/dist/compose/resolve-block-seq.js +21 -17
  10. package/browser/dist/compose/resolve-end.js +7 -8
  11. package/browser/dist/compose/resolve-flow-collection.js +158 -199
  12. package/browser/dist/compose/resolve-flow-scalar.js +62 -26
  13. package/browser/dist/compose/resolve-props.js +72 -37
  14. package/browser/dist/compose/util-contains-newline.js +15 -12
  15. package/browser/dist/compose/util-map-includes.js +17 -0
  16. package/browser/dist/doc/Document.js +74 -99
  17. package/browser/dist/doc/anchors.js +72 -0
  18. package/browser/dist/doc/createNode.js +35 -19
  19. package/browser/dist/doc/directives.js +5 -0
  20. package/browser/dist/errors.js +16 -12
  21. package/browser/dist/index.js +3 -3
  22. package/browser/dist/nodes/Alias.js +51 -28
  23. package/browser/dist/nodes/Collection.js +23 -92
  24. package/browser/dist/nodes/Node.js +9 -1
  25. package/browser/dist/nodes/Pair.js +16 -231
  26. package/browser/dist/nodes/YAMLMap.js +8 -4
  27. package/browser/dist/nodes/YAMLSeq.js +7 -4
  28. package/browser/dist/nodes/addPairToJSMap.js +103 -0
  29. package/browser/dist/nodes/toJS.js +12 -10
  30. package/browser/dist/options.js +1 -2
  31. package/browser/dist/parse/cst-scalar.js +219 -0
  32. package/browser/dist/parse/cst-stringify.js +61 -0
  33. package/browser/dist/parse/cst-visit.js +97 -0
  34. package/{dist/parse/tokens.js → browser/dist/parse/cst.js} +12 -7
  35. package/browser/dist/parse/lexer.js +149 -125
  36. package/browser/dist/parse/parser.js +272 -196
  37. package/browser/dist/public-api.js +11 -14
  38. package/browser/dist/schema/Schema.js +28 -0
  39. package/browser/dist/{tags/failsafe → schema/common}/map.js +0 -0
  40. package/browser/dist/schema/common/null.js +13 -0
  41. package/browser/dist/{tags/failsafe → schema/common}/seq.js +1 -1
  42. package/browser/dist/{tags/failsafe → schema/common}/string.js +0 -0
  43. package/browser/dist/schema/core/bool.js +19 -0
  44. package/browser/dist/schema/core/float.js +40 -0
  45. package/browser/dist/schema/core/int.js +38 -0
  46. package/browser/dist/schema/core/schema.js +23 -0
  47. package/browser/dist/{tags/json.js → schema/json/schema.js} +5 -6
  48. package/browser/dist/schema/tags.js +79 -0
  49. package/browser/dist/{tags → schema}/yaml-1.1/binary.js +0 -0
  50. package/browser/dist/schema/yaml-1.1/bool.js +26 -0
  51. package/browser/dist/schema/yaml-1.1/float.js +43 -0
  52. package/browser/dist/schema/yaml-1.1/int.js +71 -0
  53. package/browser/dist/{tags → schema}/yaml-1.1/omap.js +0 -0
  54. package/browser/dist/{tags → schema}/yaml-1.1/pairs.js +9 -6
  55. package/browser/dist/schema/yaml-1.1/schema.js +37 -0
  56. package/browser/dist/{tags → schema}/yaml-1.1/set.js +0 -0
  57. package/browser/dist/{tags → schema}/yaml-1.1/timestamp.js +0 -0
  58. package/browser/dist/stringify/stringify.js +8 -6
  59. package/browser/dist/stringify/stringifyCollection.js +122 -0
  60. package/browser/dist/stringify/stringifyComment.js +14 -0
  61. package/browser/dist/stringify/stringifyDocument.js +64 -0
  62. package/browser/dist/stringify/stringifyPair.js +111 -0
  63. package/browser/dist/stringify/stringifyString.js +53 -52
  64. package/browser/dist/visit.js +20 -1
  65. package/dist/compose/compose-collection.d.ts +4 -4
  66. package/dist/compose/compose-collection.js +12 -9
  67. package/dist/compose/compose-doc.d.ts +4 -3
  68. package/dist/compose/compose-doc.js +23 -6
  69. package/dist/compose/compose-node.d.ts +15 -7
  70. package/dist/compose/compose-node.js +27 -17
  71. package/dist/compose/compose-scalar.d.ts +4 -3
  72. package/dist/compose/compose-scalar.js +20 -22
  73. package/dist/compose/composer.d.ts +28 -23
  74. package/dist/compose/composer.js +109 -79
  75. package/dist/compose/resolve-block-map.d.ts +5 -4
  76. package/dist/compose/resolve-block-map.js +41 -29
  77. package/dist/compose/resolve-block-scalar.d.ts +5 -3
  78. package/dist/compose/resolve-block-scalar.js +14 -17
  79. package/dist/compose/resolve-block-seq.d.ts +4 -4
  80. package/dist/compose/resolve-block-seq.js +21 -17
  81. package/dist/compose/resolve-end.d.ts +3 -2
  82. package/dist/compose/resolve-end.js +7 -8
  83. package/dist/compose/resolve-flow-collection.d.ts +4 -5
  84. package/dist/compose/resolve-flow-collection.js +157 -198
  85. package/dist/compose/resolve-flow-scalar.d.ts +5 -3
  86. package/dist/compose/resolve-flow-scalar.js +62 -26
  87. package/dist/compose/resolve-props.d.ts +16 -10
  88. package/dist/compose/resolve-props.js +72 -37
  89. package/dist/compose/util-contains-newline.d.ts +1 -1
  90. package/dist/compose/util-contains-newline.js +15 -12
  91. package/dist/compose/util-empty-scalar-position.d.ts +1 -1
  92. package/dist/compose/util-map-includes.d.ts +4 -0
  93. package/dist/compose/util-map-includes.js +19 -0
  94. package/dist/doc/Document.d.ts +35 -15
  95. package/dist/doc/Document.js +72 -97
  96. package/dist/doc/anchors.d.ts +24 -0
  97. package/dist/doc/anchors.js +77 -0
  98. package/dist/doc/createNode.d.ts +10 -11
  99. package/dist/doc/createNode.js +34 -18
  100. package/dist/doc/directives.d.ts +1 -0
  101. package/dist/doc/directives.js +5 -0
  102. package/dist/errors.d.ts +11 -8
  103. package/dist/errors.js +16 -12
  104. package/dist/index.d.ts +5 -3
  105. package/dist/index.js +3 -3
  106. package/dist/nodes/Alias.d.ts +19 -9
  107. package/dist/nodes/Alias.js +51 -28
  108. package/dist/nodes/Collection.d.ts +9 -17
  109. package/dist/nodes/Collection.js +22 -91
  110. package/dist/nodes/Node.d.ts +10 -4
  111. package/dist/nodes/Node.js +9 -0
  112. package/dist/nodes/Pair.d.ts +10 -13
  113. package/dist/nodes/Pair.js +15 -230
  114. package/dist/nodes/Scalar.d.ts +6 -3
  115. package/dist/nodes/YAMLMap.d.ts +3 -3
  116. package/dist/nodes/YAMLMap.js +8 -4
  117. package/dist/nodes/YAMLSeq.d.ts +3 -3
  118. package/dist/nodes/YAMLSeq.js +7 -4
  119. package/dist/nodes/addPairToJSMap.d.ts +3 -0
  120. package/dist/nodes/addPairToJSMap.js +105 -0
  121. package/dist/nodes/toJS.d.ts +4 -5
  122. package/dist/nodes/toJS.js +12 -10
  123. package/dist/options.d.ts +41 -25
  124. package/dist/options.js +1 -2
  125. package/dist/parse/cst-scalar.d.ts +58 -0
  126. package/dist/parse/cst-scalar.js +223 -0
  127. package/dist/parse/cst-stringify.d.ts +8 -0
  128. package/dist/parse/cst-stringify.js +63 -0
  129. package/dist/parse/cst-visit.d.ts +39 -0
  130. package/dist/parse/cst-visit.js +99 -0
  131. package/dist/parse/{tokens.d.ts → cst.d.ts} +23 -7
  132. package/{browser/dist/parse/tokens.js → dist/parse/cst.js} +27 -1
  133. package/dist/parse/lexer.d.ts +7 -14
  134. package/dist/parse/lexer.js +150 -126
  135. package/dist/parse/parser.d.ts +31 -24
  136. package/dist/parse/parser.js +274 -198
  137. package/dist/public-api.d.ts +7 -7
  138. package/dist/public-api.js +11 -14
  139. package/dist/{doc → schema}/Schema.d.ts +6 -3
  140. package/dist/schema/Schema.js +30 -0
  141. package/dist/{tags/failsafe → schema/common}/map.d.ts +0 -0
  142. package/dist/{tags/failsafe → schema/common}/map.js +0 -0
  143. package/dist/schema/common/null.d.ts +4 -0
  144. package/dist/schema/common/null.js +15 -0
  145. package/dist/{tags/failsafe → schema/common}/seq.d.ts +0 -0
  146. package/dist/{tags/failsafe → schema/common}/seq.js +1 -1
  147. package/dist/{tags/failsafe → schema/common}/string.d.ts +0 -0
  148. package/dist/{tags/failsafe → schema/common}/string.js +0 -0
  149. package/dist/schema/core/bool.d.ts +4 -0
  150. package/dist/schema/core/bool.js +21 -0
  151. package/dist/schema/core/float.d.ts +4 -0
  152. package/dist/schema/core/float.js +44 -0
  153. package/dist/schema/core/int.d.ts +4 -0
  154. package/dist/schema/core/int.js +42 -0
  155. package/dist/schema/core/schema.d.ts +1 -0
  156. package/dist/schema/core/schema.js +25 -0
  157. package/dist/schema/json/schema.d.ts +2 -0
  158. package/dist/{tags/json.js → schema/json/schema.js} +5 -6
  159. package/dist/schema/tags.d.ts +41 -0
  160. package/dist/schema/tags.js +82 -0
  161. package/dist/{tags → schema}/types.d.ts +3 -7
  162. package/dist/{tags → schema}/yaml-1.1/binary.d.ts +0 -0
  163. package/dist/{tags → schema}/yaml-1.1/binary.js +0 -0
  164. package/dist/schema/yaml-1.1/bool.d.ts +7 -0
  165. package/dist/schema/yaml-1.1/bool.js +29 -0
  166. package/dist/schema/yaml-1.1/float.d.ts +4 -0
  167. package/dist/schema/yaml-1.1/float.js +47 -0
  168. package/dist/schema/yaml-1.1/int.d.ts +5 -0
  169. package/dist/schema/yaml-1.1/int.js +76 -0
  170. package/dist/{tags → schema}/yaml-1.1/omap.d.ts +0 -0
  171. package/dist/{tags → schema}/yaml-1.1/omap.js +0 -0
  172. package/dist/{tags → schema}/yaml-1.1/pairs.d.ts +3 -2
  173. package/dist/{tags → schema}/yaml-1.1/pairs.js +9 -6
  174. package/dist/schema/yaml-1.1/schema.d.ts +1 -0
  175. package/dist/schema/yaml-1.1/schema.js +39 -0
  176. package/dist/{tags → schema}/yaml-1.1/set.d.ts +1 -1
  177. package/dist/{tags → schema}/yaml-1.1/set.js +0 -0
  178. package/dist/{tags → schema}/yaml-1.1/timestamp.d.ts +0 -0
  179. package/dist/{tags → schema}/yaml-1.1/timestamp.js +0 -0
  180. package/dist/stringify/stringify.d.ts +1 -2
  181. package/dist/stringify/stringify.js +8 -6
  182. package/dist/stringify/stringifyCollection.d.ts +21 -0
  183. package/dist/stringify/stringifyCollection.js +124 -0
  184. package/dist/stringify/stringifyComment.d.ts +2 -0
  185. package/dist/stringify/stringifyComment.js +17 -0
  186. package/dist/stringify/stringifyDocument.d.ts +3 -0
  187. package/dist/stringify/stringifyDocument.js +66 -0
  188. package/dist/stringify/stringifyPair.d.ts +3 -0
  189. package/dist/stringify/stringifyPair.js +113 -0
  190. package/dist/stringify/stringifyString.js +53 -52
  191. package/dist/test-events.d.ts +1 -2
  192. package/dist/test-events.js +25 -12
  193. package/dist/util.d.ts +1 -1
  194. package/dist/visit.d.ts +10 -1
  195. package/dist/visit.js +20 -1
  196. package/package.json +9 -8
  197. package/browser/dist/doc/Anchors.js +0 -102
  198. package/browser/dist/doc/Schema.js +0 -27
  199. package/browser/dist/doc/getSchemaTags.js +0 -30
  200. package/browser/dist/stringify/addComment.js +0 -17
  201. package/browser/dist/tags/core.js +0 -109
  202. package/browser/dist/tags/failsafe/index.js +0 -7
  203. package/browser/dist/tags/index.js +0 -34
  204. package/browser/dist/tags/yaml-1.1/index.js +0 -152
  205. package/dist/doc/Anchors.d.ts +0 -36
  206. package/dist/doc/Anchors.js +0 -104
  207. package/dist/doc/Schema.js +0 -29
  208. package/dist/doc/getSchemaTags.d.ts +0 -3
  209. package/dist/doc/getSchemaTags.js +0 -32
  210. package/dist/stringify/addComment.d.ts +0 -2
  211. package/dist/stringify/addComment.js +0 -20
  212. package/dist/tags/core.d.ts +0 -14
  213. package/dist/tags/core.js +0 -119
  214. package/dist/tags/failsafe/index.d.ts +0 -1
  215. package/dist/tags/failsafe/index.js +0 -9
  216. package/dist/tags/index.d.ts +0 -31
  217. package/dist/tags/index.js +0 -37
  218. package/dist/tags/json.d.ts +0 -2
  219. package/dist/tags/yaml-1.1/index.d.ts +0 -2
  220. package/dist/tags/yaml-1.1/index.js +0 -154
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var tokens = require('./tokens.js');
3
+ var cst = require('./cst.js');
4
4
 
5
5
  /*
6
6
  START -> stream
@@ -81,9 +81,11 @@ function isEmpty(ch) {
81
81
  return false;
82
82
  }
83
83
  }
84
- const invalidFlowScalarChars = [',', '[', ']', '{', '}'];
85
- const invalidIdentifierChars = [' ', ',', '[', ']', '{', '}', '\n', '\r', '\t'];
86
- const isNotIdentifierChar = (ch) => !ch || invalidIdentifierChars.includes(ch);
84
+ const hexDigits = '0123456789ABCDEFabcdef'.split('');
85
+ const tagChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-#;/?:@&=+$_.!~*'()".split('');
86
+ const invalidFlowScalarChars = ',[]{}'.split('');
87
+ const invalidAnchorChars = ' ,[]{}\n\r\t'.split('');
88
+ const isNotAnchorChar = (ch) => !ch || invalidAnchorChars.includes(ch);
87
89
  /**
88
90
  * Splits an input string into lexical tokens, i.e. smaller strings that are
89
91
  * easily identifiable by `tokens.tokenType()`.
@@ -100,13 +102,7 @@ const isNotIdentifierChar = (ch) => !ch || invalidIdentifierChars.includes(ch);
100
102
  * - `\u{FEFF}` (Byte order mark): Emitted separately outside documents
101
103
  */
102
104
  class Lexer {
103
- /**
104
- * Define/initialise a YAML lexer. `push` will be called separately with each
105
- * token when `lex()` is passed an input string.
106
- *
107
- * @public
108
- */
109
- constructor(push) {
105
+ constructor() {
110
106
  /**
111
107
  * Flag indicating whether the end of the current buffer marks the end of
112
108
  * all input
@@ -140,26 +136,28 @@ class Lexer {
140
136
  this.indentNext = 0;
141
137
  /** Indentation level of the current line. */
142
138
  this.indentValue = 0;
139
+ /** Position of the next \n character. */
140
+ this.lineEndPos = null;
143
141
  /** Stores the state of the lexer if reaching the end of incpomplete input */
144
142
  this.next = null;
145
143
  /** A pointer to `buffer`; the current position of the lexer. */
146
144
  this.pos = 0;
147
- this.push = push;
148
145
  }
149
146
  /**
150
- * Read YAML tokens from the `source` string, calling the callback
151
- * defined in the constructor for each one. If `incomplete`, a part
152
- * of the last line may be left as a buffer for the next call.
147
+ * Generate YAML tokens from the `source` string. If `incomplete`,
148
+ * a part of the last line may be left as a buffer for the next call.
153
149
  *
154
- * @public
150
+ * @returns A generator of lexical tokens
155
151
  */
156
- lex(source, incomplete) {
157
- if (source)
152
+ *lex(source, incomplete = false) {
153
+ if (source) {
158
154
  this.buffer = this.buffer ? this.buffer + source : source;
155
+ this.lineEndPos = null;
156
+ }
159
157
  this.atEnd = !incomplete;
160
158
  let next = this.next || 'stream';
161
159
  while (next && (incomplete || this.hasChars(1)))
162
- next = this.parseNext(next);
160
+ next = yield* this.parseNext(next);
163
161
  }
164
162
  atLineEnd() {
165
163
  let i = this.pos;
@@ -198,7 +196,11 @@ class Lexer {
198
196
  return offset;
199
197
  }
200
198
  getLine() {
201
- let end = this.buffer.indexOf('\n', this.pos);
199
+ let end = this.lineEndPos;
200
+ if (typeof end !== 'number' || (end !== -1 && end < this.pos)) {
201
+ end = this.buffer.indexOf('\n', this.pos);
202
+ this.lineEndPos = end;
203
+ }
202
204
  if (end === -1)
203
205
  return this.atEnd ? this.buffer.substring(this.pos) : null;
204
206
  if (this.buffer[end - 1] === '\r')
@@ -211,38 +213,39 @@ class Lexer {
211
213
  setNext(state) {
212
214
  this.buffer = this.buffer.substring(this.pos);
213
215
  this.pos = 0;
216
+ this.lineEndPos = null;
214
217
  this.next = state;
215
218
  return null;
216
219
  }
217
220
  peek(n) {
218
221
  return this.buffer.substr(this.pos, n);
219
222
  }
220
- parseNext(next) {
223
+ *parseNext(next) {
221
224
  switch (next) {
222
225
  case 'stream':
223
- return this.parseStream();
226
+ return yield* this.parseStream();
224
227
  case 'line-start':
225
- return this.parseLineStart();
228
+ return yield* this.parseLineStart();
226
229
  case 'block-start':
227
- return this.parseBlockStart();
230
+ return yield* this.parseBlockStart();
228
231
  case 'doc':
229
- return this.parseDocument();
232
+ return yield* this.parseDocument();
230
233
  case 'flow':
231
- return this.parseFlowCollection();
234
+ return yield* this.parseFlowCollection();
232
235
  case 'quoted-scalar':
233
- return this.parseQuotedScalar();
236
+ return yield* this.parseQuotedScalar();
234
237
  case 'block-scalar':
235
- return this.parseBlockScalar();
238
+ return yield* this.parseBlockScalar();
236
239
  case 'plain-scalar':
237
- return this.parsePlainScalar();
240
+ return yield* this.parsePlainScalar();
238
241
  }
239
242
  }
240
- parseStream() {
243
+ *parseStream() {
241
244
  let line = this.getLine();
242
245
  if (line === null)
243
246
  return this.setNext('stream');
244
- if (line[0] === tokens.BOM) {
245
- this.pushCount(1);
247
+ if (line[0] === cst.BOM) {
248
+ yield* this.pushCount(1);
246
249
  line = line.substring(1);
247
250
  }
248
251
  if (line[0] === '%') {
@@ -260,21 +263,21 @@ class Lexer {
260
263
  else
261
264
  break;
262
265
  }
263
- const n = this.pushCount(dirEnd) + this.pushSpaces(true);
264
- this.pushCount(line.length - n); // possible comment
266
+ const n = (yield* this.pushCount(dirEnd)) + (yield* this.pushSpaces(true));
267
+ yield* this.pushCount(line.length - n); // possible comment
265
268
  this.pushNewline();
266
269
  return 'stream';
267
270
  }
268
271
  if (this.atLineEnd()) {
269
- const sp = this.pushSpaces(true);
270
- this.pushCount(line.length - sp);
271
- this.pushNewline();
272
+ const sp = yield* this.pushSpaces(true);
273
+ yield* this.pushCount(line.length - sp);
274
+ yield* this.pushNewline();
272
275
  return 'stream';
273
276
  }
274
- this.push(tokens.DOCUMENT);
275
- return this.parseLineStart();
277
+ yield cst.DOCUMENT;
278
+ return yield* this.parseLineStart();
276
279
  }
277
- parseLineStart() {
280
+ *parseLineStart() {
278
281
  const ch = this.charAt(0);
279
282
  if (!ch && !this.atEnd)
280
283
  return this.setNext('line-start');
@@ -283,80 +286,80 @@ class Lexer {
283
286
  return this.setNext('line-start');
284
287
  const s = this.peek(3);
285
288
  if (s === '---' && isEmpty(this.charAt(3))) {
286
- this.pushCount(3);
289
+ yield* this.pushCount(3);
287
290
  this.indentValue = 0;
288
291
  this.indentNext = 0;
289
292
  return 'doc';
290
293
  }
291
294
  else if (s === '...' && isEmpty(this.charAt(3))) {
292
- this.pushCount(3);
295
+ yield* this.pushCount(3);
293
296
  return 'stream';
294
297
  }
295
298
  }
296
- this.indentValue = this.pushSpaces(false);
299
+ this.indentValue = yield* this.pushSpaces(false);
297
300
  if (this.indentNext > this.indentValue && !isEmpty(this.charAt(1)))
298
301
  this.indentNext = this.indentValue;
299
- return this.parseBlockStart();
302
+ return yield* this.parseBlockStart();
300
303
  }
301
- parseBlockStart() {
304
+ *parseBlockStart() {
302
305
  const [ch0, ch1] = this.peek(2);
303
306
  if (!ch1 && !this.atEnd)
304
307
  return this.setNext('block-start');
305
308
  if ((ch0 === '-' || ch0 === '?' || ch0 === ':') && isEmpty(ch1)) {
306
- const n = this.pushCount(1) + this.pushSpaces(true);
309
+ const n = (yield* this.pushCount(1)) + (yield* this.pushSpaces(true));
307
310
  this.indentNext = this.indentValue + 1;
308
311
  this.indentValue += n;
309
- return this.parseBlockStart();
312
+ return yield* this.parseBlockStart();
310
313
  }
311
314
  return 'doc';
312
315
  }
313
- parseDocument() {
314
- this.pushSpaces(true);
316
+ *parseDocument() {
317
+ yield* this.pushSpaces(true);
315
318
  const line = this.getLine();
316
319
  if (line === null)
317
320
  return this.setNext('doc');
318
- let n = this.pushIndicators();
321
+ let n = yield* this.pushIndicators();
319
322
  switch (line[n]) {
320
323
  case '#':
321
- this.pushCount(line.length - n);
324
+ yield* this.pushCount(line.length - n);
322
325
  // fallthrough
323
326
  case undefined:
324
- this.pushNewline();
325
- return this.parseLineStart();
327
+ yield* this.pushNewline();
328
+ return yield* this.parseLineStart();
326
329
  case '{':
327
330
  case '[':
328
- this.pushCount(1);
331
+ yield* this.pushCount(1);
329
332
  this.flowKey = false;
330
333
  this.flowLevel = 1;
331
334
  return 'flow';
332
335
  case '}':
333
336
  case ']':
334
337
  // this is an error
335
- this.pushCount(1);
338
+ yield* this.pushCount(1);
336
339
  return 'doc';
337
340
  case '*':
338
- this.pushUntil(isNotIdentifierChar);
341
+ yield* this.pushUntil(isNotAnchorChar);
339
342
  return 'doc';
340
343
  case '"':
341
344
  case "'":
342
- return this.parseQuotedScalar();
345
+ return yield* this.parseQuotedScalar();
343
346
  case '|':
344
347
  case '>':
345
- n += this.parseBlockScalarHeader();
346
- n += this.pushSpaces(true);
347
- this.pushCount(line.length - n);
348
- this.pushNewline();
349
- return this.parseBlockScalar();
348
+ n += yield* this.parseBlockScalarHeader();
349
+ n += yield* this.pushSpaces(true);
350
+ yield* this.pushCount(line.length - n);
351
+ yield* this.pushNewline();
352
+ return yield* this.parseBlockScalar();
350
353
  default:
351
- return this.parsePlainScalar();
354
+ return yield* this.parsePlainScalar();
352
355
  }
353
356
  }
354
- parseFlowCollection() {
357
+ *parseFlowCollection() {
355
358
  let nl, sp;
356
359
  let indent = -1;
357
360
  do {
358
- nl = this.pushNewline();
359
- sp = this.pushSpaces(true);
361
+ nl = yield* this.pushNewline();
362
+ sp = yield* this.pushSpaces(true);
360
363
  if (nl > 0)
361
364
  this.indentValue = indent = sp;
362
365
  } while (nl + sp > 0);
@@ -376,54 +379,54 @@ class Lexer {
376
379
  if (!atFlowEndMarker) {
377
380
  // this is an error
378
381
  this.flowLevel = 0;
379
- this.push(tokens.FLOW_END);
380
- return this.parseLineStart();
382
+ yield cst.FLOW_END;
383
+ return yield* this.parseLineStart();
381
384
  }
382
385
  }
383
386
  let n = 0;
384
387
  while (line[n] === ',')
385
- n += this.pushCount(1) + this.pushSpaces(true);
386
- n += this.pushIndicators();
388
+ n += (yield* this.pushCount(1)) + (yield* this.pushSpaces(true));
389
+ n += yield* this.pushIndicators();
387
390
  switch (line[n]) {
388
391
  case undefined:
389
392
  return 'flow';
390
393
  case '#':
391
- this.pushCount(line.length - n);
394
+ yield* this.pushCount(line.length - n);
392
395
  return 'flow';
393
396
  case '{':
394
397
  case '[':
395
- this.pushCount(1);
398
+ yield* this.pushCount(1);
396
399
  this.flowKey = false;
397
400
  this.flowLevel += 1;
398
401
  return 'flow';
399
402
  case '}':
400
403
  case ']':
401
- this.pushCount(1);
404
+ yield* this.pushCount(1);
402
405
  this.flowKey = true;
403
406
  this.flowLevel -= 1;
404
407
  return this.flowLevel ? 'flow' : 'doc';
405
408
  case '*':
406
- this.pushUntil(isNotIdentifierChar);
409
+ yield* this.pushUntil(isNotAnchorChar);
407
410
  return 'flow';
408
411
  case '"':
409
412
  case "'":
410
413
  this.flowKey = true;
411
- return this.parseQuotedScalar();
414
+ return yield* this.parseQuotedScalar();
412
415
  case ':': {
413
416
  const next = this.charAt(1);
414
417
  if (this.flowKey || isEmpty(next) || next === ',') {
415
- this.pushCount(1);
416
- this.pushSpaces(true);
418
+ yield* this.pushCount(1);
419
+ yield* this.pushSpaces(true);
417
420
  return 'flow';
418
421
  }
419
422
  }
420
423
  // fallthrough
421
424
  default:
422
425
  this.flowKey = false;
423
- return this.parsePlainScalar();
426
+ return yield* this.parsePlainScalar();
424
427
  }
425
428
  }
426
- parseQuotedScalar() {
429
+ *parseQuotedScalar() {
427
430
  const quote = this.charAt(0);
428
431
  let end = this.buffer.indexOf(quote, this.pos + 1);
429
432
  if (quote === "'") {
@@ -441,17 +444,19 @@ class Lexer {
441
444
  end = this.buffer.indexOf('"', end + 1);
442
445
  }
443
446
  }
444
- let nl = this.buffer.indexOf('\n', this.pos);
445
- if (nl !== -1 && nl < end) {
446
- while (nl !== -1 && nl < end) {
447
+ // Only looking for newlines within the quotes
448
+ const qb = this.buffer.substring(0, end);
449
+ let nl = qb.indexOf('\n', this.pos);
450
+ if (nl !== -1) {
451
+ while (nl !== -1) {
447
452
  const cs = this.continueScalar(nl + 1);
448
453
  if (cs === -1)
449
454
  break;
450
- nl = this.buffer.indexOf('\n', cs);
455
+ nl = qb.indexOf('\n', cs);
451
456
  }
452
- if (nl !== -1 && nl < end) {
457
+ if (nl !== -1) {
453
458
  // this is an error caused by an unexpected unindent
454
- end = nl - 1;
459
+ end = nl - (qb[nl - 1] === '\r' ? 2 : 1);
455
460
  }
456
461
  }
457
462
  if (end === -1) {
@@ -459,10 +464,10 @@ class Lexer {
459
464
  return this.setNext('quoted-scalar');
460
465
  end = this.buffer.length;
461
466
  }
462
- this.pushToIndex(end + 1, false);
467
+ yield* this.pushToIndex(end + 1, false);
463
468
  return this.flowLevel ? 'flow' : 'doc';
464
469
  }
465
- parseBlockScalarHeader() {
470
+ *parseBlockScalarHeader() {
466
471
  this.blockScalarIndent = -1;
467
472
  this.blockScalarKeep = false;
468
473
  let i = this.pos;
@@ -475,9 +480,9 @@ class Lexer {
475
480
  else if (ch !== '-')
476
481
  break;
477
482
  }
478
- return this.pushUntil(ch => isEmpty(ch) || ch === '#');
483
+ return yield* this.pushUntil(ch => isEmpty(ch) || ch === '#');
479
484
  }
480
- parseBlockScalar() {
485
+ *parseBlockScalar() {
481
486
  let nl = this.pos - 1; // may be -1 if this.pos === 0
482
487
  let indent = 0;
483
488
  let ch;
@@ -534,11 +539,11 @@ class Lexer {
534
539
  break;
535
540
  } while (true);
536
541
  }
537
- this.push(tokens.SCALAR);
538
- this.pushToIndex(nl + 1, true);
539
- return this.parseLineStart();
542
+ yield cst.SCALAR;
543
+ yield* this.pushToIndex(nl + 1, true);
544
+ return yield* this.parseLineStart();
540
545
  }
541
- parsePlainScalar() {
546
+ *parsePlainScalar() {
542
547
  const inFlow = this.flowLevel > 0;
543
548
  let end = this.pos - 1;
544
549
  let i = this.pos - 1;
@@ -551,17 +556,18 @@ class Lexer {
551
556
  end = i;
552
557
  }
553
558
  else if (isEmpty(ch)) {
554
- const next = this.buffer[i + 1];
555
- if (next === '#' || (inFlow && invalidFlowScalarChars.includes(next)))
556
- break;
559
+ let next = this.buffer[i + 1];
557
560
  if (ch === '\r') {
558
561
  if (next === '\n') {
559
562
  i += 1;
560
563
  ch = '\n';
564
+ next = this.buffer[i + 1];
561
565
  }
562
566
  else
563
567
  end = i;
564
568
  }
569
+ if (next === '#' || (inFlow && invalidFlowScalarChars.includes(next)))
570
+ break;
565
571
  if (ch === '\n') {
566
572
  const cs = this.continueScalar(i + 1);
567
573
  if (cs === -1)
@@ -577,69 +583,87 @@ class Lexer {
577
583
  }
578
584
  if (!ch && !this.atEnd)
579
585
  return this.setNext('plain-scalar');
580
- this.push(tokens.SCALAR);
581
- this.pushToIndex(end + 1, true);
586
+ yield cst.SCALAR;
587
+ yield* this.pushToIndex(end + 1, true);
582
588
  return inFlow ? 'flow' : 'doc';
583
589
  }
584
- pushCount(n) {
590
+ *pushCount(n) {
585
591
  if (n > 0) {
586
- this.push(this.buffer.substr(this.pos, n));
592
+ yield this.buffer.substr(this.pos, n);
587
593
  this.pos += n;
588
594
  return n;
589
595
  }
590
596
  return 0;
591
597
  }
592
- pushToIndex(i, allowEmpty) {
598
+ *pushToIndex(i, allowEmpty) {
593
599
  const s = this.buffer.slice(this.pos, i);
594
600
  if (s) {
595
- this.push(s);
601
+ yield s;
596
602
  this.pos += s.length;
597
603
  return s.length;
598
604
  }
599
605
  else if (allowEmpty)
600
- this.push('');
606
+ yield '';
601
607
  return 0;
602
608
  }
603
- pushIndicators() {
609
+ *pushIndicators() {
604
610
  switch (this.charAt(0)) {
605
611
  case '!':
606
- if (this.charAt(1) === '<')
607
- return (this.pushVerbatimTag() +
608
- this.pushSpaces(true) +
609
- this.pushIndicators());
610
- // fallthrough
612
+ return ((yield* this.pushTag()) +
613
+ (yield* this.pushSpaces(true)) +
614
+ (yield* this.pushIndicators()));
611
615
  case '&':
612
- return (this.pushUntil(isNotIdentifierChar) +
613
- this.pushSpaces(true) +
614
- this.pushIndicators());
616
+ return ((yield* this.pushUntil(isNotAnchorChar)) +
617
+ (yield* this.pushSpaces(true)) +
618
+ (yield* this.pushIndicators()));
615
619
  case ':':
616
620
  case '?': // this is an error outside flow collections
617
621
  case '-': // this is an error
618
622
  if (isEmpty(this.charAt(1))) {
619
623
  if (this.flowLevel === 0)
620
624
  this.indentNext = this.indentValue + 1;
621
- return (this.pushCount(1) + this.pushSpaces(true) + this.pushIndicators());
625
+ return ((yield* this.pushCount(1)) +
626
+ (yield* this.pushSpaces(true)) +
627
+ (yield* this.pushIndicators()));
622
628
  }
623
629
  }
624
630
  return 0;
625
631
  }
626
- pushVerbatimTag() {
627
- let i = this.pos + 2;
628
- let ch = this.buffer[i];
629
- while (!isEmpty(ch) && ch !== '>')
630
- ch = this.buffer[++i];
631
- return this.pushToIndex(ch === '>' ? i + 1 : i, false);
632
+ *pushTag() {
633
+ if (this.charAt(1) === '<') {
634
+ let i = this.pos + 2;
635
+ let ch = this.buffer[i];
636
+ while (!isEmpty(ch) && ch !== '>')
637
+ ch = this.buffer[++i];
638
+ return yield* this.pushToIndex(ch === '>' ? i + 1 : i, false);
639
+ }
640
+ else {
641
+ let i = this.pos + 1;
642
+ let ch = this.buffer[i];
643
+ while (ch) {
644
+ if (tagChars.includes(ch))
645
+ ch = this.buffer[++i];
646
+ else if (ch === '%' &&
647
+ hexDigits.includes(this.buffer[i + 1]) &&
648
+ hexDigits.includes(this.buffer[i + 2])) {
649
+ ch = this.buffer[(i += 3)];
650
+ }
651
+ else
652
+ break;
653
+ }
654
+ return yield* this.pushToIndex(i, false);
655
+ }
632
656
  }
633
- pushNewline() {
657
+ *pushNewline() {
634
658
  const ch = this.buffer[this.pos];
635
659
  if (ch === '\n')
636
- return this.pushCount(1);
660
+ return yield* this.pushCount(1);
637
661
  else if (ch === '\r' && this.charAt(1) === '\n')
638
- return this.pushCount(2);
662
+ return yield* this.pushCount(2);
639
663
  else
640
664
  return 0;
641
665
  }
642
- pushSpaces(allowTabs) {
666
+ *pushSpaces(allowTabs) {
643
667
  let i = this.pos - 1;
644
668
  let ch;
645
669
  do {
@@ -647,17 +671,17 @@ class Lexer {
647
671
  } while (ch === ' ' || (allowTabs && ch === '\t'));
648
672
  const n = i - this.pos;
649
673
  if (n > 0) {
650
- this.push(this.buffer.substr(this.pos, n));
674
+ yield this.buffer.substr(this.pos, n);
651
675
  this.pos = i;
652
676
  }
653
677
  return n;
654
678
  }
655
- pushUntil(test) {
679
+ *pushUntil(test) {
656
680
  let i = this.pos;
657
681
  let ch = this.buffer[i];
658
682
  while (!test(ch))
659
683
  ch = this.buffer[++i];
660
- return this.pushToIndex(i, false);
684
+ return yield* this.pushToIndex(i, false);
661
685
  }
662
686
  }
663
687
 
@@ -1,23 +1,32 @@
1
- import { Token } from './tokens.js';
1
+ import { Token } from './cst.js';
2
2
  /**
3
3
  * A YAML concrete syntax tree (CST) parser
4
4
  *
5
- * While the `parse()` method provides an API for parsing a source string
6
- * directly, the parser may also be used with a user-provided lexer:
7
- *
8
5
  * ```ts
9
- * const cst: Token[] = []
10
- * const parser = new Parser(tok => cst.push(tok))
11
6
  * const src: string = ...
7
+ * for (const token of new Parser().parse(src)) {
8
+ * // token: Token
9
+ * }
10
+ * ```
12
11
  *
13
- * // The following would be equivalent to `parser.parse(src, false)`
14
- * const lexer = new Lexer(parser.next)
15
- * lexer.lex(src, false)
16
- * parser.end()
12
+ * To use the parser with a user-provided lexer:
13
+ *
14
+ * ```ts
15
+ * function* parse(source: string, lexer: Lexer) {
16
+ * const parser = new Parser()
17
+ * for (const lexeme of lexer.lex(source))
18
+ * yield* parser.next(lexeme)
19
+ * yield* parser.end()
20
+ * }
21
+ *
22
+ * const src: string = ...
23
+ * const lexer = new Lexer()
24
+ * for (const token of parse(src, lexer)) {
25
+ * // token: Token
26
+ * }
17
27
  * ```
18
28
  */
19
29
  export declare class Parser {
20
- private push;
21
30
  private onNewLine?;
22
31
  /** If true, space and sequence indicators count as indentation */
23
32
  private atNewLine;
@@ -36,29 +45,26 @@ export declare class Parser {
36
45
  /** The type of the current token, set in parse() */
37
46
  private type;
38
47
  /**
39
- * @param push - Called separately with each parsed token
40
48
  * @param onNewLine - If defined, called separately with the start position of
41
49
  * each new line (in `parse()`, including the start of input).
42
- * @public
43
50
  */
44
- constructor(push: (token: Token) => void, onNewLine?: (offset: number) => void);
51
+ constructor(onNewLine?: (offset: number) => void);
45
52
  /**
46
- * Parse `source` as a YAML stream, calling `push` with each directive,
47
- * document and other structure as it is completely parsed. If `incomplete`,
48
- * a part of the last line may be left as a buffer for the next call.
53
+ * Parse `source` as a YAML stream.
54
+ * If `incomplete`, a part of the last line may be left as a buffer for the next call.
55
+ *
56
+ * Errors are not thrown, but yielded as `{ type: 'error', message }` tokens.
49
57
  *
50
- * Errors are not thrown, but pushed out as `{ type: 'error', message }` tokens.
51
- * @public
58
+ * @returns A generator of tokens representing each directive, document, and other structure.
52
59
  */
53
- parse(source: string, incomplete?: boolean): void;
60
+ parse(source: string, incomplete?: boolean): Generator<Token, void, unknown>;
54
61
  /**
55
- * Advance the parser by the `source` of one lexical token. Bound to the
56
- * Parser instance, so may be used directly as a callback function.
62
+ * Advance the parser by the `source` of one lexical token.
57
63
  */
58
- next: (source: string) => void;
64
+ next(source: string): Generator<Token, void, unknown>;
59
65
  private lexer;
60
66
  /** Call at end of input to push out any remaining constructions */
61
- end(): void;
67
+ end(): Generator<Token, void, unknown>;
62
68
  private get sourceToken();
63
69
  private step;
64
70
  private peek;
@@ -72,6 +78,7 @@ export declare class Parser {
72
78
  private flowCollection;
73
79
  private flowScalar;
74
80
  private startBlockValue;
81
+ private atIndentedComment;
75
82
  private documentEnd;
76
83
  private lineEnd;
77
84
  }