package gopp import ( "bytes" "context" "io" ) type Parsed struct { Texts [][]byte PreCode []byte Codes [][]byte } type Preprocessor struct { xgo *XGo tags [2][]byte preTag byte } // Get the new preprocessor with default options. func New(xgo *XGo) *Preprocessor { pp := &Preprocessor{} pp.xgo = xgo pp.tags = [2][]byte{ []byte("{{"), []byte("}}"), } pp.preTag = '#' return pp } func (pp *Preprocessor) XGo() *XGo { return pp.xgo } func (pp *Preprocessor) Parse( ctx context.Context, input io.Reader, ) (*Parsed, error) { data, err := io.ReadAll(input) if err != nil { return nil, err } //var b bytes.Buffer preCode := []byte(nil) texts := [][]byte{} codes := [][]byte{} pref := append(pp.tags[0], pp.preTag) if bytes.HasPrefix(data, pref) { idxEnd := bytes.Index(data, pp.tags[1]) if idxEnd < 0 { return nil, UnexpectedError{ What: "pre-code start tag", } } preCode = data[len(pref):idxEnd] //texts = append(texts, []byte{}) data = data[idxEnd+len(pp.tags[1]):] } for { idxStart := bytes.Index(data, pp.tags[0]) idxEnd := bytes.Index(data, pp.tags[1]) //fmt.Printf("cock %d %d %d\n", last, idxStart, idxEnd) if idxStart < 0 { if idxEnd >= 0 { return nil, UnexpectedError{ What: "end tag", } } texts = append(texts, data) break } else if idxEnd < 0 { return nil, UnexpectedError{ What: "start tag", } } text := data[:idxStart] texts = append(texts, text) code := data[idxStart+len(pp.tags[0]):idxEnd] codes = append(codes, code) data = data[idxEnd + len(pp.tags[1]):] } return &Parsed{ Texts: texts, PreCode: preCode, Codes: codes, }, nil } func (pp *Preprocessor) Render( ctx context.Context, input io.Reader, output io.Writer, ) error { parsed, err := pp.Parse(ctx, input) if err != nil { return err } return pp.xgo.Render(ctx, parsed, output) } func (pp *Preprocessor) Compile( ctx context.Context, input io.Reader, ) (*Compiled, error) { parsed, err := pp.Parse(ctx, input) if err != nil { return nil, err } compiled, err := pp.xgo.Compile( ctx, parsed, ) if err != nil { return nil, err } return compiled, nil }