Implemented code blocks

This commit is contained in:
Eduard Urbach 2024-04-01 21:27:10 +02:00
parent e19a41c792
commit f75ea823a9
Signed by: akyoto
GPG Key ID: C874F672B1AF20C0
3 changed files with 50 additions and 2 deletions

View File

@ -4,11 +4,13 @@ Markdown renderer.
## Features ## Features
- Code
- Links - Links
- Lists - Lists
- Headers - Headers
- Paragraphs - Paragraphs
- Quotes - Quotes
- Tables
## Installation ## Installation
@ -26,9 +28,12 @@ html := markdown.Render("# Header")
``` ```
PASS: TestEmpty PASS: TestEmpty
PASS: TestParagraphs PASS: TestParagraph
PASS: TestHeader PASS: TestHeader
PASS: TestLink PASS: TestLink
PASS: TestList
PASS: TestTables
PASS: TestCode
PASS: TestQuote PASS: TestQuote
PASS: TestCombined PASS: TestCombined
PASS: TestSecurity PASS: TestSecurity
@ -38,7 +43,7 @@ coverage: 100.0% of statements
## Benchmarks ## Benchmarks
``` ```
BenchmarkSmall-12 2411152 489.1 ns/op 248 B/op 5 allocs/op BenchmarkSmall-12 2421213 494.2 ns/op 248 B/op 5 allocs/op
``` ```
## License ## License

View File

@ -16,7 +16,9 @@ type renderer struct {
quoteLevel int quoteLevel int
listLevel int listLevel int
tableLevel int tableLevel int
codeLines int
tableHeaderWritten bool tableHeaderWritten bool
inCodeBlock bool
} }
// Render creates HTML from the supplied markdown text. // Render creates HTML from the supplied markdown text.
@ -52,6 +54,23 @@ func Render(markdown string) string {
} }
func (r *renderer) processLine(line string) { func (r *renderer) processLine(line string) {
if r.inCodeBlock {
if strings.HasPrefix(line, "```") {
r.out.WriteString("</code></pre>")
r.inCodeBlock = false
r.codeLines = 0
} else {
if r.codeLines != 0 {
r.out.WriteByte('\n')
}
r.out.WriteString(html.EscapeString(line))
r.codeLines++
}
return
}
newQuoteLevel := 0 newQuoteLevel := 0
for strings.HasPrefix(line, ">") { for strings.HasPrefix(line, ">") {
@ -107,6 +126,25 @@ func (r *renderer) processLine(line string) {
r.out.WriteString("</li>") r.out.WriteString("</li>")
return return
case '`':
if strings.HasPrefix(line, "```") {
language := line[3:]
if !r.inCodeBlock {
if language != "" {
r.out.WriteString("<pre><code class=\"language-")
r.out.WriteString(html.EscapeString(language))
r.out.WriteString("\">")
} else {
r.out.WriteString("<pre><code>")
}
r.inCodeBlock = true
}
return
}
case '|': case '|':
r.closeParagraphs() r.closeParagraphs()
line = line[1:] line = line[1:]

View File

@ -49,6 +49,11 @@ func TestTables(t *testing.T) {
assert.Equal(t, markdown.Render("| 1 | 2 |\n| --- | --- |\n| 1 | 2 |"), "<table><thead><tr><th>1</th><th>2</th></tr></thead><tbody><tr><td>1</td><td>2</td></tr></tbody></table>") assert.Equal(t, markdown.Render("| 1 | 2 |\n| --- | --- |\n| 1 | 2 |"), "<table><thead><tr><th>1</th><th>2</th></tr></thead><tbody><tr><td>1</td><td>2</td></tr></tbody></table>")
} }
func TestCode(t *testing.T) {
assert.Equal(t, markdown.Render("```\nText\n```"), "<pre><code>Text</code></pre>")
assert.Equal(t, markdown.Render("```go\ntype A struct {\n\t\n}\n```"), "<pre><code class=\"language-go\">type A struct {\n\t\n}</code></pre>")
}
func TestQuote(t *testing.T) { func TestQuote(t *testing.T) {
assert.Equal(t, markdown.Render("> Line"), "<blockquote><p>Line</p></blockquote>") assert.Equal(t, markdown.Render("> Line"), "<blockquote><p>Line</p></blockquote>")
assert.Equal(t, markdown.Render("> Line 1\n> Line 2"), "<blockquote><p>Line 1 Line 2</p></blockquote>") assert.Equal(t, markdown.Render("> Line 1\n> Line 2"), "<blockquote><p>Line 1 Line 2</p></blockquote>")