aside.go 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. package parser
  2. import (
  3. "bytes"
  4. "github.com/gomarkdown/markdown/ast"
  5. )
  6. // returns aisde prefix length
  7. func (p *Parser) asidePrefix(data []byte) int {
  8. i := 0
  9. n := len(data)
  10. for i < 3 && i < n && data[i] == ' ' {
  11. i++
  12. }
  13. if i+1 < n && data[i] == 'A' && data[i+1] == '>' {
  14. if i+2 < n && data[i+2] == ' ' {
  15. return i + 3
  16. }
  17. return i + 2
  18. }
  19. return 0
  20. }
  21. // aside ends with at least one blank line
  22. // followed by something without a aside prefix
  23. func (p *Parser) terminateAside(data []byte, beg, end int) bool {
  24. if IsEmpty(data[beg:]) <= 0 {
  25. return false
  26. }
  27. if end >= len(data) {
  28. return true
  29. }
  30. return p.asidePrefix(data[end:]) == 0 && IsEmpty(data[end:]) == 0
  31. }
  32. // parse a aside fragment
  33. func (p *Parser) aside(data []byte) int {
  34. var raw bytes.Buffer
  35. beg, end := 0, 0
  36. // identical to quote
  37. for beg < len(data) {
  38. end = beg
  39. // Step over whole lines, collecting them. While doing that, check for
  40. // fenced code and if one's found, incorporate it altogether,
  41. // irregardless of any contents inside it
  42. for end < len(data) && data[end] != '\n' {
  43. if p.extensions&FencedCode != 0 {
  44. if i := p.fencedCodeBlock(data[end:], false); i > 0 {
  45. // -1 to compensate for the extra end++ after the loop:
  46. end += i - 1
  47. break
  48. }
  49. }
  50. end++
  51. }
  52. end = skipCharN(data, end, '\n', 1)
  53. if pre := p.asidePrefix(data[beg:]); pre > 0 {
  54. // skip the prefix
  55. beg += pre
  56. } else if p.terminateAside(data, beg, end) {
  57. break
  58. }
  59. // this line is part of the aside
  60. raw.Write(data[beg:end])
  61. beg = end
  62. }
  63. block := p.AddBlock(&ast.Aside{})
  64. p.Block(raw.Bytes())
  65. p.Finalize(block)
  66. return end
  67. }