pp.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. package gopp
  2. import (
  3. "bytes"
  4. "context"
  5. "io"
  6. )
  7. type Parsed struct {
  8. Texts [][]byte
  9. PreCode []byte
  10. Codes [][]byte
  11. }
  12. type Preprocessor struct {
  13. xgo *XGo
  14. tags [2][]byte
  15. preTag byte
  16. }
  17. // Get the new preprocessor with default options.
  18. func New(xgo *XGo) *Preprocessor {
  19. pp := &Preprocessor{}
  20. pp.xgo = xgo
  21. pp.tags = [2][]byte{
  22. []byte("{{"),
  23. []byte("}}"),
  24. }
  25. pp.preTag = '#'
  26. return pp
  27. }
  28. func (pp *Preprocessor) XGo() *XGo {
  29. return pp.xgo
  30. }
  31. func (pp *Preprocessor) Parse(
  32. ctx context.Context,
  33. input io.Reader,
  34. ) (*Parsed, error) {
  35. data, err := io.ReadAll(input)
  36. if err != nil {
  37. return nil, err
  38. }
  39. //var b bytes.Buffer
  40. preCode := []byte(nil)
  41. texts := [][]byte{}
  42. codes := [][]byte{}
  43. pref := append(pp.tags[0], pp.preTag)
  44. if bytes.HasPrefix(data, pref) {
  45. idxEnd := bytes.Index(data, pp.tags[1])
  46. if idxEnd < 0 {
  47. return nil, UnexpectedError{
  48. What: "pre-code start tag",
  49. }
  50. }
  51. preCode = data[len(pref):idxEnd]
  52. //texts = append(texts, []byte{})
  53. data = data[idxEnd+len(pp.tags[1]):]
  54. }
  55. for {
  56. idxStart := bytes.Index(data, pp.tags[0])
  57. idxEnd := bytes.Index(data, pp.tags[1])
  58. //fmt.Printf("cock %d %d %d\n", last, idxStart, idxEnd)
  59. if idxStart < 0 {
  60. if idxEnd >= 0 {
  61. return nil, UnexpectedError{
  62. What: "end tag",
  63. }
  64. }
  65. texts = append(texts, data)
  66. break
  67. } else if idxEnd < 0 {
  68. return nil, UnexpectedError{
  69. What: "start tag",
  70. }
  71. }
  72. text := data[:idxStart]
  73. texts = append(texts, text)
  74. code := data[idxStart+len(pp.tags[0]):idxEnd]
  75. codes = append(codes, code)
  76. data = data[idxEnd + len(pp.tags[1]):]
  77. }
  78. return &Parsed{
  79. Texts: texts,
  80. PreCode: preCode,
  81. Codes: codes,
  82. }, nil
  83. }
  84. func (pp *Preprocessor) Render(
  85. ctx context.Context,
  86. input io.Reader,
  87. output io.Writer,
  88. ) error {
  89. parsed, err := pp.Parse(ctx, input)
  90. if err != nil { return err }
  91. return pp.xgo.Render(ctx, parsed, output)
  92. }
  93. func (pp *Preprocessor) Compile(
  94. ctx context.Context,
  95. input io.Reader,
  96. ) (*Compiled, error) {
  97. parsed, err := pp.Parse(ctx, input)
  98. if err != nil {
  99. return nil, err
  100. }
  101. compiled, err := pp.xgo.Compile(
  102. ctx,
  103. parsed,
  104. )
  105. if err != nil {
  106. return nil, err
  107. }
  108. return compiled, nil
  109. }