thematic_break.go (1583B)
1 package parser 2 3 import ( 4 "github.com/yuin/goldmark/ast" 5 "github.com/yuin/goldmark/text" 6 "github.com/yuin/goldmark/util" 7 ) 8 9 type thematicBreakPraser struct { 10 } 11 12 var defaultThematicBreakPraser = &thematicBreakPraser{} 13 14 // NewThematicBreakParser returns a new BlockParser that 15 // parses thematic breaks. 16 func NewThematicBreakParser() BlockParser { 17 return defaultThematicBreakPraser 18 } 19 20 func isThematicBreak(line []byte, offset int) bool { 21 w, pos := util.IndentWidth(line, offset) 22 if w > 3 { 23 return false 24 } 25 mark := byte(0) 26 count := 0 27 for i := pos; i < len(line); i++ { 28 c := line[i] 29 if util.IsSpace(c) { 30 continue 31 } 32 if mark == 0 { 33 mark = c 34 count = 1 35 if mark == '*' || mark == '-' || mark == '_' { 36 continue 37 } 38 return false 39 } 40 if c != mark { 41 return false 42 } 43 count++ 44 } 45 return count > 2 46 } 47 48 func (b *thematicBreakPraser) Trigger() []byte { 49 return []byte{'-', '*', '_'} 50 } 51 52 func (b *thematicBreakPraser) Open(parent ast.Node, reader text.Reader, pc Context) (ast.Node, State) { 53 line, segment := reader.PeekLine() 54 if isThematicBreak(line, reader.LineOffset()) { 55 reader.Advance(segment.Len() - 1) 56 return ast.NewThematicBreak(), NoChildren 57 } 58 return nil, NoChildren 59 } 60 61 func (b *thematicBreakPraser) Continue(node ast.Node, reader text.Reader, pc Context) State { 62 return Close 63 } 64 65 func (b *thematicBreakPraser) Close(node ast.Node, reader text.Reader, pc Context) { 66 // nothing to do 67 } 68 69 func (b *thematicBreakPraser) CanInterruptParagraph() bool { 70 return true 71 } 72 73 func (b *thematicBreakPraser) CanAcceptIndentedLine() bool { 74 return false 75 }