Skip to content

Commit

Permalink
Merge pull request #5 from odknt/feat/task_list
Browse files Browse the repository at this point in the history
Add task list support
  • Loading branch information
sachaos authored Apr 3, 2019
2 parents 3866750 + 3e48c02 commit 52f3a7a
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 1 deletion.
8 changes: 7 additions & 1 deletion handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,5 +137,11 @@ func markdownFileToHTML(filename string) []byte {
panic(err)
}

return blackfriday.Run(bytes, blackfriday.WithExtensions(blackfriday.CommonExtensions))
return blackfriday.Run(
bytes,
blackfriday.WithExtensions(blackfriday.CommonExtensions),
blackfriday.WithRenderer(newRenderer(blackfriday.HTMLRendererParameters{
Flags: blackfriday.CommonHTMLFlags,
})),
)
}
98 changes: 98 additions & 0 deletions renderer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package main

import (
"bytes"
"io"

"github.com/russross/blackfriday/v2"
)

type renderer struct {
*blackfriday.HTMLRenderer

inTaskList bool
}

var (
checkedTag = []byte(`<input type="checkbox" checked="" disabled="">`)
uncheckedTag = []byte(`<input type="checkbox" disabled="">`)

taskListTagOpen = []byte(`<ul class="contains-task-list">`)
taskListTagClose = []byte(`</ul>`)

listItemTagOpen = []byte(`<li class="task-list-item">`)
listItemTagClose = []byte(`</li>`)
)

func newRenderer(params blackfriday.HTMLRendererParameters) *renderer {
return &renderer{
HTMLRenderer: blackfriday.NewHTMLRenderer(params),
}
}

func (r *renderer) RenderNode(w io.Writer, node *blackfriday.Node, entering bool) blackfriday.WalkStatus {
switch node.Type {
case blackfriday.List:
if node.ListFlags == blackfriday.ListItemBeginningOfList {
if entering {
r.inTaskList = r.processTaskList(node)
if r.inTaskList {
w.Write(taskListTagOpen)
return blackfriday.GoToNext
}
} else {
r.inTaskList = false
}
}
case blackfriday.Item:
if r.inTaskList {
if entering {
w.Write(listItemTagOpen)
} else {
w.Write(listItemTagClose)
}
return blackfriday.GoToNext
}
case blackfriday.Text:
if r.inTaskList {
prefix := r.getTaskListItemPrefix(node)
if len(prefix) > 0 {
w.Write(prefix)
node.Literal = node.Literal[3:]
}
}
}
// fallback to blackfriday.Renderer
return r.HTMLRenderer.RenderNode(w, node, entering)
}

func (r *renderer) processTaskList(node *blackfriday.Node) bool {
cur := node.FirstChild
for cur != nil {
child := cur.FirstChild
if child.Type != blackfriday.Paragraph {
continue
}

child = child.FirstChild
if child.Type != blackfriday.Text {
continue
}

prefix := r.getTaskListItemPrefix(child)
if len(prefix) > 0 {
return true
}
cur = cur.Next
}
return false
}

func (r *renderer) getTaskListItemPrefix(node *blackfriday.Node) []byte {
if bytes.HasPrefix(node.Literal, []byte("[ ] ")) {
return uncheckedTag
} else if bytes.HasPrefix(node.Literal, []byte("[x] ")) {
return checkedTag
}
return []byte{}
}

0 comments on commit 52f3a7a

Please sign in to comment.