enhanceable.js
1 import { bablr, Source, Context } from '@bablr/bablr-vm'; 2 import { createParseStrategy } from '@bablr/bablr-vm-strategy-parse'; 3 import { sourceFromQuasis } from '@bablr/helpers/source'; 4 import { evaluateReturnSync, getCooked, getRoot } from '@bablr/agast-helpers/tree'; 5 import { 6 buildBasicNodeMatcher, 7 buildOpenNodeMatcher, 8 buildPropertyMatcher, 9 } from '@bablr/helpers/builders'; 10 11 export { treeFromStreamSync, treeFromStreamAsync, streamFromTree } from '@bablr/agast-helpers/tree'; 12 13 export { Context }; 14 15 export function streamParse(language, matcher, sourceText, props, options = {}) { 16 const { enhancers = {} } = options; 17 18 const source = Source.from(sourceText); 19 20 const context = language instanceof Context ? language : Context.from(language); 21 22 let bablr_ = bablr; 23 let createParseStrategy_ = createParseStrategy; 24 25 if (enhancers.bablr) { 26 bablr_ = enhancers.bablr(bablr); 27 } 28 29 if (enhancers.createBablrStrategy) { 30 createParseStrategy_ = enhancers.createBablrStrategy(createParseStrategy); 31 } 32 33 return bablr_(context, source, createParseStrategy_(matcher, props), options); 34 } 35 36 export const buildEmbeddedTag = (context, defaultMatcher, props, options = {}) => { 37 const defaultTag = (quasis, ...expressions) => { 38 return evaluateReturnSync( 39 streamParse(context, defaultMatcher, sourceFromQuasis(quasis), props, { 40 ...options, 41 expressions, 42 }), 43 ); 44 }; 45 46 return new Proxy(defaultTag, { 47 apply(defaultTag, receiver, argsList) { 48 return defaultTag.apply(receiver, argsList); 49 }, 50 51 get(_, type) { 52 return (quasis, ...expressions) => { 53 const matcher = buildPropertyMatcher( 54 null, 55 buildBasicNodeMatcher( 56 buildOpenNodeMatcher( 57 {}, 58 getCooked( 59 getRoot(defaultMatcher).properties.nodeMatcher.node.properties.open.node.properties 60 .language.node.properties.content.node, 61 ), 62 type, 63 ), 64 ), 65 ); 66 67 return evaluateReturnSync( 68 streamParse(context, matcher, sourceFromQuasis(quasis), props, { 69 ...options, 70 expressions, 71 }), 72 ); 73 }; 74 }, 75 }); 76 }; 77 78 export const buildRawTag = (context, defaultMatcher, props, options = {}) => { 79 const embeddedTag = buildEmbeddedTag(context, defaultMatcher, props, options); 80 81 const defaultTag = (quasis, ...exprs) => { 82 return embeddedTag(quasis.raw, ...exprs); 83 }; 84 85 return new Proxy(defaultTag, { 86 apply(defaultTag, receiver, argsList) { 87 return defaultTag.apply(receiver, argsList); 88 }, 89 90 get(_, type) { 91 return (quasis, ...exprs) => { 92 return embeddedTag[type](quasis, ...exprs); 93 }; 94 }, 95 }); 96 }; 97 98 export const buildTag = buildRawTag;