github.com/Azareal/Gosora@v0.0.0-20210729070923-553e66b59003/rev_templates.go (about) 1 //+lbuild experiment 2 3 // ! EXPERIMENTAL 4 package main 5 6 import ( 7 "errors" 8 "regexp" 9 ) 10 11 type Mango struct { 12 tagFinder *regexp.Regexp 13 } 14 15 func (m *Mango) Init() { 16 m.tagFinder = regexp.MustCompile(`(?s)\{\{(.*)\}\}`) 17 } 18 19 func (m *Mango) Parse(tmpl string) (out string, err error) { 20 tagIndices := m.tagFinder.FindAllStringIndex(tmpl, -1) 21 if len(tagIndices) > 0 { 22 if tagIndices[0][0] == 0 { 23 return "", errors.New("We don't support tags in the outermost layer yet") 24 } 25 var lastTag = 0 26 var lastID = 0 27 for _, tagIndex := range tagIndices { 28 var nestingLayer = 0 29 for i := tagIndex[0]; i > 0; i-- { 30 switch tmpl[i] { 31 case '>': 32 ii, closeTag, err := m.tasteTagToLeft(tmpl, i) 33 if err != nil { 34 return "", err 35 } 36 if closeTag { 37 nestingLayer++ 38 } else { 39 _, tagID := m.parseTag(tmpl, ii, i) 40 if tagID == "" { 41 out += tmpl[lastTag:ii] + m.injectID(ii, i) 42 lastID++ 43 } else { 44 out += tmpl[lastTag:i] 45 } 46 } 47 case '<': 48 49 } 50 } 51 } 52 } 53 return "", nil 54 } 55 56 func (m *Mango) injectID(start int, end int) string { 57 return "" 58 } 59 60 func (m *Mango) parseTag(tmpl string, start int, end int) (tagType string, tagID string) { 61 var i = start 62 for ; i < end; i++ { 63 if tmpl[i] == ' ' { 64 break 65 } 66 } 67 tagType = tmpl[start:i] 68 i = start 69 for ; i < (end - 4); i++ { 70 if tmpl[i] == ' ' && tmpl[i+1] == 'i' && tmpl[i+2] == 'd' && tmpl[i+3] == '=' { 71 tagID = m.extractAttributeContents(tmpl, i+4, end) 72 } 73 } 74 return tagType, tagID 75 } 76 77 func (m *Mango) extractAttributeContents(tmpl string, i int, end int) (contents string) { 78 var start = i 79 var quoteChar byte = 0 // nolint 80 if m.isHTMLQuoteChar(tmpl[i]) { 81 i++ 82 quoteChar = tmpl[i] 83 } 84 i += 3 85 for ; i < end; i++ { 86 if quoteChar != 0 { 87 if tmpl[i] == quoteChar { 88 break 89 } 90 } else if tmpl[i] == ' ' { 91 break 92 } 93 } 94 return tmpl[start:i] 95 } 96 97 func (m *Mango) isHTMLQuoteChar(char byte) bool { 98 return char == '\'' || char == '"' 99 } 100 101 func (m *Mango) tasteTagToLeft(tmpl string, index int) (indexOut int, closeTag bool, err error) { 102 var foundLeftBrace = false 103 for ; index > 0; index-- { 104 // What if the / isn't adjacent to the < but has a space instead? Is that even valid? 105 if index >= 1 && tmpl[index] == '/' && tmpl[index-1] == '<' { 106 closeTag = true 107 break 108 } else if tmpl[index] == '<' { 109 foundLeftBrace = true 110 } 111 } 112 if !foundLeftBrace { 113 return index, closeTag, errors.New("The left portion of the tag is missing") 114 } 115 return index, closeTag, nil 116 }