diff options
Diffstat (limited to 'vendor/gitlab.com/golang-commonmark/markdown/html_block.go')
-rw-r--r-- | vendor/gitlab.com/golang-commonmark/markdown/html_block.go | 222 |
1 files changed, 222 insertions, 0 deletions
diff --git a/vendor/gitlab.com/golang-commonmark/markdown/html_block.go b/vendor/gitlab.com/golang-commonmark/markdown/html_block.go new file mode 100644 index 00000000..98a89499 --- /dev/null +++ b/vendor/gitlab.com/golang-commonmark/markdown/html_block.go @@ -0,0 +1,222 @@ +// 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 ( + "regexp" + "strings" +) + +var ( + htmlBlocks = []string{ + "address", + "article", + "aside", + "base", + "basefont", + "blockquote", + "body", + "caption", + "center", + "col", + "colgroup", + "dd", + "details", + "dialog", + "dir", + "div", + "dl", + "dt", + "fieldset", + "figcaption", + "figure", + "footer", + "form", + "frame", + "frameset", + "h1", + "h2", + "h3", + "h4", + "h5", + "h6", + "head", + "header", + "hr", + "html", + "iframe", + "legend", + "li", + "link", + "main", + "menu", + "menuitem", + "meta", + "nav", + "noframes", + "ol", + "optgroup", + "option", + "p", + "param", + "section", + "source", + "summary", + "table", + "tbody", + "td", + "tfoot", + "th", + "thead", + "title", + "tr", + "track", + "ul", + } + + htmlBlocksSet = make(map[string]bool) + + rStartCond1 = regexp.MustCompile(`(?i)^(pre|script|style)([\n\t >]|$)`) + rEndCond1 = regexp.MustCompile(`(?i)</(pre|script|style)>`) + rStartCond6 = regexp.MustCompile(`(?i)^/?(` + strings.Join(htmlBlocks, "|") + `)(\s|$|>|/>)`) + rStartCond7 = regexp.MustCompile(`(?i)^(/[a-z][a-z0-9-]*|[a-z][a-z0-9-]*(\s+[a-z_:][a-z0-9_.:-]*\s*=\s*("[^"]*"|'[^']*'|[ "'=<>\x60]))*\s*/?)>\s*$`) +) + +func init() { + for _, tag := range htmlBlocks { + htmlBlocksSet[tag] = true + } +} + +func min(a, b int) int { + if a < b { + return a + } + return b +} + +func matchTagName(s string) string { + if len(s) < 2 { + return "" + } + + i := 0 + if s[0] == '/' { + i++ + } + start := i + max := min(15+i, len(s)) + for i < max && isLetter(s[i]) { + i++ + } + if i >= len(s) { + return "" + } + + switch s[i] { + case ' ', '\n', '/', '>': + return strings.ToLower(s[start:i]) + default: + return "" + } +} + +func ruleHTMLBlock(s *StateBlock, startLine, endLine int, silent bool) bool { + if !s.Md.HTML { + return false + } + + pos := s.BMarks[startLine] + s.TShift[startLine] + max := s.EMarks[startLine] + + if pos+1 >= max { + return false + } + + src := s.Src + + if src[pos] != '<' { + return false + } + + pos++ + b := src[pos] + if !htmlSecond(b) { + return false + } + + nextLine := startLine + 1 + + var endCond func(string) bool + + if pos+2 < max && isLetter(b) && rStartCond1.MatchString(src[pos:]) { + endCond = func(s string) bool { + return rEndCond1.MatchString(s) + } + } else if strings.HasPrefix(src[pos:], "!--") { + endCond = func(s string) bool { + return strings.Contains(s, "-->") + } + } else if b == '?' { + endCond = func(s string) bool { + return strings.Contains(s, "?>") + } + } else if b == '!' && pos+1 < max && isUppercaseLetter(src[pos+1]) { + endCond = func(s string) bool { + return strings.Contains(s, ">") + } + } else if strings.HasPrefix(src[pos:], "![CDATA[") { + endCond = func(s string) bool { + return strings.Contains(s, "]]>") + } + } else if pos+2 < max && (isLetter(b) || b == '/' && isLetter(src[pos+1])) { + terminator := true + if rStartCond6.MatchString(src[pos:max]) { + } else if rStartCond7.MatchString(src[pos:max]) { + terminator = false + } else { + return false + } + if silent { + return terminator + } + endCond = func(s string) bool { + return s == "" + } + } else { + return false + } + + if silent { + return true + } + + if !endCond(src[pos:max]) { + for nextLine < endLine { + if s.SCount[nextLine] < s.BlkIndent { + break + } + + pos := s.BMarks[nextLine] + s.TShift[nextLine] + max := s.EMarks[nextLine] + lineText := src[pos:max] + if endCond(lineText) { + if pos != max { + nextLine++ + } + break + } + nextLine++ + } + } + + s.Line = nextLine + s.PushToken(&HTMLBlock{ + Content: s.Lines(startLine, nextLine, s.BlkIndent, true), + Map: [2]int{startLine, nextLine}, + }) + + return true +} |