2023-03-24 07:12:23 +01:00
// Copyright 2014 The Gogs Authors. All rights reserved.
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package common
import (
"fmt"
"net/http"
2024-06-17 08:16:14 +02:00
"path"
2023-03-24 07:12:23 +01:00
"strings"
2024-05-30 15:04:01 +08:00
repo_model "code.gitea.io/gitea/models/repo"
2024-06-17 08:16:14 +02:00
"code.gitea.io/gitea/modules/httplib"
2023-03-24 07:12:23 +01:00
"code.gitea.io/gitea/modules/markup"
"code.gitea.io/gitea/modules/markup/markdown"
"code.gitea.io/gitea/modules/setting"
2024-02-27 15:12:22 +08:00
"code.gitea.io/gitea/services/context"
2023-03-24 07:12:23 +01:00
)
// RenderMarkup renders markup text for the /markup and /markdown endpoints
2024-06-17 08:16:14 +02:00
func RenderMarkup ( ctx * context . Base , repo * context . Repository , mode , text , urlPathContext , filePath string , wiki bool ) {
// urlPathContext format is "/subpath/{user}/{repo}/src/{branch, commit, tag}/{identifier/path}/{file/dir}"
// filePath is the path of the file to render if the end user is trying to preview a repo file (mode == "file")
// filePath will be used as RenderContext.RelativePath
2023-03-24 07:12:23 +01:00
2024-06-17 08:16:14 +02:00
// for example, when previewing file "/gitea/owner/repo/src/branch/features/feat-123/doc/CHANGE.md", then filePath is "doc/CHANGE.md"
// and the urlPathContext is "/gitea/owner/repo/src/branch/features/feat-123/doc"
var markupType , relativePath string
links := markup . Links { AbsolutePrefix : true }
if urlPathContext != "" {
links . Base = fmt . Sprintf ( "%s%s" , httplib . GuessCurrentHostURL ( ctx ) , urlPathContext )
2023-03-24 07:12:23 +01:00
}
switch mode {
case "markdown" :
// Raw markdown
if err := markdown . RenderRaw ( & markup . RenderContext {
2024-06-17 08:16:14 +02:00
Ctx : ctx ,
Links : links ,
2023-03-24 07:12:23 +01:00
} , strings . NewReader ( text ) , ctx . Resp ) ; err != nil {
ctx . Error ( http . StatusInternalServerError , err . Error ( ) )
}
return
case "comment" :
2024-06-17 08:16:14 +02:00
// Issue & comment content
2023-03-24 07:12:23 +01:00
markupType = markdown . MarkupName
case "gfm" :
2024-06-17 08:16:14 +02:00
// GitHub Flavored Markdown
2023-03-24 07:12:23 +01:00
markupType = markdown . MarkupName
case "file" :
2024-06-17 08:16:14 +02:00
markupType = "" // render the repo file content by its extension
2023-03-24 07:12:23 +01:00
relativePath = filePath
default :
ctx . Error ( http . StatusUnprocessableEntity , fmt . Sprintf ( "Unknown mode: %s" , mode ) )
return
}
2024-06-17 08:16:14 +02:00
fields := strings . SplitN ( strings . TrimPrefix ( urlPathContext , setting . AppSubURL + "/" ) , "/" , 5 )
if len ( fields ) == 5 && fields [ 2 ] == "src" && ( fields [ 3 ] == "branch" || fields [ 3 ] == "commit" || fields [ 3 ] == "tag" ) {
// absolute base prefix is something like "https://host/subpath/{user}/{repo}"
absoluteBasePrefix := fmt . Sprintf ( "%s%s/%s" , httplib . GuessCurrentAppURL ( ctx ) , fields [ 0 ] , fields [ 1 ] )
fileDir := path . Dir ( filePath ) // it is "doc" if filePath is "doc/CHANGE.md"
refPath := strings . Join ( fields [ 3 : ] , "/" ) // it is "branch/features/feat-12/doc"
refPath = strings . TrimSuffix ( refPath , "/" + fileDir ) // now we get the correct branch path: "branch/features/feat-12"
links = markup . Links { AbsolutePrefix : true , Base : absoluteBasePrefix , BranchPath : refPath , TreePath : fileDir }
2023-03-24 07:12:23 +01:00
}
meta := map [ string ] string { }
2024-05-30 15:04:01 +08:00
var repoCtx * repo_model . Repository
2023-05-21 09:50:53 +08:00
if repo != nil && repo . Repository != nil {
2024-05-30 15:04:01 +08:00
repoCtx = repo . Repository
2023-03-24 07:12:23 +01:00
if mode == "comment" {
2023-10-11 06:24:07 +02:00
meta = repo . Repository . ComposeMetas ( ctx )
2023-03-24 07:12:23 +01:00
} else {
2023-10-11 06:24:07 +02:00
meta = repo . Repository . ComposeDocumentMetas ( ctx )
2023-03-24 07:12:23 +01:00
}
}
if mode != "comment" {
meta [ "mode" ] = "document"
}
if err := markup . Render ( & markup . RenderContext {
2024-06-17 08:16:14 +02:00
Ctx : ctx ,
Repo : repoCtx ,
Links : links ,
2023-03-24 07:12:23 +01:00
Metas : meta ,
IsWiki : wiki ,
Type : markupType ,
RelativePath : relativePath ,
} , strings . NewReader ( text ) , ctx . Resp ) ; err != nil {
if markup . IsErrUnsupportedRenderExtension ( err ) {
ctx . Error ( http . StatusUnprocessableEntity , err . Error ( ) )
} else {
ctx . Error ( http . StatusInternalServerError , err . Error ( ) )
}
return
}
}