44package markup
55
66import (
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
165175func 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