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.

processor.go 1.8KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. // Copyright 2023 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package svg
  4. import (
  5. "bytes"
  6. "fmt"
  7. "regexp"
  8. "sync"
  9. )
  10. type normalizeVarsStruct struct {
  11. reXMLDoc,
  12. reComment,
  13. reAttrXMLNs,
  14. reAttrSize,
  15. reAttrClassPrefix *regexp.Regexp
  16. }
  17. var (
  18. normalizeVars *normalizeVarsStruct
  19. normalizeVarsOnce sync.Once
  20. )
  21. // Normalize normalizes the SVG content: set default width/height, remove unnecessary tags/attributes
  22. // It's designed to work with valid SVG content. For invalid SVG content, the returned content is not guaranteed.
  23. func Normalize(data []byte, size int) []byte {
  24. normalizeVarsOnce.Do(func() {
  25. normalizeVars = &normalizeVarsStruct{
  26. reXMLDoc: regexp.MustCompile(`(?s)<\?xml.*?>`),
  27. reComment: regexp.MustCompile(`(?s)<!--.*?-->`),
  28. reAttrXMLNs: regexp.MustCompile(`(?s)\s+xmlns\s*=\s*"[^"]*"`),
  29. reAttrSize: regexp.MustCompile(`(?s)\s+(width|height)\s*=\s*"[^"]+"`),
  30. reAttrClassPrefix: regexp.MustCompile(`(?s)\s+class\s*=\s*"`),
  31. }
  32. })
  33. data = normalizeVars.reXMLDoc.ReplaceAll(data, nil)
  34. data = normalizeVars.reComment.ReplaceAll(data, nil)
  35. data = bytes.TrimSpace(data)
  36. svgTag, svgRemaining, ok := bytes.Cut(data, []byte(">"))
  37. if !ok || !bytes.HasPrefix(svgTag, []byte(`<svg`)) {
  38. return data
  39. }
  40. normalized := bytes.Clone(svgTag)
  41. normalized = normalizeVars.reAttrXMLNs.ReplaceAll(normalized, nil)
  42. normalized = normalizeVars.reAttrSize.ReplaceAll(normalized, nil)
  43. normalized = normalizeVars.reAttrClassPrefix.ReplaceAll(normalized, []byte(` class="`))
  44. normalized = bytes.TrimSpace(normalized)
  45. normalized = fmt.Appendf(normalized, ` width="%d" height="%d"`, size, size)
  46. if !bytes.Contains(normalized, []byte(` class="`)) {
  47. normalized = append(normalized, ` class="svg"`...)
  48. }
  49. normalized = append(normalized, '>')
  50. normalized = append(normalized, svgRemaining...)
  51. return normalized
  52. }