mirror of
https://github.com/russross/blackfriday.git
synced 2024-03-22 13:40:34 +08:00
experiment: render headers directly to output buffer to avoid a copy; minor speed boost
This commit is contained in:
parent
45ab8d0dc4
commit
cf97fbd897
19
block.go
19
block.go
|
@ -186,10 +186,12 @@ func blockPrefixHeader(out *bytes.Buffer, rndr *render, data []byte) int {
|
|||
end--
|
||||
}
|
||||
if end > i {
|
||||
var work bytes.Buffer
|
||||
parseInline(&work, rndr, data[i:end])
|
||||
if rndr.mk.Header != nil {
|
||||
rndr.mk.Header(out, work.Bytes(), level, rndr.mk.Opaque)
|
||||
work := func() bool {
|
||||
parseInline(out, rndr, data[i:end])
|
||||
return true
|
||||
}
|
||||
rndr.mk.Header(out, work, level, rndr.mk.Opaque)
|
||||
}
|
||||
}
|
||||
return skip
|
||||
|
@ -1071,9 +1073,14 @@ func blockParagraph(out *bytes.Buffer, rndr *render, data []byte) int {
|
|||
renderParagraph(out, rndr, data[:prev])
|
||||
|
||||
// render the header
|
||||
var work bytes.Buffer
|
||||
parseInline(&work, rndr, data[prev:i-1])
|
||||
rndr.mk.Header(out, work.Bytes(), level, rndr.mk.Opaque)
|
||||
// this ugly, convoluted closure avoids forcing variables onto the heap
|
||||
work := func(o *bytes.Buffer, r *render, d []byte) func() bool {
|
||||
return func() bool {
|
||||
parseInline(o, r, d)
|
||||
return true
|
||||
}
|
||||
}(out, rndr, data[prev:i-1])
|
||||
rndr.mk.Header(out, work, level, rndr.mk.Opaque)
|
||||
|
||||
// find the end of the underline
|
||||
for ; i < len(data) && data[i] != '\n'; i++ {
|
||||
|
|
19
html.go
19
html.go
|
@ -163,10 +163,11 @@ func attrEscape(out *bytes.Buffer, src []byte) {
|
|||
}
|
||||
}
|
||||
|
||||
func htmlHeader(out *bytes.Buffer, text []byte, level int, opaque interface{}) {
|
||||
func htmlHeader(out *bytes.Buffer, text func() bool, level int, opaque interface{}) {
|
||||
options := opaque.(*htmlOptions)
|
||||
marker := out.Len()
|
||||
|
||||
if out.Len() > 0 {
|
||||
if marker > 0 {
|
||||
out.WriteByte('\n')
|
||||
}
|
||||
|
||||
|
@ -177,7 +178,10 @@ func htmlHeader(out *bytes.Buffer, text []byte, level int, opaque interface{}) {
|
|||
out.WriteString(fmt.Sprintf("<h%d>", level))
|
||||
}
|
||||
|
||||
out.Write(text)
|
||||
if !text() {
|
||||
out.Truncate(marker)
|
||||
return
|
||||
}
|
||||
out.WriteString(fmt.Sprintf("</h%d>\n", level))
|
||||
}
|
||||
|
||||
|
@ -572,8 +576,10 @@ func htmlNormalText(out *bytes.Buffer, text []byte, opaque interface{}) {
|
|||
attrEscape(out, text)
|
||||
}
|
||||
|
||||
func htmlTocHeader(out *bytes.Buffer, text []byte, level int, opaque interface{}) {
|
||||
func htmlTocHeader(out *bytes.Buffer, text func() bool, level int, opaque interface{}) {
|
||||
options := opaque.(*htmlOptions)
|
||||
marker := out.Len()
|
||||
|
||||
for level > options.tocData.currentLevel {
|
||||
if options.tocData.currentLevel > 0 {
|
||||
out.WriteString("<li>")
|
||||
|
@ -595,8 +601,9 @@ func htmlTocHeader(out *bytes.Buffer, text []byte, level int, opaque interface{}
|
|||
out.WriteString("\">")
|
||||
options.tocData.headerCount++
|
||||
|
||||
if len(text) > 0 {
|
||||
out.Write(text)
|
||||
if !text() {
|
||||
out.Truncate(marker)
|
||||
return
|
||||
}
|
||||
out.WriteString("</a></li>\n")
|
||||
}
|
||||
|
|
9
latex.go
9
latex.go
|
@ -76,7 +76,9 @@ func latexBlockQuote(out *bytes.Buffer, text []byte, opaque interface{}) {
|
|||
|
||||
//BlockHtml func(out *bytes.Buffer, text []byte, opaque interface{})
|
||||
|
||||
func latexHeader(out *bytes.Buffer, text []byte, level int, opaque interface{}) {
|
||||
func latexHeader(out *bytes.Buffer, text func() bool, level int, opaque interface{}) {
|
||||
marker := out.Len()
|
||||
|
||||
switch level {
|
||||
case 1:
|
||||
out.WriteString("\n\\section{")
|
||||
|
@ -91,7 +93,10 @@ func latexHeader(out *bytes.Buffer, text []byte, level int, opaque interface{})
|
|||
case 6:
|
||||
out.WriteString("\n\\textbf{")
|
||||
}
|
||||
out.Write(text)
|
||||
if !text() {
|
||||
out.Truncate(marker)
|
||||
return
|
||||
}
|
||||
out.WriteString("}\n")
|
||||
}
|
||||
|
||||
|
|
|
@ -99,7 +99,7 @@ type Renderer struct {
|
|||
BlockCode func(out *bytes.Buffer, text []byte, lang string, opaque interface{})
|
||||
BlockQuote func(out *bytes.Buffer, text []byte, opaque interface{})
|
||||
BlockHtml func(out *bytes.Buffer, text []byte, opaque interface{})
|
||||
Header func(out *bytes.Buffer, text []byte, level int, opaque interface{})
|
||||
Header func(out *bytes.Buffer, text func() bool, level int, opaque interface{})
|
||||
HRule func(out *bytes.Buffer, opaque interface{})
|
||||
List func(out *bytes.Buffer, text []byte, flags int, opaque interface{})
|
||||
ListItem func(out *bytes.Buffer, text []byte, flags int, opaque interface{})
|
||||
|
|
Loading…
Reference in New Issue
Block a user