Implemented tables
This commit is contained in:
parent
8e009702c2
commit
e19a41c792
@ -38,7 +38,7 @@ coverage: 100.0% of statements
|
|||||||
## Benchmarks
|
## Benchmarks
|
||||||
|
|
||||||
```
|
```
|
||||||
BenchmarkSmall-12 2585194 462.4 ns/op 248 B/op 5 allocs/op
|
BenchmarkSmall-12 2411152 489.1 ns/op 248 B/op 5 allocs/op
|
||||||
```
|
```
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
66
Render.go
66
Render.go
@ -11,10 +11,12 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type renderer struct {
|
type renderer struct {
|
||||||
out strings.Builder
|
out strings.Builder
|
||||||
paragraphLevel int
|
paragraphLevel int
|
||||||
quoteLevel int
|
quoteLevel int
|
||||||
listLevel int
|
listLevel int
|
||||||
|
tableLevel int
|
||||||
|
tableHeaderWritten bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render creates HTML from the supplied markdown text.
|
// Render creates HTML from the supplied markdown text.
|
||||||
@ -104,6 +106,51 @@ func (r *renderer) processLine(line string) {
|
|||||||
r.writeText(line)
|
r.writeText(line)
|
||||||
r.out.WriteString("</li>")
|
r.out.WriteString("</li>")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
case '|':
|
||||||
|
r.closeParagraphs()
|
||||||
|
line = line[1:]
|
||||||
|
|
||||||
|
if r.tableLevel == 0 {
|
||||||
|
r.out.WriteString("<table><thead>")
|
||||||
|
r.tableLevel++
|
||||||
|
}
|
||||||
|
|
||||||
|
column := 0
|
||||||
|
|
||||||
|
for {
|
||||||
|
pipe := strings.IndexByte(line, '|')
|
||||||
|
|
||||||
|
if pipe == -1 {
|
||||||
|
r.out.WriteString("</tr>")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
content := strings.TrimSpace(line[:pipe])
|
||||||
|
|
||||||
|
if strings.HasPrefix(content, "---") {
|
||||||
|
r.out.WriteString("</thead><tbody>")
|
||||||
|
r.tableHeaderWritten = true
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if column == 0 {
|
||||||
|
r.out.WriteString("<tr>")
|
||||||
|
}
|
||||||
|
|
||||||
|
if r.tableHeaderWritten {
|
||||||
|
r.out.WriteString("<td>")
|
||||||
|
r.writeText(content)
|
||||||
|
r.out.WriteString("</td>")
|
||||||
|
} else {
|
||||||
|
r.out.WriteString("<th>")
|
||||||
|
r.writeText(content)
|
||||||
|
r.out.WriteString("</th>")
|
||||||
|
}
|
||||||
|
|
||||||
|
line = line[pipe+1:]
|
||||||
|
column++
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if r.paragraphLevel == 0 {
|
if r.paragraphLevel == 0 {
|
||||||
@ -121,6 +168,7 @@ func (r *renderer) processLine(line string) {
|
|||||||
func (r *renderer) closeAll() {
|
func (r *renderer) closeAll() {
|
||||||
r.closeLists()
|
r.closeLists()
|
||||||
r.closeParagraphs()
|
r.closeParagraphs()
|
||||||
|
r.closeTables()
|
||||||
}
|
}
|
||||||
|
|
||||||
// closeParagraphs closes open paragraphs.
|
// closeParagraphs closes open paragraphs.
|
||||||
@ -141,6 +189,16 @@ func (r *renderer) closeLists() {
|
|||||||
r.listLevel = 0
|
r.listLevel = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// closeTables closes open tables.
|
||||||
|
func (r *renderer) closeTables() {
|
||||||
|
for range r.tableLevel {
|
||||||
|
r.out.WriteString("</tbody></table>")
|
||||||
|
}
|
||||||
|
|
||||||
|
r.tableLevel = 0
|
||||||
|
r.tableHeaderWritten = false
|
||||||
|
}
|
||||||
|
|
||||||
// writeText converts inline markdown to HTML.
|
// writeText converts inline markdown to HTML.
|
||||||
func (r *renderer) writeText(markdown string) {
|
func (r *renderer) writeText(markdown string) {
|
||||||
var (
|
var (
|
||||||
|
@ -44,6 +44,11 @@ func TestList(t *testing.T) {
|
|||||||
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>")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestTables(t *testing.T) {
|
||||||
|
assert.Equal(t, markdown.Render("| Head |\n| --- |\n| Body |"), "<table><thead><tr><th>Head</th></tr></thead><tbody><tr><td>Body</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 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>")
|
||||||
|
Loading…
Reference in New Issue
Block a user