mirror of
https://github.com/42wim/matterbridge.git
synced 2024-11-25 04:02:03 -08:00
234 lines
4.6 KiB
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
|
||
|
}
|