func NewBlockReader(source []byte, segments *Segments) BlockReader {
	r := &blockReader{
		source: source,
	}
	if segments != nil {
		r.Reset(segments)
	}
	return r
}
NewBlockReader returns a new BlockReader.
package text
import (
	"io"
	"regexp"
	"unicode/utf8"
	"github.com/yuin/goldmark/util"
)
const invalidValue = -1
const EOF = byte(0xff)
type Reader interface {
	io.RuneReader
	Source() []byte
	ResetPosition()
	Peek() byte
	PeekLine() ([]byte, Segment)
	PrecendingCharacter() rune
	Value(Segment) []byte
	LineOffset() int
	Position() (int, Segment)
	SetPosition(int, Segment)
	SetPadding(int)
	Advance(int)
	AdvanceAndSetPadding(int, int)
	AdvanceLine()
	SkipSpaces() (Segment, int, bool)
	SkipBlankLines() (Segment, int, bool)
	Match(reg *regexp.Regexp) bool
	FindSubMatch(reg *regexp.Regexp) [][]byte
	FindClosure(opener, closer byte, options FindClosureOptions) (*Segments, bool)
}
type FindClosureOptions struct {
	CodeSpan bool
	Nesting bool
	Newline bool
	Advance bool
}
type reader struct {
	source       []byte
	sourceLength int
	line         int
	peekedLine   []byte
	pos          Segment
	head         int
	lineOffset   int
}
func NewReader(source []byte) Reader {
	r := &reader{
		source:       source,
		sourceLength: len(source),
	}
	r.ResetPosition()
	return r
}
func (r *reader) FindClosure(opener, closer byte, options FindClosureOptions) (*Segments, bool) {
	return findClosureReader(r, opener, closer, options)
}
func (r *reader) ResetPosition() {
	r.line = -1
	r.head = 0
	r.lineOffset = -1
	r.AdvanceLine()
}
func (r *reader) Source() []byte {
	return r.source
}
func (r *reader) Value(seg Segment) []byte {
	return seg.Value(r.source)
}
func (r *reader) Peek() byte {
	if r.pos.Start >= 0 && r.pos.Start < r.sourceLength {
		if r.pos.Padding != 0 {
			return space[0]
		}
		return r.source[r.pos.Start]
	}
	return EOF
}
func (r *reader) PeekLine() ([]byte, Segment) {
	if r.pos.Start >= 0 && r.pos.Start < r.sourceLength {
		if r.peekedLine == nil {
			r.peekedLine = r.pos.Value(r.Source())
		}
		return r.peekedLine, r.pos
	}
	return nil, r.pos
}
func (r *reader) ReadRune() (rune, int, error) {
	return readRuneReader(r)
}
func (r *reader) LineOffset() int {
	if r.lineOffset < 0 {
		v := 0
		for i := r.head; i < r.pos.Start; i++ {
			if r.source[i] == '\t' {
				v += util.TabWidth(v)
			} else {
				v++
			}
		}
		r.lineOffset = v - r.pos.Padding
	}
	return r.lineOffset
}
func (r *reader) PrecendingCharacter() rune {
	if r.pos.Start <= 0 {
		if r.pos.Padding != 0 {
			return rune(' ')
		}
		return rune('\n')
	}
	i := r.pos.Start - 1
	for ; i >= 0; i-- {
		if utf8.RuneStart(r.source[i]) {
			break
		}
	}
	rn, _ := utf8.DecodeRune(r.source[i:])
	return rn
}
func (r *reader) Advance(n int) {
	r.lineOffset = -1
	if n < len(r.peekedLine) && r.pos.Padding == 0 {
		r.pos.Start += n
		r.peekedLine = nil
		return
	}
	r.peekedLine = nil
	l := r.sourceLength
	for ; n > 0 && r.pos.Start < l; n-- {
		if r.pos.Padding != 0 {
			r.pos.Padding--
			continue
		}
		if r.source[r.pos.Start] == '\n' {
			r.AdvanceLine()
			continue
		}
		r.pos.Start++
	}
}
func (r *reader) AdvanceAndSetPadding(n, padding int) {
	r.Advance(n)
	if padding > r.pos.Padding {
		r.SetPadding(padding)
	}
}
func (r *reader) AdvanceLine() {
	r.lineOffset = -1
	r.peekedLine = nil
	r.pos.Start = r.pos.Stop
	r.head = r.pos.Start
	if r.pos.Start < 0 {
		return
	}
	r.pos.Stop = r.sourceLength
	for i := r.pos.Start; i < r.sourceLength; i++ {
		c := r.source[i]
		if c == '\n' {
			r.pos.Stop = i + 1
			break
		}
	}
	r.line++
	r.pos.Padding = 0
}
func (r *reader) Position() (int, Segment) {
	return r.line, r.pos
}
func (r *reader) SetPosition(line int, pos Segment) {
	r.lineOffset = -1
	r.line = line
	r.pos = pos
}
func (r *reader) SetPadding(v int) {
	r.pos.Padding = v
}
func (r *reader) SkipSpaces() (Segment, int, bool) {
	return skipSpacesReader(r)
}
func (r *reader) SkipBlankLines() (Segment, int, bool) {
	return skipBlankLinesReader(r)
}
func (r *reader) Match(reg *regexp.Regexp) bool {
	return matchReader(r, reg)
}
func (r *reader) FindSubMatch(reg *regexp.Regexp) [][]byte {
	return findSubMatchReader(r, reg)
}
type BlockReader interface {
	Reader
	Reset(segment *Segments)
}
type blockReader struct {
	source         []byte
	segments       *Segments
	segmentsLength int
	line           int
	pos            Segment
	head           int
	last           int
	lineOffset     int
}