You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

svg.go 1.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. // Copyright 2020 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package svg
  4. import (
  5. "fmt"
  6. "html/template"
  7. "path"
  8. "regexp"
  9. "strings"
  10. "code.gitea.io/gitea/modules/html"
  11. "code.gitea.io/gitea/modules/log"
  12. "code.gitea.io/gitea/modules/public"
  13. )
  14. var (
  15. // SVGs contains discovered SVGs
  16. SVGs = map[string]string{}
  17. widthRe = regexp.MustCompile(`width="[0-9]+?"`)
  18. heightRe = regexp.MustCompile(`height="[0-9]+?"`)
  19. )
  20. const defaultSize = 16
  21. // Init discovers SVGs and populates the `SVGs` variable
  22. func Init() error {
  23. files, err := public.AssetFS().ListFiles("assets/img/svg")
  24. if err != nil {
  25. return err
  26. }
  27. // Remove `xmlns` because inline SVG does not need it
  28. reXmlns := regexp.MustCompile(`(<svg\b[^>]*?)\s+xmlns="[^"]*"`)
  29. for _, file := range files {
  30. if path.Ext(file) != ".svg" {
  31. continue
  32. }
  33. bs, err := public.AssetFS().ReadFile("assets/img/svg", file)
  34. if err != nil {
  35. log.Error("Failed to read SVG file %s: %v", file, err)
  36. } else {
  37. SVGs[file[:len(file)-4]] = reXmlns.ReplaceAllString(string(bs), "$1")
  38. }
  39. }
  40. return nil
  41. }
  42. // RenderHTML renders icons - arguments icon name (string), size (int), class (string)
  43. func RenderHTML(icon string, others ...any) template.HTML {
  44. size, class := html.ParseSizeAndClass(defaultSize, "", others...)
  45. if svgStr, ok := SVGs[icon]; ok {
  46. if size != defaultSize {
  47. svgStr = widthRe.ReplaceAllString(svgStr, fmt.Sprintf(`width="%d"`, size))
  48. svgStr = heightRe.ReplaceAllString(svgStr, fmt.Sprintf(`height="%d"`, size))
  49. }
  50. if class != "" {
  51. svgStr = strings.Replace(svgStr, `class="`, fmt.Sprintf(`class="%s `, class), 1)
  52. }
  53. return template.HTML(svgStr)
  54. }
  55. return ""
  56. }