diff --git a/README.md b/README.md index b395b3f..b3d4f7f 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,8 @@ Markdown renderer. ## Features - +- Headers +- Paragraphs ## Installation @@ -15,16 +16,25 @@ go get git.akyoto.dev/go/markdown ## Usage ```go +html := markdown.Render("# Header") +fmt.Println(html) ``` ## Tests ``` +PASS: TestEmpty +PASS: TestParagraphs +PASS: TestHeader +PASS: TestCombined +coverage: 100.0% of statements ``` ## Benchmarks - +``` +BenchmarkSmall-12 2187232 544.9 ns/op 296 B/op 9 allocs/op +``` ## License diff --git a/Render.go b/Render.go index 3197db0..55c3f83 100644 --- a/Render.go +++ b/Render.go @@ -1,6 +1,71 @@ package markdown +import ( + "html" + "strings" +) + +var ( + headerStart = []string{"
") + out.WriteString(html.EscapeString(paragraph.String())) + out.WriteString("
") + paragraph.Reset() + } + + for { + if i > len(markdown) { + flush() + return out.String() + } + + if i != len(markdown) && markdown[i] != '\n' { + i++ + continue + } + + line := markdown[lineStart:i] + lineStart = i + 1 + i++ + + switch { + case strings.HasPrefix(line, "#"): + flush() + space := strings.IndexByte(line, ' ') + + if space > 0 && space <= 6 { + out.WriteString(headerStart[space-1]) + out.WriteString(html.EscapeString(line[space+1:])) + out.WriteString(headerEnd[space-1]) + } + + default: + if len(line) == 0 { + continue + } + + if paragraph.Len() > 0 { + paragraph.WriteByte(' ') + } + + paragraph.WriteString(line) + } + } } diff --git a/Render_test.go b/Render_test.go index c2ab965..d20a666 100644 --- a/Render_test.go +++ b/Render_test.go @@ -7,7 +7,28 @@ import ( "git.akyoto.dev/go/markdown" ) -func TestRender(t *testing.T) { - html := markdown.Render("# Hello") - assert.Equal(t, html, "Text
") + assert.Equal(t, markdown.Render("Text\n"), "Text
") + assert.Equal(t, markdown.Render("Text\n\n"), "Text
") + assert.Equal(t, markdown.Render("Text\n\n\n"), "Text
") + assert.Equal(t, markdown.Render("Line 1\nLine 2"), "Line 1 Line 2
") +} + +func TestHeader(t *testing.T) { + assert.Equal(t, markdown.Render("# Header"), "Line 1. Line 2. Line 3.
") + assert.Equal(t, markdown.Render("# Header 1\nLine 1.\n# Header 2\nLine 2."), "Line 1.
Line 2.
") } diff --git a/benchmarks_test.go b/benchmarks_test.go new file mode 100644 index 0000000..ffdb413 --- /dev/null +++ b/benchmarks_test.go @@ -0,0 +1,13 @@ +package markdown_test + +import ( + "testing" + + "git.akyoto.dev/go/markdown" +) + +func BenchmarkSmall(b *testing.B) { + for range b.N { + markdown.Render("# Header\nText.\nText.\n# Header\nText.\nText.") + } +}