diff --git a/models/repo2.go b/models/repo2.go index 91c057808b..8356c52de4 100644 --- a/models/repo2.go +++ b/models/repo2.go @@ -191,3 +191,15 @@ func GetLastestCommit(userName, repoName string) (*Commit, error) { } return commit, nil } + +func GetCommits(userName, reposName, branchname string) ([]*git.Commit, error) { + repo, err := git.OpenRepository(RepoPath(userName, reposName)) + if err != nil { + return nil, err + } + r, err := repo.LookupReference(fmt.Sprintf("refs/heads/%s", branchname)) + if err != nil { + return nil, err + } + return r.AllCommits() +} diff --git a/modules/base/markdown.go b/modules/base/markdown.go index d170abe1b3..049b107548 100644 --- a/modules/base/markdown.go +++ b/modules/base/markdown.go @@ -5,35 +5,78 @@ package base import ( - "github.com/slene/blackfriday" + "bytes" + "path" + + "github.com/gogits/gfm" ) -func RenderMarkdown(rawBytes []byte) []byte { +func isletter(c byte) bool { + return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') +} + +func isalnum(c byte) bool { + return (c >= '0' && c <= '9') || isletter(c) +} + +var validLinks = [][]byte{[]byte("http://"), []byte("https://"), []byte("ftp://"), []byte("mailto://")} + +func isLink(link []byte) bool { + for _, prefix := range validLinks { + if len(link) > len(prefix) && bytes.Equal(bytes.ToLower(link[:len(prefix)]), prefix) && isalnum(link[len(prefix)]) { + return true + } + } + + return false +} + +type CustomRender struct { + gfm.Renderer + urlPrefix string +} + +func (options *CustomRender) Link(out *bytes.Buffer, link []byte, title []byte, content []byte) { + if len(link) > 0 && !isLink(link) { + if link[0] == '#' { + link = append([]byte(options.urlPrefix), link...) + } else { + link = []byte(path.Join(options.urlPrefix, string(link))) + } + } + + options.Renderer.Link(out, link, title, content) +} + +func RenderMarkdown(rawBytes []byte, urlPrefix string) []byte { htmlFlags := 0 - htmlFlags |= blackfriday.HTML_USE_XHTML - // htmlFlags |= blackfriday.HTML_USE_SMARTYPANTS - // htmlFlags |= blackfriday.HTML_SMARTYPANTS_FRACTIONS - // htmlFlags |= blackfriday.HTML_SMARTYPANTS_LATEX_DASHES - htmlFlags |= blackfriday.HTML_SKIP_HTML - htmlFlags |= blackfriday.HTML_SKIP_STYLE - htmlFlags |= blackfriday.HTML_SKIP_SCRIPT - htmlFlags |= blackfriday.HTML_GITHUB_BLOCKCODE - htmlFlags |= blackfriday.HTML_OMIT_CONTENTS - htmlFlags |= blackfriday.HTML_COMPLETE_PAGE - renderer := blackfriday.HtmlRenderer(htmlFlags, "", "") + htmlFlags |= gfm.HTML_USE_XHTML + // htmlFlags |= gfm.HTML_USE_SMARTYPANTS + // htmlFlags |= gfm.HTML_SMARTYPANTS_FRACTIONS + // htmlFlags |= gfm.HTML_SMARTYPANTS_LATEX_DASHES + htmlFlags |= gfm.HTML_SKIP_HTML + htmlFlags |= gfm.HTML_SKIP_STYLE + htmlFlags |= gfm.HTML_SKIP_SCRIPT + htmlFlags |= gfm.HTML_GITHUB_BLOCKCODE + htmlFlags |= gfm.HTML_OMIT_CONTENTS + htmlFlags |= gfm.HTML_COMPLETE_PAGE + renderer := &CustomRender{ + Renderer: gfm.HtmlRenderer(htmlFlags, "", ""), + urlPrefix: urlPrefix, + } // set up the parser extensions := 0 - extensions |= blackfriday.EXTENSION_NO_INTRA_EMPHASIS - extensions |= blackfriday.EXTENSION_TABLES - extensions |= blackfriday.EXTENSION_FENCED_CODE - extensions |= blackfriday.EXTENSION_AUTOLINK - extensions |= blackfriday.EXTENSION_STRIKETHROUGH - extensions |= blackfriday.EXTENSION_HARD_LINE_BREAK - extensions |= blackfriday.EXTENSION_SPACE_HEADERS - extensions |= blackfriday.EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK + extensions |= gfm.EXTENSION_NO_INTRA_EMPHASIS + extensions |= gfm.EXTENSION_TABLES + extensions |= gfm.EXTENSION_FENCED_CODE + extensions |= gfm.EXTENSION_AUTOLINK + extensions |= gfm.EXTENSION_STRIKETHROUGH + extensions |= gfm.EXTENSION_HARD_LINE_BREAK + extensions |= gfm.EXTENSION_SPACE_HEADERS + extensions |= gfm.EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK - body := blackfriday.Markdown(rawBytes, renderer, extensions) + body := gfm.Markdown(rawBytes, renderer, extensions) return body } diff --git a/routers/repo/single.go b/routers/repo/single.go index cf64cc6b52..0bf3454530 100644 --- a/routers/repo/single.go +++ b/routers/repo/single.go @@ -102,9 +102,13 @@ func Single(ctx *middleware.Context, params martini.Params) { if readmeFile.Size > 1024*1024 || readmeFile.Filemode != git.FileModeBlob { ctx.Data["FileIsLarge"] = true } else if blob, err := readmeFile.LookupBlob(); err != nil { - ctx.Data["FileIsLarge"] = true + ctx.Data["ReadmeExist"] = false } else { - ctx.Data["ReadmeContent"] = string(base.RenderMarkdown(blob.Contents())) + // current repo branch link + urlPrefix := "http://" + base.Domain + "/" + ctx.Repo.Owner.LowerName + "/" + + ctx.Repo.Repository.Name + "/blob/" + params["branchname"] + + ctx.Data["ReadmeContent"] = string(base.RenderMarkdown(blob.Contents(), urlPrefix)) } } @@ -131,8 +135,15 @@ func Setting(ctx *middleware.Context, params martini.Params) { ctx.Render.HTML(200, "repo/setting", ctx.Data) } -func Commits(ctx *middleware.Context) { +func Commits(ctx *middleware.Context, params martini.Params) { ctx.Data["IsRepoToolbarCommits"] = true + commits, err := models.GetCommits(params["username"], + params["reponame"], params["branchname"]) + if err != nil { + ctx.Render.Error(404) + return + } + ctx.Data["Commits"] = commits ctx.Render.HTML(200, "repo/commits", ctx.Data) } diff --git a/templates/repo/commits.tmpl b/templates/repo/commits.tmpl index 7ebe68b6a0..9190a030a3 100644 --- a/templates/repo/commits.tmpl +++ b/templates/repo/commits.tmpl @@ -4,6 +4,11 @@ {{template "repo/toolbar" .}}
+
{{template "base/footer" .}} \ No newline at end of file diff --git a/web.go b/web.go index b1399953b1..2177d5662f 100644 --- a/web.go +++ b/web.go @@ -74,7 +74,7 @@ func runWeb(*cli.Context) { m.Post("/:username/:reponame/settings", middleware.SignInRequire(true), middleware.RepoAssignment(true), repo.SettingPost) m.Get("/:username/:reponame/settings", middleware.SignInRequire(true), middleware.RepoAssignment(true), repo.Setting) - m.Get("/:username/:reponame/commits", middleware.SignInRequire(false), middleware.RepoAssignment(true), repo.Commits) + m.Get("/:username/:reponame/commits/:branchname", middleware.SignInRequire(false), middleware.RepoAssignment(true), repo.Commits) m.Get("/:username/:reponame/issues", middleware.SignInRequire(false), middleware.RepoAssignment(true), repo.Issues) m.Get("/:username/:reponame/pulls", middleware.SignInRequire(false), middleware.RepoAssignment(true), repo.Pulls) m.Get("/:username/:reponame/branches", middleware.SignInRequire(false), middleware.RepoAssignment(true), repo.Branches)