Skip to content

Commit c567c00

Browse files
committed
fix
1 parent 12a81d3 commit c567c00

20 files changed

Lines changed: 268 additions & 146 deletions

File tree

modules/markup/asciicast/asciicast.go

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,27 +20,23 @@ func init() {
2020
// See https://github.com/asciinema/asciinema/blob/develop/doc/asciicast-v2.md
2121
type Renderer struct{}
2222

23-
// Name implements markup.Renderer
2423
func (Renderer) Name() string {
2524
return "asciicast"
2625
}
2726

28-
// Extensions implements markup.Renderer
29-
func (Renderer) Extensions() []string {
30-
return []string{".cast"}
27+
func (Renderer) FileNamePatterns() []string {
28+
return []string{"*.cast"}
3129
}
3230

3331
const (
3432
playerClassName = "asciinema-player-container"
3533
playerSrcAttr = "data-asciinema-player-src"
3634
)
3735

38-
// SanitizerRules implements markup.Renderer
3936
func (Renderer) SanitizerRules() []setting.MarkupSanitizerRule {
4037
return []setting.MarkupSanitizerRule{{Element: "div", AllowAttr: playerSrcAttr}}
4138
}
4239

43-
// Render implements markup.Renderer
4440
func (Renderer) Render(ctx *markup.RenderContext, _ io.Reader, output io.Writer) error {
4541
rawURL := fmt.Sprintf("%s/%s/%s/raw/%s/%s",
4642
setting.AppSubURL,

modules/markup/console/console.go

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,29 +20,24 @@ func init() {
2020
markup.RegisterRenderer(Renderer{})
2121
}
2222

23-
// Renderer implements markup.Renderer
2423
type Renderer struct{}
2524

2625
var _ markup.RendererContentDetector = (*Renderer)(nil)
2726

28-
// Name implements markup.Renderer
2927
func (Renderer) Name() string {
3028
return "console"
3129
}
3230

33-
// Extensions implements markup.Renderer
34-
func (Renderer) Extensions() []string {
35-
return []string{".sh-session"}
31+
func (Renderer) FileNamePatterns() []string {
32+
return []string{"*.sh-session"}
3633
}
3734

38-
// SanitizerRules implements markup.Renderer
3935
func (Renderer) SanitizerRules() []setting.MarkupSanitizerRule {
4036
return []setting.MarkupSanitizerRule{
4137
{Element: "span", AllowAttr: "class", Regexp: `^term-((fg[ix]?|bg)\d+|container)$`},
4238
}
4339
}
4440

45-
// CanRender implements markup.RendererContentDetector
4641
func (Renderer) CanRender(filename string, sniffedType typesniffer.SniffedType, prefetchBuf []byte) bool {
4742
if !sniffedType.IsTextPlain() {
4843
return false

modules/markup/csv/csv.go

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,16 @@ func init() {
2020
markup.RegisterRenderer(Renderer{})
2121
}
2222

23-
// Renderer implements markup.Renderer for csv files
2423
type Renderer struct{}
2524

26-
// Name implements markup.Renderer
2725
func (Renderer) Name() string {
2826
return "csv"
2927
}
3028

31-
// Extensions implements markup.Renderer
32-
func (Renderer) Extensions() []string {
33-
return []string{".csv", ".tsv"}
29+
func (Renderer) FileNamePatterns() []string {
30+
return []string{"*.csv", "*.tsv"}
3431
}
3532

36-
// SanitizerRules implements markup.Renderer
3733
func (Renderer) SanitizerRules() []setting.MarkupSanitizerRule {
3834
return []setting.MarkupSanitizerRule{
3935
{Element: "table", AllowAttr: "class", Regexp: `^data-table$`},

modules/markup/external/external.go

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121

2222
// RegisterRenderers registers all supported third part renderers according settings
2323
func RegisterRenderers() {
24+
markup.RegisterRenderer(&openAPIRenderer{})
2425
for _, renderer := range setting.ExternalMarkupRenderers {
2526
if renderer.Enabled && renderer.Command != "" && len(renderer.FileExtensions) > 0 {
2627
markup.RegisterRenderer(&Renderer{renderer})
@@ -38,22 +39,19 @@ var (
3839
_ markup.ExternalRenderer = (*Renderer)(nil)
3940
)
4041

41-
// Name returns the external tool name
42+
// Name returns the external tool name (also the renderer type, also the markup type)
4243
func (p *Renderer) Name() string {
4344
return p.MarkupName
4445
}
4546

46-
// NeedPostProcess implements markup.Renderer
4747
func (p *Renderer) NeedPostProcess() bool {
4848
return p.MarkupRenderer.NeedPostProcess
4949
}
5050

51-
// Extensions returns the supported extensions of the tool
52-
func (p *Renderer) Extensions() []string {
51+
func (p *Renderer) FileNamePatterns() []string {
5352
return p.FileExtensions
5453
}
5554

56-
// SanitizerRules implements markup.Renderer
5755
func (p *Renderer) SanitizerRules() []setting.MarkupSanitizerRule {
5856
return p.MarkupSanitizerRules
5957
}

modules/markup/external/openapi.go

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
// Copyright 2026 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
package external
5+
6+
import (
7+
"fmt"
8+
"html"
9+
"io"
10+
11+
"code.gitea.io/gitea/modules/markup"
12+
"code.gitea.io/gitea/modules/setting"
13+
"code.gitea.io/gitea/modules/util"
14+
)
15+
16+
type openAPIRenderer struct{}
17+
18+
var (
19+
_ markup.PostProcessRenderer = (*openAPIRenderer)(nil)
20+
_ markup.ExternalRenderer = (*openAPIRenderer)(nil)
21+
)
22+
23+
func (p *openAPIRenderer) Name() string {
24+
return "openapi"
25+
}
26+
27+
func (p *openAPIRenderer) NeedPostProcess() bool {
28+
return false
29+
}
30+
31+
func (p *openAPIRenderer) FileNamePatterns() []string {
32+
return []string{
33+
"openapi.yaml",
34+
"openapi.yml",
35+
"openapi.json",
36+
"swagger.yaml",
37+
"swagger.yml",
38+
"swagger.json",
39+
}
40+
}
41+
42+
func (p *openAPIRenderer) SanitizerRules() []setting.MarkupSanitizerRule {
43+
return nil
44+
}
45+
46+
func (p *openAPIRenderer) GetExternalRendererOptions() (ret markup.ExternalRendererOptions) {
47+
ret.SanitizerDisabled = true
48+
ret.DisplayInIframe = true
49+
ret.ContentSandbox = ""
50+
return ret
51+
}
52+
53+
func (p *openAPIRenderer) Render(ctx *markup.RenderContext, input io.Reader, output io.Writer) error {
54+
content, err := io.ReadAll(input)
55+
if err != nil {
56+
return err
57+
}
58+
// TODO: can extract this to a tmpl file later
59+
_, err = io.WriteString(output, fmt.Sprintf(
60+
`<!DOCTYPE html>
61+
<html>
62+
<head>
63+
<meta name="viewport" content="width=device-width, initial-scale=1">
64+
<link rel="stylesheet" href="%s/assets/css/swagger.css?v=%s">
65+
</head>
66+
<body>
67+
<div id="swagger-ui"><textarea class="swagger-spec-content" data-spec-filename="%s">%s</textarea></div>
68+
<script src="%s/assets/js/swagger.js?v=%s"></script>
69+
</body>
70+
</html>`,
71+
setting.StaticURLPrefix,
72+
setting.AssetVersion,
73+
html.EscapeString(ctx.RenderOptions.RelativePath),
74+
html.EscapeString(util.UnsafeBytesToString(content)),
75+
setting.StaticURLPrefix,
76+
setting.AssetVersion,
77+
))
78+
return err
79+
}

modules/markup/markdown/markdown.go

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -240,30 +240,24 @@ func init() {
240240
markup.RegisterRenderer(Renderer{})
241241
}
242242

243-
// Renderer implements markup.Renderer
244243
type Renderer struct{}
245244

246245
var _ markup.PostProcessRenderer = (*Renderer)(nil)
247246

248-
// Name implements markup.Renderer
249247
func (Renderer) Name() string {
250248
return MarkupName
251249
}
252250

253-
// NeedPostProcess implements markup.PostProcessRenderer
254251
func (Renderer) NeedPostProcess() bool { return true }
255252

256-
// Extensions implements markup.Renderer
257-
func (Renderer) Extensions() []string {
258-
return setting.Markdown.FileExtensions
253+
func (Renderer) FileNamePatterns() []string {
254+
return setting.Markdown.FileNamePatterns
259255
}
260256

261-
// SanitizerRules implements markup.Renderer
262257
func (Renderer) SanitizerRules() []setting.MarkupSanitizerRule {
263258
return []setting.MarkupSanitizerRule{}
264259
}
265260

266-
// Render implements markup.Renderer
267261
func (Renderer) Render(ctx *markup.RenderContext, input io.Reader, output io.Writer) error {
268262
return render(ctx, input, output)
269263
}

modules/markup/orgmode/orgmode.go

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,20 +33,16 @@ var (
3333
_ markup.PostProcessRenderer = (*renderer)(nil)
3434
)
3535

36-
// Name implements markup.Renderer
3736
func (renderer) Name() string {
3837
return "orgmode"
3938
}
4039

41-
// NeedPostProcess implements markup.PostProcessRenderer
4240
func (renderer) NeedPostProcess() bool { return true }
4341

44-
// Extensions implements markup.Renderer
45-
func (renderer) Extensions() []string {
46-
return []string{".org"}
42+
func (renderer) FileNamePatterns() []string {
43+
return []string{"*.org"}
4744
}
4845

49-
// SanitizerRules implements markup.Renderer
5046
func (renderer) SanitizerRules() []setting.MarkupSanitizerRule {
5147
return []setting.MarkupSanitizerRule{}
5248
}

modules/markup/render.go

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44
package markup
55

66
import (
7+
"bytes"
78
"context"
9+
"errors"
810
"fmt"
911
"html/template"
1012
"io"
@@ -16,6 +18,7 @@ import (
1618
"code.gitea.io/gitea/modules/htmlutil"
1719
"code.gitea.io/gitea/modules/markup/internal"
1820
"code.gitea.io/gitea/modules/setting"
21+
"code.gitea.io/gitea/modules/typesniffer"
1922
"code.gitea.io/gitea/modules/util"
2023

2124
"golang.org/x/sync/errgroup"
@@ -144,22 +147,29 @@ func (ctx *RenderContext) WithHelper(helper RenderHelper) *RenderContext {
144147
return ctx
145148
}
146149

147-
// FindRendererByContext finds renderer by RenderContext
148-
// TODO: it should be merged with other similar functions like GetRendererByFileName, DetectMarkupTypeByFileName, etc
149-
func FindRendererByContext(ctx *RenderContext) (Renderer, error) {
150+
func (ctx *RenderContext) DetectMarkupRenderer(prefetchBuf []byte) Renderer {
150151
if ctx.RenderOptions.MarkupType == "" && ctx.RenderOptions.RelativePath != "" {
151-
ctx.RenderOptions.MarkupType = DetectMarkupTypeByFileName(ctx.RenderOptions.RelativePath)
152-
if ctx.RenderOptions.MarkupType == "" {
153-
return nil, util.NewInvalidArgumentErrorf("unsupported file to render: %q", ctx.RenderOptions.RelativePath)
152+
var sniffedType typesniffer.SniffedType
153+
if len(prefetchBuf) > 0 {
154+
sniffedType = typesniffer.DetectContentType(prefetchBuf)
154155
}
156+
ctx.RenderOptions.MarkupType = DetectRendererTypeByPrefetch(ctx.RenderOptions.RelativePath, sniffedType, prefetchBuf)
155157
}
158+
return renderers[ctx.RenderOptions.MarkupType]
159+
}
156160

157-
renderer := renderers[ctx.RenderOptions.MarkupType]
161+
func (ctx *RenderContext) DetectMarkupRendererByReader(in io.Reader) (Renderer, io.Reader, error) {
162+
prefetchBuf := make([]byte, 512)
163+
n, err := util.ReadAtMost(in, prefetchBuf)
164+
if err != nil && err != io.EOF {
165+
return nil, nil, err
166+
}
167+
prefetchBuf = prefetchBuf[:n]
168+
renderer := ctx.DetectMarkupRenderer(prefetchBuf)
158169
if renderer == nil {
159-
return nil, util.NewNotExistErrorf("unsupported markup type: %q", ctx.RenderOptions.MarkupType)
170+
return nil, nil, errors.New("markup renderer not supported")
160171
}
161-
162-
return renderer, nil
172+
return renderer, io.MultiReader(bytes.NewReader(prefetchBuf), in), nil
163173
}
164174

165175
func RendererNeedPostProcess(renderer Renderer) bool {
@@ -170,12 +180,12 @@ func RendererNeedPostProcess(renderer Renderer) bool {
170180
}
171181

172182
// Render renders markup file to HTML with all specific handling stuff.
173-
func Render(ctx *RenderContext, input io.Reader, output io.Writer) error {
174-
renderer, err := FindRendererByContext(ctx)
183+
func Render(rctx *RenderContext, origInput io.Reader, output io.Writer) error {
184+
renderer, input, err := rctx.DetectMarkupRendererByReader(origInput)
175185
if err != nil {
176186
return err
177187
}
178-
return RenderWithRenderer(ctx, renderer, input, output)
188+
return RenderWithRenderer(rctx, renderer, input, output)
179189
}
180190

181191
// RenderString renders Markup string to HTML with all specific handling stuff and return string
@@ -287,10 +297,10 @@ func Init(renderHelpFuncs *RenderHelperFuncs) {
287297
}
288298

289299
// since setting maybe changed extensions, this will reload all renderer extensions mapping
290-
extRenderers = make(map[string]Renderer)
300+
fileNameRenderers = make(map[string]Renderer)
291301
for _, renderer := range renderers {
292-
for _, ext := range renderer.Extensions() {
293-
extRenderers[strings.ToLower(ext)] = renderer
302+
for _, pattern := range renderer.FileNamePatterns() {
303+
fileNameRenderers[pattern] = renderer
294304
}
295305
}
296306
}

0 commit comments

Comments
 (0)