summaryrefslogtreecommitdiffstats
path: root/modules/svg/processor.go
diff options
context:
space:
mode:
Diffstat (limited to 'modules/svg/processor.go')
-rw-r--r--modules/svg/processor.go59
1 files changed, 59 insertions, 0 deletions
diff --git a/modules/svg/processor.go b/modules/svg/processor.go
new file mode 100644
index 00000000..82248fb0
--- /dev/null
+++ b/modules/svg/processor.go
@@ -0,0 +1,59 @@
+// Copyright 2023 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package svg
+
+import (
+ "bytes"
+ "fmt"
+ "regexp"
+ "sync"
+)
+
+type normalizeVarsStruct struct {
+ reXMLDoc,
+ reComment,
+ reAttrXMLNs,
+ reAttrSize,
+ reAttrClassPrefix *regexp.Regexp
+}
+
+var (
+ normalizeVars *normalizeVarsStruct
+ normalizeVarsOnce sync.Once
+)
+
+// Normalize normalizes the SVG content: set default width/height, remove unnecessary tags/attributes
+// It's designed to work with valid SVG content. For invalid SVG content, the returned content is not guaranteed.
+func Normalize(data []byte, size int) []byte {
+ normalizeVarsOnce.Do(func() {
+ normalizeVars = &normalizeVarsStruct{
+ reXMLDoc: regexp.MustCompile(`(?s)<\?xml.*?>`),
+ reComment: regexp.MustCompile(`(?s)<!--.*?-->`),
+
+ reAttrXMLNs: regexp.MustCompile(`(?s)\s+xmlns\s*=\s*"[^"]*"`),
+ reAttrSize: regexp.MustCompile(`(?s)\s+(width|height)\s*=\s*"[^"]+"`),
+ reAttrClassPrefix: regexp.MustCompile(`(?s)\s+class\s*=\s*"`),
+ }
+ })
+ data = normalizeVars.reXMLDoc.ReplaceAll(data, nil)
+ data = normalizeVars.reComment.ReplaceAll(data, nil)
+
+ data = bytes.TrimSpace(data)
+ svgTag, svgRemaining, ok := bytes.Cut(data, []byte(">"))
+ if !ok || !bytes.HasPrefix(svgTag, []byte(`<svg`)) {
+ return data
+ }
+ normalized := bytes.Clone(svgTag)
+ normalized = normalizeVars.reAttrXMLNs.ReplaceAll(normalized, nil)
+ normalized = normalizeVars.reAttrSize.ReplaceAll(normalized, nil)
+ normalized = normalizeVars.reAttrClassPrefix.ReplaceAll(normalized, []byte(` class="`))
+ normalized = bytes.TrimSpace(normalized)
+ normalized = fmt.Appendf(normalized, ` width="%d" height="%d"`, size, size)
+ if !bytes.Contains(normalized, []byte(` class="`)) {
+ normalized = append(normalized, ` class="svg"`...)
+ }
+ normalized = append(normalized, '>')
+ normalized = append(normalized, svgRemaining...)
+ return normalized
+}