diff --git a/README.md b/README.md index cb6a627..c283397 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # markdown -Markdown renderer. +A markdown renderer that supports only a subset of the CommonMark spec in order to make the rendering more efficient and the syntax more consistent. ## Features @@ -43,7 +43,9 @@ coverage: 100.0% of statements ## Benchmarks ``` -BenchmarkSmall-12 2421213 494.2 ns/op 248 B/op 5 allocs/op +BenchmarkSmall-12 7223979 164.2 ns/op 64 B/op 2 allocs/op +BenchmarkMedium-12 832531 1310 ns/op 992 B/op 2 allocs/op +BenchmarkLarge-12 295946 3732 ns/op 3712 B/op 3 allocs/op ``` ## License diff --git a/Render.go b/Render.go index df118b7..024803c 100644 --- a/Render.go +++ b/Render.go @@ -10,8 +10,9 @@ var ( headerEnd = []string{"", "", "", "", "", ""} ) +// renderer represents a Markdown to HTML renderer. type renderer struct { - out strings.Builder + out []byte paragraphLevel int quoteLevel int listLevel int @@ -29,15 +30,17 @@ func Render(markdown string) string { lineStart = 0 ) + r.out = make([]byte, 0, nextPowerOf2(uint32(len(markdown)+4))) + for { if i > len(markdown) { r.closeAll() for range r.quoteLevel { - r.out.WriteString("") + r.WriteString("") } - return r.out.String() + return string(r.out) } if i != len(markdown) && markdown[i] != '\n' { @@ -56,15 +59,15 @@ func Render(markdown string) string { func (r *renderer) processLine(line string) { if r.inCodeBlock { if strings.HasPrefix(line, "```") { - r.out.WriteString("") + r.WriteString("") r.inCodeBlock = false r.codeLines = 0 } else { if r.codeLines != 0 { - r.out.WriteByte('\n') + r.WriteByte('\n') } - r.out.WriteString(html.EscapeString(line)) + r.WriteString(html.EscapeString(line)) r.codeLines++ } @@ -82,13 +85,13 @@ func (r *renderer) processLine(line string) { r.closeParagraphs() for range newQuoteLevel - r.quoteLevel { - r.out.WriteString("
") + r.WriteString("
") } } else if newQuoteLevel < r.quoteLevel { r.closeParagraphs() for range r.quoteLevel - newQuoteLevel { - r.out.WriteString("
") + r.WriteString("
") } } @@ -105,9 +108,9 @@ func (r *renderer) processLine(line string) { space := strings.IndexByte(line, ' ') if space > 0 && space <= 6 { - r.out.WriteString(headerStart[space-1]) + r.WriteString(headerStart[space-1]) r.writeText(line[space+1:]) - r.out.WriteString(headerEnd[space-1]) + r.WriteString(headerEnd[space-1]) } return @@ -117,13 +120,13 @@ func (r *renderer) processLine(line string) { line = strings.TrimSpace(line[1:]) if r.listLevel == 0 { - r.out.WriteString("