@@ -8,16 +8,38 @@ import type {
88 HookInfo ,
99 PrimitiveType ,
1010 Runtime ,
11+ TaggedTemplateHandler ,
1112} from "./types.ts" ;
1213
14+ export interface InterpreterOptions {
15+ locale ?: string | null ;
16+ hooks ?: Record < string , Hook > ;
17+ taggedTemplate ?: TaggedTemplateHandler ;
18+ }
19+
20+ function defaultTaggedTemplateHandler (
21+ strings : TemplateStringsArray ,
22+ ...args : unknown [ ]
23+ ) : string {
24+ return strings . reduce ( ( carry , string , index ) => {
25+ if ( index > 0 ) {
26+ carry += args [ index - 1 ] ;
27+ }
28+ return carry + string ;
29+ } ) ;
30+ }
31+
1332export class Interpreter implements Runtime {
1433 _cache : Map < string , AstTemplate > = new Map ( ) ;
1534 _decorator : ( source : PrimitiveType ) => unknown ;
35+ _taggedTemplate : TaggedTemplateHandler ;
1636
17- constructor ( hooks : Record < string , Hook > , locale ?: string | null ) {
18- this . _decorator = createDecorator ( hooks , {
19- locale : locale ?? null ,
37+ constructor ( options : InterpreterOptions = { } ) {
38+ this . _decorator = createDecorator ( options . hooks ?? { } , {
39+ locale : options . locale ?? null ,
2040 } ) ;
41+ this . _taggedTemplate = options . taggedTemplate ??
42+ defaultTaggedTemplateHandler ;
2143 }
2244
2345 execute ( text : string , parameters : FormatParameters ) : string {
@@ -31,38 +53,38 @@ export class Interpreter implements Runtime {
3153
3254 executeAst ( ast : AstTemplate , parameters : FormatParameters ) : string {
3355 const [ strings , values ] = ast ;
34- let result = strings [ 0 ] ?? "" ;
35- values . forEach ( ( [ valueName , methods ] , valueIndex ) => {
36- const self = parameters [ valueName ] ;
56+ return this . _taggedTemplate (
57+ Object . assign ( strings , { raw : strings } ) ,
58+ ...values . map ( ( [ valueName , methods ] ) => {
59+ const self = parameters [ valueName ] ;
3760
38- let value = this . _decorator ( self ) ;
39- for ( const [ methodName , methodArgs ] of methods ) {
40- const method = getSafeMethod ( value , methodName ) ;
41- if ( method ) {
42- value = method (
43- ...methodArgs . map ( ( methodArg ) => {
44- switch ( methodArg [ 0 ] ) {
45- case 2 :
46- return methodArg [ 1 ] ;
47- case 3 :
48- return methodArg [ 1 ] ;
49- case 4 :
50- return ( ) =>
51- this . executeAst ( methodArg [ 1 ] , { _ : self , ...parameters } ) ;
52- default :
53- throw new Error (
54- `Unknown method argument type: ${ methodArg [ 0 ] } ` ,
55- ) ;
56- }
57- } ) ,
58- ) ;
61+ let value = this . _decorator ( self ) ;
62+ for ( const [ methodName , methodArgs ] of methods ) {
63+ const method = getSafeMethod ( value , methodName ) ;
64+ if ( method ) {
65+ value = method (
66+ ...methodArgs . map ( ( methodArg ) => {
67+ switch ( methodArg [ 0 ] ) {
68+ case 2 :
69+ return methodArg [ 1 ] ;
70+ case 3 :
71+ return methodArg [ 1 ] ;
72+ case 4 :
73+ return ( ) =>
74+ this . executeAst ( methodArg [ 1 ] , { _ : self , ...parameters } ) ;
75+ default :
76+ throw new Error (
77+ `Unknown method argument type: ${ methodArg [ 0 ] } ` ,
78+ ) ;
79+ }
80+ } ) ,
81+ ) ;
82+ }
5983 }
60- }
6184
62- result += value && value . toString ? value . toString ( ) : ( value ?? "" ) ;
63- result += strings [ valueIndex + 1 ] ?? "" ;
64- } ) ;
65- return result ;
85+ return value && value . toString ? value . toString ( ) : ( value ?? "" ) ;
86+ } ) ,
87+ ) ;
6688 }
6789}
6890
0 commit comments