mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 08:30:25 +08:00 
			
		
		
		
	Add markup package to prepare for org markup format (#1493)
This commit is contained in:
		
				
					committed by
					
						
						Kim "BKC" Carlbäcker
					
				
			
			
				
	
			
			
			
						parent
						
							f0db3da713
						
					
				
				
					commit
					52627032bc
				
			@@ -19,6 +19,7 @@ import (
 | 
			
		||||
	"golang.org/x/net/html"
 | 
			
		||||
 | 
			
		||||
	"code.gitea.io/gitea/modules/base"
 | 
			
		||||
	"code.gitea.io/gitea/modules/markup"
 | 
			
		||||
	"code.gitea.io/gitea/modules/setting"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@@ -40,18 +41,6 @@ func IsMarkdownFile(name string) bool {
 | 
			
		||||
	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 (
 | 
			
		||||
	// MentionPattern matches string that mentions someone, e.g. @Unknwon
 | 
			
		||||
	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 {
 | 
			
		||||
	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
 | 
			
		||||
 | 
			
		||||
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) {
 | 
			
		||||
	setting.AppURL = AppURL
 | 
			
		||||
	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/lfs"
 | 
			
		||||
	"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/templates"
 | 
			
		||||
	"github.com/Unknwon/paginater"
 | 
			
		||||
@@ -56,7 +56,7 @@ func renderDirectory(ctx *context.Context, treeLink string) {
 | 
			
		||||
 | 
			
		||||
	var readmeFile *git.Blob
 | 
			
		||||
	for _, entry := range entries {
 | 
			
		||||
		if entry.IsDir() || !markdown.IsReadmeFile(entry.Name()) {
 | 
			
		||||
		if entry.IsDir() || !markup.IsReadmeFile(entry.Name()) {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@@ -87,17 +87,16 @@ func renderDirectory(ctx *context.Context, treeLink string) {
 | 
			
		||||
		if isTextFile {
 | 
			
		||||
			d, _ := ioutil.ReadAll(dataRc)
 | 
			
		||||
			buf = append(buf, d...)
 | 
			
		||||
			switch {
 | 
			
		||||
			case markdown.IsMarkdownFile(readmeFile.Name()):
 | 
			
		||||
			newbuf := markup.Render(readmeFile.Name(), buf, treeLink, ctx.Repo.Repository.ComposeMetas())
 | 
			
		||||
			if newbuf != nil {
 | 
			
		||||
				ctx.Data["IsMarkdown"] = true
 | 
			
		||||
				buf = markdown.Render(buf, treeLink, ctx.Repo.Repository.ComposeMetas())
 | 
			
		||||
			default:
 | 
			
		||||
			} else {
 | 
			
		||||
				// FIXME This is the only way to show non-markdown files
 | 
			
		||||
				// instead of a broken "View Raw" link
 | 
			
		||||
				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)
 | 
			
		||||
		buf = append(buf, d...)
 | 
			
		||||
 | 
			
		||||
		isMarkdown := markdown.IsMarkdownFile(blob.Name())
 | 
			
		||||
		ctx.Data["IsMarkdown"] = isMarkdown
 | 
			
		||||
		tp := markup.Type(blob.Name())
 | 
			
		||||
		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
 | 
			
		||||
		if readmeExist && isMarkdown {
 | 
			
		||||
			ctx.Data["FileContent"] = string(markdown.Render(buf, path.Dir(treeLink), ctx.Repo.Repository.ComposeMetas()))
 | 
			
		||||
		if readmeExist && isSupportedMarkup {
 | 
			
		||||
			ctx.Data["FileContent"] = string(markup.Render(blob.Name(), buf, path.Dir(treeLink), ctx.Repo.Repository.ComposeMetas()))
 | 
			
		||||
		} else {
 | 
			
		||||
			// Building code view blocks with line number on server side.
 | 
			
		||||
			var fileContent string
 | 
			
		||||
 
 | 
			
		||||
@@ -19,6 +19,7 @@ import (
 | 
			
		||||
	"code.gitea.io/gitea/modules/base"
 | 
			
		||||
	"code.gitea.io/gitea/modules/context"
 | 
			
		||||
	"code.gitea.io/gitea/modules/markdown"
 | 
			
		||||
	"code.gitea.io/gitea/modules/markup"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
@@ -322,7 +323,7 @@ func Wiki(ctx *context.Context) {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ename := entry.Name()
 | 
			
		||||
	if !markdown.IsMarkdownFile(ename) {
 | 
			
		||||
	if markup.Type(ename) != markdown.MarkupName {
 | 
			
		||||
		ext := strings.ToUpper(filepath.Ext(ename))
 | 
			
		||||
		ctx.Data["FormatWarning"] = fmt.Sprintf("%s rendering is not supported at the moment. Rendered as Markdown.", ext)
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user