1
1
mirror of https://github.com/go-gitea/gitea synced 2025-07-22 18:28:37 +00:00

Refactor render system (#32492)

There were too many patches to the Render system, it's really difficult
to make further improvements.

This PR clears the legacy problems and fix TODOs.

1. Rename `RenderContext.Type` to `RenderContext.MarkupType` to clarify
its usage.
2. Use `ContentMode` to replace `meta["mode"]` and `IsWiki`, to clarify
the rendering behaviors.
3. Use "wiki" mode instead of "mode=gfm + wiki=true"
4. Merge `renderByType` and `renderByFile`
5. Add more comments

----

The problem of "mode=document": in many cases it is not set, so many
non-comment places use comment's hard line break incorrectly
This commit is contained in:
wxiaoguang
2024-11-14 13:02:11 +08:00
committed by GitHub
parent 985e2a8af3
commit 3f9c3e7bc3
32 changed files with 237 additions and 257 deletions

View File

@@ -5,21 +5,22 @@
package common
import (
"errors"
"fmt"
"net/http"
"path"
"strings"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/modules/httplib"
"code.gitea.io/gitea/modules/markup"
"code.gitea.io/gitea/modules/markup/markdown"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/services/context"
)
// RenderMarkup renders markup text for the /markup and /markdown endpoints
func RenderMarkup(ctx *context.Base, repo *context.Repository, mode, text, urlPathContext, filePath string, wiki bool) {
func RenderMarkup(ctx *context.Base, repo *context.Repository, mode, text, urlPathContext, filePath string) {
// 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
@@ -27,32 +28,33 @@ func RenderMarkup(ctx *context.Base, repo *context.Repository, mode, text, urlPa
// 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}
renderCtx := &markup.RenderContext{
Ctx: ctx,
Links: markup.Links{AbsolutePrefix: true},
MarkupType: markdown.MarkupName,
}
if urlPathContext != "" {
links.Base = fmt.Sprintf("%s%s", httplib.GuessCurrentHostURL(ctx), urlPathContext)
renderCtx.Links.Base = fmt.Sprintf("%s%s", httplib.GuessCurrentHostURL(ctx), urlPathContext)
}
switch mode {
case "markdown":
// Raw markdown
if err := markdown.RenderRaw(&markup.RenderContext{
Ctx: ctx,
Links: links,
}, strings.NewReader(text), ctx.Resp); err != nil {
if mode == "" || mode == "markdown" {
// raw markdown doesn't need any special handling
if err := markdown.RenderRaw(renderCtx, strings.NewReader(text), ctx.Resp); err != nil {
ctx.Error(http.StatusInternalServerError, err.Error())
}
return
}
switch mode {
case "gfm": // legacy mode, do nothing
case "comment":
// Issue & comment content
markupType = markdown.MarkupName
case "gfm":
// GitHub Flavored Markdown
markupType = markdown.MarkupName
renderCtx.ContentMode = markup.RenderContentAsComment
case "wiki":
renderCtx.ContentMode = markup.RenderContentAsWiki
case "file":
markupType = "" // render the repo file content by its extension
relativePath = filePath
// render the repo file content by its extension
renderCtx.MarkupType = ""
renderCtx.RelativePath = filePath
renderCtx.InStandalonePage = true
default:
ctx.Error(http.StatusUnprocessableEntity, fmt.Sprintf("Unknown mode: %s", mode))
return
@@ -67,33 +69,19 @@ func RenderMarkup(ctx *context.Base, repo *context.Repository, mode, text, urlPa
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}
renderCtx.Links = markup.Links{AbsolutePrefix: true, Base: absoluteBasePrefix, BranchPath: refPath, TreePath: fileDir}
}
meta := map[string]string{}
var repoCtx *repo_model.Repository
if repo != nil && repo.Repository != nil {
repoCtx = repo.Repository
if mode == "comment" {
meta = repo.Repository.ComposeMetas(ctx)
renderCtx.Repo = repo.Repository
if renderCtx.ContentMode == markup.RenderContentAsComment {
renderCtx.Metas = repo.Repository.ComposeMetas(ctx)
} else {
meta = repo.Repository.ComposeDocumentMetas(ctx)
renderCtx.Metas = repo.Repository.ComposeDocumentMetas(ctx)
}
}
if mode != "comment" {
meta["mode"] = "document"
}
if err := markup.Render(&markup.RenderContext{
Ctx: ctx,
Repo: repoCtx,
Links: links,
Metas: meta,
IsWiki: wiki,
Type: markupType,
RelativePath: relativePath,
}, strings.NewReader(text), ctx.Resp); err != nil {
if markup.IsErrUnsupportedRenderExtension(err) {
if err := markup.Render(renderCtx, strings.NewReader(text), ctx.Resp); err != nil {
if errors.Is(err, util.ErrInvalidArgument) {
ctx.Error(http.StatusUnprocessableEntity, err.Error())
} else {
ctx.Error(http.StatusInternalServerError, err.Error())