diff --git a/README.md b/README.md index b59879e..c5f42be 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,7 @@ Markdown renderer. ## Features - Links +- Lists - Headers - Paragraphs - Quotes @@ -37,7 +38,7 @@ coverage: 100.0% of statements ## Benchmarks ``` -BenchmarkSmall-12 2425053 492.8 ns/op 248 B/op 5 allocs/op +BenchmarkSmall-12 2585194 462.4 ns/op 248 B/op 5 allocs/op ``` ## License diff --git a/Render.go b/Render.go index 1447a87..d13efe2 100644 --- a/Render.go +++ b/Render.go @@ -14,6 +14,7 @@ type renderer struct { out strings.Builder paragraphLevel int quoteLevel int + listLevel int } // Render creates HTML from the supplied markdown text. @@ -26,7 +27,7 @@ func Render(markdown string) string { for { if i > len(markdown) { - r.closeParagraphs() + r.closeAll() for range r.quoteLevel { r.out.WriteString("") @@ -72,8 +73,14 @@ func (r *renderer) processLine(line string) { r.quoteLevel = newQuoteLevel - if strings.HasPrefix(line, "#") { - r.closeParagraphs() + if len(line) == 0 { + r.closeAll() + return + } + + switch line[0] { + case '#': + r.closeAll() space := strings.IndexByte(line, ' ') if space > 0 && space <= 6 { @@ -83,10 +90,19 @@ func (r *renderer) processLine(line string) { } return - } - if len(line) == 0 { + case '-', '*': r.closeParagraphs() + line = strings.TrimSpace(line[1:]) + + if r.listLevel == 0 { + r.out.WriteString("
Prefix text suffix.
") } +func TestList(t *testing.T) { + assert.Equal(t, markdown.Render("- Entry"), "") assert.Equal(t, markdown.Render("> Line 1\n> Line 2"), "Line
") @@ -51,6 +57,9 @@ func TestCombined(t *testing.T) { assert.Equal(t, markdown.Render("# Header\nLine 1.\nLine 2.\nLine 3."), "Line 1 Line 2
Line 1. Line 2. Line 3.
") assert.Equal(t, markdown.Render("# Header 1\nLine 1.\n# Header 2\nLine 2."), "Line 1.
Line 2.
") assert.Equal(t, markdown.Render("# [Header Link](https://example.com/)"), "Text.
") + assert.Equal(t, markdown.Render("- Entry\n# Header"), "") } func TestSecurity(t *testing.T) {
- Entry
Header