Files
MokoGitea/modules/markup/renderer.go
T
Jonathan Miller 9a5720e8ad
Universal: PR Check / Build RC Package (pull_request) Blocked by required conditions
Universal: PR Check / Branch Policy (pull_request) Successful in 1s
Branch Policy Check / Verify merge target (pull_request) Successful in 1s
PR RC Release / Build RC Release (pull_request) Successful in 3s
Universal: PR Check / Validate PR (pull_request) Failing after 6s
Branch Cleanup / Delete merged branch (pull_request) Successful in 1s
chore: rename Go module from git. to code.mokoconsulting.tech (#336)
Full namespace migration: update the Go module path and all import
statements from git.mokoconsulting.tech to code.mokoconsulting.tech.
Also updates all URL references in templates, workflows, configs,
tests, and documentation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-31 10:28:25 -05:00

109 lines
3.0 KiB
Go

// Copyright 2017 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package markup
import (
"io"
"path"
"strings"
"code.mokoconsulting.tech/MokoConsulting/MokoGitea/modules/setting"
"code.mokoconsulting.tech/MokoConsulting/MokoGitea/modules/typesniffer"
)
// Renderer defines an interface for rendering markup file to HTML
type Renderer interface {
Name() string // markup format name, also the renderer type, also the external tool name
FileNamePatterns() []string
SanitizerRules() []setting.MarkupSanitizerRule
Render(ctx *RenderContext, input io.Reader, output io.Writer) error
}
// PostProcessRenderer defines an interface for renderers who need post process
type PostProcessRenderer interface {
NeedPostProcess() bool
}
type ExternalRendererOptions struct {
SanitizerDisabled bool
DisplayInIframe bool
ContentSandbox string
}
// ExternalRenderer defines an interface for external renderers
type ExternalRenderer interface {
GetExternalRendererOptions() ExternalRendererOptions
}
// RendererContentDetector detects if the content can be rendered
// by specified renderer
type RendererContentDetector interface {
CanRender(filename string, sniffedType typesniffer.SniffedType, prefetchBuf []byte) bool
}
var (
fileNameRenderers = make(map[string]Renderer)
renderers = make(map[string]Renderer)
)
// RegisterRenderer registers a new markup file renderer
func RegisterRenderer(renderer Renderer) {
// TODO: need to handle conflicts
renderers[renderer.Name()] = renderer
}
func RefreshFileNamePatterns() {
// TODO: need to handle conflicts
fileNameRenderers = make(map[string]Renderer)
for _, renderer := range renderers {
for _, ext := range renderer.FileNamePatterns() {
fileNameRenderers[strings.ToLower(ext)] = renderer
}
}
}
func DetectRendererTypeByFilename(filename string) Renderer {
basename := path.Base(strings.ToLower(filename))
ext1 := path.Ext(basename)
if renderer := fileNameRenderers[basename]; renderer != nil {
return renderer
}
if renderer := fileNameRenderers["*"+ext1]; renderer != nil {
return renderer
}
if basename, ok := strings.CutSuffix(basename, ext1); ok {
ext2 := path.Ext(basename)
if renderer := fileNameRenderers["*"+ext2+ext1]; renderer != nil {
return renderer
}
}
return nil
}
// DetectRendererTypeByPrefetch detects the markup type of the content
func DetectRendererTypeByPrefetch(filename string, sniffedType typesniffer.SniffedType, prefetchBuf []byte) string {
if filename != "" {
byExt := DetectRendererTypeByFilename(filename)
if byExt != nil {
return byExt.Name()
}
}
for _, renderer := range renderers {
if detector, ok := renderer.(RendererContentDetector); ok && detector.CanRender(filename, sniffedType, prefetchBuf) {
return renderer.Name()
}
}
return ""
}
func PreviewableExtensions() []string {
exts := make([]string, 0, len(fileNameRenderers))
for p := range fileNameRenderers {
if s, ok := strings.CutPrefix(p, "*"); ok {
exts = append(exts, s)
}
}
return exts
}