From 086a46994a9f59ba06bfacdf2041817ef2f6671c Mon Sep 17 00:00:00 2001 From: Lauris BH Date: Thu, 31 Oct 2019 03:06:25 +0200 Subject: Rewrite markdown rendering to blackfriday v2 and rewrite orgmode rendering to go-org (#8560) * Rewrite markdown rendering to blackfriday v2.0 * Fix style * Fix go mod with golang 1.13 * Fix blackfriday v2 import * Inital orgmode renderer migration to go-org * Vendor go-org dependency * Ignore errors :/ * Update go-org to latest version * Update test * Fix go-org test * Remove unneeded code * Fix comments * Fix markdown test * Fix blackfriday regression rendering HTML block --- modules/markup/orgmode/orgmode.go | 100 ++++++++++++++++++++++++++------- modules/markup/orgmode/orgmode_test.go | 10 ++-- 2 files changed, 84 insertions(+), 26 deletions(-) (limited to 'modules/markup/orgmode') diff --git a/modules/markup/orgmode/orgmode.go b/modules/markup/orgmode/orgmode.go index f63155201e..54188d2734 100644 --- a/modules/markup/orgmode/orgmode.go +++ b/modules/markup/orgmode/orgmode.go @@ -5,12 +5,16 @@ package markup import ( + "bytes" + "fmt" + "html" + "strings" + "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/markup" - "code.gitea.io/gitea/modules/markup/markdown" + "code.gitea.io/gitea/modules/util" - "github.com/chaseadamsio/goorgeous" - "github.com/russross/blackfriday" + "github.com/niklasfasching/go-org/org" ) func init() { @@ -32,23 +36,23 @@ func (Parser) Extensions() []string { } // Render renders orgmode rawbytes to HTML -func Render(rawBytes []byte, urlPrefix string, metas map[string]string, isWiki bool) (result []byte) { - defer func() { - if err := recover(); err != nil { - log.Error("Panic in orgmode.Render: %v Just returning the rawBytes", err) - result = rawBytes - } - }() - htmlFlags := blackfriday.HTML_USE_XHTML - htmlFlags |= blackfriday.HTML_SKIP_STYLE - htmlFlags |= blackfriday.HTML_OMIT_CONTENTS - renderer := &markdown.Renderer{ - Renderer: blackfriday.HtmlRenderer(htmlFlags, "", ""), - URLPrefix: urlPrefix, - IsWiki: isWiki, +func Render(rawBytes []byte, urlPrefix string, metas map[string]string, isWiki bool) []byte { + htmlWriter := org.NewHTMLWriter() + + renderer := &Renderer{ + HTMLWriter: htmlWriter, + URLPrefix: urlPrefix, + IsWiki: isWiki, + } + + htmlWriter.ExtendingWriter = renderer + + res, err := org.New().Silent().Parse(bytes.NewReader(rawBytes), "").Write(renderer) + if err != nil { + log.Error("Panic in orgmode.Render: %v Just returning the rawBytes", err) + return rawBytes } - result = goorgeous.Org(rawBytes, renderer) - return + return []byte(res) } // RenderString reners orgmode string to HTML string @@ -56,7 +60,63 @@ func RenderString(rawContent string, urlPrefix string, metas map[string]string, return string(Render([]byte(rawContent), urlPrefix, metas, isWiki)) } -// Render implements markup.Parser +// Render reners orgmode string to HTML string func (Parser) Render(rawBytes []byte, urlPrefix string, metas map[string]string, isWiki bool) []byte { return Render(rawBytes, urlPrefix, metas, isWiki) } + +// Renderer implements org.Writer +type Renderer struct { + *org.HTMLWriter + URLPrefix string + IsWiki bool +} + +var byteMailto = []byte("mailto:") + +// WriteRegularLink renders images, links or videos +func (r *Renderer) WriteRegularLink(l org.RegularLink) { + link := []byte(html.EscapeString(l.URL)) + if l.Protocol == "file" { + link = link[len("file:"):] + } + if len(link) > 0 && !markup.IsLink(link) && + link[0] != '#' && !bytes.HasPrefix(link, byteMailto) { + lnk := string(link) + if r.IsWiki { + lnk = util.URLJoin("wiki", lnk) + } + link = []byte(util.URLJoin(r.URLPrefix, lnk)) + } + + description := string(link) + if l.Description != nil { + description = r.nodesAsString(l.Description...) + } + switch l.Kind() { + case "image": + r.WriteString(fmt.Sprintf(`%s`, link, description, description)) + case "video": + r.WriteString(fmt.Sprintf(``, link, description, description)) + default: + r.WriteString(fmt.Sprintf(`%s`, link, description, description)) + } +} + +func (r *Renderer) emptyClone() *Renderer { + wcopy := *(r.HTMLWriter) + wcopy.Builder = strings.Builder{} + + rcopy := *r + rcopy.HTMLWriter = &wcopy + + wcopy.ExtendingWriter = &rcopy + + return &rcopy +} + +func (r *Renderer) nodesAsString(nodes ...org.Node) string { + tmp := r.emptyClone() + org.WriteNodes(tmp, nodes...) + return tmp.String() +} diff --git a/modules/markup/orgmode/orgmode_test.go b/modules/markup/orgmode/orgmode_test.go index 3846922c25..40323912b4 100644 --- a/modules/markup/orgmode/orgmode_test.go +++ b/modules/markup/orgmode/orgmode_test.go @@ -27,12 +27,12 @@ func TestRender_StandardLinks(t *testing.T) { assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(buffer)) } - googleRendered := `

https://google.com/

` + googleRendered := "

\nhttps://google.com/\n

" test("[[https://google.com/]]", googleRendered) lnk := util.URLJoin(AppSubURL, "WikiPage") test("[[WikiPage][WikiPage]]", - `

WikiPage

`) + "

\nWikiPage\n

") } func TestRender_Images(t *testing.T) { @@ -45,10 +45,8 @@ func TestRender_Images(t *testing.T) { } url := "../../.images/src/02/train.jpg" - title := "Train" result := util.URLJoin(AppSubURL, url) - test( - "[[file:"+url+"]["+title+"]]", - `

`+title+`

`) + test("[[file:"+url+"]]", + "

\n\""+result+"\"\n

") } -- cgit v1.2.3