func (p *Parser) figureBlock(data []byte, doRender bool) int {
	beg, marker := sFigureLine(data, "")
	if beg == 0 || beg >= len(data) {
		return 0
	}
	var raw bytes.Buffer
	for {
		figEnd, _ := sFigureLine(data[beg:], marker)
		if figEnd != 0 {
			beg += figEnd
			break
		}
		end := skipUntilChar(data, beg, '\n') + 1
		if end >= len(data) {
			return 0
		}
		if doRender {
			raw.Write(data[beg:end])
		}
		beg = end
	}
	if !doRender {
		return beg
	}
	figure := &ast.CaptionFigure{}
	p.addBlock(figure)
	p.block(raw.Bytes())
	defer p.finalize(figure)
	if captionContent, id, consumed := p.caption(data[beg:], []byte("Figure: ")); consumed > 0 {
		caption := &ast.Caption{}
		p.Inline(caption, captionContent)
		figure.HeadingID = id
		p.addChild(caption)
		beg += consumed
	}
	p.finalize(figure)
	return beg
}
figureBlock returns the end index if data contains a figure block at the beginning,
or 0 otherwise. It writes to out if doRender is true, otherwise it has no side effects.
If doRender is true, a final newline is mandatory to recognize the figure block.
package parser
import (
	"bytes"
	"github.com/gomarkdown/markdown/ast"
)
func sFigureLine(data []byte, oldmarker string) (end int, marker string) {
	i, size := 0, 0
	n := len(data)
	for i < n && i < 3 && data[i] == ' ' {
		i++
	}
	if i+1 >= n {
		return 0, ""
	}
	if data[i] != '!' || data[i+1] != '-' {
		return 0, ""
	}
	i++
	c := data[i]  
	for i < n && data[i] == c {
		size++
		i++
	}
	if size < 3 {
		return 0, ""
	}
	marker = string(data[i-size : i])
	if oldmarker != "" && marker != oldmarker {
		return 0, ""
	}
	i = skipChar(data, i, ' ')
	if i >= n || data[i] != '\n' {
		if i == n {
			return i, marker
		}
		return 0, ""
	}
	return i + 1, marker  
}