Implemented text formatting

This commit is contained in:
Eduard Urbach 2024-04-02 19:48:35 +02:00
parent a06f513d65
commit 52c995659d
Signed by: akyoto
GPG Key ID: C874F672B1AF20C0
3 changed files with 57 additions and 14 deletions

View File

@ -31,6 +31,8 @@ html := markdown.Render("# Header")
PASS: TestEmpty PASS: TestEmpty
PASS: TestParagraph PASS: TestParagraph
PASS: TestHeader PASS: TestHeader
PASS: TestItalic
PASS: TestBold
PASS: TestLink PASS: TestLink
PASS: TestList PASS: TestList
PASS: TestTables PASS: TestTables
@ -45,9 +47,9 @@ coverage: 100.0% of statements
## Benchmarks ## Benchmarks
``` ```
BenchmarkSmall-12 8846642 135.5 ns/op 32 B/op 1 allocs/op BenchmarkSmall-12 8109500 145.1 ns/op 32 B/op 1 allocs/op
BenchmarkMedium-12 711596 1465 ns/op 512 B/op 1 allocs/op BenchmarkMedium-12 556713 1906 ns/op 512 B/op 1 allocs/op
BenchmarkLarge-12 279253 3874 ns/op 2560 B/op 2 allocs/op BenchmarkLarge-12 218116 4588 ns/op 2560 B/op 2 allocs/op
``` ```
## License ## License

View File

@ -122,7 +122,8 @@ func (r *renderer) processLine(line string) {
return return
} }
line = strings.TrimSpace(line[1:]) if len(line) > 1 && line[1] == ' ' {
line = line[2:]
if r.listLevel == 0 { if r.listLevel == 0 {
r.WriteString("<ul>") r.WriteString("<ul>")
@ -133,6 +134,7 @@ func (r *renderer) processLine(line string) {
r.writeText(line) r.writeText(line)
r.WriteString("</li>") r.WriteString("</li>")
return return
}
case '`': case '`':
if strings.HasPrefix(line, "```") { if strings.HasPrefix(line, "```") {
@ -255,12 +257,14 @@ func (r *renderer) writeText(markdown string) {
textStart = -1 textStart = -1
textEnd = -1 textEnd = -1
urlStart = -1 urlStart = -1
parentheses = 0
codeStart = -1 codeStart = -1
emStart = -1
strongStart = -1
parentheses = 0
) )
for { for {
if i == len(markdown) { if i >= len(markdown) {
r.WriteString(html.EscapeString(markdown[tokenStart:])) r.WriteString(html.EscapeString(markdown[tokenStart:]))
return return
} }
@ -315,6 +319,30 @@ func (r *renderer) writeText(markdown string) {
tokenStart = i tokenStart = i
codeStart = i + 1 codeStart = i + 1
} }
case '*', '_':
if i == emStart {
strongStart = i + 1
emStart = -1
} else if strongStart != -1 {
r.WriteString("<strong>")
r.WriteString(html.EscapeString(markdown[strongStart:i]))
r.WriteString("</strong>")
strongStart = -1
i++
tokenStart = i + 1
} else if emStart != -1 {
r.WriteString("<em>")
r.WriteString(html.EscapeString(markdown[emStart:i]))
r.WriteString("</em>")
emStart = -1
tokenStart = i + 1
} else {
r.WriteString(html.EscapeString(markdown[tokenStart:i]))
tokenStart = i
emStart = i + 1
}
} }
i++ i++

View File

@ -29,6 +29,16 @@ func TestHeader(t *testing.T) {
assert.Equal(t, markdown.Render("###### Header"), "<h6>Header</h6>") assert.Equal(t, markdown.Render("###### Header"), "<h6>Header</h6>")
} }
func TestItalic(t *testing.T) {
assert.Equal(t, markdown.Render("*italic*"), "<p><em>italic</em></p>")
assert.Equal(t, markdown.Render("_italic_"), "<p><em>italic</em></p>")
}
func TestBold(t *testing.T) {
assert.Equal(t, markdown.Render("**bold**"), "<p><strong>bold</strong></p>")
assert.Equal(t, markdown.Render("__bold__"), "<p><strong>bold</strong></p>")
}
func TestLink(t *testing.T) { func TestLink(t *testing.T) {
assert.Equal(t, markdown.Render("[text](https://example.com/)"), "<p><a href=\"https://example.com/\">text</a></p>") assert.Equal(t, markdown.Render("[text](https://example.com/)"), "<p><a href=\"https://example.com/\">text</a></p>")
assert.Equal(t, markdown.Render("[text](https://example.com/"), "<p>[text](https://example.com/</p>") assert.Equal(t, markdown.Render("[text](https://example.com/"), "<p>[text](https://example.com/</p>")
@ -42,6 +52,7 @@ func TestList(t *testing.T) {
assert.Equal(t, markdown.Render("- Entry"), "<ul><li>Entry</li></ul>") assert.Equal(t, markdown.Render("- Entry"), "<ul><li>Entry</li></ul>")
assert.Equal(t, markdown.Render("- Entry 1\n- Entry 2"), "<ul><li>Entry 1</li><li>Entry 2</li></ul>") assert.Equal(t, markdown.Render("- Entry 1\n- Entry 2"), "<ul><li>Entry 1</li><li>Entry 2</li></ul>")
assert.Equal(t, markdown.Render("- Entry 1\n- Entry 2\n- Entry 3"), "<ul><li>Entry 1</li><li>Entry 2</li><li>Entry 3</li></ul>") assert.Equal(t, markdown.Render("- Entry 1\n- Entry 2\n- Entry 3"), "<ul><li>Entry 1</li><li>Entry 2</li><li>Entry 3</li></ul>")
assert.Equal(t, markdown.Render("-"), "<p>-</p>")
} }
func TestTables(t *testing.T) { func TestTables(t *testing.T) {
@ -77,6 +88,8 @@ func TestCombined(t *testing.T) {
assert.Equal(t, markdown.Render("# Title\n\n- Entry 1\n- Entry 2\n\nText."), "<h1>Title</h1><ul><li>Entry 1</li><li>Entry 2</li></ul><p>Text.</p>") assert.Equal(t, markdown.Render("# Title\n\n- Entry 1\n- Entry 2\n\nText."), "<h1>Title</h1><ul><li>Entry 1</li><li>Entry 2</li></ul><p>Text.</p>")
assert.Equal(t, markdown.Render("- Entry\n# Header"), "<ul><li>Entry</li></ul><h1>Header</h1>") assert.Equal(t, markdown.Render("- Entry\n# Header"), "<ul><li>Entry</li></ul><h1>Header</h1>")
assert.Equal(t, markdown.Render("> - Entry\n> # Header"), "<blockquote><ul><li>Entry</li></ul><h1>Header</h1></blockquote>") assert.Equal(t, markdown.Render("> - Entry\n> # Header"), "<blockquote><ul><li>Entry</li></ul><h1>Header</h1></blockquote>")
assert.Equal(t, markdown.Render("> **bold** and *italic* text."), "<blockquote><p><strong>bold</strong> and <em>italic</em> text.</p></blockquote>")
assert.Equal(t, markdown.Render("> __bold__ and _italic_ text."), "<blockquote><p><strong>bold</strong> and <em>italic</em> text.</p></blockquote>")
} }
func TestSecurity(t *testing.T) { func TestSecurity(t *testing.T) {