From 5bc2a1a6f98ae42ab5c30299d26082ffae54b859 Mon Sep 17 00:00:00 2001
From: slene <vslene@gmail.com>
Date: Mon, 17 Mar 2014 18:46:54 +0800
Subject: [PATCH] show readme.md

---
 models/repo2.go            | 16 ++++++++++++
 modules/base/markdown.go   | 39 +++++++++++++++++++++++++++++
 routers/repo/single.go     | 51 +++++++++++++++++++++++++++-----------
 templates/repo/single.tmpl | 12 ++++++---
 4 files changed, 101 insertions(+), 17 deletions(-)
 create mode 100644 modules/base/markdown.go

diff --git a/models/repo2.go b/models/repo2.go
index 0c17a58335..b31244b414 100644
--- a/models/repo2.go
+++ b/models/repo2.go
@@ -5,6 +5,7 @@
 package models
 
 import (
+	"fmt"
 	"path"
 	"strings"
 	"time"
@@ -22,12 +23,25 @@ type Commit struct {
 	Message string
 }
 
+var (
+	ErrRepoFileNotLoaded = fmt.Errorf("repo file not loaded")
+)
+
 type RepoFile struct {
 	*git.TreeEntry
 	Path    string
 	Message string
 	Created time.Time
 	Size    int64
+	Repo    *git.Repository
+}
+
+func (file *RepoFile) LookupBlob() (*git.Blob, error) {
+	if file.Repo == nil {
+		return nil, ErrRepoFileNotLoaded
+	}
+
+	return file.Repo.LookupBlob(file.Id)
 }
 
 func GetBranches(userName, reposName string) ([]string, error) {
@@ -80,6 +94,7 @@ func GetReposFiles(userName, reposName, branchName, rpath string) ([]*RepoFile,
 					lastCommit.Message(),
 					lastCommit.Committer.When,
 					size,
+					repo,
 				})
 			case git.FileModeTree:
 				repodirs = append(repodirs, &RepoFile{
@@ -88,6 +103,7 @@ func GetReposFiles(userName, reposName, branchName, rpath string) ([]*RepoFile,
 					lastCommit.Message(),
 					lastCommit.Committer.When,
 					size,
+					repo,
 				})
 			}
 		}
diff --git a/modules/base/markdown.go b/modules/base/markdown.go
new file mode 100644
index 0000000000..d170abe1b3
--- /dev/null
+++ b/modules/base/markdown.go
@@ -0,0 +1,39 @@
+// Copyright 2014 The Gogs 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 base
+
+import (
+	"github.com/slene/blackfriday"
+)
+
+func RenderMarkdown(rawBytes []byte) []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, "", "")
+
+	// 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
+
+	body := blackfriday.Markdown(rawBytes, renderer, extensions)
+
+	return body
+}
diff --git a/routers/repo/single.go b/routers/repo/single.go
index c144106cb8..f47a2f7bfc 100644
--- a/routers/repo/single.go
+++ b/routers/repo/single.go
@@ -8,9 +8,11 @@ import (
 	"strings"
 
 	"github.com/codegangsta/martini"
-	// "github.com/slene/blackfriday"
+
+	"github.com/gogits/git"
 
 	"github.com/gogits/gogs/models"
+	"github.com/gogits/gogs/modules/base"
 	"github.com/gogits/gogs/modules/middleware"
 )
 
@@ -43,12 +45,14 @@ func Single(ctx *middleware.Context, params martini.Params) {
 		params["branchname"] = "master"
 	}
 
-	// Directory and file list.
+	// Get tree path
 	treename := params["_1"]
+
+	// Directory and file list.
 	files, err := models.GetReposFiles(params["username"], params["reponame"],
 		params["branchname"], treename)
 	if err != nil {
-		ctx.Handle(200, "repo.Single", err)
+		ctx.Render.Error(404)
 		return
 	}
 	ctx.Data["Username"] = params["username"]
@@ -58,7 +62,7 @@ func Single(ctx *middleware.Context, params martini.Params) {
 	// Branches.
 	brs, err := models.GetBranches(params["username"], params["reponame"])
 	if err != nil {
-		ctx.Handle(200, "repo.Single", err)
+		ctx.Render.Error(404)
 		return
 	}
 	ctx.Data["Branches"] = brs
@@ -73,22 +77,41 @@ func Single(ctx *middleware.Context, params martini.Params) {
 		}
 	}
 
-	// Latest commit.
+	// Get latest commit according username and repo name
 	commit, err := models.GetLastestCommit(params["username"], params["reponame"])
 	if err != nil {
-		ctx.Handle(200, "repo.Single", err)
+		ctx.Render.Error(404)
 		return
 	}
 	ctx.Data["LatestCommit"] = commit
 
-	// README.
-	// for _, f := range files {
-	// 	if f.Name == "README.md" {
-	// ctx.Data["ReadmeName"] = "README.md"
-	// ctx.Data["ReadmeContent"] =
-	// 		break
-	// 	}
-	// }
+	var readmeFile *models.RepoFile
+
+	for _, f := range files {
+		if !f.IsFile() {
+			continue
+		}
+
+		if len(f.Name) < 6 {
+			continue
+		}
+
+		if strings.ToLower(f.Name[:6]) == "readme" {
+			readmeFile = f
+			break
+		}
+	}
+
+	if readmeFile != nil {
+		// if file large than 1M not show it
+		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
+		} else {
+			ctx.Data["ReadmeContent"] = string(base.RenderMarkdown(blob.Contents()))
+		}
+	}
 
 	ctx.Data["Paths"] = Paths
 	ctx.Data["Treenames"] = treenames
diff --git a/templates/repo/single.tmpl b/templates/repo/single.tmpl
index 153910f78a..c22f129fb7 100644
--- a/templates/repo/single.tmpl
+++ b/templates/repo/single.tmpl
@@ -87,9 +87,15 @@
             <div class="panel-heading file-head">
                 <i class="icon fa fa-book"></i> README.md
             </div>
-            <div class="panel-body file-body markdown">
-                markdown content
-            </div>
+            {{if .FileIsLarge}}
+                <div class="panel-footer">
+                    Large file size 1000kb
+                </div>
+            {{else}}
+                <div class="panel-body file-body markdown">
+                    {{.ReadmeContent|str2html}}
+                </div>
+            {{end}}
         </div>
     </div>
 </div>