@@ -8,16 +8,38 @@ import type {
8
8
HookInfo ,
9
9
PrimitiveType ,
10
10
Runtime ,
11
+ TaggedTemplateHandler ,
11
12
} from "./types.ts" ;
12
13
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
+
13
32
export class Interpreter implements Runtime {
14
33
_cache : Map < string , AstTemplate > = new Map ( ) ;
15
34
_decorator : ( source : PrimitiveType ) => unknown ;
35
+ _taggedTemplate : TaggedTemplateHandler ;
16
36
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 ,
20
40
} ) ;
41
+ this . _taggedTemplate = options . taggedTemplate ??
42
+ defaultTaggedTemplateHandler ;
21
43
}
22
44
23
45
execute ( text : string , parameters : FormatParameters ) : string {
@@ -31,38 +53,38 @@ export class Interpreter implements Runtime {
31
53
32
54
executeAst ( ast : AstTemplate , parameters : FormatParameters ) : string {
33
55
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 ] ;
37
60
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
+ }
59
83
}
60
- }
61
84
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
+ ) ;
66
88
}
67
89
}
68
90
0 commit comments