@bablr/agast-helpers 0.9.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/builders.js +148 -95
- package/lib/path.js +1303 -437
- package/lib/print.js +66 -43
- package/lib/shorthand.js +17 -13
- package/lib/stream.js +433 -32
- package/lib/symbols.js +3 -2
- package/lib/tags.js +106 -57
- package/lib/template.js +44 -42
- package/lib/tree.js +59 -513
- package/package.json +3 -3
- package/lib/path-facade.js +0 -44
package/lib/stream.js
CHANGED
|
@@ -1,23 +1,32 @@
|
|
|
1
1
|
import { Coroutine } from '@bablr/coroutine';
|
|
2
2
|
import emptyStack from '@iter-tools/imm-stack';
|
|
3
|
-
import { getStreamIterator, StreamIterable, StreamGenerator } from '@bablr/stream-iterator';
|
|
3
|
+
import { getStreamIterator, StreamIterable, StreamGenerator, wait } from '@bablr/stream-iterator';
|
|
4
|
+
import * as Tags from './tags.js';
|
|
4
5
|
import { printTag } from './print.js';
|
|
5
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
buildChild,
|
|
8
|
+
buildGapTag,
|
|
9
|
+
buildNullTag,
|
|
10
|
+
buildOpenNodeTag,
|
|
11
|
+
buildProperty,
|
|
12
|
+
buildReference,
|
|
13
|
+
} from './builders.js';
|
|
6
14
|
import {
|
|
7
15
|
OpenNodeTag,
|
|
8
16
|
CloseNodeTag,
|
|
9
17
|
ReferenceTag,
|
|
10
18
|
GapTag,
|
|
11
19
|
NullTag,
|
|
12
|
-
InitializerTag,
|
|
13
20
|
LiteralTag,
|
|
14
21
|
BindingTag,
|
|
15
22
|
DoctypeTag,
|
|
16
23
|
ShiftTag,
|
|
17
24
|
AttributeDefinition,
|
|
18
25
|
} from './symbols.js';
|
|
26
|
+
import { buildNode, isGapNode, Path } from './path.js';
|
|
27
|
+
import { streamFromTree } from './tree.js';
|
|
19
28
|
|
|
20
|
-
export { getStreamIterator, StreamIterable, StreamGenerator };
|
|
29
|
+
export { getStreamIterator, StreamIterable, StreamGenerator, wait };
|
|
21
30
|
|
|
22
31
|
export * from './print.js';
|
|
23
32
|
|
|
@@ -29,6 +38,120 @@ export const maybeWait = (maybePromise, callback) => {
|
|
|
29
38
|
}
|
|
30
39
|
};
|
|
31
40
|
|
|
41
|
+
function* __flatMap(fn, tags) {
|
|
42
|
+
const co = new Coroutine(getStreamIterator(tags));
|
|
43
|
+
|
|
44
|
+
for (;;) {
|
|
45
|
+
co.advance();
|
|
46
|
+
|
|
47
|
+
if (co.current instanceof Promise) {
|
|
48
|
+
co.current = yield wait(co.current);
|
|
49
|
+
}
|
|
50
|
+
if (co.done) break;
|
|
51
|
+
|
|
52
|
+
let { value } = co;
|
|
53
|
+
|
|
54
|
+
yield* fn(value);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export const flatMap = (fn, tags) => new StreamIterable(__flatMap(fn, tags));
|
|
61
|
+
|
|
62
|
+
export const evaluateReturnSync = (iterable) => {
|
|
63
|
+
const co = new Coroutine(iterable[Symbol.iterator]());
|
|
64
|
+
while (!co.done) co.advance();
|
|
65
|
+
return co.value;
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
export const evaluateReturnAsync = async (iterable) => {
|
|
69
|
+
const co = new Coroutine(getStreamIterator(iterable));
|
|
70
|
+
while (!co.done) {
|
|
71
|
+
co.advance();
|
|
72
|
+
|
|
73
|
+
if (co.current instanceof Promise) {
|
|
74
|
+
co.current = await co.current;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return co.value;
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
function* __treeFromStream(tags, options) {
|
|
81
|
+
let path = null;
|
|
82
|
+
const co = new Coroutine(getStreamIterator(tags));
|
|
83
|
+
const expressionsCo = new Coroutine(getStreamIterator(options.expressions || []));
|
|
84
|
+
|
|
85
|
+
for (;;) {
|
|
86
|
+
co.advance();
|
|
87
|
+
|
|
88
|
+
if (co.current instanceof Promise) {
|
|
89
|
+
co.current = yield wait(co.current);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (co.done) break;
|
|
93
|
+
|
|
94
|
+
let tag = co.value;
|
|
95
|
+
|
|
96
|
+
if (tag.type === 'Effect' || tag.type === DoctypeTag) {
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (!path) {
|
|
101
|
+
path = Path.from(buildNode(Tags.fromValues([tag])));
|
|
102
|
+
|
|
103
|
+
// if (tag.value.selfClosing) {
|
|
104
|
+
// path = null;
|
|
105
|
+
// }
|
|
106
|
+
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (tag.type === GapTag && !path.held) {
|
|
111
|
+
if (!expressionsCo.current || !expressionsCo.done) {
|
|
112
|
+
expressionsCo.advance();
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if (path.node.value.flags.token) {
|
|
116
|
+
if (expressionsCo.done || expressionsCo.value != null) {
|
|
117
|
+
let node = expressionsCo.value;
|
|
118
|
+
if (isGapNode(node)) {
|
|
119
|
+
throw new Error('not implemented');
|
|
120
|
+
} else {
|
|
121
|
+
path = path.advance(tag);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
} else {
|
|
125
|
+
let node = expressionsCo.done
|
|
126
|
+
? buildNode(buildGapTag())
|
|
127
|
+
: path == null || expressionsCo.value == null
|
|
128
|
+
? buildNode(buildNullTag())
|
|
129
|
+
: expressionsCo.value;
|
|
130
|
+
|
|
131
|
+
path = path.advance(node);
|
|
132
|
+
}
|
|
133
|
+
} else {
|
|
134
|
+
path = path.advance(tag);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (!path.done) {
|
|
139
|
+
throw new Error('imbalanced tag stack');
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
return path?.node;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export const treeFromStream = (tags, options = {}) => __treeFromStream(tags, options);
|
|
146
|
+
|
|
147
|
+
export const treeFromStreamSync = (tokens, options = {}) => {
|
|
148
|
+
return evaluateReturnSync(treeFromStream(tokens, options));
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
export const treeFromStreamAsync = async (tokens, options = {}) => {
|
|
152
|
+
return evaluateReturnAsync(treeFromStream(tokens, options));
|
|
153
|
+
};
|
|
154
|
+
|
|
32
155
|
function* __isEmpty(tags) {
|
|
33
156
|
const co = new Coroutine(getStreamIterator(tags));
|
|
34
157
|
|
|
@@ -36,7 +159,7 @@ function* __isEmpty(tags) {
|
|
|
36
159
|
co.advance();
|
|
37
160
|
|
|
38
161
|
if (co.current instanceof Promise) {
|
|
39
|
-
co.current = yield co.current;
|
|
162
|
+
co.current = yield wait(co.current);
|
|
40
163
|
}
|
|
41
164
|
if (co.done) break;
|
|
42
165
|
|
|
@@ -55,7 +178,7 @@ function* __isEmpty(tags) {
|
|
|
55
178
|
|
|
56
179
|
if (tag.value.literalValue) return false;
|
|
57
180
|
|
|
58
|
-
if (depth === 0 && ref.
|
|
181
|
+
if (depth === 0 && ref.type === '@') {
|
|
59
182
|
return false;
|
|
60
183
|
}
|
|
61
184
|
|
|
@@ -137,7 +260,7 @@ function* __generateCSTML(tags, options) {
|
|
|
137
260
|
co.advance();
|
|
138
261
|
|
|
139
262
|
if (co.current instanceof Promise) {
|
|
140
|
-
co.current = yield co.current;
|
|
263
|
+
co.current = yield wait(co.current);
|
|
141
264
|
}
|
|
142
265
|
if (co.done) break;
|
|
143
266
|
|
|
@@ -155,8 +278,6 @@ function* __generateCSTML(tags, options) {
|
|
|
155
278
|
|
|
156
279
|
prevTag = tag;
|
|
157
280
|
}
|
|
158
|
-
|
|
159
|
-
yield* '\n';
|
|
160
281
|
}
|
|
161
282
|
|
|
162
283
|
export const generateCSTML = (tags, options = {}) =>
|
|
@@ -174,24 +295,18 @@ function* __prettyGroupTags(tags) {
|
|
|
174
295
|
|
|
175
296
|
const co = new Coroutine(getStreamIterator(tags));
|
|
176
297
|
|
|
177
|
-
let ref = null;
|
|
178
|
-
|
|
179
298
|
for (;;) {
|
|
180
299
|
co.advance();
|
|
181
300
|
|
|
182
|
-
if (co.done) break;
|
|
183
|
-
|
|
184
301
|
if (co.current instanceof Promise) {
|
|
185
|
-
co.current = yield co.current;
|
|
302
|
+
co.current = yield wait(co.current);
|
|
186
303
|
}
|
|
187
304
|
|
|
305
|
+
if (co.done) break;
|
|
306
|
+
|
|
188
307
|
const tag = co.value;
|
|
189
308
|
const isOpenClose = tag.type === CloseNodeTag || tag.type === OpenNodeTag;
|
|
190
309
|
|
|
191
|
-
if (tag.type === ReferenceTag) {
|
|
192
|
-
ref = tag;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
310
|
if (
|
|
196
311
|
(tag.type === 'Effect' && tag.value.verb === 'write') ||
|
|
197
312
|
[
|
|
@@ -200,11 +315,10 @@ function* __prettyGroupTags(tags) {
|
|
|
200
315
|
BindingTag,
|
|
201
316
|
GapTag,
|
|
202
317
|
NullTag,
|
|
203
|
-
InitializerTag,
|
|
204
318
|
ShiftTag,
|
|
205
319
|
AttributeDefinition,
|
|
206
|
-
|
|
207
|
-
|
|
320
|
+
OpenNodeTag,
|
|
321
|
+
].includes(tag.type)
|
|
208
322
|
) {
|
|
209
323
|
state.broken = true;
|
|
210
324
|
|
|
@@ -222,14 +336,14 @@ function* __prettyGroupTags(tags) {
|
|
|
222
336
|
|
|
223
337
|
if (tag.type === CloseNodeTag) {
|
|
224
338
|
if (!state.broken && (isToken(state.open) || state.holding.length === 1)) {
|
|
225
|
-
let { flags,
|
|
339
|
+
let { flags, name, attributes } = state.holding[0].value;
|
|
226
340
|
|
|
227
341
|
let literal = state.holding
|
|
228
342
|
.slice(1)
|
|
229
343
|
.map((lit) => lit.value)
|
|
230
344
|
.join('');
|
|
231
345
|
|
|
232
|
-
yield buildOpenNodeTag(flags,
|
|
346
|
+
yield buildOpenNodeTag(flags, name, literal, attributes, true);
|
|
233
347
|
} else {
|
|
234
348
|
if (state.holding.length) {
|
|
235
349
|
yield* state.holding;
|
|
@@ -242,7 +356,7 @@ function* __prettyGroupTags(tags) {
|
|
|
242
356
|
}
|
|
243
357
|
|
|
244
358
|
if (tag.type === OpenNodeTag) {
|
|
245
|
-
if (tag.value.
|
|
359
|
+
if (tag.value.selfClosing) {
|
|
246
360
|
yield tag;
|
|
247
361
|
} else {
|
|
248
362
|
states = states.push({ holding: [tag], broken: false, open: tag });
|
|
@@ -253,6 +367,293 @@ function* __prettyGroupTags(tags) {
|
|
|
253
367
|
}
|
|
254
368
|
}
|
|
255
369
|
|
|
370
|
+
let pushFrame = (parent = null) => {
|
|
371
|
+
let heldProperties = parent ? [...parent.heldProperties] : [];
|
|
372
|
+
if (parent) {
|
|
373
|
+
parent.heldProperties = [];
|
|
374
|
+
}
|
|
375
|
+
return {
|
|
376
|
+
parent,
|
|
377
|
+
depth: !parent ? 0 : parent.depth + 1,
|
|
378
|
+
ref: null,
|
|
379
|
+
bindings: [],
|
|
380
|
+
open: null,
|
|
381
|
+
coverDepth: 0,
|
|
382
|
+
heldProperties,
|
|
383
|
+
expanded: false,
|
|
384
|
+
shifting: parent?.shifting || false,
|
|
385
|
+
};
|
|
386
|
+
};
|
|
387
|
+
|
|
388
|
+
let popFrame = (frame) => {
|
|
389
|
+
let { heldProperties } = frame;
|
|
390
|
+
|
|
391
|
+
if (frame.parent) {
|
|
392
|
+
frame.parent.heldProperties = heldProperties;
|
|
393
|
+
frame.parent.shifting = frame.shifting;
|
|
394
|
+
} else if (heldProperties.length) {
|
|
395
|
+
throw new Error();
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
return frame.parent;
|
|
399
|
+
};
|
|
400
|
+
|
|
401
|
+
function* emitHeld(frame, nextTag) {
|
|
402
|
+
if (frame.ref?.flags.expression && nextTag?.type === ShiftTag) return;
|
|
403
|
+
|
|
404
|
+
for (let property of frame.heldProperties) {
|
|
405
|
+
let { reference, bindings, node } = property;
|
|
406
|
+
yield buildChild(ReferenceTag, reference);
|
|
407
|
+
let isAnonymous = node.value.flags.token && !node.value.name;
|
|
408
|
+
if (!isAnonymous) {
|
|
409
|
+
for (let binding of bindings) {
|
|
410
|
+
yield buildChild(BindingTag, binding);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
yield* streamFromTree(node);
|
|
414
|
+
}
|
|
415
|
+
frame.heldProperties = [];
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
export const hoistTrivia = (tags) => {
|
|
419
|
+
const co = new Coroutine(getStreamIterator(tags));
|
|
420
|
+
|
|
421
|
+
return new StreamIterable(__hoistTriviaOuter(co));
|
|
422
|
+
};
|
|
423
|
+
|
|
424
|
+
function* __hoistTriviaOuter(co) {
|
|
425
|
+
co.advance();
|
|
426
|
+
|
|
427
|
+
let firstTag = co.value;
|
|
428
|
+
|
|
429
|
+
co.advance();
|
|
430
|
+
|
|
431
|
+
yield* __hoistTrivia(co, firstTag);
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
function* __hoistTrivia(co, firstTag) {
|
|
435
|
+
if (co.current instanceof Promise) {
|
|
436
|
+
co.current = yield wait(co.current);
|
|
437
|
+
}
|
|
438
|
+
let frame = null;
|
|
439
|
+
let lastFrame = null;
|
|
440
|
+
let alreadyAdvanced = true;
|
|
441
|
+
let tag;
|
|
442
|
+
let nextTag;
|
|
443
|
+
|
|
444
|
+
tag = firstTag;
|
|
445
|
+
nextTag = co.value;
|
|
446
|
+
|
|
447
|
+
for (;;) {
|
|
448
|
+
if (co.done || !nextTag) break;
|
|
449
|
+
|
|
450
|
+
if (!alreadyAdvanced) {
|
|
451
|
+
co.advance();
|
|
452
|
+
|
|
453
|
+
if (co.current instanceof Promise) {
|
|
454
|
+
co.current = yield wait(co.current);
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
alreadyAdvanced = false;
|
|
458
|
+
|
|
459
|
+
nextTag = co.value;
|
|
460
|
+
|
|
461
|
+
if (tag.type === OpenNodeTag) {
|
|
462
|
+
let isCover = tag.value.type === Symbol.for('_');
|
|
463
|
+
let parentFrame = frame?.ref && !frame.open ? frame.parent : frame;
|
|
464
|
+
let done = false;
|
|
465
|
+
|
|
466
|
+
if (frame?.ref.type === '#' && !frame.ref.name) {
|
|
467
|
+
let { heldProperties } = frame;
|
|
468
|
+
if (heldProperties.length) {
|
|
469
|
+
let property = heldProperties[heldProperties.length - 1];
|
|
470
|
+
|
|
471
|
+
if (property.node) {
|
|
472
|
+
throw new Error();
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
let node = yield* treeFromStream(new StreamIterable(__hoistTrivia(co, tag)));
|
|
476
|
+
|
|
477
|
+
frame.heldProperties[heldProperties.length - 1] = buildProperty([
|
|
478
|
+
property.tags[0],
|
|
479
|
+
property.tags[1] || [],
|
|
480
|
+
node,
|
|
481
|
+
]);
|
|
482
|
+
|
|
483
|
+
nextTag = co.value;
|
|
484
|
+
|
|
485
|
+
lastFrame = frame;
|
|
486
|
+
|
|
487
|
+
frame = popFrame(frame);
|
|
488
|
+
|
|
489
|
+
if (
|
|
490
|
+
!frame.ref.flags.expression &&
|
|
491
|
+
(frame.expanded || frame.parent?.open.value.type !== Symbol.for('_'))
|
|
492
|
+
) {
|
|
493
|
+
yield* emitHeld(frame, nextTag);
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
done = true;
|
|
497
|
+
}
|
|
498
|
+
} else if (frame && !isCover) {
|
|
499
|
+
if (!frame.shifting && frame.ref && frame.ref.type !== '_') {
|
|
500
|
+
yield buildChild(ReferenceTag, frame.ref);
|
|
501
|
+
let isAnonymous = tag.value.flags.token && !tag.value.name;
|
|
502
|
+
if (!isAnonymous) {
|
|
503
|
+
for (let binding of frame.bindings) {
|
|
504
|
+
yield buildChild(BindingTag, binding);
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
if (!done) {
|
|
511
|
+
if (!frame?.ref || frame.open) {
|
|
512
|
+
frame = pushFrame(parentFrame);
|
|
513
|
+
|
|
514
|
+
frame.heldProperties = parentFrame?.heldProperties ? [...parentFrame.heldProperties] : [];
|
|
515
|
+
|
|
516
|
+
if (tag.value.type === Symbol.for('__')) {
|
|
517
|
+
frame.open = tag;
|
|
518
|
+
frame.ref = buildReference();
|
|
519
|
+
} else if (isCover) {
|
|
520
|
+
frame.ref = parentFrame?.ref || buildReference('_');
|
|
521
|
+
frame.bindings =
|
|
522
|
+
parentFrame && tag.value.type === Symbol.for('_') ? [...parentFrame.bindings] : [];
|
|
523
|
+
frame.shifting =
|
|
524
|
+
parentFrame && tag.value.type === Symbol.for('_') ? parentFrame.shifting : false;
|
|
525
|
+
} else {
|
|
526
|
+
frame.ref = buildReference();
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
frame.coverDepth = isCover ? (parentFrame?.coverDepth ?? 0) + 1 : 0;
|
|
531
|
+
|
|
532
|
+
frame.open = tag;
|
|
533
|
+
|
|
534
|
+
if (tag.value.selfClosing) {
|
|
535
|
+
lastFrame = frame;
|
|
536
|
+
|
|
537
|
+
frame = popFrame(frame);
|
|
538
|
+
|
|
539
|
+
if (!frame) {
|
|
540
|
+
yield tag;
|
|
541
|
+
|
|
542
|
+
break;
|
|
543
|
+
} else {
|
|
544
|
+
yield tag;
|
|
545
|
+
}
|
|
546
|
+
} else {
|
|
547
|
+
if (!isCover) {
|
|
548
|
+
yield tag;
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
} else if (tag.type === ReferenceTag) {
|
|
553
|
+
let parentFrame = frame;
|
|
554
|
+
|
|
555
|
+
frame = pushFrame(parentFrame);
|
|
556
|
+
|
|
557
|
+
if (tag.value.type === '#' && !tag.value.name) {
|
|
558
|
+
if (parentFrame.depth === 0 && parentFrame.coverDepth && !parentFrame.expanded) {
|
|
559
|
+
yield parentFrame.open;
|
|
560
|
+
|
|
561
|
+
parentFrame.expanded = true;
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
frame.heldProperties.push(buildProperty([tag]));
|
|
565
|
+
} else {
|
|
566
|
+
if (!parentFrame.shifting) {
|
|
567
|
+
yield* emitHeld(frame, nextTag);
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
frame.coverDepth = parentFrame.coverDepth;
|
|
572
|
+
frame.ref = tag.value.type === '_' ? parentFrame.ref : tag.value;
|
|
573
|
+
frame.bindings = parentFrame && tag.value.type === '_' ? [...parentFrame.bindings] : [];
|
|
574
|
+
frame.shifting = parentFrame && tag.value.type === '_' ? parentFrame.shifting : false;
|
|
575
|
+
|
|
576
|
+
if (tag.value.type === '_' && parentFrame.expanded) {
|
|
577
|
+
yield tag;
|
|
578
|
+
}
|
|
579
|
+
} else if (tag.type === ShiftTag) {
|
|
580
|
+
let doneFrame = frame;
|
|
581
|
+
|
|
582
|
+
frame = pushFrame(doneFrame);
|
|
583
|
+
|
|
584
|
+
frame.coverDepth = doneFrame?.coverDepth || 0;
|
|
585
|
+
frame.ref = lastFrame.ref;
|
|
586
|
+
frame.bindings = doneFrame && tag.value.type === '_' ? [...doneFrame.bindings] : [];
|
|
587
|
+
frame.shifting = true;
|
|
588
|
+
// frame.heldProperties = [...doneFrame.heldProperties];
|
|
589
|
+
|
|
590
|
+
yield tag;
|
|
591
|
+
} else if (tag.type === BindingTag) {
|
|
592
|
+
let { heldProperties } = frame;
|
|
593
|
+
if (heldProperties.length) {
|
|
594
|
+
let property = heldProperties[heldProperties.length - 1];
|
|
595
|
+
let { tags, node } = property;
|
|
596
|
+
if (!node) {
|
|
597
|
+
heldProperties[heldProperties.length - 1] = buildProperty([
|
|
598
|
+
tags[0],
|
|
599
|
+
[...(tags[1] || []), tag],
|
|
600
|
+
]);
|
|
601
|
+
frame.bindings.push(tag.value);
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
if (!frame.ref) {
|
|
605
|
+
frame = pushFrame(frame);
|
|
606
|
+
frame.ref = buildReference();
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
frame.bindings.push(tag.value);
|
|
610
|
+
} else if (tag.type === CloseNodeTag) {
|
|
611
|
+
lastFrame = frame;
|
|
612
|
+
|
|
613
|
+
if (!lastFrame.open.value.type || !lastFrame.parent) {
|
|
614
|
+
yield* emitHeld(lastFrame, nextTag);
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
frame = popFrame(frame);
|
|
618
|
+
|
|
619
|
+
if (frame) {
|
|
620
|
+
frame.heldProperties = [...lastFrame.heldProperties];
|
|
621
|
+
if (!lastFrame?.coverDepth) {
|
|
622
|
+
yield tag;
|
|
623
|
+
}
|
|
624
|
+
} else {
|
|
625
|
+
if (lastFrame.expanded || lastFrame.open.value.type !== Symbol.for('_')) {
|
|
626
|
+
yield tag;
|
|
627
|
+
}
|
|
628
|
+
break;
|
|
629
|
+
}
|
|
630
|
+
} else if (tag.type === GapTag || tag.type === NullTag) {
|
|
631
|
+
if (frame.ref) {
|
|
632
|
+
yield buildChild(ReferenceTag, frame.ref);
|
|
633
|
+
}
|
|
634
|
+
lastFrame = frame;
|
|
635
|
+
|
|
636
|
+
frame = popFrame(frame);
|
|
637
|
+
|
|
638
|
+
if (tag.type === GapTag && frame.heldProperties.length) {
|
|
639
|
+
yield tag;
|
|
640
|
+
|
|
641
|
+
frame.shifting = false;
|
|
642
|
+
|
|
643
|
+
yield* emitHeld(frame, nextTag);
|
|
644
|
+
} else {
|
|
645
|
+
yield tag;
|
|
646
|
+
}
|
|
647
|
+
} else {
|
|
648
|
+
yield tag;
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
tag = nextTag;
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
if (frame) throw new Error();
|
|
655
|
+
}
|
|
656
|
+
|
|
256
657
|
function* __generatePrettyCSTML(tags, options) {
|
|
257
658
|
let { indent = ' ', inline: inlineOption = true } = options;
|
|
258
659
|
|
|
@@ -261,7 +662,8 @@ function* __generatePrettyCSTML(tags, options) {
|
|
|
261
662
|
return;
|
|
262
663
|
}
|
|
263
664
|
|
|
264
|
-
const co = new Coroutine(getStreamIterator(prettyGroupTags(tags)));
|
|
665
|
+
const co = new Coroutine(getStreamIterator(prettyGroupTags(hoistTrivia(tags))));
|
|
666
|
+
// const co = new Coroutine(getStreamIterator(prettyGroupTags(tags)));
|
|
265
667
|
let indentLevel = 0;
|
|
266
668
|
let first = true;
|
|
267
669
|
let inline = false;
|
|
@@ -270,19 +672,19 @@ function* __generatePrettyCSTML(tags, options) {
|
|
|
270
672
|
for (;;) {
|
|
271
673
|
co.advance();
|
|
272
674
|
|
|
273
|
-
if (co.done) break;
|
|
274
|
-
|
|
275
675
|
if (co.current instanceof Promise) {
|
|
276
|
-
co.current = yield co.current;
|
|
676
|
+
co.current = yield wait(co.current);
|
|
277
677
|
}
|
|
278
678
|
|
|
679
|
+
if (co.done) break;
|
|
680
|
+
|
|
279
681
|
const tag = co.value;
|
|
280
682
|
|
|
281
683
|
if (tag.type === 'Effect') {
|
|
282
684
|
continue;
|
|
283
685
|
}
|
|
284
686
|
|
|
285
|
-
if (tag.type === BindingTag && !tag.value.
|
|
687
|
+
if (tag.type === BindingTag && !tag.value.segments?.length) {
|
|
286
688
|
continue;
|
|
287
689
|
}
|
|
288
690
|
|
|
@@ -293,7 +695,6 @@ function* __generatePrettyCSTML(tags, options) {
|
|
|
293
695
|
(tag.type === NullTag ||
|
|
294
696
|
tag.type === GapTag ||
|
|
295
697
|
tag.type === BindingTag ||
|
|
296
|
-
tag.type === InitializerTag ||
|
|
297
698
|
(tag.type === OpenNodeTag && tag.value.selfClosing));
|
|
298
699
|
|
|
299
700
|
if (!first && !inline) {
|
|
@@ -374,11 +775,11 @@ export const getCooked = (tags) => {
|
|
|
374
775
|
}
|
|
375
776
|
}
|
|
376
777
|
|
|
377
|
-
if (!(ref.
|
|
778
|
+
if (!(ref.type === '#' || (ref.type === '@' && attributes.cooked))) {
|
|
378
779
|
throw new Error('cookable nodes must not contain other nodes');
|
|
379
780
|
}
|
|
380
781
|
|
|
381
|
-
if (ref.
|
|
782
|
+
if (ref.type === '@') {
|
|
382
783
|
const { cooked: cookedValue } = tag.value.attributes;
|
|
383
784
|
|
|
384
785
|
if (!cookedValue) throw new Error('cannot cook string: it contains uncooked escapes');
|
package/lib/symbols.js
CHANGED
|
@@ -6,12 +6,13 @@ export const ShiftTag = Symbol.for('ShiftTag');
|
|
|
6
6
|
export const GapTag = Symbol.for('GapTag');
|
|
7
7
|
export const BindingTag = Symbol.for('BindingTag');
|
|
8
8
|
export const NullTag = Symbol.for('NullTag');
|
|
9
|
-
export const InitializerTag = Symbol.for('InitializerTag');
|
|
10
9
|
export const AttributeDefinition = Symbol.for('AttributeDefinition');
|
|
11
10
|
export const LiteralTag = Symbol.for('LiteralTag');
|
|
12
11
|
|
|
13
12
|
export const Document = Symbol.for('Document');
|
|
13
|
+
export const TreeNode = Symbol.for('TreeNode');
|
|
14
|
+
export const NullNode = Symbol.for('NullNode');
|
|
15
|
+
export const GapNode = Symbol.for('GapNode');
|
|
14
16
|
export const Node = Symbol.for('Node');
|
|
15
17
|
|
|
16
18
|
export const Property = Symbol.for('Property');
|
|
17
|
-
export const PropertyWrapper = Symbol.for('PropertyWrapper');
|