mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2024-10-31 22:38:58 +00:00
Add markup package to prepare for org markup format (#1493)
This commit is contained in:
parent
f0db3da713
commit
52627032bc
6 changed files with 157 additions and 51 deletions
|
@ -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)
|
||||||
|
}
|
||||||
|
|
|
@ -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
72
modules/markup/markup.go
Normal 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."
|
||||||
|
}
|
36
modules/markup/markup_test.go
Normal file
36
modules/markup/markup_test.go
Normal 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))
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue