matterbridge/vendor/gitlab.com/golang-commonmark/markdown/blockquote.go

234 lines
4.6 KiB
Go

// Copyright 2015 The Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package markdown
import "unicode/utf8"
var blockquoteTerminatedBy []BlockRule
func ruleBlockQuote(s *StateBlock, startLine, endLine int, silent bool) bool {
if s.SCount[startLine]-s.BlkIndent >= 4 {
return false
}
pos := s.BMarks[startLine] + s.TShift[startLine]
max := s.EMarks[startLine]
src := s.Src
if pos >= max {
return false
}
if src[pos] != '>' {
return false
}
pos++
if silent {
return true
}
initial := s.SCount[startLine] + pos - (s.BMarks[startLine] + s.TShift[startLine])
offset := initial
spaceAfterMarker := false
adjustTab := false
if pos < max {
if src[pos] == ' ' {
pos++
initial++
offset++
spaceAfterMarker = true
} else if src[pos] == '\t' {
spaceAfterMarker = true
if (s.BSCount[startLine]+offset)%4 == 3 {
pos++
initial++
offset++
} else {
adjustTab = true
}
}
}
oldBMarks := []int{s.BMarks[startLine]}
s.BMarks[startLine] = pos
for pos < max {
r, size := utf8.DecodeRuneInString(src[pos:])
if runeIsSpace(r) {
if r == '\t' {
d := 0
if adjustTab {
d = 1
}
offset += 4 - (offset+s.BSCount[startLine]+d)%4
} else {
offset++
}
} else {
break
}
pos += size
}
oldBSCount := []int{s.BSCount[startLine]}
d := 0
if spaceAfterMarker {
d = 1
}
s.BSCount[startLine] = s.SCount[startLine] + 1 + d
lastLineEmpty := pos >= max
oldSCount := []int{s.SCount[startLine]}
s.SCount[startLine] = offset - initial
oldTShift := []int{s.TShift[startLine]}
s.TShift[startLine] = pos - s.BMarks[startLine]
oldParentType := s.ParentType
s.ParentType = ptBlockQuote
wasOutdented := false
oldLineMax := s.LineMax
nextLine := startLine + 1
for ; nextLine < endLine; nextLine++ {
if s.SCount[nextLine] < s.BlkIndent {
wasOutdented = true
}
pos = s.BMarks[nextLine] + s.TShift[nextLine]
max = s.EMarks[nextLine]
if pos >= max {
break
}
pos++
if src[pos-1] == '>' && !wasOutdented {
initial = s.SCount[nextLine] + pos + (s.BMarks[nextLine] + s.TShift[nextLine])
offset = initial
if pos >= len(src) || src[pos] != ' ' && src[pos] != '\t' {
spaceAfterMarker = true
} else if src[pos] == ' ' {
pos++
initial++
offset++
adjustTab = false
spaceAfterMarker = true
} else if src[pos] == '\t' {
spaceAfterMarker = true
if (s.BSCount[nextLine]+offset)%4 == 3 {
pos++
initial++
offset++
adjustTab = false
} else {
adjustTab = true
}
}
oldBMarks = append(oldBMarks, s.BMarks[nextLine])
s.BMarks[nextLine] = pos
for pos < max {
r, size := utf8.DecodeRuneInString(src[pos:])
if runeIsSpace(r) {
if r == '\t' {
d := 0
if adjustTab {
d = 1
}
offset += 4 - (offset+s.BSCount[startLine]+d)%4
} else {
offset++
}
} else {
break
}
pos += size
}
lastLineEmpty = pos >= max
oldBSCount = append(oldBSCount, s.BSCount[nextLine])
d := 0
if spaceAfterMarker {
d = 1
}
s.BSCount[nextLine] = s.SCount[nextLine] + 1 + d
oldSCount = append(oldSCount, s.SCount[nextLine])
s.SCount[nextLine] = offset - initial
oldTShift = append(oldTShift, s.TShift[nextLine])
s.TShift[nextLine] = pos - s.BMarks[nextLine]
continue
}
if lastLineEmpty {
break
}
terminate := false
for _, r := range blockquoteTerminatedBy {
if r(s, nextLine, endLine, true) {
terminate = true
break
}
}
if terminate {
s.LineMax = nextLine
if s.BlkIndent != 0 {
oldBMarks = append(oldBMarks, s.BMarks[nextLine])
oldBSCount = append(oldBSCount, s.BSCount[nextLine])
oldTShift = append(oldTShift, s.TShift[nextLine])
oldSCount = append(oldSCount, s.SCount[nextLine])
s.SCount[nextLine] -= s.BlkIndent
}
break
}
oldBMarks = append(oldBMarks, s.BMarks[nextLine])
oldBSCount = append(oldBSCount, s.BSCount[nextLine])
oldTShift = append(oldTShift, s.TShift[nextLine])
oldSCount = append(oldSCount, s.SCount[nextLine])
s.SCount[nextLine] = -1
}
oldIndent := s.BlkIndent
s.BlkIndent = 0
tok := &BlockquoteOpen{
Map: [2]int{startLine, 0},
}
s.PushOpeningToken(tok)
s.Md.Block.Tokenize(s, startLine, nextLine)
s.PushClosingToken(&BlockquoteClose{})
s.LineMax = oldLineMax
s.ParentType = oldParentType
tok.Map[1] = s.Line
for i := 0; i < len(oldTShift); i++ {
s.BMarks[startLine+i] = oldBMarks[i]
s.TShift[startLine+i] = oldTShift[i]
s.SCount[startLine+i] = oldSCount[i]
s.BSCount[startLine+i] = oldBSCount[i]
}
s.BlkIndent = oldIndent
return true
}