//+lbuild experiment // ! EXPERIMENTAL package main import ( "errors" "regexp" ) type Mango struct { tagFinder *regexp.Regexp } func (m *Mango) Init() { m.tagFinder = regexp.MustCompile(`(?s)\{\{(.*)\}\}`) } func (m *Mango) Parse(tmpl string) (out string, err error) { tagIndices := m.tagFinder.FindAllStringIndex(tmpl, -1) if len(tagIndices) > 0 { if tagIndices[0][0] == 0 { return "", errors.New("We don't support tags in the outermost layer yet") } var lastTag = 0 var lastID = 0 for _, tagIndex := range tagIndices { var nestingLayer = 0 for i := tagIndex[0]; i > 0; i-- { switch tmpl[i] { case '>': ii, closeTag, err := m.tasteTagToLeft(tmpl, i) if err != nil { return "", err } if closeTag { nestingLayer++ } else { _, tagID := m.parseTag(tmpl, ii, i) if tagID == "" { out += tmpl[lastTag:ii] + m.injectID(ii, i) lastID++ } else { out += tmpl[lastTag:i] } } case '<': } } } } return "", nil } func (m *Mango) injectID(start int, end int) string { return "" } func (m *Mango) parseTag(tmpl string, start int, end int) (tagType string, tagID string) { var i = start for ; i < end; i++ { if tmpl[i] == ' ' { break } } tagType = tmpl[start:i] i = start for ; i < (end - 4); i++ { if tmpl[i] == ' ' && tmpl[i+1] == 'i' && tmpl[i+2] == 'd' && tmpl[i+3] == '=' { tagID = m.extractAttributeContents(tmpl, i+4, end) } } return tagType, tagID } func (m *Mango) extractAttributeContents(tmpl string, i int, end int) (contents string) { var start = i var quoteChar byte = 0 // nolint if m.isHTMLQuoteChar(tmpl[i]) { i++ quoteChar = tmpl[i] } i += 3 for ; i < end; i++ { if quoteChar != 0 { if tmpl[i] == quoteChar { break } } else if tmpl[i] == ' ' { break } } return tmpl[start:i] } func (m *Mango) isHTMLQuoteChar(char byte) bool { return char == '\'' || char == '"' } func (m *Mango) tasteTagToLeft(tmpl string, index int) (indexOut int, closeTag bool, err error) { var foundLeftBrace = false for ; index > 0; index-- { // What if the / isn't adjacent to the < but has a space instead? Is that even valid? if index >= 1 && tmpl[index] == '/' && tmpl[index-1] == '<' { closeTag = true break } else if tmpl[index] == '<' { foundLeftBrace = true } } if !foundLeftBrace { return index, closeTag, errors.New("The left portion of the tag is missing") } return index, closeTag, nil }