59 lines · 1.8 KB · Go
RawDownload
// 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}