forgejo/modules/svg/svg.go
wxiaoguang a797b8458e
Keep (add if not existing) xmlns attribute for generated SVG images (#23410)
Fix #23409 

Developers could browse & preview the local SVG images files directly.

It still has clear output.

![image](https://user-images.githubusercontent.com/2114189/224317107-f4b26c76-e36a-4e80-9eee-d8dc2e16421f.png)


![image](https://user-images.githubusercontent.com/2114189/224317527-2d4ca131-978c-4933-b071-4bae483f06e1.png)

---------

Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: delvh <leon@kske.dev>
2023-03-21 13:39:27 +08:00

52 lines
1.3 KiB
Go

// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package svg
import (
"fmt"
"html/template"
"regexp"
"strings"
"code.gitea.io/gitea/modules/html"
)
var (
// SVGs contains discovered SVGs
SVGs map[string]string
widthRe = regexp.MustCompile(`width="[0-9]+?"`)
heightRe = regexp.MustCompile(`height="[0-9]+?"`)
)
const defaultSize = 16
// Init discovers SVGs and populates the `SVGs` variable
func Init() {
SVGs = Discover()
// Remove `xmlns` because inline SVG does not need it
r := regexp.MustCompile(`(<svg\b[^>]*?)\s+xmlns="[^"]*"`)
for name, svg := range SVGs {
SVGs[name] = r.ReplaceAllString(svg, "$1")
}
}
// Render render icons - arguments icon name (string), size (int), class (string)
func RenderHTML(icon string, others ...interface{}) template.HTML {
size, class := html.ParseSizeAndClass(defaultSize, "", others...)
if svgStr, ok := SVGs[icon]; ok {
if size != defaultSize {
svgStr = widthRe.ReplaceAllString(svgStr, fmt.Sprintf(`width="%d"`, size))
svgStr = heightRe.ReplaceAllString(svgStr, fmt.Sprintf(`height="%d"`, size))
}
if class != "" {
svgStr = strings.Replace(svgStr, `class="`, fmt.Sprintf(`class="%s `, class), 1)
}
return template.HTML(svgStr)
}
return template.HTML("")
}