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)