// 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" type ParserInline struct { } type ( InlineRule func(*StateInline, bool) bool PostprocessRule func(*StateInline) ) var ( inlineRules []InlineRule postprocessRules []PostprocessRule ) func (i ParserInline) Parse(src string, md *Markdown, env *Environment) []Token { if src == "" { return nil } var s StateInline s.Src = src s.Md = md s.Env = env s.PosMax = len(src) s.Tokens = s.bootstrap[:0] i.Tokenize(&s) for _, r := range postprocessRules { r(&s) } return s.Tokens } func (ParserInline) Tokenize(s *StateInline) { end := s.PosMax src := s.Src maxNesting := s.Md.MaxNesting ok := false for s.Pos < end { if s.Level < maxNesting { for _, rule := range inlineRules { ok = rule(s, false) if ok { break } } } if ok { if s.Pos >= end { break } continue } r, size := utf8.DecodeRuneInString(src[s.Pos:]) s.Pending.WriteRune(r) s.Pos += size } if s.Pending.Len() > 0 { s.PushPending() } } func (ParserInline) SkipToken(s *StateInline) { pos := s.Pos if s.Cache != nil { if newPos, ok := s.Cache[pos]; ok { s.Pos = newPos return } } else { s.Cache = make(map[int]int) } ok := false if s.Level < s.Md.MaxNesting { for _, r := range inlineRules { s.Level++ ok = r(s, true) s.Level-- if ok { break } } } else { s.Pos = s.PosMax } if !ok { _, size := utf8.DecodeRuneInString(s.Src[s.Pos:]) s.Pos += size } s.Cache[pos] = s.Pos }