github.com/qioalice/ekago/v3@v3.3.2-0.20221202205325-5c262d586ee4/ekastr/interpolation.go (about) 1 // Copyright © 2020. All rights reserved. 2 // Author: Ilya Stroy. 3 // Contacts: iyuryevich@pm.me, https://github.com/qioalice 4 // License: https://opensource.org/licenses/MIT 5 6 package ekastr 7 8 /* 9 10 */ 11 func Interpolate(s string, cbVerbFound, cbTextFound func(v string)) { 12 f1 := func(v []byte) { cbVerbFound(B2S(v)) } 13 f2 := func(v []byte) { cbTextFound(B2S(v)) } 14 Interpolateb(S2B(s), f1, f2) 15 } 16 17 /* 18 19 */ 20 func Interpolateb(p []byte, cbVerbFound, cbTextFound func(v []byte)) { 21 22 var ( 23 part []byte 24 isVerb bool 25 ) 26 27 if len(p) == 0 { 28 return 29 } 30 31 for len(p) > 0 { 32 part, p, isVerb = i9nGetNext(p) 33 if isVerb { 34 cbVerbFound(part) 35 } else { 36 cbTextFound(part) 37 } 38 } 39 } 40 41 /* 42 43 */ 44 // parseFirstVerb parses 'format', extracts first verb (even if it's "just text" 45 // verb), saves it to ce.formatParts and then returns the rest of 'format' string. 46 func i9nGetNext(p []byte) (part, nextP []byte, isVerb bool) { 47 48 if len(p) == 0 { 49 return nil, nil, false 50 } 51 52 //goland:noinspection GoSnakeCaseUsage 53 const ( 54 VERB_START_INDICATOR byte = '{' 55 VERB_END_INDICATOR byte = '}' 56 ) 57 58 var ( 59 i = 0 60 pc byte // prev char 61 wv bool // true if current parsing verb is complex verb (not "just text") 62 wve bool // true if complex verb has been closed correctly 63 ) 64 65 for _, c := range p { 66 switch { 67 case c == VERB_START_INDICATOR && pc == VERB_START_INDICATOR && wv: 68 // unexpected "{{" inside complex verb, treat all prev as "just text", 69 // try to treat as starting complex verb 70 wv = false 71 i-- 72 73 case c == VERB_START_INDICATOR && pc == VERB_START_INDICATOR && i > 1: 74 // > 1 (not > 0) because if string started with "{{", after first "{" 75 // i already == 1. 76 // 77 // was "just text", found complex verb start 78 i-- 79 80 case c == VERB_END_INDICATOR && pc == VERB_END_INDICATOR && wv: 81 // ending of complex verb 82 wve = true 83 i++ 84 85 case c == VERB_START_INDICATOR && pc == VERB_START_INDICATOR: 86 // this is the beginning of 'format' and of complex verb 87 wv = true 88 i++ 89 continue 90 91 default: 92 pc = c 93 i++ 94 continue 95 } 96 break 97 } 98 99 return p[:i], p[i:], wv && wve 100 }