shithub: hugo

Download patch

ref: 563a6302a0a27f1b8412d4ab621e336f83159727
parent: d4acacd4f50a6c0c25c22e7cc989f196bd225fd5
author: Anthony Fok <[email protected]>
date: Fri Jan 30 02:17:50 EST 2015

Very experimental support for mmark

Either name the content files as `*.mmark`,
or add `markup = "mmark"` in the front matter
of your `*.md` content files.

--- a/helpers/content.go
+++ b/helpers/content.go
@@ -22,6 +22,7 @@
 	"html/template"
 	"os/exec"
 
+	"github.com/miekg/mmark"
 	"github.com/russross/blackfriday"
 	bp "github.com/spf13/hugo/bufferpool"
 	jww "github.com/spf13/jwalterweatherman"
@@ -74,6 +75,19 @@
 
 var stripHTMLReplacer = strings.NewReplacer("\n", " ", "</p>", "\n", "<br>", "\n", "<br />", "\n")
 
+var mmarkExtensionMap = map[string]int{
+	"tables":                 mmark.EXTENSION_TABLES,
+	"fencedCode":             mmark.EXTENSION_FENCED_CODE,
+	"autolink":               mmark.EXTENSION_AUTOLINK,
+	"laxHtmlBlocks":          mmark.EXTENSION_LAX_HTML_BLOCKS,
+	"spaceHeaders":           mmark.EXTENSION_SPACE_HEADERS,
+	"hardLineBreak":          mmark.EXTENSION_HARD_LINE_BREAK,
+	"footnotes":              mmark.EXTENSION_FOOTNOTES,
+	"noEmptyLineBeforeBlock": mmark.EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK,
+	"headerIds":              mmark.EXTENSION_HEADER_IDS,
+	"autoHeaderIds":          mmark.EXTENSION_AUTO_HEADER_IDS,
+}
+
 // StripHTML accepts a string, strips out all HTML tags and returns it.
 func StripHTML(s string) string {
 
@@ -174,6 +188,61 @@
 		getMarkdownExtensions(ctx))
 }
 
+// mmark
+func GetMmarkHtmlRenderer(defaultFlags int, ctx *RenderingContext) mmark.Renderer {
+	renderParameters := mmark.HtmlRendererParameters{
+		FootnoteAnchorPrefix:       viper.GetString("FootnoteAnchorPrefix"),
+		FootnoteReturnLinkContents: viper.GetString("FootnoteReturnLinkContents"),
+	}
+
+	b := len(ctx.DocumentID) != 0
+
+	if b && !ctx.getConfig().PlainIDAnchors {
+		renderParameters.FootnoteAnchorPrefix = ctx.DocumentID + ":" + renderParameters.FootnoteAnchorPrefix
+		// renderParameters.HeaderIDSuffix = ":" + ctx.DocumentId
+	}
+
+	htmlFlags := defaultFlags
+	htmlFlags |= mmark.HTML_FOOTNOTE_RETURN_LINKS
+
+	return mmark.HtmlRendererWithParameters(htmlFlags, "", "", renderParameters)
+}
+
+func GetMmarkExtensions(ctx RenderingContext) int {
+	flags := 0
+	flags |= mmark.EXTENSION_TABLES
+	flags |= mmark.EXTENSION_FENCED_CODE
+	flags |= mmark.EXTENSION_AUTOLINK
+	flags |= mmark.EXTENSION_SPACE_HEADERS
+	flags |= mmark.EXTENSION_CITATION
+	flags |= mmark.EXTENSION_TITLEBLOCK_TOML
+	flags |= mmark.EXTENSION_HEADER_IDS
+	flags |= mmark.EXTENSION_AUTO_HEADER_IDS
+	flags |= mmark.EXTENSION_UNIQUE_HEADER_IDS
+	flags |= mmark.EXTENSION_FOOTNOTES
+	flags |= mmark.EXTENSION_SHORT_REF
+	flags |= mmark.EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK
+	flags |= mmark.EXTENSION_INCLUDE
+
+	for _, extension := range ctx.getConfig().Extensions {
+		if flag, ok := mmarkExtensionMap[extension]; ok {
+			flags |= flag
+		}
+	}
+	return flags
+}
+
+func MmarkRender(ctx *RenderingContext) []byte {
+	return mmark.Parse(ctx.Content, GetMmarkHtmlRenderer(0, ctx),
+		GetMmarkExtensions(*ctx)).Bytes()
+}
+
+func MmarkRenderWithTOC(ctx *RenderingContext) []byte {
+	return mmark.Parse(ctx.Content,
+		GetMmarkHtmlRenderer(0, ctx),
+		GetMmarkExtensions(*ctx)).Bytes()
+}
+
 // ExtractTOC extracts Table of Contents from content.
 func ExtractTOC(content []byte) (newcontent []byte, toc []byte) {
 	origContent := make([]byte, len(content))
@@ -238,6 +307,8 @@
 		return markdownRenderWithTOC(ctx)
 	case "asciidoc":
 		return []byte(GetAsciidocContent(ctx.Content))
+	case "mmark":
+		return MmarkRenderWithTOC(ctx)
 	case "rst":
 		return []byte(GetRstContent(ctx.Content))
 	}
@@ -252,6 +323,8 @@
 		return markdownRender(ctx)
 	case "asciidoc":
 		return []byte(GetAsciidocContent(ctx.Content))
+	case "mmark":
+		return MmarkRender(ctx)
 	case "rst":
 		return []byte(GetRstContent(ctx.Content))
 	}
--- a/helpers/general.go
+++ b/helpers/general.go
@@ -19,10 +19,6 @@
 	"encoding/hex"
 	"errors"
 	"fmt"
-	"github.com/spf13/cast"
-	bp "github.com/spf13/hugo/bufferpool"
-	jww "github.com/spf13/jwalterweatherman"
-	"github.com/spf13/viper"
 	"io"
 	"net"
 	"path/filepath"
@@ -29,6 +25,11 @@
 	"reflect"
 	"strings"
 	"sync"
+
+	"github.com/spf13/cast"
+	bp "github.com/spf13/hugo/bufferpool"
+	jww "github.com/spf13/jwalterweatherman"
+	"github.com/spf13/viper"
 )
 
 // Filepath separator defined by os.Separator.
@@ -66,6 +67,8 @@
 		return "markdown"
 	case "asciidoc", "adoc", "ad":
 		return "asciidoc"
+	case "mmark":
+		return "mmark"
 	case "rst":
 		return "rst"
 	case "html", "htm":
--- a/helpers/general_test.go
+++ b/helpers/general_test.go
@@ -21,6 +21,7 @@
 		{"adoc", "asciidoc"},
 		{"ad", "asciidoc"},
 		{"rst", "rst"},
+		{"mmark", "mmark"},
 		{"html", "html"},
 		{"htm", "html"},
 		{"excel", "unknown"},
--- a/hugolib/handler_page.go
+++ b/hugolib/handler_page.go
@@ -25,6 +25,7 @@
 	RegisterHandler(new(htmlHandler))
 	RegisterHandler(new(asciidocHandler))
 	RegisterHandler(new(rstHandler))
+	RegisterHandler(new(mmarkHandler))
 }
 
 type basicPageHandler Handle
@@ -149,6 +150,33 @@
 		}
 		tmpContent = replaced[0]
 		tmpTableOfContents = replaced[1]
+	}
+
+	p.Content = helpers.BytesToHTML(tmpContent)
+	p.TableOfContents = helpers.BytesToHTML(tmpTableOfContents)
+
+	return HandledResult{err: nil}
+}
+
+type mmarkHandler struct {
+	basicPageHandler
+}
+
+func (h mmarkHandler) Extensions() []string { return []string{"mmark"} }
+func (h mmarkHandler) PageConvert(p *Page, t tpl.Template) HandledResult {
+	p.ProcessShortcodes(t)
+
+	tmpContent, tmpTableOfContents := helpers.ExtractTOC(p.renderContent(helpers.RemoveSummaryDivider(p.rawContent)))
+
+	if len(p.contentShortCodes) > 0 {
+		tmpContentWithTokensReplaced, err := replaceShortcodeTokens(tmpContent, shortcodePlaceholderPrefix, true, p.contentShortCodes)
+
+		if err != nil {
+			jww.FATAL.Printf("Fail to replace short code tokens in %s:\n%s", p.BaseFileName(), err.Error())
+			return HandledResult{err: err}
+		} else {
+			tmpContent = tmpContentWithTokensReplaced
+		}
 	}
 
 	p.Content = helpers.BytesToHTML(tmpContent)