code.gitea.io/gitea@v1.19.3/modules/markup/asciicast/asciicast.go (about) 1 // Copyright 2023 The Gitea Authors. All rights reserved. 2 // SPDX-License-Identifier: MIT 3 4 package asciicast 5 6 import ( 7 "fmt" 8 "io" 9 "net/url" 10 "regexp" 11 12 "code.gitea.io/gitea/modules/markup" 13 "code.gitea.io/gitea/modules/setting" 14 ) 15 16 func init() { 17 markup.RegisterRenderer(Renderer{}) 18 } 19 20 // Renderer implements markup.Renderer for asciicast files. 21 // See https://github.com/asciinema/asciinema/blob/develop/doc/asciicast-v2.md 22 type Renderer struct{} 23 24 // Name implements markup.Renderer 25 func (Renderer) Name() string { 26 return "asciicast" 27 } 28 29 // Extensions implements markup.Renderer 30 func (Renderer) Extensions() []string { 31 return []string{".cast"} 32 } 33 34 const ( 35 playerClassName = "asciinema-player-container" 36 playerSrcAttr = "data-asciinema-player-src" 37 ) 38 39 // SanitizerRules implements markup.Renderer 40 func (Renderer) SanitizerRules() []setting.MarkupSanitizerRule { 41 return []setting.MarkupSanitizerRule{ 42 {Element: "div", AllowAttr: "class", Regexp: regexp.MustCompile(playerClassName)}, 43 {Element: "div", AllowAttr: playerSrcAttr}, 44 } 45 } 46 47 // Render implements markup.Renderer 48 func (Renderer) Render(ctx *markup.RenderContext, _ io.Reader, output io.Writer) error { 49 rawURL := fmt.Sprintf("%s/%s/%s/raw/%s/%s", 50 setting.AppSubURL, 51 url.PathEscape(ctx.Metas["user"]), 52 url.PathEscape(ctx.Metas["repo"]), 53 ctx.Metas["BranchNameSubURL"], 54 url.PathEscape(ctx.RelativePath), 55 ) 56 57 _, err := io.WriteString(output, fmt.Sprintf( 58 `<div class="%s" %s="%s"></div>`, 59 playerClassName, 60 playerSrcAttr, 61 rawURL, 62 )) 63 return err 64 }