Add markup package to prepare for org markup format (#1493)

This commit is contained in:
Lunny Xiao 2017-04-21 15:01:08 +08:00 committed by Kim "BKC" Carlbäcker
parent f0db3da713
commit 52627032bc
6 changed files with 157 additions and 51 deletions

View file

@ -19,6 +19,7 @@ import (
"golang.org/x/net/html" "golang.org/x/net/html"
"code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/markup"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
) )
@ -40,18 +41,6 @@ func IsMarkdownFile(name string) bool {
return false return false
} }
// IsReadmeFile reports whether name looks like a README file
// based on its name.
func IsReadmeFile(name string) bool {
name = strings.ToLower(name)
if len(name) < 6 {
return false
} else if len(name) == 6 {
return name == "readme"
}
return name[:7] == "readme."
}
var ( var (
// MentionPattern matches string that mentions someone, e.g. @Unknwon // MentionPattern matches string that mentions someone, e.g. @Unknwon
MentionPattern = regexp.MustCompile(`(\s|^|\W)@[0-9a-zA-Z-_\.]+`) MentionPattern = regexp.MustCompile(`(\s|^|\W)@[0-9a-zA-Z-_\.]+`)
@ -707,3 +696,31 @@ func RenderString(raw, urlPrefix string, metas map[string]string) string {
func RenderWiki(rawBytes []byte, urlPrefix string, metas map[string]string) string { func RenderWiki(rawBytes []byte, urlPrefix string, metas map[string]string) string {
return string(render(rawBytes, urlPrefix, metas, true)) return string(render(rawBytes, urlPrefix, metas, true))
} }
var (
// MarkupName describes markup's name
MarkupName = "markdown"
)
func init() {
markup.RegisterParser(Parser{})
}
// Parser implements markup.Parser
type Parser struct {
}
// Name implements markup.Parser
func (Parser) Name() string {
return MarkupName
}
// Extensions implements markup.Parser
func (Parser) Extensions() []string {
return setting.Markdown.FileExtensions
}
// Render implements markup.Parser
func (Parser) Render(rawBytes []byte, urlPrefix string, metas map[string]string, isWiki bool) []byte {
return render(rawBytes, urlPrefix, metas, isWiki)
}

View file

@ -1,3 +1,7 @@
// Copyright 2017 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package markdown_test package markdown_test
import ( import (
@ -586,31 +590,6 @@ func TestMisc_IsMarkdownFile(t *testing.T) {
} }
} }
func TestMisc_IsReadmeFile(t *testing.T) {
trueTestCases := []string{
"readme",
"README",
"readME.mdown",
"README.md",
}
falseTestCases := []string{
"test.md",
"wow.MARKDOWN",
"LOL.mDoWn",
"test",
"abcdefg",
"abcdefghijklmnopqrstuvwxyz",
"test.md.test",
}
for _, testCase := range trueTestCases {
assert.True(t, IsReadmeFile(testCase))
}
for _, testCase := range falseTestCases {
assert.False(t, IsReadmeFile(testCase))
}
}
func TestMisc_IsSameDomain(t *testing.T) { func TestMisc_IsSameDomain(t *testing.T) {
setting.AppURL = AppURL setting.AppURL = AppURL
setting.AppSubURL = AppSubURL setting.AppSubURL = AppSubURL

72
modules/markup/markup.go Normal file
View file

@ -0,0 +1,72 @@
// Copyright 2017 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package markup
import (
"path/filepath"
"strings"
)
// Parser defines an interface for parsering markup file to HTML
type Parser interface {
Name() string // markup format name
Extensions() []string
Render(rawBytes []byte, urlPrefix string, metas map[string]string, isWiki bool) []byte
}
var (
parsers = make(map[string]Parser)
)
// RegisterParser registers a new markup file parser
func RegisterParser(parser Parser) {
for _, ext := range parser.Extensions() {
parsers[strings.ToLower(ext)] = parser
}
}
// Render renders markup file to HTML with all specific handling stuff.
func Render(filename string, rawBytes []byte, urlPrefix string, metas map[string]string) []byte {
return render(filename, rawBytes, urlPrefix, metas, false)
}
func render(filename string, rawBytes []byte, urlPrefix string, metas map[string]string, isWiki bool) []byte {
extension := strings.ToLower(filepath.Ext(filename))
if parser, ok := parsers[extension]; ok {
return parser.Render(rawBytes, urlPrefix, metas, isWiki)
}
return nil
}
// RenderString renders Markdown to HTML with special links and returns string type.
func RenderString(filename string, raw, urlPrefix string, metas map[string]string) string {
return string(render(filename, []byte(raw), urlPrefix, metas, false))
}
// RenderWiki renders markdown wiki page to HTML and return HTML string
func RenderWiki(filename string, rawBytes []byte, urlPrefix string, metas map[string]string) string {
return string(render(filename, rawBytes, urlPrefix, metas, true))
}
// Type returns if markup format via the filename
func Type(filename string) string {
extension := strings.ToLower(filepath.Ext(filename))
if parser, ok := parsers[extension]; ok {
return parser.Name()
}
return ""
}
// IsReadmeFile reports whether name looks like a README file
// based on its name.
func IsReadmeFile(name string) bool {
name = strings.ToLower(name)
if len(name) < 6 {
return false
} else if len(name) == 6 {
return name == "readme"
}
return name[:7] == "readme."
}

View file

@ -0,0 +1,36 @@
// Copyright 2017 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package markup
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestMisc_IsReadmeFile(t *testing.T) {
trueTestCases := []string{
"readme",
"README",
"readME.mdown",
"README.md",
}
falseTestCases := []string{
"test.md",
"wow.MARKDOWN",
"LOL.mDoWn",
"test",
"abcdefg",
"abcdefghijklmnopqrstuvwxyz",
"test.md.test",
}
for _, testCase := range trueTestCases {
assert.True(t, IsReadmeFile(testCase))
}
for _, testCase := range falseTestCases {
assert.False(t, IsReadmeFile(testCase))
}
}

View file

@ -21,7 +21,7 @@ import (
"code.gitea.io/gitea/modules/highlight" "code.gitea.io/gitea/modules/highlight"
"code.gitea.io/gitea/modules/lfs" "code.gitea.io/gitea/modules/lfs"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/markdown" "code.gitea.io/gitea/modules/markup"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/templates" "code.gitea.io/gitea/modules/templates"
"github.com/Unknwon/paginater" "github.com/Unknwon/paginater"
@ -56,7 +56,7 @@ func renderDirectory(ctx *context.Context, treeLink string) {
var readmeFile *git.Blob var readmeFile *git.Blob
for _, entry := range entries { for _, entry := range entries {
if entry.IsDir() || !markdown.IsReadmeFile(entry.Name()) { if entry.IsDir() || !markup.IsReadmeFile(entry.Name()) {
continue continue
} }
@ -87,17 +87,16 @@ func renderDirectory(ctx *context.Context, treeLink string) {
if isTextFile { if isTextFile {
d, _ := ioutil.ReadAll(dataRc) d, _ := ioutil.ReadAll(dataRc)
buf = append(buf, d...) buf = append(buf, d...)
switch { newbuf := markup.Render(readmeFile.Name(), buf, treeLink, ctx.Repo.Repository.ComposeMetas())
case markdown.IsMarkdownFile(readmeFile.Name()): if newbuf != nil {
ctx.Data["IsMarkdown"] = true ctx.Data["IsMarkdown"] = true
buf = markdown.Render(buf, treeLink, ctx.Repo.Repository.ComposeMetas()) } else {
default:
// FIXME This is the only way to show non-markdown files // FIXME This is the only way to show non-markdown files
// instead of a broken "View Raw" link // instead of a broken "View Raw" link
ctx.Data["IsMarkdown"] = true ctx.Data["IsMarkdown"] = true
buf = bytes.Replace(buf, []byte("\n"), []byte(`<br>`), -1) newbuf = bytes.Replace(buf, []byte("\n"), []byte(`<br>`), -1)
} }
ctx.Data["FileContent"] = string(buf) ctx.Data["FileContent"] = string(newbuf)
} }
} }
@ -182,13 +181,15 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st
d, _ := ioutil.ReadAll(dataRc) d, _ := ioutil.ReadAll(dataRc)
buf = append(buf, d...) buf = append(buf, d...)
isMarkdown := markdown.IsMarkdownFile(blob.Name()) tp := markup.Type(blob.Name())
ctx.Data["IsMarkdown"] = isMarkdown isSupportedMarkup := tp != ""
// FIXME: currently set IsMarkdown for compitable
ctx.Data["IsMarkdown"] = isSupportedMarkup
readmeExist := isMarkdown || markdown.IsReadmeFile(blob.Name()) readmeExist := isSupportedMarkup || markup.IsReadmeFile(blob.Name())
ctx.Data["ReadmeExist"] = readmeExist ctx.Data["ReadmeExist"] = readmeExist
if readmeExist && isMarkdown { if readmeExist && isSupportedMarkup {
ctx.Data["FileContent"] = string(markdown.Render(buf, path.Dir(treeLink), ctx.Repo.Repository.ComposeMetas())) ctx.Data["FileContent"] = string(markup.Render(blob.Name(), buf, path.Dir(treeLink), ctx.Repo.Repository.ComposeMetas()))
} else { } else {
// Building code view blocks with line number on server side. // Building code view blocks with line number on server side.
var fileContent string var fileContent string

View file

@ -19,6 +19,7 @@ import (
"code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/markdown" "code.gitea.io/gitea/modules/markdown"
"code.gitea.io/gitea/modules/markup"
) )
const ( const (
@ -322,7 +323,7 @@ func Wiki(ctx *context.Context) {
} }
ename := entry.Name() ename := entry.Name()
if !markdown.IsMarkdownFile(ename) { if markup.Type(ename) != markdown.MarkupName {
ext := strings.ToUpper(filepath.Ext(ename)) ext := strings.ToUpper(filepath.Ext(ename))
ctx.Data["FormatWarning"] = fmt.Sprintf("%s rendering is not supported at the moment. Rendered as Markdown.", ext) ctx.Data["FormatWarning"] = fmt.Sprintf("%s rendering is not supported at the moment. Rendered as Markdown.", ext)
} }