code_block.go 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. package parser
  2. import "github.com/usememos/memos/plugin/gomark/parser/tokenizer"
  3. type CodeBlockParser struct {
  4. Language string
  5. Content string
  6. }
  7. func NewCodeBlockParser() *CodeBlockParser {
  8. return &CodeBlockParser{}
  9. }
  10. func (*CodeBlockParser) Match(tokens []*tokenizer.Token) *CodeBlockParser {
  11. if len(tokens) < 9 {
  12. return nil
  13. }
  14. if tokens[0].Type != tokenizer.Backtick || tokens[1].Type != tokenizer.Backtick || tokens[2].Type != tokenizer.Backtick {
  15. return nil
  16. }
  17. if tokens[3].Type != tokenizer.Newline && tokens[4].Type != tokenizer.Newline {
  18. return nil
  19. }
  20. cursor, language := 4, ""
  21. if tokens[3].Type != tokenizer.Newline {
  22. language = tokens[3].Value
  23. cursor = 5
  24. }
  25. content, matched := "", false
  26. for ; cursor < len(tokens)-3; cursor++ {
  27. if tokens[cursor].Type == tokenizer.Newline && tokens[cursor+1].Type == tokenizer.Backtick && tokens[cursor+2].Type == tokenizer.Backtick && tokens[cursor+3].Type == tokenizer.Backtick {
  28. if cursor+3 == len(tokens)-1 {
  29. matched = true
  30. break
  31. } else if tokens[cursor+4].Type == tokenizer.Newline {
  32. matched = true
  33. break
  34. }
  35. }
  36. content += tokens[cursor].Value
  37. }
  38. if !matched {
  39. return nil
  40. }
  41. return &CodeBlockParser{
  42. Language: language,
  43. Content: content,
  44. }
  45. }