reduce copying for lists
Russ Ross russ@russross.com
Sat, 25 Jun 2011 15:02:46 -0600
4 files changed,
45 insertions(+),
31 deletions(-)
M
block.go
→
block.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.go
→
html.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("<") - case '>': + out.WriteString(""") + continue + } + if ch == '&' { if i > org { out.Write(src[org:i]) } org = i + 1 - out.WriteString(">") - case '&': + out.WriteString("&") + continue + } + if ch == '<' { if i > org { out.Write(src[org:i]) } org = i + 1 - out.WriteString("&") - case '"': + out.WriteString("<") + continue + } + if ch == '>' { if i > org { out.Write(src[org:i]) } org = i + 1 - out.WriteString(""") + out.WriteString(">") + 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.go
→
latex.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.go
→
markdown.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{})