mirror of
https://github.com/danog/gojekyll.git
synced 2024-11-26 23:14:40 +01:00
Implement markdown=1
This commit is contained in:
parent
63ca72592e
commit
440104d56e
@ -1,6 +1,13 @@
|
||||
package pipelines
|
||||
|
||||
import "github.com/russross/blackfriday"
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"regexp"
|
||||
|
||||
"github.com/russross/blackfriday"
|
||||
"golang.org/x/net/html"
|
||||
)
|
||||
|
||||
const blackfridayFlags = 0 |
|
||||
blackfriday.HTML_USE_XHTML |
|
||||
@ -22,8 +29,88 @@ const blackfridayExtensions = 0 |
|
||||
// added relative to commonExtensions
|
||||
blackfriday.EXTENSION_AUTO_HEADER_IDS
|
||||
|
||||
func markdownRenderer(input []byte) []byte {
|
||||
func renderMarkdown(md []byte) []byte {
|
||||
renderer := blackfriday.HtmlRenderer(blackfridayFlags, "", "")
|
||||
return blackfriday.MarkdownOptions(input, renderer, blackfriday.Options{
|
||||
html := blackfriday.MarkdownOptions(md, renderer, blackfriday.Options{
|
||||
Extensions: blackfridayExtensions})
|
||||
html, err := renderInnerMarkdown(html)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return html
|
||||
}
|
||||
|
||||
var markdownAttrRE = regexp.MustCompile(`\s*markdown\s*=\s*("1"|'1'|1)\s*`)
|
||||
|
||||
func renderInnerMarkdown(b []byte) ([]byte, error) {
|
||||
z := html.NewTokenizer(bytes.NewReader(b))
|
||||
buf := new(bytes.Buffer)
|
||||
outer:
|
||||
for {
|
||||
tt := z.Next()
|
||||
switch tt {
|
||||
case html.ErrorToken:
|
||||
if z.Err() == io.EOF {
|
||||
break outer
|
||||
}
|
||||
return nil, z.Err()
|
||||
case html.StartTagToken:
|
||||
if hasAttr(z) {
|
||||
tag := markdownAttrRE.ReplaceAll(z.Raw(), []byte(" "))
|
||||
tag = bytes.Replace(tag, []byte(" >"), []byte(">"), 1)
|
||||
_, err := buf.Write(tag)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := processInnerMarkdown(buf, z); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// the above leaves z set to the end token
|
||||
}
|
||||
}
|
||||
_, err := buf.Write(z.Raw())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
func hasAttr(z *html.Tokenizer) bool {
|
||||
for {
|
||||
k, v, more := z.TagAttr()
|
||||
switch {
|
||||
case string(k) == "markdown" && string(v) == "1":
|
||||
return true
|
||||
case !more:
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func processInnerMarkdown(w io.Writer, z *html.Tokenizer) error {
|
||||
buf := new(bytes.Buffer)
|
||||
depth := 1
|
||||
loop:
|
||||
for {
|
||||
tt := z.Next()
|
||||
switch tt {
|
||||
case html.ErrorToken:
|
||||
return z.Err()
|
||||
case html.StartTagToken:
|
||||
depth++
|
||||
case html.EndTagToken:
|
||||
depth--
|
||||
if depth == 0 {
|
||||
break loop
|
||||
}
|
||||
}
|
||||
_, err := buf.Write(z.Raw())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
html := renderMarkdown(buf.Bytes())
|
||||
_, err := w.Write(html)
|
||||
return err
|
||||
}
|
||||
|
19
pipelines/markdown_test.go
Normal file
19
pipelines/markdown_test.go
Normal file
@ -0,0 +1,19 @@
|
||||
package pipelines
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func renderMarkdownString(s string) string {
|
||||
return string(renderMarkdown([]byte(s)))
|
||||
}
|
||||
|
||||
func TestRenderMarkdown(t *testing.T) {
|
||||
require.Equal(t, "<p><em>b</em></p>\n", renderMarkdownString("*b*"))
|
||||
require.Equal(t, "<div>*b*</div>\n", renderMarkdownString("<div>*b*</div>"))
|
||||
require.Equal(t, "<div a=1><p><em>b</em></p>\n</div>\n", renderMarkdownString(`<div a=1 markdown="1">*b*</div>`))
|
||||
require.Equal(t, "<div a=1><p><em>b</em></p>\n</div>\n", renderMarkdownString(`<div a=1 markdown='1'>*b*</div>`))
|
||||
require.Equal(t, "<div a=1><p><em>b</em></p>\n</div>\n", renderMarkdownString(`<div a=1 markdown=1>*b*</div>`))
|
||||
}
|
@ -70,7 +70,7 @@ func (p *Pipeline) Render(w io.Writer, src []byte, vars liquid.Bindings, filenam
|
||||
return err
|
||||
}
|
||||
if p.cfg.IsMarkdown(filename) {
|
||||
src = markdownRenderer(src)
|
||||
src = renderMarkdown(src)
|
||||
}
|
||||
_, err = w.Write(src)
|
||||
return err
|
||||
|
Loading…
Reference in New Issue
Block a user