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 09:07:21 +02:00
|
|
|
"path"
|
2023-03-24 07:12:23 +01:00
|
|
|
"strings"
|
|
|
|
|
2024-06-17 09:07:21 +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 08:12:22 +01: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 09:07:21 +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 09:07:21 +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 09:07:21 +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 09:07:21 +02:00
|
|
|
// Issue & comment content
|
2023-03-24 07:12:23 +01:00
|
|
|
markupType = markdown.MarkupName
|
|
|
|
case "gfm":
|
2024-06-17 09:07:21 +02:00
|
|
|
// GitHub Flavored Markdown
|
2023-03-24 07:12:23 +01:00
|
|
|
markupType = markdown.MarkupName
|
|
|
|
case "file":
|
2024-06-17 09:07:21 +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 09:07:21 +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{}
|
2023-05-21 03:50:53 +02:00
|
|
|
if repo != nil && repo.Repository != nil {
|
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 09:07:21 +02:00
|
|
|
Ctx: ctx,
|
|
|
|
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
|
|
|
|
}
|
|
|
|
}
|