diff options
Diffstat (limited to 'vendor/github.com/yuin/goldmark/parser/delimiter.go')
-rw-r--r-- | vendor/github.com/yuin/goldmark/parser/delimiter.go | 238 |
1 files changed, 0 insertions, 238 deletions
diff --git a/vendor/github.com/yuin/goldmark/parser/delimiter.go b/vendor/github.com/yuin/goldmark/parser/delimiter.go deleted file mode 100644 index d097e3fb3..000000000 --- a/vendor/github.com/yuin/goldmark/parser/delimiter.go +++ /dev/null @@ -1,238 +0,0 @@ -package parser - -import ( - "fmt" - "strings" - - "github.com/yuin/goldmark/ast" - "github.com/yuin/goldmark/text" - "github.com/yuin/goldmark/util" -) - -// A DelimiterProcessor interface provides a set of functions about -// Delimiter nodes. -type DelimiterProcessor interface { - // IsDelimiter returns true if given character is a delimiter, otherwise false. - IsDelimiter(byte) bool - - // CanOpenCloser returns true if given opener can close given closer, otherwise false. - CanOpenCloser(opener, closer *Delimiter) bool - - // OnMatch will be called when new matched delimiter found. - // OnMatch should return a new Node correspond to the matched delimiter. - OnMatch(consumes int) ast.Node -} - -// A Delimiter struct represents a delimiter like '*' of the Markdown text. -type Delimiter struct { - ast.BaseInline - - Segment text.Segment - - // CanOpen is set true if this delimiter can open a span for a new node. - // See https://spec.commonmark.org/0.30/#can-open-emphasis for details. - CanOpen bool - - // CanClose is set true if this delimiter can close a span for a new node. - // See https://spec.commonmark.org/0.30/#can-open-emphasis for details. - CanClose bool - - // Length is a remaining length of this delimiter. - Length int - - // OriginalLength is a original length of this delimiter. - OriginalLength int - - // Char is a character of this delimiter. - Char byte - - // PreviousDelimiter is a previous sibling delimiter node of this delimiter. - PreviousDelimiter *Delimiter - - // NextDelimiter is a next sibling delimiter node of this delimiter. - NextDelimiter *Delimiter - - // Processor is a DelimiterProcessor associated with this delimiter. - Processor DelimiterProcessor -} - -// Inline implements Inline.Inline. -func (d *Delimiter) Inline() {} - -// Dump implements Node.Dump. -func (d *Delimiter) Dump(source []byte, level int) { - fmt.Printf("%sDelimiter: \"%s\"\n", strings.Repeat(" ", level), string(d.Text(source))) -} - -var kindDelimiter = ast.NewNodeKind("Delimiter") - -// Kind implements Node.Kind. -func (d *Delimiter) Kind() ast.NodeKind { - return kindDelimiter -} - -// Text implements Node.Text. -func (d *Delimiter) Text(source []byte) []byte { - return d.Segment.Value(source) -} - -// ConsumeCharacters consumes delimiters. -func (d *Delimiter) ConsumeCharacters(n int) { - d.Length -= n - d.Segment = d.Segment.WithStop(d.Segment.Start + d.Length) -} - -// CalcComsumption calculates how many characters should be used for opening -// a new span correspond to given closer. -func (d *Delimiter) CalcComsumption(closer *Delimiter) int { - if (d.CanClose || closer.CanOpen) && (d.OriginalLength+closer.OriginalLength)%3 == 0 && closer.OriginalLength%3 != 0 { - return 0 - } - if d.Length >= 2 && closer.Length >= 2 { - return 2 - } - return 1 -} - -// NewDelimiter returns a new Delimiter node. -func NewDelimiter(canOpen, canClose bool, length int, char byte, processor DelimiterProcessor) *Delimiter { - c := &Delimiter{ - BaseInline: ast.BaseInline{}, - CanOpen: canOpen, - CanClose: canClose, - Length: length, - OriginalLength: length, - Char: char, - PreviousDelimiter: nil, - NextDelimiter: nil, - Processor: processor, - } - return c -} - -// ScanDelimiter scans a delimiter by given DelimiterProcessor. -func ScanDelimiter(line []byte, before rune, min int, processor DelimiterProcessor) *Delimiter { - i := 0 - c := line[i] - j := i - if !processor.IsDelimiter(c) { - return nil - } - for ; j < len(line) && c == line[j]; j++ { - } - if (j - i) >= min { - after := rune(' ') - if j != len(line) { - after = util.ToRune(line, j) - } - - var canOpen, canClose bool - beforeIsPunctuation := util.IsPunctRune(before) - beforeIsWhitespace := util.IsSpaceRune(before) - afterIsPunctuation := util.IsPunctRune(after) - afterIsWhitespace := util.IsSpaceRune(after) - - isLeft := !afterIsWhitespace && - (!afterIsPunctuation || beforeIsWhitespace || beforeIsPunctuation) - isRight := !beforeIsWhitespace && - (!beforeIsPunctuation || afterIsWhitespace || afterIsPunctuation) - - if line[i] == '_' { - canOpen = isLeft && (!isRight || beforeIsPunctuation) - canClose = isRight && (!isLeft || afterIsPunctuation) - } else { - canOpen = isLeft - canClose = isRight - } - return NewDelimiter(canOpen, canClose, j-i, c, processor) - } - return nil -} - -// ProcessDelimiters processes the delimiter list in the context. -// Processing will be stop when reaching the bottom. -// -// If you implement an inline parser that can have other inline nodes as -// children, you should call this function when nesting span has closed. -func ProcessDelimiters(bottom ast.Node, pc Context) { - lastDelimiter := pc.LastDelimiter() - if lastDelimiter == nil { - return - } - var closer *Delimiter - if bottom != nil { - if bottom != lastDelimiter { - for c := lastDelimiter.PreviousSibling(); c != nil && c != bottom; { - if d, ok := c.(*Delimiter); ok { - closer = d - } - c = c.PreviousSibling() - } - } - } else { - closer = pc.FirstDelimiter() - } - if closer == nil { - pc.ClearDelimiters(bottom) - return - } - for closer != nil { - if !closer.CanClose { - closer = closer.NextDelimiter - continue - } - consume := 0 - found := false - maybeOpener := false - var opener *Delimiter - for opener = closer.PreviousDelimiter; opener != nil && opener != bottom; opener = opener.PreviousDelimiter { - if opener.CanOpen && opener.Processor.CanOpenCloser(opener, closer) { - maybeOpener = true - consume = opener.CalcComsumption(closer) - if consume > 0 { - found = true - break - } - } - } - if !found { - next := closer.NextDelimiter - if !maybeOpener && !closer.CanOpen { - pc.RemoveDelimiter(closer) - } - closer = next - continue - } - opener.ConsumeCharacters(consume) - closer.ConsumeCharacters(consume) - - node := opener.Processor.OnMatch(consume) - - parent := opener.Parent() - child := opener.NextSibling() - - for child != nil && child != closer { - next := child.NextSibling() - node.AppendChild(node, child) - child = next - } - parent.InsertAfter(parent, opener, node) - - for c := opener.NextDelimiter; c != nil && c != closer; { - next := c.NextDelimiter - pc.RemoveDelimiter(c) - c = next - } - - if opener.Length == 0 { - pc.RemoveDelimiter(opener) - } - - if closer.Length == 0 { - next := closer.NextDelimiter - pc.RemoveDelimiter(closer) - closer = next - } - } - pc.ClearDelimiters(bottom) -} |