Procházet zdrojové kódy

Add @ # commit link detect on all markdown render

Unknown před 11 roky
rodič
revize
8c9a0494ec

+ 35 - 10
modules/base/markdown.go

@@ -90,8 +90,10 @@ func (options *CustomRender) Link(out *bytes.Buffer, link []byte, title []byte,
 }
 
 var (
-	mentionPattern = regexp.MustCompile(`@[0-9a-zA-Z_]{1,}`)
-	commitPattern  = regexp.MustCompile(`[^>]http[s]{0,}.*commit/[0-9a-zA-Z]{1,}`)
+	mentionPattern    = regexp.MustCompile(`@[0-9a-zA-Z_]{1,}`)
+	commitPattern     = regexp.MustCompile(`(\s|^)https?.*commit/[0-9a-zA-Z]+(#+[0-9a-zA-Z-]*)?`)
+	issueFullPattern  = regexp.MustCompile(`(\s|^)https?.*issues/[0-9]+(#+[0-9a-zA-Z-]*)?`)
+	issueIndexPattern = regexp.MustCompile(`(\s|^)#[0-9]+`)
 )
 
 func RenderSpecialLink(rawBytes []byte, urlPrefix string) []byte {
@@ -102,8 +104,31 @@ func RenderSpecialLink(rawBytes []byte, urlPrefix string) []byte {
 	}
 	ms = commitPattern.FindAll(rawBytes, -1)
 	for _, m := range ms {
-		rawBytes = bytes.Replace(rawBytes, m,
-			[]byte(fmt.Sprintf(`<code><a href="%s">%s</a></code>`, m, m)), -1)
+		m = bytes.TrimPrefix(m, []byte(" "))
+		i := strings.Index(string(m), "commit/")
+		j := strings.Index(string(m), "#")
+		if j == -1 {
+			j = len(m)
+		}
+		rawBytes = bytes.Replace(rawBytes, m, []byte(fmt.Sprintf(
+			` <code><a href="%s">%s</a></code>`, m, ShortSha(string(m[i+7:j])))), -1)
+	}
+	ms = issueFullPattern.FindAll(rawBytes, -1)
+	for _, m := range ms {
+		m = bytes.TrimPrefix(m, []byte(" "))
+		i := strings.Index(string(m), "issues/")
+		j := strings.Index(string(m), "#")
+		if j == -1 {
+			j = len(m)
+		}
+		rawBytes = bytes.Replace(rawBytes, m, []byte(fmt.Sprintf(
+			` <a href="%s">#%s</a>`, m, ShortSha(string(m[i+7:j])))), -1)
+	}
+	ms = issueIndexPattern.FindAll(rawBytes, -1)
+	for _, m := range ms {
+		m = bytes.TrimPrefix(m, []byte(" "))
+		rawBytes = bytes.Replace(rawBytes, m, []byte(fmt.Sprintf(
+			` <a href="%s/issues/%s">%s</a>`, urlPrefix, m[1:], m)), -1)
 	}
 	return rawBytes
 }
@@ -122,10 +147,10 @@ func RenderMarkdown(rawBytes []byte, urlPrefix string) []byte {
 	htmlFlags |= gfm.HTML_GITHUB_BLOCKCODE
 	htmlFlags |= gfm.HTML_OMIT_CONTENTS
 	// htmlFlags |= gfm.HTML_COMPLETE_PAGE
-	renderer := &CustomRender{
-		Renderer:  gfm.HtmlRenderer(htmlFlags, "", ""),
-		urlPrefix: urlPrefix,
-	}
+	// renderer := &CustomRender{
+	// 	Renderer:  gfm.HtmlRenderer(htmlFlags, "", ""),
+	// 	urlPrefix: urlPrefix,
+	// }
 
 	// set up the parser
 	extensions := 0
@@ -138,7 +163,7 @@ func RenderMarkdown(rawBytes []byte, urlPrefix string) []byte {
 	extensions |= gfm.EXTENSION_SPACE_HEADERS
 	extensions |= gfm.EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK
 
-	body = gfm.Markdown(body, renderer, extensions)
-	fmt.Println(string(body))
+	// body = gfm.Markdown(body, renderer, extensions)
+	// fmt.Println(string(body))
 	return body
 }

+ 1 - 1
routers/api/v1/miscellaneous.go

@@ -13,6 +13,6 @@ func Markdown(ctx *middleware.Context) {
 	content := ctx.Query("content")
 	ctx.Render.JSON(200, map[string]interface{}{
 		"ok":      true,
-		"content": string(base.RenderMarkdown([]byte(content), "")),
+		"content": string(base.RenderMarkdown([]byte(content), ctx.Query("repoLink"))),
 	})
 }

+ 4 - 4
routers/repo/issue.go

@@ -147,7 +147,7 @@ func ViewIssue(ctx *middleware.Context, params martini.Params) {
 		return
 	}
 	issue.Poster = u
-	issue.RenderedContent = string(base.RenderMarkdown([]byte(issue.Content), ""))
+	issue.RenderedContent = string(base.RenderMarkdown([]byte(issue.Content), ctx.Repo.RepoLink))
 
 	// Get comments.
 	comments, err := models.GetIssueComments(issue.Id)
@@ -164,7 +164,7 @@ func ViewIssue(ctx *middleware.Context, params martini.Params) {
 			return
 		}
 		comments[i].Poster = u
-		comments[i].Content = string(base.RenderMarkdown([]byte(comments[i].Content), ""))
+		comments[i].Content = string(base.RenderMarkdown([]byte(comments[i].Content), ctx.Repo.RepoLink))
 	}
 
 	ctx.Data["Title"] = issue.Name
@@ -193,7 +193,7 @@ func UpdateIssue(ctx *middleware.Context, params martini.Params, form auth.Creat
 		return
 	}
 
-	if ctx.User.Id != issue.PosterId {
+	if ctx.User.Id != issue.PosterId && !ctx.Repo.IsOwner {
 		ctx.Handle(404, "issue.UpdateIssue", nil)
 		return
 	}
@@ -211,7 +211,7 @@ func UpdateIssue(ctx *middleware.Context, params martini.Params, form auth.Creat
 	ctx.JSON(200, map[string]interface{}{
 		"ok":      true,
 		"title":   issue.Name,
-		"content": string(base.RenderMarkdown([]byte(issue.Content), "")),
+		"content": string(base.RenderMarkdown([]byte(issue.Content), ctx.Repo.RepoLink)),
 	})
 }
 

+ 1 - 1
templates/issue/view.tmpl

@@ -72,7 +72,7 @@
                                 </div>
                                 <ul class="nav nav-tabs" data-init="tabs">
                                     <li class="active issue-write"><a href="#issue-textarea" data-toggle="tab">Write</a></li>
-                                    <li class="issue-preview"><a href="#issue-preview" data-toggle="tab" data-ajax="/api/v1/markdown?repo=repo_id&issue=issue_id&comment=new" data-ajax-name="issue-preview" data-ajax-method="post" data-preview="#issue-preview">Preview</a></li>
+                                    <li class="issue-preview"><a href="#issue-preview" data-toggle="tab" data-ajax="/api/v1/markdown?repoLink={{.RepoLink}}" data-ajax-name="issue-preview" data-ajax-method="post" data-preview="#issue-preview">Preview</a></li>
                                 </ul>
                                 <div class="tab-content">
                                     <div class="tab-pane" id="issue-textarea">