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 |"), "1 2 1 2
")
}
+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
")