| @@ -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 | |||
| @@ -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." | |||
| } | |||
| @@ -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) | |||
| } | |||