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  }