stream.js
1 import { Coroutine } from '@bablr/coroutine'; 2 import { 3 generatePrettyCSTML as agastGeneratePrettyCSTML, 4 generateCSTML as agastGenerateCSTML, 5 stringFromStream, 6 getStreamIterator, 7 StreamIterable, 8 } from '@bablr/agast-helpers/stream'; 9 import isString from 'iter-tools-es/methods/is-string'; 10 import emptyStack from '@iter-tools/imm-stack'; 11 import { DoctypeTag, OpenNodeTag, CloseNodeTag } from './symbols.js'; 12 13 import { unresolveLanguage } from './grammar.js'; 14 15 const { freeze } = Object; 16 17 function* __resolveTags(ctx, tags) { 18 const co = new Coroutine(getStreamIterator(tags)); 19 let languages = emptyStack; 20 21 for (;;) { 22 co.advance(); 23 24 if (co.current instanceof Promise) { 25 co.current = yield co.current; 26 } 27 28 if (co.done) break; 29 30 const tag = co.value; 31 32 if (tag.type === DoctypeTag) { 33 languages = languages.push(ctx.languages.get(tag.value.attributes.bablrLanguage)); 34 } 35 36 if (tag.type === CloseNodeTag) { 37 languages = languages.pop(); 38 } 39 40 if (tag.type === OpenNodeTag) { 41 if (isString(tag.value.language)) { 42 const currentLanguage = languages.value; 43 const nodeLanguageURL = tag.value.language; 44 const nodeLanguage = ctx.languages.get(nodeLanguageURL); 45 46 languages = languages.push(nodeLanguage); 47 48 yield freeze({ 49 type: OpenNodeTag, 50 value: freeze({ 51 ...tag.value, 52 language: unresolveLanguage(ctx, currentLanguage, nodeLanguageURL), 53 }), 54 }); 55 } else { 56 yield tag; 57 } 58 } else { 59 yield tag; 60 } 61 } 62 } 63 64 export const resolveTags = (ctx, tags) => { 65 return new StreamIterable(__resolveTags(ctx, tags)); 66 }; 67 68 export const generatePrettyCSTML = (tags, options = {}) => { 69 const { ctx } = options; 70 71 return agastGeneratePrettyCSTML(ctx ? resolveTags(ctx, tags) : tags, options); 72 }; 73 74 export const printPrettyCSTML = (tags, options = {}) => { 75 return stringFromStream(generatePrettyCSTML(tags, options)); 76 }; 77 78 export const generateCSTML = (tags, options = {}) => { 79 const { ctx } = options; 80 81 return agastGenerateCSTML(ctx ? resolveTags(ctx, tags) : tags, options); 82 }; 83 84 export const printCSTML = (tags, options = {}) => { 85 return stringFromStream(generateCSTML(tags, options)); 86 };