mirror of
https://github.com/gohugoio/hugo.git
synced 2024-11-21 20:46:30 -05:00
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.
This commit is contained in:
parent
d4acacd4f5
commit
563a6302a0
4 changed files with 109 additions and 4 deletions
|
@ -22,6 +22,7 @@ import (
|
|||
"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 blackfridayExtensionMap = map[string]int{
|
|||
|
||||
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 @@ func markdownRenderWithTOC(ctx *RenderingContext) []byte {
|
|||
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 @@ func RenderBytesWithTOC(ctx *RenderingContext) []byte {
|
|||
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 @@ func RenderBytes(ctx *RenderingContext) []byte {
|
|||
return markdownRender(ctx)
|
||||
case "asciidoc":
|
||||
return []byte(GetAsciidocContent(ctx.Content))
|
||||
case "mmark":
|
||||
return MmarkRender(ctx)
|
||||
case "rst":
|
||||
return []byte(GetRstContent(ctx.Content))
|
||||
}
|
||||
|
|
|
@ -19,16 +19,17 @@ import (
|
|||
"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"
|
||||
"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 @@ func GuessType(in string) string {
|
|||
return "markdown"
|
||||
case "asciidoc", "adoc", "ad":
|
||||
return "asciidoc"
|
||||
case "mmark":
|
||||
return "mmark"
|
||||
case "rst":
|
||||
return "rst"
|
||||
case "html", "htm":
|
||||
|
|
|
@ -21,6 +21,7 @@ func TestGuessType(t *testing.T) {
|
|||
{"adoc", "asciidoc"},
|
||||
{"ad", "asciidoc"},
|
||||
{"rst", "rst"},
|
||||
{"mmark", "mmark"},
|
||||
{"html", "html"},
|
||||
{"htm", "html"},
|
||||
{"excel", "unknown"},
|
||||
|
|
|
@ -25,6 +25,7 @@ func init() {
|
|||
RegisterHandler(new(htmlHandler))
|
||||
RegisterHandler(new(asciidocHandler))
|
||||
RegisterHandler(new(rstHandler))
|
||||
RegisterHandler(new(mmarkHandler))
|
||||
}
|
||||
|
||||
type basicPageHandler Handle
|
||||
|
@ -156,3 +157,30 @@ func (h rstHandler) PageConvert(p *Page, t tpl.Template) HandledResult {
|
|||
|
||||
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)
|
||||
p.TableOfContents = helpers.BytesToHTML(tmpTableOfContents)
|
||||
|
||||
return HandledResult{err: nil}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue