From f75ea823a98bd078497edef8d809f18f3f442d91 Mon Sep 17 00:00:00 2001 From: Eduard Urbach Date: Mon, 1 Apr 2024 21:27:10 +0200 Subject: [PATCH] Implemented code blocks --- README.md | 9 +++++++-- Render.go | 38 ++++++++++++++++++++++++++++++++++++++ Render_test.go | 5 +++++ 3 files changed, 50 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index cbadd97..cb6a627 100644 --- a/README.md +++ b/README.md @@ -4,11 +4,13 @@ Markdown renderer. ## Features +- Code - Links - Lists - Headers - Paragraphs - Quotes +- Tables ## Installation @@ -26,9 +28,12 @@ html := markdown.Render("# Header") ``` PASS: TestEmpty -PASS: TestParagraphs +PASS: TestParagraph PASS: TestHeader PASS: TestLink +PASS: TestList +PASS: TestTables +PASS: TestCode PASS: TestQuote PASS: TestCombined PASS: TestSecurity @@ -38,7 +43,7 @@ coverage: 100.0% of statements ## 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 diff --git a/Render.go b/Render.go index a9c7a49..df118b7 100644 --- a/Render.go +++ b/Render.go @@ -16,7 +16,9 @@ type renderer struct { quoteLevel int listLevel int tableLevel int + codeLines int tableHeaderWritten bool + inCodeBlock bool } // Render creates HTML from the supplied markdown text. @@ -52,6 +54,23 @@ func Render(markdown string) string { } func (r *renderer) processLine(line string) { + if r.inCodeBlock { + if strings.HasPrefix(line, "```") { + r.out.WriteString("") + 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 for strings.HasPrefix(line, ">") { @@ -107,6 +126,25 @@ func (r *renderer) processLine(line string) { r.out.WriteString("") return + case '`': + if strings.HasPrefix(line, "```") { + language := line[3:] + + if !r.inCodeBlock { + if language != "" { + r.out.WriteString("
")
+				} else {
+					r.out.WriteString("
")
+				}
+
+				r.inCodeBlock = true
+			}
+
+			return
+		}
+
 	case '|':
 		r.closeParagraphs()
 		line = line[1:]
diff --git a/Render_test.go b/Render_test.go
index c9718ee..30a2cac 100644
--- a/Render_test.go
+++ b/Render_test.go
@@ -49,6 +49,11 @@ func TestTables(t *testing.T) {
 	assert.Equal(t, markdown.Render("| 1 | 2 |\n| --- | --- |\n| 1 | 2 |"), "
12
12
") } +func TestCode(t *testing.T) { + assert.Equal(t, markdown.Render("```\nText\n```"), "
Text
") + assert.Equal(t, markdown.Render("```go\ntype A struct {\n\t\n}\n```"), "
type A struct {\n\t\n}
") +} + func TestQuote(t *testing.T) { assert.Equal(t, markdown.Render("> Line"), "

Line

") assert.Equal(t, markdown.Render("> Line 1\n> Line 2"), "

Line 1 Line 2

")