Implemented headers and paragraphs
This commit is contained in:
parent
a4e5243ab3
commit
93d5949eff
14
README.md
14
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
|
||||
|
||||
|
67
Render.go
67
Render.go
@ -1,6 +1,71 @@
|
||||
package markdown
|
||||
|
||||
import (
|
||||
"html"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
headerStart = []string{"<h1>", "<h2>", "<h3>", "<h4>", "<h5>", "<h6>"}
|
||||
headerEnd = []string{"</h1>", "</h2>", "</h3>", "</h4>", "</h5>", "</h6>"}
|
||||
)
|
||||
|
||||
// Render creates HTML from the supplied markdown text.
|
||||
func Render(markdown string) string {
|
||||
return ""
|
||||
var (
|
||||
out = strings.Builder{}
|
||||
paragraph = strings.Builder{}
|
||||
i = 0
|
||||
lineStart = 0
|
||||
)
|
||||
|
||||
flush := func() {
|
||||
if paragraph.Len() == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
out.WriteString("<p>")
|
||||
out.WriteString(html.EscapeString(paragraph.String()))
|
||||
out.WriteString("</p>")
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,28 @@ import (
|
||||
"git.akyoto.dev/go/markdown"
|
||||
)
|
||||
|
||||
func TestRender(t *testing.T) {
|
||||
html := markdown.Render("# Hello")
|
||||
assert.Equal(t, html, "<h1>Hello</h1>")
|
||||
func TestEmpty(t *testing.T) {
|
||||
assert.Equal(t, markdown.Render(""), "")
|
||||
}
|
||||
|
||||
func TestParagraphs(t *testing.T) {
|
||||
assert.Equal(t, markdown.Render("Text"), "<p>Text</p>")
|
||||
assert.Equal(t, markdown.Render("Text\n"), "<p>Text</p>")
|
||||
assert.Equal(t, markdown.Render("Text\n\n"), "<p>Text</p>")
|
||||
assert.Equal(t, markdown.Render("Text\n\n\n"), "<p>Text</p>")
|
||||
assert.Equal(t, markdown.Render("Line 1\nLine 2"), "<p>Line 1 Line 2</p>")
|
||||
}
|
||||
|
||||
func TestHeader(t *testing.T) {
|
||||
assert.Equal(t, markdown.Render("# Header"), "<h1>Header</h1>")
|
||||
assert.Equal(t, markdown.Render("## Header"), "<h2>Header</h2>")
|
||||
assert.Equal(t, markdown.Render("### Header"), "<h3>Header</h3>")
|
||||
assert.Equal(t, markdown.Render("#### Header"), "<h4>Header</h4>")
|
||||
assert.Equal(t, markdown.Render("##### Header"), "<h5>Header</h5>")
|
||||
assert.Equal(t, markdown.Render("###### Header"), "<h6>Header</h6>")
|
||||
}
|
||||
|
||||
func TestCombined(t *testing.T) {
|
||||
assert.Equal(t, markdown.Render("# Header\nLine 1.\nLine 2.\nLine 3."), "<h1>Header</h1><p>Line 1. Line 2. Line 3.</p>")
|
||||
assert.Equal(t, markdown.Render("# Header 1\nLine 1.\n# Header 2\nLine 2."), "<h1>Header 1</h1><p>Line 1.</p><h1>Header 2</h1><p>Line 2.</p>")
|
||||
}
|
||||
|
13
benchmarks_test.go
Normal file
13
benchmarks_test.go
Normal file
@ -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.")
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user