all repos — grayfriday @ eff64c563f75c50f8af0ec650e719846efff659b

blackfriday fork with a few changes

reduce copying for lists
Russ Ross russ@russross.com
Sat, 25 Jun 2011 15:02:46 -0600
commit

eff64c563f75c50f8af0ec650e719846efff659b

parent

cf97fbd89772bdcef0e088d38e9ce4ecb261ea15

4 files changed, 45 insertions(+), 31 deletions(-)

jump to
M block.goblock.go

@@ -882,20 +882,22 @@ }

// parse ordered or unordered list block func blockList(out *bytes.Buffer, rndr *render, data []byte, flags int) int { - var work bytes.Buffer - - i, j := 0, 0 - for i < len(data) { - j = blockListItem(&work, rndr, data[i:], &flags) - i += j + i := 0 + work := func() bool { + j := 0 + for i < len(data) { + j = blockListItem(out, rndr, data[i:], &flags) + i += j - if j == 0 || flags&LIST_ITEM_END_OF_LIST != 0 { - break + if j == 0 || flags&LIST_ITEM_END_OF_LIST != 0 { + break + } } + return true } if rndr.mk.List != nil { - rndr.mk.List(out, work.Bytes(), flags, rndr.mk.Opaque) + rndr.mk.List(out, work, flags, rndr.mk.Opaque) } return i }
M html.gohtml.go

@@ -123,39 +123,42 @@

func attrEscape(out *bytes.Buffer, src []byte) { org := 0 for i, ch := range src { - // doing this check is a bit faster than falling into - // the switch statement. as the compiler improves, this - // should be unnecessary - if ch != '"' && ch != '&' && ch != '<' && ch != '>' { - continue - } - - switch ch { - case '<': + // using if statements is a bit faster than a switch statement. + // as the compiler improves, this should be unnecessary + // this is only worthwhile because attrEscape is the single + // largest CPU user in normal use + if ch == '"' { if i > org { // copy all the normal characters since the last escape out.Write(src[org:i]) } org = i + 1 - out.WriteString("&lt;") - case '>': + out.WriteString("&quot;") + continue + } + if ch == '&' { if i > org { out.Write(src[org:i]) } org = i + 1 - out.WriteString("&gt;") - case '&': + out.WriteString("&amp;") + continue + } + if ch == '<' { if i > org { out.Write(src[org:i]) } org = i + 1 - out.WriteString("&amp;") - case '"': + out.WriteString("&lt;") + continue + } + if ch == '>' { if i > org { out.Write(src[org:i]) } org = i + 1 - out.WriteString("&quot;") + out.WriteString("&gt;") + continue } } if org < len(src) {

@@ -351,8 +354,10 @@ out.Write(text)

out.WriteString("</td>") } -func htmlList(out *bytes.Buffer, text []byte, flags int, opaque interface{}) { - if out.Len() > 0 { +func htmlList(out *bytes.Buffer, text func() bool, flags int, opaque interface{}) { + marker := out.Len() + + if marker > 0 { out.WriteByte('\n') } if flags&LIST_TYPE_ORDERED != 0 {

@@ -360,7 +365,10 @@ out.WriteString("<ol>\n")

} else { out.WriteString("<ul>\n") } - out.Write(text) + if !text() { + out.Truncate(marker) + return + } if flags&LIST_TYPE_ORDERED != 0 { out.WriteString("</ol>\n") } else {
M latex.golatex.go

@@ -104,13 +104,17 @@ func latexHRule(out *bytes.Buffer, opaque interface{}) {

out.WriteString("\n\\HRule\n") } -func latexList(out *bytes.Buffer, text []byte, flags int, opaque interface{}) { +func latexList(out *bytes.Buffer, text func() bool, flags int, opaque interface{}) { + marker := out.Len() if flags&LIST_TYPE_ORDERED != 0 { out.WriteString("\n\\begin{enumerate}\n") } else { out.WriteString("\n\\begin{itemize}\n") } - out.Write(text) + if !text() { + out.Truncate(marker) + return + } if flags&LIST_TYPE_ORDERED != 0 { out.WriteString("\n\\end{enumerate}\n") } else {
M markdown.gomarkdown.go

@@ -101,7 +101,7 @@ BlockQuote func(out *bytes.Buffer, text []byte, opaque interface{})

BlockHtml func(out *bytes.Buffer, text []byte, 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{}) + List func(out *bytes.Buffer, text func() bool, flags int, opaque interface{}) ListItem func(out *bytes.Buffer, text []byte, flags int, opaque interface{}) Paragraph func(out *bytes.Buffer, text []byte, opaque interface{}) Table func(out *bytes.Buffer, header []byte, body []byte, columnData []int, opaque interface{})