HTML render fix

release/v1.15
Unknwon 2015-11-20 05:37:51 -05:00
parent 74dfe439c2
commit 126228d146
1 changed files with 32 additions and 8 deletions

View File

@ -14,6 +14,7 @@ import (
"regexp"
"strings"
"github.com/Unknwon/com"
"github.com/russross/blackfriday"
"golang.org/x/net/html"
@ -99,13 +100,26 @@ func (options *CustomRender) Link(out *bytes.Buffer, link []byte, title []byte,
options.Renderer.Link(out, link, title, content)
}
var (
svgSuffix = []byte(".svg")
svgSuffixWithMark = []byte(".svg?")
)
func (options *CustomRender) Image(out *bytes.Buffer, link []byte, title []byte, alt []byte) {
prefix := strings.Replace(options.urlPrefix, "/src/", "/raw/", 1)
if len(link) > 0 && !isLink(link) {
if link[0] != '/' {
prefix += "/"
if len(link) > 0 {
if isLink(link) {
// External link with .svg suffix usually means CI status.
if bytes.HasSuffix(link, svgSuffix) || bytes.Contains(link, svgSuffixWithMark) {
options.Renderer.Image(out, link, title, alt)
return
}
} else {
if link[0] != '/' {
prefix += "/"
}
link = []byte(prefix + string(link))
}
link = []byte(prefix + string(link))
}
out.WriteString(`<a href="`)
@ -236,12 +250,16 @@ var (
rightAngleBracket = []byte(">")
)
var noEndTags = []string{"img", "input", "br", "hr"}
// PostProcessMarkdown treats different types of HTML differently,
// and only renders special links for plain text blocks.
func PostProcessMarkdown(rawHtml []byte, urlPrefix string) []byte {
var startTag string
startTags := make([]string, 0, 5)
var buf bytes.Buffer
tokenizer := html.NewTokenizer(bytes.NewReader(rawHtml))
OUTER_LOOP:
for html.ErrorToken != tokenizer.Next() {
token := tokenizer.Token()
switch token.Type {
@ -249,26 +267,32 @@ func PostProcessMarkdown(rawHtml []byte, urlPrefix string) []byte {
buf.Write(RenderSpecialLink([]byte(token.String()), urlPrefix))
case html.StartTagToken:
startTag = token.Data
buf.WriteString(token.String())
tagName := token.Data
// If this is an excluded tag, we skip processing all output until a close tag is encountered.
if strings.EqualFold("a", tagName) || strings.EqualFold("code", tagName) || strings.EqualFold("pre", tagName) {
for html.ErrorToken != tokenizer.Next() {
token = tokenizer.Token()
// Copy the token to the output verbatim
buf.WriteString(token.String())
// If this is the close tag, we are done
if html.EndTagToken == token.Type && strings.EqualFold(tagName, token.Data) {
if token.Type == html.EndTagToken && strings.EqualFold(tagName, token.Data) {
break
}
}
continue OUTER_LOOP
}
if !com.IsSliceContainsStr(noEndTags, token.Data) {
startTags = append(startTags, token.Data)
}
case html.EndTagToken:
buf.Write(leftAngleBracket)
buf.WriteString(startTag)
buf.WriteString(startTags[len(startTags)-1])
buf.Write(rightAngleBracket)
startTags = startTags[:len(startTags)-1]
default:
buf.WriteString(token.String())
}