44package markup
55
66import (
7+ "bytes"
78 "context"
89 "fmt"
910 "html/template"
@@ -16,6 +17,7 @@ import (
1617 "code.gitea.io/gitea/modules/htmlutil"
1718 "code.gitea.io/gitea/modules/markup/internal"
1819 "code.gitea.io/gitea/modules/setting"
20+ "code.gitea.io/gitea/modules/typesniffer"
1921 "code.gitea.io/gitea/modules/util"
2022
2123 "golang.org/x/sync/errgroup"
@@ -144,22 +146,29 @@ func (ctx *RenderContext) WithHelper(helper RenderHelper) *RenderContext {
144146 return ctx
145147}
146148
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 ) {
149+ func (ctx * RenderContext ) DetectMarkupRenderer (prefetchBuf []byte ) Renderer {
150150 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 )
151+ var sniffedType typesniffer. SniffedType
152+ if len ( prefetchBuf ) > 0 {
153+ sniffedType = typesniffer . DetectContentType ( prefetchBuf )
154154 }
155+ ctx .RenderOptions .MarkupType = DetectRendererTypeByPrefetch (ctx .RenderOptions .RelativePath , sniffedType , prefetchBuf )
155156 }
157+ return renderers [ctx .RenderOptions .MarkupType ]
158+ }
156159
157- renderer := renderers [ctx .RenderOptions .MarkupType ]
160+ func (ctx * RenderContext ) DetectMarkupRendererByReader (in io.Reader ) (Renderer , io.Reader , error ) {
161+ prefetchBuf := make ([]byte , 512 )
162+ n , err := util .ReadAtMost (in , prefetchBuf )
163+ if err != nil && err != io .EOF {
164+ return nil , nil , err
165+ }
166+ prefetchBuf = prefetchBuf [:n ]
167+ renderer := ctx .DetectMarkupRenderer (prefetchBuf )
158168 if renderer == nil {
159- return nil , util .NewNotExistErrorf ( "unsupported markup type: %q" , ctx . RenderOptions . MarkupType )
169+ return nil , nil , util .NewInvalidArgumentErrorf ( "unable to find a render" )
160170 }
161-
162- return renderer , nil
171+ return renderer , io .MultiReader (bytes .NewReader (prefetchBuf ), in ), nil
163172}
164173
165174func RendererNeedPostProcess (renderer Renderer ) bool {
@@ -170,12 +179,12 @@ func RendererNeedPostProcess(renderer Renderer) bool {
170179}
171180
172181// 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 )
182+ func Render (rctx * RenderContext , origInput io.Reader , output io.Writer ) error {
183+ renderer , input , err := rctx . DetectMarkupRendererByReader ( origInput )
175184 if err != nil {
176185 return err
177186 }
178- return RenderWithRenderer (ctx , renderer , input , output )
187+ return RenderWithRenderer (rctx , renderer , input , output )
179188}
180189
181190// RenderString renders Markup string to HTML with all specific handling stuff and return string
@@ -287,12 +296,14 @@ func Init(renderHelpFuncs *RenderHelperFuncs) {
287296 }
288297
289298 // since setting maybe changed extensions, this will reload all renderer extensions mapping
290- extRenderers = make (map [string ]Renderer )
299+ fileNameRenderers = make (map [string ]Renderer )
291300 for _ , renderer := range renderers {
292- for _ , ext := range renderer .Extensions () {
293- extRenderers [ strings . ToLower ( ext ) ] = renderer
301+ for _ , pattern := range renderer .FileNamePatterns () {
302+ fileNameRenderers [ pattern ] = renderer
294303 }
295304 }
305+
306+ RefreshFileNamePatterns ()
296307}
297308
298309func ComposeSimpleDocumentMetas () map [string ]string {
0 commit comments