mirror of
https://github.com/cwinfo/matterbridge.git
synced 2024-12-27 11:15:39 +00:00
142 lines
2.7 KiB
Go
142 lines
2.7 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 "strings"
|
||
|
|
||
|
const (
|
||
|
ptRoot = iota
|
||
|
ptList
|
||
|
ptBlockQuote
|
||
|
ptParagraph
|
||
|
ptReference
|
||
|
)
|
||
|
|
||
|
type StateBlock struct {
|
||
|
StateCore
|
||
|
|
||
|
BMarks []int // offsets of the line beginnings
|
||
|
EMarks []int // offsets of the line endings
|
||
|
TShift []int // indents for each line
|
||
|
SCount []int
|
||
|
BSCount []int
|
||
|
BlkIndent int // required block content indent (in a list etc.)
|
||
|
Line int // line index in the source string
|
||
|
LineMax int // number of lines
|
||
|
Tight bool // loose or tight mode for lists
|
||
|
ParentType byte // parent block type
|
||
|
Level int
|
||
|
}
|
||
|
|
||
|
func (s *StateBlock) IsLineEmpty(n int) bool {
|
||
|
return s.BMarks[n]+s.TShift[n] >= s.EMarks[n]
|
||
|
}
|
||
|
|
||
|
func (s *StateBlock) SkipEmptyLines(from int) int {
|
||
|
for from < s.LineMax && s.IsLineEmpty(from) {
|
||
|
from++
|
||
|
}
|
||
|
return from
|
||
|
}
|
||
|
|
||
|
func (s *StateBlock) SkipSpaces(pos int) int {
|
||
|
src := s.Src
|
||
|
for pos < len(src) && byteIsSpace(src[pos]) {
|
||
|
pos++
|
||
|
}
|
||
|
return pos
|
||
|
}
|
||
|
|
||
|
func (s *StateBlock) SkipBytes(pos int, b byte) int {
|
||
|
src := s.Src
|
||
|
for pos < len(src) && src[pos] == b {
|
||
|
pos++
|
||
|
}
|
||
|
return pos
|
||
|
}
|
||
|
|
||
|
func (s *StateBlock) SkipBytesBack(pos int, b byte, min int) int {
|
||
|
for pos > min {
|
||
|
pos--
|
||
|
if s.Src[pos] != b {
|
||
|
return pos + 1
|
||
|
}
|
||
|
}
|
||
|
return pos
|
||
|
}
|
||
|
|
||
|
func (s *StateBlock) SkipSpacesBack(pos int, min int) int {
|
||
|
for pos > min {
|
||
|
pos--
|
||
|
if !byteIsSpace(s.Src[pos]) {
|
||
|
return pos + 1
|
||
|
}
|
||
|
}
|
||
|
return pos
|
||
|
}
|
||
|
|
||
|
func (s *StateBlock) Lines(begin, end, indent int, keepLastLf bool) string {
|
||
|
if begin == end {
|
||
|
return ""
|
||
|
}
|
||
|
|
||
|
src := s.Src
|
||
|
|
||
|
queue := make([]string, end-begin)
|
||
|
|
||
|
for i, line := 0, begin; line < end; i, line = i+1, line+1 {
|
||
|
lineIndent := 0
|
||
|
lineStart := s.BMarks[line]
|
||
|
first := lineStart
|
||
|
last := s.EMarks[line]
|
||
|
if (line+1 < end || keepLastLf) && last < len(src) {
|
||
|
last++
|
||
|
}
|
||
|
|
||
|
for first < last && lineIndent < indent {
|
||
|
ch := src[first]
|
||
|
|
||
|
if byteIsSpace(ch) {
|
||
|
if ch == '\t' {
|
||
|
lineIndent += 4 - (lineIndent+s.BSCount[line])%4
|
||
|
} else {
|
||
|
lineIndent++
|
||
|
}
|
||
|
} else if first-lineStart < s.TShift[line] {
|
||
|
lineIndent++
|
||
|
} else {
|
||
|
break
|
||
|
}
|
||
|
|
||
|
first++
|
||
|
}
|
||
|
|
||
|
if lineIndent > indent {
|
||
|
queue[i] = strings.Repeat(" ", lineIndent-indent) + src[first:last]
|
||
|
} else {
|
||
|
queue[i] = src[first:last]
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return strings.Join(queue, "")
|
||
|
}
|
||
|
|
||
|
func (s *StateBlock) PushToken(tok Token) {
|
||
|
tok.SetLevel(s.Level)
|
||
|
s.Tokens = append(s.Tokens, tok)
|
||
|
}
|
||
|
|
||
|
func (s *StateBlock) PushOpeningToken(tok Token) {
|
||
|
tok.SetLevel(s.Level)
|
||
|
s.Level++
|
||
|
s.Tokens = append(s.Tokens, tok)
|
||
|
}
|
||
|
|
||
|
func (s *StateBlock) PushClosingToken(tok Token) {
|
||
|
s.Level--
|
||
|
tok.SetLevel(s.Level)
|
||
|
s.Tokens = append(s.Tokens, tok)
|
||
|
}
|