d2/lib/compress/compress.go
2022-11-25 19:22:31 -08:00

67 lines
1.4 KiB
Go

package compress
import (
"bytes"
"compress/flate"
"encoding/base64"
"io"
"strings"
"oss.terrastruct.com/d2/d2graph"
)
var compressionDict = "->" +
"<-" +
"--" +
"<->"
var compressionDictBytes []byte
// Compress takes a D2 script and compresses it to a URL-encoded string
func Compress(raw string) (string, error) {
var b bytes.Buffer
zw, err := flate.NewWriterDict(&b, flate.DefaultCompression, []byte(compressionDict))
if err != nil {
return "", err
}
if _, err := io.Copy(zw, strings.NewReader(raw)); err != nil {
return "", err
}
if err := zw.Close(); err != nil {
return "", err
}
encoded := base64.URLEncoding.EncodeToString(b.Bytes())
return encoded, nil
}
// Decompress takes a compressed, URL-encoded string and returns the decompressed D2 script
func Decompress(encoded string) (string, error) {
b64Decoded, err := base64.URLEncoding.DecodeString(encoded)
if err != nil {
return "", err
}
zr := flate.NewReaderDict(bytes.NewReader(b64Decoded), []byte(compressionDict))
var b bytes.Buffer
if _, err := io.Copy(&b, zr); err != nil {
return "", err
}
if err := zr.Close(); err != nil {
return "", nil
}
return b.String(), nil
}
func init() {
for k := range d2graph.StyleKeywords {
compressionDict += k
}
for k := range d2graph.ReservedKeywords {
compressionDict += k
}
for k := range d2graph.ReservedKeywordHolders {
compressionDict += k
}
}